From 6d106c22f212bc3167b1bd4c4ab00f6480187c59 Mon Sep 17 00:00:00 2001 From: tsantalis Date: Sun, 7 Apr 2024 10:36:28 -0400 Subject: [PATCH] Improved storing of local files for initial commit --- ...0e5adae69c7b17c951f1198a6b6900721a1ee.json | 2 +- .../javadoc/JavaDocExternalFilter.java | 355 ++ .../javadoc/JavaDocInfoComponent.java | 510 +++ .../javadoc/JavaDocInfoGenerator.java | 1268 ++++++ .../codeInsight/javadoc/JavaDocManager.java | 737 ++++ .../codeInsight/javadoc/JavaDocUtil.java | 408 ++ .../actions/ShowJavaDocInfoAction.java | 115 + .../codeInsight/lookup/CharFilter.java | 17 + .../lookup/DeferredUserLookupValue.java | 14 + .../intellij/codeInsight/lookup/Lookup.java | 29 + .../codeInsight/lookup/LookupAdapter.java | 12 + .../codeInsight/lookup/LookupEvent.java | 33 + .../codeInsight/lookup/LookupItem.java | 154 + .../codeInsight/lookup/LookupItemUtil.java | 243 ++ .../codeInsight/lookup/LookupListener.java | 14 + .../codeInsight/lookup/LookupManager.java | 31 + .../lookup/LookupValueWithUIHint.java | 14 + .../lookup/PresentableLookupValue.java | 12 + .../lookup/impl/BackspaceHandler.java | 54 + .../codeInsight/lookup/impl/DownHandler.java | 29 + .../codeInsight/lookup/impl/EndHandler.java | 24 + .../codeInsight/lookup/impl/HomeHandler.java | 24 + .../lookup/impl/LookupCellRenderer.java | 555 +++ .../codeInsight/lookup/impl/LookupImpl.java | 526 +++ .../lookup/impl/LookupManagerImpl.java | 236 + .../lookup/impl/PageDownHandler.java | 24 + .../lookup/impl/PageUpHandler.java | 24 + .../lookup/impl/TestLookupManager.java | 91 + .../codeInsight/lookup/impl/TypedHandler.java | 84 + .../codeInsight/lookup/impl/UpHandler.java | 29 + .../lookup/impl/actions/ChooseItemAction.java | 27 + .../impl/actions/ChooseItemReplaceAction.java | 29 + .../navigation/CtrlMouseHandler.java | 688 +++ .../navigation/GotoImplementationHandler.java | 239 + .../navigation/IncrementalSearchHandler.java | 461 ++ .../navigation/MethodDownHandler.java | 47 + .../navigation/MethodUpDownUtil.java | 50 + .../navigation/MethodUpHandler.java | 47 + .../navigation/NavigationUtil.java | 47 + .../actions/GotoDeclarationAction.java | 251 ++ .../actions/GotoImplementationAction.java | 18 + .../navigation/actions/GotoSuperAction.java | 92 + .../actions/GotoTypeDeclarationAction.java | 78 + .../actions/IncrementalSearchAction.java | 39 + .../navigation/actions/MethodDownAction.java | 24 + .../navigation/actions/MethodUpAction.java | 24 + .../codeInsight/template/Expression.java | 12 + .../template/ExpressionContext.java | 18 + .../codeInsight/template/ExpressionUtil.java | 59 + .../template/InvokeActionResult.java | 24 + .../intellij/codeInsight/template/Macro.java | 17 + .../template/PsiElementResult.java | 45 + .../codeInsight/template/PsiTypeResult.java | 43 + .../intellij/codeInsight/template/Result.java | 10 + .../codeInsight/template/Template.java | 31 + .../codeInsight/template/TemplateBuilder.java | 128 + .../codeInsight/template/TemplateManager.java | 28 + .../template/TemplateStateListener.java | 8 + .../codeInsight/template/TextResult.java | 23 + .../actions/SaveAsTemplateAction.java | 159 + .../template/impl/ConstantNode.java | 31 + .../template/impl/EditTemplateDialog.java | 603 +++ .../template/impl/EditVariableDialog.java | 360 ++ .../codeInsight/template/impl/EmptyNode.java | 28 + .../template/impl/ListTemplatesHandler.java | 79 + .../impl/LiveTemplatesConfigurable.java | 59 + .../template/impl/MacroCallNode.java | 45 + .../template/impl/MacroParser.java | 122 + .../template/impl/SelectionNode.java | 25 + .../impl/SurroundWithTemplateHandler.java | 194 + .../codeInsight/template/impl/TableMap.java | 70 + .../template/impl/TableSorter.java | 314 ++ .../template/impl/TemplateColors.java | 7 + .../template/impl/TemplateContext.java | 77 + .../template/impl/TemplateEditorUtil.java | 114 + .../template/impl/TemplateImpl.java | 358 ++ .../template/impl/TemplateImplUtil.java | 75 + .../template/impl/TemplateListPanel.java | 719 +++ .../template/impl/TemplateManagerImpl.java | 274 ++ .../template/impl/TemplateSegments.java | 64 + .../template/impl/TemplateSettings.java | 457 ++ .../template/impl/TemplateState.java | 971 +++++ .../template/impl/TemplateTextLexer.java | 280 ++ .../template/impl/TemplateTokenType.java | 9 + .../codeInsight/template/impl/Variable.java | 105 + .../template/impl/VariableNode.java | 54 + .../impl/actions/ListTemplatesAction.java | 12 + .../impl/actions/NextVariableAction.java | 37 + .../impl/actions/PreviousVariableAction.java | 37 + .../actions/SurroundWithTemplateAction.java | 14 + .../template/macro/ArrayVariableMacro.java | 46 + .../template/macro/BaseCompleteMacro.java | 152 + .../template/macro/CapitalizeMacro.java | 44 + .../macro/CastToLeftSideTypeMacro.java | 60 + .../macro/ClassNameCompleteMacro.java | 26 + .../template/macro/ClassNameMacro.java | 62 + .../template/macro/CompleteMacro.java | 21 + .../template/macro/CompleteSmartMacro.java | 21 + .../template/macro/ComponentTypeOfMacro.java | 67 + .../template/macro/CurrentPackageMacro.java | 48 + .../template/macro/DecapitalizeMacro.java | 44 + .../macro/DescendantClassesEnumMacro.java | 102 + .../codeInsight/template/macro/EnumMacro.java | 44 + .../template/macro/ExpectedTypeMacro.java | 87 + .../template/macro/GuessElementTypeMacro.java | 70 + .../macro/IterableComponentTypeMacro.java | 75 + .../template/macro/IterableVariableMacro.java | 45 + .../template/macro/LineNumberMacro.java | 33 + .../template/macro/MacroFactory.java | 65 + .../codeInsight/template/macro/MacroUtil.java | 139 + .../template/macro/MethodNameMacro.java | 51 + .../macro/QualifiedClassNameMacro.java | 49 + .../template/macro/RightSideTypeMacro.java | 57 + .../template/macro/SuggestIndexNameMacro.java | 64 + .../macro/SuggestVariableNameMacro.java | 75 + .../template/macro/VariableOfTypeMacro.java | 93 + .../template/macro/VariableTypeMacroBase.java | 40 + .../codeInspection/InspectionDiff.java | 122 + .../codeInspection/InspectionMain.java | 80 + .../actions/CodeInspectionAction.java | 19 + .../actions/ViewOfflineResultsAction.java | 118 + .../canBeFinal/CanBeFinalInspection.java | 248 ++ .../codeInspection/dataFlow/ControlFlow.java | 76 + .../dataFlow/ControlFlowAnalyzer.java | 1155 +++++ .../dataFlow/DataFlowInspection.java | 242 + .../dataFlow/DataFlowRunner.java | 182 + .../dataFlow/DfaInstructionState.java | 38 + .../dataFlow/DfaMemoryState.java | 36 + .../dataFlow/DfaMemoryStateImpl.java | 503 +++ .../dataFlow/DfaVariableState.java | 107 + .../codeInspection/dataFlow/SortedIntSet.java | 50 + .../instructions/AssignInstruction.java | 33 + .../instructions/BinopInstruction.java | 128 + .../instructions/BranchingInstruction.java | 60 + .../ConditionalGotoInstruction.java | 99 + .../dataFlow/instructions/DupInstruction.java | 25 + .../instructions/EmptyInstruction.java | 24 + .../instructions/EmptyStackInstruction.java | 26 + .../FieldReferenceInstruction.java | 58 + .../FlushVariableInstruction.java | 34 + .../instructions/GosubInstruction.java | 27 + .../instructions/GotoInstruction.java | 36 + .../dataFlow/instructions/Instruction.java | 47 + .../instructions/MethodCallInstruction.java | 64 + .../dataFlow/instructions/NotInstruction.java | 27 + .../dataFlow/instructions/PopInstruction.java | 22 + .../instructions/PushInstruction.java | 29 + .../ReturnFromSubInstruction.java | 19 + .../instructions/ReturnInstruction.java | 21 + .../instructions/SwapInstruction.java | 26 + .../instructions/TypeCastInstruction.java | 70 + .../dataFlow/value/DfaConstValue.java | 99 + .../dataFlow/value/DfaNewValue.java | 80 + .../dataFlow/value/DfaRelationValue.java | 143 + .../dataFlow/value/DfaTypeValue.java | 101 + .../dataFlow/value/DfaUnknownValue.java | 44 + .../dataFlow/value/DfaValue.java | 26 + .../dataFlow/value/DfaValueFactory.java | 94 + .../dataFlow/value/DfaVariableValue.java | 93 + .../deadCode/DeadCodeInspection.java | 820 ++++ .../deadCode/DeadHTMLComposer.java | 307 ++ .../deadCode/DummyEntryPointsTool.java | 77 + .../deadCode/RefEntryPointFilter.java | 20 + .../deadCode/RefUnreachableFilter.java | 20 + .../deadCode/RefUnreferencedFilter.java | 32 + .../defUse/DefUseInspection.java | 234 + .../codeInspection/defUse/DefUseUtil.java | 490 +++ .../deprecation/DeprecationInspection.java | 50 + .../emptyMethod/EmptyMethodInspection.java | 237 + .../equalsAndHashcode/EqualsAndHashcode.java | 107 + .../ex/AddAssertStatementFix.java | 44 + .../ex/BaseLocalInspectionTool.java | 18 + .../codeInspection/ex/Descriptor.java | 120 + .../codeInspection/ex/DescriptorComposer.java | 125 + .../ex/DescriptorProviderInspection.java | 179 + .../codeInspection/ex/EntryPointsManager.java | 192 + .../ex/FilteringInspectionTool.java | 66 + .../codeInspection/ex/HTMLComposer.java | 513 +++ .../ex/InspectionApplication.java | 200 + .../ex/InspectionManagerEx.java | 927 ++++ .../codeInspection/ex/InspectionProfile.java | 88 + .../ex/InspectionProfileImpl.java | 675 +++ .../codeInspection/ex/InspectionTool.java | 111 + .../ex/InspectionToolRegistrar.java | 150 + .../codeInspection/ex/JobDescriptor.java | 45 + .../ex/LocalInspectionToolWrapper.java | 151 + .../ex/LocalQuickFixWrapper.java | 100 + .../ex/ProblemDescriptorImpl.java | 60 + .../codeInspection/ex/QuickFixAction.java | 188 + .../codeInspection/ex/QuickFixWrapper.java | 43 + .../ex/StandardInspectionToolsProvider.java | 50 + .../codeInspection/ex/VisibleTreeState.java | 167 + .../export/ExportToHTMLDialog.java | 56 + .../export/HTMLExportFrameMaker.java | 67 + .../codeInspection/export/HTMLExporter.java | 129 + .../localCanBeFinal/LocalCanBeFinal.java | 279 ++ .../GenericsInspectionToolBase.java | 47 + .../RedundantTypeArgsInspection.java | 122 + ...ciousCollectionsMethodCallsInspection.java | 157 + .../RedundantCastInspection.java | 126 + .../redundantCast/RedundantCastUtil.java | 328 ++ .../codeInspection/reference/RefClass.java | 567 +++ .../codeInspection/reference/RefElement.java | 327 ++ .../codeInspection/reference/RefEntity.java | 59 + .../codeInspection/reference/RefField.java | 173 + .../reference/RefImplicitConstructor.java | 56 + .../codeInspection/reference/RefManager.java | 346 ++ .../codeInspection/reference/RefMethod.java | 725 +++ .../codeInspection/reference/RefPackage.java | 29 + .../reference/RefParameter.java | 100 + .../codeInspection/reference/RefProject.java | 31 + .../codeInspection/reference/RefUtil.java | 514 +++ .../codeInspection/reference/RefVisitor.java | 31 + .../SameParameterValueInspection.java | 95 + .../SameReturnValueInspection.java | 97 + .../intellij/codeInspection/ui/Browser.java | 258 ++ .../codeInspection/ui/EntryPointsNode.java | 20 + .../ui/InspectionGroupNode.java | 29 + .../codeInspection/ui/InspectionNode.java | 50 + .../ui/InspectionPackageNode.java | 25 + .../ui/InspectionResultsView.java | 741 ++++ .../codeInspection/ui/InspectionRootNode.java | 35 + .../codeInspection/ui/InspectionTree.java | 275 ++ .../codeInspection/ui/InspectionTreeNode.java | 38 + .../ui/ProblemDescriptionNode.java | 58 + .../ui/RefAlphabeticalComparator.java | 36 + .../codeInspection/ui/RefElementNode.java | 150 + .../unneededThrows/UnneededThrows.java | 201 + .../UnusedParametersInspection.java | 205 + .../unusedReturnValue/UnusedReturnValue.java | 140 + .../util/RefEntityAlphabeticalComparator.java | 44 + .../codeInspection/util/RefFilter.java | 26 + .../codeInspection/util/XMLExportUtl.java | 149 + .../visibility/VisibilityInspection.java | 327 ++ .../source/com/intellij/compiler/Chunk.java | 63 + .../compiler/CompilerConfiguration.java | 463 ++ .../intellij/compiler/CompilerException.java | 14 + .../com/intellij/compiler/CompilerIOUtil.java | 55 + .../compiler/CompilerMessageImpl.java | 121 + .../CompilerWorkspaceConfiguration.java | 49 + .../source/com/intellij/compiler/HelpID.java | 8 + .../intellij/compiler/JavacOutputParser.java | 267 ++ .../com/intellij/compiler/JavacSettings.java | 99 + .../intellij/compiler/JikesOutputParser.java | 124 + .../com/intellij/compiler/JikesSettings.java | 98 + .../intellij/compiler/ModuleCompilerUtil.java | 228 + .../com/intellij/compiler/OutputParser.java | 81 + .../com/intellij/compiler/RmicSettings.java | 76 + .../com/intellij/compiler/SymbolTable.java | 167 + .../compiler/actions/CompileAction.java | 169 + .../compiler/actions/CompileActionBase.java | 22 + .../actions/CompileProjectAction.java | 34 + .../actions/GenerateAntBuildAction.java | 185 + .../actions/GenerateAntBuildDialog.java | 248 ++ .../compiler/actions/MakeModuleAction.java | 68 + .../compiler/ant/BuildProperties.java | 295 ++ .../com/intellij/compiler/ant/ChunkBuild.java | 76 + .../intellij/compiler/ant/CleanModule.java | 20 + .../intellij/compiler/ant/CleanProject.java | 30 + .../com/intellij/compiler/ant/Comment.java | 44 + .../ant/CompileModuleChunkTarget.java | 104 + .../compiler/ant/CompilerExcludes.java | 53 + .../ant/CompilerResourcePatterns.java | 41 + .../compiler/ant/CompositeGenerator.java | 49 + .../compiler/ant/GenerationOptions.java | 164 + .../compiler/ant/GenerationUtils.java | 46 + .../com/intellij/compiler/ant/Generator.java | 35 + .../LibraryDefinitionsGeneratorFactory.java | 84 + .../intellij/compiler/ant/ModuleChunk.java | 88 + .../compiler/ant/ModuleChunkAntProject.java | 31 + .../compiler/ant/ModuleChunkClasspath.java | 141 + .../compiler/ant/ModuleChunkSourcepath.java | 160 + .../intellij/compiler/ant/ModuleSources.java | 146 + .../ant/MultipleFileProjectBuild.java | 27 + .../intellij/compiler/ant/ProjectBuild.java | 77 + .../compiler/ant/PropertyFileGenerator.java | 68 + .../compiler/ant/SingleFileProjectBuild.java | 23 + .../source/com/intellij/compiler/ant/Tag.java | 67 + .../compiler/ant/taskdefs/AntCall.java | 15 + .../compiler/ant/taskdefs/AntProject.java | 14 + .../compiler/ant/taskdefs/Attribute.java | 14 + .../intellij/compiler/ant/taskdefs/Copy.java | 17 + .../compiler/ant/taskdefs/Delete.java | 14 + .../compiler/ant/taskdefs/DirSet.java | 15 + .../compiler/ant/taskdefs/Dirname.java | 14 + .../compiler/ant/taskdefs/Exclude.java | 16 + .../compiler/ant/taskdefs/FileSet.java | 16 + .../compiler/ant/taskdefs/Import.java | 18 + .../compiler/ant/taskdefs/Include.java | 16 + .../intellij/compiler/ant/taskdefs/Jar.java | 14 + .../intellij/compiler/ant/taskdefs/Javac.java | 34 + .../compiler/ant/taskdefs/Manifest.java | 14 + .../intellij/compiler/ant/taskdefs/Mkdir.java | 14 + .../intellij/compiler/ant/taskdefs/Param.java | 18 + .../intellij/compiler/ant/taskdefs/Path.java | 15 + .../compiler/ant/taskdefs/PathElement.java | 17 + .../compiler/ant/taskdefs/PathRef.java | 16 + .../compiler/ant/taskdefs/PatternSet.java | 14 + .../compiler/ant/taskdefs/PatternSetRef.java | 14 + .../compiler/ant/taskdefs/Property.java | 25 + .../compiler/ant/taskdefs/Target.java | 33 + .../compiler/ant/taskdefs/ZipFileSet.java | 25 + .../classParsing/AnnotationConstantValue.java | 70 + .../classParsing/AnnotationNameValuePair.java | 23 + .../AnnotationPrimitiveConstantValue.java | 57 + .../classParsing/ClassFileReader.java | 748 ++++ .../classParsing/ClassInfoConstantValue.java | 41 + .../compiler/classParsing/ConstantValue.java | 19 + .../classParsing/ConstantValueArray.java | 53 + .../classParsing/DoubleConstantValue.java | 34 + .../classParsing/EnumConstantValue.java | 57 + .../compiler/classParsing/FieldInfo.java | 39 + .../classParsing/FloatConstantValue.java | 34 + .../classParsing/GenericMethodSignature.java | 82 + .../classParsing/IntegerConstantValue.java | 34 + .../classParsing/LongConstantValue.java | 33 + .../compiler/classParsing/MemberInfo.java | 136 + .../classParsing/MemberInfoExternalizer.java | 176 + .../classParsing/MemberReferenceInfo.java | 55 + .../compiler/classParsing/MethodInfo.java | 248 ++ .../compiler/classParsing/ReferenceInfo.java | 24 + .../classParsing/SignatureParser.java | 237 + .../SignatureParsingException.java | 11 + .../classParsing/StringConstantValue.java | 36 + .../compiler/impl/CompileContextImpl.java | 232 + .../intellij/compiler/impl/CompileDriver.java | 1593 +++++++ .../impl/CompilerContentIterator.java | 42 + .../compiler/impl/CompilerErrorTreeView.java | 106 + .../intellij/compiler/impl/CompilerUtil.java | 179 + .../compiler/impl/CompositeScope.java | 57 + .../impl/ExcludeEntryDescription.java | 81 + .../compiler/impl/FileIndexCompileScope.java | 33 + .../impl/FileProcessingCompilerAdapter.java | 38 + .../FileProcessingCompilerStateCache.java | 88 + .../compiler/impl/FileSetCompileScope.java | 119 + .../compiler/impl/ModuleCompileScope.java | 139 + .../impl/OneProjectItemCompileScope.java | 70 + .../impl/PackagingCompilerAdapter.java | 18 + .../compiler/impl/ProjectCompileScope.java | 41 + .../intellij/compiler/impl/StateCache.java | 57 + .../compiler/impl/TimestampCache.java | 33 + .../compiler/impl/TrackDependenciesScope.java | 33 + .../impl/javaCompiler/BackendCompiler.java | 19 + .../javaCompiler/BackendCompilerWrapper.java | 877 ++++ .../javaCompiler/CompilerParsingThread.java | 140 + .../DummySourceGeneratingCompiler.java | 111 + .../DummyTransformingCompiler.java | 58 + .../impl/javaCompiler/JavaCompiler.java | 90 + .../impl/javaCompiler/JavacCompiler.java | 328 ++ .../impl/javaCompiler/JikesCompiler.java | 196 + .../impl/javaCompiler/ModuleChunk.java | 228 + .../impl/javaCompiler/OutputItemImpl.java | 39 + .../resourceCompiler/ResourceCompiler.java | 218 + .../impl/rmiCompiler/RmicCompiler.java | 452 ++ .../compiler/make/AnnotationTargets.java | 33 + .../intellij/compiler/make/BoundsParser.java | 67 + .../com/intellij/compiler/make/Cache.java | 1046 +++++ .../make/CacheCorruptedException.java | 25 + .../intellij/compiler/make/CacheUtils.java | 211 + .../compiler/make/CachingSearcher.java | 55 + .../compiler/make/ChangeDescription.java | 9 + .../ChangedConstantsDependencyProcessor.java | 240 + ...gedRetentionPolicyDependencyProcessor.java | 86 + .../compiler/make/ClassInfoProcessor.java | 16 + .../intellij/compiler/make/Dependency.java | 89 + .../compiler/make/DependencyCache.java | 737 ++++ .../make/DependencyCacheNavigator.java | 70 + .../compiler/make/DependencyProcessor.java | 903 ++++ .../compiler/make/FieldChangeDescription.java | 25 + .../com/intellij/compiler/make/MakeUtil.java | 255 ++ .../make/MethodChangeDescription.java | 68 + .../compiler/make/RetentionPolicies.java | 27 + .../compiler/make/SourceFileFinder.java | 88 + .../compiler/options/ComparingUtils.java | 33 + .../options/CompilerConfigurable.java | 70 + .../options/CompilerUIConfigurable.java | 207 + .../compiler/options/JavaCompilersTab.java | 112 + .../compiler/options/JavacConfigurable.java | 87 + .../compiler/options/JikesConfigurable.java | 89 + .../compiler/options/RmicConfigurable.java | 89 + .../progress/CompilerProgressDialog.java | 145 + .../progress/CompilerProgressIndicator.java | 493 +++ .../com/intellij/debugger/DebugException.java | 10 + .../debugger/DebuggerInvocationUtil.java | 81 + .../intellij/debugger/DebuggerManagerEx.java | 41 + .../debugger/EvaluatingComputable.java | 12 + .../source/com/intellij/debugger/HelpID.java | 13 + .../com/intellij/debugger/InstanceFilter.java | 70 + .../debugger/actions/AddToWatchAction.java | 107 + .../actions/AdjustArrayRangeAction.java | 76 + .../debugger/actions/AutoRendererAction.java | 36 + .../debugger/actions/CopyValueAction.java | 87 + .../actions/CustomizeContextViewAction.java | 55 + .../actions/CustomizeThreadsViewAction.java | 26 + .../debugger/actions/DebuggerAction.java | 122 + .../debugger/actions/DebuggerActions.java | 33 + .../actions/EditFrameSourceAction.java | 19 + .../debugger/actions/EditSourceAction.java | 118 + .../debugger/actions/EditWatchAction.java | 37 + .../debugger/actions/EvaluateAction.java | 127 + .../debugger/actions/ExportThreadsAction.java | 71 + .../debugger/actions/ForceStepIntoAction.java | 33 + .../debugger/actions/ForceStepOverAction.java | 37 + .../debugger/actions/FreezeThreadAction.java | 62 + .../actions/GotoFrameSourceAction.java | 44 + .../debugger/actions/HotSwapAction.java | 52 + .../debugger/actions/InspectAction.java | 105 + .../debugger/actions/JumpToObjectAction.java | 116 + .../debugger/actions/NewWatchAction.java | 28 + .../debugger/actions/PauseAction.java | 32 + .../debugger/actions/PlaceInDocument.java | 13 + .../debugger/actions/PopFrameAction.java | 105 + .../debugger/actions/QuickEvaluateAction.java | 56 + .../actions/RemoveAllWatchesAction.java | 31 + .../debugger/actions/RemoveWatchAction.java | 53 + .../debugger/actions/ResumeAction.java | 34 + .../debugger/actions/ResumeThreadAction.java | 59 + .../debugger/actions/RunToCursorAction.java | 70 + .../debugger/actions/SetValueAction.java | 469 ++ .../actions/ShowExecutionPointAction.java | 31 + .../debugger/actions/ShowFrameAction.java | 27 + .../debugger/actions/StepIntoAction.java | 32 + .../debugger/actions/StepOutAction.java | 33 + .../debugger/actions/StepOverAction.java | 33 + .../actions/ThrowDebugExceptionAction.java | 17 + .../ToggleBreakpointEnabledAction.java | 75 + .../actions/ToggleFieldBreakpointAction.java | 163 + .../actions/ToggleLineBreakpointAction.java | 91 + .../actions/ToggleMethodBreakpointAction.java | 125 + .../debugger/actions/ViewAsGroup.java | 149 + .../actions/ViewBreakpointsAction.java | 64 + .../SurroundWithRuntimeCastHandler.java | 139 + .../engine/CompoundPositionManager.java | 85 + .../intellij/debugger/engine/ContextUtil.java | 181 + .../engine/DebugProcessAdapterImpl.java | 65 + .../debugger/engine/DebugProcessEvents.java | 402 ++ .../debugger/engine/DebugProcessImpl.java | 1517 +++++++ .../engine/DebuggerManagerThreadImpl.java | 243 ++ .../com/intellij/debugger/engine/JVMName.java | 19 + .../intellij/debugger/engine/JVMNameUtil.java | 288 ++ .../debugger/engine/PositionManagerImpl.java | 244 ++ .../engine/RemoteDebugProcessHandler.java | 55 + .../debugger/engine/RemoteStateState.java | 66 + .../intellij/debugger/engine/RequestHint.java | 151 + .../debugger/engine/SuspendContextImpl.java | 171 + .../engine/SuspendContextRunnable.java | 12 + .../debugger/engine/SuspendManager.java | 31 + .../debugger/engine/SuspendManagerImpl.java | 280 ++ .../debugger/engine/SuspendManagerUtil.java | 174 + .../debugger/engine/VMEventListener.java | 13 + .../evaluation/DebuggerHighlightFilter.java | 53 + .../evaluation/EvaluateRuntimeException.java | 20 + .../evaluation/EvaluationContextImpl.java | 73 + .../engine/evaluation/EvaluationListener.java | 17 + .../evaluation/TextWithImportsImpl.java | 138 + .../expression/ArrayAccessEvaluator.java | 84 + .../expression/ArrayInitializerEvaluator.java | 35 + .../expression/AssignmentEvaluator.java | 70 + .../expression/BinaryExpressionEvaluator.java | 357 ++ .../expression/BlockStatementEvaluator.java | 33 + .../BreakContinueStatementEvaluator.java | 36 + .../evaluation/expression/BreakException.java | 24 + .../expression/ClassObjectEvaluator.java | 31 + .../expression/CodeFragmentEvaluator.java | 113 + .../ConditionalExpressionEvaluator.java | 37 + .../expression/ContinueException.java | 23 + .../evaluation/expression/Evaluator.java | 22 + .../expression/EvaluatorBuilderImpl.java | 812 ++++ .../expression/ExpressionEvaluatorImpl.java | 65 + .../evaluation/expression/FieldEvaluator.java | 163 + .../expression/ForStatementEvaluator.java | 82 + .../expression/IfStatementEvaluator.java | 55 + .../expression/InspectArrayItem.java | 13 + .../evaluation/expression/InspectEntity.java | 9 + .../evaluation/expression/InspectField.java | 14 + .../evaluation/expression/InspectLocal.java | 16 + .../expression/InstanceofEvaluator.java | 58 + .../expression/LiteralEvaluator.java | 46 + .../expression/LocalVariableEvaluator.java | 107 + .../evaluation/expression/MapStack.java | 59 + .../expression/MethodEvaluator.java | 103 + .../expression/NewArrayInstanceEvaluator.java | 135 + .../expression/NewClassInstanceEvaluator.java | 70 + .../expression/PostfixOperationEvaluator.java | 45 + .../SyntheticVariableEvaluator.java | 58 + .../evaluation/expression/ThisEvaluator.java | 61 + .../expression/TypeCastEvaluator.java | 62 + .../evaluation/expression/TypeEvaluator.java | 36 + .../expression/UnaryExpressionEvaluator.java | 72 + .../expression/WhileStatementEvaluator.java | 62 + .../engine/events/DebuggerCommandImpl.java | 31 + .../events/DebuggerContextCommandImpl.java | 53 + .../events/SuspendContextCommandImpl.java | 45 + .../requests/LocatableEventRequestor.java | 19 + .../engine/requests/RequestManagerImpl.java | 409 ++ .../impl/CloseWorkerThreadException.java | 11 + .../debugger/impl/DebuggerContextImpl.java | 154 + .../impl/DebuggerContextListener.java | 16 + .../debugger/impl/DebuggerContextUtil.java | 42 + .../debugger/impl/DebuggerManagerImpl.java | 449 ++ .../impl/DebuggerManagerListener.java | 15 + .../debugger/impl/DebuggerSession.java | 465 ++ .../debugger/impl/DebuggerStateManager.java | 67 + .../debugger/impl/DebuggerUtilsEx.java | 612 +++ .../debugger/impl/DebuggerUtilsImpl.java | 113 + .../intellij/debugger/impl/EventQueue.java | 101 + .../impl/EventQueueClosedException.java | 11 + ...cDebuggerParametersRunnerConfigurable.java | 140 + .../debugger/impl/GenericDebuggerRunner.java | 133 + .../impl/GenericDebuggerRunnerSettings.java | 89 + .../intellij/debugger/impl/HotSwapFile.java | 16 + .../debugger/impl/HotSwapManager.java | 175 + .../debugger/impl/HotSwapProgress.java | 106 + .../debugger/impl/InvokeAndWaitEvent.java | 15 + .../debugger/impl/InvokeAndWaitEventImpl.java | 29 + .../debugger/impl/InvokeAndWaitThread.java | 30 + .../intellij/debugger/impl/InvokeThread.java | 133 + .../debugger/impl/MultiProcessCommand.java | 53 + .../intellij/debugger/impl/PositionUtil.java | 28 + .../debugger/impl/ReloadClassesWorker.java | 297 ++ .../impl/SimpleStackFrameContext.java | 31 + .../impl/descriptors/data/ArrayItemData.java | 64 + .../impl/descriptors/data/DescriptorData.java | 38 + .../impl/descriptors/data/DescriptorKey.java | 11 + .../impl/descriptors/data/DisplayKey.java | 14 + .../impl/descriptors/data/FieldData.java | 47 + .../impl/descriptors/data/LocalData.java | 37 + .../descriptors/data/SimpleDisplayKey.java | 25 + .../impl/descriptors/data/StackFrameData.java | 42 + .../impl/descriptors/data/StaticData.java | 50 + .../descriptors/data/StaticFieldData.java | 42 + .../impl/descriptors/data/ThisData.java | 49 + .../impl/descriptors/data/ThreadData.java | 37 + .../descriptors/data/ThreadGroupData.java | 38 + .../descriptors/data/UserExpressionData.java | 48 + .../com/intellij/debugger/jdi/JdiProxy.java | 35 + .../com/intellij/debugger/jdi/JdiTimer.java | 12 + .../debugger/jdi/LocalVariableProxyImpl.java | 66 + .../jdi/ObjectReferenceProxyImpl.java | 124 + .../debugger/jdi/StackFrameProxyImpl.java | 297 ++ .../debugger/jdi/StringReferenceProxy.java | 34 + .../jdi/ThreadGroupReferenceProxyImpl.java | 88 + .../jdi/ThreadReferenceProxyImpl.java | 186 + .../debugger/jdi/VirtualMachineProxyImpl.java | 457 ++ .../settings/ArrayRendererConfigurable.java | 111 + .../settings/CompositeConfigurable.java | 67 + .../debugger/settings/DebuggerColors.java | 11 + .../settings/DebuggerConfigurable.java | 58 + .../settings/DebuggerGeneralConfigurable.java | 161 + .../debugger/settings/DebuggerSettings.java | 139 + .../settings/NodeRendererSettingsImpl.java | 214 + .../settings/ThreadsViewConfigurable.java | 73 + .../settings/ThreadsViewSettings.java | 53 + .../settings/ViewsGeneralConfigurable.java | 119 + .../settings/ViewsGeneralSettings.java | 80 + .../debugger/ui/ClassFilterEditor.java | 334 ++ .../ui/ClassFilterEditorAddDialog.java | 100 + .../debugger/ui/CompletedInputDialog.java | 67 + .../debugger/ui/CompletedInputTextField.java | 11 + .../debugger/ui/DebuggerEditorImpl.java | 128 + .../ui/DebuggerExpressionComboBox.java | 179 + .../debugger/ui/DebuggerPanelsManager.java | 155 + .../intellij/debugger/ui/DebuggerRecents.java | 56 + .../debugger/ui/DebuggerSessionTab.java | 451 ++ .../debugger/ui/DebuggerStatementEditor.java | 107 + .../debugger/ui/EditorEvaluationCommand.java | 75 + .../debugger/ui/EvaluationDialog.java | 199 + .../debugger/ui/EvaluatorRunnable.java | 12 + .../intellij/debugger/ui/ExportDialog.java | 243 ++ .../ui/ExpressionEvaluationDialog.java | 108 + .../intellij/debugger/ui/GetJPDADialog.java | 60 + .../debugger/ui/HotSwapProgressImpl.java | 95 + .../com/intellij/debugger/ui/HotSwapUI.java | 180 + .../debugger/ui/InstanceFilterEditor.java | 44 + .../debugger/ui/PositionHighlighter.java | 354 ++ .../debugger/ui/RunHotswapDialog.java | 161 + .../ui/StatementEvaluationDialog.java | 137 + .../com/intellij/debugger/ui/ValueHint.java | 322 ++ .../debugger/ui/ValueLookupManager.java | 134 + .../debugger/ui/WeakMouseListener.java | 26 + .../debugger/ui/WeakMouseMotionListener.java | 26 + .../breakpoints/AddFieldBreakpointDialog.java | 121 + .../breakpoints/AnyExceptionBreakpoint.java | 44 + .../debugger/ui/breakpoints/Breakpoint.java | 265 ++ .../ui/breakpoints/BreakpointManager.java | 772 ++++ .../BreakpointManagerListener.java | 12 + .../BreakpointNameCellRenderer.java | 38 + .../ui/breakpoints/BreakpointPanel.java | 245 ++ .../BreakpointPropertiesPanel.java | 460 ++ .../ui/breakpoints/BreakpointTableModel.java | 118 + .../BreakpointWithHighlighter.java | 530 +++ ...BreakpointsConfigurationDialogFactory.java | 487 +++ .../breakpoints/EditClassFiltersDialog.java | 79 + .../EditInstanceFiltersDialog.java | 67 + .../ExceptionBreakpointPropertiesPanel.java | 102 + .../ui/breakpoints/FieldBreakpoint.java | 312 ++ .../FieldBreakpointPropertiesPanel.java | 89 + .../ui/breakpoints/FilteredRequestor.java | 173 + .../ui/breakpoints/LineBreakpoint.java | 258 ++ .../LineBreakpointPropertiesPanel.java | 16 + .../ui/breakpoints/MethodBreakpoint.java | 293 ++ .../MethodBreakpointPropertiesPanel.java | 88 + .../ui/impl/DebuggerComboBoxRenderer.java | 42 + .../debugger/ui/impl/DebuggerPanel.java | 140 + .../debugger/ui/impl/DebuggerTreeBase.java | 293 ++ .../ui/impl/DebuggerTreeRenderer.java | 206 + .../debugger/ui/impl/FrameDebuggerTree.java | 151 + .../intellij/debugger/ui/impl/FramePanel.java | 294 ++ .../debugger/ui/impl/InspectDebuggerTree.java | 56 + .../debugger/ui/impl/InspectDialog.java | 66 + .../debugger/ui/impl/InspectPanel.java | 49 + .../debugger/ui/impl/MainWatchPanel.java | 97 + .../debugger/ui/impl/ThreadsDebuggerTree.java | 191 + .../debugger/ui/impl/ThreadsPanel.java | 72 + .../intellij/debugger/ui/impl/TipManager.java | 128 + .../com/intellij/debugger/ui/impl/UIUtil.java | 145 + .../debugger/ui/impl/WatchDebuggerTree.java | 121 + .../intellij/debugger/ui/impl/WatchPanel.java | 63 + .../ui/impl/nodes/ArrayIndexHelper.java | 43 + .../ui/impl/nodes/NodeComparator.java | 32 + .../debugger/ui/impl/tree/TreeBuilder.java | 120 + .../ui/impl/tree/TreeBuilderNode.java | 96 + .../watch/ArrayElementDescriptorImpl.java | 68 + .../debugger/ui/impl/watch/DebuggerTree.java | 728 ++++ .../watch/DebuggerTreeNodeExpression.java | 281 ++ .../ui/impl/watch/DebuggerTreeNodeImpl.java | 236 + .../ui/impl/watch/DefaultNodeDescriptor.java | 33 + .../ui/impl/watch/DescriptorTree.java | 54 + .../ui/impl/watch/EvaluationDescriptor.java | 94 + .../ui/impl/watch/FieldDescriptorImpl.java | 130 + .../watch/LocalVariableDescriptorImpl.java | 134 + .../ui/impl/watch/MarkedDescriptorTree.java | 44 + .../ui/impl/watch/MessageDescriptor.java | 59 + .../impl/watch/NodeDescriptorFactoryImpl.java | 184 + .../ui/impl/watch/NodeDescriptorImpl.java | 131 + .../ui/impl/watch/NodeManagerImpl.java | 81 + .../impl/watch/StackFrameDescriptorImpl.java | 135 + .../ui/impl/watch/StaticDescriptorImpl.java | 57 + .../ui/impl/watch/ThisDescriptorImpl.java | 54 + .../ui/impl/watch/ThreadDescriptorImpl.java | 158 + .../impl/watch/ThreadGroupDescriptorImpl.java | 66 + .../watch/UserExpressionDescriptorImpl.java | 71 + .../ui/impl/watch/ValueDescriptorImpl.java | 263 ++ .../ui/impl/watch/WatchItemDescriptor.java | 70 + .../ui/impl/watch/render/ArrayRenderer.java | 187 + .../ui/impl/watch/render/ClassRenderer.java | 198 + .../impl/watch/render/PrimitiveRenderer.java | 127 + .../diagnostic/DefaultIdeaErrorLogger.java | 127 + .../com/intellij/diagnostic/Diagnostic.java | 35 + .../intellij/diagnostic/DialogAppender.java | 79 + .../diagnostic/DropAnErrorAction.java | 22 + .../diagnostic/EAPSendErrorDialog.java | 165 + .../diagnostic/ErrorReportConfigurable.java | 110 + .../intellij/diagnostic/PluginException.java | 33 + .../intellij/diagnostic/ReportMessages.java | 19 + .../source/com/intellij/diff/Block.java | 97 + .../source/com/intellij/diff/FindBlock.java | 51 + .../intellij/dupLocator/util/PsiAnchor.java | 102 + .../errorreport/ErrorReportSender.java | 363 ++ .../intellij/errorreport/bean/ErrorBean.java | 72 + .../errorreport/bean/ExceptionBean.java | 128 + .../errorreport/bean/NotifierBean.java | 47 + .../error/InternalEAPException.java | 14 + .../errorreport/error/NewBuildException.java | 14 + .../error/NoSuchEAPUserException.java | 14 + .../error/NoSuchExceptionException.java | 26 + .../errorreport/error/SendException.java | 14 + .../intellij/errorreport/itn/ITNProxy.java | 294 ++ .../execution/ConfigurationTypeEx.java | 16 + .../com/intellij/execution/ExecutionUtil.java | 189 + .../execution/ExternalizablePath.java | 48 + .../com/intellij/execution/Location.java | 57 + .../com/intellij/execution/PsiLocation.java | 84 + .../execution/RunJavaConfiguration.java | 14 + .../com/intellij/execution/RunManager.java | 58 + .../intellij/execution/RunManagerConfig.java | 31 + .../execution/RuntimeConfiguration.java | 43 + .../execution/SingleClassConfiguration.java | 27 + .../TerminateRemoteProcessDialog.java | 59 + .../actions/BaseRunConfigurationAction.java | 111 + .../actions/ConfigurationContext.java | 113 + .../execution/actions/CreateAction.java | 108 + .../actions/EditRunConfigurationsAction.java | 28 + .../actions/PreferedProducerFind.java | 57 + .../actions/RunConfigurationAction.java | 204 + .../execution/actions/RunContextAction.java | 40 + .../execution/actions/StopAction.java | 55 + .../execution/applet/AppletConfigurable.java | 269 ++ .../execution/applet/AppletConfiguration.java | 318 ++ .../applet/AppletConfigurationType.java | 117 + .../application/ApplicationConfigurable2.java | 56 + .../application/ApplicationConfiguration.java | 150 + .../ApplicationConfigurationProducer.java | 67 + .../ApplicationConfigurationType.java | 121 + .../filters/TextConsoleBuilderImpl.java | 34 + .../impl/ConfigurationSettingsEditor.java | 205 + .../intellij/execution/impl/ConsoleState.java | 86 + .../execution/impl/ConsoleViewImpl.java | 740 ++++ .../impl/DisposedPsiManagerCheck.java | 33 + .../impl/EditConfigurationsDialog.java | 29 + .../execution/impl/ExecutionManagerImpl.java | 136 + .../execution/impl/ExecutionRegistryImpl.java | 186 + .../execution/impl/RunConfigurable.java | 210 + .../intellij/execution/impl/RunDialog.java | 98 + .../execution/impl/RunManagerImpl.java | 413 ++ .../impl/RunnerAndConfigurationSettings.java | 235 + .../impl/SingleConfigurationConfigurable.java | 253 ++ .../impl/TypeTemplatesConfigurable.java | 121 + .../execution/impl/ValidationResult.java | 32 + .../execution/junit/JUnitProcessHandler.java | 120 + .../intellij/execution/junit/JUnitUtil.java | 296 ++ .../junit/ModuleBasedConfiguration.java | 88 + .../execution/junit/RefactoringListeners.java | 180 + .../junit/RuntimeConfigurationProducer.java | 80 + .../com/intellij/execution/junit2/Filter.java | 119 + .../intellij/execution/junit2/Printable.java | 6 + .../intellij/execution/junit2/Printer.java | 21 + .../intellij/execution/junit2/PushReader.java | 57 + .../junit2/SegmentedInputStream.java | 115 + .../BrowseModuleValueActionListener.java | 37 + .../junit2/configuration/ClassBrowser.java | 149 + .../configuration/CommonJavaParameters.java | 93 + .../ConfigurationModuleSelector.java | 97 + .../configuration/RunConfigurationModule.java | 143 + .../execution/junit2/info/MethodLocation.java | 70 + .../junit2/segments/DeferedActionsQueue.java | 7 + .../segments/DeferedActionsQueueImpl.java | 33 + .../junit2/segments/DispatchListener.java | 14 + .../junit2/segments/InputConsumer.java | 12 + .../junit2/segments/PacketExtractorBase.java | 24 + .../junit2/segments/SegmentReader.java | 68 + .../junit2/states/DiffHyperlink.java | 82 + .../junit2/states/MethodLineLocation.java | 23 + .../junit2/states/StackTraceLine.java | 138 + .../junit2/ui/FailedTestsNavigator.java | 149 + .../execution/junit2/ui/PoolOfTestIcons.java | 13 + .../execution/junit2/ui/TestTreeView.java | 84 + .../execution/junit2/ui/TestsUIUtil.java | 60 + .../junit2/ui/actions/TestTreeExpander.java | 47 + .../junit2/ui/actions/ToolbarPanel.java | 122 + .../ui/properties/JUnitPropertyListener.java | 8 + .../properties/ScrollToTestSourceAction.java | 36 + .../execution/remote/RemoteConfigurable.java | 163 + .../execution/remote/RemoteConfiguration.java | 71 + .../remote/RemoteConfigurationType.java | 59 + .../runners/ProcessProxyFactoryImpl.java | 38 + .../execution/runners/ProcessProxyImpl.java | 107 + .../execution/runners/RestartAction.java | 77 + .../execution/runners/RunContentBuilder.java | 150 + .../execution/ui/RunContentManagerImpl.java | 592 +++ .../execution/util/JavaParametersUtil.java | 35 + .../RefactoringElementListenerComposite.java | 30 + .../util/StoringPropertyContainer.java | 50 + .../ApplicabilityFilter.java | 7 + .../FeatureUsageTracker.java | 187 + .../featureStatistics/GroupDescriptor.java | 21 + .../ShowFeatureUsageStatisticsAction.java | 21 + .../ShowFeatureUsageStatisticsDialog.java | 205 + .../ui/AdaptiveTipDialog.java | 88 + .../ui/ProgressTipPanel.java | 153 + .../intellij/find/FindProgressIndicator.java | 68 + .../com/intellij/find/FindSettings.java | 76 + .../source/com/intellij/find/FindUtil.java | 607 +++ .../find/actions/FindInPathAction.java | 26 + .../find/actions/FindUsagesAction.java | 40 + .../find/actions/FindUsagesInFileAction.java | 72 + .../find/actions/ReplaceInPathAction.java | 27 + .../findInProject/FindInProjectManager.java | 180 + .../findUsages/FindClassUsagesDialog.java | 112 + .../findUsages/FindMethodUsagesDialog.java | 102 + .../findUsages/FindPackageUsagesDialog.java | 73 + .../findUsages/FindThrowUsagesDialog.java | 108 + .../find/findUsages/FindUsagesDialog.java | 339 ++ .../find/findUsages/FindUsagesManager.java | 892 ++++ .../find/findUsages/FindUsagesOptions.java | 79 + .../find/findUsages/FindUsagesUtil.java | 599 +++ .../findUsages/FindVariableUsagesDialog.java | 49 + .../PsiElement2UsageTargetAdapter.java | 124 + .../com/intellij/find/impl/FindDialog.java | 798 ++++ .../intellij/find/impl/FindInProjectUtil.java | 337 ++ .../intellij/find/impl/FindManagerImpl.java | 474 ++ .../intellij/find/impl/FindResultImpl.java | 24 + .../intellij/find/impl/FindSettingsImpl.java | 220 + .../source/com/intellij/find/impl/HelpID.java | 18 + .../ReplaceInProjectManager.java | 403 ++ .../intellij/help/impl/HelpManagerImpl.java | 97 + .../intellij/help/impl/IdeaHelpBroker.java | 742 ++++ .../help/impl/IdeaHelpContentViewUI.java | 35 + .../com/intellij/help/impl/IdeaJHelp.java | 39 + .../help/impl/IdeaJHelpContentViewer.java | 31 + .../com/intellij/ide/CopyPasteManagerEx.java | 501 +++ .../ide/GeneralSettingsConfigurable.java | 275 ++ .../source/com/intellij/ide/IconUtilEx.java | 126 + .../com/intellij/ide/IdeEventQueue.java | 396 ++ .../source/com/intellij/ide/IdePopup.java | 10 + .../com/intellij/ide/IdePopupManager.java | 42 + .../source/com/intellij/ide/IdeView.java | 9 + .../ide/MacOSApplicationProvider.java | 100 + .../com/intellij/ide/PasteProvider.java | 14 + .../intellij/ide/RecentProjectsManager.java | 210 + .../com/intellij/ide/SaveAndSyncHandler.java | 227 + .../com/intellij/ide/SwingCleanuper.java | 159 + .../com/intellij/ide/TipOfTheDayManager.java | 64 + .../intellij/ide/actionMacro/ActionMacro.java | 225 + .../actionMacro/ActionMacroConfigurable.java | 51 + .../ActionMacroConfigurationPanel.java | 155 + .../ide/actionMacro/ActionMacroManager.java | 302 ++ .../ide/actionMacro/EditMacrosDialog.java | 21 + .../actionMacro/actions/EditMacrosAction.java | 21 + .../ide/actionMacro/actions/MacrosGroup.java | 29 + .../actions/PlaybackLastMacroAction.java | 21 + .../StartStopMacroRecordingAction.java | 27 + .../com/intellij/ide/actions/AboutAction.java | 291 ++ .../ide/actions/ActivateToolWindowAction.java | 89 + .../ide/actions/AssociateFileType.java | 34 + .../com/intellij/ide/actions/BackAction.java | 24 + .../actions/BaseNavigateToSourceAction.java | 117 + .../ChangeSplitterOrientationAction.java | 33 + .../ChooseComponentsToExportDialog.java | 196 + .../ide/actions/CloneElementAction.java | 35 + .../ide/actions/CloseActiveTabAction.java | 22 + .../ide/actions/CloseAllEditorsAction.java | 38 + .../CloseAllEditorsButActiveAction.java | 40 + .../CloseAllUnmodifiedEditorsAction.java | 68 + .../ide/actions/CloseEditorAction.java | 40 + .../ide/actions/CloseProjectAction.java | 27 + .../ide/actions/CloseTabToolbarAction.java | 17 + .../ide/actions/CloseWindowAction.java | 52 + .../ide/actions/CodeEditorActionGroup.java | 22 + .../ide/actions/CollapseAllAction.java | 12 + .../ide/actions/CommanderViewActionGroup.java | 24 + .../ide/actions/ContextHelpAction.java | 42 + .../com/intellij/ide/actions/CopyAction.java | 25 + .../ide/actions/CopyElementAction.java | 114 + .../intellij/ide/actions/CopyPathsAction.java | 44 + .../ide/actions/CreateClassAction.java | 69 + .../CreateDirectoryOrPackageAction.java | 209 + .../ide/actions/CreateElementActionBase.java | 168 + .../ide/actions/CreateFileAction.java | 76 + .../com/intellij/ide/actions/CutAction.java | 25 + .../intellij/ide/actions/DeleteAction.java | 63 + .../ide/actions/EditFileTemplatesAction.java | 18 + .../ide/actions/EditSourceAction.java | 10 + .../com/intellij/ide/actions/ExitAction.java | 17 + .../intellij/ide/actions/ExpandAllAction.java | 12 + .../ide/actions/ExportSettingsAction.java | 98 + .../ide/actions/ExportToTextFileAction.java | 42 + .../ExportToTextFileToolbarAction.java | 19 + .../ide/actions/ExternalJavaDocAction.java | 66 + .../intellij/ide/actions/ForwardAction.java | 24 + .../intellij/ide/actions/GotoActionBase.java | 46 + .../intellij/ide/actions/GotoClassAction.java | 42 + .../intellij/ide/actions/GotoFileAction.java | 43 + .../intellij/ide/actions/GotoLineAction.java | 42 + .../ide/actions/GotoSymbolAction.java | 34 + .../ide/actions/HelpTopicsAction.java | 12 + .../ide/actions/HideAllToolWindowsAction.java | 56 + .../ide/actions/HideToolWindowAction.java | 50 + .../ide/actions/ImportSettingsAction.java | 136 + .../ide/actions/JumpToLastEditAction.java | 30 + .../ide/actions/JumpToLastWindowAction.java | 34 + .../ide/actions/NewElementAction.java | 53 + .../ide/actions/NewProjectAction.java | 17 + .../ide/actions/NextOccurenceAction.java | 18 + .../actions/NextOccurenceToolbarAction.java | 20 + .../intellij/ide/actions/NextSplitAction.java | 39 + .../intellij/ide/actions/NextTabAction.java | 14 + .../actions/OccurenceNavigatorActionBase.java | 131 + .../intellij/ide/actions/OnlineDocAction.java | 14 + .../intellij/ide/actions/OpenFileAction.java | 161 + .../ide/actions/OpenProjectAction.java | 51 + .../com/intellij/ide/actions/OtherGroup.java | 17 + .../com/intellij/ide/actions/PasteAction.java | 25 + .../ide/actions/PinActiveTabAction.java | 89 + .../intellij/ide/actions/PrevSplitAction.java | 39 + .../ide/actions/PreviousOccurenceAction.java | 18 + .../PreviousOccurenceToolbarAction.java | 20 + .../ide/actions/PreviousTabAction.java | 14 + .../QuickChangeCodeStyleSchemeAction.java | 54 + .../actions/QuickChangeColorSchemeAction.java | 38 + .../ide/actions/QuickChangeKeymapAction.java | 32 + .../ide/actions/QuickChangeLookAndFeel.java | 33 + .../ide/actions/QuickChangeSchemesAction.java | 27 + .../ide/actions/QuickSwitchSchemeAction.java | 72 + .../ide/actions/RecentProjectsGroup.java | 18 + .../com/intellij/ide/actions/RedoAction.java | 50 + .../intellij/ide/actions/RefreshAction.java | 9 + .../ide/actions/ReloadFromDiskAction.java | 72 + .../actions/RestoreDefaultLayoutAction.java | 29 + .../com/intellij/ide/actions/RunGcAction.java | 20 + .../intellij/ide/actions/SaveAllAction.java | 12 + .../ide/actions/SaveFileAsTemplateAction.java | 93 + .../ide/actions/SearchAgainAction.java | 47 + .../ide/actions/SearchBackAction.java | 47 + .../intellij/ide/actions/SelectAllAction.java | 34 + .../intellij/ide/actions/SelectInAction.java | 110 + .../intellij/ide/actions/SelectInContext.java | 260 ++ .../actions/ShowModulePropertiesAction.java | 37 + .../ide/actions/ShowPopupMenuAction.java | 105 + .../ide/actions/ShowRecentFilesAction.java | 190 + .../ide/actions/ShowSettingsAction.java | 27 + .../ide/actions/ShowSettingsUtilImpl.java | 120 + .../intellij/ide/actions/ShowTipsAction.java | 17 + .../com/intellij/ide/actions/SplitAction.java | 40 + .../ide/actions/SplitHorizontalAction.java | 14 + .../ide/actions/SplitVerticalAction.java | 12 + .../ide/actions/StoreDefaultLayoutAction.java | 29 + .../ide/actions/SwapPanelsAction.java | 30 + .../intellij/ide/actions/SyncViewsAction.java | 33 + .../ide/actions/SynchronizeAction.java | 36 + .../ide/actions/TabNavigationActionBase.java | 86 + .../TemplateProjectPropertiesAction.java | 18 + .../ide/actions/ToggleDockModeAction.java | 60 + .../ide/actions/ToggleFloatingModeAction.java | 56 + .../actions/ToggleFullScreenModeAction.java | 98 + .../ide/actions/TogglePinnedModeAction.java | 53 + .../ide/actions/TogglePopupHintsAction.java | 51 + .../ToggleReadOnlyAttributeAction.java | 64 + .../ide/actions/ToolWindowsGroup.java | 134 + .../com/intellij/ide/actions/UndoAction.java | 52 + .../intellij/ide/actions/UnsplitAction.java | 33 + .../ide/actions/UnsplitAllAction.java | 33 + .../ide/actions/ViewSourceAction.java | 10 + .../ide/actions/ViewStatusBarAction.java | 20 + .../ide/actions/ViewStructureAction.java | 98 + .../ide/actions/ViewToolbarAction.java | 18 + .../ide/actions/tree/BaseTreeNodeAction.java | 38 + .../actions/tree/CollapseTreeNodeAction.java | 11 + .../actions/tree/ExpandTreeNodeAction.java | 11 + .../tree/FullyExpandTreeNodeAction.java | 11 + .../com/intellij/ide/bookmarks/Bookmark.java | 37 + .../ide/bookmarks/BookmarkManager.java | 235 + .../ide/bookmarks/BookmarksDialog.java | 364 ++ .../bookmarks/CommanderBookmarksDialog.java | 48 + .../ide/bookmarks/EditorBookmarksDialog.java | 76 + .../actions/GotoBookmarkActionBase.java | 39 + .../bookmarks/actions/NextBookmarkAction.java | 12 + .../actions/PreviousBookmarkAction.java | 12 + .../actions/ToggleBookmarkAction.java | 88 + .../ide/commander/AbstractListBuilder.java | 424 ++ .../commander/ColoredCommanderRenderer.java | 55 + .../com/intellij/ide/commander/Commander.java | 490 +++ .../ide/commander/CommanderHistory.java | 120 + .../ide/commander/CommanderPanel.java | 515 +++ .../commander/CommanderSelectInTarget.java | 75 + .../com/intellij/ide/commander/HelpID.java | 5 + .../ide/commander/ProjectListBuilder.java | 229 + .../ide/errorTreeView/ErrorTreeElement.java | 36 + .../errorTreeView/ErrorTreeElementKind.java | 45 + .../ErrorTreeNodeDescriptor.java | 29 + .../ide/errorTreeView/ErrorViewStructure.java | 218 + .../errorTreeView/ErrorViewTreeBuilder.java | 49 + .../ide/errorTreeView/GroupingElement.java | 48 + .../NavigatableMessageElement.java | 67 + .../errorTreeView/NewErrorTreeRenderer.java | 88 + .../errorTreeView/NewErrorTreeViewPanel.java | 514 +++ .../errorTreeView/SimpleMessageElement.java | 34 + .../actions/TestErrorViewAction.java | 105 + .../actions/TestNewErrorViewAction.java | 23 + .../impl/ErrorTreeViewConfiguration.java | 60 + .../impl/ErrorViewTextExporter.java | 106 + .../ide/fileTemplates/FileTemplate.java | 56 + .../fileTemplates/FileTemplateManager.java | 78 + .../ide/fileTemplates/FileTemplateUtil.java | 394 ++ .../actions/CreateFromTemplateGroup.java | 238 + .../impl/AllFileTemplatesConfigurable.java | 725 +++ .../impl/FileTemplateConfigurable.java | 388 ++ .../impl/FileTemplateDescriptionImpl.java | 20 + .../fileTemplates/impl/FileTemplateImpl.java | 363 ++ .../impl/FileTemplateManagerImpl.java | 871 ++++ .../fileTemplates/impl/FileTemplateTab.java | 60 + .../impl/FileTemplateTabAsList.java | 120 + .../impl/FileTemplateTabAsTree.java | 143 + .../impl/FileTemplateTextLexer.java | 292 ++ .../impl/FileTemplateTokenType.java | 9 + .../ui/ConfigureTemplatesDialog.java | 38 + .../ui/CreateFromTemplateDialog.java | 100 + .../ui/CreateFromTemplatePanel.java | 149 + .../ui/SelectTemplateDialog.java | 100 + .../hierarchy/HierarchyBrowserManager.java | 78 + .../hierarchy/HierarchyNodeDescriptor.java | 78 + .../ide/hierarchy/HierarchyNodeRenderer.java | 26 + .../ide/hierarchy/HierarchyTreeBuilder.java | 171 + .../ide/hierarchy/HierarchyTreeStructure.java | 124 + .../actions/BrowseCallHierarchyAction.java | 95 + .../actions/BrowseMethodHierarchyAction.java | 135 + .../actions/BrowseTypeHierarchyAction.java | 135 + .../hierarchy/call/CallHierarchyBrowser.java | 573 +++ .../call/CallHierarchyNodeDescriptor.java | 139 + .../call/CalleeMethodsTreeStructure.java | 117 + .../call/CallerMethodsTreeStructure.java | 108 + .../method/ImplementMethodAction.java | 18 + .../method/MethodHierarchyBrowser.java | 510 +++ .../method/MethodHierarchyNodeDescriptor.java | 165 + .../method/MethodHierarchyTreeStructure.java | 241 + .../hierarchy/method/MethodHierarchyUtil.java | 65 + .../method/OverrideImplementMethodAction.java | 120 + .../method/OverrideMethodAction.java | 18 + .../type/SubtypesHierarchyTreeStructure.java | 40 + .../SupertypesHierarchyTreeStructure.java | 29 + .../hierarchy/type/TypeHierarchyBrowser.java | 514 +++ .../type/TypeHierarchyNodeDescriptor.java | 67 + .../type/TypeHierarchyTreeStructure.java | 59 + .../ide/highlighter/ArchiveFileType.java | 104 + .../intellij/ide/highlighter/DTDFileType.java | 128 + .../ide/highlighter/GuiFormFileType.java | 104 + .../ide/highlighter/HighlighterFactory.java | 69 + .../ide/highlighter/HtmlFileHighlighter.java | 104 + .../ide/highlighter/HtmlFileType.java | 129 + .../ide/highlighter/JavaClassFileType.java | 118 + .../ide/highlighter/JavaFileHighlighter.java | 136 + .../ide/highlighter/JavaFileType.java | 121 + .../ide/highlighter/ModuleFileType.java | 104 + .../ide/highlighter/ProjectFileType.java | 104 + .../ide/highlighter/UnknownFileType.java | 101 + .../ide/highlighter/WorkspaceFileType.java | 104 + .../ide/highlighter/XHtmlFileType.java | 127 + .../ide/highlighter/XmlFileHighlighter.java | 151 + .../intellij/ide/highlighter/XmlFileType.java | 120 + .../custom/AbstractCustomLexer.java | 108 + .../custom/CustomFileHighlighter.java | 76 + .../custom/CustomFileTypeLexer.java | 81 + .../custom/CustomHighlighterColors.java | 14 + .../custom/PosBufferTokenizer.java | 358 ++ .../ide/highlighter/custom/SyntaxTable.java | 184 + .../highlighter/custom/SyntaxTableLexer.java | 193 + .../impl/CustomFileTypeBraceMatcher.java | 66 + .../custom/impl/CustomFileTypeEditor.java | 315 ++ .../impl/CustomFileTypeQuoteHandler.java | 73 + .../custom/impl/ModifyKeywordDialog.java | 67 + .../custom/tokens/BaseTokenParser.java | 22 + .../custom/tokens/BraceTokenParser.java | 20 + .../custom/tokens/HexNumberParser.java | 33 + .../custom/tokens/IdentifierParser.java | 32 + .../custom/tokens/KeywordParser.java | 107 + .../custom/tokens/LineCommentParser.java | 29 + .../custom/tokens/MultilineCommentParser.java | 39 + .../custom/tokens/NumberParser.java | 75 + .../custom/tokens/PrefixedTokenParser.java | 34 + .../custom/tokens/QuotedStringParser.java | 26 + .../highlighter/custom/tokens/TokenInfo.java | 36 + .../custom/tokens/TokenParser.java | 13 + .../custom/tokens/WhitespaceParser.java | 22 + .../ide/impl/CommonActionsManagerImpl.java | 79 + .../ide/impl/ContentManagerWatcher.java | 64 + .../intellij/ide/impl/DataManagerImpl.java | 243 ++ .../com/intellij/ide/impl/DataValidator.java | 65 + .../ide/impl/EditorHighlighterImpl.java | 140 + .../ide/impl/PackageViewSelectInTarget.java | 73 + .../ide/impl/ProjectPaneSelectInTarget.java | 38 + .../com/intellij/ide/impl/ProjectUtil.java | 215 + .../ide/impl/ProjectViewSelectInTarget.java | 62 + .../ide/impl/StructureViewSelectInTarget.java | 79 + .../ide/impl/StructureViewWrapper.java | 189 + .../ide/impl/dataRules/CopyProviderRule.java | 15 + .../ide/impl/dataRules/CutProviderRule.java | 15 + .../ide/impl/dataRules/FileEditorRule.java | 19 + .../ide/impl/dataRules/FileTextRule.java | 32 + .../ide/impl/dataRules/GetDataRule.java | 7 + .../ide/impl/dataRules/ModuleRule.java | 43 + .../ide/impl/dataRules/NavigatableRule.java | 29 + .../ide/impl/dataRules/PasteProviderRule.java | 15 + .../ide/impl/dataRules/PasteTargetRule.java | 11 + .../dataRules/ProjectFileDirectoryRule.java | 27 + .../ide/impl/dataRules/PsiFileRule.java | 15 + .../impl/dataRules/VirtualFileArrayRule.java | 165 + .../ide/impl/dataRules/VirtualFileRule.java | 60 + .../ide/macro/ClasspathEntryMacro.java | 30 + .../intellij/ide/macro/ClasspathMacro.java | 23 + .../intellij/ide/macro/ColumnNumberMacro.java | 20 + .../com/intellij/ide/macro/DataAccessor.java | 165 + .../intellij/ide/macro/FileClassMacro.java | 46 + .../com/intellij/ide/macro/FileDirMacro.java | 29 + .../FileDirRelativeToProjectRootMacro.java | 34 + .../FileDirRelativeToProjectRootMacro2.java | 21 + .../FileDirRelativeToSourcepathMacro.java | 33 + .../FileDirRelativeToSourcepathMacro2.java | 21 + .../com/intellij/ide/macro/FileExtMacro.java | 22 + .../com/intellij/ide/macro/FileFQPackage.java | 20 + .../com/intellij/ide/macro/FileNameMacro.java | 22 + .../ide/macro/FileNameWithoutExtension.java | 22 + .../intellij/ide/macro/FilePackageMacro.java | 21 + .../com/intellij/ide/macro/FilePathMacro.java | 22 + .../FilePathRelativeToProjectRootMacro.java | 29 + .../FilePathRelativeToProjectRootMacro2.java | 21 + .../FilePathRelativeToSourcepathMacro.java | 29 + .../FilePathRelativeToSourcepathMacro2.java | 21 + .../ide/macro/FileRelativeDirMacro.java | 35 + .../ide/macro/FileRelativeDirMacro2.java | 21 + .../ide/macro/FileRelativePathMacro.java | 27 + .../ide/macro/FileRelativePathMacro2.java | 21 + .../intellij/ide/macro/JavaDocPathMacro.java | 32 + .../com/intellij/ide/macro/JdkPathMacro.java | 37 + .../intellij/ide/macro/LineNumberMacro.java | 29 + .../source/com/intellij/ide/macro/Macro.java | 64 + .../com/intellij/ide/macro/MacroManager.java | 142 + .../com/intellij/ide/macro/MacrosDialog.java | 208 + .../intellij/ide/macro/OutputPathMacro.java | 60 + .../ide/macro/ProjectFileDirMacro.java | 29 + .../ide/macro/ProjectFilePathMacro.java | 17 + .../intellij/ide/macro/ProjectNameMacro.java | 28 + .../intellij/ide/macro/ProjectPathMacro.java | 23 + .../com/intellij/ide/macro/PromptMacro.java | 24 + .../ide/macro/SecondQueueExpandMacro.java | 4 + .../ide/macro/SourcepathEntryMacro.java | 31 + .../intellij/ide/macro/SourcepathMacro.java | 23 + .../plugins/AvailablePluginsTableModel.java | 44 + .../plugins/InstalledPluginsTableModel.java | 23 + .../plugins/PluginDescriptorComparator.java | 60 + .../intellij/ide/plugins/PluginInstaller.java | 174 + .../intellij/ide/plugins/PluginManager.java | 584 +++ .../ide/plugins/PluginManagerColumnInfo.java | 385 ++ .../plugins/PluginManagerConfigurable.java | 153 + .../ide/plugins/PluginManagerMain.java | 942 ++++ .../com/intellij/ide/plugins/PluginNode.java | 281 ++ .../com/intellij/ide/plugins/PluginTable.java | 72 + .../ide/plugins/PluginTableModel.java | 73 + .../ide/plugins/RepositoryContentHandler.java | 116 + .../ide/plugins/RepositoryHelper.java | 238 + .../ide/plugins/SortableProvider.java | 15 + .../ide/plugins/cl/PluginClassLoader.java | 136 + .../projectView/BaseProjectTreeBuilder.java | 118 + .../CompositePsiClasChildrenSource.java | 21 + .../com/intellij/ide/projectView/HelpID.java | 5 + .../intellij/ide/projectView/ProjectView.java | 59 + .../ProjectViewPsiTreeChangeListener.java | 96 + .../projectView/PsiClassChildrenSource.java | 55 + .../actions/ChangeProjectViewAction.java | 32 + .../actions/ProjectViewActionGroup.java | 24 + .../impl/AbstractProjectTreeStructure.java | 46 + .../impl/AbstractProjectViewPSIPane.java | 280 ++ .../impl/AbstractProjectViewPane.java | 167 + .../ide/projectView/impl/AbstractUrl.java | 39 + .../impl/ClassesTreeStructureProvider.java | 65 + .../ide/projectView/impl/DirectoryUrl.java | 48 + .../impl/FormMergerTreeStructureProvider.java | 82 + .../ide/projectView/impl/ModuleGroup.java | 54 + .../ide/projectView/impl/ModuleUrl.java | 34 + .../projectView/impl/MoveModuleToGroup.java | 63 + .../impl/MoveModulesToGroupAction.java | 57 + .../ide/projectView/impl/PackageViewPane.java | 215 + .../ProjectAbstractTreeStructureBase.java | 34 + .../projectView/impl/ProjectTreeBuilder.java | 96 + .../impl/ProjectTreeStructure.java | 55 + .../ide/projectView/impl/ProjectViewImpl.java | 1189 +++++ .../ide/projectView/impl/ProjectViewPane.java | 106 + .../ide/projectView/impl/ProjectViewTree.java | 34 + .../projectView/impl/RenameModuleHandler.java | 110 + .../impl/nodes/AbstractModuleNode.java | 72 + .../impl/nodes/AbstractProjectNode.java | 99 + .../projectView/impl/nodes/BasePsiNode.java | 115 + .../projectView/impl/nodes/ClassTreeNode.java | 70 + .../ide/projectView/impl/nodes/Form.java | 54 + .../ide/projectView/impl/nodes/FormNode.java | 50 + .../impl/nodes/LibraryGroupElement.java | 35 + .../impl/nodes/LibraryGroupNode.java | 83 + .../impl/nodes/ModuleGroupNode.java | 57 + .../impl/nodes/NamedLibraryElement.java | 49 + .../impl/nodes/NamedLibraryElementNode.java | 77 + .../impl/nodes/PackageElement.java | 54 + .../impl/nodes/PackageElementNode.java | 196 + .../projectView/impl/nodes/PackageUtil.java | 571 +++ .../impl/nodes/PackageViewLibrariesNode.java | 107 + .../impl/nodes/PackageViewModuleNode.java | 61 + .../impl/nodes/PackageViewProjectNode.java | 110 + .../impl/nodes/ProjectViewModuleNode.java | 53 + .../impl/nodes/ProjectViewProjectNode.java | 26 + .../impl/nodes/PsiDirectoryNode.java | 50 + .../projectView/impl/nodes/PsiFieldNode.java | 34 + .../projectView/impl/nodes/PsiFileNode.java | 44 + .../projectView/impl/nodes/PsiMethodNode.java | 41 + .../intellij/ide/startup/CacheUpdater.java | 10 + .../com/intellij/ide/startup/FileContent.java | 75 + .../ide/startup/FileSystemSynchronizer.java | 188 + .../startup/StartupActionScriptManager.java | 209 + .../ide/startup/StartupManagerEx.java | 18 + .../ide/startup/impl/StartupManagerImpl.java | 130 + .../ide/structureView/StructureView.java | 13 + .../structureView/StructureViewExtension.java | 38 + .../structureView/StructureViewFactory.java | 23 + .../impl/AddAllMembersProcessor.java | 148 + .../impl/StructureNodeRenderer.java | 139 + .../impl/StructureTreeBuilder.java | 162 + .../impl/StructureViewFactoryImpl.java | 98 + .../impl/StructureViewState.java | 30 + .../impl/VisibilityComparator.java | 41 + .../impl/common/PsiTreeElementBase.java | 87 + .../impl/java/AccessLevelProvider.java | 37 + .../structureView/impl/java/FieldsFilter.java | 23 + .../impl/java/InheritedMembersFilter.java | 30 + .../impl/java/JavaClassTreeElement.java | 72 + .../impl/java/JavaClassTreeElementBase.java | 43 + .../impl/java/JavaFileTreeElement.java | 52 + .../impl/java/JavaFileTreeModel.java | 57 + .../structureView/impl/java/KindSorter.java | 79 + .../impl/java/PropertiesGrouper.java | 39 + .../impl/java/PropertyGroup.java | 170 + .../impl/java/PsiFieldTreeElement.java | 35 + .../impl/java/PsiMethodTreeElement.java | 41 + .../impl/java/PublicElementsFilter.java | 28 + .../impl/java/SuperTypeGroup.java | 93 + .../impl/java/SuperTypesGrouper.java | 60 + .../impl/xml/XmlFileTreeElement.java | 62 + .../impl/xml/XmlStructureViewTreeModel.java | 65 + .../impl/xml/XmlTagTreeElement.java | 62 + .../StructureViewComponent.java | 588 +++ .../newStructureView/TreeActionWrapper.java | 33 + .../newStructureView/TreeActionsOwner.java | 7 + .../newStructureView/TreeModelWrapper.java | 49 + .../ide/todo/AllTodosTreeBuilder.java | 37 + .../ide/todo/AllTodosTreeStructure.java | 38 + .../ide/todo/CurrentFileTodosPanel.java | 81 + .../ide/todo/CurrentFileTodosTreeBuilder.java | 44 + .../todo/CurrentFileTodosTreeStructure.java | 89 + .../com/intellij/ide/todo/FileTree.java | 177 + .../ide/todo/HighlightedRegionProvider.java | 10 + .../ide/todo/SmartTodoItemPointer.java | 54 + .../todo/SmartTodoItemPointerComparator.java | 21 + .../com/intellij/ide/todo/ToDoSettings.java | 5 + .../com/intellij/ide/todo/ToDoSummary.java | 20 + .../ide/todo/TodoCompositeRenderer.java | 54 + .../intellij/ide/todo/TodoConfiguration.java | 138 + .../ide/todo/TodoFileDirComparator.java | 52 + .../com/intellij/ide/todo/TodoFilter.java | 196 + .../com/intellij/ide/todo/TodoPanel.java | 586 +++ .../intellij/ide/todo/TodoPanelSettings.java | 82 + .../intellij/ide/todo/TodoTreeBuilder.java | 694 +++ .../intellij/ide/todo/TodoTreeStructure.java | 230 + .../com/intellij/ide/todo/TodoView.java | 275 ++ .../ide/todo/configurable/FilterDialog.java | 199 + .../todo/configurable/FiltersTableModel.java | 62 + .../ide/todo/configurable/PatternDialog.java | 112 + .../todo/configurable/PatternsTableModel.java | 73 + .../todo/configurable/TodoConfigurable.java | 543 +++ .../TodoPatternTableCellRenderer.java | 39 + .../TodoTypeListCellRenderer.java | 23 + .../TodoTypeTableCellRenderer.java | 25 + .../intellij/ide/todo/nodes/BaseToDoNode.java | 27 + .../ide/todo/nodes/SingleFileToDoNode.java | 31 + .../intellij/ide/todo/nodes/SummaryNode.java | 81 + .../intellij/ide/todo/nodes/ToDoRootNode.java | 40 + .../intellij/ide/todo/nodes/TodoDirNode.java | 184 + .../intellij/ide/todo/nodes/TodoFileNode.java | 147 + .../intellij/ide/todo/nodes/TodoItemNode.java | 144 + .../ide/ui/AppearanceConfigurable.java | 390 ++ .../com/intellij/ide/ui/LafManager.java | 536 +++ .../intellij/ide/ui/LafManagerListener.java | 14 + .../com/intellij/ide/ui/UISettings.java | 195 + .../intellij/ide/ui/UISettingsListener.java | 10 + .../intellij/ide/updates/UpdateChecker.java | 135 + .../com/intellij/ide/util/DeleteDialog.java | 143 + .../com/intellij/ide/util/DeleteHandler.java | 269 ++ .../com/intellij/ide/util/DeleteUtil.java | 163 + .../intellij/ide/util/DirectoryChooser.java | 343 ++ .../util/DirectoryChooserModuleTreeView.java | 175 + .../ide/util/DirectoryChooserView.java | 28 + .../com/intellij/ide/util/DirectoryUtil.java | 85 + .../com/intellij/ide/util/EditSourceUtil.java | 35 + .../com/intellij/ide/util/EditorHelper.java | 27 + .../intellij/ide/util/ElementsChooser.java | 401 ++ .../intellij/ide/util/ExportToFileUtil.java | 212 + .../intellij/ide/util/FQNameCellRenderer.java | 65 + .../ide/util/FileStructureDialog.java | 293 ++ .../ide/util/GotoLineNumberDialog.java | 98 + .../com/intellij/ide/util/JavaUtil.java | 193 + .../com/intellij/ide/util/MemberChooser.java | 933 ++++ .../ide/util/MemberContainerCellRenderer.java | 43 + .../util/NavigationItemListCellRenderer.java | 98 + .../ide/util/PackageChooserDialog.java | 331 ++ .../com/intellij/ide/util/PackageUtil.java | 322 ++ .../ide/util/PropertiesComponentImpl.java | 98 + .../ide/util/PsiClassListCellRenderer.java | 28 + .../ide/util/PsiElementListCellRenderer.java | 94 + .../SuperMethodOrPointcutWarningDialog.java | 86 + .../ide/util/SuperMethodWarningUtil.java | 59 + .../com/intellij/ide/util/TipDialog.java | 56 + .../com/intellij/ide/util/TipPanel.java | 158 + .../com/intellij/ide/util/TipUIUtil.java | 103 + .../ide/util/TreeClassChooserDialog.java | 386 ++ .../ide/util/gotoByName/ChooseByNameBase.java | 912 ++++ .../util/gotoByName/ChooseByNameModel.java | 21 + .../util/gotoByName/ChooseByNamePanel.java | 57 + .../util/gotoByName/ChooseByNamePopup.java | 155 + .../ContributorsBasedGotoByModel.java | 78 + .../DefaultClassNavigationContributor.java | 67 + .../DefaultSymbolNavigationContributor.java | 163 + .../ide/util/gotoByName/GotoClassModel2.java | 82 + .../util/gotoByName/GotoFileCellRenderer.java | 21 + .../ide/util/gotoByName/GotoFileModel.java | 92 + .../gotoByName/GotoSymbolCellRenderer.java | 21 + .../ide/util/gotoByName/GotoSymbolModel2.java | 71 + .../util/projectWizard/JdkChooserPanel.java | 194 + .../ModuleCreationPromptStep.java | 66 + .../util/projectWizard/ModuleTypeStep.java | 317 ++ .../util/projectWizard/NameLocationStep.java | 287 ++ .../util/projectWizard/NamePathComponent.java | 234 + .../util/projectWizard/OutputPathsStep.java | 72 + .../util/projectWizard/ProjectJdkStep.java | 104 + .../util/projectWizard/ProjectNameStep.java | 120 + .../ProjectWizardStepFactoryImpl.java | 39 + .../util/projectWizard/ProjectWizardUtil.java | 37 + .../util/projectWizard/SourcePathsStep.java | 463 ++ .../ide/util/projectWizard/ToolbarPanel.java | 26 + .../scopeChooser/PackageSetChooserCombo.java | 78 + .../util/scopeChooser/ScopeChooserCombo.java | 273 ++ .../util/scopeChooser/ScopeEditorPanel.java | 469 ++ .../util/treeView/AbstractTreeBuilder.java | 802 ++++ .../util/treeView/AbstractTreeStructure.java | 16 + .../treeView/AbstractTreeStructureBase.java | 54 + .../util/treeView/AbstractTreeUpdater.java | 133 + .../ide/util/treeView/AlphaComparator.java | 58 + .../ide/util/treeView/IndexComparator.java | 20 + .../util/treeView/SmartElementDescriptor.java | 63 + .../ide/util/treeView/SourceComparator.java | 46 + .../ide/util/treeView/TreeBuilderUtil.java | 79 + .../ide/util/treeView/TreeViewUtil.java | 78 + .../treeView/XmlDoctypeNodeDescriptor.java | 14 + .../smartTree/CachingChildrenTreeNode.java | 180 + .../util/treeView/smartTree/GroupWrapper.java | 26 + .../smartTree/SmartTreeStructure.java | 53 + .../smartTree/TreeElementWrapper.java | 34 + .../intellij/idea/CommandLineApplication.java | 68 + .../com/intellij/idea/IdeaApplication.java | 134 + .../source/com/intellij/idea/IdeaLogger.java | 158 + .../intellij/idea/IdeaTestApplication.java | 32 + .../source/com/intellij/idea/Launcher.java | 51 + .../com/intellij/idea/LoggerFactory.java | 120 + .../source/com/intellij/idea/SocketLock.java | 169 + .../com/intellij/internal/diGraph/Edge.java | 15 + .../com/intellij/internal/diGraph/Node.java | 18 + .../diGraph/analyzer/GlobalAnalyzer.java | 92 + .../internal/diGraph/analyzer/Mark.java | 14 + .../internal/diGraph/analyzer/MarkedEdge.java | 15 + .../internal/diGraph/analyzer/MarkedNode.java | 15 + .../diGraph/analyzer/OneEndFunctor.java | 12 + .../diGraph/analyzer/TwoEndsFunctor.java | 14 + .../internal/diGraph/impl/EdgeImpl.java | 45 + .../internal/diGraph/impl/NodeImpl.java | 74 + .../internal/encodings/DecodeBytesAction.java | 10 + .../internal/encodings/EncodingViewer.java | 89 + .../internal/psiView/PsiViewerDialog.java | 265 ++ .../internal/psiView/ViewerAction.java | 19 + .../psiView/ViewerNodeDescriptor.java | 28 + .../internal/psiView/ViewerTreeBuilder.java | 34 + .../internal/psiView/ViewerTreeStructure.java | 111 + .../j2ee/extResources/AddEditRemovePanel.java | 183 + .../j2ee/extResources/EditLocationDialog.java | 105 + .../ExternalResourceConfigurable.java | 254 ++ .../ExternalResourceListener.java | 8 + .../j2ee/make/BuildInstructionBase.java | 37 + .../intellij/j2ee/make/BuildRecipeImpl.java | 71 + .../j2ee/make/FileCopyInstructionImpl.java | 144 + .../intellij/j2ee/make/IgnoredFileFilter.java | 22 + .../make/J2EEModuleBuildInstructionImpl.java | 203 + .../make/JarAndCopyBuildInstructionImpl.java | 114 + .../j2ee/module/J2EEModuleContainerImpl.java | 352 ++ .../intellij/j2ee/module/LibraryLinkImpl.java | 355 ++ .../intellij/j2ee/module/ModuleLinkImpl.java | 164 + .../intellij/j2ee/module/OrderEntryInfo.java | 85 + .../j2ee/module/ResolvableElement.java | 36 + .../j2ee/module/TransactionalEditable.java | 14 + .../editor/SplitterProportionsData.java | 84 + .../openapi/ex/ExternalResourceManagerEx.java | 27 + .../impl/ExternalResourceManagerImpl.java | 255 ++ .../openapi/impl/LibrariesManagerImpl.java | 55 + .../j2ee/run/localRun/EnvVariablesTable.java | 203 + .../javadoc/GenerateJavadocDialog.java | 152 + .../intellij/javadoc/JavadocConfigurable.java | 140 + .../javadoc/JavadocConfiguration.java | 315 ++ .../javadoc/JavadocGenerationManager.java | 92 + .../javadoc/JavadocGenerationPanel.java | 114 + .../actions/GenerateJavadocAction.java | 51 + .../intellij/jsp/impl/TldTagDescriptor.java | 141 + .../com/intellij/lexer/BaseHtmlLexer.java | 214 + .../intellij/lexer/DtdHighlightingLexer.java | 96 + .../com/intellij/lexer/EscapedJavaLexer.java | 157 + .../intellij/lexer/HtmlHighlightingLexer.java | 182 + .../source/com/intellij/lexer/HtmlLexer.java | 110 + .../com/intellij/lexer/JavaDocLexer.java | 16 + .../intellij/lexer/JavaHighlightingLexer.java | 35 + .../source/com/intellij/lexer/JavaLexer.java | 398 ++ .../com/intellij/lexer/OldXmlLexer.java | 24 + .../intellij/lexer/StringLiteralLexer.java | 188 + .../lexer/XHtmlHighlightingLexer.java | 11 + .../source/com/intellij/lexer/XHtmlLexer.java | 18 + .../intellij/lexer/XmlHighlightingLexer.java | 116 + .../source/com/intellij/lexer/XmlLexer.java | 17 + .../source/com/intellij/lexer/_HtmlLexer.java | 567 +++ .../source/com/intellij/lexer/_JavaLexer.java | 1873 ++++++++ .../com/intellij/lexer/_OldXmlLexer.java | 1638 +++++++ .../source/com/intellij/lexer/_XmlLexer.java | 845 ++++ .../actionSystem/ex/ActionButtonLook.java | 32 + .../actionSystem/ex/ActionManagerEx.java | 70 + .../actionSystem/ex/AnActionListener.java | 17 + .../actionSystem/ex/DataConstantsEx.java | 78 + .../openapi/actionSystem/ex/QuickList.java | 147 + .../actionSystem/ex/QuickListsManager.java | 200 + .../actionSystem/ex/TimerListener.java | 8 + .../actionSystem/impl/ActionButton.java | 280 ++ .../impl/ActionButtonWithText.java | 80 + .../actionSystem/impl/ActionManagerImpl.java | 719 +++ .../openapi/actionSystem/impl/ActionMenu.java | 192 + .../actionSystem/impl/ActionMenuItem.java | 194 + .../impl/ActionPopupMenuImpl.java | 132 + .../actionSystem/impl/ActionToolbarImpl.java | 561 +++ .../openapi/actionSystem/impl/EmptyIcon.java | 46 + .../impl/IdeaActionButtonLook.java | 59 + .../impl/PresentationFactory.java | 27 + .../actionSystem/impl/ProxyShortcutSet.java | 27 + .../openapi/actionSystem/impl/StubItem.java | 14 + .../openapi/actionSystem/impl/Utils.java | 158 + .../actionSystem/impl/WeakTimerListener.java | 38 + .../openapi/application/ex/ApplicationEx.java | 49 + .../application/ex/ApplicationInfoEx.java | 28 + .../application/ex/ApplicationManagerEx.java | 25 + .../application/ex/DecodeDefaultsUtil.java | 37 + .../openapi/application/ex/PathManagerEx.java | 27 + .../application/impl/ApplicationImpl.java | 920 ++++ .../application/impl/ApplicationInfoImpl.java | 166 + .../application/impl/LaterInvocatorEx.java | 234 + .../application/impl/ModalityStateEx.java | 71 + .../openapi/command/CommandProcessorEx.java | 9 + .../openapi/command/impl/CommandMerger.java | 200 + .../command/impl/CommandProcessorImpl.java | 260 ++ .../command/impl/CurrentEditorProvider.java | 10 + .../impl/DocumentEditingUndoProvider.java | 137 + .../impl/DocumentReferenceByDocument.java | 40 + .../impl/DocumentReferenceByVirtualFile.java | 39 + .../openapi/command/impl/DummyProject.java | 93 + .../openapi/command/impl/EditorAndState.java | 27 + .../command/impl/EditorChangeAction.java | 72 + .../impl/FileOperationsUndoProvider.java | 419 ++ .../impl/FocusBasedCurrentEditorProvider.java | 15 + .../intellij/openapi/command/impl/Redo.java | 40 + .../intellij/openapi/command/impl/Undo.java | 40 + .../openapi/command/impl/UndoManagerImpl.java | 537 +++ .../openapi/command/impl/UndoOrRedo.java | 259 ++ .../command/impl/UndoRedoStacksHolder.java | 137 + .../openapi/command/impl/UndoableGroup.java | 180 + .../command/undo/DocumentReference.java | 43 + .../command/undo/NonUndoableAction.java | 17 + .../openapi/command/undo/UndoManager.java | 34 + .../openapi/command/undo/UndoableAction.java | 28 + .../command/undo/UnexpectedUndoException.java | 8 + .../openapi/compiler/ex/CompileContextEx.java | 15 + .../openapi/compiler/ex/CompilerPathsEx.java | 163 + .../components/ex/ComponentManagerEx.java | 15 + .../components/ex/ComponentRegistrar.java | 9 + .../components/impl/ComponentManagerImpl.java | 539 +++ .../openapi/diff/actions/BaseDiffAction.java | 94 + .../CompareClipboardWithSelection.java | 77 + .../diff/actions/CompareFileWithEditor.java | 110 + .../openapi/diff/actions/CompareFiles.java | 78 + .../openapi/diff/actions/DiffActions.java | 8 + .../diff/actions/DiffWalkerAction.java | 34 + .../diff/actions/IgnoreWhiteSpacesAction.java | 64 + .../diff/actions/MergeActionGroup.java | 56 + .../diff/actions/MergeFilesAction.java | 102 + .../openapi/diff/actions/MergeOperations.java | 177 + .../openapi/diff/actions/NextDiffAction.java | 29 + .../diff/actions/PreviousDiffAction.java | 29 + .../openapi/diff/ex/DiffContentFactory.java | 46 + .../openapi/diff/ex/DiffFragment.java | 64 + .../intellij/openapi/diff/ex/DiffPanelEx.java | 25 + .../openapi/diff/ex/DiffPanelOptions.java | 89 + .../openapi/diff/ex/DiffStatusBar.java | 115 + .../openapi/diff/impl/ComparisonPolicy.java | 221 + .../diff/impl/ContentChangeListener.java | 7 + .../openapi/diff/impl/CurrentLineMarker.java | 58 + .../diff/impl/DiffFragmentBuilder.java | 170 + .../diff/impl/DiffHighliterFactory.java | 7 + .../diff/impl/DiffHighliterFactoryImpl.java | 21 + .../openapi/diff/impl/DiffPanelImpl.java | 326 ++ .../intellij/openapi/diff/impl/DiffRange.java | 28 + .../openapi/diff/impl/DiffSideView.java | 227 + .../openapi/diff/impl/DiffSidesContainer.java | 10 + .../openapi/diff/impl/DiffSplitter.java | 43 + .../diff/impl/DiffToolbarComponent.java | 30 + .../openapi/diff/impl/DiffToolbarImpl.java | 71 + .../intellij/openapi/diff/impl/DiffUtil.java | 76 + .../diff/impl/DiffVersionComponent.java | 8 + .../openapi/diff/impl/EditingSides.java | 10 + .../openapi/diff/impl/EditorSource.java | 34 + .../openapi/diff/impl/FrameWrapper.java | 153 + .../intellij/openapi/diff/impl/Rediffers.java | 98 + .../openapi/diff/impl/TwoSidesContainer.java | 6 + .../diff/impl/external/BaseExternalTool.java | 88 + .../diff/impl/external/BinaryDiffTool.java | 45 + .../diff/impl/external/CompositeDiffTool.java | 48 + .../diff/impl/external/DiffManagerImpl.java | 135 + .../diff/impl/external/DiffOptionsForm.java | 109 + .../diff/impl/external/ExtCompareFiles.java | 106 + .../diff/impl/external/ExtCompareFolders.java | 23 + .../diff/impl/external/FrameDiffTool.java | 110 + .../openapi/diff/impl/fragments/Fragment.java | 18 + .../diff/impl/fragments/FragmentList.java | 37 + .../diff/impl/fragments/FragmentListImpl.java | 87 + .../diff/impl/fragments/InlineFragment.java | 51 + .../diff/impl/fragments/LineBlock.java | 55 + .../diff/impl/fragments/LineFragment.java | 179 + .../impl/highlighting/BufferedStringList.java | 29 + .../diff/impl/highlighting/DiffMarkup.java | 199 + .../impl/highlighting/DiffPanelState.java | 38 + .../impl/highlighting/EditorPlaceHolder.java | 72 + .../diff/impl/highlighting/FragmentSide.java | 85 + .../impl/highlighting/LineBlockDivider.java | 35 + .../diff/impl/highlighting/LineRenderer.java | 30 + .../diff/impl/highlighting/List2D.java | 47 + .../highlighting/SimpleDiffPanelState.java | 91 + .../openapi/diff/impl/highlighting/Util.java | 327 ++ .../diff/impl/incrementalMerge/Change.java | 251 ++ .../impl/incrementalMerge/ChangeCounter.java | 74 + .../impl/incrementalMerge/ChangeList.java | 213 + .../impl/incrementalMerge/ChangeType.java | 131 + .../impl/incrementalMerge/ConflictChange.java | 52 + .../incrementalMerge/DiffRangeMarker.java | 87 + .../impl/incrementalMerge/MergeBuilder.java | 304 ++ .../impl/incrementalMerge/MergeConflict.java | 66 + .../diff/impl/incrementalMerge/MergeList.java | 240 + .../incrementalMerge/MergeSearchHelper.java | 79 + .../impl/incrementalMerge/SimpleChange.java | 64 + .../ui/ApplyNonConflicts.java | 38 + .../impl/incrementalMerge/ui/EditorPlace.java | 146 + .../impl/incrementalMerge/ui/MergePanel2.java | 519 +++ .../ui/OpenPartialDiffAction.java | 69 + .../mergeTool/DiffRequestFactoryImpl.java | 138 + .../diff/impl/mergeTool/MergeRequestImpl.java | 150 + .../diff/impl/mergeTool/MergeTool.java | 53 + .../diff/impl/mergeTool/MergeVersion.java | 98 + .../openapi/diff/impl/processing/ByWord.java | 354 ++ .../diff/impl/processing/DiffCorrection.java | 248 ++ .../processing/DiffFragmentsProcessor.java | 17 + .../diff/impl/processing/DiffPolicy.java | 48 + .../diff/impl/processing/Formatting.java | 21 + .../impl/processing/FragmentsCollector.java | 28 + .../processing/LineFragmentsCollector.java | 65 + .../impl/processing/PreferWholeLines.java | 39 + .../impl/processing/TextCompareProcessor.java | 73 + .../diff/impl/processing/UniteSameType.java | 63 + .../openapi/diff/impl/processing/Word.java | 64 + .../diff/impl/settings/DiffColorsForm.java | 374 ++ .../diff/impl/splitter/DiffDividerPaint.java | 39 + .../diff/impl/splitter/DividerPoligon.java | 109 + .../impl/splitter/FoldingTransformation.java | 74 + .../openapi/diff/impl/splitter/Interval.java | 72 + .../diff/impl/splitter/LineBlocks.java | 206 + .../impl/splitter/LinearTransformation.java | 24 + .../diff/impl/splitter/Transformation.java | 5 + .../openapi/diff/impl/splitter/Trapezium.java | 41 + .../impl/util/ContentDocumentListener.java | 29 + .../openapi/diff/impl/util/ContextLogger.java | 89 + .../openapi/diff/impl/util/DiffDivider.java | 70 + .../impl/util/DiffPanelOutterComponent.java | 150 + .../openapi/diff/impl/util/DocumentUtil.java | 51 + .../openapi/diff/impl/util/FocusDiffSide.java | 9 + .../diff/impl/util/FontSizeSynchronizer.java | 76 + .../diff/impl/util/GutterActionRenderer.java | 22 + .../openapi/diff/impl/util/LabeledEditor.java | 34 + .../diff/impl/util/SyncScrollSupport.java | 158 + .../openapi/diff/impl/util/TextDiffType.java | 67 + .../openapi/diff/impl/util/ThreePanels.java | 47 + .../editor/actions/BackspaceAction.java | 86 + .../openapi/editor/actions/CopyAction.java | 29 + .../openapi/editor/actions/CutAction.java | 31 + .../editor/actions/CutLineEndAction.java | 72 + .../openapi/editor/actions/DeleteAction.java | 105 + .../actions/DeleteLineAtCaretAction.java | 69 + .../editor/actions/DeleteToWordEndAction.java | 61 + .../actions/DeleteToWordStartAction.java | 37 + .../editor/actions/DuplicateAction.java | 55 + .../editor/actions/EditorActionUtil.java | 434 ++ .../actions/EmacsStyleIndentAction.java | 74 + .../openapi/editor/actions/EnterAction.java | 82 + .../openapi/editor/actions/EscapeAction.java | 34 + .../openapi/editor/actions/FindAction.java | 28 + .../editor/actions/FindWordAtCaretAction.java | 36 + .../editor/actions/IndentSelectionAction.java | 69 + .../editor/actions/JoinLinesAction.java | 61 + .../openapi/editor/actions/LineEndAction.java | 26 + .../actions/LineEndWithSelectionAction.java | 26 + .../editor/actions/LineStartAction.java | 26 + .../actions/LineStartWithSelectionAction.java | 26 + .../editor/actions/MoveCaretDownAction.java | 30 + .../MoveCaretDownWithSelectionAction.java | 26 + .../editor/actions/MoveCaretLeftAction.java | 27 + .../MoveCaretLeftWithSelectionAction.java | 27 + .../editor/actions/MoveCaretRightAction.java | 26 + .../MoveCaretRightWithSelectionAction.java | 26 + .../editor/actions/MoveCaretUpAction.java | 31 + .../MoveCaretUpWithSelectionAction.java | 27 + .../actions/MoveDownAndScrollAction.java | 26 + .../MoveDownWithSelectionAndScrollAction.java | 26 + .../editor/actions/MoveUpAndScrollAction.java | 26 + .../MoveUpWithSelectionAndScrollAction.java | 26 + .../editor/actions/MultiplePasteAction.java | 252 ++ .../editor/actions/NextWordAction.java | 26 + .../actions/NextWordWithSelectionAction.java | 26 + .../editor/actions/PageBottomAction.java | 26 + .../PageBottomWithSelectionAction.java | 26 + .../editor/actions/PageDownAction.java | 26 + .../actions/PageDownWithSelectionAction.java | 26 + .../openapi/editor/actions/PageTopAction.java | 26 + .../actions/PageTopWithSelectionAction.java | 26 + .../openapi/editor/actions/PageUpAction.java | 26 + .../actions/PageUpWithSelectionAction.java | 26 + .../openapi/editor/actions/PasteAction.java | 32 + .../editor/actions/PasteFromX11Action.java | 39 + .../editor/actions/PreviousWordAction.java | 26 + .../PreviousWordWithSelectionAction.java | 27 + .../openapi/editor/actions/ReplaceAction.java | 37 + .../editor/actions/ScrollDownAction.java | 26 + .../editor/actions/ScrollToCenterAction.java | 27 + .../editor/actions/ScrollUpAction.java | 26 + .../editor/actions/SelectLineAction.java | 26 + .../actions/SelectWordAtCaretAction.java | 59 + .../editor/actions/SplitLineAction.java | 39 + .../editor/actions/StartNewLineAction.java | 40 + .../openapi/editor/actions/TabAction.java | 80 + .../openapi/editor/actions/TextEndAction.java | 35 + .../actions/TextEndWithSelectionAction.java | 36 + .../editor/actions/TextStartAction.java | 34 + .../actions/TextStartWithSelectionAction.java | 35 + .../editor/actions/ToggleCaseAction.java | 38 + .../actions/ToggleColumnModeAction.java | 43 + .../actions/ToggleInsertStateAction.java | 28 + .../actions/ToggleShowLineNumbersAction.java | 63 + .../actions/ToggleShowWhitespacesAction.java | 41 + .../actions/UnindentSelectionAction.java | 71 + .../actions/UnselectWordAtCaretAction.java | 25 + .../colors/ex/DefaultColorSchemesManager.java | 65 + .../colors/impl/AbstractColorsScheme.java | 295 ++ .../colors/impl/DefaultColorsScheme.java | 63 + .../colors/impl/EditorColorsManagerImpl.java | 295 ++ .../colors/impl/EditorColorsSchemeImpl.java | 74 + .../openapi/editor/ex/DocumentEx.java | 29 + .../editor/ex/EditReadOnlyListener.java | 9 + .../editor/ex/EditorEventMulticasterEx.java | 19 + .../intellij/openapi/editor/ex/EditorEx.java | 99 + .../editor/ex/EditorGutterComponentEx.java | 22 + .../openapi/editor/ex/EditorMarkupModel.java | 18 + .../ex/EditorSettingsExternalizable.java | 281 ++ .../openapi/editor/ex/ErrorStripeAdapter.java | 10 + .../openapi/editor/ex/ErrorStripeEvent.java | 30 + .../editor/ex/ErrorStripeListener.java | 7 + .../editor/ex/FocusChangeListener.java | 13 + .../openapi/editor/ex/FoldingModelEx.java | 19 + .../openapi/editor/ex/Highlighter.java | 12 + .../editor/ex/HighlighterIterator.java | 15 + .../openapi/editor/ex/LineIterator.java | 14 + .../openapi/editor/ex/MarkupModelEx.java | 12 + .../openapi/editor/ex/RangeHighlighterEx.java | 16 + .../openapi/editor/ex/util/EditorUtil.java | 186 + .../editor/ex/util/EmptyHighlighter.java | 79 + .../editor/ex/util/LexerHighlighter.java | 231 + .../openapi/editor/ex/util/SegmentArray.java | 170 + .../editor/ex/util/SegmentArrayWithData.java | 36 + .../openapi/editor/impl/BorderEffect.java | 200 + .../openapi/editor/impl/CaretModelImpl.java | 412 ++ .../openapi/editor/impl/DocumentImpl.java | 706 +++ .../impl/DocumentMarkupModelManager.java | 65 + .../editor/impl/EditorActionManagerImpl.java | 57 + .../editor/impl/EditorComponentImpl.java | 152 + .../editor/impl/EditorFactoryImpl.java | 163 + .../impl/EditorGutterComponentImpl.java | 1169 +++++ .../openapi/editor/impl/EditorImpl.java | 3877 +++++++++++++++++ .../editor/impl/EditorMarkupModelImpl.java | 412 ++ .../openapi/editor/impl/FoldRegionImpl.java | 54 + .../openapi/editor/impl/FoldingModelImpl.java | 555 +++ .../openapi/editor/impl/HighlighterList.java | 87 + .../openapi/editor/impl/IterationState.java | 508 +++ .../editor/impl/LeftHandScrollbarLayout.java | 1040 +++++ .../openapi/editor/impl/LineIteratorImpl.java | 45 + .../intellij/openapi/editor/impl/LineSet.java | 181 + .../openapi/editor/impl/MarkupModelImpl.java | 183 + .../editor/impl/PersistentLineMarker.java | 36 + .../editor/impl/PersistentRangeMarker.java | 56 + .../editor/impl/RangeHighlighterImpl.java | 192 + .../openapi/editor/impl/RangeIterator.java | 146 + .../openapi/editor/impl/RangeMarkerImpl.java | 173 + .../editor/impl/ScrollingModelImpl.java | 485 +++ .../editor/impl/SelectionModelImpl.java | 524 +++ .../openapi/editor/impl/SettingsImpl.java | 306 ++ .../editor/impl/VisibleEditorsTracker.java | 64 + .../editor/impl/event/DocumentEventImpl.java | 173 + .../event/EditorEventMulticasterImpl.java | 117 + .../editor/impl/event/MarkupModelEvent.java | 23 + .../impl/event/MarkupModelListener.java | 7 + .../markup/MarkupEditorFilterFactory.java | 28 + .../fileChooser/actions/FileDeleteAction.java | 101 + .../fileChooser/actions/GotoHomeAction.java | 38 + .../actions/GotoProjectDirectory.java | 42 + .../fileChooser/actions/NewFolderAction.java | 54 + .../fileChooser/ex/FileChooserDialogImpl.java | 297 ++ .../fileChooser/ex/FileNodeDescriptor.java | 56 + .../ex/FileSystemTreeFactoryImpl.java | 67 + .../fileChooser/ex/FileSystemTreeImpl.java | 306 ++ .../fileChooser/ex/RootFileElement.java | 57 + .../impl/FileChooserFactoryImpl.java | 29 + .../fileChooser/impl/FileComparator.java | 41 + .../fileChooser/impl/FileTreeBuilder.java | 101 + .../fileChooser/impl/FileTreeStructure.java | 141 + .../fileEditor/ex/FileEditorManagerEx.java | 103 + .../ex/FileEditorProviderManager.java | 31 + .../fileEditor/ex/IdeDocumentHistory.java | 23 + .../fileEditor/impl/EditorComposite.java | 306 ++ .../fileEditor/impl/EditorHistoryManager.java | 303 ++ .../impl/EditorTabbedContainer.java | 465 ++ .../openapi/fileEditor/impl/EditorWindow.java | 758 ++++ .../impl/EditorWithProviderComposite.java | 56 + .../fileEditor/impl/EditorsSplitters.java | 505 +++ .../impl/FileDocumentManagerImpl.java | 572 +++ .../impl/FileEditorManagerImpl.java | 1208 +++++ .../impl/FileEditorProviderManagerImpl.java | 124 + .../openapi/fileEditor/impl/HistoryEntry.java | 130 + .../impl/IdeDocumentHistoryImpl.java | 509 +++ .../openapi/fileEditor/impl/LoadTextUtil.java | 113 + .../impl/TrailingSpacesStripper.java | 24 + .../impl/text/TextEditorComponent.java | 432 ++ .../fileEditor/impl/text/TextEditorImpl.java | 214 + .../impl/text/TextEditorProvider.java | 264 ++ .../fileEditor/impl/text/TextEditorState.java | 58 + .../openapi/fileTypes/PlainTextFileType.java | 101 + .../openapi/fileTypes/UserBinaryFileType.java | 62 + .../openapi/fileTypes/ex/FakeFileType.java | 62 + .../openapi/fileTypes/ex/FileTypeChooser.java | 131 + .../fileTypes/ex/FileTypeManagerEx.java | 29 + .../fileTypes/impl/FileTypeConfigurable.java | 475 ++ .../fileTypes/impl/FileTypeManagerImpl.java | 811 ++++ .../fileTypes/impl/FileTypeRenderer.java | 27 + .../openapi/keymap/ex/KeymapManagerEx.java | 22 + .../keymap/ex/KeymapManagerListener.java | 7 + .../keymap/ex/WeakKeymapManagerListener.java | 24 + .../openapi/keymap/impl/Converter01.java | 109 + .../openapi/keymap/impl/DefaultKeymap.java | 62 + .../keymap/impl/DefaultKeymapImpl.java | 21 + .../keymap/impl/IdeKeyEventDispatcher.java | 398 ++ .../keymap/impl/IdeMouseEventDispatcher.java | 126 + .../openapi/keymap/impl/KeymapImpl.java | 726 +++ .../keymap/impl/KeymapManagerImpl.java | 242 + .../keymap/impl/MacOSDefaultKeymap.java | 98 + .../openapi/keymap/impl/ui/ActionsTree.java | 456 ++ .../keymap/impl/ui/ActionsTreeUtil.java | 538 +++ .../keymap/impl/ui/EditKeymapsDialog.java | 30 + .../keymap/impl/ui/EditQuickListDialog.java | 50 + .../impl/ui/KeyboardShortcutDialog.java | 284 ++ .../keymap/impl/ui/KeymapConfigurable.java | 59 + .../openapi/keymap/impl/ui/KeymapPanel.java | 930 ++++ .../keymap/impl/ui/MouseShortcutDialog.java | 281 ++ .../keymap/impl/ui/QuickListPanel.java | 320 ++ .../localVcs/impl/LvcsConfigurable.java | 254 ++ .../impl/UpToDateLineNumberProviderImpl.java | 61 + .../openapi/module/JavaModuleType.java | 85 + .../openapi/module/UnknownModuleType.java | 17 + .../impl/ModuleConfigurationStateImpl.java | 38 + .../openapi/module/impl/ModuleImpl.java | 404 ++ .../module/impl/ModuleManagerImpl.java | 772 ++++ .../module/impl/ModulePointerImpl.java | 51 + .../module/impl/ModuleTypeManagerImpl.java | 94 + .../openapi/module/impl/ModuleUtil.java | 148 + .../colors/pages/ColorSettingsPagesImpl.java | 73 + .../colors/pages/CustomColorsPage.java | 117 + .../colors/pages/GeneralColorsPage.java | 112 + .../options/colors/pages/HTMLColorsPage.java | 97 + .../colors/pages/JavaColorSettingsPage.java | 189 + .../options/colors/pages/XMLColorsPage.java | 95 + .../options/ex/ControlPanelMnemonicsUtil.java | 44 + .../ex/ControlPanelSettingsEditor.java | 394 ++ .../options/ex/ExplorerSettingsEditor.java | 532 +++ .../options/ex/IdeConfigurablesGroup.java | 34 + .../ex/ProjectConfigurableWrapper.java | 74 + .../options/ex/ProjectConfigurablesGroup.java | 51 + .../options/ex/SingleConfigurableEditor.java | 165 + .../progress/impl/ProgressManagerImpl.java | 166 + .../util/BlockingProgressIndicator.java | 9 + .../progress/util/ColorProgressBar.java | 220 + .../progress/util/CommandLineProgress.java | 28 + .../util/DispatchThreadProgressWindow.java | 53 + .../progress/util/MaxIntervalCalculator.java | 39 + .../openapi/progress/util/ProgressBar.java | 59 + .../progress/util/ProgressIndicatorBase.java | 175 + .../util/ProgressIndicatorListener.java | 14 + .../ProgressIndicatorListenerAdapter.java | 18 + .../openapi/progress/util/ProgressStream.java | 46 + .../openapi/progress/util/ProgressWindow.java | 375 ++ .../util/ProgressWindowWithNotification.java | 60 + .../progress/util/SmoothProgressAdapter.java | 165 + .../progress/util/StatusBarProgress.java | 114 + .../openapi/project/ex/ProjectEx.java | 23 + .../openapi/project/ex/ProjectManagerEx.java | 30 + .../project/impl/DefineMacrosDialog.java | 110 + .../openapi/project/impl/ProjectImpl.java | 564 +++ .../project/impl/ProjectManagerImpl.java | 696 +++ .../project/impl/ProjectReloadStateImpl.java | 97 + .../impl/UndefinedMacrosConfigurable.java | 75 + .../project/impl/convertors/Convertor01.java | 122 + .../project/impl/convertors/Convertor12.java | 15 + .../project/impl/convertors/Convertor23.java | 95 + .../project/impl/convertors/Convertor34.java | 739 ++++ .../openapi/project/impl/convertors/Util.java | 18 + .../openapi/projectRoots/ex/PathUtilEx.java | 73 + .../openapi/projectRoots/ex/ProjectRoot.java | 13 + .../projectRoots/ex/ProjectRootContainer.java | 31 + .../impl/CompositeProjectRoot.java | 97 + .../projectRoots/impl/JavaSdkImpl.java | 451 ++ .../projectRoots/impl/MockJdkWrapper.java | 82 + .../projectRoots/impl/ProjectJdkImpl.java | 331 ++ .../impl/ProjectJdkTableImpl.java | 151 + .../impl/ProjectRootContainerImpl.java | 251 ++ .../projectRoots/impl/ProjectRootUtil.java | 109 + .../projectRoots/impl/SimpleProjectRoot.java | 104 + .../projectRoots/impl/UnknownSdkType.java | 97 + .../projectRoots/ui/NotifiableSdkModel.java | 15 + .../openapi/projectRoots/ui/PathEditor.java | 381 ++ .../projectRoots/ui/ProjectJdksEditor.java | 52 + .../openapi/projectRoots/ui/SdkEditor.java | 513 +++ .../openapi/projectRoots/ui/Util.java | 43 + .../roots/ex/ProjectRootManagerEx.java | 35 + .../roots/impl/ClonableContentEntry.java | 10 + .../roots/impl/ClonableContentFolder.java | 11 + .../roots/impl/ClonableOrderEntry.java | 11 + .../openapi/roots/impl/ContentEntryImpl.java | 250 ++ .../roots/impl/ContentFolderBaseImpl.java | 73 + .../openapi/roots/impl/DirectoryIndex.java | 17 + .../roots/impl/DirectoryIndexImpl.java | 900 ++++ .../openapi/roots/impl/DirectoryInfo.java | 61 + .../openapi/roots/impl/ExcludeFolderImpl.java | 39 + .../roots/impl/ExcludedOutputFolderImpl.java | 41 + .../openapi/roots/impl/FileIndexImplUtil.java | 22 + .../impl/InheritedJdkOrderEntryImpl.java | 143 + .../roots/impl/LibraryOrderEntryBaseImpl.java | 166 + .../roots/impl/LibraryOrderEntryImpl.java | 237 + .../roots/impl/ModuleFileIndexImpl.java | 135 + .../roots/impl/ModuleJdkOrderEntryImpl.java | 175 + .../impl/ModuleLibraryOrderEntryImpl.java | 146 + .../roots/impl/ModuleLibraryTable.java | 120 + .../roots/impl/ModuleOrderEntryImpl.java | 260 ++ .../roots/impl/ModuleRootEventImpl.java | 21 + .../roots/impl/ModuleRootManagerImpl.java | 502 +++ .../impl/ModuleSourceOrderEntryImpl.java | 125 + .../roots/impl/OldModuleRootsKeeper.java | 60 + .../roots/impl/OrderEntryBaseImpl.java | 25 + .../openapi/roots/impl/OrderEntryFactory.java | 53 + .../openapi/roots/impl/OrderEntryUtil.java | 72 + .../roots/impl/ProjectFileIndexImpl.java | 240 + .../roots/impl/ProjectRootManagerImpl.java | 627 +++ .../roots/impl/RootModelComponentBase.java | 35 + .../openapi/roots/impl/RootModelImpl.java | 1053 +++++ .../roots/impl/RootProviderBaseImpl.java | 23 + .../openapi/roots/impl/SourceFolderImpl.java | 81 + .../roots/impl/WritableOrderEntry.java | 11 + .../libraries/ApplicationLibraryTable.java | 64 + .../roots/impl/libraries/LibraryEx.java | 12 + .../roots/impl/libraries/LibraryImpl.java | 258 ++ .../impl/libraries/LibraryTableBase.java | 211 + .../impl/libraries/LibraryTableImplUtil.java | 33 + .../libraries/LibraryTablesRegistrarImpl.java | 88 + .../impl/libraries/ProjectLibraryTable.java | 33 + .../openapi/roots/ui/LightFilePointer.java | 73 + .../components/ScrollablePanel.java | 49 + .../layout/ComponentOperation.java | 78 + .../ui/componentsList/layout/Orientation.java | 86 + .../layout/OrientedDimensionSum.java | 28 + .../componentsList/layout/SizeProperty.java | 21 + .../layout/VerticalStackLayout.java | 65 + .../configuration/ActionsHeaderComponent.java | 55 + .../configuration/ContentEntriesEditor.java | 616 +++ .../ui/configuration/ContentEntryEditor.java | 302 ++ .../ContentEntryEditorListenerAdapter.java | 35 + .../ContentEntryTreeCellRenderer.java | 107 + .../configuration/ContentEntryTreeEditor.java | 222 + .../ui/configuration/ContentRootPanel.java | 370 ++ ...tModuleConfigurationEditorFactoryImpl.java | 47 + .../DefaultModuleEditorsProvider.java | 39 + .../ui/configuration/FilePathClipper.java | 39 + .../ui/configuration/IconActionComponent.java | 38 + .../roots/ui/configuration/IconSet.java | 44 + .../roots/ui/configuration/JavadocEditor.java | 257 ++ .../LibrariesAlphaComparator.java | 48 + .../configuration/LibraryChooserElement.java | 79 + .../LibraryTableModifiableModelProvider.java | 11 + .../ui/configuration/ModuleCreationInfo.java | 11 + .../roots/ui/configuration/ModuleEditor.java | 409 ++ .../ui/configuration/ModuleEditorState.java | 47 + .../configuration/ModuleElementsEditor.java | 49 + ...oduleLevelConfigurablesEditorProvider.java | 126 + .../configuration/ModulesAlphaComparator.java | 18 + .../ui/configuration/ModulesConfigurable.java | 106 + .../ui/configuration/ModulesConfigurator.java | 676 +++ .../MoveTableRowButtonListener.java | 56 + .../ui/configuration/NamedLibrariesPanel.java | 235 + .../ui/configuration/ResizingWrapper.java | 18 + .../configuration/ScalableIconComponent.java | 54 + .../actions/ContentEntryEditingAction.java | 67 + .../actions/ModuleDeleteProvider.java | 84 + .../actions/ModulesConfigurationAction.java | 37 + .../actions/NewModuleAction.java | 92 + .../actions/ToggleExcludedStateAction.java | 59 + .../actions/ToggleSourcesStateAction.java | 77 + .../libraryEditor/ClassesElement.java | 28 + .../ClassesElementDescriptor.java | 26 + .../libraryEditor/ItemElement.java | 64 + .../libraryEditor/ItemElementDescriptor.java | 29 + .../libraryEditor/JavadocElement.java | 28 + .../JavadocElementDescriptor.java | 26 + .../libraryEditor/LibraryEditor.java | 75 + .../libraryEditor/LibraryElement.java | 42 + .../LibraryElementDescriptor.java | 62 + .../libraryEditor/LibraryFileChooser.java | 145 + .../libraryEditor/LibraryTableEditor.java | 781 ++++ .../LibraryTableTreeBuilder.java | 27 + .../LibraryTableTreeContentElement.java | 5 + .../LibraryTableTreeStructure.java | 154 + .../libraryEditor/LibraryTreeRenderer.java | 34 + .../libraryEditor/LibraryTreeStructure.java | 146 + .../libraryEditor/SourcesElement.java | 28 + .../SourcesElementDescriptor.java | 26 + .../libraryEditor/UrlComparator.java | 11 + .../util/BaseTextCommentCellAppearance.java | 40 + .../openapi/roots/ui/util/CellAppearance.java | 8 + .../roots/ui/util/CellAppearanceUtils.java | 230 + .../roots/ui/util/CompositeAppearance.java | 182 + .../roots/ui/util/HttpUrlCellAppearance.java | 17 + .../ui/util/JarSubfileCellAppearance.java | 23 + .../ui/util/ModifiableCellAppearance.java | 9 + .../ui/util/SimpleTextCellAppearance.java | 47 + .../ui/util/ValidFileCellAppearance.java | 44 + .../watcher/impl/OrderEntryPredicate.java | 13 + .../intellij/openapi/ui/ex/MessagesEx.java | 231 + .../openapi/ui/ex/MultiLineLabel.java | 23 + .../ui/impl/DialogWrapperPeerFactoryImpl.java | 22 + .../ui/impl/DialogWrapperPeerImpl.java | 532 +++ .../intellij/openapi/vcs/FilePathImpl.java | 162 + .../actions/AbstractCommonCheckinAction.java | 320 ++ .../vcs/actions/AbstractVcsAction.java | 113 + .../openapi/vcs/actions/CashedVcsContext.java | 126 + .../vcs/actions/CommonCheckinFilesAction.java | 89 + .../actions/CommonCheckinProjectAction.java | 39 + .../actions/SelectedBlockHistoryAction.java | 69 + .../vcs/actions/ShowChangeMarkerAction.java | 85 + .../actions/ShowNextChangeMarkerAction.java | 23 + .../actions/ShowPrevChangeMarkerAction.java | 21 + .../vcs/actions/TabbedShowHistoryAction.java | 116 + .../openapi/vcs/actions/VcsActionGroup.java | 31 + .../vcs/actions/VcsContextWrapper.java | 201 + .../openapi/vcs/actions/VcsGroupsWrapper.java | 144 + .../openapi/vcs/ex/DocumentWrapper.java | 39 + .../openapi/vcs/ex/LineStatusTracker.java | 740 ++++ .../vcs/ex/ProjectLevelVcsManagerEx.java | 19 + .../com/intellij/openapi/vcs/ex/Range.java | 182 + .../openapi/vcs/ex/RangesBuilder.java | 48 + .../openapi/vcs/history/FileHistoryPanel.java | 1025 +++++ .../history/impl/VcsBlockHistoryDialog.java | 72 + .../vcs/history/impl/VcsHistoryDialog.java | 391 ++ .../vcs/impl/AbstractVcsHelperImpl.java | 441 ++ .../vcs/impl/FileStatusFactoryImpl.java | 97 + .../openapi/vcs/impl/FileStatusImpl.java | 38 + .../vcs/impl/FileStatusManagerImpl.java | 276 ++ .../vcs/impl/ProjectLevelVcsManagerImpl.java | 410 ++ .../vcs/impl/VcsManagerConfigurable.java | 73 + .../VcsManagerPerModuleConfiguration.java | 52 + .../openapi/vcs/readOnlyHandler/FileInfo.java | 110 + .../vcs/readOnlyHandler/HandleType.java | 58 + .../ReadonlyStatusHandlerImpl.java | 102 + .../vcs/ui/exclude/SortedComboBoxModel.java | 29 + .../update/AbstractCommonUpdateAction.java | 319 ++ .../openapi/vcs/update/AbstractTreeNode.java | 80 + .../openapi/vcs/update/ActionInfo.java | 94 + .../CommonStatusFileOrDirectoryAction.java | 7 + .../vcs/update/CommonStatusProjectAction.java | 7 + .../CommonUpdateFileOrDirectoryAction.java | 41 + .../vcs/update/CommonUpdateProjectAction.java | 41 + .../openapi/vcs/update/DirectoryTreeNode.java | 89 + .../vcs/update/FileOrDirectoryTreeNode.java | 96 + .../openapi/vcs/update/FileTreeNode.java | 53 + .../openapi/vcs/update/GroupByPackages.java | 71 + .../openapi/vcs/update/GroupTreeNode.java | 164 + .../openapi/vcs/update/RestoreUpdateTree.java | 108 + .../openapi/vcs/update/ScopeInfo.java | 73 + .../openapi/vcs/update/UpdateInfo.java | 94 + .../openapi/vcs/update/UpdateInfoTree.java | 228 + .../update/UpdateOrStatusOptionsDialog.java | 100 + .../openapi/vcs/update/UpdateRootNode.java | 46 + .../vcs/update/UpdateTreeCellRenderer.java | 19 + .../vfs/ex/VirtualFileManagerAdapter.java | 10 + .../openapi/vfs/ex/VirtualFileManagerEx.java | 29 + .../openapi/vfs/ex/dummy/DummyFileSystem.java | 72 + .../vfs/ex/dummy/VirtualFileDataImpl.java | 97 + .../ex/dummy/VirtualFileDirectoryImpl.java | 81 + .../openapi/vfs/ex/dummy/VirtualFileImpl.java | 91 + .../openapi/vfs/ex/http/HttpFileSystem.java | 46 + .../openapi/vfs/ex/http/VirtualFileImpl.java | 135 + .../vfs/impl/VirtualFileManagerImpl.java | 412 ++ .../impl/VirtualFilePointerContainerImpl.java | 247 ++ .../vfs/impl/VirtualFilePointerImpl.java | 156 + .../impl/VirtualFilePointerManagerImpl.java | 278 ++ .../vfs/impl/jar/JarFileSystemImpl.java | 285 ++ .../vfs/impl/local/LocalFileSystemImpl.java | 682 +++ .../vfs/impl/local/VirtualFileImpl.java | 838 ++++ .../vfs/impl/local/VirtualFileInfoAction.java | 64 + .../wm/ex/IdeFocusTraversalPolicy.java | 120 + .../wm/ex/LayoutFocusTraversalPolicyExt.java | 91 + .../intellij/openapi/wm/ex/StatusBarEx.java | 32 + .../intellij/openapi/wm/ex/ToolWindowEx.java | 30 + .../wm/ex/ToolWindowManagerAdapter.java | 12 + .../openapi/wm/ex/ToolWindowManagerEx.java | 33 + .../wm/ex/ToolWindowManagerListener.java | 15 + .../openapi/wm/ex/WindowManagerEx.java | 110 + .../intellij/openapi/wm/impl/ActiveStack.java | 91 + .../openapi/wm/impl/CommandProcessor.java | 51 + .../openapi/wm/impl/DesktopLayout.java | 318 ++ .../openapi/wm/impl/FloatingDecorator.java | 353 ++ .../openapi/wm/impl/HierarchyWatcher.java | 51 + .../intellij/openapi/wm/impl/IdeFrame.java | 166 + .../intellij/openapi/wm/impl/IdeMenuBar.java | 167 + .../intellij/openapi/wm/impl/IdeRootPane.java | 137 + .../openapi/wm/impl/InternalDecorator.java | 793 ++++ .../wm/impl/InternalDecoratorListener.java | 25 + .../intellij/openapi/wm/impl/SideStack.java | 70 + .../com/intellij/openapi/wm/impl/Stripe.java | 126 + .../openapi/wm/impl/StripeButton.java | 172 + .../openapi/wm/impl/StripeButtonUI.java | 158 + .../com/intellij/openapi/wm/impl/Surface.java | 134 + .../openapi/wm/impl/TestWindowManager.java | 142 + .../intellij/openapi/wm/impl/TitlePanel.java | 167 + .../openapi/wm/impl/ToolWindowImpl.java | 178 + .../wm/impl/ToolWindowManagerImpl.java | 1207 +++++ .../openapi/wm/impl/ToolWindowsPane.java | 716 +++ .../openapi/wm/impl/VisibilityWatcher.java | 58 + .../intellij/openapi/wm/impl/WindowInfo.java | 341 ++ .../openapi/wm/impl/WindowManagerImpl.java | 501 +++ .../openapi/wm/impl/WindowWatcher.java | 289 ++ .../wm/impl/commands/ApplyWindowInfoCmd.java | 38 + .../wm/impl/commands/FinalizableCommand.java | 16 + .../wm/impl/commands/InvokeLaterCmd.java | 23 + .../RequestFocusInEditorComponentCmd.java | 78 + .../commands/RequestFocusInToolWindowCmd.java | 103 + .../wm/impl/commands/UpdateRootPaneCmd.java | 28 + .../wm/impl/status/MemoryUsagePanel.java | 166 + .../openapi/wm/impl/status/PositionPanel.java | 43 + .../openapi/wm/impl/status/StatusBarImpl.java | 253 ++ .../openapi/wm/impl/status/TextPanel.java | 134 + .../wm/impl/status/TogglePopupHintsPanel.java | 130 + .../status/ToggleReadOnlyAttributePanel.java | 56 + .../DependenciesBuilder.java | 144 + .../packageDependencies/DependencyRule.java | 77 + .../DependencyUISettings.java | 36 + .../DependencyValidationManager.java | 144 + .../FindDependencyUtil.java | 45 + .../actions/AnalyzeDependenciesAction.java | 15 + .../actions/AnalyzeDependenciesHandler.java | 28 + .../packageSet/PackageSetFactoryImpl.java | 187 + .../ui/DependecyNodeComparator.java | 10 + .../ui/DependenciesPanel.java | 584 +++ .../ui/DependencyConfigurable.java | 245 ++ .../packageDependencies/ui/FileNode.java | 89 + .../ui/GeneralGroupNode.java | 56 + .../packageDependencies/ui/LibraryNode.java | 62 + .../packageDependencies/ui/ModuleNode.java | 60 + .../ui/PackageDependenciesNode.java | 70 + .../packageDependencies/ui/PackageNode.java | 84 + .../packageDependencies/ui/RootNode.java | 15 + .../ui/TreeExpantionMonitor.java | 77 + .../ui/TreeModelBuilder.java | 415 ++ .../packageDependencies/ui/UsagesPanel.java | 184 + .../intellij/peer/impl/PeerFactoryImpl.java | 196 + .../intellij/pom/core/impl/PomModelImpl.java | 159 + .../pom/java/impl/PomJavaAspectImpl.java | 212 + .../projectView/LibrariesElement.java | 72 + .../source/com/intellij/psi/PsiLock.java | 11 + .../AllVariablesControlFlowPolicy.java | 33 + .../psi/controlFlow/BranchingInstruction.java | 18 + .../psi/controlFlow/CallInstruction.java | 28 + .../psi/controlFlow/CommentInstruction.java | 17 + .../CompositeInstructionClientVisitor.java | 119 + .../ConditionalBranchingInstruction.java | 30 + .../ConditionalGoToInstruction.java | 37 + .../ConditionalThrowToInstruction.java | 16 + .../intellij/psi/controlFlow/ControlFlow.java | 32 + .../psi/controlFlow/ControlFlowAnalyzer.java | 1544 +++++++ .../psi/controlFlow/ControlFlowFactory.java | 84 + .../psi/controlFlow/ControlFlowImpl.java | 99 + .../ControlFlowInstructionVisitor.java | 49 + .../psi/controlFlow/ControlFlowPolicy.java | 12 + .../psi/controlFlow/ControlFlowStack.java | 37 + .../psi/controlFlow/ControlFlowSubRange.java | 96 + .../psi/controlFlow/ControlFlowUtil.java | 1403 ++++++ .../psi/controlFlow/EmptyInstruction.java | 11 + .../psi/controlFlow/GoToInstruction.java | 46 + .../intellij/psi/controlFlow/Instruction.java | 9 + .../psi/controlFlow/InstructionBase.java | 16 + .../controlFlow/InstructionClientVisitor.java | 11 + .../controlFlow/LocalsControlFlowPolicy.java | 44 + ...lsOrMyInstanceFieldsControlFlowPolicy.java | 41 + .../controlFlow/ReadVariableInstruction.java | 19 + .../psi/controlFlow/ReturnInstruction.java | 84 + .../psi/controlFlow/SimpleInstruction.java | 21 + .../psi/controlFlow/ThrowToInstruction.java | 28 + .../controlFlow/WriteVariableInstruction.java | 19 + .../com/intellij/psi/filters/AndFilter.java | 82 + .../com/intellij/psi/filters/ClassFilter.java | 68 + .../psi/filters/ConstructorFilter.java | 39 + .../intellij/psi/filters/ContentFilter.java | 33 + .../intellij/psi/filters/ContextGetter.java | 15 + .../psi/filters/ElementExtractorFilter.java | 60 + .../intellij/psi/filters/ElementFilter.java | 16 + .../com/intellij/psi/filters/FalseFilter.java | 38 + .../com/intellij/psi/filters/FilterUtil.java | 200 + .../intellij/psi/filters/GeneratorFilter.java | 93 + .../psi/filters/InitializableFilter.java | 12 + .../com/intellij/psi/filters/NotFilter.java | 57 + .../com/intellij/psi/filters/OrFilter.java | 91 + .../com/intellij/psi/filters/ScopeFilter.java | 30 + .../com/intellij/psi/filters/TextFilter.java | 123 + .../com/intellij/psi/filters/TrueFilter.java | 42 + .../filters/classes/AnnotationTypeFilter.java | 46 + .../psi/filters/classes/AnyInnerFilter.java | 66 + .../classes/AssignableFromContextFilter.java | 63 + .../classes/ClassAssignableFilter.java | 54 + .../classes/ClassAssignableToFilter.java | 39 + .../psi/filters/classes/EnumFilter.java | 39 + .../psi/filters/classes/InterfaceFilter.java | 46 + .../filters/classes/ThisOrAnyInnerFilter.java | 26 + .../element/ExcludeDeclaredFilter.java | 70 + .../element/ExcludeSillyAssignment.java | 32 + .../psi/filters/element/ModifierFilter.java | 104 + .../filters/element/PackageEqualsFilter.java | 61 + .../filters/element/ReferenceOnFilter.java | 33 + .../psi/filters/getters/AllClassesGetter.java | 62 + .../psi/filters/getters/CastTypeGetter.java | 29 + .../filters/getters/ExpectedTypesGetter.java | 68 + .../psi/filters/getters/FilterGetter.java | 38 + .../getters/InstanceOfLeftPartTypeGetter.java | 27 + .../psi/filters/getters/MembersGetter.java | 56 + .../psi/filters/getters/TemplatesGetter.java | 44 + .../psi/filters/getters/ThisGetter.java | 44 + .../psi/filters/getters/ThrowsListGetter.java | 33 + .../getters/XmlAttributeValueGetter.java | 36 + .../filters/position/AfterElementFilter.java | 39 + .../filters/position/BeforeElementFilter.java | 36 + .../filters/position/InsideElementFilter.java | 30 + .../psi/filters/position/LeftNeighbour.java | 34 + .../filters/position/ParentElementFilter.java | 52 + .../ParentSkipReferenceElementFilter.java | 37 + .../position/PositionElementFilter.java | 49 + .../position/PreviousElementFilter.java | 32 + .../psi/filters/position/RootTagFilter.java | 32 + .../filters/position/StartElementFilter.java | 28 + .../filters/position/SuperParentFilter.java | 33 + .../psi/filters/position/TokenTypeFilter.java | 72 + .../psi/filters/types/ArrayTypeFilter.java | 25 + .../filters/types/AssignableFromFilter.java | 74 + .../filters/types/AssignableGroupFilter.java | 36 + .../psi/filters/types/AssignableToFilter.java | 93 + .../psi/filters/types/ReturnTypeFilter.java | 78 + .../psi/filters/types/TypeClassFilter.java | 48 + .../TypeCodeFragmentIsVoidEnabledFilter.java | 24 + .../psi/filters/types/TypeFilter.java | 28 + .../intellij/psi/impl/CachedValueImpl.java | 173 + .../psi/impl/CachedValuesManagerImpl.java | 67 + .../com/intellij/psi/impl/CheckUtil.java | 62 + .../psi/impl/CommitToPsiFileAction.java | 10 + .../psi/impl/CompositeShortNamesCache.java | 185 + .../psi/impl/ConstantExpressionEvaluator.java | 558 +++ .../com/intellij/psi/impl/DebugUtil.java | 226 + .../com/intellij/psi/impl/ElementBase.java | 183 + .../psi/impl/EmptySubstitutorImpl.java | 75 + .../psi/impl/InheritanceImplUtil.java | 145 + .../intellij/psi/impl/PsiClassImplUtil.java | 883 ++++ .../impl/PsiConstantEvaluationHelperImpl.java | 27 + .../psi/impl/PsiDocumentManagerImpl.java | 469 ++ .../com/intellij/psi/impl/PsiElementBase.java | 140 + .../psi/impl/PsiElementFactoryImpl.java | 805 ++++ .../com/intellij/psi/impl/PsiFileEx.java | 7 + .../com/intellij/psi/impl/PsiImplUtil.java | 371 ++ .../psi/impl/PsiManagerConfiguration.java | 34 + .../com/intellij/psi/impl/PsiManagerImpl.java | 1072 +++++ .../psi/impl/PsiModificationTrackerImpl.java | 94 + .../intellij/psi/impl/PsiNameHelperImpl.java | 77 + .../psi/impl/PsiShortNamesCacheImpl.java | 385 ++ .../intellij/psi/impl/PsiSubstitutorImpl.java | 325 ++ .../psi/impl/PsiSuperMethodImplUtil.java | 315 ++ .../psi/impl/PsiToDocumentSynchronizer.java | 179 + .../psi/impl/PsiTreeChangeEventImpl.java | 79 + .../com/intellij/psi/impl/PsiVariableEx.java | 9 + .../psi/impl/SharedPsiElementImplUtil.java | 95 + .../com/intellij/psi/impl/TextBlock.java | 52 + .../intellij/psi/impl/cache/CacheManager.java | 36 + .../psi/impl/cache/ClassInitializerView.java | 7 + .../intellij/psi/impl/cache/ClassView.java | 30 + .../psi/impl/cache/DeclarationView.java | 14 + .../psi/impl/cache/DirectoryView.java | 9 + .../intellij/psi/impl/cache/FieldView.java | 18 + .../com/intellij/psi/impl/cache/FileView.java | 26 + .../cache/InitializerTooLongException.java | 4 + .../intellij/psi/impl/cache/MethodView.java | 24 + .../psi/impl/cache/ModifierFlags.java | 27 + .../psi/impl/cache/RepositoryElementType.java | 34 + .../psi/impl/cache/RepositoryItemView.java | 17 + .../psi/impl/cache/impl/CacheUtil.java | 77 + .../cache/impl/CompositeCacheManager.java | 97 + .../cache/impl/idCache/BaseFilterLexer.java | 95 + .../cache/impl/idCache/IdTableBuilding.java | 315 ++ .../impl/cache/impl/idCache/VfsIndexer.java | 106 + .../cache/impl/idCache/XmlFilterLexer.java | 37 + .../impl/repositoryCache/RecordUtil.java | 651 +++ .../cache/impl/repositoryCache/TypeInfo.java | 10 + .../psi/impl/compiled/ClsAnnotationImpl.java | 86 + .../ClsAnnotationParameterListImpl.java | 71 + .../psi/impl/compiled/ClsAnnotationsUtil.java | 169 + .../ClsArrayInitializerMemberValueImpl.java | 69 + .../psi/impl/compiled/ClsClassImpl.java | 1140 +++++ .../ClsClassObjectAccessExpressionImpl.java | 58 + .../psi/impl/compiled/ClsDocCommentImpl.java | 82 + .../psi/impl/compiled/ClsDocTagImpl.java | 127 + .../psi/impl/compiled/ClsElementImpl.java | 193 + .../impl/compiled/ClsEnumConstantImpl.java | 88 + .../psi/impl/compiled/ClsFieldImpl.java | 617 +++ .../psi/impl/compiled/ClsFileImpl.java | 288 ++ .../psi/impl/compiled/ClsIdentifierImpl.java | 53 + .../ClsJavaCodeReferenceElementImpl.java | 301 ++ .../compiled/ClsLiteralExpressionImpl.java | 71 + .../psi/impl/compiled/ClsMethodImpl.java | 829 ++++ .../impl/compiled/ClsModifierListImpl.java | 161 + .../impl/compiled/ClsModifierListOwner.java | 10 + .../impl/compiled/ClsNameValuePairImpl.java | 66 + .../compiled/ClsPackageStatementImpl.java | 83 + .../psi/impl/compiled/ClsParameterImpl.java | 196 + .../impl/compiled/ClsParameterListImpl.java | 73 + .../psi/impl/compiled/ClsParsingUtil.java | 47 + .../compiled/ClsPrefixExpressionImpl.java | 94 + .../compiled/ClsReferenceExpressionImpl.java | 170 + .../impl/compiled/ClsReferenceListImpl.java | 96 + .../ClsReferenceParametersListImpl.java | 69 + .../compiled/ClsRepositoryPsiElement.java | 61 + .../psi/impl/compiled/ClsTypeElementImpl.java | 193 + .../impl/compiled/ClsTypeParameterImpl.java | 326 ++ .../ClsTypeParameterReferenceImpl.java | 165 + .../compiled/ClsTypeParametersListImpl.java | 85 + .../psi/impl/file/PsiBinaryFileImpl.java | 262 ++ .../psi/impl/file/PsiDirectoryImpl.java | 605 +++ .../psi/impl/file/PsiFileImplUtil.java | 63 + .../psi/impl/file/PsiPackageImpl.java | 432 ++ .../psi/impl/file/impl/FileManager.java | 35 + .../psi/impl/file/impl/FileManagerImpl.java | 1216 ++++++ .../psi/impl/light/ImplicitVariableImpl.java | 21 + .../psi/impl/light/LightClassReference.java | 219 + .../light/LightClassReferenceExpression.java | 56 + .../intellij/psi/impl/light/LightElement.java | 122 + .../impl/light/LightEmptyImplementsList.java | 36 + .../psi/impl/light/LightIdentifier.java | 37 + .../intellij/psi/impl/light/LightKeyword.java | 40 + .../intellij/psi/impl/light/LightMethod.java | 146 + .../psi/impl/light/LightModifierList.java | 47 + .../psi/impl/light/LightPackageReference.java | 149 + .../LightPackageReferenceExpression.java | 39 + .../light/LightReferenceParameterList.java | 63 + .../psi/impl/light/LightTypeElement.java | 48 + .../psi/impl/light/LightVariableBase.java | 81 + .../intellij/psi/impl/meta/MetaRegistry.java | 350 ++ .../impl/migration/MigrationClassImpl.java | 233 + .../impl/migration/MigrationPackageImpl.java | 41 + .../psi/impl/migration/PsiMigrationImpl.java | 135 + .../psi/impl/search/LowLevelSearchUtil.java | 184 + .../psi/impl/search/PsiSearchHelperImpl.java | 1587 +++++++ .../psi/impl/search/ThrowSearchUtil.java | 167 + .../psi/impl/search/TodoItemImpl.java | 53 + .../impl/smartPointers/LazyPointerImpl.java | 74 + .../impl/smartPointers/SmartPointerEx.java | 39 + .../SmartPointerManagerImpl.java | 333 ++ .../SmartPsiElementPointerImpl.java | 307 ++ .../psi/impl/source/CharTableImpl.java | 140 + .../psi/impl/source/CodeFragmentElement.java | 9 + .../intellij/psi/impl/source/Constants.java | 121 + .../intellij/psi/impl/source/DummyHolder.java | 157 + .../psi/impl/source/DummyHolderElement.java | 9 + .../psi/impl/source/ParsingContext.java | 90 + .../impl/source/PsiAnnotationMethodImpl.java | 34 + .../impl/source/PsiAnonymousClassImpl.java | 154 + .../psi/impl/source/PsiClassImpl.java | 755 ++++ .../impl/source/PsiClassInitializerImpl.java | 81 + .../impl/source/PsiClassReferenceType.java | 162 + .../psi/impl/source/PsiCodeFragmentImpl.java | 241 + .../psi/impl/source/PsiEnumConstantImpl.java | 274 ++ .../PsiEnumConstantInitializerImpl.java | 134 + .../source/PsiExpressionCodeFragmentImpl.java | 25 + .../psi/impl/source/PsiFieldImpl.java | 373 ++ .../intellij/psi/impl/source/PsiFileImpl.java | 336 ++ .../impl/source/PsiImmediateClassType.java | 230 + .../psi/impl/source/PsiImportListImpl.java | 221 + .../source/PsiImportStatementBaseImpl.java | 81 + .../impl/source/PsiImportStatementImpl.java | 65 + .../PsiImportStaticReferenceElementImpl.java | 357 ++ .../source/PsiImportStaticStatementImpl.java | 114 + .../PsiJavaCodeReferenceElementImpl.java | 893 ++++ .../psi/impl/source/PsiJavaFileBaseImpl.java | 438 ++ .../psi/impl/source/PsiJavaFileImpl.java | 32 + .../psi/impl/source/PsiLabelReference.java | 87 + .../psi/impl/source/PsiMethodImpl.java | 364 ++ .../psi/impl/source/PsiModifierListImpl.java | 270 ++ .../psi/impl/source/PsiParameterImpl.java | 147 + .../psi/impl/source/PsiParameterListImpl.java | 90 + .../psi/impl/source/PsiPlainTextFileImpl.java | 55 + .../psi/impl/source/PsiReferenceListImpl.java | 126 + .../impl/source/PsiTypeCodeFragmentImpl.java | 67 + .../psi/impl/source/PsiTypeElementImpl.java | 120 + .../impl/source/SourceJavaCodeReference.java | 35 + .../psi/impl/source/SourceTreeToPsiMap.java | 50 + .../impl/source/codeStyle/BraceEnforcer.java | 94 + .../impl/source/codeStyle/CodeEditUtil.java | 405 ++ .../source/codeStyle/CodeFormatterFacade.java | 233 + .../codeStyle/CodeStyleManagerImpl.java | 1180 +++++ .../source/codeStyle/CodeStyleSchemeImpl.java | 154 + .../codeStyle/CodeStyleSchemesImpl.java | 216 + .../psi/impl/source/codeStyle/Helper.java | 704 +++ .../impl/source/codeStyle/ImportHelper.java | 718 +++ .../psi/impl/source/codeStyle/IndentImpl.java | 73 + .../source/codeStyle/ReferenceAdjuster.java | 227 + .../codeStyle/javadoc/CommentFormatter.java | 214 + .../codeStyle/javadoc/JDClassComment.java | 56 + .../source/codeStyle/javadoc/JDComment.java | 193 + .../codeStyle/javadoc/JDMethodComment.java | 181 + .../source/codeStyle/javadoc/JDParser.java | 458 ++ .../source/codeStyle/javadoc/NameDesc.java | 28 + .../impl/source/html/HtmlDocumentImpl.java | 57 + .../psi/impl/source/html/HtmlFileImpl.java | 38 + .../psi/impl/source/html/HtmlTagImpl.java | 104 + .../html/dtd/HtmlAttributeDescriptorImpl.java | 92 + .../html/dtd/HtmlElementDescriptorImpl.java | 148 + .../source/html/dtd/HtmlNSDescriptorImpl.java | 96 + .../impl/source/javadoc/ExceptionTagInfo.java | 83 + .../source/javadoc/JavadocManagerImpl.java | 67 + .../impl/source/javadoc/ParamDocTagInfo.java | 109 + .../source/javadoc/PsiDocCommentImpl.java | 288 ++ .../javadoc/PsiDocMethodOrFieldRef.java | 290 ++ .../impl/source/javadoc/PsiDocParamRef.java | 89 + .../impl/source/javadoc/PsiDocTagImpl.java | 90 + .../source/javadoc/PsiDocTagValueImpl.java | 33 + .../impl/source/javadoc/PsiDocTokenImpl.java | 25 + .../impl/source/javadoc/ReturnDocTagInfo.java | 42 + .../impl/source/javadoc/SeeDocTagInfo.java | 114 + .../impl/source/javadoc/SerialDocTagInfo.java | 35 + .../impl/source/javadoc/SimpleDocTagInfo.java | 53 + .../psi/impl/source/jsp/jspJava/JspText.java | 19 + .../source/jsp/tagLibrary/FileLoader.java | 83 + .../impl/source/jsp/tagLibrary/JarLoader.java | 112 + .../impl/source/jsp/tagLibrary/Loader.java | 20 + .../source/parsing/ChameleonTransforming.java | 79 + .../impl/source/parsing/ClassBodyParsing.java | 138 + .../source/parsing/DeclarationParsing.java | 982 +++++ .../source/parsing/ExpressionParsing.java | 889 ++++ .../impl/source/parsing/FileTextParsing.java | 137 + .../psi/impl/source/parsing/GTTokens.java | 116 + .../source/parsing/ImportsTextParsing.java | 132 + .../impl/source/parsing/JavadocParsing.java | 317 ++ .../psi/impl/source/parsing/ParseUtil.java | 532 +++ .../psi/impl/source/parsing/Parsing.java | 260 ++ .../impl/source/parsing/StatementParsing.java | 923 ++++ .../impl/source/parsing/xml/XmlParsing.java | 768 ++++ .../impl/source/parsing/xml/XmlPsiLexer.java | 24 + .../resolve/ClassResolverProcessor.java | 205 + .../source/resolve/PsiResolveHelperImpl.java | 438 ++ .../psi/impl/source/resolve/ResolveCache.java | 220 + .../impl/source/resolve/ResolveClassUtil.java | 63 + .../source/resolve/ResolveVariableUtil.java | 43 + .../resolve/VariableResolverProcessor.java | 78 + .../resolve/reference/ElementManipulator.java | 16 + .../resolve/reference/ProviderBinding.java | 54 + .../reference/PsiReferenceProvider.java | 26 + .../reference/ReferenceProvidersRegistry.java | 187 + .../reference/impl/GenericReference.java | 109 + .../reference/impl/PsiMultiReference.java | 107 + .../manipulators/PlainFileManipulator.java | 28 + .../XmlAttributeValueManipulator.java | 53 + .../providers/GenericReferenceProvider.java | 33 + .../JavaClassListReferenceProvider.java | 50 + .../providers/JavaClassReferenceProvider.java | 246 ++ .../impl/source/text/BlockSupportImpl.java | 159 + .../psi/impl/source/tree/ChangeUtil.java | 697 +++ .../psi/impl/source/tree/ChildRole.java | 230 + .../impl/source/tree/CompositeElement.java | 301 ++ .../impl/source/tree/CompositePsiElement.java | 266 ++ .../psi/impl/source/tree/ElementType.java | 97 + .../psi/impl/source/tree/Factory.java | 544 +++ .../psi/impl/source/tree/FileElement.java | 77 + .../psi/impl/source/tree/HtmlFileElement.java | 21 + .../impl/source/tree/JavaDocElementType.java | 15 + .../psi/impl/source/tree/JavaElementType.java | 95 + .../psi/impl/source/tree/LeafElement.java | 117 + .../psi/impl/source/tree/LeafPsiElement.java | 214 + .../source/tree/PlainTextFileElement.java | 7 + .../psi/impl/source/tree/PsiCommentImpl.java | 25 + .../impl/source/tree/PsiErrorElementImpl.java | 43 + .../impl/source/tree/PsiPlainTextImpl.java | 19 + .../impl/source/tree/PsiWhiteSpaceImpl.java | 20 + .../psi/impl/source/tree/SharedImplUtil.java | 194 + .../psi/impl/source/tree/SourceUtil.java | 128 + .../psi/impl/source/tree/TreeElement.java | 184 + .../psi/impl/source/tree/TreeUtil.java | 342 ++ .../psi/impl/source/tree/XmlFileElement.java | 21 + .../tree/java/AnnotationMethodElement.java | 36 + .../tree/java/AnonymousClassElement.java | 12 + .../tree/java/AnonymousClassElementBase.java | 69 + .../impl/source/tree/java/ClassElement.java | 284 ++ .../tree/java/ClassInitializerElement.java | 51 + .../source/tree/java/EnumConstantElement.java | 81 + .../java/EnumConstantInitializerElement.java | 13 + .../source/tree/java/ExtendsListElement.java | 56 + .../impl/source/tree/java/FieldElement.java | 101 + .../tree/java/ImplementsListElement.java | 56 + .../source/tree/java/ImportListElement.java | 29 + .../tree/java/ImportStatementBaseElement.java | 58 + .../tree/java/ImportStatementElement.java | 24 + .../java/ImportStaticStatementElement.java | 43 + .../source/tree/java/JavaFileElement.java | 74 + .../impl/source/tree/java/MethodElement.java | 126 + .../source/tree/java/ModifierListElement.java | 33 + .../source/tree/java/ParameterElement.java | 58 + .../tree/java/ParameterListElement.java | 130 + .../source/tree/java/PsiAnnotationImpl.java | 70 + .../java/PsiAnnotationParameterListImpl.java | 77 + .../java/PsiArrayAccessExpressionImpl.java | 88 + .../PsiArrayInitializerExpressionImpl.java | 84 + .../PsiArrayInitializerMemberValueImpl.java | 65 + .../tree/java/PsiAssertStatementImpl.java | 88 + .../java/PsiAssignmentExpressionImpl.java | 78 + .../tree/java/PsiBinaryExpressionImpl.java | 130 + .../tree/java/PsiBlockStatementImpl.java | 51 + .../tree/java/PsiBreakStatementImpl.java | 104 + .../source/tree/java/PsiCatchSectionImpl.java | 86 + .../PsiClassObjectAccessExpressionImpl.java | 72 + .../source/tree/java/PsiCodeBlockImpl.java | 197 + .../java/PsiConditionalExpressionImpl.java | 139 + .../tree/java/PsiContinueStatementImpl.java | 103 + .../java/PsiDeclarationStatementImpl.java | 93 + .../tree/java/PsiDoWhileStatementImpl.java | 105 + .../tree/java/PsiEmptyExpressionImpl.java | 22 + .../tree/java/PsiEmptyStatementImpl.java | 18 + .../tree/java/PsiExpressionListImpl.java | 138 + .../java/PsiExpressionListStatementImpl.java | 56 + .../tree/java/PsiExpressionStatementImpl.java | 57 + .../source/tree/java/PsiForStatementImpl.java | 160 + .../tree/java/PsiForeachStatementImpl.java | 122 + .../source/tree/java/PsiIdentifierImpl.java | 28 + .../source/tree/java/PsiIfStatementImpl.java | 139 + .../source/tree/java/PsiInlineDocTagImpl.java | 98 + .../java/PsiInstanceOfExpressionImpl.java | 69 + .../source/tree/java/PsiJavaTokenImpl.java | 26 + .../impl/source/tree/java/PsiKeywordImpl.java | 41 + .../tree/java/PsiLabeledStatementImpl.java | 92 + .../tree/java/PsiLiteralExpressionImpl.java | 384 ++ .../tree/java/PsiLocalVariableImpl.java | 238 + .../java/PsiMethodCallExpressionImpl.java | 114 + .../tree/java/PsiNameValuePairImpl.java | 197 + .../tree/java/PsiNewExpressionImpl.java | 244 ++ .../tree/java/PsiPackageStatementImpl.java | 73 + .../java/PsiParenthesizedExpressionImpl.java | 71 + .../tree/java/PsiPostfixExpressionImpl.java | 58 + .../tree/java/PsiPrefixExpressionImpl.java | 84 + .../tree/java/PsiReferenceExpressionImpl.java | 569 +++ .../java/PsiReferenceParameterListImpl.java | 164 + .../tree/java/PsiReturnStatementImpl.java | 64 + .../tree/java/PsiSuperExpressionImpl.java | 129 + .../java/PsiSwitchLabelStatementImpl.java | 81 + .../tree/java/PsiSwitchStatementImpl.java | 84 + .../java/PsiSynchronizedStatementImpl.java | 79 + .../tree/java/PsiThisExpressionImpl.java | 102 + .../tree/java/PsiThrowStatementImpl.java | 64 + .../source/tree/java/PsiThrowsListImpl.java | 55 + .../source/tree/java/PsiTryStatementImpl.java | 154 + .../tree/java/PsiTypeCastExpressionImpl.java | 75 + ...PsiTypeParameterExtendsBoundsListImpl.java | 90 + .../tree/java/PsiTypeParameterImpl.java | 343 ++ .../tree/java/PsiTypeParameterListImpl.java | 122 + .../tree/java/PsiWhileStatementImpl.java | 86 + .../tree/java/ReferenceListElement.java | 76 + .../tree/java/ReplaceExpressionUtil.java | 143 + .../tree/java/TypeParameterElement.java | 46 + ...TypeParameterExtendsBoundsListElement.java | 102 + .../tree/java/TypeParameterListElement.java | 113 + .../psi/impl/source/xml/TagNameReference.java | 140 + .../impl/source/xml/XmlAttlistDeclImpl.java | 44 + .../impl/source/xml/XmlAttributeDeclImpl.java | 123 + .../psi/impl/source/xml/XmlAttributeImpl.java | 225 + .../source/xml/XmlAttributeValueImpl.java | 57 + .../psi/impl/source/xml/XmlCommentImpl.java | 17 + .../psi/impl/source/xml/XmlDeclImpl.java | 17 + .../psi/impl/source/xml/XmlDoctypeImpl.java | 163 + .../psi/impl/source/xml/XmlDocumentImpl.java | 116 + .../source/xml/XmlElementContentSpecImpl.java | 52 + .../impl/source/xml/XmlElementDeclImpl.java | 80 + .../psi/impl/source/xml/XmlElementImpl.java | 61 + .../impl/source/xml/XmlEntityDeclImpl.java | 216 + .../psi/impl/source/xml/XmlEntityRefImpl.java | 116 + .../source/xml/XmlEnumeratedTypeImpl.java | 28 + .../psi/impl/source/xml/XmlFileImpl.java | 90 + .../impl/source/xml/XmlMarkupDeclImpl.java | 22 + .../impl/source/xml/XmlNotationDeclImpl.java | 39 + .../xml/XmlProcessingInstructionImpl.java | 44 + .../psi/impl/source/xml/XmlPrologImpl.java | 37 + .../psi/impl/source/xml/XmlTagImpl.java | 965 ++++ .../psi/impl/source/xml/XmlTagValueImpl.java | 84 + .../psi/impl/source/xml/XmlTextImpl.java | 612 +++ .../psi/impl/source/xml/XmlTokenImpl.java | 56 + .../impl/source/xml/dtd/DTDElementType.java | 39 + .../java/ClassPresentationUtil.java | 110 + .../java/SymbolPresentationUtil.java | 126 + .../psi/scope/BaseScopeProcessor.java | 15 + .../intellij/psi/scope/ElementClassHint.java | 5 + .../MethodProcessorSetupFailedException.java | 14 + .../com/intellij/psi/scope/NameHint.java | 5 + .../psi/scope/PsiConflictResolver.java | 17 + .../DuplicateConflictResolver.java | 49 + .../JavaMethodsConflictResolver.java | 253 ++ .../JavaVariableConflictResolver.java | 103 + .../processor/ConflictFilterProcessor.java | 109 + .../processor/FilterElementProcessor.java | 64 + .../scope/processor/FilterScopeProcessor.java | 87 + .../processor/MethodCandidatesProcessor.java | 53 + .../processor/MethodResolverProcessor.java | 59 + .../psi/scope/processor/MethodsProcessor.java | 95 + .../processor/VariablesNotProcessor.java | 31 + .../scope/processor/VariablesProcessor.java | 76 + .../psi/scope/util/PsiScopesUtil.java | 346 ++ .../impl/StatisticsManagerImpl.java | 279 ++ .../psi/statistics/impl/StatisticsUnit.java | 118 + .../statistics/impl/WrongFormatException.java | 5 + .../com/intellij/psi/text/BlockSupport.java | 14 + .../intellij/psi/tree/DefaultRoleFinder.java | 26 + .../com/intellij/psi/tree/RoleFinder.java | 8 + .../com/intellij/psi/xml/XmlChildRole.java | 54 + .../refactoring/BaseRefactoringProcessor.java | 381 ++ .../com/intellij/refactoring/HelpID.java | 100 + .../refactoring/IntroduceHandlerBase.java | 66 + .../refactoring/RefactoringDialog.java | 155 + .../intellij/refactoring/RefactoringImpl.java | 60 + .../refactoring/RefactoringManager.java | 52 + .../refactoring/RefactoringSettings.java | 222 + .../actions/AnonymousToInnerAction.java | 21 + .../actions/BaseRefactoringAction.java | 91 + .../actions/ChangeSignatureAction.java | 23 + .../ConvertToInstanceMethodAction.java | 24 + .../actions/EncapsulateFieldsAction.java | 43 + .../actions/ExtractInterfaceAction.java | 35 + .../actions/ExtractMethodAction.java | 24 + .../actions/ExtractSuperclassAction.java | 35 + .../InheritanceToDelegationAction.java | 21 + .../refactoring/actions/InlineAction.java | 28 + .../actions/IntroduceConstantAction.java | 22 + .../actions/IntroduceFieldAction.java | 21 + .../actions/IntroduceParameterAction.java | 28 + .../actions/IntroduceVariableAction.java | 24 + .../actions/MakeMethodStaticAction.java | 30 + .../actions/MethodDuplicatesAction.java | 27 + .../refactoring/actions/MigrateAction.java | 22 + .../refactoring/actions/MoveAction.java | 35 + .../refactoring/actions/PullUpAction.java | 36 + .../refactoring/actions/PushDownAction.java | 37 + .../actions/RenameElementAction.java | 54 + .../ReplaceConstructorWithFactoryAction.java | 27 + .../refactoring/actions/SafeDeleteAction.java | 36 + .../actions/TempWithQueryAction.java | 21 + .../actions/TurnRefsToSuperAction.java | 21 + .../refactoring/actions/TypeCookAction.java | 59 + .../AnonymousToInnerDialog.java | 217 + .../AnonymousToInnerHandler.java | 491 +++ .../anonymousToInner/VariableInfo.java | 19 + .../ChangeClassSignatureDialog.java | 255 ++ .../ChangeClassSignatureProcessor.java | 195 + .../ChangeClassSigntaureViewDescriptor.java | 43 + .../TypeParameterInfo.java | 64 + .../changeSignature/ChangeInfo.java | 189 + .../ChangeSignatureDialog.java | 666 +++ .../ChangeSignatureHandler.java | 111 + .../ChangeSignatureProcessor.java | 1018 +++++ .../changeSignature/ChangeSignatureUtil.java | 62 + .../ChangeSignatureViewDescriptor.java | 102 + .../changeSignature/ExceptionsTableModel.java | 130 + ...ewParameterCollidesWithLocalUsageInfo.java | 33 + .../changeSignature/ParameterInfo.java | 127 + .../changeSignature/ParameterTableModel.java | 205 + .../changeSignature/ThrownExceptionInfo.java | 55 + .../ConvertToInstanceMethodDialog.java | 124 + .../ConvertToInstanceMethodHandler.java | 98 + .../ConvertToInstanceMethodProcessor.java | 350 ++ ...ConvertToInstanceMethodViewDescriptor.java | 59 + .../ImplementingClassUsageInfo.java | 20 + .../JavaDocUsageInfo.java | 19 + .../MethodCallUsageInfo.java | 23 + .../ParameterUsageInfo.java | 22 + .../refactoring/copy/CopyClassDialog.java | 185 + .../copy/CopyFilesOrDirectoriesDialog.java | 196 + .../refactoring/copy/CopyHandler.java | 410 ++ .../EncapsulateFieldsDialog.java | 686 +++ .../EncapsulateFieldsHandler.java | 111 + .../EncapsulateFieldsProcessor.java | 530 +++ .../EncapsulateFieldsViewDescriptor.java | 93 + .../extractInterface/ExtractClassUtil.java | 50 + .../ExtractInterfaceDialog.java | 295 ++ .../ExtractInterfaceHandler.java | 138 + .../ExtractInterfaceProcessor.java | 49 + .../extractMethod/ExtractMethodDialog.java | 309 ++ .../extractMethod/ExtractMethodHandler.java | 127 + .../extractMethod/ExtractMethodProcessor.java | 877 ++++ .../extractMethod/PrepareFailedException.java | 27 + .../extractSuperclass/BindToOldUsageInfo.java | 15 + .../ExtractSuperBaseDialog.java | 69 + .../ExtractSuperBaseProcessor.java | 144 + .../ExtractSuperClassProcessor.java | 55 + .../ExtractSuperClassUtil.java | 141 + .../ExtractSuperClassViewDescriptor.java | 46 + .../ExtractSuperclassDialog.java | 249 ++ .../ExtractSuperclassHandler.java | 157 + .../InheritanceToDelegationDialog.java | 272 ++ .../InheritanceToDelegationHandler.java | 155 + .../InheritanceToDelegationProcessor.java | 1195 +++++ .../InheritanceToDelegationUtil.java | 27 + ...InheritanceToDelegationViewDescriptor.java | 33 + .../InnerClassConstructor.java | 34 + .../InnerClassMethod.java | 15 + .../usageInfo/FieldAccessibility.java | 26 + .../InheritanceToDelegationUsageInfo.java | 20 + ...ngerOverridingSubClassMethodUsageInfo.java | 25 + .../NonDelegatedMemberUsageInfo.java | 16 + .../usageInfo/ObjectUpcastedUsageInfo.java | 12 + ...nqualifiedNonDelegatedMemberUsageInfo.java | 13 + .../usageInfo/UpcastedUsageInfo.java | 15 + .../inline/InlineConstantFieldHandler.java | 60 + .../inline/InlineConstantFieldProcessor.java | 223 + .../refactoring/inline/InlineFieldDialog.java | 111 + .../refactoring/inline/InlineHandler.java | 55 + .../inline/InlineLocalHandler.java | 283 ++ .../inline/InlineMethodDialog.java | 110 + .../inline/InlineMethodHandler.java | 102 + .../inline/InlineMethodProcessor.java | 1162 +++++ .../refactoring/inline/InlineOptions.java | 11 + .../inline/InlineViewDescriptor.java | 104 + .../inline/ReferencedElementsCollector.java | 23 + .../BaseExpressionToFieldHandler.java | 530 +++ .../introduceField/ElementToWorkOn.java | 86 + .../IntroduceConstantDialog.java | 446 ++ .../IntroduceConstantHandler.java | 191 + .../introduceField/IntroduceFieldDialog.java | 547 +++ .../introduceField/IntroduceFieldHandler.java | 150 + .../introduceField/LocalToFieldHandler.java | 286 ++ .../ChangedMethodCallInfo.java | 17 + .../ClassMemberInExprUsageInfo.java | 17 + .../EnclosingMethodSelectionDialog.java | 107 + .../introduceParameter/ExternalUsageInfo.java | 17 + .../introduceParameter/InExprUsageInfo.java | 22 + .../introduceParameter/InternalUsageInfo.java | 21 + .../IntroduceParameterDialog.java | 372 ++ .../IntroduceParameterHandler.java | 279 ++ .../IntroduceParameterProcessor.java | 778 ++++ .../IntroduceParameterViewDescriptor.java | 56 + .../LocalVariableInExprUsageInfo.java | 17 + .../ParameterInExprUsageInfo.java | 21 + .../refactoring/introduceParameter/Util.java | 91 + .../IntroduceVariableBase.java | 492 +++ .../IntroduceVariableDialog.java | 253 ++ .../IntroduceVariableHandler.java | 79 + .../IntroduceVariableSettings.java | 24 + .../impl/RefactoringListenerManagerImpl.java | 56 + .../impl/RefactoringTransaction.java | 22 + .../impl/impl/RefactoringTransactionImpl.java | 94 + .../makeMethodStatic/InternalUsageInfo.java | 45 + .../MakeMethodStaticProcessor.java | 521 +++ .../OverridingMethodUsageInfo.java | 13 + .../makeMethodStatic/SelfUsageInfo.java | 17 + .../makeMethodStatic/Settings.java | 118 + .../memberPullUp/JavaDocPanel.java | 82 + .../memberPullUp/PullUpConflictsUtil.java | 223 + .../memberPullUp/PullUpDialog.java | 251 ++ .../memberPullUp/PullUpHandler.java | 202 + .../memberPullUp/PullUpHelper.java | 642 +++ .../memberPushDown/PushDownConflicts.java | 109 + .../memberPushDown/PushDownDialog.java | 112 + .../memberPushDown/PushDownHandler.java | 116 + .../memberPushDown/PushDownProcessor.java | 183 + .../PushDownUsageViewDescriptor.java | 96 + .../migration/EditMigrationDialog.java | 322 ++ .../migration/EditMigrationEntryDialog.java | 136 + .../migration/MigrationDialog.java | 248 ++ .../migration/MigrationManager.java | 24 + .../refactoring/migration/MigrationMap.java | 82 + .../migration/MigrationMapEntry.java | 67 + .../migration/MigrationMapSet.java | 284 ++ .../migration/MigrationProcessor.java | 155 + .../MigrationUsagesViewDescriptor.java | 97 + .../refactoring/migration/MigrationUtil.java | 112 + .../refactoring/move/MoveCallback.java | 9 + .../refactoring/move/MoveHandler.java | 458 ++ .../AutocreatingMoveDestination.java | 43 + ...eatingSingleSourceRootMoveDestination.java | 72 + .../MoveClassesOrPackagesDialog.java | 345 ++ .../MoveClassesOrPackagesImpl.java | 436 ++ .../MoveClassesOrPackagesProcessor.java | 601 +++ .../MoveClassesOrPackagesUtil.java | 306 ++ .../MoveClassesOrPackagesViewDescriptor.java | 125 + .../MultipleRootsMoveDestination.java | 100 + .../SingleSourceRootMoveDestination.java | 67 + .../MoveFilesOrDirectoriesDialog.java | 137 + .../MoveFilesOrDirectoriesProcessor.java | 151 + .../MoveFilesOrDirectoriesUtil.java | 260 ++ .../MoveFilesOrDirectoriesViewDescriptor.java | 113 + .../move/moveInner/MoveInnerDialog.java | 263 ++ .../move/moveInner/MoveInnerImpl.java | 59 + .../move/moveInner/MoveInnerProcessor.java | 506 +++ .../moveInner/MoveInnerViewDescriptor.java | 101 + .../moveMembers/MoveMemberViewDescriptor.java | 92 + .../move/moveMembers/MoveMembersDialog.java | 373 ++ .../move/moveMembers/MoveMembersImpl.java | 105 + .../move/moveMembers/MoveMembersOptions.java | 18 + .../moveMembers/MoveMembersProcessor.java | 497 +++ ...onvertToInstanceMethodRefactoringImpl.java | 34 + .../IntroduceParameterRefactoringImpl.java | 71 + .../impl/MakeMethodStaticRefactoringImpl.java | 64 + .../MoveClassesOrPackagesRefactoringImpl.java | 47 + .../impl/MoveInnerRefactoringImpl.java | 52 + .../impl/MoveMembersRefactoringImpl.java | 52 + .../RefactoringActionHandlerFactoryImpl.java | 152 + .../openapi/impl/RefactoringFactoryImpl.java | 133 + .../openapi/impl/RenameRefactoringImpl.java | 63 + ...ConstructorWithFactoryRefactoringImpl.java | 43 + .../impl/SafeDeleteRefactoringImpl.java | 46 + .../impl/TurnRefsToSuperRefactoringImpl.java | 32 + .../openapi/impl/TypeCookRefactoringImpl.java | 28 + .../rename/AutomaticRenamingDialog.java | 246 ++ .../ClassHidesImportedClassUsageInfo.java | 36 + ...ClassHidesUnqualifiableClassUsageInfo.java | 26 + .../rename/CollidingClassImportUsageInfo.java | 21 + .../rename/CollisionUsageInfo.java | 18 + .../rename/LocalHidesFieldUsageInfo.java | 19 + .../LocalHidesRenamedLocalUsageInfo.java | 33 + .../rename/PsiElementRenameHandler.java | 189 + .../refactoring/rename/RenameDialog.java | 511 +++ .../refactoring/rename/RenameHandler.java | 11 + .../rename/RenameHandlerRegistry.java | 40 + .../refactoring/rename/RenameProcessor.java | 560 +++ .../refactoring/rename/RenameUtil.java | 884 ++++ .../rename/RenameVariableUsageInfo.java | 21 + .../rename/RenameViewDescriptor.java | 143 + .../rename/ResolvableCollisionUsageInfo.java | 17 + .../rename/SubmemberHidesMemberUsageInfo.java | 34 + .../UnresolvableCollisionUsageInfo.java | 19 + .../rename/naming/AutomaticRenamer.java | 128 + .../naming/AutomaticVariableRenamer.java | 59 + .../rename/naming/FormsRenamer.java | 44 + .../rename/naming/InheritorRenamer.java | 32 + .../rename/naming/NameSuggester.java | 287 ++ .../ReplaceConstructorWithFactoryDialog.java | 171 + .../ReplaceConstructorWithFactoryHandler.java | 194 + ...eplaceConstructorWithFactoryProcessor.java | 348 ++ ...eConstructorWithFactoryViewDescriptor.java | 54 + .../safeDelete/OverridingMethodsDialog.java | 195 + .../safeDelete/SafeDeleteDialog.java | 124 + .../safeDelete/SafeDeleteHandler.java | 90 + .../safeDelete/SafeDeleteProcessor.java | 728 ++++ .../SafeDeleteUsageViewDescriptor.java | 77 + .../safeDelete/UnsafeUsagesDialog.java | 84 + .../refactoring/safeDelete/UsageHolder.java | 95 + .../SafeDeleteFieldWriteReference.java | 30 + .../SafeDeleteOverridingMethodUsageInfo.java | 21 + .../usageInfo/SafeDeletePrivatizeMethod.java | 16 + ...eDeleteReferenceSimpleDeleteUsageInfo.java | 25 + .../SafeDeleteReferenceUsageInfo.java | 28 + .../usageInfo/SafeDeleteUsageInfo.java | 29 + .../tempWithQuery/TempWithQueryHandler.java | 161 + .../RefsToSuperViewDescriptor.java | 103 + .../TurnRefsToSuperDialog.java | 118 + .../TurnRefsToSuperHandler.java | 79 + .../TurnRefsToSuperProcessor.java | 126 + .../TurnRefsToSuperProcessorBase.java | 549 +++ .../TurnToSuperReferenceUsageInfo.java | 13 + .../intellij/refactoring/typeCook/Bottom.java | 60 + .../refactoring/typeCook/Settings.java | 14 + .../refactoring/typeCook/TypeCookDialog.java | 161 + .../refactoring/typeCook/TypeCookHandler.java | 41 + .../typeCook/TypeCookProcessor.java | 101 + .../typeCook/TypeCookViewDescriptor.java | 88 + .../intellij/refactoring/typeCook/Util.java | 741 ++++ .../deductive/PsiExtendedTypeVisitor.java | 14 + .../deductive/PsiTypeVariableFactory.java | 81 + .../deductive/builder/Constraint.java | 64 + .../typeCook/deductive/builder/Subtype.java | 29 + .../typeCook/deductive/builder/System.java | 256 ++ .../deductive/builder/SystemBuilder.java | 711 +++ .../typeCook/deductive/resolver/Binding.java | 17 + .../deductive/resolver/BindingFactory.java | 259 ++ .../deductive/resolver/ResolverTree.java | 122 + .../deductive/util/VictimCollector.java | 86 + .../typeCook/deductive/util/Visitor.java | 28 + .../refactoring/ui/ClassCellRenderer.java | 69 + .../ui/CodeFragmentTableCellEditor.java | 50 + .../ui/CodeFragmentTableCellRenderer.java | 43 + .../ui/ColorConfiguringCellRenderer.java | 28 + .../refactoring/ui/ConflictsDialog.java | 65 + .../refactoring/ui/DelegationPanel.java | 52 + .../ui/EditableRowTableManager.java | 163 + .../refactoring/ui/EnableDisableAction.java | 41 + .../intellij/refactoring/ui/InfoDialog.java | 70 + .../refactoring/ui/MemberSelectionPanel.java | 42 + .../refactoring/ui/MemberSelectionTable.java | 393 ++ .../refactoring/ui/MethodCellRenderer.java | 37 + .../refactoring/ui/NameSuggestionsField.java | 205 + .../ui/NameSuggestionsGenerator.java | 15 + .../ui/NameSuggestionsManager.java | 95 + .../refactoring/ui/RowEditableTableModel.java | 14 + .../refactoring/ui/StringTableCellEditor.java | 36 + .../ui/TypeListCreatingVisitor.java | 34 + .../intellij/refactoring/ui/TypeSelector.java | 137 + .../refactoring/ui/TypeSelectorManager.java | 10 + .../ui/TypeSelectorManagerImpl.java | 200 + .../ui/UsageViewDescriptorAdapter.java | 81 + .../refactoring/ui/VisibilityPanel.java | 142 + .../ui/YesNoPreviewUsagesDialog.java | 77 + .../refactoring/util/CanonicalTypes.java | 200 + .../refactoring/util/ConflictsUtil.java | 87 + .../util/FieldConflictsResolver.java | 119 + .../refactoring/util/JavaDocPolicy.java | 48 + .../refactoring/util/ParameterTablePanel.java | 324 ++ .../util/RefactoringHierarchyUtil.java | 234 + .../util/RefactoringMessageDialog.java | 65 + .../util/RefactoringMessageUtil.java | 310 ++ .../refactoring/util/RefactoringUtil.java | 1474 +++++++ .../refactoring/util/VisibilityUtil.java | 73 + .../ANDCombinedMemberInfoModel.java | 72 + .../ClassMemberReferencesVisitor.java | 84 + .../util/classMembers/ClassMembersUtil.java | 15 + .../ClassThisReferencesVisitor.java | 91 + .../DelegatingMemberInfoModel.java | 57 + .../DependencyMemberInfoModel.java | 71 + .../util/classMembers/ElementNeedsThis.java | 44 + .../InterfaceContainmentVerifier.java | 10 + .../InterfaceDependencyMemberInfoModel.java | 31 + .../InterfaceMemberDependencyGraph.java | 125 + .../MemberDependenciesStorage.java | 56 + .../classMembers/MemberDependencyGraph.java | 36 + .../util/classMembers/MemberInfo.java | 188 + .../util/classMembers/MemberInfoChange.java | 23 + .../MemberInfoChangeListener.java | 15 + .../util/classMembers/MemberInfoModel.java | 36 + .../util/classMembers/MemberInfoStorage.java | 164 + .../MemberInfoTooltipManager.java | 41 + .../UsedByDependencyMemberInfoModel.java | 26 + .../UsedByMemberDependencyGraph.java | 110 + ...ndInterfacesDependencyMemberInfoModel.java | 44 + .../UsesDependencyMemberInfoModel.java | 48 + .../UsesMemberDependencyGraph.java | 129 + .../util/classRefs/ClassInstanceScanner.java | 181 + .../util/classRefs/ClassReferenceScanner.java | 71 + .../ClassReferenceSearchingScanner.java | 26 + .../util/classRefs/ClassReferenceVisitor.java | 28 + .../ClassReferenceVisitorAdapter.java | 36 + .../DelegatingClassReferenceVisitor.java | 48 + .../util/duplicates/DuplicatesFinder.java | 273 ++ .../util/duplicates/DuplicatesImpl.java | 116 + .../duplicates/ExpressionReturnValue.java | 43 + .../refactoring/util/duplicates/Match.java | 204 + .../util/duplicates/MatchProvider.java | 20 + .../duplicates/MethodDuplicatesHandler.java | 154 + .../ReturnStatementReturnValue.java | 34 + .../util/duplicates/ReturnValue.java | 18 + .../util/duplicates/VariableReturnValue.java | 41 + .../util/javadoc/MethodJavaDocHelper.java | 84 + .../util/occurences/BaseOccurenceManager.java | 92 + .../ExpressionOccurenceManager.java | 61 + .../LocalVariableOccurenceManager.java | 29 + .../NotInSuperCallOccurenceFilter.java | 14 + .../NotInSuperOrThisCallFilterBase.java | 29 + .../util/occurences/NotInThisCallFilter.java | 15 + .../util/occurences/OccurenceFilter.java | 7 + .../util/occurences/OccurenceManager.java | 15 + .../DefaultConstructorImplicitUsageInfo.java | 20 + .../DefaultConstructorUsageCollector.java | 22 + .../NoConstructorClassUsageInfo.java | 20 + .../testFramework/EditorActionTestCase.java | 84 + .../intellij/testFramework/IdeaTestCase.java | 476 ++ .../LightCodeInsightTestCase.java | 358 ++ .../testFramework/LightIdeaTestCase.java | 317 ++ .../testFramework/LoggedErrorProcessor.java | 67 + .../testFramework/MockVirtualFile.java | 162 + .../testFramework/ModuleTestCase.java | 123 + .../intellij/testFramework/PsiTestCase.java | 196 + .../intellij/testFramework/PsiTestData.java | 42 + .../intellij/testFramework/PsiTestUtil.java | 88 + .../testFramework/TestEditorManagerImpl.java | 294 ++ .../intellij/testFramework/TestLogger.java | 44 + .../testFramework/TestLoggerFactory.java | 82 + .../TestSourceBasedTestCase.java | 108 + .../intellij/tools/ExternalToolsGroup.java | 84 + .../com/intellij/tools/FilterDialog.java | 174 + .../source/com/intellij/tools/FilterInfo.java | 117 + .../intellij/tools/OutputFiltersDialog.java | 210 + .../com/intellij/tools/SimpleActionGroup.java | 32 + .../source/com/intellij/tools/Tool.java | 367 ++ .../source/com/intellij/tools/ToolAction.java | 30 + .../com/intellij/tools/ToolConfigurable.java | 63 + .../com/intellij/tools/ToolEditorDialog.java | 480 ++ .../com/intellij/tools/ToolManager.java | 131 + .../source/com/intellij/tools/ToolsPanel.java | 444 ++ .../intellij/ui/AbstractToolTipHandler.java | 249 ++ .../intellij/ui/ActivatableLineBorder.java | 35 + .../com/intellij/ui/AnimatingSurface.java | 54 + .../ui/AutoScrollFromSourceHandler.java | 32 + .../ui/AutoScrollToSourceHandler.java | 94 + .../intellij/ui/BooleanTableCellRenderer.java | 42 + .../source/com/intellij/ui/CheckboxTree.java | 147 + .../com/intellij/ui/CheckedTreeNode.java | 24 + .../com/intellij/ui/CollapsiblePanel.java | 125 + .../com/intellij/ui/CollapsingListener.java | 8 + .../source/com/intellij/ui/ColorPanel.java | 313 ++ .../intellij/ui/ColoredTableCellRenderer.java | 25 + .../com/intellij/ui/CompTitledBorder.java | 178 + .../com/intellij/ui/DialogButtonGroup.java | 106 + .../source/com/intellij/ui/EdgeBorder.java | 68 + .../com/intellij/ui/EditorComboBoxEditor.java | 52 + .../intellij/ui/EditorComboBoxRenderer.java | 29 + .../com/intellij/ui/EditorTextField.java | 358 ++ .../ui/FieldPanelWithChangeSupport.java | 15 + .../source/com/intellij/ui/Focusable.java | 8 + .../com/intellij/ui/HeavyweightHint.java | 99 + .../ui/HighlightableCellRenderer.java | 35 + .../intellij/ui/HighlightableComponent.java | 371 ++ .../com/intellij/ui/HighlightedRegion.java | 15 + .../com/intellij/ui/HighlightedText.java | 60 + .../source/com/intellij/ui/Hint.java | 29 + .../source/com/intellij/ui/HintListener.java | 11 + .../intellij/ui/HorizontalLabeledIcon.java | 108 + .../com/intellij/ui/HoverHyperlinkLabel.java | 76 + .../com/intellij/ui/HyperlinkLabel.java | 96 + .../source/com/intellij/ui/IdeGraphics2D.java | 312 ++ .../com/intellij/ui/IdeaBlueMetalTheme.java | 66 + .../source/com/intellij/ui/LabeledIcon.java | 108 + .../com/intellij/ui/LightweightHint.java | 151 + .../com/intellij/ui/ListSpeedSearch.java | 35 + .../com/intellij/ui/ListToolTipHandler.java | 74 + .../source/com/intellij/ui/ListenerUtil.java | 58 + .../com/intellij/ui/MultiLineTooltipUI.java | 53 + .../ui/MultilineTreeCellRenderer.java | 450 ++ .../com/intellij/ui/NonFocusableCheckBox.java | 13 + .../intellij/ui/OneSideRoundedLineBorder.java | 82 + .../com/intellij/ui/PasswordFieldPanel.java | 9 + .../com/intellij/ui/RightAlignedLabelUI.java | 301 ++ .../source/com/intellij/ui/RowIcon.java | 80 + .../com/intellij/ui/SelectionSaver.java | 80 + .../source/com/intellij/ui/SideBorder.java | 61 + .../source/com/intellij/ui/SideBorder2.java | 70 + .../com/intellij/ui/SpeedSearchBase.java | 440 ++ .../source/com/intellij/ui/Splash.java | 70 + .../source/com/intellij/ui/SplittingUtil.java | 43 + .../intellij/ui/StateRestoringCheckBox.java | 88 + .../com/intellij/ui/StrikeoutLabel.java | 33 + .../source/com/intellij/ui/Surface.java | 344 ++ .../com/intellij/ui/TabbedPaneWrapper.java | 558 +++ .../ui/TableCellEditorWithButton.java | 133 + .../source/com/intellij/ui/TableCellKey.java | 33 + .../com/intellij/ui/TableToolTipHandler.java | 73 + .../com/intellij/ui/TreeExpandCollapse.java | 53 + .../source/com/intellij/ui/TreeList.java | 169 + .../com/intellij/ui/TreeSpeedSearch.java | 73 + .../com/intellij/ui/TreeToolTipHandler.java | 63 + .../ui/content/ComponentContentUI.java | 53 + .../ui/content/ContentFactoryImpl.java | 22 + .../ui/content/ContentManagerUtil.java | 44 + .../com/intellij/ui/content/MessageView.java | 4 + .../ui/content/TabbedPaneContentUI.java | 392 ++ .../intellij/ui/content/impl/ContentImpl.java | 162 + .../ui/content/impl/ContentManagerImpl.java | 272 ++ .../ui/content/impl/MessageViewImpl.java | 47 + .../errorView/impl/ErrorViewFactoryImpl.java | 79 + .../com/intellij/ui/plaf/beg/BegBorders.java | 255 ++ .../com/intellij/ui/plaf/beg/BegButtonUI.java | 98 + .../intellij/ui/plaf/beg/BegCellRenderer.java | 247 ++ .../intellij/ui/plaf/beg/BegCheckBoxUI.java | 19 + .../ui/plaf/beg/BegComboBoxButton.java | 179 + .../intellij/ui/plaf/beg/BegComboBoxUI.java | 25 + .../com/intellij/ui/plaf/beg/BegListUI.java | 65 + .../intellij/ui/plaf/beg/BegMenuBorder.java | 59 + .../intellij/ui/plaf/beg/BegMenuItemUI.java | 517 +++ .../ui/plaf/beg/BegPopupMenuBorder.java | 39 + .../ui/plaf/beg/BegRadioButtonUI.java | 19 + .../intellij/ui/plaf/beg/BegResources.java | 10 + .../intellij/ui/plaf/beg/BegScrollBarUI.java | 61 + .../intellij/ui/plaf/beg/BegScrollPaneUI.java | 53 + .../intellij/ui/plaf/beg/BegTabbedPaneUI.java | 372 ++ .../com/intellij/ui/plaf/beg/BegTableUI.java | 68 + .../ui/plaf/beg/BegTreeHandleUtil.java | 45 + .../com/intellij/ui/plaf/beg/BegTreeUI.java | 25 + .../com/intellij/ui/plaf/beg/IdeaMenuUI.java | 468 ++ .../uiDesigner/ActiveDecorationLayer.java | 267 ++ .../uiDesigner/CutCopyPasteSupport.java | 269 ++ .../com/intellij/uiDesigner/DesignSpacer.java | 23 + .../com/intellij/uiDesigner/DragLayer.java | 33 + .../uiDesigner/DragSelectionProcessor.java | 338 ++ .../intellij/uiDesigner/ErrorAnalizer.java | 247 ++ .../com/intellij/uiDesigner/ErrorInfo.java | 23 + .../intellij/uiDesigner/EventProcessor.java | 30 + .../intellij/uiDesigner/FormEditingUtil.java | 691 +++ .../com/intellij/uiDesigner/GlassLayer.java | 81 + .../intellij/uiDesigner/GridChangeUtil.java | 231 + .../uiDesigner/GroupSelectionProcessor.java | 127 + .../uiDesigner/GuiDesignerConfigurable.java | 814 ++++ .../uiDesigner/GuiDesignerConfiguration.java | 46 + .../com/intellij/uiDesigner/GuiEditor.java | 804 ++++ .../com/intellij/uiDesigner/HSpacer.java | 91 + .../uiDesigner/HierarchyChangeListener.java | 15 + .../uiDesigner/InplaceEditingLayer.java | 323 ++ .../uiDesigner/InsertComponentProcessor.java | 295 ++ .../intellij/uiDesigner/LoaderFactory.java | 116 + .../intellij/uiDesigner/MainProcessor.java | 278 ++ .../com/intellij/uiDesigner/Painter.java | 305 ++ .../uiDesigner/PassiveDecorationLayer.java | 73 + .../com/intellij/uiDesigner/Properties.java | 98 + .../uiDesigner/PsiPropertiesProvider.java | 108 + .../uiDesigner/RadAtomicComponent.java | 30 + .../com/intellij/uiDesigner/RadComponent.java | 450 ++ .../com/intellij/uiDesigner/RadContainer.java | 570 +++ .../uiDesigner/RadErrorComponent.java | 91 + .../com/intellij/uiDesigner/RadHSpacer.java | 23 + .../intellij/uiDesigner/RadRootContainer.java | 68 + .../intellij/uiDesigner/RadScrollPane.java | 63 + .../com/intellij/uiDesigner/RadSplitPane.java | 100 + .../intellij/uiDesigner/RadTabbedPane.java | 204 + .../com/intellij/uiDesigner/RadVSpacer.java | 24 + .../intellij/uiDesigner/ResizeProcessor.java | 124 + .../intellij/uiDesigner/SelectionState.java | 63 + .../intellij/uiDesigner/SelectionWatcher.java | 64 + .../com/intellij/uiDesigner/VSpacer.java | 91 + .../uiDesigner/XYLayoutManagerImpl.java | 55 + .../com/intellij/uiDesigner/XmlReader.java | 179 + .../com/intellij/uiDesigner/XmlWriter.java | 142 + .../actions/AbstractMoveSelectionAction.java | 123 + .../actions/CreateDialogAction.java | 256 ++ .../actions/DataBindingWizardAction.java | 169 + .../actions/ExpandSelectionAction.java | 81 + .../actions/MoveSelectionToDownAction.java | 25 + .../actions/MoveSelectionToLeftAction.java | 25 + .../actions/MoveSelectionToRightAction.java | 25 + .../actions/MoveSelectionToUpAction.java | 25 + .../uiDesigner/actions/PreviewFormAction.java | 287 ++ .../uiDesigner/actions/ShowJavadocAction.java | 84 + .../actions/ShrinkSelectionAction.java | 52 + .../actions/StartInplaceEditingAction.java | 53 + .../componentTree/ComponentPtr.java | 74 + .../componentTree/ComponentPtrDescriptor.java | 56 + .../ComponentSelectionListener.java | 13 + .../componentTree/ComponentTree.java | 319 ++ .../componentTree/ComponentTreeBuilder.java | 239 + .../componentTree/ComponentTreeStructure.java | 107 + .../componentTree/QuickFixManagerImpl.java | 47 + .../componentTree/RootDescriptor.java | 24 + .../uiDesigner/editor/MyEditorState.java | 43 + .../uiDesigner/editor/UIFormEditor.java | 141 + .../editor/UIFormEditorProvider.java | 73 + .../uiDesigner/make/BindingsCache.java | 92 + .../uiDesigner/make/CopyResourcesUtil.java | 55 + .../make/Form2ByteCodeCompiler.java | 369 ++ .../uiDesigner/make/Form2SourceCompiler.java | 259 ++ .../make/FormSourceCodeGenerator.java | 783 ++++ .../uiDesigner/palette/ComponentItem.java | 270 ++ .../palette/ComponentItemDialog.java | 126 + .../uiDesigner/palette/GroupItem.java | 94 + .../intellij/uiDesigner/palette/Palette.java | 828 ++++ .../IntrospectedProperty.java | 63 + .../propertyInspector/Property.java | 101 + .../propertyInspector/PropertyEditor.java | 110 + .../PropertyEditorAdapter.java | 13 + .../PropertyEditorListener.java | 31 + .../propertyInspector/PropertyInspector.java | 120 + .../PropertyInspectorTable.java | 1000 +++++ .../propertyInspector/PropertyRenderer.java | 25 + .../QuickFixManagerImpl.java | 55 + .../editors/BindingEditor.java | 145 + .../editors/BooleanEditor.java | 49 + .../editors/BorderTypeEditor.java | 48 + .../editors/ComboBoxPropertyEditor.java | 56 + .../propertyInspector/editors/IntEditor.java | 63 + .../editors/IntEnumEditor.java | 90 + .../editors/string/KeyChooserDialog.java | 182 + .../editors/string/StringEditor.java | 152 + .../editors/string/StringEditorDialog.java | 261 ++ .../properties/AbstractDimensionPropery.java | 121 + .../properties/AbstractInsetsProperty.java | 191 + .../properties/BindingProperty.java | 123 + .../properties/BorderProperty.java | 140 + .../properties/ClassToBindProperty.java | 141 + .../properties/HGapProperty.java | 55 + .../properties/HSizePolicyProperty.java | 21 + .../properties/IntroBooleanProperty.java | 42 + .../properties/IntroDimensionProperty.java | 47 + .../properties/IntroDoubleProperty.java | 43 + .../properties/IntroInsetsProperty.java | 51 + .../properties/IntroIntProperty.java | 52 + .../properties/IntroRectangleProperty.java | 202 + .../properties/IntroStringProperty.java | 192 + .../properties/MarginProperty.java | 47 + .../properties/MaximumSizeProperty.java | 23 + .../properties/MinimumSizeProperty.java | 23 + .../properties/PreferredSizeProperty.java | 23 + .../SameSizeHorizontallyProperty.java | 64 + .../SameSizeVerticallyProperty.java | 64 + .../properties/SizePolicyProperty.java | 137 + .../properties/VGapProperty.java | 55 + .../properties/VSizePolicyProperty.java | 21 + .../renderers/BooleanRenderer.java | 26 + .../renderers/ClassToBindRenderer.java | 30 + .../renderers/DimensionRenderer.java | 14 + .../renderers/InsetsPropertyRenderer.java | 26 + .../renderers/IntEnumRenderer.java | 33 + .../renderers/LabelPropertyRenderer.java | 44 + .../renderers/RectangleRenderer.java | 27 + .../renderers/SizePolicyRenderer.java | 42 + .../renderers/StringRenderer.java | 22 + .../quickFixes/CreateClassToBindFix.java | 112 + .../uiDesigner/quickFixes/CreateFieldFix.java | 155 + .../quickFixes/FocusListenerImpl.java | 34 + .../quickFixes/LightBulbComponentImpl.java | 60 + .../uiDesigner/quickFixes/QuickFix.java | 34 + .../quickFixes/QuickFixManager.java | 202 + .../uiDesigner/quickFixes/ShowHintAction.java | 43 + .../quickFixes/VisibilityWatcherImpl.java | 31 + .../uiDesigner/wizard/BeanProperty.java | 63 + .../wizard/BeanPropertyListCellRenderer.java | 38 + .../wizard/BeanPropertyTableCellEditor.java | 47 + .../wizard/BeanPropertyTableCellRenderer.java | 62 + .../intellij/uiDesigner/wizard/BeanStep.java | 203 + .../uiDesigner/wizard/BindCompositeStep.java | 68 + .../wizard/BindToExistingBeanStep.java | 273 ++ .../uiDesigner/wizard/BindToNewBeanStep.java | 154 + .../uiDesigner/wizard/DataBindingWizard.java | 86 + .../uiDesigner/wizard/FormProperty.java | 77 + .../wizard/FormProperty2BeanProperty.java | 22 + .../wizard/FormPropertyTableCellRenderer.java | 90 + .../intellij/uiDesigner/wizard/Generator.java | 726 +++ .../uiDesigner/wizard/WizardData.java | 80 + .../intellij/unscramble/UnscrambleAction.java | 21 + .../intellij/unscramble/UnscrambleDialog.java | 356 ++ .../UnscrambleFromClipboardAction.java | 40 + .../intellij/usageView/FindUsagesCommand.java | 15 + .../com/intellij/usageView/UsageViewUtil.java | 534 +++ .../usageView/impl/SelectInEditorHandler.java | 36 + .../usageView/impl/UsageViewManagerImpl.java | 176 + .../com/intellij/util/ActionRunner.java | 107 + .../com/intellij/util/EditorPopupHandler.java | 28 + .../com/intellij/util/IJSwingUtilities.java | 160 + .../intellij/util/ScrambledInputStream.java | 51 + .../intellij/util/ScrambledOutputStream.java | 34 + .../util/config/AbstractProperty.java | 80 + .../intellij/util/config/BooleanProperty.java | 15 + .../ExternalizablePropertyContainer.java | 145 + .../intellij/util/config/Externalizer.java | 95 + .../com/intellij/util/config/IntProperty.java | 15 + .../intellij/util/config/ListProperty.java | 46 + .../util/config/StorageAccessors.java | 50 + .../intellij/util/config/StorageProperty.java | 33 + .../intellij/util/config/StringProperty.java | 13 + .../util/config/ToggleBooleanProperty.java | 42 + .../intellij/util/config/ValueProperty.java | 26 + .../com/intellij/util/io/ByteBufferMap.java | 176 + .../util/io/ByteBufferMapWriteHandler.java | 100 + .../util/io/ByteBufferRADataInput.java | 91 + .../com/intellij/util/io/FileByteBuffer.java | 254 ++ .../com/intellij/util/io/FileKeyProvider.java | 48 + .../util/io/IntArrayValueProvider.java | 85 + .../intellij/util/io/IntValueProvider.java | 27 + .../intellij/util/io/IntegerKeyProvider.java | 44 + .../util/io/RandomAccessDataInput.java | 11 + .../intellij/util/io/RecordDataOutput.java | 12 + .../intellij/util/io/StringKeyProvider.java | 74 + .../com/intellij/util/io/WriteableMap.java | 17 + .../intellij/util/io/WriteableMapAdapter.java | 39 + .../io/WriteableTIntObjectMapAdapter.java | 38 + .../util/net/AuthenticationDialog.java | 68 + .../util/net/AuthenticationPanel.java | 38 + .../util/net/HTTPProxySettingsDialog.java | 47 + .../util/net/HTTPProxySettingsPanel.java | 133 + .../intellij/util/net/HttpConfigurable.java | 112 + .../intellij/util/net/IOExceptionDialog.java | 85 + .../com/intellij/util/net/LockException.java | 14 + .../properties/EncodingAwareProperties.java | 28 + .../util/text/ElementPresentation.java | 349 ++ .../CellEditorComponentWithBrowseButton.java | 100 + .../util/ui/tree/TreeModelAdapter.java | 21 + .../xml/actions/ValidateXmlAction.java | 64 + .../xml/actions/ValidateXmlActionHandler.java | 402 ++ .../xml/impl/BasicXmlAttributeDescriptor.java | 56 + .../impl/dtd/XmlAttributeDescriptorImpl.java | 102 + .../impl/dtd/XmlElementDescriptorImpl.java | 252 ++ .../xml/impl/dtd/XmlNSDescriptorImpl.java | 138 + .../schema/AnyXmlAttributeDescriptor.java | 88 + .../impl/schema/AnyXmlElementDescriptor.java | 88 + .../impl/schema/ComplexTypeDescriptor.java | 369 ++ .../xml/impl/schema/SimpleTypeDescriptor.java | 12 + .../xml/impl/schema/StdTypeDescriptor.java | 12 + .../xml/impl/schema/TypeDescriptor.java | 9 + .../schema/XmlAttributeDescriptorImpl.java | 83 + .../schema/XmlElementDescriptorByType.java | 67 + .../impl/schema/XmlElementDescriptorImpl.java | 263 ++ .../xml/impl/schema/XmlNSDescriptorImpl.java | 484 ++ .../com/intellij/xml/util/HtmlUtil.java | 122 + .../xml/util/XmlNSDescriptorSequence.java | 137 + .../xml/util/XmlResourceResolver.java | 130 + .../source/com/intellij/xml/util/XmlUtil.java | 824 ++++ .../CompositeAttributeTagDescriptor.java | 33 + .../util/documentation/EntityDescriptor.java | 50 + .../HtmlAttributeDescriptor.java | 54 + .../documentation/HtmlDescriptorsTable.java | 127 + .../HtmlDocumentationProvider.java | 245 ++ .../util/documentation/HtmlTagDescriptor.java | 38 + .../XHtmlDocumentationProvider.java | 50 + .../XmlDocumentationProvider.java | 157 + .../dependencies/src/com/package1/Class1.java | 7 + .../dependencies/src/com/package1/Class2.java | 4 + .../inspection/canBeFinal/SCR6073/src/A.java | 6 + .../inspection/canBeFinal/SCR6781/src/A.java | 12 + .../inspection/canBeFinal/SCR6845/src/A.java | 3 + .../inspection/canBeFinal/SCR6861/src/A.java | 12 + .../canBeFinal/SCR7737/ext_src/B.java | 6 + .../inspection/canBeFinal/SCR7737/src/A.java | 6 + .../canBeFinal/fieldAndTryBlock/src/Foo.java | 10 + .../inspection/canBeFinal/fields/src/Foo.java | 23 + .../canBeFinal/methodInheritance/src/a.java | 10 + .../canBeFinal/privateInners/src/Foo.java | 10 + .../simpleClassInheritance/src/Foo.java | 5 + .../simpleClassInheritance1/src/Foo.java | 5 + .../CatchParameterCantBeNull/src/Test.java | 16 + .../src/GenericInstanceof.java | 12 + .../dataFlow/Instanceof/src/Foo.java | 14 + .../dataFlow/SCR13626/src/Test.java | 16 + .../inspection/dataFlow/SCR13702/src/Foo.java | 5 + .../inspection/dataFlow/SCR13871/src/Aaa.java | 12 + .../dataFlow/SCR14314/src/Finally.java | 37 + .../dataFlow/SCR14819/src/Test.java | 17 + .../dataFlow/SCR15162/src/NullTest.java | 9 + .../dataFlow/SCR15406/src/CodeFlowTest.java | 28 + .../dataFlow/SCR18186/src/Test.java | 61 + .../dataFlow/SCR39950/src/Test.java | 12 + .../inspection/dataFlow/andEq/src/Test.java | 8 + .../dataFlow/caseAndNpe/src/CaseAndNpe.java | 122 + .../inspection/dataFlow/cce/src/Cce.java | 19 + .../exceptionCFG/src/ExceptionCFG.java | 34 + .../inspection/dataFlow/inst/src/Inst.java | 27 + .../inspection/dataFlow/npe1/src/Npe.java | 9 + .../dataFlow/nullableField/src/Test.java | 8 + .../inspection/dataFlow/orBug/src/Test.java | 8 + .../dataFlow/scrIDEA1/src/Test.java | 16 + .../dataFlow/thisInstanceof/src/Test.java | 5 + .../dataFlow/wrongEqualTypes/src/Test.java | 8 + .../inspection/dataFlow/xor/src/Test.java | 8 + .../SCR28019/src/AsynchronousImageLoader.java | 17 + .../inspection/defUse/SCR40364/src/Test.java | 16 + .../defUse/SCR5144/src/AssignTest.java | 10 + .../defUse/SCR6843/src/NotUsedTest.java | 7 + .../defUse/arrayIndexUsages/src/Foo.java | 11 + .../defUse/unusedVariable/src/Foo.java | 5 + .../emptyMethod/SCR8321/src/MyAdapter.java | 5 + .../SCR8321/src/MyAdapterUsage.java | 8 + .../emptyMethod/SCR8321/src/MyListener.java | 5 + .../externalOverride/ext_src/Derived.java | 5 + .../externalOverride/src/Base.java | 5 + .../emptyMethod/superCall/src/Base.java | 3 + .../emptyMethod/superCall/src/Derived.java | 5 + .../localCanBeFinal/SCR11757/src/Test.java | 24 + .../SCR6744_1/src/foo/Test.java | 6 + .../SCR6744_2/src/foo/Test.java | 7 + .../SCR6744_3/src/foo/Test.java | 7 + .../SCR6744_4/src/foo/Test.java | 8 + .../SCR6744_5/src/foo/Test.java | 9 + .../SCR6744_6/src/foo/Test.java | 10 + .../localCanBeFinal/SCR7428/src/Junk.java | 20 + .../localCanBeFinal/SCR7428_1/src/Junk.java | 24 + .../SCR7601/src/TestFinal2.java | 8 + .../localCanBeFinal/if/src/Test.java | 11 + .../incompleteAssignment/src/Test.java | 13 + .../multiWriteNoRead/src/Test.java | 9 + .../localCanBeFinal/parameters/src/Test.java | 19 + .../redundantThrow/SCR14543/src/E.java | 14 + .../redundantThrow/SCR6858/src/Foo.java | 6 + .../SCR8322/src/aPackage/AClass.java | 13 + .../SCR8322/src/aPackage/AClassTwo.java | 10 + .../SCR8322/src/aPackage/AnInterface.java | 7 + .../visibility/SCR11792/src/Foo.java | 10 + .../SCR5008/src/marti/p1/SubClass.java | 6 + .../SCR5008/src/marti/p1/SuperClass.java | 5 + .../inspection/visibility/SCR6856/src/A.java | 12 + .../visibility/innerConstructor/src/Foo.java | 7 + .../src/package1/PackageLevelServer.java | 5 + .../src/package1/PublicServer.java | 5 + .../packageLevelTops/src/package2/Client.java | 9 + .../src/com/package1/Class1.java | 4 + .../src/com/package1/Class2.java | 8 + .../src/com/package1/Class4.java | 4 + .../src/com/package1/Form1.java | 4 + .../arrayIndexOutOfBounds/src/bla/Bla.java | 4 + .../arrayIndexOutOfBounds/src/bla/Blu.java | 4 + .../constantValues/ClassWithConstants.java | 19 + .../testData/psi/normalizeDeclaration/1.java | 5 + .../psi/normalizeDeclaration/1_after.java | 7 + .../testData/psi/normalizeDeclaration/2.java | 5 + .../psi/normalizeDeclaration/2_after.java | 7 + .../psi/normalizeDeclaration/SCR6549.java | 5 + .../normalizeDeclaration/SCR6549_after.java | 6 + .../psi/normalizeDeclaration/SCR9467.java | 5 + .../psi/normalizeDeclaration/SCR9467_1.java | 3 + .../normalizeDeclaration/SCR9467_1_after.java | 5 + .../normalizeDeclaration/SCR9467_after.java | 7 + .../changeClassSignature/AddParam.java | 9 + .../changeClassSignature/NoParams.java | 10 + .../changeClassSignature/RemoveAllParams.java | 5 + .../changeClassSignature/ReorderParams.java | 8 + .../changeSignature/AddRuntimeException.java | 8 + .../changeSignature/AlreadyHandled.java | 8 + .../changeSignature/CovariantReturnType.java | 19 + .../changeSignature/DefaultConstructor.java | 11 + .../changeSignature/EnumConstructor.java | 7 + .../changeSignature/GenerateDelegate.java | 16 + .../GenerateDelegateConstructor.java | 10 + .../GenerateDelegateDefaultConstructor.java | 15 + .../GenerateDelegateForAbstract.java | 8 + ...erateDelegateWithParametersReordering.java | 18 + .../GenerateDelegateWithReturn.java | 9 + .../changeSignature/GenericTypes.java | 7 + .../GenericTypesInOldParameters.java | 11 + .../changeSignature/ParameterReorder.java | 11 + .../changeSignature/ReorderExceptions.java | 34 + .../refactoring/changeSignature/SCR40895.java | 9 + .../refactoring/changeSignature/Simple.java | 7 + .../TypeParametersInMethod.java | 9 + .../changeSignature/UseAnyVariable.java | 14 + .../refactoring/changeSignature/Varargs1.java | 10 + .../convertToInstanceMethod/Interface.java | 22 + .../convertToInstanceMethod/Interface2.java | 16 + .../InterfaceTypeParameter.java | 13 + .../convertToInstanceMethod/Simple.java | 16 + .../TypeParameter.java | 7 + .../refactoring/extractMethod/AnonInner.java | 21 + .../extractMethod/AnonInner_after.java | 25 + .../extractMethod/BooleanExpression.java | 5 + .../BooleanExpression_after.java | 9 + .../extractMethod/CodeDuplicates.java | 8 + .../extractMethod/CodeDuplicates2.java | 15 + .../extractMethod/CodeDuplicates2_after.java | 19 + .../extractMethod/CodeDuplicates3.java | 15 + .../extractMethod/CodeDuplicates3_after.java | 17 + .../extractMethod/CodeDuplicates4.java | 15 + .../extractMethod/CodeDuplicates4_after.java | 17 + .../extractMethod/CodeDuplicates5.java | 23 + .../extractMethod/CodeDuplicates5_after.java | 26 + .../CodeDuplicatesWithOutputValue.java | 16 + .../CodeDuplicatesWithOutputValue1.java | 19 + .../CodeDuplicatesWithOutputValue1_after.java | 23 + .../CodeDuplicatesWithOutputValue_after.java | 21 + .../CodeDuplicatesWithReturn.java | 13 + .../CodeDuplicatesWithReturn2.java | 12 + .../CodeDuplicatesWithReturn2_after.java | 15 + .../CodeDuplicatesWithReturn_after.java | 16 + .../extractMethod/CodeDuplicates_after.java | 12 + .../extractMethod/ExitPoints1.java | 9 + .../extractMethod/ExitPoints2.java | 10 + .../extractMethod/ExitPoints3.java | 10 + .../extractMethod/ExitPoints4.java | 12 + .../extractMethod/ExitPoints5.java | 12 + .../extractMethod/ExitPoints5_after.java | 16 + .../extractMethod/ExitPointsInsideLoop.java | 9 + .../extractMethod/ExpressionDuplicates.java | 10 + .../ExpressionDuplicates_after.java | 14 + .../extractMethod/ExtractFromAnonymous.java | 9 + .../ExtractFromAnonymous_after.java | 16 + .../extractMethod/ExtractFromCodeBlock.java | 10 + .../ExtractFromCodeBlock_after.java | 12 + .../extractMethod/ExtractFromFinally.java | 11 + .../ExtractFromFinally_after.java | 15 + .../extractMethod/ExtractFromTryFinally.java | 10 + .../ExtractFromTryFinally_after.java | 16 + .../extractMethod/FinalOutputVar.java | 8 + .../extractMethod/FinalOutputVar_after.java | 13 + .../refactoring/extractMethod/Finally.java | 22 + .../extractMethod/Finally_after.java | 26 + .../refactoring/extractMethod/ForEach.java | 9 + .../extractMethod/ForEach_after.java | 13 + .../refactoring/extractMethod/LesyaBug.java | 15 + .../extractMethod/LesyaBug_after.java | 20 + .../extractMethod/OneBranchAssignment.java | 13 + .../OneBranchAssignment_after.java | 19 + .../refactoring/extractMethod/SCR12245.java | 11 + .../extractMethod/SCR12245_after.java | 15 + .../refactoring/extractMethod/SCR15815.java | 11 + .../extractMethod/SCR15815_after.java | 16 + .../refactoring/extractMethod/SCR27887.java | 41 + .../extractMethod/SCR27887_after.java | 46 + .../refactoring/extractMethod/SCR28427.java | 5 + .../extractMethod/SCR28427_after.java | 9 + .../refactoring/extractMethod/SCR32924.java | 6 + .../extractMethod/SCR32924_after.java | 10 + .../refactoring/extractMethod/Scr10464.java | 9 + .../extractMethod/Scr10464_after.java | 13 + .../refactoring/extractMethod/Scr6241.java | 7 + .../extractMethod/Scr6241_after.java | 11 + .../refactoring/extractMethod/Scr7091.java | 29 + .../extractMethod/Scr7091_after.java | 33 + .../refactoring/extractMethod/Scr9852.java | 9 + .../extractMethod/Scr9852_after.java | 13 + .../refactoring/extractMethod/TryFinally.java | 13 + .../extractMethod/TryFinallyInsideFor.java | 17 + .../TryFinallyInsideFor_after.java | 21 + .../extractMethod/TryFinally_after.java | 17 + .../extractMethod/UnusedInitializedVar.java | 14 + .../UnusedInitializedVar_after.java | 21 + .../extractMethod/UseVarAfterTry.java | 13 + .../extractMethod/UseVarAfterTry_after.java | 19 + .../abstractBase/after/A.java | 11 + .../abstractBase/after/Base.java | 2 + .../abstractBase/before/A.java | 2 + .../abstractBase/before/Base.java | 2 + .../abstractBase1/after/A.java | 9 + .../abstractBase1/after/Base.java | 2 + .../abstractBase1/before/A.java | 5 + .../abstractBase1/before/Base.java | 2 + .../getter/after/A.java | 7 + .../getter/after/B.java | 15 + .../getter/before/A.java | 7 + .../getter/before/B.java | 2 + .../hierarchy/after/A.java | 4 + .../hierarchy/after/Base.java | 2 + .../hierarchy/after/Test.java | 3 + .../hierarchy/after/X.java | 10 + .../hierarchy/before/A.java | 4 + .../hierarchy/before/Base.java | 2 + .../hierarchy/before/Test.java | 3 + .../hierarchy/before/X.java | 8 + .../innerClass/after/A.java | 17 + .../innerClass/after/Base.java | 11 + .../innerClass/before/A.java | 8 + .../innerClass/before/Base.java | 11 + .../innerClassForInterface/after/A.java | 20 + .../after/BaseClass.java | 7 + .../after/BaseInterface.java | 3 + .../innerClassForInterface/before/A.java | 12 + .../before/BaseClass.java | 7 + .../before/BaseInterface.java | 3 + .../after/A.java | 18 + .../after/BaseClass.java | 7 + .../after/BaseInterface.java | 3 + .../before/A.java | 8 + .../before/BaseClass.java | 7 + .../before/BaseInterface.java | 3 + .../interfaceDelegation/after/A.java | 21 + .../interfaceDelegation/after/Intf.java | 4 + .../interfaceDelegation/after/Usage.java | 12 + .../interfaceDelegation/before/A.java | 9 + .../interfaceDelegation/before/Intf.java | 4 + .../interfaceDelegation/before/Usage.java | 12 + .../interfaces/after/A.java | 11 + .../interfaces/after/Base.java | 7 + .../interfaces/after/I.java | 3 + .../interfaces/after/J.java | 3 + .../interfaces/after/Usage.java | 23 + .../interfaces/before/A.java | 2 + .../interfaces/before/Base.java | 7 + .../interfaces/before/I.java | 3 + .../interfaces/before/J.java | 3 + .../interfaces/before/Usage.java | 23 + .../overridenMethods/after/A.java | 23 + .../overridenMethods/after/Base.java | 12 + .../overridenMethods/before/A.java | 13 + .../overridenMethods/before/Base.java | 12 + .../scr20557/after/xxx/SCR20557.java | 531 +++ .../scr20557/before/xxx/SCR20557.java | 511 +++ .../simpleInsertion/after/A.java | 7 + .../simpleInsertion/after/B.java | 11 + .../simpleInsertion/before/A.java | 7 + .../simpleInsertion/before/B.java | 2 + .../subClass/after/A.java | 20 + .../subClass/after/B.java | 5 + .../subClass/after/DelegatedBase.java | 7 + .../subClass/after/Usage.java | 20 + .../subClass/before/A.java | 10 + .../subClass/before/B.java | 5 + .../subClass/before/DelegatedBase.java | 7 + .../subClass/before/Usage.java | 20 + .../subClassNoMethods/after/A.java | 16 + .../subClassNoMethods/after/B.java | 5 + .../after/DelegatedBase.java | 7 + .../subClassNoMethods/after/Usage.java | 20 + .../subClassNoMethods/before/A.java | 10 + .../subClassNoMethods/before/B.java | 5 + .../before/DelegatedBase.java | 7 + .../subClassNoMethods/before/Usage.java | 20 + .../subinterface/after/A.java | 12 + .../subinterface/after/B.java | 2 + .../subinterface/after/J.java | 2 + .../subinterface/after/Usage.java | 6 + .../subinterface/before/A.java | 4 + .../subinterface/before/B.java | 2 + .../subinterface/before/J.java | 2 + .../subinterface/before/Usage.java | 6 + .../superCalls/after/A.java | 9 + .../superCalls/after/B.java | 11 + .../superCalls/before/A.java | 9 + .../superCalls/before/B.java | 9 + .../refactoring/inlineLocal/Inference.java | 12 + .../refactoring/inlineLocal/Qualifier.java | 12 + .../refactoring/inlineMethod/ArrayAccess.java | 11 + .../refactoring/inlineMethod/CallInFor.java | 19 + .../refactoring/inlineMethod/CallUnderIf.java | 14 + .../inlineMethod/ChainingConstructor.java | 22 + .../inlineMethod/ConflictingField.java | 11 + .../inlineMethod/FieldInitializer.java | 7 + .../inlineMethod/FinalParameters.java | 10 + .../inlineMethod/FinalParameters1.java | 15 + .../refactoring/inlineMethod/InlineParms.java | 30 + .../inlineMethod/InlineWithQualifier.java | 33 + .../InlineWithQualifierFromSuper.java | 17 + .../inlineMethod/InlineWithTry.java | 12 + .../inlineMethod/LocalVariableResult.java | 17 + .../refactoring/inlineMethod/NameClash.java | 12 + .../refactoring/inlineMethod/SCR20655.java | 11 + .../refactoring/inlineMethod/SCR22644.java | 17 + .../refactoring/inlineMethod/SCR31093.java | 10 + .../refactoring/inlineMethod/SCR37742.java | 12 + .../refactoring/inlineMethod/Scr10884.java | 16 + .../refactoring/inlineMethod/Scr13831.java | 12 + .../refactoring/inlineMethod/SideEffect.java | 11 + .../inlineMethod/StaticFieldInitializer.java | 8 + .../refactoring/inlineMethod/Try.java | 14 + .../inlineMethod/TrySynchronized.java | 14 + .../inlineMethod/VoidWithReturn.java | 9 + .../refactoring/introduceField/after1.java | 8 + .../refactoring/introduceField/before1.java | 6 + .../introduceParameter/after01.java | 5 + .../introduceParameter/after02.java | 18 + .../introduceParameter/after03.java | 12 + .../introduceParameter/after04.java | 13 + .../introduceParameter/after05.java | 14 + .../introduceParameter/after06.java | 14 + .../introduceParameter/after07.java | 14 + .../introduceParameter/after08.java | 18 + .../introduceParameter/after09.java | 16 + .../introduceParameter/after10.java | 16 + .../introduceParameter/after11.java | 16 + .../introduceParameter/after12.java | 16 + .../introduceParameter/after13.java | 18 + .../introduceParameter/after14.java | 6 + .../introduceParameter/after15.java | 16 + .../introduceParameter/after16.java | 19 + .../introduceParameter/after17.java | 16 + .../introduceParameter/after18.java | 5 + .../introduceParameter/after19.java | 23 + .../introduceParameter/after20.java | 10 + .../introduceParameter/after21.java | 10 + .../introduceParameter/after22.java | 18 + .../introduceParameter/after23.java | 25 + .../introduceParameter/after24.java | 9 + .../introduceParameter/after25.java | 8 + .../introduceParameter/after26.java | 9 + .../introduceParameter/after27.java | 8 + .../introduceParameter/after28.java | 14 + .../introduceParameter/after29.java | 17 + .../introduceParameter/after30.java | 12 + .../introduceParameter/before01.java | 5 + .../introduceParameter/before02.java | 18 + .../introduceParameter/before03.java | 12 + .../introduceParameter/before04.java | 13 + .../introduceParameter/before05.java | 14 + .../introduceParameter/before06.java | 14 + .../introduceParameter/before07.java | 14 + .../introduceParameter/before08.java | 18 + .../introduceParameter/before09.java | 16 + .../introduceParameter/before10.java | 16 + .../introduceParameter/before11.java | 16 + .../introduceParameter/before12.java | 15 + .../introduceParameter/before13.java | 18 + .../introduceParameter/before14.java | 6 + .../introduceParameter/before15.java | 15 + .../introduceParameter/before16.java | 18 + .../introduceParameter/before17.java | 13 + .../introduceParameter/before18.java | 5 + .../introduceParameter/before19.java | 21 + .../introduceParameter/before20.java | 10 + .../introduceParameter/before21.java | 10 + .../introduceParameter/before22.java | 17 + .../introduceParameter/before23.java | 25 + .../introduceParameter/before24.java | 9 + .../introduceParameter/before25.java | 7 + .../introduceParameter/before26.java | 8 + .../introduceParameter/before27.java | 8 + .../introduceParameter/before28.java | 13 + .../introduceParameter/before29.java | 17 + .../introduceParameter/before30.java | 12 + .../refactoring/makeMethodStatic/after1.java | 4 + .../makeMethodStatic/after10-np.java | 13 + .../refactoring/makeMethodStatic/after10.java | 13 + .../refactoring/makeMethodStatic/after11.java | 12 + .../refactoring/makeMethodStatic/after12.java | 6 + .../refactoring/makeMethodStatic/after13.java | 5 + .../refactoring/makeMethodStatic/after14.java | 11 + .../refactoring/makeMethodStatic/after15.java | 9 + .../refactoring/makeMethodStatic/after16.java | 11 + .../refactoring/makeMethodStatic/after17.java | 10 + .../refactoring/makeMethodStatic/after18.java | 5 + .../refactoring/makeMethodStatic/after19.java | 7 + .../refactoring/makeMethodStatic/after2.java | 6 + .../refactoring/makeMethodStatic/after3.java | 6 + .../refactoring/makeMethodStatic/after4.java | 6 + .../refactoring/makeMethodStatic/after5.java | 6 + .../refactoring/makeMethodStatic/after6.java | 6 + .../refactoring/makeMethodStatic/after7.java | 10 + .../refactoring/makeMethodStatic/after8.java | 12 + .../refactoring/makeMethodStatic/after9.java | 12 + .../refactoring/makeMethodStatic/before1.java | 4 + .../makeMethodStatic/before10.java | 13 + .../makeMethodStatic/before11.java | 12 + .../makeMethodStatic/before12.java | 6 + .../makeMethodStatic/before13.java | 5 + .../makeMethodStatic/before14.java | 11 + .../makeMethodStatic/before15.java | 9 + .../makeMethodStatic/before16.java | 9 + .../makeMethodStatic/before17.java | 9 + .../makeMethodStatic/before18.java | 5 + .../makeMethodStatic/before19.java | 7 + .../refactoring/makeMethodStatic/before2.java | 6 + .../refactoring/makeMethodStatic/before3.java | 6 + .../refactoring/makeMethodStatic/before4.java | 6 + .../refactoring/makeMethodStatic/before5.java | 6 + .../refactoring/makeMethodStatic/before6.java | 6 + .../refactoring/makeMethodStatic/before7.java | 10 + .../refactoring/makeMethodStatic/before8.java | 12 + .../refactoring/makeMethodStatic/before9.java | 12 + .../migration/package/after/p1/C.java | 7 + .../migration/package/after/p1/C1.java | 7 + .../migration/package/before/p1/C.java | 7 + .../migration/package/before/p1/C1.java | 7 + .../after/p1/C.java | 7 + .../after/p1/C1.java | 7 + .../before/p1/C.java | 7 + .../before/p1/C1.java | 7 + .../toNonExistentClass/after/p1/C.java | 7 + .../toNonExistentClass/after/p1/C1.java | 8 + .../toNonExistentClass/before/p1/C.java | 7 + .../toNonExistentClass/before/p1/C1.java | 7 + .../after/p1/C.java | 7 + .../after/p1/C1.java | 7 + .../before/p1/C.java | 7 + .../before/p1/C1.java | 7 + .../contextChange1/after/pack1/Class2.java | 4 + .../contextChange1/after/pack2/Class1.java | 7 + .../contextChange1/before/pack1/Class1.java | 5 + .../contextChange1/before/pack1/Class2.java | 4 + .../contextChange2/after/pack1/Class2.java | 4 + .../contextChange2/after/pack2/Class1.java | 9 + .../contextChange2/before/pack1/Class1.java | 7 + .../contextChange2/before/pack1/Class2.java | 4 + .../moveClass/jsp/after/WEB-INF/TestTEI.java | 13 + .../moveClass/jsp/after/pack2/TestClass.java | 4 + .../moveClass/jsp/before/WEB-INF/TestTEI.java | 13 + .../moveClass/jsp/before/pack1/TestClass.java | 4 + .../moveClass/localClass/after/pack2/A.java | 9 + .../moveClass/localClass/before/pack1/A.java | 9 + .../moveMultiple1/after/pack2/Class1.java | 6 + .../moveMultiple1/after/pack2/Class2.java | 4 + .../moveMultiple1/before/pack1/Class1.java | 6 + .../moveMultiple1/before/pack1/Class2.java | 4 + .../moveClass/nonJava/after/pack2/Class1.java | 4 + .../nonJava/before/pack1/Class1.java | 4 + .../stringsAndComments/after/Client.java | 6 + .../after/pack2/Class1.java | 4 + .../stringsAndComments/before/Client.java | 6 + .../before/pack1/Class1.java | 4 + .../after/pack2/AClass.java | 5 + .../before/pack1/AClass.java | 5 + .../nonJavaFiles/after/pack1/Inner.java | 4 + .../nonJavaFiles/after/pack1/Outer.java | 6 + .../nonJavaFiles/before/pack1/Outer.java | 8 + .../scr13730/after/pack1/Client.java | 12 + .../scr13730/after/pack1/StaticInner.java | 15 + .../scr13730/after/pack1/TopLevel.java | 4 + .../scr13730/before/pack1/Client.java | 12 + .../scr13730/before/pack1/TopLevel.java | 17 + .../moveInner/scr15142/after/xxx/Inner.java | 4 + .../moveInner/scr15142/after/xxx/Outer.java | 8 + .../moveInner/scr15142/before/xxx/Outer.java | 10 + .../moveInner/scr22592/after/xxx/Inner.java | 9 + .../moveInner/scr22592/after/xxx/Outer.java | 7 + .../moveInner/scr22592/before/xxx/Outer.java | 9 + .../moveInner/scr30106/after/p/A.java | 4 + .../moveInner/scr30106/after/p/B.java | 13 + .../moveInner/scr30106/after/p/X.java | 5 + .../moveInner/scr30106/before/p/A.java | 9 + .../moveInner/scr30106/before/p/X.java | 5 + .../moveMembers/innerClass/after/A.java | 2 + .../moveMembers/innerClass/after/B.java | 9 + .../moveMembers/innerClass/after/C.java | 3 + .../moveMembers/innerClass/before/A.java | 7 + .../moveMembers/innerClass/before/B.java | 3 + .../moveMembers/innerClass/before/C.java | 3 + .../moveMembers/javadocRefs/after/Class1.java | 9 + .../moveMembers/javadocRefs/after/Class2.java | 5 + .../moveMembers/javadocRefs/after/User.java | 6 + .../javadocRefs/before/Class1.java | 11 + .../javadocRefs/before/Class2.java | 3 + .../moveMembers/javadocRefs/before/User.java | 6 + .../after/pack1/A.java | 7 + .../after/pack1/Outer.java | 6 + .../after/pack2/B.java | 12 + .../before/pack1/A.java | 10 + .../before/pack1/Outer.java | 6 + .../before/pack2/B.java | 4 + .../moveMembers/scr11871/after/pack1/A.java | 7 + .../moveMembers/scr11871/after/pack1/B.java | 7 + .../moveMembers/scr11871/before/pack1/A.java | 10 + .../moveMembers/scr11871/before/pack1/B.java | 4 + .../moveMembers/scr40064/after/Test.java | 16 + .../moveMembers/scr40064/before/Test.java | 15 + .../moveMembers/scr40947/after/Test.java | 11 + .../moveMembers/scr40947/before/Test.java | 10 + .../moveMembers/twoMethods/after/pack1/A.java | 5 + .../moveMembers/twoMethods/after/pack1/C.java | 14 + .../moveMembers/twoMethods/after/pack2/B.java | 4 + .../twoMethods/before/pack1/A.java | 13 + .../twoMethods/before/pack1/C.java | 4 + .../twoMethods/before/pack2/B.java | 4 + .../moveMembers/weirdDeclaration/after/A.java | 3 + .../moveMembers/weirdDeclaration/after/B.java | 4 + .../weirdDeclaration/before/A.java | 5 + .../weirdDeclaration/before/B.java | 2 + .../insidePackage/after/a/b/a/A.java | 4 + .../movePackage/insidePackage/before/a/A.java | 4 + .../moveSingle/after/pack2/User1.java | 7 + .../moveSingle/after/pack2/User2.java | 7 + .../moveSingle/after/target/pack1/Class1.java | 4 + .../moveSingle/before/pack1/Class1.java | 4 + .../moveSingle/before/pack2/User1.java | 7 + .../moveSingle/before/pack2/User2.java | 7 + .../movePackage/qualifiedRef/after/Usage.java | 5 + .../qualifiedRef/after/package2/test/A.java | 7 + .../qualifiedRef/before/Usage.java | 5 + .../qualifiedRef/before/package1/test/A.java | 7 + .../after/src1/target/pack1/A.java | 4 + .../after/src2/target/pack1/B.java | 4 + .../movePackage/before/src1/pack1/A.java | 4 + .../movePackage/before/src2/pack1/B.java | 4 + .../collision/after/pack1/List.java | 4 + .../collision/after/pack2/Usage.java | 9 + .../collision/after/pack2/Usage2.java | 9 + .../collision/before/pack1/MyList.java | 4 + .../collision/before/pack2/Usage.java | 10 + .../collision/before/pack2/Usage2.java | 9 + .../renameClass/import/after/FooBar.java | 5 + .../renameClass/import/after/a/BlubFoo.java | 4 + .../renameClass/import/before/FooBar.java | 5 + .../renameClass/import/before/a/Blubfoo.java | 4 + .../innerClass/after/pack1/OuterClass.java | 9 + .../innerClass/before/pack1/OuterClass.java | 9 + .../nonJava/after/pack1/Class1New.java | 3 + .../nonJava/before/pack1/Class1.java | 3 + .../refactoring/renameField/after01.java | 9 + .../refactoring/renameField/after02.java | 14 + .../refactoring/renameField/after03.java | 16 + .../refactoring/renameField/before01.java | 9 + .../refactoring/renameField/before02.java | 14 + .../refactoring/renameField/before03.java | 16 + .../multi/staticImport1/after/pack1/A.java | 6 + .../staticImport1/after/pack2/Usage.java | 9 + .../multi/staticImport1/before/pack1/A.java | 6 + .../staticImport1/before/pack2/Usage.java | 9 + .../multi/staticImport2/after/pack1/A.java | 6 + .../staticImport2/after/pack2/Usage.java | 9 + .../multi/staticImport2/before/pack1/A.java | 6 + .../staticImport2/before/pack2/Usage.java | 9 + .../multi/staticImport3/after/pack1/A.java | 9 + .../staticImport3/after/pack2/Usage.java | 10 + .../multi/staticImport3/before/pack1/A.java | 9 + .../staticImport3/before/pack2/Usage.java | 9 + .../multi/staticImport4/after/pack1/A.java | 9 + .../staticImport4/after/pack2/Usage.java | 9 + .../multi/staticImport4/before/pack1/A.java | 9 + .../staticImport4/before/pack2/Usage.java | 9 + .../after01.java | 8 + .../after02.java | 22 + .../after03.java | 12 + .../after04.java | 17 + .../after05.java | 14 + .../after06.java | 13 + .../after07.java | 8 + .../before01.java | 4 + .../before02.java | 18 + .../before03.java | 6 + .../before04.java | 13 + .../before05.java | 10 + .../before06.java | 9 + .../before07.java | 2 + .../arrayElementAssignment/after/C.java | 2 + .../arrayElementAssignment/after/Client.java | 10 + .../arrayElementAssignment/after/I.java | 2 + .../arrayElementAssignment/before/C.java | 2 + .../arrayElementAssignment/before/Client.java | 10 + .../arrayElementAssignment/before/I.java | 2 + .../turnRefsToSuper/cast/after/A.java | 5 + .../turnRefsToSuper/cast/after/Client.java | 11 + .../turnRefsToSuper/cast/after/I.java | 3 + .../turnRefsToSuper/cast/before/A.java | 5 + .../turnRefsToSuper/cast/before/Client.java | 11 + .../turnRefsToSuper/cast/before/I.java | 3 + .../turnRefsToSuper/classUsage/after/A.java | 5 + .../classUsage/after/Client.java | 9 + .../turnRefsToSuper/classUsage/after/I.java | 3 + .../turnRefsToSuper/classUsage/before/A.java | 5 + .../classUsage/before/Client.java | 9 + .../turnRefsToSuper/classUsage/before/I.java | 3 + .../commonInheritor/after/Client.java | 20 + .../commonInheritor/before/Client.java | 20 + .../commonInheritorFail/after/Client.java | 20 + .../commonInheritorFail/before/Client.java | 20 + .../commonInheritorResults/after/Client.java | 20 + .../commonInheritorResults/before/Client.java | 20 + .../after/Client.java | 20 + .../before/Client.java | 20 + .../after/Client.java | 20 + .../before/Client.java | 20 + .../fieldTest/after/Component1.java | 11 + .../fieldTest/after/ComponentCaller.java | 20 + .../fieldTest/after/IDoSomething.java | 3 + .../fieldTest/before/Component1.java | 11 + .../fieldTest/before/ComponentCaller.java | 20 + .../fieldTest/before/IDoSomething.java | 3 + .../turnRefsToSuper/instanceOf/after/A.java | 2 + .../instanceOf/after/Client.java | 5 + .../turnRefsToSuper/instanceOf/after/I.java | 2 + .../turnRefsToSuper/instanceOf/before/A.java | 2 + .../instanceOf/before/Client.java | 5 + .../turnRefsToSuper/instanceOf/before/I.java | 2 + .../methodFromSuper/after/AClass.java | 5 + .../methodFromSuper/after/ASuper.java | 4 + .../methodFromSuper/after/ASuper2.java | 3 + .../methodFromSuper/after/Client.java | 7 + .../methodFromSuper/before/AClass.java | 5 + .../methodFromSuper/before/ASuper.java | 4 + .../methodFromSuper/before/ASuper2.java | 3 + .../methodFromSuper/before/Client.java | 7 + .../removeImport/after/pack1/AClass.java | 5 + .../removeImport/after/pack1/AnInterface.java | 5 + .../removeImport/after/pack2/Client.java | 10 + .../removeImport/after/pack2/Client2.java | 11 + .../removeImport/before/pack1/AClass.java | 5 + .../before/pack1/AnInterface.java | 5 + .../removeImport/before/pack2/Client.java | 10 + .../removeImport/before/pack2/Client2.java | 10 + .../turnRefsToSuper/returnValue/after/A.java | 2 + .../turnRefsToSuper/returnValue/after/B.java | 13 + .../turnRefsToSuper/returnValue/after/I.java | 4 + .../turnRefsToSuper/returnValue/before/A.java | 2 + .../turnRefsToSuper/returnValue/before/B.java | 13 + .../turnRefsToSuper/returnValue/before/I.java | 4 + .../turnRefsToSuper/returnValue2/after/A.java | 2 + .../turnRefsToSuper/returnValue2/after/B.java | 13 + .../turnRefsToSuper/returnValue2/after/I.java | 4 + .../returnValue2/before/A.java | 2 + .../returnValue2/before/B.java | 13 + .../returnValue2/before/I.java | 4 + .../turnRefsToSuper/scr34000/after/Main.java | 10 + .../turnRefsToSuper/scr34000/after/Model.java | 3 + .../scr34000/after/SimpleModel.java | 2 + .../turnRefsToSuper/scr34000/after/View.java | 3 + .../turnRefsToSuper/scr34000/before/Main.java | 10 + .../scr34000/before/Model.java | 3 + .../scr34000/before/SimpleModel.java | 2 + .../turnRefsToSuper/scr34000/before/View.java | 3 + .../scr34020/after/test/C.java | 17 + .../scr34020/before/test/C.java | 17 + .../superClass/after/AClass.java | 7 + .../superClass/after/ASuper.java | 6 + .../superClass/after/Client.java | 6 + .../superClass/before/AClass.java | 7 + .../superClass/before/ASuper.java | 6 + .../superClass/before/Client.java | 6 + .../turnRefsToSuper/toArray/after/A.java | 2 + .../turnRefsToSuper/toArray/after/B.java | 11 + .../turnRefsToSuper/toArray/after/I.java | 4 + .../turnRefsToSuper/toArray/before/A.java | 2 + .../turnRefsToSuper/toArray/before/B.java | 11 + .../turnRefsToSuper/toArray/before/I.java | 4 + .../useAsArg/after/AClass.java | 3 + .../useAsArg/after/Client.java | 14 + .../turnRefsToSuper/useAsArg/after/I.java | 3 + .../useAsArg/before/AClass.java | 3 + .../useAsArg/before/Client.java | 14 + .../turnRefsToSuper/useAsArg/before/I.java | 3 + .../refactoring/typeCook/t01/after/test.java | 20 + .../refactoring/typeCook/t01/before/test.java | 20 + .../refactoring/typeCook/t02/after/test.java | 19 + .../refactoring/typeCook/t02/before/test.java | 19 + .../refactoring/typeCook/t03/after/test.java | 19 + .../refactoring/typeCook/t03/before/test.java | 19 + .../refactoring/typeCook/t04/after/test.java | 18 + .../refactoring/typeCook/t04/before/test.java | 18 + .../refactoring/typeCook/t05/after/test.java | 19 + .../refactoring/typeCook/t05/before/test.java | 19 + .../refactoring/typeCook/t06/after/test.java | 19 + .../refactoring/typeCook/t06/before/test.java | 19 + .../refactoring/typeCook/t07/after/test.java | 20 + .../refactoring/typeCook/t07/before/test.java | 20 + .../refactoring/typeCook/t08/after/test.java | 21 + .../refactoring/typeCook/t08/before/test.java | 21 + .../refactoring/typeCook/t09/after/test.java | 19 + .../refactoring/typeCook/t09/before/test.java | 19 + .../refactoring/typeCook/t10/after/test.java | 20 + .../refactoring/typeCook/t10/before/test.java | 20 + .../refactoring/typeCook/t100/after/test.java | 11 + .../typeCook/t100/before/test.java | 11 + .../refactoring/typeCook/t101/after/test.java | 11 + .../typeCook/t101/before/test.java | 11 + .../refactoring/typeCook/t102/after/test.java | 11 + .../typeCook/t102/before/test.java | 11 + .../refactoring/typeCook/t103/after/test.java | 15 + .../typeCook/t103/before/test.java | 15 + .../refactoring/typeCook/t104/after/test.java | 17 + .../typeCook/t104/before/test.java | 17 + .../refactoring/typeCook/t105/after/test.java | 15 + .../typeCook/t105/before/test.java | 15 + .../refactoring/typeCook/t106/after/test.java | 12 + .../typeCook/t106/before/test.java | 12 + .../refactoring/typeCook/t107/after/test.java | 12 + .../typeCook/t107/before/test.java | 12 + .../refactoring/typeCook/t108/after/test.java | 14 + .../typeCook/t108/before/test.java | 14 + .../refactoring/typeCook/t109/after/test.java | 12 + .../typeCook/t109/before/test.java | 12 + .../refactoring/typeCook/t11/after/test.java | 19 + .../refactoring/typeCook/t11/before/test.java | 19 + .../refactoring/typeCook/t110/after/test.java | 15 + .../typeCook/t110/before/test.java | 15 + .../refactoring/typeCook/t111/after/test.java | 15 + .../typeCook/t111/before/test.java | 15 + .../refactoring/typeCook/t112/after/test.java | 13 + .../typeCook/t112/before/test.java | 13 + .../refactoring/typeCook/t113/after/test.java | 13 + .../typeCook/t113/before/test.java | 13 + .../refactoring/typeCook/t114/after/test.java | 12 + .../typeCook/t114/before/test.java | 12 + .../refactoring/typeCook/t115/after/test.java | 13 + .../typeCook/t115/before/test.java | 13 + .../refactoring/typeCook/t116/after/test.java | 13 + .../typeCook/t116/before/test.java | 13 + .../refactoring/typeCook/t117/after/test.java | 12 + .../typeCook/t117/before/test.java | 12 + .../refactoring/typeCook/t118/after/test.java | 19 + .../typeCook/t118/before/test.java | 19 + .../refactoring/typeCook/t119/after/test.java | 15 + .../typeCook/t119/before/test.java | 15 + .../refactoring/typeCook/t12/after/test.java | 22 + .../refactoring/typeCook/t12/before/test.java | 22 + .../refactoring/typeCook/t120/after/test.java | 15 + .../typeCook/t120/before/test.java | 15 + .../refactoring/typeCook/t121/after/test.java | 15 + .../typeCook/t121/before/test.java | 15 + .../refactoring/typeCook/t122/after/test.java | 13 + .../typeCook/t122/before/test.java | 13 + .../refactoring/typeCook/t123/after/test.java | 13 + .../typeCook/t123/before/test.java | 13 + .../refactoring/typeCook/t124/after/test.java | 12 + .../typeCook/t124/before/test.java | 12 + .../refactoring/typeCook/t125/after/test.java | 20 + .../typeCook/t125/before/test.java | 20 + .../refactoring/typeCook/t126/after/test.java | 19 + .../typeCook/t126/before/test.java | 19 + .../refactoring/typeCook/t127/after/test.java | 32 + .../typeCook/t127/before/test.java | 32 + .../refactoring/typeCook/t128/after/test.java | 21 + .../typeCook/t128/before/test.java | 21 + .../refactoring/typeCook/t129/after/test.java | 22 + .../typeCook/t129/before/test.java | 22 + .../refactoring/typeCook/t13/after/test.java | 22 + .../refactoring/typeCook/t13/before/test.java | 22 + .../refactoring/typeCook/t130/after/test.java | 25 + .../typeCook/t130/before/test.java | 25 + .../refactoring/typeCook/t131/after/test.java | 19 + .../typeCook/t131/before/test.java | 19 + .../refactoring/typeCook/t132/after/test.java | 32 + .../typeCook/t132/before/test.java | 32 + .../refactoring/typeCook/t133/after/test.java | 13 + .../typeCook/t133/before/test.java | 13 + .../refactoring/typeCook/t134/after/test.java | 20 + .../typeCook/t134/before/test.java | 20 + .../refactoring/typeCook/t135/after/test.java | 17 + .../typeCook/t135/before/test.java | 17 + .../refactoring/typeCook/t136/after/test.java | 14 + .../typeCook/t136/before/test.java | 14 + .../refactoring/typeCook/t137/after/test.java | 19 + .../typeCook/t137/before/test.java | 19 + .../refactoring/typeCook/t138/after/test.java | 25 + .../typeCook/t138/before/test.java | 25 + .../refactoring/typeCook/t139/after/test.java | 16 + .../typeCook/t139/before/test.java | 16 + .../refactoring/typeCook/t14/after/test.java | 23 + .../refactoring/typeCook/t14/before/test.java | 23 + .../refactoring/typeCook/t140/after/test.java | 21 + .../typeCook/t140/before/test.java | 21 + .../typeCook/t141/before/test.java | 8 + .../typeCook/t142/before/test.java | 8 + .../typeCook/t143/before/test.java | 13 + .../typeCook/t144/before/test.java | 15 + .../typeCook/t145/before/test.java | 13 + .../refactoring/typeCook/t15/after/test.java | 22 + .../refactoring/typeCook/t15/before/test.java | 22 + .../refactoring/typeCook/t16/after/test.java | 23 + .../refactoring/typeCook/t16/before/test.java | 23 + .../refactoring/typeCook/t17/after/test.java | 20 + .../refactoring/typeCook/t17/before/test.java | 20 + .../refactoring/typeCook/t18/after/test.java | 20 + .../refactoring/typeCook/t18/before/test.java | 20 + .../refactoring/typeCook/t19/after/test.java | 20 + .../refactoring/typeCook/t19/before/test.java | 20 + .../refactoring/typeCook/t20/after/test.java | 26 + .../refactoring/typeCook/t20/before/test.java | 26 + .../refactoring/typeCook/t21/after/test.java | 29 + .../refactoring/typeCook/t21/before/test.java | 29 + .../refactoring/typeCook/t22/after/test.java | 25 + .../refactoring/typeCook/t22/before/test.java | 25 + .../refactoring/typeCook/t23/after/test.java | 28 + .../refactoring/typeCook/t23/before/test.java | 28 + .../refactoring/typeCook/t24/after/test.java | 31 + .../refactoring/typeCook/t24/before/test.java | 31 + .../refactoring/typeCook/t25/after/test.java | 28 + .../refactoring/typeCook/t25/before/test.java | 28 + .../refactoring/typeCook/t26/after/test.java | 18 + .../refactoring/typeCook/t26/before/test.java | 18 + .../refactoring/typeCook/t27/after/test.java | 28 + .../refactoring/typeCook/t27/before/test.java | 28 + .../refactoring/typeCook/t28/after/test.java | 13 + .../refactoring/typeCook/t28/before/test.java | 13 + .../refactoring/typeCook/t29/after/test.java | 15 + .../refactoring/typeCook/t29/before/test.java | 15 + .../refactoring/typeCook/t30/after/test.java | 15 + .../refactoring/typeCook/t30/before/test.java | 15 + .../refactoring/typeCook/t31/after/test.java | 16 + .../refactoring/typeCook/t31/before/test.java | 16 + .../refactoring/typeCook/t32/after/test.java | 22 + .../refactoring/typeCook/t32/before/test.java | 22 + .../refactoring/typeCook/t33/after/test.java | 14 + .../refactoring/typeCook/t33/before/test.java | 14 + .../refactoring/typeCook/t34/after/test.java | 17 + .../refactoring/typeCook/t34/before/test.java | 17 + .../refactoring/typeCook/t35/after/test.java | 20 + .../refactoring/typeCook/t35/before/test.java | 20 + .../refactoring/typeCook/t36/after/test.java | 21 + .../refactoring/typeCook/t36/before/test.java | 21 + .../refactoring/typeCook/t37/after/test.java | 25 + .../refactoring/typeCook/t37/before/test.java | 25 + .../refactoring/typeCook/t38/after/test.java | 25 + .../refactoring/typeCook/t38/before/test.java | 25 + .../refactoring/typeCook/t39/after/test.java | 29 + .../refactoring/typeCook/t39/before/test.java | 29 + .../refactoring/typeCook/t40/after/test.java | 26 + .../refactoring/typeCook/t40/before/test.java | 26 + .../refactoring/typeCook/t41/after/test.java | 21 + .../refactoring/typeCook/t41/before/test.java | 21 + .../refactoring/typeCook/t42/after/test.java | 21 + .../refactoring/typeCook/t42/before/test.java | 21 + .../refactoring/typeCook/t43/after/test.java | 17 + .../refactoring/typeCook/t43/before/test.java | 17 + .../refactoring/typeCook/t44/after/test.java | 19 + .../refactoring/typeCook/t44/before/test.java | 19 + .../refactoring/typeCook/t45/after/test.java | 16 + .../refactoring/typeCook/t45/before/test.java | 16 + .../refactoring/typeCook/t46/after/test.java | 18 + .../refactoring/typeCook/t46/before/test.java | 18 + .../refactoring/typeCook/t47/after/test.java | 18 + .../refactoring/typeCook/t47/before/test.java | 18 + .../refactoring/typeCook/t48/after/test.java | 20 + .../refactoring/typeCook/t48/before/test.java | 20 + .../refactoring/typeCook/t49/after/test.java | 17 + .../refactoring/typeCook/t49/before/test.java | 17 + .../refactoring/typeCook/t50/after/test.java | 21 + .../refactoring/typeCook/t50/before/test.java | 21 + .../refactoring/typeCook/t51/after/test.java | 19 + .../refactoring/typeCook/t51/before/test.java | 19 + .../refactoring/typeCook/t52/after/test.java | 21 + .../refactoring/typeCook/t52/before/test.java | 21 + .../refactoring/typeCook/t53/after/test.java | 21 + .../refactoring/typeCook/t53/before/test.java | 21 + .../refactoring/typeCook/t54/after/test.java | 15 + .../refactoring/typeCook/t54/before/test.java | 15 + .../refactoring/typeCook/t55/after/test.java | 17 + .../refactoring/typeCook/t55/before/test.java | 17 + .../refactoring/typeCook/t56/after/test.java | 28 + .../refactoring/typeCook/t56/before/test.java | 28 + .../refactoring/typeCook/t57/after/test.java | 16 + .../refactoring/typeCook/t57/before/test.java | 16 + .../refactoring/typeCook/t58/after/test.java | 14 + .../refactoring/typeCook/t58/before/test.java | 14 + .../refactoring/typeCook/t59/after/test.java | 16 + .../refactoring/typeCook/t59/before/test.java | 16 + .../refactoring/typeCook/t60/after/test.java | 20 + .../refactoring/typeCook/t60/before/test.java | 20 + .../refactoring/typeCook/t61/after/test.java | 14 + .../refactoring/typeCook/t61/before/test.java | 14 + .../refactoring/typeCook/t62/after/test.java | 11 + .../refactoring/typeCook/t62/before/test.java | 11 + .../refactoring/typeCook/t63/after/test.java | 14 + .../refactoring/typeCook/t63/before/test.java | 14 + .../refactoring/typeCook/t64/after/test.java | 17 + .../refactoring/typeCook/t64/before/test.java | 17 + .../refactoring/typeCook/t65/after/test.java | 13 + .../refactoring/typeCook/t65/before/test.java | 13 + .../refactoring/typeCook/t66/after/test.java | 14 + .../refactoring/typeCook/t66/before/test.java | 14 + .../refactoring/typeCook/t67/after/test.java | 22 + .../refactoring/typeCook/t67/before/test.java | 22 + .../refactoring/typeCook/t68/after/test.java | 20 + .../refactoring/typeCook/t68/before/test.java | 20 + .../refactoring/typeCook/t69/after/test.java | 29 + .../refactoring/typeCook/t69/before/test.java | 29 + .../refactoring/typeCook/t70/after/test.java | 21 + .../refactoring/typeCook/t70/before/test.java | 21 + .../refactoring/typeCook/t71/after/test.java | 22 + .../refactoring/typeCook/t71/before/test.java | 22 + .../refactoring/typeCook/t72/after/test.java | 17 + .../refactoring/typeCook/t72/before/test.java | 17 + .../refactoring/typeCook/t73/after/test.java | 16 + .../refactoring/typeCook/t73/before/test.java | 16 + .../refactoring/typeCook/t74/after/test.java | 16 + .../refactoring/typeCook/t74/before/test.java | 16 + .../refactoring/typeCook/t75/after/test.java | 31 + .../refactoring/typeCook/t75/before/test.java | 31 + .../refactoring/typeCook/t76/after/test.java | 33 + .../refactoring/typeCook/t76/before/test.java | 33 + .../refactoring/typeCook/t77/after/test.java | 33 + .../refactoring/typeCook/t77/before/test.java | 33 + .../refactoring/typeCook/t78/after/test.java | 25 + .../refactoring/typeCook/t78/before/test.java | 25 + .../refactoring/typeCook/t79/after/test.java | 21 + .../refactoring/typeCook/t79/before/test.java | 21 + .../refactoring/typeCook/t80/after/test.java | 29 + .../refactoring/typeCook/t80/before/test.java | 29 + .../refactoring/typeCook/t81/after/test.java | 13 + .../refactoring/typeCook/t81/before/test.java | 13 + .../refactoring/typeCook/t82/after/test.java | 19 + .../refactoring/typeCook/t82/before/test.java | 19 + .../refactoring/typeCook/t83/after/test.java | 18 + .../refactoring/typeCook/t83/before/test.java | 18 + .../refactoring/typeCook/t84/after/test.java | 12 + .../refactoring/typeCook/t84/before/test.java | 12 + .../refactoring/typeCook/t85/after/test.java | 12 + .../refactoring/typeCook/t85/before/test.java | 12 + .../refactoring/typeCook/t86/after/test.java | 15 + .../refactoring/typeCook/t86/before/test.java | 15 + .../refactoring/typeCook/t87/after/test.java | 11 + .../refactoring/typeCook/t87/before/test.java | 11 + .../refactoring/typeCook/t88/after/test.java | 11 + .../refactoring/typeCook/t88/before/test.java | 11 + .../refactoring/typeCook/t89/after/test.java | 14 + .../refactoring/typeCook/t89/before/test.java | 14 + .../refactoring/typeCook/t90/after/test.java | 23 + .../refactoring/typeCook/t90/before/test.java | 23 + .../refactoring/typeCook/t91/after/test.java | 25 + .../refactoring/typeCook/t91/before/test.java | 25 + .../refactoring/typeCook/t92/after/test.java | 27 + .../refactoring/typeCook/t92/before/test.java | 27 + .../refactoring/typeCook/t93/after/test.java | 9 + .../refactoring/typeCook/t93/before/test.java | 9 + .../refactoring/typeCook/t94/after/test.java | 12 + .../refactoring/typeCook/t94/before/test.java | 12 + .../refactoring/typeCook/t95/after/test.java | 15 + .../refactoring/typeCook/t95/before/test.java | 15 + .../refactoring/typeCook/t96/after/test.java | 17 + .../refactoring/typeCook/t96/before/test.java | 17 + .../refactoring/typeCook/t97/after/test.java | 14 + .../refactoring/typeCook/t97/before/test.java | 14 + .../refactoring/typeCook/t98/after/test.java | 15 + .../refactoring/typeCook/t98/before/test.java | 15 + .../refactoring/typeCook/t99/after/test.java | 18 + .../refactoring/typeCook/t99/before/test.java | 18 + .../testSource/AllTests.java | 10 + .../testSource/com/intellij/ClassFinder.java | 55 + .../testSource/com/intellij/TestAll.java | 375 ++ .../com/intellij/TestCaseLoader.java | 124 + .../com/intellij/TestClassesFilter.java | 138 + .../codeInsight/CodeInsightTestCase.java | 389 ++ .../codeInsight/CodeInsightTestData.java | 42 + .../daemon/DaemonAnalyzerTestCase.java | 80 + .../daemon/ExpectedHighlightingData.java | 237 + .../daemon/LightDaemonAnalyzerTestCase.java | 61 + .../quickFix/LightQuickFixTestCase.java | 113 + .../codeInspection/CanBeFinalTest.java | 74 + .../intellij/codeInspection/DataFlowTest.java | 117 + .../intellij/codeInspection/DefUseTest.java | 40 + .../codeInspection/EmptyMethodTest.java | 24 + .../codeInspection/LocalCanBeFinalTest.java | 95 + .../codeInspection/RedundantThrowTest.java | 16 + .../VisibilityInspectionTest.java | 53 + .../dependencies/DependenciesPanelTest.java | 83 + .../find/findUsages/FindParameterTest.java | 29 + .../com/intellij/idea/LockSupportTest.java | 55 + .../intellij/localVcs/MockAbstractVcs.java | 91 + .../com/intellij/mock/MockApplication.java | 194 + .../com/intellij/mock/MockDocument.java | 190 + .../mock/MockEditorEventMulticaster.java | 44 + .../com/intellij/mock/MockEditorFactory.java | 77 + .../com/intellij/mock/MockFileSystem.java | 81 + .../intellij/mock/MockProgressInidicator.java | 114 + .../com/intellij/mock/MockProject.java | 105 + .../com/intellij/mock/MockPsiManager.java | 192 + .../intellij/mock/MockVirtualFileManager.java | 49 + .../openapi/execution/ParametersListTest.java | 29 + .../intellij/openapi/roots/ui/TempFiles.java | 109 + .../com/intellij/openapi/ui/SplitterTest.java | 118 + .../vcs/ui/exclude/SortedListModelTest.java | 61 + .../projectView/BaseProjectViewTestCase.java | 267 ++ .../FormMergerTreeStructureProviderTest.java | 38 + .../projectView/TestProjectTreeStructure.java | 34 + .../com/intellij/psi/AddClassToFileTest.java | 21 + .../psi/AddRemoveInTypeParameterListTest.java | 62 + .../psi/ArrayIndexOutOfBoundsTest.java | 120 + .../com/intellij/psi/CodeFragmentsTest.java | 17 + .../com/intellij/psi/ConstantValuesTest.java | 258 ++ .../psi/NormalizeDeclarationTest.java | 45 + .../psi/OverlappingSourceRootsTest.java | 126 + .../com/intellij/psi/ParsingTestCase.java | 72 + .../refactoring/ChangeSignatureTest.java | 264 ++ .../refactoring/ExtractMethodTest.java | 163 + .../InheritanceToDelegationTest.java | 172 + .../IntroduceFieldInSameClassTest.java | 20 + .../refactoring/IntroduceParameterTest.java | 256 ++ .../refactoring/MakeMethodStaticTest.java | 168 + .../refactoring/MockInlineMethodOptions.java | 19 + .../MockIntroduceFieldHandler.java | 30 + .../intellij/refactoring/MoveClassTest.java | 87 + .../intellij/refactoring/MoveInnerTest.java | 61 + .../intellij/refactoring/MoveMembersTest.java | 88 + .../refactoring/MovePackageMultirootTest.java | 63 + .../intellij/refactoring/MovePackageTest.java | 59 + .../refactoring/MultiFileTestCase.java | 62 + .../intellij/refactoring/RenameClassTest.java | 51 + .../refactoring/RenameFieldsTest.java | 41 + .../refactoring/RenameMethodMultiTest.java | 53 + .../ReplaceConstructorWithFactoryTest.java | 82 + .../refactoring/TurnRefsToSuperTest.java | 111 + .../intellij/refactoring/TypeCookTest.java | 719 +++ .../ChangeClassSignatureTest.java | 67 + .../ConvertToInstanceMethodTest.java | 33 + .../refactoring/inline/InlineLocalTest.java | 35 + .../refactoring/inline/InlineMethodTest.java | 89 + .../refactoring/migration/MigrationTest.java | 51 + .../moveMembers/MockMoveMembersOptions.java | 48 + .../rename/naming/NameSuggesterTest.java | 118 + .../com/intellij/ui/BasicTreeModel.java | 29 + .../intellij/ui/TreeExpandCollapseTest.java | 180 + .../uiDesigner/TestGridChangeUtil.java | 308 ++ .../intellij/uiDesigner/TestTextDiffer.java | 43 + .../com/intellij/util/DateFormatUtilTest.java | 67 + .../intellij/util/IJSwingUtilitiesTest.java | 55 + .../util/UniqueFileNamesProviderTest.java | 17 + .../com/intellij/util/XMLOutputterTest.java | 39 + .../config/ExternalizablePropertyTest.java | 79 + .../com/intellij/util/diff/DiffTest.java | 69 + .../intellij/util/graph/DFSTBuilderTest.java | 119 + .../util/graph/GraphGeneratorTest.java | 55 + .../intellij/util/graph/GraphTestUtil.java | 39 + .../com/intellij/util/graph/TestNode.java | 20 + .../util/text/StringSearcherTest.java | 19 + .../intellij/util/ui/tree/TreeUtilTest.java | 162 + .../util/src/com/intellij/Patches.java | 122 + .../RuntimeInterruptedException.java | 7 + .../diagnostic/ApplicationInfoProvider.java | 11 + .../openapi/diagnostic/DefaultLogger.java | 44 + .../intellij/openapi/diagnostic/Logger.java | 81 + .../com/intellij/openapi/util/Comparing.java | 44 + .../com/intellij/openapi/util/Computable.java | 12 + .../com/intellij/openapi/util/Condition.java | 29 + .../openapi/util/DefaultJDOMExternalizer.java | 248 ++ .../intellij/openapi/util/EmptyRunnable.java | 16 + .../com/intellij/openapi/util/Factory.java | 12 + .../openapi/util/InvalidDataException.java | 15 + .../openapi/util/JDOMExternalizable.java | 16 + .../util/JDOMExternalizableStringList.java | 87 + .../openapi/util/JDOMExternalizer.java | 52 + .../openapi/util/JDOMExternalizerUtil.java | 37 + .../com/intellij/openapi/util/JDOMUtil.java | 300 ++ .../src/com/intellij/openapi/util/Key.java | 21 + .../intellij/openapi/util/MultiValuesMap.java | 39 + .../openapi/util/NamedJDOMExternalizable.java | 9 + .../src/com/intellij/openapi/util/Pair.java | 52 + .../src/com/intellij/openapi/util/Ref.java | 34 + .../openapi/util/ShutDownTracker.java | 72 + .../com/intellij/openapi/util/SystemInfo.java | 55 + .../com/intellij/openapi/util/TextRange.java | 76 + .../intellij/openapi/util/UserDataHolder.java | 12 + .../openapi/util/UserDataHolderBase.java | 112 + .../openapi/util/WriteExternalException.java | 15 + .../intellij/openapi/util/io/FileUtil.java | 380 ++ .../openapi/util/text/LineTokenizer.java | 127 + .../openapi/util/text/StringUtil.java | 475 ++ .../src/com/intellij/ui/SmartExpander.java | 46 + .../util/src/com/intellij/ui/TableUtil.java | 177 + .../util/src/com/intellij/util/ArrayUtil.java | 123 + .../com/intellij/util/BooleanValueHolder.java | 49 + .../src/com/intellij/util/CodeWriter.java | 78 + .../util/src/com/intellij/util/EventUtil.java | 53 + .../src/com/intellij/util/ImageLoader.java | 91 + .../util/IncorrectOperationException.java | 22 + .../com/intellij/util/ListWithSelection.java | 71 + .../com/intellij/util/LocalTimeCounter.java | 13 + .../com/intellij/util/NewInstanceFactory.java | 49 + .../intellij/util/PatchedSoftReference.java | 77 + .../intellij/util/PatchedWeakReference.java | 77 + .../src/com/intellij/util/PatternUtil.java | 66 + .../util/src/com/intellij/util/SmartList.java | 95 + .../util/src/com/intellij/util/TreeItem.java | 66 + .../util/UniqueFileNamesProvider.java | 57 + .../src/com/intellij/util/Validateable.java | 10 + .../intellij/util/ValidateableReference.java | 19 + .../util/WeakPropertyChangeAdapter.java | 30 + .../com/intellij/util/cls/BytePointer.java | 18 + .../intellij/util/cls/ClsFormatException.java | 16 + .../src/com/intellij/util/cls/ClsUtil.java | 349 ++ .../util/containers/ArrayListSet.java | 42 + .../util/containers/BidirectionalMap.java | 87 + .../util/containers/CoModifiableList.java | 63 + .../intellij/util/containers/CollectUtil.java | 73 + .../util/containers/ComparatorUtil.java | 26 + .../util/containers/ContainerUtil.java | 166 + .../util/containers/ConvertingIterator.java | 52 + .../intellij/util/containers/Convertor.java | 9 + .../util/containers/DoubleArrayList.java | 154 + .../util/containers/EmptyIterator.java | 22 + .../intellij/util/containers/Enumerator.java | 79 + .../util/containers/FilteringIterator.java | 131 + .../com/intellij/util/containers/HashMap.java | 26 + .../com/intellij/util/containers/HashSet.java | 26 + .../intellij/util/containers/HugeArray.java | 67 + .../util/containers/IntArrayList.java | 154 + .../util/containers/InternalIterator.java | 102 + .../util/containers/LongArrayList.java | 154 + .../intellij/util/containers/OrderedSet.java | 97 + .../com/intellij/util/containers/Queue.java | 117 + .../util/containers/SequenceIterator.java | 58 + .../intellij/util/containers/SoftHashMap.java | 293 ++ .../util/containers/SoftValueHashMap.java | 101 + .../containers/VariableWidthIntArray.java | 124 + .../intellij/util/containers/WeakHashMap.java | 328 ++ .../intellij/util/containers/WeakList.java | 134 + .../util/containers/WeakReferenceArray.java | 248 ++ .../util/containers/WeakValueHashMap.java | 95 + .../util/src/com/intellij/util/diff/Diff.java | 113 + .../src/com/intellij/util/diff/IntLCS.java | 121 + .../com/intellij/util/diff/LCSBuilder.java | 13 + .../intellij/util/diff/LinkedDiffPaths.java | 121 + .../src/com/intellij/util/diff/Reindexer.java | 122 + .../util/enumeration/ArrayEnumeration.java | 32 + .../enumeration/ArrayListEnumeration.java | 31 + .../util/enumeration/DoubleEnumeration.java | 32 + .../util/enumeration/EmptyEnumeration.java | 25 + .../util/enumeration/EnumerationCopy.java | 37 + .../util/enumeration/LightEnumeration.java | 9 + .../enumeration/LightEnumerationAdapter.java | 40 + .../util/enumeration/SequenceEnumeration.java | 53 + .../util/enumeration/SingleEnumeration.java | 29 + .../util/exception/RootException.java | 38 + .../util/exception/RootRuntimeException.java | 36 + .../intellij/util/graph/CachingSemiGraph.java | 45 + .../com/intellij/util/graph/DFSTBuilder.java | 150 + .../src/com/intellij/util/graph/Graph.java | 19 + .../intellij/util/graph/GraphGenerator.java | 63 + .../util/src/com/intellij/util/io/IOUtil.java | 44 + .../src/com/intellij/util/io/ZipUtil.java | 226 + .../util/text/CharArrayCharSequence.java | 48 + .../com/intellij/util/text/CharArrayUtil.java | 175 + .../util/text/CloneableTokenizer.java | 35 + .../intellij/util/text/DateFormatUtil.java | 119 + .../com/intellij/util/text/LineReader.java | 154 + .../util/text/MergingCharSequence.java | 37 + .../intellij/util/text/StringSearcher.java | 156 + .../intellij/util/text/StringTokenizer.java | 150 + .../util/ui/AbstractTableCellEditor.java | 13 + .../src/com/intellij/util/ui/ColumnInfo.java | 79 + .../util/ui/ComboBoxTableCellEditor.java | 73 + .../util/ui/ComboBoxTableCellRenderer.java | 89 + .../com/intellij/util/ui/IdeaUIManager.java | 29 + .../com/intellij/util/ui/ItemRemovable.java | 37 + .../intellij/util/ui/LabelWithTooltip.java | 54 + .../com/intellij/util/ui/ListTableModel.java | 125 + .../intellij/util/ui/SortableColumnModel.java | 25 + .../util/src/com/intellij/util/ui/Table.java | 184 + .../com/intellij/util/ui/TableViewModel.java | 13 + .../util/src/com/intellij/util/ui/Tree.java | 102 + .../util/ui/treetable/ListTreeTableModel.java | 52 + .../ListTreeTableModelOnColumns.java | 105 + .../intellij/util/ui/treetable/TreeTable.java | 369 ++ .../ui/treetable/TreeTableCellEditor.java | 50 + .../ui/treetable/TreeTableCellRenderer.java | 60 + .../util/ui/treetable/TreeTableModel.java | 49 + .../ui/treetable/TreeTableModelAdapter.java | 127 + .../util/ui/treetable/TreeTableTree.java | 95 + .../intellij/openapi/util/TextRangeTest.java | 37 + .../com/intellij/util/Assertion.java | 297 ++ .../com/intellij/util/StringConvertion.java | 19 + .../util/containers/CoModifiableListTest.java | 67 + .../util/containers/ContainerUtilTest.java | 13 + .../util/containers/EnumeratorTest.java | 21 + .../containers/FilteringIteratorTest.java | 115 + .../util/containers/HugeArrayTest.java | 59 + .../intellij/util/containers/QueueTest.java | 54 + .../util/containers/SequenceIteratorTest.java | 47 + .../containers/TObjectIntHashMapTest.java | 21 + .../util/containers/WeakListTest.java | 120 + .../containers/WeakReferenceArrayTest.java | 315 ++ .../util/containers/WeaksTestCase.java | 90 + .../com/intellij/util/diff/IntLCSTest.java | 72 + .../util/diff/LinkedDiffPathsTest.java | 60 + .../com/intellij/util/diff/ReindexerTest.java | 48 + 4410 files changed, 466482 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/actions/ShowJavaDocInfoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/CharFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/Lookup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupEvent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItemUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/PresentableLookupValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/DownHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/EndHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/HomeHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageDownHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageUpHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TestLookupManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TypedHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/UpHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/CtrlMouseHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/GotoImplementationHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodDownHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpDownUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/NavigationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoImplementationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoSuperAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/IncrementalSearchAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Expression.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/InvokeActionResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Macro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiElementResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiTypeResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Result.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Template.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateStateListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TextResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/actions/SaveAsTemplateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ConstantNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EditTemplateDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EditVariableDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EmptyNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ListTemplatesHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/LiveTemplatesConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroCallNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SelectionNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SurroundWithTemplateHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableSorter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateColors.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateListPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSegments.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTextLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTokenType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/Variable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/VariableNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/ListTemplatesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/SurroundWithTemplateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ArrayVariableMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CapitalizeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CastToLeftSideTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteSmartMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ComponentTypeOfMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CurrentPackageMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DecapitalizeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DescendantClassesEnumMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/EnumMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ExpectedTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/GuessElementTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableComponentTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableVariableMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/LineNumberMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MethodNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/QualifiedClassNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/RightSideTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableOfTypeMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableTypeMacroBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionDiff.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionMain.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/CodeInspectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlow.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowRunner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaInstructionState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaVariableState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/SortedIntSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/Instruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaNewValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadCodeInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefEntryPointFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreferencedFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deprecation/DeprecationInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/AddAssertStatementFix.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/BaseLocalInspectionTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/Descriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorComposer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorProviderInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/EntryPointsManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/FilteringInspectionTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/HTMLComposer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionApplication.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfile.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionToolRegistrar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/JobDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalQuickFixWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/StandardInspectionToolsProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/VisibleTreeState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/ExportToHTMLDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/HTMLExportFrameMaker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/HTMLExporter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/GenericsInspectionToolBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/SuspiciousCollectionsMethodCallsInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefEntity.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefImplicitConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefMethod.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefPackage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefParameter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameReturnValue/SameReturnValueInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/Browser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/EntryPointsNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionGroupNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionPackageNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionResultsView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionRootNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/ProblemDescriptionNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefAlphabeticalComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefElementNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unneededThrows/UnneededThrows.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefEntityAlphabeticalComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/XMLExportUtl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/visibility/VisibilityInspection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/Chunk.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerIOUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerMessageImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerWorkspaceConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacOutputParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesOutputParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ModuleCompilerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/OutputParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/RmicSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/SymbolTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/MakeModuleAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/BuildProperties.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ChunkBuild.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanModule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Comment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompileModuleChunkTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerExcludes.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerResourcePatterns.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompositeGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationUtils.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Generator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunk.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkAntProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkClasspath.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkSourcepath.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleSources.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/MultipleFileProjectBuild.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ProjectBuild.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/PropertyFileGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/SingleFileProjectBuild.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Tag.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntCall.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Attribute.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Copy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Delete.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/DirSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Dirname.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Exclude.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/FileSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Import.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Include.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Jar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Javac.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Manifest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Mkdir.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Param.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Path.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathRef.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSetRef.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Property.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Target.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/ZipFileSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationNameValuePair.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassFileReader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassInfoConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValueArray.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/DoubleConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/EnumConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FieldInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FloatConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/GenericMethodSignature.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/IntegerConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/LongConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfoExternalizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberReferenceInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MethodInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ReferenceInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParsingException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/StringConstantValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileContextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileDriver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerContentIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerErrorTreeView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompositeScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ExcludeEntryDescription.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileIndexCompileScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileSetCompileScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ModuleCompileScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/OneProjectItemCompileScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/PackagingCompilerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ProjectCompileScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/StateCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TimestampCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TrackDependenciesScope.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavacCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JikesCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/AnnotationTargets.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/BoundsParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Cache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheCorruptedException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheUtils.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CachingSearcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangeDescription.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ClassInfoProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Dependency.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCacheNavigator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/FieldChangeDescription.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MakeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MethodChangeDescription.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/RetentionPolicies.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/SourceFileFinder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/ComparingUtils.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerUIConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavaCompilersTab.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavacConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JikesConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/RmicConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressIndicator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebugException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerInvocationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/EvaluatingComputable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/InstanceFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AddToWatchAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AutoRendererAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CopyValueAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeContextViewAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeThreadsViewAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerActions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditFrameSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditWatchAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EvaluateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ExportThreadsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepIntoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepOverAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/FreezeThreadAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/GotoFrameSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/HotSwapAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/InspectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/JumpToObjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/NewWatchAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PauseAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PlaceInDocument.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PopFrameAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/QuickEvaluateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveAllWatchesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveWatchAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeThreadAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RunToCursorAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/SetValueAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowExecutionPointAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowFrameAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepIntoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOverAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ThrowDebugExceptionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleLineBreakpointAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewAsGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewBreakpointsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/codeinsight/SurroundWithRuntimeCastHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/CompoundPositionManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/ContextUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessAdapterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessEvents.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMName.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMNameUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/PositionManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteDebugProcessHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteStateState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RequestHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextRunnable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/VMEventListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/DebuggerHighlightFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayAccessEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayInitializerEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BinaryExpressionEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ClassObjectEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ContinueException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/Evaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/FieldEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectArrayItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectEntity.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectLocal.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InstanceofEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MapStack.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewArrayInstanceEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ThisEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeCastEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/UnaryExpressionEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerCommandImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerContextCommandImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/SuspendContextCommandImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/LocatableEventRequestor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/RequestManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/CloseWorkerThreadException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerSession.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerStateManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueueClosedException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerParametersRunnerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunnerSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapFile.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapProgress.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEvent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEventImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitThread.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeThread.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/MultiProcessCommand.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/PositionUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/ReloadClassesWorker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/SimpleStackFrameContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ArrayItemData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorKey.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DisplayKey.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/FieldData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/LocalData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/SimpleDisplayKey.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StackFrameData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticFieldData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThisData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadGroupData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/UserExpressionData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiProxy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiTimer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/LocalVariableProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StackFrameProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StringReferenceProxy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/CompositeConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerColors.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerGeneralConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditorAddDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputTextField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerEditorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerExpressionComboBox.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerPanelsManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerRecents.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerSessionTab.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerStatementEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EditorEvaluationCommand.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluatorRunnable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExportDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExpressionEvaluationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/GetJPDADialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapProgressImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/InstanceFilterEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/PositionHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/RunHotswapDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/StatementEvaluationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueLookupManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseMotionListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/Breakpoint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointNameCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointsConfigurationDialogFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerComboBoxRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FrameDebuggerTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FramePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDebuggerTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/MainWatchPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/TipManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/UIUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchDebuggerTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/NodeComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilderNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ArrayElementDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DefaultNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DescriptorTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MarkedDescriptorTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThisDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadGroupDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/Diagnostic.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DialogAppender.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DropAnErrorAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/EAPSendErrorDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ErrorReportConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/PluginException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ReportMessages.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/Block.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/FindBlock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/dupLocator/util/PsiAnchor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/ErrorReportSender.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ErrorBean.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ExceptionBean.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/NotifierBean.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/InternalEAPException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NewBuildException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchEAPUserException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchExceptionException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/SendException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/itn/ITNProxy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ConfigurationTypeEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExecutionUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExternalizablePath.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/Location.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/PsiLocation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunJavaConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManagerConfig.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RuntimeConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/SingleClassConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/TerminateRemoteProcessDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/BaseRunConfigurationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/ConfigurationContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/CreateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/EditRunConfigurationsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/PreferedProducerFind.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunConfigurationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunContextAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/StopAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurationType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurable2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationProducer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/filters/TextConsoleBuilderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConfigurationSettingsEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleViewImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/DisposedPsiManagerCheck.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/EditConfigurationsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionRegistryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunnerAndConfigurationSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/SingleConfigurationConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/TypeTemplatesConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ValidationResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitProcessHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/ModuleBasedConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RefactoringListeners.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RuntimeConfigurationProducer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Filter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/PushReader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/SegmentedInputStream.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/BrowseModuleValueActionListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ClassBrowser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/CommonJavaParameters.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ConfigurationModuleSelector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/RunConfigurationModule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/info/MethodLocation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DispatchListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/InputConsumer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/PacketExtractorBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/SegmentReader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/DiffHyperlink.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/MethodLineLocation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/StackTraceLine.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/FailedTestsNavigator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/PoolOfTestIcons.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestTreeView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestsUIUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/TestTreeExpander.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/ToolbarPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/JUnitPropertyListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/ScrollToTestSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurationType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RestartAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RunContentBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ui/RunContentManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/JavaParametersUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/RefactoringElementListenerComposite.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/StoringPropertyContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ApplicabilityFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/FeatureUsageTracker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/GroupDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/AdaptiveTipDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/ProgressTipPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindProgressIndicator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindInPathAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesInFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/ReplaceInPathAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findInProject/FindInProjectManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindClassUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindMethodUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindPackageUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindThrowUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindVariableUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindInProjectUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindResultImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindSettingsImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/replaceInProject/ReplaceInProjectManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/HelpManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpBroker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpContentViewUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelp.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelpContentViewer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/CopyPasteManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/GeneralSettingsConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IconUtilEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeEventQueue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopupManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/MacOSApplicationProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/PasteProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/RecentProjectsManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SaveAndSyncHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SwingCleanuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/TipOfTheDayManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurationPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/EditMacrosDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/EditMacrosAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/MacrosGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AboutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ActivateToolWindowAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AssociateFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BackAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BaseNavigateToSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChangeSplitterOrientationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChooseComponentsToExportDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloneElementAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseActiveTabAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllUnmodifiedEditorsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseEditorAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseTabToolbarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseWindowAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CodeEditorActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CollapseAllAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CommanderViewActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ContextHelpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyElementAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyPathsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateClassAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateElementActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/DeleteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditFileTemplatesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExitAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExpandAllAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportSettingsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileToolbarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExternalJavaDocAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ForwardAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoClassAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoLineAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoSymbolAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HelpTopicsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideAllToolWindowsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideToolWindowAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ImportSettingsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastEditAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastWindowAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewElementAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceToolbarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextSplitAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextTabAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OccurenceNavigatorActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OnlineDocAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OtherGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PasteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PinActiveTabAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PrevSplitAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceToolbarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousTabAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeColorSchemeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeKeymapAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeLookAndFeel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeSchemesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickSwitchSchemeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RecentProjectsGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RedoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RefreshAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ReloadFromDiskAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RestoreDefaultLayoutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RunGcAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveAllAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveFileAsTemplateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchAgainAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchBackAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectAllAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowModulePropertiesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowPopupMenuAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowRecentFilesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsUtilImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowTipsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitHorizontalAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitVerticalAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/StoreDefaultLayoutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SwapPanelsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SyncViewsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SynchronizeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TabNavigationActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TemplateProjectPropertiesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleDockModeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFloatingModeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFullScreenModeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TogglePinnedModeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TogglePopupHintsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleReadOnlyAttributeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToolWindowsGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/UndoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/UnsplitAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/UnsplitAllAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ViewSourceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ViewStatusBarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ViewStructureAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ViewToolbarAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/tree/BaseTreeNodeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/tree/CollapseTreeNodeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/tree/ExpandTreeNodeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/tree/FullyExpandTreeNodeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/Bookmark.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/BookmarkManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/BookmarksDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/CommanderBookmarksDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/EditorBookmarksDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/GotoBookmarkActionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/NextBookmarkAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/PreviousBookmarkAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/ToggleBookmarkAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/AbstractListBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ColoredCommanderRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/Commander.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderHistory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderSelectInTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ProjectListBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElementKind.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/GroupingElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NavigatableMessageElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/SimpleMessageElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestErrorViewAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestNewErrorViewAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorTreeViewConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/FileTemplate.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/FileTemplateManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/FileTemplateUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateDescriptionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplatePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyBrowserManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseCallHierarchyAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseMethodHierarchyAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseTypeHierarchyAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyBrowser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CalleeMethodsTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/ImplementMethodAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyBrowser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideMethodAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SubtypesHierarchyTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SupertypesHierarchyTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyBrowser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ArchiveFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/DTDFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/GuiFormFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HighlighterFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaClassFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ModuleFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ProjectFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/UnknownFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/WorkspaceFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XHtmlFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileTypeLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomHighlighterColors.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/PosBufferTokenizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTableLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BaseTokenParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/KeywordParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/NumberParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/CommonActionsManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ContentManagerWatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/DataManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/DataValidator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/EditorHighlighterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/PackageViewSelectInTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectViewSelectInTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewSelectInTarget.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CopyProviderRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CutProviderRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileEditorRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileTextRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/GetDataRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ModuleRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/NavigatableRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteProviderRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteTargetRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PsiFileRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathEntryMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ColumnNumberMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/DataAccessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileClassMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileExtMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileFQPackage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameWithoutExtension.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePackageMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JavaDocPathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JdkPathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/LineNumberMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/Macro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacroManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacrosDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/OutputPathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFileDirMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFilePathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectNameMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectPathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/PromptMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SecondQueueExpandMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathEntryMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathMacro.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/AvailablePluginsTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/InstalledPluginsTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginDescriptorComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginInstaller.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerColumnInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerMain.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryContentHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/SortableProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/cl/PluginClassLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/BaseProjectTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/CompositePsiClasChildrenSource.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/PsiClassChildrenSource.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ChangeProjectViewAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ProjectViewActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractUrl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/DirectoryUrl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/FormMergerTreeStructureProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleUrl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModuleToGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModulesToGroupAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/PackageViewPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectAbstractTreeStructureBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/RenameModuleHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/BasePsiNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/Form.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/FormNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ModuleGroupNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElementNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewLibrariesNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewProjectNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFieldNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiMethodNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/CacheUpdater.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileContent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileSystemSynchronizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupActionScriptManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/impl/StartupManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewExtension.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureNodeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/VisibilityComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/AccessLevelProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/FieldsFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/InheritedMembersFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/KindSorter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertiesGrouper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertyGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiFieldTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PublicElementsFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypeGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypesGrouper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlFileTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlStructureViewTreeModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlTagTreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionsOwner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeModelWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/AllTodosTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/AllTodosTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/FileTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/HighlightedRegionProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/SmartTodoItemPointer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/SmartTodoItemPointerComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/ToDoSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/ToDoSummary.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoCompositeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFileDirComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanelSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FilterDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FiltersTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternsTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoPatternTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeListCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/BaseToDoNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SingleFileToDoNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SummaryNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/ToDoRootNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoDirNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoFileNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoItemNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/AppearanceConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/LafManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/LafManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettingsListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/updates/UpdateChecker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserModuleTreeView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditSourceUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditorHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ElementsChooser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ExportToFileUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FQNameCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FileStructureDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/GotoLineNumberDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/JavaUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberChooser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberContainerCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/NavigationItemListCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageChooserDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PropertiesComponentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiClassListCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiElementListCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodOrPointcutWarningDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodWarningUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipUIUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TreeClassChooserDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoClassModel2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/JdkChooserPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleCreationPromptStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleTypeStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NameLocationStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NamePathComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/OutputPathsStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectJdkStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectNameStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/SourcePathsStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ToolbarPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/PackageSetChooserCombo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeUpdater.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AlphaComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/IndexComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SmartElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SourceComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeBuilderUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeViewUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/XmlDoctypeNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/CommandLineApplication.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaApplication.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaLogger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaTestApplication.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/Launcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/LoggerFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/SocketLock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Edge.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Node.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/GlobalAnalyzer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/Mark.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedEdge.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/OneEndFunctor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/TwoEndsFunctor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/EdgeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/NodeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/DecodeBytesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/EncodingViewer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/PsiViewerDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/AddEditRemovePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/EditLocationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildInstructionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildRecipeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/FileCopyInstructionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/IgnoredFileFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/J2EEModuleBuildInstructionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/JarAndCopyBuildInstructionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/J2EEModuleContainerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/LibraryLinkImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ModuleLinkImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/OrderEntryInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ResolvableElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/TransactionalEditable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/view/common/editor/SplitterProportionsData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/ex/ExternalResourceManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/ExternalResourceManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/LibrariesManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/run/localRun/EnvVariablesTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/GenerateJavadocDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/actions/GenerateJavadocAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/jsp/impl/TldTagDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/BaseHtmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/DtdHighlightingLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/EscapedJavaLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlHighlightingLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaDocLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaHighlightingLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/OldXmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/StringLiteralLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlHighlightingLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlHighlightingLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_HtmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_JavaLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_OldXmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_XmlLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionButtonLook.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/AnActionListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickListsManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/TimerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButton.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButtonWithText.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenu.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/EmptyIcon.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/IdeaActionButtonLook.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/PresentationFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ProxyShortcutSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/StubItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/Utils.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/WeakTimerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/ex/ApplicationEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/ex/ApplicationInfoEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/ex/ApplicationManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/ex/DecodeDefaultsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/ex/PathManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ApplicationImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ApplicationInfoImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/LaterInvocatorEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ModalityStateEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/CommandProcessorEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandMerger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandProcessorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CurrentEditorProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentEditingUndoProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByDocument.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByVirtualFile.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DummyProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorAndState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorChangeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FileOperationsUndoProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FocusBasedCurrentEditorProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Redo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Undo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoOrRedo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoableGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/DocumentReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/NonUndoableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UnexpectedUndoException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompileContextEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompilerPathsEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentRegistrar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/impl/ComponentManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/BaseDiffAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFileWithEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFiles.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffActions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffWalkerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeFilesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeOperations.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/NextDiffAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/PreviousDiffAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffContentFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffFragment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffStatusBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ComparisonPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ContentChangeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/CurrentLineMarker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffPanelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffRange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSideView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSidesContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSplitter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffVersionComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditingSides.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditorSource.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/FrameWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/Rediffers.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/TwoSidesContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BaseExternalTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/CompositeDiffTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffOptionsForm.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/FrameDiffTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/Fragment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/InlineFragment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineBlock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineFragment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/BufferedStringList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineBlockDivider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/List2D.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/Util.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/Change.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeCounter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ConflictChange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/DiffRangeMarker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeConflict.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeSearchHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/SimpleChange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/OpenPartialDiffAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeTool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeVersion.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/ByWord.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffCorrection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffFragmentsProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Formatting.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/FragmentsCollector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/UniteSameType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Word.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/settings/DiffColorsForm.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/FoldingTransformation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Interval.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LineBlocks.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LinearTransformation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Transformation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Trapezium.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContentDocumentListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContextLogger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffDivider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DocumentUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FocusDiffSide.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FontSizeSynchronizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/GutterActionRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/LabeledEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/TextDiffType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ThreePanels.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/BackspaceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CopyAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutLineEndAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteLineAtCaretAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordEndAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordStartAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DuplicateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EditorActionUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EmacsStyleIndentAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EnterAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EscapeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindWordAtCaretAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/IndentSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/JoinLinesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownAndScrollAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownWithSelectionAndScrollAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpAndScrollAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpWithSelectionAndScrollAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MultiplePasteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteFromX11Action.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ReplaceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollToCenterAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectLineAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectWordAtCaretAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SplitLineAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/StartNewLineAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TabAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TextEndAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TextEndWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TextStartAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TextStartWithSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ToggleCaseAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ToggleInsertStateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ToggleShowLineNumbersAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ToggleShowWhitespacesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/UnindentSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/UnselectWordAtCaretAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/ex/DefaultColorSchemesManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/DefaultColorsScheme.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/DocumentEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditReadOnlyListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEventMulticasterEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorMarkupModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeEvent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FocusChangeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FoldingModelEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/Highlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/HighlighterIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/LineIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/MarkupModelEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/RangeHighlighterEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EditorUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EmptyHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/LexerHighlighter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArray.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArrayWithData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/BorderEffect.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/CaretModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentMarkupModelManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorActionManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorComponentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldRegionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldingModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/HighlighterList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/IterationState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LeftHandScrollbarLayout.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineIteratorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/MarkupModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentLineMarker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentRangeMarker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeMarkerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/ScrollingModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SelectionModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SettingsImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/VisibleEditorsTracker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/EditorEventMulticasterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelEvent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/markup/MarkupEditorFilterFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/FileDeleteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoHomeAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoProjectDirectory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/NewFolderAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileNodeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/RootFileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileChooserFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorProviderManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/IdeDocumentHistory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorComposite.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWindow.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/HistoryEntry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/PlainTextFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/UserBinaryFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FakeFileType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/WeakKeymapManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/Converter01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymapImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/KeymapImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/MacOSDefaultKeymap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditKeymapsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditQuickListDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeyboardShortcutDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/MouseShortcutDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/LvcsConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/UpToDateLineNumberProviderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/JavaModuleType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/UnknownModuleType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModulePointerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleTypeManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/ColorSettingsPagesImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/CustomColorsPage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/HTMLColorsPage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/XMLColorsPage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelMnemonicsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelSettingsEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ExplorerSettingsEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurableWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/SingleConfigurableEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/impl/ProgressManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/BlockingProgressIndicator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ColorProgressBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/CommandLineProgress.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/DispatchThreadProgressWindow.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/MaxIntervalCalculator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListenerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressStream.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindow.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/SmoothProgressAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/StatusBarProgress.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/DefineMacrosDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectReloadStateImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/UndefinedMacrosConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor12.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor23.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor34.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Util.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/PathUtilEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRoot.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRootContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/CompositeProjectRoot.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/NotifiableSdkModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/PathEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/SdkEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/Util.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentEntry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentFolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableOrderEntry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndex.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludedOutputFolderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/FileIndexImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootEventImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OldModuleRootsKeeper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelComponentBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootProviderBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/SourceFolderImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/WritableOrderEntry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ApplicationLibraryTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ProjectLibraryTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/LightFilePointer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/components/ScrollablePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/ComponentOperation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/Orientation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/OrientedDimensionSum.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/SizeProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/VerticalStackLayout.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ActionsHeaderComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/FilePathClipper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconActionComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibrariesAlphaComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryTableModifiableModelProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleCreationInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditorState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleLevelConfigurablesEditorProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/MoveTableRowButtonListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/NamedLibrariesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ResizingWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ScalableIconComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ContentEntryEditingAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModulesConfigurationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleExcludedStateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryFileChooser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeContentElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/UrlComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/BaseTextCommentCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearanceUtils.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CompositeAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/HttpUrlCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/JarSubfileCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ModifiableCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/SimpleTextCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ValidFileCellAppearance.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/watcher/impl/OrderEntryPredicate.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MessagesEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MultiLineLabel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/FilePathImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractCommonCheckinAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractVcsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CashedVcsContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/SelectedBlockHistoryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowChangeMarkerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowNextChangeMarkerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowPrevChangeMarkerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsContextWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsGroupsWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/DocumentWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/LineStatusTracker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/ProjectLevelVcsManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/Range.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/RangesBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/FileHistoryPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsBlockHistoryDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerPerModuleConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/FileInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/HandleType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ui/exclude/SortedComboBoxModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ActionInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusFileOrDirectoryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateFileOrDirectoryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateProjectAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/DirectoryTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileOrDirectoryTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupByPackages.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/RestoreUpdateTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ScopeInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfoTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateOrStatusOptionsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateRootNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateTreeCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDataImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDirectoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/HttpFileSystem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/VirtualFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileInfoAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/StatusBarEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/WindowManagerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ActiveStack.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/CommandProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/DesktopLayout.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/FloatingDecorator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/HierarchyWatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeFrame.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeMenuBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeRootPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecorator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecoratorListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/SideStack.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Stripe.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/StripeButton.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/StripeButtonUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Surface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TestWindowManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TitlePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowsPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/VisibilityWatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowWatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/ApplyWindowInfoCmd.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/InvokeLaterCmd.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/UpdateRootPaneCmd.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/PositionPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/TextPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependenciesBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyRule.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyUISettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyValidationManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/FindDependencyUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/packageSet/PackageSetFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependecyNodeComparator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependenciesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependencyConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/FileNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/GeneralGroupNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/LibraryNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/ModuleNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageDependenciesNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/RootNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeModelBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/UsagesPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/peer/impl/PeerFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/core/impl/PomModelImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/java/impl/PomJavaAspectImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/projectView/LibrariesElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/PsiLock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/AllVariablesControlFlowPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/BranchingInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CallInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CommentInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CompositeInstructionClientVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalBranchingInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalGoToInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalThrowToInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlow.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowInstructionVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowStack.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowSubRange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/EmptyInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/GoToInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/Instruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionClientVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReadVariableInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReturnInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/SimpleInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ThrowToInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/WriteVariableInstruction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/AndFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ClassFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ConstructorFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContentFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContextGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementExtractorFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FalseFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FilterUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/GeneratorFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/InitializableFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/NotFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/OrFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ScopeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TextFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TrueFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnnotationTypeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnyInnerFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AssignableFromContextFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableToFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/EnumFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/InterfaceFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ThisOrAnyInnerFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeDeclaredFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeSillyAssignment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ModifierFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/PackageEqualsFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ReferenceOnFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/AllClassesGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/CastTypeGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ExpectedTypesGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/FilterGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/InstanceOfLeftPartTypeGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/MembersGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/TemplatesGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThisGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThrowsListGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/XmlAttributeValueGetter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/AfterElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/BeforeElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/InsideElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/LeftNeighbour.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentSkipReferenceElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PositionElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PreviousElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/RootTagFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/StartElementFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/SuperParentFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/TokenTypeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ArrayTypeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableFromFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableGroupFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableToFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ReturnTypeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeClassFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeCodeFragmentIsVoidEnabledFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValuesManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CheckUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CommitToPsiFileAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CompositeShortNamesCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ConstantExpressionEvaluator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/DebugUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ElementBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/EmptySubstitutorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/InheritanceImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiClassImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiConstantEvaluationHelperImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiDocumentManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiFileEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiModificationTrackerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiNameHelperImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiShortNamesCacheImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSubstitutorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSuperMethodImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiToDocumentSynchronizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiTreeChangeEventImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiVariableEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/SharedPsiElementImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/TextBlock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/CacheManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassInitializerView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DeclarationView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DirectoryView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FieldView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FileView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/InitializerTooLongException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/MethodView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ModifierFlags.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryElementType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryItemView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CacheUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CompositeCacheManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/BaseFilterLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/IdTableBuilding.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/VfsIndexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/XmlFilterLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/RecordUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/TypeInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsArrayInitializerMemberValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocTagImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFieldImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsMethodImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListOwner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParsingUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPrefixExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceParametersListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiBinaryFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiDirectoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiFileImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiPackageImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/ImplicitVariableImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReferenceExpression.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightEmptyImplementsList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightIdentifier.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightKeyword.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightMethod.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightModifierList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReferenceExpression.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightReferenceParameterList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightTypeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightVariableBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/meta/MetaRegistry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationClassImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationPackageImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/PsiMigrationImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/LowLevelSearchUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/PsiSearchHelperImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/ThrowSearchUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/TodoItemImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerEx.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CharTableImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CodeFragmentElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/Constants.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolderElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/ParsingContext.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnnotationMethodImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassInitializerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassReferenceType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiCodeFragmentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantInitializerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiExpressionCodeFragmentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFieldImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImmediateClassType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiLabelReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiMethodImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiModifierListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiPlainTextFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiReferenceListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeCodeFragmentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceJavaCodeReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceTreeToPsiMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/BraceEnforcer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/Helper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ImportHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/IndentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlDocumentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlTagImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlElementDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ExceptionTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/JavadocManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ParamDocTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocCommentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTokenImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ReturnDocTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SerialDocTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/jspJava/JspText.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/FileLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/JarLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/Loader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ChameleonTransforming.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ClassBodyParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/DeclarationParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ExpressionParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/FileTextParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/GTTokens.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ImportsTextParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/JavadocParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ParseUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/Parsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/StatementParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ElementManipulator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/PsiReferenceProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/GenericReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/PsiMultiReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PlainFileManipulator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/GenericReferenceProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassListReferenceProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/text/BlockSupportImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChangeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChildRole.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositePsiElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ElementType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/Factory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/FileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/HtmlFileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaDocElementType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaElementType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafPsiElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PlainTextFileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiCommentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiErrorElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiPlainTextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiWhiteSpaceImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SharedImplUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SourceUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/XmlFileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElementBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassInitializerElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantInitializerElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ExtendsListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/FieldElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImplementsListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementBaseElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStaticStatementElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/JavaFileElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/MethodElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ModifierListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayAccessExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssertStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssignmentExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBlockStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBreakStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiClassObjectAccessExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiContinueStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDeclarationStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDoWhileStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForeachStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIdentifierImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIfStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInstanceOfExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiJavaTokenImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiKeywordImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLabeledStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLocalVariableImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiParenthesizedExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReturnStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSuperExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSynchronizedStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowsListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTryStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterListImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiWhileStatementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReferenceListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReplaceExpressionUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterExtendsBoundsListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/TagNameReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttlistDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlCommentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDocumentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementContentSpecImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEnumeratedTypeImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlFileImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlMarkupDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlNotationDeclImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlProcessingInstructionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlPrologImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagValueImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTextImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTokenImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/dtd/DTDElementType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/ClassPresentationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/SymbolPresentationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/BaseScopeProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/ElementClassHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/MethodProcessorSetupFailedException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/NameHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/PsiConflictResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/DuplicateConflictResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaVariableConflictResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/ConflictFilterProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterElementProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterScopeProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodResolverProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodsProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesNotProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/util/PsiScopesUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsUnit.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/WrongFormatException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/text/BlockSupport.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/DefaultRoleFinder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/RoleFinder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/xml/XmlChildRole.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/BaseRefactoringProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/HelpID.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/IntroduceHandlerBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/AnonymousToInnerAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/BaseRefactoringAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ChangeSignatureAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/EncapsulateFieldsAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractInterfaceAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractMethodAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractSuperclassAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InheritanceToDelegationAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InlineAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceConstantAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceFieldAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceParameterAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceVariableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MakeMethodStaticAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MethodDuplicatesAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MigrateAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MoveAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PullUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PushDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/RenameElementAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/SafeDeleteAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TempWithQueryAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TurnRefsToSuperAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TypeCookAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/VariableInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSigntaureViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/TypeParameterInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ExceptionsTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/NewParameterCollidesWithLocalUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ThrownExceptionInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ImplementingClassUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/JavaDocUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/MethodCallUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ParameterUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyClassDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractClassUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/PrepareFailedException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/BindToOldUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassMethod.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/FieldAccessibility.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/InheritanceToDelegationUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NoLongerOverridingSubClassMethodUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NonDelegatedMemberUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/ObjectUpcastedUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UnqualifiedNonDelegatedMemberUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UpcastedUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineFieldDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineLocalHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/ReferencedElementsCollector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/ElementToWorkOn.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/LocalToFieldHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ChangedMethodCallInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ClassMemberInExprUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/EnclosingMethodSelectionDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ExternalUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InExprUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InternalUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/LocalVariableInExprUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ParameterInExprUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/Util.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableSettings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringListenerManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringTransaction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/impl/RefactoringTransactionImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/InternalUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/MakeMethodStaticProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/OverridingMethodUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/SelfUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/Settings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/JavaDocPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownConflicts.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownUsageViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationEntryDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapEntry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUsagesViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveCallback.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingMoveDestination.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MultipleRootsMoveDestination.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMemberViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ConvertToInstanceMethodRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/IntroduceParameterRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MakeMethodStaticRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveClassesOrPackagesRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveInnerRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveMembersRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringActionHandlerFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RenameRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ReplaceConstructorWithFactoryRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/SafeDeleteRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TurnRefsToSuperRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TypeCookRefactoringImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/AutomaticRenamingDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesImportedClassUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesUnqualifiableClassUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollidingClassImportUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollisionUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesFieldUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/PsiElementRenameHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandlerRegistry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameVariableUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ResolvableCollisionUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/SubmemberHidesMemberUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/UnresolvableCollisionUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticRenamer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticVariableRenamer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/FormsRenamer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/InheritorRenamer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/NameSuggester.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/OverridingMethodsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteUsageViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UnsafeUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UsageHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteFieldWriteReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteOverridingMethodUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeletePrivatizeMethod.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceSimpleDeleteUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/tempWithQuery/TempWithQueryHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/RefsToSuperViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnToSuperReferenceUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Bottom.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Settings.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookViewDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Util.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/System.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/Visitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ClassCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ColorConfiguringCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ConflictsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/DelegationPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EditableRowTableManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EnableDisableAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/InfoDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MethodCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/RowEditableTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/StringTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeListCreatingVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/UsageViewDescriptorAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/VisibilityPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/YesNoPreviewUsagesDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/CanonicalTypes.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ConflictsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/FieldConflictsResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/JavaDocPolicy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ParameterTablePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringHierarchyUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/VisibilityUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMemberReferencesVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassThisReferencesVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceContainmentVerifier.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassInstanceScanner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceScanner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceSearchingScanner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitorAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/DelegatingClassReferenceVisitor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/Match.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MatchProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/VariableReturnValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/javadoc/MethodJavaDocHelper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/BaseOccurenceManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/ExpressionOccurenceManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/LocalVariableOccurenceManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperCallOccurenceFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperOrThisCallFilterBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInThisCallFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorImplicitUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorUsageCollector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/NoConstructorClassUsageInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/EditorActionTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/IdeaTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightCodeInsightTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightIdeaTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LoggedErrorProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/MockVirtualFile.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/ModuleTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestEditorManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLogger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLoggerFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestSourceBasedTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ExternalToolsGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/OutputFiltersDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/SimpleActionGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/Tool.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolEditorDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolsPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AbstractToolTipHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ActivatableLineBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AnimatingSurface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollFromSourceHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollToSourceHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/BooleanTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckboxTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckedTreeNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsiblePanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsingListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColorPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColoredTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CompTitledBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/DialogButtonGroup.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EdgeBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorTextField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/FieldPanelWithChangeSupport.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Focusable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HeavyweightHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightedRegion.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightedText.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Hint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HintListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HorizontalLabeledIcon.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HoverHyperlinkLabel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HyperlinkLabel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeGraphics2D.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeaBlueMetalTheme.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LabeledIcon.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LightweightHint.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListSpeedSearch.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListToolTipHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListenerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultiLineTooltipUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultilineTreeCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/NonFocusableCheckBox.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/OneSideRoundedLineBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/PasswordFieldPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RightAlignedLabelUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RowIcon.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SelectionSaver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SpeedSearchBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Splash.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SplittingUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StateRestoringCheckBox.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StrikeoutLabel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Surface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TabbedPaneWrapper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableCellEditorWithButton.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableCellKey.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableToolTipHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeExpandCollapse.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeSpeedSearch.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeToolTipHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ComponentContentUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentManagerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/MessageView.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/TabbedPaneContentUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/MessageViewImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/errorView/impl/ErrorViewFactoryImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegBorders.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegButtonUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCheckBoxUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxButton.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegListUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuItemUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegPopupMenuBorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegRadioButtonUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegResources.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegScrollBarUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegScrollPaneUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTabbedPaneUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTableUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeHandleUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/IdeaMenuUI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ActiveDecorationLayer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/CutCopyPasteSupport.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DesignSpacer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragLayer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragSelectionProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorAnalizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/EventProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/FormEditingUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GlassLayer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GridChangeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GroupSelectionProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfiguration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/HSpacer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/HierarchyChangeListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/InplaceEditingLayer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/InsertComponentProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/LoaderFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/MainProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Painter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PassiveDecorationLayer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Properties.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PsiPropertiesProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadAtomicComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadErrorComponent.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadHSpacer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadRootContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadScrollPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadSplitPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadTabbedPane.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadVSpacer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ResizeProcessor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionWatcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/VSpacer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/XYLayoutManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/XmlReader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/XmlWriter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/AbstractMoveSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/CreateDialogAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/DataBindingWizardAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ExpandSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToDownAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToLeftAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToRightAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToUpAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/PreviewFormAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShowJavadocAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShrinkSelectionAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/StartInplaceEditingAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtr.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtrDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentSelectionListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/QuickFixManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/RootDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/MyEditorState.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditorProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/BindingsCache.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/CopyResourcesUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2SourceCompiler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/FormSourceCodeGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItemDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/GroupItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/Palette.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/IntrospectedProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/Property.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditorAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditorListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyInspector.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/QuickFixManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BindingEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BooleanEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BorderTypeEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEnumEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditorDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractDimensionPropery.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractInsetsProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BorderProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HGapProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HSizePolicyProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroBooleanProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDimensionProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDoubleProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroInsetsProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroIntProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroRectangleProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroStringProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MarginProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MaximumSizeProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MinimumSizeProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/PreferredSizeProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeHorizontallyProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeVerticallyProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SizePolicyProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VGapProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VSizePolicyProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/BooleanRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/ClassToBindRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/DimensionRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/InsetsPropertyRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/IntEnumRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/LabelPropertyRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/RectangleRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/SizePolicyRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/StringRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateClassToBindFix.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateFieldFix.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/FocusListenerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/LightBulbComponentImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFix.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFixManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/ShowHintAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/VisibilityWatcherImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyListCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindCompositeStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToExistingBeanStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/DataBindingWizard.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormProperty2BeanProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormPropertyTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/Generator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/WizardData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleFromClipboardAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/FindUsagesCommand.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/UsageViewUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/SelectInEditorHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/UsageViewManagerImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ActionRunner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/EditorPopupHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/IJSwingUtilities.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledInputStream.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledOutputStream.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/AbstractProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/BooleanProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ExternalizablePropertyContainer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/Externalizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/IntProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ListProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageAccessors.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StringProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ToggleBooleanProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ValueProperty.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMapWriteHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferRADataInput.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileByteBuffer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileKeyProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntArrayValueProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntValueProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntegerKeyProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RandomAccessDataInput.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RecordDataOutput.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/StringKeyProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMapAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableTIntObjectMapAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsPanel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HttpConfigurable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/IOExceptionDialog.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/LockException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/properties/EncodingAwareProperties.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/text/ElementPresentation.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/CellEditorComponentWithBrowseButton.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/tree/TreeModelAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlAction.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlActionHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlAttributeDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlElementDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlAttributeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlElementDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/SimpleTypeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/StdTypeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/TypeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/HtmlUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlNSDescriptorSequence.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlResourceResolver.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/CompositeAttributeTagDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/EntityDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlAttributeDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDescriptorsTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlTagDescriptor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XmlDocumentationProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6073/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6781/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6845/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6861/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/ext_src/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fieldAndTryBlock/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fields/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/methodInheritance/src/a.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/privateInners/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance1/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/CatchParameterCantBeNull/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/GenericInstanceof/src/GenericInstanceof.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/Instanceof/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13626/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13702/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13871/src/Aaa.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14314/src/Finally.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14819/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15162/src/NullTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15406/src/CodeFlowTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR18186/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR39950/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/andEq/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/caseAndNpe/src/CaseAndNpe.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/cce/src/Cce.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/exceptionCFG/src/ExceptionCFG.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/inst/src/Inst.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/npe1/src/Npe.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/nullableField/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/orBug/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/scrIDEA1/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/thisInstanceof/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/wrongEqualTypes/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/xor/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR28019/src/AsynchronousImageLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR40364/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR5144/src/AssignTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR6843/src/NotUsedTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/arrayIndexUsages/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/unusedVariable/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapterUsage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyListener.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/ext_src/Derived.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/src/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Derived.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR11757/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_1/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_2/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_3/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_4/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_5/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_6/src/foo/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428/src/Junk.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428_1/src/Junk.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7601/src/TestFinal2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/if/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/incompleteAssignment/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/multiWriteNoRead/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/parameters/src/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR14543/src/E.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR6858/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClassTwo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AnInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR11792/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SubClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SuperClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR6856/src/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/innerConstructor/src/Foo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PackageLevelServer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PublicServer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package2/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class4.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Form1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Bla.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Blu.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/constantValues/ClassWithConstants.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/AddParam.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/NoParams.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/RemoveAllParams.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/ReorderParams.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AddRuntimeException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AlreadyHandled.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/CovariantReturnType.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/DefaultConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/EnumConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegate.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateDefaultConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateForAbstract.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithParametersReordering.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithReturn.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypes.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypesInOldParameters.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ParameterReorder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ReorderExceptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/SCR40895.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Simple.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/TypeParametersInMethod.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/UseAnyVariable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Varargs1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/InterfaceTypeParameter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Simple.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/TypeParameter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints3.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints4.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPointsInsideLoop.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry_after.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/X.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/X.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Intf.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Intf.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/J.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/J.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/Base.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/before/xxx/SCR20557.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/DelegatedBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/DelegatedBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/DelegatedBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/DelegatedBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/J.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/J.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Inference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Qualifier.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ArrayAccess.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallInFor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallUnderIf.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ChainingConstructor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ConflictingField.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FieldInitializer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineParms.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifier.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifierFromSuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithTry.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/LocalVariableResult.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/NameClash.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR20655.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR22644.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR31093.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR37742.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr10884.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr13831.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SideEffect.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/StaticFieldInitializer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Try.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/TrySynchronized.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/VoidWithReturn.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/after1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/before1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after04.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after05.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after06.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after07.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after08.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after09.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after10.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after11.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after12.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after13.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after14.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after15.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after16.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after17.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after18.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after19.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after20.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after21.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after22.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after23.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after24.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after25.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after26.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after27.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after28.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after29.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after30.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before04.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before05.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before06.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before07.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before08.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before09.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before10.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before11.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before12.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before13.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before14.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before15.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before16.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before17.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before18.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before19.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before20.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before21.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before22.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before23.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before24.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before25.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before26.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before27.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before28.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before29.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before30.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10-np.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after11.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after12.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after13.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after14.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after15.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after16.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after17.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after18.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after19.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after3.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after4.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after5.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after6.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after7.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after8.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after9.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before10.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before11.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before12.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before13.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before14.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before15.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before16.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before17.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before18.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before19.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before3.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before4.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before5.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before6.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before7.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before8.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before9.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack2/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack2/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/WEB-INF/TestTEI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/pack2/TestClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/WEB-INF/TestTEI.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/pack1/TestClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/after/pack2/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/after/pack2/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/pack2/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/after/pack2/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/before/pack1/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Inner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/before/pack1/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/StaticInner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/TopLevel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/TopLevel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Inner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/before/xxx/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Inner.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/before/xxx/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/X.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/X.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/User.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/User.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/Outer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/after/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/before/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/after/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/before/Test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack2/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack2/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/after/a/b/a/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/before/a/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/target/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/package2/test/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/package1/test/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack1/List.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack1/MyList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/FooBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/a/BlubFoo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/FooBar.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/a/Blubfoo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/after/pack1/OuterClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/before/pack1/OuterClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/after/pack1/Class1New.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/before/pack1/Class1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack1/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack2/Usage.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after04.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after05.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after06.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after07.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before01.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before02.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before03.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before04.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before05.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before06.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before07.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/Component1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/ComponentCaller.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/IDoSomething.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/Component1.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/ComponentCaller.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/IDoSomething.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AnInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AnInterface.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client2.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Main.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Model.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/SimpleModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/View.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Main.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Model.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/SimpleModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/View.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/after/test/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/before/test/C.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/ASuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/ASuper.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/A.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/B.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/AClass.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/Client.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/I.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t141/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t142/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t143/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t144/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t145/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/after/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/before/test.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/AllTests.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ClassFinder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestAll.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestCaseLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestClassesFilter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/ExpectedHighlightingData.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/CanBeFinalTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/DataFlowTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/DefUseTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/EmptyMethodTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/LocalCanBeFinalTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/RedundantThrowTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInspection/VisibilityInspectionTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/dependencies/DependenciesPanelTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/find/findUsages/FindParameterTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/idea/LockSupportTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/localVcs/MockAbstractVcs.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockApplication.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockDocument.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockEditorEventMulticaster.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockEditorFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockFileSystem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockProgressInidicator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockProject.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockPsiManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/mock/MockVirtualFileManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/openapi/execution/ParametersListTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/openapi/roots/ui/TempFiles.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/openapi/ui/SplitterTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/openapi/vcs/ui/exclude/SortedListModelTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/projectView/BaseProjectViewTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/projectView/FormMergerTreeStructureProviderTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/projectView/TestProjectTreeStructure.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/AddClassToFileTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/AddRemoveInTypeParameterListTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/ArrayIndexOutOfBoundsTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/CodeFragmentsTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/ConstantValuesTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/NormalizeDeclarationTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/OverlappingSourceRootsTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/psi/ParsingTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/ChangeSignatureTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/ExtractMethodTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/InheritanceToDelegationTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/IntroduceParameterTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MakeMethodStaticTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MockInlineMethodOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MockIntroduceFieldHandler.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MoveClassTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MoveInnerTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MoveMembersTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MovePackageMultirootTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MovePackageTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/MultiFileTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/RenameClassTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/RenameFieldsTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/RenameMethodMultiTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/ReplaceConstructorWithFactoryTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/TurnRefsToSuperTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/TypeCookTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/inline/InlineLocalTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/inline/InlineMethodTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/migration/MigrationTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/refactoring/rename/naming/NameSuggesterTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ui/BasicTreeModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ui/TreeExpandCollapseTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/uiDesigner/TestGridChangeUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/uiDesigner/TestTextDiffer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/DateFormatUtilTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/IJSwingUtilitiesTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/UniqueFileNamesProviderTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/XMLOutputterTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/config/ExternalizablePropertyTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/diff/DiffTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/graph/DFSTBuilderTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/graph/GraphGeneratorTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/graph/GraphTestUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/graph/TestNode.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/text/StringSearcherTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/util/ui/tree/TreeUtilTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/Patches.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/application/RuntimeInterruptedException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/diagnostic/ApplicationInfoProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/diagnostic/Logger.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Comparing.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Computable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Condition.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/DefaultJDOMExternalizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/EmptyRunnable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Factory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/InvalidDataException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/JDOMExternalizable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/JDOMExternalizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/JDOMExternalizerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/JDOMUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Key.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/MultiValuesMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/NamedJDOMExternalizable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Pair.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/Ref.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/ShutDownTracker.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/SystemInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/TextRange.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/UserDataHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/UserDataHolderBase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/WriteExternalException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/io/FileUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/text/LineTokenizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/openapi/util/text/StringUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/ui/SmartExpander.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/ui/TableUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ArrayUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/BooleanValueHolder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/CodeWriter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/EventUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ImageLoader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/IncorrectOperationException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ListWithSelection.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/LocalTimeCounter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/NewInstanceFactory.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/PatchedSoftReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/PatchedWeakReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/PatternUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/SmartList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/TreeItem.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/UniqueFileNamesProvider.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/Validateable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ValidateableReference.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/WeakPropertyChangeAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/cls/BytePointer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/cls/ClsFormatException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/cls/ClsUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/ArrayListSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/BidirectionalMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/CoModifiableList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/CollectUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/ComparatorUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/ContainerUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/ConvertingIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/Convertor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/DoubleArrayList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/EmptyIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/Enumerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/FilteringIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/HashMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/HashSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/HugeArray.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/IntArrayList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/InternalIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/LongArrayList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/OrderedSet.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/Queue.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/SequenceIterator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/SoftHashMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/SoftValueHashMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/VariableWidthIntArray.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/WeakHashMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/WeakList.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/WeakReferenceArray.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/containers/WeakValueHashMap.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/diff/Diff.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/diff/IntLCS.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/diff/LCSBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/diff/LinkedDiffPaths.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/diff/Reindexer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/ArrayEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/ArrayListEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/DoubleEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/EmptyEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/EnumerationCopy.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/LightEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/LightEnumerationAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/SequenceEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/enumeration/SingleEnumeration.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/exception/RootException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/exception/RootRuntimeException.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/graph/CachingSemiGraph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/graph/DFSTBuilder.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/graph/Graph.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/graph/GraphGenerator.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/io/IOUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/io/ZipUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/CharArrayCharSequence.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/CharArrayUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/CloneableTokenizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/DateFormatUtil.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/LineReader.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/MergingCharSequence.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/StringSearcher.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/text/StringTokenizer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/AbstractTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/ColumnInfo.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/ComboBoxTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/ComboBoxTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/IdeaUIManager.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/ItemRemovable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/LabelWithTooltip.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/ListTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/SortableColumnModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/Table.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/TableViewModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/Tree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/ListTreeTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/ListTreeTableModelOnColumns.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTable.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTableCellEditor.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTableCellRenderer.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTableModel.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTableModelAdapter.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/src/com/intellij/util/ui/treetable/TreeTableTree.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/openapi/util/TextRangeTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/Assertion.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/StringConvertion.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/CoModifiableListTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/ContainerUtilTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/EnumeratorTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/FilteringIteratorTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/HugeArrayTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/QueueTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/SequenceIteratorTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/TObjectIntHashMapTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/WeakListTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/WeakReferenceArrayTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/containers/WeaksTestCase.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/diff/IntLCSTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/diff/LinkedDiffPathsTest.java create mode 100644 src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/util/testSource/com/intellij/util/diff/ReindexerTest.java diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee.json b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee.json index e6971af6dc9..0ecded23a47 100644 --- a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee.json +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee.json @@ -1 +1 @@ -{"parentCommitId":"0","currentCommitId":"7460e5adae69c7b17c951f1198a6b6900721a1ee","filesBefore":[],"filesCurrent":["UIDesignerCore/src/com/intellij/uiDesigner/compiler/AlienFormFileException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/ClassToBindNotFoundException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/CodeGenerationException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/Utils.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/CompiledClassPropertiesProvider.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IRootContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwAtomicComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwHSpacer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroBooleanProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroDimensionProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroDoubleProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroInsetsProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroIntProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroRectangleProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntrospectedProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwRbIntroStringProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwRootContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwScrollPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwSplitPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwTabbedPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwVSpacer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwXmlReader.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/PropertiesProvider.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/StringDescriptor.java","UIDesignerCore/src/com/intellij/uiDesigner/shared/BorderType.java","UIDesignerCore/src/com/intellij/uiDesigner/shared/XYLayoutManager.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test1.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test2.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test3.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test4.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test5.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test6.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test7.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test8.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestEmpty.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestEqualSizeCells.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestGaps.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestPrefSize.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestSpans.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestTextAreas.java","UsageView/src/com/intellij/usages/TextChunk.java","UsageView/src/com/intellij/usages/Usage.java","UsageView/src/com/intellij/usages/UsageGroup.java","UsageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java","UsageView/src/com/intellij/usages/UsageModelTracker.java","UsageView/src/com/intellij/usages/UsagePresentation.java","UsageView/src/com/intellij/usages/UsageSearcher.java","UsageView/src/com/intellij/usages/UsageTarget.java","UsageView/src/com/intellij/usages/UsageView.java","UsageView/src/com/intellij/usages/UsageViewManager.java","UsageView/src/com/intellij/usages/UsageViewPresentation.java","UsageView/src/com/intellij/usages/UsageViewSettings.java","UsageView/src/com/intellij/usages/actions/ExcludeUsageAction.java","UsageView/src/com/intellij/usages/actions/IncludeExcludeActionBase.java","UsageView/src/com/intellij/usages/actions/IncludeUsageAction.java","UsageView/src/com/intellij/usages/impl/ExporterToTextFile.java","UsageView/src/com/intellij/usages/impl/GroupNode.java","UsageView/src/com/intellij/usages/impl/Node.java","UsageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java","UsageView/src/com/intellij/usages/impl/UsageNode.java","UsageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java","UsageView/src/com/intellij/usages/impl/UsageTargetNode.java","UsageView/src/com/intellij/usages/impl/UsageViewImpl.java","UsageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java","UsageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java","UsageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java","UsageView/src/com/intellij/usages/impl/rules/ClassGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/MethodGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/PackageGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/UsageType.java","UsageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java","UsageView/src/com/intellij/usages/rules/MergeableUsage.java","UsageView/src/com/intellij/usages/rules/PsiElementUsage.java","UsageView/src/com/intellij/usages/rules/UsageGroupingRule.java","UsageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java","UsageView/src/com/intellij/usages/rules/UsageInFile.java","UsageView/src/com/intellij/usages/rules/UsageInFiles.java","UsageView/src/com/intellij/usages/rules/UsageInLibrary.java","UsageView/src/com/intellij/usages/rules/UsageInModule.java","UsageView/testSource/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/ActionsPlugin.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/GarbageCollectionAction.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/HelloWorldAction.java","doc/openapi/examples/plugin/src/com/intellij/openapi/samples/SampleApplicationPlugin.java","doc/openapi/examples/plugin/src/com/intellij/openapi/samples/SampleProjectPlugin.java","doc/openapi/examples/toolWindow/src/com/intellij/openapi/samples/SimpleToolWindowPlugin.java","doc/openapi/examples/vfs/src/com/intellij/openapi/samples/VfsSamplePlugin.java","forms_rt/src/com/intellij/uiDesigner/core/AbstractLayout.java","forms_rt/src/com/intellij/uiDesigner/core/DimensionInfo.java","forms_rt/src/com/intellij/uiDesigner/core/GridConstraints.java","forms_rt/src/com/intellij/uiDesigner/core/GridLayoutManager.java","forms_rt/src/com/intellij/uiDesigner/core/HorizontalInfo.java","forms_rt/src/com/intellij/uiDesigner/core/LayoutState.java","forms_rt/src/com/intellij/uiDesigner/core/Spacer.java","forms_rt/src/com/intellij/uiDesigner/core/SupportCode.java","forms_rt/src/com/intellij/uiDesigner/core/Util.java","forms_rt/src/com/intellij/uiDesigner/core/VerticalInfo.java","javac2/src/com/intellij/uiDesigner/ant/Javac2.java","openapi/src/com/intellij/ant/AntElementRole.java","openapi/src/com/intellij/ant/PsiAntElement.java","openapi/src/com/intellij/codeHighlighting/BackgroundEditorHighlighter.java","openapi/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java","openapi/src/com/intellij/codeHighlighting/HighlightingPass.java","openapi/src/com/intellij/codeInsight/ExpectedTypeInfo.java","openapi/src/com/intellij/codeInsight/ExpectedTypesProvider.java","openapi/src/com/intellij/codeInsight/highlighting/HighlightManager.java","openapi/src/com/intellij/codeInsight/intention/IntentionAction.java","openapi/src/com/intellij/codeInsight/intention/IntentionManager.java","openapi/src/com/intellij/codeInspection/InspectionManager.java","openapi/src/com/intellij/codeInspection/InspectionToolProvider.java","openapi/src/com/intellij/codeInspection/LocalInspectionTool.java","openapi/src/com/intellij/codeInspection/LocalQuickFix.java","openapi/src/com/intellij/codeInspection/ProblemDescriptor.java","openapi/src/com/intellij/codeInspection/ProblemHighlightType.java","openapi/src/com/intellij/debugger/DebuggerContext.java","openapi/src/com/intellij/debugger/DebuggerManager.java","openapi/src/com/intellij/debugger/NoDataException.java","openapi/src/com/intellij/debugger/PositionManager.java","openapi/src/com/intellij/debugger/SourcePosition.java","openapi/src/com/intellij/debugger/engine/DebugProcess.java","openapi/src/com/intellij/debugger/engine/DebugProcessAdapter.java","openapi/src/com/intellij/debugger/engine/DebugProcessListener.java","openapi/src/com/intellij/debugger/engine/DebuggerUtils.java","openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java","openapi/src/com/intellij/debugger/engine/StackFrameContext.java","openapi/src/com/intellij/debugger/engine/SuspendContext.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluateException.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java","openapi/src/com/intellij/debugger/engine/evaluation/TextWithImports.java","openapi/src/com/intellij/debugger/engine/jdi/LocalVariableProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ObjectReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ThreadGroupReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ThreadReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java","openapi/src/com/intellij/debugger/engine/managerThread/DebuggerCommand.java","openapi/src/com/intellij/debugger/engine/managerThread/DebuggerManagerThread.java","openapi/src/com/intellij/debugger/engine/managerThread/SuspendContextCommand.java","openapi/src/com/intellij/debugger/requests/ClassPrepareRequestor.java","openapi/src/com/intellij/debugger/requests/RequestManager.java","openapi/src/com/intellij/debugger/requests/Requestor.java","openapi/src/com/intellij/debugger/ui/CompletitionEditor.java","openapi/src/com/intellij/debugger/ui/tree/ArrayElementDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java","openapi/src/com/intellij/debugger/ui/tree/FieldDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/LocalVariableDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/NodeDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorFactory.java","openapi/src/com/intellij/debugger/ui/tree/NodeManager.java","openapi/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/StaticDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ThreadDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ThreadGroupDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/UserExpressionDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ValueDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java","openapi/src/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java","openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java","openapi/src/com/intellij/debugger/ui/tree/render/NodeRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java","openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/Renderer.java","openapi/src/com/intellij/debugger/ui/tree/render/RendererProvider.java","openapi/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java","openapi/src/com/intellij/execution/CantRunException.java","openapi/src/com/intellij/execution/DefaultExecutionResult.java","openapi/src/com/intellij/execution/ExecutionException.java","openapi/src/com/intellij/execution/ExecutionManager.java","openapi/src/com/intellij/execution/ExecutionRegistry.java","openapi/src/com/intellij/execution/ExecutionResult.java","openapi/src/com/intellij/execution/RunConfigurationConfigurableAdapter.java","openapi/src/com/intellij/execution/configurations/CommandLineState.java","openapi/src/com/intellij/execution/configurations/ConfigurationFactory.java","openapi/src/com/intellij/execution/configurations/ConfigurationInfoProvider.java","openapi/src/com/intellij/execution/configurations/ConfigurationPerRunnerSettings.java","openapi/src/com/intellij/execution/configurations/ConfigurationTemplate.java","openapi/src/com/intellij/execution/configurations/ConfigurationType.java","openapi/src/com/intellij/execution/configurations/GeneralCommandLine.java","openapi/src/com/intellij/execution/configurations/JavaCommandLine.java","openapi/src/com/intellij/execution/configurations/JavaCommandLineState.java","openapi/src/com/intellij/execution/configurations/JavaParameters.java","openapi/src/com/intellij/execution/configurations/ParametersList.java","openapi/src/com/intellij/execution/configurations/PatchedRunnableState.java","openapi/src/com/intellij/execution/configurations/RemoteConnection.java","openapi/src/com/intellij/execution/configurations/RemoteState.java","openapi/src/com/intellij/execution/configurations/RunConfiguration.java","openapi/src/com/intellij/execution/configurations/RunConfigurationBase.java","openapi/src/com/intellij/execution/configurations/RunConfigurationWithRunnerSettings.java","openapi/src/com/intellij/execution/configurations/RunProfile.java","openapi/src/com/intellij/execution/configurations/RunProfileState.java","openapi/src/com/intellij/execution/configurations/RunnableState.java","openapi/src/com/intellij/execution/configurations/RunnerSettings.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationError.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationException.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationWarning.java","openapi/src/com/intellij/execution/filters/CompositeFilter.java","openapi/src/com/intellij/execution/filters/ExceptionFilter.java","openapi/src/com/intellij/execution/filters/Filter.java","openapi/src/com/intellij/execution/filters/HyperlinkInfo.java","openapi/src/com/intellij/execution/filters/InvalidExpressionException.java","openapi/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java","openapi/src/com/intellij/execution/filters/RegexpFilter.java","openapi/src/com/intellij/execution/filters/TextConsoleBuilder.java","openapi/src/com/intellij/execution/process/DefaultJavaProcessHandler.java","openapi/src/com/intellij/execution/process/OSProcessHandler.java","openapi/src/com/intellij/execution/process/ProcessAdapter.java","openapi/src/com/intellij/execution/process/ProcessEvent.java","openapi/src/com/intellij/execution/process/ProcessHandler.java","openapi/src/com/intellij/execution/process/ProcessListener.java","openapi/src/com/intellij/execution/process/ProcessNotCreatedException.java","openapi/src/com/intellij/execution/process/ProcessOutputTypes.java","openapi/src/com/intellij/execution/process/ProcessTerminatedListener.java","openapi/src/com/intellij/execution/runners/JavaProgramRunner.java","openapi/src/com/intellij/execution/runners/ProcessProxy.java","openapi/src/com/intellij/execution/runners/ProcessProxyFactory.java","openapi/src/com/intellij/execution/ui/CloseAction.java","openapi/src/com/intellij/execution/ui/ConsoleView.java","openapi/src/com/intellij/execution/ui/ConsoleViewContentType.java","openapi/src/com/intellij/execution/ui/ExecutionConsole.java","openapi/src/com/intellij/execution/ui/RunContentDescriptor.java","openapi/src/com/intellij/execution/ui/RunContentListener.java","openapi/src/com/intellij/execution/ui/RunContentManager.java","openapi/src/com/intellij/find/FindManager.java","openapi/src/com/intellij/find/FindModel.java","openapi/src/com/intellij/find/FindResult.java","openapi/src/com/intellij/ide/AutoScrollToSourceOptionProvider.java","openapi/src/com/intellij/ide/BrowserUtil.java","openapi/src/com/intellij/ide/CommonActionsManager.java","openapi/src/com/intellij/ide/CopyProvider.java","openapi/src/com/intellij/ide/CutProvider.java","openapi/src/com/intellij/ide/DataManager.java","openapi/src/com/intellij/ide/DeleteProvider.java","openapi/src/com/intellij/ide/EditorHighlighter.java","openapi/src/com/intellij/ide/ExporterToTextFile.java","openapi/src/com/intellij/ide/GeneralSettings.java","openapi/src/com/intellij/ide/OccurenceNavigator.java","openapi/src/com/intellij/ide/OccurenceNavigatorSupport.java","openapi/src/com/intellij/ide/SelectInManager.java","openapi/src/com/intellij/ide/SelectInTarget.java","openapi/src/com/intellij/ide/TreeExpander.java","openapi/src/com/intellij/ide/actions/CollapseAllToolbarAction.java","openapi/src/com/intellij/ide/actions/ExpandAllToolbarAction.java","openapi/src/com/intellij/ide/actions/TreeCollapseAllActionBase.java","openapi/src/com/intellij/ide/actions/TreeExpandAllActionBase.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateDescriptor.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateGroupDescriptor.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateGroupDescriptorFactory.java","openapi/src/com/intellij/ide/projectView/PresentationData.java","openapi/src/com/intellij/ide/projectView/ProjectViewNode.java","openapi/src/com/intellij/ide/projectView/TreeStructureProvider.java","openapi/src/com/intellij/ide/projectView/ViewSettings.java","openapi/src/com/intellij/ide/structureView/StructureViewModel.java","openapi/src/com/intellij/ide/structureView/StructureViewTreeElement.java","openapi/src/com/intellij/ide/util/BrowseFilesListener.java","openapi/src/com/intellij/ide/util/PropertiesComponent.java","openapi/src/com/intellij/ide/util/projectWizard/ExistingModuleLoader.java","openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java","openapi/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java","openapi/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java","openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java","openapi/src/com/intellij/ide/util/projectWizard/WizardContext.java","openapi/src/com/intellij/ide/util/treeView/AbstractTreeNode.java","openapi/src/com/intellij/ide/util/treeView/NodeDescriptor.java","openapi/src/com/intellij/ide/util/treeView/NodeOptions.java","openapi/src/com/intellij/ide/util/treeView/NodeRenderer.java","openapi/src/com/intellij/ide/util/treeView/smartTree/ActionPresentation.java","openapi/src/com/intellij/ide/util/treeView/smartTree/ActionPresentationData.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Filter.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Group.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Grouper.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Sorter.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeAction.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeElement.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeModel.java","openapi/src/com/intellij/ide/wizard/AbstractWizard.java","openapi/src/com/intellij/ide/wizard/CommitStepException.java","openapi/src/com/intellij/ide/wizard/Step.java","openapi/src/com/intellij/ide/wizard/StepAdapter.java","openapi/src/com/intellij/j2ee/PasswordUtil.java","openapi/src/com/intellij/j2ee/j2eeDom/ClassUtil.java","openapi/src/com/intellij/j2ee/make/BuildInstruction.java","openapi/src/com/intellij/j2ee/make/BuildInstructionVisitor.java","openapi/src/com/intellij/j2ee/make/BuildRecipe.java","openapi/src/com/intellij/j2ee/make/FileCopyInstruction.java","openapi/src/com/intellij/j2ee/make/J2EEBuildParticipant.java","openapi/src/com/intellij/j2ee/make/J2EEModuleBuildInstruction.java","openapi/src/com/intellij/j2ee/make/JarAndCopyBuildInstruction.java","openapi/src/com/intellij/j2ee/make/ManifestBuilder.java","openapi/src/com/intellij/j2ee/make/ModuleBuildProperties.java","openapi/src/com/intellij/j2ee/module/ContainerElement.java","openapi/src/com/intellij/j2ee/module/LibraryLink.java","openapi/src/com/intellij/j2ee/module/ModuleLink.java","openapi/src/com/intellij/j2ee/run/localRun/EnvironmentVariable.java","openapi/src/com/intellij/j2ee/ui/Commitable.java","openapi/src/com/intellij/j2ee/ui/CommitablePanel.java","openapi/src/com/intellij/j2ee/ui/CompositeCommitable.java","openapi/src/com/intellij/j2ee/ui/Warning.java","openapi/src/com/intellij/lexer/CompositeLexer.java","openapi/src/com/intellij/lexer/EmptyLexer.java","openapi/src/com/intellij/lexer/FilterLexer.java","openapi/src/com/intellij/lexer/LayeredLexer.java","openapi/src/com/intellij/lexer/Lexer.java","openapi/src/com/intellij/lexer/MergingLexerAdapter.java","openapi/src/com/intellij/navigation/ChooseByNameContributor.java","openapi/src/com/intellij/navigation/ChooseByNameRegistry.java","openapi/src/com/intellij/navigation/ItemPresentation.java","openapi/src/com/intellij/navigation/NavigationItem.java","openapi/src/com/intellij/openapi/Disposeable.java","openapi/src/com/intellij/openapi/actionSystem/ActionButtonComponent.java","openapi/src/com/intellij/openapi/actionSystem/ActionGroup.java","openapi/src/com/intellij/openapi/actionSystem/ActionManager.java","openapi/src/com/intellij/openapi/actionSystem/ActionPlaces.java","openapi/src/com/intellij/openapi/actionSystem/ActionPopupMenu.java","openapi/src/com/intellij/openapi/actionSystem/ActionStub.java","openapi/src/com/intellij/openapi/actionSystem/ActionToolbar.java","openapi/src/com/intellij/openapi/actionSystem/AnAction.java","openapi/src/com/intellij/openapi/actionSystem/AnActionEvent.java","openapi/src/com/intellij/openapi/actionSystem/Anchor.java","openapi/src/com/intellij/openapi/actionSystem/CommonShortcuts.java","openapi/src/com/intellij/openapi/actionSystem/Constraints.java","openapi/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java","openapi/src/com/intellij/openapi/actionSystem/DataConstants.java","openapi/src/com/intellij/openapi/actionSystem/DataContext.java","openapi/src/com/intellij/openapi/actionSystem/DataProvider.java","openapi/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java","openapi/src/com/intellij/openapi/actionSystem/IdeActions.java","openapi/src/com/intellij/openapi/actionSystem/KeyboardShortcut.java","openapi/src/com/intellij/openapi/actionSystem/MouseShortcut.java","openapi/src/com/intellij/openapi/actionSystem/Presentation.java","openapi/src/com/intellij/openapi/actionSystem/Separator.java","openapi/src/com/intellij/openapi/actionSystem/Shortcut.java","openapi/src/com/intellij/openapi/actionSystem/ShortcutSet.java","openapi/src/com/intellij/openapi/actionSystem/ToggleAction.java","openapi/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java","openapi/src/com/intellij/openapi/actionSystem/ex/CustomComponentAction.java","openapi/src/com/intellij/openapi/application/Application.java","openapi/src/com/intellij/openapi/application/ApplicationAdapter.java","openapi/src/com/intellij/openapi/application/ApplicationInfo.java","openapi/src/com/intellij/openapi/application/ApplicationListener.java","openapi/src/com/intellij/openapi/application/ApplicationManager.java","openapi/src/com/intellij/openapi/application/ModalityState.java","openapi/src/com/intellij/openapi/application/ModalityStateListener.java","openapi/src/com/intellij/openapi/application/PathManager.java","openapi/src/com/intellij/openapi/command/CommandAdapter.java","openapi/src/com/intellij/openapi/command/CommandEvent.java","openapi/src/com/intellij/openapi/command/CommandListener.java","openapi/src/com/intellij/openapi/command/CommandProcessor.java","openapi/src/com/intellij/openapi/command/UndoConfirmationPolicy.java","openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java","openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java","openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java","openapi/src/com/intellij/openapi/compiler/CompileContext.java","openapi/src/com/intellij/openapi/compiler/CompileScope.java","openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java","openapi/src/com/intellij/openapi/compiler/CompileTask.java","openapi/src/com/intellij/openapi/compiler/Compiler.java","openapi/src/com/intellij/openapi/compiler/CompilerManager.java","openapi/src/com/intellij/openapi/compiler/CompilerMessage.java","openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java","openapi/src/com/intellij/openapi/compiler/CompilerPaths.java","openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java","openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java","openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java","openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java","openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java","openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java","openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java","openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java","openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java","openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java","openapi/src/com/intellij/openapi/compiler/Validator.java","openapi/src/com/intellij/openapi/compiler/ValidityState.java","openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java","openapi/src/com/intellij/openapi/components/ApplicationComponent.java","openapi/src/com/intellij/openapi/components/BaseComponent.java","openapi/src/com/intellij/openapi/components/ComponentManager.java","openapi/src/com/intellij/openapi/components/ExportableApplicationComponent.java","openapi/src/com/intellij/openapi/components/ProjectComponent.java","openapi/src/com/intellij/openapi/components/SettingsSavingComponent.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsModule.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsRepository.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsResult.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsServices.java","openapi/src/com/intellij/openapi/cvsIntegration/DateOrRevision.java","openapi/src/com/intellij/openapi/diagnostic/ErrorLogger.java","openapi/src/com/intellij/openapi/diagnostic/IdeaLoggingEvent.java","openapi/src/com/intellij/openapi/diff/BinaryContent.java","openapi/src/com/intellij/openapi/diff/DiffColors.java","openapi/src/com/intellij/openapi/diff/DiffContent.java","openapi/src/com/intellij/openapi/diff/DiffContentUtil.java","openapi/src/com/intellij/openapi/diff/DiffManager.java","openapi/src/com/intellij/openapi/diff/DiffPanel.java","openapi/src/com/intellij/openapi/diff/DiffPanelFactory.java","openapi/src/com/intellij/openapi/diff/DiffRequest.java","openapi/src/com/intellij/openapi/diff/DiffRequestFactory.java","openapi/src/com/intellij/openapi/diff/DiffTool.java","openapi/src/com/intellij/openapi/diff/DiffToolbar.java","openapi/src/com/intellij/openapi/diff/DiffViewer.java","openapi/src/com/intellij/openapi/diff/DocumentContent.java","openapi/src/com/intellij/openapi/diff/DocumentsSynchonizer.java","openapi/src/com/intellij/openapi/diff/FileContent.java","openapi/src/com/intellij/openapi/diff/FragmentContent.java","openapi/src/com/intellij/openapi/diff/LineTokenizer.java","openapi/src/com/intellij/openapi/diff/MergeRequest.java","openapi/src/com/intellij/openapi/diff/SimpleContent.java","openapi/src/com/intellij/openapi/diff/SimpleDiffRequest.java","openapi/src/com/intellij/openapi/editor/CaretModel.java","openapi/src/com/intellij/openapi/editor/Document.java","openapi/src/com/intellij/openapi/editor/DocumentFragment.java","openapi/src/com/intellij/openapi/editor/Editor.java","openapi/src/com/intellij/openapi/editor/EditorFactory.java","openapi/src/com/intellij/openapi/editor/EditorGutter.java","openapi/src/com/intellij/openapi/editor/EditorModificationUtil.java","openapi/src/com/intellij/openapi/editor/EditorSettings.java","openapi/src/com/intellij/openapi/editor/FoldRegion.java","openapi/src/com/intellij/openapi/editor/FoldingModel.java","openapi/src/com/intellij/openapi/editor/HighlighterColors.java","openapi/src/com/intellij/openapi/editor/LogicalPosition.java","openapi/src/com/intellij/openapi/editor/RangeMarker.java","openapi/src/com/intellij/openapi/editor/ReadOnlyFragmentModificationException.java","openapi/src/com/intellij/openapi/editor/ReadOnlyModificationException.java","openapi/src/com/intellij/openapi/editor/ScrollType.java","openapi/src/com/intellij/openapi/editor/ScrollingModel.java","openapi/src/com/intellij/openapi/editor/SelectionModel.java","openapi/src/com/intellij/openapi/editor/TextAnnotationGutterProvider.java","openapi/src/com/intellij/openapi/editor/VisualPosition.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorAction.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorActionManager.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorWriteActionHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/ReadonlyFragmentModificationHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/TypedAction.java","openapi/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java","openapi/src/com/intellij/openapi/editor/colors/ColorKey.java","openapi/src/com/intellij/openapi/editor/colors/EditorColors.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsAdapter.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsListener.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsManager.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsScheme.java","openapi/src/com/intellij/openapi/editor/colors/EditorFontType.java","openapi/src/com/intellij/openapi/editor/colors/TextAttributesKey.java","openapi/src/com/intellij/openapi/editor/event/CaretEvent.java","openapi/src/com/intellij/openapi/editor/event/CaretListener.java","openapi/src/com/intellij/openapi/editor/event/DocumentAdapter.java","openapi/src/com/intellij/openapi/editor/event/DocumentEvent.java","openapi/src/com/intellij/openapi/editor/event/DocumentListener.java","openapi/src/com/intellij/openapi/editor/event/EditorEventMulticaster.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryEvent.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryListener.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseEvent.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseEventArea.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseListener.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseMotionAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseMotionListener.java","openapi/src/com/intellij/openapi/editor/event/MockDocumentEvent.java","openapi/src/com/intellij/openapi/editor/event/SelectionEvent.java","openapi/src/com/intellij/openapi/editor/event/SelectionListener.java","openapi/src/com/intellij/openapi/editor/event/VisibleAreaEvent.java","openapi/src/com/intellij/openapi/editor/event/VisibleAreaListener.java","openapi/src/com/intellij/openapi/editor/markup/ActiveGutterRenderer.java","openapi/src/com/intellij/openapi/editor/markup/EffectType.java","openapi/src/com/intellij/openapi/editor/markup/ErrorStripeRenderer.java","openapi/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java","openapi/src/com/intellij/openapi/editor/markup/GutterIconRenderer.java","openapi/src/com/intellij/openapi/editor/markup/HighlighterLayer.java","openapi/src/com/intellij/openapi/editor/markup/HighlighterTargetArea.java","openapi/src/com/intellij/openapi/editor/markup/LineMarkerRenderer.java","openapi/src/com/intellij/openapi/editor/markup/MarkupEditorFilter.java","openapi/src/com/intellij/openapi/editor/markup/MarkupModel.java","openapi/src/com/intellij/openapi/editor/markup/RangeHighlighter.java","openapi/src/com/intellij/openapi/editor/markup/SeparatorPlacement.java","openapi/src/com/intellij/openapi/editor/markup/TextAttributes.java","openapi/src/com/intellij/openapi/fileChooser/FileChooser.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDialog.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserFactory.java","openapi/src/com/intellij/openapi/fileChooser/FileElement.java","openapi/src/com/intellij/openapi/fileChooser/FileSystemTree.java","openapi/src/com/intellij/openapi/fileChooser/FileSystemTreeFactory.java","openapi/src/com/intellij/openapi/fileEditor/DocumentsEditor.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManager.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManagerAdapter.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManagerListener.java","openapi/src/com/intellij/openapi/fileEditor/FileEditor.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorLocation.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManager.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerAdapter.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerListener.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorPolicy.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorProvider.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorState.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorStateLevel.java","openapi/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java","openapi/src/com/intellij/openapi/fileEditor/TextEditor.java","openapi/src/com/intellij/openapi/fileEditor/TextEditorLocation.java","openapi/src/com/intellij/openapi/fileEditor/VetoDocumentReloadException.java","openapi/src/com/intellij/openapi/fileEditor/VetoDocumentSavingException.java","openapi/src/com/intellij/openapi/fileTypes/FileHighlighter.java","openapi/src/com/intellij/openapi/fileTypes/FileHighlighterBase.java","openapi/src/com/intellij/openapi/fileTypes/FileType.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeEvent.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeListener.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeManager.java","openapi/src/com/intellij/openapi/fileTypes/PlainFileHighlighter.java","openapi/src/com/intellij/openapi/fileTypes/StdFileTypes.java","openapi/src/com/intellij/openapi/fileTypes/UserFileType.java","openapi/src/com/intellij/openapi/help/HelpManager.java","openapi/src/com/intellij/openapi/ide/CopyPasteManager.java","openapi/src/com/intellij/openapi/localVcs/LocalVcs.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsItemsLocker.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsPurgingProvider.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsServices.java","openapi/src/com/intellij/openapi/localVcs/LvcsAction.java","openapi/src/com/intellij/openapi/localVcs/LvcsComparator.java","openapi/src/com/intellij/openapi/localVcs/LvcsConfiguration.java","openapi/src/com/intellij/openapi/localVcs/LvcsDirectory.java","openapi/src/com/intellij/openapi/localVcs/LvcsDirectoryRevision.java","openapi/src/com/intellij/openapi/localVcs/LvcsFile.java","openapi/src/com/intellij/openapi/localVcs/LvcsFileRevision.java","openapi/src/com/intellij/openapi/localVcs/LvcsLabel.java","openapi/src/com/intellij/openapi/localVcs/LvcsLabelListener.java","openapi/src/com/intellij/openapi/localVcs/LvcsObject.java","openapi/src/com/intellij/openapi/localVcs/LvcsRevision.java","openapi/src/com/intellij/openapi/localVcs/UpToDateLineNumberProvider.java","openapi/src/com/intellij/openapi/localVcs/VirtualFileInfo.java","openapi/src/com/intellij/openapi/module/ModifiableModuleModel.java","openapi/src/com/intellij/openapi/module/Module.java","openapi/src/com/intellij/openapi/module/ModuleComponent.java","openapi/src/com/intellij/openapi/module/ModuleConfigurationEditor.java","openapi/src/com/intellij/openapi/module/ModuleManager.java","openapi/src/com/intellij/openapi/module/ModulePointer.java","openapi/src/com/intellij/openapi/module/ModulePointerManager.java","openapi/src/com/intellij/openapi/module/ModuleType.java","openapi/src/com/intellij/openapi/module/ModuleTypeManager.java","openapi/src/com/intellij/openapi/module/ModuleWithNameAlreadyExists.java","openapi/src/com/intellij/openapi/options/BaseConfigurable.java","openapi/src/com/intellij/openapi/options/BaseConfigurableWithChangeSupport.java","openapi/src/com/intellij/openapi/options/CompositeSettingsBuilder.java","openapi/src/com/intellij/openapi/options/CompositeSettingsEditor.java","openapi/src/com/intellij/openapi/options/Configurable.java","openapi/src/com/intellij/openapi/options/ConfigurableGroup.java","openapi/src/com/intellij/openapi/options/ConfigurationException.java","openapi/src/com/intellij/openapi/options/GroupSettingsBuilder.java","openapi/src/com/intellij/openapi/options/SettingsEditor.java","openapi/src/com/intellij/openapi/options/SettingsEditorConfigurable.java","openapi/src/com/intellij/openapi/options/SettingsEditorGroup.java","openapi/src/com/intellij/openapi/options/SettingsEditorListener.java","openapi/src/com/intellij/openapi/options/SettingsEditorWrapper.java","openapi/src/com/intellij/openapi/options/ShowSettingsUtil.java","openapi/src/com/intellij/openapi/options/UnnamedConfigurable.java","openapi/src/com/intellij/openapi/options/UnnamedConfigurableGroup.java","openapi/src/com/intellij/openapi/options/colors/AttributesDescriptor.java","openapi/src/com/intellij/openapi/options/colors/ColorDescriptor.java","openapi/src/com/intellij/openapi/options/colors/ColorSettingsPage.java","openapi/src/com/intellij/openapi/options/colors/ColorSettingsPages.java","openapi/src/com/intellij/openapi/progress/ProcessCanceledException.java","openapi/src/com/intellij/openapi/progress/ProgressFunComponentProvider.java","openapi/src/com/intellij/openapi/progress/ProgressIndicator.java","openapi/src/com/intellij/openapi/progress/ProgressManager.java","openapi/src/com/intellij/openapi/project/ModuleListener.java","openapi/src/com/intellij/openapi/project/Project.java","openapi/src/com/intellij/openapi/project/ProjectManager.java","openapi/src/com/intellij/openapi/project/ProjectManagerAdapter.java","openapi/src/com/intellij/openapi/project/ProjectManagerListener.java","openapi/src/com/intellij/openapi/project/ProjectReloadState.java","openapi/src/com/intellij/openapi/projectRoots/AdditionalDataConfigurable.java","openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java","openapi/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java","openapi/src/com/intellij/openapi/projectRoots/ProjectRootListener.java","openapi/src/com/intellij/openapi/projectRoots/Sdk.java","openapi/src/com/intellij/openapi/projectRoots/SdkAdditionalData.java","openapi/src/com/intellij/openapi/projectRoots/SdkModel.java","openapi/src/com/intellij/openapi/projectRoots/SdkModificator.java","openapi/src/com/intellij/openapi/projectRoots/SdkType.java","openapi/src/com/intellij/openapi/roots/ContentEntry.java","openapi/src/com/intellij/openapi/roots/ContentFolder.java","openapi/src/com/intellij/openapi/roots/ContentIterator.java","openapi/src/com/intellij/openapi/roots/ExcludeFolder.java","openapi/src/com/intellij/openapi/roots/ExcludedOutputFolder.java","openapi/src/com/intellij/openapi/roots/ExportableOrderEntry.java","openapi/src/com/intellij/openapi/roots/FileIndex.java","openapi/src/com/intellij/openapi/roots/InheritedJdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/JdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/LibraryOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModifiableRootModel.java","openapi/src/com/intellij/openapi/roots/ModuleFileIndex.java","openapi/src/com/intellij/openapi/roots/ModuleJdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModuleOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModuleRootEvent.java","openapi/src/com/intellij/openapi/roots/ModuleRootListener.java","openapi/src/com/intellij/openapi/roots/ModuleRootManager.java","openapi/src/com/intellij/openapi/roots/ModuleRootModel.java","openapi/src/com/intellij/openapi/roots/ModuleSourceOrderEntry.java","openapi/src/com/intellij/openapi/roots/OrderEntry.java","openapi/src/com/intellij/openapi/roots/OrderRootType.java","openapi/src/com/intellij/openapi/roots/ProjectFileIndex.java","openapi/src/com/intellij/openapi/roots/ProjectRootManager.java","openapi/src/com/intellij/openapi/roots/ProjectRootsTraversing.java","openapi/src/com/intellij/openapi/roots/RootPolicy.java","openapi/src/com/intellij/openapi/roots/RootProvider.java","openapi/src/com/intellij/openapi/roots/SearchingPolicy.java","openapi/src/com/intellij/openapi/roots/SourceFolder.java","openapi/src/com/intellij/openapi/roots/Synthetic.java","openapi/src/com/intellij/openapi/roots/UserDefinedExcludeFolder.java","openapi/src/com/intellij/openapi/roots/libraries/Library.java","openapi/src/com/intellij/openapi/roots/libraries/LibraryTable.java","openapi/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java","openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationEditorProvider.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModulesProvider.java","openapi/src/com/intellij/openapi/startup/StartupManager.java","openapi/src/com/intellij/openapi/ui/ComboBox.java","openapi/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java","openapi/src/com/intellij/openapi/ui/DialogBuilder.java","openapi/src/com/intellij/openapi/ui/DialogWrapper.java","openapi/src/com/intellij/openapi/ui/DialogWrapperDialog.java","openapi/src/com/intellij/openapi/ui/DialogWrapperPeer.java","openapi/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java","openapi/src/com/intellij/openapi/ui/FixedSizeButton.java","openapi/src/com/intellij/openapi/ui/InputException.java","openapi/src/com/intellij/openapi/ui/InputValidator.java","openapi/src/com/intellij/openapi/ui/LabeledComponent.java","openapi/src/com/intellij/openapi/ui/Messages.java","openapi/src/com/intellij/openapi/ui/MultiLineLabelUI.java","openapi/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java","openapi/src/com/intellij/openapi/ui/Splitter.java","openapi/src/com/intellij/openapi/ui/TestDialog.java","openapi/src/com/intellij/openapi/ui/TextComponentAccessor.java","openapi/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java","openapi/src/com/intellij/openapi/ui/VerticalFlowLayout.java","openapi/src/com/intellij/openapi/util/DimensionService.java","openapi/src/com/intellij/openapi/util/ExceptionMessages.java","openapi/src/com/intellij/openapi/util/IconLoader.java","openapi/src/com/intellij/openapi/util/Iconable.java","openapi/src/com/intellij/openapi/util/ModificationTracker.java","openapi/src/com/intellij/openapi/vcs/AbstractVcs.java","openapi/src/com/intellij/openapi/vcs/AbstractVcsHelper.java","openapi/src/com/intellij/openapi/vcs/CheckinProjectPanel.java","openapi/src/com/intellij/openapi/vcs/EditFileProvider.java","openapi/src/com/intellij/openapi/vcs/FilePath.java","openapi/src/com/intellij/openapi/vcs/FileStatus.java","openapi/src/com/intellij/openapi/vcs/FileStatusFactory.java","openapi/src/com/intellij/openapi/vcs/FileStatusListener.java","openapi/src/com/intellij/openapi/vcs/FileStatusManager.java","openapi/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java","openapi/src/com/intellij/openapi/vcs/SelectionChangeListener.java","openapi/src/com/intellij/openapi/vcs/TransactionProvider.java","openapi/src/com/intellij/openapi/vcs/TransactionRunnable.java","openapi/src/com/intellij/openapi/vcs/VcsConfiguration.java","openapi/src/com/intellij/openapi/vcs/VcsDataConstants.java","openapi/src/com/intellij/openapi/vcs/VcsException.java","openapi/src/com/intellij/openapi/vcs/actions/StandardVcsGroup.java","openapi/src/com/intellij/openapi/vcs/actions/VcsContext.java","openapi/src/com/intellij/openapi/vcs/actions/VcsContextFactory.java","openapi/src/com/intellij/openapi/vcs/checkin/CheckinEnvironment.java","openapi/src/com/intellij/openapi/vcs/fileView/DualViewColumnInfo.java","openapi/src/com/intellij/openapi/vcs/history/CurrentRevision.java","openapi/src/com/intellij/openapi/vcs/history/HistoryAsTreeProvider.java","openapi/src/com/intellij/openapi/vcs/history/VcsFileRevision.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistoryProvider.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistorySession.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java","openapi/src/com/intellij/openapi/vcs/history/VcsRevisionNumber.java","openapi/src/com/intellij/openapi/vcs/ui/OptionsDialog.java","openapi/src/com/intellij/openapi/vcs/ui/Refreshable.java","openapi/src/com/intellij/openapi/vcs/ui/RefreshableOnComponent.java","openapi/src/com/intellij/openapi/vcs/ui/ReplaceFileConfirmationDialog.java","openapi/src/com/intellij/openapi/vcs/update/FileGroup.java","openapi/src/com/intellij/openapi/vcs/update/UpdateEnvironment.java","openapi/src/com/intellij/openapi/vcs/update/UpdateSession.java","openapi/src/com/intellij/openapi/vcs/update/UpdateSessionAdapter.java","openapi/src/com/intellij/openapi/vcs/update/UpdatedFiles.java","openapi/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsFileSystem.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsVirtualFile.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsVirtualFolder.java","openapi/src/com/intellij/openapi/vfs/CharsetToolkit.java","openapi/src/com/intellij/openapi/vfs/JarFileSystem.java","openapi/src/com/intellij/openapi/vfs/LocalFileSystem.java","openapi/src/com/intellij/openapi/vfs/ModificationAttemptEvent.java","openapi/src/com/intellij/openapi/vfs/ModificationAttemptListener.java","openapi/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java","openapi/src/com/intellij/openapi/vfs/SmartEncodingInputStream.java","openapi/src/com/intellij/openapi/vfs/VfsUtil.java","openapi/src/com/intellij/openapi/vfs/VirtualFile.java","openapi/src/com/intellij/openapi/vfs/VirtualFileAdapter.java","openapi/src/com/intellij/openapi/vfs/VirtualFileEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFileFilter.java","openapi/src/com/intellij/openapi/vfs/VirtualFileListener.java","openapi/src/com/intellij/openapi/vfs/VirtualFileManager.java","openapi/src/com/intellij/openapi/vfs/VirtualFileMoveEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFilePropertyEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFileSystem.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointer.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerContainer.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerFactory.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerListener.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java","openapi/src/com/intellij/openapi/wm/FocusWatcher.java","openapi/src/com/intellij/openapi/wm/StatusBar.java","openapi/src/com/intellij/openapi/wm/ToolWindow.java","openapi/src/com/intellij/openapi/wm/ToolWindowAnchor.java","openapi/src/com/intellij/openapi/wm/ToolWindowId.java","openapi/src/com/intellij/openapi/wm/ToolWindowManager.java","openapi/src/com/intellij/openapi/wm/ToolWindowType.java","openapi/src/com/intellij/openapi/wm/WindowManager.java","openapi/src/com/intellij/peer/PeerFactory.java","openapi/src/com/intellij/pom/java/LanguageLevel.java","openapi/src/com/intellij/pom/java/PomJavaAspect.java","openapi/src/com/intellij/pom/java/events/JavaTreeChanged.java","openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java","openapi/src/com/intellij/pom/java/events/PomJavaChange.java","openapi/src/com/intellij/psi/CustomHighlighterTokenType.java","openapi/src/com/intellij/psi/EmptySubstitutor.java","openapi/src/com/intellij/psi/GenericsUtil.java","openapi/src/com/intellij/psi/ImplicitVariable.java","openapi/src/com/intellij/psi/JavaDocTokenType.java","openapi/src/com/intellij/psi/JavaElementVisitor.java","openapi/src/com/intellij/psi/JavaTokenType.java","openapi/src/com/intellij/psi/PsiAnnotation.java","openapi/src/com/intellij/psi/PsiAnnotationMemberValue.java","openapi/src/com/intellij/psi/PsiAnnotationMethod.java","openapi/src/com/intellij/psi/PsiAnnotationParameterList.java","openapi/src/com/intellij/psi/PsiAnonymousClass.java","openapi/src/com/intellij/psi/PsiArrayAccessExpression.java","openapi/src/com/intellij/psi/PsiArrayInitializerExpression.java","openapi/src/com/intellij/psi/PsiArrayInitializerMemberValue.java","openapi/src/com/intellij/psi/PsiArrayType.java","openapi/src/com/intellij/psi/PsiAspectManagerListener.java","openapi/src/com/intellij/psi/PsiAssertStatement.java","openapi/src/com/intellij/psi/PsiAssignmentExpression.java","openapi/src/com/intellij/psi/PsiBinaryExpression.java","openapi/src/com/intellij/psi/PsiBinaryFile.java","openapi/src/com/intellij/psi/PsiBlockStatement.java","openapi/src/com/intellij/psi/PsiBreakStatement.java","openapi/src/com/intellij/psi/PsiCall.java","openapi/src/com/intellij/psi/PsiCallExpression.java","openapi/src/com/intellij/psi/PsiCapturedWildcardType.java","openapi/src/com/intellij/psi/PsiCatchSection.java","openapi/src/com/intellij/psi/PsiClass.java","openapi/src/com/intellij/psi/PsiClassInitializer.java","openapi/src/com/intellij/psi/PsiClassObjectAccessExpression.java","openapi/src/com/intellij/psi/PsiClassType.java","openapi/src/com/intellij/psi/PsiCodeBlock.java","openapi/src/com/intellij/psi/PsiCodeFragment.java","openapi/src/com/intellij/psi/PsiComment.java","openapi/src/com/intellij/psi/PsiCompiledElement.java","openapi/src/com/intellij/psi/PsiConditionalExpression.java","openapi/src/com/intellij/psi/PsiConstantEvaluationHelper.java","openapi/src/com/intellij/psi/PsiConstructorCall.java","openapi/src/com/intellij/psi/PsiContinueStatement.java","openapi/src/com/intellij/psi/PsiDeclarationStatement.java","openapi/src/com/intellij/psi/PsiDirectory.java","openapi/src/com/intellij/psi/PsiDoWhileStatement.java","openapi/src/com/intellij/psi/PsiDocCommentOwner.java","openapi/src/com/intellij/psi/PsiDocumentManager.java","openapi/src/com/intellij/psi/PsiElement.java","openapi/src/com/intellij/psi/PsiElementFactory.java","openapi/src/com/intellij/psi/PsiElementFinder.java","openapi/src/com/intellij/psi/PsiElementVisitor.java","openapi/src/com/intellij/psi/PsiEllipsisType.java","openapi/src/com/intellij/psi/PsiEmptyStatement.java","openapi/src/com/intellij/psi/PsiEnumConstant.java","openapi/src/com/intellij/psi/PsiEnumConstantInitializer.java","openapi/src/com/intellij/psi/PsiErrorElement.java","openapi/src/com/intellij/psi/PsiExpression.java","openapi/src/com/intellij/psi/PsiExpressionCodeFragment.java","openapi/src/com/intellij/psi/PsiExpressionList.java","openapi/src/com/intellij/psi/PsiExpressionListStatement.java","openapi/src/com/intellij/psi/PsiExpressionStatement.java","openapi/src/com/intellij/psi/PsiExternalChangeAction.java","openapi/src/com/intellij/psi/PsiField.java","openapi/src/com/intellij/psi/PsiFile.java","openapi/src/com/intellij/psi/PsiForStatement.java","openapi/src/com/intellij/psi/PsiForeachStatement.java","openapi/src/com/intellij/psi/PsiIdentifier.java","openapi/src/com/intellij/psi/PsiIfStatement.java","openapi/src/com/intellij/psi/PsiImportHolder.java","openapi/src/com/intellij/psi/PsiImportList.java","openapi/src/com/intellij/psi/PsiImportStatement.java","openapi/src/com/intellij/psi/PsiImportStatementBase.java","openapi/src/com/intellij/psi/PsiImportStaticReferenceElement.java","openapi/src/com/intellij/psi/PsiImportStaticStatement.java","openapi/src/com/intellij/psi/PsiInlineDocTag.java","openapi/src/com/intellij/psi/PsiInstanceOfExpression.java","openapi/src/com/intellij/psi/PsiIntersectionType.java","openapi/src/com/intellij/psi/PsiJavaCodeReferenceElement.java","openapi/src/com/intellij/psi/PsiJavaFile.java","openapi/src/com/intellij/psi/PsiJavaReference.java","openapi/src/com/intellij/psi/PsiJavaToken.java","openapi/src/com/intellij/psi/PsiKeyword.java","openapi/src/com/intellij/psi/PsiLabeledStatement.java","openapi/src/com/intellij/psi/PsiLiteralExpression.java","openapi/src/com/intellij/psi/PsiLocalVariable.java","openapi/src/com/intellij/psi/PsiManager.java","openapi/src/com/intellij/psi/PsiMember.java","openapi/src/com/intellij/psi/PsiMethod.java","openapi/src/com/intellij/psi/PsiMethodCallExpression.java","openapi/src/com/intellij/psi/PsiMigration.java","openapi/src/com/intellij/psi/PsiModifier.java","openapi/src/com/intellij/psi/PsiModifierList.java","openapi/src/com/intellij/psi/PsiModifierListOwner.java","openapi/src/com/intellij/psi/PsiNameHelper.java","openapi/src/com/intellij/psi/PsiNameValuePair.java","openapi/src/com/intellij/psi/PsiNamedElement.java","openapi/src/com/intellij/psi/PsiNewExpression.java","openapi/src/com/intellij/psi/PsiPackage.java","openapi/src/com/intellij/psi/PsiPackageStatement.java","openapi/src/com/intellij/psi/PsiParameter.java","openapi/src/com/intellij/psi/PsiParameterList.java","openapi/src/com/intellij/psi/PsiParenthesizedExpression.java","openapi/src/com/intellij/psi/PsiPlainText.java","openapi/src/com/intellij/psi/PsiPlainTextFile.java","openapi/src/com/intellij/psi/PsiPostfixExpression.java","openapi/src/com/intellij/psi/PsiPrefixExpression.java","openapi/src/com/intellij/psi/PsiPrimitiveType.java","openapi/src/com/intellij/psi/PsiRecursiveElementVisitor.java","openapi/src/com/intellij/psi/PsiReference.java","openapi/src/com/intellij/psi/PsiReferenceExpression.java","openapi/src/com/intellij/psi/PsiReferenceList.java","openapi/src/com/intellij/psi/PsiReferenceParameterList.java","openapi/src/com/intellij/psi/PsiResolveHelper.java","openapi/src/com/intellij/psi/PsiReturnStatement.java","openapi/src/com/intellij/psi/PsiStatement.java","openapi/src/com/intellij/psi/PsiSubstitutor.java","openapi/src/com/intellij/psi/PsiSuperExpression.java","openapi/src/com/intellij/psi/PsiSwitchLabelStatement.java","openapi/src/com/intellij/psi/PsiSwitchStatement.java","openapi/src/com/intellij/psi/PsiSynchronizedStatement.java","openapi/src/com/intellij/psi/PsiThisExpression.java","openapi/src/com/intellij/psi/PsiThrowStatement.java","openapi/src/com/intellij/psi/PsiTreeChangeAdapter.java","openapi/src/com/intellij/psi/PsiTreeChangeEvent.java","openapi/src/com/intellij/psi/PsiTreeChangeListener.java","openapi/src/com/intellij/psi/PsiTryStatement.java","openapi/src/com/intellij/psi/PsiType.java","openapi/src/com/intellij/psi/PsiTypeCastExpression.java","openapi/src/com/intellij/psi/PsiTypeCodeFragment.java","openapi/src/com/intellij/psi/PsiTypeElement.java","openapi/src/com/intellij/psi/PsiTypeParameter.java","openapi/src/com/intellij/psi/PsiTypeParameterList.java","openapi/src/com/intellij/psi/PsiTypeParameterListOwner.java","openapi/src/com/intellij/psi/PsiTypeVisitor.java","openapi/src/com/intellij/psi/PsiVariable.java","openapi/src/com/intellij/psi/PsiWhileStatement.java","openapi/src/com/intellij/psi/PsiWhiteSpace.java","openapi/src/com/intellij/psi/PsiWildcardType.java","openapi/src/com/intellij/psi/ResolveResult.java","openapi/src/com/intellij/psi/SmartPointerManager.java","openapi/src/com/intellij/psi/SmartPsiElementPointer.java","openapi/src/com/intellij/psi/SmartTypePointer.java","openapi/src/com/intellij/psi/StringEscapesTokenTypes.java","openapi/src/com/intellij/psi/TokenType.java","openapi/src/com/intellij/psi/XmlElementVisitor.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleManager.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleScheme.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSchemes.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSettings.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSettingsManager.java","openapi/src/com/intellij/psi/codeStyle/Indent.java","openapi/src/com/intellij/psi/codeStyle/NameUtil.java","openapi/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java","openapi/src/com/intellij/psi/codeStyle/VariableKind.java","openapi/src/com/intellij/psi/html/HtmlTag.java","openapi/src/com/intellij/psi/infos/CandidateInfo.java","openapi/src/com/intellij/psi/infos/CandidatesGroup.java","openapi/src/com/intellij/psi/infos/ClassCandidateInfo.java","openapi/src/com/intellij/psi/infos/MethodCandidateInfo.java","openapi/src/com/intellij/psi/javadoc/JavadocManager.java","openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java","openapi/src/com/intellij/psi/javadoc/PsiDocComment.java","openapi/src/com/intellij/psi/javadoc/PsiDocTag.java","openapi/src/com/intellij/psi/javadoc/PsiDocTagValue.java","openapi/src/com/intellij/psi/javadoc/PsiDocToken.java","openapi/src/com/intellij/psi/jsp/JspFile.java","openapi/src/com/intellij/psi/jsp/JspImplicitVariable.java","openapi/src/com/intellij/psi/meta/PsiMetaData.java","openapi/src/com/intellij/psi/meta/PsiMetaOwner.java","openapi/src/com/intellij/psi/scope/PsiScopeProcessor.java","openapi/src/com/intellij/psi/search/GlobalSearchScope.java","openapi/src/com/intellij/psi/search/IdentifierPosition.java","openapi/src/com/intellij/psi/search/LocalSearchScope.java","openapi/src/com/intellij/psi/search/PsiElementProcessor.java","openapi/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java","openapi/src/com/intellij/psi/search/PsiReferenceProcessor.java","openapi/src/com/intellij/psi/search/PsiSearchHelper.java","openapi/src/com/intellij/psi/search/PsiSearchScopeUtil.java","openapi/src/com/intellij/psi/search/PsiShortNamesCache.java","openapi/src/com/intellij/psi/search/SearchScope.java","openapi/src/com/intellij/psi/search/TodoAttributes.java","openapi/src/com/intellij/psi/search/TodoItem.java","openapi/src/com/intellij/psi/search/TodoPattern.java","openapi/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScope.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScopeManager.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java","openapi/src/com/intellij/psi/search/scope/packageSet/PackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/PackageSetFactory.java","openapi/src/com/intellij/psi/search/scope/packageSet/ParsingException.java","openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java","openapi/src/com/intellij/psi/statistics/StatisticsManager.java","openapi/src/com/intellij/psi/tree/IElementType.java","openapi/src/com/intellij/psi/tree/TokenSet.java","openapi/src/com/intellij/psi/tree/java/IJavaDocElementType.java","openapi/src/com/intellij/psi/tree/java/IJavaElementType.java","openapi/src/com/intellij/psi/tree/java/IKeywordElementType.java","openapi/src/com/intellij/psi/tree/jsp/IJspElementType.java","openapi/src/com/intellij/psi/tree/xml/IDTDElementType.java","openapi/src/com/intellij/psi/tree/xml/IXmlElementType.java","openapi/src/com/intellij/psi/util/ConstantEvaluationOverflowException.java","openapi/src/com/intellij/psi/util/ConstantExpressionUtil.java","openapi/src/com/intellij/psi/util/InheritanceUtil.java","openapi/src/com/intellij/psi/util/IsConstantExpressionVisitor.java","openapi/src/com/intellij/psi/util/MethodSignature.java","openapi/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java","openapi/src/com/intellij/psi/util/MethodSignatureBase.java","openapi/src/com/intellij/psi/util/MethodSignatureHandMade.java","openapi/src/com/intellij/psi/util/MethodSignatureUtil.java","openapi/src/com/intellij/psi/util/PropertyUtil.java","openapi/src/com/intellij/psi/util/PsiElementFilter.java","openapi/src/com/intellij/psi/util/PsiFormatUtil.java","openapi/src/com/intellij/psi/util/PsiMatcher.java","openapi/src/com/intellij/psi/util/PsiMatcherExpression.java","openapi/src/com/intellij/psi/util/PsiMatcherImpl.java","openapi/src/com/intellij/psi/util/PsiModificationTracker.java","openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java","openapi/src/com/intellij/psi/util/PsiTreeUtil.java","openapi/src/com/intellij/psi/util/PsiUtil.java","openapi/src/com/intellij/psi/util/TypeConversionUtil.java","openapi/src/com/intellij/psi/xml/XmlAttlistDecl.java","openapi/src/com/intellij/psi/xml/XmlAttribute.java","openapi/src/com/intellij/psi/xml/XmlAttributeDecl.java","openapi/src/com/intellij/psi/xml/XmlAttributeValue.java","openapi/src/com/intellij/psi/xml/XmlComment.java","openapi/src/com/intellij/psi/xml/XmlDecl.java","openapi/src/com/intellij/psi/xml/XmlDoctype.java","openapi/src/com/intellij/psi/xml/XmlDocument.java","openapi/src/com/intellij/psi/xml/XmlElement.java","openapi/src/com/intellij/psi/xml/XmlElementContentSpec.java","openapi/src/com/intellij/psi/xml/XmlElementDecl.java","openapi/src/com/intellij/psi/xml/XmlEntityDecl.java","openapi/src/com/intellij/psi/xml/XmlEntityRef.java","openapi/src/com/intellij/psi/xml/XmlEnumeratedType.java","openapi/src/com/intellij/psi/xml/XmlFile.java","openapi/src/com/intellij/psi/xml/XmlMarkupDecl.java","openapi/src/com/intellij/psi/xml/XmlNotationDecl.java","openapi/src/com/intellij/psi/xml/XmlProcessingInstruction.java","openapi/src/com/intellij/psi/xml/XmlProlog.java","openapi/src/com/intellij/psi/xml/XmlTag.java","openapi/src/com/intellij/psi/xml/XmlTagChild.java","openapi/src/com/intellij/psi/xml/XmlTagValue.java","openapi/src/com/intellij/psi/xml/XmlText.java","openapi/src/com/intellij/psi/xml/XmlToken.java","openapi/src/com/intellij/psi/xml/XmlTokenType.java","openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java","openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java","openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java","openapi/src/com/intellij/refactoring/MoveDestination.java","openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java","openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java","openapi/src/com/intellij/refactoring/PackageWrapper.java","openapi/src/com/intellij/refactoring/Refactoring.java","openapi/src/com/intellij/refactoring/RefactoringActionHandler.java","openapi/src/com/intellij/refactoring/RefactoringActionHandlerFactory.java","openapi/src/com/intellij/refactoring/RefactoringFactory.java","openapi/src/com/intellij/refactoring/RenameRefactoring.java","openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java","openapi/src/com/intellij/refactoring/SafeDeleteRefactoring.java","openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java","openapi/src/com/intellij/refactoring/TypeCookRefactoring.java","openapi/src/com/intellij/refactoring/listeners/RefactoringElementListener.java","openapi/src/com/intellij/refactoring/listeners/RefactoringElementListenerProvider.java","openapi/src/com/intellij/refactoring/listeners/RefactoringListenerManager.java","openapi/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java","openapi/src/com/intellij/refactoring/util/NonCodeUsageInfo.java","openapi/src/com/intellij/ui/AbstractBox.java","openapi/src/com/intellij/ui/AbstractFieldPanel.java","openapi/src/com/intellij/ui/ColoredListCellRenderer.java","openapi/src/com/intellij/ui/ColoredTreeCellRenderer.java","openapi/src/com/intellij/ui/ComboBoxFieldPanel.java","openapi/src/com/intellij/ui/ComboboxWithBrowseButton.java","openapi/src/com/intellij/ui/CommandButtonGroup.java","openapi/src/com/intellij/ui/DocumentAdapter.java","openapi/src/com/intellij/ui/FieldPanel.java","openapi/src/com/intellij/ui/FilteringListModel.java","openapi/src/com/intellij/ui/GuiUtils.java","openapi/src/com/intellij/ui/IdeBorderFactory.java","openapi/src/com/intellij/ui/InsertPathAction.java","openapi/src/com/intellij/ui/JScrollPane2.java","openapi/src/com/intellij/ui/LayeredIcon.java","openapi/src/com/intellij/ui/ListScrollingUtil.java","openapi/src/com/intellij/ui/ListUtil.java","openapi/src/com/intellij/ui/OptionGroup.java","openapi/src/com/intellij/ui/OrderPanel.java","openapi/src/com/intellij/ui/OrderPanelListener.java","openapi/src/com/intellij/ui/PanelWithButtons.java","openapi/src/com/intellij/ui/PopupHandler.java","openapi/src/com/intellij/ui/RawCommandLineEditor.java","openapi/src/com/intellij/ui/ReorderableListController.java","openapi/src/com/intellij/ui/RoundedLineBorder.java","openapi/src/com/intellij/ui/ScrollPaneFactory.java","openapi/src/com/intellij/ui/SimpleColoredComponent.java","openapi/src/com/intellij/ui/SimpleColoredRenderer.java","openapi/src/com/intellij/ui/SimpleTextAttributes.java","openapi/src/com/intellij/ui/SortedListModel.java","openapi/src/com/intellij/ui/TableCellState.java","openapi/src/com/intellij/ui/TextFieldWithHistory.java","openapi/src/com/intellij/ui/UIHelper.java","openapi/src/com/intellij/ui/UserActivityListener.java","openapi/src/com/intellij/ui/UserActivityWatcher.java","openapi/src/com/intellij/ui/content/Content.java","openapi/src/com/intellij/ui/content/ContentFactory.java","openapi/src/com/intellij/ui/content/ContentManager.java","openapi/src/com/intellij/ui/content/ContentManagerAdapter.java","openapi/src/com/intellij/ui/content/ContentManagerEvent.java","openapi/src/com/intellij/ui/content/ContentManagerListener.java","openapi/src/com/intellij/ui/content/ContentUI.java","openapi/src/com/intellij/ui/dualView/CellWrapper.java","openapi/src/com/intellij/ui/dualView/DualTreeElement.java","openapi/src/com/intellij/ui/dualView/DualView.java","openapi/src/com/intellij/ui/dualView/TreeTableView.java","openapi/src/com/intellij/ui/errorView/ContentManagerProvider.java","openapi/src/com/intellij/ui/errorView/ErrorViewFactory.java","openapi/src/com/intellij/ui/table/BaseTableView.java","openapi/src/com/intellij/ui/table/ItemsProvider.java","openapi/src/com/intellij/ui/table/SelectionProvider.java","openapi/src/com/intellij/ui/table/TableHeaderRenderer.java","openapi/src/com/intellij/ui/table/TableView.java","openapi/src/com/intellij/unscramble/UnscrambleSupport.java","openapi/src/com/intellij/usageView/UsageInfo.java","openapi/src/com/intellij/usageView/UsageTreeColors.java","openapi/src/com/intellij/usageView/UsageTreeColorsScheme.java","openapi/src/com/intellij/usageView/UsageViewDescriptor.java","openapi/src/com/intellij/usageView/UsageViewManager.java","openapi/src/com/intellij/util/Alarm.java","openapi/src/com/intellij/util/CharTable.java","openapi/src/com/intellij/util/CommonProcessors.java","openapi/src/com/intellij/util/EditSourceOnDoubleClickHandler.java","openapi/src/com/intellij/util/EditSourceOnEnterKeyHandler.java","openapi/src/com/intellij/util/EnvironmentUtil.java","openapi/src/com/intellij/util/Generator.java","openapi/src/com/intellij/util/IconUtil.java","openapi/src/com/intellij/util/Icons.java","openapi/src/com/intellij/util/Options.java","openapi/src/com/intellij/util/PathUtil.java","openapi/src/com/intellij/util/PathsList.java","openapi/src/com/intellij/util/Processor.java","openapi/src/com/intellij/util/WeakListener.java","openapi/src/com/intellij/util/concurrency/Mutex.java","openapi/src/com/intellij/util/concurrency/ReadWriteLock.java","openapi/src/com/intellij/util/concurrency/ReentrantLock.java","openapi/src/com/intellij/util/concurrency/ReentrantLock2.java","openapi/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java","openapi/src/com/intellij/util/concurrency/Semaphore.java","openapi/src/com/intellij/util/concurrency/SwingWorker.java","openapi/src/com/intellij/util/concurrency/Sync.java","openapi/src/com/intellij/util/concurrency/Sync2.java","openapi/src/com/intellij/util/concurrency/WorkerThread.java","openapi/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java","openapi/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java","openapi/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java","openapi/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java","openapi/src/com/intellij/util/config/Storage.java","openapi/src/com/intellij/util/io/ReadOnlyAttributeUtil.java","openapi/src/com/intellij/util/ui/ErrorTreeView.java","openapi/src/com/intellij/util/ui/FileLabel.java","openapi/src/com/intellij/util/ui/FilePathSplittingPolicy.java","openapi/src/com/intellij/util/ui/MessageCategory.java","openapi/src/com/intellij/util/ui/SplitByLetterPolicy.java","openapi/src/com/intellij/util/ui/SplitBySeparatorPolicy.java","openapi/src/com/intellij/util/ui/tree/IndexTreePathState.java","openapi/src/com/intellij/util/ui/tree/TreePathState.java","openapi/src/com/intellij/util/ui/tree/TreeUtil.java","openapi/src/com/intellij/vcsUtil/VcsSelection.java","openapi/src/com/intellij/vcsUtil/VcsUtil.java","openapi/src/com/intellij/xml/XmlAttributeDescriptor.java","openapi/src/com/intellij/xml/XmlElementDescriptor.java","openapi/src/com/intellij/xml/XmlNSDescriptor.java","openapi/src/com/intellij/xml/util/XmlTagTextUtil.java","plugins/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java","plugins/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesProvider.java","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight/intention/ConditionalOperatorConvertor.java","plugins/conditionalOperatorConvertor/testSrc/com/intellij/codeInsight/ConditionalToIfTest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/CvsRoot.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IClientEnvironment.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IConnectionStreams.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ICvsCommandStopper.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ICvsRootProvider.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IRequestProcessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/RequestProcessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ResponseService.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ValidRequestsExpectedException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/Entry.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/IAdminReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/IAdminWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/InvalidEntryFormatException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandAbortedException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CvsFile.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CvsFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DefaultEntryParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DefaultFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DirectoryPruner.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/FileObjects.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/FileSystemScanner.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/GlobalOptions.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/ICvsFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/ICvsFilesVisitor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IGlobalOptions.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IOCommandException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IUpdatingCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/KeywordSubstitution.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/LocalFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/Watch.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add/AddCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add/AddParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateLine.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExpandedModules.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/Module.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit/CommitCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit/CommitParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/importcmd/ImportCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/Revision.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/SymbolicName.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove/RemoveCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove/RemoveParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditEditorsMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsFileInfoContainer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/TabStringTokenizer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/UneditCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag/TagCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag/TagParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdatedFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch/WatchCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch/WatchMode.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watchers/WatchersCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/AuthenticationException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/ConnectionSettings.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/IConnection.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/PServerConnection.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/PServerPasswordScrambler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/UnknownUserException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/DualListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/EventManager.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ICvsListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ICvsListenerRegistry.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IDirectoryListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IEntryListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IEventSender.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IFileInfoListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IMessageListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IModuleExpansionListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ITerminationListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/TaggedMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/AbstractFileObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/DirectoryObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileDetails.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileStatus.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ICvsFileSystem.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IFileReadOnlyHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IFileSystem.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ILocalFileReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ILocalFileWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IReaderFactory.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IReceiveTextFilePreprocessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ISendTextFilePreprocessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IWriterFactory.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/OutOfFileSystemException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AbstractInputStreamReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AbstractOutputStreamWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AsciiOutputStreamWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/EncodingException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/IStreamLogger.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/StreamUtilities.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/IProgressViewer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/RangeProgressViewer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/AbstractResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/FileInfoAndDirectoryResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/FileInfoAndMessageResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/DummyRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/FileStateRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/IRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/AbstractFileStateRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/AbstractRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ArgumentRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ArgumentxRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/CaseRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/CommandRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/DirectoryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/EntryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ExpandModulesRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/GlobalOptionRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/GzipStreamRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/IRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/IsModifiedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/KoptRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/LocalDirectoryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ModifiedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/NotifyRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/QuestionableRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/Requests.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ResponseExpectingRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/RootRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/SetRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/StickyRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/UnchangedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/UseUnchangedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ValidRequestsRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ValidResponsesRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/AbstractResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/DefaultResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/IResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/IResponseServices.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ResponseParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ResponseUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ValidRequestsResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/BugLog.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/IIgnoreFileFilter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/IStringPattern.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/SimpleStringPattern.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/ConnectionSettingsImpl.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SmPublicKeyAuthentification.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SolveableAuthenticationException.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SshTypesToUse.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/ClientEnvironment.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminReader.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminUtils.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/DateComparator.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/DummyAdminWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/EntriesDotLog.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/EntriesHandler.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin/AdminCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin/ChangeKeywordSubstCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/impord/CreateModuleCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/CvsFileSystem.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/DummyLocalFileWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/FileSystem.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/LocalFileReader.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/LocalFileWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util/AllIgnoreFileFilter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util/DefaultIgnoreFileFilter.java","plugins/cvs2/source/com/intellij/cvsSupport2/Cvs2Configurable.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsActionPlaces.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsResultEx.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsStandardOperationsProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsStatusEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsUpdateEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsUtil.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsVcs2.java","plugins/cvs2/source/com/intellij/cvsSupport2/UpdateConfigurable.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbstractAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbstractWatchAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbsttractWatchOnOffAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ActionOnSelectedElement.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AddFileOrDirectoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AnnotateToggleAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AsbtractActionFromEditGroup.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/BranchAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CheckoutAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CheckoutFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ConfigureCvsRootsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CreateTagAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/Cvs2Group.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CvsGlobalAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/DeleteTagAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/EditAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/GetFileFromRepositoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/GlobalSettingsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/IgnoreFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ImportAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RemoveLocallyDeletedFilesAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RemoveLocallyFileOrDirectoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RestoreFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/UneditAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/UnmarkAddedAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ViewEditorsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ViewWatchersAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchAddAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchOffAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchOnAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchRemoveAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/actionVisibility/CvsActionVisibility.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CashedCvsContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContextAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsLightweightFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateByBranchUpdateSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateSettingsOnCvsConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/AddHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsEntriesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsStorageComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsStorageSupportingDeletionComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/DeleteHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/DeletedCVSDirectoryStorage.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/AdditionalOptionsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsCheckinEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsDiffColors.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsRollbacker.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/DirectoryContent.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/VirtualFileEntry.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/AbstractConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsApplicationLevelConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsRootConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/DateOrRevisionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ExtConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ImportConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/LocalSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ProxySettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/ConfigureCvsGlobalSettingsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsListCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsRootAsStringConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsRootFieldByFieldConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/GlobalCvsSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/SelectCvsConfgurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/SelectCvsConfigurationDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ConnectionOnProcess.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ConnectionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsMethod.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootData.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootOnEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootOnFileSystem.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootParser.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/RootFormatter.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/SelfTestingConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/SelfTestingConnectionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtLoginProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/LocalConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/LocalConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/ui/LocalConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerCvsSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerLoginProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerLoginProviderImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/ui/PServerSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/SSHPasswordProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/SshConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui/SshConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui/SshPasswordDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ui/ProxySettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/consoleView/EditorAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CheckoutHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/Cvs2Renderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsElementFactory.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsModule.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsTree.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsTreeModel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/FolderDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/GetContentCallback.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/LoginAbortedException.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ModuleDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/RemoteResourceDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/ModalityContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoreFileFilter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoreFileFilterBasedOnCvsEntriesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoredFilesInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoredFilesInfoImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/UserDirIgnores.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AbstractCvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AllFilesInProject.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AnyProcessedFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CheckoutHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CommandCvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsMessagePattern.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsMessagesConsole.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsUpdatePolicy.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/FileSetToBeUpdated.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/SelectedFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/UpdateHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CompositeOperaton.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CreateFileObjects.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsExecutionEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsOperationOnFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/FindAllRoots.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/LocalPathIndifferentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/LocalPathIndifferentOperationHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/PostCvsActivity.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/ReceivedFileProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/RepositoryModificationOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/RepositoryPathProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/UpdatedFilesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddFileOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddedFileInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AbstractAddFileConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AbstractAddOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddDirectoryConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddFileConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddMultiplyFilesOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddOneFileOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddedFileCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate/AnnotateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate/Annotation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutAdminReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFileByRevisionOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFileOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui/CheckoutFileDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui/FileCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCommit/CommitFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContent.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetFileContentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditorInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditorsOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/UneditOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditCvsConfigurationFieldByFieldDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors/ErrorMessagesProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors/ErrorProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport/ImportDetails.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport/ImportOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/LocalPathIndifferentLogOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/LogOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/RlogCommand.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsCompositeListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsListenerWithProgress.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsListenersCollection.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesTranslator.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/FileMessage.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/MessageEvent.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsRemove/RemoveFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/BranchOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/BranchesProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/RTagOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/RtagCommand.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnVirtualFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/CreateTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/CvsTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/DeleteTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/SelectTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/TagNameFieldOwner.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/TagsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/MergedWithConflictProjectOrModuleFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/UpdateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/UpdateReceivedFileProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui/CorruptedProjectFilesDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui/UpdateOptionsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatchOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatcherInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatchersOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui/WatcherDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui/WatchersPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/CommandWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDate.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/CalendarView.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/DateOrRevisionOrTagSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/IntegerSpinnerModel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderForLightFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderOnCache.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderOnStoredRepositoryPath.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminWriterOnCache.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminWriterStoringRepositoryPath.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/ConstantLocalFileReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/DeafAdminReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/DeafAdminWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses/CvsEntriesListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses/CvsStatusProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CannotFindCvsRootException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CvsException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CvsProcessException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/ErrorRegistry.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/InvalidModuleDescriptionException.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/ComparableVcsRevisionOnOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsFileRevision.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsFileRevisionImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsHistoryProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsRevisionNumber.java","plugins/cvs2/source/com/intellij/cvsSupport2/impl/CvsServicesImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/impl/ModuleChooser.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/CvsCommandStopper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/FileReadOnlyHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/ProjectContentInfoProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/DeafLocalFileWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/InputStreamWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/LocalFileReaderBasedOnVFS.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/OutputStreamWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReadThread.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReadWriteStatistics.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReceiveTextFilePreprocessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/SendTextFilePreprocessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/StoringLineSeparatorsLocalFileWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/StreamLogger.java","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution/KeywordSubstitutionListWithSelection.java","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution/KeywordSubstitutionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/AbstractListCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/ChangeKeywordSubstitutionPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsRootChangeListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsTabbedWindow.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/KeywordSubstitutionComboBoxWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/Options.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/PasswordPromptDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/RestoreDirectoriesConfirmationDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/SelectFileVersionDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/SelectFromListDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/CvsWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectCVSConfigurationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/WizardStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutFolderToTheSameFolder.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutToTheDirectoryWithModuleName.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CreateDirectoryForFolderStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/SimpleCheckoutStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/CvsFieldValidator.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/FileExtension.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportSettingsStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportTree.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/SelectImportLocationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/updateinfo/UpdatedFilesProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/util/CvsFileUtil.java","plugins/cvs2/source/com/intellij/cvsSupport2/util/CvsVfsUtil.java","plugins/debuggerCommonViews/src/actions/ShowAllAs.java","plugins/debuggerCommonViews/src/actions/ShowAllAsDecimal.java","plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java","pom/src/com/intellij/pom/PomElement.java","pom/src/com/intellij/pom/PomModel.java","pom/src/com/intellij/pom/PomModelAspect.java","pom/src/com/intellij/pom/PomPresentation.java","pom/src/com/intellij/pom/PomTransaction.java","pom/src/com/intellij/pom/Presentable.java","pom/src/com/intellij/pom/event/PomChangeSet.java","pom/src/com/intellij/pom/event/PomModelEvent.java","pom/src/com/intellij/pom/event/PomModelListener.java","runtimesource/FormPreviewFrame.java","runtimesource/com/intellij/rt/ant/execution/AntMain2.java","runtimesource/com/intellij/rt/ant/execution/IdeaAntLogger2.java","runtimesource/com/intellij/rt/ant/execution/IdeaInputHandler.java","runtimesource/com/intellij/rt/ant/execution/PacketFactory.java","runtimesource/com/intellij/rt/compiler/JavacRunner.java","runtimesource/com/intellij/rt/debugger/BatchEvaluatorServer.java","runtimesource/com/intellij/rt/execution/application/AppMain.java","runtimesource/com/intellij/rt/execution/application/MainAppClassLoader.java","runtimesource/com/intellij/rt/execution/junit/IdeaTestRunner.java","runtimesource/com/intellij/rt/execution/junit/TestAllInPackage2.java","runtimesource/com/intellij/rt/execution/junit/TestRunnerUtil.java","runtimesource/com/intellij/rt/execution/junit2/ComparisonDetailsExtractor.java","runtimesource/com/intellij/rt/execution/junit2/DeafStream.java","runtimesource/com/intellij/rt/execution/junit2/ExceptionPacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/FileComparisonFailure.java","runtimesource/com/intellij/rt/execution/junit2/JUnitStarter.java","runtimesource/com/intellij/rt/execution/junit2/KnownException.java","runtimesource/com/intellij/rt/execution/junit2/PacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/RunOnce.java","runtimesource/com/intellij/rt/execution/junit2/TestMeter.java","runtimesource/com/intellij/rt/execution/junit2/TestResultsSender.java","runtimesource/com/intellij/rt/execution/junit2/TreeSender.java","runtimesource/com/intellij/rt/execution/junit2/segments/EchoOutputStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/OutputObjectRegistry.java","runtimesource/com/intellij/rt/execution/junit2/segments/OutputObjectRegistryImpl.java","runtimesource/com/intellij/rt/execution/junit2/segments/Packet.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketProcessor.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketProcessors.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketWriter.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfDelimiters.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfKnownObjects.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfTestTypes.java","runtimesource/com/intellij/rt/execution/junit2/segments/SegmentedOutputStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/SegmentedStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/TraceFilter.java","runtimesource/com/intellij/rt/execution/junit2/states/PoolOfTestStates.java","source/com/intellij/analysis/AnalysisScope.java","source/com/intellij/analysis/BaseAnalysisAction.java","source/com/intellij/application/options/CodeCompletionOptions.java","source/com/intellij/application/options/CodeCompletionPanel.java","source/com/intellij/application/options/CodeStyleBlankLinesConfigurable.java","source/com/intellij/application/options/CodeStyleBlankLinesPanel.java","source/com/intellij/application/options/CodeStyleGeneralConfigurable.java","source/com/intellij/application/options/CodeStyleImportsConfigurable.java","source/com/intellij/application/options/CodeStyleImportsPanel.java","source/com/intellij/application/options/CodeStyleIndentAndBracesConfigurable.java","source/com/intellij/application/options/CodeStyleIndentAndBracesPanel.java","source/com/intellij/application/options/CodeStyleSchemesConfigurable.java","source/com/intellij/application/options/CodeStyleSpacesConfigurable.java","source/com/intellij/application/options/CodeStyleSpacesPanel.java","source/com/intellij/application/options/CodeStyleXmlConfigurable.java","source/com/intellij/application/options/CodeStyleXmlPanel.java","source/com/intellij/application/options/EditorOptions.java","source/com/intellij/application/options/EditorOptionsPanel.java","source/com/intellij/application/options/ErrorHighlightingPanel.java","source/com/intellij/application/options/JavaDocFormattingPanel.java","source/com/intellij/application/options/JavadocFormatConfigurable.java","source/com/intellij/application/options/OptionTableWithPreviewPanel.java","source/com/intellij/application/options/OptionTreeWithPreviewPanel.java","source/com/intellij/application/options/PathMacros.java","source/com/intellij/application/options/ReplacePathToMacroMap.java","source/com/intellij/application/options/SaveSchemeDialog.java","source/com/intellij/application/options/SelectFontDialog.java","source/com/intellij/application/options/WrappingConfigurable.java","source/com/intellij/application/options/WrappingPanel.java","source/com/intellij/application/options/colors/ClickNavigator.java","source/com/intellij/application/options/colors/ColorAndFontDescription.java","source/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java","source/com/intellij/application/options/colors/ColorAndFontOptions.java","source/com/intellij/application/options/colors/EditorSchemeAttributeDescriptor.java","source/com/intellij/application/options/colors/TailPanel.java","source/com/intellij/application/options/colors/TextAttributesDescription.java","source/com/intellij/application/options/colors/highlighting/HighlightData.java","source/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java","source/com/intellij/application/options/pathMacros/PathMacroConfigurable.java","source/com/intellij/application/options/pathMacros/PathMacroEditor.java","source/com/intellij/application/options/pathMacros/PathMacroListEditor.java","source/com/intellij/application/options/pathMacros/PathMacroTable.java","source/com/intellij/codeEditor/printing/ExportToHTMLAction.java","source/com/intellij/codeEditor/printing/ExportToHTMLDialog.java","source/com/intellij/codeEditor/printing/ExportToHTMLManager.java","source/com/intellij/codeEditor/printing/ExportToHTMLSettings.java","source/com/intellij/codeEditor/printing/HTMLTextPainter.java","source/com/intellij/codeEditor/printing/MultiFilePainter.java","source/com/intellij/codeEditor/printing/PageSizes.java","source/com/intellij/codeEditor/printing/PrintAction.java","source/com/intellij/codeEditor/printing/PrintDialog.java","source/com/intellij/codeEditor/printing/PrintManager.java","source/com/intellij/codeEditor/printing/PrintSettings.java","source/com/intellij/codeEditor/printing/TextPainter.java","source/com/intellij/codeFormatting/general/FormatterUtil.java","source/com/intellij/codeInsight/AutoPopupController.java","source/com/intellij/codeInsight/ChangeContextUtil.java","source/com/intellij/codeInsight/CodeInsightActionHandler.java","source/com/intellij/codeInsight/CodeInsightColors.java","source/com/intellij/codeInsight/CodeInsightSettings.java","source/com/intellij/codeInsight/CodeInsightUtil.java","source/com/intellij/codeInsight/ExceptionUtil.java","source/com/intellij/codeInsight/ExpectedTypeInfoImpl.java","source/com/intellij/codeInsight/ExpectedTypeUtil.java","source/com/intellij/codeInsight/PopupActionChooser.java","source/com/intellij/codeInsight/TailType.java","source/com/intellij/codeInsight/TargetElementUtil.java","source/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java","source/com/intellij/codeInsight/actions/BaseCodeInsightAction.java","source/com/intellij/codeInsight/actions/GenerateDTDAction.java","source/com/intellij/codeInsight/actions/LayoutCodeDialog.java","source/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java","source/com/intellij/codeInsight/actions/OptimizeImportsAction.java","source/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java","source/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java","source/com/intellij/codeInsight/actions/ReformatCodeAction.java","source/com/intellij/codeInsight/actions/ReformatCodeProcessor.java","source/com/intellij/codeInsight/completion/BasicInsertHandler.java","source/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java","source/com/intellij/codeInsight/completion/CompletionContext.java","source/com/intellij/codeInsight/completion/CompletionData.java","source/com/intellij/codeInsight/completion/CompletionPreferencePolicy.java","source/com/intellij/codeInsight/completion/CompletionUtil.java","source/com/intellij/codeInsight/completion/CompletionVariant.java","source/com/intellij/codeInsight/completion/DefaultCharFilter.java","source/com/intellij/codeInsight/completion/DefaultInsertHandler.java","source/com/intellij/codeInsight/completion/DocAnalyzer.java","source/com/intellij/codeInsight/completion/DotAutoLookupHandler.java","source/com/intellij/codeInsight/completion/HtmlCompletionData.java","source/com/intellij/codeInsight/completion/InsertHandler.java","source/com/intellij/codeInsight/completion/Java15CompletionData.java","source/com/intellij/codeInsight/completion/JavaCompletionData.java","source/com/intellij/codeInsight/completion/JavaDocCompletionData.java","source/com/intellij/codeInsight/completion/JavadocAutoLookupHandler.java","source/com/intellij/codeInsight/completion/KeywordChooser.java","source/com/intellij/codeInsight/completion/LookupHandler.java","source/com/intellij/codeInsight/completion/ModifierChooser.java","source/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java","source/com/intellij/codeInsight/completion/XHtmlCompletionData.java","source/com/intellij/codeInsight/completion/XmlAutoLookupHandler.java","source/com/intellij/codeInsight/completion/XmlCharFilter.java","source/com/intellij/codeInsight/completion/XmlCompletionData.java","source/com/intellij/codeInsight/completion/actions/ClassNameCompletionAction.java","source/com/intellij/codeInsight/completion/actions/CodeCompletionAction.java","source/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java","source/com/intellij/codeInsight/completion/actions/SmartCodeCompletionAction.java","source/com/intellij/codeInsight/completion/proc/VariablesProcessor.java","source/com/intellij/codeInsight/completion/scope/CompletionElement.java","source/com/intellij/codeInsight/completion/scope/CompletionProcessor.java","source/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java","source/com/intellij/codeInsight/daemon/DaemonCodeAnalyzerSettings.java","source/com/intellij/codeInsight/daemon/HighlightDisplayKey.java","source/com/intellij/codeInsight/daemon/InspectionProfileConvertor.java","source/com/intellij/codeInsight/daemon/QuickFixProvider.java","source/com/intellij/codeInsight/daemon/impl/AddNoInspectionCommentAction.java","source/com/intellij/codeInsight/daemon/impl/AddNoInspectionDocTagAction.java","source/com/intellij/codeInsight/daemon/impl/CodeFoldingPass.java","source/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java","source/com/intellij/codeInsight/daemon/impl/DaemonTooltipUtil.java","source/com/intellij/codeInsight/daemon/impl/EditorTracker.java","source/com/intellij/codeInsight/daemon/impl/EditorTrackerListener.java","source/com/intellij/codeInsight/daemon/impl/ErrorStripeHandler.java","source/com/intellij/codeInsight/daemon/impl/FileStatusMap.java","source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/GotoNextErrorHandler.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfo.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoComposite.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoFilter.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoFilterImpl.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java","source/com/intellij/codeInsight/daemon/impl/HighlightVisitor.java","source/com/intellij/codeInsight/daemon/impl/LineMarkerInfo.java","source/com/intellij/codeInsight/daemon/impl/LineMarkerNavigator.java","source/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java","source/com/intellij/codeInsight/daemon/impl/OverridenMarkersPass.java","source/com/intellij/codeInsight/daemon/impl/Pass.java","source/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java","source/com/intellij/codeInsight/daemon/impl/RefCountHolder.java","source/com/intellij/codeInsight/daemon/impl/RefreshStatusRenderer.java","source/com/intellij/codeInsight/daemon/impl/ShowErrorDescriptionHandler.java","source/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java","source/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java","source/com/intellij/codeInsight/daemon/impl/TextEditorBackgroundHighlighter.java","source/com/intellij/codeInsight/daemon/impl/TextEditorHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java","source/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java","source/com/intellij/codeInsight/daemon/impl/actions/GotoNextErrorAction.java","source/com/intellij/codeInsight/daemon/impl/actions/GotoPreviousErrorAction.java","source/com/intellij/codeInsight/daemon/impl/actions/ShowErrorDescriptionAction.java","source/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/ClassUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java","source/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddDefaultConstructorFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToThrowsAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodBodyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AdjustPackageNameFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/BringVariableIntoScopeAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CastConstructorParametersFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodParametersFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstantFieldFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorMatchingSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateVarFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeferFinalAssignmentFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMethodBodyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java","source/com/intellij/codeInsight/daemon/impl/quickfix/EnableOptimizeImportsOnTheFlyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ExtendsListFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GuessTypeParameters.java","source/com/intellij/codeInsight/daemon/impl/quickfix/IgnoreExtResourceAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/InsertNewFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/InsertSuperFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeClassInterfaceFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeMethodConstructorFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeVarargParameterLastFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodParameterFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveBoundClassToFrontFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToSeparateFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveToPackageFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/OptimizeImportsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveNewQualifierFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantElseAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedParameterFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenamePublicClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java","source/com/intellij/codeInsight/editorActions/BackspaceHandler.java","source/com/intellij/codeInsight/editorActions/CodeBlockEndAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockEndWithSelectionAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockStartAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockStartWithSelectionAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockUtil.java","source/com/intellij/codeInsight/editorActions/CopyHandler.java","source/com/intellij/codeInsight/editorActions/CutHandler.java","source/com/intellij/codeInsight/editorActions/EndHandler.java","source/com/intellij/codeInsight/editorActions/EnterHandler.java","source/com/intellij/codeInsight/editorActions/HtmlSelectioner.java","source/com/intellij/codeInsight/editorActions/JoinLinesHandler.java","source/com/intellij/codeInsight/editorActions/PasteHandler.java","source/com/intellij/codeInsight/editorActions/RestoreReferencesDialog.java","source/com/intellij/codeInsight/editorActions/SelectWordHandler.java","source/com/intellij/codeInsight/editorActions/SelectWordUtil.java","source/com/intellij/codeInsight/editorActions/TextBlockTransferable.java","source/com/intellij/codeInsight/editorActions/TypedHandler.java","source/com/intellij/codeInsight/editorActions/UnSelectWordHandler.java","source/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/BreakingControlFlowEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/CompletionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/EnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingForBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingWhileBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java","source/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java","source/com/intellij/codeInsight/folding/CodeFoldingManager.java","source/com/intellij/codeInsight/folding/CodeFoldingState.java","source/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java","source/com/intellij/codeInsight/folding/impl/CodeFoldingSettings.java","source/com/intellij/codeInsight/folding/impl/CollapseAllRegionsHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseExpandJavadocsHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseRegionHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java","source/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java","source/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java","source/com/intellij/codeInsight/folding/impl/ExpandAllRegionsHandler.java","source/com/intellij/codeInsight/folding/impl/ExpandRegionHandler.java","source/com/intellij/codeInsight/folding/impl/FoldingPolicy.java","source/com/intellij/codeInsight/folding/impl/FoldingUpdate.java","source/com/intellij/codeInsight/folding/impl/FoldingUtil.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseAllRegionsAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseJavadocsAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseRegionAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandAllRegionsAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandJavadocsAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandRegionAction.java","source/com/intellij/codeInsight/folding/impl/actions/FoldingGroup.java","source/com/intellij/codeInsight/generation/AutoIndentLinesHandler.java","source/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java","source/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java","source/com/intellij/codeInsight/generation/GenerateConstructorHandler.java","source/com/intellij/codeInsight/generation/GenerateDelegateHandler.java","source/com/intellij/codeInsight/generation/GenerateEqualsHandler.java","source/com/intellij/codeInsight/generation/GenerateEqualsHelper.java","source/com/intellij/codeInsight/generation/GenerateGetterAndSetterHandler.java","source/com/intellij/codeInsight/generation/GenerateGetterHandler.java","source/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java","source/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java","source/com/intellij/codeInsight/generation/GenerateMembersUtil.java","source/com/intellij/codeInsight/generation/GenerateSetterHandler.java","source/com/intellij/codeInsight/generation/ImplementMethodsHandler.java","source/com/intellij/codeInsight/generation/OverrideImplementUtil.java","source/com/intellij/codeInsight/generation/OverrideMethodsHandler.java","source/com/intellij/codeInsight/generation/TemplateGenerationInfo.java","source/com/intellij/codeInsight/generation/actions/AutoIndentLinesAction.java","source/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java","source/com/intellij/codeInsight/generation/actions/CommentByBlockCommentAction.java","source/com/intellij/codeInsight/generation/actions/CommentByLineCommentAction.java","source/com/intellij/codeInsight/generation/actions/GenerateAction.java","source/com/intellij/codeInsight/generation/actions/GenerateConstructorAction.java","source/com/intellij/codeInsight/generation/actions/GenerateDelegateAction.java","source/com/intellij/codeInsight/generation/actions/GenerateEqualsAction.java","source/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java","source/com/intellij/codeInsight/generation/actions/ImplementMethodsAction.java","source/com/intellij/codeInsight/generation/actions/OverrideMethodsAction.java","source/com/intellij/codeInsight/generation/actions/SurroundWithAction.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundStatementsHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithBlockHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithCastHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithDoWhileHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithForHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfElseExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfElseHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithNotHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithNotInstanceofHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithParenthesesHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithRunnableHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithSynchronizedHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryCatchFinallyHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryCatchHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryFinallyHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithUtil.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithWhileHandler.java","source/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java","source/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java","source/com/intellij/codeInsight/guess/GuessManager.java","source/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java","source/com/intellij/codeInsight/guess/impl/MethodPattern.java","source/com/intellij/codeInsight/guess/impl/MethodPatternMap.java","source/com/intellij/codeInsight/highlighting/BraceHighlighter.java","source/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java","source/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java","source/com/intellij/codeInsight/highlighting/HighlightHandlerBase.java","source/com/intellij/codeInsight/highlighting/HighlightManagerImpl.java","source/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java","source/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java","source/com/intellij/codeInsight/hint/EditorFragmentComponent.java","source/com/intellij/codeInsight/hint/HintManager.java","source/com/intellij/codeInsight/hint/HintUtil.java","source/com/intellij/codeInsight/hint/ImplementationViewComponent.java","source/com/intellij/codeInsight/hint/ParameterInfoComponent.java","source/com/intellij/codeInsight/hint/ParameterInfoController.java","source/com/intellij/codeInsight/hint/PrevNextParameterHandler.java","source/com/intellij/codeInsight/hint/QuestionAction.java","source/com/intellij/codeInsight/hint/ShowContainerInfoHandler.java","source/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java","source/com/intellij/codeInsight/hint/TooltipController.java","source/com/intellij/codeInsight/hint/TooltipGroup.java","source/com/intellij/codeInsight/hint/actions/NextParameterAction.java","source/com/intellij/codeInsight/hint/actions/PrevParameterAction.java","source/com/intellij/codeInsight/hint/actions/ShowContainerInfoAction.java","source/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java","source/com/intellij/codeInsight/hint/actions/ShowParameterInfoAction.java","source/com/intellij/codeInsight/intention/actions/ShowIntentionActionsAction.java","source/com/intellij/codeInsight/intention/impl/AddOnDemandStaticImportAction.java","source/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java","source/com/intellij/codeInsight/intention/impl/AddSingleMemberStaticImportAction.java","source/com/intellij/codeInsight/intention/impl/BaseIntentionAction.java","source/com/intellij/codeInsight/intention/impl/CreateClassDialog.java","source/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java","source/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractClassAction.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodAction.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java","source/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java","source/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java","source/com/intellij/codeInsight/intention/impl/MakeTypeGeneric.java","source/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java","source/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java","source/com/intellij/codeInsight/intention/impl/SplitIfAction.java","source/com/intellij/codeInsight/intention/impl/TypeExpression.java","source/com/intellij/codeInsight/intention/impl/config/IntentionActionMetaData.java","source/com/intellij/codeInsight/intention/impl/config/IntentionDescriptionPanel.java","source/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java","source/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java","source/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java", "source/com/intellij/compiler/actions/CompileDirtyAction.java", "source/com/intellij/compiler/CompilerManagerImpl.java", "source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java"],"renamedFilesHint":{},"repositoryDirectoriesBefore":[],"repositoryDirectoriesCurrent":["UsageView/testSource/com","plugins/cvs2/source/com/intellij","plugins","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution","openapi/src/com/intellij/codeInsight","pom/src/com/intellij","doc/openapi/examples/vfs/src/com/intellij/openapi","openapi/src/com/intellij/debugger/engine/jdi","source/com/intellij/codeInsight/guess/impl","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/impord","forms_rt","UsageView/src/com/intellij/usages/rules","UIDesignerCore","doc/openapi/examples/toolWindow/src","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving","plugins/cvs2/source/com/intellij/cvsSupport2/updateinfo","source/com","openapi/src/com/intellij/psi/tree","plugins/cvs2/javacvs-src/org/netbeans/lib","openapi/src/com/intellij/openapi/localVcs","runtimesource/com/intellij","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command","source/com/intellij/codeInsight/editorActions/smartEnter","openapi/src/com/intellij/openapi/vcs/vfs","openapi/src/com/intellij/ui/dualView","openapi/src/com/intellij/debugger/engine/evaluation","openapi/src/com/intellij/navigation","openapi/src/com/intellij/openapi/fileEditor","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui","source/com/intellij/codeInsight/completion","openapi/src/com/intellij/openapi/ide","source/com/intellij","source/com/intellij/codeInsight/editorActions","openapi/src/com/intellij/openapi/actionSystem","openapi/src/com/intellij/openapi/cvsIntegration","openapi/src/com/intellij/ui/table","openapi/src/com/intellij/openapi","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs","openapi/src/com/intellij/usageView","openapi/src/com/intellij/openapi/editor/markup","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls","openapi/src/com/intellij/openapi/roots","openapi/src/com/intellij/openapi/fileTypes","doc/openapi/examples/plugin/src/com/intellij","source/com/intellij/codeEditor","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui","openapi/src/com/intellij/openapi/editor/colors","openapi/src/com/intellij/debugger/engine","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui","openapi/src/com/intellij/find","openapi/src/com/intellij/vcsUtil","plugins/conditionalOperatorConvertor/source/com","openapi/src/com/intellij/openapi/diagnostic","source/com/intellij/codeInsight/folding/impl/actions","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient","plugins/conditionalOperatorConvertor","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject","openapi/src/com/intellij/psi/jsp","openapi/src/com/intellij/util/ui","UsageView/src","plugins/conditionalOperatorConvertor/testSrc/com/intellij","doc/openapi/examples/actions/src/com/intellij","UIDesignerCore/testSource/com/intellij/uiDesigner/core","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses","openapi/src/com/intellij/debugger/requests","runtimesource/com/intellij/rt/execution/junit2","source/com/intellij/codeInsight/hint","openapi/src/com/intellij/openapi/module","UsageView/src/com","doc/openapi/examples","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ui","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight","plugins/conditionalOperatorConvertor/testSrc/com","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event","openapi/src/com/intellij/openapi/vcs/checkin","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io","openapi/src/com/intellij/openapi/help","openapi/src/com/intellij/psi/search","openapi/src/com","openapi/src/com/intellij/openapi/editor/actionSystem","openapi/src/com/intellij/debugger/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request","forms_rt/src","openapi/src/com/intellij/openapi/progress","openapi/src/com/intellij/psi/html","plugins/cvs2/source/com/intellij/cvsSupport2/connections","openapi/src/com/intellij/psi/tree/java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/ui","source/com/intellij/codeInsight/folding","openapi/src/com/intellij/psi","runtimesource/com/intellij/rt/execution/junit","doc/openapi/examples/toolWindow","openapi/src/com/intellij/j2ee/ui","plugins/cvs2/source/com/intellij/cvsSupport2/consoleView","doc/openapi/examples/vfs/src","openapi/src/com/intellij/ide","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh","openapi/src/com/intellij/openapi/vcs/ui","openapi/src/com/intellij/openapi/application","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag","plugins/comparingReferences/source/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate","doc/openapi/examples/toolWindow/src/com","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate","pom/src/com/intellij/pom","javac2/src/com/intellij/uiDesigner","source/com/intellij/codeInsight/actions","runtimesource/com","source/com/intellij/codeFormatting/general","javac2/src/com/intellij/uiDesigner/ant","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut","openapi/src/com/intellij/codeHighlighting","plugins/cvs2/source","source/com/intellij/codeInsight/intention","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local","forms_rt/src/com/intellij/uiDesigner","openapi/src/com/intellij/pom/java","openapi/src/com/intellij/ide/util/treeView/smartTree","openapi/src/com/intellij/xml","UsageView/testSource","doc/openapi/examples/toolWindow/src/com/intellij/openapi","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport","plugins/conditionalOperatorConvertor/source","openapi/src/com/intellij/openapi/roots/libraries","source/com/intellij/codeInsight/completion/actions","doc","openapi/src/com/intellij/openapi/roots/ui","openapi/src/com/intellij/psi/statistics","openapi/src/com/intellij/openapi/roots/ui/configuration","source/com/intellij/application/options/colors","openapi/src/com/intellij/unscramble","openapi/src/com/intellij/openapi/vcs/update","openapi/src/com/intellij/ui","runtimesource/com/intellij/rt/debugger","source/com/intellij/codeInsight/intention/actions","UIDesignerCore/testSource/com/intellij/uiDesigner","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log","plugins/cvs2/javacvs-src","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsRemove","runtimesource/com/intellij/rt/ant","runtimesource/com/intellij/rt","UsageView/src/com/intellij/usages/impl","openapi/src/com/intellij/psi/codeStyle","openapi/src/com/intellij/ui/errorView","openapi/src/com/intellij/openapi/projectRoots","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui","plugins/cvs2/smartcvs-src","forms_rt/src/com/intellij/uiDesigner/core","doc/openapi/examples/plugin/src/com","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update","source/com/intellij/application/options","openapi/src/com/intellij/psi/xml","doc/openapi/examples/actions","UIDesignerCore/src","javac2/src","openapi/src/com/intellij/ide/projectView","UsageView/testSource/com/intellij/usages/impl","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout","openapi/src/com/intellij/psi/meta","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd","openapi/src/com/intellij/util/concurrency/readwrite","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending","runtimesource/com/intellij/rt/execution/junit2/segments","source/com/intellij/codeEditor/printing","source/com/intellij/codeInsight","plugins/cvs2/source/com/intellij/cvsSupport2/actions/actionVisibility","source/com/intellij/application/options/colors/highlighting","openapi/src/com/intellij/openapi/startup","UIDesignerCore/src/com/intellij/uiDesigner/compiler","plugins/cvs2/source/com/intellij/cvsSupport2/history","openapi/src/com/intellij/openapi/wm","plugins/cvs2/javacvs-src/org/netbeans","openapi/src/com/intellij/util/config","plugins/cvs2/maverick_utils/com","openapi/src/com/intellij/openapi/editor","pom/src/com/intellij/pom/event","UIDesignerCore/src/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts","doc/openapi/examples/vfs","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCommit","doc/openapi/examples/actions/src","UsageView/src/com/intellij/usages/impl/rules","plugins/cvs2/source/com/intellij/cvsSupport2","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection","plugins/cvs2/source/com/intellij/cvsSupport2/actions","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages","openapi/src/com/intellij/ide/util/projectWizard","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch","plugins/cvs2/source/com/intellij/cvsSupport2/impl","openapi/src/com/intellij/openapi/vfs/pointers","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response","plugins/cvs2/source/com/intellij/cvsSupport2/config","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight/intention","UsageView/src/com/intellij","plugins/cvs2/smartcvs-src/org/netbeans","runtimesource/com/intellij/rt/execution/application","source/com/intellij/codeInsight/hint/actions","doc/openapi/examples/vfs/src/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui","openapi/src/com/intellij/psi/javadoc","openapi/src/com/intellij/openapi/diff","openapi/src/com/intellij/openapi/util","UIDesignerCore/testSource/com/intellij","plugins/comparingReferences/source","plugins/cvs2/smartcvs-src/org","openapi/src/com/intellij/codeInspection","doc/openapi/examples/toolWindow/src/com/intellij/openapi/samples","openapi/src/com/intellij/util/io","UsageView/testSource/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision","openapi/src/com/intellij/execution","doc/openapi/examples/actions/src/com/intellij/openapi","forms_rt/src/com","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/importcmd","plugins/comparingReferences","openapi/src/com/intellij/execution/configurations","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ui","source/com/intellij/codeInsight/guess","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog","source/com/intellij/codeInsight/daemon/impl/actions","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io","openapi/src/com/intellij/debugger/engine/managerThread","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout","openapi/src/com/intellij/openapi/compiler","pom","UsageView","source/com/intellij/codeInsight/generation/surroundWith","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit","source/com/intellij/codeInsight/generation/actions","plugins/cvs2/source/com","openapi/src/com/intellij/ide/actions","openapi/src/com/intellij/j2ee/module","openapi/src/com/intellij/openapi/ui","openapi/src/com/intellij/j2ee/make","UIDesignerCore/testSource","plugins/cvs2/source/com/intellij/cvsSupport2/ui","source/com/intellij/codeFormatting","openapi/src/com/intellij/codeInsight/highlighting","plugins/cvs2","plugins/debuggerCommonViews/src","openapi/src/com/intellij/refactoring","openapi/src/com/intellij/openapi/components","source/com/intellij/codeInsight/daemon/impl/quickfix","plugins/debuggerCommonViews/src/actions","UIDesignerCore/src/com/intellij/uiDesigner/lw","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util","openapi/src/com/intellij/execution/runners","source/com/intellij/analysis","openapi/src/com/intellij/openapi/actionSystem/ex","openapi/src/com/intellij/j2ee","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status","source","doc/openapi/examples/actions/src/com/intellij/openapi/samples","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util","openapi/src/com/intellij/j2ee/j2eeDom","openapi/src/com/intellij/psi/search/scope/packageSet","pom/src","openapi/src/com/intellij/ide/structureView","runtimesource/com/intellij/rt/compiler","doc/openapi/examples/vfs/src/com/intellij/openapi/samples","openapi/src/com/intellij/openapi/project","plugins/cvs2/source/com/intellij/cvsSupport2/application","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore","openapi/src/com/intellij/execution/filters","openapi/src/com/intellij/ide/util","source/com/intellij/codeInsight/intention/impl","openapi/src/com/intellij/openapi/fileChooser","openapi/src/com/intellij/openapi/editor/event","forms_rt/src/com/intellij","runtimesource/com/intellij/rt/execution/junit2/states","openapi/src/com/intellij/j2ee/run/localRun","plugins/conditionalOperatorConvertor/source/com/intellij","openapi/src/com/intellij/debugger","openapi/src/com/intellij/psi/infos","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext","pom/src/com","openapi/src/com/intellij/refactoring/util","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watchers","source/com/intellij/codeInsight/completion/proc","UIDesignerCore/src/com","openapi/src/com/intellij/util/ui/tree","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit","plugins/comparingReferences/source/com","openapi/src/com/intellij/util","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command","plugins/cvs2/javacvs-src/org","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin","UsageView/src/com/intellij/usages/actions","UsageView/testSource/com/intellij/usages","openapi/src/com/intellij/pom/java/events","openapi/src/com/intellij/refactoring/listeners","openapi/src/com/intellij/util/concurrency","openapi/src/com/intellij/psi/tree/xml","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick","runtimesource/com/intellij/rt/ant/execution","javac2/src/com","doc/openapi","openapi/src/com/intellij/openapi/vcs","openapi/src/com/intellij/ide/util/treeView","plugins/conditionalOperatorConvertor/testSrc/com/intellij/codeInsight","source/com/intellij/application","openapi/src/com/intellij/lexer","UIDesignerCore/testSource/com","openapi/src/com/intellij/openapi/vcs/history","openapi/src/com/intellij/xml/util","openapi/src/com/intellij/openapi/options","openapi/src/com/intellij/execution/ui","openapi","source/com/intellij/codeInsight/daemon/impl/analysis","plugins/debuggerCommonViews","source/com/intellij/codeInsight/highlighting/actions","openapi/src/com/intellij/ant","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui","openapi/src/com/intellij/peer","doc/openapi/examples/plugin","openapi/src/com/intellij/pom","doc/openapi/examples/toolWindow/src/com/intellij","source/com/intellij/codeInsight/folding/impl","source/com/intellij/codeInsight/daemon","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin","UIDesignerCore/src/com/intellij/uiDesigner/shared","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove","openapi/src/com/intellij/openapi/vfs","source/com/intellij/application/options/pathMacros","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate","openapi/src/com/intellij/psi/tree/jsp","openapi/src/com/intellij/codeInsight/intention","doc/openapi/examples/actions/src/com","UIDesignerCore/src/com/intellij/uiDesigner","openapi/src/com/intellij/openapi/options/colors","openapi/src/com/intellij/ide/wizard","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update","openapi/src/com/intellij/psi/util","openapi/src/com/intellij/psi/scope","plugins/cvs2/source/com/intellij/cvsSupport2/util","openapi/src/com/intellij/execution/process","plugins/cvs2/maverick_utils","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress","openapi/src/com/intellij/ide/fileTemplates","plugins/conditionalOperatorConvertor/testSrc","runtimesource","source/com/intellij/codeInsight/completion/scope","source/com/intellij/codeInsight/intention/impl/config","openapi/src","doc/openapi/examples/vfs/src/com","plugins/cvs2/maverick_utils/com/intellij","openapi/src/com/intellij/debugger/ui/tree/render","openapi/src/com/intellij/ui/content","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser","doc/openapi/examples/plugin/src/com/intellij/openapi/samples","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui","openapi/src/com/intellij/psi/search/scope","plugins/cvs2/smartcvs-src/org/netbeans/lib","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2","source/com/intellij/codeInsight/daemon/impl","plugins/comparingReferences/source/com/intellij/codeInspection","javac2","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout","openapi/src/com/intellij/j2ee/run","UsageView/src/com/intellij/usages","openapi/src/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl","javac2/src/com/intellij","openapi/src/com/intellij/openapi/command","source/com/intellij/codeInsight/generation/ui","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch","runtimesource/com/intellij/rt/execution","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/ui","openapi/src/com/intellij/openapi/vcs/actions","openapi/src/com/intellij/openapi/vcs/fileView","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors","openapi/src/com/intellij/debugger/ui/tree","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add","source/com/intellij/codeInsight/highlighting","source/com/intellij/codeInsight/generation","doc/openapi/examples/plugin/src","doc/openapi/examples/plugin/src/com/intellij/openapi"]} \ No newline at end of file +{"parentCommitId":"0","currentCommitId":"7460e5adae69c7b17c951f1198a6b6900721a1ee","filesBefore":[],"filesCurrent":["UIDesignerCore/src/com/intellij/uiDesigner/compiler/AlienFormFileException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/ClassToBindNotFoundException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/CodeGenerationException.java","UIDesignerCore/src/com/intellij/uiDesigner/compiler/Utils.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/CompiledClassPropertiesProvider.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/IRootContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwAtomicComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwComponent.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwHSpacer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroBooleanProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroDimensionProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroDoubleProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroInsetsProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroIntProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntroRectangleProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwIntrospectedProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwRbIntroStringProperty.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwRootContainer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwScrollPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwSplitPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwTabbedPane.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwVSpacer.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/LwXmlReader.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/PropertiesProvider.java","UIDesignerCore/src/com/intellij/uiDesigner/lw/StringDescriptor.java","UIDesignerCore/src/com/intellij/uiDesigner/shared/BorderType.java","UIDesignerCore/src/com/intellij/uiDesigner/shared/XYLayoutManager.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test1.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test2.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test3.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test4.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test5.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test6.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test7.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/Test8.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestEmpty.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestEqualSizeCells.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestGaps.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestPrefSize.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestSpans.java","UIDesignerCore/testSource/com/intellij/uiDesigner/core/TestTextAreas.java","UsageView/src/com/intellij/usages/TextChunk.java","UsageView/src/com/intellij/usages/Usage.java","UsageView/src/com/intellij/usages/UsageGroup.java","UsageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java","UsageView/src/com/intellij/usages/UsageModelTracker.java","UsageView/src/com/intellij/usages/UsagePresentation.java","UsageView/src/com/intellij/usages/UsageSearcher.java","UsageView/src/com/intellij/usages/UsageTarget.java","UsageView/src/com/intellij/usages/UsageView.java","UsageView/src/com/intellij/usages/UsageViewManager.java","UsageView/src/com/intellij/usages/UsageViewPresentation.java","UsageView/src/com/intellij/usages/UsageViewSettings.java","UsageView/src/com/intellij/usages/actions/ExcludeUsageAction.java","UsageView/src/com/intellij/usages/actions/IncludeExcludeActionBase.java","UsageView/src/com/intellij/usages/actions/IncludeUsageAction.java","UsageView/src/com/intellij/usages/impl/ExporterToTextFile.java","UsageView/src/com/intellij/usages/impl/GroupNode.java","UsageView/src/com/intellij/usages/impl/Node.java","UsageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java","UsageView/src/com/intellij/usages/impl/UsageNode.java","UsageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java","UsageView/src/com/intellij/usages/impl/UsageTargetNode.java","UsageView/src/com/intellij/usages/impl/UsageViewImpl.java","UsageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java","UsageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java","UsageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java","UsageView/src/com/intellij/usages/impl/rules/ClassGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/MethodGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/NonCodeUsageGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/PackageGroupingRule.java","UsageView/src/com/intellij/usages/impl/rules/UsageType.java","UsageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java","UsageView/src/com/intellij/usages/rules/MergeableUsage.java","UsageView/src/com/intellij/usages/rules/PsiElementUsage.java","UsageView/src/com/intellij/usages/rules/UsageGroupingRule.java","UsageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java","UsageView/src/com/intellij/usages/rules/UsageInFile.java","UsageView/src/com/intellij/usages/rules/UsageInFiles.java","UsageView/src/com/intellij/usages/rules/UsageInLibrary.java","UsageView/src/com/intellij/usages/rules/UsageInModule.java","UsageView/testSource/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/ActionsPlugin.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/GarbageCollectionAction.java","doc/openapi/examples/actions/src/com/intellij/openapi/samples/HelloWorldAction.java","doc/openapi/examples/plugin/src/com/intellij/openapi/samples/SampleApplicationPlugin.java","doc/openapi/examples/plugin/src/com/intellij/openapi/samples/SampleProjectPlugin.java","doc/openapi/examples/toolWindow/src/com/intellij/openapi/samples/SimpleToolWindowPlugin.java","doc/openapi/examples/vfs/src/com/intellij/openapi/samples/VfsSamplePlugin.java","forms_rt/src/com/intellij/uiDesigner/core/AbstractLayout.java","forms_rt/src/com/intellij/uiDesigner/core/DimensionInfo.java","forms_rt/src/com/intellij/uiDesigner/core/GridConstraints.java","forms_rt/src/com/intellij/uiDesigner/core/GridLayoutManager.java","forms_rt/src/com/intellij/uiDesigner/core/HorizontalInfo.java","forms_rt/src/com/intellij/uiDesigner/core/LayoutState.java","forms_rt/src/com/intellij/uiDesigner/core/Spacer.java","forms_rt/src/com/intellij/uiDesigner/core/SupportCode.java","forms_rt/src/com/intellij/uiDesigner/core/Util.java","forms_rt/src/com/intellij/uiDesigner/core/VerticalInfo.java","javac2/src/com/intellij/uiDesigner/ant/Javac2.java","openapi/src/com/intellij/ant/AntElementRole.java","openapi/src/com/intellij/ant/PsiAntElement.java","openapi/src/com/intellij/codeHighlighting/BackgroundEditorHighlighter.java","openapi/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java","openapi/src/com/intellij/codeHighlighting/HighlightingPass.java","openapi/src/com/intellij/codeInsight/ExpectedTypeInfo.java","openapi/src/com/intellij/codeInsight/ExpectedTypesProvider.java","openapi/src/com/intellij/codeInsight/highlighting/HighlightManager.java","openapi/src/com/intellij/codeInsight/intention/IntentionAction.java","openapi/src/com/intellij/codeInsight/intention/IntentionManager.java","openapi/src/com/intellij/codeInspection/InspectionManager.java","openapi/src/com/intellij/codeInspection/InspectionToolProvider.java","openapi/src/com/intellij/codeInspection/LocalInspectionTool.java","openapi/src/com/intellij/codeInspection/LocalQuickFix.java","openapi/src/com/intellij/codeInspection/ProblemDescriptor.java","openapi/src/com/intellij/codeInspection/ProblemHighlightType.java","openapi/src/com/intellij/debugger/DebuggerContext.java","openapi/src/com/intellij/debugger/DebuggerManager.java","openapi/src/com/intellij/debugger/NoDataException.java","openapi/src/com/intellij/debugger/PositionManager.java","openapi/src/com/intellij/debugger/SourcePosition.java","openapi/src/com/intellij/debugger/engine/DebugProcess.java","openapi/src/com/intellij/debugger/engine/DebugProcessAdapter.java","openapi/src/com/intellij/debugger/engine/DebugProcessListener.java","openapi/src/com/intellij/debugger/engine/DebuggerUtils.java","openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java","openapi/src/com/intellij/debugger/engine/StackFrameContext.java","openapi/src/com/intellij/debugger/engine/SuspendContext.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluateException.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java","openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java","openapi/src/com/intellij/debugger/engine/evaluation/TextWithImports.java","openapi/src/com/intellij/debugger/engine/jdi/LocalVariableProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ObjectReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ThreadGroupReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/ThreadReferenceProxy.java","openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java","openapi/src/com/intellij/debugger/engine/managerThread/DebuggerCommand.java","openapi/src/com/intellij/debugger/engine/managerThread/DebuggerManagerThread.java","openapi/src/com/intellij/debugger/engine/managerThread/SuspendContextCommand.java","openapi/src/com/intellij/debugger/requests/ClassPrepareRequestor.java","openapi/src/com/intellij/debugger/requests/RequestManager.java","openapi/src/com/intellij/debugger/requests/Requestor.java","openapi/src/com/intellij/debugger/ui/CompletitionEditor.java","openapi/src/com/intellij/debugger/ui/tree/ArrayElementDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java","openapi/src/com/intellij/debugger/ui/tree/FieldDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/LocalVariableDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/NodeDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorFactory.java","openapi/src/com/intellij/debugger/ui/tree/NodeManager.java","openapi/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/StaticDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ThreadDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ThreadGroupDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/UserExpressionDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/ValueDescriptor.java","openapi/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java","openapi/src/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java","openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java","openapi/src/com/intellij/debugger/ui/tree/render/NodeRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java","openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java","openapi/src/com/intellij/debugger/ui/tree/render/Renderer.java","openapi/src/com/intellij/debugger/ui/tree/render/RendererProvider.java","openapi/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java","openapi/src/com/intellij/execution/CantRunException.java","openapi/src/com/intellij/execution/DefaultExecutionResult.java","openapi/src/com/intellij/execution/ExecutionException.java","openapi/src/com/intellij/execution/ExecutionManager.java","openapi/src/com/intellij/execution/ExecutionRegistry.java","openapi/src/com/intellij/execution/ExecutionResult.java","openapi/src/com/intellij/execution/RunConfigurationConfigurableAdapter.java","openapi/src/com/intellij/execution/configurations/CommandLineState.java","openapi/src/com/intellij/execution/configurations/ConfigurationFactory.java","openapi/src/com/intellij/execution/configurations/ConfigurationInfoProvider.java","openapi/src/com/intellij/execution/configurations/ConfigurationPerRunnerSettings.java","openapi/src/com/intellij/execution/configurations/ConfigurationTemplate.java","openapi/src/com/intellij/execution/configurations/ConfigurationType.java","openapi/src/com/intellij/execution/configurations/GeneralCommandLine.java","openapi/src/com/intellij/execution/configurations/JavaCommandLine.java","openapi/src/com/intellij/execution/configurations/JavaCommandLineState.java","openapi/src/com/intellij/execution/configurations/JavaParameters.java","openapi/src/com/intellij/execution/configurations/ParametersList.java","openapi/src/com/intellij/execution/configurations/PatchedRunnableState.java","openapi/src/com/intellij/execution/configurations/RemoteConnection.java","openapi/src/com/intellij/execution/configurations/RemoteState.java","openapi/src/com/intellij/execution/configurations/RunConfiguration.java","openapi/src/com/intellij/execution/configurations/RunConfigurationBase.java","openapi/src/com/intellij/execution/configurations/RunConfigurationWithRunnerSettings.java","openapi/src/com/intellij/execution/configurations/RunProfile.java","openapi/src/com/intellij/execution/configurations/RunProfileState.java","openapi/src/com/intellij/execution/configurations/RunnableState.java","openapi/src/com/intellij/execution/configurations/RunnerSettings.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationError.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationException.java","openapi/src/com/intellij/execution/configurations/RuntimeConfigurationWarning.java","openapi/src/com/intellij/execution/filters/CompositeFilter.java","openapi/src/com/intellij/execution/filters/ExceptionFilter.java","openapi/src/com/intellij/execution/filters/Filter.java","openapi/src/com/intellij/execution/filters/HyperlinkInfo.java","openapi/src/com/intellij/execution/filters/InvalidExpressionException.java","openapi/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java","openapi/src/com/intellij/execution/filters/RegexpFilter.java","openapi/src/com/intellij/execution/filters/TextConsoleBuilder.java","openapi/src/com/intellij/execution/process/DefaultJavaProcessHandler.java","openapi/src/com/intellij/execution/process/OSProcessHandler.java","openapi/src/com/intellij/execution/process/ProcessAdapter.java","openapi/src/com/intellij/execution/process/ProcessEvent.java","openapi/src/com/intellij/execution/process/ProcessHandler.java","openapi/src/com/intellij/execution/process/ProcessListener.java","openapi/src/com/intellij/execution/process/ProcessNotCreatedException.java","openapi/src/com/intellij/execution/process/ProcessOutputTypes.java","openapi/src/com/intellij/execution/process/ProcessTerminatedListener.java","openapi/src/com/intellij/execution/runners/JavaProgramRunner.java","openapi/src/com/intellij/execution/runners/ProcessProxy.java","openapi/src/com/intellij/execution/runners/ProcessProxyFactory.java","openapi/src/com/intellij/execution/ui/CloseAction.java","openapi/src/com/intellij/execution/ui/ConsoleView.java","openapi/src/com/intellij/execution/ui/ConsoleViewContentType.java","openapi/src/com/intellij/execution/ui/ExecutionConsole.java","openapi/src/com/intellij/execution/ui/RunContentDescriptor.java","openapi/src/com/intellij/execution/ui/RunContentListener.java","openapi/src/com/intellij/execution/ui/RunContentManager.java","openapi/src/com/intellij/find/FindManager.java","openapi/src/com/intellij/find/FindModel.java","openapi/src/com/intellij/find/FindResult.java","openapi/src/com/intellij/ide/AutoScrollToSourceOptionProvider.java","openapi/src/com/intellij/ide/BrowserUtil.java","openapi/src/com/intellij/ide/CommonActionsManager.java","openapi/src/com/intellij/ide/CopyProvider.java","openapi/src/com/intellij/ide/CutProvider.java","openapi/src/com/intellij/ide/DataManager.java","openapi/src/com/intellij/ide/DeleteProvider.java","openapi/src/com/intellij/ide/EditorHighlighter.java","openapi/src/com/intellij/ide/ExporterToTextFile.java","openapi/src/com/intellij/ide/GeneralSettings.java","openapi/src/com/intellij/ide/OccurenceNavigator.java","openapi/src/com/intellij/ide/OccurenceNavigatorSupport.java","openapi/src/com/intellij/ide/SelectInManager.java","openapi/src/com/intellij/ide/SelectInTarget.java","openapi/src/com/intellij/ide/TreeExpander.java","openapi/src/com/intellij/ide/actions/CollapseAllToolbarAction.java","openapi/src/com/intellij/ide/actions/ExpandAllToolbarAction.java","openapi/src/com/intellij/ide/actions/TreeCollapseAllActionBase.java","openapi/src/com/intellij/ide/actions/TreeExpandAllActionBase.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateDescriptor.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateGroupDescriptor.java","openapi/src/com/intellij/ide/fileTemplates/FileTemplateGroupDescriptorFactory.java","openapi/src/com/intellij/ide/projectView/PresentationData.java","openapi/src/com/intellij/ide/projectView/ProjectViewNode.java","openapi/src/com/intellij/ide/projectView/TreeStructureProvider.java","openapi/src/com/intellij/ide/projectView/ViewSettings.java","openapi/src/com/intellij/ide/structureView/StructureViewModel.java","openapi/src/com/intellij/ide/structureView/StructureViewTreeElement.java","openapi/src/com/intellij/ide/util/BrowseFilesListener.java","openapi/src/com/intellij/ide/util/PropertiesComponent.java","openapi/src/com/intellij/ide/util/projectWizard/ExistingModuleLoader.java","openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java","openapi/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java","openapi/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java","openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java","openapi/src/com/intellij/ide/util/projectWizard/WizardContext.java","openapi/src/com/intellij/ide/util/treeView/AbstractTreeNode.java","openapi/src/com/intellij/ide/util/treeView/NodeDescriptor.java","openapi/src/com/intellij/ide/util/treeView/NodeOptions.java","openapi/src/com/intellij/ide/util/treeView/NodeRenderer.java","openapi/src/com/intellij/ide/util/treeView/smartTree/ActionPresentation.java","openapi/src/com/intellij/ide/util/treeView/smartTree/ActionPresentationData.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Filter.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Group.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Grouper.java","openapi/src/com/intellij/ide/util/treeView/smartTree/Sorter.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeAction.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeElement.java","openapi/src/com/intellij/ide/util/treeView/smartTree/TreeModel.java","openapi/src/com/intellij/ide/wizard/AbstractWizard.java","openapi/src/com/intellij/ide/wizard/CommitStepException.java","openapi/src/com/intellij/ide/wizard/Step.java","openapi/src/com/intellij/ide/wizard/StepAdapter.java","openapi/src/com/intellij/j2ee/PasswordUtil.java","openapi/src/com/intellij/j2ee/j2eeDom/ClassUtil.java","openapi/src/com/intellij/j2ee/make/BuildInstruction.java","openapi/src/com/intellij/j2ee/make/BuildInstructionVisitor.java","openapi/src/com/intellij/j2ee/make/BuildRecipe.java","openapi/src/com/intellij/j2ee/make/FileCopyInstruction.java","openapi/src/com/intellij/j2ee/make/J2EEBuildParticipant.java","openapi/src/com/intellij/j2ee/make/J2EEModuleBuildInstruction.java","openapi/src/com/intellij/j2ee/make/JarAndCopyBuildInstruction.java","openapi/src/com/intellij/j2ee/make/ManifestBuilder.java","openapi/src/com/intellij/j2ee/make/ModuleBuildProperties.java","openapi/src/com/intellij/j2ee/module/ContainerElement.java","openapi/src/com/intellij/j2ee/module/LibraryLink.java","openapi/src/com/intellij/j2ee/module/ModuleLink.java","openapi/src/com/intellij/j2ee/run/localRun/EnvironmentVariable.java","openapi/src/com/intellij/j2ee/ui/Commitable.java","openapi/src/com/intellij/j2ee/ui/CommitablePanel.java","openapi/src/com/intellij/j2ee/ui/CompositeCommitable.java","openapi/src/com/intellij/j2ee/ui/Warning.java","openapi/src/com/intellij/lexer/CompositeLexer.java","openapi/src/com/intellij/lexer/EmptyLexer.java","openapi/src/com/intellij/lexer/FilterLexer.java","openapi/src/com/intellij/lexer/LayeredLexer.java","openapi/src/com/intellij/lexer/Lexer.java","openapi/src/com/intellij/lexer/MergingLexerAdapter.java","openapi/src/com/intellij/navigation/ChooseByNameContributor.java","openapi/src/com/intellij/navigation/ChooseByNameRegistry.java","openapi/src/com/intellij/navigation/ItemPresentation.java","openapi/src/com/intellij/navigation/NavigationItem.java","openapi/src/com/intellij/openapi/Disposeable.java","openapi/src/com/intellij/openapi/actionSystem/ActionButtonComponent.java","openapi/src/com/intellij/openapi/actionSystem/ActionGroup.java","openapi/src/com/intellij/openapi/actionSystem/ActionManager.java","openapi/src/com/intellij/openapi/actionSystem/ActionPlaces.java","openapi/src/com/intellij/openapi/actionSystem/ActionPopupMenu.java","openapi/src/com/intellij/openapi/actionSystem/ActionStub.java","openapi/src/com/intellij/openapi/actionSystem/ActionToolbar.java","openapi/src/com/intellij/openapi/actionSystem/AnAction.java","openapi/src/com/intellij/openapi/actionSystem/AnActionEvent.java","openapi/src/com/intellij/openapi/actionSystem/Anchor.java","openapi/src/com/intellij/openapi/actionSystem/CommonShortcuts.java","openapi/src/com/intellij/openapi/actionSystem/Constraints.java","openapi/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java","openapi/src/com/intellij/openapi/actionSystem/DataConstants.java","openapi/src/com/intellij/openapi/actionSystem/DataContext.java","openapi/src/com/intellij/openapi/actionSystem/DataProvider.java","openapi/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java","openapi/src/com/intellij/openapi/actionSystem/IdeActions.java","openapi/src/com/intellij/openapi/actionSystem/KeyboardShortcut.java","openapi/src/com/intellij/openapi/actionSystem/MouseShortcut.java","openapi/src/com/intellij/openapi/actionSystem/Presentation.java","openapi/src/com/intellij/openapi/actionSystem/Separator.java","openapi/src/com/intellij/openapi/actionSystem/Shortcut.java","openapi/src/com/intellij/openapi/actionSystem/ShortcutSet.java","openapi/src/com/intellij/openapi/actionSystem/ToggleAction.java","openapi/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java","openapi/src/com/intellij/openapi/actionSystem/ex/CustomComponentAction.java","openapi/src/com/intellij/openapi/application/Application.java","openapi/src/com/intellij/openapi/application/ApplicationAdapter.java","openapi/src/com/intellij/openapi/application/ApplicationInfo.java","openapi/src/com/intellij/openapi/application/ApplicationListener.java","openapi/src/com/intellij/openapi/application/ApplicationManager.java","openapi/src/com/intellij/openapi/application/ModalityState.java","openapi/src/com/intellij/openapi/application/ModalityStateListener.java","openapi/src/com/intellij/openapi/application/PathManager.java","openapi/src/com/intellij/openapi/command/CommandAdapter.java","openapi/src/com/intellij/openapi/command/CommandEvent.java","openapi/src/com/intellij/openapi/command/CommandListener.java","openapi/src/com/intellij/openapi/command/CommandProcessor.java","openapi/src/com/intellij/openapi/command/UndoConfirmationPolicy.java","openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java","openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java","openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java","openapi/src/com/intellij/openapi/compiler/CompileContext.java","openapi/src/com/intellij/openapi/compiler/CompileScope.java","openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java","openapi/src/com/intellij/openapi/compiler/CompileTask.java","openapi/src/com/intellij/openapi/compiler/Compiler.java","openapi/src/com/intellij/openapi/compiler/CompilerManager.java","openapi/src/com/intellij/openapi/compiler/CompilerMessage.java","openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java","openapi/src/com/intellij/openapi/compiler/CompilerPaths.java","openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java","openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java","openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java","openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java","openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java","openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java","openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java","openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java","openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java","openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java","openapi/src/com/intellij/openapi/compiler/Validator.java","openapi/src/com/intellij/openapi/compiler/ValidityState.java","openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java","openapi/src/com/intellij/openapi/components/ApplicationComponent.java","openapi/src/com/intellij/openapi/components/BaseComponent.java","openapi/src/com/intellij/openapi/components/ComponentManager.java","openapi/src/com/intellij/openapi/components/ExportableApplicationComponent.java","openapi/src/com/intellij/openapi/components/ProjectComponent.java","openapi/src/com/intellij/openapi/components/SettingsSavingComponent.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsModule.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsRepository.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsResult.java","openapi/src/com/intellij/openapi/cvsIntegration/CvsServices.java","openapi/src/com/intellij/openapi/cvsIntegration/DateOrRevision.java","openapi/src/com/intellij/openapi/diagnostic/ErrorLogger.java","openapi/src/com/intellij/openapi/diagnostic/IdeaLoggingEvent.java","openapi/src/com/intellij/openapi/diff/BinaryContent.java","openapi/src/com/intellij/openapi/diff/DiffColors.java","openapi/src/com/intellij/openapi/diff/DiffContent.java","openapi/src/com/intellij/openapi/diff/DiffContentUtil.java","openapi/src/com/intellij/openapi/diff/DiffManager.java","openapi/src/com/intellij/openapi/diff/DiffPanel.java","openapi/src/com/intellij/openapi/diff/DiffPanelFactory.java","openapi/src/com/intellij/openapi/diff/DiffRequest.java","openapi/src/com/intellij/openapi/diff/DiffRequestFactory.java","openapi/src/com/intellij/openapi/diff/DiffTool.java","openapi/src/com/intellij/openapi/diff/DiffToolbar.java","openapi/src/com/intellij/openapi/diff/DiffViewer.java","openapi/src/com/intellij/openapi/diff/DocumentContent.java","openapi/src/com/intellij/openapi/diff/DocumentsSynchonizer.java","openapi/src/com/intellij/openapi/diff/FileContent.java","openapi/src/com/intellij/openapi/diff/FragmentContent.java","openapi/src/com/intellij/openapi/diff/LineTokenizer.java","openapi/src/com/intellij/openapi/diff/MergeRequest.java","openapi/src/com/intellij/openapi/diff/SimpleContent.java","openapi/src/com/intellij/openapi/diff/SimpleDiffRequest.java","openapi/src/com/intellij/openapi/editor/CaretModel.java","openapi/src/com/intellij/openapi/editor/Document.java","openapi/src/com/intellij/openapi/editor/DocumentFragment.java","openapi/src/com/intellij/openapi/editor/Editor.java","openapi/src/com/intellij/openapi/editor/EditorFactory.java","openapi/src/com/intellij/openapi/editor/EditorGutter.java","openapi/src/com/intellij/openapi/editor/EditorModificationUtil.java","openapi/src/com/intellij/openapi/editor/EditorSettings.java","openapi/src/com/intellij/openapi/editor/FoldRegion.java","openapi/src/com/intellij/openapi/editor/FoldingModel.java","openapi/src/com/intellij/openapi/editor/HighlighterColors.java","openapi/src/com/intellij/openapi/editor/LogicalPosition.java","openapi/src/com/intellij/openapi/editor/RangeMarker.java","openapi/src/com/intellij/openapi/editor/ReadOnlyFragmentModificationException.java","openapi/src/com/intellij/openapi/editor/ReadOnlyModificationException.java","openapi/src/com/intellij/openapi/editor/ScrollType.java","openapi/src/com/intellij/openapi/editor/ScrollingModel.java","openapi/src/com/intellij/openapi/editor/SelectionModel.java","openapi/src/com/intellij/openapi/editor/TextAnnotationGutterProvider.java","openapi/src/com/intellij/openapi/editor/VisualPosition.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorAction.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorActionManager.java","openapi/src/com/intellij/openapi/editor/actionSystem/EditorWriteActionHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/ReadonlyFragmentModificationHandler.java","openapi/src/com/intellij/openapi/editor/actionSystem/TypedAction.java","openapi/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java","openapi/src/com/intellij/openapi/editor/colors/ColorKey.java","openapi/src/com/intellij/openapi/editor/colors/EditorColors.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsAdapter.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsListener.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsManager.java","openapi/src/com/intellij/openapi/editor/colors/EditorColorsScheme.java","openapi/src/com/intellij/openapi/editor/colors/EditorFontType.java","openapi/src/com/intellij/openapi/editor/colors/TextAttributesKey.java","openapi/src/com/intellij/openapi/editor/event/CaretEvent.java","openapi/src/com/intellij/openapi/editor/event/CaretListener.java","openapi/src/com/intellij/openapi/editor/event/DocumentAdapter.java","openapi/src/com/intellij/openapi/editor/event/DocumentEvent.java","openapi/src/com/intellij/openapi/editor/event/DocumentListener.java","openapi/src/com/intellij/openapi/editor/event/EditorEventMulticaster.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryEvent.java","openapi/src/com/intellij/openapi/editor/event/EditorFactoryListener.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseEvent.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseEventArea.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseListener.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseMotionAdapter.java","openapi/src/com/intellij/openapi/editor/event/EditorMouseMotionListener.java","openapi/src/com/intellij/openapi/editor/event/MockDocumentEvent.java","openapi/src/com/intellij/openapi/editor/event/SelectionEvent.java","openapi/src/com/intellij/openapi/editor/event/SelectionListener.java","openapi/src/com/intellij/openapi/editor/event/VisibleAreaEvent.java","openapi/src/com/intellij/openapi/editor/event/VisibleAreaListener.java","openapi/src/com/intellij/openapi/editor/markup/ActiveGutterRenderer.java","openapi/src/com/intellij/openapi/editor/markup/EffectType.java","openapi/src/com/intellij/openapi/editor/markup/ErrorStripeRenderer.java","openapi/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java","openapi/src/com/intellij/openapi/editor/markup/GutterIconRenderer.java","openapi/src/com/intellij/openapi/editor/markup/HighlighterLayer.java","openapi/src/com/intellij/openapi/editor/markup/HighlighterTargetArea.java","openapi/src/com/intellij/openapi/editor/markup/LineMarkerRenderer.java","openapi/src/com/intellij/openapi/editor/markup/MarkupEditorFilter.java","openapi/src/com/intellij/openapi/editor/markup/MarkupModel.java","openapi/src/com/intellij/openapi/editor/markup/RangeHighlighter.java","openapi/src/com/intellij/openapi/editor/markup/SeparatorPlacement.java","openapi/src/com/intellij/openapi/editor/markup/TextAttributes.java","openapi/src/com/intellij/openapi/fileChooser/FileChooser.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserDialog.java","openapi/src/com/intellij/openapi/fileChooser/FileChooserFactory.java","openapi/src/com/intellij/openapi/fileChooser/FileElement.java","openapi/src/com/intellij/openapi/fileChooser/FileSystemTree.java","openapi/src/com/intellij/openapi/fileChooser/FileSystemTreeFactory.java","openapi/src/com/intellij/openapi/fileEditor/DocumentsEditor.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManager.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManagerAdapter.java","openapi/src/com/intellij/openapi/fileEditor/FileDocumentManagerListener.java","openapi/src/com/intellij/openapi/fileEditor/FileEditor.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorLocation.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManager.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerAdapter.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorManagerListener.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorPolicy.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorProvider.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorState.java","openapi/src/com/intellij/openapi/fileEditor/FileEditorStateLevel.java","openapi/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java","openapi/src/com/intellij/openapi/fileEditor/TextEditor.java","openapi/src/com/intellij/openapi/fileEditor/TextEditorLocation.java","openapi/src/com/intellij/openapi/fileEditor/VetoDocumentReloadException.java","openapi/src/com/intellij/openapi/fileEditor/VetoDocumentSavingException.java","openapi/src/com/intellij/openapi/fileTypes/FileHighlighter.java","openapi/src/com/intellij/openapi/fileTypes/FileHighlighterBase.java","openapi/src/com/intellij/openapi/fileTypes/FileType.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeEvent.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeListener.java","openapi/src/com/intellij/openapi/fileTypes/FileTypeManager.java","openapi/src/com/intellij/openapi/fileTypes/PlainFileHighlighter.java","openapi/src/com/intellij/openapi/fileTypes/StdFileTypes.java","openapi/src/com/intellij/openapi/fileTypes/UserFileType.java","openapi/src/com/intellij/openapi/help/HelpManager.java","openapi/src/com/intellij/openapi/ide/CopyPasteManager.java","openapi/src/com/intellij/openapi/localVcs/LocalVcs.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsItemsLocker.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsPurgingProvider.java","openapi/src/com/intellij/openapi/localVcs/LocalVcsServices.java","openapi/src/com/intellij/openapi/localVcs/LvcsAction.java","openapi/src/com/intellij/openapi/localVcs/LvcsComparator.java","openapi/src/com/intellij/openapi/localVcs/LvcsConfiguration.java","openapi/src/com/intellij/openapi/localVcs/LvcsDirectory.java","openapi/src/com/intellij/openapi/localVcs/LvcsDirectoryRevision.java","openapi/src/com/intellij/openapi/localVcs/LvcsFile.java","openapi/src/com/intellij/openapi/localVcs/LvcsFileRevision.java","openapi/src/com/intellij/openapi/localVcs/LvcsLabel.java","openapi/src/com/intellij/openapi/localVcs/LvcsLabelListener.java","openapi/src/com/intellij/openapi/localVcs/LvcsObject.java","openapi/src/com/intellij/openapi/localVcs/LvcsRevision.java","openapi/src/com/intellij/openapi/localVcs/UpToDateLineNumberProvider.java","openapi/src/com/intellij/openapi/localVcs/VirtualFileInfo.java","openapi/src/com/intellij/openapi/module/ModifiableModuleModel.java","openapi/src/com/intellij/openapi/module/Module.java","openapi/src/com/intellij/openapi/module/ModuleComponent.java","openapi/src/com/intellij/openapi/module/ModuleConfigurationEditor.java","openapi/src/com/intellij/openapi/module/ModuleManager.java","openapi/src/com/intellij/openapi/module/ModulePointer.java","openapi/src/com/intellij/openapi/module/ModulePointerManager.java","openapi/src/com/intellij/openapi/module/ModuleType.java","openapi/src/com/intellij/openapi/module/ModuleTypeManager.java","openapi/src/com/intellij/openapi/module/ModuleWithNameAlreadyExists.java","openapi/src/com/intellij/openapi/options/BaseConfigurable.java","openapi/src/com/intellij/openapi/options/BaseConfigurableWithChangeSupport.java","openapi/src/com/intellij/openapi/options/CompositeSettingsBuilder.java","openapi/src/com/intellij/openapi/options/CompositeSettingsEditor.java","openapi/src/com/intellij/openapi/options/Configurable.java","openapi/src/com/intellij/openapi/options/ConfigurableGroup.java","openapi/src/com/intellij/openapi/options/ConfigurationException.java","openapi/src/com/intellij/openapi/options/GroupSettingsBuilder.java","openapi/src/com/intellij/openapi/options/SettingsEditor.java","openapi/src/com/intellij/openapi/options/SettingsEditorConfigurable.java","openapi/src/com/intellij/openapi/options/SettingsEditorGroup.java","openapi/src/com/intellij/openapi/options/SettingsEditorListener.java","openapi/src/com/intellij/openapi/options/SettingsEditorWrapper.java","openapi/src/com/intellij/openapi/options/ShowSettingsUtil.java","openapi/src/com/intellij/openapi/options/UnnamedConfigurable.java","openapi/src/com/intellij/openapi/options/UnnamedConfigurableGroup.java","openapi/src/com/intellij/openapi/options/colors/AttributesDescriptor.java","openapi/src/com/intellij/openapi/options/colors/ColorDescriptor.java","openapi/src/com/intellij/openapi/options/colors/ColorSettingsPage.java","openapi/src/com/intellij/openapi/options/colors/ColorSettingsPages.java","openapi/src/com/intellij/openapi/progress/ProcessCanceledException.java","openapi/src/com/intellij/openapi/progress/ProgressFunComponentProvider.java","openapi/src/com/intellij/openapi/progress/ProgressIndicator.java","openapi/src/com/intellij/openapi/progress/ProgressManager.java","openapi/src/com/intellij/openapi/project/ModuleListener.java","openapi/src/com/intellij/openapi/project/Project.java","openapi/src/com/intellij/openapi/project/ProjectManager.java","openapi/src/com/intellij/openapi/project/ProjectManagerAdapter.java","openapi/src/com/intellij/openapi/project/ProjectManagerListener.java","openapi/src/com/intellij/openapi/project/ProjectReloadState.java","openapi/src/com/intellij/openapi/projectRoots/AdditionalDataConfigurable.java","openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java","openapi/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java","openapi/src/com/intellij/openapi/projectRoots/ProjectRootListener.java","openapi/src/com/intellij/openapi/projectRoots/Sdk.java","openapi/src/com/intellij/openapi/projectRoots/SdkAdditionalData.java","openapi/src/com/intellij/openapi/projectRoots/SdkModel.java","openapi/src/com/intellij/openapi/projectRoots/SdkModificator.java","openapi/src/com/intellij/openapi/projectRoots/SdkType.java","openapi/src/com/intellij/openapi/roots/ContentEntry.java","openapi/src/com/intellij/openapi/roots/ContentFolder.java","openapi/src/com/intellij/openapi/roots/ContentIterator.java","openapi/src/com/intellij/openapi/roots/ExcludeFolder.java","openapi/src/com/intellij/openapi/roots/ExcludedOutputFolder.java","openapi/src/com/intellij/openapi/roots/ExportableOrderEntry.java","openapi/src/com/intellij/openapi/roots/FileIndex.java","openapi/src/com/intellij/openapi/roots/InheritedJdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/JdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/LibraryOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModifiableRootModel.java","openapi/src/com/intellij/openapi/roots/ModuleFileIndex.java","openapi/src/com/intellij/openapi/roots/ModuleJdkOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModuleOrderEntry.java","openapi/src/com/intellij/openapi/roots/ModuleRootEvent.java","openapi/src/com/intellij/openapi/roots/ModuleRootListener.java","openapi/src/com/intellij/openapi/roots/ModuleRootManager.java","openapi/src/com/intellij/openapi/roots/ModuleRootModel.java","openapi/src/com/intellij/openapi/roots/ModuleSourceOrderEntry.java","openapi/src/com/intellij/openapi/roots/OrderEntry.java","openapi/src/com/intellij/openapi/roots/OrderRootType.java","openapi/src/com/intellij/openapi/roots/ProjectFileIndex.java","openapi/src/com/intellij/openapi/roots/ProjectRootManager.java","openapi/src/com/intellij/openapi/roots/ProjectRootsTraversing.java","openapi/src/com/intellij/openapi/roots/RootPolicy.java","openapi/src/com/intellij/openapi/roots/RootProvider.java","openapi/src/com/intellij/openapi/roots/SearchingPolicy.java","openapi/src/com/intellij/openapi/roots/SourceFolder.java","openapi/src/com/intellij/openapi/roots/Synthetic.java","openapi/src/com/intellij/openapi/roots/UserDefinedExcludeFolder.java","openapi/src/com/intellij/openapi/roots/libraries/Library.java","openapi/src/com/intellij/openapi/roots/libraries/LibraryTable.java","openapi/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java","openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationEditorProvider.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java","openapi/src/com/intellij/openapi/roots/ui/configuration/ModulesProvider.java","openapi/src/com/intellij/openapi/startup/StartupManager.java","openapi/src/com/intellij/openapi/ui/ComboBox.java","openapi/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java","openapi/src/com/intellij/openapi/ui/DialogBuilder.java","openapi/src/com/intellij/openapi/ui/DialogWrapper.java","openapi/src/com/intellij/openapi/ui/DialogWrapperDialog.java","openapi/src/com/intellij/openapi/ui/DialogWrapperPeer.java","openapi/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java","openapi/src/com/intellij/openapi/ui/FixedSizeButton.java","openapi/src/com/intellij/openapi/ui/InputException.java","openapi/src/com/intellij/openapi/ui/InputValidator.java","openapi/src/com/intellij/openapi/ui/LabeledComponent.java","openapi/src/com/intellij/openapi/ui/Messages.java","openapi/src/com/intellij/openapi/ui/MultiLineLabelUI.java","openapi/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java","openapi/src/com/intellij/openapi/ui/Splitter.java","openapi/src/com/intellij/openapi/ui/TestDialog.java","openapi/src/com/intellij/openapi/ui/TextComponentAccessor.java","openapi/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java","openapi/src/com/intellij/openapi/ui/VerticalFlowLayout.java","openapi/src/com/intellij/openapi/util/DimensionService.java","openapi/src/com/intellij/openapi/util/ExceptionMessages.java","openapi/src/com/intellij/openapi/util/IconLoader.java","openapi/src/com/intellij/openapi/util/Iconable.java","openapi/src/com/intellij/openapi/util/ModificationTracker.java","openapi/src/com/intellij/openapi/vcs/AbstractVcs.java","openapi/src/com/intellij/openapi/vcs/AbstractVcsHelper.java","openapi/src/com/intellij/openapi/vcs/CheckinProjectPanel.java","openapi/src/com/intellij/openapi/vcs/EditFileProvider.java","openapi/src/com/intellij/openapi/vcs/FilePath.java","openapi/src/com/intellij/openapi/vcs/FileStatus.java","openapi/src/com/intellij/openapi/vcs/FileStatusFactory.java","openapi/src/com/intellij/openapi/vcs/FileStatusListener.java","openapi/src/com/intellij/openapi/vcs/FileStatusManager.java","openapi/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java","openapi/src/com/intellij/openapi/vcs/SelectionChangeListener.java","openapi/src/com/intellij/openapi/vcs/TransactionProvider.java","openapi/src/com/intellij/openapi/vcs/TransactionRunnable.java","openapi/src/com/intellij/openapi/vcs/VcsConfiguration.java","openapi/src/com/intellij/openapi/vcs/VcsDataConstants.java","openapi/src/com/intellij/openapi/vcs/VcsException.java","openapi/src/com/intellij/openapi/vcs/actions/StandardVcsGroup.java","openapi/src/com/intellij/openapi/vcs/actions/VcsContext.java","openapi/src/com/intellij/openapi/vcs/actions/VcsContextFactory.java","openapi/src/com/intellij/openapi/vcs/checkin/CheckinEnvironment.java","openapi/src/com/intellij/openapi/vcs/fileView/DualViewColumnInfo.java","openapi/src/com/intellij/openapi/vcs/history/CurrentRevision.java","openapi/src/com/intellij/openapi/vcs/history/HistoryAsTreeProvider.java","openapi/src/com/intellij/openapi/vcs/history/VcsFileRevision.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistoryProvider.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistorySession.java","openapi/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java","openapi/src/com/intellij/openapi/vcs/history/VcsRevisionNumber.java","openapi/src/com/intellij/openapi/vcs/ui/OptionsDialog.java","openapi/src/com/intellij/openapi/vcs/ui/Refreshable.java","openapi/src/com/intellij/openapi/vcs/ui/RefreshableOnComponent.java","openapi/src/com/intellij/openapi/vcs/ui/ReplaceFileConfirmationDialog.java","openapi/src/com/intellij/openapi/vcs/update/FileGroup.java","openapi/src/com/intellij/openapi/vcs/update/UpdateEnvironment.java","openapi/src/com/intellij/openapi/vcs/update/UpdateSession.java","openapi/src/com/intellij/openapi/vcs/update/UpdateSessionAdapter.java","openapi/src/com/intellij/openapi/vcs/update/UpdatedFiles.java","openapi/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsFileSystem.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsVirtualFile.java","openapi/src/com/intellij/openapi/vcs/vfs/VcsVirtualFolder.java","openapi/src/com/intellij/openapi/vfs/CharsetToolkit.java","openapi/src/com/intellij/openapi/vfs/JarFileSystem.java","openapi/src/com/intellij/openapi/vfs/LocalFileSystem.java","openapi/src/com/intellij/openapi/vfs/ModificationAttemptEvent.java","openapi/src/com/intellij/openapi/vfs/ModificationAttemptListener.java","openapi/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java","openapi/src/com/intellij/openapi/vfs/SmartEncodingInputStream.java","openapi/src/com/intellij/openapi/vfs/VfsUtil.java","openapi/src/com/intellij/openapi/vfs/VirtualFile.java","openapi/src/com/intellij/openapi/vfs/VirtualFileAdapter.java","openapi/src/com/intellij/openapi/vfs/VirtualFileEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFileFilter.java","openapi/src/com/intellij/openapi/vfs/VirtualFileListener.java","openapi/src/com/intellij/openapi/vfs/VirtualFileManager.java","openapi/src/com/intellij/openapi/vfs/VirtualFileMoveEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFilePropertyEvent.java","openapi/src/com/intellij/openapi/vfs/VirtualFileSystem.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointer.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerContainer.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerFactory.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerListener.java","openapi/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java","openapi/src/com/intellij/openapi/wm/FocusWatcher.java","openapi/src/com/intellij/openapi/wm/StatusBar.java","openapi/src/com/intellij/openapi/wm/ToolWindow.java","openapi/src/com/intellij/openapi/wm/ToolWindowAnchor.java","openapi/src/com/intellij/openapi/wm/ToolWindowId.java","openapi/src/com/intellij/openapi/wm/ToolWindowManager.java","openapi/src/com/intellij/openapi/wm/ToolWindowType.java","openapi/src/com/intellij/openapi/wm/WindowManager.java","openapi/src/com/intellij/peer/PeerFactory.java","openapi/src/com/intellij/pom/java/LanguageLevel.java","openapi/src/com/intellij/pom/java/PomJavaAspect.java","openapi/src/com/intellij/pom/java/events/JavaTreeChanged.java","openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java","openapi/src/com/intellij/pom/java/events/PomJavaChange.java","openapi/src/com/intellij/psi/CustomHighlighterTokenType.java","openapi/src/com/intellij/psi/EmptySubstitutor.java","openapi/src/com/intellij/psi/GenericsUtil.java","openapi/src/com/intellij/psi/ImplicitVariable.java","openapi/src/com/intellij/psi/JavaDocTokenType.java","openapi/src/com/intellij/psi/JavaElementVisitor.java","openapi/src/com/intellij/psi/JavaTokenType.java","openapi/src/com/intellij/psi/PsiAnnotation.java","openapi/src/com/intellij/psi/PsiAnnotationMemberValue.java","openapi/src/com/intellij/psi/PsiAnnotationMethod.java","openapi/src/com/intellij/psi/PsiAnnotationParameterList.java","openapi/src/com/intellij/psi/PsiAnonymousClass.java","openapi/src/com/intellij/psi/PsiArrayAccessExpression.java","openapi/src/com/intellij/psi/PsiArrayInitializerExpression.java","openapi/src/com/intellij/psi/PsiArrayInitializerMemberValue.java","openapi/src/com/intellij/psi/PsiArrayType.java","openapi/src/com/intellij/psi/PsiAspectManagerListener.java","openapi/src/com/intellij/psi/PsiAssertStatement.java","openapi/src/com/intellij/psi/PsiAssignmentExpression.java","openapi/src/com/intellij/psi/PsiBinaryExpression.java","openapi/src/com/intellij/psi/PsiBinaryFile.java","openapi/src/com/intellij/psi/PsiBlockStatement.java","openapi/src/com/intellij/psi/PsiBreakStatement.java","openapi/src/com/intellij/psi/PsiCall.java","openapi/src/com/intellij/psi/PsiCallExpression.java","openapi/src/com/intellij/psi/PsiCapturedWildcardType.java","openapi/src/com/intellij/psi/PsiCatchSection.java","openapi/src/com/intellij/psi/PsiClass.java","openapi/src/com/intellij/psi/PsiClassInitializer.java","openapi/src/com/intellij/psi/PsiClassObjectAccessExpression.java","openapi/src/com/intellij/psi/PsiClassType.java","openapi/src/com/intellij/psi/PsiCodeBlock.java","openapi/src/com/intellij/psi/PsiCodeFragment.java","openapi/src/com/intellij/psi/PsiComment.java","openapi/src/com/intellij/psi/PsiCompiledElement.java","openapi/src/com/intellij/psi/PsiConditionalExpression.java","openapi/src/com/intellij/psi/PsiConstantEvaluationHelper.java","openapi/src/com/intellij/psi/PsiConstructorCall.java","openapi/src/com/intellij/psi/PsiContinueStatement.java","openapi/src/com/intellij/psi/PsiDeclarationStatement.java","openapi/src/com/intellij/psi/PsiDirectory.java","openapi/src/com/intellij/psi/PsiDoWhileStatement.java","openapi/src/com/intellij/psi/PsiDocCommentOwner.java","openapi/src/com/intellij/psi/PsiDocumentManager.java","openapi/src/com/intellij/psi/PsiElement.java","openapi/src/com/intellij/psi/PsiElementFactory.java","openapi/src/com/intellij/psi/PsiElementFinder.java","openapi/src/com/intellij/psi/PsiElementVisitor.java","openapi/src/com/intellij/psi/PsiEllipsisType.java","openapi/src/com/intellij/psi/PsiEmptyStatement.java","openapi/src/com/intellij/psi/PsiEnumConstant.java","openapi/src/com/intellij/psi/PsiEnumConstantInitializer.java","openapi/src/com/intellij/psi/PsiErrorElement.java","openapi/src/com/intellij/psi/PsiExpression.java","openapi/src/com/intellij/psi/PsiExpressionCodeFragment.java","openapi/src/com/intellij/psi/PsiExpressionList.java","openapi/src/com/intellij/psi/PsiExpressionListStatement.java","openapi/src/com/intellij/psi/PsiExpressionStatement.java","openapi/src/com/intellij/psi/PsiExternalChangeAction.java","openapi/src/com/intellij/psi/PsiField.java","openapi/src/com/intellij/psi/PsiFile.java","openapi/src/com/intellij/psi/PsiForStatement.java","openapi/src/com/intellij/psi/PsiForeachStatement.java","openapi/src/com/intellij/psi/PsiIdentifier.java","openapi/src/com/intellij/psi/PsiIfStatement.java","openapi/src/com/intellij/psi/PsiImportHolder.java","openapi/src/com/intellij/psi/PsiImportList.java","openapi/src/com/intellij/psi/PsiImportStatement.java","openapi/src/com/intellij/psi/PsiImportStatementBase.java","openapi/src/com/intellij/psi/PsiImportStaticReferenceElement.java","openapi/src/com/intellij/psi/PsiImportStaticStatement.java","openapi/src/com/intellij/psi/PsiInlineDocTag.java","openapi/src/com/intellij/psi/PsiInstanceOfExpression.java","openapi/src/com/intellij/psi/PsiIntersectionType.java","openapi/src/com/intellij/psi/PsiJavaCodeReferenceElement.java","openapi/src/com/intellij/psi/PsiJavaFile.java","openapi/src/com/intellij/psi/PsiJavaReference.java","openapi/src/com/intellij/psi/PsiJavaToken.java","openapi/src/com/intellij/psi/PsiKeyword.java","openapi/src/com/intellij/psi/PsiLabeledStatement.java","openapi/src/com/intellij/psi/PsiLiteralExpression.java","openapi/src/com/intellij/psi/PsiLocalVariable.java","openapi/src/com/intellij/psi/PsiManager.java","openapi/src/com/intellij/psi/PsiMember.java","openapi/src/com/intellij/psi/PsiMethod.java","openapi/src/com/intellij/psi/PsiMethodCallExpression.java","openapi/src/com/intellij/psi/PsiMigration.java","openapi/src/com/intellij/psi/PsiModifier.java","openapi/src/com/intellij/psi/PsiModifierList.java","openapi/src/com/intellij/psi/PsiModifierListOwner.java","openapi/src/com/intellij/psi/PsiNameHelper.java","openapi/src/com/intellij/psi/PsiNameValuePair.java","openapi/src/com/intellij/psi/PsiNamedElement.java","openapi/src/com/intellij/psi/PsiNewExpression.java","openapi/src/com/intellij/psi/PsiPackage.java","openapi/src/com/intellij/psi/PsiPackageStatement.java","openapi/src/com/intellij/psi/PsiParameter.java","openapi/src/com/intellij/psi/PsiParameterList.java","openapi/src/com/intellij/psi/PsiParenthesizedExpression.java","openapi/src/com/intellij/psi/PsiPlainText.java","openapi/src/com/intellij/psi/PsiPlainTextFile.java","openapi/src/com/intellij/psi/PsiPostfixExpression.java","openapi/src/com/intellij/psi/PsiPrefixExpression.java","openapi/src/com/intellij/psi/PsiPrimitiveType.java","openapi/src/com/intellij/psi/PsiRecursiveElementVisitor.java","openapi/src/com/intellij/psi/PsiReference.java","openapi/src/com/intellij/psi/PsiReferenceExpression.java","openapi/src/com/intellij/psi/PsiReferenceList.java","openapi/src/com/intellij/psi/PsiReferenceParameterList.java","openapi/src/com/intellij/psi/PsiResolveHelper.java","openapi/src/com/intellij/psi/PsiReturnStatement.java","openapi/src/com/intellij/psi/PsiStatement.java","openapi/src/com/intellij/psi/PsiSubstitutor.java","openapi/src/com/intellij/psi/PsiSuperExpression.java","openapi/src/com/intellij/psi/PsiSwitchLabelStatement.java","openapi/src/com/intellij/psi/PsiSwitchStatement.java","openapi/src/com/intellij/psi/PsiSynchronizedStatement.java","openapi/src/com/intellij/psi/PsiThisExpression.java","openapi/src/com/intellij/psi/PsiThrowStatement.java","openapi/src/com/intellij/psi/PsiTreeChangeAdapter.java","openapi/src/com/intellij/psi/PsiTreeChangeEvent.java","openapi/src/com/intellij/psi/PsiTreeChangeListener.java","openapi/src/com/intellij/psi/PsiTryStatement.java","openapi/src/com/intellij/psi/PsiType.java","openapi/src/com/intellij/psi/PsiTypeCastExpression.java","openapi/src/com/intellij/psi/PsiTypeCodeFragment.java","openapi/src/com/intellij/psi/PsiTypeElement.java","openapi/src/com/intellij/psi/PsiTypeParameter.java","openapi/src/com/intellij/psi/PsiTypeParameterList.java","openapi/src/com/intellij/psi/PsiTypeParameterListOwner.java","openapi/src/com/intellij/psi/PsiTypeVisitor.java","openapi/src/com/intellij/psi/PsiVariable.java","openapi/src/com/intellij/psi/PsiWhileStatement.java","openapi/src/com/intellij/psi/PsiWhiteSpace.java","openapi/src/com/intellij/psi/PsiWildcardType.java","openapi/src/com/intellij/psi/ResolveResult.java","openapi/src/com/intellij/psi/SmartPointerManager.java","openapi/src/com/intellij/psi/SmartPsiElementPointer.java","openapi/src/com/intellij/psi/SmartTypePointer.java","openapi/src/com/intellij/psi/StringEscapesTokenTypes.java","openapi/src/com/intellij/psi/TokenType.java","openapi/src/com/intellij/psi/XmlElementVisitor.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleManager.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleScheme.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSchemes.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSettings.java","openapi/src/com/intellij/psi/codeStyle/CodeStyleSettingsManager.java","openapi/src/com/intellij/psi/codeStyle/Indent.java","openapi/src/com/intellij/psi/codeStyle/NameUtil.java","openapi/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java","openapi/src/com/intellij/psi/codeStyle/VariableKind.java","openapi/src/com/intellij/psi/html/HtmlTag.java","openapi/src/com/intellij/psi/infos/CandidateInfo.java","openapi/src/com/intellij/psi/infos/CandidatesGroup.java","openapi/src/com/intellij/psi/infos/ClassCandidateInfo.java","openapi/src/com/intellij/psi/infos/MethodCandidateInfo.java","openapi/src/com/intellij/psi/javadoc/JavadocManager.java","openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java","openapi/src/com/intellij/psi/javadoc/PsiDocComment.java","openapi/src/com/intellij/psi/javadoc/PsiDocTag.java","openapi/src/com/intellij/psi/javadoc/PsiDocTagValue.java","openapi/src/com/intellij/psi/javadoc/PsiDocToken.java","openapi/src/com/intellij/psi/jsp/JspFile.java","openapi/src/com/intellij/psi/jsp/JspImplicitVariable.java","openapi/src/com/intellij/psi/meta/PsiMetaData.java","openapi/src/com/intellij/psi/meta/PsiMetaOwner.java","openapi/src/com/intellij/psi/scope/PsiScopeProcessor.java","openapi/src/com/intellij/psi/search/GlobalSearchScope.java","openapi/src/com/intellij/psi/search/IdentifierPosition.java","openapi/src/com/intellij/psi/search/LocalSearchScope.java","openapi/src/com/intellij/psi/search/PsiElementProcessor.java","openapi/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java","openapi/src/com/intellij/psi/search/PsiReferenceProcessor.java","openapi/src/com/intellij/psi/search/PsiSearchHelper.java","openapi/src/com/intellij/psi/search/PsiSearchScopeUtil.java","openapi/src/com/intellij/psi/search/PsiShortNamesCache.java","openapi/src/com/intellij/psi/search/SearchScope.java","openapi/src/com/intellij/psi/search/TodoAttributes.java","openapi/src/com/intellij/psi/search/TodoItem.java","openapi/src/com/intellij/psi/search/TodoPattern.java","openapi/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScope.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScopeManager.java","openapi/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java","openapi/src/com/intellij/psi/search/scope/packageSet/PackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/PackageSetFactory.java","openapi/src/com/intellij/psi/search/scope/packageSet/ParsingException.java","openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java","openapi/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java","openapi/src/com/intellij/psi/statistics/StatisticsManager.java","openapi/src/com/intellij/psi/tree/IElementType.java","openapi/src/com/intellij/psi/tree/TokenSet.java","openapi/src/com/intellij/psi/tree/java/IJavaDocElementType.java","openapi/src/com/intellij/psi/tree/java/IJavaElementType.java","openapi/src/com/intellij/psi/tree/java/IKeywordElementType.java","openapi/src/com/intellij/psi/tree/jsp/IJspElementType.java","openapi/src/com/intellij/psi/tree/xml/IDTDElementType.java","openapi/src/com/intellij/psi/tree/xml/IXmlElementType.java","openapi/src/com/intellij/psi/util/ConstantEvaluationOverflowException.java","openapi/src/com/intellij/psi/util/ConstantExpressionUtil.java","openapi/src/com/intellij/psi/util/InheritanceUtil.java","openapi/src/com/intellij/psi/util/IsConstantExpressionVisitor.java","openapi/src/com/intellij/psi/util/MethodSignature.java","openapi/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java","openapi/src/com/intellij/psi/util/MethodSignatureBase.java","openapi/src/com/intellij/psi/util/MethodSignatureHandMade.java","openapi/src/com/intellij/psi/util/MethodSignatureUtil.java","openapi/src/com/intellij/psi/util/PropertyUtil.java","openapi/src/com/intellij/psi/util/PsiElementFilter.java","openapi/src/com/intellij/psi/util/PsiFormatUtil.java","openapi/src/com/intellij/psi/util/PsiMatcher.java","openapi/src/com/intellij/psi/util/PsiMatcherExpression.java","openapi/src/com/intellij/psi/util/PsiMatcherImpl.java","openapi/src/com/intellij/psi/util/PsiModificationTracker.java","openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java","openapi/src/com/intellij/psi/util/PsiTreeUtil.java","openapi/src/com/intellij/psi/util/PsiUtil.java","openapi/src/com/intellij/psi/util/TypeConversionUtil.java","openapi/src/com/intellij/psi/xml/XmlAttlistDecl.java","openapi/src/com/intellij/psi/xml/XmlAttribute.java","openapi/src/com/intellij/psi/xml/XmlAttributeDecl.java","openapi/src/com/intellij/psi/xml/XmlAttributeValue.java","openapi/src/com/intellij/psi/xml/XmlComment.java","openapi/src/com/intellij/psi/xml/XmlDecl.java","openapi/src/com/intellij/psi/xml/XmlDoctype.java","openapi/src/com/intellij/psi/xml/XmlDocument.java","openapi/src/com/intellij/psi/xml/XmlElement.java","openapi/src/com/intellij/psi/xml/XmlElementContentSpec.java","openapi/src/com/intellij/psi/xml/XmlElementDecl.java","openapi/src/com/intellij/psi/xml/XmlEntityDecl.java","openapi/src/com/intellij/psi/xml/XmlEntityRef.java","openapi/src/com/intellij/psi/xml/XmlEnumeratedType.java","openapi/src/com/intellij/psi/xml/XmlFile.java","openapi/src/com/intellij/psi/xml/XmlMarkupDecl.java","openapi/src/com/intellij/psi/xml/XmlNotationDecl.java","openapi/src/com/intellij/psi/xml/XmlProcessingInstruction.java","openapi/src/com/intellij/psi/xml/XmlProlog.java","openapi/src/com/intellij/psi/xml/XmlTag.java","openapi/src/com/intellij/psi/xml/XmlTagChild.java","openapi/src/com/intellij/psi/xml/XmlTagValue.java","openapi/src/com/intellij/psi/xml/XmlText.java","openapi/src/com/intellij/psi/xml/XmlToken.java","openapi/src/com/intellij/psi/xml/XmlTokenType.java","openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java","openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java","openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java","openapi/src/com/intellij/refactoring/MoveDestination.java","openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java","openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java","openapi/src/com/intellij/refactoring/PackageWrapper.java","openapi/src/com/intellij/refactoring/Refactoring.java","openapi/src/com/intellij/refactoring/RefactoringActionHandler.java","openapi/src/com/intellij/refactoring/RefactoringActionHandlerFactory.java","openapi/src/com/intellij/refactoring/RefactoringFactory.java","openapi/src/com/intellij/refactoring/RenameRefactoring.java","openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java","openapi/src/com/intellij/refactoring/SafeDeleteRefactoring.java","openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java","openapi/src/com/intellij/refactoring/TypeCookRefactoring.java","openapi/src/com/intellij/refactoring/listeners/RefactoringElementListener.java","openapi/src/com/intellij/refactoring/listeners/RefactoringElementListenerProvider.java","openapi/src/com/intellij/refactoring/listeners/RefactoringListenerManager.java","openapi/src/com/intellij/refactoring/util/MoveRenameUsageInfo.java","openapi/src/com/intellij/refactoring/util/NonCodeUsageInfo.java","openapi/src/com/intellij/ui/AbstractBox.java","openapi/src/com/intellij/ui/AbstractFieldPanel.java","openapi/src/com/intellij/ui/ColoredListCellRenderer.java","openapi/src/com/intellij/ui/ColoredTreeCellRenderer.java","openapi/src/com/intellij/ui/ComboBoxFieldPanel.java","openapi/src/com/intellij/ui/ComboboxWithBrowseButton.java","openapi/src/com/intellij/ui/CommandButtonGroup.java","openapi/src/com/intellij/ui/DocumentAdapter.java","openapi/src/com/intellij/ui/FieldPanel.java","openapi/src/com/intellij/ui/FilteringListModel.java","openapi/src/com/intellij/ui/GuiUtils.java","openapi/src/com/intellij/ui/IdeBorderFactory.java","openapi/src/com/intellij/ui/InsertPathAction.java","openapi/src/com/intellij/ui/JScrollPane2.java","openapi/src/com/intellij/ui/LayeredIcon.java","openapi/src/com/intellij/ui/ListScrollingUtil.java","openapi/src/com/intellij/ui/ListUtil.java","openapi/src/com/intellij/ui/OptionGroup.java","openapi/src/com/intellij/ui/OrderPanel.java","openapi/src/com/intellij/ui/OrderPanelListener.java","openapi/src/com/intellij/ui/PanelWithButtons.java","openapi/src/com/intellij/ui/PopupHandler.java","openapi/src/com/intellij/ui/RawCommandLineEditor.java","openapi/src/com/intellij/ui/ReorderableListController.java","openapi/src/com/intellij/ui/RoundedLineBorder.java","openapi/src/com/intellij/ui/ScrollPaneFactory.java","openapi/src/com/intellij/ui/SimpleColoredComponent.java","openapi/src/com/intellij/ui/SimpleColoredRenderer.java","openapi/src/com/intellij/ui/SimpleTextAttributes.java","openapi/src/com/intellij/ui/SortedListModel.java","openapi/src/com/intellij/ui/TableCellState.java","openapi/src/com/intellij/ui/TextFieldWithHistory.java","openapi/src/com/intellij/ui/UIHelper.java","openapi/src/com/intellij/ui/UserActivityListener.java","openapi/src/com/intellij/ui/UserActivityWatcher.java","openapi/src/com/intellij/ui/content/Content.java","openapi/src/com/intellij/ui/content/ContentFactory.java","openapi/src/com/intellij/ui/content/ContentManager.java","openapi/src/com/intellij/ui/content/ContentManagerAdapter.java","openapi/src/com/intellij/ui/content/ContentManagerEvent.java","openapi/src/com/intellij/ui/content/ContentManagerListener.java","openapi/src/com/intellij/ui/content/ContentUI.java","openapi/src/com/intellij/ui/dualView/CellWrapper.java","openapi/src/com/intellij/ui/dualView/DualTreeElement.java","openapi/src/com/intellij/ui/dualView/DualView.java","openapi/src/com/intellij/ui/dualView/TreeTableView.java","openapi/src/com/intellij/ui/errorView/ContentManagerProvider.java","openapi/src/com/intellij/ui/errorView/ErrorViewFactory.java","openapi/src/com/intellij/ui/table/BaseTableView.java","openapi/src/com/intellij/ui/table/ItemsProvider.java","openapi/src/com/intellij/ui/table/SelectionProvider.java","openapi/src/com/intellij/ui/table/TableHeaderRenderer.java","openapi/src/com/intellij/ui/table/TableView.java","openapi/src/com/intellij/unscramble/UnscrambleSupport.java","openapi/src/com/intellij/usageView/UsageInfo.java","openapi/src/com/intellij/usageView/UsageTreeColors.java","openapi/src/com/intellij/usageView/UsageTreeColorsScheme.java","openapi/src/com/intellij/usageView/UsageViewDescriptor.java","openapi/src/com/intellij/usageView/UsageViewManager.java","openapi/src/com/intellij/util/Alarm.java","openapi/src/com/intellij/util/CharTable.java","openapi/src/com/intellij/util/CommonProcessors.java","openapi/src/com/intellij/util/EditSourceOnDoubleClickHandler.java","openapi/src/com/intellij/util/EditSourceOnEnterKeyHandler.java","openapi/src/com/intellij/util/EnvironmentUtil.java","openapi/src/com/intellij/util/Generator.java","openapi/src/com/intellij/util/IconUtil.java","openapi/src/com/intellij/util/Icons.java","openapi/src/com/intellij/util/Options.java","openapi/src/com/intellij/util/PathUtil.java","openapi/src/com/intellij/util/PathsList.java","openapi/src/com/intellij/util/Processor.java","openapi/src/com/intellij/util/WeakListener.java","openapi/src/com/intellij/util/concurrency/Mutex.java","openapi/src/com/intellij/util/concurrency/ReadWriteLock.java","openapi/src/com/intellij/util/concurrency/ReentrantLock.java","openapi/src/com/intellij/util/concurrency/ReentrantLock2.java","openapi/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java","openapi/src/com/intellij/util/concurrency/Semaphore.java","openapi/src/com/intellij/util/concurrency/SwingWorker.java","openapi/src/com/intellij/util/concurrency/Sync.java","openapi/src/com/intellij/util/concurrency/Sync2.java","openapi/src/com/intellij/util/concurrency/WorkerThread.java","openapi/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java","openapi/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java","openapi/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java","openapi/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java","openapi/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java","openapi/src/com/intellij/util/config/Storage.java","openapi/src/com/intellij/util/io/ReadOnlyAttributeUtil.java","openapi/src/com/intellij/util/ui/ErrorTreeView.java","openapi/src/com/intellij/util/ui/FileLabel.java","openapi/src/com/intellij/util/ui/FilePathSplittingPolicy.java","openapi/src/com/intellij/util/ui/MessageCategory.java","openapi/src/com/intellij/util/ui/SplitByLetterPolicy.java","openapi/src/com/intellij/util/ui/SplitBySeparatorPolicy.java","openapi/src/com/intellij/util/ui/tree/IndexTreePathState.java","openapi/src/com/intellij/util/ui/tree/TreePathState.java","openapi/src/com/intellij/util/ui/tree/TreeUtil.java","openapi/src/com/intellij/vcsUtil/VcsSelection.java","openapi/src/com/intellij/vcsUtil/VcsUtil.java","openapi/src/com/intellij/xml/XmlAttributeDescriptor.java","openapi/src/com/intellij/xml/XmlElementDescriptor.java","openapi/src/com/intellij/xml/XmlNSDescriptor.java","openapi/src/com/intellij/xml/util/XmlTagTextUtil.java","plugins/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java","plugins/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesProvider.java","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight/intention/ConditionalOperatorConvertor.java","plugins/conditionalOperatorConvertor/testSrc/com/intellij/codeInsight/ConditionalToIfTest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/CvsRoot.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IClientEnvironment.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IConnectionStreams.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ICvsCommandStopper.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ICvsRootProvider.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/IRequestProcessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/RequestProcessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ResponseService.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/ValidRequestsExpectedException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/Entry.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/IAdminReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/IAdminWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin/InvalidEntryFormatException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/AbstractParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/Command.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandAbortedException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CommandUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CvsFile.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/CvsFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DefaultEntryParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DefaultFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/DirectoryPruner.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/FileObjects.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/FileSystemScanner.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/GlobalOptions.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/ICvsFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/ICvsFilesVisitor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IGlobalOptions.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IOCommandException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/IUpdatingCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/KeywordSubstitution.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/LocalFiles.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/Watch.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add/AddCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add/AddParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateLine.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate/AnnotateMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/CheckoutCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ExpandedModules.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/Module.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit/CommitCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit/CommitParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/importcmd/ImportCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/LogMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/Revision.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log/SymbolicName.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove/RemoveCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove/RemoveParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditEditorsMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsFileInfoContainer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/EditorsMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/TabStringTokenizer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout/UneditCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusInformation.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status/StatusMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag/TagCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag/TagParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdateMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update/UpdatedFileInfo.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch/WatchCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch/WatchMode.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watchers/WatchersCommand.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/AuthenticationException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/ConnectionSettings.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/IConnection.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/PServerConnection.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/PServerPasswordScrambler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection/UnknownUserException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/DualListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/EventManager.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ICvsListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ICvsListenerRegistry.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IDirectoryListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IEntryListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IEventSender.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IFileInfoListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IMessageListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/IModuleExpansionListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/ITerminationListener.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event/TaggedMessageParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/AbstractFileObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/DirectoryObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileDetails.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileObject.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileStatus.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/FileUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ICvsFileSystem.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IFileReadOnlyHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IFileSystem.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ILocalFileReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ILocalFileWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IReaderFactory.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IReceiveTextFilePreprocessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/ISendTextFilePreprocessor.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/IWriterFactory.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file/OutOfFileSystemException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AbstractInputStreamReader.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AbstractOutputStreamWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/AsciiOutputStreamWriter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/EncodingException.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/IStreamLogger.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io/StreamUtilities.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/IProgressViewer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/RangeProgressViewer.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/AbstractResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/FileInfoAndDirectoryResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving/FileInfoAndMessageResponseProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/DummyRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/FileStateRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending/IRequestsProgressHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/AbstractFileStateRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/AbstractRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ArgumentRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ArgumentxRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/CaseRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/CommandRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/DirectoryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/EntryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ExpandModulesRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/GlobalOptionRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/GzipStreamRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/IRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/IsModifiedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/KoptRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/LocalDirectoryRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ModifiedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/NotifyRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/QuestionableRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/Requests.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ResponseExpectingRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/RootRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/SetRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/StickyRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/UnchangedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/UseUnchangedRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ValidRequestsRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request/ValidResponsesRequest.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/AbstractResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/DefaultResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/IResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/IResponseServices.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ResponseParser.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ResponseUtils.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response/ValidRequestsResponseHandler.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/BugLog.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/IIgnoreFileFilter.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/IStringPattern.java","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util/SimpleStringPattern.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/ConnectionSettingsImpl.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SmPublicKeyAuthentification.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SolveableAuthenticationException.java","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick/SshTypesToUse.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/ClientEnvironment.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminReader.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminUtils.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/AdminWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/DateComparator.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/DummyAdminWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/EntriesDotLog.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin/EntriesHandler.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin/AdminCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin/ChangeKeywordSubstCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/impord/CreateModuleCommand.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/CvsFileSystem.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/DummyLocalFileWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/FileSystem.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/LocalFileReader.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file/LocalFileWriter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util/AllIgnoreFileFilter.java","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util/DefaultIgnoreFileFilter.java","plugins/cvs2/source/com/intellij/cvsSupport2/Cvs2Configurable.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsActionPlaces.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsResultEx.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsStandardOperationsProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsStatusEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsUpdateEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsUtil.java","plugins/cvs2/source/com/intellij/cvsSupport2/CvsVcs2.java","plugins/cvs2/source/com/intellij/cvsSupport2/UpdateConfigurable.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbstractAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbstractWatchAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AbsttractWatchOnOffAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ActionOnSelectedElement.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AddFileOrDirectoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AnnotateToggleAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/AsbtractActionFromEditGroup.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/BranchAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/BrowseCvsRepositoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CheckoutAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CheckoutFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ConfigureCvsRootsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CreateTagAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/Cvs2Group.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/CvsGlobalAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/DeleteTagAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/EditAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/GetFileFromRepositoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/GlobalSettingsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/IgnoreFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ImportAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RemoveLocallyDeletedFilesAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RemoveLocallyFileOrDirectoryAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/RestoreFileAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/UneditAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/UnmarkAddedAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ViewEditorsAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/ViewWatchersAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchAddAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchOffAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchOnAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/WatchRemoveAction.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/actionVisibility/CvsActionVisibility.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CashedCvsContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContextAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext/CvsLightweightFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateByBranchUpdateSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update/UpdateSettingsOnCvsConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/AddHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsEntriesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsStorageComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/CvsStorageSupportingDeletionComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/DeleteHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/application/DeletedCVSDirectoryStorage.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/AdditionalOptionsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsCheckinEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsDiffColors.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/CvsRollbacker.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/DirectoryContent.java","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject/VirtualFileEntry.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/AbstractConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsApplicationLevelConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/CvsRootConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/DateOrRevisionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ExtConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ImportConfiguration.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/LocalSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ProxySettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/ConfigureCvsGlobalSettingsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsListCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsRootAsStringConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/CvsRootFieldByFieldConfigurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/GlobalCvsSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/SelectCvsConfgurationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui/SelectCvsConfigurationDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ConnectionOnProcess.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ConnectionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsMethod.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootData.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootOnEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootOnFileSystem.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootParser.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/CvsRootProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/RootFormatter.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/SelfTestingConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/SelfTestingConnectionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtConnectionCvsSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ExtLoginProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/LocalConnection.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/LocalConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/ui/LocalConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerCvsSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerLoginProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/PServerLoginProviderImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/ui/PServerSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/SSHPasswordProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/SshConnectionSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui/SshConnectionSettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui/SshPasswordDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ui/ProxySettingsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/consoleView/EditorAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CheckoutHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/Cvs2Renderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsElementFactory.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsModule.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsTree.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/CvsTreeModel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/FolderDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/GetContentCallback.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/LoginAbortedException.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ModuleDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/RemoteResourceDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution/ModalityContext.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoreFileFilter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoreFileFilterBasedOnCvsEntriesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoredFilesInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/IgnoredFilesInfoImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore/UserDirIgnores.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AbstractCvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AllFilesInProject.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/AnyProcessedFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CheckoutHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CommandCvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsMessagePattern.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsMessagesConsole.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/CvsUpdatePolicy.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/FileSetToBeUpdated.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/SelectedFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers/UpdateHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CompositeOperaton.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CreateFileObjects.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsExecutionEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/CvsOperationOnFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/FindAllRoots.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/LocalPathIndifferentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/LocalPathIndifferentOperationHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/PostCvsActivity.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/ReceivedFileProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/RepositoryModificationOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/RepositoryPathProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common/UpdatedFilesManager.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddFileOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/AddedFileInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AbstractAddFileConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AbstractAddOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddDirectoryConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddFileConfirmationPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddMultiplyFilesOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddOneFileOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui/AddedFileCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate/AnnotateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate/Annotation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutAdminReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFileByRevisionOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFileOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui/CheckoutFileDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui/FileCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCommit/CommitFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContent.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetFileContentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditorInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/EditorsOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/UneditOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditCvsConfigurationFieldByFieldDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditOptionsDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui/EditorsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors/ErrorMessagesProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors/ErrorProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport/ImportDetails.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport/ImportOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/LocalPathIndifferentLogOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/LogOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog/RlogCommand.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsCompositeListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsListenerWithProgress.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsListenersCollection.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesAdapter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/CvsMessagesTranslator.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/FileMessage.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages/MessageEvent.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsRemove/RemoveFilesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/BranchOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/BranchesProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/RTagOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/RtagCommand.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsHelper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnVirtualFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/CreateTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/CvsTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/DeleteTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/SelectTagDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/TagNameFieldOwner.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui/TagsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/MergedWithConflictProjectOrModuleFile.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/UpdateOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/UpdateReceivedFileProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui/CorruptedProjectFilesDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui/UpdateOptionsPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatchOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatcherInfo.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/WatchersOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui/WatcherDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui/WatchersPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/CommandWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDate.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/RevisionOrDateImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/SimpleRevision.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/CalendarView.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/DateOrRevisionOrTagSettings.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui/IntegerSpinnerModel.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderForLightFiles.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderOnCache.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminReaderOnStoredRepositoryPath.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminWriterOnCache.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/AdminWriterStoringRepositoryPath.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/ConstantLocalFileReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/DeafAdminReader.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls/DeafAdminWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses/CvsEntriesListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses/CvsStatusProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CannotFindCvsRootException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CvsException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/CvsProcessException.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/ErrorRegistry.java","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling/InvalidModuleDescriptionException.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/ComparableVcsRevisionOnOperation.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsFileRevision.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsFileRevisionImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsHistoryProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/history/CvsRevisionNumber.java","plugins/cvs2/source/com/intellij/cvsSupport2/impl/CvsServicesImpl.java","plugins/cvs2/source/com/intellij/cvsSupport2/impl/ModuleChooser.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/CvsCommandStopper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/FileReadOnlyHandler.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/ProjectContentInfoProvider.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/DeafLocalFileWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/InputStreamWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/LocalFileReaderBasedOnVFS.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/OutputStreamWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReadThread.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReadWriteStatistics.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/ReceiveTextFilePreprocessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/SendTextFilePreprocessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/StoringLineSeparatorsLocalFileWriter.java","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io/StreamLogger.java","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution/KeywordSubstitutionListWithSelection.java","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution/KeywordSubstitutionWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/AbstractListCellRenderer.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/ChangeKeywordSubstitutionPanel.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsRootChangeListener.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsTabbedWindow.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/KeywordSubstitutionComboBoxWrapper.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/Options.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/PasswordPromptDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/RestoreDirectoriesConfirmationDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/SelectFileVersionDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/SelectFromListDialog.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/CvsWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectCVSConfigurationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/SelectLocationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/WizardStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutFolderToTheSameFolder.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutToTheDirectoryWithModuleName.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/CreateDirectoryForFolderStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout/SimpleCheckoutStrategy.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/CvsFieldValidator.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/FileExtension.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportSettingsStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportTree.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/ImportWizard.java","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs/SelectImportLocationStep.java","plugins/cvs2/source/com/intellij/cvsSupport2/updateinfo/UpdatedFilesProcessor.java","plugins/cvs2/source/com/intellij/cvsSupport2/util/CvsFileUtil.java","plugins/cvs2/source/com/intellij/cvsSupport2/util/CvsVfsUtil.java","plugins/debuggerCommonViews/src/actions/ShowAllAs.java","plugins/debuggerCommonViews/src/actions/ShowAllAsDecimal.java","plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java","pom/src/com/intellij/pom/PomElement.java","pom/src/com/intellij/pom/PomModel.java","pom/src/com/intellij/pom/PomModelAspect.java","pom/src/com/intellij/pom/PomPresentation.java","pom/src/com/intellij/pom/PomTransaction.java","pom/src/com/intellij/pom/Presentable.java","pom/src/com/intellij/pom/event/PomChangeSet.java","pom/src/com/intellij/pom/event/PomModelEvent.java","pom/src/com/intellij/pom/event/PomModelListener.java","runtimesource/FormPreviewFrame.java","runtimesource/com/intellij/rt/ant/execution/AntMain2.java","runtimesource/com/intellij/rt/ant/execution/IdeaAntLogger2.java","runtimesource/com/intellij/rt/ant/execution/IdeaInputHandler.java","runtimesource/com/intellij/rt/ant/execution/PacketFactory.java","runtimesource/com/intellij/rt/compiler/JavacRunner.java","runtimesource/com/intellij/rt/debugger/BatchEvaluatorServer.java","runtimesource/com/intellij/rt/execution/application/AppMain.java","runtimesource/com/intellij/rt/execution/application/MainAppClassLoader.java","runtimesource/com/intellij/rt/execution/junit/IdeaTestRunner.java","runtimesource/com/intellij/rt/execution/junit/TestAllInPackage2.java","runtimesource/com/intellij/rt/execution/junit/TestRunnerUtil.java","runtimesource/com/intellij/rt/execution/junit2/ComparisonDetailsExtractor.java","runtimesource/com/intellij/rt/execution/junit2/DeafStream.java","runtimesource/com/intellij/rt/execution/junit2/ExceptionPacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/FileComparisonFailure.java","runtimesource/com/intellij/rt/execution/junit2/JUnitStarter.java","runtimesource/com/intellij/rt/execution/junit2/KnownException.java","runtimesource/com/intellij/rt/execution/junit2/PacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/RunOnce.java","runtimesource/com/intellij/rt/execution/junit2/TestMeter.java","runtimesource/com/intellij/rt/execution/junit2/TestResultsSender.java","runtimesource/com/intellij/rt/execution/junit2/TreeSender.java","runtimesource/com/intellij/rt/execution/junit2/segments/EchoOutputStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/OutputObjectRegistry.java","runtimesource/com/intellij/rt/execution/junit2/segments/OutputObjectRegistryImpl.java","runtimesource/com/intellij/rt/execution/junit2/segments/Packet.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketFactory.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketProcessor.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketProcessors.java","runtimesource/com/intellij/rt/execution/junit2/segments/PacketWriter.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfDelimiters.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfKnownObjects.java","runtimesource/com/intellij/rt/execution/junit2/segments/PoolOfTestTypes.java","runtimesource/com/intellij/rt/execution/junit2/segments/SegmentedOutputStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/SegmentedStream.java","runtimesource/com/intellij/rt/execution/junit2/segments/TraceFilter.java","runtimesource/com/intellij/rt/execution/junit2/states/PoolOfTestStates.java","source/com/intellij/analysis/AnalysisScope.java","source/com/intellij/analysis/BaseAnalysisAction.java","source/com/intellij/application/options/CodeCompletionOptions.java","source/com/intellij/application/options/CodeCompletionPanel.java","source/com/intellij/application/options/CodeStyleBlankLinesConfigurable.java","source/com/intellij/application/options/CodeStyleBlankLinesPanel.java","source/com/intellij/application/options/CodeStyleGeneralConfigurable.java","source/com/intellij/application/options/CodeStyleImportsConfigurable.java","source/com/intellij/application/options/CodeStyleImportsPanel.java","source/com/intellij/application/options/CodeStyleIndentAndBracesConfigurable.java","source/com/intellij/application/options/CodeStyleIndentAndBracesPanel.java","source/com/intellij/application/options/CodeStyleSchemesConfigurable.java","source/com/intellij/application/options/CodeStyleSpacesConfigurable.java","source/com/intellij/application/options/CodeStyleSpacesPanel.java","source/com/intellij/application/options/CodeStyleXmlConfigurable.java","source/com/intellij/application/options/CodeStyleXmlPanel.java","source/com/intellij/application/options/EditorOptions.java","source/com/intellij/application/options/EditorOptionsPanel.java","source/com/intellij/application/options/ErrorHighlightingPanel.java","source/com/intellij/application/options/JavaDocFormattingPanel.java","source/com/intellij/application/options/JavadocFormatConfigurable.java","source/com/intellij/application/options/OptionTableWithPreviewPanel.java","source/com/intellij/application/options/OptionTreeWithPreviewPanel.java","source/com/intellij/application/options/PathMacros.java","source/com/intellij/application/options/ReplacePathToMacroMap.java","source/com/intellij/application/options/SaveSchemeDialog.java","source/com/intellij/application/options/SelectFontDialog.java","source/com/intellij/application/options/WrappingConfigurable.java","source/com/intellij/application/options/WrappingPanel.java","source/com/intellij/application/options/colors/ClickNavigator.java","source/com/intellij/application/options/colors/ColorAndFontDescription.java","source/com/intellij/application/options/colors/ColorAndFontDescriptionPanel.java","source/com/intellij/application/options/colors/ColorAndFontOptions.java","source/com/intellij/application/options/colors/EditorSchemeAttributeDescriptor.java","source/com/intellij/application/options/colors/TailPanel.java","source/com/intellij/application/options/colors/TextAttributesDescription.java","source/com/intellij/application/options/colors/highlighting/HighlightData.java","source/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java","source/com/intellij/application/options/pathMacros/PathMacroConfigurable.java","source/com/intellij/application/options/pathMacros/PathMacroEditor.java","source/com/intellij/application/options/pathMacros/PathMacroListEditor.java","source/com/intellij/application/options/pathMacros/PathMacroTable.java","source/com/intellij/codeEditor/printing/ExportToHTMLAction.java","source/com/intellij/codeEditor/printing/ExportToHTMLDialog.java","source/com/intellij/codeEditor/printing/ExportToHTMLManager.java","source/com/intellij/codeEditor/printing/ExportToHTMLSettings.java","source/com/intellij/codeEditor/printing/HTMLTextPainter.java","source/com/intellij/codeEditor/printing/MultiFilePainter.java","source/com/intellij/codeEditor/printing/PageSizes.java","source/com/intellij/codeEditor/printing/PrintAction.java","source/com/intellij/codeEditor/printing/PrintDialog.java","source/com/intellij/codeEditor/printing/PrintManager.java","source/com/intellij/codeEditor/printing/PrintSettings.java","source/com/intellij/codeEditor/printing/TextPainter.java","source/com/intellij/codeFormatting/general/FormatterUtil.java","source/com/intellij/codeInsight/AutoPopupController.java","source/com/intellij/codeInsight/ChangeContextUtil.java","source/com/intellij/codeInsight/CodeInsightActionHandler.java","source/com/intellij/codeInsight/CodeInsightColors.java","source/com/intellij/codeInsight/CodeInsightSettings.java","source/com/intellij/codeInsight/CodeInsightUtil.java","source/com/intellij/codeInsight/ExceptionUtil.java","source/com/intellij/codeInsight/ExpectedTypeInfoImpl.java","source/com/intellij/codeInsight/ExpectedTypeUtil.java","source/com/intellij/codeInsight/PopupActionChooser.java","source/com/intellij/codeInsight/TailType.java","source/com/intellij/codeInsight/TargetElementUtil.java","source/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java","source/com/intellij/codeInsight/actions/BaseCodeInsightAction.java","source/com/intellij/codeInsight/actions/GenerateDTDAction.java","source/com/intellij/codeInsight/actions/LayoutCodeDialog.java","source/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java","source/com/intellij/codeInsight/actions/OptimizeImportsAction.java","source/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java","source/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java","source/com/intellij/codeInsight/actions/ReformatCodeAction.java","source/com/intellij/codeInsight/actions/ReformatCodeProcessor.java","source/com/intellij/codeInsight/completion/BasicInsertHandler.java","source/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java","source/com/intellij/codeInsight/completion/CompletionContext.java","source/com/intellij/codeInsight/completion/CompletionData.java","source/com/intellij/codeInsight/completion/CompletionPreferencePolicy.java","source/com/intellij/codeInsight/completion/CompletionUtil.java","source/com/intellij/codeInsight/completion/CompletionVariant.java","source/com/intellij/codeInsight/completion/DefaultCharFilter.java","source/com/intellij/codeInsight/completion/DefaultInsertHandler.java","source/com/intellij/codeInsight/completion/DocAnalyzer.java","source/com/intellij/codeInsight/completion/DotAutoLookupHandler.java","source/com/intellij/codeInsight/completion/HtmlCompletionData.java","source/com/intellij/codeInsight/completion/InsertHandler.java","source/com/intellij/codeInsight/completion/Java15CompletionData.java","source/com/intellij/codeInsight/completion/JavaCompletionData.java","source/com/intellij/codeInsight/completion/JavaDocCompletionData.java","source/com/intellij/codeInsight/completion/JavadocAutoLookupHandler.java","source/com/intellij/codeInsight/completion/KeywordChooser.java","source/com/intellij/codeInsight/completion/LookupHandler.java","source/com/intellij/codeInsight/completion/ModifierChooser.java","source/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java","source/com/intellij/codeInsight/completion/XHtmlCompletionData.java","source/com/intellij/codeInsight/completion/XmlAutoLookupHandler.java","source/com/intellij/codeInsight/completion/XmlCharFilter.java","source/com/intellij/codeInsight/completion/XmlCompletionData.java","source/com/intellij/codeInsight/completion/actions/ClassNameCompletionAction.java","source/com/intellij/codeInsight/completion/actions/CodeCompletionAction.java","source/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java","source/com/intellij/codeInsight/completion/actions/SmartCodeCompletionAction.java","source/com/intellij/codeInsight/completion/proc/VariablesProcessor.java","source/com/intellij/codeInsight/completion/scope/CompletionElement.java","source/com/intellij/codeInsight/completion/scope/CompletionProcessor.java","source/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java","source/com/intellij/codeInsight/daemon/DaemonCodeAnalyzerSettings.java","source/com/intellij/codeInsight/daemon/HighlightDisplayKey.java","source/com/intellij/codeInsight/daemon/InspectionProfileConvertor.java","source/com/intellij/codeInsight/daemon/QuickFixProvider.java","source/com/intellij/codeInsight/daemon/impl/AddNoInspectionCommentAction.java","source/com/intellij/codeInsight/daemon/impl/AddNoInspectionDocTagAction.java","source/com/intellij/codeInsight/daemon/impl/CodeFoldingPass.java","source/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java","source/com/intellij/codeInsight/daemon/impl/DaemonTooltipUtil.java","source/com/intellij/codeInsight/daemon/impl/EditorTracker.java","source/com/intellij/codeInsight/daemon/impl/EditorTrackerListener.java","source/com/intellij/codeInsight/daemon/impl/ErrorStripeHandler.java","source/com/intellij/codeInsight/daemon/impl/FileStatusMap.java","source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/GotoNextErrorHandler.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfo.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoComposite.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoFilter.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoFilterImpl.java","source/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java","source/com/intellij/codeInsight/daemon/impl/HighlightVisitor.java","source/com/intellij/codeInsight/daemon/impl/LineMarkerInfo.java","source/com/intellij/codeInsight/daemon/impl/LineMarkerNavigator.java","source/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java","source/com/intellij/codeInsight/daemon/impl/OverridenMarkersPass.java","source/com/intellij/codeInsight/daemon/impl/Pass.java","source/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java","source/com/intellij/codeInsight/daemon/impl/RefCountHolder.java","source/com/intellij/codeInsight/daemon/impl/RefreshStatusRenderer.java","source/com/intellij/codeInsight/daemon/impl/ShowErrorDescriptionHandler.java","source/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java","source/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java","source/com/intellij/codeInsight/daemon/impl/TextEditorBackgroundHighlighter.java","source/com/intellij/codeInsight/daemon/impl/TextEditorHighlightingPass.java","source/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java","source/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java","source/com/intellij/codeInsight/daemon/impl/actions/GotoNextErrorAction.java","source/com/intellij/codeInsight/daemon/impl/actions/GotoPreviousErrorAction.java","source/com/intellij/codeInsight/daemon/impl/actions/ShowErrorDescriptionAction.java","source/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/ClassUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java","source/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java","source/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddDefaultConstructorFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToThrowsAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodBodyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/AdjustPackageNameFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/BringVariableIntoScopeAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CastConstructorParametersFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodParametersFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstantFieldFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorMatchingSuperAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/CreateVarFromUsageAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeferFinalAssignmentFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMethodBodyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java","source/com/intellij/codeInsight/daemon/impl/quickfix/EnableOptimizeImportsOnTheFlyFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ExtendsListFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/GuessTypeParameters.java","source/com/intellij/codeInsight/daemon/impl/quickfix/IgnoreExtResourceAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/InsertNewFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/InsertSuperFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeClassInterfaceFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeMethodConstructorFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MakeVarargParameterLastFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodParameterFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveBoundClassToFrontFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToSeparateFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/MoveToPackageFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/OptimizeImportsFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveNewQualifierFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantElseAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedParameterFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenamePublicClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchAction.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java","source/com/intellij/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java","source/com/intellij/codeInsight/editorActions/BackspaceHandler.java","source/com/intellij/codeInsight/editorActions/CodeBlockEndAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockEndWithSelectionAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockStartAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockStartWithSelectionAction.java","source/com/intellij/codeInsight/editorActions/CodeBlockUtil.java","source/com/intellij/codeInsight/editorActions/CopyHandler.java","source/com/intellij/codeInsight/editorActions/CutHandler.java","source/com/intellij/codeInsight/editorActions/EndHandler.java","source/com/intellij/codeInsight/editorActions/EnterHandler.java","source/com/intellij/codeInsight/editorActions/HtmlSelectioner.java","source/com/intellij/codeInsight/editorActions/JoinLinesHandler.java","source/com/intellij/codeInsight/editorActions/PasteHandler.java","source/com/intellij/codeInsight/editorActions/RestoreReferencesDialog.java","source/com/intellij/codeInsight/editorActions/SelectWordHandler.java","source/com/intellij/codeInsight/editorActions/SelectWordUtil.java","source/com/intellij/codeInsight/editorActions/TextBlockTransferable.java","source/com/intellij/codeInsight/editorActions/TypedHandler.java","source/com/intellij/codeInsight/editorActions/UnSelectWordHandler.java","source/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/BreakingControlFlowEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/CompletionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/EnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingForBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/MissingWhileBodyFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java","source/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterAction.java","source/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java","source/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java","source/com/intellij/codeInsight/folding/CodeFoldingManager.java","source/com/intellij/codeInsight/folding/CodeFoldingState.java","source/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java","source/com/intellij/codeInsight/folding/impl/CodeFoldingSettings.java","source/com/intellij/codeInsight/folding/impl/CollapseAllRegionsHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseExpandJavadocsHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseRegionHandler.java","source/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java","source/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java","source/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java","source/com/intellij/codeInsight/folding/impl/ExpandAllRegionsHandler.java","source/com/intellij/codeInsight/folding/impl/ExpandRegionHandler.java","source/com/intellij/codeInsight/folding/impl/FoldingPolicy.java","source/com/intellij/codeInsight/folding/impl/FoldingUpdate.java","source/com/intellij/codeInsight/folding/impl/FoldingUtil.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseAllRegionsAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseJavadocsAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseRegionAction.java","source/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandAllRegionsAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandJavadocsAction.java","source/com/intellij/codeInsight/folding/impl/actions/ExpandRegionAction.java","source/com/intellij/codeInsight/folding/impl/actions/FoldingGroup.java","source/com/intellij/codeInsight/generation/AutoIndentLinesHandler.java","source/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java","source/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java","source/com/intellij/codeInsight/generation/GenerateConstructorHandler.java","source/com/intellij/codeInsight/generation/GenerateDelegateHandler.java","source/com/intellij/codeInsight/generation/GenerateEqualsHandler.java","source/com/intellij/codeInsight/generation/GenerateEqualsHelper.java","source/com/intellij/codeInsight/generation/GenerateGetterAndSetterHandler.java","source/com/intellij/codeInsight/generation/GenerateGetterHandler.java","source/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java","source/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java","source/com/intellij/codeInsight/generation/GenerateMembersUtil.java","source/com/intellij/codeInsight/generation/GenerateSetterHandler.java","source/com/intellij/codeInsight/generation/ImplementMethodsHandler.java","source/com/intellij/codeInsight/generation/OverrideImplementUtil.java","source/com/intellij/codeInsight/generation/OverrideMethodsHandler.java","source/com/intellij/codeInsight/generation/TemplateGenerationInfo.java","source/com/intellij/codeInsight/generation/actions/AutoIndentLinesAction.java","source/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java","source/com/intellij/codeInsight/generation/actions/CommentByBlockCommentAction.java","source/com/intellij/codeInsight/generation/actions/CommentByLineCommentAction.java","source/com/intellij/codeInsight/generation/actions/GenerateAction.java","source/com/intellij/codeInsight/generation/actions/GenerateConstructorAction.java","source/com/intellij/codeInsight/generation/actions/GenerateDelegateAction.java","source/com/intellij/codeInsight/generation/actions/GenerateEqualsAction.java","source/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java","source/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java","source/com/intellij/codeInsight/generation/actions/ImplementMethodsAction.java","source/com/intellij/codeInsight/generation/actions/OverrideMethodsAction.java","source/com/intellij/codeInsight/generation/actions/SurroundWithAction.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundStatementsHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithBlockHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithCastHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithDoWhileHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithForHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfElseExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfElseHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfExpressionHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithIfHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithNotHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithNotInstanceofHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithParenthesesHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithRunnableHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithSynchronizedHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryCatchFinallyHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryCatchHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithTryFinallyHandler.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithUtil.java","source/com/intellij/codeInsight/generation/surroundWith/SurroundWithWhileHandler.java","source/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java","source/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java","source/com/intellij/codeInsight/guess/GuessManager.java","source/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java","source/com/intellij/codeInsight/guess/impl/MethodPattern.java","source/com/intellij/codeInsight/guess/impl/MethodPatternMap.java","source/com/intellij/codeInsight/highlighting/BraceHighlighter.java","source/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java","source/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java","source/com/intellij/codeInsight/highlighting/HighlightHandlerBase.java","source/com/intellij/codeInsight/highlighting/HighlightManagerImpl.java","source/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java","source/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java","source/com/intellij/codeInsight/hint/EditorFragmentComponent.java","source/com/intellij/codeInsight/hint/HintManager.java","source/com/intellij/codeInsight/hint/HintUtil.java","source/com/intellij/codeInsight/hint/ImplementationViewComponent.java","source/com/intellij/codeInsight/hint/ParameterInfoComponent.java","source/com/intellij/codeInsight/hint/ParameterInfoController.java","source/com/intellij/codeInsight/hint/PrevNextParameterHandler.java","source/com/intellij/codeInsight/hint/QuestionAction.java","source/com/intellij/codeInsight/hint/ShowContainerInfoHandler.java","source/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java","source/com/intellij/codeInsight/hint/TooltipController.java","source/com/intellij/codeInsight/hint/TooltipGroup.java","source/com/intellij/codeInsight/hint/actions/NextParameterAction.java","source/com/intellij/codeInsight/hint/actions/PrevParameterAction.java","source/com/intellij/codeInsight/hint/actions/ShowContainerInfoAction.java","source/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java","source/com/intellij/codeInsight/hint/actions/ShowParameterInfoAction.java","source/com/intellij/codeInsight/intention/actions/ShowIntentionActionsAction.java","source/com/intellij/codeInsight/intention/impl/AddOnDemandStaticImportAction.java","source/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java","source/com/intellij/codeInsight/intention/impl/AddSingleMemberStaticImportAction.java","source/com/intellij/codeInsight/intention/impl/BaseIntentionAction.java","source/com/intellij/codeInsight/intention/impl/CreateClassDialog.java","source/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java","source/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractClassAction.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodAction.java","source/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java","source/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java","source/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java","source/com/intellij/codeInsight/intention/impl/MakeTypeGeneric.java","source/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java","source/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java","source/com/intellij/codeInsight/intention/impl/SplitIfAction.java","source/com/intellij/codeInsight/intention/impl/TypeExpression.java","source/com/intellij/codeInsight/intention/impl/config/IntentionActionMetaData.java","source/com/intellij/codeInsight/intention/impl/config/IntentionDescriptionPanel.java","source/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java","source/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java","source/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java","source/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java","source/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java","source/com/intellij/codeInsight/javadoc/JavaDocInfoComponent.java","source/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java","source/com/intellij/codeInsight/javadoc/JavaDocManager.java","source/com/intellij/codeInsight/javadoc/JavaDocUtil.java","source/com/intellij/codeInsight/javadoc/actions/ShowJavaDocInfoAction.java","source/com/intellij/codeInsight/lookup/CharFilter.java","source/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java","source/com/intellij/codeInsight/lookup/Lookup.java","source/com/intellij/codeInsight/lookup/LookupAdapter.java","source/com/intellij/codeInsight/lookup/LookupEvent.java","source/com/intellij/codeInsight/lookup/LookupItem.java","source/com/intellij/codeInsight/lookup/LookupItemUtil.java","source/com/intellij/codeInsight/lookup/LookupListener.java","source/com/intellij/codeInsight/lookup/LookupManager.java","source/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java","source/com/intellij/codeInsight/lookup/PresentableLookupValue.java","source/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java","source/com/intellij/codeInsight/lookup/impl/DownHandler.java","source/com/intellij/codeInsight/lookup/impl/EndHandler.java","source/com/intellij/codeInsight/lookup/impl/HomeHandler.java","source/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java","source/com/intellij/codeInsight/lookup/impl/LookupImpl.java","source/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java","source/com/intellij/codeInsight/lookup/impl/PageDownHandler.java","source/com/intellij/codeInsight/lookup/impl/PageUpHandler.java","source/com/intellij/codeInsight/lookup/impl/TestLookupManager.java","source/com/intellij/codeInsight/lookup/impl/TypedHandler.java","source/com/intellij/codeInsight/lookup/impl/UpHandler.java","source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java","source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java","source/com/intellij/codeInsight/navigation/CtrlMouseHandler.java","source/com/intellij/codeInsight/navigation/GotoImplementationHandler.java","source/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java","source/com/intellij/codeInsight/navigation/MethodDownHandler.java","source/com/intellij/codeInsight/navigation/MethodUpDownUtil.java","source/com/intellij/codeInsight/navigation/MethodUpHandler.java","source/com/intellij/codeInsight/navigation/NavigationUtil.java","source/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java","source/com/intellij/codeInsight/navigation/actions/GotoImplementationAction.java","source/com/intellij/codeInsight/navigation/actions/GotoSuperAction.java","source/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java","source/com/intellij/codeInsight/navigation/actions/IncrementalSearchAction.java","source/com/intellij/codeInsight/navigation/actions/MethodDownAction.java","source/com/intellij/codeInsight/navigation/actions/MethodUpAction.java","source/com/intellij/codeInsight/template/Expression.java","source/com/intellij/codeInsight/template/ExpressionContext.java","source/com/intellij/codeInsight/template/ExpressionUtil.java","source/com/intellij/codeInsight/template/InvokeActionResult.java","source/com/intellij/codeInsight/template/Macro.java","source/com/intellij/codeInsight/template/PsiElementResult.java","source/com/intellij/codeInsight/template/PsiTypeResult.java","source/com/intellij/codeInsight/template/Result.java","source/com/intellij/codeInsight/template/Template.java","source/com/intellij/codeInsight/template/TemplateBuilder.java","source/com/intellij/codeInsight/template/TemplateManager.java","source/com/intellij/codeInsight/template/TemplateStateListener.java","source/com/intellij/codeInsight/template/TextResult.java","source/com/intellij/codeInsight/template/actions/SaveAsTemplateAction.java","source/com/intellij/codeInsight/template/impl/ConstantNode.java","source/com/intellij/codeInsight/template/impl/EditTemplateDialog.java","source/com/intellij/codeInsight/template/impl/EditVariableDialog.java","source/com/intellij/codeInsight/template/impl/EmptyNode.java","source/com/intellij/codeInsight/template/impl/ListTemplatesHandler.java","source/com/intellij/codeInsight/template/impl/LiveTemplatesConfigurable.java","source/com/intellij/codeInsight/template/impl/MacroCallNode.java","source/com/intellij/codeInsight/template/impl/MacroParser.java","source/com/intellij/codeInsight/template/impl/SelectionNode.java","source/com/intellij/codeInsight/template/impl/SurroundWithTemplateHandler.java","source/com/intellij/codeInsight/template/impl/TableMap.java","source/com/intellij/codeInsight/template/impl/TableSorter.java","source/com/intellij/codeInsight/template/impl/TemplateColors.java","source/com/intellij/codeInsight/template/impl/TemplateContext.java","source/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java","source/com/intellij/codeInsight/template/impl/TemplateImpl.java","source/com/intellij/codeInsight/template/impl/TemplateImplUtil.java","source/com/intellij/codeInsight/template/impl/TemplateListPanel.java","source/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java","source/com/intellij/codeInsight/template/impl/TemplateSegments.java","source/com/intellij/codeInsight/template/impl/TemplateSettings.java","source/com/intellij/codeInsight/template/impl/TemplateState.java","source/com/intellij/codeInsight/template/impl/TemplateTextLexer.java","source/com/intellij/codeInsight/template/impl/TemplateTokenType.java","source/com/intellij/codeInsight/template/impl/Variable.java","source/com/intellij/codeInsight/template/impl/VariableNode.java","source/com/intellij/codeInsight/template/impl/actions/ListTemplatesAction.java","source/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java","source/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java","source/com/intellij/codeInsight/template/impl/actions/SurroundWithTemplateAction.java","source/com/intellij/codeInsight/template/macro/ArrayVariableMacro.java","source/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java","source/com/intellij/codeInsight/template/macro/CapitalizeMacro.java","source/com/intellij/codeInsight/template/macro/CastToLeftSideTypeMacro.java","source/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java","source/com/intellij/codeInsight/template/macro/ClassNameMacro.java","source/com/intellij/codeInsight/template/macro/CompleteMacro.java","source/com/intellij/codeInsight/template/macro/CompleteSmartMacro.java","source/com/intellij/codeInsight/template/macro/ComponentTypeOfMacro.java","source/com/intellij/codeInsight/template/macro/CurrentPackageMacro.java","source/com/intellij/codeInsight/template/macro/DecapitalizeMacro.java","source/com/intellij/codeInsight/template/macro/DescendantClassesEnumMacro.java","source/com/intellij/codeInsight/template/macro/EnumMacro.java","source/com/intellij/codeInsight/template/macro/ExpectedTypeMacro.java","source/com/intellij/codeInsight/template/macro/GuessElementTypeMacro.java","source/com/intellij/codeInsight/template/macro/IterableComponentTypeMacro.java","source/com/intellij/codeInsight/template/macro/IterableVariableMacro.java","source/com/intellij/codeInsight/template/macro/LineNumberMacro.java","source/com/intellij/codeInsight/template/macro/MacroFactory.java","source/com/intellij/codeInsight/template/macro/MacroUtil.java","source/com/intellij/codeInsight/template/macro/MethodNameMacro.java","source/com/intellij/codeInsight/template/macro/QualifiedClassNameMacro.java","source/com/intellij/codeInsight/template/macro/RightSideTypeMacro.java","source/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java","source/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java","source/com/intellij/codeInsight/template/macro/VariableOfTypeMacro.java","source/com/intellij/codeInsight/template/macro/VariableTypeMacroBase.java","source/com/intellij/codeInspection/InspectionDiff.java","source/com/intellij/codeInspection/InspectionMain.java","source/com/intellij/codeInspection/actions/CodeInspectionAction.java","source/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java","source/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java","source/com/intellij/codeInspection/dataFlow/ControlFlow.java","source/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java","source/com/intellij/codeInspection/dataFlow/DataFlowInspection.java","source/com/intellij/codeInspection/dataFlow/DataFlowRunner.java","source/com/intellij/codeInspection/dataFlow/DfaInstructionState.java","source/com/intellij/codeInspection/dataFlow/DfaMemoryState.java","source/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java","source/com/intellij/codeInspection/dataFlow/DfaVariableState.java","source/com/intellij/codeInspection/dataFlow/SortedIntSet.java","source/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/Instruction.java","source/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java","source/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java","source/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaNewValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaValue.java","source/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java","source/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java","source/com/intellij/codeInspection/deadCode/DeadCodeInspection.java","source/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java","source/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java","source/com/intellij/codeInspection/deadCode/RefEntryPointFilter.java","source/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java","source/com/intellij/codeInspection/deadCode/RefUnreferencedFilter.java","source/com/intellij/codeInspection/defUse/DefUseInspection.java","source/com/intellij/codeInspection/defUse/DefUseUtil.java","source/com/intellij/codeInspection/deprecation/DeprecationInspection.java","source/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java","source/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java","source/com/intellij/codeInspection/ex/AddAssertStatementFix.java","source/com/intellij/codeInspection/ex/BaseLocalInspectionTool.java","source/com/intellij/codeInspection/ex/Descriptor.java","source/com/intellij/codeInspection/ex/DescriptorComposer.java","source/com/intellij/codeInspection/ex/DescriptorProviderInspection.java","source/com/intellij/codeInspection/ex/EntryPointsManager.java","source/com/intellij/codeInspection/ex/FilteringInspectionTool.java","source/com/intellij/codeInspection/ex/HTMLComposer.java","source/com/intellij/codeInspection/ex/InspectionApplication.java","source/com/intellij/codeInspection/ex/InspectionManagerEx.java","source/com/intellij/codeInspection/ex/InspectionProfile.java","source/com/intellij/codeInspection/ex/InspectionProfileImpl.java","source/com/intellij/codeInspection/ex/InspectionTool.java","source/com/intellij/codeInspection/ex/InspectionToolRegistrar.java","source/com/intellij/codeInspection/ex/JobDescriptor.java","source/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java","source/com/intellij/codeInspection/ex/LocalQuickFixWrapper.java","source/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java","source/com/intellij/codeInspection/ex/QuickFixAction.java","source/com/intellij/codeInspection/ex/QuickFixWrapper.java","source/com/intellij/codeInspection/ex/StandardInspectionToolsProvider.java","source/com/intellij/codeInspection/ex/VisibleTreeState.java","source/com/intellij/codeInspection/export/ExportToHTMLDialog.java","source/com/intellij/codeInspection/export/HTMLExportFrameMaker.java","source/com/intellij/codeInspection/export/HTMLExporter.java","source/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java","source/com/intellij/codeInspection/miscGenerics/GenericsInspectionToolBase.java","source/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java","source/com/intellij/codeInspection/miscGenerics/SuspiciousCollectionsMethodCallsInspection.java","source/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java","source/com/intellij/codeInspection/redundantCast/RedundantCastUtil.java","source/com/intellij/codeInspection/reference/RefClass.java","source/com/intellij/codeInspection/reference/RefElement.java","source/com/intellij/codeInspection/reference/RefEntity.java","source/com/intellij/codeInspection/reference/RefField.java","source/com/intellij/codeInspection/reference/RefImplicitConstructor.java","source/com/intellij/codeInspection/reference/RefManager.java","source/com/intellij/codeInspection/reference/RefMethod.java","source/com/intellij/codeInspection/reference/RefPackage.java","source/com/intellij/codeInspection/reference/RefParameter.java","source/com/intellij/codeInspection/reference/RefProject.java","source/com/intellij/codeInspection/reference/RefUtil.java","source/com/intellij/codeInspection/reference/RefVisitor.java","source/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java","source/com/intellij/codeInspection/sameReturnValue/SameReturnValueInspection.java","source/com/intellij/codeInspection/ui/Browser.java","source/com/intellij/codeInspection/ui/EntryPointsNode.java","source/com/intellij/codeInspection/ui/InspectionGroupNode.java","source/com/intellij/codeInspection/ui/InspectionNode.java","source/com/intellij/codeInspection/ui/InspectionPackageNode.java","source/com/intellij/codeInspection/ui/InspectionResultsView.java","source/com/intellij/codeInspection/ui/InspectionRootNode.java","source/com/intellij/codeInspection/ui/InspectionTree.java","source/com/intellij/codeInspection/ui/InspectionTreeNode.java","source/com/intellij/codeInspection/ui/ProblemDescriptionNode.java","source/com/intellij/codeInspection/ui/RefAlphabeticalComparator.java","source/com/intellij/codeInspection/ui/RefElementNode.java","source/com/intellij/codeInspection/unneededThrows/UnneededThrows.java","source/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java","source/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java","source/com/intellij/codeInspection/util/RefEntityAlphabeticalComparator.java","source/com/intellij/codeInspection/util/RefFilter.java","source/com/intellij/codeInspection/util/XMLExportUtl.java","source/com/intellij/codeInspection/visibility/VisibilityInspection.java","source/com/intellij/compiler/Chunk.java","source/com/intellij/compiler/CompilerConfiguration.java","source/com/intellij/compiler/CompilerException.java","source/com/intellij/compiler/CompilerIOUtil.java","source/com/intellij/compiler/CompilerManagerImpl.java","source/com/intellij/compiler/CompilerMessageImpl.java","source/com/intellij/compiler/CompilerWorkspaceConfiguration.java","source/com/intellij/compiler/HelpID.java","source/com/intellij/compiler/JavacOutputParser.java","source/com/intellij/compiler/JavacSettings.java","source/com/intellij/compiler/JikesOutputParser.java","source/com/intellij/compiler/JikesSettings.java","source/com/intellij/compiler/ModuleCompilerUtil.java","source/com/intellij/compiler/OutputParser.java","source/com/intellij/compiler/RmicSettings.java","source/com/intellij/compiler/SymbolTable.java","source/com/intellij/compiler/actions/CompileAction.java","source/com/intellij/compiler/actions/CompileActionBase.java","source/com/intellij/compiler/actions/CompileDirtyAction.java","source/com/intellij/compiler/actions/CompileProjectAction.java","source/com/intellij/compiler/actions/GenerateAntBuildAction.java","source/com/intellij/compiler/actions/GenerateAntBuildDialog.java","source/com/intellij/compiler/actions/MakeModuleAction.java","source/com/intellij/compiler/ant/BuildProperties.java","source/com/intellij/compiler/ant/ChunkBuild.java","source/com/intellij/compiler/ant/CleanModule.java","source/com/intellij/compiler/ant/CleanProject.java","source/com/intellij/compiler/ant/Comment.java","source/com/intellij/compiler/ant/CompileModuleChunkTarget.java","source/com/intellij/compiler/ant/CompilerExcludes.java","source/com/intellij/compiler/ant/CompilerResourcePatterns.java","source/com/intellij/compiler/ant/CompositeGenerator.java","source/com/intellij/compiler/ant/GenerationOptions.java","source/com/intellij/compiler/ant/GenerationUtils.java","source/com/intellij/compiler/ant/Generator.java","source/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java","source/com/intellij/compiler/ant/ModuleChunk.java","source/com/intellij/compiler/ant/ModuleChunkAntProject.java","source/com/intellij/compiler/ant/ModuleChunkClasspath.java","source/com/intellij/compiler/ant/ModuleChunkSourcepath.java","source/com/intellij/compiler/ant/ModuleSources.java","source/com/intellij/compiler/ant/MultipleFileProjectBuild.java","source/com/intellij/compiler/ant/ProjectBuild.java","source/com/intellij/compiler/ant/PropertyFileGenerator.java","source/com/intellij/compiler/ant/SingleFileProjectBuild.java","source/com/intellij/compiler/ant/Tag.java","source/com/intellij/compiler/ant/taskdefs/AntCall.java","source/com/intellij/compiler/ant/taskdefs/AntProject.java","source/com/intellij/compiler/ant/taskdefs/Attribute.java","source/com/intellij/compiler/ant/taskdefs/Copy.java","source/com/intellij/compiler/ant/taskdefs/Delete.java","source/com/intellij/compiler/ant/taskdefs/DirSet.java","source/com/intellij/compiler/ant/taskdefs/Dirname.java","source/com/intellij/compiler/ant/taskdefs/Exclude.java","source/com/intellij/compiler/ant/taskdefs/FileSet.java","source/com/intellij/compiler/ant/taskdefs/Import.java","source/com/intellij/compiler/ant/taskdefs/Include.java","source/com/intellij/compiler/ant/taskdefs/Jar.java","source/com/intellij/compiler/ant/taskdefs/Javac.java","source/com/intellij/compiler/ant/taskdefs/Manifest.java","source/com/intellij/compiler/ant/taskdefs/Mkdir.java","source/com/intellij/compiler/ant/taskdefs/Param.java","source/com/intellij/compiler/ant/taskdefs/Path.java","source/com/intellij/compiler/ant/taskdefs/PathElement.java","source/com/intellij/compiler/ant/taskdefs/PathRef.java","source/com/intellij/compiler/ant/taskdefs/PatternSet.java","source/com/intellij/compiler/ant/taskdefs/PatternSetRef.java","source/com/intellij/compiler/ant/taskdefs/Property.java","source/com/intellij/compiler/ant/taskdefs/Target.java","source/com/intellij/compiler/ant/taskdefs/ZipFileSet.java","source/com/intellij/compiler/classParsing/AnnotationConstantValue.java","source/com/intellij/compiler/classParsing/AnnotationNameValuePair.java","source/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java","source/com/intellij/compiler/classParsing/ClassFileReader.java","source/com/intellij/compiler/classParsing/ClassInfoConstantValue.java","source/com/intellij/compiler/classParsing/ConstantValue.java","source/com/intellij/compiler/classParsing/ConstantValueArray.java","source/com/intellij/compiler/classParsing/DoubleConstantValue.java","source/com/intellij/compiler/classParsing/EnumConstantValue.java","source/com/intellij/compiler/classParsing/FieldInfo.java","source/com/intellij/compiler/classParsing/FloatConstantValue.java","source/com/intellij/compiler/classParsing/GenericMethodSignature.java","source/com/intellij/compiler/classParsing/IntegerConstantValue.java","source/com/intellij/compiler/classParsing/LongConstantValue.java","source/com/intellij/compiler/classParsing/MemberInfo.java","source/com/intellij/compiler/classParsing/MemberInfoExternalizer.java","source/com/intellij/compiler/classParsing/MemberReferenceInfo.java","source/com/intellij/compiler/classParsing/MethodInfo.java","source/com/intellij/compiler/classParsing/ReferenceInfo.java","source/com/intellij/compiler/classParsing/SignatureParser.java","source/com/intellij/compiler/classParsing/SignatureParsingException.java","source/com/intellij/compiler/classParsing/StringConstantValue.java","source/com/intellij/compiler/impl/CompileContextImpl.java","source/com/intellij/compiler/impl/CompileDriver.java","source/com/intellij/compiler/impl/CompilerContentIterator.java","source/com/intellij/compiler/impl/CompilerErrorTreeView.java","source/com/intellij/compiler/impl/CompilerUtil.java","source/com/intellij/compiler/impl/CompositeScope.java","source/com/intellij/compiler/impl/ExcludeEntryDescription.java","source/com/intellij/compiler/impl/FileIndexCompileScope.java","source/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java","source/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java","source/com/intellij/compiler/impl/FileSetCompileScope.java","source/com/intellij/compiler/impl/ModuleCompileScope.java","source/com/intellij/compiler/impl/OneProjectItemCompileScope.java","source/com/intellij/compiler/impl/PackagingCompilerAdapter.java","source/com/intellij/compiler/impl/ProjectCompileScope.java","source/com/intellij/compiler/impl/StateCache.java","source/com/intellij/compiler/impl/TimestampCache.java","source/com/intellij/compiler/impl/TrackDependenciesScope.java","source/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java","source/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java","source/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java","source/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java","source/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java","source/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java","source/com/intellij/compiler/impl/javaCompiler/JavacCompiler.java","source/com/intellij/compiler/impl/javaCompiler/JikesCompiler.java","source/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java","source/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java","source/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java","source/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java","source/com/intellij/compiler/make/AnnotationTargets.java","source/com/intellij/compiler/make/BoundsParser.java","source/com/intellij/compiler/make/Cache.java","source/com/intellij/compiler/make/CacheCorruptedException.java","source/com/intellij/compiler/make/CacheUtils.java","source/com/intellij/compiler/make/CachingSearcher.java","source/com/intellij/compiler/make/ChangeDescription.java","source/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java","source/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java","source/com/intellij/compiler/make/ClassInfoProcessor.java","source/com/intellij/compiler/make/Dependency.java","source/com/intellij/compiler/make/DependencyCache.java","source/com/intellij/compiler/make/DependencyCacheNavigator.java","source/com/intellij/compiler/make/DependencyProcessor.java","source/com/intellij/compiler/make/FieldChangeDescription.java","source/com/intellij/compiler/make/MakeUtil.java","source/com/intellij/compiler/make/MethodChangeDescription.java","source/com/intellij/compiler/make/RetentionPolicies.java","source/com/intellij/compiler/make/SourceFileFinder.java","source/com/intellij/compiler/options/ComparingUtils.java","source/com/intellij/compiler/options/CompilerConfigurable.java","source/com/intellij/compiler/options/CompilerUIConfigurable.java","source/com/intellij/compiler/options/JavaCompilersTab.java","source/com/intellij/compiler/options/JavacConfigurable.java","source/com/intellij/compiler/options/JikesConfigurable.java","source/com/intellij/compiler/options/RmicConfigurable.java","source/com/intellij/compiler/progress/CompilerProgressDialog.java","source/com/intellij/compiler/progress/CompilerProgressIndicator.java","source/com/intellij/debugger/DebugException.java","source/com/intellij/debugger/DebuggerInvocationUtil.java","source/com/intellij/debugger/DebuggerManagerEx.java","source/com/intellij/debugger/EvaluatingComputable.java","source/com/intellij/debugger/HelpID.java","source/com/intellij/debugger/InstanceFilter.java","source/com/intellij/debugger/actions/AddToWatchAction.java","source/com/intellij/debugger/actions/AdjustArrayRangeAction.java","source/com/intellij/debugger/actions/AutoRendererAction.java","source/com/intellij/debugger/actions/CopyValueAction.java","source/com/intellij/debugger/actions/CustomizeContextViewAction.java","source/com/intellij/debugger/actions/CustomizeThreadsViewAction.java","source/com/intellij/debugger/actions/DebuggerAction.java","source/com/intellij/debugger/actions/DebuggerActions.java","source/com/intellij/debugger/actions/EditFrameSourceAction.java","source/com/intellij/debugger/actions/EditSourceAction.java","source/com/intellij/debugger/actions/EditWatchAction.java","source/com/intellij/debugger/actions/EvaluateAction.java","source/com/intellij/debugger/actions/ExportThreadsAction.java","source/com/intellij/debugger/actions/ForceStepIntoAction.java","source/com/intellij/debugger/actions/ForceStepOverAction.java","source/com/intellij/debugger/actions/FreezeThreadAction.java","source/com/intellij/debugger/actions/GotoFrameSourceAction.java","source/com/intellij/debugger/actions/HotSwapAction.java","source/com/intellij/debugger/actions/InspectAction.java","source/com/intellij/debugger/actions/JumpToObjectAction.java","source/com/intellij/debugger/actions/NewWatchAction.java","source/com/intellij/debugger/actions/PauseAction.java","source/com/intellij/debugger/actions/PlaceInDocument.java","source/com/intellij/debugger/actions/PopFrameAction.java","source/com/intellij/debugger/actions/QuickEvaluateAction.java","source/com/intellij/debugger/actions/RemoveAllWatchesAction.java","source/com/intellij/debugger/actions/RemoveWatchAction.java","source/com/intellij/debugger/actions/ResumeAction.java","source/com/intellij/debugger/actions/ResumeThreadAction.java","source/com/intellij/debugger/actions/RunToCursorAction.java","source/com/intellij/debugger/actions/SetValueAction.java","source/com/intellij/debugger/actions/ShowExecutionPointAction.java","source/com/intellij/debugger/actions/ShowFrameAction.java","source/com/intellij/debugger/actions/StepIntoAction.java","source/com/intellij/debugger/actions/StepOutAction.java","source/com/intellij/debugger/actions/StepOverAction.java","source/com/intellij/debugger/actions/ThrowDebugExceptionAction.java","source/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java","source/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java","source/com/intellij/debugger/actions/ToggleLineBreakpointAction.java","source/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java","source/com/intellij/debugger/actions/ViewAsGroup.java","source/com/intellij/debugger/actions/ViewBreakpointsAction.java","source/com/intellij/debugger/codeinsight/SurroundWithRuntimeCastHandler.java","source/com/intellij/debugger/engine/CompoundPositionManager.java","source/com/intellij/debugger/engine/ContextUtil.java","source/com/intellij/debugger/engine/DebugProcessAdapterImpl.java","source/com/intellij/debugger/engine/DebugProcessEvents.java","source/com/intellij/debugger/engine/DebugProcessImpl.java","source/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java","source/com/intellij/debugger/engine/JVMName.java","source/com/intellij/debugger/engine/JVMNameUtil.java","source/com/intellij/debugger/engine/PositionManagerImpl.java","source/com/intellij/debugger/engine/RemoteDebugProcessHandler.java","source/com/intellij/debugger/engine/RemoteStateState.java","source/com/intellij/debugger/engine/RequestHint.java","source/com/intellij/debugger/engine/SuspendContextImpl.java","source/com/intellij/debugger/engine/SuspendContextRunnable.java","source/com/intellij/debugger/engine/SuspendManager.java","source/com/intellij/debugger/engine/SuspendManagerImpl.java","source/com/intellij/debugger/engine/SuspendManagerUtil.java","source/com/intellij/debugger/engine/VMEventListener.java","source/com/intellij/debugger/engine/evaluation/DebuggerHighlightFilter.java","source/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java","source/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java","source/com/intellij/debugger/engine/evaluation/EvaluationListener.java","source/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java","source/com/intellij/debugger/engine/evaluation/expression/ArrayAccessEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/ArrayInitializerEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/BinaryExpressionEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/BreakException.java","source/com/intellij/debugger/engine/evaluation/expression/ClassObjectEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/ContinueException.java","source/com/intellij/debugger/engine/evaluation/expression/Evaluator.java","source/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java","source/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java","source/com/intellij/debugger/engine/evaluation/expression/FieldEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/InspectArrayItem.java","source/com/intellij/debugger/engine/evaluation/expression/InspectEntity.java","source/com/intellij/debugger/engine/evaluation/expression/InspectField.java","source/com/intellij/debugger/engine/evaluation/expression/InspectLocal.java","source/com/intellij/debugger/engine/evaluation/expression/InstanceofEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/MapStack.java","source/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/NewArrayInstanceEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/ThisEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/TypeCastEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/TypeEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/UnaryExpressionEvaluator.java","source/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java","source/com/intellij/debugger/engine/events/DebuggerCommandImpl.java","source/com/intellij/debugger/engine/events/DebuggerContextCommandImpl.java","source/com/intellij/debugger/engine/events/SuspendContextCommandImpl.java","source/com/intellij/debugger/engine/requests/LocatableEventRequestor.java","source/com/intellij/debugger/engine/requests/RequestManagerImpl.java","source/com/intellij/debugger/impl/CloseWorkerThreadException.java","source/com/intellij/debugger/impl/DebuggerContextImpl.java","source/com/intellij/debugger/impl/DebuggerContextListener.java","source/com/intellij/debugger/impl/DebuggerContextUtil.java","source/com/intellij/debugger/impl/DebuggerManagerImpl.java","source/com/intellij/debugger/impl/DebuggerManagerListener.java","source/com/intellij/debugger/impl/DebuggerSession.java","source/com/intellij/debugger/impl/DebuggerStateManager.java","source/com/intellij/debugger/impl/DebuggerUtilsEx.java","source/com/intellij/debugger/impl/DebuggerUtilsImpl.java","source/com/intellij/debugger/impl/EventQueue.java","source/com/intellij/debugger/impl/EventQueueClosedException.java","source/com/intellij/debugger/impl/GenericDebuggerParametersRunnerConfigurable.java","source/com/intellij/debugger/impl/GenericDebuggerRunner.java","source/com/intellij/debugger/impl/GenericDebuggerRunnerSettings.java","source/com/intellij/debugger/impl/HotSwapFile.java","source/com/intellij/debugger/impl/HotSwapManager.java","source/com/intellij/debugger/impl/HotSwapProgress.java","source/com/intellij/debugger/impl/InvokeAndWaitEvent.java","source/com/intellij/debugger/impl/InvokeAndWaitEventImpl.java","source/com/intellij/debugger/impl/InvokeAndWaitThread.java","source/com/intellij/debugger/impl/InvokeThread.java","source/com/intellij/debugger/impl/MultiProcessCommand.java","source/com/intellij/debugger/impl/PositionUtil.java","source/com/intellij/debugger/impl/ReloadClassesWorker.java","source/com/intellij/debugger/impl/SimpleStackFrameContext.java","source/com/intellij/debugger/impl/descriptors/data/ArrayItemData.java","source/com/intellij/debugger/impl/descriptors/data/DescriptorData.java","source/com/intellij/debugger/impl/descriptors/data/DescriptorKey.java","source/com/intellij/debugger/impl/descriptors/data/DisplayKey.java","source/com/intellij/debugger/impl/descriptors/data/FieldData.java","source/com/intellij/debugger/impl/descriptors/data/LocalData.java","source/com/intellij/debugger/impl/descriptors/data/SimpleDisplayKey.java","source/com/intellij/debugger/impl/descriptors/data/StackFrameData.java","source/com/intellij/debugger/impl/descriptors/data/StaticData.java","source/com/intellij/debugger/impl/descriptors/data/StaticFieldData.java","source/com/intellij/debugger/impl/descriptors/data/ThisData.java","source/com/intellij/debugger/impl/descriptors/data/ThreadData.java","source/com/intellij/debugger/impl/descriptors/data/ThreadGroupData.java","source/com/intellij/debugger/impl/descriptors/data/UserExpressionData.java","source/com/intellij/debugger/jdi/JdiProxy.java","source/com/intellij/debugger/jdi/JdiTimer.java","source/com/intellij/debugger/jdi/LocalVariableProxyImpl.java","source/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java","source/com/intellij/debugger/jdi/StackFrameProxyImpl.java","source/com/intellij/debugger/jdi/StringReferenceProxy.java","source/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java","source/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java","source/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java","source/com/intellij/debugger/settings/ArrayRendererConfigurable.java","source/com/intellij/debugger/settings/CompositeConfigurable.java","source/com/intellij/debugger/settings/DebuggerColors.java","source/com/intellij/debugger/settings/DebuggerConfigurable.java","source/com/intellij/debugger/settings/DebuggerGeneralConfigurable.java","source/com/intellij/debugger/settings/DebuggerSettings.java","source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java","source/com/intellij/debugger/settings/ThreadsViewConfigurable.java","source/com/intellij/debugger/settings/ThreadsViewSettings.java","source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java","source/com/intellij/debugger/settings/ViewsGeneralSettings.java","source/com/intellij/debugger/ui/ClassFilterEditor.java","source/com/intellij/debugger/ui/ClassFilterEditorAddDialog.java","source/com/intellij/debugger/ui/CompletedInputDialog.java","source/com/intellij/debugger/ui/CompletedInputTextField.java","source/com/intellij/debugger/ui/DebuggerEditorImpl.java","source/com/intellij/debugger/ui/DebuggerExpressionComboBox.java","source/com/intellij/debugger/ui/DebuggerPanelsManager.java","source/com/intellij/debugger/ui/DebuggerRecents.java","source/com/intellij/debugger/ui/DebuggerSessionTab.java","source/com/intellij/debugger/ui/DebuggerStatementEditor.java","source/com/intellij/debugger/ui/EditorEvaluationCommand.java","source/com/intellij/debugger/ui/EvaluationDialog.java","source/com/intellij/debugger/ui/EvaluatorRunnable.java","source/com/intellij/debugger/ui/ExportDialog.java","source/com/intellij/debugger/ui/ExpressionEvaluationDialog.java","source/com/intellij/debugger/ui/GetJPDADialog.java","source/com/intellij/debugger/ui/HotSwapProgressImpl.java","source/com/intellij/debugger/ui/HotSwapUI.java","source/com/intellij/debugger/ui/InstanceFilterEditor.java","source/com/intellij/debugger/ui/PositionHighlighter.java","source/com/intellij/debugger/ui/RunHotswapDialog.java","source/com/intellij/debugger/ui/StatementEvaluationDialog.java","source/com/intellij/debugger/ui/ValueHint.java","source/com/intellij/debugger/ui/ValueLookupManager.java","source/com/intellij/debugger/ui/WeakMouseListener.java","source/com/intellij/debugger/ui/WeakMouseMotionListener.java","source/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java","source/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java","source/com/intellij/debugger/ui/breakpoints/Breakpoint.java","source/com/intellij/debugger/ui/breakpoints/BreakpointManager.java","source/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java","source/com/intellij/debugger/ui/breakpoints/BreakpointNameCellRenderer.java","source/com/intellij/debugger/ui/breakpoints/BreakpointPanel.java","source/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java","source/com/intellij/debugger/ui/breakpoints/BreakpointTableModel.java","source/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java","source/com/intellij/debugger/ui/breakpoints/BreakpointsConfigurationDialogFactory.java","source/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java","source/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java","source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java","source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java","source/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java","source/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java","source/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java","source/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java","source/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java","source/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java","source/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java","source/com/intellij/debugger/ui/impl/DebuggerComboBoxRenderer.java","source/com/intellij/debugger/ui/impl/DebuggerPanel.java","source/com/intellij/debugger/ui/impl/DebuggerTreeBase.java","source/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java","source/com/intellij/debugger/ui/impl/FrameDebuggerTree.java","source/com/intellij/debugger/ui/impl/FramePanel.java","source/com/intellij/debugger/ui/impl/InspectDebuggerTree.java","source/com/intellij/debugger/ui/impl/InspectDialog.java","source/com/intellij/debugger/ui/impl/InspectPanel.java","source/com/intellij/debugger/ui/impl/MainWatchPanel.java","source/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java","source/com/intellij/debugger/ui/impl/ThreadsPanel.java","source/com/intellij/debugger/ui/impl/TipManager.java","source/com/intellij/debugger/ui/impl/UIUtil.java","source/com/intellij/debugger/ui/impl/WatchDebuggerTree.java","source/com/intellij/debugger/ui/impl/WatchPanel.java","source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java","source/com/intellij/debugger/ui/impl/nodes/NodeComparator.java","source/com/intellij/debugger/ui/impl/tree/TreeBuilder.java","source/com/intellij/debugger/ui/impl/tree/TreeBuilderNode.java","source/com/intellij/debugger/ui/impl/watch/ArrayElementDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java","source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java","source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java","source/com/intellij/debugger/ui/impl/watch/DefaultNodeDescriptor.java","source/com/intellij/debugger/ui/impl/watch/DescriptorTree.java","source/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java","source/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/MarkedDescriptorTree.java","source/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java","source/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java","source/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java","source/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/ThisDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/ThreadDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/ThreadGroupDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java","source/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java","source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java","source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java","source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java","source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java","source/com/intellij/diagnostic/Diagnostic.java","source/com/intellij/diagnostic/DialogAppender.java","source/com/intellij/diagnostic/DropAnErrorAction.java","source/com/intellij/diagnostic/EAPSendErrorDialog.java","source/com/intellij/diagnostic/ErrorReportConfigurable.java","source/com/intellij/diagnostic/PluginException.java","source/com/intellij/diagnostic/ReportMessages.java","source/com/intellij/diff/Block.java","source/com/intellij/diff/FindBlock.java","source/com/intellij/dupLocator/util/PsiAnchor.java","source/com/intellij/errorreport/ErrorReportSender.java","source/com/intellij/errorreport/bean/ErrorBean.java","source/com/intellij/errorreport/bean/ExceptionBean.java","source/com/intellij/errorreport/bean/NotifierBean.java","source/com/intellij/errorreport/error/InternalEAPException.java","source/com/intellij/errorreport/error/NewBuildException.java","source/com/intellij/errorreport/error/NoSuchEAPUserException.java","source/com/intellij/errorreport/error/NoSuchExceptionException.java","source/com/intellij/errorreport/error/SendException.java","source/com/intellij/errorreport/itn/ITNProxy.java","source/com/intellij/execution/ConfigurationTypeEx.java","source/com/intellij/execution/ExecutionUtil.java","source/com/intellij/execution/ExternalizablePath.java","source/com/intellij/execution/Location.java","source/com/intellij/execution/PsiLocation.java","source/com/intellij/execution/RunJavaConfiguration.java","source/com/intellij/execution/RunManager.java","source/com/intellij/execution/RunManagerConfig.java","source/com/intellij/execution/RuntimeConfiguration.java","source/com/intellij/execution/SingleClassConfiguration.java","source/com/intellij/execution/TerminateRemoteProcessDialog.java","source/com/intellij/execution/actions/BaseRunConfigurationAction.java","source/com/intellij/execution/actions/ConfigurationContext.java","source/com/intellij/execution/actions/CreateAction.java","source/com/intellij/execution/actions/EditRunConfigurationsAction.java","source/com/intellij/execution/actions/PreferedProducerFind.java","source/com/intellij/execution/actions/RunConfigurationAction.java","source/com/intellij/execution/actions/RunContextAction.java","source/com/intellij/execution/actions/StopAction.java","source/com/intellij/execution/applet/AppletConfigurable.java","source/com/intellij/execution/applet/AppletConfiguration.java","source/com/intellij/execution/applet/AppletConfigurationType.java","source/com/intellij/execution/application/ApplicationConfigurable2.java","source/com/intellij/execution/application/ApplicationConfiguration.java","source/com/intellij/execution/application/ApplicationConfigurationProducer.java","source/com/intellij/execution/application/ApplicationConfigurationType.java","source/com/intellij/execution/filters/TextConsoleBuilderImpl.java","source/com/intellij/execution/impl/ConfigurationSettingsEditor.java","source/com/intellij/execution/impl/ConsoleState.java","source/com/intellij/execution/impl/ConsoleViewImpl.java","source/com/intellij/execution/impl/DisposedPsiManagerCheck.java","source/com/intellij/execution/impl/EditConfigurationsDialog.java","source/com/intellij/execution/impl/ExecutionManagerImpl.java","source/com/intellij/execution/impl/ExecutionRegistryImpl.java","source/com/intellij/execution/impl/RunConfigurable.java","source/com/intellij/execution/impl/RunDialog.java","source/com/intellij/execution/impl/RunManagerImpl.java","source/com/intellij/execution/impl/RunnerAndConfigurationSettings.java","source/com/intellij/execution/impl/SingleConfigurationConfigurable.java","source/com/intellij/execution/impl/TypeTemplatesConfigurable.java","source/com/intellij/execution/impl/ValidationResult.java","source/com/intellij/execution/junit/JUnitProcessHandler.java","source/com/intellij/execution/junit/JUnitUtil.java","source/com/intellij/execution/junit/ModuleBasedConfiguration.java","source/com/intellij/execution/junit/RefactoringListeners.java","source/com/intellij/execution/junit/RuntimeConfigurationProducer.java","source/com/intellij/execution/junit2/Filter.java","source/com/intellij/execution/junit2/Printable.java","source/com/intellij/execution/junit2/Printer.java","source/com/intellij/execution/junit2/PushReader.java","source/com/intellij/execution/junit2/SegmentedInputStream.java","source/com/intellij/execution/junit2/configuration/BrowseModuleValueActionListener.java","source/com/intellij/execution/junit2/configuration/ClassBrowser.java","source/com/intellij/execution/junit2/configuration/CommonJavaParameters.java","source/com/intellij/execution/junit2/configuration/ConfigurationModuleSelector.java","source/com/intellij/execution/junit2/configuration/RunConfigurationModule.java","source/com/intellij/execution/junit2/info/MethodLocation.java","source/com/intellij/execution/junit2/segments/DeferedActionsQueue.java","source/com/intellij/execution/junit2/segments/DeferedActionsQueueImpl.java","source/com/intellij/execution/junit2/segments/DispatchListener.java","source/com/intellij/execution/junit2/segments/InputConsumer.java","source/com/intellij/execution/junit2/segments/PacketExtractorBase.java","source/com/intellij/execution/junit2/segments/SegmentReader.java","source/com/intellij/execution/junit2/states/DiffHyperlink.java","source/com/intellij/execution/junit2/states/MethodLineLocation.java","source/com/intellij/execution/junit2/states/StackTraceLine.java","source/com/intellij/execution/junit2/ui/FailedTestsNavigator.java","source/com/intellij/execution/junit2/ui/PoolOfTestIcons.java","source/com/intellij/execution/junit2/ui/TestTreeView.java","source/com/intellij/execution/junit2/ui/TestsUIUtil.java","source/com/intellij/execution/junit2/ui/actions/TestTreeExpander.java","source/com/intellij/execution/junit2/ui/actions/ToolbarPanel.java","source/com/intellij/execution/junit2/ui/properties/JUnitPropertyListener.java","source/com/intellij/execution/junit2/ui/properties/ScrollToTestSourceAction.java","source/com/intellij/execution/remote/RemoteConfigurable.java","source/com/intellij/execution/remote/RemoteConfiguration.java","source/com/intellij/execution/remote/RemoteConfigurationType.java","source/com/intellij/execution/runners/ProcessProxyFactoryImpl.java","source/com/intellij/execution/runners/ProcessProxyImpl.java","source/com/intellij/execution/runners/RestartAction.java","source/com/intellij/execution/runners/RunContentBuilder.java","source/com/intellij/execution/ui/RunContentManagerImpl.java","source/com/intellij/execution/util/JavaParametersUtil.java","source/com/intellij/execution/util/RefactoringElementListenerComposite.java","source/com/intellij/execution/util/StoringPropertyContainer.java","source/com/intellij/featureStatistics/ApplicabilityFilter.java","source/com/intellij/featureStatistics/FeatureUsageTracker.java","source/com/intellij/featureStatistics/GroupDescriptor.java","source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java","source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java","source/com/intellij/featureStatistics/ui/AdaptiveTipDialog.java","source/com/intellij/featureStatistics/ui/ProgressTipPanel.java","source/com/intellij/find/FindProgressIndicator.java","source/com/intellij/find/FindSettings.java","source/com/intellij/find/FindUtil.java","source/com/intellij/find/actions/FindInPathAction.java","source/com/intellij/find/actions/FindUsagesAction.java","source/com/intellij/find/actions/FindUsagesInFileAction.java","source/com/intellij/find/actions/ReplaceInPathAction.java","source/com/intellij/find/findInProject/FindInProjectManager.java","source/com/intellij/find/findUsages/FindClassUsagesDialog.java","source/com/intellij/find/findUsages/FindMethodUsagesDialog.java","source/com/intellij/find/findUsages/FindPackageUsagesDialog.java","source/com/intellij/find/findUsages/FindThrowUsagesDialog.java","source/com/intellij/find/findUsages/FindUsagesDialog.java","source/com/intellij/find/findUsages/FindUsagesManager.java","source/com/intellij/find/findUsages/FindUsagesOptions.java","source/com/intellij/find/findUsages/FindUsagesUtil.java","source/com/intellij/find/findUsages/FindVariableUsagesDialog.java","source/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java","source/com/intellij/find/impl/FindDialog.java","source/com/intellij/find/impl/FindInProjectUtil.java","source/com/intellij/find/impl/FindManagerImpl.java","source/com/intellij/find/impl/FindResultImpl.java","source/com/intellij/find/impl/FindSettingsImpl.java","source/com/intellij/find/impl/HelpID.java","source/com/intellij/find/replaceInProject/ReplaceInProjectManager.java","source/com/intellij/help/impl/HelpManagerImpl.java","source/com/intellij/help/impl/IdeaHelpBroker.java","source/com/intellij/help/impl/IdeaHelpContentViewUI.java","source/com/intellij/help/impl/IdeaJHelp.java","source/com/intellij/help/impl/IdeaJHelpContentViewer.java","source/com/intellij/ide/CopyPasteManagerEx.java","source/com/intellij/ide/GeneralSettingsConfigurable.java","source/com/intellij/ide/IconUtilEx.java","source/com/intellij/ide/IdeEventQueue.java","source/com/intellij/ide/IdePopup.java","source/com/intellij/ide/IdePopupManager.java","source/com/intellij/ide/IdeView.java","source/com/intellij/ide/MacOSApplicationProvider.java","source/com/intellij/ide/PasteProvider.java","source/com/intellij/ide/RecentProjectsManager.java","source/com/intellij/ide/SaveAndSyncHandler.java","source/com/intellij/ide/SwingCleanuper.java","source/com/intellij/ide/TipOfTheDayManager.java","source/com/intellij/ide/actionMacro/ActionMacro.java","source/com/intellij/ide/actionMacro/ActionMacroConfigurable.java","source/com/intellij/ide/actionMacro/ActionMacroConfigurationPanel.java","source/com/intellij/ide/actionMacro/ActionMacroManager.java","source/com/intellij/ide/actionMacro/EditMacrosDialog.java","source/com/intellij/ide/actionMacro/actions/EditMacrosAction.java","source/com/intellij/ide/actionMacro/actions/MacrosGroup.java","source/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java","source/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java","source/com/intellij/ide/actions/AboutAction.java","source/com/intellij/ide/actions/ActivateToolWindowAction.java","source/com/intellij/ide/actions/AssociateFileType.java","source/com/intellij/ide/actions/BackAction.java","source/com/intellij/ide/actions/BaseNavigateToSourceAction.java","source/com/intellij/ide/actions/ChangeSplitterOrientationAction.java","source/com/intellij/ide/actions/ChooseComponentsToExportDialog.java","source/com/intellij/ide/actions/CloneElementAction.java","source/com/intellij/ide/actions/CloseActiveTabAction.java","source/com/intellij/ide/actions/CloseAllEditorsAction.java","source/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java","source/com/intellij/ide/actions/CloseAllUnmodifiedEditorsAction.java","source/com/intellij/ide/actions/CloseEditorAction.java","source/com/intellij/ide/actions/CloseProjectAction.java","source/com/intellij/ide/actions/CloseTabToolbarAction.java","source/com/intellij/ide/actions/CloseWindowAction.java","source/com/intellij/ide/actions/CodeEditorActionGroup.java","source/com/intellij/ide/actions/CollapseAllAction.java","source/com/intellij/ide/actions/CommanderViewActionGroup.java","source/com/intellij/ide/actions/ContextHelpAction.java","source/com/intellij/ide/actions/CopyAction.java","source/com/intellij/ide/actions/CopyElementAction.java","source/com/intellij/ide/actions/CopyPathsAction.java","source/com/intellij/ide/actions/CreateClassAction.java","source/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java","source/com/intellij/ide/actions/CreateElementActionBase.java","source/com/intellij/ide/actions/CreateFileAction.java","source/com/intellij/ide/actions/CutAction.java","source/com/intellij/ide/actions/DeleteAction.java","source/com/intellij/ide/actions/EditFileTemplatesAction.java","source/com/intellij/ide/actions/EditSourceAction.java","source/com/intellij/ide/actions/ExitAction.java","source/com/intellij/ide/actions/ExpandAllAction.java","source/com/intellij/ide/actions/ExportSettingsAction.java","source/com/intellij/ide/actions/ExportToTextFileAction.java","source/com/intellij/ide/actions/ExportToTextFileToolbarAction.java","source/com/intellij/ide/actions/ExternalJavaDocAction.java","source/com/intellij/ide/actions/ForwardAction.java","source/com/intellij/ide/actions/GotoActionBase.java","source/com/intellij/ide/actions/GotoClassAction.java","source/com/intellij/ide/actions/GotoFileAction.java","source/com/intellij/ide/actions/GotoLineAction.java","source/com/intellij/ide/actions/GotoSymbolAction.java","source/com/intellij/ide/actions/HelpTopicsAction.java","source/com/intellij/ide/actions/HideAllToolWindowsAction.java","source/com/intellij/ide/actions/HideToolWindowAction.java","source/com/intellij/ide/actions/ImportSettingsAction.java","source/com/intellij/ide/actions/JumpToLastEditAction.java","source/com/intellij/ide/actions/JumpToLastWindowAction.java","source/com/intellij/ide/actions/NewElementAction.java","source/com/intellij/ide/actions/NewProjectAction.java","source/com/intellij/ide/actions/NextOccurenceAction.java","source/com/intellij/ide/actions/NextOccurenceToolbarAction.java","source/com/intellij/ide/actions/NextSplitAction.java","source/com/intellij/ide/actions/NextTabAction.java","source/com/intellij/ide/actions/OccurenceNavigatorActionBase.java","source/com/intellij/ide/actions/OnlineDocAction.java","source/com/intellij/ide/actions/OpenFileAction.java","source/com/intellij/ide/actions/OpenProjectAction.java","source/com/intellij/ide/actions/OtherGroup.java","source/com/intellij/ide/actions/PasteAction.java","source/com/intellij/ide/actions/PinActiveTabAction.java","source/com/intellij/ide/actions/PrevSplitAction.java","source/com/intellij/ide/actions/PreviousOccurenceAction.java","source/com/intellij/ide/actions/PreviousOccurenceToolbarAction.java","source/com/intellij/ide/actions/PreviousTabAction.java","source/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java","source/com/intellij/ide/actions/QuickChangeColorSchemeAction.java","source/com/intellij/ide/actions/QuickChangeKeymapAction.java","source/com/intellij/ide/actions/QuickChangeLookAndFeel.java","source/com/intellij/ide/actions/QuickChangeSchemesAction.java","source/com/intellij/ide/actions/QuickSwitchSchemeAction.java","source/com/intellij/ide/actions/RecentProjectsGroup.java","source/com/intellij/ide/actions/RedoAction.java","source/com/intellij/ide/actions/RefreshAction.java","source/com/intellij/ide/actions/ReloadFromDiskAction.java","source/com/intellij/ide/actions/RestoreDefaultLayoutAction.java","source/com/intellij/ide/actions/RunGcAction.java","source/com/intellij/ide/actions/SaveAllAction.java","source/com/intellij/ide/actions/SaveFileAsTemplateAction.java","source/com/intellij/ide/actions/SearchAgainAction.java","source/com/intellij/ide/actions/SearchBackAction.java","source/com/intellij/ide/actions/SelectAllAction.java","source/com/intellij/ide/actions/SelectInAction.java","source/com/intellij/ide/actions/SelectInContext.java","source/com/intellij/ide/actions/ShowModulePropertiesAction.java","source/com/intellij/ide/actions/ShowPopupMenuAction.java","source/com/intellij/ide/actions/ShowRecentFilesAction.java","source/com/intellij/ide/actions/ShowSettingsAction.java","source/com/intellij/ide/actions/ShowSettingsUtilImpl.java","source/com/intellij/ide/actions/ShowTipsAction.java","source/com/intellij/ide/actions/SplitAction.java","source/com/intellij/ide/actions/SplitHorizontalAction.java","source/com/intellij/ide/actions/SplitVerticalAction.java","source/com/intellij/ide/actions/StoreDefaultLayoutAction.java","source/com/intellij/ide/actions/SwapPanelsAction.java","source/com/intellij/ide/actions/SyncViewsAction.java","source/com/intellij/ide/actions/SynchronizeAction.java","source/com/intellij/ide/actions/TabNavigationActionBase.java","source/com/intellij/ide/actions/TemplateProjectPropertiesAction.java","source/com/intellij/ide/actions/ToggleDockModeAction.java","source/com/intellij/ide/actions/ToggleFloatingModeAction.java","source/com/intellij/ide/actions/ToggleFullScreenModeAction.java","source/com/intellij/ide/actions/TogglePinnedModeAction.java","source/com/intellij/ide/actions/TogglePopupHintsAction.java","source/com/intellij/ide/actions/ToggleReadOnlyAttributeAction.java","source/com/intellij/ide/actions/ToolWindowsGroup.java","source/com/intellij/ide/actions/UndoAction.java","source/com/intellij/ide/actions/UnsplitAction.java","source/com/intellij/ide/actions/UnsplitAllAction.java","source/com/intellij/ide/actions/ViewSourceAction.java","source/com/intellij/ide/actions/ViewStatusBarAction.java","source/com/intellij/ide/actions/ViewStructureAction.java","source/com/intellij/ide/actions/ViewToolbarAction.java","source/com/intellij/ide/actions/tree/BaseTreeNodeAction.java","source/com/intellij/ide/actions/tree/CollapseTreeNodeAction.java","source/com/intellij/ide/actions/tree/ExpandTreeNodeAction.java","source/com/intellij/ide/actions/tree/FullyExpandTreeNodeAction.java","source/com/intellij/ide/bookmarks/Bookmark.java","source/com/intellij/ide/bookmarks/BookmarkManager.java","source/com/intellij/ide/bookmarks/BookmarksDialog.java","source/com/intellij/ide/bookmarks/CommanderBookmarksDialog.java","source/com/intellij/ide/bookmarks/EditorBookmarksDialog.java","source/com/intellij/ide/bookmarks/actions/GotoBookmarkActionBase.java","source/com/intellij/ide/bookmarks/actions/NextBookmarkAction.java","source/com/intellij/ide/bookmarks/actions/PreviousBookmarkAction.java","source/com/intellij/ide/bookmarks/actions/ToggleBookmarkAction.java","source/com/intellij/ide/commander/AbstractListBuilder.java","source/com/intellij/ide/commander/ColoredCommanderRenderer.java","source/com/intellij/ide/commander/Commander.java","source/com/intellij/ide/commander/CommanderHistory.java","source/com/intellij/ide/commander/CommanderPanel.java","source/com/intellij/ide/commander/CommanderSelectInTarget.java","source/com/intellij/ide/commander/HelpID.java","source/com/intellij/ide/commander/ProjectListBuilder.java","source/com/intellij/ide/errorTreeView/ErrorTreeElement.java","source/com/intellij/ide/errorTreeView/ErrorTreeElementKind.java","source/com/intellij/ide/errorTreeView/ErrorTreeNodeDescriptor.java","source/com/intellij/ide/errorTreeView/ErrorViewStructure.java","source/com/intellij/ide/errorTreeView/ErrorViewTreeBuilder.java","source/com/intellij/ide/errorTreeView/GroupingElement.java","source/com/intellij/ide/errorTreeView/NavigatableMessageElement.java","source/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java","source/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java","source/com/intellij/ide/errorTreeView/SimpleMessageElement.java","source/com/intellij/ide/errorTreeView/actions/TestErrorViewAction.java","source/com/intellij/ide/errorTreeView/actions/TestNewErrorViewAction.java","source/com/intellij/ide/errorTreeView/impl/ErrorTreeViewConfiguration.java","source/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java","source/com/intellij/ide/fileTemplates/FileTemplate.java","source/com/intellij/ide/fileTemplates/FileTemplateManager.java","source/com/intellij/ide/fileTemplates/FileTemplateUtil.java","source/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java","source/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateDescriptionImpl.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.java","source/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java","source/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java","source/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java","source/com/intellij/ide/fileTemplates/ui/CreateFromTemplatePanel.java","source/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java","source/com/intellij/ide/hierarchy/HierarchyBrowserManager.java","source/com/intellij/ide/hierarchy/HierarchyNodeDescriptor.java","source/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java","source/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java","source/com/intellij/ide/hierarchy/HierarchyTreeStructure.java","source/com/intellij/ide/hierarchy/actions/BrowseCallHierarchyAction.java","source/com/intellij/ide/hierarchy/actions/BrowseMethodHierarchyAction.java","source/com/intellij/ide/hierarchy/actions/BrowseTypeHierarchyAction.java","source/com/intellij/ide/hierarchy/call/CallHierarchyBrowser.java","source/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java","source/com/intellij/ide/hierarchy/call/CalleeMethodsTreeStructure.java","source/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java","source/com/intellij/ide/hierarchy/method/ImplementMethodAction.java","source/com/intellij/ide/hierarchy/method/MethodHierarchyBrowser.java","source/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java","source/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java","source/com/intellij/ide/hierarchy/method/MethodHierarchyUtil.java","source/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java","source/com/intellij/ide/hierarchy/method/OverrideMethodAction.java","source/com/intellij/ide/hierarchy/type/SubtypesHierarchyTreeStructure.java","source/com/intellij/ide/hierarchy/type/SupertypesHierarchyTreeStructure.java","source/com/intellij/ide/hierarchy/type/TypeHierarchyBrowser.java","source/com/intellij/ide/hierarchy/type/TypeHierarchyNodeDescriptor.java","source/com/intellij/ide/hierarchy/type/TypeHierarchyTreeStructure.java","source/com/intellij/ide/highlighter/ArchiveFileType.java","source/com/intellij/ide/highlighter/DTDFileType.java","source/com/intellij/ide/highlighter/GuiFormFileType.java","source/com/intellij/ide/highlighter/HighlighterFactory.java","source/com/intellij/ide/highlighter/HtmlFileHighlighter.java","source/com/intellij/ide/highlighter/HtmlFileType.java","source/com/intellij/ide/highlighter/JavaClassFileType.java","source/com/intellij/ide/highlighter/JavaFileHighlighter.java","source/com/intellij/ide/highlighter/JavaFileType.java","source/com/intellij/ide/highlighter/ModuleFileType.java","source/com/intellij/ide/highlighter/ProjectFileType.java","source/com/intellij/ide/highlighter/UnknownFileType.java","source/com/intellij/ide/highlighter/WorkspaceFileType.java","source/com/intellij/ide/highlighter/XHtmlFileType.java","source/com/intellij/ide/highlighter/XmlFileHighlighter.java","source/com/intellij/ide/highlighter/XmlFileType.java","source/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java","source/com/intellij/ide/highlighter/custom/CustomFileHighlighter.java","source/com/intellij/ide/highlighter/custom/CustomFileTypeLexer.java","source/com/intellij/ide/highlighter/custom/CustomHighlighterColors.java","source/com/intellij/ide/highlighter/custom/PosBufferTokenizer.java","source/com/intellij/ide/highlighter/custom/SyntaxTable.java","source/com/intellij/ide/highlighter/custom/SyntaxTableLexer.java","source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java","source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java","source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java","source/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java","source/com/intellij/ide/highlighter/custom/tokens/BaseTokenParser.java","source/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java","source/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java","source/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java","source/com/intellij/ide/highlighter/custom/tokens/KeywordParser.java","source/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java","source/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java","source/com/intellij/ide/highlighter/custom/tokens/NumberParser.java","source/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java","source/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java","source/com/intellij/ide/highlighter/custom/tokens/TokenInfo.java","source/com/intellij/ide/highlighter/custom/tokens/TokenParser.java","source/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java","source/com/intellij/ide/impl/CommonActionsManagerImpl.java","source/com/intellij/ide/impl/ContentManagerWatcher.java","source/com/intellij/ide/impl/DataManagerImpl.java","source/com/intellij/ide/impl/DataValidator.java","source/com/intellij/ide/impl/EditorHighlighterImpl.java","source/com/intellij/ide/impl/PackageViewSelectInTarget.java","source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java","source/com/intellij/ide/impl/ProjectUtil.java","source/com/intellij/ide/impl/ProjectViewSelectInTarget.java","source/com/intellij/ide/impl/StructureViewSelectInTarget.java","source/com/intellij/ide/impl/StructureViewWrapper.java","source/com/intellij/ide/impl/dataRules/CopyProviderRule.java","source/com/intellij/ide/impl/dataRules/CutProviderRule.java","source/com/intellij/ide/impl/dataRules/FileEditorRule.java","source/com/intellij/ide/impl/dataRules/FileTextRule.java","source/com/intellij/ide/impl/dataRules/GetDataRule.java","source/com/intellij/ide/impl/dataRules/ModuleRule.java","source/com/intellij/ide/impl/dataRules/NavigatableRule.java","source/com/intellij/ide/impl/dataRules/PasteProviderRule.java","source/com/intellij/ide/impl/dataRules/PasteTargetRule.java","source/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java","source/com/intellij/ide/impl/dataRules/PsiFileRule.java","source/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java","source/com/intellij/ide/impl/dataRules/VirtualFileRule.java","source/com/intellij/ide/macro/ClasspathEntryMacro.java","source/com/intellij/ide/macro/ClasspathMacro.java","source/com/intellij/ide/macro/ColumnNumberMacro.java","source/com/intellij/ide/macro/DataAccessor.java","source/com/intellij/ide/macro/FileClassMacro.java","source/com/intellij/ide/macro/FileDirMacro.java","source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java","source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro2.java","source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java","source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro2.java","source/com/intellij/ide/macro/FileExtMacro.java","source/com/intellij/ide/macro/FileFQPackage.java","source/com/intellij/ide/macro/FileNameMacro.java","source/com/intellij/ide/macro/FileNameWithoutExtension.java","source/com/intellij/ide/macro/FilePackageMacro.java","source/com/intellij/ide/macro/FilePathMacro.java","source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java","source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro2.java","source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java","source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro2.java","source/com/intellij/ide/macro/FileRelativeDirMacro.java","source/com/intellij/ide/macro/FileRelativeDirMacro2.java","source/com/intellij/ide/macro/FileRelativePathMacro.java","source/com/intellij/ide/macro/FileRelativePathMacro2.java","source/com/intellij/ide/macro/JavaDocPathMacro.java","source/com/intellij/ide/macro/JdkPathMacro.java","source/com/intellij/ide/macro/LineNumberMacro.java","source/com/intellij/ide/macro/Macro.java","source/com/intellij/ide/macro/MacroManager.java","source/com/intellij/ide/macro/MacrosDialog.java","source/com/intellij/ide/macro/OutputPathMacro.java","source/com/intellij/ide/macro/ProjectFileDirMacro.java","source/com/intellij/ide/macro/ProjectFilePathMacro.java","source/com/intellij/ide/macro/ProjectNameMacro.java","source/com/intellij/ide/macro/ProjectPathMacro.java","source/com/intellij/ide/macro/PromptMacro.java","source/com/intellij/ide/macro/SecondQueueExpandMacro.java","source/com/intellij/ide/macro/SourcepathEntryMacro.java","source/com/intellij/ide/macro/SourcepathMacro.java","source/com/intellij/ide/plugins/AvailablePluginsTableModel.java","source/com/intellij/ide/plugins/InstalledPluginsTableModel.java","source/com/intellij/ide/plugins/PluginDescriptorComparator.java","source/com/intellij/ide/plugins/PluginInstaller.java","source/com/intellij/ide/plugins/PluginManager.java","source/com/intellij/ide/plugins/PluginManagerColumnInfo.java","source/com/intellij/ide/plugins/PluginManagerConfigurable.java","source/com/intellij/ide/plugins/PluginManagerMain.java","source/com/intellij/ide/plugins/PluginNode.java","source/com/intellij/ide/plugins/PluginTable.java","source/com/intellij/ide/plugins/PluginTableModel.java","source/com/intellij/ide/plugins/RepositoryContentHandler.java","source/com/intellij/ide/plugins/RepositoryHelper.java","source/com/intellij/ide/plugins/SortableProvider.java","source/com/intellij/ide/plugins/cl/PluginClassLoader.java","source/com/intellij/ide/projectView/BaseProjectTreeBuilder.java","source/com/intellij/ide/projectView/CompositePsiClasChildrenSource.java","source/com/intellij/ide/projectView/HelpID.java","source/com/intellij/ide/projectView/ProjectView.java","source/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java","source/com/intellij/ide/projectView/PsiClassChildrenSource.java","source/com/intellij/ide/projectView/actions/ChangeProjectViewAction.java","source/com/intellij/ide/projectView/actions/ProjectViewActionGroup.java","source/com/intellij/ide/projectView/impl/AbstractProjectTreeStructure.java","source/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java","source/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java","source/com/intellij/ide/projectView/impl/AbstractUrl.java","source/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java","source/com/intellij/ide/projectView/impl/DirectoryUrl.java","source/com/intellij/ide/projectView/impl/FormMergerTreeStructureProvider.java","source/com/intellij/ide/projectView/impl/ModuleGroup.java","source/com/intellij/ide/projectView/impl/ModuleUrl.java","source/com/intellij/ide/projectView/impl/MoveModuleToGroup.java","source/com/intellij/ide/projectView/impl/MoveModulesToGroupAction.java","source/com/intellij/ide/projectView/impl/PackageViewPane.java","source/com/intellij/ide/projectView/impl/ProjectAbstractTreeStructureBase.java","source/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java","source/com/intellij/ide/projectView/impl/ProjectTreeStructure.java","source/com/intellij/ide/projectView/impl/ProjectViewImpl.java","source/com/intellij/ide/projectView/impl/ProjectViewPane.java","source/com/intellij/ide/projectView/impl/ProjectViewTree.java","source/com/intellij/ide/projectView/impl/RenameModuleHandler.java","source/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java","source/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java","source/com/intellij/ide/projectView/impl/nodes/BasePsiNode.java","source/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java","source/com/intellij/ide/projectView/impl/nodes/Form.java","source/com/intellij/ide/projectView/impl/nodes/FormNode.java","source/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java","source/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java","source/com/intellij/ide/projectView/impl/nodes/ModuleGroupNode.java","source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java","source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java","source/com/intellij/ide/projectView/impl/nodes/PackageElement.java","source/com/intellij/ide/projectView/impl/nodes/PackageElementNode.java","source/com/intellij/ide/projectView/impl/nodes/PackageUtil.java","source/com/intellij/ide/projectView/impl/nodes/PackageViewLibrariesNode.java","source/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java","source/com/intellij/ide/projectView/impl/nodes/PackageViewProjectNode.java","source/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java","source/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java","source/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java","source/com/intellij/ide/projectView/impl/nodes/PsiFieldNode.java","source/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java","source/com/intellij/ide/projectView/impl/nodes/PsiMethodNode.java","source/com/intellij/ide/startup/CacheUpdater.java","source/com/intellij/ide/startup/FileContent.java","source/com/intellij/ide/startup/FileSystemSynchronizer.java","source/com/intellij/ide/startup/StartupActionScriptManager.java","source/com/intellij/ide/startup/StartupManagerEx.java","source/com/intellij/ide/startup/impl/StartupManagerImpl.java","source/com/intellij/ide/structureView/StructureView.java","source/com/intellij/ide/structureView/StructureViewExtension.java","source/com/intellij/ide/structureView/StructureViewFactory.java","source/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java","source/com/intellij/ide/structureView/impl/StructureNodeRenderer.java","source/com/intellij/ide/structureView/impl/StructureTreeBuilder.java","source/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java","source/com/intellij/ide/structureView/impl/StructureViewState.java","source/com/intellij/ide/structureView/impl/VisibilityComparator.java","source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java","source/com/intellij/ide/structureView/impl/java/AccessLevelProvider.java","source/com/intellij/ide/structureView/impl/java/FieldsFilter.java","source/com/intellij/ide/structureView/impl/java/InheritedMembersFilter.java","source/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java","source/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java","source/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java","source/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java","source/com/intellij/ide/structureView/impl/java/KindSorter.java","source/com/intellij/ide/structureView/impl/java/PropertiesGrouper.java","source/com/intellij/ide/structureView/impl/java/PropertyGroup.java","source/com/intellij/ide/structureView/impl/java/PsiFieldTreeElement.java","source/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java","source/com/intellij/ide/structureView/impl/java/PublicElementsFilter.java","source/com/intellij/ide/structureView/impl/java/SuperTypeGroup.java","source/com/intellij/ide/structureView/impl/java/SuperTypesGrouper.java","source/com/intellij/ide/structureView/impl/xml/XmlFileTreeElement.java","source/com/intellij/ide/structureView/impl/xml/XmlStructureViewTreeModel.java","source/com/intellij/ide/structureView/impl/xml/XmlTagTreeElement.java","source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java","source/com/intellij/ide/structureView/newStructureView/TreeActionWrapper.java","source/com/intellij/ide/structureView/newStructureView/TreeActionsOwner.java","source/com/intellij/ide/structureView/newStructureView/TreeModelWrapper.java","source/com/intellij/ide/todo/AllTodosTreeBuilder.java","source/com/intellij/ide/todo/AllTodosTreeStructure.java","source/com/intellij/ide/todo/CurrentFileTodosPanel.java","source/com/intellij/ide/todo/CurrentFileTodosTreeBuilder.java","source/com/intellij/ide/todo/CurrentFileTodosTreeStructure.java","source/com/intellij/ide/todo/FileTree.java","source/com/intellij/ide/todo/HighlightedRegionProvider.java","source/com/intellij/ide/todo/SmartTodoItemPointer.java","source/com/intellij/ide/todo/SmartTodoItemPointerComparator.java","source/com/intellij/ide/todo/ToDoSettings.java","source/com/intellij/ide/todo/ToDoSummary.java","source/com/intellij/ide/todo/TodoCompositeRenderer.java","source/com/intellij/ide/todo/TodoConfiguration.java","source/com/intellij/ide/todo/TodoFileDirComparator.java","source/com/intellij/ide/todo/TodoFilter.java","source/com/intellij/ide/todo/TodoPanel.java","source/com/intellij/ide/todo/TodoPanelSettings.java","source/com/intellij/ide/todo/TodoTreeBuilder.java","source/com/intellij/ide/todo/TodoTreeStructure.java","source/com/intellij/ide/todo/TodoView.java","source/com/intellij/ide/todo/configurable/FilterDialog.java","source/com/intellij/ide/todo/configurable/FiltersTableModel.java","source/com/intellij/ide/todo/configurable/PatternDialog.java","source/com/intellij/ide/todo/configurable/PatternsTableModel.java","source/com/intellij/ide/todo/configurable/TodoConfigurable.java","source/com/intellij/ide/todo/configurable/TodoPatternTableCellRenderer.java","source/com/intellij/ide/todo/configurable/TodoTypeListCellRenderer.java","source/com/intellij/ide/todo/configurable/TodoTypeTableCellRenderer.java","source/com/intellij/ide/todo/nodes/BaseToDoNode.java","source/com/intellij/ide/todo/nodes/SingleFileToDoNode.java","source/com/intellij/ide/todo/nodes/SummaryNode.java","source/com/intellij/ide/todo/nodes/ToDoRootNode.java","source/com/intellij/ide/todo/nodes/TodoDirNode.java","source/com/intellij/ide/todo/nodes/TodoFileNode.java","source/com/intellij/ide/todo/nodes/TodoItemNode.java","source/com/intellij/ide/ui/AppearanceConfigurable.java","source/com/intellij/ide/ui/LafManager.java","source/com/intellij/ide/ui/LafManagerListener.java","source/com/intellij/ide/ui/UISettings.java","source/com/intellij/ide/ui/UISettingsListener.java","source/com/intellij/ide/updates/UpdateChecker.java","source/com/intellij/ide/util/DeleteDialog.java","source/com/intellij/ide/util/DeleteHandler.java","source/com/intellij/ide/util/DeleteUtil.java","source/com/intellij/ide/util/DirectoryChooser.java","source/com/intellij/ide/util/DirectoryChooserModuleTreeView.java","source/com/intellij/ide/util/DirectoryChooserView.java","source/com/intellij/ide/util/DirectoryUtil.java","source/com/intellij/ide/util/EditSourceUtil.java","source/com/intellij/ide/util/EditorHelper.java","source/com/intellij/ide/util/ElementsChooser.java","source/com/intellij/ide/util/ExportToFileUtil.java","source/com/intellij/ide/util/FQNameCellRenderer.java","source/com/intellij/ide/util/FileStructureDialog.java","source/com/intellij/ide/util/GotoLineNumberDialog.java","source/com/intellij/ide/util/JavaUtil.java","source/com/intellij/ide/util/MemberChooser.java","source/com/intellij/ide/util/MemberContainerCellRenderer.java","source/com/intellij/ide/util/NavigationItemListCellRenderer.java","source/com/intellij/ide/util/PackageChooserDialog.java","source/com/intellij/ide/util/PackageUtil.java","source/com/intellij/ide/util/PropertiesComponentImpl.java","source/com/intellij/ide/util/PsiClassListCellRenderer.java","source/com/intellij/ide/util/PsiElementListCellRenderer.java","source/com/intellij/ide/util/SuperMethodOrPointcutWarningDialog.java","source/com/intellij/ide/util/SuperMethodWarningUtil.java","source/com/intellij/ide/util/TipDialog.java","source/com/intellij/ide/util/TipPanel.java","source/com/intellij/ide/util/TipUIUtil.java","source/com/intellij/ide/util/TreeClassChooserDialog.java","source/com/intellij/ide/util/gotoByName/ChooseByNameBase.java","source/com/intellij/ide/util/gotoByName/ChooseByNameModel.java","source/com/intellij/ide/util/gotoByName/ChooseByNamePanel.java","source/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java","source/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java","source/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java","source/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java","source/com/intellij/ide/util/gotoByName/GotoClassModel2.java","source/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java","source/com/intellij/ide/util/gotoByName/GotoFileModel.java","source/com/intellij/ide/util/gotoByName/GotoSymbolCellRenderer.java","source/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java","source/com/intellij/ide/util/projectWizard/JdkChooserPanel.java","source/com/intellij/ide/util/projectWizard/ModuleCreationPromptStep.java","source/com/intellij/ide/util/projectWizard/ModuleTypeStep.java","source/com/intellij/ide/util/projectWizard/NameLocationStep.java","source/com/intellij/ide/util/projectWizard/NamePathComponent.java","source/com/intellij/ide/util/projectWizard/OutputPathsStep.java","source/com/intellij/ide/util/projectWizard/ProjectJdkStep.java","source/com/intellij/ide/util/projectWizard/ProjectNameStep.java","source/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java","source/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java","source/com/intellij/ide/util/projectWizard/SourcePathsStep.java","source/com/intellij/ide/util/projectWizard/ToolbarPanel.java","source/com/intellij/ide/util/scopeChooser/PackageSetChooserCombo.java","source/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java","source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java","source/com/intellij/ide/util/treeView/AbstractTreeBuilder.java","source/com/intellij/ide/util/treeView/AbstractTreeStructure.java","source/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java","source/com/intellij/ide/util/treeView/AbstractTreeUpdater.java","source/com/intellij/ide/util/treeView/AlphaComparator.java","source/com/intellij/ide/util/treeView/IndexComparator.java","source/com/intellij/ide/util/treeView/SmartElementDescriptor.java","source/com/intellij/ide/util/treeView/SourceComparator.java","source/com/intellij/ide/util/treeView/TreeBuilderUtil.java","source/com/intellij/ide/util/treeView/TreeViewUtil.java","source/com/intellij/ide/util/treeView/XmlDoctypeNodeDescriptor.java","source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java","source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java","source/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java","source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java","source/com/intellij/idea/CommandLineApplication.java","source/com/intellij/idea/IdeaApplication.java","source/com/intellij/idea/IdeaLogger.java","source/com/intellij/idea/IdeaTestApplication.java","source/com/intellij/idea/Launcher.java","source/com/intellij/idea/LoggerFactory.java","source/com/intellij/idea/SocketLock.java","source/com/intellij/internal/diGraph/Edge.java","source/com/intellij/internal/diGraph/Node.java","source/com/intellij/internal/diGraph/analyzer/GlobalAnalyzer.java","source/com/intellij/internal/diGraph/analyzer/Mark.java","source/com/intellij/internal/diGraph/analyzer/MarkedEdge.java","source/com/intellij/internal/diGraph/analyzer/MarkedNode.java","source/com/intellij/internal/diGraph/analyzer/OneEndFunctor.java","source/com/intellij/internal/diGraph/analyzer/TwoEndsFunctor.java","source/com/intellij/internal/diGraph/impl/EdgeImpl.java","source/com/intellij/internal/diGraph/impl/NodeImpl.java","source/com/intellij/internal/encodings/DecodeBytesAction.java","source/com/intellij/internal/encodings/EncodingViewer.java","source/com/intellij/internal/psiView/PsiViewerDialog.java","source/com/intellij/internal/psiView/ViewerAction.java","source/com/intellij/internal/psiView/ViewerNodeDescriptor.java","source/com/intellij/internal/psiView/ViewerTreeBuilder.java","source/com/intellij/internal/psiView/ViewerTreeStructure.java","source/com/intellij/j2ee/extResources/AddEditRemovePanel.java","source/com/intellij/j2ee/extResources/EditLocationDialog.java","source/com/intellij/j2ee/extResources/ExternalResourceConfigurable.java","source/com/intellij/j2ee/extResources/ExternalResourceListener.java","source/com/intellij/j2ee/make/BuildInstructionBase.java","source/com/intellij/j2ee/make/BuildRecipeImpl.java","source/com/intellij/j2ee/make/FileCopyInstructionImpl.java","source/com/intellij/j2ee/make/IgnoredFileFilter.java","source/com/intellij/j2ee/make/J2EEModuleBuildInstructionImpl.java","source/com/intellij/j2ee/make/JarAndCopyBuildInstructionImpl.java","source/com/intellij/j2ee/module/J2EEModuleContainerImpl.java","source/com/intellij/j2ee/module/LibraryLinkImpl.java","source/com/intellij/j2ee/module/ModuleLinkImpl.java","source/com/intellij/j2ee/module/OrderEntryInfo.java","source/com/intellij/j2ee/module/ResolvableElement.java","source/com/intellij/j2ee/module/TransactionalEditable.java","source/com/intellij/j2ee/module/view/common/editor/SplitterProportionsData.java","source/com/intellij/j2ee/openapi/ex/ExternalResourceManagerEx.java","source/com/intellij/j2ee/openapi/impl/ExternalResourceManagerImpl.java","source/com/intellij/j2ee/openapi/impl/LibrariesManagerImpl.java","source/com/intellij/j2ee/run/localRun/EnvVariablesTable.java","source/com/intellij/javadoc/GenerateJavadocDialog.java","source/com/intellij/javadoc/JavadocConfigurable.java","source/com/intellij/javadoc/JavadocConfiguration.java","source/com/intellij/javadoc/JavadocGenerationManager.java","source/com/intellij/javadoc/JavadocGenerationPanel.java","source/com/intellij/javadoc/actions/GenerateJavadocAction.java","source/com/intellij/jsp/impl/TldTagDescriptor.java","source/com/intellij/lexer/BaseHtmlLexer.java","source/com/intellij/lexer/DtdHighlightingLexer.java","source/com/intellij/lexer/EscapedJavaLexer.java","source/com/intellij/lexer/HtmlHighlightingLexer.java","source/com/intellij/lexer/HtmlLexer.java","source/com/intellij/lexer/JavaDocLexer.java","source/com/intellij/lexer/JavaHighlightingLexer.java","source/com/intellij/lexer/JavaLexer.java","source/com/intellij/lexer/OldXmlLexer.java","source/com/intellij/lexer/StringLiteralLexer.java","source/com/intellij/lexer/XHtmlHighlightingLexer.java","source/com/intellij/lexer/XHtmlLexer.java","source/com/intellij/lexer/XmlHighlightingLexer.java","source/com/intellij/lexer/XmlLexer.java","source/com/intellij/lexer/_HtmlLexer.java","source/com/intellij/lexer/_JavaLexer.java","source/com/intellij/lexer/_OldXmlLexer.java","source/com/intellij/lexer/_XmlLexer.java","source/com/intellij/openapi/actionSystem/ex/ActionButtonLook.java","source/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java","source/com/intellij/openapi/actionSystem/ex/AnActionListener.java","source/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java","source/com/intellij/openapi/actionSystem/ex/QuickList.java","source/com/intellij/openapi/actionSystem/ex/QuickListsManager.java","source/com/intellij/openapi/actionSystem/ex/TimerListener.java","source/com/intellij/openapi/actionSystem/impl/ActionButton.java","source/com/intellij/openapi/actionSystem/impl/ActionButtonWithText.java","source/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java","source/com/intellij/openapi/actionSystem/impl/ActionMenu.java","source/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java","source/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java","source/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java","source/com/intellij/openapi/actionSystem/impl/EmptyIcon.java","source/com/intellij/openapi/actionSystem/impl/IdeaActionButtonLook.java","source/com/intellij/openapi/actionSystem/impl/PresentationFactory.java","source/com/intellij/openapi/actionSystem/impl/ProxyShortcutSet.java","source/com/intellij/openapi/actionSystem/impl/StubItem.java","source/com/intellij/openapi/actionSystem/impl/Utils.java","source/com/intellij/openapi/actionSystem/impl/WeakTimerListener.java","source/com/intellij/openapi/application/ex/ApplicationEx.java","source/com/intellij/openapi/application/ex/ApplicationInfoEx.java","source/com/intellij/openapi/application/ex/ApplicationManagerEx.java","source/com/intellij/openapi/application/ex/DecodeDefaultsUtil.java","source/com/intellij/openapi/application/ex/PathManagerEx.java","source/com/intellij/openapi/application/impl/ApplicationImpl.java","source/com/intellij/openapi/application/impl/ApplicationInfoImpl.java","source/com/intellij/openapi/application/impl/LaterInvocatorEx.java","source/com/intellij/openapi/application/impl/ModalityStateEx.java","source/com/intellij/openapi/command/CommandProcessorEx.java","source/com/intellij/openapi/command/impl/CommandMerger.java","source/com/intellij/openapi/command/impl/CommandProcessorImpl.java","source/com/intellij/openapi/command/impl/CurrentEditorProvider.java","source/com/intellij/openapi/command/impl/DocumentEditingUndoProvider.java","source/com/intellij/openapi/command/impl/DocumentReferenceByDocument.java","source/com/intellij/openapi/command/impl/DocumentReferenceByVirtualFile.java","source/com/intellij/openapi/command/impl/DummyProject.java","source/com/intellij/openapi/command/impl/EditorAndState.java","source/com/intellij/openapi/command/impl/EditorChangeAction.java","source/com/intellij/openapi/command/impl/FileOperationsUndoProvider.java","source/com/intellij/openapi/command/impl/FocusBasedCurrentEditorProvider.java","source/com/intellij/openapi/command/impl/Redo.java","source/com/intellij/openapi/command/impl/Undo.java","source/com/intellij/openapi/command/impl/UndoManagerImpl.java","source/com/intellij/openapi/command/impl/UndoOrRedo.java","source/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java","source/com/intellij/openapi/command/impl/UndoableGroup.java","source/com/intellij/openapi/command/undo/DocumentReference.java","source/com/intellij/openapi/command/undo/NonUndoableAction.java","source/com/intellij/openapi/command/undo/UndoManager.java","source/com/intellij/openapi/command/undo/UndoableAction.java","source/com/intellij/openapi/command/undo/UnexpectedUndoException.java","source/com/intellij/openapi/compiler/ex/CompileContextEx.java","source/com/intellij/openapi/compiler/ex/CompilerPathsEx.java","source/com/intellij/openapi/components/ex/ComponentManagerEx.java","source/com/intellij/openapi/components/ex/ComponentRegistrar.java","source/com/intellij/openapi/components/impl/ComponentManagerImpl.java","source/com/intellij/openapi/diff/actions/BaseDiffAction.java","source/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java","source/com/intellij/openapi/diff/actions/CompareFileWithEditor.java","source/com/intellij/openapi/diff/actions/CompareFiles.java","source/com/intellij/openapi/diff/actions/DiffActions.java","source/com/intellij/openapi/diff/actions/DiffWalkerAction.java","source/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java","source/com/intellij/openapi/diff/actions/MergeActionGroup.java","source/com/intellij/openapi/diff/actions/MergeFilesAction.java","source/com/intellij/openapi/diff/actions/MergeOperations.java","source/com/intellij/openapi/diff/actions/NextDiffAction.java","source/com/intellij/openapi/diff/actions/PreviousDiffAction.java","source/com/intellij/openapi/diff/ex/DiffContentFactory.java","source/com/intellij/openapi/diff/ex/DiffFragment.java","source/com/intellij/openapi/diff/ex/DiffPanelEx.java","source/com/intellij/openapi/diff/ex/DiffPanelOptions.java","source/com/intellij/openapi/diff/ex/DiffStatusBar.java","source/com/intellij/openapi/diff/impl/ComparisonPolicy.java","source/com/intellij/openapi/diff/impl/ContentChangeListener.java","source/com/intellij/openapi/diff/impl/CurrentLineMarker.java","source/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java","source/com/intellij/openapi/diff/impl/DiffHighliterFactory.java","source/com/intellij/openapi/diff/impl/DiffHighliterFactoryImpl.java","source/com/intellij/openapi/diff/impl/DiffPanelImpl.java","source/com/intellij/openapi/diff/impl/DiffRange.java","source/com/intellij/openapi/diff/impl/DiffSideView.java","source/com/intellij/openapi/diff/impl/DiffSidesContainer.java","source/com/intellij/openapi/diff/impl/DiffSplitter.java","source/com/intellij/openapi/diff/impl/DiffToolbarComponent.java","source/com/intellij/openapi/diff/impl/DiffToolbarImpl.java","source/com/intellij/openapi/diff/impl/DiffUtil.java","source/com/intellij/openapi/diff/impl/DiffVersionComponent.java","source/com/intellij/openapi/diff/impl/EditingSides.java","source/com/intellij/openapi/diff/impl/EditorSource.java","source/com/intellij/openapi/diff/impl/FrameWrapper.java","source/com/intellij/openapi/diff/impl/Rediffers.java","source/com/intellij/openapi/diff/impl/TwoSidesContainer.java","source/com/intellij/openapi/diff/impl/external/BaseExternalTool.java","source/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java","source/com/intellij/openapi/diff/impl/external/CompositeDiffTool.java","source/com/intellij/openapi/diff/impl/external/DiffManagerImpl.java","source/com/intellij/openapi/diff/impl/external/DiffOptionsForm.java","source/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java","source/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java","source/com/intellij/openapi/diff/impl/external/FrameDiffTool.java","source/com/intellij/openapi/diff/impl/fragments/Fragment.java","source/com/intellij/openapi/diff/impl/fragments/FragmentList.java","source/com/intellij/openapi/diff/impl/fragments/FragmentListImpl.java","source/com/intellij/openapi/diff/impl/fragments/InlineFragment.java","source/com/intellij/openapi/diff/impl/fragments/LineBlock.java","source/com/intellij/openapi/diff/impl/fragments/LineFragment.java","source/com/intellij/openapi/diff/impl/highlighting/BufferedStringList.java","source/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java","source/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java","source/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java","source/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java","source/com/intellij/openapi/diff/impl/highlighting/LineBlockDivider.java","source/com/intellij/openapi/diff/impl/highlighting/LineRenderer.java","source/com/intellij/openapi/diff/impl/highlighting/List2D.java","source/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java","source/com/intellij/openapi/diff/impl/highlighting/Util.java","source/com/intellij/openapi/diff/impl/incrementalMerge/Change.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeCounter.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ConflictChange.java","source/com/intellij/openapi/diff/impl/incrementalMerge/DiffRangeMarker.java","source/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilder.java","source/com/intellij/openapi/diff/impl/incrementalMerge/MergeConflict.java","source/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java","source/com/intellij/openapi/diff/impl/incrementalMerge/MergeSearchHelper.java","source/com/intellij/openapi/diff/impl/incrementalMerge/SimpleChange.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java","source/com/intellij/openapi/diff/impl/incrementalMerge/ui/OpenPartialDiffAction.java","source/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java","source/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java","source/com/intellij/openapi/diff/impl/mergeTool/MergeTool.java","source/com/intellij/openapi/diff/impl/mergeTool/MergeVersion.java","source/com/intellij/openapi/diff/impl/processing/ByWord.java","source/com/intellij/openapi/diff/impl/processing/DiffCorrection.java","source/com/intellij/openapi/diff/impl/processing/DiffFragmentsProcessor.java","source/com/intellij/openapi/diff/impl/processing/DiffPolicy.java","source/com/intellij/openapi/diff/impl/processing/Formatting.java","source/com/intellij/openapi/diff/impl/processing/FragmentsCollector.java","source/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java","source/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java","source/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java","source/com/intellij/openapi/diff/impl/processing/UniteSameType.java","source/com/intellij/openapi/diff/impl/processing/Word.java","source/com/intellij/openapi/diff/impl/settings/DiffColorsForm.java","source/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java","source/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java","source/com/intellij/openapi/diff/impl/splitter/FoldingTransformation.java","source/com/intellij/openapi/diff/impl/splitter/Interval.java","source/com/intellij/openapi/diff/impl/splitter/LineBlocks.java","source/com/intellij/openapi/diff/impl/splitter/LinearTransformation.java","source/com/intellij/openapi/diff/impl/splitter/Transformation.java","source/com/intellij/openapi/diff/impl/splitter/Trapezium.java","source/com/intellij/openapi/diff/impl/util/ContentDocumentListener.java","source/com/intellij/openapi/diff/impl/util/ContextLogger.java","source/com/intellij/openapi/diff/impl/util/DiffDivider.java","source/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java","source/com/intellij/openapi/diff/impl/util/DocumentUtil.java","source/com/intellij/openapi/diff/impl/util/FocusDiffSide.java","source/com/intellij/openapi/diff/impl/util/FontSizeSynchronizer.java","source/com/intellij/openapi/diff/impl/util/GutterActionRenderer.java","source/com/intellij/openapi/diff/impl/util/LabeledEditor.java","source/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java","source/com/intellij/openapi/diff/impl/util/TextDiffType.java","source/com/intellij/openapi/diff/impl/util/ThreePanels.java","source/com/intellij/openapi/editor/actions/BackspaceAction.java","source/com/intellij/openapi/editor/actions/CopyAction.java","source/com/intellij/openapi/editor/actions/CutAction.java","source/com/intellij/openapi/editor/actions/CutLineEndAction.java","source/com/intellij/openapi/editor/actions/DeleteAction.java","source/com/intellij/openapi/editor/actions/DeleteLineAtCaretAction.java","source/com/intellij/openapi/editor/actions/DeleteToWordEndAction.java","source/com/intellij/openapi/editor/actions/DeleteToWordStartAction.java","source/com/intellij/openapi/editor/actions/DuplicateAction.java","source/com/intellij/openapi/editor/actions/EditorActionUtil.java","source/com/intellij/openapi/editor/actions/EmacsStyleIndentAction.java","source/com/intellij/openapi/editor/actions/EnterAction.java","source/com/intellij/openapi/editor/actions/EscapeAction.java","source/com/intellij/openapi/editor/actions/FindAction.java","source/com/intellij/openapi/editor/actions/FindWordAtCaretAction.java","source/com/intellij/openapi/editor/actions/IndentSelectionAction.java","source/com/intellij/openapi/editor/actions/JoinLinesAction.java","source/com/intellij/openapi/editor/actions/LineEndAction.java","source/com/intellij/openapi/editor/actions/LineEndWithSelectionAction.java","source/com/intellij/openapi/editor/actions/LineStartAction.java","source/com/intellij/openapi/editor/actions/LineStartWithSelectionAction.java","source/com/intellij/openapi/editor/actions/MoveCaretDownAction.java","source/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java","source/com/intellij/openapi/editor/actions/MoveCaretLeftAction.java","source/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java","source/com/intellij/openapi/editor/actions/MoveCaretRightAction.java","source/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java","source/com/intellij/openapi/editor/actions/MoveCaretUpAction.java","source/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java","source/com/intellij/openapi/editor/actions/MoveDownAndScrollAction.java","source/com/intellij/openapi/editor/actions/MoveDownWithSelectionAndScrollAction.java","source/com/intellij/openapi/editor/actions/MoveUpAndScrollAction.java","source/com/intellij/openapi/editor/actions/MoveUpWithSelectionAndScrollAction.java","source/com/intellij/openapi/editor/actions/MultiplePasteAction.java","source/com/intellij/openapi/editor/actions/NextWordAction.java","source/com/intellij/openapi/editor/actions/NextWordWithSelectionAction.java","source/com/intellij/openapi/editor/actions/PageBottomAction.java","source/com/intellij/openapi/editor/actions/PageBottomWithSelectionAction.java","source/com/intellij/openapi/editor/actions/PageDownAction.java","source/com/intellij/openapi/editor/actions/PageDownWithSelectionAction.java","source/com/intellij/openapi/editor/actions/PageTopAction.java","source/com/intellij/openapi/editor/actions/PageTopWithSelectionAction.java","source/com/intellij/openapi/editor/actions/PageUpAction.java","source/com/intellij/openapi/editor/actions/PageUpWithSelectionAction.java","source/com/intellij/openapi/editor/actions/PasteAction.java","source/com/intellij/openapi/editor/actions/PasteFromX11Action.java","source/com/intellij/openapi/editor/actions/PreviousWordAction.java","source/com/intellij/openapi/editor/actions/PreviousWordWithSelectionAction.java","source/com/intellij/openapi/editor/actions/ReplaceAction.java","source/com/intellij/openapi/editor/actions/ScrollDownAction.java","source/com/intellij/openapi/editor/actions/ScrollToCenterAction.java","source/com/intellij/openapi/editor/actions/ScrollUpAction.java","source/com/intellij/openapi/editor/actions/SelectLineAction.java","source/com/intellij/openapi/editor/actions/SelectWordAtCaretAction.java","source/com/intellij/openapi/editor/actions/SplitLineAction.java","source/com/intellij/openapi/editor/actions/StartNewLineAction.java","source/com/intellij/openapi/editor/actions/TabAction.java","source/com/intellij/openapi/editor/actions/TextEndAction.java","source/com/intellij/openapi/editor/actions/TextEndWithSelectionAction.java","source/com/intellij/openapi/editor/actions/TextStartAction.java","source/com/intellij/openapi/editor/actions/TextStartWithSelectionAction.java","source/com/intellij/openapi/editor/actions/ToggleCaseAction.java","source/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java","source/com/intellij/openapi/editor/actions/ToggleInsertStateAction.java","source/com/intellij/openapi/editor/actions/ToggleShowLineNumbersAction.java","source/com/intellij/openapi/editor/actions/ToggleShowWhitespacesAction.java","source/com/intellij/openapi/editor/actions/UnindentSelectionAction.java","source/com/intellij/openapi/editor/actions/UnselectWordAtCaretAction.java","source/com/intellij/openapi/editor/colors/ex/DefaultColorSchemesManager.java","source/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java","source/com/intellij/openapi/editor/colors/impl/DefaultColorsScheme.java","source/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java","source/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java","source/com/intellij/openapi/editor/ex/DocumentEx.java","source/com/intellij/openapi/editor/ex/EditReadOnlyListener.java","source/com/intellij/openapi/editor/ex/EditorEventMulticasterEx.java","source/com/intellij/openapi/editor/ex/EditorEx.java","source/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java","source/com/intellij/openapi/editor/ex/EditorMarkupModel.java","source/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java","source/com/intellij/openapi/editor/ex/ErrorStripeAdapter.java","source/com/intellij/openapi/editor/ex/ErrorStripeEvent.java","source/com/intellij/openapi/editor/ex/ErrorStripeListener.java","source/com/intellij/openapi/editor/ex/FocusChangeListener.java","source/com/intellij/openapi/editor/ex/FoldingModelEx.java","source/com/intellij/openapi/editor/ex/Highlighter.java","source/com/intellij/openapi/editor/ex/HighlighterIterator.java","source/com/intellij/openapi/editor/ex/LineIterator.java","source/com/intellij/openapi/editor/ex/MarkupModelEx.java","source/com/intellij/openapi/editor/ex/RangeHighlighterEx.java","source/com/intellij/openapi/editor/ex/util/EditorUtil.java","source/com/intellij/openapi/editor/ex/util/EmptyHighlighter.java","source/com/intellij/openapi/editor/ex/util/LexerHighlighter.java","source/com/intellij/openapi/editor/ex/util/SegmentArray.java","source/com/intellij/openapi/editor/ex/util/SegmentArrayWithData.java","source/com/intellij/openapi/editor/impl/BorderEffect.java","source/com/intellij/openapi/editor/impl/CaretModelImpl.java","source/com/intellij/openapi/editor/impl/DocumentImpl.java","source/com/intellij/openapi/editor/impl/DocumentMarkupModelManager.java","source/com/intellij/openapi/editor/impl/EditorActionManagerImpl.java","source/com/intellij/openapi/editor/impl/EditorComponentImpl.java","source/com/intellij/openapi/editor/impl/EditorFactoryImpl.java","source/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java","source/com/intellij/openapi/editor/impl/EditorImpl.java","source/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java","source/com/intellij/openapi/editor/impl/FoldRegionImpl.java","source/com/intellij/openapi/editor/impl/FoldingModelImpl.java","source/com/intellij/openapi/editor/impl/HighlighterList.java","source/com/intellij/openapi/editor/impl/IterationState.java","source/com/intellij/openapi/editor/impl/LeftHandScrollbarLayout.java","source/com/intellij/openapi/editor/impl/LineIteratorImpl.java","source/com/intellij/openapi/editor/impl/LineSet.java","source/com/intellij/openapi/editor/impl/MarkupModelImpl.java","source/com/intellij/openapi/editor/impl/PersistentLineMarker.java","source/com/intellij/openapi/editor/impl/PersistentRangeMarker.java","source/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java","source/com/intellij/openapi/editor/impl/RangeIterator.java","source/com/intellij/openapi/editor/impl/RangeMarkerImpl.java","source/com/intellij/openapi/editor/impl/ScrollingModelImpl.java","source/com/intellij/openapi/editor/impl/SelectionModelImpl.java","source/com/intellij/openapi/editor/impl/SettingsImpl.java","source/com/intellij/openapi/editor/impl/VisibleEditorsTracker.java","source/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java","source/com/intellij/openapi/editor/impl/event/EditorEventMulticasterImpl.java","source/com/intellij/openapi/editor/impl/event/MarkupModelEvent.java","source/com/intellij/openapi/editor/impl/event/MarkupModelListener.java","source/com/intellij/openapi/editor/markup/MarkupEditorFilterFactory.java","source/com/intellij/openapi/fileChooser/actions/FileDeleteAction.java","source/com/intellij/openapi/fileChooser/actions/GotoHomeAction.java","source/com/intellij/openapi/fileChooser/actions/GotoProjectDirectory.java","source/com/intellij/openapi/fileChooser/actions/NewFolderAction.java","source/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java","source/com/intellij/openapi/fileChooser/ex/FileNodeDescriptor.java","source/com/intellij/openapi/fileChooser/ex/FileSystemTreeFactoryImpl.java","source/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java","source/com/intellij/openapi/fileChooser/ex/RootFileElement.java","source/com/intellij/openapi/fileChooser/impl/FileChooserFactoryImpl.java","source/com/intellij/openapi/fileChooser/impl/FileComparator.java","source/com/intellij/openapi/fileChooser/impl/FileTreeBuilder.java","source/com/intellij/openapi/fileChooser/impl/FileTreeStructure.java","source/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java","source/com/intellij/openapi/fileEditor/ex/FileEditorProviderManager.java","source/com/intellij/openapi/fileEditor/ex/IdeDocumentHistory.java","source/com/intellij/openapi/fileEditor/impl/EditorComposite.java","source/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java","source/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java","source/com/intellij/openapi/fileEditor/impl/EditorWindow.java","source/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java","source/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java","source/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java","source/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java","source/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java","source/com/intellij/openapi/fileEditor/impl/HistoryEntry.java","source/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java","source/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java","source/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java","source/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java","source/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java","source/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java","source/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java","source/com/intellij/openapi/fileTypes/PlainTextFileType.java","source/com/intellij/openapi/fileTypes/UserBinaryFileType.java","source/com/intellij/openapi/fileTypes/ex/FakeFileType.java","source/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java","source/com/intellij/openapi/fileTypes/ex/FileTypeManagerEx.java","source/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java","source/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java","source/com/intellij/openapi/fileTypes/impl/FileTypeRenderer.java","source/com/intellij/openapi/keymap/ex/KeymapManagerEx.java","source/com/intellij/openapi/keymap/ex/KeymapManagerListener.java","source/com/intellij/openapi/keymap/ex/WeakKeymapManagerListener.java","source/com/intellij/openapi/keymap/impl/Converter01.java","source/com/intellij/openapi/keymap/impl/DefaultKeymap.java","source/com/intellij/openapi/keymap/impl/DefaultKeymapImpl.java","source/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java","source/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java","source/com/intellij/openapi/keymap/impl/KeymapImpl.java","source/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java","source/com/intellij/openapi/keymap/impl/MacOSDefaultKeymap.java","source/com/intellij/openapi/keymap/impl/ui/ActionsTree.java","source/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java","source/com/intellij/openapi/keymap/impl/ui/EditKeymapsDialog.java","source/com/intellij/openapi/keymap/impl/ui/EditQuickListDialog.java","source/com/intellij/openapi/keymap/impl/ui/KeyboardShortcutDialog.java","source/com/intellij/openapi/keymap/impl/ui/KeymapConfigurable.java","source/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java","source/com/intellij/openapi/keymap/impl/ui/MouseShortcutDialog.java","source/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java","source/com/intellij/openapi/localVcs/impl/LvcsConfigurable.java","source/com/intellij/openapi/localVcs/impl/UpToDateLineNumberProviderImpl.java","source/com/intellij/openapi/module/JavaModuleType.java","source/com/intellij/openapi/module/UnknownModuleType.java","source/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java","source/com/intellij/openapi/module/impl/ModuleImpl.java","source/com/intellij/openapi/module/impl/ModuleManagerImpl.java","source/com/intellij/openapi/module/impl/ModulePointerImpl.java","source/com/intellij/openapi/module/impl/ModuleTypeManagerImpl.java","source/com/intellij/openapi/module/impl/ModuleUtil.java","source/com/intellij/openapi/options/colors/pages/ColorSettingsPagesImpl.java","source/com/intellij/openapi/options/colors/pages/CustomColorsPage.java","source/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java","source/com/intellij/openapi/options/colors/pages/HTMLColorsPage.java","source/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java","source/com/intellij/openapi/options/colors/pages/XMLColorsPage.java","source/com/intellij/openapi/options/ex/ControlPanelMnemonicsUtil.java","source/com/intellij/openapi/options/ex/ControlPanelSettingsEditor.java","source/com/intellij/openapi/options/ex/ExplorerSettingsEditor.java","source/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java","source/com/intellij/openapi/options/ex/ProjectConfigurableWrapper.java","source/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java","source/com/intellij/openapi/options/ex/SingleConfigurableEditor.java","source/com/intellij/openapi/progress/impl/ProgressManagerImpl.java","source/com/intellij/openapi/progress/util/BlockingProgressIndicator.java","source/com/intellij/openapi/progress/util/ColorProgressBar.java","source/com/intellij/openapi/progress/util/CommandLineProgress.java","source/com/intellij/openapi/progress/util/DispatchThreadProgressWindow.java","source/com/intellij/openapi/progress/util/MaxIntervalCalculator.java","source/com/intellij/openapi/progress/util/ProgressBar.java","source/com/intellij/openapi/progress/util/ProgressIndicatorBase.java","source/com/intellij/openapi/progress/util/ProgressIndicatorListener.java","source/com/intellij/openapi/progress/util/ProgressIndicatorListenerAdapter.java","source/com/intellij/openapi/progress/util/ProgressStream.java","source/com/intellij/openapi/progress/util/ProgressWindow.java","source/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java","source/com/intellij/openapi/progress/util/SmoothProgressAdapter.java","source/com/intellij/openapi/progress/util/StatusBarProgress.java","source/com/intellij/openapi/project/ex/ProjectEx.java","source/com/intellij/openapi/project/ex/ProjectManagerEx.java","source/com/intellij/openapi/project/impl/DefineMacrosDialog.java","source/com/intellij/openapi/project/impl/ProjectImpl.java","source/com/intellij/openapi/project/impl/ProjectManagerImpl.java","source/com/intellij/openapi/project/impl/ProjectReloadStateImpl.java","source/com/intellij/openapi/project/impl/UndefinedMacrosConfigurable.java","source/com/intellij/openapi/project/impl/convertors/Convertor01.java","source/com/intellij/openapi/project/impl/convertors/Convertor12.java","source/com/intellij/openapi/project/impl/convertors/Convertor23.java","source/com/intellij/openapi/project/impl/convertors/Convertor34.java","source/com/intellij/openapi/project/impl/convertors/Util.java","source/com/intellij/openapi/projectRoots/ex/PathUtilEx.java","source/com/intellij/openapi/projectRoots/ex/ProjectRoot.java","source/com/intellij/openapi/projectRoots/ex/ProjectRootContainer.java","source/com/intellij/openapi/projectRoots/impl/CompositeProjectRoot.java","source/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java","source/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java","source/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java","source/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java","source/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java","source/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java","source/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java","source/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java","source/com/intellij/openapi/projectRoots/ui/NotifiableSdkModel.java","source/com/intellij/openapi/projectRoots/ui/PathEditor.java","source/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java","source/com/intellij/openapi/projectRoots/ui/SdkEditor.java","source/com/intellij/openapi/projectRoots/ui/Util.java","source/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java","source/com/intellij/openapi/roots/impl/ClonableContentEntry.java","source/com/intellij/openapi/roots/impl/ClonableContentFolder.java","source/com/intellij/openapi/roots/impl/ClonableOrderEntry.java","source/com/intellij/openapi/roots/impl/ContentEntryImpl.java","source/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java","source/com/intellij/openapi/roots/impl/DirectoryIndex.java","source/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java","source/com/intellij/openapi/roots/impl/DirectoryInfo.java","source/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java","source/com/intellij/openapi/roots/impl/ExcludedOutputFolderImpl.java","source/com/intellij/openapi/roots/impl/FileIndexImplUtil.java","source/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/LibraryOrderEntryBaseImpl.java","source/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java","source/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/ModuleLibraryTable.java","source/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/ModuleRootEventImpl.java","source/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java","source/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java","source/com/intellij/openapi/roots/impl/OldModuleRootsKeeper.java","source/com/intellij/openapi/roots/impl/OrderEntryBaseImpl.java","source/com/intellij/openapi/roots/impl/OrderEntryFactory.java","source/com/intellij/openapi/roots/impl/OrderEntryUtil.java","source/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java","source/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java","source/com/intellij/openapi/roots/impl/RootModelComponentBase.java","source/com/intellij/openapi/roots/impl/RootModelImpl.java","source/com/intellij/openapi/roots/impl/RootProviderBaseImpl.java","source/com/intellij/openapi/roots/impl/SourceFolderImpl.java","source/com/intellij/openapi/roots/impl/WritableOrderEntry.java","source/com/intellij/openapi/roots/impl/libraries/ApplicationLibraryTable.java","source/com/intellij/openapi/roots/impl/libraries/LibraryEx.java","source/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java","source/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java","source/com/intellij/openapi/roots/impl/libraries/LibraryTableImplUtil.java","source/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java","source/com/intellij/openapi/roots/impl/libraries/ProjectLibraryTable.java","source/com/intellij/openapi/roots/ui/LightFilePointer.java","source/com/intellij/openapi/roots/ui/componentsList/components/ScrollablePanel.java","source/com/intellij/openapi/roots/ui/componentsList/layout/ComponentOperation.java","source/com/intellij/openapi/roots/ui/componentsList/layout/Orientation.java","source/com/intellij/openapi/roots/ui/componentsList/layout/OrientedDimensionSum.java","source/com/intellij/openapi/roots/ui/componentsList/layout/SizeProperty.java","source/com/intellij/openapi/roots/ui/componentsList/layout/VerticalStackLayout.java","source/com/intellij/openapi/roots/ui/configuration/ActionsHeaderComponent.java","source/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java","source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java","source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java","source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java","source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java","source/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java","source/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java","source/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java","source/com/intellij/openapi/roots/ui/configuration/FilePathClipper.java","source/com/intellij/openapi/roots/ui/configuration/IconActionComponent.java","source/com/intellij/openapi/roots/ui/configuration/IconSet.java","source/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java","source/com/intellij/openapi/roots/ui/configuration/LibrariesAlphaComparator.java","source/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java","source/com/intellij/openapi/roots/ui/configuration/LibraryTableModifiableModelProvider.java","source/com/intellij/openapi/roots/ui/configuration/ModuleCreationInfo.java","source/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java","source/com/intellij/openapi/roots/ui/configuration/ModuleEditorState.java","source/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java","source/com/intellij/openapi/roots/ui/configuration/ModuleLevelConfigurablesEditorProvider.java","source/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java","source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurable.java","source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java","source/com/intellij/openapi/roots/ui/configuration/MoveTableRowButtonListener.java","source/com/intellij/openapi/roots/ui/configuration/NamedLibrariesPanel.java","source/com/intellij/openapi/roots/ui/configuration/ResizingWrapper.java","source/com/intellij/openapi/roots/ui/configuration/ScalableIconComponent.java","source/com/intellij/openapi/roots/ui/configuration/actions/ContentEntryEditingAction.java","source/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java","source/com/intellij/openapi/roots/ui/configuration/actions/ModulesConfigurationAction.java","source/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java","source/com/intellij/openapi/roots/ui/configuration/actions/ToggleExcludedStateAction.java","source/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElementDescriptor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElementDescriptor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElementDescriptor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElementDescriptor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryFileChooser.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeBuilder.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeContentElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeStructure.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeRenderer.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElement.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElementDescriptor.java","source/com/intellij/openapi/roots/ui/configuration/libraryEditor/UrlComparator.java","source/com/intellij/openapi/roots/ui/util/BaseTextCommentCellAppearance.java","source/com/intellij/openapi/roots/ui/util/CellAppearance.java","source/com/intellij/openapi/roots/ui/util/CellAppearanceUtils.java","source/com/intellij/openapi/roots/ui/util/CompositeAppearance.java","source/com/intellij/openapi/roots/ui/util/HttpUrlCellAppearance.java","source/com/intellij/openapi/roots/ui/util/JarSubfileCellAppearance.java","source/com/intellij/openapi/roots/ui/util/ModifiableCellAppearance.java","source/com/intellij/openapi/roots/ui/util/SimpleTextCellAppearance.java","source/com/intellij/openapi/roots/ui/util/ValidFileCellAppearance.java","source/com/intellij/openapi/roots/watcher/impl/OrderEntryPredicate.java","source/com/intellij/openapi/ui/ex/MessagesEx.java","source/com/intellij/openapi/ui/ex/MultiLineLabel.java","source/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java","source/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java","source/com/intellij/openapi/vcs/FilePathImpl.java","source/com/intellij/openapi/vcs/actions/AbstractCommonCheckinAction.java","source/com/intellij/openapi/vcs/actions/AbstractVcsAction.java","source/com/intellij/openapi/vcs/actions/CashedVcsContext.java","source/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java","source/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java","source/com/intellij/openapi/vcs/actions/SelectedBlockHistoryAction.java","source/com/intellij/openapi/vcs/actions/ShowChangeMarkerAction.java","source/com/intellij/openapi/vcs/actions/ShowNextChangeMarkerAction.java","source/com/intellij/openapi/vcs/actions/ShowPrevChangeMarkerAction.java","source/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java","source/com/intellij/openapi/vcs/actions/VcsActionGroup.java","source/com/intellij/openapi/vcs/actions/VcsContextWrapper.java","source/com/intellij/openapi/vcs/actions/VcsGroupsWrapper.java","source/com/intellij/openapi/vcs/ex/DocumentWrapper.java","source/com/intellij/openapi/vcs/ex/LineStatusTracker.java","source/com/intellij/openapi/vcs/ex/ProjectLevelVcsManagerEx.java","source/com/intellij/openapi/vcs/ex/Range.java","source/com/intellij/openapi/vcs/ex/RangesBuilder.java","source/com/intellij/openapi/vcs/history/FileHistoryPanel.java","source/com/intellij/openapi/vcs/history/impl/VcsBlockHistoryDialog.java","source/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java","source/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java","source/com/intellij/openapi/vcs/impl/FileStatusFactoryImpl.java","source/com/intellij/openapi/vcs/impl/FileStatusImpl.java","source/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java","source/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java","source/com/intellij/openapi/vcs/impl/VcsManagerConfigurable.java","source/com/intellij/openapi/vcs/impl/VcsManagerPerModuleConfiguration.java","source/com/intellij/openapi/vcs/readOnlyHandler/FileInfo.java","source/com/intellij/openapi/vcs/readOnlyHandler/HandleType.java","source/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java","source/com/intellij/openapi/vcs/ui/exclude/SortedComboBoxModel.java","source/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java","source/com/intellij/openapi/vcs/update/AbstractTreeNode.java","source/com/intellij/openapi/vcs/update/ActionInfo.java","source/com/intellij/openapi/vcs/update/CommonStatusFileOrDirectoryAction.java","source/com/intellij/openapi/vcs/update/CommonStatusProjectAction.java","source/com/intellij/openapi/vcs/update/CommonUpdateFileOrDirectoryAction.java","source/com/intellij/openapi/vcs/update/CommonUpdateProjectAction.java","source/com/intellij/openapi/vcs/update/DirectoryTreeNode.java","source/com/intellij/openapi/vcs/update/FileOrDirectoryTreeNode.java","source/com/intellij/openapi/vcs/update/FileTreeNode.java","source/com/intellij/openapi/vcs/update/GroupByPackages.java","source/com/intellij/openapi/vcs/update/GroupTreeNode.java","source/com/intellij/openapi/vcs/update/RestoreUpdateTree.java","source/com/intellij/openapi/vcs/update/ScopeInfo.java","source/com/intellij/openapi/vcs/update/UpdateInfo.java","source/com/intellij/openapi/vcs/update/UpdateInfoTree.java","source/com/intellij/openapi/vcs/update/UpdateOrStatusOptionsDialog.java","source/com/intellij/openapi/vcs/update/UpdateRootNode.java","source/com/intellij/openapi/vcs/update/UpdateTreeCellRenderer.java","source/com/intellij/openapi/vfs/ex/VirtualFileManagerAdapter.java","source/com/intellij/openapi/vfs/ex/VirtualFileManagerEx.java","source/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java","source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDataImpl.java","source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDirectoryImpl.java","source/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java","source/com/intellij/openapi/vfs/ex/http/HttpFileSystem.java","source/com/intellij/openapi/vfs/ex/http/VirtualFileImpl.java","source/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java","source/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java","source/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java","source/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java","source/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java","source/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java","source/com/intellij/openapi/vfs/impl/local/VirtualFileImpl.java","source/com/intellij/openapi/vfs/impl/local/VirtualFileInfoAction.java","source/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java","source/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java","source/com/intellij/openapi/wm/ex/StatusBarEx.java","source/com/intellij/openapi/wm/ex/ToolWindowEx.java","source/com/intellij/openapi/wm/ex/ToolWindowManagerAdapter.java","source/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java","source/com/intellij/openapi/wm/ex/ToolWindowManagerListener.java","source/com/intellij/openapi/wm/ex/WindowManagerEx.java","source/com/intellij/openapi/wm/impl/ActiveStack.java","source/com/intellij/openapi/wm/impl/CommandProcessor.java","source/com/intellij/openapi/wm/impl/DesktopLayout.java","source/com/intellij/openapi/wm/impl/FloatingDecorator.java","source/com/intellij/openapi/wm/impl/HierarchyWatcher.java","source/com/intellij/openapi/wm/impl/IdeFrame.java","source/com/intellij/openapi/wm/impl/IdeMenuBar.java","source/com/intellij/openapi/wm/impl/IdeRootPane.java","source/com/intellij/openapi/wm/impl/InternalDecorator.java","source/com/intellij/openapi/wm/impl/InternalDecoratorListener.java","source/com/intellij/openapi/wm/impl/SideStack.java","source/com/intellij/openapi/wm/impl/Stripe.java","source/com/intellij/openapi/wm/impl/StripeButton.java","source/com/intellij/openapi/wm/impl/StripeButtonUI.java","source/com/intellij/openapi/wm/impl/Surface.java","source/com/intellij/openapi/wm/impl/TestWindowManager.java","source/com/intellij/openapi/wm/impl/TitlePanel.java","source/com/intellij/openapi/wm/impl/ToolWindowImpl.java","source/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java","source/com/intellij/openapi/wm/impl/ToolWindowsPane.java","source/com/intellij/openapi/wm/impl/VisibilityWatcher.java","source/com/intellij/openapi/wm/impl/WindowInfo.java","source/com/intellij/openapi/wm/impl/WindowManagerImpl.java","source/com/intellij/openapi/wm/impl/WindowWatcher.java","source/com/intellij/openapi/wm/impl/commands/ApplyWindowInfoCmd.java","source/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java","source/com/intellij/openapi/wm/impl/commands/InvokeLaterCmd.java","source/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java","source/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java","source/com/intellij/openapi/wm/impl/commands/UpdateRootPaneCmd.java","source/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java","source/com/intellij/openapi/wm/impl/status/PositionPanel.java","source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java","source/com/intellij/openapi/wm/impl/status/TextPanel.java","source/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java","source/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java","source/com/intellij/packageDependencies/DependenciesBuilder.java","source/com/intellij/packageDependencies/DependencyRule.java","source/com/intellij/packageDependencies/DependencyUISettings.java","source/com/intellij/packageDependencies/DependencyValidationManager.java","source/com/intellij/packageDependencies/FindDependencyUtil.java","source/com/intellij/packageDependencies/actions/AnalyzeDependenciesAction.java","source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java","source/com/intellij/packageDependencies/packageSet/PackageSetFactoryImpl.java","source/com/intellij/packageDependencies/ui/DependecyNodeComparator.java","source/com/intellij/packageDependencies/ui/DependenciesPanel.java","source/com/intellij/packageDependencies/ui/DependencyConfigurable.java","source/com/intellij/packageDependencies/ui/FileNode.java","source/com/intellij/packageDependencies/ui/GeneralGroupNode.java","source/com/intellij/packageDependencies/ui/LibraryNode.java","source/com/intellij/packageDependencies/ui/ModuleNode.java","source/com/intellij/packageDependencies/ui/PackageDependenciesNode.java","source/com/intellij/packageDependencies/ui/PackageNode.java","source/com/intellij/packageDependencies/ui/RootNode.java","source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java","source/com/intellij/packageDependencies/ui/TreeModelBuilder.java","source/com/intellij/packageDependencies/ui/UsagesPanel.java","source/com/intellij/peer/impl/PeerFactoryImpl.java","source/com/intellij/pom/core/impl/PomModelImpl.java","source/com/intellij/pom/java/impl/PomJavaAspectImpl.java","source/com/intellij/projectView/LibrariesElement.java","source/com/intellij/psi/PsiLock.java","source/com/intellij/psi/controlFlow/AllVariablesControlFlowPolicy.java","source/com/intellij/psi/controlFlow/BranchingInstruction.java","source/com/intellij/psi/controlFlow/CallInstruction.java","source/com/intellij/psi/controlFlow/CommentInstruction.java","source/com/intellij/psi/controlFlow/CompositeInstructionClientVisitor.java","source/com/intellij/psi/controlFlow/ConditionalBranchingInstruction.java","source/com/intellij/psi/controlFlow/ConditionalGoToInstruction.java","source/com/intellij/psi/controlFlow/ConditionalThrowToInstruction.java","source/com/intellij/psi/controlFlow/ControlFlow.java","source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java","source/com/intellij/psi/controlFlow/ControlFlowFactory.java","source/com/intellij/psi/controlFlow/ControlFlowImpl.java","source/com/intellij/psi/controlFlow/ControlFlowInstructionVisitor.java","source/com/intellij/psi/controlFlow/ControlFlowPolicy.java","source/com/intellij/psi/controlFlow/ControlFlowStack.java","source/com/intellij/psi/controlFlow/ControlFlowSubRange.java","source/com/intellij/psi/controlFlow/ControlFlowUtil.java","source/com/intellij/psi/controlFlow/EmptyInstruction.java","source/com/intellij/psi/controlFlow/GoToInstruction.java","source/com/intellij/psi/controlFlow/Instruction.java","source/com/intellij/psi/controlFlow/InstructionBase.java","source/com/intellij/psi/controlFlow/InstructionClientVisitor.java","source/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java","source/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java","source/com/intellij/psi/controlFlow/ReadVariableInstruction.java","source/com/intellij/psi/controlFlow/ReturnInstruction.java","source/com/intellij/psi/controlFlow/SimpleInstruction.java","source/com/intellij/psi/controlFlow/ThrowToInstruction.java","source/com/intellij/psi/controlFlow/WriteVariableInstruction.java","source/com/intellij/psi/filters/AndFilter.java","source/com/intellij/psi/filters/ClassFilter.java","source/com/intellij/psi/filters/ConstructorFilter.java","source/com/intellij/psi/filters/ContentFilter.java","source/com/intellij/psi/filters/ContextGetter.java","source/com/intellij/psi/filters/ElementExtractorFilter.java","source/com/intellij/psi/filters/ElementFilter.java","source/com/intellij/psi/filters/FalseFilter.java","source/com/intellij/psi/filters/FilterUtil.java","source/com/intellij/psi/filters/GeneratorFilter.java","source/com/intellij/psi/filters/InitializableFilter.java","source/com/intellij/psi/filters/NotFilter.java","source/com/intellij/psi/filters/OrFilter.java","source/com/intellij/psi/filters/ScopeFilter.java","source/com/intellij/psi/filters/TextFilter.java","source/com/intellij/psi/filters/TrueFilter.java","source/com/intellij/psi/filters/classes/AnnotationTypeFilter.java","source/com/intellij/psi/filters/classes/AnyInnerFilter.java","source/com/intellij/psi/filters/classes/AssignableFromContextFilter.java","source/com/intellij/psi/filters/classes/ClassAssignableFilter.java","source/com/intellij/psi/filters/classes/ClassAssignableToFilter.java","source/com/intellij/psi/filters/classes/EnumFilter.java","source/com/intellij/psi/filters/classes/InterfaceFilter.java","source/com/intellij/psi/filters/classes/ThisOrAnyInnerFilter.java","source/com/intellij/psi/filters/element/ExcludeDeclaredFilter.java","source/com/intellij/psi/filters/element/ExcludeSillyAssignment.java","source/com/intellij/psi/filters/element/ModifierFilter.java","source/com/intellij/psi/filters/element/PackageEqualsFilter.java","source/com/intellij/psi/filters/element/ReferenceOnFilter.java","source/com/intellij/psi/filters/getters/AllClassesGetter.java","source/com/intellij/psi/filters/getters/CastTypeGetter.java","source/com/intellij/psi/filters/getters/ExpectedTypesGetter.java","source/com/intellij/psi/filters/getters/FilterGetter.java","source/com/intellij/psi/filters/getters/InstanceOfLeftPartTypeGetter.java","source/com/intellij/psi/filters/getters/MembersGetter.java","source/com/intellij/psi/filters/getters/TemplatesGetter.java","source/com/intellij/psi/filters/getters/ThisGetter.java","source/com/intellij/psi/filters/getters/ThrowsListGetter.java","source/com/intellij/psi/filters/getters/XmlAttributeValueGetter.java","source/com/intellij/psi/filters/position/AfterElementFilter.java","source/com/intellij/psi/filters/position/BeforeElementFilter.java","source/com/intellij/psi/filters/position/InsideElementFilter.java","source/com/intellij/psi/filters/position/LeftNeighbour.java","source/com/intellij/psi/filters/position/ParentElementFilter.java","source/com/intellij/psi/filters/position/ParentSkipReferenceElementFilter.java","source/com/intellij/psi/filters/position/PositionElementFilter.java","source/com/intellij/psi/filters/position/PreviousElementFilter.java","source/com/intellij/psi/filters/position/RootTagFilter.java","source/com/intellij/psi/filters/position/StartElementFilter.java","source/com/intellij/psi/filters/position/SuperParentFilter.java","source/com/intellij/psi/filters/position/TokenTypeFilter.java","source/com/intellij/psi/filters/types/ArrayTypeFilter.java","source/com/intellij/psi/filters/types/AssignableFromFilter.java","source/com/intellij/psi/filters/types/AssignableGroupFilter.java","source/com/intellij/psi/filters/types/AssignableToFilter.java","source/com/intellij/psi/filters/types/ReturnTypeFilter.java","source/com/intellij/psi/filters/types/TypeClassFilter.java","source/com/intellij/psi/filters/types/TypeCodeFragmentIsVoidEnabledFilter.java","source/com/intellij/psi/filters/types/TypeFilter.java","source/com/intellij/psi/impl/CachedValueImpl.java","source/com/intellij/psi/impl/CachedValuesManagerImpl.java","source/com/intellij/psi/impl/CheckUtil.java","source/com/intellij/psi/impl/CommitToPsiFileAction.java","source/com/intellij/psi/impl/CompositeShortNamesCache.java","source/com/intellij/psi/impl/ConstantExpressionEvaluator.java","source/com/intellij/psi/impl/DebugUtil.java","source/com/intellij/psi/impl/ElementBase.java","source/com/intellij/psi/impl/EmptySubstitutorImpl.java","source/com/intellij/psi/impl/InheritanceImplUtil.java","source/com/intellij/psi/impl/PsiClassImplUtil.java","source/com/intellij/psi/impl/PsiConstantEvaluationHelperImpl.java","source/com/intellij/psi/impl/PsiDocumentManagerImpl.java","source/com/intellij/psi/impl/PsiElementBase.java","source/com/intellij/psi/impl/PsiElementFactoryImpl.java","source/com/intellij/psi/impl/PsiFileEx.java","source/com/intellij/psi/impl/PsiImplUtil.java","source/com/intellij/psi/impl/PsiManagerConfiguration.java","source/com/intellij/psi/impl/PsiManagerImpl.java","source/com/intellij/psi/impl/PsiModificationTrackerImpl.java","source/com/intellij/psi/impl/PsiNameHelperImpl.java","source/com/intellij/psi/impl/PsiShortNamesCacheImpl.java","source/com/intellij/psi/impl/PsiSubstitutorImpl.java","source/com/intellij/psi/impl/PsiSuperMethodImplUtil.java","source/com/intellij/psi/impl/PsiToDocumentSynchronizer.java","source/com/intellij/psi/impl/PsiTreeChangeEventImpl.java","source/com/intellij/psi/impl/PsiVariableEx.java","source/com/intellij/psi/impl/SharedPsiElementImplUtil.java","source/com/intellij/psi/impl/TextBlock.java","source/com/intellij/psi/impl/cache/CacheManager.java","source/com/intellij/psi/impl/cache/ClassInitializerView.java","source/com/intellij/psi/impl/cache/ClassView.java","source/com/intellij/psi/impl/cache/DeclarationView.java","source/com/intellij/psi/impl/cache/DirectoryView.java","source/com/intellij/psi/impl/cache/FieldView.java","source/com/intellij/psi/impl/cache/FileView.java","source/com/intellij/psi/impl/cache/InitializerTooLongException.java","source/com/intellij/psi/impl/cache/MethodView.java","source/com/intellij/psi/impl/cache/ModifierFlags.java","source/com/intellij/psi/impl/cache/RepositoryElementType.java","source/com/intellij/psi/impl/cache/RepositoryItemView.java","source/com/intellij/psi/impl/cache/impl/CacheUtil.java","source/com/intellij/psi/impl/cache/impl/CompositeCacheManager.java","source/com/intellij/psi/impl/cache/impl/idCache/BaseFilterLexer.java","source/com/intellij/psi/impl/cache/impl/idCache/IdTableBuilding.java","source/com/intellij/psi/impl/cache/impl/idCache/VfsIndexer.java","source/com/intellij/psi/impl/cache/impl/idCache/XmlFilterLexer.java","source/com/intellij/psi/impl/cache/impl/repositoryCache/RecordUtil.java","source/com/intellij/psi/impl/cache/impl/repositoryCache/TypeInfo.java","source/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java","source/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java","source/com/intellij/psi/impl/compiled/ClsAnnotationsUtil.java","source/com/intellij/psi/impl/compiled/ClsArrayInitializerMemberValueImpl.java","source/com/intellij/psi/impl/compiled/ClsClassImpl.java","source/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java","source/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java","source/com/intellij/psi/impl/compiled/ClsDocTagImpl.java","source/com/intellij/psi/impl/compiled/ClsElementImpl.java","source/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java","source/com/intellij/psi/impl/compiled/ClsFieldImpl.java","source/com/intellij/psi/impl/compiled/ClsFileImpl.java","source/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java","source/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java","source/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java","source/com/intellij/psi/impl/compiled/ClsMethodImpl.java","source/com/intellij/psi/impl/compiled/ClsModifierListImpl.java","source/com/intellij/psi/impl/compiled/ClsModifierListOwner.java","source/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java","source/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java","source/com/intellij/psi/impl/compiled/ClsParameterImpl.java","source/com/intellij/psi/impl/compiled/ClsParameterListImpl.java","source/com/intellij/psi/impl/compiled/ClsParsingUtil.java","source/com/intellij/psi/impl/compiled/ClsPrefixExpressionImpl.java","source/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java","source/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java","source/com/intellij/psi/impl/compiled/ClsReferenceParametersListImpl.java","source/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java","source/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java","source/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java","source/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java","source/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java","source/com/intellij/psi/impl/file/PsiBinaryFileImpl.java","source/com/intellij/psi/impl/file/PsiDirectoryImpl.java","source/com/intellij/psi/impl/file/PsiFileImplUtil.java","source/com/intellij/psi/impl/file/PsiPackageImpl.java","source/com/intellij/psi/impl/file/impl/FileManager.java","source/com/intellij/psi/impl/file/impl/FileManagerImpl.java","source/com/intellij/psi/impl/light/ImplicitVariableImpl.java","source/com/intellij/psi/impl/light/LightClassReference.java","source/com/intellij/psi/impl/light/LightClassReferenceExpression.java","source/com/intellij/psi/impl/light/LightElement.java","source/com/intellij/psi/impl/light/LightEmptyImplementsList.java","source/com/intellij/psi/impl/light/LightIdentifier.java","source/com/intellij/psi/impl/light/LightKeyword.java","source/com/intellij/psi/impl/light/LightMethod.java","source/com/intellij/psi/impl/light/LightModifierList.java","source/com/intellij/psi/impl/light/LightPackageReference.java","source/com/intellij/psi/impl/light/LightPackageReferenceExpression.java","source/com/intellij/psi/impl/light/LightReferenceParameterList.java","source/com/intellij/psi/impl/light/LightTypeElement.java","source/com/intellij/psi/impl/light/LightVariableBase.java","source/com/intellij/psi/impl/meta/MetaRegistry.java","source/com/intellij/psi/impl/migration/MigrationClassImpl.java","source/com/intellij/psi/impl/migration/MigrationPackageImpl.java","source/com/intellij/psi/impl/migration/PsiMigrationImpl.java","source/com/intellij/psi/impl/search/LowLevelSearchUtil.java","source/com/intellij/psi/impl/search/PsiSearchHelperImpl.java","source/com/intellij/psi/impl/search/ThrowSearchUtil.java","source/com/intellij/psi/impl/search/TodoItemImpl.java","source/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java","source/com/intellij/psi/impl/smartPointers/SmartPointerEx.java","source/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java","source/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java","source/com/intellij/psi/impl/source/CharTableImpl.java","source/com/intellij/psi/impl/source/CodeFragmentElement.java","source/com/intellij/psi/impl/source/Constants.java","source/com/intellij/psi/impl/source/DummyHolder.java","source/com/intellij/psi/impl/source/DummyHolderElement.java","source/com/intellij/psi/impl/source/ParsingContext.java","source/com/intellij/psi/impl/source/PsiAnnotationMethodImpl.java","source/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java","source/com/intellij/psi/impl/source/PsiClassImpl.java","source/com/intellij/psi/impl/source/PsiClassInitializerImpl.java","source/com/intellij/psi/impl/source/PsiClassReferenceType.java","source/com/intellij/psi/impl/source/PsiCodeFragmentImpl.java","source/com/intellij/psi/impl/source/PsiEnumConstantImpl.java","source/com/intellij/psi/impl/source/PsiEnumConstantInitializerImpl.java","source/com/intellij/psi/impl/source/PsiExpressionCodeFragmentImpl.java","source/com/intellij/psi/impl/source/PsiFieldImpl.java","source/com/intellij/psi/impl/source/PsiFileImpl.java","source/com/intellij/psi/impl/source/PsiImmediateClassType.java","source/com/intellij/psi/impl/source/PsiImportListImpl.java","source/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java","source/com/intellij/psi/impl/source/PsiImportStatementImpl.java","source/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java","source/com/intellij/psi/impl/source/PsiImportStaticStatementImpl.java","source/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java","source/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java","source/com/intellij/psi/impl/source/PsiJavaFileImpl.java","source/com/intellij/psi/impl/source/PsiLabelReference.java","source/com/intellij/psi/impl/source/PsiMethodImpl.java","source/com/intellij/psi/impl/source/PsiModifierListImpl.java","source/com/intellij/psi/impl/source/PsiParameterImpl.java","source/com/intellij/psi/impl/source/PsiParameterListImpl.java","source/com/intellij/psi/impl/source/PsiPlainTextFileImpl.java","source/com/intellij/psi/impl/source/PsiReferenceListImpl.java","source/com/intellij/psi/impl/source/PsiTypeCodeFragmentImpl.java","source/com/intellij/psi/impl/source/PsiTypeElementImpl.java","source/com/intellij/psi/impl/source/SourceJavaCodeReference.java","source/com/intellij/psi/impl/source/SourceTreeToPsiMap.java","source/com/intellij/psi/impl/source/codeStyle/BraceEnforcer.java","source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java","source/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java","source/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java","source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemeImpl.java","source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java","source/com/intellij/psi/impl/source/codeStyle/Helper.java","source/com/intellij/psi/impl/source/codeStyle/ImportHelper.java","source/com/intellij/psi/impl/source/codeStyle/IndentImpl.java","source/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java","source/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java","source/com/intellij/psi/impl/source/html/HtmlDocumentImpl.java","source/com/intellij/psi/impl/source/html/HtmlFileImpl.java","source/com/intellij/psi/impl/source/html/HtmlTagImpl.java","source/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java","source/com/intellij/psi/impl/source/html/dtd/HtmlElementDescriptorImpl.java","source/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java","source/com/intellij/psi/impl/source/javadoc/ExceptionTagInfo.java","source/com/intellij/psi/impl/source/javadoc/JavadocManagerImpl.java","source/com/intellij/psi/impl/source/javadoc/ParamDocTagInfo.java","source/com/intellij/psi/impl/source/javadoc/PsiDocCommentImpl.java","source/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java","source/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java","source/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java","source/com/intellij/psi/impl/source/javadoc/PsiDocTagValueImpl.java","source/com/intellij/psi/impl/source/javadoc/PsiDocTokenImpl.java","source/com/intellij/psi/impl/source/javadoc/ReturnDocTagInfo.java","source/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java","source/com/intellij/psi/impl/source/javadoc/SerialDocTagInfo.java","source/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java","source/com/intellij/psi/impl/source/jsp/jspJava/JspText.java","source/com/intellij/psi/impl/source/jsp/tagLibrary/FileLoader.java","source/com/intellij/psi/impl/source/jsp/tagLibrary/JarLoader.java","source/com/intellij/psi/impl/source/jsp/tagLibrary/Loader.java","source/com/intellij/psi/impl/source/parsing/ChameleonTransforming.java","source/com/intellij/psi/impl/source/parsing/ClassBodyParsing.java","source/com/intellij/psi/impl/source/parsing/DeclarationParsing.java","source/com/intellij/psi/impl/source/parsing/ExpressionParsing.java","source/com/intellij/psi/impl/source/parsing/FileTextParsing.java","source/com/intellij/psi/impl/source/parsing/GTTokens.java","source/com/intellij/psi/impl/source/parsing/ImportsTextParsing.java","source/com/intellij/psi/impl/source/parsing/JavadocParsing.java","source/com/intellij/psi/impl/source/parsing/ParseUtil.java","source/com/intellij/psi/impl/source/parsing/Parsing.java","source/com/intellij/psi/impl/source/parsing/StatementParsing.java","source/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java","source/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java","source/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java","source/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java","source/com/intellij/psi/impl/source/resolve/ResolveCache.java","source/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java","source/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java","source/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java","source/com/intellij/psi/impl/source/resolve/reference/ElementManipulator.java","source/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java","source/com/intellij/psi/impl/source/resolve/reference/PsiReferenceProvider.java","source/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java","source/com/intellij/psi/impl/source/resolve/reference/impl/GenericReference.java","source/com/intellij/psi/impl/source/resolve/reference/impl/PsiMultiReference.java","source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PlainFileManipulator.java","source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java","source/com/intellij/psi/impl/source/resolve/reference/impl/providers/GenericReferenceProvider.java","source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassListReferenceProvider.java","source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java","source/com/intellij/psi/impl/source/text/BlockSupportImpl.java","source/com/intellij/psi/impl/source/tree/ChangeUtil.java","source/com/intellij/psi/impl/source/tree/ChildRole.java","source/com/intellij/psi/impl/source/tree/CompositeElement.java","source/com/intellij/psi/impl/source/tree/CompositePsiElement.java","source/com/intellij/psi/impl/source/tree/ElementType.java","source/com/intellij/psi/impl/source/tree/Factory.java","source/com/intellij/psi/impl/source/tree/FileElement.java","source/com/intellij/psi/impl/source/tree/HtmlFileElement.java","source/com/intellij/psi/impl/source/tree/JavaDocElementType.java","source/com/intellij/psi/impl/source/tree/JavaElementType.java","source/com/intellij/psi/impl/source/tree/LeafElement.java","source/com/intellij/psi/impl/source/tree/LeafPsiElement.java","source/com/intellij/psi/impl/source/tree/PlainTextFileElement.java","source/com/intellij/psi/impl/source/tree/PsiCommentImpl.java","source/com/intellij/psi/impl/source/tree/PsiErrorElementImpl.java","source/com/intellij/psi/impl/source/tree/PsiPlainTextImpl.java","source/com/intellij/psi/impl/source/tree/PsiWhiteSpaceImpl.java","source/com/intellij/psi/impl/source/tree/SharedImplUtil.java","source/com/intellij/psi/impl/source/tree/SourceUtil.java","source/com/intellij/psi/impl/source/tree/TreeElement.java","source/com/intellij/psi/impl/source/tree/TreeUtil.java","source/com/intellij/psi/impl/source/tree/XmlFileElement.java","source/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java","source/com/intellij/psi/impl/source/tree/java/AnonymousClassElement.java","source/com/intellij/psi/impl/source/tree/java/AnonymousClassElementBase.java","source/com/intellij/psi/impl/source/tree/java/ClassElement.java","source/com/intellij/psi/impl/source/tree/java/ClassInitializerElement.java","source/com/intellij/psi/impl/source/tree/java/EnumConstantElement.java","source/com/intellij/psi/impl/source/tree/java/EnumConstantInitializerElement.java","source/com/intellij/psi/impl/source/tree/java/ExtendsListElement.java","source/com/intellij/psi/impl/source/tree/java/FieldElement.java","source/com/intellij/psi/impl/source/tree/java/ImplementsListElement.java","source/com/intellij/psi/impl/source/tree/java/ImportListElement.java","source/com/intellij/psi/impl/source/tree/java/ImportStatementBaseElement.java","source/com/intellij/psi/impl/source/tree/java/ImportStatementElement.java","source/com/intellij/psi/impl/source/tree/java/ImportStaticStatementElement.java","source/com/intellij/psi/impl/source/tree/java/JavaFileElement.java","source/com/intellij/psi/impl/source/tree/java/MethodElement.java","source/com/intellij/psi/impl/source/tree/java/ModifierListElement.java","source/com/intellij/psi/impl/source/tree/java/ParameterElement.java","source/com/intellij/psi/impl/source/tree/java/ParameterListElement.java","source/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiAnnotationParameterListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiArrayAccessExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiAssertStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiAssignmentExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiBlockStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiBreakStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiClassObjectAccessExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiContinueStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiDeclarationStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiDoWhileStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiEmptyExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiEmptyStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiExpressionListStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiForStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiForeachStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiIdentifierImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiIfStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiInstanceOfExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiJavaTokenImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiKeywordImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiLabeledStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiLocalVariableImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiParenthesizedExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiReturnStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiSuperExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiSwitchStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiSynchronizedStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiThrowStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiThrowsListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiTryStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterListImpl.java","source/com/intellij/psi/impl/source/tree/java/PsiWhileStatementImpl.java","source/com/intellij/psi/impl/source/tree/java/ReferenceListElement.java","source/com/intellij/psi/impl/source/tree/java/ReplaceExpressionUtil.java","source/com/intellij/psi/impl/source/tree/java/TypeParameterElement.java","source/com/intellij/psi/impl/source/tree/java/TypeParameterExtendsBoundsListElement.java","source/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java","source/com/intellij/psi/impl/source/xml/TagNameReference.java","source/com/intellij/psi/impl/source/xml/XmlAttlistDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlAttributeDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java","source/com/intellij/psi/impl/source/xml/XmlAttributeValueImpl.java","source/com/intellij/psi/impl/source/xml/XmlCommentImpl.java","source/com/intellij/psi/impl/source/xml/XmlDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java","source/com/intellij/psi/impl/source/xml/XmlDocumentImpl.java","source/com/intellij/psi/impl/source/xml/XmlElementContentSpecImpl.java","source/com/intellij/psi/impl/source/xml/XmlElementDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlElementImpl.java","source/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java","source/com/intellij/psi/impl/source/xml/XmlEnumeratedTypeImpl.java","source/com/intellij/psi/impl/source/xml/XmlFileImpl.java","source/com/intellij/psi/impl/source/xml/XmlMarkupDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlNotationDeclImpl.java","source/com/intellij/psi/impl/source/xml/XmlProcessingInstructionImpl.java","source/com/intellij/psi/impl/source/xml/XmlPrologImpl.java","source/com/intellij/psi/impl/source/xml/XmlTagImpl.java","source/com/intellij/psi/impl/source/xml/XmlTagValueImpl.java","source/com/intellij/psi/impl/source/xml/XmlTextImpl.java","source/com/intellij/psi/impl/source/xml/XmlTokenImpl.java","source/com/intellij/psi/impl/source/xml/dtd/DTDElementType.java","source/com/intellij/psi/presentation/java/ClassPresentationUtil.java","source/com/intellij/psi/presentation/java/SymbolPresentationUtil.java","source/com/intellij/psi/scope/BaseScopeProcessor.java","source/com/intellij/psi/scope/ElementClassHint.java","source/com/intellij/psi/scope/MethodProcessorSetupFailedException.java","source/com/intellij/psi/scope/NameHint.java","source/com/intellij/psi/scope/PsiConflictResolver.java","source/com/intellij/psi/scope/conflictResolvers/DuplicateConflictResolver.java","source/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java","source/com/intellij/psi/scope/conflictResolvers/JavaVariableConflictResolver.java","source/com/intellij/psi/scope/processor/ConflictFilterProcessor.java","source/com/intellij/psi/scope/processor/FilterElementProcessor.java","source/com/intellij/psi/scope/processor/FilterScopeProcessor.java","source/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java","source/com/intellij/psi/scope/processor/MethodResolverProcessor.java","source/com/intellij/psi/scope/processor/MethodsProcessor.java","source/com/intellij/psi/scope/processor/VariablesNotProcessor.java","source/com/intellij/psi/scope/processor/VariablesProcessor.java","source/com/intellij/psi/scope/util/PsiScopesUtil.java","source/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java","source/com/intellij/psi/statistics/impl/StatisticsUnit.java","source/com/intellij/psi/statistics/impl/WrongFormatException.java","source/com/intellij/psi/text/BlockSupport.java","source/com/intellij/psi/tree/DefaultRoleFinder.java","source/com/intellij/psi/tree/RoleFinder.java","source/com/intellij/psi/xml/XmlChildRole.java","source/com/intellij/refactoring/BaseRefactoringProcessor.java","source/com/intellij/refactoring/HelpID.java","source/com/intellij/refactoring/IntroduceHandlerBase.java","source/com/intellij/refactoring/RefactoringDialog.java","source/com/intellij/refactoring/RefactoringImpl.java","source/com/intellij/refactoring/RefactoringManager.java","source/com/intellij/refactoring/RefactoringSettings.java","source/com/intellij/refactoring/actions/AnonymousToInnerAction.java","source/com/intellij/refactoring/actions/BaseRefactoringAction.java","source/com/intellij/refactoring/actions/ChangeSignatureAction.java","source/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java","source/com/intellij/refactoring/actions/EncapsulateFieldsAction.java","source/com/intellij/refactoring/actions/ExtractInterfaceAction.java","source/com/intellij/refactoring/actions/ExtractMethodAction.java","source/com/intellij/refactoring/actions/ExtractSuperclassAction.java","source/com/intellij/refactoring/actions/InheritanceToDelegationAction.java","source/com/intellij/refactoring/actions/InlineAction.java","source/com/intellij/refactoring/actions/IntroduceConstantAction.java","source/com/intellij/refactoring/actions/IntroduceFieldAction.java","source/com/intellij/refactoring/actions/IntroduceParameterAction.java","source/com/intellij/refactoring/actions/IntroduceVariableAction.java","source/com/intellij/refactoring/actions/MakeMethodStaticAction.java","source/com/intellij/refactoring/actions/MethodDuplicatesAction.java","source/com/intellij/refactoring/actions/MigrateAction.java","source/com/intellij/refactoring/actions/MoveAction.java","source/com/intellij/refactoring/actions/PullUpAction.java","source/com/intellij/refactoring/actions/PushDownAction.java","source/com/intellij/refactoring/actions/RenameElementAction.java","source/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java","source/com/intellij/refactoring/actions/SafeDeleteAction.java","source/com/intellij/refactoring/actions/TempWithQueryAction.java","source/com/intellij/refactoring/actions/TurnRefsToSuperAction.java","source/com/intellij/refactoring/actions/TypeCookAction.java","source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java","source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java","source/com/intellij/refactoring/anonymousToInner/VariableInfo.java","source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java","source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java","source/com/intellij/refactoring/changeClassSignature/ChangeClassSigntaureViewDescriptor.java","source/com/intellij/refactoring/changeClassSignature/TypeParameterInfo.java","source/com/intellij/refactoring/changeSignature/ChangeInfo.java","source/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java","source/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java","source/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java","source/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java","source/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java","source/com/intellij/refactoring/changeSignature/ExceptionsTableModel.java","source/com/intellij/refactoring/changeSignature/NewParameterCollidesWithLocalUsageInfo.java","source/com/intellij/refactoring/changeSignature/ParameterInfo.java","source/com/intellij/refactoring/changeSignature/ParameterTableModel.java","source/com/intellij/refactoring/changeSignature/ThrownExceptionInfo.java","source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java","source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodHandler.java","source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java","source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodViewDescriptor.java","source/com/intellij/refactoring/convertToInstanceMethod/ImplementingClassUsageInfo.java","source/com/intellij/refactoring/convertToInstanceMethod/JavaDocUsageInfo.java","source/com/intellij/refactoring/convertToInstanceMethod/MethodCallUsageInfo.java","source/com/intellij/refactoring/convertToInstanceMethod/ParameterUsageInfo.java","source/com/intellij/refactoring/copy/CopyClassDialog.java","source/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java","source/com/intellij/refactoring/copy/CopyHandler.java","source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java","source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java","source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java","source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java","source/com/intellij/refactoring/extractInterface/ExtractClassUtil.java","source/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java","source/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java","source/com/intellij/refactoring/extractInterface/ExtractInterfaceProcessor.java","source/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java","source/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java","source/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java","source/com/intellij/refactoring/extractMethod/PrepareFailedException.java","source/com/intellij/refactoring/extractSuperclass/BindToOldUsageInfo.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassProcessor.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassViewDescriptor.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java","source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java","source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java","source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java","source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java","source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationUtil.java","source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationViewDescriptor.java","source/com/intellij/refactoring/inheritanceToDelegation/InnerClassConstructor.java","source/com/intellij/refactoring/inheritanceToDelegation/InnerClassMethod.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/FieldAccessibility.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/InheritanceToDelegationUsageInfo.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NoLongerOverridingSubClassMethodUsageInfo.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NonDelegatedMemberUsageInfo.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/ObjectUpcastedUsageInfo.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UnqualifiedNonDelegatedMemberUsageInfo.java","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UpcastedUsageInfo.java","source/com/intellij/refactoring/inline/InlineConstantFieldHandler.java","source/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java","source/com/intellij/refactoring/inline/InlineFieldDialog.java","source/com/intellij/refactoring/inline/InlineHandler.java","source/com/intellij/refactoring/inline/InlineLocalHandler.java","source/com/intellij/refactoring/inline/InlineMethodDialog.java","source/com/intellij/refactoring/inline/InlineMethodHandler.java","source/com/intellij/refactoring/inline/InlineMethodProcessor.java","source/com/intellij/refactoring/inline/InlineOptions.java","source/com/intellij/refactoring/inline/InlineViewDescriptor.java","source/com/intellij/refactoring/inline/ReferencedElementsCollector.java","source/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java","source/com/intellij/refactoring/introduceField/ElementToWorkOn.java","source/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java","source/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java","source/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java","source/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java","source/com/intellij/refactoring/introduceField/LocalToFieldHandler.java","source/com/intellij/refactoring/introduceParameter/ChangedMethodCallInfo.java","source/com/intellij/refactoring/introduceParameter/ClassMemberInExprUsageInfo.java","source/com/intellij/refactoring/introduceParameter/EnclosingMethodSelectionDialog.java","source/com/intellij/refactoring/introduceParameter/ExternalUsageInfo.java","source/com/intellij/refactoring/introduceParameter/InExprUsageInfo.java","source/com/intellij/refactoring/introduceParameter/InternalUsageInfo.java","source/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java","source/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java","source/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java","source/com/intellij/refactoring/introduceParameter/IntroduceParameterViewDescriptor.java","source/com/intellij/refactoring/introduceParameter/LocalVariableInExprUsageInfo.java","source/com/intellij/refactoring/introduceParameter/ParameterInExprUsageInfo.java","source/com/intellij/refactoring/introduceParameter/Util.java","source/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java","source/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java","source/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java","source/com/intellij/refactoring/introduceVariable/IntroduceVariableSettings.java","source/com/intellij/refactoring/listeners/impl/RefactoringListenerManagerImpl.java","source/com/intellij/refactoring/listeners/impl/RefactoringTransaction.java","source/com/intellij/refactoring/listeners/impl/impl/RefactoringTransactionImpl.java","source/com/intellij/refactoring/makeMethodStatic/InternalUsageInfo.java","source/com/intellij/refactoring/makeMethodStatic/MakeMethodStaticProcessor.java","source/com/intellij/refactoring/makeMethodStatic/OverridingMethodUsageInfo.java","source/com/intellij/refactoring/makeMethodStatic/SelfUsageInfo.java","source/com/intellij/refactoring/makeMethodStatic/Settings.java","source/com/intellij/refactoring/memberPullUp/JavaDocPanel.java","source/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java","source/com/intellij/refactoring/memberPullUp/PullUpDialog.java","source/com/intellij/refactoring/memberPullUp/PullUpHandler.java","source/com/intellij/refactoring/memberPullUp/PullUpHelper.java","source/com/intellij/refactoring/memberPushDown/PushDownConflicts.java","source/com/intellij/refactoring/memberPushDown/PushDownDialog.java","source/com/intellij/refactoring/memberPushDown/PushDownHandler.java","source/com/intellij/refactoring/memberPushDown/PushDownProcessor.java","source/com/intellij/refactoring/memberPushDown/PushDownUsageViewDescriptor.java","source/com/intellij/refactoring/migration/EditMigrationDialog.java","source/com/intellij/refactoring/migration/EditMigrationEntryDialog.java","source/com/intellij/refactoring/migration/MigrationDialog.java","source/com/intellij/refactoring/migration/MigrationManager.java","source/com/intellij/refactoring/migration/MigrationMap.java","source/com/intellij/refactoring/migration/MigrationMapEntry.java","source/com/intellij/refactoring/migration/MigrationMapSet.java","source/com/intellij/refactoring/migration/MigrationProcessor.java","source/com/intellij/refactoring/migration/MigrationUsagesViewDescriptor.java","source/com/intellij/refactoring/migration/MigrationUtil.java","source/com/intellij/refactoring/move/MoveCallback.java","source/com/intellij/refactoring/move/MoveHandler.java","source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingMoveDestination.java","source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java","source/com/intellij/refactoring/move/moveClassesOrPackages/MultipleRootsMoveDestination.java","source/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java","source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java","source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesProcessor.java","source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java","source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesViewDescriptor.java","source/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java","source/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java","source/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java","source/com/intellij/refactoring/move/moveInner/MoveInnerViewDescriptor.java","source/com/intellij/refactoring/move/moveMembers/MoveMemberViewDescriptor.java","source/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java","source/com/intellij/refactoring/move/moveMembers/MoveMembersImpl.java","source/com/intellij/refactoring/move/moveMembers/MoveMembersOptions.java","source/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java","source/com/intellij/refactoring/openapi/impl/ConvertToInstanceMethodRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/IntroduceParameterRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/MakeMethodStaticRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/MoveClassesOrPackagesRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/MoveInnerRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/MoveMembersRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/RefactoringActionHandlerFactoryImpl.java","source/com/intellij/refactoring/openapi/impl/RefactoringFactoryImpl.java","source/com/intellij/refactoring/openapi/impl/RenameRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/ReplaceConstructorWithFactoryRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/SafeDeleteRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/TurnRefsToSuperRefactoringImpl.java","source/com/intellij/refactoring/openapi/impl/TypeCookRefactoringImpl.java","source/com/intellij/refactoring/rename/AutomaticRenamingDialog.java","source/com/intellij/refactoring/rename/ClassHidesImportedClassUsageInfo.java","source/com/intellij/refactoring/rename/ClassHidesUnqualifiableClassUsageInfo.java","source/com/intellij/refactoring/rename/CollidingClassImportUsageInfo.java","source/com/intellij/refactoring/rename/CollisionUsageInfo.java","source/com/intellij/refactoring/rename/LocalHidesFieldUsageInfo.java","source/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java","source/com/intellij/refactoring/rename/PsiElementRenameHandler.java","source/com/intellij/refactoring/rename/RenameDialog.java","source/com/intellij/refactoring/rename/RenameHandler.java","source/com/intellij/refactoring/rename/RenameHandlerRegistry.java","source/com/intellij/refactoring/rename/RenameProcessor.java","source/com/intellij/refactoring/rename/RenameUtil.java","source/com/intellij/refactoring/rename/RenameVariableUsageInfo.java","source/com/intellij/refactoring/rename/RenameViewDescriptor.java","source/com/intellij/refactoring/rename/ResolvableCollisionUsageInfo.java","source/com/intellij/refactoring/rename/SubmemberHidesMemberUsageInfo.java","source/com/intellij/refactoring/rename/UnresolvableCollisionUsageInfo.java","source/com/intellij/refactoring/rename/naming/AutomaticRenamer.java","source/com/intellij/refactoring/rename/naming/AutomaticVariableRenamer.java","source/com/intellij/refactoring/rename/naming/FormsRenamer.java","source/com/intellij/refactoring/rename/naming/InheritorRenamer.java","source/com/intellij/refactoring/rename/naming/NameSuggester.java","source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java","source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryHandler.java","source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java","source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryViewDescriptor.java","source/com/intellij/refactoring/safeDelete/OverridingMethodsDialog.java","source/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java","source/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java","source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java","source/com/intellij/refactoring/safeDelete/SafeDeleteUsageViewDescriptor.java","source/com/intellij/refactoring/safeDelete/UnsafeUsagesDialog.java","source/com/intellij/refactoring/safeDelete/UsageHolder.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteFieldWriteReference.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteOverridingMethodUsageInfo.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeletePrivatizeMethod.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceSimpleDeleteUsageInfo.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceUsageInfo.java","source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteUsageInfo.java","source/com/intellij/refactoring/tempWithQuery/TempWithQueryHandler.java","source/com/intellij/refactoring/turnRefsToSuper/RefsToSuperViewDescriptor.java","source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperDialog.java","source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperHandler.java","source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java","source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java","source/com/intellij/refactoring/turnRefsToSuper/TurnToSuperReferenceUsageInfo.java","source/com/intellij/refactoring/typeCook/Bottom.java","source/com/intellij/refactoring/typeCook/Settings.java","source/com/intellij/refactoring/typeCook/TypeCookDialog.java","source/com/intellij/refactoring/typeCook/TypeCookHandler.java","source/com/intellij/refactoring/typeCook/TypeCookProcessor.java","source/com/intellij/refactoring/typeCook/TypeCookViewDescriptor.java","source/com/intellij/refactoring/typeCook/Util.java","source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java","source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java","source/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java","source/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java","source/com/intellij/refactoring/typeCook/deductive/builder/System.java","source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java","source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java","source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java","source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java","source/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java","source/com/intellij/refactoring/typeCook/deductive/util/Visitor.java","source/com/intellij/refactoring/ui/ClassCellRenderer.java","source/com/intellij/refactoring/ui/CodeFragmentTableCellEditor.java","source/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java","source/com/intellij/refactoring/ui/ColorConfiguringCellRenderer.java","source/com/intellij/refactoring/ui/ConflictsDialog.java","source/com/intellij/refactoring/ui/DelegationPanel.java","source/com/intellij/refactoring/ui/EditableRowTableManager.java","source/com/intellij/refactoring/ui/EnableDisableAction.java","source/com/intellij/refactoring/ui/InfoDialog.java","source/com/intellij/refactoring/ui/MemberSelectionPanel.java","source/com/intellij/refactoring/ui/MemberSelectionTable.java","source/com/intellij/refactoring/ui/MethodCellRenderer.java","source/com/intellij/refactoring/ui/NameSuggestionsField.java","source/com/intellij/refactoring/ui/NameSuggestionsGenerator.java","source/com/intellij/refactoring/ui/NameSuggestionsManager.java","source/com/intellij/refactoring/ui/RowEditableTableModel.java","source/com/intellij/refactoring/ui/StringTableCellEditor.java","source/com/intellij/refactoring/ui/TypeListCreatingVisitor.java","source/com/intellij/refactoring/ui/TypeSelector.java","source/com/intellij/refactoring/ui/TypeSelectorManager.java","source/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java","source/com/intellij/refactoring/ui/UsageViewDescriptorAdapter.java","source/com/intellij/refactoring/ui/VisibilityPanel.java","source/com/intellij/refactoring/ui/YesNoPreviewUsagesDialog.java","source/com/intellij/refactoring/util/CanonicalTypes.java","source/com/intellij/refactoring/util/ConflictsUtil.java","source/com/intellij/refactoring/util/FieldConflictsResolver.java","source/com/intellij/refactoring/util/JavaDocPolicy.java","source/com/intellij/refactoring/util/ParameterTablePanel.java","source/com/intellij/refactoring/util/RefactoringHierarchyUtil.java","source/com/intellij/refactoring/util/RefactoringMessageDialog.java","source/com/intellij/refactoring/util/RefactoringMessageUtil.java","source/com/intellij/refactoring/util/RefactoringUtil.java","source/com/intellij/refactoring/util/VisibilityUtil.java","source/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/ClassMemberReferencesVisitor.java","source/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java","source/com/intellij/refactoring/util/classMembers/ClassThisReferencesVisitor.java","source/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java","source/com/intellij/refactoring/util/classMembers/InterfaceContainmentVerifier.java","source/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java","source/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java","source/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java","source/com/intellij/refactoring/util/classMembers/MemberInfo.java","source/com/intellij/refactoring/util/classMembers/MemberInfoChange.java","source/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java","source/com/intellij/refactoring/util/classMembers/MemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java","source/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java","source/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java","source/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java","source/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java","source/com/intellij/refactoring/util/classRefs/ClassInstanceScanner.java","source/com/intellij/refactoring/util/classRefs/ClassReferenceScanner.java","source/com/intellij/refactoring/util/classRefs/ClassReferenceSearchingScanner.java","source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitor.java","source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitorAdapter.java","source/com/intellij/refactoring/util/classRefs/DelegatingClassReferenceVisitor.java","source/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java","source/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java","source/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java","source/com/intellij/refactoring/util/duplicates/Match.java","source/com/intellij/refactoring/util/duplicates/MatchProvider.java","source/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java","source/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java","source/com/intellij/refactoring/util/duplicates/ReturnValue.java","source/com/intellij/refactoring/util/duplicates/VariableReturnValue.java","source/com/intellij/refactoring/util/javadoc/MethodJavaDocHelper.java","source/com/intellij/refactoring/util/occurences/BaseOccurenceManager.java","source/com/intellij/refactoring/util/occurences/ExpressionOccurenceManager.java","source/com/intellij/refactoring/util/occurences/LocalVariableOccurenceManager.java","source/com/intellij/refactoring/util/occurences/NotInSuperCallOccurenceFilter.java","source/com/intellij/refactoring/util/occurences/NotInSuperOrThisCallFilterBase.java","source/com/intellij/refactoring/util/occurences/NotInThisCallFilter.java","source/com/intellij/refactoring/util/occurences/OccurenceFilter.java","source/com/intellij/refactoring/util/occurences/OccurenceManager.java","source/com/intellij/refactoring/util/usageInfo/DefaultConstructorImplicitUsageInfo.java","source/com/intellij/refactoring/util/usageInfo/DefaultConstructorUsageCollector.java","source/com/intellij/refactoring/util/usageInfo/NoConstructorClassUsageInfo.java","source/com/intellij/testFramework/EditorActionTestCase.java","source/com/intellij/testFramework/IdeaTestCase.java","source/com/intellij/testFramework/LightCodeInsightTestCase.java","source/com/intellij/testFramework/LightIdeaTestCase.java","source/com/intellij/testFramework/LoggedErrorProcessor.java","source/com/intellij/testFramework/MockVirtualFile.java","source/com/intellij/testFramework/ModuleTestCase.java","source/com/intellij/testFramework/PsiTestCase.java","source/com/intellij/testFramework/PsiTestData.java","source/com/intellij/testFramework/PsiTestUtil.java","source/com/intellij/testFramework/TestEditorManagerImpl.java","source/com/intellij/testFramework/TestLogger.java","source/com/intellij/testFramework/TestLoggerFactory.java","source/com/intellij/testFramework/TestSourceBasedTestCase.java","source/com/intellij/tools/ExternalToolsGroup.java","source/com/intellij/tools/FilterDialog.java","source/com/intellij/tools/FilterInfo.java","source/com/intellij/tools/OutputFiltersDialog.java","source/com/intellij/tools/SimpleActionGroup.java","source/com/intellij/tools/Tool.java","source/com/intellij/tools/ToolAction.java","source/com/intellij/tools/ToolConfigurable.java","source/com/intellij/tools/ToolEditorDialog.java","source/com/intellij/tools/ToolManager.java","source/com/intellij/tools/ToolsPanel.java","source/com/intellij/ui/AbstractToolTipHandler.java","source/com/intellij/ui/ActivatableLineBorder.java","source/com/intellij/ui/AnimatingSurface.java","source/com/intellij/ui/AutoScrollFromSourceHandler.java","source/com/intellij/ui/AutoScrollToSourceHandler.java","source/com/intellij/ui/BooleanTableCellRenderer.java","source/com/intellij/ui/CheckboxTree.java","source/com/intellij/ui/CheckedTreeNode.java","source/com/intellij/ui/CollapsiblePanel.java","source/com/intellij/ui/CollapsingListener.java","source/com/intellij/ui/ColorPanel.java","source/com/intellij/ui/ColoredTableCellRenderer.java","source/com/intellij/ui/CompTitledBorder.java","source/com/intellij/ui/DialogButtonGroup.java","source/com/intellij/ui/EdgeBorder.java","source/com/intellij/ui/EditorComboBoxEditor.java","source/com/intellij/ui/EditorComboBoxRenderer.java","source/com/intellij/ui/EditorTextField.java","source/com/intellij/ui/FieldPanelWithChangeSupport.java","source/com/intellij/ui/Focusable.java","source/com/intellij/ui/HeavyweightHint.java","source/com/intellij/ui/HighlightableCellRenderer.java","source/com/intellij/ui/HighlightableComponent.java","source/com/intellij/ui/HighlightedRegion.java","source/com/intellij/ui/HighlightedText.java","source/com/intellij/ui/Hint.java","source/com/intellij/ui/HintListener.java","source/com/intellij/ui/HorizontalLabeledIcon.java","source/com/intellij/ui/HoverHyperlinkLabel.java","source/com/intellij/ui/HyperlinkLabel.java","source/com/intellij/ui/IdeGraphics2D.java","source/com/intellij/ui/IdeaBlueMetalTheme.java","source/com/intellij/ui/LabeledIcon.java","source/com/intellij/ui/LightweightHint.java","source/com/intellij/ui/ListSpeedSearch.java","source/com/intellij/ui/ListToolTipHandler.java","source/com/intellij/ui/ListenerUtil.java","source/com/intellij/ui/MultiLineTooltipUI.java","source/com/intellij/ui/MultilineTreeCellRenderer.java","source/com/intellij/ui/NonFocusableCheckBox.java","source/com/intellij/ui/OneSideRoundedLineBorder.java","source/com/intellij/ui/PasswordFieldPanel.java","source/com/intellij/ui/RightAlignedLabelUI.java","source/com/intellij/ui/RowIcon.java","source/com/intellij/ui/SelectionSaver.java","source/com/intellij/ui/SideBorder.java","source/com/intellij/ui/SideBorder2.java","source/com/intellij/ui/SpeedSearchBase.java","source/com/intellij/ui/Splash.java","source/com/intellij/ui/SplittingUtil.java","source/com/intellij/ui/StateRestoringCheckBox.java","source/com/intellij/ui/StrikeoutLabel.java","source/com/intellij/ui/Surface.java","source/com/intellij/ui/TabbedPaneWrapper.java","source/com/intellij/ui/TableCellEditorWithButton.java","source/com/intellij/ui/TableCellKey.java","source/com/intellij/ui/TableToolTipHandler.java","source/com/intellij/ui/TreeExpandCollapse.java","source/com/intellij/ui/TreeList.java","source/com/intellij/ui/TreeSpeedSearch.java","source/com/intellij/ui/TreeToolTipHandler.java","source/com/intellij/ui/content/ComponentContentUI.java","source/com/intellij/ui/content/ContentFactoryImpl.java","source/com/intellij/ui/content/ContentManagerUtil.java","source/com/intellij/ui/content/MessageView.java","source/com/intellij/ui/content/TabbedPaneContentUI.java","source/com/intellij/ui/content/impl/ContentImpl.java","source/com/intellij/ui/content/impl/ContentManagerImpl.java","source/com/intellij/ui/content/impl/MessageViewImpl.java","source/com/intellij/ui/errorView/impl/ErrorViewFactoryImpl.java","source/com/intellij/ui/plaf/beg/BegBorders.java","source/com/intellij/ui/plaf/beg/BegButtonUI.java","source/com/intellij/ui/plaf/beg/BegCellRenderer.java","source/com/intellij/ui/plaf/beg/BegCheckBoxUI.java","source/com/intellij/ui/plaf/beg/BegComboBoxButton.java","source/com/intellij/ui/plaf/beg/BegComboBoxUI.java","source/com/intellij/ui/plaf/beg/BegListUI.java","source/com/intellij/ui/plaf/beg/BegMenuBorder.java","source/com/intellij/ui/plaf/beg/BegMenuItemUI.java","source/com/intellij/ui/plaf/beg/BegPopupMenuBorder.java","source/com/intellij/ui/plaf/beg/BegRadioButtonUI.java","source/com/intellij/ui/plaf/beg/BegResources.java","source/com/intellij/ui/plaf/beg/BegScrollBarUI.java","source/com/intellij/ui/plaf/beg/BegScrollPaneUI.java","source/com/intellij/ui/plaf/beg/BegTabbedPaneUI.java","source/com/intellij/ui/plaf/beg/BegTableUI.java","source/com/intellij/ui/plaf/beg/BegTreeHandleUtil.java","source/com/intellij/ui/plaf/beg/BegTreeUI.java","source/com/intellij/ui/plaf/beg/IdeaMenuUI.java","source/com/intellij/uiDesigner/ActiveDecorationLayer.java","source/com/intellij/uiDesigner/CutCopyPasteSupport.java","source/com/intellij/uiDesigner/DesignSpacer.java","source/com/intellij/uiDesigner/DragLayer.java","source/com/intellij/uiDesigner/DragSelectionProcessor.java","source/com/intellij/uiDesigner/ErrorAnalizer.java","source/com/intellij/uiDesigner/ErrorInfo.java","source/com/intellij/uiDesigner/EventProcessor.java","source/com/intellij/uiDesigner/FormEditingUtil.java","source/com/intellij/uiDesigner/GlassLayer.java","source/com/intellij/uiDesigner/GridChangeUtil.java","source/com/intellij/uiDesigner/GroupSelectionProcessor.java","source/com/intellij/uiDesigner/GuiDesignerConfigurable.java","source/com/intellij/uiDesigner/GuiDesignerConfiguration.java","source/com/intellij/uiDesigner/GuiEditor.java","source/com/intellij/uiDesigner/HSpacer.java","source/com/intellij/uiDesigner/HierarchyChangeListener.java","source/com/intellij/uiDesigner/InplaceEditingLayer.java","source/com/intellij/uiDesigner/InsertComponentProcessor.java","source/com/intellij/uiDesigner/LoaderFactory.java","source/com/intellij/uiDesigner/MainProcessor.java","source/com/intellij/uiDesigner/Painter.java","source/com/intellij/uiDesigner/PassiveDecorationLayer.java","source/com/intellij/uiDesigner/Properties.java","source/com/intellij/uiDesigner/PsiPropertiesProvider.java","source/com/intellij/uiDesigner/RadAtomicComponent.java","source/com/intellij/uiDesigner/RadComponent.java","source/com/intellij/uiDesigner/RadContainer.java","source/com/intellij/uiDesigner/RadErrorComponent.java","source/com/intellij/uiDesigner/RadHSpacer.java","source/com/intellij/uiDesigner/RadRootContainer.java","source/com/intellij/uiDesigner/RadScrollPane.java","source/com/intellij/uiDesigner/RadSplitPane.java","source/com/intellij/uiDesigner/RadTabbedPane.java","source/com/intellij/uiDesigner/RadVSpacer.java","source/com/intellij/uiDesigner/ResizeProcessor.java","source/com/intellij/uiDesigner/SelectionState.java","source/com/intellij/uiDesigner/SelectionWatcher.java","source/com/intellij/uiDesigner/VSpacer.java","source/com/intellij/uiDesigner/XYLayoutManagerImpl.java","source/com/intellij/uiDesigner/XmlReader.java","source/com/intellij/uiDesigner/XmlWriter.java","source/com/intellij/uiDesigner/actions/AbstractMoveSelectionAction.java","source/com/intellij/uiDesigner/actions/CreateDialogAction.java","source/com/intellij/uiDesigner/actions/DataBindingWizardAction.java","source/com/intellij/uiDesigner/actions/ExpandSelectionAction.java","source/com/intellij/uiDesigner/actions/MoveSelectionToDownAction.java","source/com/intellij/uiDesigner/actions/MoveSelectionToLeftAction.java","source/com/intellij/uiDesigner/actions/MoveSelectionToRightAction.java","source/com/intellij/uiDesigner/actions/MoveSelectionToUpAction.java","source/com/intellij/uiDesigner/actions/PreviewFormAction.java","source/com/intellij/uiDesigner/actions/ShowJavadocAction.java","source/com/intellij/uiDesigner/actions/ShrinkSelectionAction.java","source/com/intellij/uiDesigner/actions/StartInplaceEditingAction.java","source/com/intellij/uiDesigner/componentTree/ComponentPtr.java","source/com/intellij/uiDesigner/componentTree/ComponentPtrDescriptor.java","source/com/intellij/uiDesigner/componentTree/ComponentSelectionListener.java","source/com/intellij/uiDesigner/componentTree/ComponentTree.java","source/com/intellij/uiDesigner/componentTree/ComponentTreeBuilder.java","source/com/intellij/uiDesigner/componentTree/ComponentTreeStructure.java","source/com/intellij/uiDesigner/componentTree/QuickFixManagerImpl.java","source/com/intellij/uiDesigner/componentTree/RootDescriptor.java","source/com/intellij/uiDesigner/editor/MyEditorState.java","source/com/intellij/uiDesigner/editor/UIFormEditor.java","source/com/intellij/uiDesigner/editor/UIFormEditorProvider.java","source/com/intellij/uiDesigner/make/BindingsCache.java","source/com/intellij/uiDesigner/make/CopyResourcesUtil.java","source/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java","source/com/intellij/uiDesigner/make/Form2SourceCompiler.java","source/com/intellij/uiDesigner/make/FormSourceCodeGenerator.java","source/com/intellij/uiDesigner/palette/ComponentItem.java","source/com/intellij/uiDesigner/palette/ComponentItemDialog.java","source/com/intellij/uiDesigner/palette/GroupItem.java","source/com/intellij/uiDesigner/palette/Palette.java","source/com/intellij/uiDesigner/propertyInspector/IntrospectedProperty.java","source/com/intellij/uiDesigner/propertyInspector/Property.java","source/com/intellij/uiDesigner/propertyInspector/PropertyEditor.java","source/com/intellij/uiDesigner/propertyInspector/PropertyEditorAdapter.java","source/com/intellij/uiDesigner/propertyInspector/PropertyEditorListener.java","source/com/intellij/uiDesigner/propertyInspector/PropertyInspector.java","source/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java","source/com/intellij/uiDesigner/propertyInspector/PropertyRenderer.java","source/com/intellij/uiDesigner/propertyInspector/QuickFixManagerImpl.java","source/com/intellij/uiDesigner/propertyInspector/editors/BindingEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/BooleanEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/BorderTypeEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/IntEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/IntEnumEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java","source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditor.java","source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditorDialog.java","source/com/intellij/uiDesigner/propertyInspector/properties/AbstractDimensionPropery.java","source/com/intellij/uiDesigner/propertyInspector/properties/AbstractInsetsProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/BorderProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/HGapProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/HSizePolicyProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroBooleanProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroDimensionProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroDoubleProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroInsetsProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroIntProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroRectangleProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/IntroStringProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/MarginProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/MaximumSizeProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/MinimumSizeProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/PreferredSizeProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeHorizontallyProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeVerticallyProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/SizePolicyProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/VGapProperty.java","source/com/intellij/uiDesigner/propertyInspector/properties/VSizePolicyProperty.java","source/com/intellij/uiDesigner/propertyInspector/renderers/BooleanRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/ClassToBindRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/DimensionRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/InsetsPropertyRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/IntEnumRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/LabelPropertyRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/RectangleRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/SizePolicyRenderer.java","source/com/intellij/uiDesigner/propertyInspector/renderers/StringRenderer.java","source/com/intellij/uiDesigner/quickFixes/CreateClassToBindFix.java","source/com/intellij/uiDesigner/quickFixes/CreateFieldFix.java","source/com/intellij/uiDesigner/quickFixes/FocusListenerImpl.java","source/com/intellij/uiDesigner/quickFixes/LightBulbComponentImpl.java","source/com/intellij/uiDesigner/quickFixes/QuickFix.java","source/com/intellij/uiDesigner/quickFixes/QuickFixManager.java","source/com/intellij/uiDesigner/quickFixes/ShowHintAction.java","source/com/intellij/uiDesigner/quickFixes/VisibilityWatcherImpl.java","source/com/intellij/uiDesigner/wizard/BeanProperty.java","source/com/intellij/uiDesigner/wizard/BeanPropertyListCellRenderer.java","source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellEditor.java","source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellRenderer.java","source/com/intellij/uiDesigner/wizard/BeanStep.java","source/com/intellij/uiDesigner/wizard/BindCompositeStep.java","source/com/intellij/uiDesigner/wizard/BindToExistingBeanStep.java","source/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java","source/com/intellij/uiDesigner/wizard/DataBindingWizard.java","source/com/intellij/uiDesigner/wizard/FormProperty.java","source/com/intellij/uiDesigner/wizard/FormProperty2BeanProperty.java","source/com/intellij/uiDesigner/wizard/FormPropertyTableCellRenderer.java","source/com/intellij/uiDesigner/wizard/Generator.java","source/com/intellij/uiDesigner/wizard/WizardData.java","source/com/intellij/unscramble/UnscrambleAction.java","source/com/intellij/unscramble/UnscrambleDialog.java","source/com/intellij/unscramble/UnscrambleFromClipboardAction.java","source/com/intellij/usageView/FindUsagesCommand.java","source/com/intellij/usageView/UsageViewUtil.java","source/com/intellij/usageView/impl/SelectInEditorHandler.java","source/com/intellij/usageView/impl/UsageViewManagerImpl.java","source/com/intellij/util/ActionRunner.java","source/com/intellij/util/EditorPopupHandler.java","source/com/intellij/util/IJSwingUtilities.java","source/com/intellij/util/ScrambledInputStream.java","source/com/intellij/util/ScrambledOutputStream.java","source/com/intellij/util/config/AbstractProperty.java","source/com/intellij/util/config/BooleanProperty.java","source/com/intellij/util/config/ExternalizablePropertyContainer.java","source/com/intellij/util/config/Externalizer.java","source/com/intellij/util/config/IntProperty.java","source/com/intellij/util/config/ListProperty.java","source/com/intellij/util/config/StorageAccessors.java","source/com/intellij/util/config/StorageProperty.java","source/com/intellij/util/config/StringProperty.java","source/com/intellij/util/config/ToggleBooleanProperty.java","source/com/intellij/util/config/ValueProperty.java","source/com/intellij/util/io/ByteBufferMap.java","source/com/intellij/util/io/ByteBufferMapWriteHandler.java","source/com/intellij/util/io/ByteBufferRADataInput.java","source/com/intellij/util/io/FileByteBuffer.java","source/com/intellij/util/io/FileKeyProvider.java","source/com/intellij/util/io/IntArrayValueProvider.java","source/com/intellij/util/io/IntValueProvider.java","source/com/intellij/util/io/IntegerKeyProvider.java","source/com/intellij/util/io/RandomAccessDataInput.java","source/com/intellij/util/io/RecordDataOutput.java","source/com/intellij/util/io/StringKeyProvider.java","source/com/intellij/util/io/WriteableMap.java","source/com/intellij/util/io/WriteableMapAdapter.java","source/com/intellij/util/io/WriteableTIntObjectMapAdapter.java","source/com/intellij/util/net/AuthenticationDialog.java","source/com/intellij/util/net/AuthenticationPanel.java","source/com/intellij/util/net/HTTPProxySettingsDialog.java","source/com/intellij/util/net/HTTPProxySettingsPanel.java","source/com/intellij/util/net/HttpConfigurable.java","source/com/intellij/util/net/IOExceptionDialog.java","source/com/intellij/util/net/LockException.java","source/com/intellij/util/properties/EncodingAwareProperties.java","source/com/intellij/util/text/ElementPresentation.java","source/com/intellij/util/ui/CellEditorComponentWithBrowseButton.java","source/com/intellij/util/ui/tree/TreeModelAdapter.java","source/com/intellij/xml/actions/ValidateXmlAction.java","source/com/intellij/xml/actions/ValidateXmlActionHandler.java","source/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java","source/com/intellij/xml/impl/dtd/XmlAttributeDescriptorImpl.java","source/com/intellij/xml/impl/dtd/XmlElementDescriptorImpl.java","source/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java","source/com/intellij/xml/impl/schema/AnyXmlAttributeDescriptor.java","source/com/intellij/xml/impl/schema/AnyXmlElementDescriptor.java","source/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java","source/com/intellij/xml/impl/schema/SimpleTypeDescriptor.java","source/com/intellij/xml/impl/schema/StdTypeDescriptor.java","source/com/intellij/xml/impl/schema/TypeDescriptor.java","source/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java","source/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java","source/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java","source/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java","source/com/intellij/xml/util/HtmlUtil.java","source/com/intellij/xml/util/XmlNSDescriptorSequence.java","source/com/intellij/xml/util/XmlResourceResolver.java","source/com/intellij/xml/util/XmlUtil.java","source/com/intellij/xml/util/documentation/CompositeAttributeTagDescriptor.java","source/com/intellij/xml/util/documentation/EntityDescriptor.java","source/com/intellij/xml/util/documentation/HtmlAttributeDescriptor.java","source/com/intellij/xml/util/documentation/HtmlDescriptorsTable.java","source/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java","source/com/intellij/xml/util/documentation/HtmlTagDescriptor.java","source/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java","source/com/intellij/xml/util/documentation/XmlDocumentationProvider.java","testData/dependencies/dependencies/src/com/package1/Class1.java","testData/dependencies/dependencies/src/com/package1/Class2.java","testData/inspection/canBeFinal/SCR6073/src/A.java","testData/inspection/canBeFinal/SCR6781/src/A.java","testData/inspection/canBeFinal/SCR6845/src/A.java","testData/inspection/canBeFinal/SCR6861/src/A.java","testData/inspection/canBeFinal/SCR7737/ext_src/B.java","testData/inspection/canBeFinal/SCR7737/src/A.java","testData/inspection/canBeFinal/fieldAndTryBlock/src/Foo.java","testData/inspection/canBeFinal/fields/src/Foo.java","testData/inspection/canBeFinal/methodInheritance/src/a.java","testData/inspection/canBeFinal/privateInners/src/Foo.java","testData/inspection/canBeFinal/simpleClassInheritance/src/Foo.java","testData/inspection/canBeFinal/simpleClassInheritance1/src/Foo.java","testData/inspection/dataFlow/CatchParameterCantBeNull/src/Test.java","testData/inspection/dataFlow/GenericInstanceof/src/GenericInstanceof.java","testData/inspection/dataFlow/Instanceof/src/Foo.java","testData/inspection/dataFlow/SCR13626/src/Test.java","testData/inspection/dataFlow/SCR13702/src/Foo.java","testData/inspection/dataFlow/SCR13871/src/Aaa.java","testData/inspection/dataFlow/SCR14314/src/Finally.java","testData/inspection/dataFlow/SCR14819/src/Test.java","testData/inspection/dataFlow/SCR15162/src/NullTest.java","testData/inspection/dataFlow/SCR15406/src/CodeFlowTest.java","testData/inspection/dataFlow/SCR18186/src/Test.java","testData/inspection/dataFlow/SCR39950/src/Test.java","testData/inspection/dataFlow/andEq/src/Test.java","testData/inspection/dataFlow/caseAndNpe/src/CaseAndNpe.java","testData/inspection/dataFlow/cce/src/Cce.java","testData/inspection/dataFlow/exceptionCFG/src/ExceptionCFG.java","testData/inspection/dataFlow/inst/src/Inst.java","testData/inspection/dataFlow/npe1/src/Npe.java","testData/inspection/dataFlow/nullableField/src/Test.java","testData/inspection/dataFlow/orBug/src/Test.java","testData/inspection/dataFlow/scrIDEA1/src/Test.java","testData/inspection/dataFlow/thisInstanceof/src/Test.java","testData/inspection/dataFlow/wrongEqualTypes/src/Test.java","testData/inspection/dataFlow/xor/src/Test.java","testData/inspection/defUse/SCR28019/src/AsynchronousImageLoader.java","testData/inspection/defUse/SCR40364/src/Test.java","testData/inspection/defUse/SCR5144/src/AssignTest.java","testData/inspection/defUse/SCR6843/src/NotUsedTest.java","testData/inspection/defUse/arrayIndexUsages/src/Foo.java","testData/inspection/defUse/unusedVariable/src/Foo.java","testData/inspection/emptyMethod/SCR8321/src/MyAdapter.java","testData/inspection/emptyMethod/SCR8321/src/MyAdapterUsage.java","testData/inspection/emptyMethod/SCR8321/src/MyListener.java","testData/inspection/emptyMethod/externalOverride/ext_src/Derived.java","testData/inspection/emptyMethod/externalOverride/src/Base.java","testData/inspection/emptyMethod/superCall/src/Base.java","testData/inspection/emptyMethod/superCall/src/Derived.java","testData/inspection/localCanBeFinal/SCR11757/src/Test.java","testData/inspection/localCanBeFinal/SCR6744_1/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR6744_2/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR6744_3/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR6744_4/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR6744_5/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR6744_6/src/foo/Test.java","testData/inspection/localCanBeFinal/SCR7428/src/Junk.java","testData/inspection/localCanBeFinal/SCR7428_1/src/Junk.java","testData/inspection/localCanBeFinal/SCR7601/src/TestFinal2.java","testData/inspection/localCanBeFinal/if/src/Test.java","testData/inspection/localCanBeFinal/incompleteAssignment/src/Test.java","testData/inspection/localCanBeFinal/multiWriteNoRead/src/Test.java","testData/inspection/localCanBeFinal/parameters/src/Test.java","testData/inspection/redundantThrow/SCR14543/src/E.java","testData/inspection/redundantThrow/SCR6858/src/Foo.java","testData/inspection/redundantThrow/SCR8322/src/aPackage/AClass.java","testData/inspection/redundantThrow/SCR8322/src/aPackage/AClassTwo.java","testData/inspection/redundantThrow/SCR8322/src/aPackage/AnInterface.java","testData/inspection/visibility/SCR11792/src/Foo.java","testData/inspection/visibility/SCR5008/src/marti/p1/SubClass.java","testData/inspection/visibility/SCR5008/src/marti/p1/SuperClass.java","testData/inspection/visibility/SCR6856/src/A.java","testData/inspection/visibility/innerConstructor/src/Foo.java","testData/inspection/visibility/packageLevelTops/src/package1/PackageLevelServer.java","testData/inspection/visibility/packageLevelTops/src/package1/PublicServer.java","testData/inspection/visibility/packageLevelTops/src/package2/Client.java","testData/projectView/standardProviders/src/com/package1/Class1.java","testData/projectView/standardProviders/src/com/package1/Class2.java","testData/projectView/standardProviders/src/com/package1/Class4.java","testData/projectView/standardProviders/src/com/package1/Form1.java","testData/psi/arrayIndexOutOfBounds/src/bla/Bla.java","testData/psi/arrayIndexOutOfBounds/src/bla/Blu.java","testData/psi/constantValues/ClassWithConstants.java","testData/psi/normalizeDeclaration/1.java","testData/psi/normalizeDeclaration/1_after.java","testData/psi/normalizeDeclaration/2.java","testData/psi/normalizeDeclaration/2_after.java","testData/psi/normalizeDeclaration/SCR6549.java","testData/psi/normalizeDeclaration/SCR6549_after.java","testData/psi/normalizeDeclaration/SCR9467.java","testData/psi/normalizeDeclaration/SCR9467_1.java","testData/psi/normalizeDeclaration/SCR9467_1_after.java","testData/psi/normalizeDeclaration/SCR9467_after.java","testData/refactoring/changeClassSignature/AddParam.java","testData/refactoring/changeClassSignature/NoParams.java","testData/refactoring/changeClassSignature/RemoveAllParams.java","testData/refactoring/changeClassSignature/ReorderParams.java","testData/refactoring/changeSignature/AddRuntimeException.java","testData/refactoring/changeSignature/AlreadyHandled.java","testData/refactoring/changeSignature/CovariantReturnType.java","testData/refactoring/changeSignature/DefaultConstructor.java","testData/refactoring/changeSignature/EnumConstructor.java","testData/refactoring/changeSignature/GenerateDelegate.java","testData/refactoring/changeSignature/GenerateDelegateConstructor.java","testData/refactoring/changeSignature/GenerateDelegateDefaultConstructor.java","testData/refactoring/changeSignature/GenerateDelegateForAbstract.java","testData/refactoring/changeSignature/GenerateDelegateWithParametersReordering.java","testData/refactoring/changeSignature/GenerateDelegateWithReturn.java","testData/refactoring/changeSignature/GenericTypes.java","testData/refactoring/changeSignature/GenericTypesInOldParameters.java","testData/refactoring/changeSignature/ParameterReorder.java","testData/refactoring/changeSignature/ReorderExceptions.java","testData/refactoring/changeSignature/SCR40895.java","testData/refactoring/changeSignature/Simple.java","testData/refactoring/changeSignature/TypeParametersInMethod.java","testData/refactoring/changeSignature/UseAnyVariable.java","testData/refactoring/changeSignature/Varargs1.java","testData/refactoring/convertToInstanceMethod/Interface.java","testData/refactoring/convertToInstanceMethod/Interface2.java","testData/refactoring/convertToInstanceMethod/InterfaceTypeParameter.java","testData/refactoring/convertToInstanceMethod/Simple.java","testData/refactoring/convertToInstanceMethod/TypeParameter.java","testData/refactoring/extractMethod/AnonInner.java","testData/refactoring/extractMethod/AnonInner_after.java","testData/refactoring/extractMethod/BooleanExpression.java","testData/refactoring/extractMethod/BooleanExpression_after.java","testData/refactoring/extractMethod/CodeDuplicates.java","testData/refactoring/extractMethod/CodeDuplicates2.java","testData/refactoring/extractMethod/CodeDuplicates2_after.java","testData/refactoring/extractMethod/CodeDuplicates3.java","testData/refactoring/extractMethod/CodeDuplicates3_after.java","testData/refactoring/extractMethod/CodeDuplicates4.java","testData/refactoring/extractMethod/CodeDuplicates4_after.java","testData/refactoring/extractMethod/CodeDuplicates5.java","testData/refactoring/extractMethod/CodeDuplicates5_after.java","testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue.java","testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1.java","testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1_after.java","testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue_after.java","testData/refactoring/extractMethod/CodeDuplicatesWithReturn.java","testData/refactoring/extractMethod/CodeDuplicatesWithReturn2.java","testData/refactoring/extractMethod/CodeDuplicatesWithReturn2_after.java","testData/refactoring/extractMethod/CodeDuplicatesWithReturn_after.java","testData/refactoring/extractMethod/CodeDuplicates_after.java","testData/refactoring/extractMethod/ExitPoints1.java","testData/refactoring/extractMethod/ExitPoints2.java","testData/refactoring/extractMethod/ExitPoints3.java","testData/refactoring/extractMethod/ExitPoints4.java","testData/refactoring/extractMethod/ExitPoints5.java","testData/refactoring/extractMethod/ExitPoints5_after.java","testData/refactoring/extractMethod/ExitPointsInsideLoop.java","testData/refactoring/extractMethod/ExpressionDuplicates.java","testData/refactoring/extractMethod/ExpressionDuplicates_after.java","testData/refactoring/extractMethod/ExtractFromAnonymous.java","testData/refactoring/extractMethod/ExtractFromAnonymous_after.java","testData/refactoring/extractMethod/ExtractFromCodeBlock.java","testData/refactoring/extractMethod/ExtractFromCodeBlock_after.java","testData/refactoring/extractMethod/ExtractFromFinally.java","testData/refactoring/extractMethod/ExtractFromFinally_after.java","testData/refactoring/extractMethod/ExtractFromTryFinally.java","testData/refactoring/extractMethod/ExtractFromTryFinally_after.java","testData/refactoring/extractMethod/FinalOutputVar.java","testData/refactoring/extractMethod/FinalOutputVar_after.java","testData/refactoring/extractMethod/Finally.java","testData/refactoring/extractMethod/Finally_after.java","testData/refactoring/extractMethod/ForEach.java","testData/refactoring/extractMethod/ForEach_after.java","testData/refactoring/extractMethod/LesyaBug.java","testData/refactoring/extractMethod/LesyaBug_after.java","testData/refactoring/extractMethod/OneBranchAssignment.java","testData/refactoring/extractMethod/OneBranchAssignment_after.java","testData/refactoring/extractMethod/SCR12245.java","testData/refactoring/extractMethod/SCR12245_after.java","testData/refactoring/extractMethod/SCR15815.java","testData/refactoring/extractMethod/SCR15815_after.java","testData/refactoring/extractMethod/SCR27887.java","testData/refactoring/extractMethod/SCR27887_after.java","testData/refactoring/extractMethod/SCR28427.java","testData/refactoring/extractMethod/SCR28427_after.java","testData/refactoring/extractMethod/SCR32924.java","testData/refactoring/extractMethod/SCR32924_after.java","testData/refactoring/extractMethod/Scr10464.java","testData/refactoring/extractMethod/Scr10464_after.java","testData/refactoring/extractMethod/Scr6241.java","testData/refactoring/extractMethod/Scr6241_after.java","testData/refactoring/extractMethod/Scr7091.java","testData/refactoring/extractMethod/Scr7091_after.java","testData/refactoring/extractMethod/Scr9852.java","testData/refactoring/extractMethod/Scr9852_after.java","testData/refactoring/extractMethod/TryFinally.java","testData/refactoring/extractMethod/TryFinallyInsideFor.java","testData/refactoring/extractMethod/TryFinallyInsideFor_after.java","testData/refactoring/extractMethod/TryFinally_after.java","testData/refactoring/extractMethod/UnusedInitializedVar.java","testData/refactoring/extractMethod/UnusedInitializedVar_after.java","testData/refactoring/extractMethod/UseVarAfterTry.java","testData/refactoring/extractMethod/UseVarAfterTry_after.java","testData/refactoring/inheritanceToDelegation/abstractBase/after/A.java","testData/refactoring/inheritanceToDelegation/abstractBase/after/Base.java","testData/refactoring/inheritanceToDelegation/abstractBase/before/A.java","testData/refactoring/inheritanceToDelegation/abstractBase/before/Base.java","testData/refactoring/inheritanceToDelegation/abstractBase1/after/A.java","testData/refactoring/inheritanceToDelegation/abstractBase1/after/Base.java","testData/refactoring/inheritanceToDelegation/abstractBase1/before/A.java","testData/refactoring/inheritanceToDelegation/abstractBase1/before/Base.java","testData/refactoring/inheritanceToDelegation/getter/after/A.java","testData/refactoring/inheritanceToDelegation/getter/after/B.java","testData/refactoring/inheritanceToDelegation/getter/before/A.java","testData/refactoring/inheritanceToDelegation/getter/before/B.java","testData/refactoring/inheritanceToDelegation/hierarchy/after/A.java","testData/refactoring/inheritanceToDelegation/hierarchy/after/Base.java","testData/refactoring/inheritanceToDelegation/hierarchy/after/Test.java","testData/refactoring/inheritanceToDelegation/hierarchy/after/X.java","testData/refactoring/inheritanceToDelegation/hierarchy/before/A.java","testData/refactoring/inheritanceToDelegation/hierarchy/before/Base.java","testData/refactoring/inheritanceToDelegation/hierarchy/before/Test.java","testData/refactoring/inheritanceToDelegation/hierarchy/before/X.java","testData/refactoring/inheritanceToDelegation/innerClass/after/A.java","testData/refactoring/inheritanceToDelegation/innerClass/after/Base.java","testData/refactoring/inheritanceToDelegation/innerClass/before/A.java","testData/refactoring/inheritanceToDelegation/innerClass/before/Base.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/A.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseClass.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseInterface.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/A.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseClass.java","testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseInterface.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/A.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseClass.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseInterface.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/A.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseClass.java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseInterface.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/A.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Intf.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Usage.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/A.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Intf.java","testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Usage.java","testData/refactoring/inheritanceToDelegation/interfaces/after/A.java","testData/refactoring/inheritanceToDelegation/interfaces/after/Base.java","testData/refactoring/inheritanceToDelegation/interfaces/after/I.java","testData/refactoring/inheritanceToDelegation/interfaces/after/J.java","testData/refactoring/inheritanceToDelegation/interfaces/after/Usage.java","testData/refactoring/inheritanceToDelegation/interfaces/before/A.java","testData/refactoring/inheritanceToDelegation/interfaces/before/Base.java","testData/refactoring/inheritanceToDelegation/interfaces/before/I.java","testData/refactoring/inheritanceToDelegation/interfaces/before/J.java","testData/refactoring/inheritanceToDelegation/interfaces/before/Usage.java","testData/refactoring/inheritanceToDelegation/overridenMethods/after/A.java","testData/refactoring/inheritanceToDelegation/overridenMethods/after/Base.java","testData/refactoring/inheritanceToDelegation/overridenMethods/before/A.java","testData/refactoring/inheritanceToDelegation/overridenMethods/before/Base.java","testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java","testData/refactoring/inheritanceToDelegation/scr20557/before/xxx/SCR20557.java","testData/refactoring/inheritanceToDelegation/simpleInsertion/after/A.java","testData/refactoring/inheritanceToDelegation/simpleInsertion/after/B.java","testData/refactoring/inheritanceToDelegation/simpleInsertion/before/A.java","testData/refactoring/inheritanceToDelegation/simpleInsertion/before/B.java","testData/refactoring/inheritanceToDelegation/subClass/after/A.java","testData/refactoring/inheritanceToDelegation/subClass/after/B.java","testData/refactoring/inheritanceToDelegation/subClass/after/DelegatedBase.java","testData/refactoring/inheritanceToDelegation/subClass/after/Usage.java","testData/refactoring/inheritanceToDelegation/subClass/before/A.java","testData/refactoring/inheritanceToDelegation/subClass/before/B.java","testData/refactoring/inheritanceToDelegation/subClass/before/DelegatedBase.java","testData/refactoring/inheritanceToDelegation/subClass/before/Usage.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/A.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/B.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/DelegatedBase.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/Usage.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/A.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/B.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/DelegatedBase.java","testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/Usage.java","testData/refactoring/inheritanceToDelegation/subinterface/after/A.java","testData/refactoring/inheritanceToDelegation/subinterface/after/B.java","testData/refactoring/inheritanceToDelegation/subinterface/after/J.java","testData/refactoring/inheritanceToDelegation/subinterface/after/Usage.java","testData/refactoring/inheritanceToDelegation/subinterface/before/A.java","testData/refactoring/inheritanceToDelegation/subinterface/before/B.java","testData/refactoring/inheritanceToDelegation/subinterface/before/J.java","testData/refactoring/inheritanceToDelegation/subinterface/before/Usage.java","testData/refactoring/inheritanceToDelegation/superCalls/after/A.java","testData/refactoring/inheritanceToDelegation/superCalls/after/B.java","testData/refactoring/inheritanceToDelegation/superCalls/before/A.java","testData/refactoring/inheritanceToDelegation/superCalls/before/B.java","testData/refactoring/inlineLocal/Inference.java","testData/refactoring/inlineLocal/Qualifier.java","testData/refactoring/inlineMethod/ArrayAccess.java","testData/refactoring/inlineMethod/CallInFor.java","testData/refactoring/inlineMethod/CallUnderIf.java","testData/refactoring/inlineMethod/ChainingConstructor.java","testData/refactoring/inlineMethod/ConflictingField.java","testData/refactoring/inlineMethod/FieldInitializer.java","testData/refactoring/inlineMethod/FinalParameters.java","testData/refactoring/inlineMethod/FinalParameters1.java","testData/refactoring/inlineMethod/InlineParms.java","testData/refactoring/inlineMethod/InlineWithQualifier.java","testData/refactoring/inlineMethod/InlineWithQualifierFromSuper.java","testData/refactoring/inlineMethod/InlineWithTry.java","testData/refactoring/inlineMethod/LocalVariableResult.java","testData/refactoring/inlineMethod/NameClash.java","testData/refactoring/inlineMethod/SCR20655.java","testData/refactoring/inlineMethod/SCR22644.java","testData/refactoring/inlineMethod/SCR31093.java","testData/refactoring/inlineMethod/SCR37742.java","testData/refactoring/inlineMethod/Scr10884.java","testData/refactoring/inlineMethod/Scr13831.java","testData/refactoring/inlineMethod/SideEffect.java","testData/refactoring/inlineMethod/StaticFieldInitializer.java","testData/refactoring/inlineMethod/Try.java","testData/refactoring/inlineMethod/TrySynchronized.java","testData/refactoring/inlineMethod/VoidWithReturn.java","testData/refactoring/introduceField/after1.java","testData/refactoring/introduceField/before1.java","testData/refactoring/introduceParameter/after01.java","testData/refactoring/introduceParameter/after02.java","testData/refactoring/introduceParameter/after03.java","testData/refactoring/introduceParameter/after04.java","testData/refactoring/introduceParameter/after05.java","testData/refactoring/introduceParameter/after06.java","testData/refactoring/introduceParameter/after07.java","testData/refactoring/introduceParameter/after08.java","testData/refactoring/introduceParameter/after09.java","testData/refactoring/introduceParameter/after10.java","testData/refactoring/introduceParameter/after11.java","testData/refactoring/introduceParameter/after12.java","testData/refactoring/introduceParameter/after13.java","testData/refactoring/introduceParameter/after14.java","testData/refactoring/introduceParameter/after15.java","testData/refactoring/introduceParameter/after16.java","testData/refactoring/introduceParameter/after17.java","testData/refactoring/introduceParameter/after18.java","testData/refactoring/introduceParameter/after19.java","testData/refactoring/introduceParameter/after20.java","testData/refactoring/introduceParameter/after21.java","testData/refactoring/introduceParameter/after22.java","testData/refactoring/introduceParameter/after23.java","testData/refactoring/introduceParameter/after24.java","testData/refactoring/introduceParameter/after25.java","testData/refactoring/introduceParameter/after26.java","testData/refactoring/introduceParameter/after27.java","testData/refactoring/introduceParameter/after28.java","testData/refactoring/introduceParameter/after29.java","testData/refactoring/introduceParameter/after30.java","testData/refactoring/introduceParameter/before01.java","testData/refactoring/introduceParameter/before02.java","testData/refactoring/introduceParameter/before03.java","testData/refactoring/introduceParameter/before04.java","testData/refactoring/introduceParameter/before05.java","testData/refactoring/introduceParameter/before06.java","testData/refactoring/introduceParameter/before07.java","testData/refactoring/introduceParameter/before08.java","testData/refactoring/introduceParameter/before09.java","testData/refactoring/introduceParameter/before10.java","testData/refactoring/introduceParameter/before11.java","testData/refactoring/introduceParameter/before12.java","testData/refactoring/introduceParameter/before13.java","testData/refactoring/introduceParameter/before14.java","testData/refactoring/introduceParameter/before15.java","testData/refactoring/introduceParameter/before16.java","testData/refactoring/introduceParameter/before17.java","testData/refactoring/introduceParameter/before18.java","testData/refactoring/introduceParameter/before19.java","testData/refactoring/introduceParameter/before20.java","testData/refactoring/introduceParameter/before21.java","testData/refactoring/introduceParameter/before22.java","testData/refactoring/introduceParameter/before23.java","testData/refactoring/introduceParameter/before24.java","testData/refactoring/introduceParameter/before25.java","testData/refactoring/introduceParameter/before26.java","testData/refactoring/introduceParameter/before27.java","testData/refactoring/introduceParameter/before28.java","testData/refactoring/introduceParameter/before29.java","testData/refactoring/introduceParameter/before30.java","testData/refactoring/makeMethodStatic/after1.java","testData/refactoring/makeMethodStatic/after10-np.java","testData/refactoring/makeMethodStatic/after10.java","testData/refactoring/makeMethodStatic/after11.java","testData/refactoring/makeMethodStatic/after12.java","testData/refactoring/makeMethodStatic/after13.java","testData/refactoring/makeMethodStatic/after14.java","testData/refactoring/makeMethodStatic/after15.java","testData/refactoring/makeMethodStatic/after16.java","testData/refactoring/makeMethodStatic/after17.java","testData/refactoring/makeMethodStatic/after18.java","testData/refactoring/makeMethodStatic/after19.java","testData/refactoring/makeMethodStatic/after2.java","testData/refactoring/makeMethodStatic/after3.java","testData/refactoring/makeMethodStatic/after4.java","testData/refactoring/makeMethodStatic/after5.java","testData/refactoring/makeMethodStatic/after6.java","testData/refactoring/makeMethodStatic/after7.java","testData/refactoring/makeMethodStatic/after8.java","testData/refactoring/makeMethodStatic/after9.java","testData/refactoring/makeMethodStatic/before1.java","testData/refactoring/makeMethodStatic/before10.java","testData/refactoring/makeMethodStatic/before11.java","testData/refactoring/makeMethodStatic/before12.java","testData/refactoring/makeMethodStatic/before13.java","testData/refactoring/makeMethodStatic/before14.java","testData/refactoring/makeMethodStatic/before15.java","testData/refactoring/makeMethodStatic/before16.java","testData/refactoring/makeMethodStatic/before17.java","testData/refactoring/makeMethodStatic/before18.java","testData/refactoring/makeMethodStatic/before19.java","testData/refactoring/makeMethodStatic/before2.java","testData/refactoring/makeMethodStatic/before3.java","testData/refactoring/makeMethodStatic/before4.java","testData/refactoring/makeMethodStatic/before5.java","testData/refactoring/makeMethodStatic/before6.java","testData/refactoring/makeMethodStatic/before7.java","testData/refactoring/makeMethodStatic/before8.java","testData/refactoring/makeMethodStatic/before9.java","testData/refactoring/migration/package/after/p1/C.java","testData/refactoring/migration/package/after/p1/C1.java","testData/refactoring/migration/package/before/p1/C.java","testData/refactoring/migration/package/before/p1/C1.java","testData/refactoring/migration/packageToNonExistentPackage/after/p1/C.java","testData/refactoring/migration/packageToNonExistentPackage/after/p1/C1.java","testData/refactoring/migration/packageToNonExistentPackage/before/p1/C.java","testData/refactoring/migration/packageToNonExistentPackage/before/p1/C1.java","testData/refactoring/migration/toNonExistentClass/after/p1/C.java","testData/refactoring/migration/toNonExistentClass/after/p1/C1.java","testData/refactoring/migration/toNonExistentClass/before/p1/C.java","testData/refactoring/migration/toNonExistentClass/before/p1/C1.java","testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C.java","testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C1.java","testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C.java","testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C1.java","testData/refactoring/moveClass/contextChange1/after/pack1/Class2.java","testData/refactoring/moveClass/contextChange1/after/pack2/Class1.java","testData/refactoring/moveClass/contextChange1/before/pack1/Class1.java","testData/refactoring/moveClass/contextChange1/before/pack1/Class2.java","testData/refactoring/moveClass/contextChange2/after/pack1/Class2.java","testData/refactoring/moveClass/contextChange2/after/pack2/Class1.java","testData/refactoring/moveClass/contextChange2/before/pack1/Class1.java","testData/refactoring/moveClass/contextChange2/before/pack1/Class2.java","testData/refactoring/moveClass/jsp/after/WEB-INF/TestTEI.java","testData/refactoring/moveClass/jsp/after/pack2/TestClass.java","testData/refactoring/moveClass/jsp/before/WEB-INF/TestTEI.java","testData/refactoring/moveClass/jsp/before/pack1/TestClass.java","testData/refactoring/moveClass/localClass/after/pack2/A.java","testData/refactoring/moveClass/localClass/before/pack1/A.java","testData/refactoring/moveClass/moveMultiple1/after/pack2/Class1.java","testData/refactoring/moveClass/moveMultiple1/after/pack2/Class2.java","testData/refactoring/moveClass/moveMultiple1/before/pack1/Class1.java","testData/refactoring/moveClass/moveMultiple1/before/pack1/Class2.java","testData/refactoring/moveClass/nonJava/after/pack2/Class1.java","testData/refactoring/moveClass/nonJava/before/pack1/Class1.java","testData/refactoring/moveClass/stringsAndComments/after/Client.java","testData/refactoring/moveClass/stringsAndComments/after/pack2/Class1.java","testData/refactoring/moveClass/stringsAndComments/before/Client.java","testData/refactoring/moveClass/stringsAndComments/before/pack1/Class1.java","testData/refactoring/moveClass/stringsAndComments2/after/pack2/AClass.java","testData/refactoring/moveClass/stringsAndComments2/before/pack1/AClass.java","testData/refactoring/moveInner/nonJavaFiles/after/pack1/Inner.java","testData/refactoring/moveInner/nonJavaFiles/after/pack1/Outer.java","testData/refactoring/moveInner/nonJavaFiles/before/pack1/Outer.java","testData/refactoring/moveInner/scr13730/after/pack1/Client.java","testData/refactoring/moveInner/scr13730/after/pack1/StaticInner.java","testData/refactoring/moveInner/scr13730/after/pack1/TopLevel.java","testData/refactoring/moveInner/scr13730/before/pack1/Client.java","testData/refactoring/moveInner/scr13730/before/pack1/TopLevel.java","testData/refactoring/moveInner/scr15142/after/xxx/Inner.java","testData/refactoring/moveInner/scr15142/after/xxx/Outer.java","testData/refactoring/moveInner/scr15142/before/xxx/Outer.java","testData/refactoring/moveInner/scr22592/after/xxx/Inner.java","testData/refactoring/moveInner/scr22592/after/xxx/Outer.java","testData/refactoring/moveInner/scr22592/before/xxx/Outer.java","testData/refactoring/moveInner/scr30106/after/p/A.java","testData/refactoring/moveInner/scr30106/after/p/B.java","testData/refactoring/moveInner/scr30106/after/p/X.java","testData/refactoring/moveInner/scr30106/before/p/A.java","testData/refactoring/moveInner/scr30106/before/p/X.java","testData/refactoring/moveMembers/innerClass/after/A.java","testData/refactoring/moveMembers/innerClass/after/B.java","testData/refactoring/moveMembers/innerClass/after/C.java","testData/refactoring/moveMembers/innerClass/before/A.java","testData/refactoring/moveMembers/innerClass/before/B.java","testData/refactoring/moveMembers/innerClass/before/C.java","testData/refactoring/moveMembers/javadocRefs/after/Class1.java","testData/refactoring/moveMembers/javadocRefs/after/Class2.java","testData/refactoring/moveMembers/javadocRefs/after/User.java","testData/refactoring/moveMembers/javadocRefs/before/Class1.java","testData/refactoring/moveMembers/javadocRefs/before/Class2.java","testData/refactoring/moveMembers/javadocRefs/before/User.java","testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/A.java","testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/Outer.java","testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2/B.java","testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/A.java","testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/Outer.java","testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2/B.java","testData/refactoring/moveMembers/scr11871/after/pack1/A.java","testData/refactoring/moveMembers/scr11871/after/pack1/B.java","testData/refactoring/moveMembers/scr11871/before/pack1/A.java","testData/refactoring/moveMembers/scr11871/before/pack1/B.java","testData/refactoring/moveMembers/scr40064/after/Test.java","testData/refactoring/moveMembers/scr40064/before/Test.java","testData/refactoring/moveMembers/scr40947/after/Test.java","testData/refactoring/moveMembers/scr40947/before/Test.java","testData/refactoring/moveMembers/twoMethods/after/pack1/A.java","testData/refactoring/moveMembers/twoMethods/after/pack1/C.java","testData/refactoring/moveMembers/twoMethods/after/pack2/B.java","testData/refactoring/moveMembers/twoMethods/before/pack1/A.java","testData/refactoring/moveMembers/twoMethods/before/pack1/C.java","testData/refactoring/moveMembers/twoMethods/before/pack2/B.java","testData/refactoring/moveMembers/weirdDeclaration/after/A.java","testData/refactoring/moveMembers/weirdDeclaration/after/B.java","testData/refactoring/moveMembers/weirdDeclaration/before/A.java","testData/refactoring/moveMembers/weirdDeclaration/before/B.java","testData/refactoring/movePackage/insidePackage/after/a/b/a/A.java","testData/refactoring/movePackage/insidePackage/before/a/A.java","testData/refactoring/movePackage/moveSingle/after/pack2/User1.java","testData/refactoring/movePackage/moveSingle/after/pack2/User2.java","testData/refactoring/movePackage/moveSingle/after/target/pack1/Class1.java","testData/refactoring/movePackage/moveSingle/before/pack1/Class1.java","testData/refactoring/movePackage/moveSingle/before/pack2/User1.java","testData/refactoring/movePackage/moveSingle/before/pack2/User2.java","testData/refactoring/movePackage/qualifiedRef/after/Usage.java","testData/refactoring/movePackage/qualifiedRef/after/package2/test/A.java","testData/refactoring/movePackage/qualifiedRef/before/Usage.java","testData/refactoring/movePackage/qualifiedRef/before/package1/test/A.java","testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1/A.java","testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1/B.java","testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1/A.java","testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1/B.java","testData/refactoring/renameClass/collision/after/pack1/List.java","testData/refactoring/renameClass/collision/after/pack2/Usage.java","testData/refactoring/renameClass/collision/after/pack2/Usage2.java","testData/refactoring/renameClass/collision/before/pack1/MyList.java","testData/refactoring/renameClass/collision/before/pack2/Usage.java","testData/refactoring/renameClass/collision/before/pack2/Usage2.java","testData/refactoring/renameClass/import/after/FooBar.java","testData/refactoring/renameClass/import/after/a/BlubFoo.java","testData/refactoring/renameClass/import/before/FooBar.java","testData/refactoring/renameClass/import/before/a/Blubfoo.java","testData/refactoring/renameClass/innerClass/after/pack1/OuterClass.java","testData/refactoring/renameClass/innerClass/before/pack1/OuterClass.java","testData/refactoring/renameClass/nonJava/after/pack1/Class1New.java","testData/refactoring/renameClass/nonJava/before/pack1/Class1.java","testData/refactoring/renameField/after01.java","testData/refactoring/renameField/after02.java","testData/refactoring/renameField/after03.java","testData/refactoring/renameField/before01.java","testData/refactoring/renameField/before02.java","testData/refactoring/renameField/before03.java","testData/refactoring/renameMethod/multi/staticImport1/after/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport1/after/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport1/before/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport1/before/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport2/after/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport2/after/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport2/before/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport2/before/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport3/after/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport3/after/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport3/before/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport3/before/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport4/after/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport4/after/pack2/Usage.java","testData/refactoring/renameMethod/multi/staticImport4/before/pack1/A.java","testData/refactoring/renameMethod/multi/staticImport4/before/pack2/Usage.java","testData/refactoring/replaceConstructorWithFactory/after01.java","testData/refactoring/replaceConstructorWithFactory/after02.java","testData/refactoring/replaceConstructorWithFactory/after03.java","testData/refactoring/replaceConstructorWithFactory/after04.java","testData/refactoring/replaceConstructorWithFactory/after05.java","testData/refactoring/replaceConstructorWithFactory/after06.java","testData/refactoring/replaceConstructorWithFactory/after07.java","testData/refactoring/replaceConstructorWithFactory/before01.java","testData/refactoring/replaceConstructorWithFactory/before02.java","testData/refactoring/replaceConstructorWithFactory/before03.java","testData/refactoring/replaceConstructorWithFactory/before04.java","testData/refactoring/replaceConstructorWithFactory/before05.java","testData/refactoring/replaceConstructorWithFactory/before06.java","testData/refactoring/replaceConstructorWithFactory/before07.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/C.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/Client.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/I.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/C.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/Client.java","testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/I.java","testData/refactoring/turnRefsToSuper/cast/after/A.java","testData/refactoring/turnRefsToSuper/cast/after/Client.java","testData/refactoring/turnRefsToSuper/cast/after/I.java","testData/refactoring/turnRefsToSuper/cast/before/A.java","testData/refactoring/turnRefsToSuper/cast/before/Client.java","testData/refactoring/turnRefsToSuper/cast/before/I.java","testData/refactoring/turnRefsToSuper/classUsage/after/A.java","testData/refactoring/turnRefsToSuper/classUsage/after/Client.java","testData/refactoring/turnRefsToSuper/classUsage/after/I.java","testData/refactoring/turnRefsToSuper/classUsage/before/A.java","testData/refactoring/turnRefsToSuper/classUsage/before/Client.java","testData/refactoring/turnRefsToSuper/classUsage/before/I.java","testData/refactoring/turnRefsToSuper/commonInheritor/after/Client.java","testData/refactoring/turnRefsToSuper/commonInheritor/before/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorFail/after/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorFail/before/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResults/after/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResults/before/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after/Client.java","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before/Client.java","testData/refactoring/turnRefsToSuper/fieldTest/after/Component1.java","testData/refactoring/turnRefsToSuper/fieldTest/after/ComponentCaller.java","testData/refactoring/turnRefsToSuper/fieldTest/after/IDoSomething.java","testData/refactoring/turnRefsToSuper/fieldTest/before/Component1.java","testData/refactoring/turnRefsToSuper/fieldTest/before/ComponentCaller.java","testData/refactoring/turnRefsToSuper/fieldTest/before/IDoSomething.java","testData/refactoring/turnRefsToSuper/instanceOf/after/A.java","testData/refactoring/turnRefsToSuper/instanceOf/after/Client.java","testData/refactoring/turnRefsToSuper/instanceOf/after/I.java","testData/refactoring/turnRefsToSuper/instanceOf/before/A.java","testData/refactoring/turnRefsToSuper/instanceOf/before/Client.java","testData/refactoring/turnRefsToSuper/instanceOf/before/I.java","testData/refactoring/turnRefsToSuper/methodFromSuper/after/AClass.java","testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper.java","testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper2.java","testData/refactoring/turnRefsToSuper/methodFromSuper/after/Client.java","testData/refactoring/turnRefsToSuper/methodFromSuper/before/AClass.java","testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper.java","testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper2.java","testData/refactoring/turnRefsToSuper/methodFromSuper/before/Client.java","testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AClass.java","testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AnInterface.java","testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client.java","testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client2.java","testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AClass.java","testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AnInterface.java","testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client.java","testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client2.java","testData/refactoring/turnRefsToSuper/returnValue/after/A.java","testData/refactoring/turnRefsToSuper/returnValue/after/B.java","testData/refactoring/turnRefsToSuper/returnValue/after/I.java","testData/refactoring/turnRefsToSuper/returnValue/before/A.java","testData/refactoring/turnRefsToSuper/returnValue/before/B.java","testData/refactoring/turnRefsToSuper/returnValue/before/I.java","testData/refactoring/turnRefsToSuper/returnValue2/after/A.java","testData/refactoring/turnRefsToSuper/returnValue2/after/B.java","testData/refactoring/turnRefsToSuper/returnValue2/after/I.java","testData/refactoring/turnRefsToSuper/returnValue2/before/A.java","testData/refactoring/turnRefsToSuper/returnValue2/before/B.java","testData/refactoring/turnRefsToSuper/returnValue2/before/I.java","testData/refactoring/turnRefsToSuper/scr34000/after/Main.java","testData/refactoring/turnRefsToSuper/scr34000/after/Model.java","testData/refactoring/turnRefsToSuper/scr34000/after/SimpleModel.java","testData/refactoring/turnRefsToSuper/scr34000/after/View.java","testData/refactoring/turnRefsToSuper/scr34000/before/Main.java","testData/refactoring/turnRefsToSuper/scr34000/before/Model.java","testData/refactoring/turnRefsToSuper/scr34000/before/SimpleModel.java","testData/refactoring/turnRefsToSuper/scr34000/before/View.java","testData/refactoring/turnRefsToSuper/scr34020/after/test/C.java","testData/refactoring/turnRefsToSuper/scr34020/before/test/C.java","testData/refactoring/turnRefsToSuper/superClass/after/AClass.java","testData/refactoring/turnRefsToSuper/superClass/after/ASuper.java","testData/refactoring/turnRefsToSuper/superClass/after/Client.java","testData/refactoring/turnRefsToSuper/superClass/before/AClass.java","testData/refactoring/turnRefsToSuper/superClass/before/ASuper.java","testData/refactoring/turnRefsToSuper/superClass/before/Client.java","testData/refactoring/turnRefsToSuper/toArray/after/A.java","testData/refactoring/turnRefsToSuper/toArray/after/B.java","testData/refactoring/turnRefsToSuper/toArray/after/I.java","testData/refactoring/turnRefsToSuper/toArray/before/A.java","testData/refactoring/turnRefsToSuper/toArray/before/B.java","testData/refactoring/turnRefsToSuper/toArray/before/I.java","testData/refactoring/turnRefsToSuper/useAsArg/after/AClass.java","testData/refactoring/turnRefsToSuper/useAsArg/after/Client.java","testData/refactoring/turnRefsToSuper/useAsArg/after/I.java","testData/refactoring/turnRefsToSuper/useAsArg/before/AClass.java","testData/refactoring/turnRefsToSuper/useAsArg/before/Client.java","testData/refactoring/turnRefsToSuper/useAsArg/before/I.java","testData/refactoring/typeCook/t01/after/test.java","testData/refactoring/typeCook/t01/before/test.java","testData/refactoring/typeCook/t02/after/test.java","testData/refactoring/typeCook/t02/before/test.java","testData/refactoring/typeCook/t03/after/test.java","testData/refactoring/typeCook/t03/before/test.java","testData/refactoring/typeCook/t04/after/test.java","testData/refactoring/typeCook/t04/before/test.java","testData/refactoring/typeCook/t05/after/test.java","testData/refactoring/typeCook/t05/before/test.java","testData/refactoring/typeCook/t06/after/test.java","testData/refactoring/typeCook/t06/before/test.java","testData/refactoring/typeCook/t07/after/test.java","testData/refactoring/typeCook/t07/before/test.java","testData/refactoring/typeCook/t08/after/test.java","testData/refactoring/typeCook/t08/before/test.java","testData/refactoring/typeCook/t09/after/test.java","testData/refactoring/typeCook/t09/before/test.java","testData/refactoring/typeCook/t10/after/test.java","testData/refactoring/typeCook/t10/before/test.java","testData/refactoring/typeCook/t100/after/test.java","testData/refactoring/typeCook/t100/before/test.java","testData/refactoring/typeCook/t101/after/test.java","testData/refactoring/typeCook/t101/before/test.java","testData/refactoring/typeCook/t102/after/test.java","testData/refactoring/typeCook/t102/before/test.java","testData/refactoring/typeCook/t103/after/test.java","testData/refactoring/typeCook/t103/before/test.java","testData/refactoring/typeCook/t104/after/test.java","testData/refactoring/typeCook/t104/before/test.java","testData/refactoring/typeCook/t105/after/test.java","testData/refactoring/typeCook/t105/before/test.java","testData/refactoring/typeCook/t106/after/test.java","testData/refactoring/typeCook/t106/before/test.java","testData/refactoring/typeCook/t107/after/test.java","testData/refactoring/typeCook/t107/before/test.java","testData/refactoring/typeCook/t108/after/test.java","testData/refactoring/typeCook/t108/before/test.java","testData/refactoring/typeCook/t109/after/test.java","testData/refactoring/typeCook/t109/before/test.java","testData/refactoring/typeCook/t11/after/test.java","testData/refactoring/typeCook/t11/before/test.java","testData/refactoring/typeCook/t110/after/test.java","testData/refactoring/typeCook/t110/before/test.java","testData/refactoring/typeCook/t111/after/test.java","testData/refactoring/typeCook/t111/before/test.java","testData/refactoring/typeCook/t112/after/test.java","testData/refactoring/typeCook/t112/before/test.java","testData/refactoring/typeCook/t113/after/test.java","testData/refactoring/typeCook/t113/before/test.java","testData/refactoring/typeCook/t114/after/test.java","testData/refactoring/typeCook/t114/before/test.java","testData/refactoring/typeCook/t115/after/test.java","testData/refactoring/typeCook/t115/before/test.java","testData/refactoring/typeCook/t116/after/test.java","testData/refactoring/typeCook/t116/before/test.java","testData/refactoring/typeCook/t117/after/test.java","testData/refactoring/typeCook/t117/before/test.java","testData/refactoring/typeCook/t118/after/test.java","testData/refactoring/typeCook/t118/before/test.java","testData/refactoring/typeCook/t119/after/test.java","testData/refactoring/typeCook/t119/before/test.java","testData/refactoring/typeCook/t12/after/test.java","testData/refactoring/typeCook/t12/before/test.java","testData/refactoring/typeCook/t120/after/test.java","testData/refactoring/typeCook/t120/before/test.java","testData/refactoring/typeCook/t121/after/test.java","testData/refactoring/typeCook/t121/before/test.java","testData/refactoring/typeCook/t122/after/test.java","testData/refactoring/typeCook/t122/before/test.java","testData/refactoring/typeCook/t123/after/test.java","testData/refactoring/typeCook/t123/before/test.java","testData/refactoring/typeCook/t124/after/test.java","testData/refactoring/typeCook/t124/before/test.java","testData/refactoring/typeCook/t125/after/test.java","testData/refactoring/typeCook/t125/before/test.java","testData/refactoring/typeCook/t126/after/test.java","testData/refactoring/typeCook/t126/before/test.java","testData/refactoring/typeCook/t127/after/test.java","testData/refactoring/typeCook/t127/before/test.java","testData/refactoring/typeCook/t128/after/test.java","testData/refactoring/typeCook/t128/before/test.java","testData/refactoring/typeCook/t129/after/test.java","testData/refactoring/typeCook/t129/before/test.java","testData/refactoring/typeCook/t13/after/test.java","testData/refactoring/typeCook/t13/before/test.java","testData/refactoring/typeCook/t130/after/test.java","testData/refactoring/typeCook/t130/before/test.java","testData/refactoring/typeCook/t131/after/test.java","testData/refactoring/typeCook/t131/before/test.java","testData/refactoring/typeCook/t132/after/test.java","testData/refactoring/typeCook/t132/before/test.java","testData/refactoring/typeCook/t133/after/test.java","testData/refactoring/typeCook/t133/before/test.java","testData/refactoring/typeCook/t134/after/test.java","testData/refactoring/typeCook/t134/before/test.java","testData/refactoring/typeCook/t135/after/test.java","testData/refactoring/typeCook/t135/before/test.java","testData/refactoring/typeCook/t136/after/test.java","testData/refactoring/typeCook/t136/before/test.java","testData/refactoring/typeCook/t137/after/test.java","testData/refactoring/typeCook/t137/before/test.java","testData/refactoring/typeCook/t138/after/test.java","testData/refactoring/typeCook/t138/before/test.java","testData/refactoring/typeCook/t139/after/test.java","testData/refactoring/typeCook/t139/before/test.java","testData/refactoring/typeCook/t14/after/test.java","testData/refactoring/typeCook/t14/before/test.java","testData/refactoring/typeCook/t140/after/test.java","testData/refactoring/typeCook/t140/before/test.java","testData/refactoring/typeCook/t141/before/test.java","testData/refactoring/typeCook/t142/before/test.java","testData/refactoring/typeCook/t143/before/test.java","testData/refactoring/typeCook/t144/before/test.java","testData/refactoring/typeCook/t145/before/test.java","testData/refactoring/typeCook/t15/after/test.java","testData/refactoring/typeCook/t15/before/test.java","testData/refactoring/typeCook/t16/after/test.java","testData/refactoring/typeCook/t16/before/test.java","testData/refactoring/typeCook/t17/after/test.java","testData/refactoring/typeCook/t17/before/test.java","testData/refactoring/typeCook/t18/after/test.java","testData/refactoring/typeCook/t18/before/test.java","testData/refactoring/typeCook/t19/after/test.java","testData/refactoring/typeCook/t19/before/test.java","testData/refactoring/typeCook/t20/after/test.java","testData/refactoring/typeCook/t20/before/test.java","testData/refactoring/typeCook/t21/after/test.java","testData/refactoring/typeCook/t21/before/test.java","testData/refactoring/typeCook/t22/after/test.java","testData/refactoring/typeCook/t22/before/test.java","testData/refactoring/typeCook/t23/after/test.java","testData/refactoring/typeCook/t23/before/test.java","testData/refactoring/typeCook/t24/after/test.java","testData/refactoring/typeCook/t24/before/test.java","testData/refactoring/typeCook/t25/after/test.java","testData/refactoring/typeCook/t25/before/test.java","testData/refactoring/typeCook/t26/after/test.java","testData/refactoring/typeCook/t26/before/test.java","testData/refactoring/typeCook/t27/after/test.java","testData/refactoring/typeCook/t27/before/test.java","testData/refactoring/typeCook/t28/after/test.java","testData/refactoring/typeCook/t28/before/test.java","testData/refactoring/typeCook/t29/after/test.java","testData/refactoring/typeCook/t29/before/test.java","testData/refactoring/typeCook/t30/after/test.java","testData/refactoring/typeCook/t30/before/test.java","testData/refactoring/typeCook/t31/after/test.java","testData/refactoring/typeCook/t31/before/test.java","testData/refactoring/typeCook/t32/after/test.java","testData/refactoring/typeCook/t32/before/test.java","testData/refactoring/typeCook/t33/after/test.java","testData/refactoring/typeCook/t33/before/test.java","testData/refactoring/typeCook/t34/after/test.java","testData/refactoring/typeCook/t34/before/test.java","testData/refactoring/typeCook/t35/after/test.java","testData/refactoring/typeCook/t35/before/test.java","testData/refactoring/typeCook/t36/after/test.java","testData/refactoring/typeCook/t36/before/test.java","testData/refactoring/typeCook/t37/after/test.java","testData/refactoring/typeCook/t37/before/test.java","testData/refactoring/typeCook/t38/after/test.java","testData/refactoring/typeCook/t38/before/test.java","testData/refactoring/typeCook/t39/after/test.java","testData/refactoring/typeCook/t39/before/test.java","testData/refactoring/typeCook/t40/after/test.java","testData/refactoring/typeCook/t40/before/test.java","testData/refactoring/typeCook/t41/after/test.java","testData/refactoring/typeCook/t41/before/test.java","testData/refactoring/typeCook/t42/after/test.java","testData/refactoring/typeCook/t42/before/test.java","testData/refactoring/typeCook/t43/after/test.java","testData/refactoring/typeCook/t43/before/test.java","testData/refactoring/typeCook/t44/after/test.java","testData/refactoring/typeCook/t44/before/test.java","testData/refactoring/typeCook/t45/after/test.java","testData/refactoring/typeCook/t45/before/test.java","testData/refactoring/typeCook/t46/after/test.java","testData/refactoring/typeCook/t46/before/test.java","testData/refactoring/typeCook/t47/after/test.java","testData/refactoring/typeCook/t47/before/test.java","testData/refactoring/typeCook/t48/after/test.java","testData/refactoring/typeCook/t48/before/test.java","testData/refactoring/typeCook/t49/after/test.java","testData/refactoring/typeCook/t49/before/test.java","testData/refactoring/typeCook/t50/after/test.java","testData/refactoring/typeCook/t50/before/test.java","testData/refactoring/typeCook/t51/after/test.java","testData/refactoring/typeCook/t51/before/test.java","testData/refactoring/typeCook/t52/after/test.java","testData/refactoring/typeCook/t52/before/test.java","testData/refactoring/typeCook/t53/after/test.java","testData/refactoring/typeCook/t53/before/test.java","testData/refactoring/typeCook/t54/after/test.java","testData/refactoring/typeCook/t54/before/test.java","testData/refactoring/typeCook/t55/after/test.java","testData/refactoring/typeCook/t55/before/test.java","testData/refactoring/typeCook/t56/after/test.java","testData/refactoring/typeCook/t56/before/test.java","testData/refactoring/typeCook/t57/after/test.java","testData/refactoring/typeCook/t57/before/test.java","testData/refactoring/typeCook/t58/after/test.java","testData/refactoring/typeCook/t58/before/test.java","testData/refactoring/typeCook/t59/after/test.java","testData/refactoring/typeCook/t59/before/test.java","testData/refactoring/typeCook/t60/after/test.java","testData/refactoring/typeCook/t60/before/test.java","testData/refactoring/typeCook/t61/after/test.java","testData/refactoring/typeCook/t61/before/test.java","testData/refactoring/typeCook/t62/after/test.java","testData/refactoring/typeCook/t62/before/test.java","testData/refactoring/typeCook/t63/after/test.java","testData/refactoring/typeCook/t63/before/test.java","testData/refactoring/typeCook/t64/after/test.java","testData/refactoring/typeCook/t64/before/test.java","testData/refactoring/typeCook/t65/after/test.java","testData/refactoring/typeCook/t65/before/test.java","testData/refactoring/typeCook/t66/after/test.java","testData/refactoring/typeCook/t66/before/test.java","testData/refactoring/typeCook/t67/after/test.java","testData/refactoring/typeCook/t67/before/test.java","testData/refactoring/typeCook/t68/after/test.java","testData/refactoring/typeCook/t68/before/test.java","testData/refactoring/typeCook/t69/after/test.java","testData/refactoring/typeCook/t69/before/test.java","testData/refactoring/typeCook/t70/after/test.java","testData/refactoring/typeCook/t70/before/test.java","testData/refactoring/typeCook/t71/after/test.java","testData/refactoring/typeCook/t71/before/test.java","testData/refactoring/typeCook/t72/after/test.java","testData/refactoring/typeCook/t72/before/test.java","testData/refactoring/typeCook/t73/after/test.java","testData/refactoring/typeCook/t73/before/test.java","testData/refactoring/typeCook/t74/after/test.java","testData/refactoring/typeCook/t74/before/test.java","testData/refactoring/typeCook/t75/after/test.java","testData/refactoring/typeCook/t75/before/test.java","testData/refactoring/typeCook/t76/after/test.java","testData/refactoring/typeCook/t76/before/test.java","testData/refactoring/typeCook/t77/after/test.java","testData/refactoring/typeCook/t77/before/test.java","testData/refactoring/typeCook/t78/after/test.java","testData/refactoring/typeCook/t78/before/test.java","testData/refactoring/typeCook/t79/after/test.java","testData/refactoring/typeCook/t79/before/test.java","testData/refactoring/typeCook/t80/after/test.java","testData/refactoring/typeCook/t80/before/test.java","testData/refactoring/typeCook/t81/after/test.java","testData/refactoring/typeCook/t81/before/test.java","testData/refactoring/typeCook/t82/after/test.java","testData/refactoring/typeCook/t82/before/test.java","testData/refactoring/typeCook/t83/after/test.java","testData/refactoring/typeCook/t83/before/test.java","testData/refactoring/typeCook/t84/after/test.java","testData/refactoring/typeCook/t84/before/test.java","testData/refactoring/typeCook/t85/after/test.java","testData/refactoring/typeCook/t85/before/test.java","testData/refactoring/typeCook/t86/after/test.java","testData/refactoring/typeCook/t86/before/test.java","testData/refactoring/typeCook/t87/after/test.java","testData/refactoring/typeCook/t87/before/test.java","testData/refactoring/typeCook/t88/after/test.java","testData/refactoring/typeCook/t88/before/test.java","testData/refactoring/typeCook/t89/after/test.java","testData/refactoring/typeCook/t89/before/test.java","testData/refactoring/typeCook/t90/after/test.java","testData/refactoring/typeCook/t90/before/test.java","testData/refactoring/typeCook/t91/after/test.java","testData/refactoring/typeCook/t91/before/test.java","testData/refactoring/typeCook/t92/after/test.java","testData/refactoring/typeCook/t92/before/test.java","testData/refactoring/typeCook/t93/after/test.java","testData/refactoring/typeCook/t93/before/test.java","testData/refactoring/typeCook/t94/after/test.java","testData/refactoring/typeCook/t94/before/test.java","testData/refactoring/typeCook/t95/after/test.java","testData/refactoring/typeCook/t95/before/test.java","testData/refactoring/typeCook/t96/after/test.java","testData/refactoring/typeCook/t96/before/test.java","testData/refactoring/typeCook/t97/after/test.java","testData/refactoring/typeCook/t97/before/test.java","testData/refactoring/typeCook/t98/after/test.java","testData/refactoring/typeCook/t98/before/test.java","testData/refactoring/typeCook/t99/after/test.java","testData/refactoring/typeCook/t99/before/test.java","testSource/AllTests.java","testSource/com/intellij/ClassFinder.java","testSource/com/intellij/TestAll.java","testSource/com/intellij/TestCaseLoader.java","testSource/com/intellij/TestClassesFilter.java","testSource/com/intellij/codeInsight/CodeInsightTestCase.java","testSource/com/intellij/codeInsight/CodeInsightTestData.java","testSource/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java","testSource/com/intellij/codeInsight/daemon/ExpectedHighlightingData.java","testSource/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java","testSource/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java","testSource/com/intellij/codeInspection/CanBeFinalTest.java","testSource/com/intellij/codeInspection/DataFlowTest.java","testSource/com/intellij/codeInspection/DefUseTest.java","testSource/com/intellij/codeInspection/EmptyMethodTest.java","testSource/com/intellij/codeInspection/LocalCanBeFinalTest.java","testSource/com/intellij/codeInspection/RedundantThrowTest.java","testSource/com/intellij/codeInspection/VisibilityInspectionTest.java","testSource/com/intellij/dependencies/DependenciesPanelTest.java","testSource/com/intellij/find/findUsages/FindParameterTest.java","testSource/com/intellij/idea/LockSupportTest.java","testSource/com/intellij/localVcs/MockAbstractVcs.java","testSource/com/intellij/mock/MockApplication.java","testSource/com/intellij/mock/MockDocument.java","testSource/com/intellij/mock/MockEditorEventMulticaster.java","testSource/com/intellij/mock/MockEditorFactory.java","testSource/com/intellij/mock/MockFileSystem.java","testSource/com/intellij/mock/MockProgressInidicator.java","testSource/com/intellij/mock/MockProject.java","testSource/com/intellij/mock/MockPsiManager.java","testSource/com/intellij/mock/MockVirtualFileManager.java","testSource/com/intellij/openapi/execution/ParametersListTest.java","testSource/com/intellij/openapi/roots/ui/TempFiles.java","testSource/com/intellij/openapi/ui/SplitterTest.java","testSource/com/intellij/openapi/vcs/ui/exclude/SortedListModelTest.java","testSource/com/intellij/projectView/BaseProjectViewTestCase.java","testSource/com/intellij/projectView/FormMergerTreeStructureProviderTest.java","testSource/com/intellij/projectView/TestProjectTreeStructure.java","testSource/com/intellij/psi/AddClassToFileTest.java","testSource/com/intellij/psi/AddRemoveInTypeParameterListTest.java","testSource/com/intellij/psi/ArrayIndexOutOfBoundsTest.java","testSource/com/intellij/psi/CodeFragmentsTest.java","testSource/com/intellij/psi/ConstantValuesTest.java","testSource/com/intellij/psi/NormalizeDeclarationTest.java","testSource/com/intellij/psi/OverlappingSourceRootsTest.java","testSource/com/intellij/psi/ParsingTestCase.java","testSource/com/intellij/refactoring/ChangeSignatureTest.java","testSource/com/intellij/refactoring/ExtractMethodTest.java","testSource/com/intellij/refactoring/InheritanceToDelegationTest.java","testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java","testSource/com/intellij/refactoring/IntroduceParameterTest.java","testSource/com/intellij/refactoring/MakeMethodStaticTest.java","testSource/com/intellij/refactoring/MockInlineMethodOptions.java","testSource/com/intellij/refactoring/MockIntroduceFieldHandler.java","testSource/com/intellij/refactoring/MoveClassTest.java","testSource/com/intellij/refactoring/MoveInnerTest.java","testSource/com/intellij/refactoring/MoveMembersTest.java","testSource/com/intellij/refactoring/MovePackageMultirootTest.java","testSource/com/intellij/refactoring/MovePackageTest.java","testSource/com/intellij/refactoring/MultiFileTestCase.java","testSource/com/intellij/refactoring/RenameClassTest.java","testSource/com/intellij/refactoring/RenameFieldsTest.java","testSource/com/intellij/refactoring/RenameMethodMultiTest.java","testSource/com/intellij/refactoring/ReplaceConstructorWithFactoryTest.java","testSource/com/intellij/refactoring/TurnRefsToSuperTest.java","testSource/com/intellij/refactoring/TypeCookTest.java","testSource/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java","testSource/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodTest.java","testSource/com/intellij/refactoring/inline/InlineLocalTest.java","testSource/com/intellij/refactoring/inline/InlineMethodTest.java","testSource/com/intellij/refactoring/migration/MigrationTest.java","testSource/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java","testSource/com/intellij/refactoring/rename/naming/NameSuggesterTest.java","testSource/com/intellij/ui/BasicTreeModel.java","testSource/com/intellij/ui/TreeExpandCollapseTest.java","testSource/com/intellij/uiDesigner/TestGridChangeUtil.java","testSource/com/intellij/uiDesigner/TestTextDiffer.java","testSource/com/intellij/util/DateFormatUtilTest.java","testSource/com/intellij/util/IJSwingUtilitiesTest.java","testSource/com/intellij/util/UniqueFileNamesProviderTest.java","testSource/com/intellij/util/XMLOutputterTest.java","testSource/com/intellij/util/config/ExternalizablePropertyTest.java","testSource/com/intellij/util/diff/DiffTest.java","testSource/com/intellij/util/graph/DFSTBuilderTest.java","testSource/com/intellij/util/graph/GraphGeneratorTest.java","testSource/com/intellij/util/graph/GraphTestUtil.java","testSource/com/intellij/util/graph/TestNode.java","testSource/com/intellij/util/text/StringSearcherTest.java","testSource/com/intellij/util/ui/tree/TreeUtilTest.java","util/src/com/intellij/Patches.java","util/src/com/intellij/openapi/application/RuntimeInterruptedException.java","util/src/com/intellij/openapi/diagnostic/ApplicationInfoProvider.java","util/src/com/intellij/openapi/diagnostic/DefaultLogger.java","util/src/com/intellij/openapi/diagnostic/Logger.java","util/src/com/intellij/openapi/util/Comparing.java","util/src/com/intellij/openapi/util/Computable.java","util/src/com/intellij/openapi/util/Condition.java","util/src/com/intellij/openapi/util/DefaultJDOMExternalizer.java","util/src/com/intellij/openapi/util/EmptyRunnable.java","util/src/com/intellij/openapi/util/Factory.java","util/src/com/intellij/openapi/util/InvalidDataException.java","util/src/com/intellij/openapi/util/JDOMExternalizable.java","util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java","util/src/com/intellij/openapi/util/JDOMExternalizer.java","util/src/com/intellij/openapi/util/JDOMExternalizerUtil.java","util/src/com/intellij/openapi/util/JDOMUtil.java","util/src/com/intellij/openapi/util/Key.java","util/src/com/intellij/openapi/util/MultiValuesMap.java","util/src/com/intellij/openapi/util/NamedJDOMExternalizable.java","util/src/com/intellij/openapi/util/Pair.java","util/src/com/intellij/openapi/util/Ref.java","util/src/com/intellij/openapi/util/ShutDownTracker.java","util/src/com/intellij/openapi/util/SystemInfo.java","util/src/com/intellij/openapi/util/TextRange.java","util/src/com/intellij/openapi/util/UserDataHolder.java","util/src/com/intellij/openapi/util/UserDataHolderBase.java","util/src/com/intellij/openapi/util/WriteExternalException.java","util/src/com/intellij/openapi/util/io/FileUtil.java","util/src/com/intellij/openapi/util/text/LineTokenizer.java","util/src/com/intellij/openapi/util/text/StringUtil.java","util/src/com/intellij/ui/SmartExpander.java","util/src/com/intellij/ui/TableUtil.java","util/src/com/intellij/util/ArrayUtil.java","util/src/com/intellij/util/BooleanValueHolder.java","util/src/com/intellij/util/CodeWriter.java","util/src/com/intellij/util/EventUtil.java","util/src/com/intellij/util/ImageLoader.java","util/src/com/intellij/util/IncorrectOperationException.java","util/src/com/intellij/util/ListWithSelection.java","util/src/com/intellij/util/LocalTimeCounter.java","util/src/com/intellij/util/NewInstanceFactory.java","util/src/com/intellij/util/PatchedSoftReference.java","util/src/com/intellij/util/PatchedWeakReference.java","util/src/com/intellij/util/PatternUtil.java","util/src/com/intellij/util/SmartList.java","util/src/com/intellij/util/TreeItem.java","util/src/com/intellij/util/UniqueFileNamesProvider.java","util/src/com/intellij/util/Validateable.java","util/src/com/intellij/util/ValidateableReference.java","util/src/com/intellij/util/WeakPropertyChangeAdapter.java","util/src/com/intellij/util/cls/BytePointer.java","util/src/com/intellij/util/cls/ClsFormatException.java","util/src/com/intellij/util/cls/ClsUtil.java","util/src/com/intellij/util/containers/ArrayListSet.java","util/src/com/intellij/util/containers/BidirectionalMap.java","util/src/com/intellij/util/containers/CoModifiableList.java","util/src/com/intellij/util/containers/CollectUtil.java","util/src/com/intellij/util/containers/ComparatorUtil.java","util/src/com/intellij/util/containers/ContainerUtil.java","util/src/com/intellij/util/containers/ConvertingIterator.java","util/src/com/intellij/util/containers/Convertor.java","util/src/com/intellij/util/containers/DoubleArrayList.java","util/src/com/intellij/util/containers/EmptyIterator.java","util/src/com/intellij/util/containers/Enumerator.java","util/src/com/intellij/util/containers/FilteringIterator.java","util/src/com/intellij/util/containers/HashMap.java","util/src/com/intellij/util/containers/HashSet.java","util/src/com/intellij/util/containers/HugeArray.java","util/src/com/intellij/util/containers/IntArrayList.java","util/src/com/intellij/util/containers/InternalIterator.java","util/src/com/intellij/util/containers/LongArrayList.java","util/src/com/intellij/util/containers/OrderedSet.java","util/src/com/intellij/util/containers/Queue.java","util/src/com/intellij/util/containers/SequenceIterator.java","util/src/com/intellij/util/containers/SoftHashMap.java","util/src/com/intellij/util/containers/SoftValueHashMap.java","util/src/com/intellij/util/containers/VariableWidthIntArray.java","util/src/com/intellij/util/containers/WeakHashMap.java","util/src/com/intellij/util/containers/WeakList.java","util/src/com/intellij/util/containers/WeakReferenceArray.java","util/src/com/intellij/util/containers/WeakValueHashMap.java","util/src/com/intellij/util/diff/Diff.java","util/src/com/intellij/util/diff/IntLCS.java","util/src/com/intellij/util/diff/LCSBuilder.java","util/src/com/intellij/util/diff/LinkedDiffPaths.java","util/src/com/intellij/util/diff/Reindexer.java","util/src/com/intellij/util/enumeration/ArrayEnumeration.java","util/src/com/intellij/util/enumeration/ArrayListEnumeration.java","util/src/com/intellij/util/enumeration/DoubleEnumeration.java","util/src/com/intellij/util/enumeration/EmptyEnumeration.java","util/src/com/intellij/util/enumeration/EnumerationCopy.java","util/src/com/intellij/util/enumeration/LightEnumeration.java","util/src/com/intellij/util/enumeration/LightEnumerationAdapter.java","util/src/com/intellij/util/enumeration/SequenceEnumeration.java","util/src/com/intellij/util/enumeration/SingleEnumeration.java","util/src/com/intellij/util/exception/RootException.java","util/src/com/intellij/util/exception/RootRuntimeException.java","util/src/com/intellij/util/graph/CachingSemiGraph.java","util/src/com/intellij/util/graph/DFSTBuilder.java","util/src/com/intellij/util/graph/Graph.java","util/src/com/intellij/util/graph/GraphGenerator.java","util/src/com/intellij/util/io/IOUtil.java","util/src/com/intellij/util/io/ZipUtil.java","util/src/com/intellij/util/text/CharArrayCharSequence.java","util/src/com/intellij/util/text/CharArrayUtil.java","util/src/com/intellij/util/text/CloneableTokenizer.java","util/src/com/intellij/util/text/DateFormatUtil.java","util/src/com/intellij/util/text/LineReader.java","util/src/com/intellij/util/text/MergingCharSequence.java","util/src/com/intellij/util/text/StringSearcher.java","util/src/com/intellij/util/text/StringTokenizer.java","util/src/com/intellij/util/ui/AbstractTableCellEditor.java","util/src/com/intellij/util/ui/ColumnInfo.java","util/src/com/intellij/util/ui/ComboBoxTableCellEditor.java","util/src/com/intellij/util/ui/ComboBoxTableCellRenderer.java","util/src/com/intellij/util/ui/IdeaUIManager.java","util/src/com/intellij/util/ui/ItemRemovable.java","util/src/com/intellij/util/ui/LabelWithTooltip.java","util/src/com/intellij/util/ui/ListTableModel.java","util/src/com/intellij/util/ui/SortableColumnModel.java","util/src/com/intellij/util/ui/Table.java","util/src/com/intellij/util/ui/TableViewModel.java","util/src/com/intellij/util/ui/Tree.java","util/src/com/intellij/util/ui/treetable/ListTreeTableModel.java","util/src/com/intellij/util/ui/treetable/ListTreeTableModelOnColumns.java","util/src/com/intellij/util/ui/treetable/TreeTable.java","util/src/com/intellij/util/ui/treetable/TreeTableCellEditor.java","util/src/com/intellij/util/ui/treetable/TreeTableCellRenderer.java","util/src/com/intellij/util/ui/treetable/TreeTableModel.java","util/src/com/intellij/util/ui/treetable/TreeTableModelAdapter.java","util/src/com/intellij/util/ui/treetable/TreeTableTree.java","util/testSource/com/intellij/openapi/util/TextRangeTest.java","util/testSource/com/intellij/util/Assertion.java","util/testSource/com/intellij/util/StringConvertion.java","util/testSource/com/intellij/util/containers/CoModifiableListTest.java","util/testSource/com/intellij/util/containers/ContainerUtilTest.java","util/testSource/com/intellij/util/containers/EnumeratorTest.java","util/testSource/com/intellij/util/containers/FilteringIteratorTest.java","util/testSource/com/intellij/util/containers/HugeArrayTest.java","util/testSource/com/intellij/util/containers/QueueTest.java","util/testSource/com/intellij/util/containers/SequenceIteratorTest.java","util/testSource/com/intellij/util/containers/TObjectIntHashMapTest.java","util/testSource/com/intellij/util/containers/WeakListTest.java","util/testSource/com/intellij/util/containers/WeakReferenceArrayTest.java","util/testSource/com/intellij/util/containers/WeaksTestCase.java","util/testSource/com/intellij/util/diff/IntLCSTest.java","util/testSource/com/intellij/util/diff/LinkedDiffPathsTest.java","util/testSource/com/intellij/util/diff/ReindexerTest.java"],"renamedFilesHint":{},"repositoryDirectoriesBefore":[],"repositoryDirectoriesCurrent":["testData/refactoring/movePackageMultiroot/movePackage/before","testSource/com/intellij/util","testData/refactoring/moveMembers/twoMethods/after","source/com/intellij/openapi/editor/markup","testData/refactoring/renameMethod/multi/staticImport1/before/pack1","source/com/intellij/codeInsight/guess/impl","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/impord","testData/refactoring/renameMethod/multi/staticImport1/before/pack2","testData/refactoring/typeCook/t50/after","source/com/intellij/openapi/roots/ui/configuration/libraryEditor","testData/refactoring/inheritanceToDelegation/subClass/after","source/com/intellij/openapi/ui","source/com/intellij/openapi/fileTypes/impl","source/com/intellij/refactoring/changeClassSignature","openapi/src/com/intellij/openapi/localVcs","testData/refactoring/inheritanceToDelegation/getter","source/com/intellij/openapi/roots/ex","testData/refactoring/moveClass/localClass/before/pack1","testData/projectView/standardProviders","source/com/intellij/refactoring/typeCook/deductive/util","util","testData/refactoring/turnRefsToSuper/arrayElementAssignment/before","source/com/intellij/psi/impl/meta","testData/inspection/dataFlow/SCR15406/src","testData/inspection/localCanBeFinal/SCR7428/src","openapi/src/com/intellij/openapi/fileEditor","testSource/com/intellij/util/graph","source/com/intellij/psi/impl/source/resolve/reference/impl/providers","source/com/intellij/codeInsight/editorActions","source/com/intellij/ide/util/treeView","source/com/intellij/execution/filters","testData/refactoring/moveMembers/innerClass/after","testData/refactoring/typeCook/t55/after","openapi/src/com/intellij/openapi/fileTypes","source/com/intellij/ide/structureView/impl/xml","testData/refactoring/inheritanceToDelegation/overridenMethods/before","testData/refactoring/typeCook/t134/after","doc/openapi/examples/plugin/src/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/cvshandlers","testData/refactoring/turnRefsToSuper/returnValue2/before","testData/refactoring/inheritanceToDelegation/innerClass","openapi/src/com/intellij/openapi/editor/colors","source/com/intellij/openapi/wm","source/com/intellij/openapi/projectRoots","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate/ui","openapi/src/com/intellij/find","source/com/intellij/openapi/vcs/history","source/com/intellij/openapi/progress","source/com/intellij/codeInsight/folding/impl/actions","plugins/conditionalOperatorConvertor","testData/refactoring/turnRefsToSuper/scr34020/before","testData/refactoring/typeCook/t09/before","testData/refactoring/turnRefsToSuper/classUsage/before","source/com/intellij/codeInspection/util","openapi/src/com/intellij/psi/jsp","testData/refactoring/inheritanceToDelegation/subClassNoMethods/after","testData/refactoring/movePackage","testData/refactoring/turnRefsToSuper/removeImport/before","testData/refactoring/typeCook/t34/after","testData/inspection/dataFlow/SCR13626/src","UIDesignerCore/testSource/com/intellij/uiDesigner/core","source/com/intellij/codeInsight/hint","runtimesource/com/intellij/rt/execution/junit2","UsageView/src/com","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser/ui","source/com/intellij/uiDesigner/propertyInspector/editors","util/src/com/intellij/util/cls","testSource/com","testData/refactoring/typeCook/t71/after","source/com/intellij/ide/projectView/impl","testData/refactoring/turnRefsToSuper/fieldTest/after","source/com/intellij/diff","source/com/intellij/refactoring/introduceField","source/com/intellij/psi/impl/source/resolve","testData/inspection/defUse/SCR5144","testData/refactoring/typeCook/t39/before","openapi/src/com/intellij/openapi/help","openapi/src/com/intellij/psi/search","testData/refactoring/renameClass/innerClass","testData/refactoring/migration/toNonExistentClass/after","testData/psi/arrayIndexOutOfBounds","source/com/intellij/refactoring/typeCook","source/com/intellij/psi/impl/light","testData/refactoring/moveMembers/javadocRefs/before","source/com/intellij/refactoring/move/moveMembers","testData/refactoring/typeCook/t09/after","openapi/src/com/intellij/psi/tree/java","testData/refactoring/migration/package/before/p1","testData/refactoring/typeCook/t92/after","testData/refactoring/migration/packageToNonExistentPackage/after","source/com/intellij/psi/statistics","testData/refactoring/typeCook/t104/after","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/tag","testData/refactoring/moveMembers/innerClass/before","source/com/intellij/j2ee/module","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/annotate","testData/refactoring/typeCook/t13/after","source/com/intellij/refactoring","testData/inspection/dataFlow/nullableField/src","source/com/intellij/refactoring/typeCook/deductive","source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators","testData/inspection/canBeFinal/fields","source/com/intellij/psi/impl/source/jsp/tagLibrary","source/com/intellij/featureStatistics","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAnnotate","pom/src/com/intellij/pom","source/com/intellij/refactoring/listeners/impl/impl","source/com/intellij/codeInsight/actions","testData/inspection/canBeFinal/fieldAndTryBlock","testData/refactoring/typeCook/t80/after","testData/refactoring/typeCook/t130/before","testSource/com/intellij/openapi/execution","source/com/intellij/debugger/ui/impl","source/com/intellij/ide/hierarchy/method","source/com/intellij/psi/impl/source/parsing/xml","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut","plugins/cvs2/source","testData/refactoring/typeCook/t20/after","forms_rt/src/com/intellij/uiDesigner","openapi/src/com/intellij/pom/java","openapi/src/com/intellij/ide/util/treeView/smartTree","testData/refactoring/typeCook/t69/before","UsageView/testSource","util/src/com/intellij/util/ui","util/src","testData/refactoring/renameMethod/multi","testData/inspection/dataFlow/SCR13871","testData/refactoring/typeCook/t18/after","testData/refactoring/renameClass/innerClass/before/pack1","plugins/conditionalOperatorConvertor/source","source/com/intellij/debugger/settings","source/com/intellij/codeInsight/completion/actions","testData/inspection/defUse","source/com/intellij/refactoring/util","source/com/intellij/refactoring/inheritanceToDelegation/usageInfo","source/com/intellij/codeInsight/intention/actions","openapi/src/com/intellij/ui","openapi/src/com/intellij/openapi/vcs/update","source/com/intellij/ui/errorView/impl","testSource/com/intellij/openapi","source/com/intellij/execution/junit2/ui/actions","testData/inspection/canBeFinal/SCR6073/src","testData/refactoring/typeCook/t70/before","source/com/intellij/codeInsight/template","testData/refactoring/typeCook/t85/after","testData/inspection/defUse/SCR28019/src","source/com/intellij/debugger/engine/requests","source/com/intellij/ide/fileTemplates/actions","source/com/intellij/codeInspection/export","testData/refactoring/migration/packageToNonExistentPackage/before","testData/refactoring/typeCook/t129/before","testData/refactoring/movePackage/insidePackage/before/a","testData/refactoring/typeCook/t118/before","source/com/intellij/ide/util/scopeChooser","doc/openapi/examples/actions","testData/refactoring/inheritanceToDelegation/interfaceDelegation/after","testData/inspection/visibility/SCR11792/src","UsageView/testSource/com/intellij/usages/impl","testData/inspection/visibility/packageLevelTops/src","testData/refactoring/migration/unexistingClassInUnexistingPackage/after","testSource/com/intellij/openapi/vcs/ui/exclude","source/com/intellij/ide/util/projectWizard","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/sending","source/com/intellij/openapi/roots/ui/configuration/actions","testData/refactoring/typeCook/t81/before","source/com/intellij/codeInsight","testData/refactoring/renameMethod/multi/staticImport3/before/pack2","testData/refactoring/moveMembers/scr11871","testData/refactoring/typeCook/t139/after","source/com/intellij/internal/diGraph/impl","testData/refactoring/renameMethod/multi/staticImport3/before/pack1","testData/inspection/localCanBeFinal/SCR7428_1/src","openapi/src/com/intellij/openapi/wm","testData/refactoring/moveClass/jsp","testData/refactoring/turnRefsToSuper/fieldTest","source/com/intellij/psi/impl/file","testData/refactoring/moveClass/contextChange1/after","testData/refactoring/renameClass/nonJava/after/pack1","util/src/com/intellij/util/text","source/com/intellij/openapi/roots/ui/componentsList/components","source/com/intellij/ide/util/gotoByName","testData/refactoring/turnRefsToSuper/cast","source/com/intellij/errorreport","testData/inspection/dataFlow/nullableField","source/com/intellij/codeInspection/equalsAndHashcode","openapi/src/com/intellij/ide/util/projectWizard","source/com/intellij/xml","source/com/intellij/codeInsight/lookup/impl","source/com/intellij/codeInsight/navigation/actions","testData/refactoring/typeCook/t141/before","testData/refactoring/typeCook/t25/after","testData/dependencies/dependencies","testData/refactoring/typeCook/t76/after","source/com/intellij/util/text","testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1","source/com/intellij/usageView","source/com/intellij/openapi/fileEditor/impl/text","source/com/intellij/uiDesigner/editor","testData/inspection/dataFlow/inst","openapi/src/com/intellij/openapi/util","testData/refactoring/typeCook/t10/before","source/com/intellij/openapi/wm/impl","testData/inspection/canBeFinal/simpleClassInheritance1/src","plugins/comparingReferences/source","UIDesignerCore/testSource/com/intellij","source/com/intellij/ui/plaf","source/com/intellij/uiDesigner","source/com/intellij/psi/impl/cache/impl/idCache","testData/refactoring/typeCook/t137/before","testData/inspection/dataFlow/caseAndNpe","source/com/intellij/errorreport/bean","UsageView/testSource/com/intellij","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision","source/com/intellij/refactoring/safeDelete","testData/inspection/localCanBeFinal/SCR11757","testData/refactoring/typeCook/t66/before","testData/refactoring/typeCook/t96/before","source/com/intellij/uiDesigner/propertyInspector/properties","testData/refactoring/typeCook/t122/after","testData/refactoring/moveInner/scr15142","testData/refactoring/typeCook/t83/after","source/com/intellij/codeInsight/daemon/impl/actions","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2","source/com/intellij/psi/scope/processor","util/testSource/com/intellij/openapi","source/com/intellij/psi/impl/file/impl","testData/refactoring/typeCook/t22/after","testData/refactoring/moveClass/nonJava/after/pack2","openapi/src/com/intellij/openapi/compiler","testData/inspection/canBeFinal/SCR6861/src","source/com/intellij/j2ee/openapi/impl","pom","testData/refactoring/typeCook/t126/before","source/com/intellij/openapi/keymap/impl/ui","source/com/intellij/codeInsight/generation/surroundWith","testData/refactoring/typeCook/t101/after","testData/refactoring/convertToInstanceMethod","plugins/cvs2/source/com","source/com/intellij/psi/scope/conflictResolvers","openapi/src/com/intellij/openapi/ui","source/com/intellij/openapi/roots/impl/libraries","source/com/intellij/codeInspection/redundantCast","source/com/intellij/openapi/keymap/ex","testData/refactoring/movePackageMultiroot/movePackage/after/src1/target","openapi/src/com/intellij/codeInsight/highlighting","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before","source/com/intellij/codeInspection/localCanBeFinal","source/com/intellij/codeInsight/daemon/impl/quickfix","UIDesignerCore/src/com/intellij/uiDesigner/lw","testData/refactoring/typeCook/t115/before","testData/refactoring/typeCook/t37/after","testData/refactoring/typeCook/t109","source","testData/refactoring/turnRefsToSuper/arrayElementAssignment","testData/refactoring/typeCook/t108","testData/inspection/defUse/unusedVariable","testData/refactoring/moveMembers/scr40064/before","testData/refactoring/typeCook/t103","testData/refactoring/typeCook/t102","testData/refactoring/typeCook/t106/after","testData/refactoring/typeCook/t101","testData/refactoring/typeCook/t100","testData/refactoring/typeCook/t107","testData/refactoring/moveInner/scr15142/after","testData/refactoring/typeCook/t106","testData/refactoring/typeCook/t44/before","source/com/intellij/codeInspection/defUse","testData/refactoring/typeCook/t105","testData/refactoring/typeCook/t104","openapi/src/com/intellij/j2ee/j2eeDom","util/testSource/com/intellij/util/diff","source/com/intellij/ide/bookmarks","openapi/src/com/intellij/openapi/project","testData/refactoring/moveInner/nonJavaFiles/before","plugins/cvs2/source/com/intellij/cvsSupport2/application","openapi/src/com/intellij/execution/filters","testData/refactoring/typeCook/t85/before","source/com/intellij/codeInsight/intention/impl","testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2","testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1","testData/refactoring/moveInner/scr30106/after","testData/refactoring/migration/packageToNonExistentPackage","openapi/src/com/intellij/psi/infos","source/com/intellij/xml/impl/dtd","source/com/intellij/ide/actionMacro","testSource/com/intellij/psi","pom/src/com","testData/refactoring/moveInner/scr13730/before/pack1","testData/refactoring/turnRefsToSuper/commonInheritor","testData/refactoring/typeCook/t33/before","testData/refactoring/moveClass/stringsAndComments2/before","testData/refactoring/typeCook/t55/before","testData/refactoring/typeCook/t145/before","testData/inspection/redundantThrow/SCR14543","source/com/intellij/util/net","testData/refactoring/typeCook/t88/before","source/com/intellij/openapi/roots/watcher/impl","testData/refactoring/typeCook/t77/before","testData/refactoring/typeCook/t88/after","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command/admin","testData/refactoring/typeCook/t127/after","testData/refactoring/typeCook/t99/before","UsageView/src/com/intellij/usages/actions","source/com/intellij/codeInspection/deprecation","testData/inspection/localCanBeFinal/multiWriteNoRead/src","testData/refactoring/turnRefsToSuper/scr34020/after","testData/refactoring/moveClass/contextChange2/before","testData/refactoring/typeCook/t24/before","testData/inspection/localCanBeFinal/SCR6744_6/src/foo","doc/openapi","source/com/intellij/openapi/wm/ex","openapi/src/com/intellij/ide/util/treeView","source/com/intellij/openapi/fileTypes","testData/inspection/dataFlow/SCR39950/src","testData/refactoring/movePackage/moveSingle","testData/refactoring/turnRefsToSuper/returnValue/before","source/com/intellij/openapi/vfs/impl","testData/refactoring/typeCook/t63/before","testData/refactoring/typeCook/t58/after","openapi","source/com/intellij/refactoring/rename","plugins/debuggerCommonViews","source/com/intellij/openapi/compiler","openapi/src/com/intellij/ant","testData/refactoring/typeCook/t06/after","testData/inspection/visibility/SCR5008","source/com/intellij/codeInspection/canBeFinal","source/com/intellij/ide/util/treeView/smartTree","testData/refactoring/typeCook/t125/after","source/com/intellij/codeInspection/emptyMethod","testData/refactoring/typeCook/t13/before","testData/refactoring/typeCook/t39/after","testData/refactoring/typeCook/t104/before","doc/openapi/examples/plugin","testData/dependencies","testData/refactoring/moveClass/stringsAndComments/before/pack1","testData/inspection/dataFlow/SCR15162","testData/refactoring/typeCook/t35/before","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before","source/com/intellij/internal/encodings","source/com/intellij/uiDesigner/make","testData/refactoring/typeCook/t74/before","source/com/intellij/ide/todo","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/admin","testData/inspection/visibility/SCR11792","testData/refactoring/typeCook/t52/before","testData/refactoring/introduceParameter","source/com/intellij/openapi/vcs/readOnlyHandler","source/com/intellij/application/options/pathMacros","testData/refactoring/renameMethod/multi/staticImport1","testData/refactoring/renameMethod/multi/staticImport2","testData/refactoring/renameMethod/multi/staticImport3","testData/refactoring/renameMethod/multi/staticImport4","source/com/intellij/psi/impl/search","openapi/src/com/intellij/psi/tree/jsp","source/com/intellij/openapi/vfs/impl/local","openapi/src/com/intellij/codeInsight/intention","source/com/intellij/refactoring/actions","testData/refactoring/inheritanceToDelegation/innerClassForInterface/after","source/com/intellij/psi","openapi/src/com/intellij/openapi/options/colors","testSource/com/intellij/idea","source/com/intellij/openapi/command","testData/refactoring/typeCook/t04/after","testData/projectView","source/com/intellij/openapi/compiler/ex","util/testSource/com/intellij/util","plugins/cvs2/source/com/intellij/cvsSupport2/util","testData/refactoring/typeCook/t46/before","source/com/intellij/openapi/roots/watcher","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress","source/com/intellij/openapi/ui/ex","source/com/intellij/dupLocator/util","openapi/src/com/intellij/ide/fileTemplates","source/com/intellij/packageDependencies/ui","testData/refactoring/typeCook/t109/after","testData/inspection/redundantThrow","testData/projectView/standardProviders/src/com/package1","plugins/cvs2/source/com/intellij/cvsSupport2/cvsBrowser","source/com/intellij/psi/controlFlow","source/com/intellij/refactoring/memberPullUp","testData/refactoring/inheritanceToDelegation/simpleInsertion","plugins/cvs2/smartcvs-src/org/netbeans/lib","source/com/intellij/idea","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/admin","testSource/com/intellij/refactoring/move","plugins/comparingReferences/source/com/intellij/codeInspection","source/com/intellij/refactoring/extractMethod","testData/refactoring/typeCook/t02/before","testData/refactoring/typeCook/t52/after","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/file","util/src/com/intellij/util/io","testData/refactoring/turnRefsToSuper/methodFromSuper","source/com/intellij/openapi/vcs/impl","testData/inspection/dataFlow/SCR18186/src","testData/inspection/dataFlow/wrongEqualTypes/src","testData/refactoring/inheritanceToDelegation/superCalls/before","testData/refactoring/inheritanceToDelegation/abstractBase/after","source/com/intellij/psi/presentation","testData/refactoring/typeCook/t02/after","runtimesource/com/intellij/rt/execution","source/com/intellij/refactoring/move/moveInner","source/com/intellij/psi/impl/source/resolve/reference","util/src/com/intellij","testSource/com/intellij/localVcs","source/com/intellij/openapi/diff/impl/external","source/com/intellij/openapi/command/undo","source/com/intellij/help","testData/inspection/dataFlow/npe1/src","testData/inspection/localCanBeFinal/SCR6744_4","testData/refactoring/moveClass/nonJava","testData/inspection/localCanBeFinal/SCR6744_3","testData/inspection/localCanBeFinal/SCR6744_2","testData/inspection/localCanBeFinal/SCR6744_1","testData/refactoring/typeCook/t53/after","source/com/intellij/pom","testData/inspection/localCanBeFinal/SCR6744_6","source/com/intellij/codeInsight/highlighting","testData/inspection/localCanBeFinal/SCR6744_5","testData/refactoring/typeCook/t120/after","util/testSource/com","source/com/intellij/openapi/options/colors/pages","testData/refactoring/inheritanceToDelegation/scr20557/after","doc/openapi/examples/plugin/src/com/intellij/openapi","testData/refactoring/turnRefsToSuper/useAsArg","testData/refactoring/typeCook/t01/after","source/com/intellij/pom/java","testData/refactoring/inheritanceToDelegation/subClassNoMethods","testData/refactoring/typeCook/t90/after","source/com/intellij/ui/plaf/beg","testData/refactoring/typeCook/t131/before","testData/refactoring/moveClass/jsp/before/pack1","plugins","source/com/intellij/psi/impl/smartPointers","pom/src/com/intellij","testData/refactoring/movePackageMultiroot/movePackage/before/src1","testData/refactoring/movePackageMultiroot/movePackage/before/src2","testData/inspection/canBeFinal/simpleClassInheritance/src","openapi/src/com/intellij/debugger/engine/jdi","testData/refactoring/typeCook/t68/before","testData/inspection/localCanBeFinal/SCR6744_4/src","doc/openapi/examples/toolWindow/src","testData/refactoring/typeCook/t23/after","source/com/intellij/openapi/diff/impl/mergeTool","testData/refactoring/inheritanceToDelegation/innerClassForInterface/before","source/com/intellij/debugger/codeinsight","testData/inspection/visibility/innerConstructor/src","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/command","testData/refactoring/typeCook/t90/before","source/com/intellij/codeInsight/template/macro","source/com/intellij/ide/highlighter","testData/refactoring/typeCook/t16/before","openapi/src/com/intellij/ui/table","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/javacvsSpecificImpls","testData/refactoring/renameMethod/multi/staticImport4/after","testData/refactoring/typeCook/t30/before","testData/refactoring/typeCook/t38/before","testData/refactoring/typeCook/t71/before","source/com/intellij/psi/filters/position","testData/refactoring/movePackage/qualifiedRef","source/com/intellij/codeEditor","source/com/intellij/uiDesigner/propertyInspector","testData/refactoring/typeCook/t95/after","openapi/src/com/intellij/vcsUtil","testData/refactoring/inheritanceToDelegation/hierarchy","testData/refactoring/turnRefsToSuper/instanceOf","testSource/com/intellij/refactoring/migration","testData/refactoring/typeCook/t28/after","source/com/intellij/refactoring/util/classRefs","openapi/src/com/intellij/openapi/diagnostic","plugins/cvs2/source/com/intellij/cvsSupport2/checkinProject","testSource/com/intellij/codeInsight/daemon","source/com/intellij/errorreport/itn","source/com/intellij/compiler/classParsing","testData/refactoring/turnRefsToSuper/commonInheritorResults/before","testData/refactoring/inheritanceToDelegation/superCalls/after","source/com/intellij/psi/impl/cache","openapi/src/com/intellij/util/ui","testData/inspection/dataFlow/CatchParameterCantBeNull","testData/refactoring/typeCook/t112/before","testData/inspection/emptyMethod/superCall/src","testData/refactoring/moveClass/localClass","testData/refactoring/moveInner/scr13730","testData/refactoring/moveMembers/scr11871/after/pack1","testData/refactoring/typeCook/t57/after","testData/refactoring/moveClass/moveMultiple1","openapi/src/com/intellij/openapi/module","doc/openapi/examples","source/com/intellij/ide/fileTemplates/impl","source/com/intellij/ide/actions","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch","source/com/intellij/codeInspection/reference","testData/refactoring/migration/toNonExistentClass/after/p1","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight","source/com/intellij/ide/ui","testData/refactoring/movePackage/moveSingle/before","source/com/intellij/debugger/engine/events","openapi/src/com/intellij/openapi/vcs/checkin","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl/io","source/com/intellij/psi/impl/source/javadoc","testData/refactoring/typeCook/t110/after","testData/psi","openapi/src/com/intellij/openapi/editor/actionSystem","openapi/src/com/intellij/debugger/ui","source/com/intellij/openapi/diff/actions","source/com/intellij/ide/structureView/newStructureView","testData/inspection/dataFlow/SCR13702","testData/inspection/localCanBeFinal/if","testData/refactoring/renameClass/collision/after","testData","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/request","testData/inspection/emptyMethod/superCall","testData/refactoring/typeCook/t106/before","openapi/src/com/intellij/openapi/progress","testData/refactoring/typeCook/t128/before","testData/inspection/localCanBeFinal/SCR6744_3/src/foo","util/src/com/intellij/util","source/com/intellij/usageView/impl","testData/inspection/redundantThrow/SCR6858","testData/refactoring/typeCook/t65/after","testData/inspection/dataFlow/GenericInstanceof/src","source/com/intellij/psi/scope","source/com/intellij/ide/commander","openapi/src/com/intellij/openapi/vcs/ui","testData/inspection/dataFlow/SCR18186","testData/refactoring/moveInner","testData/refactoring/typeCook/t36/after","testSource/com/intellij/refactoring/inline","source/com/intellij/internal/psiView","testData/inspection/dataFlow/xor/src","testData/refactoring/movePackage/insidePackage/after/a/b","testData/refactoring/turnRefsToSuper/commonInheritorResults/after","javac2/src/com/intellij/uiDesigner","source/com/intellij/debugger/ui/impl/watch/render","testData/refactoring/typeCook/t22/before","testData/refactoring/renameClass/nonJava","testData/refactoring/turnRefsToSuper/scr34020","source/com/intellij/debugger/engine/evaluation/expression","testSource/com/intellij/openapi/ui","source/com/intellij/psi/impl/cache/impl","testData/refactoring/moveInner/scr15142/before/xxx","source/com/intellij/ide/todo/nodes","source/com/intellij/openapi/actionSystem/impl","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/file","testData/refactoring/typeCook/t134/before","testData/refactoring/moveClass/contextChange2/before/pack1","source/com/intellij/openapi/diff/ex","testData/refactoring/turnRefsToSuper/returnValue/after","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local","testData/refactoring/moveInner/scr15142/after/xxx","testData/refactoring/typeCook/t65/before","openapi/src/com/intellij/xml","testData/refactoring/inlineLocal","source/com/intellij/ide/updates","openapi/src/com/intellij/openapi/roots/libraries","source/com/intellij/openapi/diff/impl","testData/inspection/canBeFinal/SCR7737/ext_src","source/com/intellij/debugger/ui","source/com/intellij/refactoring/openapi/impl","doc","testData/refactoring/typeCook/t66/after","source/com/intellij/psi/impl/source/parsing","openapi/src/com/intellij/psi/statistics","source/com/intellij/application/options/colors","source/com/intellij/codeInsight/navigation","testData/inspection/dataFlow/scrIDEA1/src","testData/refactoring/moveClass/contextChange1/before/pack1","testData/refactoring/inheritanceToDelegation/subinterface/after","testData/inspection/defUse/arrayIndexUsages","testData/refactoring/typeCook/t32/after","testData/refactoring/typeCook/t125/before","testData/inspection/visibility/SCR6856/src","testData/inspection/localCanBeFinal/parameters","testData/refactoring/movePackage/qualifiedRef/before","testData/refactoring/moveClass/moveMultiple1/before","testData/inspection/localCanBeFinal/SCR7601/src","source/com/intellij/pom/core/impl","testData/refactoring/moveClass/localClass/after/pack2","source/com/intellij/uiDesigner/quickFixes","testData/refactoring/typeCook/t93/before","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/ui","testData/refactoring/moveClass/stringsAndComments2/after","forms_rt/src/com/intellij/uiDesigner/core","source/com/intellij/packageDependencies","source/com/intellij/openapi/vfs/impl/jar","source/com/intellij/openapi/module/impl","source/com/intellij/openapi/actionSystem/ex","openapi/src/com/intellij/psi/xml","testData/refactoring/typeCook/t140/after","testData/refactoring/moveClass/jsp/after/WEB-INF","testData/inspection/localCanBeFinal/SCR6744_2/src","UIDesignerCore/src","source/com/intellij/codeInspection/miscGenerics","testData/inspection/dataFlow/SCR39950","source/com/intellij/openapi/localVcs/impl","source/com/intellij/uiDesigner/actions","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/reservedcheckout","testData/refactoring/typeCook/t24/after","testData/refactoring/typeCook/t43/before","testData/refactoring/migration/toNonExistentClass/before/p1","testData/inspection/localCanBeFinal/SCR7428","testData/refactoring/typeCook/t27/after","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd","openapi/src/com/intellij/util/concurrency/readwrite","runtimesource/com/intellij/rt/execution/junit2/segments","testData/refactoring/moveMembers/javadocRefs/after","testData/refactoring/migration/packageToNonExistentPackage/before/p1","UIDesignerCore/src/com/intellij/uiDesigner/compiler","util/src/com/intellij/openapi/util","testData/refactoring/typeCook/t87/before","source/com/intellij/openapi/diff/impl/highlighting","openapi/src/com/intellij/openapi/editor","pom/src/com/intellij/pom/event","source/com/intellij/execution/remote","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver","source/com/intellij/compiler/ant","testData/refactoring/renameMethod/multi/staticImport2/after/pack2","testData/refactoring/typeCook/t31/after","testData/refactoring/renameMethod/multi/staticImport2/after/pack1","plugins/cvs2/source/com/intellij/cvsSupport2/actions","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsMessages","source/com/intellij/refactoring/typeCook/deductive/builder","source/com/intellij/openapi/components","source/com/intellij/ide/highlighter/custom/impl","plugins/cvs2/source/com/intellij/cvsSupport2/config","openapi/src/com/intellij/openapi/vfs/pointers","source/com/intellij/ide/startup/impl","testData/inspection/emptyMethod","plugins/cvs2/smartcvs-src/org/netbeans","doc/openapi/examples/vfs/src/com/intellij","testData/inspection/dataFlow/SCR14314/src","testData/refactoring/turnRefsToSuper/methodFromSuper/before","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh/ui","source/com/intellij/psi/impl/source/codeStyle/javadoc","testData/inspection/canBeFinal/SCR6781/src","openapi/src/com/intellij/openapi/diff","source/com/intellij/jsp","testSource","source/com/intellij/openapi/editor/ex/util","testData/inspection/localCanBeFinal/incompleteAssignment","testData/refactoring/typeCook/t21/before","source/com/intellij/refactoring/ui","testData/inspection/dataFlow/cce/src","testData/refactoring/typeCook/t25/before","testData/inspection/defUse/SCR6843","testData/refactoring/turnRefsToSuper/removeImport/after/pack2","testData/refactoring/turnRefsToSuper/removeImport/after/pack1","source/com/intellij/openapi/application/ex","testData/refactoring/renameClass","openapi/src/com/intellij/util/io","openapi/src/com/intellij/execution","source/com/intellij/debugger","source/com/intellij/openapi/options","testData/inspection/localCanBeFinal/SCR6744_2/src/foo","testData/refactoring/typeCook/t62/before","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ui","testData/refactoring/typeCook/t114/after","source/com/intellij/ide/actions/tree","source/com/intellij/codeInspection/dataFlow/instructions","source/com/intellij/util/ui","testData/inspection/dataFlow/SCR15406","testData/refactoring/typeCook/t69/after","source/com/intellij/ide/errorTreeView/impl","openapi/src/com/intellij/debugger/engine/managerThread","testData/refactoring/typeCook/t29/after","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/checkout","source/com/intellij/j2ee/module/view/common/editor","testData/refactoring/moveClass/jsp/before","testData/refactoring/typeCook/t103/before","testData/refactoring/typeCook/t62/after","source/com/intellij/ide/macro","testSource/com/intellij/openapi/roots","source/com/intellij/projectView","testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1","testData/refactoring/typeCook/t122/before","source/com/intellij/psi/scope/util","UsageView","source/com/intellij/ui","testData/inspection/emptyMethod/SCR8321","testData/refactoring/inheritanceToDelegation/overridenMethods/after","util/testSource","testData/refactoring/typeCook/t144/before","source/com/intellij/compiler/options","source/com/intellij/openapi/project/ex","testData/refactoring/typeCook/t96/after","openapi/src/com/intellij/ide/actions","source/com/intellij/xml/impl/schema","testData/refactoring/typeCook/t119/after","testData/refactoring/inheritanceToDelegation/hierarchy/before","source/com/intellij/ide/bookmarks/actions","source/com/intellij/execution/ui","testData/refactoring/renameMethod/multi/staticImport1/before","testData/refactoring/typeCook","plugins/debuggerCommonViews/src","source/com/intellij/debugger/impl","testData/refactoring/typeCook/t107/before","source/com/intellij/ide/hierarchy","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient/util","testData/inspection/defUse/arrayIndexUsages/src","openapi/src/com/intellij/execution/runners","source/com/intellij/codeInsight/template/impl","source/com/intellij/internal/diGraph","testData/refactoring/typeCook/t67/after","testData/refactoring/replaceConstructorWithFactory","testData/refactoring/inheritanceToDelegation/simpleInsertion/before","source/com/intellij/analysis","source/com/intellij/uiDesigner/componentTree","openapi/src/com/intellij/j2ee","openapi/src/com/intellij/openapi/actionSystem/ex","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/status","testData/inspection/defUse/SCR28019","testData/refactoring/typeCook/t47/before","source/com/intellij/openapi/application/impl","source/com/intellij/featureStatistics/ui","testData/refactoring/inheritanceToDelegation/subinterface","testData/refactoring/moveClass/localClass/after","openapi/src/com/intellij/psi/search/scope/packageSet","openapi/src/com/intellij/ide/structureView","source/com/intellij/refactoring/typeCook/deductive/resolver","testData/inspection/canBeFinal/fieldAndTryBlock/src","plugins/cvs2/source/com/intellij/cvsSupport2/cvsIgnore","source/com/intellij/j2ee/extResources","source/com/intellij/refactoring/migration","util/src/com/intellij/openapi/util/io","testData/refactoring/typeCook/t94/after","source/com/intellij/ide/structureView/impl","util/testSource/com/intellij","testData/refactoring/typeCook/t91/after","testData/refactoring/typeCook/t06/before","testData/refactoring/turnRefsToSuper/scr34000","testData/inspection/dataFlow/caseAndNpe/src","openapi/src/com/intellij/debugger","testData/refactoring/inheritanceToDelegation/abstractBase1/after","source/com/intellij/openapi/editor","source/com/intellij/debugger/impl/descriptors/data","testData/inspection/dataFlow/Instanceof","testData/refactoring/movePackageMultiroot","testData/refactoring/renameClass/nonJava/after","testData/refactoring/inheritanceToDelegation/interfaceDelegation/before","source/com/intellij/openapi/actionSystem","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/commit","plugins/comparingReferences/source/com","source/com/intellij/execution/junit2/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command","source/com/intellij/openapi/options/ex","testSource/com/intellij/util/diff","source/com/intellij/psi/filters/classes","util/src/com/intellij/util/ui/treetable","source/com/intellij/openapi/fileEditor/ex","testData/projectView/standardProviders/src","UsageView/testSource/com/intellij/usages","openapi/src/com/intellij/refactoring/listeners","source/com/intellij/uiDesigner/propertyInspector/renderers","testData/refactoring/makeMethodStatic","testData/refactoring/typeCook/t64/after","source/com/intellij/refactoring/convertToInstanceMethod","testData/refactoring/turnRefsToSuper/commonInheritorResults","testData/refactoring/typeCook/t03/before","runtimesource/com/intellij/rt/ant/execution","testData/refactoring/turnRefsToSuper/commonInheritorFail/after","source/com/intellij/refactoring/replaceConstructorWithFactory","testData/refactoring/turnRefsToSuper/removeImport","testData/refactoring/typeCook/t93/after","testData/refactoring/typeCook/t138/before","UIDesignerCore/testSource/com","source/com/intellij/codeInsight/javadoc","source/com/intellij/codeInspection","testData/refactoring/typeCook/t60/after","openapi/src/com/intellij/openapi/vcs/history","source/com/intellij/openapi/diff/impl/splitter","openapi/src/com/intellij/execution/ui","source/com/intellij/j2ee/module/view/common","testData/refactoring/typeCook/t117/after","testData/refactoring/typeCook/t98/after","source/com/intellij/codeInsight/highlighting/actions","source/com/intellij/tools","source/com/intellij/javadoc/actions","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsContent","testData/inspection/dataFlow/thisInstanceof","util/src/com/intellij/openapi/application","testData/inspection/localCanBeFinal/SCR6744_6/src","testData/refactoring/movePackageMultiroot/movePackage/after/src2/target","testData/refactoring/typeCook/t28/before","testData/refactoring/typeCook/t19/before","testSource/com/intellij/refactoring/move/moveMembers","testData/refactoring/typeCook/t100/before","testData/refactoring/moveMembers/scr40947/after","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch/ui","source/com/intellij/ide/hierarchy/type","source/com/intellij/openapi/vfs/ex/http","testData/refactoring/renameMethod/multi/staticImport2/after","testData/refactoring/movePackage/moveSingle/after/pack2","source/com/intellij/openapi/projectRoots/impl","testData/refactoring/typeCook/t118/after","doc/openapi/examples/toolWindow/src/com/intellij","source/com/intellij/find/actions","testData/refactoring/renameClass/import","source/com/intellij/featureStatistics/actions","testData/refactoring/typeCook/t56/before","testData/inspection/canBeFinal/SCR7737/src","testData/refactoring/moveMembers/twoMethods","testData/refactoring/typeCook/t111/after","UIDesignerCore/src/com/intellij/uiDesigner/shared","testData/refactoring/typeCook/t61/after","source/com/intellij/testFramework","testData/refactoring/typeCook/t112/after","source/com/intellij/find/findInProject","source/com/intellij/openapi/keymap","source/com/intellij/openapi/vcs/ex","UIDesignerCore/src/com/intellij/uiDesigner","testSource/com/intellij/refactoring/rename","testData/refactoring/turnRefsToSuper/scr34020/after/test","openapi/src/com/intellij/ide/wizard","source/com/intellij/openapi/vcs/actions","source/com/intellij/ide/highlighter/custom","testData/refactoring/typeCook/t40/before","testData/refactoring/renameClass/collision/before/pack2","testData/refactoring/renameClass/collision/before/pack1","testData/refactoring/typeCook/t116/before","testData/refactoring/moveClass/jsp/before/WEB-INF","source/com/intellij/codeInspection/actions","testData/refactoring/typeCook/t97/after","openapi/src/com/intellij/psi/util","openapi/src/com/intellij/psi/scope","source/com/intellij/openapi/diff/impl/incrementalMerge/ui","testData/refactoring/typeCook/t113/after","testData/refactoring/typeCook/t116/after","plugins/cvs2/maverick_utils","source/com/intellij/psi/filters","testData/refactoring/renameMethod/multi/staticImport3/after","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail","testData/inspection/dataFlow/wrongEqualTypes","source/com/intellij/codeInsight/completion/scope","testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1","testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2","source/com/intellij/util/io","openapi/src/com/intellij/debugger/ui/tree/render","testData/refactoring/typeCook/t78/before","openapi/src/com/intellij/ui/content","doc/openapi/examples/plugin/src/com/intellij/openapi/samples","source/com/intellij/codeInspection/visibility","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit/ui","openapi/src/com/intellij/psi/search/scope","testSource/com/intellij/util/config","source/com/intellij/ide/impl/dataRules","testData/refactoring/renameClass/collision","source/com/intellij/codeInsight/daemon/impl","testData/refactoring/turnRefsToSuper","source/com/intellij/codeInsight/lookup/impl/actions","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after","source/com/intellij/ide/plugins/cl","testData/refactoring/moveInner/scr22592/before","testData/refactoring/moveClass/contextChange1/after/pack1","testData/refactoring/moveClass/contextChange1/after/pack2","openapi/src/com/intellij/j2ee/run","source/com/intellij/openapi/localVcs","testData/refactoring/inheritanceToDelegation/simpleInsertion/after","UsageView/src/com/intellij/usages","testData/refactoring/renameClass/innerClass/after/pack1","javac2/src/com/intellij","testData/refactoring/renameMethod/multi/staticImport1/after","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsWatch","testData/refactoring/changeClassSignature","plugins/cvs2/source/com/intellij/cvsSupport2/connections/pserver/ui","openapi/src/com/intellij/openapi/vcs/fileView","testData/refactoring/typeCook/t84/before","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/add","testData/refactoring/moveClass/stringsAndComments/after","testData/refactoring/turnRefsToSuper/removeImport/after","testData/refactoring/typeCook/t99/after","source/com/intellij/codeInsight/generation","source/com/intellij/refactoring/turnRefsToSuper","testData/refactoring/typeCook/t115/after","testData/refactoring/renameClass/import/after/a","source/com/intellij/j2ee/run","plugins/cvs2/source/com/intellij","UsageView/testSource/com","testData/refactoring/typeCook/t23/before","plugins/cvs2/source/com/intellij/cvsSupport2/keywordSubstitution","testData/refactoring/turnRefsToSuper/classUsage/after","openapi/src/com/intellij/codeInsight","testData/refactoring/inheritanceToDelegation/hierarchy/after","testData/refactoring/movePackage/moveSingle/after/target/pack1","doc/openapi/examples/vfs/src/com/intellij/openapi","source/com/intellij/openapi/editor/colors/ex","testData/refactoring/typeCook/t135/before","source/com/intellij/openapi/vcs/history/impl","forms_rt","testData/inspection/canBeFinal/fields/src","UsageView/src/com/intellij/usages/rules","source/com/intellij/ui/content/impl","testData/refactoring/typeCook/t64/before","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/progress/receiving","plugins/cvs2/source/com/intellij/cvsSupport2/updateinfo","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract","openapi/src/com/intellij/psi/tree","source/com/intellij/openapi/diff/impl/settings","source/com/intellij/ide/errorTreeView","plugins/cvs2/javacvs-src/org/netbeans/lib","source/com/intellij/execution/junit2","source/com/intellij/refactoring/util/occurences","testData/refactoring/movePackage/qualifiedRef/before/package1/test","source/com/intellij/openapi/command/impl","testData/refactoring/typeCook/t94/before","testData/inspection/dataFlow/Instanceof/src","source/com/intellij/psi/tree","runtimesource/com/intellij","testData/refactoring/moveInner/scr15142/before","testData/refactoring/typeCook/t63/after","testData/refactoring/turnRefsToSuper/returnValue2","testData/refactoring/moveMembers/outerClassTypeParameters/before","source/com/intellij/codeInsight/editorActions/smartEnter","testData/refactoring/typeCook/t89/after","testData/refactoring/turnRefsToSuper/methodFromSuper/after","testData/refactoring/moveClass","source/com/intellij/openapi/keymap/impl","openapi/src/com/intellij/navigation","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsAdd/ui","openapi/src/com/intellij/openapi/ide","testData/psi/normalizeDeclaration","source/com/intellij","testData/refactoring/typeCook/t12/before","openapi/src/com/intellij/openapi/actionSystem","openapi/src/com/intellij/openapi/cvsIntegration","openapi/src/com/intellij/openapi","openapi/src/com/intellij/usageView","openapi/src/com/intellij/openapi/editor/markup","testData/refactoring/inheritanceToDelegation/innerClass/after","testData/refactoring/typeCook/t34/before","source/com/intellij/openapi/diff","testData/refactoring/typeCook/t53/before","source/com/intellij/openapi/project/impl/convertors","testData/refactoring/typeCook/t75/before","source/com/intellij/openapi/roots/ui/util","testData/refactoring/moveClass/nonJava/before/pack1","openapi/src/com/intellij/debugger/engine","testData/refactoring/typeCook/t68/after","testData/inspection/canBeFinal/simpleClassInheritance","source/com/intellij/ide/actionMacro/actions","source/com/intellij/codeInsight/template/impl/actions","source/com/intellij/openapi/progress/impl","plugins/cvs2/smartcvs-src/org/netbeans/lib/cvsclient","testData/refactoring/typeCook/t84/after","source/com/intellij/psi/impl/cache/impl/repositoryCache","source/com/intellij/compiler/progress","testData/inspection/dataFlow/scrIDEA1","source/com/intellij/psi/impl/source/text","testData/inspection/visibility/packageLevelTops/src/package2","testData/inspection/visibility/packageLevelTops/src/package1","testData/refactoring/turnRefsToSuper/scr34000/after","testData/refactoring/renameClass/nonJava/before","testSource/com/intellij/util/ui/tree","testData/refactoring/inheritanceToDelegation/subClassNoMethods/before","UsageView/src","plugins/conditionalOperatorConvertor/testSrc/com/intellij","testData/refactoring/inheritanceToDelegation/interfaces","testData/refactoring/typeCook/t42/before","testData/refactoring/turnRefsToSuper/toArray/before","testData/refactoring/moveMembers/twoMethods/after/pack2","doc/openapi/examples/actions/src/com/intellij","testData/refactoring/moveMembers/twoMethods/after/pack1","plugins/cvs2/source/com/intellij/cvsSupport2/cvsstatuses","source/com/intellij/compiler/impl/javaCompiler","testData/refactoring/moveInner/nonJavaFiles/after","testData/inspection/localCanBeFinal/SCR11757/src","testData/refactoring/typeCook/t126/after","testData/refactoring/turnRefsToSuper/scr34020/before/test","plugins/conditionalOperatorConvertor/testSrc/com","source/com/intellij/psi/impl/migration","testData/refactoring/typeCook/t83/before","testData/refactoring/inheritanceToDelegation/overridenMethods","openapi/src/com","testData/inspection/canBeFinal/privateInners/src","source/com/intellij/refactoring/introduceParameter","testData/refactoring/typeCook/t42/after","forms_rt/src","testData/refactoring/typeCook/t12/after","testData/inspection/localCanBeFinal/parameters/src","testData/refactoring/movePackage/insidePackage/after","testSource/com/intellij/codeInsight","openapi/src/com/intellij/psi","runtimesource/com/intellij/rt/execution/junit","testData/refactoring/typeCook/t72/before","testData/refactoring/moveInner/scr22592/after","doc/openapi/examples/toolWindow","testData/inspection/visibility/SCR5008/src","testSource/com/intellij/codeInsight/daemon/quickFix","testData/inspection/dataFlow","source/com/intellij/ide/hierarchy/call","testData/refactoring/renameMethod/multi/staticImport2/before/pack2","testData/refactoring/renameMethod/multi/staticImport2/before/pack1","openapi/src/com/intellij/j2ee/ui","plugins/cvs2/source/com/intellij/cvsSupport2/consoleView","source/com/intellij/psi/impl/compiled","source/com/intellij/refactoring/util/javadoc","openapi/src/com/intellij/openapi/application","plugins/comparingReferences/source/com/intellij","source/com/intellij/refactoring/anonymousToInner","testSource/com/intellij/openapi/vcs","source/com/intellij/jsp/impl","doc/openapi/examples/toolWindow/src/com","source/com/intellij/refactoring/encapsulateFields","testData/inspection/dataFlow/SCR15162/src","testData/refactoring/changeSignature","testData/refactoring/typeCook/t28","testData/refactoring/moveClass/contextChange2/after","testData/refactoring/typeCook/t27","testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1","testData/refactoring/typeCook/t26","testData/refactoring/typeCook/t25","testData/refactoring/typeCook/t24","testData/refactoring/inheritanceToDelegation/scr20557/after/xxx","testData/refactoring/typeCook/t20/before","testData/refactoring/typeCook/t23","testData/refactoring/typeCook/t22","testData/refactoring/typeCook/t21","testData/refactoring/typeCook/t20","testData/refactoring/typeCook/t26/before","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext","source/com/intellij/openapi/fileChooser","testData/refactoring/typeCook/t29","testData/refactoring/typeCook/t17","source/com/intellij/codeInspection/ui","testData/refactoring/typeCook/t16","testData/refactoring/inheritanceToDelegation/scr20557/before","testData/refactoring/typeCook/t15","testData/refactoring/typeCook/t14","testData/refactoring/typeCook/t13","doc/openapi/examples/toolWindow/src/com/intellij/openapi","source/com/intellij/execution/actions","testData/refactoring/typeCook/t12","testData/refactoring/typeCook/t11","testData/refactoring/typeCook/t10","testSource/com/intellij/ui","util/src/com/intellij/util/containers","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsImport","testData/refactoring/inheritanceToDelegation","testData/refactoring/typeCook/t26/after","source/com/intellij/psi/statistics/impl","testData/inspection/dataFlow/exceptionCFG","testData/refactoring/turnRefsToSuper/instanceOf/before","testData/refactoring/typeCook/t102/before","testData/refactoring/typeCook/t19","testData/inspection/dataFlow/SCR13626","testData/refactoring/movePackage/moveSingle/after/target","testData/refactoring/typeCook/t18","testData/refactoring/typeCook/t06","testData/refactoring/typeCook/t05","testData/refactoring/typeCook/t04","testData/refactoring/typeCook/t03","testData/refactoring/typeCook/t02","testData/refactoring/typeCook/t01","runtimesource/com/intellij/rt/debugger","testData/inspection/canBeFinal/SCR6845","testData/refactoring/typeCook/t72/after","UIDesignerCore/testSource/com/intellij/uiDesigner","testData/refactoring","source/com/intellij/openapi/vcs/ui","source/com/intellij/ide/fileTemplates/ui","plugins/cvs2/javacvs-src","testData/refactoring/typeCook/t31/before","source/com/intellij/refactoring/util/usageInfo","source/com/intellij/refactoring/inheritanceToDelegation","runtimesource/com/intellij/rt/ant","runtimesource/com/intellij/rt","testData/refactoring/typeCook/t09","testData/refactoring/typeCook/t08","testData/refactoring/moveInner/scr30106/before","testData/refactoring/typeCook/t07","testData/refactoring/typeCook/t86/before","openapi/src/com/intellij/ui/errorView","openapi/src/com/intellij/openapi/projectRoots","source/com/intellij/openapi/projectRoots/ex","testData/refactoring/typeCook/t97/before","testData/refactoring/typeCook/t33/after","plugins/cvs2/smartcvs-src","testData/refactoring/typeCook/t100/after","source/com/intellij/execution/applet","doc/openapi/examples/plugin/src/com","source/com/intellij/find","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/update","testData/inspection/canBeFinal/SCR6861","testData/refactoring/typeCook/t21/after","testSource/com/intellij/refactoring","testData/refactoring/typeCook/t77/after","testData/refactoring/typeCook/t113/before","testData/refactoring/typeCook/t69","testData/refactoring/typeCook/t68","source/com/intellij/openapi/roots","testData/refactoring/typeCook/t67","testData/refactoring/typeCook/t66","testData/refactoring/typeCook/t65","testData/refactoring/typeCook/t64","source/com/intellij/ide/impl","testData/refactoring/typeCook/t63","testData/refactoring/typeCook/t62","testData/refactoring/typeCook/t61","testSource/com/intellij/refactoring/convertToInstanceMethod","testData/refactoring/typeCook/t60","source/com/intellij/openapi/roots/ui/configuration","testData/refactoring/movePackage/insidePackage/before","source/com/intellij/codeEditor/printing","source/com/intellij/openapi/project/impl","source/com/intellij/execution","testData/refactoring/typeCook/t17/after","testData/inspection/localCanBeFinal/SCR6744_4/src/foo","testData/refactoring/typeCook/t48/before","plugins/cvs2/source/com/intellij/cvsSupport2/actions/actionVisibility","source/com/intellij/application/options/colors/highlighting","source/com/intellij/psi/text","openapi/src/com/intellij/openapi/startup","testData/refactoring/typeCook/t59","plugins/cvs2/javacvs-src/org/netbeans","testData/refactoring/typeCook/t58","testData/refactoring/typeCook/t57","source/com/intellij/openapi/editor/colors","testData/refactoring/typeCook/t56","testData/refactoring/typeCook/t55","testData/refactoring/typeCook/t54","testData/refactoring/typeCook/t53","testData/refactoring/typeCook/t52","testData/refactoring/typeCook/t51","testData/refactoring/typeCook/t50","testData/refactoring/typeCook/t119/before","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsCommit","testData/refactoring/typeCook/t108/before","UsageView/src/com/intellij/usages/impl/rules","source/com/intellij/openapi/components/impl","testData/refactoring/typeCook/t04/before","plugins/cvs2/source/com/intellij/cvsSupport2","testData/refactoring/typeCook/t138/after","testData/refactoring/typeCook/t49","testData/refactoring/typeCook/t48","testData/inspection/localCanBeFinal/SCR7428_1","testData/refactoring/typeCook/t47","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/connection","testData/refactoring/typeCook/t46","testData/refactoring/typeCook/t15/before","testData/refactoring/typeCook/t45","testData/refactoring/typeCook/t44","testData/refactoring/inheritanceToDelegation/getter/after","testData/refactoring/typeCook/t43","testData/refactoring/movePackage/qualifiedRef/before/package1","testData/refactoring/typeCook/t42","testData/refactoring/migration/package/after/p1","testData/refactoring/typeCook/t41","testData/refactoring/typeCook/t40","source/com/intellij/openapi/fileChooser/ex","source/com/intellij/psi/filters/element","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watch","testData/refactoring/typeCook/t124/before","testData/refactoring/typeCook/t37/before","testData/refactoring/moveMembers/outerClassTypeParameters/after","testData/refactoring/moveInner/scr22592","source/com/intellij/openapi/roots/ui/componentsList/layout","testData/refactoring/renameMethod/multi/staticImport4/before/pack1","testData/refactoring/renameMethod/multi/staticImport4/before/pack2","UsageView/src/com/intellij","testData/refactoring/typeCook/t59/before","testData/refactoring/typeCook/t75/after","testData/refactoring/typeCook/t39","testData/refactoring/typeCook/t38","testData/refactoring/typeCook/t37","testData/refactoring/typeCook/t36","testData/refactoring/migration/package/after","testData/refactoring/movePackageMultiroot/movePackage","testData/refactoring/typeCook/t35","testData/refactoring/typeCook/t34","testData/refactoring/typeCook/t33","testData/refactoring/typeCook/t32","source/com/intellij/compiler/actions","source/com/intellij/refactoring/extractSuperclass","testData/refactoring/typeCook/t31","testData/refactoring/typeCook/t30","source/com/intellij/openapi/diff/impl/util","openapi/src/com/intellij/psi/javadoc","testData/refactoring/moveMembers/javadocRefs","source/com/intellij/codeInsight/lookup","source/com/intellij/openapi/fileEditor","source/com/intellij/ide/projectView","source/com/intellij/psi/impl/source/xml","source/com/intellij/refactoring/changeSignature","source/com/intellij/refactoring/safeDelete/usageInfo","source/com/intellij/packageDependencies/packageSet","testData/refactoring/typeCook/t70/after","plugins/cvs2/smartcvs-src/org","openapi/src/com/intellij/codeInspection","source/com/intellij/refactoring/openapi","testData/refactoring/typeCook/t30/after","doc/openapi/examples/actions/src/com/intellij/openapi","testData/refactoring/inheritanceToDelegation/scr20557/before/xxx","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/importcmd","testData/refactoring/typeCook/t99","testData/refactoring/typeCook/t98","testData/refactoring/typeCook/t97","source/com/intellij/codeInsight/guess","testData/refactoring/typeCook/t96","testData/refactoring/typeCook/t95","testData/inspection/visibility/packageLevelTops","testData/refactoring/typeCook/t94","testData/refactoring/typeCook/t03/after","testData/refactoring/typeCook/t93","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsLog","testData/refactoring/typeCook/t92","testData/refactoring/typeCook/t91","testData/refactoring/typeCook/t90","testData/refactoring/moveMembers/weirdDeclaration/after","source/com/intellij/pom/java/impl","source/com/intellij/refactoring/move/moveFilesOrDirectories","testData/dependencies/dependencies/src","testSource/com/intellij/find","testData/refactoring/typeCook/t140/before","testData/refactoring/typeCook/t89","testData/refactoring/typeCook/t88","testData/refactoring/typeCook/t87","testData/refactoring/extractMethod","testData/refactoring/typeCook/t86","testData/refactoring/typeCook/t85","testData/refactoring/typeCook/t84","testData/refactoring/typeCook/t108/after","testData/refactoring/typeCook/t83","testData/refactoring/typeCook/t82","source/com/intellij/compiler/make","testData/refactoring/typeCook/t81","testData/refactoring/typeCook/t80","source/com/intellij/codeInspection/unneededThrows","testData/refactoring/moveMembers/twoMethods/before","source/com/intellij/find/findUsages","source/com/intellij/openapi/editor/colors/impl","testData/inspection/visibility/SCR5008/src/marti/p1","openapi/src/com/intellij/j2ee/module","testData/dependencies/dependencies/src/com/package1","testData/refactoring/typeCook/t79","testData/refactoring/typeCook/t78","testData/refactoring/typeCook/t77","testData/refactoring/typeCook/t76","testData/refactoring/typeCook/t75","testData/refactoring/typeCook/t74","testData/refactoring/typeCook/t73","source/com/intellij/openapi/progress/util","testData/refactoring/typeCook/t72","testData/refactoring/typeCook/t71","testData/refactoring/typeCook/t70","source/com/intellij/codeFormatting","testData/refactoring/typeCook/t56/after","openapi/src/com/intellij/refactoring","testSource/com/intellij/openapi/roots/ui","openapi/src/com/intellij/openapi/components","source/com/intellij/debugger/jdi","source/com/intellij/compiler/ant/taskdefs","testData/refactoring/turnRefsToSuper/classUsage","testData/refactoring/turnRefsToSuper/useAsArg/before","testData/refactoring/typeCook/t103/after","testData/refactoring/typeCook/t80/before","testData/inspection/dataFlow/SCR13871/src","testData/refactoring/moveInner/scr30106","testData/refactoring/movePackage/qualifiedRef/after/package2/test","util/src/com/intellij/openapi/util/text","testData/refactoring/moveMembers/scr40064/after","source/com/intellij/refactoring/introduceVariable","source/com/intellij/openapi/wm/impl/commands","testData/refactoring/migration/unexistingClassInUnexistingPackage/before","testData/refactoring/typeCook/t129/after","source/com/intellij/openapi/project","openapi/src/com/intellij/ide/util","source/com/intellij/psi/impl","openapi/src/com/intellij/j2ee/run/localRun","plugins/conditionalOperatorConvertor/source/com/intellij","util/testSource/com/intellij/openapi/util","testData/refactoring/renameMethod/multi/staticImport3/after/pack2","testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1","testData/refactoring/renameMethod/multi/staticImport3/after/pack1","testData/refactoring/moveClass/contextChange2/after/pack1","source/com/intellij/refactoring/util/classMembers","testData/projectView/standardProviders/src/com","testData/psi/arrayIndexOutOfBounds/src/bla","source/com/intellij/ide/startup","testData/refactoring/moveClass/contextChange2/after/pack2","source/com/intellij/refactoring/rename/naming","testData/refactoring/renameClass/collision/after/pack2","testData/refactoring/movePackage/insidePackage/after/a/b/a","testData/refactoring/renameClass/collision/after/pack1","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/watchers","source/com/intellij/codeInsight/completion/proc","source/com/intellij/psi/impl/source/codeStyle","source/com/intellij/openapi","testData/refactoring/migration/toNonExistentClass/before","testSource/com/intellij/dependencies","testData/refactoring/typeCook/t50/before","testData/refactoring/turnRefsToSuper/instanceOf/after","source/com/intellij/uiDesigner/propertyInspector/editors/string","testData/refactoring/typeCook/t35/after","source/com/intellij/psi/impl/source/html","source/com/intellij/uiDesigner/palette","source/com/intellij/psi/xml","plugins/cvs2/javacvs-src/org","testData/refactoring/typeCook/t08/after","testData/refactoring/turnRefsToSuper/returnValue","util/src/com/intellij/util/graph","testData/refactoring/typeCook/t91/before","testData/inspection/localCanBeFinal/SCR6744_1/src","openapi/src/com/intellij/pom/java/events","source/com/intellij/ui/content","testData/refactoring/typeCook/t59/after","testData/inspection/canBeFinal/SCR6781","openapi/src/com/intellij/util/concurrency","testData/refactoring/renameClass/import/before/a","source/com/intellij/j2ee","testData/refactoring/inlineMethod","source/com/intellij/codeInspection/ex","javac2/src/com","testData/refactoring/turnRefsToSuper/toArray","source/com/intellij/j2ee/openapi","testData/refactoring/typeCook/t132/before","source/com/intellij/codeInspection/sameParameterValue","testData/refactoring/movePackage/qualifiedRef/after/package2","plugins/conditionalOperatorConvertor/testSrc/com/intellij/codeInsight","source/com/intellij/application","testData/refactoring/moveClass/nonJava/before","openapi/src/com/intellij/xml/util","testData/refactoring/typeCook/t61/before","testData/refactoring/typeCook/t38/after","testSource/com/intellij/uiDesigner","testData/refactoring/moveMembers/scr11871/before/pack1","testData/refactoring/moveClass/jsp/after/pack2","testData/refactoring/renameMethod/multi/staticImport2/before","testData/refactoring/renameMethod/multi/staticImport4/before","testData/inspection/emptyMethod/externalOverride/ext_src","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations","testData/refactoring/typeCook/t105/after","testData/refactoring/inheritanceToDelegation/scr20557","source/com/intellij/j2ee/make","testData/inspection/dataFlow/SCR13702/src","testData/refactoring/typeCook/t121/before","testData/refactoring/moveClass/nonJava/after","openapi/src/com/intellij/pom","testData/refactoring/moveClass/moveMultiple1/after","source/com/intellij/internal","testData/refactoring/typeCook/t143/before","util/src/com/intellij/util/diff","testData/refactoring/typeCook/t124/after","testData/refactoring/typeCook/t05/after","testData/inspection/localCanBeFinal/SCR6744_1/src/foo","source/com/intellij/openapi/roots/impl","testData/refactoring/moveClass/contextChange2","testData/refactoring/moveClass/contextChange1","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsUpdate","testData/refactoring/inheritanceToDelegation/subClass","testData/refactoring/turnRefsToSuper/superClass/after","doc/openapi/examples/actions/src/com","source/com/intellij/openapi/editor/ex","source/com/intellij/compiler","testData/refactoring/moveMembers/scr40947/before","source/com/intellij/openapi/fileEditor/impl","source/com/intellij/openapi/module","source/com/intellij/packageDependencies/actions","testData/refactoring/typeCook/t110/before","source/com/intellij/openapi/projectRoots/ui","testData/inspection/canBeFinal/methodInheritance","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient","testData/refactoring/introduceField","testData/refactoring/inheritanceToDelegation/getter/before","testData/refactoring/moveMembers/weirdDeclaration/before","testData/refactoring/typeCook/t123/after","testData/refactoring/inheritanceToDelegation/innerClass/before","testData/inspection/dataFlow/exceptionCFG/src","openapi/src","plugins/cvs2/maverick_utils/com/intellij","source/com/intellij/ide/util","source/com/intellij/execution/junit2/info","source/com/intellij/openapi/vfs/ex/dummy","testData/refactoring/typeCook/t54/after","source/com/intellij/dupLocator","testData/refactoring/turnRefsToSuper/superClass","testData/refactoring/typeCook/t51/after","source/com/intellij/ide/structureView","source/com/intellij/psi/filters/types","testData/refactoring/inheritanceToDelegation/abstractBase","testData/refactoring/moveMembers/scr11871/before","source/com/intellij/psi/impl/source/tree/java","source/com/intellij/ide/highlighter/custom/tokens","plugins/cvs2/source/com/intellij/cvsSupport2/javacvsImpl","openapi/src/com/intellij/openapi/command","testData/refactoring/typeCook/t121/after","testData/inspection/visibility","source/com/intellij/refactoring/tempWithQuery","testData/refactoring/inheritanceToDelegation/subClass/before","source/com/intellij/codeInsight/javadoc/actions","testData/refactoring/typeCook/t29/before","testData/refactoring/typeCook/t18/before","testData/refactoring/typeCook/t07/before","testData/inspection/redundantThrow/SCR8322/src","util/src/com/intellij/openapi/diagnostic","testData/refactoring/moveClass/contextChange1/before","testData/refactoring/typeCook/t27/before","testData/refactoring/typeCook/t10/after","source/com/intellij/peer/impl","testData/refactoring/migration/packageToNonExistentPackage/after/p1","testData/refactoring/typeCook/t139/before","testData/refactoring/moveInner/nonJavaFiles","testData/refactoring/moveClass/moveMultiple1/after/pack2","UIDesignerCore","testData/refactoring/typeCook/t60/before","source/com/intellij/openapi/editor/impl/event","source/com","testData/refactoring/typeCook/t102/after","source/com/intellij/openapi/diff/impl/processing","testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after","testData/refactoring/typeCook/t98/before","testData/refactoring/moveMembers/twoMethods/before/pack1","testData/refactoring/moveMembers/twoMethods/before/pack2","testData/inspection/canBeFinal/simpleClassInheritance1","testData/refactoring/moveClass/moveMultiple1/before/pack1","testSource/com/intellij","openapi/src/com/intellij/openapi/vcs/vfs","openapi/src/com/intellij/ui/dualView","openapi/src/com/intellij/debugger/engine/evaluation","source/com/intellij/ui/errorView","source/com/intellij/util/config","source/com/intellij/codeInsight/completion","source/com/intellij/javadoc","testData/inspection/redundantThrow/SCR6858/src","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/importToCvs","testData/refactoring/moveClass/localClass/before","testData/refactoring/renameClass/import/after","openapi/src/com/intellij/openapi/roots","testSource/com/intellij/find/findUsages","testData/refactoring/turnRefsToSuper/fieldTest/before","testData/refactoring/inheritanceToDelegation/subinterface/before","testData/refactoring/moveMembers","testData/refactoring/typeCook/t15/after","source/com/intellij/xml/util/documentation","testData/refactoring/typeCook/t57/before","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/dateOrRevision/ui","testData/dependencies/dependencies/src/com","testData/refactoring/typeCook/t79/before","plugins/conditionalOperatorConvertor/source/com","testData/refactoring/typeCook/t107/after","source/com/intellij/refactoring/memberPushDown","source/com/intellij/debugger/impl/descriptors","testData/refactoring/typeCook/t44/after","testData/inspection/canBeFinal/privateInners","testData/refactoring/inheritanceToDelegation/interfaceDelegation","source/com/intellij/codeInspection/sameReturnValue","testData/refactoring/migration","testData/refactoring/moveInner/scr13730/after/pack1","testData/refactoring/typeCook/t87/after","testData/refactoring/turnRefsToSuper/removeImport/before/pack1","testData/refactoring/typeCook/t41/before","testData/refactoring/turnRefsToSuper/removeImport/before/pack2","source/com/intellij/openapi/application","source/com/intellij/execution/junit2/ui/properties","testData/refactoring/typeCook/t117/before","openapi/src/com/intellij/debugger/requests","testData/inspection/canBeFinal/SCR6073","testData/refactoring/typeCook/t07/after","testData/refactoring/turnRefsToSuper/commonInheritorFail","testData/refactoring/typeCook/t49/before","testData/inspection/dataFlow/GenericInstanceof","testData/inspection/localCanBeFinal","testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1","util/src/com/intellij/util/exception","testData/refactoring/renameClass/collision/before","testData/refactoring/turnRefsToSuper/cast/before","plugins/cvs2/source/com/intellij/cvsSupport2/config/ui","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/event","testData/inspection/defUse/SCR40364/src","testData/inspection/localCanBeFinal/SCR6744_5/src","testData/inspection/visibility/innerConstructor","testData/refactoring/typeCook/t11/before","testData/refactoring/typeCook/t08/before","testData/refactoring/typeCook/t128/after","testData/refactoring/moveInner/nonJavaFiles/before/pack1","testData/refactoring/moveClass/stringsAndComments","openapi/src/com/intellij/psi/html","plugins/cvs2/source/com/intellij/cvsSupport2/connections","testData/refactoring/typeCook/t123/before","plugins/cvs2/source/com/intellij/cvsSupport2/connections/local/ui","testData/refactoring/typeCook/t120/before","source/com/intellij/codeInsight/folding","testData/inspection/dataFlow/andEq","source/com/intellij/compiler/impl/resourceCompiler","testData/inspection/defUse/SCR5144/src","testData/refactoring/moveClass/jsp/after","testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1","testData/refactoring/typeCook/t142/before","source/com/intellij/help/impl","source/com/intellij/util","testData/refactoring/typeCook/t131/after","source/com/intellij/openapi/roots/ui/componentsList","testData/refactoring/moveInner/nonJavaFiles/after/pack1","testData/refactoring/typeCook/t132/after","doc/openapi/examples/vfs/src","openapi/src/com/intellij/ide","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ssh","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/common","testData/inspection/dataFlow/SCR14819","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections","source/com/intellij/refactoring/listeners/impl","testSource/com/intellij/refactoring/rename/naming","testData/refactoring/typeCook/t109/before","testData/refactoring/typeCook/t101/before","testData/refactoring/inheritanceToDelegation/abstractBase1","runtimesource/com","source/com/intellij/codeFormatting/general","source/com/intellij/refactoring/extractInterface","source/com/intellij/unscramble","javac2/src/com/intellij/uiDesigner/ant","testSource/com/intellij/util/ui","openapi/src/com/intellij/codeHighlighting","source/com/intellij/codeInsight/intention","source/com/intellij/util/ui/tree","testData/refactoring/typeCook/t136/before","testData/refactoring/typeCook/t145","testData/refactoring/typeCook/t144","testData/refactoring/typeCook/t40/after","source/com/intellij/refactoring/move","source/com/intellij/xml/actions","testData/refactoring/typeCook/t143","testData/refactoring/typeCook/t142","testData/refactoring/typeCook/t141","testData/refactoring/typeCook/t140","testData/refactoring/turnRefsToSuper/commonInheritor/before","source/com/intellij/psi/filters/getters","source/com/intellij/xml/util","testData/refactoring/typeCook/t86/after","source/com/intellij/openapi/diff/impl/incrementalMerge","source/com/intellij/refactoring/move/moveClassesOrPackages","testData/refactoring/typeCook/t78/after","testData/refactoring/typeCook/t137/after","testData/refactoring/typeCook/t136","testData/refactoring/typeCook/t135","testData/refactoring/typeCook/t134","testData/refactoring/typeCook/t133","testData/refactoring/typeCook/t139","testSource/com/intellij/refactoring/changeClassSignature","testData/refactoring/typeCook/t138","testData/refactoring/typeCook/t137","openapi/src/com/intellij/openapi/roots/ui","source/com/intellij/execution/util","testData/refactoring/typeCook/t132","testData/refactoring/typeCook/t131","source/com/intellij/psi/impl/source/resolve/reference/impl","testData/refactoring/typeCook/t130","openapi/src/com/intellij/openapi/roots/ui/configuration","source/com/intellij/debugger/ui/impl/watch","openapi/src/com/intellij/unscramble","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/log","testData/inspection/defUse/SCR6843/src","testData/refactoring/typeCook/t125","testData/refactoring/typeCook/t124","testData/refactoring/typeCook/t123","testData/refactoring/typeCook/t122","testData/refactoring/moveClass/stringsAndComments/before","testData/refactoring/typeCook/t129","testData/refactoring/typeCook/t128","testData/refactoring/typeCook/t127","testData/refactoring/typeCook/t126","testData/inspection/visibility/SCR5008/src/marti","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsRemove","testData/inspection/dataFlow/npe1","testData/refactoring/typeCook/t121","testData/refactoring/typeCook/t120","UsageView/src/com/intellij/usages/impl","openapi/src/com/intellij/psi/codeStyle","testData/refactoring/typeCook/t119","testData/refactoring/typeCook/t73/after","util/src/com","testData/refactoring/typeCook/t114","testData/refactoring/typeCook/t113","testData/refactoring/typeCook/t112","testData/refactoring/typeCook/t111","testData/refactoring/typeCook/t118","source/com/intellij/application/options","testData/refactoring/typeCook/t117","testData/refactoring/typeCook/t116","testData/refactoring/typeCook/t115","testData/refactoring/typeCook/t79/after","source/com/intellij/execution/junit2/configuration","testData/refactoring/typeCook/t110","testData/refactoring/moveInner/scr30106/before/p","testData/refactoring/typeCook/t05/before","source/com/intellij/j2ee/run/localRun","javac2/src","openapi/src/com/intellij/ide/projectView","source/com/intellij/debugger/engine/evaluation","testData/refactoring/turnRefsToSuper/scr34000/before","source/com/intellij/ide/todo/configurable","source/com/intellij/ide/hierarchy/actions","source/com/intellij/openapi/components/ex","openapi/src/com/intellij/psi/meta","testData/inspection/localCanBeFinal/SCR6744_3/src","testData/refactoring/typeCook/t82/before","testData/refactoring/typeCook/t136/after","testData/refactoring/movePackage/insidePackage/after/a","plugins/cvs2/source/com/intellij/cvsSupport2/history","testData/refactoring/moveMembers/outerClassTypeParameters","testData/refactoring/turnRefsToSuper/toArray/after","openapi/src/com/intellij/util/config","plugins/cvs2/maverick_utils/com","util/testSource/com/intellij/util/containers","UIDesignerCore/src/com/intellij","source/com/intellij/execution/runners","testData/refactoring/moveMembers/scr40064","doc/openapi/examples/vfs","testData/refactoring/typeCook/t74/after","source/com/intellij/peer","doc/openapi/examples/actions/src","testData/refactoring/typeCook/t19/after","testData/refactoring/inheritanceToDelegation/abstractBase1/before","testData/refactoring/typeCook/t82/after","testData/refactoring/migration/package/before","plugins/cvs2/source/com/intellij/cvsSupport2/impl","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/response","testData/refactoring/inheritanceToDelegation/abstractBase/before","testData/refactoring/typeCook/t32/before","testData/refactoring/typeCook/t54/before","testData/refactoring/typeCook/t76/before","plugins/conditionalOperatorConvertor/source/com/intellij/codeInsight/intention","runtimesource/com/intellij/rt/execution/application","source/com/intellij/codeInsight/hint/actions","source/com/intellij/compiler/impl/rmiCompiler","testData/refactoring/movePackageMultiroot/movePackage/after","source/com/intellij/codeInsight/template/actions","source/com/intellij/psi/presentation/java","testData/inspection/localCanBeFinal/if/src","source/com/intellij/debugger/ui/impl/tree","testData/inspection/emptyMethod/externalOverride","source/com/intellij/find/replaceInProject","source/com/intellij/openapi/fileChooser/actions","testData/refactoring/typeCook/t81/after","source/com/intellij/codeInspection/dataFlow/value","source/com/intellij/openapi/roots/ui","testData/refactoring/typeCook/t133/before","doc/openapi/examples/toolWindow/src/com/intellij/openapi/samples","testSource/com/intellij/codeInspection","testData/inspection/redundantThrow/SCR8322/src/aPackage","testData/inspection/localCanBeFinal/multiWriteNoRead","testData/inspection/emptyMethod/SCR8321/src","source/com/intellij/codeInspection/dataFlow","forms_rt/src/com","plugins/comparingReferences","openapi/src/com/intellij/execution/configurations","testData/inspection/emptyMethod/externalOverride/src","testData/refactoring/renameMethod","source/com/intellij/ide/plugins","testData/refactoring/typeCook/t92/before","source/com/intellij/openapi/editor/impl","testData/refactoring/typeCook/t43/after","testData/refactoring/inheritanceToDelegation/innerClassForInterface","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/io","testData/inspection/dataFlow/SCR14314","testData/inspection/visibility/SCR6856","testData/refactoring/inheritanceToDelegation/superCalls","source/com/intellij/j2ee/openapi/ex","testData/refactoring/inheritanceToDelegation/interfaces/after","testData/inspection/localCanBeFinal/SCR6744_5/src/foo","source/com/intellij/execution/application","source/com/intellij/debugger/actions","source/com/intellij/codeInspection/unusedReturnValue","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsEdit","source/com/intellij/codeInsight/generation/actions","source/com/intellij/codeInspection/unusedParameters","openapi/src/com/intellij/j2ee/make","testData/inspection/dataFlow/SCR14819/src","testData/inspection/dataFlow/CatchParameterCantBeNull/src","source/com/intellij/ide/errorTreeView/actions","testData/inspection/redundantThrow/SCR8322","UIDesignerCore/testSource","testData/refactoring/typeCook/t135/after","testData/refactoring/typeCook/t16/after","plugins/cvs2/source/com/intellij/cvsSupport2/ui","testData/refactoring/moveInner/scr30106/after/p","source/com/intellij/pom/core","plugins/cvs2","source/com/intellij/compiler/impl","plugins/debuggerCommonViews/src/actions","testData/inspection/redundantThrow/SCR14543/src","source/com/intellij/ide/fileTemplates","testData/refactoring/renameClass/import/before","source/com/intellij/lexer","testData/refactoring/typeCook/t114/before","testData/refactoring/typeCook/t14/after","testData/refactoring/turnRefsToSuper/superClass/before","doc/openapi/examples/actions/src/com/intellij/openapi/samples","testData/refactoring/typeCook/t133/after","source/com/intellij/psi/impl/source/html/dtd","source/com/intellij/refactoring/util/duplicates","testData/refactoring/renameClass/innerClass/after","testData/inspection/canBeFinal/methodInheritance/src","testData/inspection","plugins/cvs2/source/com/intellij/cvsSupport2/errorHandling","testSource/com/intellij/mock","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/util","testData/refactoring/moveInner/scr13730/after","pom/src","runtimesource/com/intellij/rt/compiler","doc/openapi/examples/vfs/src/com/intellij/openapi/samples","testData/psi/arrayIndexOutOfBounds/src","openapi/src/com/intellij/openapi/fileChooser","openapi/src/com/intellij/openapi/editor/event","source/com/intellij/refactoring/listeners","forms_rt/src/com/intellij","runtimesource/com/intellij/rt/execution/junit2/states","testData/refactoring/renameMethod/multi/staticImport1/after/pack2","testData/refactoring/renameMethod/multi/staticImport1/after/pack1","testData/refactoring/inheritanceToDelegation/interfaces/before","testSource/com/intellij/projectView","testData/refactoring/typeCook/t130/after","testData/refactoring/typeCook/t11/after","source/com/intellij/openapi/vfs/ex","testData/refactoring/turnRefsToSuper/commonInheritor/after","testData/refactoring/typeCook/t14/before","source/com/intellij/refactoring/copy","testData/inspection/canBeFinal/SCR7737","source/com/intellij/j2ee/module/view","plugins/cvs2/source/com/intellij/cvsSupport2/actions/cvsContext","testData/inspection/defUse/SCR40364","testData/refactoring/typeCook/t36/before","openapi/src/com/intellij/refactoring/util","testData/inspection/localCanBeFinal/SCR7601","source/com/intellij/psi/impl/source/jsp","util/src/com/intellij/util/enumeration","UIDesignerCore/src/com","testData/refactoring/movePackage/insidePackage","openapi/src/com/intellij/util/ui/tree","testData/refactoring/typeCook/t58/before","source/com/intellij/debugger/ui/breakpoints","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/ui","testData/refactoring/moveClass/stringsAndComments/after/pack2","openapi/src/com/intellij/util","source/com/intellij/openapi/vcs/ui/exclude","testData/inspection/canBeFinal","testData/refactoring/migration/unexistingClassInUnexistingPackage","testData/refactoring/turnRefsToSuper/cast/after","source/com/intellij/psi/impl/source/tree","testData/inspection/dataFlow/inst/src","testData/psi/constantValues","testData/inspection/canBeFinal/SCR6845/src","testData/refactoring/moveClass/stringsAndComments2","testData/inspection/dataFlow/thisInstanceof/src","source/com/intellij/uiDesigner/wizard","testData/refactoring/typeCook/t41/after","openapi/src/com/intellij/psi/tree/xml","source/com/intellij/xml/impl","testData/inspection/dataFlow/andEq/src","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2/connections/sshViaMaverick","testData/refactoring/migration/toNonExistentClass","source/com/intellij/psi/impl/source/xml/dtd","openapi/src/com/intellij/openapi/vcs","testData/refactoring/moveMembers/scr40947","testData/refactoring/movePackageMultiroot/movePackage/after/src1","testData/refactoring/movePackageMultiroot/movePackage/after/src2","testData/refactoring/moveInner/scr22592/before/xxx","openapi/src/com/intellij/lexer","source/com/intellij/ide/projectView/impl/nodes","testData/refactoring/turnRefsToSuper/returnValue2/after","testData/refactoring/typeCook/t67/before","source/com/intellij/openapi/fileChooser/impl","source/com/intellij/errorreport/error","util/src/com/intellij/ui","openapi/src/com/intellij/openapi/options","testData/inspection/defUse/unusedVariable/src","source/com/intellij/util/properties","source/com/intellij/codeInsight/daemon/impl/analysis","source/com/intellij/ide/structureView/impl/java","testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before","testData/refactoring/moveClass/stringsAndComments2/after/pack2","source/com/intellij/openapi/fileTypes/ex","source/com/intellij/find/impl","testData/refactoring/typeCook/t46/after","testData/refactoring/migration/package","testData/refactoring/typeCook/t17/before","openapi/src/com/intellij/peer","testData/refactoring/renameClass/nonJava/before/pack1","source/com/intellij/diagnostic","testData/inspection/dataFlow/orBug","source/com/intellij/codeInsight/folding/impl","testData/refactoring/typeCook/t45/after","source/com/intellij/codeInsight/daemon","source/com/intellij/ide/projectView/actions","source/com/intellij/execution/impl","source/com/intellij/ide","plugins/cvs2/javacvs-src/org/netbeans/lib/cvsclient/command/remove","source/com/intellij/execution/junit2/states","util/src/com/intellij/openapi","testData/inspection/dataFlow/orBug/src","source/com/intellij/execution/junit","openapi/src/com/intellij/openapi/vfs","testData/refactoring/renameField","source/com/intellij/openapi/editor/actions","source/com/intellij/psi/impl/source","testData/inspection/dataFlow/cce","testData/refactoring/typeCook/t01/before","testData/refactoring/typeCook/t111/before","source/com/intellij/internal/diGraph/analyzer","plugins/cvs2/source/com/intellij/cvsSupport2/actions/update","testData/refactoring/typeCook/t47/after","testData/refactoring/moveInner/scr22592/after/xxx","openapi/src/com/intellij/execution/process","testData/refactoring/moveMembers/weirdDeclaration","testData/refactoring/typeCook/t45/before","source/com/intellij/psi/impl/source/jsp/jspJava","plugins/cvs2/source/com/intellij/cvsSupport2/connections/ext/ui","source/com/intellij/ide/structureView/impl/common","testSource/com/intellij/util/text","source/com/intellij/openapi/vcs","source/com/intellij/openapi/ui/impl","runtimesource","plugins/conditionalOperatorConvertor/testSrc","source/com/intellij/codeInsight/intention/impl/config","doc/openapi/examples/vfs/src/com","testData/refactoring/renameMethod/multi/staticImport4/after/pack1","testData/refactoring/turnRefsToSuper/arrayElementAssignment/after","testData/refactoring/typeCook/t89/before","testData/refactoring/renameMethod/multi/staticImport4/after/pack2","source/com/intellij/openapi/vcs/update","testData/refactoring/moveClass/stringsAndComments2/before/pack1","source/com/intellij/refactoring/makeMethodStatic","source/com/intellij/execution/junit2/segments","source/com/intellij/debugger/engine","source/com/intellij/openapi/options/colors","plugins/cvs2/maverick_utils/com/intellij/cvsSupport2","testData/refactoring/turnRefsToSuper/useAsArg/after","testData/refactoring/moveMembers/scr11871/after","testData/refactoring/turnRefsToSuper/commonInheritorFail/before","javac2","plugins/cvs2/source/com/intellij/cvsSupport2/cvsExecution","source/com/intellij/openapi/diff/impl/fragments","testData/refactoring/typeCook/t105/before","testData/inspection/dataFlow/xor","testData/refactoring/typeCook/t49/after","plugins/cvs2/source/com/intellij/cvsSupport2/ui/experts/checkout","testData/refactoring/moveInner/scr13730/before","testData/refactoring/typeCook/t127/before","openapi/src/com/intellij","source/com/intellij/codeInspection/deadCode","testData/refactoring/movePackage/moveSingle/after","testData/refactoring/typeCook/t73/before","testData/refactoring/movePackage/moveSingle/before/pack1","source/com/intellij/codeInsight/generation/ui","testData/refactoring/movePackage/moveSingle/before/pack2","testData/refactoring/typeCook/t51/before","source/com/intellij/refactoring/inline","source/com/intellij/openapi/wm/impl/status","openapi/src/com/intellij/openapi/vcs/actions","testData/refactoring/typeCook/t48/after","source/com/intellij/openapi/vfs","plugins/cvs2/source/com/intellij/cvsSupport2/cvsoperations/cvsErrors","openapi/src/com/intellij/debugger/ui/tree","source/com/intellij/debugger/ui/impl/nodes","testSource/com/intellij/openapi/vcs/ui","testData/refactoring/renameClass/innerClass/before","testData/refactoring/typeCook/t95/before","testData/inspection/localCanBeFinal/incompleteAssignment/src","testData/refactoring/movePackage/qualifiedRef/after","testData/refactoring/moveMembers/innerClass","testData/refactoring/renameMethod/multi/staticImport3/before","doc/openapi/examples/plugin/src"]} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java new file mode 100644 index 00000000000..1d2d2975d39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java @@ -0,0 +1,355 @@ +package com.intellij.codeInsight.javadoc; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; +import com.intellij.util.IJSwingUtilities; +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.List; +import java.net.MalformedURLException; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: May 2, 2003 + * Time: 8:35:34 PM + * To change this template use Options | File Templates. + */ + +public class JavaDocExternalFilter { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.javadoc.JavaDocExternalFilter"); + + private Project myProject; + private PsiManager myManager; + + private static Pattern ourHTMLsuffix = Pattern.compile("[.][hH][tT][mM][lL]?"); + private static Pattern ourParentFolderprefix = Pattern.compile("^[.][.]/"); + private static Pattern ourAnchorsuffix = Pattern.compile("#(.*)$"); + private static Pattern ourHTMLFilesuffix = Pattern.compile("/[^/]*[.][hH][tT][mM][lL]?$"); + private static Pattern ourHREFselector = Pattern.compile("]*)\""); + private static Pattern ourAnnihilator = Pattern.compile("/[^/^.]*/[.][.]/"); + private static Pattern ourIMGselector = Pattern.compile("]*)\""); + + private static abstract class RefConvertor { + private Pattern mySelector; + + public RefConvertor(Pattern selector) { + mySelector = selector; + } + + protected abstract String convertReference(String root, String href); + + public String refFilter(String root, String read) { + String toMatch = read.toUpperCase(); + String ready = ""; + int prev = 0; + Matcher matcher = mySelector.matcher(toMatch); + + while (matcher.find()) { + String before = read.substring(prev, matcher.start(1) - 1); // Before reference + String href = read.substring(matcher.start(1), matcher.end(1)); // The URL + + prev = matcher.end(1) + 1; + ready += before + "\"" + convertReference(root, href) + "\""; + } + + return read = ready + read.substring(prev, read.length()); + } + } + + private RefConvertor myIMGConvertor = new RefConvertor(ourIMGselector) { + protected String convertReference(String root, String href) { + if (StringUtil.startsWithChar(href, '#')) { + return "doc_element://" + root + href; + } + + return ourHTMLFilesuffix.matcher(root).replaceAll("/") + href; + } + }; + + private RefConvertor[] myReferenceConvertors = new RefConvertor[]{ + new RefConvertor(ourHREFselector) { + protected String convertReference(String root, String href) { + if (BrowserUtil.isAbsoluteURL(href)) { + return href; + } + + if (StringUtil.startsWithChar(href, '#')) { + return "doc_element://" + root + href; + } + + String nakedRoot = ourHTMLFilesuffix.matcher(root).replaceAll("/"); + + String stripped = ourHTMLsuffix.matcher(href).replaceAll(""); + int len = stripped.length(); + + do stripped = ourParentFolderprefix.matcher(stripped).replaceAll(""); while (len > (len = stripped.length())); + + final String elementRef = stripped.replaceAll("/", "."); + final String classRef = ourAnchorsuffix.matcher(elementRef).replaceAll(""); + + return + (myManager.findClass(classRef) != null) + ? "psi_element://" + elementRef + : "doc_element://" + doAnnihilate(nakedRoot + href); + } + }, + + myIMGConvertor + }; + + public JavaDocExternalFilter(Project project) { + myProject = project; + myManager = PsiManager.getInstance(myProject); + } + + private static String doAnnihilate(String path) { + int len = path.length(); + + do { + path = ourAnnihilator.matcher(path).replaceAll("/"); + } + while (len > (len = path.length())); + + return path; + } + + private interface Waiter{ + void sayYes(); + + boolean runMe(); + } + + public static boolean isJavaDocURL(String url) { + final InputStream stream = getStreamByUrl(url); + + if (stream == null) { + return false; + } + + final Waiter waiter = new Waiter(){ + Boolean key = new Boolean(false); + Object LOCK = new Object(); + + public void sayYes(){ + key = new Boolean(true); + synchronized (LOCK) { + LOCK.notify(); + } + } + + public boolean runMe(){ + try { + synchronized (LOCK) { + LOCK.wait(600); + } + } + catch (InterruptedException e) { + return false; + } + + return key.booleanValue(); + } + }; + + new Thread(new Runnable() { + public void run() { + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + int lookUp = 6; + + while (lookUp > 0) { + if (reader.readLine().indexOf("Generated by javadoc") != -1) { + waiter.sayYes(); + } + + lookUp--; + } + + reader.close(); + } + catch (final Exception e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Cannot fetch remote source: " + e, + "IO Error", + Messages.getErrorIcon()); + } + }); + } + } + }).start(); + + return waiter.runMe(); + } + + private String correctRefs(String root, String read) { + String result = read; + + for (int i = 0; i < myReferenceConvertors.length; i++) { + result = myReferenceConvertors[i].refFilter(root, result); + } + + return result; + } + + public String filterInternalDocInfo(String text, String surl) { + if (text == null) { + return null; + } + + text = JavaDocUtil.fixupText(text); + + if (surl == null) { + return text; + } + + String root = ourAnchorsuffix.matcher(surl).replaceAll(""); + + return correctRefs(root, text); + } + + + private static InputStream getStreamByUrl(final String surl) { + try { + if (surl.startsWith("jar:")) { + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(BrowserUtil.getDocURL(surl)); + + if (file == null) { + return null; + } + + return file.getInputStream(); + } + + return BrowserUtil.getURL(surl).openStream(); + } + catch (final IOException e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Cannot fetch remote JavaDocs: " + e, + "IO Error", + Messages.getErrorIcon()); + } + }); + } + + return null; + } + + public String getExternalDocInfo(String surl) { + if (surl == null) { + return null; + } + + Matcher anchorMatcher = ourAnchorsuffix.matcher(surl); + String startSection = ""; + String endSection = "SUMMARY ======== -->"; + boolean isClassDoc = true; + + if (anchorMatcher.find()) { + isClassDoc = false; + startSection = "\n"); + + String read; + + try { + while (((read = buf.readLine()) != null) && read.toUpperCase().indexOf(startSection) == -1) ; + + if (read == null) { + return null; + } + + data.append(read); + + if (isClassDoc) { + boolean skip = false; + + while (((read = buf.readLine()) != null) && !read.toUpperCase().equals("
")) { + if (read.toUpperCase().indexOf("") != -1) { // read=class name in

+ data.append("

\n"); + skip = true; + } + else if (!skip) data.append(read); //correctRefs(root, read)); + } + + data.append("
\n"); + + StringBuffer classDetails = new StringBuffer(); + + while (((read = buf.readLine()) != null) && !read.toUpperCase().equals("
")) { + classDetails.append(read); //correctRefs(root, read)); + classDetails.append("\n"); + } + + while (((read = buf.readLine()) != null) && !read.toUpperCase().equals("

")) { + data.append(read); //correctRefs(root, read)); + data.append("\n"); + } + + data.append(classDetails); + data.append("

\n"); + } + + while (((read = buf.readLine()) != null) && read.indexOf(endSection) == -1) { + + if (read.toUpperCase().indexOf("


") == -1) { + data.append(read); //correctRefs(root, read)); + data.append("\n"); + } + } + + data.append("\n"); + + buf.close(); + } + catch (final IOException e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Cannot fetch remote JavaDocs: " + e, + "IO Error", + Messages.getErrorIcon()); + } + }); + } + + String docText = correctRefs(root, data.toString()); + + if (LOG.isDebugEnabled()) { + LOG.debug("Filtered JavaDoc: " + docText + "\n"); + } + + return JavaDocUtil.fixupText(docText); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoComponent.java new file mode 100644 index 00000000000..a6a281f642c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoComponent.java @@ -0,0 +1,510 @@ +package com.intellij.codeInsight.javadoc; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiVariable; +import com.intellij.ui.EdgeBorder; +import com.intellij.ui.LightweightHint; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.View; +import java.awt.*; +import java.awt.event.*; +import java.util.Stack; + +public class JavaDocInfoComponent extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.javadoc.JavaDocInfoComponent"); + + private static final Icon LIB_ICON_CLOSED = IconLoader.getIcon("/nodes/ppLibClosed.png"); + + private static final int MAX_WIDTH = 500; + private static final int MAX_HEIGHT = 300; + private static final int MIN_HEIGHT = 45; + + private final JavaDocManager myManager; + private PsiElement myElement; + + private Stack myBackStack = new Stack(); + private Stack myForwardStack = new Stack(); + private ActionToolbar myToolBar; + private boolean myIsEmpty; + private boolean myIsShown; + private JLabel myElementLabel; + + private static class Context { + final PsiElement element; + final String text; + final Rectangle viewRect; + + public Context(PsiElement element, String text, Rectangle viewRect) { + this.element = element; + this.text = text; + this.viewRect = viewRect; + } + } + + private JScrollPane myScrollPane; + private JEditorPane myEditorPane; + private String myText; // myEditorPane.getText() surprisingly crashes.., let's cache the text + private JPanel myControlPanel; + private boolean myControlPanelVisible; + private ExternalDocAction myExternalDocAction; + + private LightweightHint myHint; + + private HashMap myKeyboardActions = new HashMap(); // KeyStroke --> ActionListener + + public boolean requestFocusInWindow() { + return myScrollPane.requestFocusInWindow(); + } + + public JavaDocInfoComponent(final JavaDocManager manager) { + myManager = manager; + myIsEmpty = true; + myIsShown = false; + + myEditorPane = new JEditorPane("text/html", "") { + public Dimension getPreferredScrollableViewportSize() { + if (getWidth() == 0 || getHeight() == 0) { + setSize(MAX_WIDTH, MAX_HEIGHT); + } + Insets ins = myEditorPane.getInsets(); + View rootView = myEditorPane.getUI().getRootView(myEditorPane); + rootView.setSize(MAX_WIDTH, MAX_HEIGHT); // Necessary! Without this line, size will not increase then you go from small page to bigger one + int prefHeight = (int) rootView.getPreferredSpan(View.Y_AXIS); + prefHeight += ins.bottom + ins.top + myScrollPane.getHorizontalScrollBar().getMaximumSize().height; + return new Dimension(MAX_WIDTH, Math.max(MIN_HEIGHT, Math.min(MAX_HEIGHT, prefHeight))); + } + + { + enableEvents(KeyEvent.KEY_EVENT_MASK); + } + + protected void processKeyEvent(KeyEvent e) { + KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e); + ActionListener listener = (ActionListener) myKeyboardActions.get(keyStroke); + if (listener != null) { + listener.actionPerformed(new ActionEvent(JavaDocInfoComponent.this, 0, "")); + e.consume(); + return; + } + super.processKeyEvent(e); + } + }; + myText = ""; + myEditorPane.setEditable(false); + myEditorPane.setBackground(HintUtil.INFORMATION_COLOR); + + myScrollPane = new JScrollPane(myEditorPane); + myScrollPane.setBorder(null); + + myEditorPane.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + myManager.requestFocus(); + } + }); + + myEditorPane.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + Component previouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(manager.getProject()); + + if (!(previouslyFocused == myEditorPane)) { + myHint.hide(); + } + } + }); + + this.setLayout(new BorderLayout()); + this.add(myScrollPane, BorderLayout.CENTER); + this.setBorder(BorderFactory.createLineBorder(Color.black)); + + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new BackAction()); + group.add(new ForwardAction()); + group.add(myExternalDocAction = new ExternalDocAction()); + myToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.JAVADOC_TOOLBAR, group, true); + + myControlPanel = new JPanel(); + myControlPanel.setLayout(new BorderLayout()); + myControlPanel.setBorder(new EdgeBorder(EdgeBorder.EDGE_BOTTOM)); + JPanel dummyPanel = new JPanel(); + + myElementLabel = new JLabel(); + + dummyPanel.setLayout(new BorderLayout()); + dummyPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + + dummyPanel.add(myElementLabel, BorderLayout.EAST); + + myControlPanel.add(myToolBar.getComponent(), BorderLayout.WEST); + myControlPanel.add(dummyPanel, BorderLayout.CENTER); + myControlPanelVisible = false; + + myEditorPane.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + HyperlinkEvent.EventType type = e.getEventType(); + if (type == HyperlinkEvent.EventType.ACTIVATED) { + manager.navigateByLink(JavaDocInfoComponent.this, e.getDescription()); + } else if (type == HyperlinkEvent.EventType.ENTERED) { + myEditorPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } else if (type == HyperlinkEvent.EventType.EXITED) { + myEditorPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + }); + + registerActions(); + + updateControlState(); + } + + public synchronized boolean isEmpty() { + return myIsEmpty; + } + + public synchronized void startWait() { + myIsEmpty = true; + } + + private void setControlPanelVisible(boolean visible) { + if (visible == myControlPanelVisible) return; + if (visible) { + this.add(myControlPanel, BorderLayout.NORTH); + } else { + this.remove(myControlPanel); + } + myControlPanelVisible = visible; + } + + public void setHint(LightweightHint hint) { + myHint = hint; + } + + public JComponent getComponent() { + return myEditorPane; + } + + public PsiElement getElement() { + return myElement; + } + + public void setText(String text) { + setText(text, false); + } + + public void setText(String text, boolean clean) { + updateControlState(); + setDataInternal(myElement, text, new Rectangle(0, 0), true); + if (clean) { + myIsEmpty = false; + } + } + + public void setData(PsiElement element, String text) { + if (myElement != null) { + myBackStack.push(saveContext()); + myForwardStack.clear(); + } + + if (element != null) { + myElement = element; + } + + myIsEmpty = false; + updateControlState(); + setDataInternal(element, text, new Rectangle(0, 0)); + } + + private void setDataInternal(PsiElement element, String text, final Rectangle viewRect) { + setDataInternal(element, text, viewRect, false); + } + + private void setDataInternal(PsiElement element, String text, final Rectangle viewRect, boolean skip) { + boolean justShown = false; + + myElement = element; + + if (!myIsShown && myHint != null) { + myEditorPane.setText(text); + myManager.showHint(myHint); + myIsShown = justShown = true; + myManager.takeFocus(myHint); + } + + if (myHint.getComponent().getRootPane() == null) { + return; + } + + if (!justShown) { + myEditorPane.setText(text); + } + + if (!skip) { + myText = text; + } + + if (myHint != null) { + Rectangle bounds = myHint.getBounds(); + Dimension preferredSize = myHint.getComponent().getPreferredSize(); + int height = preferredSize.height; + JLayeredPane layeredPane = myHint.getComponent().getRootPane().getLayeredPane(); + + if (bounds.y + height >= layeredPane.getHeight()) { + height = layeredPane.getHeight() - bounds.y - 1; + } + + if (true){//myIsShown && !justShown) { + Point p = myManager.chooseBestHintPosition(myHint); + + if (p != null) { + myHint.setBounds(p.x, p.y, preferredSize.width, height); + } else { + myHint.setBounds(bounds.x, bounds.y, preferredSize.width, height); + } + } + } + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myEditorPane.scrollRectToVisible(viewRect); + } + }); + } + + private void goBack() { + if (myBackStack.isEmpty()) return; + Context context = (Context) myBackStack.pop(); + myForwardStack.push(saveContext()); + restoreContext(context); + updateControlState(); + } + + private void goForward() { + if (myForwardStack.isEmpty()) return; + Context context = (Context) myForwardStack.pop(); + myBackStack.push(saveContext()); + restoreContext(context); + updateControlState(); + } + + private Context saveContext() { + Rectangle rect = myScrollPane.getViewport().getViewRect(); + return new Context(myElement, myText, rect); + } + + private void restoreContext(Context context) { + setDataInternal(context.element, context.text, context.viewRect); + } + + //TODO: Move to a more proper place + public static void customizeElementLabel(final PsiElement element, final JLabel label) { + if (element != null) { + PsiFile file = element.getContainingFile(); + VirtualFile vfile = file == null ? null : file.getVirtualFile(); + + if (vfile == null) { + label.setText(""); + label.setIcon(null); + + return; + } + + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(element.getProject()).getFileIndex(); + final Module module = fileIndex.getModuleForFile(vfile); + + if (module != null) { + label.setText(module.getName()); + label.setIcon(module.getModuleType().getNodeIcon(false)); + } else { + final OrderEntry[] entries = fileIndex.getOrderEntriesForFile(vfile); + + OrderEntry entry = null; + + for (int i = 0; i < entries.length; i++) { + OrderEntry order = entries[i]; + if (order instanceof LibraryOrderEntry || order instanceof JdkOrderEntry) { + entry = order; + break; + } + } + + if (entry != null) { + label.setText(entry.getPresentableName()); + label.setIcon(LIB_ICON_CLOSED); + } + } + } + } + + private void updateControlState() { + customizeElementLabel(myElement, myElementLabel); + ((ActionToolbarEx) myToolBar).updateActions(); // update faster + setControlPanelVisible(true);//(!myBackStack.isEmpty() || !myForwardStack.isEmpty()); + } + + private class BackAction extends AnAction implements HintManager.ActionToIgnore { + public BackAction() { + super("Back", null, IconLoader.getIcon("/actions/back.png")); + } + + public void actionPerformed(AnActionEvent e) { + goBack(); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(!myBackStack.isEmpty()); + } + } + + private class ForwardAction extends AnAction implements HintManager.ActionToIgnore { + public ForwardAction() { + super("Forward", null, IconLoader.getIcon("/actions/forward.png")); + } + + public void actionPerformed(AnActionEvent e) { + goForward(); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(!myForwardStack.isEmpty()); + } + } + + private class ExternalDocAction extends AnAction implements HintManager.ActionToIgnore { + public ExternalDocAction() { + super("View External JavaDoc", null, IconLoader.getIcon("/actions/browser-externalJavaDoc.png")); + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EXTERNAL_JAVADOC).getShortcutSet(), null); + } + + public void actionPerformed(AnActionEvent e) { + if (myElement != null) { + myManager.openJavaDoc(myElement); + } + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myElement != null); + if (myElement instanceof PsiVariable && !(myElement instanceof PsiField)) { + presentation.setEnabled(false); + } + } + } + + private void registerActions() { + myExternalDocAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EXTERNAL_JAVADOC).getShortcutSet(), + myEditorPane); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + int value = scrollBar.getValue() - scrollBar.getUnitIncrement(-1); + value = Math.max(value, 0); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + int value = scrollBar.getValue() + scrollBar.getUnitIncrement(+1); + value = Math.min(value, scrollBar.getMaximum()); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getHorizontalScrollBar(); + int value = scrollBar.getValue() - scrollBar.getUnitIncrement(-1); + value = Math.max(value, 0); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getHorizontalScrollBar(); + int value = scrollBar.getValue() + scrollBar.getUnitIncrement(+1); + value = Math.min(value, scrollBar.getMaximum()); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + int value = scrollBar.getValue() - scrollBar.getBlockIncrement(-1); + value = Math.max(value, 0); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + int value = scrollBar.getValue() + scrollBar.getBlockIncrement(+1); + value = Math.min(value, scrollBar.getMaximum()); + scrollBar.setValue(value); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getHorizontalScrollBar(); + scrollBar.setValue(0); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getHorizontalScrollBar(); + scrollBar.setValue(scrollBar.getMaximum()); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, KeyEvent.CTRL_MASK), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + scrollBar.setValue(0); + } + }); + + myKeyboardActions.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, KeyEvent.CTRL_MASK), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JScrollBar scrollBar = myScrollPane.getVerticalScrollBar(); + scrollBar.setValue(scrollBar.getMaximum()); + } + }); + } + + public String getText() { + return myText; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java new file mode 100644 index 00000000000..93e79292662 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -0,0 +1,1268 @@ +package com.intellij.codeInsight.javadoc; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class JavaDocInfoGenerator { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.javadoc.JavaDocInfoGenerator"); + + private static final Pattern ourNotDot = Pattern.compile("[^.]"); + private static final Pattern ourWhitespaces = Pattern.compile("[ \\n\\r\\t]+"); + private static final Matcher ourNotDotMatcher = ourNotDot.matcher(""); + private static final Matcher ourWhitespacesMatcher = ourWhitespaces.matcher(""); + + private Project myProject; + private PsiElement myElement; + private JavaDocManager.DocumentationProvider myProvider; + + interface InheritDocProvider { + Pair> getInheritDoc(); + + PsiClass getElement(); + } + + private static final InheritDocProvider ourEmptyProvider = new InheritDocProvider() { + public Pair> getInheritDoc() { + return null; + } + + public PsiClass getElement() { + return null; + } + }; + + private static final InheritDocProvider ourEmptyElementsProvider = mapProvider(ourEmptyProvider, false); + + private static InheritDocProvider mapProvider(final InheritDocProvider i, + final boolean dropFirst) { + return new InheritDocProvider() { + public Pair> getInheritDoc() { + Pair> pair = i.getInheritDoc(); + + if (pair == null) { + return null; + } + + PsiElement[] elements; + PsiElement[] rawElements = pair.first.getDataElements(); + + if (dropFirst && rawElements != null && rawElements.length > 0) { + elements = new PsiElement[rawElements.length - 1]; + + for (int i = 0; i < elements.length; i++) { + elements[i] = rawElements[i + 1]; + } + } + else { + elements = rawElements; + } + + return new Pair>(elements, mapProvider(pair.second, dropFirst)); + } + + public PsiClass getElement() { + return i.getElement(); + } + }; + } + + interface DocTagLocator { + T find(PsiDocComment comment); + } + + private DocTagLocator parameterLocator(final String name) { + return new DocTagLocator() { + public PsiDocTag find(PsiDocComment comment) { + if (comment == null) { + return null; + } + + PsiDocTag[] tags = comment.findTagsByName("param"); + + for (int i = 0; i < tags.length; i++) { + PsiDocTag tag = tags[i]; + PsiDocTagValue value = tag.getValueElement(); + + if (value != null) { + String text = value.getText(); + + if (text != null && text.equals(name)) { + return tag; + } + } + } + + return null; + } + }; + } + + private DocTagLocator exceptionLocator(final String name) { + return new DocTagLocator() { + public PsiDocTag find(PsiDocComment comment) { + if (comment == null) { + return null; + } + + PsiDocTag[] tags = getThrowsTags(comment); + + for (int i = 0; i < tags.length; i++) { + PsiDocTag tag = tags[i]; + PsiDocTagValue value = tag.getValueElement(); + + if (value != null) { + String text = value.getText(); + + if (text != null && areWeakEqual(text, name)) { + return tag; + } + } + } + + return null; + } + }; + } + + public JavaDocInfoGenerator(Project project, PsiElement element,JavaDocManager.DocumentationProvider _provider) { + myProject = project; + myElement = element; + myProvider = _provider; + } + + public String generateDocInfo() { + StringBuffer buffer = new StringBuffer(); + if (myElement instanceof PsiClass) { + generateClassJavaDoc(buffer, (PsiClass)myElement); + } + else if (myElement instanceof PsiMethod) { + generateMethodJavaDoc(buffer, (PsiMethod)myElement); + } + else if (myElement instanceof PsiField) { + generateFieldJavaDoc(buffer, (PsiField)myElement); + } + else if (myElement instanceof PsiVariable) { + generateVariableJavaDoc(buffer, (PsiVariable)myElement); + } + else if (myElement instanceof PsiFile) { + generateFileJavaDoc(buffer, (PsiFile)myElement); //used for Ctrl-Click + } + else { + if (myProvider!=null) { + return myProvider.generateDoc(myElement,myElement.getUserData(JavaDocManager.ORIGINAL_ELEMENT_KEY)); + } + return null; + } + String text = buffer.toString(); + if (text.length() == 0) { + return null; + } + if (LOG.isDebugEnabled()) { + LOG.debug("Generated JavaDoc:"); + LOG.debug(text); + } + + text = StringUtil.replace(text, "/>", ">"); + + return text; + } + + private void generateClassJavaDoc(StringBuffer buffer, PsiClass aClass) { + if (aClass instanceof PsiAnonymousClass) return; + PsiManager manager = aClass.getManager(); + generatePrologue(buffer); + + PsiFile file = aClass.getContainingFile(); + if (file instanceof PsiJavaFile) { + String packageName = ((PsiJavaFile)file).getPackageName(); + if (packageName.length() > 0) { + buffer.append(""); + buffer.append(packageName); + buffer.append(""); + //buffer.append("
"); + } + } + + buffer.append("
");
+    String modifiers = PsiFormatUtil.formatModifiers(aClass, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);
+    if (modifiers.length() > 0) {
+      buffer.append(modifiers);
+      buffer.append(" ");
+    }
+    buffer.append(aClass.isInterface() ? "interface" : "class");
+    buffer.append(" ");
+    String refText = JavaDocUtil.getReferenceText(myProject, aClass);
+    if (refText == null) {
+      buffer.setLength(0);
+      return;
+    }
+    String labelText = JavaDocUtil.getLabelText(myProject, manager, refText, aClass);
+    buffer.append("");
+    buffer.append(labelText);
+    buffer.append("");
+
+    buffer.append(generateTypeParameters(aClass));
+
+    buffer.append("\n");
+
+    PsiClassType[] refs = JavaDocUtil.getExtendsList(aClass);
+
+    String qName = aClass.getQualifiedName();
+
+    if (refs.length > 0 || !aClass.isInterface() && (qName == null || !qName.equals("java.lang.Object"))) {
+      buffer.append("extends ");
+      if (refs.length == 0) {
+        generateLink(buffer, "java.lang.Object", null, aClass, false);
+      }
+      else {
+        for (int i = 0; i < refs.length; i++) {
+          generateType(buffer, refs[i], aClass);
+          if (i < refs.length - 1) {
+            buffer.append(", ");
+          }
+        }
+      }
+      buffer.append("\n");
+    }
+
+    refs = JavaDocUtil.getImplementsList(aClass);
+
+    if (refs.length > 0) {
+      buffer.append("implements ");
+      for (int i = 0; i < refs.length; i++) {
+        generateType(buffer, refs[i], aClass);
+        if (i < refs.length - 1) {
+          buffer.append(", ");
+        }
+      }
+      buffer.append("\n");
+    }
+    if (buffer.charAt(buffer.length() - 1) == '\n') {
+      buffer.setLength(buffer.length() - 1);
+    }
+    buffer.append("
"); + //buffer.append("
"); + + PsiDocComment comment = aClass.getDocComment(); + if (comment != null) { + generateDescription(buffer, comment); + generateDeprecatedSection(buffer, comment); + generateSinceSection(buffer, comment); + generateSeeAlsoSection(buffer, comment); + } + + generateEpilogue(buffer); + } + + private void generateFieldJavaDoc(StringBuffer buffer, PsiField field) { + generatePrologue(buffer); + + PsiClass parentClass = field.getContainingClass(); + if (parentClass != null) { + String qName = parentClass.getQualifiedName(); + if (qName != null) { + buffer.append(""); + //buffer.append(qName); + generateLink(buffer, qName, qName, field, false); + buffer.append(""); + //buffer.append("
"); + } + } + + buffer.append("
");
+    String modifiers = PsiFormatUtil.formatModifiers(field, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);
+    if (modifiers.length() > 0) {
+      buffer.append(modifiers);
+      buffer.append(" ");
+    }
+    generateType(buffer, field.getType(), field);
+    buffer.append(" ");
+    buffer.append("");
+    buffer.append(field.getName());
+    appendInitializer(buffer, field);
+    buffer.append("");
+    buffer.append("
"); + //buffer.append("
"); + + PsiDocComment comment = field.getDocComment(); + if (comment != null) { + generateDescription(buffer, comment); + generateDeprecatedSection(buffer, comment); + generateSinceSection(buffer, comment); + generateSeeAlsoSection(buffer, comment); + } + + generateEpilogue(buffer); + } + + // not a javadoc in fact.. + private void generateVariableJavaDoc(StringBuffer buffer, PsiVariable variable) { + generatePrologue(buffer); + + buffer.append("
");
+    String modifiers = PsiFormatUtil.formatModifiers(variable, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);
+    if (modifiers.length() > 0) {
+      buffer.append(modifiers);
+      buffer.append(" ");
+    }
+    generateType(buffer, variable.getType(), variable);
+    buffer.append(" ");
+    buffer.append("");
+    buffer.append(variable.getName());
+    appendInitializer(buffer, variable);
+    buffer.append("");
+    buffer.append("
"); + //buffer.append("
"); + + generateEpilogue(buffer); + } + + // not a javadoc in fact.. + private void generateFileJavaDoc(StringBuffer buffer, PsiFile file) { + generatePrologue(buffer); + buffer.append(file.getVirtualFile().getPresentableUrl()); + generateEpilogue(buffer); + } + + private void appendInitializer(StringBuffer buffer, PsiVariable variable) { + PsiExpression initializer = variable.getInitializer(); + if (initializer != null) { + String text = initializer.getText(); + text = text.trim(); + int index1 = text.indexOf('\n'); + if (index1 < 0) index1 = text.length(); + int index2 = text.indexOf('\r'); + if (index2 < 0) index2 = text.length(); + int index = Math.min(index1, index2); + boolean trunc = index < text.length(); + text = text.substring(0, index); + buffer.append(" = "); + text = StringUtil.replace(text, "<", "<"); + text = StringUtil.replace(text, ">", ">"); + buffer.append(text); + if (trunc) { + buffer.append("..."); + } + } + } + + private void generateMethodJavaDoc(StringBuffer buffer, PsiMethod method) { + generatePrologue(buffer); + + PsiClass parentClass = method.getContainingClass(); + if (parentClass != null) { + String qName = parentClass.getQualifiedName(); + if (qName != null) { + buffer.append(""); + generateLink(buffer, qName, qName, method, false); + //buffer.append(qName); + buffer.append(""); + //buffer.append("
"); + } + } + + buffer.append("
");
+    int indent = 0;
+    String modifiers = PsiFormatUtil.formatModifiers(method, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);
+    if (modifiers.length() > 0) {
+      buffer.append(modifiers);
+      buffer.append(" ");
+      indent += modifiers.length() + 1;
+    }
+
+    PsiTypeParameter[] params = method.getTypeParameterList().getTypeParameters();
+
+    if (params.length > 0) {
+      buffer.append("<");
+      for (int i = 0; i < params.length; i++) {
+        PsiTypeParameter param = params[i];
+
+        buffer.append(param.getName());
+
+        PsiClassType[] extendees = JavaDocUtil.getExtendsList(param);
+
+        if (extendees.length > 0) {
+          buffer.append(" extends ");
+
+          for (int j = 0; j < extendees.length; j++) {
+            generateType(buffer, extendees[j], method);
+
+            if (j < extendees.length - 1) {
+              buffer.append(" & ");
+            }
+          }
+        }
+
+        if (i < params.length - 1) {
+          buffer.append(", ");
+        }
+      }
+      buffer.append("> ");
+    }
+
+    if (method.getReturnType() != null) {
+      indent += generateType(buffer, method.getReturnType(), method);
+      buffer.append(" ");
+      indent++;
+    }
+    buffer.append("");
+    String name = method.getName();
+    buffer.append(name);
+    buffer.append("");
+    indent += name.length();
+
+    buffer.append("(");
+    indent++;
+    indent--;//???
+    PsiParameter[] parms = method.getParameterList().getParameters();
+    for (int i = 0; i < parms.length; i++) {
+      PsiParameter parm = parms[i];
+      generateType(buffer, parm.getType(), method);
+      buffer.append(" ");
+      if (parm.getName() != null) {
+        buffer.append(parm.getName());
+      }
+      if (i < parms.length - 1) {
+        buffer.append(",\n");
+        for (int j = 0; j < indent; j++) {
+          buffer.append(" ");
+        }
+      }
+    }
+    buffer.append(")");
+
+    PsiClassType[] refs = method.getThrowsList().getReferencedTypes();
+    if (refs.length > 0) {
+      buffer.append("\n");
+      indent -= "throws".length() + 1;
+      for (int i = 0; i < indent; i++) {
+        buffer.append(" ");
+      }
+      indent += "throws".length() + 1;
+      buffer.append("throws ");
+      for (int i = 0; i < refs.length; i++) {
+        generateLink(buffer, refs[i].getCanonicalText(), null, method, false);
+        if (i < refs.length - 1) {
+          buffer.append(",\n");
+          for (int j = 0; j < indent; j++) {
+            buffer.append(" ");
+          }
+        }
+      }
+    }
+
+    buffer.append("
"); + //buffer.append("
"); + + PsiDocComment comment = method.getDocComment(); + + generateMethodDescription(buffer, method); + + generateSuperMethodsSection(buffer, method, false); + generateSuperMethodsSection(buffer, method, true); + + if (comment != null) { + generateDeprecatedSection(buffer, comment); + } + + generateParametersSection(buffer, method); + generateReturnsSection(buffer, method); + generateThrowsSection(buffer, method); + + if (comment != null) { + generateSinceSection(buffer, comment); + generateSeeAlsoSection(buffer, comment); + } + + generateEpilogue(buffer); + } + + private void generatePrologue(StringBuffer buffer) { + buffer.append(""); + } + + private void generateEpilogue(StringBuffer buffer) { + while (true) { + if (buffer.length() < "
".length()) break; + char c = buffer.charAt(buffer.length() - 1); + if (c == '\n' || c == '\r' || c == ' ' || c == '\t') { + buffer.setLength(buffer.length() - 1); + continue; + } + String tail = buffer.substring(buffer.length() - "
".length()); + if (tail.equalsIgnoreCase("
")) { + buffer.setLength(buffer.length() - "
".length()); + continue; + } + break; + } + buffer.append(""); + } + + private void generateDescription(StringBuffer buffer, PsiDocComment comment) { + PsiElement[] elements = comment.getDescriptionElements(); + generateValue(buffer, elements, ourEmptyElementsProvider); + } + + private boolean isEmptyDescription(PsiDocComment comment) { + PsiElement[] description = comment.getDescriptionElements(); + + for (int i = 0; i < description.length; i++) { + String text = description[i].getText(); + + if (text != null) { + if (ourWhitespacesMatcher.reset(text).replaceAll("").length() != 0) { + return false; + } + } + } + + return true; + } + + private void generateMethodDescription(StringBuffer buffer, final PsiMethod method) { + final DocTagLocator descriptionLocator = new DocTagLocator() { + public PsiElement[] find(PsiDocComment comment) { + if (comment == null) { + return null; + } + + if (isEmptyDescription(comment)) { + return null; + } + + return comment.getDescriptionElements(); + } + }; + + PsiDocComment comment = method.getDocComment(); + + if (comment != null) { + if (!isEmptyDescription(comment)) { + generateValue + (buffer, comment.getDescriptionElements(), + new InheritDocProvider() { + public Pair> getInheritDoc() { + return findInheritDocTag(method, descriptionLocator); + } + + public PsiClass getElement() { + return method.getContainingClass(); + } + }); + return; + } + } + + Pair> pair = findInheritDocTag(method, descriptionLocator); + + if (pair != null) { + PsiElement[] elements = pair.first; + PsiClass extendee = pair.second.getElement(); + + if (elements != null) { + buffer.append("
"); + buffer.append("
"); + buffer.append("Description copied from " + (extendee.isInterface() ? "interface: " : "class: ")); + buffer.append(""); + generateLink(buffer, extendee, JavaDocUtil.getShortestClassName(extendee, method)); + buffer.append("
"); + generateValue(buffer, elements, pair.second); + buffer.append("
"); + } + } + } + + private void generateValue(StringBuffer buffer, PsiElement[] elements, InheritDocProvider provider) { + generateValue(buffer, elements, 0, provider); + } + + private String getDocRoot() { + PsiClass aClass = null; + + if (myElement instanceof PsiClass) { + aClass = (PsiClass)myElement; + } + else if (myElement instanceof PsiMember) { + aClass = ((PsiMember)myElement).getContainingClass(); + } + else { + LOG.error("Class or member expected but found " + myElement.getClass().getName()); + } + + String qName = aClass.getQualifiedName(); + + if (qName == null) { + return ""; + } + + return "../" + ourNotDotMatcher.reset(qName).replaceAll("").replaceAll(".", "../"); + } + + private void generateValue(StringBuffer buffer, + PsiElement[] elements, + int startIndex, + InheritDocProvider provider) { + int predictOffset = + startIndex < elements.length ? + elements[startIndex].getTextOffset() + elements[startIndex].getText().length() : + 0; + + for (int i = startIndex; i < elements.length; i++) { + if (elements[i].getTextOffset() > predictOffset) buffer.append(" "); + predictOffset = elements[i].getTextOffset() + elements[i].getText().length(); + PsiElement element = elements[i]; + if (element instanceof PsiInlineDocTag) { + PsiInlineDocTag tag = (PsiInlineDocTag)element; + if (tag.getName().equals("link")) { + generateLinkValue(tag, buffer, false); + } + else if (tag.getName().equals("literal")) { + generateLiteralValue(tag, buffer); + } + else if (tag.getName().equals("code")) { + generateCodeValue(tag, buffer); + } + else if (tag.getName().equals("linkplain")) { + generateLinkValue(tag, buffer, true); + } + else if (tag.getName().equals("inheritDoc")) { + Pair> inheritInfo = provider.getInheritDoc(); + + if (inheritInfo != null) { + generateValue(buffer, inheritInfo.first, inheritInfo.second); + } + } + else if (tag.getName().equals("docRoot")) { + buffer.append(getDocRoot()); + } + else { + buffer.append(element.getText()); + } + } + else { + buffer.append(element.getText()); + } + } + } + + private void generateCodeValue(PsiInlineDocTag tag, StringBuffer buffer) { + buffer.append(""); + generateLiteralValue(tag, buffer); + buffer.append(""); + } + + private void generateLiteralValue(PsiInlineDocTag tag, StringBuffer buffer) { + PsiElement[] elements = tag.getDataElements(); + + for (int i = 0; i < elements.length; i++) { + String text = elements[i].getText(); + + text = text.replaceAll("<", "<"); + text = text.replaceAll(">", ">"); + + buffer.append(text); + } + } + + private void generateLinkValue(PsiInlineDocTag tag, StringBuffer buffer, boolean plainLink) { + PsiElement[] tagElements = tag.getDataElements(); + int predictOffset = tagElements.length > 0 + ? tagElements[0].getTextOffset() + tagElements[0].getText().length() + : 0; + StringBuffer buffer1 = new StringBuffer(); + for (int j = 0; j < tagElements.length; j++) { + PsiElement tagElement = tagElements[j]; + + if (tagElement.getTextOffset() > predictOffset) buffer1.append(" "); + predictOffset = tagElement.getTextOffset() + tagElement.getText().length(); + + buffer1.append(tagElement.getText()); + + if (j < tagElements.length - 1) { + buffer1.append(" "); + } + } + String text = buffer1.toString().trim(); + if (text.length() > 0) { + int index = JavaDocUtil.extractReference(text); + String refText = text.substring(0, index).trim(); + String label = text.substring(index).trim(); + if (label.length() == 0) { + label = null; + } + generateLink(buffer, refText, label, tagElements[0], plainLink); + } + } + + private void generateDeprecatedSection(StringBuffer buffer, PsiDocComment comment) { + PsiDocTag tag = comment.findTagByName("deprecated"); + if (tag != null) { + buffer.append("
"); + buffer.append("Deprecated. "); + buffer.append(""); + generateValue(buffer, tag.getDataElements(), ourEmptyElementsProvider); + buffer.append(""); + buffer.append("
"); + } + } + + private void generateSinceSection(StringBuffer buffer, PsiDocComment comment) { + PsiDocTag tag = comment.findTagByName("since"); + if (tag != null) { + buffer.append("
"); + buffer.append("
Since:"); + buffer.append("
"); + generateValue(buffer, tag.getDataElements(), ourEmptyElementsProvider); + buffer.append("
"); + } + } + + private void generateSeeAlsoSection(StringBuffer buffer, PsiDocComment comment) { + PsiDocTag[] tags = comment.findTagsByName("see"); + if (tags.length > 0) { + buffer.append("
"); + buffer.append("
See Also:"); + buffer.append("
"); + for (int i = 0; i < tags.length; i++) { + PsiDocTag tag = tags[i]; + PsiElement[] elements = tag.getDataElements(); + if (elements.length > 0) { + String text = elements[0].getText(); + if (StringUtil.startsWithChar(text, '\"') || StringUtil.startsWithChar(text, '<')) { + buffer.append(text); + } + else { + int index = JavaDocUtil.extractReference(text); + String refText = text.substring(0, index).trim(); + String label = text.substring(index).trim(); + if (label.length() == 0) { + label = null; + } + generateLink(buffer, refText, label, comment, false); + } + generateValue(buffer, elements, 1, ourEmptyElementsProvider); + } + if (i < tags.length - 1) { + buffer.append(",\n"); + } + } + buffer.append("
"); + } + } + + private void generateParametersSection(StringBuffer buffer, final PsiMethod method) { + PsiDocComment comment = method.getDocComment(); + PsiParameter[] params = method.getParameterList().getParameters(); + PsiDocTag[] localTags = comment != null ? localTags = comment.findTagsByName("param") : PsiDocTag.EMPTY_ARRAY; + + LinkedList>> collectedTags = + new LinkedList>>(); + + for (int i = 0; i < params.length; i++) { + final String paramName = params[i].getName(); + Pair> parmTag = null; + + for (int j = 0; j < localTags.length; j++) { + PsiDocTag localTag = localTags[j]; + PsiDocTagValue value = localTag.getValueElement(); + + if (value != null) { + String tagName = value.getText(); + + if (tagName != null && tagName.equals(paramName)) { + parmTag = + new Pair> + (localTag, + new InheritDocProvider() { + public Pair> getInheritDoc() { + return findInheritDocTag(method, parameterLocator(paramName)); + } + + public PsiClass getElement() { + return method.getContainingClass(); + } + }); + break; + } + } + } + + if (parmTag == null) { + parmTag = findInheritDocTag(method, parameterLocator(paramName)); + } + + if (parmTag != null) { + collectedTags.addLast(parmTag); + } + } + + if (collectedTags.size() > 0) { + buffer.append("
"); + buffer.append("
Parameters:"); + for (Iterator>> i = collectedTags.iterator(); i.hasNext();) { + Pair> tag = i.next(); + PsiElement[] elements = tag.first.getDataElements(); + if (elements.length == 0) continue; + String text = elements[0].getText(); + buffer.append("
"); + int spaceIndex = text.indexOf(' '); + if (spaceIndex < 0) { + spaceIndex = text.length(); + } + String parmName = text.substring(0, spaceIndex); + buffer.append(""); + buffer.append(parmName); + buffer.append(""); + buffer.append(" - "); + buffer.append(text.substring(spaceIndex)); + generateValue(buffer, elements, 1, mapProvider(tag.second, true)); + } + buffer.append("
"); + } + } + + private void generateReturnsSection(StringBuffer buffer, PsiMethod method) { + PsiDocComment comment = method.getDocComment(); + PsiDocTag tag = comment == null ? null : comment.findTagByName("return"); + Pair> pair = + tag == null ? null : new Pair>(tag, ourEmptyProvider); + + if (pair == null && myElement instanceof PsiMethod) { + pair = findInheritDocTag(((PsiMethod)myElement), new DocTagLocator() { + public PsiDocTag find(PsiDocComment comment) { + if (comment == null) { + return null; + } + + return comment.findTagByName("return"); + } + }); + } + + if (pair != null) { + buffer.append("
"); + buffer.append("
Returns:"); + buffer.append("
"); + generateValue(buffer, pair.first.getDataElements(), mapProvider(pair.second, false)); + buffer.append("
"); + } + } + + private PsiDocTag[] getThrowsTags(PsiDocComment comment) { + if (comment == null) { + return PsiDocTag.EMPTY_ARRAY; + } + + PsiDocTag[] tags1 = comment.findTagsByName("throws"); + PsiDocTag[] tags2 = comment.findTagsByName("exception"); + + return ArrayUtil.mergeArrays(tags1, tags2, PsiDocTag.class); + } + + private static boolean areWeakEqual(String one, String two) { + return one.equals(two) || one.endsWith(two) || two.endsWith(one); + } + + private void generateThrowsSection(StringBuffer buffer, PsiMethod method) { + PsiDocComment comment = method.getDocComment(); + PsiDocTag[] localTags = getThrowsTags(comment); + + LinkedList>> collectedTags = + new LinkedList>>(); + + LinkedList holder = new LinkedList(Arrays.asList(method.getThrowsList().getReferencedTypes())); + + for (int i = localTags.length - 1; i > -1; i--) { + try { + PsiDocTagValue valueElement = localTags[i].getValueElement(); + + if (valueElement != null) { + PsiClassType t = (PsiClassType)method.getManager().getElementFactory().createTypeFromText(valueElement.getText(), method); + + if (!holder.contains(t)) { + holder.addFirst(t); + } + } + } + catch (IncorrectOperationException e) { + LOG.error("Incorrect operation exception."); + } + } + + PsiClassType[] trousers = holder.toArray(new PsiClassType[holder.size()]); + + for (int i = 0; i < trousers.length; i++) { + if (trousers[i] != null) { + String paramName = trousers[i].getCanonicalText(); + Pair> parmTag = null; + + for (int j = 0; j < localTags.length; j++) { + PsiDocTag localTag = localTags[j]; + PsiDocTagValue value = localTag.getValueElement(); + + if (value != null) { + String tagName = value.getText(); + + if (tagName != null && areWeakEqual(tagName, paramName)) { + parmTag = new Pair>(localTag, ourEmptyProvider); + break; + } + } + } + + if (parmTag == null) { + parmTag = findInheritDocTag(method, exceptionLocator(paramName)); + } + + if (parmTag != null) { + collectedTags.addLast(parmTag); + } + else { + try { + final PsiDocTag tag = method.getManager().getElementFactory().createDocCommentFromText("/** @exception " + paramName + " */", + method.getContainingFile()).getTags()[0]; + + collectedTags.addLast(new Pair>(tag, ourEmptyProvider)); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + } + + if (collectedTags.size() > 0) { + buffer.append("
"); + buffer.append("
Throws:"); + for (Iterator>> i = collectedTags.iterator(); i.hasNext();) { + Pair> tag = i.next(); + PsiElement[] elements = tag.first.getDataElements(); + if (elements.length == 0) continue; + buffer.append("
"); + String text = elements[0].getText(); + int index = JavaDocUtil.extractReference(text); + String refText = text.substring(0, index).trim(); + generateLink(buffer, refText, null, method, false); + String rest = text.substring(index); + if (rest.length() > 0 || elements.length > 1) buffer.append(" - "); + buffer.append(rest); + generateValue(buffer, elements, 1, mapProvider(tag.second, true)); + } + buffer.append("
"); + } + } + + private void generateSuperMethodsSection(StringBuffer buffer, PsiMethod method, boolean overrides) { + PsiClass parentClass = method.getContainingClass(); + if (parentClass == null) return; + if (parentClass.isInterface() && !overrides) return; + PsiMethod[] supers = PsiSuperMethodUtil.findSuperMethods(method); + if (supers.length == 0) return; + boolean headerGenerated = false; + for (int i = 0; i < supers.length; i++) { + PsiMethod superMethod = supers[i]; + boolean isAbstract = superMethod.hasModifierProperty(PsiModifier.ABSTRACT); + if (overrides) { + if (parentClass.isInterface() ? !isAbstract : isAbstract) continue; + } + else { + if (!isAbstract) continue; + } + PsiClass superClass = superMethod.getContainingClass(); + if (!headerGenerated) { + buffer.append("
"); + buffer.append("
"); + buffer.append(overrides ? "Overrides:" : "Specified by:"); + buffer.append(""); + headerGenerated = true; + } + buffer.append("
"); + + generateLink(buffer, superMethod, superMethod.getName()); + buffer.append(" in "); + buffer.append(superClass.isInterface() ? "interface " : "class "); + generateLink(buffer, superClass, superClass.getName()); + } + if (headerGenerated) { + buffer.append("
"); + } + } + + private void generateLink(StringBuffer buffer, PsiElement element, String label) { + String refText = JavaDocUtil.getReferenceText(myProject, element); + if (refText != null) { + JavaDocUtil.createHyperlink(buffer, refText,label,false); + //return generateLink(buffer, refText, label, context, false); + } + } + + /** + * @return Length of the generated label. + */ + private int generateLink(StringBuffer buffer, String refText, String label, PsiElement context, boolean plainLink) { + if (label == null) { + PsiManager manager = PsiManager.getInstance(myProject); + label = JavaDocUtil.getLabelText(myProject, manager, refText, context); + } + + LOG.assertTrue(refText != null, "refText appears to be null."); + + boolean isBrokenLink = JavaDocUtil.findReferenceTarget(context.getManager(), refText, context) == null; + if (isBrokenLink) { + buffer.append(""); + buffer.append(label); + buffer.append(""); + return label.length(); + } + + + JavaDocUtil.createHyperlink(buffer, refText,label,plainLink); + return label.length(); + } + + /** + * @return Length of the generated label. + */ + private int generateType(StringBuffer buffer, PsiType type, PsiElement context) { + if (type instanceof PsiPrimitiveType) { + String text = type.getCanonicalText(); + buffer.append(text); + return text.length(); + } + + if (type instanceof PsiArrayType) { + int rest = generateType(buffer, ((PsiArrayType)type).getComponentType(), context); + buffer.append("[]"); + return rest + 2; + } + + if (type instanceof PsiWildcardType){ + PsiWildcardType wt = ((PsiWildcardType)type); + + buffer.append("?"); + + PsiType bound = wt.getBound(); + + if (bound != null){ + final String keyword = wt.isExtends() ? " extends " : " super "; + buffer.append(keyword); + return generateType(buffer, bound, context) + 1 + keyword.length(); + } + + return 1; + } + + if (type instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics(); + PsiClass psiClass = result.getElement(); + PsiSubstitutor psiSubst = result.getSubstitutor(); + + if (psiClass == null) { + String text = "" + type.getCanonicalText() + ""; + buffer.append(text); + return text.length(); + } + + String qName = psiClass.getQualifiedName(); + + if (qName == null || psiClass instanceof PsiTypeParameter) { + String text = type.getCanonicalText(); + buffer.append(text); + return text.length(); + } + + int length = generateLink(buffer, qName, null, context, false); + + if (psiClass.hasTypeParameters()) { + StringBuffer subst = new StringBuffer(); + boolean goodSubst = true; + + PsiTypeParameter[] params = psiClass.getTypeParameterList().getTypeParameters(); + + subst.append("<"); + for (int i = 0; i < params.length; i++) { + PsiType t = psiSubst.substitute(params[i]); + + if (t == null) { + goodSubst = false; + break; + } + + generateType(subst, t, context); + + if (i < params.length - 1) { + subst.append(", "); + } + } + + if (goodSubst) { + subst.append(">"); + String text = subst.toString(); + + buffer.append(text); + length += text.length(); + } + } + + return length; + } + + return 0; + } + + private String generateTypeParameters(PsiClass aClass) { + if (aClass.hasTypeParameters()) { + PsiTypeParameterList list = aClass.getTypeParameterList(); + + if (list == null) return ""; + + PsiTypeParameter[] parms = list.getTypeParameters(); + + StringBuffer buffer = new StringBuffer(); + + buffer.append("<"); + + for (int i = 0; i < parms.length; i++) { + PsiTypeParameter p = parms[i]; + + buffer.append(p.getName()); + + PsiClassType[] refs = JavaDocUtil.getExtendsList(p); + + if (refs.length > 0) { + buffer.append(" extends "); + + for (int j = 0; j < refs.length; j++) { + generateType(buffer, refs[j], aClass); + + if (j < refs.length - 1) { + buffer.append(" & "); + } + } + } + + if (i < parms.length - 1) { + buffer.append(", "); + } + } + + buffer.append(">"); + + return buffer.toString(); + } + + return ""; + } + + private Pair> searchDocTagInOverridenMethod(PsiMethod method, + final PsiClass extendee, + final DocTagLocator loc) { + if (extendee != null) { + final PsiMethod overriden = extendee.findMethodBySignature(method, false); + + if (overriden != null) { + T tag = loc.find(overriden.getDocComment()); + + if (tag != null) { + return new Pair> + (tag, + new InheritDocProvider() { + public Pair> getInheritDoc() { + return findInheritDocTag(overriden, loc); + } + + public PsiClass getElement() { + return extendee; + } + }); + } + } + } + + return null; + } + + private Pair> searchDocTagInExtendees(PsiClassType[] exts, + PsiMethod method, + DocTagLocator loc, + boolean deep) { + for (int i = 0; i < exts.length; i++) { + PsiClass extendee = exts[i].resolve(); + + if (extendee != null) { + Pair> tag = searchDocTagInOverridenMethod(method, extendee, loc); + + if (tag != null) { + return tag; + } + + if (deep) { + tag = findInheritDocTagInClass(method, extendee, loc); + + if (tag != null) { + return tag; + } + } + } + } + + return null; + } + + private Pair> findInheritDocTagInClass(PsiMethod aMethod, + PsiClass aClass, + DocTagLocator loc) { + if (aClass == null) { + return null; + } + + PsiClassType[] implementee = JavaDocUtil.getImplementsList(aClass); + Pair> tag = searchDocTagInExtendees(implementee, aMethod, loc, false); + + if (tag != null) { + return tag; + } + + tag = searchDocTagInExtendees(implementee, aMethod, loc, true); + + if (tag != null) { + return tag; + } + + PsiClassType[] extendee = JavaDocUtil.getExtendsList(aClass); + tag = searchDocTagInExtendees(extendee, aMethod, loc, false); + + if (tag != null) { + return tag; + } + + return searchDocTagInExtendees(extendee, aMethod, loc, true); + } + + private Pair> findInheritDocTag(PsiMethod method, DocTagLocator loc) { + PsiClass aClass = method.getContainingClass(); + + if (aClass == null) { + return null; + } + + return findInheritDocTagInClass(method, aClass, loc); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocManager.java new file mode 100644 index 00000000000..291fdd81c13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocManager.java @@ -0,0 +1,737 @@ +package com.intellij.codeInsight.javadoc; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.BrowserUtil; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.http.HttpFileSystem; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.jsp.JspImplUtil; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.LightweightHint; +import com.intellij.util.Alarm; +import com.intellij.xml.util.documentation.XmlDocumentationProvider; +import com.intellij.xml.util.documentation.HtmlDocumentationProvider; +import com.intellij.xml.util.documentation.XHtmlDocumentationProvider; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.lang.ref.WeakReference; +import java.util.HashMap; + +public class JavaDocManager implements ProjectComponent { + private final Project myProject; + private Editor myEditor = null; + + private WeakReference myDocInfoHintRef; + private boolean myRequestFocus; + private Component myPreviouslyFocused = null; + private HashMap documentationProviders = new HashMap(); + public static final Key ORIGINAL_ELEMENT_KEY = Key.create("Original element"); + + public DocumentationProvider getProvider(FileType fileType) { + return documentationProviders.get(fileType); + } + + public interface DocumentationProvider { + String getUrlFor(PsiElement element, PsiElement originalElement); + + String generateDoc(PsiElement element, PsiElement originalElement); + + PsiElement getDocumentationElementForLookupItem(Object object, PsiElement element); + + PsiElement getDocumentationElementForLink(String link, PsiElement context); + } + + public void registerDocumentationProvider(FileType fileType,DocumentationProvider provider) { + documentationProviders.put(fileType, provider); + } + + public static JavaDocManager getInstance(Project project) { + return project.getComponent(JavaDocManager.class); + } + + public JavaDocManager(Project project) { + myProject = project; + + registerDocumentationProvider(StdFileTypes.HTML, new HtmlDocumentationProvider(project)); + registerDocumentationProvider(StdFileTypes.XHTML, new XHtmlDocumentationProvider(project)); + registerDocumentationProvider(StdFileTypes.JSP,new JspImplUtil.JspDocumentationProvider(project)); + + registerDocumentationProvider(StdFileTypes.XML, new XmlDocumentationProvider()); + } + + public String getComponentName() { + return "JavaDocManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public LightweightHint showJavaDocInfo(PsiElement element) { + myRequestFocus = false; + + final JavaDocInfoComponent component = new JavaDocInfoComponent(this); + + final LightweightHint hint = new LightweightHint(component) { + public void hide() { + super.hide(); + + if (myPreviouslyFocused != null && myPreviouslyFocused.getParent() instanceof ChooseByNameBase.JPanelProvider) { + ((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).unregisterHint(); + } + + myEditor = null; + myPreviouslyFocused = null; + } + }; + + LightweightHint oldHint = getDocInfoHint(); + + if (oldHint != null) { + JavaDocInfoComponent oldComponent = (JavaDocInfoComponent)oldHint.getComponent(); + PsiElement element1 = oldComponent.getElement(); + if (element != null && element.equals(element1)) { + return oldHint; + } + oldHint.hide(); + } + + component.setHint(hint); + + fetchDocInfo(getDefaultProvider(element), component); + + myDocInfoHintRef = new WeakReference(hint); + + Window window = WindowManager.getInstance().suggestParentWindow(myProject); + JLayeredPane layeredPane; + + if (window instanceof JFrame) { + layeredPane = ((JFrame)window).getLayeredPane(); + } + else if (window instanceof JDialog) { + layeredPane = ((JDialog)window).getLayeredPane(); + } + else { + throw new IllegalStateException("cannot find parent window: project=" + myProject + "; window=" + window); + } + + myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(myProject); + + if (myPreviouslyFocused == null || !(myPreviouslyFocused.getParent() instanceof ChooseByNameBase.JPanelProvider)) { + myRequestFocus = true; + } + + hookFocus(hint); + + Point p = chooseBestHintPosition(hint); + Dimension preferredTextFieldPanelSize = component.getPreferredSize(); + + component.setBounds(p.x, p.y, preferredTextFieldPanelSize.width, preferredTextFieldPanelSize.height); + + final JLayeredPane _layeredPane = layeredPane; + + _layeredPane.add(component, new Integer(500)); + + component.registerKeyboardAction(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + _layeredPane.remove(component); + _layeredPane.repaint(component.getBounds()); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + return hint; + } + + public LightweightHint showJavaDocInfo(final Editor editor, PsiFile file, boolean requestFocus) { + myEditor = editor; + myRequestFocus = requestFocus; + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + PsiElement element = TargetElementUtil.findTargetElement(editor, + TargetElementUtil.ELEMENT_NAME_ACCEPTED + | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + | TargetElementUtil.LOOKUP_ITEM_ACCEPTED + | TargetElementUtil.NEW_AS_CONSTRUCTOR + | TargetElementUtil.THIS_ACCEPTED + | TargetElementUtil.SUPER_ACCEPTED); + PsiElement originalElement = (file != null)?file.findElementAt(editor.getCaretModel().getOffset()): null; + + if (element == null && editor != null) { + final PsiReference ref = TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()); + + if (ref != null) { + final PsiElement parent = ref.getElement().getParent(); + + if (parent instanceof PsiMethodCallExpression) { + element = parent; + } + } + + Lookup activeLookup = LookupManager.getInstance(myProject).getActiveLookup(); + + if (activeLookup != null) { + LookupItem item = activeLookup.getCurrentItem(); + if (item == null) return null; + + if (file!=null) { + DocumentationProvider documentationProvider = documentationProviders.get(file.getFileType()); + if (documentationProvider!=null) { + + if (ref!=null) originalElement = ref.getElement(); + element = documentationProvider.getDocumentationElementForLookupItem(item.getObject(), originalElement); + } + } + } + } + + if (element instanceof PsiAnonymousClass) { + element = ((PsiAnonymousClass)element).getBaseClassType().resolve(); + } + + if (element == null && file != null) { // look if we are within a javadoc comment + element = originalElement; + if (element == null) return null; + PsiDocComment comment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class); + if (comment == null) return null; + element = comment.getParent(); + if (!(element instanceof PsiClass) && !(element instanceof PsiField) && !(element instanceof PsiMethod)) return null; + } + + LightweightHint oldHint = getDocInfoHint(); + if (oldHint != null) { + JavaDocInfoComponent component = (JavaDocInfoComponent)oldHint.getComponent(); + PsiElement element1 = component.getElement(); + if (element != null && element.equals(element1)) { + if (requestFocus) { + component.getComponent().requestFocus(); + } + return oldHint; + } + oldHint.hide(); + } + + JavaDocInfoComponent component = new JavaDocInfoComponent(this); + + final IdeFrame frame = WindowManagerEx.getInstanceEx().getFrame(myProject); + try { + element.putUserData(ORIGINAL_ELEMENT_KEY,originalElement); + } catch(RuntimeException ex) {} // PsiPackage does not allow putUserData + + LightweightHint hint = new LightweightHint(component) { + public void hide() { + frame.setDefaultFocusableComponent(editor.getContentComponent()); + try { + super.hide(); + } + finally { + frame.setDefaultFocusableComponent(null); + } + editor.getContentComponent().requestFocusInWindow(); + + if (myPreviouslyFocused != null && myPreviouslyFocused.getParent() instanceof ChooseByNameBase.JPanelProvider) { + ((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).unregisterHint(); + } + + myEditor = null; + myPreviouslyFocused = null; + } + }; + component.setHint(hint); + + fetchDocInfo(getDefaultProvider(element), component); + + if (LookupManager.getInstance(myProject).getActiveLookup() != null) { + myRequestFocus = false; // move focus on the second try from lookups + } + + myDocInfoHintRef = new WeakReference(hint); + + return hint; + } + + void hookFocus(LightweightHint hint) { + if (myPreviouslyFocused.getParent() instanceof ChooseByNameBase.JPanelProvider) { + ((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).registerHint(hint); + } + } + + void takeFocus(LightweightHint hint) { + if (myRequestFocus) { + hint.getComponent().requestFocusInWindow(); + } + } + + Point chooseBestHintPosition(LightweightHint hint) { + if (myEditor != null) { + takeFocus(hint); + + Point result; + HintManager hintManager = HintManager.getInstance(); + Dimension hintSize = hint.getComponent().getPreferredSize(); + JComponent editorComponent = myEditor.getComponent(); + JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); + + Point p3 = hintManager.getHintPosition(hint, myEditor, HintManager.UNDER); + Point p4 = hintManager.getHintPosition(hint, myEditor, HintManager.ABOVE); + p3.x = Math.max(p3.x, 0); + p3.x = Math.min(p3.x, layeredPane.getWidth() - hintSize.width); + p4.x = Math.max(p4.x, 0); + p4.x = Math.min(p4.x, layeredPane.getWidth() - hintSize.width); + + int underSpace = layeredPane.getHeight() - p3.y; + int aboveSpace = p4.y + hintSize.height; + p4.y = Math.max(0, p4.y); + if (aboveSpace > underSpace) { + result = p4; + } + else { + result = p3; + } + return result; + } + + if (myPreviouslyFocused != null) { + Window window = WindowManager.getInstance().suggestParentWindow(myProject); + JLayeredPane layeredPane; + + if (window instanceof JFrame) { + layeredPane = ((JFrame)window).getLayeredPane(); + } + else if (window instanceof JDialog) { + layeredPane = ((JDialog)window).getLayeredPane(); + } + else { + throw new IllegalStateException("cannot find parent window: project=" + myProject + "; window=" + window); + } + + //myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(myProject); + + Dimension preferredTextFieldPanelSize = hint.getComponent().getPreferredSize(); + int x = (layeredPane.getWidth() - preferredTextFieldPanelSize.width) / 2; + int y = (layeredPane.getHeight() - preferredTextFieldPanelSize.height) / 2; + + if (ChooseByNameBase.isMyComponent(myPreviouslyFocused)) { + y = myPreviouslyFocused.getParent().getY() - preferredTextFieldPanelSize.height; + } + + return new Point(x, y); + } + + return null; + } + + public JavaDocProvider getDefaultProvider(final PsiElement element) { + return new JavaDocProvider() { + public String getJavaDoc() { + return getDocInfo(element); + } + + public PsiElement getElement() { + return element; + } + }; + } + + private String getExternalJavaDocUrl(final PsiElement element) { + String url = null; + + if (element instanceof PsiClass) { + url = findUrlForClass((PsiClass)element); + } + else if (element instanceof PsiField) { + PsiField field = (PsiField)element; + PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + url = findUrlForClass(aClass); + if (url != null) { + url += "#" + field.getName(); + } + } + } + else if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + PsiClass aClass = method.getContainingClass(); + if (aClass != null) { + url = findUrlForClass(aClass); + if (url != null) { + String signature = PsiFormatUtil.formatMethod(method, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_FQ_CLASS_NAMES); + url += "#" + signature; + } + } + } + else if (element instanceof PsiPackage) { + url = findUrlForPackage((PsiPackage)element); + } + else if (element instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)element).getPackage(); + if (aPackage != null) { + url = findUrlForPackage(aPackage); + } + } else { + DocumentationProvider provider = getProviderFromElement(element); + if (provider!=null) url = provider.getUrlFor(element,element.getUserData(ORIGINAL_ELEMENT_KEY)); + } + + return url == null ? null : url.replace('\\', '/'); + } + + public void openJavaDoc(final PsiElement element) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.javadoc.external"); + String url = getExternalJavaDocUrl(element); + if (url != null) { + BrowserUtil.launchBrowser(url); + } + else { + Messages.showMessageDialog(myProject, + "The documentation for this element is not found.\nPlease add all the needed paths to API docs in Project Settings.", + "No Documentation", + Messages.getErrorIcon()); + } + } + + public LightweightHint getDocInfoHint() { + if (myDocInfoHintRef == null) return null; + LightweightHint hint = myDocInfoHintRef.get(); + if (hint == null || !hint.isVisible()) { + myDocInfoHintRef = null; + return null; + } + return hint; + } + + private String findUrlForClass(PsiClass aClass) { + String qName = aClass.getQualifiedName(); + if (qName == null) return null; + PsiFile file = aClass.getContainingFile(); + if (!(file instanceof PsiJavaFile)) return null; + String packageName = ((PsiJavaFile)file).getPackageName(); + + String relPath; + if (packageName.length() > 0) { + relPath = packageName.replace('.', '/') + '/' + qName.substring(packageName.length() + 1) + ".html"; + } + else { + relPath = qName + ".html"; + } + + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile == null) return null; + final VirtualFile virtualFile = containingFile.getVirtualFile(); + if (virtualFile == null) return null; + + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + Module module = fileIndex.getModuleForFile(virtualFile); + + if (module != null) { + VirtualFile[] javadocPaths = ModuleRootManager.getInstance(module).getJavadocPaths(); + String httpRoot = getHttpRoot(javadocPaths, relPath); + if (httpRoot != null) return httpRoot; + } + + final OrderEntry[] orderEntries = fileIndex.getOrderEntriesForFile(virtualFile); + for (int i = 0; i < orderEntries.length; i++) { + OrderEntry orderEntry = orderEntries[i]; + final VirtualFile[] files = orderEntry.getFiles(OrderRootType.JAVADOC); + final String httpRoot = getHttpRoot(files, relPath); + if (httpRoot != null) return httpRoot; + } + return null; + } + + private static String getHttpRoot(final VirtualFile[] roots, String relPath) { + for (int i = 0; i < roots.length; i++) { + VirtualFile root = roots[i]; + if (root.getFileSystem() instanceof HttpFileSystem) { + return root.getUrl() + relPath; + } + else { + VirtualFile file = root.findFileByRelativePath(relPath); + if (file != null) return file.getUrl(); + } + } + + return null; + } + + private String findUrlForPackage(PsiPackage aPackage) { + String qName = aPackage.getQualifiedName(); + qName = qName.replace('.', File.separatorChar); + String[] docPaths = JavaDocUtil.getDocPaths(myProject); + for (int i = 0; i < docPaths.length; i++) { + String url = docPaths[i] + File.separator + qName + File.separatorChar + "package-summary.html"; + File file = new File(url); + if (file.exists()) return /*"file:///" + */url; + } + return null; + } + + private String findUrlForLink(PsiPackage basePackage, String link) { + int index = link.indexOf('#'); + String tail = ""; + if (index >= 0) { + tail = link.substring(index); + link = link.substring(0, index); + } + + String qName = basePackage.getQualifiedName(); + qName = qName.replace('.', File.separatorChar); + String[] docPaths = JavaDocUtil.getDocPaths(myProject); + for (int i = 0; i < docPaths.length; i++) { + String url = docPaths[i] + File.separator + qName + File.separatorChar + link; + File file = new File(url); + if (file.exists()) return url + tail; + } + return null; + } + + public void fetchDocInfo(final JavaDocProvider jdp, final JavaDocInfoComponent component) { + component.startWait(); + + new Alarm().addRequest(new Runnable() { + public void run() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (component.isEmpty()) { + component.setText("Fetching JavaDocs...."); + } + } + }); + } + }, + 600); + + new Thread(new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final String text = jdp.getJavaDoc(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (text == null) { + component.setText("No JavaDoc found.", true); + } + else if (text.length() == 0) { + component.setText(component.getText(), true); + } + else { + component.setData(jdp.getElement(), text); + } + } + }); + } + }); + } + }).start(); + } + + public String getDocInfo(PsiElement element) { + if (element instanceof PsiMethodCallExpression) { + return getMethodCandidateInfo(((PsiMethodCallExpression)element)); + } + else { + String externalDoc; + JavaDocExternalFilter docFilter = new JavaDocExternalFilter(myProject); + String docURL = getExternalJavaDocUrl(element); + + return + ( + element instanceof PsiCompiledElement && + (externalDoc = docFilter.getExternalDocInfo(docURL)) != null + ) + ? externalDoc + : docFilter.filterInternalDocInfo( + new JavaDocInfoGenerator(myProject, element, getProviderFromElement(element)).generateDocInfo(), + docURL + ); + } + } + + public DocumentationProvider getProviderFromElement(final PsiElement element) { + PsiElement originalElement = element.getUserData(ORIGINAL_ELEMENT_KEY); + PsiFile containingFile = (originalElement!=null)?originalElement.getContainingFile() : element.getContainingFile(); + VirtualFile vfile = (containingFile!=null)?containingFile.getVirtualFile() : null; + + return (vfile!=null)?getProvider(vfile.getFileType()):null; + } + + private String getMethodCandidateInfo(PsiMethodCallExpression expr) { + final PsiResolveHelper rh = expr.getManager().getResolveHelper(); + final CandidateInfo[] candidates = rh.getReferencedMethodCandidates(expr, true); + + final String text = expr.getText(); + if (candidates.length > 0) { + final StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < candidates.length; i++) { + final CandidateInfo candidate = candidates[i]; + final PsiElement element = candidate.getElement(); + + if (!(element instanceof PsiMethod)) { + continue; + } + + sb.append("  
"); + sb.append(PsiFormatUtil.formatMethod(((PsiMethod)element), + candidate.getSubstitutor(), + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE)); + sb.append("
"); + } + + return "Candidates for method call " + text + " are:

" + sb + ""; + } + + return "No candidates found for method call " + text + "."; + } + + void navigateByLink(final JavaDocInfoComponent component, String url) { + component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + final PsiManager manager = PsiManager.getInstance(myProject); + String prefix = "psi_element://"; + if (url.startsWith(prefix)) { + final String refText = url.substring(prefix.length()); + final PsiElement targetElement = JavaDocUtil.findReferenceTarget(manager, refText, component.getElement()); + if (targetElement != null) { + fetchDocInfo(getDefaultProvider(targetElement), component); + } + } + else { + final String docUrl = url; + + fetchDocInfo + (new JavaDocProvider() { + String getElementLocator(String url) { + String prefix = "doc_element://"; + if (url.startsWith(prefix)) { + return url.substring(prefix.length()); + } + return null; + } + + public String getJavaDoc() { + String url = getElementLocator(docUrl); + if (url != null && JavaDocExternalFilter.isJavaDocURL(url)) { + String text = new JavaDocExternalFilter(myProject).getExternalDocInfo(url); + + if (text != null) { + return text; + } + } + + if (url == null) { + url = docUrl; + } + + PsiElement element = component.getElement(); + if (element != null) { + PsiElement parent = element; + while (true) { + if (parent == null || parent instanceof PsiDirectory) break; + parent = parent.getParent(); + } + if (parent != null) { + PsiPackage aPackage = ((PsiDirectory)parent).getPackage(); + if (aPackage != null) { + String url1 = findUrlForLink(aPackage, url); + if (url1 != null) { + url = url1; + } + } + } + } + + BrowserUtil.launchBrowser(url); + + return ""; + } + + public PsiElement getElement() { + //String loc = getElementLocator(docUrl); + // + //if (loc != null) { + // PsiElement context = component.getElement(); + // return JavaDocUtil.findReferenceTarget(context.getManager(), loc, context); + //} + + return component.getElement(); + } + }, component); + } + + component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + void showHint(LightweightHint hint) { + Point p = chooseBestHintPosition(hint); + + if (myEditor != null) { + HintManager hintManager = HintManager.getInstance(); + hintManager.showEditorHint(hint, myEditor, p, + HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_LOOKUP_ITEM_CHANGE | + HintManager.HIDE_BY_TEXT_CHANGE | + HintManager.HIDE_BY_SCROLLING, + 0, false); + + if (LookupManager.getInstance(myProject).getActiveLookup() != null) { + myRequestFocus = false; // move focus on the second try from lookups + } + if (myRequestFocus) { + hint.getComponent().requestFocusInWindow(); + } + } + else if (myPreviouslyFocused != null) { + Dimension preferred = hint.getComponent().getPreferredSize(); + hint.setBounds(p.x, p.y, preferred.width, preferred.height); + } + } + + public void requestFocus() { + if (myPreviouslyFocused != null && myPreviouslyFocused.getParent() instanceof ChooseByNameBase.JPanelProvider) { + ((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).requestFocus(); + } + } + + public Project getProject() { + return myProject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocUtil.java new file mode 100644 index 00000000000..29290b97de8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/JavaDocUtil.java @@ -0,0 +1,408 @@ +package com.intellij.codeInsight.javadoc; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.http.HttpFileSystem; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.StringTokenizer; +import java.util.LinkedList; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class JavaDocUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.javadoc.JavaDocUtil"); + + private static final Pattern ourTypePattern = Pattern.compile("[ ]+[^ ^\\[^\\]]"); + private static final Pattern ourLtFixupPattern = Pattern.compile("<([^/^\\w^!])"); + private static final Pattern ourToQuote = Pattern.compile("[\\\\\\.\\^\\$\\?\\*\\+\\|\\)\\}\\]\\{\\(\\[]"); + + public static void createHyperlink(StringBuffer buffer, String refText,String label,boolean plainLink) { + buffer.append(""); + if (!plainLink) { + buffer.append(""); + } + buffer.append(label); + if (!plainLink) { + buffer.append(""); + } + buffer.append(""); + } + + public static String[] getDocPaths(Project project) { + ArrayList result = new ArrayList(); + + final VirtualFile[] roots = ProjectRootManagerEx.getInstanceEx(project).getRootFiles(ProjectRootType.JAVADOC); + for (int i = 0; i < roots.length; i++) { + VirtualFile root = roots[i]; + if (!(root.getFileSystem() instanceof HttpFileSystem)) { + result.add(root.getUrl()); + } + } + + return (String[])result.toArray(new String[result.size()]); + } + + /** + * Extracts a reference to a source element from the beginning of the text. + * + * @return length of the extracted reference + */ + public static int extractReference(String text) { + int lparenthIndex = text.indexOf('('); + int spaceIndex = text.indexOf(' '); + if (spaceIndex < 0) { + spaceIndex = text.length(); + } + if (lparenthIndex < 0) { + return spaceIndex; + } + else { + if (spaceIndex < lparenthIndex) { + return spaceIndex; + } + int rparenthIndex = text.indexOf(')', lparenthIndex); + if (rparenthIndex < 0) { + rparenthIndex = text.length() - 1; + } + return rparenthIndex + 1; + } + } + + public static PsiElement findReferenceTarget(PsiManager manager, String refText, PsiElement context) { + int poundIndex = refText.indexOf('#'); + if (poundIndex < 0) { + PsiClass aClass = manager.getResolveHelper().resolveReferencedClass(refText, context); + + if (aClass == null) aClass = manager.findClass(refText, context.getResolveScope()); + + if (aClass != null) return aClass.getNavigationElement(); + PsiPackage aPackage = manager.findPackage(refText); + if (aPackage!=null) return aPackage; + JavaDocManager.DocumentationProvider provider = JavaDocManager.getInstance(manager.getProject()).getProviderFromElement(context); + if (provider!=null) { + return provider.getDocumentationElementForLink(refText,context); + } + return null; + } + else { + String classRef = refText.substring(0, poundIndex).trim(); + if (classRef.length() > 0) { + PsiClass aClass = manager.getResolveHelper().resolveReferencedClass(classRef, context); + + if (aClass == null) aClass = manager.findClass(classRef, context.getResolveScope()); + + if (aClass == null) return null; + return findReferencedMember(aClass, refText.substring(poundIndex + 1), context); + } + else { + String memberRefText = refText.substring(1); + PsiElement scope = context; + while (true) { + if (scope instanceof PsiFile) break; + if (scope instanceof PsiClass) { + PsiElement member = findReferencedMember((PsiClass)scope, memberRefText, context); + if (member != null) return member; + } + scope = scope.getParent(); + } + return null; + } + } + } + + private static PsiElement findReferencedMember(PsiClass aClass, String memberRefText, PsiElement context) { + int parenthIndex = memberRefText.indexOf('('); + if (parenthIndex < 0) { + String name = memberRefText; + PsiField field = aClass.findFieldByName(name, true); + if (field != null) return field.getNavigationElement(); + PsiClass inner = aClass.findInnerClassByName(name, true); + if (inner != null) return inner.getNavigationElement(); + PsiMethod[] methods = aClass.getAllMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method.getName().equals(name)) return method.getNavigationElement(); + } + return null; + } + else { + String name = memberRefText.substring(0, parenthIndex).trim(); + if (!StringUtil.endsWithChar(memberRefText, ')')) return null; + String parmsText = memberRefText.substring(parenthIndex + 1, memberRefText.length() - 1).trim(); + StringTokenizer tokenizer = new StringTokenizer(parmsText.replaceAll("[*]", ""), ","); + PsiType[] types = new PsiType[tokenizer.countTokens()]; + int i = 0; + PsiElementFactory factory = aClass.getManager().getElementFactory(); + while (tokenizer.hasMoreTokens()) { + String parmText = tokenizer.nextToken().trim(); + try { + Matcher typeMatcher = ourTypePattern.matcher(parmText); + String typeText = parmText; + + if (typeMatcher.find()) { + typeText = parmText.substring(0, typeMatcher.start()); + } + + PsiType type = factory.createTypeFromText(typeText, context); + types[i++] = type; + } + catch (IncorrectOperationException e) { + LOG.info(e); + } + } + PsiMethod[] methods = aClass.getAllMethods(); + MethodsLoop: + for (int j = 0; j < methods.length; j++) { + PsiMethod method = methods[j]; + if (!method.getName().equals(name)) continue; + PsiParameter[] parms = method.getParameterList().getParameters(); + if (parms.length != types.length) continue; + for (int k = 0; k < parms.length; k++) { + PsiParameter parm = parms[k]; + if ( + types[k] != null && !TypeConversionUtil.erasure(parm.getType()).getCanonicalText().equals(types[k].getCanonicalText()) + ) { + continue MethodsLoop; + } + } + return method.getNavigationElement(); + } + return null; + } + } + + public static String getReferenceText(Project project, PsiElement element) { + if (element instanceof PsiPackage) { + return ((PsiPackage)element).getQualifiedName(); + } + else if (element instanceof PsiClass) { + final String refText = ((PsiClass)element).getQualifiedName(); + if (refText != null) return refText; + return ((PsiClass)element).getName(); + } + else if (element instanceof PsiField) { + PsiField field = (PsiField)element; + String name = field.getName(); + PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + return getReferenceText(project, aClass) + "#" + name; + } + else { + return "#" + name; + } + } + else if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + String name = method.getName(); + StringBuffer buffer = new StringBuffer(); + PsiClass aClass = method.getContainingClass(); + if (aClass != null) { + buffer.append(getReferenceText(project, aClass)); + } + buffer.append("#"); + buffer.append(name); + buffer.append("("); + PsiParameter[] parms = method.getParameterList().getParameters(); + CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(project); + boolean spaceBeforeComma = styleSettings.SPACE_BEFORE_COMMA; + boolean spaceAfterComma = styleSettings.SPACE_AFTER_COMMA; + for (int i = 0; i < parms.length; i++) { + PsiParameter parm = parms[i]; + String typeText = parm.getType().getCanonicalText(); + buffer.append(typeText); + if (i < parms.length - 1) { + if (spaceBeforeComma) { + buffer.append(" "); + } + buffer.append(","); + if (spaceAfterComma) { + buffer.append(" "); + } + } + } + buffer.append(")"); + return buffer.toString(); + } + else { + return null; + } + } + + public static String getShortestClassName(PsiClass aClass, PsiElement context) { + String qName = aClass.getQualifiedName(); + + if (qName == null) return aClass.getName(); + + String packageName = ((PsiJavaFile)aClass.getContainingFile()).getPackageName(); + + LOG.assertTrue(packageName != null, "packageName==null"); + if (packageName.length() == 0) return qName; + + LOG.assertTrue(packageName.length() >= 0, "Ctrl-Mouse: class is " + aClass.getQualifiedName()); + + String shortName = packageName.length() < qName.length() ? qName.substring(packageName.length() + 1) : qName; + + return + aClass.equals(aClass.getManager().getResolveHelper().resolveReferencedClass(shortName, context)) ? + shortName : + qName; + } + + public static String getLabelText(Project project, PsiManager manager, String refText, PsiElement context) { + PsiElement refElement = findReferenceTarget(manager, refText, context); + if (refElement == null) { + return refText.replaceFirst("^#", "").replaceAll("#", "."); + } + int poundIndex = refText.indexOf('#'); + if (poundIndex < 0) { + if (refElement instanceof PsiClass) { + return getShortestClassName((PsiClass)refElement, context); + } + else { + return refText; + } + } + else { + PsiClass aClass = null; + if (refElement instanceof PsiField) { + aClass = ((PsiField)refElement).getContainingClass(); + } + else if (refElement instanceof PsiMethod) { + aClass = ((PsiMethod)refElement).getContainingClass(); + } + else if (refElement instanceof PsiClass){ + return refText.replaceAll("#", "."); + } + if (aClass == null) return refText; + String classRef = refText.substring(0, poundIndex).trim(); + String memberText = refText.substring(poundIndex + 1); + String memberLabel = getMemberLabelText(project, manager, memberText, context); + if (classRef.length() > 0) { + PsiElement refClass = findReferenceTarget(manager, classRef, context); + if (refClass instanceof PsiClass) { + PsiElement scope = context; + while (true) { + if (scope == null || scope instanceof PsiFile) break; + if (scope.equals(refClass)) { + return memberLabel; + } + scope = scope.getParent(); + } + } + return getLabelText(project, manager, classRef, context) + "." + memberLabel; + } + else { + return memberLabel; + } + } + } + + private static String getMemberLabelText(Project project, PsiManager manager, String memberText, PsiElement context) { + int parenthIndex = memberText.indexOf('('); + if (parenthIndex < 0) return memberText; + if (!StringUtil.endsWithChar(memberText, ')')) return memberText; + String parms = memberText.substring(parenthIndex + 1, memberText.length() - 1); + StringBuffer buffer = new StringBuffer(); + CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(project); + boolean spaceBeforeComma = styleSettings.SPACE_BEFORE_COMMA; + boolean spaceAfterComma = styleSettings.SPACE_AFTER_COMMA; + StringTokenizer tokenizer = new StringTokenizer(parms, ","); + while (tokenizer.hasMoreTokens()) { + String param = tokenizer.nextToken().trim(); + int index1 = param.indexOf('['); + if (index1 < 0) index1 = param.length(); + int index2 = param.indexOf(' '); + if (index2 < 0) index2 = param.length(); + int index = Math.min(index1, index2); + String className = param.substring(0, index).trim(); + String shortClassName = getLabelText(project, manager, className, context); + buffer.append(shortClassName); + buffer.append(param.substring(className.length())); + if (tokenizer.hasMoreElements()) { + if (spaceBeforeComma) { + buffer.append(" "); + } + buffer.append(","); + if (spaceAfterComma) { + buffer.append(" "); + } + } + } + return memberText.substring(0, parenthIndex + 1) + buffer.toString() + ")"; + } + + private static String quote(String x) { + if (ourToQuote.matcher(x).find()) { + return "\\" + x; + } + + return x; + } + + public static String fixupText(String docText) { + Matcher fixupMatcher = ourLtFixupPattern.matcher(docText); + LinkedList secondSymbols = new LinkedList(); + + while (fixupMatcher.find()) { + String s = fixupMatcher.group(1); + + //[db] that's workaround to avoid internal bug + if (!s.equals("\\")) { + secondSymbols.addFirst(s); + } + } + + for (Iterator i = secondSymbols.iterator(); i.hasNext();) { + String s = i.next(); + String pattern = "<" + quote(s); + + try { + docText = Pattern.compile(pattern).matcher(docText).replaceAll("<" + pattern); + } + catch (PatternSyntaxException e) { + LOG.error("Pattern syntax exception on " + pattern); + } + } + + return docText; + } + + public static PsiClassType[] getImplementsList(PsiClass aClass) { + if (aClass instanceof PsiAnonymousClass) { + return new PsiClassType[]{((PsiAnonymousClass)aClass).getBaseClassType()}; + } + + PsiReferenceList list = aClass.getImplementsList(); + + return list == null ? PsiClassType.EMPTY_ARRAY : list.getReferencedTypes(); + } + + public static PsiClassType[] getExtendsList(PsiClass aClass) { + if (aClass instanceof PsiAnonymousClass) { + return new PsiClassType[]{((PsiAnonymousClass)aClass).getBaseClassType()}; + } + + PsiReferenceList list = aClass.getExtendsList(); + + return list == null ? PsiClassType.EMPTY_ARRAY : list.getReferencedTypes(); + } + + public static final void formatEntityName(String type, String name, StringBuffer destination) { + destination.append(type).append(": ").append(name).append("
"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/actions/ShowJavaDocInfoAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/actions/ShowJavaDocInfoAction.java new file mode 100644 index 00000000000..4d5bb2971cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/javadoc/actions/ShowJavaDocInfoAction.java @@ -0,0 +1,115 @@ +package com.intellij.codeInsight.javadoc.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +public class ShowJavaDocInfoAction extends BaseCodeInsightAction implements HintManager.ActionToIgnore { + public ShowJavaDocInfoAction() { + setEnabledInModalContext(true); + } + + protected CodeInsightActionHandler getHandler() { + return new CodeInsightActionHandler() { + public void invoke(Project project, Editor editor, PsiFile file) { + JavaDocManager.getInstance(project).showJavaDocInfo(editor, file, true); + } + + public boolean startInWriteAction() { + return true; + } + }; + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file.canContainJavaCode(); // && !(file instanceof PsiCodeFragment); + } + + protected boolean isValidForLookup() { + return true; + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if (editor == null && element == null) { + presentation.setEnabled(false); + return; + } + + if (LookupManager.getInstance(project).getActiveLookup() != null) { + if (!isValidForLookup()) { + presentation.setEnabled(false); + } + else { + presentation.setEnabled(true); + } + } + else { + if (editor != null) { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null || !isValidForFile(project, editor, file)) { + presentation.setEnabled(false); + } + else { + presentation.setEnabled(isEnabledForFile(project, editor, file)); + } + } + + if (element != null) { + presentation.setEnabled(true); + } + } + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + final PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + + if (project != null && editor != null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.quickjavadoc"); + if (LookupManager.getInstance(project).getActiveLookup() != null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.quickjavadoc.lookup"); + } + actionPerformedImpl(project, editor); + } + else if (element != null && project != null) { + if (element instanceof PsiMethod || + element instanceof PsiClass || + element instanceof PsiField || + element instanceof PsiVariable) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.quickjavadoc.ctrln"); + CommandProcessor.getInstance().executeCommand(project, + new Runnable() { + public void run() { + JavaDocManager.getInstance(project).showJavaDocInfo(element); + } + }, + getCommandName(), + null); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/CharFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/CharFilter.java new file mode 100644 index 00000000000..1258376d91f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/CharFilter.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jul 23, 2002 + * Time: 2:18:55 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInsight.lookup; + +public interface CharFilter { + int ADD_TO_PREFIX = 0; + int SELECT_ITEM_AND_FINISH_LOOKUP = 1; + int HIDE_LOOKUP = 2; + + int accept(char c); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java new file mode 100644 index 00000000000..f33ceee0d17 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java @@ -0,0 +1,14 @@ +package com.intellij.codeInsight.lookup; + +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Sep 29, 2004 + * Time: 7:38:32 PM + * To change this template use File | Settings | File Templates. + */ +public interface DeferredUserLookupValue extends PresentableLookupValue { + boolean handleUserSelection(LookupItem item,Project project); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/Lookup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/Lookup.java new file mode 100644 index 00000000000..bde202291f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/Lookup.java @@ -0,0 +1,29 @@ +package com.intellij.codeInsight.lookup; + +import com.intellij.openapi.util.UserDataHolder; + +import java.awt.Rectangle; + +public interface Lookup extends UserDataHolder{ + char NORMAL_SELECT_CHAR = '\n'; + char REPLACE_SELECT_CHAR = '\t'; + + LookupItem getCurrentItem(); + void setCurrentItem(LookupItem item); + + void addLookupListener(LookupListener listener); + void removeLookupListener(LookupListener listener); + + /** + * @return bounds in layered pane coordinate system + */ + Rectangle getBounds(); + + /** + * @return bounds of the current item in the layered pane coordinate system. + */ + Rectangle getCurrentItemBounds(); + boolean isPositionedAboveCaret(); + + boolean fillInCommonPrefix(boolean toCompleteUniqueName); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupAdapter.java new file mode 100644 index 00000000000..0351898262f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupAdapter.java @@ -0,0 +1,12 @@ +package com.intellij.codeInsight.lookup; + +public abstract class LookupAdapter implements LookupListener{ + public void itemSelected(LookupEvent event){ + } + + public void lookupCanceled(LookupEvent event){ + } + + public void currentItemChanged(LookupEvent event){ + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupEvent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupEvent.java new file mode 100644 index 00000000000..c963a379a65 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupEvent.java @@ -0,0 +1,33 @@ +package com.intellij.codeInsight.lookup; + +import java.util.EventObject; + +public class LookupEvent extends EventObject { + + private final Lookup myLookup; + private final LookupItem myItem; + private final char myCompletionChar; + + public LookupEvent(Lookup lookup, LookupItem item){ + this(lookup, item, (char)0); + } + + public LookupEvent(Lookup lookup, LookupItem item, char completionChar){ + super(lookup); + myLookup = lookup; + myItem = item; + myCompletionChar = completionChar; + } + + public Lookup getLookup(){ + return myLookup; + } + + public LookupItem getItem(){ + return myItem; + } + + public char getCompletionChar(){ + return myCompletionChar; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItem.java new file mode 100644 index 00000000000..09de1fb0922 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItem.java @@ -0,0 +1,154 @@ +package com.intellij.codeInsight.lookup; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; +import com.intellij.util.containers.HashMap; + +import java.util.Map; + +/** + * This class represents an item of a lookup list. + */ +public final class LookupItem implements Comparable{ + public static final Object HIGHLIGHTED_ATTR = Key.create("highlighted"); + public static final Object TYPE_ATTR = Key.create("type"); + public static final Object ICON_ATTR = Key.create("icon"); + public static final Object TAIL_TEXT_ATTR = Key.create("tailText"); + public static final Object TAIL_TEXT_SMALL_ATTR = Key.create("tailTextSmall"); + public static final Object FORCE_SHOW_SIGNATURE_ATTR = Key.create("forceShowSignature"); + public static final Object FORCE_SHOW_FQN_ATTR = Key.create("forseFQNForClasses"); + + public static final Object DO_NOT_AUTOCOMPLETE_ATTR = Key.create("DO_NOT_AUTOCOMPLETE_ATTR"); + public static final Object DO_AUTOCOMPLETE_ATTR = Key.create("DO_AUTOCOMPLETE_ATTR"); + public static final Object INSERT_HANDLER_ATTR = Key.create("INSERT_HANDLER_ATTR"); + + public static final Object GENERATE_ANONYMOUS_BODY_ATTR = Key.create("GENERATE_ANONYMOUS_BODY_ATTR"); + public static final Object CONTAINING_CLASS_ATTR = Key.create("CONTAINING_CLASS_ATTR"); // used for dummy-constructors + public static final Object BRACKETS_COUNT_ATTR = Key.create("BRACKETS_COUNT_ATTR"); + public static final Object OVERWRITE_ON_AUTOCOMPLETE_ATTR = Key.create("OVERWRITE_ON_AUTOCOMPLETE_ATTR"); + public static final Object NEW_OBJECT_ATTR = Key.create("NEW_OBJECT_ATTR"); + public static final Object DONT_CHECK_FOR_INNERS = Key.create("DONT_CHECK_FOR_INNERS"); + public static final Object FORCE_QUALIFY = Key.create("FORCE_QUALIFY"); + public static final Object SUBSTITUTOR = Key.create("SUBSTITUTOR"); + public static final Object TYPE = Key.create("TYPE"); + public static final Object INDICATE_ANONYMOUS = Key.create("INDICATE ANONYMOUS"); + + private Object myObject; + private String myLookupString; + private Map myAttributes = null; + + + public LookupItem(Object o, String lookupString){ + setObject(o); + myLookupString = lookupString; + } + + public void setObject(Object o) { + if (o instanceof PsiElement){ + PsiElement element = (PsiElement)o; + Project project = element.getProject(); + myObject = SmartPointerManager.getInstance(project).createSmartPsiElementPointer((PsiElement)o); + } + else{ + myObject = o; + } + } + + public boolean equals(Object o){ + if (o == this) return true; + if (o instanceof LookupItem){ + LookupItem item = (LookupItem)o; + return Comparing.equal(myObject, item.myObject) + && Comparing.equal(myLookupString, item.myLookupString) + && Comparing.equal(myAttributes, item.myAttributes); + } + return false; + } + + public Map getAttributes(){ + return myAttributes; + } + + public void setAttributes(Map attributes){ + myAttributes = attributes; + } + + public int hashCode() { + return myLookupString.hashCode(); + } + + public String toString() { + return getLookupString(); + } + + /** + * Returns a data object. This object is used e.g. for rendering the node. + */ + public Object getObject() { + if (myObject instanceof SmartPsiElementPointer){ + return ((SmartPsiElementPointer)myObject).getElement(); + } + else{ + return myObject; + } + } + + /** + * Returns a string which will be inserted to the editor when this item is + * choosen. + */ + public String getLookupString() { + return myLookupString; + } + + public void setLookupString(String lookupString) { + myLookupString = lookupString; + } + + public Object getAttribute(Object key){ + if (myAttributes != null){ + return myAttributes.get(key); + } + else{ + return null; + } + } + + public void setAttribute(Object key, Object value){ + if (myAttributes == null){ + myAttributes = new HashMap(5); + } + myAttributes.put(key, value); + } + + public InsertHandler getInsertHandler(){ + return (InsertHandler)getAttribute(INSERT_HANDLER_ATTR); + } + + public int getTailType(){ + final Integer tailType = (Integer) getAttribute(CompletionUtil.TAIL_TYPE_ATTR); + if(tailType != null) + return tailType.intValue(); + return -1; + } + + public void setTailType(int type){ + setAttribute(CompletionUtil.TAIL_TYPE_ATTR, new Integer(type)); + } + + public int compareTo(Object o){ + if(o instanceof String){ + return getLookupString().compareTo(((String) o)); + } + if(!(o instanceof LookupItem)){ + throw new RuntimeException("Trying to compare LookupItem with " + o.getClass() + "!!!"); + } + return getLookupString().compareTo(((LookupItem)o).getLookupString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItemUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItemUtil.java new file mode 100644 index 00000000000..527ca2ad7de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupItemUtil.java @@ -0,0 +1,243 @@ +package com.intellij.codeInsight.lookup; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.codeInsight.TailType; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.template.Template; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.util.PsiUtil; + +import java.util.Iterator; +import java.util.LinkedHashSet; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 06.02.2003 + * Time: 16:05:20 + * To change this template use Options | File Templates. + */ +public class LookupItemUtil{ + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.LookupItemUtil"); + + public static LookupItem addLookupItem(LinkedHashSet set, Object object, String prefix) { + LOG.assertTrue(object != null, "Lookup item can't be null!"); + return addLookupItem(set, object, prefix, -1); + } + + public static LookupItem addLookupItem(LinkedHashSet set, Object object, String prefix, InsertHandler handler) { + LOG.assertTrue(object != null, "Lookup item can't be null!"); + LookupItem item = addLookupItem(set, object, prefix, -1); + if (item != null) { + item.setAttribute(LookupItem.INSERT_HANDLER_ATTR, handler); + } + return item; + } + + public static LookupItem addLookupItem(LinkedHashSet set, Object object, String prefix, int tailType) { + LOG.assertTrue(object != null, "Lookup item can't be null!"); + //TODO[ik]: remove the check: it is always false? + if (object instanceof PsiType) { + PsiType psiType = (PsiType)object; + for (Iterator iterator = set.iterator(); iterator.hasNext();) { + LookupItem lookupItem = (LookupItem)iterator.next(); + Object o = lookupItem.getObject(); + if (o.equals(psiType)) { + return lookupItem; + } + } + } + + LookupItem item = LookupItemUtil.objectToLookupItem(object); + String text = item.getLookupString(); + if (CompletionUtil.startsWith(text, prefix)) { + item.setLookupString(text); + if (tailType >= 0) { + item.setAttribute(CompletionUtil.TAIL_TYPE_ATTR, new Integer(tailType)); + } + return set.add(item) ? item : null; + } + else{ + return null; + } + } + + public static void addLookupItems(LinkedHashSet set, Object[] objects, String prefix) { + for (int i = 0; i < objects.length; i++) { + LOG.assertTrue(objects[i] != null, "Lookup item can't be null!"); + addLookupItem(set, objects[i], prefix); + } + } + + public static void removeLookupItem(LinkedHashSet set, Object object) { + Iterator iter = set.iterator(); + while (iter.hasNext()) { + LookupItem item = (LookupItem)iter.next(); + if (object.equals(item.getObject())) { + iter.remove(); + break; + } + } + } + + public static boolean containsItem(LinkedHashSet set, Object object) { + final Iterator iter = set.iterator(); + while (iter.hasNext()) { + final LookupItem item = (LookupItem)iter.next(); + if (object != null && object.equals(item.getObject())) { + return true; + } + } + return false; + } + + public static LookupItem objectToLookupItem(Object object) { + String s = null; + LookupItem item = new LookupItem(object, ""); + int tailType = TailType.NONE; + if (object instanceof PsiElement){ + PsiElement element = (PsiElement) object; + if(element.getUserData(CompletionUtil.ORIGINAL_KEY) != null){ + element = element.getUserData(CompletionUtil.ORIGINAL_KEY); + object = element; + item = new LookupItem(object, ""); + } + s = PsiUtil.getName(element); + } + if (object instanceof PsiMethod) { + PsiMethod method = (PsiMethod)object; + s = method.getName(); + PsiType type = method.getReturnType(); + if (type == PsiType.VOID) { + tailType = TailType.SEMICOLON; + } + } + else if (object instanceof PsiPackage) { + tailType = TailType.DOT; + } + else if (object instanceof PsiKeyword) { + s = ((PsiKeyword)object).getText(); + } + else if (object instanceof PsiExpression) { + s = ((PsiExpression)object).getText(); + } + else if (object instanceof PsiType) { + final PsiType type = (PsiType) object; + if(type instanceof PsiPrimitiveType) + s = ((PsiType)object).getPresentableText(); + else if(type instanceof PsiArrayType){ + PsiType contentType = type; + int dim = 0; + final StringBuffer tail = new StringBuffer(); + while(contentType instanceof PsiArrayType){ + contentType = ((PsiArrayType) contentType).getComponentType(); + tail.append("[]"); + dim++; + } + if(contentType instanceof PsiClassType){ + PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType)contentType).resolveGenerics(); + final PsiClass psiClass = classResolveResult.getElement(); + final PsiSubstitutor substitutor = classResolveResult.getSubstitutor(); + final String text; + if(psiClass != null){ + text = formatTypeName(psiClass, substitutor); + } + else{ + text = type.getPresentableText(); + } + String typeString = text; + if (text.indexOf('<') > 0) { + typeString = text.substring(0, text.indexOf('<')); + } + s = text.substring(typeString.lastIndexOf('.') + 1); + item = psiClass != null ? new LookupItem(psiClass, s) : new LookupItem(text, s) ; + item.setAttribute(LookupItem.SUBSTITUTOR, substitutor); + } + else{ + item = new LookupItem(contentType, ""); + s = contentType.getPresentableText(); + } + item.setAttribute(LookupItem.TAIL_TEXT_ATTR, " " + tail.toString() + ""); + item.setAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR, ""); + item.setAttribute(LookupItem.BRACKETS_COUNT_ATTR, new Integer(dim)); + } + else if(type instanceof PsiClassType){ + PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType)type).resolveGenerics(); + final PsiClass psiClass = classResolveResult.getElement(); + final PsiSubstitutor substitutor = classResolveResult.getSubstitutor(); + final String text; + if(psiClass != null) text = formatTypeName(psiClass, substitutor); + else text = type.getPresentableText(); + if(text != null){ + String typeString = text; + if (text.indexOf('<') > 0) { + typeString = text.substring(0, text.indexOf('<')); + } + s = text.substring(typeString.lastIndexOf('.') + 1); + + item = psiClass != null ? new LookupItem(psiClass, s) : new LookupItem(text, s) ; + item.setAttribute(LookupItem.SUBSTITUTOR, substitutor); + } + else s = type.getPresentableText(); + } + else + s = type.getPresentableText(); + item.setAttribute(LookupItem.TYPE, type); + } + else if (object instanceof PsiMetaData) { + s = ((PsiMetaData)object).getName(); + } + else if (object instanceof String) { + s = (String)object; + } + else if (object instanceof Template) { + s = ""; + } + else if (object instanceof PsiPointcutDef) { + s = ((PsiPointcutDef)object).getName(); + } else if (object instanceof PresentableLookupValue) { + s = ((PresentableLookupValue)object).getPresentation(); + } + + if (s == null) { + LOG.assertTrue(false, "Null string for object: " + object + " of class " + object.getClass()); + } + item.setLookupString(s); + item.setAttribute(CompletionUtil.TAIL_TYPE_ATTR, new Integer(tailType)); + return item; + } + + public static String formatTypeName(final PsiClass element, final PsiSubstitutor substitutor) { + final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(element.getProject()); + String name = element.getName(); + if(substitutor != null){ + final PsiTypeParameterList list = element.getTypeParameterList(); + final PsiTypeParameter[] params = list != null ? list.getTypeParameters() : null; + if(params != null && params.length > 0){ + boolean flag = true; + StringBuffer buffer = new StringBuffer(); + buffer.append("<"); + for(int i = 0; i < params.length; i++){ + final PsiTypeParameter param = params[i]; + final PsiType type = substitutor.substitute(param); + if(type == null){ + flag = false; + break; + } + buffer.append(type.getPresentableText()); + if(i < params.length - 1){ buffer.append(","); + if(styleSettings.SPACE_AFTER_COMMA) buffer.append(" "); + } + } + buffer.append(">"); + if(flag) name += buffer; + } + } + return name; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupListener.java new file mode 100644 index 00000000000..1ededd2fb35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupListener.java @@ -0,0 +1,14 @@ +package com.intellij.codeInsight.lookup; + +import java.util.EventListener; + +public interface LookupListener extends EventListener { + /** + * Note: this event comes inside the command that performs inserting of text into the editor. + */ + void itemSelected(LookupEvent event); + + void lookupCanceled(LookupEvent event); + + void currentItemChanged(LookupEvent event); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupManager.java new file mode 100644 index 00000000000..0ee4fea6506 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupManager.java @@ -0,0 +1,31 @@ +package com.intellij.codeInsight.lookup; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +import java.beans.PropertyChangeListener; + +public abstract class LookupManager { + public static LookupManager getInstance(Project project){ + return project.getComponent(LookupManager.class); + } + + public abstract Lookup showLookup( + Editor editor, + LookupItem[] items, + String prefix, + LookupItemPreferencePolicy itemPreferencePolicy, + CharFilter filter); + public abstract void hideActiveLookup(); + public abstract Lookup getActiveLookup(); + + public static final String PROP_ACTIVE_LOOKUP = "activeLookup"; + + public abstract void addPropertyChangeListener(PropertyChangeListener listener); + public abstract void removePropertyChangeListener(PropertyChangeListener listener); + + public abstract PsiElement[] getAllElementsForItem(LookupItem item); + + public abstract boolean isDisposed(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java new file mode 100644 index 00000000000..14476443d02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java @@ -0,0 +1,14 @@ +package com.intellij.codeInsight.lookup; + +import java.awt.*; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 10.12.2004 + * Time: 13:25:56 + * To change this template use File | Settings | File Templates. + */ +public interface LookupValueWithUIHint extends PresentableLookupValue { + Color getColorHint(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/PresentableLookupValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/PresentableLookupValue.java new file mode 100644 index 00000000000..44ad90a5f45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/PresentableLookupValue.java @@ -0,0 +1,12 @@ +package com.intellij.codeInsight.lookup; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 10.12.2004 + * Time: 13:38:25 + * To change this template use File | Settings | File Templates. + */ +public interface PresentableLookupValue { + String getPresentation(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java new file mode 100644 index 00000000000..7eda3cd178e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java @@ -0,0 +1,54 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +import javax.swing.*; +import java.awt.*; + +class BackspaceHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public BackspaceHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = (LookupImpl)editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + if (lookup.getPrefix().length() > lookup.getInitialPrefix().length()){ + lookup.setPrefix(lookup.getPrefix().substring(0, lookup.getPrefix().length() - 1)); + if (LookupImpl.isNarrowDownMode()){ + lookup.updateList(); + Point point=lookup.calculatePosition(); + Dimension preferredSize = lookup.getComponent().getPreferredSize(); + lookup.setBounds(point.x,point.y,preferredSize.width,preferredSize.height); + } + else{ + String prefix = lookup.getPrefix().toLowerCase(); + ListModel model = lookup.getList().getModel(); + for(int i = 0; i < model.getSize(); i++){ + LookupItem item = (LookupItem)model.getElementAt(i); + String s = item.getLookupString(); + if (s.toLowerCase().startsWith(prefix)){ + lookup.getList().setSelectedIndex(i); + lookup.getList().ensureIndexIsVisible(i); + break; + } + } + } + lookup.getList().repaint(); + } + else{ + lookup.hide(); + } + + myOriginalHandler.execute(editor, dataContext); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/DownHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/DownHandler.java new file mode 100644 index 00000000000..7c76bd4d583 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/DownHandler.java @@ -0,0 +1,29 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtilEx; + +class DownHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public DownHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtilEx.moveDown(lookup.getList(), 0); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + return lookup != null || myOriginalHandler.isEnabled(editor, dataContext); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/EndHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/EndHandler.java new file mode 100644 index 00000000000..53d36f10aac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/EndHandler.java @@ -0,0 +1,24 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtil; + +class EndHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public EndHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtil.moveEnd(lookup.getList()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/HomeHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/HomeHandler.java new file mode 100644 index 00000000000..311c96a2d29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/HomeHandler.java @@ -0,0 +1,24 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtil; + +class HomeHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public HomeHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtil.moveHome(lookup.getList()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java new file mode 100644 index 00000000000..af61c6aff07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java @@ -0,0 +1,555 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.impl.TemplateSettings; +import com.intellij.ide.IconUtilEx; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.*; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.ui.StrikeoutLabel; +import com.intellij.xml.XmlElementDescriptor; + +import javax.swing.*; +import java.awt.*; + +class LookupCellRenderer implements ListCellRenderer { + private final int ICON_FLAGS; + private final Icon EMPTY_ICON; + public final int ICON_WIDTH; + private final Font NORMAL_FONT; + private final Font BOLD_FONT; + private final Font SMALL_FONT; + private final int FONT_WIDTH; + + public static final Color BACKGROUND_COLOR = new Color(235, 244, 254); + private static final Color FOREGROUND_COLOR = Color.black; + private static final Color GRAYED_FOREGROUND_COLOR = new Color(160, 160, 160); + private static final Color SELECTED_BACKGROUND_COLOR = new Color(0, 82, 164); + private static final Color SELECTED_FOREGROUND_COLOR = Color.white; + private static final Color SELECTED_GRAYED_FOREGROUND_COLOR = Color.white; + + private static final Color PREFIX_FOREGROUND_COLOR = new Color(176, 0, 176); + private static final Color SELECTED_PREFIX_FOREGROUND_COLOR = new Color(249, 236, 204); + + private static final Color EMPTY_ITEM_FOREGROUND_COLOR = FOREGROUND_COLOR; + + private static final int MAX_LENGTH = 70; + + private final boolean SHOW_SIGNATURES; + + private LookupImpl myLookup; + + private StrikeoutLabel myLabel0; // highlighted part of name + private StrikeoutLabel myLabel1; // rest of name + private StrikeoutLabel myLabel2; // parameters and tail text + private JLabel myLabel3; // type + private JPanel myPanel; + private boolean myHasNonTemplates; + private int myMaxTemplateDescriptionLength = 0; + + public LookupCellRenderer(LookupImpl lookup) { + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + NORMAL_FONT = scheme.getFont(EditorFontType.PLAIN); + BOLD_FONT = scheme.getFont(EditorFontType.BOLD); + SMALL_FONT = NORMAL_FONT; + + CodeInsightSettings settings = CodeInsightSettings.getInstance(); + SHOW_SIGNATURES = settings.SHOW_SIGNATURES_IN_LOOKUPS; + ICON_FLAGS = SHOW_SIGNATURES ? Iconable.ICON_FLAG_VISIBILITY : 0; + EMPTY_ICON = IconUtilEx.getEmptyIcon(SHOW_SIGNATURES); + ICON_WIDTH = EMPTY_ICON.getIconWidth(); + + myLookup = lookup; + myLabel0 = new StrikeoutLabel("", SwingConstants.LEFT); + myLabel0.setOpaque(true); + myLabel1 = new StrikeoutLabel("", SwingConstants.LEFT); + myLabel1.setOpaque(true); + myLabel2 = new StrikeoutLabel("", SwingConstants.LEFT); + myLabel2.setOpaque(true); + myLabel3 = new JLabel("", SwingConstants.LEFT); + myLabel3.setOpaque(true); + myPanel = new JPanel(new BorderLayout()){ + public void paint(Graphics g){ + Graphics2D g2d=(Graphics2D)g; + UISettings uiSettings=UISettings.getInstance(); + if(uiSettings.ANTIALIASING_IN_EDITOR){ + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + }else{ + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + } + super.paint(g); + } + }; + myPanel.add(myLabel0, BorderLayout.WEST); + JPanel panel = new JPanel(new BorderLayout()); + myPanel.add(panel, BorderLayout.CENTER); + panel.add(myLabel1, BorderLayout.WEST); + panel.add(myLabel2, BorderLayout.CENTER); + panel.add(myLabel3, BorderLayout.EAST); + + JLabel label = myLabel0; + label.setText("A"); + label.setIcon(null); + label.setFont(NORMAL_FONT); + FONT_WIDTH = label.getPreferredSize().width; + + final LookupItem[] items = lookup.getItems(); + for (int i = 0; i < items.length; i++) { + LookupItem item = items[i]; + if (!(item.getObject() instanceof Template)) { + myHasNonTemplates = true; + break; + } + else { + Template template = (Template)item.getObject(); + myMaxTemplateDescriptionLength = Math.max(myMaxTemplateDescriptionLength, template.getDescription().length()); + } + } + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean hasFocus) { + + LookupItem item = (LookupItem)value; + JLabel label0 = getLabel0(item); + JLabel label1 = getLabel1(item); + JLabel label2 = getLabel2(item); + JLabel label3 = getLabel3(item); + Color background = isSelected ? SELECTED_BACKGROUND_COLOR : BACKGROUND_COLOR; + Color foreground = isSelected ? SELECTED_FOREGROUND_COLOR : FOREGROUND_COLOR; + + Color sampleBackground = background; + + if (item.getObject() instanceof LookupValueWithUIHint) { + Color proposedBackground = ((LookupValueWithUIHint)item.getObject()).getColorHint(); + + if (proposedBackground == null) { + proposedBackground = BACKGROUND_COLOR; + } + + sampleBackground = proposedBackground; + label3.setText(" "); + } + + if (item.getAttribute(LookupImpl.EMPTY_ITEM_ATTRIBUTE) != null){ + foreground = EMPTY_ITEM_FOREGROUND_COLOR; + } + label0.setBackground(background); + label1.setBackground(background); + label2.setBackground(background); + label3.setBackground(sampleBackground); + label0.setForeground(isSelected ? SELECTED_PREFIX_FOREGROUND_COLOR : PREFIX_FOREGROUND_COLOR); + label1.setForeground(foreground); + label2.setForeground(foreground); + label3.setForeground(foreground); + + boolean isSmall = item.getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null; + if (isSmall){ + label2.setForeground(isSelected ? SELECTED_GRAYED_FOREGROUND_COLOR : GRAYED_FOREGROUND_COLOR); + } + + return myPanel; + } + + private JLabel getLabel0(LookupItem item){ + Object o = item.getObject(); + String prefix = myLookup.getPrefix().toLowerCase(); + String name = getName(item); + String text; + Icon icon; + if (prefix.length() > 0 && name.toLowerCase().startsWith(prefix)){ + text = name.substring(0, prefix.length()); + icon = getIcon(item); + } + else{ + text = ""; + icon = null; + } + boolean highlighted = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null; + boolean bold = highlighted || o instanceof PsiKeyword || o instanceof PsiExpression; + boolean strikeout = isToStrikeout(item); + + StrikeoutLabel label = myLabel0; + label.setText(text); + label.setIcon(icon); + label.setFont(bold ? BOLD_FONT : NORMAL_FONT); + label.setStrikeout(strikeout); + return label; + } + + private JLabel getLabel1(LookupItem item){ + Object o = item.getObject(); + String prefix = myLookup.getPrefix().toLowerCase(); + String name = getName(item); + String text; + Icon icon; + if (prefix.length() > 0 && name.toLowerCase().startsWith(prefix)){ + text = name.substring(prefix.length()); + icon = null; + } + else{ + text = name; + icon = getIcon(item); + } + boolean highlighted = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null; + boolean bold = highlighted || o instanceof PsiKeyword || o instanceof PsiExpression; + boolean overstrike = isToStrikeout(item); + + StrikeoutLabel label = myLabel1; + label.setText(text); + label.setIcon(icon); + label.setFont(bold ? BOLD_FONT : NORMAL_FONT); + label.setStrikeout(overstrike); + return label; + } + + private JLabel getLabel2(final LookupItem item){ + String text = null; + + if (showSignature(item)){ + Object o = item.getObject(); + if (o instanceof PsiElement) { + final PsiElement element = (PsiElement)o; + if (element.isValid() && element instanceof PsiMethod){ + PsiMethod method = (PsiMethod)element; + final PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR); + text = PsiFormatUtil.formatMethod(method, + substitutor != null ? substitutor : PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE); + } + } + } + + String tailText = (String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR); + if (tailText != null){ + if (text == null){ + text = tailText; + } + else{ + text += tailText; + } + } + if(item.getAttribute(LookupItem.INDICATE_ANONYMOUS) != null){ + if(item.getObject() instanceof PsiClass){ + final PsiClass psiClass = (PsiClass) item.getObject(); + if(psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)){ + text += "{...}"; + } + } + } + + StrikeoutLabel label = myLabel2; + if (text != null){ + String s = text; + int width = getTextWidth(item); + int n = width - MAX_LENGTH * FONT_WIDTH; + if (n > 0){ + n = Math.min(n, (s.length() - 7) * FONT_WIDTH); + if (n >= 0){ + s = s.substring(0, s.length() - n / FONT_WIDTH - 3) + "..."; + } + } + label.setText(s); + } + else{ + label.setText(""); + } + boolean isSmall = item.getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null; + label.setFont(isSmall ? SMALL_FONT : NORMAL_FONT); + boolean overstrike = isToStrikeout(item); + label.setStrikeout(overstrike); + return label; + } + + private boolean showSignature(LookupItem item) { + return SHOW_SIGNATURES || item.getAttribute(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null; + } + + private JLabel getLabel3(LookupItem item){ + myLabel3.setHorizontalTextPosition(JLabel.RIGHT); + + Object o = item.getObject(); + String text = null; + if (o instanceof PsiElement){ + if (showSignature(item)) { + PsiType typeAttr = (PsiType)item.getAttribute(LookupItem.TYPE_ATTR); + if (typeAttr != null){ + text = typeAttr.getPresentableText(); + } + else{ + final PsiElement element = (PsiElement)o; + if (element.isValid()) { + if (element instanceof PsiMethod){ + PsiMethod method = (PsiMethod)element; + if (!method.isConstructor()){ + final PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR); + if(substitutor != null) + text = substitutor.substitute(method.getReturnType()).getPresentableText(); + else + text = method.getReturnType().getPresentableText(); + } + } + else if (element instanceof PsiVariable){ + PsiVariable variable = (PsiVariable)element; + text = variable.getType().getPresentableText(); + } + else if (element instanceof PsiExpression){ + PsiExpression expression = (PsiExpression)element; + PsiType type = expression.getType(); + if (type != null){ + text = type.getPresentableText(); + } + } + } + } + } + } + else if (o instanceof Template){ + text = getTemplateDescriptionString((Template)o); + } + + JLabel label = myLabel3; + label.setText(text != null ? text + " " : ""); + label.setFont(NORMAL_FONT); + return label; + } + + private static String getName(final LookupItem item){ + final Object o = item.getObject(); + String name = null; + if (o instanceof PsiElement) { + final PsiElement element = (PsiElement)o; + if (element.isValid()) { + name = PsiUtil.getName(element); + + if (element instanceof PsiAnonymousClass) { + name = null; + } + else if(element instanceof PsiClass){ + PsiSubstitutor substitutor = (PsiSubstitutor)item.getAttribute(LookupItem.SUBSTITUTOR); + if (substitutor != null && !substitutor.isValid()) { + PsiType type = (PsiType)item.getAttribute(LookupItem.TYPE); + if (type != null) { + name = type.getPresentableText(); + } + } + else { + name = LookupItemUtil.formatTypeName((PsiClass)element, substitutor); + } + } + else if (element instanceof PsiKeyword || element instanceof PsiExpression || element instanceof PsiTypeElement){ + name = element.getText(); + } + } + } + else if (o instanceof PsiType){ + name = ((PsiType)o).getPresentableText(); + } + else if (o instanceof Template){ + name = getKeyString((Template)o); + } + else if (o instanceof XmlElementDescriptor) { + name = ((XmlElementDescriptor)o).getDefaultName(); + } + else if (o instanceof PsiMetaData) { + name = ((PsiMetaData)o).getName(); + } + else if (o instanceof PresentableLookupValue ) { + name = ((PresentableLookupValue)o).getPresentation(); + } else { + name = String.valueOf(o); + } + if (name == null){ + name = ""; + } + + if(item.getAttribute(LookupItem.FORCE_QUALIFY) != null){ + if(o instanceof PsiElement && ((PsiElement)o).getParent() instanceof PsiClass) + name = ((PsiClass) ((PsiElement) o).getParent()).getName() + "." + name; + } + + return name; + } + + private Icon getIcon(LookupItem item){ + Icon iconAttr = (Icon)item.getAttribute(LookupItem.ICON_ATTR); + if (iconAttr != null) return iconAttr; + Icon icon = null; + Object o = item.getObject(); + if (o instanceof PsiElement) { + final PsiElement element = (PsiElement)o; + if (element.isValid()) { + icon = element.getIcon(ICON_FLAGS); + } + } + if (icon == null){ + icon = EMPTY_ICON; + } + return icon; + } + + public int getMaximumWidth(final LookupItem[] items){ + int maxWidth = 0; + for(int i = 0; i < items.length; i++) { + LookupItem item = items[i]; + maxWidth = Math.max(maxWidth, getTextWidth(item)); + } + maxWidth = Math.min(maxWidth, MAX_LENGTH * FONT_WIDTH); + return maxWidth + EMPTY_ICON.getIconWidth() + myLabel0.getIconTextGap() + FONT_WIDTH; + } + + /** + * Should be called in atomic action. + * @return width in pixels + */ + private int getTextWidth(LookupItem item){ + PsiSubstitutor substitutor = (PsiSubstitutor)item.getAttribute(LookupItem.SUBSTITUTOR); + Object o = item.getObject(); + String text = getName(item); + + substitutor = substitutor != null ? substitutor : PsiSubstitutor.EMPTY; + + if (o instanceof PsiElement) { + PsiElement element = (PsiElement)o; + if (element instanceof PsiMethod){ + PsiMethod method = (PsiMethod)element; + if (showSignature(item)){ + String parms = PsiFormatUtil.formatMethod( + method, + substitutor, + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE); + text += parms; + } + } + } + + final String TYPE_GAP = "XXX"; + if (o instanceof PsiElement) { + if (showSignature(item)){ + PsiType typeAttr = (PsiType)item.getAttribute(LookupItem.TYPE_ATTR); + if (typeAttr != null){ + text += typeAttr.getPresentableText() + TYPE_GAP; + } + else{ + PsiElement element = (PsiElement)o; + if (element instanceof PsiMethod){ + PsiMethod method = (PsiMethod)element; + if (!method.isConstructor()){ + text += substitutor.substitute(method.getReturnType()).getPresentableText() + TYPE_GAP; + } + } + else if (element instanceof PsiVariable){ + PsiVariable variable = (PsiVariable)element; + text += substitutor.substitute(variable.getType()).getPresentableText() + TYPE_GAP; + } + else if (element instanceof PsiExpression){ + PsiExpression expression = (PsiExpression)element; + PsiType type = expression.getType(); + if (type != null){ + text += type.getPresentableText() + TYPE_GAP; + } + } + } + } + } + else if (o instanceof Template){ + text += getTemplateDescriptionString((Template)o) + TYPE_GAP; + } + + if(item.getAttribute(LookupItem.FORCE_QUALIFY) != null){ + if(o instanceof PsiElement && ((PsiElement)o).getParent() instanceof PsiClass) + text = ((PsiClass) ((PsiElement) o).getParent()).getName() + "." + text; + } + + + int width = myPanel.getFontMetrics(NORMAL_FONT).stringWidth(text) + 2; + + String tailText = (String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR); + if(item.getAttribute(LookupItem.INDICATE_ANONYMOUS) != null){ + if(item.getObject() instanceof PsiClass){ + final PsiClass psiClass = (PsiClass) item.getObject(); + if(psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)){ + tailText += "{...}"; + } + } + } + + if (tailText != null){ + boolean isSmall = item.getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null; + FontMetrics fontMetrics = myPanel.getFontMetrics(isSmall ? SMALL_FONT : NORMAL_FONT); + width += fontMetrics.stringWidth(tailText); + } + + return width; + } + + private boolean isToStrikeout(LookupItem item) { + final PsiMethod[] allMethods = (PsiMethod[])item.getAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE); + if (allMethods != null){ + for(int i = 0; i < allMethods.length; i++){ + PsiMethod method = allMethods[i]; + if (!method.isValid()) { //? + return false; + } + if (!isDeprecated(method)){ + return false; + } + } + return true; + } + else{ + Object o = item.getObject(); + if (o instanceof PsiElement) { + final PsiElement element = (PsiElement)o; + if (element.isValid()) { + return isDeprecated(element); + } + } + } + return false; + } + + private static boolean isDeprecated(PsiElement element) { + if (!(element instanceof PsiDocCommentOwner)) return false; + return ((PsiDocCommentOwner)element).isDeprecated(); + } + + private static String getKeyString(Template template) { + return template.getKey(); + } + + private String getTemplateDescriptionString(Template template) { + int max = MAX_LENGTH - TemplateSettings.getInstance().getMaxKeyLength(); + max = Math.min(max, myMaxTemplateDescriptionLength + 1); + + StringBuffer buffer = new StringBuffer(max); + buffer.append(' '); + buffer.append(template.getDescription()); + if (buffer.length() > max){ + buffer.setLength(max - "...".length()); + buffer.append("..."); + } + else if (!myHasNonTemplates){ + while(buffer.length() < max){ + buffer.append(' '); + } + } + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupImpl.java new file mode 100644 index 00000000000..72da8430ff5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -0,0 +1,526 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +public class LookupImpl extends LightweightHint implements Lookup { + static final Object EMPTY_ITEM_ATTRIBUTE = Key.create("emptyItem"); + static final Object ALL_METHODS_ATTRIBUTE = Key.create("allMethods"); + + public static final Key LOOKUP_IN_EDITOR_KEY = Key.create("LOOKUP_IN_EDITOR_KEY"); + + private final Project myProject; + private final Editor myEditor; + private final LookupItem[] myItems; + private String myPrefix; + private final LookupItemPreferencePolicy myItemPreferencePolicy; + private final CharFilter myCharFilter; + + private RangeMarker myLookupStartMarker; + private String myInitialPrefix; + private JList myList; + private LookupCellRenderer myCellRenderer; + private Boolean myPositionedAbove = null; + + private CaretListener myEditorCaretListener; + private EditorMouseListener myEditorMouseListener; + private DocumentListener myDocumentListener; + + private ArrayList myListeners = new ArrayList(); + private HashMap myUserMap = new HashMap(); + + private boolean myCanceled = true; + private boolean myDisposed = false; + private int myIndex; + + public LookupImpl(Project project, + Editor editor, + LookupItem[] items, + String prefix, + LookupItemPreferencePolicy itemPreferencePolicy, + CharFilter filter){ + super(new JPanel(new BorderLayout())); + myProject = project; + myEditor = editor; + myItems = items; + myPrefix = prefix; + myItemPreferencePolicy = itemPreferencePolicy; + myCharFilter = filter; + + myEditor.putUserData(LOOKUP_IN_EDITOR_KEY, this); + + if (myPrefix == null){ + myPrefix = ""; + } + myInitialPrefix = myPrefix; + + myList = new JList() ; + myList.setFocusable(false); + + myCellRenderer = new LookupCellRenderer(this); + myList.setCellRenderer(myCellRenderer); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + updateList(); + + myList.setBackground(LookupCellRenderer.BACKGROUND_COLOR); + + JScrollPane scrollPane = new JScrollPane(myList); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(new com.intellij.ui.plaf.beg.BegPopupMenuBorder()); + getComponent().add(scrollPane, BorderLayout.CENTER); + + myEditorCaretListener = new CaretListener() { + public void caretPositionChanged(CaretEvent e){ + int curOffset = myEditor.getCaretModel().getOffset(); + if (curOffset != myLookupStartMarker.getStartOffset() + myPrefix.length()){ + hide(); + } + } + }; + myEditor.getCaretModel().addCaretListener(myEditorCaretListener); + + myEditorMouseListener = new EditorMouseAdapter() { + public void mouseClicked(EditorMouseEvent e){ + e.consume(); + hide(); + } + }; + myEditor.addEditorMouseListener(myEditorMouseListener); + + myDocumentListener = new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + if (!myLookupStartMarker.isValid()){ + hide(); + } + } + }; + myEditor.getDocument().addDocumentListener(myDocumentListener); + + myList.addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e){ + LookupItem item = (LookupItem)myList.getSelectedValue(); + if (item != null && item.getAttribute(EMPTY_ITEM_ATTRIBUTE) != null){ + item = null; + } + fireCurrentItemChanged(item); + } + } + ); + + myList.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e){ + if (e.getClickCount() == 2){ + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + finishLookup(NORMAL_SELECT_CHAR); + } + }, + "", + null + ); + } + } + } + ); + selectMostPreferableItem(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run(){ + if (myIndex >= 0 && myIndex < myList.getModel().getSize()){ + ListScrollingUtil.selectItem(myList, myIndex); + } + else if(myItems.length > 0){ + ListScrollingUtil.selectItem(myList, 0); + } + } + }); + } + + + Project getProject(){ + return myProject; + } + + String getPrefix(){ + return myPrefix; + } + + void setPrefix(String prefix){ + myPrefix = prefix; + } + + String getInitialPrefix(){ + return myInitialPrefix; + } + + JList getList(){ + return myList; + } + + public LookupItem[] getItems(){ + return myItems; + } + + void updateList(){ + Object oldSelected = myList.getSelectedValue(); + DefaultListModel model = new DefaultListModel(); + ArrayList array = new ArrayList(); + String prefix = myPrefix.toLowerCase(); + for(int i = 0; i < myItems.length; i++){ + LookupItem item = myItems[i]; + String text = item.getLookupString(); + if (text.toLowerCase().startsWith(prefix)){ + model.addElement(item); + array.add(item); + } + } + boolean isEmpty = array.size() == 0; + if (isEmpty){ + LookupItem item = new LookupItem("No suggestions", ""); + item.setAttribute(EMPTY_ITEM_ATTRIBUTE, ""); + model.addElement(item); + array.add(item); + } + //PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.saveToString()); + myList.setModel(model); + + myList.setVisibleRowCount(Math.min(myList.getModel().getSize(), CodeInsightSettings.getInstance().LOOKUP_HEIGHT)); + + if (!isEmpty){ + selectMostPreferableItem(); + if (myIndex >= 0){ + ListScrollingUtil.selectItem(myList, myIndex); + } + else{ + if (oldSelected == null || !ListScrollingUtil.selectItem(myList, oldSelected)){ + ListScrollingUtil.selectItem(myList, 0); + } + } + } + + LookupItem[] items = (LookupItem[])array.toArray(new LookupItem[array.size()]); + int maxWidth = myCellRenderer.getMaximumWidth(items); + myList.setFixedCellWidth(maxWidth); + } + + /** + * @return point in layered pane coordinate system. + */ + Point calculatePosition(){ + Dimension dim = getComponent().getPreferredSize(); + int lookupStart = myLookupStartMarker.getStartOffset(); + LogicalPosition pos = myEditor.offsetToLogicalPosition(lookupStart); + Point location = myEditor.logicalPositionToXY(pos); + location.y += myEditor.getLineHeight(); + JComponent editorComponent = myEditor.getComponent(); + JComponent internalComponent = myEditor.getContentComponent(); + JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); + Point layeredPanePoint=SwingUtilities.convertPoint(internalComponent,location, layeredPane); + layeredPanePoint.x = layeredPanePoint.x - myCellRenderer.ICON_WIDTH - 5 /*?*/; + if (dim.width > layeredPane.getWidth()){ + dim.width = layeredPane.getWidth(); + } + int wshift = layeredPane.getWidth() - (layeredPanePoint.x + dim.width); + if (wshift < 0){ + layeredPanePoint.x += wshift; + } + if (myPositionedAbove == null){ + int hshift = layeredPane.getHeight() - (layeredPanePoint.y + dim.height); + myPositionedAbove = hshift < 0 ? Boolean.TRUE : Boolean.FALSE; + } + if (myPositionedAbove.booleanValue()){ + layeredPanePoint.y -= dim.height + myEditor.getLineHeight(); + } + return layeredPanePoint; + } + + public void finishLookup(final char completionChar){ + final LookupItem item = (LookupItem)myList.getSelectedValue(); + if (item == null){ + hide(); + return; + } + + if(item.getObject() instanceof DeferredUserLookupValue) { + if(!((DeferredUserLookupValue)item.getObject()).handleUserSelection(item,myProject)) { + hide(); + return; + } + } + + final String s = item.getLookupString(); + final int prefixLength = myPrefix.length(); + if (item.getAttribute(EMPTY_ITEM_ATTRIBUTE) != null){ + hide(); + return; + } + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run(){ + myCanceled = false; + hide(); + + int lookupStart = myLookupStartMarker.getStartOffset(); + //SD - start + //this patch fixes the problem, that template is finished after showing lookup + LogicalPosition lookupPosition = myEditor.offsetToLogicalPosition(lookupStart); + myEditor.getCaretModel().moveToLogicalPosition(lookupPosition); + //SD - end + + if (myEditor.getSelectionModel().hasSelection()){ + myEditor.getDocument().deleteString(myEditor.getSelectionModel().getSelectionStart(), myEditor.getSelectionModel().getSelectionEnd()); + } + if (s.startsWith(myPrefix)){ + myEditor.getDocument().insertString(lookupStart + prefixLength, s.substring(prefixLength)); + } + else{ + if (prefixLength > 0){ + myEditor.getDocument().deleteString(lookupStart, lookupStart + prefixLength); + } + myEditor.getDocument().insertString(lookupStart, s); + } + int offset = lookupStart + s.length(); + myEditor.getCaretModel().moveToOffset(offset); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + myEditor.getSelectionModel().removeSelection(); + fireItemSelected(item, completionChar); + } + } + ); + } + + public void show(){ + int offset = myEditor.getSelectionModel().hasSelection() + ? myEditor.getSelectionModel().getSelectionStart() + : myEditor.getCaretModel().getOffset(); + int lookupStart = offset - myPrefix.length(); + myLookupStartMarker = myEditor.getDocument().createRangeMarker(lookupStart, lookupStart); + myLookupStartMarker.setGreedyToLeft(true); + //myList.setSelectedIndex(0); + if (ApplicationManager.getApplication().isUnitTestMode()) return; + + Point p = calculatePosition(); + HintManager hintManager = HintManager.getInstance(); + hintManager.showEditorHint(this, myEditor, p, HintManager.HIDE_BY_ESCAPE | HintManager.UPDATE_BY_SCROLLING, 0, false); + } + + private void selectMostPreferableItem(){ + //if (!isVisible()) return; + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (myItemPreferencePolicy == null){ + myIndex = -1; + } + else{ + myItemPreferencePolicy.setPrefix(myPrefix); + DefaultListModel model = (DefaultListModel)myList.getModel(); + Object[] items = model.toArray(); + LookupItem prefItem = null; + int prefItemIndex = -1; + for(int i = 0; i < items.length; i++){ + LookupItem item = (LookupItem)items[i]; + if (prefItem == null){ + prefItem = item; + prefItemIndex = i; + } + else{ + int d = myItemPreferencePolicy.compare(item, prefItem); + if (d < 0){ + prefItem = item; + prefItemIndex = i; + } + } + } + myIndex = prefItem != null ? prefItemIndex : -1; + } + myList.setSelectedIndex(myIndex); + } + + public LookupItem getCurrentItem(){ + LookupItem item = (LookupItem)myList.getSelectedValue(); + if (item != null && item.getAttribute(EMPTY_ITEM_ATTRIBUTE) != null){ + return null; + } + return item; + } + + public void setCurrentItem(LookupItem item){ + ListScrollingUtil.selectItem(myList, item); + } + + public void addLookupListener(LookupListener listener){ + myListeners.add(listener); + } + + public void removeLookupListener(LookupListener listener){ + myListeners.remove(listener); + } + + public Rectangle getCurrentItemBounds(){ + int index = myList.getSelectedIndex(); + Rectangle itmBounds = myList.getCellBounds(index, index); + if (itmBounds == null){ + return null; + } + Rectangle listBounds=myList.getBounds(); + JLayeredPane layeredPane=myList.getRootPane().getLayeredPane(); + Point layeredPanePoint=SwingUtilities.convertPoint(myList,listBounds.x,listBounds.y,layeredPane); + itmBounds.x = layeredPanePoint.x; + itmBounds.y = layeredPanePoint.y; + return itmBounds; + } + + private void fireItemSelected(final LookupItem item, char completionChar){ + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); //[Mike] todo: remove? Valentin thinks it's a major performance hit. + + if (myItemPreferencePolicy != null){ + myItemPreferencePolicy.itemSelected(item); + } + + if (myListeners.size() > 0){ + LookupEvent event = new LookupEvent(this, item, completionChar); + LookupListener[] listeners = (LookupListener[])myListeners.toArray(new LookupListener[myListeners.size()]); + for(int i = 0; i < listeners.length; i++){ + listeners[i].itemSelected(event); + } + } + } + + private void fireLookupCanceled(){ + if (myListeners.size() > 0){ + LookupEvent event = new LookupEvent(this, null); + LookupListener[] listeners = (LookupListener[])myListeners.toArray(new LookupListener[myListeners.size()]); + for(int i = 0; i < listeners.length; i++){ + listeners[i].lookupCanceled(event); + } + } + } + + private void fireCurrentItemChanged(LookupItem item){ + if (myListeners.size() > 0){ + LookupEvent event = new LookupEvent(this, item); + LookupListener[] listeners = (LookupListener[])myListeners.toArray(new LookupListener[myListeners.size()]); + for(int i = 0; i < listeners.length; i++){ + listeners[i].currentItemChanged(event); + } + } + } + + public boolean fillInCommonPrefix(boolean toCompleteUniqueName){ + ListModel listModel = myList.getModel(); + String commonPrefix = null; + String subprefix = null; + boolean isStrict = false; + for(int i = 0; i < listModel.getSize(); i++){ + LookupItem item = (LookupItem)listModel.getElementAt(i); + if (item.getAttribute(EMPTY_ITEM_ATTRIBUTE) != null) return false; + String string = item.getLookupString(); + String string1 = string.substring(0, myPrefix.length()); + String string2 = string.substring(myPrefix.length()); + if (commonPrefix == null){ + commonPrefix = string2; + subprefix = string1; + } + else{ + while(commonPrefix.length() > 0){ + if (string2.startsWith(commonPrefix)){ + if (string2.length() > commonPrefix.length()){ + isStrict = true; + } + if (!string1.equals(subprefix)){ + subprefix = null; + } + break; + } + commonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1); + } + if (commonPrefix.length() == 0) return false; + } + } + + if (!isStrict && !toCompleteUniqueName) return false; + + final String _subprefix = subprefix; + final String _commonPrefix = commonPrefix; + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run(){ + if (_subprefix != null){ // correct case + int lookupStart = myLookupStartMarker.getStartOffset(); + myEditor.getDocument().replaceString(lookupStart, lookupStart + _subprefix.length(), _subprefix); + } + myPrefix += _commonPrefix; + EditorModificationUtil.insertStringAtCaret(myEditor, _commonPrefix); + } + }, + null, + null + ); + myList.repaint(); // to refresh prefix highlighting + return true; + } + + public boolean isPositionedAboveCaret(){ + return myPositionedAbove.booleanValue(); + } + + public void hide(){ + if (myDisposed) return; + myDisposed = true; + + myEditor.getCaretModel().removeCaretListener(myEditorCaretListener); + myEditor.removeEditorMouseListener(myEditorMouseListener); + myEditor.getDocument().removeDocumentListener(myDocumentListener); + myEditor.putUserData(LOOKUP_IN_EDITOR_KEY, null); + + super.hide(); + + if (myCanceled){ + fireLookupCanceled(); + } + } + + public T getUserData(Key key){ + return (T)myUserMap.get(key); + } + + public void putUserData(Key key, T value){ + if (value != null){ + myUserMap.put(key, value); + } + else{ + myUserMap.remove(key); + } + } + + static boolean isNarrowDownMode(){ + return CodeInsightSettings.getInstance().NARROW_DOWN_LOOKUP_LIST; + } + + public CharFilter getCharFilter() { + return myCharFilter; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java new file mode 100644 index 00000000000..7872c66e924 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java @@ -0,0 +1,236 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.EditorFactoryAdapter; +import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.Alarm; +import com.intellij.util.containers.HashMap; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +public class LookupManagerImpl extends LookupManager implements ProjectComponent { + private final Project myProject; + + protected Lookup myActiveLookup = null; + protected Editor myActiveLookupEditor = null; + private PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this); + + protected static final Comparator COMPARATOR = new Comparator(){ + public int compare(Object o1, Object o2){ + LookupItem item1 = (LookupItem)o1; + LookupItem item2 = (LookupItem)o2; + return item1.getLookupString().compareToIgnoreCase(item2.getLookupString()); + } + }; + private boolean myIsDisposed; + private EditorFactoryAdapter myEditorFactoryListener; + + public LookupManagerImpl(Project project, EditorFactory editorFactory) { + myProject = project; + + myEditorFactoryListener = new EditorFactoryAdapter() { + public void editorReleased(EditorFactoryEvent event) { + if (event.getEditor() == myActiveLookupEditor){ + hideActiveLookup(); + } + } + }; + editorFactory.addEditorFactoryListener(myEditorFactoryListener); + } + + public String getComponentName(){ + return "LookupManager"; + } + + public void initComponent() { } + + public void disposeComponent(){ + EditorFactory.getInstance().removeEditorFactoryListener(myEditorFactoryListener); + myIsDisposed = true; + } + + public void projectOpened(){ + } + + public void projectClosed(){ + } + + public Lookup showLookup( + final Editor editor, + LookupItem[] items, + String prefix, + LookupItemPreferencePolicy itemPreferencePolicy, + CharFilter filter + ) { + hideActiveLookup(); + + final CodeInsightSettings settings = CodeInsightSettings.getInstance(); + + items = (LookupItem[])items.clone(); + if (!settings.SHOW_SIGNATURES_IN_LOOKUPS){ + items = filterEqualSignatures(items); + } + + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); + + if (sortItems(psiFile, items)) { + Arrays.sort(items, COMPARATOR); + } + + final Alarm alarm = new Alarm(); + final Runnable request = new Runnable(){ + public void run() { + JavaDocManager.getInstance(myProject).showJavaDocInfo(editor, psiFile, false); + } + }; + if (settings.AUTO_POPUP_JAVADOC_INFO){ + alarm.addRequest(request, settings.JAVADOC_INFO_DELAY); + } + + final DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(myProject); + if (daemonCodeAnalyzer != null) { + daemonCodeAnalyzer.setUpdateByTimerEnabled(false); + } + myActiveLookup = new LookupImpl(myProject, editor, items, prefix, itemPreferencePolicy, filter); + myActiveLookupEditor = editor; + ((LookupImpl)myActiveLookup).show(); + myActiveLookup.addLookupListener( + new LookupAdapter(){ + public void itemSelected(LookupEvent event) { + dispose(); + } + + public void lookupCanceled(LookupEvent event) { + dispose(); + } + + public void currentItemChanged(LookupEvent event) { + alarm.cancelAllRequests(); + if (settings.AUTO_POPUP_JAVADOC_INFO){ + alarm.addRequest(request, settings.JAVADOC_INFO_DELAY); + } + } + + private void dispose(){ + alarm.cancelAllRequests(); + if (daemonCodeAnalyzer != null) { + daemonCodeAnalyzer.setUpdateByTimerEnabled(true); + } + myActiveLookup.removeLookupListener(this); + Lookup lookup = myActiveLookup; + myActiveLookup = null; + myActiveLookupEditor = null; + myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, lookup, myActiveLookup); + } + } + ); + myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, null, myActiveLookup); + return myActiveLookup; + } + + public void hideActiveLookup() { + if (myActiveLookup != null){ + ((LookupImpl)myActiveLookup).hide(); + Lookup lookup = myActiveLookup; + myActiveLookup = null; + myActiveLookupEditor = null; + myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, lookup, myActiveLookup); + } + } + + private static boolean sortItems(PsiFile containingFile, LookupItem[] items) { + if (!(containingFile instanceof XmlFile)) return true; + + for (int i = 0; i < items.length; i++) { + LookupItem item = items[i]; + if (item.getObject() instanceof PsiElement) return true; + } + + return CodeInsightSettings.getInstance().SORT_XML_LOOKUP_ITEMS; + } + + public Lookup getActiveLookup() { + return myActiveLookup; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.removePropertyChangeListener(listener); + } + + public PsiElement[] getAllElementsForItem(LookupItem item) { + PsiMethod[] allMethods = (PsiMethod[])item.getAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE); + if (allMethods != null){ + return allMethods; + } + else{ + if (item.getObject() instanceof PsiElement){ + return new PsiElement[]{(PsiElement)item.getObject()}; + } + else{ + return null; + } + } + } + + public boolean isDisposed() { + return myIsDisposed; + } + + protected LookupItem[] filterEqualSignatures(LookupItem[] items) { + ArrayList array = new ArrayList(); + HashMap methodNameToItem = new HashMap(); + for(int i = 0; i < items.length; i++){ + LookupItem item = items[i]; + if (item.getAttribute(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null) { + array.add(item); + continue; + } + Object o = item.getObject(); + if (o instanceof PsiMethod){ + String name = ((PsiMethod)o).getName(); + LookupItem item1 = (LookupItem)methodNameToItem.get(name); + if (item1 != null) { + ArrayList allMethods = (ArrayList)item1.getAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE); + allMethods.add(o); + continue; + } + else{ + methodNameToItem.put(name, item); + ArrayList allMethods = new ArrayList(); + allMethods.add(o); + item.setAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE, allMethods); + } + } + array.add(item); + } + items = (LookupItem[])array.toArray(new LookupItem[array.size()]); + for(int i = 0; i < items.length; i++){ + LookupItem item = items[i]; + ArrayList allMethods = (ArrayList)item.getAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE); + if (allMethods != null){ + item.setAttribute(LookupImpl.ALL_METHODS_ATTRIBUTE, allMethods.toArray(new PsiMethod[allMethods.size()])); + } + } + return items; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageDownHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageDownHandler.java new file mode 100644 index 00000000000..9432b49d72b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageDownHandler.java @@ -0,0 +1,24 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtil; + +class PageDownHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public PageDownHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtil.movePageDown(lookup.getList()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageUpHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageUpHandler.java new file mode 100644 index 00000000000..9b48a05b947 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/PageUpHandler.java @@ -0,0 +1,24 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtil; + +class PageUpHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public PageUpHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtil.movePageUp(lookup.getList()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TestLookupManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TestLookupManager.java new file mode 100644 index 00000000000..8cb8296c036 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TestLookupManager.java @@ -0,0 +1,91 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.lookup.CharFilter; +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlFile; + +import java.util.Arrays; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.08.2003 + * Time: 16:20:00 + * To change this template use Options | File Templates. + */ +public class TestLookupManager extends LookupManagerImpl{ + private Project myProject; + public TestLookupManager(Project project){ + super(project, EditorFactory.getInstance()); + myProject = project; + } + + public Lookup showLookup( + final Editor editor, + LookupItem[] items, + String prefix, + LookupItemPreferencePolicy itemPreferencePolicy, + CharFilter filter) { + hideActiveLookup(); + + final CodeInsightSettings settings = CodeInsightSettings.getInstance(); + + items = (LookupItem[])items.clone(); + if (!settings.SHOW_SIGNATURES_IN_LOOKUPS){ + items = filterEqualSignatures(items); + } + + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); + + if (sortItems(psiFile, items)) { + Arrays.sort(items, COMPARATOR); + } + + myActiveLookup = new LookupImpl(myProject, editor, items, prefix, itemPreferencePolicy, filter); + myActiveLookupEditor = editor; + ((LookupImpl)myActiveLookup).show(); + return myActiveLookup; + } + + private static boolean sortItems(PsiFile containingFile, LookupItem[] items) { + if (!(containingFile instanceof XmlFile)) return true; + + for (int i = 0; i < items.length; i++) { + LookupItem item = items[i]; + if (item.getObject() instanceof PsiElement) return true; + } + + return CodeInsightSettings.getInstance().SORT_XML_LOOKUP_ITEMS; + } + + + public void forceSelection(char completion, int index){ + final LookupImpl lookup = ((LookupImpl)myActiveLookup); + if(lookup == null) throw new RuntimeException("There are no items in this lookup"); + final LookupItem[] items = lookup.getItems(); + final LookupItem lookupItem = items[index]; + lookup.setCurrentItem(lookupItem); + lookup.finishLookup(completion); + } + + public void forceSelection(char completion, LookupItem item){ + final LookupImpl lookup = ((LookupImpl)myActiveLookup); + lookup.setCurrentItem(item); + lookup.finishLookup(completion); + } + + + public LookupItem[] getItems(){ + final LookupImpl lookup = ((LookupImpl)myActiveLookup); + return lookup != null ? lookup.getItems() : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TypedHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TypedHandler.java new file mode 100644 index 00000000000..45a2a33c5f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/TypedHandler.java @@ -0,0 +1,84 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.lookup.CharFilter; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.actionSystem.TypedActionHandler; +import com.intellij.openapi.project.Project; +import com.intellij.ui.ListScrollingUtil; + +import javax.swing.*; +import java.awt.*; + +class TypedHandler implements TypedActionHandler { + private final TypedActionHandler myOriginalHandler; + + public TypedHandler(TypedActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(final Editor editor, final char charTyped, DataContext dataContext){ + final LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, charTyped, dataContext); + return; + } + + CharFilter charFilter = lookup.getCharFilter(); + final int result = charFilter.accept(charTyped); + + CommandProcessor.getInstance().executeCommand( + (Project)dataContext.getData(DataConstants.PROJECT), new Runnable() { + public void run(){ + EditorModificationUtil.deleteSelectedText(editor); + if (result == CharFilter.ADD_TO_PREFIX) { + lookup.setPrefix(lookup.getPrefix() + charTyped); + EditorModificationUtil.insertStringAtCaret(editor, String.valueOf(charTyped)); } + } + }, + "", + null + ); + + if (result == CharFilter.ADD_TO_PREFIX){ + if (LookupImpl.isNarrowDownMode()){ + lookup.updateList(); + Point point=lookup.calculatePosition(); + Dimension preferredSize = lookup.getComponent().getPreferredSize(); + lookup.setBounds(point.x,point.y,preferredSize.width,preferredSize.height); + } + else{ + String prefix = lookup.getPrefix().toLowerCase(); + ListModel model = lookup.getList().getModel(); + for(int i = 0; i < model.getSize(); i++){ + LookupItem item = (LookupItem)model.getElementAt(i); + String s = item.getLookupString(); + if (s.toLowerCase().startsWith(prefix)){ + ListScrollingUtil.selectItem(lookup.getList(), i); + break; + } + } + } + + lookup.getList().repaint(); + } + else{ + if (result == CharFilter.SELECT_ITEM_AND_FINISH_LOOKUP){ + LookupItem item = lookup.getCurrentItem(); + if (item != null){ + FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.finishByDotEtc"); + lookup.finishLookup(charTyped); + return; + } + } + + lookup.hide(); + myOriginalHandler.execute(editor, charTyped, dataContext); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/UpHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/UpHandler.java new file mode 100644 index 00000000000..594bdd64c27 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/UpHandler.java @@ -0,0 +1,29 @@ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.ui.ListScrollingUtilEx; + +class UpHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public UpHandler(EditorActionHandler originalHandler){ + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + if (lookup == null){ + myOriginalHandler.execute(editor, dataContext); + return; + } + + ListScrollingUtilEx.moveUp(lookup.getList(), 0); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + return lookup != null || myOriginalHandler.isEnabled(editor, dataContext); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java new file mode 100644 index 00000000000..8bc0cf74cb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java @@ -0,0 +1,27 @@ +package com.intellij.codeInsight.lookup.impl.actions; + +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class ChooseItemAction extends EditorAction { + public ChooseItemAction(){ + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + lookup.finishLookup(Lookup.NORMAL_SELECT_CHAR); + } + } + + public void update(Editor editor, Presentation presentation, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + presentation.setEnabled(lookup != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java new file mode 100644 index 00000000000..cb0f91ac6d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java @@ -0,0 +1,29 @@ +package com.intellij.codeInsight.lookup.impl.actions; + +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class ChooseItemReplaceAction extends EditorAction { + public ChooseItemReplaceAction(){ + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.replace"); + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + lookup.finishLookup(Lookup.REPLACE_SELECT_CHAR); + } + } + + public void update(Editor editor, Presentation presentation, DataContext dataContext){ + LookupImpl lookup = editor.getUserData(LookupImpl.LOOKUP_IN_EDITOR_KEY); + presentation.setEnabled(lookup != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/CtrlMouseHandler.java new file mode 100644 index 00000000000..535ad1d6ef7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/CtrlMouseHandler.java @@ -0,0 +1,688 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.ant.PsiAntElement; +import com.intellij.ant.impl.dom.impl.PsiAntTarget; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.codeInsight.javadoc.JavaDocUtil; +import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction; +import com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; +import com.intellij.openapi.fileEditor.FileEditorManagerEvent; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocToken; +import com.intellij.psi.jsp.JspToken; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlToken; +import com.intellij.ui.LightweightHint; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class CtrlMouseHandler implements ProjectComponent { + private Project myProject; + private static TextAttributes ourReferenceAttributes; + private RangeHighlighter myHighlighter; + private Editor myHighlighterView; + private Cursor myStoredCursor; + private Info myStoredInfo; + private TooltipProvider myTooltipProvider = null; + + private KeyListener myEditorKeyListener = new KeyAdapter() { + public void keyPressed(final KeyEvent e) { + handleKey(e); + } + + public void keyReleased(final KeyEvent e) { + handleKey(e); + } + + private void handleKey(final KeyEvent e) { + int modifiers = e.getModifiers(); + + if (isControlShiftMask(modifiers)) { + if (myTooltipProvider != null) { + if (!myTooltipProvider.isTypeBrowsed()) { + disposeHighlighter(); + } + myTooltipProvider.execute(true); + } + } else if (isControlMask(modifiers)) { + if (myTooltipProvider != null) { + if (myTooltipProvider.isTypeBrowsed()) { + disposeHighlighter(); + } + myTooltipProvider.execute(false); + } + } else { + disposeHighlighter(); + myTooltipProvider = null; + } + } + }; + + private FileEditorManagerListener myFileEditorManagerListener = new FileEditorManagerAdapter() { + public void selectionChanged(FileEditorManagerEvent e) { + disposeHighlighter(); + myTooltipProvider = null; + } + }; + + private VisibleAreaListener myVisibleAreaListener = new VisibleAreaListener() { + public void visibleAreaChanged(VisibleAreaEvent e) { + disposeHighlighter(); + myTooltipProvider = null; + } + }; + + private EditorMouseAdapter myEditorMouseAdapter = new EditorMouseAdapter() { + public void mouseReleased(EditorMouseEvent e) { + disposeHighlighter(); + myTooltipProvider = null; + } + }; + + private EditorMouseMotionListener myEditorMouseMotionListener = new EditorMouseMotionAdapter() { + public void mouseMoved(final EditorMouseEvent e) { + if (e.isConsumed()) { + return; + } + + MouseEvent mouseEvent = e.getMouseEvent(); + + Editor editor = e.getEditor(); + Point point = mouseEvent.getPoint(); + LogicalPosition pos = editor.xyToLogicalPosition(new Point(point.x, point.y)); + int offset = editor.logicalPositionToOffset(pos); + int selStart = editor.getSelectionModel().getSelectionStart(); + int selEnd = editor.getSelectionModel().getSelectionEnd(); + + int modifiers = mouseEvent.getModifiers(); + + if ((!isControlMask(modifiers) && !isControlShiftMask(modifiers)) || offset >= selStart && offset < selEnd) { + disposeHighlighter(); + myTooltipProvider = null; + return; + } + + myTooltipProvider = new TooltipProvider(editor, pos); + myTooltipProvider.execute(isControlShiftMask(modifiers)); + } + }; + + static { + ourReferenceAttributes = new TextAttributes(); + ourReferenceAttributes.setForegroundColor(Color.blue); + ourReferenceAttributes.setEffectColor(Color.blue); + ourReferenceAttributes.setEffectType(EffectType.LINE_UNDERSCORE); + } + + public CtrlMouseHandler(Project project) { + myProject = project; + } + + public String getComponentName() { + return "CtrlMouseHandler"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void projectOpened() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + eventMulticaster.addEditorMouseListener(myEditorMouseAdapter); + eventMulticaster.addEditorMouseMotionListener(myEditorMouseMotionListener); + } + + public void projectClosed() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + eventMulticaster.removeEditorMouseListener(myEditorMouseAdapter); + eventMulticaster.removeEditorMouseMotionListener(myEditorMouseMotionListener); + } + + private static boolean isControlMask(int modifiers) { + int mask = SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK; + return modifiers == mask; + } + + private static boolean isControlShiftMask(int modifiers) { + int mask = (SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK) | KeyEvent.SHIFT_MASK; + return modifiers == mask; + } + + private static class JavaInfoGenerator { + private static void newLine(StringBuffer buffer) { + // Don't know why space has to be added after newline for good text alignment... + buffer.append("\n "); + } + + private static void generateType(StringBuffer buffer, PsiType type, PsiElement context) { + if (type instanceof PsiPrimitiveType) { + buffer.append(type.getCanonicalText()); + + return; + } + + if (type instanceof PsiWildcardType) { + PsiWildcardType wc = ((PsiWildcardType) type); + PsiType bound = wc.getBound(); + + buffer.append("?"); + + if (bound != null) { + buffer.append(wc.isExtends() ? " extends " : " super "); + generateType(buffer, bound, context); + } + } + + if (type instanceof PsiArrayType) { + generateType(buffer, ((PsiArrayType) type).getComponentType(), context); + buffer.append("[]"); + + return; + } + + if (type instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = ((PsiClassType) type).resolveGenerics(); + PsiClass psiClass = result.getElement(); + PsiSubstitutor psiSubst = result.getSubstitutor(); + + if (psiClass == null || psiClass instanceof PsiTypeParameter) { + buffer.append(type.getPresentableText()); + return; + } + + buffer.append(JavaDocUtil.getShortestClassName(psiClass, context)); + + if (psiClass.hasTypeParameters()) { + StringBuffer subst = new StringBuffer(); + boolean goodSubst = true; + + PsiTypeParameter[] params = psiClass.getTypeParameterList().getTypeParameters(); + + subst.append("<"); + for (int i = 0; i < params.length; i++) { + PsiType t = psiSubst.substitute(params[i]); + + if (t == null) { + goodSubst = false; + break; + } + + generateType(subst, t, context); + + if (i < params.length - 1) { + subst.append(", "); + } + } + + if (goodSubst) { + subst.append(">"); + String text = subst.toString(); + + buffer.append(text); + } + } + } + + return; + } + + private static void generateInitializer(StringBuffer buffer, PsiVariable variable) { + PsiExpression initializer = variable.getInitializer(); + if (initializer != null) { + String text = initializer.getText().trim(); + int index1 = text.indexOf('\n'); + if (index1 < 0) index1 = text.length(); + int index2 = text.indexOf('\r'); + if (index2 < 0) index2 = text.length(); + int index = Math.min(index1, index2); + boolean trunc = index < text.length(); + text = text.substring(0, index); + buffer.append(" = "); + buffer.append(text); + if (trunc) { + buffer.append("..."); + } + } + } + + private static void generateModifiers(StringBuffer buffer, PsiElement element) { + String modifiers = PsiFormatUtil.formatModifiers(element, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY); + + if (modifiers.length() > 0) { + buffer.append(modifiers); + buffer.append(" "); + } + } + + private static String generatePackageInfo(PsiPackage aPackage) { + return aPackage.getQualifiedName(); + } + + private static String generateAttributeValueInfo(PsiAntElement antElement) { + if (antElement instanceof PsiAntTarget) return null; + + PsiElement navigationElement = antElement.getNavigationElement(); + if (navigationElement instanceof XmlAttributeValue) { + return PsiTreeUtil.getParentOfType(navigationElement, XmlTag.class).getText(); + } + + return null; + } + + private static String generateClassInfo(PsiClass aClass) { + StringBuffer buffer = new StringBuffer(); + + if (aClass instanceof PsiAnonymousClass) return "anonymous class"; + + PsiFile file = aClass.getContainingFile(); + + if (file instanceof PsiJavaFile) { + String packageName = ((PsiJavaFile) file).getPackageName(); + if (packageName.length() > 0) { + buffer.append(packageName); + newLine(buffer); + } + } + + generateModifiers(buffer, aClass); + + buffer.append(aClass.isInterface() ? "interface " : aClass instanceof PsiTypeParameter ? "class parameter " : "class "); + + buffer.append(JavaDocUtil.getShortestClassName(aClass, aClass)); + + if (aClass.hasTypeParameters()) { + PsiTypeParameter[] parms = aClass.getTypeParameterList().getTypeParameters(); + + buffer.append("<"); + + for (int i = 0; i < parms.length; i++) { + PsiTypeParameter p = parms[i]; + + buffer.append(p.getName()); + + PsiClassType[] refs = p.getExtendsList().getReferencedTypes(); + + if (refs.length > 0) { + buffer.append(" extends "); + + for (int j = 0; j < refs.length; j++) { + generateType(buffer, refs[j], aClass); + + if (j < refs.length - 1) { + buffer.append(" & "); + } + } + } + + if (i < parms.length - 1) { + buffer.append(", "); + } + } + + buffer.append(">"); + } + + PsiReferenceList extendsList = aClass.getExtendsList(); + PsiClassType[] refs = extendsList == null ? PsiClassType.EMPTY_ARRAY : extendsList.getReferencedTypes(); + if (refs.length > 0 || !aClass.isInterface() && !"java.lang.Object".equals(aClass.getQualifiedName())) { + buffer.append(" extends "); + if (refs.length == 0) { + buffer.append("Object"); + } else { + for (int i = 0; i < refs.length; i++) { + generateType(buffer, refs[i], aClass); + + if (i < refs.length - 1) { + buffer.append(", "); + } + } + } + } + + refs = aClass.getImplementsList().getReferencedTypes(); + if (refs.length > 0) { + newLine(buffer); + buffer.append("implements "); + for (int i = 0; i < refs.length; i++) { + generateType(buffer, refs[i], aClass); + + if (i < refs.length - 1) { + buffer.append(", "); + } + } + } + + return buffer.toString(); + } + + private static String generateMethodInfo(PsiMethod method) { + StringBuffer buffer = new StringBuffer(); + + PsiClass parentClass = method.getContainingClass(); + + if (parentClass != null) { + buffer.append(JavaDocUtil.getShortestClassName(parentClass, method)); + newLine(buffer); + } + + generateModifiers(buffer, method); + + PsiTypeParameter[] params = method.getTypeParameterList().getTypeParameters(); + + if (params.length > 0) { + buffer.append("<"); + for (int i = 0; i < params.length; i++) { + PsiTypeParameter param = params[i]; + + buffer.append(param.getName()); + + PsiClassType[] extendees = param.getExtendsList().getReferencedTypes(); + + if (extendees.length > 0) { + buffer.append(" extends "); + + for (int j = 0; j < extendees.length; j++) { + generateType(buffer, extendees[j], method); + + if (j < extendees.length - 1) { + buffer.append(" & "); + } + } + } + + if (i < params.length - 1) { + buffer.append(", "); + } + } + buffer.append("> "); + } + + if (method.getReturnType() != null) { + generateType(buffer, method.getReturnType(), method); + buffer.append(" "); + } + + buffer.append(method.getName()); + + buffer.append(" ("); + PsiParameter[] parms = method.getParameterList().getParameters(); + for (int i = 0; i < parms.length; i++) { + PsiParameter parm = parms[i]; + generateType(buffer, parm.getType(), method); + buffer.append(" "); + if (parm.getName() != null) { + buffer.append(parm.getName()); + } + if (i < parms.length - 1) { + buffer.append(", "); + } + } + + buffer.append(")"); + + PsiClassType[] refs = method.getThrowsList().getReferencedTypes(); + if (refs.length > 0) { + newLine(buffer); + buffer.append(" throws "); + for (int i = 0; i < refs.length; i++) { + PsiClass throwsClass = refs[i].resolve(); + + if (throwsClass != null) { + buffer.append(JavaDocUtil.getShortestClassName(throwsClass, method)); + } else { + buffer.append(refs[i].getPresentableText()); + } + + if (i < refs.length - 1) { + buffer.append(", "); + } + } + } + + return buffer.toString(); + } + + private static String generateFieldInfo(PsiField field) { + StringBuffer buffer = new StringBuffer(); + PsiClass parentClass = field.getContainingClass(); + + if (parentClass != null) { + buffer.append(JavaDocUtil.getShortestClassName(parentClass, field)); + newLine(buffer); + } + + generateModifiers(buffer, field); + + generateType(buffer, field.getType(), field); + buffer.append(" "); + buffer.append(field.getName()); + + generateInitializer(buffer, field); + + return buffer.toString(); + } + + private static String generateVariableInfo(PsiVariable variable) { + StringBuffer buffer = new StringBuffer(); + + generateModifiers(buffer, variable); + + generateType(buffer, variable.getType(), variable); + + buffer.append(" "); + + buffer.append(variable.getName()); + generateInitializer(buffer, variable); + + return buffer.toString(); + } + + private static String generateFileInfo(PsiFile file) { + return file.getVirtualFile().getPresentableUrl(); + } + + public static String generateInfo(PsiElement element) { + if (element instanceof PsiClass) { + return generateClassInfo((PsiClass) element); + } else if (element instanceof PsiMethod) { + return generateMethodInfo((PsiMethod) element); + } else if (element instanceof PsiField) { + return generateFieldInfo((PsiField) element); + } else if (element instanceof PsiVariable) { + return generateVariableInfo((PsiVariable) element); + } else if (element instanceof PsiFile) { + return generateFileInfo((PsiFile) element); + } else if (element instanceof PsiPackage) { + return generatePackageInfo((PsiPackage) element); + } else if (element instanceof PsiAntElement) { + return generateAttributeValueInfo(((PsiAntElement) element)); + } else { + return null; + } + } + } + + private static class Info { + public final PsiElement myTargetElement; + public final PsiElement myElementAtPointer; + public final int myStartOffset; + public final int myEndOffset; + + public Info(PsiElement targetElement, PsiElement elementAtPointer) { + myTargetElement = targetElement; + myElementAtPointer = elementAtPointer; + myStartOffset = elementAtPointer.getTextOffset(); + myEndOffset = myStartOffset + elementAtPointer.getTextLength(); + } + + public Info(PsiElement targetElement, PsiElement elementAtPointer, int startOffset, int endOffset) { + myTargetElement = targetElement; + myElementAtPointer = elementAtPointer; + myStartOffset = startOffset; + myEndOffset = endOffset; + } + } + + private Info getInfoAt(final Editor editor, LogicalPosition pos, boolean browseType) { + Document document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if (file == null) return null; + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + final int offset = editor.logicalPositionToOffset(pos); + + int selStart = editor.getSelectionModel().getSelectionStart(); + int selEnd = editor.getSelectionModel().getSelectionEnd(); + + if (offset >= selStart && offset < selEnd) return null; + + + PsiElement targetElement; + if (browseType) { + targetElement = GotoTypeDeclarationAction.findSymbolType(myProject, editor, offset); + } else { + PsiReference ref = TargetElementUtil.findReference(editor, offset); + if (ref != null) { + PsiElement resolvedElement = ref.resolve(); + + if (resolvedElement != null) { + PsiElement e = ref.getElement(); + return new Info(resolvedElement, + e, + e.getTextRange().getStartOffset() + ref.getRangeInElement().getStartOffset(), + e.getTextRange().getStartOffset() + ref.getRangeInElement().getEndOffset()); + } + } + targetElement = GotoDeclarationAction.findTargetElement(myProject, editor, offset); + } + if (targetElement != null && targetElement.isPhysical()) { + PsiElement elementAtPointer = file.findElementAt(offset); + if (elementAtPointer instanceof PsiIdentifier + || elementAtPointer instanceof PsiKeyword + || elementAtPointer instanceof JspToken + || elementAtPointer instanceof PsiDocToken + || elementAtPointer instanceof XmlToken) { + return new Info(targetElement, elementAtPointer); + } + } + + return null; + } + + private void disposeHighlighter() { + if (myHighlighter != null) { + myHighlighterView.getMarkupModel().removeHighlighter(myHighlighter); + Component internalComponent = myHighlighterView.getContentComponent(); + internalComponent.setCursor(myStoredCursor); + internalComponent.removeKeyListener(myEditorKeyListener); + myHighlighterView.getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener); + FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myFileEditorManagerListener); + HintManager hintManager = HintManager.getInstance(); + hintManager.hideAllHints(); + myHighlighter = null; + myHighlighterView = null; + myStoredCursor = null; + } + myStoredInfo = null; + } + + private class TooltipProvider { + private final Editor myEditor; + private final LogicalPosition myPosition; + private boolean myBrowseType; + + public TooltipProvider(Editor editor, LogicalPosition pos) { + myEditor = editor; + myPosition = pos; + } + + public boolean isTypeBrowsed() { + return myBrowseType; + } + + public void execute(boolean browseType) { + myBrowseType = browseType; + Info info = getInfoAt(myEditor, myPosition, myBrowseType); + if (info == null) return; + + Component internalComponent = myEditor.getContentComponent(); + if (myHighlighter != null) { + if (!Comparing.equal(info.myElementAtPointer, myStoredInfo.myElementAtPointer) || + info.myStartOffset != myStoredInfo.myStartOffset || + info.myEndOffset != myStoredInfo.myEndOffset) { + disposeHighlighter(); + } else { + // highlighter already set + internalComponent.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + return; + } + } + + if (info.myTargetElement != null && info.myElementAtPointer != null) { + //if (info.myTargetElement.isPhysical()) { + installLinkHighlighter(info); + //} + + internalComponent.addKeyListener(myEditorKeyListener); + myEditor.getScrollingModel().addVisibleAreaListener(myVisibleAreaListener); + myStoredCursor = internalComponent.getCursor(); + myStoredInfo = info; + internalComponent.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + FileEditorManager.getInstance(myProject).addFileEditorManagerListener(myFileEditorManagerListener); + + String text = JavaInfoGenerator.generateInfo(info.myTargetElement); //JavaDocManager.getInstance(myProject).getDocInfo(info.myTargetElement); + + if (text == null) return; + + JLabel label = HintUtil.createInformationLabel(text); + label.setUI(new MultiLineLabelUI()); + Font FONT = UIManager.getFont("Label.font"); + label.setFont(FONT); + final LightweightHint hint = new LightweightHint(label); + final HintManager hintManager = HintManager.getInstance(); + label.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent e) { + hintManager.hideAllHints(); + } + }); + Point p = hintManager.getHintPosition(hint, myEditor, myPosition, HintManager.ABOVE); + hintManager.showEditorHint(hint, myEditor, p, + HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | + HintManager.HIDE_BY_SCROLLING, + 0, false); + } + } + + private void installLinkHighlighter(Info info) { + int startOffset = info.myStartOffset; + int endOffset = info.myEndOffset; + myHighlighter = + myEditor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, HighlighterLayer.SELECTION + 1, + ourReferenceAttributes, HighlighterTargetArea.EXACT_RANGE); + myHighlighterView = myEditor; + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/GotoImplementationHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/GotoImplementationHandler.java new file mode 100644 index 00000000000..7ed03a2a17b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/GotoImplementationHandler.java @@ -0,0 +1,239 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.highlighting.HighlightDefUseHandler; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.ide.util.MemberContainerCellRenderer; +import com.intellij.ide.util.PsiClassListCellRenderer; +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiUtil; +import com.intellij.ui.ListPopup; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; + +public class GotoImplementationHandler implements CodeInsightActionHandler { + protected interface ResultsFilter { + boolean acceptClass(PsiClass aClass); + + boolean acceptMethod(PsiMethod method); + } + + public void invoke(Project project, Editor editor, PsiFile file) { + int flags = TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + | TargetElementUtil.ELEMENT_NAME_ACCEPTED + | TargetElementUtil.LOOKUP_ITEM_ACCEPTED + | TargetElementUtil.THIS_ACCEPTED + | TargetElementUtil.SUPER_ACCEPTED; + final PsiElement element = TargetElementUtil.findTargetElement(editor, flags); + if (new HighlightDefUseHandler ().invoke(false, project, editor, file)) + return; + if (!(element instanceof PsiMethod) && !(element instanceof PsiClass)) + return; + + PsiElement[] result = searchImplementations(editor, file, element, false); + if (result != null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.implementation"); + show(project, editor, element, result); + } + } + + public PsiElement[] searchImplementations(Editor editor, PsiFile file, final PsiElement element, boolean includeSelf) { + final PsiElement[][] result = new PsiElement[1][]; + if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously( + new Runnable() { + public void run() { + result[0] = getSearchResults(element); + } + }, + "Searching For Implementations...", + true, + element.getProject())) return null; + + if (result[0] != null && result[0].length > 0) { + if (!includeSelf) return filterElements(editor, file, element, result[0]); + PsiElement[] all = new PsiElement[result[0].length + 1]; + all[0] = element; + System.arraycopy(result[0], 0, all, 1, result[0].length); + return filterElements(editor, file, element, all); + } + return includeSelf ? new PsiElement[] {element} : new PsiElement[0]; + } + + public boolean startInWriteAction() { + return false; + } + + protected ResultsFilter createFilter(Project project, final Editor editor, final PsiFile file, PsiElement element) { + final PsiElement element1 = TargetElementUtil.findTargetElement(editor, TargetElementUtil.ELEMENT_NAME_ACCEPTED); + + return new ResultsFilter() { + public boolean acceptClass(PsiClass aClass) { + return aClass != element1; + } + + public boolean acceptMethod(PsiMethod method) { + return method != element1; + } + }; + } + + private static void getOverridingMethods(PsiMethod method, ArrayList list) { + if (!method.hasModifierProperty(PsiModifier.FINAL)) { + PsiManager manager = method.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + GlobalSearchScope scope = GlobalSearchScope.allScope(manager.getProject()); + PsiMethod[] methods = helper.findOverridingMethods(method, scope, true); + + AddMethodLoop: + for (int i = 0; i < methods.length; i++) { + PsiMethod m = methods[i]; + PsiClass aClass = m.getContainingClass(); + if (aClass != null) { + for (int j = 0; j < methods.length; j++) { + if (j == i) continue; + PsiMethod method1 = methods[j]; + PsiClass aClass1 = method1.getContainingClass(); + if (aClass1 != null) { + if (aClass.isInheritor(aClass1, true)) continue AddMethodLoop; + } + } + } + if (!list.contains(m)) { + list.add(m); + getOverridingMethods(m, list); + } + } + } + + } + + protected PsiElement[] filterElements(Editor editor, PsiFile file, PsiElement element, PsiElement[] targetElements) { + if (targetElements.length <= 1) return targetElements; + Project project = file.getProject(); + ResultsFilter filter = createFilter(project, editor, file, element); + + ArrayList result = new ArrayList(); + for (int i = 0; i < targetElements.length; i++) { + PsiElement targetElement = targetElements[i]; + if (targetElement instanceof PsiClass && filter.acceptClass(((PsiClass) targetElement))) { + result.add(targetElement); + } + else if (targetElement instanceof PsiMethod && filter.acceptMethod(((PsiMethod) targetElement))) { + result.add(targetElement); + } + } + + if (result.size() == targetElements.length) { + return targetElements; + } + else { + return result.toArray(new PsiElement[result.size()]); + } + } + + private PsiElement[] getSearchResults(PsiElement sourceElement) { + if (sourceElement instanceof PsiMethod) { + return getMethodImplementations((PsiMethod) sourceElement); + } + else if (sourceElement instanceof PsiClass) { + return getClassImplementations((PsiClass) sourceElement); + } + else { + return new PsiElement[]{sourceElement}; + } + } + + private PsiElement[] getClassImplementations(final PsiClass psiClass) { + final ArrayList list = new ArrayList(); + + PsiSearchHelper helper = psiClass.getManager().getSearchHelper(); + GlobalSearchScope searchScope = GlobalSearchScope.allScope(psiClass.getProject()); + helper.processInheritors(new PsiBaseElementProcessor() { + public boolean execute(PsiClass element) { + PsiClass inheritor = element; + if (!inheritor.isInterface()) list.add(inheritor); + return true; + } + }, psiClass, searchScope, true); + + if (!psiClass.isInterface()) { + list.add(psiClass); + } + + return list.toArray(new PsiElement[list.size()]); + } + + private PsiElement[] getMethodImplementations(final PsiMethod method) { + ArrayList result = new ArrayList(); + + getOverridingMethods(method, result); + if (!method.hasModifierProperty(PsiModifier.ABSTRACT)) { + result.add(0, method); + } + + return result.toArray(new PsiElement[result.size()]); + } + + private void show(final Project project, Editor editor, final PsiElement sourceElement, final PsiElement[] elements) { + if (elements == null || elements.length == 0) { + return; + } + + if (elements.length == 1) { + Navigatable descriptor = EditSourceUtil.getDescriptor(elements[0]); + if (descriptor != null) { + descriptor.navigate(true); + } + } + else { + PsiElementListCellRenderer renderer = sourceElement instanceof PsiMethod + ? new MemberContainerCellRenderer(!PsiUtil.allMethodsHaveSameSignature(Arrays.asList(elements).toArray(PsiMethod.EMPTY_ARRAY))) + : new PsiClassListCellRenderer(); + + Arrays.sort(elements, renderer.getComparator()); + + final JList list = new JList(elements); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setCellRenderer(renderer); + + renderer.installSpeedSearch(list); + + final Runnable runnable = new Runnable() { + public void run() { + int index = list.getSelectedIndex(); + if (index < 0) return; + PsiElement element = (PsiElement) list.getSelectedValue(); + Navigatable descriptor = EditSourceUtil.getDescriptor(element); + if (descriptor != null) { + descriptor.navigate(true); + } + } + }; + + String title = " Choose Implementation of " + ((PsiNamedElement) sourceElement).getName(); + ListPopup listPopup = new ListPopup(title, list, runnable, project); + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + Point caretLocation = editor.logicalPositionToXY(caretPosition); + int x = caretLocation.x; + int y = caretLocation.y; + Point editorLocation = editor.getContentComponent().getLocationOnScreen(); + x += editorLocation.x; + y += editorLocation.y; + listPopup.show(x, y); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java new file mode 100644 index 00000000000..be4f5a1dd3b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java @@ -0,0 +1,461 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.TypedAction; +import com.intellij.openapi.editor.actionSystem.TypedActionHandler; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.ui.LightweightHint; +import com.intellij.util.text.StringSearcher; + +import javax.swing.*; +import java.awt.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class IncrementalSearchHandler { + private static final Key SEARCH_DATA_IN_EDITOR_VIEW_KEY = Key.create("IncrementalSearchHandler.SEARCH_DATA_IN_EDITOR_VIEW_KEY"); + private static final Key SEARCH_DATA_IN_HINT_KEY = Key.create("IncrementalSearchHandler.SEARCH_DATA_IN_HINT_KEY"); + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.IncrementalSearchHandler"); + + private static boolean ourActionsRegistered = false; + + private static class PerHintSearchData { + final Project project; + final JLabel label; + + int searchStart; + RangeHighlighter segmentHighlighter; + boolean ignoreCaretMove = false; + + public PerHintSearchData(Project project, JLabel label) { + this.project = project; + this.label = label; + } + } + + private static class PerEditorSearchData { + LightweightHint hint; + String lastSearch; + } + + public void invoke(Project project, final Editor editor) { + if (!ourActionsRegistered){ + ourActionsRegistered = true; + + EditorActionManager actionManager = EditorActionManager.getInstance(); + + TypedAction typedAction = actionManager.getTypedAction(); + typedAction.setupHandler(new IncrementalSearchHandler.MyTypedHandler(typedAction.getHandler())); + + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE, new IncrementalSearchHandler.BackSpaceHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE))); + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP, new IncrementalSearchHandler.UpHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP))); + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN, new IncrementalSearchHandler.DownHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN))); + } + + FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.incremental.search"); + + String selection = editor.getSelectionModel().getSelectedText(); + JLabel label2 = new MyLabel(selection == null ? "" : selection); + + PerEditorSearchData data = (PerEditorSearchData)editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + if (data == null) { + data = new PerEditorSearchData(); + } else { + if (data.hint != null) { + if (data.lastSearch != null) { + PerHintSearchData hintData = (PerHintSearchData) data.hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + //The user has not started typing + if ("".equals(hintData.label.getText())) { + label2 = new MyLabel(data.lastSearch); + } + } + data.hint.hide(); + } + } + + JLabel label1 = new MyLabel(" Search for: "); + label1.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + + JPanel panel = new MyPanel(label1); + panel.add(label1, BorderLayout.WEST); + panel.add(label2, BorderLayout.CENTER); + panel.setBorder(BorderFactory.createLineBorder(Color.black)); + + final DocumentListener[] documentListener = new DocumentListener[1]; + final CaretListener[] caretListener = new CaretListener[1]; + final LightweightHint hint = new LightweightHint(panel) { + public void hide() { + PerHintSearchData data = (PerHintSearchData)getUserData(SEARCH_DATA_IN_HINT_KEY); + LOG.assertTrue(data != null); + String prefix = data.label.getText(); + + super.hide(); + + if (data.segmentHighlighter != null){ + editor.getMarkupModel().removeHighlighter(data.segmentHighlighter); + } + PerEditorSearchData editorData = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + editorData.hint = null; + editorData.lastSearch = prefix; + + if (documentListener[0] != null){ + editor.getDocument().removeDocumentListener(documentListener[0]); + } + + if (caretListener[0] != null){ + CaretListener listener = caretListener[0]; + editor.getCaretModel().removeCaretListener(listener); + } + } + }; + + documentListener[0] = new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + if (!hint.isVisible()) return; + hint.hide(); + } + }; + editor.getDocument().addDocumentListener(documentListener[0]); + + caretListener[0] = new CaretListener() { + public void caretPositionChanged(CaretEvent e) { + PerHintSearchData data = (PerHintSearchData)hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + if (data != null && data.ignoreCaretMove) return; + if (!hint.isVisible()) return; + hint.hide(); + } + }; + CaretListener listener = caretListener[0]; + editor.getCaretModel().addCaretListener(listener); + + final JComponent component = editor.getComponent(); + int x = SwingUtilities.convertPoint(component,0,0,component).x; + int y = - hint.getComponent().getPreferredSize().height; + Point p = SwingUtilities.convertPoint(component,x,y,component.getRootPane().getLayeredPane()); + + HintManager hintManager = HintManager.getInstance(); + hintManager.showEditorHint(hint, editor, p, HintManager.HIDE_BY_ESCAPE | HintManager.HIDE_BY_TEXT_CHANGE, 0, false); + + PerHintSearchData hintData = new PerHintSearchData(project, label2); + hintData.searchStart = editor.getCaretModel().getOffset(); + hint.putUserData(SEARCH_DATA_IN_HINT_KEY, hintData); + + data.hint = hint; + editor.putUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY, data); + + if (hintData.label.getText().length() > 0) { + updatePosition(editor, hintData, true, false); + } + } + + private static boolean acceptableRegExp(String pattern) { + final int len = pattern.length(); + + for(int i=0;i 0){ + TextAttributes attributes = editor.getColorsScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + data.segmentHighlighter = editor.getMarkupModel().addRangeHighlighter(index, index + matchLength, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE); + } + data.ignoreCaretMove = true; + editor.getCaretModel().moveToOffset(index); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + data.ignoreCaretMove = false; + IdeDocumentHistory.getInstance(data.project).includeCurrentCommandAsNavigation(); + } + } + + private static boolean detectSmartCaseSensitive(String prefix) { + boolean hasUpperCase = false; + for(int i = 0; i < prefix.length(); i++){ + char c = prefix.charAt(i); + if (Character.isUpperCase(c) && Character.toUpperCase(c) != Character.toLowerCase(c)){ + hasUpperCase = true; + break; + } + } + return hasUpperCase; + } + + private static class MyLabel extends JLabel { + public MyLabel(String text) { + super(text); + this.setBackground(HintUtil.INFORMATION_COLOR); + this.setForeground(Color.black); + this.setOpaque(true); + } + } + + private static class MyPanel extends JPanel{ + private Component myLeft; + + public MyPanel(Component left) { + super(new BorderLayout()); + myLeft = left; + } + + public Dimension getPreferredSize() { + Dimension size = super.getPreferredSize(); + Dimension lSize = myLeft.getPreferredSize(); + return new Dimension(size.width + lSize.width, size.height); + } + + public Dimension getTruePreferredSize() { + return super.getPreferredSize(); + } + } + + public static class MyTypedHandler implements TypedActionHandler { + private TypedActionHandler myOriginalHandler; + + public MyTypedHandler(TypedActionHandler originalAction) { + myOriginalHandler = originalAction; + } + + public void execute(Editor editor, char charTyped, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData)editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + if (data == null || data.hint == null){ + myOriginalHandler.execute(editor, charTyped, dataContext); + } + else{ + LightweightHint hint = data.hint; + PerHintSearchData hintData = (PerHintSearchData) hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + String text = hintData.label.getText(); + text += charTyped; + hintData.label.setText(text); + MyPanel comp = (MyPanel)hint.getComponent(); + if (comp.getTruePreferredSize().width > comp.getSize().width){ + Dimension preferredSize = hint.getComponent().getPreferredSize(); + Rectangle bounds = hint.getBounds(); + hint.setBounds(bounds.x, bounds.y, preferredSize.width, preferredSize.height); + } + updatePosition(editor, hintData, false, false); + } + } + } + + public static class BackSpaceHandler extends EditorActionHandler{ + private EditorActionHandler myOriginalHandler; + + public BackSpaceHandler(EditorActionHandler originalAction) { + myOriginalHandler = originalAction; + } + + public void execute(Editor editor, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + if (data == null || data.hint == null){ + myOriginalHandler.execute(editor, dataContext); + } + else{ + LightweightHint hint = data.hint; + PerHintSearchData hintData = (PerHintSearchData) hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + String text = hintData.label.getText(); + if (text.length() > 0){ + text = text.substring(0, text.length() - 1); + } + hintData.label.setText(text); + updatePosition(editor, hintData, false, false); + } + } + } + + public static class UpHandler extends EditorActionHandler { + private EditorActionHandler myOriginalHandler; + + public UpHandler(EditorActionHandler originalHandler) { + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + if (data == null || data.hint == null){ + myOriginalHandler.execute(editor, dataContext); + } + else{ + LightweightHint hint = data.hint; + PerHintSearchData hintData = (PerHintSearchData) hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + String prefix = hintData.label.getText(); + if (prefix == null) return; + hintData.searchStart = editor.getCaretModel().getOffset(); + if (hintData.searchStart == 0) return; + hintData.searchStart--; + updatePosition(editor, hintData, true, true); + hintData.searchStart = editor.getCaretModel().getOffset(); + } + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + return (data != null && data.hint != null) || myOriginalHandler.isEnabled(editor, dataContext); + } + } + + public static class DownHandler extends EditorActionHandler { + private EditorActionHandler myOriginalHandler; + + public DownHandler(EditorActionHandler originalHandler) { + myOriginalHandler = originalHandler; + } + + public void execute(Editor editor, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + if (data == null || data.hint == null){ + myOriginalHandler.execute(editor, dataContext); + } + else{ + LightweightHint hint = data.hint; + PerHintSearchData hintData = (PerHintSearchData) hint.getUserData(SEARCH_DATA_IN_HINT_KEY); + String prefix = hintData.label.getText(); + if (prefix == null) return; + hintData.searchStart = editor.getCaretModel().getOffset(); + if (hintData.searchStart == editor.getDocument().getTextLength()) return; + hintData.searchStart++; + updatePosition(editor, hintData, true, false); + hintData.searchStart = editor.getCaretModel().getOffset(); + } + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + PerEditorSearchData data = (PerEditorSearchData) editor.getUserData(SEARCH_DATA_IN_EDITOR_VIEW_KEY); + return (data != null && data.hint != null) || myOriginalHandler.isEnabled(editor, dataContext); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodDownHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodDownHandler.java new file mode 100644 index 00000000000..d56b2d64869 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodDownHandler.java @@ -0,0 +1,47 @@ + +package com.intellij.codeInsight.navigation; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; + +public class MethodDownHandler implements CodeInsightActionHandler { + public void invoke(Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + int caretOffset = editor.getCaretModel().getOffset(); + int caretLine = editor.getCaretModel().getLogicalPosition().line; + PsiElement element = file; + if (file instanceof XmlFile) { + PsiElement elementAt = file.findElementAt(caretOffset); + elementAt = PsiTreeUtil.getParentOfType(elementAt, XmlTag.class); + if (elementAt != null) element = elementAt; + } + int[] offsets = MethodUpDownUtil.getNavigationOffsets(element); + for(int i = 0; i < offsets.length; i++){ + int offset = offsets[i]; + if (offset > caretOffset){ + int line = editor.offsetToLogicalPosition(offset).line; + if (line > caretLine){ + editor.getCaretModel().moveToOffset(offset); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_DOWN); + IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation(); + break; + } + } + } + } + + public boolean startInWriteAction() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpDownUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpDownUtil.java new file mode 100644 index 00000000000..1e94e71ffab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpDownUtil.java @@ -0,0 +1,50 @@ + +package com.intellij.codeInsight.navigation; + +import com.intellij.psi.*; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; + +import java.util.ArrayList; +import java.util.Arrays; + +public class MethodUpDownUtil { + public static int[] getNavigationOffsets(PsiElement element) { + ArrayList array = new ArrayList(); + addNavigationElements(array, element); + int[] offsets = new int[array.size()]; + for(int i = 0; i < array.size(); i++){ + PsiElement e = (PsiElement)array.get(i); + offsets[i] = e.getTextOffset(); + } + Arrays.sort(offsets); + return offsets; + } + + private static void addNavigationElements(ArrayList array, PsiElement element) { + if (element instanceof PsiJavaFile || element instanceof PsiClass){ + PsiElement[] children = element.getChildren(); + for(int i = 0; i < children.length; i++){ + PsiElement child = children[i]; + if (child instanceof PsiMethod || child instanceof PsiClass){ + array.add(child); + addNavigationElements(array, child); + } + if (element instanceof PsiClass && child instanceof PsiJavaToken && child.getText().equals("}")){ + array.add(child); + } + } + } else if (element instanceof XmlFile || element instanceof XmlTag) { + PsiElement parent = element instanceof XmlFile ? element : element.getParent(); + + PsiElement[] children = parent.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + if (child instanceof XmlTag) { + array.add(child); + } + } + addNavigationElements(array, element.getParent()); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpHandler.java new file mode 100644 index 00000000000..5c6f014dd36 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/MethodUpHandler.java @@ -0,0 +1,47 @@ + +package com.intellij.codeInsight.navigation; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; + +public class MethodUpHandler implements CodeInsightActionHandler { + public void invoke(Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + int caretOffset = editor.getCaretModel().getOffset(); + int caretLine = editor.getCaretModel().getLogicalPosition().line; + PsiElement element = file; + if (file instanceof XmlFile) { + PsiElement elementAt = file.findElementAt(caretOffset); + elementAt = PsiTreeUtil.getParentOfType(elementAt, XmlTag.class); + if (elementAt != null) element = elementAt; + } + int[] offsets = MethodUpDownUtil.getNavigationOffsets(element); + for(int i = offsets.length - 1; i >= 0; i--){ + int offset = offsets[i]; + if (offset < caretOffset){ + int line = editor.offsetToLogicalPosition(offset).line; + if (line < caretLine){ + editor.getCaretModel().moveToOffset(offset); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_UP); + IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation(); + break; + } + } + } + } + + public boolean startInWriteAction() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/NavigationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/NavigationUtil.java new file mode 100644 index 00000000000..4ee0819d8e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/NavigationUtil.java @@ -0,0 +1,47 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.ide.util.gotoByName.GotoSymbolCellRenderer; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.ui.ListPopup; + +import javax.swing.*; + +/** + * @author ven + */ +public final class NavigationUtil { + public static ListPopup getPsiElementPopup(PsiElement[] elements, String title, final Project project) { + PsiElementListCellRenderer renderer = new GotoSymbolCellRenderer(); + return getPsiElementPopup(elements, renderer, title, project); + + } + + public static ListPopup getPsiElementPopup(final PsiElement[] elements, + final PsiElementListCellRenderer renderer, + final String title, + final Project project) { + final JList list = new JList(elements); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setCellRenderer(renderer); + renderer.installSpeedSearch(list); + + final Runnable runnable = new Runnable() { + public void run() { + int index = list.getSelectedIndex(); + if (index < 0) return; + PsiElement element = (PsiElement) list.getSelectedValue(); + Navigatable descriptor = EditSourceUtil.getDescriptor(element); + if (descriptor != null) { + descriptor.navigate(true); + } + } + }; + + ListPopup listPopup = new ListPopup(title, list, runnable, project); + return listPopup; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java new file mode 100644 index 00000000000..2e9027cc456 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java @@ -0,0 +1,251 @@ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.navigation.NavigationUtil; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspAction; +import com.intellij.psi.jsp.JspAttribute; +import com.intellij.psi.jsp.JspImplicitVariable; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.ui.ListPopup; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class GotoDeclarationAction extends BaseCodeInsightAction implements CodeInsightActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.actions.GotoDeclarationAction"); + + protected CodeInsightActionHandler getHandler() { + return this; + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + boolean b = file.canContainJavaCode() || file instanceof XmlFile; + if (!b) { + FileTypeSupportCapabilities supportCapabilities = file.getFileType().getSupportCapabilities(); + b = (supportCapabilities!=null)?supportCapabilities.hasNavigation():false; + } + return b; + } + + protected boolean isValidForLookup() { + return true; + } + + public void invoke(final Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + int offset = getOffset(editor); + PsiElement element = findTargetElement(project, editor, offset); + if (element == null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration"); + chooseAmbigousTarget(project, editor, offset); + return; + } + + if (element instanceof JspImplicitVariable) { + final JspImplicitVariable variable = (JspImplicitVariable) element; + element = variable.getDeclaration(); + } + if (element == null) return; + + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration"); + PsiElement navElement = element.getNavigationElement(); + + //TODO: move this logic to ClsMethodImpl.getNavigationElement + if (navElement == element && element instanceof PsiCompiledElement && element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + if (method.isConstructor() && method.getParameterList().getParameters().length == 0) { + PsiClass aClass = method.getContainingClass(); + PsiElement navClass = aClass.getNavigationElement(); + if (aClass != navClass) navElement = navClass; + } + } + + PsiFile targetFile = navElement.getContainingFile(); + // Fix for floating declarations such as array class, jsp taglib etc. + if (targetFile == null || targetFile.getVirtualFile() == null) return; + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, targetFile.getVirtualFile(), navElement.getTextOffset()); + FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + } + + + private void chooseAmbigousTarget(final Project project, final Editor editor, int offset) { + final PsiElement[] candidates = suggestCandidates(project, editor, offset); + if (candidates.length == 0) { + return; + } else if (candidates.length == 1) { + Navigatable navigatable = EditSourceUtil.getDescriptor(candidates[0]); + if (navigatable != null) { + navigatable.navigate(true); + } + } else { + String title = " Go To Overloaded Declaration Of " + ((PsiNamedElement) candidates[0]).getName(); + ListPopup listPopup = NavigationUtil.getPsiElementPopup(candidates, title, project); + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + Point caretLocation = editor.logicalPositionToXY(caretPosition); + int x = caretLocation.x; + int y = caretLocation.y; + Point location = editor.getContentComponent().getLocationOnScreen(); + x += location.x; + y += location.y; + listPopup.show(x, y); + } + } + + private PsiElement[] suggestCandidates(Project project, Editor editor, int offset) { + PsiReference reference = TargetElementUtil.findReference(editor, offset); + if (reference != null) { + PsiElement parent = reference.getElement().getParent(); + if (parent instanceof PsiMethodCallExpression) { + PsiMethodCallExpression callExpr = (PsiMethodCallExpression) parent; + boolean allowStatics = false; + PsiExpression qualifier = callExpr.getMethodExpression().getQualifierExpression(); + if (qualifier == null) { + allowStatics = true; + } else if (qualifier instanceof PsiJavaCodeReferenceElement) { + PsiElement referee = ((PsiJavaCodeReferenceElement) qualifier).advancedResolve(true).getElement(); + if (referee instanceof PsiClass) allowStatics = true; + } + PsiManager manager = PsiManager.getInstance(project); + PsiResolveHelper helper = manager.getResolveHelper(); + PsiElement[] candidates = PsiUtil.mapElements(helper.getReferencedMethodCandidates(callExpr, false)); + ArrayList methods = new ArrayList(); + for (int i = 0; i < candidates.length; i++) { + PsiMethod candidate = (PsiMethod) candidates[i]; + if (candidate.hasModifierProperty(PsiModifier.STATIC) && !allowStatics) continue; + List supers = Arrays.asList(PsiSuperMethodUtil.findSuperMethods(candidate)); + if (supers.isEmpty()) { + methods.add(candidate); + } else { + methods.addAll(supers); + } + } + return methods.toArray(new PsiElement[methods.size()]); + } + } + return PsiElement.EMPTY_ARRAY; + } + + public boolean startInWriteAction() { + return false; + } + + protected int getOffset(Editor editor) { + return editor.getCaretModel().getOffset(); + } + + private PsiElement findDeclarationAction(PsiElement place, JspImplicitVariable variable) { + if (place == null) return null; + + if (place instanceof JspAction) { + JspAction action = (JspAction) place; + + final JspAttribute[] attributes = action.getAttributes(); + + for (int i = 0; i < attributes.length; i++) { + JspAttribute attribute = attributes[i]; + final PsiElement valueElement = attribute.getValueElement(); + if (valueElement == null) continue; + final PsiReference reference = valueElement.getReference(); + if (reference != null && reference.resolve() == variable) return attribute.getValueElement(); + } + + JspImplicitVariable[] variables = action.getDeclaredVariables(); + + if (variables != null) { + for (int i = 0; i < variables.length; i++) { + JspImplicitVariable v = variables[i]; + + if (v == variable) { + return action; + } + } + } + } + + PsiElement[] children = place.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + PsiElement action = findDeclarationAction(child, variable); + if (action != null) return action; + } + + return null; + } + + public static PsiElement findTargetElement(Project project, Editor editor, int offset) { + int flags = TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + | TargetElementUtil.NEW_AS_CONSTRUCTOR + | TargetElementUtil.LOOKUP_ITEM_ACCEPTED + | TargetElementUtil.THIS_ACCEPTED + | TargetElementUtil.SUPER_ACCEPTED; + PsiElement element = TargetElementUtil.findTargetElement(editor, flags, offset); + if (element instanceof PsiPackage) return null; + + if (element != null) return element; + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file != null) { + PsiElement elementAt = file.findElementAt(offset); + if (elementAt instanceof PsiKeyword) { + IElementType type = ((PsiKeyword) elementAt).getTokenType(); + if (type == JavaTokenType.CONTINUE_KEYWORD) { + if (elementAt.getParent() instanceof PsiContinueStatement) { + PsiStatement statement = ((PsiContinueStatement) elementAt.getParent()).findContinuedStatement(); + return statement; + } + } else if (type == JavaTokenType.BREAK_KEYWORD) { + if (elementAt.getParent() instanceof PsiBreakStatement) { + PsiStatement statement = ((PsiBreakStatement) elementAt.getParent()).findExitedStatement(); + if (statement == null) return null; + if (statement.getParent() instanceof PsiLabeledStatement) { + statement = (PsiStatement) statement.getParent(); + } + return statement.getNextSibling(); //? + } + } + } else if (elementAt instanceof PsiIdentifier) { + PsiElement parent = elementAt.getParent(); + PsiStatement statement = null; + if (parent instanceof PsiContinueStatement) { + statement = ((PsiContinueStatement) parent).findContinuedStatement(); + } else if (parent instanceof PsiBreakStatement) { + statement = ((PsiBreakStatement) parent).findExitedStatement(); + } + if (statement == null) return null; + + LOG.assertTrue(statement.getParent() instanceof PsiLabeledStatement); + return ((PsiLabeledStatement) statement.getParent()).getLabelIdentifier(); + } + } + + return null; + } + + /* + public void update(AnActionEvent event, Presentation presentation) { + super.update(event, presentation); + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + presentation.setText("Go to " + getTemplatePresentation().getText()); + } + } + */ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoImplementationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoImplementationAction.java new file mode 100644 index 00000000000..e1272bbe669 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoImplementationAction.java @@ -0,0 +1,18 @@ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.navigation.GotoImplementationHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +public class GotoImplementationAction extends BaseCodeInsightAction { + protected CodeInsightActionHandler getHandler(){ + return new GotoImplementationHandler(); + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file.canContainJavaCode(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoSuperAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoSuperAction.java new file mode 100644 index 00000000000..4176c8a4afc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoSuperAction.java @@ -0,0 +1,92 @@ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.highlighting.HighlightDefUseHandler; +import com.intellij.codeInsight.navigation.NavigationUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.ListPopup; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +/** + * + */ +public class GotoSuperAction extends BaseCodeInsightAction implements CodeInsightActionHandler { + + protected CodeInsightActionHandler getHandler() { + return this; + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file.canContainJavaCode(); + } + + public void invoke(final Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + if (new HighlightDefUseHandler ().invoke(true, project, editor, file)) + return; + + int offset = editor.getCaretModel().getOffset(); + PsiElement[] superElements = findSuperElements(file, offset); + if (superElements == null || superElements.length == 0) return; + if (superElements.length == 1) { + PsiElement superElement = superElements[0].getNavigationElement(); + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, superElement.getContainingFile().getVirtualFile(), superElement.getTextOffset()); + FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + } else { + String title = " Choose super " + (superElements[0] instanceof PsiMethod ? "method " : "class or interface "); + ListPopup listPopup = NavigationUtil.getPsiElementPopup(superElements, title, project); + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + Point caretLocation = editor.logicalPositionToXY(caretPosition); + int x = caretLocation.x; + int y = caretLocation.y; + Point location = editor.getContentComponent().getLocationOnScreen(); + x += location.x; + y += location.y; + listPopup.show(x, y); + } + } + + public boolean startInWriteAction() { + return false; + } + + private static PsiElement[] findSuperElements(PsiFile file, int offset) { + PsiElement element = file.findElementAt(offset); + if (element == null) return null; + + PsiElement e = PsiTreeUtil.getParentOfType(element, new Class[]{PsiMethod.class, PsiClass.class}); + if (e instanceof PsiClass) { + PsiClass aClass = (PsiClass) e; + java.util.List allSupers = new ArrayList(Arrays.asList(aClass.getSupers())); + for (Iterator iterator = allSupers.iterator(); iterator.hasNext();) { + PsiClass superClass = iterator.next(); + if ("java.lang.Object".equals(superClass.getQualifiedName())) iterator.remove(); + } + return allSupers.toArray(new PsiClass[allSupers.size()]); + } else if (e instanceof PsiMethod) { + PsiMethod method = (PsiMethod) e; + if (method.isConstructor()) { + PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method); + if (constructorInSuper != null) { + return new PsiElement[]{constructorInSuper}; + } + } else { + return PsiSuperMethodUtil.findSuperMethods(method, false); + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java new file mode 100644 index 00000000000..8f95e0397bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/GotoTypeDeclarationAction.java @@ -0,0 +1,78 @@ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; + +/** + * + */ +public class GotoTypeDeclarationAction extends BaseCodeInsightAction implements CodeInsightActionHandler{ + + protected CodeInsightActionHandler getHandler(){ + return this; + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file.canContainJavaCode(); + } + + protected boolean isValidForLookup() { + return true; + } + + public void invoke(final Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + int offset = getOffset(editor); + PsiElement symbolType = findSymbolType(project, editor, offset); + if (symbolType == null) return; + symbolType = symbolType.getNavigationElement(); + OpenFileDescriptor descriptor=new OpenFileDescriptor(project, symbolType.getContainingFile().getVirtualFile(), symbolType.getTextOffset()); + FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + } + + public boolean startInWriteAction() { + return false; + } + + public static PsiElement findSymbolType(Project project, Editor editor, int offset) { + PsiElement targetElement = TargetElementUtil.findTargetElement(editor, + TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED | + TargetElementUtil.ELEMENT_NAME_ACCEPTED | + TargetElementUtil.LOOKUP_ITEM_ACCEPTED, + offset + ); + PsiType type = null; + if (targetElement instanceof PsiVariable){ + type = ((PsiVariable)targetElement).getType(); + } + else if (targetElement instanceof PsiMethod){ + type = ((PsiMethod)targetElement).getReturnType(); + } + else{ + return null; + } + if (type == null) return null; + return PsiUtil.resolveClassInType(type); + } + + protected int getOffset(Editor editor) { + return editor.getCaretModel().getOffset(); + } + + /* + public void update(AnActionEvent event, Presentation presentation) { + super.update(event, presentation); + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + presentation.setText("Go to " + getTemplatePresentation().getText()); + } + } + */ +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/IncrementalSearchAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/IncrementalSearchAction.java new file mode 100644 index 00000000000..9ee8a33b5a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/IncrementalSearchAction.java @@ -0,0 +1,39 @@ +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.navigation.IncrementalSearchHandler; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; + +public class IncrementalSearchAction extends AnAction{ + public IncrementalSearchAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) return; + + new IncrementalSearchHandler().invoke(project, editor); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null){ + presentation.setEnabled(false); + return; + } + + presentation.setEnabled(true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodDownAction.java new file mode 100644 index 00000000000..180d22cfa29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodDownAction.java @@ -0,0 +1,24 @@ + +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.navigation.MethodDownHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.xml.XmlFile; + +/** + * + */ +public class MethodDownAction extends BaseCodeInsightAction { + protected CodeInsightActionHandler getHandler() { + return new MethodDownHandler(); + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file instanceof PsiJavaFile || file instanceof XmlFile; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodUpAction.java new file mode 100644 index 00000000000..ba5007e24b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/navigation/actions/MethodUpAction.java @@ -0,0 +1,24 @@ + +package com.intellij.codeInsight.navigation.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.navigation.MethodUpHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.xml.XmlFile; + +/** + * + */ +public class MethodUpAction extends BaseCodeInsightAction { + protected CodeInsightActionHandler getHandler() { + return new MethodUpHandler(); + } + + protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + return file instanceof PsiJavaFile || file instanceof XmlFile; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Expression.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Expression.java new file mode 100644 index 00000000000..03b8f0c738c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Expression.java @@ -0,0 +1,12 @@ +package com.intellij.codeInsight.template; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.openapi.util.Key; + +public interface Expression { + Key AUTO_POPUP_NEXT_LOOKUP = Key.create("AUTO_POPUP_NEXT_LOOKUP"); + Result calculateResult(ExpressionContext context); + Result calculateQuickResult(ExpressionContext context); + LookupItem[] calculateLookupItems(ExpressionContext context); +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionContext.java new file mode 100644 index 00000000000..454d76acee7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionContext.java @@ -0,0 +1,18 @@ +package com.intellij.codeInsight.template; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; + +import java.util.Map; + +public interface ExpressionContext { + String SELECTION = "SELECTION"; + + Project getProject(); + Editor getEditor(); + int getStartOffset(); + int getTemplateStartOffset(); + int getTemplateEndOffset(); + Map getProperties(); +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionUtil.java new file mode 100644 index 00000000000..05124e653ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/ExpressionUtil.java @@ -0,0 +1,59 @@ + package com.intellij.codeInsight.template; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.text.BlockSupport; +import com.intellij.util.IncorrectOperationException; + +/** + * @author mike + */ +public class ExpressionUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.ExpressionUtil"); + + public static String[] getNames(final ExpressionContext context) { + Project project = context.getProject(); + int offset = context.getStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + String[] names = null; + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement element = file.findElementAt(offset); + if (element instanceof PsiIdentifier){ + names = getNamesForIdentifier(project, (PsiIdentifier)element); + } + else{ + PsiFile fileCopy = (PsiFile)file.copy(); + BlockSupport blockSupport = project.getComponent(BlockSupport.class); + try{ + blockSupport.reparseRange(fileCopy, offset, offset, "xxx"); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + PsiElement identifierCopy = fileCopy.findElementAt(offset); + if (identifierCopy instanceof PsiIdentifier) { + names = getNamesForIdentifier(project, (PsiIdentifier)identifierCopy); + } + } + return names; + } + + private static String[] getNamesForIdentifier(Project project, PsiIdentifier identifier){ + if (identifier.getParent() instanceof PsiVariable){ + PsiVariable var = (PsiVariable)identifier.getParent(); + if (var.getNameIdentifier().equals(identifier)){ + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + VariableKind variableKind = codeStyleManager.getVariableKind(var); + SuggestedNameInfo suggestedInfo = codeStyleManager.suggestVariableName(variableKind, null, var.getInitializer(), var.getType()); + return suggestedInfo.names; //TODO: callback about choosen name + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/InvokeActionResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/InvokeActionResult.java new file mode 100644 index 00000000000..361d5116978 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/InvokeActionResult.java @@ -0,0 +1,24 @@ + +package com.intellij.codeInsight.template; + +import com.intellij.psi.PsiElement; + +public class InvokeActionResult implements Result{ + private final Runnable myAction; + + public InvokeActionResult(Runnable action) { + myAction = action; + } + + public Runnable getAction() { + return myAction; + } + + public boolean equalsToText(String text, PsiElement context) { + return true; //no text result will be provided anyway + } + + public String toString() { + return ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Macro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Macro.java new file mode 100644 index 00000000000..fd4edcb5ee4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Macro.java @@ -0,0 +1,17 @@ +package com.intellij.codeInsight.template; + +import com.intellij.codeInsight.lookup.LookupItem; + +public interface Macro { + String getName(); + + String getDescription (); + + String getDefaultValue(); + + Result calculateResult(Expression[] params, ExpressionContext context); + + Result calculateQuickResult(Expression[] params, ExpressionContext context); + + LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiElementResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiElementResult.java new file mode 100644 index 00000000000..ce7fc80df6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiElementResult.java @@ -0,0 +1,45 @@ +package com.intellij.codeInsight.template; + +import com.intellij.psi.*; +import com.intellij.psi.SmartPsiElementPointer; +import com.intellij.psi.SmartPointerManager; + +public class PsiElementResult implements Result { + private SmartPsiElementPointer myPointer = null; + + public PsiElementResult(PsiElement element) { + if (element != null) { + myPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); + } + } + + public PsiElement getElement() { + return myPointer != null ? myPointer.getElement() : null; + } + + public boolean equalsToText(String text, PsiElement context) { + return text.equals(toString()); + } + + public String toString() { + String text = null; + PsiElement element = getElement(); + if (element != null) { + if (element instanceof PsiVariable) { + text = ((PsiVariable)element).getName(); + } + else if (element instanceof PsiMethod) { + text = ((PsiMethod)element).getName() + "()"; + } + else if (element instanceof PsiClass) { + PsiIdentifier identifier = ((PsiClass)element).getNameIdentifier(); + if (identifier == null) return ""; + text = identifier.getText(); + } + else { + text = element.getText(); + } + } + return text; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiTypeResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiTypeResult.java new file mode 100644 index 00000000000..c2b83b46835 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/PsiTypeResult.java @@ -0,0 +1,43 @@ +package com.intellij.codeInsight.template; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author max, dsl + */ +public class PsiTypeResult implements Result { + private final SmartTypePointer myTypePointer; + private PsiManager myPsiManager; + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.PsiTypeResult"); + + public PsiTypeResult(PsiType type, PsiManager manager) { + final PsiType actualType = PsiUtil.convertAnonymousToBaseType(type); + myTypePointer = SmartPointerManager.getInstance(manager.getProject()).createSmartTypePointer(actualType); + myPsiManager = manager; + } + + public PsiType getType() { + return myTypePointer.getType(); + } + + public boolean equalsToText(String text, PsiElement context) { + if (text.length() == 0) return false; + final PsiType type = getType(); + if (text.equals(type.getCanonicalText())) return true; + try { + PsiTypeCastExpression cast = (PsiTypeCastExpression)myPsiManager.getElementFactory().createExpressionFromText("(" + text + ")a", context); + return cast.getCastType().getType().equals(type); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return false; + } + } + + public String toString() { + return getType().getCanonicalText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Result.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Result.java new file mode 100644 index 00000000000..7a0ac63e784 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Result.java @@ -0,0 +1,10 @@ +package com.intellij.codeInsight.template; + +import com.intellij.psi.PsiElement; + +public interface Result { + boolean equalsToText (String text, PsiElement context); + + String toString(); +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Template.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Template.java new file mode 100644 index 00000000000..5b08d129bba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/Template.java @@ -0,0 +1,31 @@ +package com.intellij.codeInsight.template; + +public interface Template { + void addTextSegment(String text); + void addVariableSegment(String name); + + void addVariable(String name, Expression expression, Expression defaultValueExpression, boolean isAlwaysStopAt); + void addVariable(String name, String expression, String defaultValueExpression, boolean isAlwaysStopAt); + + void addEndVariable(); + void addSelectionStartVariable(); + void addSelectionEndVariable(); + + String getKey(); + + String getDescription(); + + void setToReformat(boolean toReformat); + + void setToIndent(boolean toIndent); + + void setInline(boolean isInline); + + int getSegmentsCount(); + + String getSegmentName( int segmentIndex); + + int getSegmentOffset(int segmentIndex); + + String getTemplateText(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateBuilder.java new file mode 100644 index 00000000000..d04edc6cfcd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateBuilder.java @@ -0,0 +1,128 @@ +package com.intellij.codeInsight.template; + +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author mike + */ +public class TemplateBuilder { + private PsiElement myContainerElement; + private Map myExpressions = new HashMap(); + private Map myVariableExpressions = new HashMap(); + private Map myAlwaysStopAtMap = new HashMap(); + private Map myVariableNamesMap = new HashMap(); + private Set myElements = new TreeSet(new Comparator() { + public int compare(final PsiElement e1, final PsiElement e2) { + return e1.getTextRange().getStartOffset() - e2.getTextRange().getStartOffset(); + } + }); + + private PsiElement myEndElement; + private PsiElement mySelection; + + public TemplateBuilder(PsiElement element) { + myContainerElement = element; + } + + public void replaceElement(PsiElement element, Expression expression, boolean alwaysStopAt) { + myAlwaysStopAtMap.put(element, alwaysStopAt ? Boolean.TRUE : Boolean.FALSE); + replaceElement(element, expression); + } + + public void replaceElement(PsiElement element, String varName, Expression expression, boolean alwaysStopAt) { + myAlwaysStopAtMap.put(element, alwaysStopAt ? Boolean.TRUE : Boolean.FALSE); + myVariableNamesMap.put(element, varName); + replaceElement(element, expression); + } + + public void replaceElement (PsiElement element, String varName, String dependantVariableName, boolean alwaysStopAt) { + myAlwaysStopAtMap.put(element, alwaysStopAt ? Boolean.TRUE : Boolean.FALSE); + myVariableNamesMap.put(element, varName); + myVariableExpressions.put(element, dependantVariableName); + myElements.add(element); + } + + public void replaceElement(PsiElement element, Expression expression) { + myExpressions.put(element, expression); + myElements.add(element); + } + + /** + * Adds end variable after the specified element + */ + public void setEndVariableAfter(PsiElement element) { + element = element.getNextSibling(); + myEndElement = element; + myElements.add(element); + } + + public void setSelection(PsiElement element) { + mySelection = element; + myElements.add(element); + } + + public Template buildInlineTemplate() { + Template template = buildTemplate(); + template.setInline(true); + return template; + } + + public Template buildTemplate() { + TemplateManager manager = TemplateManager.getInstance(myContainerElement.getProject()); + final Template template = manager.createTemplate("", ""); + + String text = myContainerElement.getText(); + final int containerStart = myContainerElement.getTextRange().getStartOffset(); + int start = 0; + for (Iterator iterator = myElements.iterator(); iterator.hasNext();) { + final PsiElement element = iterator.next(); + int offset = element.getTextRange().getStartOffset() - containerStart; + template.addTextSegment(text.substring(start, offset)); + + if (element == mySelection) { + template.addSelectionStartVariable(); + template.addTextSegment(mySelection.getText()); + template.addSelectionEndVariable(); + } else if (element == myEndElement) { + template.addEndVariable(); + start = offset; + continue; + } else { + final boolean alwaysStopAt = myAlwaysStopAtMap.get(element) == null ? true : myAlwaysStopAtMap.get(element).booleanValue(); + final Expression expression = myExpressions.get(element); + final String variableName = myVariableNamesMap.get(element) == null ? String.valueOf(expression.hashCode()) : myVariableNamesMap.get(element); + + if (expression != null) { + template.addVariable(variableName, expression, expression, alwaysStopAt); + } else { + template.addVariableSegment(variableName); + } + } + + start = element.getTextRange().getEndOffset() - containerStart; + } + + template.addTextSegment(text.substring(start)); + + for (Iterator iterator1 = myElements.iterator(); iterator1.hasNext();) { + PsiElement element = iterator1.next(); + final String dependantVariable = myVariableExpressions.get(element); + if (dependantVariable != null) { + final boolean alwaysStopAt = myAlwaysStopAtMap.get(element) == null ? true : myAlwaysStopAtMap.get(element).booleanValue(); + final Expression expression = myExpressions.get(element); + final String variableName = myVariableNamesMap.get(element) == null + ? String.valueOf(expression.hashCode()) + : myVariableNamesMap.get(element); + template.addVariable(variableName, dependantVariable, dependantVariable, alwaysStopAt); + } + } + + template.setToIndent(false); + template.setToReformat(false); + + return template; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateManager.java new file mode 100644 index 00000000000..537a2bc9a66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateManager.java @@ -0,0 +1,28 @@ + +package com.intellij.codeInsight.template; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +public abstract class TemplateManager { + public static TemplateManager getInstance(Project project) { + return project.getComponent(TemplateManager.class); + } + + public abstract void startTemplate(Editor editor, Template template); + + public abstract void startTemplate(Editor editor, String selectionString, Template template); + + public abstract void startTemplate(Editor editor, Template template, TemplateStateListener listener); + + public abstract boolean startTemplate(Editor editor, char shortcutChar); + + public abstract int getContextType(PsiFile file, int offset); + + public abstract Template createTemplate(String key, String group); + + public abstract Template createTemplate(String key, String group, String text); + + public abstract Template getActiveTemplate(Editor editor); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateStateListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateStateListener.java new file mode 100644 index 00000000000..70aa78c49df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TemplateStateListener.java @@ -0,0 +1,8 @@ +package com.intellij.codeInsight.template; + +/** + * @author Mike + */ +public interface TemplateStateListener { + public void templateFinished(Template template); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TextResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TextResult.java new file mode 100644 index 00000000000..6739d7e0403 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/TextResult.java @@ -0,0 +1,23 @@ +package com.intellij.codeInsight.template; + +import com.intellij.psi.PsiElement; + +public class TextResult implements Result{ + private final String myText; + + public TextResult(String text) { + myText = text; + } + + public String getText() { + return myText; + } + + public boolean equalsToText(String text, PsiElement context) { + return text.equals(myText); + } + + public String toString() { + return myText; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/actions/SaveAsTemplateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/actions/SaveAsTemplateAction.java new file mode 100644 index 00000000000..39c4b29cba0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/actions/SaveAsTemplateAction.java @@ -0,0 +1,159 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Aug 20, 2002 + * Time: 5:04:04 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInsight.template.actions; + +import com.intellij.codeInsight.template.impl.EditTemplateDialog; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.codeInsight.template.impl.TemplateSettings; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiElementFilter; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.HashMap; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class SaveAsTemplateAction extends AnAction { + public SaveAsTemplateAction() { + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + PsiFile file = (PsiFile)dataContext.getData(DataConstants.PSI_FILE); + + Project project = file.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final TextRange selection = new TextRange(editor.getSelectionModel().getSelectionStart(), + editor.getSelectionModel().getSelectionEnd()); + PsiElement current = file.findElementAt(selection.getStartOffset()); + int startOffset = selection.getStartOffset(); + while (current instanceof PsiWhiteSpace) { + current = current.getNextSibling(); + startOffset = current.getTextRange().getStartOffset(); + } + + if (startOffset >= selection.getEndOffset()) startOffset = selection.getStartOffset(); + + final PsiElement[] psiElements = PsiTreeUtil.collectElements(file, new PsiElementFilter() { + public boolean isAccepted(PsiElement element) { + if (!(element instanceof PsiJavaCodeReferenceElement)) return false; + if (!selection.contains(element.getTextRange())) return false; + PsiElement ref = ((PsiJavaCodeReferenceElement)element).resolve(); + if (!(ref instanceof PsiClass)) return false; + PsiClass psiClass = (PsiClass)ref; + if (!(psiClass.getParent() instanceof PsiJavaFile)) return false; + PsiDirectory directory = PsiTreeUtil.getParentOfType(psiClass, PsiDirectory.class); + if (directory.getPackage().getQualifiedName().equals("java.lang")) return false; + return true; + } + }); + + final Document document = EditorFactory.getInstance().createDocument(editor.getDocument().getText(). + substring(startOffset, + selection.getEndOffset())); + final int offsetDelta = startOffset; + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + Map rangeToClass = new HashMap(); + + for (int i = 0; i < psiElements.length; i++) { + PsiElement element = psiElements[i]; + TextRange textRange = element.getTextRange(); + rangeToClass.put(document.createRangeMarker( + element.getTextRange().getStartOffset() - offsetDelta, + textRange.getEndOffset() - offsetDelta), + ((PsiJavaCodeReferenceElement)element).resolve()); + } + + Set ranges = rangeToClass.keySet(); + for (Iterator i = ranges.iterator(); i.hasNext();) { + RangeMarker textRange = (RangeMarker)i.next(); + PsiClass psiClass = (PsiClass)rangeToClass.get(textRange); + document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), psiClass.getQualifiedName()); + } + } + }); + } + }, null, null); + + TemplateSettings templateSettings = TemplateSettings.getInstance(); + + TemplateImpl template = new TemplateImpl("", document.getText(), TemplateSettings.USER_GROUP_NAME); + + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file.getVirtualFile()); + if (fileType == StdFileTypes.HTML) { + template.getTemplateContext().HTML = true; + template.getTemplateContext().JAVA_CODE = false; + } + else if (fileType == StdFileTypes.XML) { + template.getTemplateContext().XML = true; + template.getTemplateContext().JAVA_CODE = false; + } + else if (fileType == StdFileTypes.JSP) { + template.getTemplateContext().JSP = true; + template.getTemplateContext().JAVA_CODE = false; + } + else if (fileType != StdFileTypes.JAVA) { + template.getTemplateContext().OTHER = true; + template.getTemplateContext().JAVA_CODE = false; + } + + String defaultShortcut = ""; + if (templateSettings.getDefaultShortcutChar() == TemplateSettings.ENTER_CHAR) defaultShortcut = "Enter"; + if (templateSettings.getDefaultShortcutChar() == TemplateSettings.TAB_CHAR) defaultShortcut = "Tab"; + if (templateSettings.getDefaultShortcutChar() == TemplateSettings.SPACE_CHAR) defaultShortcut = "Space"; + + EditTemplateDialog dialog = new EditTemplateDialog( + editor.getComponent(), + "Edit Live Template", + template, + templateSettings.getTemplates(), + defaultShortcut); + dialog.show(); + if (!dialog.isOK()) { + return; + } + dialog.apply(); + templateSettings.addTemplate(template); + templateSettings.setLastSelectedTemplateKey(template.getKey()); + } + + public void update(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + PsiFile file = (PsiFile)dataContext.getData(DataConstants.PSI_FILE); + + if (file == null || editor == null) { + e.getPresentation().setEnabled(false); + } + else { + e.getPresentation().setEnabled(editor.getSelectionModel().hasSelection()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ConstantNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ConstantNode.java new file mode 100644 index 00000000000..ef8ed85ebd8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ConstantNode.java @@ -0,0 +1,31 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.editor.*; +import java.util.*; +import com.intellij.openapi.project.Project; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; + +/** + * + */ +class ConstantNode implements Expression { + private Result myValue; + + public ConstantNode(String value) { + myValue = new TextResult(value); + } + + public Result calculateResult(ExpressionContext context) { + return myValue; + } + + public Result calculateQuickResult(ExpressionContext context) { + return myValue; + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + return new LookupItem[0]; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EditTemplateDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EditTemplateDialog.java new file mode 100644 index 00000000000..bd78c553fd7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EditTemplateDialog.java @@ -0,0 +1,603 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; + +public class EditTemplateDialog extends DialogWrapper { + private TemplateImpl[] myTemplates; + private TemplateImpl myTemplate; + + private final JTextField myKeyField; + private final JTextField myDescription; + private final ComboBox myGroupCombo; + private final Editor myTemplateEditor; + private ArrayList myVariables = new ArrayList(); + + private JComboBox myExpandByCombo; + private String myDefaultShortcutItem; + private JCheckBox myCbReformat; + private JCheckBox myCbShortenFQNames; + + private JCheckBox myCbJavaCode; + private JCheckBox myCbJavaComment; + private JCheckBox myCbJavaString; + private JCheckBox myCbCompletion; + private JCheckBox myCbOther; + private JCheckBox myCbHTML; + private JCheckBox myCbXML; + private JCheckBox myCbJSP; + + private JButton myEditVariablesButton; + + private static final String SPACE = "Space"; + private static final String TAB = "Tab"; + private static final String ENTER = "Enter"; + + public EditTemplateDialog(Component parent, String title, TemplateImpl template, TemplateImpl[] templates, String defaultShortcut) { + super(parent, true); + setOKButtonText("OK"); + setTitle(title); + + myTemplate = template; + myTemplates = templates; + myDefaultShortcutItem = "Default (" + defaultShortcut + ")"; + + myKeyField=new JTextField(); + myDescription=new JTextField(); + myGroupCombo=new ComboBox(-1); + myTemplateEditor = TemplateEditorUtil.createEditor(false); + + init(); + reset(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public void doHelpAction() { + HelpManager.getInstance().invokeHelp("editing.templates.defineTemplates.editTemplate"); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.codeInsight.template.impl.EditTemplateDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return myKeyField; + } + + protected void dispose() { + super.dispose(); + EditorFactory.getInstance().releaseEditor(myTemplateEditor); + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weighty = 0; + + gbConstraints.gridwidth = 2; + gbConstraints.gridx = 0; + + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Template text")); + JPanel textPanel = panel1; + textPanel.setPreferredSize(new Dimension(500, 160)); + textPanel.setMinimumSize(new Dimension(500, 160)); + textPanel.setLayout(new BorderLayout()); + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.gridy++; + textPanel.add(myTemplateEditor.getComponent(), BorderLayout.CENTER); + panel.add(textPanel, gbConstraints); + + gbConstraints.weighty = 0; + gbConstraints.gridy++; + myEditVariablesButton = new JButton("Edit variables"); + myEditVariablesButton.setDefaultCapable(false); + myEditVariablesButton.setMaximumSize(myEditVariablesButton.getPreferredSize()); + panel.add(myEditVariablesButton, gbConstraints); + + gbConstraints.weighty = 0; + gbConstraints.gridwidth = 1; + gbConstraints.gridy++; + panel.add(createTemplateOptionsPanel(), gbConstraints); + + gbConstraints.gridx = 1; + panel.add(createContextPanel(), gbConstraints); + + myKeyField.getDocument().addDocumentListener(new com.intellij.ui.DocumentAdapter() { + protected void textChanged(javax.swing.event.DocumentEvent e) { + validateOKButton(); + } + }); + + myTemplateEditor.getDocument().addDocumentListener( + new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + validateOKButton(); + validateEditVariablesButton(); + } + } + ); + + myEditVariablesButton.addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent e) { + editVariables(); + } + } + ); + return panel; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.insets = new Insets(4,4,4,4); + gbConstraints.weighty = 1; + + gbConstraints.weightx = 0; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + JLabel keyPrompt = new JLabel("Abbreviation:"); + keyPrompt.setDisplayedMnemonic('A'); + keyPrompt.setLabelFor(myKeyField); + panel.add(keyPrompt, gbConstraints); + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + panel.add(myKeyField, gbConstraints); + + gbConstraints.weightx = 0; + gbConstraints.gridx = 2; + JLabel groupPrompt = new JLabel("Group:"); + groupPrompt.setDisplayedMnemonic('G'); + groupPrompt.setLabelFor(myGroupCombo); + panel.add(groupPrompt, gbConstraints); + + gbConstraints.weightx = 1; + gbConstraints.gridx = 3; + myGroupCombo.setEditable(true); + panel.add(myGroupCombo, gbConstraints); + + gbConstraints.weightx = 0; + gbConstraints.gridx = 0; + gbConstraints.gridy++; + JLabel descriptionPrompt = new JLabel("Description:"); + descriptionPrompt.setDisplayedMnemonic('D'); + descriptionPrompt.setLabelFor(myDescription); + panel.add(descriptionPrompt, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.gridwidth = 3; + gbConstraints.weightx = 1; + panel.add(myDescription, gbConstraints); + + return panel; + } + + private JPanel createTemplateOptionsPanel() { + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Options")); + JPanel panel = panel1; + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.weighty = 0; + gbConstraints.weightx = 0; + gbConstraints.gridy = 0; + panel.add(new JLabel("Expand with "), gbConstraints); + + gbConstraints.gridx = 1; + myExpandByCombo = new JComboBox(); + myExpandByCombo.addItem(myDefaultShortcutItem); + myExpandByCombo.addItem(SPACE); + myExpandByCombo.addItem(TAB); + myExpandByCombo.addItem(ENTER); + panel.add(myExpandByCombo, gbConstraints); + gbConstraints.weightx = 1; + gbConstraints.gridx = 2; + panel.add(new JPanel(), gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridy++; + gbConstraints.gridwidth = 3; + myCbReformat = new JCheckBox("Reformat according to style"); + myCbReformat.setMnemonic('R'); + panel.add(myCbReformat, gbConstraints); + + gbConstraints.gridy++; + myCbShortenFQNames = new JCheckBox("Shorten FQ names"); + myCbShortenFQNames.setMnemonic('F'); + panel.add(myCbShortenFQNames, gbConstraints); + + gbConstraints.weighty = 1; + gbConstraints.gridy++; + panel.add(new JPanel(), gbConstraints); + + return panel; + } + + private JPanel createContextPanel() { + ChangeListener listener = new ChangeListener() { + public void stateChanged(ChangeEvent e) { + myExpandByCombo.setEnabled(!isEnabledInStaticContextOnly()); + } + + }; + + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Context")); + JPanel panel = panel1; + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + + gbConstraints.gridy = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + myCbJavaCode = new JCheckBox("Java code"); + myCbJavaCode.setMnemonic('J'); + myCbJavaCode.getModel().addChangeListener(listener); + panel.add(myCbJavaCode, gbConstraints); + + gbConstraints.gridx = 1; + myCbHTML = new JCheckBox("HTML"); + myCbHTML.setMnemonic('H'); + panel.add(myCbHTML, gbConstraints); + myCbHTML.getModel().addChangeListener(listener); + + gbConstraints.gridy++; + gbConstraints.gridx = 0; + myCbJavaComment = new JCheckBox("Java comment"); + myCbJavaComment.setMnemonic('c'); + panel.add(myCbJavaComment, gbConstraints); + myCbJavaComment.getModel().addChangeListener(listener); + + gbConstraints.gridx = 1; + myCbXML = new JCheckBox("XML"); + myCbXML.setMnemonic('x'); + panel.add(myCbXML, gbConstraints); + myCbXML.getModel().addChangeListener(listener); + + gbConstraints.gridy++; + gbConstraints.gridx = 0; + myCbJavaString = new JCheckBox("Java string"); + myCbJavaString.setMnemonic('s'); + panel.add(myCbJavaString, gbConstraints); + myCbJavaString.getModel().addChangeListener(listener); + + gbConstraints.gridx = 1; + myCbJSP = new JCheckBox("JSP"); + myCbJSP.setMnemonic('P'); + panel.add(myCbJSP, gbConstraints); + myCbJSP.getModel().addChangeListener(listener); + + gbConstraints.gridy++; + gbConstraints.gridx = 0; + myCbCompletion = new JCheckBox("Smart type completion"); + myCbCompletion.setMnemonic('o'); + panel.add(myCbCompletion, gbConstraints); + myCbCompletion.getModel().addChangeListener(listener); + + gbConstraints.gridx = 1; + myCbOther = new JCheckBox("Other"); + myCbOther.setMnemonic('t'); + panel.add(myCbOther, gbConstraints); + myCbOther.getModel().addChangeListener(listener); + + addUpdateHighlighterAction(myCbJavaCode); + addUpdateHighlighterAction(myCbJavaComment); + addUpdateHighlighterAction(myCbJavaString); + addUpdateHighlighterAction(myCbCompletion); + addUpdateHighlighterAction(myCbXML); + addUpdateHighlighterAction(myCbHTML); + addUpdateHighlighterAction(myCbJSP); + addUpdateHighlighterAction(myCbOther); + + return panel; + } + + private boolean isEnabledInStaticContextOnly() { + return + myCbCompletion.isSelected() && + !myCbJavaCode.isSelected() && + !myCbJavaComment.isSelected() && + !myCbJavaString.isSelected() && + !myCbXML.isSelected() && + !myCbHTML.isSelected() && + !myCbJSP.isSelected() && + !myCbOther.isSelected(); + } + + private void addUpdateHighlighterAction(JCheckBox checkbox) { + checkbox.addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent e) { + updateHighlighter(); + } + } + ); + } + + private void updateHighlighter() { + TemplateContext templateContext = new TemplateContext(); + updateTemplateContext(templateContext); + TemplateEditorUtil.setHighlighter(myTemplateEditor, templateContext); + ((EditorEx) myTemplateEditor).repaint(0, myTemplateEditor.getDocument().getTextLength()); + } + + private void validateEditVariablesButton() { + ArrayList variables = new ArrayList(); + parseVariables(myTemplateEditor.getDocument().getCharsSequence(), variables); + + boolean enable = false; + + for (Iterator iterator = variables.iterator(); iterator.hasNext();) { + Variable variable = (Variable)iterator.next(); + if (!TemplateImpl.INTERNAL_VARS_SET.contains(variable.getName())) enable = true; + } + + myEditVariablesButton.setEnabled(enable); + } + + private void validateOKButton() { + boolean isEnabled = true; + if(myKeyField.getText().trim().length() == 0) { + isEnabled = false; + } + if(myTemplateEditor.getDocument().getTextLength() == 0) { + isEnabled = false; + } + setOKActionEnabled(isEnabled); + } + + private void reset() { + myKeyField.setText(myTemplate.getKey()); + myDescription.setText(myTemplate.getDescription()); + + if(myTemplate.getShortcutChar() == TemplateSettings.DEFAULT_CHAR) { + myExpandByCombo.setSelectedItem(myDefaultShortcutItem); + } + else if(myTemplate.getShortcutChar() == TemplateSettings.TAB_CHAR) { + myExpandByCombo.setSelectedItem(TAB); + } + else if(myTemplate.getShortcutChar() == TemplateSettings.ENTER_CHAR) { + myExpandByCombo.setSelectedItem(ENTER); + } + else { + myExpandByCombo.setSelectedItem(SPACE); + } + + CommandProcessor.getInstance().executeCommand( + null, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myTemplateEditor.getDocument().replaceString(0, myTemplateEditor.getDocument().getTextLength(), myTemplate.getString()); + } + }); + } + }, + "", + null + ); + + UndoManager.getGlobalInstance().clearUndoRedoQueue(TextEditorProvider.getInstance().getTextEditor(myTemplateEditor)); + + Set groups = new TreeSet(); + for (int i = 0; i < myTemplates.length; i++) { + TemplateImpl template = myTemplates[i]; + groups.add(template.getGroupName()); + } + + for (Iterator i = groups.iterator(); i.hasNext();) { + String groupName = (String)i.next(); + myGroupCombo.addItem(groupName); + } + + myGroupCombo.setSelectedItem(myTemplate.getGroupName()); + + myVariables.clear(); + for(int i = 0; i < myTemplate.getVariableCount(); i++) { + Variable variable = new Variable(myTemplate.getVariableNameAt(i), + myTemplate.getExpressionStringAt(i), + myTemplate.getDefaultValueStringAt(i), + myTemplate.isAlwaysStopAt(i)); + myVariables.add(variable); + } + + myCbJavaCode.setSelected(myTemplate.getTemplateContext().JAVA_CODE); + myCbJavaComment.setSelected(myTemplate.getTemplateContext().JAVA_COMMENT); + myCbJavaString.setSelected(myTemplate.getTemplateContext().JAVA_STRING); + myCbCompletion.setSelected(myTemplate.getTemplateContext().COMPLETION); + myCbOther.setSelected(myTemplate.getTemplateContext().OTHER); + myCbHTML.setSelected(myTemplate.getTemplateContext().HTML); + myCbXML.setSelected(myTemplate.getTemplateContext().XML); + myCbJSP.setSelected(myTemplate.getTemplateContext().JSP); + + myCbReformat.setSelected(myTemplate.isToReformat()); + myCbShortenFQNames.setSelected(myTemplate.isToShortenLongNames()); + myExpandByCombo.setEnabled(!isEnabledInStaticContextOnly()); + + updateHighlighter(); + validateOKButton(); + validateEditVariablesButton(); + } + + public void apply() { + updateVariablesByTemplateText(); + myTemplate.setKey(myKeyField.getText().trim()); + myTemplate.setDescription(myDescription.getText().trim()); + myTemplate.setGroupName(((String)myGroupCombo.getSelectedItem()).trim()); + + Object selectedItem = myExpandByCombo.getSelectedItem(); + if(myDefaultShortcutItem.equals(selectedItem)) { + myTemplate.setShortcutChar(TemplateSettings.DEFAULT_CHAR); + } + else if(TAB.equals(selectedItem)) { + myTemplate.setShortcutChar(TemplateSettings.TAB_CHAR); + } + else if(ENTER.equals(selectedItem)) { + myTemplate.setShortcutChar(TemplateSettings.ENTER_CHAR); + } + else { + myTemplate.setShortcutChar(TemplateSettings.SPACE_CHAR); + } + + myTemplate.removeAllParsed(); + + for(int i = 0; i < myVariables.size(); i++) { + Variable variable = (Variable)myVariables.get(i); + myTemplate.addVariable(variable.getName(), + variable.getExpressionString(), + variable.getDefaultValueString(), + variable.isAlwaysStopAt()); + } + + updateTemplateContext(myTemplate.getTemplateContext()); + + myTemplate.setToReformat(myCbReformat.isSelected()); + myTemplate.setToShortenLongNames(myCbShortenFQNames.isSelected()); + + myTemplate.setString(myTemplateEditor.getDocument().getText()); + myTemplate.parseSegments(); + } + + private void updateTemplateContext(TemplateContext templateContext) { + templateContext.JAVA_CODE = myCbJavaCode.isSelected(); + templateContext.JAVA_COMMENT = myCbJavaComment.isSelected(); + templateContext.JAVA_STRING = myCbJavaString.isSelected(); + templateContext.COMPLETION = myCbCompletion.isSelected(); + templateContext.OTHER = myCbOther.isSelected(); + templateContext.HTML = myCbHTML.isSelected(); + templateContext.XML = myCbXML.isSelected(); + templateContext.JSP = myCbJSP.isSelected(); + } + + private void editVariables() { + updateVariablesByTemplateText(); + ArrayList newVariables = new ArrayList(); + + for(int i = 0; i < myVariables.size(); i++){ + Variable variable = (Variable)myVariables.get(i); + if (!TemplateImpl.INTERNAL_VARS_SET.contains(variable.getName())) { + newVariables.add(variable.clone()); + } + } + + EditVariableDialog editVariableDialog = new EditVariableDialog(myTemplateEditor, myEditVariablesButton, newVariables); + editVariableDialog.show(); + if(!editVariableDialog.isOK()) return; + myVariables = newVariables; + } + + private void updateVariablesByTemplateText() { + + ArrayList parsedVariables = new ArrayList(); + parseVariables(myTemplateEditor.getDocument().getCharsSequence(), parsedVariables); + + Hashtable oldVariableNames = new Hashtable(); + for(int j = 0; j < myVariables.size(); j++){ + Variable oldVariable = (Variable)myVariables.get(j); + String name = oldVariable.getName(); + oldVariableNames.put(name, name); + } + + Hashtable newVariableNames = new Hashtable(); + for(int j = 0; j < parsedVariables.size(); j++){ + Variable newVariable = (Variable)parsedVariables.get(j); + String name = newVariable.getName(); + newVariableNames.put(name, name); + } + + int oldVariableNumber = 0; + for(int i = 0; i < parsedVariables.size(); i++){ + Variable variable = (Variable)parsedVariables.get(i); + String name = variable.getName(); + if(oldVariableNames.get(name) != null) { + Variable oldVariable = null; + for(;oldVariableNumber additionalMacros; + + public EditVariableDialog(Editor editor, Component parent, ArrayList variables, boolean _hasMoveVars, java.util.List _additionalMacros) { + super(parent, true); + + hasMoveVars = _hasMoveVars; + additionalMacros = _additionalMacros; + setButtonsMargin(null); + myVariables = variables; + myEditor = editor; + init(); + setTitle("Edit Template Variables"); + setOKButtonText("OK"); + updateButtons(); + } + + public EditVariableDialog(Editor editor, Component parent, ArrayList variables) { + this(editor,parent,variables,true,null); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("editing.templates.defineTemplates.editTemplVars"); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.codeInsight.template.impl.EditVariableDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return myTable; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createTitledBorder("Variables")); + JPanel tablePanel = panel; + tablePanel.setLayout(new BorderLayout()); + tablePanel.add(createVariablesTable(), BorderLayout.CENTER); + if (hasMoveVars) tablePanel.add(createTableButtonPanel(), BorderLayout.EAST); + return tablePanel; + } + + private JPanel createTableButtonPanel() { + JPanel tableButtonsPanel = new JPanel(); + tableButtonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + + tableButtonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(0, 0, 4, 0); + myMoveUpButton = new JButton("Move Up"); +// myMoveUpButton.setMargin(new Insets(2,0,0,2)); + myMoveUpButton.setMnemonic('U'); + tableButtonsPanel.add(myMoveUpButton, gbConstraints); + myMoveDownButton = new JButton("Move Down"); +// myMoveDownButton.setMargin(new Insets(2,0,0,2)); + myMoveDownButton.setMnemonic('D'); + tableButtonsPanel.add(myMoveDownButton, gbConstraints); + + gbConstraints.weighty = 1; + tableButtonsPanel.add(new JPanel(), gbConstraints); + + myMoveUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + moveRowUp(); + } + } + ); + + myMoveDownButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + moveRowDown(); + } + } + ); + + return tableButtonsPanel; + } + + private JComponent createVariablesTable() { + final String[] names = {"Name", "Expression", "Default value", "Skip if defined"}; + // Create a model of the data. + TableModel dataModel = new AbstractTableModel() { + public int getColumnCount() { + return names.length; + } + + public int getRowCount() { + return myVariables.size(); + } + + public Object getValueAt(int row, int col) { + Variable variable = (Variable)myVariables.get(row); + if (col == 0) { + return variable.getName(); + } + if (col == 1) { + return variable.getExpressionString(); + } + if (col == 2) { + return variable.getDefaultValueString(); + } + else { + return variable.isAlwaysStopAt() ? Boolean.FALSE : Boolean.TRUE; + } + } + + public String getColumnName(int column) { + return names[column]; + } + + public Class getColumnClass(int c) { + if (c <= 2) { + return String.class; + } + else { + return Boolean.class; + } + } + + public boolean isCellEditable(int row, int col) { + return true; + } + + public void setValueAt(Object aValue, int row, int col) { + Variable variable = (Variable)myVariables.get(row); + if (col == 0) { + String varName = (String) aValue; + Variable newVar = new Variable (varName, variable.getExpressionString(), variable.getDefaultValueString(), + variable.isAlwaysStopAt()); + myVariables.set(row, newVar); + updateTemplateTextByVarNameChange(variable, newVar); + } + else if (col == 1) { + variable.setExpressionString((String)aValue); + } + else if (col == 2) { + variable.setDefaultValueString((String)aValue); + } + else { + variable.setAlwaysStopAt(!((Boolean)aValue).booleanValue()); + } + } + }; + + // Create the table + myTable = new Table(dataModel); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.setPreferredScrollableViewportSize(new Dimension(500, myTable.getRowHeight() * 8)); + myTable.getColumn(names[0]).setPreferredWidth(120); + myTable.getColumn(names[1]).setPreferredWidth(200); + myTable.getColumn(names[2]).setPreferredWidth(200); + myTable.getColumn(names[3]).setPreferredWidth(100); + if (myVariables.size() > 0) { + myTable.getSelectionModel().setSelectionInterval(0, 0); + } + + JComboBox comboField = new JComboBox(); + Macro[] macros = MacroFactory.getMacros(); + + if (additionalMacros!=null) { + ArrayList list = new ArrayList(macros.length + additionalMacros.size()); + list.addAll( Arrays.asList(macros) ); + list.addAll( additionalMacros ); + macros = (Macro[])list.toArray(new Macro[0]); + } + + Arrays.sort(macros, new Comparator () { + public int compare(Macro m1, Macro m2) { + return m1.getDescription().compareTo(m2.getDescription()); + } + }); + for (int i = 0; i < macros.length; i++) { + Macro macro = macros[i]; + comboField.addItem(macro.getDescription()); + } + comboField.setEditable(true); + DefaultCellEditor cellEditor = new DefaultCellEditor(comboField); + cellEditor.setClickCountToStart(1); + myTable.getColumn(names[1]).setCellEditor(cellEditor); + myTable.setRowHeight(comboField.getPreferredSize().height); + + JTextField textField = new JTextField(); + + /*textField.addMouseListener( + new PopupHandler(){ + public void invokePopup(Component comp,int x,int y){ + showCellPopup((JTextField)comp,x,y); + } + } + );*/ + + cellEditor = new DefaultCellEditor(textField); + cellEditor.setClickCountToStart(1); + myTable.setDefaultEditor(String.class, cellEditor); + + myTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateButtons(); + } + } + ); + JScrollPane scrollpane = ScrollPaneFactory.createScrollPane(myTable); + return scrollpane; + } + + private void updateButtons() { + int selected = myTable.getSelectedRow(); + if (myMoveUpButton != null) { + myMoveUpButton.setEnabled(selected >= 1); + } + if (myMoveDownButton != null) { + myMoveDownButton.setEnabled(selected >= 0 && selected < myVariables.size() - 1); + } + } + + private void moveRowUp() { + int selected = myTable.getSelectedRow(); + if (selected < 1) { + return; + } + if (myTable.isEditing()) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + moveElementUp(myVariables, selected); + + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsUpdated(selected - 1, selected); + myTable.setRowSelectionInterval(selected - 1, selected - 1); + } + + private static void moveElementUp(ArrayList array, int offset) { + Object element = array.get(offset); + Object previousElement = array.get(offset - 1); + array.set(offset, previousElement); + array.set(offset - 1, element); + } + + private void moveRowDown() { + int selected = myTable.getSelectedRow(); + if (selected >= myVariables.size() - 1 || selected < 0) { + return; + } + if (myTable.isEditing()) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + moveElementDown(myVariables, selected); + + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsUpdated(selected, selected + 1); + myTable.setRowSelectionInterval(selected + 1, selected + 1); + } + + private static void moveElementDown(ArrayList array, int offset) { + Object element = array.get(offset); + Object nextElement = array.get(offset + 1); + array.set(offset, nextElement); + array.set(offset + 1, element); + } + + protected void doOKAction() { + if (myTable.isEditing()) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + super.doOKAction(); + } + + /*private void showCellPopup(final JTextField field,int x,int y) { + JPopupMenu menu = new JPopupMenu(); + final Macro[] macros = MacroFactory.getMacros(); + for (int i = 0; i < macros.length; i++) { + final Macro macro = macros[i]; + JMenuItem item = new JMenuItem(macro.getName()); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + field.saveToString().insertString(field.getCaretPosition(), macro.getName() + "()", null); + } + catch (BadLocationException e1) { + LOG.error(e1); + } + } + }); + menu.add(item); + } + menu.show(field, x, y); + }*/ + + private void updateTemplateTextByVarNameChange(final Variable oldVar, final Variable newVar) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(null, new Runnable() { + public void run() { + Document document = myEditor.getDocument(); + String templateText = document.getText(); + templateText = templateText.replaceAll("\\$" + oldVar.getName() + "\\$", "\\$" + newVar.getName() + "\\$"); + document.replaceString(0, document.getTextLength(), templateText); + } + }, null, null); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EmptyNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EmptyNode.java new file mode 100644 index 00000000000..277582c449e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/EmptyNode.java @@ -0,0 +1,28 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.Result; +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.codeInsight.template.Template; + +/** + * + */ +class EmptyNode implements Expression { + public EmptyNode() { + } + + public Result calculateResult(ExpressionContext context) { + return null; + } + + public Result calculateQuickResult(ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ListTemplatesHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ListTemplatesHandler.java new file mode 100644 index 00000000000..d3951952dfb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/ListTemplatesHandler.java @@ -0,0 +1,79 @@ + +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; + +import java.util.ArrayList; + +public class ListTemplatesHandler implements CodeInsightActionHandler{ + public void invoke(final Project project, final Editor editor, PsiFile file) { + if (!file.isWritable()) return; + EditorUtil.fillVirtualSpaceUntil(editor, editor.getCaretModel().getLogicalPosition().column, editor.getCaretModel().getLogicalPosition().line); + + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + int offset = editor.getCaretModel().getOffset(); + String prefix = getPrefix(editor.getDocument(), offset); + int contextType = TemplateManager.getInstance(project).getContextType(file, offset); + + TemplateImpl[] templates = TemplateSettings.getInstance().getTemplates(); + ArrayList array = new ArrayList(); + for(int i = 0; i < templates.length; i++){ + TemplateImpl template = templates[i]; + if (template.isDeactivated() || template.isSelectionTemplate()) continue; + String key = template.getKey(); + if (key.startsWith(prefix) && template.getTemplateContext().isInContext(contextType)){ + LookupItem item = new LookupItem(template, key); + array.add(item); + } + } + LookupItem[] items = (LookupItem[])array.toArray(new LookupItem[array.size()]); + + if (items.length == 0){ + String text = prefix.length() == 0 + ? "No templates defined in this context" + : "No templates starting with '" + prefix + "' defined in this context"; + HintManager.getInstance().showErrorHint(editor, text); + return; + } + + Lookup lookup = LookupManager.getInstance(project).showLookup(editor, items, prefix, null, new CharFilter() { + public int accept(char c) { + if (Character.isJavaIdentifierPart(c)) return CharFilter.ADD_TO_PREFIX; + return CharFilter.SELECT_ITEM_AND_FINISH_LOOKUP; + } + }); + lookup.addLookupListener( + new LookupAdapter() { + public void itemSelected(LookupEvent event) { + TemplateManager.getInstance(project).startTemplate(editor, '\0'); + } + } + ); + } + + public boolean startInWriteAction() { + return true; + } + + private String getPrefix(Document document, int offset) { + CharSequence chars = document.getCharsSequence(); + int start = offset; + while(true){ + if (start == 0) break; + char c = chars.charAt(start - 1); + if (Character.isWhitespace(c)) break; + //if (!Character.isJavaIdentifierPart(c)) break; + start--; + } + return chars.subSequence(start, offset).toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/LiveTemplatesConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/LiveTemplatesConfigurable.java new file mode 100644 index 00000000000..9afea314f33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/LiveTemplatesConfigurable.java @@ -0,0 +1,59 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class LiveTemplatesConfigurable extends BaseConfigurable implements ApplicationComponent { + private TemplateListPanel myPanel; + + public String getComponentName() { + return "LiveTemplatesConfigurable"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public LiveTemplatesConfigurable() { + } + + public boolean isModified() { + return myPanel.isModified(); + } + + public JComponent createComponent() { + myPanel = new TemplateListPanel(); + return myPanel; + } + + public String getDisplayName() { + return "Live Templates"; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/liveTemplates.png"); + } + + public void reset() { + myPanel.reset(); + } + + public void apply() { + myPanel.apply(); + } + + public void disposeUIResources() { + if (myPanel != null) { + myPanel.dispose(); + } + myPanel = null; + } + + public String getHelpTopic() { + return "editing.templates"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroCallNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroCallNode.java new file mode 100644 index 00000000000..af5a4847c94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroCallNode.java @@ -0,0 +1,45 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.codeInsight.template.Macro; +import com.intellij.codeInsight.template.Result; + +import java.util.ArrayList; + +/** + * + */ +public class MacroCallNode implements Expression { + public Macro getMacro() { + return myMacro; + } + + private Macro myMacro; + private ArrayList myParameters = new ArrayList(); + + public MacroCallNode(Macro macro) { + myMacro = macro; + } + + public void addParameter(Expression node) { + myParameters.add(node); + } + + public Result calculateResult(ExpressionContext context) { + Expression[] parameters = (Expression[])myParameters.toArray(new Expression[myParameters.size()]); + return myMacro.calculateResult(parameters, context); + } + + public Result calculateQuickResult(ExpressionContext context) { + Expression[] parameters = (Expression[])myParameters.toArray(new Expression[myParameters.size()]); + return myMacro.calculateQuickResult(parameters, context); + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + Expression[] parameters = (Expression[])myParameters.toArray(new Expression[myParameters.size()]); + return myMacro.calculateLookupItems(parameters, context); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroParser.java new file mode 100644 index 00000000000..3737a43db28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/MacroParser.java @@ -0,0 +1,122 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.Macro; +import com.intellij.codeInsight.template.macro.MacroFactory; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * + */ +class MacroParser { +//----------------------------------------------------------------------------------- + public static Expression parse(String expression) { + if(expression.length() == 0) { + return new ConstantNode(""); + } + Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3); + lexer.start(expression.toCharArray(), 0, expression.length()); + skipWhitespaces(lexer); + return parseMacro(lexer, expression); + } +//----------------------------------------------------------------------------------- + private static void advance(Lexer lexer) { + lexer.advance(); + skipWhitespaces(lexer); + } + +//----------------------------------------------------------------------------------- + private static void skipWhitespaces(Lexer lexer) { + while(lexer.getTokenType() == JavaTokenType.WHITE_SPACE) { + lexer.advance(); + } + } +//----------------------------------------------------------------------------------- + private static String getString(Lexer lexer, String expression) { + return expression.substring(lexer.getTokenStart(), lexer.getTokenEnd()); + } + +//----------------------------------------------------------------------------------- + private static Expression parseMacro(Lexer lexer, String expression) { + IElementType tokenType = lexer.getTokenType(); + String token = getString(lexer, expression); + if(tokenType == JavaTokenType.STRING_LITERAL) { + advance(lexer); + + return new ConstantNode(token.substring(1, token.length()-1).replaceAll("\\\\n", "\n"). + replaceAll("\\\\r", "\r").replaceAll("\\\\t", "\t").replaceAll("\\\\f", "\f").replaceAll("\\\\(.)", "$1")); + } + + if(tokenType != JavaTokenType.IDENTIFIER) { + System.out.println("Bad macro syntax: Not identifier: " + token); + advance(lexer); + return new ConstantNode(""); + } + + Macro macro = MacroFactory.createMacro(token); + if(macro == null) { + return parseVariable(lexer, expression); + } + + advance(lexer); + MacroCallNode macroCallNode = new MacroCallNode(macro); + if(lexer.getTokenType() == null) { + return macroCallNode; + } + + String token2 = getString(lexer, expression); + if(!token2.equals("(")) { + return macroCallNode; + } + + advance(lexer); + parseParameters(macroCallNode, lexer, expression); + String token3 = getString(lexer, expression); + if(!token3.equals(")")) { + System.out.println("Bad macro syntax: ) expected: " + expression); + } + advance(lexer); + return macroCallNode; + } + private static void parseParameters(MacroCallNode macroCallNode, Lexer lexer, String expression) { + if (!getString(lexer, expression).equals(")")) { + while (lexer.getTokenType() != null) { + Expression node = parseMacro(lexer, expression); + macroCallNode.addParameter(node); + String token = getString(lexer, expression); + + if (token.equals(",")) { + advance(lexer); + } else { + break; + } + } + } + } + + private static Expression parseVariable(Lexer lexer, String expression) { + String variableName = getString(lexer, expression); + advance(lexer); + + if(lexer.getTokenType() == null) { + if(TemplateImpl.END.equals(variableName)) { + return new EmptyNode(); + } + + return new VariableNode(variableName, null); + } + + String token = getString(lexer, expression); + if(!token.equals("=")) { + return new VariableNode(variableName, null); + } + + advance(lexer); + Expression node = parseMacro(lexer, expression); + return new VariableNode(variableName, node); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SelectionNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SelectionNode.java new file mode 100644 index 00000000000..34c93edb2ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SelectionNode.java @@ -0,0 +1,25 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.lookup.LookupItem; + +/** + * @author mike + */ +public class SelectionNode implements Expression { + public SelectionNode() { + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + return new LookupItem[0]; + } + + public Result calculateQuickResult(ExpressionContext context) { + return new TextResult((String)context.getProperties().get(ExpressionContext.SELECTION)); + } + + public Result calculateResult(ExpressionContext context) { + return calculateQuickResult(context); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SurroundWithTemplateHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SurroundWithTemplateHandler.java new file mode 100644 index 00000000000..5c4acd74b66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/SurroundWithTemplateHandler.java @@ -0,0 +1,194 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.ui.ListPopup; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.SpeedSearchBase; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +/** + * @author mike + */ +public class SurroundWithTemplateHandler implements CodeInsightActionHandler { + public SurroundWithTemplateHandler() { + } + + public void invoke(final Project project, final Editor editor, PsiFile file) { + if (!file.isWritable()) return; + if (!editor.getSelectionModel().hasSelection()) { + editor.getSelectionModel().selectLineAtCaret(); + if (!editor.getSelectionModel().hasSelection()) return; + } + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + int offset = editor.getCaretModel().getOffset(); + int contextType = TemplateManager.getInstance(project).getContextType(file, offset); + TemplateImpl[] templates = TemplateSettings.getInstance().getTemplates(); + ArrayList array = new ArrayList(); + for (int i = 0; i < templates.length; i++) { + TemplateImpl template = templates[i]; + if (template.isDeactivated()) continue; + if (template.getTemplateContext().isInContext(contextType) && template.isSelectionTemplate()) { + array.add(template); + } + } + if (array.isEmpty()) { + HintManager.getInstance().showErrorHint(editor, "No templates defined in this context"); + return; + } + Collections.sort(array, new Comparator() { + public int compare(TemplateImpl o1, TemplateImpl o2) { + return o1.getKey().compareTo(o2.getKey()); + } + }); + final TemplateImpl[] listData = array.toArray(new TemplateImpl[array.size()]); + final JList list = new JList(listData); + list.setCellRenderer(new MyListCellRenderer(listData)); + ListPopup listPopup = new ListPopup( + " Select Template ", + list, + new Runnable() { + public void run() { + String selectionString = editor.getSelectionModel().getSelectedText(); + TemplateImpl template = (TemplateImpl)list.getSelectedValue(); + if (selectionString != null) { + if (template.isToReformat()) selectionString = selectionString.trim(); + } + TemplateManager.getInstance(project).startTemplate(editor, selectionString, template); + } + }, + project + ); + new MySpeedSearchBase(listPopup, list, listData); + LogicalPosition pos = editor.getCaretModel().getLogicalPosition(); + Point caretLocation = editor.logicalPositionToXY(new LogicalPosition(pos.line + 1, pos.column)); + int y = caretLocation.y; + int x = caretLocation.x; + Point location = editor.getContentComponent().getLocationOnScreen(); + x += location.x; + y += location.y; + listPopup.show(x, y); + } + + public boolean startInWriteAction() { + return true; + } + + private class MyListCellRenderer extends JPanel implements ListCellRenderer { + private JLabel myAbbreviation = new JLabel(); + private JLabel myDescription = new JLabel(); + + public MyListCellRenderer(TemplateImpl[] templates) { + setLayout(new BorderLayout()); + add(myAbbreviation, BorderLayout.WEST); + add(myDescription, BorderLayout.CENTER); + myAbbreviation.setAlignmentX(JComponent.LEFT_ALIGNMENT); + myDescription.setAlignmentX(JComponent.LEFT_ALIGNMENT); + myAbbreviation.setHorizontalAlignment(JCheckBox.LEFT); + myDescription.setHorizontalAlignment(JCheckBox.LEFT); + myAbbreviation.setOpaque(true); + myDescription.setOpaque(true); + int width = 0; + int height = 0; + for (int i = 0; i < templates.length; i++) { + TemplateImpl template = templates[i]; + myAbbreviation.setText(getAbbreviation(template)); + final Dimension preferredSize = myAbbreviation.getPreferredSize(); + width = Math.max(width, preferredSize.width); + height = Math.max(height, preferredSize.height); + } + myAbbreviation.setPreferredSize(new Dimension(width, height)); + myAbbreviation.setMinimumSize(new Dimension(width, height)); + myAbbreviation.setMaximumSize(new Dimension(width, height)); + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + TemplateImpl template = (TemplateImpl)value; + myAbbreviation.setText(getAbbreviation(template)); + myDescription.setText(" " + template.getDescription() + " "); + if (isSelected) { + myAbbreviation.setBackground(list.getSelectionBackground()); + myDescription.setBackground(list.getSelectionBackground()); + setBackground(list.getSelectionBackground()); + myAbbreviation.setForeground(list.getSelectionForeground()); + myDescription.setForeground(list.getSelectionForeground()); + } + else { + myAbbreviation.setBackground(list.getBackground()); + myDescription.setBackground(list.getBackground()); + myAbbreviation.setForeground(list.getForeground()); + myDescription.setForeground(list.getForeground()); + setBackground(list.getBackground()); + } + if (cellHasFocus) { + setBorder(BorderFactory.createLineBorder(Color.black)); + } + else { + setBorder(BorderFactory.createLineBorder(list.getBackground())); + } + return this; + } + + private String getAbbreviation(TemplateImpl template) { + return " " + template.getKey() + " "; + } + } + + private class MySpeedSearchBase extends SpeedSearchBase { + private ListPopup myListPopup; + private final JList myList; + private final TemplateImpl[] myListData; + + public MySpeedSearchBase(ListPopup listPopup, JList list, TemplateImpl[] listData) { + super(list); + myListPopup = listPopup; + myList = list; + myListData = listData; + } + + protected Object[] getAllElements() { + return myListData; + } + + protected String getElementText(Object element) { + return ((TemplateImpl)element).getKey(); + } + + protected int getSelectedIndex() { + return myList.getSelectedIndex(); + } + + protected void selectElement(Object element, String selectedText) { + ListScrollingUtil.selectItem(myList, element); + int matches = 0; + TemplateImpl result = null; + for (int i = 0; i < myListData.length; i++) { + TemplateImpl template = myListData[i]; + if (template.getKey().toLowerCase().startsWith(selectedText.toLowerCase())) matches++; + if (template.getKey().equalsIgnoreCase(selectedText)) result = template; + } + if (matches == 1 && result != null) { + myListPopup.closePopup(true); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableMap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableMap.java new file mode 100644 index 00000000000..99108d25d3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableMap.java @@ -0,0 +1,70 @@ +package com.intellij.codeInsight.template.impl; + +/** + * In a chain of data manipulators some behaviour is common. TableMap + * provides most of this behavour and can be subclassed by filters + * that only need to override a handful of specific methods. TableMap + * implements TableModel by routing all requests to its model, and + * TableModelListener by routing all events to its listeners. Inserting + * a TableMap which has not been subclassed into a chain of table filters + * should have no effect. + * + * @version 1.4 12/17/97 + * @author Philip Milne */ + +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; + +public class TableMap extends AbstractTableModel + implements TableModelListener { + protected TableModel model; + + public TableModel getModel() { + return model; + } + + public void setModel(TableModel model) { + this.model = model; + model.addTableModelListener(this); + } + + // By default, implement TableModel by forwarding all messages + // to the model. + + public Object getValueAt(int aRow, int aColumn) { + return model.getValueAt(aRow, aColumn); + } + + public void setValueAt(Object aValue, int aRow, int aColumn) { + model.setValueAt(aValue, aRow, aColumn); + } + + public int getRowCount() { + return (model == null) ? 0 : model.getRowCount(); + } + + public int getColumnCount() { + return (model == null) ? 0 : model.getColumnCount(); + } + + public String getColumnName(int aColumn) { + return model.getColumnName(aColumn); + } + + public Class getColumnClass(int aColumn) { + return model.getColumnClass(aColumn); + } + + public boolean isCellEditable(int row, int column) { + return model.isCellEditable(row, column); + } +// +// Implementation of the TableModelListener interface, +// + // By default forward all events to all the listeners. + public void tableChanged(TableModelEvent e) { + fireTableChanged(e); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableSorter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableSorter.java new file mode 100644 index 00000000000..8035b3c9770 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TableSorter.java @@ -0,0 +1,314 @@ +package com.intellij.codeInsight.template.impl; + +/** + * A sorter for TableModels. The sorter has a model (conforming to TableModel) + * and itself implements TableModel. TableSorter does not store or copy + * the data in the TableModel, instead it maintains an array of + * integers which it keeps the same size as the number of rows in its + * model. When the model changes it notifies the sorter that something + * has changed eg. "rowsAdded" so that its internal array of integers + * can be reallocated. As requests are made of the sorter (like + * getValueAt(row, col) it redirects them to its model via the mapping + * array. That way the TableSorter appears to hold another copy of the table + * with the rows in a different order. The sorting algorthm used is stable + * which means that it does not move around rows when its comparison + * function returns 0 to denote that they are equivalent. + * + * @version 1.5 12/17/97 + * @author Philip Milne + */ + +import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Date; +import java.util.Vector; + +public class TableSorter extends TableMap { + int indexes[]; + Vector sortingColumns = new Vector(); + boolean ascending = true; + int compares; + + public int mapRow (int row) { + return indexes[row]; + } + + public TableSorter() { + indexes = new int[0]; // for consistency + } + + public TableSorter(TableModel model) { + setModel(model); + } + + public void setModel(TableModel model) { + super.setModel(model); + reallocateIndexes(); + } + + public int compareRowsByColumn(int row1, int row2, int column) { + Class type = model.getColumnClass(column); + TableModel data = model; + + // Check for nulls. + + Object o1 = data.getValueAt(row1, column); + Object o2 = data.getValueAt(row2, column); + + // If both values are null, return 0. + if (o1 == null && o2 == null) { + return 0; + } else if (o1 == null) { // Define null less than everything. + return -1; + } else if (o2 == null) { + return 1; + } + + /* + * We copy all returned values from the getValue call in case + * an optimised model is reusing one object to return many + * values. The Number subclasses in the JDK are immutable and + * so will not be used in this way but other subclasses of + * Number might want to do this to save space and avoid + * unnecessary heap allocation. + */ + + if (type.getSuperclass() == java.lang.Number.class) { + Number n1 = (Number)data.getValueAt(row1, column); + double d1 = n1.doubleValue(); + Number n2 = (Number)data.getValueAt(row2, column); + double d2 = n2.doubleValue(); + + if (d1 < d2) { + return -1; + } else if (d1 > d2) { + return 1; + } else { + return 0; + } + } else if (type == java.util.Date.class) { + Date d1 = (Date)data.getValueAt(row1, column); + long n1 = d1.getTime(); + Date d2 = (Date)data.getValueAt(row2, column); + long n2 = d2.getTime(); + + if (n1 < n2) { + return -1; + } else if (n1 > n2) { + return 1; + } else { + return 0; + } + } else if (type == String.class) { + String s1 = (String)data.getValueAt(row1, column); + String s2 = (String)data.getValueAt(row2, column); + int result = s1.compareTo(s2); + + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } else { + return 0; + } + } else if (type == Boolean.class) { + Boolean bool1 = (Boolean)data.getValueAt(row1, column); + boolean b1 = bool1.booleanValue(); + Boolean bool2 = (Boolean)data.getValueAt(row2, column); + boolean b2 = bool2.booleanValue(); + + if (b1 == b2) { + return 0; + } else if (b1) { // Define false < true + return 1; + } else { + return -1; + } + } else { + Object v1 = data.getValueAt(row1, column); + String s1 = v1.toString(); + Object v2 = data.getValueAt(row2, column); + String s2 = v2.toString(); + int result = s1.compareTo(s2); + + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } else { + return 0; + } + } + } + + public int compare(int row1, int row2) { + compares++; + for (int level = 0; level < sortingColumns.size(); level++) { + Integer column = (Integer)sortingColumns.elementAt(level); + int result = compareRowsByColumn(row1, row2, column.intValue()); + if (result != 0) { + return ascending ? result : -result; + } + } + return 0; + } + + public void reallocateIndexes() { + int rowCount = model.getRowCount(); + + // Set up a new array of indexes with the right number of elements + // for the new data model. + indexes = new int[rowCount]; + + // Initialise with the identity mapping. + for (int row = 0; row < rowCount; row++) { + indexes[row] = row; + } + } + + public void tableChanged(TableModelEvent e) { + //System.out.println("Sorter: tableChanged"); + reallocateIndexes(); + + super.tableChanged(e); + } + + public void checkModel() { + if (indexes.length != model.getRowCount()) { + System.err.println("Sorter not informed of a change in model."); + } + } + + public void sort(Object sender) { + checkModel(); + + compares = 0; + // n2sort(); + // qsort(0, indexes.length-1); + shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length); + //System.out.println("Compares: "+compares); + } + + public void n2sort() { + for (int i = 0; i < getRowCount(); i++) { + for (int j = i+1; j < getRowCount(); j++) { + if (compare(indexes[i], indexes[j]) == -1) { + swap(i, j); + } + } + } + } + + // This is a home-grown implementation which we have not had time + // to research - it may perform poorly in some circumstances. It + // requires twice the space of an in-place algorithm and makes + // NlogN assigments shuttling the values between the two + // arrays. The number of compares appears to vary between N-1 and + // NlogN depending on the initial order but the main reason for + // using it here is that, unlike qsort, it is stable. + public void shuttlesort(int from[], int to[], int low, int high) { + if (high - low < 2) { + return; + } + int middle = (low + high)/2; + shuttlesort(to, from, low, middle); + shuttlesort(to, from, middle, high); + + int p = low; + int q = middle; + + /* This is an optional short-cut; at each recursive call, + check to see if the elements in this subset are already + ordered. If so, no further comparisons are needed; the + sub-array can just be copied. The array must be copied rather + than assigned otherwise sister calls in the recursion might + get out of sinc. When the number of elements is three they + are partitioned so that the first set, [low, mid), has one + element and and the second, [mid, high), has two. We skip the + optimisation when the number of elements is three or less as + the first compare in the normal merge will produce the same + sequence of steps. This optimisation seems to be worthwhile + for partially ordered lists but some analysis is needed to + find out how the performance drops to Nlog(N) as the initial + order diminishes - it may drop very quickly. */ + + if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { + for (int i = low; i < high; i++) { + to[i] = from[i]; + } + return; + } + + // A normal merge. + + for (int i = low; i < high; i++) { + if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { + to[i] = from[p++]; + } + else { + to[i] = from[q++]; + } + } + } + + public void swap(int i, int j) { + int tmp = indexes[i]; + indexes[i] = indexes[j]; + indexes[j] = tmp; + } + + // The mapping only affects the contents of the data rows. + // Pass all requests to these rows through the mapping array: "indexes". + + public Object getValueAt(int aRow, int aColumn) { + checkModel(); + return model.getValueAt(indexes[aRow], aColumn); + } + + public void setValueAt(Object aValue, int aRow, int aColumn) { + checkModel(); + model.setValueAt(aValue, indexes[aRow], aColumn); + } + + public void sortByColumn(int column) { + sortByColumn(column, true); + } + + public void sortByColumn(int column, boolean ascending) { + this.ascending = ascending; + sortingColumns.removeAllElements(); + sortingColumns.addElement(new Integer(column)); + sort(this); + super.tableChanged(new TableModelEvent(this)); + } + + // There is no-where else to put this. + // Add a mouse listener to the Table to trigger a table sort + // when a column heading is clicked in the JTable. + public void addMouseListenerToHeaderInTable(JTable table) { + final TableSorter sorter = this; + final JTable tableView = table; + tableView.setColumnSelectionAllowed(false); + MouseAdapter listMouseListener = new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + TableColumnModel columnModel = tableView.getColumnModel(); + int viewColumn = columnModel.getColumnIndexAtX(e.getX()); + int column = tableView.convertColumnIndexToModel(viewColumn); + if (e.getClickCount() == 1 && column != -1) { + //System.out.println("Sorting ..."); + int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; + boolean ascending = (shiftPressed == 0); + sorter.sortByColumn(column, ascending); + } + } + }; + JTableHeader th = tableView.getTableHeader(); + th.addMouseListener(listMouseListener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateColors.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateColors.java new file mode 100644 index 00000000000..6523667dcfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateColors.java @@ -0,0 +1,7 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.editor.colors.TextAttributesKey; + +public interface TemplateColors { + TextAttributesKey TEMPLATE_VARIABLE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("TEMPLATE_VARIABLE_ATTRIBUTES"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateContext.java new file mode 100644 index 00000000000..cc720c8a0f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateContext.java @@ -0,0 +1,77 @@ +package com.intellij.codeInsight.template.impl; + + +import com.intellij.openapi.util.*; +import org.jdom.Element; + +public class TemplateContext implements JDOMExternalizable, Cloneable { + + public boolean JAVA_CODE = true; + public boolean JAVA_COMMENT = false; + public boolean JAVA_STRING = false; + public boolean XML = false; + public boolean HTML = false; + public boolean JSP = false; + public boolean COMPLETION = false; + public boolean OTHER = false; + + private static final int NONE_CONTEXT = 0; + public static final int JAVA_CODE_CONTEXT = 1; + public static final int JAVA_COMMENT_CONTEXT = 2; + public static final int JAVA_STRING_CONTEXT = 3; + public static final int XML_CONTEXT = 4; + public static final int HTML_CONTEXT = 5; + public static final int JSP_CONTEXT = 6; + public static final int OTHER_CONTEXT = 7; + public static final int COMPLETION_CONTEXT = 8;; + + public Object clone() { + try { + return super.clone(); + } + catch(CloneNotSupportedException e) { + return null; + } + } + + public boolean isInContext(int contextType) { + switch(contextType){ + case NONE_CONTEXT: + return false; + + case JAVA_CODE_CONTEXT: + return JAVA_CODE; + + case JAVA_COMMENT_CONTEXT: + return JAVA_COMMENT; + + case JAVA_STRING_CONTEXT: + return JAVA_STRING; + + case XML_CONTEXT: + return XML; + + case HTML_CONTEXT: + return HTML; + case JSP_CONTEXT: + return JSP; + + case COMPLETION_CONTEXT: + return COMPLETION; + + case OTHER_CONTEXT: + return OTHER; + + default: + throw new IllegalArgumentException(); + } + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java new file mode 100644 index 00000000000..2d23ef3b3e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java @@ -0,0 +1,114 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.lexer.CompositeLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.MergingLexerAdapter; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.util.LexerHighlighter; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileHighlighterBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +public class TemplateEditorUtil { + public static Editor createEditor(boolean isReadOnly) { + EditorFactory editorFactory = EditorFactory.getInstance(); + Document doc = editorFactory.createDocument(""); + Editor editor = (isReadOnly ? editorFactory.createViewer(doc) : editorFactory.createEditor(doc)); + + EditorSettings editorSettings = editor.getSettings(); + editorSettings.setVirtualSpace(false); + editorSettings.setLineMarkerAreaShown(false); + editorSettings.setLineNumbersShown(false); + editorSettings.setFoldingOutlineShown(false); + + EditorColorsScheme scheme = editor.getColorsScheme(); + scheme.setColor(EditorColors.CARET_ROW_COLOR, null); + + return editor; + } + + public static void setHighlighter(Editor editor, TemplateContext templateContext) { + int count1 = + (templateContext.JAVA_CODE || templateContext.COMPLETION ? 1 : 0) + + (templateContext.JAVA_COMMENT ? 1 : 0) + + (templateContext.JAVA_STRING ? 1 : 0) + + (templateContext.OTHER ? 1 : 0); + int count2 = + (templateContext.HTML ? 1 : 0) + + (templateContext.XML ? 1 : 0) + + (templateContext.JSP ? 1 : 0); + int count = count1 + count2; + + FileType fileType; + if ((templateContext.JAVA_CODE || templateContext.COMPLETION) && count == 1) { + fileType = StdFileTypes.JAVA; + } + else if (templateContext.HTML && count1 == 0) { + fileType = StdFileTypes.HTML; + } + else if (templateContext.XML && count1 == 0) { + fileType = StdFileTypes.XML; + } + else if (templateContext.JSP && count1 == 0) { + fileType = StdFileTypes.JSP; + } + else { + fileType = StdFileTypes.PLAIN_TEXT; + } + + FileHighlighter highlighter = createTemplateTextHighlighter(fileType.getHighlighter(null)); + ((EditorEx)editor).setHighlighter(new LexerHighlighter(highlighter, EditorColorsManager.getInstance().getGlobalScheme())); + } + + private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{TemplateTokenType.TEXT}); + + private static FileHighlighter createTemplateTextHighlighter(final FileHighlighter original) { + return new TemplateHighlighter(original); + } + + private static class TemplateHighlighter extends FileHighlighterBase { + private Lexer myLexer; + private FileHighlighter myOriginalHighlighter; + + public TemplateHighlighter(FileHighlighter original) { + myOriginalHighlighter = original; + Lexer originalLexer = original.getHighlightingLexer(); + Lexer templateLexer = new TemplateTextLexer(); + templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE); + + myLexer = new CompositeLexer(originalLexer, templateLexer) { + protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) { + if (type2 == TemplateTokenType.VARIABLE) { + return type2; + } + else { + return type1; + } + } + }; + } + + public Lexer getHighlightingLexer() { + return myLexer; + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (tokenType == TemplateTokenType.VARIABLE) { + return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); + } + + return myOriginalHighlighter.getTokenHighlights(tokenType); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImpl.java new file mode 100644 index 00000000000..7aad0f67294 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImpl.java @@ -0,0 +1,358 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.Template; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.tree.IElementType; + +import java.util.*; + +/** + * + */ +public class TemplateImpl implements Template { + private String myKey; + private String myString = null; + private String myDescription; + private String myGroupName; + private char myShortcutChar = TemplateSettings.DEFAULT_CHAR; + private ArrayList myVariables = new ArrayList(); + private ArrayList mySegments = null; + private String myTemplateText = null; + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TemplateImpl)) return false; + + final TemplateImpl template = (TemplateImpl) o; + + if (isToReformat != template.isToReformat) return false; + if (isToShortenLongNames != template.isToShortenLongNames) return false; + if (myShortcutChar != template.myShortcutChar) return false; + if (myDescription != null ? !myDescription.equals(template.myDescription) : template.myDescription != null) return false; + if (myGroupName != null ? !myGroupName.equals(template.myGroupName) : template.myGroupName != null) return false; + if (myKey != null ? !myKey.equals(template.myKey) : template.myKey != null) return false; + if (myString != null ? !myString.equals(template.myString) : template.myString != null) return false; + if (myTemplateText != null ? !myTemplateText.equals(template.myTemplateText) : template.myTemplateText != null) return false; + + if (myVariables == null && template.myVariables == null) return true; + if (myVariables == null || template.myVariables == null) return false; + if (myVariables.size() != template.myVariables.size()) return false; + for (Iterator it = myVariables.iterator(); it.hasNext();) { + Variable variable = it.next(); + if (template.myVariables.indexOf(variable) < 0) return false; + } + + return true; + } + + public int hashCode() { + int result; + result = myKey.hashCode(); + result = 29 * result + myString.hashCode(); + result = 29 * result + myGroupName.hashCode(); + return result; + } + + private boolean isToReformat = false; + private boolean isToShortenLongNames = true; + private boolean toParseSegments = true; + private TemplateContext myTemplateContext = new TemplateContext(); + + public static final String END = "END"; + public static final String SELECTION = "SELECTION"; + public static final String SELECTION_START = "SELECTION_START"; + public static final String SELECTION_END = "SELECTION_END"; + public static final Set INTERNAL_VARS_SET = new HashSet(Arrays.asList( + new String[] {END, SELECTION, SELECTION_START, SELECTION_END} + )); + + private boolean isDeactivated = false; + + public boolean isInline() { + return myIsInline; + } + + private boolean isToIndent = true; + + + public void setInline(boolean isInline) { + myIsInline = isInline; + } + + private boolean myIsInline = false; + + + + public TemplateImpl(String key, String group) { + toParseSegments = false; + myKey = key; + myGroupName = group; + myTemplateText = ""; + mySegments = new ArrayList(); + } + + public void addTextSegment(String text) { + text = StringUtil.convertLineSeparators(text, "\n"); + myTemplateText = myTemplateText + text; + } + + public void addVariableSegment (String name) { + mySegments.add(new Segment(name, myTemplateText.length())); + } + + public void addVariable(String name, Expression expression, Expression defaultValueExpression, boolean isAlwaysStopAt) { + Segment segment = new Segment(name, myTemplateText.length()); + mySegments.add(segment); + Variable variable = new Variable(name, expression, defaultValueExpression, isAlwaysStopAt); + myVariables.add(variable); + } + + public void addEndVariable() { + Segment segment = new Segment(END, myTemplateText.length()); + mySegments.add(segment); + } + + public void addSelectionStartVariable() { + Segment segment = new Segment(SELECTION_START, myTemplateText.length()); + mySegments.add(segment); + } + + public void addSelectionEndVariable() { + Segment segment = new Segment(SELECTION_END, myTemplateText.length()); + mySegments.add(segment); + } + + public TemplateImpl(String key, String string, String group) { + myKey = key; + myString = string; + myGroupName = group; + } + + public TemplateImpl copy() { + TemplateImpl template = new TemplateImpl(myKey, myString, myGroupName); + template.myDescription = myDescription; + template.myShortcutChar = myShortcutChar; + template.isToReformat = isToReformat; + template.isToShortenLongNames = isToShortenLongNames; + template.myIsInline = myIsInline; + template.myTemplateContext = (TemplateContext)myTemplateContext.clone(); + template.isDeactivated = isDeactivated; + for(int i = 0; i < myVariables.size(); i++){ + Variable variable = myVariables.get(i); + template.addVariable(variable.getName(), variable.getExpressionString(), variable.getDefaultValueString(), variable.isAlwaysStopAt()); + } + return template; + } + + public boolean isToReformat() { + return isToReformat; + } + + public void setToReformat(boolean toReformat) { + isToReformat = toReformat; + } + + public void setToIndent(boolean toIndent) { + isToIndent = toIndent; + } + + public boolean isToIndent() { + return isToIndent; + } + + public boolean isToShortenLongNames() { + return isToShortenLongNames; + } + + public void setToShortenLongNames(boolean toShortenLongNames) { + isToShortenLongNames = toShortenLongNames; + } + + public void setDeactivated(boolean isDeactivated) { + this.isDeactivated = isDeactivated; + } + + public boolean isDeactivated() { + return isDeactivated; + } + + public TemplateContext getTemplateContext() { + return myTemplateContext; + } + + public int getEndSegmentNumber() { + return getVariableSegmentNumber(END); + } + + public int getSelectionStartSegmentNumber() { + return getVariableSegmentNumber(SELECTION_START); + } + + public int getSelectionEndSegmentNumber() { + return getVariableSegmentNumber(SELECTION_END); + } + + public int getVariableSegmentNumber(String variableName) { + parseSegments(); + for (int i = 0; i < mySegments.size(); i++) { + Segment segment = mySegments.get(i); + if (segment.name.equals(variableName)) { + return i; + } + } + return -1; + } + + public String getTemplateText() { + parseSegments(); + return myTemplateText; + } + + public String getSegmentName(int i) { + parseSegments(); + return mySegments.get(i).name; + } + + public int getSegmentOffset(int i) { + parseSegments(); + return mySegments.get(i).offset; + } + + public int getSegmentsCount() { + parseSegments(); + return mySegments.size(); + } + + public void parseSegments() { + if(!toParseSegments) { + return; + } + if(mySegments != null) { + return; + } + myString = StringUtil.convertLineSeparators(myString, "\n"); + mySegments = new ArrayList(); + StringBuffer buffer = new StringBuffer(""); + TemplateTextLexer lexer = new TemplateTextLexer(); + lexer.start(myString.toCharArray()); + while(true){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + int start = lexer.getTokenStart(); + int end = lexer.getTokenEnd(); + String token = myString.substring(start, end); + if (tokenType == TemplateTokenType.VARIABLE){ + String name = token.substring(1, token.length() - 1); + Segment segment = new Segment(name, buffer.length()); + mySegments.add(segment); + } + else if (tokenType == TemplateTokenType.ESCAPE_DOLLAR){ + buffer.append("$"); + } + else{ + buffer.append(token); + } + lexer.advance(); + } + myTemplateText = buffer.toString(); + } + + public void removeAllParsed() { + myVariables.clear(); + mySegments = null; + } + + public void addVariable(String name, String expression, String defaultValue, boolean isAlwaysStopAt) { + Variable variable = new Variable(name, expression, defaultValue, isAlwaysStopAt); + myVariables.add(variable); + } + + public int getVariableCount() { + return myVariables.size(); + } + + public String getVariableNameAt(int i) { + return myVariables.get(i).getName(); + } + + public String getExpressionStringAt(int i) { + return myVariables.get(i).getExpressionString(); + } + + public Expression getExpressionAt(int i) { + return myVariables.get(i).getExpression(); + } + + public String getDefaultValueStringAt(int i) { + return myVariables.get(i).getDefaultValueString(); + } + + public Expression getDefaultValueAt(int i) { + return myVariables.get(i).getDefaultValueExpression(); + } + + public boolean isAlwaysStopAt(int i) { + return myVariables.get(i).isAlwaysStopAt(); + } + + public String getKey() { + return myKey; + } + + public void setKey(String key) { + myKey = key; + } + + public String getString() { + parseSegments(); + return myString; + } + + public void setString(String string) { + myString = string; + } + + public String getDescription() { + return myDescription; + } + + public void setDescription(String description) { + myDescription = description; + } + + public char getShortcutChar() { + return myShortcutChar; + } + + public void setShortcutChar(char shortcutChar) { + myShortcutChar = shortcutChar; + } + + public String getGroupName() { + return myGroupName; + } + + public void setGroupName(String groupName) { + myGroupName = groupName; + } + + public boolean isSelectionTemplate() { + for (Iterator iterator = myVariables.iterator(); iterator.hasNext();) { + Variable v = iterator.next(); + if (v.getName().equals(SELECTION)) return true; + } + + return false; + } + + private static class Segment { + public String name; + public int offset; + + public Segment(String name, int offset) { + this.name = name; + this.offset = offset; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImplUtil.java new file mode 100644 index 00000000000..ef7d17a2a07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateImplUtil.java @@ -0,0 +1,75 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.text.CharArrayUtil; + +import java.util.ArrayList; +import java.util.Set; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Mar 19, 2004 + * Time: 1:28:54 PM + * To change this template use File | Settings | File Templates. + */ +public class TemplateImplUtil { + public static boolean validateTemplateText(String s) { + TemplateTextLexer lexer = new TemplateTextLexer(); + lexer.start(s.toCharArray()); + int end = -1; + while(true){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + int start = lexer.getTokenStart(); + if (tokenType == TemplateTokenType.VARIABLE){ + if (start == end) return false; + end = lexer.getTokenEnd(); + } else { + end = -1; + } + lexer.advance(); + } + return true; + } + + public static void parseVariables(CharSequence text, ArrayList variables, Set predefinedVars) { + TemplateTextLexer lexer = new TemplateTextLexer(); + char[] chars = CharArrayUtil.fromSequence(text); + lexer.start(chars, 0, text.length()); + while(true){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + int start = lexer.getTokenStart(); + int end = lexer.getTokenEnd(); + String token = text.subSequence(start, end).toString(); + if (tokenType == TemplateTokenType.VARIABLE){ + String name = token.substring(1, token.length() - 1); + boolean isFound = false; + + if (predefinedVars!=null && predefinedVars.contains(name) && !name.equals(TemplateImpl.SELECTION)){ + isFound = true; + } + else{ + for(int i = 0; i < variables.size(); i++){ + Variable variable = (Variable)variables.get(i); + if (variable.getName().equals(name)){ + isFound = true; + break; + } + } + } + + if (!isFound){ + variables.add(new Variable(name, "", "", true)); + } + } + lexer.advance(); + } + } + + public static Expression parseTemplate(String text) { + return MacroParser.parse(text); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateListPanel.java new file mode 100644 index 00000000000..b19f2ad58cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -0,0 +1,719 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.*; +import com.intellij.ui.dualView.TreeTableView; +import com.intellij.util.ui.treetable.TreeTable; +import com.intellij.util.ui.treetable.TreeTableModel; +import com.intellij.util.ui.treetable.TreeTable; +import com.intellij.util.ui.treetable.ListTreeTableModelOnColumns; +import com.intellij.util.Alarm; +import com.intellij.util.ui.ColumnInfo; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.table.AbstractTableModel; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; + +/** + * + */ +class TemplateListPanel extends JPanel { + + private TreeTable myTreeTable; + private JButton myAddButton; + private JButton myCopyButton; + private JButton myEditButton; + private JButton myRemoveButton; + private Editor myEditor; + private SortedMap myTemplates = new TreeMap(); + private JComboBox myExpandByCombo; + private boolean isModified = false; + private static final String SPACE = "Space"; + private static final String TAB = "Tab"; + private static final String ENTER = "Enter"; + private static final String[] myColumnNames = {"Abbreviation", "Description", "Active"}; + private DefaultMutableTreeNode myTreeRoot = new DefaultMutableTreeNode(); + private DefaultTreeModel myTreeTableModel; + + private Alarm myAlarm = new Alarm(); + private boolean myUpdateNeeded = false; + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.impl.TemplateListPanel"); + private static final Icon TEMPLATE_ICON = IconLoader.getIcon("/general/template.png"); + private static final Icon TEMPLATE_GROUP_ICON = IconLoader.getIcon("/general/templateGroup.png"); + + public TemplateListPanel() { + setLayout(new BorderLayout()); + fillPanel(this); + } + + public void dispose() { + EditorFactory.getInstance().releaseEditor(myEditor); + } + + public void reset() { + TemplateSettings templateSettings = TemplateSettings.getInstance(); + initTemplates(templateSettings.getTemplates(), templateSettings.getLastSelectedTemplateKey()); + + if (templateSettings.getDefaultShortcutChar() == TemplateSettings.TAB_CHAR) { + myExpandByCombo.setSelectedItem(TAB); + } + else if (templateSettings.getDefaultShortcutChar() == TemplateSettings.ENTER_CHAR) { + myExpandByCombo.setSelectedItem(ENTER); + } + else { + myExpandByCombo.setSelectedItem(SPACE); + } + isModified = false; + myUpdateNeeded = true; + } + + public void apply() { + TemplateSettings templateSettings = TemplateSettings.getInstance(); + templateSettings.setTemplates(getTemplates()); + templateSettings.setDefaultShortcutChar(getDefaultShortcutChar()); + } + + public boolean isModified() { + TemplateSettings templateSettings = TemplateSettings.getInstance(); + if (templateSettings.getDefaultShortcutChar() != getDefaultShortcutChar()) { + return true; + } + return isModified; + } + + private char getDefaultShortcutChar() { + Object selectedItem = myExpandByCombo.getSelectedItem(); + if (TAB.equals(selectedItem)) { + return TemplateSettings.TAB_CHAR; + } + else if (ENTER.equals(selectedItem)) { + return TemplateSettings.ENTER_CHAR; + } + else { + return TemplateSettings.SPACE_CHAR; + } + } + + private TemplateImpl[] getTemplates() { + TemplateImpl[] newTemplates = new TemplateImpl[myTemplates.size()]; + Iterator iterator = myTemplates.keySet().iterator(); + int i = 0; + while (iterator.hasNext()) { + newTemplates[i] = (TemplateImpl)myTemplates.get(iterator.next()); + i++; + } + return newTemplates; + } + + private void fillPanel(JPanel optionsPanel) { + JPanel tablePanel = new JPanel(); + tablePanel.setBorder(BorderFactory.createLineBorder(Color.gray)); + tablePanel.setLayout(new BorderLayout()); + tablePanel.add(createTable(), BorderLayout.CENTER); + + JPanel tableButtonsPanel = new JPanel(); + tableButtonsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + tableButtonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(0, 0, 4, 0); + + myAddButton = new JButton("Add..."); + myAddButton.setMnemonic('A'); + myAddButton.setMargin(new Insets(2, 4, 2, 4)); + tableButtonsPanel.add(myAddButton, gbConstraints); + myCopyButton = new JButton("Copy..."); + myCopyButton.setEnabled(false); + myCopyButton.setMnemonic('C'); + myCopyButton.setMargin(new Insets(2, 4, 2, 4)); + tableButtonsPanel.add(myCopyButton, gbConstraints); + myEditButton = new JButton("Edit..."); + myEditButton.setEnabled(false); + myEditButton.setMnemonic('E'); + myEditButton.setMargin(new Insets(2, 4, 2, 4)); + tableButtonsPanel.add(myEditButton, gbConstraints); + myRemoveButton = new JButton("Remove"); + myRemoveButton.setEnabled(false); + myRemoveButton.setMnemonic('R'); + myRemoveButton.setMargin(new Insets(2, 4, 2, 4)); + tableButtonsPanel.add(myRemoveButton, gbConstraints); + + gbConstraints.weighty = 1; + tableButtonsPanel.add(new JPanel(), gbConstraints); + + tablePanel.add(tableButtonsPanel, BorderLayout.EAST); + optionsPanel.add(tablePanel, BorderLayout.CENTER); + + JPanel textPanel = new JPanel(new BorderLayout()); + textPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + myEditor = TemplateEditorUtil.createEditor(true); + textPanel.add(myEditor.getComponent(), BorderLayout.CENTER); + textPanel.add(createExpandByPanel(), BorderLayout.SOUTH); + textPanel.setPreferredSize(new Dimension(100, myEditor.getLineHeight() * 12)); + + optionsPanel.add(textPanel, BorderLayout.SOUTH); + + myAddButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + addRow(); + } + } + ); + + myCopyButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + copyRow(); + } + } + ); + + myEditButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + edit(); + } + } + ); + + myRemoveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + removeRow(); + } + } + ); + } + + private JPanel createExpandByPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.weighty = 0; + gbConstraints.insets = new Insets(4, 0, 0, 0); + gbConstraints.weightx = 0; + gbConstraints.gridy = 0; +// panel.add(createLabel("By default expand with "), gbConstraints); + panel.add(new JLabel("By default expand with "), gbConstraints); + + gbConstraints.gridx = 1; + myExpandByCombo = new JComboBox(); + myExpandByCombo.addItem(SPACE); + myExpandByCombo.addItem(TAB); + myExpandByCombo.addItem(ENTER); + panel.add(myExpandByCombo, gbConstraints); + + gbConstraints.gridx = 2; + gbConstraints.weightx = 1; + panel.add(new JPanel(), gbConstraints); + + return panel; + } + + private TemplateKey getTemplateKey(int row) { + JTree tree = myTreeTable.getTree(); + TreePath path = tree.getPathForRow(row); + if (path != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (node.getUserObject() instanceof TemplateImpl) { + return new TemplateKey((TemplateImpl)node.getUserObject()); + } + } + + return null; + } + + private void edit() { + int selected = myTreeTable.getSelectedRow(); + if (selected < 0) return; + + TemplateKey templateKey = getTemplateKey(selected); + if (templateKey == null) return; + + TemplateImpl template = (TemplateImpl)myTemplates.get(templateKey); + EditTemplateDialog dialog = new EditTemplateDialog(this, "Edit Live Template", template, getTemplates(), + (String)myExpandByCombo.getSelectedItem()); + dialog.show(); + if (!dialog.isOK()) return; + + myTemplates.remove(new TemplateKey(template)); + dialog.apply(); + myTemplates.put(new TemplateKey(template), template); + + AbstractTableModel model = (AbstractTableModel)myTreeTable.getModel(); + + model.fireTableRowsUpdated(selected, selected); + myTreeTable.setRowSelectionInterval(selected, selected); + + updateTemplateTextArea(); + isModified = true; + } + + private void addRow() { + TemplateImpl template = new TemplateImpl("", "", TemplateSettings.USER_GROUP_NAME); + EditTemplateDialog dialog = new EditTemplateDialog(this, "Edit Live Template", template, getTemplates(), + (String)myExpandByCombo.getSelectedItem()); + dialog.show(); + if (!dialog.isOK()) return; + dialog.apply(); + + addTemplate(template); + isModified = true; + } + + private void copyRow() { + int selected = myTreeTable.getSelectedRow(); + if (selected < 0) return; + + TemplateKey templateKey = getTemplateKey(selected); + LOG.assertTrue(templateKey != null); + TemplateImpl template = ((TemplateImpl)myTemplates.get(templateKey)).copy(); + EditTemplateDialog dialog = new EditTemplateDialog(this, "Copy Live Template", template, getTemplates(), + (String)myExpandByCombo.getSelectedItem()); + dialog.show(); + if (!dialog.isOK()) return; + + dialog.apply(); + addTemplate(template); + isModified = true; + } + + private void removeRow() { + int selected = myTreeTable.getSelectedRow(); + if (selected < 0) return; + int result = Messages.showOkCancelDialog(this, "Do you want to delete this template?", "Confirm Delete", + Messages.getQuestionIcon()); + if (result != DialogWrapper.OK_EXIT_CODE) return; + + removeTemplateAt(selected); + /*AbstractTableModel model = (AbstractTableModel)myTreeTable.getModel(); + model.fireTableRowsDeleted(selected, selected); + if (selected >= myTreeTable.getRowCount()) { + selected = myTreeTable.getRowCount() - 1; + } + if (selected >= 0) { + myTreeTable.setRowSelectionInterval(selected, selected); + }*/ + isModified = true; + } + + private JScrollPane createTable() { + ColumnInfo[] columnInfos = {new MyColumnInfo(myColumnNames[0]) { + public Class getColumnClass() { + return TreeTableModel.class; + } + + public boolean isCellEditable(Object o) { + return true; + } + }, new MyColumnInfo(myColumnNames[1]), new ActivationStateColumnInfo(myColumnNames[2])}; + + myTreeRoot = new DefaultMutableTreeNode(); + + myTreeTableModel = new ListTreeTableModelOnColumns(myTreeRoot, columnInfos); + myTreeTable = new MyTable((ListTreeTableModelOnColumns)myTreeTableModel); + myTreeTable.setRootVisible(false); + myTreeTable.setDefaultRenderer(Boolean.class, new BooleanTableCellRenderer()); + myTreeTable.getTree().setShowsRootHandles(true); + myTreeTable.getTableHeader().setReorderingAllowed(false); + + myTreeTable.setTreeCellRenderer(new ColoredTreeCellRenderer () { + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + value = ((DefaultMutableTreeNode)value).getUserObject(); + + setPaintFocusBorder(false); + if (value instanceof TemplateImpl) { + setIcon(TEMPLATE_ICON); + append (((TemplateImpl)value).getKey(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + else if (value instanceof String) { + setIcon(TEMPLATE_GROUP_ICON); + append ((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + } + }); + + myTreeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTreeTable.setPreferredScrollableViewportSize(new Dimension(300, myTreeTable.getRowHeight() * 10)); + myTreeTable.getColumn(myColumnNames[0]).setPreferredWidth(80); + myTreeTable.getColumn(myColumnNames[1]).setPreferredWidth(260); + myTreeTable.getColumn(myColumnNames[2]).setPreferredWidth(12); + + myTreeTable.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + addRow(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), + JComponent.WHEN_FOCUSED + ); + + myTreeTable.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + removeRow(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_FOCUSED + ); + + myTreeTable.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2 && myTreeTable.columnAtPoint(e.getPoint()) != 2) { + edit(); + } + } + } + ); + + JScrollPane scrollpane = ScrollPaneFactory.createScrollPane(myTreeTable); + if (myTemplates.size() > 0) { + myTreeTable.setRowSelectionInterval(0, 0); + } + scrollpane.setPreferredSize(new Dimension(600, 400)); + return scrollpane; + } + + private void updateTemplateTextArea() { + if (!myUpdateNeeded) return; + + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + int selected = myTreeTable.getSelectedRow(); + if (selected < 0 || selected >= myTemplates.size()) { + myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), ""); + } + else { + TemplateKey templateKey = getTemplateKey(selected); + if (templateKey != null) { + TemplateImpl template = (TemplateImpl)myTemplates.get(templateKey); + String text = template.getString(); + myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), text); + TemplateEditorUtil.setHighlighter(myEditor, template.getTemplateContext()); + } else { + myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), ""); + } + } + } + }); + } + }, 100); + } + + private void addTemplate(TemplateImpl template) { + myTemplates.put(new TemplateKey(template), template); + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(template); + if (myTreeRoot.getChildCount() > 0) { + for (DefaultMutableTreeNode child = (DefaultMutableTreeNode)myTreeRoot.getFirstChild(); + child != null; + child = (DefaultMutableTreeNode)myTreeRoot.getChildAfter(child)) { + String group = (String)child.getUserObject(); + if (group.equals(template.getGroupName())) { + int index = getIndexToInsert (child, template.getKey()); + child.insert(node, index); + myTreeTableModel.nodesWereInserted(child, new int[]{index}); + setSelectedNode(node); + return; + } + } + } + int index = getIndexToInsert(myTreeRoot, template.getGroupName()); + DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(template.getGroupName()); + myTreeRoot.insert(groupNode, index); + myTreeTableModel.nodesWereInserted(myTreeRoot, new int[]{index}); + + groupNode.add(node); + myTreeTableModel.nodesWereInserted(groupNode, new int[]{0}); + + setSelectedNode(node); + } + + private int getIndexToInsert(DefaultMutableTreeNode parent, String key) { + if (parent.getChildCount() == 0) return 0; + + int res = 0; + for (DefaultMutableTreeNode child = (DefaultMutableTreeNode)parent.getFirstChild(); + child != null; + child = (DefaultMutableTreeNode)parent.getChildAfter(child)) { + Object o = child.getUserObject(); + String key1 = o instanceof TemplateImpl ? ((TemplateImpl)o).getKey() : (String)o; + if (key1.compareTo(key) > 0) return res; + res++; + } + return res; + } + + private void setSelectedNode(DefaultMutableTreeNode node) { + JTree tree = myTreeTable.getTree(); + TreePath path = new TreePath(node.getPath()); + tree.expandPath(path.getParentPath()); + int row = tree.getRowForPath(path); + myTreeTable.getSelectionModel().setSelectionInterval(row, row); + myTreeTable.scrollRectToVisible(myTreeTable.getCellRect(row, 0, true)); + } + + private void removeTemplateAt(int row) { + JTree tree = myTreeTable.getTree(); + TreePath path = tree.getPathForRow(row); + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + LOG.assertTrue(node.getUserObject() instanceof TemplateImpl); + + TemplateImpl template = (TemplateImpl)node.getUserObject(); + myTemplates.remove(new TemplateKey(template)); + + DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent(); + TreePath treePathToSelect = (parent.getChildAfter(node) != null || parent.getChildCount() == 1 ? + tree.getPathForRow(row + 1) : + tree.getPathForRow(row - 1)); + DefaultMutableTreeNode toSelect = treePathToSelect != null ? (DefaultMutableTreeNode)treePathToSelect.getLastPathComponent() : null; + + removeNodeFromParent(node); + if (parent.getChildCount() == 0) removeNodeFromParent(parent); + if (toSelect != null) { + setSelectedNode(toSelect); + } + } + + private void removeNodeFromParent(DefaultMutableTreeNode node) { + TreeNode parent = node.getParent(); + int idx = myTreeTableModel.getIndexOfChild(parent, node); + node.removeFromParent(); + myTreeTableModel.nodesWereRemoved(parent, new int[]{idx}, new TreeNode[]{node}); + } + + private void initTemplates(TemplateImpl[] templates, String lastSelectedKey) { + myTreeRoot.removeAllChildren(); + SortedMap> groups = new TreeMap>(); + for (int i = 0; i < templates.length; i++) { + TemplateImpl template = templates[i].copy(); + myTemplates.put(new TemplateKey(template), template); + String group = template.getGroupName(); + List ts = groups.get(group); + if (ts == null) { + ts = new ArrayList(); + groups.put(group, ts); + } + ts.add(template); + } + + DefaultMutableTreeNode nodeToSelect = null; + for (Iterator>> iterator1 = groups.entrySet().iterator(); + iterator1.hasNext();) { + Map.Entry entry = iterator1.next(); + String group = (String)entry.getKey(); + List groupTemplates = (List)entry.getValue(); + DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(group); + for (Iterator iterator2 = groupTemplates.iterator(); iterator2.hasNext();) { + TemplateImpl template = (TemplateImpl)iterator2.next(); + DefaultMutableTreeNode node = new DefaultMutableTreeNode(template); + groupNode.add(node); + + if (lastSelectedKey != null && lastSelectedKey.equals(template.getKey())) { + nodeToSelect = node; + } + } + myTreeRoot.add(groupNode); + } + + myTreeTableModel.nodeStructureChanged(myTreeRoot); + + if (nodeToSelect != null) { + JTree tree = myTreeTable.getTree(); + TreePath path = new TreePath(nodeToSelect.getPath()); + tree.expandPath(path.getParentPath()); + int rowToSelect = tree.getRowForPath(path); + myTreeTable.getSelectionModel().setSelectionInterval(rowToSelect, rowToSelect); + final Rectangle rect = myTreeTable.getCellRect(rowToSelect, 0, true); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myTreeTable.scrollRectToVisible(rect); + } + }); + } + } + + private class MyTable extends TreeTableView { + + public MyTable(ListTreeTableModelOnColumns model) { + super(model); + } + + public void valueChanged(ListSelectionEvent event) { + super.valueChanged(event); + + boolean enableButtons = false; + int selected = getSelectedRow(); + if (selected >= 0 && selected < myTreeTable.getRowCount()) { + TemplateSettings templateSettings = TemplateSettings.getInstance(); + TemplateKey templateKey = getTemplateKey(selected); + if (templateKey != null) { + TemplateImpl template = (TemplateImpl)myTemplates.get(templateKey); + if (template != null) { + templateSettings.setLastSelectedTemplateKey(template.getKey()); + } + } else { + templateSettings.setLastSelectedTemplateKey(null); + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTreeTable.getTree().getPathForRow(selected).getLastPathComponent(); + enableButtons = !(node.getUserObject() instanceof String); + } + updateTemplateTextArea(); + if (myCopyButton != null) { + myCopyButton.setEnabled(enableButtons); + myEditButton.setEnabled(enableButtons); + myRemoveButton.setEnabled(enableButtons); + } + } + } + + + private static class TemplateKey implements Comparable { + private String myKey; + private String myGroupName; + + public TemplateKey(TemplateImpl template) { + myKey = template.getKey(); + if (myKey == null) { + myKey = ""; + } + myGroupName = template.getGroupName(); + if (myGroupName == null) { + myGroupName = ""; + } + } + + public boolean equals(Object obj) { + if (!(obj instanceof TemplateKey)) { + return false; + } + TemplateKey templateKey = (TemplateKey)obj; + return (myGroupName.compareTo(templateKey.myGroupName) == 0) && + (myKey.compareTo(templateKey.myKey) == 0); + } + + public int compareTo(Object obj) { + if (!(obj instanceof TemplateKey)) { + return 1; + } + TemplateKey templateKey = (TemplateKey)obj; + int result = myGroupName.compareTo(templateKey.myGroupName); + return result != 0 ? result : myKey.compareTo(templateKey.myKey); + } + } + + class ActivationStateColumnInfo extends ColumnInfo { + public ActivationStateColumnInfo(String name) { + super(name); + } + + public boolean isCellEditable(Object o) { + return o != null; + } + + public void setValue(Object obj, Object aValue) { + obj = ((DefaultMutableTreeNode)obj).getUserObject(); + if (obj instanceof TemplateImpl) { + TemplateImpl template = (TemplateImpl)obj; + boolean state = !((Boolean)aValue).booleanValue(); + if (state != template.isDeactivated()) { + template.setDeactivated(!((Boolean)aValue).booleanValue()); + isModified = true; + } + } + } + + public Class getColumnClass() { + return Boolean.class; + } + + public Object valueOf(Object object) { + object = ((DefaultMutableTreeNode)object).getUserObject(); + if (object instanceof TemplateImpl) { + return ((TemplateImpl)object).isDeactivated() ? Boolean.FALSE : Boolean.TRUE; + } + else { + return null; + } + } + + } + + class MyColumnInfo extends ColumnInfo { + public MyColumnInfo(String name) {super(name);} + + public Object valueOf(Object object) { + object = ((DefaultMutableTreeNode)object).getUserObject(); + if (object instanceof TemplateImpl) { + TemplateImpl template = (TemplateImpl)object; + if (getName().equals(myColumnNames[0])) { + return template.getKey(); + } + else if (getName().equals(myColumnNames[1])) { + return template.getDescription(); + } + } + else if (object instanceof String) { + if (getName().equals(myColumnNames[0])) { + return object; + } + else { + return null; + } + } + LOG.assertTrue(false); + return null; + } + + public Comparator getComparator() { + if (myColumnNames[0].equals(getName())) { + return new Comparator() { + public int compare(Object o, Object o1) { + o = ((DefaultMutableTreeNode)o).getUserObject(); + o1 = ((DefaultMutableTreeNode)o1).getUserObject(); + if (o instanceof TemplateImpl && o1 instanceof TemplateImpl) { + return ((TemplateImpl)o).getKey().compareTo(((TemplateImpl)o1).getKey()); + } + else if (o instanceof String && o1 instanceof String) { + return ((String)o).compareTo(((String)o1)); + } + return 0; + } + }; + } + + return null; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java new file mode 100644 index 00000000000..e279e96053b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java @@ -0,0 +1,274 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.codeInsight.template.TemplateStateListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.event.EditorFactoryAdapter; +import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.editor.event.EditorFactoryListener; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspDeclaration; +import com.intellij.psi.jsp.JspExpression; +import com.intellij.psi.jsp.JspUtil; + +public class TemplateManagerImpl extends TemplateManager implements ProjectComponent { + protected Project myProject; + private EditorFactoryListener myEditorFactoryListener; + + private static final Key TEMPLATE_STATE_KEY = Key.create("TEMPLATE_STATE_KEY"); + + public TemplateManagerImpl(Project project) { + myProject = project; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + EditorFactory.getInstance().removeEditorFactoryListener(myEditorFactoryListener); + } + + public void projectOpened() { + myEditorFactoryListener = new EditorFactoryAdapter() { + public void editorReleased(EditorFactoryEvent event) { + Editor removedEditor = event.getEditor(); + TemplateState tState = getTemplateState(removedEditor); + if (tState != null) { + tState.dispose(); + } + removedEditor.putUserData(TEMPLATE_STATE_KEY, null); + } + }; + EditorFactory.getInstance().addEditorFactoryListener(myEditorFactoryListener); + } + + public Template createTemplate(String key, String group) { + return new TemplateImpl(key, group); + } + + public Template createTemplate(String key, String group, String text) { + return new TemplateImpl(key, text, group); + } + + public static TemplateState getTemplateState(Editor editor) { + return (TemplateState) editor.getUserData(TEMPLATE_STATE_KEY); + } + + private TemplateState initTemplateState(final Editor editor) { + TemplateState prevState = getTemplateState(editor); + if (prevState != null) { + prevState.dispose(); + } + TemplateState state = new TemplateState(myProject, editor); + editor.putUserData(TEMPLATE_STATE_KEY, state); + return state; + } + + public boolean startTemplate(Editor editor, char shortcutChar) { + return startTemplate(this, editor, shortcutChar); + } + + public void startTemplate(final Editor editor, Template template) { + startTemplate(editor, template, null); + } + + public void startTemplate(Editor editor, String selectionString, Template template) { + startTemplate(editor, selectionString, template, null); + } + + private void startTemplate(final Editor editor, final String selectionString, final Template template, TemplateStateListener listener) { + final TemplateState templateState = initTemplateState(editor); + + templateState.getProperties().put(ExpressionContext.SELECTION, selectionString); + + if (listener != null) { + templateState.addTemplateStateListener(listener); + } + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + if (selectionString != null) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + EditorModificationUtil.deleteSelectedText(editor); + } + }); + } else { + editor.getSelectionModel().removeSelection(); + } + templateState.start((TemplateImpl) template); + } + }, + "Insert Code Template", null + ); + + if (ApplicationManager.getApplication().isUnitTestMode()) { + if (!templateState.isFinished()) templateState.gotoEnd(); + } + } + + public void startTemplate(final Editor editor, final Template template, TemplateStateListener listener) { + startTemplate(editor, null, template, listener); + } + + public boolean startTemplate(TemplateManagerImpl templateManager, final Editor editor, char shortcutChar) { + final Document document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(templateManager.myProject).getPsiFile(document); + if (file == null) return false; + + TemplateSettings templateSettings = TemplateSettings.getInstance(); + CharSequence text = document.getCharsSequence(); + final int caretOffset = editor.getCaretModel().getOffset(); + TemplateImpl template = null; + int wordStart = 0; + for (int i = 1; i <= templateSettings.getMaxKeyLength(); i++) { + wordStart = caretOffset - i; + if (wordStart < 0) { + break; + } + String key = text.subSequence(wordStart, caretOffset).toString(); + template = templateSettings.getTemplate(key); + if (template != null && template.isDeactivated()) { + template = null; + } + if (template != null) { + if (Character.isJavaIdentifierStart(key.charAt(0))) { + if (wordStart > 0 && Character.isJavaIdentifierPart(text.charAt(wordStart - 1))) { + template = null; + continue; + } + } + break; + } + } + + if (template == null) return false; + + if (shortcutChar != 0 && getShortcutChar(template) != shortcutChar) { + return false; + } + + if (template.isSelectionTemplate()) return false; + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitDocument(document); + } + }, + "", null + ); + if (!templateManager.checkContext(template, file, caretOffset - template.getKey().length())) { + return false; + } + if (!editor.getDocument().isWritable()) { + editor.getDocument().fireReadOnlyModificationAttempt(); + return false; + } + final int wordStart0 = wordStart; + final TemplateImpl template0 = template; + final TemplateState templateState0 = templateManager.initTemplateState(editor); + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + myProject, new Runnable() { + public void run() { + editor.getDocument().deleteString(wordStart0, caretOffset); + editor.getCaretModel().moveToOffset(wordStart0); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + templateState0.start(template0); + } + }, + "Insert Code Template", null + ); + return true; + } + + private static char getShortcutChar(TemplateImpl template) { + char c = template.getShortcutChar(); + if (c == TemplateSettings.DEFAULT_CHAR) { + return TemplateSettings.getInstance().getDefaultShortcutChar(); + } + else { + return c; + } + } + + private boolean checkContext(final TemplateImpl template, final PsiFile file, final int offset) { + int contextType = getContextType(file, offset); + TemplateContext templateContext = template.getTemplateContext(); + return templateContext.isInContext(contextType); + } + + public int getContextType(PsiFile file, int offset) { + VirtualFile vFile = file.getVirtualFile(); + FileType fileType; + if (file instanceof PsiCodeFragment) { + fileType = StdFileTypes.JAVA; + } + else { + fileType = FileTypeManager.getInstance().getFileTypeByFile(vFile); + } + + if (fileType == StdFileTypes.XML) { + return TemplateContext.XML_CONTEXT; + } + if (fileType == StdFileTypes.HTML) { + return TemplateContext.HTML_CONTEXT; + } + if (fileType == StdFileTypes.PLAIN_TEXT) { + return TemplateContext.OTHER_CONTEXT; + } + PsiElement element = file.findElementAt(offset); + if (fileType == StdFileTypes.JSP) { + PsiElement parent = element; + while (parent != null && !(parent instanceof JspExpression) && !(parent instanceof JspDeclaration)) { + parent = parent.getParent(); + } + if (parent == null && JspUtil.getContainingScriptletStart(element) == null) { + return TemplateContext.JSP_CONTEXT; + } + } + if (isInComment(element)) { + return TemplateContext.JAVA_COMMENT_CONTEXT; + } + if (element instanceof PsiJavaToken) { + if (((PsiJavaToken)element).getTokenType() == JavaTokenType.STRING_LITERAL) { + return TemplateContext.JAVA_STRING_CONTEXT; + } + } + return TemplateContext.JAVA_CODE_CONTEXT; + } + + private boolean isInComment(PsiElement element) { + if (element == null) { + return false; + } + if (element instanceof PsiComment) { + return true; + } + return isInComment(element.getParent()); + } + + public String getComponentName() { + return "TemplateManager"; + } + + public Template getActiveTemplate(Editor editor) { + final TemplateState templateState = getTemplateState(editor); + return templateState != null ? templateState.getTemplate() : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSegments.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSegments.java new file mode 100644 index 00000000000..f3f373533b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSegments.java @@ -0,0 +1,64 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.impl.RangeMarkerImpl; + +import java.util.ArrayList; + +public class TemplateSegments { + private ArrayList mySegments = new ArrayList(); + private Editor myEditor; + + public TemplateSegments(Editor editor) { + myEditor = editor; + } + + public int getSegmentStart(int i) { + RangeMarker rangeMarker = mySegments.get(i); + return rangeMarker.getStartOffset(); + } + + public int getSegmentEnd(int i) { + RangeMarker rangeMarker = mySegments.get(i); + return rangeMarker.getEndOffset(); + } + + public boolean isValid(int i) { + return mySegments.get(i).isValid(); + } + + public void removeAll() { + mySegments.clear(); + } + + public void addSegment(int start, int end) { + RangeMarker rangeMarker = (myEditor.getDocument()).createRangeMarker(start, end); + mySegments.add(rangeMarker); + } + + public void setSegmentGreedy (int i, boolean state) { + RangeMarker marker = mySegments.get(i); + marker.setGreedyToLeft(state); + marker.setGreedyToRight(state); + } + + public boolean isInvalid() { + for (int i = 0; i < mySegments.size(); i++) { + RangeMarker marker = mySegments.get(i); + if(!marker.isValid()) { + return true; + } + } + return false; + } + + public void replaceSegmentAt(int index, int start, int end) { + RangeMarker rangeMarker = mySegments.get(index); + ((RangeMarkerImpl)rangeMarker).invalidate(); + Document doc = myEditor.getDocument(); + rangeMarker = doc.createRangeMarker(start, end); + mySegments.set(index, rangeMarker); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSettings.java new file mode 100644 index 00000000000..9cc7d4ad7ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateSettings.java @@ -0,0 +1,457 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Template; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ex.DecodeDefaultsUtil; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.IllegalDataException; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + + +public class TemplateSettings implements JDOMExternalizable, ExportableApplicationComponent { + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.impl.TemplateSettings"); + + public static final String USER_GROUP_NAME = "user"; + private static final String TEMPLATE_SET = "templateSet"; + private static final String GROUP = "group"; + private static final String TEMPLATE = "template"; + + private static final String DELETED_TEMPLATES = "deleted_templates"; + private List myDeletedTemplates = new ArrayList(); + + private static final String[] DEFAULT_TEMPLATES = new String[]{ + "/liveTemplates/html_xml", + "/liveTemplates/iterations", + "/liveTemplates/other", + "/liveTemplates/output", + "/liveTemplates/plain", + "/liveTemplates/surround" + }; + + public static final char SPACE_CHAR = ' '; + public static final char TAB_CHAR = '\t'; + public static final char ENTER_CHAR = '\n'; + public static final char DEFAULT_CHAR = 'D'; + + private static final String SPACE = "SPACE"; + private static final String TAB = "TAB"; + private static final String ENTER = "ENTER"; + + private static final String NAME = "name"; + private static final String VALUE = "value"; + private static final String DESCRIPTION = "description"; + private static final String SHORTCUT = "shortcut"; + + private static final String VARIABLE = "variable"; + private static final String EXPRESSION = "expression"; + private static final String DEFAULT_VALUE = "defaultValue"; + private static final String ALWAYS_STOP_AT = "alwaysStopAt"; + + private static final String CONTEXT = "context"; + private static final String TO_REFORMAT = "toReformat"; + private static final String TO_SHORTEN_FQ_NAMES = "toShortenFQNames"; + + private static final String DEFAULT_SHORTCUT = "defaultShortcut"; + private String DEACTIVATED = "deactivated"; + + private Map myTemplates = new LinkedHashMap(); + private Map myDefaultTemplates = new LinkedHashMap(); + private int myMaxKeyLength = 0; + private char myDefaultShortcutChar = TAB_CHAR; + private String myLastSelectedTemplateKey; + + public TemplateSettings(Application application) { + loadTemplates(application); + } + + public File[] getExportFiles() { + return new File[]{getTemplateDirectory(true),PathManager.getDefaultOptionsFile()}; + } + + public String getPresentableName() { + return "Code templates"; + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public static TemplateSettings getInstance() { + return ApplicationManager.getApplication().getComponent(TemplateSettings.class); + } + + public void readExternal(Element parentNode) throws InvalidDataException { + Element element = parentNode.getChild(DEFAULT_SHORTCUT); + if (element != null) { + String shortcut = element.getAttributeValue(SHORTCUT); + if (TAB.equals(shortcut)) { + myDefaultShortcutChar = TAB_CHAR; + } else if (ENTER.equals(shortcut)) { + myDefaultShortcutChar = ENTER_CHAR; + } else { + myDefaultShortcutChar = SPACE_CHAR; + } + } + + Element deleted = parentNode.getChild(DELETED_TEMPLATES); + if (deleted != null) { + List children = deleted.getChildren(); + for (Iterator it = children.iterator(); it.hasNext();) { + Element child = (Element) it.next(); + myDeletedTemplates.add(child.getAttributeValue(NAME)); + } + } + + loadTemplates(ApplicationManager.getApplication()); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + Element element = new Element(DEFAULT_SHORTCUT); + if (myDefaultShortcutChar == TAB_CHAR) { + element.setAttribute(SHORTCUT, TAB); + } else if (myDefaultShortcutChar == ENTER_CHAR) { + element.setAttribute(SHORTCUT, ENTER); + } else { + element.setAttribute(SHORTCUT, SPACE); + } + parentNode.addContent(element); + + if (myDeletedTemplates.size() > 0) { + Element deleted = new Element(DELETED_TEMPLATES); + for (Iterator it = myDeletedTemplates.iterator(); it.hasNext();) { + Element template = new Element(TEMPLATE); + template.setAttribute(NAME, (String) it.next()); + deleted.addContent(template); + + } + parentNode.addContent(deleted); + } + } + + public String getLastSelectedTemplateKey() { + return myLastSelectedTemplateKey; + } + + public void setLastSelectedTemplateKey(String key) { + myLastSelectedTemplateKey = key; + } + + public TemplateImpl[] getTemplates() { + return (TemplateImpl[]) myTemplates.values().toArray(new TemplateImpl[myTemplates.size()]); + } + + public char getDefaultShortcutChar() { + return myDefaultShortcutChar; + } + + public void setDefaultShortcutChar(char defaultShortcutChar) { + myDefaultShortcutChar = defaultShortcutChar; + } + + public TemplateImpl getTemplate(String key) { + return (TemplateImpl) myTemplates.get(key); + } + + public int getMaxKeyLength() { + return myMaxKeyLength; + } + + public void setTemplates(TemplateImpl[] newTemplates) { + myTemplates.clear(); + myMaxKeyLength = 0; + for (int i = 0; i < newTemplates.length; i++) { + TemplateImpl template = newTemplates[i]; + myTemplates.put(template.getKey(), template); + myMaxKeyLength = Math.max(myMaxKeyLength, template.getKey().length()); + } + + saveTemplates(newTemplates); + } + + public void addTemplate(Template template) { + myTemplates.put(template.getKey(), template); + myMaxKeyLength = Math.max(myMaxKeyLength, template.getKey().length()); + saveTemplates(getTemplates()); + } + + private TemplateImpl addTemplate(String key, String string, String group, String description, String shortcut, boolean isDefault) { + TemplateImpl template = new TemplateImpl(key, string, group); + template.setDescription(description); + if (TAB.equals(shortcut)) { + template.setShortcutChar(TAB_CHAR); + } else if (ENTER.equals(shortcut)) { + template.setShortcutChar(ENTER_CHAR); + } else if (SPACE.equals(shortcut)) { + template.setShortcutChar(SPACE_CHAR); + } else { + template.setShortcutChar(DEFAULT_CHAR); + } + if (isDefault) { + myDefaultTemplates.put(key, template); + if (myTemplates.get(key) != null) return template; + } + myTemplates.put(key, template); + myMaxKeyLength = Math.max(myMaxKeyLength, key.length()); + return template; + } + + private static File getTemplateDirectory(boolean toCreate) { + String directoryPath = PathManager.getConfigPath() + File.separator + "templates"; + File directory = new File(directoryPath); + if (!directory.exists()) { + if (!toCreate) { + return null; + } + if (!directory.mkdir()) { + if (LOG.isDebugEnabled()) { + LOG.debug("cannot create directory: " + directory.getAbsolutePath()); + } + return null; + } + } + return directory; + } + + private static File[] getUserTemplateFiles() { + File directory = getTemplateDirectory(false); + if (directory == null || !directory.exists()) { + directory = getTemplateDirectory(true); + } + return directory.listFiles(); + } + + private void loadTemplates(Application application) { + if (application.isUnitTestMode()) return; //test load speed optimization + File[] files = getUserTemplateFiles(); + if (files == null) { + return; + } + + try { + for (int i = 0; i < files.length; i++) { + String name = files[i].getName(); + if (!name.toLowerCase().endsWith(".xml")) continue; + readTemplateFile(files[i]); + } + + for (int i = 0; i < DEFAULT_TEMPLATES.length; i++) { + String defTemplate = DEFAULT_TEMPLATES[i]; + String templateName = getDefaultTemplateName(defTemplate); + readDefTemplateFile(DecodeDefaultsUtil.getDefaultsInputStream(this, defTemplate), templateName); + } + } catch (Exception e) { + LOG.error(e); + } + } + + private String getDefaultTemplateName(String defTemplate) { + return defTemplate.substring(defTemplate.lastIndexOf("/") + 1); + } + + private void readDefTemplateFile(InputStream inputStream, String defGroupName) throws JDOMException, InvalidDataException, IOException { + readTemplateFile(JDOMUtil.loadDocument(inputStream), defGroupName, true); + } + + private void readTemplateFile(File file) throws JDOMException, InvalidDataException, IOException { + if (!file.exists()) return; + + String defGroupName = file.getName().substring(0, file.getName().lastIndexOf('.')); + readTemplateFile(JDOMUtil.loadDocument(file), defGroupName, false); + } + + private void readTemplateFile(Document document, String defGroupName, boolean isDefault) throws InvalidDataException { + if (document == null) { + throw new InvalidDataException(); + } + Element root = document.getRootElement(); + if (root == null || !TEMPLATE_SET.equals(root.getName())) { + throw new InvalidDataException(); + } + + String groupName = root.getAttributeValue(GROUP); + if (groupName == null || groupName.length() == 0) groupName = defGroupName; + + for (Iterator iterator = root.getChildren(TEMPLATE).iterator(); iterator.hasNext();) { + Element element = (Element) iterator.next(); + + String name = element.getAttributeValue(NAME); + String value = element.getAttributeValue(VALUE); + String description = element.getAttributeValue(DESCRIPTION); + String shortcut = element.getAttributeValue(SHORTCUT); + if (isDefault && myDeletedTemplates.contains(name)) continue; + TemplateImpl template = addTemplate(name, value, groupName, description, shortcut, isDefault); + template.setToReformat("true".equals(element.getAttributeValue(TO_REFORMAT))); + template.setToShortenLongNames("true".equals(element.getAttributeValue(TO_SHORTEN_FQ_NAMES))); + template.setDeactivated("true".equals(element.getAttributeValue(DEACTIVATED))); + + + for (Iterator i = element.getChildren(VARIABLE).iterator(); i.hasNext();) { + Element e = (Element) i.next(); + String variableName = e.getAttributeValue(NAME); + String expression = e.getAttributeValue(EXPRESSION); + String defaultValue = e.getAttributeValue(DEFAULT_VALUE); + boolean isAlwaysStopAt = "true".equals(e.getAttributeValue(ALWAYS_STOP_AT)); + template.addVariable(variableName, expression, defaultValue, isAlwaysStopAt); + } + + Element context = element.getChild(CONTEXT); + if (context != null) { + DefaultJDOMExternalizer.readExternal(template.getTemplateContext(), context); + } + } + } + + private void saveTemplates(final TemplateImpl[] templates) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + List templateNames = new ArrayList(); + for (int i = 0; i < templates.length; i++) { + templateNames.add(templates[i].getKey()); + } + myDeletedTemplates.clear(); + for (Iterator it = myDefaultTemplates.keySet().iterator(); it.hasNext();) { + String defTemplateName = (String) it.next(); + if (!templateNames.contains(defTemplateName)) { + myDeletedTemplates.add(defTemplateName); + } + } + + File[] files = getUserTemplateFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + files[i].delete(); + } + } + + if (templates.length == 0) return; + com.intellij.util.containers.HashMap groupToDocumentMap = new com.intellij.util.containers.HashMap(); + for (int i = 0; i < templates.length; i++) { + TemplateImpl template = templates[i]; + if (template.equals(myDefaultTemplates.get(template.getKey()))) continue; + + String groupName = templates[i].getGroupName(); + Element templateSetElement = (Element) groupToDocumentMap.get(groupName); + if (templateSetElement == null) { + templateSetElement = new Element(TEMPLATE_SET); + templateSetElement.setAttribute(GROUP, groupName); + groupToDocumentMap.put(groupName, templateSetElement); + } + try { + saveTemplate(template, templateSetElement); + } catch (IllegalDataException e) { + } + } + + File dir = getTemplateDirectory(true); + if (dir == null) { + return; + } + + Collection groups = groupToDocumentMap.entrySet(); + for (Iterator it = groups.iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + String groupName = (String) entry.getKey(); + Element templateSetElement = (Element) entry.getValue(); + + String fileName = convertName(groupName); + String filePath = findFirstNotExistingFile(dir, fileName, ".xml"); + try { + JDOMUtil.writeDocument(new Document(templateSetElement), filePath, CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } catch (IOException e) { + LOG.error(e); + } + } + } + }); + } + + private void saveTemplate(TemplateImpl template, Element templateSetElement) { + Element element = new Element(TEMPLATE); + element.setAttribute(NAME, template.getKey()); + element.setAttribute(VALUE, template.getString()); + if (template.getShortcutChar() == TAB_CHAR) { + element.setAttribute(SHORTCUT, TAB); + } else if (template.getShortcutChar() == ENTER_CHAR) { + element.setAttribute(SHORTCUT, ENTER); + } else if (template.getShortcutChar() == SPACE_CHAR) { + element.setAttribute(SHORTCUT, SPACE); + } + if (template.getDescription() != null) { + element.setAttribute(DESCRIPTION, template.getDescription()); + } + element.setAttribute(TO_REFORMAT, template.isToReformat() ? "true" : "false"); + element.setAttribute(TO_SHORTEN_FQ_NAMES, template.isToShortenLongNames() ? "true" : "false"); + if (template.isDeactivated()) { + element.setAttribute(DEACTIVATED, "true"); + } + + for (int i = 0; i < template.getVariableCount(); i++) { + Element variableElement = new Element(VARIABLE); + variableElement.setAttribute(NAME, template.getVariableNameAt(i)); + variableElement.setAttribute(EXPRESSION, template.getExpressionStringAt(i)); + variableElement.setAttribute(DEFAULT_VALUE, template.getDefaultValueStringAt(i)); + variableElement.setAttribute(ALWAYS_STOP_AT, template.isAlwaysStopAt(i) ? "true" : "false"); + element.addContent(variableElement); + } + + try { + Element contextElement = new Element(CONTEXT); + DefaultJDOMExternalizer.writeExternal(template.getTemplateContext(), contextElement); + element.addContent(contextElement); + } catch (WriteExternalException e) { + } + templateSetElement.addContent(element); + } + + private String findFirstNotExistingFile(File directory, String fileName, String extension) { + String filePath = directory.getAbsolutePath() + File.separator + fileName + extension; + File file = new File(filePath); + if (!file.exists()) { + return filePath; + } + for (int i = 1; ; i++) { + filePath = directory.getAbsolutePath() + File.separator + fileName + i + extension; + file = new File(filePath); + if (!file.exists()) { + return filePath; + } + } + } + + + private String convertName(String s) { + if (s == null || s.length() == 0) { + return "_"; + } + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isJavaIdentifierPart(c) || c == ' ') { + buf.append(c); + } else { + buf.append('_'); + } + } + return buf.toString(); + } + + public String getComponentName() { + return "TemplateSettings"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateState.java new file mode 100644 index 00000000000..68b8dcc0e7e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateState.java @@ -0,0 +1,971 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.AutoPopupController; +import com.intellij.codeInsight.completion.DefaultCharFilter; +import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.impl.DocumentReferenceByDocument; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.command.undo.UnexpectedUndoException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.IntArrayList; + +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * + */ +public class TemplateState { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.impl.TemplateState"); + private Project myProject; + private Editor myEditor; + + private TemplateImpl myTemplate; + private TemplateSegments mySegments = null; + private Hashtable myVariables = new Hashtable(); + + private boolean toProcessChangedUpdate = true; + private RangeMarker myTemplateRange = null; + private ArrayList myTabStopHighlighters = new ArrayList(); + private int myCurrentVariableNumber = -1; + private int myCurrentSegmentNumber = -1; + private boolean toProcessTab = true; + private boolean myChangesFlag = false; + + private CommandAdapter myCommandListener; + + private List myListeners = new ArrayList(); + private DocumentAdapter myEditorDocumentListener; + private Map myProperties = new HashMap(); + private boolean myTemplateIndented = false; + private CodeStyleManager myCodeStyleManager; + private Document myDocument; + + public TemplateState(Project project, final Editor editor) { + myProject = project; + myEditor = editor; + myCodeStyleManager = CodeStyleManager.getInstance(project); + myDocument = myEditor.getDocument(); + } + + private void initListeners() { + myEditorDocumentListener = new DocumentAdapter() { + public void beforeDocumentChange(DocumentEvent e) { + if (!isFinished()) { + if (toProcessChangedUpdate) { + UndoManager undoManager = UndoManager.getInstance(myProject); + if (!undoManager.isUndoInProgress() && !undoManager.isRedoInProgress()) { + if (myCurrentSegmentNumber >= 0) { + myChangesFlag = e.getOffset() < mySegments.getSegmentStart(myCurrentSegmentNumber) + || e.getOffset() + e.getOldLength() > mySegments.getSegmentEnd(myCurrentSegmentNumber); + } + } + } + } + } + }; + + myCommandListener = new CommandAdapter() { + public void beforeCommandFinished(CommandEvent event) { + //This is a hack to deal with closing lookup, TODO: remove redundant string on update + if (!"Up".equals(event.getCommandName()) && !"Down".equals(event.getCommandName())) { + afterChangedUpdate(); + } + } + }; + + myDocument.addDocumentListener(myEditorDocumentListener); + CommandProcessor.getInstance().addCommandListener(myCommandListener); + } + + public synchronized void dispose() { + if (myEditorDocumentListener != null) { + myDocument.removeDocumentListener(myEditorDocumentListener); + myEditorDocumentListener = null; + } + if (myCommandListener != null) { + CommandProcessor.getInstance().removeCommandListener(myCommandListener); + myCommandListener = null; + } + + //Avoid the leak of the editor + releaseEditor(); + myDocument = null; + } + + public boolean isToProcessTab() { + return toProcessTab; + } + + private void setCurrentVariableNumber(int variableNumber) { + int prevSegmentNumber = getCurrentSegmentNumber(); + myCurrentVariableNumber = variableNumber; + ((DocumentEx) myDocument).setStripTrailingSpacesEnabled(variableNumber < 0); + if (variableNumber < 0) { + myCurrentSegmentNumber = -1; + releaseAll(); + } else { + myCurrentSegmentNumber = getCurrentSegmentNumber(); + if (myCurrentSegmentNumber >= 0) { + mySegments.setSegmentGreedy(myCurrentSegmentNumber, true); + } + if (prevSegmentNumber >= 0) { + mySegments.setSegmentGreedy(prevSegmentNumber, false); + } + } + } + + public TextResult getVariableValue(String variableName) { + if (variableName.equals(TemplateImpl.SELECTION)) { + return new TextResult((String) getProperties().get(ExpressionContext.SELECTION)); + } + if (variableName.equals(TemplateImpl.END)) { + return new TextResult(""); + } + + CharSequence text = myDocument.getCharsSequence(); + int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + if (segmentNumber < 0) { + return null; + } + int start = mySegments.getSegmentStart(segmentNumber); + int end = mySegments.getSegmentEnd(segmentNumber); + int length = myDocument.getTextLength(); + if (start >= length || end > length) { + return null; + } + return new TextResult(text.subSequence(start, end).toString()); + } + + public TextRange getCurrentVariableRange() { + int number = getCurrentSegmentNumber(); + if (number == -1) return null; + return new TextRange(mySegments.getSegmentStart(number), mySegments.getSegmentEnd(number)); + } + + public TextRange getVariableRange(String variableName) { + int segment = myTemplate.getVariableSegmentNumber(variableName); + if (segment < 0) return null; + + return new TextRange(mySegments.getSegmentStart(segment), mySegments.getSegmentEnd(segment)); + } + + public boolean isFinished() { + return (myCurrentVariableNumber < 0); + } + + private void releaseAll() { + if (mySegments != null) { + mySegments.removeAll(); + mySegments = null; + } + myTemplateRange = null; + myTemplate = null; + myVariables.clear(); + releaseEditor(); + myTabStopHighlighters.clear(); + } + + private void releaseEditor() { + if (myEditor != null) { + for (int i = 0; i < myTabStopHighlighters.size(); i++) { + RangeHighlighter segmentHighlighter = myTabStopHighlighters.get(i); + myEditor.getMarkupModel().removeHighlighter(segmentHighlighter); + } + + myEditor = null; + } + } + + public void start(TemplateImpl template) { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + UndoManager.getInstance(myProject).undoableActionPerformed( + new UndoableAction() { + public void undo() throws UnexpectedUndoException { + if (myDocument != null) { + setCurrentVariableNumber(-1); + } + } + + public void redo() throws UnexpectedUndoException { + //TODO: + // throw new UnexpectedUndoException("Not implemented"); + } + + public DocumentReference[] getAffectedDocuments() { + if (myDocument == null) return new DocumentReference[0]; + return new DocumentReference[]{DocumentReferenceByDocument.createDocumentReference(myDocument)}; + } + + public boolean isComplex() { + return false; + } + } + ); + myTemplateIndented = false; + myCurrentVariableNumber = -1; + mySegments = new TemplateSegments(myEditor); + myTemplate = template; + + int caretOffset = myEditor.getCaretModel().getOffset(); + if (template.isInline()) { + myTemplateRange = myDocument.createRangeMarker(caretOffset, caretOffset + template.getTemplateText().length()); + } else { + myTemplateRange = myDocument.createRangeMarker(caretOffset, caretOffset); + } + myTemplateRange.setGreedyToLeft(true); + myTemplateRange.setGreedyToRight(true); + + processAllExpressions(template); + } + + private void processAllExpressions(final TemplateImpl template) { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + toProcessChangedUpdate = false; + if (!template.isInline()) myDocument.insertString(myTemplateRange.getStartOffset(), template.getTemplateText()); + for (int i = 0; i < template.getSegmentsCount(); i++) { + int segmentOffset = myTemplateRange.getStartOffset() + template.getSegmentOffset(i); + mySegments.addSegment(segmentOffset, segmentOffset); + } + toProcessChangedUpdate = true; + calcResults(false); + calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start. + doReformat(); + + int nextVariableNumber = getNextVariableNumber(-1); + if (nextVariableNumber == -1) { + finishTemplateEditing(); + } else { + setCurrentVariableNumber(nextVariableNumber); + initTabStopHighlighters(); + initListeners(); + focusCurrentExpression(); + } + } + } + ); + } + + private void doReformat() { + final Runnable action = new Runnable() { + public void run() { + IntArrayList indices = initEmptyVariables(); + reformat(); + restoreEmptyVariables(indices); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + + private void afterChangedUpdate() { + if (isFinished() || !toProcessChangedUpdate) return; + LOG.assertTrue(myTemplate != null); + UndoManager undoManager = UndoManager.getInstance(myProject); + if (undoManager.isUndoInProgress() || undoManager.isRedoInProgress()) return; + + if (myChangesFlag) { + setCurrentVariableNumber(-1); + } else { + if (!mySegments.isInvalid()) { + toProcessChangedUpdate = false; + calcResults(true); + toProcessChangedUpdate = true; + } + } + } + + private String getExpressionString(int index) { + CharSequence text = myDocument.getCharsSequence(); + + if (!mySegments.isValid(index)) return ""; + + int start = mySegments.getSegmentStart(index); + int end = mySegments.getSegmentEnd(index); + + return text.subSequence(start, end).toString(); + } + + private int getCurrentSegmentNumber() { + if (myCurrentVariableNumber == -1) { + return -1; + } + String variableName = myTemplate.getVariableNameAt(myCurrentVariableNumber); + return myTemplate.getVariableSegmentNumber(variableName); + } + + private void focusCurrentExpression() { + if (isFinished()) { + return; + } + + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + + int currentSegmentNumber = getCurrentSegmentNumber(); + if (currentSegmentNumber < 0) return; + int start = mySegments.getSegmentStart(currentSegmentNumber); + int end = mySegments.getSegmentEnd(currentSegmentNumber); + myEditor.getCaretModel().moveToOffset(end); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + myEditor.getSelectionModel().removeSelection(); + + + myEditor.getSelectionModel().setSelection(start, end); + Expression expressionNode = myTemplate.getExpressionAt(myCurrentVariableNumber); + + final ExpressionContext context = createExpressionContext(start); + final LookupItem[] lookupItems = expressionNode.calculateLookupItems(context); + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument); + if (lookupItems != null && lookupItems.length > 0) { + final LookupItemPreferencePolicy preferencePolicy = new LookupItemPreferencePolicy() { + public int compare(Object o1, Object o2) { + if (o1.equals(o2)) return 0; + if (o1.equals(lookupItems[0])) return -1; + if (o2.equals(lookupItems[0])) return +1; + return 0; + } + + public void setPrefix(String prefix) {} + + public void itemSelected(LookupItem item) { + } + }; + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myEditor == null) return; + + final LookupManager lookupManager = LookupManager.getInstance(myProject); + if (lookupManager.isDisposed()) return; + final Lookup lookup = lookupManager.showLookup(myEditor, lookupItems, "", preferencePolicy, + new DefaultCharFilter(psiFile)); + lookup.setCurrentItem(lookupItems[0]); // [Valentin] not absolutely correct but all existing macros return the first item as the result + toProcessTab = false; + lookup.addLookupListener( + new LookupAdapter() { + public void lookupCanceled(LookupEvent event) { + lookup.removeLookupListener(this); + toProcessTab = true; + } + + public void itemSelected(LookupEvent event) { + lookup.removeLookupListener(this); + toProcessTab = true; + + final LookupItem item = event.getItem(); + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + Integer bracketCount = (Integer) item.getAttribute(LookupItem.BRACKETS_COUNT_ATTR); + if (bracketCount != null) { + StringBuffer tail = new StringBuffer(); + for (int i = 0; i < bracketCount.intValue(); i++) { + tail.append("[]"); + } + EditorModificationUtil.insertStringAtCaret(myEditor, tail.toString()); + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + } + + updateTypeBindings(item.getObject(), psiFile, context); + + char c = event.getCompletionChar(); + if (c == '.') { + EditorModificationUtil.insertStringAtCaret(myEditor, "."); + AutoPopupController.getInstance(myProject).autoPopupMemberLookup(myEditor); + return; + } + + if (item.getAttribute(Expression.AUTO_POPUP_NEXT_LOOKUP) != null) { + AutoPopupController.getInstance(myProject).autoPopupMemberLookup(myEditor); + return; + } + + if (!isFinished()) { + toProcessChangedUpdate = false; + calcResults(true); + toProcessChangedUpdate = true; + } + + nextTab(); + } + } + ); + } + }); + } else { + Result result = expressionNode.calculateResult(context); + if (result instanceof PsiElementResult) { + updateTypeBindings(((PsiElementResult) result).getElement(), psiFile, context); + } + if (result instanceof PsiTypeResult) { + updateTypeBindings(((PsiTypeResult) result).getType(), psiFile, context); + } + if (result instanceof InvokeActionResult) { + ((InvokeActionResult) result).getAction().run(); + } + } + focusCurrentHighlighter(true); + } + + + private void updateTypeBindings(Object item, PsiFile file, ExpressionContext context) { + PsiClass aClass = null; + if (item instanceof PsiClass) { + aClass = (PsiClass) item; + } else if (item instanceof PsiType) { + aClass = PsiUtil.resolveClassInType(((PsiType) item)); + } + + if (aClass != null) { + if (aClass instanceof PsiTypeParameter) { + if (((PsiTypeParameter)aClass).getOwner() instanceof PsiMethod) { + int start = context.getStartOffset(); + PsiElement element = file.findElementAt(start); + PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (method != null) { + PsiTypeParameterList paramList = method.getTypeParameterList(); + PsiTypeParameter[] params = paramList.getTypeParameters(); + for (int i = 0; i < params.length; i++) { + PsiTypeParameter param = params[i]; + if (param.getName().equals(aClass.getName())) return; + } + try { + toProcessChangedUpdate = false; + paramList.add(aClass.copy()); + toProcessChangedUpdate = true; + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + } else { + TextRange range = getCurrentVariableRange(); + if (range != null) { + addImportForClass(aClass, range.getStartOffset(), range.getEndOffset()); + } + } + } + } + + + private void calcResults(final boolean isQuick) { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + BitSet calcedSegments = new BitSet(); + + do { + calcedSegments.clear(); + for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) { + String variableName = myTemplate.getVariableNameAt(i); + int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + if (segmentNumber < 0) continue; + Expression expression = myTemplate.getExpressionAt(i); + Expression defaultValue = myTemplate.getDefaultValueAt(i); + String oldValue = getVariableValue(variableName).getText(); + recalcSegment(segmentNumber, isQuick, expression, defaultValue); + String newValue = getVariableValue(variableName).getText(); + if (!newValue.equals(oldValue)) { + calcedSegments.set(segmentNumber); + } + } + + for (int i = 0; i < myTemplate.getSegmentsCount(); i++) { + if (!calcedSegments.get(i)) { + String variableName = myTemplate.getSegmentName(i); + String newValue = getVariableValue(variableName).getText(); + int start = mySegments.getSegmentStart(i); + int end = mySegments.getSegmentEnd(i); + toProcessChangedUpdate = false; + replaceString(newValue, start, end, i); + toProcessChangedUpdate = true; + } + } + } while (!calcedSegments.isEmpty()); + } + } + ); + } + + private void recalcSegment(int segmentNumber, boolean isQuick, Expression expressionNode, Expression defaultValue) { + String oldValue = getExpressionString(segmentNumber); + int start = mySegments.getSegmentStart(segmentNumber); + int end = mySegments.getSegmentEnd(segmentNumber); + ExpressionContext context = createExpressionContext(start); + Result result; + if (isQuick) { + result = expressionNode.calculateQuickResult(context); + } else { + result = expressionNode.calculateResult(context); + if (expressionNode instanceof ConstantNode) { + if (result instanceof TextResult) { + TextResult text = (TextResult) result; + if (text.getText().equals("") && defaultValue != null) { + result = defaultValue.calculateResult(context); + } + } + } + if (result == null && defaultValue != null) { + result = defaultValue.calculateResult(context); + } + } + if (result == null) return; + + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument); + PsiElement element = psiFile.findElementAt(start); + if (result.equalsToText(oldValue, element)) return; + + String newValue = result.toString(); + if (newValue == null) newValue = ""; + + if (element instanceof PsiJavaToken && ((PsiJavaToken) element).getTokenType() == JavaTokenType.STRING_LITERAL) { + newValue = StringUtil.escapeStringCharacters(newValue); + } + + toProcessChangedUpdate = false; + replaceString(newValue, start, end, segmentNumber); + + if (result instanceof PsiTypeResult) { + PsiTypeElement t = PsiTreeUtil.getParentOfType(psiFile.findElementAt(start), PsiTypeElement.class); + if (t != null && t.getTextRange().getStartOffset() == start) { + try { + PsiJavaCodeReferenceElement ref = t.getInnermostComponentReferenceElement(); + if (ref != null) { + myCodeStyleManager.shortenClassReferences(ref); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + if (ApplicationManager.getApplication().isUnitTestMode()) { + if (result instanceof PsiTypeResult) updateTypeBindings(((PsiTypeResult) result).getType(), psiFile, context); + else if (result instanceof PsiClass) updateTypeBindings(result, psiFile, context); + } + + toProcessChangedUpdate = true; + LOG.assertTrue(!PsiDocumentManager.getInstance(myProject).isUncommited(myDocument)); + } + + private void replaceString(String newValue, int start, int end, int segmentNumber) { + String oldText = myDocument.getCharsSequence().subSequence(start, end).toString(); + if (!oldText.equals(newValue)) { + myDocument.replaceString(start, end, newValue); + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + + mySegments.replaceSegmentAt(segmentNumber, start, start + newValue.length()); + } + } + + public void previousTab() { + if (isFinished()) { + return; + } + int previousVariableNumber = getPreviousVariableNumber(myCurrentVariableNumber); + if (previousVariableNumber >= 0) { + focusCurrentHighlighter(false); + calcResults(false); + doReformat(); + setCurrentVariableNumber(previousVariableNumber); + focusCurrentExpression(); + } + } + + public void nextTab() { + if (isFinished()) { + return; + } + int nextVariableNumber = getNextVariableNumber(myCurrentVariableNumber); + if (nextVariableNumber == -1) { + calcResults(false); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + reformat(); + } + }); + finishTemplateEditing(); + return; + } + focusCurrentHighlighter(false); + calcResults(false); + doReformat(); + setCurrentVariableNumber(nextVariableNumber); + focusCurrentExpression(); + } + + private ExpressionContext createExpressionContext(final int start) { + return new ExpressionContext() { + public Project getProject() { + return myProject; + } + + public Editor getEditor() { + return myEditor; + } + + public int getStartOffset() { + return start; + } + + public int getTemplateStartOffset() { + if (myTemplateRange == null) { + return -1; + } + return myTemplateRange.getStartOffset(); + } + + public int getTemplateEndOffset() { + if (myTemplateRange == null) { + return -1; + } + return myTemplateRange.getEndOffset(); + } + + public Map getProperties() { + return myProperties; + } + }; + } + + public void gotoEnd() { + calcResults(false); + doReformat(); + finishTemplateEditing(); + } + + private void finishTemplateEditing() { + int endSegmentNumber = myTemplate.getEndSegmentNumber(); + int offset = myTemplateRange.getEndOffset(); + if (endSegmentNumber >= 0) { + offset = mySegments.getSegmentStart(endSegmentNumber); + } + myEditor.getCaretModel().moveToOffset(offset); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + myEditor.getSelectionModel().removeSelection(); + + int selStart = myTemplate.getSelectionStartSegmentNumber(); + int selEnd = myTemplate.getSelectionEndSegmentNumber(); + if (selStart >= 0 && selEnd >= 0) { + myEditor.getSelectionModel().setSelection( + mySegments.getSegmentStart(selStart), + mySegments.getSegmentStart(selEnd) + ); + } + + fireTemplateFinished(); + myListeners.clear(); + setCurrentVariableNumber(-1); + myProject = null; + } + + private int getNextVariableNumber(int currentVariableNumber) { + for (int i = currentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) { + if (checkIfTabStop(i)) { + return i; + } + } + return -1; + } + + private int getPreviousVariableNumber(int currentVariableNumber) { + for (int i = currentVariableNumber - 1; i >= 0; i--) { + if (checkIfTabStop(i)) { + return i; + } + } + return -1; + } + + private boolean checkIfTabStop(int currentVariableNumber) { + Expression expression = myTemplate.getExpressionAt(currentVariableNumber); + if (expression == null) { + return false; + } + if (myTemplate.isAlwaysStopAt(currentVariableNumber)) { + return true; + } + String variableName = myTemplate.getVariableNameAt(currentVariableNumber); + int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + if (segmentNumber <= 0) return false; + int start = mySegments.getSegmentStart(segmentNumber); + ExpressionContext context = createExpressionContext(start); + Result result = expression.calculateResult(context); + if (result == null) { + return true; + } + LookupItem[] items = expression.calculateLookupItems(context); + if (items == null) return false; + return items.length > 1; + } + + private IntArrayList initEmptyVariables() { + int endSegmentNumber = myTemplate.getEndSegmentNumber(); + int selStart = myTemplate.getSelectionStartSegmentNumber(); + int selEnd = myTemplate.getSelectionEndSegmentNumber(); + toProcessChangedUpdate = false; + IntArrayList indices = new IntArrayList(); + for (int i = 0; i < myTemplate.getSegmentsCount(); i++) { + int length = mySegments.getSegmentEnd(i) - mySegments.getSegmentStart(i); + if (length != 0) continue; + if (i == endSegmentNumber || i == selStart || i == selEnd) continue; + + String name = myTemplate.getSegmentName(i); + for (int j = 0; j < myTemplate.getVariableCount(); j++) { + if (myTemplate.getVariableNameAt(j).equals(name)) { + Expression e = myTemplate.getExpressionAt(j); + String marker = "a"; + if (e instanceof MacroCallNode) { + marker = ((MacroCallNode) e).getMacro().getDefaultValue(); + } + int start = mySegments.getSegmentStart(i); + myDocument.insertString(start, marker); + mySegments.replaceSegmentAt(i, start, start + marker.length()); + indices.add(i); + break; + } + } + } + toProcessChangedUpdate = true; + return indices; + } + + private void restoreEmptyVariables(IntArrayList indices) { + toProcessChangedUpdate = false; + for (int i = 0; i < indices.size(); i++) { + int index = indices.get(i); + + String name = myTemplate.getSegmentName(index); + for (int j = 0; j < myTemplate.getVariableCount(); j++) { + if (myTemplate.getVariableNameAt(j).equals(name)) { + Expression e = myTemplate.getExpressionAt(j); + String marker = "a"; //was default + if (e instanceof MacroCallNode) { + marker = ((MacroCallNode) e).getMacro().getDefaultValue(); + } + myDocument.deleteString(mySegments.getSegmentStart(index), mySegments.getSegmentStart(index) + marker.length()); + break; + } + } + } + toProcessChangedUpdate = true; + } + + private void initTabStopHighlighters() { + for (int i = 0; i < myTemplate.getVariableCount(); i++) { + String variableName = myTemplate.getVariableNameAt(i); + int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + if (segmentNumber < 0) continue; + RangeHighlighter segmentHighlighter = getSegmentHighlighter(segmentNumber, false, false); + myTabStopHighlighters.add(segmentHighlighter); + } + + int endSegmentNumber = myTemplate.getEndSegmentNumber(); + if (endSegmentNumber >= 0) { + RangeHighlighter segmentHighlighter = getSegmentHighlighter(endSegmentNumber, false, true); + myTabStopHighlighters.add(segmentHighlighter); + } + } + + private RangeHighlighter getSegmentHighlighter(int segmentNumber, boolean isSelected, boolean isEnd) { + TextAttributes attributes = isSelected + ? new TextAttributes(null, null, Color.red, EffectType.BOXED, 0) + : new TextAttributes(); + TextAttributes endAttributes = new TextAttributes(); + + RangeHighlighter segmentHighlighter = null; + int start = mySegments.getSegmentStart(segmentNumber); + int end = mySegments.getSegmentEnd(segmentNumber); + if (isEnd) { + segmentHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, endAttributes, HighlighterTargetArea.EXACT_RANGE); + } else { + segmentHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE); + } + segmentHighlighter.setGreedyToLeft(true); + segmentHighlighter.setGreedyToRight(true); + return segmentHighlighter; + } + + private void focusCurrentHighlighter(boolean toSelect) { + if (isFinished()) { + return; + } + if (myCurrentVariableNumber >= myTabStopHighlighters.size()) { + return; + } + RangeHighlighter segmentHighlighter = myTabStopHighlighters.get(myCurrentVariableNumber); + if (segmentHighlighter != null) { + RangeHighlighter newSegmentHighlighter = getSegmentHighlighter(getCurrentSegmentNumber(), toSelect, false); + if (newSegmentHighlighter != null) { + myEditor.getMarkupModel().removeHighlighter(segmentHighlighter); + myTabStopHighlighters.set(myCurrentVariableNumber, newSegmentHighlighter); + } + } + } + + private void reformat() { + final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument); + if (file != null) { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + if (myTemplate.isToShortenLongNames()) { + try { + toProcessChangedUpdate = false; + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + codeStyleManager.shortenClassReferences(file, myTemplateRange.getStartOffset(), myTemplateRange.getEndOffset()); + toProcessChangedUpdate = true; + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + if (myTemplate.isToReformat()) { + try { + toProcessChangedUpdate = false; + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + int endSegmentNumber = myTemplate.getEndSegmentNumber(); + PsiElement marker = null; + if (endSegmentNumber >= 0) { + int endVarOffset = mySegments.getSegmentStart(endSegmentNumber); + marker = codeStyleManager.insertNewLineIndentMarker(file, endVarOffset); + } + codeStyleManager.reformatRange(file, myTemplateRange.getStartOffset(), myTemplateRange.getEndOffset()); + + if (marker != null && marker.isValid()) { //[ven] TODO: [max] correct javadoc reformatting to eliminate isValid() check!!! + TextRange range = marker.getTextRange(); + mySegments.replaceSegmentAt(endSegmentNumber, range.getStartOffset(), range.getEndOffset()); + myDocument.deleteString(range.getStartOffset(), range.getEndOffset()); + } + toProcessChangedUpdate = true; + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } else if (myTemplate.isToIndent()) { + if (!myTemplateIndented) { + smartIndent(myTemplateRange.getStartOffset(), myTemplateRange.getEndOffset()); + myTemplateIndented = true; + } + } + } + } + + private void smartIndent(int startOffset, int endOffset) { + int startLineNum = myDocument.getLineNumber(startOffset); + int endLineNum = myDocument.getLineNumber(endOffset); + if (endLineNum == startLineNum) { + return; + } + + int indentLineNum = startLineNum; + + int lineLength = 0; + for (; indentLineNum >= 0; indentLineNum--) { + lineLength = myDocument.getLineEndOffset(indentLineNum) - myDocument.getLineStartOffset(indentLineNum); + if (lineLength > 0) { + break; + } + } + if (indentLineNum < 0) { + return; + } + StringBuffer buffer = new StringBuffer(); + CharSequence text = myDocument.getCharsSequence(); + for (int i = 0; i < lineLength; i++) { + char ch = text.charAt(myDocument.getLineStartOffset(indentLineNum) + i); + if (ch != ' ' && ch != '\t') { + break; + } + buffer.append(ch); + } + if (buffer.length() == 0) { + return; + } + String stringToInsert = buffer.toString(); + for (int i = startLineNum + 1; i <= endLineNum; i++) { + myDocument.insertString(myDocument.getLineStartOffset(i), stringToInsert); + } + } + + public void addTemplateStateListener(TemplateStateListener listener) { + myListeners.add(listener); + } + + private void fireTemplateFinished() { + TemplateStateListener[] listeners = myListeners.toArray(new TemplateStateListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].templateFinished(myTemplate); + } + } + + private void addImportForClass(final PsiClass aClass, int startOffset, int endOffset) { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (!aClass.isValid() || aClass.getQualifiedName() == null) return; + + PsiManager manager = PsiManager.getInstance(myProject); + PsiResolveHelper helper = manager.getResolveHelper(); + + final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument); + CharSequence chars = myDocument.getCharsSequence(); + + PsiElement element = file.findElementAt(startOffset); + String refText = chars.subSequence(startOffset, endOffset).toString(); + PsiClass refClass = helper.resolveReferencedClass(refText, element); + if (aClass.equals(refClass)) return; + + if (element instanceof PsiIdentifier) { + PsiElement parent = element.getParent(); + while (parent != null) { + PsiElement tmp = parent.getParent(); + if (!(tmp instanceof PsiJavaCodeReferenceElement) || tmp.getTextRange().getEndOffset() > endOffset) break; + parent = tmp; + } + if (parent instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement) parent).isQualified()) { + final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) parent; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + ref.bindToElement(aClass); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }); + } + } + } + + public Map getProperties() { + return myProperties; + } + + public TemplateImpl getTemplate() { + return myTemplate; + } + + void reset() { + myListeners = new ArrayList(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTextLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTextLexer.java new file mode 100644 index 00000000000..ae9072accfa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTextLexer.java @@ -0,0 +1,280 @@ +/* It's an automatically generated code. Do not modify it. */ +package com.intellij.codeInsight.template.impl; +import com.intellij.lexer.Lexer; +import com.intellij.psi.tree.IElementType; + + +class TemplateTextLexer implements Lexer, Cloneable { + private static final int YY_F = -1; + private static final int YY_NO_STATE = -1; + private static final int YY_NOT_ACCEPT = 0; + private static final int YY_START = 1; + private static final int YY_END = 2; + private static final int YY_NO_ANCHOR = 4; + private static final char YYEOF = '\uFFFF'; + + private IElementType myTokenType; + public final void start(char[] buffer){ + start(buffer, 0, buffer.length); + } + public final void start(char[] buffer, int startOffset, int endOffset){ + yy_buffer = buffer; + yy_buffer_index = startOffset; + yy_buffer_length = endOffset; + myTokenType = null; + } + public final void start(char[] buffer, int startOffset, int endOffset, int initialState){ + start(buffer, startOffset, endOffset); + } + public final int getState(){ + return 0; + } + public final int getLastState() { + return LAST_STATE; + } + public final IElementType getTokenType(){ + locateToken(); + return myTokenType; + } + public final int getTokenStart(){ + if (myTokenType != null){ + return yy_buffer_start; + } + else{ + return yy_buffer_index; + } + } + public final int getTokenEnd(){ + locateToken(); + return yy_buffer_end; + } + public final void advance(){ + locateToken(); + myTokenType = null; + } + public final char[] getBuffer(){ + return yy_buffer; + } + public final int getBufferEnd(){ + return yy_buffer_length; + } + protected final void locateToken(){ + if (myTokenType != null) return; + _locateToken(); + } + public int getSmartUpdateShift() { + return -1; + } + public Object clone() { + try{ + return super.clone(); + } + catch(CloneNotSupportedException e){ + return null; + } + } + private int yy_buffer_index; + private int yy_buffer_start; + private int yy_buffer_end; + private char yy_buffer[]; + private int yy_buffer_length; + private int yy_lexical_state; + + public TemplateTextLexer () { + yy_lexical_state = YYINITIAL; + + myTokenType = null; + } + + private boolean yy_eof_done = false; + public static final short YYINITIAL = 0; + public static final short LAST_STATE = 1; + private static final int yy_state_dtrans[] = { + 0 + }; + private static final int YY_E_INTERNAL = 0; + private static final int YY_E_MATCH = 1; + private java.lang.String yy_error_string[] = { + "Error: Internal error.\n", + "Error: Unmatched input.\n" + }; + private void yy_error (int code,boolean fatal) { + java.lang.System.out.print(yy_error_string[code]); + java.lang.System.out.flush(); + if (fatal) { + throw new Error("Fatal Error.\n"); + } + } +private static int [][] unpackFromString(int size1, int size2, String st) + { + int colonIndex = -1; + String lengthString; + int sequenceLength = 0; + int sequenceInteger = 0; + int commaIndex; + String workString; + int res[][] = new int[size1][size2]; + for (int i= 0; i < size1; i++) + for (int j= 0; j < size2; j++) + { + if (sequenceLength == 0) + { + commaIndex = st.indexOf(','); + if (commaIndex == -1) + workString = st; + else + workString = st.substring(0, commaIndex); + st = st.substring(commaIndex+1); + colonIndex = workString.indexOf(':'); + if (colonIndex == -1) + { + res[i][j] = Integer.parseInt(workString); + } + else + { + lengthString = workString.substring(colonIndex+1); + sequenceLength = Integer.parseInt(lengthString); + workString = workString.substring(0,colonIndex); + sequenceInteger = Integer.parseInt(workString); + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + else + { + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + return res; + } + private static final int yy_acpt[] = { + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR + }; + private static final int yy_cmap[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 0, 2, + 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 0, 0 + + }; + private static final int yy_rmap[] = { + 0, 1, 1, 1, 2, 3 + }; + private static final int yy_nxt[][] = unpackFromString(4,3, +"1,5,1,-1:4,3,4,-1,2,4"); + public void _locateToken () + { + char yy_lookahead; + int yy_anchor = YY_NO_ANCHOR; + int yy_state = yy_state_dtrans[yy_lexical_state]; + int yy_next_state = YY_NO_STATE; + int yy_last_accept_state = YY_NO_STATE; + boolean yy_initial = true; + int yy_this_accept; + + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + while (true) { + if (yy_buffer_index < yy_buffer_length){ + yy_lookahead = yy_buffer[yy_buffer_index++]; + if (yy_lookahead < 0 || yy_lookahead > 127){ + if (Character.isJavaIdentifierStart(yy_lookahead)){ + yy_lookahead = 'A'; + } + else if (Character.isJavaIdentifierPart(yy_lookahead)){ + yy_lookahead = '9'; + } + else{ + yy_lookahead = '#'; + } + } + } + else{ + yy_lookahead = YYEOF; + } + yy_next_state = YY_F; + if (YYEOF != yy_lookahead) { + yy_next_state = yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]]; + } + if (YY_F != yy_next_state) { + yy_state = yy_next_state; + yy_initial = false; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + } + else { + if (YYEOF == yy_lookahead && true == yy_initial) { + myTokenType = null; return; + } + else if (YY_NO_STATE == yy_last_accept_state) { + throw (new Error("Lexical Error: Unmatched Input.")); + } + else { + yy_buffer_index = yy_buffer_end; + yy_anchor = yy_acpt[yy_last_accept_state]; + if (0 != (YY_END & yy_anchor)) { + --yy_buffer_end; + } + if (0 != (YY_START & yy_anchor)) { + ++yy_buffer_start; + } + switch (yy_last_accept_state) { + case 1: + { myTokenType = TemplateTokenType.TEXT; return; } + case -2: + break; + case 2: + { myTokenType = TemplateTokenType.ESCAPE_DOLLAR; return; } + case -3: + break; + case 3: + { myTokenType = TemplateTokenType.VARIABLE; return; } + case -4: + break; + case 5: + { myTokenType = TemplateTokenType.TEXT; return; } + case -5: + break; + default: + yy_error(YY_E_INTERNAL,false); + case -1: + } + yy_initial = true; + yy_state = yy_state_dtrans[yy_lexical_state]; + yy_next_state = YY_NO_STATE; + yy_last_accept_state = YY_NO_STATE; + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTokenType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTokenType.java new file mode 100644 index 00000000000..c0d5d462be9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/TemplateTokenType.java @@ -0,0 +1,9 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.psi.tree.IElementType; + +interface TemplateTokenType { + IElementType TEXT = new IElementType("TEXT"); + IElementType VARIABLE = new IElementType("VARIABLE"); + IElementType ESCAPE_DOLLAR = new IElementType("ESCAPE_DOLLAR"); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/Variable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/Variable.java new file mode 100644 index 00000000000..8841611ff4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/Variable.java @@ -0,0 +1,105 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Expression; + +public class Variable implements Cloneable { + private String myName; + private boolean myAlwaysStopAt; + + private String myExpressionString; + private Expression myExpression = null; + + private String myDefaultValueString; + private Expression myDefaultValueExpression; + + public Variable(String name, Expression expression, Expression defaultValueExpression, boolean alwaysStopAt) { + myName = name; + myExpression = expression; + myDefaultValueExpression = defaultValueExpression; + myAlwaysStopAt = alwaysStopAt; + } + + public Variable(String name, String expression, String defaultValueString, boolean alwaysStopAt) { + myName = name; + myExpressionString = expression; + myDefaultValueString = defaultValueString; + myAlwaysStopAt = alwaysStopAt; + } + + public String getExpressionString() { + return myExpressionString; + } + + public void setExpressionString(String expressionString) { + myExpressionString = expressionString; + myExpression = null; + } + + public Expression getExpression() { + if (myExpression == null) { + if (myName.equals(TemplateImpl.SELECTION)) { + myExpression = new SelectionNode(); + } + else { + myExpression = MacroParser.parse(myExpressionString); + } + } + return myExpression; + } + + public String getDefaultValueString() { + return myDefaultValueString; + } + + public void setDefaultValueString(String defaultValueString) { + myDefaultValueString = defaultValueString; + myDefaultValueExpression = null; + } + + public Expression getDefaultValueExpression() { + if (myDefaultValueExpression == null) { + myDefaultValueExpression = MacroParser.parse(myDefaultValueString); + } + return myDefaultValueExpression; + } + + public String getName() { + return myName; + } + + public boolean isAlwaysStopAt() { + if (myName.equals(TemplateImpl.SELECTION)) return false; + return myAlwaysStopAt; + } + + public void setAlwaysStopAt(boolean alwaysStopAt) { + myAlwaysStopAt = alwaysStopAt; + } + + public Object clone() { + return new Variable(myName, myExpressionString, myDefaultValueString, myAlwaysStopAt); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Variable)) return false; + + final Variable variable = (Variable) o; + + if (myAlwaysStopAt != variable.myAlwaysStopAt) return false; + if (myDefaultValueString != null ? !myDefaultValueString.equals(variable.myDefaultValueString) : variable.myDefaultValueString != null) return false; + if (myExpressionString != null ? !myExpressionString.equals(variable.myExpressionString) : variable.myExpressionString != null) return false; + if (myName != null ? !myName.equals(variable.myName) : variable.myName != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myName != null ? myName.hashCode() : 0); + result = 29 * result + (myAlwaysStopAt ? 1 : 0); + result = 29 * result + (myExpressionString != null ? myExpressionString.hashCode() : 0); + result = 29 * result + (myDefaultValueString != null ? myDefaultValueString.hashCode() : 0); + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/VariableNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/VariableNode.java new file mode 100644 index 00000000000..fd3d8744a5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/VariableNode.java @@ -0,0 +1,54 @@ +package com.intellij.codeInsight.template.impl; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.codeInsight.template.Result; +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.lookup.LookupItem; + +/** + * + */ +class VariableNode implements Expression { + private String myName; + private Expression myInitialValue; + + public VariableNode(String name, Expression initialValue) { + myName = name; + myInitialValue = initialValue; + } + + public Result calculateResult(ExpressionContext context) { + Result ret = null; + if (myInitialValue != null){ + ret = myInitialValue.calculateResult(context); + } + else{ + ret = TemplateManagerImpl.getTemplateState(context.getEditor()).getVariableValue(getName()); + } + return ret; + } + + public Result calculateQuickResult(ExpressionContext context) { + Result ret = null; + if (myInitialValue != null){ + ret = myInitialValue.calculateQuickResult(context); + } + else{ + ret = TemplateManagerImpl.getTemplateState(context.getEditor()).getVariableValue(getName()); + } + return ret; + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + if (myInitialValue == null){ + return null; + } + return myInitialValue.calculateLookupItems(context); + } + + private String getName() { + return myName; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/ListTemplatesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/ListTemplatesAction.java new file mode 100644 index 00000000000..c16eb5c08f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/ListTemplatesAction.java @@ -0,0 +1,12 @@ + +package com.intellij.codeInsight.template.impl.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.template.impl.ListTemplatesHandler; + +public class ListTemplatesAction extends BaseCodeInsightAction{ + protected CodeInsightActionHandler getHandler() { + return new ListTemplatesHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java new file mode 100644 index 00000000000..7b4718d53cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java @@ -0,0 +1,37 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 16, 2002 + * Time: 6:16:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInsight.template.impl.actions; + +import com.intellij.codeInsight.template.impl.TemplateManagerImpl; +import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class NextVariableAction extends EditorAction { + public NextVariableAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + CommandProcessor.getInstance().setCurrentCommandName("Go to Next Code Template Tab"); + templateState.nextTab(); + } + } + + public void update(Editor editor, Presentation presentation, DataContext dataContext) { + TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + presentation.setEnabled(templateState != null && !templateState.isFinished() && templateState.isToProcessTab()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java new file mode 100644 index 00000000000..f2eaece10f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java @@ -0,0 +1,37 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 16, 2002 + * Time: 6:16:33 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInsight.template.impl.actions; + +import com.intellij.codeInsight.template.impl.TemplateManagerImpl; +import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class PreviousVariableAction extends EditorAction { + public PreviousVariableAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + CommandProcessor.getInstance().setCurrentCommandName("Go to Previous Code Template Tab"); + templateState.previousTab(); + } + } + + public void update(Editor editor, Presentation presentation, DataContext dataContext) { + final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + presentation.setEnabled(templateState != null && !templateState.isFinished()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/SurroundWithTemplateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/SurroundWithTemplateAction.java new file mode 100644 index 00000000000..662b73b3be6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/impl/actions/SurroundWithTemplateAction.java @@ -0,0 +1,14 @@ +package com.intellij.codeInsight.template.impl.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.template.impl.SurroundWithTemplateHandler; + +/** + * @author mike + */ +public class SurroundWithTemplateAction extends BaseCodeInsightAction { + protected CodeInsightActionHandler getHandler() { + return new SurroundWithTemplateHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ArrayVariableMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ArrayVariableMacro.java new file mode 100644 index 00000000000..24b83ae59bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ArrayVariableMacro.java @@ -0,0 +1,46 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import java.util.ArrayList; + +public class ArrayVariableMacro extends VariableTypeMacroBase { + public String getName() { + return "arrayVariable"; + } + + public String getDescription() { + return "arrayVariable()"; + } + + protected PsiVariable[] getVariables(Expression[] params, final ExpressionContext context) { + if (params.length != 0) return null; + + Project project = context.getProject(); + final int offset = context.getStartOffset(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final ArrayList array = new ArrayList(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + PsiVariable[] variables = MacroUtil.getVariablesVisibleAt(place, ""); + for(int i = 0; i < variables.length; i++){ + PsiType type = variables[i].getType(); + if (type instanceof PsiArrayType){ + array.add(variables[i]); + } + } + return (PsiVariable[])array.toArray(new PsiVariable[array.size()]); + } +} + + + + + + + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java new file mode 100644 index 00000000000..02debc9bea1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java @@ -0,0 +1,152 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.template.impl.TemplateManagerImpl; +import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; + +public abstract class BaseCompleteMacro implements Macro { + private final String myName; + + public BaseCompleteMacro(String name) { + myName = name; + } + + abstract CodeInsightActionHandler getCompletionHandler (); + + public String getName() { + return myName; + } + + public String getDescription() { + return myName + "()"; + } + + public String getDefaultValue() { + return "a"; + } + + public final Result calculateResult(Expression[] params, final ExpressionContext context) { + return new InvokeActionResult( + new Runnable() { + public void run() { + invokeCompletion(context); + } + } + ); + } + + private void invokeCompletion(final ExpressionContext context) { + final Project project = context.getProject(); + final Editor editor = context.getEditor(); + + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + getCompletionHandler().invoke(project, editor, PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument())); + } + }, + "", + null + ); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + final LookupManager lookupManager = LookupManager.getInstance(project); + Lookup lookup = lookupManager.getActiveLookup(); + + if (lookup != null) { + lookup.addLookupListener(new MyLookupListener(context)); + } + else { + TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + if (templateState != null) { + TextRange range = templateState.getCurrentVariableRange(); + if (range != null && range.getLength() > 0/* && TemplateEditorUtil.getOffset(editor) == range.getEndOffset()*/) { + templateState.nextTab(); + } + } + } + } + }, + "", + null + ); + } + }); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return null; + } + + private class MyLookupListener extends LookupAdapter { + private final ExpressionContext myContext; + + public MyLookupListener(ExpressionContext context) { + myContext = context; + } + + public void itemSelected(LookupEvent event) { + final Project project = myContext.getProject(); + final LookupManager lookupManager = LookupManager.getInstance(project); + + LookupItem item = event.getItem(); + + if (item.getAttribute(Expression.AUTO_POPUP_NEXT_LOOKUP) != null) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + invokeCompletion(myContext); + } + }); + return; + } + + final PsiElement[] elements = lookupManager.getAllElementsForItem(item); + + boolean goNextTab = false; + + if (elements == null) { + goNextTab = true; + } + else { + if (elements.length != 1) { + goNextTab = false; + } + else { + if (elements[0] instanceof PsiMethod) { + PsiMethod method = (PsiMethod)elements[0]; + goNextTab = method.getParameterList().getParameters().length == 0; + } + else { + goNextTab = true; + } + } + } + + if (goNextTab) { + TemplateState templateState = TemplateManagerImpl.getTemplateState(myContext.getEditor()); + if (templateState != null) { + templateState.nextTab(); + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CapitalizeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CapitalizeMacro.java new file mode 100644 index 00000000000..92cd52cc20e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CapitalizeMacro.java @@ -0,0 +1,44 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; + +public class CapitalizeMacro implements Macro { + + public String getName() { + return "capitalize"; + } + + public String getDescription() { + return "capitalize(String)"; + } + + public String getDefaultValue() { + return "A"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + Result result = params[0].calculateResult(context); + return execute(result); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + Result result = params[0].calculateQuickResult(context); + return execute(result); + } + + private Result execute(Result result) { + if (result == null) return null; + String text = result.toString(); + if (text.length() > 0) { + text = text.substring(0, 1).toUpperCase() + text.substring(1, text.length()); + } + return new TextResult(text); + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CastToLeftSideTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CastToLeftSideTypeMacro.java new file mode 100644 index 00000000000..09350eff5fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CastToLeftSideTypeMacro.java @@ -0,0 +1,60 @@ +/* + * @author ven + */ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +public class CastToLeftSideTypeMacro implements Macro { + public String getName() { + return "castToLeftSideType"; + } + + public String getDescription() { + return "castToLeftSideType()"; + } + + public String getDefaultValue() { + return "(A)"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + int offset = context.getStartOffset(); + Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement element = file.findElementAt(offset); + element = PsiTreeUtil.getParentOfType(element, new Class[] {PsiAssignmentExpression.class, PsiVariable.class}); + PsiType leftType = null; + PsiExpression rightSide = null; + if (element instanceof PsiAssignmentExpression) { + PsiAssignmentExpression assignment = (PsiAssignmentExpression) element; + leftType = assignment.getLExpression().getType(); + rightSide = assignment.getRExpression(); + } else if (element instanceof PsiVariable) { + PsiVariable var = (PsiVariable) element; + leftType = var.getType(); + rightSide = var.getInitializer(); + } + + while (rightSide instanceof PsiTypeCastExpression) rightSide = ((PsiTypeCastExpression) rightSide).getOperand(); + + if (leftType != null && rightSide != null && rightSide.getType() != null && !leftType.isAssignableFrom(rightSide.getType())) { + return new TextResult("("+ leftType.getCanonicalText() + ")"); + } + + return new TextResult(""); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return new LookupItem[0]; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java new file mode 100644 index 00000000000..9aaafe3b393 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java @@ -0,0 +1,26 @@ + +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.completion.CodeCompletionHandler; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.codeInsight.completion.LookupData; +import com.intellij.codeInsight.completion.ClassNameCompletionHandler; + +public class ClassNameCompleteMacro extends BaseCompleteMacro { + public ClassNameCompleteMacro() { + super("classNameComplete"); + } + + CodeInsightActionHandler getCompletionHandler() { + ClassNameCompletionHandler classNameCompletionHandler = new ClassNameCompletionHandler() { + protected void handleEmptyLookup(CompletionContext context, LookupData lookupData) { + // noithing + } + }; + + classNameCompletionHandler.setShowOnEmptyPrefix(true); + + return classNameCompletionHandler; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameMacro.java new file mode 100644 index 00000000000..109b25550eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ClassNameMacro.java @@ -0,0 +1,62 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +public class ClassNameMacro implements Macro { + + public String getName() { + return "className"; + } + + public String getDescription() { + return "className()"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + Project project = context.getProject(); + int templateStartOffset = context.getTemplateStartOffset(); + int offset = templateStartOffset > 0 ? context.getTemplateStartOffset() - 1 : context.getTemplateStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + PsiClass aClass = null; + + while(place != null){ + if (place instanceof PsiClass && !(place instanceof PsiAnonymousClass) && !(place instanceof PsiTypeParameter)){ + aClass = (PsiClass)place; + break; + } + if (place instanceof PsiJavaFile){ + PsiClass[] classes = ((PsiJavaFile)place).getClasses(); + aClass = classes.length != 0 ? classes[0] : null; + break; + } + place = place.getParent(); + } + + if (aClass == null) return null; + String result = aClass.getName(); + while (aClass.getContainingClass() != null && aClass.getContainingClass().getName() != null) { + result = aClass.getContainingClass().getName() + "$" + result; + aClass = aClass.getContainingClass(); + } + return new TextResult(result); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteMacro.java new file mode 100644 index 00000000000..f3e44a3340e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteMacro.java @@ -0,0 +1,21 @@ + +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.completion.CodeCompletionHandler; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.codeInsight.completion.LookupData; + +public class CompleteMacro extends BaseCompleteMacro { + public CompleteMacro() { + super("complete"); + } + + CodeInsightActionHandler getCompletionHandler() { + return new CodeCompletionHandler() { + protected void handleEmptyLookup(CompletionContext context, LookupData lookupData) { + // noithing + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteSmartMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteSmartMacro.java new file mode 100644 index 00000000000..98d1459dcb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CompleteSmartMacro.java @@ -0,0 +1,21 @@ + +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.codeInsight.completion.LookupData; +import com.intellij.codeInsight.completion.SmartCodeCompletionHandler; + +public class CompleteSmartMacro extends BaseCompleteMacro { + public CompleteSmartMacro() { + super("completeSmart"); + } + + CodeInsightActionHandler getCompletionHandler() { + return new SmartCodeCompletionHandler() { + protected void handleEmptyLookup(CompletionContext context, LookupData lookupData) { + // nothing + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ComponentTypeOfMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ComponentTypeOfMacro.java new file mode 100644 index 00000000000..d4863b7d480 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ComponentTypeOfMacro.java @@ -0,0 +1,67 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.psi.*; + +public class ComponentTypeOfMacro implements Macro { + public String getName() { + return "componentTypeOf"; + } + + public String getDescription() { + return "componentTypeOf(Array)"; + } + + public String getDefaultValue() { + return "A"; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + LookupItem[] lookupItems = params[0].calculateLookupItems(context); + if (lookupItems == null) return null; + + for (int i = 0; i < lookupItems.length; i++) { + LookupItem item = lookupItems[i]; + Integer bracketsCount = (Integer)item.getAttribute(LookupItem.BRACKETS_COUNT_ATTR); + if (bracketsCount == null) return null; + item.setAttribute(LookupItem.BRACKETS_COUNT_ATTR, new Integer(bracketsCount.intValue() - 1)); + } + + return lookupItems; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + if (params.length != 1) return null; + final Result result = params[0].calculateResult(context); + if (result == null) return null; + + PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); + if (result instanceof PsiTypeResult) { + PsiType type = ((PsiTypeResult) result).getType(); + if (type instanceof PsiArrayType) { + return new PsiTypeResult(((PsiArrayType) type).getComponentType(), PsiManager.getInstance(context.getProject())); + } + } + + PsiExpression expr = MacroUtil.resultToPsiExpression(result, context); + PsiType type; + if (expr == null) { + type = MacroUtil.resultToPsiType(result, context); + } + else{ + type = expr.getType(); + } + if (type instanceof PsiArrayType) { + return new PsiTypeResult(((PsiArrayType) type).getComponentType(), PsiManager.getInstance(context.getProject())); + } + + return new PsiElementResult(null); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CurrentPackageMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CurrentPackageMacro.java new file mode 100644 index 00000000000..9e1dc2d554a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/CurrentPackageMacro.java @@ -0,0 +1,48 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + + +/** + * Created by IntelliJ IDEA. + * User: ven + * Date: May 13, 2003 + * Time: 8:36:42 PM + * To change this template use Options | File Templates. + */ +class CurrentPackageMacro implements Macro { + public String getName() { + return "currentPackage"; + } + + public String getDescription() { + return "currentPackage()"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + Project project = context.getProject(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + if (!(file instanceof PsiJavaFile)) return new TextResult (""); + PsiDocumentManager.getInstance(project).commitDocument(context.getEditor().getDocument()); + return new TextResult (((PsiJavaFile)file).getPackageName()); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return calculateResult(params, context); + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return new LookupItem[0]; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DecapitalizeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DecapitalizeMacro.java new file mode 100644 index 00000000000..537056efc42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DecapitalizeMacro.java @@ -0,0 +1,44 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; + +public class DecapitalizeMacro implements Macro { + + public String getName() { + return "decapitalize"; + } + + public String getDescription() { + return "decapitalize()"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + Result result = params[0].calculateResult(context); + return execute(result); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + Result result = params[0].calculateQuickResult(context); + return execute(result); + } + + private Result execute(Result result) { + if (result == null) return null; + String text = result.toString(); + if (text.length() > 0) { + text = text.substring(0, 1).toLowerCase() + text.substring(1, text.length()); + } + return new TextResult(text); + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DescendantClassesEnumMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DescendantClassesEnumMacro.java new file mode 100644 index 00000000000..ea1a0a18fba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/DescendantClassesEnumMacro.java @@ -0,0 +1,102 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.template.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.PsiSearchHelper; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; + +public class DescendantClassesEnumMacro implements Macro{ + public String getName() { + return "descendantClassesEnum"; + } + + public String getDescription() { + return "descendantClassesEnum(String)"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + final List classes = findDescendants(context, params); + if (classes == null || classes.size() == 0) return null; + Result[] results = calculateResults(classes); + + return results[0]; + } + + private Result[] calculateResults(final List classes) { + Result[] results = new Result[classes.size()]; + int i = 0; + + for (Iterator iterator = classes.iterator(); iterator.hasNext();) { + results[i++] = new PsiElementResult(iterator.next()); + } + return results; + } + + private List findDescendants(ExpressionContext context, Expression[] params) { + if (params == null || params.length == 0) return null; + PsiManager instance = PsiManager.getInstance(context.getProject()); + + final PsiClass myBaseClass = instance.findClass( + params[0].calculateResult(context).toString(), + GlobalSearchScope.allScope(context.getProject()) + ); + + if (myBaseClass!=null) { + PsiSearchHelper helper = instance.getSearchHelper(); + + final List classes = new ArrayList(); + + helper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + classes.add(element); + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, myBaseClass, GlobalSearchScope.projectScope(context.getProject()), true, true); + + return classes; + } + + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + final List classes = findDescendants(context, params); + if (classes == null || classes.size() == 0) return null; + Result[] results = calculateResults(classes); + + return results[0]; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + final List classes = findDescendants(context, params); + if (classes == null || classes.size() == 0) return null; + + LinkedHashSet set = new LinkedHashSet(); + boolean isFQN = params.length > 1 && params[1].calculateResult(context).toString().equals("true"); + + for (Iterator iterator = classes.iterator(); iterator.hasNext();) { + PsiClass object = iterator.next(); + LookupItemUtil.addLookupItem(set, (isFQN)?object.getQualifiedName():object.getName(), ""); + } + + return set.toArray(new LookupItem[set.size()]); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/EnumMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/EnumMacro.java new file mode 100644 index 00000000000..39eeb870c04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/EnumMacro.java @@ -0,0 +1,44 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.template.*; +import java.util.LinkedHashSet; + +public class EnumMacro implements Macro{ + public String getName() { + return "enum"; + } + + public String getDescription() { + return "enum(...)"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + if (params == null || params.length == 0) return null; + Result result = params[0].calculateResult(context); + return result; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + if (params == null || params.length == 0) return null; + Result result = params[0].calculateQuickResult(context); + return result; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + if (params == null || params.length ==0) return null; + LinkedHashSet set = new LinkedHashSet(); + + for(int i = 0; i < params.length; i++){ + Result object = params[i].calculateResult(context); + LookupItemUtil.addLookupItem(set, object.toString(), ""); + } + return set.toArray(new LookupItem[set.size()]); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ExpectedTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ExpectedTypeMacro.java new file mode 100644 index 00000000000..f2228ba7c71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/ExpectedTypeMacro.java @@ -0,0 +1,87 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.ExpectedTypesProvider; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.text.BlockSupport; +import com.intellij.util.IncorrectOperationException; + +import java.util.LinkedHashSet; + +public class ExpectedTypeMacro implements Macro{ + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.macro.ExpectedTypeMacro"); + + public String getName() { + return "expectedType"; + } + + public String getDescription() { + return "expectedType()"; + } + + public String getDefaultValue() { + return "A"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + PsiType[] types = getExpectedTypes(params, context); + if (types == null || types.length == 0) return null; + return new PsiTypeResult(types[0], PsiManager.getInstance(context.getProject())); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + PsiType[] types = getExpectedTypes(params, context); + if (types == null || types.length < 2) return null; + LinkedHashSet set = new LinkedHashSet(); + for(int i = 0; i < types.length; i++){ + LookupItemUtil.addLookupItem(set, types[i], ""); + } + return set.toArray(new LookupItem[set.size()]); + } + + private PsiType[] getExpectedTypes(Expression[] params, final ExpressionContext context) { + if (params.length != 0) return null; + + final Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiType[] types = null; + + int offset = context.getTemplateStartOffset(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + + PsiElement element = file.findElementAt(offset); + if (!(element instanceof PsiIdentifier)) { + PsiFile fileCopy = (PsiFile)file.copy(); + BlockSupport blockSupport = project.getComponent(BlockSupport.class); + try{ + blockSupport.reparseRange(fileCopy, offset, offset, "xxx)"); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + element = fileCopy.findElementAt(offset); + } + + if (element instanceof PsiIdentifier && element.getParent() instanceof PsiExpression) { + ExpectedTypeInfo[] infos = ExpectedTypesProvider.getInstance(project).getExpectedTypes((PsiExpression)element.getParent(), false); + if (infos.length > 0){ + types = new PsiType[infos.length]; + for(int i = 0; i < infos.length; i++) { + ExpectedTypeInfo info = infos[i]; + types[i] = info.getType(); + } + } + } + + return types; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/GuessElementTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/GuessElementTypeMacro.java new file mode 100644 index 00000000000..4dcc4a5e0b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/GuessElementTypeMacro.java @@ -0,0 +1,70 @@ + +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.guess.GuessManager; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; + +import java.util.LinkedHashSet; + +public class GuessElementTypeMacro implements Macro { + public String getName() { + return "guessElementType"; + } + + public String getDescription() { + return "guessElementType(Container)"; + } + + public String getDefaultValue() { + return "A"; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + PsiType[] types = guessTypes(params, context); + if (types == null || types.length == 0) return null; + return new PsiTypeResult(types[0], PsiManager.getInstance(context.getProject())); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + PsiType[] types = guessTypes(params, context); + if (types == null || types.length < 2) return null; + LinkedHashSet set = new LinkedHashSet(); + for(int i = 0; i < types.length; i++){ + LookupItemUtil.addLookupItem(set, types[i], ""); + } + return set.toArray(new LookupItem[set.size()]); + } + + private PsiType[] guessTypes(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + final Result result = params[0].calculateResult(context); + if (result == null) return null; + + Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiExpression expr = MacroUtil.resultToPsiExpression(result, context); + if (expr == null) return null; + PsiType[] types = GuessManager.getInstance(project).guessContainerElementType(expr, new TextRange(context.getTemplateStartOffset(), context.getTemplateEndOffset())); + for (int i = 0; i < types.length; i++) { + PsiType type = types[i]; + if (type instanceof PsiWildcardType) { + if (((PsiWildcardType)type).isExtends()) { + types[i] = ((PsiWildcardType)type).getBound(); + } else { + types[i] = PsiType.getJavaLangObject(expr.getManager(), expr.getResolveScope()); + } + } + } + return types; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableComponentTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableComponentTypeMacro.java new file mode 100644 index 00000000000..e42d75500fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableComponentTypeMacro.java @@ -0,0 +1,75 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; + +/** + * @author ven + */ +public class IterableComponentTypeMacro implements Macro { + public String getName() { + return "iterableComponentType"; + } + + public String getDescription() { + return "iterableComponentType(ArrayOrIterable)"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + if (params.length != 1) return null; + final Result result = params[0].calculateResult(context); + if (result == null) return null; + + Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiExpression expr = MacroUtil.resultToPsiExpression(result, context); + if (expr == null) return null; + PsiManager manager = expr.getManager(); + PsiType type = expr.getType(); + if (type instanceof PsiArrayType) { + return new PsiTypeResult(((PsiArrayType)type).getComponentType(), manager); + } + + if (type instanceof PsiClassType) { + PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics(); + PsiClass aClass = resolveResult.getElement(); + + if (aClass != null) { + PsiClass iterableClass = manager.findClass("java.lang.Iterable", aClass.getResolveScope()); + if (iterableClass != null) { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(iterableClass, aClass, resolveResult.getSubstitutor()); + if (substitutor != null) { + PsiType parameterType = substitutor.substitute(iterableClass.getTypeParameters()[0]); + if (parameterType != null) { + if (parameterType instanceof PsiWildcardType) { + if (((PsiWildcardType)parameterType).isExtends()) { + return new PsiTypeResult(((PsiWildcardType)parameterType).getBound(), manager); + } + else return null; + } + return new PsiTypeResult(parameterType, manager); + } + } + } + } + } + + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return calculateResult(params, context); + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return new LookupItem[0]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableVariableMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableVariableMacro.java new file mode 100644 index 00000000000..096165d5863 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/IterableVariableMacro.java @@ -0,0 +1,45 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.template.Expression; +import com.intellij.codeInsight.template.ExpressionContext; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import java.util.ArrayList; + +/** + * @author ven + */ +public class IterableVariableMacro extends VariableTypeMacroBase { + public String getName() { + return "iterableVariable"; + } + + public String getDescription() { + return "iterableVariable()"; + } + + protected PsiVariable[] getVariables(Expression[] params, final ExpressionContext context) { + if (params.length != 0) return null; + + Project project = context.getProject(); + final int offset = context.getStartOffset(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final ArrayList array = new ArrayList(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + PsiVariable[] variables = MacroUtil.getVariablesVisibleAt(place, ""); + PsiType iterableType = PsiManager.getInstance(project).getElementFactory().createTypeByFQClassName("java.lang.Iterable", file.getResolveScope()); + for(int i = 0; i < variables.length; i++){ + PsiVariable var = variables[i]; + if (var.getParent() instanceof PsiForeachStatement && var.getParent().getTextRange().contains(offset)) { + continue; + } + PsiType type = var.getType(); + if (type instanceof PsiArrayType || iterableType.isAssignableFrom(type)){ + array.add(var); + } + } + return array.toArray(new PsiVariable[array.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/LineNumberMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/LineNumberMacro.java new file mode 100644 index 00000000000..743e53688eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/LineNumberMacro.java @@ -0,0 +1,33 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; + +public class LineNumberMacro implements Macro{ + public String getName() { + return "lineNumber"; + } + + public String getDescription() { + return "lineNumber()"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + final int offset = context.getStartOffset(); + int line = context.getEditor().offsetToLogicalPosition(offset).line + 1; + return new TextResult("" + line); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return calculateResult(params, context); + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return new LookupItem[0]; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroFactory.java new file mode 100644 index 00000000000..495c778e864 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroFactory.java @@ -0,0 +1,65 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.template.Macro; + +import java.util.Collection; +import java.util.Hashtable; + +public class MacroFactory { + private static Hashtable myMacroTable = null; + + public static Macro createMacro(String name) { + if(myMacroTable == null) { + init(); + } + + return myMacroTable.get(name); + } + + public static Macro[] getMacros() { + if(myMacroTable == null) { + init(); + } + + final Collection values = myMacroTable.values(); + return values.toArray(new Macro[values.size()]); + } + + private static void init() { + myMacroTable = new Hashtable(); + + register(new ArrayVariableMacro()); + register(new VariableOfTypeMacro()); + register(new ComponentTypeOfMacro()); + register(new SuggestVariableNameMacro()); + + register(new SuggestIndexNameMacro()); + register(new GuessElementTypeMacro()); + register(new ExpectedTypeMacro()); + register(new MethodNameMacro()); + + register(new ClassNameMacro()); + register(new QualifiedClassNameMacro()); + register(new LineNumberMacro()); + register(new EnumMacro()); + + register(new CapitalizeMacro()); + register(new DecapitalizeMacro()); + register(new CompleteMacro()); + register(new CompleteSmartMacro()); + + register(new ClassNameCompleteMacro()); + register(new CurrentPackageMacro()); + register(new RightSideTypeMacro()); + register(new CastToLeftSideTypeMacro()); + + register(new IterableVariableMacro()); + register(new IterableComponentTypeMacro()); + register(new DescendantClassesEnumMacro()); + } + + private static void register(Macro macro) { + myMacroTable.put(macro.getName(), macro); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroUtil.java new file mode 100644 index 00000000000..dcd5664f7bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MacroUtil.java @@ -0,0 +1,139 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.completion.proc.VariablesProcessor; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +class MacroUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.macro.MacroUtil"); + + public static PsiType resultToPsiType(Result result, ExpressionContext context){ + if (result instanceof PsiTypeResult) { + return ((PsiTypeResult) result).getType(); + } + Project project = context.getProject(); + String text = result.toString(); + if (text == null) return null; + PsiManager manager = PsiManager.getInstance(project); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + //-1: Hack to deal with stupid resolve + PsiElement place = file != null ? file.findElementAt(context.getStartOffset()) : null; + PsiDeclarationStatement decl = file != null ? (PsiDeclarationStatement) PsiTreeUtil.getParentOfType(place, PsiDeclarationStatement.class) : null; + if (decl != null) { + place = file.findElementAt(decl.getTextOffset() -1); + } + PsiElementFactory factory = manager.getElementFactory(); + try{ + return factory.createTypeFromText(text, place); + } + catch(IncorrectOperationException e){ + return null; + } + } + + public static PsiExpression resultToPsiExpression(Result result, ExpressionContext context){ + if (result instanceof PsiElementResult){ + PsiElement element = ((PsiElementResult)result).getElement(); + if (element instanceof PsiExpression){ + return (PsiExpression)element; + } + } + Project project = context.getProject(); + String text = result.toString(); + if (text == null) return null; + PsiManager manager = PsiManager.getInstance(project); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + //-1: Hack to deal with resolve algorithm + PsiElement place = file != null ? file.findElementAt(context.getStartOffset()) : null; + if (place != null) { + PsiElement parent = place.getParent(); + if (parent != null) { + PsiElement parentOfParent = parent.getParent(); + if (parentOfParent instanceof PsiDeclarationStatement) { + place = file.findElementAt(parentOfParent.getTextOffset() -1); + } + } + } + PsiElementFactory factory = manager.getElementFactory(); + try{ + return factory.createExpressionFromText(text, place); + } + catch(IncorrectOperationException e){ + return null; + } + } + + public static PsiExpression[] getStandardExpressions(PsiElement place) { + ArrayList array = new ArrayList(); + PsiElementFactory factory = place.getManager().getElementFactory(); + try { + array.add(factory.createExpressionFromText("true", null)); + array.add(factory.createExpressionFromText("false", null)); + + PsiElement scope = place; + boolean firstClass = true; + boolean static_flag = false; + while (scope != null) { + if (scope instanceof PsiModifierListOwner && ((PsiModifierListOwner)scope).getModifierList() != null){ + if(((PsiModifierListOwner)scope).hasModifierProperty(PsiModifier.STATIC)){ + static_flag = true; + } + } + if (scope instanceof PsiClass) { + PsiClass aClass = (PsiClass)scope; + + String name = aClass.getName(); + PsiExpression expr = null; + if(!static_flag){ + if (firstClass) { + expr = factory.createExpressionFromText("this", place); + } + else { + if (name != null) { + expr = factory.createExpressionFromText(name + ".this", place); + } + } + if (expr != null) { + array.add(expr); + } + } + firstClass = false; + if (aClass.hasModifierProperty(PsiModifier.STATIC)) break; + } + else if (scope instanceof PsiMember) { + if (((PsiMember)scope).hasModifierProperty(PsiModifier.STATIC)) break; + } + scope = scope.getParent(); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return (PsiExpression[])array.toArray(new PsiExpression[array.size()]); + } + + public static PsiVariable[] getVariablesVisibleAt(final PsiElement place, String prefix) { + final List list = new ArrayList(); + VariablesProcessor varproc = new VariablesProcessor(prefix, true, list){ + public boolean execute(PsiElement pe, PsiSubstitutor substitutor) { + if(!(pe instanceof PsiField) || PsiUtil.isAccessible(((PsiField)pe), place, null)) return super.execute(pe, substitutor); + return true; + } + }; + PsiScopesUtil.treeWalkUp(varproc, place, null); + return varproc.getResultsAsArray(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MethodNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MethodNameMacro.java new file mode 100644 index 00000000000..97a193dc3ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/MethodNameMacro.java @@ -0,0 +1,51 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +public class MethodNameMacro implements Macro { + + public String getName() { + return "methodName"; + } + + public String getDescription() { + return "methodName()"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + Project project = context.getProject(); + int templateStartOffset = context.getTemplateStartOffset(); + final int offset = templateStartOffset > 0 ? context.getTemplateStartOffset() - 1 : context.getTemplateStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + while(place != null){ + if (place instanceof PsiMethod){ + return new TextResult(((PsiMethod)place).getName()); + } else if (place instanceof PsiClassInitializer) { + return ((PsiClassInitializer) place).hasModifierProperty(PsiModifier.STATIC) ? + new TextResult("'static initializer'") : + new TextResult("'instance initializer'"); + } + place = place.getParent(); + } + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/QualifiedClassNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/QualifiedClassNameMacro.java new file mode 100644 index 00000000000..f6b8bf54cbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/QualifiedClassNameMacro.java @@ -0,0 +1,49 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +public class QualifiedClassNameMacro implements Macro { + + public String getName() { + return "qualifiedClassName"; + } + + public String getDescription() { + return "qualifiedClassName()"; + } + + public String getDefaultValue() { + return ""; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + Project project = context.getProject(); + int templateStartOffset = context.getTemplateStartOffset(); + final int offset = templateStartOffset > 0 ? context.getTemplateStartOffset() - 1 : context.getTemplateStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + while(place != null){ + if (place instanceof PsiClass && !(place instanceof PsiAnonymousClass) && !(place instanceof PsiTypeParameter)){ + final PsiClass psiClass = ((PsiClass)place); + return new TextResult(psiClass.getQualifiedName()); + } + place = place.getParent(); + } + + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/RightSideTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/RightSideTypeMacro.java new file mode 100644 index 00000000000..ebe713f425f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/RightSideTypeMacro.java @@ -0,0 +1,57 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.RefactoringUtil; + + +/** + * @author ven + */ +public class RightSideTypeMacro implements Macro { + public String getName() { + return "rightSideType"; + } + + public String getDescription() { + return "rightSideType()"; + } + + public String getDefaultValue() { + return "A"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + int offset = context.getStartOffset(); + Project project = context.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement element = file.findElementAt(offset); + element = PsiTreeUtil.getParentOfType(element, new Class[] {PsiAssignmentExpression.class, PsiVariable.class}); + if (element instanceof PsiAssignmentExpression) { + PsiAssignmentExpression assignment = (PsiAssignmentExpression) element; + PsiExpression rhs = assignment.getRExpression(); + if (rhs == null) return null; + return new PsiTypeResult(rhs.getType(), rhs.getManager()); + } else if (element instanceof PsiVariable) { + PsiVariable var = (PsiVariable) element; + PsiExpression initializer = var.getInitializer(); + if (initializer == null) return null; + PsiType type = RefactoringUtil.getTypeByExpression(initializer); + if (type == null) return null; + return new PsiTypeResult(type, initializer.getManager()); + } + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return new LookupItem[0]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java new file mode 100644 index 00000000000..3fd8fe12124 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java @@ -0,0 +1,64 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +public class SuggestIndexNameMacro implements Macro{ + public String getName() { + return "suggestIndexName"; + } + + public String getDescription() { + return "suggestIndexName()"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, final ExpressionContext context) { + if (params.length != 0) return null; + + final Project project = context.getProject(); + final int offset = context.getStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + PsiVariable[] vars = MacroUtil.getVariablesVisibleAt(place, ""); + ChooseLetterLoop: + for(char letter = 'i'; letter <= 'z'; letter++){ + for(int i = 0; i < vars.length; i++) { + PsiVariable var = vars[i]; + PsiIdentifier identifier = var.getNameIdentifier(); + if (place.equals(identifier)) continue; + if (var instanceof PsiLocalVariable) { + PsiElement parent = var.getParent(); + if (parent instanceof PsiDeclarationStatement) { + if (PsiTreeUtil.isAncestor(parent, place, false) && + var.getTextRange().getStartOffset() > place.getTextRange().getStartOffset()) continue; + } + } + String name = identifier.getText(); + if (name.length() == 1 && name.charAt(0) == letter){ + continue ChooseLetterLoop; + } + } + return new TextResult("" + letter); + } + + return null; + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, ExpressionContext context) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java new file mode 100644 index 00000000000..cfca5f0d360 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java @@ -0,0 +1,75 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.template.*; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiVariable; + +import java.util.Arrays; +import java.util.LinkedList; + +public class SuggestVariableNameMacro implements Macro { + + public String getName() { + return "suggestVariableName"; + } + + public String getDescription() { + return "suggestVariableName()"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + String[] names = getNames(context); + if (names == null || names.length == 0) return null; + return new TextResult(names[0]); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + String[] names = getNames(context); + if (names == null || names.length < 2) return null; + LookupItem[] items = new LookupItem[names.length]; + for(int i = 0; i < names.length; i++) { + String name = names[i]; + items[i] = new LookupItem(name, name); + } + return items; + } + + private String[] getNames (final ExpressionContext context) { + String[] names = ExpressionUtil.getNames(context); + if (names == null || names.length == 0) return names; + PsiFile file = PsiDocumentManager.getInstance(context.getProject()).getPsiFile(context.getEditor().getDocument()); + PsiElement e = file.findElementAt(context.getStartOffset()); + PsiVariable[] vars = MacroUtil.getVariablesVisibleAt(e, ""); + LinkedList namesList = new LinkedList(Arrays.asList(names)); + for (int i = 0; i < vars.length; i++) { + if (e.equals(vars[i].getNameIdentifier())) continue; + namesList.remove(vars[i].getName()); + } + + if (namesList.size() == 0) { + String name = names[0]; + index: for (int j = 1; ; j++) { + String name1 = name + j; + for (int i = 0; i < vars.length; i++) { + PsiVariable var = vars[i]; + if (name1.equals(var.getName()) && !var.getNameIdentifier().equals(e)) continue index; + } + return new String[] {name1}; + } + } + + return (String[]) namesList.toArray(new String[namesList.size()]); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableOfTypeMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableOfTypeMacro.java new file mode 100644 index 00000000000..75d2c0e368b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableOfTypeMacro.java @@ -0,0 +1,93 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +import java.util.ArrayList; +import java.util.LinkedHashSet; + +public class VariableOfTypeMacro implements Macro { + + public String getName() { + return "variableOfType"; + } + + public String getDescription() { + return "variableOfType(Type)"; + } + + public String getDefaultValue() { + return "a"; + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + final PsiElement[] vars = getVariables(params, context); + if (vars == null || vars.length == 0) return null; + return new PsiElementResult(vars[0]); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + final PsiElement[] vars = getVariables(params, context); + if (vars == null || vars.length < 2) return null; + final LinkedHashSet set = new LinkedHashSet(); + for(int i = 0; i < vars.length; i++){ + LookupItemUtil.addLookupItem(set, vars[i], ""); + } + return (LookupItem[])set.toArray(new LookupItem[set.size()]); + } + + private PsiElement[] getVariables(Expression[] params, final ExpressionContext context) { + if (params.length != 1) return null; + final Result result = params[0].calculateResult(context); + if (result == null) return null; + + Project project = context.getProject(); + final int offset = context.getStartOffset(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final ArrayList array = new ArrayList(); + PsiType type = MacroUtil.resultToPsiType(result, context); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); + PsiElement place = file.findElementAt(offset); + + PsiVariable[] variables = MacroUtil.getVariablesVisibleAt(place, ""); + PsiManager manager = PsiManager.getInstance(project); + for(int i = 0; i < variables.length; i++){ + PsiVariable var = variables[i]; + + if (var instanceof PsiField && ((PsiField)var).hasModifierProperty(PsiModifier.STATIC)) { + PsiClass varClass = ((PsiField)var).getContainingClass(); + PsiClass placeClass = PsiTreeUtil.getParentOfType(place, PsiClass.class); + if (!manager.areElementsEquivalent(varClass, placeClass)) continue; + } else if (var instanceof PsiLocalVariable) { + if (var.getParent() instanceof PsiDeclarationStatement && var.getParent().getTextRange().contains(offset)) { + continue; + } + } + + PsiType type1 = var.getType(); + if (type == null || type.isAssignableFrom(type1)){ + array.add(variables[i]); + } + } + + PsiExpression[] expressions = MacroUtil.getStandardExpressions(place); + for(int i = 0; i < expressions.length; i++){ + PsiExpression expr = expressions[i]; + PsiType type1 = expr.getType(); + if (type == null || type1 != null && type.isAssignableFrom(type1)){ + array.add(expr); + } + } + return (PsiElement[])array.toArray(new PsiElement[array.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableTypeMacroBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableTypeMacroBase.java new file mode 100644 index 00000000000..175648240b3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInsight/template/macro/VariableTypeMacroBase.java @@ -0,0 +1,40 @@ +package com.intellij.codeInsight.template.macro; + +import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.psi.PsiVariable; + +import java.util.LinkedHashSet; + +/** + * @author ven + */ +public abstract class VariableTypeMacroBase implements Macro { + protected abstract PsiVariable[] getVariables(Expression[] params, final ExpressionContext context); + + public LookupItem[] calculateLookupItems(Expression[] params, final ExpressionContext context) { + final PsiVariable[] vars = getVariables(params, context); + if (vars == null || vars.length < 2) return null; + LinkedHashSet set = new LinkedHashSet(); + for(int i = 0; i < vars.length; i++){ + LookupItemUtil.addLookupItem(set, vars[i], ""); + } + return (LookupItem[]) set.toArray(new LookupItem[set.size()]); + } + + public Result calculateResult(Expression[] params, ExpressionContext context) { + final PsiVariable[] vars = getVariables(params, context); + if (vars == null || vars.length == 0) return null; + return new PsiElementResult(vars[0]); + } + + public Result calculateQuickResult(Expression[] params, ExpressionContext context) { + return null; + } + + public String getDefaultValue() { + return "a"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionDiff.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionDiff.java new file mode 100644 index 00000000000..c929ae665b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionDiff.java @@ -0,0 +1,122 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 21, 2002 + * Time: 7:36:28 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.HashMap; +import org.jdom.Document; +import org.jdom.Element; + +import java.io.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class InspectionDiff { + private static HashMap ourFileToProblem; + + public static void main(String[] args) { + if (args.length != 3 && args.length != 2) { + System.out.println("Required parameters: []"); + } + + String oldPath = args[0]; + String newPath = args[1]; + String outPath = args.length == 3 ? args[2] : null; + + + try { + InputStream oldStream = new BufferedInputStream(new FileInputStream(oldPath)); + InputStream newStream = new BufferedInputStream(new FileInputStream(newPath)); + + Document oldDoc = JDOMUtil.loadDocument(oldStream); + Document newDoc = JDOMUtil.loadDocument(newStream); + + OutputStream outStream = System.out; + if (outPath != null) { + outStream = new BufferedOutputStream(new FileOutputStream(outPath)); + } + + Document delta = createDelta(oldDoc, newDoc); + JDOMUtil.writeDocument(delta, outStream, "\n"); + } catch (Exception e) { + System.out.println(e); + e.printStackTrace(); + } + } + + private static Document createDelta(Document oldDoc, Document newDoc) { + Element oldRoot = oldDoc.getRootElement(); + Element newRoot = newDoc.getRootElement(); + + + ourFileToProblem = new HashMap(); + List newProblems = newRoot.getChildren("problem"); + for (Iterator iterator = newProblems.iterator(); iterator.hasNext();) { + Element newProblem = (Element) iterator.next(); + addProblem(newProblem); + } + + List oldProblems = oldRoot.getChildren("problem"); + for (Iterator iterator = oldProblems.iterator(); iterator.hasNext();) { + Element oldProblem = (Element) iterator.next(); + removeIfEquals(oldProblem); + } + + Element root = new Element("problems"); + Document delta = new Document(root); + + for (Iterator iterator = ourFileToProblem.values().iterator(); iterator.hasNext();) { + ArrayList fileList = (ArrayList) iterator.next(); + if (fileList != null) { + for (int i = 0; i < fileList.size(); i++) { + Element element = (Element) fileList.get(i); + root.addContent((Element) element.clone()); + } + } + } + + return delta; + } + + private static void removeIfEquals(Element problem) { + String fileName = problem.getChildText("file"); + ArrayList problemList = (ArrayList) ourFileToProblem.get(fileName); + if (problemList != null) { + Element[] problems = (Element[]) problemList.toArray(new Element[problemList.size()]); + for (int i = 0; i < problems.length; i++) { + Element toCheck = problems[i]; + if (equals(problem, toCheck)) problemList.remove(toCheck); + } + } + } + + private static void addProblem(Element problem) { + String fileName = problem.getChildText("file"); + ArrayList problemList = (ArrayList) ourFileToProblem.get(fileName); + if (problemList == null) { + problemList = new ArrayList(); + ourFileToProblem.put(fileName, problemList); + } + problemList.add(problem); + } + + private static boolean equals(Element oldProblem, Element newProblem) { + if (!Comparing.equal(oldProblem.getChildText("class"), newProblem.getChildText("class"))) return false; + if (!Comparing.equal(oldProblem.getChildText("field"), newProblem.getChildText("field"))) return false; + if (!Comparing.equal(oldProblem.getChildText("method"), newProblem.getChildText("method"))) return false; + if (!Comparing.equal(oldProblem.getChildText("constructor"), newProblem.getChildText("constructor"))) return false; + if (!Comparing.equal(oldProblem.getChildText("interface"), newProblem.getChildText("interface"))) return false; + if (!Comparing.equal(oldProblem.getChildText("problem_class"), newProblem.getChildText("problem_class"))) return false; + if (!Comparing.equal(oldProblem.getChildText("description"), newProblem.getChildText("description"))) return false; + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionMain.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionMain.java new file mode 100644 index 00000000000..a2db0918715 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/InspectionMain.java @@ -0,0 +1,80 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 23, 2002 + * Time: 5:20:01 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection; + +import com.intellij.codeInspection.ex.InspectionApplication; +import com.intellij.ide.license.AuthorizationAction; +import com.intellij.ide.license.impl.InspectionLicense; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.licensecommon.license.LicenseData; + +public class InspectionMain { + public static void main(String[] args) { + PluginManager.main(args, InspectionMain.class.getName(), "start"); + } + + protected static void start(final String[] args) { + if (!com.intellij.idea.Main.checkStartupPossible()) { + System.exit(-1); + } + InspectionLicense.getInstance().startUp(new AuthorizationAction() { + public void proceed(LicenseData license) { + if (args.length < 3) { + printHelp(); + } + + System.setProperty("idea.load.plugins.category", "inspection"); + final InspectionApplication application = new InspectionApplication(); + + application.myProjectPath = args[0]; + application.myProfilePath = args[1]; + application.myOutPath = args[2]; + + try { + for (int i = 3; i < args.length; i++) { + String arg = args[i]; + if ("-d".equals(arg)) { + application.mySourceDirectory = args[++i]; + } + else if ("-v0".equals(arg)) { + application.setVerboseLevel(0); + } + else if ("-v1".equals(arg)) { + application.setVerboseLevel(1); + } + else if ("-v2".equals(arg)) { + application.setVerboseLevel(2); + } + else { + printHelp(); + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + printHelp(); + } + + application.startup(); + } + + public void cancel() { + } + }); + } + + + public static void printHelp() { + System.out.println("Expected parameters: []\n" + + "Avaliable options are:\n" + + "-d -- directory to be inspected. Optional. Whole project is inspected by default.\n" + + "-v[0|1|2] -- verbose level. 0 - silent, 1 - verbose, 2 - most verbose."); + System.exit(1); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/CodeInspectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/CodeInspectionAction.java new file mode 100644 index 00000000000..117b7c46d01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/CodeInspectionAction.java @@ -0,0 +1,19 @@ +package com.intellij.codeInspection.actions; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.analysis.BaseAnalysisAction; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; + +public class CodeInspectionAction extends BaseAnalysisAction { + public CodeInspectionAction() { + super(AnalysisScope.SOURCE_JAVA_FILES, "Inspection", "Inspect", "Inspection"); + } + + protected void analyze(Project project, AnalysisScope scope) { + FileDocumentManager.getInstance().saveAllDocuments(); + ((InspectionManagerEx) InspectionManager.getInstance(project)).doInspections(scope, true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java new file mode 100644 index 00000000000..287a1f81087 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java @@ -0,0 +1,118 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 23, 2002 + * Time: 7:14:29 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.actions; + +import com.intellij.codeInspection.offlineViewer.OfflineViewerHandler; +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.util.Icons; +import org.jdom.Document; +import org.jdom.JDOMException; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileView; +import java.io.File; +import java.io.IOException; + +public class ViewOfflineResultsAction extends AnAction { + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + presentation.setVisible(ActionPlaces.MAIN_MENU.equals(event.getPlace())); + } + + public void actionPerformed(AnActionEvent event) { + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + String lastFilePath=getLastFilePath(project); + String path = lastFilePath != null ? lastFilePath : RecentProjectsManager.getInstance().getLastProjectPath(); + JFileChooser fileChooser = new JFileChooser(path); + FileView fileView = new FileView() { + public Icon getIcon(File f) { + if (f.isDirectory()) return super.getIcon(f); + if (f.getName().endsWith(".ipr")) { + return Icons.PROJECT_ICON; + } + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(f.getName()); + return fileType.getIcon(); + } + }; + + fileChooser.setFileView(fileView); + fileChooser.setAcceptAllFileFilterUsed(false); + fileChooser.setDialogTitle("Open File"); + + class TypeFilter extends FileFilter { + private FileType myType; + + + public TypeFilter() { + myType = StdFileTypes.XML; + myDescription = myType.getDescription(); + } + + public boolean accept(File f) { + if (f.isDirectory()) return true; + FileType type = FileTypeManager.getInstance().getFileTypeByFileName(f.getName()); + return myType == type; + } + + public String getDescription() { + return myDescription; + } + + private String myDescription; + } + + fileChooser.addChoosableFileFilter(new TypeFilter()); + + if (fileChooser.showOpenDialog(WindowManager.getInstance().suggestParentWindow(project)) != JFileChooser.APPROVE_OPTION) return; + File file = fileChooser.getSelectedFile(); + if (file == null) return; + setLastFilePath(project, file.getParent()); + + Document doc; + try { + doc = JDOMUtil.loadDocument(file); + ((ProjectEx) project).getExpandMacroReplacements().substitute(doc.getRootElement(), SystemInfo.isFileSystemCaseSensitive); + } catch (JDOMException e) { + Messages.showMessageDialog(project, "Error parsing the results file", "Error", Messages.getErrorIcon()); + return; + } catch (IOException e) { + Messages.showMessageDialog(project, "Error loading the results file", "Error", Messages.getErrorIcon()); + return; + } + + new OfflineViewerHandler(project).execute(doc); + } + + private static String getLastFilePath(Project project) { + return PropertiesComponent.getInstance(project).getValue("last_opened_file_path"); + } + + private static void setLastFilePath(Project project,String path) { + PropertiesComponent.getInstance(project).setValue("last_opened_file_path",path); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java new file mode 100644 index 00000000000..0bdee99de84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java @@ -0,0 +1,248 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 24, 2001 + * Time: 2:46:32 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.canBeFinal; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.reference.*; +import com.intellij.codeInspection.util.RefFilter; +import com.intellij.codeInspection.util.XMLExportUtl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; + +public class CanBeFinalInspection extends FilteringInspectionTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.canBeFinal.CanBeFinalInspection"); + + public boolean REPORT_CLASSES = true; + public boolean REPORT_METHODS = true; + public boolean REPORT_FIELDS = true; + private QuickFixAction[] myQuickFixActions; + public static final String DISPLAY_NAME = "Declaration can have final modifier"; + public static final String SHORT_NAME = "CanBeFinal"; + private CanBeFinalFilter myFilter; + private CanBeFinalComposer myComposer; + + public CanBeFinalInspection() { + myQuickFixActions = new QuickFixAction[]{new AcceptSuggested()}; + } + + private class OptionsPanel extends JPanel { + private final JCheckBox myReportClassesCheckbox; + private final JCheckBox myReportMethodsCheckbox; + private final JCheckBox myReportFieldsCheckbox; + + private OptionsPanel() { + super(new GridBagLayout()); + + GridBagConstraints gc = new GridBagConstraints(); + gc.weighty = 0; + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + gc.anchor = GridBagConstraints.NORTHWEST; + + + myReportClassesCheckbox = new JCheckBox("Report classes"); + myReportClassesCheckbox.setSelected(REPORT_CLASSES); + myReportClassesCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myReportClassesCheckbox.isSelected(); + REPORT_CLASSES = selected; + } + }); + gc.gridy = 0; + add(myReportClassesCheckbox, gc); + + myReportMethodsCheckbox = new JCheckBox("Report methods"); + myReportMethodsCheckbox.setSelected(REPORT_METHODS); + myReportMethodsCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myReportMethodsCheckbox.isSelected(); + REPORT_METHODS = selected; + } + }); + gc.gridy++; + add(myReportMethodsCheckbox, gc); + + myReportFieldsCheckbox = new JCheckBox("Report fields"); + myReportFieldsCheckbox.setSelected(REPORT_FIELDS); + myReportFieldsCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myReportFieldsCheckbox.isSelected(); + REPORT_FIELDS = selected; + } + }); + + gc.weighty = 1; + gc.gridy++; + add(myReportFieldsCheckbox, gc); + } + } + + public boolean isReportClasses() { + return REPORT_CLASSES; + } + + public boolean isReportMethods() { + return REPORT_METHODS; + } + + public boolean isReportFields() { + return REPORT_FIELDS; + } + + public JComponent createOptionsPanel() { + return new OptionsPanel(); + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + } + + public boolean queryExternalUsagesRequests() { + final CanBeFinalFilter filter = new CanBeFinalFilter(this); + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (filter.accepts(refElement)) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + if (!refMethod.isStatic() && refMethod.getAccessModifier() != PsiModifier.PRIVATE && + !(refMethod instanceof RefImplicitConstructor)) { + getManager().enqueueDerivedMethodsProcessing(refMethod, new InspectionManagerEx.DerivedMethodsProcessor() { + public boolean process(PsiMethod derivedMethod) { + refMethod.setCanBeFinal(false); + return false; + } + }); + } + } + + public void visitClass(final RefClass refClass) { + if (!refClass.isAnonymous()) { + getManager().enqueueDerivedClassesProcessing(refClass, new InspectionManagerEx.DerivedClassesProcessor() { + public boolean process(PsiClass inheritor) { + refClass.setCanBeFinal(false); + return false; + } + }); + } + } + + public void visitField(final RefField refField) { + getManager().enqueueFieldUsagesProcessor(refField, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + PsiElement expression = psiReference.getElement(); + if (expression instanceof PsiReferenceExpression && PsiUtil.isAccessedForWriting((PsiExpression)expression)) { + refField.setCanBeFinal(false); + return false; + } + return true; + } + }); + } + }); + } + } + }); + + return false; + } + + public RefFilter getFilter() { + if (myFilter == null) { + myFilter = new CanBeFinalFilter(this); + } + return myFilter; + } + + public HTMLComposer getComposer() { + if (myComposer == null) { + myComposer = new CanBeFinalComposer(this); + } + return myComposer; + } + + public void exportResults(final Element parentNode) { + final CanBeFinalFilter filter = new CanBeFinalFilter(this); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (filter.accepts(refElement)) { + Element element = XMLExportUtl.createElement(refElement, parentNode, -1); + Element problemClassElement = new Element("problem_class"); + problemClassElement.addContent("can be final"); + element.addContent(problemClassElement); + + Element descriptionElement = new Element("description"); + descriptionElement.addContent("declaration can have final modifier"); + element.addContent(descriptionElement); + } + } + }); + } + + public QuickFixAction[] getQuickFixes() { + return myQuickFixActions; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[]{InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return SHORT_NAME; + } + + private static void makeFinal(PsiModifierListOwner psiElement, RefElement refElement) { + try { + if (psiElement instanceof PsiVariable) { + ((PsiVariable)psiElement).normalizeDeclaration(); + } + psiElement.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + + refElement.setIsFinal(true); + } + + private class AcceptSuggested extends QuickFixAction { + private AcceptSuggested() { + super("Accept Suggested Final Modifier", CanBeFinalInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiModifierListOwner psiElement = refElement.getElement(); + + if (psiElement == null) continue; + makeFinal(psiElement, refElement); + } + + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlow.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlow.java new file mode 100644 index 00000000000..dce32de474d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlow.java @@ -0,0 +1,76 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 11, 2002 + * Time: 3:05:34 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.instructions.FlushVariableInstruction; +import com.intellij.codeInspection.dataFlow.instructions.Instruction; +import com.intellij.codeInspection.dataFlow.instructions.ReturnInstruction; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiVariable; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Stack; + +public class ControlFlow { + private final ArrayList myInstructions = new ArrayList(); + private final HashMap myElementToStartOffsetMap = new HashMap(); + private final HashMap myElementToEndOffsetMap = new HashMap(); + private final Stack myElementStack = new Stack(); + private DfaVariableValue[] myFields; + + public Instruction[] getInstructions(){ + addInstruction(new ReturnInstruction()); + return (Instruction[])myInstructions.toArray(new Instruction[myInstructions.size()]); + } + + public int getInstructionCount() { + return myInstructions.size(); + } + + public void startElement(PsiElement psiElement) { + myElementStack.push(psiElement); + myElementToStartOffsetMap.put(psiElement, new Integer(myInstructions.size())); + } + + public void finishElement(PsiElement psiElement) { + myElementToEndOffsetMap.put(psiElement, new Integer(myInstructions.size())); + } + + public void addInstruction(Instruction instruction) { + instruction.setIndex(myInstructions.size()); + myInstructions.add(instruction); + } + + public void removeVariable(PsiVariable variable) { + DfaVariableValue var = DfaVariableValue.Factory.getInstance().create(variable, false); + addInstruction(new FlushVariableInstruction(var)); + } + + public int getStartOffset(PsiElement element){ + Integer value = (Integer)myElementToStartOffsetMap.get(element); + if (value == null) return -1; + return value.intValue(); + } + + public int getEndOffset(PsiElement element){ + Integer value = (Integer)myElementToEndOffsetMap.get(element); + if (value == null) return -1; + return value.intValue(); + } + + public DfaVariableValue[] getFields() { + return myFields; + } + + public void setFields(DfaVariableValue[] fields) { + myFields = fields; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java new file mode 100644 index 00000000000..978e86a2f13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -0,0 +1,1155 @@ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInspection.dataFlow.instructions.*; +import com.intellij.codeInspection.dataFlow.value.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Stack; + +class ControlFlowAnalyzer extends PsiElementVisitor { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer"); + private static final int NOT_FOUND = -10; + private ControlFlow myPass1Flow; + private ControlFlow myPass2Flow; + private ControlFlow myCurrentFlow; + private int myPassNumber; + private HashSet myFields; + private Stack myCatchStack; + private PsiType myRuntimeException; + + private static class CantAnalyzeException extends RuntimeException { + } + + public ControlFlow buildControlFlow(PsiElement codeFragment) { + if (codeFragment == null) return null; + + myRuntimeException = PsiType.getJavaLangRuntimeException(codeFragment.getManager(), codeFragment.getResolveScope()); + myFields = new HashSet(); + myCatchStack = new Stack(); + myPassNumber = 1; + myPass1Flow = new ControlFlow(); + myCurrentFlow = myPass1Flow; + + try { + codeFragment.accept(this); + } + catch (CantAnalyzeException e) { + return null; + } + + myPassNumber = 2; + myPass2Flow = new ControlFlow(); + myCurrentFlow = myPass2Flow; + + codeFragment.accept(this); + + myPass2Flow.setFields(myFields.toArray(new DfaVariableValue[myFields.size()])); + return myPass2Flow; + } + + private boolean myRecursionStopper = false; + + private void addInstruction(Instruction instruction) { + ProgressManager.getInstance().checkCanceled(); + + if (!myRecursionStopper) { + myRecursionStopper = true; + try { + //Add extra conditional goto in order to handle possible runtime exceptions that could be caught by finally block. + if (instruction instanceof BranchingInstruction || instruction instanceof AssignInstruction || + instruction instanceof MethodCallInstruction) { + addConditionalRuntimeThrow(); + } + } + finally { + myRecursionStopper = false; + } + } + + myCurrentFlow.addInstruction(instruction); + } + + private int getEndOffset(PsiElement element) { + return myPassNumber == 2 ? myPass1Flow.getEndOffset(element) : 0; + } + + private int getStartOffset(PsiElement element) { + return myPassNumber == 2 ? myPass1Flow.getStartOffset(element) : 0; + } + + private void startElement(PsiElement element) { + myCurrentFlow.startElement(element); + } + + private void finishElement(PsiElement element) { + myCurrentFlow.finishElement(element); + } + + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + startElement(expression); + + try { + PsiExpression lExpr = expression.getLExpression(); + PsiExpression rExpr = expression.getRExpression(); + + if (lExpr == null || rExpr == null) { + pushUnknown(); + return; + } + + lExpr.accept(this); + + IElementType op = expression.getOperationSign().getTokenType(); + boolean isBoolean = expression.getType() == PsiType.BOOLEAN; + if (op == JavaTokenType.EQ) { + rExpr.accept(this); + } + else if (op == JavaTokenType.ANDEQ) { + if (isBoolean) { + generateAndExpression(lExpr, rExpr); + } + else { + generateDefaultBinop(lExpr, rExpr); + } + } + else if (op == JavaTokenType.OREQ) { + if (isBoolean) { + generateOrExpression(lExpr, rExpr); + } + else { + generateDefaultBinop(lExpr, rExpr); + } + } + else if (op == JavaTokenType.XOREQ) { + if (isBoolean) { + generateXorExpression(expression, lExpr, rExpr); + } + else { + generateDefaultBinop(lExpr, rExpr); + } + } + else { + generateDefaultBinop(lExpr, rExpr); + } + + if (lExpr instanceof PsiReferenceExpression) { + PsiReferenceExpression psiDestReference = (PsiReferenceExpression)lExpr; + PsiVariable psiDestVariable = DfaValueFactory.resolveVariable(psiDestReference); + if (psiDestVariable != null) { + addInstruction(new AssignInstruction()); + lExpr.accept(this); + return; + } + } + + addInstruction(new PopInstruction()); + addInstruction(new PopInstruction()); + lExpr.accept(this); + } + finally { + finishElement(expression); + } + } + + private void generateDefaultBinop(PsiExpression lExpr, PsiExpression rExpr) { + lExpr.accept(this); + rExpr.accept(this); + addInstruction(new BinopInstruction(null, null)); + } + + public void visitAssertStatement(PsiAssertStatement statement) { + startElement(statement); + final PsiExpression condition = statement.getAssertCondition(); + final PsiExpression description = statement.getAssertDescription(); + if (condition != null) { + condition.accept(this); + addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), false, condition)); + if (description != null) { + description.accept(this); + } + addInstruction(new ReturnInstruction()); + } + finishElement(statement); + } + + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + startElement(statement); + + PsiElement[] elements = statement.getDeclaredElements(); + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (element instanceof PsiClass) { + element.accept(this); + } + else if (element instanceof PsiVariable) { + PsiVariable variable = (PsiVariable)element; + PsiExpression initializer = variable.getInitializer(); + if (initializer != null) { + initializeVariable(variable, initializer); + } + } + } + + finishElement(statement); + } + + private void initializeVariable(PsiVariable variable, PsiExpression initializer) { + DfaVariableValue dfaVariable = DfaVariableValue.Factory.getInstance().create(variable, false); + addInstruction(new PushInstruction(dfaVariable)); + initializer.accept(this); + addInstruction(new AssignInstruction()); + } + + public void visitCodeBlock(PsiCodeBlock block) { + startElement(block); + + PsiStatement[] statements = block.getStatements(); + for (int i = 0; i < statements.length; i++) { + statements[i].accept(this); + } + + for (int i = 0; i < statements.length; i++) { + PsiStatement statement = statements[i]; + if (statement instanceof PsiDeclarationStatement) { + PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)statement; + PsiElement[] declarations = declarationStatement.getDeclaredElements(); + for (int j = 0; j < declarations.length; j++) { + PsiElement declaration = declarations[j]; + if (declaration instanceof PsiVariable) { + myCurrentFlow.removeVariable((PsiVariable)declaration); + } + } + } + } + + finishElement(block); + } + + public void visitBlockStatement(PsiBlockStatement statement) { + startElement(statement); + statement.getCodeBlock().accept(this); + finishElement(statement); + } + + public void visitBreakStatement(PsiBreakStatement statement) { + startElement(statement); + + PsiStatement exitedStatement = statement.findExitedStatement(); + + if (exitedStatement != null) { + int offset = myPass1Flow.getEndOffset(exitedStatement); + addInstruction(new GotoInstruction(offset)); + } + + finishElement(statement); + } + + public void visitContinueStatement(PsiContinueStatement statement) { + startElement(statement); + PsiStatement continuedStatement = statement.findContinuedStatement(); + if (continuedStatement != null) { + int offset = -1; + if (continuedStatement instanceof PsiForStatement) { + PsiStatement body = ((PsiForStatement)continuedStatement).getBody(); + offset = myPass1Flow.getEndOffset(body); + } + else if (continuedStatement instanceof PsiWhileStatement) { + PsiStatement body = ((PsiWhileStatement)continuedStatement).getBody(); + offset = myPass1Flow.getEndOffset(body); + } + else if (continuedStatement instanceof PsiDoWhileStatement) { + PsiStatement body = ((PsiDoWhileStatement)continuedStatement).getBody(); + offset = myPass1Flow.getEndOffset(body); + } + else if (continuedStatement instanceof PsiForeachStatement) { + PsiStatement body = ((PsiForeachStatement)continuedStatement).getBody(); + offset = myPass1Flow.getEndOffset(body); + } + Instruction instruction = offset != -1 + ? (Instruction)new GotoInstruction(offset) + : new EmptyInstruction(); + addInstruction(instruction); + } + finishElement(statement); + } + + public void visitDoWhileStatement(PsiDoWhileStatement statement) { + startElement(statement); + + PsiStatement body = statement.getBody(); + if (body == null) return; + body.accept(this); + PsiExpression condition = statement.getCondition(); + if (condition != null) { + condition.accept(this); + addInstruction(new ConditionalGotoInstruction(getStartOffset(statement), false, condition)); + } + + finishElement(statement); + } + + public void visitEmptyStatement(PsiEmptyStatement statement) { + startElement(statement); + finishElement(statement); + } + + public void visitExpressionStatement(PsiExpressionStatement statement) { + startElement(statement); + statement.getExpression().accept(this); + addInstruction(new PopInstruction()); + finishElement(statement); + } + + public void visitExpressionListStatement(PsiExpressionListStatement statement) { + startElement(statement); + PsiExpression[] expressions = statement.getExpressionList().getExpressions(); + for (int i = 0; i < expressions.length; i++) { + PsiExpression expr = expressions[i]; + expr.accept(this); + addInstruction(new PopInstruction()); + } + finishElement(statement); + } + + public void visitForeachStatement(PsiForeachStatement statement) { + startElement(statement); + final PsiParameter parameter = statement.getIterationParameter(); + final PsiExpression iteratedValue = statement.getIteratedValue(); + + if (iteratedValue != null) { + initializeVariable(parameter, iteratedValue); + addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), true, iteratedValue)); + } + + final PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + finishElement(statement); + myCurrentFlow.removeVariable(parameter); + } + + public void visitForStatement(PsiForStatement statement) { + final ArrayList declaredVariables = new ArrayList(); + startElement(statement); + + PsiStatement initialization = statement.getInitialization(); + if (initialization != null) { + initialization.accept(this); + initialization.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + PsiElement[] declaredElements = statement.getDeclaredElements(); + for (int i = 0; i < declaredElements.length; i++) { + PsiElement element = declaredElements[i]; + if (element instanceof PsiVariable) { + declaredVariables.add(element); + } + } + } + }); + } + + PsiExpression condition = statement.getCondition(); + if (condition != null) { + condition.accept(this); + } + else { + addInstruction(new PushInstruction(DfaConstValue.Factory.getInstance().getTrue())); + } + addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), true, condition)); + + PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + PsiStatement update = statement.getUpdate(); + if (update != null) { + update.accept(this); + } + + int offset = initialization != null + ? getEndOffset(initialization) + : getStartOffset(statement); + + addInstruction(new GotoInstruction(offset)); + finishElement(statement); + + for (int i = 0; i < declaredVariables.size(); i++) { + PsiVariable psiVariable = (PsiVariable)declaredVariables.get(i); + myCurrentFlow.removeVariable(psiVariable); + } + } + + public void visitIfStatement(PsiIfStatement statement) { + startElement(statement); + + PsiExpression condition = statement.getCondition(); + + PsiStatement thenStatement = statement.getThenBranch(); + PsiStatement elseStatement = statement.getElseBranch(); + + int offset = elseStatement != null + ? getStartOffset(elseStatement) + : getEndOffset(statement); + + if (condition != null) { + condition.accept(this); + addInstruction(new ConditionalGotoInstruction(offset, true, condition)); + } + + if (thenStatement != null) { + thenStatement.accept(this); + } + + if (elseStatement != null) { + offset = getEndOffset(statement); + Instruction instruction = new GotoInstruction(offset); + addInstruction(instruction); + elseStatement.accept(this); + } + + finishElement(statement); + } + + public void visitLabeledStatement(PsiLabeledStatement statement) { + startElement(statement); + PsiStatement childStatement = statement.getStatement(); + if (childStatement != null) { + childStatement.accept(this); + } + finishElement(statement); + } + + public void visitReturnStatement(PsiReturnStatement statement) { + startElement(statement); + + PsiExpression returnValue = statement.getReturnValue(); + if (returnValue != null) { + returnValue.accept(this); + addInstruction(new PopInstruction()); + } + + int finallyOffset = getFinallyOffset(); + if (finallyOffset != NOT_FOUND) { + addInstruction(new GosubInstruction(finallyOffset)); + } + addInstruction(new ReturnInstruction()); + finishElement(statement); + } + + public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) { + startElement(statement); + finishElement(statement); + } + + public void visitSwitchStatement(PsiSwitchStatement statement) { + startElement(statement); + PsiElementFactory psiFactory = statement.getManager().getElementFactory(); + PsiExpression caseExpression = statement.getExpression(); + + if (caseExpression != null && !(caseExpression instanceof PsiReferenceExpression)) { + caseExpression.accept(this); + addInstruction(new PopInstruction()); + } + + PsiCodeBlock body = statement.getBody(); + + if (body != null) { + PsiStatement[] statements = body.getStatements(); + PsiSwitchLabelStatement defaultLabel = null; + for (int i = 0; i < statements.length; i++) { + PsiStatement aStatement = statements[i]; + if (aStatement instanceof PsiSwitchLabelStatement) { + PsiSwitchLabelStatement psiLabelStatement = (PsiSwitchLabelStatement)aStatement; + if (psiLabelStatement.isDefaultCase()) { + defaultLabel = psiLabelStatement; + } + else { + try { + int offset = getStartOffset(aStatement); + PsiExpression caseValue = psiLabelStatement.getCaseValue(); + + if (caseExpression instanceof PsiReferenceExpression && + caseValue.getManager().getConstantEvaluationHelper().computeConstantExpression(caseValue) != null) { + PsiExpression psiComparison = psiFactory.createExpressionFromText( + caseExpression.getText() + "==" + caseValue.getText(), statement); + psiComparison.accept(this); + } + else { + pushUnknown(); + } + + addInstruction(new ConditionalGotoInstruction(offset, false, aStatement)); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + } + + int offset = defaultLabel != null ? getStartOffset(defaultLabel) : getEndOffset(body); + addInstruction(new GotoInstruction(offset)); + + body.accept(this); + } + + finishElement(statement); + } + + public void visitSynchronizedStatement(PsiSynchronizedStatement statement) { + startElement(statement); + + PsiExpression lock = statement.getLockExpression(); + if (lock != null) { + lock.accept(this); + addInstruction(new PopInstruction()); + } + + addInstruction(new FlushVariableInstruction(null)); + + PsiCodeBlock body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + finishElement(statement); + } + + public void visitThrowStatement(PsiThrowStatement statement) { + startElement(statement); + + PsiExpression exception = statement.getException(); + + if (exception != null) { + exception.accept(this); + addThrowCode(exception.getType()); + } + + finishElement(statement); + } + + private void addConditionalRuntimeThrow() { + for (int i = myCatchStack.size() - 1; i >= 0; i--) { + CatchDescriptor cd = myCatchStack.get(i); + if (cd.isFinally()) { + final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null); + pushUnknown(); + addInstruction(branch); + addInstruction(new GosubInstruction(cd.getJumpOffset())); + addInstruction(new ReturnInstruction()); + branch.setOffset(myCurrentFlow.getInstructionCount()); + } + else if (cd.getType() instanceof PsiClassType && + ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)cd.getType())) { + pushUnknown(); + final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null); + addInstruction(branch); + addInstruction(new PushInstruction(DfaNewValue.Factory.getInstance().create(myRuntimeException))); + addGotoCatch(cd); + branch.setOffset(myCurrentFlow.getInstructionCount()); + return; + } + } + } + + private void addThrowCode(PsiType exceptionClass) { + if (exceptionClass == null) return; + for (int i = myCatchStack.size() - 1; i >= 0; i--) { + CatchDescriptor cd = myCatchStack.get(i); + if (cd.isFinally()) { + addInstruction(new GosubInstruction(cd.getJumpOffset())); + } + else if (cd.getType().isAssignableFrom(exceptionClass)) { // Definite catch. + addGotoCatch(cd); + return; + } + else if (exceptionClass.isAssignableFrom(cd.getType())) { // Probable catch + addInstruction(new DupInstruction()); + pushUnknown(); + final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null); + addInstruction(branch); + addGotoCatch(cd); + branch.setOffset(myCurrentFlow.getInstructionCount()); + } + } + + addInstruction(new ReturnInstruction()); + } + + /** + * Exception is expected on the stack. + * + * @param cd + */ + private void addGotoCatch(CatchDescriptor cd) { + addInstruction(new PushInstruction(DfaVariableValue.Factory.getInstance().create(cd.getParameter(), false))); + addInstruction(new SwapInstruction()); + addInstruction(new AssignInstruction()); + addInstruction(new GotoInstruction(cd.getJumpOffset())); + } + + private int getFinallyOffset() { + for (int i = myCatchStack.size() - 1; i >= 0; i--) { + CatchDescriptor cd = myCatchStack.get(i); + if (cd.isFinally()) return cd.getJumpOffset(); + } + + return NOT_FOUND; + } + + class CatchDescriptor { + private final PsiType myType; + private PsiParameter myParameter; + private final PsiCodeBlock myBlock; + private final boolean myIsFinally; + + public CatchDescriptor(PsiCodeBlock finallyBlock) { + myType = null; + myBlock = finallyBlock; + myIsFinally = true; + } + + public CatchDescriptor(PsiParameter parameter, PsiCodeBlock catchBlock) { + myType = parameter.getType(); + myParameter = parameter; + myBlock = catchBlock; + myIsFinally = false; + } + + public PsiType getType() { + return myType; + } + + public boolean isFinally() { + return myIsFinally; + } + + public int getJumpOffset() { + return getStartOffset(myBlock); + } + + public PsiParameter getParameter() { return myParameter; } + } + + public void visitErrorElement(PsiErrorElement element) { + throw new CantAnalyzeException(); + } + + public void visitTryStatement(PsiTryStatement statement) { + startElement(statement); + PsiCodeBlock finallyBlock = statement.getFinallyBlock(); + + if (finallyBlock != null) { + myCatchStack.push(new CatchDescriptor(finallyBlock)); + } + + int catchesPushCount = 0; + PsiCatchSection[] sections = statement.getCatchSections(); + for (int i = 0; i < sections.length; i++) { + PsiCodeBlock catchBlock = sections[i].getCatchBlock(); + PsiParameter parameter = sections[i].getParameter(); + if (parameter != null && catchBlock != null && parameter.getType() instanceof PsiClassType && + !ExceptionUtil.isUncheckedException((PsiClassType)parameter.getType())) { + myCatchStack.push(new CatchDescriptor(parameter, catchBlock)); + catchesPushCount++; + } + else { + throw new CantAnalyzeException(); + } + } + + int endOffset = finallyBlock == null ? getEndOffset(statement) : getStartOffset(finallyBlock) - 2; + + PsiCodeBlock tryBlock = statement.getTryBlock(); + + if (tryBlock != null) { + tryBlock.accept(this); + } + + for (int i = 0; i < catchesPushCount; i++) myCatchStack.pop(); + + addInstruction(new GotoInstruction(endOffset)); + + for (int i = 0; i < sections.length; i++) { + sections[i].accept(this); + addInstruction(new GotoInstruction(endOffset)); + } + + if (finallyBlock != null) { + myCatchStack.pop(); + addInstruction(new GosubInstruction(getStartOffset(finallyBlock))); + addInstruction(new GotoInstruction(getEndOffset(statement))); + finallyBlock.accept(this); + addInstruction(new ReturnFromSubInstruction()); + } + + finishElement(statement); + } + + public void visitCatchSection(PsiCatchSection section) { + PsiCodeBlock catchBlock = section.getCatchBlock(); + if (catchBlock != null) catchBlock.accept(this); + } + + public void visitWhileStatement(PsiWhileStatement statement) { + startElement(statement); + + PsiExpression condition = statement.getCondition(); + + if (condition != null) { + condition.accept(this); + addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), true, condition)); + } + + PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + if (condition != null) { + addInstruction(new GotoInstruction(getStartOffset(statement))); + } + + finishElement(statement); + } + + public void visitExpressionList(PsiExpressionList list) { + startElement(list); + + PsiExpression[] expressions = list.getExpressions(); + for (int i = 0; i < expressions.length; i++) { + expressions[i].accept(this); + } + + finishElement(list); + } + + public void visitExpression(PsiExpression expression) { + startElement(expression); + pushUnknown(); + finishElement(expression); + } + + public void visitArrayAccessExpression(PsiArrayAccessExpression expression) { + //TODO::: + startElement(expression); + + addInstruction(new FieldReferenceInstruction(expression)); + + PsiExpression arrayExpression = expression.getArrayExpression(); + if (arrayExpression != null) { + arrayExpression.accept(this); + addInstruction(new PopInstruction()); + } + + PsiExpression indexExpression = expression.getIndexExpression(); + if (indexExpression != null) { + indexExpression.accept(this); + addInstruction(new PopInstruction()); + } + + pushTypeOrUnknown(arrayExpression); + finishElement(expression); + } + + public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { + //TODO::: + startElement(expression); + PsiExpression[] initializers = expression.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + initializers[i].accept(this); + addInstruction(new PopInstruction()); + } + pushUnknown(); + finishElement(expression); + } + + public void visitBinaryExpression(PsiBinaryExpression expression) { + startElement(expression); + + try { + String op = expression.getOperationSign().getText(); + PsiExpression lExpr = expression.getLOperand(); + PsiExpression rExpr = expression.getROperand(); + + if (lExpr == null || rExpr == null) { + pushUnknown(); + return; + } + + if ("&&".equals(op)) { + generateAndExpression(lExpr, rExpr); + } + else if ("||".equals(op)) { + generateOrExpression(lExpr, rExpr); + } + else if ("^".equals(op) && expression.getType() == PsiType.BOOLEAN) { + generateXorExpression(expression, lExpr, rExpr); + } + else { + lExpr.accept(this); + rExpr.accept(this); + addInstruction(new BinopInstruction(op, expression.isPhysical() ? expression : null)); + } + } + finally { + finishElement(expression); + } + } + + private void generateXorExpression(PsiExpression expression, + PsiExpression lExpr, + PsiExpression rExpr) { + lExpr.accept(this); + rExpr.accept(this); + addInstruction(new BinopInstruction("!=", expression.isPhysical() ? expression : null)); + } + + private void generateOrExpression(PsiExpression lExpr, PsiExpression rExpr) { + lExpr.accept(this); + addInstruction(new ConditionalGotoInstruction(getStartOffset(rExpr), true, lExpr)); + addInstruction(new PushInstruction(DfaConstValue.Factory.getInstance().getTrue())); + addInstruction(new GotoInstruction(getEndOffset(rExpr))); + rExpr.accept(this); + } + + private void generateAndExpression(PsiExpression lExpr, PsiExpression rExpr) { + lExpr.accept(this); + ConditionalGotoInstruction firstTrueGoto = new ConditionalGotoInstruction(-1, true, lExpr); + addInstruction(firstTrueGoto); + rExpr.accept(this); + + GotoInstruction overPushFalse = new GotoInstruction(-1); + addInstruction(overPushFalse); + PushInstruction pushFalse = new PushInstruction(DfaConstValue.Factory.getInstance().getFalse()); + addInstruction(pushFalse); + + firstTrueGoto.setOffset(pushFalse.getIndex()); + overPushFalse.setOffset(pushFalse.getIndex() + 1); + } + + public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { + startElement(expression); + PsiElement[] children = expression.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].accept(this); + } + pushUnknown(); + finishElement(expression); + } + + public void visitConditionalExpression(PsiConditionalExpression expression) { + startElement(expression); + + PsiExpression condition = expression.getCondition(); + + PsiExpression thenExpression = expression.getThenExpression(); + PsiExpression elseExpression = expression.getElseExpression(); + + if (condition != null && thenExpression != null && elseExpression != null) { + condition.accept(this); + addInstruction(new ConditionalGotoInstruction(getStartOffset(elseExpression), true, condition)); + thenExpression.accept(this); + + addInstruction(new GotoInstruction(getEndOffset(expression))); + elseExpression.accept(this); + } + else { + pushUnknown(); + } + + finishElement(expression); + } + + private void pushUnknown() { + addInstruction(new PushInstruction(DfaUnknownValue.getInstance())); + } + + public void visitInstanceOfExpression(PsiInstanceOfExpression expression) { + startElement(expression); + PsiExpression operand = expression.getOperand(); + PsiTypeElement checkType = expression.getCheckType(); + if (operand != null && checkType != null) { + operand.accept(this); + PsiType type = checkType.getType(); + if (type instanceof PsiClassType) { + type = ((PsiClassType)type).rawType(); + } + addInstruction(new PushInstruction(DfaTypeValue.Factory.getInstance().create(type))); + addInstruction(new BinopInstruction("instanceof", expression)); + } + else { + pushUnknown(); + } + + finishElement(expression); + } + + private void addMethodThrows(PsiMethod method) { + if (method != null) { + PsiClassType[] refs = method.getThrowsList().getReferencedTypes(); + for (int i = 0; i < refs.length; i++) { + ConditionalGotoInstruction cond = new ConditionalGotoInstruction(NOT_FOUND, false, null); + pushUnknown(); + addInstruction(cond); + addInstruction(new EmptyStackInstruction()); + addInstruction(new PushInstruction(DfaTypeValue.Factory.getInstance().create(refs[i]))); + addThrowCode(refs[i]); + cond.setOffset(myCurrentFlow.getInstructionCount()); + } + } + } + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + try { + startElement(expression); + + PsiReferenceExpression methodExpression = expression.getMethodExpression(); + + PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + if (qualifierExpression != null) { + final String text = qualifierExpression.getText(); + if ("System".equals(text)) { + PsiElement resolved = methodExpression.getReference().resolve(); + if (resolved != null && resolved instanceof PsiMethod) { + PsiMethod method = (PsiMethod)resolved; + if ("exit".equals(method.getName())) { + addInstruction(new ReturnInstruction()); + return; + } + } + } + else if ("LOG".equals(text)) { + final PsiType qualifierType = qualifierExpression.getType(); + if (qualifierType != null && qualifierType.equalsToText("com.intellij.openapi.diagnostic.Logger")) { + PsiElement resolved = methodExpression.getReference().resolve(); + if (resolved != null && resolved instanceof PsiMethod) { + PsiMethod method = (PsiMethod)resolved; + final String methodName = method.getName(); + if ("error".equals(methodName)) { + processMethodParameters(expression); + addInstruction(new ReturnInstruction()); + return; + } + else if ("assertTrue".equals(methodName)) { + PsiExpression[] params = expression.getArgumentList().getExpressions(); + params[0].accept(this); + for (int i = 1; i < params.length; i++) { + params[i].accept(this); + addInstruction(new PopInstruction()); + } + addInstruction(new ConditionalGotoInstruction(getEndOffset(expression) - 1, false, null)); + addInstruction(new ReturnInstruction()); + addInstruction(new PushInstruction(DfaUnknownValue.getInstance())); + return; + } + } + } + } + } + + if (qualifierExpression != null) { + qualifierExpression.accept(this); + addInstruction(new PopInstruction()); + } + + processMethodParameters(expression); + + addInstruction(new MethodCallInstruction(expression)); + PsiExpression expr = methodExpression; + + if (myCatchStack.size() > 0) { + addMethodThrows((PsiMethod)methodExpression.getReference().resolve()); + } + + pushTypeOrUnknown(expr); + } + finally { + finishElement(expression); + } + } + + private void processMethodParameters(PsiMethodCallExpression expression) { + PsiExpression[] params = expression.getArgumentList().getExpressions(); + for (int i = 0; i < params.length; i++) { + params[i].accept(this); + addInstruction(new PopInstruction()); + } + } + + private void pushTypeOrUnknown(PsiExpression expr) { + PsiType psiReturnType = expr.getType(); + DfaValue dfaValue = null; + if (psiReturnType != null && psiReturnType instanceof PsiClassType) { + dfaValue = DfaTypeValue.Factory.getInstance().create(psiReturnType); + } + + addInstruction(new PushInstruction(dfaValue == null ? DfaUnknownValue.getInstance() : dfaValue)); + } + + public void visitNewExpression(PsiNewExpression expression) { + startElement(expression); + + PsiExpressionList expressionList = expression.getArgumentList(); + if (expressionList != null) { + PsiExpression[] parameterExpressions = expressionList.getExpressions(); + for (int i = 0; i < parameterExpressions.length; i++) { + parameterExpressions[i].accept(this); + addInstruction(new PopInstruction()); + } + } + + if (myCatchStack.size() > 0) { + addMethodThrows(expression.resolveConstructor()); + } + addInstruction(new PushInstruction(DfaValueFactory.create(expression))); + + finishElement(expression); + } + + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { + startElement(expression); + PsiExpression inner = expression.getExpression(); + if (inner != null) { + inner.accept(this); + } + else { + pushUnknown(); + } + finishElement(expression); + } + + public void visitPostfixExpression(PsiPostfixExpression expression) { + startElement(expression); + + PsiExpression operand = expression.getOperand(); + if (operand != null) { + operand.accept(this); + addInstruction(new PopInstruction()); + } + pushUnknown(); + + if (operand instanceof PsiReferenceExpression) { + PsiVariable psiVariable = DfaValueFactory.resolveVariable((PsiReferenceExpression)expression.getOperand()); + if (psiVariable != null) { + DfaVariableValue dfaVariable = DfaVariableValue.Factory.getInstance().create(psiVariable, false); + addInstruction(new FlushVariableInstruction(dfaVariable)); + } + } + + finishElement(expression); + } + + public void visitPrefixExpression(PsiPrefixExpression expression) { + startElement(expression); + + PsiExpression operand = expression.getOperand(); + + if (operand != null) { + operand.accept(this); + if (expression.getOperationSign().getTokenType() == JavaTokenType.EXCL) { + addInstruction(new NotInstruction()); + } + else { + addInstruction(new PopInstruction()); + pushUnknown(); + + if (operand instanceof PsiReferenceExpression) { + PsiVariable psiVariable = DfaValueFactory.resolveVariable((PsiReferenceExpression)operand); + if (psiVariable != null) { + DfaVariableValue dfaVariable = DfaVariableValue.Factory.getInstance().create(psiVariable, false); + addInstruction(new FlushVariableInstruction(dfaVariable)); + } + } + } + } + else { + pushUnknown(); + } + + finishElement(expression); + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + startElement(expression); + + DfaValue dfaValue = DfaValueFactory.create(expression); + if (dfaValue instanceof DfaVariableValue) { + DfaVariableValue dfaVariable = (DfaVariableValue)dfaValue; + PsiVariable psiVariable = dfaVariable.getPsiVariable(); + if (psiVariable instanceof PsiField) { + addField(dfaVariable); + } + } + + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null && expression.resolve() instanceof PsiField) { + addInstruction(new FieldReferenceInstruction(expression)); + } + + addInstruction(new PushInstruction(dfaValue != null ? dfaValue : DfaUnknownValue.getInstance())); + + finishElement(expression); + } + + private void addField(DfaVariableValue field) { + myFields.add(field); + } + + public void visitSuperExpression(PsiSuperExpression expression) { + startElement(expression); + addInstruction(new PushInstruction(DfaNewValue.Factory.getInstance().create(expression.getType()))); + finishElement(expression); + } + + public void visitThisExpression(PsiThisExpression expression) { + startElement(expression); + addInstruction(new PushInstruction(DfaNewValue.Factory.getInstance().create(expression.getType()))); + finishElement(expression); + } + + public void visitLiteralExpression(PsiLiteralExpression expression) { + startElement(expression); + + DfaValue dfaValue = DfaValueFactory.create(expression); + addInstruction(new PushInstruction(dfaValue != null ? dfaValue : DfaUnknownValue.getInstance())); + + finishElement(expression); + } + + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + startElement(expression); + PsiExpression operand = expression.getOperand(); + + if (operand != null) { + operand.accept(this); + } + else { + pushTypeOrUnknown(expression); + } + + TypeCastInstruction tcInstruction = TypeCastInstruction.createInstruction(expression); + if (tcInstruction != null) { + addInstruction(tcInstruction); + } + + finishElement(expression); + } + + public void visitClass(PsiClass aClass) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowInspection.java new file mode 100644 index 00000000000..baa9f312148 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowInspection.java @@ -0,0 +1,242 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 24, 2001 + * Time: 2:46:32 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.dataFlow.instructions.*; +import com.intellij.codeInspection.ex.AddAssertStatementFix; +import com.intellij.codeInspection.ex.BaseLocalInspectionTool; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class DataFlowInspection extends BaseLocalInspectionTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection"); + + public static final String DISPLAY_NAME = "Constant conditions & exceptions"; + public static final String SHORT_NAME = "ConstantConditions"; + + public DataFlowInspection() { + } + + public ProblemDescriptor[] checkMethod(PsiMethod method, InspectionManager manager, boolean isOnTheFly) { + return analyzeCodeBlock(method.getBody(), manager); + } + + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + List allProblems = null; + final PsiClassInitializer[] initializers = aClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + final ProblemDescriptor[] problems = analyzeCodeBlock(initializers[i].getBody(), manager); + if (problems != null) { + if (allProblems == null) { + allProblems = new ArrayList(1); + } + allProblems.addAll(Arrays.asList(problems)); + } + } + return allProblems == null ? null : allProblems.toArray(new ProblemDescriptor[allProblems.size()]); + } + + private ProblemDescriptor[] analyzeCodeBlock(final PsiCodeBlock body, InspectionManager manager) { + if (body == null) return null; + DataFlowRunner dfaRunner = new DataFlowRunner(); + if (dfaRunner.analyzeMethod(body)) { + HashSet[] constConditions = dfaRunner.getConstConditionalExpressions(); + if (constConditions[0].size() > 0 || + constConditions[1].size() > 0 || + dfaRunner.getNPEInstructions().size() > 0 || + dfaRunner.getCCEInstructions().size() > 0 || + dfaRunner.getRedundantInstanceofs().size() > 0) { + return createDescription(dfaRunner, manager); + } + } + + return null; + } + + private LocalQuickFix createAssertNotNullFix(PsiExpression qualifier) { + if (qualifier != null && qualifier.getManager().getEffectiveLanguageLevel().hasAssertKeyword() && + !(qualifier instanceof PsiMethodCallExpression)) { + try { + PsiBinaryExpression binary = (PsiBinaryExpression)qualifier.getManager().getElementFactory().createExpressionFromText("a != null", + null); + binary.getLOperand().replace(qualifier); + return new AddAssertStatementFix(binary); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + return null; + } + + private ProblemDescriptor[] createDescription(DataFlowRunner runner, InspectionManager manager) { + HashSet[] constConditions = runner.getConstConditionalExpressions(); + HashSet trueSet = constConditions[0]; + HashSet falseSet = constConditions[1]; + Set npeSet = runner.getNPEInstructions(); + Set cceSet = runner.getCCEInstructions(); + Set redundantInstanceofs = runner.getRedundantInstanceofs(); + + ArrayList allProblems = new ArrayList(); + for (Iterator iterator = trueSet.iterator(); iterator.hasNext();) { + Instruction branchingInstruction = (Instruction)iterator.next(); + allProblems.add(branchingInstruction); + } + + for (Iterator iterator = falseSet.iterator(); iterator.hasNext();) { + Instruction branchingInstruction = (Instruction)iterator.next(); + allProblems.add(branchingInstruction); + } + + for (Iterator iterator = npeSet.iterator(); iterator.hasNext();) { + Instruction methodCallInstruction = (Instruction)iterator.next(); + allProblems.add(methodCallInstruction); + } + + for (Iterator iterator = cceSet.iterator(); iterator.hasNext();) { + Instruction typeCastInstruction = (Instruction)iterator.next(); + allProblems.add(typeCastInstruction); + } + + for (Iterator iterator = redundantInstanceofs.iterator(); iterator.hasNext();) { + Instruction instruction = (Instruction)iterator.next(); + allProblems.add(instruction); + } + + Collections.sort(allProblems, new Comparator() { + public int compare(Object o1, Object o2) { + int i1 = ((Instruction)o1).getIndex(); + int i2 = ((Instruction)o2).getIndex(); + + if (i1 == i2) return 0; + if (i1 > i2) return 1; + + return -1; + } + }); + + ArrayList descriptions = new ArrayList(allProblems.size()); + HashSet reportedAnchors = new HashSet(); + + for (int i = 0; i < allProblems.size(); i++) { + Instruction instruction = allProblems.get(i); + + if (instruction instanceof MethodCallInstruction) { + MethodCallInstruction mcInstruction = (MethodCallInstruction)instruction; + PsiMethodCallExpression callExpression = mcInstruction.getCallExpression(); + LocalQuickFix fix = createAssertNotNullFix(callExpression.getMethodExpression().getQualifierExpression()); + + descriptions.add(manager.createProblemDescriptor(mcInstruction.getCallExpression(), + "Method invocation #ref #loc may produce java.lang.NullPointerException.", + fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + else if (instruction instanceof FieldReferenceInstruction) { + FieldReferenceInstruction frInstruction = (FieldReferenceInstruction)instruction; + PsiExpression expression = frInstruction.getExpression(); + if (expression instanceof PsiArrayAccessExpression) { + LocalQuickFix fix = createAssertNotNullFix(((PsiArrayAccessExpression)expression).getArrayExpression()); + descriptions.add(manager.createProblemDescriptor(expression, + "Array access #ref #loc may produce java.lang.NullPointerException<./code>.", + fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + else { + LocalQuickFix fix = createAssertNotNullFix(((PsiReferenceExpression)expression).getQualifierExpression()); + descriptions.add(manager.createProblemDescriptor(expression, + "Member variable access #ref #loc may produce java.lang.NullPointerException<./code>.", + fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + else if (instruction instanceof TypeCastInstruction) { + TypeCastInstruction tcInstruction = (TypeCastInstruction)instruction; + PsiTypeCastExpression typeCast = tcInstruction.getCastExpression(); + descriptions.add(manager.createProblemDescriptor(typeCast.getCastType(), + "Casting " + typeCast.getOperand().getText() + + " to #ref #loc may produce java.lang.ClassCastException.", + null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + else if (instruction instanceof BranchingInstruction) { + PsiElement psiAnchor = ((BranchingInstruction)instruction).getPsiAnchor(); + if (instruction instanceof BinopInstruction && ((BinopInstruction)instruction).isInstanceofRedundant()) { + if (((BinopInstruction)instruction).canBeNull()) { + descriptions.add(manager.createProblemDescriptor(psiAnchor, + "Condition #ref #loc is redundant and can be replaced with != null", + new RedundantInstanceofFix(), + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + else { + descriptions.add(manager.createProblemDescriptor(psiAnchor, + "Condition #ref #loc is always true", + null, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + else if (psiAnchor instanceof PsiSwitchLabelStatement) { + if (falseSet.contains(instruction)) { + descriptions.add(manager.createProblemDescriptor(psiAnchor, "Switch label#ref #loc is unreachable.", null, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + else if (psiAnchor != null) { + if (!reportedAnchors.contains(psiAnchor)) { + descriptions.add(manager.createProblemDescriptor(psiAnchor, "Condition #ref #loc is always " + + (trueSet.contains(instruction) ? "true" : "false") + + ".", null, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + reportedAnchors.add(psiAnchor); + } + } + } + } + + return descriptions.toArray(new ProblemDescriptor[descriptions.size()]); + } + + private static class RedundantInstanceofFix implements LocalQuickFix { + public String getName() { + return "Replace with != null"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + final PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement instanceof PsiInstanceOfExpression) { + try { + final PsiExpression compareToNull = psiElement.getManager().getElementFactory(). + createExpressionFromText(((PsiInstanceOfExpression)psiElement).getOperand().getText() + " != null", + psiElement.getParent()); + psiElement.replace(compareToNull); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + } + + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getShortName() { + return SHORT_NAME; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowRunner.java new file mode 100644 index 00000000000..cea77892cd4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -0,0 +1,182 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 10:16:39 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.instructions.BinopInstruction; +import com.intellij.codeInspection.dataFlow.instructions.BranchingInstruction; +import com.intellij.codeInspection.dataFlow.instructions.Instruction; +import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.PsiCodeBlock; + +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.HashSet; +import java.util.Set; + +public class DataFlowRunner { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowRunner"); + private static final long ourTimeLimit = 10000; + + private Instruction[] myInstructions; + private final HashSet myNPEInstructions; + private DfaVariableValue[] myFields; + private final HashSet myCCEInstructions; + + public Instruction getInstruction(int index) { + return myInstructions[index]; + } + + public DataFlowRunner() { + myNPEInstructions = new HashSet(); + myCCEInstructions = new HashSet(); + DfaValueFactory.freeInstance(); + } + + public boolean analyzeMethod(PsiCodeBlock psiBlock) { + try { + ControlFlow flow = new ControlFlowAnalyzer().buildControlFlow(psiBlock); + if (flow == null) return false; + + myInstructions = flow.getInstructions(); + myFields = flow.getFields(); + + if (LOG.isDebugEnabled()) { + for (int i = 0; i < myInstructions.length; i++) { + Instruction instruction = myInstructions[i]; + LOG.debug("" + i + ": " + instruction.toString()); + } + } + + int branchCount = 0; + for (int i = 0; i < myInstructions.length; i++) { + Instruction instruction = myInstructions[i]; + if (instruction instanceof BranchingInstruction) branchCount++; + } + + if (branchCount > 80) return false; // Do not even try. Definetly will out of time. + + final ArrayList queue = new ArrayList(); + queue.add(new DfaInstructionState(myInstructions[0], DfaMemoryStateImpl.createEmpty())); + + final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); + final long before = System.currentTimeMillis(); + while (queue.size() > 0) { + if (!unitTestMode && System.currentTimeMillis() - before > ourTimeLimit) return false; + ProgressManager.getInstance().checkCanceled(); + + DfaInstructionState instructionState = (DfaInstructionState)queue.remove(0); + if (LOG.isDebugEnabled()) { + LOG.debug(instructionState.toString()); + } + + Instruction instruction = instructionState.getInstruction(); + long distance = instructionState.getDistanceFromStart(); + + if (instruction instanceof BranchingInstruction) { + instruction.setMemoryStateProcessed(instructionState.getMemoryState().createCopy()); + } + + DfaInstructionState[] after = instruction.apply(DataFlowRunner.this, instructionState.getMemoryState()); + if (after != null) { + for (int i = 0; i < after.length; i++) { + DfaInstructionState state = after[i]; + Instruction nextInstruction = state.getInstruction(); + if (!(nextInstruction instanceof BranchingInstruction) || + !nextInstruction.isMemoryStateProcessed(state.getMemoryState())) { + state.setDistanceFromStart(distance + 1); + queue.add(state); + } + } + } + } + + return true; + } + catch (EmptyStackException e) /* TODO[max] !!! hack (of 18186). Please fix in better times. */ { + return false; + } + finally { + DfaValueFactory.freeInstance(); + } + } + + public void onInstructionProducesNPE(Instruction instruction) { + myNPEInstructions.add(instruction); + } + + public void onInstructionProducesCCE(Instruction instruction) { + myCCEInstructions.add(instruction); + } + + public Set getCCEInstructions() { + return myCCEInstructions; + } + + public Set getNPEInstructions() { + return myNPEInstructions; + } + + public Set getRedundantInstanceofs() { + HashSet result = new HashSet(1); + for (int i = 0; i < myInstructions.length; i++) { + Instruction instruction = myInstructions[i]; + if (instruction instanceof BinopInstruction) { + if (((BinopInstruction)instruction).isInstanceofRedundant()) { + result.add(instruction); + } + } + } + + return result; + } + + public DfaVariableValue[] getFields() { + return myFields; + } + + public HashSet[] getConstConditionalExpressions() { + HashSet trueSet = new HashSet(); + HashSet falseSet = new HashSet(); + + for (int i = 0; i < myInstructions.length; i++) { + Instruction instruction = myInstructions[i]; + if (instruction instanceof BranchingInstruction) { + BranchingInstruction branchingInstruction = (BranchingInstruction)instruction; + if (branchingInstruction.getPsiAnchor() != null && branchingInstruction.isConditionConst()) { + if (!branchingInstruction.isTrueReachable()) { + falseSet.add(branchingInstruction); + } + + if (!branchingInstruction.isFalseReachable()) { + trueSet.add(branchingInstruction); + } + } + } + } + + for (int i = 0; i < myInstructions.length; i++) { + Instruction instruction = myInstructions[i]; + if (instruction instanceof BranchingInstruction) { + BranchingInstruction branchingInstruction = (BranchingInstruction)instruction; + if (branchingInstruction.isTrueReachable()) { + falseSet.remove(branchingInstruction); + } + if (branchingInstruction.isFalseReachable()) { + trueSet.remove(branchingInstruction); + } + } + } + + return new HashSet[]{trueSet, falseSet}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaInstructionState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaInstructionState.java new file mode 100644 index 00000000000..8b5504441e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaInstructionState.java @@ -0,0 +1,38 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 9:40:01 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.instructions.Instruction; + +public class DfaInstructionState { + private final DfaMemoryState myBeforeMemoryState; + private final Instruction myInstruction; + private long myDistanceFromStart = 0; + + public DfaInstructionState(Instruction myInstruction, DfaMemoryState myBeforeMemoryState) { + this.myBeforeMemoryState = myBeforeMemoryState; + this.myInstruction = myInstruction; + } + + public long getDistanceFromStart() { return myDistanceFromStart; } + + public void setDistanceFromStart(long distanceFromStart) { myDistanceFromStart = distanceFromStart; } + + public Instruction getInstruction() { + return myInstruction; + } + + public DfaMemoryState getMemoryState() { + return myBeforeMemoryState; + } + + public String toString() { + return "" + getInstruction().getIndex() + ": " + getMemoryState().toString() + " " + getInstruction().toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryState.java new file mode 100644 index 00000000000..33c1d7aec8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryState.java @@ -0,0 +1,36 @@ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.value.DfaRelationValue; +import com.intellij.codeInspection.dataFlow.value.DfaValue; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 16, 2003 + * Time: 10:25:44 PM + * To change this template use Options | File Templates. + */ +public interface DfaMemoryState { + DfaMemoryState createCopy(); + + DfaValue pop(); + void push(DfaValue value); + + int popOffset(); + void pushOffset(int offset); + + void emptyStack(); + + void setVarValue(DfaVariableValue var, DfaValue value); + + boolean applyInstanceofOrNull(DfaRelationValue dfaCond); + + boolean applyCondition(DfaValue dfaCond); + + void flushFields(DataFlowRunner runner); + + void flushVariable(DfaVariableValue variable); + + boolean isNull(DfaValue dfaVar); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java new file mode 100644 index 00000000000..ed3b47ab938 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -0,0 +1,503 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 9:39:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.value.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiVariable; +import gnu.trove.TIntStack; +import gnu.trove.TLongArrayList; +import gnu.trove.TLongHashSet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Stack; + +public class DfaMemoryStateImpl implements DfaMemoryState { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DfaMemoryStateImpl"); + private ArrayList myEqClasses; + private int myStateSize; + private Stack myStack; + private TIntStack myOffsetStack; + private TLongHashSet myDistinctClasses; + private com.intellij.util.containers.HashMap myVariableStates; + + private DfaMemoryStateImpl() { + } + + public static DfaMemoryState createEmpty() { + DfaMemoryStateImpl empty = new DfaMemoryStateImpl(); + + empty.myEqClasses = new ArrayList(); + empty.myStateSize = 0; + empty.myStack = new Stack(); + empty.myDistinctClasses = new TLongHashSet(); + empty.myVariableStates = new com.intellij.util.containers.HashMap(); + empty.myOffsetStack = new TIntStack(1); + return empty; + } + + public DfaMemoryState createCopy() { + DfaMemoryStateImpl newState = new DfaMemoryStateImpl(); + + newState.myStack = (Stack) myStack.clone(); + newState.myDistinctClasses = new TLongHashSet(myDistinctClasses.toArray()); + newState.myEqClasses = new ArrayList(); + newState.myStateSize = myStateSize; + newState.myVariableStates = new com.intellij.util.containers.HashMap(); + newState.myOffsetStack = new TIntStack(myOffsetStack); + + for (int i = 0; i < myEqClasses.size(); i++) { + SortedIntSet aClass = myEqClasses.get(i); + newState.myEqClasses.add(aClass != null ? new SortedIntSet(aClass.toNativeArray()) : null); + } + + try { + for (Iterator iterator = myVariableStates.keySet().iterator(); iterator.hasNext();) { + DfaVariableValue dfaVariableValue = (DfaVariableValue) iterator.next(); + newState.myVariableStates.put(dfaVariableValue, ((DfaVariableState) myVariableStates.get(dfaVariableValue)).clone()); + } + } catch (CloneNotSupportedException e) { + LOG.error(e); + } + return newState; + } + + public boolean equals(Object obj) { + if (obj == this) return true; + if (!(obj instanceof DfaMemoryState)) return false; + DfaMemoryStateImpl that = (DfaMemoryStateImpl) obj; + + if (myStateSize != that.myStateSize) return false; + if (myDistinctClasses.size() != that.myDistinctClasses.size()) return false; + + if (!myStack.equals(that.myStack)) return false; + if (!myOffsetStack.equals(that.myOffsetStack)) return false; + if (!myVariableStates.equals(that.myVariableStates)) return false; + + int[] permutation = getPermutationToSortedState(); + int[] thatPermutation = that.getPermutationToSortedState(); + + for(int i = 0; i < myStateSize; i++) { + SortedIntSet thisClass = myEqClasses.get(permutation[i]); + SortedIntSet thatClass = that.myEqClasses.get(thatPermutation[i]); + if (thisClass == null) break; + if (thisClass.compareTo(thatClass) != 0) return false; + } + + long[] pairs = getSortedDistinctClasses(permutation); + long[] thatPairs = that.getSortedDistinctClasses(thatPermutation); + + for (int i = 0; i < pairs.length; i++) { + if (pairs[i] != thatPairs[i]) { + return false; + } + } + + return true; + } + + private long[] getSortedDistinctClasses(int[] permutation) { + long[] pairs = myDistinctClasses.toArray(); + for (int i = 0; i < pairs.length; i++) { + pairs[i] = convert(pairs[i], permutation); + } + Arrays.sort(pairs); + return pairs; + } + + private long convert(long pair, int[] permutation) { + if (myEqClasses.get(low(pair)) == null || myEqClasses.get(high(pair)) == null) { + return -1L; + } + return createPair(inversePermutation(permutation, low(pair)), inversePermutation(permutation, high(pair))); + } + + private static int inversePermutation(int[] permutation, int idx) { + for (int i = 0; i < permutation.length; i++) { + if (idx == permutation[i]) return i; + } + return -1; + } + + private int[] getPermutationToSortedState() { + int size = myEqClasses.size(); + int[] permutation = new int[size]; + for (int i = 0; i < size; i++) { + permutation[i] = i; + } + + for (int i = 0; i < permutation.length; i++) { + for (int j = i + 1; j < permutation.length; j++) { + if (compare(permutation[i], permutation[j]) > 0) { + int t = permutation[i]; + permutation[i] = permutation[j]; + permutation[j] = t; + } + } + } + + return permutation; + } + + private int compare(int i1, int i2) { + SortedIntSet s1 = myEqClasses.get(i1); + SortedIntSet s2 = myEqClasses.get(i2); + if (s1 == null && s2 == null) return 0; + if (s1 == null) return 1; + if (s2 == null) return -1; + return s1.compareTo(s2); + } + + public int hashCode() { + return 0; + //return myEqClasses.hashCode() + myStack.hashCode() + myVariableStates.hashCode(); + } + + private void appendClass(StringBuffer buf, int aClassIndex) { + SortedIntSet aClass = myEqClasses.get(aClassIndex); + if (aClass != null) { + buf.append("("); + int[] values = aClass.toNativeArray(); + for (int i = 0; i < values.length; i++) { + if (i > 0) buf.append(", "); + int value = values[i]; + DfaValue dfaValue = DfaValueFactory.getInstance().getValue(value); + buf.append(dfaValue); + } + buf.append(")"); + } + } + + public String toString() { + StringBuffer result = new StringBuffer(); + result.append('<'); + + for (int i = 0; i < myEqClasses.size(); i++) { + appendClass(result, i); + } + + result.append(" distincts: "); + long[] dclasses = myDistinctClasses.toArray(); + for (int i = 0; i < dclasses.length; i++) { + long pair = dclasses[i]; + result.append("{"); + appendClass(result, low(pair)); + result.append(", "); + appendClass(result, high(pair)); + result.append("} "); + } + + result.append(" stack: "); + for (int i = 0; i < myStack.size(); i++) { + result.append(myStack.elementAt(i)); + } + result.append('>'); + return result.toString(); + } + + public DfaValue pop() { + return (DfaValue) myStack.pop(); + } + + public void push(DfaValue value) { + myStack.push(value); + } + + public int popOffset() { + return myOffsetStack.pop(); + } + + public void pushOffset(int offset) { + myOffsetStack.push(offset); + } + + public void emptyStack() { + myStack.removeAllElements(); + } + + public void setVarValue(DfaVariableValue var, DfaValue value) { + flushVariable(var); + if (value instanceof DfaUnknownValue) return; + + if (value instanceof DfaNewValue) { + DfaTypeValue dfaType = DfaTypeValue.Factory.getInstance().create(((DfaNewValue)value).getType()); + DfaRelationValue dfaInstanceof = DfaRelationValue.Factory.getInstance().create(var, dfaType, "instanceof", false); + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + DfaRelationValue dfaNotNull = DfaRelationValue.Factory.getInstance().create(var, dfaNull, "==", true); + applyCondition(dfaInstanceof); + applyCondition(dfaNotNull); + } else if (value instanceof DfaTypeValue) { + DfaRelationValue dfaInstanceof = DfaRelationValue.Factory.getInstance().create(var, value, "instanceof", false); + applyInstanceofOrNull(dfaInstanceof); + } else { + DfaRelationValue dfaEqual = DfaRelationValue.Factory.getInstance().create(var, value, "==", false); + applyCondition(dfaEqual); + + if (value instanceof DfaVariableValue) { + try { + DfaVariableState newState = (DfaVariableState) (getVariableState((DfaVariableValue) value)).clone(); + myVariableStates.put(var, newState); + } catch (CloneNotSupportedException e) { + LOG.error(e); + } + } + } + } + + private int getOrCreateEqClassIndex(DfaValue dfaValue) { + for (int i = 0; i < myEqClasses.size(); i++) { + SortedIntSet aClass = myEqClasses.get(i); + if (aClass != null && aClass.contains(dfaValue.getID())) return i; + } + + SortedIntSet aClass = new SortedIntSet(); + aClass.add(dfaValue.getID()); + myEqClasses.add(aClass); + myStateSize++; + + return myEqClasses.size() - 1; + } + + private int getEqClassIndex(DfaValue dfaValue) { + for (int i = 0; i < myEqClasses.size(); i++) { + SortedIntSet aClass = myEqClasses.get(i); + if (aClass != null && aClass.contains(dfaValue.getID())) return i; + } + + return -1; + } + + private boolean unitClasses(int c1Index, int c2Index) { + SortedIntSet c1 = myEqClasses.get(c1Index); + SortedIntSet c2 = myEqClasses.get(c2Index); + + int nConst = 0; + int[] c1s = c1.toNativeArray(); + for (int i = 0; i < c1s.length; i++) { + DfaValue dfaValue = DfaValueFactory.getInstance().getValue(c1s[i]); + if (dfaValue instanceof DfaConstValue) nConst++; + } + + int[] c2s = c2.toNativeArray(); + for (int i = 0; i < c2s.length; i++) { + DfaValue dfaValue = DfaValueFactory.getInstance().getValue(c2s[i]); + if (dfaValue instanceof DfaConstValue) nConst++; + } + + if (nConst > 1) return false; + + TLongArrayList c2Pairs = new TLongArrayList(); + long[] distincts = myDistinctClasses.toArray(); + for (int i = 0; i < distincts.length; i++) { + int pc1 = low(distincts[i]); + int pc2 = high(distincts[i]); + boolean addedToC1 = false; + + if (pc1 == c1Index || pc2 == c1Index) { + addedToC1 = true; + } + + if (pc1 == c2Index || pc2 == c2Index) { + if (addedToC1) return false; + c2Pairs.add(distincts[i]); + } + } + + c1.add(c2.toNativeArray()); + long[] c2Array = c2Pairs.toNativeArray(); + myDistinctClasses.removeAll(c2Array); + myEqClasses.set(c2Index, null); + myStateSize--; + + for (int i = 0; i < c2Array.length; i++) { + long l = c2Array[i]; + myDistinctClasses.add(createPair(c1Index, low(l) == c2Index ? high(l) : low(l))); + } + + return true; + } + + private static int low(long l) { + return (int) (l & 0xFFFFFFFF); + } + + private static int high(long l) { + return (int) ((l & 0xFFFFFFFF00000000L) >> 32); + } + + private static long createPair(int i1, int i2) { + if (i1 < i2) { + long l = i1; + l <<= 32; + l += i2; + return l; + } else { + long l = i2; + l <<= 32; + l += i1; + return l; + } + } + + private void makeClassesDistinct(int c1Index, int c2Index) { + myDistinctClasses.add(createPair(c1Index, c2Index)); + } + + public boolean isNull(DfaValue dfaValue) { + if (dfaValue instanceof DfaVariableValue || dfaValue instanceof DfaConstValue) { + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + int c1Index = getOrCreateEqClassIndex(dfaValue); + int c2Index = getOrCreateEqClassIndex(dfaNull); + + return c1Index == c2Index; + } + + return false; + } + + public boolean isNotNull(DfaVariableValue dfaVar) { + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + int c1Index = getOrCreateEqClassIndex(dfaVar); + int c2Index = getOrCreateEqClassIndex(dfaNull); + + long[] pairs = myDistinctClasses.toArray(); + for (int i = 0; i < pairs.length; i++) { + long pair = pairs[i]; + if (low(pair) == c1Index && high(pair) == c2Index || + high(pair) == c1Index && low(pair) == c2Index) { + return true; + } + } + + return false; + } + + public boolean applyInstanceofOrNull(DfaRelationValue dfaCond) { + DfaVariableValue dfaVar = (DfaVariableValue) dfaCond.getLeftOperand(); + DfaTypeValue dfaType = (DfaTypeValue) dfaCond.getRightOperand(); + + if (!isNotNull(dfaVar)) return true; + return getVariableState(dfaVar).setInstanceofValue(dfaType); + } + + public boolean applyCondition(DfaValue dfaCond) { + if (dfaCond instanceof DfaUnknownValue) return true; + if (dfaCond instanceof DfaVariableValue) { + DfaVariableValue dfaVar = (DfaVariableValue) dfaCond; + DfaVariableValue dfaNormalVar = dfaVar.isNegated() ? (DfaVariableValue) dfaVar.createNegated() : dfaVar; + DfaConstValue dfaTrue = DfaConstValue.Factory.getInstance().getTrue(); + DfaRelationValue dfaEqualsTrue = DfaRelationValue.Factory.getInstance().create(dfaNormalVar, dfaTrue, "==", dfaVar.isNegated()); + return applyCondition(dfaEqualsTrue); + } + + if (dfaCond instanceof DfaConstValue) { + if (dfaCond == DfaConstValue.Factory.getInstance().getTrue()) return true; + if (dfaCond == DfaConstValue.Factory.getInstance().getFalse()) return false; + return true; + } + + if (!(dfaCond instanceof DfaRelationValue)) { + return true; + } + + DfaRelationValue dfaRelation = (DfaRelationValue) dfaCond; + DfaValue dfaLeft = dfaRelation.getLeftOperand(); + DfaValue dfaRight = dfaRelation.getRightOperand(); + + if (dfaRight instanceof DfaTypeValue) { + if (dfaLeft instanceof DfaVariableValue) { + DfaVariableState varState = getVariableState((DfaVariableValue) dfaLeft); + DfaVariableValue dfaVar = (DfaVariableValue) dfaLeft; + if (dfaRelation.isNegated()) { + return varState.addNotInstanceofValue((DfaTypeValue) dfaRight) + ? true + : applyCondition(compareToNull(dfaVar, false)); + } + + return applyCondition(compareToNull(dfaVar, true)) + ? varState.setInstanceofValue((DfaTypeValue) dfaRight) + : false; + + } + + return true; + } + + if (dfaLeft instanceof DfaUnknownValue || dfaRight instanceof DfaUnknownValue) { + return true; + } + + // DfaConstValue || DfaVariableValue + int c1Index = getOrCreateEqClassIndex(dfaLeft); + int c2Index = getOrCreateEqClassIndex(dfaRight); + + if (!dfaRelation.isNegated()) { //Equals + if (c1Index == c2Index) return true; + if (!unitClasses(c1Index, c2Index)) return false; + } else { // Not Equals + if (c1Index == c2Index) return false; + makeClassesDistinct(c1Index, c2Index); + } + + return true; + } + + private DfaRelationValue compareToNull(DfaVariableValue dfaVar, boolean negated) { + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + DfaRelationValue myDfaNotNull = DfaRelationValue.Factory.getInstance().create(dfaVar, dfaNull, "==", negated); + return myDfaNotNull; + } + + private DfaVariableState getVariableState(DfaVariableValue dfaVar) { + DfaVariableState state = (DfaVariableState) myVariableStates.get(dfaVar); + + if (state == null) { + state = new DfaVariableState(); + myVariableStates.put(dfaVar, state); + final PsiVariable psiVariable = dfaVar.getPsiVariable(); + if (psiVariable != null) { + state.setInstanceofValue(DfaTypeValue.Factory.getInstance().create(psiVariable.getType())); + } + } + + return state; + } + + public void flushFields(DataFlowRunner runner) { + DfaVariableValue[] fields = runner.getFields(); + for (int i = 0; i < fields.length; i++) { + DfaVariableValue field = fields[i]; + flushVariable(field); + } + } + + public void flushVariable(DfaVariableValue variable) { + int varClassIndex = getEqClassIndex(variable); + if (varClassIndex != -1) { + SortedIntSet varClass = myEqClasses.get(varClassIndex); + varClass.removeValue(variable.getID()); + + if (varClass.size() == 0) { + myEqClasses.set(varClassIndex, null); + myStateSize--; + long[] pairs = myDistinctClasses.toArray(); + for (int i = 0; i < pairs.length; i++) { + long pair = pairs[i]; + if (low(pair)== varClassIndex || high(pair) == varClassIndex) { + myDistinctClasses.remove(pair); + } + } + } + } + + myVariableStates.remove(variable); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaVariableState.java new file mode 100644 index 00000000000..9b4b4758eb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/DfaVariableState.java @@ -0,0 +1,107 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 3, 2002 + * Time: 9:49:29 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInspection.dataFlow.value.DfaTypeValue; +import com.intellij.psi.PsiPrimitiveType; + +import java.util.HashSet; +import java.util.Iterator; + +public class DfaVariableState implements Cloneable { + private HashSet myInstanceofValues; + private HashSet myNotInstanceofValues; + + public DfaVariableState() { + myInstanceofValues = new HashSet(); + myNotInstanceofValues = new HashSet(); + } + + private boolean checkInstanceofValue(DfaTypeValue dfaType) { + if (myInstanceofValues.contains(dfaType)) return true; + + for (Iterator iterator = myNotInstanceofValues.iterator(); iterator.hasNext();) { + DfaTypeValue dfaTypeValue = (DfaTypeValue) iterator.next(); + if (dfaTypeValue.isAssignableFrom(dfaType)) return false; + } + + for (Iterator iterator = myInstanceofValues.iterator(); iterator.hasNext();) { + DfaTypeValue dfaTypeValue = (DfaTypeValue)iterator.next(); + if (!dfaType.isConvertibleFrom(dfaTypeValue)) { + return false; + } + } + + return true; + } + + public boolean setInstanceofValue(DfaTypeValue dfaType) { + if (dfaType.getType() instanceof PsiPrimitiveType) return true; + + if (checkInstanceofValue(dfaType)) { + myInstanceofValues.add(dfaType); + return true; + } + + return false; + } + + public boolean addNotInstanceofValue(DfaTypeValue dfaType) { + if (myNotInstanceofValues.contains(dfaType)) return true; + + for (Iterator iterator = myInstanceofValues.iterator(); iterator.hasNext();) { + DfaTypeValue dfaTypeValue = (DfaTypeValue) iterator.next(); + if (dfaType.isAssignableFrom(dfaTypeValue)) return false; + } + + myNotInstanceofValues.add(dfaType); + return true; + } + + public int hashCode() { + return myInstanceofValues.hashCode() + myNotInstanceofValues.hashCode(); + } + + public boolean equals(Object obj) { + if (obj == this) return true; + if (!(obj instanceof DfaVariableState)) return false; + DfaVariableState aState = (DfaVariableState) obj; + return myInstanceofValues.equals(aState.myInstanceofValues) && myNotInstanceofValues.equals(aState.myNotInstanceofValues); + } + + protected Object clone() throws CloneNotSupportedException { + DfaVariableState newState = new DfaVariableState(); + + newState.myInstanceofValues = (HashSet) myInstanceofValues.clone(); + newState.myNotInstanceofValues = (HashSet) myNotInstanceofValues.clone(); + + return newState; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + + buf.append("instanceof {"); + for (Iterator iterator = myInstanceofValues.iterator(); iterator.hasNext();) { + DfaTypeValue dfaTypeValue = (DfaTypeValue) iterator.next(); + buf.append(dfaTypeValue); + if (iterator.hasNext()) buf.append(", "); + } + buf.append("} "); + + buf.append("not instanceof {"); + for (Iterator iterator = myNotInstanceofValues.iterator(); iterator.hasNext();) { + DfaTypeValue dfaTypeValue = (DfaTypeValue) iterator.next(); + buf.append(dfaTypeValue); + if (iterator.hasNext()) buf.append(", "); + } + buf.append("}"); + return buf.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/SortedIntSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/SortedIntSet.java new file mode 100644 index 00000000000..dba7e528628 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/SortedIntSet.java @@ -0,0 +1,50 @@ +package com.intellij.codeInspection.dataFlow; + +import gnu.trove.TIntArrayList; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Aug 3, 2003 + * Time: 6:16:20 PM + * To change this template use Options | File Templates. + */ +public class SortedIntSet extends TIntArrayList implements Comparable { + public SortedIntSet() { + } + + public SortedIntSet(int[] values) { + super(values); + } + + public void add(int val) { + int idx = indexOf(val); + if (idx != -1) return; + for(idx = 0; idx < size(); idx++) { + if (get(idx) > val) { + insert(idx, val); + return; + } + } + super.add(val); + } + + public void add(int[] vals) { + for (int i = 0; i < vals.length; i++) { + add(vals[i]); + } + } + + public void removeValue(int val) { + remove(indexOf(val)); + } + + public int compareTo(SortedIntSet t) { + if (t == this) return 0; + if (t.size() != size()) return size() - t.size(); + for (int i = 0; i < size(); i++) { + if (_data[i] != t._data[i]) return _data[i] - t._data[i]; + } + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java new file mode 100644 index 00000000000..6beba1d680d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java @@ -0,0 +1,33 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:47:33 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; +import com.intellij.codeInspection.dataFlow.value.DfaValue; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; + +public class AssignInstruction extends Instruction { + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + + DfaValue dfaSource = memState.pop(); + DfaValue dfaDest = memState.pop(); + + if (dfaDest instanceof DfaVariableValue) { + DfaVariableValue var = (DfaVariableValue) dfaDest; + memState.setVarValue(var, dfaSource); + } + + return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "ASSIGN"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java new file mode 100644 index 00000000000..e4066896c5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java @@ -0,0 +1,128 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 1:11:08 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; + +import java.util.ArrayList; + +public class BinopInstruction extends BranchingInstruction { + private final String myOperationSign; + private boolean myIsInstanceofRedundant = true; + private boolean myIsReachable = false; + private boolean myCanBeNullInInstanceof = false; + + public BinopInstruction(String opSign, PsiElement psiAnchor) { + if (opSign != null && + ("==".equals(opSign) || "!=".equals(opSign) || "instanceof".equals(opSign))) { + myOperationSign = opSign; + if (!"instanceof".equals(opSign)) myIsInstanceofRedundant = false; + } + else { + myOperationSign = null; + myIsInstanceofRedundant = false; + } + + setPsiAnchor(psiAnchor); + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + myIsReachable = true; + final Instruction next = runner.getInstruction(getIndex() + 1); + + DfaValue dfaRight = memState.pop(); + DfaValue dfaLeft = memState.pop(); + + if (myOperationSign != null) { + ArrayList states = new ArrayList(); + if (("==".equals(myOperationSign) || "!=".equals(myOperationSign)) && + dfaLeft instanceof DfaConstValue && dfaRight instanceof DfaConstValue) { + boolean negated = "!=".equals(myOperationSign); + if (dfaLeft == dfaRight ^ negated) { + memState.push(DfaConstValue.Factory.getInstance().getTrue()); + setTrueReachable(); + } + else { + memState.push(DfaConstValue.Factory.getInstance().getFalse()); + setFalseReachable(); + } + return new DfaInstructionState[]{new DfaInstructionState(next, memState)}; + } + + DfaRelationValue dfaRelation = DfaRelationValue.Factory.getInstance().create(dfaLeft, dfaRight, myOperationSign, + false); + if (dfaRelation != null) { + myCanBeNullInInstanceof = true; + + final DfaMemoryState trueCopy = memState.createCopy(); + if (trueCopy.applyCondition(dfaRelation)) { + trueCopy.push(DfaConstValue.Factory.getInstance().getTrue()); + setTrueReachable(); + states.add(new DfaInstructionState(next, trueCopy)); + } + + final DfaMemoryState falseCopy = memState; + if (falseCopy.applyCondition(dfaRelation.createNegated())) { + falseCopy.push(DfaConstValue.Factory.getInstance().getFalse()); + setFalseReachable(); + states.add(new DfaInstructionState(next, falseCopy)); + if (myIsInstanceofRedundant && !falseCopy.isNull(dfaLeft)) { + myIsInstanceofRedundant = false; + } + } + + return states.toArray(new DfaInstructionState[states.size()]); + } + else { + if ("instanceof".equals(myOperationSign) && + (dfaLeft instanceof DfaTypeValue || dfaLeft instanceof DfaNewValue) && + dfaRight instanceof DfaTypeValue) { + final PsiType leftType; + if (dfaLeft instanceof DfaNewValue) { + leftType = ((DfaNewValue)dfaLeft).getType(); + } + else { + leftType = ((DfaTypeValue)dfaLeft).getType(); + myCanBeNullInInstanceof = true; + } + + if (!((DfaTypeValue)dfaRight).getType().isAssignableFrom(leftType)) { + myIsInstanceofRedundant = false; + } + } + else { + myIsInstanceofRedundant = false; + } + memState.push(DfaUnknownValue.getInstance()); + } + } + else { + memState.push(DfaUnknownValue.getInstance()); + } + + return new DfaInstructionState[]{new DfaInstructionState(next, memState)}; + } + + public boolean isInstanceofRedundant() { + return myIsInstanceofRedundant && !isConditionConst() && myIsReachable; + } + + public boolean canBeNull() { + return myCanBeNullInInstanceof; + } + + public String toString() { + return "BINOP " + myOperationSign; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java new file mode 100644 index 00000000000..40f839d6955 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java @@ -0,0 +1,60 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 8, 2002 + * Time: 10:03:49 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; + +public abstract class BranchingInstruction extends Instruction { + protected boolean myIsTrueReachable; + protected boolean myIsFalseReachable; + private boolean isConstTrue; + private PsiElement myExpression; + + protected BranchingInstruction() { + myIsTrueReachable = false; + myIsFalseReachable = false; + setPsiAnchor(null); + } + + public boolean isTrueReachable() { + return myIsTrueReachable; + } + + public boolean isFalseReachable() { + return myIsFalseReachable; + } + + public PsiElement getPsiAnchor() { + return myExpression; + } + + protected void setTrueReachable() { + myIsTrueReachable = true; + } + + protected void setFalseReachable() { + myIsFalseReachable = true; + } + + public boolean isConditionConst() { + return !isConstTrue && myIsTrueReachable != myIsFalseReachable; + } + + private static boolean isBoolConst(PsiElement condition) { + if (!(condition instanceof PsiLiteralExpression)) return false; + String text = condition.getText(); + return "true".equals(text) || "false".equals(text); + } + + protected void setPsiAnchor(PsiElement psiAcnchor) { + myExpression = psiAcnchor; + isConstTrue = psiAcnchor != null ? isBoolConst(psiAcnchor) : false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java new file mode 100644 index 00000000000..8c52b68dd90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java @@ -0,0 +1,99 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:48:29 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + + +import com.intellij.codeInspection.dataFlow.*; +import com.intellij.codeInspection.dataFlow.value.DfaValue; +import com.intellij.codeInspection.dataFlow.value.DfaConstValue; +import com.intellij.psi.PsiElement; + +import java.util.ArrayList; + +public class ConditionalGotoInstruction extends BranchingInstruction { + private int myOffset; + private final boolean myIsNegated; + + public ConditionalGotoInstruction(int myOffset, boolean isNegated, PsiElement psiAnchor) { + this.myOffset = myOffset; + myIsNegated = isNegated; + setPsiAnchor(psiAnchor); + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + DfaValue cond = memState.pop(); + + DfaValue condTrue; + DfaValue condFalse; + + if (myIsNegated) { + condFalse = cond; + condTrue = cond.createNegated(); + } else { + condTrue = cond; + condFalse = cond.createNegated(); + } + + if (condTrue == DfaConstValue.Factory.getInstance().getTrue()) { + markBranchReachable(true); + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getOffset()), memState)}; + } + + if (condFalse == DfaConstValue.Factory.getInstance().getTrue()) { + markBranchReachable(false); + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + + ArrayList result = new ArrayList(); + + DfaMemoryState thenState = memState.createCopy(); + DfaMemoryState elseState = memState.createCopy(); + + if (thenState.applyCondition(condTrue)) { + result.add(new DfaInstructionState(runner.getInstruction(getOffset()), thenState)); + markBranchReachable(true); + } + + if (elseState.applyCondition(condFalse)) { + result.add(new DfaInstructionState(runner.getInstruction(getIndex() + 1), elseState)); + markBranchReachable(false); + } + + return (DfaInstructionState[]) result.toArray(new DfaInstructionState[result.size()]); + } + + private void markBranchReachable(boolean isTrueBranch) { + if (isTrueBranch ^ myIsNegated) { + setTrueReachable(); + } + else { + setFalseReachable(); + } + } + + public String toString() { + return "cond_goto " + myOffset; + } + + public int getOffset() { + return myOffset; + } + + public boolean isTrueReachable() { + return myIsTrueReachable; + } + + public boolean isFalseReachable() { + return myIsFalseReachable; + } + + public void setOffset(int offset) { + myOffset = offset; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java new file mode 100644 index 00000000000..55e9933a0ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java @@ -0,0 +1,25 @@ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.DfaValue; + +/** + * @author max + */ +public class DupInstruction extends Instruction { + public DupInstruction() {} + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + final DfaValue a = memState.pop(); + memState.push(a); + memState.push(a); + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "DUP"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java new file mode 100644 index 00000000000..24630445bc1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java @@ -0,0 +1,24 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:48:42 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; + + +public class EmptyInstruction extends Instruction { + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + DfaMemoryState nextState = memState; //.createCopy(); + return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, nextState)}; + } + + public String toString() { + return "EMPTY"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java new file mode 100644 index 00000000000..430e21f73e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Mar 15, 2002 + * Time: 5:04:29 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; + +public class EmptyStackInstruction extends Instruction { + public EmptyStackInstruction() { + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState dfaMemoryState) { + dfaMemoryState.emptyStack(); + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, dfaMemoryState)}; + } + + public String toString() { + return "EMTY_STACK"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java new file mode 100644 index 00000000000..8e966a6f7bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java @@ -0,0 +1,58 @@ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.DfaConstValue; +import com.intellij.codeInspection.dataFlow.value.DfaRelationValue; +import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.psi.PsiArrayAccessExpression; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiVariable; + +/** + * @author max + */ +public class FieldReferenceInstruction extends Instruction { + private PsiExpression myExpression; + private DfaRelationValue myDfaNotNull; + + public FieldReferenceInstruction(PsiReferenceExpression expression) { + this(expression.getQualifierExpression()); + myExpression = expression; + } + + public FieldReferenceInstruction(PsiArrayAccessExpression expression) { + this(expression.getArrayExpression()); + myExpression = expression; + } + + private FieldReferenceInstruction(PsiExpression varReferenceExpression) { + myDfaNotNull = null; + if (varReferenceExpression instanceof PsiReferenceExpression) { + PsiVariable psiVariable = DfaValueFactory.resolveVariable((PsiReferenceExpression)varReferenceExpression); + if (psiVariable != null) { + DfaVariableValue dfaVariable = DfaVariableValue.Factory.getInstance().create(psiVariable, false); + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + myDfaNotNull = DfaRelationValue.Factory.getInstance().create(dfaVariable, dfaNull, "==", true); + } + } + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + if (myDfaNotNull != null && !memState.applyCondition(myDfaNotNull)) { + runner.onInstructionProducesNPE(this); + return new DfaInstructionState[0]; + } + + return new DfaInstructionState[]{new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + + public String toString() { + return "FIELD_REFERENCE: " + myExpression.getText(); + } + + public PsiExpression getExpression() { return myExpression; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java new file mode 100644 index 00000000000..2a9d959cb24 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java @@ -0,0 +1,34 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:48:06 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; + +public class FlushVariableInstruction extends Instruction { + private final DfaVariableValue myVariable; + + public FlushVariableInstruction(DfaVariableValue expr) { + myVariable = expr; + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + if (myVariable != null) { + memState.flushVariable(myVariable); + } else { + memState.flushFields(runner); + } + return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "FLUSH " + (myVariable != null ? myVariable.toString() : " all fields"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java new file mode 100644 index 00000000000..19558be7f9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java @@ -0,0 +1,27 @@ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; + +/** + * @author max + */ +public class GosubInstruction extends Instruction { + private int mySubprogramOffset; + + public GosubInstruction(int subprogramOffset) { + mySubprogramOffset = subprogramOffset; + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + final int returnIndex = getIndex() + 1; + memState.pushOffset(returnIndex); + Instruction nextInstruction = runner.getInstruction(mySubprogramOffset); + return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "GOSUB: " + mySubprogramOffset; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java new file mode 100644 index 00000000000..7035ce38663 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java @@ -0,0 +1,36 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:48:19 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; + + +public class GotoInstruction extends Instruction { + private int myOffset; + + public GotoInstruction(int myOffset) { + this.myOffset = myOffset; + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + Instruction nextInstruction = runner.getInstruction(myOffset); + return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "GOTO: " + myOffset; + } + + public void setOffset(int offset) { + myOffset = offset; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/Instruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/Instruction.java new file mode 100644 index 00000000000..86c6f0075cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/Instruction.java @@ -0,0 +1,47 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:46:40 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; + +import java.util.ArrayList; + +public abstract class Instruction { + private int myIndex; + private final ArrayList myProcessedStates; + + protected Instruction() { + myProcessedStates = new ArrayList(); + } + + public abstract DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState dfaBeforeMemoryState); + + public boolean isMemoryStateProcessed(DfaMemoryState dfaMemState) { + for (int i = 0; i < myProcessedStates.size(); i++) { + DfaMemoryState state = (DfaMemoryState) myProcessedStates.get(i); + if (dfaMemState.equals(state)) return true; + } + + return false; + } + + public void setMemoryStateProcessed(DfaMemoryState dfaMemState) { + myProcessedStates.add(dfaMemState); + } + + public void setIndex(int index) { + myIndex = index; + } + + public int getIndex() { + return myIndex; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java new file mode 100644 index 00000000000..9bc8ce5e9f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java @@ -0,0 +1,64 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 26, 2002 + * Time: 10:48:52 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.DfaConstValue; +import com.intellij.codeInspection.dataFlow.value.DfaRelationValue; +import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiVariable; + + +public class MethodCallInstruction extends Instruction { + private final PsiMethodCallExpression myCall; + private DfaRelationValue myDfaNotNull; + + public MethodCallInstruction(PsiMethodCallExpression call) { + myCall = call; + myDfaNotNull = null; + PsiExpression qualifierExpression = call.getMethodExpression().getQualifierExpression(); + if (qualifierExpression instanceof PsiReferenceExpression) { + PsiReferenceExpression expression = (PsiReferenceExpression)qualifierExpression; + PsiVariable psiVariable = DfaValueFactory.resolveVariable(expression); + if (psiVariable != null) { + DfaVariableValue dfaVariable = DfaVariableValue.Factory.getInstance().create(psiVariable, false); + DfaConstValue dfaNull = DfaConstValue.Factory.getInstance().getNull(); + myDfaNotNull = DfaRelationValue.Factory.getInstance().create(dfaVariable, dfaNull, "==", true); + } + } + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + try { + if (myDfaNotNull != null && !memState.applyCondition(myDfaNotNull)) { + runner.onInstructionProducesNPE(this); + return new DfaInstructionState[0]; + } + + return new DfaInstructionState[]{new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + finally { + memState.flushFields(runner); + } + } + + public PsiMethodCallExpression getCallExpression() { + return myCall; + } + + public String toString() { + return "CALL_METHOD: " + myCall.getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java new file mode 100644 index 00000000000..8135dba6314 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 2:32:58 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; +import com.intellij.codeInspection.dataFlow.value.DfaValue; + +public class NotInstruction extends Instruction { + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + DfaValue dfaValue = memState.pop(); + + dfaValue = dfaValue.createNegated(); + memState.push(dfaValue); + + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + + public String toString() { + return "NOT"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java new file mode 100644 index 00000000000..f4655446d70 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java @@ -0,0 +1,22 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 2:32:35 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; + +public class PopInstruction extends Instruction { + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + memState.pop(); + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + + public String toString() { + return "POP"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java new file mode 100644 index 00000000000..f86f5bad8ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java @@ -0,0 +1,29 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 1:25:41 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; +import com.intellij.codeInspection.dataFlow.value.DfaValue; + +public class PushInstruction extends Instruction { + private final DfaValue myValue; + + public PushInstruction(DfaValue myValue) { + this.myValue = myValue; + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + memState.push(myValue); + return new DfaInstructionState[]{new DfaInstructionState(runner.getInstruction(getIndex() + 1),memState)}; + } + + public String toString() { + return "PUSH " + myValue; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java new file mode 100644 index 00000000000..b2b76c657e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java @@ -0,0 +1,19 @@ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; + +/** + * @author max + */ +public class ReturnFromSubInstruction extends Instruction{ + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + int offset = memState.popOffset(); + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(offset), memState)}; + } + + public String toString() { + return "RETURN_FROM_SUB"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java new file mode 100644 index 00000000000..84747314bba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java @@ -0,0 +1,21 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 10:05:49 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.*; + +public class ReturnInstruction extends Instruction { + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + return new DfaInstructionState[0]; + } + + public String toString() { + return "RETURN"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java new file mode 100644 index 00000000000..a941938f161 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java @@ -0,0 +1,26 @@ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.DfaValue; + +/** + * @author max + */ +public class SwapInstruction extends Instruction { + public SwapInstruction() {} + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + final DfaValue a = memState.pop(); + final DfaValue b = memState.pop(); + memState.push(a); + memState.push(b); + Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)}; + } + + public String toString() { + return "SWAP"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java new file mode 100644 index 00000000000..2de6a53e977 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java @@ -0,0 +1,70 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Apr 9, 2002 + * Time: 10:27:17 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.instructions; + +import com.intellij.codeInspection.dataFlow.DataFlowRunner; +import com.intellij.codeInspection.dataFlow.DfaInstructionState; +import com.intellij.codeInspection.dataFlow.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.value.*; +import com.intellij.codeInspection.redundantCast.RedundantCastUtil; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeCastExpression; + +public class TypeCastInstruction extends Instruction { + private final PsiTypeCastExpression myCastExpression; + private final DfaRelationValue myInstanceofRelation; + private final boolean myIsSemantical; + + public static TypeCastInstruction createInstruction(PsiTypeCastExpression castExpression) { + PsiExpression expr = castExpression.getOperand(); + PsiType castType = castExpression.getCastType().getType(); + + if (expr == null || castType == null) return null; + + if (RedundantCastUtil.isTypeCastSemantical(castExpression)) { + return new TypeCastInstruction(); + } + + DfaValue dfaExpr = DfaValueFactory.create(expr); + DfaTypeValue dfaType = DfaTypeValue.Factory.getInstance().create(castType); + if (dfaExpr == null) return null; + + DfaRelationValue dfaInstanceof = DfaRelationValue.Factory.getInstance().create(dfaExpr, dfaType, "instanceof", false); + return dfaInstanceof != null ? new TypeCastInstruction(castExpression, dfaInstanceof) : null; + } + + public TypeCastInstruction() { + myCastExpression = null; + myInstanceofRelation = null; + myIsSemantical = true; + } + + private TypeCastInstruction(PsiTypeCastExpression castExpression, DfaRelationValue instanceofRelation) { + myIsSemantical = false; + myCastExpression = castExpression; + myInstanceofRelation = instanceofRelation; + } + + public DfaInstructionState[] apply(DataFlowRunner runner, DfaMemoryState memState) { + if (myIsSemantical) { + memState.pop(); + memState.push(DfaUnknownValue.getInstance()); + } + else if (!memState.applyInstanceofOrNull(myInstanceofRelation)) { + runner.onInstructionProducesCCE(this); + } + + return new DfaInstructionState[] {new DfaInstructionState(runner.getInstruction(getIndex() + 1), memState)}; + } + + public PsiTypeCastExpression getCastExpression() { + return myCastExpression; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java new file mode 100644 index 00000000000..da3ee6c9ca7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java @@ -0,0 +1,99 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 6:31:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.psi.PsiLiteralExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiVariable; +import com.intellij.util.containers.HashMap; + +public class DfaConstValue extends DfaValue { + public static class Factory { + private DfaConstValue dfaNull; + private DfaConstValue dfaFalse; + private DfaConstValue dfaTrue; + + + private static volatile Factory myInstance; + private final HashMap myValues; + + private Factory() { + myValues = new HashMap(); + dfaNull = new DfaConstValue(null); + dfaFalse = new DfaConstValue(Boolean.FALSE); + dfaTrue = new DfaConstValue(Boolean.TRUE); + } + + public static Factory getInstance() { + if (myInstance == null) { + myInstance = new Factory(); + } + return myInstance; + } + + public static void freeInstance() { + myInstance = null; + } + + public DfaConstValue create(PsiLiteralExpression expr) { + if (expr.getType() == PsiType.NULL) return dfaNull; + Object value = expr.getValue(); + if (value == null) return null; + return createFromValue(value); + } + + public DfaConstValue create(PsiVariable variable) { + Object value = variable.computeConstantValue(); + if (value == null) return null; + return createFromValue(value); + } + + private DfaConstValue createFromValue(Object value) { + if (value == Boolean.TRUE) return dfaTrue; + if (value == Boolean.FALSE) return dfaFalse; + + DfaConstValue instance = myValues.get(value); + if (instance == null) { + instance = new DfaConstValue(value); + myValues.put(value, instance); + } + + return instance; + } + + public DfaConstValue getFalse() { + return dfaFalse; + } + + public DfaConstValue getTrue() { + return dfaTrue; + } + + public DfaConstValue getNull() { + return dfaNull; + } + } + + private Object myValue; + + private DfaConstValue(Object value) { + myValue = value; + } + + public String toString() { + if (myValue == null) return "null"; + return myValue.toString(); + } + + public DfaValue createNegated() { + if (this == Factory.getInstance().getTrue()) return Factory.getInstance().getFalse(); + if (this == Factory.getInstance().getFalse()) return Factory.getInstance().getTrue(); + return DfaUnknownValue.getInstance(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaNewValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaNewValue.java new file mode 100644 index 00000000000..387d386e307 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaNewValue.java @@ -0,0 +1,80 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 6:45:14 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.psi.PsiType; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class DfaNewValue extends DfaValue { + public static class Factory { + private static volatile Factory myInstance; + private final DfaNewValue mySharedInstance; + private final HashMap> myStringToObject; + + private Factory() { + mySharedInstance = new DfaNewValue(); + myStringToObject = new HashMap>(); + } + + public static Factory getInstance() { + if (myInstance == null) { + myInstance = new Factory(); + } + return myInstance; + } + + public static void freeInstance() { + myInstance = null; + } + + public DfaValue create(PsiType type) { + if (type == null) return DfaUnknownValue.getInstance(); + mySharedInstance.myType = type; + + String id = mySharedInstance.toString(); + ArrayList conditions = myStringToObject.get(id); + if (conditions == null) { + conditions = new ArrayList(); + myStringToObject.put(id, conditions); + } else { + for (int i = 0; i < conditions.size(); i++) { + DfaNewValue aNew = conditions.get(i); + if (aNew.hardEquals(mySharedInstance)) return aNew; + } + } + + DfaNewValue result = new DfaNewValue(type); + conditions.add(result); + return result; + } + } + + private PsiType myType; + + private DfaNewValue(PsiType myType) { + this.myType = myType; + } + + private DfaNewValue() { + } + + public String toString() { + return "new " + myType.getCanonicalText(); + } + + public PsiType getType() { + return myType; + } + + private boolean hardEquals(DfaNewValue aNew) { + return aNew.myType == myType; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java new file mode 100644 index 00000000000..f339201f07f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java @@ -0,0 +1,143 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 6, 2002 + * Time: 10:01:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class DfaRelationValue extends DfaValue { + private DfaValue myLeftOperand; + private DfaValue myRightOperand; + private String myRelation; + private boolean myIsNegated; + + public static class Factory { + private static volatile Factory myInstance; + private final DfaRelationValue mySharedInstance; + private final HashMap> myStringToObject; + + private Factory() { + mySharedInstance = new DfaRelationValue(); + myStringToObject = new HashMap>(); + } + + public static Factory getInstance() { + if (myInstance == null) { + myInstance = new Factory(); + } + return myInstance; + } + + public static void freeInstance() { + myInstance = null; + } + + public DfaRelationValue create(DfaValue dfaLeft, DfaValue dfaRight, String relation, boolean negated) { + if (dfaRight instanceof DfaTypeValue && !"instanceof".equals(relation)) return null; + + if (!(dfaLeft instanceof DfaVariableValue || dfaRight instanceof DfaVariableValue)) { + return null; + } + + if (!(dfaLeft instanceof DfaVariableValue)) { + return create(dfaRight, dfaLeft, getSymmetricOperation(relation), negated); + } + + // To canonical form. + if ("!=".equals(relation)) { + relation = "=="; + negated = !negated; + } + else if ("<".equals(relation)) { + relation = ">="; + negated = !negated; + } + else if ("<=".equals(relation)) { + relation = ">"; + negated = !negated; + } + + mySharedInstance.myLeftOperand = dfaLeft; + mySharedInstance.myRightOperand = dfaRight; + mySharedInstance.myRelation = relation; + mySharedInstance.myIsNegated = negated; + + String id = mySharedInstance.toString(); + ArrayList conditions = myStringToObject.get(id); + if (conditions == null) { + conditions = new ArrayList(); + myStringToObject.put(id, conditions); + } + else { + for (int i = 0; i < conditions.size(); i++) { + DfaRelationValue rel = conditions.get(i); + if (rel.hardEquals(mySharedInstance)) return rel; + } + } + + DfaRelationValue result = new DfaRelationValue(dfaLeft, dfaRight, relation, negated); + conditions.add(result); + return result; + } + + private static String getSymmetricOperation(String sign) { + if ("<".equals(sign)) { + return ">"; + } + else if (">=".equals(sign)) { + return "<="; + } + else if (">".equals(sign)) { + return "<"; + } + else if ("<=".equals(sign)) { + return ">="; + } + + return sign; + } + } + + private DfaRelationValue() { + } + + private DfaRelationValue(DfaValue myLeftOperand, DfaValue myRightOperand, String myRelation, boolean myIsNegated) { + this.myLeftOperand = myLeftOperand; + this.myRightOperand = myRightOperand; + this.myRelation = myRelation; + this.myIsNegated = myIsNegated; + } + + public DfaValue getLeftOperand() { + return myLeftOperand; + } + + public DfaValue getRightOperand() { + return myRightOperand; + } + + public boolean isNegated() { + return myIsNegated; + } + + public DfaValue createNegated() { + return Factory.getInstance().create(myLeftOperand, myRightOperand, myRelation, !myIsNegated); + } + + private boolean hardEquals(DfaRelationValue rel) { + return rel.myLeftOperand.equals(myLeftOperand) && rel.myRightOperand.equals(myRightOperand) && + rel.myRelation.equals(myRelation) && + rel.myIsNegated == myIsNegated; + } + + public String toString() { + return (isNegated() ? "not " : "") + myLeftOperand + myRelation + myRightOperand; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java new file mode 100644 index 00000000000..f8736d4f552 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java @@ -0,0 +1,101 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 6:32:01 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class DfaTypeValue extends DfaValue { + public static class Factory { + private static volatile Factory ourInstance; + private final DfaTypeValue mySharedInstance; + private final HashMap> myStringToObject; + + private Factory() { + mySharedInstance = new DfaTypeValue(); + myStringToObject = new HashMap>(); + } + + public static Factory getInstance() { + if (ourInstance == null) { + ourInstance = new Factory(); + } + return ourInstance; + } + + public static void freeInstance() { + ourInstance = null; + } + + public DfaTypeValue create(PsiType myType) { + mySharedInstance.myType = myType; + mySharedInstance.myCanonicalText = myType.getCanonicalText(); + if (mySharedInstance.myCanonicalText == null) { + mySharedInstance.myCanonicalText = "null"; + } + + String id = mySharedInstance.toString(); + ArrayList conditions = myStringToObject.get(id); + if (conditions == null) { + conditions = new ArrayList(); + myStringToObject.put(id, conditions); + } else { + for (int i = 0; i < conditions.size(); i++) { + DfaTypeValue aType = conditions.get(i); + if (aType.hardEquals(mySharedInstance)) return aType; + } + } + + DfaTypeValue result = new DfaTypeValue(myType); + conditions.add(result); + return result; + } + } + + private PsiType myType; + private String myCanonicalText; + + private DfaTypeValue() { + } + + private DfaTypeValue(PsiType type) { + myType = type; + myCanonicalText = type.getCanonicalText(); + if (myCanonicalText == null) { + myCanonicalText = "null"; + } + } + + public PsiType getType() { + return myType; + } + + public String toString() { + return myCanonicalText; + } + + private boolean hardEquals(DfaTypeValue aType) { + return aType.toString().equals(toString()); + } + + public boolean isAssignableFrom(DfaTypeValue dfaType) { + if (dfaType == null) return false; + return myType.isAssignableFrom(dfaType.myType); + } + + public boolean isConvertibleFrom(DfaTypeValue dfaType) { + if (dfaType == null) return false; + return myType.isConvertibleFrom(dfaType.myType); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java new file mode 100644 index 00000000000..0baf9b2f1f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java @@ -0,0 +1,44 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 11:23:22 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +public class DfaUnknownValue extends DfaValue { + private static volatile DfaUnknownValue myInstance; + + public static DfaUnknownValue getInstance() { + if (myInstance == null) { + myInstance = new DfaUnknownValue(); + } + return myInstance; + } + + private DfaUnknownValue() { + } + + public DfaValue createNegated() { + return this; + } + + public String toString() { + return ""; + } + + public boolean equals(Object obj) { + return obj == this; + } + + public int hashCode() { + return 0; + } + + public int getID() { + return 0; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValue.java new file mode 100644 index 00000000000..8fd5d567ab8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValue.java @@ -0,0 +1,26 @@ +package com.intellij.codeInspection.dataFlow.value; + +public class DfaValue { + private final int myID; + + protected DfaValue() { + myID = DfaValueFactory.getInstance().createID(this); + } + + public int getID() { + return myID; + } + + public DfaValue createNegated() { + return DfaUnknownValue.getInstance(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof DfaValue)) return false; + return getID() == ((DfaValue) obj).getID(); + } + + public int hashCode() { + return getID(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java new file mode 100644 index 00000000000..da1e0ceaa35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java @@ -0,0 +1,94 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 7, 2002 + * Time: 2:33:28 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import gnu.trove.TIntObjectHashMap; + +public class DfaValueFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.value.DfaValueFactory"); + + private static volatile DfaValueFactory myInstance = null; + private int myLastID; + private TIntObjectHashMap myValues; + + private DfaValueFactory() { + myValues = new TIntObjectHashMap(); + myLastID = 0; + } + + public static DfaValueFactory getInstance() { + if (myInstance == null) { + myInstance = new DfaValueFactory(); + } + + return myInstance; + } + + public int createID(DfaValue value) { + myLastID++; + LOG.assertTrue(myLastID >= 0, "Overflow"); + myValues.put(myLastID, value); + return myLastID; + } + + public DfaValue getValue(int id) { + return myValues.get(id); + } + + public static DfaValue create(PsiExpression psiExpression) { + DfaValue result = null; + + if (psiExpression instanceof PsiReferenceExpression) { + PsiElement psiSource = ((PsiReferenceExpression)psiExpression).resolve(); + + if (psiSource != null) { + if (psiSource instanceof PsiVariable) { + DfaConstValue constValue = DfaConstValue.Factory.getInstance().create((PsiVariable)psiSource); + if (constValue != null) return constValue; + } + + PsiVariable psiVariable = resolveVariable((PsiReferenceExpression)psiExpression); + if (psiVariable != null) { + result = DfaVariableValue.Factory.getInstance().create(psiVariable, false); + } + } + } + else if (psiExpression instanceof PsiLiteralExpression) { + result = DfaConstValue.Factory.getInstance().create((PsiLiteralExpression)psiExpression); + } + else if (psiExpression instanceof PsiNewExpression) { + result = DfaNewValue.Factory.getInstance().create(psiExpression.getType()); + } + + return result; + } + + public static PsiVariable resolveVariable(PsiReferenceExpression refExpression) { + PsiExpression qualifier = refExpression.getQualifierExpression(); + if (qualifier == null || qualifier instanceof PsiThisExpression) { + PsiElement resolved = refExpression.resolve(); + if (resolved instanceof PsiVariable) { + return (PsiVariable)resolved; + } + } + + return null; + } + + public static void freeInstance() { + DfaVariableValue.Factory.freeInstance(); + DfaConstValue.Factory.freeInstance(); + DfaNewValue.Factory.freeInstance(); + DfaTypeValue.Factory.freeInstance(); + DfaRelationValue.Factory.freeInstance(); + myInstance = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java new file mode 100644 index 00000000000..3ca53e73c94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java @@ -0,0 +1,93 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 28, 2002 + * Time: 6:31:08 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.dataFlow.value; + +import com.intellij.psi.PsiVariable; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class DfaVariableValue extends DfaValue { + public static class Factory { + private static volatile Factory myInstance; + private final DfaVariableValue mySharedInstance; + private final HashMap> myStringToObject; + + private Factory() { + mySharedInstance = new DfaVariableValue(); + myStringToObject = new HashMap>(); + } + + public static Factory getInstance() { + if (myInstance == null) { + myInstance = new Factory(); + } + return myInstance; + } + + public static void freeInstance() { + myInstance = null; + } + + public DfaVariableValue create(PsiVariable myVariable, boolean isNegated) { + mySharedInstance.myVariable = myVariable; + mySharedInstance.myIsNegated = isNegated; + + String id = mySharedInstance.toString(); + ArrayList conditions = myStringToObject.get(id); + if (conditions == null) { + conditions = new ArrayList(); + myStringToObject.put(id, conditions); + } else { + for (int i = 0; i < conditions.size(); i++) { + DfaVariableValue aVar = conditions.get(i); + if (aVar.hardEquals(mySharedInstance)) return aVar; + } + } + + DfaVariableValue result = new DfaVariableValue(myVariable, isNegated); + conditions.add(result); + return result; + } + } + + private PsiVariable myVariable; + private boolean myIsNegated; + + private DfaVariableValue(PsiVariable variable, boolean isNegated) { + myVariable = variable; + myIsNegated = isNegated; + } + + private DfaVariableValue() { + myVariable = null; + myIsNegated = false; + } + + public PsiVariable getPsiVariable() { + return myVariable; + } + + public boolean isNegated() { + return myIsNegated; + } + + public DfaValue createNegated() { + return Factory.getInstance().create(getPsiVariable(), !myIsNegated); + } + + public String toString() { + if (myVariable == null) return "$currentException"; + return (myIsNegated ? "!" : "") + myVariable.getName(); + } + + private boolean hardEquals(DfaVariableValue aVar) { + return aVar.myVariable == myVariable && aVar.myIsNegated == myIsNegated; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadCodeInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadCodeInspection.java new file mode 100644 index 00000000000..6e6b7871c02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadCodeInspection.java @@ -0,0 +1,820 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 12, 2001 + * Time: 9:40:45 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ + +package com.intellij.codeInspection.deadCode; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.reference.*; +import com.intellij.codeInspection.util.RefFilter; +import com.intellij.codeInspection.util.XMLExportUtl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiNonJavaFileReferenceProcessor; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.util.containers.HashMap; +import com.intellij.util.text.CharArrayUtil; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; + +public class DeadCodeInspection extends FilteringInspectionTool { + public boolean ADD_MAINS_TO_ENTRIES = true; + public boolean ADD_JUNIT_TO_ENTRIES = true; + public boolean ADD_EJB_TO_ENTRIES = true; + public boolean ADD_APPLET_TO_ENTRIES = true; + public boolean ADD_SERVLET_TO_ENTRIES = true; + public boolean ADD_NONJAVA_TO_ENTRIES = true; + + private final Project myProject; + private HashSet myProcessedSuspicious = null; + private int myPhase; + private QuickFixAction[] myQuickFixActions; + public static final String DISPLAY_NAME = "Unused declaration"; + private RefUnreferencedFilter myFilter; + private DeadHTMLComposer myComposer; + public static final String SHORT_NAME = "UnusedDeclaration"; + + public DeadCodeInspection(Project project) { + myProject = project; + myQuickFixActions = new QuickFixAction[]{new PermanentDeleteAction(), new CommentOutBin(), new MoveToEntries()}; + } + + private class OptionsPanel extends JPanel { + private JCheckBox myMainsCheckbox; + private JCheckBox myJUnitCheckbox; + private JCheckBox myEJBMethodsCheckbox; + private JCheckBox myAppletToEntries; + private JCheckBox myServletToEntries; + private JCheckBox myNonJavaCheckbox; + + private OptionsPanel() { + super(new GridBagLayout()); + GridBagConstraints gc = new GridBagConstraints(); + gc.weightx = 1; + gc.weighty = 0; + gc.fill = GridBagConstraints.HORIZONTAL; + gc.anchor = GridBagConstraints.NORTHWEST; + + myMainsCheckbox = new JCheckBox("Automatically add all void main(String args[]) methods to entry points"); + myMainsCheckbox.setSelected(ADD_MAINS_TO_ENTRIES); + myMainsCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myMainsCheckbox.isSelected(); + ADD_MAINS_TO_ENTRIES = selected; + } + }); + + gc.gridy = 0; + add(myMainsCheckbox, gc); + + myEJBMethodsCheckbox = new JCheckBox("Automatically add all EJB interface methods to entry points"); + myEJBMethodsCheckbox.setSelected(ADD_EJB_TO_ENTRIES); + myEJBMethodsCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myEJBMethodsCheckbox.isSelected(); + ADD_EJB_TO_ENTRIES = selected; + } + }); + gc.gridy++; + add(myEJBMethodsCheckbox, gc); + + myJUnitCheckbox = new JCheckBox("Automatically add all JUnit testcases to entry points"); + myJUnitCheckbox.setSelected(ADD_JUNIT_TO_ENTRIES); + myJUnitCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myJUnitCheckbox.isSelected(); + ADD_JUNIT_TO_ENTRIES = selected; + } + }); + + gc.gridy++; + add(myJUnitCheckbox, gc); + + myAppletToEntries = new JCheckBox("Automatically add all applets to entry points"); + myAppletToEntries.setSelected(ADD_APPLET_TO_ENTRIES); + myAppletToEntries.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myAppletToEntries.isSelected(); + ADD_APPLET_TO_ENTRIES = selected; + } + }); + gc.gridy++; + add(myAppletToEntries, gc); + + myServletToEntries = new JCheckBox("Automatically add all servlets to entry points"); + myServletToEntries.setSelected(ADD_SERVLET_TO_ENTRIES); + myServletToEntries.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myServletToEntries.isSelected(); + ADD_SERVLET_TO_ENTRIES = selected; + } + }); + gc.gridy++; + add(myServletToEntries, gc); + + myNonJavaCheckbox = + new JCheckBox("Automatically add classes that have usages in non-java files to entry points"); + myNonJavaCheckbox.setSelected(ADD_NONJAVA_TO_ENTRIES); + myNonJavaCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myNonJavaCheckbox.isSelected(); + ADD_NONJAVA_TO_ENTRIES = selected; + } + }); + + gc.gridy++; + gc.weighty = 1; + add(myNonJavaCheckbox, gc); + } + } + + public JComponent createOptionsPanel() { + return new OptionsPanel(); + } + + private boolean isAddMainsEnabled() { + return ADD_MAINS_TO_ENTRIES; + } + + private boolean isAddJUnitEnabled() { + return ADD_JUNIT_TO_ENTRIES; + } + + private boolean isAddAppletEnabled() { + return ADD_APPLET_TO_ENTRIES; + } + + private boolean isAddServletEnabled() { + return ADD_SERVLET_TO_ENTRIES; + } + + private boolean isAddEjbInterfaceMethodsEnabled() { + return ADD_EJB_TO_ENTRIES; + } + + private boolean isAddNonJavaUsedEnabled() { + return ADD_NONJAVA_TO_ENTRIES; + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return ""; + } + + public String getShortName() { + return SHORT_NAME; + } + + private static boolean isSerialVersionUIDField(PsiField field) { + if (!"serialVersionUID".equals(field.getName())) return false; + if (!field.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = field.getContainingClass(); + if (aClass != null && !isSerializable(aClass)) return false; + return true; + } + + private static boolean isWriteObjectMethod(PsiMethod method) { + if (!"writeObject".equals(method.getName())) return false; + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 1) return false; + if (!parameters[0].getType().equalsToText("java.io.ObjectOutputStream")) return false; + if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = method.getContainingClass(); + if (aClass != null && !isSerializable(aClass)) return false; + return true; + } + + private static boolean isReadObjectMethod(PsiMethod method) { + if (!"readObject".equals(method.getName())) return false; + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 1) return false; + if (!parameters[0].getType().equalsToText("java.io.ObjectInputStream")) return false; + if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = method.getContainingClass(); + if (aClass != null && !isSerializable(aClass)) return false; + return true; + } + + private static boolean isWriteReplaceMethod(PsiMethod method) { + if (!"writeReplace".equals(method.getName())) return false; + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 0) return false; + if (!method.getReturnType().equalsToText("java.lang.Object")) return false; + if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = method.getContainingClass(); + if (aClass != null && !isSerializable(aClass)) return false; + return true; + } + + private static boolean isReadResolveMethod(PsiMethod method) { + if (!"readResolve".equals(method.getName())) return false; + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 0) return false; + if (!method.getReturnType().equalsToText("java.lang.Object")) return false; + if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = method.getContainingClass(); + if (aClass != null && !isSerializable(aClass)) return false; + return true; + } + + private static boolean isSerializable(PsiClass aClass) { + PsiClass serializableClass = aClass.getManager().findClass("java.io.Serializable", aClass.getResolveScope()); + if (serializableClass == null) return false; + return aClass.isInheritor(serializableClass, true); + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); // Find all declaration elements. + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(final RefElement refElement) { + if (!refElement.isSuspicious()) return; + refElement.accept(new RefVisitor() { + public void visitMethod(RefMethod method) { + if (isAddMainsEnabled() && method.isAppMain()) { + getEntryPointsManager().addEntryPoint(method, false); + } + } + + public void visitClass(RefClass aClass) { + if (isAddJUnitEnabled() && aClass.isTestCase()) { + PsiClass psiClass = (PsiClass)aClass.getElement(); + addTestcaseEntries(psiClass); + } + else if ( + isAddAppletEnabled() && aClass.isApplet() || + isAddServletEnabled() && aClass.isServlet() || + aClass.isEjb()) { + getEntryPointsManager().addEntryPoint(aClass, false); + } + } + }); + } + }); + + if (isAddNonJavaUsedEnabled()) { + checkForReachables(); + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + final RefFilter filter = new StrictUnreferencedFilter(); + final PsiSearchHelper helper = PsiManager.getInstance(getRefManager().getProject()).getSearchHelper(); + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(final RefElement refElement) { + if (refElement instanceof RefClass && filter.accepts(refElement)) { + findExternalClassReferences((RefClass)refElement); + } + else if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElement; + if (refMethod.isConstructor() && filter.accepts(refMethod)) { + findExternalClassReferences(refMethod.getOwnerClass()); + } + } + } + + private void findExternalClassReferences(final RefClass refElement) { + PsiClass psiClass = (PsiClass)refElement.getElement(); + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName != null) { + helper.processUsagesInNonJavaFiles(qualifiedName, + new PsiNonJavaFileReferenceProcessor() { + public boolean process(PsiFile file, int startOffset, int endOffset) { + getEntryPointsManager().addEntryPoint(refElement, false); + return false; + } + }, + GlobalSearchScope.projectScope(myProject)); + } + } + }); + } + }, null); + } + + myProcessedSuspicious = new HashSet(); + myPhase = 1; + } + + private void addTestcaseEntries(PsiClass testClass) { + RefClass refClass = (RefClass)getRefManager().getReference(testClass); + getEntryPointsManager().addEntryPoint(refClass, false); + PsiMethod[] testMethods = testClass.getMethods(); + for (int j = 0; j < testMethods.length; j++) { + PsiMethod psiMethod = testMethods[j]; + if (psiMethod.hasModifierProperty(PsiModifier.PUBLIC) && + !psiMethod.hasModifierProperty(PsiModifier.ABSTRACT) && + psiMethod.getName().startsWith("test") || "suite".equals(psiMethod.getName())) { + RefMethod refMethod = (RefMethod)getRefManager().getReference(psiMethod); + getEntryPointsManager().addEntryPoint(refMethod, false); + } + } + } + + private static class StrictUnreferencedFilter extends RefFilter { + public int getElementProblemCount(RefElement refElement) { + if (refElement instanceof RefParameter) return 0; + if (refElement.isEntry() || !refElement.isSuspicious()) return 0; + + if (refElement instanceof RefField) { + RefField refField = (RefField)refElement; + if (refField.isUsedForReading() && !refField.isUsedForWriting()) return 1; + if (refField.isUsedForWriting() && !refField.isUsedForReading()) return 1; + } + + if (refElement instanceof RefClass && ((RefClass)refElement).isAnonymous()) return 0; + return refElement.isReferenced() ? 0 : 1; + } + } + + public boolean queryExternalUsagesRequests() { + checkForReachables(); + final RefFilter filter = myPhase == 1 ? (RefFilter)new StrictUnreferencedFilter() : new RefUnreachableFilter(); + final boolean[] requestAdded = new boolean[]{false}; + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefClass && ((RefClass)refElement).isAnonymous()) return; + if (filter.accepts(refElement) && !myProcessedSuspicious.contains(refElement)) { + refElement.accept(new RefVisitor() { + public void visitField(final RefField refField) { + myProcessedSuspicious.add(refField); + PsiField psiField = (PsiField)refField.getElement(); + if (isSerialVersionUIDField(psiField)) { + getEntryPointsManager().addEntryPoint(refField, false); + return; + } + + getManager().enqueueFieldUsagesProcessor(refField, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + getEntryPointsManager().addEntryPoint(refField, false); + return false; + } + }); + requestAdded[0] = true; + } + + public void visitMethod(final RefMethod refMethod) { + myProcessedSuspicious.add(refMethod); + if (refMethod instanceof RefImplicitConstructor) { + visitClass(refMethod.getOwnerClass()); + } + else { + PsiMethod psiMethod = (PsiMethod)refMethod.getElement(); + if (isSerializablePatternMethod(psiMethod)) { + getEntryPointsManager().addEntryPoint(refMethod, false); + return; + } + + if (!refMethod.isLibraryOverride() && refMethod.getAccessModifier() != PsiModifier.PRIVATE) { + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + myProcessedSuspicious.add(iterator.next()); + } + + if (isAddEjbInterfaceMethodsEnabled()) { + if (refMethod.isEjbDeclaration() || refMethod.isEjbImplementation()) { + addEjbMethodToEntries(refMethod); + return; + } + } + + enqueueMethodUsages(refMethod); + requestAdded[0] = true; + } + } + } + + public void visitClass(final RefClass refClass) { + myProcessedSuspicious.add(refClass); + if (refClass.isEjb()) { + getEntryPointsManager().addEntryPoint(refClass, false); + } + else if (!refClass.isAnonymous()) { + getManager().enqueueDerivedClassesProcessing(refClass, new InspectionManagerEx.DerivedClassesProcessor() { + public boolean process(PsiClass inheritor) { + getEntryPointsManager().addEntryPoint(refClass, false); + return false; + } + }); + + getManager().enqueueClassUsagesProcessing(refClass, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + getEntryPointsManager().addEntryPoint(refClass, false); + return false; + } + }); + requestAdded[0] = true; + } + } + }); + } + } + }); + + if (!requestAdded[0]) { + if (myPhase == 2) { + myProcessedSuspicious = null; + return false; + } + else { + myPhase = 2; + } + } + + return true; + } + + private static boolean isSerializablePatternMethod(PsiMethod psiMethod) { + return isReadObjectMethod(psiMethod) || isWriteObjectMethod(psiMethod) || isReadResolveMethod(psiMethod) || + isWriteReplaceMethod(psiMethod); + } + + private void addEjbMethodToEntries(RefMethod refMethod) { + getEntryPointsManager().addEntryPoint(refMethod, false); + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + addEjbMethodToEntries(refSuper); + } + } + + private void enqueueMethodUsages(final RefMethod refMethod) { + if (refMethod.getSuperMethods().isEmpty()) { + getManager().enqueueMethodUsagesProcessor(refMethod, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + getEntryPointsManager().addEntryPoint(refMethod, false); + return false; + } + }); + } + else { + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + enqueueMethodUsages(refSuper); + } + } + } + + public RefFilter getFilter() { + if (myFilter == null) { + myFilter = new RefUnreferencedFilter(); + } + return myFilter; + } + + public HTMLComposer getComposer() { + if (myComposer == null) { + myComposer = new DeadHTMLComposer(this); + } + return myComposer; + } + + public void exportResults(final org.jdom.Element parentNode) { + final RefUnreferencedFilter filter = new RefUnreferencedFilter(); + final DeadHTMLComposer composer = new DeadHTMLComposer(this); + + checkForReachables(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (filter.accepts(refElement)) { + if (refElement instanceof RefImplicitConstructor) return; + org.jdom.Element element = XMLExportUtl.createElement(refElement, parentNode, -1); + org.jdom.Element problemClassElement = new org.jdom.Element("problem_class"); + problemClassElement.addContent("unused declaration"); + element.addContent(problemClassElement); + + org.jdom.Element descriptionElement = new org.jdom.Element("description"); + StringBuffer buf = new StringBuffer(); + composer.appendProblemSynopsis(refElement, buf); + descriptionElement.addContent(buf.toString()); + element.addContent(descriptionElement); + } + } + }); + } + + public QuickFixAction[] getQuickFixes() { + return myQuickFixActions; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[]{InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + private void commentOutDead(PsiElement psiElement) { + PsiFile psiFile = psiElement.getContainingFile(); + + if (psiFile != null) { + Document doc = PsiDocumentManager.getInstance(myProject).getDocument(psiFile); + TextRange textRange = psiElement.getTextRange(); + SimpleDateFormat format = new SimpleDateFormat(); + String date = format.format(new Date()); + + int startOffset = textRange.getStartOffset(); + CharSequence chars = doc.getCharsSequence(); + while (CharArrayUtil.regionMatches(chars, startOffset, "// --Commented out by Inspection")) { + int line = doc.getLineNumber(startOffset) + 1; + if (line < doc.getLineCount()) { + startOffset = doc.getLineStartOffset(line); + startOffset = CharArrayUtil.shiftForward(chars, startOffset, " \t"); + } + } + + int endOffset = textRange.getEndOffset(); + + int line1 = doc.getLineNumber(startOffset); + int line2 = doc.getLineNumber(endOffset - 1); + + if (line1 == line2) { + doc.insertString(startOffset, "// --Commented out by Inspection (" + date + "): "); + } + else { + for (int i = line1; i <= line2; i++) { + doc.insertString(doc.getLineStartOffset(i), "//"); + } + + doc.insertString(doc.getLineStartOffset(Math.min(line2 + 1, doc.getLineCount() - 1)), + "// --Commented out by Inspection STOP (" + date + ")" + "\n"); + doc.insertString(doc.getLineStartOffset(line1), "// --Commented out by Inspection START (" + date + "):" + "\n"); + } + } + } + + private static EntryPointsManager getEntryPointsManager(Project project) { + return EntryPointsManager.getInstance(project); + } + + private class PermanentDeleteAction extends QuickFixAction { + public PermanentDeleteAction() { + super("Safe Delete", IconLoader.getIcon("/actions/cancel.png"), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + DeadCodeInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + ArrayList deletedRefs = new ArrayList(1); + final ArrayList psiElements = new ArrayList(); + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiElement psiElement = refElement.getElement(); + if (psiElement == null) continue; + psiElements.add(psiElement); + RefUtil.removeRefElement(refElement, deletedRefs); + } + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + new SafeDeleteHandler().invoke(myProject, psiElements.toArray(new PsiElement[psiElements.size()]), false); + } + }); + + return true; + } + } + + private class CommentOutBin extends QuickFixAction { + public CommentOutBin() { + super("Comment Out", null, KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, + SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), + DeadCodeInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + ArrayList deletedRefs = new ArrayList(1); + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiElement psiElement = refElement.getElement(); + if (psiElement == null) continue; + commentOutDead(psiElement); + RefUtil.removeRefElement(refElement, deletedRefs); + } + + EntryPointsManager entryPointsManager = getEntryPointsManager(myProject); + for (int i = 0; i < deletedRefs.size(); i++) { + RefElement refElement = deletedRefs.get(i); + entryPointsManager.removeEntryPoint(refElement); + } + + return true; + } + } + + private class MoveToEntries extends QuickFixAction { + private MoveToEntries() { + super("Add as Entry Point", null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), DeadCodeInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + EntryPointsManager.getInstance(getManager().getProject()).addEntryPoint(refElement, true); + } + + return true; + } + } + + public void checkForReachables() { + CodeScanner codeScanner = new CodeScanner(); + + // Cleanup previous reachability information. + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + refElement.setReachable(false); + } + }); + + + SmartRefElementPointer[] entryPoints = getEntryPointsManager().getEntryPoints(); + for (int i = 0; i < entryPoints.length; i++) { + SmartRefElementPointer entry = entryPoints[i]; + if (entry.getRefElement() != null) { + processEntryPoint(entry.getRefElement(), codeScanner); + } + } + + while (codeScanner.newlyInstantiatedClassesCount() != 0) { + codeScanner.cleanInstantiatedClassesCount(); + codeScanner.processDelayedMethods(); + } + } + + private static class CodeScanner extends RefVisitor { + private final HashMap> myClassIDtoMethods; + private final HashSet myInstantiatedClasses; + private int myInstantiatedClassesCount; + private final HashSet myProcessedMethods; + + private CodeScanner() { + myClassIDtoMethods = new HashMap>(); + myInstantiatedClasses = new HashSet(); + myProcessedMethods = new HashSet(); + myInstantiatedClassesCount = 0; + } + + public void visitMethod(RefMethod method) { + if (!myProcessedMethods.contains(method)) { + // Process class's static intitializers + if (method.isStatic() || method.isConstructor()) { + if (method.isConstructor()) { + addInstantiatedClass(method.getOwnerClass()); + } + else { + method.getOwnerClass().setReachable(true); + } + myProcessedMethods.add(method); + makeContentReachable(method); + makeClassInitializersReachable(method.getOwnerClass()); + } + else { + if (isClassInstantiated(method.getOwnerClass())) { + myProcessedMethods.add(method); + makeContentReachable(method); + } + else { + addDelayedMethod(method); + } + + for (Iterator iterator = method.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refSub = iterator.next(); + visitMethod(refSub); + } + } + } + } + + public void visitClass(RefClass refClass) { + boolean alreadyActive = refClass.isReachable(); + refClass.setReachable(true); + + if (!alreadyActive) { + // Process class's static intitializers. + makeClassInitializersReachable(refClass); + } + + addInstantiatedClass(refClass); + } + + public void visitField(RefField field) { + // Process class's static intitializers. + if (!field.isReachable()) { + makeContentReachable(field); + makeClassInitializersReachable(field.getOwnerClass()); + } + } + + private void addInstantiatedClass(RefClass refClass) { + if (myInstantiatedClasses.add(refClass)) { + refClass.setReachable(true); + myInstantiatedClassesCount++; + + ArrayList methods = refClass.getLibraryMethods(); + for (int i = 0; i < methods.size(); i++) { + RefMethod refMethod = methods.get(i); + refMethod.accept(this); + } + + for (Iterator iterator = refClass.getBaseClasses().iterator(); iterator.hasNext();) { + RefClass baseClass = iterator.next(); + addInstantiatedClass(baseClass); + } + } + } + + private void makeContentReachable(RefElement refElement) { + refElement.setReachable(true); + for (Iterator iterator = refElement.getOutReferences().iterator(); iterator.hasNext();) { + RefElement refCallee = iterator.next(); + refCallee.accept(this); + } + } + + private void makeClassInitializersReachable(RefClass refClass) { + for (Iterator iterator = refClass.getOutReferences().iterator(); iterator.hasNext();) { + RefElement refCallee = iterator.next(); + refCallee.accept(this); + } + } + + private void addDelayedMethod(RefMethod refMethod) { + HashSet methods = myClassIDtoMethods.get(refMethod.getOwnerClass()); + if (methods == null) { + methods = new HashSet(); + myClassIDtoMethods.put(refMethod.getOwnerClass(), methods); + } + methods.add(refMethod); + } + + private boolean isClassInstantiated(RefClass refClass) { + return myInstantiatedClasses.contains(refClass); + } + + private int newlyInstantiatedClassesCount() { + return myInstantiatedClassesCount; + } + + private void cleanInstantiatedClassesCount() { + myInstantiatedClassesCount = 0; + } + + private void processDelayedMethods() { + RefClass[] instClasses = myInstantiatedClasses.toArray(new RefClass[myInstantiatedClasses.size()]); + for (int i = 0; i < instClasses.length; i++) { + RefClass refClass = instClasses[i]; + if (isClassInstantiated(refClass)) { + HashSet methods = myClassIDtoMethods.get(refClass); + if (methods != null) { + RefMethod[] arMethods = methods.toArray(new RefMethod[methods.size()]); + for (int j = 0; j < arMethods.length; j++) { + arMethods[j].accept(this); + } + } + } + } + } + } + + private void processEntryPoint(RefElement refEntry, CodeScanner codeScanner) { + refEntry.accept(codeScanner); + } + + public void cleanup() { + super.cleanup(); + getEntryPointsManager().cleanup(); + } + + private EntryPointsManager getEntryPointsManager() { + return EntryPointsManager.getInstance(myProject); + } + + public void updateContent() { + checkForReachables(); + super.updateContent(); + } + + protected boolean shouldLoadElementCallees() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java new file mode 100644 index 00000000000..957377a32c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java @@ -0,0 +1,307 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 22, 2001 + * Time: 4:58:38 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.deadCode; + +import com.intellij.codeInspection.ex.HTMLComposer; +import com.intellij.codeInspection.ex.InspectionTool; +import com.intellij.codeInspection.reference.*; + +import java.util.Iterator; + +public class DeadHTMLComposer extends HTMLComposer { + private final InspectionTool myTool; + + public DeadHTMLComposer(InspectionTool tool) { + myTool = tool; + } + + public void compose(final StringBuffer buf, RefEntity refEntity) { + genPageHeader(buf, refEntity); + + if (refEntity instanceof RefElement) { + RefElement refElement = (RefElement) refEntity; + if (refElement.isSuspicious() && !refElement.isEntry()) { + appendHeading(buf, "Problem synopsis"); + buf.append("
"); + appendAfterHeaderIndention(buf); + appendProblemSynopsis(refElement, buf); + + buf.append("

"); + appendResolution(buf, myTool, refElement); + + refElement.accept(new RefVisitor() { + public void visitClass(RefClass aClass) { + appendClassInstantiations(buf, aClass); + appendDerivedClasses(buf, aClass); + appendClassExtendsImplements(buf, aClass); + appendLibraryMethods(buf, aClass); + appendTypeReferences(buf, aClass); + } + + public void visitMethod(RefMethod method) { + appendElementInReferences(buf, method); + appendElementOutReferences(buf, method); + appendDerivedMethods(buf, method); + appendSuperMethods(buf, method); + } + + public void visitField(RefField field) { + appendElementInReferences(buf, field); + appendElementOutReferences(buf, field); + } + }); + } else { + appendNoProblems(buf); + } + } + } + + public void appendProblemSynopsis(final RefElement refElement, final StringBuffer buf) { + refElement.accept(new RefVisitor() { + public void visitField(RefField field) { + if (field.isUsedForReading() && !field.isUsedForWriting()) { + buf.append("Field is never assigned."); + return; + } + + if (!field.isUsedForReading() && field.isUsedForWriting()) { + if (field.isOnlyAssignedInInitializer()) { + buf.append("Field has no usages."); + return; + } + + buf.append("Field is assigned but never accessed."); + return; + } + + int nUsages = field.getInReferences().size(); + if (nUsages == 0) { + buf.append("Field has no usages."); + } else if (nUsages == 1) { + buf.append("Field has one usage but it is not reachable from entry points."); + } else { + buf.append("Field has "); + appendNumereable(buf, nUsages, "usage", "", "s"); + buf.append(" but they are not reachable from entry points."); + } + } + + public void visitClass(RefClass refClass) { + if (refClass.isAnonymous()) { + buf.append("Anonymous class declaration context is not reachable from entry points. Class is never instantiated."); + } else if (refClass.isInterface() || refClass.isAbstract()) { + appendClassOrInterface(buf, refClass, true); + buf.append(" "); + + int nDerived = getImplementationsCount(refClass); + + if (nDerived == 0) { + buf.append("is not implemented."); + } else if (nDerived == 1) { + buf.append("has an implementation but
  • it is never instantiated OR
  • no instantiations are reachable from entry points.
"); + } else { + buf.append("has "); + appendNumereable(buf, nDerived, "direct or indirect implementation", "", "s"); + buf.append(" but
  • they are never instantiated OR
  • no instantiations are reachable from entry points.
"); + } + } else if (refClass.isUtilityClass()) { + buf.append("No class references has been found. Class static initializer is not reachable."); + } else { + int nInstantiationsCount = getInstantiationsCount(refClass); + + if (nInstantiationsCount == 0) { + int nImplementations = getImplementationsCount(refClass); + if (nImplementations != 0) { + buf.append("Neither the class nor "); + appendNumereable(buf, nImplementations, " its implementation", "", "s"); + buf.append(" are ever instantiated."); + } else { + buf.append("Class is not instantiated."); + } + } else if (nInstantiationsCount == 1) { + buf.append("Class has one instantiation but it is not reachable from entry points."); + } else { + buf.append("Class has "); + appendNumereable(buf, nInstantiationsCount, "instantiation", "", "s"); + buf.append(" but they are not reachable from entry points."); + } + } + } + + public void visitMethod(RefMethod method) { + RefClass refClass = method.getOwnerClass(); + + if (method.isLibraryOverride()) { + buf.append("Method overrides a library method but
  • its "); + appendClassOrInterface(buf, refClass, false); + buf.append(" is never instantiated OR
  • its"); + appendClassOrInterface(buf, refClass, false); + buf.append(" instantiation is not reachable from entry points.
"); + } else if (method.isStatic() || method.isConstructor()) { + buf.append(method.isConstructor() ? "Constructor " : "Method "); + int nRefs = method.getInReferences().size(); + if (nRefs == 0) { + buf.append("is never used."); + } else if (method.isConstructor() && method.isSuspiciousRecursive()) { + buf.append("has usage(s) but they all belong to recursive calls chain that has no members reachable from entry points."); + } else if (nRefs == 1) { + buf.append("has one usage but it is not reachable from entry points."); + } else { + buf.append("has "); + appendNumereable(buf, nRefs, "usage", "", "s"); + buf.append(" usages but they are not reachable from entry points."); + } + } else if (refClass.isSuspicious()) { + if (method.isAbstract()) { + buf.append("
  • Abstract method is not implemented OR
  • "); + buf.append("
  • Implementation class is never instantiated OR
  • "); + buf.append("
  • An instantiation is not reachable from entry points.
"); + } else { + buf.append("
  • Method owner class is never instantiated OR
  • "); + buf.append("
  • An instantiation is not reachable from entry points.
"); + } + } else { + int nOwnRefs = method.getInReferences().size(); + int nSuperRefs = getSuperRefsCount(method); + int nDerivedRefs = getDerivedRefsCount(method); + + if (nOwnRefs == 0 && nSuperRefs == 0 && nDerivedRefs == 0) { + buf.append("Method is never used."); + } else if (nDerivedRefs > 0 && nSuperRefs == 0 && nOwnRefs == 0) { + buf.append("Method is never used as a member of this "); + appendClassOrInterface(buf, refClass, false); + buf.append(", but only as a member of the implementation class(es)."); + buf.append("The project will stay compilable if the method is removed from the "); + appendClassOrInterface(buf, refClass, false); + buf.append("."); + } else if (method.isSuspiciousRecursive()) { + buf.append("Method has usage(s) but they all belong to recursive calls chain that has no members reachable from entry points."); + } else { + buf.append("Method is not reachable from entry points."); + } + } + } + }); + } + + protected void appendAdditionalListItemInfo(StringBuffer buf, RefElement refElement) { + if (refElement instanceof RefImplicitConstructor) { + refElement = ((RefImplicitConstructor)refElement).getOwnerClass(); + } + + buf.append("
"); + if (refElement instanceof RefClass) { + RefClass refClass = (RefClass) refElement; + if (refClass.isUtilityClass()) { + // Append nothing. + } else if (refClass.isAnonymous()) { + buf.append(refClass.isSuspicious() ? "Anonymous class context is not reachable. Class is not instantiated." : "Instantiated"); + } else if (refClass.isInterface() || refClass.isAbstract()) { + buf.append(refClass.isSuspicious() ? "Has no reachable implementation instantiations. " : "Has reachable implementation instantiations."); + } else { + buf.append(refClass.isSuspicious() ? "Has no reachable instantiations. " : "Has reachable instantiations. "); + } + + appendNumereable(buf, getInstantiationsCount(refClass), "instantiation", "", "s"); + buf.append(" found in the project code."); + } else { + buf.append(refElement.isSuspicious() ? "Not Reachable. " : "Reachable. "); + int nUsageCount = refElement.getInReferences().size(); + if (refElement instanceof RefMethod) { + nUsageCount += getDerivedRefsCount((RefMethod) refElement); + } + buf.append(nUsageCount); + buf.append(" usages found in the project code."); + } + + buf.append(""); + } + + private int getDerivedRefsCount(RefMethod refMethod) { + int count = 0; + + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refDerived = iterator.next(); + count += refDerived.getInReferences().size() + getDerivedRefsCount(refDerived); + } + + return count; + } + + private int getSuperRefsCount(RefMethod refMethod) { + int count = 0; + + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + count += refSuper.getInReferences().size() + getSuperRefsCount(refSuper); + } + + return count; + } + + private static int getInstantiationsCount(RefClass aClass) { + if (!aClass.isAnonymous()) { + int count = 0; + + for (Iterator iterator = aClass.getConstructors().iterator(); iterator.hasNext();) { + RefMethod refConstructor = iterator.next(); + count += refConstructor.getInReferences().size(); + } + + for (Iterator iterator = aClass.getSubClasses().iterator(); iterator.hasNext();) { + RefClass subClass = iterator.next(); + count += getInstantiationsCount(subClass); + count -= subClass.getConstructors().size(); + } + + return count; + } + + return 1; + } + + private static int getImplementationsCount(RefClass refClass) { + int count = 0; + for (Iterator iterator = refClass.getSubClasses().iterator(); iterator.hasNext();) { + RefClass subClass = iterator.next(); + if (!subClass.isInterface() && !subClass.isAbstract()) { + count++; + } + count += getImplementationsCount(subClass); + } + + return count; + } + + private void appendClassInstantiations(StringBuffer buf, RefClass refClass) { + if (!refClass.isInterface() && !refClass.isAbstract() && !refClass.isUtilityClass()) { + boolean found = false; + + appendHeading(buf, "Instantiated from"); + + startList(); + for (Iterator iterator = refClass.getConstructors().iterator(); iterator.hasNext();) { + RefMethod refMethod = iterator.next(); + for (Iterator constructorCallersIterator = refMethod.getInReferences().iterator(); constructorCallersIterator.hasNext();) { + RefElement refCaller = constructorCallersIterator.next(); + appendListItem(buf, refCaller); + found = true; + } + } + + if (!found) { + startListItem(buf); + buf.append("No instantiations found."); + doneListItem(buf); + } + + doneList(buf); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java new file mode 100644 index 00000000000..10249d05a67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java @@ -0,0 +1,77 @@ +package com.intellij.codeInspection.deadCode; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.util.RefFilter; +import org.jdom.Element; + +/** + * @author max + */ +public class DummyEntryPointsTool extends FilteringInspectionTool { + private RefEntryPointFilter myFilter; + private DeadCodeInspection myOwner; + private QuickFixAction[] myQuickFixActions; + + public DummyEntryPointsTool(DeadCodeInspection owner) { + myOwner = owner; + } + + public RefFilter getFilter() { + if (myFilter == null) { + myFilter = new RefEntryPointFilter(); + } + return myFilter; + } + + public void runInspection(AnalysisScope scope) {} + + public void exportResults(Element parentNode) {} + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[0]; + } + + public String getDisplayName() { + return "Entry Points"; + } + + public String getGroupDisplayName() { + return ""; + } + + public String getShortName() { + return ""; + } + + public HTMLComposer getComposer() { + return new DeadHTMLComposer(this); + } + + public InspectionManagerEx getManager() { + return myOwner.getManager(); + } + + public QuickFixAction[] getQuickFixes() { + if (myQuickFixActions == null) { + myQuickFixActions = new QuickFixAction[]{new MoveEntriesToSuspicious()}; + } + return myQuickFixActions; + } + + private class MoveEntriesToSuspicious extends QuickFixAction { + private MoveEntriesToSuspicious() { + super("Remove from Entry Points", null, null, DummyEntryPointsTool.this); + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + EntryPointsManager.getInstance(getManager().getProject()).removeEntryPoint(refElement); + } + + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefEntryPointFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefEntryPointFilter.java new file mode 100644 index 00000000000..9ec54da9cd2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefEntryPointFilter.java @@ -0,0 +1,20 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 2, 2001 + * Time: 12:05:14 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.deadCode; + +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefParameter; +import com.intellij.codeInspection.util.RefFilter; + +public class RefEntryPointFilter extends RefFilter { + public int getElementProblemCount(RefElement refElement) { + if (refElement instanceof RefParameter) return 0; + return refElement.isEntry() ? 1 : 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java new file mode 100644 index 00000000000..6297a30b9fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java @@ -0,0 +1,20 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 2, 2001 + * Time: 12:07:30 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.deadCode; + +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefParameter; +import com.intellij.codeInspection.util.RefFilter; + +public class RefUnreachableFilter extends RefFilter { + public int getElementProblemCount(RefElement refElement) { + if (refElement instanceof RefParameter) return 0; + return refElement.isSuspicious() ? 1 : 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreferencedFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreferencedFilter.java new file mode 100644 index 00000000000..eb7fbf47382 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deadCode/RefUnreferencedFilter.java @@ -0,0 +1,32 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 2, 2001 + * Time: 12:14:37 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.deadCode; + +import com.intellij.codeInspection.reference.RefClass; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefField; +import com.intellij.codeInspection.reference.RefParameter; + +public class RefUnreferencedFilter extends RefUnreachableFilter { + public int getElementProblemCount(RefElement refElement) { + if (refElement instanceof RefParameter) return 0; + if (refElement.isEntry() || !refElement.isSuspicious()) return 0; + + if (refElement instanceof RefField) { + RefField refField = (RefField) refElement; + if (refField.isUsedForReading() && !refField.isUsedForWriting()) return 1; + if (refField.isUsedForWriting() && !refField.isUsedForReading()) return 1; + } + + if (refElement instanceof RefClass && ((RefClass)refElement).isAnonymous()) return 0; + if (!refElement.hasSuspiciousCallers() || refElement.isSuspiciousRecursive()) return 1; + + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseInspection.java new file mode 100644 index 00000000000..716ac749f24 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseInspection.java @@ -0,0 +1,234 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 24, 2001 + * Time: 2:46:32 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.defUse; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.BaseLocalInspectionTool; +import com.intellij.codeInspection.ex.ProblemDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import gnu.trove.THashSet; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.*; +import java.util.List; + +public class DefUseInspection extends BaseLocalInspectionTool { + public boolean REPORT_PREFIX_EXPRESSIONS = false; + public boolean REPORT_POSTFIX_EXPRESSIONS = true; + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defUse.DefUseInspection"); + + public static final String DISPLAY_NAME = "Unused assignment"; + public static final String SHORT_NAME = "UnusedAssignment"; + + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + List allProblems = null; + final PsiClassInitializer[] initializers = aClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + final ProblemDescriptor[] problems = checkCodeBlock(initializers[i].getBody(), manager, isOnTheFly); + if (problems != null) { + if (allProblems == null) { + allProblems = new ArrayList(1); + } + allProblems.addAll(Arrays.asList(problems)); + } + } + return allProblems == null ? null : allProblems.toArray(new ProblemDescriptor[allProblems.size()]); + } + + public ProblemDescriptor[] checkMethod(PsiMethod method, final InspectionManager manager, final boolean isOnTheFly) { + return checkCodeBlock(method.getBody(), manager, isOnTheFly); + } + + private ProblemDescriptor[] checkCodeBlock(final PsiCodeBlock body, + final InspectionManager manager, + final boolean isOnTheFly) { + if (body == null) return null; + final List descriptions = new ArrayList(); + final Set usedVariables = new THashSet(); + List unusedDefs = DefUseUtil.getUnusedDefs(body, usedVariables); + + if (unusedDefs != null && !unusedDefs.isEmpty()) { + Collections.sort(unusedDefs, new Comparator() { + public int compare(DefUseUtil.Info o1, DefUseUtil.Info o2) { + int offset1 = o1.getContext().getTextOffset(); + int offset2 = o2.getContext().getTextOffset(); + + if (offset1 == offset2) return 0; + if (offset1 < offset2) return -1; + + return 1; + } + }); + + for (int i = 0; i < unusedDefs.size(); i++) { + DefUseUtil.Info info = unusedDefs.get(i); + PsiElement context = info.getContext(); + PsiVariable psiVariable = info.getVariable(); + + if (context instanceof PsiDeclarationStatement) { + if (!info.isRead()) { + if (!isOnTheFly) { + descriptions.add(manager.createProblemDescriptor(psiVariable.getNameIdentifier(), + "Variable #ref #loc is never used.", null, + ProblemHighlightType.LIKE_UNUSED_SYMBOL)); + } + } + else { + descriptions.add(manager.createProblemDescriptor(psiVariable.getInitializer(), + "Variable " + psiVariable.getName() + + " initializer #ref #loc is redundant.", new RemoveInitializerFix(), + ProblemHighlightType.LIKE_UNUSED_SYMBOL)); + } + } + else if (context instanceof PsiAssignmentExpression && + ((PsiAssignmentExpression)context).getOperationSign().getTokenType() == JavaTokenType.EQ) { + final PsiAssignmentExpression assignment = (PsiAssignmentExpression)context; + descriptions.add(manager.createProblemDescriptor(assignment.getRExpression(), "The value #ref assigned to " + + assignment.getLExpression().getText() + + " #loc is never used.", + null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + else { + if (context instanceof PsiPrefixExpression && REPORT_PREFIX_EXPRESSIONS || + context instanceof PsiPostfixExpression && REPORT_POSTFIX_EXPRESSIONS) { + descriptions.add(manager.createProblemDescriptor(context, "The value changed at #ref #loc is never used.", + null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + } + } + + body.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitClass(PsiClass aClass) { + } + + public void visitLocalVariable(PsiLocalVariable variable) { + if (!usedVariables.contains(variable) && variable.getInitializer() == null && !isOnTheFly) { + descriptions.add(manager.createProblemDescriptor(variable.getNameIdentifier(), + "Variable #ref #loc is never used.", null, + ProblemHighlightType.LIKE_UNUSED_SYMBOL)); + } + } + + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + PsiExpression lExpression = expression.getLExpression(); + PsiExpression rExpression = expression.getRExpression(); + + if (lExpression instanceof PsiReferenceExpression && rExpression instanceof PsiReferenceExpression) { + PsiReferenceExpression lRef = (PsiReferenceExpression)lExpression; + PsiReferenceExpression rRef = (PsiReferenceExpression)rExpression; + + if (lRef.resolve() != rRef.resolve()) return; + PsiExpression lQualifier = lRef.getQualifierExpression(); + PsiExpression rQualifier = rRef.getQualifierExpression(); + + if ((lQualifier == null && rQualifier == null || + lQualifier instanceof PsiThisExpression && rQualifier instanceof PsiThisExpression || + lQualifier instanceof PsiThisExpression && rQualifier == null || + lQualifier == null && rQualifier instanceof PsiThisExpression) && !isOnTheFly) { + descriptions.add(manager.createProblemDescriptor(expression, "The variable is assigned to itself in #ref.", + null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + } + }); + + return descriptions.isEmpty() + ? null + : (ProblemDescriptor[])descriptions.toArray(new ProblemDescriptorImpl[descriptions.size()]); + } + + public JComponent createOptionsPanel() { + return new OptionsPanel(); + } + + private class OptionsPanel extends JPanel { + private final JCheckBox myReportPrefix; + private final JCheckBox myReportPostfix; + + private OptionsPanel() { + super(new GridBagLayout()); + + GridBagConstraints gc = new GridBagConstraints(); + gc.weighty = 0; + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + gc.anchor = GridBagConstraints.NORTHWEST; + + + myReportPrefix = new JCheckBox("Report ++i when may be replaced with (i + 1)"); + myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS); + myReportPrefix.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected(); + } + }); + gc.gridy = 0; + add(myReportPrefix, gc); + + myReportPostfix = new JCheckBox("Report i++ when changed value is not used afterwards"); + myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS); + myReportPostfix.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected(); + } + }); + + gc.weighty = 1; + gc.gridy++; + add(myReportPostfix, gc); + } + } + + + private static class RemoveInitializerFix implements LocalQuickFix { + public String getName() { + return "Remove Redundant Initializer"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + final PsiElement psiInitializer = descriptor.getPsiElement(); + if (!(psiInitializer instanceof PsiExpression)) return; + if (!(psiInitializer.getParent() instanceof PsiVariable)) return; + + try { + psiInitializer.delete(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getShortName() { + return SHORT_NAME; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseUtil.java new file mode 100644 index 00000000000..69bfd5da4f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/defUse/DefUseUtil.java @@ -0,0 +1,490 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Mar 22, 2002 + * Time: 7:25:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.defUse; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.*; +import com.intellij.psi.controlFlow.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.IntArrayList; +import gnu.trove.THashSet; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class DefUseUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defUse.DefUseUtil"); + + public static class Info { + private final PsiVariable myVariable; + private final PsiElement myContext; + private final boolean myIsRead; + + public Info(PsiVariable variable, PsiElement context, boolean read) { + myVariable = variable; + myContext = context; + myIsRead = read; + } + + public PsiVariable getVariable() { + return myVariable; + } + + public PsiElement getContext() { + return myContext; + } + + public boolean isRead() { + return myIsRead; + } + } + + private static class InstructionState { + private Set myVariablesUseArmed; + private final int myInstructionIdx; + private final IntArrayList myBackwardTraces; + + public InstructionState(int instructionIdx) { + myInstructionIdx = instructionIdx; + myBackwardTraces = new IntArrayList(); + myVariablesUseArmed = null; + } + + public void addBackwardTrace(int i) { + myBackwardTraces.add(i); + } + + public IntArrayList getBackwardTraces() { + return myBackwardTraces; + } + + public int getInstructionIdx() { + return myInstructionIdx; + } + + void mergeUseArmed(PsiVariable psiVariable) { + touch(); + myVariablesUseArmed.add(psiVariable); + } + + boolean mergeUseDisarmed(PsiVariable psiVariable) { + touch(); + + boolean result = myVariablesUseArmed.contains(psiVariable); + myVariablesUseArmed.remove(psiVariable); + + return result; + } + + void touch() { + if (myVariablesUseArmed == null) myVariablesUseArmed = new THashSet(); + } + + public boolean equals(Object obj) { + InstructionState state = (InstructionState) obj; + if (myVariablesUseArmed == null && state.myVariablesUseArmed == null) return true; + if (myVariablesUseArmed == null || state.myVariablesUseArmed == null) return false; + + return myVariablesUseArmed.equals(state.myVariablesUseArmed); + } + + public void merge(InstructionState state) { + touch(); + myVariablesUseArmed.addAll(state.myVariablesUseArmed); + } + } + + public static List getUnusedDefs(PsiCodeBlock body, Set outUsedVariables) { + if (body != null) { + List unusedDefs = new ArrayList(); + IntArrayList exitPoints = new IntArrayList(); + + ControlFlow flow; + try { + flow = new ControlFlowAnalyzer(body, ourPolicy).buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return null; + } + Instruction[] instructions = flow.getInstructions(); + if (LOG.isDebugEnabled()) { + System.out.println(flow); + } + + Set assignedVariables = new THashSet(); + Set readVariables = new THashSet(); + for (int i = 0; i < instructions.length; i++) { + Instruction instruction = instructions[i]; + ProgressManager.getInstance().checkCanceled(); + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction writeInstruction = (WriteVariableInstruction)instruction; + PsiElement context = flow.getElement(i); + context = PsiTreeUtil.getParentOfType(context, PsiStatement.class, false); + PsiVariable psiVariable = writeInstruction.variable; + if (context != null && !(context instanceof PsiDeclarationStatement && psiVariable.getInitializer() == null)) { + assignedVariables.add(psiVariable); + } + } else if (instruction instanceof ReadVariableInstruction) { + ReadVariableInstruction readInstruction = (ReadVariableInstruction) instruction; + readVariables.add(readInstruction.variable); + } + } + + InstructionState[] states = getStates(instructions); + + boolean[] defsArmed = new boolean[instructions.length]; + for (int i = 0; i < defsArmed.length; i++) defsArmed[i] = false; + + List queue = new ArrayList(); + + InstructionState startupState = states[instructions.length]; + startupState.touch(); + + for (Iterator iterator = assignedVariables.iterator(); iterator.hasNext();) { + PsiVariable psiVariable = iterator.next(); + if (psiVariable instanceof PsiField) { + startupState.mergeUseArmed(psiVariable); + } + } + + ControlFlowUtil.findExitPointsAndStatements(flow, 0, flow.getSize() - 1, exitPoints, new ArrayList(), + ControlFlowUtil.DEFAULT_EXIT_STATEMENTS_CLASSES); + + if (exitPoints.isEmpty()) return null; + for (int i = 0; i < exitPoints.size(); i++) { + startupState.addBackwardTrace(exitPoints.get(i)); + } + + queue.add(startupState); + + while (!queue.isEmpty()) { + ProgressManager.getInstance().checkCanceled(); + InstructionState state = queue.remove(0); + + int idx = state.getInstructionIdx(); + if (idx < instructions.length) { + Instruction instruction = instructions[idx]; + + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction writeInstruction = (WriteVariableInstruction) instruction; + PsiVariable psiVariable = writeInstruction.variable; + outUsedVariables.add(psiVariable); + if (state.mergeUseDisarmed(psiVariable)) { + defsArmed[idx] = true; + } + } else if (instruction instanceof ReadVariableInstruction) { + ReadVariableInstruction readInstruction = (ReadVariableInstruction)instruction; + state.mergeUseArmed(readInstruction.variable); + outUsedVariables.add(readInstruction.variable); + } else { + state.touch(); + } + } + + for (int i = 0; i < state.getBackwardTraces().size(); i++) { + int prevIdx = state.getBackwardTraces().get(i); + if (!state.equals(states[prevIdx])) { + states[prevIdx].merge(state); + queue.add(states[prevIdx]); + } + } + } + + for (int i = 0; i < instructions.length; i++) { + Instruction instruction = instructions[i]; + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction writeInstruction = (WriteVariableInstruction)instruction; + if (!defsArmed[i]) { + PsiElement context = flow.getElement(i); + context = PsiTreeUtil.getParentOfType(context, new Class[] {PsiStatement.class, PsiAssignmentExpression.class, PsiPostfixExpression.class, PsiPrefixExpression.class}, false); + PsiVariable psiVariable = writeInstruction.variable; + if (context != null && !(context instanceof PsiTryStatement)) { + if (context instanceof PsiDeclarationStatement && psiVariable.getInitializer() == null) { + if (!assignedVariables.contains(psiVariable)) { + unusedDefs.add(new Info(psiVariable, context, false)); + } + } else { + unusedDefs.add(new Info(psiVariable, context, readVariables.contains(psiVariable))); + } + } + } + } + } + + return unusedDefs; + } + + return null; + } + + public static PsiElement[] getDefs(PsiCodeBlock body, final PsiVariable def, PsiElement ref) { + try { + return new RefsDefs(body) { + + final InstructionState[] states = getStates(instructions); + + protected int nNext(int index) { + return states[index].getBackwardTraces().size(); + } + + protected int getNext(int index, int no) { + return states[index].getBackwardTraces().get(no); + } + + protected boolean defs() { return true; } + + protected void processInstruction(final Set res, final Instruction instruction, int index) { + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction; + if (instructionW.variable == def) { + + final PsiElement element = flow.getElement(index); + element.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression ref) { + if (PsiUtil.isAccessedForWriting(ref)) { + if (ref.resolve() == def) + res.add(ref); + } + } + public void visitVariable(PsiVariable var) { + if (var == def && (var instanceof PsiParameter || var.hasInitializer())) + res.add(var.getNameIdentifier()); + } + }); + } + } + } + }.get(def, ref); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return null; + } + } + + public static PsiElement[] getRefs(PsiCodeBlock body, final PsiVariable def, PsiElement ref) { + try { + return new RefsDefs(body) { + + protected int nNext(int index) { + return instructions[index].nNext(); + } + + protected int getNext(int index, int no) { + return instructions[index].getNext(index, no); + } + + protected boolean defs() { return false; } + + protected void processInstruction(final Set res, final Instruction instruction, int index) { + if (instruction instanceof ReadVariableInstruction) { + ReadVariableInstruction instructionR = (ReadVariableInstruction)instruction; + if (instructionR.variable == def) { + + final PsiElement element = flow.getElement(index); + element.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression ref) { + if (ref.resolve() == def) + res.add(ref); + } + }); + } + } + } + }.get(def, ref); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return null; + } + } + + protected static abstract class RefsDefs { + + protected abstract int nNext(int index); + protected abstract int getNext(int index, int no); + + final Instruction[] instructions; + final ControlFlow flow; + final PsiCodeBlock body; + + + protected RefsDefs(PsiCodeBlock body) throws ControlFlowAnalyzer.AnalysisCanceledException { + this.body = body; + flow = new ControlFlowAnalyzer(body, ourPolicy, false, false, true).buildControlFlow(); + instructions = flow.getInstructions(); + } + + protected abstract void processInstruction(Set res, final Instruction instruction, int index); + protected abstract boolean defs (); + + public PsiElement [] get (final PsiVariable def, PsiElement ref) { + if (body != null) { + + if (LOG.isDebugEnabled()) { + for (int i = 0; i < instructions.length; i++) { + Instruction instruction = instructions[i]; + System.out.println("" + i + ": " + instruction); + } + } + + { + final boolean [] visited = new boolean[instructions.length + 1]; + final boolean [] parmsVisited = new boolean [1]; + visited [visited.length-1] = true; // stop on the code end + int elem = flow.getStartOffset(ref); + + // hack: ControlFlow doesn't contains parameters initialization + if (elem == -1 && def instanceof PsiParameter) + elem = 0; + + if (elem != -1) { + if (!defs () && instructions [elem] instanceof ReadVariableInstruction) { + LOG.assertTrue(nNext(elem) == 1); + LOG.assertTrue(getNext(elem,0) == elem+1); + elem += 1; + } + + final Set res = new THashSet(); + class Inner { + + void traverse (int index) { + visited [index] = true; + + if (defs ()) { + final Instruction instruction = instructions [index]; + processInstruction(res, instruction, index); + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction; + if (instructionW.variable == def) { + return; + } + } + + // hack: ControlFlow doesnn't contains parameters initialization + if (index == 0 && !parmsVisited [0]) { + parmsVisited [0] = true; + if (def instanceof PsiParameter) + res.add (def.getNameIdentifier()); + } + } + + final int nNext = nNext (index); + for (int i = 0; i < nNext; i++) { + final int prev = getNext(index, i); + if (!visited [prev]) { + if (!defs ()) { + final Instruction instruction = instructions [prev]; + if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction; + if (instructionW.variable == def) { + continue; + } + } else { + processInstruction(res, instruction, prev); + } + } + traverse (prev); + + } + } + } + } + new Inner ().traverse (elem); + return res.toArray(new PsiElement[res.size ()]); + } + } + } + return null; + } + } + + + private static InstructionState[] getStates(final Instruction[] instructions) { + final InstructionState[] states = new InstructionState[instructions.length + 1]; + for (int i = 0; i < states.length; i++) { + states[i] = new InstructionState(i); + } + + for (int i = 0; i < instructions.length; i++) { + final Instruction instruction = instructions[i]; + for (int j = 0; j != instruction.nNext(); ++ j) { + states [instruction.getNext(i, j)].addBackwardTrace(i); + } + } + return states; + } + + private static final ControlFlowPolicy ourPolicy = new ControlFlowPolicy() { + public PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + if (refExpr.isQualified()) return null; + + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) { + return (PsiVariable) refElement; + } + + return null; + } + + public boolean isParameterAccepted(PsiParameter psiParameter) { + return true; + } + + public boolean isLocalVariableAccepted(PsiLocalVariable psiVariable) { + return true; + } + }; + + public static PsiElement[] getDefsRefs (final boolean defs, PsiFile file, final PsiElement target) { + if (!(target instanceof PsiIdentifier)) { + return null; + } + + if (file instanceof PsiCompiledElement) + file = (PsiFile)((PsiCompiledElement)file).getMirror(); + + if (file instanceof PsiJavaFile) { + final PsiElement def; + final PsiElement refElem = target.getParent (); + { + if (refElem instanceof PsiReference) { + def = ((PsiReference)refElem).resolve(); + } else { + def = refElem; + } + } + + if (def instanceof PsiLocalVariable || def instanceof PsiParameter) { + final PsiVariable var = (PsiVariable) def; + final PsiMethod method; + { + PsiElement p = var; + while (!(p instanceof PsiMethod)) { + final PsiElement parent = p.getParent(); + LOG.assertTrue (parent != null); + p = parent; + } + method = (PsiMethod)p; + } + final PsiCodeBlock body = method.getBody(); + final PsiElement[] elems = + (defs + ? DefUseUtil.getDefs(body, var, refElem) + : DefUseUtil.getRefs(body, var, refElem) + ); + return elems; + } + } + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deprecation/DeprecationInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deprecation/DeprecationInspection.java new file mode 100644 index 00000000000..6d647f4bf12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/deprecation/DeprecationInspection.java @@ -0,0 +1,50 @@ +package com.intellij.codeInspection.deprecation; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefMethod; + +/** + * @author max + */ +public class DeprecationInspection extends DescriptorProviderInspection { + public DeprecationInspection() { + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod && ((RefMethod) refElement).isOverridesDeprecated()) { + addProblemElement(refElement, new ProblemDescriptor[]{getManager().createProblemDescriptor(refElement.getElement(), "Overrides deprecated method.", null, ProblemHighlightType.LIKE_DEPRECATED)}); + } else if (refElement.isUsesDeprecatedApi()) { + if (getDescriptions(refElement) != null) return; + addProblemElement(refElement, new ProblemDescriptor[] {getManager().createProblemDescriptor(refElement.getElement(), "Uses deprecated API.", null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)}); + } + } + }); + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {InspectionManagerEx.BUILD_GRAPH}; + } + + public String getDisplayName() { + return "Deprecated API usage"; + } + + public String getGroupDisplayName() { + return ""; + } + + public String getShortName() { + return "Deprecation"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java new file mode 100644 index 00000000000..476c7c9ef75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java @@ -0,0 +1,237 @@ +package com.intellij.codeInspection.emptyMethod; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.reference.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * @author max + */ +public class EmptyMethodInspection extends DescriptorProviderInspection { + public static final String DISPLAY_NAME = "Empty method"; + private QuickFix myQuickFix; + public static final String SHORT_NAME = "EmptyMethod"; + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElement; + ProblemDescriptor[] descriptors = checkMethod(refMethod); + if (descriptors != null) { + addProblemElement(refElement, descriptors); + } + } + } + }); + } + + private ProblemDescriptor[] checkMethod(RefMethod refMethod) { + if (!refMethod.isBodyEmpty()) return null; + if (refMethod.isConstructor()) return null; + + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + if (checkMethod(refSuper) != null) return null; + } + + String message = null; + if (refMethod.isOnlyCallsSuper()) { + RefMethod refSuper = findSuperWithBody(refMethod); + if (refSuper == null || RefUtil.compareAccess(refMethod.getAccessModifier(), refSuper.getAccessModifier()) <= 0) { + message = "Method only calls its super."; + } + } + else if (refMethod.hasBody() && hasEmptySuperImplementation(refMethod)) { + message = "Empty method overrides empty method."; + } + else if (areAllImplementationsEmpty(refMethod)) { + if (refMethod.hasBody()) { + if (refMethod.getDerivedMethods().size() == 0) { + if (refMethod.getSuperMethods().size() == 0) { + message = "The method is empty."; + } + } + else { + message = "The method and all it's deriveables are empty."; + } + } + else { + if (refMethod.getDerivedMethods().size() > 0) { + message = "All implementations of this method are empty."; + } + } + } + + if (message != null) { + return new ProblemDescriptor[]{ + getManager().createProblemDescriptor(refMethod.getElement(), message, getFix(), ProblemHighlightType.GENERIC_ERROR_OR_WARNING)}; + } + + return null; + } + + private static RefMethod findSuperWithBody(RefMethod refMethod) { + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + if (refSuper.hasBody()) return refSuper; + } + return null; + } + + private boolean areAllImplementationsEmpty(RefMethod refMethod) { + if (refMethod.hasBody() && !refMethod.isBodyEmpty()) return false; + + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refDerived = iterator.next(); + if (!areAllImplementationsEmpty(refDerived)) return false; + } + + return true; + } + + private static boolean hasEmptySuperImplementation(RefMethod refMethod) { + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + if (refSuper.hasBody() && refSuper.isBodyEmpty()) return true; + } + + return false; + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (getDescriptions(refElement) != null) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + getManager().enqueueDerivedMethodsProcessing(refMethod, new InspectionManagerEx.DerivedMethodsProcessor() { + public boolean process(PsiMethod derivedMethod) { + PsiCodeBlock body = derivedMethod.getBody(); + if (body == null) return true; + if (body.getStatements().length == 0) return true; + if (RefUtil.isMethodOnlyCallsSuper(derivedMethod)) return true; + + ignoreElement(refMethod); + return false; + } + }); + } + }); + } + } + }); + + return false; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[]{InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return SHORT_NAME; + } + + public EmptyMethodInspection() { + } + + private LocalQuickFix getFix() { + if (myQuickFix == null) { + myQuickFix = new QuickFix(); + } + return myQuickFix; + } + + private class QuickFix implements LocalQuickFix { + public String getName() { + return "Delete Unnecessary Method(s)"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + RefElement refElement = getElement(descriptor); + if (refElement.isValid() && refElement instanceof RefMethod) { + List refElements = new ArrayList(1); + RefMethod refMethod = (RefMethod)refElement; + final List psiElements = new ArrayList(); + if (refMethod.isOnlyCallsSuper()) { + deleteMethod(refMethod, psiElements, refElements); + } + else if (refMethod.hasBody() && hasEmptySuperImplementation(refMethod)) { + deleteMethod(refMethod, psiElements, refElements); + } + else if (areAllImplementationsEmpty(refMethod)) { + if (refMethod.hasBody()) { + if (refMethod.getDerivedMethods().size() == 0) { + if (refMethod.getSuperMethods().size() == 0) { + deleteMethod(refMethod, psiElements, refElements); + } + } + else { + deleteHierarchy(refMethod, psiElements, refElements); + } + } + else { + deleteHierarchy(refMethod, psiElements, refElements); + } + } + + ArrayList deletedRefs = new ArrayList(1); + for (int i = 0; i < refElements.size(); i++) { + RefElement element = refElements.get(i); + RefUtil.removeRefElement(element, deletedRefs); + } + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + new SafeDeleteHandler().invoke(getManager().getProject(), + psiElements.toArray(new PsiElement[psiElements.size()]), false); + } + }); + } + } + + private void deleteHierarchy(RefMethod refMethod, List result, List refElements) { + Collection derivedMethods = refMethod.getDerivedMethods(); + RefMethod[] refMethods = derivedMethods.toArray(new RefMethod[derivedMethods.size()]); + for (int i = 0; i < refMethods.length; i++) { + RefMethod refDerived = refMethods[i]; + deleteMethod(refDerived, result, refElements); + } + deleteMethod(refMethod, result, refElements); + } + + private void deleteMethod(RefMethod refMethod, List result, List refElements) { + refElements.add(refMethod); + PsiElement psiElement = refMethod.getElement(); + if (psiElement == null) return; + if (!result.contains(psiElement)) result.add(psiElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java new file mode 100644 index 00000000000..7e755d4e9af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java @@ -0,0 +1,107 @@ +package com.intellij.codeInspection.equalsAndHashcode; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.psi.*; +import com.intellij.psi.util.MethodSignatureUtil; + +/** + * @author max + */ +public class EqualsAndHashcode extends DescriptorProviderInspection { + private static final JobDescriptor JOB_DESCRIPTOR = new JobDescriptor("Searching for equals() and hashCode() in "); + + private PsiMethod myHashCode; + private PsiMethod myEquals; + + public EqualsAndHashcode() { + } + + public void initialize(InspectionManagerEx manager) { + super.initialize(manager); + myHashCode = null; + myEquals = null; + PsiManager psiManager = PsiManager.getInstance(getManager().getProject()); + PsiClass psiObjectClass = psiManager.findClass("java.lang.Object"); + PsiMethod[] methods = psiObjectClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if ("equals".equals(method.getName())) { + myEquals = method; + } else if ("hashCode".equals(method.getName())) { + myHashCode = method; + } + } + } + + public void runInspection(AnalysisScope scope) { + JOB_DESCRIPTOR.setTotalAmount(scope.getFileCount()); + + scope.accept(new PsiElementVisitor() { + public void visitFile(PsiFile file) { + if (file instanceof PsiJavaFile) { + getManager().incrementJobDoneAmount(JOB_DESCRIPTOR, file.getVirtualFile().getPresentableUrl()); + super.visitFile(file); + } + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitElement(PsiElement element) { + PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + child.accept(this); + } + } + + public void visitClass(PsiClass aClass) { + super.visitClass(aClass); + + boolean hasEquals = false; + boolean hasHashCode = false; + PsiMethod[] methods = aClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (MethodSignatureUtil.areSignaturesEqual(method, myEquals)) { + hasEquals = true; + } else if (MethodSignatureUtil.areSignaturesEqual(method, myHashCode)) { + hasHashCode = true; + } + } + + if (hasEquals != hasHashCode) { + addProblemElement(getManager().getRefManager().getReference(aClass), + new ProblemDescriptor[]{getManager().createProblemDescriptor(aClass, + hasEquals + ? "Class has equals() defined but " + + "does not define hashCode()." + : "Class has hashCode() defined but " + + "does not define equals().", null,ProblemHighlightType.GENERIC_ERROR_OR_WARNING)}); + } + } + }); + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {JOB_DESCRIPTOR}; + } + + public String getDisplayName() { + return "equals() and hashCode() not paired"; + } + + public String getGroupDisplayName() { + return ""; + } + + public String getShortName() { + return "EqualsAndHashcode"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/AddAssertStatementFix.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/AddAssertStatementFix.java new file mode 100644 index 00000000000..7a6f9de7403 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/AddAssertStatementFix.java @@ -0,0 +1,44 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; + + +/** + * @author ven + */ +public class AddAssertStatementFix implements LocalQuickFix { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.AddAssertStatementFix"); + private PsiExpression myExpressionToAssert; + + public String getName() { + return "Assert '" + myExpressionToAssert.getText() + "'"; + } + + public AddAssertStatementFix(PsiExpression expressionToAssert) { + myExpressionToAssert = expressionToAssert; + LOG.assertTrue(PsiType.BOOLEAN.equals(myExpressionToAssert.getType())); + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + PsiStatement anchorStatement = PsiTreeUtil.getParentOfType(element, PsiStatement.class); + LOG.assertTrue(anchorStatement != null); + + String text = "assert c;"; + PsiAssertStatement assertStatement; + try { + assertStatement = (PsiAssertStatement)element.getManager().getElementFactory().createStatementFromText(text, null); + assertStatement.getAssertCondition().replace(myExpressionToAssert); + anchorStatement.getParent().addBefore(assertStatement, anchorStatement); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/BaseLocalInspectionTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/BaseLocalInspectionTool.java new file mode 100644 index 00000000000..7d5ac375619 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/BaseLocalInspectionTool.java @@ -0,0 +1,18 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInspection.LocalInspectionTool; + +/** + * User: anna + * Date: Dec 27, 2004 + */ +public abstract class BaseLocalInspectionTool extends LocalInspectionTool { + public HighlightDisplayLevel getDefaultLevel() { + return HighlightDisplayLevel.ERROR; + } + + public boolean isEnabledByDefault() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/Descriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/Descriptor.java new file mode 100644 index 00000000000..aa5d86121a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/Descriptor.java @@ -0,0 +1,120 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import javax.swing.*; + +/** + * User: anna + * Date: Dec 8, 2004 + */ +public class Descriptor { + private String myText; + private String myGroup; + private String myDescriptorFileName; + private HighlightDisplayKey myKey; + private JComponent myAdditionalConfigPanel; + private Element myConfig; + private InspectionToolsPanel.LevelChooser myChooser; + private InspectionTool myTool; + private HighlightDisplayLevel myLevel; + private boolean myEnabled = false; + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.Descriptor"); + + + public Descriptor(String text, + HighlightDisplayKey key, + JComponent additionalConfigPanel, + String descriptionFileName, + HighlightDisplayLevel level, + boolean enabled) { + myText = text; + myGroup = "General"; + myDescriptorFileName = descriptionFileName; + myKey = key; + myAdditionalConfigPanel = additionalConfigPanel; + myConfig = null; + myEnabled = enabled; + myChooser = new InspectionToolsPanel.LevelChooser(); + myChooser.setLevel(level); + myLevel = level; + } + + public Descriptor(InspectionTool tool, HighlightDisplayLevel level, boolean enabled) { + Element config = new Element("options"); + try { + tool.writeExternal(config); + } + catch (WriteExternalException e) { + LOG.error(e); + } + myText = tool.getDisplayName(); + myGroup = tool.getGroupDisplayName() != null && tool.getGroupDisplayName().length() == 0 ? "General" : tool.getGroupDisplayName(); + myDescriptorFileName = tool.getDescriptionFileName(); + myKey = HighlightDisplayKey.find(tool.getShortName()); + if (myKey == null) { + myKey = HighlightDisplayKey.register(tool.getShortName()); + } + myAdditionalConfigPanel = tool.createOptionsPanel(); + myConfig = config; + myChooser = new InspectionToolsPanel.LevelChooser(); + myChooser.setLevel(level); + myEnabled = enabled; + myTool = tool; + myLevel = level; + } + + public boolean isEnabled() { + return myEnabled; + } + + public void setEnabled(final boolean enabled) { + myEnabled = enabled; + } + + public String getText() { + return myText; + } + + public HighlightDisplayKey getKey() { + return myKey; + } + + public HighlightDisplayLevel getLevel() { + return myLevel; + } + + public JComponent getAdditionalConfigPanel() { + return myAdditionalConfigPanel; + } + + public InspectionToolsPanel.LevelChooser getChooser() { + return myChooser; + } + + public void setChooserLevel(HighlightDisplayLevel level) { + getChooser().setLevel(level); + } + + public Element getConfig() { + return myConfig; + } + + public InspectionTool getTool() { + return myTool; + } + + public String getDescriptorFileName() { + return myDescriptorFileName; + } + + public String getGroup() { + return myGroup; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorComposer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorComposer.java new file mode 100644 index 00000000000..28bf1bc8950 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorComposer.java @@ -0,0 +1,125 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * @author max + */ +public class DescriptorComposer extends HTMLComposer { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorComposer"); + private DescriptorProviderInspection myTool; + + public DescriptorComposer(DescriptorProviderInspection tool) { + myTool = tool; + } + + public void compose(StringBuffer buf, RefEntity refEntity) { + Project project = myTool.getManager().getProject(); + if (refEntity instanceof RefElement) { + RefElement refElement = (RefElement) refEntity; + + genPageHeader(buf, refElement); + + if (myTool.getDescriptions(refElement) != null) { + appendHeading(buf, "Problem synopsis"); + + ProblemDescriptor[] descriptions = myTool.getDescriptions(refElement); + + startList(); + for (int i = 0; i < descriptions.length; i++) { + final ProblemDescriptor description = descriptions[i]; + + startListItem(buf); + composeDescription(description, project, i, buf); + doneListItem(buf); + } + + doneList(buf); + + appendResolution(buf, myTool, refElement); + } else { + appendNoProblems(buf); + } + } + } + + public void compose(StringBuffer buf, RefElement refElement, ProblemDescriptor descriptor) { + Project project = myTool.getManager().getProject(); + ProblemDescriptor[] descriptions = myTool.getDescriptions(refElement); + + int problemIdx = -1; + for (int i = 0; i < descriptions.length; i++) { + ProblemDescriptor description = descriptions[i]; + if (description == descriptor) { + problemIdx = i; + break; + } + } + if (problemIdx == -1) return; + + genPageHeader(buf, refElement); + appendHeading(buf, "Problem synopsis"); + buf.append("
"); + appendAfterHeaderIndention(buf); + + composeDescription(descriptor, project, problemIdx, buf); + final LocalQuickFix fix = descriptor.getFix(); + if (fix != null) { + buf.append("

"); + appendHeading(buf, "Problem resolution"); + buf.append("
"); + appendAfterHeaderIndention(buf); + + buf.append(""); + buf.append(fix.getName()); + buf.append(""); + } + } + + private void composeDescription(final ProblemDescriptor description, + Project project, + int i, + StringBuffer buf) { + PsiElement expression = description.getPsiElement(); + StringBuffer anchor = new StringBuffer(); + if (expression != null) { + VirtualFile vFile = expression.getContainingFile().getVirtualFile(); + + anchor.append(""); + anchor.append(expression.getText().replaceAll("\\$", "\\\\\\$")); + anchor.append(""); + } + else { + anchor.append("invalidated item"); + } + + String descriptionTemplate = description.getDescriptionTemplate(); + if (descriptionTemplate != null) { + String res = descriptionTemplate.replaceAll("#ref", anchor.toString()); + res = res.replaceAll("#loc", "at line " + description.getLineNumber()); + buf.append(res); + } + else { + buf.append("No error message provided."); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorProviderInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorProviderInspection.java new file mode 100644 index 00000000000..275a77ac810 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/DescriptorProviderInspection.java @@ -0,0 +1,179 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefUtil; +import com.intellij.codeInspection.ui.InspectionPackageNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; +import com.intellij.codeInspection.ui.ProblemDescriptionNode; +import com.intellij.codeInspection.ui.RefElementNode; +import com.intellij.codeInspection.util.XMLExportUtl; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; + +import java.util.*; + +/** + * @author max + */ +public abstract class DescriptorProviderInspection extends InspectionTool { + private HashMap myProblemElements; + private HashMap> myPackageContents = null; + private HashMap myProblemToElements; + private DescriptorComposer myComposer; + private QuickFixAction[] myQuickFixActions; + + + protected DescriptorProviderInspection() { + myProblemElements = new HashMap(); + myProblemToElements = new HashMap(); + myQuickFixActions = new QuickFixAction[]{new LocalQuickFixWrapper(this)}; + } + + protected void addProblemElement(RefElement refElement, ProblemDescriptor[] descriptions) { + if (refElement == null) return; + + myProblemElements.put(refElement, descriptions); + for (int i = 0; i < descriptions.length; i++) { + ProblemDescriptor description = descriptions[i]; + myProblemToElements.put(description, refElement); + } + } + + protected void ignoreElement(RefElement refElement) { + if (refElement == null) return; + myProblemElements.remove(refElement); + } + + public void ignoreProblem(ProblemDescriptor problem) { + RefElement refElement = myProblemToElements.get(problem); + if (refElement != null) ignoreProblem(refElement, problem); + } + + public void ignoreProblem(RefElement refElement, ProblemDescriptor problem) { + if (refElement == null) return; + myProblemToElements.remove(problem); + ProblemDescriptor[] descriptors = myProblemElements.get(refElement); + if (descriptors != null) { + ArrayList newDescriptors = new ArrayList(Arrays.asList(descriptors)); + newDescriptors.remove(problem); + if (newDescriptors.size() > 0) { + myProblemElements.put(refElement, newDescriptors.toArray(new ProblemDescriptor[newDescriptors.size()])); + } + else { + myProblemElements.remove(refElement); + } + } + } + + public void cleanup() { + super.cleanup(); + myProblemElements.clear(); + } + + public ProblemDescriptor[] getDescriptions(RefElement refElement) { + if (!refElement.isValid()) { + ignoreElement(refElement); + return null; + } + + return myProblemElements.get(refElement); + } + + public HTMLComposer getComposer() { + if (myComposer == null) { + myComposer = new DescriptorComposer(this); + } + return myComposer; + } + + public void exportResults(final Element parentNode) { + final Project project = getManager().getProject(); + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(final RefElement refElement) { + if (myProblemElements.containsKey(refElement)) { + ProblemDescriptor[] descriptions = getDescriptions(refElement); + for (int i = 0; i < descriptions.length; i++) { + ProblemDescriptor description = descriptions[i]; + + int line = description.getLineNumber(); + final String template = description.getDescriptionTemplate(); + final PsiElement psiElement = description.getPsiElement(); + final String text = psiElement.getText(); + String problemText = template.replaceAll("#ref", text.replaceAll("\\$", "\\\\\\$")); + problemText = problemText.replaceAll(" #loc ", " "); + + Element element = XMLExportUtl.createElement(refElement, parentNode, line); + Element problemClassElement = new Element("problem_class"); + problemClassElement.addContent(getDisplayName()); + element.addContent(problemClassElement); + Element descriptionElement = new Element("description"); + descriptionElement.addContent(problemText); + element.addContent(descriptionElement); + } + } + } + }); + } + + public boolean hasReportedProblems() { + return myProblemElements.size() > 0; + } + + public void updateContent() { + myPackageContents = new HashMap>(); + final Set elements = myProblemElements.keySet(); + for(Iterator iterator = elements.iterator(); iterator.hasNext(); ) { + RefElement element = iterator.next(); + String packageName = RefUtil.getPackageName(element); + Set content = myPackageContents.get(packageName); + if (content == null) { + content = new HashSet(); + myPackageContents.put(packageName, content); + } + content.add(element); + } + } + + public InspectionTreeNode[] getContents() { + List content = new ArrayList(); + Set packages = myPackageContents.keySet(); + for (Iterator iterator = packages.iterator(); iterator.hasNext();) { + String p = iterator.next(); + InspectionPackageNode pNode = new InspectionPackageNode(p); + Set elements = myPackageContents.get(p); + for(Iterator iterator1 = elements.iterator(); iterator1.hasNext(); ) { + RefElement refElement = iterator1.next(); + final RefElementNode elemNode = new RefElementNode(refElement, false); + pNode.add(elemNode); + final ProblemDescriptor[] problems = myProblemElements.get(refElement); + if (problems.length > 1) { + for (int i = 0; i < problems.length; i++) { + ProblemDescriptor problem = problems[i]; + elemNode.add(new ProblemDescriptionNode(refElement, problem)); + } + } else if (problems.length == 1) { + elemNode.setProblem(problems[0]); + } + } + content.add(pNode); + } + return content.toArray(new InspectionTreeNode[content.size()]); + } + + public Map> getPackageContent() { + return myPackageContents; + } + + public QuickFixAction[] getQuickFixes() { + return myQuickFixActions; + } + + protected RefElement getElement(ProblemDescriptor descriptor) { + return myProblemToElements.get(descriptor); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/EntryPointsManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/EntryPointsManager.java new file mode 100644 index 00000000000..ebed6b3316c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/EntryPointsManager.java @@ -0,0 +1,192 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 27, 2002 + * Time: 2:57:13 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.reference.*; +import com.intellij.codeInspection.ui.ConstructorPicker; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.*; + +public class EntryPointsManager implements JDOMExternalizable, ProjectComponent{ + private final Map myFQNameToSmartEntryPointRef; + + public EntryPointsManager() { + myFQNameToSmartEntryPointRef = new LinkedHashMap(); // To keep the order between readExternal to writeExternal + } + + public static EntryPointsManager getInstance(Project project) { + return project.getComponent(EntryPointsManager.class); + } + + public void readExternal(Element element) throws InvalidDataException { + Element entryPointsElement = element.getChild("entry_points"); + List content = entryPointsElement.getChildren(); + for (Iterator iterator = content.iterator(); iterator.hasNext();) { + Element entryElement = (Element) iterator.next(); + if ("entry_point".equals(entryElement.getName())) { + SmartRefElementPointer entryPoint = new SmartRefElementPointer(entryElement); + myFQNameToSmartEntryPointRef.put(entryPoint.getFQName(), entryPoint); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + Element parentNode = element; + Element entryPointsElement = new Element("entry_points"); + + for (Iterator iterator = myFQNameToSmartEntryPointRef.values().iterator(); iterator.hasNext();) { + SmartRefElementPointer entryPoint = (SmartRefElementPointer) iterator.next(); + if (entryPoint.isPersistent()) { + entryPoint.writeExternal(entryPointsElement); + } + } + + parentNode.addContent(entryPointsElement); + } + + public void resolveEntryPoints(final RefManager manager) { + validateEntryPoints(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (Iterator iterator = myFQNameToSmartEntryPointRef.values().iterator(); iterator.hasNext();) { + SmartRefElementPointer entryPoint = (SmartRefElementPointer) iterator.next(); + if (entryPoint.resolve(manager)) { + RefElement refElement = entryPoint.getRefElement(); + refElement.setEntry(true); + refElement.setPermanentEntry(entryPoint.isPersistent()); + } + } + } + }); + } + + private void purgeTemporaryEntryPoints() { + Collection collection = myFQNameToSmartEntryPointRef.values(); + SmartRefElementPointer[] entries = (SmartRefElementPointer[]) collection.toArray(new SmartRefElementPointer[collection.size()]); + for (int i = 0; i < entries.length; i++) { + SmartRefElementPointer entry = entries[i]; + if (!entry.isPersistent()) { + myFQNameToSmartEntryPointRef.remove(entry.getFQName()); + RefElement refElement = entry.getRefElement(); + if (refElement != null) refElement.setEntry(false); + entry.freeReference(); + } + } + } + + public void addEntryPoint(RefElement newEntryPoint, boolean isPersistent) { + if (!newEntryPoint.isValid()) return; + if (newEntryPoint instanceof RefClass) { + RefClass refClass = (RefClass) newEntryPoint; + + if (refClass.isAnonymous()) { + // Anonymous class cannot be an entry point. + return; + } + + ArrayList refConstructors = refClass.getConstructors(); + if (refConstructors.size() == 1) { + addEntryPoint((RefElement) refConstructors.get(0), isPersistent); + return; + } else if (refConstructors.size() > 1) { + // Many constructors here. Need to ask user which ones are used + ArrayList pickedConstructors = ConstructorPicker.pickConstructorsFrom(refClass, refConstructors); + for (int i = 0; i < pickedConstructors.size(); i++) { + addEntryPoint((RefMethod) pickedConstructors.get(i), isPersistent); + } + + return; + } + } + + if (myFQNameToSmartEntryPointRef.get(newEntryPoint.getExternalName()) == null) { + SmartRefElementPointer entry = new SmartRefElementPointer(newEntryPoint, isPersistent); + myFQNameToSmartEntryPointRef.put(entry.getFQName(), entry); + newEntryPoint.setEntry(true); + newEntryPoint.setPermanentEntry(entry.isPersistent()); + } + } + + public void removeEntryPoint(RefElement anEntryPoint) { + if (anEntryPoint instanceof RefClass) { + RefClass refClass = (RefClass) anEntryPoint; + if (!refClass.isInterface()) { + anEntryPoint = refClass.getDefaultConstructor(); + } + } + + if (anEntryPoint == null) return; + + Set set = myFQNameToSmartEntryPointRef.entrySet(); + Object key = null; + for(Iterator iterator = set.iterator(); iterator.hasNext(); ) { + Map.Entry entry = (Map.Entry)iterator.next(); + SmartRefElementPointer value = (SmartRefElementPointer) entry.getValue(); + if (value.getRefElement() == anEntryPoint) { + key = entry.getKey(); + break; + } + } + + if (key != null) { + myFQNameToSmartEntryPointRef.remove(key); + anEntryPoint.setEntry(false); + } + } + + public SmartRefElementPointer[] getEntryPoints() { + validateEntryPoints(); + Collection collection = myFQNameToSmartEntryPointRef.values(); + return (SmartRefElementPointer[]) collection.toArray(new SmartRefElementPointer[collection.size()]); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getComponentName() { + return "EntryPointsManager"; + } + + private void validateEntryPoints() { + Collection collection = myFQNameToSmartEntryPointRef.values(); + SmartRefElementPointer[] entries = (SmartRefElementPointer[]) collection.toArray(new SmartRefElementPointer[collection.size()]); + for (int i = 0; i < entries.length; i++) { + SmartRefElementPointer entry = entries[i]; + RefElement refElement = entry.getRefElement(); + if (refElement != null && !refElement.isValid()) { + myFQNameToSmartEntryPointRef.remove(entry.getFQName()); + } + } + } + + public void cleanup() { + purgeTemporaryEntryPoints(); + Collection entries = myFQNameToSmartEntryPointRef.values(); + for(Iterator iterator = entries.iterator(); iterator.hasNext(); ) { + SmartRefElementPointer entry = (SmartRefElementPointer)iterator.next(); + entry.freeReference(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/FilteringInspectionTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/FilteringInspectionTool.java new file mode 100644 index 00000000000..3b5d124a10a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/FilteringInspectionTool.java @@ -0,0 +1,66 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefUtil; +import com.intellij.codeInspection.ui.InspectionPackageNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; +import com.intellij.codeInspection.ui.RefElementNode; +import com.intellij.codeInspection.util.RefFilter; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +/** + * @author max + */ +public abstract class FilteringInspectionTool extends InspectionTool { + public abstract RefFilter getFilter(); + HashMap> myPackageContents = null; + + public InspectionTreeNode[] getContents() { + List content = new ArrayList(); + Set packages = myPackageContents.keySet(); + for (Iterator iterator = packages.iterator(); iterator.hasNext();) { + String p = iterator.next(); + InspectionPackageNode pNode = new InspectionPackageNode(p); + Set elements = myPackageContents.get(p); + for(Iterator iterator1 = elements.iterator(); iterator1.hasNext(); ) { + RefElement refElement = iterator1.next(); + pNode.add(new RefElementNode(refElement, shouldLoadElementCallees())); + } + content.add(pNode); + } + return content.toArray(new InspectionTreeNode[content.size()]); + } + + protected boolean shouldLoadElementCallees() { + return false; + } + + public void updateContent() { + myPackageContents = new HashMap>(); + getManager().getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement.isValid() && getFilter().accepts(refElement)) { + String packageName = RefUtil.getPackageName(refElement); + Set content = myPackageContents.get(packageName); + if (content == null) { + content = new HashSet(); + myPackageContents.put(packageName, content); + } + content.add(refElement); + } + } + }); + } + + public boolean hasReportedProblems() { + return myPackageContents.size() > 0; + } + + public Map> getPackageContent() { + return myPackageContents; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/HTMLComposer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/HTMLComposer.java new file mode 100644 index 00000000000..eb1b087c469 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/HTMLComposer.java @@ -0,0 +1,513 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 22, 2001 + * Time: 4:54:17 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.export.HTMLExporter; +import com.intellij.codeInspection.reference.*; +import com.intellij.psi.*; + +import java.util.Iterator; + +/** + * @author max + */ +public abstract class HTMLComposer { + private HTMLExporter myExporter; + private int[] myListStack; + private int myListStackTop; + + protected HTMLComposer() { + myListStack = new int[5]; + myListStackTop = -1; + } + + public abstract void compose(StringBuffer buf, RefEntity refEntity); + + public void compose(StringBuffer buf, RefElement refElement, ProblemDescriptor descriptor) {} + + public void composeWithExporter(StringBuffer buf, RefEntity refEntity, HTMLExporter exporter) { + myExporter = exporter; + compose(buf, refEntity); + myExporter = null; + } + + protected void genPageHeader(final StringBuffer buf, RefEntity refEntity) { + if (refEntity instanceof RefElement) { + RefElement refElement = (RefElement)refEntity; + + appendHeading(buf, "Name"); + buf.append("
"); + appendAfterHeaderIndention(buf); + appendAccessModifier(buf, refElement); + appendShortName(buf, refElement); + buf.append("

"); + + appendHeading(buf, "Location"); + buf.append("
"); + appendAfterHeaderIndention(buf); + appendLocation(buf, refElement); + buf.append("

"); + } + } + + public static void appendHeading(final StringBuffer buf, String name) { + buf.append( + "     "); + buf.append(name); + buf.append(":"); + } + + private static void appendAccessModifier(final StringBuffer buf, RefElement refElement) { + String modifier = refElement.getAccessModifier(); + if (modifier != null && modifier != PsiModifier.PACKAGE_LOCAL) { + buf.append(modifier); + buf.append(" "); + } + } + + private void appendLocation(final StringBuffer buf, final RefElement refElement) { + RefEntity owner = refElement.getOwner(); + buf.append(""); + buf.append(RefUtil.getPackageName(refElement)); + buf.append("
"); + } + else if (owner instanceof RefMethod) { + buf.append("method "); + appendElementReference(buf, (RefElement)owner); + } + else if (owner instanceof RefField) { + buf.append("field "); + appendElementReference(buf, (RefElement)owner); + buf.append(" initializer"); + } + else if (owner instanceof RefClass) { + appendClassOrInterface(buf, (RefClass)owner, false); + buf.append(" "); + appendElementReference(buf, (RefElement)owner); + } + buf.append(""); + } + + protected static void appendClassOrInterface(StringBuffer buf, RefClass refClass, boolean capitalizeFirstLetter) { + if (refClass.isInterface()) { + buf.append(capitalizeFirstLetter ? "Interface" : "interface"); + } + else if (refClass.isAbstract()) { + buf.append(capitalizeFirstLetter ? "Abstract class" : "abstract class"); + } + else { + buf.append(capitalizeFirstLetter ? "Class" : "class"); + } + } + + private static void appendShortName(final StringBuffer buf, RefElement refElement) { + refElement.accept(new RefVisitor() { + public void visitClass(RefClass refClass) { + if (refClass.isStatic()) { + buf.append("static "); + } + + appendClassOrInterface(buf, refClass, false); + buf.append(" "); + buf.append(refClass.getName()); + buf.append(""); + } + + public void visitField(RefField field) { + PsiField psiField = (PsiField)field.getElement(); + + if (field.isStatic()) { + buf.append("static "); + } + + buf.append("field "); + + buf.append(psiField.getType().getPresentableText()); + buf.append(" "); + buf.append(psiField.getName()); + buf.append(""); + } + + public void visitMethod(RefMethod method) { + PsiMethod psiMethod = (PsiMethod)method.getElement(); + PsiType returnType = psiMethod.getReturnType(); + + if (method.isStatic()) { + buf.append("static "); + } + else if (method.isAbstract()) { + buf.append("abstract "); + } + + buf.append(method.isConstructor() ? "constructor " : "method "); + buf.append(""); + + if (returnType != null) { + buf.append(returnType.getPresentableText()); + buf.append(" "); + } + + buf.append(""); + buf.append(psiMethod.getName()); + buf.append(""); + appendMethodParameters(buf, psiMethod, true); + buf.append(""); + } + }); + } + + private static void appendMethodParameters(StringBuffer buf, PsiMethod method, boolean showNames) { + PsiParameter[] params = method.getParameterList().getParameters(); + buf.append('('); + for (int i = 0; i < params.length; i++) { + if (i != 0) buf.append(", "); + PsiParameter param = params[i]; + buf.append(param.getType().getPresentableText()); + if (showNames) { + buf.append(' '); + buf.append(param.getName()); + } + } + buf.append(')'); + } + + private static void appendQualifiedName(StringBuffer buf, RefEntity refEntity) { + String qName = ""; + + while (!(refEntity instanceof RefProject)) { + if (qName.length() > 0) qName = "." + qName; + + final String name; + if (refEntity instanceof RefMethod) { + PsiMethod psiMethod = (PsiMethod)((RefMethod)refEntity).getElement(); + if (psiMethod != null) { + name = psiMethod.getName(); + } + else { + name = refEntity.getName(); + } + } + else { + name = refEntity.getName(); + } + + qName = name + qName; + refEntity = refEntity.getOwner(); + } + + buf.append(qName); + } + + private void appendElementReference(final StringBuffer buf, RefElement refElement) { + appendElementReference(buf, refElement, true); + } + + public void appendElementReference(final StringBuffer buf, RefElement refElement, String linkText, String frameName) { + buf.append(""); + buf.append(linkText); + buf.append(""); + } + + protected void appendQuickFix(final StringBuffer buf, String text, int index) { + if (myExporter == null) { + buf.append(""); + buf.append(text); + buf.append(""); + } + } + + private void appendElementReference(final StringBuffer buf, RefElement refElement, boolean isPackageIncluded) { + appendElementReference(buf, refElement, isPackageIncluded, null); + } + + private void appendElementReference(final StringBuffer buf, + RefElement refElement, + boolean isPackageIncluded, + String frameName) { + if (refElement instanceof RefImplicitConstructor) { + buf.append("implicit constructor of "); + refElement = ((RefImplicitConstructor)refElement).getOwnerClass(); + } + + buf.append(""); + if (refElement instanceof RefField) { + RefField field = (RefField)refElement; + PsiField psiField = (PsiField)field.getElement(); + buf.append(psiField.getType().getPresentableText()); + buf.append(" "); + } + else if (refElement instanceof RefMethod) { + RefMethod method = (RefMethod)refElement; + PsiMethod psiMethod = (PsiMethod)method.getElement(); + PsiType returnType = psiMethod.getReturnType(); + + if (returnType != null) { + buf.append(returnType.getPresentableText()); + buf.append(" "); + } + } + + buf.append(""); + + if (RefUtil.isAnonymousClass(refElement)) { + buf.append("anonymous"); + } + else if (refElement instanceof RefMethod) { + PsiMethod psiMethod = (PsiMethod)refElement.getElement(); + buf.append(psiMethod.getName()); + } + else { + buf.append(refElement.getName()); + } + + buf.append(""); + + if (refElement instanceof RefMethod) { + PsiMethod psiMethod = (PsiMethod)refElement.getElement(); + appendMethodParameters(buf, psiMethod, false); + } + + buf.append(""); + + if (RefUtil.isAnonymousClass(refElement)) { + buf.append(" in "); + appendElementReference(buf, ((RefElement)refElement.getOwner()), isPackageIncluded); + } + else if (isPackageIncluded) { + buf.append(" ("); + appendQualifiedName(buf, refElement.getOwner()); +// buf.append(RefUtil.getPackageName(refElement)); + buf.append(")"); + } + } + + protected static void appendNumereable(StringBuffer buf, + int n, + String statement, + String singleEnding, + String multipleEnding) { + buf.append(n); + buf.append(' '); + buf.append(statement); + + if (n % 10 == 1 && n % 100 != 11) { + buf.append(singleEnding); + } + else { + buf.append(multipleEnding); + } + } + + protected void appendElementInReferences(StringBuffer buf, RefElement refElement) { + if (refElement.getInReferences().size() > 0) { + appendHeading(buf, "Used from"); + startList(); + for (Iterator iterator = refElement.getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + appendListItem(buf, refCaller); + } + doneList(buf); + } + } + + protected void appendElementOutReferences(StringBuffer buf, RefElement refElement) { + if (refElement.getOutReferences().size() > 0) { + appendHeading(buf, "Uses the following"); + startList(); + for (Iterator iterator = refElement.getOutReferences().iterator(); iterator.hasNext();) { + RefElement refCallee = iterator.next(); + appendListItem(buf, refCallee); + } + doneList(buf); + } + } + + protected void appendListItem(StringBuffer buf, RefElement refElement) { + startListItem(buf); + buf.append(""); + doneListItem(buf); + } + + protected void appendAdditionalListItemInfo(StringBuffer buf, RefElement refElement) { + // Default appends nothing. + } + + protected void appendClassExtendsImplements(StringBuffer buf, RefClass refClass) { + if (refClass.getBaseClasses().size() > 0) { + appendHeading(buf, "Extends/implements"); + startList(); + for (Iterator iterator = refClass.getBaseClasses().iterator(); iterator.hasNext();) { + RefClass refBase = iterator.next(); + appendListItem(buf, refBase); + } + doneList(buf); + } + } + + protected void appendDerivedClasses(StringBuffer buf, RefClass refClass) { + if (refClass.getSubClasses().size() > 0) { + if (refClass.isInterface()) { + appendHeading(buf, "Extended/implemented by"); + } + else { + appendHeading(buf, "Extended by"); + } + + startList(); + for (Iterator iterator = refClass.getSubClasses().iterator(); iterator.hasNext();) { + RefClass refDerived = iterator.next(); + appendListItem(buf, refDerived); + } + doneList(buf); + } + } + + protected void appendLibraryMethods(StringBuffer buf, RefClass refClass) { + if (refClass.getLibraryMethods().size() > 0) { + appendHeading(buf, "Overrides library methods"); + + startList(); + for (Iterator iterator = refClass.getLibraryMethods().iterator(); iterator.hasNext();) { + RefMethod refMethod = iterator.next(); + appendListItem(buf, refMethod); + } + doneList(buf); + } + } + + protected void appendSuperMethods(StringBuffer buf, RefMethod refMethod) { + if (refMethod.getSuperMethods().size() > 0) { + appendHeading(buf, "Overrides/implements"); + + startList(); + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + appendListItem(buf, refSuper); + } + doneList(buf); + } + } + + protected void appendDerivedMethods(StringBuffer buf, RefMethod refMethod) { + if (refMethod.getDerivedMethods().size() > 0) { + appendHeading(buf, "Derived methods"); + + startList(); + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refDerived = iterator.next(); + appendListItem(buf, refDerived); + } + doneList(buf); + } + } + + protected void appendTypeReferences(StringBuffer buf, RefClass refClass) { + if (refClass.getInTypeReferences().size() > 0) { + appendHeading(buf, "The following uses this type"); + + startList(); + for (Iterator iterator = refClass.getInTypeReferences().iterator(); iterator.hasNext();) { + RefElement refElement = (RefElement)iterator.next(); + appendListItem(buf, refElement); + } + doneList(buf); + } + } + + protected void appendResolution(StringBuffer buf, InspectionTool tool, RefElement where) { + QuickFixAction[] quickFixes = tool.getQuickFixes(); + if (quickFixes != null) { + boolean listStarted = false; + for (int i = 0; i < quickFixes.length; i++) { + QuickFixAction quickFix = quickFixes[i]; + final String text = quickFix.getText(where); + if (text == null) continue; + if (!listStarted) { + appendHeading(buf, "Problem resolution"); + startList(); + listStarted = true; + } + startListItem(buf); + appendQuickFix(buf, text, i); + doneListItem(buf); + } + + if (listStarted) { + doneList(buf); + } + } + } + + protected void startList() { + myListStackTop++; + myListStack[myListStackTop] = 0; + } + + protected void doneList(StringBuffer buf) { + if (myListStack[myListStackTop] != 0) { + buf.append("
 
"); + } + myListStackTop--; + } + + protected void startListItem(StringBuffer buf) { + myListStack[myListStackTop]++; + buf.append("
  • "); + } + + protected static void doneListItem(StringBuffer buf) { + buf.append("
  • "); + } + + public static void appendAfterHeaderIndention(StringBuffer buf) { + buf.append("          "); + } + + protected static void appendNoProblems(StringBuffer buf) { + buf.append("
    "); + appendAfterHeaderIndention(buf); + buf.append("No problems found
    "); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionApplication.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionApplication.java new file mode 100644 index 00000000000..27df702ced7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionApplication.java @@ -0,0 +1,200 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.InspectionMain; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.idea.CommandLineApplication; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import org.jdom.JDOMException; + +import javax.swing.*; +import java.io.*; + +/** + * @author max + */ +public class InspectionApplication extends CommandLineApplication { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionApplication"); + + public String myProjectPath = null; + public String myOutPath = null; + public String mySourceDirectory = null; + public String myProfilePath = null; + private Project myProject; + private int myVerboseLevel = 0; + + public InspectionApplication() { + super(false, false, "componentSets/InspectionComponents"); + } + + public void startup() { + if (myProjectPath == null || myOutPath == null || myProfilePath == null) { + InspectionMain.printHelp(); + } + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ApplicationEx application = ApplicationManagerEx.getApplicationEx(); + try { + logMessage(1, "Starting up... "); + application.doNotSave(); + application.load(PathManager.getOptionsPath()); + logMessageLn(1, "done."); + + InspectionApplication.this.run(); + } + catch (Exception e) { + LOG.error(e); + } + finally { + application.exit(); + } + } + }); + } + + public void run() { + try { + myProjectPath = myProjectPath.replace(File.separatorChar, '/'); + VirtualFile vfsProject = LocalFileSystem.getInstance().findFileByPath(myProjectPath); + if (vfsProject == null) { + logError("File " + myProjectPath + " cannot be found"); + InspectionMain.printHelp(); + } + + File profileFile = new File(myProfilePath); + if (!profileFile.exists()) { + logError("File " + myProfilePath + " cannot be found"); + InspectionMain.printHelp(); + } + + + logMessage(1, "Opening project... "); + myProject = ProjectManagerEx.getInstanceEx().loadProject(myProjectPath); + logMessageLn(1, "done."); + logMessage(1, "Initializing project..."); + + final InspectionManagerEx im = (InspectionManagerEx)InspectionManager.getInstance(myProject); + final AnalysisScope scope; + + InspectionProfileImpl profile = new InspectionProfileImpl(profileFile, null); + im.setProfile(profile); + + if (mySourceDirectory == null) { + scope = new AnalysisScope(myProject, AnalysisScope.SOURCE_JAVA_FILES); + runStartupActivity(); + } + else { + mySourceDirectory = mySourceDirectory.replace(File.separatorChar, '/'); + + VirtualFile vfsDir = LocalFileSystem.getInstance().findFileByPath(mySourceDirectory); + if (vfsDir == null) { + logError("Directory " + mySourceDirectory + " cannot be found"); + InspectionMain.printHelp(); + } + + runStartupActivity(); + PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(vfsDir); + scope = new AnalysisScope(psiDirectory, AnalysisScope.SOURCE_JAVA_FILES); + } + + logMessageLn(1, "done."); + + final OutputStream outStream = new BufferedOutputStream(new FileOutputStream(myOutPath)); + + PsiClass psiObjectClass = PsiManager.getInstance(myProject).findClass("java.lang.Object"); + if (psiObjectClass == null) { + logError("The JDK is not configured properly for this project. Inspection cannot run."); + return; + } + + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + im.launchInspectionsOffline(scope, outStream); + logMessageLn(1, "\nDone.\n"); + } + }, new ProgressIndicatorBase() { + private String lastPrefix = ""; + + public void setText(String text) { + if (myVerboseLevel == 0) return; + + if (myVerboseLevel == 1) { + int idx = text.indexOf(" in "); + if (idx == -1) { + idx = text.indexOf(" of "); + } + + if (idx == -1) return; + String prefix = text.substring(0, idx); + if (prefix.equals(lastPrefix)) { + logMessage(1, "."); + return; + } + lastPrefix = prefix; + logMessageLn(1, ""); + logMessageLn(1, prefix); + return; + } + + logMessageLn(2, text); + } + }); + } + catch (IOException e) { + LOG.error(e); + InspectionMain.printHelp(); + } + catch (InvalidDataException e) { + LOG.error(e); + } + catch (JDOMException e) { + LOG.error(e); + } + } + + private void runStartupActivity() { + ((StartupManagerImpl)StartupManager.getInstance(myProject)).runStartupActivities(); + } + + public Object getData(String dataId) { + if (DataConstants.PROJECT.equals(dataId)) return myProject; + return super.getData(dataId); + } + + public void setVerboseLevel(int verboseLevel) { + myVerboseLevel = verboseLevel; + } + + private void logMessage(int minVerboseLevel, String message) { + if (myVerboseLevel >= minVerboseLevel) { + System.out.print(message); + } + } + + private void logError(String message) { + System.err.println(message); + } + + private void logMessageLn(int minVerboseLevel, String message) { + if (myVerboseLevel >= minVerboseLevel) { + System.out.println(message); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionManagerEx.java new file mode 100644 index 00000000000..8f578f3a8e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionManagerEx.java @@ -0,0 +1,927 @@ +/* + * Author: max + * Date: Oct 9, 2001 + * Time: 8:43:17 PM + */ + +package com.intellij.codeInspection.ex; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeEditor.printing.ExportToHTMLSettings; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.export.ExportToHTMLDialog; +import com.intellij.codeInspection.export.HTMLExportFrameMaker; +import com.intellij.codeInspection.reference.*; +import com.intellij.codeInspection.ui.InspectCodePanel; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.ide.BrowserUtil; +import com.intellij.ide.actions.NextOccurenceToolbarAction; +import com.intellij.ide.actions.PreviousOccurenceToolbarAction; +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ui.configuration.LibrariesEditor; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.search.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.content.*; +import com.intellij.util.containers.HashMap; +import org.jdom.Document; +import org.jdom.Element; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InspectionManagerEx extends InspectionManager implements JDOMExternalizable, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionManagerEx"); + private RefManager myRefManager; + private ContentManager myContentManager; + private AnalysisScope myCurrentScope; + private final UIOptions myUIOptions; + private final Project myProject; + private List myJobDescriptors; + private InspectionResultsView myView = null; + + private HashMap> myDerivedMethodsRequests; + private HashMap> myDerivedClassesRequests; + private HashMap> myMethodUsagesRequests; + private HashMap> myFieldUsagesRequests; + private HashMap> myClassUsagesRequests; + private ProgressIndicator myProgressIndicator; + private String myCurrentProfileName; + + + public static final JobDescriptor BUILD_GRAPH = new JobDescriptor("Processing project usages in "); + public static final JobDescriptor FIND_EXTERNAL_USAGES = new JobDescriptor("Processing external usages of "); + public static final JobDescriptor LOCAL_ANALYSIS = new JobDescriptor("Analyzing code in "); + + public static final String HELP_ID = "codeInspection"; + + public static final String SUPPRESS_INSPECTIONS_TAG_NAME = "noinspection"; + public static final String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "com.intellij.util.annotations.NoInspection"; + + //for use in local comments + public static final Pattern SUPPRESS_PATTERN = Pattern.compile("//" + SUPPRESS_INSPECTIONS_TAG_NAME + " (\\w+(,\\w+)*)"); + + private InspectionProfile myExternalProfile = null; + + public InspectionManagerEx(Project project) { + myProject = project; + + myUIOptions = new UIOptions(); + + myRefManager = null; + myCurrentScope = null; + myContentManager = null; + myCurrentProfileName = "Default"; + } + + public Project getProject() { + return myProject; + } + + public ContentManager getContentManager() { + return myContentManager; + } + + public void initComponent() { } + + public void disposeComponent() { + cleanup(); + } + + public void projectOpened() { + myContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(new ComponentContentUI(), true, myProject); + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.INSPECTION, + myContentManager.getComponent(), + ToolWindowAnchor.BOTTOM); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowInspection.png")); + new ContentManagerWatcher(toolWindow, myContentManager); + myContentManager.addContentManagerListener(new ContentManagerAdapter() { + public void contentRemoved(ContentManagerEvent event) { + myView = null; + } + }); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(myUIOptions, element); + + Element profileElement = element.getChild("profile"); + if (profileElement != null) { + myCurrentProfileName = profileElement.getAttributeValue("name"); + } + else { + myCurrentProfileName = "Default"; + } + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(myUIOptions, element); + + Element profileElement = new Element("profile"); + profileElement.setAttribute("name", myCurrentProfileName); + element.addContent(profileElement); + } + + public InspectionProfile getCurrentProfile() { + if (myExternalProfile != null) return myExternalProfile; + InspectionProfile profile = InspectionProfileManager.getInstance().getProfile(myCurrentProfileName); + if (profile == null) { + myCurrentProfileName = "Default"; + profile = InspectionProfileManager.getInstance().getProfile(myCurrentProfileName); + } + return profile; + } + + public ProblemDescriptor createProblemDescriptor(PsiElement psiElement, + String descriptionTemplate, + LocalQuickFix fix, + ProblemHighlightType highlightType) { + return new ProblemDescriptorImpl(psiElement, descriptionTemplate, fix, highlightType); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.INSPECTION); + } + + private void addView(InspectionResultsView view) { + myView = view; + ContentManager contentManager = getContentManager(); + + Content content = PeerFactory.getInstance().getContentFactory().createContent(view, "FOOO", false); + + content.setDisplayName("Inspection Results"); + contentManager.addContent(content); + contentManager.setSelectedContent(content); + + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.INSPECTION).activate(null); + } + + private boolean isInspectionToolIdMentioned(String inspectionsList, String inspectionToolID) { + String[] ids = inspectionsList.split(","); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + if (id.equals(inspectionToolID) || id.equals("ALL")) return true; + } + return false; + } + + public boolean isToCheckMember(PsiDocCommentOwner member, String inspectionToolID) { + PsiDocComment docComment = member.getDocComment(); + if (docComment != null) { + PsiDocTag inspectionTag = docComment.findTagByName(SUPPRESS_INSPECTIONS_TAG_NAME); + if (inspectionTag != null) { + + String valueText = inspectionTag.getValueElement().getText(); + return !isInspectionToolIdMentioned(valueText, inspectionToolID); + } + } + + PsiModifierList modifierList = member.getModifierList(); + if (modifierList != null) { + PsiAnnotation annotation = modifierList.findAnnotation(SUPPRESS_INSPECTIONS_ANNOTATION_NAME); + if (annotation != null) { + PsiAnnotationMemberValue attributeValue = annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); + if (attributeValue instanceof PsiArrayInitializerMemberValue) { + PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)attributeValue).getInitializers(); + for (int i = 0; i < initializers.length; i++) { + PsiAnnotationMemberValue initializer = initializers[i]; + if (initializer instanceof PsiLiteralExpression) { + Object value = ((PsiLiteralExpression)initializer).getValue(); + if (inspectionToolID.equals(value) || "ALL".equals(value)) return false; + } + } + } + } + } + return true; + } + + public boolean inspectionResultSuppressed(PsiElement place, LocalInspectionTool tool) { + PsiStatement statement = PsiTreeUtil.getParentOfType(place, PsiStatement.class); + if (statement != null) { + PsiElement prev = PsiTreeUtil.skipSiblingsBackward(statement, new Class[]{PsiWhiteSpace.class}); + if (prev instanceof PsiComment) { + String text = prev.getText(); + Matcher matcher = SUPPRESS_PATTERN.matcher(text); + if (matcher.matches()) { + return isInspectionToolIdMentioned(matcher.group(1), tool.getID()); + } + } + } + return false; + } + + public interface DerivedClassesProcessor { + boolean process(PsiClass inheritor); + } + + public interface DerivedMethodsProcessor { + boolean process(PsiMethod derivedMethod); + } + + public interface UsagesProcessor { + boolean process(PsiReference psiReference); + } + + public void enqueueClassUsagesProcessing(RefClass refClass, UsagesProcessor p) { + if (myClassUsagesRequests == null) myClassUsagesRequests = new HashMap>(); + enqueueRequestImpl(refClass, myClassUsagesRequests, p); + } + + public void enqueueDerivedClassesProcessing(RefClass refClass, DerivedClassesProcessor p) { + if (myDerivedClassesRequests == null) myDerivedClassesRequests = new HashMap>(); + enqueueRequestImpl(refClass, myDerivedClassesRequests, p); + } + + public void enqueueDerivedMethodsProcessing(RefMethod refMethod, DerivedMethodsProcessor p) { + if (refMethod.isConstructor() || refMethod.isStatic()) return; + if (myDerivedMethodsRequests == null) myDerivedMethodsRequests = new HashMap>(); + enqueueRequestImpl(refMethod, myDerivedMethodsRequests, p); + } + + public void enqueueFieldUsagesProcessor(RefField refField, UsagesProcessor p) { + if (myFieldUsagesRequests == null) myFieldUsagesRequests = new HashMap>(); + enqueueRequestImpl(refField, myFieldUsagesRequests, p); + } + + public void enqueueMethodUsagesProcessor(RefMethod refMethod, UsagesProcessor p) { + if (myMethodUsagesRequests == null) myMethodUsagesRequests = new HashMap>(); + enqueueRequestImpl(refMethod, myMethodUsagesRequests, p); + } + + private static void enqueueRequestImpl(RefElement refElement, HashMap requestMap, Object processor) { + ArrayList requests = (ArrayList)requestMap.get(refElement.getElement()); + if (requests == null) { + requests = new ArrayList(); + requestMap.put(refElement.getElement(), requests); + } + requests.add(processor); + } + + private void cleanup() { + myProgressIndicator = null; + + myDerivedMethodsRequests = null; + myDerivedClassesRequests = null; + myMethodUsagesRequests = null; + myFieldUsagesRequests = null; + myClassUsagesRequests = null; + + getCurrentProfile().cleanup(); + + EntryPointsManager.getInstance(getProject()).cleanup(); + + if (myRefManager != null) { + myRefManager.cleanup(); + myRefManager = null; + } + } + + public void setCurrentScope(AnalysisScope currentScope) { + myCurrentScope = currentScope; + } + + public void doInspections(final AnalysisScope scope, boolean showDialog) { + while (PsiManager.getInstance(getProject()).findClass("java.lang.Object") == null) { + Messages.showMessageDialog(getProject(), + "The JDK is not configured properly for this project. Inspection cannot proceed.", + "Error", + Messages.getErrorIcon()); + final ProjectJdk projectJdk = LibrariesEditor.chooseAndSetJDK(myProject); + if (projectJdk == null) return; + } + + if (showDialog || myCurrentScope == null) { + final InspectCodePanel itc = new InspectCodePanel(this, scope); + + itc.show(); + if (!itc.isOK()) return; + + + } + + close(); + getContentManager().removeAllContents(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myCurrentScope = scope; + launchInspections(scope); + } + }); + } + + private void rerun() { + if (myCurrentScope.isValid()) { + cleanup(); + doInspections(myCurrentScope, false); + } + } + + public RefManager getRefManager() { + if (myRefManager == null) { + myRefManager = new RefManager(myProject, myCurrentScope); + } + + return myRefManager; + } + + public void launchInspectionsOffline(final AnalysisScope scope, OutputStream outStream) { + cleanup(); + + myCurrentScope = scope; + final Element root = new Element("problems"); + final Document doc = new Document(root); + + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + performInspectionsWithProgress(scope); + + InspectionTool[] tools = getCurrentProfile().getInspectionTools(myProject); + for (int i = 0; i < tools.length; i++) { + InspectionTool tool = tools[i]; + if (getCurrentProfile().isToolEnabled(HighlightDisplayKey.find(tool.getShortName()))) { + tool.exportResults(root); + } + } + } + }); + + try { + ((ProjectEx)getProject()).getMacroReplacements().substitute(doc.getRootElement(), SystemInfo.isFileSystemCaseSensitive); + JDOMUtil.writeDocument(doc, outStream, "\n"); + } + catch (IOException e) { + LOG.error(e); + } + } + + public void processSearchRequests() { + final PsiSearchHelper helper = PsiManager.getInstance(getProject()).getSearchHelper(); + final RefManager refManager = getRefManager(); + final AnalysisScope scope = refManager.getScope(); + + final SearchScope searchScope = new GlobalSearchScope() { + public boolean contains(VirtualFile file) { + return !scope.contains(file); + } + + public int compare(VirtualFile file1, VirtualFile file2) { + return 0; + } + + public boolean isSearchInModuleContent(Module aModule) { + return true; + } + + public boolean isSearchInLibraries() { + return false; + } + }; + + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + if (myDerivedClassesRequests != null) { + ArrayList sortedIDs = getSortedIDs(myDerivedClassesRequests); + for (int i = 0; i < sortedIDs.size(); i++) { + PsiClass psiClass = (PsiClass)sortedIDs.get(i); + incrementJobDoneAmount(FIND_EXTERNAL_USAGES, psiClass.getQualifiedName()); + + final List processors = myDerivedClassesRequests.get(psiClass); + helper.processInheritors(new PsiBaseElementProcessor() { + public boolean execute(PsiClass element) { + PsiClass inheritor = element; + if (scope.contains(inheritor)) return true; + DerivedClassesProcessor[] processorsArrayed = processors.toArray(new DerivedClassesProcessor[processors.size()]); + for (int j = 0; j < processorsArrayed.length; j++) { + DerivedClassesProcessor processor = processorsArrayed[j]; + if (!processor.process(inheritor)) { + processors.remove(processor); + } + } + return processors.size() > 0; + } + }, psiClass, searchScope, false); + } + + myDerivedClassesRequests = null; + } + + if (myDerivedMethodsRequests != null) { + ArrayList sortedIDs = getSortedIDs(myDerivedMethodsRequests); + for (int i = 0; i < sortedIDs.size(); i++) { + PsiMethod psiMethod = (PsiMethod)sortedIDs.get(i); + final RefMethod refMethod = (RefMethod)refManager.getReference(psiMethod); + + incrementJobDoneAmount(FIND_EXTERNAL_USAGES, RefUtil.getQualifiedName(refMethod)); + + final List processors = myDerivedMethodsRequests.get(psiMethod); + helper.processOverridingMethods(new PsiBaseElementProcessor() { + public boolean execute(PsiMethod element) { + PsiMethod derivedMethod = element; + if (scope.contains(derivedMethod)) return true; + DerivedMethodsProcessor[] processorsArrayed = processors.toArray(new DerivedMethodsProcessor[processors.size()]); + for (int j = 0; j < processorsArrayed.length; j++) { + DerivedMethodsProcessor processor = processorsArrayed[j]; + if (!processor.process(derivedMethod)) { + processors.remove(processor); + } + } + + return processors.size() > 0; + } + }, psiMethod, searchScope, true); + } + + myDerivedMethodsRequests = null; + } + + if (myFieldUsagesRequests != null) { + ArrayList sortedIDs = getSortedIDs(myFieldUsagesRequests); + for (int i = 0; i < sortedIDs.size(); i++) { + PsiField psiField = (PsiField)sortedIDs.get(i); + final List processors = myFieldUsagesRequests.get(psiField); + + incrementJobDoneAmount(FIND_EXTERNAL_USAGES, RefUtil.getQualifiedName(refManager.getReference(psiField))); + + helper.processReferences(createReferenceProcessor(processors), psiField, searchScope, false); + } + + myFieldUsagesRequests = null; + } + + if (myClassUsagesRequests != null) { + ArrayList sortedIDs = getSortedIDs(myClassUsagesRequests); + for (int i = 0; i < sortedIDs.size(); i++) { + PsiClass psiClass = (PsiClass)sortedIDs.get(i); + final List processors = myClassUsagesRequests.get(psiClass); + + incrementJobDoneAmount(FIND_EXTERNAL_USAGES, psiClass.getQualifiedName()); + + helper.processReferences(createReferenceProcessor(processors), psiClass, searchScope, false); + } + + myClassUsagesRequests = null; + } + + if (myMethodUsagesRequests != null) { + ArrayList sortedIDs = getSortedIDs(myMethodUsagesRequests); + for (int i = 0; i < sortedIDs.size(); i++) { + PsiMethod psiMethod = (PsiMethod)sortedIDs.get(i); + final List processors = myMethodUsagesRequests.get(psiMethod); + + incrementJobDoneAmount(FIND_EXTERNAL_USAGES, RefUtil.getQualifiedName(refManager.getReference(psiMethod))); + + helper.processReferencesIncludingOverriding(createReferenceProcessor(processors), psiMethod, searchScope); + } + + myMethodUsagesRequests = null; + } + } + }, null); + } + + private int getRequestCount() { + int sum = 0; + + sum += getRequestListSize(myClassUsagesRequests); + sum += getRequestListSize(myDerivedClassesRequests); + sum += getRequestListSize(myDerivedMethodsRequests); + sum += getRequestListSize(myFieldUsagesRequests); + sum += getRequestListSize(myMethodUsagesRequests); + + return sum; + } + + private static int getRequestListSize(HashMap list) { + if (list == null) return 0; + return list.size(); + } + + private static ArrayList getSortedIDs(HashMap requests) { + ArrayList result = new ArrayList(); + for (Iterator iterator = requests.keySet().iterator(); iterator.hasNext();) { + PsiElement id = (PsiElement)iterator.next(); + result.add(id); + } + + Collections.sort(result, new Comparator() { + public int compare(Object o1, Object o2) { + PsiElement i1 = (PsiElement)o1; + PsiElement i2 = (PsiElement)o2; + + return i1.getContainingFile().getName().compareTo(i2.getContainingFile().getName()); + } + }); + + return result; + } + + private PsiReferenceProcessor createReferenceProcessor(final List processors) { + return new PsiReferenceProcessor() { + public boolean execute(PsiReference reference) { + AnalysisScope scope = getRefManager().getScope(); + if (scope.contains(reference.getElement()) || + PsiTreeUtil.getParentOfType(reference.getElement(), PsiDocComment.class) != null) { + return true; + } + UsagesProcessor[] processorsArrayed = processors.toArray(new UsagesProcessor[processors.size()]); + for (int j = 0; j < processorsArrayed.length; j++) { + UsagesProcessor processor = processorsArrayed[j]; + if (!processor.process(reference)) { + processors.remove(processor); + } + } + + return processors.size() > 0; + } + }; + } + + private void launchInspections(final AnalysisScope scope) { + cleanup(); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + } + }); + + + LOG.info("Code inspection started"); + + Runnable runInspection = new Runnable() { + public void run() { + performInspectionsWithProgress(scope); + } + }; + + if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously(runInspection, "Inspecting Code...", true, myProject)) return; + + InspectionResultsView view = new InspectionResultsView(myProject); + InspectionTool[] tools = getCurrentProfile().getInspectionTools(myProject); + if (!view.update(tools)) { + Messages.showMessageDialog(myProject, + "No suspicious code found", + "Code Inspection", + Messages.getInformationIcon()); + } + else { + addView(view); + } + } + + private void performInspectionsWithProgress(final AnalysisScope scope) { + try { + myProgressIndicator = ProgressManager.getInstance().getProgressIndicator(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + PsiManager.getInstance(myProject).startBatchFilesProcessingMode(); + getRefManager().inspectionReadActionStarted(); + EntryPointsManager.getInstance(getProject()).resolveEntryPoints(getRefManager()); + + InspectionTool[] tools = getCurrentProfile().getInspectionTools(myProject); + ArrayList localTools = initJobDescriptors(tools, scope); + + List needRepeatSearchRequest = new ArrayList(); + runTools(tools, localTools, needRepeatSearchRequest, scope); + performPostRunFindUsages(needRepeatSearchRequest); + } + catch (ProcessCanceledException e) { + cleanup(); + throw e; + } + finally { + PsiManager.getInstance(myProject).finishBatchFilesProcessingMode(); + } + } + }); + } + finally { + if (myRefManager != null) { + getRefManager().inspectionReadActionFinished(); + } + } + } + + private void performPostRunFindUsages(List needRepeatSearchRequest) { + FIND_EXTERNAL_USAGES.setTotalAmount(getRequestCount() * 2); + + do { + processSearchRequests(); + InspectionTool[] requestors = needRepeatSearchRequest.toArray(new InspectionTool[needRepeatSearchRequest.size()]); + for (int i = 0; i < requestors.length; i++) { + InspectionTool requestor = requestors[i]; + if (!requestor.queryExternalUsagesRequests()) needRepeatSearchRequest.remove(requestor); + } + int oldSearchRequestCount = FIND_EXTERNAL_USAGES.getTotalAmount(); + float proportion = FIND_EXTERNAL_USAGES.getProgress(); + int totalAmount = oldSearchRequestCount + getRequestCount() * 2; + FIND_EXTERNAL_USAGES.setTotalAmount(totalAmount); + FIND_EXTERNAL_USAGES.setDoneAmount((int)(totalAmount * proportion)); + } + while (needRepeatSearchRequest.size() > 0); + } + + private void runTools(InspectionTool[] tools, + final ArrayList localTools, + List needRepeatSearchRequest, + final AnalysisScope scope) { + final PsiManager psiManager = PsiManager.getInstance(myProject); + for (int i = 0; i < tools.length; i++) { + InspectionTool tool = tools[i]; + if (getCurrentProfile().isToolEnabled(HighlightDisplayKey.find(tool.getShortName()))) tool.initialize(this); + } + + try { + scope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitJavaFile(PsiJavaFile file) { + incrementJobDoneAmount(LOCAL_ANALYSIS, file.getVirtualFile().getPresentableUrl()); + for (int i = 0; i < localTools.size(); i++) { + LocalInspectionToolWrapper tool = localTools.get(i); + tool.processFile(file); + psiManager.dropResolveCaches(); + } + } + }); + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable e) { + LOG.error(e); + } + + for (int i = 0; i < tools.length; i++) { + InspectionTool tool = tools[i]; + if (getCurrentProfile().isToolEnabled(HighlightDisplayKey.find(tool.getShortName())) && + !(tool instanceof LocalInspectionToolWrapper)) { + try { + tool.runInspection(scope); + + if (tool.queryExternalUsagesRequests()) { + needRepeatSearchRequest.add(tool); + } + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable e) { + LOG.error(e); + } + } + } + } + + private ArrayList initJobDescriptors(InspectionTool[] tools, + final AnalysisScope scope) { + ArrayList localTools = new ArrayList(); + myJobDescriptors = new ArrayList(); + for (int i = 0; i < tools.length; i++) { + InspectionTool tool = tools[i]; + if (getCurrentProfile().isToolEnabled(HighlightDisplayKey.find(tool.getShortName()))) { + if (tool instanceof LocalInspectionToolWrapper) { + LocalInspectionToolWrapper wrapper = (LocalInspectionToolWrapper)tool; + localTools.add(wrapper); + appendJobDescriptor(LOCAL_ANALYSIS); + } + else { + JobDescriptor[] jobDescriptors = tool.getJobDescriptors(); + for (int j = 0; j < jobDescriptors.length; j++) { + appendJobDescriptor(jobDescriptors[j]); + } + } + } + } + + BUILD_GRAPH.setTotalAmount(scope.getFileCount()); + LOCAL_ANALYSIS.setTotalAmount(scope.getFileCount()); + return localTools; + } + + private void appendJobDescriptor(JobDescriptor job) { + if (!myJobDescriptors.contains(job)) { + myJobDescriptors.add(job); + job.setDoneAmount(0); + } + } + + public UIOptions getUIOptions() { + return myUIOptions; + } + + public class UIOptions implements JDOMExternalizable { + public boolean AUTOSCROLL_TO_SOURCE = false; + public float SPLITTER_PROPORTION = 0.5f; + public final AutoScrollToSourceHandler myAutoScrollToSourceHandler; + + public UIOptions() { + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return AUTOSCROLL_TO_SOURCE; + } + + protected void setAutoScrollMode(boolean state) { + AUTOSCROLL_TO_SOURCE = state; + } + }; + } + + public void readExternal(org.jdom.Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(org.jdom.Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + } + + private class CloseAction extends AnAction { + private CloseAction() { + super("Close", null, IconLoader.getIcon("/actions/cancel.png")); + } + + public void actionPerformed(AnActionEvent e) { + close(); + } + } + + public void close() { + getContentManager().removeAllContents(); + cleanup(); + } + + public void addCommonActions(DefaultActionGroup group, InspectionResultsView view) { + group.add(new CloseAction()); + group.add(createToggleAutoscrollAction()); + group.add(new RerunAction(view)); + group.add(new PreviousOccurenceToolbarAction(view.getOccurenceNavigator())); + group.add(new NextOccurenceToolbarAction(view.getOccurenceNavigator())); + group.add(new ExportHTMLAction()); + group.add(new HelpAction()); + } + + public ToggleAction createToggleAutoscrollAction() { + return myUIOptions.myAutoScrollToSourceHandler.createToggleAction(); + } + + public void installAutoscrollHandler(JTree tree) { + myUIOptions.myAutoScrollToSourceHandler.install(tree); + } + + private void exportHTML() { + ExportToHTMLDialog exportToHTMLDialog = new ExportToHTMLDialog(myProject); + final ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myProject); + if (exportToHTMLSettings.OUTPUT_DIRECTORY == null) { + exportToHTMLSettings.OUTPUT_DIRECTORY = PathManager.getHomePath() + File.separator + "exportToHTML"; + } + exportToHTMLDialog.reset(); + exportToHTMLDialog.show(); + if (!exportToHTMLDialog.isOK()) { + return; + } + exportToHTMLDialog.apply(); + + final String outputDirectoryName = exportToHTMLSettings.OUTPUT_DIRECTORY; + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final Runnable exportRunnable = new Runnable() { + public void run() { + HTMLExportFrameMaker maker = new HTMLExportFrameMaker(outputDirectoryName, myProject); + maker.start(); + try { + myView.exportHTML(maker); + } + catch (ProcessCanceledException e) { + // Do nothing here. + } + + maker.done(); + } + }; + + if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously(exportRunnable, "Generating HTML...", true, myProject)) return; + + if (exportToHTMLSettings.OPEN_IN_BROWSER) { + BrowserUtil.launchBrowser(exportToHTMLSettings.OUTPUT_DIRECTORY + File.separator + "index.html"); + } + } + }); + } + + public void setLeftSplitterProportion(float proportion) { + getUIOptions().SPLITTER_PROPORTION = proportion; + } + + private static class HelpAction extends AnAction { + private HelpAction() { + super("Help", null, IconLoader.getIcon("/actions/help.png")); + } + + public void actionPerformed(AnActionEvent event) { + HelpManager.getInstance().invokeHelp(HELP_ID); + } + } + + private class ExportHTMLAction extends AnAction { + public ExportHTMLAction() { + super("Export HTML", null, IconLoader.getIcon("/actions/export.png")); + } + + public void actionPerformed(AnActionEvent e) { + exportHTML(); + } + } + + private class RerunAction extends AnAction { + public RerunAction(JComponent comp) { + super("Rerun Inspection", "Rerun Inspection", IconLoader.getIcon("/actions/refreshUsages.png")); + registerCustomShortcutSet(CommonShortcuts.getRerun(), comp); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myCurrentScope.isValid()); + } + + public void actionPerformed(AnActionEvent e) { + rerun(); + } + } + + public String getComponentName() { + return "InspectionManager"; + } + + public void refreshViews() { + InspectionTool[] tools = getCurrentProfile().getInspectionTools(myProject); + myView.update(tools); + } + + public void incrementJobDoneAmount(JobDescriptor job, String message) { + if (myProgressIndicator == null) return; + + ProgressManager.getInstance().checkCanceled(); + + int old = job.getDoneAmount(); + job.setDoneAmount(old + 1); + + int jobCount = myJobDescriptors.size(); + float totalProgress = 0; + for (int i = 0; i < myJobDescriptors.size(); i++) { + totalProgress += myJobDescriptors.get(i).getProgress(); + } + + totalProgress /= jobCount; + + myProgressIndicator.setFraction(totalProgress); + myProgressIndicator.setText(job.getDisplayName() + " " + message); + } + + public void setProfile(InspectionProfile profile) { + myCurrentProfileName = profile.getName(); + } + + public void setExternalProfile(InspectionProfile profile) { + myExternalProfile = profile; + } + + public boolean areResultsShown() { + return myView != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfile.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfile.java new file mode 100644 index 00000000000..152459792e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfile.java @@ -0,0 +1,88 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.openapi.project.Project; + +import java.io.File; + +/** + * User: anna + * Date: Dec 7, 2004 + */ +public interface InspectionProfile { + + String getName(); + + HighlightDisplayLevel getErrorLevel(HighlightDisplayKey inspectionToolKey); + + InspectionTool getInspectionTool(String displayName); + + InspectionTool[] getInspectionTools(Project project); + + LocalInspectionTool[] getHighlightingLocalInspectionTools(); + + File getFile(); + + InspectionProfileManager getManager(); + + void cleanup(); + + boolean wasInitialized(); + + ModifiableModel getModifiableModel(); + + boolean isToolEnabled(HighlightDisplayKey key); + + interface ModifiableModel { + + InspectionProfile getParentProfile(); + + String getBaseProfileName(); + + void setBaseProfile(InspectionProfileImpl profile); + + void removeInheritance(boolean inheritFromBaseBase); + + String getName(); + + void setName(String name); + + void enableTool(String inspectionTool); + + void disableTool(String inspectionTool); + + void setErrorLevel(HighlightDisplayKey key, HighlightDisplayLevel level); + + HighlightDisplayLevel getErrorLevel(HighlightDisplayKey inspectionToolKey); + + boolean isToolEnabled(HighlightDisplayKey key); + + void commit(); + + boolean isChanged(); + + void setModified(final boolean toolsSettingsChanged); + + VisibleTreeState getExpandedNodes(); + + boolean isProperSetting(HighlightDisplayKey key); + + void setAdditionalJavadocTags(String tags); + + void resetToBase(); + + LocalInspectionToolWrapper[] getLocalInspectionToolWrappers(); + + InspectionTool[] getInspectionTools(Project project); + + String getAdditionalJavadocTags(); + + void copyFrom(InspectionProfileImpl profile); + + void inheritFrom(InspectionProfileImpl profile); + + void loadAdditionalSettingsFromBaseProfile(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfileImpl.java new file mode 100644 index 00000000000..79058fbf811 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionProfileImpl.java @@ -0,0 +1,675 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInsight.daemon.InspectionProfileConvertor; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; + +/** + * @author max + */ +public class InspectionProfileImpl implements InspectionProfile.ModifiableModel, InspectionProfile { + public static final InspectionProfileImpl EMPTY_PROFILE = new InspectionProfileImpl("empty"); + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionProfileImpl"); + private static String VALID_VERSION = "1.0"; + private String myName; + private File myFile; + + //fiff from base + // private HashMap myEnabledTools; + private HashMap myTools = new HashMap(); + private HashMap myLocalTools = new HashMap(); + private InspectionProfileManager myManager; + + //diff map with base profile + private LinkedHashMap myDisplayLevelMap = new LinkedHashMap(); + + private InspectionProfileImpl mySource; + private InspectionProfileImpl myBaseProfile = null; + //private String myBaseProfileName; + + public void setModified(final boolean modified) { + myModified = modified; + } + + private boolean myModified = false; + private boolean myInitialized = false; + + private VisibleTreeState myVisibleTreeState = new VisibleTreeState(); + + private String myAdditionalJavadocTags = ""; + + public InspectionProfileImpl(File file, InspectionProfileManager manager) throws IOException, JDOMException { + this(getProfileName(file), getBaseProfileName(file), file, manager); + mySource = null; + } + + public InspectionProfileImpl(String name, String baseProfileName, File file, InspectionProfileManager manager) { + myName = name; + myFile = file; + myManager = manager; + if (baseProfileName != null) { + myBaseProfile = manager.getProfile(baseProfileName); + if (myBaseProfile == null) {//was not init yet + myBaseProfile = new InspectionProfileImpl(baseProfileName, manager); + } + } + mySource = null; + } + + public InspectionProfileImpl(String name, InspectionProfileManager manager) { + myName = name; + myFile = new File(InspectionProfileManager.getProfileDirectory(), myName + ".xml"); + myManager = manager; + mySource = null; + } + + + InspectionProfileImpl(InspectionProfileImpl inspectionProfile) { + myName = inspectionProfile.getName(); + myFile = inspectionProfile.getFile(); + myManager = inspectionProfile.getManager(); + myDisplayLevelMap = new LinkedHashMap(inspectionProfile.myDisplayLevelMap); + myLocalTools = new HashMap(inspectionProfile.myLocalTools); + myTools = new HashMap(inspectionProfile.myTools); + myVisibleTreeState = new VisibleTreeState(inspectionProfile.myVisibleTreeState); + myAdditionalJavadocTags = inspectionProfile.myAdditionalJavadocTags; + myBaseProfile = inspectionProfile.myBaseProfile; + mySource = inspectionProfile; + } + + //for tests only + public InspectionProfileImpl(final String inspectionProfile) { + myName = inspectionProfile; + myInitialized = true; + setDefaultErrorLevels(); + } + + public InspectionProfile getParentProfile() { + return mySource; + } + + public String getBaseProfileName() { + if (myBaseProfile == null) return null; + return myBaseProfile.getName(); + } + + public void setBaseProfile(InspectionProfileImpl profile) { + myBaseProfile = profile; + } + + public void removeInheritance(boolean inheritFromBaseBase) { + if (myBaseProfile != null) { + LinkedHashMap map = new LinkedHashMap(); + if (inheritFromBaseBase) { + map.putAll(myBaseProfile.myDisplayLevelMap); + myBaseProfile = myBaseProfile.myBaseProfile; + } + else { + map.putAll(myBaseProfile.getFullDisplayMap()); + myBaseProfile = null; + } + map.putAll(myDisplayLevelMap); + myDisplayLevelMap = map; + } + } + + private HashMap getFullDisplayMap() { + final HashMap map = new HashMap(); + if (myBaseProfile != null) { + map.putAll(myBaseProfile.getFullDisplayMap()); + } + map.putAll(myDisplayLevelMap); + return map; + } + + public boolean isChanged() { + return myModified; + } + + public VisibleTreeState getExpandedNodes() { + return myVisibleTreeState; + } + + private boolean toolSettingsAreEqual(String toolDisplayName, + InspectionProfileImpl profile1, + InspectionProfileImpl profile2) { + final InspectionTool tool1 = profile1.getInspectionTool(toolDisplayName);//findInspectionToolByName(profile1, toolDisplayName); + final InspectionTool tool2 = profile2.getInspectionTool(toolDisplayName);//findInspectionToolByName(profile2, toolDisplayName); + if (tool1 == null && tool2 == null) { + return true; + } + if (tool1 != null && tool2 != null) { + try { + Element oldToolSettings = new Element("root"); + tool1.writeExternal(oldToolSettings); + Element newToolSettings = new Element("root"); + tool2.writeExternal(newToolSettings); + return JDOMUtil.areElementsEqual(oldToolSettings, newToolSettings); + } + catch (WriteExternalException e) { + LOG.error(e); + } + } + return false; + } + + public boolean isProperSetting(HighlightDisplayKey key) { + if (myBaseProfile == null) { + return false; + } + final boolean toolsSettings = toolSettingsAreEqual(key.toString(), this, myBaseProfile); + if (myDisplayLevelMap.keySet().contains(key)) { + if (toolsSettings && myDisplayLevelMap.get(key).equals(myBaseProfile.getToolState(key))) { + myDisplayLevelMap.remove(key); + return false; + } + return true; + } + if (key == HighlightDisplayKey.UNKNOWN_JAVADOC_TAG && + !myBaseProfile.getAdditionalJavadocTags().equals(getAdditionalJavadocTags())) { + return true; + } + if (!toolsSettings) { + myDisplayLevelMap.put(key, myBaseProfile.getToolState(key)); + return true; + } + + return false; + } + + + public void setAdditionalJavadocTags(String tags) { + if (myBaseProfile != null && myBaseProfile.getAdditionalJavadocTags().length() > 0) { + myAdditionalJavadocTags = tags.length() > myBaseProfile.getAdditionalJavadocTags().length() + ? tags.substring(myBaseProfile.getAdditionalJavadocTags().length() + 1).trim() + : ""; + } + else { + myAdditionalJavadocTags = tags; + } + } + + public void resetToBase() { + if (myBaseProfile != null) { + myDisplayLevelMap = new LinkedHashMap(myBaseProfile.myDisplayLevelMap); + myBaseProfile = myBaseProfile.myBaseProfile; + } + else { + boolean toolsWereNotInstantiated = false; + if (myTools.isEmpty() || myLocalTools.isEmpty()) { + getInspectionTools(null); + toolsWereNotInstantiated = true; + } + myDisplayLevelMap.clear(); + setDefaultErrorLevels(); + final ArrayList toolNames = new ArrayList(myTools.keySet()); + toolNames.addAll(myLocalTools.keySet()); + for (Iterator iterator = toolNames.iterator(); iterator.hasNext();) { + final InspectionTool tool = getInspectionTool(iterator.next()); + final HighlightDisplayLevel defaultLevel = tool.getDefaultLevel(); + HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName()); + if (key == null) { + key = HighlightDisplayKey.register(tool.getShortName()); + } + myDisplayLevelMap.put(key, + new ToolState(defaultLevel, tool.isEnabledByDefault())); + } + if (toolsWereNotInstantiated) { + //to instantiate tools correctly + myTools.clear(); + } + } + myInitialized = true; + } + + private void setDefaultErrorLevels() { + myDisplayLevelMap.put(HighlightDisplayKey.DEPRECATED_SYMBOL, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.UNUSED_IMPORT, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.UNUSED_SYMBOL, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.UNUSED_THROWS_DECL, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.SILLY_ASSIGNMENT, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.ACCESS_STATIC_VIA_INSTANCE, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.WRONG_PACKAGE_STATEMENT, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.JAVADOC_ERROR, new ToolState(HighlightDisplayLevel.ERROR)); + myDisplayLevelMap.put(HighlightDisplayKey.UNKNOWN_JAVADOC_TAG, new ToolState(HighlightDisplayLevel.ERROR)); + myDisplayLevelMap.put(HighlightDisplayKey.EJB_ERROR, new ToolState(HighlightDisplayLevel.ERROR)); + myDisplayLevelMap.put(HighlightDisplayKey.EJB_WARNING, new ToolState(HighlightDisplayLevel.WARNING)); + myDisplayLevelMap.put(HighlightDisplayKey.ILLEGAL_DEPENDENCY, new ToolState(HighlightDisplayLevel.WARNING)); + } + + public String getName() { + return myName; + } + + public void setName(String name) { + myName = name; + } + + public HighlightDisplayLevel getErrorLevel(HighlightDisplayKey inspectionToolKey) { + return getToolState(inspectionToolKey).getLevel(); + } + + private ToolState getToolState(HighlightDisplayKey key) { + ToolState state = myDisplayLevelMap.get(key); + if (state == null) { + if (myBaseProfile != null) { + state = myBaseProfile.getToolState(key); + } + } + //default level for converted profiles + if (state == null) { + state = new ToolState(HighlightDisplayLevel.WARNING, false); + } + return state; + } + + private void readExternal(Element element, boolean readLocalTools) throws InvalidDataException { + myDisplayLevelMap.clear(); + final String version = element.getAttributeValue("version"); + if (version == null || !version.equals(VALID_VERSION)) { + try { + InspectionProfileConvertor.convertToNewFormat(myFile, this); + element = JDOMUtil.loadDocument(myFile).getRootElement(); + } + catch (IOException e) { + LOG.error(e); + } + catch (JDOMException e) { + LOG.error(e); + } + } + for (Iterator i = element.getChildren("inspection_tool").iterator(); i.hasNext();) { + Element toolElement = (Element)i.next(); + + String toolClassName = toolElement.getAttributeValue("class"); + + HighlightDisplayKey key = HighlightDisplayKey.find(toolClassName); + if (key == null) { + key = HighlightDisplayKey.register(toolClassName); + } + + final String levelName = toolElement.getAttributeValue("level"); + HighlightDisplayLevel level = HighlightDisplayLevel.find(levelName); + if (level == null || level == HighlightDisplayLevel.DO_NOT_SHOW) {//from old profiles + level = HighlightDisplayLevel.WARNING; + } + + final String enabled = toolElement.getAttributeValue("enabled"); + myDisplayLevelMap.put(key, new ToolState(level, enabled != null && "true".equals(enabled))); + + InspectionTool tool = getInspectionTool(toolClassName); + if (tool != null) { + if (!(tool instanceof LocalInspectionToolWrapper) || readLocalTools) { + tool.readExternal(toolElement); + } + } + } + myVisibleTreeState.readExternal(element); + final Element additionalJavadocs = element.getChild("ADDITIONAL_JAVADOC_TAGS"); + if (additionalJavadocs != null) { + myAdditionalJavadocTags = additionalJavadocs.getAttributeValue("value"); + } + final String baseProfileName = element.getAttributeValue("base_profile"); + if (baseProfileName != null && myBaseProfile == null) { + myBaseProfile = InspectionProfileManager.getInstance().getProfile(baseProfileName); + if (baseProfileName.equals("Default")) { + myBaseProfile.resetToBase(); + } + if (!myBaseProfile.wasInitialized()) { + myBaseProfile.load(readLocalTools); + } + } + } + + + public void writeExternal(Element element) throws WriteExternalException { + element.setAttribute("version", VALID_VERSION); + for (Iterator iterator = myDisplayLevelMap.keySet().iterator(); iterator.hasNext();) { + final HighlightDisplayKey key = iterator.next(); + Element inspectionElement = new Element("inspection_tool"); + final String toolName = key.toString(); + inspectionElement.setAttribute("class", toolName); + inspectionElement.setAttribute("level", getErrorLevel(key).toString()); + inspectionElement.setAttribute("enabled", isToolEnabled(key) ? "true" : "false"); + + final InspectionTool tool = getInspectionTool(toolName); + if (tool != null) { + tool.writeExternal(inspectionElement); + } + element.addContent(inspectionElement); + } + myVisibleTreeState.writeExternal(element); + if (myAdditionalJavadocTags != null && myAdditionalJavadocTags.length() != 0) { + final Element additionalTags = new Element("ADDITIONAL_JAVADOC_TAGS"); + additionalTags.setAttribute("value", myAdditionalJavadocTags); + element.addContent(additionalTags); + } + if (myBaseProfile != null) { + element.setAttribute("base_profile", myBaseProfile.getName()); + } + } + + public InspectionTool getInspectionTool(String displayName) { + if (myTools.get(displayName) != null) { + return myTools.get(displayName); + } + if (myLocalTools.get(displayName) != null) { + return myLocalTools.get(displayName); + } + return null; + } + + public InspectionProfileManager getManager() { + return myManager; + } + + private static String getProfileName(File file) throws JDOMException, IOException { + if (file.exists()) { + Document doc = JDOMUtil.loadDocument(file); + Element root = doc.getRootElement(); + String profileName = root.getAttributeValue("profile_name"); + if (profileName != null) return profileName; + } + String fileName = file.getName(); + int extensionIndex = fileName.lastIndexOf(".xml"); + return fileName.substring(0, extensionIndex); + } + + private static String getBaseProfileName(File file) throws JDOMException, IOException { + if (file.exists()) { + Document doc = JDOMUtil.loadDocument(file); + Element root = doc.getRootElement(); + String profileName = root.getAttributeValue("base_profile"); + if (profileName != null) return profileName; + } + return null; + } + + void save(File file, String name) { + try { + Element root = new Element("inspections"); + root.setAttribute("profile_name", name); + writeExternal(root); + if (file != null) { + JDOMUtil.writeDocument(new Document(root), file, CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + } + catch (WriteExternalException e) { + LOG.error(e); + } + catch (IOException e) { + LOG.error(e); + } + } + + public void load(boolean readLocalTools) { + try { + if (myName.equals("Default")) { + resetToBase(); + return; + } + if (myFile == null || !myFile.exists()) { + if (myBaseProfile != null) { + loadAdditionalSettingsFromBaseProfile(); + } + return; + } + + Document document = JDOMUtil.loadDocument(myFile); + readExternal(document.getRootElement(), readLocalTools); + myInitialized = true; + } + catch (JDOMException e) { + LOG.error(e); + } + catch (IOException e) { + LOG.error(e); + } + catch (InvalidDataException e) { + LOG.error(e); + } + } + + public void loadAdditionalSettingsFromBaseProfile() {//load additional settings from base profile + if (myBaseProfile == null) return; + try { + final ArrayList toolNames = new ArrayList(myTools.keySet()); + toolNames.addAll(myLocalTools.keySet()); + for (Iterator iterator = toolNames.iterator(); iterator.hasNext();) { + final String key = iterator.next(); + if (myDisplayLevelMap.containsKey(HighlightDisplayKey.find(key))) { + continue; + } + Element root = new Element("root"); + final InspectionTool baseInspectionTool = myBaseProfile.getInspectionTool(key); + if (baseInspectionTool != null) { + baseInspectionTool.writeExternal(root); + InspectionTool tool = getInspectionTool(key); + tool.readExternal(root); + } + } + } + catch (WriteExternalException e) { + LOG.error(e); + } + catch (InvalidDataException e) { + LOG.error(e); + } + } + + public File getFile() { + return myFile; + } + + public InspectionTool[] getInspectionTools(Project project) { + if (myBaseProfile != null && myBaseProfile.myTools.isEmpty()) { + myBaseProfile.getInspectionTools(project); + } + if (myTools.isEmpty()) { + boolean localToolsWereInitialized = true; + final InspectionTool[] tools = InspectionToolRegistrar.getInstance().createTools(project); + for (int i = 0; i < tools.length; i++) { + if (!(tools[i] instanceof LocalInspectionToolWrapper)) { + myTools.put(tools[i].getShortName(), tools[i]); + } + else { + if (!myLocalTools.containsKey(tools[i].getShortName())) {//do not touch exist local tools + localToolsWereInitialized = false; + myLocalTools.put(tools[i].getShortName(), (LocalInspectionToolWrapper)tools[i]); + } + } + } + load(!localToolsWereInitialized); + loadAdditionalSettingsFromBaseProfile(); + } + ArrayList result = new ArrayList(); + result.addAll(myLocalTools.values()); + result.addAll(myTools.values()); + return result.toArray(new InspectionTool[result.size()]); + } + + public LocalInspectionToolWrapper[] getLocalInspectionToolWrappers() { + if (myBaseProfile != null && myBaseProfile.myLocalTools.isEmpty()) { + myBaseProfile.getLocalInspectionToolWrappers(); + } + if (myLocalTools.isEmpty()) { + final LocalInspectionTool[] localTools = InspectionToolRegistrar.getInstance().createLocalTools(); + for (int i = 0; i < localTools.length; i++) { + myLocalTools.put(localTools[i].getShortName(), new LocalInspectionToolWrapper(localTools[i])); + } + load(true); + loadAdditionalSettingsFromBaseProfile(); + } + return myLocalTools.values().toArray(new LocalInspectionToolWrapper[myLocalTools.values().size()]); + } + + public LocalInspectionTool[] getHighlightingLocalInspectionTools() { + ArrayList enabled = new ArrayList(); + final LocalInspectionToolWrapper[] tools = myLocalTools.isEmpty() + ? getLocalInspectionToolWrappers() + : myLocalTools.values().toArray( + new LocalInspectionToolWrapper[myLocalTools.values().size()]); + for (int i = 0; i < tools.length; i++) { + LocalInspectionToolWrapper tool = tools[i]; + final ToolState state = getToolState(HighlightDisplayKey.find(tool.getShortName())); + if (state.isEnabled()) { + enabled.add(tool.getTool()); + } + } + return enabled.toArray(new LocalInspectionTool[enabled.size()]); + } + + public ModifiableModel getModifiableModel() { + return new InspectionProfileImpl(this); + } + + public String getAdditionalJavadocTags() { + if (myBaseProfile != null) { + return myBaseProfile.getAdditionalJavadocTags().length() > 0 ? myBaseProfile.getAdditionalJavadocTags() + + (myAdditionalJavadocTags.length() > 0 + ? "," + myAdditionalJavadocTags + : "") : + myAdditionalJavadocTags; + } + return myAdditionalJavadocTags; + } + + public void copyFrom(InspectionProfileImpl profile) { + myDisplayLevelMap = new LinkedHashMap(profile.myDisplayLevelMap); + myBaseProfile = profile.myBaseProfile; + myAdditionalJavadocTags = profile.myAdditionalJavadocTags; + } + + public void inheritFrom(InspectionProfileImpl profile) { + myBaseProfile = profile; + } + + public void cleanup() { + if (myTools.isEmpty()) return; + if (!myTools.isEmpty()) { + for (Iterator iterator = myTools.keySet().iterator(); iterator.hasNext();) { + myTools.get(iterator.next()).cleanup(); + } + } + myTools.clear(); + } + + public boolean wasInitialized() { + return myInitialized; + } + + public void enableTool(String inspectionTool) { + final HighlightDisplayKey key = HighlightDisplayKey.find(inspectionTool); + setState(key, + new ToolState(getErrorLevel(key), true)); + } + + public void disableTool(String inspectionTool) { + final HighlightDisplayKey key = HighlightDisplayKey.find(inspectionTool); + setState(key, + new ToolState(getErrorLevel(key), false)); + } + + + public void setErrorLevel(HighlightDisplayKey key, HighlightDisplayLevel level) { + setState(key, new ToolState(level, isToolEnabled(key))); + } + + private void setState(HighlightDisplayKey key, ToolState state) { + if (myBaseProfile != null && + state.equals(myBaseProfile.getToolState(key))) { + myDisplayLevelMap.remove(key); + } + else { + myDisplayLevelMap.put(key, state); + } + } + + public boolean isToolEnabled(HighlightDisplayKey key) { + final ToolState toolState = getToolState(key); + if (toolState != null) { + return toolState.isEnabled(); + } + return false; + } + + //invoke when isChanged() == true + public void commit() { + LOG.assertTrue(mySource != null); + mySource.commit(this); + mySource = null; + myManager.initProfile(this); + } + + private void commit(InspectionProfileImpl inspectionProfile) { + myName = inspectionProfile.myName; + myDisplayLevelMap = inspectionProfile.myDisplayLevelMap; + myVisibleTreeState = inspectionProfile.myVisibleTreeState; + myBaseProfile = inspectionProfile.myBaseProfile; + myTools = inspectionProfile.myTools; + myLocalTools = inspectionProfile.myLocalTools; + myAdditionalJavadocTags = inspectionProfile.myAdditionalJavadocTags; + save(new File(InspectionProfileManager.getProfileDirectory(), myName + ".xml"), myName); + } + + private static class ToolState { + private HighlightDisplayLevel myLevel; + private boolean myEnabled; + + public ToolState(final HighlightDisplayLevel level, final boolean enabled) { + myLevel = level; + myEnabled = enabled; + } + + public ToolState(final HighlightDisplayLevel level) { + myLevel = level; + myEnabled = true; + } + + public HighlightDisplayLevel getLevel() { + return myLevel; + } + + public void setLevel(final HighlightDisplayLevel level) { + myLevel = level; + } + + public boolean isEnabled() { + return myEnabled; + } + + public void setEnabled(final boolean enabled) { + myEnabled = enabled; + } + + public boolean equals(Object object) { + if (!(object instanceof ToolState)) return false; + final ToolState state = (ToolState)object; + return myLevel == state.getLevel() && + myEnabled == state.isEnabled(); + } + + public int hashCode() { + return myLevel.hashCode(); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionTool.java new file mode 100644 index 00000000000..ca260aa0e06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionTool.java @@ -0,0 +1,111 @@ +/* + * Author: max + * Date: Oct 9, 2001 + * Time: 8:50:56 PM + */ + +package com.intellij.codeInspection.ex; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.ui.InspectionTreeNode; +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 org.jdom.Element; + +import javax.swing.*; +import java.util.Map; +import java.util.Set; + +public abstract class InspectionTool implements JDOMExternalizable { + private InspectionManagerEx myManager; + private JComponent myOptions; + + public InspectionTool() { + } + + public void initialize(InspectionManagerEx manager) { + myManager = manager; + } + + public InspectionManagerEx getManager() { + return myManager; + } + + public RefManager getRefManager() { + return myManager.getRefManager(); + } + + public abstract void runInspection(AnalysisScope scope); + + public abstract void exportResults(Element parentNode); + + public QuickFixAction[] getQuickFixes() { + return null; + } + + public abstract JobDescriptor[] getJobDescriptors(); + + protected JComponent createOptionsPanel() { + return new JPanel(); + } + + public final JComponent getOptionsPanel(boolean forceCreate) { + if (myOptions == null || forceCreate) { + myOptions = createOptionsPanel(); + } + + return myOptions; + } + + public boolean queryExternalUsagesRequests() { + return false; + } + + public HighlightDisplayLevel getDefaultLevel() { + return HighlightDisplayLevel.WARNING; + } + + public boolean isEnabledByDefault() { + return getDefaultLevel() != HighlightDisplayLevel.DO_NOT_SHOW; + } + + public abstract String getDisplayName(); + + public abstract String getGroupDisplayName(); + + public abstract String getShortName(); + + public final String getDescriptionFileName() { + return getShortName() + ".html"; + } + + public final String getFolderName() { + return getShortName(); + } + + public void cleanup() { + } + + public abstract HTMLComposer getComposer(); + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public abstract boolean hasReportedProblems(); + + public abstract void updateContent(); + + public abstract InspectionTreeNode[] getContents(); + + public abstract Map> getPackageContent(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionToolRegistrar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionToolRegistrar.java new file mode 100644 index 00000000000..f8b840b9ad4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/InspectionToolRegistrar.java @@ -0,0 +1,150 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.InspectionToolProvider; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** + * @author max + */ +public class InspectionToolRegistrar implements ApplicationComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionToolRegistrar"); + + private final ArrayList myInspectionTools; + private final ArrayList myLocalInspectionTools; + + public InspectionToolRegistrar(InspectionToolProvider[] providers) { + myInspectionTools = new ArrayList(); + myLocalInspectionTools = new ArrayList(); + + for (int i = 0; i < providers.length; i++) { + InspectionToolProvider provider = providers[i]; + Class[] classes = provider.getInspectionClasses(); + for (int j = 0; j < classes.length; j++) { + if (LocalInspectionTool.class.isAssignableFrom(classes[j])) { + registerLocalInspection(classes[j]); + } + else { + registerInspectionTool(classes[j]); + } + } + } + } + + public static InspectionToolRegistrar getInstance() { + return ApplicationManager.getApplication().getComponent(InspectionToolRegistrar.class); + } + + public String getComponentName() { + return "InspectionToolRegistrar"; + } + + public void readExternal(Element element) throws InvalidDataException { + } + + public void writeExternal(Element element) throws WriteExternalException { + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public void registerLocalInspection(Class toolClass) { + myLocalInspectionTools.add(toolClass); + } + + public void registerInspectionTool(Class toolClass) { + if (myInspectionTools.contains(toolClass)) return; + myInspectionTools.add(toolClass); + } + + public InspectionTool[] createTools(Project project) { + int ordinaryToolsSize = myInspectionTools.size(); + InspectionTool[] tools = new InspectionTool[ordinaryToolsSize + myLocalInspectionTools.size()]; + for (int i = 0; i < tools.length; i++) { + tools[i] = i < ordinaryToolsSize + ? instantiateTool(myInspectionTools.get(i), project) + : new LocalInspectionToolWrapper(instantiateLocalTool(myLocalInspectionTools.get(i - ordinaryToolsSize))); + } + + return tools; + } + + private LocalInspectionTool instantiateLocalTool(Class toolClass) { + try { + Constructor constructor; + Object[] args; + constructor = toolClass.getDeclaredConstructor(new Class[0]); + args = ArrayUtil.EMPTY_OBJECT_ARRAY; + return (LocalInspectionTool) constructor.newInstance(args); + } catch (NoSuchMethodException e) { + LOG.error(e); + } catch (SecurityException e) { + LOG.error(e); + } catch (InstantiationException e) { + LOG.error(e); + } catch (IllegalAccessException e) { + LOG.error(e); + } catch (IllegalArgumentException e) { + LOG.error(e); + } catch (InvocationTargetException e) { + LOG.error(e); + } + return null; + } + + private InspectionTool instantiateTool(Class toolClass, Project project) { + try { + Constructor constructor; + Object[] args; + try { + constructor = toolClass.getDeclaredConstructor(new Class[]{Project.class}); + args = new Object[]{project}; + } + catch (NoSuchMethodException e) { + constructor = toolClass.getDeclaredConstructor(new Class[0]); + args = ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + constructor.setAccessible(true); + return (InspectionTool) constructor.newInstance(args); + } catch (SecurityException e) { + LOG.error(e); + } catch (NoSuchMethodException e) { + LOG.error(e); + } catch (InstantiationException e) { + LOG.error(e); + } catch (IllegalAccessException e) { + LOG.error(e); + } catch (IllegalArgumentException e) { + LOG.error(e); + } catch (InvocationTargetException e) { + LOG.error(e); + } + + return null; + } + + public LocalInspectionTool[] createLocalTools() { + LocalInspectionTool[] tools = new LocalInspectionTool[myLocalInspectionTools.size()]; + for (int i = 0; i < tools.length; i++) { + tools[i] = instantiateLocalTool(myLocalInspectionTools.get(i)); + } + + return tools; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/JobDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/JobDescriptor.java new file mode 100644 index 00000000000..792351af63c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/JobDescriptor.java @@ -0,0 +1,45 @@ +package com.intellij.codeInspection.ex; + +/** + * @author max + */ +public class JobDescriptor { + private String myDisplayName; + private int myTotalAmount; + private int myDoneAmount; + + public JobDescriptor(String displayName) { + myDisplayName = displayName; + } + + public String getDisplayName() { + return myDisplayName; + } + + public int getTotalAmount() { + return myTotalAmount; + } + + public void setTotalAmount(int totalAmount) { + myTotalAmount = totalAmount; + } + + public int getDoneAmount() { + return myDoneAmount; + } + + public void setDoneAmount(int doneAmount) { + myDoneAmount = doneAmount; + } + + public float getProgress() { + float localProgress = getDoneAmount(); + if (getTotalAmount() != 0) { + localProgress /= getTotalAmount(); + } else { + localProgress = 0; + } + + return localProgress; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java new file mode 100644 index 00000000000..bef47cb78ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java @@ -0,0 +1,151 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.*; +import org.jdom.Element; + +import javax.swing.*; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * @author max + */ +public final class LocalInspectionToolWrapper extends DescriptorProviderInspection { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.LocalInspectionToolWrapper"); + + private LocalInspectionTool myTool; + + public LocalInspectionToolWrapper(LocalInspectionTool tool) { + myTool = tool; + } + + public LocalInspectionTool getTool() { + return myTool; + } + + public void processFile(PsiJavaFile file) { + file.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitField(PsiField field) { + super.visitField(field); + if (getManager().isToCheckMember(field, myTool.getID())) { + ProblemDescriptor[] problemDescriptions = myTool.checkField(field, getManager(), false); + if (problemDescriptions != null) { + problemDescriptions = filterUnsuppressedPeoblemDescriptions(problemDescriptions); + RefManager refManager = getManager().getRefManager(); + RefElement refElement = refManager.getReference(field); + if (refElement != null) { + addProblemElement(refElement, problemDescriptions); + } + } + } + } + + private ProblemDescriptor[] filterUnsuppressedPeoblemDescriptions(ProblemDescriptor[] problemDescriptions) { + Set set = null; + for (int i = 0; i < problemDescriptions.length; i++) { + ProblemDescriptor description = problemDescriptions[i]; + if (getManager().inspectionResultSuppressed(description.getPsiElement(), myTool)) { + if (set == null) set = new LinkedHashSet(Arrays.asList(problemDescriptions)); + set.remove(description); + } + } + return set == null ? problemDescriptions : set.toArray(new ProblemDescriptor[set.size()]); + } + + public void visitClass(PsiClass aClass) { + super.visitClass(aClass); + if (getManager().isToCheckMember(aClass, myTool.getID()) && !(aClass instanceof PsiTypeParameter)) { + ProblemDescriptor[] problemDescriptions = myTool.checkClass(aClass, getManager(), false); + if (problemDescriptions != null) { + problemDescriptions = filterUnsuppressedPeoblemDescriptions(problemDescriptions); + RefManager refManager = getManager().getRefManager(); + RefElement refElement = refManager.getReference(aClass); + if (refElement != null) { + addProblemElement(refElement, problemDescriptions); + } + } + } + } + + + public void visitMethod(PsiMethod method) { + super.visitMethod(method); + if (getManager().isToCheckMember(method, myTool.getID())) { + ProblemDescriptor[] problemDescriptions = myTool.checkMethod(method, getManager(), false); + if (problemDescriptions != null) { + problemDescriptions = filterUnsuppressedPeoblemDescriptions(problemDescriptions); + RefManager refManager = getManager().getRefManager(); + RefElement refElement = refManager.getReference(method); + if (refElement != null) { + addProblemElement(refElement, problemDescriptions); + } + } + } + } + }); + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[0]; + } + + public void runInspection(AnalysisScope scope) { + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode()); + scope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitJavaFile(PsiJavaFile file) { + processFile(file); + } + }); + } + + public String getDisplayName() { + return myTool.getDisplayName(); + } + + public String getGroupDisplayName() { + return myTool.getGroupDisplayName(); + } + + public String getShortName() { + return myTool.getShortName(); + } + + public boolean isEnabledByDefault() { + return myTool.isEnabledByDefault(); + } + + public HighlightDisplayLevel getDefaultLevel() { + return myTool.getDefaultLevel(); + } + + public void readExternal(Element element) throws InvalidDataException { + myTool.readSettings(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + myTool.writeSettings(element); + } + + protected JComponent createOptionsPanel() { + JComponent provided = myTool.createOptionsPanel(); + return provided == null ? super.createOptionsPanel() : provided; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalQuickFixWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalQuickFixWrapper.java new file mode 100644 index 00000000000..671c1759737 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/LocalQuickFixWrapper.java @@ -0,0 +1,100 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.psi.PsiElement; + +/** + * @author max + */ +public class LocalQuickFixWrapper extends QuickFixAction { + private DescriptorProviderInspection myTool; + + public LocalQuickFixWrapper(DescriptorProviderInspection tool) { + super("Apply fix", tool); + myTool = tool; + } + + public void update(AnActionEvent e) { + super.update(e); + if (e.getPresentation().isEnabled()) { + final InspectionResultsView invoker = getInvoker(e); + if (invoker != null) { + ProblemDescriptor[] descriptors = invoker.getSelectedDescriptors(); + boolean hasFixes = false; + for (int i = 0; i < descriptors.length; i++) { + ProblemDescriptor descriptor = descriptors[i]; + if (descriptor.getFix() != null && descriptor.getPsiElement() != null) { + hasFixes = true; + break; + } + } + + if (hasFixes) { + e.getPresentation().setVisible(true); + e.getPresentation().setEnabled(true); + e.getPresentation().setText(getName(descriptors)); + return; + } + } + } + + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + } + + public String getText(RefElement where) { + return getName(getDescriptors(where)); + } + + private ProblemDescriptor[] getDescriptors(RefElement refElement) { + return myTool.getDescriptions(refElement); + } + + private String getName(ProblemDescriptor[] descriptors) { + String name = null; + for (int i = 0; i < descriptors.length; i++) { + ProblemDescriptor descriptor = descriptors[i]; + final LocalQuickFix fix = descriptor.getFix(); + if (fix != null) { + if (name == null) { + name = fix.getName(); + } + else { + if (!name.equals(fix.getName())) { + name = "Apply fix"; + } + } + } + } + return name; + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + ProblemDescriptor[] problems = myTool.getDescriptions(refElement); + if (problems != null) { + PsiElement psiElement = refElement.getElement(); + if (psiElement != null) { + for (int j = 0; j < problems.length; j++) { + LocalQuickFix fix = problems[j].getFix(); + if (fix != null) { + fix.applyFix(psiElement.getProject(), problems[j]); + myTool.ignoreProblem(refElement, problems[j]); + } + } + } + } + } + + return true; + } + + protected boolean isProblemDescriptorsAcceptable() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java new file mode 100644 index 00000000000..292b5b0fc01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java @@ -0,0 +1,60 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; + +/** + * @author max + */ +public class ProblemDescriptorImpl implements ProblemDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.ProblemDescriptorImpl"); + + private SmartPsiElementPointer mySmartPointer; + private final String myDescriptionTemplate; + private final LocalQuickFix myFix; + private ProblemHighlightType myHighlightType; + + public ProblemDescriptorImpl(PsiElement psiElement, String descriptionTemplate, LocalQuickFix fix, ProblemHighlightType highlightType) { + LOG.assertTrue(psiElement.isValid()); + LOG.assertTrue(psiElement.isPhysical()); + myFix = fix; + myHighlightType = highlightType; + final Project project = psiElement.getProject(); + mySmartPointer = SmartPointerManager.getInstance(project).createLazyPointer(psiElement); + myDescriptionTemplate = descriptionTemplate; + } + + public PsiElement getPsiElement() { + return mySmartPointer.getElement(); + } + + public int getLineNumber() { + PsiElement psiElement = getPsiElement(); + if (psiElement == null) return -1; + LOG.assertTrue(psiElement.isPhysical()); + Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(psiElement.getContainingFile()); + if (document == null) return -1; + return document.getLineNumber(psiElement.getTextOffset()) + 1; + } + + public LocalQuickFix getFix() { + return myFix; + } + + public ProblemHighlightType getHighlightType() { + return myHighlightType; + } + + public String getDescriptionTemplate() { + return myDescriptionTemplate; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixAction.java new file mode 100644 index 00000000000..78a9d5c25e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixAction.java @@ -0,0 +1,188 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefImplicitConstructor; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; + +import javax.swing.*; +import java.util.*; + +/** + * @author max + */ +public abstract class QuickFixAction extends AnAction { + private InspectionTool myTool; + + public InspectionResultsView getInvoker(AnActionEvent e) { + return (InspectionResultsView)e.getDataContext().getData(DataConstantsEx.INSPECTION_VIEW); + } + + protected QuickFixAction(String text, InspectionTool tool) { + this(text, IconLoader.getIcon("/actions/createFromUsage.png"), null, tool); + } + + protected QuickFixAction(String text, Icon icon, KeyStroke keyStroke, InspectionTool tool) { + super(text, null, icon); + myTool = tool; + if (keyStroke != null) { + registerCustomShortcutSet(new CustomShortcutSet(keyStroke), null); + } + } + + public void update(AnActionEvent e) { + final InspectionResultsView view = getInvoker(e); + if (view == null) { + e.getPresentation().setEnabled(false); + return; + } + + if (!view.isSingleToolInSelection() || view.getSelectedTool() != myTool) { + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + return; + } + + if (!isProblemDescriptorsAcceptable() && view.getSelectedElements().length > 0 || + isProblemDescriptorsAcceptable() && view.getSelectedDescriptors().length > 0) { + e.getPresentation().setVisible(true); + e.getPresentation().setEnabled(true); + } + } + + protected boolean isProblemDescriptorsAcceptable() { + return false; + } + + public String getText(RefElement where) { + return getTemplatePresentation().getText(); + } + + public void actionPerformed(final AnActionEvent e) { + if (isProblemDescriptorsAcceptable()) { + final InspectionResultsView view = getInvoker(e); + final ProblemDescriptor[] descriptors = view.getSelectedDescriptors(); + if (descriptors.length > 0) { + doApplyFix(view.getProject(), (DescriptorProviderInspection)view.getSelectedTool(), descriptors); + return; + } + } + + doApplyFix(getSelectedElements(e)); + } + + protected RefElement[] getSelectedElements(AnActionEvent e) { + final InspectionResultsView invoker = getInvoker(e); + if (invoker == null) return new RefElement[0]; + List selection = new ArrayList(Arrays.asList(invoker.getSelectedElements())); + PsiDocumentManager.getInstance(invoker.getProject()).commitAllDocuments(); + Collections.sort(selection, new Comparator() { + public int compare(Object o1, Object o2) { + RefElement r1 = (RefElement)o1; + RefElement r2 = (RefElement)o2; + int i1 = r1 instanceof RefImplicitConstructor ? 0 : r1.getElement().getTextOffset(); + int i2 = r2 instanceof RefImplicitConstructor ? 0 : r2.getElement().getTextOffset(); + if (i1 < i2) return 1; + if (i1 == i2) return 0; + return -1; + } + }); + + return selection.toArray(new RefElement[selection.size()]); + } + + private void doApplyFix(final Project project, + final DescriptorProviderInspection tool, + final ProblemDescriptor[] descriptors) { + final Set readOnlyFiles = new com.intellij.util.containers.HashSet(); + for (int i = 0; i < descriptors.length; i++) { + ProblemDescriptor descriptor = descriptors[i]; + final PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement != null && !psiElement.isWritable()) { + readOnlyFiles.add(psiElement.getContainingFile().getVirtualFile()); + } + } + + if (readOnlyFiles.isEmpty()) { + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + CommandProcessor.getInstance().markCurrentCommandAsComplex(project); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (int i = 0; i < descriptors.length; i++) { + ProblemDescriptor descriptor = descriptors[i]; + if (descriptor.getPsiElement() != null && descriptor.getFix() != null) { + descriptor.getFix().applyFix(project, descriptor); + tool.ignoreProblem(descriptor); + } + } + } + }); + } + }, getTemplatePresentation().getText(), null); + ((InspectionManagerEx)InspectionManager.getInstance(project)).refreshViews(); + } + else { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()])); + } + } + + public void doApplyFix(final RefElement[] refElements) { + Set readOnlyFiles = getReadOnlyFiles(refElements); + if (readOnlyFiles.isEmpty()) { + if (refElements.length > 0) { + final Project project = refElements[0].getRefManager().getProject(); + final boolean[] refreshNeeded = new boolean[1]; + + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + CommandProcessor.getInstance().markCurrentCommandAsComplex(project); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + refreshNeeded[0] = applyFix(refElements); + } + }); + } + }, getTemplatePresentation().getText(), null); + + if (refreshNeeded[0]) { + ((InspectionManagerEx)InspectionManager.getInstance(project)).refreshViews(); + } + } + } + else { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()])); + } + } + + private Set getReadOnlyFiles(final RefElement[] refElements) { + Set readOnlyFiles = new com.intellij.util.containers.HashSet(); + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiElement psiElement = refElement.getElement(); + if (psiElement == null) continue; + if (!psiElement.isWritable()) readOnlyFiles.add(psiElement.getContainingFile().getVirtualFile()); + } + return readOnlyFiles; + } + + /** + * @return true if immediate UI update needed. + */ + protected abstract boolean applyFix(RefElement[] refElements); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixWrapper.java new file mode 100644 index 00000000000..d9e76c1725b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/QuickFixWrapper.java @@ -0,0 +1,43 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; + +/** + * @author max + */ +public class QuickFixWrapper implements IntentionAction { + private ProblemDescriptor myDescriptor; + + public QuickFixWrapper(ProblemDescriptor descriptor) { + myDescriptor = descriptor; + } + + public String getText() { + return getFamilyName(); + } + + public String getFamilyName() { + return myDescriptor.getFix().getName(); + } + + public boolean isAvailable(Project project, Editor editor, PsiFile file) { + PsiElement psiElement = myDescriptor.getPsiElement(); + return psiElement != null && psiElement.isValid(); + } + + public void invoke(Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!CodeInsightUtil.prepareFileForWrite(file)) return; + myDescriptor.getFix().applyFix(project, myDescriptor); + } + + public boolean startInWriteAction() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/StandardInspectionToolsProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/StandardInspectionToolsProvider.java new file mode 100644 index 00000000000..7da428c6cef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/StandardInspectionToolsProvider.java @@ -0,0 +1,50 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.InspectionToolProvider; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.codeInsight.i18n.StringI18nInspection; + +/** + * @author max + */ +public class StandardInspectionToolsProvider implements InspectionToolProvider, ApplicationComponent { + public String getComponentName() { + return "StandardInspectionToolsProvider"; + } + + public void initComponent() { } + + public void disposeComponent() { + + } + + public Class[] getInspectionClasses() { + return new Class[] { + com.intellij.codeInspection.deadCode.DeadCodeInspection.class, + com.intellij.codeInspection.visibility.VisibilityInspection.class, + com.intellij.codeInspection.canBeStatic.CanBeStaticInspection.class, + com.intellij.codeInspection.canBeFinal.CanBeFinalInspection.class, + com.intellij.codeInspection.unusedParameters.UnusedParametersInspection.class, + com.intellij.codeInspection.sameParameterValue.SameParameterValueInspection.class, + com.intellij.codeInspection.unusedReturnValue.UnusedReturnValue.class, + com.intellij.codeInspection.sameReturnValue.SameReturnValueInspection.class, + com.intellij.codeInspection.emptyMethod.EmptyMethodInspection.class, + com.intellij.codeInspection.unneededThrows.UnneededThrows.class, + + com.intellij.codeInspection.dataFlow.DataFlowInspection.class, + com.intellij.codeInspection.defUse.DefUseInspection.class, + com.intellij.codeInspection.redundantCast.RedundantCastInspection.class, + com.intellij.codeInspection.miscGenerics.RedundantTypeArgsInspection.class, + com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspection.class, + com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal.class, + + com.intellij.codeInspection.javaDoc.JavaDocInspection.class, + com.intellij.codeInspection.deprecation.DeprecationInspection.class, + com.intellij.codeInspection.equalsAndHashcode.EqualsAndHashcode.class, + com.intellij.codeInspection.ejb.EJBInspection.class, + + StringI18nInspection.class, + + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/VisibleTreeState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/VisibleTreeState.java new file mode 100644 index 00000000000..f8afc9ae215 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ex/VisibleTreeState.java @@ -0,0 +1,167 @@ +package com.intellij.codeInspection.ex; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; +import org.jdom.Element; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.*; + +/** + * User: anna + * Date: Dec 18, 2004 + */ +public class VisibleTreeState implements JDOMExternalizable { + + private static final String EXPANDED = "expanded_node"; + private static final String SELECTED = "selected_node"; + private static final String NAME = "name"; + + private HashSet myExpandedNodes = new HashSet(); + private HashSet mySelectedNodes = new HashSet(); + + public VisibleTreeState(VisibleTreeState src) { + myExpandedNodes.addAll(src.myExpandedNodes); + mySelectedNodes.addAll(src.mySelectedNodes); + } + + public VisibleTreeState() { + } + + public void expandNode(String nodeTitle) { + myExpandedNodes.add(nodeTitle); + } + + public void collapseNode(String nodeTitle) { + myExpandedNodes.remove(nodeTitle); + } + + public void restoreVisibleState(Tree tree) { + ArrayList pathsToExpand = new ArrayList(); + ArrayList toSelect = new ArrayList(); + traverseNodes((DefaultMutableTreeNode)tree.getModel().getRoot(), pathsToExpand, toSelect); + TreeUtil.restoreExpandedPaths(tree, pathsToExpand); + if (toSelect.isEmpty()) { + TreeUtil.selectFirstNode(tree); + } + else { + for (Iterator iterator = toSelect.iterator(); iterator.hasNext();) { + TreeUtil.selectPath(tree, iterator.next()); + } + } + } + + private void traverseNodes(final DefaultMutableTreeNode root, List pathsToExpand, List toSelect) { + final Object userObject = root.getUserObject(); + final TreeNode[] rootPath = ((DefaultMutableTreeNode)root).getPath(); + if (userObject instanceof Descriptor) { + final String displayName = ((Descriptor)userObject).getText(); + if (mySelectedNodes.contains(displayName)) { + toSelect.add(new TreePath(rootPath)); + } + if (myExpandedNodes.contains(displayName)) { + pathsToExpand.add(new TreePath(rootPath)); + } + } + else { + if (mySelectedNodes.contains(userObject)) { + toSelect.add(new TreePath(rootPath)); + } + if (myExpandedNodes.contains(userObject)) { + pathsToExpand.add(new TreePath(rootPath)); + } + for (int i = 0; i < root.getChildCount(); i++) { + traverseNodes((DefaultMutableTreeNode)root.getChildAt(i), pathsToExpand, toSelect); + } + } + } + + public void saveVisibleState(Tree tree) { + myExpandedNodes.clear(); + final DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)tree.getModel().getRoot(); + Enumeration expanded = tree.getExpandedDescendants(new TreePath(rootNode.getPath())); + if (expanded != null) { + while (expanded.hasMoreElements()) { + final TreePath treePath = (TreePath)expanded.nextElement(); + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent(); + String expandedNode; + if (node.getUserObject() instanceof Descriptor) { + expandedNode = ((Descriptor)node.getUserObject()).getText(); + } + else { + expandedNode = (String)node.getUserObject(); + } + myExpandedNodes.add(expandedNode); + } + } + mySelectedNodes.clear(); + final TreePath[] selectionPaths = tree.getSelectionPaths(); + for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPaths[i].getLastPathComponent(); + String selectedNode; + if (node.getUserObject() instanceof Descriptor) { + selectedNode = ((Descriptor)node.getUserObject()).getText(); + } + else { + selectedNode = (String)node.getUserObject(); + } + mySelectedNodes.add(selectedNode); + } + } + + + public void readExternal(Element element) throws InvalidDataException { + myExpandedNodes.clear(); + for (Iterator iterator = element.getChildren(EXPANDED).iterator(); iterator.hasNext();) { + myExpandedNodes.add(iterator.next().getAttributeValue(NAME)); + } + mySelectedNodes.clear(); + for (Iterator iterator = element.getChildren(SELECTED).iterator(); iterator.hasNext();) { + mySelectedNodes.add(iterator.next().getAttributeValue(NAME)); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (Iterator iterator = myExpandedNodes.iterator(); iterator.hasNext();) { + final String expandedNode = iterator.next(); + Element exp = new Element(EXPANDED); + exp.setAttribute(NAME, expandedNode); + element.addContent(exp); + } + for (Iterator iterator = mySelectedNodes.iterator(); iterator.hasNext();) { + final String selectedNode = iterator.next(); + Element exp = new Element(SELECTED); + exp.setAttribute(NAME, selectedNode); + element.addContent(exp); + } + } + + public boolean compare(Object object) { + if (!(object instanceof VisibleTreeState)) return false; + final VisibleTreeState that = (VisibleTreeState)object; + if (myExpandedNodes == null && that.myExpandedNodes != null) { + return false; + } + if (myExpandedNodes.size() != that.myExpandedNodes.size()) return false; + for (Iterator iterator = myExpandedNodes.iterator(); iterator.hasNext();) { + if (!that.myExpandedNodes.contains(iterator.next())) { + return false; + } + } + if (mySelectedNodes == null) { + return that.mySelectedNodes == null; + } + if (mySelectedNodes.size() != that.mySelectedNodes.size()) return false; + for (Iterator iterator = mySelectedNodes.iterator(); iterator.hasNext();) { + if (!that.mySelectedNodes.contains(iterator.next())) { + return false; + } + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/ExportToHTMLDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/ExportToHTMLDialog.java new file mode 100644 index 00000000000..13882a72d4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/ExportToHTMLDialog.java @@ -0,0 +1,56 @@ +package com.intellij.codeInspection.export; + +import com.intellij.codeEditor.printing.ExportToHTMLSettings; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.ui.OptionGroup; + +import javax.swing.*; + +// TODO copy-paste result of com.intellij.codeEditor.printing.ExportToHTMLDialog +public class ExportToHTMLDialog extends DialogWrapper{ + private JCheckBox myCbOpenInBrowser; + private final Project myProject; + private TextFieldWithBrowseButton myTargetDirectoryField; + + public ExportToHTMLDialog(Project project) { + super(project, true); + myProject = project; + setOKButtonText("Save"); + setTitle("Export to HTML"); + init(); + } + + protected JComponent createNorthPanel() { + OptionGroup optionGroup = new OptionGroup(); + + myTargetDirectoryField = new TextFieldWithBrowseButton(); + optionGroup.add(com.intellij.codeEditor.printing.ExportToHTMLDialog.assignLabel(myTargetDirectoryField, myProject)); + + return optionGroup.createPanel(); + } + + protected JComponent createCenterPanel() { + OptionGroup optionGroup = new OptionGroup("Options"); + + myCbOpenInBrowser = new JCheckBox("Open generated HTML in browser"); + myCbOpenInBrowser.setMnemonic('b'); + optionGroup.add(myCbOpenInBrowser); + + return optionGroup.createPanel(); + } + + public void reset() { + ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myProject); + myCbOpenInBrowser.setSelected(exportToHTMLSettings.OPEN_IN_BROWSER); + myTargetDirectoryField.setText(exportToHTMLSettings.OUTPUT_DIRECTORY); + } + + public void apply() { + ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myProject); + + exportToHTMLSettings.OPEN_IN_BROWSER = myCbOpenInBrowser.isSelected(); + exportToHTMLSettings.OUTPUT_DIRECTORY = myTargetDirectoryField.getText(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/HTMLExportFrameMaker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/HTMLExportFrameMaker.java new file mode 100644 index 00000000000..93117ccf6ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/export/HTMLExportFrameMaker.java @@ -0,0 +1,67 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 21, 2002 + * Time: 1:16:43 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.export; + +import com.intellij.codeInspection.ex.InspectionTool; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; + +public class HTMLExportFrameMaker { + private final String myRootFolder; + private Project myProject; + private final ArrayList myInspectionTools; + + public HTMLExportFrameMaker(String rootFolder, Project project) { + myRootFolder = rootFolder; + myProject = project; + myInspectionTools = new ArrayList(); + } + + public void start() { + StringBuffer buf = new StringBuffer(); + buf.append(""); + HTMLExporter.writeFile(myRootFolder, "empty.html", buf, myProject); + } + + public void done() { + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < myInspectionTools.size(); i++) { + InspectionTool tool = (InspectionTool) myInspectionTools.get(i); + buf.append(""); + buf.append(tool.getDisplayName()); + buf.append("
    "); + } + + HTMLExporter.writeFile(myRootFolder, "index.html", buf, myProject); + } + + public void startInspection(InspectionTool tool) { + myInspectionTools.add(tool); + StringBuffer buf = new StringBuffer(); + buf.append("IntelliJ Idea Code Inspection results"); + buf.append(""); + buf.append(""); + buf.append(""); + buf.append(""); + buf.append(""); + buf.append("Inspections "); + myComposer.appendElementReference(buf, element, "Open source", "_blank"); + buf.append("
    "); + } + + public static void writeFile(String folder, String fileName, StringBuffer buf, Project project) { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + String fullPath = folder + File.separator + fileName; + + if (indicator != null) { + ProgressManager.getInstance().checkCanceled(); + indicator.setText("Generating HTML:" + fullPath); + } + + try { + File myFolder = new File(folder); + myFolder.mkdirs(); + FileWriter myWriter = new FileWriter(fullPath); + myWriter.write(buf.toString().toCharArray()); + myWriter.close(); + } catch (IOException e) { + Messages.showMessageDialog( + project, + "Error writing to " + fullPath, + "Inspection Results Export", + Messages.getErrorIcon() + ); + throw new ProcessCanceledException(); + } + } + + public String getURL(RefElement element) { + myGeneratedReferences.add(element); + return fileNameForElement(element); + } + + private String fileNameForElement(RefElement element) { + String fileName = (String) myElementToFilenameMap.get(element); + + if (fileName == null) { + fileName = "e" + Integer.toString(++myFileCounter) + ".html"; + myElementToFilenameMap.put(element, fileName); + } + + return fileName; + } + + private Set getReferencesWithoutPages() { + HashSet result = new HashSet(); + for (Iterator iterator = myGeneratedReferences.iterator(); iterator.hasNext();) { + RefElement refElement = (RefElement) iterator.next(); + if (!myGeneratedPages.contains(refElement)) { + result.add(refElement); + } + } + + return result; + } + + public void generateReferencedPages() { + Set extras = getReferencesWithoutPages(); + while (extras.size() > 0) { + for (Iterator iterator = extras.iterator(); iterator.hasNext();) { + RefElement refElement = (RefElement) iterator.next(); + createPage(refElement); + } + extras = getReferencesWithoutPages(); + } + } + + public String getRootFolder() { + return myRootFolder; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java new file mode 100644 index 00000000000..858041ca464 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -0,0 +1,279 @@ +package com.intellij.codeInspection.localCanBeFinal; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.BaseLocalInspectionTool; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.controlFlow.ControlFlow; +import com.intellij.psi.controlFlow.ControlFlowAnalyzer; +import com.intellij.psi.controlFlow.ControlFlowPolicy; +import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +/** + * @author max + */ +public class LocalCanBeFinal extends BaseLocalInspectionTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal"); + + public boolean REPORT_VARIABLES = true; + public boolean REPORT_PARAMETERS = true; + + private LocalQuickFix myQuickFix; + + public LocalCanBeFinal() { + myQuickFix = new AcceptSuggested(); + } + + public ProblemDescriptor[] checkMethod(PsiMethod method, InspectionManager manager, boolean isOnTheFly) { + return checkCodeBlock(method.getBody(), manager, isOnTheFly); + } + + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + List allProblems = null; + final PsiClassInitializer[] initializers = aClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + final ProblemDescriptor[] problems = checkCodeBlock(initializers[i].getBody(), manager, isOnTheFly); + if (problems != null) { + if (allProblems == null) { + allProblems = new ArrayList(1); + } + allProblems.addAll(Arrays.asList(problems)); + } + } + return allProblems == null ? null : allProblems.toArray(new ProblemDescriptor[allProblems.size()]); + } + + public ProblemDescriptor[] checkCodeBlock(final PsiCodeBlock body, InspectionManager manager, boolean isOnTheFly) { + if (body == null) return null; + final ControlFlow flow; + try { + flow = new ControlFlowAnalyzer(body, new ControlFlowPolicy() { + public PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + if (refExpr.isQualified()) return null; + + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) { + if (!isVariableDeclaredInMethod((PsiVariable)refElement)) return null; + return (PsiVariable)refElement; + } + + return null; + } + + public boolean isParameterAccepted(PsiParameter psiParameter) { + return isVariableDeclaredInMethod(psiParameter); + } + + public boolean isLocalVariableAccepted(PsiLocalVariable psiVariable) { + return isVariableDeclaredInMethod(psiVariable); + } + + private boolean isVariableDeclaredInMethod(PsiVariable psiVariable) { + return PsiTreeUtil.getParentOfType(psiVariable, PsiClass.class) + == PsiTreeUtil.getParentOfType(body, PsiClass.class); + } + }).buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return null; + } + + int start = flow.getStartOffset(body); + int end = flow.getEndOffset(body); + + PsiVariable[] writtenVariables = ControlFlowUtil.getWrittenVariables(flow, start, end); + final HashSet ssaVarsSet = new HashSet(); + body.accept(new PsiRecursiveElementVisitor() { + public void visitCodeBlock(PsiCodeBlock block) { + super.visitCodeBlock(block); + PsiElement anchor = block; + if (block.getParent() instanceof PsiSwitchStatement) { + anchor = block.getParent(); + } + int from = flow.getStartOffset(anchor); + int end = flow.getEndOffset(anchor); + PsiVariable[] ssa = ControlFlowUtil.getSSAVariables(flow, from, end, true); + HashSet declared = getDeclaredVariables(block); + for (int i = 0; i < ssa.length; i++) { + PsiVariable psiVariable = ssa[i]; + if (declared.contains(psiVariable)) { + ssaVarsSet.add(psiVariable); + } + } + } + + private HashSet getDeclaredVariables(PsiCodeBlock block) { + final HashSet result = new HashSet(); + PsiElement[] children = block.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + child.accept(new PsiElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + PsiElement[] declaredElements = statement.getDeclaredElements(); + for (int i = 0; i < declaredElements.length; i++) { + PsiElement declaredElement = declaredElements[i]; + if (declaredElement instanceof PsiVariable) result.add(declaredElement); + } + } + }); + } + + return result; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + }); + + ArrayList result = new ArrayList(ssaVarsSet); + + if (body.getParent() instanceof PsiMethod) { + PsiMethod method = (PsiMethod)body.getParent(); + PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (!result.contains(parameter)) result.add(parameter); + } + } + + PsiVariable[] psiVariables = result.toArray(new PsiVariable[result.size()]); + for (int i = 0; i < psiVariables.length; i++) { + PsiVariable psiVariable = psiVariables[i]; + if (!isReportParameters() && psiVariable instanceof PsiParameter || + !isReportVariables() && psiVariable instanceof PsiLocalVariable || + psiVariable.hasModifierProperty(PsiModifier.FINAL)) { + result.remove(psiVariable); + } + + if (psiVariable instanceof PsiLocalVariable) { + PsiDeclarationStatement decl = (PsiDeclarationStatement)psiVariable.getParent(); + if (decl != null && decl.getParent() instanceof PsiForStatement) { + result.remove(psiVariable); + } + } + } + + for (int i = 0; i < writtenVariables.length; i++) { + PsiVariable writtenVariable = writtenVariables[i]; + if (writtenVariable instanceof PsiParameter) { + result.remove(writtenVariable); + } + } + + if (result.size() == 0) return null; + ProblemDescriptor[] problems = new ProblemDescriptor[result.size()]; + for (int i = 0; i < problems.length; i++) { + PsiVariable problemVariable = result.get(i); + problems[i] = manager. + createProblemDescriptor(problemVariable.getNameIdentifier(), + (problemVariable instanceof PsiParameter + ? "Parameter" + : "Variable") + " #ref can have final modifier.", + myQuickFix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + + return problems; + } + + public String getDisplayName() { + return "Local variable or parameter can be final"; + } + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getShortName() { + return "LocalCanBeFinal"; + } + + private static class AcceptSuggested implements LocalQuickFix { + public String getName() { + return "Accept Suggested Final Modifier"; + } + + public void applyFix(Project project, ProblemDescriptor problem) { + PsiElement nameIdentifier = problem.getPsiElement(); + if (nameIdentifier == null) return; + PsiVariable psiVariable = (PsiVariable)nameIdentifier.getParent(); + if (psiVariable == null) return; + try { + psiVariable.normalizeDeclaration(); + psiVariable.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + public JComponent createOptionsPanel() { + return new OptionsPanel(); + } + + private boolean isReportVariables() { + return REPORT_VARIABLES; + } + + private boolean isReportParameters() { + return REPORT_PARAMETERS; + } + + private class OptionsPanel extends JPanel { + private final JCheckBox myReportVariablesCheckbox; + private final JCheckBox myReportParametersCheckbox; + + private OptionsPanel() { + super(new GridBagLayout()); + + GridBagConstraints gc = new GridBagConstraints(); + gc.weighty = 0; + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + gc.anchor = GridBagConstraints.NORTHWEST; + + + myReportVariablesCheckbox = new JCheckBox("Report local variables"); + myReportVariablesCheckbox.setSelected(REPORT_VARIABLES); + myReportVariablesCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myReportVariablesCheckbox.isSelected(); + REPORT_VARIABLES = selected; + } + }); + gc.gridy = 0; + add(myReportVariablesCheckbox, gc); + + myReportParametersCheckbox = new JCheckBox("Report method parameters"); + myReportParametersCheckbox.setSelected(REPORT_PARAMETERS); + myReportParametersCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myReportParametersCheckbox.isSelected(); + REPORT_PARAMETERS = selected; + } + }); + + gc.weighty = 1; + gc.gridy++; + add(myReportParametersCheckbox, gc); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/GenericsInspectionToolBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/GenericsInspectionToolBase.java new file mode 100644 index 00000000000..c05a675896b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/GenericsInspectionToolBase.java @@ -0,0 +1,47 @@ +package com.intellij.codeInspection.miscGenerics; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ex.BaseLocalInspectionTool; +import com.intellij.psi.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author ven + */ +abstract class GenericsInspectionToolBase extends BaseLocalInspectionTool { + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + final PsiClassInitializer[] initializers = aClass.getInitializers(); + if (initializers == null || initializers.length == 0) return null; + List descriptors = new ArrayList(); + for (int i = 0; i < initializers.length; i++) { + final ProblemDescriptor[] localDescriptions = getDescriptions(initializers[i], manager); + if (localDescriptions != null) { + descriptors.addAll(Arrays.asList(localDescriptions)); + } + } + if (descriptors.isEmpty()) return null; + return descriptors.toArray(new ProblemDescriptor[descriptors.size()]); + } + + public ProblemDescriptor[] checkField(PsiField field, InspectionManager manager, boolean isOnTheFly) { + final PsiExpression initializer = field.getInitializer(); + if (initializer != null) { + return getDescriptions(initializer, manager); + } + return null; + } + + public ProblemDescriptor[] checkMethod(PsiMethod psiMethod, InspectionManager manager, boolean isOnTheFly) { + final PsiCodeBlock body = psiMethod.getBody(); + if (body != null) { + return getDescriptions(body, manager); + } + return null; + } + + public abstract ProblemDescriptor[] getDescriptions(PsiElement place, InspectionManager manager); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java new file mode 100644 index 00000000000..669f324c759 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/RedundantTypeArgsInspection.java @@ -0,0 +1,122 @@ +package com.intellij.codeInspection.miscGenerics; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author ven + */ +public class RedundantTypeArgsInspection extends GenericsInspectionToolBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.miscGenerics.RedundantTypeArgsInspection"); + + public RedundantTypeArgsInspection() { + myQuickFixAction = new MyQuickFixAction(); + } + + private LocalQuickFix myQuickFixAction; + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getDisplayName() { + return "Redundant type arguments"; + } + + public String getShortName() { + return "RedundantTypeArguments"; + } + + + + public ProblemDescriptor[] checkMethod(PsiMethod psiMethod, InspectionManager manager, boolean isOnTheFly) { + final PsiCodeBlock body = psiMethod.getBody(); + if (body != null) { + return getDescriptions(body, manager); + } + return null; + } + + public ProblemDescriptor[] getDescriptions(PsiElement place, final InspectionManager inspectionManager) { + final List problems = new ArrayList(); + place.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) {} + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + final PsiType[] typeArguments = expression.getTypeArguments(); + if (typeArguments.length > 0) { + checkCallExpression(expression.getMethodExpression(), typeArguments, expression, inspectionManager, problems); + } + } + + public void visitNewExpression(PsiNewExpression expression) { + final PsiType[] typeArguments = expression.getTypeArguments(); + if (typeArguments.length > 0) { + final PsiJavaCodeReferenceElement classReference = expression.getClassReference(); + if (classReference != null) { + checkCallExpression(classReference, typeArguments, expression, inspectionManager, problems); + } + } + } + + private void checkCallExpression(final PsiJavaCodeReferenceElement reference, + final PsiType[] typeArguments, + PsiCallExpression expression, + final InspectionManager inspectionManager, final List problems) { + + final ResolveResult resolveResult = reference.advancedResolve(false); + + if (resolveResult.getElement() instanceof PsiMethod && resolveResult.isValidResult()) { + PsiMethod method = (PsiMethod)resolveResult.getElement(); + final PsiTypeParameter[] typeParameters = method.getTypeParameterList().getTypeParameters(); + if (typeParameters.length == typeArguments.length) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + PsiResolveHelper resolveHelper = expression.getManager().getResolveHelper(); + for (int i = 0; i < typeParameters.length; i++) { + PsiTypeParameter typeParameter = typeParameters[i]; + final PsiType inferedType = resolveHelper.inferTypeForMethodTypeParameter(typeParameter, parameters, + expression.getArgumentList().getExpressions(), + resolveResult.getSubstitutor(), expression); + if (!typeArguments[i].equals(inferedType)) return; + } + + final ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(expression.getTypeArgumentList(), + "Explicit type arguments can be inferred", + myQuickFixAction, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + problems.add(descriptor); + } + } + } + + }); + + if (problems.isEmpty()) return null; + return problems.toArray(new ProblemDescriptor[problems.size()]); + } + + private class MyQuickFixAction implements LocalQuickFix { + public String getName() { + return "Remove explicit type arguments"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + final PsiReferenceParameterList typeArgumentList = (PsiReferenceParameterList)descriptor.getPsiElement(); + try { + typeArgumentList.delete(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/SuspiciousCollectionsMethodCallsInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/SuspiciousCollectionsMethodCallsInspection.java new file mode 100644 index 00000000000..90c422796e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/miscGenerics/SuspiciousCollectionsMethodCallsInspection.java @@ -0,0 +1,157 @@ +package com.intellij.codeInspection.miscGenerics; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; +import java.text.MessageFormat; + +/** + * @author ven + */ +public class SuspiciousCollectionsMethodCallsInspection extends GenericsInspectionToolBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspection"); + + private List myMethods = new ArrayList(); + private List myIndices = new ArrayList(); + + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + try { + try { + setupPatternMethods(aClass.getManager(), aClass.getResolveScope()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + + return super.checkClass(aClass, manager, isOnTheFly); + } + finally { + myIndices.clear(); + myMethods.clear(); + } + } + + public ProblemDescriptor[] checkMethod(PsiMethod method, InspectionManager manager, boolean isOnTheFly) { + try { + try { + setupPatternMethods(method.getManager(), method.getResolveScope()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + + return super.checkMethod(method, manager, isOnTheFly); + } + finally { + myIndices.clear(); + myMethods.clear(); + } + } + + private void setupPatternMethods(PsiManager manager, GlobalSearchScope searchScope) throws IncorrectOperationException { + final PsiElementFactory elementFactory = manager.getElementFactory(); + final PsiClass collectionClass = manager.findClass("java.util.Collection", searchScope); + if (collectionClass != null) { + addMethod(collectionClass.findMethodBySignature(elementFactory.createMethodFromText("boolean remove(Object o);", null), false), 0); + addMethod(collectionClass.findMethodBySignature(elementFactory.createMethodFromText("boolean contains(Object o);", null), false), 0); + } + + final PsiClass listClass = manager.findClass("java.util.List", searchScope); + if (listClass != null) { + addMethod(listClass.findMethodBySignature(elementFactory.createMethodFromText("boolean indexOf(Object o);", null), false), 0); + addMethod(listClass.findMethodBySignature(elementFactory.createMethodFromText("boolean lastIndexOf(Object o);", null), false), 0); + } + + final PsiClass mapClass = manager.findClass("java.util.Map", searchScope); + if (mapClass != null) { + addMethod(mapClass.findMethodBySignature(elementFactory.createMethodFromText("boolean remove(Object o);", null), false), 0); + addMethod(mapClass.findMethodBySignature(elementFactory.createMethodFromText("boolean get(Object o);", null), false), 0); + addMethod(mapClass.findMethodBySignature(elementFactory.createMethodFromText("boolean containsKey(Object o);", null), false), 0); + addMethod(mapClass.findMethodBySignature(elementFactory.createMethodFromText("boolean containsValue(Object o);", null), false), 1); + } + + myMethods.remove(null); + } + + private void addMethod(final PsiMethod patternMethod, int typeParamIndex) { + if (patternMethod != null) { + myMethods.add(patternMethod); + myIndices.add(new Integer(typeParamIndex)); + } + } + + public ProblemDescriptor[] getDescriptions(PsiElement place, final InspectionManager manager) { + final List problems = new ArrayList(); + place.accept(new PsiRecursiveElementVisitor() { + public void visitMethodCallExpression(PsiMethodCallExpression methodCall) { + final PsiExpression[] args = methodCall.getArgumentList().getExpressions(); + if (args.length != 1 || !(args[0].getType() instanceof PsiClassType)) return; + + final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); + Iterator indicesIterator = myIndices.iterator(); + for (Iterator methodsIterator = myMethods.iterator(); methodsIterator.hasNext();) { + PsiMethod patternMethod = methodsIterator.next(); + Integer index = indicesIterator.next(); + if (!patternMethod.getName().equals(methodExpression.getReferenceName())) continue; + final ResolveResult resolveResult = methodExpression.advancedResolve(false); + final PsiMethod psiMethod = (PsiMethod)resolveResult.getElement(); + if (psiMethod != null && isInheritorOrSelf(psiMethod, patternMethod)) { + PsiTypeParameter[] typeParameters = psiMethod.getContainingClass().getTypeParameters(); + int i = index.intValue(); + if (typeParameters.length <= i) return; + final PsiTypeParameter typeParameter = typeParameters[i]; + PsiType typeParamMapping = resolveResult.getSubstitutor().substitute(typeParameter); + if (typeParamMapping != null) { + if (!typeParamMapping.isConvertibleFrom(args[0].getType())) { + final String message = MessageFormat.format("For no non-null object of type ''{0}'' can ''{1}'' return 'true'", new Object[]{ + PsiFormatUtil.formatType(args[0].getType(), 0, PsiSubstitutor.EMPTY), + PsiFormatUtil.formatMethod(psiMethod, resolveResult.getSubstitutor(), PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_CONTAINING_CLASS, + PsiFormatUtil.SHOW_TYPE)}); + problems.add(manager.createProblemDescriptor(args[0], message, + null, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + return; + } + } + } + } + } + + private boolean isInheritorOrSelf(PsiMethod inheritorCandidate, PsiMethod base) { + PsiClass aClass = inheritorCandidate.getContainingClass(); + PsiClass bClass = base.getContainingClass(); + if (aClass == null || bClass == null) return false; + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(bClass, aClass, PsiSubstitutor.EMPTY); + if (substitutor == null) return false; + return MethodSignatureUtil.findMethodBySignature(bClass, inheritorCandidate.getSignature(substitutor), false) == base; + } + }); + + if (problems.isEmpty()) return null; + return problems.toArray(new ProblemDescriptor[problems.size()]); + } + + public String getDisplayName() { + return "Suspicious collections method calls"; + } + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getShortName() { + return "SuspiciousMethodCalls"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java new file mode 100644 index 00000000000..3ea914f688a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java @@ -0,0 +1,126 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 24, 2001 + * Time: 2:46:32 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.redundantCast; + +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.BaseLocalInspectionTool; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RedundantCastInspection extends BaseLocalInspectionTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.redundantCast.RedundantCastInspection"); + private LocalQuickFix myQuickFixAction; + public static final String DISPLAY_NAME = "Redundant type cast"; + public static final String SHORT_NAME = "RedundantCast"; + + public RedundantCastInspection() { + myQuickFixAction = new AcceptSuggested(); + } + + public ProblemDescriptor[] checkClass(PsiClass aClass, InspectionManager manager, boolean isOnTheFly) { + final PsiClassInitializer[] initializers = aClass.getInitializers(); + if (initializers == null || initializers.length == 0) return null; + List descriptors = new ArrayList(); + for (int i = 0; i < initializers.length; i++) { + final ProblemDescriptor[] localDescriptions = getDescriptions(initializers[i], manager); + if (localDescriptions != null) { + descriptors.addAll(Arrays.asList(localDescriptions)); + } + } + if (descriptors.isEmpty()) return null; + return descriptors.toArray(new ProblemDescriptor[descriptors.size()]); + } + + public ProblemDescriptor[] checkField(PsiField field, InspectionManager manager, boolean isOnTheFly) { + final PsiExpression initializer = field.getInitializer(); + if (initializer != null) { + return getDescriptions(initializer, manager); + } + return null; + } + + public ProblemDescriptor[] checkMethod(PsiMethod psiMethod, InspectionManager manager, boolean isOnTheFly) { + return getDescriptions(psiMethod, manager); + } + + private ProblemDescriptor[] getDescriptions(PsiElement where, InspectionManager manager) { + List redundantCasts = RedundantCastUtil.getRedundantCasts(where); + if (redundantCasts.isEmpty()) return null; + ProblemDescriptor[] descriptions = new ProblemDescriptor[redundantCasts.size()]; + for (int i = 0; i < redundantCasts.size(); i++) { + descriptions[i] = createDescription(redundantCasts.get(i), manager); + } + return descriptions; + } + + private ProblemDescriptor createDescription(PsiTypeCastExpression cast, InspectionManager manager) { + return manager.createProblemDescriptor(cast.getCastType(), "Casting " + cast.getOperand().getText() + " to " + + "#ref #loc is redundant", myQuickFixAction, + ProblemHighlightType.LIKE_UNUSED_SYMBOL); + } + + + private class AcceptSuggested implements LocalQuickFix { + public String getName() { + return "Remove Redundant Cast(s)"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + PsiElement castTypeElement = descriptor.getPsiElement(); + PsiTypeCastExpression cast = (PsiTypeCastExpression)castTypeElement.getParent(); + removeCast(cast); + } + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Local Code Analysis"; + } + + public String getShortName() { + return SHORT_NAME; + } + + private void removeCast(PsiTypeCastExpression castExpression) { + if (castExpression == null) return; + PsiExpression operand = castExpression.getOperand(); + if (operand == null) return; + if (operand instanceof PsiParenthesizedExpression) { + final PsiParenthesizedExpression parExpr = (PsiParenthesizedExpression)operand; + operand = parExpr.getExpression(); + } + + PsiElement toBeReplaced = castExpression; + + PsiElement parent = castExpression.getParent(); + while (parent instanceof PsiParenthesizedExpression) { + toBeReplaced = parent; + parent = parent.getParent(); + } + + try { + toBeReplaced.replace(operand); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastUtil.java new file mode 100644 index 00000000000..cc4033ffa33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/redundantCast/RedundantCastUtil.java @@ -0,0 +1,328 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Mar 24, 2002 + * Time: 6:08:14 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.redundantCast; + +import com.intellij.psi.*; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RedundantCastUtil { + public static List getRedundantCasts(PsiElement where) { + final ArrayList result = new ArrayList(); + PsiElementProcessor processor = new PsiBaseElementProcessor() { + public boolean execute(PsiTypeCastExpression element) { + result.add(element); + return true; + } + }; + where.accept(new MyVisitor(processor)); + return result; + } + + private static class MyVisitor extends PsiRecursiveElementVisitor { + private final PsiElementProcessor myProcessor; + private Set myFoundCasts = new HashSet(); + + public MyVisitor(PsiElementProcessor processor) { + myProcessor = processor; + } + + private void addToResults(PsiTypeCastExpression typeCast){ + if (!isTypeCastSemantical(typeCast)) { + if (myFoundCasts.add(typeCast)) { + myProcessor.execute(typeCast); + } + } + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitConditionalExpression(PsiConditionalExpression expression) { + // Do not go inside conditional expression because branches are required to be exactly the same type, not assignable. + } + + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + processPossibleTypeCast(expression.getRExpression(), expression.getLExpression().getType()); + super.visitAssignmentExpression(expression); + } + + public void visitVariable(PsiVariable variable) { + processPossibleTypeCast(variable.getInitializer(), variable.getType()); + super.visitVariable(variable); + } + + public void visitBinaryExpression(PsiBinaryExpression expression) { + PsiExpression rExpr = deParenthesize(expression.getROperand()); + PsiExpression lExpr = deParenthesize(expression.getLOperand()); + + if (rExpr != null && lExpr != null) { + if (lExpr instanceof PsiTypeCastExpression) { + PsiTypeCastExpression typeCast = (PsiTypeCastExpression)lExpr; + PsiExpression operand = typeCast.getOperand(); + if (operand != null && operand.getType() != null) { + if (expression.getOperationSign().getTokenType() != JavaTokenType.PLUS || + !typeCast.getCastType().getType().equalsToText("java.lang.String") || + operand.getType().equalsToText("java.lang.String")) { + addToResults(typeCast); + } + } + } + if (rExpr instanceof PsiTypeCastExpression) { + addToResults((PsiTypeCastExpression)rExpr); + } + } + super.visitBinaryExpression(expression); + } + + private void processPossibleTypeCast(PsiExpression rExpr, PsiType lType) { + rExpr = deParenthesize(rExpr); + if (rExpr instanceof PsiTypeCastExpression) { + PsiExpression castOperand = ((PsiTypeCastExpression)rExpr).getOperand(); + if (castOperand != null) { + PsiType operandType = castOperand.getType(); + if (operandType != null) { + if (lType != null && lType.isAssignableFrom(operandType)) { + addToResults((PsiTypeCastExpression)rExpr); + } + } + } + } + } + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + processCall(expression); + + checkForVirtual(expression); + } + + private void checkForVirtual(PsiMethodCallExpression methodCall) { + PsiReferenceExpression methodExpr = methodCall.getMethodExpression(); + PsiExpression qualifier = methodExpr.getQualifierExpression(); + try { + if (!(qualifier instanceof PsiParenthesizedExpression)) return; + PsiExpression operand = ((PsiParenthesizedExpression)qualifier).getExpression(); + if (!(operand instanceof PsiTypeCastExpression)) return; + PsiTypeCastExpression typeCast = (PsiTypeCastExpression)operand; + PsiExpression castOperand = typeCast.getOperand(); + if (castOperand == null) return; + + PsiType type = castOperand.getType(); + if (type == null) return; + if (type instanceof PsiPrimitiveType) return; + + final ResolveResult resolveResult = methodExpr.advancedResolve(false); + PsiMethod targetMethod = (PsiMethod)resolveResult.getElement(); + if (targetMethod == null) return; + if (targetMethod.hasModifierProperty(PsiModifier.STATIC)) return; + + try { + PsiManager manager = methodExpr.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + + PsiMethodCallExpression newCall = (PsiMethodCallExpression)factory.createExpressionFromText(methodCall.getText(), methodCall); + PsiExpression newQualifier = newCall.getMethodExpression().getQualifierExpression(); + PsiExpression newOperand = ((PsiTypeCastExpression)((PsiParenthesizedExpression)newQualifier).getExpression()).getOperand(); + newQualifier.replace(newOperand); + + final ResolveResult newResult = newCall.getMethodExpression().advancedResolve(false); + if (!newResult.isValidResult()) return; + final PsiMethod newTargetMethod = (PsiMethod)newResult.getElement(); + final PsiType newReturnType = newResult.getSubstitutor().substitute(newTargetMethod.getReturnType()); + final PsiType oldReturnType = resolveResult.getSubstitutor().substitute(targetMethod.getReturnType()); + if (newReturnType.equals(oldReturnType)) { + if (newTargetMethod.equals(targetMethod)) { + addToResults(typeCast); + } else if (newTargetMethod.getSignature(newResult.getSubstitutor()).equals(targetMethod.getSignature(resolveResult.getSubstitutor())) && + !(newTargetMethod.isDeprecated() && !targetMethod.isDeprecated())) { // see SCR11555, SCR14559 + addToResults(typeCast); + } + } + qualifier = ((PsiTypeCastExpression) ((PsiParenthesizedExpression) qualifier).getExpression()).getOperand(); + } + catch (IncorrectOperationException e) { + return; + } + } finally { + if (qualifier != null) { + qualifier.accept(this); + } + } + } + + public void visitNewExpression(PsiNewExpression expression) { + processCall(expression); + super.visitNewExpression(expression); + } + + private void processCall(PsiCallExpression expression){ + PsiMethod oldMethod = null; + PsiParameter[] methodParms = null; + boolean[] typeCastCandidates = null; + boolean hasCandidate = false; + + + + PsiExpressionList argumentList = expression.getArgumentList(); + if (argumentList == null) return; + PsiExpression[] args = argumentList.getExpressions(); + for (int i = 0; i < args.length; i++) { + PsiExpression arg = args[i]; + arg = deParenthesize(arg); + if (arg instanceof PsiTypeCastExpression) { + if (oldMethod == null){ + oldMethod = expression.resolveMethod(); + if (oldMethod == null) return; + methodParms = oldMethod.getParameterList().getParameters(); + if (methodParms.length == 0 || methodParms.length > args.length) return; + typeCastCandidates = new boolean[args.length]; + } + + PsiExpression castOperand = ((PsiTypeCastExpression)arg).getOperand(); + if (castOperand == null) return; + PsiType operandType = castOperand.getType(); + if (operandType == null) return; + PsiParameter methodParm = methodParms[Math.min(i, methodParms.length - 1)]; + if (!methodParm.getType().isAssignableFrom(operandType)) continue; + + //Check explicit cast for varargs parameter, see SCR 37199 + if (args.length == methodParms.length) { + if (PsiType.NULL.equals(operandType) && methodParm.isVarArgs()) continue; + } + + typeCastCandidates[i] = true; + hasCandidate = true; + } + } + + if (hasCandidate) { + PsiManager manager = expression.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + + ResolveResult newResult; + + try { + PsiCallExpression newCall = (PsiCallExpression)factory.createExpressionFromText(expression.getText(), expression); + PsiExpression[] newArgs = newCall.getArgumentList().getExpressions(); + for (int i = newArgs.length - 1; i >= 0; i--) { + if (typeCastCandidates[i]){ + PsiTypeCastExpression castExpression = (PsiTypeCastExpression)deParenthesize(newArgs[i]); + PsiExpression castOperand = castExpression.getOperand(); + if (castOperand == null) return; + castExpression.replace(castOperand); + } + } + + newResult = newCall.resolveMethodGenerics(); + } + catch (IncorrectOperationException e) { + return; + } + + if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult()) { + for(int i = 0; i < args.length; i++){ + PsiExpression arg = deParenthesize(args[i]); + if (typeCastCandidates[i]){ + addToResults((PsiTypeCastExpression)arg); + } + } + } + } + + for (int i = 0; i < args.length; i++) { + PsiExpression arg = args[i]; + if (arg instanceof PsiTypeCastExpression){ + PsiExpression castOperand = ((PsiTypeCastExpression)arg).getOperand(); + castOperand.accept(this); + } + else{ + arg.accept(this); + } + } + } + + private PsiExpression deParenthesize(PsiExpression arg) { + while (arg instanceof PsiParenthesizedExpression) arg = ((PsiParenthesizedExpression) arg).getExpression(); + return arg; + } + + public void visitTypeCastExpression(PsiTypeCastExpression typeCast) { + if (!myFoundCasts.contains(typeCast)){ + PsiExpression operand = typeCast.getOperand(); + if (operand == null) return; + + PsiElement expr = deParenthesize(operand); + + if (expr instanceof PsiTypeCastExpression){ + PsiType castType = ((PsiTypeCastExpression)expr).getCastType().getType(); + if (!(castType instanceof PsiPrimitiveType)){ + addToResults((PsiTypeCastExpression)expr); + } + } else { + processAlreadyHasTypeCast(typeCast); + } + } + + super.visitTypeCastExpression(typeCast); + } + + private void processAlreadyHasTypeCast(PsiTypeCastExpression typeCast){ + PsiElement parent = typeCast.getParent(); + while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent(); + if (parent instanceof PsiExpressionList) return; // do not replace in arg lists - should be handled by parent + + if (isTypeCastSemantical(typeCast)) return; + + PsiType toType = typeCast.getCastType().getType(); + PsiType fromType = typeCast.getOperand().getType(); + if (fromType == null || toType == null) return; + if (parent instanceof PsiReferenceExpression) { + if (toType instanceof PsiClassType && fromType instanceof PsiPrimitiveType) return; //explicit boxing + + //Check accessibility + if (fromType instanceof PsiClassType) { + PsiElement element = ((PsiReferenceExpression)parent).resolve(); + if (!(element instanceof PsiMember)) return; + PsiClass accessClass = ((PsiClassType)fromType).resolve(); + if (accessClass == null) return; + if (!parent.getManager().getResolveHelper().isAccessible((PsiMember)element, typeCast, accessClass)) return; + } + } + + if (toType.isAssignableFrom(fromType)) { + addToResults(typeCast); + } + } + } + + public static boolean isTypeCastSemantical(PsiTypeCastExpression typeCast) { + PsiExpression operand = typeCast.getOperand(); + if (operand != null) { + PsiType opType = operand.getType(); + PsiType castType = typeCast.getCastType().getType(); + if (castType instanceof PsiPrimitiveType) { + if (opType instanceof PsiPrimitiveType) { + return !opType.equals(castType); // let's suppose all not equal primitive casts are necessary + } + } + else if (castType instanceof PsiClassType && ((PsiClassType)castType).hasParameters()) { + if (opType instanceof PsiClassType && ((PsiClassType)opType).isRaw()) return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefClass.java new file mode 100644 index 00000000000..912cee2d210 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefClass.java @@ -0,0 +1,567 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 4:29:19 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; +import com.intellij.execution.junit.JUnitUtil; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.*; +import com.intellij.psi.controlFlow.ControlFlow; +import com.intellij.psi.controlFlow.ControlFlowAnalyzer; +import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.controlFlow.LocalsOrMyInstanceFieldsControlFlowPolicy; +import com.intellij.psi.util.PsiFormatUtil; + +import java.util.*; + +public class RefClass extends RefElement { + private static final int IS_ANONYMOUS_MASK = 0x10000; + private static final int IS_INTERFACE_MASK = 0x20000; + private static final int IS_UTILITY_MASK = 0x40000; + private static final int IS_ABSTRACT_MASK = 0x80000; + private static final int IS_EJB_MASK = 0x100000; + private static final int IS_APPLET_MASK = 0x200000; + private static final int IS_SERVLET_MASK = 0x400000; + private static final int IS_TESTCASE_MASK = 0x800000; + private static final int IS_LOCAL_MASK = 0x1000000; + + private final HashSet myBases; + private final HashSet mySubClasses; + private final ArrayList myConstructors; + private RefMethod myDefaultConstructor; + private final ArrayList myOverridingMethods; + private final HashSet myInTypeReferences; + private final HashSet myInstanceReferences; + private ArrayList myClassExporters; + + public RefClass(PsiClass psiClass, RefManager manager) { + super(psiClass, manager); + + myConstructors = new ArrayList(1); + mySubClasses = new HashSet(0); + myBases = new HashSet(0); + myOverridingMethods = new ArrayList(2); + myInTypeReferences = new HashSet(0); + myInstanceReferences = new HashSet(0); + myDefaultConstructor = null; + + PsiElement psiParent = psiClass.getParent(); + if (psiParent instanceof PsiFile) { + PsiJavaFile psiFile = (PsiJavaFile) psiParent; + String packageName = psiFile.getPackageName(); + if (!"".equals(packageName)) { + manager.getPackage(packageName).add(this); + } else { + manager.getRefProject().getDefaultPackage().add(this); + } + + setCanBeStatic(false); + } else { + while (!(psiParent instanceof PsiClass || psiParent instanceof PsiMethod || psiParent instanceof PsiField)) { + psiParent = psiParent.getParent(); + } + RefElement refParent = manager.getReference(psiParent); + refParent.add(this); + + if (!(getOwner().getOwner() instanceof RefPackage)) { + setCanBeStatic(false); + } + } + + setAbstract(psiClass.hasModifierProperty(PsiModifier.ABSTRACT)); + + setAnonymous(psiClass instanceof PsiAnonymousClass); + setIsLocal(!(isAnonymous() || psiParent instanceof PsiClass || psiParent instanceof PsiFile)); + setInterface(psiClass.isInterface()); + + if (isAbstract() || isAnonymous() || isInterface()) { + setCanBeFinal(false); + } + + initializeSuperReferences(psiClass); + + PsiMethod[] psiMethods = psiClass.getMethods(); + PsiField[] psiFields = psiClass.getFields(); + + setUtilityClass(psiMethods.length > 0 || psiFields.length > 0); + + HashSet allFields = new HashSet(); + + for (int i = 0; i < psiFields.length; i++) { + PsiField psiField = psiFields[i]; + getRefManager().getFieldReference(this, psiField); + allFields.add(psiField); + } + + for (int i = 0; i < psiMethods.length; i++) { + PsiMethod psiMethod = psiMethods[i]; + RefMethod refMethod = getRefManager().getMethodReference(this, psiMethod); + + if (refMethod != null) { + if (psiMethod.isConstructor()) { + if (psiMethod.getParameterList().getParameters().length > 0 || + !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) { + setUtilityClass(false); + } + + addConstructor(refMethod); + if (psiMethod.getParameterList().getParameters().length == 0) { + setDefaultConstructor(refMethod); + } + } else { + if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) { + setUtilityClass(false); + } + } + } + } + + if (myConstructors.size() == 0 && !isInterface() && !isAnonymous()) { + RefImplicitConstructor refImplicitConstructor = new RefImplicitConstructor(this); + setDefaultConstructor(refImplicitConstructor); + addConstructor(refImplicitConstructor); + } + + if (isInterface()) { + for (int i = 0; i < psiFields.length && isUtilityClass(); i++) { + PsiField psiField = psiFields[i]; + if (!psiField.hasModifierProperty(PsiModifier.STATIC)) { + setUtilityClass(false); + } + } + + setCanBeStatic(false); + } + + if (isAnonymous()) { + setCanBeStatic(false); + } + + setApplet(manager.getApplet() != null && psiClass.isInheritor(manager.getApplet(), true)); + if (!isApplet()) setServlet(manager.getServlet() != null && psiClass.isInheritor(manager.getServlet(), true)); + if (!isApplet() && !isServlet()) { + setTestCase(JUnitUtil.isTestCaseClass(psiClass)); + for (Iterator iterator = getBaseClasses().iterator(); iterator.hasNext();) { + RefClass refBase = iterator.next(); + refBase.setTestCase(true); + } + } + } + + private void initializeSuperReferences(PsiClass psiClass) { + if (!isSelfInheritor(psiClass)) { + PsiClass[] supers = psiClass.getSupers(); + for (int i = 0; i < supers.length; i++) { + PsiClass psiSuperClass = supers[i]; + if (RefUtil.belongsToScope(psiSuperClass, getRefManager())) { + RefClass refClass = (RefClass) getRefManager().getReference(psiSuperClass); + if (refClass != null) { + myBases.add(refClass); + refClass.markOverriden(this); + } + } + } + } + } + + private static boolean isSelfInheritor(PsiClass psiClass) { + ArrayList visited = new ArrayList(); + return isSelfInheritor(psiClass, visited); + } + + private static boolean isSelfInheritor(PsiClass psiClass, ArrayList visited) { + if (visited.contains(psiClass)) return true; + + visited.add(psiClass); + PsiClass[] supers = psiClass.getSupers(); + for (int i = 0; i < supers.length; i++) { + PsiClass aSuper = supers[i]; + if (isSelfInheritor(aSuper, visited)) return true; + } + visited.remove(psiClass); + + return false; + } + + private void setDefaultConstructor(RefMethod defaultConstructor) { + if (defaultConstructor != null) { + for (Iterator iterator = getBaseClasses().iterator(); iterator.hasNext();) { + RefClass superClass = iterator.next(); + RefMethod superDefaultConstructor = superClass.getDefaultConstructor(); + + if (superDefaultConstructor != null) { + superDefaultConstructor.addInReference(defaultConstructor); + defaultConstructor.addOutReference(superDefaultConstructor); + } + } + } + + myDefaultConstructor = defaultConstructor; + } + + private void markOverriden(RefClass subClass) { + mySubClasses.add(subClass); + setCanBeFinal(false); + } + + public void buildReferences() { + PsiClass psiClass = (PsiClass) getElement(); + + if (psiClass != null) { + final PsiClassInitializer[] initializers = psiClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + PsiClassInitializer classInitializer = initializers[i]; + RefUtil.addReferences(psiClass, this, classInitializer.getBody()); + } + + PsiMethod[] psiMethods = psiClass.getMethods(); + PsiField[] psiFields = psiClass.getFields(); + + HashSet allFields = new HashSet(); + + for (int i = 0; i < psiFields.length; i++) { + PsiField psiField = psiFields[i]; + getRefManager().getFieldReference(this, psiField); + allFields.add(psiField); + } + + ArrayList instanceInitializerInitializedFields = new ArrayList(); + boolean hasInitializers = false; + for (int i = 0; i < initializers.length; i++) { + PsiClassInitializer initializer = initializers[i]; + PsiCodeBlock body = initializer.getBody(); + if (body != null) { + hasInitializers = true; + ControlFlowAnalyzer analyzer = new ControlFlowAnalyzer(body, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance()); + ControlFlow flow; + try { + flow = analyzer.buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + flow = ControlFlow.EMPTY; + } + PsiVariable[] ssaVariables = ControlFlowUtil.getSSAVariables(flow, false); + PsiVariable[] writtenVariables = ControlFlowUtil.getWrittenVariables(flow, 0, flow.getSize()); + for (int j = 0; j < ssaVariables.length; j++) { + PsiVariable psiVariable = writtenVariables[j]; + if (allFields.contains(psiVariable)) { + if (instanceInitializerInitializedFields.contains(psiVariable)) { + allFields.remove(psiVariable); + instanceInitializerInitializedFields.remove(psiVariable); + } else { + instanceInitializerInitializedFields.add(psiVariable); + } + } + } + for (int j = 0; j < writtenVariables.length; j++) { + PsiVariable psiVariable = writtenVariables[j]; + if (!instanceInitializerInitializedFields.contains(psiVariable)) { + allFields.remove(psiVariable); + } + } + } + } + + for (int i = 0; i < psiMethods.length; i++) { + PsiMethod psiMethod = psiMethods[i]; + RefMethod refMethod = getRefManager().getMethodReference(this, psiMethod); + + if (refMethod != null) { + if (psiMethod.isConstructor()) { + PsiCodeBlock body = psiMethod.getBody(); + if (body != null) { + hasInitializers = true; + ControlFlowAnalyzer analyzer = new ControlFlowAnalyzer(body, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance()); + ControlFlow flow; + try { + flow = analyzer.buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + flow = ControlFlow.EMPTY; + } + + PsiVariable[] writtenVariables = ControlFlowUtil.getWrittenVariables(flow, 0, flow.getSize()); + for (int j = 0; j < writtenVariables.length; j++) { + PsiVariable psiVariable = writtenVariables[j]; + if (instanceInitializerInitializedFields.contains(psiVariable)) { + allFields.remove(psiVariable); + instanceInitializerInitializedFields.remove(psiVariable); + } + } + + + List redirectedConstructors = HighlightControlFlowUtil.getRedirectedConstructors(psiMethod); + if ((redirectedConstructors == null || redirectedConstructors.isEmpty())) { + PsiVariable[] ssaVariables = ControlFlowUtil.getSSAVariables(flow, false); + ArrayList good = new ArrayList(Arrays.asList(ssaVariables)); + good.addAll(instanceInitializerInitializedFields); + allFields.retainAll(good); + } else { + allFields.removeAll(Arrays.asList(writtenVariables)); + } + } + } + } + } + + for (int i = 0; i < psiFields.length; i++) { + PsiField psiField = psiFields[i]; + if ((!hasInitializers || !allFields.contains(psiField)) && psiField.getInitializer() == null) { + RefField refField = (RefField) getRefManager().getReference(psiField); + refField.setCanBeFinal(false); + } + } + + EjbClassRole role = J2EERolesUtil.getEjbRole(psiClass); + if (role != null) { + setEjb(true); + setCanBeStatic(false); + setCanBeFinal(false); + if (role.getType() == EjbClassRole.EJB_CLASS_ROLE_HOME_INTERFACE || + role.getType() == EjbClassRole.EJB_CLASS_ROLE_REMOTE_INTERFACE) { + PsiClassType remoteExceptionType = psiClass.getManager().getElementFactory().createTypeByFQClassName("java.rmi.RemoteException", psiClass.getResolveScope()); + PsiMethod[] allMethods = psiClass.getAllMethods(); + for (int i = 0; i < allMethods.length; i++) { + PsiMethod psiMethod = allMethods[i]; + if (!RefUtil.belongsToScope(psiMethod, getRefManager())) continue; + RefMethod refMethod = getRefManager().getMethodReference(this, psiMethod); + if (refMethod != null) { + refMethod.updateThrowsList(remoteExceptionType); + } + } + } + } + } + } + + public void accept(RefVisitor visitor) { + visitor.visitClass(this); + } + + public HashSet getBaseClasses() { + return myBases; + } + + public HashSet getSubClasses() { + return mySubClasses; + } + + public ArrayList getConstructors() { + return myConstructors; + } + + public Set getInTypeReferences() { + return myInTypeReferences; + } + + public void addTypeReference(RefElement from) { + if (from != null) { + myInTypeReferences.add(from); + } + } + + public Set getInstanceReferences() { + return myInstanceReferences; + } + + public void addInstanceReference(RefElement from) { + myInstanceReferences.add(from); + } + + public RefMethod getDefaultConstructor() { + return myDefaultConstructor; + } + + private void addConstructor(RefMethod refConstructor) { + myConstructors.add(refConstructor); + } + + public void addLibraryOverrideMethod(RefMethod refMethod) { + myOverridingMethods.add(refMethod); + } + + public ArrayList getLibraryMethods() { + return myOverridingMethods; + } + + public boolean isAnonymous() { + return checkFlag(IS_ANONYMOUS_MASK); + } + + public boolean isInterface() { + return checkFlag(IS_INTERFACE_MASK); + } + + public boolean isSuspicious() { + if (isUtilityClass() && getOutReferences().isEmpty()) return false; + return super.isSuspicious(); + } + + public boolean isUtilityClass() { + return checkFlag(IS_UTILITY_MASK); + } + + public String getExternalName() { + final String[] result = new String[1]; + final Runnable runnable = new Runnable() { + public void run() { + PsiClass psiClass = (PsiClass) getElement(); + result[0] = PsiFormatUtil.formatClass(psiClass, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_FQ_NAME); + } + }; + + ApplicationManager.getApplication().runReadAction(runnable); + + return result[0]; + } + + public static RefClass classFromExternalName(RefManager manager, String externalName) { + PsiClass psiClass = PsiManager.getInstance(manager.getProject()).findClass(externalName); + RefClass refClass = null; + + if (psiClass != null) { + refClass = (RefClass) manager.getReference(psiClass); + } + + return refClass; + } + + public void referenceRemoved() { + super.referenceRemoved(); + + for (Iterator iterator = getSubClasses().iterator(); iterator.hasNext();) { + RefClass subClass = iterator.next(); + subClass.removeBase(this); + } + + for (Iterator iterator = getBaseClasses().iterator(); iterator.hasNext();) { + RefClass superClass = iterator.next(); + superClass.getSubClasses().remove(this); + } + } + + private void removeBase(RefClass superClass) { + getBaseClasses().remove(superClass); + } + + protected void methodRemoved(RefMethod method) { + getConstructors().remove(method); + getLibraryMethods().remove(method); + + if (getDefaultConstructor() == method) { + setDefaultConstructor(null); + } + } + + public boolean isAbstract() { + return checkFlag(IS_ABSTRACT_MASK); + } + + public boolean isEjb() { + return checkFlag(IS_EJB_MASK); + } + + public boolean isApplet() { + return checkFlag(IS_APPLET_MASK); + } + + public boolean isServlet() { + return checkFlag(IS_SERVLET_MASK); + } + + public boolean isTestCase() { + return checkFlag(IS_TESTCASE_MASK); + } + + public boolean isLocalClass() { + return checkFlag(IS_LOCAL_MASK); + } + + public boolean isCanBeStatic() { + for (Iterator iterator = getBaseClasses().iterator(); iterator.hasNext();) { + RefClass refBase = iterator.next(); + if (!refBase.isCanBeStatic()) { + setCanBeStatic(false); + return false; + } + } + + return super.isCanBeStatic(); + } + + public boolean isReferenced() { + if (super.isReferenced()) return true; + + if (isInterface() || isAbstract()) { + if (getSubClasses().size() > 0) return true; + } + + return false; + } + + public boolean hasSuspiciousCallers() { + if (super.hasSuspiciousCallers()) return true; + + if (isInterface() || isAbstract()) { + if (getSubClasses().size() > 0) return true; + } + + return false; + } + + public void addClassExporter(RefElement exporter) { + if (myClassExporters == null) myClassExporters = new ArrayList(1); + if (myClassExporters.contains(exporter)) return; + myClassExporters.add(exporter); + } + + public ArrayList getClassExporters() { + return myClassExporters; + } + + private void setAnonymous(boolean anonymous) { + setFlag(anonymous, IS_ANONYMOUS_MASK); + } + + private void setInterface(boolean anInterface) { + setFlag(anInterface, IS_INTERFACE_MASK); + } + + private void setUtilityClass(boolean utilityClass) { + setFlag(utilityClass, IS_UTILITY_MASK); + } + + private void setAbstract(boolean anAbstract) { + setFlag(anAbstract, IS_ABSTRACT_MASK); + } + + private void setEjb(boolean ejb) { + setFlag(ejb, IS_EJB_MASK); + } + + private void setApplet(boolean applet) { + setFlag(applet, IS_APPLET_MASK); + } + + private void setServlet(boolean servlet) { + setFlag(servlet, IS_SERVLET_MASK); + } + + private void setTestCase(boolean testCase) { + setFlag(testCase, IS_TESTCASE_MASK); + } + + public void setIsLocal(boolean isLocal) { + setFlag(isLocal, IS_LOCAL_MASK); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefElement.java new file mode 100644 index 00000000000..dc91087e3bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefElement.java @@ -0,0 +1,327 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 4:28:53 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Stack; + +public abstract class RefElement extends RefEntity { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.reference.RefElement"); + private static final int ACCESS_MODIFIER_MASK = 0x03; + private static final int ACCESS_PRIVATE = 0x00; + private static final int ACCESS_PROTECTED = 0x01; + private static final int ACCESS_PACKAGE = 0x02; + private static final int ACCESS_PUBLIC = 0x03; + + private static final int IS_STATIC_MASK = 0x04; + private static final int IS_FINAL_MASK = 0x08; + private static final int IS_CAN_BE_STATIC_MASK = 0x10; + private static final int IS_CAN_BE_FINAL_MASK = 0x20; + private static final int IS_REACHABLE_MASK = 0x40; + private static final int IS_ENTRY_MASK = 0x80; + private static final int IS_PERMANENT_ENTRY_MASK = 0x100; + private static final int IS_USES_DEPRECATION_MASK = 0x200; + + + private SmartPsiElementPointer myID; + private final RefManager myManager; + + private final ArrayList myOutReferences; + private final ArrayList myInReferences; + + private int myFlags; + private boolean myIsDeleted ; + + protected RefElement(String name, RefElement owner) { + super(name); + myManager = owner.getRefManager(); + myID = null; + myFlags = 0; + + myOutReferences = new ArrayList(0); + myInReferences = new ArrayList(0); + + String am = owner.getAccessModifier(); + final int access_id; + + if (PsiModifier.PRIVATE.equals(am)) { + access_id = ACCESS_PRIVATE; + } + else if (PsiModifier.PUBLIC.equals(am)) { + access_id = ACCESS_PUBLIC; + } + else if (PsiModifier.PACKAGE_LOCAL.equals(am)) { + access_id = ACCESS_PACKAGE; + } + else { + access_id = ACCESS_PROTECTED; + } + + myFlags = ((myFlags >> 2) << 2) | access_id; + } + + protected RefElement(PsiModifierListOwner elem, RefManager manager) { + super(RefUtil.getName(elem)); + myManager = manager; + myID = SmartPointerManager.getInstance(manager.getProject()).createSmartPsiElementPointer(elem); + myFlags = 0; + + setCanBeStatic(true); + setCanBeFinal(true); + + setAccessModifier(RefUtil.getAccessModifier(elem)); + + myOutReferences = new ArrayList(0); + myInReferences = new ArrayList(0); + + initialize(elem); + } + + protected void initialize(PsiModifierListOwner elem) { + setIsStatic(elem.hasModifierProperty(PsiModifier.STATIC)); + setIsFinal(elem.hasModifierProperty(PsiModifier.FINAL)); + } + + public boolean isValid() { + if (myIsDeleted) return false; + final PsiElement element = getElement(); + return element != null && element.isPhysical(); + } + + public RefManager getRefManager() { + return myManager; + } + + public String getExternalName() { + return getName(); + } + + public PsiModifierListOwner getElement() { + return (PsiModifierListOwner)myID.getElement(); + } + + public abstract void accept(RefVisitor visitor); + + public void buildReferences() { + } + + protected void markReferenced(final RefElement refFrom, PsiElement psiFrom, PsiElement psiWhat, final boolean forWriting, boolean forReading, PsiReferenceExpression expressionFrom) { + addInReference(refFrom); + } + + public boolean isReachable() { + return checkFlag(IS_REACHABLE_MASK); + } + + public boolean isReferenced() { + return getInReferences().size() > 0; + } + + public boolean hasSuspiciousCallers() { + for (Iterator iterator = getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + if (refCaller.isSuspicious()) return true; + } + + return false; + } + + public boolean isSuspiciousRecursive() { + return isCalledOnlyFrom(this, new Stack()); + } + + private boolean isCalledOnlyFrom(RefElement refElement, Stack callStack) { + if (callStack.contains(this)) return refElement == this ? true : false; + if (getInReferences().size() == 0) return false; + + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + for (Iterator iterator = refMethod.getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + if (refSuper.getInReferences().size() > 0) return false; + } + } + + callStack.push(this); + for (Iterator iterator = getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + if (!refCaller.isSuspicious() || !refCaller.isCalledOnlyFrom(refElement, callStack)) { + callStack.pop(); + return false; + } + } + + callStack.pop(); + return true; + } + + public void addReference(RefElement refWhat, PsiElement psiWhat, PsiElement psiFrom, boolean forWriting, boolean forReading, PsiReferenceExpression expression) { + if (refWhat != null) { + addOutReference(refWhat); + refWhat.markReferenced(this, psiFrom, psiWhat, forWriting, forReading, expression); + } + } + + public Collection getOutReferences() { + return myOutReferences; + } + + public Collection getInReferences() { + return myInReferences; + } + + public void addInReference(RefElement refElement) { + if (!myInReferences.contains(refElement)) { + myInReferences.add(refElement); + } + } + + public void addOutReference(RefElement refElement) { + if (!myOutReferences.contains(refElement)) { + myOutReferences.add(refElement); + } + } + + public boolean isFinal() { + return checkFlag(IS_FINAL_MASK); + } + + public boolean isStatic() { + return checkFlag(IS_STATIC_MASK); + } + + public void setIsStatic(boolean isStatic) { + setFlag(isStatic, IS_STATIC_MASK); + } + + protected boolean checkFlag(int mask) { + return (myFlags & mask) != 0; + } + + protected void setFlag(boolean b, int mask) { + if (b) { + myFlags |= mask; + } else { + myFlags &= ~mask; + } + } + + public void setCanBeStatic(boolean canBeStatic) { + setFlag(canBeStatic, IS_CAN_BE_STATIC_MASK); + } + + public boolean isCanBeStatic() { + return checkFlag(IS_CAN_BE_STATIC_MASK); + } + + public void setCanBeFinal(boolean canBeFinal) { + setFlag(canBeFinal, IS_CAN_BE_FINAL_MASK); + } + + public boolean isCanBeFinal() { + return checkFlag(IS_CAN_BE_FINAL_MASK); + } + + public boolean isUsesDeprecatedApi() { + return checkFlag(IS_USES_DEPRECATION_MASK); + } + + public void setUsesDeprecatedApi(boolean usesDeprecatedApi) { + setFlag(usesDeprecatedApi, IS_USES_DEPRECATION_MASK); + } + + public void setIsFinal(boolean isFinal) { + setFlag(isFinal, IS_FINAL_MASK); + } + + public void setEntry(boolean entry) { + setFlag(entry, IS_ENTRY_MASK); + } + + public boolean isEntry() { + return checkFlag(IS_ENTRY_MASK); + } + + public boolean isPermanentEntry() { + return checkFlag(IS_PERMANENT_ENTRY_MASK); + } + + public void setPermanentEntry(boolean permanentEntry) { + setFlag(permanentEntry, IS_PERMANENT_ENTRY_MASK); + } + + public void setReachable(boolean reachable) { + setFlag(reachable, IS_REACHABLE_MASK); + } + + public boolean isSuspicious() { + return !isReachable(); + } + + public String getAccessModifier() { + int access_id = myFlags & ACCESS_MODIFIER_MASK; + if (access_id == ACCESS_PRIVATE) return PsiModifier.PRIVATE; + if (access_id == ACCESS_PUBLIC) return PsiModifier.PUBLIC; + if (access_id == ACCESS_PACKAGE) return PsiModifier.PACKAGE_LOCAL; + return PsiModifier.PROTECTED; + } + + public void setAccessModifier(String am) { + final int access_id; + + if (PsiModifier.PRIVATE.equals(am)) { + access_id = ACCESS_PRIVATE; + } + else if (PsiModifier.PUBLIC.equals(am)) { + access_id = ACCESS_PUBLIC; + } + else if (PsiModifier.PACKAGE_LOCAL.equals(am)) { + access_id = ACCESS_PACKAGE; + } + else { + access_id = ACCESS_PROTECTED; + } + + myFlags = ((myFlags >> 2) << 2) | access_id; + } + + public void referenceRemoved() { + myIsDeleted = true; + if (getOwner() != null) { + getOwner().removeChild(this); + } + + for (Iterator iterator = getOutReferences().iterator(); iterator.hasNext();) { + RefElement refCallee = iterator.next(); + refCallee.getInReferences().remove(this); + } + + for (Iterator iterator = getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + refCaller.getOutReferences().remove(this); + } + } + + public URL getURL() { + try { + return new URL(getElement().getContainingFile().getVirtualFile().getUrl() + "#" + getElement().getTextRange().getStartOffset()); + } catch (MalformedURLException e) { + LOG.error(e); + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefEntity.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefEntity.java new file mode 100644 index 00000000000..920ac934008 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefEntity.java @@ -0,0 +1,59 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 15, 2001 + * Time: 5:14:35 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import java.util.ArrayList; + +public abstract class RefEntity { + private RefEntity myOwner; + private ArrayList myChildren; + private final String myName; + + protected RefEntity(String name) { + myName = name != null ? name : "noname"; + myOwner = null; + myChildren = null; + } + + public String getName() { + return myName; + } + + public ArrayList getChildren() { + return myChildren; + } + + public RefEntity getOwner() { + return myOwner; + } + + private void setOwner(RefEntity owner) { + myOwner = owner; + } + + public void add(RefEntity child) { + if (myChildren == null) { + myChildren = new ArrayList(); + } + + myChildren.add(child); + child.setOwner(this); + } + + protected void removeChild(RefEntity child) { + if (myChildren != null) { + myChildren.remove(child); + child.setOwner(null); + } + } + + public String toString() { + return getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefField.java new file mode 100644 index 00000000000..4f70ed2d546 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefField.java @@ -0,0 +1,173 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 4:29:10 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; + +public class RefField extends RefElement { + private static final int USED_FOR_READING_MASK = 0x10000; + private static final int USED_FOR_WRITING_MASK = 0x20000; + private static final int ASSIGNED_ONLY_IN_INITIALIZER = 0x40000; + + public RefField(PsiField field, RefManager manager) { + this((RefClass) manager.getReference(field.getContainingClass()), field, manager); + } + + public RefField(RefClass ownerClass, PsiField field, RefManager manager) { + super(field, manager); + + ownerClass.add(this); + + PsiClass psiClass = field.getContainingClass(); + + if (psiClass.isInterface()) { + setIsStatic(true); + setIsFinal(true); + } + + setCanBeStatic(isStatic()); + } + + protected void markReferenced(RefElement refFrom, PsiElement psiFrom, PsiElement psiWhat, boolean forWriting, boolean forReading, PsiReferenceExpression expressionFrom) { + super.markReferenced(refFrom, psiFrom, psiWhat, forWriting, forReading, expressionFrom); + + boolean referencedFromClassInitializer = false; + + if (forWriting && expressionFrom != null) { + PsiClassInitializer initializer = PsiTreeUtil.getParentOfType(expressionFrom, PsiClassInitializer.class); + if (initializer != null) { + if (initializer.getParent() instanceof PsiClass && psiFrom == initializer.getParent()) { + referencedFromClassInitializer = true; + } + } + } + + if (forWriting) { + setUsedForWriting(true); + if (!(refFrom instanceof RefMethod) || + !((RefMethod)refFrom).isConstructor() || + ((PsiField) psiWhat).hasInitializer()) { + if (!referencedFromClassInitializer) { + setCanBeFinal(false); + } + } + } + + if (forReading) { + setUsedForReading(true); + } + } + + public boolean isUsedForReading() { + return checkFlag(USED_FOR_READING_MASK); + } + + private void setUsedForReading(boolean usedForReading) { + setFlag(usedForReading, USED_FOR_READING_MASK); + } + + public boolean isUsedForWriting() { + return checkFlag(USED_FOR_WRITING_MASK); + } + + private void setUsedForWriting(boolean usedForWriting) { + setFlag(false, ASSIGNED_ONLY_IN_INITIALIZER); + setFlag(usedForWriting, USED_FOR_WRITING_MASK); + } + + public boolean isOnlyAssignedInInitializer() { + return checkFlag(ASSIGNED_ONLY_IN_INITIALIZER); + } + + public void accept(RefVisitor visitor) { + visitor.visitField(this); + } + + public void buildReferences() { + PsiField psiField = (PsiField) getElement(); + if (psiField != null) { + RefUtil.addReferences(psiField, this, psiField.getInitializer()); + if (psiField.getInitializer() != null || psiField instanceof PsiEnumConstant) { + if (!checkFlag(USED_FOR_WRITING_MASK)) { + setFlag(true, ASSIGNED_ONLY_IN_INITIALIZER); + setFlag(true, USED_FOR_WRITING_MASK); + } + } + PsiType type = psiField.getType(); + if (type != null) { + PsiType psiType = type; + RefClass ownerClass = RefUtil.getOwnerClass(getRefManager(), psiField); + + if (ownerClass != null) { + psiType = psiType.getDeepComponentType(); + if (psiType instanceof PsiClassType) { + PsiClass psiClass = PsiUtil.resolveClassInType(psiType); + if (psiClass != null && RefUtil.belongsToScope(psiClass, getRefManager())) { + RefClass refClass = (RefClass) getRefManager().getReference(psiClass); + if (refClass != null) { + refClass.addTypeReference(ownerClass); + refClass.addClassExporter(this); + } + } + } + } + } + } + } + + public RefClass getOwnerClass() { + return (RefClass) getOwner(); + } + + public String getExternalName() { + final String[] result = new String[1]; + final Runnable runnable = new Runnable() { + public void run() { + PsiField psiField = (PsiField) getElement(); + result[0] = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_FQ_NAME | + PsiFormatUtil.SHOW_CONTAINING_CLASS, + PsiSubstitutor.EMPTY); + } + }; + + ApplicationManager.getApplication().runReadAction(runnable); + + return result[0]; + } + + public static RefField fieldFromExternalName(RefManager manager, String externalName) { + RefField refField = null; + + int lastDotIdx = externalName.lastIndexOf('.'); + String className = externalName.substring(0, lastDotIdx); + String fieldName = externalName.substring(lastDotIdx + 1); + + if (RefClass.classFromExternalName(manager, className) != null) { + PsiClass psiClass = PsiManager.getInstance(manager.getProject()).findClass(className); + PsiField psiField = psiClass.findFieldByName(fieldName, false); + + if (psiField != null) { + refField = (RefField) manager.getReference(psiField); + } + } + + return refField; + } + + public boolean isSuspicious() { + if (isEntry()) return false; + if (super.isSuspicious()) return true; + return isUsedForReading() != isUsedForWriting(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefImplicitConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefImplicitConstructor.java new file mode 100644 index 00000000000..9fffbcd5967 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefImplicitConstructor.java @@ -0,0 +1,56 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 28, 2001 + * Time: 4:17:17 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifierListOwner; + +public class RefImplicitConstructor extends RefMethod { + private RefClass myOwnerClass; + + public RefImplicitConstructor(RefClass ownerClass) { + super("implicit constructor of " + ownerClass.getName(), ownerClass); + myOwnerClass = ownerClass; + } + + public void buildReferences() { + } + + public boolean isSuspicious() { + return getOwnerClass().isSuspicious(); + } + + public String getName() { + return "implicit constructor of " + getOwnerClass().getName(); + } + + public String getExternalName() { + return getOwnerClass().getExternalName(); + } + + public boolean isValid() { + return getOwnerClass().isValid(); + } + + public String getAccessModifier() { + return getOwnerClass().getAccessModifier(); + } + + public void setAccessModifier(String am) { + getOwnerClass().setAccessModifier(am); + } + + public PsiModifierListOwner getElement() { + return getOwnerClass().getElement(); + } + + public RefClass getOwnerClass() { + return myOwnerClass == null ? super.getOwnerClass() : myOwnerClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefManager.java new file mode 100644 index 00000000000..f82099be26f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefManager.java @@ -0,0 +1,346 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 22, 2001 + * Time: 8:21:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInsight.daemon.impl.analysis.AlternativeWay; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; + +public class RefManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.reference.RefManager"); + + private final Project myProject; + private final AnalysisScope myScope; + private final RefProject myRefProject; + private final PsiManager myPsiManager; + private HashMap myRefTable; + private HashMap myPackages; + private final ProjectIterator myProjectIterator; + private boolean myDeclarationsFound; + private PsiMethod myAppMainPattern; + private PsiClass myApplet; + private PsiClass myServlet; + private boolean myIsInProcess = false; + + public interface RefIterator { + void accept(RefElement refElement); + } + + public RefManager(Project project, AnalysisScope scope) { + myDeclarationsFound = false; + myProject = project; + myScope = scope; + myRefProject = new RefProject(this); + myRefTable = new HashMap(); + myPsiManager = PsiManager.getInstance(project); + + myProjectIterator = new ProjectIterator(); + + PsiElementFactory factory = myPsiManager.getElementFactory(); + try { + myAppMainPattern = factory.createMethodFromText("void main(String[] args);", null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + + myApplet = myPsiManager.findClass("java.applet.Applet"); + myServlet = myPsiManager.findClass("javax.servlet.Servlet"); + } + + public void iterate(RefIterator iterator) { + final HashMap refTable = getRefTable(); + for (Iterator refIterator = refTable.values().iterator(); refIterator.hasNext();) { + RefElement refElement = refIterator.next(); + iterator.accept(refElement); + if (refElement instanceof RefClass) { + RefClass refClass = (RefClass)refElement; + RefMethod refDefaultConstructor = refClass.getDefaultConstructor(); + if (refDefaultConstructor != null && refDefaultConstructor instanceof RefImplicitConstructor) { + iterator.accept(refClass.getDefaultConstructor()); + } + } + } + } + + public void cleanup() { + myRefTable = null; + } + + public AnalysisScope getScope() { + return myScope; + } + + + public void findAllDeclarations() { + if (!myDeclarationsFound) { + long before = System.currentTimeMillis(); + getScope().accept(myProjectIterator); + myDeclarationsFound = true; + + LOG.info("Total duration of processing project usages:" + (System.currentTimeMillis() - before)); + } + } + + public void inspectionReadActionStarted() { + myIsInProcess = true; + } + + public void inspectionReadActionFinished() { + myIsInProcess = false; + } + + public PsiElement getPsiAtOffset(VirtualFile vFile, int textOffset) { + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); + if (psiFile == null) return null; + + PsiElement psiElem = psiFile.findElementAt(textOffset); + + while (psiElem != null) { + if (psiElem instanceof PsiClass || + psiElem instanceof PsiMethod || + psiElem instanceof PsiField || + psiElem instanceof PsiParameter) { + return psiElem.getTextOffset() == textOffset ? psiElem : null; + } + + psiElem = psiElem.getParent(); + } + + return null; + } + + public Project getProject() { + return myProject; + } + + public RefProject getRefProject() { + return myRefProject; + } + + public HashMap getRefTable() { + return myRefTable; + } + + public RefPackage getPackage(String packageName) { + if (myPackages == null) { + myPackages = new HashMap(); + } + + RefPackage refPackage = (RefPackage)myPackages.get(packageName); + if (refPackage == null) { + refPackage = new RefPackage(packageName); + myPackages.put(packageName, refPackage); + + int dotIndex = packageName.lastIndexOf('.'); + if (dotIndex >= 0) { + getPackage(packageName.substring(0, dotIndex)).add(refPackage); + } + else { + getRefProject().add(refPackage); + } + } + + return refPackage; + } + + public void removeReference(RefElement refElem) { + final HashMap refTable = getRefTable(); + + if (refElem instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElem; + RefParameter[] params = refMethod.getParameters(); + for (int i = 0; i < params.length; i++) { + removeReference(params[i]); + } + } + + if (refTable.remove(refElem.getElement()) != null) return; + + //PsiElement may have been invalidated and new one returned by getElement() is different so we need to do this stuff. + Set keys = refTable.keySet(); + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + PsiElement psiElement = (PsiElement)iterator.next(); + if (refTable.get(psiElement) == refElem) { + refTable.remove(psiElement); + return; + } + } + } + + private class ProjectIterator extends PsiElementVisitor { + public void visitElement(PsiElement element) { + PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].accept(this); + } + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + } + + public void visitFile(PsiFile file) { + if (file instanceof PsiJavaFile && !(file instanceof PsiCompiledElement)) { + InspectionManagerEx manager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + manager.incrementJobDoneAmount(InspectionManagerEx.BUILD_GRAPH, file.getVirtualFile().getPresentableUrl()); + if (RefUtil.belongsToScope(file, RefManager.this)) { + AlternativeWay.processFile(file); + super.visitFile(file); + myPsiManager.dropResolveCaches(); + } + } + } + + public void visitClass(PsiClass aClass) { + if (!(aClass instanceof PsiTypeParameter)) { + super.visitClass(aClass); + RefElement refClass = RefManager.this.getReference(aClass); + refClass.buildReferences(); + ArrayList children = refClass.getChildren(); + if (children != null) { + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + RefElement refChild = (RefElement)iterator.next(); + refChild.buildReferences(); + } + } + } + } + + public void visitVariable(PsiVariable variable) { + super.visitVariable(variable); + RefUtil.addTypeReference(variable, variable.getType(), RefManager.this); + } + + public void visitInstanceOfExpression(PsiInstanceOfExpression expression) { + super.visitInstanceOfExpression(expression); + RefUtil.addTypeReference(expression, expression.getCheckType().getType(), RefManager.this); + } + + public void visitThisExpression(PsiThisExpression expression) { + super.visitThisExpression(expression); + if (expression.getQualifier() != null) { + RefUtil.addTypeReference(expression, expression.getType(), RefManager.this); + addInstanceReference(expression, (PsiClass)expression.getQualifier().resolve()); + } + } + + private void addInstanceReference(PsiThisExpression psiElement, PsiClass psiClass) { + RefClass ownerClass = RefUtil.getOwnerClass(RefManager.this, psiElement); + + if (ownerClass != null) { + RefClass refClass = (RefClass)RefManager.this.getReference(psiClass); + if (refClass != null) { + refClass.addInstanceReference(ownerClass); + } + + if (refClass != ownerClass) { + ownerClass.setCanBeStatic(false); + } + } + } + } + + public PsiMethod getAppMainPattern() { + return myAppMainPattern; + } + + public PsiClass getApplet() { + return myApplet; + } + + public PsiClass getServlet() { + return myServlet; + } + + public RefElement getReference(PsiElement elem) { + LOG.assertTrue(isValidPointForReference(), "References may become invalid after process is finished"); + if (elem != null && !(elem instanceof PsiPackage) && RefUtil.belongsToScope(elem, this)) { + if (!elem.isValid()) return null; + + RefElement ref = getRefTable().get(elem); + if (ref == null) { + if (elem instanceof PsiClass) { + ref = new RefClass((PsiClass)elem, this); + } + else if (elem instanceof PsiMethod) { + ref = new RefMethod((PsiMethod)elem, this); + } + else if (elem instanceof PsiField) { + ref = new RefField((PsiField)elem, this); + } + else { + return null; + } + + getRefTable().put(elem, ref); + } + + return ref; + } + + return null; + } + + public RefMethod getMethodReference(RefClass refClass, PsiMethod psiMethod) { + LOG.assertTrue(isValidPointForReference(), "References may become invalid after process is finished"); + + RefMethod ref = (RefMethod)getRefTable().get(psiMethod); + + if (ref == null) { + ref = new RefMethod(refClass, psiMethod, this); + getRefTable().put(psiMethod, ref); + } + + return ref; + } + + public RefField getFieldReference(RefClass refClass, PsiField psiField) { + LOG.assertTrue(isValidPointForReference(), "References may become invalid after process is finished"); + RefField ref = (RefField)getRefTable().get(psiField); + + if (ref == null) { + ref = new RefField(refClass, psiField, this); + getRefTable().put(psiField, ref); + } + + return ref; + } + + public RefParameter getParameterReference(PsiParameter param, int index) { + LOG.assertTrue(isValidPointForReference(), "References may become invalid after process is finished"); + RefElement ref = getRefTable().get(param); + + if (ref == null) { + ref = new RefParameter(param, index, this); + getRefTable().put(param, ref); + } + + return (RefParameter)ref; + } + + private boolean isValidPointForReference() { + return myIsInProcess || ApplicationManager.getApplication().isUnitTestMode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefMethod.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefMethod.java new file mode 100644 index 00000000000..281f8b9a607 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefMethod.java @@ -0,0 +1,725 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 4:29:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.j2ee.ejb.role.EjbDeclMethodRole; +import com.intellij.j2ee.ejb.role.EjbImplMethodRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class RefMethod extends RefElement { + private static final int IS_APPMAIN_MASK = 0x10000; + private static final int IS_LIBRARY_OVERRIDE_MASK = 0x20000; + private static final int IS_CONSTRUCTOR_MASK = 0x40000; + private static final int IS_ABSTRACT_MASK = 0x80000; + private static final int IS_BODY_EMPTY_MASK = 0x100000; + private static final int IS_ONLY_CALLS_SUPER_MASK = 0x200000; + private static final int IS_RETURN_VALUE_USED_MASK = 0x400000; + private static final int IS_EJB_DECLARATION_MASK = 0x800000; + private static final int IS_EJB_IMPLEMENTATION_MASK = 0x1000000; + private static final int IS_OVERRIDES_DEPRECATED_MASK = 0x2000000; + + private static final String RETURN_VALUE_UNDEFINED = "#"; + + private final ArrayList mySuperMethods; + private final ArrayList myDerivedMethods; + private ArrayList myUnThrownExceptions; + + private final RefParameter[] myParameters; + private String myReturnValueTemplate; + + public RefMethod(PsiMethod method, RefManager manager) { + this((RefClass) manager.getReference(method.getContainingClass()), method, manager); + } + + public RefMethod(RefClass ownerClass, PsiMethod method, RefManager manager) { + super(method, manager); + + ownerClass.add(this); + + myDerivedMethods = new ArrayList(0); + setConstructor(method.isConstructor()); + setFlag(method.getReturnType() == null || PsiType.VOID == method.getReturnType(), IS_RETURN_VALUE_USED_MASK); + + if (!isReturnValueUsed()) { + myReturnValueTemplate = RETURN_VALUE_UNDEFINED; + } + + if (isConstructor()) { + addReference(getOwnerClass(), getOwnerClass().getElement(), method, false, true, null); + setCanBeStatic(false); + } + + if (getOwnerClass().isInterface() || !(getOwnerClass().getOwner() instanceof RefPackage)) { + setCanBeStatic(false); + } + + if (getOwnerClass().isInterface()) { + setAbstract(false); + } else { + setAbstract(method.hasModifierProperty(PsiModifier.ABSTRACT)); + } + + + setAppMain(RefUtil.isAppMain(method, this)); + setLibraryOverride(method.hasModifierProperty(PsiModifier.NATIVE)); + + mySuperMethods = new ArrayList(0); + + initializeSuperMethods(method); + if (isLibraryOverride()) { + getOwnerClass().addLibraryOverrideMethod(this); + setCanBeStatic(false); + } + + if (getSuperMethods().size() > 0 || isAbstract()) { + setCanBeStatic(false); + } + + if (getOwnerClass().isTestCase() && method.getName().startsWith("test")) { + setCanBeStatic(false); + } + + PsiParameter[] paramList = method.getParameterList().getParameters(); + myParameters = new RefParameter[paramList.length]; + for (int i = 0; i < paramList.length; i++) { + PsiParameter parameter = paramList[i]; + myParameters[i] = getRefManager().getParameterReference(parameter, i); + } + + if (isConstructor() || isAbstract() || isStatic() || getAccessModifier() == PsiModifier.PRIVATE || ownerClass.isAnonymous() || ownerClass.isInterface()) { + setCanBeFinal(false); + } + + if (method.hasModifierProperty(PsiModifier.NATIVE)) { + updateReturnValueTemplate(null); + updateThrowsList(null); + } + + if (getAccessModifier() == PsiModifier.PRIVATE && !(getOwnerClass().getOwner() instanceof RefElement)) { + setCanBeFinal(false); + } + + collectUncaughtExceptions(method); + } + + private void checkForSuperCall(PsiMethod method) { + if (isConstructor()) { + boolean isBaseExplicitlyCalled = false; + PsiCodeBlock body = method.getBody(); + if (body == null) return; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + PsiExpression firstExpression = ((PsiExpressionStatement) first).getExpression(); + if (firstExpression instanceof PsiMethodCallExpression) { + PsiExpression qualifierExpression = ((PsiMethodCallExpression)firstExpression).getMethodExpression().getQualifierExpression(); + if (qualifierExpression instanceof PsiReferenceExpression) { + String text = qualifierExpression.getText(); + if ("super".equals(text) || text.equals(this)) { + isBaseExplicitlyCalled = true; + } + } + } + } + } + + if (!isBaseExplicitlyCalled) { + for (Iterator iterator = getOwnerClass().getBaseClasses().iterator(); iterator.hasNext();) { + RefClass superClass = iterator.next(); + RefMethod superDefaultConstructor = superClass.getDefaultConstructor(); + + if (superDefaultConstructor != null) { + superDefaultConstructor.addInReference(this); + addOutReference(superDefaultConstructor); + } + } + } + } + } + + // To be used only from RefImplicitConstructor. + protected RefMethod(String name, RefClass ownerClass) { + super(name, ownerClass); + + ownerClass.add(this); + + myDerivedMethods = new ArrayList(0); + mySuperMethods = new ArrayList(0); + + addOutReference(getOwnerClass()); + getOwnerClass().addInReference(this); + + setConstructor(true); + + myParameters = new RefParameter[0]; + } + + public Collection getSuperMethods() { + return mySuperMethods; + } + + public Collection getDerivedMethods() { + return myDerivedMethods; + } + + public boolean isBodyEmpty() { + return checkFlag(IS_BODY_EMPTY_MASK); + } + + public boolean isOnlyCallsSuper() { + return checkFlag(IS_ONLY_CALLS_SUPER_MASK); + } + + public boolean hasBody() { + return !isAbstract() && !getOwnerClass().isInterface() || !isBodyEmpty(); + } + + private void initializeSuperMethods(PsiMethod method) { + PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method); + for (int i = 0; i < superMethods.length; i++) { + PsiMethod psiSuperMethod = superMethods[i]; + if (RefUtil.isDeprecated(psiSuperMethod) && !psiSuperMethod.hasModifierProperty(PsiModifier.ABSTRACT)) setOverridesDeprecated(true); + if (RefUtil.belongsToScope(psiSuperMethod, getRefManager())) { + RefMethod refSuperMethod = (RefMethod) getRefManager().getReference(psiSuperMethod); + if (refSuperMethod != null) { + addSuperMethod(refSuperMethod); + refSuperMethod.markExtended(this); + } + } else { + setLibraryOverride(true); + } + } + } + + private void addSuperMethod(RefMethod refSuperMethod) { + if (!getSuperMethods().contains(refSuperMethod)) { + getSuperMethods().add(refSuperMethod); + } + } + + public void addReference(RefElement refWhat, PsiElement psiWhat, PsiElement psiFrom, boolean forWriting, boolean forReading, PsiReferenceExpression expression) { + if (refWhat instanceof RefParameter) { + if (forWriting) { + ((RefParameter)refWhat).parameterReferenced(true); + } + if (forReading) { + ((RefParameter)refWhat).parameterReferenced(false); + } + } else { + super.addReference(refWhat, psiWhat, psiFrom, forWriting, forReading, expression); + } + } + + private void markExtended(RefMethod method) { + setCanBeStatic(false); + setCanBeFinal(false); + if (!myDerivedMethods.contains(method)) { + myDerivedMethods.add(method); + } + } + + public RefParameter[] getParameters() { + return myParameters; + } + + public void buildReferences() { + // Work on code block to find what we're referencing... + PsiMethod method = (PsiMethod) getElement(); + if (method != null) { + PsiCodeBlock body = method.getBody(); + RefUtil.addReferences(method, this, body); + checkForSuperCall(method); + setOnlyCallsSuper(RefUtil.isMethodOnlyCallsSuper(method)); + + setBodyEmpty(isOnlyCallsSuper() || !isLibraryOverride() && (body == null || body.getStatements().length == 0)); + + EjbClassRole classRole = J2EERolesUtil.getEjbRole(method.getContainingClass()); + if (classRole != null) { + if (!getSuperMethods().isEmpty() || isLibraryOverride()) { + setCanBeFinal(false); + } + + EjbMethodRole role = J2EERolesUtil.getEjbRole(method); + if (role != null) { + setCanBeStatic(false); + int roleType = role.getType(); + if (role instanceof EjbDeclMethodRole) { + setEjbDeclaration(true); + setCanBeFinal(false); + + if (roleType == EjbDeclMethodRole.EJB_METHOD_ROLE_FINDER_DECL || + roleType == EjbDeclMethodRole.EJB_METHOD_ROLE_CMP_SETTER_DECL || + roleType == EjbDeclMethodRole.EJB_METHOD_ROLE_CMR_SETTER_DECL || + roleType == EjbDeclMethodRole.EJB_METHOD_ROLE_CMP_GETTER_DECL || + roleType == EjbDeclMethodRole.EJB_METHOD_ROLE_CMR_GETTER_DECL) { + for (int i = 0; i < myParameters.length; i++) { + RefParameter refParameter = myParameters[i]; + refParameter.parameterReferenced(false); + refParameter.parameterReferenced(true); + } + } + } else if (role instanceof EjbImplMethodRole) { + PsiMethod[] declarations = EjbUtil.findEjbDeclarations(method); + if (declarations.length != 0) { + for (int i = 0; i < declarations.length; i++) { + PsiMethod psiDeclaration = declarations[i]; + if (RefUtil.belongsToScope(psiDeclaration, getRefManager())) { + RefMethod refDeclaration = (RefMethod) getRefManager().getReference(psiDeclaration); + + if (refDeclaration != null) { + addSuperMethod(refDeclaration); + refDeclaration.markExtended(this); + } else { + setLibraryOverride(true); + } + } else { + setLibraryOverride(true); + } + } + } + + if (roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMP_GETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMP_SETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMR_GETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMR_SETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CREATE_IMPL) { + setBodyEmpty(false); + } + + if (roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMP_GETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMP_SETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMR_GETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_CMR_SETTER_IMPL || + roleType == EjbImplMethodRole.EJB_METHOD_ROLE_FINDER_IMPL) { + for (int i = 0; i < myParameters.length; i++) { + RefParameter refParameter = myParameters[i]; + refParameter.parameterReferenced(false); + refParameter.parameterReferenced(true); + } + } + + setCanBeFinal(false); + setEjbImplementation(true); + } + } + } + + PsiType retType = method.getReturnType(); + if (retType != null) { + PsiType psiType = retType; + RefClass ownerClass = RefUtil.getOwnerClass(getRefManager(), method); + + if (ownerClass != null) { + psiType = psiType.getDeepComponentType(); + + if (psiType instanceof PsiClassType) { + PsiClass psiClass = PsiUtil.resolveClassInType(psiType); + if (psiClass != null && RefUtil.belongsToScope(psiClass, getRefManager())) { + RefClass refClass = (RefClass) getRefManager().getReference(psiClass); + if (refClass != null) { + refClass.addTypeReference(ownerClass); + refClass.addClassExporter(this); + } + } + } + } + } + + RefParameter[] parameters = getParameters(); + for (int i = 0; i < parameters.length; i++) { + RefParameter parameter = parameters[i]; + parameter.initializeFinalFlag(); + } + } + } + + private boolean isEjbException(String qualifiedName) { + return "javax.ejb.CreateException".equals(qualifiedName) || + "java.rmi.RemoteException".equals(qualifiedName) || + "javax.ejb.FinderException".equals(qualifiedName) || + "javax.ejb.RemoveException".equals(qualifiedName); + } + + private void collectUncaughtExceptions(PsiMethod method) { + if (isLibraryOverride()) return; + if (getOwnerClass().isTestCase() && method.getName().startsWith("test")) return; + + if (getSuperMethods().size() == 0) { + PsiClassType[] throwsList = method.getThrowsList().getReferencedTypes(); + if (throwsList.length > 0) { + EjbClassRole role = J2EERolesUtil.getEjbRole(method.getContainingClass()); + myUnThrownExceptions = new ArrayList(throwsList.length); + for (int i = 0; i < throwsList.length; i++) { + final PsiClassType type = throwsList[i]; + String qualifiedName = type.getCanonicalText(); + if (role != null && isEjbException(qualifiedName)) continue; + myUnThrownExceptions.add(type); + } + } + } + + PsiCodeBlock body = method.getBody(); + if (body == null) return; + + PsiClassType[] exceptionTypes = ExceptionUtil.collectUnhandledExceptions(method, body); + if (exceptionTypes != null) { + for (int i = 0; i < exceptionTypes.length; i++) { + final PsiClassType exceptionType = exceptionTypes[i]; + updateThrowsList(exceptionType); + } + } + } + + public void accept(RefVisitor visitor) { + visitor.visitMethod(this); + } + + public boolean isLibraryOverride() { + if (checkFlag(IS_LIBRARY_OVERRIDE_MASK)) return true; + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod superMethod = iterator.next(); + if (superMethod.isLibraryOverride()) { + setFlag(true, IS_LIBRARY_OVERRIDE_MASK); + return true; + } + } + + return false; + } + + public boolean isAppMain() { + return checkFlag(IS_APPMAIN_MASK); + } + + public boolean isAbstract() { + return checkFlag(IS_ABSTRACT_MASK); + } + + public boolean isEjbDeclaration() { + return checkFlag(IS_EJB_DECLARATION_MASK); + } + + public boolean isEjbImplementation() { + return checkFlag(IS_EJB_IMPLEMENTATION_MASK); + } + + public boolean isReferenced() { + // Directly called from somewhere.. + for (Iterator iterator = getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + if (!getDerivedMethods().contains(refCaller)) return true; + } + + // Library override probably called from library code. + return isLibraryOverride(); + } + + public boolean hasSuspiciousCallers() { + // Directly called from somewhere.. + for (Iterator iterator = getInReferences().iterator(); iterator.hasNext();) { + RefElement refCaller = iterator.next(); + if (refCaller.isSuspicious() && !getDerivedMethods().contains(refCaller)) return true; + } + + // Library override probably called from library code. + if (isLibraryOverride()) return true; + + // Class isn't instantiated. Most probably we have problem with class, not method. + if (!isStatic() && !isConstructor()) { + if (getOwnerClass().isSuspicious()) return true; + + // Is an override. Probably called via reference to base class. + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + if (refSuper.isSuspicious()) return true; + } + } + + return false; + } + + public boolean isConstructor() { + return checkFlag(IS_CONSTRUCTOR_MASK); + } + + public RefClass getOwnerClass() { + return (RefClass) getOwner(); + } + + public String getName() { + if (isValid()) { + final String[] result = new String[1]; + final Runnable runnable = new Runnable() { + public void run() { + PsiMethod psiMethod = (PsiMethod) getElement(); + result[0] = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + } + }; + + ApplicationManager.getApplication().runReadAction(runnable); + + return result[0]; + } else { + return super.getName(); + } + } + + public String getExternalName() { + final String[] result = new String[1]; + final Runnable runnable = new Runnable() { + public void run() { + PsiMethod psiMethod = (PsiMethod) getElement(); + result[0] = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_FQ_NAME | + PsiFormatUtil.SHOW_TYPE | + PsiFormatUtil.SHOW_CONTAINING_CLASS | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_TYPE + ); + } + }; + + ApplicationManager.getApplication().runReadAction(runnable); + + return result[0]; + } + + public static RefMethod methodFromExternalName(RefManager manager, String externalName) { + RefMethod refMethod = null; + + int spaceIdx = externalName.indexOf(' '); + int lastDotIdx = externalName.lastIndexOf('.'); + boolean notype = false; + + int parenIndex = externalName.indexOf('('); + + while (lastDotIdx > parenIndex) lastDotIdx = externalName.lastIndexOf('.', lastDotIdx - 1); + + if (spaceIdx < 0 || spaceIdx > lastDotIdx || spaceIdx > parenIndex) { + notype = true; + } + + String className = externalName.substring(notype ? 0 : spaceIdx + 1, lastDotIdx); + String methodSignature = notype ? externalName.substring(lastDotIdx + 1) + : externalName.substring(0, spaceIdx) + ' ' + externalName.substring(lastDotIdx + 1); + + if (RefClass.classFromExternalName(manager, className) == null) return null; + try { + PsiClass psiClass = PsiManager.getInstance(manager.getProject()).findClass(className); + PsiElementFactory factory = psiClass.getManager().getElementFactory(); + PsiMethod patternMethod = factory.createMethodFromText(methodSignature, psiClass); + PsiMethod psiMethod = psiClass.findMethodBySignature(patternMethod, false); + + if (psiMethod != null) { + refMethod = (RefMethod) manager.getReference(psiMethod); + } + } catch (IncorrectOperationException e) { + // Do nothing. Returning null is acceptable in this case. + return null; + } + + return refMethod; + } + + public void referenceRemoved() { + if (getOwnerClass() != null) { + getOwnerClass().methodRemoved(this); + } + + super.referenceRemoved(); + + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod superMethod = iterator.next(); + superMethod.getDerivedMethods().remove(this); + } + + for (Iterator iterator = getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod subMethod = iterator.next(); + subMethod.getSuperMethods().remove(this); + } + + ArrayList deletedRefs = new ArrayList(); + RefParameter[] parameters = getParameters(); + for (int i = 0; i < parameters.length; i++) { + RefParameter parameter = parameters[i]; + RefUtil.removeRefElement(parameter, deletedRefs); + } + } + + public boolean isSuspicious() { + if (isConstructor() && getAccessModifier() == PsiModifier.PRIVATE && getParameters().length == 0 && getOwnerClass().getConstructors().size() == 1) return false; + return super.isSuspicious(); + } + + public void setReturnValueUsed(boolean value) { + if (checkFlag(IS_RETURN_VALUE_USED_MASK) == value) return; + setFlag(value, IS_RETURN_VALUE_USED_MASK); + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + refSuper.setReturnValueUsed(value); + } + } + + public boolean isReturnValueUsed() { + return checkFlag(IS_RETURN_VALUE_USED_MASK); + } + + public void updateReturnValueTemplate(PsiExpression expression) { + if (myReturnValueTemplate == null) return; + + if (getSuperMethods().size() > 0) { + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + refSuper.updateReturnValueTemplate(expression); + } + } else { + String newTemplate = null; + if (expression instanceof PsiLiteralExpression) { + PsiLiteralExpression psiLiteralExpression = (PsiLiteralExpression) expression; + newTemplate = psiLiteralExpression.getText(); + } else if (expression instanceof PsiReferenceExpression) { + PsiReferenceExpression referenceExpression = (PsiReferenceExpression) expression; + PsiElement resolved = referenceExpression.resolve(); + if (resolved instanceof PsiField) { + PsiField psiField = (PsiField) resolved; + if (psiField.hasModifierProperty(PsiModifier.STATIC) && + psiField.hasModifierProperty(PsiModifier.FINAL) && + RefUtil.compareAccess(RefUtil.getAccessModifier(psiField), getAccessModifier()) >= 0) { + newTemplate = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_FQ_NAME, PsiSubstitutor.EMPTY); + } + } + } else if (RefUtil.isCallToSuperMethod(expression, (PsiMethod) getElement())) return; + + if (myReturnValueTemplate == RETURN_VALUE_UNDEFINED) { + myReturnValueTemplate = newTemplate; + } else if (!Comparing.equal(myReturnValueTemplate, newTemplate)) { + myReturnValueTemplate = null; + } + } + } + + public void updateParameterValues(PsiExpression[] args) { + if (isLibraryOverride()) return; + + if (getSuperMethods().size() > 0) { + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + refSuper.updateParameterValues(args); + } + } else { + if (myParameters.length == args.length) { + for (int i = 0; i < myParameters.length; i++) { + RefParameter refParameter = myParameters[i]; + refParameter.updateTemplateValue(args[i]); + } + } + } + } + + public String getReturnValueIfSame() { + if (myReturnValueTemplate == RETURN_VALUE_UNDEFINED) return null; + return myReturnValueTemplate; + } + + public void updateThrowsList(PsiClassType exceptionType) { + if (getSuperMethods().size() > 0) { + for (Iterator iterator = getSuperMethods().iterator(); iterator.hasNext();) { + RefMethod refSuper = iterator.next(); + refSuper.updateThrowsList(exceptionType); + } + } else if (myUnThrownExceptions != null) { + if (exceptionType == null) { + myUnThrownExceptions = null; + return; + } + + PsiClassType[] arrayed = myUnThrownExceptions.toArray(new PsiClassType[myUnThrownExceptions.size()]); + for (int i = arrayed.length - 1; i >= 0; i--) { + PsiClassType classType = arrayed[i]; + if (classType.isAssignableFrom(exceptionType)) { + myUnThrownExceptions.remove(i); + } + } + + if (myUnThrownExceptions.size() == 0) myUnThrownExceptions = null; + } + } + + public PsiClassType[] getUnThrownExceptions() { + if (myUnThrownExceptions == null) return null; + return myUnThrownExceptions.toArray(new PsiClassType[myUnThrownExceptions.size()]); + } + + public boolean isOverridesDeprecated() { + return checkFlag(IS_OVERRIDES_DEPRECATED_MASK); + } + + private void setOverridesDeprecated(boolean overridesDeprecated) { + setFlag(overridesDeprecated, IS_OVERRIDES_DEPRECATED_MASK); + } + + public void setAccessModifier(String am) { + super.setAccessModifier(am); + if (am == PsiModifier.PRIVATE && getOwner() != null && !(getOwnerClass().getOwner() instanceof RefElement)) { + setCanBeFinal(false); + } + } + + private void setLibraryOverride(boolean libraryOverride) { + setFlag(libraryOverride, IS_LIBRARY_OVERRIDE_MASK); + } + + private void setAppMain(boolean appMain) { + setFlag(appMain, IS_APPMAIN_MASK); + } + + private void setAbstract(boolean anAbstract) { + setFlag(anAbstract, IS_ABSTRACT_MASK); + } + + private void setBodyEmpty(boolean bodyEmpty) { + setFlag(bodyEmpty, IS_BODY_EMPTY_MASK); + } + + private void setOnlyCallsSuper(boolean onlyCallsSuper) { + setFlag(onlyCallsSuper, IS_ONLY_CALLS_SUPER_MASK); + } + + private void setEjbDeclaration(boolean ejbDeclaration) { + setFlag(ejbDeclaration, IS_EJB_DECLARATION_MASK); + } + + private void setEjbImplementation(boolean ejbImplementation) { + setFlag(ejbImplementation, IS_EJB_IMPLEMENTATION_MASK); + } + + private void setConstructor(boolean constructor) { + setFlag(constructor, IS_CONSTRUCTOR_MASK); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefPackage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefPackage.java new file mode 100644 index 00000000000..5dd1678dd69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefPackage.java @@ -0,0 +1,29 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 15, 2001 + * Time: 5:17:38 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + + + +public class RefPackage extends RefEntity { + private final String myQualifiedName; + + public RefPackage(String name) { + super(getPackageSuffix(name)); + myQualifiedName = name; + } + + public String getQualifiedName() { + return myQualifiedName; + } + + private static String getPackageSuffix(String fullName) { + int dotIndex = fullName.lastIndexOf('.'); + return (dotIndex >= 0) ? fullName.substring(dotIndex + 1) : fullName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefParameter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefParameter.java new file mode 100644 index 00000000000..def7af19517 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefParameter.java @@ -0,0 +1,100 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 4:35:07 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; + +public class RefParameter extends RefElement { + private static final int USED_FOR_READING_MASK = 0x10000; + private static final int USED_FOR_WRITING_MASK = 0x20000; + private static final String VALUE_UNDEFINED = "#"; + + private final short myIndex; + private String myActualValueTemplate; + + public RefParameter(PsiParameter parameter, int index, RefManager manager) { + super(parameter, manager); + + myIndex = (short)index; + myActualValueTemplate = VALUE_UNDEFINED; + } + + public void parameterReferenced(boolean forWriting) { + if (forWriting) { + setUsedForWriting(); + } else { + setUsedForReading(); + } + } + + public boolean isUsedForReading() { + return checkFlag(USED_FOR_READING_MASK); + } + + private void setUsedForReading() { + setFlag(true, USED_FOR_READING_MASK); + } + + public boolean isUsedForWriting() { + return checkFlag(USED_FOR_WRITING_MASK); + } + + private void setUsedForWriting() { + setFlag(true, USED_FOR_WRITING_MASK); + } + + public void accept(RefVisitor visitor) { + visitor.visitParameter(this); + } + + public int getIndex() { + return myIndex; + } + + protected void initialize(PsiElement elem) { + // Empty is important here. Final modifier is externally set by RefMethod.buildReferences. + } + + public void updateTemplateValue(PsiExpression expression) { + if (myActualValueTemplate == null) return; + + String newTemplate = null; + if (expression instanceof PsiLiteralExpression) { + PsiLiteralExpression psiLiteralExpression = (PsiLiteralExpression) expression; + newTemplate = psiLiteralExpression.getText(); + } else if (expression instanceof PsiReferenceExpression) { + PsiReferenceExpression referenceExpression = (PsiReferenceExpression) expression; + PsiElement resolved = referenceExpression.resolve(); + if (resolved instanceof PsiField) { + PsiField psiField = (PsiField) resolved; + if (psiField.hasModifierProperty(PsiModifier.STATIC) && + psiField.hasModifierProperty(PsiModifier.FINAL)) { + newTemplate = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_FQ_NAME, PsiSubstitutor.EMPTY); + } + } + } + + if (myActualValueTemplate == VALUE_UNDEFINED) { + myActualValueTemplate = newTemplate; + } else if (!Comparing.equal(myActualValueTemplate, newTemplate)) { + myActualValueTemplate = null; + } + } + + public String getActualValueIfSame() { + if (myActualValueTemplate == VALUE_UNDEFINED) return null; + return myActualValueTemplate; + } + + public void initializeFinalFlag() { + setIsFinal(getElement().hasModifierProperty(PsiModifier.FINAL)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefProject.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefProject.java new file mode 100644 index 00000000000..aa293329792 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefProject.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 16, 2001 + * Time: 12:50:45 AM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +public class RefProject extends RefEntity { + private final RefManager myRefManager; + private RefPackage myDefaultPackage; + + public RefProject(RefManager refManager) { + super(RefUtil.getProjectFileName(refManager.getProject())); + myRefManager = refManager; + } + + private RefManager getRefManager() { + return myRefManager; + } + + public RefPackage getDefaultPackage() { + if (myDefaultPackage == null) { + myDefaultPackage = getRefManager().getPackage("default package"); + } + + return myDefaultPackage; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefUtil.java new file mode 100644 index 00000000000..5c59329257a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefUtil.java @@ -0,0 +1,514 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 6:03:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +import com.intellij.codeInspection.ex.EntryPointsManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.util.*; + +import java.util.ArrayList; +import java.util.Iterator; + +public class RefUtil { + private RefUtil() {} + + public static void addReferences(final PsiModifierListOwner psiFrom, final RefElement refFrom, PsiElement findIn) { + if (findIn != null) { + findIn.accept( + new PsiRecursiveElementVisitor() { + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + + PsiElement psiResolved = expression.resolve(); + + if (psiResolved instanceof PsiModifierListOwner) { + updateCanBeStatic(refFrom, psiFrom, (PsiModifierListOwner)psiResolved); + if (isDeprecated(psiResolved)) refFrom.setUsesDeprecatedApi(true); + } + + RefElement refResolved = refFrom.getRefManager().getReference(psiResolved); + refFrom.addReference( + refResolved, psiResolved, psiFrom, PsiUtil.isAccessedForWriting(expression), + PsiUtil.isAccessedForReading(expression), expression + ); + + if (refResolved instanceof RefMethod) { + updateRefMethod(psiResolved, refResolved, expression, psiFrom, refFrom); + } + } + + public void visitThisExpression(PsiThisExpression expression) { + super.visitThisExpression(expression); + PsiJavaCodeReferenceElement qualifier = expression.getQualifier(); + if (qualifier != null) { + PsiClass psiClass = (PsiClass)qualifier.resolve(); + if (psiClass != null) { + updateCanBeStatic(refFrom, psiFrom, + MethodSignatureUtil.findMethodBySignature(psiClass, + MethodSignatureUtil.createMethodSignature("hashCode", (PsiType[])null, null, PsiSubstitutor.EMPTY), + true)); + } + } + refFrom.setCanBeStatic(false); + } + + public void visitNewExpression(PsiNewExpression newExpr) { + super.visitNewExpression(newExpr); + PsiMethod psiConstructor = newExpr.resolveConstructor(); + + if (psiConstructor != null) { + updateCanBeStatic(refFrom, psiFrom, psiConstructor.getContainingClass()); + if (isDeprecated(psiConstructor)) refFrom.setUsesDeprecatedApi(true); + } + + RefMethod refConstructor = (RefMethod)refFrom.getRefManager().getReference( + psiConstructor + ); + refFrom.addReference(refConstructor, psiConstructor, psiFrom, false, true, null); + + if (newExpr.getArgumentList() != null) { + PsiExpression[] psiParams = newExpr.getArgumentList().getExpressions(); + for (int i = 0; i < psiParams.length; i++) { + PsiExpression param = psiParams[i]; + param.accept(this); + } + + if (refConstructor != null) { + refConstructor.updateParameterValues(psiParams); + } + } + + if (refConstructor == null) { // No explicit constructor referenced. Should use default one. + PsiType newType = newExpr.getType(); + if (newType instanceof PsiClassType) { + PsiClass psiClass = PsiUtil.resolveClassInType(newType); + + RefClass refClass = (RefClass)refFrom.getRefManager().getReference(psiClass); + + if (psiClass != null) { + updateCanBeStatic(refFrom, psiFrom, psiClass); + } + + if (refClass != null) { + RefMethod refDefaultConstructor = refClass.getDefaultConstructor(); + + if (refDefaultConstructor != null) { + refDefaultConstructor.addInReference(refFrom); + refFrom.addOutReference(refDefaultConstructor); + } + else { + refFrom.addReference(refClass, psiClass, psiFrom, false, true, null); + } + } + } + } + } + + public void visitAnonymousClass(PsiAnonymousClass psiClass) { + RefClass refClass = (RefClass)refFrom.getRefManager().getReference(psiClass); + refFrom.addReference(refClass, psiClass, psiFrom, false, true, null); + } + + public void visitReturnStatement(PsiReturnStatement statement) { + super.visitReturnStatement(statement); + + if (refFrom instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refFrom; + refMethod.updateReturnValueTemplate(statement.getReturnValue()); + } + } + + public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { + super.visitClassObjectAccessExpression(expression); + final PsiTypeElement operand = expression.getOperand(); + if (operand == null) return; + final PsiType type = operand.getType(); + if (type instanceof PsiClassType) { + PsiClassType classType = (PsiClassType)type; + PsiClass psiClass = classType.resolve(); + if (psiClass != null) { + RefClass refClass = (RefClass)refFrom.getRefManager().getReference(psiClass); + if (refClass != null) { + RefMethod refDefaultConstructor = refClass.getDefaultConstructor(); + + if (refDefaultConstructor != null) { + refDefaultConstructor.addInReference(refFrom); + refFrom.addOutReference(refDefaultConstructor); + } + else { + refFrom.addReference(refClass, psiClass, psiFrom, false, true, null); + } + } + } + } + } + } + ); + } + } + + private static void updateRefMethod(PsiElement psiResolved, + RefElement refResolved, + PsiElement refExpression, + final PsiElement psiFrom, + final RefElement refFrom) { + PsiMethod psiMethod = (PsiMethod)psiResolved; + RefMethod refMethod = (RefMethod)refResolved; + + PsiMethodCallExpression call = PsiTreeUtil.getParentOfType( + refExpression, + PsiMethodCallExpression.class + ); + if (call != null) { + PsiType returnType = psiMethod.getReturnType(); + if (!psiMethod.isConstructor() && returnType != PsiType.VOID) { + if (!(call.getParent() instanceof PsiExpressionStatement)) { + refMethod.setReturnValueUsed(true); + } + + addTypeReference(psiFrom, returnType, refFrom.getRefManager()); + } + + PsiExpressionList argumentList = call.getArgumentList(); + if (argumentList != null && argumentList.getExpressions().length > 0) { + refMethod.updateParameterValues(argumentList.getExpressions()); + } + } + } + + public static String getName(PsiElement element) { + if (element instanceof PsiAnonymousClass) { + PsiAnonymousClass psiAnonymousClass = (PsiAnonymousClass)element; + PsiClass psiBaseClass = psiAnonymousClass.getBaseClassType().resolve(); + return "anonymous (" + (psiBaseClass != null ? psiBaseClass.getQualifiedName() : "") + ")"; + } + + String name = null; + if (element instanceof PsiNamedElement) { + name = ((PsiNamedElement)element).getName(); + } + + return name == null ? "anonymous" : name; + } + + public static boolean isDeprecated(PsiElement psiResolved) { + if (psiResolved instanceof PsiDocCommentOwner) { + return ((PsiDocCommentOwner)psiResolved).isDeprecated(); + } + return false; + } + + public static boolean belongsToScope(PsiElement psiElement, RefManager refManager) { + if (psiElement instanceof PsiCompiledElement) return false; + if (psiElement instanceof PsiPackage) return false; //? + if (psiElement instanceof PsiTypeParameter) return false; + if (!psiElement.getManager().isInProject(psiElement)) return false; + + return refManager.getScope() != null ? refManager.getScope().contains(psiElement) : true; + } + + public static boolean isAppMain(PsiMethod psiMethod, RefMethod refMethod) { + if (!refMethod.isStatic()) return false; + + PsiMethod appMainPattern = refMethod.getRefManager().getAppMainPattern(); + return MethodSignatureUtil.areSignaturesEqual(psiMethod, appMainPattern); + } + + public static RefPackage getPackage(RefEntity refEntity) { + while (refEntity != null && !(refEntity instanceof RefPackage)) refEntity = refEntity.getOwner(); + + return (RefPackage)refEntity; + } + + public static String getProjectFileName(Project project) { + VirtualFile projectFile = project.getProjectFile(); + if (projectFile == null) return ""; + return projectFile.getName(); + } + + + public static RefClass getTopLevelClass(RefElement refElement) { + RefEntity refParent = refElement.getOwner(); + + while (!(refParent instanceof RefPackage)) { + refElement = (RefElement)refParent; + refParent = refParent.getOwner(); + } + + return (RefClass)refElement; + } + + public static boolean isInheritor(RefClass subClass, RefClass superClass) { + if (subClass == superClass) return true; + + for (Iterator iterator = subClass.getBaseClasses().iterator(); iterator.hasNext();) { + RefClass baseClass = iterator.next(); + if (isInheritor(baseClass, superClass)) return true; + } + + return false; + } + + public static boolean isInheritor(PsiClass subClass, PsiClass superClass) { + if (samePsiElement(subClass, superClass)) return true; + + return subClass.isInheritor(superClass, true); + } + + public static String getPackageName(RefEntity refEntity) { + RefPackage refPackage = getPackage(refEntity); + + return refPackage == null ? "default package" : refPackage.getQualifiedName(); + } + + public static String getQualifiedName(RefEntity refEntity) { + String result; + + if (refEntity == null || refEntity instanceof RefElement && !((RefElement)refEntity).isValid()) return "invalid"; + + if (refEntity instanceof RefPackage) { + result = ((RefPackage)refEntity).getQualifiedName(); + } + else if (refEntity.getOwner() == null) { + result = refEntity.getName(); + } + else if (refEntity instanceof RefClass && ((RefClass)refEntity).isAnonymous()) { + result = refEntity.getName() + " in " + getQualifiedName(refEntity.getOwner()); + } + else if (refEntity instanceof RefMethod && ((RefMethod)refEntity).getOwnerClass().isAnonymous()) { + result = "anonymous." + refEntity.getName(); + } + else { + result = refEntity.getName(); + + RefEntity refParent = refEntity.getOwner(); + while (refParent != null && !(refParent instanceof RefProject) && !(refParent instanceof RefPackage)) { + result = refParent.getName() + "." + result; + refParent = refParent.getOwner(); + } + } + + return result; + } + + public static String getAccessModifier(PsiModifierListOwner psiElement) { + if (psiElement instanceof PsiParameter) return PsiModifier.PACKAGE_LOCAL; + + PsiModifierList list = psiElement.getModifierList(); + String result = PsiModifier.PACKAGE_LOCAL; + + if (list != null) { + if (list.hasModifierProperty(PsiModifier.PRIVATE)) { + result = PsiModifier.PRIVATE; + } + else if (list.hasModifierProperty(PsiModifier.PROTECTED)) { + result = PsiModifier.PROTECTED; + } + else if (list.hasModifierProperty(PsiModifier.PUBLIC)) { + result = PsiModifier.PUBLIC; + } + else if (psiElement.getParent() instanceof PsiClass) { + PsiClass ownerClass = (PsiClass)psiElement.getParent(); + if (ownerClass.isInterface()) { + result = PsiModifier.PUBLIC; + } + } + } + + return result; + } + + public static RefClass getOwnerClass(RefManager refManager, PsiElement psiElement) { + while (psiElement != null && !(psiElement instanceof PsiClass)) { + psiElement = psiElement.getParent(); + } + + return psiElement != null ? (RefClass)refManager.getReference(psiElement) : null; + } + + public static RefClass getOwnerClass(RefElement refElement) { + RefEntity parent = refElement.getOwner(); + + while (!(parent instanceof RefClass) && parent instanceof RefElement) { + parent = parent.getOwner(); + } + + if (parent instanceof RefClass) return (RefClass)parent; + + return null; + } + + public static PsiClass getPsiOwnerClass(PsiElement psiElement) { + PsiElement parent = psiElement.getParent(); + + while (!(parent instanceof PsiClass) && !(parent instanceof PsiFile) && parent != null) { + parent = parent.getParent(); + } + + if (parent != null && parent instanceof PsiClass) return (PsiClass)parent; + + return null; + } + + static boolean samePsiElement(PsiElement e1, PsiElement e2) { + PsiManager manager = e1.getManager(); + + return manager.areElementsEquivalent(e1, e2); + } + + public static boolean isAnonymousClass(RefElement element) { + if (element instanceof RefClass) { + if (((RefClass)element).isAnonymous()) return true; + } + + return false; + } + + public static boolean isMethodOnlyCallsSuper(PsiMethod method) { + boolean hasStatements = false; + PsiCodeBlock body = method.getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + for (int i = 0; i < statements.length; i++) { + PsiStatement statement = statements[i]; + + boolean isCallToSameSuper = false; + if (statement instanceof PsiExpressionStatement) { + isCallToSameSuper = isCallToSuperMethod(((PsiExpressionStatement)statement).getExpression(), method); + } + else if (statement instanceof PsiReturnStatement) { + PsiExpression expression = ((PsiReturnStatement)statement).getReturnValue(); + isCallToSameSuper = expression == null || isCallToSuperMethod(expression, method); + } + + hasStatements = true; + if (isCallToSameSuper) continue; + + return false; + } + } + + return hasStatements; + } + + public static boolean isCallToSuperMethod(PsiExpression expression, PsiMethod method) { + if (expression instanceof PsiMethodCallExpression) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression; + if (methodCall.getMethodExpression().getQualifierExpression() instanceof PsiSuperExpression) { + PsiMethod superMethod = (PsiMethod)methodCall.getMethodExpression().resolve(); + if (superMethod == null || !MethodSignatureUtil.areSignaturesEqual(method, superMethod)) return false; + PsiExpression[] args = methodCall.getArgumentList().getExpressions(); + PsiParameter[] parms = method.getParameterList().getParameters(); + + for (int i = 0; i < args.length; i++) { + PsiExpression arg = args[i]; + if (!(arg instanceof PsiReferenceExpression)) return false; + if (!parms[i].equals(((PsiReferenceExpression)arg).resolve())) return false; + } + + return true; + } + } + + return false; + } + + public static int compareAccess(String a1, String a2) { + int i1 = getAccessNumber(a1); + int i2 = getAccessNumber(a2); + + if (i1 == i2) return 0; + if (i1 < i2) return -1; + return 1; + } + + private static int getAccessNumber(String a) { + if (a == PsiModifier.PRIVATE) { + return 0; + } + else if (a == PsiModifier.PACKAGE_LOCAL) { + return 1; + } + else if (a == PsiModifier.PROTECTED) { + return 2; + } + else if (a == PsiModifier.PUBLIC) return 3; + + return -1; + } + + public static void removeRefElement(RefElement refElement, ArrayList deletedRefs) { + if (refElement.isEntry()) { + EntryPointsManager.getInstance(refElement.getRefManager().getProject()).removeEntryPoint(refElement); + } + + ArrayList children = refElement.getChildren(); + if (children != null) { + RefElement[] refElements = (RefElement[])children.toArray(new RefElement[children.size()]); + for (int i = 0; i < refElements.length; i++) { + RefElement refChild = refElements[i]; + removeRefElement(refChild, deletedRefs); + } + } + + refElement.getRefManager().removeReference(refElement); + refElement.referenceRemoved(); + if (!deletedRefs.contains(refElement)) deletedRefs.add(refElement); + } + + public static void addTypeReference(PsiElement psiElement, PsiType psiType, RefManager refManager) { + RefClass ownerClass = getOwnerClass(refManager, psiElement); + + if (ownerClass != null) { + psiType = psiType.getDeepComponentType(); + + if (psiType instanceof PsiClassType) { + PsiClass psiClass = PsiUtil.resolveClassInType(psiType); + if (psiClass != null && belongsToScope(psiClass, refManager)) { + RefClass refClass = (RefClass)refManager.getReference(psiClass); + if (refClass != null) { + refClass.addTypeReference(ownerClass); + } + } + } + } + } + + public static void updateCanBeStatic(RefElement refElement, PsiModifierListOwner psiThis, PsiModifierListOwner psiWhat) { + if (refElement.getOwner() instanceof RefPackage) return; + + if (psiWhat instanceof PsiLocalVariable || psiWhat instanceof PsiParameter) return; + + if (psiThis.hasModifierProperty(PsiModifier.STATIC)) return; + + if (psiThis instanceof PsiAnonymousClass) { + RefElement refOwner = (RefElement)refElement.getOwner(); + updateCanBeStatic(refOwner, refOwner.getElement(), psiWhat); + } + else if (!psiWhat.hasModifierProperty(PsiModifier.STATIC)) { + PsiClass whatClass = getPsiOwnerClass(psiWhat); + PsiClass myClass = getPsiOwnerClass(psiThis); + + if (whatClass == null || myClass == null) return; + + if (isInheritor(myClass, whatClass)) { + refElement.setCanBeStatic(false); + if (refElement instanceof RefClass) return; + } + + RefElement refMyClass = refElement.getRefManager().getReference(myClass); + updateCanBeStatic(refMyClass, myClass, psiWhat); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefVisitor.java new file mode 100644 index 00000000000..37e862a9309 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/reference/RefVisitor.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Oct 21, 2001 + * Time: 10:13:46 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.reference; + +public class RefVisitor { + public void visitElement(RefElement elem) { + + } + + public void visitField(RefField field) { + visitElement(field); + } + + public void visitMethod(RefMethod method) { + visitElement(method); + } + + public void visitParameter(RefParameter parameter) { + visitElement(parameter); + } + + public void visitClass(RefClass aClass) { + visitElement(aClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java new file mode 100644 index 00000000000..1ff603d186a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java @@ -0,0 +1,95 @@ +package com.intellij.codeInspection.sameParameterValue; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.ex.ProblemDescriptorImpl; +import com.intellij.codeInspection.reference.*; +import com.intellij.psi.PsiReference; + +import java.util.ArrayList; + +/** + * @author max + */ +public class SameParameterValueInspection extends DescriptorProviderInspection { + public SameParameterValueInspection() { + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + ProblemDescriptor[] descriptors = checkMethod(refMethod); + if (descriptors != null) { + addProblemElement(refElement, descriptors); + } + } + } + }); + } + + private ProblemDescriptor[] checkMethod(RefMethod refMethod) { + if (refMethod.isLibraryOverride()) return null; + if (!refMethod.getSuperMethods().isEmpty()) return null; + + ArrayList problems = null; + RefParameter[] parameters = refMethod.getParameters(); + for (int i = 0; i < parameters.length; i++) { + RefParameter refParameter = parameters[i]; + String value = refParameter.getActualValueIfSame(); + if (value != null) { + if (problems == null) problems = new ArrayList(1); + problems.add(getManager().createProblemDescriptor(refMethod.getElement(), + "Actual value of parameter '" + refParameter.getName() + + "' value is always '" + value + "'.", + null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); + } + } + + return problems == null ? null : (ProblemDescriptor[]) problems.toArray(new ProblemDescriptorImpl[problems.size()]); + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (getDescriptions(refElement) != null) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + getManager().enqueueMethodUsagesProcessor(refMethod, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + ignoreElement(refMethod); + return false; + } + }); + } + }); + } + } + }); + + return false; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return "Actual method parameter is the same constant"; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return "SameParameterValue"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameReturnValue/SameReturnValueInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameReturnValue/SameReturnValueInspection.java new file mode 100644 index 00000000000..fb39bf2d6d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/sameReturnValue/SameReturnValueInspection.java @@ -0,0 +1,97 @@ +package com.intellij.codeInspection.sameReturnValue; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefMethod; +import com.intellij.codeInspection.reference.RefVisitor; +import com.intellij.psi.PsiMethod; + +/** + * @author max + */ +public class SameReturnValueInspection extends DescriptorProviderInspection { + public SameReturnValueInspection() { + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + ProblemDescriptor[] descriptors = checkMethod(refMethod); + if (descriptors != null) { + addProblemElement(refElement, descriptors); + } + } + } + }); + } + + private ProblemDescriptor[] checkMethod(RefMethod refMethod) { + if (refMethod.isConstructor()) return null; + if (refMethod.isLibraryOverride()) return null; + + if (!refMethod.getSuperMethods().isEmpty()) return null; + + String returnValue = refMethod.getReturnValueIfSame(); + if (returnValue != null) { + final String messagePrefix; + if (refMethod.getDerivedMethods().isEmpty()) { + messagePrefix = "Method always returns "; + } else if (refMethod.hasBody()) { + messagePrefix = "Method and all its deriveables always return "; + } else { + messagePrefix = "All implementations of this method always return "; + } + + return new ProblemDescriptor[] {getManager().createProblemDescriptor(refMethod.getElement(), messagePrefix + returnValue + ".", null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)}; + } + + return null; + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (getDescriptions(refElement) != null) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + getManager().enqueueDerivedMethodsProcessing(refMethod, new InspectionManagerEx.DerivedMethodsProcessor() { + public boolean process(PsiMethod derivedMethod) { + ignoreElement(refMethod); + return false; + } + }); + } + }); + } + } + }); + + return false; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return "Method returns the same value"; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return "SameReturnValue"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/Browser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/Browser.java new file mode 100644 index 00000000000..e6403ecbc93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/Browser.java @@ -0,0 +1,258 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.HTMLComposer; +import com.intellij.codeInspection.ex.InspectionTool; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.reference.RefImplicitConstructor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiElement; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLFrameHyperlinkEvent; +import java.awt.*; +import java.io.IOException; +import java.io.StringReader; +import java.net.URL; +import java.util.ArrayList; + +public class Browser extends JPanel { + private final ArrayList myClickListeners; + private RefEntity myCurrentEntity; + private final JEditorPane myHTMLViewer; + private InspectionResultsView myView; + + public static class ClickEvent { + public static final int REF_ELEMENT = 1; + public static final int FILE_OFFSET = 2; + private final VirtualFile myFile; + private final int myStartPosition; + private final int myEndPosition; + private final RefElement refElement; + private final int myEventType; + + public ClickEvent(VirtualFile myFile, int myStartPosition, int myEndPosition) { + this.myFile = myFile; + this.myStartPosition = myStartPosition; + this.myEndPosition = myEndPosition; + myEventType = FILE_OFFSET; + refElement = null; + } + + public int getEventType() { + return myEventType; + } + + public VirtualFile getFile() { + return myFile; + } + + public int getStartOffset() { + return myStartPosition; + } + + public int getEndOffset() { + return myEndPosition; + } + + public RefElement getClickedElement() { + return refElement; + } + + } + + public interface ClickListener { + void referenceClicked(ClickEvent e); + } + + private void showPageFromHistory(RefEntity newEntity) { + try { + String html = generateHTML(newEntity); + myHTMLViewer.read(new StringReader(html), null); + myHTMLViewer.setCaretPosition(0); + myCurrentEntity = newEntity; + } + catch (Exception e) { + showEmpty(); + } + } + + public void showPageFor(RefElement refElement, ProblemDescriptor descriptor) { + try { + myCurrentEntity = refElement; + String html = generateHTML(refElement, descriptor); + myHTMLViewer.read(new StringReader(html), null); + myHTMLViewer.setCaretPosition(0); + } + catch (Exception e) { + showEmpty(); + } + } + + public void showPageFor(RefEntity newEntity) { + if (newEntity instanceof RefImplicitConstructor) { + newEntity = ((RefImplicitConstructor)newEntity).getOwnerClass(); + } + + if (newEntity != myCurrentEntity) { + showPageFromHistory(newEntity); + } + } + + public Browser(InspectionResultsView view) { + super(new BorderLayout()); + myView = view; + + myClickListeners = new ArrayList(); + myCurrentEntity = null; + + myHTMLViewer = new JEditorPane("text/html", "Select tree node for detailed information"); + myHTMLViewer.setEditable(false); + myHTMLViewer.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + JEditorPane pane = (JEditorPane)e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e; + HTMLDocument doc = (HTMLDocument)pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + } + else { + try { + URL url = e.getURL(); + String ref = url.getRef(); + if (ref.startsWith("pos:")) { + int delimeterPos = ref.indexOf(':', "pos:".length() + 1); + String startPosition = ref.substring("pos:".length(), delimeterPos); + String endPosition = ref.substring(delimeterPos + 1); + Integer textStartOffset = new Integer(startPosition); + Integer textEndOffset = new Integer(endPosition); + String fileURL = url.toExternalForm(); + fileURL = fileURL.substring(0, fileURL.indexOf('#')); + VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL); + if (vFile != null) { + fireClickEvent(vFile, textStartOffset.intValue(), textEndOffset.intValue()); + } + } + else if (ref.startsWith("descr:")) { + int descriptionIndex = Integer.parseInt(ref.substring("descr:".length())); + ProblemDescriptor descriptor = ((DescriptorProviderInspection)getTool()).getDescriptions( + (RefElement)myCurrentEntity)[descriptionIndex]; + PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement == null) return; + VirtualFile vFile = psiElement.getContainingFile().getVirtualFile(); + if (vFile != null) { + TextRange range = psiElement.getTextRange(); + fireClickEvent(vFile, range.getStartOffset(), range.getEndOffset()); + } + } + else if (ref.startsWith("invoke:")) { + int actionNumber = Integer.parseInt(ref.substring("invoke:".length())); + getTool().getQuickFixes()[actionNumber].doApplyFix(new RefElement[]{(RefElement)myCurrentEntity}); + } + else if (ref.startsWith("invokelocal:")) { + myView.invokeLocalFix(); + } + else { + int offset = Integer.parseInt(ref); + String fileURL = url.toExternalForm(); + fileURL = fileURL.substring(0, fileURL.indexOf('#')); + VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL); + if (vFile != null) { + fireClickEvent(vFile, offset, offset); + } + } + } + catch (Throwable t) { + t.printStackTrace(); + } + } + } + } + }); + + add(new JScrollPane(myHTMLViewer), BorderLayout.CENTER); + } + + public void addClickListener(ClickListener listener) { + myClickListeners.add(listener); + } + + private void fireClickEvent(VirtualFile file, int startPosition, int endPosition) { + ClickEvent e = new ClickEvent(file, startPosition, endPosition); + + for (int i = 0; i < myClickListeners.size(); i++) { + ClickListener listener = (ClickListener)myClickListeners.get(i); + listener.referenceClicked(e); + } + } + + private String generateHTML(final RefEntity refEntity) { + final StringBuffer buf = new StringBuffer(); + if (refEntity instanceof RefElement) { + final Runnable action = new Runnable() { + public void run() { + getComposer().compose(buf, refEntity); + } + }; + ApplicationManager.getApplication().runReadAction(action); + } + else { + getComposer().compose(buf, refEntity); + } + + uppercaseFirstLetter(buf); + + buf.insert(0, ""); + buf.append(""); + + return buf.toString(); + } + + private String generateHTML(final RefElement refElement, final ProblemDescriptor descriptor) { + final StringBuffer buf = new StringBuffer(); + final Runnable action = new Runnable() { + public void run() { + getComposer().compose(buf, refElement, descriptor); + } + }; + ApplicationManager.getApplication().runReadAction(action); + + uppercaseFirstLetter(buf); + + buf.insert(0, ""); + buf.append(""); + + return buf.toString(); + } + + private void uppercaseFirstLetter(final StringBuffer buf) { + if (buf.length() > 1) { + char[] firstLetter = new char[1]; + buf.getChars(0, 1, firstLetter, 0); + buf.setCharAt(0, Character.toUpperCase(firstLetter[0])); + } + } + + public void showEmpty() { + myCurrentEntity = null; + try { + myHTMLViewer.read(new StringReader(""), null); + } + catch (IOException e) { + } + } + + private InspectionTool getTool() { return myView.getSelectedTool(); } + + private HTMLComposer getComposer() { return getTool().getComposer(); } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/EntryPointsNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/EntryPointsNode.java new file mode 100644 index 00000000000..a374ad800d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/EntryPointsNode.java @@ -0,0 +1,20 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.deadCode.DummyEntryPointsTool; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * @author max + */ +public class EntryPointsNode extends InspectionNode { + private static final Icon ENTRY_POINTS = IconLoader.getIcon("/nodes/entryPoints.png"); + public EntryPointsNode(DummyEntryPointsTool tool) { + super(tool); + } + + public Icon getIcon(boolean expanded) { + return ENTRY_POINTS; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionGroupNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionGroupNode.java new file mode 100644 index 00000000000..d51af2d5df3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionGroupNode.java @@ -0,0 +1,29 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; + +import javax.swing.*; + +/** + * @author max + */ +public class InspectionGroupNode extends InspectionTreeNode { + private static final Icon EMPTY = EmptyIcon.create(0, IconUtilEx.getEmptyIcon(false).getIconHeight()); + + public InspectionGroupNode(String groupTitle) { + super(groupTitle); + } + + public String getGroupTitle() { + return (String) getUserObject(); + } + + public Icon getIcon(boolean expanded) { + return EMPTY; + } + + public boolean appearsBold() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionNode.java new file mode 100644 index 00000000000..2ffc79dac01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionNode.java @@ -0,0 +1,50 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.ex.InspectionTool; +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.LayeredIcon; + +import javax.swing.*; +import java.util.Enumeration; + +/** + * @author max + */ +public class InspectionNode extends InspectionTreeNode { + public static final Icon TOOL; + + static { + final LayeredIcon layeredIcon = new LayeredIcon(2); + layeredIcon.setIcon(IconLoader.getIcon("/general/toolWindowInspection.png"), 0); + layeredIcon.setIcon(IconUtilEx.getEmptyIcon(false), 1); + TOOL = layeredIcon; + } + + public InspectionNode(InspectionTool tool) { + super(tool); + } + + public String toString() { + return getTool().getDisplayName(); + } + + public InspectionTool getTool() { + return (InspectionTool)getUserObject(); + } + + public Icon getIcon(boolean expanded) { + return TOOL; + } + + public int getProblemCount() { + int sum = 0; + Enumeration children = children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + if (child instanceof EntryPointsNode) continue; + sum += child.getProblemCount(); + } + return sum; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionPackageNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionPackageNode.java new file mode 100644 index 00000000000..2d4cdbf48b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionPackageNode.java @@ -0,0 +1,25 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * @author max + */ +public class InspectionPackageNode extends InspectionTreeNode { + private static final Icon packageOpenIcon = IconLoader.getIcon("/nodes/packageOpen.png"); + private static final Icon packageClosedIcon = IconLoader.getIcon("/nodes/packageClosed.png"); + + public InspectionPackageNode(String packageName) { + super(packageName); + } + + public String getPackageName() { + return (String) getUserObject(); + } + + public Icon getIcon(boolean expanded) { + return expanded ? packageOpenIcon : packageClosedIcon; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionResultsView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionResultsView.java new file mode 100644 index 00000000000..ac1b0982a09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -0,0 +1,741 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.deadCode.DeadCodeInspection; +import com.intellij.codeInspection.deadCode.DummyEntryPointsTool; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.InspectionTool; +import com.intellij.codeInspection.ex.QuickFixAction; +import com.intellij.codeInspection.export.HTMLExportFrameMaker; +import com.intellij.codeInspection.export.HTMLExporter; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.reference.RefImplicitConstructor; +import com.intellij.codeInspection.util.RefEntityAlphabeticalComparator; +import com.intellij.ide.OccurenceNavigator; +import com.intellij.ide.OccurenceNavigatorSupport; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionListPopup; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.ui.ListPopup; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.SmartExpander; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.*; +import java.util.List; + +/** + * @author max + */ +public class InspectionResultsView extends JPanel implements OccurenceNavigator, DataProvider { + public static final RefElement[] EMPTY_ELEMENTS_ARRAY = new RefElement[0]; + public static final ProblemDescriptor[] EMPTY_DESCRIPTORS = new ProblemDescriptor[0]; + private Project myProject; + private InspectionTree myTree; + private Browser myBrowser; + private Splitter mySplitter; + private Map myGroups = null; + private OccurenceNavigator myOccurenceNavigator; + + public InspectionResultsView(final Project project) { + setLayout(new BorderLayout()); + + myProject = project; + myTree = new InspectionTree(project); + myOccurenceNavigator = new OccurenceNavigatorSupport(myTree) { + protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) { + if (node instanceof RefElementNode) { + final RefElementNode refNode = (RefElementNode)node; + if (refNode.hasDescriptorsUnder()) return null; + final RefElement element = refNode.getElement(); + if (element == null || !element.isValid()) return null; + final ProblemDescriptor problem = refNode.getProblem(); + if (problem != null) { + final PsiElement psiElement = problem.getPsiElement(); + if (psiElement == null || !psiElement.isValid()) return null; + return getOpenFileDescriptor(psiElement); + } + return getOpenFileDescriptor(element); + } + else if (node instanceof ProblemDescriptionNode) { + if (!((ProblemDescriptionNode)node).getElement().isValid()) return null; + final PsiElement psiElement = ((ProblemDescriptionNode)node).getDescriptor().getPsiElement(); + + if (psiElement == null || !psiElement.isValid()) return null; + return getOpenFileDescriptor(psiElement); + } + return null; + } + + public String getNextOccurenceActionName() { + return "Go Next Problem"; + } + + public String getPreviousOccurenceActionName() { + return "Go Prev Problem"; + } + }; + + myBrowser = new Browser(this); + + final InspectionManagerEx manager = (InspectionManagerEx)InspectionManager.getInstance(project); + mySplitter = new Splitter(false, manager.getUIOptions().SPLITTER_PROPORTION); + + mySplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree)); + mySplitter.setSecondComponent(myBrowser); + + mySplitter.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { + Float newProportion = (Float)evt.getNewValue(); + manager.setLeftSplitterProportion(newProportion.floatValue()); + } + } + }); + + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + syncBrowser(); + syncSource(); + } + }); + + myTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (!e.isPopupTrigger() && e.getClickCount() == 2) { + Navigatable navigatable = (Navigatable)getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(true); + } + } + } + }); + + myTree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + Navigatable navigatable = (Navigatable)getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(false); + } + } + } + }); + + myTree.addMouseListener(new PopupHandler() { + public void invokePopup(Component comp, int x, int y) { + popupInvoked(comp, x, y); + } + }); + + SmartExpander.installOn(myTree); + + myBrowser.addClickListener(new Browser.ClickListener() { + public void referenceClicked(final Browser.ClickEvent e) { + if (e.getEventType() == Browser.ClickEvent.REF_ELEMENT) { + showSource(e.getClickedElement()); + } + else if (e.getEventType() == Browser.ClickEvent.FILE_OFFSET) { + final VirtualFile file = e.getFile(); + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file, e.getStartOffset()); + Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + TextAttributes selectionAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes( + EditorColors.SEARCH_RESULT_ATTRIBUTES); + HighlightManager.getInstance(project).addRangeHighlight(editor, e.getStartOffset(), e.getEndOffset(), + selectionAttributes, true, new ArrayList()); + } + } + }); + + add(mySplitter, BorderLayout.CENTER); + + DefaultActionGroup commonActionGroup = new DefaultActionGroup(); + manager.addCommonActions(commonActionGroup, this); + commonActionGroup.add(new InvokeQuickFixAction()); + ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.CODE_INSPECTION, + commonActionGroup, false); + add(actionToolbar.getComponent(), BorderLayout.WEST); + } + + private static OpenFileDescriptor getOpenFileDescriptor(PsiElement psiElement) { + return new OpenFileDescriptor(psiElement.getProject(), psiElement.getContainingFile().getVirtualFile(), psiElement.getTextOffset()); + } + + private void syncSource() { + if (isAutoScrollMode()) { + Navigatable navigatable = (Navigatable)getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(false); + } + } + } + + private boolean isAutoScrollMode() { + String activeToolWindowId = ToolWindowManager.getInstance(myProject).getActiveToolWindowId(); + final InspectionManagerEx manager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + return manager.getUIOptions().AUTOSCROLL_TO_SOURCE && + (activeToolWindowId == null || activeToolWindowId.equals(ToolWindowId.INSPECTION)); + } + + private static void showSource(final RefElement refElement) { + OpenFileDescriptor descriptor = getOpenFileDescriptor(refElement); + if (descriptor != null) { + Project project = refElement.getRefManager().getProject(); + FileEditorManager.getInstance(project).openTextEditor(descriptor, false); + } + } + + private static OpenFileDescriptor getOpenFileDescriptor(final RefElement refElement) { + OpenFileDescriptor descriptor = null; + final VirtualFile[] file = new VirtualFile[1]; + final int[] offset = new int[1]; + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + PsiElement psiElement = refElement.getElement(); + if (psiElement != null) { + file[0] = psiElement.getContainingFile().getVirtualFile(); + offset[0] = psiElement.getTextOffset(); + } + else { + file[0] = null; + } + } + }); + + if (file[0] != null) { + descriptor = new OpenFileDescriptor(refElement.getRefManager().getProject(), file[0], offset[0]); + } + return descriptor; + } + + public void syncBrowser() { + if (myTree.getSelectionModel().getSelectionCount() != 1) { + myBrowser.showEmpty(); + } + else { + TreePath pathSelected = myTree.getSelectionModel().getLeadSelectionPath(); + if (pathSelected != null) { + final InspectionTreeNode node = (InspectionTreeNode)pathSelected.getLastPathComponent(); + if (node instanceof RefElementNode) { + final RefElementNode refElementNode = (RefElementNode)node; + if (!refElementNode.hasDescriptorsUnder()) { + final ProblemDescriptor problem = refElementNode.getProblem(); + RefElement refSelected = refElementNode.getElement(); + if (problem != null) { + showInBrowser(refSelected, problem); + } + else { + showInBrowser(refSelected); + } + } + } + else if (node instanceof ProblemDescriptionNode) { + final ProblemDescriptionNode problemNode = (ProblemDescriptionNode)node; + showInBrowser(problemNode.getElement(), problemNode.getDescriptor()); + } + else { + myBrowser.showEmpty(); + } + } + } + } + + public void showInBrowser(final RefEntity refEntity) { + Cursor currentCursor = getCursor(); + setCursor(new Cursor(Cursor.WAIT_CURSOR)); + myBrowser.showPageFor(refEntity); + setCursor(currentCursor); + } + + public void showInBrowser(final RefElement refElement, ProblemDescriptor descriptor) { + Cursor currentCursor = getCursor(); + setCursor(new Cursor(Cursor.WAIT_CURSOR)); + myBrowser.showPageFor(refElement, descriptor); + setCursor(currentCursor); + } + + public void addTool(InspectionTool tool) { + tool.updateContent(); + if (tool.hasReportedProblems()) { + final InspectionNode toolNode = new InspectionNode(tool); + initToolNode(tool, toolNode, getToolParentNode(tool.getGroupDisplayName().length() > 0 ? tool.getGroupDisplayName() : "General")); + if (tool instanceof DeadCodeInspection) { + final DummyEntryPointsTool entryPoints = new DummyEntryPointsTool((DeadCodeInspection)tool); + entryPoints.updateContent(); + initToolNode(entryPoints, new EntryPointsNode(entryPoints), toolNode); + } + regsisterActionShortcuts(tool); + } + } + + private void initToolNode(InspectionTool tool, InspectionNode toolNode, InspectionTreeNode parentNode) { + final InspectionTreeNode[] contents = tool.getContents(); + for (int i = 0; i < contents.length; i++) { + InspectionTreeNode content = contents[i]; + toolNode.add(content); + } + parentNode.add(toolNode); + } + + private void regsisterActionShortcuts(InspectionTool tool) { + final QuickFixAction[] fixes = tool.getQuickFixes(); + if (fixes != null) { + for (int i = 0; i < fixes.length; i++) { + QuickFixAction fix = fixes[i]; + fix.registerCustomShortcutSet(fix.getShortcutSet(), this); + } + } + } + + public boolean update(InspectionTool[] tools) { + myTree.removeAllNodes(); + boolean resultsFound = false; + final InspectionManagerEx manager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + myGroups = new HashMap(); + for (int i = 0; i < tools.length; i++) { + InspectionTool tool = tools[i]; + if (manager.getCurrentProfile().isToolEnabled(HighlightDisplayKey.find(tool.getShortName()))) { + addTool(tool); + resultsFound |= tool.hasReportedProblems(); + } + } + myTree.sort(); + myTree.restoreExpantionAndSelection(); + return resultsFound; + } + + private InspectionTreeNode getToolParentNode(String groupName) { + if (groupName == null || groupName.length() == 0) return myTree.getRoot(); + InspectionGroupNode group = myGroups.get(groupName); + if (group == null) { + group = new InspectionGroupNode(groupName); + myGroups.put(groupName, group); + myTree.getRoot().add(group); + } + return group; + } + + public void exportHTML(HTMLExportFrameMaker frameMaker) { + final InspectionTreeNode root = myTree.getRoot(); + final Enumeration children = root.children(); + while (children.hasMoreElements()) { + InspectionTreeNode node = (InspectionTreeNode)children.nextElement(); + if (node instanceof InspectionNode) { + exportHTML(frameMaker, (InspectionNode)node); + } + else if (node instanceof InspectionGroupNode) { + final Enumeration groupChildren = node.children(); + while (groupChildren.hasMoreElements()) { + InspectionNode toolNode = (InspectionNode)groupChildren.nextElement(); + exportHTML(frameMaker, toolNode); + } + } + } + } + + private void exportHTML(HTMLExportFrameMaker frameMaker, InspectionNode node) { + InspectionTool tool = node.getTool(); + HTMLExporter exporter = new HTMLExporter(frameMaker.getRootFolder() + "/" + tool.getFolderName(), + tool.getComposer(), myProject); + frameMaker.startInspection(tool); + exportHTML(tool, exporter); + exporter.generateReferencedPages(); + } + + public void exportHTML(InspectionTool tool, HTMLExporter exporter) { + StringBuffer packageIndex = new StringBuffer(); + packageIndex.append(""); + + final Map> content = tool.getPackageContent(); + ArrayList packageNames = new ArrayList(content.keySet()); + + Collections.sort(packageNames, RefEntityAlphabeticalComparator.getInstance()); + for (int i = 0; i < packageNames.size(); i++) { + String packageName = packageNames.get(i); + appendPackageReference(packageIndex, packageName); + final ArrayList packageContent = new ArrayList(content.get(packageName)); + Collections.sort(packageContent, RefEntityAlphabeticalComparator.getInstance()); + StringBuffer contentIndex = new StringBuffer(); + contentIndex.append(""); + for (int j = 0; j < packageContent.size(); j++) { + RefElement refElement = packageContent.get(j); + if (refElement instanceof RefImplicitConstructor) { + refElement = ((RefImplicitConstructor)refElement).getOwnerClass(); + } + + contentIndex.append(""); + contentIndex.append(refElement.getName()); + contentIndex.append("
    "); + + exporter.createPage(refElement); + } + + contentIndex.append(""); + HTMLExporter.writeFile(exporter.getRootFolder(), packageName + "-index.html", contentIndex, myProject); + } + + packageIndex.append(""); + + HTMLExporter.writeFile(exporter.getRootFolder(), "index.html", packageIndex, myProject); + } + + private static void appendPackageReference(StringBuffer packageIndex, String packageName) { + packageIndex.append(""); + packageIndex.append(packageName); + packageIndex.append("
    "); + } + + public OccurenceNavigator getOccurenceNavigator() { + return myOccurenceNavigator; + } + + public boolean hasNextOccurence() { + return myOccurenceNavigator.hasNextOccurence(); + } + + public boolean hasPreviousOccurence() { + return myOccurenceNavigator.hasPreviousOccurence(); + } + + public OccurenceNavigator.OccurenceInfo goNextOccurence() { + return myOccurenceNavigator.goNextOccurence(); + } + + public OccurenceNavigator.OccurenceInfo goPreviousOccurence() { + return myOccurenceNavigator.goPreviousOccurence(); + } + + public String getNextOccurenceActionName() { + return myOccurenceNavigator.getNextOccurenceActionName(); + } + + public String getPreviousOccurenceActionName() { + return myOccurenceNavigator.getPreviousOccurenceActionName(); + } + + public void invokeLocalFix() { + if (myTree.getSelectionCount() != 1) return; + final InspectionTreeNode node = (InspectionTreeNode)myTree.getSelectionPath().getLastPathComponent(); + if (node instanceof ProblemDescriptionNode) { + final ProblemDescriptionNode problemNode = (ProblemDescriptionNode)node; + final ProblemDescriptor descriptor = problemNode.getDescriptor(); + final RefElement element = problemNode.getElement(); + invokeFix(element, descriptor); + } + else if (node instanceof RefElementNode) { + RefElementNode elementNode = (RefElementNode)node; + RefElement element = elementNode.getElement(); + ProblemDescriptor descriptor = elementNode.getProblem(); + if (descriptor != null) { + invokeFix(element, descriptor); + } + } + } + + private void invokeFix(final RefElement element, final ProblemDescriptor descriptor) { + final LocalQuickFix fix = descriptor.getFix(); + if (fix != null) { + PsiElement psiElement = element.getElement(); + if (psiElement != null && psiElement.isValid()) { + if (!psiElement.isWritable()) { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + new VirtualFile[]{psiElement.getContainingFile().getVirtualFile()}); + return; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + Runnable command = new Runnable() { + public void run() { + CommandProcessor.getInstance().markCurrentCommandAsComplex(myProject); + fix.applyFix(myProject, descriptor); + } + }; + CommandProcessor.getInstance().executeCommand(myProject, command, fix.getName(), null); + ((DescriptorProviderInspection)getSelectedTool()).ignoreProblem(element, descriptor); + ((InspectionManagerEx)InspectionManager.getInstance(myProject)).refreshViews(); + } + }); + } + } + } + + protected class InvokeQuickFixAction extends AnAction { + public InvokeQuickFixAction() { + super("Apply a quickfix", "Apply an inspection quickfix", IconLoader.getIcon("/actions/createFromUsage.png")); + + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS).getShortcutSet(), + myTree); + } + + public void update(AnActionEvent e) { + if (!isSingleToolInSelection()) { + e.getPresentation().setEnabled(false); + return; + } + + final QuickFixAction[] quickFixes = getSelectedTool().getQuickFixes(); + if (quickFixes == null || quickFixes.length == 0) { + e.getPresentation().setEnabled(false); + return; + } + + ActionGroup fixes = new ActionGroup() { + public AnAction[] getChildren(AnActionEvent e) { + return quickFixes; + } + }; + + e.getPresentation().setEnabled(!ActionListPopup.isGroupEmpty(fixes, e, new java.util.HashMap())); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final QuickFixAction[] quickFixes = getSelectedTool().getQuickFixes(); + ActionGroup fixes = new ActionGroup() { + public AnAction[] getChildren(AnActionEvent e) { + return quickFixes; + } + }; + + ListPopup popup = ActionListPopup.createListPopup(" Accept Resolution ", fixes, dataContext, false, false); + + Point location = getSelectedTreeNodeBounds(); + if (location == null) return; + popup.show(location.x, location.y); + } + + private Point getSelectedTreeNodeBounds() { + int row = myTree.getLeadSelectionRow(); + if (row == -1) return null; + Rectangle rowBounds = myTree.getRowBounds(row); + Point location = rowBounds.getLocation(); + location = new Point(location.x, location.y + rowBounds.height); + SwingUtilities.convertPointToScreen(location, myTree); + return location; + } + } + + public Project getProject() { return myProject; } + + public Object getData(String dataId) { + if (dataId.equals(DataConstantsEx.INSPECTION_VIEW)) return this; + TreePath[] paths = myTree.getSelectionPaths(); + + if (paths == null) return null; + + if (paths.length > 1) { + if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return collectPsiElements(); + } + else { + return null; + } + } + + TreePath path = paths[0]; + + InspectionTreeNode selectedNode = (InspectionTreeNode)path.getLastPathComponent(); + + if (selectedNode instanceof RefElementNode) { + final RefElementNode refElementNode = (RefElementNode)selectedNode; + RefElement refElement = refElementNode.getElement(); + final RefElement item; + if (refElement instanceof RefImplicitConstructor) { + item = ((RefImplicitConstructor)refElement).getOwnerClass(); + } + else { + item = refElement; + } + + if (!item.isValid()) return null; + + PsiElement psiElement = item.getElement(); + if (psiElement == null) return null; + + if (refElementNode.getProblem() != null) { + psiElement = refElementNode.getProblem().getPsiElement(); + if (psiElement == null) return null; + } + + if (DataConstants.NAVIGATABLE.equals(dataId)) { + return new OpenFileDescriptor(myProject, psiElement.getContainingFile().getVirtualFile(), psiElement.getTextOffset()); + } + else if (DataConstants.PSI_ELEMENT.equals(dataId)) { + return psiElement; + } + } + else if (selectedNode instanceof ProblemDescriptionNode && DataConstants.NAVIGATABLE.equals(dataId)) { + PsiElement psiElement = ((ProblemDescriptionNode)selectedNode).getDescriptor().getPsiElement(); + if (psiElement == null || !psiElement.isValid()) return null; + return new OpenFileDescriptor(myProject, psiElement.getContainingFile().getVirtualFile(), psiElement.getTextOffset()); + } + + return null; + } + + private PsiElement[] collectPsiElements() { + RefElement[] refElements = getSelectedElements(); + List psiElements = new ArrayList(); + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiElement psiElement = refElement.getElement(); + if (psiElement != null && psiElement.isValid()) { + psiElements.add(psiElement); + } + } + + return psiElements.toArray(new PsiElement[psiElements.size()]); + } + + private void popupInvoked(Component component, int x, int y) { + if (!isSingleToolInSelection()) return; + + final TreePath path; + if (myTree.hasFocus()) { + path = myTree.getLeadSelectionPath(); + } + else { + path = null; + } + + if (path == null) return; + + DefaultActionGroup actions = new DefaultActionGroup(); + actions.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); + actions.add(ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES)); + + final InspectionTool tool = getSelectedTool(); + final QuickFixAction[] quickFixes = tool.getQuickFixes(); + if (quickFixes != null) { + for (int i = 0; i < quickFixes.length; i++) { + actions.add(quickFixes[i]); + } + } + actions.add(ActionManager.getInstance().getAction(IdeActions.GROUP_VERSION_CONTROLS)); + + ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.CODE_INSPECTION, actions); + menu.getComponent().show(component, x, y); + } + + public ProblemDescriptor[] getSelectedDescriptors() { + if (myTree.getSelectionCount() == 0 || !(getSelectedTool() instanceof DescriptorProviderInspection)) return EMPTY_DESCRIPTORS; + final TreePath[] paths = myTree.getSelectionPaths(); + Set descriptors = new HashSet(); + for (int i = 0; i < paths.length; i++) { + Object node = paths[i].getLastPathComponent(); + if (node instanceof ProblemDescriptionNode) { + final ProblemDescriptionNode problemNode = (ProblemDescriptionNode)node; + descriptors.add(problemNode.getDescriptor()); + } + } + + final RefElement[] elements = getSelectedElements(); + final DescriptorProviderInspection tool = (DescriptorProviderInspection)getSelectedTool(); + for (int i = 0; i < elements.length; i++) { + RefElement element = elements[i]; + final ProblemDescriptor[] descriptions = tool.getDescriptions(element); + if (descriptions != null) descriptors.addAll(Arrays.asList(descriptions)); + } + return descriptors.toArray(new ProblemDescriptor[descriptors.size()]); + } + + public RefElement[] getSelectedElements() { + TreePath[] selectionPaths = myTree.getSelectionPaths(); + if (selectionPaths != null) { + final InspectionTool selectedTool = getSelectedTool(); + if (selectedTool == null) return EMPTY_ELEMENTS_ARRAY; + + Set result = new HashSet(); + for (int i = 0; i < selectionPaths.length; i++) { + final InspectionTreeNode node = (InspectionTreeNode)selectionPaths[i].getLastPathComponent(); + addElementsInNode(node, result); + } + return result.toArray(new RefElement[result.size()]); + } + return EMPTY_ELEMENTS_ARRAY; + } + + public void addElementsInNode(InspectionTreeNode node, Collection out) { + if (!node.isValid()) return; + if (node instanceof RefElementNode) { + out.add(((RefElementNode)node).getElement()); + } + else if (node instanceof InspectionPackageNode || node instanceof InspectionNode) { + final Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + addElementsInNode(child, out); + } + } + } + + public InspectionTool getSelectedTool() { + final TreePath[] paths = myTree.getSelectionPaths(); + if (paths == null) return null; + InspectionTool tool = null; + for (int i = 0; i < paths.length; i++) { + Object[] nodes = paths[i].getPath(); + for (int j = nodes.length - 1; j >= 0; j--) { + Object node = nodes[j]; + if (node instanceof InspectionNode) { + if (tool == null) { + tool = ((InspectionNode)node).getTool(); + } + else if (tool != ((InspectionNode)node).getTool()) { + return null; + } + break; + } + } + } + + return tool; + } + + public boolean isSingleToolInSelection() { + return getSelectedTool() != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionRootNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionRootNode.java new file mode 100644 index 00000000000..2d0f6216d23 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionRootNode.java @@ -0,0 +1,35 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Icons; + +import javax.swing.*; + +/** + * @author max + */ +public class InspectionRootNode extends InspectionTreeNode { + private static final Icon INFO = IconLoader.getIcon("/compiler/info.png"); + private Project myProject; + + public InspectionRootNode(Project project) { + super(project); + myProject = project; + } + + public String toString() { + final VirtualFile projectFile = myProject.getProjectFile(); + return isEmpty() ? "Nothing left to show" : + projectFile != null ? projectFile.getName() : myProject.getProjectFilePath(); + } + + private boolean isEmpty() { + return getChildCount() == 0; + } + + public Icon getIcon(boolean expanded) { + return isEmpty() ? INFO : Icons.PROJECT_ICON; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTree.java new file mode 100644 index 00000000000..2471c4b5948 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTree.java @@ -0,0 +1,275 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 4, 2001 + * Time: 5:19:35 PM + */ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.reference.RefClass; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.event.TreeWillExpandListener; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.ExpandVetoException; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; + +public class InspectionTree extends Tree { + private final HashSet myExpandedUserObjects; + private SelectionPath mySelectionPath; + + public InspectionTree(final Project project) { + super(new InspectionRootNode(project)); + + setCellRenderer(new CellRenderer());//project)); + setShowsRootHandles(true); + putClientProperty("JTree.lineStyle", "Angled"); + addTreeWillExpandListener(new ExpandListener()); + + myExpandedUserObjects = new HashSet(); + myExpandedUserObjects.add(project); + + TreeToolTipHandler.install(this); + TreeUtil.installActions(this); + new TreeSpeedSearch(this); + + addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + TreePath newSelection = e.getNewLeadSelectionPath(); + if (newSelection != null) { + mySelectionPath = new SelectionPath(newSelection); + } + } + }); + } + + public void removeAllNodes() { + getRoot().removeAllChildren(); + nodeStructureChanged(getRoot()); + } + + public InspectionTreeNode getRoot() { + return (InspectionTreeNode)getModel().getRoot(); + } + + public void nodeStructureChanged(InspectionTreeNode node) { + ((DefaultTreeModel)getModel()).nodeStructureChanged(node); + } + + private class ExpandListener implements TreeWillExpandListener { + public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { + final InspectionTreeNode node = (InspectionTreeNode)event.getPath().getLastPathComponent(); + myExpandedUserObjects.add(node.getUserObject()); + if (node instanceof RefElementNode && !node.children().hasMoreElements()) { + ((RefElementNode)node).loadChildren(); + sortChildren(node); + } + + // Smart expand + if (node.getChildCount() == 1) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + expandPath(new TreePath(node.getPath())); + } + }); + } + } + + public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { + InspectionTreeNode node = (InspectionTreeNode)event.getPath().getLastPathComponent(); + myExpandedUserObjects.remove(node.getUserObject()); + } + } + + public void restoreExpantionAndSelection() { + restoreExpantion(); + if (mySelectionPath != null) { + mySelectionPath.restore(); + } + } + + private void restoreExpantion() { + restoreExpantionStatus((InspectionTreeNode)getModel().getRoot()); + } + + + private void restoreExpantionStatus(InspectionTreeNode node) { + if (myExpandedUserObjects.contains(node.getUserObject())) { + TreeNode[] pathToNode = node.getPath(); + expandPath(new TreePath(pathToNode)); + Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode childNode = (InspectionTreeNode)children.nextElement(); + restoreExpantionStatus(childNode); + } + } + } + + private class CellRenderer extends ColoredTreeCellRenderer { + /* private Project myProject; + InspectionManagerEx myManager; + public CellRenderer(Project project) { + myProject = project; + myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + }*/ + + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + InspectionTreeNode node = (InspectionTreeNode)value; + + if (!node.isWritable()) { + append("(Read-only) ", SimpleTextAttributes.ERROR_ATTRIBUTES); + } + + append(node.toString(), appearsBold(node) + ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES + : getMainForegroundAttributes(node)); + + if (!node.isValid()) { + append(" (INVALID)", SimpleTextAttributes.ERROR_ATTRIBUTES); + } + + int problemCount = node.getProblemCount(); + if (problemCount > 0) { + if (problemCount == 1) { + append(" (" + problemCount + " item)", SimpleTextAttributes.GRAYED_ATTRIBUTES); + } + else { + append(" (" + problemCount + " items)", SimpleTextAttributes.GRAYED_ATTRIBUTES); + } + } + + setIcon(node.getIcon(expanded)); + /* if (node instanceof InspectionNode){ + final HighlightDisplayLevel level = myManager.getCurrentProfile().getErrorLevel(HighlightDisplayKey.find(((InspectionNode)node).getTool().getDisplayName())); + LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(node.getIcon(expanded), 1); + icon.setIcon(level.getIcon(), + 0); + setIcon(icon); + }*/ + } + + private SimpleTextAttributes getMainForegroundAttributes(InspectionTreeNode node) { + SimpleTextAttributes foreground = SimpleTextAttributes.REGULAR_ATTRIBUTES; + if (node instanceof RefElementNode) { + RefElement refElement = ((RefElementNode)node).getElement(); + + if (refElement instanceof RefClass) { + RefElement defaultConstructor = ((RefClass)refElement).getDefaultConstructor(); + if (defaultConstructor != null) refElement = defaultConstructor; + } + + if (refElement.isEntry() && refElement.isPermanentEntry()) { + foreground = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.blue); + } + } + return foreground; + } + + private boolean appearsBold(Object node) { + return ((InspectionTreeNode)node).appearsBold(); + } + } + + public void sort() { + sortChildren(getRoot()); + } + + protected void sortChildren(InspectionTreeNode node) { + TreeUtil.sort(node, RefAlphabeticalComparator.getInstance()); + } + + private class SelectionPath { + private Object[] myPath; + private int[] myIndicies; + + public SelectionPath(TreePath path) { + myPath = path.getPath(); + myIndicies = new int[myPath.length]; + for (int i = 0; i < myPath.length - 1; i++) { + InspectionTreeNode node = (InspectionTreeNode)myPath[i]; + myIndicies[i + 1] = getChildIndex(node, (InspectionTreeNode)myPath[i + 1]); + } + } + + private int getChildIndex(InspectionTreeNode node, InspectionTreeNode child) { + int idx = 0; + Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode ch = (InspectionTreeNode)children.nextElement(); + if (ch == child) break; + idx++; + } + return idx; + } + + public void restore() { + getSelectionModel().removeSelectionPaths(getSelectionModel().getSelectionPaths()); + TreeUtil.selectPath(InspectionTree.this, restorePath()); + } + + private TreePath restorePath() { + ArrayList newPath = new ArrayList(); + + newPath.add(getModel().getRoot()); + restorePath(newPath, 1); + + return new TreePath(newPath.toArray(new InspectionTreeNode[newPath.size()])); + } + + private void restorePath(ArrayList newPath, int idx) { + if (idx >= myPath.length) return; + InspectionTreeNode oldNode = (InspectionTreeNode)myPath[idx]; + + InspectionTreeNode newRoot = (InspectionTreeNode)newPath.get(idx - 1); + if (newRoot instanceof RefElementNode) { + ((RefElementNode)newRoot).loadChildren(); + } + + RefAlphabeticalComparator comparator = RefAlphabeticalComparator.getInstance(); + Enumeration children = newRoot.children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + if (comparator.compare(child, oldNode) == 0) { + newPath.add(child); + restorePath(newPath, idx + 1); + return; + } + } + + // Exactly same element not found. Trying to select somewhat near. + int count = newRoot.getChildCount(); + if (count > 0) { + if (myIndicies[idx] < count) { + newPath.add(newRoot.getChildAt(myIndicies[idx])); + } + else { + newPath.add(newRoot.getChildAt(count - 1)); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTreeNode.java new file mode 100644 index 00000000000..10e65348261 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/InspectionTreeNode.java @@ -0,0 +1,38 @@ +package com.intellij.codeInspection.ui; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Enumeration; + +/** + * @author max + */ +public abstract class InspectionTreeNode extends DefaultMutableTreeNode { + protected InspectionTreeNode(Object userObject) { + super(userObject); + } + + public abstract Icon getIcon(boolean expanded); + + public int getProblemCount() { + int sum = 0; + Enumeration children = children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + sum += child.getProblemCount(); + } + return sum; + } + + public boolean isValid() { + return true; + } + + public boolean appearsBold() { + return false; + } + + public boolean isWritable() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/ProblemDescriptionNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/ProblemDescriptionNode.java new file mode 100644 index 00000000000..6fb09364a9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/ProblemDescriptionNode.java @@ -0,0 +1,58 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; + +import javax.swing.*; + +/** + * @author max + */ +public class ProblemDescriptionNode extends InspectionTreeNode { + public static final Icon INFO = IconLoader.getIcon("/compiler/information.png"); + private RefElement myElement; + private ProblemDescriptor myDescriptor; + + public ProblemDescriptionNode(RefElement element, ProblemDescriptor descriptor) { + super(descriptor); + myElement = element; + myDescriptor = descriptor; + } + + public RefElement getElement() { return myElement; } + public ProblemDescriptor getDescriptor() { return myDescriptor; } + + public Icon getIcon(boolean expanded) { + return INFO; + } + + public int getProblemCount() { + return 1; + } + + public boolean isValid() { + if (!myElement.isValid()) return false; + final PsiElement psiElement = myDescriptor.getPsiElement(); + return psiElement != null && psiElement.isValid(); + } + + public String toString() { + return isValid() ? renderDescriptionMessage(myDescriptor) : ""; + } + + private static String renderDescriptionMessage(ProblemDescriptor descriptor) { + PsiElement psiElement = descriptor.getPsiElement(); + String message = descriptor.getDescriptionTemplate(); + + if (psiElement != null && psiElement.isValid() && message != null) { + message = message.replaceAll("<[^>]*>", ""); + message = StringUtil.replace(message, "#ref", psiElement.getText()); + message = StringUtil.replace(message, "#loc", ""); + return message; + } + return ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefAlphabeticalComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefAlphabeticalComparator.java new file mode 100644 index 00000000000..5686c553c9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefAlphabeticalComparator.java @@ -0,0 +1,36 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 23, 2001 + * Time: 10:31:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.ui; + +import java.util.Comparator; + +public class RefAlphabeticalComparator implements Comparator { + private static RefAlphabeticalComparator ourInstance = null; + + public int compare(Object o1, Object o2) { + InspectionTreeNode node1 = (InspectionTreeNode)o1; + InspectionTreeNode node2 = (InspectionTreeNode)o2; + + if (node1 instanceof InspectionNode && node2 instanceof InspectionGroupNode) return -1; + if (node2 instanceof InspectionNode && node1 instanceof InspectionGroupNode) return 1; + + if (node1 instanceof EntryPointsNode && node2 instanceof InspectionPackageNode) return -1; + if (node2 instanceof EntryPointsNode && node1 instanceof InspectionPackageNode) return 1; + + return node1.toString().compareTo(node2.toString()); + } + + public static RefAlphabeticalComparator getInstance() { + if (ourInstance == null) { + ourInstance = new RefAlphabeticalComparator(); + } + + return ourInstance; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefElementNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefElementNode.java new file mode 100644 index 00000000000..01f650ba8b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/ui/RefElementNode.java @@ -0,0 +1,150 @@ +package com.intellij.codeInspection.ui; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiElement; + +import javax.swing.*; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreeNode; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author max + */ +public class RefElementNode extends InspectionTreeNode { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ui.RefElementNode"); + private boolean myShouldLoadCallees; + private boolean myHasDescriptorsUnder = false; + private ProblemDescriptor mySingleDescriptor = null; + + public RefElementNode(RefElement element, boolean shouldLoadCallees) { + super(element); + LOG.assertTrue(element != null); + myShouldLoadCallees = shouldLoadCallees; + } + + public boolean hasDescriptorsUnder() { return myHasDescriptorsUnder; } + + public RefElement getElement() { + return (RefElement)getUserObject(); + } + + public Icon getIcon(boolean expanded) { + final PsiElement element = getElement().getElement(); + return element != null ? element.getIcon(Iconable.ICON_FLAG_VISIBILITY) : null; + } + + public boolean isWritable() { + final PsiElement element = getElement().getElement(); + return element != null ? element.isWritable() : true; + } + + public int getProblemCount() { + if (myShouldLoadCallees) { + return getParent() instanceof RefElementNode ? 0 : 1; + } + return myHasDescriptorsUnder ? super.getProblemCount() : 1; + } + + public String toString() { + final RefElement element = getElement(); + if (element instanceof RefImplicitConstructor) { + return RefUtil.getQualifiedName(((RefImplicitConstructor)element).getOwnerClass()); + } + return RefUtil.getQualifiedName(element); + } + + public boolean isValid() { + return getElement().isValid(); + } + + public void loadChildren() { + if (myShouldLoadCallees) { + Set newChildren = getPossibleChildren(getElement()); + for (Iterator iterator = newChildren.iterator(); iterator.hasNext();) { + RefElement refChild = (RefElement) iterator.next(); + add(new RefElementNode(refChild, true)); + } + } + } + + public void add(MutableTreeNode newChild) { + super.add(newChild); + if (newChild instanceof ProblemDescriptionNode) { + myHasDescriptorsUnder = true; + } + } + + public void setProblem(ProblemDescriptor descriptor) { + mySingleDescriptor = descriptor; + } + + public ProblemDescriptor getProblem() { + return mySingleDescriptor; + } + + public boolean isLeaf() { + if (myShouldLoadCallees) { + return getPossibleChildren(getElement()).size() == 0; + } + return super.isLeaf(); + } + + private Set getPossibleChildren(RefElement refElement) { + final TreeNode[] pathToRoot = getPath(); + + final HashSet newChildren = new HashSet(); + + if (!refElement.isValid()) return newChildren; + + Iterator outReferences = refElement.getOutReferences().iterator(); + while (outReferences.hasNext()) { + RefElement refCallee = outReferences.next(); + if (refCallee.isSuspicious()) { + if (notInPath(pathToRoot, refCallee)) newChildren.add(refCallee); + } + } + + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + + if (!refMethod.isStatic() && !refMethod.isConstructor() && !refMethod.getOwnerClass().isAnonymous()) { + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refDerived = iterator.next(); + if (refDerived.isSuspicious()) { + if (notInPath(pathToRoot, refDerived)) newChildren.add(refDerived); + } + } + } + } else if (refElement instanceof RefClass) { + RefClass refClass = (RefClass) refElement; + for (Iterator iterator = refClass.getSubClasses().iterator(); iterator.hasNext();) { + RefClass subClass = iterator.next(); + if ((subClass.isInterface() || subClass.isAbstract()) && subClass.isSuspicious()) { + if (notInPath(pathToRoot, subClass)) newChildren.add(subClass); + } + } + + if (refClass.getDefaultConstructor() != null && refClass.getDefaultConstructor() instanceof RefImplicitConstructor) { + Set fromConstructor = getPossibleChildren(refClass.getDefaultConstructor()); + newChildren.addAll(fromConstructor); + } + } + + return newChildren; + } + + private boolean notInPath(TreeNode[] pathToRoot, RefElement refChild) { + for (int i = 0; i < pathToRoot.length; i++) { + InspectionTreeNode node = (InspectionTreeNode) pathToRoot[i]; + if (node instanceof RefElementNode && ((RefElementNode)node).getElement() == refChild) return false; + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unneededThrows/UnneededThrows.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unneededThrows/UnneededThrows.java new file mode 100644 index 00000000000..51a20c9357c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unneededThrows/UnneededThrows.java @@ -0,0 +1,201 @@ +package com.intellij.codeInspection.unneededThrows; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.ex.ProblemDescriptorImpl; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefMethod; +import com.intellij.codeInspection.reference.RefVisitor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author max + */ +public class UnneededThrows extends DescriptorProviderInspection { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.unneededThrows.UnneededThrows"); + public static final String DISPLAY_NAME = "Redundant throws clause"; + private QuickFix myQuickFix; + public static final String SHORT_NAME = "UnneededThrows"; + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElement; + ProblemDescriptorImpl[] descriptors = checkMethod(refMethod); + if (descriptors != null) { + addProblemElement(refElement, descriptors); + } + } + } + }); + } + + private ProblemDescriptorImpl[] checkMethod(RefMethod refMethod) { + if (refMethod.isLibraryOverride()) return null; + if (refMethod.getSuperMethods().size() > 0) return null; + + PsiClassType[] unThrown = refMethod.getUnThrownExceptions(); + if (unThrown == null) return null; + + PsiMethod psiMethod = (PsiMethod)refMethod.getElement(); + PsiClassType[] throwsList = psiMethod.getThrowsList().getReferencedTypes(); + PsiJavaCodeReferenceElement[] throwsRefs = psiMethod.getThrowsList().getReferenceElements(); + ArrayList problems = null; + + for (int i = 0; i < throwsList.length; i++) { + PsiClassType throwsType = throwsList[i]; + PsiJavaCodeReferenceElement throwsRef = throwsRefs[i]; + if (ExceptionUtil.isUncheckedException(throwsType)) continue; + + for (int j = 0; j < unThrown.length; j++) { + PsiClassType s = unThrown[j]; + if (s.equals(throwsType)) { + if (problems == null) problems = new ArrayList(1); + + final String message; + if (refMethod.isAbstract() || refMethod.getOwnerClass().isInterface()) { + message = " in method implementations"; + } + else if (refMethod.getDerivedMethods().size() > 0) { + message = " in this method, nor in its derivables."; + } + else { + message = "."; + } + + problems.add( + getManager().createProblemDescriptor(throwsRef, "The declared exception #ref is never thrown" + message, getFix(), + ProblemHighlightType.LIKE_UNUSED_SYMBOL)); + } + } + } + + if (problems != null) { + return problems.toArray(new ProblemDescriptorImpl[problems.size()]); + } + + return null; + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (getDescriptions(refElement) != null) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + getManager().enqueueDerivedMethodsProcessing(refMethod, new InspectionManagerEx.DerivedMethodsProcessor() { + public boolean process(PsiMethod derivedMethod) { + ignoreElement(refMethod); + return true; + } + }); + } + }); + } + } + }); + + return false; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[]{InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return SHORT_NAME; + } + + public UnneededThrows() { + } + + private LocalQuickFix getFix() { + if (myQuickFix == null) { + myQuickFix = new QuickFix(); + } + return myQuickFix; + } + + private class QuickFix implements LocalQuickFix { + public String getName() { + return "Remove unnecessary throws declarations"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + RefElement refElement = getElement(descriptor); + if (refElement.isValid() && refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElement; + removeExcessiveThrows(refMethod); + } + } + + private void removeExcessiveThrows(RefMethod refMethod) { + try { + Project project = getManager().getProject(); + ProblemDescriptor[] problems = getDescriptions(refMethod); + if (problems == null) return; + PsiManager psiManager = PsiManager.getInstance(project); + List refsToDelete = new ArrayList(); + for (int i = 0; i < problems.length; i++) { + ProblemDescriptor problem = problems[i]; + PsiJavaCodeReferenceElement classRef = (PsiJavaCodeReferenceElement)problem.getPsiElement(); + if (classRef == null) continue; + PsiType psiType = psiManager.getElementFactory().createType(classRef); + removeException(refMethod, psiType, refsToDelete); + } + + for (Iterator iterator = refsToDelete.iterator(); iterator.hasNext();) { + iterator.next().delete(); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private void removeException(RefMethod refMethod, PsiType exceptionType, + List refsToDelete) { + PsiMethod psiMethod = (PsiMethod)refMethod.getElement(); + PsiManager psiManager = psiMethod.getManager(); + + PsiJavaCodeReferenceElement[] refs = psiMethod.getThrowsList().getReferenceElements(); + for (int i = 0; i < refs.length; i++) { + PsiJavaCodeReferenceElement ref = refs[i]; + PsiType refType = psiManager.getElementFactory().createType(ref); + if (exceptionType.isAssignableFrom(refType)) { + refsToDelete.add(ref); + } + } + + for (Iterator iterator = refMethod.getDerivedMethods().iterator(); iterator.hasNext();) { + RefMethod refDerived = iterator.next(); + removeException(refDerived, exceptionType, refsToDelete); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java new file mode 100644 index 00000000000..a0903891969 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java @@ -0,0 +1,205 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 24, 2001 + * Time: 2:46:32 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.unusedParameters; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefMethod; +import com.intellij.codeInspection.reference.RefParameter; +import com.intellij.codeInspection.util.RefFilter; +import com.intellij.codeInspection.util.XMLExportUtl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiReferenceProcessor; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; +import com.intellij.refactoring.changeSignature.ParameterInfo; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class UnusedParametersInspection extends FilteringInspectionTool { + private UnusedParametersFilter myFilter; + private UnusedParametersComposer myComposer; + + public UnusedParametersInspection() { + + myQuickFixActions = new QuickFixAction[] {new AcceptSuggested()}; + } + + private QuickFixAction[] myQuickFixActions; + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + // Do additional search of problem elements outside the scope. + final Runnable action = new Runnable() { + public void run() { + if (getRefManager().getScope().getScopeType() != AnalysisScope.PROJECT) { + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + final UnusedParametersFilter filter = new UnusedParametersFilter(); + final PsiSearchHelper helper = PsiManager.getInstance(getManager().getProject()).getSearchHelper(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (filter.accepts(refElement)) { + RefMethod refMethod = (RefMethod) refElement; + PsiMethod psiMethod = (PsiMethod) refMethod.getElement(); + if (!refMethod.isStatic() && !refMethod.isConstructor() && refMethod.getAccessModifier() != PsiModifier.PRIVATE) { + PsiMethod[] derived = helper.findOverridingMethods(psiMethod, GlobalSearchScope.projectScope(getManager().getProject()), true); + ArrayList unusedParameters = filter.getUnusedParameters(refMethod); + for (Iterator paramIterator = unusedParameters.iterator(); paramIterator.hasNext();) { + final RefParameter refParameter = (RefParameter) paramIterator.next(); + int idx = refParameter.getIndex(); + + if (refMethod.isAbstract() && derived.length == 0) { + refParameter.parameterReferenced(false); + } else { + final boolean[] found = new boolean[]{false}; + for (int i = 0; i < derived.length && !found[0]; i++) { + if (!getRefManager().getScope().contains(derived[i])) { + PsiParameter psiParameter = derived[i].getParameterList().getParameters()[idx]; + helper.processReferences(new PsiReferenceProcessor() { + public boolean execute(PsiReference element) { + refParameter.parameterReferenced(false); + found[0] = true; + return false; + } + }, psiParameter, helper.getAccessScope(psiParameter), false); + } + } + } + } + } + } + } + }); + } + }, null); + } + } + }; + ApplicationManager.getApplication().runReadAction(action); + } + + public RefFilter getFilter() { + if (myFilter == null) { + myFilter = new UnusedParametersFilter(); + } + return myFilter; + } + + public void exportResults(final Element parentNode) { + final UnusedParametersFilter filter = new UnusedParametersFilter(); + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (filter.accepts(refElement)) { + ArrayList unusedParameters = filter.getUnusedParameters((RefMethod)refElement); + for (int i = 0; i < unusedParameters.size(); i++) { + Element element = XMLExportUtl.createElement(refElement, parentNode, -1); + Element problemClassElement = new Element("problem_class"); + problemClassElement.addContent("parameter is not used"); + element.addContent(problemClassElement); + + RefParameter refParameter = (RefParameter) unusedParameters.get(i); + Element descriptionElement = new Element("description"); + descriptionElement.addContent("parameter " + refParameter.getName() + " is not used"); + element.addContent(descriptionElement); + } + } + } + }); + } + + public QuickFixAction[] getQuickFixes() { + return myQuickFixActions; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + private class AcceptSuggested extends QuickFixAction { + private AcceptSuggested() { + super("Delete Unused Parameter(s)",IconLoader.getIcon("/actions/cancel.png"), null, UnusedParametersInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefMethod refMethod = (RefMethod) refElements[i]; + PsiMethod psiMethod = (PsiMethod) refMethod.getElement(); + + if (psiMethod == null) continue; + + ArrayList psiParameters = new ArrayList(); + UnusedParametersFilter filter = (UnusedParametersFilter)getFilter(); + for (Iterator paramIterator = filter.getUnusedParameters(refMethod).iterator(); paramIterator.hasNext();) { + RefParameter refParameter = (RefParameter) paramIterator.next(); + psiParameters.add(refParameter.getElement()); + } + + removeUnusedParameterViaChangeSignature(psiMethod, psiParameters); + + filter.ignore(refMethod); + } + + return true; + } + } + + public String getDisplayName() { + return "Unused method parameters"; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return "UnusedParameters"; + } + + public HTMLComposer getComposer() { + if (myComposer == null) { + myComposer = new UnusedParametersComposer(myFilter, this); + } + return myComposer; + } + + private void removeUnusedParameterViaChangeSignature(final PsiMethod psiMethod, final Collection parametersToDelete) { + ArrayList newParameters = new ArrayList(); + PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters(); + for (int i = 0; i < oldParameters.length; i++) { + PsiParameter oldParameter = oldParameters[i]; + if (!parametersToDelete.contains(oldParameter)) { + newParameters.add(new ParameterInfo(i, oldParameter.getName(), oldParameter.getType())); + } + } + + ParameterInfo[] parameterInfos = (ParameterInfo[]) newParameters.toArray(new ParameterInfo[newParameters.size()]); + + ChangeSignatureProcessor csp = new ChangeSignatureProcessor(getManager().getProject(), + psiMethod, + false, null, psiMethod.getName(), + psiMethod.getReturnType(), + parameterInfos, + false, BaseRefactoringProcessor.EMPTY_CALLBACK); + + csp.run(null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java new file mode 100644 index 00000000000..5a640291507 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java @@ -0,0 +1,140 @@ +package com.intellij.codeInspection.unusedReturnValue; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ex.DescriptorProviderInspection; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.JobDescriptor; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefManager; +import com.intellij.codeInspection.reference.RefMethod; +import com.intellij.codeInspection.reference.RefVisitor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; +import com.intellij.refactoring.changeSignature.ParameterInfo; + +/** + * @author max + */ +public class UnusedReturnValue extends DescriptorProviderInspection { + private QuickFix myQuickFix; + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); + + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + ProblemDescriptor[] descriptors = checkMethod(refMethod); + if (descriptors != null) { + addProblemElement(refElement, descriptors); + } + } + } + }); + } + + private ProblemDescriptor[] checkMethod(RefMethod refMethod) { + if (refMethod.isConstructor()) return null; + if (refMethod.isLibraryOverride()) return null; + if (refMethod.getInReferences().size() == 0) return null; + if (refMethod.getSuperMethods().size() > 0) return null; + + if (!refMethod.isReturnValueUsed()) { + return new ProblemDescriptor[]{ + getManager().createProblemDescriptor(refMethod.getElement(), "Return value of the method is never used.", + getFix(), ProblemHighlightType.GENERIC_ERROR_OR_WARNING)}; + } + + return null; + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (getDescriptions(refElement) != null) { + refElement.accept(new RefVisitor() { + public void visitMethod(final RefMethod refMethod) { + getManager().enqueueMethodUsagesProcessor(refMethod, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + ignoreElement(refMethod); + return false; + } + }); + } + }); + } + } + }); + + return false; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[] {InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + public String getDisplayName() { + return "Unused method return value"; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return "UnusedReturnValue"; + } + + public UnusedReturnValue() { + } + + private LocalQuickFix getFix() { + if (myQuickFix == null) { + myQuickFix = new QuickFix(); + } + return myQuickFix; + } + + private class QuickFix implements LocalQuickFix { + public String getName() { + return "Make Method void"; + } + + public void applyFix(Project project, ProblemDescriptor descriptor) { + RefElement refElement = getElement(descriptor); + if (refElement.isValid() && refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod)refElement; + makeMethodVoid(refMethod); + } + } + + private void makeMethodVoid(RefMethod refMethod) { + PsiMethod psiMethod = (PsiMethod) refMethod.getElement(); + if (psiMethod == null) return; + PsiParameter[] params = psiMethod.getParameterList().getParameters(); + ParameterInfo[] infos = new ParameterInfo[params.length]; + for (int i = 0; i < params.length; i++) { + PsiParameter param = params[i]; + infos[i] = new ParameterInfo(i, param.getName(), param.getType()); + } + + ChangeSignatureProcessor csp = new ChangeSignatureProcessor(getManager().getProject(), + psiMethod, + false, null, psiMethod.getName(), + PsiType.VOID, + infos, + false, BaseRefactoringProcessor.EMPTY_CALLBACK); + + csp.run(null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefEntityAlphabeticalComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefEntityAlphabeticalComparator.java new file mode 100644 index 00000000000..bd5bd4f5f42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefEntityAlphabeticalComparator.java @@ -0,0 +1,44 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 20, 2002 + * Time: 10:11:39 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.util; + +import com.intellij.codeInspection.reference.RefPackage; + +import java.util.Comparator; + +public class RefEntityAlphabeticalComparator implements Comparator { + private static RefEntityAlphabeticalComparator ourEntity; + + public int compare(Object o1, Object o2) { + + if (o1 == o2) return 0; + + if (o1 instanceof RefPackage && !(o2 instanceof RefPackage)) { + return 1; + } + + if (o2 instanceof RefPackage && !(o1 instanceof RefPackage)) { + return -1; + } + + if (o1 instanceof RefPackage) { + return ((RefPackage)o1).getQualifiedName().compareToIgnoreCase(((RefPackage)o2).getQualifiedName()); + } + + return o1.toString().compareToIgnoreCase(o2.toString()); + } + + public static RefEntityAlphabeticalComparator getInstance() { + if (ourEntity == null) { + ourEntity = new RefEntityAlphabeticalComparator(); + } + + return ourEntity; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefFilter.java new file mode 100644 index 00000000000..9b7129e47ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/RefFilter.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 1, 2001 + * Time: 11:42:56 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.util; + +import com.intellij.codeInspection.reference.*; + +public abstract class RefFilter { + // Default accepts implementation accepts element if one under unaccepted one. Thus it will accept all and only upper level classes. + public int getElementProblemCount(RefElement refElement) { + if (refElement instanceof RefParameter) return 0; + RefEntity refOwner = refElement.getOwner(); + if (refOwner == null || !(refOwner instanceof RefElement)) return 1; + + return 1 - getElementProblemCount((RefElement)refOwner); + } + + public final boolean accepts(RefElement refElement) { + return getElementProblemCount(refElement) > 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/XMLExportUtl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/XMLExportUtl.java new file mode 100644 index 00000000000..d6f85df09f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/util/XMLExportUtl.java @@ -0,0 +1,149 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 23, 2002 + * Time: 2:36:58 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.util; + +import com.intellij.codeInspection.reference.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.util.PsiFormatUtil; +import org.jdom.Element; + +public class XMLExportUtl { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.util.XMLExportUtl"); + public static Element createElement(RefElement refElement, Element parentNode, int actualLine) { + if (refElement instanceof RefImplicitConstructor) { + return createElement((RefElement) refElement.getOwner(), parentNode, actualLine); + } + + Element problem = new Element("problem"); + + PsiElement psiElement = refElement.getElement(); + PsiFile psiFile = psiElement.getContainingFile(); + + Element fileElement = new Element("file"); + Element lineElement = new Element("line"); + fileElement.addContent(psiFile.getVirtualFile().getUrl()); + + if (actualLine == -1) { + Document document = PsiDocumentManager.getInstance(refElement.getRefManager().getProject()).getDocument(psiFile); + lineElement.addContent(String.valueOf(document.getLineNumber(psiElement.getTextOffset()) + 1)); + } else { + lineElement.addContent(String.valueOf(actualLine)); + } + + problem.addContent(fileElement); + problem.addContent(lineElement); + + + if (refElement instanceof RefMethod) { + RefMethod refMethod = (RefMethod) refElement; + appendMethod(refMethod, problem); + } else if (refElement instanceof RefField) { + RefField refField = (RefField) refElement; + appendField(refField, problem); + } else if (refElement instanceof RefClass) { + RefClass refClass = (RefClass)refElement; + appendClass(refClass, problem); + } else { + LOG.error("Unknown refElement"); + } + parentNode.addContent(problem); + + return problem; + } + + private static void appendClass(RefClass refClass, Element parentNode) { + PsiClass psiClass = (PsiClass) refClass.getElement(); + PsiDocComment psiDocComment = psiClass.getDocComment(); + + PsiFile psiFile = psiClass.getContainingFile(); + + if (psiFile instanceof PsiJavaFile) { + String packageName = ((PsiJavaFile)psiFile).getPackageName(); + Element packageElement = new Element("package"); + packageElement.addContent(packageName.length() > 0 ? packageName : ""); + parentNode.addContent(packageElement); + } + + Element classElement = new Element("class"); + if (psiDocComment != null) { + PsiDocTag[] tags = psiDocComment.getTags(); + for (int i = 0; i < tags.length; i++) { + PsiDocTag tag = tags[i]; + if ("author".equals(tag.getName()) && tag.getValueElement() != null) { + classElement.setAttribute("author", tag.getValueElement().getText()); + } + } + } + + String name = PsiFormatUtil.formatClass(psiClass, PsiFormatUtil.SHOW_NAME); + Element nameElement = new Element("name"); + nameElement.addContent(name); + classElement.addContent(nameElement); + + Element displayName = new Element("display_name"); + displayName.addContent(RefUtil.getQualifiedName(refClass)); + classElement.addContent(displayName); + + parentNode.addContent(classElement); + + RefClass topClass = RefUtil.getTopLevelClass(refClass); + if (topClass != refClass) { + appendClass(topClass, classElement); + } + } + + private static void appendMethod(final RefMethod refMethod, Element parentNode) { + Element methodElement = new Element(refMethod.isConstructor() ? "constructor" : "method"); + + PsiMethod psiMethod = (PsiMethod) refMethod.getElement(); + String name = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_FQ_NAME | + PsiFormatUtil.SHOW_TYPE | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_TYPE + ); + + Element shortNameElement = new Element("name"); + shortNameElement.addContent(name); + methodElement.addContent(shortNameElement); + + Element displayName = new Element("display_name"); + displayName.addContent(RefUtil.getQualifiedName(refMethod)); + methodElement.addContent(displayName); + + appendClass(RefUtil.getTopLevelClass(refMethod), methodElement); + + parentNode.addContent(methodElement); + } + + private static void appendField(final RefField refField, Element parentNode) { + Element fieldElement = new Element("field"); + PsiField psiField = (PsiField) refField.getElement(); + String name = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_TYPE, + PsiSubstitutor.EMPTY); + + Element shortNameElement = new Element("name"); + shortNameElement.addContent(name); + fieldElement.addContent(shortNameElement); + + Element displayName = new Element("display_name"); + displayName.addContent(RefUtil.getQualifiedName(refField)); + fieldElement.addContent(displayName); + + appendClass(RefUtil.getTopLevelClass(refField), fieldElement); + + parentNode.addContent(fieldElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/visibility/VisibilityInspection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/visibility/VisibilityInspection.java new file mode 100644 index 00000000000..04dedbd4d04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/codeInspection/visibility/VisibilityInspection.java @@ -0,0 +1,327 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 21, 2001 + * Time: 8:46:41 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.codeInspection.visibility; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.reference.*; +import com.intellij.codeInspection.util.XMLExportUtl; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.j2eeDom.ejb.Ejb; +import com.intellij.j2ee.j2eeDom.ejb.EjbModel; +import com.intellij.j2ee.j2eeDom.ejb.EntityBean; +import com.intellij.j2ee.j2eeDom.xmlData.ObjectsList; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; + +public class VisibilityInspection extends FilteringInspectionTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.visibility.VisibilityInspection"); + public boolean SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS = true; + public boolean SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES = true; + public boolean SUGGEST_PRIVATE_FOR_INNERS = false; + private WeakerAccessFilter myFilter; + private QuickFixAction[] myQuickFixActions; + public static final String DISPLAY_NAME = "Declaration access can be weaker"; + private VisibilityPageComposer myComposer; + public static final String SHORT_NAME = "WeakerAccess"; + + public VisibilityInspection() { + myQuickFixActions = new QuickFixAction[]{new AcceptSuggestedAccess()}; + } + + private class OptionsPanel extends JPanel { + private final JCheckBox myPackageLocalForMembersCheckbox; + private final JCheckBox myPrivateForInnersCheckbox; + private JCheckBox myPackageLocalForTopClassesCheckbox; + + private OptionsPanel() { + super(new GridBagLayout()); + + GridBagConstraints gc = new GridBagConstraints(); + gc.fill = GridBagConstraints.HORIZONTAL; + gc.weightx = 1; + gc.weighty = 0; + gc.anchor = GridBagConstraints.NORTHWEST; + + myPackageLocalForMembersCheckbox = new JCheckBox("Suggest package local visibility level for class members"); + myPackageLocalForMembersCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS); + myPackageLocalForMembersCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myPackageLocalForMembersCheckbox.isSelected(); + SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS = selected; + } + }); + + gc.gridy = 0; + add(myPackageLocalForMembersCheckbox, gc); + + myPackageLocalForTopClassesCheckbox = new JCheckBox("Suggest package local visibility level for top-level classes"); + myPackageLocalForTopClassesCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES); + myPackageLocalForTopClassesCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myPackageLocalForTopClassesCheckbox.isSelected(); + SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES = selected; + } + }); + + gc.gridy = 1; + add(myPackageLocalForTopClassesCheckbox, gc); + + + myPrivateForInnersCheckbox = new JCheckBox("Suggest private for inner class members when referenced from outer class only"); + myPrivateForInnersCheckbox.setSelected(SUGGEST_PRIVATE_FOR_INNERS); + myPrivateForInnersCheckbox.getModel().addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + boolean selected = myPrivateForInnersCheckbox.isSelected(); + SUGGEST_PRIVATE_FOR_INNERS = selected; + } + }); + + gc.gridy = 2; + gc.weighty = 1; + add(myPrivateForInnersCheckbox, gc); + } + } + + public JComponent createOptionsPanel() { + return new OptionsPanel(); + } + + public String getDisplayName() { + return DISPLAY_NAME; + } + + public String getGroupDisplayName() { + return "Declaration Redundancy"; + } + + public String getShortName() { + return SHORT_NAME; + } + + public WeakerAccessFilter getFilter() { + return myFilter; + } + + public void runInspection(AnalysisScope scope) { + getRefManager().findAllDeclarations(); // Find all declaration elements. + + myFilter = new WeakerAccessFilter(isPackageLocalForMembersShouldBeSuggested(), + isPackageLocalForTopClassesShouldBeSuggested(), + isPrivateForInnersShouldBeSuggested()); + + SmartRefElementPointer[] entryPoints = EntryPointsManager.getInstance(getManager().getProject()).getEntryPoints(); + for (int i = 0; i < entryPoints.length; i++) { + RefElement refElement = entryPoints[i].getRefElement(); + if (refElement != null) { + myFilter.addIgnoreList(refElement); + } + } + + EjbModel[] ejbRootDescriptors = EjbUtil.getEjbModels(getManager().getProject()); + for (int i = 0; i < ejbRootDescriptors.length; i++) { + EjbModel ejbRootDescriptor = ejbRootDescriptors[i]; + ejbRootDescriptor.getEjbs().visitAllElements(new ObjectsList.ElementVisitor() { + public void acceptElement(Ejb ejb) { + if (ejb instanceof EntityBean) { + EntityBean entityBean = (EntityBean)ejb; + PsiClass primaryKeyClass = entityBean.getPrimaryKeyClass().getPsiClass(); + if (primaryKeyClass != null) { + PsiField[] fields = primaryKeyClass.getFields(); + for (int k = 0; k < fields.length; k++) { + PsiField field = fields[k]; + RefField refField = (RefField)getRefManager().getReference(field); + if (refField != null) { + myFilter.addIgnoreList(refField); + } + } + + PsiMethod[] constructors = primaryKeyClass.getConstructors(); + for (int k = 0; k < constructors.length; k++) { + PsiMethod constructor = constructors[k]; + if (constructor.getParameterList().getParameters().length == 0) { + RefMethod refConstructor = (RefMethod)getRefManager().getReference(constructor); + if (refConstructor != null) { + myFilter.addIgnoreList(refConstructor); + } + } + } + } + } + } + }); + } + } + + public boolean queryExternalUsagesRequests() { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (myFilter.accepts(refElement)) { + refElement.accept(new RefVisitor() { + public void visitField(final RefField refField) { + if (refField.getAccessModifier() != PsiModifier.PRIVATE) { + getManager().enqueueFieldUsagesProcessor(refField, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + myFilter.addIgnoreList(refField); + return false; + } + }); + } + } + + public void visitMethod(final RefMethod refMethod) { + if (refMethod.isAppMain()) { + myFilter.addIgnoreList(refMethod); + } + else if (!refMethod.isLibraryOverride() && refMethod.getAccessModifier() != PsiModifier.PRIVATE && + !(refMethod instanceof RefImplicitConstructor)) { + getManager().enqueueDerivedMethodsProcessing(refMethod, new InspectionManagerEx.DerivedMethodsProcessor() { + public boolean process(PsiMethod derivedMethod) { + myFilter.addIgnoreList(refMethod); + return false; + } + }); + + getManager().enqueueMethodUsagesProcessor(refMethod, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + myFilter.addIgnoreList(refMethod); + return false; + } + }); + } + } + + public void visitClass(final RefClass refClass) { + if (!refClass.isAnonymous()) { + getManager().enqueueDerivedClassesProcessing(refClass, new InspectionManagerEx.DerivedClassesProcessor() { + public boolean process(PsiClass inheritor) { + myFilter.addIgnoreList(refClass); + return false; + } + }); + + getManager().enqueueClassUsagesProcessing(refClass, new InspectionManagerEx.UsagesProcessor() { + public boolean process(PsiReference psiReference) { + myFilter.addIgnoreList(refClass); + return false; + } + }); + } + } + }); + } + } + }); + + return false; + } + + public void exportResults(final Element parentNode) { + getRefManager().iterate(new RefManager.RefIterator() { + public void accept(RefElement refElement) { + if (myFilter.accepts(refElement)) { + Element element = XMLExportUtl.createElement(refElement, parentNode, -1); + Element problemClassElement = new Element("problem_class"); + problemClassElement.addContent("access modifier can be weaker"); + element.addContent(problemClassElement); + Element descriptionElement = new Element("description"); + String possibleAccess = myFilter.getPossibleAccess(refElement); + descriptionElement.addContent("can be " + (possibleAccess == PsiModifier.PACKAGE_LOCAL ? "package local" : possibleAccess)); + element.addContent(descriptionElement); + } + } + }); + } + + public QuickFixAction[] getQuickFixes() { + return myQuickFixActions; + } + + public JobDescriptor[] getJobDescriptors() { + return new JobDescriptor[]{InspectionManagerEx.BUILD_GRAPH, InspectionManagerEx.FIND_EXTERNAL_USAGES}; + } + + private boolean isPackageLocalForMembersShouldBeSuggested() { + return SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS; + } + + private boolean isPackageLocalForTopClassesShouldBeSuggested() { + return SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES; + } + + private boolean isPrivateForInnersShouldBeSuggested() { + return SUGGEST_PRIVATE_FOR_INNERS; + } + + private void changeAccessLevel(PsiModifierListOwner psiElement, RefElement refElement, String newAccess) { + try { + if (psiElement instanceof PsiVariable) { + ((PsiVariable)psiElement).normalizeDeclaration(); + } + + PsiModifierList list = psiElement.getModifierList(); + + if (psiElement instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)psiElement; + PsiClass containingClass = psiMethod.getContainingClass(); + if (containingClass != null && containingClass.getParent() instanceof PsiFile && + newAccess == PsiModifier.PRIVATE && + list.hasModifierProperty(PsiModifier.FINAL)) { + list.setModifierProperty(PsiModifier.FINAL, false); + } + } + + list.setModifierProperty(newAccess, true); + refElement.setAccessModifier(newAccess); + myFilter.addIgnoreList(refElement); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + public void cleanup() { + super.cleanup(); + if (getFilter() != null) { + getFilter().cleanup(); + } + } + + public HTMLComposer getComposer() { + if (myComposer == null) { + myComposer = new VisibilityPageComposer(myFilter, this); + } + return myComposer; + } + + private class AcceptSuggestedAccess extends QuickFixAction { + private AcceptSuggestedAccess() { + super("Accept Suggested Access Level", VisibilityInspection.this); + } + + protected boolean applyFix(RefElement[] refElements) { + for (int i = 0; i < refElements.length; i++) { + RefElement refElement = refElements[i]; + PsiModifierListOwner psiElement = refElement.getElement(); + if (psiElement == null) continue; + String accessLevel = getFilter().getPossibleAccess(refElement); + changeAccessLevel(psiElement, refElement, accessLevel); + } + + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/Chunk.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/Chunk.java new file mode 100644 index 00000000000..025cafca83f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/Chunk.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler; + +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Eugene Zhuravlev + * Date: Sep 27, 2004 + */ +public class Chunk { + private final Set myNodes; + + public Chunk(Node node) { + this(new HashSet()); + myNodes.add(node); + } + + public Chunk(Set nodes) { + myNodes = nodes; + } + + public Set getNodes() { + return myNodes; + } + + public boolean containsNode(Node node) { + return myNodes.contains(node); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Chunk)) return false; + + final Chunk chunk = (Chunk)o; + + if (!myNodes.equals(chunk.myNodes)) return false; + + return true; + } + + public int hashCode() { + return myNodes.hashCode(); + } + + public String toString() { // for debugging only + final StringBuffer buf = new StringBuffer(); + buf.append("["); + for (Iterator it = myNodes.iterator(); it.hasNext();) { + final Node node = it.next(); + if (buf.length() > 1) { + buf.append(", "); + } + buf.append(node.toString()); + } + buf.append("]"); + return buf.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerConfiguration.java new file mode 100644 index 00000000000..53cc6da932b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerConfiguration.java @@ -0,0 +1,463 @@ +/** + * created at Jan 3, 2002 + * @author Jeka + */ +package com.intellij.compiler; + +import com.intellij.compiler.impl.ExcludeEntryDescription; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Options; +import org.jdom.Element; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class CompilerConfiguration implements JDOMExternalizable, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.CompilerConfiguration"); + + public static final String TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME = "tests.external.compiler.home"; + public static final int DEPENDENCY_FORMAT_VERSION = 41; + public static final String JAVAC = "Javac"; + public static final String JIKES = "Jikes"; + + public String DEFAULT_COMPILER = JAVAC; + public boolean CLEAR_OUTPUT_DIRECTORY = false; + + public static final String SINGLE = "single"; + // exclude from compile + private List myExcludeEntryDescriptions = new ArrayList(); + // extensions of the files considered as resource files + private List myRegexpResourcePaterns = new ArrayList(getDefaultRegexpPatterns()); + // extensions of the files considered as resource files. If present, Overrides patterns in old regexp format stored in myRegexpResourcePaterns + private List myWildcardPatterns = new ArrayList(); + private List myWildcardCompiledPatterns = new ArrayList(); + private boolean myWildcardPatternsInitialized = false; + private final Project myProject; + + + public int DEPLOY_AFTER_MAKE = Options.SHOW_DIALOG; + + { + loadDefaultWildcardPatterns(); + } + + public CompilerConfiguration(Project project) { + myProject = project; + } + + public void loadDefaultWildcardPatterns() { + if (!myWildcardPatterns.isEmpty()) { + removeWildcardPatterns(); + } + addWildcardResourcePattern("?*.properties"); + addWildcardResourcePattern("?*.xml"); + addWildcardResourcePattern("?*.gif"); + addWildcardResourcePattern("?*.png"); + addWildcardResourcePattern("?*.jpeg"); + addWildcardResourcePattern("?*.jpg"); + addWildcardResourcePattern("?*.html"); + addWildcardResourcePattern("?*.dtd"); + addWildcardResourcePattern("?*.tld"); + } + + private List getDefaultRegexpPatterns() { + return Arrays.asList(new Pattern[] { + compilePattern(".+\\.(properties|xml|html|dtd|tld)"), + compilePattern(".+\\.(gif|png|jpeg|jpg)") + }); + } + + private Pattern compilePattern(String s) throws PatternSyntaxException { + final Pattern pattern; + if (SystemInfo.isFileSystemCaseSensitive) { + pattern = Pattern.compile(s); + } + else { + pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE); + } + return pattern; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public String[] getResourceFilePatterns() { + return getWildcardPatterns(); + } + + public String[] getRegexpPatterns() { + String[] patterns = new String[myRegexpResourcePaterns.size()]; + int index = 0; + for (Iterator it = myRegexpResourcePaterns.iterator(); it.hasNext();) { + patterns[index++] = ((Pattern)it.next()).pattern(); + } + return patterns; + } + + public String[] getWildcardPatterns() { + return myWildcardPatterns.toArray(new String[myWildcardPatterns.size()]); + } + + public void addResourceFilePattern(String namePattern) throws PatternSyntaxException { + addWildcardResourcePattern(namePattern); + } + + // need this method only for handling patterns in old regexp format + private void addRegexpPattern(String namePattern) { + Pattern pattern = compilePattern(namePattern); + if (pattern != null) { + myRegexpResourcePaterns.add(pattern); + } + } + + private void addWildcardResourcePattern(final String wildcardPattern) { + final Pattern pattern = compilePattern(convertToRegexp(wildcardPattern)); + if (pattern != null) { + myWildcardPatterns.add(wildcardPattern); + myWildcardCompiledPatterns.add(pattern.matcher("")); + } + } + + public void removeResourceFilePatterns() { + removeWildcardPatterns(); + } + + public void removeRegexpPatterns() { + myRegexpResourcePaterns.clear(); + } + + public void removeWildcardPatterns() { + myWildcardPatterns.clear(); + myWildcardCompiledPatterns.clear(); + } + + private String convertToRegexp(String wildcardPattern) { + if (isPatternNegated(wildcardPattern)) { + wildcardPattern = wildcardPattern.substring(1); + } + return wildcardPattern. + replaceAll("\\\\!", "!"). + replaceAll("\\.", "\\\\."). + replaceAll("\\*\\?", ".+"). + replaceAll("\\?\\*", ".+"). + replaceAll("\\*", ".*"). + replaceAll("\\?", "."). + replaceAll("(?:\\.\\*)+", ".*") // optimization + ; + } + + public boolean isPatternNegated(String wildcardPattern) { + return wildcardPattern.length() > 1 && wildcardPattern.charAt(0) == '!'; + } + + public boolean isResourceFile(String name) { + int idx = 0; + for (Iterator it = myWildcardCompiledPatterns.iterator(); it.hasNext(); idx++) { + final Matcher matcher = it.next(); + matcher.reset(name); + final boolean matches = matcher.matches(); + if (isPatternNegated(myWildcardPatterns.get(idx))? !matches : matches) { + return true; + } + } + return false; + } + + public ExcludeEntryDescription[] getExcludeEntryDescriptions() { + return (ExcludeEntryDescription[])myExcludeEntryDescriptions.toArray(new ExcludeEntryDescription[myExcludeEntryDescriptions.size()]); + } + + public void addExcludeEntryDescription(ExcludeEntryDescription description) { + myExcludeEntryDescriptions.add(description); + } + + public void removeAllExcludeEntryDescriptions() { + myExcludeEntryDescriptions.clear(); + } + + // property names + private static final String EXCLUDE_FROM_COMPILE = "excludeFromCompile"; + private static final String RESOURCE_EXTENSIONS = "resourceExtensions"; + private static final String WILDCARD_RESOURCE_PATTERNS = "wildcardResourcePatterns"; + private static final String ENTRY = "entry"; + private static final String NAME = "name"; + private static final String FILE = "file"; + private static final String DIRECTORY = "directory"; + private static final String URL = "url"; + private static final String INCLUDE_SUBDIRECTORIES = "includeSubdirectories"; + + public void readExternal(Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + + Element node = parentNode.getChild(EXCLUDE_FROM_COMPILE); + if (node != null) { + for (Iterator i = node.getChildren().iterator(); i.hasNext();) { + Element element = (Element)i.next(); + String url = element.getAttributeValue(URL); + if (url == null) continue; + if(FILE.equals(element.getName())) { + ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, false, true); + myExcludeEntryDescriptions.add(excludeEntryDescription); + } + if(DIRECTORY.equals(element.getName())) { + boolean includeSubdirectories = true; + if("false".equals(element.getAttributeValue(INCLUDE_SUBDIRECTORIES))) { + includeSubdirectories = false; + } + ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, includeSubdirectories, false); + myExcludeEntryDescriptions.add(excludeEntryDescription); + } + } + } + + removeRegexpPatterns(); + node = parentNode.getChild(RESOURCE_EXTENSIONS); + if (node != null) { + for (Iterator iterator = node.getChildren(ENTRY).iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + String pattern = element.getAttributeValue(NAME); + if (pattern != null && !"".equals(pattern)) { + addRegexpPattern(pattern); + } + } + } + + removeWildcardPatterns(); + node = parentNode.getChild(WILDCARD_RESOURCE_PATTERNS); + if (node != null) { + myWildcardPatternsInitialized = true; + for (Iterator iterator = node.getChildren(ENTRY).iterator(); iterator.hasNext();) { + final Element element = (Element)iterator.next(); + String pattern = element.getAttributeValue(NAME); + if (pattern != null && !"".equals(pattern)) { + addWildcardResourcePattern(pattern); + } + } + } + + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, parentNode); + + if(myExcludeEntryDescriptions.size() > 0) { + Element newChild = new Element(EXCLUDE_FROM_COMPILE); + for (Iterator it = myExcludeEntryDescriptions.iterator(); it.hasNext();) { + ExcludeEntryDescription description = (ExcludeEntryDescription)it.next(); + if(description.isFile()) { + Element entry = new Element(FILE); + entry.setAttribute(URL, description.getUrl()); + newChild.addContent(entry); + } + else { + Element entry = new Element(DIRECTORY); + entry.setAttribute(URL, description.getUrl()); + entry.setAttribute(INCLUDE_SUBDIRECTORIES, description.isIncludeSubdirectories() ? "true" : "false"); + newChild.addContent(entry); + } + } + parentNode.addContent(newChild); + } + + String[] patterns = getRegexpPatterns(); + final Element newChild = new Element(RESOURCE_EXTENSIONS); + for (int idx = 0; idx < patterns.length; idx++) { + final String pattern = patterns[idx]; + final Element entry = new Element(ENTRY); + entry.setAttribute(NAME, pattern); + newChild.addContent(entry); + } + parentNode.addContent(newChild); + + if (myWildcardPatternsInitialized || !myWildcardPatterns.isEmpty()) { + final Element wildcardPatterns = new Element(WILDCARD_RESOURCE_PATTERNS); + for (Iterator it = myWildcardPatterns.iterator(); it.hasNext();) { + final String wildcardPattern = it.next(); + final Element entry = new Element(ENTRY); + entry.setAttribute(NAME, wildcardPattern); + wildcardPatterns.addContent(entry); + } + parentNode.addContent(wildcardPatterns); + } + } + + public static CompilerConfiguration getInstance(Project project) { + return project.getComponent(CompilerConfiguration.class); + } + + public boolean isExcludedFromCompilation(VirtualFile virtualFile) { + for (Iterator it = myExcludeEntryDescriptions.iterator(); it.hasNext();) { + ExcludeEntryDescription entryDescription = (ExcludeEntryDescription)it.next(); + VirtualFile descriptionFile = entryDescription.getVirtualFile(); + if (descriptionFile == null) { + continue; + } + if(entryDescription.isFile()) { + if(descriptionFile.equals(virtualFile)) { + return true; + } + } + else { + if(entryDescription.isIncludeSubdirectories()) { + if (VfsUtil.isAncestor(descriptionFile, virtualFile, false)) { + return true; + } + } + else { + if (virtualFile.isDirectory()) { + continue; + } + if (descriptionFile.equals(virtualFile.getParent())) { + return true; + } + } + } + } + return false; + } + + public String getComponentName() { + return "CompilerConfiguration"; + } + + public String getDefaultCompiler() { + return DEFAULT_COMPILER; + } + + public void setDefaultCompiler(String defaultCompiler) { + LOG.assertTrue(defaultCompiler.equals(JAVAC) || defaultCompiler.equals(JIKES), "Unsupported compiler"); + this.DEFAULT_COMPILER = defaultCompiler; + } + + public boolean isClearOutputDirectory() { + return CLEAR_OUTPUT_DIRECTORY; + } + + public void setClearOutputDirectory(boolean value) { + this.CLEAR_OUTPUT_DIRECTORY = value; + } + + public void convertPatterns() { + if (!needPatternConversion()) { + return; + } + try { + boolean ok = doConvertPatterns(); + if (!ok) { + final String initialPatternString = patternsToString(getRegexpPatterns()); + final String message = "The format of resource patterns has changed.\n" + + "IDEA failed to convert existing regular expression patterns:\n" + + initialPatternString +"\n" + + "Please enter pattern string in a new format.\n" + + "Each resource pattern may contain the following wildcards:\n" + + "? - one character\n" + + "* - zero or more characters\n" + + "! - negate the pattern (allowed only at the start of a pattern)\n" + + "Use ; (semicolon) to separate resource patterns;\n" + + "Escape the \"!\" character with a backslash (\"\\\").\n" + + "You might also need to modify template project settings.\n" + + "Press \"OK\" to accept entered patterns, \"Cancel\" to load default patterns in new format."; + final String wildcardPatterns = Messages.showInputDialog(myProject, message, "Pattern Conversion", Messages.getWarningIcon(), initialPatternString, new InputValidator() { + public boolean checkInput(String inputString) { + return true; + } + public boolean canClose(String inputString) { + final StringTokenizer tokenizer = new StringTokenizer(inputString, ";", false); + StringBuffer errMessage = new StringBuffer(); + + while (tokenizer.hasMoreTokens()) { + String pattern = tokenizer.nextToken(); + try { + addWildcardResourcePattern(pattern); + } + catch (PatternSyntaxException e) { + errMessage.append("\n\n"); + errMessage.append(pattern); + errMessage.append(": "); + errMessage.append(e.getMessage()); + } + } + + if (errMessage.length() > 0) { + errMessage.insert(0, "The following resource patterns are malformed:"); + Messages.showErrorDialog(errMessage.toString(), "Malformed Resource Patterns"); + removeWildcardPatterns(); + return false; + } + return true; + } + }); + if (wildcardPatterns == null) { // cancel pressed + loadDefaultWildcardPatterns(); + } + } + } + finally { + myWildcardPatternsInitialized = true; + } + } + + private boolean needPatternConversion() { + return !myWildcardPatternsInitialized && !myRegexpResourcePaterns.isEmpty(); + } + + private boolean doConvertPatterns() { + final String[] regexpPatterns = getRegexpPatterns(); + final List converted = new ArrayList(); + final Pattern multipleExtensionsPatternPattern = compilePattern("\\.\\+\\\\\\.\\((\\w+(?:\\|\\w+)*)\\)"); + final Pattern singleExtensionPatternPattern = compilePattern("\\.\\+\\\\\\.(\\w+)"); + for (int idx = 0; idx < regexpPatterns.length; idx++) { + final String regexpPattern = regexpPatterns[idx]; + final Matcher multipleExtensionsMatcher = multipleExtensionsPatternPattern.matcher(regexpPattern); + if (multipleExtensionsMatcher.matches()) { + final StringTokenizer tokenizer = new StringTokenizer(multipleExtensionsMatcher.group(1), "|", false); + while (tokenizer.hasMoreTokens()) { + converted.add("?*." + tokenizer.nextToken()); + } + } + else { + final Matcher singleExtensionMatcher = singleExtensionPatternPattern.matcher(regexpPattern); + if (singleExtensionMatcher.matches()) { + converted.add("?*." + singleExtensionMatcher.group(1)); + } + else { + return false; + } + } + } + for (Iterator it = converted.iterator(); it.hasNext();) { + final String wildcardPattern = (String)it.next(); + addWildcardResourcePattern(wildcardPattern); + } + return true; + } + + private static String patternsToString(final String[] patterns) { + final StringBuffer extensionsString = new StringBuffer(); + for (int idx = 0; idx < patterns.length; idx++) { + if (idx > 0) { + extensionsString.append(";"); + } + extensionsString.append(patterns[idx]); + } + return extensionsString.toString(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerException.java new file mode 100644 index 00000000000..0962db6877c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerException.java @@ -0,0 +1,14 @@ +/* + * @author: Eugene Zhuravlev + * Date: Oct 15, 2002 + * Time: 1:55:22 PM + */ +package com.intellij.compiler; + +public class CompilerException extends Exception { + + public CompilerException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerIOUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerIOUtil.java new file mode 100644 index 00000000000..6882780089d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerIOUtil.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class CompilerIOUtil { + public static String readString(DataInput stream) throws IOException { + final int length = stream.readInt(); + if (length == -1) { + return null; + } + if (length == 0) { + return ""; + } + + char[] chars = new char[length]; + byte[] bytes = new byte[length*2]; + stream.readFully(bytes); + + for (int i = 0, i2 = 0; i < length; i++, i2+=2) { + chars[i] = (char)((bytes[i2] << 8) + bytes[i2 + 1]); + } + + return StringFactory.createStringFromConstantArray(chars); + } + + public static void writeString(String s, DataOutput stream) throws IOException { + if (s == null) { + stream.writeInt(-1); + return; + } + + if (s.length() == 0) { + stream.writeInt(0); + return; + } + + char[] chars = s.toCharArray(); + byte[] bytes = new byte[chars.length * 2]; + + stream.writeInt(chars.length); + for (int i = 0, i2 = 0; i < chars.length; i++, i2 += 2) { + char aChar = chars[i]; + bytes[i2] = (byte)((aChar >>> 8) & 0xFF); + bytes[i2 + 1] = (byte)((aChar) & 0xFF); + } + + stream.write(bytes); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerMessageImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerMessageImpl.java new file mode 100644 index 00000000000..2e5b92fb2c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerMessageImpl.java @@ -0,0 +1,121 @@ +package com.intellij.compiler; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilerMessage; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +public final class CompilerMessageImpl implements CompilerMessage { + + private Project myProject; + private final CompilerMessageCategory myCategory; + private final String myMessage; + private VirtualFile myFile; + private final int myRow; + private final int myColumn; + + public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message, final String url, int row, int column) { + myProject = project; + myCategory = category; + myMessage = (message != null)? message : ""; + myRow = row; + myColumn = column; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + myFile = (url != null)? VirtualFileManager.getInstance().findFileByUrl(url) : null; + } + }); + } + + public CompilerMessageCategory getCategory() { + return myCategory; + } + + public String getMessage() { + return myMessage; + } + + public Navigatable getNavigatable() { + final VirtualFile virtualFile = getVirtualFile(); + if (virtualFile != null) { + final int line = getLine() - 1; // editor lines are zero-based + final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document != null && line >= 0 && line < document.getLineCount()) { + final int offset; + if (getColumn() > 0) { + final int lineStart = document.getLineStartOffset(line); + final int lineEnd = document.getLineEndOffset(line); + final CharSequence chText = document.getCharsSequence().subSequence(lineStart, lineEnd); + final int tabSize = CodeStyleSettingsManager.getSettings(myProject).getTabSize(FileTypeManager.getInstance().getFileTypeByFile(virtualFile)); + offset = lineStart + EditorUtil.calcOffset(null, chText, 0, chText.length(), getColumn(), tabSize) - 1; + } + else { + offset = document.getLineStartOffset(line); + } + if (offset >= 0 && offset < document.getTextLength()) { + return new OpenFileDescriptor(myProject, virtualFile, offset); + } + } + } + return null; + } + + public VirtualFile getVirtualFile() { + return myFile; + } + + public String getExportTextPrefix() { + if (getLine() >= 0) return "line (" + getLine() + ")"; + + return ""; + } + + public String getRenderTextPrefix() { + if (getLine() >= 0) return "(" + getLine() + ", " + getColumn() + ")"; + + return ""; + } + + public int getLine() { + return myRow; + } + + public int getColumn() { + return myColumn; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CompilerMessage)) return false; + + final CompilerMessageImpl compilerMessage = (CompilerMessageImpl)o; + + if (myColumn != compilerMessage.myColumn) return false; + if (myRow != compilerMessage.myRow) return false; + if (!myCategory.equals(compilerMessage.myCategory)) return false; + if (myFile != null ? !myFile.equals(compilerMessage.myFile) : compilerMessage.myFile != null) return false; + if (!myMessage.equals(compilerMessage.myMessage)) return false; + + return true; + } + + public int hashCode() { + int result; + result = myCategory.hashCode(); + result = 29 * result + myMessage.hashCode(); + result = 29 * result + (myFile != null ? myFile.hashCode() : 0); + result = 29 * result + myRow; + result = 29 * result + myColumn; + return result; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerWorkspaceConfiguration.java new file mode 100644 index 00000000000..2359009e683 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/CompilerWorkspaceConfiguration.java @@ -0,0 +1,49 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.compiler; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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 org.jdom.Element; + +public class CompilerWorkspaceConfiguration implements JDOMExternalizable, ProjectComponent { + + public boolean COMPILE_IN_BACKGROUND = false; + public boolean AUTO_SHOW_ERRORS_IN_EDITOR = true; + public boolean CLOSE_MESSAGE_VIEW_IF_SUCCESS = true; + public boolean COMPILE_DEPENDENT_FILES = false; + + + public static CompilerWorkspaceConfiguration getInstance(Project project) { + return project.getComponent(CompilerWorkspaceConfiguration.class); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getComponentName() { + return "CompilerWorkspaceConfiguration"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/HelpID.java new file mode 100644 index 00000000000..6d9a878dd35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/HelpID.java @@ -0,0 +1,8 @@ +package com.intellij.compiler; + +/** + * + */ +public interface HelpID { + String COMPILER = "compiling"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacOutputParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacOutputParser.java new file mode 100644 index 00000000000..261674f8000 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacOutputParser.java @@ -0,0 +1,267 @@ +package com.intellij.compiler; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; + +public class JavacOutputParser extends OutputParser { + private int myTabSize; + + public JavacOutputParser(Project project) { + myTabSize = CodeStyleSettingsManager.getSettings(project).getTabSize(StdFileTypes.JAVA); + } + + public boolean processMessageLine(Callback callback) { + final String line = callback.getNextLine(); + if(line == null) { + return false; + } + if (StringUtil.startsWithChar(line, '[') && StringUtil.endsWithChar(line, ']')){ + processLoading(line, callback); + return true; + } + int colonIndex1 = line.indexOf(':'); + if (colonIndex1 == 1){ // drive letter + colonIndex1 = line.indexOf(':', colonIndex1 + 1); + } + if(colonIndex1 == -1) { + if(line.endsWith("errors") || line.endsWith("error")) { + //addMessage(messageHandler,MessageCategory.STATISTICS, line); + return true; + } + if(line.endsWith("warnings") || line.endsWith("warning")) { + //addMessage(messageHandler,MessageCategory.STATISTICS, line); + return true; + } + } + + if (colonIndex1 >= 0){ + String part1 = line.substring(0, colonIndex1).trim(); + + if(part1.equals("error")) { + addMessage(callback, CompilerMessageCategory.ERROR, line.substring(colonIndex1)); + return true; + } + if(part1.equals("javac")) { + addMessage(callback, CompilerMessageCategory.ERROR, line); + return true; + } + + int colonIndex2 = line.indexOf(':', colonIndex1 + 1); + if (colonIndex2 >= 0){ + final String filePath = part1.replace(File.separatorChar, '/'); + final VirtualFile[] file = new VirtualFile[1]; + ApplicationManager.getApplication().runReadAction(new Runnable(){ + public void run(){ + file[0] = LocalFileSystem.getInstance().findFileByPath(filePath); + } + }); + + try { + int lineNum = Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim()); + String message = line.substring(colonIndex2 + 1).trim(); + CompilerMessageCategory category = CompilerMessageCategory.ERROR; + if (message.startsWith("warning:")){ + message = message.substring("warning:".length()).trim(); + category = CompilerMessageCategory.WARNING; + } + + ArrayList messages = new ArrayList(); + messages.add(message); + int colNum = 0; + String prevLine = null; + do{ + final String nextLine = callback.getNextLine(); + if (nextLine == null) { + return false; + } + if (nextLine.trim().equals("^")){ + final int fakeColNum = nextLine.indexOf('^') + 1; + final CharSequence chars = (prevLine != null)? prevLine : line; + final int offsetColNum = EditorUtil.calcOffset(null, chars, 0, chars.length(), fakeColNum, 8); + colNum = EditorUtil.calcColumnNumber(null, chars,0, offsetColNum, myTabSize); + break; + } + if (prevLine != null) { + messages.add(prevLine); + } + prevLine = nextLine; + } + while(true); + + if (colNum > 0){ + messages = convertMessages(messages); + StringBuffer buf = new StringBuffer(); + for (Iterator it = messages.iterator(); it.hasNext();) { + String m = (String)it.next(); + if (buf.length() > 0) { + buf.append("\n"); + } + buf.append(m); + } + addMessage(callback, category, buf.toString(), VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath), lineNum, colNum); + return true; + } + } + catch (NumberFormatException e) { + } + } + } + + if(line.endsWith("java.lang.OutOfMemoryError")) { + addMessage(callback, CompilerMessageCategory.ERROR, "Out of memory. Increase the maximum heap size in Project Properties|Compiler settings."); + return true; + } + + addMessage(callback, CompilerMessageCategory.INFORMATION, line); + return true; + } + + + private static ArrayList convertMessages(ArrayList messages) { + if(messages.size() <= 1) { + return messages; + } + String line0 = (String)messages.get(0); + String line1 = (String)messages.get(1); + int colonIndex = line1.indexOf(':'); + if (colonIndex > 0){ + String part1 = line1.substring(0, colonIndex).trim(); + if (part1.equals("symbol")){ + String symbol = line1.substring(colonIndex + 1).trim(); + messages.remove(1); + if(messages.size() >= 2) { + messages.remove(1); + } + messages.set(0, line0+" " + symbol); + } + } + return messages; + } + + /* + private boolean isError(String line) { + for (int idx = 0; idx < myErrorPatterns.length; idx++) { + Pattern errorPattern = myErrorPatterns[idx]; + if (errorPattern.matcher(line).matches()) { + return true; + } + } + return false; + } + + private boolean isWarning(String line) { + for (int idx = 0; idx < myWarningPatterns.length; idx++) { + Pattern errorPattern = myWarningPatterns[idx]; + if (errorPattern.matcher(line).matches()) { + return true; + } + } + return false; + } + + + private Pattern[] myErrorPatterns; + private Pattern[] myWarningPatterns; + + private static final String COMPILER_RB = "com.sun.tools.javac.v8.resources.compiler"; + + private void precompilePatterns(Project project) { + final ClassLoader loader = createLoader((ProjectJdkEx)ProjectRootManagerEx.getInstanceEx(project).getJdk()); + if (loader == null) { + return; + } + final ResourceBundle bundle = ResourceBundle.getBundle(COMPILER_RB, Locale.getDefault(), loader); + final Enumeration keys = bundle.getKeys(); + List errorPatterns = new ArrayList(); + List warningPatterns = new ArrayList(); + while (keys.hasMoreElements()) { + final Object elem = keys.nextElement(); + if (!(elem instanceof String)) { + continue; + } + String key = (String)elem; + if (key.startsWith("compiler.err.")) { + addPattern(errorPatterns, bundle.getString(key)); + } + else if (key.startsWith("compiler.warn.")) { + addPattern(warningPatterns, bundle.getString(key)); + } + } + myErrorPatterns = (Pattern[])errorPatterns.toArray(new Pattern[errorPatterns.size()]); + myWarningPatterns = (Pattern[])warningPatterns.toArray(new Pattern[warningPatterns.size()]); + } + + private static ClassLoader createLoader(final ProjectJdkEx jdk){ + if (jdk == null) { + return null; + } + final String toolsJarPath = jdk.getToolsPath(); + try { + final URL url = new URL("file:"+toolsJarPath.replace(File.separatorChar, '/')); + ClassLoader loader = new URLClassLoader(new URL[] {url}, null); + + if (LOG.isDebugEnabled()) { + LOG.debug("COMPILER RESOURCE BUNDLE URL = " + url); + } + + return loader; + } + catch (MalformedURLException e) { + LOG.error(e); + return null; + } + } + + private static void addPattern(Collection patterns, String patternString) { + final int length = patternString.length(); + StringBuffer buf = new StringBuffer(length); + boolean insideParam = false; + for (int idx = 0; idx < length; idx++ ) { + final char ch = patternString.charAt(idx); + if (ch == '{') { + insideParam = true; + continue; + } + if (ch == '}') { + insideParam = false; + buf.append(".*?"); + continue; + } + if (!insideParam) { + if (ch == '\\') { + continue; // quote character + } + if (ch == '\'') { // check double quotes + if (idx + 1 < length) { + if (patternString.charAt(idx+1) == '\'') { + idx += 1; + buf.append('\''); + continue; + } + } + } + if (ch == '(' || ch == ')' || ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == '.' || ch == '*'){ + buf.append('\\'); + } + buf.append(ch); + } + } + final Pattern pattern = Pattern.compile(buf.toString()); + patterns.add(pattern); + } + */ + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacSettings.java new file mode 100644 index 00000000000..77d97c09d97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JavacSettings.java @@ -0,0 +1,99 @@ +package com.intellij.compiler; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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.openapi.vfs.CharsetToolkit; +import org.jdom.Element; + +import java.nio.charset.Charset; +import java.util.StringTokenizer; + +public class JavacSettings implements JDOMExternalizable, ProjectComponent { + public boolean DEBUGGING_INFO = true; + public boolean GENERATE_NO_WARNINGS = false; + public boolean DEPRECATION = true; + public String ADDITIONAL_OPTIONS_STRING = ""; + public int MAXIMUM_HEAP_SIZE = 128; + public boolean USE_GENERICS_COMPILER = false; + + private boolean myTestsUseExternalCompiler = false; + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public boolean isTestsUseExternalCompiler() { + return myTestsUseExternalCompiler; + } + + public void setTestsUseExternalCompiler(boolean testsUseExternalCompiler) { + myTestsUseExternalCompiler = testsUseExternalCompiler; + } + + public String getOptionsString() { + StringBuffer options = new StringBuffer(); + if(DEBUGGING_INFO) { + options.append("-g "); + } + if(DEPRECATION) { + options.append("-deprecation "); + } + if(GENERATE_NO_WARNINGS) { + options.append("-nowarn "); + } + boolean isEncodingSet = false; + final StringTokenizer tokenizer = new StringTokenizer(ADDITIONAL_OPTIONS_STRING, " \t\r\n"); + while(tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if("-g".equals(token)) { + continue; + } + if("-deprecation".equals(token)) { + continue; + } + if("-nowarn".equals(token)) { + continue; + } + options.append(token); + options.append(" "); + if ("-encoding".equals(token)) { + isEncodingSet = true; + } + } + if (!isEncodingSet) { + final Charset ideCharset = CharsetToolkit.getIDEOptionsCharset(); + if ((CharsetToolkit.getDefaultSystemCharset() != ideCharset)) { + options.append("-encoding "); + options.append(ideCharset.name()); + } + } + return options.toString(); + } + + public static JavacSettings getInstance(Project project) { + return project.getComponent(JavacSettings.class); + } + + public String getComponentName() { + return "JavacSettings"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesOutputParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesOutputParser.java new file mode 100644 index 00000000000..f7f43382b38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesOutputParser.java @@ -0,0 +1,124 @@ +package com.intellij.compiler; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.util.text.StringUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.StringTokenizer; + +public class JikesOutputParser extends OutputParser { + private JikesSettings myJikesSettings; + + public JikesOutputParser(Project project) { + myJikesSettings = JikesSettings.getInstance(project); + } + + public boolean processMessageLine(Callback callback) { + String line = callback.getNextLine(); + if (line == null) { + return false; + } + if (line.equals("")) { + /* + if (JikesSettings.getInstance(project).IS_INCREMENTAL_MODE) { + return true; + } + */ + return false; + } + if (StringUtil.startsWithChar(line, '[') && StringUtil.endsWithChar(line, ']')) { + processLoading(line, callback); + return true; + } +//sae + if (myJikesSettings.IS_EMACS_ERRORS_MODE) { + int colNum; + int lineNum; + + String filePath = ""; + if (line.indexOf(".java:") > 5) filePath = line.substring(0, line.indexOf(".java:") + 5); + filePath = filePath.replace(File.separatorChar, '/'); + final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath); + final VirtualFile[] file = new VirtualFile[1]; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + file[0] = VirtualFileManager.getInstance().findFileByUrl(url); + } + }); + if (line.indexOf(".java:") > 6) { + line = line.substring(line.indexOf(".java:") + 6); + +//second token = start line + StringTokenizer tokenizer = new StringTokenizer(line, ":"); +//first token = filename + String token = tokenizer.nextToken(); + + try { + lineNum = Integer.parseInt(token); + } + catch (Exception e) { + addMessage(callback, CompilerMessageCategory.INFORMATION, line); + return true; + } +//thrd token = start column + token = tokenizer.nextToken(); + try { + colNum = Integer.parseInt(token); + } + catch (Exception e) { + addMessage(callback, CompilerMessageCategory.INFORMATION, line); + return true; + } +//4,5 token = end line/column tmp not used + tokenizer.nextToken(); + tokenizer.nextToken(); +// 6 error type + CompilerMessageCategory category = CompilerMessageCategory.INFORMATION; + ArrayList messages = new ArrayList(); + String message; + token = tokenizer.nextToken().trim(); + if ("Caution".equalsIgnoreCase(token)) { + category = CompilerMessageCategory.WARNING; + } + else if ("Warning".equalsIgnoreCase(token) || "Semantic Warning".equalsIgnoreCase(token)) { // Semantic errors/warnings were introduced in jikes 1.18 + category = CompilerMessageCategory.WARNING; + } + else if ("Error".equalsIgnoreCase(token) || "Semantic Error".equalsIgnoreCase(token)) { + category = CompilerMessageCategory.ERROR; + } + + message = token; + message = message.concat(" "); + message = message.concat(tokenizer.nextToken("")); + messages.add(message); + + if (colNum > 0 && messages.size() > 0) { + StringBuffer buf = new StringBuffer(); + for (Iterator it = messages.iterator(); it.hasNext();) { + String m = (String)it.next(); + if (buf.length() > 0) { + buf.append("\n"); + } + buf.append(m); + } + addMessage(callback, category, buf.toString(), url, lineNum, colNum); + return true; + } + } + } +//--sae + +//Enter to continue + if (!(line.matches(".*Enter\\s+to\\s+continue.*"))) { + addMessage(callback, CompilerMessageCategory.INFORMATION, line); + } + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesSettings.java new file mode 100644 index 00000000000..533b1a3e6ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/JikesSettings.java @@ -0,0 +1,98 @@ +package com.intellij.compiler; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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 org.jdom.Element; + +import java.util.StringTokenizer; + +public class JikesSettings implements JDOMExternalizable, ProjectComponent { + public String JIKES_PATH = ""; + public boolean DEBUGGING_INFO = true; + public boolean DEPRECATION = true; + public boolean GENERATE_NO_WARNINGS = false; + public boolean IS_EMACS_ERRORS_MODE = true; + + public String ADDITIONAL_OPTIONS_STRING = ""; + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public String getOptionsString() { + StringBuffer options = new StringBuffer(); + if(DEBUGGING_INFO) { + options.append("-g "); + } + if(DEPRECATION) { + options.append("-deprecation "); + } + if(GENERATE_NO_WARNINGS) { + options.append("-nowarn "); + } + /* + if(IS_INCREMENTAL_MODE) { + options.append("++ "); + } + */ + if(IS_EMACS_ERRORS_MODE) { + options.append("+E "); + } + + StringTokenizer tokenizer = new StringTokenizer(ADDITIONAL_OPTIONS_STRING, " \t\r\n"); + while(tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if("-g".equals(token)) { + continue; + } + if("-deprecation".equals(token)) { + continue; + } + if("-nowarn".equals(token)) { + continue; + } + if("++".equals(token)) { + continue; + } + if("+M".equals(token)) { + continue; + } + if("+F".equals(token)) { + continue; + } + if("+E".equals(token)) { + continue; + } + options.append(token); + options.append(" "); + } + return options.toString(); + } + + public static JikesSettings getInstance(Project project) { + return project.getComponent(JikesSettings.class); + } + + public String getComponentName() { + return "JikesSettings"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ModuleCompilerUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ModuleCompilerUtil.java new file mode 100644 index 00000000000..20371ada3d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ModuleCompilerUtil.java @@ -0,0 +1,228 @@ +package com.intellij.compiler; + +import com.intellij.j2ee.j2eeDom.J2EEModuleProperties; +import com.intellij.j2ee.j2eeDom.application.J2EEApplicationModel; +import com.intellij.j2ee.j2eeDom.application.ModuleInApplication; +import com.intellij.j2ee.j2eeDom.xmlData.ObjectsList; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; + +import java.util.*; + +/** + * @author dsl + */ +public final class ModuleCompilerUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.ModuleCompilerUtil"); + private ModuleCompilerUtil() { } + + public static Module[] getDependencies(Module module) { + if (!ModuleType.J2EE_APPLICATION.equals(module.getModuleType())) { + return ModuleRootManager.getInstance(module).getDependencies(); + } + List result = new ArrayList(); + final ObjectsList modules = ((J2EEApplicationModel)J2EEModuleProperties.getInstance(module)).getModules(); + final Iterator iterator = modules.iterator(); + while (iterator.hasNext()) { + final ModuleInApplication moduleInApplication = iterator.next(); + final Module depModule = moduleInApplication.getReferenceModule(); + if (depModule != null && !dependsOn(depModule, module)) { + result.add(depModule); + } + } + return result.toArray(new Module[result.size()]); + } + + public static Comparator moduleDependencyComparator(Project project) { + final Module[] modules = ModuleManager.getInstance(project).getModules(); + final Graph graph = createModuleGraph(modules); + DFSTBuilder builder = new DFSTBuilder(graph); + return builder.comparator(); + } + + public static Graph createModuleGraph(final Module[] modules) { + return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return Arrays.asList(modules); + } + + public Iterator getIn(Module module) { + return Arrays.asList(getDependencies(module)).iterator(); + } + })); + } + + private static boolean dependsOn(Module dependant, Module dependee) { + if (dependant.equals(dependee)) return true; + final Module[] dependencies = ModuleRootManager.getInstance(dependant).getDependencies(); + for (int i = 0; i < dependencies.length; i++) { + final Module dependency = dependencies[i]; + if (dependsOn(dependency, dependee)) return true; + } + return false; + } + + + public static List> getSortedModuleChunks(Project project, Module[] modules) { + final Module[] allModules = ModuleManager.getInstance(project).getModules(); + return getSortedModuleChunks(modules, createModuleGraph(allModules)); + } + + public static List> getSortedModuleChunks(Module[] modules, Graph moduleGraph) { + final Graph> graph = toChunkGraph(moduleGraph); + final List> chunks = new ArrayList>(moduleGraph.getNodes().size()); + for (Iterator> it = graph.getNodes().iterator(); it.hasNext();) { + chunks.add(it.next()); + } + DFSTBuilder> builder = new DFSTBuilder>(graph); + if (!builder.isAcyclic()) { + LOG.error("Acyclic graph expected"); + return null; + } + + Collections.sort(chunks, builder.comparator()); + + if (LOG.isDebugEnabled()) { + LOG.debug("---Sorted module chunks:"); + logChunks(chunks); + } + + final Set modulesSet = new HashSet(Arrays.asList(modules)); + // leave only those chunks that contain at least one module from modules + for (Iterator> it = chunks.iterator(); it.hasNext();) { + final Chunk chunk = it.next(); + if (!intersects(chunk.getNodes(), modulesSet)) { + it.remove(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("---Chunks to be processed:"); + logChunks(chunks); + } + return chunks; + } + + private static void logChunks(final List> chunks) { + for (Iterator it = chunks.iterator(); it.hasNext();) { + final Chunk chunk = (Chunk)it.next(); + System.out.println(chunk); + } + System.out.println("---"); + } + + private static boolean intersects(Set set1, Set set2) { + for (Iterator it = set1.iterator(); it.hasNext();) { + if (set2.contains(it.next())) { + return true; + } + } + return false; + } + + public static Graph> toChunkGraph(final Graph graph) { + final Set> chunks = new HashSet>(); + + final Map> nodeToChunkMap = new HashMap>(); + for (Iterator it = graph.getNodes().iterator(); it.hasNext();) { + final Chunk chunk = buildChunk(graph, it.next()); + chunks.add(chunk); + for (Iterator nodeIterator = chunk.getNodes().iterator(); nodeIterator.hasNext();) { + nodeToChunkMap.put(nodeIterator.next(), chunk); + } + } + + return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph>() { + public Collection> getNodes() { + return chunks; + } + + public Iterator> getIn(Chunk chunk) { + final Set chunkNodes = chunk.getNodes(); + final Set> ins = new HashSet>(); + for (Iterator chunkNodesIterator = chunkNodes.iterator(); chunkNodesIterator.hasNext();) { + final Node node = chunkNodesIterator.next(); + for (Iterator nodeIns = graph.getIn(node); nodeIns.hasNext();) { + final Node in = nodeIns.next(); + if (!chunk.containsNode(in)) { + ins.add(nodeToChunkMap.get(in)); + } + } + } + return ins.iterator(); + } + })); + + } + + private static Chunk buildChunk(Graph graph, final Node node) { + final Set outs = new HashSet(); + final Set ins = new HashSet(); + + addAllReachable(graph, outs, node, true); // add all vertices reachable from node + addAllReachable(graph, ins, node, false); // add all vertices node is reachable from + + outs.retainAll(ins); + if (outs.isEmpty()) { + return new Chunk(node); + } + + return new Chunk(outs); + } + + private static void addAllReachable(Graph graph, final Set reachableSet, final Node node, final boolean fromTheNode) { + final Set toProcess = new HashSet(); + final Set alreadyProcessed = new HashSet(); + toProcess.add(node); + while (!toProcess.isEmpty()) { + alreadyProcessed.addAll(toProcess); + final List nodes = new ArrayList(toProcess); + toProcess.clear(); + for (Iterator nodesToProcessIterator = nodes.iterator(); nodesToProcessIterator.hasNext();) { + final Node n = nodesToProcessIterator.next(); + for (Iterator it = graph.getNodes().iterator(); it.hasNext();) { + final Node n1 = it.next(); + if (fromTheNode? hasArc(graph, n, n1) : hasArc(graph, n1, n)) { + reachableSet.add(n1); + if (!alreadyProcessed.contains(n1)) { + toProcess.add(n1); + } + } + } + } + } + } + + private static boolean hasArc(Graph graph, Node from, Node to) { + for (Iterator it = graph.getOut(from); it.hasNext();) { + if (to.equals(it.next())) { + return true; + } + } + return false; + } + + + public static void sortModules(final Project project, final List modules) { + final Application applicationEx = ApplicationManager.getApplication(); + if (applicationEx.isDispatchThread()) { + Collections.sort(modules, moduleDependencyComparator(project)); + } + else { + applicationEx.runReadAction(new Runnable() { + public void run() { + Collections.sort(modules, moduleDependencyComparator(project)); + } + }); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/OutputParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/OutputParser.java new file mode 100644 index 00000000000..06e8d970f47 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/OutputParser.java @@ -0,0 +1,81 @@ +package com.intellij.compiler; + +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; + +import java.io.File; + +public abstract class OutputParser { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.OutputParser"); + public static interface Callback { + String getNextLine(); + void setProgressText(String text); + void fileProcessed(String path); + void fileGenerated(String path); + void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum); + } + + public abstract boolean processMessageLine(Callback callback); + + protected void processLoading(String line, final Callback callback) { + //if (LOG.isDebugEnabled()) { + // LOG.debug(line); + //} + if (line.startsWith("[parsing started")){ // javac + String filePath = line.substring("[parsing started".length(), line.length() - 1).trim(); + filePath = filePath.replace(File.separatorChar, '/'); + processParsingMessage(callback, filePath); + } + else if (line.startsWith("[parsed") && line.indexOf(".java") >= 0) { // javac version 1.2.2 + int index = line.indexOf(".java"); + String filePath = line.substring("[parsed".length(), index + ".java".length()).trim(); + processParsingMessage(callback, filePath.replace(File.separatorChar, '/')); + } + else if (line.startsWith("[read") && line.endsWith(".java]")){ // jikes + String filePath = line.substring("[read".length(), line.length() - 1).trim(); + processParsingMessage(callback, filePath.replace(File.separatorChar, '/')); + } + else if (line.startsWith("[parsing completed")){ + } + else if (line.startsWith("[loading") || line.startsWith("[loaded") || line.startsWith("[read")){ + if (LOG.isDebugEnabled()) { + LOG.debug(line); + } + callback.setProgressText("Loading classes..."); + } + else if (line.startsWith("[checking")){ + String className = line.substring("[checking".length(), line.length() - 1).trim(); + callback.setProgressText("Compiling " + className + "..."); + } + else if (line.startsWith("[wrote") || line.startsWith("[write")){ + String filePath = line.substring("[wrote".length(), line.length() - 1).trim(); + processParsingMessage(callback, filePath.replace(File.separatorChar, '/')); + } + } + + private void processParsingMessage(final Callback callback, final String filePath) { + int index = filePath.lastIndexOf('/'); + final String name = index >= 0 ? filePath.substring(index + 1) : filePath; + + final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name); + if (StdFileTypes.JAVA.equals(fileType)) { + callback.fileProcessed(filePath); + callback.setProgressText("Parsing " + name + "..."); + } + else if (StdFileTypes.CLASS.equals(fileType)) { + callback.fileGenerated(filePath); + } + } + + protected void addMessage(Callback callback, CompilerMessageCategory type, String message) { + if(message == null || message.trim().length() == 0) return; + addMessage(callback, type, message, null, -1, -1); + } + + protected void addMessage(Callback callback, CompilerMessageCategory type, String text, String url, int line, int column){ + callback.message(type, text, url, line, column); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/RmicSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/RmicSettings.java new file mode 100644 index 00000000000..440ba52f6e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/RmicSettings.java @@ -0,0 +1,76 @@ +package com.intellij.compiler; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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 org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +public class RmicSettings implements JDOMExternalizable, ProjectComponent { + public boolean IS_EANABLED = false; + public boolean DEBUGGING_INFO = true; + public boolean GENERATE_NO_WARNINGS = false; + public boolean GENERATE_IIOP_STUBS = false; + public String ADDITIONAL_OPTIONS_STRING = ""; + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public String[] getOptions() { + List options = new ArrayList(); + if(DEBUGGING_INFO) { + options.add("-g"); + } + if(GENERATE_NO_WARNINGS) { + options.add("-nowarn"); + } + if(GENERATE_IIOP_STUBS) { + options.add("-iiop"); + } + final StringTokenizer tokenizer = new StringTokenizer(ADDITIONAL_OPTIONS_STRING, " \t\r\n"); + while(tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if("-g".equals(token)) { + continue; + } + if("-iiop".equals(token)) { + continue; + } + if("-nowarn".equals(token)) { + continue; + } + options.add(token); + } + return options.toArray(new String[options.size()]); + } + + public static RmicSettings getInstance(Project project) { + return project.getComponent(RmicSettings.class); + } + + public String getComponentName() { + return "RmicSettings"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/SymbolTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/SymbolTable.java new file mode 100644 index 00000000000..60dcdc030f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/SymbolTable.java @@ -0,0 +1,167 @@ +/* + * @author: Eugene Zhuravlev + * Date: Mar 3, 2003 + * Time: 12:34:44 PM + */ +package com.intellij.compiler; + +import com.intellij.openapi.diagnostic.Logger; +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TObjectIntHashMap; +import gnu.trove.TObjectIntProcedure; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class SymbolTable { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.SymbolTable"); + private TIntObjectHashMap myIdToSymbolMap = new TIntObjectHashMap(10, 0.9f); + private TObjectIntHashMap mySymbolToIdMap = new TObjectIntHashMap(10, 0.9f); + private int myNextAvailableId = 0; + private long myTimeStamp; + private int myVersion; + private boolean myIsDirty = false; + + public SymbolTable() { + updateTimeStamp(); + } + + public SymbolTable(DataInput input) throws IOException { + myTimeStamp = input.readLong(); + myVersion = input.readInt(); + myNextAvailableId = input.readInt(); + int size = input.readInt(); + myIdToSymbolMap = new TIntObjectHashMap(size, 0.9f); + mySymbolToIdMap = new TObjectIntHashMap(size, 0.9f); + + while (size-- > 0) { + final String symbol = CompilerIOUtil.readString(input); + final int id = input.readInt(); + myIdToSymbolMap.put(id, symbol); + mySymbolToIdMap.put(symbol, id); + } + } + + public int getVersion() { + return myVersion; + } + + public boolean isFull() { + return (Integer.MAX_VALUE - myNextAvailableId) <= 10000; + } + + public synchronized boolean isDirty() { + return myIsDirty; + } + + public synchronized void save(final DataOutput output) throws IOException { + output.writeLong(myTimeStamp); + output.writeInt(CompilerConfiguration.DEPENDENCY_FORMAT_VERSION); + output.writeInt(myNextAvailableId); + final int size = mySymbolToIdMap.size(); + output.writeInt(size); + final SymbolToIdWriteProcedure symbolToIdWriteProcedure = new SymbolToIdWriteProcedure(output); + mySymbolToIdMap.forEachEntry(symbolToIdWriteProcedure); + final IOException ex = symbolToIdWriteProcedure.getException(); + if (ex != null) { + throw ex; + } + myIsDirty = false; + } + + public synchronized int getId(String symbol) { + if ("".equals(symbol)) { + return -1; + } + LOG.assertTrue(symbol != null); + final int id; + if (mySymbolToIdMap.containsKey(symbol)) { + id = mySymbolToIdMap.get(symbol); + } + else { + id = myNextAvailableId++; + mySymbolToIdMap.put(symbol, id); + myIdToSymbolMap.put(id, symbol); + myIsDirty = true; + } + return id; + } + + public synchronized String getSymbol(int id) { + if (id == -1) { + return ""; + } + if (myIdToSymbolMap.containsKey(id)) { + return (String)myIdToSymbolMap.get(id); + } + return null; + } + + /* + public void removeUnusedIds(final TIntHashSet idsToKeep) { + LOG.info("BEGIN Compacting compiler cache symbol table"); + final int[] keys = myIdToSymbolMap.keys(); + for (int idx = 0; idx < keys.length; idx++) { + int key = keys[idx]; + if (idsToKeep.contains(key)) { + continue; + } + final Object value = myIdToSymbolMap.get(key); + mySymbolToIdMap.remove(value); + myIdToSymbolMap.remove(key); + myIsDirty = true; + LOG.info("Removed entry [" + key + "<->" + value + "]"); + } + myIdToSymbolMap.compact(); + mySymbolToIdMap.compact(); + final int[] maxValue = new int[] {0}; + idsToKeep.forEach(new TIntProcedure() { + public boolean execute(int value) { + if (maxValue[0] < value) { + maxValue[0] = value; + } + return true; + } + }); + myNextAvailableId = maxValue[0] + 1; + LOG.info("Next available ID = "+myNextAvailableId); + LOG.info("END Compacting compiler cache symbol table"); + } + */ + +// --Recycle Bin START (7/2/03 2:47 PM): +// public long getTimeStamp() { +// return myTimeStamp; +// } +// --Recycle Bin STOP (7/2/03 2:47 PM) + + public synchronized final void updateTimeStamp() { + myTimeStamp = System.currentTimeMillis(); + } + + private static class SymbolToIdWriteProcedure implements TObjectIntProcedure { + private final DataOutput myOutput; + private IOException myException = null; + + public SymbolToIdWriteProcedure(DataOutput output) { + myOutput = output; + } + + public boolean execute(Object a, int b) { + try { + CompilerIOUtil.writeString((String)a, myOutput); + myOutput.writeInt(b); + return true; + } + catch (IOException e) { + myException = e; + return false; + } + } + + public IOException getException() { + return myException; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileAction.java new file mode 100644 index 00000000000..688793ef18d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileAction.java @@ -0,0 +1,169 @@ +package com.intellij.compiler.actions; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerWorkspaceConfiguration; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; + +import java.util.ArrayList; +import java.util.List; + +public class CompileAction extends CompileActionBase { + + protected void doAction(DataContext dataContext, Project project) { + final Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + if (module != null) { + CompilerManager.getInstance(project).compile(module, null); + } + else { + VirtualFile[] files = getCompilableFiles(project, (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY)); + if (files.length > 0) { + CompilerManager.getInstance(project).compile(files, null, CompilerWorkspaceConfiguration.getInstance(project).COMPILE_DEPENDENT_FILES); + } + } + + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + + presentation.setText("Compile"); + presentation.setVisible(true); + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + + final VirtualFile[] files = getCompilableFiles(project, (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY)); + if (module == null && files.length == 0) { + presentation.setEnabled(false); + return; + } + + String elementDescription = null; + if (module != null) { + elementDescription = "Module '" + module.getName() + "'"; + } + else { + PsiPackage aPackage = null; + if (files.length == 1) { + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(files[0]); + if (directory != null) { + aPackage = directory.getPackage(); + } + } + else { + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if (element instanceof PsiPackage) { + aPackage = (PsiPackage)element; + } + } + + if (aPackage != null) { + String name = aPackage.getQualifiedName(); + if(name == null || name.length() == 0) { + name = ""; + } + elementDescription = "'" + name + "'"; + } + else if (files.length == 1) { + final VirtualFile file = files[0]; + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + if(StdFileTypes.JAVA.equals(fileType) || compilerConfiguration.isResourceFile(file.getName())) { + elementDescription = "'" + file.getName() + "'"; + } + else { + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + // the action should be invisible in popups for non-java files + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + } + } + else { + elementDescription = "Selected Files"; + } + } + + if (elementDescription == null) { + presentation.setEnabled(false); + return; + } + + presentation.setText(createPresentationText(elementDescription), false); + presentation.setEnabled(true); + } + + private static String createPresentationText(String elementDescription) { + StringBuffer buffer = new StringBuffer(40); + buffer.append("Compile "); + int length = elementDescription.length(); + if (length > 23) { + if (StringUtil.startsWithChar(elementDescription, '\'')) { + buffer.append("'"); + } + buffer.append("..."); + buffer.append(elementDescription.substring(length - 20, length)); + } + else { + buffer.append(elementDescription); + } + return buffer.toString(); + } + + private static VirtualFile[] getCompilableFiles(Project project, VirtualFile[] files) { + if (files == null || files.length == 0) { + return VirtualFile.EMPTY_ARRAY; + } + final PsiManager psiManager = PsiManager.getInstance(project); + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final FileTypeManager typeManager = FileTypeManager.getInstance(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final List filesToCompile = new ArrayList(); + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = files[idx]; + if (!fileIndex.isInSourceContent(file)) { + continue; + } + if (!(file.getFileSystem() instanceof LocalFileSystem)) { + continue; + } + if(file.isDirectory()) { + final PsiDirectory directory = psiManager.findDirectory(file); + if (directory == null || directory.getPackage() == null) { + continue; + } + } + else { + FileType fileType = typeManager.getFileTypeByFile(file); + if(!(StdFileTypes.JAVA.equals(fileType) || compilerConfiguration.isResourceFile(file.getName()))) { + continue; + } + } + filesToCompile.add(file); + } + return filesToCompile.size() > 0? filesToCompile.toArray(new VirtualFile[filesToCompile.size()]) : VirtualFile.EMPTY_ARRAY; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileActionBase.java new file mode 100644 index 00000000000..78daacab2df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileActionBase.java @@ -0,0 +1,22 @@ +package com.intellij.compiler.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; + +public abstract class CompileActionBase extends AnAction { + + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return; + } + + doAction(dataContext, project); + } + + protected abstract void doAction(final DataContext dataContext, final Project project); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileProjectAction.java new file mode 100644 index 00000000000..198f3146bf0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/CompileProjectAction.java @@ -0,0 +1,34 @@ +package com.intellij.compiler.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.compiler.CompileStatusNotification; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsConfiguration; +import com.intellij.openapi.project.Project; +import com.intellij.util.ProfilingUtil; + +public class CompileProjectAction extends CompileActionBase { + protected void doAction(DataContext dataContext, final Project project) { + ProfilingUtil.operationStarted("make"); + + CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() { + public void finished(boolean aborted, int errors, int warnings) { + //TODO move this option to the other configuration object + if (!aborted && LvcsConfiguration.getInstance().ADD_LABEL_ON_PROJECT_COMPILATION) { + String text = getTemplatePresentation().getText(); + LocalVcs.getInstance(project).addLabel(errors == 0 ? "'" + text + "' with no errors" : "'" + text + "' with errors", ""); + } + } + }); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildAction.java new file mode 100644 index 00000000000..6915a0b7027 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildAction.java @@ -0,0 +1,185 @@ +package com.intellij.compiler.actions; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.ant.*; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VfsUtil; + +import java.io.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class GenerateAntBuildAction extends CompileActionBase { + + protected void doAction(DataContext dataContext, final Project project) { + CompilerConfiguration.getInstance(project).convertPatterns(); + final GenerateAntBuildDialog dialog = new GenerateAntBuildDialog(project); + dialog.show(); + if (dialog.isOK()) { + String[] names = dialog.getRepresentativeModuleNames(); + final GenerationOptions genOptions = new GenerationOptions(project, dialog.isGenerateSingleFileBuild(), dialog.isFormsCompilationEnabled(), dialog.isBackupFiles(), names); + generate(project, genOptions); + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } + + private void generate(final Project project, final GenerationOptions genOptions) { + final List filesToRefresh = new ArrayList(); + try { + final File[] generated; + if (genOptions.generateSingleFile) { + generated = generateSingleFileBuild(project, genOptions, filesToRefresh); + } + else { + generated = generateMultipleFileBuild(project, genOptions, filesToRefresh); + } + if (generated != null) { + StringBuffer filesString = new StringBuffer(); + for (int idx = 0; idx < generated.length; idx++) { + final File file = generated[idx]; + if (idx > 0) { + filesString.append(",\n"); + } + filesString.append(file.getPath()); + } + Messages.showInfoMessage(project, "Ant build files successfully generated:\n" + filesString.toString(), "Generate Ant Build"); + } + } + catch (IOException e) { + Messages.showErrorDialog(project, "Failed to generate ant build script: " + e.getMessage(), "Generate Ant Build"); + } + finally { + if (filesToRefresh.size() > 0) { + CompilerUtil.refreshIOFiles(filesToRefresh.toArray(new File[filesToRefresh.size()])); + } + } + } + + private boolean backup(final File file, final Project project, GenerationOptions genOptions, List filesToRefresh) { + if (!genOptions.backupPreviouslyGeneratedFiles || !file.exists()) { + return true; + } + final String path = file.getPath(); + final int extensionIndex = path.lastIndexOf("."); + final String extension = path.substring(extensionIndex, path.length()); + final String backupPath = path.substring(0, extensionIndex) + "_" + new Date(file.lastModified()).toString().replaceAll("\\s+", "_").replaceAll(":", "-") + extension; + final File backupFile = new File(backupPath); + final boolean ok = file.renameTo(backupFile); + if (!ok) { + Messages.showErrorDialog(project, "Failed to backup file " + path, "Backup Error"); + } + filesToRefresh.add(backupFile); + return ok; + } + + public File[] generateSingleFileBuild(Project project, GenerationOptions genOptions, List filesToRefresh) throws IOException { + final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getProjectFile().getParent()); + projectBuildFileDestDir.mkdirs(); + final File destFile = new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + ".xml"); + final File propertiesFile = new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project)); + + if (!backup(destFile, project, genOptions, filesToRefresh)) { + return null; + } + if (!backup(propertiesFile, project, genOptions, filesToRefresh)) { + return null; + } + + destFile.createNewFile(); + propertiesFile.createNewFile(); + final DataOutputStream dataOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(destFile))); + try { + new SingleFileProjectBuild(project, genOptions).generate(dataOutput); + } + finally { + dataOutput.close(); + } + final DataOutputStream propertiesOut = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(propertiesFile))); + try { + new PropertyFileGenerator(project).generate(propertiesOut); + } + finally { + propertiesOut.close(); + } + filesToRefresh.add(destFile); + filesToRefresh.add(propertiesFile); + return new File[] {destFile, propertiesFile}; + } + + public File[] generateMultipleFileBuild(Project project, GenerationOptions genOptions, List filesToRefresh) throws IOException { + final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getProjectFile().getParent()); + projectBuildFileDestDir.mkdirs(); + final List generated = new ArrayList(); + final File projectBuildFile = new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + ".xml"); + final File propertiesFile = new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project)); + + if (!backup(projectBuildFile, project, genOptions, filesToRefresh)) { + return null; + } + if (!backup(propertiesFile, project, genOptions, filesToRefresh)) { + return null; + } + + projectBuildFile.createNewFile(); + final DataOutputStream mainDataOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(projectBuildFile))); + try { + + final MultipleFileProjectBuild build = new MultipleFileProjectBuild(project, genOptions); + build.generate(mainDataOutput); + generated.add(projectBuildFile); + + // the sequence in which modules are imported is important cause output path properties for dependent modules should be defined first + ModuleChunk[] chunks = genOptions.getModuleChunks(); + + for (int idx = 0; idx < chunks.length; idx++) { + final ModuleChunk chunk = chunks[idx]; + final File chunkBaseDir = BuildProperties.getModuleChunkBaseDir(chunk); + chunkBaseDir.mkdirs(); + final File chunkBuildFile = new File(chunkBaseDir, BuildProperties.getModuleChunkBuildFileName(chunk) + ".xml"); + + final boolean moduleBackupOk = backup(chunkBuildFile, project, genOptions, filesToRefresh); + if (!moduleBackupOk) { + return null; + } + + chunkBuildFile.createNewFile(); + final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(chunkBuildFile))); + try { + new ModuleChunkAntProject(project, chunk, genOptions).generate(out); + generated.add(chunkBuildFile); + } + finally { + out.close(); + } + } + } + finally { + mainDataOutput.close(); + } + // properties + final DataOutputStream propertiesOut = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(propertiesFile))); + try { + new PropertyFileGenerator(project).generate(propertiesOut); + generated.add(propertiesFile); + } + finally { + propertiesOut.close(); + } + + filesToRefresh.addAll(generated); + return generated.toArray(new File[generated.size()]); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildDialog.java new file mode 100644 index 00000000000..5c059295f55 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/GenerateAntBuildDialog.java @@ -0,0 +1,248 @@ +package com.intellij.compiler.actions; + +import com.intellij.compiler.Chunk; +import com.intellij.compiler.ModuleCompilerUtil; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.util.ListWithSelection; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ui.ComboBoxTableCellEditor; +import com.intellij.util.ui.Table; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 29, 2004 + */ +public class GenerateAntBuildDialog extends DialogWrapper{ + private JPanel myPanel; + private JRadioButton myGenerateSingleFileBuild; + private JRadioButton myGenerateMultipleFilesBuild; + private JCheckBox myEnableUIFormsCompilation; + private JRadioButton myCbBackupFiles; + private JRadioButton myCbOverwriteFiles; + private final Project myProject; + private static final String SINGLE_FILE_PROPERTY = "GenerateAntBuildDialog.generateSingleFile"; + private static final String UI_FORM_PROPERTY = "GenerateAntBuildDialog.enableUiFormCompile"; + private static final String BACKUP_FILES_PROPERTY = "GenerateAntBuildDialog.backupFiles"; + private JPanel myChunksPanel; + private MyTableModel myTableModel; + private Table myTable; + + public GenerateAntBuildDialog(Project project) { + super(project, false); + myProject = project; + setTitle("Generate Ant Build"); + init(); + loadSettings(); + } + + private List> getCycleChunks() { + List> chunks = ModuleCompilerUtil.getSortedModuleChunks(myProject, ModuleManager.getInstance(myProject).getModules()); + for (Iterator> it = chunks.iterator(); it.hasNext();) { + final Chunk chunk = it.next(); + if (chunk.getNodes().size() == 1) { + it.remove(); + } + } + return chunks; + } + + private void loadSettings() { + final PropertiesComponent properties = PropertiesComponent.getInstance(myProject); + final boolean singleFile = properties.isTrueValue(SINGLE_FILE_PROPERTY); + myGenerateSingleFileBuild.setSelected(singleFile); + myGenerateMultipleFilesBuild.setSelected(!singleFile); + final boolean uiForm = properties.isTrueValue(UI_FORM_PROPERTY); + myEnableUIFormsCompilation.setSelected(uiForm); + final boolean backup = properties.isTrueValue(BACKUP_FILES_PROPERTY); + myCbBackupFiles.setSelected(backup); + myCbOverwriteFiles.setSelected(!backup); + } + + private void saveSettings() { + final PropertiesComponent properties = PropertiesComponent.getInstance(myProject); + properties.setValue(SINGLE_FILE_PROPERTY, Boolean.toString(myGenerateSingleFileBuild.isSelected())); + properties.setValue(UI_FORM_PROPERTY, Boolean.toString(myEnableUIFormsCompilation.isSelected())); + properties.setValue(BACKUP_FILES_PROPERTY, Boolean.toString(myCbBackupFiles.isSelected())); + } + + protected void dispose() { + saveSettings(); + super.dispose(); + } + + protected JComponent createCenterPanel() { + final ButtonGroup group = new ButtonGroup(); + group.add(myGenerateMultipleFilesBuild); + group.add(myGenerateSingleFileBuild); + + final ButtonGroup group1 = new ButtonGroup(); + group1.add(myCbBackupFiles); + group1.add(myCbOverwriteFiles); + + myGenerateMultipleFilesBuild.setSelected(true); + myCbBackupFiles.setSelected(true); + myEnableUIFormsCompilation.setSelected(true); + + initChunksPanel(); + + return myPanel; + } + + private void initChunksPanel() { + java.util.List> chunks = getCycleChunks(); + if (chunks.size() == 0) { + return; + } + myChunksPanel.setLayout(new BorderLayout()); + myChunksPanel.setBorder(IdeBorderFactory.createTitledBorder("Cyclic Module Dependencies")); + final String text = + "Some modules have cyclic dependencies.\n" + + "In order to generate ant build script, please select the \"main\" (representative) module for each dependency cycle.\n" + + "The source code for all modules in the cycle will be compiled into the main module's output folders;\n" + + "All modules in the cycle will use the JSDK assigned to the main module;\n" + + "Any jar archives created will be named after the name of the main module."; + JLabel textLabel = new JLabel(text); + textLabel.setUI(new MultiLineLabelUI()); + textLabel.setBorder(IdeBorderFactory.createEmptyBorder(4, 4, 6, 4)); + myChunksPanel.add(textLabel, BorderLayout.NORTH); + + myTableModel = new MyTableModel(chunks); + myTable = new Table(myTableModel); + myTable.fixColumnWidthToHeader(MyTableModel.NUMBER_COLUMN); + final TableColumn nameColumn = myTable.getColumnModel().getColumn(MyTableModel.NAME_COLUMN); + nameColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE); + nameColumn.setCellRenderer(new MyTableCellRenderer()); + + final Dimension preferredSize = new Dimension(myTable.getPreferredSize()); + preferredSize.height = (myTableModel.getRowCount() + 2) * myTable.getRowHeight() + myTable.getTableHeader().getHeight(); + + final JScrollPane scrollPane = new JScrollPane(myTable); + scrollPane.setPreferredSize(preferredSize); + myChunksPanel.add(scrollPane, BorderLayout.CENTER); + } + + protected void doOKAction() { + if (myTable != null) { + TableCellEditor cellEditor = myTable.getCellEditor(); + if (cellEditor != null) { + cellEditor.stopCellEditing(); + } + } + super.doOKAction(); + } + + public boolean isGenerateSingleFileBuild() { + return myGenerateSingleFileBuild.isSelected(); + } + + public boolean isFormsCompilationEnabled() { + return myEnableUIFormsCompilation.isSelected(); + } + + public boolean isBackupFiles() { + return myCbBackupFiles.isSelected(); + } + + public String[] getRepresentativeModuleNames() { + return myTableModel != null? myTableModel.getModuleRepresentatives() : ArrayUtil.EMPTY_STRING_ARRAY; + } + + private static class MyTableModel extends AbstractTableModel { + private static final int NUMBER_COLUMN = 0; + private static final int NAME_COLUMN = 1; + + private final List myItems = new ArrayList(); + + public MyTableModel(List> chunks) { + for (Iterator> it = chunks.iterator(); it.hasNext();) { + final Chunk chunk = it.next(); + final ListWithSelection item = new ListWithSelection(); + for (Iterator modulesIterator = chunk.getNodes().iterator(); modulesIterator.hasNext();) { + final Module module = (Module)modulesIterator.next(); + item.add(module.getName()); + } + item.selectFirst(); + myItems.add(item); + } + } + + public String[] getModuleRepresentatives() { + final String[] names = new String[myItems.size()]; + int index = 0; + for (Iterator it = myItems.iterator(); it.hasNext();) { + final ListWithSelection listWithSelection = it.next(); + names[index++] = (String)listWithSelection.getSelection(); + } + return names; + } + + public int getColumnCount() { + return 2; + } + + public int getRowCount() { + return myItems.size(); + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == 1; + } + + public Class getColumnClass(int columnIndex) { + switch (columnIndex) { + case NUMBER_COLUMN : return Integer.class; + case NAME_COLUMN : return ListWithSelection.class; + default: return null; + } + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch (columnIndex) { + case NUMBER_COLUMN: return new Integer(rowIndex + 1); + case NAME_COLUMN: return myItems.get(rowIndex); + default: return null; + } + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (columnIndex == NAME_COLUMN) { + myItems.get(rowIndex).select(aValue); + } + } + + public String getColumnName(int columnIndex) { + switch (columnIndex) { + case NUMBER_COLUMN : return "N"; + case NAME_COLUMN : return "Main Module"; + } + return super.getColumnName(columnIndex); + } + } + + private static class MyTableCellRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (value instanceof ListWithSelection) { + value = ((ListWithSelection)value).getSelection(); + } + final JLabel component = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + component.setHorizontalAlignment(SwingConstants.CENTER); + return component; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/MakeModuleAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/MakeModuleAction.java new file mode 100644 index 00000000000..f069d065abb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/actions/MakeModuleAction.java @@ -0,0 +1,68 @@ +package com.intellij.compiler.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.ProfilingUtil; + +public class MakeModuleAction extends CompileActionBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.actions.MakeModuleAction"); + + protected void doAction(DataContext dataContext, Project project) { + Module[] modules = (Module[])dataContext.getData(DataConstantsEx.MODULE_CONTEXT_ARRAY); + Module module; + if (modules == null) { + module = (Module)dataContext.getData(DataConstants.MODULE); + if (module == null) { + return; + } + modules = new Module[]{module}; + } + try { + ProfilingUtil.operationStarted("make"); + + CompilerManager.getInstance(project).make(modules[0].getProject(), modules, null); + } + catch (Exception e) { + LOG.error(e); + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + final DataContext dataContext = event.getDataContext(); + final Module module = (Module)dataContext.getData(DataConstants.MODULE); + Module[] modules = (Module[])dataContext.getData(DataConstantsEx.MODULE_CONTEXT_ARRAY); + final boolean isEnabled = module != null || modules != null; + presentation.setEnabled(isEnabled); + final String actionName = getTemplatePresentation().getText(); + + String presentationText; + if (modules != null) { + String text = actionName; + for (int i = 0; i < modules.length; i++) { + if (text.length() > 30) { + text = "Make Selected Modules"; + break; + } + Module toMake = modules[i]; + if (i!=0) { + text += ","; + } + text += " '" + toMake.getName() + "'"; + } + presentationText = text; + } + else if (module != null) { + presentationText = actionName + " '" + module.getName() + "'"; + } + else { + presentationText = actionName; + } + presentation.setText(presentationText); + presentation.setVisible(isEnabled || !ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace())); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/BuildProperties.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/BuildProperties.java new file mode 100644 index 00000000000..be7575cfd4a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/BuildProperties.java @@ -0,0 +1,295 @@ +package com.intellij.compiler.ant; + +import com.intellij.application.options.PathMacros; +import com.intellij.compiler.JavacSettings; +import com.intellij.compiler.ant.taskdefs.FileSet; +import com.intellij.compiler.ant.taskdefs.Include; +import com.intellij.compiler.ant.taskdefs.Path; +import com.intellij.compiler.ant.taskdefs.Property; +import com.intellij.j2ee.appServerIntegrations.impl.ApplicationServersManagerImpl; +import com.intellij.j2ee.serverInstances.ApplicationServersManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +// todo: move path variables properties and jdk home properties into te generated property file +public class BuildProperties extends CompositeGenerator { + public static final String TARGET_ALL = "all"; + public static final String TARGET_CLEAN = "clean"; + public static final String TARGET_INIT = "init"; + public static final String DEFAULT_TARGET = TARGET_ALL; + + public static final String PROPERTY_COMPILER_NAME = "compiler.name"; + public static final String PROPERTY_COMPILER_ADDITIONAL_ARGS = "compiler.args"; + public static final String PROPERTY_COMPILER_MAX_MEMORY = "compiler.max.memory"; + public static final String PROPERTY_COMPILER_EXCLUDES = "compiler.excluded"; + public static final String PROPERTY_COMPILER_RESOURCE_PATTERNS = "compiler.resources"; + public static final String PROPERTY_COMPILER_GENERATE_DEBUG_INFO = "compiler.debug"; + public static final String PROPERTY_COMPILER_GENERATE_NO_WARNINGS = "compiler.generate.no.warnings"; + public static final String PROPERTY_PROJECT_JDK_HOME = "project.jdk.home"; + public static final String PROPERTY_PROJECT_JDK_CLASSPATH = "project.jdk.classpath"; + public static final String PROPERTY_SKIP_TESTS = "skip.tests"; + + public BuildProperties(Project project, final GenerationOptions genOptions) { + add(new Property(getPropertyFileName(project))); + + add(new Comment("Uncomment the following property if no tests compilation is needed", new Property(PROPERTY_SKIP_TESTS, "true"))); + final JavacSettings javacSettings = JavacSettings.getInstance(project); + if (genOptions.enableFormCompiler) { + add(new Comment("The task requires the following libraries from IntelliJ IDEA distribution:"), 1); + add(new Comment(" javac2.jar; jdom.jar; bcel.jar")); + add(new Tag("taskdef", new Pair[] { + new Pair("name", "javac2"), + new Pair("classname", "com.intellij.uiDesigner.ant.Javac2"), + })); + } + + add(new Comment("Compiler options"), 1); + add(new Property(PROPERTY_COMPILER_GENERATE_DEBUG_INFO, javacSettings.DEBUGGING_INFO? "on" : "off"), 1); + add(new Property(PROPERTY_COMPILER_GENERATE_NO_WARNINGS, javacSettings.GENERATE_NO_WARNINGS? "on" : "off")); + add(new Property(PROPERTY_COMPILER_ADDITIONAL_ARGS, javacSettings.ADDITIONAL_OPTIONS_STRING)); + add(new Property(PROPERTY_COMPILER_MAX_MEMORY, Integer.toString(javacSettings.MAXIMUM_HEAP_SIZE) + "m")); + + if (CompilerExcludes.isAvailable(project)) { + add(new CompilerExcludes(project, genOptions)); + } + + add(new CompilerResourcePatterns(project)); + + createJdkGenerators(project); + + LibraryDefinitionsGeneratorFactory factory = new LibraryDefinitionsGeneratorFactory((ProjectEx)project, genOptions); + + final Generator projectLibs = factory.create(LibraryTablesRegistrar.getInstance().getLibraryTable(project), getProjectBaseDir(project), "Project Libraries"); + if (projectLibs != null) { + add(projectLibs); + } + + final Generator globalLibs = factory.create(LibraryTablesRegistrar.getInstance().getLibraryTable(), null, "Global Libraries"); + if (globalLibs != null) { + add(globalLibs); + } + + LibraryTable appServerLibraryTable = ((ApplicationServersManagerImpl)ApplicationServersManager.getInstance()).getLibraryTable(); + if (appServerLibraryTable.getLibraries().length != 0) { + final Generator appServerLibs = factory.create(appServerLibraryTable, null, "Application Server Libraries"); + if (appServerLibs != null){ + add(appServerLibs); + } + } + } + + private void createJdkGenerators(final Project project) { + final ProjectJdk[] jdks = getUsedJdks(project); + + if (jdks.length > 0) { + add(new Comment("JDK definitions"), 1); + + for (int idx = 0; idx < jdks.length; idx++) { + final ProjectJdk jdk = jdks[idx]; + if (jdk.getHomeDirectory() == null) { + continue; + } + final File homeDir = VfsUtil.virtualToIoFile(jdk.getHomeDirectory()); + final String jdkName = jdk.getName(); + final String jdkHomeProperty = getJdkHomeProperty(jdkName); + final FileSet fileSet = new FileSet(propertyRef(jdkHomeProperty)); + final String[] urls = jdk.getRootProvider().getUrls(OrderRootType.COMPILATION_CLASSES); + for (int i = 0; i < urls.length; i++) { + final String path = GenerationUtils.trimJarSeparator(VirtualFileManager.extractPath(urls[i])); + final File pathElement = new File(path); + final String relativePath = FileUtil.getRelativePath(homeDir, pathElement); + if (relativePath != null) { + fileSet.add(new Include(relativePath.replace(File.separatorChar, '/'))); + } + } + //add(new Property(jdkHomeProperty, homeDir.getPath().replace(File.separatorChar, '/')), 1); + final Path jdkPath = new Path(getJdkPathId(jdkName)); + jdkPath.add(fileSet); + add(jdkPath); + } + } + + final ProjectJdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk(); + add(new Property(PROPERTY_PROJECT_JDK_HOME, projectJdk != null? propertyRef(getJdkHomeProperty(projectJdk.getName())) : ""), 1); + add(new Property(PROPERTY_PROJECT_JDK_CLASSPATH, projectJdk != null? getJdkPathId(projectJdk.getName()) : "")); + } + + public static ProjectJdk[] getUsedJdks(Project project) { + final Set jdks = new HashSet(); + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + ProjectJdk jdk = ModuleRootManager.getInstance(module).getJdk(); + if (jdk != null) { + jdks.add(jdk); + } + } + return jdks.toArray(new ProjectJdk[jdks.size()]); + } + + public static String getPropertyFileName(Project project) { + return getProjectBuildFileName(project) + ".properties"; + } + + public static String getJdkPathId(final String jdkName) { + return "jdk.classpath." + convertName(jdkName); + } + + public static String getModuleChunkJdkClasspathProperty(final String moduleChunkName) { + return "module.jdk.classpath." + convertName(moduleChunkName); + } + + public static String getModuleChunkJdkHomeProperty(final String moduleChunkName) { + return "module.jdk.home." + convertName(moduleChunkName); + } + + public static String getModuleChunkCompilerArgsProperty(final String moduleName) { + return "compiler.args." + convertName(moduleName); + } + + public static String getLibraryPathId(final String libraryName) { + return "library." + convertName(libraryName) + ".classpath"; + } + + public static String getJdkHomeProperty(final String jdkName) { + return "jdk.home." + convertName(jdkName); + } + + public static String getCompileTargetName(String moduleName) { + return "compile.module." + convertName(moduleName); + } + + public static String getOutputPathProperty(String moduleName) { + return convertName(moduleName) + ".output.dir"; + } + + public static String getOutputPathForTestsProperty(String moduleName) { + return convertName(moduleName) + ".testoutput.dir"; + } + + public static String getClasspathProperty(String moduleName) { + return convertName(moduleName) + ".module.classpath"; + } + + public static String getBootClasspathProperty(String moduleName) { + return convertName(moduleName) + ".module.bootclasspath"; + } + + public static String getSourcepathProperty(String moduleName) { + return convertName(moduleName) + ".module.sourcepath"; + } + + public static String getTestSourcepathProperty(String moduleName) { + return convertName(moduleName) + ".module.test.sourcepath"; + } + + public static String getExcludedFromModuleProperty(String moduleName) { + return "excluded.from.module." + convertName(moduleName); + } + + public static String getExcludedFromCompilationProperty(String moduleName) { + return "excluded.from.compilation." + convertName(moduleName); + } + + public static String getProjectBuildFileName(Project project) { + return convertName(project.getName()); + } + + public static String getModuleChunkBuildFileName(final ModuleChunk chunk) { + return "module_" + convertName(chunk.getName()); + } + + public static String getModuleCleanTargetName(String moduleName) { + return "clean.module." + convertName(moduleName); + } + + public static String getModuleChunkBasedirProperty(ModuleChunk chunk) { + return "module." + convertName(chunk.getName()) + ".basedir"; + } + + /** + * left for compatibility + */ + public static String getModuleBasedirProperty(Module module) { + return "module." + convertName(module.getName()) + ".basedir"; + } + + public static String getProjectBaseDirProperty() { + return "basedir"; + } + + public static File getModuleChunkBaseDir(ModuleChunk chunk) { + return chunk.getBaseDir(); + } + + public static File getProjectBaseDir(final Project project) { + return new File(project.getProjectFilePath()).getParentFile(); + } + + private static String convertName(final String name) { + return JDOMUtil.escapeText(name.replaceAll("\"", "").replaceAll("\\s+", "_").toLowerCase()); + } + + public static String getPathMacroProperty(String pathMacro) { + return "path.variable." + convertName(pathMacro); + } + + // J2EE + public static String getJ2EEExplodedPathProperty(String moduleName) { + return convertName(moduleName) + ".dir.exploded"; + } + + public static String getJ2EEExplodedPathProperty() { + return "j2ee.dir.exploded"; + } + + public static String getJ2EEJarPathProperty() { + return "j2ee.path.jar"; + } + + public static String getJ2EEJarPathProperty(String moduleName) { + return convertName(moduleName) + ".path.jar"; + } + + public static String getJ2EEBuildTargetName(String moduleName) { + return "j2ee.build."+convertName(moduleName); + } + + public static String getJ2EEExplodedBuildTargetName(String moduleName) { + return "j2ee.build.exploded."+convertName(moduleName); + } + + public static String getJ2EEJarBuildTargetName(String moduleName) { + return "j2ee.build.jar."+convertName(moduleName); + } + + public static String getTempDirForModuleProperty(String moduleName) { + return "tmp.dir."+convertName(moduleName); + } + + public static String propertyRef(String propertyName) { + return "${" + propertyName + "}"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ChunkBuild.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ChunkBuild.java new file mode 100644 index 00000000000..196e69c1f9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ChunkBuild.java @@ -0,0 +1,76 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.j2ee.J2EEBuildTarget; +import com.intellij.compiler.ant.j2ee.J2EEExplodedBuildTarget; +import com.intellij.compiler.ant.j2ee.J2EEJarBuildTarget; +import com.intellij.compiler.ant.taskdefs.Path; +import com.intellij.compiler.ant.taskdefs.Property; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 22, 2004 + */ +public class ChunkBuild extends CompositeGenerator{ + + public ChunkBuild(Project project, ModuleChunk chunk, GenerationOptions genOptions) { + final File chunkBaseDir = chunk.getBaseDir(); + if (chunk.isJ2EEApplication()) { + add(new CompileModuleChunkTarget(project, chunk, VirtualFile.EMPTY_ARRAY, VirtualFile.EMPTY_ARRAY, chunkBaseDir, genOptions), 1); + } + else { + + if (chunk.isJdkInherited()) { + add(new Property(BuildProperties.getModuleChunkJdkHomeProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_PROJECT_JDK_HOME))); + add(new Property(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_PROJECT_JDK_CLASSPATH))); + } + else { + final ProjectJdk jdk = chunk.getJdk(); + add(new Property(BuildProperties.getModuleChunkJdkHomeProperty(chunk.getName()), jdk != null? BuildProperties.propertyRef(BuildProperties.getJdkHomeProperty(jdk.getName())): "")); + add(new Property(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()), jdk != null? BuildProperties.getJdkPathId(jdk.getName()) : "")); + } + + add(new Property(BuildProperties.getModuleChunkCompilerArgsProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_ADDITIONAL_ARGS)), 1); + + final String outputPathUrl = chunk.getOutputDirUrl(); + String location = outputPathUrl != null? + GenerationUtils.toRelativePath(VirtualFileManager.extractPath(outputPathUrl), chunkBaseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions, !chunk.isSavePathsRelative()) : + "undefined"; + add(new Property(BuildProperties.getOutputPathProperty(chunk.getName()), location), 1); + + final String testOutputPathUrl = chunk.getTestsOutputDirUrl(); + if (testOutputPathUrl != null) { + location = GenerationUtils.toRelativePath(VirtualFileManager.extractPath(testOutputPathUrl), chunkBaseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions, !chunk.isSavePathsRelative()); + } + add(new Property(BuildProperties.getOutputPathForTestsProperty(chunk.getName()), location)); + + add(createBootclasspath(chunk), 1); + add(new ModuleChunkClasspath(chunk, genOptions), 1); + + final ModuleChunkSourcepath moduleSources = new ModuleChunkSourcepath(project, chunk, genOptions); + add(moduleSources, 1); + add(new CompileModuleChunkTarget(project, chunk, moduleSources.getSourceRoots(), moduleSources.getTestSourceRoots(), chunkBaseDir, genOptions), 1); + } + + add(new CleanModule(chunk), 1); + + if (chunk.isJ2EE()) { + add(new J2EEBuildTarget(chunk, chunkBaseDir, genOptions)); + add(new J2EEExplodedBuildTarget(chunk, chunkBaseDir, genOptions)); + add(new J2EEJarBuildTarget(chunk, chunkBaseDir, genOptions)); + } + } + + private Generator createBootclasspath(ModuleChunk chunk) { + final Path bootclasspath = new Path(BuildProperties.getBootClasspathProperty(chunk.getName())); + bootclasspath.add(new Comment("Paths to be included in compilation bootclasspath")); + return bootclasspath; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanModule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanModule.java new file mode 100644 index 00000000000..23152742500 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanModule.java @@ -0,0 +1,20 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Delete; +import com.intellij.compiler.ant.taskdefs.Target; +import com.intellij.openapi.module.ModuleType; + +/** + * @author Eugene Zhuravlev + * Date: Mar 24, 2004 + */ +public class CleanModule extends Target { + public CleanModule(ModuleChunk chunk) { + super(BuildProperties.getModuleCleanTargetName(chunk.getName()), null, "cleanup module", null); + final String chunkName = chunk.getName(); + if (!chunk.isJ2EEApplication()) { + add(new Delete(BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunkName)))); + add(new Delete(BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunkName)))); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanProject.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanProject.java new file mode 100644 index 00000000000..8dd60780fe9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CleanProject.java @@ -0,0 +1,30 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Target; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 24, 2004 + */ +public class CleanProject extends Generator { + private Target myTarget; + + public CleanProject(GenerationOptions genOptions) { + StringBuffer dependencies = new StringBuffer(); + final ModuleChunk[] chunks = genOptions.getModuleChunks(); + for (int idx = 0; idx < chunks.length; idx++) { + if (idx > 0) { + dependencies.append(", "); + } + dependencies.append(BuildProperties.getModuleCleanTargetName(chunks[idx].getName())); + } + myTarget = new Target(BuildProperties.TARGET_CLEAN, dependencies.toString(), "cleanup all", null); + } + + public void generate(DataOutput out) throws IOException { + myTarget.generate(out); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Comment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Comment.java new file mode 100644 index 00000000000..d97313cdff1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Comment.java @@ -0,0 +1,44 @@ +package com.intellij.compiler.ant; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Comment extends Generator{ + private final String myComment; + private final Generator myCommentedData; + + public Comment(String comment) { + this(comment, null); + } + + public Comment(Generator commentedData) { + this(null, commentedData); + } + + public Comment(String comment, Generator commentedData) { + myComment = comment; + myCommentedData = commentedData; + } + + public void generate(DataOutput out) throws IOException { + if (myComment != null) { + out.writeBytes(""); + if (myCommentedData != null) { + crlf(out); + } + } + if (myCommentedData != null) { + out.writeBytes(""); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompileModuleChunkTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompileModuleChunkTarget.java new file mode 100644 index 00000000000..3d3d47cae5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompileModuleChunkTarget.java @@ -0,0 +1,104 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.*; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.project.Project; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class CompileModuleChunkTarget extends CompositeGenerator { + private final Target myMainTarget; + private final Target myProductionTarget; + private final Target myTestsTarget; + + public CompileModuleChunkTarget(final Project project, ModuleChunk moduleChunk, VirtualFile[] sourceRoots, VirtualFile[] testSourceRoots, File baseDir, GenerationOptions genOptions) { + final String moduleChunkName = moduleChunk.getName(); + final Tag compilerArgs = new Tag("compilerarg", new Pair[]{new Pair("line", BuildProperties.propertyRef(BuildProperties.getModuleChunkCompilerArgsProperty(moduleChunkName)))}); + final Tag classpathTag = new Tag("classpath", new Pair[]{new Pair("refid", BuildProperties.getClasspathProperty(moduleChunkName))}); + final Tag bootclasspathTag = new Tag("bootclasspath", new Pair[]{new Pair("refid", BuildProperties.getBootClasspathProperty(moduleChunkName))}); + final PatternSetRef compilerExcludes = CompilerExcludes.isAvailable(project)? new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(moduleChunkName)) : null; + + final String mainTargetName = BuildProperties.getCompileTargetName(moduleChunkName); + final String productionTargetName = mainTargetName + ".production"; + final String testsTargetName = mainTargetName + ".tests"; + + myMainTarget = new Target(mainTargetName, productionTargetName + "," + testsTargetName, "compile module(s) " + moduleChunkName, null); + myProductionTarget = new Target(productionTargetName, getChunkDependenciesString(moduleChunk), "compile module(s) " + moduleChunkName + " production classes", null); + myTestsTarget = new Target(testsTargetName, productionTargetName, "compile module(s) " + moduleChunkName + " test classes", BuildProperties.PROPERTY_SKIP_TESTS); + + if (sourceRoots.length > 0) { + final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName)); + myProductionTarget.add(new Mkdir(outputPathRef)); + + final Javac javac = new Javac(genOptions.enableFormCompiler? "javac2" : "javac", moduleChunkName, outputPathRef); + javac.add(compilerArgs); + javac.add(bootclasspathTag); + javac.add(classpathTag); + javac.add(new Tag("src", new Pair[]{new Pair("refid", BuildProperties.getSourcepathProperty(moduleChunkName))})); + if (compilerExcludes != null) { + javac.add(compilerExcludes); + } + + myProductionTarget.add(javac); + myProductionTarget.add(createCopyTask(project, moduleChunk, sourceRoots, outputPathRef, baseDir, genOptions)); + } + + if (testSourceRoots.length > 0) { + final String testOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(moduleChunkName)); + myTestsTarget.add(new Mkdir(testOutputPathRef)); + + final Javac javac = new Javac(genOptions.enableFormCompiler? "javac2" : "javac", moduleChunkName, testOutputPathRef); + javac.add(compilerArgs); + javac.add(classpathTag); + javac.add(new Tag("classpath", new Pair[]{new Pair("location", BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName)))})); + javac.add(new Tag("src", new Pair[]{new Pair("refid", BuildProperties.getTestSourcepathProperty(moduleChunkName))})); + if (compilerExcludes != null) { + javac.add(compilerExcludes); + } + + myTestsTarget.add(javac); + myTestsTarget.add(createCopyTask(project, moduleChunk, testSourceRoots, testOutputPathRef, baseDir, genOptions)); + } + + add(myMainTarget); + add(myProductionTarget, 1); + add(myTestsTarget, 1); + } + + private String getChunkDependenciesString(ModuleChunk moduleChunk) { + final StringBuffer moduleDependencies = new StringBuffer(); + final ModuleChunk[] dependencies = moduleChunk.getDependentChunks(); + for (int idx = 0; idx < dependencies.length; idx++) { + final ModuleChunk dependency = dependencies[idx]; + if (idx > 0) { + moduleDependencies.append(","); + } + moduleDependencies.append(BuildProperties.getCompileTargetName(dependency.getName())); + } + return moduleDependencies.toString(); + } + + private static Generator createCopyTask(final Project project, ModuleChunk chunk, VirtualFile[] sourceRoots, String toDir, File baseDir, final GenerationOptions genOptions) { + final Tag filesSelector = new Tag("type", new Pair[] {new Pair("type", "file")}); + final PatternSetRef excludes = CompilerExcludes.isAvailable(project)? new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(chunk.getName())) : null; + //final String resourcePatternsPropertyRef = propertyRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS); + final PatternSetRef resourcePatternsPatternSet = new PatternSetRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS); + final Copy copy = new Copy(toDir); + for (int idx = 0; idx < sourceRoots.length; idx++) { + final VirtualFile root = sourceRoots[idx]; + final FileSet fileSet = new FileSet(GenerationUtils.toRelativePath(root, baseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions, !chunk.isSavePathsRelative())); + fileSet.add(resourcePatternsPatternSet); + fileSet.add(filesSelector); + if (excludes != null) { + fileSet.add(excludes); + } + copy.add(fileSet); + } + return copy; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerExcludes.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerExcludes.java new file mode 100644 index 00000000000..8dcce155ec1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerExcludes.java @@ -0,0 +1,53 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.ant.taskdefs.Exclude; +import com.intellij.compiler.ant.taskdefs.PatternSet; +import com.intellij.compiler.impl.ExcludeEntryDescription; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class CompilerExcludes extends Generator{ + private final PatternSet myPatternSet; + + public CompilerExcludes(Project project, GenerationOptions genOptions) { + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final ExcludeEntryDescription[] excludeEntryDescriptions = compilerConfiguration.getExcludeEntryDescriptions(); + myPatternSet = new PatternSet(BuildProperties.PROPERTY_COMPILER_EXCLUDES); + for (int idx = 0; idx < excludeEntryDescriptions.length; idx++) { + final ExcludeEntryDescription entry = excludeEntryDescriptions[idx]; + final String path = genOptions.subsitutePathWithMacros(VirtualFileManager.extractPath(entry.getUrl())); + if (entry.isFile()) { + myPatternSet.add(new Exclude(path)); + } + else { + if (entry.isIncludeSubdirectories()) { + myPatternSet.add(new Exclude(path + "/**")); + } + else { + myPatternSet.add(new Exclude(path + "/*")); + } + } + } + } + + + + public void generate(DataOutput out) throws IOException { + myPatternSet.generate(out); + } + + public static boolean isAvailable(Project project) { + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final ExcludeEntryDescription[] excludeEntryDescriptions = compilerConfiguration.getExcludeEntryDescriptions(); + return excludeEntryDescriptions.length > 0; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerResourcePatterns.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerResourcePatterns.java new file mode 100644 index 00000000000..f582292668e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompilerResourcePatterns.java @@ -0,0 +1,41 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.ant.taskdefs.Exclude; +import com.intellij.compiler.ant.taskdefs.Include; +import com.intellij.compiler.ant.taskdefs.PatternSet; +import com.intellij.openapi.project.Project; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class CompilerResourcePatterns extends Generator{ + private final PatternSet myPatternSet; + + public CompilerResourcePatterns(Project project) { + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final String[] patterns = compilerConfiguration.getResourceFilePatterns(); + myPatternSet = new PatternSet(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS); + for (int idx = 0; idx < patterns.length; idx++) { + String pattern = patterns[idx]; + if (compilerConfiguration.isPatternNegated(pattern)) { + myPatternSet.add(new Exclude("**/" + pattern.substring(1))); + } + else { + myPatternSet.add(new Include("**/" + pattern)); + } + } + } + + + + public void generate(DataOutput out) throws IOException { + myPatternSet.generate(out); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompositeGenerator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompositeGenerator.java new file mode 100644 index 00000000000..33294142498 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/CompositeGenerator.java @@ -0,0 +1,49 @@ +package com.intellij.compiler.ant; + +import com.intellij.openapi.util.Pair; + +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 25, 2004 + */ +public class CompositeGenerator extends Generator{ + private final List> myGenerators = new ArrayList>(); + + public CompositeGenerator() { + } + + public CompositeGenerator(Generator generator1, Generator generator2, int emptyLinesCount) { + add(generator1); + add(generator2, emptyLinesCount); + } + + public final void add(Generator generator) { + add(generator, 0); + } + + public final void add(Generator generator, int emptyLinesCount) { + myGenerators.add(new Pair(generator, new Integer(emptyLinesCount))); + } + + public void generate(DataOutput out) throws IOException { + for (Iterator it = myGenerators.iterator(); it.hasNext();) { + final Pair pair = (Pair)it.next(); + crlf(out); + final int emptyLinesCount = pair.getSecond().intValue(); + for (int idx = 0; idx < emptyLinesCount; idx++) { + crlf(out); + } + pair.getFirst().generate(out); + } + } + + public final int getGeneratorCount() { + return myGenerators.size(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationOptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationOptions.java new file mode 100644 index 00000000000..260b0ed531b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationOptions.java @@ -0,0 +1,164 @@ +package com.intellij.compiler.ant; + +import com.intellij.application.options.PathMacros; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.compiler.Chunk; +import com.intellij.compiler.ModuleCompilerUtil; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; + +import javax.naming.OperationNotSupportedException; +import java.io.File; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Mar 25, 2004 + */ +public class GenerationOptions { + public final boolean generateSingleFile; + public final boolean enableFormCompiler; + public final boolean backupPreviouslyGeneratedFiles; + private final ReplacePathToMacroMap myMacroReplacementMap; // from absolute path to macro substitutions + private final Map myOutputUrlToPropertyRefMap; // from absolute path to macro substitutions + private final ModuleChunk[] myModuleChunks; + private final Project myProject; + + public GenerationOptions(Project project, + boolean generateSingleFile, + boolean enableFormCompiler, + boolean backupPreviouslyGeneratedFiles, + String[] representativeModuleNames) { + myProject = project; + this.generateSingleFile = generateSingleFile; + this.enableFormCompiler = enableFormCompiler; + this.backupPreviouslyGeneratedFiles = backupPreviouslyGeneratedFiles; + myMacroReplacementMap = createReplacementMap(); + myModuleChunks = createModuleChunks(representativeModuleNames); + myOutputUrlToPropertyRefMap = createOutputUrlToPropertyRefMap(myModuleChunks); + } + + public String subsitutePathWithMacros(String path) { + if (myMacroReplacementMap.size() == 0) { + return path; // optimization + } + return myMacroReplacementMap.substitute(path, SystemInfo.isFileSystemCaseSensitive); + } + + public String getPropertyRefForUrl(String url) { + return myOutputUrlToPropertyRefMap.get(url); + } + + private static ReplacePathToMacroMap createReplacementMap() { + final PathMacros pathMacros = PathMacros.getInstance(); + final Set macroNames = pathMacros.getUserMacroNames(); + final ReplacePathToMacroMap map = new ReplacePathToMacroMap(); + for (Iterator it = macroNames.iterator(); it.hasNext();) { + final String macroName = (String)it.next(); + map.put(pathMacros.getValue(macroName), BuildProperties.propertyRef(BuildProperties.getPathMacroProperty(macroName))); + } + return map; + } + + private Map createOutputUrlToPropertyRefMap(ModuleChunk[] chunks) { + final Map map = new HashMap(); + + for (int idx = 0; idx < chunks.length; idx++) { + final ModuleChunk chunk = chunks[idx]; + final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunk.getName())); + final String testsOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunk.getName())); + + final Module[] modules = chunk.getModules(); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final String outputPathUrl = rootManager.getCompilerOutputPathUrl(); + if (outputPathUrl != null) { + map.put(outputPathUrl, outputPathRef); + } + final String outputPathForTestsUrl = rootManager.getCompilerOutputPathForTestsUrl(); + if (outputPathForTestsUrl != null) { + if (outputPathUrl == null || !outputPathForTestsUrl.equals(outputPathUrl)) { + map.put(outputPathForTestsUrl, testsOutputPathRef); + } + } + } + } + return map; + } + + public ModuleChunk[] getModuleChunks() { + return myModuleChunks; + } + + protected ModuleChunk[] createModuleChunks(String[] representativeModuleNames) { + final Set mainModuleNames = new HashSet(Arrays.asList(representativeModuleNames)); + final Graph> chunkGraph = ModuleCompilerUtil.toChunkGraph(ModuleCompilerUtil.createModuleGraph(ModuleManager.getInstance(myProject).getModules())); + final Map, ModuleChunk> map = new HashMap, ModuleChunk>(); + final Map> reverseMap = new HashMap>(); + for (Iterator> it = chunkGraph.getNodes().iterator(); it.hasNext();) { + final Chunk chunk = it.next(); + final Set modules = chunk.getNodes(); + final ModuleChunk moduleChunk = new ModuleChunk(modules.toArray(new Module[modules.size()])); + for (Iterator modulesIterator = modules.iterator(); modulesIterator.hasNext();) { + final Module module = (Module)modulesIterator.next(); + if (mainModuleNames.contains(module.getName())) { + moduleChunk.setMainModule(module); + break; + } + } + map.put(chunk, moduleChunk); + reverseMap.put(moduleChunk, chunk); + } + + final Graph moduleChunkGraph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return map.values(); + } + + public Iterator getIn(ModuleChunk n) { + final Chunk chunk = reverseMap.get(n); + final Iterator> in = chunkGraph.getIn(chunk); + return new Iterator() { + public boolean hasNext() { + return in.hasNext(); + } + public ModuleChunk next() { + return map.get(in.next()); + } + public void remove() { + new OperationNotSupportedException(); + } + }; + } + })); + final Collection nodes = moduleChunkGraph.getNodes(); + final ModuleChunk[] moduleChunks = nodes.toArray(new ModuleChunk[nodes.size()]); + for (int idx = 0; idx < moduleChunks.length; idx++) { + ModuleChunk moduleChunk = moduleChunks[idx]; + final Iterator depsIterator = moduleChunkGraph.getIn(moduleChunk); + List deps = new ArrayList(); + while(depsIterator.hasNext()) { + deps.add(depsIterator.next()); + } + moduleChunk.setDependentChunks(deps.toArray(new ModuleChunk[deps.size()])); + } + Arrays.sort(moduleChunks, new DFSTBuilder(moduleChunkGraph).comparator()); + if (generateSingleFile) { + final File baseDir = BuildProperties.getProjectBaseDir(myProject); + for (int idx = 0; idx < moduleChunks.length; idx++) { + ModuleChunk chunk = moduleChunks[idx]; + chunk.setBaseDir(baseDir); + } + } + return moduleChunks; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationUtils.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationUtils.java new file mode 100644 index 00000000000..c7f087530ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/GenerationUtils.java @@ -0,0 +1,46 @@ +package com.intellij.compiler.ant; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PathUtil; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class GenerationUtils { + + public static String toRelativePath(final VirtualFile file, + File baseDir, + final String baseDirPropertyName, + GenerationOptions genOptions, + boolean useAbsolutePathsForOuterPaths) { + return toRelativePath(PathUtil.getLocalPath(file).replace(File.separatorChar, '/'), baseDir, baseDirPropertyName, genOptions, useAbsolutePathsForOuterPaths); + } + + public static String toRelativePath(final String path, + File baseDir, + final String baseDirPropertyName, + GenerationOptions genOptions, + boolean useAbsolutePathsForOuterPaths) { + if (baseDir != null) { + final String relativepath = FileUtil.getRelativePath(baseDir, new File(path)); + if (relativepath != null) { + if (!useAbsolutePathsForOuterPaths || relativepath.indexOf("..") < 0) { + final String _relativePath = relativepath.replace(File.separatorChar, '/'); + final String root = BuildProperties.propertyRef(baseDirPropertyName); + return ".".equals(_relativePath)? root : root + "/" + _relativePath; + } + } + } + return genOptions.subsitutePathWithMacros(path); + } + + public static String trimJarSeparator(final String path) { + return path.endsWith(JarFileSystem.JAR_SEPARATOR)? path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()) : path; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Generator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Generator.java new file mode 100644 index 00000000000..d81f72d6725 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Generator.java @@ -0,0 +1,35 @@ +package com.intellij.compiler.ant; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +public abstract class Generator { + private static int ourIndent = 0; + private static final int INDENT_SHIFT = 2; + + public abstract void generate(DataOutput out) throws IOException; + + protected static void crlf(DataOutput out) throws IOException { + out.writeBytes(System.getProperty("line.separator")); + indent(out); + } + + protected static void shiftIndent() { + ourIndent += INDENT_SHIFT; + } + + protected static void unshiftIndent() { + ourIndent -= INDENT_SHIFT; + } + + protected static void indent(DataOutput out) throws IOException { + for (int idx = 0; idx < ourIndent; idx++) { + out.writeBytes(" "); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java new file mode 100644 index 00000000000..0159664d699 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Path; +import com.intellij.compiler.ant.taskdefs.PathElement; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Eugene Zhuravlev + * Date: Nov 25, 2004 + */ +public class LibraryDefinitionsGeneratorFactory { + private final ProjectEx myProject; + private GenerationOptions myGenOptions; + private Set myUsedLibraries = new HashSet(); + + public LibraryDefinitionsGeneratorFactory(ProjectEx project, GenerationOptions genOptions) { + myProject = project; + myGenOptions = genOptions; + final ModuleManager moduleManager = ModuleManager.getInstance(project); + final Module[] modules = moduleManager.getModules(); + for (int idx = 0; idx < modules.length; idx++) { + final OrderEntry[] orderEntries = ModuleRootManager.getInstance(modules[idx]).getOrderEntries(); + for (int i = 0; i < orderEntries.length; i++) { + OrderEntry orderEntry = orderEntries[i]; + if (orderEntry instanceof LibraryOrderEntry && orderEntry.isValid()) { + Library library = ((LibraryOrderEntry)orderEntry).getLibrary(); + if (library != null) { + final String name = library.getName(); + if (name != null) { + myUsedLibraries.add(name); + } + } + } + } + } + } + + public Generator create(LibraryTable libraryTable, File baseDir, final String comment) { + final Library[] libraries = libraryTable.getLibraries(); + if (libraries.length == 0) { + return null; + } + + final CompositeGenerator gen = new CompositeGenerator(); + + gen.add(new Comment(comment), 1); + + for (int idx = 0; idx < libraries.length; idx++) { + final Library library = libraries[idx]; + final String libraryName = library.getName(); + if (!myUsedLibraries.contains(libraryName)) { + continue; + } + + final VirtualFile[] files = library.getFiles(OrderRootType.COMPILATION_CLASSES); + final Path libraryPath = new Path(BuildProperties.getLibraryPathId(libraryName)); + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + libraryPath.add(new PathElement(GenerationUtils.toRelativePath(file, baseDir, BuildProperties.getProjectBaseDirProperty(), myGenOptions, !myProject.isSavePathsRelative()))); + } + gen.add(libraryPath, 1); + } + return gen.getGeneratorCount() > 0? gen : null; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunk.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunk.java new file mode 100644 index 00000000000..c9ac39ceae1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunk.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.ant; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.projectRoots.ProjectJdk; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Nov 19, 2004 + */ +public class ModuleChunk { + private final Module[] myModules; + private Module myMainModule; + private ModuleChunk[] myDependentChunks; + private File myBaseDir = null; + + public ModuleChunk(Module[] modules) { + myModules = modules; + myMainModule = myModules[0]; // todo: temporary, let user configure this + } + + public String getName() { + return myMainModule.getName(); + } + + public Module[] getModules() { + return myModules; + } + + public String getOutputDirUrl() { + return ModuleRootManager.getInstance(myMainModule).getCompilerOutputPathUrl(); + } + + public String getTestsOutputDirUrl() { + return ModuleRootManager.getInstance(myMainModule).getCompilerOutputPathForTestsUrl(); + } + + public boolean isJ2EE() { + // assuming that j2ee modules cannot be found inside cycles + return myModules.length == 1 && myModules[0].getModuleType().isJ2EE(); + } + + public boolean isSavePathsRelative() { + return myMainModule.isSavePathsRelative(); + } + + public boolean isJ2EEApplication() { + return myModules.length == 1 && ModuleType.J2EE_APPLICATION.equals(myModules[0].getModuleType()); + } + + public boolean isJdkInherited() { + return ModuleRootManager.getInstance(myMainModule).isJdkInherited(); + } + + public ProjectJdk getJdk() { + return ModuleRootManager.getInstance(myMainModule).getJdk(); + } + + public ModuleChunk[] getDependentChunks() { + return myDependentChunks; + } + + public void setDependentChunks(ModuleChunk[] dependentChunks) { + myDependentChunks = dependentChunks; + } + + public File getBaseDir() { + if (myBaseDir != null) { + return myBaseDir; + } + return new File(myMainModule.getModuleFilePath()).getParentFile(); + } + + public void setBaseDir(File baseDir) { + myBaseDir = baseDir; + } + + public void setMainModule(Module module) { + myMainModule = module; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkAntProject.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkAntProject.java new file mode 100644 index 00000000000..d63556644f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkAntProject.java @@ -0,0 +1,31 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.AntProject; +import com.intellij.compiler.ant.taskdefs.Dirname; +import com.intellij.openapi.project.Project; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +public class ModuleChunkAntProject extends Generator{ + private AntProject myAntProject; + + public ModuleChunkAntProject(Project project, ModuleChunk moduleChunk, GenerationOptions genOptions) { + myAntProject = new AntProject(BuildProperties.getModuleChunkBuildFileName(moduleChunk), BuildProperties.getCompileTargetName(moduleChunk.getName())); + myAntProject.add(new Dirname(BuildProperties.getModuleChunkBasedirProperty(moduleChunk), BuildProperties.propertyRef("ant.file." + BuildProperties.getModuleChunkBuildFileName(moduleChunk)))); + myAntProject.add(new ChunkBuild(project, moduleChunk, genOptions)); + + } + + public void generate(DataOutput out) throws IOException { + out.writeBytes(""); + crlf(out); + myAntProject.generate(out); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkClasspath.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkClasspath.java new file mode 100644 index 00000000000..dc486728f2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkClasspath.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Path; +import com.intellij.compiler.ant.taskdefs.PathElement; +import com.intellij.compiler.ant.taskdefs.PathRef; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.containers.OrderedSet; +import gnu.trove.TObjectHashingStrategy; + +import java.util.Iterator; + +/** + * @author Eugene Zhuravlev + * Date: Nov 22, 2004 + */ +public class ModuleChunkClasspath extends Path{ + + public ModuleChunkClasspath(ModuleChunk chunk, final GenerationOptions genOptions) { + super(BuildProperties.getClasspathProperty(chunk.getName())); + + final OrderedSet pathItems = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); + final String compilerOutputPathUrl = chunk.getOutputDirUrl(); + final String compilerOutputPathForTestsUrl = chunk.getTestsOutputDirUrl(); + final String moduleChunkBasedirProperty = BuildProperties.getModuleChunkBasedirProperty(chunk); + final Module[] modules = chunk.getModules(); + for (int moduleIdx = 0; moduleIdx < modules.length; moduleIdx++) { + final Module module = modules[moduleIdx]; + final OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); + for (int idx = 0; idx < orderEntries.length; idx++) { + final OrderEntry orderEntry = orderEntries[idx]; + if (!orderEntry.isValid()) { + continue; + } + if (orderEntry instanceof JdkOrderEntry) { + pathItems.add(new PathRefItem(BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName())))); + } + else if (orderEntry instanceof LibraryOrderEntry && !((LibraryOrderEntry)orderEntry).isModuleLevel()) { + final String libraryName = ((LibraryOrderEntry)orderEntry).getLibraryName(); + pathItems.add(new PathRefItem(BuildProperties.getLibraryPathId(libraryName))); + } + else { + final String[] files = orderEntry.getUrls(OrderRootType.COMPILATION_CLASSES); + for (int i = 0; i < files.length; i++) { + String url = files[i]; + if (url.endsWith(JarFileSystem.JAR_SEPARATOR)) { + url = url.substring(0, url.length() - JarFileSystem.JAR_SEPARATOR.length()); + } + if (compilerOutputPathUrl != null) { + if (url.equals(compilerOutputPathUrl)) { + continue; + } + } + if (compilerOutputPathForTestsUrl != null) { + if (url.equals(compilerOutputPathForTestsUrl)) { + continue; + } + } + final String propertyRef = genOptions.getPropertyRefForUrl(url); + if (propertyRef != null) { + pathItems.add(new PathElementItem(propertyRef)); + } + else { + final String path = VirtualFileManager.extractPath(url); + pathItems.add(new PathElementItem(GenerationUtils.toRelativePath(path, chunk.getBaseDir(), moduleChunkBasedirProperty, genOptions, !chunk.isSavePathsRelative()))); + } + } + } + } + } + for (Iterator it = pathItems.iterator(); it.hasNext();) { + add(it.next().toGenerator()); + } + } + + private abstract static class ClasspathItem { + protected final String myValue; + + public ClasspathItem(String value) { + myValue = value; + } + + public abstract Generator toGenerator(); + } + + private static class PathElementItem extends ClasspathItem { + public PathElementItem(String value) { + super(value); + } + + public Generator toGenerator() { + return new PathElement(myValue); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PathElementItem)) return false; + + final PathElementItem pathElementItem = (PathElementItem)o; + + if (!myValue.equals(pathElementItem.myValue)) return false; + + return true; + } + + public int hashCode() { + return myValue.hashCode(); + } + } + + private static class PathRefItem extends ClasspathItem { + public PathRefItem(String value) { + super(value); + } + + public Generator toGenerator() { + return new PathRef(myValue); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PathRefItem)) return false; + + final PathRefItem pathRefItem = (PathRefItem)o; + + if (!myValue.equals(pathRefItem.myValue)) return false; + + return true; + } + + public int hashCode() { + return myValue.hashCode(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkSourcepath.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkSourcepath.java new file mode 100644 index 00000000000..7bb8f942961 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleChunkSourcepath.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleFileIndex; +import com.intellij.openapi.roots.ContentEntry; + +import java.io.File; +import java.util.List; +import java.util.ArrayList; + +/** + * @author Eugene Zhuravlev + * Date: Nov 22, 2004 + */ +public class ModuleChunkSourcepath extends CompositeGenerator{ + private VirtualFile[] mySourceRoots; + private VirtualFile[] myTestSourceRoots; + + public ModuleChunkSourcepath(final Project project, ModuleChunk chunk, final GenerationOptions genOptions) { + final Path sourcepath = new Path(BuildProperties.getSourcepathProperty(chunk.getName())); + final Path testSourcepath = new Path(BuildProperties.getTestSourcepathProperty(chunk.getName())); + final PatternSet excludedFromCompilation = new PatternSet(BuildProperties.getExcludedFromCompilationProperty(chunk.getName())); + final String moduleChunkBasedirProperty = BuildProperties.getModuleChunkBasedirProperty(chunk); + final Module[] modules = chunk.getModules(); + + if (CompilerExcludes.isAvailable(project)) { + excludedFromCompilation.add(new PatternSetRef(BuildProperties.PROPERTY_COMPILER_EXCLUDES)); + } + + final List sourceRootFiles = new ArrayList(); + final List testSourceRootFiles = new ArrayList(); + + for (int moduleIdx = 0; moduleIdx < modules.length; moduleIdx++) { + final Module module = modules[moduleIdx]; + final String moduleName = module.getName(); + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final ModuleFileIndex moduleFileIndex = rootManager.getFileIndex(); + + + final PatternSet excludedFromModule = new PatternSet(BuildProperties.getExcludedFromModuleProperty(moduleName)); + + final ContentEntry[] contentEntries = rootManager.getContentEntries(); + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + final VirtualFile file = contentEntry.getFile(); + if (file == null) { + continue; // filter invalid entries + } + if (!(file.getFileSystem() instanceof LocalFileSystem)) { + continue; // skip content roots inside jar and zip archives + } + final VirtualFile dirSetRoot = getDirSetRoot(contentEntry); + + final String dirSetRootRelativeToBasedir = GenerationUtils.toRelativePath(dirSetRoot, chunk.getBaseDir(), moduleChunkBasedirProperty, genOptions, !module.isSavePathsRelative()); + final DirSet sourcesDirSet = new DirSet(dirSetRootRelativeToBasedir); + final DirSet testSourcesDirSet = new DirSet(dirSetRootRelativeToBasedir); + + final VirtualFile[] sourceRoots = contentEntry.getSourceFolderFiles(); + for (int i = 0; i < sourceRoots.length; i++) { + final VirtualFile root = sourceRoots[i]; + if (!moduleFileIndex.isInContent(root)) { + continue; // skip library sources + } + + addExcludePatterns(module, root, root, excludedFromModule, true); + + final Include include = new Include(VfsUtil.getRelativePath(root, dirSetRoot, '/')); + if (moduleFileIndex.isInTestSourceContent(root)) { + testSourcesDirSet.add(include); + testSourceRootFiles.add(root); + } + else { + sourcesDirSet.add(include); + sourceRootFiles.add(root); + } + } + if (sourcesDirSet.getGeneratorCount() > 0) { + sourcepath.add(sourcesDirSet); + } + if (testSourcesDirSet.getGeneratorCount() > 0) { + testSourcepath.add(testSourcesDirSet); + } + } + + if (excludedFromModule.getGeneratorCount() > 0) { + add(excludedFromModule); + excludedFromCompilation.add(new PatternSetRef(BuildProperties.getExcludedFromModuleProperty(moduleName))); + } + } + + mySourceRoots = sourceRootFiles.toArray(new VirtualFile[sourceRootFiles.size()]); + myTestSourceRoots = testSourceRootFiles.toArray(new VirtualFile[testSourceRootFiles.size()]); + + if (excludedFromCompilation.getGeneratorCount() > 0) { + add(excludedFromCompilation, 1); + } + if (sourcepath.getGeneratorCount() > 0) { + add(sourcepath, 1); + } + if (testSourcepath.getGeneratorCount() != 0) { + add(testSourcepath, 1); + } + } + + public VirtualFile[] getSourceRoots() { + return mySourceRoots; + } + + public VirtualFile[] getTestSourceRoots() { + return myTestSourceRoots; + } + + private VirtualFile getDirSetRoot(final ContentEntry contentEntry) { + final VirtualFile contentRoot = contentEntry.getFile(); + final VirtualFile[] sourceFolderFiles = contentEntry.getSourceFolderFiles(); + for (int idx = 0; idx < sourceFolderFiles.length; idx++) { + VirtualFile sourceFolderFile = sourceFolderFiles[idx]; + if (contentRoot.equals(sourceFolderFile)) { + return contentRoot.getParent(); + } + } + return contentRoot; + } + + private void addExcludePatterns(Module module, final VirtualFile root, VirtualFile dir, CompositeGenerator generator, final boolean parentIncluded) { + final boolean isIncluded = ModuleRootManager.getInstance(module).getFileIndex().isInContent(dir); + if (isIncluded != parentIncluded) { + final String relativePath = VfsUtil.getRelativePath(dir, root, '/'); + if (isIncluded) { + generator.add(new Include(relativePath + "/**")); + } + else { + if (!isExcludedByDefault(dir.getName())) { + generator.add(new Exclude(relativePath + "/**")); + } + } + } + final VirtualFile[] children = dir.getChildren(); + for (int idx = 0; idx < children.length; idx++) { + VirtualFile child = children[idx]; + if (child.isDirectory()) { + addExcludePatterns(module, root, child, generator, isIncluded); + } + } + } + + private boolean isExcludedByDefault(String name) { + return "CVS".equals(name) || "SCCS".equals(name) || ".DS_Store".equals(name); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleSources.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleSources.java new file mode 100644 index 00000000000..399b4619318 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ModuleSources.java @@ -0,0 +1,146 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.*; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModuleFileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class ModuleSources extends CompositeGenerator{ + private VirtualFile[] mySourceRoots = VirtualFile.EMPTY_ARRAY; + private VirtualFile[] myTestSourceRoots = VirtualFile.EMPTY_ARRAY; + + public ModuleSources(Module module, File baseDir, final GenerationOptions genOptions) { + /* + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final ModuleFileIndex moduleFileIndex = rootManager.getFileIndex(); + + final List sourceRootFiles = new ArrayList(); + final List testSourceRootFiles = new ArrayList(); + + final Path sourcepath = new Path(BuildProperties.getSourcepathProperty(module.getName())); + final Path testSourcepath = new Path(BuildProperties.getTestSourcepathProperty(module.getName())); + final PatternSet excludedFromModule = new PatternSet(BuildProperties.getExcludedFromModuleProperty(module.getName())); + + final ContentEntry[] contentEntries = rootManager.getContentEntries(); + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + final VirtualFile file = contentEntry.getFile(); + if (file == null) { + continue; // filter invalid entries + } + if (!(file.getFileSystem() instanceof LocalFileSystem)) { + continue; // skip content roots inside jar and zip archives + } + final VirtualFile dirSetRoot = getDirSetRoot(contentEntry); + + final String dirSetRootRelativeToBasedir = GenerationUtils.toRelativePath(dirSetRoot, baseDir, BuildProperties.getModuleChunkBasedirProperty(module), genOptions, !module.isSavePathsRelative()); + final DirSet sourcesDirSet = new DirSet(dirSetRootRelativeToBasedir); + final DirSet testSourcesDirSet = new DirSet(dirSetRootRelativeToBasedir); + + final VirtualFile[] sourceRoots = contentEntry.getSourceFolderFiles(); + for (int i = 0; i < sourceRoots.length; i++) { + final VirtualFile root = sourceRoots[i]; + if (!moduleFileIndex.isInContent(root)) { + continue; // skip library sources + } + + addExcludePatterns(module, root, root, excludedFromModule, true); + + final Include include = new Include(VfsUtil.getRelativePath(root, dirSetRoot, '/')); + if (moduleFileIndex.isInTestSourceContent(root)) { + testSourcesDirSet.add(include); + testSourceRootFiles.add(root); + } + else { + sourcesDirSet.add(include); + sourceRootFiles.add(root); + } + } + if (sourcesDirSet.getGeneratorCount() > 0) { + sourcepath.add(sourcesDirSet); + } + if (testSourcesDirSet.getGeneratorCount() > 0) { + testSourcepath.add(testSourcesDirSet); + } + } + + mySourceRoots = sourceRootFiles.toArray(new VirtualFile[sourceRootFiles.size()]); + myTestSourceRoots = testSourceRootFiles.toArray(new VirtualFile[testSourceRootFiles.size()]); + + final String moduleName = module.getName(); + + add(excludedFromModule); + + final PatternSet excludedFromCompilation = new PatternSet(BuildProperties.getExcludedFromCompilationProperty(moduleName)); + excludedFromCompilation.add(new PatternSetRef(BuildProperties.getExcludedFromModuleProperty(moduleName))); + excludedFromCompilation.add(new PatternSetRef(BuildProperties.PROPERTY_COMPILER_EXCLUDES)); + add(excludedFromCompilation, 1); + + if (sourcepath.getGeneratorCount() > 0) { + add(sourcepath, 1); + } + if (testSourcepath.getGeneratorCount() != 0) { + add(testSourcepath, 1); + } + */ + } + + private VirtualFile getDirSetRoot(final ContentEntry contentEntry) { + final VirtualFile contentRoot = contentEntry.getFile(); + final VirtualFile[] sourceFolderFiles = contentEntry.getSourceFolderFiles(); + for (int idx = 0; idx < sourceFolderFiles.length; idx++) { + VirtualFile sourceFolderFile = sourceFolderFiles[idx]; + if (contentRoot.equals(sourceFolderFile)) { + return contentRoot.getParent(); + } + } + return contentRoot; + } + + private void addExcludePatterns(Module module, final VirtualFile root, VirtualFile dir, CompositeGenerator generator, final boolean parentIncluded) { + final boolean isIncluded = ModuleRootManager.getInstance(module).getFileIndex().isInContent(dir); + if (isIncluded != parentIncluded) { + final String relativePath = VfsUtil.getRelativePath(dir, root, '/'); + if (isIncluded) { + generator.add(new Include(relativePath + "/**")); + } + else { + if (!isExcludedByDefault(dir.getName())) { + generator.add(new Exclude(relativePath + "/**")); + } + } + } + final VirtualFile[] children = dir.getChildren(); + for (int idx = 0; idx < children.length; idx++) { + VirtualFile child = children[idx]; + if (child.isDirectory()) { + addExcludePatterns(module, root, child, generator, isIncluded); + } + } + } + + private boolean isExcludedByDefault(String name) { + return "CVS".equals(name) || "SCCS".equals(name) || ".DS_Store".equals(name); + } + + public VirtualFile[] getSourceRoots() { + return mySourceRoots; + } + + public VirtualFile[] getTestSourceRoots() { + return myTestSourceRoots; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/MultipleFileProjectBuild.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/MultipleFileProjectBuild.java new file mode 100644 index 00000000000..73df5c4d6e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/MultipleFileProjectBuild.java @@ -0,0 +1,27 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Import; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +public class MultipleFileProjectBuild extends ProjectBuild{ + public MultipleFileProjectBuild(Project project, GenerationOptions genOptions) { + super(project, genOptions); + } + + protected Generator createModuleBuildGenerator(ModuleChunk chunk, GenerationOptions genOptions) { + final String chunkBuildFile = BuildProperties.getModuleChunkBaseDir(chunk).getPath() + File.separator + BuildProperties.getModuleChunkBuildFileName(chunk) + ".xml"; + final File projectBaseDir = BuildProperties.getProjectBaseDir(myProject); + final String pathToFile = GenerationUtils.toRelativePath( + chunkBuildFile, projectBaseDir, BuildProperties.getProjectBaseDirProperty(), genOptions, !chunk.isSavePathsRelative() + ); + return new Import(pathToFile); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ProjectBuild.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ProjectBuild.java new file mode 100644 index 00000000000..ee3d5633e1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/ProjectBuild.java @@ -0,0 +1,77 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.Chunk; +import com.intellij.compiler.ModuleCompilerUtil; +import com.intellij.compiler.ant.taskdefs.AntProject; +import com.intellij.compiler.ant.taskdefs.Target; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; + +import javax.naming.OperationNotSupportedException; +import java.io.DataOutput; +import java.io.IOException; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Mar 24, 2004 + */ +public abstract class ProjectBuild extends Generator { + protected final Project myProject; + private final AntProject myAntProject; + + public ProjectBuild(Project project, GenerationOptions genOptions) { + myProject = project; + myAntProject = new AntProject(BuildProperties.getProjectBuildFileName(myProject), BuildProperties.DEFAULT_TARGET); + + myAntProject.add(new BuildProperties(myProject, genOptions), 1); + + // the sequence in which modules are imported is important cause output path properties for dependent modules should be defined first + + final StringBuffer alltargetNames = new StringBuffer(); + alltargetNames.append(BuildProperties.TARGET_INIT); + alltargetNames.append(", "); + alltargetNames.append(BuildProperties.TARGET_CLEAN); + final ModuleChunk[] chunks = genOptions.getModuleChunks(); + + if (chunks.length > 0) { + myAntProject.add(new Comment("Modules"), 1); + + for (int idx = 0; idx < chunks.length; idx++) { + final ModuleChunk chunk = chunks[idx]; + myAntProject.add(createModuleBuildGenerator(chunk, genOptions), 1); + if (alltargetNames.length() > 0) { + alltargetNames.append(", "); + } + final String chunkName = chunk.getName(); + + if (chunk.isJ2EE()) { + alltargetNames.append(BuildProperties.getJ2EEBuildTargetName(chunkName)); + } + else { + alltargetNames.append(BuildProperties.getCompileTargetName(chunkName)); + } + } + } + + final Target initTarget = new Target(BuildProperties.TARGET_INIT, null, "Build initialization", null); + initTarget.add(new Comment("Perform any build initialization in this target")); + myAntProject.add(initTarget, 1); + myAntProject.add(new CleanProject(genOptions), 1); + myAntProject.add(new Target(BuildProperties.TARGET_ALL, alltargetNames.toString(), "build all", null), 1); + } + + public void generate(DataOutput out) throws IOException { + out.writeBytes(""); + crlf(out); + myAntProject.generate(out); + } + + protected abstract Generator createModuleBuildGenerator(final ModuleChunk chunk, GenerationOptions genOptions); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/PropertyFileGenerator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/PropertyFileGenerator.java new file mode 100644 index 00000000000..7c1f70406be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/PropertyFileGenerator.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.ant; + +import com.intellij.application.options.PathMacros; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VfsUtil; + +import java.io.DataOutput; +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 27, 2004 + */ +public class PropertyFileGenerator extends Generator{ + private List> myProperties = new ArrayList>(); + + public PropertyFileGenerator(Project project) { + // path variables + final PathMacros pathMacros = PathMacros.getInstance(); + final Set macroNamesSet = pathMacros.getUserMacroNames(); + if (macroNamesSet.size() > 0) { + final String[] macroNames = macroNamesSet.toArray(new String[macroNamesSet.size()]); + Arrays.sort(macroNames); + for (int idx = 0; idx < macroNames.length; idx++) { + final String macroName = macroNames[idx]; + addProperty(BuildProperties.getPathMacroProperty(macroName), pathMacros.getValue(macroName)); + } + } + // jdk homes + final ProjectJdk[] usedJdks = BuildProperties.getUsedJdks(project); + for (int idx = 0; idx < usedJdks.length; idx++) { + ProjectJdk jdk = usedJdks[idx]; + if (jdk.getHomeDirectory() == null) { + continue; + } + final File homeDir = VfsUtil.virtualToIoFile(jdk.getHomeDirectory()); + addProperty(BuildProperties.getJdkHomeProperty(jdk.getName()), homeDir.getPath().replace(File.separatorChar, '/')); + } + } + + public void addProperty(String name, String value) { + myProperties.add(new Pair(name, value)); + } + + public void generate(DataOutput out) throws IOException { + boolean isFirst = true; + for (Iterator> it = myProperties.iterator(); it.hasNext();) { + final Pair pair = (Pair)it.next(); + if (!isFirst) { + crlf(out); + } + else { + isFirst = false; + } + out.writeBytes(pair.getFirst()); + out.writeBytes("="); + out.writeBytes(pair.getSecond()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/SingleFileProjectBuild.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/SingleFileProjectBuild.java new file mode 100644 index 00000000000..3a69b077c5c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/SingleFileProjectBuild.java @@ -0,0 +1,23 @@ +package com.intellij.compiler.ant; + +import com.intellij.compiler.ant.taskdefs.Dirname; +import com.intellij.openapi.project.Project; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +public class SingleFileProjectBuild extends ProjectBuild { + public SingleFileProjectBuild(Project project, GenerationOptions genOptions) { + super(project, genOptions); + } + + protected Generator createModuleBuildGenerator(ModuleChunk chunk, GenerationOptions genOptions) { + final CompositeGenerator gen = new CompositeGenerator(); + gen.add(new Comment("Module " + chunk.getName())); + gen.add(new Dirname(BuildProperties.getModuleChunkBasedirProperty(chunk), BuildProperties.propertyRef("ant.file")), 1); + gen.add(new ChunkBuild(myProject, chunk, genOptions), 1); + return gen; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Tag.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Tag.java new file mode 100644 index 00000000000..ca6c1178962 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/Tag.java @@ -0,0 +1,67 @@ +package com.intellij.compiler.ant; + +import com.intellij.openapi.util.Pair; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Tag extends CompositeGenerator { + private final String myTagName; + private final Pair[] myTagOptions; + + public Tag(String tagName, Pair[] tagOptions) { + myTagName = tagName; + myTagOptions = tagOptions; + } + + public void generate(DataOutput out) throws IOException { + out.writeBytes("<"); + out.writeBytes(myTagName); + if (myTagOptions != null && myTagOptions.length > 0) { + out.writeBytes(" "); + int generated = 0; + for (int idx = 0; idx < myTagOptions.length; idx++) { + final Pair option = myTagOptions[idx]; + if (option == null) { + continue; + } + if (generated > 0) { + out.writeBytes(" "); + } + out.writeBytes((String)option.getFirst()); + out.writeBytes("=\""); + out.writeBytes((String)option.getSecond()); + out.writeBytes("\""); + generated += 1; + } + } + if (getGeneratorCount() > 0) { + out.writeBytes(">"); + shiftIndent(); + try { + super.generate(out); + } + finally { + unshiftIndent(); + } + crlf(out); + out.writeBytes(""); + } + else { + out.writeBytes("/>"); + } + } + + protected static Pair pair(String v1, String v2) { + if (v2 == null) { + return null; + } + return new Pair(v1, v2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntCall.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntCall.java new file mode 100644 index 00000000000..c2d64297f7b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntCall.java @@ -0,0 +1,15 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class AntCall extends Tag{ + + public AntCall(final String target) { + super("antcall", new Pair[] {new Pair("target", target)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntProject.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntProject.java new file mode 100644 index 00000000000..41b4796e9e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/AntProject.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 25, 2004 + */ +public class AntProject extends Tag { + public AntProject(String name, String defaultTarget) { + super("project", new Pair[]{new Pair("name", name), new Pair("default", defaultTarget)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Attribute.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Attribute.java new file mode 100644 index 00000000000..0ec2ac4c9bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Attribute.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Attribute extends Tag{ + public Attribute(String name, String value) { + super("attribute", new Pair[] {Pair.create("name", name),Pair.create("value", value)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Copy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Copy.java new file mode 100644 index 00000000000..db1c067dc1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Copy.java @@ -0,0 +1,17 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 23, 2004 + */ +public class Copy extends Tag { + public Copy(String toDir) { + super("copy", new Pair[] {new Pair("todir", toDir)}); + } + public Copy(String file, String toFile) { + super("copy", new Pair[] {new Pair("file", file), new Pair("tofile", toFile)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Delete.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Delete.java new file mode 100644 index 00000000000..f1c35eae2dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Delete.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Delete extends Tag{ + public Delete(String dir) { + super("delete", new Pair[] {Pair.create("dir", dir)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/DirSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/DirSet.java new file mode 100644 index 00000000000..0efc44631cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/DirSet.java @@ -0,0 +1,15 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class DirSet extends Tag{ + + public DirSet(final String dir) { + super("dirset", new Pair[] {new Pair("dir", dir)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Dirname.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Dirname.java new file mode 100644 index 00000000000..1452989d0e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Dirname.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 25, 2004 + */ +public class Dirname extends Tag{ + public Dirname(String property, String file) { + super("dirname", new Pair[] {new Pair("property", property), new Pair("file", file)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Exclude.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Exclude.java new file mode 100644 index 00000000000..659b40d1eb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Exclude.java @@ -0,0 +1,16 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Exclude extends Tag { + + public Exclude(final String name) { + super("exclude", new Pair[] {new Pair("name", name)}); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/FileSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/FileSet.java new file mode 100644 index 00000000000..5f5f0c5af90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/FileSet.java @@ -0,0 +1,16 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class FileSet extends Tag{ + + public FileSet(final String dir) { + super("fileset", new Pair[] {pair("dir", dir)}); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Import.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Import.java new file mode 100644 index 00000000000..f771082434d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Import.java @@ -0,0 +1,18 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 24, 2004 + */ +public class Import extends Tag{ + public Import(String file, boolean optional) { + super("import", new Pair[] {new Pair("file", file), new Pair("optional", optional? "true" : "false")}); + } + + public Import(String file) { + super("import", new Pair[] {new Pair("file", file)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Include.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Include.java new file mode 100644 index 00000000000..43e286842ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Include.java @@ -0,0 +1,16 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Include extends Tag { + + public Include(final String name) { + super("include", new Pair[] {new Pair("name", name)}); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Jar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Jar.java new file mode 100644 index 00000000000..7ecbb550dbe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Jar.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Jar extends Tag { + public Jar(final String destFile, String duplicate) { + super("jar", new Pair[] {Pair.create("destfile", destFile), Pair.create("duplicate", duplicate)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Javac.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Javac.java new file mode 100644 index 00000000000..642c82c3794 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Javac.java @@ -0,0 +1,34 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.compiler.ant.BuildProperties; +import com.intellij.compiler.ant.Tag; +import com.intellij.openapi.util.Pair; + +/** + * @author Eugene Zhuravlev + * Date: Mar 16, 2004 + */ +public class Javac extends Tag{ + + public Javac(final String outputDir, final String moduleName) { + this("javac", moduleName, outputDir); + } + + public Javac(final String taskName, String moduleName, final String outputDir) { + super(taskName, new Pair[]{ + pair("destdir", outputDir), + pair("debug", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_DEBUG_INFO)), + pair("nowarn", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_NO_WARNINGS)), + pair("memoryMaximumSize", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_MAX_MEMORY)), + pair("fork", "true"), + pair("executable", getExecutable(moduleName)) + }); + } + + private static String getExecutable(String moduleName) { + if (moduleName == null) { + return null; + } + return BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkHomeProperty(moduleName)) + "/bin/javac"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Manifest.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Manifest.java new file mode 100644 index 00000000000..697d6f12ed8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Manifest.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Manifest extends Tag{ + public Manifest() { + super("manifest", new Pair[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Mkdir.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Mkdir.java new file mode 100644 index 00000000000..dce6a5bef4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Mkdir.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 17, 2004 + */ +public class Mkdir extends Tag { + public Mkdir(String directory) { + super("mkdir", new Pair[] {new Pair("dir", directory)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Param.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Param.java new file mode 100644 index 00000000000..81b75b8994a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Param.java @@ -0,0 +1,18 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Param extends Tag { + public Param(final String name, final String value) { + super("param", new Pair[] { + new Pair("name", name), + new Pair("value", value) + }); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Path.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Path.java new file mode 100644 index 00000000000..53bc2a1cc3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Path.java @@ -0,0 +1,15 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Path extends Tag{ + + public Path(final String id) { + super("path", new Pair[] {pair("id", id)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathElement.java new file mode 100644 index 00000000000..c3af3ff563e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathElement.java @@ -0,0 +1,17 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class PathElement extends Tag{ + + public PathElement(String dir) { + super("pathelement", new Pair[]{new Pair("location", dir)}); + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathRef.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathRef.java new file mode 100644 index 00000000000..405e50c640d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PathRef.java @@ -0,0 +1,16 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class PathRef extends Tag{ + + public PathRef(final String refid) { + super("path", new Pair[] {pair("refid", refid)}); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSet.java new file mode 100644 index 00000000000..dda19cdf58f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSet.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class PatternSet extends Tag{ + public PatternSet(final String id) { + super("patternset", new Pair[] {new Pair("id", id)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSetRef.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSetRef.java new file mode 100644 index 00000000000..5df2846c837 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/PatternSetRef.java @@ -0,0 +1,14 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class PatternSetRef extends Tag{ + public PatternSetRef(final String refid) { + super("patternset", new Pair[] {new Pair("refid", refid)}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Property.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Property.java new file mode 100644 index 00000000000..3152c93dda8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Property.java @@ -0,0 +1,25 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.compiler.ant.Tag; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Property extends Tag { + + public Property(final String name, final String value) { + super("property", new Pair[] { + new Pair("name", name), + new Pair("value", value) + }); + } + + public Property(final String filePath) { + super("property", new Pair[] { + new Pair("file", filePath), + }); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Target.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Target.java new file mode 100644 index 00000000000..e3867d5feeb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/Target.java @@ -0,0 +1,33 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.compiler.ant.Tag; +import com.intellij.openapi.util.Pair; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class Target extends Tag{ + public Target(String name, String depends, String description, String unlessCondition) { + super("target", getOptions(name, depends, description, unlessCondition)); + } + + private static Pair[] getOptions(String name, String depends, String description, String unlessCondition) { + final List options = new ArrayList(); + options.add(new Pair("name", name)); + if (depends != null && depends.length() > 0) { + options.add(new Pair("depends", depends)); + } + if (description != null && description.length() > 0) { + options.add(new Pair("description", description)); + } + if (unlessCondition != null && unlessCondition.length() > 0) { + options.add(new Pair("unless", unlessCondition)); + } + return options.toArray(new Pair[options.size()]); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/ZipFileSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/ZipFileSet.java new file mode 100644 index 00000000000..6b4bb92d77f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/ant/taskdefs/ZipFileSet.java @@ -0,0 +1,25 @@ +package com.intellij.compiler.ant.taskdefs; + +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.compiler.ant.Tag; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 19, 2004 + */ +public class ZipFileSet extends Tag{ + public ZipFileSet(String fileOrDir, final String relativePath, boolean isDir) { + super("zipfileset", new Pair[] { + pair(isDir ? "dir" : "file", fileOrDir), + pair("prefix", isDir ? relativePath : makeFilePrefix(relativePath))}); + } + + private static String makeFilePrefix(final String fileName) { + final String parent = new File(fileName).getParent(); + if (parent == null) return ""; + return FileUtil.toSystemIndependentName(parent); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationConstantValue.java new file mode 100644 index 00000000000..80302e5f24e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationConstantValue.java @@ -0,0 +1,70 @@ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +/** + * @author Eugene Zhuravlev + * Date: Apr 2, 2004 + */ +public class AnnotationConstantValue extends ConstantValue { + public static final AnnotationConstantValue[] EMPTY_ARRAY = new AnnotationConstantValue[0]; + public static final AnnotationConstantValue[][] EMPTY_ARRAY_ARRAY = new AnnotationConstantValue[0][]; + public final int myQName; + public final AnnotationNameValuePair[] myMemberValues; + + public AnnotationConstantValue(int qName, AnnotationNameValuePair[] memberValues) { + myQName = qName; + myMemberValues = memberValues; + } + + public int getAnnotationQName() { + return myQName; + } + + /** + * @return an array of Integer -> ConstantValue pairs + */ + public AnnotationNameValuePair[] getMemberValues() { + return myMemberValues; + } + + public AnnotationConstantValue(DataInput in) throws IOException { + myQName = in.readInt(); + final int size = in.readInt(); + myMemberValues = new AnnotationNameValuePair[size]; + for (int idx = 0; idx < myMemberValues.length; idx++) { + final int name = in.readInt(); + final ConstantValue constantValue = MemberInfoExternalizer.loadConstantValue(in); + myMemberValues[idx] = new AnnotationNameValuePair(name, constantValue); + } + } + + public void save(DataOutput out) throws IOException { + out.writeInt(myQName); + out.writeInt(myMemberValues.length); + for (int idx = 0; idx < myMemberValues.length; idx++) { + final AnnotationNameValuePair nameValuePair = myMemberValues[idx]; + out.writeInt(nameValuePair.getName()); + MemberInfoExternalizer.saveConstantValue(out, nameValuePair.getValue()); + } + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AnnotationConstantValue)) return false; + + final AnnotationConstantValue annotationConstantValue = (AnnotationConstantValue)o; + + if (myQName != annotationConstantValue.myQName) return false; + if (!Arrays.equals(myMemberValues, annotationConstantValue.myMemberValues)) return false; + + return true; + } + + public int hashCode() { + return myQName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationNameValuePair.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationNameValuePair.java new file mode 100644 index 00000000000..d0defb9e65a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationNameValuePair.java @@ -0,0 +1,23 @@ +package com.intellij.compiler.classParsing; + +/** + * @author Eugene Zhuravlev + * Date: Apr 8, 2004 + */ +public class AnnotationNameValuePair { + private final int myName; + private final ConstantValue myValue; + + public AnnotationNameValuePair(int name, ConstantValue value) { + myName = name; + myValue = value; + } + + public int getName() { + return myName; + } + + public ConstantValue getValue() { + return myValue; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java new file mode 100644 index 00000000000..8a9df5a79cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java @@ -0,0 +1,57 @@ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author Eugene Zhuravlev + * Date: Apr 2, 2004 + */ +public class AnnotationPrimitiveConstantValue extends ConstantValue{ + private final char myValueTag; + private final ConstantValue myValue; + + public AnnotationPrimitiveConstantValue(char valueTag, ConstantValue value) { + myValueTag = valueTag; + myValue = value; + } + + public AnnotationPrimitiveConstantValue(DataInput in) throws IOException { + myValueTag = in.readChar(); + myValue = MemberInfoExternalizer.loadConstantValue(in); + } + + public char getValueTag() { + return myValueTag; + } + + public ConstantValue getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + out.writeChar(myValueTag); + MemberInfoExternalizer.saveConstantValue(out, myValue); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AnnotationPrimitiveConstantValue)) return false; + + final AnnotationPrimitiveConstantValue memberValue = (AnnotationPrimitiveConstantValue)o; + + if (myValueTag != memberValue.myValueTag) return false; + if (!myValue.equals(memberValue.myValue)) return false; + + return true; + } + + public int hashCode() { + int result; + result = (int)myValueTag; + result = 29 * result + myValue.hashCode(); + return result; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassFileReader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassFileReader.java new file mode 100644 index 00000000000..1d76db46320 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassFileReader.java @@ -0,0 +1,748 @@ +/** + * created at Jan 2, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import com.intellij.compiler.SymbolTable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.cls.BytePointer; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.cls.ClsUtil; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileReader { + private File myFile; + private byte[] myData; + private int[] myConstantPoolOffsets = null; // the last offset points to the constant pool end + + private String myQualifiedName; + private String myGenericSignature; + private List myReferences; + private List myFields; + private List myMethods; + private String mySourceFileName; + private String mySuperClassName; + private String[] mySuperInterfaces; + private final SymbolTable mySymbolTable; + private AnnotationConstantValue[] myRuntimeVisibleAnnotations; + private AnnotationConstantValue[] myRuntimeInvisibleAnnotations; + + public ClassFileReader(File file, SymbolTable symbolTable) throws ClsFormatException { + mySymbolTable = symbolTable; + if (file == null) { + throw new ClsFormatException(); + } + if (file.isDirectory()) { + throw new ClsFormatException(); + } + myFile = file; + } + + public String getPath() { + return myFile.getAbsolutePath(); + } + + public ReferenceInfo[] getReferences() throws ClsFormatException { + parseConstantPool(); + return myReferences.toArray(new ReferenceInfo[myReferences.size()]); + } + + public MethodInfo[] getMethods() throws ClsFormatException{ + if (myMethods == null) { + parseMembers(); + } + return myMethods.toArray(new MethodInfo[myMethods.size()]); + } + + public FieldInfo[] getFields() throws ClsFormatException{ + if (myFields == null) { + parseMembers(); + } + return myFields.toArray(new FieldInfo[myFields.size()]); + } + + private void parseMembers() throws ClsFormatException { + initConstantPool(); + myMethods = new ArrayList(); + myFields = new ArrayList(); + BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd()); + ptr.offset += 2; // access flags + ptr.offset += 2; // this class + ptr.offset += 2; // super class + int count = ClsUtil.readU2(ptr); // interface count + ptr.offset += 2 * count; // skip interface infos + count = ClsUtil.readU2(ptr); // field count + while (count-- > 0) { + FieldInfo field = (FieldInfo)readMemberStructure(ptr, true); + String name = mySymbolTable.getSymbol(field.getName()); + if (name.indexOf('$') < 0 && name.indexOf('<') < 0){ // skip synthetic fields + myFields.add(field); + } + } + count = ClsUtil.readU2(ptr); // method count + while (count-- > 0) { + MethodInfo method = (MethodInfo)readMemberStructure(ptr, false); + String name = mySymbolTable.getSymbol(method.getName()); + if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip synthetic methods + myMethods.add(method); + } + else if ("".equals(name)) { // store constructors + myMethods.add(method); + } + } + + final ClsAttributeTable attributeTable = readAttributes(ptr); + mySourceFileName = attributeTable.sourceFile; + myGenericSignature = attributeTable.genericSignature; + myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations; + myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations; + } + + private MemberInfo readMemberStructure(BytePointer ptr, boolean isField) throws ClsFormatException { + int flags = ClsUtil.readU2(ptr); + int nameIndex = ClsUtil.readU2(ptr); + int descriptorIndex = ClsUtil.readU2(ptr); + + BytePointer p = new BytePointer(getData(), getOffsetInConstantPool(nameIndex)); + String name = ClsUtil.readUtf8Info(p); + p.offset = getOffsetInConstantPool(descriptorIndex); + String descriptor = ClsUtil.readUtf8Info(p); + + if (isField) { + final ClsAttributeTable attributeTable = readAttributes(ptr); + return new FieldInfo( + mySymbolTable.getId(name), + mySymbolTable.getId(descriptor), + attributeTable.genericSignature != null? mySymbolTable.getId(attributeTable.genericSignature) : -1, + flags, + attributeTable.constantValue, + attributeTable.runtimeVisibleAnnotations, + attributeTable.runtimeInvisibleAnnotations + ); + } + else { + final ClsAttributeTable attributeTable = readAttributes(ptr); + int[] intExceptions = null; + if (attributeTable.exceptions != null) { + intExceptions = new int[attributeTable.exceptions.length]; + for (int idx = 0; idx < intExceptions.length; idx++) { + intExceptions[idx] = mySymbolTable.getId(attributeTable.exceptions[idx]); + } + } + return new MethodInfo( + mySymbolTable.getId(name), + mySymbolTable.getId(descriptor), + attributeTable.genericSignature != null? mySymbolTable.getId(attributeTable.genericSignature) : -1, + flags, + intExceptions, + "".equals(name), + attributeTable.runtimeVisibleAnnotations, + attributeTable.runtimeInvisibleAnnotations, + attributeTable.runtimeVisibleParameterAnnotations, + attributeTable.runtimeInvisibleParameterAnnotations, + attributeTable.annotationDefault + ); + } + } + + public String getQualifiedName() throws ClsFormatException { + if (myQualifiedName == null) { + BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 2); + ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + int tag = ClsUtil.readU1(ptr); + if (tag != ClsUtil.CONSTANT_Class){ + throw new ClsFormatException(); + } + ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + myQualifiedName = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in the names + } + return myQualifiedName; + } + + /** + * @return fully qualified name of the class' superclass. In case there is no super return "" + */ + public String getSuperClass() throws ClsFormatException { + if (mySuperClassName == null) { + BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 4); + int index = ClsUtil.readU2(ptr); + if (index == 0) { + if ("java.lang.Object".equals(getQualifiedName())) { + mySuperClassName = ""; + } + else { + throw new ClsFormatException(); + } + } + else { + ptr.offset = getOffsetInConstantPool(index); + mySuperClassName = readClassInfo(ptr); // keep '$' in the name for anonymous classes + if (isInterface()) { + if (!"java.lang.Object".equals(mySuperClassName)) { + throw new ClsFormatException(); + } + } + /* + else { + if (!MakeUtil.isAnonymous(mySuperClassName)) { + mySuperClassName = mySuperClassName.replace('$', '.'); + } + } + */ + } + } + return mySuperClassName; + } + + public String[] getSuperInterfaces() throws ClsFormatException { + if (mySuperInterfaces == null) { + BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 6); + int count = ClsUtil.readU2(ptr); + mySuperInterfaces = new String[count]; + BytePointer auxPtr = new BytePointer(ptr.bytes, 0); + for (int idx = 0; idx < mySuperInterfaces.length; idx++) { + auxPtr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + mySuperInterfaces[idx] = readClassInfo(auxPtr); + } + } + return mySuperInterfaces; + } + + + public String getSourceFileName() throws ClsFormatException { + if (mySourceFileName == null) { + parseMembers(); + if (mySourceFileName == null) { + mySourceFileName = ""; + } + } + return mySourceFileName; + } + + public String getGenericSignature() throws ClsFormatException { + if (myGenericSignature == null) { + parseMembers(); + if (myGenericSignature == null) { + myGenericSignature = ""; + } + } + return (myGenericSignature.length() != 0)? myGenericSignature : null; + } + + public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException { + if (myRuntimeVisibleAnnotations == null) { + parseMembers(); + if (myRuntimeVisibleAnnotations == null) { + myRuntimeVisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; + } + } + return myRuntimeVisibleAnnotations; + } + + public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException { + if (myRuntimeInvisibleAnnotations == null) { + parseMembers(); + if (myRuntimeInvisibleAnnotations == null) { + myRuntimeInvisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; + } + } + return myRuntimeInvisibleAnnotations; + } + + public boolean isInterface(){ + return (getAccessFlags() & ClsUtil.ACC_INTERFACE) != 0; + } + +// helper methods + private void parseConstantPool() throws ClsFormatException { + if (myReferences != null) { + return; + } + myReferences = new ArrayList(); + initConstantPool(); + final BytePointer ptr = new BytePointer(getData(), 0); + ConstantPoolIterator iterator = new ConstantPoolIterator(ptr); + while (iterator.hasMoreEntries()) { + final int tag = ClsUtil.readU1(ptr); + if (tag == ClsUtil.CONSTANT_Fieldref || tag == ClsUtil.CONSTANT_Methodref || tag == ClsUtil.CONSTANT_InterfaceMethodref) { + //ptr.offset -= 1; // position to the beginning of the structure + MemberReferenceInfo refInfo = readRefStructure(tag, ptr); + if (refInfo != null) { + myReferences.add(refInfo); + } + /* + String name = mySymbolTable.getSymbol(refInfo.getMemberInfo().getName()); + if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip refs to synthetic members + myReferences.add(refInfo); + } + else if ("".equals(name)) { // add instance initializers (constructors) + myReferences.add(refInfo); + } + else { + System.out.println("ReferenceInfo thrown out: " + mySymbolTable.getSymbol(refInfo.getClassName()) + "." + mySymbolTable.getSymbol(refInfo.getMemberInfo().getName())); + ourWasteReferenceObjectsCounter += 1; + } + */ + } + else if (tag == ClsUtil.CONSTANT_Class) { + ptr.offset -= 1; // position to the beginning of the structure + String className = readClassInfo(ptr); + myReferences.add(new ReferenceInfo(mySymbolTable.getId(className))); + } + iterator.next(); + } + //System.out.println("ourWasteReferenceObjectsCounter = " + ourWasteReferenceObjectsCounter); + } + + private MemberReferenceInfo readRefStructure(int tag, BytePointer ptr) throws ClsFormatException { + /* + if (tag != ClsUtil.CONSTANT_Fieldref && tag != ClsUtil.CONSTANT_Methodref && tag != ClsUtil.CONSTANT_InterfaceMethodref) { + throw new ClsFormatException(); + } + */ + int classInfoIndex = ClsUtil.readU2(ptr); + int nameTypeInfoIndex = ClsUtil.readU2(ptr); + + ptr.offset = getOffsetInConstantPool(classInfoIndex); + if (ClsUtil.CONSTANT_Class != ClsUtil.readU1(ptr)) { + throw new ClsFormatException(); + } + ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + String className = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in names + + ptr.offset = getOffsetInConstantPool(nameTypeInfoIndex); + if (ClsUtil.CONSTANT_NameAndType != ClsUtil.readU1(ptr)) { + throw new ClsFormatException(); + } + int memberNameIndex = ClsUtil.readU2(ptr); + int descriptorIndex = ClsUtil.readU2(ptr); + + ptr.offset = getOffsetInConstantPool(memberNameIndex); + String memberName = ClsUtil.readUtf8Info(ptr); + + if ((memberName.indexOf('$') >= 0 || memberName.indexOf('<') >= 0) && !"".equals(memberName)) { // skip refs to synthetic members + return null; + } + + ptr.offset = getOffsetInConstantPool(descriptorIndex); + String descriptor = ClsUtil.readUtf8Info(ptr); + + MemberInfo info = ClsUtil.CONSTANT_Fieldref == tag? (MemberInfo)new FieldInfo(mySymbolTable.getId(memberName), mySymbolTable.getId(descriptor)) : (MemberInfo)new MethodInfo(mySymbolTable.getId(memberName), mySymbolTable.getId(descriptor), "".equals(memberName)); + return new MemberReferenceInfo(mySymbolTable.getId(className), info); + } + + public int getAccessFlags(){ + try{ + int offset = getConstantPoolEnd(); + byte[] data = getData(); + if (offset + 2 > data.length){ + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + return (b1 << 8) + b2; + } + catch(ClsFormatException e){ + return 0; + } + } + + private byte[] getData(){ + if (myData == null) { + try{ + if (myFile.isDirectory()) { + throw new IOException("Cannot read from file " + myFile.getPath() + "."); + } + myData = FileUtil.loadFileBytes(myFile); + } + catch(IOException e){ + myData = new byte[0]; + } + } + return myData; + } + + private int getOffsetInConstantPool(int index) throws ClsFormatException { + initConstantPool(); + if (index < 1 || index >= myConstantPoolOffsets.length){ + throw new ClsFormatException(); + } + return myConstantPoolOffsets[index - 1]; + } + + private int getConstantPoolEnd() throws ClsFormatException { + initConstantPool(); + return myConstantPoolOffsets[myConstantPoolOffsets.length - 1]; + } + + private void initConstantPool() throws ClsFormatException { + if (myConstantPoolOffsets == null){ + BytePointer ptr = new BytePointer(getData(), 0); + ConstantPoolIterator iterator = new ConstantPoolIterator(ptr); + myConstantPoolOffsets = new int[iterator.getEntryCount()]; + myConstantPoolOffsets[0] = iterator.getCurrentOffset(); + int index = 1; + while (iterator.hasMoreEntries()) { + int tag = ClsUtil.readU1(ptr); + if (tag == ClsUtil.CONSTANT_Long || tag == ClsUtil.CONSTANT_Double) { + myConstantPoolOffsets[index++] = ptr.offset + 8; // takes 2 entries! + } + iterator.next(); + myConstantPoolOffsets[index++] = iterator.getCurrentOffset(); + } + } + } + + private String readClassInfo(BytePointer ptr) throws ClsFormatException{ + final int tag = ClsUtil.readU1(ptr); + if (tag != ClsUtil.CONSTANT_Class){ + throw new ClsFormatException("Wrong record tag: " + tag + "; expected: " + ClsUtil.CONSTANT_Class); + } + int index = ClsUtil.readU2(ptr); + return ClsUtil.readUtf8Info(new BytePointer(ptr.bytes, getOffsetInConstantPool(index)), '/', '.'); + } + + private ClsAttributeTable readAttributes(BytePointer ptr) throws ClsFormatException { + int count = ClsUtil.readU2(ptr); // attributeCount + final ClsAttributeTable attributes = new ClsAttributeTable(); + while (count-- > 0) { + final String attrName = readAttributeName(ptr); + if ("Exceptions".equals(attrName)) { + attributes.exceptions = readExceptions(ptr); + } + else if ("Signature".equals(attrName)) { + attributes.genericSignature = readSignatureAttribute(ptr); + } + else if ("SourceFile".equals(attrName)) { + attributes.sourceFile = readSourceFileAttribute(ptr); + } + else if ("ConstantValue".equals(attrName)){ + attributes.constantValue = readFieldConstantValue(ptr); + } + else if ("RuntimeVisibleAnnotations".equals(attrName)) { + attributes.runtimeVisibleAnnotations = readAnnotations(ptr); + } + else if ("RuntimeInvisibleAnnotations".equals(attrName)) { + attributes.runtimeInvisibleAnnotations = readAnnotations(ptr); + } + else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) { + attributes.runtimeVisibleParameterAnnotations = readParameterAnnotations(ptr); + } + else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) { + attributes.runtimeInvisibleParameterAnnotations = readParameterAnnotations(ptr); + } + else if ("AnnotationDefault".equals(attrName)) { + attributes.annotationDefault = readAnnotationMemberValue(new BytePointer(ptr.bytes, ptr.offset + 6)); + } + gotoNextAttribute(ptr); + } + return attributes; + } + + private String readAttributeName(BytePointer p) throws ClsFormatException { + final BytePointer ptr = new BytePointer(p.bytes, p.offset); + final int nameIndex = ClsUtil.readU2(ptr); + ptr.offset = getOffsetInConstantPool(nameIndex); + return ClsUtil.readUtf8Info(ptr); + } + + private void gotoNextAttribute(BytePointer ptr) throws ClsFormatException { + ptr.offset += 2; // skip name index + final int length = ClsUtil.readU4(ptr); // important! Do not inline since ptr.offset is also changed inside ClsUtil.readU4() method + ptr.offset += length; + } + + /** + Signature_attribute { + u2 attribute_name_index; (must be equal to "Signature") + u4 attribute_length; (must be equal to 2) + u2 signature_index; + } + */ + private String readSignatureAttribute(BytePointer p) throws ClsFormatException { + final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length + if (ClsUtil.readU4(ptr) != 2) { + return null; + } + ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + return ClsUtil.readUtf8Info(ptr); + } + + private String[] readExceptions(BytePointer p) throws ClsFormatException{ + final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the count of exceptions + int count = ClsUtil.readU2(ptr); + final ArrayList array = new ArrayList(count); + while (count-- > 0) { + int idx = ClsUtil.readU2(ptr); + if (idx != 0) { + final String exceptionClass = readClassInfo(new BytePointer(ptr.bytes, getOffsetInConstantPool(idx))); + array.add(exceptionClass); + } + } + return array.toArray(new String[array.size()]); + } + + private String readSourceFileAttribute(BytePointer p) throws ClsFormatException { + BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length + if (ClsUtil.readU4(ptr) != 2) { + return null; + } + ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); + String path = ClsUtil.readUtf8Info(ptr); + // jdk version 1.3.0 puts full path to the source, but later versions store only short name + final int slashIndex = path.lastIndexOf('/'); + if (slashIndex >= 0) { + path = path.substring(slashIndex + 1, path.length()); + } + return path; + } + + private ConstantValue readFieldConstantValue(BytePointer p) throws ClsFormatException{ + final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); + if (ClsUtil.readU4(ptr) != 2) { + throw new ClsFormatException(); // attribute length must be 2 + } + int valueIndex = ClsUtil.readU2(ptr); + ptr.offset = getOffsetInConstantPool(valueIndex); + return readConstant(ptr); + } + + private ConstantValue readConstant(final BytePointer ptr) throws ClsFormatException { + final int tag = ClsUtil.readU1(ptr); + switch (tag) { + case ClsUtil.CONSTANT_Integer : + { + int value = ClsUtil.readU4(ptr); + return new IntegerConstantValue(value); + } + case ClsUtil.CONSTANT_Float: + { + float floatValue = ClsUtil.readFloat(ptr); + return new FloatConstantValue(floatValue); + } + case ClsUtil.CONSTANT_Long : + { + int high = ClsUtil.readU4(ptr); + int low = ClsUtil.readU4(ptr); + long v = ((long)high << 32) | (low & 0xFFFFFFFFL); + return new LongConstantValue(v); + } + case ClsUtil.CONSTANT_Double : + { + double doubleValue = ClsUtil.readDouble(ptr); + return new DoubleConstantValue(doubleValue); + } + case ClsUtil.CONSTANT_String : + { + int stringIndex = ClsUtil.readU2(ptr); + ptr.offset = getOffsetInConstantPool(stringIndex); + return new StringConstantValue(ClsUtil.readUtf8Info(ptr)); + } + default : throw new ClsFormatException(); + } + } + + private AnnotationConstantValue[] readAnnotations(BytePointer p) throws ClsFormatException { + final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); + return readAnnotationsArray(ptr); + } + + private AnnotationConstantValue[][] readParameterAnnotations(BytePointer p) throws ClsFormatException { + final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the number of parameters + final int numberOfParams = ClsUtil.readU1(ptr); + if (numberOfParams == 0) { + return null; + } + final AnnotationConstantValue[][] annotations = new AnnotationConstantValue[numberOfParams][]; + for (int parameterIndex = 0; parameterIndex < numberOfParams; parameterIndex++) { + annotations[parameterIndex] = readAnnotationsArray(ptr); + } + return annotations; + } + + private AnnotationConstantValue[] readAnnotationsArray(BytePointer ptr) throws ClsFormatException { + final int numberOfAnnotations = ClsUtil.readU2(ptr); + if (numberOfAnnotations == 0) { + return AnnotationConstantValue.EMPTY_ARRAY; + } + AnnotationConstantValue[] annotations = new AnnotationConstantValue[numberOfAnnotations]; + for (int attributeIndex = 0; attributeIndex < numberOfAnnotations; attributeIndex++) { + annotations[attributeIndex] = readAnnotation(ptr); + } + return annotations; + } + + private AnnotationConstantValue readAnnotation(BytePointer ptr) throws ClsFormatException { + final int classInfoIndex = ClsUtil.readU2(ptr); + final String qName = readAnnotationClassName(new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex))); + final List memberValues = new ArrayList(); + final int numberOfPairs = ClsUtil.readU2(ptr); + for (int idx = 0; idx < numberOfPairs; idx++) { + final int memberNameIndex = ClsUtil.readU2(ptr); + final String memberName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(memberNameIndex)); + final ConstantValue memberValue = readAnnotationMemberValue(ptr); + memberValues.add(new AnnotationNameValuePair(mySymbolTable.getId(memberName), memberValue)); + } + return new AnnotationConstantValue(mySymbolTable.getId(qName), memberValues.toArray(new AnnotationNameValuePair[memberValues.size()])); + } + + private String readAnnotationClassName(BytePointer ptr) throws ClsFormatException { + // TODO: need this method because because of incomplete class format spec at the moment of writing + // it is not clear what structure is expected: CONSTANT_Utf8 or CONSTANT_Class + final int tag = ClsUtil.readU1(ptr); + if (tag == ClsUtil.CONSTANT_Utf8) { + return ClsUtil.getTypeText(ptr.bytes, ptr.offset + 2); //skip length + } + if (tag == ClsUtil.CONSTANT_Class){ + ptr.offset -= 1; // rollback + return readClassInfo(ptr); + } + throw new ClsFormatException("Incorrect tag: " + tag + " expected either ClsUtil.CONSTANT_Utf8(" + ClsUtil.CONSTANT_Utf8 + ") or ClsUtil.CONSTANT_Class(" + ClsUtil.CONSTANT_Class + ")"); + } + + private ConstantValue readAnnotationMemberValue(BytePointer ptr) throws ClsFormatException { + final char tag = (char)ClsUtil.readU1(ptr); + switch (tag) { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': { + final int valueIndex = ClsUtil.readU2(ptr); + return new AnnotationPrimitiveConstantValue(tag, readConstant(new BytePointer(ptr.bytes, getOffsetInConstantPool(valueIndex)))); + } + case 's': { + final int valueIndex = ClsUtil.readU2(ptr); + return new StringConstantValue(ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(valueIndex))); + } + case 'e': { + final int typeNameIndex = ClsUtil.readU2(ptr); + final int constantNameIndex = ClsUtil.readU2(ptr); + final String typeName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(typeNameIndex)); + final String constantName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(constantNameIndex)); + return new EnumConstantValue(mySymbolTable.getId(typeName), mySymbolTable.getId(constantName)); + } + case 'c' : { + final int classInfoIndex = ClsUtil.readU2(ptr); + BytePointer p = new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex)); + final int recordTag = ClsUtil.readU1(p); + if (recordTag != ClsUtil.CONSTANT_Utf8) { + throw new ClsFormatException("Wrong record tag: " + recordTag + "; expected: " + ClsUtil.CONSTANT_Utf8); + } + p.offset += 2; //Skip length + final String className = ClsUtil.getTypeText(p.bytes, p.offset); + return new ClassInfoConstantValue(mySymbolTable.getId(className)); + } + case '@' : { + return readAnnotation(ptr); + } + case '[' : { + final int numberOfValues = ClsUtil.readU2(ptr); + final ConstantValue[] values = new ConstantValue[numberOfValues]; + for (int idx = 0; idx < numberOfValues; idx++) { + values[idx] = readAnnotationMemberValue(ptr); + } + return new ConstantValueArray(values); + } + default : throw new ClsFormatException("Wrong tag for annotation member value: " + tag); + } + } + + private static class ClsAttributeTable { + public String[] exceptions; + public String genericSignature; + public String sourceFile; + public ConstantValue constantValue; + public AnnotationConstantValue[] runtimeVisibleAnnotations; + public AnnotationConstantValue[] runtimeInvisibleAnnotations; + public AnnotationConstantValue[][] runtimeVisibleParameterAnnotations; + public AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations; + public ConstantValue annotationDefault; + } + + private static class ConstantPoolIterator { + private BytePointer myPtr; + private int myEntryCount; + private int myCurrentEntryIndex; + private int myCurrentOffset; + + public ConstantPoolIterator(BytePointer ptr) throws ClsFormatException { + myPtr = ptr; + myPtr.offset = 0; + int magic = ClsUtil.readU4(myPtr); + if (magic != ClsUtil.MAGIC){ + throw new ClsFormatException(); + } + myPtr.offset += 2; // minor version + myPtr.offset += 2; // major version + myEntryCount = ClsUtil.readU2(myPtr); + if (myEntryCount < 1){ + throw new ClsFormatException(); + } + myCurrentEntryIndex = 1; // Entry at index 0 is included in the count but is not present in the constant pool + myCurrentOffset = myPtr.offset; + } + + public int getEntryCount() { + return myEntryCount; + } + + public int getCurrentOffset() { + return myCurrentOffset; + } + + /** + * tests if there are unread entries + */ + public boolean hasMoreEntries() { + return myCurrentEntryIndex < myEntryCount; + } + + /** + * Positions the pointer to the next entry + */ + public void next() throws ClsFormatException { + myPtr.offset = myCurrentOffset; + int tag = ClsUtil.readU1(myPtr); + switch(tag){ + default: + throw new ClsFormatException(); + + case ClsUtil.CONSTANT_Class: + case ClsUtil.CONSTANT_String: + myPtr.offset += 2; + break; + + case ClsUtil.CONSTANT_Fieldref: + case ClsUtil.CONSTANT_Methodref: + case ClsUtil.CONSTANT_InterfaceMethodref: + case ClsUtil.CONSTANT_Integer: + case ClsUtil.CONSTANT_Float: + case ClsUtil.CONSTANT_NameAndType: + myPtr.offset += 4; + break; + + case ClsUtil.CONSTANT_Long: + case ClsUtil.CONSTANT_Double: + myPtr.offset += 8; + myCurrentEntryIndex++; // takes 2 entries + break; + + case ClsUtil.CONSTANT_Utf8: + int length = ClsUtil.readU2(myPtr); + myPtr.offset += length; + break; + } + myCurrentEntryIndex++; + myCurrentOffset = myPtr.offset; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassInfoConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassInfoConstantValue.java new file mode 100644 index 00000000000..ba4a435f8a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ClassInfoConstantValue.java @@ -0,0 +1,41 @@ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class ClassInfoConstantValue extends ConstantValue{ + private final int myValue; + + public ClassInfoConstantValue(int value) { + myValue = value; + } + + public ClassInfoConstantValue(DataInput in) throws IOException{ + myValue = in.readInt(); + } + + public int getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeInt(myValue); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClassInfoConstantValue)) return false; + + final ClassInfoConstantValue classInfoConstantValue = (ClassInfoConstantValue)o; + + if (myValue != classInfoConstantValue.myValue) return false; + + return true; + } + + public int hashCode() { + return myValue; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValue.java new file mode 100644 index 00000000000..283411a1714 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValue.java @@ -0,0 +1,19 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataOutput; +import java.io.IOException; + +public class ConstantValue { + public static final ConstantValue EMPTY_CONSTANT_VALUE = new ConstantValue(); + + protected ConstantValue() { + } + + public void save(DataOutput out) throws IOException { + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValueArray.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValueArray.java new file mode 100644 index 00000000000..42e951bb75e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ConstantValueArray.java @@ -0,0 +1,53 @@ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +/** + * @author Eugene Zhuravlev + * Date: Apr 2, 2004 + */ +public class ConstantValueArray extends ConstantValue{ + private final ConstantValue[] myValue; + + public ConstantValueArray(ConstantValue[] value) { + myValue = value; + } + + public ConstantValueArray(DataInput in) throws IOException { + final int size = in.readInt(); + myValue = new ConstantValue[size]; + for (int idx = 0; idx < size; idx++) { + myValue[idx] = MemberInfoExternalizer.loadConstantValue(in); + } + } + + public ConstantValue[] getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + out.writeInt(myValue.length); + for (int idx = 0; idx < myValue.length; idx++) { + MemberInfoExternalizer.saveConstantValue(out, myValue[idx]); + } + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ConstantValueArray)) return false; + + final ConstantValueArray constantValueArray = (ConstantValueArray)o; + + if (!Arrays.equals(myValue, constantValueArray.myValue)) return false; + + return true; + } + + public int hashCode() { + return 0; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/DoubleConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/DoubleConstantValue.java new file mode 100644 index 00000000000..8364ba5e8b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/DoubleConstantValue.java @@ -0,0 +1,34 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class DoubleConstantValue extends ConstantValue{ + private final double myValue; + + public DoubleConstantValue(double value) { + myValue = value; + } + + public DoubleConstantValue(DataInput in) throws IOException{ + myValue = in.readDouble(); + } + + public double getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeDouble(myValue); + } + + public boolean equals(Object obj) { + return (obj instanceof DoubleConstantValue) && (((DoubleConstantValue)obj).myValue == myValue); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/EnumConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/EnumConstantValue.java new file mode 100644 index 00000000000..3802a2f8acb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/EnumConstantValue.java @@ -0,0 +1,57 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class EnumConstantValue extends ConstantValue{ + private final int myTypeName; + private final int myConstantName; + + public EnumConstantValue(int typeName, int constantName) { + myTypeName = typeName; + myConstantName = constantName; + } + + public EnumConstantValue(DataInput in) throws IOException{ + myTypeName = in.readInt(); + myConstantName = in.readInt(); + } + + public int getTypeName() { + return myTypeName; + } + + public int getConstantName() { + return myConstantName; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeInt(myTypeName); + out.writeInt(myConstantName); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof EnumConstantValue)) return false; + + final EnumConstantValue enumConstantValue = (EnumConstantValue)o; + + if (myConstantName != enumConstantValue.myConstantName) return false; + if (myTypeName != enumConstantValue.myTypeName) return false; + + return true; + } + + public int hashCode() { + int result; + result = myTypeName; + result = 29 * result + myConstantName; + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FieldInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FieldInfo.java new file mode 100644 index 00000000000..b4c060dcfb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FieldInfo.java @@ -0,0 +1,39 @@ +/** + * created at Jan 10, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class FieldInfo extends MemberInfo { + public static final FieldInfo[] EMPTY_ARRAY = new FieldInfo[0]; + private final ConstantValue myConstantValue; + + public FieldInfo(int name, int descriptor) { + super(name, descriptor); + myConstantValue = ConstantValue.EMPTY_CONSTANT_VALUE; + } + + public FieldInfo(int name, int descriptor, final int genericSignature, int flags, ConstantValue value, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) { + super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations); + myConstantValue = (value != null)? value : ConstantValue.EMPTY_CONSTANT_VALUE; + } + + public FieldInfo(DataInput in) throws IOException { + super(in); + myConstantValue = MemberInfoExternalizer.loadConstantValue(in); + } + + public ConstantValue getConstantValue() { + return myConstantValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + MemberInfoExternalizer.saveConstantValue(out, myConstantValue); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FloatConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FloatConstantValue.java new file mode 100644 index 00000000000..fbc901bfac1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/FloatConstantValue.java @@ -0,0 +1,34 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class FloatConstantValue extends ConstantValue{ + private final float myValue; + + public FloatConstantValue(float value) { + myValue = value; + } + + public FloatConstantValue(DataInput in) throws IOException{ + myValue = in.readFloat(); + } + + public float getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeFloat(myValue); + } + + public boolean equals(Object obj) { + return (obj instanceof FloatConstantValue) && (((FloatConstantValue)obj).myValue == myValue); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/GenericMethodSignature.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/GenericMethodSignature.java new file mode 100644 index 00000000000..3e2c79ac663 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/GenericMethodSignature.java @@ -0,0 +1,82 @@ +package com.intellij.compiler.classParsing; + +import com.intellij.util.ArrayUtil; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 4, 2004 + */ +public class GenericMethodSignature { + private final String myFormalTypeParams; + private final String[] myParamSignatures; + private final String myReturnTypeSignature; + private final String myThrowsSignature; + + private GenericMethodSignature(String formalTypeParams, String[] paramSignatures, String returnTypeSignature, String throwsSignature) { + myFormalTypeParams = formalTypeParams; + myParamSignatures = paramSignatures; + myReturnTypeSignature = returnTypeSignature; + myThrowsSignature = throwsSignature; + } + + public String getFormalTypeParams() { + return myFormalTypeParams; + } + + public String[] getParamSignatures() { + return myParamSignatures; + } + + public String getReturnTypeSignature() { + return myReturnTypeSignature; + } + + public String getThrowsSignature() { + return myThrowsSignature; + } + + public static GenericMethodSignature parse(String methodSignature) throws SignatureParsingException { + final StringCharacterIterator it = new StringCharacterIterator(methodSignature); + + final StringBuffer formals = new StringBuffer(); + if (it.current() == '<') { + SignatureParser.INSTANCE.parseFormalTypeParameters(it, formals); + } + + if (it.current() != '(') { + throw new SignatureParsingException("'(' expected"); + } + + it.next(); // skip '(' + + final String[] paramSignatures; + if (it.current() != ')') { + final List params = new ArrayList(); + while (it.current() != ')') { + final StringBuffer typeSignature = new StringBuffer(); + SignatureParser.INSTANCE.parseTypeSignature(it, typeSignature); + params.add(typeSignature.toString()); + } + paramSignatures = params.toArray(new String[params.size()]); + } + else { + paramSignatures = ArrayUtil.EMPTY_STRING_ARRAY; + } + it.next(); // skip ')' + + final StringBuffer returnTypeSignature = new StringBuffer(); + SignatureParser.INSTANCE.parseReturnType(it, returnTypeSignature); + + final StringBuffer throwsSignature = new StringBuffer(); + if (it.current() != CharacterIterator.DONE) { + SignatureParser.INSTANCE.parseThrowsSignature(it, throwsSignature); + } + + return new GenericMethodSignature(formals.toString(), paramSignatures, returnTypeSignature.toString(), throwsSignature.toString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/IntegerConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/IntegerConstantValue.java new file mode 100644 index 00000000000..e6a5d9e6253 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/IntegerConstantValue.java @@ -0,0 +1,34 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IntegerConstantValue extends ConstantValue{ + private final int myValue; + + public IntegerConstantValue(int value) { + myValue = value; + } + + public IntegerConstantValue(DataInput in) throws IOException{ + myValue = in.readInt(); + } + + public int getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeInt(myValue); + } + + public boolean equals(Object obj) { + return (obj instanceof IntegerConstantValue) && (((IntegerConstantValue)obj).myValue == myValue); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/LongConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/LongConstantValue.java new file mode 100644 index 00000000000..18020f401e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/LongConstantValue.java @@ -0,0 +1,33 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class LongConstantValue extends ConstantValue{ + private final long myValue; + + public LongConstantValue(long value) { + myValue = value; + } + public LongConstantValue(DataInput in) throws IOException{ + myValue = in.readLong(); + } + + public long getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeLong(myValue); + } + + public boolean equals(Object obj) { + return (obj instanceof LongConstantValue) && (((LongConstantValue)obj).myValue == myValue); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfo.java new file mode 100644 index 00000000000..326ae2cef18 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfo.java @@ -0,0 +1,136 @@ +/** + * created at Jan 8, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import com.intellij.util.cls.ClsUtil; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public abstract class MemberInfo { + public static final MemberInfo[] EMPTY_MEMBER_INFO_ARRAY = new MemberInfo[0]; + private static final int FLAG_INFO_UNAVAILABLE = 0x8000; + private final int myName; + private final int myDescriptor; + private final int myGenericSignature; + private final int myFlags; + private final AnnotationConstantValue[] myRuntimeVisibleAnnotations; + private final AnnotationConstantValue[] myRuntimeInvisibleAnnotations; + + protected MemberInfo(int name, int descriptor) { + this(name, descriptor, -1, FLAG_INFO_UNAVAILABLE, AnnotationConstantValue.EMPTY_ARRAY, AnnotationConstantValue.EMPTY_ARRAY); + } + + protected MemberInfo(int name, int descriptor, int genericSignature, int flags, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) { + myDescriptor = descriptor; + myGenericSignature = genericSignature; + myName = name; + myFlags = flags; + myRuntimeVisibleAnnotations = runtimeVisibleAnnotations != null? runtimeVisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY; + myRuntimeInvisibleAnnotations = runtimeInvisibleAnnotations != null? runtimeInvisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY; + } + + protected MemberInfo(DataInput in) throws IOException { + myName = in.readInt(); + myDescriptor = in.readInt(); + myGenericSignature = in.readInt(); + myFlags = in.readInt(); + myRuntimeVisibleAnnotations = loadAnnotations(in); + myRuntimeInvisibleAnnotations = loadAnnotations(in); + } + + public void save(DataOutput out) throws IOException { + out.writeInt(myName); + out.writeInt(myDescriptor); + out.writeInt(myGenericSignature); + out.writeInt(myFlags); + saveAnnotations(out, myRuntimeVisibleAnnotations); + saveAnnotations(out, myRuntimeInvisibleAnnotations); + } + + public int getName() { + return myName; + } + + public int getDescriptor() { + return myDescriptor; + } + + public int getGenericSignature() { + return myGenericSignature; + } + + public boolean isFlagInfoAvailable() { + return myFlags != FLAG_INFO_UNAVAILABLE; + } + + public int getFlags() { + return myFlags; + } + + public boolean isPublic() { + return ClsUtil.isPublic(myFlags); + } + + public boolean isProtected() { + return ClsUtil.isProtected(myFlags); + } + + public boolean isFinal() { + return ClsUtil.isFinal(myFlags); + } + + public boolean isPrivate() { + return ClsUtil.isPrivate(myFlags); + } + + public boolean isPackageLocal() { + return ClsUtil.isPackageLocal(myFlags); + } + + public boolean isStatic() { + return ClsUtil.isStatic(myFlags); + } + + public boolean equals(Object obj) { + if (!(obj instanceof MemberInfo)) return false; + MemberInfo info = (MemberInfo)obj; + return (myName == info.myName) && (myDescriptor == info.myDescriptor); + } + + public int hashCode() { + return myName + myDescriptor; + } + + public AnnotationConstantValue[] getRuntimeVisibleAnnotations() { + return myRuntimeVisibleAnnotations; + } + + public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() { + return myRuntimeInvisibleAnnotations; + } + + protected final void saveAnnotations(DataOutput out, final AnnotationConstantValue[] annotations) throws IOException { + out.writeInt(annotations.length); + for (int idx = 0; idx < annotations.length; idx++) { + MemberInfoExternalizer.saveConstantValue(out, annotations[idx]); + } + } + + protected final AnnotationConstantValue[] loadAnnotations(DataInput in) throws IOException { + final int size = in.readInt(); + if (size == 0) { + return AnnotationConstantValue.EMPTY_ARRAY; + } + final AnnotationConstantValue[] annotations = new AnnotationConstantValue[size]; + for (int idx = 0; idx < size; idx++) { + annotations[idx] = (AnnotationConstantValue)MemberInfoExternalizer.loadConstantValue(in); + } + return annotations; + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfoExternalizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfoExternalizer.java new file mode 100644 index 00000000000..131cb95d160 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberInfoExternalizer.java @@ -0,0 +1,176 @@ +/** + * created at Jan 10, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class MemberInfoExternalizer { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MemberInfoExternalizer"); + + public static final byte FIELD_INFO_TAG = 1; + public static final byte METHOD_INFO_TAG = 2; + + public static final byte DECLARATION_INFO_TAG = 9; + public static final byte MEMBER_DECLARATION_INFO_TAG = 10; + + public static final byte REFERENCE_INFO_TAG = 11; + public static final byte MEMBER_REFERENCE_INFO_TAG = 12; + + public static final byte LONG_CONSTANT_TAG = 3; + public static final byte FLOAT_CONSTANT_TAG = 4; + public static final byte DOUBLE_CONSTANT_TAG = 5; + public static final byte INTEGER_CONSTANT_TAG = 6; + public static final byte STRING_CONSTANT_TAG = 7; + public static final byte CONSTANT_TAG = 8; + public static final byte ANNOTATION_CONSTANT_TAG = 13; + public static final byte ANNOTATION_PRIMITIVE_CONSTANT_TAG = 14; + public static final byte CONSTANT_VALUE_ARRAY_TAG = 15; + public static final byte CLASS_CONSTANT_VALUE_TAG = 16; + public static final byte ENUM_CONSTANT_VALUE_TAG = 17; + + public static MemberInfo loadMemberInfo(DataInput in) throws IOException { + byte tag = in.readByte(); + if (tag == METHOD_INFO_TAG) { + return new MethodInfo(in); + } + else if (tag == FIELD_INFO_TAG) { + return new FieldInfo(in); + } + LOG.assertTrue(false, "Unknown member info"); + return null; + } + + public static ItemInfo loadItemInfo(DataInput in) throws IOException { + byte tag = in.readByte(); + if (tag == DECLARATION_INFO_TAG) { + return new DeclarationInfo(in); + } + else if (tag == MEMBER_DECLARATION_INFO_TAG) { + return new MemberDeclarationInfo(in); + } + else if (tag == REFERENCE_INFO_TAG) { + return new ReferenceInfo(in); + } + else if (tag == MEMBER_REFERENCE_INFO_TAG) { + return new MemberReferenceInfo(in); + } + LOG.assertTrue(false, "Unknown declaration info tag: " + tag); + return null; + } + + public static ConstantValue loadConstantValue(DataInput in) throws IOException { + byte tag = in.readByte(); + if (tag == LONG_CONSTANT_TAG) { + return new LongConstantValue(in); + } + else if (tag == FLOAT_CONSTANT_TAG) { + return new FloatConstantValue(in); + } + else if (tag == DOUBLE_CONSTANT_TAG) { + return new DoubleConstantValue(in); + } + else if (tag == INTEGER_CONSTANT_TAG) { + return new IntegerConstantValue(in); + } + else if (tag == STRING_CONSTANT_TAG) { + return new StringConstantValue(in); + } + else if (tag == CONSTANT_TAG) { + return ConstantValue.EMPTY_CONSTANT_VALUE; + } + else if (tag == ANNOTATION_CONSTANT_TAG) { + return new AnnotationConstantValue(in); + } + else if (tag == ANNOTATION_PRIMITIVE_CONSTANT_TAG) { + return new AnnotationPrimitiveConstantValue(in); + } + else if (tag == CONSTANT_VALUE_ARRAY_TAG) { + return new ConstantValueArray(in); + } + else if (tag == CLASS_CONSTANT_VALUE_TAG) { + return new ClassInfoConstantValue(in); + } + else if (tag == ENUM_CONSTANT_VALUE_TAG) { + return new EnumConstantValue(in); + } + LOG.assertTrue(false, "Unknown constant value type " + tag); + return null; + } + + public static void saveMemberInfo(DataOutput out, MemberInfo info) throws IOException { + if (info instanceof MethodInfo) { + out.writeByte(METHOD_INFO_TAG); + } + else if (info instanceof FieldInfo){ + out.writeByte(FIELD_INFO_TAG); + } + else { + LOG.assertTrue(false, "Unknown member info"); + } + info.save(out); + } + + public static void saveItemInfo(DataOutput out, ItemInfo info) throws IOException { + if (info instanceof MemberDeclarationInfo) { + out.writeByte(MEMBER_DECLARATION_INFO_TAG); + } + else if (info instanceof MemberReferenceInfo) { + out.writeByte(MEMBER_REFERENCE_INFO_TAG); + } + else if (info instanceof DeclarationInfo){ + out.writeByte(DECLARATION_INFO_TAG); + } + else if (info instanceof ReferenceInfo){ + out.writeByte(REFERENCE_INFO_TAG); + } + else { + LOG.error("Unknown info type: " + info.getClass().getName()); + } + info.save(out); + } + + public static void saveConstantValue(DataOutput out, ConstantValue value) throws IOException { + if (value instanceof LongConstantValue) { + out.writeByte(LONG_CONSTANT_TAG); + } + else if (value instanceof FloatConstantValue){ + out.writeByte(FLOAT_CONSTANT_TAG); + } + else if (value instanceof DoubleConstantValue){ + out.writeByte(DOUBLE_CONSTANT_TAG); + } + else if (value instanceof IntegerConstantValue){ + out.writeByte(INTEGER_CONSTANT_TAG); + } + else if (value instanceof StringConstantValue){ + out.writeByte(STRING_CONSTANT_TAG); + } + else if (value instanceof AnnotationConstantValue) { + out.write(ANNOTATION_CONSTANT_TAG); + } + else if (value instanceof AnnotationPrimitiveConstantValue) { + out.write(ANNOTATION_PRIMITIVE_CONSTANT_TAG); + } + else if (value instanceof ConstantValueArray) { + out.write(CONSTANT_VALUE_ARRAY_TAG); + } + else if (value instanceof ClassInfoConstantValue) { + out.write(CLASS_CONSTANT_VALUE_TAG); + } + else if (value instanceof EnumConstantValue) { + out.write(ENUM_CONSTANT_VALUE_TAG); + } + else { + out.writeByte(CONSTANT_TAG); + } + if (value != null) { + value.save(out); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberReferenceInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberReferenceInfo.java new file mode 100644 index 00000000000..3cd10c56004 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MemberReferenceInfo.java @@ -0,0 +1,55 @@ +/** + * created at Jan 8, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class MemberReferenceInfo extends ReferenceInfo { + private final MemberInfo myMemberInfo; + + public MemberReferenceInfo(int declaringClass, MemberInfo memberInfo) { + super(declaringClass); + myMemberInfo = memberInfo; + } + + public MemberReferenceInfo(DataInput in) throws IOException { + super(in); + myMemberInfo = MemberInfoExternalizer.loadMemberInfo(in); + } + + public MemberInfo getMemberInfo() { + return myMemberInfo; + } + + public boolean isFieldReference() { + return myMemberInfo instanceof FieldInfo; + } + + public boolean isMethodReference() { + return myMemberInfo instanceof MethodInfo; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + MemberInfoExternalizer.saveMemberInfo(out, myMemberInfo); + } + + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + return myMemberInfo.equals(((MemberReferenceInfo)o).myMemberInfo); + } + + public int hashCode() { + return super.hashCode() + myMemberInfo.hashCode(); + } + + public String toString() { + return "Member reference: [class name=" + getClassName() + ", member name = " + myMemberInfo.getName() + ", member descriptor=" + myMemberInfo.getDescriptor() + ", member signature=" + myMemberInfo.getGenericSignature() + "]"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MethodInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MethodInfo.java new file mode 100644 index 00000000000..27f176ca80e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/MethodInfo.java @@ -0,0 +1,248 @@ +/** + * created at Jan 10, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import com.intellij.compiler.SymbolTable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.cls.ClsUtil; +import gnu.trove.TIntHashSet; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; + +public class MethodInfo extends MemberInfo { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MethodInfo"); + + private static final int[] EMPTY_INT_ARRAY = new int[0]; + private static final int[] EXCEPTION_INFO_UNAVAILABLE = new int[0]; + public static final MethodInfo[] EMPTY_ARRAY = new MethodInfo[0]; + + private final int[] myThrownExceptions; + // cached (lazy initialized) data + private String mySignature = null; + private String[] myParameterDescriptors = null; + private String myReturnTypeSignature = null; + private final boolean myIsConstructor; + private final AnnotationConstantValue[][] myRuntimeVisibleParameterAnnotations; + private final AnnotationConstantValue[][] myRuntimeInvisibleParameterAnnotations; + private final ConstantValue myAnnotationDefault; + + public MethodInfo(int name, int descriptor, boolean isConstructor) { + super(name, descriptor); + myIsConstructor = isConstructor; + myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE; + myRuntimeVisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY; + myRuntimeInvisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY; + myAnnotationDefault = ConstantValue.EMPTY_CONSTANT_VALUE; + } + + public MethodInfo(int name, + int descriptor, + final int genericSignature, + int flags, + int[] exceptions, + boolean isConstructor, + final AnnotationConstantValue[] runtimeVisibleAnnotations, + final AnnotationConstantValue[] runtimeInvisibleAnnotations, + final AnnotationConstantValue[][] runtimeVisibleParameterAnnotations, + final AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations, ConstantValue annotationDefault) { + + super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations); + myThrownExceptions = exceptions != null? exceptions : EMPTY_INT_ARRAY; + myIsConstructor = isConstructor; + myRuntimeVisibleParameterAnnotations = runtimeVisibleParameterAnnotations; // todo: pass as parameter + myRuntimeInvisibleParameterAnnotations = runtimeInvisibleParameterAnnotations; + myAnnotationDefault = annotationDefault; + } + + public MethodInfo(DataInput in) throws IOException { + super(in); + myIsConstructor = in.readBoolean(); + int count = in.readInt(); + if (count == -1) { + myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE; + } + else if (count == 0) { + myThrownExceptions = EMPTY_INT_ARRAY; + } + else { + myThrownExceptions = new int[count]; + for (int idx = 0; idx < count; idx++) { + myThrownExceptions[idx] = in.readInt(); + } + } + myRuntimeVisibleParameterAnnotations = loadParameterAnnotations(in); + myRuntimeInvisibleParameterAnnotations = loadParameterAnnotations(in); + myAnnotationDefault = MemberInfoExternalizer.loadConstantValue(in); + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeBoolean(myIsConstructor); + if (isExceptionInfoAvailable()) { + out.writeInt(myThrownExceptions.length); + } + else { + out.writeInt(-1); + } + for (int idx = 0; idx < myThrownExceptions.length; idx++) { + out.writeInt(myThrownExceptions[idx]); + } + saveParameterAnnotations(out, myRuntimeVisibleParameterAnnotations); + saveParameterAnnotations(out, myRuntimeInvisibleParameterAnnotations); + MemberInfoExternalizer.saveConstantValue(out, myAnnotationDefault); + } + + private boolean isExceptionInfoAvailable() { + return myThrownExceptions != EXCEPTION_INFO_UNAVAILABLE; + } + + public boolean areExceptionsEqual(MethodInfo info) { + if (myThrownExceptions.length != info.myThrownExceptions.length) { + return false; + } + if (myThrownExceptions.length != 0) { // optimization + TIntHashSet exceptionsSet = new TIntHashSet(); + for (int idx = 0; idx < myThrownExceptions.length; idx++) { + exceptionsSet.add(myThrownExceptions[idx]); + } + for (int idx = 0; idx < info.myThrownExceptions.length; idx++) { + int exception = info.myThrownExceptions[idx]; + if (!exceptionsSet.contains(exception)) { + return false; + } + } + } + return true; + } + + public int[] getThrownExceptions() { + return myThrownExceptions; + } + + public String getDescriptor(SymbolTable symbolTable) { + if (mySignature == null) { + String descriptor = symbolTable.getSymbol(getDescriptor()); + String name = symbolTable.getSymbol(getName()); + mySignature = name + descriptor.substring(0, descriptor.indexOf(')') + 1); + } + return mySignature; + } + + public String getReturnTypeDescriptor(SymbolTable symbolTable) { + if (myReturnTypeSignature == null) { + String descriptor = symbolTable.getSymbol(getDescriptor()); + myReturnTypeSignature = descriptor.substring(descriptor.indexOf(')') + 1, descriptor.length()); + } + return myReturnTypeSignature; + } + + public String[] getParameterDescriptors(SymbolTable symbolTable) { + if (myParameterDescriptors == null) { + String descriptor = symbolTable.getSymbol(getDescriptor()); + int endIndex = descriptor.indexOf(')'); + if (endIndex <= 0) { + LOG.assertTrue(false, "Corrupted method descriptor: "+descriptor); + } + myParameterDescriptors = parseParameterDescriptors(descriptor.substring(1, endIndex)); + } + return myParameterDescriptors; + } + + public boolean isAbstract() { + return ClsUtil.isAbstract(getFlags()); + } + + public boolean isConstructor() { + return myIsConstructor; + } + + private String[] parseParameterDescriptors(String signature) { + ArrayList list = new ArrayList(); + String paramSignature = parseFieldType(signature); + while (paramSignature != null && !"".equals(paramSignature)) { + list.add(paramSignature); + signature = signature.substring(paramSignature.length()); + paramSignature = parseFieldType(signature); + } + return (String[])list.toArray(new String[list.size()]); + } + + private String parseFieldType(String signature) { + if (signature.length() == 0) { + return null; + } + if (signature.charAt(0) == 'B') { + return "B"; + } + if (signature.charAt(0) == 'C') { + return "C"; + } + if (signature.charAt(0) == 'D') { + return "D"; + } + if (signature.charAt(0) == 'F') { + return "F"; + } + if (signature.charAt(0) == 'I') { + return "I"; + } + if (signature.charAt(0) == 'J') { + return "J"; + } + if (signature.charAt(0) == 'S') { + return "S"; + } + if (signature.charAt(0) == 'Z') { + return "Z"; + } + if (signature.charAt(0) == 'L') { + return signature.substring(0, signature.indexOf(";") + 1); + } + if (signature.charAt(0) == '[') { + String s = parseFieldType(signature.substring(1)); + return (s != null)? ("[" + s) : null; + } + return null; + } + + public AnnotationConstantValue[][] getRuntimeVisibleParameterAnnotations() { + return myRuntimeVisibleParameterAnnotations; + } + + public AnnotationConstantValue[][] getRuntimeInvisibleParameterAnnotations() { + return myRuntimeInvisibleParameterAnnotations; + } + + public String toString() { + return mySignature; + } + + private AnnotationConstantValue[][] loadParameterAnnotations(DataInput in) throws IOException { + final int size = in.readInt(); + if (size == 0) { + return AnnotationConstantValue.EMPTY_ARRAY_ARRAY; + } + final AnnotationConstantValue[][] paramAnnotations = new AnnotationConstantValue[size][]; + for (int idx = 0; idx < size; idx++) { + paramAnnotations[idx] = loadAnnotations(in); + } + return paramAnnotations; + } + + private void saveParameterAnnotations(DataOutput out, AnnotationConstantValue[][] parameterAnnotations) throws IOException { + out.writeInt(parameterAnnotations.length); + for (int idx = 0; idx < parameterAnnotations.length; idx++) { + saveAnnotations(out, parameterAnnotations[idx]); + } + } + + public ConstantValue getAnnotationDefault() { + return myAnnotationDefault; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ReferenceInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ReferenceInfo.java new file mode 100644 index 00000000000..d6454db674c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/ReferenceInfo.java @@ -0,0 +1,24 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.IOException; + +public class ReferenceInfo extends ItemInfo { + + public static final ReferenceInfo[] EMPTY_ARRAY = new ReferenceInfo[0]; + + public ReferenceInfo(int declaringClassName) { + super(declaringClassName); + } + + public ReferenceInfo(DataInput in) throws IOException { + super(in); + } + + public String toString() { + return "Class reference[class name=" + String.valueOf(getClassName()) + "]"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParser.java new file mode 100644 index 00000000000..bbde8a1233c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParser.java @@ -0,0 +1,237 @@ +package com.intellij.compiler.classParsing; + +import java.text.CharacterIterator; + +/** + * @author Eugene Zhuravlev + * Date: Mar 4, 2004 + */ + +public class SignatureParser { + public static final SignatureParser INSTANCE = new SignatureParser(); + + public void parseIdentifier(CharacterIterator it, final StringBuffer buf) { + while (Character.isJavaIdentifierPart(it.current())) { + buf.append(it.current()); + it.next(); + } + } + + public void parseFormalTypeParameters(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() != '<') { + throw new SignatureParsingException("'<' expected"); + } + + buf.append(it.current()); // skip '<' + it.next(); + + while (it.current() != '>') { + parseFormalTypeParameter(it, buf); + } + + buf.append(it.current()); + it.next(); + } + + public void parseFormalTypeParameter(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + parseIdentifier(it, buf); + parseClassBound(it, buf); + final char current = it.current(); + if (current != CharacterIterator.DONE && current != '>') { + parseInterfaceBound(it, buf); + } + } + + public void parseClassBound(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() != ':') { + throw new SignatureParsingException("':' expected"); + } + buf.append(it.current()); + it.next(); + + final char current = it.current(); + if (current != CharacterIterator.DONE && current != ':') { + parseFieldTypeSignature(it, buf); + } + } + + public void parseInterfaceBound(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() != ':') { + throw new SignatureParsingException("':' expected"); + } + buf.append(it.current()); + it.next(); + parseFieldTypeSignature(it, buf); + } + + public void parseSuperclassSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + parseClassTypeSignature(it, buf); + } + + public void parseSuperinterfaceSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + parseClassTypeSignature(it, buf); + } + + public void parseFieldTypeSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() == 'L') { + parseClassTypeSignature(it, buf); + } + else if (it.current() == '[') { + parseArrayTypeSignature(it, buf); + } + else if (it.current() == 'T') { + parseTypeVariableSignature(it, buf); + } + else { + throw new SignatureParsingException("Expected either 'L' or '[' or 'T': " + buf.toString()); + } + } + + public void parseClassTypeSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + buf.append(it.current()); + it.next(); // consume 'L' + parseSimpleClassTypeSignature(it, buf); + while (it.current() == '/') { + parseClassTypeSignatureSuffix(it, buf); + } + if (it.current() != ';') { + throw new SignatureParsingException("';' expected: " + buf.toString()); + } + buf.append(it.current()); + it.next(); // consume ';' + } + + public void parseSimpleClassTypeSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + parseIdentifier(it, buf); + if (it.current() == '<') { + parseTypeArguments(it, buf); + } + } + + public void parseClassTypeSignatureSuffix(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + buf.append(it.current()); + it.next(); + parseSimpleClassTypeSignature(it, buf); + } + + public void parseTypeVariableSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + buf.append(it.current()); + it.next(); // consume 'T' + parseIdentifier(it, buf); + if (it.current() != ';') { + throw new SignatureParsingException("';' expected"); + } + buf.append(it.current()); + it.next(); // consume ';' + } + + public void parseTypeArguments(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + buf.append(it.current()); + it.next(); // consume '<' + while (it.current() != '>') { + parseTypeArgument(it, buf); + } + buf.append(it.current()); + it.next(); // consume '>' + } + + public void parseTypeArgument(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() == '+' || it.current() == '-') { + parseWildcardIndicator(it, buf); + } + parseFieldTypeSignature(it, buf); + } + + public void parseWildcardIndicator(CharacterIterator it, final StringBuffer buf) { + buf.append(it.current()); + it.next(); + } + + public void parseArrayTypeSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + buf.append(it.current()); + it.next(); // consume '[' + parseTypeSignature(it, buf); + } + + public void parseTypeSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + char current = it.current(); + if (current == 'B' || current == 'C' || current == 'D' || current == 'F' || current == 'I' || current == 'J' || current == 'S' || current == 'Z') { + buf.append(it.current()); + it.next(); // base type + } + else if (current == 'L' || current == '[' || current == 'T') { + parseFieldTypeSignature(it, buf); + } + else { + throw new SignatureParsingException("Unknown type signature"); + } + } + + public void parseReturnType(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() == 'V') { + buf.append(it.current()); + it.next(); + } + else { + parseTypeSignature(it, buf); + } + } + + public void parseThrowsSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() != '^') { + throw new SignatureParsingException("'^' expected"); + } + buf.append(it.current()); + it.next(); + if (it.current() == 'T') { + parseTypeVariableSignature(it, buf); + } + else { + parseClassTypeSignature(it, buf); + } + } + + public void parseMethodSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() == '<') { + parseFormalTypeParameters(it, buf); + } + + if (it.current() != '(') { + throw new SignatureParsingException("'(' expected"); + } + + buf.append(it.current()); + it.next(); // skip '(' + + while (it.current() != ')') { + parseTypeSignature(it, buf); + } + + buf.append(it.current()); + it.next(); // skip ')' + + parseReturnType(it, buf); + + if (it.current() != CharacterIterator.DONE) { + parseThrowsSignature(it, buf); + } + } + + public void parseClassSignature(CharacterIterator it, final StringBuffer buf) throws SignatureParsingException { + if (it.current() == '<') { + buf.append(it.current()); + it.next(); + while (it.current() != '>') { + parseFormalTypeParameter(it, buf); + } + buf.append(it.current()); + it.next(); + } + + parseClassTypeSignature(it, buf); + + while (it.current() != CharacterIterator.DONE) { + parseClassTypeSignature(it, buf); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParsingException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParsingException.java new file mode 100644 index 00000000000..253c7f4145c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/SignatureParsingException.java @@ -0,0 +1,11 @@ +package com.intellij.compiler.classParsing; + +/** + * @author Eugene Zhuravlev + * Date: Mar 4, 2004 + */ +public class SignatureParsingException extends Exception{ + public SignatureParsingException(String message) { + super(message); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/StringConstantValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/StringConstantValue.java new file mode 100644 index 00000000000..0ec34f93b70 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/classParsing/StringConstantValue.java @@ -0,0 +1,36 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.classParsing; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class StringConstantValue extends ConstantValue{ + private final String myValue; + + public StringConstantValue(String value) { + myValue = value; + } + + public StringConstantValue(DataInput in) throws IOException{ + myValue = in.readUTF(); + } + + public String getValue() { + return myValue; + } + + public void save(DataOutput out) throws IOException { + super.save(out); + out.writeUTF(myValue); + } + + public boolean equals(Object obj) { + return + (obj instanceof StringConstantValue) && + ((myValue == null)? ((StringConstantValue)obj).myValue == null : myValue.equals(((StringConstantValue)obj).myValue)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileContextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileContextImpl.java new file mode 100644 index 00000000000..186b8abbe4d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileContextImpl.java @@ -0,0 +1,232 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 21, 2003 + * Time: 4:19:03 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.compiler.CompilerMessageImpl; +import com.intellij.compiler.make.DependencyCache; +import com.intellij.compiler.progress.CompilerProgressIndicator; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.Compiler; +import com.intellij.openapi.compiler.ex.CompileContextEx; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + + +public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileContextImpl"); + private final Project myProject; + private final CompilerProgressIndicator myProgressIndicator; + private final Map> myMessages = new HashMap>(); + private final CompileScope myCompileScope; + private final DependencyCache myDependencyCache; + private final CompileDriver myCompileDriver; + private boolean myRebuildRequested = false; + private String myRebuildReason; + private final Map myRootToModuleMap = new HashMap(); + private final Map> myModuleToRootsMap = new HashMap>(); + private final VirtualFile[] myOutputDirectories; + + public CompileContextImpl(Project project, + CompilerProgressIndicator indicator, + CompileScope compileScope, + DependencyCache dependencyCache, + CompileDriver compileDriver) { + myProject = project; + myProgressIndicator = indicator; + myCompileScope = compileScope; + myDependencyCache = dependencyCache; + myCompileDriver = compileDriver; + myOutputDirectories = CompilerPathsEx.getOutputDirectories(ModuleManager.getInstance(project).getModules()); + } + + public DependencyCache getDependencyCache() { + return myDependencyCache; + } + + public CompilerMessage[] getMessages(CompilerMessageCategory category) { + Collection collection = myMessages.get(category); + if (collection == null) { + return CompilerMessage.EMPTY_ARRAY; + } + return (CompilerMessage[])collection.toArray(new CompilerMessage[collection.size()]); + } + + public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) { + CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, url, lineNum, columnNum); + addMessage(msg); + } + + public void addMessage(CompilerMessage msg) { + Collection messages = myMessages.get(msg.getCategory()); + if (messages == null) { + messages = new HashSet(); + myMessages.put(msg.getCategory(), messages); + } + if (messages.add(msg)) { + myProgressIndicator.addMessage(msg); + } + } + + public int getMessageCount(CompilerMessageCategory category) { + if (category != null) { + Collection collection = myMessages.get(category); + return collection != null ? collection.size() : 0; + } + int count = 0; + for (Iterator> it = myMessages.values().iterator(); it.hasNext();) { + Collection collection = it.next(); + if (collection != null) { + count += collection.size(); + } + } + return count; + } + + public CompileScope getCompileScope() { + return myCompileScope; + } + + public void requestRebuildNextTime(String message) { + if (!myRebuildRequested) { + myRebuildRequested = true; + myRebuildReason = message; + addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + } + } + + public boolean isRebuildRequested() { + return myRebuildRequested; + } + + public String getRebuildReason() { + return myRebuildReason; + } + + public ProgressIndicator getProgressIndicator() { + return myProgressIndicator; + } + + public void assignModule(VirtualFile root, Module module) { + try { + myRootToModuleMap.put(root, module); + Set set = myModuleToRootsMap.get(module); + if (set == null) { + set = new HashSet(); + myModuleToRootsMap.put(module, set); + } + set.add(root); + } + finally { + myModuleToRootsCache.remove(module); + } + } + + public VirtualFile getSourceFileByOutputFile(VirtualFile outputFile) { + if (myCompileDriver == null) { + LOG.assertTrue(false, "myCompileDriver should not be null when calling getSourceFileByOutputFile()"); + return null; + } + Compiler[] compilers = CompilerManager.getInstance(myProject).getCompilers(TranslatingCompiler.class); + for (int idx = 0; idx < compilers.length; idx++) { + final TranslatingCompilerStateCache translatingCompilerCache = myCompileDriver.getTranslatingCompilerCache((TranslatingCompiler)compilers[idx]); + if (translatingCompilerCache == null) { + continue; + } + final String sourceUrl = translatingCompilerCache.getSourceUrl(outputFile.getPath()); + if (sourceUrl == null) { + continue; + } + final VirtualFile sourceFile = VirtualFileManager.getInstance().findFileByUrl(sourceUrl); + if (sourceFile != null) { + return sourceFile; + } + } + return null; + } + + public Module getModuleByFile(VirtualFile file) { + Module module = VfsUtil.getModuleForFile(myProject, file); + if (module == null) { + for (Iterator it = myRootToModuleMap.keySet().iterator(); it.hasNext();) { + VirtualFile root = (VirtualFile)it.next(); + if (VfsUtil.isAncestor(root, file, false)) { + module = myRootToModuleMap.get(root); + break; + } + } + } + return module; + } + + + private Map myModuleToRootsCache = new HashMap(); + + public VirtualFile[] getSourceRoots(Module module) { + VirtualFile[] cachedRoots = myModuleToRootsCache.get(module); + if (cachedRoots != null) { + if (areFilesValid(cachedRoots)) { + return cachedRoots; + } + else { + myModuleToRootsCache.remove(module); // clear cache for this module and rebuild list of roots + } + } + + Set additionalRoots = myModuleToRootsMap.get(module); + VirtualFile[] moduleRoots = ModuleRootManager.getInstance(module).getSourceRoots(); + if (additionalRoots == null || additionalRoots.size() == 0) { + myModuleToRootsCache.put(module, moduleRoots); + return moduleRoots; + } + + final VirtualFile[] allRoots = new VirtualFile[additionalRoots.size() + moduleRoots.length]; + System.arraycopy(moduleRoots, 0, allRoots, 0, moduleRoots.length); + int index = moduleRoots.length; + for (Iterator it = additionalRoots.iterator(); it.hasNext();) { + allRoots[index++] = it.next(); + } + myModuleToRootsCache.put(module, allRoots); + return allRoots; + } + + private boolean areFilesValid(VirtualFile[] files) { + for (int idx = 0; idx < files.length; idx++) { + if (!files[idx].isValid()) { + return false; + } + } + return true; + } + + public VirtualFile[] getAllOutputDirectories() { + return myOutputDirectories; + } + + public VirtualFile getModuleOutputDirectory(Module module) { + return CompilerPaths.getModuleOutputDirectory(module, false); + } + + public VirtualFile getModuleOutputDirectoryForTests(Module module) { + return CompilerPaths.getModuleOutputDirectory(module, true); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileDriver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileDriver.java new file mode 100644 index 00000000000..2c5a2e9d5fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompileDriver.java @@ -0,0 +1,1593 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 17, 2003 + * Time: 1:42:26 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.compiler.*; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.DependencyCache; +import com.intellij.compiler.make.MakeUtil; +import com.intellij.compiler.progress.CompilerProgressIndicator; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.Compiler; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ui.configuration.ContentEntriesEditor; +import com.intellij.openapi.roots.ui.configuration.LibrariesEditor; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.packageDependencies.DependenciesBuilder; +import com.intellij.psi.PsiCompiledElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.ProfilingUtil; +import com.intellij.j2ee.make.impl.MakeUtilImpl; + +import java.io.*; +import java.util.*; + +public class CompileDriver { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileDriver"); + + private final Project myProject; + private final Map myCompilerToCacheMap = new com.intellij.util.containers.HashMap(); + private Map, VirtualFile> myGenerationCompilerModuleToOutputDirMap; + private String myCachesDirectoryPath; + private final ProjectCompileScope myProjectCompileScope; + private Set myOutputFilesOnDisk = null; + private boolean myShouldClearOutputDirectory; + + private Map myModuleOutputPaths = new HashMap(); + private Map myModuleTestOutputPaths = new HashMap(); + + private CompileDriver.ExitStatus myExitStatus = null; + private ProjectRootManager myProjectRootManager; + private static final String VERSION_FILE_NAME = "version.dat"; + private static final String LOCK_FILE_NAME = "in_progress.dat"; + private final FileProcessingCompilerAdapterFactory myProcessingCompilerAdapterFactory; + private final FileProcessingCompilerAdapterFactory myPackagingCompilerAdapterFactory; + + public CompileDriver(Project project) { + myProject = project; + myCachesDirectoryPath = CompilerPaths.getCacheStoreDirectory(myProject).getPath().replace('/', File.separatorChar); + myShouldClearOutputDirectory = CompilerConfiguration.getInstance(myProject).isClearOutputDirectory(); + + myGenerationCompilerModuleToOutputDirMap = + new com.intellij.util.containers.HashMap, VirtualFile>(); + + final Compiler[] compilers = CompilerManager.getInstance(myProject).getCompilers(GeneratingCompiler.class); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final Module[] allModules = ModuleManager.getInstance(myProject).getModules(); + for (int idx = 0; idx < compilers.length; idx++) { + GeneratingCompiler compiler = (GeneratingCompiler)compilers[idx]; + for (int i = 0; i < allModules.length; i++) { + final Module module = allModules[i]; + final String path = getGenerationOutputPath(compiler, module); + final File file = new File(path); + final VirtualFile vFile; + if (file.mkdirs()) { + vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + } + else { + vFile = LocalFileSystem.getInstance().findFileByPath(path); + } + Pair pair = new Pair(compiler, module); + myGenerationCompilerModuleToOutputDirMap.put(pair, vFile); + } + } + } + }); + + myProjectCompileScope = new ProjectCompileScope(myProject); + myProjectRootManager = ProjectRootManager.getInstance(myProject); + myProcessingCompilerAdapterFactory = new FileProcessingCompilerAdapterFactory() { + public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) { + return new FileProcessingCompilerAdapter(context, compiler); + } + }; + myPackagingCompilerAdapterFactory = new FileProcessingCompilerAdapterFactory() { + public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) { + return new PackagingCompilerAdapter(context, (PackagingCompiler)compiler); + } + }; + } + + public void rebuild(CompileStatusNotification callback) { + doRebuild(callback, null, true, addAdditionalRoots(myProjectCompileScope)); + } + + public void make(CompileStatusNotification callback) { + make(myProjectCompileScope, callback); + } + + public void make(Project project, Module[] modules, CompileStatusNotification callback) { + make(new ModuleCompileScope(project, modules, true), callback); + } + + public void make(Module module, CompileStatusNotification callback) { + make(new ModuleCompileScope(module, true), callback); + } + + public void make(CompileScope scope, CompileStatusNotification callback) { + final CompileScope scope1 = addAdditionalRoots(scope); + if (validateCompilerConfiguration(scope1, false)) { + startup(scope1, false, false, callback, null, true); + } + } + + public void compile(CompileScope scope, CompileStatusNotification callback, boolean trackDependencies) { + if (validateCompilerConfiguration(scope, false)) { + if (trackDependencies) { + scope = new TrackDependenciesScope(scope); + } + startup(scope, false, true, callback, null, true); + } + } + + private static class CompileStatus { + final int CACHE_FORMAT_VERSION; + final boolean COMPILATION_IN_PROGRESS; + + public CompileStatus(int cacheVersion, boolean isCompilationInProgress) { + this.CACHE_FORMAT_VERSION = cacheVersion; + this.COMPILATION_IN_PROGRESS = isCompilationInProgress; + } + } + + private CompileStatus readStatus() { + final boolean isInProgress = new File(myCachesDirectoryPath, LOCK_FILE_NAME).exists(); + int version = -1; + try { + final File versionFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME); + if (versionFile.exists()) { + DataInputStream in = new DataInputStream(new FileInputStream(versionFile)); + try { + version = in.readInt(); + } + finally { + in.close(); + } + } + } + catch (IOException e) { + LOG.info(e); // may happen in case of IDEA crashed and the file is not written properly + return null; + } + return new CompileStatus(version, isInProgress); + } + + private void writeStatus(CompileStatus status, CompileContext context) { + final File statusFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME); + final File lockFile = new File(myCachesDirectoryPath, LOCK_FILE_NAME); + try { + if (!statusFile.exists()) { + statusFile.createNewFile(); + } + DataOutputStream out = new DataOutputStream(new FileOutputStream(statusFile)); + try { + out.writeInt(status.CACHE_FORMAT_VERSION); + } + finally { + out.close(); + } + if (status.COMPILATION_IN_PROGRESS) { + lockFile.createNewFile(); + } + else { + lockFile.delete(); + } + } + catch (IOException e) { + context.addMessage(CompilerMessageCategory.ERROR, "Error: " + e.getMessage(), null, -1, -1); + } + } + + private void doRebuild(CompileStatusNotification callback, CompilerMessage message, final boolean checkCachesVersion, final CompileScope compileScope) { + if (validateCompilerConfiguration(compileScope, true)) { + startup(compileScope, true, false, callback, message, checkCachesVersion); + } + } + + private CompileScope addAdditionalRoots(CompileScope originalScope) { + CompileScope scope = originalScope; + for (Iterator> it = myGenerationCompilerModuleToOutputDirMap.keySet().iterator(); it.hasNext();) { + final Pair pair = it.next(); + final VirtualFile outputDir = myGenerationCompilerModuleToOutputDirMap.get(pair); + scope = new CompositeScope(scope, new FileSetCompileScope(new VirtualFile[] {outputDir}, new Module[]{pair.getSecond()})); + } + CompileScope additionalJ2eeScope = MakeUtilImpl.getOutOfSourceJ2eeCompileScope(scope); + if (additionalJ2eeScope != null) { + scope = new CompositeScope(scope, additionalJ2eeScope); + } + return scope; + } + + private void startup(final CompileScope scope, final boolean isRebuild, final boolean forceCompile, final CompileStatusNotification callback, CompilerMessage message, final boolean checkCachesVersion) { + final CompilerProgressIndicator indicator = new CompilerProgressIndicator( + myProject, + CompilerWorkspaceConfiguration.getInstance(myProject).COMPILE_IN_BACKGROUND, + forceCompile ? "Compile" : "Make" + ); + WindowManager.getInstance().getStatusBar(myProject).setInfo(""); + + final CompileContextImpl compileContext = new CompileContextImpl(myProject, indicator, scope, new DependencyCache(myCachesDirectoryPath), this); + for (Iterator> it = myGenerationCompilerModuleToOutputDirMap.keySet().iterator(); it.hasNext();) { + Pair pair = it.next(); + compileContext.assignModule(myGenerationCompilerModuleToOutputDirMap.get(pair), pair.getSecond()); + } + + if (message != null) { + compileContext.addMessage(message); + } + + FileDocumentManager.getInstance().saveAllDocuments(); + + new Thread("Compile Thread") { + public void run() { + synchronized (CompilerManager.getInstance(myProject)) { + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + doCompile(compileContext, isRebuild, forceCompile, callback, checkCachesVersion); + } + }, compileContext.getProgressIndicator()); + } + } + }.start(); + } + + private void doCompile(final CompileContextImpl compileContext, + final boolean isRebuild, + final boolean forceCompile, + final CompileStatusNotification callback, final boolean checkCachesVersion) { + ExitStatus status = ExitStatus.ERRORS; + boolean wereExceptions = false; + try { + compileContext.getProgressIndicator().pushState(); + if (checkCachesVersion) { + final CompileStatus compileStatus = readStatus(); + if (compileStatus == null) { + compileContext.requestRebuildNextTime("Compiler caches are corrupted. Starting rebuild..."); + } + else if (compileStatus.CACHE_FORMAT_VERSION != -1 && compileStatus.CACHE_FORMAT_VERSION != CompilerConfiguration.DEPENDENCY_FORMAT_VERSION) { + compileContext.requestRebuildNextTime("Compiler caches on disk have old format. Starting rebuild..."); + } + else if (compileStatus.COMPILATION_IN_PROGRESS) { + compileContext.requestRebuildNextTime("Previous compilation did not terminate properly. Caches may have been corrupted. Starting rebuild..."); + } + if (compileContext.isRebuildRequested()) { + return; + } + } + writeStatus(new CompileStatus(CompilerConfiguration.DEPENDENCY_FORMAT_VERSION, true), compileContext); + if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return; + } + if (!isRebuild) { + compileContext.getProgressIndicator().setText("Scanning output directories..."); + myOutputFilesOnDisk = CompilerPathsEx.getOutputFiles(myProject); + } + + status = doCompile(compileContext, isRebuild, forceCompile); + } + catch (Throwable ex) { + wereExceptions = true; + throw new RuntimeException(ex); + } + finally { + compileContext.getProgressIndicator().popState(); + final ExitStatus _status = status; + if (compileContext.isRebuildRequested()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + doRebuild( + callback, + new CompilerMessageImpl(myProject, CompilerMessageCategory.INFORMATION, compileContext.getRebuildReason(), null, -1, -1), false, compileContext.getCompileScope() + ); + } + }); + } + else { + writeStatus(new CompileStatus(CompilerConfiguration.DEPENDENCY_FORMAT_VERSION, wereExceptions), compileContext); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final int errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); + final int warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING); + final String statusMessage = createStatusMessage(_status, warningCount, errorCount); + final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); + if (statusBar != null) { // because this code is in invoke later, the code may work for already closed project + // in case another project was opened in the frame while the compiler was working (See SCR# 28591) + statusBar.setInfo(statusMessage); + } + if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { + compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); + } + if (callback != null) { + callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount); + } + + ProfilingUtil.operationFinished("make"); + } + }, ModalityState.NON_MMODAL); + } + } + } + + private static String createStatusMessage(final ExitStatus _status, final int warningCount, final int errorCount) { + if (_status == ExitStatus.CANCELLED) { + return "Compilation aborted"; + } + if (_status == ExitStatus.UP_TO_DATE) { + return "All files are up-to-date"; + } + if (_status == ExitStatus.SUCCESS) { + return (warningCount > 0) + ? "Compilation completed successfully with " + warningCount + " warnings" + : "Compilation completed successfully"; + } + return "Compilation completed with " + errorCount + " errors and " + warningCount + + (warningCount == 1 ? " warning" : " warnings"); + } + + private static class ExitStatus { + private String myName; + + private ExitStatus(String name) { + myName = name; + } + + public String toString() { + return myName; + } + + public static final ExitStatus CANCELLED = new ExitStatus("CANCELLED"); + public static final ExitStatus ERRORS = new ExitStatus("ERRORS"); + public static final ExitStatus SUCCESS = new ExitStatus("SUCCESS"); + public static final ExitStatus UP_TO_DATE = new ExitStatus("UP_TO_DATE"); + } + + private ExitStatus doCompile(CompileContextImpl context, boolean isRebuild, final boolean forceCompile) { + try { + if (isRebuild) { + deleteAll(context); + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return ExitStatus.ERRORS; + } + } + + try { + context.getProgressIndicator().pushState(); + if (!executeCompileTasks(context, true)) { + return ExitStatus.CANCELLED; + } + } + finally { + context.getProgressIndicator().popState(); + } + + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return ExitStatus.ERRORS; + } + + boolean didSomething = false; + + final CompilerManager compilerManager = CompilerManager.getInstance(myProject); + + didSomething |= generateSources(compilerManager, context, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + + didSomething |= invokeFileProcessingCompilers(compilerManager, context, SourceInstrumentingCompiler.class, myProcessingCompilerAdapterFactory, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + + try { + didSomething |= translate(context, compilerManager, forceCompile, isRebuild); + if (myExitStatus != null) { + return myExitStatus; + } + + didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassInstrumentingCompiler.class, myProcessingCompilerAdapterFactory, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + + didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassPostProcessingCompiler.class, myProcessingCompilerAdapterFactory, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + + didSomething |= invokeFileProcessingCompilers(compilerManager, context, PackagingCompiler.class, myPackagingCompilerAdapterFactory, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + + didSomething |= invokeFileProcessingCompilers(compilerManager, context, Validator.class, myProcessingCompilerAdapterFactory, forceCompile); + if (myExitStatus != null) { + return myExitStatus; + } + } + finally { + context.getProgressIndicator().setText("Saving caches..."); + context.getDependencyCache().dispose(); + } + + try { + context.getProgressIndicator().pushState(); + if (!executeCompileTasks(context, false)) { + return ExitStatus.CANCELLED; + } + } + finally { + context.getProgressIndicator().popState(); + } + + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return ExitStatus.ERRORS; + } + if (!didSomething) { + return ExitStatus.UP_TO_DATE; + } + return ExitStatus.SUCCESS; + } + catch (ProcessCanceledException e) { + return ExitStatus.CANCELLED; + } + } + + private boolean generateSources(final CompilerManager compilerManager, CompileContextImpl context, final boolean forceCompile) { + boolean didSomething = false; + + final Compiler[] sourceGenerators = compilerManager.getCompilers(SourceGeneratingCompiler.class); + for (int idx = 0; idx < sourceGenerators.length; idx++) { + if (context.getProgressIndicator().isCanceled()) { + myExitStatus = ExitStatus.CANCELLED; + return false; + } + Compiler compiler = sourceGenerators[idx]; + final boolean generatedSomething = generateOutput(context, (SourceGeneratingCompiler)compiler, forceCompile); + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + myExitStatus = ExitStatus.ERRORS; + return false; + } + didSomething |= generatedSomething; + } + return didSomething; + } + + private boolean translate(CompileContextImpl context, final CompilerManager compilerManager, final boolean forceCompile, boolean isRebuild) { + + boolean didSomething = false; + + final Compiler[] translators = compilerManager.getCompilers(TranslatingCompiler.class); + final VfsSnapshot snapshot = new VfsSnapshot(context.getCompileScope().getFiles(null, true)); + + for (int idx = 0; idx < translators.length; idx++) { + if (context.getProgressIndicator().isCanceled()) { + myExitStatus = ExitStatus.CANCELLED; + return false; + } + + final boolean compiledSomething; + compiledSomething = compileSources(context, snapshot, (TranslatingCompiler)translators[idx], forceCompile, isRebuild); + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + myExitStatus = ExitStatus.ERRORS; + return false; + } + + didSomething |= compiledSomething; + } + return didSomething; + } + + private static interface FileProcessingCompilerAdapterFactory { + FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler); + } + + private boolean invokeFileProcessingCompilers(final CompilerManager compilerManager, CompileContextImpl context, Class fileProcessingCompilerClass, FileProcessingCompilerAdapterFactory factory, boolean forceCompile) { + LOG.assertTrue(FileProcessingCompiler.class.isAssignableFrom(fileProcessingCompilerClass)); + boolean didSomething = false; + final Compiler[] classPostProcessors = compilerManager.getCompilers(fileProcessingCompilerClass); + if (classPostProcessors.length > 0) { + try { + for (int idx = 0; idx < classPostProcessors.length; idx++) { + if (context.getProgressIndicator().isCanceled()) { + myExitStatus = ExitStatus.CANCELLED; + return false; + } + + final boolean processedSomething = processFiles(factory.create(context, (FileProcessingCompiler)classPostProcessors[idx]), forceCompile); + + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + myExitStatus = ExitStatus.ERRORS; + return false; + } + + didSomething |= processedSomething; + } + } + catch(ProcessCanceledException e) { + throw e; + } + catch (Exception e) { + context.addMessage(CompilerMessageCategory.ERROR, "Error processing classes: " + e.getMessage(), null, -1, -1); + LOG.error(e); + } + } + + return didSomething; + } + + private Map> buildModuleToGenerationItemMap( + GeneratingCompiler.GenerationItem[] items) { + final Map> map = new com.intellij.util.containers.HashMap>(); + for (int idx = 0; idx < items.length; idx++) { + GeneratingCompiler.GenerationItem item = items[idx]; + Module module = item.getModule(); + LOG.assertTrue(module != null); + Set itemSet = map.get(module); + if (itemSet == null) { + itemSet = new HashSet(); + map.put(module, itemSet); + } + itemSet.add(item); + } + return map; + } + + private void deleteAll(final CompileContext context) { + context.getProgressIndicator().pushState(); + try { + final com.intellij.openapi.compiler.Compiler[] allCompilers = CompilerManager.getInstance(myProject).getCompilers(Compiler.class); + context.getProgressIndicator().setText("Clearing output directories..."); + for (int idx = 0; idx < allCompilers.length; idx++) { + final Compiler compiler = allCompilers[idx]; + if (compiler instanceof GeneratingCompiler) { + final StateCache cache = getGeneratingCompilerCache((GeneratingCompiler)compiler); + if (!myShouldClearOutputDirectory) { + deleteUrls(cache.getUrlsIterator()); + } + cache.wipe(); + } + else if (compiler instanceof FileProcessingCompiler) { + final FileProcessingCompilerStateCache cache = getFileProcessingCompilerCache((FileProcessingCompiler)compiler); + cache.wipe(); + } + else if (compiler instanceof TranslatingCompiler) { + final TranslatingCompilerStateCache cache = getTranslatingCompilerCache((TranslatingCompiler)compiler); + if (!myShouldClearOutputDirectory) { + deleteUrls(cache.getOutputUrlsIterator()); + } + cache.wipe(); + } + } + if (myShouldClearOutputDirectory) { + final File[] files = getAllOutputDirectories(); + for (int i = 0; i < files.length; i++) { + deleteAllFilesIn(files[i]); + } + // ensure output directories exist, create and refresh if not exist + final List createdFiles = new ArrayList(files.length); + for (int idx = 0; idx < files.length; idx++) { + final File file = files[idx]; + if (file.mkdirs()) { + createdFiles.add(file); + } + } + if (createdFiles.size() > 0) { + CompilerUtil.refreshIOFiles(createdFiles.toArray(new File[createdFiles.size()])); + } + } + + clearCompilerSystemDirectory(context); + } + finally { + context.getProgressIndicator().popState(); + } + } + + private void deleteUrls(final Iterator urlIterator) { + while(urlIterator.hasNext()) { + final String url = urlIterator.next(); + new File(VirtualFileManager.extractPath(url)).delete(); + } + } + + private File[] getAllOutputDirectories() { + final List outputDirs = new ArrayList(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final VirtualFile[] outputDirectories = CompilerPathsEx.getOutputDirectories( + ModuleManager.getInstance(myProject).getModules()); + for (int idx = 0; idx < outputDirectories.length; idx++) { + final File directory = VfsUtil.virtualToIoFile(outputDirectories[idx]); + outputDirs.add(directory); + } + } + }); + + return outputDirs.toArray(new File[outputDirs.size()]); + } + + private void deleteAllFilesIn(File directory) { + FileUtil.asyncDelete(directory); + directory.mkdir(); + } + + private void clearCompilerSystemDirectory(final CompileContext context) { + final File[] children = new File(myCachesDirectoryPath).listFiles(); + if (children != null) { + for (int idx = 0; idx < children.length; idx++) { + final File child = children[idx]; + final boolean deleteOk = FileUtil.delete(child); + if (!deleteOk) { + context.addMessage(CompilerMessageCategory.ERROR, "Failed to delete " + child.getPath(), null, -1, -1); + } + } + } + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (Iterator> it = myGenerationCompilerModuleToOutputDirMap.keySet().iterator(); it.hasNext();) { + Pair pair = it.next(); + final VirtualFile dir = myGenerationCompilerModuleToOutputDirMap.get(pair); + final File[] files = VfsUtil.virtualToIoFile(dir).listFiles(); + if (files != null) { + for (int idx = 0; idx < files.length; idx++) { + final File file = files[idx]; + final boolean deleteOk = FileUtil.delete(file); + if (!deleteOk) { + context.addMessage(CompilerMessageCategory.ERROR, "Failed to delete " + file.getPath(), null, -1, -1); + } + } + } + } + } + }); + } + + private VirtualFile getGenerationOutputDir(final GeneratingCompiler compiler, final Module module) { + return myGenerationCompilerModuleToOutputDirMap.get(new Pair(compiler, module)); + } + + private static String getGenerationOutputPath(GeneratingCompiler compiler, Module module) { + final String generatedCompilerDirectoryPath = CompilerPaths.getGeneratedDataDirectory(module.getProject(), compiler).getPath(); + return generatedCompilerDirectoryPath.replace(File.separatorChar, '/') + "/" + + (module.getName().replace(' ', '_') + "." + Integer.toHexString(module.getModuleFilePath().hashCode())); + } + + private boolean generateOutput(final CompileContextImpl context, final GeneratingCompiler compiler, final boolean forceGenerate) { + final GeneratingCompiler.GenerationItem[] allItems = compiler.getGenerationItems(context); + final List toGenerate = new ArrayList(); + final StateCache cache = getGeneratingCompilerCache(compiler); + final Set pathsToRemove = new HashSet(Arrays.asList(cache.getUrls())); + + final Map itemToOutputPathMap = new com.intellij.util.containers.HashMap(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < allItems.length; idx++) { + final GeneratingCompiler.GenerationItem item = allItems[idx]; + + final Module itemModule = item.getModule(); + final String outputDirPath = getGenerationOutputPath(compiler, itemModule); + final String outputPath = outputDirPath + "/" + item.getPath(); + itemToOutputPathMap.put(item, outputPath); + + final ValidityState savedState = cache.getState(outputPath); + + if (forceGenerate || savedState == null || !savedState.equalsTo(item.getValidityState())) { + toGenerate.add(item); + } + else { + pathsToRemove.remove(outputPath); + } + } + } + }); + + final List filesToRefresh = new ArrayList(); + try { + if (pathsToRemove.size() > 0) { + context.getProgressIndicator().pushState(); + context.getProgressIndicator().setText("Synchronizing output directory..."); + for (Iterator it = pathsToRemove.iterator(); it.hasNext();) { + String path = it.next(); + final File file = new File(path); + final boolean deleted = file.delete(); + if (deleted) { + cache.remove(path); + filesToRefresh.add(file); + } + } + context.getProgressIndicator().popState(); + } + + Map> moduleToItemMap = + buildModuleToGenerationItemMap(toGenerate.toArray(new GeneratingCompiler.GenerationItem[toGenerate.size()])); + List modules = new ArrayList(moduleToItemMap.size()); + for (Iterator it = moduleToItemMap.keySet().iterator(); it.hasNext();) { + modules.add(it.next()); + } + ModuleCompilerUtil.sortModules(myProject, modules); + + for (Iterator it = modules.iterator(); it.hasNext();) { + context.getProgressIndicator().pushState(); + try { + final Module module = it.next(); + final Set items = moduleToItemMap.get(module); + if (items != null && items.size() > 0) { + final VirtualFile outputDir = getGenerationOutputDir(compiler, module); + final GeneratingCompiler.GenerationItem[] successfullyGenerated = + compiler.generate(context, items.toArray(new GeneratingCompiler.GenerationItem[items.size()]), outputDir); + context.getProgressIndicator().setText("Updating caches..."); + for (int idx = 0; idx < successfullyGenerated.length; idx++) { + GeneratingCompiler.GenerationItem item = successfullyGenerated[idx]; + cache.update(itemToOutputPathMap.get(item), item.getValidityState()); + filesToRefresh.add(new File(item.getPath())); + } + } + } + finally { + context.getProgressIndicator().popState(); + } + } + } + finally { + context.getProgressIndicator().pushState(); + CompilerUtil.refreshIOFiles(filesToRefresh.toArray(new File[filesToRefresh.size()])); + if (cache.isDirty()) { + context.getProgressIndicator().setText("Saving caches..."); + cache.save(); + } + context.getProgressIndicator().popState(); + } + return toGenerate.size() > 0 || filesToRefresh.size() > 0; + } + + private boolean compileSources(final CompileContextImpl context, final VfsSnapshot snapshot, final TranslatingCompiler compiler, final boolean forceCompile, final boolean isRebuild) { + final TranslatingCompilerStateCache cache = getTranslatingCompilerCache(compiler); + final Set toCompile = new HashSet(); + final Set toDelete = new HashSet(); + final boolean wereFilesDeleted[] = new boolean[] {false}; + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + + context.getProgressIndicator().pushState(); + try { + + final Set urlsWithSourceRemoved = new HashSet(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + findOutOfDateFiles(compiler, snapshot, forceCompile, cache, toCompile, context); + + if (context.getCompileScope() instanceof TrackDependenciesScope && toCompile.size() > 0) { // should add dependent files + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + final PsiManager psiManager = PsiManager.getInstance(myProject); + final VirtualFile[] filesToCompile = toCompile.toArray(new VirtualFile[toCompile.size()]); + Set sourcesWithOutputRemoved = getSourcesWithOutputRemoved(cache); + for (int i = 0; i < filesToCompile.length; i++) { + final VirtualFile file = filesToCompile[i]; + if (fileTypeManager.getFileTypeByFile(file) == StdFileTypes.JAVA) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile != null) { + addDependentFiles(psiFile, toCompile, cache, snapshot, sourcesWithOutputRemoved); + } + } + } + } + + context.getProgressIndicator().setText("Searching for files to delete..."); + + if (!isRebuild) { + findFilesToDelete(context.getCompileScope(), snapshot, urlsWithSourceRemoved, cache, toCompile, context, toDelete, compilerConfiguration); + } + + } + }); + + if (toDelete.size() > 0) { + try { + wereFilesDeleted[0] = syncOutputDir(urlsWithSourceRemoved, context, toDelete, cache); + } + catch (CacheCorruptedException e) { + LOG.info(e); + context.requestRebuildNextTime(e.getMessage()); + } + } + + if (wereFilesDeleted[0] && toDelete.size() > 0) { + CompilerUtil.refreshPaths(toDelete.toArray(new String[toDelete.size()])); + } + + if ((wereFilesDeleted[0] || toCompile.size() > 0) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + final TranslatingCompiler.ExitStatus exitStatus = compiler.compile(context, toCompile.toArray(new VirtualFile[toCompile.size()])); + updateInternalCaches(cache, context, exitStatus.getSuccessfullyCompiled(), exitStatus.getFilesToRecompile()); + } + } + finally { + if (cache.isDirty()) { + context.getProgressIndicator().setText("Saving caches..."); + if (cache.isDirty()) { + cache.save(); + } + } + context.getProgressIndicator().popState(); + } + return toCompile.size() > 0 || wereFilesDeleted[0]; + } + + private Set getSourcesWithOutputRemoved(TranslatingCompilerStateCache cache) { + //final String[] outputUrls = cache.getOutputUrls(); + final Set set = new HashSet(); + for (Iterator it = cache.getOutputUrlsIterator(); it.hasNext();) { + String outputUrl = it.next(); + if (!myOutputFilesOnDisk.contains(outputUrl)) { + set.add(cache.getSourceUrl(outputUrl)); + } + } + return set; + } + + private void findFilesToDelete(final CompileScope scope, + VfsSnapshot snapshot, final Set urlsWithSourceRemoved, + final TranslatingCompilerStateCache cache, + final Set toCompile, + final CompileContextImpl context, + final Set toDelete, + final CompilerConfiguration compilerConfiguration) { + final List toRemove = new ArrayList(); + for (Iterator it = cache.getOutputUrlsIterator(); it.hasNext();) { + final String outputPath = it.next(); + final String sourceUrl = cache.getSourceUrl(outputPath); + final VirtualFile sourceFile = snapshot.getFileByUrl(sourceUrl); + + boolean needRecompile = false; + boolean shouldDelete = false; + + if (myOutputFilesOnDisk.contains(outputPath)) { + if (sourceFile == null) { + shouldDelete = scope.belongs(sourceUrl); + } + else { + if (toCompile.contains(sourceFile)) { + shouldDelete = true; + } + else { + final String currentOutputDir = getModuleOutputDirForFile(context, sourceFile); + if (currentOutputDir != null) { + final String className = cache.getClassName(outputPath); + final String cachedOutputDir = (className == null) ? + currentOutputDir : + outputPath.substring(0, outputPath.length() - className.length() - ".class".length() - 1); + if (CompilerUtil.pathsEqual(cachedOutputDir, currentOutputDir)) { + shouldDelete = false; + } + else { + // output for this source has been changed or the output dir was changed, need to recompile to the new output dir + shouldDelete = true; + needRecompile = true; + } + } + else { + shouldDelete = true; + } + } + } + } + else { + // output for this source has been deleted or the output dir was changed, need to recompile + needRecompile = true; + shouldDelete = true; // in case the output dir was changed, should delete from the previous location + } + + if (shouldDelete) { + toDelete.add(outputPath); + } + + if (needRecompile) { + if (sourceFile != null && scope.belongs(sourceUrl)) { + if (!compilerConfiguration.isExcludedFromCompilation(sourceFile)) { + toCompile.add(sourceFile); + toRemove.add(outputPath); + } + } + } + if (sourceFile == null) { + urlsWithSourceRemoved.add(outputPath); + } + } + for (Iterator it = toRemove.iterator(); it.hasNext();) { + cache.remove(it.next()); + } + } + + private void updateInternalCaches(final TranslatingCompilerStateCache cache, final CompileContextImpl context, final TranslatingCompiler.OutputItem[] successfullyCompiled, final VirtualFile[] filesToRecompile) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + context.getProgressIndicator().setText("Updating caches..."); + final FileTypeManager typeManager = FileTypeManager.getInstance(); + for (int idx = 0; idx < successfullyCompiled.length; idx++) { + final TranslatingCompiler.OutputItem item = successfullyCompiled[idx]; + final String outputPath = item.getOutputPath(); + final VirtualFile sourceFile = item.getSourceFile(); + final String className; + if (StdFileTypes.JAVA.equals(typeManager.getFileTypeByFile(sourceFile))) { + final String outputDir = item.getOutputRootDirectory(); + + if (!CompilerUtil.startsWith(outputPath, outputDir)) { + LOG.assertTrue(false, outputPath + " does not start with " + outputDir); + } + + className = MakeUtil.relativeClassPathToQName(outputPath.substring(outputDir.length(), outputPath.length()), '/'); + } + else { + className = null; + } + cache.update(outputPath, className, sourceFile); + } + for (int idx = 0; idx < filesToRecompile.length; idx++) { + cache.markAsModified(filesToRecompile[idx]); + } + } + }); + } + + private boolean syncOutputDir(final Set urlsWithSourceRemoved, final CompileContextImpl context, final Set toDelete, + final TranslatingCompilerStateCache cache) throws CacheCorruptedException { + + boolean wereFilesDeleted = false; + DeleteHelper deleteHelper = new DeleteHelper(myProject); + int current = 0; + int total = toDelete.size(); + final DependencyCache dependencyCache = context.getDependencyCache(); + final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode(); + + context.getProgressIndicator().pushState(); + try { + context.getProgressIndicator().setText("Synchronizing output directory..."); + for (Iterator it = toDelete.iterator(); it.hasNext();) { + final String outputPath = (String)it.next(); + context.getProgressIndicator().setFraction(((double)(++current)) / total); + if (deleteHelper.delete(outputPath)) { + wereFilesDeleted = true; + String qName = cache.getClassName(outputPath); + if (qName != null) { + final int id = dependencyCache.getSymbolTable().getId(qName); + dependencyCache.addTraverseRoot(id); + if (urlsWithSourceRemoved.contains(outputPath)) { + dependencyCache.markSourceRemoved(id); + } + } + if (isTestMode) { + CompilerManagerImpl.addDeletedPath(outputPath); + } + cache.remove(outputPath); + } + } + deleteHelper.finish(); + return wereFilesDeleted; + } + finally { + context.getProgressIndicator().popState(); + } + } + + private void findOutOfDateFiles(final TranslatingCompiler compiler, + VfsSnapshot snapshot, + final boolean forceCompile, + final TranslatingCompilerStateCache cache, + final Set toCompile, + CompileContext context) { + + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + VirtualFile[] compilableFiles = getCompilableFiles(compiler, snapshot, context); + + for (int idx = 0; idx < compilableFiles.length; idx++) { + final VirtualFile file = compilableFiles[idx]; + if (!forceCompile) { + if (compilerConfiguration.isExcludedFromCompilation(file)) { + continue; + } + } + if (forceCompile || file.getTimeStamp() != cache.getSourceTimestamp(snapshot.getUrlByFile(file))) { + toCompile.add(file); + } + } + } + + private void addDependentFiles(final PsiFile psiFile, + Set toCompile, + final TranslatingCompilerStateCache cache, + VfsSnapshot snapshot, + Set sourcesWithOutputRemoved) { + final DependenciesBuilder builder = new DependenciesBuilder(myProject, new AnalysisScope(psiFile, AnalysisScope.SOURCE_JAVA_FILES)); + builder.analyze(); + final Map> dependencies = builder.getDependencies(); + final Set dependentFiles = dependencies.get(psiFile); + if (dependentFiles != null && dependentFiles.size() > 0) { + for (Iterator it = dependentFiles.iterator(); it.hasNext();) { + final PsiFile dependentFile = (PsiFile)it.next(); + if (dependentFile instanceof PsiCompiledElement) { + continue; + } + final VirtualFile vFile = dependentFile.getVirtualFile(); + if (toCompile.contains(vFile)) { + continue; + } + String url = snapshot.getUrlByFile(vFile); + if (url == null) { // the file does not belong to this snapshot + url = vFile.getUrl(); + } + if (!sourcesWithOutputRemoved.contains(url)) { + if (vFile.getTimeStamp() == cache.getSourceTimestamp(url)) { + continue; + } + } + toCompile.add(vFile); + addDependentFiles(dependentFile, toCompile, cache, snapshot, sourcesWithOutputRemoved); + } + } + } + + private VirtualFile[] getCompilableFiles(final TranslatingCompiler compiler, VfsSnapshot snapshot, CompileContext context) { + final Set result = new HashSet(); + + for (Iterator iterator = snapshot.getUrlsIterator(); iterator.hasNext();) { + final String url = iterator.next(); + final VirtualFile file = snapshot.getFileByUrl(url); + if (compiler.isCompilableFile(file, context)) { + result.add(file); + } + } + + return result.toArray(new VirtualFile[result.size()]); + } + + private String getModuleOutputDirForFile(CompileContext context, VirtualFile file) { + final Module module = context.getModuleByFile(file); + if (module == null) { + return null; // looks like file invalidated + } + final ProjectFileIndex fileIndex = myProjectRootManager.getFileIndex(); + return getModuleOutputPath(module, fileIndex.isInTestSourceContent(file)); + } + + + // [mike] performance optimization - this method is accessed > 15,000 times in Aurora + private String getModuleOutputPath(final Module module, boolean inTestSourceContent) { + final Map map = inTestSourceContent? myModuleTestOutputPaths : myModuleOutputPaths; + String path = map.get(module); + if (path == null) { + path = CompilerPaths.getModuleOutputPath(module, inTestSourceContent); + map.put(module, path); + } + + return path; + } + + private boolean processFiles(final FileProcessingCompilerAdapter adapter, final boolean forceCompile) { + final CompileContext context = adapter.getCompileContext(); + final FileProcessingCompilerStateCache cache = getFileProcessingCompilerCache(adapter.getCompiler()); + final FileProcessingCompiler.ProcessingItem[] items = adapter.getProcessingItems(); + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return false; + } + final List toProcess = new ArrayList(); + final Set allUrls = new HashSet(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < items.length; idx++) { + FileProcessingCompiler.ProcessingItem item = items[idx]; + final VirtualFile file = item.getFile(); + final String url = file.getUrl(); + allUrls.add(url); + if (!forceCompile && cache.getTimestamp(url) == file.getTimeStamp()) { + final ValidityState state = cache.getExtState(url); + final ValidityState itemState = item.getValidityState(); + if (state != null? state.equalsTo(itemState) : itemState == null) { + continue; + } + } + toProcess.add(item); + } + } + }); + + final String[] urls = cache.getUrls(); + if (urls.length > 0) { + context.getProgressIndicator().pushState(); + context.getProgressIndicator().setText("Processing outdated files..."); + final CompileScope scope = context.getCompileScope(); + final List urlsToRemove = new ArrayList(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < urls.length; idx++) { + final String url = urls[idx]; + if (!allUrls.contains(url)) { + if (scope.belongs(url)) { + urlsToRemove.add(url); + } + } + } + } + }); + if (urlsToRemove.size() > 0) { + for (Iterator it = urlsToRemove.iterator(); it.hasNext();) { + final String url = it.next(); + adapter.processOutdatedItem(context, url, cache.getExtState(url)); + cache.remove(url); + } + } + context.getProgressIndicator().popState(); + } + + if (toProcess.size() == 0) { + return false; + } + + context.getProgressIndicator().pushState(); + final FileProcessingCompiler.ProcessingItem[] processed = + adapter.process(toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()])); + context.getProgressIndicator().popState(); + + if (processed.length > 0) { + context.getProgressIndicator().pushState(); + context.getProgressIndicator().setText("Updating caches..."); + try { + final VirtualFile[] vFiles = new VirtualFile[processed.length]; + for (int idx = 0; idx < processed.length; idx++) { + vFiles[idx] = processed[idx].getFile(); + } + CompilerUtil.refreshVirtualFiles(vFiles); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < processed.length; idx++) { + FileProcessingCompiler.ProcessingItem item = processed[idx]; + cache.update(item.getFile(), item.getValidityState()); + } + } + }); + } + finally { + if (cache.isDirty()) { + context.getProgressIndicator().setText("Saving caches..."); + cache.save(); + } + context.getProgressIndicator().popState(); + } + } + return true; + } + + public TranslatingCompilerStateCache getTranslatingCompilerCache(TranslatingCompiler compiler) { + Object cache = myCompilerToCacheMap.get(compiler); + if (cache == null) { + cache = new TranslatingCompilerStateCache(myCachesDirectoryPath, getIdPrefix(compiler)); + myCompilerToCacheMap.put(compiler, cache); + } + else { + LOG.assertTrue(cache instanceof TranslatingCompilerStateCache); + } + return (TranslatingCompilerStateCache)cache; + } + + private FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) { + Object cache = myCompilerToCacheMap.get(compiler); + if (cache == null) { + cache = new FileProcessingCompilerStateCache(myCachesDirectoryPath, getIdPrefix(compiler), compiler); + myCompilerToCacheMap.put(compiler, cache); + } + else { + LOG.assertTrue(cache instanceof FileProcessingCompilerStateCache); + } + return (FileProcessingCompilerStateCache)cache; + } + + private StateCache getGeneratingCompilerCache(final GeneratingCompiler compiler) { + Object cache = myCompilerToCacheMap.get(compiler); + if (cache == null) { + cache = new StateCache(myCachesDirectoryPath + File.separator + getIdPrefix(compiler) + "_timestamp.dat") { + public ValidityState read(DataInputStream stream) throws IOException { + return compiler.createValidityState(stream); + } + + public void write(ValidityState validityState, DataOutputStream stream) throws IOException { + validityState.save(stream); + } + }; + myCompilerToCacheMap.put(compiler, cache); + } + return (StateCache)cache; + } + + private String getIdPrefix(Compiler compiler) { + String description = compiler.getDescription(); + return description.toLowerCase().replaceAll("\\s+", "_"); + } + + public void executeCompileTask(final CompileTask task, + final CompileScope scope, + final String contentName, + final Runnable onTaskFinished) { + final CompilerProgressIndicator indicator = new CompilerProgressIndicator( + myProject, + CompilerWorkspaceConfiguration.getInstance(myProject).COMPILE_IN_BACKGROUND, + contentName + ); + final CompileContextImpl compileContext = new CompileContextImpl(myProject, indicator, scope, null, this); + + FileDocumentManager.getInstance().saveAllDocuments(); + + new Thread("Compile Task Thread") { + public void run() { + synchronized (CompilerManager.getInstance(myProject)) { + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + try { + task.execute(compileContext); + } + catch (ProcessCanceledException ex) { + // suppressed + } + finally { + if (onTaskFinished != null) { + onTaskFinished.run(); + } + } + } + }, compileContext.getProgressIndicator()); + } + } + }.start(); + } + + private boolean executeCompileTasks(CompileContext context, boolean beforeTasks) { + final CompilerManager manager = CompilerManager.getInstance(myProject); + final ProgressIndicator progressIndicator = context.getProgressIndicator(); + try { + CompileTask[] tasks = beforeTasks ? (CompileTask[])manager.getBeforeTasks() : manager.getAfterTasks(); + if (tasks.length > 0) { + progressIndicator.setText(beforeTasks ? "Executing pre-compile tasks..." : "Executing post-compile tasks..."); + for (int idx = 0; idx < tasks.length; idx++) { + CompileTask task = tasks[idx]; + if (!task.execute(context)) { + return false; + } + } + } + } + finally { + WindowManager.getInstance().getStatusBar(myProject).setInfo(""); + if (progressIndicator instanceof CompilerProgressIndicator) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ((CompilerProgressIndicator)progressIndicator).showCompilerContent(); + } + }); + } + } + return true; + } + // todo: add validation for module chunks: all modules that form a chunk must have the same JDK + private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) { + final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/; + final List modulesWithoutOutputPathSpecified = new ArrayList(); + final List modulesWithoutJdkAssigned = new ArrayList(); + final Set nonExistingOutputPaths = new HashSet(); + + for (int idx = 0; idx < scopeModules.length; idx++) { + final Module module = scopeModules[idx]; + if (ModuleType.J2EE_APPLICATION.equals(module.getModuleType())) { + continue; // makes no sence to demand jdk & output paths for such modules + } + final boolean hasSources = hasSources(module, false); + final boolean hasTestSources = hasSources(module, true); + if (!hasSources && !hasTestSources) { + // If module contains no sources, shouldn't have to select JDK or output directory (SCR #19333) + // todo still there may be problems with this approach if some generated files are attributed by this module + continue; + } + final ProjectJdk jdk = ModuleRootManager.getInstance(module).getJdk(); + if (jdk == null) { + modulesWithoutJdkAssigned.add(module.getName()); + } + final String outputPath = getModuleOutputPath(module, false); + final String testsOutputPath = getModuleOutputPath(module, true); + if (outputPath == null && testsOutputPath == null) { + modulesWithoutOutputPathSpecified.add(module.getName()); + } + else { + if (outputPath != null) { + final File file = new File(outputPath.replace('/', File.separatorChar)); + if (!file.exists()) { + nonExistingOutputPaths.add(file); + } + } + else { + if (hasSources) { + modulesWithoutOutputPathSpecified.add(module.getName()); + } + } + if (testsOutputPath != null) { + final File f = new File(testsOutputPath.replace('/', File.separatorChar)); + if (!f.exists()) { + nonExistingOutputPaths.add(f); + } + } + else { + if (hasTestSources) { + modulesWithoutOutputPathSpecified.add(module.getName()); + } + } + } + } + if (modulesWithoutJdkAssigned.size() > 0) { + showNotSpecifiedError(modulesWithoutJdkAssigned, "the JDK", LibrariesEditor.NAME); + return false; + } + + if (modulesWithoutOutputPathSpecified.size() > 0) { + showNotSpecifiedError(modulesWithoutOutputPathSpecified, "the output path", ContentEntriesEditor.NAME); + return false; + } + + if (nonExistingOutputPaths.size() > 0) { + StringBuffer paths = new StringBuffer(); + for (Iterator it = nonExistingOutputPaths.iterator(); it.hasNext();) { + File file = it.next(); + if (paths.length() > 0) { + paths.append(",\n"); + } + paths.append(file.getPath()); + } + final String notExistsMessage = (nonExistingOutputPaths.size() > 1 ? + "The following output paths do not exist:\n" : + "The following output path does not exist:\n") + + paths.toString() + + "\n\nWould you like to create" + (nonExistingOutputPaths.size() > 1 ? " them " : " it ") + "and continue?"; + final int answer = Messages.showYesNoDialog(myProject, notExistsMessage, "Output Path Does Not Exist", Messages.getQuestionIcon()); + + if (answer == 0) { // yes + for (Iterator it = nonExistingOutputPaths.iterator(); it.hasNext();) { + File file = it.next(); + final boolean succeeded = file.mkdirs(); + if (!succeeded) { + Messages.showMessageDialog(myProject, "Failed to create directory " + file.getPath(), "Unable To Create Directory", Messages.getErrorIcon()); + return false; + } + } + final Boolean refreshSuccess = ApplicationManager.getApplication().runWriteAction(new Computable() { + public Boolean compute() { + for (Iterator it = nonExistingOutputPaths.iterator(); it.hasNext();) { + File file = it.next(); + final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + if (vFile == null) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + }); + if (!refreshSuccess.booleanValue()) { + return false; + } + } + else { + return false; + } + } + + if (checkOutputAndSourceIntersection) { + if (myShouldClearOutputDirectory) { + if (!validateOutputAndSourcePathsIntersection()) { + return false; + } + } + } + final List> chunks = ModuleCompilerUtil.getSortedModuleChunks(myProject, scopeModules); + for (Iterator> it = chunks.iterator(); it.hasNext();) { + final Set chunkModules = it.next().getNodes(); + if (chunkModules.size() <= 1) { + continue; // no need to check one-module chunks + } + ProjectJdk jdk = null; + for (Iterator iterator = chunkModules.iterator(); iterator.hasNext();) { + final Module module = iterator.next(); + final ProjectJdk moduleJdk = ModuleRootManager.getInstance(module).getJdk(); + if (jdk == null) { + jdk = moduleJdk; + } + else { + if (!jdk.equals(moduleJdk)) { + showCyclicModulesHaveDifferentJdksError(chunkModules.iterator()); + return false; + } + } + } + } + final Compiler[] allCompilers = CompilerManager.getInstance(myProject).getCompilers(Compiler.class); + for (int idx = 0; idx < allCompilers.length; idx++) { + Compiler compiler = allCompilers[idx]; + if (!compiler.validateConfiguration(scope)) { + return false; + } + } + return true; + } + + private void showCyclicModulesHaveDifferentJdksError(Iterator modulesIterator) { + String moduleNameToSelect = null; + final StringBuffer message = new StringBuffer(); + message.append("The following modules must have the same JDK assigned because of cyclic dependencies between them:"); + while (modulesIterator.hasNext()) { + final Module module = modulesIterator.next(); + if (moduleNameToSelect == null) { + moduleNameToSelect = module.getName(); + } + message.append("\n").append("\"").append(module.getName()).append("\""); + } + message.append("\nPlease update modules configuration"); + Messages.showMessageDialog(myProject, message.toString(), "Cannot Start Compiler", Messages.getErrorIcon()); + showConfigurationDialog(moduleNameToSelect, null); + } + + private boolean hasSources(Module module, boolean checkTestSources) { + final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries(); + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int i = 0; i < sourceFolders.length; i++) { + final SourceFolder sourceFolder = sourceFolders[i]; + if (sourceFolder.getFile() == null) { + continue; // skip invalid source folders + } + if (checkTestSources) { + if (sourceFolder.isTestSource()) { + return true; + } + } + else { + if (!sourceFolder.isTestSource()) { + return true; + } + } + } + } + return false; + } + + private void showNotSpecifiedError(List modules, final String whatNotSpecified, String tabNameToSelect) { + StringBuffer names = new StringBuffer(); + String nameToSelect = null; + for (Iterator it = modules.iterator(); it.hasNext();) { + String name = it.next(); + if (nameToSelect == null) { + nameToSelect = name; + } + if (names.length() > 0) { + names.append(",\n"); + } + names.append("\""); + names.append(name); + names.append("\""); + } + String message = "Cannot start compiler: " + whatNotSpecified + " is not specified for" + + (modules.size() > 1 ? " modules\n" : " module ") + names.toString() + + ".\nSpecify " + whatNotSpecified + " in Configure Project."; + + if(ApplicationManager.getApplication().isUnitTestMode()) LOG.assertTrue(false, message); + + Messages.showMessageDialog( + myProject, + message, + "Cannot Start Compiler", + Messages.getErrorIcon() + ); + showConfigurationDialog(nameToSelect, tabNameToSelect); + } + + private boolean validateOutputAndSourcePathsIntersection() { + final Module[] allModules = ModuleManager.getInstance(myProject).getModules(); + final VirtualFile[] outputPaths = CompilerPathsEx.getOutputDirectories(allModules); + final Set affectedOutputPaths = new HashSet(); + for (int idx = 0; idx < allModules.length; idx++) { + final ModuleRootManager rootManager = ModuleRootManager.getInstance(allModules[idx]); + final VirtualFile[] sourceRoots = rootManager.getSourceRoots(); + for (int j = 0; j < outputPaths.length; j++) { + VirtualFile outputPath = outputPaths[j]; + for (int i = 0; i < sourceRoots.length; i++) { + VirtualFile sourceRoot = sourceRoots[i]; + if (VfsUtil.isAncestor(outputPath, sourceRoot, true) || VfsUtil.isAncestor(sourceRoot, outputPath, false)) { + affectedOutputPaths.add(outputPath); + } + } + } + } + if (affectedOutputPaths.size() > 0) { + final StringBuffer message = new StringBuffer(); + message.append("Compiler option \"Clear output directory on rebuild\" is currently on.\nHowever, source files may exist in the following output path"); + if (affectedOutputPaths.size() > 1) { + message.append("s:\n"); + } + else { + message.append(":\n"); + } + for (Iterator it = affectedOutputPaths.iterator(); it.hasNext();) { + message.append(it.next().getPath().replace('/', File.separatorChar)); + message.append("\n"); + } + message.append("\nCompilation will proceed without clearing output directories."); + final int answer = Messages.showOkCancelDialog(myProject, message.toString(), "Clear Output Files", Messages.getWarningIcon()); + if (answer == 0) { // ok + myShouldClearOutputDirectory = false; + return true; + } + else { + return false; + } + } + return true; + } + + private void showConfigurationDialog(String moduleNameToSelect, String tabNameToSelect) { + ModulesConfigurator.showDialog(myProject, moduleNameToSelect, tabNameToSelect, false); + } + + private static class VfsSnapshot { + private Map myUrlToFile = new HashMap(); + private Map myFileToUrl = new HashMap(); + + public VfsSnapshot(final VirtualFile[] files) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + myUrlToFile = new HashMap(files.length); + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + final String url = file.getUrl(); + myUrlToFile.put(url, file); + myFileToUrl.put(file, url); + } + } + }); + } + + public VirtualFile getFileByUrl(final String url) { + return myUrlToFile.get(url); + } + + public String getUrlByFile(final VirtualFile file) { + return myFileToUrl.get(file); + } + + public Iterator getUrlsIterator() { + return myUrlToFile.keySet().iterator(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerContentIterator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerContentIterator.java new file mode 100644 index 00000000000..bbc93ddecdc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerContentIterator.java @@ -0,0 +1,42 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; + +/** + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + * + * @author Eugene Zhuravlev + * Date: May 5, 2004 + */ +public class CompilerContentIterator implements ContentIterator { + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + private final FileType myFileType; + private final FileIndex myFileIndex; + private final boolean myInSourceOnly; + private final Collection myFiles; + + public CompilerContentIterator(FileType fileType, FileIndex fileIndex, boolean inSourceOnly, Collection files) { + myFileType = fileType; + myFileIndex = fileIndex; + myInSourceOnly = inSourceOnly; + myFiles = files; + } + + public boolean processFile(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) return true; + if (!(fileOrDir.getFileSystem() instanceof LocalFileSystem)) return true; + if (myInSourceOnly && !myFileIndex.isInSourceContent(fileOrDir)) return true; + if (myFileType == null || myFileType == fileTypeManager.getFileTypeByFile(fileOrDir)) { + myFiles.add(fileOrDir); + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerErrorTreeView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerErrorTreeView.java new file mode 100644 index 00000000000..0417f7eef45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerErrorTreeView.java @@ -0,0 +1,106 @@ +package com.intellij.compiler.impl; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerWorkspaceConfiguration; +import com.intellij.compiler.HelpID; +import com.intellij.compiler.options.CompilerConfigurable; +import com.intellij.ide.errorTreeView.ErrorTreeElement; +import com.intellij.ide.errorTreeView.ErrorTreeNodeDescriptor; +import com.intellij.ide.errorTreeView.GroupingElement; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +public class CompilerErrorTreeView extends NewErrorTreeViewPanel { + public CompilerErrorTreeView(Project project) { + super(project, HelpID.COMPILER); + } + + protected void fillRightToolbarGroup(DefaultActionGroup group) { + super.fillRightToolbarGroup(group); + group.add(new CompilerPropertiesAction()); + } + + protected void addExtraPopupMenuActions(DefaultActionGroup group) { + group.add(new ExcludeFromCompileAction()); + } + + protected boolean shouldShowFirstErrorInEditor() { + return CompilerWorkspaceConfiguration.getInstance(myProject).AUTO_SHOW_ERRORS_IN_EDITOR; + } + + private static class CompilerPropertiesAction extends AnAction { + public CompilerPropertiesAction() { + super("Compiler Properties", null, IconLoader.getIcon("/general/projectProperties.png")); + } + + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + ShowSettingsUtil.getInstance().editConfigurable(project, CompilerConfigurable.getInstance(project)); + } + } + + private class ExcludeFromCompileAction extends AnAction { + public ExcludeFromCompileAction() { + super("Exclude From Compile"); + } + + public void actionPerformed(AnActionEvent e) { + VirtualFile file = getSelectedFile(); + + if (file != null && file.isValid()) { + ExcludeEntryDescription description = new ExcludeEntryDescription(file, false, true); + CompilerConfiguration.getInstance(myProject).addExcludeEntryDescription(description); + FileStatusManager.getInstance(myProject).fileStatusesChanged(); + } + } + + private VirtualFile getSelectedFile() { + final ErrorTreeElement selectedElement = getSelectedErrorTreeElement(); + if (selectedElement == null) return null; + + String filePresentableText = getSelectedFilePresentableText(selectedElement); + + if (filePresentableText == null) return null; + + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePresentableText.replace('\\', '/')); + return file; + } + + private String getSelectedFilePresentableText(final ErrorTreeElement selectedElement) { + String filePresentableText = null; + + if (selectedElement instanceof GroupingElement) { + GroupingElement groupingElement = (GroupingElement)selectedElement; + filePresentableText = groupingElement.getName(); + } + else { + NodeDescriptor parentDescriptor = getSelectedNodeDescriptor().getParentDescriptor(); + if (parentDescriptor instanceof ErrorTreeNodeDescriptor) { + ErrorTreeNodeDescriptor treeNodeDescriptor = (ErrorTreeNodeDescriptor)parentDescriptor; + ErrorTreeElement element = treeNodeDescriptor.getElement(); + if (element instanceof GroupingElement) { + GroupingElement groupingElement = (GroupingElement)element; + filePresentableText = groupingElement.getName(); + } + } + + } + return filePresentableText; + } + + public void update(AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final boolean isApplicable = getSelectedFile() != null; + presentation.setEnabled(isApplicable); + presentation.setVisible(isApplicable); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerUtil.java new file mode 100644 index 00000000000..f3e25078d5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompilerUtil.java @@ -0,0 +1,179 @@ +/** + * created at Jan 3, 2002 + * @author Jeka + */ +package com.intellij.compiler.impl; + +import com.intellij.compiler.progress.CompilerProgressIndicator; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.awt.*; +import java.io.File; +import java.io.FileFilter; +import java.util.Collection; +import java.util.Collections; + +public class CompilerUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil"); + + public static String quotePath(String path) { + if(path != null && path.indexOf(' ') != -1) { + path = path.replaceAll("\\\\", "\\\\\\\\"); + path = "\"" + path + "\""; + } + return path; + } + + public static String normalizePath(String path, char pathSeparator) { + int index = path.lastIndexOf(pathSeparator); + if (index >= 0) { + return path.substring(0, index).toLowerCase() + path.substring(index); + } + return path; + } + + public static boolean startsWith(String path1, String path2) { + if (!SystemInfo.isFileSystemCaseSensitive) { + path1 = path1.toLowerCase(); + path2 = path2.toLowerCase(); + } + return path1.startsWith(path2); + } + + public static boolean pathsEqual(String path1, String path2) { + if (!SystemInfo.isFileSystemCaseSensitive) { + path1 = path1.toLowerCase(); + path2 = path2.toLowerCase(); + } + return path1.equals(path2); + } + + public static final FileFilter CLASS_FILES_FILTER = new FileFilter() { + public boolean accept(File pathname) { + if (pathname.isDirectory()) { + return true; + } + final int dotIndex = pathname.getName().lastIndexOf('.'); + if (dotIndex > 0) { + String extension = pathname.getName().substring(dotIndex); + if (extension.equalsIgnoreCase(".class")) { + return true; + } + } + return false; + } + }; + public static void collectFiles(Collection container, File rootDir, FileFilter fileFilter) { + final File[] files = rootDir.listFiles(fileFilter); + if (files == null) { + return; + } + for (int idx = 0; idx < files.length; idx++) { + File file = files[idx]; + if (file.isDirectory()) { + collectFiles(container, file, fileFilter); + } + else { + container.add(file); + } + } + } + + public static void refreshPaths(final String[] paths) { + if (paths.length == 0) { + return; + } + doRefresh(new Runnable() { + public void run() { + for (int idx = 0; idx < paths.length; idx++) { + final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(paths[idx].replace(File.separatorChar, '/')); + if (file != null) { + file.refresh(false, false); + } + } + } + }); + } + + + /** + * must not be called inside ReadAction + * @param files + */ + public static void refreshIOFiles(final File[] files) { + if (files.length == 0) { + return; + } + doRefresh(new Runnable() { + public void run() { + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(files[idx]); + if (file != null) { + file.refresh(false, false); + } + } + } + }); + } + + public static void refreshIOFile(final File file) { + doRefresh(new Runnable() { + public void run() { + final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + if (vFile != null) { + vFile.refresh(false, false); + } + } + }); + } + + public static void refreshVirtualFiles(final VirtualFile[] files) { + doRefresh(new Runnable() { + public void run() { + for (int idx = 0; idx < files.length; idx++) { + files[idx].refresh(false, false); + } + } + }); + } + + private static void doRefresh(final Runnable refreshRunnable) { + final Application applicationEx = ApplicationManager.getApplication(); + if (applicationEx.isDispatchThread()) { + applicationEx.runWriteAction(refreshRunnable); + } + else { + try { + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + ModalityState modalityState; + if (progress instanceof CompilerProgressIndicator){ + Window window = ((CompilerProgressIndicator)progress).getWindow(); + modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MMODAL; + } + else{ + modalityState = ModalityState.NON_MMODAL; + } + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(refreshRunnable); + } + }, modalityState); + } + catch (Exception e) { + LOG.error(e); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompositeScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompositeScope.java new file mode 100644 index 00000000000..2c9fa898a5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/CompositeScope.java @@ -0,0 +1,57 @@ +/* + * @author: Eugene Zhuravlev + * Date: Feb 5, 2003 + * Time: 4:17:58 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.*; + +public class CompositeScope implements CompileScope{ + private final List myScopes = new ArrayList(); + + public CompositeScope(CompileScope scope1, CompileScope scope2) { + myScopes.add(scope1); + myScopes.add(scope2); + } + + public CompositeScope(CompileScope[] scopes) { + myScopes.addAll(Arrays.asList(scopes)); + } + + public VirtualFile[] getFiles(FileType fileType, boolean inSourceOnly) { + List allFiles = new ArrayList(); + for (Iterator it = myScopes.iterator(); it.hasNext();) { + CompileScope scope = (CompileScope)it.next(); + final VirtualFile[] files = scope.getFiles(fileType, inSourceOnly); + if (files.length > 0) { + allFiles.addAll(Arrays.asList(files)); + } + } + return allFiles.toArray(new VirtualFile[allFiles.size()]); + } + + public boolean belongs(String url) { + for (Iterator it = myScopes.iterator(); it.hasNext();) { + CompileScope scope = it.next(); + if (scope.belongs(url)) { + return true; + } + } + return false; + } + + public Module[] getAffectedModules() { + Set modules = new HashSet(); + for (Iterator it = myScopes.iterator(); it.hasNext();) { + final CompileScope compileScope = it.next(); + modules.addAll(Arrays.asList(compileScope.getAffectedModules())); + } + return modules.toArray(new Module[modules.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ExcludeEntryDescription.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ExcludeEntryDescription.java new file mode 100644 index 00000000000..df9a8997931 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ExcludeEntryDescription.java @@ -0,0 +1,81 @@ +/** + * created at Jan 3, 2002 + * @author Jeka + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; + +public class ExcludeEntryDescription { + private boolean myIsFile = true; + private boolean myIncludeSubdirectories; + private VirtualFilePointer myFilePointer; + + public ExcludeEntryDescription(VirtualFile virtualFile, boolean includeSubdirectories, boolean isFile) { + myFilePointer = VirtualFilePointerManager.getInstance().create(virtualFile, null); + myIncludeSubdirectories = includeSubdirectories; + myIsFile = isFile; + } + + public ExcludeEntryDescription(String url, boolean includeSubdirectories, boolean isFile) { + myFilePointer = VirtualFilePointerManager.getInstance().create(url, null); + myIncludeSubdirectories = includeSubdirectories; + myIsFile = isFile; + } + + public ExcludeEntryDescription copy() { + return new ExcludeEntryDescription(getUrl(), myIncludeSubdirectories, myIsFile); + } + + public boolean isFile() { + return myIsFile; + } + + public String getUrl() { + return myFilePointer.getUrl(); + } + + public String getPresentableUrl() { + return myFilePointer.getPresentableUrl(); + } + + public boolean isIncludeSubdirectories() { + return myIncludeSubdirectories; + } + + public void setIncludeSubdirectories(boolean includeSubdirectories) { + myIncludeSubdirectories = includeSubdirectories; + } + + public VirtualFile getVirtualFile() { + return myFilePointer.getFile(); + } + + public boolean isValid() { + return myFilePointer.isValid(); + } + + public boolean equals(Object obj) { + if(!(obj instanceof ExcludeEntryDescription)) { + return false; + } + ExcludeEntryDescription entryDescription = (ExcludeEntryDescription)obj; + if(entryDescription.myIsFile != myIsFile) { + return false; + } + if(entryDescription.myIncludeSubdirectories != myIncludeSubdirectories) { + return false; + } + if(!Comparing.equal(entryDescription.getUrl(), getUrl())) { + return false; + } + return true; + } + + public int hashCode() { + return getUrl().hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileIndexCompileScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileIndexCompileScope.java new file mode 100644 index 00000000000..1e17d0521c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileIndexCompileScope.java @@ -0,0 +1,33 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Eugene Zhuravlev + * Date: Dec 18, 2003 + */ +public abstract class FileIndexCompileScope implements CompileScope { + + protected abstract FileIndex[] getFileIndices(); + + public VirtualFile[] getFiles(final FileType fileType, final boolean inSourceOnly) { + final Set files = new HashSet(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final FileIndex[] fileIndices = getFileIndices(); + for (int idx = 0; idx < fileIndices.length; idx++) { + final FileIndex fileIndex = fileIndices[idx]; + fileIndex.iterateContent(new CompilerContentIterator(fileType, fileIndex, inSourceOnly, files)); + } + } + }); + return files.toArray(new VirtualFile[files.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java new file mode 100644 index 00000000000..1584be77f78 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java @@ -0,0 +1,38 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.FileProcessingCompiler; +import com.intellij.openapi.compiler.ValidityState; + +/** + * @author Eugene Zhuravlev + * Date: Oct 16 + * @author 2003 + */ +public class FileProcessingCompilerAdapter { + private final CompileContext myCompileContext; + private final FileProcessingCompiler myCompiler; + + protected FileProcessingCompilerAdapter(CompileContext compileContext, FileProcessingCompiler compiler) { + myCompileContext = compileContext; + myCompiler = compiler; + } + + public CompileContext getCompileContext() { + return myCompileContext; + } + + public FileProcessingCompiler.ProcessingItem[] getProcessingItems() { + return myCompiler.getProcessingItems(getCompileContext()); + } + + public FileProcessingCompiler.ProcessingItem[] process(FileProcessingCompiler.ProcessingItem[] items) { + return myCompiler.process(getCompileContext(), items); + } + + public final FileProcessingCompiler getCompiler() { + return myCompiler; + } + + public void processOutdatedItem(CompileContext context, String url, ValidityState state){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java new file mode 100644 index 00000000000..33654c3af7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java @@ -0,0 +1,88 @@ +/* + * @author: Eugene Zhuravlev + * Date: Apr 1, 2003 + * Time: 1:17:50 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.ValidityState; +import com.intellij.openapi.compiler.ValidityStateFactory; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.*; + +public class FileProcessingCompilerStateCache { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.FileProcessingCompilerStateCache"); + private final StateCache myCache; + + public FileProcessingCompilerStateCache(String storeDirectory, String idPrefix, final ValidityStateFactory stateFactory) { + myCache = new StateCache(storeDirectory + File.separator + idPrefix + "_timestamp.dat") { + public MyState read(DataInputStream stream) throws IOException { + return new MyState(stream.readLong(), stateFactory.createValidityState(stream)); + } + + public void write(MyState state, DataOutputStream stream) throws IOException { + stream.writeLong(state.getTimestamp()); + state.getExtState().save(stream); + } + }; + } + + public void update(VirtualFile sourceFile, ValidityState extState) { + myCache.update(sourceFile.getUrl(), new MyState(sourceFile.getTimeStamp(), extState)); + } + + public void remove(String url) { + myCache.remove(url); + } + + public long getTimestamp(String url) { + final Serializable savedState = myCache.getState(url); + if (savedState != null) { + LOG.assertTrue(savedState instanceof MyState); + } + MyState state = (MyState)savedState; + return (state != null)? state.getTimestamp() : -1L; + } + + public ValidityState getExtState(String url) { + MyState state = myCache.getState(url); + return (state != null)? state.getExtState() : null; + } + + public void save() { + myCache.save(); + } + + public String[] getUrls() { + return myCache.getUrls(); + } + + public boolean wipe() { + return myCache.wipe(); + } + + public boolean isDirty() { + return myCache.isDirty(); + } + + private static class MyState implements Serializable { + private final long myTimestamp; + private final ValidityState myExtState; + + public MyState(long timestamp, ValidityState extState) { + myTimestamp = timestamp; + myExtState = extState; + } + + public long getTimestamp() { + return myTimestamp; + } + + public ValidityState getExtState() { + return myExtState; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileSetCompileScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileSetCompileScope.java new file mode 100644 index 00000000000..7940ef75350 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/FileSetCompileScope.java @@ -0,0 +1,119 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 20, 2003 + * Time: 5:34:19 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class FileSetCompileScope implements CompileScope { + private Set myRootFiles = new HashSet(); + private Set myDirectoryUrls = new HashSet(); + private Set myUrls = null; // urls caching + private final Module[] myAffectedModules; + + public FileSetCompileScope(final VirtualFile[] files, Module[] modules) { + myAffectedModules = modules; + ApplicationManager.getApplication().runReadAction( + new Runnable() { + public void run() { + for(int idx = 0; idx < files.length; idx++){ + addFile(files[idx]); + } + } + } + ); + } + + public Module[] getAffectedModules() { + return myAffectedModules; + } + + public VirtualFile[] getFiles(final FileType fileType, boolean inSourceOnly) { + final Set files = new HashSet(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final FileTypeManager typeManager = FileTypeManager.getInstance(); + for (Iterator it = myRootFiles.iterator(); it.hasNext();) { + VirtualFile file = it.next(); + if (!file.isValid()) { + it.remove(); + continue; + } + if (file.isDirectory()) { + addRecursively(files, file, fileType); + } + else { + if (fileType == null || fileType.equals(typeManager.getFileTypeByFile(file))) { + files.add(file); + } + } + } + } + }); + return files.toArray(new VirtualFile[files.size()]); + } + + public boolean belongs(String url) { + //url = CompilerUtil.normalizePath(url, '/'); + if (getUrls().contains(url)) { + return true; + } + for (Iterator it = myDirectoryUrls.iterator(); it.hasNext();) { + String directoryUrl = (String)it.next(); + if (CompilerUtil.startsWith(url, directoryUrl)) { + return true; + } + } + return false; + } + + private Set getUrls() { + if (myUrls == null) { + myUrls = new HashSet(); + for (Iterator it = myRootFiles.iterator(); it.hasNext();) { + VirtualFile file = it.next(); + String url = file.getUrl(); + myUrls.add(url); + } + } + return myUrls; + } + + private void addFile(VirtualFile file) { + if (file.isDirectory()) { + myDirectoryUrls.add(file.getUrl() + "/"); + } + myRootFiles.add(file); + myUrls = null; + } + + private void addRecursively(final Collection container, final VirtualFile fromDirectory, FileType fileType) { + VirtualFile[] children = fromDirectory.getChildren(); + if (children.length > 0) { + final FileTypeManager typeManager = FileTypeManager.getInstance(); + for (int idx = 0; idx < children.length; idx++) { + VirtualFile child = children[idx]; + if (child.isDirectory()) { + addRecursively(container, child, fileType); + } + else { + if (fileType == null || fileType.equals(typeManager.getFileTypeByFile(child))) { + container.add(child); + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ModuleCompileScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ModuleCompileScope.java new file mode 100644 index 00000000000..f75ea39bd20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ModuleCompileScope.java @@ -0,0 +1,139 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 20, 2003 + * Time: 5:34:19 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class ModuleCompileScope extends FileIndexCompileScope { + private final Project myProject; + private final Set myScopeModules; + + public ModuleCompileScope(final Module module, boolean includeDependentModules) { + myProject = module.getProject(); + myScopeModules = new HashSet(); + if (includeDependentModules) { + buildScopeModulesSet(module); + } + else { + myScopeModules.add(module); + } + } + + public ModuleCompileScope(Project project, final Module[] modules, boolean includeDependentModules) { + myProject = project; + myScopeModules = new HashSet(); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + if (includeDependentModules) { + buildScopeModulesSet(module); + } + else { + myScopeModules.add(module); + } + } + } + + private void buildScopeModulesSet(Module module) { + myScopeModules.add(module); + final Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies(); + for (int idx = 0; idx < dependencies.length; idx++) { + Module dependency = dependencies[idx]; + if (!myScopeModules.contains(dependency)) { // may be in case of module circular dependencies + buildScopeModulesSet(dependency); + } + } + } + + public Module[] getAffectedModules() { + return myScopeModules.toArray(new Module[myScopeModules.size()]); + } + + protected FileIndex[] getFileIndices() { + final FileIndex[] indices = new FileIndex[myScopeModules.size()]; + int idx = 0; + for (Iterator it = myScopeModules.iterator(); it.hasNext();) { + final Module module = (Module)it.next(); + indices[idx++] = ModuleRootManager.getInstance(module).getFileIndex(); + } + return indices; + } + + public boolean belongs(String url) { + final Module[] modules = ModuleManager.getInstance(myProject).getModules(); + Module candidateModule = null; + int maxUrlLength = 0; + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + for (int idx = 0; idx < modules.length; idx++) { + final Module module = modules[idx]; + final String[] contentRootUrls = ModuleRootManager.getInstance(module).getContentRootUrls(); + for (int i = 0; i < contentRootUrls.length; i++) { + final String contentRootUrl = contentRootUrls[i]; + if (contentRootUrl.length() < maxUrlLength) { + continue; + } + if (!CompilerUtil.startsWith(url, contentRootUrl + "/")) { + continue; + } + if (contentRootUrl.length() == maxUrlLength) { + if (candidateModule == null) { + candidateModule = module; + } + else { + // the same content root exists in several modules + if (!candidateModule.equals(module)) { + candidateModule = ApplicationManager.getApplication().runReadAction(new Computable() { + public Module compute() { + final VirtualFile contentRootFile = VirtualFileManager.getInstance().findFileByUrl(contentRootUrl); + if (contentRootFile != null) { + return projectFileIndex.getModuleForFile(contentRootFile); + } + return null; + } + }); + } + } + } + else { + maxUrlLength = contentRootUrl.length(); + candidateModule = module; + } + } + } + + if (candidateModule != null && myScopeModules.contains(candidateModule)) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(candidateModule); + final String[] excludeRootUrls = moduleRootManager.getExcludeRootUrls(); + for (int i = 0; i < excludeRootUrls.length; i++) { + if (CompilerUtil.startsWith(url, excludeRootUrls[i] + "/")) { + return false; + } + } + final String[] sourceRootUrls = moduleRootManager.getSourceRootUrls(); + for (int i = 0; i < sourceRootUrls.length; i++) { + if (CompilerUtil.startsWith(url, sourceRootUrls[i] + "/")) { + return true; + } + } + } + + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/OneProjectItemCompileScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/OneProjectItemCompileScope.java new file mode 100644 index 00000000000..0c0b22ef44b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/OneProjectItemCompileScope.java @@ -0,0 +1,70 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VfsUtil; + +import java.util.HashSet; +import java.util.Set; + +public class OneProjectItemCompileScope implements CompileScope{ + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.OneProjectItemCompileScope"); + private final Project myProject; + private final VirtualFile myFile; + private final String myUrl; + + public OneProjectItemCompileScope(Project project, VirtualFile file) { + myProject = project; + myFile = file; + final String url = SystemInfo.isFileSystemCaseSensitive? file.getUrl() : file.getUrl().toLowerCase(); + myUrl = file.isDirectory()? url + "/" : url; + } + + public VirtualFile[] getFiles(final FileType fileType, final boolean inSourceOnly) { + final Set files = new HashSet(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final FileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final ContentIterator iterator = new CompilerContentIterator(fileType, projectFileIndex, inSourceOnly, files); + if (myFile.isDirectory()){ + projectFileIndex.iterateContentUnderDirectory(myFile, iterator); + } + else{ + iterator.processFile(myFile); + } + } + }); + return files.toArray(new VirtualFile[files.size()]); + } + + public boolean belongs(String url) { + if (!SystemInfo.isFileSystemCaseSensitive) { + url = url.toLowerCase(); + } + if (myFile.isDirectory()){ + return url.startsWith(myUrl); + } + else{ + return url.equals(myUrl); + } + } + + public Module[] getAffectedModules() { + final Module module = VfsUtil.getModuleForFile(myProject, myFile); + if (module == null) { + LOG.assertTrue(false, "Module is null for file " + myFile.getPresentableUrl()); + return Module.EMPTY_ARRAY; + } + return new Module[] {module}; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/PackagingCompilerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/PackagingCompilerAdapter.java new file mode 100644 index 00000000000..1225f3a6168 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/PackagingCompilerAdapter.java @@ -0,0 +1,18 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.PackagingCompiler; +import com.intellij.openapi.compiler.ValidityState; + +public class PackagingCompilerAdapter extends FileProcessingCompilerAdapter{ + private final PackagingCompiler myCompiler; + + public PackagingCompilerAdapter(CompileContext compileContext, PackagingCompiler compiler) { + super(compileContext, compiler); + myCompiler = compiler; + } + + public void processOutdatedItem(CompileContext context, String url, ValidityState state) { + myCompiler.processOutdatedItem(context, url, state); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ProjectCompileScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ProjectCompileScope.java new file mode 100644 index 00000000000..672d7bcae5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/ProjectCompileScope.java @@ -0,0 +1,41 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 20, 2003 + * Time: 5:34:19 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.CompilerPaths; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.File; + +public class ProjectCompileScope extends FileIndexCompileScope { + private final Project myProject; + private final String myTempDirUrl; + + public ProjectCompileScope(final Project project) { + myProject = project; + final String path = CompilerPaths.getCompilerSystemDirectory(project).getPath().replace(File.separatorChar, '/'); + myTempDirUrl = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, path) + '/'; + } + + protected FileIndex[] getFileIndices() { + return new FileIndex[] {ProjectRootManager.getInstance(myProject).getFileIndex()}; + } + + public boolean belongs(String url) { + //return !url.startsWith(myTempDirUrl); + return !CompilerUtil.startsWith(url, myTempDirUrl); + } + + public Module[] getAffectedModules() { + return ModuleManager.getInstance(myProject).getModules(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/StateCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/StateCache.java new file mode 100644 index 00000000000..92965ad524d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/StateCache.java @@ -0,0 +1,57 @@ +package com.intellij.compiler.impl; + +import com.intellij.util.ArrayUtil; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Set; + +public abstract class StateCache extends MapCache { + public StateCache(String storePath) { + super(storePath); + } + + public void update(String url, T state){ + if (!load()) { + return; + } + if (state != null) { + myMap.put(url, state); + setDirty(); + } + else { + remove(url); + } + } + + public void remove(String url){ + if (!load()) { + return; + } + myMap.remove(url); + setDirty(); + } + + public T getState(String url){ + if (!load()) { + return null; + } + return myMap.get(url); + } + + public String[] getUrls() { + if (!load()) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + final Set keys = myMap.keySet(); + return keys.toArray(new String[keys.size()]); + } + + public Iterator getUrlsIterator() { + if (!load()) { + return Arrays.asList(ArrayUtil.EMPTY_STRING_ARRAY).iterator(); + } + return myMap.keySet().iterator(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TimestampCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TimestampCache.java new file mode 100644 index 00000000000..6a3b64b1293 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TimestampCache.java @@ -0,0 +1,33 @@ +/* + * @author: Eugene Zhuravlev + * Date: Apr 1, 2003 + * Time: 1:53:00 PM + */ +package com.intellij.compiler.impl; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.File; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class TimestampCache extends StateCache { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TimestampCache"); + public TimestampCache(String storeDirectory, String idPrefix) { + super(storeDirectory + File.separator + idPrefix + "_timestamp.dat"); + } + + public void update(String url, Long state) { + LOG.assertTrue(state != null); + super.update(url, state); + } + + public Long read(DataInputStream stream) throws IOException { + return new Long(stream.readLong()); + } + + public void write(Long aLong, DataOutputStream stream) throws IOException { + stream.writeLong(aLong.longValue()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TrackDependenciesScope.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TrackDependenciesScope.java new file mode 100644 index 00000000000..ea281694074 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/TrackDependenciesScope.java @@ -0,0 +1,33 @@ +package com.intellij.compiler.impl; + +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + * + * @author Eugene Zhuravlev + * Date: May 5, 2004 + */ +public class TrackDependenciesScope implements CompileScope{ + private final CompileScope myDelegate; + + public TrackDependenciesScope(CompileScope delegate) { + myDelegate = delegate; + } + + public VirtualFile[] getFiles(FileType fileType, boolean inSourceOnly) { + return myDelegate.getFiles(fileType, inSourceOnly); + } + + public boolean belongs(String url) { + return myDelegate.belongs(url); + } + + public Module[] getAffectedModules() { + return myDelegate.getAffectedModules(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java new file mode 100644 index 00000000000..860c5494b7d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java @@ -0,0 +1,19 @@ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.OutputParser; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; + +interface BackendCompiler { + OutputParser createOutputParser(); + + String[] createStartupCommand(ModuleChunk chunk, CompileContext context, String outputPath) + throws IOException, IllegalArgumentException; + + boolean checkCompiler(); + + void processTerminated(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java new file mode 100644 index 00000000000..7b8724d5354 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -0,0 +1,877 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 24, 2003 + * Time: 4:25:47 PM + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.*; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.compiler.make.Cache; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.MakeUtil; +import com.intellij.compiler.make.SourceFileFinder; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.Compiler; +import com.intellij.openapi.compiler.ex.CompileContextEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.rt.compiler.JavacRunner; +import com.intellij.util.cls.ClsFormatException; + +import java.io.*; +import java.util.*; + + +class BackendCompilerWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper"); + + private final BackendCompiler myCompiler; + private final Map>> myFileNameToSourceMap = new HashMap>>(); + private final List myFilesToRefresh = new ArrayList(); + private final Set mySuccesfullyCompiledJavaFiles = new HashSet(); // VirtualFile + private final List myOutputItems = new ArrayList(); + + private final CompileContextEx myCompileContext; + private final VirtualFile[] myFilesToCompile; + private final Project myProject; + private Set myFilesToRecompile = new HashSet(); + private ClassParsingThread myClassParsingThread; + private int myExitCode; + private Map myModuleToTempDirMap = new HashMap(); + private final ProjectFileIndex myProjectFileIndex; + + public BackendCompilerWrapper(final Project project, VirtualFile[] filesToCompile, CompileContextEx compileContext, BackendCompiler compiler) { + myProject = project; + myCompiler = compiler; + myCompileContext = compileContext; + myFilesToCompile = filesToCompile; + myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + } + + public TranslatingCompiler.OutputItem[] compile() throws CompilerException, CacheCorruptedException { + VirtualFile[] dependentFiles = null; + Application application = ApplicationManager.getApplication(); + COMPILE: try { + if (myFilesToCompile.length > 0) { + if (application.isUnitTestMode()) { + saveTestData(); + } + + final Map> moduleToFilesMap = buildModuleToFilesMap(myCompileContext, myFilesToCompile); + compileModules(moduleToFilesMap); + } + + dependentFiles = findDependentFiles(); + + if (myCompileContext.getProgressIndicator().isCanceled() || myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + break COMPILE; + } + + if (dependentFiles.length > 0) { + VirtualFile[] filesInScope = getFilesInScope(dependentFiles); + if (filesInScope.length > 0) { + final Map> moduleToFilesMap = buildModuleToFilesMap(myCompileContext, filesInScope); + compileModules(moduleToFilesMap); + } + } + } + catch (IOException e) { + throw new CompilerException("Process not started:\n" + e.getMessage(), e); + } + catch (SecurityException e) { + throw new CompilerException("Compiler not started :" + e.getMessage(), e); + } + catch (IllegalArgumentException e) { + throw new CompilerException(e.getMessage(), e); + } + finally { + myCompileContext.getProgressIndicator().pushState(); + myCompileContext.getProgressIndicator().setText("Deleting temp files..."); + for (Iterator it = myModuleToTempDirMap.keySet().iterator(); it.hasNext();) { + final Module module = it.next(); + final VirtualFile file = myModuleToTempDirMap.get(module); + if (file != null) { + final File ioFile = application.runReadAction(new Computable() { + public File compute() { + return new File(file.getPath()); + } + }); + FileUtil.asyncDelete(ioFile); + } + } + myModuleToTempDirMap.clear(); + myCompileContext.getProgressIndicator().setText("Updating caches..."); + if (mySuccesfullyCompiledJavaFiles.size() > 0 || (dependentFiles != null && dependentFiles.length > 0)) { + myCompileContext.getDependencyCache().update(); + } + myCompileContext.getProgressIndicator().popState(); + } + myFilesToRecompile = new HashSet(Arrays.asList(myFilesToCompile)); + if (dependentFiles != null) { + myFilesToRecompile.addAll(Arrays.asList(dependentFiles)); + } + myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles); + return myOutputItems.toArray(new TranslatingCompiler.OutputItem[myOutputItems.size()]); + } + + private VirtualFile[] getFilesInScope(final VirtualFile[] dependentFiles) { + final List filesInScope = new ArrayList(dependentFiles.length); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < dependentFiles.length; idx++) { + VirtualFile dependentFile = dependentFiles[idx]; + if (myCompileContext.getCompileScope().belongs(dependentFile.getUrl())) { + filesInScope.add(dependentFile); + } + } + } + }); + return filesInScope.toArray(new VirtualFile[filesInScope.size()]); + } + + private void compileModules(final Map> moduleToFilesMap) throws IOException { + final List chunks = getModuleChunks(moduleToFilesMap); + + for (Iterator it = chunks.iterator(); it.hasNext();) { + final ModuleChunk chunk = it.next(); + + runTransformingCompilers(chunk); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Module[] modules = chunk.getModules(); + StringBuffer names = new StringBuffer(); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + if (idx > 0) { + names.append(", "); + } + names.append(module.getName()); + } + myModuleName = names.toString(); + } + }); + + File fileToDelete = null; + final List pairs = new ArrayList(); + if (chunk.getModuleCount() == 1) { // optimization + final Module module = chunk.getModules()[0]; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final String sourcesOutputDir = getOutputDir(module); + if (shouldCompileTestsSeparately(module)) { + if (sourcesOutputDir != null) { + pairs.add(new OutputDir(sourcesOutputDir, ModuleChunk.SOURCES)); + } + final String testsOutputDir = getTestsOutputDir(module); + if (testsOutputDir == null) { + LOG.assertTrue(false, "Tests output dir is null for module \""+module.getName()+"\""); + } + pairs.add(new OutputDir(testsOutputDir, ModuleChunk.TEST_SOURCES)); + } + else { // both sources and test sources go into the same output + if (sourcesOutputDir == null) { + LOG.assertTrue(false, "Sources output dir is null for module \""+module.getName()+"\""); + } + pairs.add(new OutputDir(sourcesOutputDir, ModuleChunk.ALL_SOURCES)); + } + } + }); + } + else { // chunk has several modules + final File outputDir = FileUtil.createTempDirectory("compile", "output"); + fileToDelete = outputDir; + pairs.add(new OutputDir(outputDir.getPath(), ModuleChunk.ALL_SOURCES)); + } + + try { + for (Iterator i = pairs.iterator(); i.hasNext();) { + final OutputDir outputDir = i.next(); + doCompile(chunk, outputDir.getPath(), outputDir.getKind()); + if (myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + return; + } + } + } + finally { + if (fileToDelete != null) { + FileUtil.asyncDelete(fileToDelete); + } + } + } + } + + private List getModuleChunks(final Map> moduleToFilesMap) { + final List modules = new ArrayList(moduleToFilesMap.keySet()); + final List> chunks = ApplicationManager.getApplication().runReadAction(new Computable>>() { + public List> compute() { + return ModuleCompilerUtil.getSortedModuleChunks(myProject, modules.toArray(new Module[modules.size()])); + } + }); + final List moduleChunks = new ArrayList(chunks.size()); + for (Iterator> it = chunks.iterator(); it.hasNext();) { + moduleChunks.add(new ModuleChunk(myCompileContext, it.next(), moduleToFilesMap)); + } + return moduleChunks; + } + + private boolean shouldCompileTestsSeparately(Module module) { + final String moduleTestOutputDirectory = getTestsOutputDir(module); + if (moduleTestOutputDirectory == null) { + return false; + } + final String moduleOutputDirectory = getOutputDir(module); + return !moduleTestOutputDirectory.equals(moduleOutputDirectory); + } + + public VirtualFile[] getFilesToRecompile() { + return myFilesToRecompile.toArray(new VirtualFile[myFilesToRecompile.size()]); + } + + private void saveTestData() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < myFilesToCompile.length; idx++) { + VirtualFile file = myFilesToCompile[idx]; + CompilerManagerImpl.addCompiledPath(file.getPath()); + } + } + }); + } + + private VirtualFile[] findDependentFiles() throws CacheCorruptedException { + myCompileContext.getProgressIndicator().setText("Checking dependencies..."); + final int[] dependentClassInfos = myCompileContext.getDependencyCache().findDependentClasses(myCompileContext, myProject, mySuccesfullyCompiledJavaFiles); + final Set dependentFiles = new HashSet(); + final CacheCorruptedException[] _ex = new CacheCorruptedException[]{null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + SourceFileFinder sourceFileFinder = new SourceFileFinder(myProject, myCompileContext); + final Cache cache = myCompileContext.getDependencyCache().getCache(); + for (int idx = 0; idx < dependentClassInfos.length; idx++) { + final int infoQName = dependentClassInfos[idx]; + final String qualifiedName = myCompileContext.getDependencyCache().resolve(infoQName); + final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, cache.getSourceFileName(cache.getClassId(infoQName))); + if (file != null) { + if (!compilerConfiguration.isExcludedFromCompilation(file)) { + dependentFiles.add(file); + if (ApplicationManager.getApplication().isUnitTestMode()) { + CompilerManagerImpl.addRecompiledPath(file.getPath()); + } + } + } + else { + if (LOG.isDebugEnabled()) { + LOG.debug("No source file for " + myCompileContext.getDependencyCache().resolve(infoQName) + " found"); + } + } + } + } + catch (CacheCorruptedException e) { + _ex[0] = e; + } + } + }); + if (_ex[0] != null) { + throw _ex[0]; + } + myCompileContext.getProgressIndicator().setText("Found " + dependentFiles.size() + " dependent files"); + + VirtualFile[] dependent = dependentFiles.toArray(new VirtualFile[dependentFiles.size()]); + return dependent; + } + + private void doCompile(final ModuleChunk chunk, String outputDir, int sourcesFilter) throws IOException { + chunk.setSourcesFilter(sourcesFilter); + + if (ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + return chunk.getFilesToCompile().length == 0? Boolean.TRUE : Boolean.FALSE; + } + }).equals(Boolean.TRUE)) { + return; // should not invoke javac with empty sources list + } + + final Pair pair; + if (ApplicationManager.getApplication().isUnitTestMode()) { + pair = JavacSettings.getInstance(myProject).isTestsUseExternalCompiler()? runExternalCompiler(chunk, outputDir) : runEmbeddedJavac(chunk, outputDir); + } + else { + if (System.getProperty("idea.use.embedded.javac") != null && System.getProperty("idea.use.embedded.javac").equals("true")) { + pair = runEmbeddedJavac(chunk, outputDir); + } + else { + pair = runExternalCompiler(chunk, outputDir); + } + } + + int exitValue = 0; + try { + Process process = pair.getSecond(); + + final JavaCompilerParsingThread parsingThread = new JavaCompilerParsingThread(process, myCompileContext, pair.getFirst(), this); + myClassParsingThread = new ClassParsingThread(); + myClassParsingThread.start(); + parsingThread.start(); + + try { + exitValue = process.waitFor(); + } + catch (InterruptedException e) { + process.destroy(); + exitValue = process.exitValue(); + } + + try { + parsingThread.join(); + } catch (InterruptedException e) {} + + myClassParsingThread.stopParsing(); + + try { + myClassParsingThread.join(); + } catch (InterruptedException e) {} + + final Throwable error = parsingThread.getError(); + if (error != null) { + String message = error.getMessage(); + if (error instanceof CacheCorruptedException) { + myCompileContext.requestRebuildNextTime(message); + } + else { + myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + } + } + } + finally { + myClassParsingThread = null; + compileFinished(exitValue, chunk, outputDir); + myModuleName = null; + } + } + + private void runTransformingCompilers(final ModuleChunk chunk) { + final Compiler[] transformers = CompilerManager.getInstance(myProject).getCompilers(JavaSourceTransformingCompiler.class); + final Module[] modules = chunk.getModules(); + for (int idx = 0; idx < transformers.length; idx++) { + final JavaSourceTransformingCompiler transformer = (JavaSourceTransformingCompiler)transformers[idx]; + final Map originalToCopyFileMap = new HashMap(); + final Application application = ApplicationManager.getApplication(); + application.invokeAndWait(new Runnable() { + public void run() { + for (int idx = 0; idx < modules.length; idx++) { + final Module module = modules[idx]; + VirtualFile[] filesToCompile = chunk.getFilesToCompile(module); + for (int j = 0; j < filesToCompile.length; j++) { + final VirtualFile file = filesToCompile[j]; + if (transformer.isTransformable(file)) { + application.runWriteAction(new Runnable() { + public void run() { + try { + VirtualFile fileCopy = createFileCopy(getTempDir(module), file); + originalToCopyFileMap.put(file, fileCopy); + } + catch (IOException e) { + // skip it + } + } + }); + } + } + } + } + }, myCompileContext.getProgressIndicator().getModalityState()); + + // do actual transform + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + final VirtualFile[] filesToCompile = chunk.getFilesToCompile(module); + for (int j = 0; j < filesToCompile.length; j++) { + final VirtualFile file = filesToCompile[j]; + VirtualFile fileCopy = originalToCopyFileMap.get(file); + if (fileCopy != null) { + final boolean ok = transformer.transform(myCompileContext, fileCopy, file); + if (ok) { + filesToCompile[j] = fileCopy; + } + } + } + } + } + } + + private VirtualFile createFileCopy(VirtualFile tempDir, final VirtualFile file) throws IOException { + final String fileName = file.getName(); + if (tempDir.findChild(fileName) != null) { + int idx = 0; + while (true) { + final String dirName = "dir" + idx++; + final VirtualFile dir = tempDir.findChild(dirName); + if (dir == null) { + tempDir = tempDir.createChildDirectory(this, dirName); + break; + } + if (dir.findChild(fileName) == null) { + tempDir = dir; + break; + } + } + } + return VfsUtil.copyFile(this, file, tempDir); + } + + private VirtualFile getTempDir(Module module) throws IOException { + VirtualFile tempDir = myModuleToTempDirMap.get(module); + if (tempDir == null) { + final String projectName = myProject.getName(); + final String moduleName = module.getName(); + File tempDirectory = FileUtil.createTempDirectory(projectName, moduleName); + tempDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory); + if (tempDir == null) { + LOG.assertTrue(false, "Cannot locate temp directory " + tempDirectory.getPath() ); + } + myModuleToTempDirMap.put(module, tempDir); + } + return tempDir; + } + + private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) { + if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + myCompileContext.addMessage( + CompilerMessageCategory.ERROR, + "Compiler internal error. Process terminated with exit code " + exitValue, null, -1, + -1 + ); + } + myCompiler.processTerminated(); + final VirtualFile[] sourceRoots = chunk.getSourceRoots(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Set compiledWithErrors = getFilesCompiledWithErrors(); + final FileTypeManager typeManager = FileTypeManager.getInstance(); + final String outputDirPath = outputDir.replace(File.separatorChar, '/'); + for (int idx = 0; idx < sourceRoots.length; idx++) { + final VirtualFile root = sourceRoots[idx]; + buildOutputItemsList(outputDirPath, root, typeManager, compiledWithErrors, root, myProjectFileIndex.getPackageNameByDirectory(root)); + } + } + }); + CompilerUtil.refreshIOFiles(myFilesToRefresh.toArray(new File[myFilesToRefresh.size()])); + myFileNameToSourceMap.clear(); // clear the map before the next use + myFilesToRefresh.clear(); + } + + private Pair runExternalCompiler(final ModuleChunk chunk, final String outputDir) throws IOException, IllegalArgumentException{ + final String[] commands = myCompiler.createStartupCommand(chunk, myCompileContext, outputDir); + + if (LOG.isDebugEnabled()) { + StringBuffer buf = new StringBuffer(32); + for (int idx = 0; idx < commands.length; idx++) { + String command = commands[idx]; + buf.append(command); + buf.append(" "); + } + LOG.debug(buf.toString()); + } + + final Process process = Runtime.getRuntime().exec(commands); + return new Pair(myCompiler.createOutputParser(), process); + } + + private Pair runEmbeddedJavac(final ModuleChunk chunk, final String outputDir) throws IOException, IllegalArgumentException { + final String[] commands = myCompiler.createStartupCommand(chunk, myCompileContext, outputDir); + List modifiedCommands = new ArrayList(); + int index = commands.length; + boolean cpKeywordDetected = false; + for (int idx = 0; idx < commands.length; idx++) { + String command = commands[idx]; + if ("com.sun.tools.javac.Main".equals(command)) { + index = idx; + } + else { + if (idx > index) { + if (cpKeywordDetected) { + cpKeywordDetected = false; + if (command.startsWith("@")) { // expand classpath if neccesary + command = JavacRunner.readClasspath(command.substring(1)); + } + } + else if ("-classpath".equals(command) || "-cp".equals(command)){ + cpKeywordDetected = true; + } + modifiedCommands.add(command); + } + } + } + + OutputParser outputParser = myCompiler.createOutputParser(); + + final PipedInputStream in = new PipedInputStream(); + PipedOutputStream out = new PipedOutputStream(in); + final PrintWriter writer = new PrintWriter(out); + + final String[] strings = modifiedCommands.toArray(new String[modifiedCommands.size()]); + + return new Pair(outputParser, new Process() { + public OutputStream getOutputStream() { + throw new UnsupportedOperationException("Not Implemented in: " + getClass().getName()); + } + + public InputStream getInputStream() { + throw new UnsupportedOperationException("Not Implemented in: " + getClass().getName()); + } + + public void destroy() { + // is thrown in tests + //throw new UnsupportedOperationException("Not Implemented in: " + getClass().getName()); + } + + public int waitFor() { + myExitCode = com.sun.tools.javac.Main.compile(strings, writer); + writer.println(JavaCompilerParsingThread.TERMINATION_STRING); + writer.flush(); + + return myExitCode; + } + + public InputStream getErrorStream() { + return in; + } + + public int exitValue() { + return myExitCode; + } + }); + } + + private Set getFilesCompiledWithErrors() { + CompilerMessage[] messages = myCompileContext.getMessages(CompilerMessageCategory.ERROR); + Set compiledWithErrors = Collections.EMPTY_SET; + if (messages.length > 0) { + compiledWithErrors = new HashSet(); + for (int idx = 0; idx < messages.length; idx++) { + CompilerMessage message = messages[idx]; + final VirtualFile file = message.getVirtualFile(); + if (file != null) { + compiledWithErrors.add(file); + } + } + } + return compiledWithErrors; + } + + private void buildOutputItemsList(final String outputDir, VirtualFile from, FileTypeManager typeManager, Set compiledWithErrors, final VirtualFile sourceRoot, final String packagePrefix) { + final VirtualFile[] children = from.getChildren(); + for (int idx = 0; idx < children.length; idx++) { + final VirtualFile child = children[idx]; + if (child.isDirectory()) { + buildOutputItemsList(outputDir, child, typeManager, compiledWithErrors, sourceRoot, packagePrefix); + } + else { + if (StdFileTypes.JAVA.equals(typeManager.getFileTypeByFile(child))) { + updateOutputItemsList(outputDir, child, compiledWithErrors, sourceRoot, packagePrefix); + } + } + } + } + + protected final void processCompiledClass(String path) throws CacheCorruptedException { + myClassParsingThread.addPath(path); + } + + private void putName(String sourceFileName, String relativePathToSource, String pathToClass) { + Set> paths = myFileNameToSourceMap.get(sourceFileName); + + if (paths == null) { + paths = new HashSet>(); + myFileNameToSourceMap.put(sourceFileName, paths); + } + paths.add(new Pair(pathToClass, relativePathToSource)); + } + + private void updateOutputItemsList(final String outputDir, VirtualFile javaFile, Set compiledWithErrors, VirtualFile sourceRoot, final String packagePrefix) { + String name = javaFile.getName(); + if (myFileNameToSourceMap.containsKey(name)) { + Set> paths = myFileNameToSourceMap.get(name); + + if (paths != null && paths.size() > 0) { + final String prefix = packagePrefix != null && packagePrefix.length() > 0? packagePrefix.replace('.', '/') + "/" : ""; + final String filePath = !SystemInfo.isFileSystemCaseSensitive ? + "/" + CompilerUtil.normalizePath(prefix + VfsUtil.getRelativePath(javaFile, sourceRoot, '/'), '/') : + "/" + prefix + VfsUtil.getRelativePath(javaFile, sourceRoot, '/'); + for (Iterator> it = paths.iterator(); it.hasNext();) { + final Pair pair = it.next(); + if (filePath.equals(pair.getSecond())) { + final String outputPath = pair.getFirst().replace(File.separatorChar, '/'); + final Pair realLocation = moveToRealLocation(outputDir, outputPath, javaFile); + if (realLocation != null) { + myOutputItems.add(new OutputItemImpl(realLocation.getFirst(), realLocation.getSecond(), javaFile)); + if (!compiledWithErrors.contains(javaFile)) { + mySuccesfullyCompiledJavaFiles.add(javaFile); + } + } + } + } + } + } + } + + private Pair moveToRealLocation(String tempOutputDir, String pathToClass, VirtualFile sourceFile) { + final Module module = myCompileContext.getModuleByFile(sourceFile); + if (module == null) { + // do not move: looks like source file has been invalidated, need recompilation + return null; + } + final String realOutputDir; + if (myProjectFileIndex.isInTestSourceContent(sourceFile)) { + realOutputDir = getTestsOutputDir(module); + } + else { + realOutputDir = getOutputDir(module); + } + + if (tempOutputDir.equals(realOutputDir)) { // no need to move + myFilesToRefresh.add(new File(pathToClass)); + return new Pair(realOutputDir, pathToClass); + } + + final String realPathToClass = realOutputDir + pathToClass.substring(tempOutputDir.length()); + final File fromFile = new File(pathToClass); + final File toFile = new File(realPathToClass); + + boolean success = fromFile.renameTo(toFile); + if (!success) { + // assuming cause of the fail: intermediate dirs do not exist + final File parentFile = toFile.getParentFile(); + if (parentFile != null) { + parentFile.mkdirs(); + success = fromFile.renameTo(toFile); // retry after making non-existent dirs + } + } + if (!success) { // failed to move the file: e.g. because source and destination reside on different mountpoints. + try { + FileUtil.copy(fromFile, toFile); + FileUtil.delete(fromFile); + success = true; + } + catch (IOException e) { + LOG.info(e); + success = false; + } + } + if (success) { + myFilesToRefresh.add(toFile); + return new Pair(realOutputDir, realPathToClass); + } + return null; + } + + private final Map myModuleToTestsOutput = new HashMap(); + private String getTestsOutputDir(final Module module) { + if (myModuleToTestsOutput.containsKey(module)) { + return myModuleToTestsOutput.get(module); + } + final VirtualFile outputDir = myCompileContext.getModuleOutputDirectoryForTests(module); + final String out = outputDir != null? outputDir.getPath() : null; + myModuleToTestsOutput.put(module, out); + return out; + } + + private final Map myModuleToOutput = new HashMap(); + private String getOutputDir(final Module module) { + if (myModuleToOutput.containsKey(module)) { + return myModuleToOutput.get(module); + } + final VirtualFile outputDir = myCompileContext.getModuleOutputDirectory(module); + final String out = outputDir != null? outputDir.getPath() : null; + myModuleToOutput.put(module, out); + return out; + } + + private int myFilesCount = 0; + private int myClassesCount = 0; + private String myModuleName = null; + + public void sourceFileProcessed() { + myFilesCount += 1; + updateStatistics(); + } + + private void updateStatistics() { + final StringBuffer buf = new StringBuffer(64); + buf.append("Files: ").append(myFilesCount).append(" - Classes: ").append(myClassesCount); + if (myModuleName != null) { + buf.append(" - Module: ").append(myModuleName); + } + myCompileContext.getProgressIndicator().setText2(buf.toString()); + } + + private static Map> buildModuleToFilesMap(final CompileContext context, final VirtualFile[] files) { + final Map> map = new com.intellij.util.containers.HashMap>(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < files.length; idx++) { + VirtualFile file = files[idx]; + final Module module = context.getModuleByFile(file); + + if (module == null) { + continue; // looks like file invalidated + } + + Set moduleFiles = map.get(module); + if (moduleFiles == null) { + moduleFiles = new HashSet(); + map.put(module, moduleFiles); + } + moduleFiles.add(file); + } + } + }); + return map; + } + + private class ClassParsingThread extends Thread { + private final List myPaths = new LinkedList(); + private CacheCorruptedException myError = null; + private boolean myStopped = false; + + public ClassParsingThread() { + super("Class Parsing Thread"); + } + + public void run() { + try { + while (shouldProceed()) { + for (String path = getNextPath(); path != null; path = getNextPath()) { + processPath(path.replace('/', File.separatorChar)); + } + try { + Thread.sleep(5); + } + catch (InterruptedException ignored) { + } + } + } + catch (CacheCorruptedException e) { + myError = e; + } + } + + public synchronized void addPath(String path) throws CacheCorruptedException { + if (myError != null) { + throw myError; + } + myPaths.add(path); + } + + private synchronized String getNextPath() { + if (myPaths.size() == 0) { + return null; + } + return myPaths.remove(0); + } + + public synchronized void stopParsing() { + myStopped = true; + } + + public synchronized boolean shouldProceed() { + if (myError != null) { + return false; + } + if (myPaths.size() > 0) { + return true; + } + return !myStopped; + } + + private void processPath(final String path) throws CacheCorruptedException { + try { + final File file = new File(path); // the file is assumed to exist! + final int newClassQName = myCompileContext.getDependencyCache().reparseClassFile(file); + final Cache newClassesCache = myCompileContext.getDependencyCache().getNewClassesCache(); + final String sourceFileName = newClassesCache.getSourceFileName(newClassesCache.getClassId(newClassQName)); + String relativePathToSource = "/" + MakeUtil.createRelativePathToSource(myCompileContext.getDependencyCache().resolve(newClassQName), sourceFileName); + putName(sourceFileName, relativePathToSource, path); + } + catch (ClsFormatException e) { + String message; + final String m = e.getMessage(); + if (m == null || "".equals(m)) { + message = "Bad class file format:\n" + path; + } + else { + message = "Bad class file format: " + m + "\n" + path; + } + myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + } + finally { + myClassesCount += 1; + updateStatistics(); + } + } + } + + private static class OutputDir { + private final String myPath; + private final int myKind; + + public OutputDir(String path, int kind) { + myPath = path; + myKind = kind; + } + + public String getPath() { + return myPath; + } + + public int getKind() { + return myKind; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof OutputDir)) { + return false; + } + + final OutputDir outputDir = (OutputDir)o; + + if (myKind != outputDir.myKind) { + return false; + } + if (!myPath.equals(outputDir.myPath)) { + return false; + } + + return true; + } + + public int hashCode() { + int result; + result = myPath.hashCode(); + result = 29 * result + myKind; + return result; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java new file mode 100644 index 00000000000..d0531bcd79b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -0,0 +1,140 @@ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.OutputParser; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public abstract class CompilerParsingThread extends Thread implements OutputParser.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompilerParsingThread"); + public static final String TERMINATION_STRING = "__terminate_read__"; + private Reader myErrorStreamReader; + private Process myProcess; + private OutputParser myOutputParser; + private boolean mySkipLF = false; + private Throwable myError = null; + private final boolean myIsUnitTestMode; + private String myClassFileToProcess = null; + + public CompilerParsingThread(Process process, OutputParser outputParser, final boolean readErrorStream) { + myProcess = process; + myOutputParser = outputParser; + myErrorStreamReader = new BufferedReader(new InputStreamReader(readErrorStream? process.getErrorStream() : process.getInputStream()), 16384); + myIsUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); + } + + public void run() { + try { + while(true){ + if (!myIsUnitTestMode && myProcess == null) { + break; + } + if(!myOutputParser.processMessageLine(this)) { + break; + } + if (isCancelled()) { + killProcess(); + break; + } + } + if (myClassFileToProcess != null) { + processCompiledClass(myClassFileToProcess); + myClassFileToProcess = null; + } + } + catch (Throwable e) { + myError = e; + e.printStackTrace(); + killProcess(); + } + killProcess(); + } + + private void killProcess() { + if (myProcess != null) { + myProcess.destroy(); + myProcess = null; + } + } + + public Throwable getError() { + return myError; + } + + public final String getNextLine() { + try { + final String line = readLine(myErrorStreamReader); + //System.out.println("Line read: " + line); + return TERMINATION_STRING.equals(line)? null : line; + } + catch(IOException e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + return null; + } + } + + public final void fileGenerated(String path) { + String previousPath = myClassFileToProcess; + myClassFileToProcess = path; + if (previousPath != null) { + try { + processCompiledClass(previousPath); + } + catch (CacheCorruptedException e) { + myError = e; + killProcess(); + } + } + } + + public abstract void setProgressText(String text); + + public abstract void fileProcessed(String path); + + public abstract void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum); + + protected abstract boolean isCancelled(); + + protected abstract void processCompiledClass(final String classFileToProcess) throws CacheCorruptedException; + + + private String readLine(final Reader reader) throws IOException { + boolean first = true; + StringBuffer buffer = new StringBuffer(); + while(true){ + int c = reader.read(); + if (c == -1) break; + first = false; + if (c == '\n'){ + if (mySkipLF){ + mySkipLF = false; + continue; + } + break; + } + else if (c == '\r'){ + mySkipLF = true; + break; + } + else{ + mySkipLF = false; + buffer.append((char)c); + } + } + if (first) return null; + String s = buffer.toString(); + return s; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java new file mode 100644 index 00000000000..02449a3ec26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.application.ApplicationManager; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.File; +import java.util.List; +import java.util.ArrayList; + +/** + * @author Eugene Zhuravlev + * Date: Oct 9, 2004 + */ +public class DummySourceGeneratingCompiler implements SourceGeneratingCompiler{ + public static final String MODULE_NAME = "generated"; + private final Project myProject; + + public DummySourceGeneratingCompiler(Project project) { + myProject = project; + } + + public GenerationItem[] getGenerationItems(CompileContext context) { + final Module module = findMyModule(); + return new GenerationItem[] { + new MyGenerationItem("aaa/p1.properties", module), + new MyGenerationItem("bbb/p2.properties", module), + new MyGenerationItem("bbb/ccc/p3.properties", module) + }; + } + + private Module findMyModule() { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Module compute() { + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + if (MODULE_NAME.equals(module.getName())) { + return module; + } + } + return null; + } + }); + } + + public GenerationItem[] generate(CompileContext context, GenerationItem[] items, final VirtualFile outputRootDirectory) { + final String rootPath = ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return outputRootDirectory.getPath(); + } + }); + final List success = new ArrayList(); + for (int idx = 0; idx < items.length; idx++) { + try { + GenerationItem item = items[idx]; + File file = new File(rootPath + File.separator + item.getPath()); + file.getParentFile().mkdirs(); + file.createNewFile(); + success.add(item); + } + catch (IOException e) { + } + } + return success.toArray(new GenerationItem[success.size()]); + } + + public String getDescription() { + return "Dummy Source Generator"; + } + + public boolean validateConfiguration(CompileScope scope) { + return findMyModule() != null; + } + + public ValidityState createValidityState(DataInputStream is) throws IOException { + return null; + } + + private static class MyGenerationItem implements GenerationItem { + private final String myRelPath; + private final Module myModule; + + public MyGenerationItem(String relPath, Module module) { + myRelPath = relPath; + myModule = module; + } + + public String getPath() { + return myRelPath; + } + + public ValidityState getValidityState() { + return null; + } + + public Module getModule() { + return myModule; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java new file mode 100644 index 00000000000..a5e56a3d803 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.openapi.compiler.JavaSourceTransformingCompiler; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Computable; + +import java.io.*; + +/** + * @author Eugene Zhuravlev + * Date: Jul 10, 2004 + */ +public class DummyTransformingCompiler implements JavaSourceTransformingCompiler{ + public boolean isTransformable(VirtualFile file) { + return "A.java".equals(file.getName()); + } + + public boolean transform(CompileContext context, final VirtualFile file, VirtualFile originalFile) { + System.out.println("DummyTransformingCompiler.transform"); + final String url = ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return file.getPresentableUrl(); + } + }); + context.getProgressIndicator().setText("Transforming file: " + url); + try { + FileOutputStream fos = new FileOutputStream(new File(url)); + DataOutput out = new DataOutputStream(fos); + out.writeBytes("package a; "); + out.writeBytes("public class A { public static void main(String[] args) { System.out.println(\"Hello from modified class\");} }"); + fos.close(); + return true; + } + catch (FileNotFoundException e) { + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + } + catch (IOException e) { + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + } + return false; + } + + public String getDescription() { + return "a dummy compiler for testing"; + } + + public boolean validateConfiguration(CompileScope scope) { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java new file mode 100644 index 00000000000..1d47c737d51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java @@ -0,0 +1,90 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 17, 2003 + * Time: 3:22:59 PM + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerException; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.compiler.TranslatingCompiler; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.compiler.ex.CompileContextEx; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public class JavaCompiler implements TranslatingCompiler { + private Project myProject; + private BackendCompiler JAVAC_BACKEND; + private BackendCompiler JIKES_BACKEND; + + public JavaCompiler(Project project) { + myProject = project; + JAVAC_BACKEND = new JavacCompiler(project); + JIKES_BACKEND = new JikesCompiler(project); + } + + public String getDescription() { + return "Java Compiler"; + } + + public boolean isCompilableFile(VirtualFile file, CompileContext context) { + return FileTypeManager.getInstance().getFileTypeByFile(file).equals(StdFileTypes.JAVA); + } + + public ExitStatus compile(CompileContext context, VirtualFile[] files) { + final BackendCompiler backEndCompiler = getBackEndCompiler(); + final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(myProject, files, (CompileContextEx)context, backEndCompiler); + TranslatingCompiler.OutputItem[] outputItems = TranslatingCompiler.EMPTY_OUTPUT_ITEM_ARRAY; + try { + outputItems = wrapper.compile(); + } + catch (CompilerException e) { + outputItems = TranslatingCompiler.EMPTY_OUTPUT_ITEM_ARRAY; + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + } + catch (CacheCorruptedException e) { + context.requestRebuildNextTime(e.getMessage()); + } + + return new ExitStatusImpl(outputItems, wrapper.getFilesToRecompile()); + } + + public boolean validateConfiguration(CompileScope scope) { + return getBackEndCompiler().checkCompiler(); + } + + private BackendCompiler getBackEndCompiler() { + CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject); + if (CompilerConfiguration.JIKES.equals(configuration.getDefaultCompiler())) { + return JIKES_BACKEND; + } + else { + return JAVAC_BACKEND; + } + } + + private static class ExitStatusImpl implements ExitStatus { + + private OutputItem[] myOuitputItems; + private VirtualFile[] myMyFilesToRecompile; + + public ExitStatusImpl(TranslatingCompiler.OutputItem[] ouitputItems, VirtualFile[] myFilesToRecompile) { + myOuitputItems = ouitputItems; + myMyFilesToRecompile = myFilesToRecompile; + } + + public TranslatingCompiler.OutputItem[] getSuccessfullyCompiled() { + return myOuitputItems; + } + + public VirtualFile[] getFilesToRecompile() { + return myMyFilesToRecompile; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavacCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavacCompiler.java new file mode 100644 index 00000000000..8196971f784 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JavacCompiler.java @@ -0,0 +1,328 @@ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.JavacOutputParser; +import com.intellij.compiler.JavacSettings; +import com.intellij.compiler.OutputParser; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.ide.util.generics.GenericsSetupUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ex.PathUtilEx; +import com.intellij.openapi.projectRoots.impl.MockJdkWrapper; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.pom.java.LanguageLevel; + +import java.io.*; +import java.util.*; + +class JavacCompiler implements BackendCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavacCompiler"); + private Project myProject; + private final List myTempFiles = new ArrayList(); + + public boolean checkCompiler() { + final Module[] modules = ModuleManager.getInstance(myProject).getModules(); + Set checkedJdks = new HashSet(); + for (int idx = 0; idx < modules.length; idx++) { + final Module module = modules[idx]; + final ProjectJdk jdk = ModuleRootManager.getInstance(module).getJdk(); + if (jdk == null) { + continue; + } + if (checkedJdks.contains(jdk)) { + continue; + } + final VirtualFile homeDirectory = jdk.getHomeDirectory(); + if (homeDirectory == null) { + Messages.showMessageDialog(myProject, "Cannot determine home directory for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n", "Broken JDK Configuration", Messages.getErrorIcon()); + return false; + } + final String vmExecutablePath = jdk.getVMExecutablePath(); + if (vmExecutablePath == null) { + Messages.showMessageDialog(myProject, "Cannot obtain path to VM executable for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n", "Broken JDK Configuration", Messages.getErrorIcon()); + return false; + } + final String toolsJarPath = jdk.getToolsPath(); + if (toolsJarPath == null) { + Messages.showMessageDialog(myProject, "Cannot obtain path javac classes for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n", "Broken JDK Configuration", Messages.getErrorIcon()); + return false; + } + final String versionString = jdk.getVersionString(); + if (versionString == null) { + Messages.showMessageDialog(myProject, "Cannot determine version for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n", "Unknown JDK Version", Messages.getErrorIcon()); + return false; + } + if (isOfVersion(versionString, "1.0")) { + Messages.showMessageDialog(myProject, "Compilation is not supported for JDK 1.0", "Unsupported Compiler Version", Messages.getErrorIcon()); + return false; + } + if (shouldUseJSR14Compiler(versionString)) { + final File collectionsJar = GenericsSetupUtil.getGenericsJar("collect.jar", myProject); + if (!collectionsJar.exists()) { + Messages.showMessageDialog(myProject, collectionsJar.getPath() + " not found", "Compiler Classes Not Found", Messages.getErrorIcon()); + return false; + } + final File gjcJar = GenericsSetupUtil.getGenericsJar("gjc-rt.jar", myProject); + if (!gjcJar.exists()) { + Messages.showMessageDialog(myProject, gjcJar.getPath() + " not found", "Compiler Classes Not Found", Messages.getErrorIcon()); + return false; + } + } + checkedJdks.add(jdk); + } + + return true; + } + + private boolean shouldUseJSR14Compiler(String versionString) { + return isOfVersion(versionString, "1.4")? JavacSettings.getInstance(myProject).USE_GENERICS_COMPILER : false; + } + + public JavacCompiler(Project project) { + myProject = project; + } + + public OutputParser createOutputParser() { + return new JavacOutputParser(myProject); + } + + public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath) + throws IOException, IllegalArgumentException { + + final ArrayList commandLine = new ArrayList(); + + final Exception[] ex = new Exception[]{null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + _createStartupCommand(chunk, commandLine, outputPath); + } + catch (IllegalArgumentException e) { + ex[0] = e; + } + catch (IOException e) { + ex[0] = e; + } + } + }); + if (ex[0] != null) { + if (ex[0] instanceof IOException) { + throw (IOException)ex[0]; + } + else if (ex[0] instanceof IllegalArgumentException) { + throw (IllegalArgumentException)ex[0]; + } + else { + LOG.error(ex[0]); + } + } + return commandLine.toArray(new String[commandLine.size()]); + } + + private void _createStartupCommand(final ModuleChunk chunk, final ArrayList commandLine, final String outputPath) throws IOException { + final ProjectJdk jdk = getJdkForStartupCommand(chunk); + final String versionString = jdk.getVersionString(); + if (versionString == null || "".equals(versionString)) { + throw new IllegalArgumentException( + "Cannot determine version for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n"); + } + final boolean isVersion1_0 = isOfVersion(versionString, "1.0"); + final boolean isVersion1_1 = isOfVersion(versionString, "1.1"); + final boolean isVersion1_4 = isOfVersion(versionString, "1.4"); + final boolean isVersion1_5 = isOfVersion(versionString, "1.5") || isOfVersion(versionString, "5.0"); + + final JavacSettings javacSettings = JavacSettings.getInstance(myProject); + + final String vmExePath = jdk.getVMExecutablePath(); + + commandLine.add(vmExePath); + if (isVersion1_1 || isVersion1_0) { + commandLine.add("-mx" + javacSettings.MAXIMUM_HEAP_SIZE + "m"); + } + else { + commandLine.add("-Xmx" + javacSettings.MAXIMUM_HEAP_SIZE + "m"); + } + + final String javacLocation = GenericsSetupUtil.getGenericsJar("gjc-rt.jar", myProject).getPath(); + final boolean useJSR14Compiler = shouldUseJSR14Compiler(versionString); + if (useJSR14Compiler) { + commandLine.add("-Xbootclasspath/p:" + javacLocation); + } + + commandLine.add("-classpath"); + + String vmCp; + if (useJSR14Compiler) { + vmCp = javacLocation; + } + else { + vmCp = jdk.getToolsPath(); + } + + if (isVersion1_0) { + commandLine.add(vmCp); // do not use JavacRunner for jdk 1.0 + } + else { + vmCp += File.pathSeparator + PathUtilEx.getIdeaRtJarPath(); + commandLine.add(vmCp); + commandLine.add(com.intellij.rt.compiler.JavacRunner.class.getName()); + commandLine.add("\"" + versionString + "\""); + } + + if (isOfVersion(versionString, "1.2") || isVersion1_1 || isVersion1_0) { + commandLine.add("sun.tools.javac.Main"); + } + else { + commandLine.add("com.sun.tools.javac.Main"); + } + + if (useJSR14Compiler) { + commandLine.add("-bootclasspath"); + final String rtJarPath = jdk.getRtLibraryPath(); + commandLine.add(GenericsSetupUtil.getGenericsJar("collect.jar", myProject).getPath() + File.pathSeparator + rtJarPath); + } + + final LanguageLevel applicableLanguageLevel = getApplicableLanguageLevel(versionString); + if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_5)) { + commandLine.add("-source"); + commandLine.add("1.5"); + } + else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_4)) { + commandLine.add("-source"); + commandLine.add("1.4"); + } + else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_3)) { + if (isVersion1_4 || isVersion1_5) { + commandLine.add("-source"); + commandLine.add("1.3"); + } + } + + commandLine.add("-verbose"); + commandLine.add("-classpath"); + + // must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not + final String cp = chunk.getCompilationClasspath(); + if (isVersion1_0) { + commandLine.add(jdk.getToolsPath() + File.pathSeparator + cp); + } + else { + File cpFile = FileUtil.createTempFile("javac_cp", ".tmp"); + cpFile.deleteOnExit(); + myTempFiles.add(cpFile); + PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(cpFile))); + writer.println(cp); + writer.close(); + commandLine.add("@" + cpFile.getAbsolutePath()); + } + + if (!isVersion1_1 && !isVersion1_0) { + commandLine.add("-sourcepath"); + // this way we tell the compiler that the sourcepath is "empty". However, javac thinks that sourcepath is 'new File("")' + // this may cause problems if we have java code in IDEA working directory + commandLine.add("\"\""); + } + + commandLine.add("-d"); + commandLine.add(outputPath.replace('/', File.separatorChar)); + + StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(), " "); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if (isVersion1_0) { + if ("-deprecation".equals(token)) { + continue; // not supported for this version + } + } + commandLine.add(token); + } + + final VirtualFile[] files = chunk.getFilesToCompile(); + + if (isVersion1_0) { + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + String path = file.getPath(); + if (LOG.isDebugEnabled()) { + LOG.debug("Adding path for compilation " + path); + } + commandLine.add(CompilerUtil.quotePath(path)); + } + } + else { + File sourcesFile = FileUtil.createTempFile("javac", ".tmp"); + sourcesFile.deleteOnExit(); + myTempFiles.add(sourcesFile); + PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(sourcesFile))); + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + // Important: should use "/" slashes! + // but not for JDK 1.5 - see SCR 36673 + final String path = isVersion1_5? file.getPath().replace('/', File.separatorChar) : file.getPath(); + if (LOG.isDebugEnabled()) { + LOG.debug("Adding path for compilation " + path); + } + writer.println(isVersion1_1? path : CompilerUtil.quotePath(path)); + } + writer.close(); + commandLine.add("@" + sourcesFile.getAbsolutePath()); + } + } + + private ProjectJdk getJdkForStartupCommand(final ModuleChunk chunk) { + final ProjectJdk jdk = chunk.getJdk(); + if (ApplicationManager.getApplication().isUnitTestMode() && JavacSettings.getInstance(myProject).isTestsUseExternalCompiler()) { + final String jdkHomePath = System.getProperty(CompilerConfiguration.TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME, null); + if (jdkHomePath == null) { + throw new IllegalArgumentException("[TEST-MODE] Cannot determine home directory for JDK to use javac from"); + } + // when running under Mock JDK use VM executable from the JDK on which the tests run + return new MockJdkWrapper(jdkHomePath, jdk); + } + return jdk; + } + + private LanguageLevel getApplicableLanguageLevel(String versionString) { + LanguageLevel languageLevel = ProjectRootManagerEx.getInstanceEx(myProject).getLanguageLevel(); + + final boolean isVersion1_5 = isOfVersion(versionString, "1.5") || isOfVersion(versionString, "5.0"); + if (LanguageLevel.JDK_1_5.equals(languageLevel)) { + if (!isVersion1_5) { + if (!shouldUseJSR14Compiler(versionString)) { + languageLevel = LanguageLevel.JDK_1_4; + } + } + } + + if (LanguageLevel.JDK_1_4.equals(languageLevel)) { + if (!isOfVersion(versionString, "1.4") && !isVersion1_5) { + languageLevel = LanguageLevel.JDK_1_3; + } + } + + return languageLevel; + } + + private static boolean isOfVersion(String versionString, String checkedVersion) { + return versionString.indexOf(checkedVersion) > -1; + } + + public void processTerminated() { + if (myTempFiles.size() > 0) { + for (Iterator it = myTempFiles.iterator(); it.hasNext();) { + FileUtil.delete((File)it.next()); + } + myTempFiles.clear(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JikesCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JikesCompiler.java new file mode 100644 index 00000000000..204025c2b79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/JikesCompiler.java @@ -0,0 +1,196 @@ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.JikesOutputParser; +import com.intellij.compiler.JikesSettings; +import com.intellij.compiler.OutputParser; +import com.intellij.compiler.options.CompilerConfigurable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.StringTokenizer; + +class JikesCompiler implements BackendCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.JikesHandler"); + private Project myProject; + private File myTempFile; + + public JikesCompiler(Project project) { + myProject = project; + } + + public boolean checkCompiler() { + String compilerPath = getCompilerPath(); + if (compilerPath == null) { + Messages.showMessageDialog( + myProject, + "Cannot start Jikes compiler.\n" + + "The path to compiler executable is not configured", + "Error", + Messages.getErrorIcon() + ); + openConfigurationDialog(); + compilerPath = this.getCompilerPath(); // update path + if (compilerPath == null) { + return false; + } + } + + File file = new File(compilerPath); + if (!file.exists()) { + Messages.showMessageDialog( + myProject, + "Cannot start Jikes compiler.\n" + + "The file " + compilerPath + " not found.", + "Error", + Messages.getErrorIcon() + ); + openConfigurationDialog(); + compilerPath = this.getCompilerPath(); // update path + if (compilerPath == null) { + return false; + } + if (!new File(compilerPath).exists()) { + return false; + } + } + + return true; + } + + private void openConfigurationDialog() { + ShowSettingsUtil.getInstance().editConfigurable(myProject, CompilerConfigurable.getInstance(myProject)); + } + + public String getCompilerPath() { + return JikesSettings.getInstance(myProject).JIKES_PATH.replace('/', File.separatorChar); + } + + public OutputParser createOutputParser() { + return new JikesOutputParser(myProject); + } + + public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath) + throws IOException { + + final ArrayList commandLine = new ArrayList(); + final IOException[] ex = new IOException[]{null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + _createStartupCommand(chunk, commandLine, outputPath); + } + catch (IOException e) { + ex[0] = e; + } + } + }); + if (ex[0] != null) { + throw ex[0]; + } + String[] commands = (String[])commandLine.toArray(new String[commandLine.size()]); + return commands; + } + + private void _createStartupCommand(final ModuleChunk chunk, final ArrayList commandLine, final String outputPath) throws IOException { + + myTempFile = File.createTempFile("jikes", ".tmp"); + myTempFile.deleteOnExit(); + + final VirtualFile[] files = chunk.getFilesToCompile(); + PrintWriter writer = new PrintWriter(new FileWriter(myTempFile)); + for (int i = 0; i < files.length; i++) { + writer.println(files[i].getPath()); + } + writer.close(); + + String compilerPath = getCompilerPath(); + LOG.assertTrue(compilerPath != null, "No path to compiler configured"); + + commandLine.add(compilerPath); + + commandLine.add("-verbose"); + commandLine.add("-classpath"); + + // must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not + commandLine.add(chunk.getCompilationClasspath()); + + setupSourceVersion(chunk, commandLine); + commandLine.add("-sourcepath"); + String sourcePath = chunk.getSourcePath(); + if (sourcePath.length() > 0) { + commandLine.add(sourcePath); + } + else { + commandLine.add("\"\""); + } + + commandLine.add("-d"); + LOG.assertTrue(outputPath != null); + commandLine.add(outputPath.replace('/', File.separatorChar)); + + JikesSettings jikesSettings = JikesSettings.getInstance(myProject); + StringTokenizer tokenizer = new StringTokenizer(jikesSettings.getOptionsString(), " "); + while (tokenizer.hasMoreTokens()) { + commandLine.add(tokenizer.nextToken()); + } + commandLine.add("@" + myTempFile.getAbsolutePath()); + } + + private void setupSourceVersion(final ModuleChunk chunk, final ArrayList commandLine) { + final ProjectJdk jdk = chunk.getJdk(); + final String versionString = jdk.getVersionString(); + + final LanguageLevel applicableLanguageLevel = getApplicableLanguageLevel(versionString); + if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_5)) { + commandLine.add("-source"); + commandLine.add("1.4"); // -source 1.5 not supported yet by jikes, so use the highest possible version + } + else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_4)) { + commandLine.add("-source"); + commandLine.add("1.4"); + } + } + + private LanguageLevel getApplicableLanguageLevel(String versionString) { + LanguageLevel languageLevel = ProjectRootManagerEx.getInstanceEx(myProject).getLanguageLevel(); + + if (LanguageLevel.JDK_1_5.equals(languageLevel)) { + if (!(isOfVersion(versionString, "1.5") || isOfVersion(versionString, "5.0"))) { + languageLevel = LanguageLevel.JDK_1_4; + } + } + + if (LanguageLevel.JDK_1_4.equals(languageLevel)) { + if (!isOfVersion(versionString, "1.4") && !isOfVersion(versionString, "1.5") && !isOfVersion(versionString, "5.0")) { + languageLevel = LanguageLevel.JDK_1_3; + } + } + + return languageLevel; + } + + public void processTerminated() { + if (myTempFile != null) { + myTempFile.delete(); + myTempFile = null; + } + } + + private static boolean isOfVersion(String versionString, String checkedVersion) { + return versionString.indexOf(checkedVersion) > -1; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java new file mode 100644 index 00000000000..12e4896e752 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.compiler.Chunk; +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PathUtil; +import com.intellij.util.containers.OrderedSet; +import gnu.trove.TObjectHashingStrategy; + +import java.io.File; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Sep 29, 2004 + */ +public class ModuleChunk extends Chunk { + private final CompileContext myContext; + private final Map myModuleToFilesMap = new HashMap(); + private int mySourcesFilter = ALL_SOURCES; + + public ModuleChunk(CompileContext context, Chunk chunk, Map> moduleToFilesMap) { + super(chunk.getNodes()); + myContext = context; + for (Iterator it = chunk.getNodes().iterator(); it.hasNext();) { + final Module module = it.next(); + final Set set = moduleToFilesMap.get(module); + if (set != null && set.size() > 0) { + myModuleToFilesMap.put(module, set.toArray(new VirtualFile[set.size()])); + } + else { + myModuleToFilesMap.put(module, VirtualFile.EMPTY_ARRAY); + } + } + } + + public static final int SOURCES = 0x1; + public static final int TEST_SOURCES = 0x2; + public static final int ALL_SOURCES = SOURCES | TEST_SOURCES; + + public void setSourcesFilter(int filter) { + mySourcesFilter = filter; + } + + public VirtualFile[] getFilesToCompile(Module forModule) { + return myModuleToFilesMap.get(forModule); + } + + public VirtualFile[] getFilesToCompile() { + if (getModuleCount() == 0) { + return VirtualFile.EMPTY_ARRAY; // optimization + } + final Set modules = getNodes(); + + final Project project = modules.iterator().next().getProject(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + + final List filesToCompile = new ArrayList(); + for (Iterator it = modules.iterator(); it.hasNext();) { + final VirtualFile[] moduleCompilableFiles = getFilesToCompile(it.next()); + if (mySourcesFilter == ALL_SOURCES) { + filesToCompile.addAll(Arrays.asList(moduleCompilableFiles)); + } + else { + for (int idx = 0; idx < moduleCompilableFiles.length; idx++) { + final VirtualFile file = moduleCompilableFiles[idx]; + if (mySourcesFilter == TEST_SOURCES) { + if (fileIndex.isInTestSourceContent(file)) { + filesToCompile.add(file); + } + } + else { + if (!fileIndex.isInTestSourceContent(file)) { + filesToCompile.add(file); + } + } + } + } + } + return filesToCompile.toArray(new VirtualFile[filesToCompile.size()]); + } + + /** + * @return the jdk. Assumes that the jdk is the same for all modules + */ + public ProjectJdk getJdk() { + final Module module = getNodes().iterator().next(); + return ModuleRootManager.getInstance(module).getJdk(); + } + + public VirtualFile[] getSourceRoots() { + final List filteredRoots = new ArrayList(); + final Project project = getNodes().iterator().next().getProject(); + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final VirtualFile[] roots = getAllSourceRoots(); + for (int idx = 0; idx < roots.length; idx++) { + final VirtualFile root = roots[idx]; + if (mySourcesFilter != ALL_SOURCES) { + if (fileIndex.isInTestSourceContent(root)) { + if ((mySourcesFilter & TEST_SOURCES) == 0) { + continue; + } + } + else { + if ((mySourcesFilter & SOURCES) == 0) { + continue; + } + } + } + if (compilerConfiguration.isExcludedFromCompilation(root)) { + continue; + } + filteredRoots.add(root); + } + } + }); + return filteredRoots.toArray(new VirtualFile[filteredRoots.size()]); + } + + private VirtualFile[] getAllSourceRoots() { + final Set modules = getNodes(); + Set roots = new HashSet(); + for (Iterator it = modules.iterator(); it.hasNext();) { + final Module module = it.next(); + roots.addAll(Arrays.asList(myContext.getSourceRoots(module))); + } + return roots.toArray(new VirtualFile[roots.size()]); + } + + public String getCompilationClasspath() { + final StringBuffer classpathBuffer = new StringBuffer(); + + final Set modules = getNodes(); + + final OrderedSet cpFiles = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); + for (Iterator it = modules.iterator(); it.hasNext();) { + final Module module = it.next(); + final OrderEntry[] orderEntries = getSortedOrderEntries(module); + for (int i = 0; i < orderEntries.length; i++) { + cpFiles.addAll(Arrays.asList(orderEntries[i].getFiles(OrderRootType.COMPILATION_CLASSES))); + } + } + + for (Iterator it = cpFiles.iterator(); it.hasNext();) { + final VirtualFile file = it.next(); + final String path = PathUtil.getLocalPath(file); + if (path == null) { + continue; + } + if (classpathBuffer.length() > 0) { + classpathBuffer.append(File.pathSeparatorChar); + } + classpathBuffer.append(path); + } + + return classpathBuffer.toString(); + + } + + public int getModuleCount() { + return getNodes().size(); + } + + public Module[] getModules() { + final Set nodes = getNodes(); + return nodes.toArray(new Module[nodes.size()]); + } + + private static OrderEntry[] getSortedOrderEntries(Module module) { + //return ModuleRootManager.getInstance(module).getOrderEntries(); + // TODO: this is a patch for SCR 36800, After J2EE Compiler copying mechanizm is fixed, + // TODO: remove all the code below and uncomment the line above + final OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); + final List result = new ArrayList(); + final List moduleOrderEntries = new ArrayList(); + int insertIndex = 0; + for (int idx = 0; idx < orderEntries.length; idx++) { + OrderEntry orderEntry = orderEntries[idx]; + if (orderEntry instanceof ModuleOrderEntry) { + moduleOrderEntries.add(orderEntry); + } + else { + result.add(orderEntry); + if (orderEntry instanceof ModuleSourceOrderEntry) { + insertIndex = result.size() - 1; + } + } + } + if (moduleOrderEntries.size() > 0) { + result.addAll(insertIndex, moduleOrderEntries); + } + return result.toArray(new OrderEntry[result.size()]); + } + + + public String getSourcePath() { + if (getModuleCount() == 0) { + return ""; + } + final StringBuffer buffer = new StringBuffer(64); + final VirtualFile[] filteredRoots = getSourceRoots(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (int idx = 0; idx < filteredRoots.length; idx++) { + VirtualFile root = filteredRoots[idx]; + if (buffer.length() > 0) { + buffer.append(File.pathSeparatorChar); + } + buffer.append(root.getPath().replace('/', File.separatorChar)); + } + } + }); + return buffer.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java new file mode 100644 index 00000000000..78bbf15f689 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java @@ -0,0 +1,39 @@ +/* + * @author: Eugene Zhuravlev + * Date: Apr 1, 2003 + * Time: 5:58:41 PM + */ +package com.intellij.compiler.impl.javaCompiler; + +import com.intellij.openapi.compiler.TranslatingCompiler; +import com.intellij.openapi.vfs.VirtualFile; + +public class OutputItemImpl implements TranslatingCompiler.OutputItem{ + + private String myOutputPath; + private String myOutputDir; + private VirtualFile mySourceFile; + + /** + * @param outputDir + * @param outputPath relative to output directory path of the output file ('/' slashes used) + * @param sourceFile corresponding source file + */ + public OutputItemImpl(String outputDir, String outputPath, VirtualFile sourceFile) { + myOutputDir = outputDir; + myOutputPath = outputPath; + mySourceFile = sourceFile; + } + + public String getOutputPath() { + return myOutputPath; + } + + public String getOutputRootDirectory() { + return myOutputDir; + } + + public VirtualFile getSourceFile() { + return mySourceFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java new file mode 100644 index 00000000000..d344d3747b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java @@ -0,0 +1,218 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 17, 2003 + * Time: 3:48:26 PM + */ +package com.intellij.compiler.impl.resourceCompiler; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.compiler.make.MakeUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class ResourceCompiler implements TranslatingCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.resourceCompiler.ResourceCompiler"); + private final Project myProject; + private CompilerConfiguration myConfiguration; + + public ResourceCompiler(Project project, CompilerConfiguration compilerConfiguration) { + myProject = project; + myConfiguration = compilerConfiguration; + } + + public String getDescription() { + return "Resource Compiler"; + } + + public boolean validateConfiguration(CompileScope scope) { + CompilerConfiguration.getInstance(myProject).convertPatterns(); + return true; + } + + public boolean isCompilableFile(VirtualFile file, CompileContext context) { + if (!myConfiguration.isResourceFile(file.getName())) { + return false; + } + + final VirtualFile[] outputDirectories = context.getAllOutputDirectories(); + if (isUnderOutputDirectory(outputDirectories, file)) { + return false; + } + + return true; + } + + + public TranslatingCompiler.ExitStatus compile(final CompileContext context, final VirtualFile[] files) { + context.getProgressIndicator().pushState(); + context.getProgressIndicator().setText("Copying resources..."); + + final List processed = new ArrayList(files.length); + final List copyCommands = new ArrayList(files.length); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = files[idx]; + if (context.getProgressIndicator().isCanceled()) { + break; + } + context.getProgressIndicator().setFraction(((double)(idx)) / ((double)files.length)); + final Module module = context.getModuleByFile(file); + if (module == null) { + continue; // looks like file invalidated + } + final VirtualFile fileRoot = MakeUtil.getSourceRoot(context, module, file); + if (fileRoot == null) { + continue; + } + final String sourcePath = file.getPath(); + final String relativePath = VfsUtil.getRelativePath(file, fileRoot, '/'); + final String outputPath = CompilerPaths.getModuleOutputPath(module, fileIndex.isInTestSourceContent(file)); + if (outputPath == null) { + continue; + } + final String packagePrefix = fileIndex.getPackageNameByDirectory(fileRoot); + final String targetPath; + if (packagePrefix != null && packagePrefix.length() > 0) { + targetPath = outputPath + "/" + packagePrefix.replace('.', '/') + "/" + relativePath; + } + else { + targetPath = outputPath + "/" + relativePath; + } + if (!sourcePath.equals(targetPath)) { + copyCommands.add(new CopyCommand(outputPath, sourcePath, targetPath, file)); + } + } + } + }); + + final List filesToRefresh = new ArrayList(); + // do actual copy outside of read action to reduce the time the application is locked on it + for (Iterator it = copyCommands.iterator(); it.hasNext();) { + final CopyCommand command = it.next(); + try { + final MyOutputItem outputItem = command.copy(filesToRefresh); + processed.add(outputItem); + } + catch (IOException e) { + context.addMessage( + CompilerMessageCategory.ERROR, + "Error copying " + command.getFromPath() + " to " + command.getToPath() + ":\n" + e.getMessage(), + command.getSourceFileUrl(), -1, -1 + ); + } + } + if (filesToRefresh.size() > 0) { + CompilerUtil.refreshIOFiles(filesToRefresh.toArray(new File[filesToRefresh.size()])); + } + + context.getProgressIndicator().popState(); + + final OutputItem[] itemsArray = processed.toArray(new OutputItem[processed.size()]); + + return new MyExitStatus(itemsArray); + } + + private boolean isUnderOutputDirectory(VirtualFile[] outputDirectories, VirtualFile file) { + for (int idx = 0; idx < outputDirectories.length; idx++) { + if (VfsUtil.isAncestor(outputDirectories[idx], file, false)) { + return true; + } + } + return false; + } + + private static class CopyCommand { + private final String myOutputPath; + private final String myFromPath; + private final String myToPath; + private final VirtualFile mySourceFile; + + public CopyCommand(String outputPath, String fromPath, String toPath, VirtualFile sourceFile) { + myOutputPath = outputPath; + myFromPath = fromPath; + myToPath = toPath; + mySourceFile = sourceFile; + } + + public MyOutputItem copy(Collection filesToRefresh) throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug("Copying " + myFromPath + " to " + myToPath); + } + final File targetFile = new File(myToPath); + FileUtil.copy(new File(myFromPath), targetFile); + filesToRefresh.add(targetFile); + return new MyOutputItem(myOutputPath, myToPath, mySourceFile); + } + + public String getFromPath() { + return myFromPath; + } + + public String getToPath() { + return myToPath; + } + + public String getSourceFileUrl() { + // do not use mySourseFile.getUrl() directly as it requires read action + return VirtualFileManager.constructUrl(mySourceFile.getFileSystem().getProtocol(), myFromPath); + } + } + + private static class MyOutputItem implements OutputItem { + private final String myOutputPath; + private final String myTargetPath; + private final VirtualFile myFile; + + public MyOutputItem(String outputPath, String targetPath, VirtualFile file) { + myOutputPath = outputPath; + myTargetPath = targetPath; + myFile = file; + } + + public String getOutputRootDirectory() { + return myOutputPath; + } + + public String getOutputPath() { + return myTargetPath; + } + public VirtualFile getSourceFile() { + return myFile; + } + } + + private static class MyExitStatus implements ExitStatus { + private final OutputItem[] myItemsArray; + + public MyExitStatus(OutputItem[] itemsArray) { + myItemsArray = itemsArray; + } + + public OutputItem[] getSuccessfullyCompiled() { + return myItemsArray; + } + + public VirtualFile[] getFilesToRecompile() { + return VirtualFile.EMPTY_ARRAY; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java new file mode 100644 index 00000000000..fe2d4e9dcf1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java @@ -0,0 +1,452 @@ +package com.intellij.compiler.impl.rmiCompiler; + +import com.intellij.compiler.JavacOutputParser; +import com.intellij.compiler.RmicSettings; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.compiler.impl.javaCompiler.CompilerParsingThread; +import com.intellij.compiler.make.Cache; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.DependencyCache; +import com.intellij.compiler.make.CacheUtils; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.ex.CompileContextEx; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Mar 29, 2004 + */ + +public class RmicCompiler implements ClassPostProcessingCompiler{ + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.rmiCompiler.RmicCompiler"); + private final Project myProject; + //private static final FileFilter CLASSES_AND_DIRECTORIES_FILTER = new FileFilter() { + // public boolean accept(File pathname) { + // return pathname.isDirectory() || pathname.getName().endsWith(".class"); + // } + //}; + //private static final String REMOTE_INTERFACE_NAME = Remote.class.getName(); + + public RmicCompiler(Project project) { + myProject = project; + } + + public ProcessingItem[] getProcessingItems(final CompileContext context) { + if (!RmicSettings.getInstance(myProject).IS_EANABLED) { + return ProcessingItem.EMPTY_ARRAY; + } + final List items = new ArrayList(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + DependencyCache dependencyCache = ((CompileContextEx)context).getDependencyCache(); + try { + final Cache cache = dependencyCache.getCache(); + final int[] allClassNames = cache.getAllClassNames(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final LocalFileSystem lfs = LocalFileSystem.getInstance(); + for (int idx = 0; idx < allClassNames.length; idx++) { + final int className = allClassNames[idx]; + final int classId = cache.getClassId(className); + final boolean isRemoteObject = cache.isRemote(classId) && !CacheUtils.isInterface(cache, className); + if (!isRemoteObject && !dependencyCache.wasRemote(className)) { + continue; + } + final String outputPath = cache.getPath(classId); + if (outputPath == null) { + continue; + } + final VirtualFile outputClassFile = lfs.findFileByPath(outputPath.replace(File.separatorChar, '/')); + if (outputClassFile == null) { + continue; + } + final VirtualFile sourceFile = ((CompileContextEx)context).getSourceFileByOutputFile(outputClassFile); + if (sourceFile == null) { + continue; + } + final Module module = context.getModuleByFile(sourceFile); + if (module == null) { + continue; + } + final VirtualFile outputDir = fileIndex.isInTestSourceContent(sourceFile)? context.getModuleOutputDirectoryForTests(module) : context.getModuleOutputDirectory(module); + if (outputDir == null) { + continue; + } + + LOG.assertTrue(VfsUtil.isAncestor(outputDir, outputClassFile, true)); + + final RmicProcessingItem item = new RmicProcessingItem( + module, outputClassFile, new File(outputDir.getPath()), dependencyCache.resolve(className) + ); + item.setIsRemoteObject(isRemoteObject); + items.add(item); + } + } + catch (CacheCorruptedException e) { + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + } + } + }); + + return items.toArray(new ProcessingItem[items.size()]); + } + + public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) { + if (!RmicSettings.getInstance(myProject).IS_EANABLED) { + return ProcessingItem.EMPTY_ARRAY; + } + final ProgressIndicator progressIndicator = context.getProgressIndicator(); + progressIndicator.pushState(); + try { + progressIndicator.setText("Generating RMI stubs..."); + final List processed = new ArrayList(); + final Map, List> sortedByModuleAndOutputPath = new HashMap, List>(); + for (int idx = 0; idx < items.length; idx++) { + final RmicProcessingItem item = (RmicProcessingItem)items[idx]; + final Pair moduleOutputPair = new Pair(item.getModule(), item.getOutputDir()); + List dirItems = sortedByModuleAndOutputPath.get(moduleOutputPair); + if (dirItems == null) { + dirItems = new ArrayList(); + sortedByModuleAndOutputPath.put(moduleOutputPair, dirItems); + } + dirItems.add(item); + } + for (Iterator> it = sortedByModuleAndOutputPath.keySet().iterator(); it.hasNext();) { + if (progressIndicator.isCanceled()) { + break; + } + final Pair pair = it.next(); + final List dirItems = sortedByModuleAndOutputPath.get(pair); + try { + // should delete all previously generated files for the remote class if there are any + for (Iterator itemIterator = dirItems.iterator(); itemIterator.hasNext();) { + final RmicProcessingItem item = (RmicProcessingItem)itemIterator.next(); + item.deleteGeneratedFiles(); + if (!item.isRemoteObject()) { + itemIterator.remove(); // the object was remote and currently is not, so remove it from the list and do not generate stubs for it + } + } + if (dirItems.size() > 0) { + final RmicProcessingItem[] successfullyProcessed = invokeRmic(context, pair.getFirst(), dirItems, pair.getSecond()); + processed.addAll(Arrays.asList(successfullyProcessed)); + } + progressIndicator.setFraction(((double)processed.size()) / ((double)items.length)); + } + catch (IOException e) { + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + } + } + // update state so that the latest timestamps are recorded by make + final ProcessingItem[] processedItems = processed.toArray(new ProcessingItem[processed.size()]); + for (int idx = 0; idx < processedItems.length; idx++) { + RmicProcessingItem item = (RmicProcessingItem)processedItems[idx]; + item.updateState(); + } + return processedItems; + } + finally { + progressIndicator.popState(); + } + } + + private RmicProcessingItem[] invokeRmic(final CompileContext context, final Module module, final List dirItems, final File outputDir) throws IOException{ + final Map pathToItemMap = new HashMap(); + final String[] cmdLine = ApplicationManager.getApplication().runReadAction(new Computable() { + public String[] compute() { + for (Iterator it = dirItems.iterator(); it.hasNext();) { + final RmicProcessingItem item = (RmicProcessingItem)it.next(); + pathToItemMap.put(item.myStub.getPath().replace(File.separatorChar, '/'), item); + pathToItemMap.put(item.mySkel.getPath().replace(File.separatorChar, '/'), item); + pathToItemMap.put(item.myTie.getPath().replace(File.separatorChar, '/'), item); + } + return createStartupCommand(module, outputDir.getPath(), dirItems.toArray(new RmicProcessingItem[dirItems.size()])); + } + }); + + if (LOG.isDebugEnabled()) { + StringBuffer buf = new StringBuffer(); + for (int idx = 0; idx < cmdLine.length; idx++) { + if (idx > 0) { + buf.append(" "); + } + buf.append(cmdLine[idx]); + } + LOG.debug(buf.toString()); + } + + final Process process = Runtime.getRuntime().exec(cmdLine); + + final Set successfullyCompiledItems = new HashSet(); + final CompilerParsingThread parsingThread = new CompilerParsingThread(process, new JavacOutputParser(myProject), false) { + public void setProgressText(String text) { + context.getProgressIndicator().setText(text); + } + public void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) { + context.addMessage(category, message, url, lineNum, columnNum); + } + protected boolean isCancelled() { + return context.getProgressIndicator().isCanceled(); + } + public void fileProcessed(String path) { + } + protected void processCompiledClass(String classFileToProcess) { + final RmicProcessingItem item = pathToItemMap.get(classFileToProcess.replace(File.separatorChar, '/')); + if (item != null) { + successfullyCompiledItems.add(item); + } + } + }; + parsingThread.start(); + try { + parsingThread.join(); + } + catch (InterruptedException e) { + } + return successfullyCompiledItems.toArray(new RmicProcessingItem[successfullyCompiledItems.size()]); + } + + // todo: Module -> ModuleChunk + private String[] createStartupCommand(final Module module, final String outputPath, final RmicProcessingItem[] items) { + final List commandLine = new ArrayList(); + final ProjectJdk jdk = ModuleRootManager.getInstance(module).getJdk(); + + final VirtualFile homeDirectory = jdk.getHomeDirectory(); + if (homeDirectory == null) { + throw new IllegalArgumentException("Cannot determine home directory for JDK " + jdk.getName() + ".\nUpdate JDK configuration.\n"); + } + final String jdkPath = homeDirectory.getPath().replace('/', File.separatorChar); + + final String compilerPath = jdkPath + File.separator + "bin" + File.separator + "rmic"; + + commandLine.add(compilerPath); + + commandLine.add("-verbose"); + + commandLine.addAll(Arrays.asList(RmicSettings.getInstance(myProject).getOptions())); + + commandLine.add("-classpath"); + + commandLine.add(CompilerPathsEx.getCompilationClasspath(module)); + + commandLine.add("-d"); + + commandLine.add(outputPath); + + for (int idx = 0; idx < items.length; idx++) { + commandLine.add(items[idx].getClassQName()); + } + return commandLine.toArray(new String[commandLine.size()]); + } + + + public String getDescription() { + return "RMI Compiler"; + } + + public boolean validateConfiguration(CompileScope scope) { + return true; + } + + /* + private void addAllRemoteFilesFromModuleOutput(final CompileContext context, final Module module, final List items, final File outputDir, File fromDir, final JavaClass remoteInterface) { + final File[] children = fromDir.listFiles(CLASSES_AND_DIRECTORIES_FILTER); + for (int idx = 0; idx < children.length; idx++) { + final File child = children[idx]; + if (child.isDirectory()) { + addAllRemoteFilesFromModuleOutput(context, module, items, outputDir, child, remoteInterface); + } + else { + final String path = child.getPath(); + try { + final ClassParser classParser = new ClassParser(path); + final JavaClass javaClass = classParser.parse(); + // important! Need this in order to resolve other classes in the project (e.g. superclasses) + javaClass.setRepository(BcelUtils.getActiveRepository()); + if (isRmicCompilable(javaClass, remoteInterface)) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final VirtualFile outputClassFile = LocalFileSystem.getInstance().findFileByIoFile(child); + if (outputClassFile != null) { + items.add(new RmicProcessingItem(module, outputClassFile, outputDir, javaClass.getClassName())); + } + } + }); + } + } + catch (IOException e) { + context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse class file " + path + ": " + e.toString(), null, -1, -1); + } + catch (ClassFormatException e) { + context.addMessage(CompilerMessageCategory.ERROR, "Class format exception: " + e.getMessage() + " File: " + path, null, -1, -1); + } + } + } + } + */ + + /* + private boolean isRmicCompilable(final JavaClass javaClass, final JavaClass remoteInterface) { + // stubs are needed for classes that _directly_ implement remote interfaces + if (javaClass.isInterface() || isGenerated(javaClass)) { + return false; + } + final JavaClass[] directlyImplementedInterfaces = javaClass.getInterfaces(); + if (directlyImplementedInterfaces != null) { + for (int i = 0; i < directlyImplementedInterfaces.length; i++) { + if (directlyImplementedInterfaces[i].instanceOf(remoteInterface)) { + return true; + } + } + } + return false; + } + */ + + /* + private boolean isGenerated(JavaClass javaClass) { + final String sourceFileName = javaClass.getSourceFileName(); + return sourceFileName == null || !sourceFileName.endsWith(".java"); + } + */ + + + public ValidityState createValidityState(DataInputStream is) throws IOException { + return new RemoteClassValidityState(is.readLong(), is.readLong(), is.readLong(), is.readLong()); + } + + private static final class RemoteClassValidityState implements ValidityState { + private long myRemoteClassTimestamp; + private long myStubTimestamp; + private long mySkelTimestamp; + private long myTieTimestamp; + + public RemoteClassValidityState(long remoteClassTimestamp, long stubTimestamp, long skelTimestamp, long tieTimestamp) { + myRemoteClassTimestamp = remoteClassTimestamp; + myStubTimestamp = stubTimestamp; + mySkelTimestamp = skelTimestamp; + myTieTimestamp = tieTimestamp; + } + + public boolean equalsTo(ValidityState otherState) { + if (otherState instanceof RemoteClassValidityState) { + final RemoteClassValidityState state = (RemoteClassValidityState)otherState; + return myRemoteClassTimestamp == state.myRemoteClassTimestamp && + myStubTimestamp == state.myStubTimestamp && + mySkelTimestamp == state.mySkelTimestamp && + myTieTimestamp == state.myTieTimestamp; + } + return false; + } + + public void save(DataOutputStream os) throws IOException { + os.writeLong(myRemoteClassTimestamp); + os.writeLong(myStubTimestamp); + os.writeLong(mySkelTimestamp); + os.writeLong(myTieTimestamp); + } + } + private static final class RmicProcessingItem implements ProcessingItem { + private final Module myModule; + private final VirtualFile myOutputClassFile; + private final File myOutputDir; + private final String myQName; + private RemoteClassValidityState myState; + private final File myStub; + private final File mySkel; + private final File myTie; + private boolean myIsRemoteObject = false; + + public RmicProcessingItem(Module module, final VirtualFile outputClassFile, File outputDir, String qName) { + myModule = module; + myOutputClassFile = outputClassFile; + myOutputDir = outputDir; + myQName = qName; + final String relativePath; + final String baseName; + + final int index = qName.lastIndexOf('.'); + if (index >= 0) { + relativePath = qName.substring(0, index + 1).replace('.', '/'); + baseName = qName.substring(index + 1); + } + else { + relativePath = ""; + baseName = qName; + } + final String path = outputDir.getPath().replace(File.separatorChar, '/') + "/" + relativePath; + myStub = new File(path + "/" + baseName + "_Stub.class"); + mySkel = new File(path + "/" + baseName + "_Skel.class"); + myTie = new File(path + "/_" + baseName + "_Tie.class"); + updateState(); + } + + public boolean isRemoteObject() { + return myIsRemoteObject; + } + + public void setIsRemoteObject(boolean isRemote) { + myIsRemoteObject = isRemote; + } + + public VirtualFile getFile() { + return myOutputClassFile; + } + + public ValidityState getValidityState() { + return myState; + } + + public void updateState() { + myState = new RemoteClassValidityState( + myOutputClassFile.getTimeStamp(), + myStub.exists()? myStub.lastModified() : -1L, + mySkel.exists()? mySkel.lastModified() : -1L, + myTie.exists()? myTie.lastModified() : -1L + ); + } + + public void deleteGeneratedFiles() { + if (FileUtil.delete(myStub)) { + CompilerUtil.refreshIOFile(myStub); + } + if (FileUtil.delete(mySkel)) { + CompilerUtil.refreshIOFile(mySkel); + } + if (FileUtil.delete(myTie)) { + CompilerUtil.refreshIOFile(myTie); + } + } + + public String getClassQName() { + return myQName; + } + + public File getOutputDir() { + return myOutputDir; + } + + public Module getModule() { + return myModule; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/AnnotationTargets.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/AnnotationTargets.java new file mode 100644 index 00000000000..d77126bde8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/AnnotationTargets.java @@ -0,0 +1,33 @@ +package com.intellij.compiler.make; + +/** + * @author Eugene Zhuravlev + * Date: Apr 7, 2004 + */ +public interface AnnotationTargets { + /** Class, interface or enum declaration */ + int TYPE = 0x1; + + /** Field declaration (includes enum constants) */ + int FIELD = 0x2; + + /** Method declaration */ + int METHOD = 0x4; + + /** Parameter declaration */ + int PARAMETER = 0x8; + + /** Constructor declaration */ + int CONSTRUCTOR = 0x10; + + /** Local variable declaration */ + int LOCAL_VARIABLE = 0x20; + + /** Annotation type declaration */ + int ANNOTATION_TYPE = 0x40; + + /** Package declaration */ + int PACKAGE = 0x80; + + int ALL = TYPE | FIELD | METHOD | PARAMETER | CONSTRUCTOR | LOCAL_VARIABLE | ANNOTATION_TYPE | PACKAGE; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/BoundsParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/BoundsParser.java new file mode 100644 index 00000000000..19a87c3bd8e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/BoundsParser.java @@ -0,0 +1,67 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.classParsing.SignatureParser; +import com.intellij.compiler.classParsing.SignatureParsingException; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Mar 10, 2004 + */ +public class BoundsParser extends SignatureParser{ + final List myInterfaceBounds = new ArrayList(); + private int myParsingBound; + + public void parseClassBound(CharacterIterator it, StringBuffer buf) throws SignatureParsingException { + myParsingBound += 1; + try { + super.parseClassBound(it, buf); + } + finally { + myParsingBound -= 1; + } + } + + public void parseInterfaceBound(CharacterIterator it, StringBuffer buf) throws SignatureParsingException { + myParsingBound += 1; + try { + super.parseInterfaceBound(it, buf); + } + finally { + myParsingBound -= 1; + } + } + + public void parseClassTypeSignature(CharacterIterator it, StringBuffer buf) throws SignatureParsingException { + if (myParsingBound > 0) { + final int start = buf.length(); + + super.parseClassTypeSignature(it, buf); + + final String qName = convertToQalifiedName(buf.substring(start + 1, buf.length() - 1)); + myInterfaceBounds.add(qName); + } + else { + super.parseClassTypeSignature(it, buf); + } + } + + private String convertToQalifiedName(String ifaceSignature) { + ifaceSignature = ifaceSignature.replaceAll("<.*>", ""); + return ifaceSignature.replace('/', '.'); + } + + public String[] getBounds() { + return myInterfaceBounds.toArray(new String[myInterfaceBounds.size()]); + } + + public static String[] getBounds(String classSignature) throws SignatureParsingException { + final BoundsParser parser = new BoundsParser(); + parser.parseClassSignature(new StringCharacterIterator(classSignature), new StringBuffer()); + return parser.getBounds(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Cache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Cache.java new file mode 100644 index 00000000000..2555fd28d65 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Cache.java @@ -0,0 +1,1046 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.compiler.classParsing.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.ArrayUtil; +import gnu.trove.*; + +import java.io.*; + +/** + * @author Eugene Zhuravlev + * Date: Aug 8, 2003 + * Time: 7:03:56 PM + */ +public class Cache { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.Cache"); + + private final ViewPool myViewPool; + private TIntIntHashMap myQNameToClassInfoIdMap; + private TIntIntHashMap myQNameToClassDeclarationIdMap; + public static final int UNKNOWN = -1; + + private final File myDeclarationsIndexFile; + private final File myClassInfosIndexFile; + + public Cache(String storePath, int minViewCount, int maxViewCount) throws CacheCorruptedException { + myViewPool = new ViewPool(storePath, minViewCount, maxViewCount); + myDeclarationsIndexFile = new File(storePath + "/declarations_index.dat"); + myClassInfosIndexFile = new File(storePath + "/classinfo_index.dat"); + } + + public synchronized void dispose() { + myViewPool.dispose(true); + try { + if (myQNameToClassDeclarationIdMap != null) { + writeIndexMap(myQNameToClassDeclarationIdMap, myDeclarationsIndexFile); + myQNameToClassDeclarationIdMap = null; + } + if (myQNameToClassInfoIdMap != null) { + writeIndexMap(myQNameToClassInfoIdMap, myClassInfosIndexFile); + myQNameToClassInfoIdMap = null; + } + } + catch (IOException e) { + myDeclarationsIndexFile.delete(); + myClassInfosIndexFile.delete(); + LOG.info(e); + } + } + + public synchronized int[] getAllClassNames() throws CacheCorruptedException { + try { + return getQNameToClassInfoIdMap().keys(); + } + catch (IOException e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int importClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws ClsFormatException, CacheCorruptedException { + final int qName = symbolTable.getId(reader.getQualifiedName()); + + try { + final ClassInfoView classInfoView = myViewPool.getClassInfoView(getClassId(qName)); + final int id = classInfoView.getRecordId(); + + classInfoView.setQualifiedName(qName); + + final String signature = reader.getGenericSignature(); + final int genericSignature = signature != null? symbolTable.getId(signature) : -1; + classInfoView.setGenericSignature(genericSignature); + + classInfoView.setPath(reader.getPath()); + + final String superClass = reader.getSuperClass(); + final int superQName = "".equals(superClass)? Cache.UNKNOWN : symbolTable.getId(superClass); + + LOG.assertTrue(superQName != qName); + + classInfoView.setSuperQualifiedName(superQName); + + final String[] superInterfaces = reader.getSuperInterfaces(); + final int[] interfaceNames = new int[superInterfaces.length]; + for (int idx = 0; idx < superInterfaces.length; idx++) { + interfaceNames[idx] = symbolTable.getId(superInterfaces[idx]); + } + classInfoView.setSuperInterfaces(interfaceNames); + + final String sourceFileName = reader.getSourceFileName(); + if (sourceFileName != null) { + classInfoView.setSourceFileName(sourceFileName); + } + + classInfoView.setFlags(reader.getAccessFlags()); + + classInfoView.setRuntimeVisibleAnnotations(reader.getRuntimeVisibleAnnotations()); + + classInfoView.setRuntimeInvisibleAnnotations(reader.getRuntimeInvisibleAnnotations()); + + classInfoView.setReferences(reader.getReferences()); + + final FieldInfo[] fields = reader.getFields(); + final MethodInfo[] methods = reader.getMethods(); + MemberInfo[] members = ArrayUtil.mergeArrays(fields, methods, MemberInfo.class); + updateMemberDeclarations(qName, members); + + registerClassId(qName, id); + } + catch (ClsFormatException e) { + throw e; + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + return qName; + } + + public synchronized void importClassInfo(Cache fromCache, final int qName) throws CacheCorruptedException { + try { + final int fromClassId = fromCache.getClassId(qName); + + LOG.assertTrue(fromClassId != UNKNOWN); + + final ClassInfoView view = myViewPool.getClassInfoView(getClassId(qName)); + final int id = view.getRecordId(); + + final ClassInfoView classInfoView = myViewPool.getClassInfoView(id); + classInfoView.setQualifiedName(qName); + classInfoView.setGenericSignature(fromCache.getGenericSignature(fromClassId)); + classInfoView.setPath(fromCache.getPath(fromClassId)); + + final int superQualifiedName = fromCache.getSuperQualifiedName(fromClassId); + LOG.assertTrue(qName != superQualifiedName); + classInfoView.setSuperQualifiedName(superQualifiedName); + + classInfoView.setSuperInterfaces(fromCache.getSuperInterfaces(fromClassId)); + + classInfoView.setSourceFileName(fromCache.getSourceFileName(fromClassId)); + + classInfoView.setFlags(fromCache.getFlags(fromClassId)); + + classInfoView.setRuntimeVisibleAnnotations(fromCache.getRuntimeVisibleAnnotations(fromClassId)); + + classInfoView.setRuntimeInvisibleAnnotations(fromCache.getRuntimeInvisibleAnnotations(fromClassId)); + + final int fromClassDeclarationId = fromCache.getClassDeclarationId(qName); + final int[] fromFieldIds = fromCache.getFieldIds(fromClassDeclarationId); + final int[] fromMethodIds = fromCache.getMethodIds(fromClassDeclarationId); + final MemberInfo[] members = new MemberInfo[fromFieldIds.length + fromMethodIds.length]; + int currentMemberIndex = 0; + for (int idx = 0; idx < fromFieldIds.length; idx++) { + members[currentMemberIndex++] = fromCache.createFieldInfo(fromFieldIds[idx]); + } + for (int idx = 0; idx < fromMethodIds.length; idx++) { + final int methodId = fromMethodIds[idx]; + members[currentMemberIndex++] = fromCache.createMethodInfo(methodId); + } + updateMemberDeclarations(qName, members); + + registerClassId(qName, id); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getRuntimeVisibleAnnotations(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getRuntimeVisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getRuntimeInvisibleAnnotations(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getRuntimeInvisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getClassId(int qName) throws CacheCorruptedException { + try { + final TIntIntHashMap classInfoMap = getQNameToClassInfoIdMap(); + if (classInfoMap.containsKey(qName)) { + return classInfoMap.get(qName); + } + return UNKNOWN; + } + catch (IOException e) { + throw new CacheCorruptedException(e); + } + } + + private synchronized void registerClassId(final int qName, final int id) throws CacheCorruptedException { + try { + final TIntIntHashMap classInfoMap = getQNameToClassInfoIdMap(); + classInfoMap.put(qName, id); + } + catch (IOException e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getClassDeclarationId(int qName) throws CacheCorruptedException { + try { + final TIntIntHashMap declarationsMap = getQNameToClassDeclarationIdMap(); + if (declarationsMap.containsKey(qName)) { + return declarationsMap.get(qName); + } + final ClassDeclarationView view = myViewPool.getClassDeclarationView(UNKNOWN); + view.setClassName(qName); + final int id = view.getRecordId(); + declarationsMap.put(qName, id); + return id; + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getSubclasses(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getSubclasses(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void addSubclass(int classId, int subclassQName) throws CacheCorruptedException { + try { + final ClassInfoView reader = myViewPool.getClassInfoView(classId); + reader.addSubclass(subclassQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void removeSubclass(int classId, int subclassQName) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + view.removeSubclass(subclassQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getReferencedClasses(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getReferencedClasses(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized ReferenceInfo[] getReferences(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getReferences(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized String getSourceFileName(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getSourceFileName(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void setSourceFileName(int classId, String name) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + view.setSourceFileName(name); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized boolean isRemote(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.isRemote(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void setRemote(int classId, boolean remote) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + view.setRemote(remote); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getSuperQualifiedName(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + final int superQualifiedName = view.getSuperQualifiedName(); + return superQualifiedName; + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized String getPath(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getPath(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getGenericSignature(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getGenericSignature(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getSuperInterfaces(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getSuperInterfaces(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getFlags(int classId) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + return view.getFlags(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void addReferencedClass(int classId, int referencedClassName) throws CacheCorruptedException { + try { + final ClassInfoView view = myViewPool.getClassInfoView(classId); + view.addReferencedClass(referencedClassName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getFieldIds(int classDeclarationId) throws CacheCorruptedException{ + try { + final ClassDeclarationView view = myViewPool.getClassDeclarationView(classDeclarationId); + return view.getFieldIds(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getMethodIds(int classDeclarationId) throws CacheCorruptedException{ + try { + final ClassDeclarationView view = myViewPool.getClassDeclarationView(classDeclarationId); + return view.getMethodIds(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void addClassReferencer(int classDeclarationId, int referencerQName) throws CacheCorruptedException { + try { + final ClassDeclarationView view = myViewPool.getClassDeclarationView(classDeclarationId); + view.addReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void removeClassReferencer(int classDeclarationId, int referencerQName) throws CacheCorruptedException { + try { + final ClassDeclarationView view = myViewPool.getClassDeclarationView(classDeclarationId); + view.removeReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getFieldName(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getName(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getFieldDescriptor(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getDescriptor(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getFieldGenericSignature(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getGenericSignature(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getFieldFlags(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getFlags(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized ConstantValue getFieldConstantValue(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getConstantValue(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getFieldRuntimeVisibleAnnotations(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getRuntimeVisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getFieldRuntimeInvisibleAnnotations(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getRuntimeInvisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void addFieldReferencer(int fieldId, int referencerQName) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldId); + view.addReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void removeFieldReferencer(int fieldId, int referencerQName) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldId); + view.removeReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getMethodName(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getName(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getMethodDescriptor(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getDescriptor(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getMethodGenericSignature(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getGenericSignature(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int getMethodFlags(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getFlags(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getMethodRuntimeVisibleAnnotations(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getRuntimeVisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[] getMethodRuntimeInvisibleAnnotations(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getRuntimeInvisibleAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[][] getMethodRuntimeVisibleParamAnnotations(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getRuntimeVisibleParamAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized AnnotationConstantValue[][] getMethodRuntimeInvisibleParamAnnotations(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getRuntimeInvisibleParamAnnotations(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized ConstantValue getAnnotationDefault(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getAnnotationDefault(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized boolean isConstructor(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.isConstructor(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getMethodThrownExceptions(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getThrownExceptions(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void addMethodReferencer(int methodDeclarationId, int referencerQName) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + view.addReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void removeMethodReferencer(int methodDeclarationId, int referencerQName) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + view.removeReferencer(referencerQName); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized Dependency[] getBackDependencies(int classQName) throws CacheCorruptedException{ + final int classDeclarationId = getClassDeclarationId(classQName); + if (classDeclarationId == UNKNOWN) { + return null; + } + final Dependency[] dependencyArray; + try { + final TIntObjectHashMap dependencies = new TIntObjectHashMap(); + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + final int[] classReferencers = classDeclarationView.getReferencers(); + for (int idx = 0; idx < classReferencers.length; idx++) { + final int referencer = classReferencers[idx]; + if (referencer != classQName) { // skip self-dependencies + addDependency(dependencies, referencer); + } + } + + final int[] fieldIds = classDeclarationView.getFieldIds(); + for (int idx = 0; idx < fieldIds.length; idx++) { + final int fieldId = fieldIds[idx]; + final FieldDeclarationView fieldDeclarationView = myViewPool.getFieldDeclarationView(fieldId); + final int[] fieldReferencers = fieldDeclarationView.getReferencers(); + for (int i = 0; i < fieldReferencers.length; i++) { + int referencer = fieldReferencers[i]; + if (referencer != classQName) { // skip self-dependencies + final Dependency dependency = addDependency(dependencies, referencer); + dependency.addMemberInfo(createFieldInfo(fieldId)); + } + } + } + + final int[] methodIds = classDeclarationView.getMethodIds(); + for (int idx = 0; idx < methodIds.length; idx++) { + final int methodId = methodIds[idx]; + final MethodDeclarationView methodDeclarationView = myViewPool.getMethodDeclarationView(methodId); + final int[] methodReferencers = methodDeclarationView.getReferencers(); + for (int i = 0; i < methodReferencers.length; i++) { + int referencer = methodReferencers[i]; + if (referencer != classQName) { + final Dependency dependency = addDependency(dependencies, referencer); + dependency.addMemberInfo(createMethodInfo(methodId)); + } + } + } + dependencyArray = new Dependency[dependencies.size()]; + dependencies.forEachValue(new TObjectProcedure() { + private int index = 0; + public boolean execute(Object object) { + dependencyArray[index++] = (Dependency)object; + return true; + } + }); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + return dependencyArray; + } + + public synchronized FieldInfo createFieldInfo(final int fieldId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldId); + return new FieldInfo( + view.getName(), + view.getDescriptor(), + view.getGenericSignature(), + view.getFlags(), + view.getConstantValue(), + view.getRuntimeVisibleAnnotations(), + view.getRuntimeInvisibleAnnotations() + ); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized MethodInfo createMethodInfo(final int methodId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodId); + return new MethodInfo( + view.getName(), + view.getDescriptor(), + view.getGenericSignature(), + view.getFlags(), + view.getThrownExceptions(), + view.isConstructor(), + view.getRuntimeVisibleAnnotations(), + view.getRuntimeInvisibleAnnotations(), + view.getRuntimeVisibleParamAnnotations(), + view.getRuntimeInvisibleParamAnnotations(), + view.getAnnotationDefault() + ); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized void forEachDeclaration(DeclarationProcessor processor) throws CacheCorruptedException { + try { + final TIntIntHashMap declarationsMap = getQNameToClassDeclarationIdMap(); + final int[] qNames = declarationsMap.keys(); + for (int idx = 0; idx < qNames.length; idx++) { + final int qName = qNames[idx]; + if (!processor.process(new DeclarationInfo(qName))) { + return; + } + final MemberDeclarationInfo[] memberDeclarations = getMemberDeclarations(qName); + for (int i = 0; i < memberDeclarations.length; i++) { + if (!processor.process(memberDeclarations[i])) { + return; + } + } + } + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized MemberDeclarationInfo[] getMemberDeclarations(int classQName) throws CacheCorruptedException { + final int classDeclarationId = getClassDeclarationId(classQName); + final int[] fieldIds = getFieldIds(classDeclarationId); + final int[] methodIds = getMethodIds(classDeclarationId); + MemberDeclarationInfo[] infos = new MemberDeclarationInfo[fieldIds.length + methodIds.length]; + int index = 0; + for (int idx = 0; idx < fieldIds.length; idx++) { + infos[index++] = new MemberDeclarationInfo(classQName, createFieldInfo(fieldIds[idx])); + } + for (int idx = 0; idx < methodIds.length; idx++) { + infos[index++] = new MemberDeclarationInfo(classQName, createMethodInfo(methodIds[idx])); + } + return infos; + } + + private Dependency addDependency(TIntObjectHashMap container, int classQName) { + Dependency dependency = (Dependency)container.get(classQName); + if (dependency == null) { + dependency = new Dependency(classQName); + container.put(classQName, dependency); + } + return dependency; + } + + public synchronized int[] getFieldReferencers(int fieldDeclarationId) throws CacheCorruptedException { + try { + final FieldDeclarationView view = myViewPool.getFieldDeclarationView(fieldDeclarationId); + return view.getReferencers(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getMethodReferencers(int methodDeclarationId) throws CacheCorruptedException { + try { + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(methodDeclarationId); + return view.getReferencers(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + public synchronized int[] getClassReferencers(int classDeclarationId) throws CacheCorruptedException { + try { + final ClassDeclarationView view = myViewPool.getClassDeclarationView(classDeclarationId); + return view.getReferencers(); + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + private void updateMemberDeclarations(int classQName, MemberInfo[] classMembers) throws CacheCorruptedException{ + try { + final int classDeclarationId = getClassDeclarationId(classQName); + + final int[] fieldIds = getFieldIds(classDeclarationId); + final int[] methodIds = getMethodIds(classDeclarationId); + TObjectIntHashMap currentMembers = new TObjectIntHashMap(); + for (int idx = 0; idx < fieldIds.length; idx++) { + final int fieldId = fieldIds[idx]; + currentMembers.put(createFieldInfo(fieldId), fieldId); + } + for (int idx = 0; idx < methodIds.length; idx++) { + final int methodId = methodIds[idx]; + currentMembers.put(createMethodInfo(methodId), methodId); + } + + TIntHashSet fieldsToRemove = new TIntHashSet(fieldIds); + TIntHashSet methodsToRemove = new TIntHashSet(methodIds); + + for (int idx = 0; idx < classMembers.length; idx++) { + final MemberInfo classMember = classMembers[idx]; + + if (currentMembers.containsKey(classMember)) { // changed + final int memberId = currentMembers.get(classMember); + if (classMember instanceof FieldInfo) { + fieldsToRemove.remove(memberId); + } + else if (classMember instanceof MethodInfo){ + methodsToRemove.remove(memberId); + } + putMember(classDeclarationId, memberId, classMember); + } + else { // added + putMember(classDeclarationId, UNKNOWN, classMember); + } + } + + if (fieldsToRemove.size() > 0) { + final int[] fieldsArray = fieldsToRemove.toArray(); + for (int idx = 0; idx < fieldsArray.length; idx++) { + removeFieldDeclaration(classDeclarationId, fieldsArray[idx]); + } + } + + if (methodsToRemove.size() > 0) { + final int[] methodsArray = methodsToRemove.toArray(); + for (int idx = 0; idx < methodsArray.length; idx++) { + removeMethodDeclaration(classDeclarationId, methodsArray[idx]); + } + } + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } + + private void removeMethodDeclaration(int classDeclarationId, int methodId) throws IOException { + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + classDeclarationView.removeMethodId(methodId); + final MethodDeclarationView methodDeclarationView = myViewPool.getMethodDeclarationView(methodId); + //methodDeclarationView.removeRecord(); + myViewPool.removeMethodDeclarationRecord(methodDeclarationView); + } + + + private void removeFieldDeclaration(int classDeclarationId, int fieldId) throws IOException { + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + classDeclarationView.removeFieldId(fieldId); + final FieldDeclarationView fieldDeclarationView = myViewPool.getFieldDeclarationView(fieldId); + //fieldDeclarationView.removeRecord(); + myViewPool.removeFieldDeclarationRecord(fieldDeclarationView); + } + + public synchronized int putMember(final int classDeclarationId, int memberId, final MemberInfo classMember) throws CacheCorruptedException { + try { + if (classMember instanceof FieldInfo) { + FieldInfo fieldInfo = (FieldInfo)classMember; + final FieldDeclarationView view; + view = myViewPool.getFieldDeclarationView(memberId); + if (memberId == UNKNOWN) { + memberId = view.getRecordId(); + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + classDeclarationView.addFieldId(memberId); + } + view.setName(fieldInfo.getName()); + view.setDescriptor(fieldInfo.getDescriptor()); + view.setGenericSignature(fieldInfo.getGenericSignature()); + view.setFlags(fieldInfo.getFlags()); + view.setConstantValue(fieldInfo.getConstantValue()); + view.setRuntimeVisibleAnnotations(fieldInfo.getRuntimeVisibleAnnotations()); + view.setRuntimeInvisibleAnnotations(fieldInfo.getRuntimeInvisibleAnnotations()); + } + else if (classMember instanceof MethodInfo) { + MethodInfo methodInfo = (MethodInfo)classMember; + final MethodDeclarationView view = myViewPool.getMethodDeclarationView(memberId); + if (memberId == UNKNOWN) { + memberId = view.getRecordId(); + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + classDeclarationView.addMethodId(memberId); + } + view.setName(methodInfo.getName()); + view.setDescriptor(methodInfo.getDescriptor()); + view.setGenericSignature(methodInfo.getGenericSignature()); + view.setFlags(methodInfo.getFlags()); + view.setIsConstructor(methodInfo.isConstructor()); + view.setThrownExceptions(methodInfo.getThrownExceptions()); + view.setRuntimeVisibleAnnotations(methodInfo.getRuntimeVisibleAnnotations()); + view.setRuntimeInvisibleAnnotations(methodInfo.getRuntimeInvisibleAnnotations()); + view.setRuntimeVisibleParamAnnotations(methodInfo.getRuntimeVisibleParameterAnnotations()); + view.setRuntimeInvisibleParamAnnotations(methodInfo.getRuntimeInvisibleParameterAnnotations()); + view.setAnnotationDefault(methodInfo.getAnnotationDefault()); + } + else { + LOG.assertTrue(false, "Unknown member info: "+ classMember.getClass().getName()); + } + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + return memberId; + } + + private void writeIndexMap(TIntIntHashMap map, File indexFile) throws IOException { + if (!indexFile.exists()) { + indexFile.createNewFile(); + } + final DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(indexFile))); + try { + stream.writeInt(map.size()); + final IOException[] _ex = new IOException[] {null}; + map.forEachEntry(new TIntIntProcedure() { + public boolean execute(int qName, int id) { + try { + stream.writeInt(qName); + stream.writeInt(id); + } + catch (IOException e) { + _ex[0] = e; + return false; + } + return true; + } + }); + if (_ex[0] != null) { + throw _ex[0]; + } + } + finally { + stream.close(); + } + } + + private void readIndexMap(TIntIntHashMap map, File indexFile) throws IOException { + if (indexFile.exists()) { + DataInputStream stream = new DataInputStream(new ByteArrayInputStream(FileUtil.loadFileBytes(indexFile))); + try { + int size = stream.readInt(); + while (size-- > 0) { + final int qName = stream.readInt(); + final int id = stream.readInt(); + map.put(qName, id); + } + } + finally { + stream.close(); + } + } + } + + public synchronized void init() throws CacheCorruptedException { + myViewPool.init(); + } + + public synchronized void wipe() { + myViewPool.wipe(); + myClassInfosIndexFile.delete(); + myDeclarationsIndexFile.delete(); + } + + private synchronized TIntIntHashMap getQNameToClassInfoIdMap() throws IOException { + if (myQNameToClassInfoIdMap == null) { + myQNameToClassInfoIdMap = new TIntIntHashMap(); + readIndexMap(myQNameToClassInfoIdMap, myClassInfosIndexFile); + } + return myQNameToClassInfoIdMap; + } + + private synchronized TIntIntHashMap getQNameToClassDeclarationIdMap() throws IOException { + if (myQNameToClassDeclarationIdMap == null) { + myQNameToClassDeclarationIdMap = new TIntIntHashMap(); + readIndexMap(myQNameToClassDeclarationIdMap, myDeclarationsIndexFile); + } + return myQNameToClassDeclarationIdMap; + } + + public synchronized void removeClass(final int qName) throws CacheCorruptedException { + try { + final int classDeclarationId = getClassDeclarationId(qName); + if (classDeclarationId != UNKNOWN) { + final int[] fieldIds = getFieldIds(classDeclarationId); + for (int idx = 0; idx < fieldIds.length; idx++) { + final FieldDeclarationView fieldDeclarationView = myViewPool.getFieldDeclarationView(fieldIds[idx]); + //fieldDeclarationView.removeRecord(); + myViewPool.removeFieldDeclarationRecord(fieldDeclarationView); + } + final int[] methodIds = getMethodIds(classDeclarationId); + for (int idx = 0; idx < methodIds.length; idx++) { + final MethodDeclarationView methodDeclarationView = myViewPool.getMethodDeclarationView(methodIds[idx]); + //methodDeclarationView.removeRecord(); + myViewPool.removeMethodDeclarationRecord(methodDeclarationView); + } + + final ClassDeclarationView classDeclarationView = myViewPool.getClassDeclarationView(classDeclarationId); + //classDeclarationView.removeRecord(); + myViewPool.removeClassDeclarationRecord(classDeclarationView); + getQNameToClassDeclarationIdMap().remove(qName); + } + + final int classId = getClassId(qName); + if (classId != UNKNOWN) { + final ClassInfoView classInfoView = myViewPool.getClassInfoView(classId); + //classInfoView.removeRecord(); + myViewPool.removeClassInfoRecord(classInfoView); + getQNameToClassInfoIdMap().remove(qName); + } + } + catch (Throwable e) { + throw new CacheCorruptedException(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheCorruptedException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheCorruptedException.java new file mode 100644 index 00000000000..3e793e2dde8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheCorruptedException.java @@ -0,0 +1,25 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jul 10, 2003 + * Time: 4:51:25 PM + */ +package com.intellij.compiler.make; + +public class CacheCorruptedException extends Exception{ + private static final String DEFAULT_MESSAGE = "Compiler dependency information on disk is corrupted. Rebuild required."; + public CacheCorruptedException(String message) { + super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message); + } + + public CacheCorruptedException(Throwable cause) { + super(DEFAULT_MESSAGE, cause); + } + + public CacheCorruptedException(String message, Throwable cause) { + super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message, cause); + } + + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheUtils.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheUtils.java new file mode 100644 index 00000000000..e509142ecd8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CacheUtils.java @@ -0,0 +1,211 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.cls.ClsUtil; +import gnu.trove.TIntArrayList; +import gnu.trove.TIntHashSet; + +import java.util.ArrayList; + +/** + * @author Eugene Zhuravlev + * Date: Aug 18, 2003 + * Time: 6:32:32 PM + */ +public class CacheUtils { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CacheUtils"); + + public static String getMethodReturnTypeDescriptor(final Cache cache, final int methodDeclarationId, final SymbolTable symbolTable) throws CacheCorruptedException { + String descriptor = symbolTable.getSymbol(cache.getMethodDescriptor(methodDeclarationId)); + return descriptor.substring(descriptor.indexOf(')') + 1, descriptor.length()); + } + + public static String getMethodGenericSignature(final Cache cache, final int methodDeclarationId, final SymbolTable symbolTable) throws CacheCorruptedException { + final int methodGenericSignature = cache.getMethodGenericSignature(methodDeclarationId); + if (methodGenericSignature == -1) { + return null; + } + return symbolTable.getSymbol(methodGenericSignature); + } + + public static String[] getParameterSignatures(Cache cache, int methodDeclarationId, SymbolTable symbolTable) throws CacheCorruptedException { + String descriptor = symbolTable.getSymbol(cache.getMethodDescriptor(methodDeclarationId)); + int endIndex = descriptor.indexOf(')'); + if (endIndex <= 0) { + LOG.assertTrue(false, "Corrupted method descriptor: "+descriptor); + } + return parseSignature(descriptor.substring(1, endIndex)); + } + + private static String[] parseSignature(String signature) { + ArrayList list = new ArrayList(); + String paramSignature = parseParameterSignature(signature); + while (paramSignature != null && !"".equals(paramSignature)) { + list.add(paramSignature); + signature = signature.substring(paramSignature.length()); + paramSignature = parseParameterSignature(signature); + } + return (String[])list.toArray(new String[list.size()]); + } + + private static String parseParameterSignature(String signature) { + if (StringUtil.startsWithChar(signature, 'B')) { + return "B"; + } + if (StringUtil.startsWithChar(signature, 'C')) { + return "C"; + } + if (StringUtil.startsWithChar(signature, 'D')) { + return "D"; + } + if (StringUtil.startsWithChar(signature, 'F')) { + return "F"; + } + if (StringUtil.startsWithChar(signature, 'I')) { + return "I"; + } + if (StringUtil.startsWithChar(signature, 'J')) { + return "J"; + } + if (StringUtil.startsWithChar(signature, 'S')) { + return "S"; + } + if (StringUtil.startsWithChar(signature, 'Z')) { + return "Z"; + } + if (StringUtil.startsWithChar(signature, 'L')) { + return signature.substring(0, signature.indexOf(";") + 1); + } + if (StringUtil.startsWithChar(signature, '[')) { + String s = parseParameterSignature(signature.substring(1)); + return (s != null) ? ("[" + s) : null; + } + return null; + } + + public static int findField(final Cache cache, final int classDeclarationId, final int name, final int descriptor) throws CacheCorruptedException { + final int[] fieldIds = cache.getFieldIds(classDeclarationId); + for (int idx = 0; idx < fieldIds.length; idx++) { + int fieldId = fieldIds[idx]; + if (name != cache.getFieldName(fieldId)) { + continue; + } + if (descriptor != cache.getFieldDescriptor(fieldId)) { + continue; + } + return fieldId; + } + return Cache.UNKNOWN; + } + + public static int findFieldByName(final Cache cache, final int classDeclarationId, final int name) throws CacheCorruptedException { + final int[] fieldIds = cache.getFieldIds(classDeclarationId); + for (int idx = 0; idx < fieldIds.length; idx++) { + int fieldId = fieldIds[idx]; + if (name != cache.getFieldName(fieldId)) { + continue; + } + return fieldId; + } + return Cache.UNKNOWN; + } + + public static int findMethod(final Cache cache, final int classDeclarationId, final int name, final int descriptor) throws CacheCorruptedException { + final int[] methodIds = cache.getMethodIds(classDeclarationId); + for (int idx = 0; idx < methodIds.length; idx++) { + int methodId = methodIds[idx]; + if (name != cache.getMethodName(methodId)) { + continue; + } + if (descriptor != cache.getMethodDescriptor(methodId)) { + continue; + } + return methodId; + } + return Cache.UNKNOWN; + } + + public static int[] findMethodsByName(final Cache cache, final int classDeclarationId, final int name) throws CacheCorruptedException { + final int[] methodIds = cache.getMethodIds(classDeclarationId); + TIntArrayList list = new TIntArrayList(); + for (int idx = 0; idx < methodIds.length; idx++) { + final int methodId = methodIds[idx]; + if (name == cache.getMethodName(methodId)) { + list.add(methodId); + } + } + return list.toNativeArray(); + } + + public static int findMethodBySignature(final Cache cache, final int classDeclarationId, final String signature, SymbolTable symbolTable) throws CacheCorruptedException { + final int[] methodIds = cache.getMethodIds(classDeclarationId); + for (int idx = 0; idx < methodIds.length; idx++) { + int methodId = methodIds[idx]; + final int name = cache.getMethodName(methodId); + final int descriptor = cache.getMethodDescriptor(methodId); + if (signature.equals(getMethodSignature(symbolTable.getSymbol(name), symbolTable.getSymbol(descriptor)))) { + return methodId; + } + } + return Cache.UNKNOWN; + } + + public static String getMethodSignature(String name, String descriptor) { + return name + descriptor.substring(0, descriptor.indexOf(')') + 1); + } + + public static boolean areArraysContentsEqual(int[] exceptions1, int[] exceptions2) { + if (exceptions1.length != exceptions2.length) { + return false; + } + if (exceptions1.length != 0) { // optimization + TIntHashSet exceptionsSet = new TIntHashSet(exceptions1); + for (int idx = 0; idx < exceptions2.length; idx++) { + int exception = exceptions2[idx]; + if (!exceptionsSet.contains(exception)) { + return false; + } + } + } + return true; + } + + public static boolean isInterface(Cache cache, int classQName) throws CacheCorruptedException { + final int classId = cache.getClassId(classQName); + return MakeUtil.isInterface(cache.getFlags(classId)); + } + + public static boolean isAbstract(Cache cache, int classQName) throws CacheCorruptedException { + final int classId = cache.getClassId(classQName); + return ClsUtil.isAbstract(cache.getFlags(classId)); + } + + public static boolean isFinal(Cache cache, int classQName) throws CacheCorruptedException { + final int classId = cache.getClassId(classQName); + return ClsUtil.isFinal(cache.getFlags(classId)); + } + + public static final boolean isFieldReferenced(Cache cache, final int fieldId, final int referencerClassQName) throws CacheCorruptedException { + final int[] referencers = cache.getFieldReferencers(fieldId); + for (int idx = 0; idx < referencers.length; idx++) { + int referencer = referencers[idx]; + if (referencerClassQName == referencer) { + return true; + } + } + return false; + } + + public static final boolean isMethodReferenced(Cache cache, final int methodId, final int referencerClassQName) throws CacheCorruptedException { + final int[] referencers = cache.getMethodReferencers(methodId); + for (int idx = 0; idx < referencers.length; idx++) { + final int referencer = referencers[idx]; + if (referencerClassQName == referencer) { + return true; + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CachingSearcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CachingSearcher.java new file mode 100644 index 00000000000..8362a9d94df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/CachingSearcher.java @@ -0,0 +1,55 @@ +package com.intellij.compiler.make; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; + +import java.util.Map; + +/** + * @author Eugene Zhuravlev + * Date: Oct 15 + * @author 2003 + */ +public class CachingSearcher { + private final Project myProject; + private final Map myElementToReferencersMap = new com.intellij.util.containers.HashMap(); + private final PsiSearchHelper mySearchHelper; + + public CachingSearcher(Project project) { + myProject = project; + mySearchHelper = PsiManager.getInstance(myProject).getSearchHelper(); + } + + public PsiReference[] findReferences(PsiElement element) { + PsiReference[] psiReferences = myElementToReferencersMap.get(element); + if (psiReferences == null) { + psiReferences = doFindReferences(element); + myElementToReferencersMap.put(element, psiReferences); + } + return psiReferences; + } + + private PsiReference[] doFindReferences(final PsiElement psiElement) { + final ProgressManager progressManager = ProgressManager.getInstance(); + final ProgressIndicator currentProgress = progressManager.getProgressIndicator(); + final PsiReference[][] references = new PsiReference[][] {null}; + + currentProgress.startNonCancelableSection(); + try { + references[0] = mySearchHelper.findReferences(psiElement, GlobalSearchScope.projectScope(myProject), false); + } + finally { + currentProgress.finishNonCancelableSection(); + } + + return references[0]; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangeDescription.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangeDescription.java new file mode 100644 index 00000000000..fe8e91ab4eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangeDescription.java @@ -0,0 +1,9 @@ +package com.intellij.compiler.make; + +/** + * @author Eugene Zhuravlev + * Date: Apr 7, 2004 + */ +abstract class ChangeDescription { + public abstract boolean isChanged(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java new file mode 100644 index 00000000000..9e581484fad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java @@ -0,0 +1,240 @@ +/** + * created at Feb 24, 2002 + * @author Jeka + */ +package com.intellij.compiler.make; + +import com.intellij.compiler.classParsing.FieldInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.IdentifierPosition; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.util.PsiUtil; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class ChangedConstantsDependencyProcessor { + public static boolean ENABLE_TRACING = false; // used by tests + + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor"); + private final Project myProject; + private final CachingSearcher mySearcher; + private DependencyCache myDependencyCache; + private final int myQName; + private FieldInfo[] myChangedFields; + private FieldInfo[] myRemovedFields; + + + public ChangedConstantsDependencyProcessor(Project project, CachingSearcher searcher, DependencyCache dependencyCache, int qName, FieldInfo[] changedFields, FieldInfo[] removedFields) { + myProject = project; + mySearcher = searcher; + myDependencyCache = dependencyCache; + myQName = qName; + myChangedFields = changedFields; + myRemovedFields = removedFields; + } + + public void run() throws CacheCorruptedException { + final PsiManager psiManager = PsiManager.getInstance(myProject); + final CacheCorruptedException[] _ex = new CacheCorruptedException[] {null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + final String qName = myDependencyCache.resolve(myQName); + PsiClass[] classes = psiManager.findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject)); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + if (ENABLE_TRACING) { + System.out.println("Processing PsiClass " + aClass); + } + PsiField[] psiFields = aClass.getFields(); + for (int idx = 0; idx < psiFields.length; idx++) { + PsiField psiField = psiFields[idx]; + if (isFieldChanged(psiField)) { + processFieldChanged(psiField, aClass); + } + } + for (int idx = 0; idx < myRemovedFields.length; idx++) { + processFieldRemoved(myRemovedFields[idx], aClass); + } + } + } + catch (CacheCorruptedException e) { + _ex[0] = e; + } + } + }); + if (_ex[0] != null) { + throw _ex[0]; + } + } + + private void processFieldRemoved(FieldInfo info, PsiClass aClass) throws CacheCorruptedException { + if (info.isPrivate()) { + return; // optimization: don't need to search, cause may be used only in this class + } + SearchScope searchScope = GlobalSearchScope.projectScope(myProject); + if (info.isPackageLocal()) { + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile instanceof PsiJavaFile) { + final String packageName = ((PsiJavaFile)containingFile).getPackageName(); + final PsiPackage aPackage = PsiManager.getInstance(myProject).findPackage(packageName); + if (aPackage != null) { + searchScope = GlobalSearchScope.packageScope(aPackage, false); + searchScope = searchScope.intersectWith(aClass.getUseScope()); + } + } + } + final PsiSearchHelper psiSearchHelper = PsiManager.getInstance(myProject).getSearchHelper(); + PsiIdentifier[] identifiers = psiSearchHelper.findIdentifiers(myDependencyCache.resolve(info.getName()), searchScope, IdentifierPosition.IN_CODE); + for (int idx = 0; idx < identifiers.length; idx++) { + PsiIdentifier identifier = identifiers[idx]; + PsiElement parent = identifier.getParent(); + if (parent instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)parent; + PsiReference reference = refExpr.getReference(); + if (reference.resolve() == null) { + PsiClass ownerClass = getOwnerClass(refExpr); + if (ownerClass != null && !ownerClass.equals(aClass)) { + int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName()); + // should force marking of the class no matter was it compiled or not + // This will ensure the class was recompiled _after_ all the constants get their new values + if (myDependencyCache.markClass(qualifiedName, true)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+ myDependencyCache.resolve(qualifiedName) + "; reason: some constants were removed from " + myDependencyCache.resolve(myQName)); + } + } + } + } + } + } + } + + private void processFieldChanged(PsiField field, PsiClass aClass) throws CacheCorruptedException { + if (field.hasModifierProperty(PsiModifier.PRIVATE)) { + return; // optimization: don't need to search, cause may be used only in this class + } + if (ENABLE_TRACING) { + System.out.println("Processing changed field = " + field); + } + Set usages = new HashSet(); + addUsages(field, usages); + if (LOG.isDebugEnabled()) { + LOG.debug("++++++++++++++++++++++++++++++++++++++++++++++++"); + LOG.debug("Processing changed field: " + aClass.getQualifiedName() + "." + field.getName()); + } + for (Iterator it = usages.iterator(); it.hasNext();) { + PsiElement usage = (PsiElement)it.next(); + PsiClass ownerClass = getOwnerClass(usage); + if (LOG.isDebugEnabled()) { + if (ownerClass != null) { + LOG.debug("Usage " + usage + " found in class: " + ownerClass.getQualifiedName()); + } + else { + LOG.debug("Usage " + usage + " found in class: null"); + } + } + if (ownerClass != null && !ownerClass.equals(aClass)) { + int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName()); + // should force marking of the class no matter was it compiled or not + // This will ensure the class was recompiled _after_ all the constants get their new values + if (LOG.isDebugEnabled()) { + LOG.debug("Marking class id = [" + qualifiedName + "], name=[" + myDependencyCache.resolve(qualifiedName) + "]"); + } + if (myDependencyCache.markClass(qualifiedName, true)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Marked dependent class "+myDependencyCache.resolve(qualifiedName) + "; reason: constants changed in " + myDependencyCache.resolve(myQName)); + } + } + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("+++++++++++++++++++++++++++++++++++++++++++++++"); + } + } + + private void addUsages(PsiField psiField, Collection usages) { + PsiReference[] references = mySearcher.findReferences(psiField)/*doFindReferences(searchHelper, psiField)*/; + if (ENABLE_TRACING) { + System.out.println("Found " + references.length + " references to field " + psiField); + } + for (int idx = 0; idx < references.length; idx++) { + final PsiReference ref = references[idx]; + if (!(ref instanceof PsiReferenceExpression)) { + continue; + } + if (ENABLE_TRACING) { + System.out.println("Checking reference " + ref); + } + PsiElement e = ref.getElement(); + usages.add(e); + PsiField ownerField = getOwnerField(e); + if (ownerField != null) { + if (ownerField.hasModifierProperty(PsiModifier.FINAL)) { + PsiExpression initializer = ownerField.getInitializer(); + if (initializer != null && PsiUtil.isConstantExpression(initializer)) { + // if the field depends on the compile-time-constant expression and is itself final + addUsages(ownerField, usages); + } + } + } + } + } + + /* + private PsiReference[] doFindReferences(final PsiSearchHelper searchHelper, final PsiField psiField) { + final ProgressManager progressManager = ProgressManager.getInstance(); + final ProgressIndicator currentProgress = progressManager.getProgressIndicator(); + final PsiReference[][] references = new PsiReference[][] {null}; + progressManager.runProcess(new Runnable() { + public void run() { + references[0] = searchHelper.findReferences(psiField, GlobalSearchScope.projectScope(myProject), false); + if (ENABLE_TRACING) { + System.out.println("Finding referencers for " + psiField); + } + } + }, new NonCancellableProgressAdapter(currentProgress)); + return references[0]; + } + */ + + private PsiField getOwnerField(PsiElement element) { + while (!(element instanceof PsiFile)) { + if (element instanceof PsiClass) { + break; + } + if (element instanceof PsiField) { // top-level class + return (PsiField)element; + } + element = element.getParent(); + } + return null; + } + + private boolean isFieldChanged(PsiField field) throws CacheCorruptedException { + String name = field.getName(); + for (int idx = 0; idx < myChangedFields.length; idx++) { + if (name.equals(myDependencyCache.resolve(myChangedFields[idx].getName()))) { + return true; + } + } + return false; + } + + private PsiClass getOwnerClass(PsiElement element) { + while (!(element instanceof PsiFile)) { + if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class + return (PsiClass)element; + } + element = element.getParent(); + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java new file mode 100644 index 00000000000..741d7304d49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java @@ -0,0 +1,86 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.cls.ClsUtil; + +public class ChangedRetentionPolicyDependencyProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor"); + private final Project myProject; + private final CachingSearcher mySearcher; + private DependencyCache myDependencyCache; + + public ChangedRetentionPolicyDependencyProcessor(Project project, CachingSearcher searcher, DependencyCache dependencyCache) { + myProject = project; + mySearcher = searcher; + myDependencyCache = dependencyCache; + } + + public void checkAnnotationRetentionPolicyChanges(final int annotationQName) throws CacheCorruptedException { + final Cache oldCache = myDependencyCache.getCache(); + if (!ClsUtil.isAnnotation(oldCache.getFlags(oldCache.getClassId(annotationQName)))) { + return; + } + if (!hasRetentionPolicyChanged(annotationQName, oldCache, myDependencyCache.getNewClassesCache(), myDependencyCache.getSymbolTable())) { + return; + } + final PsiManager psiManager = PsiManager.getInstance(myProject); + final CacheCorruptedException[] _ex = new CacheCorruptedException[] {null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + final String qName = myDependencyCache.resolve(annotationQName); + PsiClass[] classes = psiManager.findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject)); + for (int i = 0; i < classes.length; i++) { + final PsiClass aClass = classes[i]; + if (!aClass.isAnnotationType()) { + continue; + } + final PsiReference[] references = mySearcher.findReferences(aClass); + for (int j = 0; j < references.length; j++) { + final PsiClass ownerClass = getOwnerClass(references[j].getElement()); + if (ownerClass != null && !ownerClass.equals(aClass)) { + int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName()); + if (myDependencyCache.markClass(qualifiedName, false)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Marked dependent class "+myDependencyCache.resolve(qualifiedName) + "; reason: annotation's retention policy changed from SOURCE to CLASS or RUNTIME " + myDependencyCache.resolve(annotationQName)); + } + } + } + } + } + } + catch (CacheCorruptedException e) { + _ex[0] = e; + } + } + }); + if (_ex[0] != null) { + throw _ex[0]; + } + } + + private boolean hasRetentionPolicyChanged(int annotationQName, final Cache oldCache, final Cache newCache, SymbolTable symbolTable) throws CacheCorruptedException { + // if retention policy changed from SOURCE to CLASS or RUNTIME, all sources should be recompiled to propagate changes + final int oldPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, oldCache, symbolTable); + final int newPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, newCache, symbolTable); + if ((oldPolicy == RetentionPolicies.SOURCE) && (newPolicy == RetentionPolicies.CLASS || newPolicy == RetentionPolicies.RUNTIME)) { + return true; + } + return false; + } + + private static PsiClass getOwnerClass(PsiElement element) { + while (!(element instanceof PsiFile)) { + if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class + return (PsiClass)element; + } + element = element.getParent(); + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ClassInfoProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ClassInfoProcessor.java new file mode 100644 index 00000000000..e93920d9f89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/ClassInfoProcessor.java @@ -0,0 +1,16 @@ +/* + * @author: Eugene Zhuravlev + * Date: May 14, 2003 + * Time: 10:42:29 AM + */ +package com.intellij.compiler.make; + + + +public interface ClassInfoProcessor { + /** + * @param classQName of a class info to be processed + * @return true if superclasses of info should be processed and false otherwise + */ + boolean process(int classQName) throws CacheCorruptedException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Dependency.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Dependency.java new file mode 100644 index 00000000000..499db6917d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/Dependency.java @@ -0,0 +1,89 @@ +/** + * created at Jan 4, 2002 + * @author Jeka + */ +package com.intellij.compiler.make; + +import com.intellij.compiler.classParsing.FieldInfo; +import com.intellij.compiler.classParsing.MemberInfo; +import com.intellij.compiler.classParsing.MethodInfo; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +public class Dependency { + + private final int myClassQualifiedName; + private Set myUsedMembers; // members which are used + private MemberInfo[] myMemberInfoArray = MemberInfo.EMPTY_MEMBER_INFO_ARRAY; // cached data + private MethodInfo[] myMethodInfoArray = MethodInfo.EMPTY_ARRAY; // cached data + private FieldInfo[] myFieldInfoArray = FieldInfo.EMPTY_ARRAY; // cached data + + public Dependency(int classQualifiedName) { + myClassQualifiedName = classQualifiedName; + } + + public int getClassQualifiedName() { + return myClassQualifiedName; + } + + public void addMemberInfo(MemberInfo info) { + if (myUsedMembers == null) { + myUsedMembers = new HashSet(); + } + myUsedMembers.add(info); + myMemberInfoArray = null; + myMethodInfoArray = null; + myFieldInfoArray = null; + } + + public MemberInfo[] getUsedMembers() { + if (myMemberInfoArray == null) { + if (myUsedMembers != null && myUsedMembers.size() > 0) { + myMemberInfoArray = (MemberInfo[])myUsedMembers.toArray(new MemberInfo[myUsedMembers.size()]); + } + else { + myMemberInfoArray = MemberInfo.EMPTY_MEMBER_INFO_ARRAY; + } + } + return myMemberInfoArray; + } + + public MethodInfo[] getUsedMethods() { + if (myMethodInfoArray == null) { + MemberInfo[] usedMembers = getUsedMembers(); + ArrayList list = null; + for (int idx = 0; idx < usedMembers.length; idx++) { + MemberInfo memberInfo = usedMembers[idx]; + if (memberInfo instanceof MethodInfo) { + if (list == null) { + list = new ArrayList(usedMembers.length); + } + list.add(memberInfo); + } + } + myMethodInfoArray = (list != null)? (MethodInfo[])list.toArray(new MethodInfo[list.size()]) : MethodInfo.EMPTY_ARRAY; + } + return myMethodInfoArray; + } + + public FieldInfo[] getUsedFields() { + if (myFieldInfoArray == null) { + ArrayList list = null; + MemberInfo[] usedMembers = getUsedMembers(); + for (int idx = 0; idx < usedMembers.length; idx++) { + MemberInfo memberInfo = usedMembers[idx]; + if (memberInfo instanceof FieldInfo) { + if (list == null) { + list = new ArrayList(usedMembers.length); + } + list.add(memberInfo); + } + } + myFieldInfoArray = (list != null)? (FieldInfo[])list.toArray(new FieldInfo[list.size()]) : FieldInfo.EMPTY_ARRAY; + } + return myFieldInfoArray; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCache.java new file mode 100644 index 00000000000..42f0d170c84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCache.java @@ -0,0 +1,737 @@ +/** + * created at Jan 7, 2002 + * @author Jeka + */ +package com.intellij.compiler.make; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.SymbolTable; +import com.intellij.compiler.classParsing.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.cls.ClsUtil; +import gnu.trove.TIntHashSet; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Set; +import java.rmi.Remote; + +public class DependencyCache { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.DependencyCache"); + + private Cache myCache; + private Cache myNewClassesCache; + + private static final String REMOTE_INTERFACE_NAME = Remote.class.getName(); + private final TIntHashSet myClassesWithSuperlistChanged = new TIntHashSet(); + private TIntHashSet myToUpdate = new TIntHashSet(); // qName strings to be updated. + private final TIntHashSet myTraverseRoots = new TIntHashSet(); // Dependencies are calculated from these clasess + private final TIntHashSet myClassesWithSourceRemoved = new TIntHashSet(); + private final TIntHashSet myPreviouslyRemoteClasses = new TIntHashSet(); // classes that were Remote, but became non-Remote for some reason + private TIntHashSet myMarkedInfos = new TIntHashSet(); // classes to be recompiled + + private DependencyCacheNavigator myCacheNavigator; + private SymbolTable mySymbolTable; + private String mySymbolTableFilePath; + private final String myStoreDirectoryPath; + + public DependencyCache(String storeDirectoryPath) { + myStoreDirectoryPath = storeDirectoryPath; + LOG.assertTrue(myStoreDirectoryPath != null); + + mySymbolTableFilePath = myStoreDirectoryPath + "/symboltable.dat"; + } + + + public DependencyCacheNavigator getCacheNavigator() throws CacheCorruptedException { + if (myCacheNavigator == null) { + myCacheNavigator = new DependencyCacheNavigator(getCache(), this); + } + return myCacheNavigator; + } + + public void init() throws CacheCorruptedException { + getCache().init(); + getNewClassesCache().init(); + } + + public void wipe() throws CacheCorruptedException { + getCache().wipe(); + getNewClassesCache().wipe(); + } + + public Cache getCache() throws CacheCorruptedException { + if (myCache == null) { + myCache = new Cache(myStoreDirectoryPath, 50, Integer.MAX_VALUE); + } + + return myCache; + } + + public Cache getNewClassesCache() throws CacheCorruptedException { + if (myNewClassesCache == null) { + myNewClassesCache = new Cache(myStoreDirectoryPath + "/tmp", 50, 1000); + } + return myNewClassesCache; + } + + public void addTraverseRoot(int qName) { + myTraverseRoots.add(qName); + } + + public void markSourceRemoved(int qName) { + myClassesWithSourceRemoved.add(qName); + } + + public void addClassToUpdate(int qName) { + myToUpdate.add(qName); + } + + public int reparseClassFile(File file) throws ClsFormatException, CacheCorruptedException { + SymbolTable symbolTable = getSymbolTable(); + + final int qName = getNewClassesCache().importClassInfo(new ClassFileReader(file, symbolTable), symbolTable); + addClassToUpdate(qName); + addTraverseRoot(qName); + return qName; + } + + // for profiling purposes + /* + private static void pause() { + System.out.println("PAUSED. ENTER A CHAR."); + byte[] buf = new byte[1]; + try { + System.in.read(buf); + } + catch (IOException e) { + e.printStackTrace(); + } + } + */ + + public void update() throws CacheCorruptedException { + if (myToUpdate.size() == 0) { + return; // optimization + } + + //final long updateStart = System.currentTimeMillis(); + //pause(); + + final int[] namesToUpdate = myToUpdate.toArray(); + final Cache cache = getCache(); + final DependencyCacheNavigator navigator = getCacheNavigator(); + + // remove unnecesary dependencies + for (int idx = 0; idx < namesToUpdate.length; idx++) { + final int qName = namesToUpdate[idx]; + + final int oldClassId = cache.getClassId(qName); + if (oldClassId != Cache.UNKNOWN) { + // process use-dependencies + final int[] referencedClasses = cache.getReferencedClasses(oldClassId); + for (int i = 0; i < referencedClasses.length; i++) { + final int referencedClassDeclarationId = cache.getClassDeclarationId(referencedClasses[i]); + if (referencedClassDeclarationId == Cache.UNKNOWN) { + continue; + } + + cache.removeClassReferencer(referencedClassDeclarationId, qName); + + final int[] fieldIds = cache.getFieldIds(referencedClassDeclarationId); + for (int j = 0; j < fieldIds.length; j++) { + cache.removeFieldReferencer(fieldIds[j], qName); + } + + final int[] methodIds = cache.getMethodIds(referencedClassDeclarationId); + for (int j = 0; j < methodIds.length; j++) { + cache.removeMethodReferencer(methodIds[j], qName); + } + } + // process inheritance dependencies + navigator.walkSuperClasses(qName, new ClassInfoProcessor() { + public boolean process(int classQName) throws CacheCorruptedException { + final int classId = cache.getClassId(classQName); + cache.removeSubclass(classId, qName); + return true; + } + }); + } + } + + // do update of classInfos + for (int idx = 0; idx < namesToUpdate.length; idx++) { + final int qName = namesToUpdate[idx]; + final int newInfoId = getNewClassesCache().getClassId(qName); + if (newInfoId == Cache.UNKNOWN) { + continue; // no member data to update + } + cache.importClassInfo(getNewClassesCache(), qName); + } + + // build forward-dependencies for the new infos, all new class infos must be already in the main cache! + + for (int idx = 0; idx < namesToUpdate.length; idx++) { + final int qName = namesToUpdate[idx]; + final int newClassId = getNewClassesCache().getClassId(qName); + if (newClassId == Cache.UNKNOWN) { + continue; + } + buildForwardDependencies(qName, getNewClassesCache().getReferences(newClassId)); + + boolean isRemote = false; + final int classId = cache.getClassId(qName); + // "remote objects" are classes that _directly_ implement remote interfaces + final int[] superInterfaces = cache.getSuperInterfaces(classId); + if (superInterfaces.length > 0) { + final int remoteInterfaceName = mySymbolTable.getId(REMOTE_INTERFACE_NAME); + for (int i = 0; i < superInterfaces.length; i++) { + if (isRemoteInterface(cache, superInterfaces[i], remoteInterfaceName)) { + isRemote = true; + break; + } + } + } + final boolean wasRemote = cache.isRemote(classId); + if (wasRemote && !isRemote) { + myPreviouslyRemoteClasses.add(qName); + } + cache.setRemote(classId, isRemote); + } + + // build back-dependencies + + for (int idx = 0; idx < namesToUpdate.length; idx++) { + final int qName = namesToUpdate[idx]; + buildSubclassDependencies(qName, qName); + } + + final int[] classesToRemove = myClassesWithSourceRemoved.toArray(); + for (int idx = 0; idx < classesToRemove.length; idx++) { + final int qName = classesToRemove[idx]; + cache.removeClass(qName); + } + + myToUpdate = new TIntHashSet(); + + //System.out.println("Dependency cache update took: " + (System.currentTimeMillis() - updateStart) + " ms"); + //pause(); + } + + private void buildForwardDependencies(final int classQName, final ReferenceInfo[] references) throws CacheCorruptedException { + final Cache cache = getCache(); + final int classId = cache.getClassId(classQName); + + final int genericSignature = cache.getGenericSignature(classId); + if (genericSignature != -1) { + final String genericClassSignature = resolve(genericSignature); + final int[] bounds = findBounds(genericClassSignature); + for (int idx = 0; idx < bounds.length; idx++) { + int boundClassQName = bounds[idx]; + cache.addClassReferencer(cache.getClassDeclarationId(boundClassQName), classQName); + cache.addReferencedClass(classId, boundClassQName); + } + } + + buildAnnotationDependencies(classQName, cache.getRuntimeVisibleAnnotations(classId)); + buildAnnotationDependencies(classQName, cache.getRuntimeInvisibleAnnotations(classId)); + + for (int idx = 0; idx < references.length; idx++) { + final ReferenceInfo refInfo = references[idx]; + final int declaringClassName = getActualDeclaringClassForReference(refInfo); + if (declaringClassName == Cache.UNKNOWN) { + continue; + } + final int declaringClassId = cache.getClassDeclarationId(declaringClassName); + if (refInfo instanceof MemberReferenceInfo) { + final MemberInfo memberInfo = ((MemberReferenceInfo)refInfo).getMemberInfo(); + if (memberInfo instanceof FieldInfo) { + int fieldId = CacheUtils.findField(cache, declaringClassId, memberInfo.getName(), memberInfo.getDescriptor()); + if (fieldId == Cache.UNKNOWN) { + fieldId = cache.putMember(declaringClassId, Cache.UNKNOWN, memberInfo); + } + cache.addFieldReferencer(fieldId, classQName); + } + else if (memberInfo instanceof MethodInfo) { + int methodId = CacheUtils.findMethod(cache, declaringClassId, memberInfo.getName(), memberInfo.getDescriptor()); + if (methodId == Cache.UNKNOWN) { + methodId = cache.putMember(declaringClassId, Cache.UNKNOWN, memberInfo); + } + cache.addMethodReferencer(methodId, classQName); + } + else { + LOG.error("Unknown member info class: " + memberInfo.getClass().getName()); + } + } + else { // reference to class + cache.addClassReferencer(declaringClassId, classQName); + } + cache.addReferencedClass(classId, declaringClassName); + } + final SymbolTable symbolTable = getSymbolTable(); + final int classDeclarationId = cache.getClassDeclarationId(classQName); + + final int[] fieldIds = cache.getFieldIds(classDeclarationId); + for (int idx = 0; idx < fieldIds.length; idx++) { + final int fieldId = fieldIds[idx]; + + buildAnnotationDependencies(classQName, cache.getFieldRuntimeVisibleAnnotations(fieldId)); + buildAnnotationDependencies(classQName, cache.getFieldRuntimeInvisibleAnnotations(fieldId)); + + final int signature = cache.getFieldDescriptor(fieldId); + String className = MakeUtil.parseObjectType(symbolTable.getSymbol(signature), 0); + if (className == null) { + continue; + } + final int cls = symbolTable.getId(className); + cache.addClassReferencer(cache.getClassDeclarationId(cls), classQName); + cache.addReferencedClass(classId, cls); + } + + final int[] methods = cache.getMethodIds(classDeclarationId); + for (int idx = 0; idx < methods.length; idx++) { + final int methodId = methods[idx]; + + buildAnnotationDependencies(classQName, cache.getMethodRuntimeVisibleAnnotations(methodId)); + buildAnnotationDependencies(classQName, cache.getMethodRuntimeInvisibleAnnotations(methodId)); + buildAnnotationDependencies(classQName, cache.getMethodRuntimeVisibleParamAnnotations(methodId)); + buildAnnotationDependencies(classQName, cache.getMethodRuntimeInvisibleParamAnnotations(methodId)); + + if (cache.isConstructor(methodId)) { + continue; + } + + final String returnTypeClassName = MakeUtil.parseObjectType(CacheUtils.getMethodReturnTypeDescriptor(cache, methodId, getSymbolTable()), 0); + if (returnTypeClassName != null) { + final int returnTypeClassId = symbolTable.getId(returnTypeClassName); + cache.addClassReferencer(cache.getClassDeclarationId(returnTypeClassId), classQName); + cache.addReferencedClass(classId, returnTypeClassId); + } + + String[] parameterSignatures = CacheUtils.getParameterSignatures(cache, methodId, getSymbolTable()); + for (int i = 0; i < parameterSignatures.length; i++) { + String paramClassName = MakeUtil.parseObjectType(parameterSignatures[i], 0); + if (paramClassName != null) { + final int paramClassId = symbolTable.getId(paramClassName); + cache.addClassReferencer(cache.getClassDeclarationId(paramClassId), classQName); + cache.addReferencedClass(classId, paramClassId); + } + } + } + + } + + private boolean isRemoteInterface(Cache cache, int ifaceName, final int remoteInterfaceName) throws CacheCorruptedException { + if (ifaceName == remoteInterfaceName) { + return true; + } + final int[] superInterfaces = cache.getSuperInterfaces(cache.getClassId(ifaceName)); + for (int idx = 0; idx < superInterfaces.length; idx++) { + int superInterfaceName = superInterfaces[idx]; + if (isRemoteInterface(cache, superInterfaceName, remoteInterfaceName)) { + return true; + } + } + return false; + } + + + private void buildAnnotationDependencies(int classQName, AnnotationConstantValue[][] annotations) throws CacheCorruptedException { + if (annotations == null || annotations.length == 0) { + return; + } + for (int idx = 0; idx < annotations.length; idx++) { + buildAnnotationDependencies(classQName, annotations[idx]); + } + } + + private void buildAnnotationDependencies(int classQName, AnnotationConstantValue[] annotations) throws CacheCorruptedException { + if (annotations == null || annotations.length == 0) { + return; + } + final Cache cache = getCache(); + final int classId = cache.getClassId(classQName); + for (int idx = 0; idx < annotations.length; idx++) { + AnnotationConstantValue annotation = annotations[idx]; + final int annotationQName = annotation.getAnnotationQName(); + + final int annotationDeclarationId = cache.getClassDeclarationId(annotationQName); + + cache.addClassReferencer(annotationDeclarationId, classQName); + cache.addReferencedClass(classId, annotationQName); + + final AnnotationNameValuePair[] memberValues = annotation.getMemberValues(); + for (int i = 0; i < memberValues.length; i++) { + final AnnotationNameValuePair nameValuePair = memberValues[i]; + final int[] annotationMembers = CacheUtils.findMethodsByName(cache, annotationDeclarationId, nameValuePair.getName()); + for (int j = 0; j < annotationMembers.length; j++) { + int annotationMember = annotationMembers[j]; + cache.addMethodReferencer(annotationMember, classQName); + } + } + } + } + + public int[] findBounds(final String genericClassSignature) throws CacheCorruptedException{ + try { + final String[] boundInterfaces = BoundsParser.getBounds(genericClassSignature); + int[] ids = new int[boundInterfaces.length]; + for (int i = 0; i < boundInterfaces.length; i++) { + ids[i] = getSymbolTable().getId(boundInterfaces[i]); + } + return ids; + } + catch (SignatureParsingException e) { + return new int[0]; + } + } + + // fixes JDK 1.4 javac bug that generates references in the constant pool + // to the subclass even if the field was declared in a superclass + public int getActualDeclaringClassForReference(final ReferenceInfo refInfo) throws CacheCorruptedException { + if (!(refInfo instanceof MemberReferenceInfo)) { + return refInfo.getClassName(); + } + final int declaringClassName = refInfo.getClassName(); + if (getCache().getClassId(declaringClassName) == Cache.UNKNOWN) { + return declaringClassName; + } + final int classDeclarationId = getCache().getClassDeclarationId(declaringClassName); + final MemberInfo memberInfo = ((MemberReferenceInfo)refInfo).getMemberInfo(); + if (memberInfo instanceof FieldInfo) { + if (CacheUtils.findFieldByName(getCache(), classDeclarationId, memberInfo.getName()) != Cache.UNKNOWN) { + return declaringClassName; + } + } + else if (memberInfo instanceof MethodInfo) { + if (CacheUtils.findMethod(getCache(), classDeclarationId, memberInfo.getName(), memberInfo.getDescriptor()) != Cache.UNKNOWN) { + return declaringClassName; + } + } + final DeclaringClassFinder finder = new DeclaringClassFinder(memberInfo); + getCacheNavigator().walkSuperClasses(declaringClassName, finder); + final int className = finder.getDeclaringClassName(); + return className; + //return className != Cache.UNKNOWN? className : declaringClassName; + } + + + /** + * @return qualified names of the classes that should be additionally recompiled + */ + public int[] findDependentClasses(CompileContext context, Project project, Set successfullyCompiled) throws CacheCorruptedException { + markDependencies(context, project, successfullyCompiled); + return myMarkedInfos.toArray(); + } + + private void markDependencies(CompileContext context, Project project, final Set successfullyCompiled) throws CacheCorruptedException { + try { + if (LOG.isDebugEnabled()) { + LOG.debug("====================Marking dependent files====================="); + } + // myToUpdate can be modified during the mark procedure, so use toArray() to iterate it + ProgressManager.getInstance().getProgressIndicator().startNonCancelableSection(); // this will prevent PSI from throwing ProcessCancelledException while finding dependencies + try { + int[] qNamesToUpdate = myTraverseRoots.toArray(); + final SourceFileFinder sourceFileFinder = new SourceFileFinder(project, context); + final CachingSearcher searcher = new CachingSearcher(project); + final ChangedRetentionPolicyDependencyProcessor changedRetentionPolicyDependencyProcessor = new ChangedRetentionPolicyDependencyProcessor(project, searcher, this); + for (int nameIndex = 0; nameIndex < qNamesToUpdate.length; nameIndex++) { + int qName = qNamesToUpdate[nameIndex]; + int oldInfoId = getCache().getClassId(qName); + if (oldInfoId == Cache.UNKNOWN) { + continue; + } + int newInfoId = getNewClassesCache().getClassId(qName); + if (newInfoId != Cache.UNKNOWN) { // there is a new class file created + new DependencyProcessor(project, this, qName).run(); + ArrayList changed = new ArrayList(); + ArrayList removed = new ArrayList(); + findModifiedConstants(qName, changed, removed); + if (changed.size() > 0 || removed.size() > 0) { + new ChangedConstantsDependencyProcessor( + project, searcher, this, qName, + (FieldInfo[])changed.toArray(new FieldInfo[changed.size()]), + (FieldInfo[])removed.toArray(new FieldInfo[removed.size()]) + ).run(); + } + changedRetentionPolicyDependencyProcessor.checkAnnotationRetentionPolicyChanges(qName); + } + else { + boolean isSourceDeleted = false; + if (myClassesWithSourceRemoved.contains(qName)){ // no recompiled class file, check whether the classfile exists + isSourceDeleted = true; + } + else if (!(new File(getCache().getPath(oldInfoId)).exists())) { + final String qualifiedName = resolve(qName); + final String sourceFileName = getCache().getSourceFileName(oldInfoId); + final boolean markAsRemovedSource = ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + VirtualFile sourceFile = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName); + return (sourceFile == null || successfullyCompiled.contains(sourceFile))? Boolean.TRUE : Boolean.FALSE; + } + }).booleanValue(); + if (markAsRemovedSource) { + // for Inner classes: sourceFile may exist, but the inner class declaration in it - not, thus the source for the class info should be considered removed + isSourceDeleted = true; + markSourceRemoved(qName); + myMarkedInfos.remove(qName); // if the info has been marked already, the mark should be removed + } + } + if (isSourceDeleted) { + Dependency[] backDependencies = getCache().getBackDependencies(qName); + for (int idx = 0; idx < backDependencies.length; idx++) { + if (markTargetClassInfo(backDependencies[idx])) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+backDependencies[idx].getClassQualifiedName() + "; reason: no class file found for " + qName); + } + } + } + } + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("================================================================"); + } + } + finally { + ProgressManager.getInstance().getProgressIndicator().finishNonCancelableSection(); + } + } + catch (ProcessCanceledException ignored) { + // deliberately suppressed + } + } + + private void findModifiedConstants(final int qName, Collection changedConstants, Collection removedConstants) throws CacheCorruptedException { + int[] fields = getCache().getFieldIds(getCache().getClassDeclarationId(qName)); + for (int idx = 0; idx < fields.length; idx++) { + final int field = fields[idx]; + if (ClsUtil.isStatic(getCache().getFieldFlags(field)) && ClsUtil.isFinal(getCache().getFieldFlags(field))) { + int newField = CacheUtils.findFieldByName(getNewClassesCache(), getNewClassesCache().getClassDeclarationId(qName), getCache().getFieldName(field)); + if (newField == Cache.UNKNOWN) { + if (!ConstantValue.EMPTY_CONSTANT_VALUE.equals(getCache().getFieldConstantValue(field))) { // if the field was really compile time constant + removedConstants.add(getCache().createFieldInfo(field)); + } + } + else { + if (!getCache().getFieldConstantValue(field).equals(getNewClassesCache().getFieldConstantValue(newField)) ) { + changedConstants.add(getCache().createFieldInfo(field)); + } + } + } + } + } + + private void buildSubclassDependencies(final int qName, int targetClassQName) throws CacheCorruptedException { + final int targetClassId = getCache().getClassId(targetClassQName); + + final int superQName = getCache().getSuperQualifiedName(targetClassId); + if (superQName != Cache.UNKNOWN) { + int superClassId = getCache().getClassId(superQName); + if (superClassId != Cache.UNKNOWN) { + getCache().addSubclass(superClassId, qName); + buildSubclassDependencies(qName, superQName); + } + } + + int[] interfaces = getCache().getSuperInterfaces(targetClassId); + for (int idx = 0; idx < interfaces.length; idx++) { + final int interfaceName = interfaces[idx]; + int superId = getCache().getClassId(interfaceName); + if (superId != Cache.UNKNOWN) { + getCache().addSubclass(superId, qName); + buildSubclassDependencies(qName, interfaceName); + } + } + } + + + /** + * Marks ClassInfo targeted by the dependency + * @return true if really added, false otherwise + */ + public boolean markTargetClassInfo(Dependency dependency) throws CacheCorruptedException { + return markClassInfo(dependency.getClassQualifiedName(), false); + } + + /** + * Marks ClassInfo that corresponds to the specified qualified name + * If class info is already recompiled, it is not marked + * @return true if really added, false otherwise + */ + public boolean markClass(int qualifiedName) throws CacheCorruptedException { + return markClass(qualifiedName, false); + } + + /** + * Marks ClassInfo that corresponds to the specified qualified name + * If class info is already recompiled, it is not marked unless force parameter is true + * @return true if really added, false otherwise + */ + public boolean markClass(int qualifiedName, boolean force) throws CacheCorruptedException { + return markClassInfo(qualifiedName, force); + } + + public boolean isTargetClassInfoMarked(Dependency dependency) throws CacheCorruptedException { + return isClassInfoMarked(dependency.getClassQualifiedName()); + } + + public boolean isClassInfoMarked(int qName) throws CacheCorruptedException { + return myMarkedInfos.contains(qName); + } + + /** + * @return true if really marked, false otherwise + */ + private boolean markClassInfo(int qName, boolean force) throws CacheCorruptedException { + if (getCache().getClassId(qName) == Cache.UNKNOWN) { + return false; + } + if (myClassesWithSourceRemoved.contains(qName)) { + return false; // no need to recompile since source has been removed + } + if (!force) { + if (getNewClassesCache().getClassId(qName) != Cache.UNKNOWN) { // already recompiled + return false; + } + } + return myMarkedInfos.add(qName); + } + + public void dispose() { + if (myNewClassesCache != null) { + myNewClassesCache.wipe(); + } + if (myCache != null) { + myCache.dispose(); + } + try { + if (mySymbolTable != null) { + // important: compact symbol table only after all caches and indices are updated + // [jeka] switched off + //compactSymbolTable(mySymbolTable); + final File symbolTableFile = new File(mySymbolTableFilePath); + if (!symbolTableFile.exists()) { + symbolTableFile.createNewFile(); + } + + DataOutputStream symTableStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(symbolTableFile))); + try { + mySymbolTable.save(symTableStream); + } + finally { + symTableStream.close(); + } + } + } + catch (IOException e) { + LOG.error(e); // todo + } + } + + + public SymbolTable getSymbolTable() throws CacheCorruptedException { + if (mySymbolTable == null) { + mySymbolTable = loadSymbolTable(); + } + return mySymbolTable; + } + + public String resolve(int id) throws CacheCorruptedException { + return getSymbolTable().getSymbol(id); + } + + public void registerSuperListChange(int qName) { + myClassesWithSuperlistChanged.add(qName); + } + + public int[] getClassesWithSuperlistChanged() { + return myClassesWithSuperlistChanged.toArray(); + } + + /* + public int[] getPreviouslyRemoteClasses() { + return myPreviouslyRemoteClasses.toArray(); + } + */ + public boolean wasRemote(int qName) { + return myPreviouslyRemoteClasses.contains(qName); + } + + private SymbolTable loadSymbolTable() throws CacheCorruptedException { + SymbolTable symbolTable = null; + File symbolTableFile = new File(mySymbolTableFilePath); + try { + if (symbolTableFile.exists()) { + final byte[] buf = FileUtil.loadFileBytes(symbolTableFile); + DataInputStream stream = new DataInputStream(new ByteArrayInputStream(buf)); + try { + symbolTable = new SymbolTable(stream); + if ((symbolTable.getVersion() != CompilerConfiguration.DEPENDENCY_FORMAT_VERSION) || symbolTable.isFull()) { + throw new CacheCorruptedException("Compiler caches on disk have old format. Project rebuild is required."); + } + } + finally { + stream.close(); + } + } + else { + symbolTable = new SymbolTable(); + } + } + catch (IOException e) { + LOG.info(e); + throw new CacheCorruptedException(e); + } + return symbolTable; + } + + private class DeclaringClassFinder implements ClassInfoProcessor { + private int myMemberName; + private int myMemberDescriptor; + private int myDeclaringClass = Cache.UNKNOWN; + private boolean myIsField; + + public DeclaringClassFinder(MemberInfo memberInfo) { + myMemberName = memberInfo.getName(); + myMemberDescriptor = memberInfo.getDescriptor(); + myIsField = (memberInfo instanceof FieldInfo); + } + + public int getDeclaringClassName() { + return myDeclaringClass; + } + + public boolean process(int classQName) throws CacheCorruptedException { + final int classDeclarationId = getCache().getClassDeclarationId(classQName); + if (myIsField) { + final int fieldId = CacheUtils.findField(getCache(), classDeclarationId, myMemberName, myMemberDescriptor); + if (fieldId != Cache.UNKNOWN) { + myDeclaringClass = classQName; + } + } + else { + final int methodId = CacheUtils.findMethod(getCache(), classDeclarationId, myMemberName, myMemberDescriptor); + if (methodId != Cache.UNKNOWN) { + myDeclaringClass = classQName; + return false; + } + } + return true; + } + + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCacheNavigator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCacheNavigator.java new file mode 100644 index 00000000000..a84e4857a34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyCacheNavigator.java @@ -0,0 +1,70 @@ +/* + * @author: Eugene Zhuravlev + * Date: May 26, 2003 + * Time: 8:13:56 PM + */ +package com.intellij.compiler.make; + +import com.intellij.openapi.diagnostic.Logger; + +public class DependencyCacheNavigator { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.DependencyCacheNavigator"); + + private final Cache myCache; + private final DependencyCache myDepCache; + + public DependencyCacheNavigator(Cache cache, DependencyCache depCache) { + myCache = cache; + myDepCache = depCache; + } + + public void walkSuperClasses(int classQName, ClassInfoProcessor processor) throws CacheCorruptedException { + final int classId = myCache.getClassId(classQName); + if (classId == Cache.UNKNOWN) { + return; + } + int superQName = myCache.getSuperQualifiedName(classId); + + if (classQName == superQName) { + LOG.assertTrue(false, "Superclass qualified name is the same as class' name: " + classQName); + return; + } + + if (superQName != Cache.UNKNOWN) { + int superInfoId = myCache.getClassId(superQName); + if (superInfoId != Cache.UNKNOWN) { + if (processor.process(superQName)) { + walkSuperClasses(superQName, processor); + } + } + } + int[] superInterfaces = myCache.getSuperInterfaces(classId); + for (int idx = 0; idx < superInterfaces.length; idx++) { + int superInterfaceQName = superInterfaces[idx]; + int superInfoId = myCache.getClassId(superInterfaceQName); + if (superInfoId != Cache.UNKNOWN) { + if (processor.process(superInterfaceQName)) { + walkSuperClasses(superInterfaceQName, processor); + } + } + } + } + + public void walkSubClasses(int fromClassQName, ClassInfoProcessor processor) throws CacheCorruptedException { + final int[] subclasses = myCache.getSubclasses(myCache.getClassId(fromClassQName)); + for (int idx = 0; idx < subclasses.length; idx++) { + int subQName = subclasses[idx]; + if (fromClassQName == subQName) { + LOG.assertTrue(false, "Subclass qualified name is the same as class' name: " + fromClassQName); + return; + } + int subclassId = myCache.getClassId(subQName); + if (subclassId != Cache.UNKNOWN) { + if (!processor.process(subQName)) { + break; + } + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyProcessor.java new file mode 100644 index 00000000000..aa2661fa4fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/DependencyProcessor.java @@ -0,0 +1,903 @@ +/** + * created at Feb 19, 2002 + * @author Jeka + */ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.compiler.classParsing.ConstantValue; +import com.intellij.compiler.classParsing.FieldInfo; +import com.intellij.compiler.classParsing.MemberInfo; +import com.intellij.compiler.classParsing.MethodInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.ClsUtil; +import gnu.trove.TIntHashSet; +import org.apache.bcel.classfile.Utility; + +import java.util.*; + +public class DependencyProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.DependencyProcessor"); + private final DependencyCache myDependencyCache; + private final int myQName; + private final Set myAddedMembers = new HashSet(); + private final Set myRemovedMembers = new HashSet(); + private final Set myChangedMembers = new HashSet(); + private final Map myChangeDescriptions = new HashMap(); + private final Dependency[] myBackDependencies; + private final boolean myMembersChanged; + private final boolean mySuperInterfaceAdded; + private final boolean mySuperInterfaceRemoved; + private final boolean mySuperClassChanged; + private final boolean mySuperlistGenericSignatureChanged; + private final boolean mySuperClassAdded; + private final Project myProject; + private final boolean myIsAnnotation; + private final boolean myIsRemoteInterface; + private boolean myWereAnnotationTargetsRemoved; + + public DependencyProcessor(Project project, DependencyCache dependencyCache, int qName) throws CacheCorruptedException { + myProject = project; + myDependencyCache = dependencyCache; + myQName = qName; + final Cache cache = dependencyCache.getCache(); + final Cache newClassesCache = dependencyCache.getNewClassesCache(); + + myBackDependencies = cache.getBackDependencies(qName); + addAddedMembers(qName, cache, newClassesCache, myAddedMembers); + addRemovedMembers(qName, cache, newClassesCache, myRemovedMembers); + addChangedMembers(qName, cache, newClassesCache, myChangedMembers); + + myMembersChanged = myAddedMembers.size() > 0 || myRemovedMembers.size() > 0 || myChangedMembers.size() > 0; + // track changes in super list + final int oldCacheClassId = cache.getClassId(qName); + final int newCacheClassId = newClassesCache.getClassId(qName); + + myIsRemoteInterface = CacheUtils.isInterface(cache, myQName) && cache.isRemote(oldCacheClassId); + myIsAnnotation = ClsUtil.isAnnotation(cache.getFlags(oldCacheClassId)); + myWereAnnotationTargetsRemoved = myIsAnnotation && wereAnnotationTargesRemoved(cache, newClassesCache); + + int[] oldInterfaces = cache.getSuperInterfaces(oldCacheClassId); + int[] newInterfaces = newClassesCache.getSuperInterfaces(newCacheClassId); + mySuperInterfaceRemoved = wereInterfacesRemoved(oldInterfaces, newInterfaces); + mySuperInterfaceAdded = wereInterfacesRemoved(newInterfaces, oldInterfaces); + + mySuperlistGenericSignatureChanged = isSuperlistGenericSignatureChanged(cache.getGenericSignature(oldCacheClassId), newClassesCache.getGenericSignature(newCacheClassId)); + + boolean superclassesDiffer = cache.getSuperQualifiedName(oldCacheClassId) != newClassesCache.getSuperQualifiedName(newCacheClassId); + boolean wasDerivedFromObject = "java.lang.Object".equals(dependencyCache.resolve(cache.getSuperQualifiedName(oldCacheClassId))); + mySuperClassChanged = !wasDerivedFromObject && superclassesDiffer; + mySuperClassAdded = wasDerivedFromObject && superclassesDiffer; + } + + private boolean hasMembersWithoutDefaults(Set addedMembers) { + for (Iterator it = addedMembers.iterator(); it.hasNext();) { + MemberInfo memberInfo = (MemberInfo)it.next(); + if (memberInfo instanceof MethodInfo) { + final ConstantValue annotationDefault = ((MethodInfo)memberInfo).getAnnotationDefault(); + if (annotationDefault == null || ConstantValue.EMPTY_CONSTANT_VALUE.equals(annotationDefault)) { + return true; + } + } + } + return false; + } + + private boolean wereAnnotationDefaultsRemoved() { + for (Iterator it = myChangeDescriptions.keySet().iterator(); it.hasNext();) { + final MemberInfo memberInfo = it.next(); + if (memberInfo instanceof MethodInfo) { + MethodChangeDescription description = (MethodChangeDescription)myChangeDescriptions.get(memberInfo); + if (description.removedAnnotationDefault) { + return true; + } + } + } + return false; + } + + private boolean isSuperlistGenericSignatureChanged(int oldGenericSignature, int newGenericSignature) throws CacheCorruptedException { + if (oldGenericSignature == newGenericSignature) { + return false; + } + if (oldGenericSignature != -1 && newGenericSignature != -1) { + final SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + final String _oldGenericMethodSignature = cutFormalPatrams(symbolTable.getSymbol(oldGenericSignature)); + final String _newGenericMethodSignature = cutFormalPatrams(symbolTable.getSymbol(newGenericSignature)); + return !_oldGenericMethodSignature.equals(_newGenericMethodSignature); + } + return true; + } + + private String cutFormalPatrams(String genericClassSignature) { + if (genericClassSignature.charAt(0) == '<') { + int idx = genericClassSignature.indexOf('>'); + return genericClassSignature.substring(idx + 1); + } + return genericClassSignature; + } + + public void run() throws CacheCorruptedException { + if (LOG.isDebugEnabled()) { + LOG.debug("Checking dependencies for " + myDependencyCache.resolve(myQName)); + } + final boolean superListChanged = mySuperClassChanged || mySuperClassAdded || mySuperInterfaceAdded || mySuperInterfaceRemoved || mySuperlistGenericSignatureChanged; + if (superListChanged) { + myDependencyCache.registerSuperListChange(myQName); + } + final Cache oldCache = myDependencyCache.getCache(); + final Cache newCache = myDependencyCache.getNewClassesCache(); + + if (!myMembersChanged && + (oldCache.getFlags(oldCache.getClassId(myQName)) == newCache.getFlags(newCache.getClassId(myQName))) && + !superListChanged && + !myWereAnnotationTargetsRemoved) { + return; // nothing to do + } + + if (myIsAnnotation) { + if (hasMembersWithoutDefaults(myAddedMembers)) { + markAll(myBackDependencies, "; reason: added annotation type member without default " + myDependencyCache.resolve(myQName)); + return; + } + if (myRemovedMembers.size() > 0) { + markAll(myBackDependencies, "; reason: removed annotation type member " + myDependencyCache.resolve(myQName)); + return; + } + if (myChangedMembers.size() > 0) { // for annotations "changed" means return type changed + markAll(myBackDependencies, "; reason: changed annotation member's type " + myDependencyCache.resolve(myQName)); + return; + } + if (wereAnnotationDefaultsRemoved()) { + markAll(myBackDependencies, "; reason: removed annotation member's default value " + myDependencyCache.resolve(myQName)); + return; + } + if (myWereAnnotationTargetsRemoved) { + markAll(myBackDependencies, "; reason: removed annotation's targets " + myDependencyCache.resolve(myQName)); + return; + } + } + + final DependencyCacheNavigator cacheNavigator = myDependencyCache.getCacheNavigator(); + + if (mySuperClassChanged || mySuperInterfaceRemoved || mySuperlistGenericSignatureChanged) { + // superclass changed == old removed and possibly new added + // if anything (class or interface) in the superlist was removed, should recompile all subclasses (both direct and indirect) + // and all back-dependencies of this class and its subclasses + markAll(myBackDependencies, "; reason: deleted items from the superlist or changed superlist generic signature of " + myDependencyCache.resolve(myQName)); + cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() { + public boolean process(int classQName) throws CacheCorruptedException { + markAll(oldCache.getBackDependencies(classQName), "; reason: deleted items from the superlist or changed superlist generic signature of " + myDependencyCache.resolve(myQName)); + return true; + } + }); + return; + } + + final boolean isKindChanged = + (CacheUtils.isInterface(oldCache, myQName) && !CacheUtils.isInterface(newCache, myQName)) || + (!CacheUtils.isInterface(oldCache, myQName) && CacheUtils.isInterface(newCache, myQName)); + if (isKindChanged) { + markAll(myBackDependencies, "; reason: class kind changed (class/interface) " + myDependencyCache.resolve(myQName)); + cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() { + public boolean process(int classQName) throws CacheCorruptedException { + markAll(oldCache.getBackDependencies(classQName), "; reason: class kind changed (class/interface) " + myDependencyCache.resolve(myQName)); + return true; + } + }); + return; + } + + boolean becameFinal = !CacheUtils.isFinal(oldCache, myQName) && CacheUtils.isFinal(newCache, myQName); + if (becameFinal) { + markAll(myBackDependencies, "; reason: class became final: " + myDependencyCache.resolve(myQName)); + } + else { + boolean becameAbstract = !CacheUtils.isAbstract(oldCache, myQName) && CacheUtils.isAbstract(newCache, myQName); + boolean accessRestricted = MakeUtil.isMoreAccessible(oldCache.getFlags(oldCache.getClassId(myQName)), newCache.getFlags(newCache.getClassId(myQName))); + for (int idx = 0; idx < myBackDependencies.length; idx++) { + Dependency backDependency = myBackDependencies[idx]; + if (myDependencyCache.isTargetClassInfoMarked(backDependency)) continue; + + if (accessRestricted) { + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: " + myDependencyCache.resolve(myQName) + " made less accessible"); + } + } + continue; + } + if (becameAbstract) { + if (processClassBecameAbstract(backDependency)) { + continue; + } + } + if (isDependentOnRemovedMembers(backDependency)) { + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: the class uses removed members of "+myDependencyCache.resolve(myQName)); + } + } + continue; + } + if (isDependentOnChangedMembers(backDependency)) { + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: the class uses changed members of "+myDependencyCache.resolve(myQName)); + } + } + continue; + } + MethodInfo[] usedMethods = backDependency.getUsedMethods(); + if (isDependentOnEquivalentMethods(usedMethods, myRemovedMembers)) { + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: some overloaded methods of "+myDependencyCache.resolve(myQName)+ " were removed"); + } + } + continue; + } + if (isDependentOnEquivalentMethods(usedMethods, myAddedMembers)) { + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: some overloaded methods of "+myDependencyCache.resolve(myQName)+ " were added"); + } + } + continue; + } + } + } + + final Set methodsToCheck = new HashSet(); + extractMethods(myRemovedMembers, methodsToCheck, false); + extractMethods(myAddedMembers, methodsToCheck, false); + + processInheritanceDependencies(methodsToCheck.size() > 0); + + if (!MakeUtil.isAnonymous(myDependencyCache.resolve(myQName))) { + // these checks make no sence for anonymous classes + final TIntHashSet fieldNames = new TIntHashSet(); + extractFieldNames(myAddedMembers, fieldNames); + int addedFieldsCount = fieldNames.size(); + extractFieldNames(myRemovedMembers, fieldNames); + if (fieldNames.size() > 0) { + cacheNavigator.walkSuperClasses(myQName, new ClassInfoProcessor() { + public boolean process(final int classQName) throws CacheCorruptedException { + markUseDependenciesOnFields(classQName, fieldNames); + return true; + } + }); + } + if (addedFieldsCount > 0 && CacheUtils.isInterface(oldCache, myQName)) { + final TIntHashSet visitedClasses = new TIntHashSet(); + visitedClasses.add(myQName); + cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() { + public boolean process(int subclassQName) throws CacheCorruptedException { + markUseDependenciesOnFields(subclassQName, fieldNames); + visitedClasses.add(subclassQName); + cacheNavigator.walkSuperClasses(subclassQName, new ClassInfoProcessor() { + public boolean process(int superclassQName) throws CacheCorruptedException { + if (visitedClasses.contains(superclassQName)) { + return false; + } + markUseDependenciesOnFields(superclassQName, fieldNames); + visitedClasses.add(superclassQName); + return true; + } + }); + return true; + } + }); + } + + if (methodsToCheck.size() > 0) { + cacheNavigator.walkSuperClasses(myQName, new ClassInfoProcessor() { + public boolean process(int classQName) throws CacheCorruptedException { + markUseDependenciesOnEquivalentMethods(classQName, methodsToCheck, myQName); + return true; + } + }); + + cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() { + public boolean process(int classQName) throws CacheCorruptedException { + markUseDependenciesOnEquivalentMethods(classQName, methodsToCheck, myQName); + return true; + } + }); + } + } + } + + private static final int[] ALL_TARGETS = new int[] { + AnnotationTargets.ANNOTATION_TYPE, + AnnotationTargets.CONSTRUCTOR, + AnnotationTargets.FIELD, + AnnotationTargets.LOCAL_VARIABLE, + AnnotationTargets.METHOD, + AnnotationTargets.PACKAGE, + AnnotationTargets.PARAMETER, + AnnotationTargets.TYPE + }; + private boolean wereAnnotationTargesRemoved(final Cache oldCache, final Cache newCache) throws CacheCorruptedException { + final int oldAnnotationTargets = MakeUtil.getAnnotationTargets(oldCache, myQName, myDependencyCache.getSymbolTable()); + final int newAnnotationTargets = MakeUtil.getAnnotationTargets(newCache, myQName, myDependencyCache.getSymbolTable()); + if (oldAnnotationTargets == newAnnotationTargets) { + return false; + } + for (int idx = 0; idx < ALL_TARGETS.length; idx++) { + final int target = ALL_TARGETS[idx]; + if ((oldAnnotationTargets & target) != 0 && (newAnnotationTargets & target) == 0) { + return true; + } + } + return false; + } + + private boolean hasRetentionPolicyChanged(final Cache oldCache, final Cache newCache) throws CacheCorruptedException { + // if retention policy changed from SOURCE to CLASS or RUNTIME, all sources should be recompiled to propagate changes + final int oldPolicy = MakeUtil.getAnnotationRetentionPolicy(myQName, oldCache, myDependencyCache.getSymbolTable()); + final int newPolicy = MakeUtil.getAnnotationRetentionPolicy(myQName, newCache, myDependencyCache.getSymbolTable()); + if ((oldPolicy == RetentionPolicies.SOURCE) && (newPolicy == RetentionPolicies.CLASS || newPolicy == RetentionPolicies.RUNTIME)) { + return true; + } + return false; + } + + private void markAll(Dependency[] backDependencies, String reason) throws CacheCorruptedException { + for (int idx = 0; idx < backDependencies.length; idx++) { + Dependency backDependency = backDependencies[idx]; + if (myDependencyCache.markTargetClassInfo(backDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(backDependency.getClassQualifiedName()) + reason); + } + } + } + } + + private void extractFieldNames(Collection fromCollection, TIntHashSet toCollection) { + for (Iterator it = fromCollection.iterator(); it.hasNext();) { + MemberInfo memberInfo = (MemberInfo)it.next(); + if (memberInfo instanceof FieldInfo) { + toCollection.add(memberInfo.getName()); + } + } + } + + private void extractMethods(Collection fromCollection, Collection toCollection, boolean includeConstructors) { + for (Iterator it = fromCollection.iterator(); it.hasNext();) { + MemberInfo memberInfo = (MemberInfo)it.next(); + if (memberInfo instanceof MethodInfo) { + if (includeConstructors) { + toCollection.add(memberInfo); + } + else { + if (!((MethodInfo)memberInfo).isConstructor()) { + toCollection.add(memberInfo); + } + } + } + } + } + + private boolean processClassBecameAbstract(Dependency dependency) throws CacheCorruptedException { + MemberInfo[] usedMembers = dependency.getUsedMembers(); + for (int i = 0; i < usedMembers.length; i++) { + MemberInfo usedMember = usedMembers[i]; + if (usedMember instanceof MethodInfo && ((MethodInfo)usedMember).isConstructor()) { + if (myDependencyCache.markTargetClassInfo(dependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(dependency.getClassQualifiedName()) + "; reason: " + myDependencyCache.resolve(myQName) + " made abstract"); + } + } + return true; + } + } + return false; + } + + private boolean isDependentOnRemovedMembers(Dependency dependency) { + MemberInfo[] usedMembers = dependency.getUsedMembers(); + for (int idx = 0; idx < usedMembers.length; idx++) { + MemberInfo usedMember = usedMembers[idx]; + if (myRemovedMembers.contains(usedMember)) { + return true; + } + } + return false; + } + + private boolean isDependentOnChangedMembers(Dependency dependency) { + MemberInfo[] usedMembers = dependency.getUsedMembers(); + for (int idx = 0; idx < usedMembers.length; idx++) { + final MemberInfo usedMember = usedMembers[idx]; + if (myChangedMembers.contains(usedMember)) { + if (usedMember instanceof MethodInfo) { + final MethodChangeDescription changeDescription = (MethodChangeDescription)myChangeDescriptions.get(usedMember); + if (changeDescription.returnTypeDescriptorChanged || + changeDescription.returnTypeGenericSignatureChanged || + changeDescription.throwsListChanged || + changeDescription.staticPropertyChanged || + changeDescription.accessRestricted) { + return true; + } + } + else { // FieldInfo + return true; + } + } + } + return false; + } + + private boolean isDependentOnEquivalentMethods(MethodInfo[] checkedMembers, Set members) throws CacheCorruptedException { + // check if 'members' contains method with the same name and the same numbers of parameters, but with different types + if (members.size() == 0) return false; // optimization + for (int idx = 0; idx < checkedMembers.length; idx++) { + MethodInfo checkedMethod = checkedMembers[idx]; + if (hasEquivalentMethod(members, checkedMethod)) { + return true; + } + } + return false; + } + + private void markUseDependenciesOnEquivalentMethods(final int checkedInfoQName, Set methodsToCheck, int methodsClassName) throws CacheCorruptedException { + Dependency[] backDependencies = myDependencyCache.getCache().getBackDependencies(checkedInfoQName); + for (int idx = 0; idx < backDependencies.length; idx++) { + Dependency dependency = backDependencies[idx]; + if (myDependencyCache.isTargetClassInfoMarked(dependency)) continue; + if (isDependentOnEquivalentMethods(dependency.getUsedMethods(), methodsToCheck)) { + if (myDependencyCache.markTargetClassInfo(dependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(dependency.getClassQualifiedName()) + "; reason: more specific methods added to " + myDependencyCache.resolve(methodsClassName)); + } + } + myDependencyCache.addClassToUpdate(checkedInfoQName); + } + } + } + + private void markUseDependenciesOnFields(final int classQName, TIntHashSet fieldNames) throws CacheCorruptedException { + final Cache oldCache = myDependencyCache.getCache(); + Dependency[] backDependencies = oldCache.getBackDependencies(classQName); + for (int j = 0; j < backDependencies.length; j++) { + Dependency useDependency = backDependencies[j]; + if (!myDependencyCache.isTargetClassInfoMarked(useDependency)) { + FieldInfo[] usedFields = useDependency.getUsedFields(); + for (int idx = 0; idx < usedFields.length; idx++) { + FieldInfo field = usedFields[idx]; + if (fieldNames.contains(field.getName())) { + if (myDependencyCache.markTargetClassInfo(useDependency)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(useDependency.getClassQualifiedName()) + "; reason: conflicting fields were added to the hierarchy of the class " + myDependencyCache.resolve(classQName)); + } + } + myDependencyCache.addClassToUpdate(classQName); + break; // stop iterating fields + } + } + } + } + } + + private void processInheritanceDependencies(boolean hasRemovedMethods) throws CacheCorruptedException { + final Cache oldCache = myDependencyCache.getCache(); + final Cache newCache = myDependencyCache.getNewClassesCache(); + + boolean becameFinal = !CacheUtils.isFinal(oldCache, myQName) && CacheUtils.isFinal(newCache, myQName); + final SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + + final Set removedConcreteMethods = fetchNonAbstractMethods(myRemovedMembers); + final int[] subclasses = oldCache.getSubclasses(oldCache.getClassId(myQName)); + for (int idx = 0; idx < subclasses.length/*myBackDependencies.length*/; idx++) { + final int subclassQName = subclasses[idx]; + if (myDependencyCache.isClassInfoMarked(subclassQName)) { + continue; + } + + int subclassId = oldCache.getClassId(subclassQName); + if (subclassId == Cache.UNKNOWN) { + continue; + } + + if (hasRemovedMethods && myIsRemoteInterface && !CacheUtils.isInterface(oldCache, subclassQName)) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: methods were removed from remote interface: "+myDependencyCache.resolve(myQName)); + } + } + continue; + } + + if (mySuperClassAdded || mySuperInterfaceAdded) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: the superlist of "+myDependencyCache.resolve(myQName)+ " is changed"); + } + } + continue; + } + + // if info became final, mark direct inheritors + if (becameFinal) { + if (myQName == oldCache.getSuperQualifiedName(subclassId)) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: the class "+myDependencyCache.resolve(myQName)+ " was made final"); + } + } + continue; + } + } + + // process added members + for (Iterator it = myAddedMembers.iterator(); it.hasNext();) { + final MemberInfo member = (MemberInfo)it.next(); + if (member instanceof MethodInfo) { + final MethodInfo method = (MethodInfo)member; + if (method.isAbstract()) { + // all derived classes should be marked in case an abstract method was added + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: added abstract method to " + myDependencyCache.resolve(myQName)); + } + } + break; + } + if (!method.isPrivate()) { + int derivedMethod = CacheUtils.findMethodBySignature(oldCache, oldCache.getClassDeclarationId(subclassQName), method.getDescriptor(symbolTable), symbolTable); + if (derivedMethod != Cache.UNKNOWN) { + if (!method.getReturnTypeDescriptor(symbolTable).equals(CacheUtils.getMethodReturnTypeDescriptor(oldCache, derivedMethod, symbolTable))) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: return types of method " + method + " in base and derived classes are different"); + } + } + break; + } + if (MakeUtil.isMoreAccessible(method.getFlags(), oldCache.getMethodFlags(derivedMethod))) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: the method " + method + " in derived class is less accessible than in base class"); + } + } + break; + } + if (!CacheUtils.areArraysContentsEqual(method.getThrownExceptions(), oldCache.getMethodThrownExceptions(derivedMethod))) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: exception lists of " + method + " in base and derived classes are different"); + } + } + break; + } + } + if (hasGenericsNameClashes(method, oldCache, subclassQName)) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: found method with the same name, different generic signature, but the same erasure as " + method); + } + } + break; + } + } + } + else if (member instanceof FieldInfo){ + if (CacheUtils.findFieldByName(oldCache, oldCache.getClassDeclarationId(subclassQName), member.getName()) != Cache.UNKNOWN) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: added field " + member + " to base class"); + } + } + break; + } + } + } + + // process changed members + for (Iterator it = myChangedMembers.iterator(); it.hasNext();) { + final MemberInfo changedMember = (MemberInfo)it.next(); + if (changedMember instanceof MethodInfo) { + final MethodInfo oldMethod = (MethodInfo)changedMember; + MethodChangeDescription changeDescription = (MethodChangeDescription)myChangeDescriptions.get(oldMethod); + if (changeDescription.becameAbstract) { + if (!ClsUtil.isAbstract(oldCache.getFlags(subclassId))) { // if the subclass was not abstract + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: changed base method " + oldMethod); + } + } + break; + } + } + int derivedMethod = CacheUtils.findMethodBySignature(oldCache, oldCache.getClassDeclarationId(subclassQName), oldMethod.getDescriptor(symbolTable), symbolTable); + if (derivedMethod != Cache.UNKNOWN) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: changed base method " + oldMethod); + } + } + break; + } + } + } + + if (!ClsUtil.isAbstract(oldCache.getFlags(subclassId))) { + if (hasUnimplementedAbstractMethods(subclassQName, new HashSet(removedConcreteMethods))) { + if (myDependencyCache.markClass(subclassQName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mark dependent class "+myDependencyCache.resolve(subclassQName) + "; reason: the class should be declared abstract because abstract method implementation was removed from its superclass: " + myDependencyCache.resolve(myQName)); + } + } + } + } + } + } + + private boolean hasGenericsNameClashes(final MethodInfo baseMethod, final Cache oldCache, final int subclassQName) throws CacheCorruptedException { + // it is illegal if 2 methods in a hierarchy have 1) same name 2) different signatures 3) same erasure + final int[] methods = CacheUtils.findMethodsByName(oldCache, oldCache.getClassDeclarationId(subclassQName), baseMethod.getName()); + if (methods.length > 0) { + for (int i = 0; i < methods.length; i++) { + final int methodInSubclass = methods[i]; + if (ClsUtil.isBridge(oldCache.getMethodFlags(methodInSubclass))) { + continue; + } + if (baseMethod.getDescriptor() == oldCache.getMethodDescriptor(methodInSubclass) && + baseMethod.getGenericSignature() != oldCache.getMethodGenericSignature(methodInSubclass)) { + return true; + } + } + } + return false; + } + + private Set fetchNonAbstractMethods(Set membersToCheck) { + final Set methodsToCheck = new HashSet(); + for (Iterator it = membersToCheck.iterator(); it.hasNext();) { + final MemberInfo memberInfo = (MemberInfo)it.next(); + if (memberInfo instanceof MethodInfo) { + final MethodInfo methodInfo = (MethodInfo)memberInfo; + if (!methodInfo.isAbstract() && !methodInfo.isConstructor()) { + methodsToCheck.add(memberInfo); + } + } + } + return methodsToCheck; + } + + private boolean hasUnimplementedAbstractMethods(int superQName, final Set methodsToCheck) throws CacheCorruptedException { + if (myDependencyCache.getCache().getClassId(superQName) != Cache.UNKNOWN) { + if (hasBaseAbstractMethods(superQName, methodsToCheck)) { + return true; + } + return hasBaseAbstractMethodsInHierarchy(superQName, methodsToCheck); + } + else { + final String qName = myDependencyCache.resolve(superQName); + if (!"java.lang.Object".equals(qName)) { + if (hasBaseAbstractMethods2(qName, methodsToCheck)) { + return true; + } + } + } + return false; + } + + private boolean hasBaseAbstractMethodsInHierarchy(int fromClassQName, final Set methodsToCheck) throws CacheCorruptedException { + if (fromClassQName == Cache.UNKNOWN || methodsToCheck.size() == 0) { + return false; + } + final Cache cache = myDependencyCache.getCache(); + int superName = cache.getSuperQualifiedName(cache.getClassId(fromClassQName)); + if (superName != Cache.UNKNOWN) { + if (hasUnimplementedAbstractMethods(superName, methodsToCheck)) { + return true; + } + } + if (methodsToCheck.size() == 0) { + return false; + } + int[] superInterfaces = cache.getSuperInterfaces(cache.getClassId(fromClassQName)); + for (int idx = 0; idx < superInterfaces.length; idx++) { + if (hasUnimplementedAbstractMethods(superInterfaces[idx], methodsToCheck)) { + return true; + } + } + return false; + } + + private boolean hasBaseAbstractMethods(int qName, Set methodsToCheck) throws CacheCorruptedException { + final SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + final Cache oldCache = myDependencyCache.getCache(); + final Cache newCache = myDependencyCache.getNewClassesCache(); + final Cache cache = newCache.getClassId(qName) != Cache.UNKNOWN? newCache : oldCache; // use recompiled version (if any) for searching methods + for (Iterator it = methodsToCheck.iterator(); it.hasNext();) { + final MethodInfo methodInfo = (MethodInfo)it.next(); + final int superMethod = CacheUtils.findMethodBySignature(cache, cache.getClassDeclarationId(qName), methodInfo.getDescriptor(symbolTable), symbolTable); + if (superMethod != Cache.UNKNOWN) { + if (ClsUtil.isAbstract(cache.getMethodFlags(superMethod))) { + return true; + } + it.remove(); + } + } + return false; + } + + // search using PSI + private boolean hasBaseAbstractMethods2(final String qName, final Set methodsToCheck) throws CacheCorruptedException { + final boolean[] found = new boolean[] {false}; + final CacheCorruptedException ex = ApplicationManager.getApplication().runReadAction(new Computable() { + public CacheCorruptedException compute() { + try { + final PsiManager psiManager = PsiManager.getInstance(myProject); + final PsiClass aClass = psiManager.findClass(qName, GlobalSearchScope.allScope(myProject)); + if (aClass == null) { + return null; + } + final PsiElementFactory factory = psiManager.getElementFactory(); + final PsiNameHelper nameHelper = PsiManager.getInstance(myProject).getNameHelper(); + for (Iterator it = methodsToCheck.iterator(); it.hasNext();) { + final MethodInfo methodInfo = (MethodInfo)it.next(); + if (!nameHelper.isIdentifier(myDependencyCache.resolve(methodInfo.getName()), LanguageLevel.JDK_1_3)) { // fix for SCR 16068 + continue; + } + // language level 1.3 will prevent exceptions from PSI if there are methods named "assert" + final PsiMethod methodPattern = factory.createMethodFromText(getMethodText(methodInfo), null, LanguageLevel.JDK_1_3); + final PsiMethod superMethod = aClass.findMethodBySignature(methodPattern, true); + if (superMethod != null) { + if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + found[0] = true; + return null; + } + it.remove(); + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + catch (CacheCorruptedException e) { + return e; + } + return null; + } + }); + if (ex != null) { + throw ex; + } + return found[0]; + } + + private String getMethodText(MethodInfo methodInfo) throws CacheCorruptedException { + final SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + StringBuffer text = new StringBuffer(16); + final String returnType = Utility.signatureToString(methodInfo.getReturnTypeDescriptor(symbolTable)); + text.append(returnType); + text.append(" "); + text.append(myDependencyCache.resolve(methodInfo.getName())); + text.append("("); + final String[] parameterSignatures = methodInfo.getParameterDescriptors(symbolTable); + for (int idx = 0; idx < parameterSignatures.length; idx++) { + String parameterSignature = parameterSignatures[idx]; + if (idx > 0) { + text.append(","); + } + text.append(Utility.signatureToString(parameterSignature)); + text.append(" arg"); + text.append(idx); + } + text.append(")"); + return text.toString(); + } + + private static boolean wereInterfacesRemoved(int[] oldInterfaces, int[] newInterfaces) { + for (int idx = 0; idx < oldInterfaces.length; idx++) { + int oldInterface = oldInterfaces[idx]; + boolean found = false; + for (int jdx = 0; jdx < newInterfaces.length; jdx++) { + int newInterface = newInterfaces[jdx]; + found = (oldInterface == newInterface); + if (found) { + break; + } + } + if (!found) { + return true; + } + } + return false; + } + + private void addAddedMembers(int qName, Cache oldCache, Cache newCache, Collection members) throws CacheCorruptedException { + int[] newFields = newCache.getFieldIds(newCache.getClassDeclarationId(qName)); + for (int idx = 0; idx < newFields.length; idx++) { + int newField = newFields[idx]; + if (CacheUtils.findFieldByName(oldCache, oldCache.getClassDeclarationId(qName), newCache.getFieldName(newField)) == Cache.UNKNOWN) { + members.add(newCache.createFieldInfo(newField)); + } + } + int[] newMethods = newCache.getMethodIds(newCache.getClassDeclarationId(qName)); + SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + for (int idx = 0; idx < newMethods.length; idx++) { + int newMethod = newMethods[idx]; + final int name = newCache.getMethodName(newMethod); + final int methodDescriptor = newCache.getMethodDescriptor(newMethod); + final String methodSignature = CacheUtils.getMethodSignature(symbolTable.getSymbol(name), symbolTable.getSymbol(methodDescriptor)); + if (CacheUtils.findMethodBySignature(oldCache, oldCache.getClassDeclarationId(myQName), methodSignature, symbolTable) == Cache.UNKNOWN) { + members.add(newCache.createMethodInfo(newMethod)); + } + } + } + + private void addRemovedMembers(int qName, Cache oldCache, Cache newCache, Collection members) throws CacheCorruptedException { + addAddedMembers(qName, newCache, oldCache, members); + } + + private void addChangedMembers(final int qName, Cache oldCache, Cache newCache, Collection members) throws CacheCorruptedException { + int[] oldFields = oldCache.getFieldIds(oldCache.getClassDeclarationId(qName)); + for (int idx = 0; idx < oldFields.length; idx++) { + final int oldField = oldFields[idx]; + final int newField = CacheUtils.findFieldByName(newCache, newCache.getClassDeclarationId(qName), oldCache.getFieldName(oldField)); + if (newField != Cache.UNKNOWN) { + final FieldChangeDescription changeDescription = new FieldChangeDescription(oldCache, newCache, oldField, newField); + if (changeDescription.isChanged()) { + final FieldInfo fieldInfo = oldCache.createFieldInfo(oldField); + members.add(fieldInfo); + myChangeDescriptions.put(fieldInfo, changeDescription); + } + } + } + int[] oldMethods = oldCache.getMethodIds(oldCache.getClassDeclarationId(qName)); + final SymbolTable symbolTable = myDependencyCache.getSymbolTable(); + for (int idx = 0; idx < oldMethods.length; idx++) { + final int oldMethod = oldMethods[idx]; + final int name = oldCache.getMethodName(oldMethod); + final int methodDescriptor = oldCache.getMethodDescriptor(oldMethod); + final String signature = CacheUtils.getMethodSignature(symbolTable.getSymbol(name), symbolTable.getSymbol(methodDescriptor)); + final int newMethod = CacheUtils.findMethodBySignature(newCache, newCache.getClassDeclarationId(qName), signature, symbolTable); + if (newMethod != Cache.UNKNOWN) { + final MethodChangeDescription changeDescription = new MethodChangeDescription(oldCache, newCache, oldMethod, newMethod, symbolTable); + if (changeDescription.isChanged()) { + final MethodInfo methodInfo = oldCache.createMethodInfo(oldMethod); + members.add(methodInfo); + myChangeDescriptions.put(methodInfo, changeDescription); + } + } + } + } + + private boolean hasEquivalentMethod(Collection members, MethodInfo modelMethod) throws CacheCorruptedException { + String[] modelSignature = modelMethod.getParameterDescriptors(myDependencyCache.getSymbolTable()); + for (Iterator it = members.iterator(); it.hasNext();) { + MemberInfo member = (MemberInfo)it.next(); + + if (!(member instanceof MethodInfo)) continue; + final MethodInfo method = (MethodInfo)member; + + if (modelMethod.getName() != method.getName()) continue; + String[] methodSignature = method.getParameterDescriptors(myDependencyCache.getSymbolTable()); + + if (modelSignature.length != methodSignature.length) continue; + + for (int i = 0; i < methodSignature.length; i++) { + if (!methodSignature[i].equals(modelSignature[i])) { + if (LOG.isDebugEnabled()) { + LOG.debug("Equivalent: " + modelMethod.getDescriptor(myDependencyCache.getSymbolTable()) + " <=> " + method.getDescriptor(myDependencyCache.getSymbolTable())); + } + return true; + } + } + } + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/FieldChangeDescription.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/FieldChangeDescription.java new file mode 100644 index 00000000000..67df8b225df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/FieldChangeDescription.java @@ -0,0 +1,25 @@ +package com.intellij.compiler.make; + +/** + * @author Eugene Zhuravlev + * Date: Apr 7, 2004 + */ +class FieldChangeDescription extends ChangeDescription { + public final boolean flagsChanged; + public final boolean descriptorChanged; + public final boolean genericSignatureChanged; + + public FieldChangeDescription(final Cache oldCache, final Cache newCache, final int oldFieldId, final int newFieldId) throws CacheCorruptedException { + descriptorChanged = oldCache.getFieldDescriptor(oldFieldId) != newCache.getFieldDescriptor(newFieldId); + + flagsChanged = oldCache.getFieldFlags(oldFieldId) != newCache.getFieldFlags(newFieldId); + + final int oldGenericSignature = oldCache.getFieldGenericSignature(oldFieldId); + final int newGenericSignature = newCache.getFieldGenericSignature(newFieldId); + genericSignatureChanged = (oldGenericSignature != newGenericSignature); + } + + public boolean isChanged() { + return flagsChanged || descriptorChanged || genericSignatureChanged; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MakeUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MakeUtil.java new file mode 100644 index 00000000000..7f6f0bcab89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MakeUtil.java @@ -0,0 +1,255 @@ +/** + * created at Jan 17, 2002 + * @author Jeka + */ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.compiler.classParsing.*; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.cls.ClsUtil; + +public class MakeUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.MakeUtil"); + public static final int[] EMPTY_INT_ARRAY = new int[0]; + + + public static VirtualFile getSourceRoot(CompileContext context, Module module, VirtualFile file) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex(); + final VirtualFile root = fileIndex.getSourceRootForFile(file); + if (root != null) { + return root; + } + // try to find among roots of generated files. + final VirtualFile[] sourceRoots = context.getSourceRoots(module); + for (int idx = 0; idx < sourceRoots.length; idx++) { + final VirtualFile sourceRoot = sourceRoots[idx]; + if (fileIndex.isInSourceContent(sourceRoot)) { + continue; // skip content source roots, need only roots for generated files + } + if (VfsUtil.isAncestor(sourceRoot, file, false)) { + return sourceRoot; + } + } + return null; + } + + /** + * cuts inner or anonymous class' parts and translates package names to lower case + */ + private static String normalizeClassName(String qName) { + int index = qName.indexOf('$'); + if (index >= 0) { + qName = qName.substring(0, index); + } + if (SystemInfo.isFileSystemCaseSensitive) { + return qName; + } + // the name of a dir should be lowercased because javac seem to allow difference in case + // between the physical directory and package name. + final int dotIndex = qName.lastIndexOf('.'); + StringBuffer buf = new StringBuffer(qName); + for (int idx = 0; idx < dotIndex; idx++) { + buf.setCharAt(idx, Character.toLowerCase(buf.charAt(idx))); + } + return buf.toString(); + } + + public static boolean isAnonymous(String name) { + int index = name.lastIndexOf('$'); + if (index >= 0) { + index++; + if (index < name.length()) { + try { + Integer.parseInt(name.substring(index)); + return true; + } + catch (NumberFormatException e) { + } + } + } + return false; + } + + /* + not needed currently + public static String getEnclosingClassName(String anonymousQName) { + return anonymousQName.substring(0, anonymousQName.lastIndexOf('$')); + } + */ + + /* + not needed currently + public static boolean isNative(int flags) { + return (ClsUtil.ACC_NATIVE & flags) != 0; + } + */ + + /** + * tests if the accessibility, denoted by flags2 is less restricted than the accessibility denoted by flags1 + * @return true means flags1 is less restricted than flags2 + * false means flags1 define more restricted access than flags2 or they have equal accessibility + */ + public static boolean isMoreAccessible(int flags1, int flags2) { + if (ClsUtil.isPrivate(flags2)) { + return ClsUtil.isPackageLocal(flags1) || ClsUtil.isProtected(flags1) || ClsUtil.isPublic(flags1); + } + if (ClsUtil.isPackageLocal(flags2)) { + return ClsUtil.isProtected(flags1) || ClsUtil.isPublic(flags1); + } + if (ClsUtil.isProtected(flags2)) { + return ClsUtil.isPublic(flags1); + } + return false; + } + + public static String relativeClassPathToQName(String relativePath, char separator) { + int start = 0; + int end = relativePath.length() - ".class".length(); + if (relativePath.startsWith(String.valueOf(separator))) { + start += 1; + } + return (start <= end)? relativePath.substring(start, end).replace(separator, '.') : null; + } + + public static String parseObjectType(final String descriptor, int fromIndex) { + int semicolonIndex = descriptor.indexOf(';', fromIndex); + if (descriptor.charAt(fromIndex) == 'L' && semicolonIndex > fromIndex) { // isObjectType + return descriptor.substring(fromIndex + 1, semicolonIndex).replace('/', '.'); + } + if (descriptor.charAt(fromIndex) == '[' && (descriptor.length() - fromIndex) > 0) { // isArrayType + return parseObjectType(descriptor, fromIndex + 1); + } + return null; + } + + public static boolean isPrimitiveType(String descriptor) { + return + "V".equals(descriptor) || + "B".equals(descriptor) || + "C".equals(descriptor) || + "D".equals(descriptor) || + "F".equals(descriptor) || + "I".equals(descriptor) || + "J".equals(descriptor) || + "S".equals(descriptor) || + "Z".equals(descriptor); + } + + public static boolean isArrayType(String descriptor) { + return StringUtil.startsWithChar(descriptor, '['); + } + + public static String getComponentType(String descriptor) { + if (!isArrayType(descriptor)) { + return null; + } + return descriptor.substring(1); + } + + + /** + * @return a normalized path to source relative to a source root by class qualified name and sourcefile short name. + * The path uses forward slashes "/". + */ + public static String createRelativePathToSource(String qualifiedName, String srcName) { + qualifiedName = normalizeClassName(qualifiedName); + int index = qualifiedName.lastIndexOf('.'); + if (index >= 0) { + srcName = qualifiedName.substring(0, index).replace('.', '/') + "/" + srcName; + } + return srcName; + } + + public static boolean isInterface(int flags) { + return (ClsUtil.ACC_INTERFACE & flags) != 0; + } + + public static int getAnnotationTargets(final Cache cache, final int annotationQName, final SymbolTable symbolTable) throws CacheCorruptedException { + final AnnotationConstantValue targetAnnotation = findAnnotation( + "java.lang.annotation.Target", + cache.getRuntimeVisibleAnnotations(cache.getClassId(annotationQName)), symbolTable); + if (targetAnnotation == null) { + return AnnotationTargets.ALL; // all program elements are annotation targets by default + } + final AnnotationNameValuePair[] memberValues = targetAnnotation.getMemberValues(); + ConstantValueArray value = (ConstantValueArray)memberValues[0].getValue(); + final ConstantValue[] targets = value.getValue(); + int annotationTargets = 0; + for (int idx = 0; idx < targets.length; idx++) { + ConstantValue target = targets[idx]; + if (target instanceof EnumConstantValue) { + final String constantName = symbolTable.getSymbol(((EnumConstantValue)target).getConstantName()); + if ("TYPE".equals(constantName)) { + annotationTargets |= AnnotationTargets.TYPE; + } + if ("FIELD".equals(constantName)) { + annotationTargets |= AnnotationTargets.FIELD; + } + if ("METHOD".equals(constantName)) { + annotationTargets |= AnnotationTargets.METHOD; + } + if ("PARAMETER".equals(constantName)) { + annotationTargets |= AnnotationTargets.PARAMETER; + } + if ("CONSTRUCTOR".equals(constantName)) { + annotationTargets |= AnnotationTargets.CONSTRUCTOR; + } + if ("LOCAL_VARIABLE".equals(constantName)) { + annotationTargets |= AnnotationTargets.LOCAL_VARIABLE; + } + if ("ANNOTATION_TYPE".equals(constantName)) { + annotationTargets |= AnnotationTargets.ANNOTATION_TYPE; + } + if ("PACKAGE".equals(constantName)) { + annotationTargets |= AnnotationTargets.PACKAGE; + } + } + } + return annotationTargets; + } + + public static int getAnnotationRetentionPolicy(final int annotationQName, final Cache cache, final SymbolTable symbolTable) throws CacheCorruptedException { + final AnnotationConstantValue retentionPolicyAnnotation = findAnnotation( + "java.lang.annotation.Retention", + cache.getRuntimeVisibleAnnotations(cache.getClassId(annotationQName)), symbolTable + ); + if (retentionPolicyAnnotation == null) { + return RetentionPolicies.CLASS; // default retention policy + } + final AnnotationNameValuePair[] memberValues = retentionPolicyAnnotation.getMemberValues(); + final EnumConstantValue value = (EnumConstantValue)memberValues[0].getValue(); + final String constantName = symbolTable.getSymbol(value.getConstantName()); + if ("SOURCE".equals(constantName)) { + return RetentionPolicies.SOURCE; + } + if ("CLASS".equals(constantName)) { + return RetentionPolicies.CLASS; + } + if ("RUNTIME".equals(constantName)) { + return RetentionPolicies.RUNTIME; + } + LOG.error("Unknown retention policy: " + constantName); + return -1; + } + + public static AnnotationConstantValue findAnnotation(final String annotationQName, + AnnotationConstantValue[] annotations, final SymbolTable symbolTable) throws CacheCorruptedException { + for (int idx = 0; idx < annotations.length; idx++) { + final AnnotationConstantValue annotation = annotations[idx]; + if (annotationQName.equals(symbolTable.getSymbol(annotation.getAnnotationQName()))) { + return annotation; + } + } + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MethodChangeDescription.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MethodChangeDescription.java new file mode 100644 index 00000000000..744e771b234 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/MethodChangeDescription.java @@ -0,0 +1,68 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.SymbolTable; +import com.intellij.compiler.classParsing.ConstantValue; +import com.intellij.compiler.classParsing.GenericMethodSignature; +import com.intellij.compiler.classParsing.SignatureParsingException; +import com.intellij.util.cls.ClsUtil; + +/** + * @author Eugene Zhuravlev + * Date: Apr 7, 2004 + */ +class MethodChangeDescription extends ChangeDescription { + public final boolean returnTypeDescriptorChanged; + public final boolean returnTypeGenericSignatureChanged; + public final boolean throwsListChanged; + public final boolean flagsChanged; + public final boolean staticPropertyChanged; + public final boolean accessRestricted; + public final boolean becameAbstract; + public final boolean removedAnnotationDefault; + + // TODO: handle changes of parameters? + public MethodChangeDescription(final Cache oldCache, final Cache newCache, final int oldMethod, final int newMethod, SymbolTable symbolTable) throws CacheCorruptedException { + final String oldRtDescriptor = CacheUtils.getMethodReturnTypeDescriptor(oldCache, oldMethod, symbolTable); + final String newRtDescriptor = CacheUtils.getMethodReturnTypeDescriptor(newCache, newMethod, symbolTable); + returnTypeDescriptorChanged = !oldRtDescriptor.equals(newRtDescriptor); + + final int oldGenericSignature = oldCache.getMethodGenericSignature(oldMethod); + final int newGenericSignature = newCache.getMethodGenericSignature(newMethod); + if (oldGenericSignature == newGenericSignature) { + returnTypeGenericSignatureChanged = false; + } + else { + if (oldGenericSignature != -1 && newGenericSignature != -1) { + try { + final GenericMethodSignature _oldGenericMethodSignature = GenericMethodSignature.parse(symbolTable.getSymbol(oldGenericSignature)); + final GenericMethodSignature _newGenericMethodSignature = GenericMethodSignature.parse(symbolTable.getSymbol(newGenericSignature)); + returnTypeGenericSignatureChanged = !_oldGenericMethodSignature.getReturnTypeSignature().equals(_newGenericMethodSignature.getReturnTypeSignature()); + } + catch (SignatureParsingException e) { + throw new CacheCorruptedException(e); + } + } + else { + returnTypeGenericSignatureChanged = true; + } + } + + throwsListChanged = !CacheUtils.areArraysContentsEqual(oldCache.getMethodThrownExceptions(oldMethod), newCache.getMethodThrownExceptions(newMethod)); + + final int oldFlags = oldCache.getMethodFlags(oldMethod); + final int newFlags = newCache.getMethodFlags(newMethod); + flagsChanged = oldFlags != newFlags; + + staticPropertyChanged = (ClsUtil.isStatic(oldFlags) && !ClsUtil.isStatic(newFlags)) || (!ClsUtil.isStatic(oldFlags) && ClsUtil.isStatic(newFlags)); // was not static and became static or was static and became not static + accessRestricted = MakeUtil.isMoreAccessible(oldFlags, newFlags); + becameAbstract = !ClsUtil.isAbstract(oldFlags) && ClsUtil.isAbstract(newFlags); + + final ConstantValue oldDefault = oldCache.getAnnotationDefault(oldMethod); + final ConstantValue newDefault = newCache.getAnnotationDefault(newMethod); + removedAnnotationDefault = (oldDefault != null && !ConstantValue.EMPTY_CONSTANT_VALUE.equals(oldDefault)) && (newDefault == null || ConstantValue.EMPTY_CONSTANT_VALUE.equals(newDefault)); + } + + public boolean isChanged() { + return returnTypeDescriptorChanged || throwsListChanged || flagsChanged || returnTypeGenericSignatureChanged || removedAnnotationDefault; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/RetentionPolicies.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/RetentionPolicies.java new file mode 100644 index 00000000000..05536074080 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/RetentionPolicies.java @@ -0,0 +1,27 @@ +package com.intellij.compiler.make; + +/** + * @author Eugene Zhuravlev + * Date: Apr 7, 2004 + */ +public interface RetentionPolicies { + /** + * Annotations are to be discarded by the compiler. + */ + int SOURCE = 0x1; + + /** + * Annotations are to be recorded in the class file by the compiler + * but need not be retained by the VM at run time. This is the default + * behavior. + */ + int CLASS = 0x2; + + /** + * Annotations are to be recorded in the class file by the compiler and + * retained by the VM at run time, so they may be read reflectively. + */ + int RUNTIME = 0x4; + + int ALL = SOURCE | CLASS | RUNTIME; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/SourceFileFinder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/SourceFileFinder.java new file mode 100644 index 00000000000..65edf0f28ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/make/SourceFileFinder.java @@ -0,0 +1,88 @@ +package com.intellij.compiler.make; + +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.HashMap; + +import java.util.Iterator; +import java.util.Map; + +/** + * Assumes that source roots in the project has not changed and caches the snapshot of source roots for effective searching + * User: JEKA + * Date: Jul 17, 2003 + * Time: 9:52:26 PM + */ +public class SourceFileFinder { + private final Project myProject; + private final CompileContext myCompileContext; + private Map myProjectSourceRoots = null; + + public SourceFileFinder(Project project, CompileContext compileContext) { + myProject = project; + myCompileContext = compileContext; + } + + public VirtualFile findSourceFile(String qualifiedName, String srcName) { + String relativePath = MakeUtil.createRelativePathToSource(qualifiedName, srcName); + Map dirs = getAllSourceRoots(); + if (!StringUtil.startsWithChar(relativePath, '/')) { + relativePath = "/" + relativePath; + } + LocalFileSystem fs = LocalFileSystem.getInstance(); + for (Iterator it = dirs.keySet().iterator(); it.hasNext();) { + final VirtualFile dir = (VirtualFile)it.next(); + final String prefix = dirs.get(dir); + String path; + if (prefix.length() > 0 ) { + if (CompilerUtil.startsWith(relativePath, prefix)) { + // if there is package prefix assigned to the root, the relative path should be corrected + path = dir.getPath() + relativePath.substring(prefix.length() - 1); + } + else { + // if there is package prefix, but the relative path does not match it, skip the root + continue; + } + } + else { + path = dir.getPath() + relativePath; + } + VirtualFile file = fs.findFileByPath(path); + if (file != null) { + return file; + } + } + return null; + } + + private Map getAllSourceRoots() { + if (myProjectSourceRoots == null) { + myProjectSourceRoots = new HashMap(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final Module[] allModules = ModuleManager.getInstance(myProject).getModules(); + for (int idx = 0; idx < allModules.length; idx++) { + final VirtualFile[] sourceRoots = myCompileContext.getSourceRoots(allModules[idx]); + for (int i = 0; i < sourceRoots.length; i++) { + final VirtualFile sourceRoot = sourceRoots[i]; + String packageName = fileIndex.getPackageNameByDirectory(sourceRoot); + myProjectSourceRoots.put(sourceRoot, packageName == null || packageName.length() == 0? "" : "/" + packageName.replace('.', '/') + "/"); + } + } + } + }); + } + return myProjectSourceRoots; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/ComparingUtils.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/ComparingUtils.java new file mode 100644 index 00000000000..4440cb75924 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/ComparingUtils.java @@ -0,0 +1,33 @@ +package com.intellij.compiler.options; + +import com.intellij.ui.RawCommandLineEditor; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public class ComparingUtils { + public static boolean isModified(JCheckBox checkBox, boolean value) { + return checkBox.isSelected() != value; + } + + public static boolean isModified(JTextField textField, int value) { + try { + int fieldValue = Integer.parseInt(textField.getText().trim()); + return fieldValue != value; + } + catch(NumberFormatException e) { + return false; + } + } + + public static boolean isModified(RawCommandLineEditor editor, String value) { + return !editor.getText().equals(value); + } + + public static boolean isModified(JTextField textField, String value) { + return !textField.getText().equals(value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerConfigurable.java new file mode 100644 index 00000000000..dfc6127d97e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerConfigurable.java @@ -0,0 +1,70 @@ +package com.intellij.compiler.options; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class CompilerConfigurable implements ProjectComponent, Configurable { + private CompilerUIConfigurable myDelegateConfigurable; + private Project myProject; + + public static CompilerConfigurable getInstance(Project project) { + return project.getComponent(CompilerConfigurable.class); + } + + public CompilerConfigurable(Project project) { + myProject = project; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public String getDisplayName() { + return "Compiler"; + } + + public boolean isModified() { + return myDelegateConfigurable.isModified(); + } + + public void reset() { + myDelegateConfigurable.reset(); + } + + public void apply() throws ConfigurationException { + myDelegateConfigurable.apply(); + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableCompiler.png"); + } + + public JComponent createComponent() { + myDelegateConfigurable = new CompilerUIConfigurable(myProject); + return myDelegateConfigurable.createComponent(); + } + + public void disposeUIResources() { + myDelegateConfigurable = null; + } + + public String getHelpTopic() { + return "project.propCompiler"; + } + + public String getComponentName() { + return "CompilerConfigurable"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerUIConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerUIConfigurable.java new file mode 100644 index 00000000000..8c73c15f170 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/CompilerUIConfigurable.java @@ -0,0 +1,207 @@ +package com.intellij.compiler.options; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerWorkspaceConfiguration; +import com.intellij.compiler.RmicSettings; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.Options; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.regex.PatternSyntaxException; + +public class CompilerUIConfigurable implements Configurable { + private JPanel myPanel; + private JPanel myExcludeTablePanel; + private JavaCompilersTab myJavaCompilersTab; + private Project myProject; + private ExcludeFromCompilePanel myExcludeFromCompilePanel; + + private JTextField myResourcePatternsField; + private JCheckBox myCbCompileInBackground; + private JCheckBox myCbClearOutputDirectory; + private JPanel myTabbedPanePanel; + private RmicConfigurable myRmicConfigurable; + private JCheckBox myCbCloseMessageViewOnSuccess; + private JCheckBox myCbCompileDependent; + private JRadioButton myDoNotDeploy; + private JRadioButton myDeploy; + private JRadioButton myShowDialog; + + public CompilerUIConfigurable(final Project project) { + myProject = project; + + myExcludeFromCompilePanel = new ExcludeFromCompilePanel(project); + myExcludeFromCompilePanel.setBorder(BorderFactory.createCompoundBorder( + IdeBorderFactory.createTitledBorder("Exclude from Compile"), BorderFactory.createEmptyBorder(2, 2, 2, 2)) + ); + myExcludeTablePanel.setLayout(new BorderLayout()); + myExcludeTablePanel.add(myExcludeFromCompilePanel, BorderLayout.CENTER); + + myTabbedPanePanel.setLayout(new BorderLayout()); + final TabbedPaneWrapper tabbedPane = new TabbedPaneWrapper(); + myJavaCompilersTab = new JavaCompilersTab(project); + tabbedPane.addTab("Java Compiler", myJavaCompilersTab.createComponent()); + myRmicConfigurable = new RmicConfigurable(RmicSettings.getInstance(project)); + tabbedPane.addTab("RMI Compiler", myRmicConfigurable.createComponent()); + myTabbedPanePanel.add(tabbedPane.getComponent(), BorderLayout.CENTER); + + myCbCompileInBackground.setMnemonic('o'); + myCbClearOutputDirectory.setMnemonic('l'); + myCbCloseMessageViewOnSuccess.setMnemonic('m'); + myCbCompileDependent.setMnemonic('d'); + + ButtonGroup deployGroup = new ButtonGroup(); + deployGroup.add(myShowDialog); + deployGroup.add(myDeploy); + deployGroup.add(myDoNotDeploy); + + } + + + public void reset() { + myExcludeFromCompilePanel.reset(); + + myJavaCompilersTab.reset(); + + myRmicConfigurable.reset(); + + final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject); + final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject); + myCbCompileInBackground.setSelected(workspaceConfiguration.COMPILE_IN_BACKGROUND); + myCbCloseMessageViewOnSuccess.setSelected(workspaceConfiguration.CLOSE_MESSAGE_VIEW_IF_SUCCESS); + myCbCompileDependent.setSelected(workspaceConfiguration.COMPILE_DEPENDENT_FILES); + myCbClearOutputDirectory.setSelected(configuration.isClearOutputDirectory()); + + configuration.convertPatterns(); + + myResourcePatternsField.setText(patternsToString(configuration.getResourceFilePatterns())); + + if (configuration.DEPLOY_AFTER_MAKE == Options.SHOW_DIALOG) { + myShowDialog.setSelected(true); + } + else if (configuration.DEPLOY_AFTER_MAKE == Options.PERFORM_ACTION_AUTOMATICALLY) { + myDeploy.setSelected(true); + } + else { + myDoNotDeploy.setSelected(true); + } + } + + private static String patternsToString(final String[] patterns) { + final StringBuffer extensionsString = new StringBuffer(); + for (int idx = 0; idx < patterns.length; idx++) { + if (idx > 0) { + extensionsString.append(";"); + } + extensionsString.append(patterns[idx]); + } + return extensionsString.toString(); + } + + public void apply() throws ConfigurationException { + myExcludeFromCompilePanel.apply(); + + myJavaCompilersTab.apply(); + + myRmicConfigurable.apply(); + + CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject); + final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject); + workspaceConfiguration.COMPILE_IN_BACKGROUND = myCbCompileInBackground.isSelected(); + workspaceConfiguration.CLOSE_MESSAGE_VIEW_IF_SUCCESS = myCbCloseMessageViewOnSuccess.isSelected(); + workspaceConfiguration.COMPILE_DEPENDENT_FILES = myCbCompileDependent.isSelected(); + configuration.setClearOutputDirectory(myCbClearOutputDirectory.isSelected()); + + configuration.removeResourceFilePatterns(); + String extensionString = myResourcePatternsField.getText().trim(); + applyResourcePatterns(extensionString, CompilerConfiguration.getInstance(myProject)); + + configuration.DEPLOY_AFTER_MAKE = getSelectedDeploymentOption(); + + } + + private static void applyResourcePatterns(String extensionString, final CompilerConfiguration configuration) + throws ConfigurationException { + StringTokenizer tokenizer = new StringTokenizer(extensionString, ";", false); + java.util.List errors = new ArrayList(); + + while (tokenizer.hasMoreTokens()) { + String namePattern = tokenizer.nextToken(); + try { + configuration.addResourceFilePattern(namePattern); + } + catch (PatternSyntaxException e) { + errors.add(new String[]{namePattern, e.getMessage()}); + } + } + + if (errors.size() > 0) { + StringBuffer message = new StringBuffer("The following resource patterns are malformed:"); + for (Iterator it = errors.iterator(); it.hasNext();) { + String[] pair = (String[])it.next(); + message.append("\n\n"); + message.append(pair[0]); + message.append(": "); + message.append(pair[1]); + } + + throw new ConfigurationException(message.toString(), "Malformed Resource Patterns"); + } + } + + public boolean isModified() { + if (myExcludeFromCompilePanel.isModified()) { + return true; + } + + boolean isModified = false; + isModified |= myJavaCompilersTab.isModified(); + isModified |= myRmicConfigurable.isModified(); + + final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject); + isModified |= ComparingUtils.isModified(myCbCompileInBackground, workspaceConfiguration.COMPILE_IN_BACKGROUND); + isModified |= ComparingUtils.isModified(myCbCloseMessageViewOnSuccess, workspaceConfiguration.CLOSE_MESSAGE_VIEW_IF_SUCCESS); + isModified |= ComparingUtils.isModified(myCbCompileDependent, workspaceConfiguration.COMPILE_DEPENDENT_FILES); + + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + isModified |= ComparingUtils.isModified(myCbClearOutputDirectory, compilerConfiguration.isClearOutputDirectory()); + isModified |= ComparingUtils.isModified(myResourcePatternsField, patternsToString(compilerConfiguration.getResourceFilePatterns())); + isModified |= compilerConfiguration.DEPLOY_AFTER_MAKE != getSelectedDeploymentOption(); + + return isModified; + } + + private int getSelectedDeploymentOption() { + if (myShowDialog.isSelected()) return Options.SHOW_DIALOG; + if (myDeploy.isSelected()) return Options.PERFORM_ACTION_AUTOMATICALLY; + return Options.DO_NOTHING; + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public void disposeUIResources() { + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavaCompilersTab.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavaCompilersTab.java new file mode 100644 index 00000000000..d023ecc044d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavaCompilersTab.java @@ -0,0 +1,112 @@ +package com.intellij.compiler.options; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.JavacSettings; +import com.intellij.compiler.JikesSettings; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public class JavaCompilersTab implements Configurable{ + private JPanel myPanel; + private JPanel myContentPanel; + private CardLayout myCardLayout; + private JRadioButton myRbSetJavacCompiler; + private JRadioButton myRbSetJikesCompiler; + + private String myDefaultCompiler; + private JikesConfigurable myJikesConfigurable; + private JavacConfigurable myJavacConfigurable; + private CompilerConfiguration myCompilerConfiguration; + + public JavaCompilersTab(final Project project) { + myCompilerConfiguration = CompilerConfiguration.getInstance(project); + myJavacConfigurable = new JavacConfigurable(JavacSettings.getInstance(project)); + myJikesConfigurable = new JikesConfigurable(JikesSettings.getInstance(project)); + + myCardLayout = new CardLayout(); + myContentPanel.setLayout(myCardLayout); + myContentPanel.add(myJavacConfigurable.createComponent(), CompilerConfiguration.JAVAC); + myContentPanel.add(myJikesConfigurable.createComponent(), CompilerConfiguration.JIKES); + + final ButtonGroup group = new ButtonGroup(); + group.add(myRbSetJavacCompiler); + group.add(myRbSetJikesCompiler); + myRbSetJavacCompiler.addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent e) { + setDefaultCompiler(CompilerConfiguration.JAVAC); + } + } + ); + + myRbSetJikesCompiler.addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent e) { + setDefaultCompiler(CompilerConfiguration.JIKES); + } + } + ); + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public boolean isModified() { + return myJavacConfigurable.isModified() || myJikesConfigurable.isModified() || !Comparing.equal(myDefaultCompiler, myCompilerConfiguration.getDefaultCompiler()); + } + + public void apply() throws ConfigurationException { + myJavacConfigurable.apply(); + myJikesConfigurable.apply(); + myCompilerConfiguration.setDefaultCompiler(myDefaultCompiler); + } + + public void reset() { + myJavacConfigurable.reset(); + myJikesConfigurable.reset(); + setDefaultCompiler(myCompilerConfiguration.getDefaultCompiler()); + } + + public void disposeUIResources() { + } + + private void setDefaultCompiler(String compiler) { + if(compiler == null) { + compiler = CompilerConfiguration.JAVAC; + } + if(CompilerConfiguration.JAVAC.equals(compiler)) { + myRbSetJavacCompiler.setSelected(true); + } + else if(CompilerConfiguration.JIKES.equals(compiler)) { + myRbSetJikesCompiler.setSelected(true); + } + myDefaultCompiler = compiler; + myCardLayout.show(myContentPanel, compiler); + myContentPanel.revalidate(); + myContentPanel.repaint(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavacConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavacConfigurable.java new file mode 100644 index 00000000000..806f21ec94c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JavacConfigurable.java @@ -0,0 +1,87 @@ +package com.intellij.compiler.options; + +import com.intellij.compiler.JavacSettings; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.ui.RawCommandLineEditor; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public class JavacConfigurable implements Configurable{ + private JPanel myPanel; + private JCheckBox myCbDebuggingInfo; + private JCheckBox myCbDeprecation; + private JCheckBox myCbGenerateNoWarnings; + private JCheckBox myUseGenericsCompilerCheckbox; + private RawCommandLineEditor myAdditionalOptionsField; + private JTextField myJavacMaximumHeapField; + private JavacSettings myJavacSettings; + + public JavacConfigurable(final JavacSettings javacSettings) { + myJavacSettings = javacSettings; + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public boolean isModified() { + boolean isModified = false; + isModified |= ComparingUtils.isModified(myJavacMaximumHeapField, myJavacSettings.MAXIMUM_HEAP_SIZE); + + isModified |= ComparingUtils.isModified(myCbDeprecation, myJavacSettings.DEPRECATION); + isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJavacSettings.DEBUGGING_INFO); + isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJavacSettings.GENERATE_NO_WARNINGS); + isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myJavacSettings.ADDITIONAL_OPTIONS_STRING); + isModified |= ComparingUtils.isModified(myUseGenericsCompilerCheckbox, myJavacSettings.USE_GENERICS_COMPILER); + return isModified; + } + + public void apply() throws ConfigurationException { + + try { + myJavacSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText()); + if(myJavacSettings.MAXIMUM_HEAP_SIZE < 1) { + myJavacSettings.MAXIMUM_HEAP_SIZE = 128; + } + } + catch(NumberFormatException exception) { + myJavacSettings.MAXIMUM_HEAP_SIZE = 128; + } + + myJavacSettings.DEPRECATION = myCbDeprecation.isSelected(); + myJavacSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected(); + myJavacSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected(); + myJavacSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText(); + myJavacSettings.USE_GENERICS_COMPILER = myUseGenericsCompilerCheckbox.isSelected(); + } + + public void reset() { + myJavacMaximumHeapField.setText(""+myJavacSettings.MAXIMUM_HEAP_SIZE); + myCbDeprecation.setSelected(myJavacSettings.DEPRECATION); + myCbDebuggingInfo.setSelected(myJavacSettings.DEBUGGING_INFO); + myCbGenerateNoWarnings.setSelected(myJavacSettings.GENERATE_NO_WARNINGS); + myAdditionalOptionsField.setText(myJavacSettings.ADDITIONAL_OPTIONS_STRING); + myUseGenericsCompilerCheckbox.setSelected(myJavacSettings.USE_GENERICS_COMPILER); + } + + public void disposeUIResources() { + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JikesConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JikesConfigurable.java new file mode 100644 index 00000000000..ce14c174181 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/JikesConfigurable.java @@ -0,0 +1,89 @@ +package com.intellij.compiler.options; + +import com.intellij.compiler.JikesSettings; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.RawCommandLineEditor; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public class JikesConfigurable implements Configurable{ + private JPanel myPanel; + private JCheckBox myCbDebuggingInfo; + private JCheckBox myCbDeprecation; + private JCheckBox myCbGenerateNoWarnings ; + private RawCommandLineEditor myAdditionalOptionsField; + private JTextField myPathField; + private JButton myJikesPathFieldBrowseButton; + private final JikesSettings myJikesSettings; + + public JikesConfigurable(JikesSettings jikesSettings) { + myJikesSettings = jikesSettings; + myJikesPathFieldBrowseButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myPathField, descriptor); + if (files.length != 0) { + myPathField.setText(files[0].getPath().replace('/', File.separatorChar)); + } + } + }); + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public boolean isModified() { + boolean isModified = false; + isModified |= ComparingUtils.isModified(myPathField, myJikesSettings.JIKES_PATH.replace('/', File.separatorChar)); + isModified |= ComparingUtils.isModified(myCbDeprecation, myJikesSettings.DEPRECATION); + isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJikesSettings.DEBUGGING_INFO); + isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJikesSettings.GENERATE_NO_WARNINGS); + isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myJikesSettings.ADDITIONAL_OPTIONS_STRING); + return isModified; + } + + public void apply() throws ConfigurationException { + myJikesSettings.JIKES_PATH = myPathField.getText().trim().replace(File.separatorChar, '/'); + myJikesSettings.DEPRECATION = myCbDeprecation.isSelected(); + myJikesSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected(); + myJikesSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected(); + myJikesSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText(); + } + + public void reset() { + myPathField.setText(myJikesSettings.JIKES_PATH.replace('/', File.separatorChar)); + myCbDeprecation.setSelected(myJikesSettings.DEPRECATION); + myCbDebuggingInfo.setSelected(myJikesSettings.DEBUGGING_INFO); + myCbGenerateNoWarnings.setSelected(myJikesSettings.GENERATE_NO_WARNINGS); + myAdditionalOptionsField.setText(myJikesSettings.ADDITIONAL_OPTIONS_STRING); + } + + public void disposeUIResources() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/RmicConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/RmicConfigurable.java new file mode 100644 index 00000000000..5b25875cba7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/options/RmicConfigurable.java @@ -0,0 +1,89 @@ +package com.intellij.compiler.options; + +import com.intellij.compiler.RmicSettings; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.ui.RawCommandLineEditor; + +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author Eugene Zhuravlev + * Date: Mar 30, 2004 + */ +public class RmicConfigurable implements Configurable{ + private JPanel myPanel; + private JCheckBox myCbEnabled; + private JCheckBox myCbGenerateIiopStubs; + private JCheckBox myCbDebuggingInfo; + private JCheckBox myCbGenerateNoWarnings; + private RawCommandLineEditor myAdditionalOptionsField; + private RmicSettings myRmicSettings; + private JLabel myFieldLabel; + + public RmicConfigurable(final RmicSettings javacSettings) { + myRmicSettings = javacSettings; + myCbEnabled.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + setOptionsEnabled(e.getStateChange() == ItemEvent.SELECTED); + } + }); + } + + private void setOptionsEnabled(final boolean selected) { + myCbGenerateIiopStubs.setEnabled(selected); + myCbGenerateNoWarnings.setEnabled(selected); + myCbDebuggingInfo.setEnabled(selected); + myFieldLabel.setEnabled(selected); + myAdditionalOptionsField.setEnabled(selected); + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public boolean isModified() { + boolean isModified = false; + isModified |= ComparingUtils.isModified(myCbEnabled, myRmicSettings.IS_EANABLED); + isModified |= ComparingUtils.isModified(myCbGenerateIiopStubs, myRmicSettings.GENERATE_IIOP_STUBS); + isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myRmicSettings.DEBUGGING_INFO); + isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myRmicSettings.GENERATE_NO_WARNINGS); + isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myRmicSettings.ADDITIONAL_OPTIONS_STRING); + return isModified; + } + + public void apply() throws ConfigurationException { + myRmicSettings.IS_EANABLED = myCbEnabled.isSelected(); + myRmicSettings.GENERATE_IIOP_STUBS = myCbGenerateIiopStubs.isSelected(); + myRmicSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected(); + myRmicSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected(); + myRmicSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText(); + } + + public void reset() { + myCbEnabled.setSelected(myRmicSettings.IS_EANABLED); + setOptionsEnabled(myRmicSettings.IS_EANABLED); + myCbGenerateIiopStubs.setSelected(myRmicSettings.GENERATE_IIOP_STUBS); + myCbDebuggingInfo.setSelected(myRmicSettings.DEBUGGING_INFO); + myCbGenerateNoWarnings.setSelected(myRmicSettings.GENERATE_NO_WARNINGS); + myAdditionalOptionsField.setText(myRmicSettings.ADDITIONAL_OPTIONS_STRING); + } + + public void disposeUIResources() { + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressDialog.java new file mode 100644 index 00000000000..8e1c2834735 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressDialog.java @@ -0,0 +1,145 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 22, 2003 + * Time: 2:41:11 PM + */ +package com.intellij.compiler.progress; + +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.util.Alarm; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class CompilerProgressDialog extends DialogWrapper{ + private JLabel myStatusLabel = new JLabel(); + private JLabel myStatisticsLabel = new JLabel(); + private JButton myCancelButton = new JButton("Cancel"); + private JButton myBackgroundButton = new JButton("Background"); + private JPanel myFunPanel = new JPanel(new BorderLayout()); + private CompilerProgressIndicator myProgressIndicator; + private Alarm myInstallFunAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + public CompilerProgressDialog(final CompilerProgressIndicator progressIndicator, Project project){ + super(project, false); + myProgressIndicator = progressIndicator; + setTitle("Compile Progress"); + init(); + setCrossClosesWindow(false); + + final JComponent cmp = ProgressManager.getInstance().getProvidedFunComponent(project, "compilation"); + if (cmp != null) { + Runnable installer = new Runnable() { + public void run() { + if (progressIndicator.isRunning() && !progressIndicator.isCanceled() && isShowing()) { + setFunComponent(cmp); + } + } + }; + myInstallFunAlarm.addRequest(installer, 3000, progressIndicator.getModalityState()); + } + } + + private void setFunComponent(JComponent c) { + myFunPanel.removeAll(); + if (c != null) { + myFunPanel.add(new JSeparator(), BorderLayout.NORTH); + myFunPanel.add(c, BorderLayout.CENTER); + myFunPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + } + pack(); + centerRelativeToParent(); + } + + public void setStatusText(String text) { + myStatusLabel.setText(text); + } + + public void setStatisticsText(String text) { + myStatisticsLabel.setText(text); + } + + protected JComponent createSouthPanel(){ + return myFunPanel; + } + + protected Border createContentPaneBorder(){ + return null; + } + + protected JComponent createCenterPanel(){ + JPanel panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + + myStatisticsLabel.setHorizontalAlignment(SwingConstants.LEFT); + myStatisticsLabel.setPreferredSize(new Dimension(380,20)); + panel.add( + myStatisticsLabel, + new GridBagConstraints(0,0,1,1,1,1,GridBagConstraints.SOUTHWEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,2,0),0,0) + ); + + myStatusLabel.setHorizontalAlignment(SwingConstants.LEFT); + myStatusLabel.setPreferredSize(new Dimension(380,20)); + panel.add( + myStatusLabel, + new GridBagConstraints(0,1,1,1,1,1,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL,new Insets(2,0,0,0),0,0) + ); + + myCancelButton.setFocusPainted(false); + panel.add( + myCancelButton, + new GridBagConstraints(1,0,1,1,0,1,GridBagConstraints.SOUTH,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0) + ); + + myBackgroundButton.setMnemonic('B'); + myBackgroundButton.setFocusPainted(false); + panel.add( + myBackgroundButton, + new GridBagConstraints(1,1,1,1,0,1,GridBagConstraints.NORTH,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0) + ); + + myCancelButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myCancelButton.setEnabled(false); + myProgressIndicator.cancel(); + } + } + ); + + myBackgroundButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myBackgroundButton.setEnabled(false); + myProgressIndicator.sendToBackground(); + } + } + ); + + return panel; + } + + public void doCancelAction() { + myCancelButton.setEnabled(false); + myProgressIndicator.cancel(); + } + + protected boolean isProgressDialog() { + return true; + } + + public String getStatusText() { + return myStatusLabel.getText(); + } + + public String getStatistics() { + return myStatisticsLabel.getText(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressIndicator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressIndicator.java new file mode 100644 index 00000000000..8359a802c8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/compiler/progress/CompilerProgressIndicator.java @@ -0,0 +1,493 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jan 22, 2003 + * Time: 2:25:31 PM + */ +package com.intellij.compiler.progress; + +import com.intellij.compiler.CompilerMessageImpl; +import com.intellij.compiler.CompilerWorkspaceConfiguration; +import com.intellij.compiler.impl.CompilerErrorTreeView; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.compiler.CompilationStatusListener; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.compiler.CompilerMessage; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.*; +import com.intellij.util.Alarm; +import com.intellij.util.ui.MessageCategory; +import com.intellij.pom.Navigatable; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.StringTokenizer; + +public class CompilerProgressIndicator extends ProgressIndicatorBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.progress.CompilerProgressIndicator"); + private static final boolean IS_UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode(); + private static final int UPDATE_INTERVAL = 50; //msec. 20 frames per second. + private static final Key CONTENT_ID_KEY = Key.create("CONTENT_ID"); + private final Key myContentId = Key.create("compile_content"); + private CompilerProgressDialog myDialog; + private NewErrorTreeViewPanel myErrorTreeView; + private final Object myMessageViewLock = new Object(); + private final Project myProject; + private final String myContentName; + private boolean myIsBackgroundMode; + private int myErrorCount = 0; + private int myWarningCount = 0; + private String myStatisticsText = ""; + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + + public CompilerProgressIndicator(Project project, boolean compileInBackground, String contentName) { + myProject = project; + myIsBackgroundMode = compileInBackground; + myContentName = contentName; + } + + public void cancel() { + if (!isCanceled()) { + super.cancel(); + closeUI(); + } + } + + public void setText(String text) { + super.setText(text); + updateProgressText(); + } + + public void setText2(String text) { + myStatisticsText = text; + updateProgressText(); + } + + public void setFraction(double fraction) { + super.setFraction(fraction); + updateProgressText(); + } + + public void addMessage(final CompilerMessage message) { + openMessageView(); + if (CompilerMessageCategory.ERROR.equals(message.getCategory())) { + myErrorCount += 1; + } + if (CompilerMessageCategory.WARNING.equals(message.getCategory())) { + myWarningCount += 1; + } + if (ApplicationManager.getApplication().isDispatchThread()) { + doAddMessage(message); + } + else { + final Window window = getWindow(); + final ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MMODAL; + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + doAddMessage(message); + } + }, modalityState); + } + } + + private void doAddMessage(final CompilerMessage message) { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + final Navigatable navigatable = message.getNavigatable(); + final VirtualFile file = message.getVirtualFile(); + final int type = translateCategory(message.getCategory()); + final String[] text = convertMessage(message); + if (navigatable != null) { + final String groupName = file != null? file.getPresentableUrl() : message.getCategory().getPresentableText(); + myErrorTreeView.addMessage(type, text, groupName, navigatable, message.getExportTextPrefix(), message.getRenderTextPrefix(), null); + } + else { + myErrorTreeView.addMessage(type, text, file, -1, -1, null); + } + } + } + } + + private String[] convertMessage(final CompilerMessage message) { + String text = message.getMessage(); + if (text.indexOf("\n") < 0) { + return new String[]{text}; + } + ArrayList lines = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(text, "\n", false); + while (tokenizer.hasMoreTokens()) { + lines.add(tokenizer.nextToken()); + } + return lines.toArray(new String[lines.size()]); + } + + public static int translateCategory(CompilerMessageCategory category) { + if (CompilerMessageCategory.ERROR.equals(category)) { + return MessageCategory.ERROR; + } + if (CompilerMessageCategory.WARNING.equals(category)) { + return MessageCategory.WARNING; + } + if (CompilerMessageCategory.STATISTICS.equals(category)) { + return MessageCategory.STATISTICS; + } + if (CompilerMessageCategory.INFORMATION.equals(category)) { + return MessageCategory.INFORMATION; + } + LOG.error("Unknown message category: " + category); + return 0; + } + + public void start() { + super.start(); + if (IS_UNIT_TEST_MODE) { + return; + } + if (myIsBackgroundMode) { + openMessageView(); + } + else { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (isRunning()) { + synchronized (myMessageViewLock) { + // clear messages from the previous compilation + if (myErrorTreeView == null) { + // if message view != null, the contents has already been cleared + removeAllContents(myProject, null); + } + } + final CompilerProgressDialog dialog = openProgressDialog(); + dialog.show(); + } + } + }, ModalityState.NON_MMODAL); + } + } + + public void stop() { + super.stop(); + if (!isCanceled()) { // when cancelled the UI is already closed + closeUI(); + } + } + + private void updateProgressText() { + if (IS_UNIT_TEST_MODE) { + return; + } + if (myAlarm.getActiveRequestCount() == 0) { + myAlarm.addRequest(myRepaintRequest, UPDATE_INTERVAL); + } + } + + private Runnable myRepaintRequest = new Runnable() { + public void run() { + SwingUtilities.invokeLater(myRepaintRunnable); + } + private Runnable myRepaintRunnable = new Runnable() { + public void run() { + String s = getText(); + if (getFraction() > 0) { + s += " " + (int)(getFraction() * 100 + 0.5) + "%"; + } + + synchronized (myMessageViewLock) { + if (myIsBackgroundMode) { + if (myErrorTreeView != null) { + myErrorTreeView.setProgressText(s); + myErrorTreeView.setProgressStatistics(myStatisticsText); + } + } + else { + if (myDialog != null) { + myDialog.setStatusText(s); + myDialog.setStatisticsText(myStatisticsText); + } + } + } + } + }; + }; + + public void sendToBackground() { + myIsBackgroundMode = true; + openMessageView(); + activateMessageView(); + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { // when cancelled, openMessageView() may not create the view + myErrorTreeView.setProgressText(myDialog.getStatusText()); + myErrorTreeView.setProgressStatistics(myDialog.getStatistics()); + } + } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + closeProgressDialog(); + } + }); + } + + // error tree view handling: + + private void openMessageView() { + if (IS_UNIT_TEST_MODE) { + return; + } + if (isCanceled()) { + return; + } + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + return; + } + myErrorTreeView = new CompilerErrorTreeView(myProject); + myErrorTreeView.setProcessController(new NewErrorTreeViewPanel.ProcessController() { + public void stopProcess() { + cancel(); + } + + public boolean isProcessStopped() { + return !isRunning(); + } + }); + } + final Window window = getWindow(); + final ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MMODAL; + // the work with ToolWindowManager should be done in the Swing thread + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final MessageView messageView = myProject.getComponent(MessageView.class); + final JComponent component; + synchronized (myMessageViewLock) { + component = myErrorTreeView.getComponent(); + } + final Content content = PeerFactory.getInstance().getContentFactory().createContent(component, myContentName, true); + content.putUserData(CONTENT_ID_KEY, myContentId); + messageView.addContent(content); + new CloseListener(content, messageView); + removeAllContents(myProject, content); + messageView.setSelectedContent(content); + ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW); + if (toolWindow != null) { + if (CompilerWorkspaceConfiguration.getInstance(myProject).COMPILE_IN_BACKGROUND) { + toolWindow.activate(null); + } + else { + toolWindow.show(null); + } + } + updateProgressText(); + } + }, modalityState); + } + + public void showCompilerContent() { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + final MessageView messageView = myProject.getComponent(MessageView.class); + Content[] contents = messageView.getContents(); + for (int idx = 0; idx < contents.length; idx++) { + Content content = contents[idx]; + if (content.getUserData(CONTENT_ID_KEY) != null) { + messageView.setSelectedContent(content); + return; + } + } + } + } + } + + public static void removeAllContents(Project project, Content notRemove) { + MessageView messageView = project.getComponent(MessageView.class); + Content[] contents = messageView.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (content.isPinned()) continue; + if (content == notRemove) continue; + if (content.getUserData(CONTENT_ID_KEY) != null) { // the content was added by me + messageView.removeContent(content); + } + } + } + + private void activateMessageView() { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW).activate(null); + } + } + } + + private void closeUI() { + if (IS_UNIT_TEST_MODE) { + return; + } + Window window = getWindow(); + ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MMODAL; + final Application application = ApplicationManager.getApplication(); + application.invokeLater(new Runnable() { + public void run() { + closeProgressDialog(); + final boolean closeViewOnSuccess = CompilerWorkspaceConfiguration.getInstance(myProject).CLOSE_MESSAGE_VIEW_IF_SUCCESS; + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + final boolean hasMessagesToRead = myErrorCount > 0 || myWarningCount > 0; + final boolean shouldRetainView = hasMessagesToRead || !closeViewOnSuccess; + if (shouldRetainView) { + addMessage( + new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, + myErrorCount + (myErrorCount == 1 ? " error" : " errors"), null, -1, -1)); + addMessage( + new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, + myWarningCount + (myWarningCount == 1 ? " warning" : " warnings"), null, -1, -1)); + activateMessageView(); + myErrorTreeView.selectFirstMessage(); + } + else { + removeAllContents(myProject, null); + } + } + } + } + }, modalityState); + } + + public Window getWindow(){ + if (!myIsBackgroundMode && myDialog != null) { + return SwingUtilities.windowForComponent(myDialog.getContentPane()); + } + else{ + return null; + } + } + + private CompilerProgressDialog openProgressDialog() { + synchronized (myMessageViewLock) { + if (myDialog == null) { + myDialog = new CompilerProgressDialog(this, myProject); + } + return myDialog; + } + } + + private void closeProgressDialog() { + synchronized (myMessageViewLock) { + if (myDialog != null) { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + myDialog = null; + } + } + } + + private class CloseListener extends ContentManagerAdapter implements ProjectManagerListener { + private Content myContent; + private ContentManager myContentManager; + private boolean myIsApplicationExitingOrProjectClosing = false; + private boolean myUserAcceptedCancel = false; + + public boolean canCloseProject(final Project project) { + if (shouldAskUser()) { + int result = Messages.showOkCancelDialog( + myProject, + "The compiler is running. Proceed with project closing?", + "Compiler Running", + Messages.getQuestionIcon() + ); + if (result != 0) { + return false; // veto closing + } + myUserAcceptedCancel = true; + + final CompilerManager compilerManager = CompilerManager.getInstance(project); + compilerManager.addCompilationStatusListener(new CompilationStatusListener() { + public void compilationFinished(boolean aborted, int errors, int warnings) { + compilerManager.removeCompilationStatusListener(this); + ProjectUtil.closeProject(project); + } + }); + cancel(); + return false; // cancel compiler and let it finish, after compilation close the project, but currently - veto closing + } + return !isRunning(); + } + + public CloseListener(Content content, ContentManager contentManager) { + myContent = content; + myContentManager = contentManager; + contentManager.addContentManagerListener(this); + ProjectManagerEx.getInstanceEx().addProjectManagerListener(myProject, this); + } + + public void contentRemoved(ContentManagerEvent event) { + if (event.getContent() == myContent) { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + myErrorTreeView = null; + if (isRunning()) { + cancel(); + } + } + } + myContentManager.removeContentManagerListener(this); + myContent.release(); + myContent = null; + } + } + + public void contentRemoveQuery(ContentManagerEvent event) { + if (event.getContent() == myContent) { + if (!isCanceled() && shouldAskUser()) { + int result = Messages.showOkCancelDialog( + myProject, + "The compiler is running. Terminate it?", + "Compiler Running", + Messages.getQuestionIcon() + ); + if (result != 0) { + event.consume(); // veto closing + } + myUserAcceptedCancel = true; + } + } + } + + private boolean shouldAskUser() { + if (myUserAcceptedCancel) { + return false; // do not ask second time if user already accepted closing + } + return !myIsApplicationExitingOrProjectClosing && isRunning(); + } + + public void projectOpened(Project project) { + } + + public void projectClosed(Project project) { + if (myContent != null) { + myContentManager.removeContent(myContent); + } + } + + public void projectClosing(Project project) { + myIsApplicationExitingOrProjectClosing = true; + ProjectManagerEx.getInstanceEx().removeProjectManagerListener(myProject, this); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebugException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebugException.java new file mode 100644 index 00000000000..26755259cbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebugException.java @@ -0,0 +1,10 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger; + +public class DebugException extends RuntimeException { + public DebugException() { + super("DebugException"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerInvocationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerInvocationUtil.java new file mode 100644 index 00000000000..8efdc3e703c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerInvocationUtil.java @@ -0,0 +1,81 @@ +package com.intellij.debugger; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DebuggerInvocationUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.DebuggerInvocationUtil"); + + public static void invokeLater(final Project project, final Runnable runnable) { + LOG.assertTrue(runnable != null); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if(project == null || project.isDisposed()) return; + + runnable.run(); + } + }); + } + + public static void invokeLater(final Project project, final Runnable runnable, ModalityState state) { + LOG.assertTrue(runnable != null); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if(project == null || project.isDisposed()) return; + + runnable.run(); + } + }, state); + } + + public static void invokeAndWait(final Project project, final Runnable runnable, ModalityState state) { + LOG.assertTrue(runnable != null); + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + if(project == null || project.isDisposed()) return; + + runnable.run(); + } + }, state); + } + + public static T commitAndRunReadAction(Project project, final com.intellij.debugger.EvaluatingComputable computable) throws EvaluateException { + final Throwable[] ex = new Throwable[] { null }; + T result = PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Computable() { + public T compute() { + try { + return computable.compute(); + } + catch (RuntimeException e) { + ex[0] = e; + } + catch (Exception th) { + ex[0] = th; + } + + return null; + } + }); + + if(ex[0] != null) { + if(ex[0] instanceof RuntimeException) { + throw (RuntimeException)ex[0]; + } + else { + throw (EvaluateException) ex[0]; + } + } + + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerManagerEx.java new file mode 100644 index 00000000000..60c158dfb9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/DebuggerManagerEx.java @@ -0,0 +1,41 @@ +package com.intellij.debugger; + +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerManagerListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.openapi.project.Project; + +import java.util.Collection; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public abstract class DebuggerManagerEx extends DebuggerManager { + public static DebuggerManagerEx getInstanceEx(Project project) { + return (DebuggerManagerEx)DebuggerManager.getInstance(project); + } + public abstract BreakpointManager getBreakpointManager(); + + public abstract Collection getSessions(); + public abstract DebuggerSession getSession(DebugProcess debugProcess); + + public abstract DebuggerContextImpl getContext(); + public abstract DebuggerStateManager getContextManager(); + + public abstract void addDebuggerManagerListener(DebuggerManagerListener debuggerManagerListener); + public abstract void removeDebuggerManagerListener(DebuggerManagerListener debuggerManagerListener); + + public abstract DebuggerSession attachVirtualMachine(String sessionName, RunProfileState state, + RemoteConnection connection, + boolean pollConnection) throws ExecutionException; + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/EvaluatingComputable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/EvaluatingComputable.java new file mode 100644 index 00000000000..13ac9c73825 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/EvaluatingComputable.java @@ -0,0 +1,12 @@ +package com.intellij.debugger; + +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface EvaluatingComputable { + T compute() throws EvaluateException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/HelpID.java new file mode 100644 index 00000000000..b13caec9c51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/HelpID.java @@ -0,0 +1,13 @@ +/* + * @author: Eugene Zhuravlev + * Date: Nov 12, 2002 + * Time: 3:25:10 PM + */ +package com.intellij.debugger; + +public interface HelpID { + String LINE_BREAKPOINTS = "debugging.lineBreakpoint"; + String METHOD_BREAKPOINTS = "debugging.methodBreakpoint"; + String EXCEPTION_BREAKPOINTS = "debugging.exceptionBreakpoint"; + String FIELD_WATCHPOINTS = "debugging.fieldWatchpoint"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/InstanceFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/InstanceFilter.java new file mode 100644 index 00000000000..d5722018483 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/InstanceFilter.java @@ -0,0 +1,70 @@ +package com.intellij.debugger; + +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 org.jdom.Element; + +/** + * User: lex + * Date: Aug 29, 2003 + * Time: 2:49:27 PM + */ +public class InstanceFilter implements JDOMExternalizable{ + public static final InstanceFilter[] EMPTY_ARRAY = new InstanceFilter[0]; + + public long ID = 0; + public boolean ENABLED = true; + + protected InstanceFilter(long ID, boolean ENABLED) { + this.ID = ID; + this.ENABLED = ENABLED; + } + + public long getId() { + return ID; + } + + public boolean isEnabled() { + return ENABLED; + } + + public void setId(long id) { + ID = id; + } + + public void setEnabled(boolean enabled) { + ENABLED = enabled; + } + + public static InstanceFilter create(String pattern) { + return new InstanceFilter(Long.parseLong(pattern), true); + } + + public static InstanceFilter create(final ClassFilter filter) { + return new InstanceFilter(Long.parseLong(filter.getPattern()), filter.isEnabled()); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public static ClassFilter[] createClassFilters(InstanceFilter[] filters) { + ClassFilter [] cFilters = new ClassFilter[filters.length]; + for (int i = 0; i < cFilters.length; i++) { + InstanceFilter instanceFilter = filters[i]; + + ClassFilter classFilter = new ClassFilter(); + classFilter.setEnabled(instanceFilter.isEnabled()); + classFilter.setPattern(Long.toString(instanceFilter.getId())); + + cFilters[i] = classFilter; + } + return cFilters; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AddToWatchAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AddToWatchAction.java new file mode 100644 index 00000000000..1b6342a36f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AddToWatchAction.java @@ -0,0 +1,107 @@ +/* + * Class AddToWatchAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.debugger.DebuggerInvocationUtil; + +public class AddToWatchAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + + if(debuggerContext == null) return; + + final DebuggerSession session = debuggerContext.getDebuggerSession(); + if(session == null) return; + final MainWatchPanel watchPanel = DebuggerPanelsManager.getInstance(debuggerContext.getProject()).getWatchPanel(); + + if(watchPanel == null) return; + + final DebuggerTreeNodeImpl[] selectedNodes = getSelectedNodes(e.getDataContext()); + + if(selectedNodes != null && selectedNodes.length > 0) { + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + for (int idx = 0; idx < selectedNodes.length; idx++) { + DebuggerTreeNodeImpl node = selectedNodes[idx]; + final NodeDescriptorImpl descriptor = node.getDescriptor(); + final TextWithImportsImpl expression = DebuggerTreeNodeExpression.createEvaluationText(node, debuggerContext); + if (expression != null) { + DebuggerInvocationUtil.invokeLater(session.getProject(), new Runnable() { + public void run() { + NodeDescriptorImpl watchDescriptor = watchPanel.getWatchTree().addWatch(expression).getDescriptor(); + watchDescriptor.displayAs(descriptor); + } + }); + } + } + } + + protected void commandCancelled() { + DebuggerInvocationUtil.invokeLater(debuggerContext.getProject(), new Runnable() { + public void run() { + for (int idx = 0; idx < selectedNodes.length; idx++) { + DebuggerTreeNodeImpl node = selectedNodes[idx]; + final NodeDescriptorImpl descriptor = node.getDescriptor(); + + if(descriptor instanceof WatchItemDescriptor) { + + final TextWithImportsImpl expression = (TextWithImportsImpl) ((WatchItemDescriptor) descriptor).getEvaluationText(); + if(expression != null) { + NodeDescriptorImpl watchDescriptor = watchPanel.getWatchTree().addWatch(expression).getDescriptor(); + watchDescriptor.displayAs(descriptor); + } + } + } + } + }); + } + }); + } else { + final Editor editor = (Editor)e.getDataContext().getData(DataConstants.EDITOR); + + TextWithImportsImpl editorText = DebuggerUtilsEx.getEditorText(editor); + + if(editorText != null) { + watchPanel.getWatchTree().addWatch(editorText); + } + } + } + + public void update(AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNodes = getSelectedNodes(e.getDataContext()); + boolean enabled; + if (selectedNodes != null) { + enabled = true; + if (getPanel(e.getDataContext()) instanceof MainWatchPanel) { + for (int i = 0; i < selectedNodes.length; i++) { + DebuggerTreeNodeImpl node = selectedNodes[i]; + NodeDescriptorImpl descriptor = node.getDescriptor(); + if(!(descriptor instanceof ValueDescriptorImpl)) { + enabled = false; + break; + } + } + } + } else { + final Editor editor = (Editor)e.getDataContext().getData(DataConstants.EDITOR); + + enabled = DebuggerUtilsEx.getEditorText(editor) != null ; + } + e.getPresentation().setVisible(enabled); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java new file mode 100644 index 00000000000..ae1131ed2ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java @@ -0,0 +1,76 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +public class AdjustArrayRangeAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + if(debuggerContext == null) return; + + DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if(debugProcess == null) return; + + Project project = debuggerContext.getProject(); + + final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if (selectedNode == null) { + return; + } + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if(!(descriptor instanceof ValueDescriptorImpl && ((ValueDescriptorImpl)descriptor).isArray())) return; + + ArrayRenderer renderer = (ArrayRenderer)((ValueDescriptorImpl)selectedNode.getDescriptor()).getLastRenderer(); + + String title = createNodeTitle("", selectedNode); + String label = selectedNode.toString(); + int index = label.indexOf('='); + if (index > 0) { + title = title + " " + label.substring(index); + } + final ArrayRenderer cloneRenderer = renderer.clone(); + AdjustRangeDialog dialog = new AdjustRangeDialog(project, title, cloneRenderer); + dialog.show(); + + if(dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { + public void contextAction() throws Exception { + selectedNode.setRenderer(cloneRenderer); + } + }); + } + } + + public void update(AnActionEvent e) { + boolean enable = false; + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode != null) { + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + enable = descriptor instanceof ValueDescriptorImpl && ((ValueDescriptorImpl)descriptor).isArray() && ((ValueDescriptorImpl) descriptor).getLastRenderer() instanceof ArrayRenderer; + } + e.getPresentation().setVisible(enable); + } + + private static String createNodeTitle(String prefix, DebuggerTreeNodeImpl node) { + if (node != null) { + DebuggerTreeNodeImpl parent = (DebuggerTreeNodeImpl)node.getParent(); + NodeDescriptorImpl descriptor = parent.getDescriptor(); + if (descriptor instanceof ValueDescriptorImpl && ((ValueDescriptorImpl)descriptor).isArray()) { + int index = parent.getIndex(node); + return createNodeTitle(prefix, parent) + "[" + index + "]"; + } + String name = (node.getDescriptor() != null)? node.getDescriptor().getName() : null; + return (name != null)? prefix + " " + name : prefix; + } + return prefix; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AutoRendererAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AutoRendererAction.java new file mode 100644 index 00000000000..e6386bf4b33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/AutoRendererAction.java @@ -0,0 +1,36 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class AutoRendererAction extends AnAction{ + public void actionPerformed(AnActionEvent e) { + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + final DebuggerTreeNodeImpl[] selectedNodes = DebuggerAction.getSelectedNodes(e.getDataContext()); + + if(debuggerContext != null && debuggerContext.getDebugProcess() != null) { + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + for (int i = 0; i < selectedNodes.length; i++) { + DebuggerTreeNodeImpl selectedNode = selectedNodes[i]; + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if (descriptor instanceof ValueDescriptorImpl) { + ((ValueDescriptorImpl) descriptor).setRenderer(null); + selectedNode.calcRepresentation(); + } + } + } + }); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CopyValueAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CopyValueAction.java new file mode 100644 index 00000000000..ba68525883a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CopyValueAction.java @@ -0,0 +1,87 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.progress.util.ProgressWindowWithNotification; +import com.intellij.openapi.project.Project; +import com.sun.jdi.Value; + +import java.awt.datatransfer.StringSelection; + +/* + * Class SetValueAction + * @author Jeka + */ +public class CopyValueAction extends DebuggerAction { + + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final Value value = getValue(e); + if (value == null) { + return; + } + + DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); + if(debuggerManager != null) { + final DebuggerContextImpl context = debuggerManager.getContext(); + + if(context != null && context.getDebuggerSession() != null) { + final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, project); + SuspendContextCommandImpl copyValueAction = new SuspendContextCommandImpl(context.getSuspendContext()) { + public void contextAction() throws Exception { + progressWindow.setText("Evaluating toString() for the expression"); + + final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(context.createEvaluationContext(), value); + + if (progressWindow.isCanceled()) return; + + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + String text = valueAsString; + + if (text == null) text = ""; + + CopyPasteManager.getInstance().setContents(new StringSelection(text)); + } + }); + } + }; + progressWindow.setTitle("Evaluating..."); + context.getDebugProcess().getManagerThread().startProgress(copyValueAction, progressWindow); + } + } + + } + + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + Value value = getValue(e); + presentation.setEnabled(value != null); + presentation.setVisible(value != null); + } + + private Value getValue(AnActionEvent e) { + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if (selectedNode == null) { + return null; + } + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if (!(descriptor instanceof ValueDescriptorImpl)) { + return null; + } + return ((ValueDescriptorImpl)descriptor).getValue(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeContextViewAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeContextViewAction.java new file mode 100644 index 00000000000..f8f973445f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeContextViewAction.java @@ -0,0 +1,55 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.settings.*; +import com.intellij.debugger.ui.PropertiesDialog; +import com.intellij.debugger.ui.impl.FrameDebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.options.Configurable; + +import javax.swing.*; +import java.util.List; +import java.util.ArrayList; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 4:39:53 PM + */ +public class CustomizeContextViewAction extends DebuggerAction{ + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + CompositeConfigurable configurable = new CompositeConfigurable() { + protected List createConfigurables() { + ArrayList array = new ArrayList(); + array.add(new ViewsGeneralConfigurable()); + array.add(new NodeRendererConfigurable(project)); + return array; + } + + public String getDisplayName() { + return "Customize view"; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + }; + + PropertiesDialog dialog = new PropertiesDialog(configurable, project); + dialog.show(); + } + + public void update(AnActionEvent e) { + DebuggerTree tree = getTree(e.getDataContext()); + e.getPresentation().setVisible(tree instanceof FrameDebuggerTree); + e.getPresentation().setText("Customize View..."); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeThreadsViewAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeThreadsViewAction.java new file mode 100644 index 00000000000..57001fc1995 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/CustomizeThreadsViewAction.java @@ -0,0 +1,26 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.settings.ThreadsViewSettings; +import com.intellij.debugger.ui.PropertiesDialog; +import com.intellij.debugger.ui.impl.ThreadsDebuggerTree; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 4:40:12 PM + */ +public class CustomizeThreadsViewAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + PropertiesDialog dialog = new PropertiesDialog(ThreadsViewSettings.getInstance().getConfigurable(), project); + dialog.show(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setVisible(getTree(e.getDataContext()) instanceof ThreadsDebuggerTree); + e.getPresentation().setText("Customize View..."); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerAction.java new file mode 100644 index 00000000000..2742727424a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerAction.java @@ -0,0 +1,122 @@ +/* + * Class DebuggerAction + * @author Jeka + */ +package com.intellij.debugger.actions; + + +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.impl.DebuggerPanel; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +public abstract class DebuggerAction extends AnAction { + private static DebuggerTreeNodeImpl[] EMPTY_TREE_NODE_ARRAY = new DebuggerTreeNodeImpl[0]; + + public static DebuggerTree getTree(DataContext dataContext){ + return (DebuggerTree)dataContext.getData(DebuggerActions.DEBUGGER_TREE); + } + + public static DebuggerPanel getPanel(DataContext dataContext){ + return (DebuggerPanel)dataContext.getData(DebuggerActions.DEBUGGER_PANEL); + } + + public static DebuggerTreeNodeImpl getSelectedNode(DataContext dataContext) { + DebuggerTree tree = getTree(dataContext); + if(tree == null) return null; + + if (tree.getSelectionCount() != 1) { + return null; + } + TreePath path = tree.getSelectionPath(); + if (path == null) { + return null; + } + Object component = path.getLastPathComponent(); + if (!(component instanceof DebuggerTreeNodeImpl)) { + return null; + } + return (DebuggerTreeNodeImpl)component; + } + + public static DebuggerTreeNodeImpl[] getSelectedNodes(DataContext dataContext) { + DebuggerTree tree = getTree(dataContext); + if(tree == null) return null; + TreePath[] paths = tree.getSelectionPaths(); + if (paths == null || paths.length == 0) { + return EMPTY_TREE_NODE_ARRAY; + } + List nodes = new ArrayList(paths.length); + for (int idx = 0; idx < paths.length; idx++) { + Object component = paths[idx].getLastPathComponent(); + if (component instanceof DebuggerTreeNodeImpl) { + nodes.add(component); + } + } + return ((DebuggerTreeNodeImpl[])nodes.toArray(new DebuggerTreeNodeImpl[nodes.size()])); + } + + public static DebuggerContextImpl getDebuggerContext(DataContext dataContext) { + DebuggerPanel panel = getPanel(dataContext); + if(panel != null) { + return panel.getContext(); + } else { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + return project != null ? (DebuggerManagerEx.getInstanceEx(project)).getContext() : DebuggerContextImpl.EMPTY_CONTEXT; + } + } + + public static DebuggerStateManager getContextManager(DataContext dataContext) { + DebuggerPanel panel = getPanel(dataContext); + return panel == null ? null : panel.getContextManager(); + } + + public static boolean isContextView(AnActionEvent e) { + return DebuggerActions.EVALUATION_DIALOG_POPUP.equals(e.getPlace()) || + DebuggerActions.FRAME_PANEL_POPUP.equals(e.getPlace()) || + DebuggerActions.WATCH_PANEL_POPUP.equals(e.getPlace()) || + DebuggerActions.INSPECT_PANEL_POPUP.equals(e.getPlace()); + } + + public static void installEditAction(final JTree tree, String actionName) { + tree.addMouseListener(new MouseAdapter(){ + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() != 2) return; + if (tree.getPathForLocation(e.getX(), e.getY()) == null) return; + DataContext dataContext = DataManager.getInstance().getDataContext(tree); + GotoFrameSourceAction.doAction(dataContext); + } + }); + ActionManager.getInstance().getAction(actionName).registerCustomShortcutSet(CommonShortcuts.getEditSource(), tree); + } + + public static boolean isFirstStart(final AnActionEvent event) { + String key = "initalized"; + if(event.getPresentation().getClientProperty(key) != null) return false; + + event.getPresentation().putClientProperty(key, key); + return true; + } + + public static void enableAction(final AnActionEvent event, final boolean enable) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + event.getPresentation().setEnabled(enable); + event.getPresentation().setVisible(true); + } + }); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerActions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerActions.java new file mode 100644 index 00000000000..2d1daeccfea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/DebuggerActions.java @@ -0,0 +1,33 @@ +/* + * Interface DebuggerActions + * @author Jeka + */ +package com.intellij.debugger.actions; + +public interface DebuggerActions { + String RESUME = "Resume"; + String PAUSE = "Pause"; + String SHOW_EXECUTION_POINT = "ShowExecutionPoint"; + String STEP_OVER = "StepOver"; + String STEP_INTO = "StepInto"; + String FORCE_STEP_INTO = "ForceStepInto"; + String STEP_OUT = "StepOut"; + String POP_FRAME = "Debugger.PopFrame"; + String RUN_TO_CURSOR = "RunToCursor"; + String VIEW_BREAKPOINTS = "ViewBreakpoints"; + String EVALUATE_EXPRESSION = "EvaluateExpression"; + String EVALUATION_DIALOG_POPUP = "Debugger.EvaluationDialogPopup"; + String FRAME_PANEL_POPUP = "Debugger.FramePanelPopup"; + String INSPECT_PANEL_POPUP = "Debugger.InspectPanelPopup"; + String THREADS_PANEL_POPUP = "Debugger.ThreadsPanelPopup"; + String WATCH_PANEL_POPUP = "Debugger.WatchesPanelPopup"; + String DEBUGGER_TREE = "DebuggerTree"; + String DEBUGGER_PANEL = "DebuggerPanel"; + String REMOVE_WATCH = "Debugger.RemoveWatch"; + String NEW_WATCH = "Debugger.NewWatch"; + String EDIT_WATCH = "Debugger.EditWatch"; + String EDIT_FRAME_SOURCE = "Debugger.EditFrameSource"; + String EDIT_NODE_SOURCE = "Debugger.EditNodeSource"; + String TOGGLE_STEP_SUSPEND_POLICY = "Debugger.ToggleStepThreadSuspendPolicy"; + String REPRESENTATION_LIST = "Debugger.Representation"; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditFrameSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditFrameSourceAction.java new file mode 100644 index 00000000000..137cdb98085 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditFrameSourceAction.java @@ -0,0 +1,19 @@ +package com.intellij.debugger.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.IdeActions; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 14, 2004 + * Time: 11:15:59 AM + * To change this template use File | Settings | File Templates. + */ +public class EditFrameSourceAction extends GotoFrameSourceAction{ + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setText(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getTemplatePresentation().getText()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditSourceAction.java new file mode 100644 index 00000000000..3bff0d69956 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditSourceAction.java @@ -0,0 +1,118 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.expression.Modifier; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class EditSourceAction extends DebuggerAction{ + public void actionPerformed(AnActionEvent e) { + final Project project = (Project) e.getDataContext().getData(DataConstants.PROJECT); + + if(project == null) return; + + final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(debuggerContext != null && selectedNode != null) { + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + final SourcePosition sourcePosition = getSourcePosition(selectedNode, debuggerContext); + if (sourcePosition != null) { + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, sourcePosition.getFile().getVirtualFile(), sourcePosition.getOffset()), true); + } + }); + } + } + }); + } + } + + private SourcePosition getSourcePosition(DebuggerTreeNodeImpl selectedNode, DebuggerContextImpl debuggerContext) { + DebuggerTreeNodeImpl node = selectedNode; + final DebuggerContextImpl context = debuggerContext; + + if(node == null) return null; + if(context == null) return null; + + final Project project = context.getProject(); + + final DebuggerSession debuggerSession = context.getDebuggerSession(); + + if(debuggerSession == null) return null; + + NodeDescriptorImpl nodeDescriptor = node.getDescriptor(); + if(nodeDescriptor instanceof WatchItemDescriptor) { + Modifier modifier = ((WatchItemDescriptor)nodeDescriptor).getModifier(); + + if(modifier == null) return null; + + nodeDescriptor = (NodeDescriptorImpl)modifier.getInspectItem(project); + } + + final NodeDescriptorImpl nodeDescriptor1 = nodeDescriptor; + return ApplicationManager.getApplication().runReadAction(new Computable() { + public SourcePosition compute() { + if (nodeDescriptor1 instanceof FieldDescriptorImpl && debuggerSession != null) { + return ((FieldDescriptorImpl)nodeDescriptor1).getSourcePosition(project, context); + } + if (nodeDescriptor1 instanceof LocalVariableDescriptorImpl && debuggerSession != null) { + return ((LocalVariableDescriptorImpl)nodeDescriptor1).getSourcePosition(project, context); + } + return null; + } + }); + } + + public void update(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); + + final Presentation presentation = e.getPresentation(); + + presentation.setEnabled(true); + + //if user used shortcut actionPerformed is called immediately after update + //we not disable presentation here to allow actionPerform work + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + presentation.setEnabled(false); + } + }); + + if(debuggerContext != null) { + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + final SourcePosition position = getSourcePosition(node, debuggerContext); + if (position != null) { + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + presentation.setEnabled(true); + } + }); + } + } + }); + } + + e.getPresentation().setText(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getTemplatePresentation().getText()); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditWatchAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditWatchAction.java new file mode 100644 index 00000000000..085de3f2c73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EditWatchAction.java @@ -0,0 +1,37 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 8:34:01 PM + */ +public class EditWatchAction extends DebuggerAction { + public void actionPerformed(final AnActionEvent e) { + final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode == null || !(selectedNode.getDescriptor() instanceof WatchItemDescriptor)) return; + + Project project = (Project) e.getDataContext().getData(DataConstants.PROJECT); + + MainWatchPanel watchPanel = DebuggerPanelsManager.getInstance(project).getWatchPanel(); + if(watchPanel != null) { + watchPanel.editNode(selectedNode); + } + } + + public void update(AnActionEvent e) { + final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + + e.getPresentation().setVisible(selectedNode != null && selectedNode.getDescriptor() instanceof WatchItemDescriptor); + } + +}; diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EvaluateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EvaluateAction.java new file mode 100644 index 00000000000..a4211dd398b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/EvaluateAction.java @@ -0,0 +1,127 @@ +/* + * Class EvaluateAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.*; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.intellij.debugger.DebuggerInvocationUtil; + +public class EvaluateAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + final DebuggerContextImpl context = DebuggerAction.getDebuggerContext(dataContext); + + if(project == null || context == null) { + return; + } + + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + + TextWithImportsImpl editorText = DebuggerUtilsEx.getEditorText(editor); + if (editorText == null) { + final DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(dataContext); + + if (selectedNode != null && selectedNode.getDescriptor() instanceof ValueDescriptorImpl) { + context.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(context) { + public void threadAction() { + final TextWithImportsImpl evaluationText = DebuggerTreeNodeExpression.createEvaluationText(selectedNode, context); + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + showEvaluationDialog(project, evaluationText); + } + }); + } + + protected void commandCancelled() { + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + if(selectedNode.getDescriptor() instanceof WatchItemDescriptor) { + TextWithImportsImpl editorText = DebuggerTreeNodeExpression.createEvaluationText(selectedNode, context); + showEvaluationDialog(project, editorText); + } + } + }); + } + }); + return; + } + } + + showEvaluationDialog(project, editorText); + } + + public static void showEvaluationDialog(Project project, TextWithImportsImpl defaultExpression, String dialogType) { + if(defaultExpression == null) { + defaultExpression = TextWithImportsImpl.EMPTY; + } + + final DialogWrapper dialog; + DebuggerSettings.getInstance().EVALUATION_DIALOG_TYPE = dialogType; + if(DebuggerSettings.EVALUATE_FRAGMENT.equals(dialogType)) { + dialog = new StatementEvaluationDialog(project, defaultExpression); + } + else { + dialog = new ExpressionEvaluationDialog(project, defaultExpression); + } + + dialog.show(); + } + + public static void showEvaluationDialog(Project project, TextWithImportsImpl text) { + showEvaluationDialog(project, text, DebuggerSettings.getInstance().EVALUATION_DIALOG_TYPE); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + DebuggerContextImpl context = getDebuggerContext(event.getDataContext()); + + boolean toEnable = false; + + if(context != null) { + DebuggerSession debuggerSession = context.getDebuggerSession(); + + toEnable = debuggerSession != null && debuggerSession.isPaused(); + } + + presentation.setEnabled(toEnable); + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace())) { + presentation.setVisible(toEnable); + } + else { + presentation.setVisible(true); + } + } + + protected interface TextAcceptor { + void accept(TextWithImportsImpl text); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ExportThreadsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ExportThreadsAction.java new file mode 100644 index 00000000000..c8b599f90ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ExportThreadsAction.java @@ -0,0 +1,71 @@ +/** + * class ExportThreadsAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.ExportDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class ExportThreadsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + + if(context.getDebuggerSession() != null) { + final String destinationDirectory; + final VirtualFile projectFile = project.getProjectFile(); + if (projectFile != null) { + destinationDirectory = projectFile.getParent().getPresentableUrl(); + } + else { + destinationDirectory = ""; + } + ExportDialog dialog = new ExportDialog(context.getDebugProcess(), destinationDirectory); + dialog.show(); + if (dialog.isOK()) { + try { + File file = new File(dialog.getFilePath()); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + String text = StringUtil.convertLineSeparators(dialog.getTextToSave(), System.getProperty("line.separator")); + writer.write(text); + writer.close(); + } + catch (IOException ex) { + Messages.showMessageDialog(project, ex.getMessage(), "Error Saving to File", Messages.getErrorIcon()); + } + } + } + } + + + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepIntoAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepIntoAction.java new file mode 100644 index 00000000000..c539d292bb7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepIntoAction.java @@ -0,0 +1,33 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class ForceStepIntoAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().stepInto(true); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepOverAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepOverAction.java new file mode 100644 index 00000000000..9196dc25190 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ForceStepOverAction.java @@ -0,0 +1,37 @@ +package com.intellij.debugger.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.DebuggerManagerEx; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class ForceStepOverAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().stepOver(true); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/FreezeThreadAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/FreezeThreadAction.java new file mode 100644 index 00000000000..74c9801b1da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/FreezeThreadAction.java @@ -0,0 +1,62 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 14, 2004 + * Time: 3:35:58 PM + * To change this template use File | Settings | File Templates. + */ +public class FreezeThreadAction extends DebuggerAction{ + public void actionPerformed(final AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNode = getSelectedNodes(e.getDataContext()); + final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + + for (int i = 0; i < selectedNode.length; i++) { + final DebuggerTreeNodeImpl debuggerTreeNode = selectedNode[i]; + ThreadDescriptorImpl threadDescriptor = ((ThreadDescriptorImpl)debuggerTreeNode.getDescriptor()); + final ThreadReferenceProxyImpl thread = threadDescriptor.getThreadReference(); + + if(!threadDescriptor.isFrozen()) { + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { + public void contextAction() throws Exception { + debugProcess.createFreezeThreadCommand(thread).run(); + debuggerTreeNode.calcValue(); + } + }); + } + } + } + + public void update(AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNode = getSelectedNodes(e.getDataContext()); + DebugProcessImpl debugProcess = getDebuggerContext(e.getDataContext()).getDebugProcess(); + + boolean visible = false; + if(debugProcess != null) { + visible = true; + for (int i = 0; i < selectedNode.length; i++) { + NodeDescriptorImpl threadDescriptor = selectedNode[i].getDescriptor(); + if(!(threadDescriptor instanceof ThreadDescriptorImpl) || ((ThreadDescriptorImpl)threadDescriptor).isFrozen()) { + visible = false; + break; + } + } + + } + + e.getPresentation().setVisible(visible); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/GotoFrameSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/GotoFrameSourceAction.java new file mode 100644 index 00000000000..d5ea24c602e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/GotoFrameSourceAction.java @@ -0,0 +1,44 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.impl.DebuggerContextUtil; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 14, 2004 + * Time: 10:36:59 AM + * To change this template use File | Settings | File Templates. + */ +public abstract class GotoFrameSourceAction extends DebuggerAction{ + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + doAction(dataContext); + } + + protected static void doAction(DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if(project == null) return; + StackFrameDescriptorImpl stackFrameDescriptor = getStackFrameDescriptor(dataContext); + if(stackFrameDescriptor != null) { + DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getStackFrame()); + } + } + + public void update(AnActionEvent e) { + e.getPresentation().setVisible(getStackFrameDescriptor(e.getDataContext()) != null); + } + + private static StackFrameDescriptorImpl getStackFrameDescriptor(DataContext dataContext) { + DebuggerTreeNodeImpl selectedNode = getSelectedNode(dataContext); + if(selectedNode == null) return null; + if(selectedNode.getDescriptor() == null || !(selectedNode.getDescriptor() instanceof StackFrameDescriptorImpl)) return null; + return (StackFrameDescriptorImpl)selectedNode.getDescriptor(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/HotSwapAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/HotSwapAction.java new file mode 100644 index 00000000000..3c4b6b7a5a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/HotSwapAction.java @@ -0,0 +1,52 @@ +package com.intellij.debugger.actions; + +import com.intellij.execution.RunManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.HotSwapUI; +import com.intellij.debugger.impl.DebuggerSession; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jun 26, 2003 + * Time: 12:52:01 PM + * To change this template use Options | File Templates. + */ +public class HotSwapAction extends AnAction{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.HotSwapAction"); + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if(project == null) { + return; + } + + DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); + DebuggerSession session = debuggerManager.getContext().getDebuggerSession(); + + if(session != null && session.isAttached()) { + HotSwapUI.getInstance(project).reloadChangedClasses(session, RunManager.getInstance(project).getConfig().isCompileBeforeRunning()); + } + } + + public void update(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if(project == null) { + e.getPresentation().setEnabled(false); + return; + } + + DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); + DebuggerSession session = debuggerManager.getContext().getDebuggerSession(); + + e.getPresentation().setEnabled(session != null && session.isAttached() && session.getProcess().canRedefineClasses()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/InspectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/InspectAction.java new file mode 100644 index 00000000000..1306f2858f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/InspectAction.java @@ -0,0 +1,105 @@ +/* + * Class InspectAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.expression.Modifier; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.ui.impl.InspectDialog; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.sun.jdi.Field; + +public class InspectAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); + if(node == null) return; + final NodeDescriptorImpl descriptor = node.getDescriptor(); + final DebuggerStateManager stateManager = getContextManager(e.getDataContext()); + if(!(descriptor instanceof ValueDescriptorImpl) || stateManager == null) return; + final DebuggerContextImpl context = stateManager.getContext(); + + if (!canInspect((ValueDescriptorImpl)descriptor, context)) { + return; + } + + context.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(context) { + public void threadAction() { + final TextWithImportsImpl evaluationText = DebuggerTreeNodeExpression.createEvaluationText(node, context); + + final NodeDescriptorImpl inspectDescriptor; + + if (descriptor instanceof WatchItemDescriptor) { + inspectDescriptor = (NodeDescriptorImpl) ((WatchItemDescriptor) descriptor).getModifier().getInspectItem(project); + } else { + inspectDescriptor = descriptor; + } + + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + InspectDialog dialog = new InspectDialog(project, + stateManager, + "Inspect '" + evaluationText + "'", + inspectDescriptor); + dialog.show(); + } + }); + } + }); + } + + private boolean canInspect(ValueDescriptorImpl descriptor, DebuggerContextImpl context) { + DebuggerSession session = context.getDebuggerSession(); + if (session == null || !session.isPaused()) return false; + + boolean isField = descriptor instanceof FieldDescriptorImpl; + + if(descriptor instanceof WatchItemDescriptor) { + Modifier modifier = ((WatchItemDescriptor)descriptor).getModifier(); + if(modifier == null || !modifier.canInspect()) return false; + isField = modifier instanceof Field; + } + + if (isField) { // check if possible + if (!context.getDebugProcess().canWatchFieldModification()) { + Messages.showMessageDialog( + context.getProject(), + "Cannot inspect: Target VM does not support modification watchpoints", + "Inspect", + Messages.getInformationIcon() + ); + return false; + } + } + return true; + } + + public void update(AnActionEvent e) { + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + boolean enabled = false; + if(selectedNode != null) { + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if(descriptor != null) { + if(descriptor instanceof LocalVariableDescriptorImpl || descriptor instanceof FieldDescriptorImpl || descriptor instanceof ArrayElementDescriptorImpl) { + enabled = true; + } + else if(descriptor instanceof WatchItemDescriptor){ + Modifier modifier = ((WatchItemDescriptor)descriptor).getModifier(); + enabled = modifier != null && modifier.canInspect(); + } + } + } + e.getPresentation().setVisible(enabled); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/JumpToObjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/JumpToObjectAction.java new file mode 100644 index 00000000000..6d37743b088 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/JumpToObjectAction.java @@ -0,0 +1,116 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.sun.jdi.*; + +import java.util.List; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class JumpToObjectAction extends DebuggerAction{ + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode == null) return; + + final NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if(!(descriptor instanceof ValueDescriptor)) return; + + DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if(debugProcess == null) return; + + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { + public void contextAction() throws Exception { + final SourcePosition sourcePosition = calcPosition((ValueDescriptor)descriptor, debugProcess); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, sourcePosition.getFile().getVirtualFile(), sourcePosition.getOffset()), true); + } + }); + } + }); + + + } + + public void update(final AnActionEvent e) { + if(!isFirstStart(e)) return; + + DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if(debugProcess == null) { + e.getPresentation().setVisible(false); + return; + } + + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode == null) { + e.getPresentation().setVisible(false); + return; + } + + final NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + + if(!(descriptor instanceof ValueDescriptor)) { + e.getPresentation().setVisible(false); + return; + } + + e.getPresentation().setVisible(true); + e.getPresentation().setEnabled(true); + + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { + public void contextAction() throws Exception { + SourcePosition sourcePosition = calcPosition((ValueDescriptor)descriptor, debugProcess); + if(sourcePosition != null) { + enableAction(e, true); + } + } + }); + } + + private SourcePosition calcPosition(final ValueDescriptor descriptor, final DebugProcessImpl debugProcess) + throws ClassNotLoadedException, AbsentInformationException { + Value value = descriptor.getValue(); + if(value != null) { + Type type = value.type(); + if(type != null) { + if(type instanceof ArrayType) { + type = ((ArrayType)type).componentType(); + } + + if(type instanceof ClassType) { + List locations = ((ClassType)type).allLineLocations(); + if(locations.size() > 0) { + final Location location = locations.get(0); + return ApplicationManager.getApplication().runReadAction(new Computable() { + public SourcePosition compute() { + return debugProcess.getPositionManager().getSourcePosition(location); + } + }); + } + } + } + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/NewWatchAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/NewWatchAction.java new file mode 100644 index 00000000000..86bdb2f99fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/NewWatchAction.java @@ -0,0 +1,28 @@ +/* + * Class NewWatchAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.ui.CompletedInputDialog; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.WatchPanel; +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +public class NewWatchAction extends DebuggerAction { + public void actionPerformed(final AnActionEvent e) { + Project project = (Project) e.getDataContext().getData(DataConstants.PROJECT); + if(project == null) return; + + final MainWatchPanel watchPanel = DebuggerPanelsManager.getInstance(project).getWatchPanel(); + if (watchPanel != null) { + watchPanel.newWatch(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PauseAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PauseAction.java new file mode 100644 index 00000000000..90fd781fdd7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PauseAction.java @@ -0,0 +1,32 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class PauseAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().pause(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && (debuggerSession.isEvaluating() || debuggerSession.isRunning())); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PlaceInDocument.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PlaceInDocument.java new file mode 100644 index 00000000000..cb22cb06ed8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PlaceInDocument.java @@ -0,0 +1,13 @@ +package com.intellij.debugger.actions; + +import com.intellij.openapi.editor.Document; + +/** + * User: lex + * Date: Oct 7, 2003 + * Time: 3:12:54 PM + */ +interface PlaceInDocument { + public Document getDocument(); + public int getOffset(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PopFrameAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PopFrameAction.java new file mode 100644 index 00000000000..7bc1a8c8b68 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/PopFrameAction.java @@ -0,0 +1,105 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.sun.jdi.InvalidStackFrameException; +import com.sun.jdi.NativeMethodException; +import com.sun.jdi.VMDisconnectedException; + +public class PopFrameAction extends DebuggerAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + StackFrameProxyImpl stackFrame = getStackFrameProxy(e); + if(stackFrame == null) return; + + try { + DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + + DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + + if(debugProcess == null) return; + + debugProcess.getManagerThread().invokeLater( + debugProcess.createPopFrameCommand( + debuggerContext, + stackFrame)); + } + catch (NativeMethodException e2){ + Messages.showMessageDialog(project, "None of the frames through and including frame may be native", "Drop to Frame", Messages.getErrorIcon()); + } + catch (InvalidStackFrameException ignored) { + } + catch(VMDisconnectedException vde) { + } + } + + private StackFrameProxyImpl getStackFrameProxy(AnActionEvent e) { + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode != null) { + NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + if(descriptor instanceof StackFrameDescriptorImpl) { + if(selectedNode.getNextSibling() != null) { + StackFrameDescriptorImpl frameDescriptor = ((StackFrameDescriptorImpl)descriptor); + return frameDescriptor.getStackFrame(); + } + else { + return null; + } + } + else if(descriptor instanceof ThreadDescriptorImpl || descriptor instanceof ThreadGroupDescriptorImpl) { + return null; + } + } + DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + StackFrameProxyImpl frameProxy = debuggerContext.getFrameProxy(); + + if(frameProxy == null) return null; + + if(frameProxy.isBottom()) return null; + + return frameProxy; + } + + private boolean isAtBreakpoint(AnActionEvent e) { + DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + if(selectedNode != null && selectedNode.getDescriptor() instanceof StackFrameDescriptorImpl) { + DebuggerTreeNodeImpl parent = (DebuggerTreeNodeImpl)selectedNode.getParent(); + if(parent != null) { + return ((ThreadDescriptorImpl)parent.getDescriptor()).isAtBreakpoint(); + } + } + DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + SuspendContextImpl suspendContext = debuggerContext.getSuspendContext(); + return suspendContext != null && debuggerContext.getThreadProxy() == suspendContext.getThread(); + } + + public void update(AnActionEvent e) { + boolean enable = false; + StackFrameProxyImpl stackFrameProxy = getStackFrameProxy(e); + + if(stackFrameProxy != null && isAtBreakpoint(e)) { + VirtualMachineProxyImpl virtualMachineProxy = stackFrameProxy.getVirtualMachine(); + enable = virtualMachineProxy.versionHigher("1.4") && virtualMachineProxy.canPopFrames(); + } + + if(ActionPlaces.MAIN_MENU.equals(e.getPlace()) || ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) { + e.getPresentation().setEnabled(enable); + } else { + e.getPresentation().setVisible(enable); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/QuickEvaluateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/QuickEvaluateAction.java new file mode 100644 index 00000000000..edf77a82c8a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/QuickEvaluateAction.java @@ -0,0 +1,56 @@ +/* + * Class EvaluateAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.ValueHint; +import com.intellij.debugger.ui.ValueLookupManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.project.Project; + +public class QuickEvaluateAction extends AnAction { + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { return; } + + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + if (debuggerSession == null || !debuggerSession.isPaused()) return; + + Editor editor = (Editor)e.getDataContext().getData(DataConstants.EDITOR); + + if(editor != null) { + LogicalPosition logicalPosition = editor.getCaretModel().getLogicalPosition(); + ValueLookupManager.getInstance(project).showHint(editor, editor.logicalPositionToXY(logicalPosition), ValueHint.MOUSE_CLICK_HINT); + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + + boolean toEnable = debuggerSession != null && debuggerSession.isPaused(); + presentation.setEnabled(toEnable); + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace())) { + presentation.setVisible(toEnable); + } + else { + presentation.setVisible(true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveAllWatchesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveAllWatchesAction.java new file mode 100644 index 00000000000..1d04cb04eec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveAllWatchesAction.java @@ -0,0 +1,31 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; + +import java.util.Enumeration; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 6:24:44 PM + */ +public class RemoveAllWatchesAction extends RemoveWatchAction { + protected DebuggerTreeNodeImpl[] getNodesToDelete(AnActionEvent e) { + DebuggerTree tree = getTree(e.getDataContext()); + if(tree == null) return null; + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)tree.getModel().getRoot(); + DebuggerTreeNodeImpl [] result = new DebuggerTreeNodeImpl[root.getChildCount()]; + int i = 0; + for(Enumeration enumeration = root.children(); enumeration.hasMoreElements(); i++) { + DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)enumeration.nextElement(); + result[i] = node; + } + return result; + } + + protected void updatePresentation(Presentation presentation, int[] idxs) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveWatchAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveWatchAction.java new file mode 100644 index 00000000000..fe5827db3b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RemoveWatchAction.java @@ -0,0 +1,53 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; + +import java.util.ArrayList; + +public class RemoveWatchAction extends DebuggerAction { + protected DebuggerTreeNodeImpl[] getNodesToDelete(AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNodes = getSelectedNodes(e.getDataContext()); + if(selectedNodes == null) return null; + ArrayList selectedWatches = new ArrayList(); + for (int i = 0; i < selectedNodes.length; i++) { + if(selectedNodes[i].getDescriptor() instanceof WatchItemDescriptor) { + selectedWatches.add(selectedNodes[i]); + } + } + + return (DebuggerTreeNodeImpl[])selectedWatches.toArray(new DebuggerTreeNodeImpl[selectedWatches.size()]); + } + + public void actionPerformed(AnActionEvent e) { + DebuggerTreeNodeImpl [] nodes = getNodesToDelete(e); + if (nodes == null || nodes.length == 0) return; + + MainWatchPanel watchPanel = (MainWatchPanel)getPanel(e.getDataContext()); + + for (int i = 0; i < nodes.length; i++) { + DebuggerTreeNodeImpl node = nodes[i]; + watchPanel.getWatchTree().removeWatch(node); + } + } + + protected void updatePresentation(Presentation presentation, int [] idxs) { + presentation.setText((idxs.length <= 1)? "Remove Watch" : "Remove Watches"); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + DebuggerTreeNodeImpl[] nodes = getNodesToDelete(event); + if (nodes != null && nodes.length > 0) { + presentation.setEnabled(true); + presentation.setVisible(true); + } + else { + presentation.setEnabled(false); + presentation.setVisible(false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeAction.java new file mode 100644 index 00000000000..bd3c9e68ed4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeAction.java @@ -0,0 +1,34 @@ + +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class ResumeAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().resume(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeThreadAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeThreadAction.java new file mode 100644 index 00000000000..facccfaab45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ResumeThreadAction.java @@ -0,0 +1,59 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 7:35:09 PM + */ +public class ResumeThreadAction extends DebuggerAction{ + public void actionPerformed(final AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNode = getSelectedNodes(e.getDataContext()); + final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + + + for (int i = 0; i < selectedNode.length; i++) { + final DebuggerTreeNodeImpl debuggerTreeNode = selectedNode[i]; + ThreadDescriptorImpl threadDescriptor = ((ThreadDescriptorImpl)debuggerTreeNode.getDescriptor()); + final ThreadReferenceProxyImpl thread = threadDescriptor.getThreadReference(); + + if(threadDescriptor.isSuspended()) { + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { + public void contextAction() throws Exception { + debugProcess.createResumeThreadCommand(getSuspendContext(), thread).run(); + debuggerTreeNode.calcValue(); + } + }); + } + } + } + + public void update(AnActionEvent e) { + DebuggerTreeNodeImpl[] selectedNode = getSelectedNodes(e.getDataContext()); + + boolean visible = false; + + if(selectedNode.length > 0){ + visible = true; + for (int i = 0; i < selectedNode.length; i++) { + NodeDescriptorImpl threadDescriptor = selectedNode[i].getDescriptor(); + if(!(threadDescriptor instanceof ThreadDescriptorImpl) || + !((ThreadDescriptorImpl)threadDescriptor).isSuspended()) { + visible = false; + break; + } + } + } + e.getPresentation().setVisible(visible); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RunToCursorAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RunToCursorAction.java new file mode 100644 index 00000000000..ddce31bf862 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/RunToCursorAction.java @@ -0,0 +1,70 @@ +/** + * class RunToCursorAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; + +public class RunToCursorAction extends AnAction { + public RunToCursorAction() { + super("Run to Cursor"); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) return; + DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + DebugProcessImpl debugProcess = context.getDebugProcess(); + if (debugProcess == null) return; + context.getDebuggerSession().runToCursor(editor.getDocument(), editor.getCaretModel().getLogicalPosition().line); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + boolean enabled; + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + + if (project == null || editor == null) { + enabled = false; + } else { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + if (file == null) { + enabled = false; + } else { + final VirtualFile virtualFile = file.getVirtualFile(); + FileType fileType = virtualFile != null ? fileTypeManager.getFileTypeByFile(virtualFile) : null; + if (StdFileTypes.JAVA != fileType && StdFileTypes.JSP != fileType) { + enabled = false; + } else { + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + enabled = debuggerSession != null && debuggerSession.isPaused(); + } + } + } + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace())) { + presentation.setVisible(enabled); + } else { + presentation.setEnabled(enabled); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/SetValueAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/SetValueAction.java new file mode 100644 index 00000000000..aea9548b2ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/SetValueAction.java @@ -0,0 +1,469 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.engine.evaluation.expression.Modifier; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.*; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.ui.*; +import com.intellij.debugger.ui.impl.DebuggerTreeRenderer; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.render.ValueLabelRenderer; +import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.util.ProgressIndicatorListenerAdapter; +import com.intellij.openapi.progress.util.ProgressWindowWithNotification; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.util.IJSwingUtilities; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.*; + +import javax.swing.*; + +/* + * Class SetValueAction + * @author Jeka + */ +public class SetValueAction extends DebuggerAction { + public void update(AnActionEvent e) { + boolean enable = false; + DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); + if (node != null) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + if(descriptor instanceof ValueDescriptorImpl){ + ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl)descriptor); + enable = valueDescriptor.canSetValue(); + } + } + e.getPresentation().setVisible(enable); + } + + private void update(final DebuggerContextImpl context) { + DebuggerInvocationUtil.invokeLater(context.getProject(), new Runnable() { + public void run() { + context.getDebuggerSession().refresh(); + } + }); + //node.setState(context); + } + + public void actionPerformed(AnActionEvent event) { + final DebuggerTreeNodeImpl node = getSelectedNode(event.getDataContext()); + if (node == null) return; + NodeDescriptorImpl descriptor = node.getDescriptor(); + if (!(descriptor instanceof ValueDescriptorImpl)) return; + if(!((ValueDescriptorImpl)descriptor).canSetValue()) return; + + DebuggerTree tree = getTree(event.getDataContext()); + final DebuggerContextImpl debuggerContext = getDebuggerContext(event.getDataContext()); + tree.saveState(node); + + if (descriptor instanceof FieldDescriptorImpl) { + FieldDescriptorImpl fieldDescriptor = (FieldDescriptorImpl)descriptor; + final Field field = fieldDescriptor.getField(); + if (!field.isStatic()) { + final ObjectReference object = fieldDescriptor.getObject(); + if (object != null) { + askAndSet(node, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + object.setValue(field, preprocessValue(evaluationContext, newValue, field.type())); + update(debuggerContext); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, + field.declaringType().classLoader()); + } + }); + } + } + else { + // field is static + ReferenceType refType = field.declaringType(); + if (refType instanceof ClassType) { + final ClassType classType = (ClassType)refType; + askAndSet(node, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + classType.setValue(field, preprocessValue(evaluationContext, newValue, field.type())); + update(debuggerContext); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, + field.declaringType().classLoader()); + } + }); + } + } + } + else if (descriptor instanceof LocalVariableDescriptorImpl) { + LocalVariableDescriptorImpl localDescriptor = (LocalVariableDescriptorImpl)descriptor; + final LocalVariableProxyImpl local = localDescriptor.getLocalVariable(); + if (local != null) { + askAndSet(node, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, + InvalidTypeException, + EvaluateException, + IncompatibleThreadStateException { + debuggerContext.getFrameProxy().setValue(local, preprocessValue(evaluationContext, newValue, local.getVariable().type())); + update(debuggerContext); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, + evaluationContext.getClassLoader()); + } + }); + } + } + else if (descriptor instanceof ArrayElementDescriptorImpl) { + final ArrayElementDescriptorImpl elementDescriptor = (ArrayElementDescriptorImpl)descriptor; + final ArrayReference array = elementDescriptor.getArray(); + if (array != null) { + final ArrayType arrType = (ArrayType)array.referenceType(); + askAndSet(node, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + array.setValue(elementDescriptor.getIndex(), preprocessValue(evaluationContext, newValue, arrType.componentType())); + update(debuggerContext); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, arrType.classLoader()); + } + }); + } + } + else if (descriptor instanceof EvaluationDescriptor) { + final EvaluationDescriptor evaluationDescriptor = (EvaluationDescriptor)descriptor; + if (evaluationDescriptor.canSetValue()) { + askAndSet(node, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + final Modifier modifier = evaluationDescriptor.getModifier(); + modifier.setValue(preprocessValue(evaluationContext, newValue, modifier.getExpectedType())); + update(debuggerContext); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, + evaluationContext.getClassLoader()); + } + }); + } + } + } + + private Value preprocessValue(EvaluationContextImpl context, Value value, Type varType) throws EvaluateException { + if (value != null && "java.lang.String".equals(varType.name()) && !(value instanceof StringReference)) { + String v = DebuggerUtilsEx.getValueAsString(context, value); + if (v != null) { + value = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(v); + } + } + if(value instanceof DoubleValue) { + double dValue = ((DoubleValue) value).doubleValue(); + if(varType instanceof FloatType && Float.MIN_VALUE <= dValue && dValue <= Float.MAX_VALUE){ + value = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf((float)dValue); + } + } + return value; + } + + private static interface SetValueRunnable { + void setValue (EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, + InvalidTypeException, + EvaluateException, + IncompatibleThreadStateException; + ReferenceType loadClass (EvaluationContextImpl evaluationContext, String className) throws EvaluateException, + InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException; + } + + private static void setValue(String expressionToShow, ExpressionEvaluator evaluator, EvaluationContextImpl evaluationContext, SetValueRunnable setValueRunnable) throws EvaluateException { + Value value; + try { + value = evaluator.evaluate(evaluationContext); + + setValueRunnable.setValue(evaluationContext, value); + } catch (EvaluateException e1) { + throw EvaluateExceptionUtil.createEvaluateException("Failed to evaluate expression '"+ + expressionToShow + "'. \n" + e1.getMessage()); + } + catch (IllegalArgumentException ex) { + throw EvaluateExceptionUtil.createEvaluateException("Failed to evaluate expression. '" + + expressionToShow + "'. \n" + "Invalid arguments :" + ex.getMessage()); + } + catch (InvalidTypeException ex) { + throw EvaluateExceptionUtil.createEvaluateException("Failed to set value : type mismatch"); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ClassNotLoadedException ex) { + final ReferenceType refType; + try { + refType = setValueRunnable.loadClass(evaluationContext, ex.className()); + if (refType != null) { + //try again + setValue(expressionToShow, evaluator, evaluationContext, setValueRunnable); + } + } + catch (InvocationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ClassNotLoadedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (InvalidTypeException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ObjectCollectedException e) { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } + } + } + + private void askAndSet(final DebuggerTreeNodeImpl node, final DebuggerContextImpl debuggerContext, final SetValueRunnable setValueRunnable) { + ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, debuggerContext.getProject()); + + SuspendContextCommandImpl askSetAction = new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + final NodeDescriptorImpl descriptor = node.getDescriptor(); + String initialString = ""; + if (descriptor instanceof ValueDescriptorImpl) { + Value currentValue = ((ValueDescriptorImpl) descriptor).getValue(); + if (currentValue instanceof StringReference) { + initialString = DebuggerUtilsEx.getValueOrErrorAsString(debuggerContext.createEvaluationContext(), currentValue); + initialString = initialString == null ? "" : "\"" + DebuggerUtilsEx.translateStringValue(initialString) + "\""; + } + else if (currentValue instanceof PrimitiveValue) { + ValueLabelRenderer renderer = ((ValueDescriptorImpl) descriptor).getRenderer(debuggerContext.getDebugProcess()); + initialString = getDisplayableString((PrimitiveValue) currentValue, renderer instanceof NodeRenderer && "HexRenderer".equals(((NodeRenderer) renderer).getUniqueId())); + } + + final String initialString1 = initialString; + DebuggerInvocationUtil.invokeLater(debuggerContext.getProject(), new Runnable() { + public void run() { + showEditor(TextWithImportsImpl.createExpressionText(initialString1), node, debuggerContext, setValueRunnable); + } + }); + } + } + }; + + progressWindow.setTitle("Evaluating..."); + debuggerContext.getDebugProcess().getManagerThread().startProgress(askSetAction, progressWindow); + } + + private void showEditor(final TextWithImportsImpl initialString, + final DebuggerTreeNodeImpl node, + final DebuggerContextImpl debuggerContext, + final SetValueRunnable setValueRunnable) { + final JPanel editorPanel = new JPanel(); + editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.X_AXIS)); + SimpleColoredComponent label = new SimpleColoredComponent(); + label.setIcon(node.getIcon()); + DebuggerTreeRenderer.getDescriptorTitle(node.getDescriptor()).appendToComponent(label); + editorPanel.add(label); + + final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox( + debuggerContext.getProject(), + PositionUtil.getContextElement(debuggerContext), + "setValue"); + comboBox.setText(initialString); + editorPanel.add(comboBox); + + final DebuggerTree.InplaceEditor editor = new DebuggerTree.InplaceEditor(node) { + public JComponent createEditorComponent() { + return editorPanel; + } + + public JComponent getContentComponent() { + return comboBox; + } + + public Editor getEditor() { + return comboBox.getEditor(); + } + + private void setValue() { + Editor editor = comboBox.getEditor(); + if(editor == null) return; + + final TextWithImportsImpl text = comboBox.getText(); + + PsiFile psiFile = PsiDocumentManager.getInstance(debuggerContext.getProject()).getPsiFile(editor.getDocument()); + + EditorEvaluationCommand evaluationCommand = new EditorEvaluationCommand(getEditor(), psiFile, debuggerContext) { + public void threadAction() { + try { + evaluate(); + } + catch(EvaluateException e) { + getProgressWindow().cancel(); + } + catch(ProcessCanceledException e) { + getProgressWindow().cancel(); + } + finally{ + if (!getProgressWindow().isCanceled()) { + DebuggerInvocationUtil.invokeLater(debuggerContext.getProject(), new Runnable() { + public void run() { + comboBox.addRecent(text); + superDoCancelAction(); + } + }); + } + } + } + + protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException { + ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl.getInstance().build(text, ContextUtil.getContextElement(evaluationContext)); + } + }); + + SetValueAction.setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, + InvalidTypeException, + EvaluateException, + IncompatibleThreadStateException { + if(!getProgressWindow().isCanceled()) { + setValueRunnable.setValue(evaluationContext, newValue); + } + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, + ClassNotLoadedException, + EvaluateException, + IncompatibleThreadStateException, + InvalidTypeException { + return setValueRunnable.loadClass(evaluationContext, className); + } + }); + + return null; + } + }; + + final ProgressWindowWithNotification progressWindow = evaluationCommand.getProgressWindow(); + progressWindow.addListener(new ProgressIndicatorListenerAdapter() { + //should return whether to stop processing + public void stopped() { + if(!progressWindow.isCanceled()) { + IJSwingUtilities.invoke(new Runnable() { + public void run() { + superDoCancelAction(); + } + }); + } + } + + + }); + + progressWindow.setTitle("Setting value..."); + debuggerContext.getDebugProcess().getManagerThread().startProgress(evaluationCommand, progressWindow); + } + + private void superDoCancelAction() { + super.doCancelAction(); + } + + public void doOKAction() { + setValue(); + } + + public void doFocusLostAction() { + setValue(); + } + }; + + final DebuggerStateManager stateManager = DebuggerManagerEx.getInstanceEx(debuggerContext.getProject()).getContextManager(); + + DebuggerContextListener listener = new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + stateManager.removeListener(this); + editor.doFocusLostAction(); + } + }; + + stateManager.addListener(listener); + + editor.show(); + } + + private static String getDisplayableString(PrimitiveValue value, boolean showAsHex) { + if (value instanceof CharValue) { + long longValue = value.longValue(); + return showAsHex ? "0x" + Long.toHexString(longValue).toUpperCase() : Long.toString(longValue); + } + if (value instanceof ByteValue) { + byte val = value.byteValue(); + String strValue = Integer.toHexString(val).toUpperCase(); + if (strValue.length() > 2) { + strValue = strValue.substring(strValue.length() - 2); + } + return showAsHex ? "0x" + strValue : value.toString(); + } + if (value instanceof ShortValue) { + short val = value.shortValue(); + String strValue = Integer.toHexString(val).toUpperCase(); + if (strValue.length() > 4) { + strValue = strValue.substring(strValue.length() - 4); + } + return showAsHex ? "0x" + strValue : value.toString(); + } + if (value instanceof IntegerValue) { + int val = value.intValue(); + return showAsHex ? "0x" + Integer.toHexString(val).toUpperCase() : value.toString(); + } + if (value instanceof LongValue) { + long val = value.longValue(); + return showAsHex ? "0x" + Long.toHexString(val).toUpperCase() + "L" : value.toString() + "L"; + } + return DebuggerUtilsEx.translateStringValue(value.toString()); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowExecutionPointAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowExecutionPointAction.java new file mode 100644 index 00000000000..50525da8081 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowExecutionPointAction.java @@ -0,0 +1,31 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class ShowExecutionPointAction extends AnAction { + public void actionPerformed(AnActionEvent event) { + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().showExecutionPoint(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused() && debuggerSession.getContextManager().getContext().getSuspendContext().getThread() != null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowFrameAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowFrameAction.java new file mode 100644 index 00000000000..91a7bfe138e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ShowFrameAction.java @@ -0,0 +1,27 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 7:45:21 PM + */ +public class ShowFrameAction extends GotoFrameSourceAction { + public void actionPerformed(AnActionEvent e) { + super.actionPerformed(e); + DebuggerStateManager stateManager = getContextManager(e.getDataContext()); + DebuggerContextImpl context = stateManager.getContext(); + + if(context != null) { + DebuggerPanelsManager.getInstance(context.getProject()).showFramePanel(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepIntoAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepIntoAction.java new file mode 100644 index 00000000000..a904b8ae346 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepIntoAction.java @@ -0,0 +1,32 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class StepIntoAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().stepInto(false); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOutAction.java new file mode 100644 index 00000000000..d85b984b130 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOutAction.java @@ -0,0 +1,33 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class StepOutAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().stepOut(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOverAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOverAction.java new file mode 100644 index 00000000000..afb1be83ae4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/StepOverAction.java @@ -0,0 +1,33 @@ + +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public class StepOverAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession().stepOver(false); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession(); + presentation.setEnabled(debuggerSession != null && debuggerSession.isPaused()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ThrowDebugExceptionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ThrowDebugExceptionAction.java new file mode 100644 index 00000000000..2195d1381b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ThrowDebugExceptionAction.java @@ -0,0 +1,17 @@ + +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebugException; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class ThrowDebugExceptionAction extends AnAction { + + public void actionPerformed(AnActionEvent event) { + try{ + throw new DebugException(); + } + catch(DebugException e){ + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java new file mode 100644 index 00000000000..f8f456f57ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java @@ -0,0 +1,75 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; + +public class ToggleBreakpointEnabledAction extends AnAction { + + public ToggleBreakpointEnabledAction() { + super("Toggle Breakpoint Enabled"); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Breakpoint breakpoint = findBreakpoint(dataContext); + breakpoint.ENABLED = !breakpoint.ENABLED; + DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().breakpointChanged(breakpoint); + breakpoint.updateUI(); + } + + private Breakpoint findBreakpoint(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if(editor == null) return null; + BreakpointManager manager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager(); + int offset = editor.getCaretModel().getOffset(); + return manager.findBreakpoint(editor.getDocument(), offset); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) { + presentation.setEnabled(false); + return; + } + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null) { + presentation.setEnabled(false); + return; + } + + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType fileType = fileTypeManager.getFileTypeByFile(file.getVirtualFile()); + if(StdFileTypes.JAVA != fileType && StdFileTypes.JSP != fileType){ + presentation.setEnabled(false); + return; + } + + Breakpoint breakpoint = findBreakpoint(dataContext); + if (breakpoint == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java new file mode 100644 index 00000000000..2de3f7aef98 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java @@ -0,0 +1,163 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.InstanceFilter; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.ui.breakpoints.FieldBreakpoint; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.sun.jdi.Field; +import com.sun.jdi.ObjectReference; + +/** + * User: lex + * Date: Sep 4, 2003 + * Time: 8:59:30 PM + */ +public class ToggleFieldBreakpointAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.ToggleFieldBreakpointAction"); + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + SourcePosition place = getPlace(e); + + if(place != null) { + Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile()); + if (document != null) { + DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); + BreakpointManager manager = debuggerManager.getBreakpointManager(); + Breakpoint breakpoint = manager.findFieldBreakpoint(document, place.getOffset()); + + if(breakpoint == null) { + FieldBreakpoint fieldBreakpoint = manager.addFieldBreakpoint(document, place.getOffset()); + if (fieldBreakpoint != null) { + if(DebuggerAction.isContextView(e)) { + DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(e.getDataContext()); + LOG.assertTrue(selectedNode != null); + ObjectReference object = ((FieldDescriptorImpl)selectedNode.getDescriptor()).getObject(); + if(object != null) { + long id = object.uniqueID(); + InstanceFilter[] instanceFilters = new InstanceFilter[] { InstanceFilter.create(Long.toString(id))}; + fieldBreakpoint.setInstanceFilters(instanceFilters); + fieldBreakpoint.INSTANCE_FILTERS_ENABLED = true; + } + } + + RequestManagerImpl.createRequests(fieldBreakpoint); + DialogWrapper dialog = manager.createConfigurationDialog(fieldBreakpoint, null); + dialog.show(); + } + } else { + manager.removeBreakpoint(breakpoint); + } + } + } + } + + public void update(AnActionEvent event){ + SourcePosition place = getPlace(event); + boolean toEnable = place != null; + + Presentation presentation = event.getPresentation(); + if(ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) || + ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace())) { + presentation.setVisible(toEnable); + } + else if(DebuggerAction.isContextView(event)) { + presentation.setText(presentation.getText().replaceFirst("Toggle", "Add")); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if(place != null) { + Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile()); + if (document != null) { + Breakpoint fieldBreakpoint = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager().findFieldBreakpoint( + document, + place.getOffset()); + if(fieldBreakpoint != null) { + presentation.setEnabled(false); + return; + } + } + } + } + presentation.setVisible(toEnable); + } + + public static SourcePosition getPlace(AnActionEvent event) { + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if(project == null) return null; + if (ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) || + ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace())) { + final PsiElement psiElement = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if(psiElement instanceof PsiField) { + return SourcePosition.createFromElement(psiElement); + } + return null; + } + + if(DebuggerAction.isContextView(event)) { + DebuggerTree tree = (DebuggerTree)event.getDataContext().getData(DebuggerActions.DEBUGGER_TREE); + if(tree != null && tree.getSelectionPath() != null) { + DebuggerTreeNodeImpl node = ((DebuggerTreeNodeImpl)tree.getSelectionPath().getLastPathComponent()); + if(node != null && node.getDescriptor() instanceof FieldDescriptorImpl) { + Field field = ((FieldDescriptorImpl)node.getDescriptor()).getField(); + PsiClass psiClass = DebuggerUtilsEx.findClass(field.declaringType().name(), project); + if(psiClass != null) { + psiClass = (PsiClass) psiClass.getNavigationElement(); + final PsiField psiField = psiClass.findFieldByName(field.name(), true); + if (psiField != null) { + return SourcePosition.createFromElement(psiField); + } + } + } + } + } + + DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(dataContext); + + if(selectedNode != null && selectedNode.getDescriptor() instanceof FieldDescriptorImpl) { + FieldDescriptorImpl descriptor = (FieldDescriptorImpl)selectedNode.getDescriptor(); + return descriptor.getSourcePosition(project, DebuggerAction.getDebuggerContext(dataContext)); + } + + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if(editor == null) { + editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + } + if (editor != null) { + final Document document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (file != null) { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType fileType = fileTypeManager.getFileTypeByFile(file.getVirtualFile()); + if (StdFileTypes.JAVA == fileType || StdFileTypes.CLASS == fileType) { + final PsiField field = FieldBreakpoint.findField(project, document, editor.getCaretModel().getOffset()); + if(field != null){ + return SourcePosition.createFromElement(field); + } + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleLineBreakpointAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleLineBreakpointAction.java new file mode 100644 index 00000000000..df71ecba3b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleLineBreakpointAction.java @@ -0,0 +1,91 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.ui.breakpoints.LineBreakpoint; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; + +public class ToggleLineBreakpointAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + PlaceInDocument place = getPlace(e); + if(place == null) return; + DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project); + if (debugManager == null) return; + BreakpointManager manager = debugManager.getBreakpointManager(); + Breakpoint breakpoint = manager.findLineBreakpoint(place.getDocument(), place.getOffset()); + if(breakpoint == null) { + int line = place.getDocument().getLineNumber(place.getOffset()); + LineBreakpoint lineBreakpoint = manager.addLineBreakpoint(place.getDocument(), line); + if(lineBreakpoint != null) { + RequestManagerImpl.createRequests(lineBreakpoint); + } + } else { + manager.removeBreakpoint(breakpoint); + } + } + + public static PlaceInDocument getPlace(AnActionEvent event) { + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if(project == null) return null; + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if(editor == null) { + editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + } + if (editor != null) { + final Document document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (file != null) { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType fileType = fileTypeManager.getFileTypeByFile(file.getVirtualFile()); + if (StdFileTypes.JAVA == fileType || StdFileTypes.JSP == fileType) { + final Editor editor1 = editor; + return new PlaceInDocument() { + public Document getDocument() { + return document; + } + + public int getOffset() { + return editor1.getCaretModel().getOffset(); + } + }; + } + } + } + return null; + } + + public void update(AnActionEvent event){ + boolean toEnable = false; + PlaceInDocument place = getPlace(event); + if (place != null) { + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + toEnable = LineBreakpoint.canAddLineBreakpoint(project, place.getDocument(), place.getDocument().getLineNumber(place.getOffset())); + } + + Presentation presentation = event.getPresentation(); + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace()) || + ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) || + ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace())) { + presentation.setVisible(toEnable); + } + else { + presentation.setEnabled(toEnable); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java new file mode 100644 index 00000000000..70d2770a1d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java @@ -0,0 +1,125 @@ +/** + * class ToggleMethodBreakpointAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.ui.breakpoints.MethodBreakpoint; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.util.text.CharArrayUtil; + +public class ToggleMethodBreakpointAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project); + if (debugManager == null) return; + BreakpointManager manager = debugManager.getBreakpointManager(); + + PlaceInDocument place = getPlace(e); + + if(place != null) { + Breakpoint breakpoint = manager.findMethodBreakpoint(place.getDocument(), place.getOffset()); + + if(breakpoint == null) { + int methodLine = place.getDocument().getLineNumber(place.getOffset()); + MethodBreakpoint methodBreakpoint = manager.addMethodBreakpoint(place.getDocument(), methodLine); + if(methodBreakpoint != null) { + RequestManagerImpl.createRequests(methodBreakpoint); + } + } else { + manager.removeBreakpoint(breakpoint); + } + } + } + + + private static PlaceInDocument getPlace(AnActionEvent event) { + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + if(project == null) return null; + + PsiElement method = null; + Document document = null; + + if (ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) || + ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace())) { + final PsiElement psiElement = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if(psiElement instanceof PsiMethod) { + method = psiElement; + document = PsiDocumentManager.getInstance(project).getDocument(method.getContainingFile()); + } + } else { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if(editor == null) { + editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + } + if (editor != null) { + document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (file != null) { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType fileType = fileTypeManager.getFileTypeByFile(file.getVirtualFile()); + if (StdFileTypes.JAVA == fileType || StdFileTypes.CLASS == fileType) { + method = findMethod(project, editor); + } + } + } + } + + if(method != null) { + final PsiElement method1 = method; + final Document document1 = document; + + return new PlaceInDocument() { + public Document getDocument() { + return document1; + } + + public int getOffset() { + return method1.getTextOffset(); + } + }; + } + return null; + } + + private static PsiMethod findMethod(Project project, Editor editor) { + if (editor == null) return null; + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if(psiFile == null) return null; + final int offset = CharArrayUtil.shiftForward(editor.getDocument().getCharsSequence(), editor.getCaretModel().getOffset(), " \t"); + return DebuggerUtilsEx.findPsiMethod(psiFile, offset); + } + + public void update(AnActionEvent event){ + boolean toEnable = getPlace(event) != null; + + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace()) || + ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) || + ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace())) { + event.getPresentation().setVisible(toEnable); + } + else { + event.getPresentation().setEnabled(toEnable); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewAsGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewAsGroup.java new file mode 100644 index 00000000000..b64504067d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewAsGroup.java @@ -0,0 +1,149 @@ +package com.intellij.debugger.actions; + +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.debugger.ui.tree.render.NodeRendererSettings; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 11:05:57 PM + */ +public class ViewAsGroup extends ActionGroup{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.ViewAsGroup"); + + private AnAction [] myChildren = new AnAction[0]; + + public ViewAsGroup() { + super(null, true); + } + + private static class RendererAction extends ToggleAction { + private final NodeRenderer myNodeRenderer; + + public RendererAction(NodeRenderer nodeRenderer) { + super(nodeRenderer.getName()); + myNodeRenderer = nodeRenderer; + } + + public boolean isSelected(AnActionEvent e) { + DebuggerTreeNodeImpl[] nodes = DebuggerAction.getSelectedNodes(e.getDataContext()); + for (int i = 0; i < nodes.length; i++) { + DebuggerTreeNodeImpl node = nodes[i]; + if(node.getDescriptor() instanceof ValueDescriptorImpl) { + if(((ValueDescriptorImpl)node.getDescriptor()).getLastRenderer() != myNodeRenderer) { + return false; + } + } + } + return true; + } + + public void setSelected(final AnActionEvent e, final boolean state) { + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + final DebuggerTreeNodeImpl[] nodes = DebuggerAction.getSelectedNodes(e.getDataContext()); + + LOG.assertTrue(debuggerContext != null && nodes != null); + + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + for (int i = 0; i < nodes.length; i++) { + final DebuggerTreeNodeImpl node = nodes[i]; + if (node.getDescriptor() instanceof ValueDescriptorImpl) { + final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl) node.getDescriptor(); + if (state) { + valueDescriptor.setRenderer(myNodeRenderer); + node.calcRepresentation(); + } + } + } + } + }); + } + } + + public AnAction[] getChildren(final AnActionEvent e) { + return myChildren; + } + + private AnAction [] calcChildren(DebuggerTreeNodeImpl [] nodes, DebuggerContextImpl debuggerContext) { + List renderers = new ArrayList(); + + List allRenderers = NodeRendererSettings.getInstance().getAllRenderers(); + + boolean anyValueDescriptor = false; + + for (Iterator iterator = allRenderers.iterator(); iterator.hasNext();) { + NodeRenderer nodeRenderer = iterator.next(); + + boolean allApp = true; + + for (int i = 0; i < nodes.length; i++) { + DebuggerTreeNodeImpl node = nodes[i]; + NodeDescriptorImpl descriptor = node.getDescriptor(); + if(descriptor instanceof ValueDescriptorImpl) { + anyValueDescriptor = true; + ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl) descriptor); + if(valueDescriptor.isValueValid() && !nodeRenderer.isApplicable(valueDescriptor.getType())) { + allApp = false; + break; + } + } + } + + if(!anyValueDescriptor) { + return new AnAction[0]; + } + + if(allApp) { + renderers.add(new RendererAction(nodeRenderer)); + } + } + + List children = new ArrayList(); + AnAction[] viewAsActions = ((DefaultActionGroup) ActionManager.getInstance().getAction(DebuggerActions.REPRESENTATION_LIST)).getChildren(null); + for (int i = 0; i < viewAsActions.length; i++) { + AnAction viewAsAction = viewAsActions[i]; + + if(viewAsAction instanceof AutoRendererAction) { + if(renderers.size() > 1) { + viewAsAction.getTemplatePresentation().setVisible(true); + children.add(viewAsAction); + } + } + else { + children.add(viewAsAction); + } + } + + children.add(Separator.getInstance()); + children.addAll(renderers); + + return children.toArray(new AnAction[children.size()]); + } + + public void update(final AnActionEvent event) { + if(!DebuggerAction.isFirstStart(event)) return; + + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(event.getDataContext()); + final DebuggerTreeNodeImpl[] selectedNodes = DebuggerAction.getSelectedNodes(event.getDataContext()); + + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + myChildren = calcChildren(selectedNodes, debuggerContext); + DebuggerAction.enableAction(event, myChildren.length > 0); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewBreakpointsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewBreakpointsAction.java new file mode 100644 index 00000000000..283dc26f105 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/actions/ViewBreakpointsAction.java @@ -0,0 +1,64 @@ +/* + * Class ViewBreakpointsAction + * @author Jeka + */ +package com.intellij.debugger.actions; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.debugger.ui.breakpoints.BreakpointPropertiesPanel; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +public class ViewBreakpointsAction extends AnAction { + private Breakpoint myInitialBreakpoint; + + public ViewBreakpointsAction(){ + this("View Breakpoints..."); + } + + public ViewBreakpointsAction(String name) { + super(name); + } + + public void setInitialBreakpoint(Breakpoint breakpoint) { + myInitialBreakpoint = breakpoint; + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project); + + if (myInitialBreakpoint == null) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + BreakpointManager manager = debugManager.getBreakpointManager(); + int offset = editor.getCaretModel().getOffset(); + Document editorDocument = editor.getDocument(); + myInitialBreakpoint = manager.findBreakpoint(editorDocument, offset); + } + } + + DialogWrapper dialog = debugManager.getBreakpointManager().createConfigurationDialog(myInitialBreakpoint, null); + dialog.show(); + myInitialBreakpoint = null; + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(true); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/codeinsight/SurroundWithRuntimeCastHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/codeinsight/SurroundWithRuntimeCastHandler.java new file mode 100644 index 00000000000..1c986b03f30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/codeinsight/SurroundWithRuntimeCastHandler.java @@ -0,0 +1,139 @@ +package com.intellij.debugger.codeinsight; + +import com.intellij.codeInsight.generation.surroundWith.SurroundExpressionHandler; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; +import com.intellij.debugger.ui.EditorEvaluationCommand; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Value; + +/** + * User: lex + * Date: Jul 17, 2003 + * Time: 7:51:01 PM + */ +public class SurroundWithRuntimeCastHandler implements SurroundExpressionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.codeinsight.SurroundWithRuntimeCastHandler"); + + public SurroundWithRuntimeCastHandler() { + } + + public boolean isApplicable(PsiExpression expr) { + PsiFile file = expr.getContainingFile(); + if (!(file instanceof PsiCodeFragment)) return false; + return file.getUserData(DebuggerExpressionComboBox.KEY) != null; + } + + public TextRange surroundExpression(Project project, Editor editor, PsiExpression expr) throws IncorrectOperationException { + DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + DebuggerSession debuggerSession = debuggerContext.getDebuggerSession(); + if (debuggerSession != null) { + SurroundWithCastWorker worker = new SurroundWithCastWorker(editor, expr, debuggerContext); + worker.getProgressWindow().setTitle("Evaluating expression..."); + debuggerContext.getDebugProcess().getManagerThread().startProgress(worker, worker.getProgressWindow()); + } + return null; + } + + private class SurroundWithCastWorker extends EditorEvaluationCommand { + public SurroundWithCastWorker(Editor editor, PsiExpression expression, DebuggerContextImpl context) { + super(editor, expression, context); + } + + protected void executeWriteCommand(final Project project, final Runnable runnable) { + DebuggerInvocationUtil.invokeLater(project, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(project, runnable, "Surround with runtime cast", null); + } + }); + } + }, getProgressWindow().getModalityState()); + } + + public void threadAction() { + final String type; + try { + type = evaluate(); + } + catch (ProcessCanceledException e) { + return; + } + catch (EvaluateException e) { + return; + } + + final Project project = myElement.getProject(); + + hold(); + + executeWriteCommand(project, new Runnable() { + public void run() { + try { + LOG.assertTrue(type != null); + + PsiElementFactory factory = myElement.getManager().getElementFactory(); + PsiParenthesizedExpression parenth = (PsiParenthesizedExpression) factory.createExpressionFromText("((" + type + ")expr)", null); + PsiTypeCastExpression cast = (PsiTypeCastExpression) parenth.getExpression(); + cast.getOperand().replace(myElement); + parenth = (PsiParenthesizedExpression)CodeStyleManager.getInstance(project).shortenClassReferences(parenth); + PsiExpression expr = (PsiExpression) myElement.replace(parenth); + TextRange range = expr.getTextRange(); + getEditor().getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + getEditor().getCaretModel().moveToOffset(range.getEndOffset()); + getEditor().getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + finally{ + release(); + } + } + }); + } + + protected String evaluate(EvaluationContextImpl evaluationContext) throws EvaluateException { + final Project project = evaluationContext.getProject(); + + ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(project, new com.intellij.debugger.EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl.getInstance().build((PsiExpression)myElement); + } + }); + + final Value value = evaluator.evaluate(evaluationContext); + if(value != null){ + return ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return DebuggerUtilsEx.getQualifiedClassName(value.type().name(), project); + } + }); + } else { + throw EvaluateExceptionUtil.createEvaluateException("Surrounded expression is null"); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/CompoundPositionManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/CompoundPositionManager.java new file mode 100644 index 00000000000..458ee7fc7df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/CompoundPositionManager.java @@ -0,0 +1,85 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.PositionManager; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.NoDataException; +import com.intellij.debugger.requests.ClassPrepareRequestor; +import com.sun.jdi.Location; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.request.ClassPrepareRequest; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Collections; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class CompoundPositionManager implements PositionManager{ + private final ArrayList myPositionManagers = new ArrayList(); + + public CompoundPositionManager() { + } + + public CompoundPositionManager(PositionManager manager) { + appendPositionManager(manager); + } + + public void appendPositionManager(PositionManager manager) { + myPositionManagers.remove(manager); + myPositionManagers.add(0, manager); + } + + public SourcePosition getSourcePosition(Location location) { + for (Iterator iterator = myPositionManagers.iterator(); iterator.hasNext();) { + PositionManager positionManager = iterator.next(); + try { + return positionManager.getSourcePosition(location); + } + catch (NoDataException e) { + } + } + return null; + } + + public List getAllClasses(SourcePosition classPosition) { + for (Iterator iterator = myPositionManagers.iterator(); iterator.hasNext();) { + PositionManager positionManager = iterator.next(); + try { + return positionManager.getAllClasses(classPosition); + } + catch (NoDataException e) { + } + } + return Collections.EMPTY_LIST; + } + + public List locationsOfLine(ReferenceType type, SourcePosition position) { + for (Iterator iterator = myPositionManagers.iterator(); iterator.hasNext();) { + PositionManager positionManager = iterator.next(); + try { + return positionManager.locationsOfLine(type, position); + } + catch (NoDataException e) { + } + } + return Collections.EMPTY_LIST; + } + + public ClassPrepareRequest createPrepareRequest(ClassPrepareRequestor requestor, SourcePosition position) { + for (Iterator iterator = myPositionManagers.iterator(); iterator.hasNext();) { + PositionManager positionManager = iterator.next(); + + try { + return positionManager.createPrepareRequest(requestor, position); + } + catch (NoDataException e) { + } + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/ContextUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/ContextUtil.java new file mode 100644 index 00000000000..61c5a4fb2b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/ContextUtil.java @@ -0,0 +1,181 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.jsp.JspImplicitVariable; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Location; + +import java.util.Iterator; +import java.util.List; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class ContextUtil { + public static final Key IS_JSP_IMPLICIT = new Key("JspImplicit"); + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.PositionUtil"); + + public static SourcePosition getSourcePosition(final StackFrameContext context) { + DebugProcessImpl debugProcess = (DebugProcessImpl)context.getDebugProcess(); + if(debugProcess == null) return null; + if(context.getFrameProxy() == null) return null; + Location location = null; + try { + location = context.getFrameProxy().location(); + } catch (Throwable th) { + LOG.debug(th); + } + return ((DebugProcessImpl)context.getDebugProcess()).getPositionManager().getSourcePosition(location); + } + + public static PsiElement getContextElement(final StackFrameContext context) { + return getContextElement(context, getSourcePosition(context)); + } + + protected static PsiElement getContextElement(final StackFrameContext context, final SourcePosition position) { + if(LOG.isDebugEnabled()) { + final SourcePosition sourcePosition = getSourcePosition(context); + LOG.assertTrue(Comparing.equal(sourcePosition, position)); + } + + final PsiElement element = getContextElement(position); + + if(element == null) return null; + + final StackFrameProxyImpl frameProxy = (StackFrameProxyImpl)context.getFrameProxy(); + + if(frameProxy == null) return element; + + try { + List list = frameProxy.visibleVariables(); + + StringBuffer buf = new StringBuffer(); + PsiResolveHelper resolveHelper = element.getManager().getResolveHelper(); + buf.append('{'); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + LocalVariableProxyImpl localVariable = iterator.next(); + + String varName = localVariable.name(); + if(resolveHelper.resolveReferencedVariable(varName, element) == null) { + buf.append(localVariable.getVariable().typeName() + " " + varName + ";"); + } + } + buf.append('}'); + + if(buf.length() > 2) { + PsiElementFactory elementFactory = element.getManager().getElementFactory(); + PsiCodeBlock codeBlockFromText = elementFactory.createCodeBlockFromText(buf.toString(), element); + + PsiStatement[] statements = codeBlockFromText.getStatements(); + for (int i = 0; i < statements.length; i++) { + PsiStatement statement = statements[i]; + if (statement instanceof PsiDeclarationStatement) { + PsiDeclarationStatement declStatement = (PsiDeclarationStatement)statement; + PsiElement[] declaredElements = declStatement.getDeclaredElements(); + for (int j = 0; j < declaredElements.length; j++) { + declaredElements[j].putUserData(IS_JSP_IMPLICIT, IS_JSP_IMPLICIT); + } + } + } + return codeBlockFromText; + } + else { + return element; + } + } + catch (IncorrectOperationException e) { + return element; + } + catch (EvaluateException e) { + return element; + } + } + + public static PsiElement getContextElement(final SourcePosition position) { + if(position == null) return null; + + final PsiFile psiFile = position.getFile(); + final PsiElement element = getContextElementInText(psiFile, position.getLine()); + + if(psiFile instanceof JspFileImpl) { + JspFileImpl jspFile = (JspFileImpl)psiFile; + JspImplicitVariable[] predefinedVariables = jspFile.getPredefinedVariables(); + StringBuffer buf = new StringBuffer(); + buf.append('{'); + for (int i = 0; i < predefinedVariables.length; i++) { + JspImplicitVariable predefinedVariable = predefinedVariables[i]; + buf.append(predefinedVariable.getText()); + buf.append(";\n"); + } + buf.append('}'); + + if(buf.length() > 2) { + PsiElementFactory elementFactory = psiFile.getManager().getElementFactory(); + try { + PsiCodeBlock codeBlockFromText = elementFactory.createCodeBlockFromText(buf.toString(), element); + PsiStatement[] statements = codeBlockFromText.getStatements(); + for (int i = 0; i < statements.length; i++) { + PsiDeclarationStatement statement = (PsiDeclarationStatement)statements[i]; + PsiElement[] declaredElements = statement.getDeclaredElements(); + for (int j = 0; j < declaredElements.length; j++) { + declaredElements[j].putUserData(IS_JSP_IMPLICIT, IS_JSP_IMPLICIT); + } + } + return codeBlockFromText; + } + catch (IncorrectOperationException e) { + LOG.assertTrue(false); + } + } + } + + return element; + } + + private static PsiElement getContextElementInText(PsiFile psiFile, int lineNumber) { + if(lineNumber < 0) return psiFile; + + String text = psiFile.getText(); + int startOffset = StringUtil.lineColToOffset(text, lineNumber, 0); + + if(startOffset == -1) return null; + + PsiElement element; + for(;;) { + for (; startOffset < text.length(); startOffset++) { + char c = text.charAt(startOffset); + if (c != ' ' && c != '\t') break; + } + element = psiFile.findElementAt(startOffset); + + if(element instanceof PsiComment) + startOffset = element.getTextRange().getEndOffset() + 1; + else + break; + } + + if (element != null && element.getParent() instanceof PsiForStatement) { + return ((PsiForStatement)element.getParent()).getInitialization(); + } + else { + return element; + } + } + + public static boolean isJspImplicit(PsiElement element) { + return element.getUserData(IS_JSP_IMPLICIT) != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessAdapterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessAdapterImpl.java new file mode 100644 index 00000000000..4a4fee9ec7b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessAdapterImpl.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RunProfileState; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 26, 2004 + * Time: 4:11:18 PM + * To change this template use File | Settings | File Templates. + */ +public class DebugProcessAdapterImpl implements DebugProcessListener { + //executed in manager thread + public final void paused(SuspendContext suspendContext) { + paused(((SuspendContextImpl)suspendContext)); + } + + //executed in manager thread + public final void resumed(SuspendContext suspendContext) { + resumed(((SuspendContextImpl)suspendContext)); + } + + //executed in manager thread + public final void processDetached(DebugProcess process) { + processDetached(((DebugProcessImpl)process)); + } + + //executed in manager thread + public final void processAttached(DebugProcess process) { + processAttached(((DebugProcessImpl)process)); + } + + //executed in manager thread + public void connectorIsReady() { + } + + public void paused(SuspendContextImpl suspendContext) { + //To change body of implemented methods use File | Settings | File Templates. + } + + //executed in manager thread + public void resumed(SuspendContextImpl suspendContext) { + //To change body of implemented methods use File | Settings | File Templates. + } + + //executed in manager thread + public void processDetached(DebugProcessImpl process) { + //To change body of implemented methods use File | Settings | File Templates. + } + + //executed in manager thread + public void processAttached(DebugProcessImpl process) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void attachException(RunProfileState state, ExecutionException exception, RemoteConnection remoteConnection) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessEvents.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessEvents.java new file mode 100644 index 00000000000..b2cbd3ec082 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessEvents.java @@ -0,0 +1,402 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.requests.LocatableEventRequestor; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.requests.Requestor; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.LineBreakpoint; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.util.concurrency.Semaphore; +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.EventRequest; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 25, 2004 + * Time: 4:39:03 PM + * To change this template use File | Settings | File Templates. + */ +public class DebugProcessEvents extends DebugProcessImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebugProcessEvents"); + private DebuggerEventThread myEventThread; + + public DebugProcessEvents(Project project) { + super(project); + } + + protected void commitVM(final VirtualMachine vm) { + super.commitVM(vm); + if(vm != null) { + vmAttached(); + + myEventThread = new DebuggerEventThread(); + myEventThread.start(); + + } + } + + private static void showStatusText(DebugProcessImpl debugProcess, Event event) { + Requestor requestor = debugProcess.getRequestsManager().findRequestor(event.request()); + Breakpoint breakpoint = null; + if(requestor instanceof Breakpoint) { + breakpoint = (Breakpoint)requestor; + } + String text = getEventText(new Pair(breakpoint, event)); + debugProcess.showStatusText(text); + } + + public static String getEventText(Pair descriptor) { + String text = ""; + Event event = descriptor.getSecond(); + if (event instanceof VMStartEvent) { + text = "Process started"; + } + else if (event instanceof VMDeathEvent) { + text = "Process terminated"; + } + else if (event instanceof VMDisconnectEvent) { + text = "Disconnected from the debugged process"; + } + else if (event instanceof ExceptionEvent) { + ExceptionEvent exceptionEvent = (ExceptionEvent)event; + ObjectReference objectReference = exceptionEvent.exception(); + try { + text = "Exception breakpoint reached. Exception '" + objectReference.referenceType().name() + "' in thread '" + exceptionEvent.thread().name() + "'"; + } + catch (Exception e) { + text = "Exception breakpoint reached. "; + } + } + else if (event instanceof AccessWatchpointEvent) { + AccessWatchpointEvent accessEvent = (AccessWatchpointEvent)event; + StringBuffer message = new StringBuffer(32); + message.append("Field watchpoint reached. "); + ObjectReference object = accessEvent.object(); + Field field = accessEvent.field(); + if (object != null) { + message.append("{"); + } + message.append(field.declaringType().name()); + if (object != null) { + message.append('@'); + message.append(object.uniqueID()); + message.append("}"); + } + message.append('.'); + message.append(field.name()); + message.append(" will be accessed."); + text = message.toString(); + } + else if (event instanceof ModificationWatchpointEvent) { + ModificationWatchpointEvent modificationEvent = (ModificationWatchpointEvent)event; + StringBuffer message = new StringBuffer(64); + message.append("Field watchpoint reached. "); + Field field = modificationEvent.field(); + ObjectReference object = modificationEvent.object(); + if (object != null) { + message.append("{"); + } + message.append(field.declaringType().name()); + if (object != null) { + message.append('@'); + message.append(object.uniqueID()); + message.append("}"); + } + message.append('.'); + message.append(field.name()); + message.append(" will be modified. Current value = '"); + message.append(modificationEvent.valueCurrent()); + message.append("'. New value = '"); + message.append(modificationEvent.valueToBe()); + message.append("'."); + text = message.toString(); + } + else if (event instanceof BreakpointEvent) { + BreakpointEvent breakpointEvent = (BreakpointEvent)event; + Breakpoint breakpoint = descriptor.getFirst(); + if (breakpoint instanceof LineBreakpoint && !((LineBreakpoint)breakpoint).isVisible()) { + text = "Stopped at cursor"; + } + else { + Location location = breakpointEvent.location(); + try { + text = "Breakpoint reached in " + location.sourceName() + "; at line "+location.lineNumber(); + } + catch (AbsentInformationException e) { + text = "Breakpoint reached"; + } + catch (InternalException e) { + text = "Breakpoint reached"; + } + } + } + else if (event instanceof MethodEntryEvent) { + MethodEntryEvent entryEvent = (MethodEntryEvent)event; + Method method = entryEvent.method(); + text = "Method '" + method + "' entered"; + } + else if (event instanceof MethodExitEvent) { + MethodExitEvent exitEvent = (MethodExitEvent)event; + Method method = exitEvent.method(); + text = "Method breakpoint reached. Method '" + method + "' is about to exit"; + } + return text; + } + + private class DebuggerEventThread extends Thread { + final VirtualMachineProxyImpl myVmProxy; + + DebuggerEventThread () { + super("DebuggerEventThread"); + myVmProxy = getVirtualMachineProxy(); + } + + private boolean myIsStopped = false; + + public synchronized void stopListening() { + myIsStopped = true; + } + + private synchronized boolean isStopped() { + return myIsStopped; + } + + public void run() { + try { + EventQueue eventQueue = myVmProxy.eventQueue(); + while (!isStopped()) { + try { + LOG.debug("Listening events"); + final EventSet eventSet = eventQueue.remove(); + + if (LOG.isDebugEnabled()) { + LOG.debug("EventSet " + eventSet.toString() + ", suspendPolicy=" + eventSet.suspendPolicy() + ";size=" + eventSet.size()); + } + + DebugProcessEvents.this.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + protected void action() throws Exception { + final SuspendContextImpl suspendContext = getSuspendManager().pushSuspendContext(eventSet); + + for (EventIterator eventIterator = eventSet.eventIterator(); eventIterator.hasNext(); ) { + final Event event = eventIterator.nextEvent(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Event : " + event); + } + try { + if (event instanceof VMStartEvent) { + //Sun WTK fails when J2ME when event set is resumed on VMStartEvent + processVMStartEvent(suspendContext, (VMStartEvent)event); + } + else if (event instanceof VMDeathEvent) { + processVMDeathEvent(suspendContext, event); + } + else if (event instanceof VMDisconnectEvent) { + processVMDeathEvent(suspendContext, event); + } + else if (event instanceof ClassPrepareEvent) { + processClassPrepareEvent(suspendContext, (ClassPrepareEvent)event); + } + //AccessWatchpointEvent, BreakpointEvent, ExceptionEvent, MethodEntryEvent, MethodExitEvent, + //ModificationWatchpointEvent, StepEvent, WatchpointEvent + else if (event instanceof StepEvent) { + processStepEvent(suspendContext, (StepEvent)event); + } + else if (event instanceof LocatableEvent) { + processLocatableEvent(suspendContext, (LocatableEvent)event); + } + else if (event instanceof ClassUnloadEvent){ + processDefaultEvent(suspendContext); + } + } + catch (VMDisconnectedException e) { + LOG.debug(e); + } + catch (Throwable e) { + LOG.error(e); + } + } + } + }); + + } + catch (InternalException e) { + LOG.debug(e); + } + catch (InterruptedException e) { + throw e; + } + catch (VMDisconnectedException e) { + throw e; + } + catch (Throwable e) { + LOG.debug(e); + } + } + } + catch (InterruptedException e) { + invokeVMDeathEvent(); + } + catch (VMDisconnectedException e) { + invokeVMDeathEvent(); + } + } + + private void invokeVMDeathEvent() { + DebugProcessEvents.this.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + protected void action() throws Exception { + SuspendContextImpl suspendContext = getSuspendManager().pushSuspendContext(EventRequest.SUSPEND_NONE, 1); + processVMDeathEvent(suspendContext, null); + } + }); + } + } + + private static void preprocessEvent(SuspendContextImpl suspendContext, ThreadReference thread) { + ThreadReferenceProxyImpl oldThread = suspendContext.getThread(); + suspendContext.setThread(thread); + + if(oldThread == null) { + //this is the first event in the eventSet that we process + suspendContext.getDebugProcess().beforeSuspend(suspendContext); + } + } + + private void processVMStartEvent(final SuspendContextImpl suspendContext, VMStartEvent event) { + preprocessEvent(suspendContext, event.thread()); + + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processVMStartEvent()"); + } + + showStatusText(this, event); + + getSuspendManager().voteResume(suspendContext); + } + + private void vmAttached() { + LOG.assertTrue(!isAttached()); + if(isDetached()) return; + + setIsAttached(); + + myDebugProcessDispatcher.getMulticaster().processAttached(this); + + showStatusText("Connected"); + if (LOG.isDebugEnabled()) { + LOG.debug("leave: processVMStartEvent()"); + } + } + + private void processVMDeathEvent(SuspendContextImpl suspendContext, Event event) { + preprocessEvent(suspendContext, null); + + if (myEventThread != null) { + myEventThread.stopListening(); + myEventThread = null; + } + + cancelRunToCursorBreakpoint(); + + closeProcess(true); + + if(event != null) { + showStatusText(this, event); + } + } + + private void processClassPrepareEvent(SuspendContextImpl suspendContext, ClassPrepareEvent event) { + preprocessEvent(suspendContext, event.thread()); + if (LOG.isDebugEnabled()) { + LOG.debug("Class prepared: " + event.referenceType().name()); + } + suspendContext.getDebugProcess().getRequestsManager().processClassPrepared(event); + + getSuspendManager().voteResume(suspendContext); + } + + private void processStepEvent(SuspendContextImpl suspendContext, StepEvent event) { + ThreadReference thread = event.thread(); + LOG.assertTrue(thread.isSuspended()); + preprocessEvent(suspendContext, thread); + + RequestHint hint = (RequestHint)event.request().getProperty("hint"); + + boolean shouldResume = false; + + if (hint != null) { + if (hint.shouldSkipFrame(suspendContext)) { + if (LOG.isDebugEnabled()) { + LOG.debug("STEPOUT doStep"); + } + shouldResume = doStep(suspendContext, hint.getDepth(), hint); + } + + if(!shouldResume && hint.isRestoreBreakpoints()) { + DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().enableBreakpoints(DebugProcessEvents.this); + } + } + + if(shouldResume) { + getSuspendManager().voteResume(suspendContext); + } else { + showStatusText(""); + getSuspendManager().voteSuspend(suspendContext); + } + } + + private void processLocatableEvent(final SuspendContextImpl suspendContext, final LocatableEvent event) { + ThreadReference thread = event.thread(); + LOG.assertTrue(thread.isSuspended()); + preprocessEvent(suspendContext, thread); + + final DebugProcessEvents debugProcess = (DebugProcessEvents)suspendContext.getDebugProcess(); + + //we use invokeLater to allow processing events during processing this one + //this is especially nesessary if a method is breakpoint condition + debugProcess.getManagerThread().invokeLater(new SuspendContextCommandImpl(suspendContext) { + public void contextAction() throws Exception { + SuspendContextImpl evaluatingContext = SuspendManagerUtil.getEvaluatingContext(debugProcess.getSuspendManager(), getSuspendContext().getThread()); + + if(evaluatingContext != null && !evaluatingContext.getEvaluationContext().isAllowBreakpoints()) { + getSuspendManager().voteResume(suspendContext); + return; + } + + LocatableEventRequestor requestor = (LocatableEventRequestor) debugProcess.getRequestsManager().findRequestor(event.request()); + + boolean shouldResumeExecution = true; + + if(requestor != null) { + shouldResumeExecution = requestor.processLocatableEvent(this, event); + } + + if(shouldResumeExecution) { + getSuspendManager().voteResume(suspendContext); + } + else { + //suspendContext.voteResume(); + getSuspendManager().voteSuspend(suspendContext); + showStatusText(debugProcess, event); + } + } + }); + //suspendContext.voteResume(); + } + + private void processDefaultEvent(SuspendContextImpl suspendContext) { + preprocessEvent(suspendContext, null); + getSuspendManager().voteResume(suspendContext); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessImpl.java new file mode 100644 index 00000000000..32f2d465b45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebugProcessImpl.java @@ -0,0 +1,1517 @@ +package com.intellij.debugger.engine; + +import com.intellij.Patches; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.PositionManager; +import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.jdi.ThreadReferenceProxy; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.DebuggerSmoothManager; +import com.intellij.debugger.ui.DescriptorHistoryManagerImpl; +import com.intellij.debugger.ui.breakpoints.LineBreakpoint; +import com.intellij.debugger.ui.impl.watch.DescriptorHistoryManager; +import com.intellij.debugger.ui.impl.watch.render.NodeRendererManagerImpl; +import com.intellij.execution.CantRunException; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessListener; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.util.Alarm; +import com.intellij.util.EventDispatcher; +import com.intellij.util.concurrency.Semaphore; +import com.sun.jdi.*; +import com.sun.jdi.connect.*; +import com.sun.jdi.request.EventRequest; +import com.sun.jdi.request.EventRequestManager; +import com.sun.jdi.request.StepRequest; +import com.sun.tools.jdi.ConnectionService; +import com.sun.tools.jdi.TransportService; +import com.sun.tools.jdi.VirtualMachineManagerService; + +import javax.swing.*; +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.*; + +public abstract class DebugProcessImpl implements DebugProcess { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebugProcessImpl"); + + private static final String SOCKET_ATTACHING_CONNECTOR_NAME = "com.sun.jdi.SocketAttach"; + private static final String SHMEM_ATTACHING_CONNECTOR_NAME = "com.sun.jdi.SharedMemoryAttach"; + private static final String SOCKET_LISTENING_CONNECTOR_NAME = "com.sun.jdi.SocketListen"; + private static final String SHMEM_LISTENING_CONNECTOR_NAME = "com.sun.jdi.SharedMemoryListen"; + + public static final String ALWAYS_FORCE_CLASSIC_VM = "always"; + public static final String NEVER_FORCE_CLASSIC_VM = "never"; + public static final String IF_SELECTED_FORCE_CLASSIC_VM = "if_selected"; + + public static final String JAVA_STRATUM = "Java"; + + private final Project myProject; + private final RequestManagerImpl myRequestManager; + + private VirtualMachineProxyImpl myVirtualMachineProxy = null; + protected EventDispatcher myDebugProcessDispatcher = EventDispatcher.create(DebugProcessListener.class, false); + protected EventDispatcher myEvaluationDispatcher = EventDispatcher.create(EvaluationListener.class, false); + + private List myProcessListeners = new ArrayList(); + + private static final int STATE_INITIAL = 0; + private static final int STATE_ATTACHED = 1; + private static final int STATE_DETACHING = 2; + private static final int STATE_DETACHED = 3; + private int myState = STATE_INITIAL; + + private boolean myCanRedefineClasses; + private boolean myCanWatchFieldModification; + + private ExecutionResult myExecution; + private RemoteConnection myConnection; + + private ConnectionService myConnectionService; + private Map myArguments; + + private LinkedList myStatusStack = new LinkedList(); + private String myStatusText; + private int mySuspendPolicy = DebuggerSettings.getInstance().isSuspendAllThreads() + ? EventRequest.SUSPEND_ALL + : EventRequest.SUSPEND_EVENT_THREAD; + + private final DescriptorHistoryManager myDescriptorHistoryManager; + private final NodeRendererManagerImpl myNodeRendererManager = new NodeRendererManagerImpl(this); + private final SuspendManager mySuspendManager = new SuspendManagerImpl(this); + protected CompoundPositionManager myPositionManager = null; + DebuggerManagerThreadImpl myDebuggerManagerThread; + public static final String MSG_FAILD_TO_CONNECT = "Failed to establish connection to the target VM"; + private HashMap myUserData = new HashMap(); + private static int LOCAL_START_TIMEOUT = 15000; + + private final Semaphore myWaitFor = new Semaphore(); + + protected DebugProcessImpl(Project project) { + myProject = project; + myRequestManager = new RequestManagerImpl(this); + myDescriptorHistoryManager = new DescriptorHistoryManagerImpl(project); + setSuspendPolicy(DebuggerSettings.getInstance().isSuspendAllThreads()); + } + + protected void commitVM(VirtualMachine vm) { + LOG.assertTrue(myState == STATE_INITIAL, "State is invalid " + myState); + DebuggerManagerThreadImpl.assertIsManagerThread(); + myPositionManager = createPositionManager(); + if (LOG.isDebugEnabled()) { + LOG.debug("*******************VM attached******************"); + } + checkVirtualMachineVersion(vm); + + myVirtualMachineProxy = new VirtualMachineProxyImpl(this, vm); + myCanRedefineClasses = myVirtualMachineProxy.canRedefineClasses(); + myCanWatchFieldModification = myVirtualMachineProxy.canWatchFieldModification(); + + String trace = System.getProperty("idea.debugger.trace"); + if (trace != null) { + int mask = 0; + StringTokenizer tokenizer = new StringTokenizer(trace); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if ("SENDS".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_SENDS; + } + else if ("RECEIVES".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_RECEIVES; + } + else if ("EVENTS".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_EVENTS; + } + else if ("REFTYPES".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_REFTYPES; + } + else if ("OBJREFS".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_OBJREFS; + } + else if ("ALL".compareToIgnoreCase(token) == 0) { + mask |= VirtualMachine.TRACE_ALL; + } + } + + vm.setDebugTraceMode(mask); + } + } + + private void stopConnecting() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + + Map arguments = myArguments; + try { + if (arguments == null) { + return; + } + if(myConnection.isServerMode()) { + ListeningConnector connector = (ListeningConnector)findConnector(SOCKET_LISTENING_CONNECTOR_NAME); + LOG.assertTrue(connector != null, "Cannot find connector: " + SOCKET_LISTENING_CONNECTOR_NAME); + connector.stopListening(arguments); + } + else { + if(myConnectionService != null) { + myConnectionService.close(); + } + } + } + catch (IOException e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + } + catch (IllegalConnectorArgumentsException e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + } + catch (ExecutionException e) { + LOG.error(e); + } + finally { + closeProcess(false); + } + } + + protected CompoundPositionManager createPositionManager() { + return new CompoundPositionManager(new PositionManagerImpl(this)); + } + + public void printToConsole(final String text) { + myExecution.getProcessHandler().notifyTextAvailable(text, ProcessOutputTypes.SYSTEM); + } + + /** + * + * @param suspendContext + * @param depth + * @param hint may be null + * @return + */ + protected boolean doStep(SuspendContextImpl suspendContext, int depth, RequestHint hint) { + final ThreadReferenceProxyImpl currentThreadProxy = suspendContext.getThread(); + if (currentThreadProxy == null || !currentThreadProxy.isSuspended()) return false; + if (LOG.isDebugEnabled()) { + LOG.debug("DO_STEP: creating step request for " + currentThreadProxy.getThreadReference()); + } + deleteStepRequests(suspendContext.getThread()); + EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager(); + StepRequest stepRequest = requestManager.createStepRequest(currentThreadProxy.getThreadReference(), StepRequest.STEP_LINE, depth); + DebuggerSettings settings = DebuggerSettings.getInstance(); + if (!(hint != null && hint.isIgnoreFilters()) && depth == StepRequest.STEP_INTO) { + if (settings.TRACING_FILTERS_ENABLED) { + String currentClassName = getCurrentClassName(currentThreadProxy); + if (currentClassName == null || !settings.isNameFiltered(currentClassName)) { + // add class filters + ClassFilter[] filters = settings.getFilters(); + for (int idx = 0; idx < filters.length; idx++) { + if (filters[idx].isEnabled()) { + stepRequest.addClassExclusionFilter(filters[idx].getPattern()); + } + } + } + } + } + + stepRequest.setSuspendPolicy(getSuspendPolicy()); + + if (hint != null) { + stepRequest.putProperty("hint", hint); + } + stepRequest.enable(); + return true; + } + + void deleteStepRequests(ThreadReferenceProxy requestsInThread) { + EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager(); + List stepRequests = requestManager.stepRequests(); + if (stepRequests.size() > 0) { + List toDelete = new ArrayList(); + for (Iterator iterator = stepRequests.iterator(); iterator.hasNext();) { + StepRequest request = (StepRequest)iterator.next(); + ThreadReference threadReference = request.thread(); + + if (threadReference.status() == ThreadReference.THREAD_STATUS_UNKNOWN) { + // [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occures + continue; + } + else if(threadReference.equals(requestsInThread.getThreadReference())) { + toDelete.add(request); + } + } + for (Iterator iterator = toDelete.iterator(); iterator.hasNext();) { + StepRequest request = (StepRequest)iterator.next(); + requestManager.deleteEventRequest(request); + } + } + } + + private String getCurrentClassName(ThreadReferenceProxyImpl thread) { + try { + final ThreadReferenceProxyImpl currentThreadProxy = thread; + if (currentThreadProxy != null) { + if (currentThreadProxy.frameCount() > 0) { + StackFrameProxyImpl stackFrame = currentThreadProxy.frame(0); + Location location = stackFrame.location(); + ReferenceType referenceType = location.declaringType(); + if (referenceType != null) { + return referenceType.name(); + } + } + } + } + catch (EvaluateException e) { + } + return null; + } + + private VirtualMachine createVirtualMachineInt() + throws ExecutionException { + + try { + if (myArguments != null) { + throw new IOException("DebugProcessImpl is already listening"); + } + + String address = myConnection.getAddress(); + if (myConnection.isServerMode()) { + ListeningConnector connector = (ListeningConnector)findConnector( + myConnection.isUseSockets() ? SOCKET_LISTENING_CONNECTOR_NAME : SHMEM_LISTENING_CONNECTOR_NAME); + if (connector == null) { + throw new CantRunException("Cannot listen using " + + (!myConnection.isUseSockets() ? "shared memory" : "socket") + + " transport: required connector not found. Check your JDK installation."); + } + myArguments = connector.defaultArguments(); + if (myArguments == null) { + throw new CantRunException("The port to listen at unspecified"); + } + + if (address == null) { + throw new CantRunException("The port to listen at unspecified"); + } + // negative port number means the caller leaves to debugger to decide at which hport to listen + Connector.Argument portArg = myConnection.isUseSockets() + ? (Connector.Argument)myArguments.get("port") + : (Connector.Argument)myArguments.get("name"); + if (portArg != null) { + portArg.setValue(address); + } + connector.startListening(myArguments); + myDebugProcessDispatcher.getMulticaster().connectorIsReady(); + try { + return connector.accept(myArguments); + } + finally { + if(myArguments != null) connector.stopListening(myArguments); + } + } + else { + AttachingConnector connector = (AttachingConnector)findConnector( + myConnection.isUseSockets() ? SOCKET_ATTACHING_CONNECTOR_NAME : SHMEM_ATTACHING_CONNECTOR_NAME); + + if (connector == null) { + throw new CantRunException("Cannot connect using " + + (myConnection.isUseSockets() ? "socket" : "shared memory") + + " transport: required connector not found. Check your JDK installation."); + } + myArguments = connector.defaultArguments(); + Connector.Argument argument; + if (myConnection.isUseSockets()) { + argument = (Connector.Argument)myArguments.get("hostname"); + if (argument != null && myConnection.getHostName() != null) { + argument.setValue(myConnection.getHostName()); + } + if (address == null) { + throw new CantRunException("The port to attach to unspecified"); + } + argument = (Connector.Argument)myArguments.get("port"); + if (argument != null) { + argument.setValue(address); + } + } + else { + if (address == null) { + throw new CantRunException("Shared memory address unspecified"); + } + argument = (Connector.Argument)myArguments.get("name"); + if (argument != null) { + argument.setValue(address); + } + } + myDebugProcessDispatcher.getMulticaster().connectorIsReady(); + try { + if(SOCKET_ATTACHING_CONNECTOR_NAME.equals(connector.name()) && Patches.SUN_BUG_338675) { + String portString = myConnection.getAddress(); + String hostString = myConnection.getHostName(); + + if (hostString == null || hostString.length() == 0) { + hostString = "localhost"; + } + hostString = hostString + ":"; + + myConnectionService = ((TransportService) connector.transport()).attach(hostString + portString); + return ((VirtualMachineManagerService) Bootstrap.virtualMachineManager()).createVirtualMachine(myConnectionService); + } + else { + return connector.attach(myArguments); + } + } + catch (IllegalArgumentException e) { + throw new CantRunException("Connector myArguments invalid : " + e.getMessage()); + } + } + } + catch (IOException e) { + throw new ExecutionException(createConnectionStatusMessage(processError(e), myConnection), e); + } + catch (IllegalConnectorArgumentsException e) { + throw new ExecutionException(createConnectionStatusMessage(processError(e), myConnection), e); + } + finally { + myArguments = null; + myConnectionService = null; + } + } + + private void pushStatisText(String text) { + if (myStatusText == null) { + myStatusText = ((StatusBarEx)WindowManager.getInstance().getStatusBar(getProject())).getInfo(); + } + + myStatusStack.addLast(myStatusText); + showStatusText(text); + } + + private void popStatisText() { + if (!myStatusStack.isEmpty()) { + showStatusText(myStatusStack.removeFirst()); + } + } + + public void showStatusText(final String text) { + myStatusText = text; + DebuggerSmoothManager.getInstanceEx().action("DebugProcessImpl.showStatusText", new Runnable() { + public void run() { + if (ProjectManagerEx.getInstanceEx().isProjectOpened(getProject())) { + WindowManager.getInstance().getStatusBar(getProject()).setInfo(text); + myStatusText = null; + } + } + }); + } + + private static Connector findConnector(String connectorName) throws ExecutionException { + VirtualMachineManager virtualMachineManager = null; + try { + virtualMachineManager = Bootstrap.virtualMachineManager(); + } + catch (Error e) { + throw new ExecutionException(e.getClass().getName() + " : " + e.getMessage() + ". Check your JDK installation."); + } + List connectors; + if (SOCKET_ATTACHING_CONNECTOR_NAME.equals(connectorName) || SHMEM_ATTACHING_CONNECTOR_NAME.equals(connectorName)) { + connectors = virtualMachineManager.attachingConnectors(); + } + else if (SOCKET_LISTENING_CONNECTOR_NAME.equals(connectorName) || SHMEM_LISTENING_CONNECTOR_NAME.equals(connectorName)) { + connectors = virtualMachineManager.listeningConnectors(); + } + else { + return null; + } + for (Iterator it = connectors.iterator(); it.hasNext();) { + Connector connector = (Connector)it.next(); + if (connectorName.equals(connector.name())) { + return connector; + } + } + return null; + } + + private void checkVirtualMachineVersion(VirtualMachine vm) { + final String version = vm.version(); + if ("1.4.0".equals(version)) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(getProject(), + "The debuggee VM version is \"" + version + + "\".\nJ2SDK 1.4.0 documented bugs may cause unstable debugger behavior.\nWe recommend you using J2SDK 1.4.0_01 or higher.", + "VM Version Warning", + Messages.getWarningIcon()); + } + }); + } + } + + /*Event dispatching*/ + public void addEvaluationListener(EvaluationListener evaluationListener) { + myEvaluationDispatcher.addListener(evaluationListener); + } + + public void removeEvaluationListener(EvaluationListener evaluationListener) { + myEvaluationDispatcher.removeListener(evaluationListener); + } + + public void addDebugProcessListener(DebugProcessListener listener) { + myDebugProcessDispatcher.addListener(listener); + } + + public void removeDebugProcessListener(DebugProcessListener listener) { + myDebugProcessDispatcher.removeListener(listener); + } + + public void addProcessListener(ProcessListener processListener) { + synchronized(myProcessListeners) { + if(getExecutionResult() != null) { + getExecutionResult().getProcessHandler().addProcessListener(processListener); + } + else { + myProcessListeners.add(processListener); + } + } + } + + public void removeProcessListener(ProcessListener processListener) { + synchronized (myProcessListeners) { + if(getExecutionResult() != null) { + getExecutionResult().getProcessHandler().removeProcessListener(processListener); + } + else { + myProcessListeners.remove(processListener); + } + } + } + + /* getters */ + public RemoteConnection getConnection() { + return myConnection; + } + + public ExecutionResult getExecutionResult() { + return myExecution; + } + + public T getUserData(Key key) { + return (T)myUserData.get(key); + } + + public void putUserData(Key key, T value) { + myUserData.put(key, value); + } + + public Project getProject() { + return myProject; + } + + public boolean canRedefineClasses() { + return myCanRedefineClasses; + } + + public boolean canWatchFieldModification() { + return myCanWatchFieldModification; + } + + public boolean isAttached() { + return myState == STATE_ATTACHED; + } + + public boolean isDetached() { + return myState == STATE_DETACHED; + } + + public boolean isDetaching() { + return myState == STATE_DETACHING; + } + + protected void setIsAttached() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myState = STATE_ATTACHED; + } + + protected void setIsDetaching() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myState = STATE_DETACHING; + } + + protected void setIsDetached() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myState = STATE_DETACHED; + } + + public RequestManagerImpl getRequestsManager() { + return myRequestManager; + } + + public VirtualMachineProxyImpl getVirtualMachineProxy() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if (myVirtualMachineProxy == null) throw new VMDisconnectedException(); + return myVirtualMachineProxy; + } + + public void appendPositionManager(final PositionManager positionManager) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myPositionManager.appendPositionManager(positionManager); + DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().updateBreakpoints(this); + } + + private LineBreakpoint myRunToCursorBreakpoint; + + public void cancelRunToCursorBreakpoint() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if (myRunToCursorBreakpoint != null) { + getRequestsManager().deleteRequest(myRunToCursorBreakpoint); + myRunToCursorBreakpoint.delete(); + myRunToCursorBreakpoint = null; + } + } + + protected void closeProcess(boolean fireDetached) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + + if (isDetached() || isDetaching()) return; + + setIsDetaching(); + myVirtualMachineProxy = null; + myPositionManager = null; + + DebugProcessImpl.this.getManagerThread().close(); + + setIsDetached(); + if(fireDetached) { + myDebugProcessDispatcher.getMulticaster().processDetached(DebugProcessImpl.this); + } + myWaitFor.up(); + } + + private static String formatMessage(String message) { + final int lineLength = 90; + StringBuffer buf = new StringBuffer(message.length()); + int index = 0; + while (index < message.length()) { + buf.append(message.substring(index, Math.min(index + lineLength, message.length()))).append('\n'); + index += lineLength; + } + return buf.toString(); + } + + public static String processError(Exception e) { + String message; + + if (e instanceof VMStartException) { + VMStartException e1 = (VMStartException)e; + message = e1.getMessage(); + } + else if (e instanceof IllegalConnectorArgumentsException) { + IllegalConnectorArgumentsException e1 = (IllegalConnectorArgumentsException)e; + message = formatMessage("Bad Argument : " + e1.getMessage()) + e1.argumentNames(); + if (LOG.isDebugEnabled()) { + LOG.debug(e1); + } + } + else if (e instanceof CantRunException) { + message = "Error Launching Debuggee.\n" + ((CantRunException)e).getMessage(); + } + else if (e instanceof VMDisconnectedException) { + message = "VM Disconnected.\n" + "Target virtual machine closed connection."; + } + else if (e instanceof UnknownHostException) { + message = "Cannot Connect to Remote Process.\n" + + "Host unknown: " + ((UnknownHostException)e).getMessage(); + } + else if (e instanceof IOException) { + IOException e1 = (IOException)e; + StringBuffer buf = new StringBuffer("Unable to open debugger port : "); + buf.append(e1.getClass().getName() + " "); + if (e1.getMessage() != null && e1.getMessage().length() > 0) { + buf.append('"'); + buf.append(e1.getMessage()); + buf.append('"'); + } + if (LOG.isDebugEnabled()) { + LOG.debug(e1); + } + message = buf.toString(); + } + else if (e instanceof ExecutionException) { + message = ((ExecutionException)e).getMessage(); + } + else { + Exception e1 = (Exception)e; + message = "Error Connecting to Remote Process.\n" + + "Exception occured: " + e1.getClass().getName() + "\n" + + "Exception message: " + e1.getMessage(); + if (LOG.isDebugEnabled()) { + LOG.debug(e1); + } + } + return message; + } + + public NodeRendererManagerImpl getNodeRendererManager() { + return myNodeRendererManager; + } + + public DescriptorHistoryManager getDescriptorHistoryManager() { + return myDescriptorHistoryManager; + } + + public static String createConnectionStatusMessage(String connectStatus, RemoteConnection connection) { + StringBuffer message = new StringBuffer(128); + message.append(connectStatus); + if (connection.isUseSockets()) { + message.append(" at '"); + message.append(connection.getHostName()); + message.append(':'); + message.append(connection.getAddress()); + message.append("' using socket transport"); + } + else { + message.append(" at address '"); + message.append(connection.getAddress()); + message.append("' using shared memory transport"); + } + message.append(". "); + String _msg = message.toString(); + return _msg; + } + + public void dispose() { + LOG.assertTrue(!isAttached()); + myNodeRendererManager.dispose(); + myDescriptorHistoryManager.dispose(); + } + + public DebuggerManagerThreadImpl getManagerThread() { + synchronized (this) { + if (myDebuggerManagerThread == null) { + myDebuggerManagerThread = new DebuggerManagerThreadImpl(); + } + return myDebuggerManagerThread; + } + } + + private static int getInvokePolicy(SuspendContext suspendContext) { + return suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD ? ThreadReference.INVOKE_SINGLE_THREADED : 0; + } + + public void waitFor() { + LOG.assertTrue(!DebuggerManagerThreadImpl.isManagerThread()); + myWaitFor.waitFor(); + } + + private abstract class InvokeCommand { + protected abstract E invokeMethod(int invokePolicy) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException; + + public E start(EvaluationContextImpl evaluationContext, Method method) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + SuspendContextImpl suspendContext = evaluationContext.getSuspendContext(); + SuspendManagerUtil.assertSuspendContext(suspendContext); + + myEvaluationDispatcher.getMulticaster().evaluationStarted(suspendContext); + + beforeMethodInvocation(suspendContext, method); + ThreadReferenceProxyImpl invokeThread = suspendContext.getThread(); + + if (SuspendManagerUtil.isEvaluating(getSuspendManager(), invokeThread)) { + throw EvaluateExceptionUtil.NESTED_EVALUATION_ERROR; + } + + Set suspendingContexts = SuspendManagerUtil.getSuspendingContexts(getSuspendManager(), invokeThread); + for (Iterator iterator = suspendingContexts.iterator(); iterator.hasNext();) { + SuspendContextImpl suspendingContext = iterator.next(); + if (suspendingContext.getThread() != invokeThread) { + if (LOG.isDebugEnabled()) { + LOG.debug("Resuming " + invokeThread + "that is paused by " + suspendingContext.getThread()); + } + LOG.assertTrue(!suspendingContext.getThread().getThreadReference().equals(invokeThread.getThreadReference())); + getSuspendManager().resumeThread(suspendingContext, invokeThread); + } + } + + Object resumeData = SuspendManagerUtil.prepareForResume(suspendContext); + suspendContext.setIsEvaluating(evaluationContext); + + getVirtualMachineProxy().clearCaches(); + + try { + for (; ;) { + try { + return invokeMethodAndFork(suspendContext); + } + catch (ClassNotLoadedException e) { + ReferenceType loadedClass = loadClass(evaluationContext, e.className(), evaluationContext.getClassLoader()); + if (loadedClass == null) throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + } + catch (ClassNotLoadedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (InvocationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (InvalidTypeException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ObjectCollectedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + finally { + suspendContext.setIsEvaluating(null); + SuspendManagerUtil.restoreAfterResume(suspendContext, resumeData); + for (Iterator iterator = getSuspendManager().getEventContexts().iterator(); iterator.hasNext();) { + SuspendContextImpl suspendingContext = iterator.next(); + if (suspendingContexts.contains(suspendingContext) && !suspendingContext.isEvaluating() && !suspendingContext.suspends(invokeThread)) { + getSuspendManager().suspendThread(suspendingContext, invokeThread); + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("getVirtualMachine().clearCaches()"); + } + getVirtualMachineProxy().clearCaches(); + afterMethodInvocation(suspendContext); + + myEvaluationDispatcher.getMulticaster().evaluationFinished(suspendContext); + } + } + + private E invokeMethodAndFork(final SuspendContextImpl context) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException { + final int invokePolicy = getInvokePolicy(context); + final Exception[] exception = new Exception[1]; + final Value[] result = new Value[1]; + DebugProcessImpl.this.getManagerThread().startLongProcessAndFork(new Runnable() { + public void run() { + ThreadReferenceProxyImpl thread = context.getThread(); + try { + if (LOG.isDebugEnabled()) { + getVirtualMachineProxy().logThreads(); + LOG.debug("Invoke in " + thread.name()); + LOG.assertTrue(thread.isSuspended(), thread.toString()); + LOG.assertTrue(context.isEvaluating()); + } + result[0] = invokeMethod(invokePolicy); + if(result[0] instanceof ObjectReference) { + context.keep(((ObjectReference)result[0])); + } + } + catch (Exception e) { + exception[0] = e; + } + finally{ + LOG.assertTrue(thread.isSuspended(), thread.toString()); + LOG.assertTrue(context.isEvaluating()); + } + } + }); + + if (exception[0] != null) { + if (exception[0] instanceof InvocationException) { + throw (InvocationException)exception[0]; + } + else if (exception[0] instanceof ClassNotLoadedException) { + throw (ClassNotLoadedException)exception[0]; + } + else if (exception[0] instanceof IncompatibleThreadStateException) { + throw (IncompatibleThreadStateException)exception[0]; + } + else if (exception[0] instanceof InvalidTypeException) { + throw (InvalidTypeException)exception[0]; + } + else if (exception[0] instanceof RuntimeException) { + throw (RuntimeException)exception[0]; + } + else { + LOG.assertTrue(false); + } + } + + return (E)result[0]; + } + } + + public Value invokeMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, + final Method method, + final List args) throws EvaluateException { + + final ThreadReference thread = getEvaluationThread(evaluationContext); + InvokeCommand invokeCommand = new InvokeCommand() { + protected Value invokeMethod(int invokePolicy) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException { + if (LOG.isDebugEnabled()) { + LOG.debug("Invoke " + method.name()); + } + return objRef.invokeMethod(thread, method, args, invokePolicy); + } + }; + return invokeCommand.start((EvaluationContextImpl)evaluationContext, method); + } + + private ThreadReference getEvaluationThread(final EvaluationContext evaluationContext) throws EvaluateException { + ThreadReferenceProxy evaluationThread = evaluationContext.getSuspendContext().getThread(); + if(evaluationThread == null) throw EvaluateExceptionUtil.NULL_STACK_FRAME; + return evaluationThread.getThreadReference(); + } + + public Value invokeMethod(final EvaluationContext evaluationContext, final ClassType classType, + final Method method, + final List args) throws EvaluateException { + + final ThreadReference thread = getEvaluationThread(evaluationContext); + InvokeCommand invokeCommand = new InvokeCommand() { + protected Value invokeMethod(int invokePolicy) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException { + if (LOG.isDebugEnabled()) { + LOG.debug("Invoke " + method.name()); + } + return classType.invokeMethod(thread, method, args, invokePolicy); + } + }; + return invokeCommand.start((EvaluationContextImpl)evaluationContext, method); + } + + public ArrayReference newInstance(final ArrayType arrayType, + final int dimension) + throws EvaluateException { + return arrayType.newInstance(dimension); + } + + public ObjectReference newInstance(final EvaluationContext evaluationContext, final ClassType classType, + final Method method, + final List args) throws EvaluateException { + final ThreadReference thread = getEvaluationThread(evaluationContext); + InvokeCommand invokeCommand = new InvokeCommand() { + protected ObjectReference invokeMethod(int invokePolicy) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException { + if (LOG.isDebugEnabled()) { + LOG.debug("New instance " + method.name()); + } + return classType.newInstance(thread, method, args, invokePolicy); + } + }; + return invokeCommand.start((EvaluationContextImpl)evaluationContext, method); + } + + public void clearCashes(int suspendPolicy) { + if (!isAttached()) return; + switch (suspendPolicy) { + case EventRequest.SUSPEND_ALL: + getVirtualMachineProxy().clearCaches(); + break; + case EventRequest.SUSPEND_EVENT_THREAD: + getVirtualMachineProxy().clearCaches(); + //suspendContext.getThread().clearAll(); + break; + } + } + + protected void beforeSuspend(SuspendContextImpl suspendContext) { + clearCashes(suspendContext.getSuspendPolicy()); + } + + private void beforeMethodInvocation(SuspendContextImpl suspendContext, Method method) { + if (LOG.isDebugEnabled()) { + LOG.debug( + "before invocation in thread " + suspendContext.getThread().name() + " method " + (method == null ? "null" : method.name())); + } + + if (method != null) { + pushStatisText("Evaluating " + DebuggerUtilsEx.methodName(method)); + } + else { + pushStatisText("Evaluating ..."); + } + } + + private void afterMethodInvocation(SuspendContextImpl suspendContext) { + if (LOG.isDebugEnabled()) { + LOG.debug("after invocation in thread " + suspendContext.getThread().name()); + } + popStatisText(); + } + + public ReferenceType findClass(EvaluationContext evaluationContext, String className, + ClassLoaderReference classLoader) throws EvaluateException { + try { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ReferenceType result = null; + final VirtualMachineProxyImpl vmProxy = getVirtualMachineProxy(); + if (vmProxy == null) { + throw new VMDisconnectedException(); + } + List list = vmProxy.classesByName(className); + for (Iterator it = list.iterator(); it.hasNext();) { + ReferenceType refType = (ReferenceType)it.next(); + if (refType.isPrepared() && Comparing.equal(refType.classLoader(), classLoader)) { + result = refType; + break; + } + } + if (result == null) { + return loadClass((EvaluationContextImpl)evaluationContext, className, classLoader); + } + else { + return result; + } + } + catch (InvocationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ClassNotLoadedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (InvalidTypeException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + private String reformatArrayName(String className) { + if (className.indexOf('[') == -1) return className; + + int dims = 0; + while (className.endsWith("[]")) { + className = className.substring(0, className.length() - 2); + dims++; + } + + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < dims; i++) { + buffer.append('['); + } + String primitiveSignature = JVMNameUtil.getPrimitiveSignature(className); + if(primitiveSignature != null) { + buffer.append(primitiveSignature); + } + else { + buffer.append('L'); + buffer.append(className); + buffer.append(';'); + } + return buffer.toString(); + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String qName, + ClassLoaderReference classLoader) throws InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + qName = reformatArrayName(qName); + ReferenceType refType = null; + VirtualMachine virtualMachine = getVirtualMachineProxy().getVirtualMachine(); + final List classClasses = virtualMachine.classesByName("java.lang.Class"); + if (classClasses.size() > 0) { + ClassType classClassType = (ClassType)classClasses.get(0); + final Method forNameMethod; + if (classLoader != null) { + forNameMethod = classClassType.concreteMethodByName("forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); + } + else { + forNameMethod = classClassType.concreteMethodByName("forName", "(Ljava/lang/String;)Ljava/lang/Class;"); + } + final List args = new ArrayList(); // do not use unmodifiable lists because the list is modified by JPDA + final StringReference qNameMirror = virtualMachine.mirrorOf(qName); + qNameMirror.disableCollection(); + args.add(qNameMirror); + if (classLoader != null) { + args.add(virtualMachine.mirrorOf(true)); + args.add(classLoader); + } + try { + final Value value = invokeMethod(evaluationContext, classClassType, forNameMethod, args); + if (value instanceof ClassObjectReference) { + refType = ((ClassObjectReference)value).reflectedType(); + } + } + finally { + qNameMirror.enableCollection(); + } + } + return refType; + } + + public int getSuspendPolicy() { + return mySuspendPolicy; + } + + public void setSuspendPolicy(boolean suspendAll) { + mySuspendPolicy = suspendAll ? EventRequest.SUSPEND_ALL : EventRequest.SUSPEND_EVENT_THREAD; + DebuggerSettings.getInstance().setSuspendPolicy(suspendAll); + } + + public void setSuspendPolicy(int policy) { + mySuspendPolicy = policy; + DebuggerSettings.getInstance().setSuspendPolicy(policy == EventRequest.SUSPEND_ALL); + } + + public void logThreads() { + if (LOG.isDebugEnabled()) { + try { + Collection allThreads = getVirtualMachineProxy().allThreads(); + for (Iterator iterator = allThreads.iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl threadReferenceProxy = iterator.next(); + LOG.debug("Thread name=" + threadReferenceProxy.name() + " suspendCount()=" + threadReferenceProxy.suspendCount()); + } + } + catch (Exception e) { + LOG.debug(e); + } + } + } + + public SuspendManager getSuspendManager() { + return mySuspendManager; + } + + public CompoundPositionManager getPositionManager() { + return myPositionManager; + } + //ManagerCommands + + public void stop(boolean forceTerminate) { + this.getManagerThread().terminateAndInvoke(createStopCommand(forceTerminate), DebuggerManagerThreadImpl.COMMAND_TIMEOUT); + } + + public StopCommand createStopCommand(boolean forceTerminate) { + return new StopCommand(forceTerminate); + } + + protected class StopCommand extends DebuggerCommandImpl { + private final boolean myIsTerminateTargetVM; + + public StopCommand(boolean isTerminateTargetVM) { + myIsTerminateTargetVM = isTerminateTargetVM; + } + + protected void action() throws Exception { + if (isAttached()) { + if (myIsTerminateTargetVM) { + getVirtualMachineProxy().exit(-1); + } + else { + getVirtualMachineProxy().dispose(); + } + } + else { + stopConnecting(); + } + } + } + + private class StepOutCommand extends ResumeCommand { + public StepOutCommand(SuspendContextImpl suspendContext) { + super(suspendContext); + } + + public void contextAction() { + showStatusText("Stepping out"); + if (doStep(getSuspendContext(), StepRequest.STEP_OUT, null)) { + super.contextAction(); + } + } + } + + private class StepIntoCommand extends ResumeCommand { + private final boolean myIgnoreFilters; + + public StepIntoCommand(SuspendContextImpl suspendContext, boolean ignoreFilters) { + super(suspendContext); + myIgnoreFilters = ignoreFilters; + } + + public void contextAction() { + showStatusText("Stepping into"); + RequestHint hint = new RequestHint(getSuspendContext(), StepRequest.STEP_INTO); + hint.setIgnoreFilters(myIgnoreFilters); + if (doStep(getSuspendContext(), StepRequest.STEP_INTO, hint)) { + super.contextAction(); + } + } + } + + private class StepOverCommand extends ResumeCommand { + private boolean myIsIgnoreBreakpoints; + + public StepOverCommand(SuspendContextImpl suspendContext, boolean ignoreBreakpoints) { + super(suspendContext); + myIsIgnoreBreakpoints = ignoreBreakpoints; + } + + public void contextAction() { + showStatusText("Stepping over"); + RequestHint hint = new RequestHint(getSuspendContext(), StepRequest.STEP_OVER); + hint.setRestoreBreakpoints(myIsIgnoreBreakpoints); + + if (doStep(getSuspendContext(), StepRequest.STEP_OVER, hint)) { + if (myIsIgnoreBreakpoints) { + DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().disableBreakpoints(DebugProcessImpl.this); + } + super.contextAction(); + } + } + } + + private class RunToCursorCommand extends ResumeCommand { + private final LineBreakpoint myRunToCursorBreakpoint; + + private RunToCursorCommand(SuspendContextImpl suspendContext, Document document, int lineIndex) { + super(suspendContext); + myRunToCursorBreakpoint = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addRunToCursorBreakpoint(document, lineIndex); + } + + public void contextAction() { + showStatusText("Run to cursor"); + cancelRunToCursorBreakpoint(); + if (myRunToCursorBreakpoint == null) { + return; + } + myRunToCursorBreakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + myRunToCursorBreakpoint.LOG_ENABLED = false; + getRequestsManager().createRequest(myRunToCursorBreakpoint); + DebugProcessImpl.this.myRunToCursorBreakpoint = myRunToCursorBreakpoint; + super.contextAction(); + } + } + + private class ResumeCommand extends SuspendContextCommandImpl { + + public ResumeCommand(SuspendContextImpl suspendContext) { + super(suspendContext); + } + + public void contextAction() { + showStatusText("Process resumed"); + getSuspendManager().resume(getSuspendContext()); + myDebugProcessDispatcher.getMulticaster().resumed(getSuspendContext()); + } + } + + private class PauseCommand extends DebuggerCommandImpl { + public PauseCommand() { + } + + public void action() { + if (!isAttached()) return; + logThreads(); + getVirtualMachineProxy().suspend(); + logThreads(); + SuspendContextImpl suspendContext = getSuspendManager().pushSuspendContext(EventRequest.SUSPEND_ALL, 0); + + myDebugProcessDispatcher.getMulticaster().paused(suspendContext); + } + } + + private class ResumeThreadCommand extends SuspendContextCommandImpl { + private final ThreadReferenceProxyImpl myThread; + + public ResumeThreadCommand(SuspendContextImpl suspendContext, ThreadReferenceProxyImpl thread) { + super(suspendContext); + myThread = thread; + } + + public void contextAction() { + if (getSuspendManager().isFrozen(myThread)) { + getSuspendManager().unfreezeThread(myThread); + } + + if (getSuspendContext().getThread() == myThread) { + DebugProcessImpl.this.getManagerThread().invoke(createResumeCommand(getSuspendContext())); + } + else { + Set suspendingContexts = SuspendManagerUtil.getSuspendingContexts(getSuspendManager(), myThread); + for (Iterator iterator = suspendingContexts.iterator(); iterator.hasNext();) { + SuspendContextImpl suspendContext = iterator.next(); + getSuspendManager().resumeThread(suspendContext, myThread); + } + } + } + } + + private class FreezeThreadCommand extends DebuggerCommandImpl { + private final ThreadReferenceProxyImpl myThread; + + public FreezeThreadCommand(ThreadReferenceProxyImpl thread) { + myThread = thread; + } + + protected void action() throws Exception { + SuspendManager suspendManager = getSuspendManager(); + if (!suspendManager.isFrozen(myThread)) { + suspendManager.freezeThread(myThread); + } + } + } + + private class PopFrameCommand extends DebuggerContextCommandImpl { + private final StackFrameProxyImpl myStackFrame; + + public PopFrameCommand(DebuggerContextImpl context, StackFrameProxyImpl frameProxy) { + super(context); + myStackFrame = frameProxy; + } + + public void threadAction() { + ThreadReferenceProxyImpl thread = myStackFrame.threadProxy(); + + if (myStackFrame.isBottom()) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + Messages.showMessageDialog(myProject, "Cannot pop bottom frame", "Action not Perfomed", Messages.getErrorIcon()); + } + }); + return; + } + + try { + thread.popFrames(myStackFrame); + } + catch (EvaluateException e) { + LOG.error(e); + } + getSuspendManager().popFrame(getSuspendContext()); + } + } + + + public ExecutionResult attachVirtualMachine(final RunProfileState state, final RemoteConnection remoteConnection, boolean pollConnection) + throws ExecutionException { + myWaitFor.down(); + + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(myState == STATE_INITIAL); + + myConnection = remoteConnection; + + createVirtualMachine(pollConnection); + + try { + synchronized (myProcessListeners) { + myExecution = state.execute(); + + for (Iterator iterator = myProcessListeners.iterator(); iterator.hasNext();) { + ProcessListener processListener = iterator.next(); + myExecution.getProcessHandler().addProcessListener(processListener); + } + myProcessListeners.clear(); + } + } + catch (ExecutionException e) { + stop(false); + throw e; + } + + if (ApplicationManager.getApplication().isUnitTestMode()) { + return myExecution; + } + + final Alarm debugPortTimeout = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + + myExecution.getProcessHandler().addProcessListener(new ProcessAdapter() { + public void processTerminated(ProcessEvent event) { + debugPortTimeout.cancelAllRequests(); + } + + public void startNotified(ProcessEvent event) { + debugPortTimeout.addRequest(new Runnable() { + public void run() { + if(myState == STATE_INITIAL) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + String message = createConnectionStatusMessage( + "Check your run/debug configuration. Failed to establish connection to the target VM", + remoteConnection + ); + Messages.showErrorDialog(myProject, message, "Cannot Debug Application"); + } + }); + } + } + }, LOCAL_START_TIMEOUT); + } + }); + + return myExecution; + } + + private void createVirtualMachine(final boolean pollConnection) throws ExecutionException { + final Semaphore semaphore = new Semaphore(); + final ExecutionException[] exception = new ExecutionException[1]; + + myDebugProcessDispatcher.addListener(new DebugProcessAdapter() { + public void connectorIsReady() { + semaphore.up(); + myDebugProcessDispatcher.removeListener(this); + } + }); + + final long time = System.currentTimeMillis(); + + this.getManagerThread().invokeLater(new DebuggerCommandImpl() { + protected void action() { + VirtualMachine vm = null; + + try { + while (System.currentTimeMillis() - time < LOCAL_START_TIMEOUT) { + try { + vm = createVirtualMachineInt(); + break; + } + catch (ExecutionException e) { + if (pollConnection && !myConnection.isServerMode() && e.getCause() instanceof IOException) { + synchronized (this) { + try { + wait(500); + } + catch (InterruptedException ie) { + break; + } + } + } + else { + exception[0] = e; + break; + } + } + } + } + finally { + semaphore.up(); + } + + if(vm != null) { + final VirtualMachine vm1 = vm; + afterProcessStarted(new Runnable() { + public void run() { + getManagerThread().invokeLater(new DebuggerCommandImpl() { + protected void action() throws Exception { + commitVM(vm1); + } + }); + } + }); + } + } + }); + + semaphore.down(); + semaphore.waitFor(); + + if (exception[0] != null) throw exception[0]; + } + + private void afterProcessStarted(final Runnable run) { + class MyProcessAdapter extends ProcessAdapter { + private boolean alreadyRun = false; + + public synchronized void run() { + if(!alreadyRun) { + alreadyRun = true; + run.run(); + } + removeProcessListener(this); + } + + public void startNotified(ProcessEvent event) { + run(); + } + } + MyProcessAdapter processListener = new MyProcessAdapter(); + addProcessListener(processListener); + if(myExecution != null) { + if(myExecution.getProcessHandler().isStartNotified()) { + processListener.run(); + } + } + } + + public DebuggerCommandImpl createPauseCommand() { + return new PauseCommand(); + } + + public SuspendContextCommandImpl createResumeCommand(SuspendContextImpl suspendContext) { + return new ResumeCommand(suspendContext); + } + + public SuspendContextCommandImpl createStepOverCommand(SuspendContextImpl suspendContext, boolean ignoreBreakpoints) { + return new StepOverCommand(suspendContext, ignoreBreakpoints); + } + + public SuspendContextCommandImpl createStepOutCommand(SuspendContextImpl suspendContext) { + return new StepOutCommand(suspendContext); + } + + public SuspendContextCommandImpl createStepIntoCommand(SuspendContextImpl suspendContext, boolean ignoreFilters) { + return new StepIntoCommand(suspendContext, ignoreFilters); + } + + public SuspendContextCommandImpl createRunToCursorCommand(SuspendContextImpl suspendContext, Document document, int lineIndex) + throws EvaluateException { + RunToCursorCommand runToCursorCommand = new RunToCursorCommand(suspendContext, document, lineIndex); + if(runToCursorCommand.myRunToCursorBreakpoint == null) { + PsiFile psiFile = PsiDocumentManager.getInstance(getProject()).getPsiFile(document); + throw new EvaluateException("There is no executable code at " + psiFile.getName() + ":" + lineIndex, null); + } + return runToCursorCommand; + } + + public DebuggerCommandImpl createFreezeThreadCommand(ThreadReferenceProxyImpl thread) { + return new FreezeThreadCommand(thread); + } + + public SuspendContextCommandImpl createResumeThreadCommand(SuspendContextImpl suspendContext, ThreadReferenceProxyImpl thread) { + return new ResumeThreadCommand(suspendContext, thread); + } + + public SuspendContextCommandImpl createPopFrameCommand(DebuggerContextImpl context, StackFrameProxyImpl stackFrame) { + return new PopFrameCommand(context, stackFrame); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java new file mode 100644 index 00000000000..4bfae3b84dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java @@ -0,0 +1,243 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.managerThread.DebuggerManagerThread; +import com.intellij.debugger.engine.managerThread.DebuggerCommand; +import com.intellij.debugger.engine.managerThread.SuspendContextCommand; +import com.intellij.debugger.impl.EventQueue; +import com.intellij.debugger.impl.InvokeAndWaitThread; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressIndicatorListenerAdapter; +import com.intellij.openapi.progress.util.ProgressWindowWithNotification; +import com.intellij.util.Alarm; +import com.sun.jdi.VMDisconnectedException; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 25, 2004 + * Time: 4:51:20 PM + * To change this template use File | Settings | File Templates. + */ +public class DebuggerManagerThreadImpl extends InvokeAndWaitThread implements DebuggerManagerThread { + public static final int HIGH_PRIORITY = 0; + public static final int NORMAL_PRIORITY = 1; + + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebuggerManagerThreadImpl"); + public static final int COMMAND_TIMEOUT = 3000; + + DebuggerManagerThreadImpl() { + super("DebuggerManagerThreadImpl", 2); + } + + public static DebuggerManagerThreadImpl createTestInstance() { + return new DebuggerManagerThreadImpl(); + } + + public static boolean isManagerThread() { + return currentThread() instanceof DebuggerManagerThreadImpl; + } + + public static void assertIsManagerThread() { + LOG.assertTrue(isManagerThread(), "Should be invoked in manager thread, use DebuggerManagerThreadImpl.getInstance(..).invoke..."); + } + + public void invokeAndWait(DebuggerCommandImpl managerCommand, int priority) { + LOG.assertTrue(!SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(!(currentThread() instanceof DebuggerManagerThreadImpl), + "Should be invoked outside manager thread, use DebuggerManagerThreadImpl.getInstance(..).invoke..."); + super.invokeAndWait(managerCommand, priority); //To change body of overridden methods use File | Settings | File Templates. + } + + public void invokeAndWait(DebuggerCommandImpl managerCommand) { + LOG.assertTrue(!SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(!(currentThread() instanceof DebuggerManagerThreadImpl), + "Should be invoked outside manager thread, use DebuggerManagerThreadImpl.getInstance(..).invoke..."); + invokeAndWait(managerCommand, NORMAL_PRIORITY); + } + + public void invoke(DebuggerCommandImpl managerCommand) { + invoke(managerCommand, NORMAL_PRIORITY); + } + + public void invoke(DebuggerCommandImpl managerCommand, int priority) { + if (currentThread() instanceof DebuggerManagerThreadImpl) { + processEvent(managerCommand); + } + else { + invokeLater(managerCommand, priority); + } + } + + public void invokeLater(DebuggerCommandImpl managerCommand, int priority) { + if(myEvents.isClosed()) { + managerCommand.notifyCancelled(); + } + else { + super.invokeLater(managerCommand, priority); + } + } + + public void invokeLater(DebuggerCommandImpl managerCommand) { + invokeLater(managerCommand, NORMAL_PRIORITY); + } + + /** + * waits COMMAND_TIMEOUT milliseconds + * if worker thread is still processing the same command + * calls terminateCommand + */ + + public void terminateAndInvoke(DebuggerCommandImpl command, int terminateTimeout) { + final DebuggerCommandImpl[] currentCommand = new DebuggerCommandImpl[1]; + + myEvents.getCurrentEvent(new EventQueue.EventGetter() { + public void event(DebuggerCommandImpl command) { + currentCommand[0] = command; + } + }); + + invoke(command, HIGH_PRIORITY); + final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + alarm.addRequest(new Runnable() { + public void run() { + if (currentCommand[0] != null) { + terminateCommand(currentCommand[0]); + } + } + }, terminateTimeout); + } + + /** + * interrupts command in old worker thread and closes old thread. + * then starts new worker thread + *

    + * Note: if old thread is working and InterruptedException is not thrown + * command will continue execution in old thread simulteniously with + * commands in new thread + *

    + * use very carefully! + */ + + public void terminateCommand(final DebuggerCommandImpl command) { + myEvents.getCurrentEvent(new EventQueue.EventGetter() { + public void event(DebuggerCommandImpl currentCommand) { + if (command == currentCommand) { + restartWorkerThread(); + } + } + }); + } + + public DebuggerCommandImpl getCurrentCommand() { + final DebuggerCommandImpl[] command = new DebuggerCommandImpl[1]; + + myEvents.getCurrentEvent(new EventQueue.EventGetter() { + public void event(DebuggerCommandImpl debuggerCommand) { + command[0] = debuggerCommand; + } + }); + + return command[0]; + } + + + public void processEvent(DebuggerCommandImpl managerCommand) { + assertIsManagerThread(); + LOG.assertTrue(managerCommand != null); + try { + if(myEvents.isClosed()) { + managerCommand.notifyCancelled(); + } + else { + managerCommand.run(); + } + } + catch (VMDisconnectedException e) { + LOG.debug(e); + } + catch (RuntimeException e) { + throw e; + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + catch (Exception e) { + LOG.error(e); + } + } + + public void startProgress(final DebuggerCommandImpl command, final ProgressWindowWithNotification progressWindow) { + progressWindow.addListener(new ProgressIndicatorListenerAdapter() { + public void cancelled() { + command.release(); + } + }); + + new Thread() { + public void run() { + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + invokeAndWait(command, HIGH_PRIORITY); + } + }, progressWindow); + } + }.start(); + } + + + public void startLongProcessAndFork(Runnable process) { + startNewWorkerThread(); + + try { + process.run(); + } + finally { + final WorkerThread thread = (WorkerThread)Thread.currentThread(); + + LOG.debug("Switching back to " + thread); + + super.invokeAndWait(new DebuggerCommandImpl() { + protected void action() throws Exception { + switchToThread(thread); + } + + protected void commandCancelled() { + LOG.debug("Event queue was closed, killing thread"); + thread.interrupt(); + } + }, NORMAL_PRIORITY); + } + } + + public void invokeCommand(final DebuggerCommand command) { + if(command instanceof SuspendContextCommand) { + SuspendContextCommand suspendContextCommand = ((SuspendContextCommand) command); + invokeLater(new SuspendContextCommandImpl((SuspendContextImpl)suspendContextCommand.getSuspendContext()) { + public void contextAction() throws Exception { + command.action(); + } + + protected void commandCancelled() { + command.commandCancelled(); + } + }); + } + else { + invokeLater(new DebuggerCommandImpl() { + protected void action() throws Exception { + command.action(); + } + + protected void commandCancelled() { + command.commandCancelled(); + } + }); + } + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMName.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMName.java new file mode 100644 index 00000000000..4945dff6b80 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMName.java @@ -0,0 +1,19 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 2, 2004 + * Time: 3:50:51 PM + * To change this template use File | Settings | File Templates. + */ +public interface JVMName { + String getName(DebugProcessImpl process) throws EvaluateException; + String getDisplayName(DebugProcessImpl debugProcess); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMNameUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMNameUtil.java new file mode 100644 index 00000000000..4be2e307d0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/JVMNameUtil.java @@ -0,0 +1,288 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.PrimitiveType; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Sep 2, 2003 + * Time: 11:25:59 AM + */ +public class JVMNameUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.JVMNameUtil"); + + public static String getPrimitiveSignature(String typeName) { + if(PsiType.BOOLEAN.getCanonicalText().equals(typeName)) { + return "Z"; + } + else if (PsiType.BYTE.getCanonicalText().equals(typeName)) { + return "B"; + } + else if (PsiType.CHAR.getCanonicalText().equals(typeName)) { + return "C"; + } + else if (PsiType.SHORT.getCanonicalText().equals(typeName)) { + return "S"; + } + else if (PsiType.INT.getCanonicalText().equals(typeName)) { + return "I"; + } + else if (PsiType.LONG.getCanonicalText().equals(typeName)) { + return "J"; + } + else if (PsiType.FLOAT.getCanonicalText().equals(typeName)) { + return "F"; + } + else if (PsiType.DOUBLE.getCanonicalText().equals(typeName)) { + return "D"; + } + else if (PsiType.VOID.getCanonicalText().equals(typeName)) { + return "V"; + } + return null; + } + + private static void appendJVMSignature(JVMNameBuffer buffer , PsiType type) + throws EvaluateException { + final PsiType psiType = TypeConversionUtil.erasure(type); + if (psiType instanceof PsiArrayType) { + buffer.append(new JVMRawText("[")); + appendJVMSignature(buffer, ((PsiArrayType) psiType).getComponentType()); + } + else if (psiType instanceof PsiClassType) { + buffer.append("L"); + + final JVMName jvmName = getJVMQualifiedName(psiType); + + if(jvmName instanceof JVMRawText) { + buffer.append(((JVMRawText)jvmName).getName().replace('.','/')); + } else { + buffer.append(new JVMName() { + public String getName(DebugProcessImpl process) throws EvaluateException { + return jvmName.getName(process).replace('.','/'); + } + + public String getDisplayName(DebugProcessImpl debugProcess) { + return jvmName.getDisplayName(debugProcess); + } + }); + } + buffer.append(";"); + } + else if (psiType instanceof PsiPrimitiveType) { + buffer.append(getPrimitiveSignature(psiType.getCanonicalText())); + } + else { + LOG.assertTrue(false, "unknown type " + type.getCanonicalText()); + } + } + + private static class JVMNameBuffer { + List myList = new ArrayList(); + + public void append(JVMName evaluator){ + LOG.assertTrue(evaluator != null); + myList.add(evaluator); + } + + public void append(char name){ + append(Character.toString(name)); + } + + public void append(String text){ + myList.add(getJVMRawText(text)); + } + + public JVMName toName() { + final List optimised = new ArrayList(); + for (Iterator iterator = myList.iterator(); iterator.hasNext();) { + JVMName evaluator = (JVMName) iterator.next(); + if(evaluator instanceof JVMRawText && optimised.size() > 0 && optimised.get(optimised.size() - 1) instanceof JVMRawText){ + JVMRawText nameEvaluator = (JVMRawText) optimised.get(optimised.size() - 1); + nameEvaluator.setName(nameEvaluator.getName() + ((JVMRawText)evaluator).getName()); + } else { + optimised.add(evaluator); + } + } + + if(optimised.size() == 1) return optimised.get(0); + if(optimised.size() == 0) return new JVMRawText(""); + + return new JVMName() { + String myName = null; + public String getName(DebugProcessImpl process) throws EvaluateException { + if(myName == null){ + String name = ""; + for (Iterator iterator = optimised.iterator(); iterator.hasNext();) { + JVMName nameEvaluator = (JVMName) iterator.next(); + name += nameEvaluator.getName(process); + } + myName = name; + } + return myName; + } + + public String getDisplayName(DebugProcessImpl debugProcess) { + if(myName == null) { + String displayName = ""; + for (Iterator iterator = optimised.iterator(); iterator.hasNext();) { + JVMName nameEvaluator = (JVMName) iterator.next(); + displayName += nameEvaluator.getDisplayName(debugProcess); + } + return displayName; + } + return myName; + } + }; + } + } + + private static class JVMRawText implements JVMName { + private String myText; + + public JVMRawText(String text) { + myText = text; + } + + public String getName(DebugProcessImpl process) throws EvaluateException { + return myText; + } + + public String getDisplayName(DebugProcessImpl debugProcess) { + return myText; + } + + public String getName() { + return myText; + } + + public void setName(String name) { + myText = name; + } + } + + private static class JVMClassAt implements JVMName { + private final SourcePosition mySourcePosition; + + public JVMClassAt(SourcePosition sourcePosition) { + mySourcePosition = sourcePosition; + } + + public String getName(DebugProcessImpl process) throws EvaluateException { + List allClasses = process.getPositionManager().getAllClasses(mySourcePosition); + if(allClasses.size() > 0) { + return allClasses.get(0).name(); + } + + throw EvaluateExceptionUtil.createEvaluateException("JVM class name is unknown - class is not prepared : " + getDisplayName(process)); + } + + public String getDisplayName(DebugProcessImpl debugProcess) { + return getClassDisplayName(debugProcess, mySourcePosition); + } + } + + public static JVMName getJVMRawText(String qualifiedName) { + return new JVMRawText(qualifiedName); + } + + public static JVMName getJVMQualifiedName(PsiType psiType) { + if(psiType instanceof PsiArrayType) { + JVMName jvmName = getJVMQualifiedName(((PsiArrayType)psiType).getComponentType()); + JVMNameBuffer buffer = new JVMNameBuffer(); + buffer.append(jvmName); + buffer.append("[]"); + return buffer.toName(); + } + + PsiClass psiClass = PsiUtil.resolveClassInType(psiType); + if (psiClass == null) { + return getJVMRawText(psiType.getCanonicalText()); + } else { + return getJVMQualifiedName(psiClass); + } + } + + public static JVMName getJVMQualifiedName(PsiClass psiClass) { + if(PsiUtil.isLocalOrAnonymousClass(psiClass)) { + return new JVMClassAt(SourcePosition.createFromElement(psiClass)); + } + else { + return getJVMRawText(getNonAnonymousClassName(psiClass)); + } + } + + public static String getNonAnonymousClassName(PsiClass aClass) { + PsiClass parentClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true); + if(parentClass != null) { + return getNonAnonymousClassName(parentClass) + "$" + aClass.getName(); + } + else { + return aClass.getQualifiedName(); + } + } + + public static JVMName getJVMSignature(PsiMethod method) throws EvaluateException { + JVMNameBuffer signature = new JVMNameBuffer(); + signature.append("("); + PsiParameterList paramList = method.getParameterList(); + if (paramList != null) { + PsiParameter[] params = paramList.getParameters(); + for (int idx = 0; idx < params.length; idx++) { + PsiParameter psiParameter = params[idx]; + appendJVMSignature(signature, psiParameter.getType()); + } + } + signature.append(")"); + if (!method.isConstructor()) { + appendJVMSignature(signature, method.getReturnType()); + } + else { + signature.append(new JVMRawText("V")); + } + return signature.toName(); + } + + public static PsiClass getClassAt(SourcePosition sourceOffset) { + PsiElement element = sourceOffset.getFile().findElementAt(sourceOffset.getOffset()); + PsiClass parentClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); + return parentClass; + } + + public static String getClassDisplayName(DebugProcessImpl debugProcess, SourcePosition classAt) { + PsiClass psiClass = getClassAt(classAt); + + if(psiClass != null && psiClass.getQualifiedName() != null) return psiClass.getQualifiedName(); + + if(debugProcess != null && debugProcess.isAttached()) { + List allClasses = debugProcess.getPositionManager().getAllClasses(classAt); + if(allClasses.size() > 0) { + return allClasses.get(0).name(); + } + } + return "Class at " + classAt.getFile().getName() + ":" + classAt.getLine(); + } + + public static PsiClass getTopLevelParentClass(PsiClass psiClass) { + PsiClass result = psiClass; + PsiClass parent = psiClass; + for(;parent!= null; parent = PsiTreeUtil.getParentOfType(parent, PsiClass.class, true)) { + result = parent; + } + return result; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/PositionManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/PositionManagerImpl.java new file mode 100644 index 00000000000..9bb5a023a79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/PositionManagerImpl.java @@ -0,0 +1,244 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.*; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.requests.ClassPrepareRequestor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.search.GlobalSearchScope; +import com.sun.jdi.AbsentInformationException; +import com.sun.jdi.Location; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.request.ClassPrepareRequest; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 2, 2004 + * Time: 8:33:41 PM + * To change this template use File | Settings | File Templates. + */ +public class PositionManagerImpl implements PositionManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.PositionManagerImpl"); + + private final DebugProcessImpl myDebugProcess; + + public PositionManagerImpl(DebugProcessImpl debugProcess) { + myDebugProcess = debugProcess; + } + + public DebugProcess getDebugProcess() { + return myDebugProcess; + } + + public List locationsOfLine(ReferenceType type, + SourcePosition position) { + try { + int line = position.getLine() + 1; + List locs = (List) (getDebugProcess().getVirtualMachineProxy().versionHigher("1.4") ? type.locationsOfLine(DebugProcessImpl.JAVA_STRATUM, null, line) : type.locationsOfLine(line)); + if (locs.size() > 0) { + return locs; + } + } + catch (AbsentInformationException e) { + } + + return new ArrayList(); + } + + public ClassPrepareRequest createPrepareRequest(final ClassPrepareRequestor requestor, final SourcePosition position) { + PsiClass psiClass = JVMNameUtil.getClassAt(position); + if(psiClass == null) { + return null; + } + + String waitPrepareFor; + ClassPrepareRequestor waitRequestor; + + if(PsiUtil.isLocalOrAnonymousClass(psiClass)) { + PsiClass parent = JVMNameUtil.getTopLevelParentClass(psiClass); + + if(parent == null) { + return null; + } + + waitPrepareFor = JVMNameUtil.getNonAnonymousClassName(parent) + "$*"; + + waitRequestor = new ClassPrepareRequestor() { + public void processClassPrepare(DebugProcess debuggerProcess, ReferenceType referenceType) { + if (((DebugProcessImpl)debuggerProcess).getPositionManager().locationsOfLine(referenceType, position).size() > 0) { + requestor.processClassPrepare(debuggerProcess, referenceType); + } + } + }; + } else { + waitPrepareFor = JVMNameUtil.getNonAnonymousClassName(psiClass); + waitRequestor = requestor; + } + return myDebugProcess.getRequestsManager().createClassPrepareRequest(waitRequestor, waitPrepareFor); + } + + public SourcePosition getSourcePosition(final Location location) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if(location == null) return null; + + PsiFile psiFile = getPsiFileByLocation(getDebugProcess().getProject(), location); + if(psiFile == null ) return null; + + int lineNumber = calcLineIndex(psiFile, location); + + return SourcePosition.createFromLine(psiFile, lineNumber); + } + + private int calcLineIndex(PsiFile psiFile, + Location location) { + LOG.assertTrue(myDebugProcess != null); + if (location == null) { + return -1; + } + + int lineNumber; + try { + lineNumber = location.lineNumber() - 1; + } + catch (InternalError e) { + lineNumber = -1; + } + + if (psiFile instanceof PsiCompiledElement || lineNumber < 0) { + final String signature = location.method().signature(); + final String name = location.method().name(); + if(location.declaringType() == null) return -1; + + final String className = location.declaringType().name(); + + if(name == null || signature == null) return -1; + + final PsiClass[] compiledClass = new PsiClass[1]; + final PsiMethod[] compiledMethod = new PsiMethod[1]; + + PsiRecursiveElementVisitor visitor = new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + expression.acceptChildren(this); + } + + public void visitClass(PsiClass aClass) { + List allClasses = myDebugProcess.getPositionManager().getAllClasses(SourcePosition.createFromElement(aClass)); + for (Iterator iterator = allClasses.iterator(); iterator.hasNext();) { + ReferenceType referenceType = iterator.next(); + if(referenceType.name().equals(className)) { + compiledClass[0] = aClass; + } + } + + aClass.acceptChildren(this); + } + + public void visitMethod(PsiMethod method) { + try { + String methodName = method.isConstructor() ? "" : method.getName(); + PsiClass containingClass = method.getContainingClass(); + + if(containingClass != null && containingClass.equals(compiledClass[0]) && name.equals(methodName) && JVMNameUtil.getJVMSignature(method).getName(myDebugProcess).equals(signature)) { + compiledMethod[0] = method; + } + } + catch (EvaluateException e) { + LOG.debug(e); + } + } + }; + psiFile.accept(visitor); + if(compiledMethod [0] != null) { + Document document = PsiDocumentManager.getInstance(myDebugProcess.getProject()).getDocument(psiFile); + if(document != null){ + return document.getLineNumber(compiledMethod[0].getTextOffset()); + } + } + return -1; + } + + return lineNumber; + } + + private static PsiFile getPsiFileByLocation(final Project project, + final Location location) { + if (location == null) { + return null; + } + final ReferenceType refType = location.declaringType(); + if (refType == null) { + return null; + } + + final String originalQName = refType.name(); + final PsiManager psiManager = PsiManager.getInstance(project); + int dollar = originalQName.indexOf('$'); + final String qName = dollar >= 0 ? originalQName.substring(0, dollar) : originalQName; + PsiClass psiClass = DebuggerUtils.findClass(qName, project); + if (psiClass == null) { + psiClass = psiManager.findClass(originalQName, GlobalSearchScope.allScope(project)); // try to lookup original name + } + + if (psiClass != null) { + psiClass = (PsiClass)psiClass.getNavigationElement(); + return psiClass.getContainingFile(); + } + + return null; + } + + public List getAllClasses(final SourcePosition classPosition) { + final PsiClass psiClass = JVMNameUtil.getClassAt(classPosition); + + if(psiClass == null) return (List)Collections.EMPTY_LIST; + + return ApplicationManager.getApplication().runReadAction(new Computable> () { + public List compute() { + if(PsiUtil.isLocalOrAnonymousClass(psiClass)) { + PsiClass parentNonLocal = JVMNameUtil.getTopLevelParentClass(psiClass); + if(parentNonLocal == null && psiClass != null) { + LOG.assertTrue(false, "Local class has no non-local parent"); + return (List)Collections.EMPTY_LIST; + } + String name = JVMNameUtil.getNonAnonymousClassName(parentNonLocal); + List outer = myDebugProcess.getVirtualMachineProxy().classesByName(name); + return findNested(outer, classPosition); + } else { + String name = JVMNameUtil.getNonAnonymousClassName(psiClass); + return myDebugProcess.getVirtualMachineProxy().classesByName(name); + } + } + }); + } + + private List findNested(List outer, SourcePosition classPosition) { + List result = new ArrayList(); + + for (Iterator iterator = outer.iterator(); iterator.hasNext();) { + ReferenceType referenceType = iterator.next(); + if(referenceType.isPrepared()) { + result.addAll(findNested((List)referenceType.nestedTypes(), classPosition)); + + try { + if(referenceType.locationsOfLine(classPosition.getLine() + 1).size() > 0) { + result.add(referenceType); + } + } + catch (AbsentInformationException e) { + } + } + } + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteDebugProcessHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteDebugProcessHandler.java new file mode 100644 index 00000000000..ef9cac9cb36 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteDebugProcessHandler.java @@ -0,0 +1,55 @@ +package com.intellij.debugger.engine; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.DebuggerManager; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.application.ModalityState; + +import java.io.OutputStream; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class RemoteDebugProcessHandler extends ProcessHandler{ + private final Project myProject; + + public RemoteDebugProcessHandler(Project project) { + myProject = project; + } + + public void startNotify() { + DebugProcess debugProcess = DebuggerManager.getInstance(myProject).getDebugProcess(this); + debugProcess.addDebugProcessListener(new DebugProcessAdapter() { + //executed in manager thread + public void processDetached(DebugProcess process) { + notifyProcessDetached(); + } + }); + super.startNotify(); + } + + protected void destroyProcessImpl() { + DebugProcess debugProcess = DebuggerManager.getInstance(myProject).getDebugProcess(this); + if(debugProcess != null) { + debugProcess.stop(true); + } + } + + protected void detachProcessImpl() { + DebugProcess debugProcess = DebuggerManager.getInstance(myProject).getDebugProcess(this); + if(debugProcess != null) { + debugProcess.stop(false); + } + } + + public boolean detachIsDefault() { + return true; + } + + public OutputStream getProcessInput() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteStateState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteStateState.java new file mode 100644 index 00000000000..7c5b996e5de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RemoteStateState.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.engine; + +import com.intellij.execution.DefaultExecutionResult; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RemoteState; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.impl.ConsoleViewImpl; +import com.intellij.execution.remote.RemoteConfiguration; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 29, 2004 + * Time: 6:27:18 PM + * To change this template use File | Settings | File Templates. + */ +public class RemoteStateState implements RemoteState { + private final Project myProject; + private final RemoteConnection myConnection; + private RunnerSettings myRunnerSettings; + private ConfigurationPerRunnerSettings myConfigurationSettings; + + public RemoteStateState(Project project, + RemoteConnection connection, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + myProject = project; + myConnection = connection; + myRunnerSettings = runnerSettings; + myConfigurationSettings = configurationSettings; + } + + public RunnerSettings getRunnerSettings() { + return myRunnerSettings; + } + + public ConfigurationPerRunnerSettings getConfigurationSettings() { + return myConfigurationSettings; + } + + public ExecutionResult execute() throws ExecutionException { + ConsoleViewImpl consoleView = new ConsoleViewImpl(myProject); + RemoteDebugProcessHandler process = new RemoteDebugProcessHandler(myProject); + consoleView.attachToProcess(process); + return new DefaultExecutionResult(consoleView, process, AnAction.EMPTY_ARRAY); + } + + public Module[] getModulesToCompile() { + return Module.EMPTY_ARRAY; + } + + public RemoteConnection getRemoteConnection() { + return myConnection; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RequestHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RequestHint.java new file mode 100644 index 00000000000..cf496e863dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/RequestHint.java @@ -0,0 +1,151 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jul 23, 2002 + * Time: 11:10:11 AM + */ +package com.intellij.debugger.engine; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.sun.jdi.Location; +import com.sun.jdi.Method; +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.request.StepRequest; + +class RequestHint { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.RequestHint"); + private final int myDepth; + private SourcePosition myPosition; + private int myFrameCount; + private VirtualMachineProxyImpl myVirtualMachineProxy; + + private boolean myIgnoreFilters = false; + private boolean myRestoreBreakpoints = false; + private boolean mySkipThisMethod = false; + + public RequestHint(final SuspendContextImpl suspendContext, int depth) { + final DebugProcessImpl debugProcess = suspendContext.getDebugProcess(); + myDepth = depth; + myVirtualMachineProxy = debugProcess.getVirtualMachineProxy(); + + try { + final ThreadReferenceProxyImpl thread = suspendContext.getThread(); + myFrameCount = thread.frameCount(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + myPosition = ContextUtil.getSourcePosition(suspendContext); + } + }); + } + catch (Exception e) { + myPosition = null; + } + } + + public void setIgnoreFilters(boolean ignoreFilters) { + myIgnoreFilters = ignoreFilters; + } + + public void setRestoreBreakpoints(boolean restoreBreakpoints) { + myRestoreBreakpoints = restoreBreakpoints; + } + + public boolean isRestoreBreakpoints() { + return myRestoreBreakpoints; + } + + public boolean isIgnoreFilters() { + return myIgnoreFilters; + } + + public int getDepth() { + return mySkipThisMethod ? StepRequest.STEP_OUT : myDepth; + } + + public boolean shouldSkipFrame(final SuspendContextImpl context) { + try { + if(mySkipThisMethod) { + mySkipThisMethod = false; + return true; + } + + if (myPosition != null) { + final SourcePosition locationPosition = ApplicationManager.getApplication().runReadAction(new Computable() { + public SourcePosition compute() { + return ContextUtil.getSourcePosition(context); + } + }); + + if(locationPosition == null) return true; + + int frameCount = -1; + if (context.getFrameProxy() != null) { + try { + frameCount = context.getFrameProxy().threadProxy().frameCount(); + } + catch (EvaluateException e) { + } + } + if (myPosition.getFile().equals(locationPosition.getFile()) && myPosition.getLine() == locationPosition.getLine() && myFrameCount == frameCount) { + return true; + } + } + DebuggerSettings settings = DebuggerSettings.getInstance(); + if (settings.SKIP_SYNTHETIC_METHODS) { + Location location = context.getFrameProxy().location(); + Method method = location.method(); + if (method != null) { + if (myVirtualMachineProxy.canGetSyntheticAttribute()? method.isSynthetic() : method.name().indexOf('$') >= 0) { + return true; + } + } + } + if (!myIgnoreFilters) { + if(settings.SKIP_GETTERS) { + boolean isGetter = ApplicationManager.getApplication().runReadAction(new Computable(){ + public Boolean compute() { + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(PositionUtil.getContextElement(context), PsiMethod.class); + if(psiMethod == null) return Boolean.FALSE; + + return new Boolean(PropertyUtil.isSimplePropertyGetter(psiMethod)); + } + }).booleanValue(); + + if(isGetter) { + mySkipThisMethod = isGetter; + return true; + } + } + + if (settings.SKIP_CONSTRUCTORS) { + Location location = context.getFrameProxy().location(); + Method method = location.method(); + if (method != null && method.isConstructor()) { + mySkipThisMethod = true; + return true; + } + } + } + return false; + } + catch (VMDisconnectedException e) { + return false; + } + catch (EvaluateException e) { + LOG.error(e); + return false; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextImpl.java new file mode 100644 index 00000000000..17eb4054dbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.containers.HashSet; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.event.EventSet; +import com.sun.jdi.request.EventRequest; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 24, 2004 + * Time: 8:04:50 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class SuspendContextImpl implements SuspendContext { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendContextImpl"); + + private final DebugProcessImpl myDebugProcess; + private final int mySuspendPolicy; + + private ThreadReferenceProxyImpl myThread; + boolean myIsVotedForResume = true; + + protected int myVotesToVote; + protected Set myResumedThreads; + + private EventSet myEventSet; + private boolean myIsResumed; + + public List myPostponedCommands = new ArrayList(); + public boolean myInProgress; + private HashSet myKeptReferences = new HashSet(); + private EvaluationContextImpl myEvaluationContext = null; + + SuspendContextImpl(DebugProcessImpl debugProcess, int suspendPolicy, int eventVotes, EventSet set) { + LOG.assertTrue(debugProcess != null); + myDebugProcess = debugProcess; + mySuspendPolicy = suspendPolicy; + myVotesToVote = eventVotes; + myEventSet = set; + } + + public void setThread(ThreadReference thread) { + assertNotResumed(); + ThreadReferenceProxyImpl threadProxy = myDebugProcess.getVirtualMachineProxy().getThreadReferenceProxy(thread); + LOG.assertTrue(myThread == null || myThread == threadProxy); + myThread = threadProxy; + } + + protected abstract void resumeImpl(); + + protected void resume(){ + assertNotResumed(); + DebuggerManagerThreadImpl.assertIsManagerThread(); + for (Iterator iterator = myKeptReferences.iterator(); iterator.hasNext();) { + ObjectReference objectReference = iterator.next(); + objectReference.enableCollection(); + } + myKeptReferences.clear(); + resumeImpl(); + myIsResumed = true; + } + + private void assertNotResumed() { + LOG.assertTrue(!myIsResumed, "Cannot access SuspendContext. SuspendContext is resumed."); + } + + + public EventSet getEventSet() { + assertNotResumed(); + return myEventSet; + } + + public DebugProcessImpl getDebugProcess() { + assertNotResumed(); + return myDebugProcess; + } + + public StackFrameProxyImpl getFrameProxy() { + assertNotResumed(); + try { + return myThread != null && myThread.frameCount() > 0 ? myThread.frame(0) : null; + } + catch (EvaluateException e) { + return null; + } + } + + public ThreadReferenceProxyImpl getThread() { + return myThread; + } + + public int getSuspendPolicy() { + assertNotResumed(); + return mySuspendPolicy; + } + + public void doNotResumeHack() { + assertNotResumed(); + myVotesToVote = 1000000000; + } + + public boolean isExplicitlyResumed(ThreadReferenceProxyImpl thread) { + return myResumedThreads != null ? myResumedThreads.contains(thread) : false; + } + + public boolean suspends(ThreadReferenceProxyImpl thread) { + assertNotResumed(); + if(isEvaluating()) return false; + switch(getSuspendPolicy()) { + case EventRequest.SUSPEND_ALL: + return !isExplicitlyResumed(thread); + case EventRequest.SUSPEND_EVENT_THREAD: + return thread == getThread(); + } + return false; + } + + public boolean isEvaluating() { + assertNotResumed(); + return myEvaluationContext != null; + } + + public EvaluationContextImpl getEvaluationContext() { + return myEvaluationContext; + } + + public boolean isResumed() { + return myIsResumed; + } + + public void setIsEvaluating(EvaluationContextImpl evaluationContext) { + assertNotResumed(); + myEvaluationContext = evaluationContext; + } + + public SuspendManager getSuspendManager() { + return myDebugProcess.getSuspendManager(); + } + + public String toString() { + if (myEventSet != null) { + return myEventSet.toString(); + } else { + return myThread != null ? myThread.toString() : "null context"; + } + } + + public void keep(ObjectReference reference) { + if(!myKeptReferences.contains(reference)) { + reference.disableCollection(); + myKeptReferences.add(reference); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextRunnable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextRunnable.java new file mode 100644 index 00000000000..de608945912 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendContextRunnable.java @@ -0,0 +1,12 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.SuspendContextImpl; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface SuspendContextRunnable { + void run(SuspendContextImpl suspendContext) throws Exception; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManager.java new file mode 100644 index 00000000000..2a57a524dbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManager.java @@ -0,0 +1,31 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.sun.jdi.event.EventSet; + +import java.util.List; + +public interface SuspendManager { + SuspendContextImpl pushSuspendContext(EventSet eventSet); + SuspendContextImpl pushSuspendContext(int suspendAll, int i); + + void resume(SuspendContextImpl suspendContext); + + //replaces current context with new one at the same location and fires 'paused' event + void popFrame(SuspendContextImpl suspendContext); + + SuspendContextImpl getPausedContext(); + boolean isFrozen(ThreadReferenceProxyImpl thread); + boolean isSuspended(ThreadReferenceProxyImpl thread); + + void freezeThread(ThreadReferenceProxyImpl invokeThread); + void unfreezeThread(ThreadReferenceProxyImpl thread); + + void resumeThread(SuspendContextImpl suspendContext, ThreadReferenceProxyImpl invokeThread); + void suspendThread(SuspendContextImpl suspendContext, ThreadReferenceProxyImpl invokeThread); + + void voteResume(SuspendContextImpl suspendContext); + void voteSuspend(SuspendContextImpl suspendContext); + + List getEventContexts(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerImpl.java new file mode 100644 index 00000000000..bbb80bb8764 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerImpl.java @@ -0,0 +1,280 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.Patches; +import com.sun.jdi.event.EventSet; +import com.sun.jdi.request.EventRequest; +import com.sun.jdi.InternalException; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 24, 2004 + * Time: 8:04:01 PM + * To change this template use File | Settings | File Templates. + */ +public class SuspendManagerImpl implements SuspendManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendManager"); + + private final LinkedList myEventContexts = new LinkedList(); + private final LinkedList myPausedContexts = new LinkedList(); + private final Set myFrozenThreads = new HashSet(); + + private final DebugProcessImpl myDebugProcess; + + public int suspends = 0; + + public SuspendManagerImpl(DebugProcessImpl debugProcess) { + myDebugProcess = debugProcess; + myDebugProcess.addDebugProcessListener(new DebugProcessAdapterImpl() { + public void processDetached(DebugProcessImpl process) { + myEventContexts.clear(); + myPausedContexts.clear(); + myFrozenThreads.clear(); + } + }); + } + + public SuspendContextImpl pushSuspendContext(final int suspendPolicy, int nVotes) { + SuspendContextImpl suspendContext = new SuspendContextImpl(myDebugProcess, suspendPolicy, nVotes, null) { + protected void resumeImpl() { + LOG.debug("Start resuming..."); + myDebugProcess.logThreads(); + switch(getSuspendPolicy()) { + case EventRequest.SUSPEND_ALL: + try { + myDebugProcess.getVirtualMachineProxy().resume(); + } + catch (InternalException e) { + //InternalException 13 means that there are running threads that we are trying to resume + //On MacOS it happened that native thread didn't stop while some java thread reached breakpoint + + //Its funny, but second resume solves the problem + if (Patches.MAC_RESUME_VM_HACK && e.errorCode() == 13) { + myDebugProcess.getVirtualMachineProxy().resume(); + } + else { + LOG.error(e); + } + } + LOG.debug("VM resumed "); + break; + case EventRequest.SUSPEND_EVENT_THREAD: + getThread().resume(); + if(LOG.isDebugEnabled()) { + LOG.debug("Thread resumed : " + getThread().toString()); + } + break; + case EventRequest.SUSPEND_NONE: + LOG.debug("None resumed"); + break; + } + if (LOG.isDebugEnabled()) { + LOG.debug("Suspends = " + suspends); + } + myDebugProcess.logThreads(); + } + }; + pushContext(suspendContext); + return suspendContext; + } + + public SuspendContextImpl pushSuspendContext(final EventSet set) { + SuspendContextImpl suspendContext = new SuspendContextImpl(myDebugProcess, set.suspendPolicy(), set.size(), set) { + protected void resumeImpl() { + if (LOG.isDebugEnabled()) { + LOG.debug("Start resuming eventSet " + set.toString() + " suspendPolicy = " + set.suspendPolicy() + ",size = " + set.size()); + } + myDebugProcess.logThreads(); + LOG.assertTrue(getThread() != null ? getThread().isSuspended() : true); + try { + set.resume(); + } + catch (InternalException e) { + //InternalException 13 means that there are running threads that we are trying to resume + //On MacOS it happened that native thread didn't stop while some java thread reached breakpoint + if (Patches.MAC_RESUME_VM_HACK && e.errorCode() == 13 && set.suspendPolicy() == EventRequest.SUSPEND_ALL) { + //Its funny, but second resume solves the problem + set.resume(); + } + else { + LOG.error(e); + } + } + LOG.debug("Set resumed "); + myDebugProcess.logThreads(); + } + }; + pushContext(suspendContext); + return suspendContext; + } + + private void pushContext(SuspendContextImpl suspendContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myEventContexts.addFirst(suspendContext); + suspends++; + if (LOG.isDebugEnabled()) { + LOG.debug("Push context : Suspends = " + suspends); + } + } + + public void resume(SuspendContextImpl context) { + SuspendManagerUtil.prepareForResume(context); + + myDebugProcess.logThreads(); + int suspendPolicy = context.getSuspendPolicy(); + context.resume(); + popContext(context); + myDebugProcess.clearCashes(suspendPolicy); + } + + + public void popFrame(SuspendContextImpl suspendContext) { + popContext(suspendContext); + SuspendContextImpl newSuspendContext = pushSuspendContext(suspendContext.getSuspendPolicy(), 0); + newSuspendContext.setThread(suspendContext.getThread().getThreadReference()); + notifyPaused(newSuspendContext); + } + + public SuspendContextImpl getPausedContext() { + return !myPausedContexts.isEmpty() ? myPausedContexts.getFirst() : null; + } + + public void popContext(SuspendContextImpl suspendContext) { + suspends--; + if (LOG.isDebugEnabled()) { + LOG.debug("popContext, suspends = " + suspends); + } + DebuggerManagerThreadImpl.assertIsManagerThread(); + boolean removed = myEventContexts.remove(suspendContext); + if(LOG.isDebugEnabled()) { + LOG.assertTrue(removed, suspendContext.toString()); + } + myPausedContexts.remove(suspendContext); + } + + void pushPausedContext(SuspendContextImpl suspendContext) { + if(LOG.isDebugEnabled()) { + LOG.assertTrue(myEventContexts.contains(suspendContext)); + } + + myPausedContexts.addFirst(suspendContext); + } + + public boolean hasEventContext(SuspendContextImpl suspendContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myEventContexts.contains(suspendContext); + } + + public List getEventContexts() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myEventContexts; + } + + public boolean isFrozen(ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myFrozenThreads.contains(thread); + } + + public boolean isSuspended(ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + + boolean suspended = false; + + for (Iterator iterator = myEventContexts.iterator(); iterator.hasNext();) { + SuspendContextImpl suspendContext = iterator.next(); + + if(suspendContext.suspends(thread) || isFrozen(thread)) { + suspended = true; + break; + } + } + + //bug in JDI : newly created thread may be resumed even when suspendPolicy == SUSPEND_ALL + //if(LOG.isDebugEnabled() && suspended) { + // LOG.assertTrue(thread.suspends(), thread.name()); + //} + return suspended && thread.isSuspended(); + } + + public void suspendThread(SuspendContextImpl context, ThreadReferenceProxyImpl thread) { + LOG.assertTrue(thread != context.getThread(), "Thread is already suspended at the breakpoint"); + + if(context.isExplicitlyResumed(thread)) { + context.myResumedThreads.remove(thread); + thread.suspend(); + } + } + + public void resumeThread(SuspendContextImpl context, ThreadReferenceProxyImpl thread) { + LOG.assertTrue(thread != context.getThread(), "Use resume() instead of resuming breakpoint thread"); + LOG.assertTrue(!context.isExplicitlyResumed(thread)); + + if(context.myResumedThreads == null) { + context.myResumedThreads = new HashSet(); + } + context.myResumedThreads.add(thread); + thread.resume(); + } + + public void freezeThread(ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + LOG.assertTrue(!isFrozen(thread)); + myFrozenThreads.add(thread); + thread.suspend(); + } + + public void unfreezeThread(ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + LOG.assertTrue(isFrozen(thread)); + myFrozenThreads.remove(thread); + thread.resume(); + } + + private void processVote(SuspendContextImpl suspendContext) { + LOG.assertTrue(suspendContext.myVotesToVote > 0); + suspendContext.myVotesToVote--; + + if (LOG.isDebugEnabled()) { + LOG.debug("myVotesToVote = " + suspendContext.myVotesToVote); + } + if(suspendContext.myVotesToVote == 0) { + if(suspendContext.myIsVotedForResume) { + resume(suspendContext); + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("vote paused"); + } + myDebugProcess.logThreads(); + myDebugProcess.cancelRunToCursorBreakpoint(); + myDebugProcess.deleteStepRequests(suspendContext.getThread()); + notifyPaused(suspendContext); + } + } + } + + private void notifyPaused(SuspendContextImpl suspendContext) { + pushPausedContext(suspendContext); + myDebugProcess.myDebugProcessDispatcher.getMulticaster().paused(suspendContext); + } + + public void voteResume(SuspendContextImpl suspendContext) { + if (LOG.isDebugEnabled()) { + LOG.debug("Resume voted"); + } + processVote(suspendContext); + } + + public void voteSuspend(SuspendContextImpl suspendContext) { + suspendContext.myIsVotedForResume = false; + processVote(suspendContext); + } + + LinkedList getPausedContexts() { + return myPausedContexts; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerUtil.java new file mode 100644 index 00000000000..569ec8232b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/SuspendManagerUtil.java @@ -0,0 +1,174 @@ +package com.intellij.debugger.engine; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.*; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class SuspendManagerUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendManagerUtil"); + + public static boolean isEvaluating(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) { + for (Iterator iterator = ((SuspendManagerImpl) suspendManager).getEventContexts().iterator(); iterator.hasNext();) { + SuspendContextImpl suspendContext = iterator.next(); + if(suspendContext.isEvaluating() && thread.equals(suspendContext.getThread())) { + return true; + } + } + return false; + } + + public static SuspendContextImpl findContextByThread(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) { + for (ListIterator iterator = ((SuspendManagerImpl) suspendManager).getPausedContexts().listIterator(); iterator.hasNext();) { + SuspendContextImpl context = iterator.next(); + if(context.getThread() == thread) { + return context; + } + } + + return null; + } + + public static void assertSuspendContext(SuspendContextImpl context) { + if(LOG.isDebugEnabled()) { + LOG.assertTrue(context.myInProgress, "You can invoke methods only inside commands invoked for SuspendContext"); + } + } + + public static void postponeCommand(SuspendContextImpl context, SuspendContextCommandImpl command) { + context.myPostponedCommands.add(command); + } + + public static void runCommand(SuspendManager suspendManager, SuspendContextCommandImpl action) throws Exception { + SuspendContextImpl suspendContext = action.getSuspendContext(); + + if(suspendContext.myInProgress) { + postponeCommand(suspendContext, action); + } + else { + if(LOG.isDebugEnabled()) { + LOG.debug("running " + suspendManager); + } + + try { + if(!suspendContext.isResumed()) { + suspendContext.myInProgress = true; + action.contextAction(); + } + else { + if (LOG.isDebugEnabled()) { + LOG.debug("Context is invalid for SuspendContextCommand" + suspendManager); + } + action.notifyCancelled(); + } + } + finally{ + if(LOG.isDebugEnabled()) { + LOG.debug("end processing " + suspendManager); + } + suspendContext.myInProgress = false; + if(!suspendContext.isResumed() && suspendContext.myPostponedCommands.size() > 0) { + suspendContext.getDebugProcess().getManagerThread().invokeLater( + suspendContext.myPostponedCommands.remove(0)); + + } + } + } + } + + public static Set getSuspendingContexts(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + Set contextThreads = new HashSet(); + + Set result = new HashSet(); + + for (Iterator iterator = ((SuspendManagerImpl) suspendManager).getEventContexts().iterator(); iterator.hasNext();) { + SuspendContextImpl suspendContext = iterator.next(); + if(suspendContext.suspends(thread)) { + ThreadReferenceProxyImpl contextThread = suspendContext.getThread(); + LOG.assertTrue(!contextThreads.contains(contextThread)); + contextThreads.add(contextThread); + result.add(suspendContext); + } + } + + return result; + } + + public static void restoreAfterResume(SuspendContextImpl context, Object resumeData) { + SuspendManager suspendManager = context.getDebugProcess().getSuspendManager(); + ResumeData data = (ResumeData) resumeData; + + ThreadReferenceProxyImpl thread = context.getThread(); + if(data.myIsFrozen && !suspendManager.isFrozen(thread)) { + suspendManager.freezeThread(thread); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("RestoreAfterResume SuspendContextImpl..."); + } + LOG.assertTrue(context.myResumedThreads == null); + + if(data.myResumedThreads != null) { + for (Iterator iterator = data.myResumedThreads.iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl resumedThreads = iterator.next(); + resumedThreads.resume(); + } + context.myResumedThreads = data.myResumedThreads; + } + } + + public static Object prepareForResume(SuspendContextImpl context) { + SuspendManager suspendManager = context.getDebugProcess().getSuspendManager(); + + ThreadReferenceProxyImpl thread = context.getThread(); + + ResumeData resumeData = new ResumeData(suspendManager.isFrozen(thread), context.myResumedThreads); + + if(resumeData.myIsFrozen) { + suspendManager.unfreezeThread(thread); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Resuming SuspendContextImpl..."); + } + if(context.myResumedThreads != null) { + for (Iterator iterator = context.myResumedThreads.iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl resumedThreads = iterator.next(); + resumedThreads.suspend(); + } + context.myResumedThreads = null; + } + + return resumeData; + } + + public static SuspendContextImpl getSuspendContextForThread(SuspendContextImpl suspendContext, ThreadReferenceProxyImpl thread) { + SuspendContextImpl context = findContextByThread(suspendContext.getDebugProcess().getSuspendManager(), thread); + return context != null && !context.myInProgress ? context : suspendContext; + } + + public static SuspendContextImpl getEvaluatingContext(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) { + for (Iterator iterator = ((SuspendManagerImpl)suspendManager).getPausedContexts().iterator(); iterator.hasNext();) { + SuspendContextImpl suspendContext = iterator.next(); + if(suspendContext.isEvaluating() && suspendContext.getThread() == thread) return suspendContext; + } + return null; + } + + private static class ResumeData { + final boolean myIsFrozen; + final Set myResumedThreads; + + public ResumeData(boolean isFrozen, Set resumedThreads) { + myIsFrozen = isFrozen; + myResumedThreads = resumedThreads; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/VMEventListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/VMEventListener.java new file mode 100644 index 00000000000..61a2a7b3a85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/VMEventListener.java @@ -0,0 +1,13 @@ +package com.intellij.debugger.engine; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jul 15, 2003 + * Time: 6:38:23 PM + * To change this template use Options | File Templates. + */ +public interface VMEventListener { + //aware! called in DebuggerEventThread + void vmEvent(com.sun.jdi.event.Event event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/DebuggerHighlightFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/DebuggerHighlightFilter.java new file mode 100644 index 00000000000..d436b46bcc7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/DebuggerHighlightFilter.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.debugger.engine.evaluation; + +import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.psi.PsiFile; + +public class DebuggerHighlightFilter implements HighlightInfoFilter, ApplicationComponent { + public boolean accept(HighlightInfoType highlightType, PsiFile file) { + return highlightType != HighlightInfoType.UNHANDLED_EXCEPTION || file == null || file.getUserData(DebuggerExpressionComboBox.KEY) == null; + } + + public String getComponentName() { + return "DebuggerHighlightsFilter"; + } + + public void initComponent() { } + + public void disposeComponent() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java new file mode 100644 index 00000000000..607dff43762 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java @@ -0,0 +1,20 @@ +package com.intellij.debugger.engine.evaluation; + +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jan 14, 2004 + * Time: 2:18:59 PM + * To change this template use File | Settings | File Templates. + */ +public class EvaluateRuntimeException extends RuntimeException{ + public EvaluateRuntimeException(EvaluateException e) { + super(e); + } + + public EvaluateException getCause() { + return (EvaluateException)super.getCause(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java new file mode 100644 index 00000000000..0c5192c8599 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java @@ -0,0 +1,73 @@ +package com.intellij.debugger.engine.evaluation; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.sun.jdi.ClassLoaderReference; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.Value; + +/** + * User: lex + * Date: Aug 28, 2003 + * Time: 2:02:29 PM + */ +public final class EvaluationContextImpl implements EvaluationContext{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.EvaluationContextImpl"); + + private final Value myThisObject; + private final SuspendContextImpl mySuspendContext; + private final StackFrameProxyImpl myFrameProxy; + private boolean myAllowBreakpoints = false; + + public EvaluationContextImpl(SuspendContextImpl suspendContext, StackFrameProxyImpl frameProxy, + Value thisObject) { + myThisObject = thisObject; + myFrameProxy = frameProxy; + mySuspendContext = suspendContext; + LOG.assertTrue(suspendContext != null); + } + + public Value getThisObject() { + return myThisObject; + } + + public SuspendContextImpl getSuspendContext() { + return mySuspendContext; + } + + public StackFrameProxyImpl getFrameProxy() { + return myFrameProxy; + } + + public DebugProcessImpl getDebugProcess() { + return getSuspendContext().getDebugProcess(); + } + + public Project getProject() { + DebugProcessImpl debugProcess = getDebugProcess(); + return debugProcess != null ? debugProcess.getProject() : null; + } + + public EvaluationContextImpl createEvaluationContext(Value value) { + EvaluationContextImpl evaluationContext = new EvaluationContextImpl(getSuspendContext(), getFrameProxy(), value); + evaluationContext.myAllowBreakpoints = isAllowBreakpoints(); + return evaluationContext; + } + + public ClassLoaderReference getClassLoader() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myFrameProxy != null ? myFrameProxy.getClassLoader() : null; + } + + public boolean isAllowBreakpoints() { + return myAllowBreakpoints; + } + + public void setAllowBreakpoints(boolean allowBreakpoints) { + myAllowBreakpoints = allowBreakpoints; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationListener.java new file mode 100644 index 00000000000..d370ea6f7c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/EvaluationListener.java @@ -0,0 +1,17 @@ +package com.intellij.debugger.engine.evaluation; + +import com.intellij.debugger.engine.SuspendContextImpl; + +import java.util.EventListener; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 3, 2004 + * Time: 7:19:30 PM + * To change this template use File | Settings | File Templates. + */ +public interface EvaluationListener extends EventListener{ + public void evaluationStarted(SuspendContextImpl context); + public void evaluationFinished(SuspendContextImpl context); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java new file mode 100644 index 00000000000..349bb77b852 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java @@ -0,0 +1,138 @@ +package com.intellij.debugger.engine.evaluation; + +import com.intellij.debugger.ui.DebuggerEditorImpl; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 6:47:49 PM + * To change this template use File | Settings | File Templates. + */ +public class TextWithImportsImpl implements TextWithImports{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.TextWithImportsImpl"); + + private final String myText; + private final String myImports; + private final CodeFragmentFactory myCodeFragmentFactory; + + public static final CodeFragmentFactory EXPRESSION_FACTORY = new CodeFragmentFactory() { + public PsiCodeFragment createCodeFragment(TextWithImportsImpl item, PsiElement context, Project project) { + String text = item.getText(); + if (StringUtil.endsWithChar(text, ';')) { + text = text.substring(0, text.length() - 1); + } + PsiExpressionCodeFragment expressionCodeFragment = PsiManager.getInstance(project).getElementFactory().createExpressionCodeFragment( + text, context, true); + initCodeFragment(item, expressionCodeFragment); + return expressionCodeFragment; + } + }; + public static final CodeFragmentFactory CODE_BLOCK_FACTORY = new CodeFragmentFactory() { + public PsiCodeFragment createCodeFragment(TextWithImportsImpl item, PsiElement context, Project project) { + PsiCodeFragment codeFragment = PsiManager.getInstance(project).getElementFactory().createCodeBlockCodeFragment( + item.getText(), context, true); + + initCodeFragment(item, codeFragment); + return codeFragment; + } + }; + + public final static TextWithImportsImpl EMPTY = createExpressionText(""); + + private static final Object IS_DEBUGGER_EDITOR = "DebuggerComboBoxEditor.IS_DEBUGGER_EDITOR"; + + public TextWithImportsImpl (CodeFragmentFactory factory, String text, String imports) { + LOG.assertTrue(factory != null); + myCodeFragmentFactory = factory; + myText = text; + myImports = imports; + LOG.assertTrue(myImports != null); + } + + public TextWithImportsImpl (CodeFragmentFactory factory, String text) { + LOG.assertTrue(factory != null); + myCodeFragmentFactory = factory; + text = text.trim(); + int separator = text.indexOf(DebuggerEditorImpl.SEPARATOR); + if(separator != -1){ + myText = text.substring(0, separator); + myImports = text.substring(separator + 1); + } else { + myText = text; + myImports = ""; + } + LOG.assertTrue(myImports != null); + } + + public String toString() { + return myText; + } + + public String saveToString() { + return myImports.equals("") ? myText : myText + DebuggerEditorImpl.SEPARATOR + myImports; + } + + public String getText() { + return myText; + } + + public String getImports() { + return myImports; + } + + public boolean equals(Object object) { + if(!(object instanceof TextWithImportsImpl)) return false; + TextWithImportsImpl item = ((TextWithImportsImpl)object); + return Comparing.equal(item.myText, myText) && Comparing.equal(item.myImports, myImports); + } + + public PsiCodeFragment createCodeFragment(PsiElement context, Project project){ + return myCodeFragmentFactory.createCodeFragment(this, context, project); + } + + public int hashCode() { + return myText.hashCode(); + } + + public static TextWithImportsImpl createExpressionText(PsiExpression expression) { + PsiFile containingFile = expression.getContainingFile(); + if(containingFile instanceof PsiExpressionCodeFragment) { + return new TextWithImportsImpl(EXPRESSION_FACTORY, expression.getText(), ((PsiCodeFragment)containingFile).importsToString()); + } + return createExpressionText(expression.getText()); + } + public static TextWithImportsImpl createExpressionText(String expression) { + return new TextWithImportsImpl(EXPRESSION_FACTORY, expression); + } + + public static TextWithImportsImpl createCodeBlockText(String expression) { + return new TextWithImportsImpl(CODE_BLOCK_FACTORY, expression); + } + + private static void initCodeFragment(TextWithImportsImpl item, PsiCodeFragment codeFragment) { + if(item.getImports() != null) { + codeFragment.addImportsFromString(item.getImports()); + } + codeFragment.setEverythingAcessible(true); + codeFragment.putUserData(DebuggerExpressionComboBox.KEY, IS_DEBUGGER_EDITOR); + } + + public boolean isEmpty() { + return "".equals(getText().trim()); + } + + public TextWithImportsImpl createText(String newText) { + return new TextWithImportsImpl(EXPRESSION_FACTORY, newText, getImports()); + } + + public CodeFragmentFactory getFactory() { + return myCodeFragmentFactory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayAccessEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayAccessEvaluator.java new file mode 100644 index 00000000000..207465af8d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayAccessEvaluator.java @@ -0,0 +1,84 @@ +/* + * Class ArrayAccessEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl; +import com.intellij.openapi.project.Project; +import com.sun.jdi.*; + +class ArrayAccessEvaluator implements Evaluator { + private Evaluator myArrayReferenceEvaluator; + private Evaluator myIndexEvaluator; + private ArrayReference myEvaluatedArrayReference; + private int myEvaluatedIndex; + + public ArrayAccessEvaluator(Evaluator arrayReferenceEvaluator, Evaluator indexEvaluator) { + myArrayReferenceEvaluator = arrayReferenceEvaluator; + myIndexEvaluator = indexEvaluator; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + myEvaluatedIndex = 0; + myEvaluatedArrayReference = null; + Value indexValue = (Value)myIndexEvaluator.evaluate(context); + Value arrayValue = (Value)myArrayReferenceEvaluator.evaluate(context); + if (!(arrayValue instanceof ArrayReference)) { + throw EvaluateExceptionUtil.createEvaluateException("Array reference expected"); + } + myEvaluatedArrayReference = (ArrayReference)arrayValue; + if (!DebuggerUtilsEx.isInteger(indexValue)) { + throw EvaluateExceptionUtil.createEvaluateException("Invalid index expression"); + } + myEvaluatedIndex = ((PrimitiveValue)indexValue).intValue(); + try { + return myEvaluatedArrayReference.getValue(myEvaluatedIndex); + } + catch (Exception e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + public Modifier getModifier() { + Modifier modifier = null; + if (myEvaluatedArrayReference != null) { + modifier = new Modifier() { + public boolean canInspect() { + return true; + } + + public boolean canSetValue() { + return true; + } + + public void setValue(Value value) throws ClassNotLoadedException, InvalidTypeException { + myEvaluatedArrayReference.setValue(myEvaluatedIndex, value); + } + + public Type getExpectedType() throws EvaluateException { + try { + ArrayType type = (ArrayType)myEvaluatedArrayReference.referenceType(); + return type.componentType(); + } + catch (ClassNotLoadedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + public NodeDescriptorImpl getInspectItem(Project project) { + return new ArrayElementDescriptorImpl(project, myEvaluatedArrayReference, myEvaluatedIndex); + } + }; + } + return modifier; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayInitializerEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayInitializerEvaluator.java new file mode 100644 index 00000000000..35938f3410e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ArrayInitializerEvaluator.java @@ -0,0 +1,35 @@ +/** + * class ArrayInitializerEvaluator + * created Jun 28, 2001 + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +class ArrayInitializerEvaluator implements Evaluator{ + private Evaluator[] myValueEvaluators; + + public ArrayInitializerEvaluator(Evaluator[] valueEvaluators) { + myValueEvaluators = valueEvaluators; + } + + /** + * @return an array of Values + */ + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object[] values = new Object[myValueEvaluators.length]; + for (int idx = 0; idx < myValueEvaluators.length; idx++) { + Evaluator evaluator = myValueEvaluators[idx]; + values[idx] = evaluator.evaluate(context); + } + return values; + } + + public Modifier getModifier() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java new file mode 100644 index 00000000000..20a21fd3e67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java @@ -0,0 +1,70 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 24, 2004 + * Time: 11:10:41 PM + * To change this template use File | Settings | File Templates. + */ +public class AssignmentEvaluator implements Evaluator{ + private final Evaluator myLeftEvaluator; + private final Evaluator myRightEvaluator; + + public AssignmentEvaluator(Evaluator leftEvaluator, Evaluator rightEvaluator) { + myLeftEvaluator = leftEvaluator; + myRightEvaluator = rightEvaluator; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object right = myRightEvaluator.evaluate(context); + if(right != null && !(right instanceof Value)) { + throw EvaluateExceptionUtil.createEvaluateException("Right part of the assignment is not value."); + } + + myLeftEvaluator.evaluate(context); + Modifier modifier = myLeftEvaluator.getModifier(); + assign(modifier, right, context); + return right; + } + + static void assign(Modifier modifier, Object right, EvaluationContextImpl context) throws EvaluateException { + if(modifier == null) { + throw EvaluateExceptionUtil.createEvaluateException("Left part of the assignment is not lvalue."); + } + try { + modifier.setValue(((Value)right)); + } + catch (ClassNotLoadedException e) { + try { + context.getDebugProcess().loadClass(context, e.className(), context.getClassLoader()); + } + catch (InvocationException e1) { + throw EvaluateExceptionUtil.createEvaluateException(e1); + } + catch (ClassNotLoadedException e1) { + throw EvaluateExceptionUtil.createEvaluateException(e1); + } + catch (IncompatibleThreadStateException e1) { + throw EvaluateExceptionUtil.createEvaluateException(e1); + } + catch (InvalidTypeException e1) { + throw EvaluateExceptionUtil.createEvaluateException(e1); + } + } + catch (InvalidTypeException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + public Modifier getModifier() { + return myLeftEvaluator.getModifier(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BinaryExpressionEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BinaryExpressionEvaluator.java new file mode 100644 index 00000000000..784d07b9e34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BinaryExpressionEvaluator.java @@ -0,0 +1,357 @@ +/* + * Class BinaryExpressionEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.sun.jdi.*; + +class BinaryExpressionEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.BinaryExpressionEvaluator"); + private Evaluator myLeftOperand; + private Evaluator myRightOperand; + private IElementType myOpType; + private String myExpectedType; // a result of PsiType.getCanonicalText() + + public BinaryExpressionEvaluator(Evaluator leftOperand, Evaluator rightOperand, IElementType opType, String expectedType) { + myLeftOperand = leftOperand; + myRightOperand = rightOperand; + myOpType = opType; + myExpectedType = expectedType; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value leftResult = (Value)myLeftOperand.evaluate(context); + return evaluateOperation(leftResult, myOpType, myRightOperand, myExpectedType, context); + + } + + static Object evaluateOperation(Value leftResult, + IElementType opType, + Evaluator rightOperand, + String expectedType, + EvaluationContextImpl context) throws EvaluateException { + VirtualMachineProxyImpl vm = context.getDebugProcess().getVirtualMachineProxy(); + if (leftResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + if (opType == JavaTokenType.OROR && v1) { + return DebuggerUtilsEx.createValue(vm, expectedType, true); + } + if (opType == JavaTokenType.ANDAND && !v1) { + return DebuggerUtilsEx.createValue(vm, expectedType, false); + } + } + Value rightResult = (Value)rightOperand.evaluate(context); + if (opType == JavaTokenType.PLUS) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 + v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 + v2); + } + if (leftResult instanceof StringReference || rightResult instanceof StringReference) { + String v1 = DebuggerUtilsEx.getValueAsString(context, leftResult); + String v2 = DebuggerUtilsEx.getValueAsString(context, rightResult); + return DebuggerUtilsEx.createValue(vm, v1 + v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '+' operation"); + } + else if (opType == JavaTokenType.MINUS) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 - v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 - v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '-' operation"); + } + else if (opType == JavaTokenType.ASTERISK) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 * v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 * v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '*' operation"); + } + else if (opType == JavaTokenType.DIV) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 / v2); + } + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 / v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 / v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '/' operation"); + } + else if (opType == JavaTokenType.PERC) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 % v2); + } + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 % v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 % v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '%' operation"); + } + else if (opType == JavaTokenType.LTLT) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 << v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 << v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '<<' operation"); + } + else if (opType == JavaTokenType.GTGT) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >> v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >> v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '>>' operation"); + } + else if (opType == JavaTokenType.GTGTGT) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >>> v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >>> v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '>>>' operation"); + } + else if (opType == JavaTokenType.AND) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 & v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 & v2); + } + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 & v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '&' operation"); + } + else if (opType == JavaTokenType.OR) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 | v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 | v2); + } + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 | v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '|' operation"); + } + else if (opType == JavaTokenType.XOR) { + if (DebuggerUtilsEx.isInteger(leftResult) && DebuggerUtilsEx.isInteger(rightResult)) { + long v1 = ((PrimitiveValue)leftResult).longValue(); + long v2 = ((PrimitiveValue)rightResult).longValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 ^ v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 ^ v2); + } + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 ^ v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '^' operation"); + } + else if (opType == JavaTokenType.EQEQ) { + if (leftResult == null && rightResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, true); + if (leftResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, rightResult.equals(leftResult)); + if (rightResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, leftResult.equals(rightResult)); + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 == v2); + } + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 == v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 == v2); + } + if (leftResult instanceof ObjectReference && rightResult instanceof ObjectReference) { + ObjectReference v1 = (ObjectReference)leftResult; + ObjectReference v2 = (ObjectReference)rightResult; + return DebuggerUtilsEx.createValue(vm, expectedType, v1.uniqueID() == v2.uniqueID()); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '==' operation"); + } + else if (opType == JavaTokenType.OROR) { + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 || v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '||' operation"); + } + else if (opType == JavaTokenType.ANDAND) { + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 && v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '&&' operation"); + } + else if (opType == JavaTokenType.NE) { + if (leftResult == null && rightResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, false); + if (leftResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, !rightResult.equals(leftResult)); + if (rightResult == null) return DebuggerUtilsEx.createValue(vm, expectedType, !leftResult.equals(rightResult)); + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 != v2); + } + if (leftResult instanceof BooleanValue && rightResult instanceof BooleanValue) { + boolean v1 = ((PrimitiveValue)leftResult).booleanValue(); + boolean v2 = ((PrimitiveValue)rightResult).booleanValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 != v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 != v2); + } + if (leftResult instanceof ObjectReference && rightResult instanceof ObjectReference) { + ObjectReference v1 = (ObjectReference)leftResult; + ObjectReference v2 = (ObjectReference)rightResult; + return DebuggerUtilsEx.createValue(vm, expectedType, v1.uniqueID() != v2.uniqueID()); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '!=' operation"); + } + else if (opType == JavaTokenType.LT) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 < v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 < v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '<' operation"); + } + else if (opType == JavaTokenType.GT) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 > v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 > v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '>' operation"); + } + else if (opType == JavaTokenType.LE) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 <= v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 <= v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '<=' operation"); + } + else if (opType == JavaTokenType.GE) { + if (DebuggerUtilsEx.isNumeric(leftResult) && DebuggerUtilsEx.isNumeric(rightResult)) { + double v1 = ((PrimitiveValue)leftResult).doubleValue(); + double v2 = ((PrimitiveValue)rightResult).doubleValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >= v2); + } + if (leftResult instanceof CharValue && rightResult instanceof CharValue) { + char v1 = ((CharValue)leftResult).charValue(); + char v2 = ((CharValue)rightResult).charValue(); + return DebuggerUtilsEx.createValue(vm, expectedType, v1 >= v2); + } + throw EvaluateExceptionUtil.createEvaluateException("Incompatible types in '>=' operation"); + } + + LOG.assertTrue(false); + + return null; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java new file mode 100644 index 00000000000..6dcf77933c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java @@ -0,0 +1,33 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 5:21:10 PM + * To change this template use File | Settings | File Templates. + */ +public class BlockStatementEvaluator implements Evaluator{ + protected Evaluator [] myStatements; + + public BlockStatementEvaluator(Evaluator[] statements) { + myStatements = statements; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(); + for (int i = 0; i < myStatements.length; i++) { + Evaluator statement = myStatements[i]; + result = statement.evaluate(context); + } + return result; + } + + public Modifier getModifier() { + return myStatements.length > 0 ? myStatements[myStatements.length - 1].getModifier() : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java new file mode 100644 index 00000000000..b0617024761 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java @@ -0,0 +1,36 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 7:27:10 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class BreakContinueStatementEvaluator implements Evaluator{ + public static Evaluator createBreakEvaluator(final String labelName) { + return new Evaluator() { + public Object evaluate(EvaluationContextImpl context) throws BreakException { + throw new BreakException(labelName); + } + + public Modifier getModifier() { + return null; + } + }; + } + + public static Evaluator createContinueEvaluator(final String labelName) { + return new Evaluator() { + public Object evaluate(EvaluationContextImpl context) throws ContinueException { + throw new ContinueException(labelName); + } + + public Modifier getModifier() { + return null; + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakException.java new file mode 100644 index 00000000000..81c77445437 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/BreakException.java @@ -0,0 +1,24 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 7:12:47 PM + * To change this template use File | Settings | File Templates. + */ +public class BreakException extends EvaluateException{ + private final String myLabelName; + + public BreakException(String labelName) { + super("No loop statements labeled with '" + labelName + "'", null); + myLabelName = labelName; + } + + public String getLabelName() { + return myLabelName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ClassObjectEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ClassObjectEvaluator.java new file mode 100644 index 00000000000..347d647030d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ClassObjectEvaluator.java @@ -0,0 +1,31 @@ +/* + * Class ClassObjectEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.ReferenceType; + +class ClassObjectEvaluator implements Evaluator { + private TypeEvaluator myTypeEvaluator; + + public ClassObjectEvaluator(TypeEvaluator typeEvaluator) { + myTypeEvaluator = typeEvaluator; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object object = myTypeEvaluator.evaluate(context); + if (!(object instanceof ReferenceType)) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot evaluate: the type specified is not a reference type"); + } + return ((ReferenceType)object).classObject(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java new file mode 100644 index 00000000000..42e0f6c44a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java @@ -0,0 +1,113 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.containers.HashMap; +import com.sun.jdi.Value; + +import java.util.Map; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 24, 2004 + * Time: 10:45:50 PM + * To change this template use File | Settings | File Templates. + */ +public class CodeFragmentEvaluator extends BlockStatementEvaluator{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.CodeFragmentEvaluator"); + + private final CodeFragmentEvaluator myParentFragmentEvaluator; + private final Map mySyntheticLocals = new HashMap(); + + public CodeFragmentEvaluator(CodeFragmentEvaluator parentFragmentEvaluator) { + super(null); + myParentFragmentEvaluator = parentFragmentEvaluator; + } + + public void setStatements(Evaluator[] evaluators) { + myStatements = evaluators; + } + + public Value getValue(String localName, VirtualMachineProxyImpl vm) throws EvaluateException { + if(!mySyntheticLocals.containsKey(localName)) { + if(myParentFragmentEvaluator != null){ + return myParentFragmentEvaluator.getValue(localName, vm); + } else { + throw EvaluateExceptionUtil.createEvaluateException("Variable is not declared " + localName); + } + } + Object value = mySyntheticLocals.get(localName); + if(value instanceof Value) { + return (Value)value; + } + else if(value == null) { + return null; + } + else if(value instanceof Boolean) { + return vm.mirrorOf(((Boolean)value).booleanValue()); + } + else if(value instanceof Byte) { + return vm.mirrorOf(((Byte)value).byteValue()); + } + else if(value instanceof Character) { + return vm.mirrorOf(((Character)value).charValue()); + } + else if(value instanceof Short) { + return vm.mirrorOf(((Short)value).shortValue()); + } + else if(value instanceof Integer) { + return vm.mirrorOf(((Integer)value).intValue()); + } + else if(value instanceof Long) { + return vm.mirrorOf(((Long)value).longValue()); + } + else if(value instanceof Float) { + return vm.mirrorOf(((Float)value).floatValue()); + } + else if(value instanceof Double) { + return vm.mirrorOf(((Double)value).doubleValue()); + } + else if(value instanceof String) { + return vm.mirrorOf((String)value); + } + else { + LOG.assertTrue(false, "unknown default initializer type " + value.getClass().getName()); + return null; + } + } + + private boolean hasValue(String localName) { + if(!mySyntheticLocals.containsKey(localName)) { + if(myParentFragmentEvaluator != null){ + return myParentFragmentEvaluator.hasValue(localName); + } else { + return false; + } + } else { + return true; + } + } + + public void setInitialValue(String localName, Object value) throws EvaluateException { + LOG.assertTrue(!(value instanceof Value), "use setValue for jdi values"); + if(hasValue(localName)) { + throw EvaluateExceptionUtil.createEvaluateException("Variable is already declared :" + localName); + } + mySyntheticLocals.put(localName, value); + } + + public void setValue(String localName, Value value) throws EvaluateException { + if(!mySyntheticLocals.containsKey(localName)) { + if(myParentFragmentEvaluator != null){ + myParentFragmentEvaluator.setValue(localName, value); + } else { + throw EvaluateExceptionUtil.createEvaluateException("Variable is not declared " + localName); + } + } + mySyntheticLocals.put(localName, value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java new file mode 100644 index 00000000000..6dd4ae61d64 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java @@ -0,0 +1,37 @@ +/* + * Class ConditionalExpressionEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.BooleanValue; +import com.sun.jdi.Value; + +class ConditionalExpressionEvaluator implements Evaluator { + private Evaluator myConditionEvaluator; + private Evaluator myThenEvaluator; + private Evaluator myElseEvaluator; + + public ConditionalExpressionEvaluator(Evaluator conditionEvaluator, Evaluator thenEvaluator, Evaluator elseEvaluator) { + myConditionEvaluator = conditionEvaluator; + myThenEvaluator = thenEvaluator; + myElseEvaluator = elseEvaluator; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value condition = (Value)myConditionEvaluator.evaluate(context); + if (condition == null || !(condition instanceof BooleanValue)) { + throw EvaluateExceptionUtil.createEvaluateException("Condition is not of type 'boolean'"); + } + return ((BooleanValue)condition).booleanValue()? myThenEvaluator.evaluate(context) : myElseEvaluator.evaluate(context); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ContinueException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ContinueException.java new file mode 100644 index 00000000000..148f64819d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ContinueException.java @@ -0,0 +1,23 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 7:12:47 PM + * To change this template use File | Settings | File Templates. + */ +public class ContinueException extends EvaluateException{ + private final String myLabelName; + + public ContinueException(String labelName) { + super("No loop statements labeled with '" + labelName + "'", null); + myLabelName = labelName; + } + + public String getLabelName() { + return myLabelName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/Evaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/Evaluator.java new file mode 100644 index 00000000000..1fab0afce7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/Evaluator.java @@ -0,0 +1,22 @@ +/* + * Interface Evaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +interface Evaluator { + /** + * @throws com.intellij.debugger.engine.evaluation.EvaluateException + */ + Object evaluate(EvaluationContextImpl context) throws EvaluateException; + + /** + * In order to obtain a modifier the expression must be evaluated first + * @return a modifier object allowing to set a value in case the expression is lvalue, + * otherwise null is returned + */ + Modifier getModifier(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java new file mode 100644 index 00000000000..540f71a9cb0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -0,0 +1,812 @@ +/* + * Class EvaluatorBuilderImpl + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.JVMName; +import com.intellij.debugger.engine.JVMNameUtil; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.ConstantExpressionEvaluator; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Value; + +import java.util.ArrayList; +import java.util.List; + +public class EvaluatorBuilderImpl implements EvaluatorBuilder { + private static final EvaluatorBuilderImpl ourInstance = new EvaluatorBuilderImpl(); + + private EvaluatorBuilderImpl() { + } + + public static EvaluatorBuilder getInstance() { + return ourInstance; + } + + public ExpressionEvaluator build(final TextWithImports text, final PsiElement contextElement) throws EvaluateException { + if (contextElement == null) { + throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS; + } + + final Project project = contextElement.getProject(); + + PsiCodeFragment codeFragment = text.createCodeFragment(contextElement, project); + DebuggerUtils.checkSyntax(codeFragment); + + if(codeFragment == null) throw EvaluateExceptionUtil.INVALID_EXPRESSION(((TextWithImportsImpl)text).getText()); + + return build(codeFragment); + } + + public ExpressionEvaluator build(final PsiElement element) throws EvaluateException { + return new Builder().buildElement(element); + } + + private static class Builder extends PsiElementVisitor { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl"); + private Evaluator myResult = null; + private PsiClass myContextPsiClass; + private CodeFragmentEvaluator myCurrentFragmentEvaluator; + + public void visitCodeFragment(PsiCodeFragment codeFragment) { + ArrayList evaluators = new ArrayList(); + + CodeFragmentEvaluator oldFragmentEvaluator = myCurrentFragmentEvaluator; + myCurrentFragmentEvaluator = new CodeFragmentEvaluator(oldFragmentEvaluator); + + for (PsiElement child = codeFragment.getFirstChild(); child != null; child = child.getNextSibling()) { + child.accept(this); + if(myResult != null) { + evaluators.add(myResult); + } + myResult = null; + } + + myCurrentFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[evaluators.size()])); + myResult = myCurrentFragmentEvaluator; + + myCurrentFragmentEvaluator = oldFragmentEvaluator; + } + + public void visitErrorElement(PsiErrorElement element) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(element.getText())); + } + + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + PsiExpression rExpression = expression.getRExpression(); + if(rExpression == null) throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + + rExpression.accept(this); + Evaluator rEvaluator = myResult; + + if(expression.getOperationSign().getTokenType() != JavaTokenType.EQ) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Operation " + expression.getOperationSign().getText() + "= is not supported.")); + } + + PsiExpression lExpression = expression.getLExpression(); + if(lExpression == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + + if(lExpression.getType() == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(lExpression.getText())); + } + + if(!TypeConversionUtil.areTypesAssignmentCompatible(lExpression.getType(), rExpression)) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Incompatible types " + expression.getText())); + } + lExpression.accept(this); + Evaluator lEvaluator = myResult; + + myResult = new AssignmentEvaluator(lEvaluator, rEvaluator); + } + + public void visitStatement(PsiStatement statement) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Statement is not supported : " + statement.getText())); + } + + public void visitBlockStatement(PsiBlockStatement statement) { + PsiStatement[] statements = statement.getCodeBlock().getStatements(); + Evaluator [] evaluators = new Evaluator[statements.length]; + for (int i = 0; i < statements.length; i++) { + PsiStatement psiStatement = statements[i]; + psiStatement.accept(this); + evaluators[i] = myResult; + myResult = null; + } + myResult = new BlockStatementEvaluator(evaluators); + } + + public void visitWhileStatement(PsiWhileStatement statement) { + PsiStatement body = statement.getBody(); + if(body == null) return; + body.accept(this); + Evaluator bodyEvaluator = myResult; + + PsiExpression condition = statement.getCondition(); + if(condition == null) return; + condition.accept(this); + String label = null; + if(statement.getParent() instanceof PsiLabeledStatement) { + label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText(); + } + myResult = new WhileStatementEvaluator(myResult, bodyEvaluator, label); + } + + public void visitForStatement(PsiForStatement statement) { + PsiStatement initializer = statement.getInitialization(); + Evaluator initializerEvaluator = null; + if(initializer != null){ + initializer.accept(this); + initializerEvaluator = myResult; + } + + PsiExpression condition = statement.getCondition(); + Evaluator conditionEvaluator = null; + if(condition != null) { + condition.accept(this); + conditionEvaluator = myResult; + } + + PsiStatement update = statement.getUpdate(); + Evaluator updateEvaluator = null; + if(update != null){ + update.accept(this); + updateEvaluator = myResult; + } + + PsiStatement body = statement.getBody(); + if(body == null) return; + body.accept(this); + Evaluator bodyEvaluator = myResult; + + String label = null; + if(statement.getParent() instanceof PsiLabeledStatement) { + label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText(); + } + myResult = new ForStatementEvaluator(initializerEvaluator, conditionEvaluator, updateEvaluator, bodyEvaluator, label); + } + + public void visitIfStatement(PsiIfStatement statement) { + PsiStatement thenBranch = statement.getThenBranch(); + if(thenBranch == null) return; + thenBranch.accept(this); + Evaluator thenEvaluator = myResult; + + PsiStatement elseBranch = statement.getElseBranch(); + Evaluator elseEvaluator = null; + if(elseBranch != null){ + elseBranch.accept(this); + elseEvaluator = myResult; + } + + PsiExpression condition = statement.getCondition(); + if(condition == null) return; + condition.accept(this); + + myResult = new IfStatementEvaluator(myResult, thenEvaluator, elseEvaluator); + } + + public void visitBreakStatement(PsiBreakStatement statement) { + PsiIdentifier labelIdentifier = statement.getLabelIdentifier(); + myResult = BreakContinueStatementEvaluator.createBreakEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null); + } + + public void visitContinueStatement(PsiContinueStatement statement) { + PsiIdentifier labelIdentifier = statement.getLabelIdentifier(); + myResult = BreakContinueStatementEvaluator.createContinueEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null); + } + + public void visitExpressionStatement(PsiExpressionStatement statement) { + statement.getExpression().accept(this); + } + + public void visitExpression(PsiExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitExpression " + expression); + } + } + + public void visitBinaryExpression(PsiBinaryExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitBinaryExpression " + expression); + } + expression.getLOperand().accept(this); + Evaluator lResult = myResult; + PsiExpression rOperand = expression.getROperand(); + if(rOperand == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + rOperand.accept(this); + IElementType opType = expression.getOperationSign().getTokenType(); + PsiType type = expression.getType(); + if (type == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(expression.getText())); + } + myResult = new BinaryExpressionEvaluator(lResult, myResult, opType, type.getCanonicalText()); + } + + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + List evaluators = new ArrayList(); + + PsiElement[] declaredElements = statement.getDeclaredElements(); + for (int i = 0; i < declaredElements.length; i++) { + PsiElement declaredElement = declaredElements[i]; + if(declaredElement instanceof PsiLocalVariable) { + if(myCurrentFragmentEvaluator != null) { + PsiLocalVariable localVariable = ((PsiLocalVariable)declaredElement); + + PsiType type = localVariable.getType(); + + if(type == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(localVariable.getName())); + } + + PsiElementFactory elementFactory = localVariable.getManager().getElementFactory(); + try { + PsiExpression initialValue = elementFactory.createExpressionFromText(CodeInsightUtil.getDefaultValueOfType(type), null); + Object value = ConstantExpressionEvaluator.computeConstantExpression(initialValue, null, true); + myCurrentFragmentEvaluator.setInitialValue(localVariable.getName(), value); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + catch (EvaluateException e) { + throw new EvaluateRuntimeException(e); + } + + PsiExpression initializer = localVariable.getInitializer(); + if(initializer != null) { + try { + if(!TypeConversionUtil.areTypesAssignmentCompatible(localVariable.getType(), initializer)) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Initializer for '" + localVariable.getName() + "' have incompatible type ")); + } + initializer.accept(this); + Evaluator rEvaluator = myResult; + + PsiExpression localVarReference = elementFactory.createExpressionFromText(localVariable.getName(), initializer); + + localVarReference.accept(this); + Evaluator lEvaluator = myResult; + + evaluators.add(new AssignmentEvaluator(lEvaluator, rEvaluator)); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } else { + throw new EvaluateRuntimeException(new EvaluateException("Local variable declarations are supported here.", null)); + } + } else { + throw new EvaluateRuntimeException(new EvaluateException("Invalid declaration : " + declaredElement.getText() + "Only local variable declarations supported.", null)); + } + } + + if(evaluators.size() > 0) { + CodeFragmentEvaluator codeFragmentEvaluator = new CodeFragmentEvaluator(myCurrentFragmentEvaluator); + codeFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[0])); + myResult = codeFragmentEvaluator; + } else { + myResult = null; + } + } + + public void visitConditionalExpression(PsiConditionalExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitConditionalExpression " + expression); + } + if (expression.getThenExpression() == null || expression.getElseExpression() == null){ + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + PsiExpression condition = expression.getCondition(); + condition.accept(this); + if (myResult == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(condition.getText())); + } + Evaluator conditionEvaluator = myResult; + expression.getThenExpression().accept(this); + if (myResult == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getThenExpression().getText())); + } + Evaluator thenEvaluator = myResult; + expression.getElseExpression().accept(this); + if (myResult == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getElseExpression().getText())); + } + Evaluator elseEvaluator = myResult; + myResult = new ConditionalExpressionEvaluator(conditionEvaluator, thenEvaluator, elseEvaluator); + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitReferenceExpression " + expression); + } + PsiExpression qualifier = expression.getQualifierExpression(); + PsiElement element = expression.resolve(); + + if (element instanceof PsiLocalVariable || element instanceof PsiParameter) { + //synthetic variable + if(element.getContainingFile() instanceof PsiCodeFragment && myCurrentFragmentEvaluator != null) { + myResult = new SyntheticVariableEvaluator(myCurrentFragmentEvaluator, ((PsiVariable)element).getName()); + return; + } + // local variable + PsiVariable psiVar = (PsiVariable)element; + String localName = psiVar.getName(); + PsiClass variableClass = getContainingClass(psiVar); + if (getContextPsiClass() == null || getContextPsiClass().equals(variableClass)) { + myResult = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element)); + return; + } + else { + // the expression references final var outside the context's class (in some of the outer classes) + int iterationCount = 0; + PsiClass aClass = getOuterClass(getContextPsiClass()); + while (aClass != null && !aClass.equals(variableClass)) { + iterationCount++; + aClass = getOuterClass(aClass); + } + if (aClass != null) { + if(psiVar.getInitializer() != null) { + Object value = psiVar.getManager().getConstantEvaluationHelper().computeConstantExpression(psiVar.getInitializer()); + if(value != null) { + myResult = new LiteralEvaluator(value, psiVar.getType().getCanonicalText()); + return; + } + } + Evaluator objectEvaluator = new ThisEvaluator(iterationCount); + myResult = new FieldEvaluator(objectEvaluator, getContextPsiClass().getQualifiedName(), "val$" + localName); + return; + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Local variable '" + localName + "' not found in class closure")); + } + } + } + else if (element instanceof PsiField) { + PsiField psiField = (PsiField)element; + PsiClass fieldClass = psiField.getContainingClass(); + if(fieldClass == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Cannot resolve class for the field : " + psiField.getName())); + } + Evaluator objectEvaluator; + if (psiField.hasModifierProperty(PsiModifier.STATIC)) { + objectEvaluator = new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(fieldClass)); + } + else if(qualifier != null) { + qualifier.accept(this); + objectEvaluator = myResult; + } + else if (fieldClass.equals(getContextPsiClass()) || getContextPsiClass().isInheritor(fieldClass, true)) { + objectEvaluator = new ThisEvaluator(); + } + else { // myContextPsiClass != fieldClass && myContextPsiClass is not a subclass of fieldClass + int iterationCount = 0; + PsiClass aClass = getContextPsiClass(); + while (aClass != null && !(aClass.equals(fieldClass) || aClass.isInheritor(fieldClass, true))) { + iterationCount++; + aClass = getOuterClass(aClass); + } + if (aClass == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Cannot find field's class sources for '" + psiField.getName() + "'")); + } + objectEvaluator = new ThisEvaluator(iterationCount); + } + myResult = new FieldEvaluator(objectEvaluator, fieldClass.getQualifiedName(), psiField.getName()); + } else { + //let's guess what this could be + PsiElement nameElement = expression.getReferenceNameElement(); // get "b" part + String name; + if (nameElement instanceof PsiIdentifier) { + name = nameElement.getText(); + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Identifier expected instead of '" + (nameElement != null ? nameElement.getText() : "(null)") + "'")); + } + + if(qualifier != null) { + if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass) { + // this is a call to a 'static' field + PsiClass psiClass = (PsiClass)((PsiReferenceExpression)qualifier).resolve(); + myResult = new FieldEvaluator(new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(psiClass)), psiClass.getQualifiedName(), name); + } + else { + PsiType type = qualifier.getType(); + if(type == null) + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Type is unknown for '" + qualifier.getText() + "'")); + + qualifier.accept(this); + if (myResult == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Cannot evaluate qualifier " + qualifier.getText())); + } + + myResult = new FieldEvaluator(myResult, type.getCanonicalText(), name); + } + } else { + myResult = new LocalVariableEvaluator(name, false); + } + } + } + + public void visitSuperExpression(PsiSuperExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitSuperExpression " + expression); + } + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("'super' is not supported")); + } + + public void visitThisExpression(PsiThisExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitThisExpression " + expression); + } + PsiJavaCodeReferenceElement qualifier = expression.getQualifier(); + int iterationCount = 0; + if (qualifier != null) { + PsiElement targetClass = qualifier.resolve(); + if (targetClass == null || getContextPsiClass() == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(qualifier.getText())); + } + try { + PsiClass aClass = getContextPsiClass(); + while (aClass != null && !aClass.equals(targetClass)) { + iterationCount++; + aClass = getOuterClass(aClass); + } + } + catch (Exception e) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(e)); + } + } + myResult = new ThisEvaluator(iterationCount); + } + + public void visitInstanceOfExpression(PsiInstanceOfExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitInstanceOfExpression " + expression); + } + PsiTypeElement checkType = expression.getCheckType(); + if(checkType == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + PsiType type = checkType.getType(); + if (type == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(expression.getCheckType().getText())); + } + expression.getOperand().accept(this); +// ClassObjectEvaluator typeEvaluator = new ClassObjectEvaluator(type.getCanonicalText()); + Evaluator operandEvaluator = myResult; + myResult = new InstanceofEvaluator(operandEvaluator, new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(type))); + } + + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitParenthesizedExpression " + expression); + } + PsiExpression expr = expression.getExpression(); + if (expr != null){ + expr.accept(this); + } + } + + public void visitPostfixExpression(PsiPostfixExpression expression) { + expression.getOperand().accept(this); + PsiType type = expression.getType(); + if(type == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(expression.getText())); + } + myResult = new PostfixOperationEvaluator(myResult, expression.getOperationSign().getTokenType(), type.getCanonicalText()); + } + + public void visitPrefixExpression(PsiPrefixExpression expression) { + PsiType type = expression.getType(); + if(type == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.UNKNOWN_TYPE(expression.getText())); + } + + expression.getOperand().accept(this); + Evaluator operand = myResult; + + IElementType tokenType = expression.getOperationSign().getTokenType(); + IElementType opType = expression.getOperationSign().getTokenType(); + + if(tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS) { + boolean isPlus = tokenType == JavaTokenType.PLUSPLUS; + + try { + PsiElementFactory elementFactory = expression.getManager().getElementFactory(); + PsiExpression one = elementFactory.createExpressionFromText("1", null); + one.accept(this); + BinaryExpressionEvaluator operationEvaluator = new BinaryExpressionEvaluator(operand, myResult, isPlus ? JavaTokenType.PLUS : JavaTokenType.MINUS, type.getCanonicalText()); + + myResult = new AssignmentEvaluator(operand, operationEvaluator); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + else { + myResult = new UnaryExpressionEvaluator(opType, expression.getType().getCanonicalText(), operand); + } + } + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + if (LOG.isDebugEnabled()) { + LOG.debug("visitMethodCallExpression " + expression); + } + PsiExpression[] argExpressions = expression.getArgumentList().getExpressions(); + List argumentEvaluators = new ArrayList(argExpressions.length); + // evaluate arguments + for (int idx = 0; idx < argExpressions.length; idx++) { + PsiExpression psiExpression = argExpressions[idx]; + psiExpression.accept(this); + if (myResult == null) { + // cannot build evaluator + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(psiExpression.getText())); + } + argumentEvaluators.add(myResult); + } + PsiReferenceExpression methodExpr = expression.getMethodExpression(); + if(methodExpr == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + PsiMethod psiMethod = (PsiMethod)methodExpr.resolve(); + + PsiExpression qualifier = methodExpr.getQualifierExpression(); + Evaluator objectEvaluator; + JVMName contextClass; + + if(psiMethod != null) { + PsiClass methodPsiClass = psiMethod.getContainingClass(); + contextClass = JVMNameUtil.getJVMQualifiedName(methodPsiClass); + if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) { + objectEvaluator = new TypeEvaluator(contextClass); + } + else if (qualifier != null ){ + qualifier.accept(this); + objectEvaluator = myResult; + } + else if (methodPsiClass.equals(getContextPsiClass()) || (getContextPsiClass() != null && getContextPsiClass().isInheritor(methodPsiClass, true))) { + objectEvaluator = new ThisEvaluator(); + } + else { + int iterationCount = 0; + PsiClass aClass = getContextPsiClass(); + while (aClass != null && !aClass.equals(methodPsiClass)) { + iterationCount++; + aClass = getOuterClass(aClass); + } + objectEvaluator = new ThisEvaluator(iterationCount); + } + } else { + //trying to guess + if (qualifier != null) { + PsiType type = qualifier.getType(); + if(type == null) + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Type is unknown for '" + qualifier.getText() + "'")); + + contextClass = JVMNameUtil.getJVMQualifiedName(type); + + if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass) { + // this is a call to a 'static' method + objectEvaluator = new TypeEvaluator(contextClass); + } else { + qualifier.accept(this); + objectEvaluator = myResult; + } + } else { + objectEvaluator = new ThisEvaluator(); + if(myContextPsiClass != null) { + contextClass = JVMNameUtil.getJVMQualifiedName(myContextPsiClass); + } else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Method " + methodExpr.getReferenceName() + " not found")); + } + } + } + + if (objectEvaluator == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + + try { + myResult = new MethodEvaluator(objectEvaluator, contextClass, methodExpr.getReferenceName(), psiMethod != null ? JVMNameUtil.getJVMSignature(psiMethod) : null, argumentEvaluators); + } + catch (EvaluateException e) { + throw new EvaluateRuntimeException(e); + } + } + + public void visitLiteralExpression(PsiLiteralExpression expression) { + Object value = expression.getValue(); + if(expression.getParsingError() != null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(expression.getParsingError())); + } + myResult = new LiteralEvaluator(value, expression.getType().getCanonicalText()); + } + + public void visitArrayAccessExpression(PsiArrayAccessExpression expression) { + if(expression.getIndexExpression() == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + expression.getIndexExpression().accept(this); + Evaluator indexEvaluator = myResult; + expression.getArrayExpression().accept(this); + Evaluator arrayEvaluator = myResult; + myResult = new ArrayAccessEvaluator(arrayEvaluator, indexEvaluator); + } + + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + expression.getOperand().accept(this); + PsiType castType = expression.getCastType().getType(); + myResult = new TypeCastEvaluator(myResult, castType.getCanonicalText(), castType instanceof PsiPrimitiveType); + } + + public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { + PsiType type = expression.getOperand().getType(); + PsiClass psiClass = PsiUtil.resolveClassInType(type); + if (psiClass == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Cannot resolve class \""+type.getCanonicalText()+"\"")); + } + myResult = new ClassObjectEvaluator(new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(psiClass))); + } + + public void visitNewExpression(PsiNewExpression expression) { + PsiType expressionPsiType = expression.getType(); + if (expressionPsiType instanceof PsiArrayType) { + Evaluator dimensionEvaluator = null; + PsiExpression[] dimensions = expression.getArrayDimensions(); + if (dimensions.length == 1){ + PsiExpression dimensionExpression = dimensions[0]; + dimensionExpression.accept(this); + if (myResult != null) { + dimensionEvaluator = myResult; + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Invalid expression for array dimension: " + dimensionExpression.getText())); + } + } + else if (dimensions.length > 1){ + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Multi-dimensional arrays new is not supported")); + } + + Evaluator initializerEvaluator = null; + PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer(); + if (arrayInitializer != null) { + if (dimensionEvaluator != null) { // initializer already exists + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + arrayInitializer.accept(this); + if (myResult != null) { + initializerEvaluator = myResult; + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(arrayInitializer.getText())); + } + /* + PsiExpression[] initializers = arrayInitializer.getInitializers(); + initializerEvaluators = new Evaluator[initializers.length]; + for (int idx = 0; idx < initializers.length; idx++) { + PsiExpression initializer = initializers[idx]; + initializer.accept(this); + if (myResult instanceof Evaluator) { + initializerEvaluators[idx] = myResult; + } + else { + throw new EvaluateException("Invalid expression for array initializer: " + initializer.getText(), true); + } + } + */ + } + if (dimensionEvaluator == null && initializerEvaluator == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + myResult = new NewArrayInstanceEvaluator( + new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)), + dimensionEvaluator, + initializerEvaluator + ); + } + else { // must be a class ref + LOG.assertTrue(expressionPsiType instanceof PsiClassType); + PsiClass aClass = ((PsiClassType)expressionPsiType).resolve(); + if(aClass instanceof PsiAnonymousClass) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException("Anonymous class evaluation is not supported")); + } + PsiExpressionList argumentList = expression.getArgumentList(); + if (argumentList == null) { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(expression.getText())); + } + PsiExpression[] argExpressions = argumentList.getExpressions(); + PsiMethod constructor = expression.resolveConstructor(); + if (constructor == null && argExpressions.length > 0) { + throw new EvaluateRuntimeException(new EvaluateException("Cannot resolve constructor '" + expression.getText() + "'", null)); + } + Evaluator[] argumentEvaluators = new Evaluator[argExpressions.length]; + // evaluate arguments + for (int idx = 0; idx < argExpressions.length; idx++) { + PsiExpression argExpression = argExpressions[idx]; + argExpression.accept(this); + if (myResult != null) { + argumentEvaluators[idx] = myResult; + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(argExpression.getText())); + } + } + try { + JVMName signature = (constructor != null)? JVMNameUtil.getJVMSignature(constructor) : JVMNameUtil.getJVMRawText("()V"); + myResult = new NewClassInstanceEvaluator( + new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)), + signature, + argumentEvaluators + ); + } + catch (EvaluateException e) { + throw new EvaluateRuntimeException(e); + } + } + } + + public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { + PsiExpression[] initializers = expression.getInitializers(); + Evaluator[] evaluators = new Evaluator[initializers.length]; + for (int idx = 0; idx < initializers.length; idx++) { + PsiExpression initializer = initializers[idx]; + initializer.accept(this); + if (myResult != null) { + evaluators[idx] = myResult; + } + else { + throw new EvaluateRuntimeException(EvaluateExceptionUtil.INVALID_EXPRESSION(initializer.getText())); + } + } + myResult = new ArrayInitializerEvaluator(evaluators); + } + + private PsiClass getOuterClass(PsiClass aClass) { + if(aClass == null) return null; + return PsiTreeUtil.getContextOfType(aClass, PsiClass.class, true); + } + + private PsiClass getContainingClass(PsiVariable variable) { + PsiElement element = PsiTreeUtil.getParentOfType(variable.getParent(), PsiClass.class, false); + return element == null ? getContextPsiClass() : (PsiClass)element; + } + + public PsiClass getContextPsiClass() { + return myContextPsiClass; + } + + protected ExpressionEvaluator buildElement(final PsiElement element) throws EvaluateException { + LOG.assertTrue(element.isValid()); + + myContextPsiClass = PsiTreeUtil.getContextOfType(element, PsiClass.class, false); + try { + element.accept(this); + } + catch (EvaluateRuntimeException e) { + throw e.getCause(); + } + if (myResult == null) { + throw EvaluateExceptionUtil.INVALID_EXPRESSION(element.toString()); + } + return new ExpressionEvaluatorImpl(myResult); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java new file mode 100644 index 00000000000..078833e3ea3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java @@ -0,0 +1,65 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.Value; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jul 15, 2003 + * Time: 1:44:35 PM + * To change this template use Options | File Templates. + */ +class ExpressionEvaluatorImpl implements ExpressionEvaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator"); + Evaluator myEvaluator; + Value myValue; + + public ExpressionEvaluatorImpl(Evaluator evaluator) { + myEvaluator = evaluator; + } + + //call evaluate before + public Value getValue() { + return myValue; + } + + //call evaluate before + public Modifier getModifier() { + return myEvaluator.getModifier(); + } + + // EvaluationContextImpl should be at the same stackFrame as it was in the call to EvaluatorBuilderImpl.build + public Value evaluate(final EvaluationContext context) throws EvaluateException { + if (!context.getDebugProcess().isAttached()) { + throw EvaluateExceptionUtil.createEvaluateException("VM disconnected"); + } + try { + if (context.getFrameProxy() == null) { + throw EvaluateExceptionUtil.NULL_STACK_FRAME; + } + + Object value = myEvaluator.evaluate((EvaluationContextImpl)context); + + if(value != null && !(value instanceof Value)) { + throw EvaluateExceptionUtil.INVALID_EXPRESSION(""); + } + + myValue = (Value) value; + return (Value) value; + } + catch (Throwable/*IncompatibleThreadStateException*/ e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + if(e instanceof EvaluateException) + throw ((EvaluateException)e); + else + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/FieldEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/FieldEvaluator.java new file mode 100644 index 00000000000..81996b86a2b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/FieldEvaluator.java @@ -0,0 +1,163 @@ +/* + * Class FieldEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl; +import com.intellij.openapi.project.Project; +import com.sun.jdi.*; + +import java.util.Iterator; + +class FieldEvaluator implements Evaluator { + private Evaluator myObjectEvaluator; + private String myClassName; + private String myFieldName; + private Object myEvaluatedQualifier; + private Field myEvaluatedField; + + public FieldEvaluator(Evaluator objectEvaluator, String contextClass, String fieldName) { + myObjectEvaluator = objectEvaluator; + myClassName = contextClass; + myFieldName = fieldName; + } + + private Field findField(Type t) { + if(t instanceof ClassType) { + ClassType cls = (ClassType) t; + if(cls.name().equals(myClassName)) { + return cls.fieldByName(myFieldName); + } else { + Field field; + for (Iterator iterator = cls.interfaces().iterator(); iterator.hasNext();) { + InterfaceType interfaceType = (InterfaceType) iterator.next(); + field = findField(interfaceType); + if(field != null) return field; + } + return findField(cls.superclass()); + } + } else if(t instanceof InterfaceType) { + InterfaceType iface = (InterfaceType) t; + if(iface.name().equals(myClassName)) { + return iface.fieldByName(myFieldName); + } else { + Field field; + for (Iterator iterator = iface.superinterfaces().iterator(); iterator.hasNext();) { + InterfaceType interfaceType = (InterfaceType) iterator.next(); + field = findField(interfaceType); + if(field != null) return field; + } + } + } else if(t instanceof ObjectReference) { + return findField(((ObjectReference) t).referenceType()); + } + + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + myEvaluatedField = null; + myEvaluatedQualifier = null; + Object object = myObjectEvaluator.evaluate(context); + + return evaluateField(object, context); + + } + + private Object evaluateField(Object object, EvaluationContextImpl context) throws EvaluateException { + if (object instanceof ReferenceType) { + ReferenceType refType = (ReferenceType)object; + Field field = findField(refType); + if (field == null || !field.isStatic()) { + field = refType.fieldByName(myFieldName); + } + if (field == null || !field.isStatic()) { + throw EvaluateExceptionUtil.createEvaluateException("No such static field: " + myFieldName); + } + myEvaluatedField = field; + myEvaluatedQualifier = refType; + return refType.getValue(field); + } + + if (object instanceof ObjectReference) { + ObjectReference objRef = (ObjectReference)object; + ReferenceType refType = objRef.referenceType(); + if (!(refType instanceof ClassType || refType instanceof ArrayType)) { + throw EvaluateExceptionUtil.createEvaluateException("Class or array type expected while evaluating field : " + myFieldName); + } + + // expressions like 'array.length' must be treated separately + if (objRef instanceof ArrayReference && "length".equals(myFieldName)) { + return DebuggerUtilsEx.createValue( + context.getDebugProcess().getVirtualMachineProxy(), + "int", + ((ArrayReference)objRef).length() + ); + } + + Field field = findField(refType); + if (field == null) { + field = refType.fieldByName(myFieldName); + } + + if (field == null) { + throw EvaluateExceptionUtil.createEvaluateException("No such non-static field: " + myFieldName); + } + myEvaluatedQualifier = field.isStatic()? (Object)refType : (Object)objRef; + myEvaluatedField = field; + return field.isStatic()? refType.getValue(field) : objRef.getValue(field); + } + + if(object == null) { + throw EvaluateExceptionUtil.createEvaluateException(new NullPointerException()); + } + + throw EvaluateExceptionUtil.createEvaluateException("Error evaluating field : " + myFieldName); + } + + public Modifier getModifier() { + Modifier modifier = null; + if (myEvaluatedField != null && (myEvaluatedQualifier instanceof ClassType || myEvaluatedQualifier instanceof ObjectReference)) { + modifier = new Modifier() { + public boolean canInspect() { + return myEvaluatedQualifier instanceof ObjectReference; + } + + public boolean canSetValue() { + return true; + } + + public void setValue(Value value) throws ClassNotLoadedException, InvalidTypeException { + if (myEvaluatedQualifier instanceof ReferenceType) { + ClassType classType = (ClassType)myEvaluatedQualifier; + classType.setValue(myEvaluatedField, value); + } + else { + ObjectReference objRef = (ObjectReference)myEvaluatedQualifier; + objRef.setValue(myEvaluatedField, value); + } + } + + public Type getExpectedType() throws ClassNotLoadedException { + return myEvaluatedField.type(); + } + + public NodeDescriptorImpl getInspectItem(Project project) { + if(myEvaluatedQualifier instanceof ObjectReference) { + return new FieldDescriptorImpl(project, (ObjectReference)myEvaluatedQualifier, myEvaluatedField); + } else + return null; + } + }; + } + return modifier; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java new file mode 100644 index 00000000000..92e6f6f0b8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java @@ -0,0 +1,82 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.util.Comparing; +import com.sun.jdi.BooleanValue; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 5:03:47 PM + * To change this template use File | Settings | File Templates. + */ +public class ForStatementEvaluator implements Evaluator { + private final Evaluator myInitializationEvaluator; + private final Evaluator myConditionEvaluator; + private final Evaluator myUpdateEvaluator; + private final Evaluator myBodyEvaluator; + + private Modifier myModifier; + private String myLabelName; + + public ForStatementEvaluator(Evaluator initializationEvaluator, Evaluator conditionEvaluator, Evaluator updateEvaluator, Evaluator bodyEvaluator, String labelName) { + myInitializationEvaluator = initializationEvaluator; + myConditionEvaluator = conditionEvaluator; + myUpdateEvaluator = updateEvaluator; + myBodyEvaluator = bodyEvaluator; + myLabelName = labelName; + } + + public Modifier getModifier() { + return myModifier; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + if(myInitializationEvaluator != null) { + value = myInitializationEvaluator.evaluate(context); + myModifier = myInitializationEvaluator.getModifier(); + } + + for (;;) { + if(myConditionEvaluator != null) { + value = myConditionEvaluator.evaluate(context); + myModifier = myConditionEvaluator.getModifier(); + if(!(value instanceof BooleanValue)) { + throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; + } else { + if(!((BooleanValue)value).booleanValue()) { + break; + } + } + } + + try { + myBodyEvaluator.evaluate(context); + } + catch (BreakException e) { + if(Comparing.equal(e.getLabelName(), myLabelName)) { + break; + } else + throw e; + } + catch (ContinueException e) { + if(Comparing.equal(e.getLabelName(), myLabelName)) { + //continue; + } else + throw e; + } + + if(myUpdateEvaluator != null) { + value = myUpdateEvaluator.evaluate(context); + myModifier = myUpdateEvaluator.getModifier(); + } + } + + return value; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java new file mode 100644 index 00000000000..cc8188a0e20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java @@ -0,0 +1,55 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.BooleanValue; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 5:03:47 PM + * To change this template use File | Settings | File Templates. + */ +public class IfStatementEvaluator implements Evaluator { + private final Evaluator myConditionEvaluator; + private final Evaluator myThenEvaluator; + private final Evaluator myElseEvaluator; + + private Modifier myModifier; + + public IfStatementEvaluator(Evaluator conditionEvaluator, Evaluator thenEvaluator, Evaluator elseEvaluator) { + myConditionEvaluator = conditionEvaluator; + myThenEvaluator = thenEvaluator; + myElseEvaluator = elseEvaluator; + } + + public Modifier getModifier() { + return myModifier; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object value = myConditionEvaluator.evaluate(context); + if(!(value instanceof BooleanValue)) { + throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; + } else { + if(((BooleanValue)value).booleanValue()) { + value = myThenEvaluator.evaluate(context); + myModifier = myThenEvaluator.getModifier(); + } + else { + if(myElseEvaluator != null) { + value = myElseEvaluator.evaluate(context); + myModifier = myElseEvaluator.getModifier(); + } else { + value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + myModifier = null; + } + } + } + return value; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectArrayItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectArrayItem.java new file mode 100644 index 00000000000..1160b4b35fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectArrayItem.java @@ -0,0 +1,13 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.sun.jdi.ArrayReference; + +/** + * User: lex + * Date: Oct 16, 2003 + * Time: 2:44:38 PM + */ +public interface InspectArrayItem extends InspectEntity{ + ArrayReference getArray (); + int getItemIndex(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectEntity.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectEntity.java new file mode 100644 index 00000000000..5e5454a5954 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectEntity.java @@ -0,0 +1,9 @@ +package com.intellij.debugger.engine.evaluation.expression; + +/** + * User: lex + * Date: Oct 15, 2003 + * Time: 11:38:02 PM + */ +public interface InspectEntity { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectField.java new file mode 100644 index 00000000000..41c19865c2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectField.java @@ -0,0 +1,14 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.sun.jdi.Field; +import com.sun.jdi.ObjectReference; + +/** + * User: lex + * Date: Oct 15, 2003 + * Time: 11:38:25 PM + */ +public interface InspectField extends InspectEntity{ + ObjectReference getObject(); + Field getField (); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectLocal.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectLocal.java new file mode 100644 index 00000000000..6e75cb4c603 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InspectLocal.java @@ -0,0 +1,16 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.sun.jdi.LocalVariable; + +/** + * User: lex + * Date: Oct 15, 2003 + * Time: 11:39:04 PM + * + * todo [lex] does this interface really required? + */ +public interface InspectLocal extends InspectEntity{ + StackFrameProxyImpl getStackFrame(); + LocalVariable getLocal (); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InstanceofEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InstanceofEvaluator.java new file mode 100644 index 00000000000..7847b0140f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/InstanceofEvaluator.java @@ -0,0 +1,58 @@ +/* + * Class InstanceofEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiType; +import com.sun.jdi.*; + +import java.util.LinkedList; +import java.util.List; + +class InstanceofEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.InstanceofEvaluator"); + private Evaluator myOperandEvaluator; + private TypeEvaluator myTypeEvaluator; + + public InstanceofEvaluator(Evaluator operandEvaluator, TypeEvaluator typeEvaluator) { + myOperandEvaluator = operandEvaluator; + myTypeEvaluator = typeEvaluator; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value value = (Value)myOperandEvaluator.evaluate(context); + if (value == null) { + return DebuggerUtilsEx.createValue(context.getDebugProcess().getVirtualMachineProxy(), PsiType.BOOLEAN.getPresentableText(), false); + } + if (!(value instanceof ObjectReference)) { + throw EvaluateExceptionUtil.createEvaluateException("Object reference expected"); + } + try { + ReferenceType refType = (ReferenceType)myTypeEvaluator.evaluate(context); + ClassObjectReference classObject = refType.classObject(); + ClassType classRefType = (ClassType)classObject.referenceType(); + Method method = classRefType.concreteMethodByName("isAssignableFrom", "(Ljava/lang/Class;)Z"); + List args = new LinkedList(); + args.add(((ObjectReference)value).referenceType().classObject()); + return context.getDebugProcess().invokeMethod(context, classObject, method, args); + } + catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java new file mode 100644 index 00000000000..0bc609981cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java @@ -0,0 +1,46 @@ +/* + * Class LiteralEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +class LiteralEvaluator implements Evaluator { + private Object myValue; + private String myExpectedType; + + public LiteralEvaluator(Object value, String expectedType) { + myValue = value; + myExpectedType = expectedType; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + if (myValue == null) { + return null; + } + VirtualMachineProxyImpl vm = context.getDebugProcess().getVirtualMachineProxy(); + if (myValue instanceof Boolean) { + return DebuggerUtilsEx.createValue(vm, myExpectedType, ((Boolean)myValue).booleanValue()); + } + if (myValue instanceof Character) { + return DebuggerUtilsEx.createValue(vm, myExpectedType, ((Character)myValue).charValue()); + } + if (myValue instanceof Number) { + return DebuggerUtilsEx.createValue(vm, myExpectedType, ((Number)myValue).doubleValue()); + } + if (myValue instanceof String) { + return DebuggerUtilsEx.createValue(vm, (String)myValue); + } + throw EvaluateExceptionUtil.UNKNOWN_TYPE(myExpectedType); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java new file mode 100644 index 00000000000..e9bf01de645 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java @@ -0,0 +1,107 @@ +/* + * Class LocalVariableEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.Type; +import com.sun.jdi.Value; + +class LocalVariableEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.LocalVariableEvaluator"); + + private String myLocalVariableName; + private EvaluationContextImpl myContext; + private LocalVariableProxyImpl myEvaluatedVariable; + private boolean myIsJspSpecial; + + public LocalVariableEvaluator(String localVariableName, boolean isJspSpecial) { + myLocalVariableName = localVariableName; + myIsJspSpecial = isJspSpecial; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + StackFrameProxyImpl frameProxy = context.getFrameProxy(); + if (frameProxy == null) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot evaluate: stack frame unavaulable"); + } + + try { + for(;;) { + LocalVariableProxyImpl local = frameProxy.visibleVariableByName(myLocalVariableName); + if (local != null) { + myEvaluatedVariable = local; + myContext = context; + return frameProxy.getValue(local); + } + + ThreadReferenceProxyImpl threadProxy = frameProxy.threadProxy(); + if(myIsJspSpecial && frameProxy.getFrameIndex() < threadProxy.frameCount() - 1) { + if(frameProxy.getFrameIndex() < threadProxy.frameCount() - 1) { + frameProxy = threadProxy.frame(frameProxy.getFrameIndex() + 1); + continue; + } + } + + break; + } + throw EvaluateExceptionUtil.createEvaluateException("Cannot find local variable '" + myLocalVariableName + "'"); + } + catch (EvaluateException e) { + myEvaluatedVariable = null; + myContext = null; + throw e; + } + } + + public Modifier getModifier() { + Modifier modifier = null; + if (myEvaluatedVariable != null && myContext != null) { + modifier = new Modifier() { + public boolean canInspect() { + return true; + } + + public boolean canSetValue() { + return true; + } + + public void setValue(Value value) throws ClassNotLoadedException, InvalidTypeException { + StackFrameProxyImpl frameProxy = myContext.getFrameProxy(); + try { + frameProxy.setValue(myEvaluatedVariable, value); + } + catch (EvaluateException e) { + LOG.error(e); + } + } + + public Type getExpectedType() throws ClassNotLoadedException { + try { + return myEvaluatedVariable.getVariable().type(); + } catch (EvaluateException e) { + LOG.error(e); + return null; + } + } + + public NodeDescriptorImpl getInspectItem(Project project) { + return new LocalVariableDescriptorImpl(project, myEvaluatedVariable); + } + }; + } + return modifier; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MapStack.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MapStack.java new file mode 100644 index 00000000000..1c5f3a4546f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MapStack.java @@ -0,0 +1,59 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.openapi.diagnostic.Logger; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 24, 2004 + * Time: 10:36:12 PM + * To change this template use File | Settings | File Templates. + */ +public class MapStack { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.MapStack"); + + private final LinkedList> myStack; + + public MapStack() { + myStack = new LinkedList>(); + push(); + } + + public void push(){ + myStack.addFirst(new HashMap()); + } + + public void pop(){ + myStack.removeFirst(); + LOG.assertTrue(myStack.size() > 0); + } + + private HashMap current() { + return myStack.getFirst(); + } + + public void put(Key key, Value value) { + current().put(key, value); + } + + public boolean containsKey(Key key){ + for (Iterator> iterator = myStack.iterator(); iterator.hasNext();) { + HashMap hashMap = iterator.next(); + if(hashMap.containsKey(key))return true; + } + return false; + } + + public Value get(Key key) { + for (Iterator> iterator = myStack.iterator(); iterator.hasNext();) { + HashMap hashMap = iterator.next(); + Value value = hashMap.get(key); + if(value != null) return value; + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java new file mode 100644 index 00000000000..ce421a0a7f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java @@ -0,0 +1,103 @@ +/* + * Class MethodEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JVMName; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.diagnostic.Logger; +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.Iterator; +import java.util.List; + +class MethodEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.MethodEvaluator"); + private JVMName myClassName; + private JVMName myMethodSignature; + private String myMethodName; + private List myArgumentEvaluators; + private Evaluator myObjectEvaluator; + + public MethodEvaluator(Evaluator objectEvaluator, JVMName className, String methodName, JVMName signature, List argumentEvaluators) { + myObjectEvaluator = objectEvaluator; + myClassName = className; + myMethodName = methodName; + myMethodSignature = signature; + myArgumentEvaluators = argumentEvaluators; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + if(!context.getDebugProcess().isAttached()) return null; + DebugProcessImpl debugProcess = context.getDebugProcess(); + Object object = myObjectEvaluator.evaluate(context); + if (LOG.isDebugEnabled()) { + LOG.debug("MethodEvaluator: object = " + object); + } + if(object == null) { + throw EvaluateExceptionUtil.createEvaluateException(new NullPointerException()); + } + if (!(object instanceof ObjectReference || object instanceof ClassType)) { + throw EvaluateExceptionUtil.createEvaluateException("Error evaluating method : " + myMethodName); + } + List args = new ArrayList(myArgumentEvaluators.size()); + for (Iterator it = myArgumentEvaluators.iterator(); it.hasNext();) { + Evaluator evaluator = (Evaluator)it.next(); + args.add(evaluator.evaluate(context)); + } + try { + String className = myClassName.getName(debugProcess); + ReferenceType referenceType; + + if(object instanceof ObjectReference) { + referenceType = (ReferenceType)DebuggerUtilsEx.getSuperType(((ObjectReference)object).referenceType(), className); + } else if(object instanceof ClassType) { + referenceType = (ReferenceType)DebuggerUtilsEx.getSuperType((ClassType)object, className); + } else { + referenceType = debugProcess.findClass(context, className, context.getClassLoader()); + } + + if (object instanceof ClassType) { + if(referenceType instanceof ClassType) { + Method jdiMethod; + if(myMethodSignature != null) { + jdiMethod = ((ClassType)referenceType).concreteMethodByName(myMethodName, myMethodSignature.getName(debugProcess)); + } else { + List list = referenceType.methodsByName(myMethodName); + jdiMethod = (Method)(list.size() > 0 ? list.get(0) : null); + } + if (jdiMethod != null && jdiMethod.isStatic()) { + return debugProcess.invokeMethod(context, (ClassType)referenceType, jdiMethod, args); + } + } + throw EvaluateExceptionUtil.createEvaluateException("No such static method: " + DebuggerUtilsEx.methodName(referenceType.name(), myMethodName, myMethodSignature != null ? myMethodSignature.getName(debugProcess) : null)); + } + // object should be ObjectReference + ObjectReference objRef = (ObjectReference)object; + Method jdiMethod = DebuggerUtilsEx.findMethod(referenceType, myMethodName, myMethodSignature != null ? myMethodSignature.getName(debugProcess) : null); + if (jdiMethod == null) { + throw EvaluateExceptionUtil.createEvaluateException("No such non-static method: " + DebuggerUtilsEx.methodName(referenceType.name(), myMethodName, myMethodSignature != null ? myMethodSignature.getName(debugProcess) : null)); + } + return debugProcess.invokeMethod(context, objRef, jdiMethod, args); + } + catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewArrayInstanceEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewArrayInstanceEvaluator.java new file mode 100644 index 00000000000..7149612b59d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewArrayInstanceEvaluator.java @@ -0,0 +1,135 @@ +/** + * class NewArrayInstanceEvaluator + * created Jun 27, 2001 + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.*; + +import java.util.ArrayList; +import java.util.List; + +class NewArrayInstanceEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.NewArrayInstanceEvaluator"); + private Evaluator myArrayTypeEvaluator; + private Evaluator myDimensionEvaluator = null; + private Evaluator myInitializerEvaluator = null; + + /** + * either dimensionEvaluator or initializerEvaluators must be null! + */ + public NewArrayInstanceEvaluator(Evaluator arrayTypeEvaluator, Evaluator dimensionEvaluator, Evaluator initializerEvaluator) { + myArrayTypeEvaluator = arrayTypeEvaluator; + myDimensionEvaluator = dimensionEvaluator; + myInitializerEvaluator = initializerEvaluator; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { +// throw new EvaluateException("Creating new array instances is not supported yet", true); + DebugProcessImpl debugProcess = context.getDebugProcess(); + Object obj = myArrayTypeEvaluator.evaluate(context); + if (!(obj instanceof ArrayType)) { + throw EvaluateExceptionUtil.createEvaluateException("Array type expected"); + } + ArrayType arrayType = (ArrayType)obj; + int dimension; + Object[] initialValues = null; + if (myDimensionEvaluator != null) { + Object o = myDimensionEvaluator.evaluate(context); + if (!(o instanceof Value && DebuggerUtilsEx.isNumeric((Value)o))) { + throw EvaluateExceptionUtil.createEvaluateException("Invalid array dimension expression"); + } + PrimitiveValue value = (PrimitiveValue)o; + dimension = value.intValue(); + } + else { // myInitializerEvaluator must not be null + Object o = myInitializerEvaluator.evaluate(context); + if (!(o instanceof Object[])) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot evaluate array initializer"); + } + initialValues = (Object[])o; + dimension = initialValues.length; + } + ArrayReference arrayReference = debugProcess.newInstance(arrayType, dimension); + if (initialValues != null && initialValues.length > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug("Setting initial values: dimension = "+dimension + "; array size is "+initialValues.length); + } + setInitialValues(arrayReference, initialValues, context); + } + return arrayReference; + } + + private void setInitialValues(ArrayReference arrayReference, Object[] values, EvaluationContextImpl context) throws EvaluateException { + ArrayType type = (ArrayType)arrayReference.referenceType(); + DebugProcessImpl debugProcess = context.getDebugProcess(); + try { + if (type.componentType() instanceof ArrayType) { + ArrayType componentType = (ArrayType)type.componentType(); + int length = arrayReference.length(); + for (int idx = 0; idx < length; idx++) { + ArrayReference componentArray = (ArrayReference)arrayReference.getValue(idx); + Object[] componentArrayValues = (Object[])values[idx]; + if (componentArray == null) { + componentArray = debugProcess.newInstance(componentType, componentArrayValues.length); + arrayReference.setValue(idx, componentArray); + } + setInitialValues(componentArray, componentArrayValues, context); + } + } + else { + if (values.length > 0) { + List list = new ArrayList(values.length); + for (int idx = 0; idx < values.length; idx++) { + list.add(values[idx]); + } + arrayReference.setValues(list); + } + } + } + catch (ClassNotLoadedException ex) { + final ReferenceType referenceType; + try { + referenceType = debugProcess.loadClass(context, ex.className(), type.classLoader()); + } + catch (InvocationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (ClassNotLoadedException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + catch (InvalidTypeException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + if (referenceType != null) { + setInitialValues(arrayReference, values, context); + } + else { + throw EvaluateExceptionUtil.createEvaluateException("Initializer's class is not loaded"); + } + } + catch (InvalidTypeException ex) { + throw EvaluateExceptionUtil.createEvaluateException("Initializer type is not assignment-compatible with array's component type"); + } + catch (IndexOutOfBoundsException ex) { + throw EvaluateExceptionUtil.createEvaluateException("Invalid array size"); + } + catch (ClassCastException ex) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot initialize array"); + } + } + + public Modifier getModifier() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java new file mode 100644 index 00000000000..35d36f4dfb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java @@ -0,0 +1,70 @@ +/** + * class NewArrayInstanceEvaluator + * created Jun 27, 2001 + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JVMName; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.sun.jdi.ClassType; +import com.sun.jdi.Method; +import com.sun.jdi.ObjectReference; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +class NewClassInstanceEvaluator implements Evaluator { + private Evaluator myClassTypeEvaluator; + private JVMName myConstructorSignature; + private Evaluator[] myParamsEvaluators; + + public NewClassInstanceEvaluator(Evaluator classTypeEvaluator, JVMName constructorSignature, Evaluator[] argumentEvaluators) { + myClassTypeEvaluator = classTypeEvaluator; + myConstructorSignature = constructorSignature; + myParamsEvaluators = argumentEvaluators; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + DebugProcessImpl debugProcess = context.getDebugProcess(); + Object obj = myClassTypeEvaluator.evaluate(context); + if (!(obj instanceof ClassType)) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot evaluate class type"); + } + ClassType classType = (ClassType)obj; + // find constructor + Method method = DebuggerUtilsEx.findMethod(classType, "", myConstructorSignature.getName(debugProcess)); + if (method == null) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot find constructor for class " + classType.name()); + } + // evaluate arguments + List arguments; + if (myParamsEvaluators != null) { + arguments = new ArrayList(myParamsEvaluators.length); + for (int idx = 0; idx < myParamsEvaluators.length; idx++) { + Evaluator evaluator = myParamsEvaluators[idx]; + arguments.add(evaluator.evaluate(context)); + } + } + else { + arguments = Collections.EMPTY_LIST; + } + ObjectReference objRef; + try { + objRef = debugProcess.newInstance(context, classType, method, arguments); + } + catch (EvaluateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + return objRef; + } + + public Modifier getModifier() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java new file mode 100644 index 00000000000..851934e3865 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java @@ -0,0 +1,45 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.sun.jdi.Value; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 5:34:50 PM + * To change this template use File | Settings | File Templates. + */ +public class PostfixOperationEvaluator implements Evaluator{ + private final Evaluator myOperandEvaluator; + private static final Evaluator myRightEvaluator = new LiteralEvaluator(new Integer(1), "byte"); + + private IElementType myOpType; + private String myExpectedType; // a result of PsiType.getCanonicalText() + + private Object myValue; + private Modifier myModifier; + + public PostfixOperationEvaluator(Evaluator operandEvaluator, IElementType opType, String expectedType) { + myOperandEvaluator = operandEvaluator; + myOpType = opType; + myExpectedType = expectedType; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + myValue = (Value)myOperandEvaluator.evaluate(context); + myModifier = myOperandEvaluator.getModifier(); + + IElementType opType = myOpType == TokenType.PLUSPLUS ? TokenType.PLUS : TokenType.MINUS; + Object operationResult = BinaryExpressionEvaluator.evaluateOperation((Value)myValue, opType, myRightEvaluator, myExpectedType, context); + AssignmentEvaluator.assign(myModifier, operationResult, context); + return myValue; + } + + public Modifier getModifier() { + return myModifier; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java new file mode 100644 index 00000000000..9eb2d82deb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java @@ -0,0 +1,58 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.sun.jdi.Type; +import com.sun.jdi.Value; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 25, 2004 + * Time: 2:53:29 PM + * To change this template use File | Settings | File Templates. + */ +public class SyntheticVariableEvaluator implements Evaluator{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.SyntheticVariableEvaluator"); + + private final CodeFragmentEvaluator myCodeFragmentEvaluator; + private final String myLocalName; + + public SyntheticVariableEvaluator(CodeFragmentEvaluator codeFragmentEvaluator, String localName) { + myCodeFragmentEvaluator = codeFragmentEvaluator; + myLocalName = localName; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + return myCodeFragmentEvaluator.getValue(myLocalName, context.getDebugProcess().getVirtualMachineProxy()); + } + + public Modifier getModifier() { + return new Modifier() { + public boolean canInspect() { + return false; + } + + public boolean canSetValue() { + return false; + } + + public void setValue(Value value) throws EvaluateException { + myCodeFragmentEvaluator.setValue(myLocalName, value); + } + + public Type getExpectedType() { + LOG.assertTrue(false); + return null; + } + + public NodeDescriptorImpl getInspectItem(Project project) { + return null; + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ThisEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ThisEvaluator.java new file mode 100644 index 00000000000..a5258cb51d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/ThisEvaluator.java @@ -0,0 +1,61 @@ +/* + * Class ThisEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.Field; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; + +import java.util.Iterator; +import java.util.List; + +class ThisEvaluator implements Evaluator { + private int myIterations; + + public ThisEvaluator() { + myIterations = 0; + } + + public ThisEvaluator(int iterations) { + myIterations = iterations; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value objRef = context.getThisObject(); + if(myIterations > 0) { + ObjectReference thisRef = (ObjectReference)objRef; + for (int idx = 0; idx < myIterations && thisRef != null; idx++) { + thisRef = getOuterObject(thisRef); + } + objRef = thisRef; + } + if(objRef == null) throw EvaluateExceptionUtil.createEvaluateException("'this' is not avalilable"); + return objRef; + } + + private static ObjectReference getOuterObject(ObjectReference objRef) { + if (objRef == null) return null; + List list = objRef.referenceType().fields(); + for (Iterator it = list.iterator(); it.hasNext();) { + Field field = (Field)it.next(); + String name = field.name(); + if (name != null && name.startsWith("this$")) { + ObjectReference rv = (ObjectReference)objRef.getValue(field); + if (rv != null) { + return rv; + } + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeCastEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeCastEvaluator.java new file mode 100644 index 00000000000..fd393b56fa9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeCastEvaluator.java @@ -0,0 +1,62 @@ +/* + * Class TypeCastEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.sun.jdi.BooleanValue; +import com.sun.jdi.CharValue; +import com.sun.jdi.PrimitiveValue; +import com.sun.jdi.Value; + +class TypeCastEvaluator implements Evaluator { + private Evaluator myOperandEvaluator; + private String myCastType; + private boolean myIsPrimitive; + + public TypeCastEvaluator(Evaluator operandEvaluator, String castType, boolean isPrimitive) { + myOperandEvaluator = operandEvaluator; + myCastType = castType; + myIsPrimitive = isPrimitive; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value value = (Value)myOperandEvaluator.evaluate(context); + if (value == null) { + if (myIsPrimitive) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot cast null to " + myCastType); + } + } + VirtualMachineProxyImpl vm = context.getDebugProcess().getVirtualMachineProxy(); + if (DebuggerUtilsEx.isNumeric(value)) { + value = DebuggerUtilsEx.createValue(vm, myCastType, ((PrimitiveValue)value).doubleValue()); + if (value == null) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot cast numeric value to " + myCastType); + } + } + else if (value instanceof BooleanValue) { + value = DebuggerUtilsEx.createValue(vm, myCastType, ((BooleanValue)value).booleanValue()); + if (value == null) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot cast boolean value to " + myCastType); + } + } + else if (value instanceof CharValue) { + value = DebuggerUtilsEx.createValue(vm, myCastType, ((CharValue)value).charValue()); + if (value == null) { + throw EvaluateExceptionUtil.createEvaluateException("Cannot cast char value to " + myCastType); + } + } + return value; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeEvaluator.java new file mode 100644 index 00000000000..83eb8708b32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/TypeEvaluator.java @@ -0,0 +1,36 @@ +/* + * Class TypeEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JVMName; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; + +class TypeEvaluator implements Evaluator { + private JVMName myTypeName; + + public TypeEvaluator(JVMName typeName) { + myTypeName = typeName; + } + + public Modifier getModifier() { + return null; + } + + /** + * @return ReferenceType in the target VM, with the given fully qualified name + */ + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + DebugProcessImpl debugProcess = context.getDebugProcess(); + String typeName = myTypeName.getName(debugProcess); + return debugProcess.findClass(context, typeName, context.getClassLoader()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/UnaryExpressionEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/UnaryExpressionEvaluator.java new file mode 100644 index 00000000000..8fd08d026d1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/UnaryExpressionEvaluator.java @@ -0,0 +1,72 @@ +/* + * Class UnaryExpressionEvaluator + * @author Jeka + */ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.sun.jdi.BooleanValue; +import com.sun.jdi.PrimitiveValue; +import com.sun.jdi.Value; + +class UnaryExpressionEvaluator implements Evaluator { + private IElementType myOperationType; + private String myExpectedType; + private Evaluator myOperandEvaluator; + + public UnaryExpressionEvaluator(IElementType operationType, String expectedType, Evaluator operandEvaluator) { + myOperationType = operationType; + myExpectedType = expectedType; + myOperandEvaluator = operandEvaluator; + } + + public Modifier getModifier() { + return null; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Value operand = (Value)myOperandEvaluator.evaluate(context); + VirtualMachineProxyImpl vm = context.getDebugProcess().getVirtualMachineProxy(); + if (myOperationType == JavaTokenType.PLUS) { + if (DebuggerUtilsEx.isNumeric(operand)) { + return operand; + } + throw EvaluateExceptionUtil.createEvaluateException("Numeric expected"); + } + else if (myOperationType == JavaTokenType.MINUS) { + if (DebuggerUtilsEx.isNumeric(operand)) { + double v = ((PrimitiveValue)operand).doubleValue(); + return DebuggerUtilsEx.createValue(vm, myExpectedType, -v); + } + throw EvaluateExceptionUtil.createEvaluateException("Numeric expected"); + } + else if (myOperationType == JavaTokenType.TILDE) { + if (DebuggerUtilsEx.isInteger(operand)) { + long v = ((PrimitiveValue)operand).longValue(); + return DebuggerUtilsEx.createValue(vm, myExpectedType, ~v); + } + throw EvaluateExceptionUtil.createEvaluateException("integer expected"); + } + else if (myOperationType == JavaTokenType.EXCL) { + if (operand instanceof BooleanValue) { + boolean v = ((BooleanValue)operand).booleanValue(); + return DebuggerUtilsEx.createValue(vm, myExpectedType, !v); + } + throw EvaluateExceptionUtil.createEvaluateException("boolean expected"); + } + else if (myOperationType == JavaTokenType.PLUSPLUS) { + throw EvaluateExceptionUtil.createEvaluateException("Prefix operation \"++\" is not supported"); + } + else if (myOperationType == JavaTokenType.MINUSMINUS) { + throw EvaluateExceptionUtil.createEvaluateException("Prefix operation \"--\" is not supported"); + } + throw EvaluateExceptionUtil.createEvaluateException("Unsupported unary expression"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java new file mode 100644 index 00000000000..653fb0d7b35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java @@ -0,0 +1,62 @@ +package com.intellij.debugger.engine.evaluation.expression; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.util.Comparing; +import com.sun.jdi.BooleanValue; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 20, 2004 + * Time: 5:03:47 PM + * To change this template use File | Settings | File Templates. + */ +public class WhileStatementEvaluator implements Evaluator { + private final Evaluator myConditionEvaluator; + private final Evaluator myBodyEvaluator; + private String myLabelName; + + public WhileStatementEvaluator(Evaluator conditionEvaluator, Evaluator bodyEvaluator, String labelName) { + myConditionEvaluator = conditionEvaluator; + myBodyEvaluator = bodyEvaluator; + myLabelName = labelName; + } + + public Modifier getModifier() { + return myConditionEvaluator.getModifier(); + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object value; + for (;;) { + value = myConditionEvaluator.evaluate(context); + if(!(value instanceof BooleanValue)) { + throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; + } else { + if(!((BooleanValue)value).booleanValue()) { + break; + } + } + try { + myBodyEvaluator.evaluate(context); + } + catch (BreakException e) { + if(Comparing.equal(e.getLabelName(), myLabelName)) { + break; + } else + throw e; + } + catch (ContinueException e) { + if(Comparing.equal(e.getLabelName(), myLabelName)) { + continue; + } else + throw e; + } + } + + return value; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerCommandImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerCommandImpl.java new file mode 100644 index 00000000000..28d0f8967e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerCommandImpl.java @@ -0,0 +1,31 @@ +package com.intellij.debugger.engine.events; + +import com.intellij.debugger.impl.InvokeAndWaitEventImpl; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 5, 2004 + * Time: 6:04:07 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class DebuggerCommandImpl extends InvokeAndWaitEventImpl { + protected abstract void action() throws Exception; + + protected void commandCancelled() { + } + + public final void notifyCancelled() { + commandCancelled(); + release(); + } + + public void run() throws Exception{ + try { + action(); + } + finally { + release(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerContextCommandImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerContextCommandImpl.java new file mode 100644 index 00000000000..5d7db83d0f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/DebuggerContextCommandImpl.java @@ -0,0 +1,53 @@ +package com.intellij.debugger.engine.events; + +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.SuspendManagerUtil; +import com.intellij.debugger.engine.SuspendManager; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.List; +import java.util.Iterator; +import java.util.Set; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public abstract class DebuggerContextCommandImpl extends SuspendContextCommandImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.events.DebuggerContextCommandImpl"); + + private final DebuggerContextImpl myDebuggerContext; + + protected DebuggerContextCommandImpl(DebuggerContextImpl debuggerContext) { + super(debuggerContext.getSuspendContext()); + myDebuggerContext = debuggerContext; + } + + public DebuggerContextImpl getDebuggerContext() { + return myDebuggerContext; + } + + public final void contextAction() throws Exception { + SuspendManager suspendManager = myDebuggerContext.getDebugProcess().getSuspendManager(); + Set suspendingContexts = SuspendManagerUtil.getSuspendingContexts(suspendManager, myDebuggerContext.getThreadProxy()); + + if(suspendingContexts.isEmpty()) { + SuspendContextImpl threadContext = SuspendManagerUtil.findContextByThread(suspendManager, myDebuggerContext.getThreadProxy()); + if(threadContext != null) { + SuspendManagerUtil.postponeCommand(threadContext, this); + } + else { + notifyCancelled(); + } + } + else { + LOG.debug("Context thread " + getSuspendContext().getThread()); + LOG.debug("Debug thread" + myDebuggerContext.getThreadProxy()); + threadAction(); + } + } + + abstract public void threadAction (); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/SuspendContextCommandImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/SuspendContextCommandImpl.java new file mode 100644 index 00000000000..26db5a31075 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/events/SuspendContextCommandImpl.java @@ -0,0 +1,45 @@ +package com.intellij.debugger.engine.events; + +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.SuspendManager; +import com.intellij.debugger.engine.SuspendManagerUtil; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.diagnostic.Logger; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 24, 2004 + * Time: 7:01:31 PM + * Performs contextAction when evaluation is available in suspend context + */ +public abstract class SuspendContextCommandImpl extends DebuggerCommandImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendContextCommand"); + private final SuspendContextImpl mySuspendContext; + + protected SuspendContextCommandImpl(SuspendContextImpl suspendContext) { + mySuspendContext = suspendContext; + } + + public abstract void contextAction() throws Exception; + + public final void action() throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("trying " + this); + } + + if (mySuspendContext == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("skip processing - context is null " + this); + } + notifyCancelled(); + return; + } + + SuspendManagerUtil.runCommand(mySuspendContext.getSuspendManager(), this); + } + + public SuspendContextImpl getSuspendContext() { + return mySuspendContext; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/LocatableEventRequestor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/LocatableEventRequestor.java new file mode 100644 index 00000000000..4122f10a6be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/LocatableEventRequestor.java @@ -0,0 +1,19 @@ +package com.intellij.debugger.engine.requests; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.requests.Requestor; +import com.sun.jdi.event.LocatableEvent; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jun 27, 2003 + * Time: 8:05:52 PM + * To change this template use Options | File Templates. + */ +public interface LocatableEventRequestor extends Requestor { + /** + * returns whether should resume + */ + boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/RequestManagerImpl.java new file mode 100644 index 00000000000..a7db296c476 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -0,0 +1,409 @@ +package com.intellij.debugger.engine.requests; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.*; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.requests.ClassPrepareRequestor; +import com.intellij.debugger.requests.RequestManager; +import com.intellij.debugger.requests.Requestor; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiClass; +import com.intellij.util.containers.HashMap; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.*; +import com.sun.jdi.event.ClassPrepareEvent; +import com.sun.jdi.request.*; + +import java.util.*; + +/** + * @author lex + * Date: May 6, 2003 + * Time: 5:32:38 PM + */ +public class RequestManagerImpl extends DebugProcessAdapterImpl implements RequestManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.RequestManagerImpl"); + + private static final Key CLASS_NAME = Key.create("ClassName"); + + private DebugProcessImpl myDebugProcess; + private HashMap myInvalidRequestors = new HashMap(); + + private Map> myRequestorToBelongedRequests = new com.intellij.util.containers.HashMap>(); + private Map myRequestsToProcessingRequestor = new HashMap(); + private EventRequestManager myEventRequestManager; + + public RequestManagerImpl(DebugProcessImpl debugProcess) { + myDebugProcess = debugProcess; + myDebugProcess.addDebugProcessListener(this); + } + + + public Set findRequests(Requestor requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if (!myRequestorToBelongedRequests.containsKey(requestor)) { + return Collections.EMPTY_SET; + } + return Collections.unmodifiableSet((Set) myRequestorToBelongedRequests.get(requestor)); + } + + public Requestor findRequestor(EventRequest request) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myRequestsToProcessingRequestor.get(request); + } + + private void addClassFilter(EventRequest request, String pattern){ + if(request instanceof AccessWatchpointRequest){ + ((AccessWatchpointRequest) request).addClassFilter(pattern); + } + else if(request instanceof ExceptionRequest){ + ((ExceptionRequest) request).addClassFilter(pattern); + } + else if(request instanceof MethodEntryRequest) { + ((MethodEntryRequest)request).addClassFilter(pattern); + } + else if(request instanceof MethodExitRequest) { + ((MethodExitRequest)request).addClassFilter(pattern); + } + else if(request instanceof ModificationWatchpointRequest) { + ((ModificationWatchpointRequest)request).addClassFilter(pattern); + } + else if(request instanceof WatchpointRequest) { + ((WatchpointRequest)request).addClassFilter(pattern); + } + } + + private void addClassExclusionFilter(EventRequest request, String pattern){ + if(request instanceof AccessWatchpointRequest){ + ((AccessWatchpointRequest) request).addClassExclusionFilter(pattern); + } + else if(request instanceof ExceptionRequest){ + ((ExceptionRequest) request).addClassExclusionFilter(pattern); + } + else if(request instanceof MethodEntryRequest) { + ((MethodEntryRequest)request).addClassExclusionFilter(pattern); + } + else if(request instanceof MethodExitRequest) { + ((MethodExitRequest)request).addClassExclusionFilter(pattern); + } + else if(request instanceof ModificationWatchpointRequest) { + ((ModificationWatchpointRequest)request).addClassExclusionFilter(pattern); + } + else if(request instanceof WatchpointRequest) { + ((WatchpointRequest)request).addClassExclusionFilter(pattern); + } + } + + private void addLocatableRequest(Breakpoint requestor, EventRequest request) { + if(DebuggerSettings.SUSPEND_ALL.equals(requestor.SUSPEND_POLICY)) { + request.setSuspendPolicy(EventRequest.SUSPEND_ALL); + } + else { + //when requestor.SUSPEND_POLICY == SUSPEND_NONE + //we should pause thread in order to evaluate conditions + request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); + } + + if (requestor.COUNT_FILTER_ENABLED) { + request.addCountFilter(requestor.COUNT_FILTER); + } + + if (requestor.CLASS_FILTERS_ENABLED) { + ClassFilter[] classFilters = requestor.getClassFilters(); + for (int idx = 0; idx < classFilters.length; idx++) { + final ClassFilter filter = classFilters[idx]; + if (!filter.isEnabled()) { + continue; + } + final JVMName jvmClassName = ApplicationManager.getApplication().runReadAction(new Computable() { + public JVMName compute() { + PsiClass psiClass = DebuggerUtilsEx.findClass(filter.getPattern(), myDebugProcess.getProject()); + if(psiClass == null) { + return null; + } + return JVMNameUtil.getJVMQualifiedName(psiClass); + } + }); + String pattern = filter.getPattern(); + try { + if(jvmClassName != null) { + pattern = jvmClassName.getName(myDebugProcess); + } + } + catch (EvaluateException e) { + } + + addClassFilter(request, pattern); + } + + final ClassFilter[] iclassFilters = requestor.getClassExclusionFilters(); + for (int idx = 0; idx < iclassFilters.length; idx++) { + ClassFilter filter = iclassFilters[idx]; + if (filter.isEnabled()) { + addClassExclusionFilter(request, filter.getPattern()); + } + } + } + + belongsToRequestor(requestor, request); + callbackOnEvent(requestor, request); + } + + private void belongsToRequestor(Requestor requestor, EventRequest request) { + Set reqSet = myRequestorToBelongedRequests.get(requestor); + if(reqSet == null) { + reqSet = new HashSet(); + myRequestorToBelongedRequests.put(requestor, reqSet); + } + reqSet.add(request); + + } + + private void callbackOnEvent(Requestor requestor, EventRequest request) { + myRequestsToProcessingRequestor.put(request, requestor); + } + + // requests creation + public ClassPrepareRequest createClassPrepareRequest(ClassPrepareRequestor requestor, String pattern) { + ClassPrepareRequest classPrepareRequest = myEventRequestManager.createClassPrepareRequest(); + classPrepareRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); + classPrepareRequest.addClassFilter(pattern); + classPrepareRequest.putProperty(CLASS_NAME, pattern); + + belongsToRequestor(requestor, classPrepareRequest); + callbackOnEvent(requestor, classPrepareRequest); + return classPrepareRequest; + } + + public ExceptionRequest createExceptionRequest(Breakpoint requestor, ReferenceType referenceType, boolean notifyCaught, boolean notifyUnCaught) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ExceptionRequest req = myEventRequestManager.createExceptionRequest(referenceType, notifyCaught, notifyUnCaught); + addLocatableRequest(requestor, req); + return req; + } + + public MethodEntryRequest createMethodEntryRequest(Breakpoint requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + MethodEntryRequest req = myEventRequestManager.createMethodEntryRequest(); + addLocatableRequest(requestor, req); + return req; + } + + public MethodExitRequest createMethodExitRequest(Breakpoint requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + MethodExitRequest req = myEventRequestManager.createMethodExitRequest(); + addLocatableRequest(requestor, req); + return req; + } + + public BreakpointRequest createBreakpointRequest(Breakpoint requestor, Location location) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + BreakpointRequest req = myEventRequestManager.createBreakpointRequest(location); + addLocatableRequest(requestor, req); + return req; + } + + public AccessWatchpointRequest createAccessWatchpointRequest(Breakpoint requestor, Field field) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + AccessWatchpointRequest req = myEventRequestManager.createAccessWatchpointRequest(field); + addLocatableRequest(requestor, req); + return req; + } + + public ModificationWatchpointRequest createModificationWatchpointRequest(Breakpoint requestor, Field field) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ModificationWatchpointRequest req = myEventRequestManager.createModificationWatchpointRequest(field); + addLocatableRequest(requestor, req); + return req; + } + + public void createRequest(Breakpoint breakpoint) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if(!myDebugProcess.isAttached() || !findRequests(breakpoint).isEmpty()) return; + breakpoint.createRequest(myDebugProcess); + } + + public void deleteRequest(Requestor requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if(!myDebugProcess.isAttached()) return; + Set requests = myRequestorToBelongedRequests.get(requestor); + if(requests == null) return; + myRequestorToBelongedRequests.remove(requestor); + for (Iterator iterator = requests.iterator(); iterator.hasNext();) { + EventRequest eventRequest = (EventRequest) iterator.next(); + myRequestsToProcessingRequestor.remove(eventRequest); + } + for (Iterator iterator = requests.iterator(); iterator.hasNext();) { + EventRequest eventRequest = (EventRequest)iterator.next(); + try { + myEventRequestManager.deleteEventRequest(eventRequest); + } catch (InternalException e) { + if(e.errorCode() == 41) { + //event request not found + //there could be no requests after hotswap + } else { + LOG.error(e); + } + } + } + } + + public void callbackOnPrepareClasses(final ClassPrepareRequestor requestor, final SourcePosition classPosition) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ClassPrepareRequest prepareRequest = myDebugProcess.getPositionManager().createPrepareRequest(requestor, classPosition); + + if(prepareRequest == null) { + setInvalid(requestor, "Breakpoint does not belong to any class"); + return; + } + + belongsToRequestor(requestor, prepareRequest); + prepareRequest.enable(); + } + + public void callbackOnPrepareClasses(ClassPrepareRequestor requestor, String classOrPatternToBeLoaded) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ClassPrepareRequest classPrepareRequest = createClassPrepareRequest(requestor, classOrPatternToBeLoaded); + + belongsToRequestor(requestor, classPrepareRequest); + classPrepareRequest.enable(); + if (LOG.isDebugEnabled()) { + LOG.debug("classOrPatternToBeLoaded = " + classOrPatternToBeLoaded); + } + } + + public void enableRequest(EventRequest request) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + LOG.assertTrue(findRequestor(request) != null); + try { + request.enable(); + } catch (InternalException e) { + if(e.errorCode() == 41) { + //event request not found + //there could be no requests after hotswap + } else { + LOG.error(e); + } + } + } + + public void setInvalid(Requestor requestor, String message) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myInvalidRequestors.put(requestor, message); + } + + public boolean isInvalid(Requestor requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myInvalidRequestors.containsKey(requestor); + } + + public String getInvalidMessage(Requestor requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myInvalidRequestors.get(requestor); + } + + public boolean isVerified(Requestor requestor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + //ClassPrepareRequest is added in any case + return findRequests(requestor).size() > 1; + } + + public void processDetached(DebugProcessImpl process) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myEventRequestManager = null; + myInvalidRequestors.clear(); + myRequestorToBelongedRequests.clear(); + myRequestsToProcessingRequestor.clear(); + } + + public void processAttached(DebugProcessImpl process) { + myEventRequestManager = myDebugProcess.getVirtualMachineProxy().eventRequestManager(); + + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(myDebugProcess.getProject()).getBreakpointManager(); + + for (Iterator iterator = breakpointManager.getBreakpoints().iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + myDebugProcess.getRequestsManager().createRequest(breakpoint); + } + } + + public void processClassPrepared(final ClassPrepareEvent event) { + if (!myDebugProcess.isAttached()) { + return; + } + + final ReferenceType refType = event.referenceType(); + + if (refType instanceof ClassType) { + ClassType classType = (ClassType)refType; + if (LOG.isDebugEnabled()) { + LOG.debug("signature = " + classType.signature()); + } + ClassPrepareRequestor requestor = (ClassPrepareRequestor)myRequestsToProcessingRequestor.get((ClassPrepareRequest)event.request()); + if (requestor != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("requestor found " + classType.signature()); + } + requestor .processClassPrepare(myDebugProcess, classType); + } + } + } + + private static interface AllProcessesCommand { + void action(DebugProcessImpl process); + } + + private static void invoke(Project project, final AllProcessesCommand command) { + Collection sessions = (DebuggerManagerEx.getInstanceEx(project)).getSessions(); + for (Iterator iterator = sessions.iterator(); iterator.hasNext();) { + DebuggerSession debuggerSession = iterator.next(); + final DebugProcessImpl process = debuggerSession.getProcess(); + if(process != null) { + process.getManagerThread().invoke(new DebuggerCommandImpl() { + protected void action() throws Exception { + command.action(process); + } + }); + } + } + } + + public static void createRequests(final Breakpoint breakpoint) { + invoke(breakpoint.getProject(), new AllProcessesCommand (){ + public void action(DebugProcessImpl process) { + process.getRequestsManager().createRequest(breakpoint); + } + }); + } + + public static void updateRequests(final Breakpoint breakpoint) { + invoke(breakpoint.getProject(), new AllProcessesCommand (){ + public void action(DebugProcessImpl process) { + process.getRequestsManager().myInvalidRequestors.remove(breakpoint); + process.getRequestsManager().deleteRequest(breakpoint); + process.getRequestsManager().createRequest(breakpoint); + } + }); + } + + public static void deleteRequests(final Breakpoint breakpoint) { + invoke(breakpoint.getProject(), new AllProcessesCommand (){ + public void action(DebugProcessImpl process) { + process.getRequestsManager().deleteRequest(breakpoint); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/CloseWorkerThreadException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/CloseWorkerThreadException.java new file mode 100644 index 00000000000..84d15d6616c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/CloseWorkerThreadException.java @@ -0,0 +1,11 @@ +package com.intellij.debugger.impl; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 31, 2004 + * Time: 4:58:01 PM + * To change this template use File | Settings | File Templates. + */ +public class CloseWorkerThreadException extends RuntimeException { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextImpl.java new file mode 100644 index 00000000000..c8c60bfc1db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextImpl.java @@ -0,0 +1,154 @@ +/* + * Interface DebuggerContextImpl + * @author Jeka + */ +package com.intellij.debugger.impl; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; + + +public final class DebuggerContextImpl implements DebuggerContext { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextImpl"); + + public static final DebuggerContextImpl EMPTY_CONTEXT = DebuggerContextImpl.createDebuggerContext((DebuggerSession) null, null, null, null); + + private boolean myInitialized; + + private final DebuggerSession myDebuggerSession; + private final DebugProcessImpl myDebugProcess; + private final SuspendContextImpl mySuspendContext; + private final ThreadReferenceProxyImpl myThreadProxy; + + private StackFrameProxyImpl myFrameProxy; + private SourcePosition mySourcePosition; + private PsiElement myContextElement; + + private DebuggerContextImpl(DebuggerSession session, DebugProcessImpl debugProcess, SuspendContextImpl context, ThreadReferenceProxyImpl threadProxy, StackFrameProxyImpl frameProxy, SourcePosition position, PsiElement contextElement, boolean initialized) { + LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy()); + LOG.assertTrue(debugProcess == null ? frameProxy == null && threadProxy == null : true); + myDebuggerSession = session; + myThreadProxy = threadProxy; + myFrameProxy = frameProxy; + myDebugProcess = debugProcess; + mySourcePosition = position; + mySuspendContext = context; + myContextElement = contextElement; + myInitialized = initialized; + } + + public DebuggerSession getDebuggerSession() { + return myDebuggerSession; + } + + public DebugProcessImpl getDebugProcess() { + return myDebugProcess; + } + + public ThreadReferenceProxyImpl getThreadProxy() { + return myThreadProxy; + } + + public SuspendContextImpl getSuspendContext() { + return mySuspendContext; + } + + public Project getProject() { + return myDebugProcess != null ? myDebugProcess.getProject() : null; + } + + public StackFrameProxyImpl getFrameProxy() { + LOG.assertTrue(myInitialized); + return myFrameProxy; + } + + public SourcePosition getSourcePosition() { + LOG.assertTrue(myInitialized); + return mySourcePosition; + } + + public PsiElement getContextElement() { + LOG.assertTrue(myInitialized); + if(myContextElement != null && !myContextElement.isValid()) { + myContextElement = ContextUtil.getContextElement(mySourcePosition); + } + return myContextElement; + } + + public EvaluationContextImpl createEvaluationContext(Value thisObject) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return new EvaluationContextImpl(getSuspendContext(), getFrameProxy(), thisObject); + } + + public EvaluationContextImpl createEvaluationContext() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + StackFrameProxyImpl frameProxy = getFrameProxy(); + ObjectReference objectReference; + try { + objectReference = frameProxy != null ? frameProxy.thisObject() : null; + } + catch (EvaluateException e) { + DebuggerCommandImpl currentCommand = getDebugProcess().getManagerThread().getCurrentCommand(); + LOG.assertTrue(currentCommand instanceof SuspendContextCommandImpl); + LOG.assertTrue(((SuspendContextCommandImpl)currentCommand).getSuspendContext().getThread() == frameProxy.threadProxy()); + LOG.error("Thread : " + frameProxy.threadProxy().name(), e); + objectReference = null; + } + return new EvaluationContextImpl(getSuspendContext(), frameProxy, objectReference); + } + + public static DebuggerContextImpl createDebuggerContext(DebuggerSession session, SuspendContextImpl context, ThreadReferenceProxyImpl threadProxy, StackFrameProxyImpl frameProxy) { + LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy()); + LOG.assertTrue(session == null || session.getProcess() != null); + return new DebuggerContextImpl(session, session != null ? session.getProcess() : null, context, threadProxy, frameProxy, null, null, context == null); + } + + public void initCaches() { + if(myInitialized) return; + + myInitialized = true; + if(myFrameProxy == null) { + if(myThreadProxy != null) { + try { + myFrameProxy = myThreadProxy.frameCount() > 0 ? myThreadProxy.frame(0) : null; + } + catch (EvaluateException e) { + } + } + } + + if(myFrameProxy != null) { + PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() { + public void run() { + mySourcePosition = ContextUtil.getSourcePosition(DebuggerContextImpl.this); + myContextElement = ContextUtil.getContextElement(mySourcePosition); + } + }); + } + } + + public void setPositionCache(SourcePosition position) { + LOG.assertTrue(!myInitialized, "Debugger context is initialized. Cannot change caches"); + mySourcePosition = position; + } + + public boolean isInitialised() { + return myInitialized; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextListener.java new file mode 100644 index 00000000000..6dad28a6411 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextListener.java @@ -0,0 +1,16 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.impl.DebuggerContextImpl; + + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jun 26, 2003 + * Time: 11:41:29 PM + * To change this template use Options | File Templates. + */ +public interface DebuggerContextListener { + + void changeEvent(DebuggerContextImpl newContext, int event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextUtil.java new file mode 100644 index 00000000000..cd95b5f7a8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerContextUtil.java @@ -0,0 +1,42 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DebuggerContextUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextUtil"); + + public static void setStackFrame(DebuggerStateManager manager, final StackFrameProxyImpl stackFrame) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + DebuggerContextImpl context = manager.getContext(); + if(context == null) return; + + DebuggerContextImpl newContext = DebuggerContextImpl.createDebuggerContext(context.getDebuggerSession(), context.getSuspendContext(), stackFrame.threadProxy(), stackFrame); + + manager.setState(newContext, context.getDebuggerSession().getState(), DebuggerSession.EVENT_REFRESH, null); + } + + public static void setThread(DebuggerStateManager contextManager, ThreadDescriptorImpl item) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + DebuggerContextImpl context = contextManager.getContext(); + + DebuggerContextImpl newContext = DebuggerContextImpl.createDebuggerContext(context.getDebuggerSession(), item.getSuspendContext(), item.getThreadReference(), null); + + contextManager.setState(newContext, context.getDebuggerSession().getState(), DebuggerSession.EVENT_REFRESH, null); + } + + public static DebuggerContextImpl createDebuggerContext(DebuggerSession session, SuspendContextImpl suspendContext){ + LOG.assertTrue(session != null); + return DebuggerContextImpl.createDebuggerContext(session, suspendContext, suspendContext != null ? suspendContext.getThread() : null, null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerImpl.java new file mode 100644 index 00000000000..25fab3c4b54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerImpl.java @@ -0,0 +1,449 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.*; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.GetJPDADialog; +import com.intellij.debugger.ui.breakpoints.BreakpointManager; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ex.PathUtilEx; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.util.ArrayUtil; +import com.intellij.util.EventDispatcher; +import com.intellij.util.PathUtil; +import com.sun.tools.jdi.TransportService; +import org.jdom.Element; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.jar.Attributes; + +public class DebuggerManagerImpl extends DebuggerManagerEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerManagerImpl"); + private final Project myProject; + private HashMap mySessions = new HashMap(); + private BreakpointManager myBreakpointManager; + + private final EventDispatcher myDispatcher = EventDispatcher.create(DebuggerManagerListener.class, false); + private final MyDebuggerStateManager myDebuggerStateManager = new MyDebuggerStateManager(); + + private DebuggerContextListener mySessionListener = new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + if(myDebuggerStateManager.myDebuggerSession == newContext.getDebuggerSession()) { + myDebuggerStateManager.fireStateChanged(newContext, event); + } + + if(event == DebuggerSession.EVENT_DISPOSE) { + dispose(newContext.getDebuggerSession()); + if(myDebuggerStateManager.myDebuggerSession == newContext.getDebuggerSession()) { + getContextManager().setState(DebuggerContextImpl.EMPTY_CONTEXT, DebuggerSession.STATE_DISPOSED, DebuggerSession.EVENT_DISPOSE, null); + } + } + } + }; + + public void addDebuggerManagerListener(DebuggerManagerListener listener) { + myDispatcher.addListener(listener); + } + + public void removeDebuggerManagerListener(DebuggerManagerListener listener) { + myDispatcher.removeListener(listener); + } + + public DebuggerManagerImpl(Project project, StartupManager startupManager) { + myProject = project; + myBreakpointManager = new BreakpointManager(myProject, startupManager, this); + } + + public DebuggerSession getSession(DebugProcess process) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + for (Iterator iterator = getSessions().iterator(); iterator.hasNext();) { + DebuggerSession debuggerSession = (DebuggerSession)iterator.next(); + if (process == debuggerSession.getProcess()) return debuggerSession; + } + return null; + } + + public Collection getSessions() { + return mySessions.values(); + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public void projectClosed() { + myBreakpointManager.dispose(); + } + + public void projectOpened() { + myBreakpointManager.init(); + } + + public void readExternal(Element element) throws InvalidDataException { + myBreakpointManager.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + myBreakpointManager.writeExternal(element); + } + + + public DebuggerSession attachVirtualMachine(String sessionName, RunProfileState state, + RemoteConnection remoteConnection, + boolean pollConnection) throws ExecutionException { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + DebuggerSession session = new DebuggerSession(sessionName, new DebugProcessEvents(myProject)); + + final ExecutionResult executionResult = session.attach(state, remoteConnection, pollConnection); + + session.getContextManager().addListener(mySessionListener); + getContextManager().setState(DebuggerContextUtil.createDebuggerContext(session, session.getContextManager().getContext().getSuspendContext()), session.getState(), DebuggerSession.EVENT_REFRESH, null); + + final ProcessHandler processHandler = executionResult.getProcessHandler(); + + synchronized (mySessions) { + mySessions.put(processHandler, session); + } + processHandler.addProcessListener(new ProcessAdapter() { + public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { + final DebugProcessImpl debugProcess = getDebugProcess(event.getProcessHandler()); + if (debugProcess != null) { + // if current thread is a "debugger manager thread", stop will execute synchronously + debugProcess.stop(willBeDestroyed); + + if (!DebuggerManagerThreadImpl.isManagerThread()) { + debugProcess.waitFor(); + } + } + } + + }); + myDispatcher.getMulticaster().sessionCreated(session); + return session; + } + + + public DebugProcessImpl getDebugProcess(final ProcessHandler processHandler) { + synchronized (mySessions) { + DebuggerSession session = mySessions.get(processHandler); + return session != null ? session.getProcess() : null; + } + } + + public void addDebugProcessListener(final ProcessHandler processHandler, final DebugProcessListener listener) { + DebugProcessImpl debugProcess = getDebugProcess(processHandler); + if (debugProcess != null) { + debugProcess.addDebugProcessListener(listener); + } + else { + processHandler.addProcessListener(new ProcessAdapter() { + public void startNotified(ProcessEvent event) { + DebugProcessImpl debugProcess = getDebugProcess(processHandler); + if (debugProcess != null) { + debugProcess.addDebugProcessListener(listener); + } + processHandler.removeProcessListener(this); + } + }); + } + } + + public void removeDebugProcessListener(final ProcessHandler processHandler, final DebugProcessListener listener) { + DebugProcessImpl debugProcess = getDebugProcess(processHandler); + if (debugProcess != null) { + debugProcess.removeDebugProcessListener(listener); + } + else { + processHandler.addProcessListener(new ProcessAdapter() { + public void startNotified(ProcessEvent event) { + DebugProcessImpl debugProcess = getDebugProcess(processHandler); + if (debugProcess != null) { + debugProcess.removeDebugProcessListener(listener); + } + processHandler.removeProcessListener(this); + } + }); + } + } + + public boolean isDebuggerManagerThread() { + return DebuggerManagerThreadImpl.isManagerThread(); + } + + public String getComponentName() { + return "DebuggerManager"; + } + + public BreakpointManager getBreakpointManager() { + return myBreakpointManager; + } + + public DebuggerContextImpl getContext() { return getContextManager().getContext(); } + + public DebuggerStateManager getContextManager() { return myDebuggerStateManager;} + + static private boolean hasWhitespace(String string) { + int length = string.length(); + for (int i = 0; i < length; i++) { + if (Character.isWhitespace(string.charAt(i))) { + return true; + } + } + return false; + } + + /* Remoting */ + private static void checkTargetJPDAInstalled(JavaParameters parameters) throws ExecutionException { + final ProjectJdk jdk = parameters.getJdk(); + if (jdk == null) { + throw new ExecutionException("JDK is not specified"); + } + final String versionString = jdk.getVersionString(); + if (versionString.indexOf("1.0") > -1 || versionString.indexOf("1.1") > -1) { + throw new ExecutionException("Debugging is not supported for JDK " + versionString); + } + if (SystemInfo.isWindows && versionString.indexOf("1.2") > -1) { + final VirtualFile homeDirectory = jdk.getHomeDirectory(); + if (homeDirectory == null || !homeDirectory.isValid()) { + throw new ExecutionException("Invalid JDK home directory specified." + versionString); + } + File dllFile = new File( + homeDirectory.getPath().replace('/', File.separatorChar) + File.separator + "bin" + File.separator + "jdwp.dll"); + if (!dllFile.exists()) { + GetJPDADialog dialog = new GetJPDADialog(); + dialog.show(); + throw new ExecutionException( + "Debug libraries are missig from JDK home.\nIn order for debugger to start, the libraries should be installed.\nPlease visit http://java.sun.com/products/jpda"); + } + } + } + + /** + * for Target JDKs versions 1.2.x - 1.3.0 the Classic VM should be used for debugging + */ + private static boolean shouldForceClassicVM(ProjectJdk jdk) { + if (SystemInfo.isMac) { + return false; + } + if (jdk == null) return false; + + String version = PathUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION); + if (version != null) { + if (version.compareTo("1.4") >= 0) { + return false; + } + if (version.startsWith("1.2") && SystemInfo.isWindows) { + return true; + } + version = version + ".0"; + if (version.startsWith("1.3.0") && SystemInfo.isWindows) { + return true; + } + if ((version.startsWith("1.3.1_07") || version.startsWith("1.3.1_08")) && SystemInfo.isWindows) { + return false; // fixes bug for these JDKs that it cannot start with -classic option + } + } + + return DebuggerSettings.getInstance().FORCE_CLASSIC_VM; + } + + public static TransportService getTransportService(boolean forceSocketTransport) throws ExecutionException { + TransportService transport = null; + try { + try { + if (forceSocketTransport) { + transport = createTransport(Class.forName("com.sun.tools.jdi.SocketTransport")); + } + else { + transport = createTransport(Class.forName("com.sun.tools.jdi.SharedMemoryTransport")); + } + } + catch (UnsatisfiedLinkError e) { + transport = createTransport(Class.forName("com.sun.tools.jdi.SocketTransport")); + } + } + catch (Exception e) { + throw new ExecutionException(e.getClass().getName() + " : " + e.getMessage()); + } + return transport; + } + + private static TransportService createTransport(final Class aClass) throws NoSuchMethodException, + InstantiationException, + IllegalAccessException, + InvocationTargetException { + final Constructor constructor = aClass.getDeclaredConstructor(new Class[0]); + constructor.setAccessible(true); + return (TransportService)constructor.newInstance(ArrayUtil.EMPTY_OBJECT_ARRAY); + } + + public static RemoteConnection createDebugParameters(final JavaParameters parameters, + final boolean serverMode, + int transport, final String debugPort, + boolean checkValidity) + throws ExecutionException { + if (checkValidity) { + checkTargetJPDAInstalled(parameters); + } + + final boolean useSockets = transport == DebuggerSettings.SOCKET_TRANSPORT; + + TransportService transportService = getTransportService(useSockets); + + String address = ""; + String listenTo = null; + + if (debugPort == null || "".equals(debugPort)) { + if(useSockets) { + try { + ServerSocket serverSocket = new ServerSocket(0); + address = Integer.toString(serverSocket.getLocalPort()); + //workaround for linux : calling close() immediately after opening socket + //may result that socket is not closed + synchronized(parameters) { + try { + parameters.wait(1); + } + catch (InterruptedException e) { + LOG.error(e); + } + } + serverSocket.close(); + } + catch (IOException e) { + if (checkValidity) { + throw new ExecutionException(DebugProcessImpl.processError(e)); + } + } + } + else { + try { + address = transportService.startListening(); + transportService.stopListening(address); + } + catch (IOException e) { + if (checkValidity) { + throw new ExecutionException(DebugProcessImpl.processError(e)); + } + } + } + } + else { + address = debugPort; + } + + if(serverMode && useSockets) { + try { + listenTo = InetAddress.getLocalHost().getHostName() + ":" + address; + } catch (UnknownHostException e) { + listenTo = "localhost:" + address; + } + } + else { + listenTo = address; + } + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + PathUtilEx.addRtJar(parameters.getClassPath()); + boolean classicVM = shouldForceClassicVM(parameters.getJdk()); + parameters.getVMParametersList().replaceOrPrepend("-classic", classicVM ? "-classic" : ""); + + parameters.getVMParametersList().replaceOrAppend("-Xdebug", "-Xdebug"); + + if (shouldForceNoJIT(parameters.getJdk())) { + parameters.getVMParametersList().replaceOrAppend("-Xnoagent", "-Xnoagent"); + parameters.getVMParametersList().replaceOrAppend("-Djava.compiler=", "-Djava.compiler=NONE"); + } + } + }); + + String xrun = "transport=" + transportService.name() + ",address=" + listenTo; + if(serverMode) { + xrun += ",suspend=y,server=n"; + } + else { + xrun += ",suspend=n,server=y"; + } + + if (hasWhitespace(xrun)) { + xrun = "\"" + xrun + "\""; + } + parameters.getVMParametersList().replaceOrAppend("-Xrunjdwp:", "-Xrunjdwp:" + xrun); + + return new RemoteConnection(useSockets, "127.0.0.1", address, serverMode); + } + + private static boolean shouldForceNoJIT(ProjectJdk jdk) { + if (jdk == null) return true; + + String version = PathUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION); + + if (version == null) return true; + + return version.startsWith("1.2") || version.startsWith("1.3"); + } + + public static RemoteConnection createDebugParameters(final JavaParameters parameters, GenericDebuggerRunnerSettings settings, boolean checkValidity) + throws ExecutionException { + return createDebugParameters(parameters, settings.LOCAL, settings.getTransport(), settings.DEBUG_PORT, checkValidity); + + } + + private static class MyDebuggerStateManager extends DebuggerStateManager { + private DebuggerSession myDebuggerSession; + + public DebuggerContextImpl getContext() { + return myDebuggerSession == null ? DebuggerContextImpl.EMPTY_CONTEXT : myDebuggerSession.getContextManager().getContext(); + } + + public void setState(DebuggerContextImpl context, int state, int event, String description) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + myDebuggerSession = context.getDebuggerSession(); + if (myDebuggerSession != null) { + myDebuggerSession.getContextManager().setState(context, state, event, description); + } + else { + fireStateChanged(context, event); + } + } + } + + private void dispose(DebuggerSession session) { + ProcessHandler processHandler = session.getProcess().getExecutionResult().getProcessHandler(); + + synchronized (mySessions) { + DebuggerSession removed = mySessions.remove(processHandler); + LOG.assertTrue(removed != null); + myDispatcher.getMulticaster().sessionRemoved(session); + } + + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerListener.java new file mode 100644 index 00000000000..917567f3d95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerManagerListener.java @@ -0,0 +1,15 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.impl.DebuggerSession; + +import java.util.EventListener; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface DebuggerManagerListener extends EventListener{ + void sessionCreated(DebuggerSession session); + void sessionRemoved(DebuggerSession session); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerSession.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerSession.java new file mode 100644 index 00000000000..f485d8d2959 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerSession.java @@ -0,0 +1,465 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.*; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationListener; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter; +import com.intellij.debugger.ui.breakpoints.LineBreakpoint; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RemoteState; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiDocumentManager; +import com.sun.jdi.request.EventRequest; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class DebuggerSession { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerSession"); + // flags + private final MyDebuggerStateManager myContextManager; + + public static final int STATE_STOPPED = 0; + public static final int STATE_RUNNING = 1; + public static final int STATE_WAITING_ATTACH = 2; + public static final int STATE_PAUSED = 3; + public static final int STATE_WAIT_EVALUATION = 5; + public static final int STATE_DISPOSED = 6; + + public static final int EVENT_ATTACHED = 0; + public static final int EVENT_DETACHED = 1; + public static final int EVENT_RESUME = 4; + public static final int EVENT_STEP = 5; + public static final int EVENT_PAUSE = 6; + public static final int EVENT_REFRESH = 7; + public static final int EVENT_CONTEXT = 8; + public static final int EVENT_START_WAIT_ATTACH = 9; + public static final int EVENT_DISPOSE = 10; + + private boolean myIsEvaluating; + + private DebuggerSessionState myState = null; + + private static final String MSG_WAITING_ATTACH = "Debugger is waiting for application to start"; + private static final String MSG_LISTENING = "Listening to the connection"; + private static final String MSG_CONNECTING = "Connecting to the target VM"; + private static final String MSG_RUNNING = "The application is running"; + private static final String MSG_CONNECTED = "Connected to the target VM"; + private static final String MSG_STOPPED = "Debugger disconnected"; + private static final String MSG_DISCONNECTED = "Disconnected from the target VM"; + private static final String MSG_WAIT_EVALUATION = "Waiting until last debugger command completes"; + + private final String mySessionName; + private final DebugProcessImpl myDebugProcess; + + private final DebuggerContextImpl SESSION_EMPTY_CONTEXT; + //Thread, user is currently stepping through + private Set mySteppingThroughThreads = new HashSet(); + + public boolean isSteppingThrough(ThreadReferenceProxyImpl threadProxy) { + return mySteppingThroughThreads.contains(threadProxy); + } + + + private class MyDebuggerStateManager extends DebuggerStateManager { + private DebuggerContextImpl myDebuggerContext; + + MyDebuggerStateManager() { + myDebuggerContext = SESSION_EMPTY_CONTEXT; + } + + public DebuggerContextImpl getContext() { + return myDebuggerContext; + } + + /** + * actually state changes not in the same sequence as you call setState + * the 'resuming' setState with context.getSuspendContext() == null may be set prior to + * the setState for the context with context.getSuspendContext() + * + * in this case we assume that the latter setState is ignored + * since the thread was resumed + */ + public void setState(final DebuggerContextImpl context, final int state, final int event, final String description) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(context.getDebuggerSession() == DebuggerSession.this || context.getDebuggerSession() == null); + final Runnable setStateRunnable = new Runnable() { + public void run() { + LOG.assertTrue(myDebuggerContext.isInitialised()); + myDebuggerContext = context; + if (LOG.isDebugEnabled()) { + LOG.debug("DebuggerSession state = " + state + ", event = " + event); + } + + myIsEvaluating = false; + + myState = new DebuggerSessionState(state, description); + fireStateChanged(context, event); + } + }; + + if(context.getSuspendContext() == null) { + setStateRunnable.run(); + } + else { + getProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(context) { + public void threadAction() { + context.initCaches(); + DebuggerInvocationUtil.invokeLater(getProject(), setStateRunnable); + } + }); + } + } + } + + protected DebuggerSession(String sessionName, final DebugProcessImpl debugProcess) { + mySessionName = sessionName; + myDebugProcess = debugProcess; + SESSION_EMPTY_CONTEXT = DebuggerContextImpl.createDebuggerContext(DebuggerSession.this, null, null, null); + myContextManager = new MyDebuggerStateManager(); + myState = new DebuggerSessionState(STATE_STOPPED, null); + myDebugProcess.addDebugProcessListener(new DebugProcessAdapterImpl() { + //executed in manager thread + public void connectorIsReady() { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + RemoteConnection connection = myDebugProcess.getConnection(); + final String connectionStatusMessage = DebugProcessImpl.createConnectionStatusMessage( + connection.isServerMode() ? DebuggerSession.MSG_LISTENING : DebuggerSession.MSG_CONNECTING, connection + ); + getContextManager().setState(SESSION_EMPTY_CONTEXT, DebuggerSession.STATE_WAITING_ATTACH, DebuggerSession.EVENT_START_WAIT_ATTACH, connectionStatusMessage); + } + }); + } + + public void paused(final SuspendContextImpl suspendContext) { + if (LOG.isDebugEnabled()) { + LOG.debug("paused"); + } + + ThreadReferenceProxyImpl currentThread = suspendContext.getThread(); + final StackFrameContext positionContext; + + if (currentThread == null) { + //Pause pressed + LOG.assertTrue(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL); + SuspendContextImpl oldContext = getProcess().getSuspendManager().getPausedContext(); + + if (oldContext != null) { + currentThread = oldContext.getThread(); + } + + if(currentThread == null) { + currentThread = getProcess().getVirtualMachineProxy().allThreads().iterator().next(); + } + + + StackFrameProxyImpl proxy; + try { + proxy = (currentThread.frameCount() > 0) ? currentThread.frame(0) : null; + } + catch (EvaluateException e) { + proxy = null; + LOG.error(e); + } + positionContext = new SimpleStackFrameContext(proxy, debugProcess); + } + else { + positionContext = suspendContext; + } + + final SourcePosition position = PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Computable() { + public SourcePosition compute() { + return ContextUtil.getSourcePosition(positionContext); + } + }); + + if (position != null) { + ArrayList toDelete = new ArrayList(); + + java.util.List> eventDescriptors = DebuggerUtilsEx.getEventDescriptors(suspendContext); + for (Iterator> iterator = eventDescriptors.iterator(); iterator.hasNext();) { + Pair eventDescriptor = iterator.next(); + Breakpoint breakpoint = eventDescriptor.getFirst(); + if (breakpoint instanceof LineBreakpoint) { + SourcePosition sourcePosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition(); + if (sourcePosition == null || sourcePosition.getLine() != position.getLine()) { + toDelete.add((LineBreakpoint)breakpoint); + } + } + } + + RequestManagerImpl requestsManager = suspendContext.getDebugProcess().getRequestsManager(); + for (Iterator iterator = toDelete.iterator(); iterator.hasNext();) { + BreakpointWithHighlighter breakpointWithHighlighter = iterator.next(); + requestsManager.deleteRequest(breakpointWithHighlighter); + requestsManager.setInvalid(breakpointWithHighlighter, "Source code changed"); + breakpointWithHighlighter.updateUI(); + } + + if (toDelete.size() > 0 && toDelete.size() == eventDescriptors.size()) { + getProcess().getManagerThread().invokeLater(myDebugProcess.createResumeCommand(suspendContext)); + return; + } + } + + final DebuggerContextImpl debuggerContext = DebuggerContextImpl.createDebuggerContext(DebuggerSession.this, suspendContext, currentThread, null); + debuggerContext.setPositionCache(position); + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getContextManager().setState(debuggerContext, STATE_PAUSED, EVENT_PAUSE, null); + } + }); + } + + public void resumed(final SuspendContextImpl suspendContext) { + final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext(); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + if (currentContext != null) { + getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, currentContext), STATE_PAUSED, EVENT_REFRESH, null); + } + else { + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_RUNNING, EVENT_REFRESH, null); + } + } + }); + } + + public void processAttached(final DebugProcessImpl process) { + final String message = DebugProcessImpl.createConnectionStatusMessage(MSG_CONNECTED, getProcess().getConnection()); + + process.getExecutionResult().getProcessHandler().notifyTextAvailable(message + "\n", ProcessOutputTypes.SYSTEM); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_RUNNING, EVENT_ATTACHED, message); + } + }); + } + + public void attachException(final RunProfileState state, final ExecutionException exception, final RemoteConnection remoteConnection) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + String message = ""; + if (state instanceof RemoteState) { + message = DebugProcessImpl.createConnectionStatusMessage(DebugProcessImpl.MSG_FAILD_TO_CONNECT, remoteConnection); + } + message += exception.getMessage(); + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_STOPPED, EVENT_DETACHED, message); + } + }); + } + + public void processDetached(final DebugProcessImpl debugProcess) { + ExecutionResult executionResult = debugProcess.getExecutionResult(); + if(executionResult != null) { + executionResult.getProcessHandler().notifyTextAvailable(DebugProcessImpl.createConnectionStatusMessage(MSG_DISCONNECTED, getProcess().getConnection()) + "\n", ProcessOutputTypes.SYSTEM); + } + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_STOPPED, EVENT_DETACHED, MSG_DISCONNECTED); + } + }); + mySteppingThroughThreads.clear(); + } + }); + + myDebugProcess.addEvaluationListener(new EvaluationListener() { + public void evaluationStarted(SuspendContextImpl context) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myIsEvaluating = true; + } + }); + } + + public void evaluationFinished(final SuspendContextImpl context) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myIsEvaluating = false; + if (context != getSuspendContext()) { + getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, context), STATE_PAUSED, EVENT_REFRESH, null); + } + } + }); + } + }); + } + + public DebuggerStateManager getContextManager() { + return myContextManager; + } + + public Project getProject() { + return getProcess().getProject(); + } + + public String getSessionName() { + return mySessionName; + } + + public DebugProcessImpl getProcess() { + return myDebugProcess; + } + + private static class DebuggerSessionState { + final int myState; + final String myDescription; + + public DebuggerSessionState(int state, String description) { + myState = state; + myDescription = description; + } + } + + private DebuggerSessionState getSessionState() { + return myState; + } + + public int getState() { + return getSessionState().myState; + } + + public String getStateDescription() { + DebuggerSessionState state = getSessionState(); + if (state.myDescription != null) return state.myDescription; + + switch (state.myState) { + case STATE_STOPPED: + return MSG_STOPPED; + case STATE_RUNNING: + return MSG_RUNNING; + case STATE_WAITING_ATTACH: + RemoteConnection connection = getProcess().getConnection(); + return DebugProcessImpl.createConnectionStatusMessage(connection.isServerMode() ? MSG_LISTENING : MSG_CONNECTING, connection); + case STATE_PAUSED: + return "Paused"; + case STATE_WAIT_EVALUATION: + return MSG_WAIT_EVALUATION; + case STATE_DISPOSED: + return MSG_STOPPED; + } + return state.myDescription; + } + + /* Stepping */ + private void resumeAction(final SuspendContextCommandImpl action, int event) { + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_WAIT_EVALUATION, event, null); + myDebugProcess.getManagerThread().invokeLater(action, DebuggerManagerThreadImpl.HIGH_PRIORITY); + } + + public void stepOut() { + mySteppingThroughThreads.add(getSuspendContext().getThread()); + resumeAction(myDebugProcess.createStepOutCommand(getSuspendContext()), EVENT_STEP); + } + + public void stepOver(boolean ignoreBreakpoints) { + mySteppingThroughThreads.add(getSuspendContext().getThread()); + resumeAction(myDebugProcess.createStepOverCommand(getSuspendContext(), ignoreBreakpoints), EVENT_STEP); + } + + public void stepInto(final boolean ignoreFilters) { + mySteppingThroughThreads.add(getSuspendContext().getThread()); + resumeAction(myDebugProcess.createStepIntoCommand(getSuspendContext(), ignoreFilters), EVENT_STEP); + } + + public void runToCursor(Document document, int line) { + try { + SuspendContextCommandImpl runToCursorCommand = myDebugProcess.createRunToCursorCommand(getSuspendContext(), document, line); + mySteppingThroughThreads.add(getSuspendContext().getThread()); + resumeAction(runToCursorCommand, EVENT_STEP); + } + catch (EvaluateException e) { + Messages.showErrorDialog(e.getMessage(), "Cannot Run to Cursor"); + } + } + + + public void resume() { + if(getSuspendContext() != null) { + mySteppingThroughThreads.remove(getSuspendContext().getThread()); + resumeAction(myDebugProcess.createResumeCommand(getSuspendContext()), EVENT_RESUME); + } + } + + public void pause() { + myDebugProcess.getManagerThread().invokeLater(myDebugProcess.createPauseCommand()); + } + + /*Presentation*/ + + public void showExecutionPoint() { + getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, getSuspendContext()), STATE_PAUSED, EVENT_REFRESH, null); + } + + public void refresh() { + if (getState() == DebuggerSession.STATE_PAUSED) { + DebuggerContextImpl context = myContextManager.getContext(); + DebuggerContextImpl newContext = DebuggerContextImpl.createDebuggerContext(this, context.getSuspendContext(), context.getThreadProxy(), context.getFrameProxy()); + myContextManager.setState(newContext, DebuggerSession.STATE_PAUSED, EVENT_REFRESH, null); + } + } + + public void dispose() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + getProcess().dispose(); + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_DISPOSED, EVENT_DISPOSE, null); + } + + // ManagerCommands + public boolean isStopped() { + return getState() == STATE_STOPPED; + } + + public boolean isAttached() { + return !isStopped() && getState() != STATE_WAITING_ATTACH; + } + + public boolean isPaused() { + return getState() == STATE_PAUSED; + } + + public boolean isConnecting() { + return getState() == STATE_WAITING_ATTACH; + } + + public boolean isEvaluating() { + return myIsEvaluating; + } + + public boolean isRunning() { + return getState() == STATE_RUNNING && !getProcess().getExecutionResult().getProcessHandler().isProcessTerminated(); + } + + private SuspendContextImpl getSuspendContext() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + return getContextManager().getContext().getSuspendContext(); + } + + protected ExecutionResult attach(final RunProfileState state, final RemoteConnection remoteConnection, final boolean pollConnection) throws ExecutionException { + final ExecutionResult executionResult = myDebugProcess.attachVirtualMachine(state, remoteConnection, pollConnection); + getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_WAITING_ATTACH, EVENT_START_WAIT_ATTACH, DebugProcessImpl.createConnectionStatusMessage(MSG_WAITING_ATTACH, remoteConnection)); + return executionResult; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerStateManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerStateManager.java new file mode 100644 index 00000000000..c78cc3047a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerStateManager.java @@ -0,0 +1,67 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.debugger.DebuggerInvocationUtil; + +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jun 4, 2003 + * Time: 12:45:56 PM + * To change this template use Options | File Templates. + */ +public abstract class DebuggerStateManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerStateManager"); + private LinkedList myListeners = new LinkedList(); + private boolean myCopyListeners = false; + + public abstract DebuggerContextImpl getContext(); + + public abstract void setState(DebuggerContextImpl context, int state, int event, String description); + + //we allow add listeners inside DebuggerContextListener.changeEvent + public void addPriorityListener(DebuggerContextListener listener){ + if(myCopyListeners) { + myListeners = new LinkedList(myListeners); + myCopyListeners = false; + } + myListeners.addFirst(listener); + } + + //we allow add listeners inside DebuggerContextListener.changeEvent + public void addListener(DebuggerContextListener listener){ + if(myCopyListeners) { + myListeners = new LinkedList(myListeners); + myCopyListeners = false; + } + myListeners.add(listener); + } + + //we allow remove listeners inside DebuggerContextListener.changeEvent + public void removeListener(DebuggerContextListener listener){ + if(myCopyListeners) { + myListeners = new LinkedList(myListeners); + myCopyListeners = false; + } + myListeners.remove(listener); + } + + protected void fireStateChanged(DebuggerContextImpl newContext, int event) { + myCopyListeners = true; + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + DebuggerContextListener debuggerContextListener = (DebuggerContextListener) iterator.next(); + try { + debuggerContextListener.changeEvent(newContext, event); + } + catch(Throwable th) { + LOG.error(th); + } + } + myCopyListeners = false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsEx.java new file mode 100644 index 00000000000..290db6ce8ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -0,0 +1,612 @@ +/* + * Class DebuggerUtilsEx + * @author Jeka + */ +package com.intellij.debugger.impl; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.requests.Requestor; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.SuspendContext; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.sun.jdi.*; +import com.sun.jdi.event.Event; +import org.jdom.Attribute; +import org.jdom.Element; + +import java.util.*; +import java.util.regex.PatternSyntaxException; + +public abstract class DebuggerUtilsEx extends DebuggerUtils { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerUtilsEx"); + + public static final int MAX_LABEL_SIZE = 255; + public static Runnable DO_NOTHING = EmptyRunnable.getInstance(); + + public static PsiMethod findPsiMethod(PsiFile file, int offset) { + PsiElement element = null; + + while(offset >= 0) { + element = file.findElementAt(offset); + if(element != null) break; + offset --; + } + + for (; element != null; element = element.getParent()) { + if (element instanceof PsiClass) return null; + if (element instanceof PsiMethod) return (PsiMethod)element; + } + return null; + } + + + public static boolean isAssignableFrom(final String baseQualifiedName, ReferenceType checkedType) { + return getSuperClass(baseQualifiedName, checkedType) != null; + + } + + public static ReferenceType getSuperClass(final String baseQualifiedName, ReferenceType checkedType) { + if (baseQualifiedName.equals(checkedType.name())) { + return checkedType; + } + + if (checkedType instanceof ClassType) { + ClassType classType = (ClassType)checkedType; + ClassType superClassType = classType.superclass(); + if (superClassType != null) { + ReferenceType superClass = getSuperClass(baseQualifiedName, superClassType); + if (superClass != null) { + return superClass; + } + } + List ifaces = classType.allInterfaces(); + for (Iterator it = ifaces.iterator(); it.hasNext();) { + InterfaceType iface = (InterfaceType)it.next(); + ReferenceType superClass = getSuperClass(baseQualifiedName, iface); + if (superClass != null) { + return superClass; + } + } + } + + if (checkedType instanceof InterfaceType) { + List list = ((InterfaceType)checkedType).superinterfaces(); + for (Iterator it = list.iterator(); it.hasNext();) { + InterfaceType superInterface = (InterfaceType)it.next(); + ReferenceType superClass = getSuperClass(baseQualifiedName, superInterface); + if (superClass != null) { + return superClass; + } + } + } + return null; + } + + public static boolean valuesEqual(Value val1, Value val2) { + if (val1 == null) { + return val2 == null; + } + if (val2 == null) { + return false; + } + if (val1 instanceof StringReference && val2 instanceof StringReference) { + return ((StringReference)val1).value().equals(((StringReference)val2).value()); + } + return val1.equals(val2); + } + + public static String getValueOrErrorAsString(final EvaluationContext evaluationContext, Value value) { + try { + return getValueAsString(evaluationContext, value); + } + catch (EvaluateException e) { + return e.getMessage(); + } + } + + public static boolean isCharOrInteger(Value value) { + return value != null && + value instanceof CharValue || + isInteger(value); + } + + private static Set myCharOrIntegers; + + public static boolean isCharOrIntegerArray(Value value) { + if (value == null) return false; + if (myCharOrIntegers == null) { + myCharOrIntegers = new HashSet(); + myCharOrIntegers.add("C"); + myCharOrIntegers.add("B"); + myCharOrIntegers.add("S"); + myCharOrIntegers.add("I"); + myCharOrIntegers.add("J"); + } + + String signature = value.type().signature(); + int i; + for (i = 0; signature.charAt(i) == '['; i++) ; + if (i == 0) return false; + signature = signature.substring(i, signature.length()); + return myCharOrIntegers.contains(signature); + } + + public static ClassFilter create(Element element) throws InvalidDataException { + ClassFilter filter = new ClassFilter(); + filter.readExternal(element); + return filter; + } + + private static boolean isFiltered(ClassFilter classFilter, String qName) { + if (!classFilter.isEnabled()) { + return false; + } + try { + if (classFilter.matches(qName)) { + return true; + } + } + catch (PatternSyntaxException e) { + LOG.debug(e); + } + return false; + } + + public static boolean isFiltered(String qName, ClassFilter[] classFilters) { + if(qName.indexOf('[') != -1) { + return false; //is array + } + + for(int i = 0; i < classFilters.length; i++) { + ClassFilter filter = classFilters[i]; + if(isFiltered(filter, qName)) { + return true; + } + } + return false; + } + + public static ClassFilter[] readFilters(List children) throws InvalidDataException { + List classFiltersList = new LinkedList(); + for (Iterator i = children.iterator(); i.hasNext();) { + Element filter = (Element)i.next(); + ClassFilter classFilter = new ClassFilter(); + classFilter.readExternal(filter); + classFiltersList.add(classFilter); + } + return (ClassFilter[])classFiltersList.toArray(new ClassFilter[classFiltersList.size()]); + } + + public static void writeFilters(Element parentNode, String tagName, ClassFilter[] filters) throws WriteExternalException { + for (int idx = 0; idx < filters.length; idx++) { + Element element = new Element(tagName); + parentNode.addContent(element); + filters[idx].writeExternal(element); + } + } + + public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) { + if (filters1.length != filters2.length) { + return false; + } + Set f1 = new HashSet(); + Set f2 = new HashSet(); + for (int idx = 0; idx < filters1.length; idx++) { + f1.add(filters1[idx]); + } + for (int idx = 0; idx < filters2.length; idx++) { + f2.add(filters2[idx]); + } + return f2.equals(f1); + } + + private static boolean elementListsEqual(List l1, List l2) { + if(l1 == null) return l2 == null; + if(l2 == null) return false; + + if(l1.size() != l2.size()) return false; + + Iterator i1 = l1.iterator(); + Iterator i2 = l2.iterator(); + + while (i2.hasNext()) { + Element elem1 = i1.next(); + Element elem2 = i2.next(); + + if(!elementsEqual(elem1, elem2)) return false; + } + return true; + } + + private static boolean attributeListsEqual(List l1, List l2) { + if(l1 == null) return l2 == null; + if(l2 == null) return false; + + if(l1.size() != l2.size()) return false; + + Iterator i1 = l1.iterator(); + Iterator i2 = l2.iterator(); + + while (i2.hasNext()) { + Attribute attr1 = i1.next(); + Attribute attr2 = i2.next(); + + if(!Comparing.equal(attr1.getName() , attr2.getName()) || + !Comparing.equal(attr1.getValue(), attr2.getValue())) return false; + } + return true; + } + + private static boolean elementsEqual(Element e1, Element e2) { + if(e1 == null) return e2 == null; + return Comparing.equal(e1.getName(), e2.getName()) && + elementListsEqual ((List )e1.getChildren (), (List )e2.getChildren ()) && + attributeListsEqual((List)e1.getAttributes(), (List)e2.getAttributes()); + } + + public static boolean externalizableEqual(JDOMExternalizable e1, JDOMExternalizable e2) { + Element root1 = new Element("root"); + Element root2 = new Element("root"); + try { + e1.writeExternal(root1); + } + catch (WriteExternalException e) { + LOG.debug(e); + } + try { + e2.writeExternal(root2); + } + catch (WriteExternalException e) { + LOG.debug(e); + } + + return elementsEqual(root1, root2); + } + + public static List> getEventDescriptors(SuspendContextImpl suspendContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if(suspendContext == null || suspendContext.getEventSet() == null) return Collections.EMPTY_LIST; + final List> eventDescriptors = new ArrayList>(); + + for (Iterator iterator = suspendContext.getEventSet().iterator(); iterator.hasNext();) { + Event event = (Event)iterator.next(); + Requestor requestor = suspendContext.getDebugProcess().getRequestsManager().findRequestor(event.request()); + if(requestor instanceof Breakpoint) { + eventDescriptors.add(new Pair((Breakpoint)requestor, event)); + } + } + return eventDescriptors; + } + + private static PsiElement findExpression(PsiElement element) { + if (!(element instanceof PsiIdentifier || element instanceof PsiKeyword)) { + return null; + } + PsiElement parent = element.getParent(); + if (parent instanceof PsiVariable) { + return element; + } + if (parent instanceof PsiReferenceExpression) { + if (parent.getParent() instanceof PsiCallExpression) return parent.getParent(); + return parent; + } + if (parent instanceof PsiThisExpression) { + return parent; + } + return null; + } + + public static TextWithImportsImpl getEditorText(final Editor editor) { + if(editor == null) return null; + final Project project = editor.getProject(); + + String defaultExpression = editor.getSelectionModel().getSelectedText(); + if (defaultExpression == null) { + int offset = editor.getCaretModel().getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile != null) { + PsiElement elementAtCursor = psiFile.findElementAt(offset); + if (elementAtCursor != null) { + PsiElement element = findExpression(elementAtCursor); + if (element != null) { + defaultExpression = element.getText(); + } + } + } + } + + if(defaultExpression != null) { + return TextWithImportsImpl.createExpressionText(defaultExpression); + } else { + return null; + } + } + + private static class SigReader { + final String buffer; + int pos = 0; + + SigReader(String s) { + buffer = s; + } + + int get() { + return buffer.charAt(pos++); + } + + int peek() { + return buffer.charAt(pos); + } + + boolean eof() { + return buffer.length() <= pos; + } + + String getSignature() { + if (eof()) return ""; + + switch (get()) { + case 'Z': + return "boolean"; + case 'B': + return "byte"; + case 'C': + return "char"; + case 'S': + return "short"; + case 'I': + return "int"; + case 'J': + return "long"; + case 'F': + return "float"; + case 'D': + return "double"; + case 'V': + return "void"; + case 'L': + int start = pos; + pos = buffer.indexOf(';', start) + 1; + LOG.assertTrue(pos > 0); + return buffer.substring(start, pos - 1).replace('/', '.'); + case '[': + return getSignature() + "[]"; + case '(': + StringBuffer result = new StringBuffer("("); + String separator = ""; + while (peek() != ')') { + result.append(separator); + result.append(getSignature()); + separator = ", "; + } + get(); + result.append(")"); + return getSignature() + " " + getClassName() + "." + getMethodName() + " " + result; + default: +// LOG.assertTrue(false, "unknown signature " + buffer); + return null; + } + } + + String getMethodName() { + return ""; + } + + String getClassName() { + return ""; + } + } + + public static String methodName(final Method m) { + return methodName(signatureToName(m.declaringType().signature()), m.name(), m.signature()); + } + + public static String methodName(final String className, final String methodName, final String signature) { + try { + return new SigReader(signature) { + String getMethodName() { + return methodName; + } + + String getClassName() { + return className; + } + }.getSignature(); + } + catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug("Internal error : unknown signature" + signature); + } + return className + "." + methodName; + } + } + + public static String signatureToName(String s) { + return new SigReader(s).getSignature(); + } + + public static Value createValue(VirtualMachineProxyImpl vm, String expectedType, double value) { + if (PsiType.DOUBLE.getPresentableText().equals(expectedType)) { + return vm.mirrorOf(value); + } + if (PsiType.FLOAT.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((float)value); + } + return createValue(vm, expectedType, (long)value); + } + + public static Value createValue(VirtualMachineProxyImpl vm, String expectedType, long value) { + if (PsiType.LONG.getPresentableText().equals(expectedType)) { + return vm.mirrorOf(value); + } + if (PsiType.INT.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((int)value); + } + if (PsiType.SHORT.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((short)value); + } + if (PsiType.BYTE.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((byte)value); + } + if (PsiType.CHAR.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((char)value); + } + return null; + } + + public static Value createValue(VirtualMachineProxyImpl vm, String expectedType, boolean value) { + if (PsiType.BOOLEAN.getPresentableText().equals(expectedType)) { + return vm.mirrorOf(value); + } + return null; + } + + public static Value createValue(VirtualMachineProxyImpl vm, String expectedType, char value) { + if (PsiType.CHAR.getPresentableText().equals(expectedType)) { + return vm.mirrorOf(value); + } + if (PsiType.LONG.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((long)value); + } + if (PsiType.INT.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((int)value); + } + if (PsiType.SHORT.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((short)value); + } + if (PsiType.BYTE.getPresentableText().equals(expectedType)) { + return vm.mirrorOf((byte)value); + } + return null; + } + + public static Value createValue(VirtualMachineProxyImpl vm, String value) { + return vm.mirrorOf(value); + } + + public static String truncateString(final String str) { + if (str.length() > MAX_LABEL_SIZE) { + return str.substring(0, MAX_LABEL_SIZE) + "..."; + } + return str; + } + + public static String getThreadStatusText(int statusId) { + switch (statusId) { + case ThreadReference.THREAD_STATUS_MONITOR: + return "MONITOR"; + case ThreadReference.THREAD_STATUS_NOT_STARTED: + return "NOT_STARTED"; + case ThreadReference.THREAD_STATUS_RUNNING: + return "RUNNING"; + case ThreadReference.THREAD_STATUS_SLEEPING: + return "SLEEPING"; + case ThreadReference.THREAD_STATUS_UNKNOWN: + return "UNKNOWN"; + case ThreadReference.THREAD_STATUS_WAIT: + return "WAIT"; + case ThreadReference.THREAD_STATUS_ZOMBIE: + return "ZOMBIE"; + default: + return "UNDEFINED"; + } + } + + //ToDo:[lex] find common implementation + public static void findAllSupertypes(final Type type, final Collection typeNames) { + if (type instanceof ClassType) { + ClassType classType = (ClassType)type; + ClassType superclassType = classType.superclass(); + if (superclassType != null) { + typeNames.add(superclassType); + findAllSupertypes(superclassType, typeNames); + } + List ifaces = classType.allInterfaces(); + for (Iterator it = ifaces.iterator(); it.hasNext();) { + InterfaceType iface = (InterfaceType)it.next(); + typeNames.add(iface); + findAllSupertypes(iface, typeNames); + } + } + if (type instanceof InterfaceType) { + List ifaces = ((InterfaceType)type).superinterfaces(); + for (Iterator it = ifaces.iterator(); it.hasNext();) { + InterfaceType iface = (InterfaceType)it.next(); + typeNames.add(iface); + findAllSupertypes(iface, typeNames); + } + } + } + + public static interface ElementVisitor { + boolean acceptElement(PsiElement element); + } + + public static void iterateLine(Project project, Document document, int line, ElementVisitor visitor) { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + int lineStart; + int lineEnd; + + try { + lineStart = document.getLineStartOffset(line); + lineEnd = document.getLineEndOffset(line); + } + catch (IndexOutOfBoundsException e) { + return; + } + + PsiElement element; + + for (int off = lineStart; off < lineEnd;) { + element = file.findElementAt(off); + if (element != null) { + if (visitor.acceptElement(element)) { + return; + } + else { + off = element.getTextRange().getEndOffset() + 1; + } + } + else { + off++; + } + } + } + + public static String getQualifiedClassName(String jdiName, Project project) { + String name = jdiName; + int startFrom = 0; + for (;;) { + int separator = name.indexOf('$', startFrom); + if(separator != -1) { + String qualifiedName = name.substring(0, separator); + PsiClass psiClass = PsiManager.getInstance(project).findClass(qualifiedName, GlobalSearchScope.allScope(project)); + if(psiClass != null) { + int tail = separator + 1; + while(tail < name.length() && Character.isDigit(name.charAt(tail))) tail ++; + name = qualifiedName + "." + name.substring(tail); + } + startFrom = separator + 1; + } else break; + } + + if(jdiName.equals(name)) { + return jdiName.replace('$', '.'); + } + + return name; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsImpl.java new file mode 100644 index 00000000000..ff8ffbe4609 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/DebuggerUtilsImpl.java @@ -0,0 +1,113 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.actions.DebuggerAction; +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.CodeFragmentFactory; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.ui.*; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.debugger.DebuggerContext; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMExternalizerUtil; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Value; +import org.jdom.Element; + +import java.util.HashMap; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DebuggerUtilsImpl extends DebuggerUtilsEx{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerUtilsImpl"); + + public String getComponentName() { + return "DebuggerUtils"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public PsiExpression substituteThis(PsiExpression expressionWithThis, PsiExpression howToEvaluateThis, Value howToEvaluateThisValue, StackFrameContext context) + throws EvaluateException { + return DebuggerTreeNodeExpression.substituteThis(expressionWithThis, howToEvaluateThis, howToEvaluateThisValue); + } + + public EvaluatorBuilder getEvaluatorBuilder() { + return EvaluatorBuilderImpl.getInstance(); + } + + public DebuggerTreeNode getSelectedNode(DataContext context) { + return DebuggerAction.getSelectedNode(context); + } + + public DebuggerContextImpl getDebuggerContext(DataContext context) { + return DebuggerAction.getDebuggerContext(context); + } + + public Element writeTextWithImports(TextWithImports text) { + Element element = new Element("TextWithImports"); + TextWithImportsImpl textImpl = (TextWithImportsImpl) text; + + element.setAttribute("text", textImpl.saveToString()); + element.setAttribute("type", textImpl.getFactory() == TextWithImportsImpl.EXPRESSION_FACTORY ? "expression" : "code fragment"); + return element; + } + + public TextWithImports readTextWithImports(Element element) { + LOG.assertTrue("TextWithImports".equals(element.getName())); + + String text = element.getAttributeValue("text"); + CodeFragmentFactory factory = "expression".equals(element.getAttributeValue("type")) ? TextWithImportsImpl.EXPRESSION_FACTORY : TextWithImportsImpl.CODE_BLOCK_FACTORY; + return new TextWithImportsImpl(factory, text); + } + + public void writeTextWithImports(Element root, String name, TextWithImports value) { + LOG.assertTrue(((TextWithImportsImpl)value).getFactory() == TextWithImportsImpl.EXPRESSION_FACTORY); + JDOMExternalizerUtil.writeField(root, name, ((TextWithImportsImpl)value).saveToString()); + } + + public TextWithImports readTextWithImports(Element root, String name) { + String s = JDOMExternalizerUtil.readField(root, name); + if(s == null) return null; + return new TextWithImportsImpl(TextWithImportsImpl.EXPRESSION_FACTORY, s); + } + + public TextWithImports createExpressionText(PsiExpression expression) { + return TextWithImportsImpl.createExpressionText(expression); + } + + public TextWithImports createExpressionWithImports(String expression) { + return new TextWithImportsImpl(TextWithImportsImpl.EXPRESSION_FACTORY, expression); + } + + public PsiElement getContextElement(StackFrameContext context) { + return PositionUtil.getContextElement(context); + } + + public PsiClass chooseClassDialog(String title, Project project) { + TreeClassChooserDialog dialog = new TreeClassChooserDialog(title, project); + dialog.show(); + return dialog.getSelectedClass(); + } + + public CompletitionEditor createEditor(Project project, PsiElement context, String recentsId) { + return new DebuggerExpressionComboBox(project, context, recentsId); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueue.java new file mode 100644 index 00000000000..bfe83dc98f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueue.java @@ -0,0 +1,101 @@ +package com.intellij.debugger.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Condition; +import com.intellij.util.concurrency.Semaphore; + +import java.util.LinkedList; + + +public class EventQueue { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.EventQueue"); + + private final LinkedList [] myEvents; + + private E myCurrentEvent; + + private boolean myIsClosed = false; + + public EventQueue (int countPriorities) { + myEvents = new LinkedList[countPriorities]; + for (int i = 0; i < myEvents.length; i++) { + myEvents[i] = new LinkedList(); + } + } + + public boolean isTerminated() { + return myIsClosed; + } + + public void put(E event, int priority) { + LOG.assertTrue(event != null); + if(LOG.isDebugEnabled()) { + LOG.debug("put event " + event); + } + + synchronized(myEvents) { + myEvents[priority].addLast(event); + myEvents.notify(); + } + } + + public void close(){ + LOG.debug("events closed"); + myIsClosed = true; + synchronized(myEvents) { + myEvents.notifyAll(); + } + } + + private E getEvent() throws EventQueueClosedException { + for (int i = 0; i < myEvents.length; i++) { + LinkedList event = (LinkedList)myEvents[i]; + if(!event.isEmpty()) return event.removeFirst(); + } + + if(myIsClosed) throw new EventQueueClosedException(); + + return null; + } + + public E get() throws EventQueueClosedException { + synchronized(myEvents) { + E event = getEvent(); + + if(event == null) { + try { + myCurrentEvent = null; + myEvents.wait(); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + + event = getEvent(); + } + + myCurrentEvent = event; + + LOG.assertTrue(event != null); + if(LOG.isDebugEnabled()) { + LOG.debug("get event " + event); + } + + return event; + } + } + + public boolean isClosed() { + return myIsClosed; + } + + public static interface EventGetter { + public void event(E event); + } + + public void getCurrentEvent(EventGetter getter) { + synchronized(myEvents) { + getter.event(myCurrentEvent); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueueClosedException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueueClosedException.java new file mode 100644 index 00000000000..f2b956ac997 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/EventQueueClosedException.java @@ -0,0 +1,11 @@ +package com.intellij.debugger.impl; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 19, 2004 + * Time: 8:48:37 PM + * To change this template use File | Settings | File Templates. + */ +public class EventQueueClosedException extends Exception{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerParametersRunnerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerParametersRunnerConfigurable.java new file mode 100644 index 00000000000..f3b486f7101 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerParametersRunnerConfigurable.java @@ -0,0 +1,140 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.settings.*; +import com.intellij.debugger.ui.PropertiesDialog; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class GenericDebuggerParametersRunnerConfigurable extends SettingsEditor { + private JPanel myPanel; + private JTextField myAddressField; + private JPanel myShMemPanel; + private JPanel myPortPanel; + private JTextField myPortField; + private boolean myIsLocal = false; + private JButton myDebuggerSettings; + private JRadioButton mySocketTransport; + private JRadioButton myShmemTransport; + private JPanel myTransportPanel; + + public GenericDebuggerParametersRunnerConfigurable(final Project project) { + myDebuggerSettings.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + DebuggerConfigurable debuggerConfigurable = new DebuggerConfigurable(); + PropertiesDialog dialog = new PropertiesDialog(debuggerConfigurable, project); + dialog.show(); + if("".equals(getPort())) { + setPort(GenericDebuggerRunnerSettings.getDefaultPort(getTransport())); + } + updateUI(); + } + }); + + final ActionListener listener = new ActionListener() { + public void actionPerformed(final ActionEvent e) { + updateUI(); + myPanel.repaint(); + } + }; + mySocketTransport.addActionListener(listener); + myShmemTransport.addActionListener(listener); + + updateUI(); + + myTransportPanel.setVisible(false); + + ButtonGroup group = new ButtonGroup(); + group.add(mySocketTransport); + group.add(myShmemTransport); + } + + private boolean isSocket() { + return getTransport() == DebuggerSettings.SOCKET_TRANSPORT; + } + + public void apply() throws ConfigurationException { + } + + public void reset() { + } + + public void disposeUIResources() { + } + + public JComponent createEditor() { + return myPanel; + } + + private void updateUI() { + myPortPanel.setVisible(isSocket()); + myShMemPanel.setVisible(!isSocket()); + } + + public void disposeEditor() { + } + + public void resetEditorFrom(GenericDebuggerRunnerSettings runnerSettings) { + String port = runnerSettings.DEBUG_PORT; + if (port == null) port = ""; + + setIsLocal(runnerSettings.LOCAL); + setTransport(runnerSettings.getTransport()); + setPort(port); + + updateUI(); + } + + private int getTransport() { + if(myIsLocal) { + return DebuggerSettings.getInstance().DEBUGGER_TRANSPORT; + } + else { + return mySocketTransport.isSelected() ? DebuggerSettings.SOCKET_TRANSPORT : DebuggerSettings.SHMEM_TRANSPORT; + } + } + + private String getPort() { + if (isSocket()) { + return myPortField.getText(); + } + else { + return myAddressField.getText(); + } + } + + private void setTransport(int transport) { + mySocketTransport.setSelected(transport == DebuggerSettings.SOCKET_TRANSPORT); + myShmemTransport.setSelected (transport != DebuggerSettings.SOCKET_TRANSPORT); + } + + private void setIsLocal(boolean b) { + myTransportPanel.setVisible(!b); + myDebuggerSettings.setVisible(b); + myIsLocal = b; + } + + private void setPort(String port) { + if (isSocket()) { + myPortField.setText(port); + } + else { + myAddressField.setText(port); + } + } + + public void applyEditorTo(GenericDebuggerRunnerSettings runnerSettings) throws ConfigurationException { + runnerSettings.LOCAL = myIsLocal; + runnerSettings.setTransport(getTransport()); + runnerSettings.setDebugPort(getPort()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunner.java new file mode 100644 index 00000000000..d5628188094 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunner.java @@ -0,0 +1,133 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.impl.DebuggerManagerImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.GenericDebuggerParametersRunnerConfigurable; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.*; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsConfiguration; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; + +public class GenericDebuggerRunner implements JavaProgramRunner { + private static final Icon ICON = IconLoader.getIcon("/actions/startDebugger.png"); + private static final Icon TOOLWINDOW_ICON = IconLoader.getIcon("/general/toolWindowDebugger.png"); + + public static final Icon RERUN_ICON = ICON; + private static final RunnerInfo DEBUGGER_INFO = new RunnerInfo(ToolWindowId.DEBUG, + "Debug selected configuration", + ICON, + TOOLWINDOW_ICON, + ToolWindowId.DEBUG, + "debugging") { + public String getRunContextActionId() { + return "DebugClass"; + } + }; + + public GenericDebuggerRunner() { + } + + public static RunnerInfo getRunnerInfo() { + return DEBUGGER_INFO; + } + + public RunContentDescriptor doExecute(final RunProfileState state, + final RunProfile runProfile, + RunContentDescriptor reuseContent, + final Project project) throws ExecutionException { + final boolean addLvcsLabel = LvcsConfiguration.getInstance().ADD_LABEL_ON_RUNNING; + final LocalVcs localVcs = LocalVcs.getInstance(project); + RunContentDescriptor contentDescriptor = null; + + final DebuggerPanelsManager manager = DebuggerPanelsManager.getInstance(project); + if (state instanceof JavaCommandLine) { + FileDocumentManager.getInstance().saveAllDocuments(); + final JavaCommandLine javaCommandLine = (JavaCommandLine)state; + if (addLvcsLabel) localVcs.addLabel("Debugging " + runProfile.getName(), ""); + RemoteConnection connection = DebuggerManagerImpl.createDebugParameters(javaCommandLine.getJavaParameters(), true, DebuggerSettings.getInstance().DEBUGGER_TRANSPORT, "", false); + contentDescriptor = manager. + attachVirtualMachine(runProfile, this, javaCommandLine, + reuseContent, + connection, true); + } + else if (state instanceof PatchedRunnableState) { + FileDocumentManager.getInstance().saveAllDocuments(); + if (addLvcsLabel) localVcs.addLabel("Debugging " + runProfile.getName(), ""); + final GenericDebuggerRunnerSettings settings = (GenericDebuggerRunnerSettings)state.getRunnerSettings().getData(); + final JavaParameters javaParameters = new JavaParameters(); + contentDescriptor = manager. + attachVirtualMachine(runProfile, this, state, + reuseContent, DebuggerManagerImpl.createDebugParameters(javaParameters, settings, + false), true); + } + else if (state instanceof RemoteState) { + FileDocumentManager.getInstance().saveAllDocuments(); + if (addLvcsLabel) localVcs.addLabel("Starting remote debugging " + runProfile.getName(), ""); + RemoteState remoteState = (RemoteState)state; + contentDescriptor = manager.attachVirtualMachine(runProfile, this, remoteState, reuseContent, + createRemoteDebugConnection(remoteState, state.getRunnerSettings()), false); + } + + return contentDescriptor != null ? contentDescriptor : null; + } + + private RemoteConnection createRemoteDebugConnection(RemoteState connection, final RunnerSettings settings) { + final RemoteConnection remoteConnection = connection.getRemoteConnection(); + + GenericDebuggerRunnerSettings debuggerRunnerSettings = ((GenericDebuggerRunnerSettings)settings.getData()); + + if (debuggerRunnerSettings != null) { + remoteConnection.setUseSockets(debuggerRunnerSettings.getTransport() == DebuggerSettings.SOCKET_TRANSPORT); + remoteConnection.setAddress(debuggerRunnerSettings.DEBUG_PORT); + } + + return remoteConnection; + } + + public RunnerInfo getInfo() { + return DEBUGGER_INFO; + } + + public GenericDebuggerRunnerSettings createConfigurationData(ConfigurationInfoProvider settingsProvider) { + return new GenericDebuggerRunnerSettings(); + } + + public void patch(JavaParameters javaParameters, RunnerSettings settings) throws ExecutionException { + GenericDebuggerRunnerSettings debuggerSettings = ((GenericDebuggerRunnerSettings)settings.getData()); + + DebuggerManagerImpl.createDebugParameters(javaParameters, debuggerSettings, false); + } + + public AnAction[] createActions(ExecutionResult executionResult) { + return new AnAction[0]; + } + + public SettingsEditor getSettingsEditor(RunConfiguration configuration) { + if (configuration instanceof RunConfigurationWithRunnerSettings) { + if (((RunConfigurationWithRunnerSettings)configuration).isSettingsNeeded()) { + return new GenericDebuggerParametersRunnerConfigurable(configuration.getProject()); + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunnerSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunnerSettings.java new file mode 100644 index 00000000000..9e7fed559b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/GenericDebuggerRunnerSettings.java @@ -0,0 +1,89 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.impl.DebuggerManagerImpl; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.configurations.RemoteConnection; +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 org.jdom.Element; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class GenericDebuggerRunnerSettings implements JDOMExternalizable { + public String DEBUG_PORT = ""; + public int TRANSPORT = DebuggerSettings.SOCKET_TRANSPORT; + public boolean LOCAL = true; + + public GenericDebuggerRunnerSettings() { + } + + private void updateDefaultAddress() { + boolean useDefaultPort = "".equals(DEBUG_PORT); + + if(getTransport() == DebuggerSettings.SOCKET_TRANSPORT) { + try { + Integer.parseInt(DEBUG_PORT); + } catch (NumberFormatException e) { + useDefaultPort = true; + } + } + + if (useDefaultPort) { + DEBUG_PORT = getDefaultPort(getTransport()); + } + } + + public static String getDefaultPort(int transport) { + try { + RemoteConnection debugParameters = DebuggerManagerImpl.createDebugParameters(new JavaParameters(), true, transport, "", false); + String address = debugParameters.getAddress(); + int colon = address.indexOf(':'); + if (colon != -1) { + return address.substring(colon + 1); + } + else { + return address; + } + } + catch (ExecutionException e) { + } + + return ""; + } + + public void setDebugPort(String port) { + DEBUG_PORT = port; + updateDefaultAddress(); + } + + public void setTransport(int transport) { + if(getTransport() != transport) { + setDebugPort(""); + } + TRANSPORT = transport; + updateDefaultAddress(); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + updateDefaultAddress(); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public int getTransport() { + if(LOCAL) + return DebuggerSettings.getInstance().DEBUGGER_TRANSPORT; + else + return TRANSPORT; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapFile.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapFile.java new file mode 100644 index 00000000000..9784069a99d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapFile.java @@ -0,0 +1,16 @@ +package com.intellij.debugger.impl; + +import com.intellij.openapi.vfs.VirtualFile; + +/** + * User: lex + * Date: Nov 18, 2003 + * Time: 2:23:38 PM + */ +public class HotSwapFile { + VirtualFile file; + + public HotSwapFile(VirtualFile file) { + this.file = file; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapManager.java new file mode 100644 index 00000000000..995b277eeda --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapManager.java @@ -0,0 +1,175 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.HashMap; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class HotSwapManager implements ProjectComponent{ + + private final Project myProject; + private Map myTimeStamps = new com.intellij.util.containers.HashMap(); + + public HotSwapManager(Project project, DebuggerManagerEx manager) { + myProject = project; + manager.addDebuggerManagerListener(new DebuggerManagerListener() { + public void sessionCreated(DebuggerSession session) { + myTimeStamps.put(session, new Long(System.currentTimeMillis())); + } + + public void sessionRemoved(DebuggerSession session) { + myTimeStamps.remove(session); + } + }); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "HotSwapManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + private long getTimeStamp(DebuggerSession session) { + Long tStamp = myTimeStamps.get(session); + return tStamp != null ? tStamp.longValue() : 0; + } + + void setTimeStamp(DebuggerSession session, long tStamp) { + myTimeStamps.put(session, new Long(tStamp)); + } + + public HashMap getModifiedClasses(final DebuggerSession session, final HotSwapProgress progress) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + final long timeStamp = getTimeStamp(session); + + final HashMap modifiedClasses = new HashMap(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final List allClasses = ProjectRootsTraversing.collectRoots(myProject, ProjectRootsTraversing.FULL_CLASSPATH_RECURSIVE).getRootDirs(); + + final VirtualFile[] allDirs = allClasses.toArray(new VirtualFile[allClasses.size()]); + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + CompilerPathsEx.visitFiles(allDirs, new CompilerPathsEx.FileVisitor() { + + protected void acceptDirectory(final VirtualFile file, final String fileRoot, final String filePath) { + progress.setText("Scanning: " + filePath); + if(file.getFileSystem() instanceof JarFileSystem && StdFileTypes.ARCHIVE.equals(fileTypeManager.getFileTypeByFile(file))) { + if(file.getTimeStamp() > timeStamp) { + super.acceptDirectory(file, fileRoot, filePath); + } + } + else { + super.acceptDirectory(file, fileRoot, filePath); + } + } + + protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { + if (file.getTimeStamp() > timeStamp && StdFileTypes.CLASS.equals(fileTypeManager.getFileTypeByFile(file))) { + if (filePath.endsWith(".class")) { + progress.setText("Scanning: " + filePath); + final String qualifiedName = filePath.substring(fileRoot.length() + 1, filePath.length() - ".class".length()).replace('/', '.'); + modifiedClasses.put(qualifiedName, new HotSwapFile(file)); + } + } + } + }); + } + }); + + return modifiedClasses; + } + + public static HotSwapManager getInstance(Project project) { + return project.getComponent(HotSwapManager.class); + } + + public void reloadClasses(DebuggerSession session, HashMap classesToReload, HotSwapProgress progress) { + long newSwapTime = System.currentTimeMillis(); + new ReloadClassesWorker(session, progress).reloadClasses(classesToReload); + setTimeStamp(session, newSwapTime); + } + + public static HashMap> getModifiedClasses(final List sessions, final HotSwapProgress swapProgress) { + final HashMap> modifiedClasses = new HashMap>(); + + final MultiProcessCommand scanClassesCommand = new MultiProcessCommand(); + + swapProgress.setCancelWorker(new Runnable() { + public void run() { + scanClassesCommand.terminate(); + } + }); + + for (Iterator iterator = sessions.iterator(); iterator.hasNext();) { + final DebuggerSession debuggerSession = iterator.next(); + if(debuggerSession.isAttached()) { + scanClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() { + protected void action() throws Exception { + swapProgress.setDebuggerSession(debuggerSession); + HashMap sessionClasses = getInstance(swapProgress.getProject()).getModifiedClasses(debuggerSession, swapProgress); + if(!sessionClasses.isEmpty()) { + modifiedClasses.put(debuggerSession, sessionClasses); + } + } + }); + } + } + + swapProgress.setTitle("Scanning for classes to reload..."); + scanClassesCommand.run(); + + return swapProgress.isCancelled() ? new HashMap>() : modifiedClasses; + } + + public static void reloadModifiedClasses(final HashMap> modifiedClasses, final HotSwapProgress reloadClassesProgress) { + final MultiProcessCommand reloadClassesCommand = new MultiProcessCommand(); + + reloadClassesProgress.setCancelWorker(new Runnable() { + public void run() { + reloadClassesCommand.terminate(); + } + }); + + for (Iterator iterator = modifiedClasses.keySet().iterator(); iterator.hasNext();) { + final DebuggerSession debuggerSession = iterator.next(); + reloadClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() { + protected void action() throws Exception { + reloadClassesProgress.setDebuggerSession(debuggerSession); + getInstance(reloadClassesProgress.getProject()).reloadClasses(debuggerSession, modifiedClasses.get(debuggerSession), reloadClassesProgress); + } + }); + } + + reloadClassesProgress.setTitle("Reloading classes..."); + reloadClassesCommand.run(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapProgress.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapProgress.java new file mode 100644 index 00000000000..b5d40669a2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/HotSwapProgress.java @@ -0,0 +1,106 @@ +package com.intellij.debugger.impl; + +import com.intellij.Patches; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.util.ui.MessageCategory; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.progress.util.SmoothProgressAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IJSwingUtilities; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.ReferenceType; + +/** + * User: lex + * Date: Nov 18, 2003 + * Time: 2:20:18 PM + */ +public abstract class HotSwapProgress { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.HotSwapProgress"); + private final Project myProject; + private Runnable myCancelWorker; + private boolean myIsCancelled; + + public HotSwapProgress(Project project) { + myProject = project; + } + + public Project getProject() { + return myProject; + } + + public abstract void addMessage(final int type, final String[] text, final VirtualFile file, final int line, final int column); + + public abstract void setText(String text); + + public abstract void setTitle(String title); + + public abstract void setFraction(double v); + + void message(final ReferenceType reference, final String text, final int category) { + IJSwingUtilities.invoke(new Runnable() { + public void run() { + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + String message = text; + VirtualFile file = null; + int lineIndex = 0; + + if (reference != null) { + String className = DebuggerUtilsEx.signatureToName(reference.signature()); + GlobalSearchScope scope = GlobalSearchScope.allScope(getProject()); + PsiClass cls = PsiManager.getInstance(getProject()).findClass(className, scope); + if (cls != null) { + file = cls.getContainingFile().getVirtualFile(); + lineIndex = StringUtil.offsetToLineNumber(cls.getContainingFile().getText(), cls.getTextOffset()); + } + + message = "Class " + DebuggerUtilsEx.signatureToName(reference.signature()) + " : " + text; + } + + addMessage( + category, + new String[]{message}, + file, lineIndex + 1, 1); + } + }); + } + + void error(ReferenceType reference, String text) { + message(reference, text, MessageCategory.ERROR); + } + + void message(ReferenceType reference, String text) { + message(reference, text, MessageCategory.INFORMATION); + } + + public void setCancelWorker(Runnable cancel) { + myCancelWorker = cancel; + } + + public void cancel() { + myIsCancelled = true; + if(myCancelWorker != null) myCancelWorker.run(); + } + + public void finished() { + } + + public abstract void setDebuggerSession(DebuggerSession debuggerSession); + + public boolean isCancelled() { + return myIsCancelled; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEvent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEvent.java new file mode 100644 index 00000000000..c6c1252f3e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEvent.java @@ -0,0 +1,15 @@ +package com.intellij.debugger.impl; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 7, 2004 + * Time: 2:40:47 PM + * To change this template use File | Settings | File Templates. + */ +public interface InvokeAndWaitEvent { + public void release(); + public void hold (); + + public void waitFor(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEventImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEventImpl.java new file mode 100644 index 00000000000..830983e5d21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitEventImpl.java @@ -0,0 +1,29 @@ +package com.intellij.debugger.impl; + +import com.intellij.util.concurrency.Semaphore; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 27, 2004 + * Time: 12:56:52 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class InvokeAndWaitEventImpl implements InvokeAndWaitEvent{ + private Semaphore myInvokeAndWaitSemaphore; + + public final void release() { + if(myInvokeAndWaitSemaphore != null) myInvokeAndWaitSemaphore.up(); + } + + public final void hold() { + if(myInvokeAndWaitSemaphore == null) { + myInvokeAndWaitSemaphore = new Semaphore(); + } + myInvokeAndWaitSemaphore.down(); + } + + public void waitFor() { + myInvokeAndWaitSemaphore.waitFor(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitThread.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitThread.java new file mode 100644 index 00000000000..79b3884c406 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeAndWaitThread.java @@ -0,0 +1,30 @@ +package com.intellij.debugger.impl; + + + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Feb 24, 2004 + * Time: 3:27:55 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class InvokeAndWaitThread extends InvokeThread{ + + public InvokeAndWaitThread(String name, int countPriorities) { + super(name, countPriorities); + } + + //Do not remove this code + //Otherwise it will be impossible to override invokeLater method + public void invokeLater(E e, int priority) { + super.invokeLater(e, priority); + } + + public void invokeAndWait(final E runnable, int priority) { + runnable.hold(); + invokeLater(runnable, priority); + runnable.waitFor(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeThread.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeThread.java new file mode 100644 index 00000000000..982a23500fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/InvokeThread.java @@ -0,0 +1,133 @@ +package com.intellij.debugger.impl; + +import com.intellij.openapi.diagnostic.Logger; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 19, 2004 + * Time: 11:42:03 AM + * To change this template use File | Settings | File Templates. + */ +public abstract class InvokeThread { + private static final int RESTART_TIMEOUT = 500; + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.InvokeThread"); + private final String myWorkerThreadName; + + private static int N = 0; + + protected static class WorkerThread extends Thread { + private final InvokeThread myOwner; + + private boolean myIsInterrupted = false; + + protected WorkerThread(InvokeThread owner, String name) { + super(name + (N ++)); + myOwner = owner; + } + + public void interrupt() { + myIsInterrupted = true; + super.interrupt(); + } + + public boolean isInterrupted() { + return myIsInterrupted || super.isInterrupted(); + } + + public InvokeThread getOwner() { + return myOwner; + } + }; + + protected final EventQueue myEvents; + + private WorkerThread myWorkerThread = null; + + public InvokeThread(String name, int countPriorites) { + myEvents = new EventQueue(countPriorites); + myWorkerThreadName = name; + startNewWorkerThread(); + } + + protected abstract void processEvent(E e); + + protected void startNewWorkerThread() { + WorkerThread workerThread = new WorkerThread(this, myWorkerThreadName) { + public void run() { + InvokeThread.this.run(); + } + }; + myWorkerThread = workerThread; + workerThread.start(); + } + + protected void restartWorkerThread() { + getWorkerThread().interrupt(); + try { + getWorkerThread().join(RESTART_TIMEOUT); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + startNewWorkerThread(); + } + + public void run() { + Thread current = Thread.currentThread(); + + for(;;) { + try { + if(current.isInterrupted()) break; + + if(getWorkerThread() != current) { + LOG.assertTrue(false, "Expected " + current + " instead of " + getWorkerThread()); + } + + processEvent(myEvents.get()); + } + catch (EventQueueClosedException e) { + break; + } + catch (RuntimeException e) { + if(e.getCause() instanceof InterruptedException) { + break; + } else { + LOG.error(e); + } + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Thread " + this.toString() + " exited"); + } + } + + protected static InvokeThread currentThread() { + Thread thread = Thread.currentThread(); + return thread instanceof WorkerThread ? ((WorkerThread)thread).getOwner() : null; + } + + public void invokeLater(E r, int priority) { + if(LOG.isDebugEnabled()) { + LOG.debug("invokeLater " + r + " in " + this); + } + myEvents.put(r, priority); + } + + protected void switchToThread(WorkerThread newWorkerThread) { + LOG.assertTrue(Thread.currentThread() instanceof WorkerThread); + myWorkerThread = newWorkerThread; + LOG.debug("Closing " + Thread.currentThread() + " new thread = " + newWorkerThread); + Thread.currentThread().interrupt(); + } + + public Thread getWorkerThread() { + return myWorkerThread; + } + + public void close() { + myEvents.close(); + LOG.debug("Closing evaluation"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/MultiProcessCommand.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/MultiProcessCommand.java new file mode 100644 index 00000000000..59109d76114 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/MultiProcessCommand.java @@ -0,0 +1,53 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.managerThread.DebuggerCommand; +import com.intellij.openapi.util.Pair; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class MultiProcessCommand implements Runnable{ + private final List> myCommands = new ArrayList>(); + + public void run() { + for(;;) { + Pair pair; + + synchronized(myCommands) { + if(myCommands.isEmpty()) break; + + pair = myCommands.get(0); + } + + pair.getFirst().getManagerThread().invokeAndWait(pair.getSecond()); + + synchronized(myCommands) { + if(myCommands.isEmpty()) break; + + myCommands.remove(0); + } + } + } + + public void terminate() { + synchronized(myCommands) { + if(myCommands.isEmpty()) return; + Pair pair = myCommands.get(0); + pair.getFirst().getManagerThread().terminateCommand(pair.getSecond()); + myCommands.clear(); + } + } + + public void addCommand(DebugProcessImpl debugProcess, DebuggerCommandImpl command) { + myCommands.add(new Pair(debugProcess, command)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/PositionUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/PositionUtil.java new file mode 100644 index 00000000000..3e0297caef2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/PositionUtil.java @@ -0,0 +1,28 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.openapi.util.Computable; +/** + * User: lex + * Date: Oct 29, 2003 + * Time: 9:29:36 PM + */ +public class PositionUtil extends ContextUtil { + public static SourcePosition getSourcePosition(final StackFrameContext context) { + if(context instanceof DebuggerContextImpl) return ((DebuggerContextImpl)context).getSourcePosition(); + + return ContextUtil.getSourcePosition(context); + } + + public static PsiElement getContextElement(final StackFrameContext context) { + if(context instanceof DebuggerContextImpl) return ((DebuggerContextImpl) context).getContextElement(); + + return ContextUtil.getContextElement(context); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/ReloadClassesWorker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/ReloadClassesWorker.java new file mode 100644 index 00000000000..3381455bf04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/ReloadClassesWorker.java @@ -0,0 +1,297 @@ +package com.intellij.debugger.impl; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.HotSwapFile; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.MethodSignature; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.MessageCategory; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.Method; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.VMDisconnectedException; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 10, 2004 + * Time: 7:12:57 PM + * To change this template use File | Settings | File Templates. + */ +class ReloadClassesWorker { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.ReloadClassesWorker"); + + private final DebuggerSession myDebuggerSession; + private final HotSwapProgress myProgress; + + public ReloadClassesWorker(DebuggerSession session, HotSwapProgress progress) { + myDebuggerSession = session; + myProgress = progress; + } + + private DebugProcessImpl getDebugProcess() { + return myDebuggerSession.getProcess(); + } + + private Project getProject() { + return myDebuggerSession.getProject(); + } + + private void reportObsoleteFrames(final Map methodsOnTheStack) { + Project project = getProject(); + PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Runnable() { + public void run() { + VirtualMachineProxyImpl vm = getDebugProcess().getVirtualMachineProxy(); + for (Iterator it = vm.allThreads().iterator(); it.hasNext();) { + try { + ThreadReferenceProxyImpl threadProxy = (ThreadReferenceProxyImpl)it.next(); + if (threadProxy.isSuspended()) { + PsiMethod[] methods = methodsOnTheStack.get(threadProxy); + if (methods != null) { + for (Iterator itf = threadProxy.frames().iterator(); itf.hasNext();) { + StackFrameProxyImpl stackFrame = (StackFrameProxyImpl)itf.next(); + if (stackFrame.location().method().isObsolete()) { + PsiMethod method = methods[stackFrame.getFrameIndex()]; + + if(method != null) { + PsiFile psiFile = method.getContainingFile(); + VirtualFile file = null; + int lineIndex = 0; + + if (psiFile != null) { + file = psiFile.getVirtualFile(); + if(file != null) { + lineIndex = StringUtil.offsetToLineNumber(psiFile.getText(), method.getTextOffset()); + } + + MethodSignature sig = method.getSignature(PsiSubstitutor.EMPTY); + myProgress.addMessage(MessageCategory.WARNING, new String[]{sig + " : Breakpoints will be ignored for the obsolete version of the method. "}, + file, lineIndex + 1, 1); + } + } + } + } + } + } + } + catch (EvaluateException e) { + } + catch (VMDisconnectedException e) { + } + } + } + }); + } + + private Map getMethodsOnTheStack() { + final Map myThreadsToMethods = new HashMap(); + + PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() { + public void run() { + VirtualMachineProxyImpl vm = getDebugProcess().getVirtualMachineProxy(); + try { + for (Iterator it = vm.allThreads().iterator(); it.hasNext();) { + ThreadReferenceProxyImpl threadProxy = (ThreadReferenceProxyImpl)it.next(); + if (threadProxy.isSuspended()) { + List frames = threadProxy.frames(); + + PsiMethod[] methods = new PsiMethod[frames.size()]; + myThreadsToMethods.put(threadProxy, methods); + for (Iterator itf = frames.iterator(); itf.hasNext();) { + StackFrameProxyImpl stackFrame = (StackFrameProxyImpl)itf.next(); + methods[stackFrame.getFrameIndex()] = findPsiMethod(getProject(), stackFrame); + } + } + } + } + catch (EvaluateException e) { + } + } + }); + + return myThreadsToMethods; + } + + private PsiMethod findPsiMethod(Project project, StackFrameProxyImpl stackFrame) { + try { + String className = DebuggerUtilsEx.signatureToName(stackFrame.location().declaringType().signature()); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + PsiClass cls = PsiManager.getInstance(project).findClass(className, scope); + if(cls == null) return null; + + Method method = stackFrame.location().method(); + PsiMethod[] methods = cls.findMethodsByName(method.name(), false); + nextMethod: for (int i = 0; i < methods.length; i++) { + PsiMethod m = methods[i]; + if (method.isStatic() == m.hasModifierProperty(PsiModifier.STATIC)) { + PsiParameter[] params = m.getParameterList().getParameters(); + List argTypes = method.argumentTypeNames(); + if (argTypes.size() == params.length) { + int j = 0; + for (Iterator iterator = argTypes.iterator(); iterator.hasNext(); j++) { + String typeName = (String)iterator.next(); + if (!params[j].getType().getCanonicalText().equals(typeName)) continue nextMethod; + } + return m; + } + } + } + } + catch (EvaluateException e) { + e.printStackTrace(); + } + + return null; + } + + private void processException(ReferenceType reference, Throwable e) { + if (e.getMessage() != null) { + myProgress.error(reference, e.getMessage()); + } + + if (e instanceof ProcessCanceledException) { + myProgress.message(null, "Operation canceled"); + return; + } + + if (e instanceof UnsupportedOperationException) { + myProgress.error(reference, "Operation not supported by VM"); + } + else if (e instanceof NoClassDefFoundError) { + myProgress.error(reference, "Class not found"); + } + else if (e instanceof VerifyError) { + myProgress.error(reference, "Verification error"); + } + else if (e instanceof UnsupportedClassVersionError) { + myProgress.error(reference, "Unsupported class version"); + } + else if (e instanceof ClassFormatError) { + myProgress.error(reference, "Class format error"); + } + else if (e instanceof ClassCircularityError) { + myProgress.error(reference, "Class circularity error"); + } + else { + myProgress.error(reference, "Exception while reloading classes : " + e.getClass().getName()); + } + } + + private byte[] loadFile(VirtualFile file) { + try { + return file.contentsToByteArray(); + } + catch (IOException e) { + return null; + } + } + + public void reloadClasses(final HashMap modifiedClasses) { + if(modifiedClasses == null) { + myProgress.addMessage(MessageCategory.INFORMATION, new String[] { "Loaded classes are up to date. Nothing to reload." }, null, -1, -1); + return; + } + + VirtualMachineProxyImpl virtualMachineProxy = getDebugProcess().getVirtualMachineProxy(); + if(virtualMachineProxy == null) return; + + virtualMachineProxy.suspend(); + + final Project project = getDebugProcess().getProject(); + try { + Map methodsOnTheStack = getMethodsOnTheStack(); + + Map redefineMap = new HashMap(); + int classN = 0; + for (Iterator iterator = modifiedClasses.keySet().iterator(); iterator.hasNext();) { + classN++; + String qualifiedName = (String)iterator.next(); + if (qualifiedName != null) { + myProgress.setText(qualifiedName); + myProgress.setFraction(classN / (double)modifiedClasses.size()); + } + + final HotSwapFile fileDescr = modifiedClasses.get(qualifiedName); + + //[max]: Generic enabled Computable confuses degenerator. + byte[] buffer = (byte[])ApplicationManager.getApplication().runReadAction(new Computable() { + public Object compute() { + return loadFile(fileDescr.file); + } + }); + + redefineMap.clear(); + List classes = virtualMachineProxy.classesByName(qualifiedName); + for (Iterator i = classes.iterator(); i.hasNext();) { + ReferenceType reference = (ReferenceType)i.next(); + + if (buffer == null) { + myProgress.error(reference, "I/O error"); + } + redefineMap.put(reference, buffer); + } + getDebugProcess().getVirtualMachineProxy().redefineClasses(redefineMap); + //myProgress.addMessage(MessageCategory.INFORMATION, new String[] { qualifiedName + " reloaded" }, null, -1, -1); + } + myProgress.setFraction(1); + myProgress.message(null, + modifiedClasses.size() + " class" + (modifiedClasses.size() == 1 ? "" : "es") + + " reloaded."); + if (LOG.isDebugEnabled()) { + LOG.debug("classes reloaded"); + } + reportObsoleteFrames(methodsOnTheStack); + if (LOG.isDebugEnabled()) { + LOG.debug("obsolete frames reported"); + } + } + catch (Throwable e) { + processException(null, e); + } + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager().reloadBreakpoints(); + (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager().updateAllRequests(); + if (LOG.isDebugEnabled()) { + LOG.debug("requests updated"); + LOG.debug("time stamp set"); + } + myDebuggerSession.refresh(); + + getDebugProcess().getManagerThread().invokeLater(new DebuggerCommandImpl() { + protected void action() throws Exception { + try { + getDebugProcess().getVirtualMachineProxy().resume(); + } + catch (Exception e) { + processException(null, e); + } + } + }); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/SimpleStackFrameContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/SimpleStackFrameContext.java new file mode 100644 index 00000000000..499c430a56e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/SimpleStackFrameContext.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.impl; + +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.jdi.StackFrameProxy; + +/** + * @author Eugene Zhuravlev + * Date: Dec 30, 2004 + */ +public final class SimpleStackFrameContext implements StackFrameContext{ + private final StackFrameProxy myProxy; + private final DebugProcess myProcess; + + public SimpleStackFrameContext(StackFrameProxy proxy, DebugProcess process) { + myProxy = proxy; + myProcess = process; + } + + public StackFrameProxy getFrameProxy() { + return myProxy; + } + + public DebugProcess getDebugProcess() { + return myProcess; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ArrayItemData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ArrayItemData.java new file mode 100644 index 00000000000..e1e12d621e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ArrayItemData.java @@ -0,0 +1,64 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.sun.jdi.ArrayReference; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public final class ArrayItemData extends DescriptorData{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.descriptors.data.ArrayItemData"); + + private ArrayReference myArray; + private int myIndex; + + public ArrayItemData(ArrayReference arrRef, int idx) { + super(ArrayElementDescriptorImpl.class); + LOG.assertTrue(arrRef != null); + LOG.assertTrue(0 <= idx); + if(LOG.isDebugEnabled()) { + LOG.assertTrue(idx <= arrRef.length()); + } + myArray = arrRef; + myIndex = idx; + } + + protected ArrayElementDescriptorImpl createDescriptorImpl(Project project) { + return new ArrayElementDescriptorImpl(project, myArray, myIndex); + } + + public DisplayKey getDisplayKey() { + return new ArrayItemDisplayKeyImpl(myIndex); + } + + public boolean equals(Object object) { + if(!(object instanceof ArrayItemData)) return false; + return ((ArrayItemData)object).myArray == myArray && + ((ArrayItemData)object).myIndex == myIndex; + } + + public int hashCode() { + return myArray.hashCode() + myIndex; + } + + private static class ArrayItemDisplayKeyImpl implements DisplayKey { + private final int myIndex; + + public ArrayItemDisplayKeyImpl(int index) { + myIndex = index; + } + + public boolean equals(Object o) { + if(!(o instanceof ArrayItemDisplayKeyImpl)) return false; + return ((ArrayItemDisplayKeyImpl)o).myIndex == myIndex; + } + + public int hashCode() { + return 0; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorData.java new file mode 100644 index 00000000000..b43b9348bee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorData.java @@ -0,0 +1,38 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public abstract class DescriptorData implements DescriptorKey{ + private static final Key DESCRIPTOR_DATA = new Key("DESCRIPTOR_DATA"); + + private final Class myDescriptorClass; + + protected DescriptorData(Class descriptorClass) { + myDescriptorClass = descriptorClass; + } + + public T createDescriptor(Project project) { + T descriptor = createDescriptorImpl(project); + descriptor.putUserData(DESCRIPTOR_DATA, this); + return descriptor; + } + + protected abstract T createDescriptorImpl(Project project); + + public abstract boolean equals(Object object); + + public abstract int hashCode(); + + public abstract DisplayKey getDisplayKey(); + + public static DescriptorData getDescriptorData(T descriptor) { + return (DescriptorData)descriptor.getUserData(DESCRIPTOR_DATA); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorKey.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorKey.java new file mode 100644 index 00000000000..10357f7d63f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DescriptorKey.java @@ -0,0 +1,11 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.tree.NodeDescriptor; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface DescriptorKey { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DisplayKey.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DisplayKey.java new file mode 100644 index 00000000000..8b0df702ac6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/DisplayKey.java @@ -0,0 +1,14 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface DisplayKey extends DescriptorKey{ + public abstract boolean equals(Object object); + + public abstract int hashCode(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/FieldData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/FieldData.java new file mode 100644 index 00000000000..53e0fada199 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/FieldData.java @@ -0,0 +1,47 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Field; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public final class FieldData extends DescriptorData{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.descriptors.data.FieldData"); + + private final ObjectReference myObjRef; + private final Field myField; + + public FieldData(ObjectReference objRef, Field field) { + super(FieldDescriptorImpl.class); + LOG.assertTrue(objRef != null); + LOG.assertTrue(field != null); + myObjRef = objRef; + myField = field; + } + + protected FieldDescriptorImpl createDescriptorImpl(Project project) { + return new FieldDescriptorImpl(project, myObjRef, myField); + } + + public boolean equals(Object object) { + if(!(object instanceof FieldData)) { + return false; + } + final FieldData fieldData = (FieldData)object; + return (fieldData.myField == myField) && (fieldData.myObjRef.equals(myObjRef)); + } + + public int hashCode() { + return myObjRef.hashCode() + myField.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myField); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/LocalData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/LocalData.java new file mode 100644 index 00000000000..b2cef56d84d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/LocalData.java @@ -0,0 +1,37 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.openapi.project.Project; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class LocalData extends DescriptorData{ + private final LocalVariableProxyImpl myLocalVariable; + + public LocalData(LocalVariableProxyImpl localVariable) { + super(LocalVariableDescriptorImpl.class); + myLocalVariable = localVariable; + } + + protected LocalVariableDescriptorImpl createDescriptorImpl(Project project) { + return new LocalVariableDescriptorImpl(project, myLocalVariable); + } + + public boolean equals(Object object) { + if(!(object instanceof LocalData)) return false; + + return ((LocalData)object).myLocalVariable.equals(myLocalVariable); + } + + public int hashCode() { + return myLocalVariable.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myLocalVariable); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/SimpleDisplayKey.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/SimpleDisplayKey.java new file mode 100644 index 00000000000..2491eed69a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/SimpleDisplayKey.java @@ -0,0 +1,25 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class SimpleDisplayKey implements DisplayKey{ + private final Object myKey; + + public SimpleDisplayKey(Object key) { + myKey = key; + } + + public boolean equals(Object o) { + if(!(o instanceof SimpleDisplayKey)) return false; + return ((SimpleDisplayKey)o).myKey.equals(myKey); + } + + public int hashCode() { + return myKey.hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StackFrameData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StackFrameData.java new file mode 100644 index 00000000000..82cbecd6839 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StackFrameData.java @@ -0,0 +1,42 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class StackFrameData extends DescriptorData{ + private static final Key STACK_FRAME = new Key("STACK_FRAME"); + private final StackFrameProxyImpl myFrame; + + public StackFrameData(StackFrameProxyImpl frame) { + super(StackFrameDescriptorImpl.class); + myFrame = frame; + } + + protected StackFrameDescriptorImpl createDescriptorImpl(Project project) { + return new StackFrameDescriptorImpl(myFrame); + } + + public boolean equals(Object object) { + if(!(object instanceof StackFrameData)) return false; + + return ((StackFrameData)object).myFrame == myFrame; + } + + public int hashCode() { + return myFrame.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(STACK_FRAME); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticData.java new file mode 100644 index 00000000000..9ae133d348e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticData.java @@ -0,0 +1,50 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.sun.jdi.ReferenceType; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.ui.impl.watch.StaticDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public final class StaticData extends DescriptorData{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.descriptors.data.StaticData"); + + private static final Key STATIC = new Key("STATIC"); + + private final ReferenceType myRefType; + + public StaticData(ReferenceType refType) { + super(StaticDescriptorImpl.class); + LOG.assertTrue(refType != null); + myRefType = refType; + } + + public ReferenceType getRefType() { + return myRefType; + } + + protected StaticDescriptorImpl createDescriptorImpl(Project project) { + return new StaticDescriptorImpl(myRefType); + } + + public boolean equals(Object object) { + if(!(object instanceof StaticData)) return false; + + return true; + } + + public int hashCode() { + return STATIC.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(STATIC); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticFieldData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticFieldData.java new file mode 100644 index 00000000000..9a3e6369f66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/StaticFieldData.java @@ -0,0 +1,42 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.sun.jdi.Field; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public final class StaticFieldData extends DescriptorData{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.descriptors.data.StaticFieldData"); + private final Field myField; + + public StaticFieldData(Field field) { + super(FieldDescriptorImpl.class); + LOG.assertTrue(field != null); + myField = field; + } + + protected FieldDescriptorImpl createDescriptorImpl(Project project) { + return new FieldDescriptorImpl(project, null, myField); + } + + public boolean equals(Object object) { + if(!(object instanceof StaticFieldData)) { + return false; + } + final StaticFieldData fieldData = (StaticFieldData)object; + return (fieldData.myField == myField); + } + + public int hashCode() { + return myField.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myField); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThisData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThisData.java new file mode 100644 index 00000000000..8a5e3291897 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThisData.java @@ -0,0 +1,49 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.ThisDescriptorImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.sun.jdi.Value; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public final class ThisData extends DescriptorData{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.descriptors.data.ThisData"); + + private static final Key THIS = new Key("THIS"); + + private final Value myThisValue; + + public ThisData(Value thisValue) { + super(ThisDescriptorImpl.class); + LOG.assertTrue(thisValue != null); + myThisValue = thisValue; + } + + public Value getThisValue() { + return myThisValue; + } + + protected ThisDescriptorImpl createDescriptorImpl(Project project) { + return new ThisDescriptorImpl(project, myThisValue); + } + + public boolean equals(Object object) { + if(!(object instanceof ThisData)) return false; + + return true; + } + + public int hashCode() { + return THIS.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(THIS); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadData.java new file mode 100644 index 00000000000..46ebc957cbc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadData.java @@ -0,0 +1,37 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.openapi.project.Project; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class ThreadData extends DescriptorData { + private final ThreadReferenceProxyImpl myThread; + public ThreadData(ThreadReferenceProxyImpl thread) { + super(ThreadDescriptorImpl.class); + myThread = thread; + } + + protected ThreadDescriptorImpl createDescriptorImpl(Project project) { + return new ThreadDescriptorImpl(myThread); + } + + public boolean equals(Object object) { + if(!(object instanceof ThreadData)) return false; + + return ((ThreadData)object).myThread == myThread; + } + + public int hashCode() { + return myThread.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myThread); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadGroupData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadGroupData.java new file mode 100644 index 00000000000..f534818afe5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/ThreadGroupData.java @@ -0,0 +1,38 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.ThreadGroupDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.openapi.project.Project; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class ThreadGroupData extends DescriptorData{ + private final ThreadGroupReferenceProxyImpl myThreadGroup; + + public ThreadGroupData(ThreadGroupReferenceProxyImpl threadGroup) { + super(ThreadGroupDescriptorImpl.class); + myThreadGroup = threadGroup; + } + + protected ThreadGroupDescriptorImpl createDescriptorImpl(Project project) { + return new ThreadGroupDescriptorImpl(myThreadGroup); + } + + public boolean equals(Object object) { + if(!(object instanceof ThreadGroupData)) return false; + + return ((ThreadGroupData)object).myThreadGroup == myThreadGroup; + } + + public int hashCode() { + return myThreadGroup.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myThreadGroup); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/UserExpressionData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/UserExpressionData.java new file mode 100644 index 00000000000..4df7c007855 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/impl/descriptors/data/UserExpressionData.java @@ -0,0 +1,48 @@ +package com.intellij.debugger.impl.descriptors.data; + +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.ui.impl.watch.UserExpressionDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.openapi.project.Project; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class UserExpressionData extends DescriptorData{ + private final ValueDescriptorImpl myParentDescriptor; + private final String myTypeName; + private final String myName; + protected TextWithImportsImpl myText; + + public UserExpressionData( + ValueDescriptorImpl parentDescriptor, + String typeName, + String name, + TextWithImportsImpl text) { + super(UserExpressionDescriptorImpl.class); + myParentDescriptor = parentDescriptor; + myTypeName = typeName; + myName = name; + myText = text; + } + + protected UserExpressionDescriptorImpl createDescriptorImpl(Project project) { + return new UserExpressionDescriptorImpl(project, myParentDescriptor, myTypeName, myName, myText); + } + + public boolean equals(Object object) { + if(!(object instanceof UserExpressionData)) return false; + + return ((UserExpressionData)object).myName == myName; + } + + public int hashCode() { + return myName.hashCode(); + } + + public DisplayKey getDisplayKey() { + return new SimpleDisplayKey(myTypeName + myName); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiProxy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiProxy.java new file mode 100644 index 00000000000..b864c04bdc1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiProxy.java @@ -0,0 +1,35 @@ +package com.intellij.debugger.jdi; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jul 10, 2003 + * Time: 4:53:44 PM + * To change this template use Options | File Templates. + */ +public abstract class JdiProxy { + protected JdiTimer myTimer; + private int myTimeStamp = 0; + + public JdiProxy(JdiTimer timer) { + myTimer = timer; + myTimeStamp = myTimer.getCurrentTime(); + } + + protected void checkValid() { + if(!isValid()) { + myTimeStamp = myTimer.getCurrentTime(); + clearCaches(); + } + } + + /** + * @deprecated for testing only + * @return + */ + public boolean isValid() { + return myTimeStamp == myTimer.getCurrentTime(); + } + + protected abstract void clearCaches(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiTimer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiTimer.java new file mode 100644 index 00000000000..fa8eeb4fb00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/JdiTimer.java @@ -0,0 +1,12 @@ +package com.intellij.debugger.jdi; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jul 10, 2003 + * Time: 5:13:25 PM + * To change this template use Options | File Templates. + */ +interface JdiTimer { + int getCurrentTime(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/LocalVariableProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/LocalVariableProxyImpl.java new file mode 100644 index 00000000000..1d1dad7b40a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/LocalVariableProxyImpl.java @@ -0,0 +1,66 @@ +package com.intellij.debugger.jdi; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.jdi.LocalVariableProxy; +import com.intellij.openapi.util.Comparing; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.LocalVariable; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class LocalVariableProxyImpl extends JdiProxy implements LocalVariableProxy { + private final StackFrameProxyImpl myFrame; + private final String myVariableName; + + private LocalVariable myVariable; + + public LocalVariableProxyImpl(StackFrameProxyImpl frame, LocalVariable variable) { + super(frame.myTimer); + myFrame = frame; + myVariableName = variable.name(); + + myVariable = variable; + } + + protected void clearCaches() { + myVariable = null; + } + + public LocalVariable getVariable() throws EvaluateException { + checkValid(); + if(myVariable == null) { + myVariable = myFrame.visibleVariableByNameInt(myVariableName); + + if(myVariable == null) { + //myFrame is not this variable's frame + throw EvaluateExceptionUtil.createEvaluateException(new IncompatibleThreadStateException()); + } + } + + return myVariable; + } + + public StackFrameProxyImpl getFrame() { + return myFrame; + } + + public int hashCode() { + return myFrame.hashCode(); + } + + public boolean equals(Object o) { + if(o instanceof LocalVariableProxyImpl) { + LocalVariableProxyImpl proxy = (LocalVariableProxyImpl)o; + return Comparing.equal(proxy.myFrame, myFrame) && myVariableName.equals(proxy.myVariableName); + } + return false; + } + + public String name() { + return myVariableName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java new file mode 100644 index 00000000000..4002df34072 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java @@ -0,0 +1,124 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class ObjectReferenceProxyImpl extends JdiProxy { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.ObjectReferenceProxyImpl"); + private final ObjectReference myObjectReference; + + //caches + private ReferenceType myReferenceType; + private Type myType; + private boolean myIsCollected = false; + + public ObjectReferenceProxyImpl(VirtualMachineProxyImpl virtualMachineProxy, ObjectReference objectReference) { + super(virtualMachineProxy); + LOG.assertTrue(objectReference != null); + myObjectReference = objectReference; + } + + public ObjectReference getObjectReference() { + checkValid(); + return isCollected() ? null : myObjectReference; + } + + public VirtualMachineProxyImpl getVirtualMachineProxy() { + return (VirtualMachineProxyImpl) myTimer; + } + + public ReferenceType referenceType() { + checkValid(); + if (myReferenceType == null) { + myReferenceType = getObjectReference().referenceType(); + } + return myReferenceType; + } + + public Type type() { + checkValid(); + if (myType == null) { + myType = getObjectReference().type(); + } + return myType; + } + + public String toString() { + return "ObjectReferenceProxyImpl: " + getObjectReference().toString() + " " + super.toString(); + } + + public Map getValues(List list) { + return getObjectReference().getValues(list); + } + + public void setValue(Field field, Value value) throws InvalidTypeException, ClassNotLoadedException { + getObjectReference().setValue(field, value); + } + + public boolean isCollected() { + checkValid(); + return myIsCollected; + } + + public long uniqueID() { + return getObjectReference().uniqueID(); + } + + /** + * @return a list of waiting ThreadReferenceProxies + * @throws IncompatibleThreadStateException + */ + public List waitingThreads() throws IncompatibleThreadStateException { + List list = getObjectReference().waitingThreads(); + List proxiesList = new ArrayList(list.size()); + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ThreadReference threadReference = iterator.next(); + proxiesList.add(getVirtualMachineProxy().getThreadReferenceProxy(threadReference)); + } + return proxiesList; + } + + public ThreadReferenceProxyImpl owningThread() throws IncompatibleThreadStateException { + ThreadReference threadReference = getObjectReference().owningThread(); + return getVirtualMachineProxy().getThreadReferenceProxy(threadReference); + } + + public int entryCount() throws IncompatibleThreadStateException { + return getObjectReference().entryCount(); + } + + public boolean equals(Object o) { + if (!(o instanceof ObjectReferenceProxyImpl)) { + return false; + } + if(this == o) return true; + + ObjectReference ref = myObjectReference; + return ref != null ? ref.equals(((ObjectReferenceProxyImpl)o).myObjectReference) : false; + } + + + public int hashCode() { + return myObjectReference.hashCode(); + } + + /** + * The advice to the proxy to clear cached data. + */ + protected void clearCaches() { + try { + myIsCollected = VirtualMachineProxyImpl.isCollected(myObjectReference); + } + catch (VMDisconnectedException e) { + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StackFrameProxyImpl.java new file mode 100644 index 00000000000..f4d012a5ad6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -0,0 +1,297 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.jdi.StackFrameProxy; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.StackFrameProxyImpl"); + private final ThreadReferenceProxyImpl myThreadProxy; + private final int myFrameFromBottomIndex; // 1-based + + //caches + private int myFrameIndex = -1; + private StackFrame myStackFrame; + private ObjectReference myThisReference; + private Location myLocation; + private ClassLoaderReference myClassLoader; + private Boolean myIsObsolete = null; + + public StackFrameProxyImpl(ThreadReferenceProxyImpl threadProxy, StackFrame frame, int fromBottomIndex /* 1-based */) { + super(threadProxy.getVirtualMachine()); + myThreadProxy = threadProxy; + myFrameFromBottomIndex = fromBottomIndex; + myStackFrame = frame; + LOG.assertTrue(frame != null); + } + + public boolean isObsolete() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + checkValid(); + if (myIsObsolete == null) { + try { + boolean isObsolete = (getVirtualMachine().versionHigher("1.4") && getStackFrame().location().method().isObsolete()); + myIsObsolete = new Boolean(isObsolete); + } + catch (InvalidStackFrameException e) { + clearCaches(); + return isObsolete(); + } + } + return myIsObsolete.booleanValue(); + } + + protected void clearCaches() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + //DebuggerManagerThreadImpl.assertIsManagerThread(); + if (LOG.isDebugEnabled()) { + LOG.debug("caches cleared " + super.toString()); + } + myFrameIndex = -1; + myStackFrame = null; + myIsObsolete = null; + myLocation = null; + myThisReference = null; + myClassLoader = null; + } + + /** + * Use with caution. Better access stackframe data through the Proxy's methods + * @return + */ + + public StackFrame getStackFrame() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + + checkValid(); + + if(myStackFrame == null) { + try { + myStackFrame = myThreadProxy.getThreadReference().frame(getFrameIndex()); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + return myStackFrame; + } + + public int getFrameIndex() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + checkValid(); + if(myFrameIndex == -1) { + int count = myThreadProxy.frameCount(); + + if(myFrameFromBottomIndex > count) throw EvaluateExceptionUtil.createEvaluateException(new IncompatibleThreadStateException()); + + myFrameIndex = count - myFrameFromBottomIndex; + } + return myFrameIndex; + } + +// public boolean isProxiedFrameValid() { +// if (myStackFrame != null) { +// try { +// myStackFrame.thread(); +// return true; +// } +// catch (InvalidStackFrameException e) { +// } +// } +// return false; +// } + + public VirtualMachineProxyImpl getVirtualMachine() { + return (VirtualMachineProxyImpl) myTimer; + } + + public Location location() throws EvaluateException { + checkValid(); + if(myLocation == null) { + try { + myLocation = getStackFrame().location(); + } + catch (InvalidStackFrameException e) { + clearCaches(); + return location(); + } + } + return myLocation; + } + + public ThreadReferenceProxyImpl threadProxy() { + return myThreadProxy; + } + + public String toString() { + try { + return "StackFrameProxyImpl: " + getStackFrame().toString(); + } + catch (EvaluateException e) { + return "StackFrameProxyImpl: " + e.getMessage() + "; frameFromBottom = " + myFrameFromBottomIndex + " threadName = " + threadProxy().name(); + } + } + + public ObjectReference thisObject() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + checkValid(); + try { + if(myThisReference == null) { + myThisReference = !isObsolete() ? getStackFrame().thisObject() : null; + } + } + catch (InvalidStackFrameException e) { + clearCaches(); + return thisObject(); + } + catch (InternalException e) { + if(e.errorCode() == 35) { + LOG.debug(e); //bug in JDK 1.5 beta + throw EvaluateExceptionUtil.createEvaluateException(e); + } else { + throw e; + } + } + return myThisReference; + } + + public List visibleVariables() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + List list = getStackFrame().visibleVariables(); + + List locals = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + LocalVariable localVariable = iterator.next(); + LOG.assertTrue(localVariable != null); + locals.add(new LocalVariableProxyImpl(this, localVariable)); + } + return locals; + } + catch (InvalidStackFrameException e) { + clearCaches(); + return visibleVariables(); + } + catch (AbsentInformationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + public LocalVariableProxyImpl visibleVariableByName(String name) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + LocalVariable variable = getStackFrame().visibleVariableByName(name); + return variable != null ? new LocalVariableProxyImpl(this, variable) : null; + } + catch (InvalidStackFrameException e) { + return visibleVariableByName(name); + } + catch (AbsentInformationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + protected LocalVariable visibleVariableByNameInt(String name) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + return getStackFrame().visibleVariableByName(name); + } + catch (InvalidStackFrameException e) { + clearCaches(); + return visibleVariableByNameInt(name); + } + catch (AbsentInformationException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + + public Value getValue(LocalVariableProxyImpl localVariable) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + return getStackFrame().getValue(localVariable.getVariable()); + } + catch (InconsistentDebugInfoException e) { + clearCaches(); + throw EvaluateExceptionUtil.INCONSISTEND_DEBUG_INFO; + } + catch (InvalidStackFrameException e) { + clearCaches(); + return getValue(localVariable); + } + } + + public Map getValues(List list) throws EvaluateException{ + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + return getStackFrame().getValues(list); + } + catch (InvalidStackFrameException e) { + clearCaches(); + return getValues(list); + } + } + + public void setValue(LocalVariableProxyImpl localVariable, Value value) throws EvaluateException, + ClassNotLoadedException, + InvalidTypeException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + getStackFrame().setValue(localVariable.getVariable(), value); + } + catch (InvalidStackFrameException e) { + clearCaches(); + setValue(localVariable, value); + } + } + + public int hashCode() { + return myThreadProxy.hashCode() + myFrameFromBottomIndex; + } + + + public boolean equals(final Object obj) { + if (!(obj instanceof StackFrameProxyImpl)) { + return false; + } + StackFrameProxyImpl frameProxy = (StackFrameProxyImpl)obj; + if(frameProxy == this)return true; + + return (myFrameFromBottomIndex == frameProxy.myFrameFromBottomIndex) && + (myThreadProxy.equals(frameProxy.myThreadProxy)); + } + + public boolean isLocalVariableVisible(LocalVariableProxyImpl var) throws EvaluateException { + try { + return var.getVariable().isVisible(getStackFrame()); + } + catch (IllegalArgumentException e) { + // can be thrown if frame's method is different than variable's method + throw EvaluateExceptionUtil.createEvaluateException("Internal error - frame's method is different than variable's method"); + } + } + + public ClassLoaderReference getClassLoader() throws EvaluateException { + if(myClassLoader == null) { + myClassLoader = location().declaringType().classLoader(); + } + return myClassLoader; + } + + public boolean isBottom() { + return myFrameFromBottomIndex == 1; + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StringReferenceProxy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StringReferenceProxy.java new file mode 100644 index 00000000000..71bec696ff5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/StringReferenceProxy.java @@ -0,0 +1,34 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.sun.jdi.StringReference; + +public class StringReferenceProxy extends ObjectReferenceProxyImpl{ + private String myStringValue; + + public StringReferenceProxy(VirtualMachineProxyImpl virtualMachineProxy, StringReference objectReference) { + super(virtualMachineProxy, objectReference); + } + + public StringReference getStringReference() { + return (StringReference)getObjectReference(); + } + + public String value() { + checkValid(); + if (myStringValue == null) { + myStringValue = getStringReference().value(); + if (myStringValue != null) { + myStringValue = myStringValue.intern(); + } + } + return myStringValue; + } + + public void clearCaches() { + myStringValue = null; + super.clearCaches(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java new file mode 100644 index 00000000000..05e3aee26d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java @@ -0,0 +1,88 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.debugger.engine.jdi.ThreadGroupReferenceProxy; +import com.sun.jdi.ThreadGroupReference; +import com.sun.jdi.ThreadReference; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ThreadGroupReferenceProxyImpl extends ObjectReferenceProxyImpl implements ThreadGroupReferenceProxy{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl"); + //caches + private ThreadGroupReferenceProxyImpl myParentThreadGroupProxy; + private boolean myIsParentGroupCached = false; + private String myName; + + public ThreadGroupReferenceProxyImpl(VirtualMachineProxyImpl virtualMachineProxy, ThreadGroupReference threadGroupReference) { + super(virtualMachineProxy, threadGroupReference); + LOG.assertTrue(threadGroupReference != null); + } + + public ThreadGroupReference getThreadGroupReference() { + return (ThreadGroupReference)getObjectReference(); + } + + public String name() { + checkValid(); + if (myName == null) { + myName = getThreadGroupReference().name(); + } + return myName; + } + + public ThreadGroupReferenceProxyImpl parent() { + checkValid(); + if (!myIsParentGroupCached) { + myParentThreadGroupProxy = getVirtualMachineProxy().getThreadGroupReferenceProxy(getThreadGroupReference().parent()); + myIsParentGroupCached = true; + } + return myParentThreadGroupProxy; + } + + public String toString() { + return "ThreadGroupReferenceProxy: " + getThreadGroupReference().toString(); + } + + public void suspend() { + getThreadGroupReference().suspend(); + } + + public void resume() { + getThreadGroupReference().resume(); + } + + public List threads() { + List list = getThreadGroupReference().threads(); + List proxies = new ArrayList(list.size()); + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ThreadReference threadReference = iterator.next(); + proxies.add(getVirtualMachineProxy().getThreadReferenceProxy(threadReference)); + } + return proxies; + } + + public List threadGroups() { + List list = getThreadGroupReference().threadGroups(); + List proxies = new ArrayList(list.size()); + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ThreadGroupReference threadGroupReference = iterator.next(); + proxies.add(getVirtualMachineProxy().getThreadGroupReferenceProxy(threadGroupReference)); + } + return proxies; + } + + public void clearCaches() { +// myIsParentGroupCached = false; +// myName = null; +// myParentThreadGroupProxy = null; + super.clearCaches(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java new file mode 100644 index 00000000000..973714dda69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java @@ -0,0 +1,186 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.jdi.ThreadReferenceProxy; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.StackFrame; +import com.sun.jdi.ThreadReference; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Comparator; + +public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl implements ThreadReferenceProxy { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.ThreadReferenceProxyImpl"); + // cached data + private String myName; + private int myFrameCount = -1; + // stackframes, 0 - bottom + private List myFramesFromBottom = new ArrayList(); + //cache build on the base of myFramesFromBottom + //0 - top + private List myFrames = new ArrayList(); + + private ThreadGroupReferenceProxyImpl myThreadGroupProxy; + + public static Comparator ourComparator = new Comparator() { + public int compare(ThreadReferenceProxyImpl th1, ThreadReferenceProxyImpl th2) { + return th1.name().compareTo(th2.name()); + } + }; + + public ThreadReferenceProxyImpl(VirtualMachineProxyImpl virtualMachineProxy, ThreadReference threadReference) { + super(virtualMachineProxy, threadReference); + LOG.assertTrue(threadReference != null); + } + + public ThreadReference getThreadReference() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return (ThreadReference)getObjectReference(); + } + + public VirtualMachineProxyImpl getVirtualMachine() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return (VirtualMachineProxyImpl) myTimer; + } + + public String name() { + checkValid(); + if (myName == null) { + myName = getThreadReference().name(); + } + return myName; + } + + public int getSuspendCount() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + //LOG.assertTrue((mySuspendCount > 0) == suspends()); + return getThreadReference().suspendCount(); + } + + public void suspend() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + getThreadReference().suspend(); + clearCaches(); + } + + public String toString() { + return "ThreadReferenceProxyImpl: " + getThreadReference().toString() + " " + super.toString(); + } + + public void resume() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + //JDI clears all caches on thread resume !! + if(LOG.isDebugEnabled()) { + LOG.debug("before resume" + getThreadReference()); + } + getVirtualMachineProxy().clearCaches(); + getThreadReference().resume(); + } + + protected void clearCaches() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myFrames = null; + myFrameCount = -1; + super.clearCaches(); + } + + public int suspendCount() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return getThreadReference().suspendCount(); + } + + public int status() { + return getThreadReference().status(); + } + + public ThreadGroupReferenceProxyImpl threadGroupProxy() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + checkValid(); + if(myThreadGroupProxy == null) { + myThreadGroupProxy = getVirtualMachineProxy().getThreadGroupReferenceProxy(getThreadReference().threadGroup()); + } + return myThreadGroupProxy; + } + + public int frameCount() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + checkValid(); + if (myFrameCount == -1) { + try { + myFrameCount = getThreadReference().frameCount(); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + return myFrameCount; + } + + public List frames() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + LOG.assertTrue(getThreadReference().isSuspended()); + checkValid(); + + if(myFrames == null) { + checkFrames(); + + myFrames = new ArrayList(frameCount()); + for (ListIterator iterator = myFramesFromBottom.listIterator(frameCount()); iterator.hasPrevious();) { + StackFrameProxyImpl stackFrameProxy = iterator.previous(); + myFrames.add(stackFrameProxy); + } + } + return myFrames; + } + + private void checkFrames() throws EvaluateException { + if (myFramesFromBottom.size() < frameCount()) { + int count = frameCount(); + List frames = null; + try { + frames = getThreadReference().frames(0, count - myFramesFromBottom.size()); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + + int index = myFramesFromBottom.size() + 1; + for (ListIterator iterator = frames.listIterator(count - myFramesFromBottom.size()); iterator.hasPrevious();) { + StackFrame stackFrame = iterator.previous(); + myFramesFromBottom.add(new StackFrameProxyImpl(this, stackFrame, index)); + index++; + } + } + } + + public StackFrameProxyImpl frame(int i) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if(!getThreadReference().isSuspended()) return null; + checkFrames(); + return myFramesFromBottom.get(frameCount() - i - 1); + } + + public void popFrames(StackFrameProxyImpl stackFrame) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + getThreadReference().popFrames(stackFrame.getStackFrame()); + } + catch (IncompatibleThreadStateException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + clearCaches(); + } + + public boolean isSuspended() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return getThreadReference().isSuspended(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java new file mode 100644 index 00000000000..2487152929f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -0,0 +1,457 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.jdi; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.jdi.VirtualMachineProxy; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.containers.*; +import com.intellij.util.containers.HashMap; +import com.sun.jdi.*; +import com.sun.jdi.event.EventQueue; +import com.sun.jdi.request.EventRequestManager; +import com.sun.tools.jdi.VoidValueImpl; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.VirtualMachineProxyImpl"); + private final DebugProcessImpl myDebugProcess; + private final VirtualMachine myVirtualMachine; + private int myTimeStamp = 0; + + // cached data + private Map myObjectReferenceProxies = new HashMap(); + private Map myAllThreads = new com.intellij.util.containers.HashMap(); + private Map myThreadGroups = new HashMap(); + private boolean myAllThreadsDirty = true; + private List myAllClasses; + public Throwable mySuspendLogger = new Throwable(); + + public VirtualMachineProxyImpl(DebugProcessImpl debugProcess, VirtualMachine virtualMachine) { + LOG.assertTrue(virtualMachine != null); + myVirtualMachine = virtualMachine; + myDebugProcess = debugProcess; + + List groups = virtualMachine.topLevelThreadGroups(); + for (Iterator it = groups.iterator(); it.hasNext();) { + ThreadGroupReference threadGroupReference = (ThreadGroupReference)it.next(); + threadGroupCreated(threadGroupReference); + } + } + + public VirtualMachine getVirtualMachine() { + return myVirtualMachine; + } + + public List classesByName(String s) { + return (List)myVirtualMachine.classesByName(s); + } + + public List allClasses() { + if (myAllClasses == null) { + myAllClasses = (List)myVirtualMachine.allClasses(); + } + return myAllClasses; + } + + public String toString() { + return myVirtualMachine.toString(); + } + + public void redefineClasses(Map map) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + myVirtualMachine.redefineClasses(map); + } finally { + clearCaches(); + } + } + + /** + * @return a list of all ThreadReferenceProxies + */ + public Collection allThreads() { + if(myAllThreadsDirty) { + myAllThreadsDirty = false; + + List threads = myVirtualMachine.allThreads(); + Map result = new HashMap(); + + for (Iterator iterator = threads.iterator(); iterator.hasNext();) { + ThreadReference threadReference = (ThreadReference)iterator.next(); + + ThreadReferenceProxyImpl threadReferenceProxy = getThreadReferenceProxy(threadReference); + LOG.assertTrue(threadReferenceProxy != null); + + result.put(threadReference, threadReferenceProxy); + } + myAllThreads = result; + } + + return (Collection)myAllThreads.values(); + } + + public void suspend() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myVirtualMachine.suspend(); + clearCaches(); + } + + public void resume() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + clearCaches(); + LOG.debug("before resume VM"); + myVirtualMachine.resume(); + LOG.debug("VM resumed"); + //logThreads(); + } + + /** + * @return a list of threadGroupProxies + */ + public List topLevelThreadGroups() { + List list = getVirtualMachine().topLevelThreadGroups(); + + List result = new ArrayList(list.size()); + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ThreadGroupReference threadGroup = iterator.next(); + result.add(getThreadGroupReferenceProxy(threadGroup)); + } + + return result; + } + + public void threadGroupCreated(ThreadGroupReference threadGroupReference){ + if(!isJ2ME()) { + ThreadGroupReferenceProxyImpl proxy = new ThreadGroupReferenceProxyImpl(this, threadGroupReference); + myThreadGroups.put(threadGroupReference, proxy); + } + } + + public boolean isJ2ME() { + return isJ2ME(getVirtualMachine()); + } + + private static boolean isJ2ME(VirtualMachine virtualMachine) { + return virtualMachine.version().startsWith("1.0"); + } + + public void threadGroupRemoved(ThreadGroupReference threadGroupReference){ + myThreadGroups.remove(threadGroupReference); + } + + public EventQueue eventQueue() { + return myVirtualMachine.eventQueue(); + } + + public EventRequestManager eventRequestManager() { + return myVirtualMachine.eventRequestManager(); + } + + public VoidValue mirrorOf() throws EvaluateException { + try { + Constructor constructor = VoidValueImpl.class.getDeclaredConstructor(new Class[]{VirtualMachine.class}); + constructor.setAccessible(true); + return constructor.newInstance(new Object[] {myVirtualMachine}); + } + catch (NoSuchMethodException e) { + LOG.error(e); + } + catch (IllegalAccessException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + catch (InstantiationException e) { + LOG.error(e); + } + throw EvaluateExceptionUtil.createEvaluateException("Cannot creat void value"); + } + + public BooleanValue mirrorOf(boolean b) { + return myVirtualMachine.mirrorOf(b); + } + + public ByteValue mirrorOf(byte b) { + return myVirtualMachine.mirrorOf(b); + } + + public CharValue mirrorOf(char c) { + return myVirtualMachine.mirrorOf(c); + } + + public ShortValue mirrorOf(short i) { + return myVirtualMachine.mirrorOf(i); + } + + public IntegerValue mirrorOf(int i) { + return myVirtualMachine.mirrorOf(i); + } + + public LongValue mirrorOf(long l) { + return myVirtualMachine.mirrorOf(l); + } + + public FloatValue mirrorOf(float v) { + return myVirtualMachine.mirrorOf(v); + } + + public DoubleValue mirrorOf(double v) { + return myVirtualMachine.mirrorOf(v); + } + + public StringReference mirrorOf(String s) { + final StringReference mirror = myVirtualMachine.mirrorOf(s); + mirror.disableCollection(); + return mirror; + } + + public Process process() { + return myVirtualMachine.process(); + } + + public void dispose() { + myVirtualMachine.dispose(); + } + + public void exit(int i) { + myVirtualMachine.exit(i); + } + + public boolean canWatchFieldModification() { + return myVirtualMachine.canWatchFieldModification(); + } + + public boolean canWatchFieldAccess() { + return myVirtualMachine.canWatchFieldAccess(); + } + + public boolean canInvokeMethods() { + return isJ2ME(); + } + + public boolean canGetBytecodes() { + return myVirtualMachine.canGetBytecodes(); + } + + public boolean canGetSyntheticAttribute() { + return myVirtualMachine.canGetSyntheticAttribute(); + } + + public boolean canGetOwnedMonitorInfo() { + return myVirtualMachine.canGetOwnedMonitorInfo(); + } + + public boolean canGetCurrentContendedMonitor() { + return myVirtualMachine.canGetCurrentContendedMonitor(); + } + + public boolean canGetMonitorInfo() { + return myVirtualMachine.canGetMonitorInfo(); + } + + public boolean canUseInstanceFilters() { + if (versionHigher("1.4")) { + return myVirtualMachine.canUseInstanceFilters(); + } else + return false; + } + + public boolean canRedefineClasses() { + if (versionHigher("1.4")) { + return myVirtualMachine.canRedefineClasses(); + } + return false; + } + + public boolean canAddMethod() { + if (versionHigher("1.4")) { + return myVirtualMachine.canAddMethod(); + } else + return false; + } + + public boolean canUnrestrictedlyRedefineClasses() { + if (versionHigher("1.4")) { + return myVirtualMachine.canUnrestrictedlyRedefineClasses(); + } else + return false; + } + + public boolean canPopFrames() { + if (versionHigher("1.4")) { + return myVirtualMachine.canPopFrames(); + } + return false; + } + + public boolean versionHigher(String version) { + return myVirtualMachine.version().compareTo(version) >= 0; + } + + public boolean canGetSourceDebugExtension() { + if (versionHigher("1.4")) { + return myVirtualMachine.canGetSourceDebugExtension(); + } else + return false; + } + + public boolean canRequestVMDeathEvent() { + if(versionHigher("1.4")){ + return myVirtualMachine.canRequestVMDeathEvent(); + } else + return false; + } + + public String getDefaultStratum() { + if(versionHigher("1.4")){ + return myVirtualMachine.getDefaultStratum(); + } else + return null; + } + + public String description() { + return myVirtualMachine.description(); + } + + public String version() { + return myVirtualMachine.version(); + } + + public String name() { + return myVirtualMachine.name(); + } + + public void setDebugTraceMode(int i) { + myVirtualMachine.setDebugTraceMode(i); + } + + public ThreadReferenceProxyImpl getThreadReferenceProxy(ThreadReference thread) { + if(thread == null) return null; + + ThreadReferenceProxyImpl proxy = myAllThreads.get(thread); + if(proxy == null) { + proxy = new ThreadReferenceProxyImpl(this, thread); + myAllThreads.put(thread, proxy); + } + + return proxy; + } + + public ThreadGroupReferenceProxyImpl getThreadGroupReferenceProxy(ThreadGroupReference group) { + if(group == null) return null; + + ThreadGroupReferenceProxyImpl proxy = myThreadGroups.get(group); + if(proxy == null) { + if(!isJ2ME()) { + proxy = new ThreadGroupReferenceProxyImpl(this, group); + myThreadGroups.put(group, proxy); + } + } + + return proxy; + } + + public ObjectReferenceProxyImpl getObjectReferenceProxy(ObjectReference objectReference) { + if (objectReference != null) { + if (objectReference instanceof ThreadReference) { + return getThreadReferenceProxy((ThreadReference)objectReference); + } + else if (objectReference instanceof ThreadGroupReference) { + return getThreadGroupReferenceProxy((ThreadGroupReference)objectReference); + } + else { + ObjectReferenceProxyImpl proxy = (ObjectReferenceProxyImpl)myObjectReferenceProxies.get(objectReference); + if (proxy == null) { + if (objectReference instanceof StringReference) { + proxy = new StringReferenceProxy(this, (StringReference)objectReference); + } + else { + proxy = new ObjectReferenceProxyImpl(this, objectReference); + } + myObjectReferenceProxies.put(objectReference, proxy); + } + return proxy; + } + } + else { + return null; + } + } + + public boolean equals(Object obj) { + LOG.assertTrue(obj instanceof VirtualMachineProxyImpl); + return myVirtualMachine.equals(((VirtualMachineProxyImpl)obj).getVirtualMachine()); + } + + public int hashCode() { + return myVirtualMachine.hashCode(); + } + + public void clearCaches() { + if (LOG.isDebugEnabled()) { + LOG.debug("VM cleared"); + } + + myAllClasses = null; + myAllThreadsDirty = true; + myTimeStamp++; + } + + public int getCurrentTime() { + return myTimeStamp; + } + + public DebugProcessImpl getDebugProcess() { + return myDebugProcess; + } + + public static boolean isCollected(ObjectReference reference) { + if(isJ2ME(reference.virtualMachine())){ + return false; + } else { + return reference.isCollected(); + } + } + + public String getResumeStack() { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + mySuspendLogger.printStackTrace(pw); + pw.flush(); + return sw.getBuffer().toString(); + } + + public boolean isSuspended() { + //logThreads(); + for (Iterator iterator = allThreads().iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl thread = (ThreadReferenceProxyImpl)iterator.next(); + if(thread.getSuspendCount() > 0) return true; + } + return false; + } + + public void logThreads() { + if(LOG.isDebugEnabled()) { + for (Iterator iterator = allThreads().iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl thread = (ThreadReferenceProxyImpl)iterator.next(); + LOG.debug("suspends " + thread + " " + thread.getSuspendCount() + " " + thread.isSuspended()); + } + } + } + + + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java new file mode 100644 index 00000000000..bba82ca735f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java @@ -0,0 +1,111 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class ArrayRendererConfigurable implements UnnamedConfigurable{ + private JTextField myEntriesLimit; + private JTextField myFirstIndex; + private JTextField myEndIndex; + + private ArrayRenderer myRenderer; + private JComponent myPanel; + + private JLabel myEntriesLimitLabel; + private JLabel myLastIndexLabel; + private JLabel myFirstIndexLabel; + + public ArrayRendererConfigurable(ArrayRenderer renderer) { + myRenderer = renderer; + + myFirstIndexLabel .setLabelFor(myFirstIndex); + myLastIndexLabel .setLabelFor(myLastIndexLabel); + myEntriesLimitLabel.setLabelFor(myEntriesLimit); + + DocumentListener listener = new DocumentListener() { + private void updateEntriesLimit() { + myEntriesLimit.setText(String.valueOf(getInt(myEndIndex) - getInt(myFirstIndex) + 1)); + } + + public void changedUpdate(DocumentEvent e) { updateEntriesLimit(); } + public void insertUpdate (DocumentEvent e) { updateEntriesLimit(); } + public void removeUpdate (DocumentEvent e) { updateEntriesLimit(); } + }; + myFirstIndex.getDocument().addDocumentListener(listener); + myEndIndex.getDocument().addDocumentListener(listener); + } + + public ArrayRenderer getRenderer() { + return myRenderer; + } + + public void reset() { + myFirstIndex .setText(String.valueOf(myRenderer.START_INDEX)); + myEndIndex .setText(String.valueOf(myRenderer.END_INDEX)); + myEntriesLimit.setText(String.valueOf(myRenderer.ENTRIES_LIMIT)); + } + + public void apply() { + applyTo(myRenderer); + } + + private void applyTo(ArrayRenderer renderer) { + int newStartIndex = getInt(myFirstIndex); + int newEndIndex = getInt(myEndIndex); + int newLimit = getInt(myEntriesLimit); + + if (newStartIndex >= 0 && newEndIndex >= 0) { + if (newStartIndex >= newEndIndex) { + int currentStartIndex = renderer.START_INDEX; + int currentEndIndex = renderer.END_INDEX; + newEndIndex = newStartIndex + (currentEndIndex - currentStartIndex); + } + + if(newLimit <= 0) newLimit = 1; + + if(newEndIndex - newStartIndex > 10000) { + if(Messages.showOkCancelDialog(myPanel.getRootPane(), "Range specified is too big. IDEA needs too much resources to perform requested operation. Are you shure you want to continue?", "Range is Too Big", Messages.getWarningIcon()) != DialogWrapper.OK_EXIT_CODE) return; + } + } + + renderer.START_INDEX = newStartIndex; + renderer.END_INDEX = newEndIndex; + renderer.ENTRIES_LIMIT = newLimit; + } + + public JComponent createComponent() { + return myPanel; + } + + private int getInt(JTextField textField) { + int newEndIndex = 0; + try { + newEndIndex = Integer.parseInt(textField.getText().trim()); + } + catch (NumberFormatException exception) { + } + return newEndIndex; + } + + public boolean isModified() { + ArrayRenderer cloneRenderer = myRenderer.clone(); + applyTo(cloneRenderer); + return !DebuggerUtilsEx.externalizableEqual(myRenderer, cloneRenderer); + } + + public void disposeUIResources() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/CompositeConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/CompositeConfigurable.java new file mode 100644 index 00000000000..65d71073fd6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/CompositeConfigurable.java @@ -0,0 +1,67 @@ +package com.intellij.debugger.settings; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; + +import javax.swing.*; +import java.util.Iterator; +import java.util.List; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public abstract class CompositeConfigurable extends BaseConfigurable { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.DebuggerConfigurable"); + + private JTabbedPane myTabbedPane; + private List myConfigurables; + + public void reset() { + for (Iterator iterator = getConfigurables().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next(); + configurable.reset(); + } + } + + public void apply() throws ConfigurationException { + for (Iterator iterator = getConfigurables().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next(); + configurable.apply(); + } + } + + public boolean isModified() { + for (Iterator iterator = getConfigurables().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next(); + if(configurable.isModified()) return true; + } + return false; + } + + public JComponent createComponent() { + myTabbedPane = new JTabbedPane(); + for (Iterator iterator = getConfigurables().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next(); + myTabbedPane.addTab(configurable.getDisplayName(), configurable.getIcon(), configurable.createComponent()); + } + return myTabbedPane; + } + + public void disposeUIResources() { + myTabbedPane = null; + myConfigurables = null; + } + + protected abstract List createConfigurables(); + + private List getConfigurables() { + if (myConfigurables == null) { + myConfigurables = createConfigurables(); + } + return myConfigurables; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerColors.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerColors.java new file mode 100644 index 00000000000..15f60981bc3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerColors.java @@ -0,0 +1,11 @@ +/** + * @author Yura Cangea + */ +package com.intellij.debugger.settings; + +import com.intellij.openapi.editor.colors.TextAttributesKey; + +public interface DebuggerColors { + TextAttributesKey BREAKPOINT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("BREAKPOINT_ATTRIBUTES"); + TextAttributesKey EXECUTIONPOINT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("EXECUTIONPOINT_ATTRIBUTES"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerConfigurable.java new file mode 100644 index 00000000000..53d02cce548 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerConfigurable.java @@ -0,0 +1,58 @@ +package com.intellij.debugger.settings; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.ide.DataManager; + +import javax.swing.*; +import java.util.List; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev & Eugene Zhuravlev + */ +public class DebuggerConfigurable extends CompositeConfigurable implements ApplicationComponent { + public DebuggerConfigurable() { + super(); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableDebugger.png"); + } + + public String getDisplayName() { + return "Debugger"; + } + + public String getHelpTopic() { + return "project.propDebugger"; + } + + public String getComponentName() { + return "DebuggerConfigurable"; + } + + protected List createConfigurables() { + ArrayList configurables = new ArrayList(); + Project project = (Project)DataManager.getInstance().getDataContext().getData(DataConstants.PROJECT); + if(project == null) { + project = ProjectManager.getInstance().getDefaultProject(); + } + configurables.add(new DebuggerGeneralConfigurable(project)); + configurables.add(new ViewsGeneralConfigurable()); + configurables.add(new NodeRendererConfigurable(project)); + return configurables; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerGeneralConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerGeneralConfigurable.java new file mode 100644 index 00000000000..e086bfa0e17 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerGeneralConfigurable.java @@ -0,0 +1,161 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.ui.ClassFilterEditor; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * User: lex + * Date: Oct 6, 2003 + * Time: 7:37:05 PM + */ +public class DebuggerGeneralConfigurable implements Configurable{ + private JPanel myPanel; + private JPanel myNodeRepresentationEditorPlace; + private JPanel mySteppingFiltersEditorPlace; + private JRadioButton mySocketTransportRadio; + private JRadioButton myShmemTransportRadio; + private JCheckBox myFiltersCheckBox; + private JCheckBox mySkipSyntheticMethodsCheckBox; + private JCheckBox mySkipConstructorsCheckBox; + private JCheckBox myHideDebuggerCheckBox; + private JRadioButton myRunHotswapAlways; + private JRadioButton myRunHotswapNever; + private JRadioButton myRunHotswapAsk; + private StateRestoringCheckBox myForceClassicCheckBox; + private ClassFilterEditor myFilterEditor; + private JTextField myValueLookupDelayField; + private JCheckBox mySkipGettersCheckBox; + private JCheckBox myCheckBox1; + + public DebuggerGeneralConfigurable(Project project) { + myFilterEditor = new ClassFilterEditor(project); + mySteppingFiltersEditorPlace.setLayout(new BorderLayout()); + mySteppingFiltersEditorPlace.add(myFilterEditor, BorderLayout.CENTER); + + ButtonGroup group = new ButtonGroup(); + group.add(mySocketTransportRadio); + group.add(myShmemTransportRadio); + + group = new ButtonGroup(); + group.add(myRunHotswapAlways); + group.add(myRunHotswapNever); + group.add(myRunHotswapAsk); + + myFiltersCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myFilterEditor.setEnabled(myFiltersCheckBox.isSelected()); + } + }); + } + + public void reset() { + if (!SystemInfo.isWindows) { + mySocketTransportRadio.setSelected(true); + myShmemTransportRadio.setEnabled(false); + } + else { + if (getSettings().DEBUGGER_TRANSPORT == DebuggerSettings.SHMEM_TRANSPORT) { + myShmemTransportRadio.setSelected(true); + } + else { + mySocketTransportRadio.setSelected(true); + } + myShmemTransportRadio.setEnabled(true); + } + mySkipGettersCheckBox.setSelected(getSettings().SKIP_GETTERS); + mySkipSyntheticMethodsCheckBox.setSelected(getSettings().SKIP_SYNTHETIC_METHODS); + mySkipConstructorsCheckBox.setSelected(getSettings().SKIP_CONSTRUCTORS); + myValueLookupDelayField.setText(Integer.toString(getSettings().VALUE_LOOKUP_DELAY)); + myHideDebuggerCheckBox.setSelected(getSettings().HIDE_DEBUGGER_ON_PROCESS_TERMINATION); + myForceClassicCheckBox.setSelected(getSettings().FORCE_CLASSIC_VM); + + myFiltersCheckBox.setSelected(getSettings().TRACING_FILTERS_ENABLED); + + myFilterEditor.setFilters(getSettings().getFilters()); + myFilterEditor.setEnabled(getSettings().TRACING_FILTERS_ENABLED); + + if(DebuggerSettings.RUN_HOTSWAP_ALWAYS.equals(getSettings().RUN_HOTSWAP_AFTER_COMPILE)) { + myRunHotswapAlways.setSelected(true); + } else if(DebuggerSettings.RUN_HOTSWAP_NEVER.equals(getSettings().RUN_HOTSWAP_AFTER_COMPILE)) { + myRunHotswapNever.setSelected(true); + } else { + myRunHotswapAsk.setSelected(true); + } + } + + public void apply() { + getSettingsTo(getSettings()); + } + + private void getSettingsTo(DebuggerSettings settings) { + if (myShmemTransportRadio.isSelected()) { + settings.DEBUGGER_TRANSPORT = DebuggerSettings.SHMEM_TRANSPORT; + } + else if (mySocketTransportRadio.isSelected()) { + settings.DEBUGGER_TRANSPORT = DebuggerSettings.SOCKET_TRANSPORT; + } + else { + settings.DEBUGGER_TRANSPORT = DebuggerSettings.SOCKET_TRANSPORT; + } + settings.SKIP_GETTERS = mySkipGettersCheckBox.isSelected(); + settings.SKIP_SYNTHETIC_METHODS = mySkipSyntheticMethodsCheckBox.isSelected(); + settings.SKIP_CONSTRUCTORS = mySkipConstructorsCheckBox.isSelected(); + try { + settings.VALUE_LOOKUP_DELAY = Integer.parseInt(myValueLookupDelayField.getText().trim()); + } + catch (NumberFormatException e) { + } + settings.HIDE_DEBUGGER_ON_PROCESS_TERMINATION = myHideDebuggerCheckBox.isSelected(); + settings.FORCE_CLASSIC_VM = myForceClassicCheckBox.isSelectedWhenSelectable(); + settings.TRACING_FILTERS_ENABLED = myFiltersCheckBox.isSelected(); + + myFilterEditor.stopEditing(); + settings.setFilters(myFilterEditor.getFilters()); + + if(myRunHotswapAlways.isSelected()) + settings.RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_ALWAYS; + else if(myRunHotswapNever.isSelected()) + settings.RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_NEVER; + else + settings.RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_ASK; + } + + public boolean isModified() { + DebuggerSettings debuggerSettings = new DebuggerSettings(); + + getSettingsTo(debuggerSettings); + return !debuggerSettings.equals(getSettings()); + } + + public String getDisplayName() { + return "General"; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + return myPanel; + } + + public void disposeUIResources() { + } + + private DebuggerSettings getSettings() { return DebuggerSettings.getInstance(); } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerSettings.java new file mode 100644 index 00000000000..5b4cf9fafb0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/DebuggerSettings.java @@ -0,0 +1,139 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.RunHotswapDialog; +import com.intellij.debugger.ClassFilter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.ui.DialogWrapper; +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 org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class DebuggerSettings implements JDOMExternalizable, ApplicationComponent { + public static final int SOCKET_TRANSPORT = 0; + public static final int SHMEM_TRANSPORT = 1; + + public static final String SUSPEND_ALL = "SuspendAll"; + public static final String SUSPEND_THREAD = "SuspendThread"; + public static final String SUSPEND_NONE = "SuspendNone"; + + public static final String EVALUATE_FRAGMENT = "EvaluateFragment"; + public static final String EVALUATE_EXPRESSION = "EvaluateExpression"; + + public static final String RUN_HOTSWAP_ALWAYS = "RunHotswapAlways"; + public static final String RUN_HOTSWAP_NEVER = "RunHotswapNever"; + public static final String RUN_HOTSWAP_ASK = "RunHotswapAsk"; + + public boolean TRACING_FILTERS_ENABLED; + public int VALUE_LOOKUP_DELAY; // ms + public int DEBUGGER_TRANSPORT; + public boolean FORCE_CLASSIC_VM; + public boolean HIDE_DEBUGGER_ON_PROCESS_TERMINATION; + public boolean SKIP_SYNTHETIC_METHODS; + public boolean SKIP_CONSTRUCTORS; + public boolean SKIP_GETTERS; + + public String EVALUATION_DIALOG_TYPE; + public String STEP_THREAD_SUSPEND_POLICY; + public String RUN_HOTSWAP_AFTER_COMPILE; + + private ClassFilter[] myFilters = ClassFilter.EMPTY_ARRAY; + + public DebuggerSettings() { + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public ClassFilter[] getFilters() { + return retrieveFilters(myFilters); + } + + private ClassFilter[] retrieveFilters(ClassFilter[] filters) { + ClassFilter[] rv = new ClassFilter[filters.length]; + for (int idx = 0; idx < rv.length; idx++) { + rv[idx] = filters[idx].clone(); + } + return rv; + } + + public boolean isNameFiltered(String qName) { + if (!TRACING_FILTERS_ENABLED) { + return false; + } + return DebuggerUtilsEx.isFiltered(qName, myFilters); + } + + void setFilters(ClassFilter[] filters) { + myFilters = (filters != null)? filters : ClassFilter.EMPTY_ARRAY; + } + + public void readExternal(Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + List filtersList = new ArrayList(); + + for (Iterator i = parentNode.getChildren("filter").iterator(); i.hasNext();) { + Element filter = (Element)i.next(); + filtersList.add(DebuggerUtilsEx.create(filter)); + } + setFilters((ClassFilter[])filtersList.toArray(new ClassFilter[filtersList.size()])); + + filtersList.clear(); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, parentNode); + Element element; + for (int idx = 0; idx < myFilters.length; idx++) { + element = new Element("filter"); + parentNode.addContent(element); + myFilters[idx].writeExternal(element); + } + } + + public static DebuggerSettings getInstance() { + return ApplicationManager.getApplication().getComponent(DebuggerSettings.class); + } + + public boolean equals(Object obj) { + if (!(obj instanceof DebuggerSettings)) return false; + DebuggerSettings secondSettings = (DebuggerSettings)obj; + + return + TRACING_FILTERS_ENABLED == secondSettings.TRACING_FILTERS_ENABLED && + VALUE_LOOKUP_DELAY == secondSettings.VALUE_LOOKUP_DELAY && + DEBUGGER_TRANSPORT == secondSettings.DEBUGGER_TRANSPORT && + FORCE_CLASSIC_VM == secondSettings.FORCE_CLASSIC_VM && + HIDE_DEBUGGER_ON_PROCESS_TERMINATION == secondSettings.HIDE_DEBUGGER_ON_PROCESS_TERMINATION && + SKIP_SYNTHETIC_METHODS == secondSettings.SKIP_SYNTHETIC_METHODS && + SKIP_CONSTRUCTORS == secondSettings.SKIP_CONSTRUCTORS && + (RUN_HOTSWAP_AFTER_COMPILE != null ? RUN_HOTSWAP_AFTER_COMPILE.equals(secondSettings.RUN_HOTSWAP_AFTER_COMPILE) : secondSettings.RUN_HOTSWAP_AFTER_COMPILE == null) && + DebuggerUtilsEx.filterEquals(myFilters, secondSettings.myFilters); + } + + public String getComponentName() { + return "DebuggerSettings"; + } + + public boolean isSuspendAllThreads() { + return SUSPEND_ALL.equals(STEP_THREAD_SUSPEND_POLICY); + } + + public void setSuspendPolicy(boolean suspendAll) { + STEP_THREAD_SUSPEND_POLICY = suspendAll ? SUSPEND_ALL : SUSPEND_THREAD; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java new file mode 100644 index 00000000000..d6e29177774 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java @@ -0,0 +1,214 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer; +import com.intellij.debugger.ui.impl.watch.render.ClassRenderer; +import com.intellij.debugger.ui.impl.watch.render.DefaultRendererProvider; +import com.intellij.debugger.ui.impl.watch.render.PrimitiveRenderer; +import com.intellij.debugger.ui.tree.render.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.InternalIterator; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Sep 18, 2003 + * Time: 8:00:25 PM + */ +public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cloneable, NamedJDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.NodeRendererSettingsImpl"); + private static final String AUTO_NODE = "node"; + + private String VERSION = "1.0"; + + private EventDispatcher myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class); + + private List myRepresentationNodes = new ArrayList(); + private PrimitiveRenderer myPrimitiveRenderer = new PrimitiveRenderer(); + private ArrayRenderer myArrayRenderer = new ArrayRenderer () { + public void setClassName(String className) { + LOG.assertTrue(this != myArrayRenderer, "Cannot change default renderer"); + } + }; + private ClassRenderer myClassRenderer = new ClassRenderer () { + public void setClassName(String name) { + LOG.assertTrue(this != myClassRenderer, "Cannot change default renderer"); + } + }; + + public NodeRendererSettingsImpl() { + } + + public String getComponentName() { + return "NodeRendererSettings"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getExternalFileName() { + return "debugger.renderers"; + } + + public NodeRendererSettingsImpl clone() { + NodeRendererSettingsImpl result = null; + try { + result = (NodeRendererSettingsImpl)super.clone(); + } + catch (CloneNotSupportedException e) { + LOG.error(e); + } + result.myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class); + result.myRepresentationNodes = new ArrayList(); + for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) { + AutoRendererNode autoRendererNode = iterator.next(); + result.addNode(autoRendererNode.clone()); + } + + result.myPrimitiveRenderer = myPrimitiveRenderer.clone(); + result.myArrayRenderer = myArrayRenderer.clone(); + result.myClassRenderer = myClassRenderer.clone(); + + return result; + } + + public boolean equals(Object o) { + if(!(o instanceof NodeRendererSettingsImpl)) return false; + + return DebuggerUtilsEx.externalizableEqual(this, (NodeRendererSettingsImpl)o); + } + + public void addListener(NodeRendererSettingsListener listener) { + myDispatcher.addListener(listener); + } + + public void removeListener(NodeRendererSettingsListener listener) { + myDispatcher.removeListener(listener); + } + + public void writeExternal(final Element element) throws WriteExternalException { + for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) { + AutoRendererNode autoRendererNode = iterator.next(); + Element nodeElement = new Element(AUTO_NODE); + autoRendererNode.writeExternal(nodeElement); + element.addContent(nodeElement); + } + element.setAttribute("VERSION", VERSION); + } + + public void readExternal(final Element root) { + String version = root.getAttributeValue("VERSION"); + if(version == null || version.compareTo(VERSION) < 0) return; + + VERSION = version; + + List children = root.getChildren(AUTO_NODE); + + myRepresentationNodes.clear(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element nodeRepresentation = iterator.next(); + try { + addNode(AutoRendererNode.read(nodeRepresentation)); + } catch (Exception e) { + LOG.debug(e); + } + } + + myDispatcher.getMulticaster().renderersChanged(); + } + + private void addNode(AutoRendererNode nodeRepresentation) { + LOG.assertTrue(nodeRepresentation != null); + myRepresentationNodes.add(nodeRepresentation); + } + + public void addRenderer(NodeRenderer renderer) { + addNode(new AutoRendererNode(renderer)); + } + + public void removeRenderer(NodeRenderer renderer) { + myRepresentationNodes.remove(renderer); + } + + public List getAllRenderers() { + List result = new ArrayList(); + + for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) { + AutoRendererNode autoRendererNode = iterator.next(); + result.add(autoRendererNode.getRenderer()); + } + result.add(getArrayRenderer()); + result.add(getClassRenderer()); + result.add(getPrimitiveRenderer()); + + return result; + } + + public boolean isDefault(Renderer renderer) { + return renderer == getArrayRenderer() || + renderer == getClassRenderer() || + renderer == getPrimitiveRenderer(); + } + + public List getAutoNodes() { + List result = new ArrayList(); + + for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) { + AutoRendererNode autoRendererNode = iterator.next(); + result.add(autoRendererNode); + } + + return result; + } + + public void setAutoNodes(List nodes) { + myRepresentationNodes = nodes; + fireRenderersChanged(); + } + + public List getRenderersByProvider(RendererProvider rendererProvider) { + List result = new ArrayList(); + + for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) { + AutoRendererNode autoRendererNode = iterator.next(); + if(autoRendererNode.getRenderer().getRendererProvider() == rendererProvider) result.add(autoRendererNode.getRenderer()); + } + return result; + } + + public void iterateRenderers(InternalIterator iterator) { + for (Iterator it = myRepresentationNodes.iterator(); it.hasNext();) { + AutoRendererNode autoRendererNode = it.next(); + iterator.visit(autoRendererNode); + } + } + + public PrimitiveRenderer getPrimitiveRenderer() { + return myPrimitiveRenderer; + } + + public ArrayRenderer getArrayRenderer() { + return myArrayRenderer; + } + + public ClassRenderer getClassRenderer() { + return myClassRenderer; + } + + public void fireRenderersChanged() { + myDispatcher.getMulticaster().renderersChanged(); + } + + public static NodeRendererSettingsImpl getInstanceEx() { + return (NodeRendererSettingsImpl)getInstance(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewConfigurable.java new file mode 100644 index 00000000000..82e07729dd8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewConfigurable.java @@ -0,0 +1,73 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; + +import javax.swing.*; +import java.util.Iterator; + +/** + * @author Eugene Belyaev + */ +public class ThreadsViewConfigurable extends BaseConfigurable { + private ThreadsViewSettings mySettings; + private JPanel myPanel; + private JCheckBox myShowGroupsCheckBox; + private JCheckBox myLineNumberCheckBox; + private JCheckBox myClassNameCheckBox; + private JCheckBox mySourceCheckBox; + private JCheckBox myShowSyntheticsCheckBox; + private JCheckBox myShowCurrentThreadChechBox; + + public ThreadsViewConfigurable(ThreadsViewSettings settings) { + mySettings = settings; + } + + public String getDisplayName() { + return "Customize Threads View";//"Threads View Properties"; + } + + public JComponent createComponent() { + return myPanel; + } + + public Icon getIcon() { + return null; + } + + public void apply() { + mySettings.SHOW_CLASS_NAME = myClassNameCheckBox.isSelected(); + mySettings.SHOW_LINE_NUMBER = myLineNumberCheckBox.isSelected(); + mySettings.SHOW_SOURCE_NAME = mySourceCheckBox.isSelected(); + mySettings.SHOW_THREAD_GROUPS = myShowGroupsCheckBox.isSelected(); + mySettings.SHOW_SYNTHETIC_FRAMES = myShowSyntheticsCheckBox.isSelected(); + mySettings.SHOW_CURRENT_THREAD = myShowCurrentThreadChechBox.isSelected(); + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + for (int i = 0; i < openProjects.length; i++) { + Project project = openProjects[i]; + for (Iterator iterator = (DebuggerManagerEx.getInstanceEx(project)).getSessions().iterator(); iterator.hasNext();) { + ((DebuggerSession)iterator.next()).refresh(); + } + } + } + + public void reset() { + myClassNameCheckBox.setSelected(mySettings.SHOW_CLASS_NAME); + myLineNumberCheckBox.setSelected(mySettings.SHOW_LINE_NUMBER); + mySourceCheckBox.setSelected(mySettings.SHOW_SOURCE_NAME); + myShowGroupsCheckBox.setSelected(mySettings.SHOW_THREAD_GROUPS); + myShowSyntheticsCheckBox.setSelected(mySettings.SHOW_SYNTHETIC_FRAMES); + myShowCurrentThreadChechBox.setSelected(mySettings.SHOW_CURRENT_THREAD); + } + + public String getHelpTopic() { + return null; + } + + public void disposeUIResources() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewSettings.java new file mode 100644 index 00000000000..86793796ea3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ThreadsViewSettings.java @@ -0,0 +1,53 @@ +package com.intellij.debugger.settings; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +public class ThreadsViewSettings implements NamedJDOMExternalizable, ApplicationComponent { + public boolean SHOW_THREAD_GROUPS = false; + public boolean SHOW_LINE_NUMBER = true; + public boolean SHOW_CLASS_NAME = true; + public boolean SHOW_SOURCE_NAME = false; + public boolean SHOW_SYNTHETIC_FRAMES = true; + public boolean SHOW_CURRENT_THREAD = true; + private Configurable myConfigurable; + + public Configurable getConfigurable() { + if (myConfigurable == null) { + myConfigurable = new ThreadsViewConfigurable(this); + } + return myConfigurable; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public String getExternalFileName() { + return "debugger.threadsview"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public String getComponentName() { + return "ThreadsViewSettings"; + } + + public static ThreadsViewSettings getInstance() { + return ApplicationManager.getApplication().getComponent(ThreadsViewSettings.class); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java new file mode 100644 index 00000000000..c568d16e18a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java @@ -0,0 +1,119 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.ui.impl.watch.render.ClassRenderer; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; + +/** + * @author Eugene Belyaev + */ +public class ViewsGeneralConfigurable implements Configurable { + private ViewsGeneralSettings myGeneralSettings; + private JPanel myPanel; + private JCheckBox myAutoscrollCheckBox; + private JCheckBox myShowSyntheticsCheckBox; + + private JCheckBox mySortCheckBox; + private JCheckBox myHideNullElementsCheckBox; + private JCheckBox myShowStaticCheckBox; + private StateRestoringCheckBox myShowStaticFinalCheckBox; + private JPanel myArrayConfigurablePlace; + private ArrayRendererConfigurable myArrayRendererConfigurable; + private JCheckBox myAlternativeViews; + + public ViewsGeneralConfigurable() { + myGeneralSettings = ViewsGeneralSettings.getInstance(); + myShowStaticCheckBox.addChangeListener(new ChangeListener(){ + public void stateChanged(ChangeEvent e) { + if(myShowStaticCheckBox.isSelected()) { + myShowStaticFinalCheckBox.makeSelectable(); + } else { + myShowStaticFinalCheckBox.makeUnselectable(false); + } + } + }); + + myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettingsImpl.getInstanceEx().getArrayRenderer()); + myArrayConfigurablePlace.setLayout(new BorderLayout()); + myArrayConfigurablePlace.add(myArrayRendererConfigurable.createComponent()); + } + + public void disposeUIResources() { + myPanel = null; + } + + public String getDisplayName() { + return "Data views"; + } + + public JComponent createComponent() { + return myPanel; + } + + public Icon getIcon() { + return null; + } + + public void apply() { + if (myPanel != null) { + ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance(); + + applyTo(generalSettings); + + myArrayRendererConfigurable.apply(); + + generalSettings.fireRendererSettingsChanged(); + } + } + + private void applyTo(ViewsGeneralSettings generalSettings) { + generalSettings.AUTOSCROLL_TO_NEW_LOCALS = myAutoscrollCheckBox.isSelected(); + generalSettings.USE_ALTERNATIVE_RENDERERS = myAlternativeViews.isSelected(); + generalSettings.HIDE_NULL_ARRAY_ELEMENTS = myHideNullElementsCheckBox.isSelected(); + + ClassRenderer classRenderer = (ClassRenderer)NodeRendererSettingsImpl.getInstance().getClassRenderer(); + + classRenderer.SORT_ASCENDING = mySortCheckBox.isSelected(); + classRenderer.SHOW_STATIC = myShowStaticCheckBox.isSelected(); + classRenderer.SHOW_STATIC_FINAL = myShowStaticFinalCheckBox.isSelectedWhenSelectable(); + classRenderer.SHOW_SYNTHETICS = myShowSyntheticsCheckBox.isSelected(); + } + + public void reset() { + ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance(); + + myAutoscrollCheckBox.setSelected(generalSettings.AUTOSCROLL_TO_NEW_LOCALS); + myHideNullElementsCheckBox.setSelected(generalSettings.HIDE_NULL_ARRAY_ELEMENTS); + myAlternativeViews.setSelected(generalSettings.USE_ALTERNATIVE_RENDERERS); + + ClassRenderer classRenderer = (ClassRenderer)NodeRendererSettingsImpl.getInstance().getClassRenderer(); + + myShowSyntheticsCheckBox.setSelected(classRenderer.SHOW_SYNTHETICS); + mySortCheckBox.setSelected(classRenderer.SORT_ASCENDING); + myShowStaticCheckBox.setSelected(classRenderer.SHOW_STATIC); + myShowStaticFinalCheckBox.setSelected(classRenderer.SHOW_STATIC_FINAL); + if(!classRenderer.SHOW_STATIC) { + myShowStaticFinalCheckBox.makeUnselectable(false); + } + + myArrayRendererConfigurable.reset(); + } + + public boolean isModified() { + ViewsGeneralSettings settings = ((ViewsGeneralSettings)ViewsGeneralSettings.getInstance()).clone(); + applyTo(settings); + + return !DebuggerUtilsEx.externalizableEqual(settings, ViewsGeneralSettings.getInstance()) || myArrayRendererConfigurable.isModified(); + } + + public String getHelpTopic() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralSettings.java new file mode 100644 index 00000000000..987dd5b4d32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/settings/ViewsGeneralSettings.java @@ -0,0 +1,80 @@ +package com.intellij.debugger.settings; + +import com.intellij.debugger.ui.tree.render.NodeRendererSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +public class ViewsGeneralSettings implements NamedJDOMExternalizable, ApplicationComponent, Cloneable { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.ViewsSettings"); + public boolean SHOW_OBJECTID = true; + public boolean HIDE_NULL_ARRAY_ELEMENTS = true; + public boolean AUTOSCROLL_TO_NEW_LOCALS = true; + public boolean USE_ALTERNATIVE_RENDERERS = true; + private NodeRendererSettings myNodeRendererSettings; + + public ViewsGeneralSettings(NodeRendererSettings instance) { + myNodeRendererSettings = instance; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public static ViewsGeneralSettings getInstance() { + return ApplicationManager.getApplication().getComponent(ViewsGeneralSettings.class); + } + + public String getExternalFileName() { + return "debugger.frameview"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + fireRendererSettingsChanged(); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public String getComponentName() { + return "ViewsSettings"; + } + + void fireRendererSettingsChanged() { + ((NodeRendererSettingsImpl) myNodeRendererSettings).fireRenderersChanged(); + } + + public boolean equals(Object object) { + if(!(object instanceof ViewsGeneralSettings)) return false; + ViewsGeneralSettings generalSettings = ((ViewsGeneralSettings) object); + return SHOW_OBJECTID == generalSettings.SHOW_OBJECTID && + HIDE_NULL_ARRAY_ELEMENTS == generalSettings.HIDE_NULL_ARRAY_ELEMENTS && + AUTOSCROLL_TO_NEW_LOCALS == generalSettings.AUTOSCROLL_TO_NEW_LOCALS; + } + + protected ViewsGeneralSettings clone() { + try { + Element root = new Element("root"); + writeExternal(root); + ViewsGeneralSettings settings = new ViewsGeneralSettings(((NodeRendererSettingsImpl)myNodeRendererSettings).clone()); + settings.readExternal(root); + return settings; + } + catch (WriteExternalException e) { + LOG.error(e); + } + catch (InvalidDataException e) { + LOG.error(e); + } + return this; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditor.java new file mode 100644 index 00000000000..742051a9285 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditor.java @@ -0,0 +1,334 @@ +/* + * Class ClassFilterEditor + * @author Jeka + */ +package com.intellij.debugger.ui; + +import com.intellij.debugger.ClassFilter; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ui.Table; +import com.intellij.ui.ScrollPaneFactory; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class ClassFilterEditor extends JPanel { + protected JTable myTable = null; + protected FilterTableModel myTableModel = null; + private JButton myAddClassButton; + protected JButton myAddPatternButton; + private JButton myRemoveButton; + protected Project myProject; + private TreeClassChooserDialog.ClassFilter myChooserFilter; + private JPanel myPanel; + private JScrollPane myScrollPane; + private JPanel myScrollPanePlace; + + public ClassFilterEditor(Project project) { + this (project, null); + } + + public ClassFilterEditor(Project project, TreeClassChooserDialog.ClassFilter classFilter) { + super(new BorderLayout()); + add(myPanel); + myTable = new Table(); + myScrollPane = ScrollPaneFactory.createScrollPane(myTable); + myScrollPanePlace.setLayout(new BorderLayout()); + myScrollPanePlace.add(myScrollPane); + + myChooserFilter = classFilter; + myProject = project; + myAddClassButton.setDefaultCapable(false); + myAddPatternButton.setDefaultCapable(false); + myRemoveButton.setDefaultCapable(false); + + myTableModel = new FilterTableModel(); + myTable.setModel(myTableModel); + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.setTableHeader(null); + myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + myTable.setColumnSelectionAllowed(false); + + TableColumnModel columnModel = myTable.getColumnModel(); + TableColumn column = columnModel.getColumn(myTableModel.CHECK_MARK); + int width = new JCheckBox().getPreferredSize().width; + column.setPreferredWidth(width); + column.setMaxWidth(width); + column.setCellRenderer(new EnabledCellRenderer(myTable.getDefaultRenderer(Boolean.class))); + columnModel.getColumn(myTableModel.FILTER).setCellRenderer(new FilterCellRenderer()); + + myTable.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myAddClassButton.doClick(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), + JComponent.WHEN_FOCUSED + ); + myTable.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myRemoveButton.doClick(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_FOCUSED + ); + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + myRemoveButton.setEnabled(myTable.getSelectedRow() > -1); + } + }); + + myAddPatternButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addPatternFilter(); + } + }); + myAddClassButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addClassFilter(); + } + }); + + myRemoveButton.addActionListener(new RemoveAction()); + myRemoveButton.setEnabled(false); + } + + public void setFilters(ClassFilter[] filters) { + myTableModel.setFilters(filters); + } + + public ClassFilter[] getFilters() { + return myTableModel.getFilters(); + } + + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + + myAddPatternButton.setEnabled(enabled); + myAddClassButton.setEnabled(enabled); + myRemoveButton.setEnabled((myTable.getSelectedRow() > -1) && enabled); + myTable.setRowSelectionAllowed(enabled); + myTableModel.fireTableDataChanged(); + } + + public void stopEditing() { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + + protected final class FilterTableModel extends AbstractTableModel { + private List myFilters = new LinkedList(); + public final int CHECK_MARK = 0; + public final int FILTER = 1; + + public FilterTableModel() { + } + + public final void setFilters(ClassFilter[] filters) { + myFilters.clear(); + if (filters != null) { + for (int idx = 0; idx < filters.length; idx++) { + myFilters.add(filters[idx]); + } + } + fireTableDataChanged(); + } + + public ClassFilter[] getFilters() { + for (Iterator it = myFilters.iterator(); it.hasNext();) { + ClassFilter filter = (ClassFilter)it.next(); + String pattern = filter.getPattern(); + if (pattern == null || "".equals(pattern)) { + it.remove(); + } + } + return (ClassFilter[])myFilters.toArray(new ClassFilter[myFilters.size()]); + } + + public ClassFilter getFilterAt(int index) { + return (ClassFilter)myFilters.get(index); + } + + public int getFilterIndex(ClassFilter filter) { + return myFilters.indexOf(filter); + } + + protected void addRow(ClassFilter filter) { + myFilters.add(filter); + int row = myFilters.size() - 1; + fireTableRowsInserted(row, row); + } + + public void removeRows(int[] rows) { + List toRemove = new LinkedList(); + for (int idx = 0; idx < rows.length; idx++) { + toRemove.add(myFilters.get(rows[idx])); + } + myFilters.removeAll(toRemove); + toRemove.clear(); + fireTableDataChanged(); + } + + public int getRowCount() { + return myFilters.size(); + } + + public int getColumnCount() { + return 2; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + ClassFilter filter = (ClassFilter)myFilters.get(rowIndex); + if (columnIndex == FILTER) { + return filter; + } + if (columnIndex == CHECK_MARK) { + return filter.isEnabled()? Boolean.TRUE : Boolean.FALSE; + } + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + ClassFilter filter = (ClassFilter)myFilters.get(rowIndex); + if (columnIndex == FILTER) { + filter.setPattern(aValue != null? aValue.toString() : ""); + } + else if (columnIndex == CHECK_MARK) { + filter.setEnabled(aValue != null? ((Boolean)aValue).booleanValue() : true); + } +// fireTableCellUpdated(rowIndex, columnIndex); + fireTableRowsUpdated(rowIndex, rowIndex); + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECK_MARK) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + if (ClassFilterEditor.this.isEnabled()) { + return (columnIndex == CHECK_MARK); + } + return false; + } + } + + private class FilterCellRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + Color color = UIManager.getColor("Table.focusCellBackground"); + UIManager.put("Table.focusCellBackground", table.getSelectionBackground()); + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (component instanceof JLabel) { + ((JLabel)component).setBorder(noFocusBorder); + } + UIManager.put("Table.focusCellBackground", color); + ClassFilter filter = (ClassFilter)table.getValueAt(row, myTableModel.FILTER); + component.setEnabled(ClassFilterEditor.this.isEnabled() && filter.isEnabled()); + return component; + } + } + + private class EnabledCellRenderer extends DefaultTableCellRenderer { + private TableCellRenderer myDelegate; + + public EnabledCellRenderer(TableCellRenderer delegate) { + myDelegate = delegate; + } + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + component.setEnabled(ClassFilterEditor.this.isEnabled()); + return component; + } + } + + protected ClassFilter createFilter(String pattern){ + return new ClassFilter(pattern); + } + + protected void addPatternFilter() { + ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject); + dialog.show(); + if (dialog.isOK()) { + String pattern = dialog.getPattern(); + if (pattern != null) { + ClassFilter filter = createFilter(pattern); + if(filter != null){ + myTableModel.addRow(filter); + int row = myTableModel.getRowCount() - 1; + myTable.getSelectionModel().setSelectionInterval(row, row); + myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true)); + + } + myTable.requestFocus(); + } + } + } + + protected void addClassFilter() { + TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Class", myProject, GlobalSearchScope.allScope(myProject), myChooserFilter, null); + chooser.show(); + PsiClass selectedClass = chooser.getSelectedClass(); + if (selectedClass != null) { + ClassFilter filter = createFilter(selectedClass.getQualifiedName()); + if(filter != null){ + myTableModel.addRow(filter); + int row = myTableModel.getRowCount() - 1; + myTable.getSelectionModel().setSelectionInterval(row, row); + myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true)); + + } + myTable.requestFocus(); + } + } + + private final class RemoveAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + if(myTable.getRowCount() == 0) return; + int[] rows = myTable.getSelectedRows(); + stopEditing(); + if (rows.length > 0) { + int newRow = rows[0] - 1; + ClassFilter filter = (newRow >= 0 && newRow < myTableModel.getRowCount())? myTableModel.getFilterAt(newRow) : null; + myTableModel.removeRows(rows); + int indexToSelect = 0; + if (filter != null) { + indexToSelect = myTableModel.getFilterIndex(filter); + if (indexToSelect < 0) { + indexToSelect = 0; + } + } + if (myTableModel.getRowCount() > 0) { + myTable.getSelectionModel().setSelectionInterval(indexToSelect, indexToSelect); + } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myTable.requestFocus(); + } + }); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditorAddDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditorAddDialog.java new file mode 100644 index 00000000000..695004d1f30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ClassFilterEditorAddDialog.java @@ -0,0 +1,100 @@ +/* + * @author: Eugene Zhuravlev + * Date: Sep 11, 2002 + * Time: 5:23:47 PM + */ +package com.intellij.debugger.ui; + +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class ClassFilterEditorAddDialog extends DialogWrapper { + private final Project myProject; + private TextFieldWithBrowseButton myClassName; + + public ClassFilterEditorAddDialog(Project project) { + super(project, true); + myProject = project; + setTitle("New Filter"); + init(); + } + + protected JComponent createCenterPanel() { + Box box = Box.createVerticalBox(); + + JPanel _panel = new JPanel(new BorderLayout()); + myClassName = new TextFieldWithBrowseButton(); + _panel.add(new JLabel("Enter the filter pattern:"), BorderLayout.NORTH); + _panel.add(myClassName, BorderLayout.CENTER); + box.add(_panel); + + box.add(Box.createVerticalBox()); + + + JPanel panel = new JPanel(new BorderLayout()); + panel.setPreferredSize(new Dimension(310, -1)); + + JLabel iconLabel = new JLabel(Messages.getQuestionIcon()); + panel.add(iconLabel, BorderLayout.WEST); + panel.add(box, BorderLayout.CENTER); + + myClassName.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PsiClass currentClass = getSelectedClass(); + TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Class", myProject, GlobalSearchScope.allScope(myProject), null, null); + if (currentClass != null) { + PsiFile containingFile = currentClass.getContainingFile(); + if (containingFile != null) { + PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + if (containingDirectory != null) { + chooser.selectDirectory(containingDirectory); + } + } + } + chooser.show(); + PsiClass selectedClass = chooser.getSelectedClass(); + if (selectedClass != null) { + myClassName.setText(selectedClass.getQualifiedName()); + } + } + }); + + myClassName.setEnabled(myProject != null); + + return panel; + } + + private PsiClass getSelectedClass() { + final PsiManager psiManager = PsiManager.getInstance(myProject); + String classQName = myClassName.getText(); + if ("".equals(classQName)) { + return null; + } + return psiManager.findClass(classQName, GlobalSearchScope.allScope(myProject)); + } + + public JComponent getPreferredFocusedComponent() { + return myClassName.getTextField(); + } + + public String getPattern() { + return myClassName.getText(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.breakpoints.BreakpointsConfigurationDialogFactory.BreakpointsConfigurationDialog.AddFieldBreakpointDialog"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputDialog.java new file mode 100644 index 00000000000..d5e835409dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputDialog.java @@ -0,0 +1,67 @@ +package com.intellij.debugger.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiElement; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.PositionUtil; + +import javax.swing.*; +import java.awt.*; + +/** + * User: lex + * Date: Sep 16, 2003 + * Time: 6:43:46 PM + */ +public class CompletedInputDialog extends DialogWrapper { + JPanel myPanel; + DebuggerExpressionComboBox myCombo; + PsiElement myContext; + Project myProject; + private JLabel myLabel; + + public CompletedInputDialog(String title, String okText, Project project) { + super(project, false); + setTitle(title); + setOKButtonText(okText); + myProject = project; + setModal(false); + DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + myContext = PositionUtil.getContextElement(debuggerContext); + this.init(); + } + + public JComponent getPreferredFocusedComponent() { + return myCombo.getPreferredFocusedComponent(); + } + + protected JComponent createCenterPanel() { + myPanel = new JPanel(new GridBagLayout()); + myLabel = new JLabel("Enter the expression"); + myPanel.add(myLabel, new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, + new Insets(0, 1, 0, 1), 0, 0)); + + myCombo = new DebuggerExpressionComboBox(myProject, myContext, "evaluation"); + myCombo.selectAll(); + + myPanel.add(myCombo, new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 1, 0, 1), 0, 0)); + myPanel.setPreferredSize(new Dimension(200, 50)); + return myPanel; + } + + public TextWithImportsImpl getExpressionText() { + return myCombo.getText(); + } + + public DebuggerExpressionComboBox getCombo() { + return myCombo; + } + + public void setExpressionLabel(String text) { + myLabel.setText(text); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputTextField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputTextField.java new file mode 100644 index 00000000000..c05ad20f99d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/CompletedInputTextField.java @@ -0,0 +1,11 @@ +package com.intellij.debugger.ui; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 31, 2004 + * Time: 7:48:44 PM + * To change this template use File | Settings | File Templates. + */ +public interface CompletedInputTextField { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerEditorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerEditorImpl.java new file mode 100644 index 00000000000..b06e4281c9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -0,0 +1,128 @@ +package com.intellij.debugger.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.TextWithImports; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 2:46:02 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class DebuggerEditorImpl extends CompletitionEditor { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerEditorImpl"); + + public static final char SEPARATOR = 13; + + private final Project myProject; + private PsiElement myContext; + + private final String myRecentsId; + + private List myDocumentListeners = new ArrayList(); + private Document myCurrentDocument; + + public DebuggerEditorImpl(Project project, PsiElement context, String recentsId) { + myProject = project; + myContext = context; + myRecentsId = recentsId; + } + + protected TextWithImportsImpl createItem(Document document, Project project) { + if (document != null) { + PsiDocumentManager.getInstance(project).commitDocument(document); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + return createText(psiFile.getText(), ((PsiCodeFragment)psiFile).importsToString()); + } + + return createText(""); + } + + protected TextWithImportsImpl createText(String text) { + return createText(text, ""); + } + + protected abstract TextWithImportsImpl createText(String text, String importsString); + + public abstract JComponent getPreferredFocusedComponent(); + + public void setContext(PsiElement context) { + TextWithImports text = getText(); + myContext = context; + setText(text); + } + + public PsiElement getContext() { + return myContext; + } + + protected Project getProject() { + return myProject; + } + + public void requestFocus() { + getPreferredFocusedComponent().requestFocus(); + } + + protected Document createDocument(TextWithImportsImpl item) { + LOG.assertTrue(myContext == null || myContext.isValid()); + + if(item == null) { + item = createText(""); + } + PsiCodeFragment codeFragment = item.createCodeFragment(getContext(), getProject()); + + if(myCurrentDocument != null) { + for (Iterator iterator = myDocumentListeners.iterator(); iterator.hasNext();) { + DocumentListener documentListener = iterator.next(); + myCurrentDocument.removeDocumentListener(documentListener); + } + } + myCurrentDocument = PsiDocumentManager.getInstance(getProject()).getDocument(codeFragment); + + for (Iterator iterator = myDocumentListeners.iterator(); iterator.hasNext();) { + DocumentListener documentListener = iterator.next(); + myCurrentDocument.addDocumentListener(documentListener); + } + + return myCurrentDocument; + } + + public String getRecentsId() { + return myRecentsId; + } + + public void addRecent(TextWithImportsImpl text) { + if(getRecentsId() != null && text != null && !"".equals(text.getText())){ + DebuggerRecents.getInstance(getProject()).addRecent(getRecentsId(), text); + } + } + + public void addDocumentListener(DocumentListener listener) { + myDocumentListeners.add(listener); + if(myCurrentDocument != null) { + myCurrentDocument.addDocumentListener(listener); + } + } + + public void removeDocumentListener(DocumentListener listener) { + myDocumentListeners.remove(listener); + if(myCurrentDocument != null) { + myCurrentDocument.removeDocumentListener(listener); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerExpressionComboBox.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerExpressionComboBox.java new file mode 100644 index 00000000000..4c7701ff2a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerExpressionComboBox.java @@ -0,0 +1,179 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiElement; +import com.intellij.ui.EditorComboBoxEditor; +import com.intellij.ui.EditorComboBoxRenderer; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * @author ven + */ +public class DebuggerExpressionComboBox extends DebuggerEditorImpl { + public static final Key KEY = Key.create("DebuggerComboBoxEditor.KEY"); + public static final int MAX_ROWS = 20; + + private MyEditorComboBoxEditor myEditor; + private ComboBox myComboBox; + protected TextWithImportsImpl myItem; + + private class MyEditorComboBoxEditor extends EditorComboBoxEditor{ + public MyEditorComboBoxEditor(Project project, FileType fileType) { + super(project, fileType); + } + + public Document getDocument() { + return (Document)super.getItem(); + } + + public Object getItem() { + Document document = (Document)super.getItem(); + return createItem(document, getProject()); + } + + public void setItem(Object item) { + super.setItem(createDocument((TextWithImportsImpl)item)); + } + } + + public void setText(TextWithImports item) { + item = item.createText(((TextWithImportsImpl) item).getText().replace('\n', ' ')); + if(myComboBox.getItemCount() == 0 || !item.equals(myComboBox.getItemAt(0))) { + myComboBox.insertItemAt(item, 0); + } + myComboBox.setSelectedIndex(0); + if(myComboBox.isEditable()) { + myComboBox.getEditor().setItem(item); + } else { + myItem = (TextWithImportsImpl)item; + } + } + + public TextWithImportsImpl getText() { + return (TextWithImportsImpl)myComboBox.getEditor().getItem(); + } + + protected void updateEditor(TextWithImportsImpl item) { + if(!myComboBox.isEditable()) return; + + boolean focusOwner = myEditor != null ? myEditor.getEditorComponent().isFocusOwner() : false; + int offset = 0; + TextWithImportsImpl oldItem = null; + if(focusOwner) { + offset = myEditor.getEditor().getCaretModel().getOffset(); + oldItem = (TextWithImportsImpl)myEditor.getItem(); + } + myEditor = new MyEditorComboBoxEditor(getProject(), StdFileTypes.JAVA); + myComboBox.setEditor(myEditor); + myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor)); + + myComboBox.setMaximumRowCount(MAX_ROWS); + + myEditor.setItem(item); + if(focusOwner) { + myEditor.getEditorComponent().requestFocus(); + if(oldItem.equals(item)) { + myEditor.getEditor().getCaretModel().moveToOffset(offset); + } + } + } + + private void setRecents() { + boolean focusOwner = myEditor != null ? myEditor.getEditorComponent().isFocusOwner() : false; + myComboBox.removeAllItems(); + if(getRecentsId() != null) { + LinkedList recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()); + ArrayList singleLine = new ArrayList(); + for (Iterator iterator = recents.iterator(); iterator.hasNext();) { + TextWithImportsImpl evaluationText = iterator.next(); + if(evaluationText.getText().indexOf('\n') == -1) { + singleLine.add(evaluationText); + } + } + addRecents(singleLine); + } + if(focusOwner) myEditor.getEditorComponent().requestFocus(); + } + + public Dimension getMinimumSize() { + Dimension size = super.getMinimumSize(); + size.width = 100; + return size; + } + + public void setEnabled(boolean enabled) { + if(myComboBox.isEditable() == enabled) return; + + myComboBox.setEnabled(enabled); + myComboBox.setEditable(enabled); + + if(enabled) { + setRecents(); + updateEditor(myItem); + } else { + myItem = (TextWithImportsImpl)myComboBox.getEditor().getItem(); + myComboBox.removeAllItems(); + myComboBox.addItem(myItem); + } + } + + public TextWithImportsImpl createText(String text, String importsString) { + return new TextWithImportsImpl(TextWithImportsImpl.EXPRESSION_FACTORY, text, importsString); + } + + private void addRecents(List expressions) { + for (Iterator iterator = expressions.iterator(); iterator.hasNext();) { + final TextWithImportsImpl text = iterator.next(); + myComboBox.addItem(text); + } + if (myComboBox.getItemCount() > 0) { + myComboBox.setSelectedIndex(0); + } + } + + public DebuggerExpressionComboBox(Project project, String recentsId) { + this(project, null, recentsId); + } + + public DebuggerExpressionComboBox(Project project, PsiElement context, String recentsId) { + super(project, context, recentsId); + myComboBox = new ComboBox(-1); + setLayout(new BorderLayout()); + add(myComboBox); + + setText(TextWithImportsImpl.createExpressionText("")); + myItem = createText(""); + setEnabled(true); + } + + public JComponent getPreferredFocusedComponent() { + return (JComponent)myComboBox.getEditor().getEditorComponent(); + } + + public void selectAll() { + myComboBox.getEditor().selectAll(); + } + + public Editor getEditor() { + return myEditor.getEditor(); + } + + public void addRecent(TextWithImportsImpl text) { + super.addRecent(text); + setRecents(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerPanelsManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerPanelsManager.java new file mode 100644 index 00000000000..68ef424b59a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerPanelsManager.java @@ -0,0 +1,155 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.*; +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentListener; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.util.HashMap; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DebuggerPanelsManager implements ProjectComponent{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerPanelsManager"); + + private final Project myProject; + + private PositionHighlighter myEditorManager; + private HashMap mySessionTabs = new HashMap(); + + public DebuggerPanelsManager(Project project) { + myProject = project; + } + + private DebuggerStateManager getContextManager() { + return DebuggerManagerEx.getInstanceEx(myProject).getContextManager(); + } + + private final RunContentListener myContentListener = new RunContentListener() { + public void contentSelected(RunContentDescriptor descriptor) { + DebuggerSessionTab sessionTab = descriptor != null ? getSessionTab(descriptor.getProcessHandler()) : null; + + if (sessionTab != null) { + getContextManager().setState(sessionTab.getContextManager().getContext(), sessionTab.getSession().getState(), DebuggerSession.EVENT_CONTEXT, null); + } + else { + getContextManager().setState(DebuggerContextImpl.EMPTY_CONTEXT, DebuggerSession.STATE_DISPOSED, DebuggerSession.EVENT_CONTEXT, null); + } + } + + public void contentRemoved(RunContentDescriptor descriptor) { + DebuggerSessionTab sessionTab = getSessionTab(descriptor.getProcessHandler()); + if (sessionTab != null) { + mySessionTabs.remove(descriptor.getProcessHandler()); + sessionTab.dispose(); + } + } + }; + + public RunContentDescriptor attachVirtualMachine(RunProfile runProfile, + JavaProgramRunner runner, + RunProfileState state, + RunContentDescriptor reuseContent, + RemoteConnection remoteConnection, + boolean pollConnection) throws ExecutionException { + DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(myProject).attachVirtualMachine(runProfile.getName(), state, remoteConnection, pollConnection); + + DebuggerSessionTab sessionTab = new DebuggerSessionTab(myProject); + RunContentDescriptor runContentDescriptor = sessionTab.attachToSession( + debuggerSession, + runner, + runProfile, + state.getRunnerSettings(), + state.getConfigurationSettings()); + + mySessionTabs.put(runContentDescriptor.getProcessHandler(), sessionTab); + return runContentDescriptor; + } + + + public void projectOpened() { + myEditorManager = new PositionHighlighter(myProject, getContextManager()); + getContextManager().addListener(new DebuggerContextListener() { + public void changeEvent(final DebuggerContextImpl newContext, int event) { + if(event == DebuggerSession.EVENT_PAUSE) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + toFront(newContext.getDebuggerSession()); + } + }); + } + } + }); + + RunContentManager contentManager = ExecutionManager.getInstance(myProject).getContentManager(); + LOG.assertTrue(contentManager != null, "Content manager is null"); + contentManager.addRunContentListener(myContentListener, GenericDebuggerRunner.getRunnerInfo()); + } + + public void projectClosed() { + ExecutionManager.getInstance(myProject).getContentManager().removeRunContentListener(myContentListener); + } + + public String getComponentName() { + return "DebuggerPanelsManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public static DebuggerPanelsManager getInstance(Project project) { + return project.getComponent(DebuggerPanelsManager.class); + } + + public MainWatchPanel getWatchPanel() { + DebuggerContextImpl context = DebuggerManagerEx.getInstanceEx(myProject).getContext(); + DebuggerSessionTab sessionTab = getSessionTab(context.getDebuggerSession()); + return sessionTab != null ? sessionTab.getWatchPanel() : null; + } + + public void showFramePanel() { + DebuggerContextImpl context = DebuggerManagerEx.getInstanceEx(myProject).getContext(); + DebuggerSessionTab sessionTab = getSessionTab(context.getDebuggerSession()); + if(sessionTab != null) { + sessionTab.showFramePanel(); + } + } + + public void toFront(DebuggerSession session) { + DebuggerSessionTab sessionTab = getSessionTab(session); + if(sessionTab != null) { + sessionTab.toFront(); + } + } + + private DebuggerSessionTab getSessionTab(ProcessHandler processHandler) { + return mySessionTabs.get(processHandler); + } + + private DebuggerSessionTab getSessionTab(DebuggerSession session) { + return session != null ? getSessionTab(session.getProcess().getExecutionResult().getProcessHandler()) : null; + } + + public void updateContextPointDescription() { + myEditorManager.updateContextPointDescription(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerRecents.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerRecents.java new file mode 100644 index 00000000000..389733a661d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerRecents.java @@ -0,0 +1,56 @@ +package com.intellij.debugger.ui; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.HashMap; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; + +import java.util.LinkedList; +import java.util.Map; + +/** + * @author Lex + */ +public class DebuggerRecents implements ProjectComponent { + private Map> myRecentExpressions = new HashMap>(); + + DebuggerRecents() { + } + + public static DebuggerRecents getInstance(Project project) { + return project.getComponent(DebuggerRecents.class); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public LinkedList getRecents(Object id) { + LinkedList result = myRecentExpressions.get(id); + if(result == null){ + result = new LinkedList(); + myRecentExpressions.put(id, result); + } + return result; + } + + public void addRecent(Object id, TextWithImportsImpl recent) { + LinkedList recents = getRecents(id); + if(recents.size() >= DebuggerExpressionComboBox.MAX_ROWS) { + recents.removeLast(); + } + recents.remove(recent); + recents.addFirst(recent); + } + + public String getComponentName() { + return "DebuggerRecents"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerSessionTab.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerSessionTab.java new file mode 100644 index 00000000000..260c51dbe16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -0,0 +1,451 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerContextListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.impl.DebuggerPanel; +import com.intellij.debugger.ui.impl.FramePanel; +import com.intellij.debugger.ui.impl.MainWatchPanel; +import com.intellij.debugger.ui.impl.ThreadsPanel; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RestartAction; +import com.intellij.execution.ui.CloseAction; +import com.intellij.execution.ui.ExecutionConsole; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.ide.actions.ContextHelpAction; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.openapi.wm.impl.WindowManagerImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.*; +import org.apache.log4j.lf5.viewer.categoryexplorer.TreeModelAdapter; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.awt.*; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DebuggerSessionTab { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerSessionTab"); + + private static final Icon DEBUG_AGAIN_ICON = IconLoader.getIcon("/actions/startDebugger.png"); + + private static final Icon CONSOLE_ICON = IconLoader.getIcon("/debugger/console.png"); + private static final Icon THREADS_ICON = IconLoader.getIcon("/debugger/threads.png"); + private static final Icon FRAME_ICON = IconLoader.getIcon("/debugger/frame.png"); + private static final Icon WATCHES_ICON = IconLoader.getIcon("/debugger/watches.png"); + + private static Key CONTENT_KIND = Key.create("ContentKind"); + public static Key CONSOLE_CONTENT = Key.create("ConsoleContent"); + public static Key THREADS_CONTENT = Key.create("ThreadsContent"); + public static Key FRAME_CONTENT = Key.create("FrameContent"); + public static Key WATCHES_CONTENT = Key.create("WatchesContent"); + + private final Project myProject; + private final ContentManager myViewsContentManager; + + private JPanel myToolBarPanel; + private ActionToolbarEx myFirstToolbar; + private ActionToolbarEx mySecondToolbar; + + /** + * 4 debugger views + */ + private final JPanel myContentPanel; + private final FramePanel myFramePanel; + private final ThreadsPanel myThreadsPanel; + private final MainWatchPanel myWatchPanel; + + private ExecutionConsole myConsole; + private JavaProgramRunner myRunner; + private RunProfile myConfiguration; + private DebuggerSession myDebuggerSession; + + private RunnerSettings myRunnerSettings; + private ConfigurationPerRunnerSettings myConfigurationSettings; + private RunContentDescriptor myRunContentDescriptor; + + private boolean myIsJustStarted = true; + + private final MyDebuggerStateManager myStateManager = new MyDebuggerStateManager(); + + public DebuggerSessionTab(Project project) { + myProject = project; + myContentPanel = new JPanel(new BorderLayout()); + if(!ApplicationManager.getApplication().isUnitTestMode()) { + getContextManager().addListener(new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + switch(event) { + case DebuggerSession.EVENT_DETACHED: + DebuggerSettings settings = DebuggerSettings.getInstance(); + + myFirstToolbar.updateActions(); + mySecondToolbar.updateActions(); + + if (settings.HIDE_DEBUGGER_ON_PROCESS_TERMINATION) { + try { + ExecutionManager.getInstance(getProject()).getContentManager().hideRunContent(myRunner, myRunContentDescriptor); + } + catch (NullPointerException e) { + //if we can get closeProcess after the project have been closed + LOG.debug(e); + } + } + break; + + case DebuggerSession.EVENT_PAUSE: + if (myIsJustStarted) { + final Content frameView = findContent(FRAME_CONTENT); + final Content watchView = findContent(WATCHES_CONTENT); + if (frameView != null) { + Content content = myViewsContentManager.getSelectedContent(); + if ((content == null || content.equals(frameView) || content.equals(watchView))) { + return; + } + showFramePanel(); + } + myIsJustStarted = false; + } + } + } + }); + } + + myWatchPanel = new MainWatchPanel(getProject(), getContextManager()) { + protected boolean shouldRebuildNow() { + return myViewsContentManager.getSelectedContent().getComponent() == this; + } + }; + updateWatchTreeTab(); + + myFramePanel = new FramePanel(getProject(), getContextManager()) { + protected boolean shouldRebuildNow() { + return myViewsContentManager.getSelectedContent().getComponent() == this; + } + }; + + myThreadsPanel = new ThreadsPanel(getProject(), getContextManager()) { + protected boolean shouldRebuildNow() { + return myViewsContentManager.getSelectedContent().getComponent() == this; + } + }; + + TabbedPaneContentUI ui = new TabbedPaneContentUI(JTabbedPane.TOP); + myViewsContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(ui, false, getProject()); + + Content content; + content = PeerFactory.getInstance().getContentFactory().createContent(myThreadsPanel, "Threads", false); + content.setIcon(THREADS_ICON); + content.putUserData(CONTENT_KIND, THREADS_CONTENT); + myViewsContentManager.addContent(content); + + content = PeerFactory.getInstance().getContentFactory().createContent(myFramePanel, "Frame", false); + content.setIcon(FRAME_ICON); + content.putUserData(CONTENT_KIND, FRAME_CONTENT); + myViewsContentManager.addContent(content); + + content = PeerFactory.getInstance().getContentFactory().createContent(myWatchPanel, "Watches", false); + content.setIcon(WATCHES_ICON); + content.putUserData(CONTENT_KIND, WATCHES_CONTENT); + myViewsContentManager.addContent(content); + + myViewsContentManager.addContentManagerListener(new ContentManagerAdapter() { + public void selectionChanged(ContentManagerEvent event) { + Content selectedContent = myViewsContentManager.getSelectedContent(); + if (selectedContent != null) { + JComponent component = selectedContent.getComponent(); + if (component instanceof DebuggerPanel) { + DebuggerPanel panel = ((DebuggerPanel)component); + if (panel.isNeedsRefresh()) { + panel.rebuildWhenVisible(); + } + } + } + } + }); + + myContentPanel.add(myViewsContentManager.getComponent(), BorderLayout.CENTER); + } + + public void showFramePanel() { + final Content content = findContent(FRAME_CONTENT); + if (content != null) { + myViewsContentManager.setSelectedContent(content); + } + } + + private Project getProject() { + return myProject; + } + + public MainWatchPanel getWatchPanel() { + return myWatchPanel; + } + + private RunContentDescriptor initUI(ExecutionResult executionResult) { + + myConsole = executionResult.getExecutionConsole(); + myRunContentDescriptor = new RunContentDescriptor(myConsole, executionResult.getProcessHandler(), myContentPanel, + getSessionName()); + + if(ApplicationManager.getApplication().isUnitTestMode()) return myRunContentDescriptor; + + Content content = findContent(CONSOLE_CONTENT); + if(content != null) { + myViewsContentManager.removeContent(content); + } + + content = PeerFactory.getInstance().getContentFactory().createContent(myConsole.getComponent(), "Console", false); + content.setIcon(CONSOLE_ICON); + content.putUserData(CONTENT_KIND, CONSOLE_CONTENT); + + Content[] contents = myViewsContentManager.getContents(); + myViewsContentManager.removeAllContents(); + + myViewsContentManager.addContent(content); + for (int i = 0; i < contents.length; i++) { + myViewsContentManager.addContent(contents[i]); + } + + if(myToolBarPanel != null) { + myContentPanel.remove(myToolBarPanel); + } + + myFirstToolbar = createFirstToolbar(myRunContentDescriptor, myContentPanel); + mySecondToolbar = createSecondToolbar(); + + myToolBarPanel = new JPanel(new GridLayout(1, 2)); + myToolBarPanel.add(myFirstToolbar.getComponent()); + myToolBarPanel.add(mySecondToolbar.getComponent()); + myContentPanel.add(myToolBarPanel, BorderLayout.WEST); + + return myRunContentDescriptor; + } + + private void updateWatchTreeTab() { + class MyContentUpdater extends TreeModelAdapter { + public void updateContent() { + Content content = findContent(WATCHES_CONTENT); + if (content != null) { + int count = myWatchPanel.getWatchTree().getWatchCount(); + String displayName = (count > 0) ? ("Watches (" + count + ")") : "Watches"; + content.setDisplayName(displayName); + } + } + public void treeStructureChanged(TreeModelEvent event) { + if(event.getPath().length <= 1) { + updateContent(); + } + } + } + MyContentUpdater updater = new MyContentUpdater(); + updater.updateContent(); + myWatchPanel.getWatchTree().getModel().addTreeModelListener(updater); + } + + private ActionToolbarEx createSecondToolbar() { + ActionManager actionManager = ActionManager.getInstance(); + DefaultActionGroup group = new DefaultActionGroup(); + AnAction action; + action = actionManager.getAction(DebuggerActions.STEP_OVER); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.STEP_INTO); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.STEP_OUT); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.FORCE_STEP_INTO); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.POP_FRAME); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.RUN_TO_CURSOR); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.VIEW_BREAKPOINTS); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.TOGGLE_STEP_SUSPEND_POLICY); + if (action != null) group.add(action); + + return (ActionToolbarEx)ActionManager.getInstance().createActionToolbar(ActionPlaces.DEBUGGER_TOOLBAR, group, false); + } + + private ActionToolbarEx createFirstToolbar(RunContentDescriptor contentDescriptor, JComponent component) { + DefaultActionGroup group = new DefaultActionGroup(); + ActionManager actionManager = ActionManager.getInstance(); + + // first toolbar + + RestartAction restarAction = new RestartAction(myRunner, myConfiguration, contentDescriptor.getProcessHandler(), DEBUG_AGAIN_ICON, + contentDescriptor, myRunnerSettings, myConfigurationSettings); + group.add(restarAction); + restarAction.registerShortcut(component); + AnAction action = actionManager.getAction(DebuggerActions.RESUME); + if (action != null) group.add(action); + action = actionManager.getAction(DebuggerActions.PAUSE); + if (action != null) group.add(action); + AnAction stopAction = actionManager.getAction(IdeActions.ACTION_STOP_PROGRAM); + if (action != null) group.add(stopAction); + action = actionManager.getAction(DebuggerActions.EVALUATE_EXPRESSION); + if (action != null) group.add(action); + group.add(new CloseAction(myRunner, contentDescriptor, getProject())); + group.add(new ContextHelpAction(myRunner.getInfo().getHelpId())); + return (ActionToolbarEx)ActionManager.getInstance().createActionToolbar(ActionPlaces.DEBUGGER_TOOLBAR, group, false); + } + + private Content findContent(Key key) { + if (myViewsContentManager != null) { + Content[] contents = myViewsContentManager.getContents(); + for (int idx = 0; idx < contents.length; idx++) { + Content content = contents[idx]; + Key kind = (Key)content.getUserData(CONTENT_KIND); + if (key.equals(kind)) { + return content; + } + } + } + return null; + } + + public void dispose() { + disposeSession(); + myThreadsPanel.dispose(); + myFramePanel.dispose(); + myWatchPanel.dispose(); + myViewsContentManager.removeAllContents(); + + myConsole = null; + } + + private void disposeSession() { + if(myDebuggerSession != null) { + myDebuggerSession.dispose(); + } + } + + private DebugProcessImpl getDebugProcess() { + return myDebuggerSession != null ? myDebuggerSession.getProcess() : null; + } + + public void reuse(DebuggerSessionTab reuseSession) { + getDebugProcess().setSuspendPolicy(reuseSession.getDebugProcess().getSuspendPolicy()); + DebuggerTreeNodeImpl[] watches = reuseSession.getWatchPanel().getWatchTree().getWatches(); + + for (int i = 0; i < watches.length; i++) { + DebuggerTreeNodeImpl watch = watches[i]; + getWatchPanel().getWatchTree().addWatch((WatchItemDescriptor)watch.getDescriptor()); + } + } + + protected void toFront() { + ((WindowManagerImpl)WindowManager.getInstance()).getFrame(getProject()).toFront(); + ExecutionManager.getInstance(getProject()).getContentManager().toFrontRunContent(myRunner, myRunContentDescriptor); + } + + public RunContentDescriptor getRunContentDescriptor() { + return myRunContentDescriptor; + } + + public ExecutionConsole getConsole() { + return myConsole; + } + + public String getSessionName() { + return myConfiguration.getName(); + } + + public ContentManager getViewsContentManager() { + return myViewsContentManager; + } + + public DebuggerStateManager getContextManager() { + return myStateManager; + } + + public TextWithImportsImpl getSelectedExpression() { + if (myDebuggerSession.getState() != DebuggerSession.STATE_PAUSED) { + return null; + } + JTree tree = myFramePanel.getFrameTree(); + if (tree == null || !tree.hasFocus()) { + tree = myWatchPanel.getWatchTree(); + if (tree == null || !tree.hasFocus()) { + return null; + } + } + TreePath path = tree.getSelectionPath(); + if (path == null) { + return null; + } + DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)path.getLastPathComponent(); + if (node == null) { + return null; + } + NodeDescriptorImpl descriptor = node.getDescriptor(); + if (!(descriptor instanceof ValueDescriptorImpl)) { + return null; + } + if (descriptor instanceof WatchItemDescriptor) { + return (TextWithImportsImpl)((WatchItemDescriptor)descriptor).getEvaluationText(); + } + return DebuggerTreeNodeExpression.createEvaluationText(node, getContextManager().getContext()); + } + + public RunContentDescriptor attachToSession( + final DebuggerSession session, + final JavaProgramRunner runner, + final RunProfile runProfile, + final RunnerSettings runnerSettings, + final ConfigurationPerRunnerSettings configurationPerRunnerSettings) throws ExecutionException { + disposeSession(); + myDebuggerSession = session; + myRunner = runner; + myRunnerSettings = runnerSettings; + myConfigurationSettings = configurationPerRunnerSettings; + myConfiguration = runProfile; + myDebuggerSession.getContextManager().addListener(new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + myStateManager.fireStateChanged(newContext, event); + } + }); + return initUI(getDebugProcess().getExecutionResult()); + } + + public DebuggerSession getSession() { + return myDebuggerSession; + } + + private class MyDebuggerStateManager extends DebuggerStateManager { + public void fireStateChanged(DebuggerContextImpl newContext, int event) { + super.fireStateChanged(newContext, event); + } + + public DebuggerContextImpl getContext() { + return myDebuggerSession.getContextManager().getContext(); + } + + public void setState(DebuggerContextImpl context, int state, int event, String description) { + myDebuggerSession.getContextManager().setState(context, state, event, description); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerStatementEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerStatementEditor.java new file mode 100644 index 00000000000..603900163a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/DebuggerStatementEditor.java @@ -0,0 +1,107 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.ui.EditorTextField; + +import javax.swing.*; +import java.awt.*; +import java.util.LinkedList; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 2:39:17 PM + * To change this template use File | Settings | File Templates. + */ +public class DebuggerStatementEditor extends DebuggerEditorImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerStatementEditor"); + + private final EditorTextField myEditor; + + private int myRecentIdx; + + public DebuggerStatementEditor(Project project, PsiElement context, String recentsId) { + super(project, context, recentsId); + myRecentIdx = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()).size(); + myEditor = new EditorTextField("", project, StdFileTypes.JAVA) { + protected EditorEx createEditor() { + EditorEx editor = super.createEditor(); + editor.setOneLineMode(false); + return editor; + } + }; + setLayout(new BorderLayout()); + add(myEditor, BorderLayout.CENTER); + + DefaultActionGroup actionGroup = new DefaultActionGroup(null, false); + actionGroup.add(new ItemAction(IdeActions.ACTION_PREVIOUS_OCCURENCE, this){ + public void actionPerformed(AnActionEvent e) { + LOG.assertTrue(myRecentIdx > 0); + myRecentIdx --; + updateTextFromRecents(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myRecentIdx > 0); + } + }); + actionGroup.add(new ItemAction(IdeActions.ACTION_NEXT_OCCURENCE, this){ + public void actionPerformed(AnActionEvent e) { + if(LOG.isDebugEnabled()) { + LinkedList recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()); + LOG.assertTrue(myRecentIdx < recents.size()); + } + myRecentIdx ++; + updateTextFromRecents(); + } + + public void update(AnActionEvent e) { + LinkedList recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()); + e.getPresentation().setEnabled(myRecentIdx < recents.size()); + } + }); + + add(ActionManager.getInstance().createActionToolbar(ActionPlaces.COMBO_PAGER, actionGroup, false).getComponent(), + BorderLayout.EAST); + + setText(TextWithImportsImpl.EMPTY); + } + + private void updateTextFromRecents() { + LinkedList recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()); + LOG.assertTrue(myRecentIdx <= recents.size()); + setText(myRecentIdx < recents.size() ? recents.get(myRecentIdx) : TextWithImportsImpl.EMPTY); + } + + public JComponent getPreferredFocusedComponent() { + return myEditor.getEditor().getContentComponent(); + } + + public TextWithImportsImpl getText() { + return createItem(myEditor.getDocument(), getProject()); + } + + public void setText(TextWithImports text) { + myEditor.setDocument(createDocument((TextWithImportsImpl)text)); + } + + public TextWithImportsImpl createText(String text, String importsString) { + return new TextWithImportsImpl(TextWithImportsImpl.CODE_BLOCK_FACTORY, text, importsString); + } + + private static abstract class ItemAction extends AnAction { + public ItemAction(String sourceActionName, JComponent component) { + copyFrom(ActionManager.getInstance().getAction(sourceActionName)); + registerCustomShortcutSet(getShortcutSet(), component); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EditorEvaluationCommand.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EditorEvaluationCommand.java new file mode 100644 index 00000000000..dff11e12cbe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EditorEvaluationCommand.java @@ -0,0 +1,75 @@ +package com.intellij.debugger.ui; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.util.ProgressWindowWithNotification; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.debugger.DebuggerInvocationUtil; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Mar 15, 2004 + * Time: 4:07:59 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class EditorEvaluationCommand extends DebuggerContextCommandImpl { + protected final PsiElement myElement; + private final Editor myEditor; + private final ProgressWindowWithNotification myProgressWindow; + private final DebuggerContextImpl myDebuggerContext; + + public EditorEvaluationCommand(Editor editor, PsiElement expression, DebuggerContextImpl context) { + super(context); + Project project = expression.getProject(); + myProgressWindow = new ProgressWindowWithNotification(true, project); + myEditor = editor; + myElement = expression; + myDebuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext(); + } + + protected abstract T evaluate(EvaluationContextImpl evaluationContext) throws EvaluateException; + + public T evaluate() throws EvaluateException { + getProgressWindow().setText("Evaluating " + myElement.getText()); + + try { + T result = evaluate(myDebuggerContext.createEvaluationContext()); + + if(getProgressWindow().isCanceled()) throw new ProcessCanceledException(); + + return result; + } catch (final EvaluateException e) { + DebuggerInvocationUtil.invokeLater(myDebuggerContext.getProject(), new Runnable() { + public void run() { + showEvaluationHint(myEditor, myElement, e); + } + }, myProgressWindow.getModalityState()); + throw e; + } + } + + public static void showEvaluationHint(final Editor myEditor, final PsiElement myElement, final EvaluateException e) { + HintManager.getInstance().showErrorHint(myEditor, e.getMessage(), myElement.getTextRange().getStartOffset(), + myElement.getTextRange().getEndOffset(), HintManager.RIGHT, + HintManager.HIDE_BY_ESCAPE | HintManager.HIDE_BY_TEXT_CHANGE, + 1500); + } + + public ProgressWindowWithNotification getProgressWindow() { + return myProgressWindow; + } + + public Editor getEditor() { + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluationDialog.java new file mode 100644 index 00000000000..69fc4c3a4c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluationDialog.java @@ -0,0 +1,199 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.ui.impl.WatchPanel; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.impl.DebuggerContextListener; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; + +import javax.swing.*; +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 4:30:11 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class EvaluationDialog extends DialogWrapper { + private MyEvaluationPanel myEvaluationPanel; + private Project myProject; + private final DebuggerContextListener myContextListener; + private final DebuggerEditorImpl myEditor; + + //TODO:[lex] move this code to DebuggerEditorImpl + private final PsiTreeChangeListener myPsiListener = new PsiTreeChangeAdapter() { + public void childRemoved(PsiTreeChangeEvent event) { checkContext(); } + public void childReplaced(PsiTreeChangeEvent event) { checkContext(); } + public void childMoved(PsiTreeChangeEvent event) { checkContext(); } + }; + + private void checkContext() { + if(getContext() != null) { + if(!getContext().isValid()) { + setDebuggerContext(DebuggerManagerEx.getInstanceEx(myProject).getContextManager().getContext()); + } + } + } + + public EvaluationDialog(Project project, TextWithImportsImpl text) { + super(project, true); + myProject = project; + setModal(false); + setCancelButtonText("Close"); + setOKButtonText("Evaluate"); + + myEditor = createEditor(); + myEvaluationPanel = new MyEvaluationPanel(myProject); + + setDebuggerContext(getDebuggerContext()); + initDialogData(text); + + myContextListener = new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + boolean close = true; + for (Iterator iterator = DebuggerManagerEx.getInstanceEx(myProject).getSessions().iterator(); iterator.hasNext();) { + DebuggerSession session = (DebuggerSession) iterator.next(); + if(!session.isStopped()) { + close = false; + break; + } + } + + if(close) { + close(CANCEL_EXIT_CODE); + } else { + setDebuggerContext(newContext); + } + } + }; + DebuggerManagerEx.getInstanceEx(myProject).getContextManager().addListener(myContextListener); + + setHorizontalStretch(1f); + setVerticalStretch(1f); + + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiListener); + } + + protected void doOKAction() { + if (isOKActionEnabled()) { + doEvaluate(); + //getDebuggerContext().getDebuggerSession().refresh(); + } + } + + protected void doEvaluate() { + if (myEditor == null || myEvaluationPanel == null) { + return; + } + + myEvaluationPanel.clear(); + TextWithImportsImpl codeToEvaluate = getCodeToEvaluate(); + if (codeToEvaluate == null) { + return; + } + try { + setOKActionEnabled(false); + NodeDescriptorImpl descriptor = myEvaluationPanel.getWatchTree().addWatch(codeToEvaluate).getDescriptor(); + myEvaluationPanel.getWatchTree().rebuild(getDebuggerContext()); + descriptor.myIsExpanded = true; + } + finally { + setOKActionEnabled(true); + } + getEditor().addRecent(getCodeToEvaluate()); + } + + protected TextWithImportsImpl getCodeToEvaluate() { + TextWithImportsImpl text = (TextWithImportsImpl)getEditor().getText(); + String s = text.getText(); + if (s != null) { + s = s.trim(); + } + if ("".equals(s)) { + return null; + } + return text; + } + + public JComponent getPreferredFocusedComponent() { + return myEditor.getPreferredFocusedComponent(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.debugger.ui.EvaluationDialog2"; + } + + protected void dispose() { + PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiListener); + DebuggerManagerEx.getInstanceEx(myProject).getContextManager().removeListener(myContextListener); + myEvaluationPanel.dispose(); + super.dispose(); + } + + protected class MyEvaluationPanel extends WatchPanel { + public MyEvaluationPanel(final Project project) { + super(project, (DebuggerManagerEx.getInstanceEx(project)).getContextManager()); + getWatchTree().setEvaluationPriority(DebuggerManagerThreadImpl.HIGH_PRIORITY); + getWatchTree().setAllowBreakpoints(true); + } + + protected ActionPopupMenu createPopupMenu() { + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.EVALUATION_DIALOG_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.EVALUATION_DIALOG_POPUP, group); + return popupMenu; + } + + protected void changeEvent(DebuggerContextImpl newContext, int event) { + if(event == DebuggerSession.EVENT_REFRESH) return; + if(newContext.getDebuggerSession() != null && newContext.getDebuggerSession().getState() == DebuggerSession.STATE_WAIT_EVALUATION) return; + + super.changeEvent(newContext, event); + } + } + + protected void setDebuggerContext(DebuggerContextImpl context) { + myEditor.setContext(PositionUtil.getContextElement(context)); + } + + protected PsiElement getContext() { + return myEditor.getContext(); + } + + protected void initDialogData(TextWithImportsImpl text) { + getEditor().setText(text); + myEvaluationPanel.clear(); + } + + public DebuggerContextImpl getDebuggerContext() { + return DebuggerManagerEx.getInstanceEx(myProject).getContext(); + } + + public DebuggerEditorImpl getEditor() { + return myEditor; + } + + protected abstract DebuggerEditorImpl createEditor(); + + protected MyEvaluationPanel getEvaluationPanel() { + return myEvaluationPanel; + } + + public Project getProject() { + return myProject; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluatorRunnable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluatorRunnable.java new file mode 100644 index 00000000000..ba2fdf4585b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/EvaluatorRunnable.java @@ -0,0 +1,12 @@ +package com.intellij.debugger.ui; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: May 28, 2003 + * Time: 1:59:27 PM + * To change this template use Options | File Templates. + */ +public interface EvaluatorRunnable extends Runnable{ + Object getValue(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExportDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExportDialog.java new file mode 100644 index 00000000000..773d7a385d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExportDialog.java @@ -0,0 +1,243 @@ +/** + * created at Dec 14, 2001 + * @author Jeka + */ +package com.intellij.debugger.ui; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.ui.impl.watch.MessageDescriptor; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.Iterator; +import java.util.List; + +public class ExportDialog extends DialogWrapper { + private JTextArea myTextArea = new JTextArea(); + private TextFieldWithBrowseButton myTfFilePath; + private Project myProject; + private final DebugProcessImpl myDebugProcess; + private CopyToClipboardAction myCopyToClipboardAction = new CopyToClipboardAction(); + + public ExportDialog(DebugProcessImpl debugProcess, String destinationDirectory) { + super(debugProcess.getProject(), true); + myDebugProcess = debugProcess; + myProject = debugProcess.getProject(); + setTitle("Export Threads"); + setOKButtonText("Save"); + + init(); + + setOKActionEnabled(false); + myCopyToClipboardAction.setEnabled(false); + + myTextArea.setText(MessageDescriptor.EVALUATING.getLabel()); + debugProcess.getManagerThread().invoke(new ExportThreadsCommand(ApplicationManager.getApplication().getModalityStateForComponent(myTextArea))); + + myTfFilePath.setText(destinationDirectory + File.separator + "threads_report.txt"); + setHorizontalStretch(1.5f); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(), myCopyToClipboardAction, getCancelAction()}; + } + + protected JComponent createNorthPanel() { + JPanel box = new JPanel(new BorderLayout()); + box.add(new JLabel("Export to file:"), BorderLayout.WEST); + myTfFilePath = new TextFieldWithBrowseButton(); + myTfFilePath.addBrowseFolderListener(null, null, myProject, FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()); + box.add(myTfFilePath, BorderLayout.CENTER); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(box, BorderLayout.CENTER); + panel.add(Box.createVerticalStrut(7), BorderLayout.SOUTH); + return panel; + } + + protected JComponent createCenterPanel() { + myTextArea.setEditable(false); + JScrollPane pane = new JScrollPane(myTextArea); + pane.setPreferredSize(new Dimension(400, 300)); + return pane; + } + + protected void doOKAction() { + String path = myTfFilePath.getText(); + File file = new File(path); + if (file.isDirectory()) { + Messages.showMessageDialog( + myProject, + "The specified file is a directory.\nPlease specify a correct file name.", + "Error", + Messages.getErrorIcon() + ); + } + else if (file.exists()) { + int answer = Messages.showYesNoDialog( + myProject, + "The file\n\"" + path + "\"\nalready exists. Would you like to overwrite it?", + "File Exists", + Messages.getQuestionIcon() + ); + if (answer == 0) { + super.doOKAction(); + } + } + else { + super.doOKAction(); + } + } + + public String getFilePath() { + return myTfFilePath.getText(); + } + + public String getTextToSave() { + return myTextArea.getText(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.ExportDialog"; + } + + public String getExportThreadsText(VirtualMachineProxyImpl vmProxy) { + StringBuffer buffer = new StringBuffer(512); + List threads = vmProxy.getVirtualMachine().allThreads(); + for (Iterator it = threads.iterator(); it.hasNext();) { + ThreadReference threadReference = (ThreadReference)it.next(); + buffer.append(threadName(threadReference)); + ReferenceType referenceType = threadReference.referenceType(); + if(referenceType != null) { + Field daemon = referenceType.fieldByName("daemon"); + if(daemon != null) { + Value value = threadReference.getValue(daemon); + if(value instanceof BooleanValue && ((BooleanValue)value).booleanValue()) { + buffer.append(" daemon"); + } + } + + Field priority = referenceType.fieldByName("priority"); + if(priority != null) { + Value value = threadReference.getValue(priority); + if(value instanceof IntegerValue) { + buffer.append(" prio=" + ((IntegerValue)value).intValue()); + } + } + } + + ThreadGroupReference groupReference = threadReference.threadGroup(); + if (groupReference != null) { + buffer.append(", in group \""); + buffer.append(groupReference.name()); + buffer.append("\""); + } + buffer.append(", status: "); + buffer.append(DebuggerUtilsEx.getThreadStatusText(threadReference.status())); + + try { + if(vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) { + List list = threadReference.ownedMonitors(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ObjectReference reference = (ObjectReference)iterator.next(); + List waiting = reference.waitingThreads(); + for (Iterator iterator1 = waiting.iterator(); iterator1.hasNext();) { + ThreadReference thread = (ThreadReference)iterator1.next(); + buffer.append("\n\t blocks " + threadName(thread)); + } + } + } + + ObjectReference waitedMonitor = vmProxy.canGetCurrentContendedMonitor() ? threadReference.currentContendedMonitor() : null; + if(waitedMonitor != null) { + if(vmProxy.canGetMonitorInfo()) { + ThreadReference waitedThread = waitedMonitor.owningThread(); + if (waitedThread != null) { + buffer.append("\n\t waiting for " + threadName(waitedThread)); + } + } + } + + List frames = threadReference.frames(); + for (Iterator frit = frames.iterator(); frit.hasNext();) { + StackFrame stackFrame = (StackFrame)frit.next(); + Location location = stackFrame.location(); + Method method = location.method(); + buffer.append("\n\t "); + buffer.append(method.name()); + buffer.append("():"); + buffer.append(Integer.toString(location.lineNumber())); + try { + String sourceName = location.sourceName(); + buffer.append(", "); + buffer.append(sourceName); + } + catch (AbsentInformationException e) { + } + catch (InternalError e) { + } + } + } + catch (IncompatibleThreadStateException e) { + buffer.append("\n\t Incompatible thread state"); + } + buffer.append("\n\n"); + } + return buffer.toString(); + } + + private String threadName(ThreadReference threadReference) { + return threadReference.name() + "@" + Long.toHexString(threadReference.uniqueID()); + } + + private class CopyToClipboardAction extends AbstractAction { + public CopyToClipboardAction() { + super("Copy"); + putValue(Action.SHORT_DESCRIPTION,"&Copy text to clipboard"); + } + + public void actionPerformed(ActionEvent e) { + String s = StringUtil.convertLineSeparators(myTextArea.getText(), "\n"); + CopyPasteManager.getInstance().setContents(new StringSelection(s)); + } + } + + private class ExportThreadsCommand extends DebuggerCommandImpl { + protected ModalityState myModalityState; + + public ExportThreadsCommand(ModalityState modalityState) { + myModalityState = modalityState; + } + + private void setText(final String text) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + myTextArea.setText(text); + setOKActionEnabled(true); + myCopyToClipboardAction.setEnabled(true); + } + }, myModalityState); + } + + protected void action() { + setText(getExportThreadsText(myDebugProcess.getVirtualMachineProxy())); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExpressionEvaluationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExpressionEvaluationDialog.java new file mode 100644 index 00000000000..68f75d459ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ExpressionEvaluationDialog.java @@ -0,0 +1,108 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.actions.EvaluateAction; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +public class ExpressionEvaluationDialog extends EvaluationDialog { + private JPanel myPanel; + private JPanel myExpressionComboPlace; + private JPanel myWatchViewPlace; + + private final SwitchAction mySwitchAction = new SwitchAction(); + + public ExpressionEvaluationDialog(Project project, TextWithImportsImpl defaultExpression) { + super(project, makeOnLine(defaultExpression)); + setTitle("Expression Evaluation"); + + myWatchViewPlace.setLayout(new BorderLayout()); + myWatchViewPlace.add(getEvaluationPanel()); + myExpressionComboPlace.setLayout(new BorderLayout()); + myExpressionComboPlace.add(getExpressionCombo()); + + KeyStroke expressionStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.ALT_MASK); + KeyStroke resultStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.ALT_MASK); + + + new AnAction() { + public void actionPerformed(AnActionEvent e) { + getExpressionCombo().requestFocus(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(expressionStroke), getRootPane()); + + new AnAction() { + public void actionPerformed(AnActionEvent e) { + getEvaluationPanel().getWatchTree().requestFocus(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(resultStroke), getRootPane()); + + this.init(); + } + + protected DebuggerExpressionComboBox createEditor() { + return new DebuggerExpressionComboBox(getProject(), PositionUtil.getContextElement(getDebuggerContext()), "evaluation"); + } + + protected JComponent createCenterPanel() { + return myPanel; + } + + private static TextWithImportsImpl makeOnLine(TextWithImportsImpl text) { + String initialExpression = text.getText(); + if (initialExpression != null) { + int size = initialExpression.length(); + StringBuffer buf = new StringBuffer(size); + for (int idx = 0; idx < size; idx++) { + char ch = initialExpression.charAt(idx); + if (ch != '\n' && ch != '\r') { + buf.append(ch); + } + } + text = text.createText(initialExpression); + } + return text; + } + + protected void initDialogData(TextWithImportsImpl text) { + super.initDialogData(text); + getExpressionCombo().selectAll(); + } + + private DebuggerExpressionComboBox getExpressionCombo() { + return (DebuggerExpressionComboBox)getEditor(); + } + + protected Action[] createActions() { + return new Action[] { getOKAction(), getCancelAction(), mySwitchAction} ; + } + + private class SwitchAction extends AbstractAction { + public SwitchAction() { + putValue(Action.NAME, "Code Fragment Mode"); + } + + public void actionPerformed(ActionEvent e) { + final TextWithImportsImpl text = (TextWithImportsImpl)getEditor().getText(); + doCancelAction(); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + EvaluateAction.showEvaluationDialog(getProject(), text, DebuggerSettings.EVALUATE_FRAGMENT); + } + }); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/GetJPDADialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/GetJPDADialog.java new file mode 100644 index 00000000000..40a698ed405 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/GetJPDADialog.java @@ -0,0 +1,60 @@ +/* + * @author: Eugene Zhuravlev + * Date: Oct 16, 2002 + * Time: 5:31:46 PM + */ +package com.intellij.debugger.ui; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class GetJPDADialog extends DialogWrapper { + private static final String JPDA_URL = "http://java.sun.com/products/jpda"; + + public GetJPDADialog() { + super(false); + setTitle("JPDA Libraries Missing"); + setResizable(false); + init(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction()}; + } + + protected JComponent createCenterPanel() { + final JPanel _panel1 = new JPanel(new BorderLayout()); + + JPanel _panel2 = new JPanel(new BorderLayout()); + _panel2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + //"Debug libraries are missig from JDK home.\nIn order for debugger to start, the libraries should be installed.\nPlease visit http://java.sun.com/products/jpda" + JLabel label1 = new JLabel("To get JPDA libraries please visit "); + //label1.setForeground(Color.black); + JLabel label2 = new JLabel(JPDA_URL); + label2.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + BrowserUtil.launchBrowser(JPDA_URL); + } + + } + ); + label2.setForeground(Color.blue.darker()); + label2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + _panel2.add(new JLabel("Cannot start debugger: debug libraries are missig from JDK home"), BorderLayout.NORTH); + _panel2.add(label1, BorderLayout.WEST); + _panel2.add(label2, BorderLayout.EAST); + _panel1.add(_panel2, BorderLayout.NORTH); + + JPanel content = new JPanel(new GridLayout(2, 1, 10, 10)); + + _panel1.add(content, BorderLayout.CENTER); + return _panel1; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapProgressImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapProgressImpl.java new file mode 100644 index 00000000000..ec8d8fd083c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapProgressImpl.java @@ -0,0 +1,95 @@ +package com.intellij.debugger.ui; + +import com.intellij.Patches; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.HotSwapProgress; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.progress.util.SmoothProgressAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.util.IJSwingUtilities; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class HotSwapProgressImpl extends HotSwapProgress{ + private HotSwapView myHotSwapView; + private final ProgressIndicator myProgressIndicator; + private final ProgressWindow myProgressWindow; + + private DebuggerSession myDebuggerSession; + + public HotSwapProgressImpl(Project project) { + super(project); + myProgressWindow = new ProgressWindow(true, getProject()) { + public void cancel() { + HotSwapProgressImpl.this.cancel(); + super.cancel(); + if (isRunning()) { + stop(); + } + } + }; + myProgressIndicator = Patches.MAC_HIDE_QUIT_HACK ? myProgressWindow : (ProgressIndicator)new SmoothProgressAdapter(myProgressWindow, project); + } + + public void addMessage(final int type, final String[] text, final VirtualFile file, final int line, final int column) { + IJSwingUtilities.invoke(new Runnable() { + public void run() { + if(myHotSwapView == null) { + myHotSwapView = HotSwapView.findView(myDebuggerSession); + } + myHotSwapView.addMessage(type, text, file, line, column, null); + } + }); + } + + public void setText(final String text) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myProgressIndicator.setText(text); + } + }, myProgressIndicator.getModalityState()); + + } + + public void setTitle(final String text) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myProgressWindow.setTitle(text); + } + }, myProgressWindow.getModalityState()); + + } + + public void setFraction(final double v) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myProgressIndicator.setFraction(v); + } + }, myProgressIndicator.getModalityState()); + } + + public boolean isCancelled() { + return myProgressIndicator.isCanceled(); + } + + public ProgressIndicator getProgressIndicator() { + return myProgressIndicator; + } + + public void setDebuggerSession(DebuggerSession session) { + final DebuggerSession oldSession = myDebuggerSession; + myDebuggerSession = session; + myProgressWindow.setTitle("Hot Swap : " + myDebuggerSession.getSessionName()); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myHotSwapView = null; + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapUI.java new file mode 100644 index 00000000000..1258f678660 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/HotSwapUI.java @@ -0,0 +1,180 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerManagerListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.HotSwapFile; +import com.intellij.debugger.impl.HotSwapManager; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilationStatusListener; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Oct 2, 2003 + * Time: 6:00:55 PM + */ +public class HotSwapUI implements ProjectComponent{ + private boolean myAskBeforeHotswap = true; + private final Project myProject; + private final CompilationStatusListener myListener = new CompilationStatusListener() { + public void compilationFinished(boolean aborted, int errors, int warnings) { + if (errors == 0 && !aborted) { + final List sessions = new ArrayList(); + Collection debuggerSessions = (DebuggerManagerEx.getInstanceEx(myProject)).getSessions(); + for (Iterator iterator = debuggerSessions.iterator(); iterator.hasNext();) { + DebuggerSession debuggerSession = (DebuggerSession)iterator.next(); + if(debuggerSession.isAttached()) { + sessions.add(debuggerSession); + } + } + if (sessions.size() > 0) { + hotSwapSessions(sessions); + } + } + } + }; + + public HotSwapUI(final Project project, CompilerManager compilerManager, DebuggerManagerEx debuggerManager) { + myProject = project; + compilerManager.addCompilationStatusListener(myListener); + debuggerManager.addDebuggerManagerListener(new DebuggerManagerListener() { + public void sessionCreated(DebuggerSession session) { + } + + public void sessionRemoved(DebuggerSession session) { + HotSwapView.removeView(session); + } + }); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "HotSwapUI"; + } + + public void initComponent() { + } + + public void disposeComponent() { + + } + + private void hotSwapSessions(final List sessions) { + final boolean askBeforeHotswap = myAskBeforeHotswap; + myAskBeforeHotswap = true; + + new Thread() { + public void run() { + final HashMap> modifiedClasses = getModifiedClasses(sessions); + + if(modifiedClasses.isEmpty()) return; + + final HashMap> classesToReload = new HashMap>(); + if(askBeforeHotswap) { + String runHotswap = DebuggerSettings.getInstance().RUN_HOTSWAP_AFTER_COMPILE; + + if(DebuggerSettings.RUN_HOTSWAP_ALWAYS.equals(runHotswap)) { + classesToReload.putAll(modifiedClasses); + } + else if (DebuggerSettings.RUN_HOTSWAP_NEVER.equals(runHotswap)) { + + } + else { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + RunHotswapDialog dialog = new RunHotswapDialog(myProject, sessions); + dialog.show(); + + if(dialog.isOK()) { + for (Iterator iterator = dialog.getSessionsToReload().iterator(); iterator.hasNext();) { + DebuggerSession debuggerSession = iterator.next(); + classesToReload.put(debuggerSession, modifiedClasses.get(debuggerSession)); + } + } + } + }, ApplicationManager.getApplication().getDefaultModalityState()); + } + } + else { + classesToReload.putAll(modifiedClasses); + } + + reloadModifiedClasses(classesToReload); + + } + }.start(); + } + + private void reloadModifiedClasses(final HashMap> modifiedClasses) { + final HotSwapProgressImpl[] reloadClassesProgress = new HotSwapProgressImpl[1]; + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + reloadClassesProgress[0] = new HotSwapProgressImpl(myProject); + } + }, ApplicationManager.getApplication().getDefaultModalityState()); + + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + HotSwapManager.reloadModifiedClasses(modifiedClasses, reloadClassesProgress[0]); + } + }, reloadClassesProgress[0].getProgressIndicator()); + } + + private HashMap> getModifiedClasses(final List sessions) { + final HashMap[] classes = new HashMap[1]; + + final HotSwapProgressImpl[] swapProgress = new HotSwapProgressImpl[1]; + + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + swapProgress[0] = new HotSwapProgressImpl(myProject); + } + }, ApplicationManager.getApplication().getDefaultModalityState()); + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + classes[0] = HotSwapManager.getModifiedClasses(sessions, swapProgress[0]); + } + }, swapProgress[0].getProgressIndicator()); + + return classes[0]; + + } + + public void reloadChangedClasses(final DebuggerSession session, boolean compileBeforeHotswap) { + dontAskHotswapAfterThisCompilation(); + if (compileBeforeHotswap) { + CompilerManager.getInstance(session.getProject()).make(null); + } + else { + if(session.isAttached()) { + final List sessions = new ArrayList(); + sessions.add(session); + hotSwapSessions(sessions); + } + } + } + + public void dontAskHotswapAfterThisCompilation() { + myAskBeforeHotswap = false; + } + + public static HotSwapUI getInstance(Project project) { + return project.getComponent(HotSwapUI.class); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/InstanceFilterEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/InstanceFilterEditor.java new file mode 100644 index 00000000000..218a9763e1d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/InstanceFilterEditor.java @@ -0,0 +1,44 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; + +/** + * User: lex + * Date: Aug 29, 2003 + * Time: 2:38:30 PM + */ +public class InstanceFilterEditor extends ClassFilterEditor { + public InstanceFilterEditor(Project project) { + super(project); + myAddPatternButton.setVisible(false); + } + + protected void addClassFilter() { + String idString = Messages.showInputDialog(myProject, "Enter instance ID:", "Add Instance Filter", Messages.getQuestionIcon()); + if (idString != null) { + ClassFilter filter = createFilter(idString); + if(filter != null){ + myTableModel.addRow(filter); + int row = myTableModel.getRowCount() - 1; + myTable.getSelectionModel().setSelectionInterval(row, row); + myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true)); + + } + myTable.requestFocus(); + } + } + + protected ClassFilter createFilter(String pattern) { + try { + Long.parseLong(pattern); + return super.createFilter(pattern); + } catch (NumberFormatException e) { + Messages.showMessageDialog(this, "Instance ID should be a numeric value of long type.", "Invalid Number Format", Messages.getErrorIcon()); + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/PositionHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/PositionHighlighter.java new file mode 100644 index 00000000000..89fe772f892 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/PositionHighlighter.java @@ -0,0 +1,354 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.actions.ViewBreakpointsAction; +import com.intellij.debugger.engine.DebugProcessEvents; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.*; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.settings.DebuggerColors; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter; +import com.intellij.debugger.ui.breakpoints.LineBreakpoint; +import com.intellij.debugger.ui.breakpoints.MethodBreakpoint; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.markup.GutterIconRenderer; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.sun.jdi.event.Event; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jul 9, 2003 + * Time: 6:24:35 PM + * To change this template use Options | File Templates. + */ +public class PositionHighlighter { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.PositionHighlighter"); + private final Project myProject; + private DebuggerContextImpl myContext = DebuggerContextImpl.EMPTY_CONTEXT; + private SelectionDescription mySelectionDescription = null; + private ExecutionPointDescription myExecutionPointDescription = null; + + public PositionHighlighter(Project project, DebuggerStateManager stateManager) { + myProject = project; + + stateManager.addListener(new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + myContext = newContext; + refresh(); + } + }); + } + + private void showLocationInEditor() { + myContext.getDebugProcess().getManagerThread().invokeLater(new ShowLocationCommand(myContext)); + } + + private void refresh() { + clearSelections(); + final DebuggerSession session = myContext.getDebuggerSession(); + if(session != null) { + switch(session.getState()) { + case DebuggerSession.STATE_PAUSED: + if(myContext.getFrameProxy() != null) { + showLocationInEditor(); + return; + } + break; + } + } + } + + protected static class ExecutionPointDescription extends SelectionDescription { + private RangeHighlighter myHighlighter; + private final int myLineIndex; + + protected ExecutionPointDescription(Editor editor, int lineIndex) { + super(editor); + myLineIndex = lineIndex; + } + + public void select() { + if(myIsActive) return; + myIsActive = true; + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + myHighlighter = myEditor.getMarkupModel().addLineHighlighter( + myLineIndex, + HighlighterLayer.SELECTION - 1, + scheme.getAttributes(DebuggerColors.EXECUTIONPOINT_ATTRIBUTES) + ); + } + + public void remove() { + if(!myIsActive) return; + myIsActive = false; + myEditor.getMarkupModel().removeHighlighter(myHighlighter); + myHighlighter = null; + } + + public RangeHighlighter getHighlighter() { + return myHighlighter; + } + } + + protected abstract static class SelectionDescription { + protected Editor myEditor; + protected boolean myIsActive; + + public SelectionDescription(Editor editor) { + myEditor = editor; + } + + public abstract void select(); + public abstract void remove(); + + public static ExecutionPointDescription createExecutionPoint(final Editor editor, + final int lineIndex) { + return new ExecutionPointDescription(editor, lineIndex); + } + + public static SelectionDescription createSelection(final Editor editor, final int lineIndex) { + return new SelectionDescription(editor) { + public void select() { + if(myIsActive) return; + myIsActive = true; + DocumentEx doc = (DocumentEx)editor.getDocument(); + editor.getSelectionModel().setSelection( + doc.getLineStartOffset(lineIndex), + doc.getLineEndOffset(lineIndex) + doc.getLineSeparatorLength(lineIndex) + ); + } + + public void remove() { + if(!myIsActive) return; + myIsActive = false; + myEditor.getSelectionModel().removeSelection(); + } + }; + } + } + + private void showSelection(final PsiFile psiFile, int lineIndex) { + if(lineIndex < 0) lineIndex = 0; + Editor editor = getEditor(psiFile, lineIndex); + if(editor == null) return; + if (mySelectionDescription != null) { + mySelectionDescription.remove(); + } + mySelectionDescription = SelectionDescription.createSelection(editor, lineIndex); + mySelectionDescription.select(); + } + + private void showExecutionPoint(final PsiFile psiFile, int lineIndex, List> events) { + if(lineIndex < 0) lineIndex = 0; + Editor editor = getEditor(psiFile, lineIndex); + if(editor == null) return; + if (myExecutionPointDescription != null) { + myExecutionPointDescription.remove(); + } + myExecutionPointDescription = SelectionDescription.createExecutionPoint(editor, lineIndex); + myExecutionPointDescription.select(); + + RangeHighlighter highlighter = myExecutionPointDescription.getHighlighter(); + + if(highlighter != null) { + final List> eventsOutOfLine = new ArrayList>(); + + for (Iterator> iterator = events.iterator(); iterator.hasNext();) { + Pair eventDescriptor = iterator.next(); + Breakpoint breakpoint = eventDescriptor.getFirst(); + if(breakpoint instanceof BreakpointWithHighlighter) { + breakpoint.reload(); + SourcePosition sourcePosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition(); + if(sourcePosition == null || sourcePosition.getLine() != lineIndex) { + eventsOutOfLine.add(eventDescriptor); + } + } else { + eventsOutOfLine.add(eventDescriptor); + } + } + + if(eventsOutOfLine.size() > 0) { + highlighter.setGutterIconRenderer(new GutterIconRenderer() { + public Icon getIcon() { + return eventsOutOfLine.get(0).getFirst().getIcon(); + } + + public String getTooltipText() { + DebugProcessImpl debugProcess = DebuggerManagerEx.getInstanceEx(myProject).getContext().getDebugProcess(); + if(debugProcess != null) { + StringBuffer buf = new StringBuffer(); + buf.append(""); + for (Iterator> iterator = eventsOutOfLine.iterator(); iterator.hasNext();) { + Pair eventDescriptor = iterator.next(); + buf.append(DebugProcessEvents.getEventText(eventDescriptor)); + if(iterator.hasNext()) { + buf.append("
    "); + } + } + buf.append(""); + return buf.toString(); + } else { + return null; + } + } + + public ActionGroup getPopupMenuActions() { + DefaultActionGroup group = new DefaultActionGroup(); + for (Iterator> iterator = eventsOutOfLine.iterator(); iterator.hasNext();) { + Pair eventDescriptor = iterator.next(); + Breakpoint breakpoint = eventDescriptor.getFirst(); + ViewBreakpointsAction viewBreakpointsAction = new ViewBreakpointsAction(breakpoint.getDisplayName()); + viewBreakpointsAction.setInitialBreakpoint(breakpoint); + group.add(viewBreakpointsAction); + } + + return group; + } + }); + } + } + } + + public Editor getEditor() { + SourcePosition position = myContext.getSourcePosition(); + if (position == null) { + return null; + } + + int lineIndex = position.getLine(); + return getEditor(position.getFile(), (lineIndex > 0? lineIndex : 0)); + } + + private Editor getEditor(final PsiFile psiFile, final int lineIndex) { + Document doc = PsiDocumentManager.getInstance(myProject).getDocument(psiFile); + if (!psiFile.isValid()) { + return null; + } + LOG.assertTrue(lineIndex >= 0 && lineIndex <= doc.getLineCount()); + FileEditorManager editorManager = FileEditorManager.getInstance(myProject); + Editor editor = editorManager.openTextEditor(new OpenFileDescriptor(myProject, psiFile.getVirtualFile(), lineIndex, 0), false); + return editor; + } + + private void clearSelections() { + if (mySelectionDescription != null || myExecutionPointDescription != null) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (mySelectionDescription != null) { + mySelectionDescription.remove(); + mySelectionDescription = null; + } + if (myExecutionPointDescription != null) { + myExecutionPointDescription.remove(); + myExecutionPointDescription = null; + } + } + }); + } + } + + + public void updateContextPointDescription() { + if(myContext.getDebuggerSession() == null) return; + + showLocationInEditor(); + } + + private class ShowLocationCommand extends DebuggerContextCommandImpl { + private final DebuggerContextImpl myContext; + + public ShowLocationCommand(DebuggerContextImpl context) { + super(context); + myContext = context; + } + + public void threadAction() { + SourcePosition position = myContext.getSourcePosition(); + if (position == null) { + return; + } + + boolean isExecutionPoint = false; + + try { + StackFrameProxyImpl frameProxy = myContext.getFrameProxy(); + isExecutionPoint = frameProxy.equals(getSuspendContext().getThread().frame(0)); + } catch(Throwable th) { + LOG.debug(th); + } + + final List> events = DebuggerUtilsEx.getEventDescriptors(getSuspendContext()); + + Document document = PsiDocumentManager.getInstance(myProject).getDocument(position.getFile()); + if(document != null) { + if(position.getLine() < 0 || position.getLine() >= document.getLineCount()) { + position = SourcePosition.createFromLine(position.getFile(), 0); + } + } + + final SourcePosition position1 = position; + if(isExecutionPoint) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + SourcePosition position2 = updatePositionFromBreakpoint(events, position1); + showExecutionPoint( + position2.getFile(), + position2.getLine(), + events); + } + }); + } else { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + showSelection( + position1.getFile(), + position1.getLine()); + } + }); + } + } + + private SourcePosition updatePositionFromBreakpoint(final List> events, SourcePosition position) { + for (Iterator> iterator = events.iterator(); iterator.hasNext();) { + Pair eventDescriptor = iterator.next(); + Breakpoint breakpoint = eventDescriptor.getFirst(); + if(breakpoint instanceof LineBreakpoint || breakpoint instanceof MethodBreakpoint) { + breakpoint.reload(); + + + SourcePosition breakPosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition(); + if(breakPosition != null && breakPosition.getLine() != position.getLine()) { + position = SourcePosition.createFromLine(position.getFile(), breakPosition.getLine()); + } + } + } + return position; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/RunHotswapDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/RunHotswapDialog.java new file mode 100644 index 00000000000..84f06cbcae5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/RunHotswapDialog.java @@ -0,0 +1,161 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ui.OptionsDialog; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.util.*; + +/** + * User: lex + * Date: Oct 6, 2003 + * Time: 5:58:17 PM + */ + + + +public class RunHotswapDialog extends OptionsDialog { + private final java.util.Set mySessionsToReload; + private final java.util.List mySessions; + private JPanel myPanel; + private JTable mySessionsTable; + + public RunHotswapDialog(Project project, java.util.List sessions) { + super(project); + if(sessions.size() == 1) { + setTitle("Reload Changed Classes for " + sessions.get(0).getSessionName()); + myPanel.setVisible(false); + } + else { + setTitle("Reload Changed Classes"); + } + setButtonsAlignment(SwingUtilities.CENTER); + mySessionsToReload = new HashSet(sessions); + mySessions = new ArrayList(sessions.size()); + mySessions.addAll(sessions); + Collections.sort(mySessions, new Comparator() { + public int compare(DebuggerSession debuggerSession, DebuggerSession debuggerSession1) { + return debuggerSession.getSessionName().compareTo(debuggerSession1.getSessionName()); + } + }); + + mySessionsTable.setModel(new AbstractTableModel() { + private static final int CHECKBOX_COLUMN = 0; + private static final int SESSION_COLUMN = 1; + + public String getColumnName(int column) { + return column == SESSION_COLUMN ? "Session" : ""; + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECKBOX_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public int getColumnCount() { + return 2; + } + + public int getRowCount() { + return mySessions.size(); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + if(columnIndex == CHECKBOX_COLUMN) { + return new Boolean(mySessionsToReload.contains(mySessions.get(rowIndex))); + } + else { + return mySessions.get(rowIndex).getSessionName(); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return rowIndex == CHECKBOX_COLUMN; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if(rowIndex == CHECKBOX_COLUMN) { + if(Boolean.TRUE.equals(aValue)) { + mySessionsToReload.add(mySessions.get(columnIndex)); + } + else { + mySessionsToReload.remove(mySessions.get(columnIndex)); + } + } + } + }); + + final TableColumn checkboxColumn = mySessionsTable.getTableHeader().getColumnModel().getColumn(0); + int width = new JCheckBox().getMinimumSize().width; + checkboxColumn.setWidth(width); + checkboxColumn.setPreferredWidth(width); + checkboxColumn.setMaxWidth(width); + this.init(); + } + + protected boolean isToBeShown() { + return DebuggerSettings.RUN_HOTSWAP_ASK.equals(DebuggerSettings.getInstance().RUN_HOTSWAP_AFTER_COMPILE); + } + + protected void setToBeShown(boolean value, boolean onOk) { + if (value) { + DebuggerSettings.getInstance().RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_ASK; + } + else { + if (onOk) { + DebuggerSettings.getInstance().RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_ALWAYS; + } + else { + DebuggerSettings.getInstance().RUN_HOTSWAP_AFTER_COMPILE = DebuggerSettings.RUN_HOTSWAP_NEVER; + } + } + } + + protected boolean shouldSaveOptionsOnCancel() { + return true; + } + + protected Action[] createActions(){ + setOKButtonText("Yes"); + setCancelButtonText("No"); + + return new Action[]{getOKAction(), getCancelAction()}; + } + + protected JComponent createNorthPanel() { + JLabel label = new JLabel("Some classes have been changed. Reload changed classes now?"); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(label, BorderLayout.CENTER); + Icon icon = UIManager.getIcon("OptionPane.questionIcon"); + if (icon != null) { + label.setIcon(icon); + label.setIconTextGap(7); + } + return panel; + } + + protected JComponent createCenterPanel() { + return myPanel; + } + + public Collection getSessionsToReload() { + ArrayList result = new ArrayList(); + + for (Iterator iterator = mySessions.iterator(); iterator.hasNext();) { + DebuggerSession debuggerSession = iterator.next(); + if(mySessionsToReload.contains(debuggerSession)) { + result.add(debuggerSession); + } + } + + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/StatementEvaluationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/StatementEvaluationDialog.java new file mode 100644 index 00000000000..090a9342aa2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/StatementEvaluationDialog.java @@ -0,0 +1,137 @@ +package com.intellij.debugger.ui; + +import com.intellij.debugger.actions.EvaluateAction; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.ui.GuiUtils; +import com.intellij.debugger.DebuggerInvocationUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 4:28:52 PM + * To change this template use File | Settings | File Templates. + */ +public class StatementEvaluationDialog extends EvaluationDialog{ + private JPanel myWatchViewPlace; + private JPanel myStatementEditorPlace; + private JPanel myPanel; + private final Action mySwitchAction = new SwitchAction(); + + public StatementEvaluationDialog(final Project project, TextWithImportsImpl text) { + super(project, text); + setTitle("Code Fragment Evaluation"); + myWatchViewPlace.setLayout(new BorderLayout()); + myWatchViewPlace.add(getEvaluationPanel()); + myStatementEditorPlace.setLayout(new BorderLayout()); + myStatementEditorPlace.add(getStatementEditor()); + + GuiUtils.replaceJSplitPaneWithIDEASplitter(myPanel); + + setDebuggerContext(getDebuggerContext()); + + KeyStroke codeFragment = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.ALT_MASK); + KeyStroke resultStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.ALT_MASK); + KeyStroke altEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK); + + new AnAction() { + public void actionPerformed(AnActionEvent e) { + getStatementEditor().requestFocus(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(codeFragment), getRootPane()); + + new AnAction() { + public void actionPerformed(AnActionEvent e) { + getEvaluationPanel().getWatchTree().requestFocus(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(resultStroke), getRootPane()); + + new AnAction() { + public void actionPerformed(AnActionEvent e) { + doOKAction(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(altEnter), getRootPane()); + + getEditor().addDocumentListener(new DocumentAdapter() { + public void documentChanged(final DocumentEvent e) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + updateSwitchButton(e.getDocument()); + } + }); + } + }); + + this.init(); + } + + private void updateSwitchButton(Document document) { + PsiDocumentManager.getInstance(getProject()).commitDocument(document); + PsiFile psiFile = PsiDocumentManager.getInstance(getProject()).getPsiFile(document); + PsiElement[] children = ((PsiCodeFragment)psiFile).getChildren(); + int nonWhite = 0; + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + if(!(child instanceof PsiWhiteSpace)) { + nonWhite++; + if(nonWhite > 1) { + mySwitchAction.setEnabled(false); + return; + } + } + } + + mySwitchAction.setEnabled(true); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(), getCancelAction(), mySwitchAction }; + } + + protected DebuggerEditorImpl createEditor() { + return new DebuggerStatementEditor(getProject(), PositionUtil.getContextElement(getDebuggerContext()), "evaluation"); + } + + protected JComponent createCenterPanel() { + return myPanel; + } + + private DebuggerStatementEditor getStatementEditor() { + return (DebuggerStatementEditor)getEditor(); + } + + private class SwitchAction extends AbstractAction { + public SwitchAction() { + putValue(Action.NAME, "Expression Mode"); + } + + public void actionPerformed(ActionEvent e) { + final TextWithImportsImpl text = (TextWithImportsImpl)getEditor().getText(); + doCancelAction(); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + EvaluateAction.showEvaluationDialog(getProject(), text, DebuggerSettings.EVALUATE_EXPRESSION); + } + }); + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueHint.java new file mode 100644 index 00000000000..9e34915d680 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueHint.java @@ -0,0 +1,322 @@ +package com.intellij.debugger.ui; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.ui.impl.DebuggerTreeRenderer; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.SimpleColoredText; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Value; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * User: lex + * Date: Nov 24, 2003 + * Time: 7:31:26 PM + */ +public class ValueHint { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.ValueHint"); + public final static int MOUSE_OVER_HINT = 0; + public final static int MOUSE_ALT_OVER_HINT = 1; + public final static int MOUSE_CLICK_HINT = 2; + + private static final int HINT_TIMEOUT = 7000; // ms + + private static TextAttributes ourReferenceAttributes; + static { + ourReferenceAttributes = new TextAttributes(); + ourReferenceAttributes.setForegroundColor(Color.blue); + ourReferenceAttributes.setEffectColor(Color.blue); + ourReferenceAttributes.setEffectType(EffectType.LINE_UNDERSCORE); + } + + private final Project myProject; + private final Editor myEditor; + private final Point myPoint; + + private LightweightHint myCurrentHint = null; + private TextRange myCurrentRange = null; + private RangeHighlighter myHighlighter = null; + private Cursor myStoredCursor = null; + private PsiExpression myCurrentExpression = null; + + private int myType; + + private boolean myShowHint = true; + + private KeyListener myEditorKeyListener = new KeyListener() { + public void keyTyped(KeyEvent e) { + } + + public void keyPressed(KeyEvent e) { + } + + public void keyReleased(KeyEvent e) { + if(!ValueLookupManager.isAltMask(e.getModifiers())) { + ValueLookupManager.getInstance(myProject).hideHint(); + } + } + }; + + public ValueHint(Project project, Editor editor, Point point, int type) { + myProject = project; + myEditor = editor; + myPoint = point; + myType = type; + myCurrentExpression = getSelectedExpression(); + } + + public void hideHint() { + myShowHint = false; + myCurrentRange = null; + if(myStoredCursor != null) { + Component internalComponent = myEditor.getContentComponent(); + internalComponent.setCursor(myStoredCursor); + if (LOG.isDebugEnabled()) { + LOG.debug("internalComponent.setCursor(myStoredCursor)"); + } + internalComponent.removeKeyListener(myEditorKeyListener); + } + + if(myCurrentHint != null) { + myCurrentHint.hide(); + myCurrentHint = null; + } + if(myHighlighter != null) { + myEditor.getMarkupModel().removeHighlighter(myHighlighter); + myHighlighter = null; + } + } + + public void invokeHint() { + if(myCurrentExpression == null) { + hideHint(); + return; + } + + if(myType == MOUSE_ALT_OVER_HINT){ + myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(myCurrentRange.getStartOffset(), myCurrentRange.getEndOffset(), HighlighterLayer.SELECTION + 1, ourReferenceAttributes, HighlighterTargetArea.EXACT_RANGE); + Component internalComponent = myEditor.getContentComponent(); + myStoredCursor = internalComponent.getCursor(); + internalComponent.addKeyListener(myEditorKeyListener); + internalComponent.setCursor(hintCursor()); + if (LOG.isDebugEnabled()) { + LOG.debug("internalComponent.setCursor(hintCursor())"); + } + } else { + evaluateHint(); + } + } + + private void evaluateHint() { + final DebuggerContextImpl debuggerContext = DebuggerManagerEx.getInstanceEx(myProject).getContext(); + + final DebuggerSession debuggerSession = debuggerContext.getDebuggerSession(); + if(debuggerSession == null || !debuggerSession.isPaused()) return; + + try { + final ExpressionEvaluator evaluator = EvaluatorBuilderImpl.getInstance().build(myCurrentExpression); + + debuggerContext.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(debuggerContext) { + public void threadAction() { + try { + final EvaluationContextImpl evaluationContext = debuggerContext.createEvaluationContext(); + final Value value = evaluator.evaluate(evaluationContext); + + TextWithImportsImpl text = TextWithImportsImpl.createExpressionText(myCurrentExpression.getText()); + final WatchItemDescriptor descriptor = new WatchItemDescriptor(myProject, text, value, false); + descriptor.setContext(evaluationContext); + descriptor.updateRepresentation(evaluationContext, new DescriptorLabelListener() { + public void labelChanged() { + if(myCurrentRange != null) { + if(myType != MOUSE_OVER_HINT || descriptor.isValueValid()) { + showHint(DebuggerTreeRenderer.getDescriptorText(descriptor, true)); + } + } + } + }); + } + catch (EvaluateException e) { + LOG.debug(e); + } + } + }, DebuggerManagerThreadImpl.HIGH_PRIORITY); + } + catch (EvaluateException e) { + LOG.debug(e); + } + } + + private void showHint(final SimpleColoredText text) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + if(myShowHint) { + JComponent label = HintUtil.createInformationLabel(text); + myCurrentHint = new LightweightHint(label); + HintManager hintManager = HintManager.getInstance(); + + //Editor may be disposed before later invokator process this action + if(myEditor.getComponent() == null || myEditor.getComponent().getRootPane() == null) return; + + Point p = hintManager.getHintPosition(myCurrentHint, myEditor, myEditor.xyToLogicalPosition(myPoint), HintManager.UNDER); + hintManager.showEditorHint( + myCurrentHint, + myEditor, + p, + HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, + HINT_TIMEOUT, + false); + if(myType == MOUSE_CLICK_HINT) { + label.requestFocusInWindow(); + } + } + } + }); + } + + // call inside ReadAction only + private boolean canProcess(PsiExpression expression) { + if (expression instanceof PsiReferenceExpression) { + PsiExpression qualifier = ((PsiReferenceExpression)expression).getQualifierExpression(); + return (qualifier == null)? true : canProcess(qualifier); + } + return !(expression instanceof PsiMethodCallExpression); + } + + private PsiExpression findExpression(PsiElement element) { + if (!(element instanceof PsiIdentifier || element instanceof PsiKeyword)) { + return null; + } + + PsiElement expression = null; + PsiElement parent = element.getParent(); + if (parent instanceof PsiVariable) { + expression = element; + } + else if (parent instanceof PsiReferenceExpression && canProcess((PsiExpression)parent)) { + expression = parent; + } + if (parent instanceof PsiThisExpression) { + expression = parent; + } + try { + if (expression != null) { + PsiElement context = element; + if(parent instanceof PsiParameter) { + try { + context = ((PsiMethod)((PsiParameter)parent).getDeclarationScope()).getBody(); + } + catch (Throwable e) {} + } else { + while(context != null && !(context instanceof PsiStatement) && !(context instanceof PsiClass)) { + context = context.getParent(); + } + } + myCurrentRange = expression.getTextRange(); + return expression.getManager().getElementFactory().createExpressionFromText(expression.getText(), context); + } + } catch (IncorrectOperationException e) { + LOG.debug(e); + } + return null; + } + + private PsiExpression getSelectedExpression() { + final PsiExpression[] selectedExpression = new PsiExpression[] { null }; + + PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() { + public void run() { + // Point -> offset + final int offset = calcOffset(myEditor, myPoint); + + + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument()); + + if(psiFile == null) return; + + int selectionStart = myEditor.getSelectionModel().getSelectionStart(); + int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); + + if(isRequestSelection() && (selectionStart <= offset && offset <= selectionEnd)) { + PsiElement ctx = (selectionStart > 0) ? psiFile.findElementAt(selectionStart - 1) : psiFile.findElementAt(selectionStart); + try { + String text = myEditor.getSelectionModel().getSelectedText(); + if(text != null && ctx != null) { + selectedExpression[0] = PsiManager.getInstance(myProject).getElementFactory().createExpressionFromText(text, ctx); + myCurrentRange = new TextRange(myEditor.getSelectionModel().getSelectionStart(), myEditor.getSelectionModel().getSelectionEnd()); + } + } catch (IncorrectOperationException e) { + } + } + + if(myCurrentRange == null) { + PsiElement elementAtCursor = psiFile.findElementAt(offset); + if (elementAtCursor == null) return; + PsiExpression expression; + expression = findExpression(elementAtCursor); + if (expression == null) return; + selectedExpression[0] = expression; + } + } + }); + return selectedExpression[0]; + } + + private boolean isRequestSelection() { + return (myType == MOUSE_CLICK_HINT || myType == MOUSE_ALT_OVER_HINT); + } + + public boolean isKeepHint(Editor editor, Point point) { + if(myType == ValueHint.MOUSE_ALT_OVER_HINT) { + return false; + } + else if(myType == ValueHint.MOUSE_CLICK_HINT) { + if(myCurrentHint != null && myCurrentHint.isVisible()) { + return true; + } + } + else { + int offset = calcOffset(editor, point); + + if (myCurrentRange != null && myCurrentRange.getStartOffset() <= offset && offset <= myCurrentRange.getEndOffset()) { + return true; + } + } + return false; + } + + private static int calcOffset(Editor editor, Point point) { + LogicalPosition pos = editor.xyToLogicalPosition(point); + return editor.logicalPositionToOffset(pos); + } + + private static Cursor hintCursor() { + return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueLookupManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueLookupManager.java new file mode 100644 index 00000000000..d31b6fe4d5c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/ValueLookupManager.java @@ -0,0 +1,134 @@ +/* + * Class ValueLookupManager + * @author Jeka + */ +package com.intellij.debugger.ui; + +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.editor.event.EditorMouseListener; +import com.intellij.openapi.editor.event.EditorMouseMotionListener; +import com.intellij.openapi.project.Project; +import com.intellij.util.Alarm; + +import java.awt.*; +import java.awt.event.MouseEvent; + +public class ValueLookupManager implements EditorMouseMotionListener, EditorMouseListener, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.ValueLookupManager"); + + private Project myProject; + private Alarm myAlarm = new Alarm(); + private ValueHint myRequest = null; + + public ValueLookupManager(Project project) { + myProject = project; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectOpened() { + EditorFactory.getInstance().getEventMulticaster().addEditorMouseMotionListener(this); + EditorFactory.getInstance().getEventMulticaster().addEditorMouseListener(this); + } + + public void projectClosed() { + EditorFactory.getInstance().getEventMulticaster().removeEditorMouseMotionListener(this); + EditorFactory.getInstance().getEventMulticaster().removeEditorMouseListener(this); + myAlarm.cancelAllRequests(); + } + + static boolean isAltMask(int modifiers) { + return modifiers == java.awt.event.InputEvent.ALT_MASK; + } + + public void mouseDragged(EditorMouseEvent e) { + } + + public void mouseMoved(EditorMouseEvent e) { + if (e.isConsumed()) { + return; + } + Editor editor = e.getEditor(); + Point point = e.getMouseEvent().getPoint(); + requestHint(editor, point, isAltMask(e.getMouseEvent().getModifiers()) ? ValueHint.MOUSE_ALT_OVER_HINT : ValueHint.MOUSE_OVER_HINT); + } + + public void requestHint(final Editor editor, final Point point, final int type) { + if (myRequest != null) { + if(myRequest.isKeepHint(editor, point)) return; + hideHint(); + } + + DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(myProject).getContext().getDebuggerSession(); + if(debuggerSession == null || !debuggerSession.isPaused()) return; + + myAlarm.cancelAllRequests(); + if(type == ValueHint.MOUSE_OVER_HINT) { + myAlarm.addRequest(new Runnable() { + public void run() { + showHint(editor, point, type); + } + }, DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY); + } else { + showHint(editor, point, type); + } + + } + + public void hideHint() { + if(myRequest != null) { + myRequest.hideHint(); + myRequest = null; + } + } + public void showHint(Editor editor, Point point, int type) { + myAlarm.cancelAllRequests(); + hideHint(); + if(editor.isDisposed()) return; + DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(myProject).getContext().getDebuggerSession(); + if(debuggerSession == null || !debuggerSession.isAttached()) return; + myRequest = new ValueHint(myProject, editor, point, type); + myRequest.invokeHint(); + } + + public void mouseReleased(EditorMouseEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + public void mouseClicked(EditorMouseEvent e) { + if(isAltMask(e.getMouseEvent().getModifiers() & ~(java.awt.event.InputEvent.BUTTON1_MASK)) && (e.getMouseEvent().getButton() == MouseEvent.BUTTON1)){ + showHint(e.getEditor(), e.getMouseEvent().getPoint(), ValueHint.MOUSE_CLICK_HINT); + } + } + + public void mouseExited(EditorMouseEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + public void mouseEntered(EditorMouseEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + public void mousePressed(EditorMouseEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + + public static ValueLookupManager getInstance(Project project) { + return project.getComponent(ValueLookupManager.class); + } + + public String getComponentName() { + return "ValueLookupManager"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseListener.java new file mode 100644 index 00000000000..70d63a774d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseListener.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.ui; + +import com.intellij.util.WeakListener; + +import javax.swing.*; +import java.awt.event.MouseListener; + +/** + * @author Eugene Zhuravlev + * Date: Dec 25, 2004 + */ +public class WeakMouseListener extends WeakListener { + public WeakMouseListener(JComponent source, MouseListener listenerImpl) { + super(source, MouseListener.class, listenerImpl); + } + public void addListener(JComponent source, MouseListener listener) { + source.addMouseListener(listener); + } + public void removeListener(JComponent source, MouseListener listener) { + source.removeMouseListener(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseMotionListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseMotionListener.java new file mode 100644 index 00000000000..a70416813e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/WeakMouseMotionListener.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.debugger.ui; + +import com.intellij.util.WeakListener; + +import javax.swing.*; +import java.awt.event.MouseMotionListener; + +/** + * @author Eugene Zhuravlev + * Date: Dec 25, 2004 + */ +public class WeakMouseMotionListener extends WeakListener { + public WeakMouseMotionListener(JComponent source, MouseMotionListener listenerImpl) { + super(source, MouseMotionListener.class, listenerImpl); + } + public void addListener(JComponent source, MouseMotionListener listener) { + source.addMouseMotionListener(listener); + } + public void removeListener(JComponent source, MouseMotionListener listener) { + source.removeMouseMotionListener(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java new file mode 100644 index 00000000000..2ceb8f781e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java @@ -0,0 +1,121 @@ +/* + * @author: Eugene Zhuravlev + * Date: Sep 11, 2002 + * Time: 5:23:47 PM + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.ide.util.MemberChooser; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +abstract class AddFieldBreakpointDialog extends DialogWrapper { + private final Project myProject; + private JPanel myPanel; + private TextFieldWithBrowseButton myFieldChooser; + private TextFieldWithBrowseButton myClassChooser; + + public AddFieldBreakpointDialog(Project project) { + super(project, true); + myProject = project; + setTitle("Add Field Watchpoint"); + init(); + } + + protected JComponent createCenterPanel() { + myClassChooser.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + updateUI(); + } + }); + + myClassChooser.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PsiClass currentClass = getSelectedClass(); + TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Field's class", myProject, GlobalSearchScope.allScope(myProject), null, null); + if (currentClass != null) { + PsiFile containingFile = currentClass.getContainingFile(); + if (containingFile != null) { + PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + if (containingDirectory != null) { + chooser.selectDirectory(containingDirectory); + } + } + } + chooser.show(); + PsiClass selectedClass = chooser.getSelectedClass(); + if (selectedClass != null) { + myClassChooser.setText(selectedClass.getQualifiedName()); + } + } + }); + + myFieldChooser.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PsiClass selectedClass = getSelectedClass(); + if (selectedClass != null) { + PsiField[] fields = selectedClass.getFields(); + MemberChooser chooser = new MemberChooser(fields, false, false, myProject); + chooser.setTitle(fields.length > 0 ? "Select Field" : "Class has no fields"); + chooser.setCopyJavadocVisible(false); + chooser.show(); + Object[] selectedElements = chooser.getSelectedElements(); + if (selectedElements != null && selectedElements.length == 1) { + PsiField field = (PsiField)selectedElements[0]; + myFieldChooser.setText(field.getName()); + } + } + } + }); + myFieldChooser.setEnabled(false); + return myPanel; + } + + private void updateUI() { + PsiClass selectedClass = getSelectedClass(); + myFieldChooser.setEnabled(selectedClass != null); + } + + private PsiClass getSelectedClass() { + final PsiManager psiManager = PsiManager.getInstance(myProject); + String classQName = myClassChooser.getText(); + if ("".equals(classQName)) { + return null; + } + return psiManager.findClass(classQName, GlobalSearchScope.allScope(myProject)); + } + + public JComponent getPreferredFocusedComponent() { + return myClassChooser.getTextField(); + } + + public String getClassName() { + return myClassChooser.getText(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.breakpoints.BreakpointsConfigurationDialogFactory.BreakpointsConfigurationDialog.AddFieldBreakpointDialog"; + } + + public String getFieldName() { + return myFieldChooser.getText(); + } + + protected abstract boolean validateData(); + + protected void doOKAction() { + if(validateData()) { + super.doOKAction(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java new file mode 100644 index 00000000000..2af5bbc6463 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java @@ -0,0 +1,44 @@ +/* + * Class AnyExceptionBreakpoint + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.sun.jdi.ReferenceType; +import org.jdom.Element; + +public class AnyExceptionBreakpoint extends ExceptionBreakpoint { + protected AnyExceptionBreakpoint(Project project) { + super(project, null); + ENABLED = false; + } + + public String getDisplayName() { + return "Any exception"; + } + + public void createRequest(DebugProcessImpl debuggerProcess) { + if (!ENABLED || !debuggerProcess.isAttached() || !debuggerProcess.getRequestsManager().findRequests(this).isEmpty()) { + return; + } + super.processClassPrepare(debuggerProcess, null); + } + + public void processClassPrepare(DebugProcess debugProcess, ReferenceType refType) { + // should be emty - does not make sence for this breakpoint + } + + public void readExternal(Element parentNode) throws InvalidDataException { + try { + super.readExternal(parentNode); + } + catch (InvalidDataException e) { + if(!READ_NO_CLASS_NAME.equals(e.getMessage())) throw e; + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/Breakpoint.java new file mode 100644 index 00000000000..7f9df91bdd4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -0,0 +1,265 @@ +/* + * Class Breakpoint + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.requests.ClassPrepareRequestor; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizerUtil; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerManagerEx; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.event.LocatableEvent; +import org.jdom.Element; + +import javax.swing.*; +import java.util.Iterator; +import java.util.List; + +public abstract class Breakpoint extends FilteredRequestor implements ClassPrepareRequestor { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.Breakpoint"); + protected final Project myProject; + + public boolean ENABLED = true; + + public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + public boolean LOG_ENABLED = false; + public boolean LOG_EXPRESSION_ENABLED = false; + private TextWithImportsImpl myLogMessage = TextWithImportsImpl.EMPTY; // an expression to be evaluated and printed + + protected Breakpoint(Project project) { + myProject = project; + } + + public Project getProject() { + return myProject; + } + + public abstract PsiClass getPsiClass(); + /** + * Request for creating all needed JPDA requests in the specified VM + * @param debuggerProcess the requesting process + */ + public abstract void createRequest(DebugProcessImpl debuggerProcess); + + /** + * Request for creating all needed JPDA requests in the specified VM + * @param debuggerProcess the requesting process + */ + public abstract void processClassPrepare(DebugProcess debuggerProcess, final ReferenceType referenceType); + + public abstract String getDisplayName (); + + public abstract Icon getIcon (); + + public abstract void reload(); + + /** + * Associates breakpoint with class. + * Create requests for loaded class and registers callback for loading classes + * @param debugProcess the requesting process + */ + protected void createOrWaitPrepare(DebugProcessImpl debugProcess, String classToBeLoaded) { + debugProcess.getRequestsManager().callbackOnPrepareClasses(this, classToBeLoaded); + + List list = debugProcess.getVirtualMachineProxy().classesByName(classToBeLoaded); + for (Iterator it = list.iterator(); it.hasNext();) { + ReferenceType refType = (ReferenceType)it.next(); + if (refType.isPrepared()) { + processClassPrepare(debugProcess, refType); + } + } + } + + protected void createOrWaitPrepare(final DebugProcessImpl debugProcess, final SourcePosition classPosition) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + debugProcess.getRequestsManager().callbackOnPrepareClasses(Breakpoint.this, classPosition); + + List list = debugProcess.getPositionManager().getAllClasses(classPosition); + for (Iterator it = list.iterator(); it.hasNext();) { + ReferenceType refType = (ReferenceType)it.next(); + if (refType.isPrepared()) { + processClassPrepare(debugProcess, refType); + } + } + } + }); + } + + /** + * returns UI representation + */ + public abstract String getEventMessage(LocatableEvent event); + + public abstract boolean isValid(); + + protected ObjectReference getThisObject(SuspendContextImpl context, LocatableEvent event) throws EvaluateException { + ThreadReferenceProxyImpl thread = context.getThread(); + if(thread != null) { + StackFrameProxyImpl stackFrameProxy = thread.frame(0); + if(stackFrameProxy != null) { + return stackFrameProxy.thisObject(); + } + } + return null; + } + + // returns whether should resume + public boolean processLocatableEvent(final SuspendContextCommandImpl action, final LocatableEvent event) { + final SuspendContextImpl context = action.getSuspendContext(); + if(!isValid()) { + context.getDebugProcess().getRequestsManager().deleteRequest(this); + return true; + } + + final String[] errorMsg = new String[] {"Breakpoint Condition Error" }; + + try { + StackFrameProxyImpl frameProxy = context.getThread().frame(0); + + EvaluationContextImpl evaluationContext = new EvaluationContextImpl(action.getSuspendContext(), frameProxy, + Breakpoint.this.getThisObject(context, event)); + + if(!evaluateCondition(evaluationContext, event)) return true; + + errorMsg[0] = "Breakpoint Action Error"; + runAction(evaluationContext, event); + } + catch (final EvaluateException ex) { + if(ApplicationManager.getApplication().isUnitTestMode()) { + System.out.println(ex.getMessage()); + return true; + } + + final boolean[] shouldResume = new boolean[]{true}; + DebuggerInvocationUtil.invokeAndWait(getProject(), new Runnable() { + public void run() { + DebuggerSession session = DebuggerManagerEx.getInstanceEx(getProject()).getSession(context.getDebugProcess()); + DebuggerPanelsManager.getInstance(myProject).toFront(session); + final StringBuffer text = new StringBuffer(128); + text.append("'Breakpoint '"); + text.append(getDisplayName()); + text.append("'\n"); + text.append(ex.getMessage()); + text.append("\nWould you like to stop at the breakpoint?"); + if (LOG.isDebugEnabled()) { + LOG.debug(text.toString()); + } + shouldResume[0] = Messages.showYesNoDialog( + myProject, + text.toString(), + errorMsg[0], + Messages.getQuestionIcon() + ) != 0; + } + }, ModalityState.NON_MMODAL); + + return shouldResume[0]; + } finally{ + + } + + if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { + return true; + } + + return false; + } + + private void runAction(final EvaluationContextImpl context, LocatableEvent event) { + if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) { + final StringBuffer buf = new StringBuffer(128); + if (LOG_ENABLED) { + buf.append(getEventMessage(event)); + buf.append("\n"); + } + if (LOG_EXPRESSION_ENABLED && getLogMessage() != null && !"".equals(getLogMessage())) { + if(!context.getDebugProcess().isAttached()) return; + + String result; + try { + ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new com.intellij.debugger.EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl.getInstance().build(getLogMessage(), ContextUtil.getContextElement(context)); + } + }); + result = DebuggerUtilsEx.getValueAsString(context, evaluator.evaluate(context)); + buf.append(getLogMessage()); + buf.append(" = "); + buf.append(result); + } catch (EvaluateException e) { + buf.append("unable to evaluate the expression \""); + buf.append(getLogMessage()); + buf.append("\""); + buf.append(" : "); + buf.append(e.getMessage()); + } + buf.append("\n"); + } + if (buf.length() > 0) { + context.getDebugProcess().printToConsole(buf.toString()); + } + } + } + + public void updateUI() { + updateUI(EmptyRunnable.getInstance()); + } + + public void updateUI(Runnable afterUpdate) { + } + + public void delete() { + RequestManagerImpl.deleteRequests(this); + } + + public void readExternal(Element parentNode) throws InvalidDataException { + super.readExternal(parentNode); + String logMessage = JDOMExternalizerUtil.readField(parentNode, "myLogMessage"); + if (logMessage != null) { + setLogMessage(TextWithImportsImpl.createExpressionText(logMessage)); + } + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + super.writeExternal(parentNode); + JDOMExternalizerUtil.writeField(parentNode, "myLogMessage", getLogMessage().saveToString()); + } + + public TextWithImportsImpl getLogMessage() { + return myLogMessage; + } + + public void setLogMessage(TextWithImportsImpl logMessage) { + myLogMessage = logMessage; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManager.java new file mode 100644 index 00000000000..f0fc2912274 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -0,0 +1,772 @@ +/* + * Class BreakpointManager + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.actions.ViewBreakpointsAction; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.*; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiField; +import com.intellij.util.Alarm; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.HashMap; +import com.sun.jdi.Field; +import com.sun.jdi.ObjectReference; +import gnu.trove.TIntHashSet; +import org.jdom.Element; + +import javax.swing.*; +import java.awt.event.MouseEvent; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +public class BreakpointManager implements JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.BreakpointManager"); + + public static final String LINE_BREAKPOINTS = "line_breakpoints"; + public static final String EXCEPTION_BREAKPOINTS = "exception_breakpoints"; + public static final String FIELD_BREAKPOINTS = "field_breakpoints"; + public static final String METHOD_BREAKPOINTS = "method_breakpoints"; + public static final String ANY_EXCEPTION_BREAKPOINT = "breakpoint_any"; + private final Project myProject; + private AnyExceptionBreakpoint myAnyExceptionBreakpoint; + private List myBreakpoints = new ArrayList(); // breakpoints storage, access should be synchronized + private List myBreakpointsListForIteration = null; // another list for breakpoints iteration, unsynchronized access ok + private Map> myDocumentBreakpoints = new HashMap>(); + + private BreakpointsConfigurationDialogFactory myBreakpointsConfigurable; + private EditorMouseListener myEditorMouseListener; + + private final EventDispatcher myDispatcher = EventDispatcher.create(BreakpointManagerListener.class); + + private StartupManager myStartupManager; + + private final DocumentListener myDocumentListener = new DocumentAdapter() { + Alarm myUpdateAlarm = new Alarm(); + + public void documentChanged(final DocumentEvent e) { + final Document document = e.getDocument(); + synchronized (BreakpointManager.this) { + List breakpoints = myDocumentBreakpoints.get(document); + + if(breakpoints != null) { + myUpdateAlarm.cancelAllRequests(); + // must create new array in order to avoid "concurrent modification" errors + final List breakpointsToUpdate = new ArrayList(breakpoints); + myUpdateAlarm.addRequest(new Runnable() { + public void run() { + if(!myProject.isDisposed()) { + PsiDocumentManager.getInstance(myProject).commitDocument(document); + update(breakpointsToUpdate); + } + } + }, 300); + } + } + } + }; + + private void update(List breakpoints) { + final TIntHashSet intHash = new TIntHashSet(); + + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + BreakpointWithHighlighter breakpoint = iterator.next(); + SourcePosition sourcePosition = breakpoint.getSourcePosition(); + breakpoint.reload(); + + if(breakpoint.isValid()) { + if(breakpoint.getSourcePosition().getLine() != sourcePosition.getLine()) { + breakpointChanged(breakpoint); + } + + if(intHash.contains(breakpoint.getLineIndex())) { + remove(breakpoint); + } + else { + intHash.add(breakpoint.getLineIndex()); + } + } + else { + remove(breakpoint); + } + } + } + + /* + // todo: not needed?? + private void setInvalid(final BreakpointWithHighlighter breakpoint) { + Collection sessions = DebuggerManagerEx.getInstanceEx(myProject).getSessions(); + + for (Iterator iterator = sessions.iterator(); iterator.hasNext();) { + DebuggerSession session = iterator.next(); + final DebugProcessImpl process = session.getProcess(); + process.getManagerThread().invokeLater(new DebuggerCommandImpl() { + protected void action() throws Exception { + process.getRequestsManager().deleteRequest(breakpoint); + process.getRequestsManager().setInvalid(breakpoint, "Source code changed"); + breakpoint.updateUI(); + } + }); + } + } + */ + + private void remove(final BreakpointWithHighlighter breakpoint) { + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + removeBreakpoint(breakpoint); + } + }); + } + + public BreakpointManager(Project project, StartupManager startupManager, DebuggerManagerImpl debuggerManager) { + myProject = project; + myStartupManager = startupManager; + myAnyExceptionBreakpoint = new AnyExceptionBreakpoint(project); + debuggerManager.getContextManager().addListener(new DebuggerContextListener() { + private DebuggerSession myPreviousSession; + + public void changeEvent(DebuggerContextImpl newContext, int event) { + if (newContext.getDebuggerSession() != myPreviousSession || event == DebuggerSession.EVENT_DETACHED) { + updateBreakpointsUI(); + myPreviousSession = newContext.getDebuggerSession(); + } + } + }); + } + + public void init() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + myEditorMouseListener = new EditorMouseAdapter() { + private EditorMouseEvent myMousePressedEvent; + + private Breakpoint toggleBreakpoint(final boolean mostSuitingBreakpoint, int line) { + Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); + Document document = editor.getDocument(); + PsiDocumentManager.getInstance(myProject).commitDocument(document); + + int offset = editor.getCaretModel().getOffset(); + int editorLine = editor.getDocument().getLineNumber(offset); + if(editorLine != line) { + offset = editor.getDocument().getLineStartOffset(line); + } + + Breakpoint breakpoint = findBreakpoint(document, offset); + if (breakpoint == null) { + if(mostSuitingBreakpoint) { + breakpoint = addFieldBreakpoint(document, offset); + if (breakpoint == null) { + breakpoint = addMethodBreakpoint(document, line); + } + if (breakpoint == null) { + breakpoint = addLineBreakpoint(document, line); + } + } + else { + breakpoint = addLineBreakpoint(document, line); + + if (breakpoint == null) { + breakpoint = addMethodBreakpoint(document, line); + } + } + + if(breakpoint != null) { + RequestManagerImpl.createRequests(breakpoint); + } + return breakpoint; + } + else { + removeBreakpoint(breakpoint); + return null; + } + } + + private boolean isFromMyProject(Editor editor) { + FileEditor[] allEditors = FileEditorManager.getInstance(myProject).getAllEditors(); + for (int idx = 0; idx < allEditors.length; idx++) { + FileEditor ed = allEditors[idx]; + if (!(ed instanceof TextEditor)) { + continue; + } + if (((TextEditor)ed).getEditor().equals(editor)) { + return true; + } + } + return false; + } + + //mousePressed + mouseReleased is a hack to keep selection in editor when shift is pressed + public void mousePressed(EditorMouseEvent e) { + if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return; + + if (e.isConsumed()) return; + + if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA && e.getMouseEvent().isShiftDown()) { + myMousePressedEvent = e; + e.consume(); + } + } + + public void mouseReleased(EditorMouseEvent e) { + if(myMousePressedEvent != null) { + mouseClicked(e); + } + myMousePressedEvent = null; + } + + public void mouseClicked(final EditorMouseEvent e) { + if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return; + + if (e.isConsumed()) return; + + if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { + PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() { + public void run() { + final Editor editor = e.getEditor(); + if (!isFromMyProject(editor)) { + return; + } + final int line = editor.xyToLogicalPosition(e.getMouseEvent().getPoint()).line; + if (line < 0) { + return; + } + MouseEvent event = e.getMouseEvent(); + if (event.isPopupTrigger()) { + return; + } + if (event.getButton() != 1) { + return; + } + + e.consume(); + + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + Breakpoint breakpoint = toggleBreakpoint(e.getMouseEvent().isAltDown(), line); + + if(e.getMouseEvent().isShiftDown() && breakpoint != null) { + breakpoint.LOG_EXPRESSION_ENABLED = true; + breakpoint.setLogMessage(DebuggerUtilsEx.getEditorText(editor)); + breakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_NONE; + + DialogWrapper dialog = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().createConfigurationDialog(breakpoint, BreakpointPropertiesPanel.CONTROL_LOG_MESSAGE); + dialog.show(); + + if(!dialog.isOK()) { + removeBreakpoint(breakpoint); + } + } + } + }); + } + }); + } + } + }; + + eventMulticaster.addEditorMouseListener(myEditorMouseListener); + eventMulticaster.addDocumentListener(myDocumentListener); + } + + public void dispose() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + eventMulticaster.removeEditorMouseListener(myEditorMouseListener); + eventMulticaster.removeDocumentListener(myDocumentListener); + } + + public DialogWrapper createConfigurationDialog(Breakpoint initialBreakpoint, String selectComponent) { + if (myBreakpointsConfigurable == null) { + myBreakpointsConfigurable = new BreakpointsConfigurationDialogFactory(myProject); + } + DialogWrapper dialog = myBreakpointsConfigurable.createDialog(initialBreakpoint, selectComponent); + return dialog; + } + + public LineBreakpoint addRunToCursorBreakpoint(Document document, int lineIndex) { + return LineBreakpoint.create(myProject, document, lineIndex, false); + } + + public LineBreakpoint addLineBreakpoint(Document document, int lineIndex) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + if (!LineBreakpoint.canAddLineBreakpoint(myProject, document, lineIndex)) return null; + + LineBreakpoint breakpoint = LineBreakpoint.create(myProject, document, lineIndex, true); + if (breakpoint == null) { + return null; + } + + addBreakpoint(breakpoint); + return breakpoint; + } + + public FieldBreakpoint addFieldBreakpoint(Field field, ObjectReference object) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, field, object); + if (fieldBreakpoint != null) { + addBreakpoint(fieldBreakpoint); + } + return fieldBreakpoint; + } + + public FieldBreakpoint addFieldBreakpoint(Document document, int offset) { + PsiField field = FieldBreakpoint.findField(myProject, document, offset); + if (field == null) return null; + + int line = document.getLineNumber(offset); + + if (document.getLineNumber(field.getNameIdentifier().getTextOffset()) < line) return null; + + return addFieldBreakpoint(document, line, field.getName()); + } + + public FieldBreakpoint addFieldBreakpoint(Document document, int lineIndex, String fieldName) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, document, lineIndex, fieldName); + if (fieldBreakpoint != null) { + addBreakpoint(fieldBreakpoint); + } + return fieldBreakpoint; + } + + public ExceptionBreakpoint addExceptionBreakpoint(String exceptionClassName) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(exceptionClassName != null); + ExceptionBreakpoint breakpoint = new ExceptionBreakpoint(myProject, exceptionClassName); + addBreakpoint(breakpoint); + if (LOG.isDebugEnabled()) { + LOG.debug("ExceptionBreakpoint Added"); + } + return breakpoint; + } + + public MethodBreakpoint addMethodBreakpoint(Document document, int lineIndex) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + MethodBreakpoint breakpoint = MethodBreakpoint.create(myProject, document, lineIndex); + if (breakpoint == null) { + return null; + } + addBreakpoint(breakpoint); + return breakpoint; + } + + /** + * @return null if not found or a breakpoint object + */ + public List findBreakpoints(final Document document, final int offset) { + LinkedList result = new LinkedList(); + + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + for (Iterator iterator = getBreakpoints().iterator(); iterator.hasNext();) { + Breakpoint breakpoint = (Breakpoint)iterator.next(); + if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) { + result.add((BreakpointWithHighlighter)breakpoint); + } + } + + return result; + } + + public BreakpointWithHighlighter findBreakpoint(final Document document, final int offset) { + List breakpoints = findBreakpoints(document, offset); + return breakpoints.isEmpty() ? null : breakpoints.get(0); + } + + public LineBreakpoint findLineBreakpoint(final Document document, final int offset) { + List breakpoints = findBreakpoints(document, offset); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + BreakpointWithHighlighter breakpointWithHighlighter = iterator.next(); + if(breakpointWithHighlighter instanceof LineBreakpoint) return (LineBreakpoint)breakpointWithHighlighter; + } + return null; + } + + public MethodBreakpoint findMethodBreakpoint(final Document document, final int offset) { + List breakpoints = findBreakpoints(document, offset); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + BreakpointWithHighlighter breakpointWithHighlighter = iterator.next(); + if(breakpointWithHighlighter instanceof MethodBreakpoint) return (MethodBreakpoint)breakpointWithHighlighter; + } + return null; + } + + public FieldBreakpoint findFieldBreakpoint(final Document document, final int offset) { + List breakpoints = findBreakpoints(document, offset); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + BreakpointWithHighlighter breakpointWithHighlighter = iterator.next(); + if(breakpointWithHighlighter instanceof FieldBreakpoint) return (FieldBreakpoint)breakpointWithHighlighter; + } + return null; + } + + public void readExternal(final Element parentNode) throws InvalidDataException { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + + myStartupManager.registerPostStartupActivity(new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() { + public void run() { + try { + readBreakpoints(parentNode, LINE_BREAKPOINTS); + readBreakpoints(parentNode, EXCEPTION_BREAKPOINTS); + final Element exceptionBreakpointsNode = parentNode.getChild(EXCEPTION_BREAKPOINTS); + if(exceptionBreakpointsNode != null) { + final Element anyExceptionBreakpoint = exceptionBreakpointsNode.getChild(ANY_EXCEPTION_BREAKPOINT); + if (anyExceptionBreakpoint != null) { + myAnyExceptionBreakpoint.readExternal(anyExceptionBreakpoint); + } + } + readBreakpoints(parentNode, FIELD_BREAKPOINTS); + readBreakpoints(parentNode, METHOD_BREAKPOINTS); + } + catch (InvalidDataException e) { + } + + DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + public void run() { + updateBreakpointsUI(); + } + }); + } + }); + } + }); + + } + + private void readBreakpoints(Element parentNode, String breakpointCategory) throws InvalidDataException { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + try { + final Element breakpointsNode = parentNode.getChild(breakpointCategory); + + Class breakpointClass = getBreakpointClass(breakpointCategory); + Constructor constructor = breakpointClass.getDeclaredConstructor(new Class[] {Project.class}); + + constructor.setAccessible(true); + + if (breakpointsNode != null) { + for (Iterator i = breakpointsNode.getChildren("breakpoint").iterator(); i.hasNext();) { + Element breakpointNode = (Element)i.next(); + Breakpoint breakpoint = (Breakpoint)constructor.newInstance(new Object[] {myProject }); + breakpoint.readExternal(breakpointNode); + addBreakpoint(breakpoint); + } + } + } + catch (NoSuchMethodException e) { + LOG.error(e); + } + catch (InstantiationException e) { + LOG.error(e); + } + catch (IllegalAccessException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + } + + private synchronized void addBreakpoint(Breakpoint breakpoint) { + myBreakpoints.add(breakpoint); + myBreakpointsListForIteration = null; + if(breakpoint instanceof BreakpointWithHighlighter) { + BreakpointWithHighlighter breakpointWithHighlighter = ((BreakpointWithHighlighter) breakpoint); + Document document = breakpointWithHighlighter.getDocument(); + if(document != null) { + List breakpoints = myDocumentBreakpoints.get(document); + + if(breakpoints == null) { + breakpoints = new ArrayList(); + myDocumentBreakpoints.put(document, breakpoints); + } + breakpoints.add(breakpointWithHighlighter); + } + } + myDispatcher.getMulticaster().breakpointsChanged(); + } + + public synchronized void removeBreakpoint(final Breakpoint breakpoint) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + if (breakpoint == null) { + return; + } + + if (myBreakpoints.remove(breakpoint)) { + myBreakpointsListForIteration = null; + if(breakpoint instanceof BreakpointWithHighlighter) { + //breakpoint.saveToString() may be invalid + + for (Iterator iterator = myDocumentBreakpoints.keySet().iterator(); iterator.hasNext();) { + final Document document = iterator.next(); + final List documentBreakpoints = myDocumentBreakpoints.get(document); + final boolean reallyRemoved = documentBreakpoints.remove(breakpoint); + if (reallyRemoved) { + if (documentBreakpoints.isEmpty()) { + myDocumentBreakpoints.remove(document); + } + break; + } + } + } + //we delete breakpoints inside release, so gutter will not fire events to deleted breakpoints + breakpoint.delete(); + + myDispatcher.getMulticaster().breakpointsChanged(); + } + } + + public void writeExternal(final Element parentNode) throws WriteExternalException { + final WriteExternalException[] exception = new WriteExternalException[1]; + + PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() { + public void run() { + try { + removeInvalidBreakpoints(); + + writeBreakpointCategory(parentNode, LINE_BREAKPOINTS); + + Element group = writeBreakpointCategory(parentNode, EXCEPTION_BREAKPOINTS); + + Element anyBreakpointNode = new Element("breakpoint_any"); + group.addContent(anyBreakpointNode); + myAnyExceptionBreakpoint.writeExternal(anyBreakpointNode); + + writeBreakpointCategory(parentNode, FIELD_BREAKPOINTS); + writeBreakpointCategory(parentNode, METHOD_BREAKPOINTS); + } + catch (WriteExternalException e) { + exception[0] = e; + } + } + }); + if (exception[0] != null) throw exception[0]; + } + + private Element writeBreakpointCategory(final Element parentNode, String breakpointCategory) throws WriteExternalException { + Element group = new Element(breakpointCategory); + parentNode.addContent(group); + Breakpoint[] breakpoints = getBreakpoints(breakpointCategory); + for (int i = 0; i < breakpoints.length; i++) { + Breakpoint breakpoint = breakpoints[i]; + + if(breakpoint.isValid()) { + Element breakpointNode = new Element("breakpoint"); + group.addContent(breakpointNode); + breakpoint.writeExternal(breakpointNode); + } + } + return group; + } + + private void removeInvalidBreakpoints() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + ArrayList toDelete = new ArrayList(); + + for (Iterator it = getBreakpoints().listIterator(); it.hasNext();) { + Breakpoint breakpoint = (Breakpoint)it.next(); + if (!breakpoint.isValid()) { + toDelete.add(breakpoint); + } + } + + for (Iterator iterator = toDelete.iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + removeBreakpoint(breakpoint); + } + } + + /** + * @return breakpoints of one of the category: + * LINE_BREAKPOINTS, EXCEPTION_BREKPOINTS, FIELD_BREAKPOINTS, METHOD_BREAKPOINTS + */ + public Breakpoint[] getBreakpoints(String category) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + removeInvalidBreakpoints(); + + Class breakpointClass = getBreakpointClass(category); + + ArrayList breakpoints = new ArrayList(); + + if (breakpointClass != null) { + for (Iterator iterator = getBreakpoints().iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + if(breakpointClass.isAssignableFrom(breakpoint.getClass())) { + breakpoints.add(breakpoint); + } + } + } + + return breakpoints.toArray(new Breakpoint[breakpoints.size()]); + } + + private Class getBreakpointClass(String category) { + if (LINE_BREAKPOINTS.equals(category)) { + return LineBreakpoint.class; + } + if (EXCEPTION_BREAKPOINTS.equals(category)) { + return ExceptionBreakpoint.class; + } + if (FIELD_BREAKPOINTS.equals(category)) { + return FieldBreakpoint.class; + } + if (METHOD_BREAKPOINTS.equals(category)) { + return MethodBreakpoint.class; + } + return null; + } + + public synchronized List getBreakpoints() { + if (myBreakpointsListForIteration == null) { + myBreakpointsListForIteration = new ArrayList(myBreakpoints); + } + return myBreakpointsListForIteration; + } + + public AnyExceptionBreakpoint getAnyExceptionBreakpoint() { + return myAnyExceptionBreakpoint; + } + + ActionGroup createMenuActions(final Breakpoint breakpoint) { + /** + * Used from Popup Menu + */ + class RemoveAction extends AnAction { + private Breakpoint myBreakpoint; + + public RemoveAction(Breakpoint breakpoint) { + super("Remove"); + myBreakpoint = breakpoint; + } + + public void actionPerformed(AnActionEvent e) { + if (myBreakpoint != null) { + removeBreakpoint(myBreakpoint); + myBreakpoint = null; + } + } + } + + /** + * Used from Popup Menu + */ + class SetEnabledAction extends AnAction { + private boolean myNewValue; + private Breakpoint myBreakpoint; + + public SetEnabledAction(Breakpoint breakpoint, boolean newValue) { + super(newValue ? "Enable" : "Disable"); + myBreakpoint = breakpoint; + myNewValue = newValue; + } + + public void actionPerformed(AnActionEvent e) { + myBreakpoint.ENABLED = myNewValue; + breakpointChanged(myBreakpoint); + myBreakpoint.updateUI(); + } + } + + ViewBreakpointsAction viewBreakpointsAction = new ViewBreakpointsAction("Properties"); + viewBreakpointsAction.setInitialBreakpoint(breakpoint); + + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new SetEnabledAction(breakpoint, !breakpoint.ENABLED)); + group.add(new RemoveAction(breakpoint)); + group.addSeparator(); + group.add(viewBreakpointsAction); + return group; + } + + //interaction with RequestManagerImpl + public void disableBreakpoints(final DebugProcessImpl debugProcess) { + List breakpoints = getBreakpoints(); + + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + debugProcess.getRequestsManager().deleteRequest(breakpoint); + } + } + + public void enableBreakpoints(final DebugProcessImpl debugProcess) { + List breakpoints = getBreakpoints(); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + debugProcess.getRequestsManager().createRequest(breakpoint); + } + } + + public void updateBreakpoints(final DebugProcessImpl debugProcess) { + List breakpoints = getBreakpoints(); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + RequestManagerImpl.updateRequests(breakpoint); + } + } + + public void updateAllRequests() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + + List breakpoints = getBreakpoints(); + for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + breakpointChanged(breakpoint); + } + } + + public void updateBreakpointsUI() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + for (Iterator iterator = getBreakpoints().iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + breakpoint.updateUI(); + } + } + + public void reloadBreakpoints() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + + for (Iterator iterator = getBreakpoints().iterator(); iterator.hasNext();) { + Breakpoint breakpoint = iterator.next(); + breakpoint.reload(); + } + } + + public void addBreakpointManagerListener(BreakpointManagerListener listener) { + myDispatcher.addListener(listener); + } + + public void removeBreakpointManagerListener(BreakpointManagerListener listener) { + myDispatcher.removeListener(listener); + } + + public void breakpointChanged(Breakpoint breakpoint) { + RequestManagerImpl.updateRequests(breakpoint); + myDispatcher.getMulticaster().breakpointsChanged(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java new file mode 100644 index 00000000000..fb792f02d56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java @@ -0,0 +1,12 @@ +package com.intellij.debugger.ui.breakpoints; + +import java.util.EventListener; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public interface BreakpointManagerListener extends EventListener{ + void breakpointsChanged (); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointNameCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointNameCellRenderer.java new file mode 100644 index 00000000000..883aaba9236 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointNameCellRenderer.java @@ -0,0 +1,38 @@ +package com.intellij.debugger.ui.breakpoints; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; + +/** + * @author Jeka + */ +public class BreakpointNameCellRenderer extends DefaultTableCellRenderer { + private Color myAnyExceptionForeground = new Color(128, 0, 0); + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + BreakpointTableModel tableModel = (BreakpointTableModel)table.getModel(); + Breakpoint breakpoint = tableModel.getBreakpoint(row); + if (breakpoint == null){ + return this; + }; + setIcon(breakpoint.getIcon()); + setDisabledIcon(breakpoint.getIcon()); + + if(isSelected){ + setForeground(UIManager.getColor("Table.selectionForeground")); + }else{ + Color foreColor; + if(breakpoint instanceof AnyExceptionBreakpoint){ + foreColor=myAnyExceptionForeground; + }else{ + foreColor=UIManager.getColor("Table.foreground"); + } + setForeground(foreColor); + } + setEnabled(breakpoint.ENABLED); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPanel.java new file mode 100644 index 00000000000..ca561905e64 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPanel.java @@ -0,0 +1,245 @@ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +/** + * @author Jeka + */ +public class BreakpointPanel { + private final BreakpointTableModel myTableModel; + private final BreakpointPropertiesPanel myPropertiesPanel; + private Breakpoint myCurrentViewableBreakpoint; + + private JPanel myPanel; + private JPanel myBreakPointsPanel; + private JPanel myTablePlace; + private JPanel myPropertiesPanelPlace; + private Table myTable; + private JButton myAddBreakpointButton; + private JButton myRemoveBreakpointButton; + private JButton myGotoSourceButton; + private JButton myViewSourceButton; + + + public BreakpointPanel(BreakpointTableModel tableModel, BreakpointPropertiesPanel propertiesPanel) { + myTableModel = tableModel; + myPropertiesPanel = propertiesPanel; + myTable = new Table(myTableModel); + myTable.setColumnSelectionAllowed(false); + InputMap inputMap = myTable.getInputMap(); + ActionMap actionMap = myTable.getActionMap(); + Object o = inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)); + if (o == null) { + o = "enable_disable"; + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), o); + } + actionMap.put(o, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] indices = myTable.getSelectedRows(); + boolean currentlyMarked = true; + for (int i = 0; i < indices.length; i++) { + final Boolean isMarked = (Boolean)myTable.getValueAt(indices[i], BreakpointTableModel.ENABLED_STATE); + currentlyMarked = isMarked != null? isMarked.booleanValue() : false; + if (!currentlyMarked) { + break; + } + } + final Boolean valueToSet = currentlyMarked ? Boolean.FALSE : Boolean.TRUE; + for (int i = 0; i < indices.length; i++) { + myTable.setValueAt(valueToSet, indices[i], BreakpointTableModel.ENABLED_STATE); + } + } + }); + + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.setTableHeader(null); + myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + myTable.setColumnSelectionAllowed(false); + JScrollPane pane = ScrollPaneFactory.createScrollPane(myTable); + int width = new JCheckBox().getPreferredSize().width; + TableColumnModel columnModel = myTable.getColumnModel(); + + TableColumn column = columnModel.getColumn(BreakpointTableModel.ENABLED_STATE); + column.setPreferredWidth(width); + column.setMaxWidth(width); + columnModel.getColumn(BreakpointTableModel.NAME).setCellRenderer(new BreakpointNameCellRenderer()); + + myTablePlace.setLayout(new BorderLayout()); + myTablePlace.add(pane, BorderLayout.CENTER); + + addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + refreshUI(); + } + }); + myTableModel.addTableModelListener(new TableModelListener() { + public void tableChanged(TableModelEvent e) { + if (e.getType() == TableModelEvent.UPDATE) { + refreshUI(); + } + } + }); + myTable.requestFocus(); + + myStubPanel = new JPanel(); + myStubPanel.setMinimumSize(myPropertiesPanel.getPanel().getMinimumSize()); + + myPropertiesPanelPlace.setLayout(new BorderLayout()); + refreshUI(); + } + + public void saveChanges() { + if (myCurrentViewableBreakpoint != null) { + myPropertiesPanel.saveTo(myCurrentViewableBreakpoint, new Runnable() { + public void run() { + myTable.repaint(); + } + }); + } + } + + public void updateButtons() { + myRemoveBreakpointButton.setEnabled(getSelectedBreakpoints().length > 0); + myGotoSourceButton.setEnabled(myCurrentViewableBreakpoint != null); + myViewSourceButton.setEnabled(myCurrentViewableBreakpoint != null); + if (!myGotoSourceButton.isEnabled() && myGotoSourceButton.hasFocus()) myGotoSourceButton.transferFocus(); + if (!myViewSourceButton.isEnabled() && myViewSourceButton.hasFocus()) myViewSourceButton.transferFocus(); + if (!myRemoveBreakpointButton.isEnabled() && myRemoveBreakpointButton.hasFocus()) myRemoveBreakpointButton.transferFocus(); + } + + public JTable getTable() { + return myTable; + } + + public JPanel getPanel() { + return myPanel; + } + + public JButton getAddBreakpointButton() { + return myAddBreakpointButton; + } + + public JButton getGotoSourceButton() { + return myGotoSourceButton; + } + + public JButton getViewSourceButton() { + return myViewSourceButton; + } + + public JButton getRemoveBreakpointButton() { + return myRemoveBreakpointButton; + } + + public void selectBreakpoint(Breakpoint breakpoint) { + int index = myTableModel.getBreakpointIndex(breakpoint); + myTable.clearSelection(); + myTable.getSelectionModel().addSelectionInterval(index, index); + myPropertiesPanel.getControl(BreakpointPropertiesPanel.CONTROL_LOG_MESSAGE); + } + + public void setBreakpoints(Breakpoint[] breakpoints) { + myTableModel.setBreakpoints(breakpoints); + if (breakpoints != null && breakpoints.length > 0) { + myTable.getSelectionModel().addSelectionInterval(0, 0); + } + } + + public Breakpoint[] getSelectedBreakpoints() { + if (myTable.getRowCount() == 0) { + return new Breakpoint[0]; + } + + int[] rows = myTable.getSelectedRows(); + if (rows.length == 0) { + return new Breakpoint[0]; + } + Breakpoint[] rv = new Breakpoint[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + rv[idx] = myTableModel.getBreakpoint(rows[idx]); + } + return rv; + } + + public void removeSelectedBreakpoints() { + TableUtil.removeSelectedItems(myTable); + myCurrentViewableBreakpoint = null; + refreshUI(); + } + + public void insertBreakpointAt(Breakpoint breakpoint, int index) { + myTableModel.insertBreakpointAt(breakpoint, index); + ListSelectionModel model = myTable.getSelectionModel(); + model.clearSelection(); + model.addSelectionInterval(index, index); + } + + public void addBreakpoint(Breakpoint breakpoint) { + myTableModel.addBreakpoint(breakpoint); + int index = myTable.getRowCount() - 1; + ListSelectionModel model = myTable.getSelectionModel(); + model.clearSelection(); + model.addSelectionInterval(index, index); + } + + public void addListSelectionListener(ListSelectionListener listener) { + myTable.getSelectionModel().addListSelectionListener(listener); + } + + public void removeListSelectionListener(ListSelectionListener listener) { + myTable.getSelectionModel().removeListSelectionListener(listener); + } + + private JPanel myStubPanel; + + private void refreshUI() { + if (myCurrentViewableBreakpoint != null) { + myPropertiesPanel.saveTo(myCurrentViewableBreakpoint, new Runnable() { + public void run() { + myTable.repaint(); + } + }); + } + Breakpoint[] breakpoints = getSelectedBreakpoints(); + Breakpoint oldBreakpoint = myCurrentViewableBreakpoint; + myCurrentViewableBreakpoint = (breakpoints != null && breakpoints.length == 1) ? breakpoints[0] : null; + if (myCurrentViewableBreakpoint != null) { + if (oldBreakpoint == null) { + myPropertiesPanelPlace.remove(myStubPanel); + myPropertiesPanelPlace.add(myPropertiesPanel.getPanel()); + myPropertiesPanelPlace.repaint(); + } + myPropertiesPanel.initFrom(myCurrentViewableBreakpoint); + } + else { + myPropertiesPanelPlace.remove(myPropertiesPanel.getPanel()); + myPropertiesPanelPlace.add(myStubPanel); + myPropertiesPanelPlace.repaint(); + } + updateButtons(); + } + + public void setBorderTitle(String titleAt) { + myBreakPointsPanel.setBorder(IdeBorderFactory.createTitledBorder(titleAt)); + } + + public JComponent getControl(String control) { + return myPropertiesPanel.getControl(control); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java new file mode 100644 index 00000000000..9d9c8f975c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -0,0 +1,460 @@ +/* + * Class BreakpointPropertiesPanel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.InstanceFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; +import com.intellij.debugger.ui.impl.UIUtil; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.ui.FieldPanel; +import com.intellij.ui.MultiLineTooltipUI; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public abstract class BreakpointPropertiesPanel { + protected final Project myProject; + private JPanel myPanel; + private DebuggerExpressionComboBox myConditionCombo; + private DebuggerExpressionComboBox myLogExpressionCombo; + private JTextField myPassCountField; + private FieldPanel myInstanceFiltersField; + + private FieldPanel myClassFiltersField; + private ClassFilter[] myClassFilters; + private ClassFilter[] myClassExclusionFilters; + private InstanceFilter[] myInstanceFilters; + + private JCheckBox myLogExpressionCheckBox; + private JCheckBox myLogMessageCheckBox; + protected JCheckBox myPassCountCheckbox; + private JCheckBox myConditionCheckbox; + private JCheckBox myInstanceFiltersCheckBox; + private JCheckBox myClassFiltersCheckBox; + + private JPanel myInstanceFiltersFieldPanel; + private JPanel myClassFiltersFieldPanel; + private JPanel myConditionComboPanel; + private JPanel myLogExpressionComboPanel; + private JPanel mySpecialBoxPanel; + private PsiClass myBreakpointPsiClass; + + private JRadioButton mySuspendThreadRadio; + private JRadioButton mySuspendNoneRadio; + private JRadioButton mySuspendAllRadio; + + ButtonGroup mySuspendPolicyGroup; + public static final String CONTROL_LOG_MESSAGE = "logMessage"; + + public JComponent getControl(String control) { + if(control == CONTROL_LOG_MESSAGE) { + return myLogExpressionCombo; + } + return null; + } + + private class MyTextField extends JTextField { + public MyTextField() { + } + + public String getToolTipText(MouseEvent event) { + reloadClassFilters(); + updateClassFilterEditor(false); + reloadInstanceFilters(); + updateInstanceFilterEditor(false); + String toolTipText = super.getToolTipText(event); + return getToolTipText().length() == 0 ? null : toolTipText; + } + + public JToolTip createToolTip() { + JToolTip toolTip = new JToolTip(){ + { + setUI(new MultiLineTooltipUI()); + } + }; + toolTip.setComponent(this); + return toolTip; + } + } + + private void insert(JPanel panel, JComponent component) { + panel.setLayout(new BorderLayout()); + panel.add(component); + } + + public BreakpointPropertiesPanel(Project project) { + myProject = project; + + mySuspendPolicyGroup = new ButtonGroup(); + mySuspendPolicyGroup.add(mySuspendAllRadio); + mySuspendPolicyGroup.add(mySuspendThreadRadio); + mySuspendPolicyGroup.add(mySuspendNoneRadio); + + myConditionCombo = new DebuggerExpressionComboBox(project, "LineBreakpoint condition"); + myLogExpressionCombo = new DebuggerExpressionComboBox(project, "LineBreakpoint logMessage"); + myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + reloadInstanceFilters(); + EditInstanceFiltersDialog _dialog = new EditInstanceFiltersDialog(myProject); + _dialog.setFilters(myInstanceFilters); + _dialog.show(); + if(_dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + myInstanceFilters = _dialog.getFilters(); + updateInstanceFilterEditor(true); + } + } + }, + null + ); + + myClassFiltersField = new FieldPanel(new MyTextField(), "", null, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + reloadClassFilters(); + + TreeClassChooserDialog.ClassFilter classFilter; + classFilter = createClassConditionFilter(); + + EditClassFiltersDialog _dialog = new EditClassFiltersDialog(myProject, classFilter); + _dialog.setFilters(myClassFilters, myClassExclusionFilters); + _dialog.show(); + if (_dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + myClassFilters = _dialog.getFilters(); + myClassExclusionFilters = _dialog.getExclusionFilters(); + updateClassFilterEditor(true); + } + } + }, + null + ); + ToolTipManager.sharedInstance().registerComponent(myClassFiltersField.getTextField()); + ToolTipManager.sharedInstance().registerComponent(myInstanceFiltersField.getTextField()); + + JComponent specialBox = createSpecialBox(); + if(specialBox != null) { + insert(mySpecialBoxPanel, specialBox); + } else { + mySpecialBoxPanel.setVisible(false); + } + + insert(myConditionComboPanel, myConditionCombo); + insert(myLogExpressionComboPanel, myLogExpressionCombo); + insert(myInstanceFiltersFieldPanel, myInstanceFiltersField); + insert(myClassFiltersFieldPanel, myClassFiltersField); + + UIUtil.enableEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo); + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateCheckboxes(); + } + }; + myPassCountCheckbox.addActionListener(listener); + myConditionCheckbox.addActionListener(listener); + myInstanceFiltersCheckBox.addActionListener(listener); + myClassFiltersCheckBox.addActionListener(listener); + UIUtil.focusEditorOnCheck(myPassCountCheckbox, myPassCountField); + UIUtil.focusEditorOnCheck(myConditionCheckbox, myConditionCombo); + UIUtil.focusEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo); + UIUtil.focusEditorOnCheck(myInstanceFiltersCheckBox, myInstanceFiltersField.getTextField()); + UIUtil.focusEditorOnCheck(myClassFiltersCheckBox, myClassFiltersField.getTextField()); + } + + protected TreeClassChooserDialog.ClassFilter createClassConditionFilter() { + TreeClassChooserDialog.ClassFilter classFilter; + if(myBreakpointPsiClass != null) { + classFilter = new TreeClassChooserDialog.ClassFilter() { + public boolean isAccepted(PsiClass aClass) { + return myBreakpointPsiClass == aClass || aClass.isInheritor(myBreakpointPsiClass, true); + } + }; + } + else { + classFilter = null; + } + return classFilter; + } + + protected JComponent createSpecialBox() { + return null; + } + + /** + * Init UI components with the values from Breakpoint + */ + public void initFrom(Breakpoint breakpoint) { + myPassCountField.setText((breakpoint.COUNT_FILTER > 0)? Integer.toString(breakpoint.COUNT_FILTER) : ""); + + PsiElement context = breakpoint.getEvaluationElement(); + myPassCountCheckbox.setSelected(breakpoint.COUNT_FILTER_ENABLED); + myConditionCheckbox.setSelected(breakpoint.CONDITION_ENABLED); + if(DebuggerSettings.SUSPEND_NONE.equals(breakpoint.SUSPEND_POLICY)) { + mySuspendPolicyGroup.setSelected(mySuspendNoneRadio.getModel(), true); + } + else if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){ + mySuspendPolicyGroup.setSelected(mySuspendThreadRadio.getModel(), true); + } + else { + mySuspendPolicyGroup.setSelected(mySuspendAllRadio.getModel(), true); + } + myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED); + myLogExpressionCheckBox.setSelected(breakpoint.LOG_EXPRESSION_ENABLED); + + myConditionCombo.setContext(context); + myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : TextWithImportsImpl.EMPTY); + myLogExpressionCombo.setContext(context); + myLogExpressionCombo.setText(breakpoint.getLogMessage() != null? breakpoint.getLogMessage() : TextWithImportsImpl.EMPTY); + + myLogExpressionCombo.setEnabled(breakpoint.LOG_EXPRESSION_ENABLED); + + myInstanceFiltersCheckBox.setSelected(breakpoint.INSTANCE_FILTERS_ENABLED); + myInstanceFiltersField.setEnabled(breakpoint.INSTANCE_FILTERS_ENABLED); + myInstanceFiltersField.getTextField().setEditable(breakpoint.INSTANCE_FILTERS_ENABLED); + myInstanceFilters = breakpoint.getInstanceFilters(); + updateInstanceFilterEditor(true); + + myClassFiltersCheckBox.setSelected(breakpoint.CLASS_FILTERS_ENABLED); + myClassFiltersField.setEnabled(breakpoint.CLASS_FILTERS_ENABLED); + myClassFiltersField.getTextField().setEditable(breakpoint.CLASS_FILTERS_ENABLED); + myClassFilters = breakpoint.getClassFilters(); + myClassExclusionFilters = breakpoint.getClassExclusionFilters(); + updateClassFilterEditor(true); + + myBreakpointPsiClass = breakpoint.getPsiClass(); + + updateCheckboxes(); + } + + /** + * Save values in the UI components to the breakpoint object + */ + public void saveTo(Breakpoint breakpoint, Runnable afterUpdate) { + try { + String text = myPassCountField.getText().trim(); + int count = !"".equals(text)? Integer.parseInt(text) : 0; + breakpoint.COUNT_FILTER = count; + if (breakpoint.COUNT_FILTER < 0) { + breakpoint.COUNT_FILTER = 0; + } + } + catch (Exception e) { + } + breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0? myPassCountCheckbox.isSelected() : false; + breakpoint.setCondition(myConditionCombo.getText()); + breakpoint.CONDITION_ENABLED = !breakpoint.getCondition().isEmpty() ? myConditionCheckbox.isSelected() : false; + breakpoint.setLogMessage(myLogExpressionCombo.getText()); + breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty()? myLogExpressionCheckBox.isSelected() : false; + breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected(); + if(mySuspendAllRadio.isSelected()) { + breakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL; + } + else if(mySuspendThreadRadio.isSelected()) { + breakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_THREAD; + } + else { + breakpoint.SUSPEND_POLICY = DebuggerSettings.SUSPEND_NONE; + } + reloadInstanceFilters(); + reloadClassFilters(); + updateInstanceFilterEditor(true); + updateClassFilterEditor(true); + + breakpoint.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 ? myInstanceFiltersCheckBox.isSelected() : false; + breakpoint.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 ? myClassFiltersCheckBox.isSelected() : false; + breakpoint.setClassFilters(myClassFilters); + breakpoint.setClassExclusionFilters(myClassExclusionFilters); + breakpoint.setInstanceFilters(myInstanceFilters); + + myConditionCombo.addRecent(myConditionCombo.getText()); + myLogExpressionCombo.addRecent(myLogExpressionCombo.getText()); + breakpoint.updateUI(afterUpdate); + } + + private String concatWith(List s, String concator) { + String result = ""; + for (Iterator iterator = s.iterator(); iterator.hasNext();) { + String str = (String) iterator.next(); + result += str + concator; + } + if(result.length() > 0) return result.substring(0, result.length() - concator.length()); + else return ""; + } + + private String concatWithEx(List s, String concator, int N, String NthConcator) { + String result = ""; + int i = 1; + for (Iterator iterator = s.iterator(); iterator.hasNext(); i++) { + String str = (String) iterator.next(); + result += str; + if(iterator.hasNext()){ + if(i % N == 0){ + result += NthConcator; + } else { + result += concator; + } + } + } + return result; + } + + private void updateInstanceFilterEditor(boolean updateText) { + List filters = new ArrayList(); + for (int i = 0; i < myInstanceFilters.length; i++) { + InstanceFilter instanceFilter = myInstanceFilters[i]; + if(instanceFilter.isEnabled()) { + filters.add(Long.toString(instanceFilter.getId())); + } + } + if (updateText) { + String editorText = concatWith(filters, " "); + myInstanceFiltersField.setText(editorText); + } + + String tipText = concatWithEx(filters, " ", (int)Math.sqrt(myInstanceFilters.length) + 1, "\n"); + myInstanceFiltersField.getTextField().setToolTipText(tipText); + } + + private void reloadInstanceFilters() { + String filtersText = myInstanceFiltersField.getText(); + + ArrayList idxs = new ArrayList(); + int startNumber = -1; + for(int i = 0; i <= filtersText.length(); i++) { + if(i < filtersText.length() && Character.isDigit(filtersText.charAt(i))){ + if(startNumber == -1) startNumber = i; + } else { + if(startNumber >=0) { + idxs.add(InstanceFilter.create(filtersText.substring(startNumber, i))); + startNumber = -1; + } + } + } + for (int i = 0; i < myInstanceFilters.length; i++) { + InstanceFilter instanceFilter = myInstanceFilters[i]; + if(!instanceFilter.isEnabled()) idxs.add(instanceFilter); + } + myInstanceFilters = idxs.toArray(new InstanceFilter[idxs.size()]); + } + + private void updateClassFilterEditor(boolean updateText) { + List filters = new ArrayList(); + for (int i = 0; i < myClassFilters.length; i++) { + ClassFilter classFilter = myClassFilters[i]; + if(classFilter.isEnabled()) { + filters.add(classFilter.getPattern()); + } + } + List excludeFilters = new ArrayList(); + for (int i = 0; i < myClassExclusionFilters.length; i++) { + ClassFilter classFilter = myClassExclusionFilters[i]; + if(classFilter.isEnabled()) { + excludeFilters.add("-" + classFilter.getPattern()); + } + } + if (updateText) { + String editorText = concatWith(filters, " "); + if(filters.size() > 0) editorText += " "; + editorText += concatWith(excludeFilters, " "); + myClassFiltersField.setText(editorText); + } + + int width = (int)Math.sqrt(myClassExclusionFilters.length + myClassFilters.length) + 1; + String tipText = concatWithEx(filters, " ", width, "\n"); + if(filters.size() > 0) tipText += "\n"; + tipText += concatWithEx(excludeFilters, " ", width, "\n"); + myClassFiltersField.getTextField().setToolTipText(tipText); + + } + + private void reloadClassFilters() { + String filtersText = myClassFiltersField.getText(); + + ArrayList classFilters = new ArrayList(); + ArrayList exclusionFilters = new ArrayList(); + int startFilter = -1; + for(int i = 0; i <= filtersText.length(); i++) { + if(i < filtersText.length() && !Character.isWhitespace(filtersText.charAt(i))){ + if(startFilter == -1) startFilter = i; + } else { + if(startFilter >=0) { + if(filtersText.charAt(startFilter) == '-'){ + exclusionFilters.add(new ClassFilter(filtersText.substring(startFilter + 1, i))); + } else { + classFilters.add(new ClassFilter(filtersText.substring(startFilter, i))); + } + startFilter = -1; + } + } + } + for (int i = 0; i < myClassFilters.length; i++) { + ClassFilter classFilter = myClassFilters[i]; + if(!classFilter.isEnabled()) classFilters.add(classFilter); + } + for (int i = 0; i < myClassExclusionFilters.length; i++) { + ClassFilter classFilter = myClassExclusionFilters[i]; + if(!classFilter.isEnabled()) exclusionFilters.add(classFilter); + } + myClassFilters = classFilters .toArray(new ClassFilter[classFilters .size()]); + myClassExclusionFilters = exclusionFilters.toArray(new ClassFilter[exclusionFilters.size()]); + } + + public void setEnabled(boolean enabled) { + myPanel.setEnabled(enabled); + Component[] components = myPanel.getComponents(); + for (int i = 0; i < components.length; i++) { + Component component = components[i]; + component.setEnabled(enabled); + } + } + + protected void updateCheckboxes() { + JCheckBox [] checkBoxes = new JCheckBox[] { myConditionCheckbox, myInstanceFiltersCheckBox, myClassFiltersCheckBox}; + JCheckBox selected = null; + for(int i =0; i < checkBoxes.length; i++) { + if(checkBoxes[i].isSelected()) { + selected = checkBoxes[i]; + break; + } + } + + if(selected != null){ + myPassCountCheckbox.setEnabled(false); + } else { + myPassCountCheckbox.setEnabled(true); + } + + for(int i =0; i < checkBoxes.length; i++) { + checkBoxes[i].setEnabled (!myPassCountCheckbox.isSelected()); + } + + myPassCountField.setEditable(myPassCountCheckbox.isSelected()); + myPassCountField.setEnabled (myPassCountCheckbox.isSelected()); + myConditionCombo.setEnabled(myConditionCheckbox.isSelected()); + myInstanceFiltersField.setEnabled(myInstanceFiltersCheckBox.isSelected()); + myInstanceFiltersField.getTextField().setEditable(myInstanceFiltersCheckBox.isSelected()); + myClassFiltersField.setEnabled(myClassFiltersCheckBox.isSelected()); + myClassFiltersField.getTextField().setEditable(myClassFiltersCheckBox.isSelected()); + } + + public JPanel getPanel() { + return myPanel; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointTableModel.java new file mode 100644 index 00000000000..6635c9b246b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointTableModel.java @@ -0,0 +1,118 @@ +/* + * Class BreakpointTableModel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.util.ui.ItemRemovable; + +import javax.swing.table.AbstractTableModel; +import java.util.LinkedList; + +public class BreakpointTableModel extends AbstractTableModel implements ItemRemovable { + public static final int ENABLED_STATE = 0; + public static final int NAME = 1; + + private java.util.List myBreakpoints = null; + + public BreakpointTableModel() { + myBreakpoints = new LinkedList(); + } + + public final void setBreakpoints(Breakpoint[] breakpoints) { + myBreakpoints.clear(); + if (breakpoints != null) { + for (int idx = 0; idx < breakpoints.length; idx++) { + myBreakpoints.add(breakpoints[idx]); + } + } + fireTableDataChanged(); + } + + public Breakpoint getBreakpoint(int index) { + if (index < 0 || index >= myBreakpoints.size()) return null; + return (Breakpoint)myBreakpoints.get(index); + } + + public int getBreakpointIndex(Breakpoint breakpoint) { + return myBreakpoints.indexOf(breakpoint); + } + + public void insertBreakpointAt(Breakpoint breakpoint, int index) { + myBreakpoints.add(index, breakpoint); + fireTableRowsInserted(index, index); + } + + public void addBreakpoint(Breakpoint breakpoint) { + myBreakpoints.add(breakpoint); + int row = myBreakpoints.size() - 1; + fireTableRowsInserted(row, row); + } + + public void removeRow(int idx) { + if (idx >= 0 && idx < myBreakpoints.size()) { + myBreakpoints.remove(idx); + fireTableRowsDeleted(idx, idx); + } + } + + public int getRowCount() { + return myBreakpoints.size(); + } + + public int getColumnCount() { + return 2; + } + + public String getColumnName(int column) { + switch (column) { + case ENABLED_STATE: + return "Enabled"; + case NAME: + return "Name"; + default : + return ""; + } + } + + public Object getValueAt(int rowIndex, int columnIndex) { + Breakpoint breakpoint = (Breakpoint)myBreakpoints.get(rowIndex); + if (columnIndex == NAME) { + return breakpoint.getDisplayName(); + } + if (columnIndex == ENABLED_STATE) { + return breakpoint.ENABLED? Boolean.TRUE : Boolean.FALSE; + } + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex < 0 || rowIndex >= myBreakpoints.size()) { + return; + } + Breakpoint breakpoint = (Breakpoint)myBreakpoints.get(rowIndex); +/* + if (columnIndex == NAME) { + breakpoint.setDisplayName((aValue != null)? aValue.toString() : ""); + } + else +*/ + if (columnIndex == ENABLED_STATE) { + boolean value = aValue != null? ((Boolean)aValue).booleanValue() : true; + breakpoint.ENABLED = value; + } + fireTableRowsUpdated(rowIndex, rowIndex); + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == ENABLED_STATE) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { +// Breakpoint breakpoint = (Breakpoint)myBreakpoints.get(rowIndex); + return (columnIndex == ENABLED_STATE /*|| breakpoint.isChecked()*/); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java new file mode 100644 index 00000000000..7e8658764f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java @@ -0,0 +1,530 @@ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.*; +import com.intellij.debugger.actions.ViewBreakpointsAction; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JVMNameUtil; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.settings.DebuggerColors; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.MarkupModelEx; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.*; +import com.sun.jdi.ReferenceType; +import org.jdom.Element; + +import javax.swing.*; +import java.awt.*; + +/** + * User: lex + * Date: Sep 2, 2003 + * Time: 3:22:55 PM + */ +public abstract class BreakpointWithHighlighter extends Breakpoint { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter"); + + private RangeHighlighter myHighlighter; + + private SourcePosition mySourcePosition; + private long myTimeStamp; + + private boolean myVisible = true; + private Icon myIcon = getSetIcon(); + private String myClassName = ""; + private String myInvalidMessage = ""; + + protected abstract void createRequestForPreparedClass(final DebugProcessImpl debugProcess, + final ReferenceType classType); + + protected abstract Icon getDisabledIcon(); + + protected abstract Icon getInvalidIcon(); + + protected abstract Icon getSetIcon(); + + protected abstract Icon getVerifiedIcon(); + + public Icon getIcon() { + return myIcon; + } + + protected String getClassName() { + return myClassName; + } + + protected Breakpoint init() { + if(!isValid()) { + getDocument().getMarkupModel(myProject).removeHighlighter(myHighlighter); + return null; + } + + if(!ApplicationManager.getApplication().isUnitTestMode()) { + updateUI(); + updateGutter(); + } + + return this; + } + + private void updateCaches(DebugProcessImpl debugProcess) { + myIcon = calcIcon(debugProcess); + myClassName = calcClassName(debugProcess); + } + + private String calcClassName(DebugProcessImpl debugProcess) { + return JVMNameUtil.getClassDisplayName(debugProcess, getSourcePosition()); + } + + private Icon calcIcon(DebugProcessImpl debugProcess) { + if (!ENABLED) { + return getDisabledIcon(); + } + + myInvalidMessage = ""; + + if (!isValid()) return getInvalidIcon(); + + if(debugProcess == null){ + return getSetIcon(); + } + + RequestManagerImpl requestsManager = debugProcess.getRequestsManager(); + + if(requestsManager.isVerified(this)){ + return getVerifiedIcon(); + } else if(requestsManager.isInvalid(this)){ + myInvalidMessage = requestsManager.getInvalidMessage(this); + return getInvalidIcon(); + } else { + return getSetIcon(); + } + } + + protected BreakpointWithHighlighter(Project project) { + //for persistency + super(project); + } + + public BreakpointWithHighlighter(final Project project, final RangeHighlighter highlighter) { + super(project); + myHighlighter = highlighter; + highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter()); + reload(); + } + + public RangeHighlighter getHighlighter() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + return myHighlighter; + } + + public boolean isValid() { + return ApplicationManager.getApplication().runReadAction(new Computable(){ + public Boolean compute() { + return new Boolean(getSourcePosition() != null && getSourcePosition().getFile().isValid()); + } + }).booleanValue(); + } + + public SourcePosition getSourcePosition() { + return mySourcePosition; + } + + public String getDescription() { + StringBuffer buf = new StringBuffer(64); + buf.append(""); + buf.append(getDisplayName()); + if(!"".equals(myInvalidMessage)) { + buf.append("
    Breakpoint is invalid : " + myInvalidMessage + "."); + } + buf.append(" 
     Suspend : "); + if(DebuggerSettings.SUSPEND_ALL.equals(SUSPEND_POLICY)) { + buf.append("all"); + } + else if(DebuggerSettings.SUSPEND_THREAD.equals(SUSPEND_POLICY)) { + buf.append("thread"); + } + else if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { + buf.append("none"); + } + buf.append(" 
     Log message: "); + buf.append(LOG_ENABLED ? "yes" : "no"); + if (LOG_EXPRESSION_ENABLED) { + buf.append(" 
     Log expression: "); + buf.append(getLogMessage()); + } + if (CONDITION_ENABLED && (getCondition() != null && !"".equals(getCondition()))) { + buf.append(" 
     Condition: "); + buf.append(getCondition()); + } + if (COUNT_FILTER_ENABLED) { + buf.append(" 
     Pass count: "); + buf.append(COUNT_FILTER); + } + if (CLASS_FILTERS_ENABLED) { + buf.append(" 
     Class filters: "); + ClassFilter[] classFilters = getClassFilters(); + for (int i = 0; i < classFilters.length; i++) { + ClassFilter classFilter = classFilters[i]; + buf.append(classFilter.getPattern() + " "); + } + } + if (INSTANCE_FILTERS_ENABLED) { + buf.append(" 
     Instance filters: "); + InstanceFilter[] instanceFilters = getInstanceFilters(); + for (int i = 0; i < instanceFilters.length; i++) { + InstanceFilter instanceFilter = instanceFilters[i]; + buf.append(Long.toString(instanceFilter.getId()) + " "); + } + } + buf.append(""); + return buf.toString(); + } + + public final void reload() { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + if (getHighlighter().isValid()) { + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(getHighlighter().getDocument()); + if(psiFile != null) { + mySourcePosition = SourcePosition.createFromOffset(psiFile, getHighlighter().getStartOffset()); + + long modificationStamp = mySourcePosition.getFile().getModificationStamp(); + if(modificationStamp != myTimeStamp) { + reload(psiFile); + } + return; + } + } + mySourcePosition = null; + } + + public void createRequest(DebugProcessImpl debugProcess) { + // check is this breakpoint is enabled, vm reference is valid and there're no requests created yet + if (!ENABLED || !debugProcess.isAttached() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { + return; + } + + if (!isValid()) { + return; + } + + createOrWaitPrepare(debugProcess, getSourcePosition()); + updateUI(); + } + + public void processClassPrepare(final DebugProcess debugProcess, final ReferenceType classType) { + if (!ENABLED || !isValid()) { + return; + } + createRequestForPreparedClass((DebugProcessImpl)debugProcess, classType); + updateUI(); + } + + + /** + * updates the state of breakpoint and all the related UI widgets etc + */ + public final void updateUI(final Runnable afterUpdate) { + if(ApplicationManager.getApplication().isUnitTestMode()) return; + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + if(PsiManager.getInstance(myProject).isDisposed()) return; + if(!isValid()) return; + + DebuggerContextImpl context = DebuggerManagerEx.getInstanceEx(myProject).getContext(); + final DebugProcessImpl debugProcess = context.getDebugProcess(); + + if(debugProcess == null || !context.getDebuggerSession().isAttached()) { + updateCaches(null); + updateGutter(); + afterUpdate.run(); + } else { + final ModalityState modalityState = ModalityState.current(); + + debugProcess.getManagerThread().invoke(new DebuggerCommandImpl() { + protected void action() throws Exception { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + updateCaches(debugProcess); + } + }); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + updateGutter(); + afterUpdate.run(); + } + }, modalityState); + } + }); + } + } + }, ModalityState.defaultModalityState()); + } + + private void updateGutter() { + if(myVisible) { + if (getHighlighter() != null && getHighlighter().isValid() && isValid()) { + setupGutterRenderer(); + } else { + DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint( + BreakpointWithHighlighter.this); + } + } + } + + /** + * called by BreakpointManeger when destroying the breakpoint + */ + public void delete() { + if (isVisible()) { + final RangeHighlighter highlighter = getHighlighter(); + if (highlighter != null) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + if (highlighter.isValid()) { + MarkupModel markupModel = highlighter.getDocument().getMarkupModel(myProject); + if (markupModel != null) { + markupModel.removeHighlighter(highlighter); + } + //we should delete it here, so gutter will not fire events to deleted breakpoint + BreakpointWithHighlighter.super.delete(); + } + } + }); + } + } + + } + + public boolean isAt(Document document, int offset) { + if (getHighlighter() == null || !getHighlighter().isValid()) return false; + return (document.equals(getHighlighter().getDocument()) && getSourcePosition().getLine() == document.getLineNumber(offset)); + } + + protected void reload(PsiFile psiFile) { + if (!(psiFile instanceof PsiJavaFile)) return; + myTimeStamp = getSourcePosition().getFile().getModificationStamp(); + } + + public PsiClass getPsiClass() { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public PsiClass compute() { + return JVMNameUtil.getClassAt(getSourcePosition()); + } + }); + } + + private void setupGutterRenderer() { + getHighlighter().setGutterIconRenderer(new GutterIconRenderer() { + public Icon getIcon() { + return BreakpointWithHighlighter.this.getIcon(); + } + + public String getTooltipText() { + return getDescription(); + } + + public AnAction getClickAction() { + return new AnAction() { + public void actionPerformed(AnActionEvent e) { + DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this); + } + }; + } + + public AnAction getMiddleButtonClickAction() { + return new AnAction() { + public void actionPerformed(AnActionEvent e) { + boolean value = !ENABLED; + ENABLED = value; + DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().breakpointChanged(BreakpointWithHighlighter.this); + updateUI(); + } + }; + } + + public ActionGroup getPopupMenuActions() { + return createMenuActions(); + } + + public GutterDraggableObject getDraggableObject() { + return new GutterDraggableObject() { + public void removeSelf() { + //DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this); + } + + public boolean copy(int line) { + return moveTo(SourcePosition.createFromLine(getSourcePosition().getFile(), line)); + } + + public Cursor getCursor() { + return new Cursor (Cursor.MOVE_CURSOR); + } + }; + } + }); + } + + protected boolean moveTo(SourcePosition position) { + RangeHighlighter oldHighlighter = myHighlighter; + + Document document = getDocument(); + myHighlighter = createHighlighter(myProject, document, position.getLine()); + + reload(); + if(!isValid()) { + document.getMarkupModel(myProject).removeHighlighter(myHighlighter); + myHighlighter = oldHighlighter; + reload(); + return false; + } + + document.getMarkupModel(myProject).removeHighlighter(oldHighlighter); + + DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().breakpointChanged(this); + updateUI(); + + return true; + } + + public boolean isVisible() { + return myVisible; + } + + public void setVisible(boolean visible) { + myVisible = visible; + } + + public Document getDocument() { + return getHighlighter().getDocument(); + } + + public int getLineIndex() { + return getSourcePosition().getLine(); + } + + protected static RangeHighlighter createHighlighter(Project project, + Document document, + int lineIndex) { + if (lineIndex < 0 || lineIndex >= document.getLineCount()) { + return null; + } + + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + TextAttributes attributes = scheme.getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES); + + RangeHighlighter highlighter = ((MarkupModelEx)document.getMarkupModel(project)).addPersistentLineHighlighter( + lineIndex, HighlighterLayer.ADDITIONAL_SYNTAX + 1, attributes); + if (!highlighter.isValid()) { + return null; + } + return highlighter; + } + + public void readExternal(Element breakpointNode) throws InvalidDataException { + super.readExternal(breakpointNode); + final String url = breakpointNode.getAttributeValue("url"); + + VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url); + if (vFile == null) throw new InvalidDataException("File number is invalid for breakpoint"); + final Document doc = FileDocumentManager.getInstance().getDocument(vFile); + if (doc == null) throw new InvalidDataException("File number is invalid for breakpoint"); + + // line number + final int line; + try { + line = Integer.parseInt(breakpointNode.getAttributeValue("line")); + } + catch (Exception e) { + throw new InvalidDataException("Line number is invalid forbreakpoint"); + } + if (line < 0) throw new InvalidDataException("Line number is invalid forbreakpoint"); + + RangeHighlighter highlighter = createHighlighter(myProject, doc, line); + + if (highlighter == null) throw new InvalidDataException(""); + + myHighlighter = highlighter; + reload(); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + super.writeExternal(parentNode); + PsiFile psiFile = getSourcePosition().getFile(); + String url = psiFile.getVirtualFile().getUrl(); + parentNode.setAttribute("url", url); + parentNode.setAttribute("line", Integer.toString(getSourcePosition().getLine())); + } + + private ActionGroup createMenuActions() { + final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager(); + /** + * Used from Popup Menu + */ + class RemoveAction extends AnAction { + private Breakpoint myBreakpoint; + + public RemoveAction(Breakpoint breakpoint) { + super("Remove"); + myBreakpoint = breakpoint; + } + + public void actionPerformed(AnActionEvent e) { + if (myBreakpoint != null) { + breakpointManager.removeBreakpoint(myBreakpoint); + myBreakpoint = null; + } + } + } + + /** + * Used from Popup Menu + */ + class SetEnabledAction extends AnAction { + private boolean myNewValue; + private Breakpoint myBreakpoint; + + public SetEnabledAction(Breakpoint breakpoint, boolean newValue) { + super(newValue ? "Enable" : "Disable"); + myBreakpoint = breakpoint; + myNewValue = newValue; + } + + public void actionPerformed(AnActionEvent e) { + myBreakpoint.ENABLED = myNewValue; + breakpointManager.breakpointChanged(myBreakpoint); + myBreakpoint.updateUI(); + } + } + + ViewBreakpointsAction viewBreakpointsAction = new ViewBreakpointsAction("Properties"); + viewBreakpointsAction.setInitialBreakpoint(this); + + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new SetEnabledAction(this, !ENABLED)); + group.add(new RemoveAction(this)); + group.addSeparator(); + group.add(viewBreakpointsAction); + return group; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointsConfigurationDialogFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointsConfigurationDialogFactory.java new file mode 100644 index 00000000000..95be88fb601 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/BreakpointsConfigurationDialogFactory.java @@ -0,0 +1,487 @@ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.HelpID; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.TabbedPaneWrapper; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +/** + * created Jun 18, 2001 + * @author Jeka + */ +public class BreakpointsConfigurationDialogFactory { + private static final String BREAKPOINT_PANEL = "breakpoint_panel"; + private static final String LINE_BREAKPOINTS_NAME = "Line Breakpoints"; + private static final String EXCEPTION_BREAKPOINTS_NAME = "Exception Breakpoints"; + private static final String FIELD_WATCHPOINTS_NAME = "Field Watchpoints"; + private static final String METHOD_BREAKPOINTS_NAME = "Method Breakpoints"; + + private Project myProject; + private BreakpointPanel myLineBreakpointsPanel; + private BreakpointPanel myExceptionBreakpointsPanel; + private BreakpointPanel myFieldBreakpointsPanel; + private BreakpointPanel myMethodBreakpointsPanel; + private int myLastSelectedTabIndex = 0; + + public BreakpointsConfigurationDialogFactory(Project project) { + myProject = project; + } + + private BreakpointManager getBreakpointManager() { + return DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager(); + } + + public DialogWrapper createDialog(Breakpoint initialBreakpoint, String selectComponent) { + BreakpointsConfigurationDialog dialog = new BreakpointsConfigurationDialog(); + dialog.selectBreakpoint(initialBreakpoint); + dialog.setPreferredFocusedComponent(selectComponent); + return dialog; + } + + private class BreakpointsConfigurationDialog extends DialogWrapper { + private JPanel myPanel; + private TabbedPaneWrapper myTabbedPane; + private JComponent myPreferredComponent; + + public BreakpointsConfigurationDialog() { + super(myProject, true); + setTitle("Breakpoints"); + setOKButtonText("&Close"); + init(); + reset(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(), getHelpAction()}; + } + + protected void doHelpAction() { + if (myLineBreakpointsPanel.getPanel().isShowing()) { + HelpManager.getInstance().invokeHelp(HelpID.LINE_BREAKPOINTS); + } + else if (myMethodBreakpointsPanel.getPanel().isShowing()) { + HelpManager.getInstance().invokeHelp(HelpID.METHOD_BREAKPOINTS); + } + else if (myExceptionBreakpointsPanel.getPanel().isShowing()) { + HelpManager.getInstance().invokeHelp(HelpID.EXCEPTION_BREAKPOINTS); + } + else if (myFieldBreakpointsPanel.getPanel().isShowing()) { + HelpManager.getInstance().invokeHelp(HelpID.FIELD_WATCHPOINTS); + } + else { + super.doHelpAction(); + } + } + + protected JComponent createCenterPanel() { + myTabbedPane = new TabbedPaneWrapper(); + myPanel = new JPanel(new BorderLayout()); + myLineBreakpointsPanel = new BreakpointPanel(new BreakpointTableModel(), new LineBreakpointPropertiesPanel(myProject)); + myLineBreakpointsPanel.getAddBreakpointButton().setVisible(false); + initPanel(myLineBreakpointsPanel); + + myExceptionBreakpointsPanel = new BreakpointPanel(new BreakpointTableModel(), new ExceptionBreakpointPropertiesPanel(myProject)) { + public void updateButtons() { + super.updateButtons(); + if(getRemoveBreakpointButton().isEnabled()) { + Breakpoint[] selectedBreakpoints = getSelectedBreakpoints(); + for (int i = 0; i < selectedBreakpoints.length; i++) { + Breakpoint bp = selectedBreakpoints[i]; + if (bp instanceof AnyExceptionBreakpoint) { + getRemoveBreakpointButton().setEnabled(false); + } + } + } + } + }; + AddExceptionBreakpointAction addExceptionBreakpointAction = new AddExceptionBreakpointAction(); + myExceptionBreakpointsPanel.getAddBreakpointButton().addActionListener(addExceptionBreakpointAction); + myExceptionBreakpointsPanel.getTable().registerKeyboardAction( + addExceptionBreakpointAction, + KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + myExceptionBreakpointsPanel.getViewSourceButton().setVisible(false); + myExceptionBreakpointsPanel.getGotoSourceButton().setVisible(false); + RemoveBreakpointAction removeExceptionBreakpointAction = new RemoveBreakpointAction(myExceptionBreakpointsPanel); + final JButton removeExceptionBreakpointButton = myExceptionBreakpointsPanel.getRemoveBreakpointButton(); + removeExceptionBreakpointButton.addActionListener(removeExceptionBreakpointAction); + myExceptionBreakpointsPanel.getTable().registerKeyboardAction( + removeExceptionBreakpointAction, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + myExceptionBreakpointsPanel.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + JTable table = myExceptionBreakpointsPanel.getTable(); + boolean shouldEnable = (table.getModel().getRowCount() > 0) && (table.getSelectedRow() >= 0); + if (shouldEnable) { + BreakpointTableModel model = (BreakpointTableModel)table.getModel(); + int[] rows = table.getSelectedRows(); + for (int idx = 0; idx < rows.length; idx++) { + Breakpoint breakpoint = model.getBreakpoint(rows[idx]); + if (breakpoint instanceof AnyExceptionBreakpoint) { + shouldEnable = false; + break; + } + } + } + removeExceptionBreakpointButton.setEnabled(shouldEnable); + } + }); + removeExceptionBreakpointButton.setEnabled(false); + + myFieldBreakpointsPanel = new BreakpointPanel(new BreakpointTableModel(), new FieldBreakpointPropertiesPanel(myProject)); + AddFieldBreakpointAction addFieldBreakpointAction = new AddFieldBreakpointAction(); + myFieldBreakpointsPanel.getAddBreakpointButton().addActionListener(addFieldBreakpointAction); + myFieldBreakpointsPanel.getTable().registerKeyboardAction( + addFieldBreakpointAction, + KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + initPanel(myFieldBreakpointsPanel); + + myMethodBreakpointsPanel = new BreakpointPanel(new BreakpointTableModel(), new MethodBreakpointPropertiesPanel(myProject)); + myMethodBreakpointsPanel.getAddBreakpointButton().setVisible(false); + initPanel(myMethodBreakpointsPanel); + + addPanel(myLineBreakpointsPanel); + addPanel(myExceptionBreakpointsPanel); + addPanel(myFieldBreakpointsPanel); + addPanel(myMethodBreakpointsPanel); + + ShortcutSet shortcutSet = ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(); + new AnAction() { + public void actionPerformed(AnActionEvent e){ + gotoSource(); + } + }.registerCustomShortcutSet(shortcutSet, myLineBreakpointsPanel.getPanel()); + new AnAction() { + public void actionPerformed(AnActionEvent e){ + gotoSource(); + } + }.registerCustomShortcutSet(shortcutSet, myMethodBreakpointsPanel.getPanel()); + + myTabbedPane.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + BreakpointPanel panel = getSelectedPanel(); + JTable table = panel.getTable(); + if (table.getRowCount() > 0 && table.getSelectedRow() < 0) { + ListSelectionModel model = table.getSelectionModel(); + model.clearSelection(); + model.addSelectionInterval(0, 0); + table.requestFocus(); + } + panel.setBorderTitle (myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex())); + } + }); + myPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + + myTabbedPane.installKeyboardNavigation(); + + // "Enter" and "Esc" keys work like "Close" button. + ActionListener closeAction = new ActionListener() { + public void actionPerformed(ActionEvent e) { + close(CANCEL_EXIT_CODE); + } + }; + myPanel.registerKeyboardAction( + closeAction, + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + myPanel.setPreferredSize(new Dimension(600, 500)); + return myPanel; + } + + private void addPanel(BreakpointPanel panel) { + JPanel jpanel = panel.getPanel(); + jpanel.putClientProperty(BREAKPOINT_PANEL, panel); + myTabbedPane.addTab(null, jpanel); + } + + private BreakpointPanel getSelectedPanel() { + JComponent selectedComponent = myTabbedPane.getSelectedComponent(); + return selectedComponent != null ? (BreakpointPanel)selectedComponent.getClientProperty(BREAKPOINT_PANEL) : null; + } + + private void initPanel(final BreakpointPanel panel) { + panel.getGotoSourceButton().addActionListener(myGotoSourceAction); + panel.getViewSourceButton().addActionListener(myViewSourceAction); + RemoveBreakpointAction removeBreakpointAction = new RemoveBreakpointAction(panel); + panel.getRemoveBreakpointButton().addActionListener(removeBreakpointAction); + panel.getTable().registerKeyboardAction( + removeBreakpointAction, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + } + + public JComponent getPreferredFocusedComponent() { + return myPreferredComponent != null ? myPreferredComponent : IdeFocusTraversalPolicy.getPreferredFocusedComponent(myTabbedPane.getComponent()); + } + + public void setPreferredFocusedComponent(String control) { + BreakpointPanel selectedPanel = getSelectedPanel(); + myPreferredComponent = selectedPanel.getControl(control); + } + + protected void dispose() { + apply(); + if (myPanel != null) { + myLastSelectedTabIndex = myTabbedPane.getSelectedIndex(); + myPanel.removeAll(); + myPanel = null; + myTabbedPane = null; + } + super.dispose(); + } + + private void apply() { + if (myLineBreakpointsPanel != null) { + myLineBreakpointsPanel.saveChanges(); + } + if (myExceptionBreakpointsPanel != null) { + myExceptionBreakpointsPanel.saveChanges(); + } + if (myFieldBreakpointsPanel != null) { + myFieldBreakpointsPanel.saveChanges(); + } + if (myMethodBreakpointsPanel != null) { + myMethodBreakpointsPanel.saveChanges(); + } + BreakpointManager breakpointManager = getBreakpointManager(); + breakpointManager.updateAllRequests(); + } + + private void reset() { + BreakpointManager breakpointManager = getBreakpointManager(); + myLineBreakpointsPanel.setBreakpoints(breakpointManager.getBreakpoints(BreakpointManager.LINE_BREAKPOINTS)); + myExceptionBreakpointsPanel.setBreakpoints(breakpointManager.getBreakpoints(BreakpointManager.EXCEPTION_BREAKPOINTS)); + myExceptionBreakpointsPanel.insertBreakpointAt(breakpointManager.getAnyExceptionBreakpoint(), 0); + myFieldBreakpointsPanel.setBreakpoints(breakpointManager.getBreakpoints(BreakpointManager.FIELD_BREAKPOINTS)); + myMethodBreakpointsPanel.setBreakpoints(breakpointManager.getBreakpoints(BreakpointManager.METHOD_BREAKPOINTS)); + updateTitles(); + if (myLastSelectedTabIndex >= myTabbedPane.getTabCount() && myLastSelectedTabIndex < 0) { + myLastSelectedTabIndex = 0; + } + myTabbedPane.setSelectedIndex(myLastSelectedTabIndex); + } + + private void selectBreakpoint(Breakpoint breakpoint) { + if (breakpoint == null) return; + if (breakpoint instanceof LineBreakpoint) { + myTabbedPane.setSelectedComponent(myLineBreakpointsPanel.getPanel()); + myLineBreakpointsPanel.selectBreakpoint(breakpoint); + } + else if (breakpoint instanceof ExceptionBreakpoint) { + myTabbedPane.setSelectedComponent(myExceptionBreakpointsPanel.getPanel()); + myExceptionBreakpointsPanel.selectBreakpoint(breakpoint); + } + else if (breakpoint instanceof FieldBreakpoint) { + myTabbedPane.setSelectedComponent(myFieldBreakpointsPanel.getPanel()); + myFieldBreakpointsPanel.selectBreakpoint(breakpoint); + } + else if (breakpoint instanceof MethodBreakpoint) { + myTabbedPane.setSelectedComponent(myMethodBreakpointsPanel.getPanel()); + myMethodBreakpointsPanel.selectBreakpoint(breakpoint); + } + } + + private AbstractAction myGotoSourceAction = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + gotoSource(); + } + }; + + private void gotoSource(){ + OpenFileDescriptor editSourceDescriptor = createEditSourceDescriptor(); + if (editSourceDescriptor == null) return; + FileEditorManager.getInstance(myProject).openTextEditor(editSourceDescriptor, true); + close(OK_EXIT_CODE); + } + + private AbstractAction myViewSourceAction = new AbstractAction () { + public void actionPerformed(ActionEvent e) { + OpenFileDescriptor editSourceDescriptor = createEditSourceDescriptor(); + if (editSourceDescriptor == null) return; + FileEditorManager.getInstance(myProject).openTextEditor(editSourceDescriptor, false); + } + }; + + private void updateTitles() { + for (int idx = 0; idx < myTabbedPane.getTabCount(); idx++) { + JComponent component = myTabbedPane.getComponentAt(idx); + if (component == myLineBreakpointsPanel.getPanel()) { + myTabbedPane.setTitleAt(idx, LINE_BREAKPOINTS_NAME + " (" + myLineBreakpointsPanel.getTable().getRowCount() + ")"); + myLineBreakpointsPanel.setBorderTitle (myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex())); + } + else if (component == myExceptionBreakpointsPanel.getPanel()) { + myTabbedPane.setTitleAt(idx, EXCEPTION_BREAKPOINTS_NAME + " (" + myExceptionBreakpointsPanel.getTable().getRowCount() + ")"); + myExceptionBreakpointsPanel.setBorderTitle (myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex())); + } + else if (component == myFieldBreakpointsPanel.getPanel()) { + myTabbedPane.setTitleAt(idx, FIELD_WATCHPOINTS_NAME + " (" + myFieldBreakpointsPanel.getTable().getRowCount() + ")"); + myFieldBreakpointsPanel.setBorderTitle (myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex())); + } + else if (component == myMethodBreakpointsPanel.getPanel()) { + myTabbedPane.setTitleAt(idx, METHOD_BREAKPOINTS_NAME + " (" + myMethodBreakpointsPanel.getTable().getRowCount() + ")"); + myMethodBreakpointsPanel.setBorderTitle (myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex())); + } + } + } + + private class AddExceptionBreakpointAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + final PsiClass throwableClass = PsiManager.getInstance(myProject).findClass("java.lang.Throwable", GlobalSearchScope.allScope(myProject)); + TreeClassChooserDialog chooser = + new TreeClassChooserDialog("Enter Exception Class", myProject, GlobalSearchScope.allScope(myProject), + new TreeClassChooserDialog.InheritanceClassFilter(throwableClass, true, true), + //null, + null); + chooser.show(); + PsiClass selectedClass = chooser.getSelectedClass(); + String qName = (selectedClass != null)? selectedClass.getQualifiedName() : null; + + if (qName != null && qName.length() > 0) { + ExceptionBreakpoint breakpoint = getBreakpointManager().addExceptionBreakpoint(qName); + myExceptionBreakpointsPanel.addBreakpoint(breakpoint); + } + myExceptionBreakpointsPanel.getTable().requestFocus(); + updateTitles(); + } + } + + private class AddFieldBreakpointAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(myProject) { + protected boolean validateData() { + String className = getClassName(); + if (className.length() == 0) { + Messages.showMessageDialog(myProject, "Cannot add watchpoint: a class name is not specified", "Add Field Watchpoint", Messages.getErrorIcon()); + return false; + } + String fieldName = getFieldName(); + if (fieldName.length() == 0) { + Messages.showMessageDialog(myProject, "Cannot add watchpoint: a field name is not specified", "Add Field Watchpoint", Messages.getErrorIcon()); + return false; + } + PsiClass psiClass = PsiManager.getInstance(myProject).findClass(className, GlobalSearchScope.allScope(myProject)); + if (psiClass != null) { + PsiFile psiFile = psiClass.getContainingFile(); + Document document = PsiDocumentManager.getInstance(myProject).getDocument(psiFile); + if(document != null) { + PsiField field = psiClass.findFieldByName(fieldName, true); + if(field != null) { + int line = document.getLineNumber(field.getTextOffset()); + FieldBreakpoint fieldBreakpoint = getBreakpointManager().addFieldBreakpoint(document, line, fieldName); + if (fieldBreakpoint != null) { + myFieldBreakpointsPanel.addBreakpoint(fieldBreakpoint); + myFieldBreakpointsPanel.getTable().requestFocus(); + updateTitles(); + return true; + } + } else { + Messages.showMessageDialog( + myProject, + "Cannot create a field watchpoint for \"" + className + "." + fieldName + "\".\nField \"" + fieldName + "\" not found", + "Error", + Messages.getErrorIcon() + ); + + } + } + } else { + Messages.showMessageDialog( + myProject, + "Cannot create a field watchpoint for \"" + className + "." + fieldName + "\".\nNo sources for class \"" + className + "\"", + "Error", + Messages.getErrorIcon() + ); + } + return false; + } + }; + dialog.show(); + } + } + + private class RemoveBreakpointAction implements ActionListener { + private BreakpointPanel myPanel; + + public RemoveBreakpointAction(BreakpointPanel panel) { + myPanel = panel; + } + + public void actionPerformed(ActionEvent e) { + Breakpoint[] breakpoints = myPanel.getSelectedBreakpoints(); + if (breakpoints != null) { + for (int idx = 0; idx < breakpoints.length; idx++) { + if (breakpoints[idx] instanceof AnyExceptionBreakpoint) { + return; + } + } + myPanel.removeSelectedBreakpoints(); + BreakpointManager manager = getBreakpointManager(); + for (int idx = 0; idx < breakpoints.length; idx++) { + manager.removeBreakpoint(breakpoints[idx]); + } + } + myPanel.getTable().requestFocus(); + updateTitles(); + } + } + + private OpenFileDescriptor createEditSourceDescriptor() { + BreakpointPanel breakpointsPanel = getSelectedPanel(); + if (breakpointsPanel == null) return null; + Breakpoint[] breakpoints = breakpointsPanel.getSelectedBreakpoints(); + if (breakpoints == null || breakpoints.length == 0) return null; + Breakpoint br = breakpoints[0]; + int line; + Document doc; + if (br instanceof BreakpointWithHighlighter) { + BreakpointWithHighlighter breakpoint = (BreakpointWithHighlighter)br; + doc = breakpoint.getDocument(); + line = breakpoint.getLineIndex(); + } + else { + return null; + } + if (line < 0 || line >= doc.getLineCount()) return null; + int offset = doc.getLineStartOffset(line); + if(br instanceof FieldBreakpoint) { + PsiField field = ((FieldBreakpoint) br).getPsiField(); + if(field != null) { + offset = field.getTextOffset(); + } + } + VirtualFile vFile = FileDocumentManager.getInstance().getFile(doc); + return new OpenFileDescriptor(myProject, vFile, offset); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java new file mode 100644 index 00000000000..3a45d87290c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditClassFiltersDialog.java @@ -0,0 +1,79 @@ +/* + * Class EditClassFiltersDialog + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ui.ClassFilterEditor; +import com.intellij.debugger.ClassFilter; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; + +public class EditClassFiltersDialog extends DialogWrapper { + private ClassFilterEditor myClassFilterEditor; + private ClassFilterEditor myClassExclusionFilterEditor; + private Project myProject; + private TreeClassChooserDialog.ClassFilter myChooserFilter; + + public EditClassFiltersDialog(Project project) { + this(project, null); + } + + public EditClassFiltersDialog(Project project, TreeClassChooserDialog.ClassFilter filter) { + super(project, true); + myChooserFilter = filter; + myProject = project; + setTitle("Class Filters"); + init(); + } + + + protected JComponent createCenterPanel() { + JPanel contentPanel = new JPanel(new BorderLayout()); + + Box mainPanel = Box.createHorizontalBox(); + + myClassFilterEditor = new ClassFilterEditor(myProject, myChooserFilter); + myClassFilterEditor.setPreferredSize(new Dimension(400, 200)); + myClassFilterEditor.setBorder(IdeBorderFactory.createTitledBorder("Class Filters")); + mainPanel.add(myClassFilterEditor); + + myClassExclusionFilterEditor = new ClassFilterEditor(myProject, myChooserFilter); + myClassExclusionFilterEditor.setPreferredSize(new Dimension(400, 200)); + myClassExclusionFilterEditor.setBorder(IdeBorderFactory.createTitledBorder("Class Exclusion Filters")); + mainPanel.add(myClassExclusionFilterEditor); + + contentPanel.add(mainPanel, BorderLayout.CENTER); + + return contentPanel; + } + + protected void dispose(){ + myClassFilterEditor.stopEditing(); + super.dispose(); + } + + public void setFilters(ClassFilter[] filters, ClassFilter[] inverseFilters) { + myClassFilterEditor.setFilters(filters); + myClassExclusionFilterEditor.setFilters(inverseFilters); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.breakpoints.EditClassFiltersDialog"; + } + + public ClassFilter[] getFilters() { + return myClassFilterEditor.getFilters(); + } + + public ClassFilter[] getExclusionFilters() { + return myClassExclusionFilterEditor.getFilters(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java new file mode 100644 index 00000000000..5117a1e6fae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java @@ -0,0 +1,67 @@ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.InstanceFilter; +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.ui.InstanceFilterEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; + +/** + * User: lex + * Date: Aug 29, 2003 + * Time: 2:44:38 PM + */ +public class EditInstanceFiltersDialog extends DialogWrapper{ + private InstanceFilterEditor myInstanceFilterEditor; + private Project myProject; + + public EditInstanceFiltersDialog (Project project) { + super(project, true); + myProject = project; + setTitle("Instance Filters"); + init(); + } + + protected JComponent createCenterPanel() { + JPanel contentPanel = new JPanel(new BorderLayout()); + + Box mainPanel = Box.createHorizontalBox(); + + myInstanceFilterEditor = new InstanceFilterEditor(myProject); + myInstanceFilterEditor.setPreferredSize(new Dimension(400, 200)); + myInstanceFilterEditor.setBorder(IdeBorderFactory.createTitledBorder("Instance Filters")); + mainPanel.add(myInstanceFilterEditor); + + contentPanel.add(mainPanel, BorderLayout.CENTER); + + return contentPanel; + } + + protected void dispose(){ + myInstanceFilterEditor.stopEditing(); + super.dispose(); + } + + public void setFilters(InstanceFilter[] filters) { + ClassFilter[] cFilters = InstanceFilter.createClassFilters(filters); + myInstanceFilterEditor.setFilters(cFilters); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.breakpoints.EditInstanceFiltersDialog"; + } + + public InstanceFilter[] getFilters() { + ClassFilter [] cFilters = myInstanceFilterEditor.getFilters(); + InstanceFilter [] ifilters = new InstanceFilter[cFilters.length]; + for (int i = 0; i < ifilters.length; i++) { + ifilters[i] = InstanceFilter.create(cFilters[i]); + } + return ifilters; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java new file mode 100644 index 00000000000..74feba9716c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java @@ -0,0 +1,102 @@ +/* + * Class ExceptionBreakpointPropertiesPanel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ide.util.TreeClassChooserDialog; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPanel { + private JCheckBox myNotifyCaughtCheckBox; + private JCheckBox myNotifyUncaughtCheckBox; + private Project myProject; + private ExceptionBreakpoint myExceptionBreakpoint; + + public ExceptionBreakpointPropertiesPanel(Project project) { + super(project); + myProject = project; + } + + protected TreeClassChooserDialog.ClassFilter createClassConditionFilter() { + return null; + } + + protected JComponent createSpecialBox() { + JPanel _panel, _panel0; + + myNotifyCaughtCheckBox = new JCheckBox("Caught exception"); + myNotifyCaughtCheckBox.setMnemonic('N'); + myNotifyUncaughtCheckBox = new JCheckBox("Uncaught exception"); + myNotifyUncaughtCheckBox.setMnemonic('o'); + + Box notificationsBox = Box.createVerticalBox(); + _panel = new JPanel(new BorderLayout()); + _panel.add(myNotifyCaughtCheckBox, BorderLayout.NORTH); + notificationsBox.add(_panel); + _panel = new JPanel(new BorderLayout()); + _panel.add(myNotifyUncaughtCheckBox, BorderLayout.NORTH); + notificationsBox.add(_panel); + + _panel = new JPanel(new BorderLayout()); + _panel0 = new JPanel(new BorderLayout()); + _panel0.add(notificationsBox, BorderLayout.CENTER); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.WEST); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.EAST); + _panel.add(_panel0, BorderLayout.NORTH); + _panel.setBorder(IdeBorderFactory.createTitledBorder("Notifications")); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + JCheckBox toCheck = null; + if (!myNotifyCaughtCheckBox.isSelected() && !myNotifyUncaughtCheckBox.isSelected()) { + Object source = e.getSource(); + if (myNotifyCaughtCheckBox.equals(source)) { + toCheck = myNotifyUncaughtCheckBox; + } + else if (myNotifyUncaughtCheckBox.equals(source)) { + toCheck = myNotifyCaughtCheckBox; + } + if (toCheck != null) { + toCheck.setSelected(true); + } + } + } + }; + myNotifyCaughtCheckBox.addActionListener(listener); + myNotifyUncaughtCheckBox.addActionListener(listener); + return _panel; + } + + protected void updateCheckboxes() { + super.updateCheckboxes(); + myPassCountCheckbox.setEnabled(!(myExceptionBreakpoint instanceof AnyExceptionBreakpoint)); + } + + public void initFrom(Breakpoint breakpoint) { + ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint; + myExceptionBreakpoint = exceptionBreakpoint; + super.initFrom(breakpoint); + + myNotifyCaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_CAUGHT); + myNotifyUncaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_UNCAUGHT); + } + + public void saveTo(Breakpoint breakpoint, Runnable afterUpdate) { + ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint; + exceptionBreakpoint.NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected(); + exceptionBreakpoint.NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected(); + + super.saveTo(breakpoint, afterUpdate); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java new file mode 100644 index 00000000000..845126d15a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java @@ -0,0 +1,312 @@ +/* + * Class FieldBreakpoint + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.jdi.VirtualMachineProxy; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.text.CharArrayUtil; +import com.sun.jdi.*; +import com.sun.jdi.event.AccessWatchpointEvent; +import com.sun.jdi.event.LocatableEvent; +import com.sun.jdi.event.ModificationWatchpointEvent; +import com.sun.jdi.request.AccessWatchpointRequest; +import com.sun.jdi.request.ModificationWatchpointRequest; +import org.jdom.Element; + +import javax.swing.*; +import java.util.List; + +public class FieldBreakpoint extends BreakpointWithHighlighter { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.FieldBreakpoint"); + public boolean WATCH_MODIFICATION = true; + public boolean WATCH_ACCESS = false; + private boolean myIsStatic; + private String myFieldName; + + private static Icon ourSetIcon = IconLoader.getIcon("/debugger/db_field_breakpoint.png"); + private static Icon ourDisabledIcon = IconLoader.getIcon("/debugger/db_disabled_field_breakpoint.png"); + private static Icon ourInvalidIcon = IconLoader.getIcon("/gutter/db_invalid_field_breakpoint.png"); + private static Icon ourVerifiedIcon = IconLoader.getIcon("/gutter/db_verified_field_breakpoint.png"); + + protected FieldBreakpoint(Project project) { + super(project); + } + + private FieldBreakpoint(Project project, RangeHighlighter highlighter, String fieldName) { + super(project, highlighter); + LOG.assertTrue(fieldName != null); + myFieldName = fieldName; + } + + public boolean isStatic() { + return myIsStatic; + } + + public String getFieldName() { + return myFieldName; + } + + + protected Icon getDisabledIcon() { return ourDisabledIcon; } + protected Icon getSetIcon () { return ourSetIcon; } + protected Icon getInvalidIcon () { return ourInvalidIcon; } + protected Icon getVerifiedIcon() { return ourVerifiedIcon; } + + public PsiField getPsiField() { + final PsiClass psiClass = getPsiClass(); + if(psiClass != null){ + PsiField field = psiClass.findFieldByName(myFieldName, true); + if(field != null) { + return field; + } + } + + return ApplicationManager.getApplication().runReadAction(new Computable() { + public PsiField compute() { + PsiElement element = getSourcePosition().getFile().findElementAt(getSourcePosition().getOffset()); + return PsiTreeUtil.getParentOfType(element, PsiField.class, false); + } + }); + } + + protected void reload(PsiFile psiFile) { + super.reload(psiFile); + PsiField field = getPsiField(); + if(field != null) { + myFieldName = field.getName(); + myIsStatic = field.hasModifierProperty(PsiModifier.STATIC); + } + if (myIsStatic) { + INSTANCE_FILTERS_ENABLED = false; + } + } + + protected boolean moveTo(SourcePosition position) { + PsiFile psiFile = position.getFile(); + Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); + + if(document == null) return false; + + final int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), position.getOffset(), " \t"); + PsiField field = PsiTreeUtil.getParentOfType(psiFile.findElementAt(offset), PsiField.class); + + if(field == null) return false; + + return super.moveTo(SourcePosition.createFromElement(field)); + } + + protected ObjectReference getThisObject(SuspendContextImpl context, LocatableEvent event) throws EvaluateException { + if (event instanceof ModificationWatchpointEvent) { + ModificationWatchpointEvent modificationEvent = (ModificationWatchpointEvent)event; + ObjectReference reference = modificationEvent.object(); + if (reference != null) { // non-static + return reference; + } + } + else if (event instanceof AccessWatchpointEvent) { + AccessWatchpointEvent accessEvent = (AccessWatchpointEvent)event; + ObjectReference reference = accessEvent.object(); + if (reference != null) { // non-static + return reference; + } + } + + return super.getThisObject(context, event); + } + + public void createRequestForPreparedClass(DebugProcessImpl debugProcess, + ReferenceType refType) { + VirtualMachineProxy vm = debugProcess.getVirtualMachineProxy(); + try { + Field field = refType.fieldByName(myFieldName); + if (field == null) { + debugProcess.getRequestsManager().setInvalid(this, "Cannot find field " + myFieldName + " in class " + refType.name()); + return; + } + RequestManagerImpl manager = debugProcess.getRequestsManager(); + if (WATCH_MODIFICATION && vm.canWatchFieldModification()) { + ModificationWatchpointRequest request = manager.createModificationWatchpointRequest(this, field); + debugProcess.getRequestsManager().enableRequest(request); + if (LOG.isDebugEnabled()) { + LOG.debug("Modification request added"); + } + } + if (WATCH_ACCESS && vm.canWatchFieldAccess()) { + AccessWatchpointRequest request = manager.createAccessWatchpointRequest(this, field); + debugProcess.getRequestsManager().enableRequest(request); + if (LOG.isDebugEnabled()) { + LOG.debug("Access request added field = "+field.name() + "; refType = "+refType.name()); + } + } + } + catch (ObjectCollectedException ex) { + LOG.debug(ex); + } + catch (Exception ex) { + LOG.debug(ex); + } + } + + public String getEventMessage(final LocatableEvent event) { + StringBuffer message = null; + if (event instanceof ModificationWatchpointEvent) { + ModificationWatchpointEvent modificationEvent = (ModificationWatchpointEvent)event; + message = new StringBuffer(64); + ObjectReference object = modificationEvent.object(); + if (object != null) { + message.append("{"); + } + message.append(modificationEvent.field().declaringType().name()); + if (object != null) { + message.append('@'); + message.append(object.uniqueID()); + message.append("}"); + } + message.append('.'); + message.append(myFieldName); + message.append(" will be modified. Current value = '"); + message.append(modificationEvent.valueCurrent()); + message.append("'; New value = '"); + message.append(modificationEvent.valueToBe()); + message.append("'\n"); + } + else if (event instanceof AccessWatchpointEvent) { + AccessWatchpointEvent accessEvent = (AccessWatchpointEvent)event; + message = new StringBuffer(32); + ObjectReference object = accessEvent.object(); + if (object != null) { + message.append("{"); + } + message.append(accessEvent.field().declaringType().name()); + if (object != null) { + message.append('@'); + message.append(object.uniqueID()); + message.append("}"); + } + message.append('.'); + message.append(myFieldName); + message.append(" will be accessed\n"); + } + return message != null ? message.toString() : null; + } + + public String getDisplayName() { + if(!isValid()) return "invalid field watchpoint"; + return "Field watchpoint, " + getClassName() + "." + myFieldName; + } + + public static FieldBreakpoint create(Project project, Document document, int lineIndex, String fieldName) { + FieldBreakpoint breakpoint = new FieldBreakpoint(project, createHighlighter(project, document, lineIndex), fieldName); + return (FieldBreakpoint)breakpoint.init(); + } + + public boolean isValid() { + return super.isValid() && ApplicationManager.getApplication().runReadAction(new Computable() { + public PsiField compute() { + return getPsiField(); + } + }) != null; + } + + public boolean isAt(Document document, int offset) { + PsiField field = findField(myProject, document, offset); + return field == getPsiField(); + } + + protected static FieldBreakpoint create(Project project, Field field, ObjectReference object) { + String fieldName = field.name(); + int line = 0; + Document document = null; + try { + List locations = field.declaringType().allLineLocations(); + if(locations.size() > 0) { + Location location = ((Location) locations.get(0)); + line = location.lineNumber(); + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(location.sourcePath()); + if(file != null) { + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if(psiFile != null) { + document = PsiDocumentManager.getInstance(project).getDocument(psiFile); + } + } + } + } + catch (AbsentInformationException e) { + LOG.debug(e); + } + catch (InternalError e) { + LOG.debug(e); + } + + if(document == null) return null; + + FieldBreakpoint fieldBreakpoint = new FieldBreakpoint(project, createHighlighter(project, document, line), fieldName); + if (!fieldBreakpoint.isStatic()) { + fieldBreakpoint.addInstanceFilter(object.uniqueID()); + } + return (FieldBreakpoint)fieldBreakpoint.init(); + } + + public static PsiField findField(Project project, Document document, int offset) { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if(file == null) return null; + offset = CharArrayUtil.shiftForward(document.getCharsSequence(), offset, " \t"); + PsiElement element = file.findElementAt(offset); + if(element == null) return null; + PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class, false); + int line = document.getLineNumber(offset); + if(field == null) { + final PsiField[] fld = new PsiField[] {null}; + DebuggerUtilsEx.iterateLine(project, document, line, new DebuggerUtilsEx.ElementVisitor() { + public boolean acceptElement(PsiElement element) { + PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class, false); + if(field != null) { + fld[0] = field; + return true; + } + return false; + } + }); + field = fld[0]; + } + + return field; + } + + public void readExternal(Element breakpointNode) throws InvalidDataException { + super.readExternal(breakpointNode); + myFieldName = breakpointNode.getAttributeValue("field_name"); + if(myFieldName == null) { + throw new InvalidDataException("No field name for field breakpoint"); + } + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + super.writeExternal(parentNode); + parentNode.setAttribute("field_name", getFieldName()); + } + + public PsiElement getEvaluationElement() { + return getPsiClass(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java new file mode 100644 index 00000000000..bbfedebcb82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java @@ -0,0 +1,89 @@ +/** + * class FieldBreakpointPropertiesPanel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiElement; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class FieldBreakpointPropertiesPanel extends BreakpointPropertiesPanel { + private JCheckBox myWatchAccessCheckBox; + private JCheckBox myWatchModificationCheckBox; + + public FieldBreakpointPropertiesPanel(final Project project) { + super(project); + } + + protected JComponent createSpecialBox() { + JPanel _panel; + JPanel _panel0; + myWatchAccessCheckBox = new JCheckBox("Field access"); + myWatchAccessCheckBox.setMnemonic('s'); + myWatchModificationCheckBox = new JCheckBox("Field modification"); + myWatchModificationCheckBox.setMnemonic('m'); + + + Box watchBox = Box.createVerticalBox(); + _panel = new JPanel(new BorderLayout()); + _panel.add(myWatchAccessCheckBox, BorderLayout.NORTH); + watchBox.add(_panel); + _panel = new JPanel(new BorderLayout()); + _panel.add(myWatchModificationCheckBox, BorderLayout.NORTH); + watchBox.add(_panel); + + _panel = new JPanel(new BorderLayout()); + _panel0 = new JPanel(new BorderLayout()); + _panel0.add(watchBox, BorderLayout.CENTER); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.WEST); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.EAST); + _panel.add(_panel0, BorderLayout.NORTH); + _panel.setBorder(IdeBorderFactory.createTitledBorder("Watch")); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + JCheckBox toCheck = null; + if (!myWatchAccessCheckBox.isSelected() && !myWatchModificationCheckBox.isSelected()) { + Object source = e.getSource(); + if (myWatchAccessCheckBox.equals(source)) { + toCheck = myWatchModificationCheckBox; + } + else if (myWatchModificationCheckBox.equals(source)) { + toCheck = myWatchAccessCheckBox; + } + if (toCheck != null) { + toCheck.setSelected(true); + } + } + } + }; + myWatchAccessCheckBox.addActionListener(listener); + myWatchModificationCheckBox.addActionListener(listener); + + return _panel; + } + + public void initFrom(Breakpoint breakpoint) { + super.initFrom(breakpoint); + FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint; + + myWatchAccessCheckBox.setSelected(fieldBreakpoint.WATCH_ACCESS); + myWatchModificationCheckBox.setSelected(fieldBreakpoint.WATCH_MODIFICATION); + } + + public void saveTo(Breakpoint breakpoint, Runnable afterUpdate) { + FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint; + + fieldBreakpoint.WATCH_ACCESS = myWatchAccessCheckBox.isSelected(); + fieldBreakpoint.WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected(); + + super.saveTo(breakpoint, afterUpdate); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java new file mode 100644 index 00000000000..e77f9c49314 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java @@ -0,0 +1,173 @@ +/** + * class FilteredRequestor + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.InstanceFilter; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.engine.requests.LocatableEventRequestor; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.util.*; +import com.intellij.psi.PsiElement; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.sun.jdi.BooleanValue; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.Value; +import com.sun.jdi.event.LocatableEvent; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; + +public abstract class FilteredRequestor implements LocatableEventRequestor, JDOMExternalizable { + public boolean COUNT_FILTER_ENABLED = false; + public int COUNT_FILTER = 0; + + public boolean CONDITION_ENABLED = false; + private TextWithImportsImpl myCondition = TextWithImportsImpl.EMPTY; + + public boolean CLASS_FILTERS_ENABLED = false; + private ClassFilter[] myClassFilters = ClassFilter.EMPTY_ARRAY; + private ClassFilter[] myClassExclusionFilters = ClassFilter.EMPTY_ARRAY; + + public boolean INSTANCE_FILTERS_ENABLED = false; + protected InstanceFilter[] myInstanceFilters = InstanceFilter.EMPTY_ARRAY; + + public FilteredRequestor() { + } + + public InstanceFilter[] getInstanceFilters() { + return myInstanceFilters; + } + + public void setInstanceFilters(InstanceFilter[] instanceFilters) { + myInstanceFilters = instanceFilters != null? instanceFilters : InstanceFilter.EMPTY_ARRAY; + } + + /** + * @return true if the ID was added or false otherwise + */ + public boolean hasObjectID(long id) { + for (int i = 0; i < myInstanceFilters.length; i++) { + InstanceFilter instanceFilter = myInstanceFilters[i]; + if (instanceFilter.getId() == id) { + return true; + } + } + return false; + } + + protected void addInstanceFilter(long l) { + final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1]; + System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length); + filters[myInstanceFilters.length] = InstanceFilter.create("" + l); + myInstanceFilters = filters; + } + + public final ClassFilter[] getClassFilters() { + return myClassFilters; + } + + public final void setClassFilters(ClassFilter[] classFilters) { + myClassFilters = classFilters != null? classFilters : ClassFilter.EMPTY_ARRAY; + } + + public ClassFilter[] getClassExclusionFilters() { + return myClassExclusionFilters; + } + + public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) { + myClassExclusionFilters = classExclusionFilters != null? classExclusionFilters : ClassFilter.EMPTY_ARRAY; + } + + public void readExternal(Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + String condition = JDOMExternalizerUtil.readField(parentNode, "myCondition"); + if (condition != null) { + setCondition(TextWithImportsImpl.createExpressionText(condition)); + } + + myClassFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren("filter")); + myClassExclusionFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren("exclusion_filter")); + + final ClassFilter [] instanceFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren("instance_id")); + final List iFilters = new ArrayList(instanceFilters.length); + + for (int i = 0; i < instanceFilters.length; i++) { + try { + iFilters.add(InstanceFilter.create(instanceFilters[i])); + } + catch (Exception e) { + } + } + myInstanceFilters = iFilters.toArray(new InstanceFilter[iFilters.size()]); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, parentNode); + JDOMExternalizerUtil.writeField(parentNode, "myCondition", getCondition().saveToString()); + DebuggerUtilsEx.writeFilters(parentNode, "filter", myClassFilters); + DebuggerUtilsEx.writeFilters(parentNode, "exclusion_filter", myClassExclusionFilters); + DebuggerUtilsEx.writeFilters(parentNode, "instance_id", InstanceFilter.createClassFilters(myInstanceFilters)); + } + + public boolean evaluateCondition(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + if(COUNT_FILTER_ENABLED) { + context.getDebugProcess().getVirtualMachineProxy().suspend(); + context.getDebugProcess().getRequestsManager().deleteRequest(this); + context.getDebugProcess().getRequestsManager().createRequest((Breakpoint)this); + context.getDebugProcess().getVirtualMachineProxy().resume(); + } + if (INSTANCE_FILTERS_ENABLED) { + Value value = context.getThisObject(); + if (value != null) { // non-static + ObjectReference reference = (ObjectReference)value; + if(!hasObjectID(reference.uniqueID())) return false; + } + } + + if (CONDITION_ENABLED && getCondition() != null && !"".equals(getCondition())) { + try { + ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new com.intellij.debugger.EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl.getInstance().build(getCondition(), getEvaluationElement()); + } + }); + Value value = evaluator.evaluate(context); + if (!(value instanceof BooleanValue)) { + throw EvaluateExceptionUtil.createEvaluateException("Type mismatch. Required boolean value"); + } + if(!((BooleanValue)value).booleanValue()) return false; + } catch (EvaluateException ex) { + if(ex.getCause() instanceof VMDisconnectedException) return false; + StringBuffer text = new StringBuffer(); + text.append("Failed to evaluate breakpoint condition\n'"); + text.append(getCondition()); + text.append("'\nReason: "); + text.append(ex.getMessage()); + throw EvaluateExceptionUtil.createEvaluateException(text.toString()); + } + return true; + } + + return true; + } + + public abstract PsiElement getEvaluationElement(); + + public TextWithImportsImpl getCondition() { + return myCondition; + } + + public void setCondition(TextWithImportsImpl condition) { + myCondition = condition; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java new file mode 100644 index 00000000000..91163a3d8c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -0,0 +1,258 @@ +/* + * Class LineBreakpoint + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.ClassFilter; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.ClassFilter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.sun.jdi.*; +import com.sun.jdi.event.LocatableEvent; +import com.sun.jdi.request.BreakpointRequest; + +import javax.swing.*; +import java.util.List; + +public class LineBreakpoint extends BreakpointWithHighlighter { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.LineBreakpoint"); + + // icons + private static Icon ourInvalidIcon = IconLoader.getIcon("/gutter/db_invalid_breakpoint.png"); + private static Icon ourSetIcon = IconLoader.getIcon("/gutter/db_set_breakpoint.png"); + private static Icon ourVerifiedIcon = IconLoader.getIcon("/gutter/db_verified_breakpoint.png"); + private static final Icon ourDisabledIcon = IconLoader.getIcon("/gutter/db_disabled_breakpoint.png"); + + private String myMethodName; + + protected LineBreakpoint(Project project) { + super(project); + } + + private LineBreakpoint(Project project, RangeHighlighter highlighter) { + super(project, highlighter); + } + + protected Icon getDisabledIcon() { return ourDisabledIcon; } + protected Icon getSetIcon () { return ourSetIcon; } + protected Icon getInvalidIcon () { return ourInvalidIcon; } + protected Icon getVerifiedIcon() { return ourVerifiedIcon; } + + protected void reload(PsiFile file) { + super.reload(file); + myMethodName = LineBreakpoint.findMethodName(file, getHighlighter().getStartOffset()); + } + + protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + List locs = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition()); + Location location = locs.size() > 0 ? locs.get(0) : null; + if (location != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Found location for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && location.method().isObsolete())); + } + BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(LineBreakpoint.this, location); + debugProcess.getRequestsManager().enableRequest(request); + if (LOG.isDebugEnabled()) { + LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex()); + } + } + else { + // there's no executable code in this class + debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, "No executable code found at line " + (getLineIndex() + 1) + " in class " + classType.name()); + if (LOG.isDebugEnabled()) { + LOG.debug("No locations of type " + classType.name() + " found at line " + getLineIndex()); + } + } + } + catch (ClassNotPreparedException ex) { + if (LOG.isDebugEnabled()) { + LOG.debug("ClassNotPreparedException: " + ex.getMessage()); + } + // there's a chance to add a breakpoint when the class is prepared + } + catch (ObjectCollectedException ex) { + if (LOG.isDebugEnabled()) { + LOG.debug("ObjectCollectedException: " + ex.getMessage()); + } + // there's a chance to add a breakpoint when the class is prepared + } + catch (InvalidLineNumberException ex) { + if (LOG.isDebugEnabled()) { + LOG.debug("InvalidLineNumberException: " + ex.getMessage()); + } + debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, "Line number is invalid"); + } + catch (InternalException ex) { + LOG.info(ex); + } + catch(Exception ex) { + LOG.info(ex); + } + updateUI(); + } + }); + } + + public boolean evaluateCondition(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + if(CLASS_FILTERS_ENABLED){ + Value value = context.getThisObject(); + ObjectReference thisObject = (ObjectReference)value; + if(thisObject == null) { + return false; + } + String name = DebuggerUtilsEx.getQualifiedClassName(thisObject.referenceType().name(), getProject()); + if(name == null) { + return false; + } + ClassFilter [] filters = getClassFilters(); + boolean matches = false; + for (int i = 0; i < filters.length; i++) { + ClassFilter classFilter = filters[i]; + if(classFilter.isEnabled() && classFilter.matches(name)) { + matches = true; + break; + } + } + if(!matches) { + return false; + } + + ClassFilter [] ifilters = getClassExclusionFilters(); + for (int i = 0; i < ifilters.length; i++) { + ClassFilter classFilter = ifilters[i]; + if(classFilter.isEnabled() && classFilter.matches(name)) { + return false; + } + } + } + return super.evaluateCondition(context, event); + } + + public String toString() { + return getDescription(); + } + + + public String getDisplayName() { + StringBuffer buffer = new StringBuffer(); + if(isValid()) { + buffer.append("Line breakpoint, "); + buffer.append(getClassName()); + if(myMethodName != null) { + buffer.append("."); + buffer.append(myMethodName); + } + } else { + buffer.append("invalid line breakpoint"); + } + return buffer.toString() + ", at line " + (getHighlighter().getDocument().getLineNumber(getHighlighter().getStartOffset()) + 1); + } + + private static String findMethodName(final PsiFile file, final int offset) { + if (!(file instanceof PsiJavaFile)) { + return null; + } + final PsiJavaFile javaFile = (PsiJavaFile)file; + final String[] rv = new String[]{""}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + PsiMethod method = DebuggerUtilsEx.findPsiMethod(javaFile, offset); + if (method != null) { + rv[0] = method.getName() + "()"; + } + } + }); + return rv[0]; + } + + public String getEventMessage(LocatableEvent event) { + final StringBuffer buf = new StringBuffer(64); + buf.append("Reached breakpoint"); + String name = event.location().declaringType().name(); + buf.append(" in class "); + buf.append(name); + buf.append(","); + buf.append(" at line "); + buf.append(getLineIndex() + 1); + return buf.toString(); + } + + public PsiElement getEvaluationElement() { + return PositionUtil.getContextElement(getSourcePosition()); + } + + protected static LineBreakpoint create(Project project, Document document, int lineIndex, boolean isVisible) { + VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + if (virtualFile == null) return null; + + LineBreakpoint breakpoint = new LineBreakpoint(project, createHighlighter(project, document, lineIndex)); + + if(!isVisible) { + document.getMarkupModel(project).removeHighlighter(breakpoint.getHighlighter()); + } + + breakpoint.setVisible(isVisible); + + return (LineBreakpoint)breakpoint.init(); + } + + public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex) { + final boolean[] canAdd = new boolean[]{false}; + + PsiDocumentManager.getInstance(project).commitDocument(document); + + DebuggerUtilsEx.iterateLine(project, document, lineIndex, new DebuggerUtilsEx.ElementVisitor() { + public boolean acceptElement(PsiElement element) { + if (!(element instanceof PsiWhiteSpace || element instanceof PsiComment)) { + PsiElement child = element; + while(element != null) { + LOG.assertTrue(element.getTextOffset() != -1, element.getContainingFile().getName()); + + if (document.getLineNumber(element.getTextOffset()) != lineIndex) { + break; + } + child = element; + element = element.getParent(); + } + + if(child instanceof PsiMethod && child.getTextRange().getEndOffset() >= document.getLineEndOffset(lineIndex)) { + PsiCodeBlock body = ((PsiMethod)child).getBody(); + if(body == null) { + canAdd[0] = false; + } + else { + PsiStatement[] statements = body.getStatements(); + canAdd[0] = statements.length > 0 && document.getLineNumber(statements[0].getTextOffset()) == lineIndex; + } + } + else { + canAdd[0] = true; + } + return true; + } + return false; + } + }); + + return canAdd[0]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java new file mode 100644 index 00000000000..6de6822d571 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java @@ -0,0 +1,16 @@ +/* + * Class LineBreakpointPropertiesPanel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +public class LineBreakpointPropertiesPanel extends BreakpointPropertiesPanel { + public LineBreakpointPropertiesPanel(Project project) { + super(project); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java new file mode 100644 index 00000000000..14ac4a2b1a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java @@ -0,0 +1,293 @@ +/* + * Class MethodBreakpoint + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JVMName; +import com.intellij.debugger.engine.JVMNameUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.requests.RequestManagerImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.util.text.CharArrayUtil; +import com.sun.jdi.Method; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.event.LocatableEvent; +import com.sun.jdi.event.MethodEntryEvent; +import com.sun.jdi.event.MethodExitEvent; +import com.sun.jdi.request.EventRequest; +import com.sun.jdi.request.MethodEntryRequest; +import com.sun.jdi.request.MethodExitRequest; + +import javax.swing.*; +import java.util.Iterator; +import java.util.Set; + +public class MethodBreakpoint extends BreakpointWithHighlighter { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.MethodBreakpoint"); + public boolean WATCH_ENTRY = true; + public boolean WATCH_EXIT = true; + + private String myMethodName; + private JVMName mySignature; + private boolean myIsStatic; + + private static Icon ourSetIcon = IconLoader.getIcon("/gutter/db_method_breakpoint.png"); + private static Icon ourDisabledIcon = IconLoader.getIcon("/gutter/db_disabled_method_breakpoint.png"); + private static Icon ourInvalidIcon = IconLoader.getIcon("/gutter/db_invalid_method_breakpoint.png"); + private static Icon ourVerifiedIcon = IconLoader.getIcon("/gutter/db_verified_method_breakpoint.png"); + + protected MethodBreakpoint(Project project) { + super(project); + } + + private MethodBreakpoint(Project project, RangeHighlighter highlighter) { + super(project, highlighter); + } + + public boolean isStatic() { + return myIsStatic; + } + + public PsiMethod getPsiMethod() { + Document document = getDocument(); + if(document == null) return null; + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if(psiFile instanceof PsiJavaFile) { + int line = getLineIndex(); + final int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), document.getLineStartOffset(line), " \t"); + PsiMethod method = DebuggerUtilsEx.findPsiMethod(psiFile, offset); + return method; + } + return null; + } + + public boolean isValid() { + return super.isValid() && myMethodName != null; + } + + protected void reload(PsiFile psiFile) { +// super.reload(psiFile); + myMethodName = null; + mySignature = null; + if(psiFile instanceof PsiJavaFile){ + MethodDescriptor descriptor = getMethodDescriptor(myProject, (PsiJavaFile)psiFile, getHighlighter().getDocument().getLineNumber(getHighlighter().getStartOffset())); + if (descriptor != null) { + myMethodName = descriptor.methodName; + mySignature = descriptor.methodSignature; + myIsStatic = descriptor.isStatic; + } + } + if (myIsStatic) { + INSTANCE_FILTERS_ENABLED = false; + } + } + + protected void createRequestForPreparedClass(DebugProcessImpl debugProcess, + ReferenceType classType) { + try { + boolean hasMethod = false; + for (Iterator iterator = classType.allMethods().iterator(); iterator.hasNext();) { + Method method = (Method)iterator.next(); + String signature = method.signature(); + String name = method.name(); + + if (myMethodName.equals(name) && mySignature.getName(debugProcess).equals(signature)) { + hasMethod = true; + break; + } + } + + if(!hasMethod) { + debugProcess.getRequestsManager().setInvalid(this, "Method not found in class " + classType.name()); + return; + } + + RequestManagerImpl requestManager = debugProcess.getRequestsManager(); + if (WATCH_ENTRY) { + MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class); + if (entryRequest == null) { + entryRequest = requestManager.createMethodEntryRequest(this); + } + else { + entryRequest.disable(); + } + //entryRequest.addClassFilter(myClassQualifiedName); + // use addClassFilter(ReferenceType) in order to stop on subclasses also! + entryRequest.addClassFilter(classType); + debugProcess.getRequestsManager().enableRequest(entryRequest); + } + if (WATCH_EXIT) { + MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class); + if (exitRequest == null) { + exitRequest = requestManager.createMethodExitRequest(this); + } + else { + exitRequest.disable(); + } + //exitRequest.addClassFilter(myClassQualifiedName); + exitRequest.addClassFilter(classType); + debugProcess.getRequestsManager().enableRequest(exitRequest); + } + } + catch (Exception e) { + LOG.debug(e); + } + } + + + public String getEventMessage(LocatableEvent event) { + final StringBuffer text = new StringBuffer(64); + text.append("Method \""); + if (event instanceof MethodEntryEvent) { + MethodEntryEvent entryEvent = (MethodEntryEvent)event; + text.append(entryEvent.method().declaringType().name()); + text.append("."); + text.append(entryEvent.method().name()); + text.append("()\" entered"); + } + else if (event instanceof MethodExitEvent) { + MethodExitEvent exitEvent = (MethodExitEvent)event; + text.append(exitEvent.method().declaringType().name()); + text.append("."); + text.append(exitEvent.method().name()); + text.append("()\" is about to exit"); + } + text.append("\n"); + return text.toString(); + } + + public PsiElement getEvaluationElement() { + return getPsiClass(); + } + + protected Icon getDisabledIcon() { return ourDisabledIcon; } + protected Icon getSetIcon () { return ourSetIcon; } + protected Icon getInvalidIcon () { return ourInvalidIcon; } + protected Icon getVerifiedIcon() { return ourVerifiedIcon; } + + public String getDisplayName() { + StringBuffer buffer = new StringBuffer(); + if(isValid()) { + buffer.append("Method breakpoint "); + buffer.append(getClassName()); + if(myMethodName != null) { + buffer.append("."); + buffer.append(myMethodName); + } + } else { + buffer.append("invalid method breakpoint"); + } + return buffer.toString(); + } + + public boolean evaluateCondition(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException { + Method method = null; + if (event instanceof MethodEntryEvent) { + MethodEntryEvent entryEvent = (MethodEntryEvent)event; + method = entryEvent.method(); + } + else if (event instanceof MethodExitEvent) { + MethodExitEvent exitEvent = (MethodExitEvent)event; + method = exitEvent.method(); + } + if (method == null) { + return false; + } + String signature = method.signature(); + String name = method.name(); + if (!(myMethodName.equals(name) && mySignature.getName(context.getDebugProcess()).equals(signature))) { + return false; + } + return super.evaluateCondition(context, event); + } + + public static MethodBreakpoint create(Project project, Document document, int lineIndex) { + MethodBreakpoint breakpoint = new MethodBreakpoint(project, createHighlighter(project, document, lineIndex)); + return (MethodBreakpoint)breakpoint.init(); + } + + + /* + not needed for a while + public static MethodBreakpoint create(Method method) { + return null; + } + */ + + /** + * finds FQ method's class name and method's signature + */ + private static MethodDescriptor getMethodDescriptor(final Project project, final PsiJavaFile psiJavaFile, final int line) { + final Document document = PsiDocumentManager.getInstance(project).getDocument(psiJavaFile); + if(document == null) return null; + final int endOffset = document.getLineEndOffset(line); + final MethodDescriptor[] descriptor = new MethodDescriptor[]{null}; + PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Runnable() { + public void run() { + try { + PsiMethod method = DebuggerUtilsEx.findPsiMethod(psiJavaFile, endOffset); + if(method == null || document.getLineNumber(method.getTextOffset()) < line) return; + + int methodNameOffset = method.getNameIdentifier().getTextOffset(); + descriptor[0] = new MethodDescriptor(); + descriptor[0].methodName = method.isConstructor() ? "" : method.getName(); + descriptor[0].methodSignature = JVMNameUtil.getJVMSignature(method); + descriptor[0].isStatic = method.hasModifierProperty(PsiModifier.STATIC); + descriptor[0].methodLine = document.getLineNumber(methodNameOffset); + } + catch (EvaluateException e) { + descriptor[0] = null; + } + } + }); + if (descriptor[0] == null) { + return null; + } + if (descriptor[0].methodName == null || descriptor[0].methodSignature == null) { + return null; + } + return descriptor[0]; + } + + private EventRequest findRequest(DebugProcessImpl debugProcess, Class requestClass) { + Set reqSet = debugProcess.getRequestsManager().findRequests(this); + for (Iterator iterator = reqSet.iterator(); iterator.hasNext();) { + EventRequest eventRequest = (EventRequest) iterator.next(); + if(eventRequest.getClass().equals(requestClass)) { + return eventRequest; + } + } + + return null; + } + + public String toString() { + return getDescription(); + } + + public boolean isBodyAt(Document document, int offset) { + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if(psiFile instanceof PsiJavaFile) { + PsiMethod method = DebuggerUtilsEx.findPsiMethod(psiFile, offset); + return method == getPsiMethod(); + } + + return false; + } + + private static final class MethodDescriptor { + String methodName; + JVMName methodSignature; + boolean isStatic; + int methodLine; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java new file mode 100644 index 00000000000..0af8ce4b528 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java @@ -0,0 +1,88 @@ +/** + * class MethodBreakpointPropertiesPanel + * @author Jeka + */ +package com.intellij.debugger.ui.breakpoints; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiElement; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MethodBreakpointPropertiesPanel extends BreakpointPropertiesPanel { + private JCheckBox myWatchEntryCheckBox; + private JCheckBox myWatchExitCheckBox; + + public MethodBreakpointPropertiesPanel(final Project project) { + super(project); + } + + protected JComponent createSpecialBox() { + JPanel _panel, _panel0; + + myWatchEntryCheckBox = new JCheckBox("Method entry"); + myWatchEntryCheckBox.setMnemonic('y'); + myWatchExitCheckBox = new JCheckBox("Method exit"); + myWatchExitCheckBox.setMnemonic('x'); + + Box watchBox = Box.createVerticalBox(); + _panel = new JPanel(new BorderLayout()); + _panel.add(myWatchEntryCheckBox, BorderLayout.NORTH); + watchBox.add(_panel); + _panel = new JPanel(new BorderLayout()); + _panel.add(myWatchExitCheckBox, BorderLayout.NORTH); + watchBox.add(_panel); + + _panel = new JPanel(new BorderLayout()); + _panel0 = new JPanel(new BorderLayout()); + _panel0.add(watchBox, BorderLayout.CENTER); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.WEST); + _panel0.add(Box.createHorizontalStrut(3), BorderLayout.EAST); + _panel.add(_panel0, BorderLayout.NORTH); + _panel.setBorder(IdeBorderFactory.createTitledBorder("Watch")); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + JCheckBox toCheck = null; + if (!myWatchEntryCheckBox.isSelected() && !myWatchExitCheckBox.isSelected()) { + Object source = e.getSource(); + if (myWatchEntryCheckBox.equals(source)) { + toCheck = myWatchExitCheckBox; + } + else if (myWatchExitCheckBox.equals(source)) { + toCheck = myWatchEntryCheckBox; + } + if (toCheck != null) { + toCheck.setSelected(true); + } + } + } + }; + myWatchEntryCheckBox.addActionListener(listener); + myWatchExitCheckBox.addActionListener(listener); + + return _panel; + } + + public void initFrom(Breakpoint breakpoint) { + super.initFrom(breakpoint); + MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint; + + myWatchEntryCheckBox.setSelected(methodBreakpoint.WATCH_ENTRY); + myWatchExitCheckBox.setSelected(methodBreakpoint.WATCH_EXIT); + } + + public void saveTo(Breakpoint breakpoint, Runnable afterUpdate) { + MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint; + + methodBreakpoint.WATCH_ENTRY = myWatchEntryCheckBox.isSelected(); + methodBreakpoint.WATCH_EXIT = myWatchExitCheckBox.isSelected(); + + super.saveTo(breakpoint, afterUpdate); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerComboBoxRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerComboBoxRenderer.java new file mode 100644 index 00000000000..36c3ee7d787 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerComboBoxRenderer.java @@ -0,0 +1,42 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicComboBoxRenderer; +import java.awt.*; + +public class DebuggerComboBoxRenderer extends BasicComboBoxRenderer { + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + + JLabel component = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (list.getComponentCount() > 0) { + Icon icon = getIcon(value); + if (icon != null) { + component.setIcon(icon); + } + } + return component; + } + + private Icon getIcon(Object item) { + if (item == null) { + return null; + } + if (item instanceof ThreadDescriptorImpl) { + ThreadDescriptorImpl descriptor = (ThreadDescriptorImpl)item; + return descriptor.getIcon(); + } + if (item instanceof StackFrameDescriptorImpl) { + return ((StackFrameDescriptorImpl)item).getIcon(); + } + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerPanel.java new file mode 100644 index 00000000000..4f4d6b8ec49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerPanel.java @@ -0,0 +1,140 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.MessageDescriptor; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.*; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.ui.PopupHandler; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.awt.*; + +public abstract class DebuggerPanel extends JPanel implements DataProvider{ + private final Project myProject; + private final DebuggerTree myTree; + private final DebuggerStateManager myStateManager; + private final DebuggerContextListener myContextListener; + private int myEvent = DebuggerSession.EVENT_REFRESH; + private boolean myNeedsRefresh = true; + + public DebuggerPanel(Project project, DebuggerStateManager stateManager) { + super(new BorderLayout()); + myProject = project; + myStateManager = stateManager; + myTree = createTreeView(); + myContextListener = new DebuggerContextListener() { + public void changeEvent(DebuggerContextImpl newContext, int event) { + DebuggerPanel.this.changeEvent(newContext, event); + } + }; + + myTree.addMouseListener(new PopupHandler(){ + public void invokePopup(Component comp,int x,int y){ + TreePath path = myTree.getLeadSelectionPath(); + + ActionPopupMenu popupMenu = createPopupMenu( + ); + if (popupMenu != null) { + popupMenu.getComponent().show(comp, x, y); + } + } + }); + setFocusTraversalPolicy(new IdeFocusTraversalPolicy() { + public Component getDefaultComponentImpl(Container focusCycleRoot) { + return myTree; + } + }); + myStateManager.addListener(myContextListener); + } + + protected abstract DebuggerTree createTreeView(); + + protected void changeEvent(DebuggerContextImpl newContext, int event) { + if(newContext.getDebuggerSession() == null) return; + + rebuildWhenVisible(event); + } + + protected boolean shouldRebuildNow() { + return true; + } + + public boolean isNeedsRefresh() { + return myNeedsRefresh; + } + + public final void rebuildWhenVisible() { + rebuildWhenVisible(myEvent); + } + + protected final void rebuildWhenVisible(int event) { + myEvent = event; + if(!shouldRebuildNow()) { + myNeedsRefresh = true; + } else { + myNeedsRefresh = false; + rebuild(event); + } + } + + protected void rebuild(int event) { + DebuggerSession debuggerSession = getContext().getDebuggerSession(); + if(debuggerSession == null) return; + + getTree().rebuild(getContext()); + } + + protected void showMessage(MessageDescriptor descriptor) { + myTree.showMessage(descriptor); + } + + public void dispose() { + myStateManager.removeListener(myContextListener); + myTree.dispose(); + } + + protected abstract ActionPopupMenu createPopupMenu(); + + public DebuggerContextImpl getContext() { + return myStateManager.getContext(); + } + + protected DebuggerTree getTree() { + return myTree; + } + + public void clear() { + myTree.removeAllChildren(); + } + + protected final Project getProject() { + return myProject; + } + + public DebuggerStateManager getContextManager() { + return myStateManager; + } + + public Object getData(String dataId) { + if (DebuggerActions.DEBUGGER_PANEL.equals(dataId)) { + return this; + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeBase.java new file mode 100644 index 00000000000..dcb54f89af3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeBase.java @@ -0,0 +1,293 @@ +/* + * Class DebuggerTreeBase + * @author Jeka + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.text.StringTokenizer; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; +import org.jdom.Element; +import org.jdom.output.XMLOutputter; + +import javax.swing.*; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.MouseEvent; + + +public class DebuggerTreeBase extends Tree { + private Project myProject; + private DebuggerTreeNodeImpl myCurrentTooltipNode; + private JComponent myCurrentTooltip; + protected final TipManager myTipManager; + + public DebuggerTreeBase(TreeModel model, Project project) { + super(model); + myProject = project; + putClientProperty("JTree.lineStyle", "Angled"); + setRootVisible(false); + setShowsRootHandles(true); + setCellRenderer(new DebuggerTreeRenderer()); + updateUI(); + myTipManager = new TipManager(this, new TipManager.TipFactory() { + public JComponent createToolTip(MouseEvent e) { + return DebuggerTreeBase.this.createToolTip(e); + } + }); + TreeUtil.installActions(this); + } + + private int getMaximumChars(String s, FontMetrics metrics, int maxWidth) { + int minChar = 0; + int maxChar = s.length(); + int chars; + while(minChar < maxChar) { + chars = (minChar + maxChar + 1) / 2; + int width = metrics.stringWidth(s.substring(0, chars)); + if(width <= maxWidth) { + minChar = chars; + } else { + maxChar = chars - 1; + } + } + return minChar; + } + + private JComponent createTipContent(String tipText) { + JToolTip tooltip = new JToolTip(); + + if(tipText == null) { + tooltip.setTipText(tipText); + } else { + Dimension rootSize = getVisibleRect().getSize(); + Insets borderInsets = tooltip.getBorder().getBorderInsets(tooltip); + rootSize.width -= (borderInsets.left + borderInsets.right) * 2; + rootSize.height -= (borderInsets.top + borderInsets.bottom) * 2; + + StringBuffer tipBuffer = new StringBuffer(tipText.length()); + StringTokenizer tokenizer = new StringTokenizer(tipText, "\n"); + while(tokenizer.hasMoreElements()) { + String line = tokenizer.nextToken(); + for (;;) { + int maximumChars = getMaximumChars(line, tooltip.getFontMetrics(tooltip.getFont()), rootSize.width); + if(maximumChars == line.length()) { + tipBuffer.append(line.substring(0, maximumChars)); + tipBuffer.append('\n'); + break; + } else { + + int chars; + for(chars = maximumChars - 2; chars > 1; chars --) { + if(getMaximumChars(line.substring(0, chars), tooltip.getFontMetrics(tooltip.getFont()), rootSize.width) < maximumChars) break; + } + tipBuffer.append(line.substring(0, chars)); + tipBuffer.append('\\'); + tipBuffer.append('\n'); + line = line.substring(maximumChars - 2); + } + } + } + + Element html = new Element("html"); + + String text = tipBuffer.toString(); + +/* int lastLine = 0; + for (int i = 0; i < text.length(); i++) { + if(text.charAt(i) == '\n') { +// Element p = new Element("p"); + Element pre = new Element("pre"); +// p.addContent(pre); + html.addContent(pre); + pre.setText(text.substring(lastLine, i)); + lastLine = i + 1; + } + } +// Element p = new Element("p"); + Element pre = new Element("pre"); +// p.addContent(pre); + html.addContent(pre); + pre.setText(text.substring(lastLine, text.length()));*/ + + Element p = new Element("pre"); + html.addContent(p); + p.setText(text); + + XMLOutputter outputter = JDOMUtil.createOutputter("\n"); + outputter.setExpandEmptyElements(true); + outputter.setNewlines(true); + outputter.setTextTrim(false); + outputter.setTrimAllWhite(false); + outputter.setLineSeparator("\n"); + outputter.setTextNormalize(false); + tooltip.setTipText(outputter.outputString(html)); + } + + tooltip.setBorder(null); + + return tooltip; + } + + public JComponent createToolTip(MouseEvent e) { + DebuggerTreeNodeImpl node = getNodeToShowTip(e); + if (node == null) return null; + + if(myCurrentTooltip != null && + myCurrentTooltip.isShowing() && + myCurrentTooltipNode == node) return myCurrentTooltip; + + myCurrentTooltipNode = node; + + JToolTip toolTip = new JToolTip(); + toolTip.setLayout(new BorderLayout()); + + String toolTipText = getTipText(node); + if(toolTipText == null) return null; + + JScrollPane scrollPane = new JScrollPane(createTipContent(toolTipText)); + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + toolTip.add(scrollPane); + + JComponent tipContent = createTipContent(toolTipText); + Rectangle tipRectangle = getTipRectangle(e, tipContent.getPreferredSize()); + if(toolTip.getBorder() != null) { + Insets borderInsets = toolTip.getBorder().getBorderInsets(this); + tipRectangle.setSize(tipRectangle.width + borderInsets.left + borderInsets.right, + tipRectangle.height + borderInsets.top + borderInsets.bottom); + } + Dimension tipSize = new Dimension(tipRectangle.getSize()); + + if(tipRectangle.getWidth() < tipContent.getPreferredSize().getWidth()) { + tipSize.height += scrollPane.getHorizontalScrollBar().getPreferredSize().height; + } + + if(tipRectangle.getHeight() < tipContent.getPreferredSize().getHeight()) { + tipSize.width += scrollPane.getVerticalScrollBar().getPreferredSize().width; + } + + if(!tipSize.equals(tipRectangle.getSize())) { + tipRectangle = getTipRectangle(e, tipSize); + } + + toolTip.setPreferredSize(tipRectangle.getSize()); + toolTip.setLocation(tipRectangle.getLocation()); + myCurrentTooltip = toolTip; + + return toolTip; + } + + private String getTipText(DebuggerTreeNodeImpl node) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + if (descriptor instanceof ValueDescriptorImpl) { + String text = ((ValueDescriptorImpl)descriptor).getLabel(); + if (text != null) { + if(StringUtil.startsWithChar(text, '{') && text.indexOf('}') > 0) { + int idx = text.indexOf('}'); + if(idx != text.length() - 1) { + text = text.substring(idx + 1); + } + } + + if(StringUtil.startsWithChar(text, '\"') && StringUtil.endsWithChar(text, '\"')) text = text.substring(1, text.length() - 1); + + if (text.length() > 0 && (text.indexOf('\n') >= 0 || !getVisibleRect().contains(getRowBounds(getRowForPath(new TreePath(node.getPath())))))) { + String tipText = prepareToolTipText(text); + return tipText; + } + } + } + return null; + } + + private DebuggerTreeNodeImpl getNodeToShowTip(MouseEvent event) { + TreePath path = getPathForLocation(event.getX(), event.getY()); + if (path != null) { + Object last = path.getLastPathComponent(); + if (last instanceof DebuggerTreeNodeImpl) return (DebuggerTreeNodeImpl)last; + } + + return null; + } + + private Rectangle getTipRectangle(MouseEvent event, Dimension tipContentSize) { + Rectangle nodeBounds = new Rectangle(event.getPoint()); + TreePath pathForLocation = getPathForLocation(event.getX(), event.getY()); + if(pathForLocation != null) { + nodeBounds = getPathBounds(pathForLocation); + } + + Rectangle contentRect = getVisibleRect(); + int x, y; + + int vgap = nodeBounds.height; + int height; + int width = Math.min(tipContentSize.width, contentRect.width); + if(event.getY() > contentRect.y + contentRect.height / 2) { + y = Math.max(contentRect.y, nodeBounds.y - tipContentSize.height - vgap); + height = Math.min(tipContentSize.height, nodeBounds.y - contentRect.y - vgap); + } else { + y = nodeBounds.y + nodeBounds.height + vgap; + height = Math.min(tipContentSize.height, contentRect.height - y); + } + + Dimension tipSize = new Dimension(width, height); + + x = event.getX() - width / 2; + if(x < contentRect.x) x = contentRect.x; + if(x + width > contentRect.x + contentRect.width) x = contentRect.x + contentRect.width - width; + + return new Rectangle(new Point(x, y), tipSize); + } + + private String prepareToolTipText(String text) { + int tabSize = CodeStyleSettingsManager.getSettings(myProject).getTabSize(StdFileTypes.JAVA); + if (tabSize < 0) tabSize = 0; + StringBuffer buf = new StringBuffer(); + boolean special = false; + for(int idx = 0; idx < text.length(); idx++) { + char c = text.charAt(idx); + if(special) { + if (c == 't') { // convert tabs to spaces + for (int i = 0; i < tabSize; i++) { + buf.append(' '); + } + } + else if (c == 'r') { // remove occurances of '\r' + } + else if (c == 'n') { + buf.append('\n'); + } + else { + buf.append('\\'); + buf.append(c); + } + special = false; + } else { + if(c == '\\') { + special = true; + } else { + buf.append(c); + } + } + } + + return buf.toString(); + } + + public void dispose() { + myTipManager.dispose(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java new file mode 100644 index 00000000000..948ec586f93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java @@ -0,0 +1,206 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleColoredText; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; + +public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.DebuggerTreeRenderer"); + + private static final Color myHighlightColor = new Color(128, 0, 0); + private static final Color myChangedValueHighlightColor = Color.blue; + private static final Color myEvaluatingHighlightColor = Color.lightGray; + private static final Color myExceptionHighlightColor = Color.red; + + private static Icon myThreadGroupIcon = IconLoader.getIcon("/debugger/threadGroup.png"); + private static Icon myCurrentThreadGroupIcon = IconLoader.getIcon("/debugger/threadGroupCurrent.png"); + private static Icon myValueIcon = IconLoader.getIcon("/debugger/value.png"); + private static Icon myArrayValueIcon = IconLoader.getIcon("/debugger/db_array.png"); + private static Icon myPrimitiveValueIcon = IconLoader.getIcon("/debugger/db_primitive.png"); + private static Icon myStaticFieldIcon = IconLoader.getIcon("/nodes/staticField.png"); + + private static Icon myStaticIcon = IconLoader.getIcon("/nodes/static.png"); + + private static Icon myErrorMessageIcon = IconLoader.getIcon("/debugger/db_error.png"); + private static Icon myInformationMessageIcon = IconLoader.getIcon("/compiler/information.png"); + + public DebuggerTreeRenderer() { + } + + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl) value; + + if(node.getText() != null) { + node.getText().appendToComponent(this); + } + + setIcon(node.getIcon()); + } + + public static Icon getDescriptorIcon(NodeDescriptorImpl descriptor) { + Icon nodeIcon = null; + if (descriptor instanceof ThreadGroupDescriptorImpl) { + nodeIcon = (((ThreadGroupDescriptorImpl)descriptor).isCurrent() ? myCurrentThreadGroupIcon : myThreadGroupIcon); + } + else if (descriptor instanceof ThreadDescriptorImpl) { + ThreadDescriptorImpl threadDescriptor = (ThreadDescriptorImpl)descriptor; + nodeIcon = threadDescriptor.getIcon(); + } + else if (descriptor instanceof StackFrameDescriptorImpl) { + StackFrameDescriptorImpl stackDescriptor = (StackFrameDescriptorImpl)descriptor; + nodeIcon = stackDescriptor.getIcon(); + } + else if (descriptor instanceof ValueDescriptorImpl) { + ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; + if (valueDescriptor instanceof FieldDescriptorImpl && ((FieldDescriptorImpl)valueDescriptor).isStatic()) { + nodeIcon = myStaticFieldIcon; + } + else if (valueDescriptor.isArray()) { + nodeIcon = myArrayValueIcon; + } + else if (valueDescriptor.isPrimitive()) { + nodeIcon = myPrimitiveValueIcon; + } + else { + nodeIcon = myValueIcon; + } + } + else if (descriptor instanceof MessageDescriptor) { + MessageDescriptor messageDescriptor = (MessageDescriptor)descriptor; + if (messageDescriptor.getKind() == MessageDescriptor.ERROR) { + nodeIcon = myErrorMessageIcon; + } + else if (messageDescriptor.getKind() == MessageDescriptor.INFORMATION) { + nodeIcon = myInformationMessageIcon; + } + else if (messageDescriptor.getKind() == MessageDescriptor.SPECIAL) { + nodeIcon = null; + } + } + else if (descriptor instanceof StaticDescriptorImpl) { + nodeIcon = myStaticIcon; + } + + return nodeIcon; + } + + public static SimpleColoredText getDescriptorText(NodeDescriptorImpl descriptor, boolean multiline) { + return getDescriptorText(descriptor, multiline, true); + } + + public static SimpleColoredText getDescriptorTitle(NodeDescriptorImpl descriptor) { + return getDescriptorText(descriptor, false, false); + } + + private static SimpleColoredText getDescriptorText(NodeDescriptorImpl descriptor, boolean multiline, boolean appendValue) { + SimpleColoredText descriptorText = new SimpleColoredText(); + + String text; + String nodeName; + + if (descriptor == null) { + text = ""; + nodeName = null; + } + else { + text = descriptor.getLabel(); + nodeName = descriptor.getName(); + } + + if(text.equals(NodeDescriptorImpl.EVALUATING_MESSAGE)) { + descriptorText.append(NodeDescriptorImpl.EVALUATING_MESSAGE, new SimpleTextAttributes(Font.PLAIN, myEvaluatingHighlightColor)); + return descriptorText; + } + + String[] strings = breakString(text, nodeName); + + SimpleTextAttributes dflt = new SimpleTextAttributes(Font.PLAIN, null); + + if (strings[0] != null) { + if (descriptor instanceof MessageDescriptor && ((MessageDescriptor)descriptor).getKind() == MessageDescriptor.SPECIAL) { + descriptorText.append(strings[0], new SimpleTextAttributes(Font.PLAIN, Color.lightGray)); + } + else { + descriptorText.append(strings[0], dflt); + } + } + if (strings[1] != null) { + descriptorText.append(strings[1], new SimpleTextAttributes(Font.PLAIN, myHighlightColor)); + } + if (strings[2] != null) { + if (descriptor instanceof ValueDescriptorImpl) { + if(multiline && strings[2].indexOf('\n') >=0) { + strings = breakString(strings[2], "="); + if(strings[2] != null) { + strings[2] = strings[0] + strings[1] + "\n" + strings[2]; + } + } + + + ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; + String valueLabel = valueDescriptor.getValueLabel(); + + strings = breakString(strings[2], valueLabel); + if (strings[0] != null) { + descriptorText.append(strings[0], dflt); + } + if (appendValue && strings[1] != null) { + if(valueLabel != null && StringUtil.startsWithChar(valueLabel, '{') && valueLabel.indexOf('}') > 0 && !StringUtil.endsWithChar(valueLabel, '}')) { + int idx = valueLabel.indexOf('}'); + String objectId = valueLabel.substring(0, idx + 1); + valueLabel = valueLabel.substring(idx + 1); + descriptorText.append(objectId, new SimpleTextAttributes(Font.PLAIN, myEvaluatingHighlightColor)); + } + + valueLabel = DebuggerUtilsEx.truncateString(valueLabel); + + if(descriptor.getEvaluateException() != null) { + String errorMessage = descriptor.getEvaluateException().getMessage(); + + if(valueLabel.endsWith(errorMessage)) { + descriptorText.append(valueLabel.substring(0, valueLabel.length() - errorMessage.length()), dflt); + descriptorText.append(errorMessage, new SimpleTextAttributes(Font.PLAIN, myExceptionHighlightColor)); + } + else { + descriptorText.append(valueLabel, valueDescriptor.isDirty() ? new SimpleTextAttributes(Font.PLAIN, myChangedValueHighlightColor) : dflt); + descriptorText.append(errorMessage, new SimpleTextAttributes(Font.PLAIN, myExceptionHighlightColor)); + } + } + else { + if(valueLabel.equals(NodeDescriptorImpl.EVALUATING_MESSAGE)) { + descriptorText.append(NodeDescriptorImpl.EVALUATING_MESSAGE, new SimpleTextAttributes(Font.PLAIN, myEvaluatingHighlightColor)); + } + else { + descriptorText.append(valueLabel, valueDescriptor.isDirty() ? new SimpleTextAttributes(Font.PLAIN, myChangedValueHighlightColor) : dflt); + } + } + } + } + else { + descriptorText.append(strings[2], dflt); + } + } + + return descriptorText; + } + + private static String[] breakString(String source, String substr) { + if (substr != null && substr.length() > 0) { + String prefix, suffix; + int index = Math.max(source.indexOf(substr), 0); + prefix = (index > 0)? source.substring(0, index) : null; + index += substr.length(); + suffix = (index < source.length() - 1)? source.substring(index) : null; + return new String[]{prefix, substr, suffix}; + } + return new String[]{source, null, null}; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FrameDebuggerTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FrameDebuggerTree.java new file mode 100644 index 00000000000..31cfb1160d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FrameDebuggerTree.java @@ -0,0 +1,151 @@ +/* + * Class FrameDebuggerTree + * @author Jeka + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.engine.SuspendManager; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.settings.ViewsGeneralSettings; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.util.ui.tree.TreeModelAdapter; +import com.intellij.debugger.DebuggerInvocationUtil; + +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.util.Enumeration; + +public class FrameDebuggerTree extends DebuggerTree { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.FrameDebuggerTree"); + private boolean myAnyNewLocals; + + public FrameDebuggerTree(Project project) { + super(project); + } + + protected void build(DebuggerContextImpl context) { + myAnyNewLocals = false; + buildWhenPaused(context, new RefreshFrameTreeCommand(context)); + } + + public void restoreNodeState(DebuggerTreeNodeImpl node) { + if(myAnyNewLocals) { + node.getDescriptor().myIsSelected = node.getDescriptor().myIsSelected && node.getDescriptor() instanceof LocalVariableDescriptorImpl; + } + super.restoreNodeState(node); + if(myAnyNewLocals && node.getDescriptor().myIsExpanded) { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getMutableModel().getRoot(); + DebuggerTreeNodeImpl lastSelected = null; + for(Enumeration children = root.children(); children.hasMoreElements();) { + DebuggerTreeNodeImpl child = children.nextElement(); + if(child.getDescriptor().myIsSelected) { + lastSelected = child; + } + } + + if(lastSelected != null) { + scrollPathToVisible(new TreePath(lastSelected.getPath())); + } + } + } + + private class RefreshFrameTreeCommand extends RefreshDebuggerTreeCommand { + public RefreshFrameTreeCommand(DebuggerContextImpl context) { + super(context); + } + + public void threadAction() { + super.threadAction(); + DebuggerTreeNodeImpl rootNode; + + final ThreadReferenceProxyImpl currentThread = getDebuggerContext().getThreadProxy(); + if(currentThread == null) return; + + try { + StackFrameProxyImpl frame = getDebuggerContext().getFrameProxy(); + + if (frame != null) { + NodeManagerImpl nodeManager = getNodeFactory(); + rootNode = nodeManager.createNode(nodeManager.getStackFrameDescriptor(null, frame), getDebuggerContext().createEvaluationContext()); + } else { + rootNode = getNodeFactory().getDefaultNode(); + SuspendManager suspendManager = getSuspendContext().getDebugProcess().getSuspendManager(); + if(suspendManager.isSuspended(currentThread)) { + try { + if(currentThread.frameCount() == 0) { + rootNode.add(MessageDescriptor.THREAD_IS_EMPTY); + } else { + rootNode.add(MessageDescriptor.DEBUG_INFO_UNAVAILABLE); + } + } + catch (EvaluateException e) { + rootNode.add(new MessageDescriptor(e.getMessage())); + } + } else { + rootNode.add(MessageDescriptor.THREAD_IS_RUNNING); + } + } + } + catch (Exception ex) { + if (LOG.isDebugEnabled()) { + LOG.debug(ex); + } + rootNode = getNodeFactory().getDefaultNode(); + rootNode.add(MessageDescriptor.DEBUG_INFO_UNAVAILABLE); + } + + final DebuggerTreeNodeImpl rootNode1 = rootNode; + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getMutableModel().setRoot(rootNode1); + treeChanged(); + + getModel().addTreeModelListener(new TreeModelAdapter() { + public void treeStructureChanged(TreeModelEvent e) { + Object[] path = e.getPath(); + if(path.length > 0 && path[path.length - 1] == rootNode1) { + if(ViewsGeneralSettings.getInstance().AUTOSCROLL_TO_NEW_LOCALS) { + autoscrollToNewLocals(rootNode1); + } + } + } + }); + } + private void autoscrollToNewLocals(DebuggerTreeNodeImpl frameNode) { + for (Enumeration e = frameNode.rawChildren(); e.hasMoreElements();) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)e.nextElement(); + NodeDescriptorImpl descriptor = child.getDescriptor(); + if(descriptor != null) { + if (descriptor instanceof LocalVariableDescriptorImpl) { + if (((LocalVariableDescriptorImpl) descriptor).isNewLocal() && getDebuggerContext().getDebuggerSession().isSteppingThrough(getDebuggerContext().getThreadProxy())) { + TreePath treePath = new TreePath(child.getPath()); + addSelectionPath (treePath); + scrollPathToVisible(treePath); + myAnyNewLocals = true; + descriptor.myIsSelected = true; + } + else { + removeSelectionPath(new TreePath(child.getPath())); + descriptor.myIsSelected = false; + } + ((LocalVariableDescriptorImpl) descriptor).setNewLocal(false); + } + } + } + } + }); + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FramePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FramePanel.java new file mode 100644 index 00000000000..ab562292b73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/FramePanel.java @@ -0,0 +1,294 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.actions.DebuggerAction; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.jdi.StackFrameProxy; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.SuspendManagerUtil; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerContextUtil; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.debugger.DebuggerInvocationUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; + +public class FramePanel extends DebuggerPanel implements DataProvider{ + private JComboBox myThreadsCombo; + private JComboBox myFramesCombo; + private ThreadsListener myThreadsListener; + private FramesListener myFramesListener; + + public FramePanel(Project project, DebuggerStateManager stateManager) { + super(project, stateManager); + myThreadsCombo = new JComboBox(); + myFramesCombo = new JComboBox(); + myThreadsCombo.setRenderer(new DebuggerComboBoxRenderer()); + myFramesCombo.setRenderer(new DebuggerComboBoxRenderer()); + myThreadsListener = new ThreadsListener(); + myFramesListener = new FramesListener(); + myThreadsCombo.addItemListener(myThreadsListener); + myFramesCombo.addActionListener(myFramesListener); + + Splitter splitter = new Splitter(); + splitter.setPreferredSize(new Dimension(-1, 23)); + splitter.setFirstComponent(new ComboPager(myFramesCombo, this)); + splitter.setSecondComponent(myThreadsCombo); + + this.add(splitter, BorderLayout.NORTH); + + add(new JScrollPane(getFrameTree()), BorderLayout.CENTER); + + DebuggerAction.installEditAction(getFrameTree(), DebuggerActions.EDIT_NODE_SOURCE); + } + + protected void rebuild(int event) { + myThreadsCombo.removeAllItems(); + myFramesCombo.removeAllItems(); + + getContext().getDebugProcess().getManagerThread().invokeLater(new RefreshFramePanelCommand()); + + super.rebuild(event); + } + + protected DebuggerTree createTreeView() { + return new FrameDebuggerTree(getProject()); + } + + protected void showMessage(MessageDescriptor messageDescriptor) { + myThreadsCombo.removeAllItems(); + myFramesCombo.removeAllItems(); + super.showMessage(messageDescriptor); + } + + protected ActionPopupMenu createPopupMenu() { + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.FRAME_PANEL_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.FRAME_PANEL_POPUP, group); + return popupMenu; + } + + public Object getData(String dataId) { + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return "debugging.debugFrame"; + } + return super.getData(dataId); + } + + public void dispose() { + super.dispose(); + myThreadsCombo.removeItemListener(myThreadsListener); + } + + private void selectThread(ThreadReferenceProxyImpl toSelect) { + int count = myThreadsCombo.getItemCount(); + for (int idx = 0; idx < count; idx++) { + ThreadDescriptorImpl item = (ThreadDescriptorImpl)myThreadsCombo.getItemAt(idx); + if (toSelect.equals(item.getThreadReference())) { + if (!item.equals(myThreadsCombo.getSelectedItem())) { + myThreadsCombo.setSelectedIndex(idx); + } + return; + } + } + } + + private void selectFrame(StackFrameProxy frame) { + int count = myFramesCombo.getItemCount(); + for (int idx = 0; idx < count; idx++) { + StackFrameDescriptorImpl item = (StackFrameDescriptorImpl)myFramesCombo.getItemAt(idx); + if (frame.equals(item.getStackFrame())) { + if (!item.equals(myFramesCombo.getSelectedItem())) { + myFramesCombo.setSelectedIndex(idx); + } + return; + } + } + } + + private class ThreadsListener implements ItemListener{ + boolean myIsEnabled = true; + + public void setEnabled(boolean enabled) { + myIsEnabled = enabled; + } + + public void itemStateChanged(ItemEvent e) { + if(!myIsEnabled) return; + if (e.getStateChange() == ItemEvent.SELECTED) { + ThreadDescriptorImpl item = (ThreadDescriptorImpl)e.getItem(); + DebuggerContextUtil.setThread(getContextManager(), item); + } + } + + } + + private class FramesListener implements ActionListener{ + boolean myIsEnabled = true; + + public void setEnabled(boolean enabled) { + myIsEnabled = enabled; + } + + public void actionPerformed(ActionEvent e) { + if(!myIsEnabled) return; + JComboBox combo = (JComboBox) e.getSource(); + StackFrameDescriptorImpl item = (StackFrameDescriptorImpl)combo.getSelectedItem(); + + if(item != null) { + DebuggerContextUtil.setStackFrame(getContextManager(), item.getStackFrame()); + } + } + } + + public FrameDebuggerTree getFrameTree() { + return (FrameDebuggerTree) getTree(); + } + + private class RefreshFramePanelCommand extends DebuggerContextCommandImpl { + private final DebuggerContextImpl myDebuggerContext; + + public RefreshFramePanelCommand() { + super(getContext()); + myDebuggerContext = getContext(); + } + + public DebuggerContextImpl getDebuggerContext() { + return myDebuggerContext; + } + + private java.util.List getThreadList() { + final java.util.List threads = new ArrayList(getSuspendContext().getDebugProcess().getVirtualMachineProxy().allThreads()); + Collections.sort(threads, ThreadReferenceProxyImpl.ourComparator); + + final java.util.List descriptors = new ArrayList(threads.size()); + EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + + for (Iterator iterator = threads.iterator(); iterator.hasNext();) { + ThreadReferenceProxyImpl thread = iterator.next(); + + ThreadDescriptorImpl threadDescriptor = new ThreadDescriptorImpl(thread); + threadDescriptor.setContext(evaluationContext); + threadDescriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); + descriptors.add(threadDescriptor); + } + return descriptors; + } + + public void threadAction() { + final ThreadReferenceProxyImpl threadToSelect = getDebuggerContext().getThreadProxy(); + if(threadToSelect == null) return; + + final java.util.List threadItems = getThreadList(); + + SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(getDebuggerContext().getSuspendContext(), threadToSelect); + getDebuggerContext().getDebugProcess().getManagerThread().invokeLater(new RefreshFramesListCommand(getDebuggerContext(), threadContext)); + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + try { + myThreadsListener.setEnabled(false); + + myThreadsCombo.removeAllItems(); + for (Iterator iterator = threadItems.iterator(); iterator.hasNext();) { + myThreadsCombo.addItem(iterator.next()); + } + + selectThread(threadToSelect); + } + finally { + myThreadsListener.setEnabled(true); + } + } + }); + } + } + + private class RefreshFramesListCommand extends SuspendContextCommandImpl { + private final DebuggerContextImpl myDebuggerContext; + + public RefreshFramesListCommand(DebuggerContextImpl debuggerContext, SuspendContextImpl suspendContext) { + super(suspendContext); + myDebuggerContext = debuggerContext; + } + + public void contextAction() throws Exception { + final java.util.List frameItems = getFrameList(myDebuggerContext.getThreadProxy()); + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + try { + myFramesListener.setEnabled(false); + myFramesCombo.removeAllItems(); + for (Iterator iterator = frameItems.iterator(); iterator.hasNext();) { + myFramesCombo.addItem(iterator.next()); + } + if(getDebuggerContext().getFrameProxy() != null) { + selectFrame(getDebuggerContext().getFrameProxy()); + } + } finally { + myFramesListener.setEnabled(true); + } + } + }); + + } + + private java.util.List getFrameList(ThreadReferenceProxyImpl thread) { + if(!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) return (java.util.List)Collections.EMPTY_LIST; + + java.util.List frames; + try { + frames = thread.frames(); + } + catch (EvaluateException e) { + frames = new ArrayList(); + } + + final java.util.List frameItems = new ArrayList(frames.size()); + + EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + for (Iterator iterator = frames.iterator(); iterator.hasNext();) { + StackFrameProxyImpl stackFrameProxy = iterator.next(); + StackFrameDescriptorImpl descriptor = new StackFrameDescriptorImpl(stackFrameProxy); + descriptor.setContext(evaluationContext); + descriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); + frameItems.add(descriptor); + } + + return frameItems; + } + + public DebuggerContextImpl getDebuggerContext() { + return myDebuggerContext; + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDebuggerTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDebuggerTree.java new file mode 100644 index 00000000000..5cf7108cb69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDebuggerTree.java @@ -0,0 +1,56 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.DebuggerInvocationUtil; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class InspectDebuggerTree extends DebuggerTree{ + private NodeDescriptorImpl myInspectDescriptor; + + public InspectDebuggerTree(Project project) { + super(project); + } + + protected void build(DebuggerContextImpl context) { + updateNode(context); + } + + public void setInspectDescriptor(NodeDescriptorImpl inspectDescriptor) { + myInspectDescriptor = inspectDescriptor; + } + + private void updateNode(final DebuggerContextImpl context) { + context.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(context) { + public void threadAction() { + final DebuggerTreeNodeImpl node = getNodeFactory().createNode(myInspectDescriptor, context.createEvaluationContext()); + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); + root.removeAllChildren(); + + root.add(node); + treeChanged(); + } + }); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDialog.java new file mode 100644 index 00000000000..367eec67037 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectDialog.java @@ -0,0 +1,66 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.impl.DebuggerContextListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; + +public class InspectDialog extends DialogWrapper implements DebuggerContextListener { + private InspectPanel myInspectView; + private Project myProject; + private DebuggerContextImpl myDebuggerContext; + + public InspectDialog(Project project, DebuggerStateManager stateManager, String title, NodeDescriptorImpl inspectDescriptor) { + super(project, true); + setTitle(title); + setModal(false); + + myDebuggerContext = stateManager.getContext(); + myProject = project; + + myInspectView = new InspectPanel(myProject, myDebuggerContext.getDebuggerSession().getContextManager(), inspectDescriptor); + myInspectView.setBorder(BorderFactory.createEtchedBorder()); + + init(); + + myDebuggerContext.getDebuggerSession().getContextManager().addListener(this); + getInspectView().rebuildWhenVisible(); + } + + protected JComponent createCenterPanel() { + return myInspectView; + } + + protected JComponent createSouthPanel() { + return null; + } + + protected void dispose() { + myDebuggerContext.getDebuggerSession().getContextManager().removeListener(this); + if (myInspectView != null) { + myInspectView.dispose(); + myInspectView = null; + } + super.dispose(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.debugger.ui.impl.InspectDialog"; + } + + public InspectPanel getInspectView() { + return myInspectView; + } + + public void changeEvent(DebuggerContextImpl newContext, int event) { + if(event == DebuggerSession.EVENT_DETACHED) { + close(CANCEL_EXIT_CODE); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectPanel.java new file mode 100644 index 00000000000..c3e1a129086 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/InspectPanel.java @@ -0,0 +1,49 @@ +/* + * Class InspectPanel + * @author Jeka + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.actions.DebuggerAction; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; + +public class InspectPanel extends DebuggerPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.InspectPanel"); + + public InspectPanel(Project project, DebuggerStateManager stateManager, NodeDescriptorImpl inspectDescriptor) { + super(project, stateManager); + LOG.assertTrue(inspectDescriptor != null); + + getInspectTree().setInspectDescriptor(inspectDescriptor); + + add(new JScrollPane(getInspectTree()), BorderLayout.CENTER); + DebuggerAction.installEditAction(getInspectTree(), DebuggerActions.EDIT_NODE_SOURCE); + } + + + protected DebuggerTree createTreeView() { + return new InspectDebuggerTree(getProject()); + } + + protected ActionPopupMenu createPopupMenu() { + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.INSPECT_PANEL_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.INSPECT_PANEL_POPUP, group); + return popupMenu; + } + + public InspectDebuggerTree getInspectTree() { + return (InspectDebuggerTree)getTree(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/MainWatchPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/MainWatchPanel.java new file mode 100644 index 00000000000..17b868b9d30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/MainWatchPanel.java @@ -0,0 +1,97 @@ +/** + * created at Dec 17, 2001 + * @author Jeka + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.ui.*; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.ui.ListenerUtil; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class MainWatchPanel extends WatchPanel implements DataProvider { + private KeyStroke myRemoveWatchAccelerator = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0); + private KeyStroke myNewWatchAccelerator = KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0); + private KeyStroke myEditWatchAccelerator = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0); + + public MainWatchPanel(Project project, DebuggerStateManager stateManager) { + super(project,stateManager); + AnAction removeWatchesAction = ActionManager.getInstance().getAction(DebuggerActions.REMOVE_WATCH); + removeWatchesAction.registerCustomShortcutSet(new CustomShortcutSet(myRemoveWatchAccelerator), getWatchTree()); + + AnAction newWatchAction = ActionManager.getInstance().getAction(DebuggerActions.NEW_WATCH); + newWatchAction.registerCustomShortcutSet(new CustomShortcutSet(myNewWatchAccelerator), getWatchTree()); + + ListenerUtil.addMouseListener(getWatchTree(), new MouseAdapter(){ + public void mouseClicked(MouseEvent e) { + if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { + AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH); + Presentation presentation = (Presentation)editWatchAction.getTemplatePresentation().clone(); + DataContext context = DataManager.getInstance().getDataContext(getWatchTree()); + + AnActionEvent actionEvent = new AnActionEvent(null, context, "WATCH_TREE", presentation, ActionManager.getInstance(), 0); + editWatchAction.actionPerformed(actionEvent); + } + } + }); + + AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH); + editWatchAction.registerCustomShortcutSet(new CustomShortcutSet(myEditWatchAccelerator), getWatchTree()); + } + + protected ActionPopupMenu createPopupMenu() { + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.WATCH_PANEL_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.WATCH_PANEL_POPUP, group); + return popupMenu; + } + + public void newWatch() { + final DebuggerTreeNodeImpl node = getWatchTree().addWatch(TextWithImportsImpl.EMPTY); + + editNode(node); + } + + public void editNode(final DebuggerTreeNodeImpl node) { + final DebuggerContextImpl context = getContext(); + final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(getProject(), PositionUtil.getContextElement(context), "evaluation"); + comboBox.setText((TextWithImportsImpl)((WatchItemDescriptor)node.getDescriptor()).getEvaluationText()); + + DebuggerTree.InplaceEditor editor = new DebuggerTree.InplaceEditor(node) { + public JComponent createEditorComponent() { + return comboBox; + } + + public JComponent getContentComponent() { + return comboBox.getPreferredFocusedComponent(); + } + + public Editor getEditor() { + return comboBox.getEditor(); + } + + public void doOKAction() { + TextWithImportsImpl text = comboBox.getText(); + WatchDebuggerTree.setWatchNodeText(node, text); + comboBox.addRecent(text); + super.doOKAction(); + } + }; + editor.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java new file mode 100644 index 00000000000..6b758943e1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java @@ -0,0 +1,191 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.settings.ThreadsViewSettings; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.debugger.DebuggerInvocationUtil; +import org.apache.log4j.lf5.viewer.categoryexplorer.TreeModelAdapter; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.util.*; + +/** + * User: lex + * Date: Sep 26, 2003 + * Time: 5:57:58 PM + */ +public class ThreadsDebuggerTree extends DebuggerTree { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.ThreadsDebuggerTree"); + + public ThreadsDebuggerTree(Project project) { + super(project); + } + + protected boolean isExpandable(DebuggerTreeNodeImpl node) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + if(descriptor instanceof StackFrameDescriptorImpl) return false; + + return descriptor.isExpandable(); + } + + protected void build(DebuggerContextImpl context) { + buildWhenPaused(context, new RefreshThreadsTreelCommand(context)); + } + + private class RefreshThreadsTreelCommand extends RefreshDebuggerTreeCommand{ + public RefreshThreadsTreelCommand(DebuggerContextImpl context) { + super(context); + } + + public void threadAction() { + super.threadAction(); + final DebuggerTreeNodeImpl root = getNodeFactory().getDefaultNode(); + + try { + DebugProcessImpl debugProcess = getDebuggerContext().getDebugProcess(); + if(debugProcess == null || !debugProcess.isAttached()) return; + + ThreadReferenceProxyImpl currentThread = ThreadsViewSettings.getInstance().SHOW_CURRENT_THREAD ? getSuspendContext().getThread() : null; + VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy(); + + EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + + if (currentThread != null && ThreadsViewSettings.getInstance().SHOW_THREAD_GROUPS) { + ThreadGroupReferenceProxyImpl topCurrentGroup = null; + + if (currentThread != null) { + topCurrentGroup = currentThread.threadGroupProxy(); + for(;;) { + ThreadGroupReferenceProxyImpl parentGroup = topCurrentGroup.parent(); + if(parentGroup != null) { + topCurrentGroup = parentGroup; + } + else { + break; + } + } + + if(topCurrentGroup != null){ + NodeManagerImpl nodeManager = getNodeFactory(); + root.add(nodeManager.createNode(nodeManager.getThreadGroupDescriptor(null, topCurrentGroup), evaluationContext)); + } else { + NodeManagerImpl nodeManager = getNodeFactory(); + root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext)); + } + } + + for (Iterator it = vm.topLevelThreadGroups().iterator(); it.hasNext();) { + ThreadGroupReferenceProxyImpl group = (ThreadGroupReferenceProxyImpl)it.next(); + NodeManagerImpl nodeManager = getNodeFactory(); + if(group != topCurrentGroup) { + DebuggerTreeNodeImpl threadGroup = nodeManager.createNode(nodeManager.getThreadGroupDescriptor(null, group), evaluationContext); + root.add(threadGroup); + } + } + } + else { + // do not show thread groups + if (currentThread != null) { + NodeManagerImpl nodeManager = getNodeFactory(); + root.insert(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext), 0); + } + List allThreads = new ArrayList(vm.allThreads()); + Collections.sort(allThreads, ThreadReferenceProxyImpl.ourComparator); + + for (Iterator it = allThreads.iterator(); it.hasNext();) { + ThreadReferenceProxyImpl threadProxy = (ThreadReferenceProxyImpl)it.next(); + if (threadProxy.equals(currentThread)) { + continue; + } + NodeManagerImpl nodeManager = getNodeFactory(); + root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, threadProxy), evaluationContext)); + } + } + } + catch (Exception ex) { + root.add( MessageDescriptor.DEBUG_INFO_UNAVAILABLE); + if (LOG.isDebugEnabled()) { + LOG.debug(ex); + } + } + + final ThreadReferenceProxyImpl thread = getSuspendContext().getThread(); + final List groups = new ArrayList(); + if (ThreadsViewSettings.getInstance().SHOW_THREAD_GROUPS) { + for(ThreadGroupReferenceProxyImpl group = thread.threadGroupProxy(); group != null; group = group.parent()) { + groups.add(group); + } + } + Collections.reverse(groups); + + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getMutableModel().setRoot(root); + treeChanged(); + selectThread(groups, thread); + } + }); + } + + private void selectThread(final List pathToThread, final ThreadReferenceProxyImpl thread) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + + + class MyTreeModelAdapter extends TreeModelAdapter { + private void structureChanged(DebuggerTreeNodeImpl node) { + for(Enumeration enumeration = node.children(); enumeration.hasMoreElements(); ) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)enumeration.nextElement(); + nodeChanged(child); + } + } + + private void nodeChanged(DebuggerTreeNodeImpl debuggerTreeNode) { + if(pathToThread.size() == 0) { + if(debuggerTreeNode.getDescriptor() instanceof ThreadDescriptorImpl && ((ThreadDescriptorImpl) debuggerTreeNode.getDescriptor()).getThreadReference() == thread) { + setSelectionPath(new TreePath(debuggerTreeNode.getPath())); + removeListener(); + } + } + else { + if(debuggerTreeNode.getDescriptor() instanceof ThreadGroupDescriptorImpl && ((ThreadGroupDescriptorImpl) debuggerTreeNode.getDescriptor()).getThreadGroupReference() == pathToThread.get(0)) { + pathToThread.remove(0); + expandPath(new TreePath(debuggerTreeNode.getPath())); + } + } + } + + private void removeListener() { + final TreeModelAdapter listener = this; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + getModel().removeTreeModelListener(listener); + } + }); + } + + public void treeStructureChanged(TreeModelEvent event) { + if(event.getPath().length <= 1) { + removeListener(); + return; + } + structureChanged((DebuggerTreeNodeImpl)event.getTreePath().getLastPathComponent()); + } + }; + + MyTreeModelAdapter listener = new MyTreeModelAdapter(); + listener.structureChanged((DebuggerTreeNodeImpl)getModel().getRoot()); + getModel().addTreeModelListener(listener); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsPanel.java new file mode 100644 index 00000000000..da6d96df05e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/ThreadsPanel.java @@ -0,0 +1,72 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.actions.DebuggerAction; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerContextUtil; +import com.intellij.debugger.impl.DebuggerContextUtil; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class ThreadsPanel extends DebuggerPanel implements DataProvider { + public ThreadsPanel(Project project, DebuggerStateManager stateManager) { + super(project, stateManager); + + DebuggerAction.installEditAction(getThreadsTree(), DebuggerActions.EDIT_FRAME_SOURCE); + + getThreadsTree().addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER && getThreadsTree().getSelectionCount() == 1) { + DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)getThreadsTree().getLastSelectedPathComponent(); + if (node != null) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + if (descriptor instanceof StackFrameDescriptorImpl) { + selectFrame(node); + } + } + } + } + }); + add(new JScrollPane(getThreadsTree()), BorderLayout.CENTER); + } + + protected DebuggerTree createTreeView() { + return new ThreadsDebuggerTree(getProject()); + } + + protected ActionPopupMenu createPopupMenu() { + DefaultActionGroup group = (DefaultActionGroup)ActionManager.getInstance().getAction(DebuggerActions.THREADS_PANEL_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.THREADS_PANEL_POPUP, group); + return popupMenu; + } + + public Object getData(String dataId) { + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return "debugging.debugThreads"; + } + return super.getData(dataId); + } + + private void selectFrame(DebuggerTreeNodeImpl node) { + StackFrameProxyImpl frame = ((StackFrameDescriptorImpl)node.getDescriptor()).getStackFrame(); + DebuggerContextUtil.setStackFrame(getContextManager(), frame); + } + + public ThreadsDebuggerTree getThreadsTree() { + return (ThreadsDebuggerTree) getTree(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/TipManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/TipManager.java new file mode 100644 index 00000000000..f507d052a1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/TipManager.java @@ -0,0 +1,128 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.WeakMouseListener; +import com.intellij.debugger.ui.WeakMouseMotionListener; +import com.intellij.ui.ListenerUtil; +import com.intellij.util.Alarm; +import com.intellij.util.WeakListener; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Jan 29, 2004 + * Time: 4:23:11 PM + * To change this template use File | Settings | File Templates. + */ +public class TipManager { + private static int SHOW_DELAY = 1000; + + public static interface TipFactory { + JComponent createToolTip (MouseEvent e); + } + + private class MyMouseListener extends MouseAdapter { + public void mouseEntered(MouseEvent e) { + tryTooltip(e); + } + + private boolean isOverTip(MouseEvent e) { + if (myCurrentTooltip != null) { + Window tipWindow = SwingUtilities.windowForComponent(myCurrentTooltip); + if(!tipWindow.isShowing()) hideTooltip(); + Point point = e.getComponent().getLocationOnScreen(); + point.translate(e.getX(), e.getY()); + return tipWindow != null && tipWindow.getBounds().contains(point); + } + return false; + } + + public void mouseExited(MouseEvent e) { + myAlarm.cancelAllRequests(); + if (isOverTip(e)) { + ListenerUtil.addMouseListener(myCurrentTooltip, new MouseAdapter() { + public void mouseExited(MouseEvent e) { + if (myCurrentTooltip != null) { + if(!isOverTip(e)) { + SwingUtilities.windowForComponent(myCurrentTooltip).removeMouseListener(this); + hideTooltip(); + } + } + } + }); + } else { + hideTooltip(); + } + } + } + + private class MyMouseMotionListener extends MouseMotionAdapter { + public void mouseMoved(MouseEvent e) { + tryTooltip(e); + } + } + + private void tryTooltip(final MouseEvent e) { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + public void run() { + showTooltip(e); + } + }, DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY); + } + + private void showTooltip(MouseEvent e) { + JComponent newTip = myTipFactory.createToolTip(e); + if(newTip == myCurrentTooltip) return; + + hideTooltip(); + + if(newTip != null && myComponent.isShowing()) { + PopupFactory popupFactory = PopupFactory.getSharedInstance(); + Point sLocation = myComponent.getLocationOnScreen(); + Point location = newTip.getLocation(); + location.x += sLocation.x; + location.y += sLocation.y; + + Popup tipPopup = popupFactory.getPopup(myComponent, newTip, + location.x, + location.y); + tipPopup.show(); + myCurrentTooltip = newTip; + } + } + + public void hideTooltip() { + if (myCurrentTooltip != null) { + Window window = SwingUtilities.windowForComponent(myCurrentTooltip); + if(window != null) window.hide(); + myCurrentTooltip = null; + } + } + + private JComponent myCurrentTooltip; + private final TipFactory myTipFactory; + private final JComponent myComponent; + private MouseListener myMouseListener = new MyMouseListener(); + private MouseMotionListener myMouseMotionListener = new MyMouseMotionListener(); + private final Alarm myAlarm = new Alarm(); + + + public TipManager(JComponent component, TipFactory factory) { + new WeakMouseListener(component, myMouseListener); + new WeakMouseMotionListener(component, myMouseMotionListener); + + myTipFactory = factory; + myComponent = component; + } + + public void dispose() { + myMouseListener = null; + myMouseMotionListener = null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/UIUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/UIUtil.java new file mode 100644 index 00000000000..842746bc47d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/UIUtil.java @@ -0,0 +1,145 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * User: lex + * Date: Sep 20, 2003 + * Time: 11:26:44 PM + */ +public class UIUtil { + public static void enableEditorOnCheck(final JCheckBox checkbox, final JComponent textfield) { + checkbox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + boolean selected = checkbox.isSelected(); + textfield.setEnabled(selected); + } + }); + textfield.setEnabled(checkbox.isSelected()); + } + + public static void focusEditorOnCheck(final JCheckBox checkbox, final JComponent component) { + final Runnable runnable = new Runnable() { + public void run() { + component.requestFocus(); + } + }; + checkbox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (checkbox.isSelected()) { + SwingUtilities.invokeLater(runnable); + } + } + }); + } + + public static class BorderedPanel extends JPanel { + private final TitledBorder myTitleBorder; + + public BorderedPanel(String title) { + super(new BorderLayout()); + myTitleBorder = IdeBorderFactory.createTitledBorder(title); + setBorder(myTitleBorder); + } + + public void setEnabled(boolean isEnabled) { + super.setEnabled(isEnabled); + + if (!isEnabled) { + Color halftone = UIManager.getColor("textInactiveText"); + myTitleBorder.setTitleColor(halftone); + } else { + Color foregrnd = getForeground(); + myTitleBorder.setTitleColor(foregrnd); + } + } + } + + public static class RadioTabbedPaneManager { + public static class Tab { + public String name; + public Component contents; + private JRadioButton button; + + public Tab(String _name, Component _contents) { + name = _name; + contents = _contents; + } + } + + ArrayList myTabs = new ArrayList(); + Tab myActiveTab; + + public RadioTabbedPaneManager() { + } + + public void addTab(String name, Component tab) { + myTabs.add(new Tab(name, tab)); + } + + public Component createComponent() { + Dimension preferredSize = null; + + JPanel result = new JPanel(new BorderLayout()); + final JPanel tabPlace = new JPanel();; + ButtonGroup buttonGroup = new ButtonGroup(); + Box buttonBox = Box.createHorizontalBox(); + for (Iterator iterator = myTabs.iterator(); iterator.hasNext();) { + final Tab tab = (Tab)iterator.next(); + tab.button = new JRadioButton(tab.name); + tab.button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + tabPlace.removeAll(); + tabPlace.add(tab.contents); + tabPlace.validate(); + tabPlace.repaint(); + myActiveTab = tab; + } + }); + buttonGroup.add(tab.button); + buttonBox.add(tab.button); + if(preferredSize == null) { + preferredSize = tab.contents.getPreferredSize(); + } else { + Dimension contentsSize = tab.contents.getPreferredSize(); + if(preferredSize .height < contentsSize.height) + preferredSize.height = contentsSize.height; + if(preferredSize.width < contentsSize.width) + preferredSize.width = contentsSize.width; + } + } + + result.add(buttonBox, BorderLayout.NORTH); + result.add(tabPlace, BorderLayout.WEST); + tabPlace.setPreferredSize(preferredSize); + + return result; + } + + public Tab getSelectedTab() { + return myActiveTab; + } + + public void setActiveTab(String s) { + getSelectedTab().button.setSelected(false); + for (Iterator iterator = myTabs.iterator(); iterator.hasNext();) { + Tab tab = (Tab)iterator.next(); + if(tab.name.equals(s)) { + tab.button.setSelected(true); + } + } + } + } + + public static Dimension max(Dimension d1, Dimension d2) { + return new Dimension(d1.width > d2.width ? d1.width : d2.width, d1.height > d2.height ? d1.height : d2.height); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchDebuggerTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchDebuggerTree.java new file mode 100644 index 00000000000..cd4ff51381a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchDebuggerTree.java @@ -0,0 +1,121 @@ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.util.Enumeration; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class WatchDebuggerTree extends DebuggerTree { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.WatchDebuggerTree"); + private boolean myAllowBreakpoints = false; + + public WatchDebuggerTree(Project project) { + super(project); + } + + public DebuggerTreeNodeImpl[] getWatches() { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)getModel().getRoot(); + DebuggerTreeNodeImpl [] watches = new DebuggerTreeNodeImpl[root.getChildCount()]; + + int i = 0; + for(Enumeration e = root.children(); e.hasMoreElements(); i++) { + watches[i] = (DebuggerTreeNodeImpl) e.nextElement(); + } + + return watches; + } + + public int getWatchCount() { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); + return root != null ? root.getChildCount() : 0; + } + + public DebuggerTreeNodeImpl addWatch(WatchItemDescriptor descriptor) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + final DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); + WatchItemDescriptor watchDescriptor = new WatchItemDescriptor(getProject(), (TextWithImportsImpl)descriptor.getEvaluationText(), myAllowBreakpoints); + watchDescriptor.displayAs(descriptor); + + final DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNodeNoUpdate(this, watchDescriptor); + root.add(node); + + treeChanged(); + getSelectionModel().setSelectionPath(new TreePath(node.getPath())); + + node.calcValue(); + + return node; + } + + public DebuggerTreeNodeImpl addWatch(TextWithImportsImpl text) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + final DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); + DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNodeNoUpdate(this, new WatchItemDescriptor(getProject(), text, myAllowBreakpoints)); + root.add(node); + + treeChanged(); + getSelectionModel().setSelectionPath(new TreePath(node.getPath())); + + node.calcValue(); + + return node; + } + + public void removeWatch(DebuggerTreeNodeImpl node) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + LOG.assertTrue(node.getDescriptor() instanceof WatchItemDescriptor); + + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); + DebuggerTreeNodeImpl nodeToSelect = (DebuggerTreeNodeImpl) node.getNextSibling(); + + getMutableModel().removeNodeFromParent(node); + treeChanged(); + + if(nodeToSelect == null && root.getChildCount() > 0) { + nodeToSelect = (DebuggerTreeNodeImpl) root.getChildAt(root.getChildCount() - 1); + } + + if(nodeToSelect != null) { + setSelectionPath(new TreePath(nodeToSelect.getPath())); + } + } + + protected void build(DebuggerContextImpl context) { + DebuggerTreeNodeImpl[] watches = getWatches(); + + for (int i = 0; i < watches.length; i++) { + DebuggerTreeNodeImpl watch = watches[i]; + watch.calcValue(); + } + } + + public static void setWatchNodeText(final DebuggerTreeNodeImpl node, TextWithImportsImpl text) { + ((WatchItemDescriptor)node.getDescriptor()).setEvaluationText(text); + node.calcValue(); + } + + public void setAllowBreakpoints(boolean b) { + myAllowBreakpoints = b; + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)getMutableModel().getRoot(); + for(Enumeration enumeration = root.children(); enumeration.hasMoreElements();){ + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)enumeration.nextElement(); + ((WatchItemDescriptor)child.getDescriptor()).setAllowBreakpoints(b); + } + } + + public void setHistoryByContext(DebuggerContextImpl debuggerContext) { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchPanel.java new file mode 100644 index 00000000000..af1844c9b48 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/WatchPanel.java @@ -0,0 +1,63 @@ +/* + * Class WatchPanel + * @author Jeka + */ +package com.intellij.debugger.ui.impl; + +import com.intellij.debugger.actions.DebuggerAction; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; +import java.util.Enumeration; + +public abstract class WatchPanel extends DebuggerPanel { + public WatchPanel(Project project, DebuggerStateManager stateManager) { + super(project, stateManager); + add(new JScrollPane(getWatchTree()), BorderLayout.CENTER); + DebuggerAction.installEditAction(getWatchTree(), DebuggerActions.EDIT_NODE_SOURCE); + } + + protected DebuggerTree createTreeView() { + return new WatchDebuggerTree(getProject()); + } + + protected void changeEvent(DebuggerContextImpl newContext, int event) { + if(event == DebuggerSession.EVENT_ATTACHED) { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getWatchTree().getModel().getRoot(); + if(root != null) { + for(Enumeration e = root.rawChildren(); e.hasMoreElements();) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl) e.nextElement(); + ((WatchItemDescriptor) child.getDescriptor()).setNew(); + } + } + } + + rebuildWhenVisible(event); + } + + protected ActionPopupMenu createPopupMenu() { + return null; + } + + public Object getData(String dataId) { + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return "debugging.debugWatches"; + } + return super.getData(dataId); + } + + public WatchDebuggerTree getWatchTree() { + return (WatchDebuggerTree) getTree(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java new file mode 100644 index 00000000000..bf223b2f1fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java @@ -0,0 +1,43 @@ +/* + * Class ArrayIndexHelper + * @author Jeka + */ +package com.intellij.debugger.ui.impl.nodes; + +import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.ArrayReference; + +public class ArrayIndexHelper { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.nodes.ArrayIndexHelper"); + private final ArrayReference myArray; + private final ArrayRenderer myRenderer; + + public ArrayIndexHelper(ArrayReference array, ArrayRenderer renderer) { + myRenderer = renderer; + myArray = array; + } + + /** + * @return normalized start index or -1 if this is not an array or array's length == 0 + */ + public int getStartIndex() { + if (myArray.length() == 0) return -1; + return myRenderer.START_INDEX; + } + + /** + * @return normalized end index or -1 if this is not an array or array's length == 0 + */ + + public int getEndIndex() { + return Math.min(myArray.length() - 1, myRenderer.END_INDEX); + } + + public ArrayRenderer newRenderer(int startIdx, int endIdx) { + ArrayRenderer result = myRenderer.clone(); + result.START_INDEX = startIdx < myArray.length() ? startIdx : 0; + result.END_INDEX = startIdx <= endIdx ? endIdx : startIdx; + return result; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/NodeComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/NodeComparator.java new file mode 100644 index 00000000000..22bfc7b985e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/nodes/NodeComparator.java @@ -0,0 +1,32 @@ +/* + * Class NodeComparator + * @author Jeka + */ +package com.intellij.debugger.ui.impl.nodes; + +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; + +import java.util.Comparator; + +/** + * Compares given DebuggerTreeTest by name + */ +public class NodeComparator implements Comparator { + public int compare(Object o1, Object o2) { + DebuggerTreeNodeImpl node1 = (DebuggerTreeNodeImpl)o1; + DebuggerTreeNodeImpl node2 = (DebuggerTreeNodeImpl)o2; + String name1 = node1.getDescriptor().getName(); + String name2 = node2.getDescriptor().getName(); + boolean invalid1 = (name1 == null || (name1.length() > 0 && Character.isDigit(name1.charAt(0)))); + boolean invalid2 = (name2 == null || (name2.length() > 0 && Character.isDigit(name2.charAt(0)))); + if (invalid1) { + return invalid2? 0 : 1; + } + else { + if (invalid2) return -1; + } + if ("this".equals(name1) || "static".equals(name1)) return -1; + if ("this".equals(name2) || "static".equals(name2)) return 1; + return name1.compareToIgnoreCase(name2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilder.java new file mode 100644 index 00000000000..4a27ac98df6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilder.java @@ -0,0 +1,120 @@ +package com.intellij.debugger.ui.impl.tree; + +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Sep 10, 2003 + * Time: 6:56:51 PM + */ +public abstract class TreeBuilder implements TreeModel { + private Object userObject; + private TreeBuilderNode myRoot; + private List myListeners = new ArrayList(); + + protected TreeBuilder(Object userObject) { + this.userObject = userObject; + } + + public Object getUserObject() { + return userObject; + } + + protected abstract void buildChildren(TreeBuilderNode node); + protected abstract boolean isExpandable (TreeBuilderNode node); + + public void setRoot(TreeBuilderNode root) { + myRoot = root; + } + + public Object getRoot() { + return myRoot; + } + + public int getChildCount(Object parent) { + return ((TreeBuilderNode) parent).getChildCount(); + } + + public boolean isLeaf(Object node) { + return ((TreeBuilderNode) node).isLeaf(); + } + + public void addTreeModelListener(TreeModelListener l) { + myListeners.add(l); + } + + public void removeTreeModelListener(TreeModelListener l) { + myListeners.remove(l); + } + + public Object getChild(Object parent, int index) { + return ((TreeBuilderNode) parent).getChildAt(index); + } + + public int getIndexOfChild(Object parent, Object child) { + return ((TreeBuilderNode) parent).getIndex((TreeNode) child); + } + + public void valueForPathChanged(TreePath path, Object newValue) { + TreeBuilderNode aNode = (TreeBuilderNode) path.getLastPathComponent(); + + aNode.setUserObject(newValue); + nodeChanged(aNode); + } + + public void nodeChanged(TreeNode node) { + TreeModelEvent event = null; + TreeNode parent = node.getParent(); + if (parent != null) { + int anIndex = parent.getIndex(node); + event = new TreeModelEvent(this, getPathToRoot(parent, 0), new int[] {anIndex}, new Object[] {node}); + } else if (node == getRoot()) { + event = new TreeModelEvent(this, getPathToRoot(node, 0), null, null); + } + if (event != null) { + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + TreeModelListener treeModelListener = (TreeModelListener) iterator.next(); + treeModelListener.treeNodesChanged(event); + } + } + } + + public void nodeStructureChanged(TreeNode node) { + TreeModelEvent event = new TreeModelEvent(this, getPathToRoot(node, 0), null, null); + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + TreeModelListener treeModelListener = (TreeModelListener) iterator.next(); + treeModelListener.treeStructureChanged(event); + } + } + + protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) { + TreeNode[] retNodes; + if(aNode == null) { + if(depth == 0) + return null; + else + retNodes = new TreeNode[depth]; + } + else { + depth++; + if(aNode == myRoot) + retNodes = new TreeNode[depth]; + else + retNodes = getPathToRoot(aNode.getParent(), depth); + retNodes[retNodes.length - depth] = aNode; + } + return retNodes; + } + + public void removeNodeFromParent(TreeBuilderNode node) { + ((TreeBuilderNode) node.getParent()).remove(node); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilderNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilderNode.java new file mode 100644 index 00000000000..af774427995 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/tree/TreeBuilderNode.java @@ -0,0 +1,96 @@ +package com.intellij.debugger.ui.impl.tree; + +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreeNode; +import java.util.Enumeration; + +/** + * User: lex + * Date: Sep 10, 2003 + * Time: 7:01:02 PM + */ +public abstract class TreeBuilderNode extends DefaultMutableTreeNode{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.tree.TreeBuilderNode"); + private boolean myChildrenBuilt = false; + + public TreeBuilderNode(Object userObject) { + super(userObject); + } + + abstract protected TreeBuilder getTreeBuilder(); + + public void removeAllChildren() { + myChildrenBuilt = true; + super.removeAllChildren(); + } + + public void add(MutableTreeNode newChild) { + myChildrenBuilt = true; + super.add(newChild); + } + + public void remove(MutableTreeNode aChild) { + myChildrenBuilt = true; + super.remove(aChild); + } + + public void insert(MutableTreeNode newChild, int childIndex) { + myChildrenBuilt = true; + super.insert(newChild, childIndex); + } + + private void checkChildren() { + if(!myChildrenBuilt) { + myChildrenBuilt = true; + if(getTreeBuilder().isExpandable(this)) { + getTreeBuilder().buildChildren(this); + } + } + } + + public void clear() { + removeAllChildren(); + myChildrenBuilt = false; + } + + //TreeNode interface + public int getChildCount() { + checkChildren(); + return super.getChildCount(); + } + + public boolean getAllowsChildren() { + checkChildren(); + return super.getAllowsChildren(); + } + + public boolean isLeaf() { + return !getTreeBuilder().isExpandable(this); + } + + public Enumeration children() { + checkChildren(); + return super.children(); + } + + public Enumeration rawChildren() { + return super.children(); + } + + public TreeNode getChildAt(int childIndex) { + checkChildren(); + return super.getChildAt(childIndex); + } + + public int getIndex(TreeNode node) { + checkChildren(); + return super.getIndex(node); + } + + public boolean isChildrenBuilt() { + return myChildrenBuilt; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ArrayElementDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ArrayElementDescriptorImpl.java new file mode 100644 index 00000000000..526156ced0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ArrayElementDescriptorImpl.java @@ -0,0 +1,68 @@ +package com.intellij.debugger.ui.impl.watch; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.tree.ArrayElementDescriptor; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.DebuggerContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiArrayAccessExpression; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiManager; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.ArrayReference; +import com.sun.jdi.Value; +import com.sun.tools.corba.se.idl.constExpr.EvaluationException; + +public class ArrayElementDescriptorImpl extends ValueDescriptorImpl implements ArrayElementDescriptor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl"); + + private int myIndex; + private ArrayReference myArray; + + public ArrayElementDescriptorImpl(Project project, ArrayReference array, int index) { + super(project); + myArray = array; + myIndex = index; + setLvalue(true); + } + + public int getIndex() { + return myIndex; + } + + public ArrayReference getArray() { + return myArray; + } + + public String getName() { + return String.valueOf(myIndex); + } + + public String calcValueName() { + return "[" + getName() + "]"; + } + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + if (!VirtualMachineProxyImpl.isCollected(myArray)) { + return myArray.getValue(myIndex); + } else { + throw EvaluateExceptionUtil.ARRAY_WAS_COLLECTED; + } + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) { + PsiElementFactory elementFactory = PsiManager.getInstance(context.getProject()).getElementFactory(); + try { + return elementFactory.createExpressionFromText("this[" + myIndex + "]", null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java new file mode 100644 index 00000000000..a43e59decfb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -0,0 +1,728 @@ +/* + * Class DebuggerTree + * @author Jeka + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.settings.ThreadsViewSettings; +import com.intellij.debugger.ui.impl.DebuggerTreeBase; +import com.intellij.debugger.ui.impl.tree.TreeBuilder; +import com.intellij.debugger.ui.impl.tree.TreeBuilderNode; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.debugger.ui.tree.render.ChildrenBuilder; +import com.intellij.debugger.ui.tree.render.NodeRendererSettings; +import com.intellij.debugger.ui.tree.render.NodeRendererSettingsListener; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentListener; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.ui.ListenerUtil; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; +import com.intellij.util.IJSwingUtilities; +import com.sun.jdi.*; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; + +public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.DebuggerTree"); + private final Key VISIBLE_RECT = new Key("VISIBLE_RECT"); + + private final Project myProject; + private final NodeManagerImpl myDescriptorManager; + + private int myPriority = DebuggerManagerThreadImpl.NORMAL_PRIORITY; + private NodeRendererSettingsListener mySettingsListener; + private DebuggerContextImpl myDebuggerContext = DebuggerContextImpl.EMPTY_CONTEXT; + + public DebuggerTree(Project project) { + super(null, project); + setScrollsOnExpand(false); + myDescriptorManager = new NodeManagerImpl(project, this); + TreeBuilder model = new TreeBuilder(this) { + protected void buildChildren(TreeBuilderNode node) { + if (((DebuggerTreeNodeImpl)node).getDescriptor() instanceof DefaultNodeDescriptor) return; + buildNode((DebuggerTreeNodeImpl)node); + } + + protected boolean isExpandable(TreeBuilderNode builderNode) { + return DebuggerTree.this.isExpandable((DebuggerTreeNodeImpl)builderNode); + } + }; + model.setRoot(getNodeFactory().getDefaultNode()); + model.addTreeModelListener(new TreeModelListener() { + public void treeNodesChanged (TreeModelEvent event) { myTipManager.hideTooltip(); } + public void treeNodesInserted (TreeModelEvent event) { myTipManager.hideTooltip(); } + public void treeNodesRemoved (TreeModelEvent event) { myTipManager.hideTooltip(); } + public void treeStructureChanged (TreeModelEvent event) { myTipManager.hideTooltip(); } + }); + + setModel(model); + + myProject = project; + new TreeSpeedSearch(this); + } + + private void installSettingsListener() { + if (mySettingsListener != null) return; + mySettingsListener = new NodeRendererSettingsListener() { + private void rendererSettingsChanged(DebuggerTreeNodeImpl node) { + if (node.getDescriptor() instanceof ValueDescriptorImpl) { + node.calcRepresentation(); + } + + try { + for (Enumeration e = node.rawChildren(); e.hasMoreElements();) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)e.nextElement(); + rendererSettingsChanged(child); + } + } + catch (NoSuchElementException e) { + } + } + + public void renderersChanged() { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)getModel().getRoot(); + if (root != null) { + rendererSettingsChanged(root); + } + + } + }; + NodeRendererSettings.getInstance().addListener(mySettingsListener); + } + + private void uninstallSettingsListener() { + if (mySettingsListener == null) return; + NodeRendererSettings.getInstance().removeListener(mySettingsListener); + mySettingsListener = null; + } + + public void removeNotify() { + uninstallSettingsListener(); + super.removeNotify(); + } + + public void addNotify() { + super.addNotify(); + installSettingsListener(); + } + + protected boolean isExpandable(DebuggerTreeNodeImpl node) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + return descriptor.isExpandable(); + } + + public Object getData(String dataId) { + if (DebuggerActions.DEBUGGER_TREE.equals(dataId)) return this; + return null; + } + + + private void buildNode(final DebuggerTreeNodeImpl node) { + if (node == null || node.getDescriptor() == null) return; + + BuildNodeCommand builder = getBuildNodeCommand(node); + builder.getNode().add(myDescriptorManager.createMessageNode(MessageDescriptor.EVALUATING)); + getDebuggerContext().getDebugProcess().getManagerThread().invokeLater(builder); + } + + private BuildNodeCommand getBuildNodeCommand(final DebuggerTreeNodeImpl node) { + if (node.getDescriptor() instanceof ThreadGroupDescriptorImpl) { + return new BuildThreadGroupCommand(node); + } + else if (node.getDescriptor() instanceof ThreadDescriptorImpl) { + return new BuildThreadCommand(node); + } + else if (node.getDescriptor() instanceof StackFrameDescriptorImpl) { + return new BuildStackFrameCommand(node); + } + else if (node.getDescriptor() instanceof ValueDescriptorImpl) { + return new BuildValueNodeCommand(node); + } + else if (node.getDescriptor() instanceof StaticDescriptorImpl) { + return new BuildStaticNodeCommand(node); + } + LOG.assertTrue(false); + return null; + } + + public void saveState(DebuggerTreeNodeImpl node) { + if (node.getDescriptor() != null) { + TreePath path = new TreePath(node.getPath()); + node.getDescriptor().myIsExpanded = isExpanded(path); + node.getDescriptor().myIsSelected = getSelectionModel().isPathSelected(path); + Rectangle rowBounds = getRowBounds(getRowForPath(path)); + if(rowBounds != null && getVisibleRect().contains(rowBounds)) { + node.getDescriptor().putUserData(VISIBLE_RECT, getVisibleRect()); + } + else { + node.getDescriptor().putUserData(VISIBLE_RECT, null); + } + } + + for (Enumeration e = node.rawChildren(); e.hasMoreElements();) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)e.nextElement(); + saveState(child); + } + } + + public void restoreState(DebuggerTreeNodeImpl node) { + if(!node.myIsStateRestored) { + restoreNodeState(node); + } + else { + node.myIsStateRestored = true; + } + if (node.getDescriptor().myIsExpanded) { + for (Enumeration e = node.rawChildren(); e.hasMoreElements();) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)e.nextElement(); + restoreState(child); + } + } + } + + public void restoreState() { + clearSelection(); + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)getModel().getRoot(); + if (root != null) { + restoreState(root); + } + } + + protected void restoreNodeState(DebuggerTreeNodeImpl node) { + Rectangle visibleRect = (Rectangle) node.getDescriptor().getUserData(VISIBLE_RECT); + if(visibleRect != null) { + scrollRectToVisible(visibleRect); + } + if (node.getDescriptor() != null) { + if (node.getParent() == null) node.getDescriptor().myIsExpanded = true; + + TreePath path = new TreePath(node.getPath()); + if (node.getDescriptor().myIsExpanded) { + expandPath(path); + } + if (node.getDescriptor().myIsSelected) { + addSelectionPath(path); + } +// if(node.getDescriptor().myIsVisible) { +// scrollPathToVisible(path); +// } + } + } + + public NodeManagerImpl getNodeFactory() { + return myDescriptorManager; + } + + public TreeBuilder getMutableModel() { + return (TreeBuilder)getModel(); + } + + public void removeAllChildren() { + DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl)getModel().getRoot(); + root.removeAllChildren(); + treeChanged(); + } + + public void showMessage(MessageDescriptor messageDesc) { + DebuggerTreeNodeImpl root = getNodeFactory().getDefaultNode(); + getMutableModel().setRoot(root); + DebuggerTreeNodeImpl message = root.add(messageDesc); + treeChanged(); + expandPath(new TreePath(message.getPath())); + } + + public void showMessage(String messageText) { + showMessage(new MessageDescriptor(messageText)); + } + + public void treeChanged() { + DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)getModel().getRoot(); + if (node != null) { + getMutableModel().nodeStructureChanged(node); + restoreState(); + } + } + + public Project getProject() { return myProject; } + + public int getPriority() { + return myPriority; + } + + public void setEvaluationPriority(int priority) { + myPriority = priority; + } + + protected abstract void build(DebuggerContextImpl context); + + public final void buildWhenPaused(DebuggerContextImpl context, RefreshDebuggerTreeCommand command) { + DebuggerSession debuggerSession = context.getDebuggerSession(); + + if(ApplicationManager.getApplication().isUnitTestMode() || debuggerSession.getState() == DebuggerSession.STATE_PAUSED) { + showMessage(MessageDescriptor.EVALUATING); + context.getDebugProcess().getManagerThread().invokeLater(command); + } + else { + showMessage(context.getDebuggerSession().getStateDescription()); + } + } + + public void rebuild(final DebuggerContextImpl context) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + + myDebuggerContext = context; + saveState(); + context.getDebugProcess().getManagerThread().invokeLater(new DebuggerContextCommandImpl(context){ + public void threadAction() { + getNodeFactory().setHistoryByContext(context); + } + }); + + build(context); + } + + public void saveState() { + saveState((DebuggerTreeNodeImpl)getModel().getRoot()); + } + + protected abstract class RefreshDebuggerTreeCommand extends DebuggerContextCommandImpl { + private final DebuggerContextImpl myDebuggerContext; + + public RefreshDebuggerTreeCommand(DebuggerContextImpl context) { + super(context); + myDebuggerContext = context; + } + + public DebuggerContextImpl getDebuggerContext() { + return myDebuggerContext; + } + + public void threadAction() { + + } + } + + public static abstract class InplaceEditor { + final DebuggerSession myDebuggerSession; + final DebuggerTreeNodeImpl myNode; + JComponent myEditorComponent; + + private ContentManagerAdapter mySelectionListener = new ContentManagerAdapter() { + public void selectionChanged(ContentManagerEvent event) { + doFocusLostAction(); + } + };; + + private KeyAdapter myKeyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if(!isShowed()) return; + if(e.getKeyCode() == KeyEvent.VK_ENTER) { + doOKAction(); + } else if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { + doCancelAction(); + } + } + }; + private FocusAdapter myFocusListener = new FocusAdapter() { + public void focusLost(FocusEvent e) { + if(!isShowed()) return; + if(e.isTemporary()) return; + if(myEditorComponent.getParent() == null) return; + doFocusLostAction(); + } + }; + private ComponentAdapter myComponentListener = new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + if(!isShowed()) return; + JTree tree = myNode.getTree(); + JLayeredPane layeredPane = tree.getRootPane().getLayeredPane(); + Rectangle bounds = getEditorBounds(); + Point layeredPanePoint=SwingUtilities.convertPoint(tree, bounds.x, bounds.y,layeredPane); + myEditorComponent.setBounds(layeredPanePoint.x,layeredPanePoint.y, bounds.width, bounds.height); + myEditorComponent.revalidate(); + } + }); + } + + public void componentHidden(ComponentEvent e) { + doFocusLostAction(); + } + }; + private RunContentListener myRunContentListener = new RunContentListener() { + public void contentSelected(RunContentDescriptor descriptor) { + doFocusLostAction(); + } + + public void contentRemoved(RunContentDescriptor descriptor) { + doFocusLostAction(); + } + }; + + protected abstract JComponent createEditorComponent(); + protected abstract JComponent getContentComponent (); + public abstract Editor getEditor (); + + public void doOKAction() { + remove(); + } + + public void doFocusLostAction() { + doCancelAction(); + } + + public void doCancelAction() { + remove(); + } + + private void remove() { + if(!isShowed()) return; + DebuggerTree tree = myNode.getTree(); + JRootPane rootPane = tree.getRootPane(); + if (rootPane != null) { + JLayeredPane layeredPane = rootPane.getLayeredPane(); + if(layeredPane != null) { + layeredPane.remove(myEditorComponent); + } + rootPane.removeComponentListener(myComponentListener); + } + if(myDebuggerSession != null) { +// ContentManager manager = myDebuggerSession.getViewsContentManager(); +// manager.removeContentManagerListener(mySelectionListener); + } + + ExecutionManager.getInstance(getProject()).getContentManager().removeRunContentListener(myRunContentListener); + + myEditorComponent = null; + + tree.repaint(); + tree.requestFocus(); + } + + private Project getProject() { + return myNode.getTree().getProject(); + } + + public InplaceEditor(DebuggerTreeNodeImpl node) { + myNode = node; + myDebuggerSession = node.getTree().getDebuggerContext().getDebuggerSession(); + } + + public DebuggerTreeNodeImpl getNode() { + return myNode; + } + + public void show() { + LOG.assertTrue(myEditorComponent == null, "editor is not released"); + final DebuggerTree tree = myNode.getTree(); + final JLayeredPane layeredPane = tree.getRootPane().getLayeredPane(); + + Rectangle bounds = getEditorBounds(); + + Point layeredPanePoint=SwingUtilities.convertPoint(tree, bounds.x, bounds.y,layeredPane); + + myEditorComponent = createEditorComponent(); + LOG.assertTrue(myEditorComponent != null); + myEditorComponent.setBounds( + layeredPanePoint.x, + layeredPanePoint.y, + bounds.width, + Math.max(bounds.height, myEditorComponent.getPreferredSize().height)); + + layeredPane.add(myEditorComponent,new Integer(250)); + + myEditorComponent.validate(); + myEditorComponent.paintImmediately(0,0,myEditorComponent.getWidth(),myEditorComponent.getHeight()); + getContentComponent().requestFocus(); + + tree.getRootPane().addComponentListener(myComponentListener); + if(myDebuggerSession != null) { +// myDebuggerSession.getViewsContentManager().addContentManagerListener(mySelectionListener); + } + ExecutionManager.getInstance(getProject()).getContentManager().addRunContentListener(myRunContentListener); + ListenerUtil.addKeyListener(getContentComponent(), myKeyListener); + ListenerUtil.addFocusListener(getContentComponent(), myFocusListener); + } + + private Rectangle getEditorBounds() { + final DebuggerTree tree = myNode.getTree(); + Rectangle bounds = tree.getVisibleRect(); + Rectangle nodeBounds = tree.getPathBounds(new TreePath(myNode.getPath())); + bounds.y = nodeBounds.y; + bounds.height = nodeBounds.height; + + if(nodeBounds.x > bounds.x) { + bounds.width = bounds.width - nodeBounds.x + bounds.x; + bounds.x = nodeBounds.x; + } + return bounds; + } + + public boolean isShowed() { + return myEditorComponent != null; + } + } + + public DebuggerContextImpl getDebuggerContext() { + return myDebuggerContext; + } + + public abstract class BuildNodeCommand extends DebuggerContextCommandImpl { + private final DebuggerTreeNodeImpl myNode; + + protected final List myChildren = new LinkedList(); + + protected BuildNodeCommand(DebuggerTreeNodeImpl node) { + super(DebuggerTree.this.getDebuggerContext()); + myNode = node; + } + + public DebuggerTreeNodeImpl getNode() { + return myNode; + } + + protected void updateUI() { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + myNode.removeAllChildren(); + for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { + DebuggerTreeNodeImpl debuggerTreeNode = iterator.next(); + myNode.add(debuggerTreeNode); + } + myNode.childrenChanged(); + } + }); + } + } + + private class BuildStackFrameCommand extends BuildNodeCommand { + public BuildStackFrameCommand(DebuggerTreeNodeImpl stackNode) { + super(stackNode); + } + + public void threadAction() { + try { + StackFrameDescriptorImpl stackDescriptor = (StackFrameDescriptorImpl)getNode().getDescriptor(); + StackFrameProxyImpl frame = stackDescriptor.getStackFrame(); + if(!getDebuggerContext().getDebugProcess().getSuspendManager().isSuspended(frame.threadProxy())) return; + + LOG.assertTrue(frame.threadProxy().isSuspended()); + + ObjectReference thisObjectReference = frame.thisObject(); + + EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + + if (thisObjectReference != null) { + myChildren.add(myDescriptorManager.createNode(myDescriptorManager.getThisDescriptor(stackDescriptor, thisObjectReference), evaluationContext)); + } + else { + ReferenceType type = frame.location().method().declaringType(); + myChildren.add(myDescriptorManager.createNode(myDescriptorManager.getStaticDescriptor(stackDescriptor, type), evaluationContext)); + } + try { + for (Iterator iterator = frame.visibleVariables().iterator(); iterator.hasNext();) { + LocalVariableProxyImpl local = iterator.next(); + + myChildren.add(myDescriptorManager.createNode(myDescriptorManager.getLocalVariableDescriptor(stackDescriptor, local), evaluationContext)); + } + } + catch (EvaluateException e) { + myChildren.add(myDescriptorManager.createMessageNode(new MessageDescriptor(e.getMessage()))); + } + } + catch (EvaluateException e) { + myChildren.clear(); + myChildren.add(myDescriptorManager.createMessageNode(new MessageDescriptor(e.getMessage()))); + } + + updateUI(); + } + } + + private class BuildThreadCommand extends BuildNodeCommand { + public BuildThreadCommand(DebuggerTreeNodeImpl threadNode) { + super(threadNode); + } + + public void threadAction() { + ThreadDescriptorImpl threadDescriptor = ((ThreadDescriptorImpl)getNode().getDescriptor()); + ThreadReferenceProxyImpl threadProxy = threadDescriptor.getThreadReference(); + if (!threadProxy.isCollected() && getDebuggerContext().getDebugProcess().getSuspendManager().isSuspended(threadProxy)) { + int status = threadProxy.status(); + if (!(status == ThreadReference.THREAD_STATUS_UNKNOWN) && + !(status == ThreadReference.THREAD_STATUS_NOT_STARTED) && + !(status == ThreadReference.THREAD_STATUS_ZOMBIE)) { + try { + for (Iterator it = threadProxy.frames().iterator(); it.hasNext();) { + StackFrameProxyImpl stackFrame = (StackFrameProxyImpl)it.next(); + //Method method = stackFrame.location().method(); + //ToDo :check whether is synthetic if (shouldDisplay(method)) { + myChildren.add(myDescriptorManager.createNode(myDescriptorManager.getStackFrameDescriptor(threadDescriptor, stackFrame), getDebuggerContext().createEvaluationContext())); + } + } + catch (EvaluateException e) { + myChildren.clear(); + myChildren.add(myDescriptorManager.createMessageNode(e.getMessage())); + LOG.debug(e); + //LOG.assertTrue(false); + // if we pause during evaluation of this method the exception is thrown + // private static void longMethod(){ + // try { + // Thread.sleep(100000); + // } catch (InterruptedException e) { + // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + // } + // } + } + } + } + updateUI(); + } + } + + private class BuildThreadGroupCommand extends BuildNodeCommand { + public BuildThreadGroupCommand(DebuggerTreeNodeImpl node) { + super(node); + } + + public void threadAction() { + ThreadGroupDescriptorImpl groupDescriptor = (ThreadGroupDescriptorImpl)getNode().getDescriptor(); + ThreadGroupReferenceProxyImpl threadGroup = groupDescriptor.getThreadGroupReference(); + + List threads = new ArrayList(threadGroup.threads()); + Collections.sort(threads, ThreadReferenceProxyImpl.ourComparator); + + EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + + boolean showCurrent = ThreadsViewSettings.getInstance().SHOW_CURRENT_THREAD; + + for (Iterator it = threadGroup.threadGroups().iterator(); it.hasNext();) { + ThreadGroupReferenceProxyImpl group = (ThreadGroupReferenceProxyImpl)it.next(); + if (group != null) { + DebuggerTreeNodeImpl threadNode = myDescriptorManager.createNode(myDescriptorManager.getThreadGroupDescriptor(groupDescriptor, group), evaluationContext); + + if (showCurrent && ((ThreadGroupDescriptorImpl)threadNode.getDescriptor()).isCurrent()) { + myChildren.add(0, threadNode); + } + else { + myChildren.add(threadNode); + } + } + } + + ArrayList threadNodes = new ArrayList(); + + for (Iterator it = threads.iterator(); it.hasNext();) { + ThreadReferenceProxyImpl thread = (ThreadReferenceProxyImpl)it.next(); + if (thread != null) { + DebuggerTreeNodeImpl threadNode = myDescriptorManager.createNode(myDescriptorManager.getThreadDescriptor(groupDescriptor, thread), evaluationContext); + if (showCurrent && ((ThreadDescriptorImpl)threadNode.getDescriptor()).isCurrent()) { + threadNodes.add(0, threadNode); + } + else { + threadNodes.add(threadNode); + } + } + } + + myChildren.addAll(threadNodes); + + updateUI(); + } + } + + private class BuildValueNodeCommand extends BuildNodeCommand { + public BuildValueNodeCommand(DebuggerTreeNodeImpl node) { + super(node); + } + + public void threadAction() { + ValueDescriptorImpl descriptor = (ValueDescriptorImpl)getNode().getDescriptor(); + try { + descriptor.getRenderer(getSuspendContext().getDebugProcess()).buildChildren(descriptor.getValue(), new ChildrenBuilder() { + public NodeManagerImpl getNodeManager() { + return myDescriptorManager; + } + + public NodeManagerImpl getDescriptorManager() { + return myDescriptorManager; + } + + public ValueDescriptorImpl getParentDescriptor() { + return (ValueDescriptorImpl)getNode().getDescriptor(); + } + + public void setChildren(final List children) { + IJSwingUtilities.invoke(new Runnable() { + public void run() { + getNode().removeAllChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + DebuggerTreeNode debuggerTreeNode = iterator.next(); + getNode().add(debuggerTreeNode); + } + getNode().childrenChanged(); + } + }); + } + }, getDebuggerContext().createEvaluationContext()); + } + catch (ObjectCollectedException e) { + getNode().removeAllChildren(); + getNode().add(getNodeFactory().createMessageNode(new MessageDescriptor("Cannot evaluate descendants, object was collected. " + e.getMessage()))); + getNode().childrenChanged(); + } + } + } + + private class BuildStaticNodeCommand extends BuildNodeCommand { + public BuildStaticNodeCommand(DebuggerTreeNodeImpl node) { + super(node); + } + + public void threadAction() { + final StaticDescriptorImpl sd = (StaticDescriptorImpl)getNode().getDescriptor(); + final ReferenceType refType = sd.getType(); + List fields = refType.allFields(); + for (Iterator it = fields.iterator(); it.hasNext();) { + Field field = (Field)it.next(); + if (field.isStatic()) { + final FieldDescriptorImpl fieldDescriptor = myDescriptorManager.getFieldDescriptor(sd, null, field); + final EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext(); + final DebuggerTreeNodeImpl node = myDescriptorManager.createNode(fieldDescriptor, evaluationContext); + myChildren.add(node); + } + } + + updateUI(); + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java new file mode 100644 index 00000000000..452938420c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java @@ -0,0 +1,281 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.Value; + +/** + * User: lex + * Date: Oct 29, 2003 + * Time: 9:24:52 PM + */ +public class DebuggerTreeNodeExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression"); + +// private static PsiExpression beautifyExpression(PsiExpression expression) throws IncorrectOperationException { +// final PsiElementFactory elementFactory = expression.getManager().getElementFactory(); +// final PsiParenthesizedExpression utility = (PsiParenthesizedExpression)elementFactory.createExpressionFromText( +// "(expr)", expression.getContext()); +// utility.getExpression().replace(expression); +// +// PsiRecursiveElementVisitor visitor = new PsiRecursiveElementVisitor() { +// public void visitTypeCastExpression(PsiTypeCastExpression expression) { +// try { +// super.visitTypeCastExpression(expression); +// +// PsiElement parent; +// PsiElement toBeReplaced = expression; +// for (parent = expression.getParent(); +// parent instanceof PsiParenthesizedExpression && parent != utility; +// parent = parent.getParent()) { +// toBeReplaced = parent; +// } +// +// if (parent instanceof PsiReferenceExpression) { +// PsiReferenceExpression reference = ((PsiReferenceExpression)parent); +// //((TypeCast)).member +// PsiElement oldResolved = reference.resolve(); +// +// if (oldResolved != null) { +// PsiReferenceExpression newReference = ((PsiReferenceExpression)reference.copy()); +// newReference.getQualifierExpression().replace(expression.getOperand()); +// PsiElement newResolved = newReference.resolve(); +// +// if (oldResolved == newResolved) { +// toBeReplaced.replace(expression.getOperand()); +// } +// else if (newResolved instanceof PsiMethod && oldResolved instanceof PsiMethod) { +// if (isSuperMethod((PsiMethod)newResolved, (PsiMethod)oldResolved)) { +// toBeReplaced.replace(expression.getOperand()); +// } +// } +// } +// } +// else { +// toBeReplaced.replace(expression.getOperand()); +// } +// } +// catch (IncorrectOperationException e) { +// throw new IncorrectOperationRuntimeException(e); +// } +// } +// +// public void visitReferenceExpression(PsiReferenceExpression expression) { +// expression.acceptChildren(this); +// +// try { +// ResolveResult resolveResult = expression.advancedResolve(false); +// +// PsiElement oldResolved = resolveResult.getElement(); +// +// if(oldResolved == null) return; +// +// PsiReferenceExpression newReference; +// if (expression instanceof PsiMethodCallExpression) { +// int length = expression.getQualifierExpression().getTextRange().getLength(); +// PsiMethodCallExpression methodCall = (PsiMethodCallExpression)elementFactory.createExpressionFromText( +// expression.getText().substring(length), expression.getContext()); +// newReference = methodCall.getMethodExpression(); +// } +// else { +// newReference = +// (PsiReferenceExpression)elementFactory.createExpressionFromText(expression.getReferenceName(), +// expression.getContext()); +// } +// +// PsiElement newResolved = newReference.resolve(); +// if (oldResolved == newResolved) { +// expression.replace(newReference); +// } +// } +// catch (IncorrectOperationException e) { +// LOG.debug(e); +// } +// } +// }; +// +// try { +// utility.accept(visitor); +// } +// catch (IncorrectOperationRuntimeException e) { +// throw e.getException(); +// } +// return utility.getExpression(); +// } + + private static boolean isSuperMethod(PsiMethod superMethod, PsiMethod overridingMethod) { + PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(overridingMethod); + for (int i = 0; i < superMethods.length; i++) { + if (superMethods[i] == superMethod) { + return true; + } + else if (isSuperMethod(superMethod, superMethods[i])) { + return true; + } + } + return false; + } + + public static PsiExpression substituteThis(PsiExpression expressionWithThis, PsiExpression howToEvaluateThis, Value howToEvaluateThisValue) + throws EvaluateException { + PsiExpression result = (PsiExpression)expressionWithThis.copy(); + + PsiClass thisClass = PsiTreeUtil.getContextOfType(result, PsiClass.class, true); + + boolean castNeeded = true; + + if (thisClass != null) { + PsiType type = howToEvaluateThis.getType(); + if(type != null) { + if(type instanceof PsiClassType) { + PsiClass psiClass = ((PsiClassType) type).resolve(); + if(psiClass != null && (psiClass == thisClass || psiClass.isInheritor(thisClass, true))) { + castNeeded = false; + } + } + else if(type instanceof PsiArrayType) { + if(thisClass == expressionWithThis.getManager().getElementFactory().getArrayClass()) { + castNeeded = false; + } + } + } + } + + if (castNeeded) { + howToEvaluateThis = castToRuntimeType(howToEvaluateThis, howToEvaluateThisValue, howToEvaluateThis.getContext()); + } + + ChangeContextUtil.encodeContextInfo(result, false); + PsiExpression psiExpression; + try { + psiExpression = (PsiExpression) ChangeContextUtil.decodeContextInfo(result, thisClass, howToEvaluateThis); + } + catch (IncorrectOperationException e) { + throw new EvaluateException("Cannot substitute '" + result.getText() + "' into '" + howToEvaluateThis.getText() + "' as 'this'", null); + } + + try { + return howToEvaluateThis.getManager().getElementFactory().createExpressionFromText(psiExpression.getText(), howToEvaluateThis.getContext()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + public static PsiExpression castToRuntimeType(PsiExpression expression, Value value, PsiElement contextElement) throws EvaluateException { + if (value instanceof ObjectReference) { + return castToType(expression, ((ObjectReference)value).referenceType(), contextElement); + } + else { + return expression; + } + } + + private static PsiExpression castToType(PsiExpression expression, ReferenceType valueType, PsiElement contextElement) throws EvaluateException{ + if (valueType != null) { + Project project = expression.getProject(); + + String typeName = DebuggerUtilsEx.getQualifiedClassName(valueType.name(), project); + PsiManager manager = PsiManager.getInstance(project); + + typeName = normalize(typeName, contextElement, project); + + PsiElementFactory elementFactory = manager.getElementFactory(); + try { + PsiParenthesizedExpression parenthExpression = (PsiParenthesizedExpression)elementFactory.createExpressionFromText( + "((" + typeName + ")expression)", null); + ((PsiTypeCastExpression)parenthExpression.getExpression()).getOperand().replace(expression); + return parenthExpression; + } + catch (IncorrectOperationException e) { + throw new EvaluateException("Invalid type name '" + typeName + "'", e); + } + } + else { + return expression; + } + } + + /** + * @param qualifiedName the class qualified name to be resolved against the current execution context + * @return short name if the class could be resolved using short name, + * otherwise returns qualifiedName + */ + public static String normalize(final String qualifiedName, PsiElement contextElement, Project project) { + if (contextElement == null) { + return qualifiedName; + } + + final PsiManager psiManager = PsiManager.getInstance(project); + PsiClass aClass = psiManager.findClass(qualifiedName, GlobalSearchScope.allScope(project)); + if (aClass != null) { + return normalizePsiClass(aClass, contextElement, psiManager.getResolveHelper()); + } + return qualifiedName; + } + + private static String normalizePsiClass(PsiClass psiClass, PsiElement contextElement, PsiResolveHelper helper) { + String name = psiClass.getName(); + PsiClass aClass = helper.resolveReferencedClass(name, contextElement); + if (psiClass.equals(aClass)) { + return name; + } + PsiClass parentClass = psiClass.getContainingClass(); + if (parentClass != null) { + return normalizePsiClass(parentClass, contextElement, helper) + "." + name; + } + return psiClass.getQualifiedName(); + } + + public static PsiExpression getEvaluationExpression(DebuggerTreeNodeImpl node, DebuggerContextImpl context) throws EvaluateException { + if(node.getDescriptor() instanceof ValueDescriptorImpl) { + return ((ValueDescriptorImpl)node.getDescriptor()).getTreeEvaluation(node, context); + } + else { + LOG.assertTrue(false, node.getDescriptor() != null ? node.getDescriptor().getClass().getName() : "null"); + return null; + } + } + + public static TextWithImportsImpl createEvaluationText(final DebuggerTreeNodeImpl node, final DebuggerContextImpl context) { + return PsiDocumentManager.getInstance(context.getProject()).commitAndRunReadAction(new Computable() { + public TextWithImportsImpl compute() { + PsiExpression expressionText = null; + try { + expressionText = getEvaluationExpression(node, context); + } catch (EvaluateException e) { + LOG.error(e.getMessage()); + return null; + } + + if (expressionText == null) return null; + + return TextWithImportsImpl.createExpressionText(expressionText); + } + }); + } + + private static class IncorrectOperationRuntimeException extends RuntimeException { + private IncorrectOperationException myException; + + public IncorrectOperationRuntimeException(IncorrectOperationException exception) { + myException = exception; + } + + public IncorrectOperationException getException() { return myException; } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java new file mode 100644 index 00000000000..d16f281705e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java @@ -0,0 +1,236 @@ +/* + * Class DebuggerTreeNodeImpl + * @author Jeka + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.impl.DebuggerTreeRenderer; +import com.intellij.debugger.ui.impl.tree.TreeBuilder; +import com.intellij.debugger.ui.impl.tree.TreeBuilderNode; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.ui.SimpleColoredText; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.tree.MutableTreeNode; +import java.util.Map; + +public class DebuggerTreeNodeImpl extends TreeBuilderNode implements DebuggerTreeNode{ + private Icon myIcon; + private SimpleColoredText myText; + private DebuggerTree myTree; + private Map myProperties = new HashMap(); + protected boolean myIsStateRestored = false; + + private DebuggerTreeNodeImpl(DebuggerTree tree, NodeDescriptor descriptor) { + super(descriptor); + myTree = tree; + } + + public DebuggerTreeNodeImpl getParent() { + return (DebuggerTreeNodeImpl) super.getParent(); + } + + protected TreeBuilder getTreeBuilder() { + return myTree.getMutableModel(); + } + + public DebuggerTree getTree() { + return (DebuggerTree) getTreeBuilder().getUserObject(); + } + + public String toString() { + NodeDescriptorImpl descriptor = getDescriptor(); + return descriptor != null? descriptor.toString() : ""; + } + + public NodeDescriptorImpl getDescriptor() { + return (NodeDescriptorImpl)getUserObject(); + } + + public Project getProject() { + return getTree().getProject(); + } + + public void setRenderer(NodeRenderer renderer) { + ((ValueDescriptorImpl) getDescriptor()).setRenderer(renderer); + calcRepresentation(); + } + + private void updateCaches() { + final NodeDescriptorImpl descriptor = getDescriptor(); + myIcon = DebuggerTreeRenderer.getDescriptorIcon(descriptor); + myText = DebuggerTreeRenderer.getDescriptorText(descriptor, false); + } + + public Icon getIcon() { + return myIcon; + } + + public SimpleColoredText getText() { + return myText; + } + + public void clear() { + super.clear(); + myIcon = null; + myText = null; + } + + private void update(final DebuggerContextImpl context, final Runnable runnable, boolean labelOnly) { + if(!labelOnly) clear(); + + if(context != null && context.getDebugProcess() != null) { + getTree().saveState(this); + + myIcon = DebuggerTreeRenderer.getDescriptorIcon(MessageDescriptor.EVALUATING); + myText = DebuggerTreeRenderer.getDescriptorText(MessageDescriptor.EVALUATING, false); + + context.getDebugProcess().getManagerThread().invoke(new DebuggerContextCommandImpl(context) { + public void threadAction() { + runnable.run(); + } + + protected void commandCancelled() { + clear(); + getDescriptor().clear(); + updateCaches(); + + labelChanged(); + childrenChanged(); + } + }); + } + + labelChanged(); + if(!labelOnly) childrenChanged(); + } + + public void calcLabel() { + final DebuggerContextImpl context = getTree().getDebuggerContext(); + update( + context, + new Runnable() { + public void run() { + getDescriptor().updateRepresentation(context.createEvaluationContext(), new DescriptorLabelListener() { + public void labelChanged() { + updateCaches(); + DebuggerTreeNodeImpl.this.labelChanged(); + } + }); + } + }, true); + } + + public void calcRepresentation() { + final DebuggerContextImpl context = getTree().getDebuggerContext(); + update( + context, + new Runnable() { + public void run() { + getDescriptor().updateRepresentation(context.createEvaluationContext(), new DescriptorLabelListener() { + public void labelChanged() { + updateCaches(); + DebuggerTreeNodeImpl.this.labelChanged(); + } + }); + } + }, false); + } + + public void calcValue() { + final DebuggerContextImpl context = getTree().getDebuggerContext(); + update( + context, + new Runnable() { + public void run() { + EvaluationContextImpl evaluationContext = context.createEvaluationContext(); + getDescriptor().setContext(evaluationContext); + getDescriptor().updateRepresentation(evaluationContext, new DescriptorLabelListener() { + public void labelChanged() { + updateCaches(); + DebuggerTreeNodeImpl.this.labelChanged(); + } + }); + DebuggerTreeNodeImpl.this.childrenChanged(); + } + }, false); + } + + private void invoke(Runnable r) { + if(SwingUtilities.isEventDispatchThread()) { + r.run(); + } + else { + SwingUtilities.invokeLater(r); + } + } + + public void labelChanged() { + invoke(new Runnable() { + public void run() { + updateCaches(); + getTree().getMutableModel().nodeChanged(DebuggerTreeNodeImpl.this); + } + }); + } + + public void childrenChanged() { + invoke(new Runnable() { + public void run() { + getTree().getMutableModel().nodeStructureChanged(DebuggerTreeNodeImpl.this); + getTree().restoreState(DebuggerTreeNodeImpl.this); + } + }); + } + + public void add(MutableTreeNode newChild) { + super.add(newChild); //To change body of overriden methods use Options | File Templates. + } + + public DebuggerTreeNodeImpl add(MessageDescriptor message) { + DebuggerTreeNodeImpl node = getNodeFactory().createMessageNode(message); + add(node); + return node; + } + + public NodeManagerImpl getNodeFactory() { + return myTree.getNodeFactory(); + } + + public Object getProperty(Key key) { + return myProperties.get(key); + } + + public void putProperty(Key key, Object data) { + myProperties.put(key, data); + } + + public static DebuggerTreeNodeImpl createNodeNoUpdate(DebuggerTree tree, NodeDescriptor descriptor) { + DebuggerTreeNodeImpl node = new DebuggerTreeNodeImpl(tree, descriptor); + node.updateCaches(); + return node; + } + + protected static DebuggerTreeNodeImpl createNode(DebuggerTree tree, NodeDescriptorImpl descriptor, EvaluationContextImpl evaluationContext) { + final DebuggerTreeNodeImpl node = new DebuggerTreeNodeImpl(tree, descriptor); + descriptor.updateRepresentationNoNotify(evaluationContext, new DescriptorLabelListener() { + public void labelChanged() { + node.updateCaches(); + node.labelChanged(); + } + }); + node.updateCaches(); + return node; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DefaultNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DefaultNodeDescriptor.java new file mode 100644 index 00000000000..14c4790a8f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DefaultNodeDescriptor.java @@ -0,0 +1,33 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.diagnostic.Logger; + + +public final class DefaultNodeDescriptor extends NodeDescriptorImpl{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.DefaultNodeDescriptor"); + public boolean equals(Object obj) { + return obj instanceof DefaultNodeDescriptor; + } + + public int hashCode() { + return 0; + } + + public boolean isExpandable() { + return true; + } + + public void setContext(EvaluationContextImpl context) { + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) { + LOG.assertTrue(false); + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DescriptorTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DescriptorTree.java new file mode 100644 index 00000000000..4e95bdc38ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/DescriptorTree.java @@ -0,0 +1,54 @@ +package com.intellij.debugger.ui.impl.watch; + +import java.util.*; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class DescriptorTree { + private HashMap> myChildrenMap = new HashMap>(); + private List myRootChildren = new ArrayList(); + + public void addChild(NodeDescriptorImpl parent, NodeDescriptorImpl child) { + List children; + + if(parent == null) { + children = myRootChildren; + } + else { + children = myChildrenMap.get(parent); + if(children == null) { + children = new ArrayList(); + myChildrenMap.put(parent, children); + } + } + children.add(child); + } + + public List getChildren(NodeDescriptorImpl parent) { + if(parent == null) return myRootChildren; + + List children = myChildrenMap.get(parent); + return children != null ? children : Collections.EMPTY_LIST; + } + + public void dfst(DFSTWalker walker) { + dfstImpl(null, myRootChildren, walker); + } + + private void dfstImpl(NodeDescriptorImpl descriptor, List children, DFSTWalker walker) { + if(children != null) { + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + NodeDescriptorImpl child = iterator.next(); + walker.visit(descriptor, child); + dfstImpl(child, myChildrenMap.get(child), walker); + } + } + } + + public interface DFSTWalker { + void visit(NodeDescriptorImpl parent, NodeDescriptorImpl child); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java new file mode 100644 index 00000000000..a111d88f8fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java @@ -0,0 +1,94 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.engine.evaluation.expression.Modifier; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionCodeFragment; +import com.intellij.debugger.EvaluatingComputable; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.EvaluatingComputable; +import com.sun.jdi.Value; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 12, 2004 + * Time: 5:24:17 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ + private Modifier myModifier; + protected TextWithImportsImpl myText; + + protected EvaluationDescriptor(TextWithImportsImpl text, Project project, Value value) { + super(project, value); + myText = text; + } + + protected EvaluationDescriptor(TextWithImportsImpl text, Project project) { + super(project); + setLvalue(false); + myText = text; + } + + protected abstract EvaluationContextImpl getEvaluationContext (EvaluationContextImpl evaluationContext); + protected abstract PsiCodeFragment getEvaluationCode (StackFrameContext context) throws EvaluateException; + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + try { + final EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext); + + final ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl.getInstance().build(getEvaluationCode(thisEvaluationContext)); + } + }); + + + if(!thisEvaluationContext.getDebugProcess().isAttached()) throw EvaluateExceptionUtil.PROCESS_EXITED; + StackFrameProxyImpl frameProxy = thisEvaluationContext.getFrameProxy(); + if (frameProxy == null) throw EvaluateExceptionUtil.NULL_STACK_FRAME; + + evaluator.evaluate(thisEvaluationContext); + + setLvalue(evaluator.getModifier() != null); + myModifier = evaluator.getModifier(); + return evaluator.getValue(); + } catch (final EvaluateException ex) { + throw new EvaluateException(ex.getMessage() + " Failed to evaluate expression", ex); + } + } + + public String calcValueName() { + return getName(); + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { + PsiElement evaluationCode = getEvaluationCode(context); + if(evaluationCode instanceof PsiExpressionCodeFragment) { + return ((PsiExpressionCodeFragment)evaluationCode).getExpression(); + } else { + throw new EvaluateException("Cannot create expression from code fragment.", null); + } + } + + public Modifier getModifier() { + return myModifier; + } + + public boolean canSetValue() { + return super.canSetValue() && myModifier != null && myModifier.canSetValue(); + } + + public TextWithImports getEvaluationText() { + return myText; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java new file mode 100644 index 00000000000..d0a5d71d675 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java @@ -0,0 +1,130 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.ui.tree.FieldDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.*; + +public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDescriptor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl"); + private final Field myField; + private ObjectReference myObject; + private Boolean myIsPrimitive = null; + private final boolean myIsStatic; + + public FieldDescriptorImpl(Project project, ObjectReference objRef, Field field) { + super(project); + myObject = objRef; + myField = field; + myIsStatic = field.isStatic(); + setLvalue(!field.isFinal()); + LOG.assertTrue(myField != null); + } + + public Field getField() { + return myField; + } + + public ObjectReference getObject() { + return myObject; + } + + public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) { + if (context.getFrameProxy() == null) return null; + final ReferenceType type = myField.declaringType(); + final PsiManager psiManager = PsiManager.getInstance(project); + final String fieldName = myField.name(); + if (fieldName.startsWith("val$")) { + // this field actually mirrors a local variable in the outer class + String varName = fieldName.substring(fieldName.lastIndexOf('$') + 1); + PsiElement element = PositionUtil.getContextElement(context); + if (element == null) return null; + PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); + if (aClass == null) return null; + aClass = (PsiClass) aClass.getNavigationElement(); + PsiVariable psiVariable = psiManager.getResolveHelper().resolveReferencedVariable(varName, aClass); + if (psiVariable == null) return null; + return SourcePosition.createFromOffset(psiVariable.getContainingFile(), psiVariable.getTextOffset()); + } + else { + PsiClass aClass = psiManager.findClass(type.name().replace('$', '.'), GlobalSearchScope.allScope(myProject)); + if (aClass == null) return null; + aClass = (PsiClass) aClass.getNavigationElement(); + PsiField[] fields = aClass.getFields(); + for (int i = 0; i < fields.length; i++) { + PsiField field = fields[i]; + if (field.getName().equals(fieldName)) { + return SourcePosition.createFromOffset(field.getContainingFile(), field.getTextOffset()); + } + } + return null; + } + } + + public boolean isPrimitive() { + if (myIsPrimitive == null) { + try { + myIsPrimitive = (myField.type() instanceof PrimitiveType)? Boolean.TRUE : Boolean.FALSE; + } + catch (Exception e) { + return super.isPrimitive(); + } + } + return myIsPrimitive.booleanValue(); + } + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + if ((myObject != null)? !VirtualMachineProxyImpl.isCollected(myObject) : true) { + return (myObject != null) ? myObject.getValue(myField) : myField.declaringType().getValue(myField); + } + else { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } + } + + public boolean isStatic() { + return myIsStatic; + } + + public String getName() { + return myField.name(); + } + + public String calcValueName() { + return getName() + ": " + myField.typeName(); + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { + PsiElementFactory elementFactory = PsiManager.getInstance(context.getProject()).getElementFactory(); + String fieldName; + if(isStatic()) { + String typeName = myField.declaringType().name().replace('$', '.'); + typeName = DebuggerTreeNodeExpression.normalize(typeName, PositionUtil.getContextElement(context), context.getProject()); + fieldName = typeName + "." + getName(); + } + else { + fieldName = "this." + getName(); + } + try { + return (PsiReferenceExpression)elementFactory.createExpressionFromText(fieldName, null); + } + catch (IncorrectOperationException e) { + throw new EvaluateException("Invalid field name '" + getName() + "'", e); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java new file mode 100644 index 00000000000..e38cce7abab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java @@ -0,0 +1,134 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.ui.tree.LocalVariableDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.LocalVariable; +import com.sun.jdi.PrimitiveType; +import com.sun.jdi.Value; + +public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements LocalVariableDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl"); + + private final StackFrameProxyImpl myFrameProxy; + private final LocalVariableProxyImpl myLocalVariable; + + private String myTypeName = ""; + private boolean myIsPrimitive; + + private boolean myIsNewLocal = true; + private boolean myIsVisible = true; + + public LocalVariableDescriptorImpl(Project project, + LocalVariableProxyImpl local) { + super(project); + setLvalue(true); + LOG.assertTrue(local != null); + myFrameProxy = local.getFrame(); + myLocalVariable = local; + } + + private boolean calcPrimitive(LocalVariable local, EvaluationContextImpl evaluationContext) { + try { + return local.type() instanceof PrimitiveType; + } + catch (ClassNotLoadedException e) { + try { + evaluationContext.getDebugProcess().loadClass(evaluationContext, myTypeName, + evaluationContext.getClassLoader()); + return local.type() instanceof PrimitiveType; + } + catch (Exception e1) { + LOG.debug(e1); + } + } + return false; + } + + public LocalVariableProxyImpl getLocalVariable() { + return myLocalVariable; + } + + public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) { + StackFrameProxyImpl frame = context.getFrameProxy(); + if (frame == null) return null; + + PsiElement place = PositionUtil.getContextElement(context); + + if (place == null) { + return null; + } + + PsiVariable psiVariable = PsiManager.getInstance(project).getResolveHelper().resolveReferencedVariable(getName(), place); + if (psiVariable == null) { + return null; + } + + PsiFile containingFile = psiVariable.getContainingFile(); + if(containingFile == null) return null; + + return SourcePosition.createFromOffset(containingFile, psiVariable.getTextOffset()); + } + + public boolean isNewLocal() { + return myIsNewLocal; + } + + public boolean isPrimitive() { + return myIsPrimitive; + } + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + myIsVisible = myFrameProxy.isLocalVariableVisible(getLocalVariable()); + if (myIsVisible) { + myTypeName = getLocalVariable().getVariable().typeName(); + myIsPrimitive = calcPrimitive(getLocalVariable().getVariable(), evaluationContext); + return myFrameProxy.getValue(getLocalVariable()); + } + + return null; + } + + public void setNewLocal(boolean aNew) { + myIsNewLocal = aNew; + } + + public void displayAs(NodeDescriptorImpl descriptor) { + super.displayAs(descriptor); + if(descriptor instanceof LocalVariableDescriptorImpl) { + myIsNewLocal = ((LocalVariableDescriptorImpl)descriptor).myIsNewLocal; + } + } + + public String getName() { + return myLocalVariable.name(); + } + + public String calcValueName() { + if (myIsVisible) { + return getName() + ": " + myTypeName; + } + return getName() + ": " + myTypeName; + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { + PsiElementFactory elementFactory = PsiManager.getInstance(context.getProject()).getElementFactory(); + try { + return elementFactory.createExpressionFromText(getName(), PositionUtil.getContextElement(context)); + } + catch (IncorrectOperationException e) { + throw new EvaluateException("Invalid local variable name '" + getName() + "'", e); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MarkedDescriptorTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MarkedDescriptorTree.java new file mode 100644 index 00000000000..64993a51e5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MarkedDescriptorTree.java @@ -0,0 +1,44 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.impl.descriptors.data.DescriptorData; +import com.intellij.debugger.impl.descriptors.data.DescriptorKey; +import com.intellij.util.containers.*; + +import java.util.*; +import java.util.HashMap; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class MarkedDescriptorTree { + private HashMap> myChildrenMap = new HashMap>(); + private Map myRootChildren = new com.intellij.util.containers.HashMap(); + + public void addChild(NodeDescriptorImpl parent, T child, DescriptorKey key) { + Map children; + + if(parent == null) { + children = myRootChildren; + } + else { + children = myChildrenMap.get(parent); + if(children == null) { + children = new com.intellij.util.containers.HashMap(); + myChildrenMap.put(parent, children); + } + } + children.put(key, child); + } + + public T getChild(NodeDescriptorImpl parent, DescriptorKey key) { + if(parent == null) return (T)myRootChildren.get(key); + Map map = myChildrenMap.get(parent); + return (T)(map != null ? map.get(key) : null); + } + + public void clear() { + myChildrenMap.clear(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java new file mode 100644 index 00000000000..55892b62368 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java @@ -0,0 +1,59 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.diagnostic.Logger; + +public class MessageDescriptor extends NodeDescriptorImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.MessageDescriptor"); + + public static final int ERROR = 0; + public static final int WARNING = 1; + public static final int INFORMATION = 2; + public static final int SPECIAL = 3; + private int myKind; + private String myMessage; + + public static MessageDescriptor DEBUG_INFO_UNAVAILABLE = new MessageDescriptor("Debug info unavailable"); + public static MessageDescriptor LOCAL_VARIABLES_INFO_UNAVAILABLE = new MessageDescriptor("Local variables debug info unavailable"); + public static MessageDescriptor ALL_ELEMENTS_IN_VISIBLE_RANGE_ARE_NULL = new MessageDescriptor("All elements in visible range are null"); + public static MessageDescriptor ALL_ELEMENTS_IN_RANGE_ARE_NULL = new MessageDescriptor("All elements are null"); + public static MessageDescriptor ARRAY_IS_EMPTY = new MessageDescriptor("Empty"); + public static MessageDescriptor CLASS_HAS_NO_FIELDS = new MessageDescriptor("Class has no fields"); + public static MessageDescriptor OBJECT_COLLECTED = new MessageDescriptor("Object was garbage collected during method invokation"); + public static MessageDescriptor EVALUATING = new MessageDescriptor(NodeDescriptorImpl.EVALUATING_MESSAGE); + public static MessageDescriptor THREAD_IS_RUNNING = new MessageDescriptor("Thread is running"); + public static MessageDescriptor THREAD_IS_EMPTY = new MessageDescriptor("Thread has no frames"); + + public MessageDescriptor(String message) { + this(message, INFORMATION); + } + + public MessageDescriptor(String message, int kind) { + myKind = kind; + myMessage = message; + } + + public int getKind() { + return myKind; + } + + public String getLabel() { + return myMessage; + } + + public boolean isExpandable() { + return false; + } + + public void setContext(EvaluationContextImpl context) { + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return myMessage; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java new file mode 100644 index 00000000000..239f6274780 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java @@ -0,0 +1,184 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.jdi.LocalVariableProxy; +import com.intellij.debugger.impl.descriptors.data.*; +import com.intellij.debugger.jdi.LocalVariableProxyImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.NodeDescriptorFactory; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.*; + +import java.util.HashMap; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.NodeDescriptorFactoryImpl"); + private DescriptorTree myCurrentDescriptors = new DescriptorTree(); + + private DescriptorTreeSearcher myDescriptorSearcher; + private DescriptorTreeSearcher myDisplayDescriptorSearcher; + + protected final Project myProject; + + public NodeDescriptorFactoryImpl(Project project) { + myProject = project; + myDescriptorSearcher = new DescriptorTreeSearcher(new MarkedDescriptorTree()); + myDisplayDescriptorSearcher = new DisplayDescriptorTreeSearcher(new MarkedDescriptorTree()); + } + + private T getDescriptor(NodeDescriptorImpl parent, DescriptorData data) { + T descriptor = data.createDescriptor(myProject); + + T oldDescriptor = findDescriptor(parent, descriptor, data); + + if(oldDescriptor != null && oldDescriptor.getClass() == descriptor.getClass()) { + descriptor.setAncestor(oldDescriptor); + } + else { + T displayDescriptor = findDisplayDescriptor(parent, descriptor, data.getDisplayKey()); + if(displayDescriptor != null) { + descriptor.displayAs(displayDescriptor); + } + } + + myCurrentDescriptors.addChild(parent, descriptor); + + return descriptor; + } + + protected T findDisplayDescriptor(NodeDescriptorImpl parent, T descriptor, DisplayKey key) { + return myDisplayDescriptorSearcher.search(parent, descriptor, key); + } + + protected T findDescriptor(NodeDescriptorImpl parent, T descriptor, DescriptorData data) { + return myDescriptorSearcher.search(parent, descriptor, data); + } + + public DescriptorTree createHistoryTree() { + return myCurrentDescriptors; + } + + public void setHistoryTree(DescriptorTree tree) { + final MarkedDescriptorTree descriptorTree = new MarkedDescriptorTree(); + tree.dfst(new DescriptorTree.DFSTWalker() { + public void visit(NodeDescriptorImpl parent, NodeDescriptorImpl child) { + descriptorTree.addChild(parent, child, DescriptorData.getDescriptorData(child)); + } + }); + + final MarkedDescriptorTree displayDescriptorTree = new MarkedDescriptorTree(); + tree.dfst(new DescriptorTree.DFSTWalker() { + public void visit(NodeDescriptorImpl parent, NodeDescriptorImpl child) { + displayDescriptorTree.addChild(parent, child, DescriptorData.getDescriptorData(child).getDisplayKey()); + } + }); + + myDescriptorSearcher = new DescriptorTreeSearcher(descriptorTree); + myDisplayDescriptorSearcher = new DisplayDescriptorTreeSearcher(displayDescriptorTree); + + myCurrentDescriptors = new DescriptorTree(); + } + + public ArrayElementDescriptorImpl getArrayItemDescriptor(NodeDescriptor parent, ArrayReference array, int index) { + return getDescriptor((NodeDescriptorImpl)parent, new ArrayItemData(array, index)); + } + + public FieldDescriptorImpl getFieldDescriptor(NodeDescriptor parent, ObjectReference objRef, Field field) { + final DescriptorData descriptorData; + if (objRef == null ) { + if (!field.isStatic()) { + LOG.assertTrue(false, "Object reference is null for non-static field: " + field); + } + descriptorData = new StaticFieldData(field); + } + else { + descriptorData = new FieldData(objRef, field); + } + return getDescriptor((NodeDescriptorImpl)parent, descriptorData); + } + + public LocalVariableDescriptorImpl getLocalVariableDescriptor(NodeDescriptor parent, LocalVariableProxy local) { + return getDescriptor((NodeDescriptorImpl)parent, new LocalData((LocalVariableProxyImpl)local)); + } + + public StackFrameDescriptorImpl getStackFrameDescriptor(NodeDescriptorImpl parent, StackFrameProxyImpl frameProxy) { + return getDescriptor(parent, new StackFrameData(frameProxy)); + } + + public StaticDescriptorImpl getStaticDescriptor(NodeDescriptorImpl parent, ReferenceType refType) {//static is unique + return getDescriptor(parent, new StaticData(refType)); + } + + public ValueDescriptorImpl getThisDescriptor(NodeDescriptorImpl parent, Value value) { + return getDescriptor((NodeDescriptorImpl)parent, new ThisData(value)); + } + + public ThreadDescriptorImpl getThreadDescriptor(NodeDescriptorImpl parent, ThreadReferenceProxyImpl thread) { + return getDescriptor((NodeDescriptorImpl)parent, new ThreadData(thread)); + } + + public ThreadGroupDescriptorImpl getThreadGroupDescriptor(NodeDescriptorImpl parent, ThreadGroupReferenceProxyImpl group) { + return getDescriptor((NodeDescriptorImpl)parent, new ThreadGroupData(group)); + } + + public UserExpressionDescriptorImpl getUserExpressionDescriptor(ValueDescriptor parent, String typeName, String name, TextWithImports expression) { + return getDescriptor((NodeDescriptorImpl)parent, new UserExpressionData((ValueDescriptorImpl)parent, typeName, name, (TextWithImportsImpl)expression)); + } + + private static class DescriptorTreeSearcher { + private final MarkedDescriptorTree myDescriportTree; + + private final HashMap mySearchedDescriptors = new HashMap(); + + public DescriptorTreeSearcher(MarkedDescriptorTree descriportTree) { + myDescriportTree = descriportTree; + } + + public T search(NodeDescriptorImpl parent, T descriptor, DescriptorKey key) { + T result = searchImpl(parent, key); + if(result != null) { + mySearchedDescriptors.put(descriptor, result); + } + return result; + } + + private T searchImpl(NodeDescriptorImpl parent, DescriptorKey key) { + if(parent == null) { + return myDescriportTree.getChild(null, key); + } + else { + NodeDescriptorImpl parentDescriptor = getSearched(parent); + return parentDescriptor != null ? myDescriportTree.getChild(parentDescriptor, key) : null; + } + } + + protected NodeDescriptorImpl getSearched(NodeDescriptorImpl parent) { + return mySearchedDescriptors.get(parent); + } + } + + private class DisplayDescriptorTreeSearcher extends DescriptorTreeSearcher { + public DisplayDescriptorTreeSearcher(MarkedDescriptorTree descriportTree) { + super(descriportTree); + } + + protected NodeDescriptorImpl getSearched(NodeDescriptorImpl parent) { + NodeDescriptorImpl searched = super.getSearched(parent); + if(searched == null) { + return myDescriptorSearcher.getSearched(parent); + } + return searched; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java new file mode 100644 index 00000000000..e170535209b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java @@ -0,0 +1,131 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.util.containers.HashMap; +import com.sun.jdi.InconsistentDebugInfoException; +import com.sun.jdi.InvalidStackFrameException; + +import java.util.List; +import java.util.ArrayList; + +public abstract class NodeDescriptorImpl implements NodeDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl"); + + public static final String UNKNOWN_VALUE_MESSAGE = ""; + public boolean myIsExpanded = false; + public boolean myIsSelected = false; + public boolean myIsVisible = false; + public boolean myIsSynthetic = false; + + private EvaluateException myEvaluateException; + private String myLabel = ""; + + private HashMap myUserData; + + private final List myChildren = new ArrayList(); + + public String getName() { + return null; + } + + public T getUserData(Key key) { + if(myUserData == null) return null; + return (T) myUserData.get(key); + } + + public void putUserData(Key key, T value) { + if(myUserData == null) { + myUserData = new HashMap(); + } + myUserData.put(key, value); + } + + public void updateRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener){ + updateRepresentationNoNotify(context, labelListener); + labelListener.labelChanged(); + } + + protected void updateRepresentationNoNotify(EvaluationContextImpl context, DescriptorLabelListener labelListener) { + try { + try { + myEvaluateException = null; + myLabel = calcRepresentation(context, labelListener); + } + catch (RuntimeException e) { + LOG.debug(e); + throw processException(e); + } + } + catch (EvaluateException e) { + setFailed(e); + } + } + + protected abstract String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException; + + private EvaluateException processException(Exception e) { + if(e instanceof InconsistentDebugInfoException) { + return new EvaluateException("Inconsistent debug information. Cannot show value. ", null); + } + + else if(e instanceof InvalidStackFrameException) { + return new EvaluateException("Internal exception - invalid stackframe. Cannot show value. ", null); + } + else { + return EvaluateExceptionUtil.DEBUG_INFO_UNAVAILABLE; + } + } + + public void displayAs(NodeDescriptorImpl descriptor) { + myIsExpanded = descriptor.myIsExpanded; + myIsSelected = descriptor.myIsSelected; + myIsVisible = descriptor.myIsVisible; + myUserData = descriptor.myUserData != null ? new HashMap(descriptor.myUserData) : null; + } + + public abstract boolean isExpandable(); + + public abstract void setContext(EvaluationContextImpl context); + + public EvaluateException getEvaluateException() { + return myEvaluateException; + } + + public String getLabel() { + return myLabel; + } + + public String toString() { + return getLabel(); + } + + protected String setFailed(EvaluateException e) { + myEvaluateException = e; + return e.getMessage(); + } + + protected String setLabel(String customLabel) { + myLabel = customLabel; + return myLabel; + } + + //Context is set to null + public void clear() { + myEvaluateException = null; + myLabel = ""; + } + + public List getChildren() { + return myChildren; + } + + public void setAncestor(NodeDescriptorImpl oldDescriptor) { + displayAs(oldDescriptor); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java new file mode 100644 index 00000000000..89684a310f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java @@ -0,0 +1,81 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.impl.nodes.NodeComparator; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.NodeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.Convertor; +import com.sun.jdi.event.Event; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + ** finds correspondence between new descriptor and one created on the previous steps + ** stores maximum CACHED_STEPS steps + ** call saveState function to start new step + */ + +public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeManager{ + private static Comparator ourNodeComparator = new NodeComparator(); + + private final DebuggerTree myDebuggerTree; + private List myBreakpoints = Collections.EMPTY_LIST; + + public NodeManagerImpl(Project project, DebuggerTree tree) { + super(project); + myDebuggerTree = tree; + } + + public static Comparator getNodeComparator() { return ourNodeComparator; } + + public DebuggerTreeNodeImpl createNode(NodeDescriptor descriptor, EvaluationContext evaluationContext) { + ((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext); + DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNode(getTree(), (NodeDescriptorImpl)descriptor, (EvaluationContextImpl)evaluationContext); + return node; + } + + public DebuggerTreeNodeImpl getDefaultNode() { + return DebuggerTreeNodeImpl.createNodeNoUpdate(getTree(), new DefaultNodeDescriptor()); + } + + public DebuggerTreeNodeImpl createMessageNode(MessageDescriptor descriptor) { + DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNodeNoUpdate(getTree(), descriptor); + return node; + } + + public DebuggerTreeNodeImpl createMessageNode(String message) { + DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNodeNoUpdate(getTree(), new MessageDescriptor(message)); + return node; + } + + public void setHistoryByContext(final DebuggerContextImpl context) { + final DebugProcessImpl debugProcess = context.getDebugProcess(); + debugProcess.getDescriptorHistoryManager().storeHistory(new DescriptorHistory(createHistoryTree(), myBreakpoints)); + + DescriptorHistory history = debugProcess.getDescriptorHistoryManager().restoreHistory(context); + + setHistoryTree(history.getDescriptorTree()); + + List> eventDescriptors = DebuggerUtilsEx.getEventDescriptors(context.getSuspendContext()); + myBreakpoints = CollectUtil.COLLECT.toList(eventDescriptors, new Convertor, Breakpoint>() { + public Breakpoint convert(Pair o) { + return o.getFirst(); + } + }); + } + + private DebuggerTree getTree() { + return myDebuggerTree; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java new file mode 100644 index 00000000000..92d1ff20868 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java @@ -0,0 +1,135 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.settings.ThreadsViewSettings; +import com.intellij.debugger.ui.tree.StackFrameDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.util.IconLoader; +import com.sun.jdi.AbsentInformationException; +import com.sun.jdi.Location; +import com.sun.jdi.Method; +import com.sun.jdi.ReferenceType; + +import javax.swing.*; + +/** + * Nodes of this type cannot be updated, because StackFrame objects become invalid as soon as VM has been resumed + */ +public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements StackFrameDescriptor{ + private final StackFrameProxyImpl myFrame; + private String myName = null; + private Location myLocation; + + private static Icon myStackFrameIcon = IconLoader.getIcon("/debugger/stackFrame.png");; + private static Icon myObsoleteFrameIcon = IconLoader.getIcon("/debugger/db_obsolete.png"); + private Icon myIcon = myStackFrameIcon; + + public StackFrameDescriptorImpl(StackFrameProxyImpl frame) { + myFrame = frame; + } + + public StackFrameProxyImpl getStackFrame() { + return myFrame; + } + + public String getName() { + return myName; + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener descriptorLabelListener) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ThreadsViewSettings settings = ThreadsViewSettings.getInstance(); + StringBuffer label = new StringBuffer(); + Location location = myFrame.location(); + Method method = location.method(); + if (method != null) { + myName = method.name(); + label.append(myName); + label.append("()"); + } + if (settings.SHOW_LINE_NUMBER) { + String lineNumber = null; + try { + lineNumber = Integer.toString(location.lineNumber()); + } + catch (InternalError e) { + lineNumber = e.toString(); + } + if (lineNumber != null) { + label.append(':'); + label.append(lineNumber); + } + } + if (settings.SHOW_CLASS_NAME) { + String name = null; + try { + ReferenceType refType = location.declaringType(); + name = refType != null ? refType.name() : null; + } + catch (InternalError e) { + name = e.toString(); + } + if (name != null) { + label.append(", "); + label.append(name); + } + } + if (settings.SHOW_SOURCE_NAME) { + try { + String sourceName; + try { + sourceName = location.sourceName(); + } + catch (InternalError e) { + sourceName = e.toString(); + } + label.append(", "); + label.append(sourceName); + } + catch (AbsentInformationException exception) { + } + } + return label.toString(); + } + + public final boolean stackFramesEqual(StackFrameDescriptorImpl d) { + return getStackFrame().equals(d.getStackFrame()); + } + + public boolean isExpandable() { + return true; + } + + public void setContext(EvaluationContextImpl context) { + try { + myLocation = myFrame.location(); + } + catch (EvaluateException e) { + myLocation = null; + } + + myIcon = calcIcon(); + } + + public Location getLocation() { + return myLocation; + } + + private Icon calcIcon() { + try { + if(getStackFrame().isObsolete()) { + return myObsoleteFrameIcon; + } + } + catch (EvaluateException e) { + } + return myStackFrameIcon; + } + + public Icon getIcon() { + return myIcon; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java new file mode 100644 index 00000000000..1ae43ddad26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java @@ -0,0 +1,57 @@ +/* + * Class StaticDescriptorImpl + * @author Jeka + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.ui.tree.StaticDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.Field; +import com.sun.jdi.ReferenceType; + +import java.util.Iterator; + +public class StaticDescriptorImpl extends NodeDescriptorImpl implements StaticDescriptor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.StaticDescriptorImpl"); + + private final ReferenceType myType; + private final boolean myHasStaticFields; + + public StaticDescriptorImpl(ReferenceType refType) { + myType = refType; + + boolean hasStaticFields = false; + for (Iterator it = myType.allFields().iterator(); it.hasNext();) { + Field field = (Field)it.next(); + if (field.isStatic()) { + hasStaticFields = true; + break; + } + } + myHasStaticFields = hasStaticFields; + } + + public ReferenceType getType() { + return myType; + } + + public String getName() { + return "static"; + } + + public boolean isExpandable() { + return myHasStaticFields; + } + + public void setContext(EvaluationContextImpl context) { + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener descriptorLabelListener) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return getName() + " = " + myType.name(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThisDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThisDescriptorImpl.java new file mode 100644 index 00000000000..fa835cb8d6c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThisDescriptorImpl.java @@ -0,0 +1,54 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.DebuggerContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiManager; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.Value; + +/** + * User: lex + * Date: Oct 8, 2003 + * Time: 5:08:07 PM + */ +public class ThisDescriptorImpl extends ValueDescriptorImpl{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.ThisDescriptorImpl"); + private final Value myValue; + + public ThisDescriptorImpl(Project project, Value value) { + super(project); + myValue = value; + } + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + return myValue; + } + + public String getName () { return "this"; } + + public String calcValueName() { + return getName(); + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) { + PsiElementFactory elementFactory = PsiManager.getInstance(context.getProject()).getElementFactory(); + try { + return elementFactory.createExpressionFromText("this", null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + public boolean canSetValue() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadDescriptorImpl.java new file mode 100644 index 00000000000..6a40533a4a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadDescriptorImpl.java @@ -0,0 +1,158 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.SuspendManager; +import com.intellij.debugger.engine.SuspendManagerUtil; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.ui.tree.ThreadDescriptor; +import com.intellij.openapi.util.IconLoader; +import com.sun.jdi.ThreadReference; + +import javax.swing.*; + +public class ThreadDescriptorImpl extends NodeDescriptorImpl implements ThreadDescriptor{ + private final ThreadReferenceProxyImpl myThread; + private String myName = null; + private boolean myIsExpandable = true; + private boolean myIsSuspended = false; + private boolean myIsCurrent; + private boolean myIsFrozen; + + private boolean myIsAtBreakpoint; + private SuspendContextImpl mySuspendContext; + + private static Icon myRunningThreadIcon = IconLoader.getIcon("/debugger/threadRunning.png"); + private static Icon myCurrentThreadIcon = IconLoader.getIcon("/debugger/threadCurrent.png"); + private static Icon myThreadAtBreakpointIcon = IconLoader.getIcon("/debugger/threadAtBreakpoint.png"); + private static Icon myFrozenThreadIcon = IconLoader.getIcon("/debugger/threadFrozen.png"); + private static Icon mySuspendedThreadIcon = IconLoader.getIcon("/debugger/threadSuspended.png"); + + public ThreadDescriptorImpl(ThreadReferenceProxyImpl thread) { + myThread = thread; + } + + public String getName() { + return myName; + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ThreadReferenceProxyImpl thread = getThreadReference(); + if (thread.isCollected()) { + return myName != null ? "Thread \"" + myName + "\" is garbage-collected" : ""; + } + + myName = thread.name(); + String label = "Thread \"" + myName + "\"@" + thread.uniqueID(); + + ThreadGroupReferenceProxyImpl gr = getThreadReference().threadGroupProxy(); + String grname = (gr != null)? gr.name() : null; + + if (grname != null && !"SYSTEM".equals(grname.toUpperCase())) { + label += " in group \"" + grname + "\""; + } + + label += " status: " + DebuggerUtilsEx.getThreadStatusText(getThreadReference().status()); + + return label; + } + + public ThreadReferenceProxyImpl getThreadReference() { + return myThread; + } + + public boolean isCurrent() { + return myIsCurrent; + } + + public boolean isFrozen() { + return myIsFrozen; + } + + private boolean calcIsCurrent(EvaluationContextImpl evaluationContext) { + ThreadReferenceProxyImpl currentThread = evaluationContext.getSuspendContext().getThread(); + return currentThread == getThreadReference(); + } + + public boolean isExpandable() { + return myIsExpandable; + } + + public void setContext(EvaluationContextImpl context) { + ThreadReferenceProxyImpl thread = getThreadReference(); + + SuspendManager suspendManager = context.getDebugProcess().getSuspendManager(); + myIsSuspended = suspendManager.isSuspended(thread); + myIsExpandable = calcExpandable(suspendManager); + SuspendContextImpl threadContext = SuspendManagerUtil.findContextByThread(suspendManager, thread); + mySuspendContext = SuspendManagerUtil.getSuspendContextForThread(context.getSuspendContext(), thread); + myIsAtBreakpoint = threadContext != null; + myIsCurrent = calcIsCurrent(context); + myIsFrozen = suspendManager.isFrozen(getThreadReference()); + } + + private boolean calcExpandable(SuspendManager manager) { + ThreadReferenceProxyImpl threadProxy = getThreadReference(); + if (threadProxy.isCollected() || !manager.isSuspended(myThread)) { + return false; + } + int status = threadProxy.status(); + if (status == ThreadReference.THREAD_STATUS_UNKNOWN || + status == ThreadReference.THREAD_STATUS_NOT_STARTED || + status == ThreadReference.THREAD_STATUS_ZOMBIE) { + return false; + } + try { + return threadProxy.frameCount() > 0; + } + catch (EvaluateException e) { + //LOG.assertTrue(false); + // if we pause during evaluation of this method the exception is thrown + // private static void longMethod(){ + // try { + // Thread.sleep(100000); + // } catch (InterruptedException e) { + // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + // } + // } + return false; + } + } + + public SuspendContextImpl getSuspendContext() { + return mySuspendContext; + } + + public boolean isAtBreakpoint() { + return myIsAtBreakpoint; + } + + public boolean isSuspended() { + return myIsSuspended; + } + + public Icon getIcon() { + Icon nodeIcon; + if(isCurrent()) { + nodeIcon = myCurrentThreadIcon; + } + else if(isFrozen()) { + nodeIcon = myFrozenThreadIcon; + } + else if(isAtBreakpoint()) { + nodeIcon = myThreadAtBreakpointIcon; + } + else if(isSuspended()) { + nodeIcon = mySuspendedThreadIcon; + } else { + nodeIcon = myRunningThreadIcon; + } + return nodeIcon; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadGroupDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadGroupDescriptorImpl.java new file mode 100644 index 00000000000..e7f3373df87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ThreadGroupDescriptorImpl.java @@ -0,0 +1,66 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.ui.tree.ThreadGroupDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; + +public class ThreadGroupDescriptorImpl extends NodeDescriptorImpl implements ThreadGroupDescriptor{ + private final ThreadGroupReferenceProxyImpl myThreadGroup; + private boolean myIsCurrent; + private String myName = null; + private boolean myIsExpandable = true; + + public ThreadGroupDescriptorImpl(ThreadGroupReferenceProxyImpl threadGroup) { + myThreadGroup = threadGroup; + } + + public ThreadGroupReferenceProxyImpl getThreadGroupReference() { + return myThreadGroup; + } + + public boolean isCurrent() { + return myIsCurrent; + } + + public String getName() { + return myName; + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + ThreadGroupReferenceProxyImpl group = getThreadGroupReference(); + if (group.isCollected()) { + return myName != null ? "Thread Group \"" + myName + "\" is garbage-collected" : ""; + } + myName = group.name(); + + return "Thread Group \"" + myName + "\"@" + group.uniqueID(); + } + + public boolean isExpandable() { + return myIsExpandable; + } + + public void setContext(EvaluationContextImpl context) { + ThreadReferenceProxyImpl threadProxy = context.getSuspendContext().getThread(); + myIsCurrent = threadProxy != null && threadProxy.getThreadReference() != null && isDescendantGroup(threadProxy.threadGroupProxy()); + myIsExpandable = calcExpandable(); + } + + private boolean isDescendantGroup(ThreadGroupReferenceProxyImpl group) { + if(group == null) return false; + + if(getThreadGroupReference() == group) return true; + + return isDescendantGroup(group.parent()); + } + + private boolean calcExpandable() { + ThreadGroupReferenceProxyImpl group = getThreadGroupReference(); + return group.threads().size() > 0 || group.threadGroups().size() > 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java new file mode 100644 index 00000000000..9d8f343f072 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java @@ -0,0 +1,71 @@ +/* + * Class StaticDescriptorImpl + * @author Jeka + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.tree.UserExpressionDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiCodeFragment; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; + +public class UserExpressionDescriptorImpl extends EvaluationDescriptor implements UserExpressionDescriptor{ + private final ValueDescriptorImpl myParentDescriptor; + private final String myTypeName; + private final String myName; + + public UserExpressionDescriptorImpl(Project project, ValueDescriptorImpl parent, String typeName, String name, TextWithImportsImpl text) { + super(text, project); + myParentDescriptor = parent; + myTypeName = typeName; + myName = name; + } + + public String getName() { + return myName; + } + + public String calcValueName() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getName()); + buffer.append(": "); + if(getValue() != null) buffer.append(getValue().type().name()); + + return buffer.toString(); + } + + protected PsiCodeFragment getEvaluationCode(final StackFrameContext context) throws EvaluateException { + Value value = myParentDescriptor.getValue(); + + if(value instanceof ObjectReference) { + final String typeName = value.type().name(); + + PsiClass psiClass = DebuggerUtilsEx.findClass(myTypeName, myProject); + + if (psiClass == null) { + throw EvaluateExceptionUtil.createEvaluateException("Invalid type name " + typeName); + } + + return getEvaluationText().createCodeFragment(psiClass, myProject); + } + else { + throw EvaluateExceptionUtil.createEvaluateException("Object reference expected instead of" + myParentDescriptor.getName()); + } + } + + public ValueDescriptorImpl getParentDescriptor() { + return myParentDescriptor; + } + + protected EvaluationContextImpl getEvaluationContext(final EvaluationContextImpl evaluationContext) { + return evaluationContext.createEvaluationContext(myParentDescriptor.getValue()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java new file mode 100644 index 00000000000..bed5f18bd8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -0,0 +1,263 @@ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiExpression; +import com.sun.jdi.*; + +public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements ValueDescriptor{ + protected final Project myProject; + + NodeRenderer myRenderer = null; + + NodeRenderer myAutoRenderer = null; + + private Value myValue; + private EvaluateException myValueException; + + private String myValueLabel; + + protected boolean myIsNew = true; + private boolean myIsDirty = false; + private boolean myIsLvalue = false; + private boolean myIsExpandable; + + protected ValueDescriptorImpl(Project project, Value value) { + myProject = project; + myValue = value; + } + + protected ValueDescriptorImpl(Project project) { + myProject = project; + myIsNew = true; + } + + public boolean isArray () { return getValue() instanceof ArrayReference; } + public boolean isDirty () { return myIsDirty; } + public boolean isLvalue () { return myIsLvalue; } + public boolean isNull () { return getValue() == null; } + public boolean isPrimitive () { return getValue() instanceof PrimitiveValue; } + public boolean isIsNew () { return myIsNew; } + + public boolean isValueValid() { + return myValueException == null; + } + + public Value getValue () { return myValue; } + + public boolean isExpandable() { + return myIsExpandable; + } + + public abstract Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException; + + public final void setContext(EvaluationContextImpl evaluationContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + Value value = null; + try { + value = calcValue(evaluationContext); + + if(!myIsNew) { + myIsDirty = (value == null)? myValue != null : !value.equals(myValue); + if(myValue instanceof DoubleValue && Double.isNaN(((DoubleValue) myValue).doubleValue())){ + myIsDirty = !(value instanceof DoubleValue && Double.isNaN(((DoubleValue) myValue).doubleValue())); + } else if(myValue instanceof FloatValue && Float.isNaN(((FloatValue) myValue).floatValue())){ + myIsDirty = !(value instanceof FloatValue && Float.isNaN(((FloatValue) myValue).floatValue())); + } + } + myValue = value; + myValueException = null; + } + catch (EvaluateException e) { + myValueException = e; + myValue = null; + myIsExpandable = false; + } + + myIsNew = false; + } + + public void setAncestor(NodeDescriptorImpl oldDescriptor) { + super.setAncestor(oldDescriptor); + myIsNew = false; + myValue = ((ValueDescriptorImpl)oldDescriptor).getValue(); + } + + protected void setLvalue (boolean value) { + myIsLvalue = value; + } + + protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener){ + if(myValueException == null) { + myIsExpandable = getRenderer(context.getDebugProcess()).isExpandable(getValue(), context, this); + } + else { + myIsExpandable = false; + } + + return setValueLabel(calcValueLabel(context, labelListener)); + } + + private String getCustomLabel(String label) { + //translate only strings in quotes + StringBuffer buf = new StringBuffer(); + if(getValue() instanceof ObjectReference) { + String idLabel = makeIdLabel((ObjectReference)getValue()); + if(!label.startsWith(idLabel)) { + buf.append(idLabel); + } + } + if(label == null) { + buf.append("null"); + } else { + if(StringUtil.startsWithChar(label, '\"') && StringUtil.endsWithChar(label, '\"')) { + buf.append('"'); + buf.append(DebuggerUtils.translateStringValue(label.substring(1, label.length() - 1))); + buf.append('"'); + } else { + buf.append(DebuggerUtils.translateStringValue(label)); + } + } + return buf.toString(); + } + + private String makeIdLabel(ObjectReference ref) { + if(ref != null) { + return getIdLabel(ref); + } else + return ""; + } + + + public String setValueLabel(String label) { + String customLabel = getCustomLabel(label); + myValueLabel = customLabel; + + return setLabel(calcValueName() + " = " + customLabel); + } + + public String setValueLabelFailed(EvaluateException e) { + String label = setFailed(e); + setValueLabel(label); + return label; + } + + public abstract String calcValueName(); + + private String calcValueLabel(EvaluationContextImpl evaluationContext, final DescriptorLabelListener labelListener) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + if(myValueException != null) { + throw myValueException; + } + return getRenderer(evaluationContext.getDebugProcess()).calcLabel(this, evaluationContext, labelListener); + } + catch (EvaluateException e) { + return setValueLabelFailed(e); + } + } + + public void displayAs(NodeDescriptorImpl descriptor) { + if (descriptor instanceof ValueDescriptorImpl) { + ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; + myRenderer = valueDescriptor.myRenderer; + } + super.displayAs(descriptor); + } + + public NodeRenderer getLastRenderer() { + return myRenderer != null ? myRenderer: myAutoRenderer; + } + + public Type getType() { + Value value = getValue(); + return value != null ? value.type() : null; + } + + public NodeRenderer getRenderer (DebugProcessImpl debugProcess) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + Type type = getType(); + if(type != null && myRenderer != null && myRenderer.isApplicable(type)) + return myRenderer; + + myAutoRenderer = debugProcess.getNodeRendererManager().getAutoRenderer(this); + return myAutoRenderer; + } + + public void setRenderer (NodeRenderer renderer) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myRenderer = renderer; + myAutoRenderer = null; + } + + //returns expression that evaluates tree to this descriptor + public PsiExpression getTreeEvaluation(DebuggerTreeNodeImpl debuggerTreeNode, DebuggerContextImpl context) throws EvaluateException { + if(debuggerTreeNode.getParent() != null && debuggerTreeNode.getParent().getDescriptor() instanceof ValueDescriptor) { + NodeDescriptorImpl descriptor = ((DebuggerTreeNodeImpl)debuggerTreeNode.getParent()).getDescriptor(); + ValueDescriptorImpl vDescriptor = ((ValueDescriptorImpl)descriptor); + PsiExpression parentEvaluation = vDescriptor.getTreeEvaluation((DebuggerTreeNodeImpl)debuggerTreeNode.getParent(), context); + + return DebuggerTreeNodeExpression.substituteThis( + vDescriptor.getRenderer(context.getDebugProcess()).getChildrenValueExpression(debuggerTreeNode, context), + parentEvaluation, vDescriptor.getValue()); + } + else { + return getDescriptorEvaluation(context); + } + } + + //returns expression that evaluates descriptor value + //use 'this' to reference parent node + //for ex. FieldDescriptorImpl should return + //this.fieldName + public abstract PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException; + + public static String getIdLabel(ObjectReference objRef) { + StringBuffer buf = new StringBuffer(); + buf.append('{'); + buf.append(objRef.type().name()).append('@'); + if(ApplicationManager.getApplication().isUnitTestMode()) { + buf.append("uniqueID"); + } + else { + buf.append(objRef.uniqueID()); + } + buf.append('}'); + + if (objRef instanceof ArrayReference) { + int idx = buf.indexOf("["); + if(idx >= 0) { + buf.insert(idx + 1, Integer.toString(((ArrayReference)objRef).length())); + } + } + + return buf.toString(); + } + + public boolean canSetValue() { + return !myIsSynthetic && isLvalue(); + } + + public String getValueLabel() { + return myValueLabel; + } + + //Context is set to null + public void clear() { + super.clear(); + setValueLabel(""); + myIsExpandable = false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java new file mode 100644 index 00000000000..6e33895f590 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java @@ -0,0 +1,70 @@ +/* + * Class WatchItemDescriptor + * @author Jeka + */ +package com.intellij.debugger.ui.impl.watch; + +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.impl.PositionUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiElement; +import com.sun.jdi.Value; + +/** + * update(Value, boolean) method must be called whenever the state of the target VM changes + */ +public class WatchItemDescriptor extends EvaluationDescriptor { + private boolean myAllowBreakpoints; + + public WatchItemDescriptor(Project project, TextWithImportsImpl text, boolean allowBreakpoints) { + super(text, project); + setValueLabel(""); + myAllowBreakpoints = allowBreakpoints; + } + + public WatchItemDescriptor(Project project, TextWithImportsImpl text, Value value, boolean allowBreakpoints) { + super(text, project, value); + setValueLabel(""); + myAllowBreakpoints = allowBreakpoints; + } + + public String getName() { + return ((TextWithImportsImpl)getEvaluationText()).getText(); + } + + public void setNew() { + myIsNew = true; + } + + // call update() after setting a new expression + public void setEvaluationText(TextWithImportsImpl evaluationText) { + if (!Comparing.equal(getEvaluationText(), evaluationText)) { + setLvalue(false); + } + myText = evaluationText; + myIsNew = true; + setValueLabel(""); + } + + protected EvaluationContextImpl getEvaluationContext(EvaluationContextImpl evaluationContext) { + evaluationContext.setAllowBreakpoints(myAllowBreakpoints); + return evaluationContext; + } + + protected PsiCodeFragment getEvaluationCode(StackFrameContext context) throws EvaluateException { + final PsiElement psiContext = PositionUtil.getContextElement(context); + return getEvaluationText().createCodeFragment(psiContext, myProject); + } + + public void setAllowBreakpoints(boolean b) { + myAllowBreakpoints = b; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java new file mode 100644 index 00000000000..86c0787d732 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java @@ -0,0 +1,187 @@ +package com.intellij.debugger.ui.impl.watch.render; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.settings.ViewsGeneralSettings; +import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.MessageDescriptor; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.ui.tree.*; +import com.intellij.debugger.ui.tree.render.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiManager; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.ArrayReference; +import com.sun.jdi.ArrayType; +import com.sun.jdi.Type; +import com.sun.jdi.Value; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +/** + * User: lex + * Date: Sep 18, 2003 + * Time: 3:07:19 PM + */ +public class ArrayRenderer extends ReferenceRenderer implements NodeRenderer, Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ArrayRenderer"); + + public static final String UNIQUE_ID = "ArrayRenderer"; + + public int START_INDEX = 0; + public int END_INDEX = 100; + public int ENTRIES_LIMIT = 100; + private final static String MORE_ELEMENTS = "..."; + + public ArrayRenderer() { + } + + public RendererProvider getRendererProvider() { + return DefaultRendererProvider.getInstance(); + } + + public String getName() { + return "Default"; + } + + public void setName(String text) { + LOG.assertTrue(false); + } + + public String getUniqueId() { + return UNIQUE_ID; + } + + public ArrayRenderer clone() { + return (ArrayRenderer)super.clone(); + } + + public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) throws EvaluateException { + return ClassRenderer.calcLabel(descriptor); + } + + public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + List children = new ArrayList(); + NodeManagerImpl nodeManager = (NodeManagerImpl)builder.getNodeManager(); + NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager(); + + ArrayReference array = (ArrayReference)value; + if (array.length() > 0) { + int added = 0; + + if(ENTRIES_LIMIT > END_INDEX - START_INDEX + 1) ENTRIES_LIMIT = END_INDEX - START_INDEX; + if(ENTRIES_LIMIT <= 0) ENTRIES_LIMIT = 1; + + if(array.length() - 1 >= START_INDEX) { + int start = START_INDEX; + int end = array.length() - 1 < END_INDEX ? array.length() - 1 : END_INDEX; + + int idx; + + for (idx = start; idx <= end; idx++) { + DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext); + + if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue; + if(added >= (ENTRIES_LIMIT + 1)/ 2) break; + children.add(arrayItemNode); + added++; + } + + start = idx; + + List childrenTail = new ArrayList(); + for (idx = end; idx >= start; idx--) { + DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext); + + if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue; + if(added >= ENTRIES_LIMIT) break; + childrenTail.add(arrayItemNode); + added++; + } + + //array is printed in the following way + // ... + // items1...itemENTRIES_LIMIT/2 + // ... + // itemENTRIES_LIMIT/2+1...itemENTRIES_LIMIT + // ... + + //when itemENTRIES_LIMIT/2+1...itemENTRIES_LIMIT set is empty, we should not add middle "..." node + if(idx >= start && !(ENTRIES_LIMIT == 1 && END_INDEX < array.length())) { + children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + } + + for (ListIterator iterator = childrenTail.listIterator(childrenTail.size()); iterator.hasPrevious();) { + DebuggerTreeNode debuggerTreeNode = iterator.previous(); + children.add(debuggerTreeNode); + } + } + + if (added == 0) { + if(START_INDEX == 0 && array.length() - 1 <= END_INDEX) + children.add(nodeManager.createMessageNode(MessageDescriptor.ALL_ELEMENTS_IN_RANGE_ARE_NULL.getLabel())); + else + children.add(nodeManager.createMessageNode(MessageDescriptor.ALL_ELEMENTS_IN_VISIBLE_RANGE_ARE_NULL.getLabel())); + } + else { + if(START_INDEX > 0) { + children.add(0, nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + } + + if(END_INDEX < array.length()) { + children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + } + } + } + + builder.setChildren(children); + } + + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public PsiExpression getChildrenValueExpression(DebuggerTreeNode node, DebuggerContext context) { + LOG.assertTrue(node.getDescriptor() instanceof ArrayElementDescriptorImpl, node.getDescriptor().getClass().getName()); + ArrayElementDescriptorImpl descriptor = (ArrayElementDescriptorImpl)node.getDescriptor(); + + PsiElementFactory elementFactory = PsiManager.getInstance(node.getProject()).getElementFactory(); + try { + return elementFactory.createExpressionFromText("this[" + descriptor.getIndex() + "]", elementFactory.getArrayClass()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) { + return value instanceof ArrayReference && ((ArrayReference)value).length() > 0; + } + + public boolean isApplicable(Type type) { + if(type == null || !(type instanceof ArrayType)) return false; + + if("[]".equals(getClassName())) return true; + + return super.isApplicable(type); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java new file mode 100644 index 00000000000..86ed120adba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java @@ -0,0 +1,198 @@ +package com.intellij.debugger.ui.impl.watch.render; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.ui.impl.watch.MessageDescriptor; +import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.tree.*; +import com.intellij.debugger.ui.tree.render.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiManager; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.*; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * User: lex + * Date: Sep 17, 2003 + * Time: 2:04:00 PM + */ +public class ClassRenderer extends ReferenceRenderer implements NodeRenderer{ + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ClassRenderer"); + + public static final String UNIQUE_ID = "ClassRenderer"; + + public boolean SORT_ASCENDING = false; + public boolean SHOW_SYNTHETICS = true; + public boolean SHOW_STATIC = false; + public boolean SHOW_STATIC_FINAL = false; + public boolean CHILDREN_PHYSICAL = true; + + public ClassRenderer() { + } + + public String getUniqueId() { + return UNIQUE_ID; + } + + public ClassRenderer clone() { + return (ClassRenderer) super.clone(); + } + + public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) + throws EvaluateException { + return calcLabel(descriptor); + } + + protected static String calcLabel(ValueDescriptor descriptor) { + ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; + Value value = valueDescriptor.getValue(); + if (value instanceof ObjectReference) { + StringBuffer buf = new StringBuffer(32); + if (value instanceof StringReference) { + buf.append('\"'); + buf.append(((StringReference)value).value()); + buf.append('\"'); + } + else if (value instanceof ClassObjectReference) { + ReferenceType type = ((ClassObjectReference)value).reflectedType(); + buf.append((type != null)?type.name():"{...}"); + } + else { + buf.append(ValueDescriptorImpl.getIdLabel((ObjectReference)value)); + } + return buf.toString(); + } + else if(value == null) { + return "null"; + } else { + return "undefined"; + } + } + + public void buildChildren(final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + final ValueDescriptorImpl parentDescriptor = (ValueDescriptorImpl)builder.getParentDescriptor(); + final NodeManager nodeManager = builder.getNodeManager(); + final NodeDescriptorFactory nodeDescriptorFactory = builder.getDescriptorManager(); + + List children = new ArrayList(); + if (value instanceof ObjectReference) { + final ObjectReference objRef = (ObjectReference)value; + final ReferenceType refType = objRef.referenceType(); + // default ObjectReference processing + List fields = refType.allFields(); + if (fields.size() > 0) { + for (Iterator it = fields.iterator(); it.hasNext();) { + Field jdiField = (Field)it.next(); + if (!shouldDisplay(jdiField)) continue; + children.add(nodeManager.createNode(nodeDescriptorFactory.getFieldDescriptor(parentDescriptor, objRef, jdiField), evaluationContext)); + } + + if(SORT_ASCENDING) { + Collections.sort(children, NodeManagerImpl.getNodeComparator()); + } + } else { + children.add(nodeManager.createMessageNode(MessageDescriptor.CLASS_HAS_NO_FIELDS.getLabel())); + } + } + builder.setChildren(children); + } + + private boolean isSynthetic(TypeComponent typeComponent) { + if (typeComponent == null) return false; + VirtualMachine machine = typeComponent.virtualMachine(); + return machine != null && machine.canGetSyntheticAttribute() && typeComponent.isSynthetic(); + } + + + private boolean shouldDisplay(TypeComponent component) { + if (!SHOW_SYNTHETICS && isSynthetic(component)) { + return false; + } + if (!(component instanceof Field)) { + return true; + } + Field field = (Field)component; + + if(!SHOW_STATIC && field.isStatic()) return false; + + if(!SHOW_STATIC_FINAL && field.isStatic() && field.isFinal()) return false; + + return true; + } + + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public PsiExpression getChildrenValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException { + FieldDescriptor fieldDescriptor = (FieldDescriptor)node.getDescriptor(); + + PsiElementFactory elementFactory = PsiManager.getInstance(node.getProject()).getElementFactory(); + try { + return elementFactory.createExpressionFromText(fieldDescriptor.getField().name(), DebuggerUtils.findClass(fieldDescriptor.getObject().referenceType().name(), context.getProject())); + } + catch (IncorrectOperationException e) { + throw new EvaluateException("Invalid field name '" + fieldDescriptor.getField().name() + "'", null); + } + } + + private static boolean valueExpandable(Value value) { + try { + if(value instanceof ArrayReference) { + return ((ArrayReference)value).length() > 0; + } else if(value instanceof ObjectReference) { + return ((ObjectReference)value).referenceType().allFields().size() > 0; + } + } + catch (ObjectCollectedException e) { + return true; + } + + return false; + } + + public boolean isExpandable(Value value, + EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + return valueExpandable(value); + } + + public boolean isApplicable(Type type) { + if(!(type instanceof ReferenceType) || type instanceof ArrayType) return false; + return super.isApplicable(type); + } + + public RendererProvider getRendererProvider() { + return DefaultRendererProvider.getInstance(); + } + + public String getName() { + return "Default"; + } + + public void setName(String text) { + LOG.assertTrue(false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java new file mode 100644 index 00000000000..5a465dbc0fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java @@ -0,0 +1,127 @@ +package com.intellij.debugger.ui.impl.watch.render; + +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.StackFrameContext; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.debugger.ui.tree.NodeDescriptor; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.debugger.ui.tree.render.*; +import com.intellij.debugger.DebuggerContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiExpression; +import com.intellij.util.IncorrectOperationException; +import com.sun.jdi.*; +import org.jdom.Element; + +/** + * User: lex + * Date: Sep 18, 2003 + * Time: 3:07:27 PM + */ +public class PrimitiveRenderer implements NodeRenderer, Cloneable { + public static final String UNIQUE_ID = "PrimitiveRenderer"; + + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.PrimitiveRenderer"); + + public PrimitiveRenderer() { + } + + public RendererProvider getRendererProvider() { + return DefaultRendererProvider.getInstance(); + } + + public String getUniqueId() { + return UNIQUE_ID; + } + + public String getName() { + return "Default"; + } + + public void setName(String text) { + LOG.assertTrue(false, "Cannot set name for primitive renderer"); + } + + public PrimitiveRenderer clone(){ + try { + return (PrimitiveRenderer)super.clone(); + } + catch (CloneNotSupportedException e) { + LOG.assertTrue(false); + return null; + } + } + + public boolean isApplicable(Type type) { + if(type == null) return true; + return type instanceof PrimitiveType || type instanceof VoidType; + } + + public String calcLabel(ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) { + Value value = valueDescriptor.getValue(); + if(value == null) { + return "null"; + } else if (value instanceof PrimitiveValue) { + StringBuffer buf = new StringBuffer(16); + if (value instanceof CharValue) { + buf.append("'"); + buf.append(DebuggerUtilsEx.translateStringValue(value.toString())); + buf.append("' "); + long longValue = ((PrimitiveValue)value).longValue(); + buf.append(Long.toString(longValue)); + } + else if (value instanceof ByteValue) { + buf.append(value.toString()); + } + else if (value instanceof ShortValue) { + buf.append(value.toString()); + } + else if (value instanceof IntegerValue) { + buf.append(value.toString()); + } + else if (value instanceof LongValue) { + buf.append(value.toString()); + } + else { + buf.append(DebuggerUtilsEx.translateStringValue(value.toString())); + } + return buf.toString(); + } else { + return "undefined"; + } + } + + public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public ChildrenRenderer getChildrenRenderer() { + return this; + } + + public ValueLabelRenderer getLabelRenderer() { + return this; + } + + public PsiExpression getChildrenValueExpression(DebuggerTreeNode node, DebuggerContext context) { + LOG.assertTrue(false); + return null; + } + + public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java new file mode 100644 index 00000000000..212ad3dc6bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.diagnostic; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.ErrorLogger; +import com.intellij.openapi.diagnostic.IdeaLoggingEvent; +import com.intellij.openapi.util.SystemInfo; + +import javax.swing.*; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author kir + */ +public class DefaultIdeaErrorLogger implements ErrorLogger { + + private static boolean ourOomOccured = false; + private final List myEventsCache = Collections.synchronizedList(new ArrayList()); + + public boolean canHandle(IdeaLoggingEvent event) { + return !DialogAppender.RELEASE_BUILD || + ApplicationManagerEx.getApplicationEx().isInternal() || + event.getThrowable() instanceof OutOfMemoryError; + } + + public void handle(IdeaLoggingEvent event) { + showDialog(event); + } + + private void showDialog(IdeaLoggingEvent event) { + try { + if (event.getThrowable() instanceof OutOfMemoryError) { + processOOMError(event); + } + else { + if (ourOomOccured) { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "OutOfMemoryException occured before this problem and " + + "it can be the reason of current one. So we recommend " + + "you to restart your IDEA.", "Error", JOptionPane.ERROR_MESSAGE); + } + }); + return; + } + myEventsCache.add(event); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + while (myEventsCache.size() > 0) { + IdeaLoggingEvent event = myEventsCache.get(0); + ErrorOccuredDialog errorOccuredDialog = new ErrorOccuredDialog(event); + errorOccuredDialog.show(); + + if (errorOccuredDialog.isShouldClose()) { + try { + ApplicationManager.getApplication().exit(); + } + catch (Throwable e) { + System.exit(0); + } + } + myEventsCache.remove(0); + } + } + }); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private void processOOMError(IdeaLoggingEvent event) throws InterruptedException, InvocationTargetException { + final String logFilePath = getLogFilePath(); + + ourOomOccured = true; + event.getThrowable().printStackTrace(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + String message = "There's not enough memory to perform the requested operation."; + message += "\n" + "Please shutdown IDEA and increase -Xmx setting in " + getSettingsFilePath(); + message += "\n" + ReportMessages.getReportAddress(); + message += "\n" + "and attach the " + logFilePath; + message += "\n" + "with a brief description of what you were doing."; + + if (JOptionPane.showOptionDialog(JOptionPane.getRootFrame(), message, "Out of Memory", + JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, + new Object[]{"Shutdown", "Ignore"}, "Shutdown") == 0) { + try { + ApplicationManager.getApplication().exit(); + } + catch (Throwable e) { + System.exit(0); + } + } + } + }); + } + + private String getLogFilePath() { + String path = PathManager.getSystemPath() + "/log/idea.log file".replace('/', File.separatorChar); + try { + return new File(path).getAbsolutePath(); + } + catch (Exception e) { + return path; + } + } + + private String getSettingsFilePath() { + if (SystemInfo.isMac) { + return PathManager.getHomePath() + "/Contents/Info.plist"; + } + return PathManager.getBinPath() + "/idea.lax".replace('/', File.separatorChar); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/Diagnostic.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/Diagnostic.java new file mode 100644 index 00000000000..c32e9cb1639 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/Diagnostic.java @@ -0,0 +1,35 @@ +package com.intellij.diagnostic; + +import com.intellij.openapi.diagnostic.Logger; + +public class Diagnostic { + public static void trace(String category, String message) { + Logger.getInstance(category).debug(message); + } + + public static boolean isTraceEnabled(String category) { + return Logger.getInstance(category).isDebugEnabled(); + } + + public static void trace(String category, Throwable exception) { + Logger.getInstance(category).error(exception); + } + + public static boolean assertTrue(String category, String message, boolean condition) { + if (condition) return true; + return Logger.getInstance(category).assertTrue(condition, message); + } + + public static boolean isAssertEnabled(String category) { + return true; + } + + public static void methodNotImplemented(String category) { + methodNotImplemented(category, ""); + } + + public static void methodNotImplemented(String category, String message) { + String message1 = "METHOD NOT IMPLEMENTED YET " + message; + Logger.getInstance(category).error(message1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DialogAppender.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DialogAppender.java new file mode 100644 index 00000000000..4b406321018 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DialogAppender.java @@ -0,0 +1,79 @@ +package com.intellij.diagnostic; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.ErrorLogger; +import com.intellij.openapi.diagnostic.IdeaLoggingEvent; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Priority; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ThrowableInformation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Mike + */ +public class DialogAppender extends AppenderSkeleton { + private static final DefaultIdeaErrorLogger DEFAULT_LOGGER = new DefaultIdeaErrorLogger(); + static final boolean RELEASE_BUILD = false; + + private Thread myDialogThread = null; + + protected synchronized void append(final LoggingEvent event) { + List loggers = new ArrayList(); + loggers.add(DEFAULT_LOGGER); + + Application application = ApplicationManager.getApplication(); + if (application != null) { + loggers.addAll(Arrays.asList(application.getComponents(ErrorLogger.class))); + } + + appendToLoggers(event, loggers.toArray(new ErrorLogger[loggers.size()])); + } + + void appendToLoggers(final LoggingEvent event, ErrorLogger[] errorLoggers) { + + if (event.level.isGreaterOrEqual(Priority.WARN)) { + if (myDialogThread != null) { + return; + } + ThrowableInformation throwable = event.getThrowableInformation(); + if (throwable == null) { + return; + } + + final IdeaLoggingEvent ideaEvent = new IdeaLoggingEvent((String)event.getMessage(), throwable.getThrowable()); + for (int i = errorLoggers.length - 1; i >= 0; i--) { + + final ErrorLogger logger = errorLoggers[i]; + if (logger.canHandle(ideaEvent)) { + + myDialogThread = new Thread(new Runnable() { + public void run() { + try { + logger.handle(ideaEvent); + } + finally { + myDialogThread = null; + } + } + }, "DialogAppender"); + myDialogThread.start(); + + break; + } + } + } + } + + public boolean requiresLayout() { + return false; + } + + public void close() { + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DropAnErrorAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DropAnErrorAction.java new file mode 100644 index 00000000000..877988d6504 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/DropAnErrorAction.java @@ -0,0 +1,22 @@ +package com.intellij.diagnostic; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Nov 6, 2003 + * Time: 4:05:51 PM + * To change this template use Options | File Templates. + */ +public class DropAnErrorAction extends AnAction { + public DropAnErrorAction() { + super ("Drop an error"); + } + + public void actionPerformed(AnActionEvent e) { + Logger.getInstance("test").error("Test"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/EAPSendErrorDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/EAPSendErrorDialog.java new file mode 100644 index 00000000000..8509759837b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/EAPSendErrorDialog.java @@ -0,0 +1,165 @@ +package com.intellij.diagnostic; + +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.util.net.HTTPProxySettingsDialog; + +import javax.swing.*; +import javax.swing.text.Keymap; +import javax.swing.event.UndoableEditListener; +import javax.swing.event.UndoableEditEvent; +import javax.swing.undo.UndoManager; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 8, 2003 + * Time: 3:49:50 PM + * To change this template use Options | File Templates. + */ +public class EAPSendErrorDialog extends DialogWrapper { + private JTextField myItnLoginTextField; + private JPasswordField myItnPasswordTextField; + private JCheckBox myRememberITNPasswordCheckBox; + + public void storeInfo () { + ErrorReportConfigurable.getInstance().ITN_LOGIN = myItnLoginTextField.getText(); + ErrorReportConfigurable.getInstance().setPlainItnPassword(new String(myItnPasswordTextField.getPassword())); + ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD = myRememberITNPasswordCheckBox.isSelected(); + } + + public void loadInfo () { + myItnLoginTextField.setText(ErrorReportConfigurable.getInstance().ITN_LOGIN); + myItnPasswordTextField.setText(ErrorReportConfigurable.getInstance().getPlainItnPassword()); + myRememberITNPasswordCheckBox.setSelected(ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD); + } + + public EAPSendErrorDialog() throws HeadlessException { + super(false); + + init (); + } + + protected JPanel myMainPanel; + protected JTextArea myErrorDescriptionTextArea; + private Action mySendAction; + private Action myCancelAction; + protected JLabel mySendingSettingsLabel; + + private boolean myShouldSend = false; + + private UndoManager undoManager = new UndoManager (); + + public boolean isShouldSend() { + return myShouldSend; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.diagnostic.AbstractSendErrorDialog"; + } + + protected void init() { + setTitle(ReportMessages.ERROR_REPORT); + getContentPane().add(myMainPanel); + mySendAction = new AbstractAction("&Send") { + public void actionPerformed(ActionEvent e) { + if (myErrorDescriptionTextArea.getText().trim().length() == 0) { + Messages.showMessageDialog(myMainPanel, + "Please fill in error description", + ReportMessages.ERROR_REPORT, + Messages.getErrorIcon()); + return; + } + myShouldSend = true; + storeInfo(); + dispose(); + } + }; + mySendAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S)); + mySendAction.putValue(Action.DEFAULT, "true"); + myCancelAction = new AbstractAction("&Cancel") { + public void actionPerformed(ActionEvent e) { + myShouldSend = false; + dispose(); + } + }; + myCancelAction.putValue(Action.MNEMONIC_KEY, new Integer (KeyEvent.VK_C)); + + mySendingSettingsLabel.addMouseListener(new MouseAdapter () { + public void mouseClicked(MouseEvent e) { + + HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog (); + settingsDialog.pack(); + settingsDialog.show(); + } + }); + mySendingSettingsLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + + loadInfo(); + + + myErrorDescriptionTextArea.getDocument().addUndoableEditListener(new UndoableEditListener () { + public void undoableEditHappened(UndoableEditEvent e) { + undoManager.addEdit(e.getEdit()); + } + }); + Keymap keymap = myErrorDescriptionTextArea.getKeymap(); + Shortcut [] undoShortcuts = KeymapManagerEx.getInstanceEx().getActiveKeymap().getShortcuts("$Undo"); + Shortcut [] redoShortcuts = KeymapManagerEx.getInstanceEx().getActiveKeymap().getShortcuts("$Redo"); + + Action undoAction = new AbstractAction ("Undo") { + public void actionPerformed(ActionEvent e) { + if (undoManager.canUndo()) + undoManager.undo(); + } + }; + + Action redoAction = new AbstractAction ("Redo") { + public void actionPerformed(ActionEvent e) { + if (undoManager.canRedo()) + undoManager.redo(); + } + }; + + for (int i = 0; i < undoShortcuts.length; i++) { + Shortcut undoShortcut = undoShortcuts[i]; + if (undoShortcut instanceof KeyboardShortcut) + keymap.addActionForKeyStroke(((KeyboardShortcut)undoShortcut).getFirstKeyStroke(), undoAction); + } + for (int i = 0; i < redoShortcuts.length; i++) { + Shortcut redoShortcut = redoShortcuts[i]; + if (redoShortcut instanceof KeyboardShortcut) + keymap.addActionForKeyStroke(((KeyboardShortcut)redoShortcut).getFirstKeyStroke(), redoAction); + } + + myErrorDescriptionTextArea.setKeymap(keymap); + + super.init (); + } + + protected JComponent createCenterPanel() { + return myMainPanel; + } + + protected Action[] createActions() { + return new Action [] {mySendAction, myCancelAction}; + } + + public String getErrorDescription() { + return myErrorDescriptionTextArea.getText(); + } + + public void setErrorDescription (String description) { + myErrorDescriptionTextArea.setText(description); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ErrorReportConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ErrorReportConfigurable.java new file mode 100644 index 00000000000..851e868e9fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ErrorReportConfigurable.java @@ -0,0 +1,110 @@ +package com.intellij.diagnostic; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +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 org.apache.xmlrpc.Base64; +import org.jdom.Element; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 11, 2003 + * Time: 8:59:04 PM + * To change this template use Options | File Templates. + */ +public class ErrorReportConfigurable implements JDOMExternalizable, ApplicationComponent { + private static final String CLOSED = "closed"; + private static final String HASH = "hash"; + private static final String ID = "id"; + private static final String THREAD = "thread"; + + public String ITN_LOGIN = ""; + public String ITN_PASSWORD_CRYPT = ""; + public boolean KEEP_ITN_PASSWORD = false; + + public String EMAIL = ""; + + private Map closedExceptions = new HashMap(); + + public static ErrorReportConfigurable getInstance() { + return ApplicationManager.getApplication().getComponent(ErrorReportConfigurable.class); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + if (! KEEP_ITN_PASSWORD) + ITN_PASSWORD_CRYPT = ""; + + Element closed = element.getChild(CLOSED); + if (closed != null) { + List hashElements = closed.getChildren(HASH); + + if (hashElements != null) + for (int i = 0; i < hashElements.size(); i++) { + Element exceptionId = (Element)hashElements.get(i); + + closedExceptions.put(exceptionId.getAttributeValue(ID), exceptionId.getAttributeValue(THREAD)); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + String itnPassword = ITN_PASSWORD_CRYPT; + if (! KEEP_ITN_PASSWORD) + ITN_PASSWORD_CRYPT = ""; + + Element closedHash = new Element (CLOSED); + Iterator it = closedExceptions.keySet().iterator(); + while (it.hasNext()) { + String id = it.next(); + String thread = closedExceptions.get(id); + + Element hash = new Element (HASH); + hash.setAttribute(ID, id); + hash.setAttribute(THREAD, thread); + + closedHash.addContent(hash); + } + + element.addContent(closedHash); + + DefaultJDOMExternalizer.writeExternal(this, element); + + ITN_PASSWORD_CRYPT = itnPassword; + } + + public boolean isClosed (String hashId) { + return closedExceptions.containsKey(hashId); + } + + public String getClosedThread (String hashId) { + return closedExceptions.get(hashId); + } + + public void addClosed (String hashId, String thread) { + closedExceptions.put(hashId, thread); + } + + public String getComponentName() { + return "ErrorReportConfigurable"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getPlainItnPassword () { + return new String(Base64.decode(ErrorReportConfigurable.getInstance().ITN_PASSWORD_CRYPT.getBytes())); + } + + public void setPlainItnPassword (String password) { + ITN_PASSWORD_CRYPT = new String(Base64.encode(new String(password).getBytes())); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/PluginException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/PluginException.java new file mode 100644 index 00000000000..9b9b36d5924 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/PluginException.java @@ -0,0 +1,33 @@ +package com.intellij.diagnostic; + +import com.intellij.ide.plugins.PluginDescriptor; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Jan 8, 2004 + * Time: 3:06:43 PM + * To change this template use Options | File Templates. + */ +public class PluginException extends RuntimeException { + private PluginDescriptor myDescriptor; + + public PluginException(Throwable e, PluginDescriptor descriptor) { + super (e.getMessage(), e); + myDescriptor = descriptor; + } + + public PluginDescriptor getDescriptor() { + return myDescriptor; + } + + public String getMessage() { + String message = super.getMessage(); + + if (message == null) + message = ""; + + message += " [Plugin: " + myDescriptor.getName() + "]"; + return message; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ReportMessages.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ReportMessages.java new file mode 100644 index 00000000000..16796a55361 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diagnostic/ReportMessages.java @@ -0,0 +1,19 @@ +/* + * @author: Eugene Zhuravlev + * Date: Mar 18, 2003 + * Time: 1:25:33 PM + */ +package com.intellij.diagnostic; + +public class ReportMessages { + + public static final boolean isEAP = true; + public static final String ERROR_REPORT = "Error Report"; + + public static String getReportAddress() { + if (isEAP) { + return "Please submit bug report to http://www.intellij.net/tracker/idea/browse"; + } + return "For assistance, contact support@intellij.com"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/Block.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/Block.java new file mode 100644 index 00000000000..f384c0d90aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/Block.java @@ -0,0 +1,97 @@ +package com.intellij.diff; + +import com.intellij.openapi.util.text.LineTokenizer; + +import java.util.Arrays; +import java.util.List; + +/** + * author: lesya + */ +public class Block { + private final String[] mySource; + private int myStart; + private int myEnd; + + public Block(String source, int start, int end) { + this(LineTokenizer.tokenize(source.toCharArray(), false), + start, end); + } + + public Block(String[] source, int start, int end) { + mySource = source; + myStart = start; + myEnd = end; + + + } + + public String getBlockContent(){ + StringBuffer result = new StringBuffer(); + + int length = myEnd - myStart + 1; + + for (int i = 0; i < length; i++) { + if ((i + myStart)>= mySource.length) break; + result.append(mySource[i + myStart]); + if (i < length - 1) result.append("\n"); + }; + + return result.toString(); + } + + public int hashCode() { + return getSourceAsList().hashCode() ^ myStart ^ myEnd; + } + + private List getSourceAsList() { + return Arrays.asList(mySource); + } + + public boolean equals(Object object) { + if (!(object instanceof Block)) return false; + Block other = (Block)object; + return getSourceAsList().equals(other.getSourceAsList()) + && myStart == other.myStart + && myEnd == other.myEnd; + } + + public int getStart() { return myStart; } + + public int getEnd() { return myEnd; } + + public void setStart(int start) { myStart = start; } + + public void setEnd(int end) { myEnd = end; } + + public String[] getSource() { + return mySource; + } + + public String toString() { + StringBuffer result = new StringBuffer(); + + appendLines(result, 0, myStart); + + appendLineTo(result, "<-----------------------------"); + + appendLines(result, myStart, myEnd + 1); + + appendLineTo(result, "----------------------------->"); + + appendLines(result, myEnd + 1, mySource.length); + + return result.toString(); + } + + private void appendLines(StringBuffer result, int from, int to) { + for (int i = from; i < to; i++){ + appendLineTo(result, mySource[i]); + } + } + + private void appendLineTo(StringBuffer result, String line) { + result.append(line); + result.append("\n"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/FindBlock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/FindBlock.java new file mode 100644 index 00000000000..3fabc26028b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/diff/FindBlock.java @@ -0,0 +1,51 @@ +package com.intellij.diff; + +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.util.diff.Diff; + +/** + * author: lesya + */ +public class FindBlock { + + private final Block myCurrentVersion; + private final Block myResult; + + public FindBlock(String[] prevVersion, Block currentVersion) { + myResult = new Block(prevVersion, currentVersion.getStart(), currentVersion.getEnd()); + myCurrentVersion = currentVersion; + } + + public FindBlock(String prevVersion, Block currentVersion) { + this(LineTokenizer.tokenize(prevVersion.toCharArray(), false), currentVersion); + } + + + public Block getBlockInThePrevVersion() { + + Diff.Change change = Diff.buildChanges(myResult.getSource(), myCurrentVersion.getSource()); + while (change != null) { + shiftIndices(change.line1, change.line1, change.line0); + shiftIndices(change.line1, change.line1 + change.inserted, change.line0 + change.deleted); + change = change.link; + } + + if (myResult.getEnd() >= myResult.getSource().length){ + myResult.setEnd(myResult.getSource().length - 1); + } + + return myResult; + } + + private void shiftIndices(int firstChangeIndex,int line1, int line0) { + int shift = line1 - line0; + + if (line1 <= myCurrentVersion.getStart()) { + myResult.setStart(myCurrentVersion.getStart() - shift); + } + + if (firstChangeIndex <= myCurrentVersion.getEnd()) { + myResult.setEnd(myCurrentVersion.getEnd() - shift); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/dupLocator/util/PsiAnchor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/dupLocator/util/PsiAnchor.java new file mode 100644 index 00000000000..56082758c01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/dupLocator/util/PsiAnchor.java @@ -0,0 +1,102 @@ +package com.intellij.dupLocator.util; + +import com.intellij.psi.*; +import com.intellij.openapi.util.TextRange; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Mar 26, 2004 + * Time: 7:03:41 PM + * To change this template use File | Settings | File Templates. + */ +public class PsiAnchor { + private Class myClass; + private int myStartOffset; + private int myEndOffset; + private PsiFile myFile; + private PsiElement myElement; + + public PsiAnchor(PsiElement element) { + if (element instanceof PsiCompiledElement || element instanceof PsiMember) { + myElement = element; + } + else { + myElement = null; + myFile = element.getContainingFile(); + myClass = element.getClass(); + + TextRange textRange = element.getTextRange(); + + if (textRange != null) { + myStartOffset = textRange.getStartOffset(); + myEndOffset = textRange.getEndOffset(); + } + } + } + + public PsiElement retrieve() { + if (myElement != null) return myElement; + + PsiElement element = myFile.findElementAt(myStartOffset); + + while (!element.getClass().equals(myClass) || + (element.getTextRange().getStartOffset() != myStartOffset) || + (element.getTextRange().getEndOffset() != myEndOffset)) { + element = element.getParent(); + } + + return element; + } + + public PsiFile getFile() { + return myElement != null ? myElement.getContainingFile() : myFile; + } + + public int getStartOffset() { + return myElement != null ? myElement.getTextRange().getStartOffset() : myStartOffset; + } + + public int getEndOffset() { + return myElement != null ? myElement.getTextRange().getEndOffset() : myEndOffset; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PsiAnchor)) return false; + + final PsiAnchor psiAnchor = (PsiAnchor)o; + + if (psiAnchor.myElement != null && myElement != null) { + return psiAnchor.myElement.equals(myElement); + } + + if (psiAnchor.myElement == null && myElement == null) { + if (myEndOffset != psiAnchor.myEndOffset) return false; + if (myStartOffset != psiAnchor.myStartOffset) return false; + if (myClass != null ? !myClass.equals(psiAnchor.myClass) : psiAnchor.myClass != null) return false; + if (myFile != null ? !myFile.equals(psiAnchor.myFile) : psiAnchor.myFile != null) return false; + + return true; + } + else { + return false; + } + } + + public int hashCode() { + int result; + + if (myElement != null){ + return myElement.hashCode(); + } + + result = (myClass != null ? myClass.hashCode() : 0); + result = 29 * result + myStartOffset; + result = 29 * result + myEndOffset; + result = 29 * result + (myFile != null ? myFile.hashCode() : 0); + + return result; + } +} + \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/ErrorReportSender.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/ErrorReportSender.java new file mode 100644 index 00000000000..bdde0d1bf14 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/ErrorReportSender.java @@ -0,0 +1,363 @@ +package com.intellij.errorreport; + +import com.intellij.diagnostic.ErrorReportConfigurable; +import com.intellij.errorreport.bean.BeanWrapper; +import com.intellij.errorreport.bean.ErrorBean; +import com.intellij.errorreport.bean.ExceptionBean; +import com.intellij.errorreport.bean.NotifierBean; +import com.intellij.errorreport.error.*; +import com.intellij.errorreport.itn.ITNProxy; +import com.intellij.idea.IdeaLogger; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.util.net.HttpConfigurable; +import org.apache.xmlrpc.XmlRpcClient; +import org.apache.xmlrpc.XmlRpcException; + +import java.io.IOException; +import java.util.Date; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: May 22, 2003 + * Time: 8:57:19 PM + * To change this template use Options | File Templates. + */ +public class ErrorReportSender { + public static final String PREPARE_URL = "http://www.intellij.net/websupport/error/"; + public static String REPORT_URL = "http://www.intellij.net/websupport/error/report?sender=i"; + //public static String REPORT_URL = "http://unit-038:8080/error/report?sender=i"; + + public static final String PRODUCT_CODE = "idea"; + + public static ErrorReportSender getInstance () { + return new ErrorReportSender(); + } + + protected ErrorReportSender () { + } + + protected static String authorizeEmail (String email) throws IOException, XmlRpcException { + XmlRpcClient client = new XmlRpcClient(REPORT_URL); + Vector params = new Vector (); + params.add("EMAIL"); + params.add(email); + + String notifierId = (String) client.execute(RemoteMethods.ERROR_AUTHORIZE, params); + return notifierId; + } + + protected static String authorizeEAP (String eapLogin) throws IOException, XmlRpcException { + XmlRpcClient client = new XmlRpcClient(REPORT_URL); + Vector params = new Vector (); + params.add("eap"); + params.add(eapLogin); + + String notifierId = (String) client.execute(RemoteMethods.ERROR_AUTHORIZE, params); + return notifierId; + } + + protected static ExceptionBean checkException (Throwable e) throws IOException, XmlRpcException, NoSuchExceptionException { + if (e instanceof StackOverflowError) { + throw new NoSuchExceptionException(e.getMessage()); + } + + XmlRpcClient client = new XmlRpcClient(REPORT_URL); + Vector params = new Vector (); + ExceptionBean exceptionBean = new ExceptionBean(e); + params.add(exceptionBean.getHashCode()); + + try { + Hashtable hashtable = (Hashtable) client.execute(RemoteMethods.ERROR_CHECK_EXCEPTION, params); + return BeanWrapper.getException(hashtable); + } catch (XmlRpcException ex) { + if (NoSuchExceptionException.isException(ex)) + throw new NoSuchExceptionException(ex.getMessage()); + else + throw ex; + } + } + + protected static void postError (ErrorBean error, ExceptionBean exceptionBean) + throws IOException, XmlRpcException { + XmlRpcClient client = new XmlRpcClient(REPORT_URL); + Vector params = new Vector (); + params.add(BeanWrapper.getHashtable(error)); + params.add(BeanWrapper.getHashtable(exceptionBean)); + + client.execute(RemoteMethods.ERROR_POST_ERROR, params); + } + + class SendTask { + private NotifierBean notifierBean; + private ErrorBean errorBean; + private Throwable throwable; + private ExceptionBean exceptionBean; + private boolean newThread = false; + private int buildNumber = -1; + + private ITask [] prepareTasks = null; + private ITask [] doTasks = null; + + public SendTask(Throwable throwable) { + this.throwable = throwable; + } + + public SendTask(ErrorBean errorBean, Throwable throwable, NotifierBean notifierBean) { + this.errorBean = errorBean; + this.throwable = throwable; + this.notifierBean = notifierBean; + } + + public int getThreadId () { + return exceptionBean.getItnThreadId(); + } + + public ITask [] getPrepareSteps () { + if (prepareTasks == null) + prepareTasks = new ITask [] { + new ITask () { + private boolean cheked = false; + + public boolean isSuccessful() { + return cheked; + } + + public String getDescription() { + return "Check for a new EAP build... "; + } + + public void run() { + try { + int itnBuildNumber = ITNProxy.getBuildNumber(); + ApplicationInfoEx appInfo = + (ApplicationInfoEx) ApplicationManager.getApplication().getComponent( + ApplicationInfo.class); + String strNumber = appInfo.getBuildNumber(); + buildNumber = -1; + try { + buildNumber = Integer.valueOf(strNumber).intValue(); + } catch (NumberFormatException e) { + + } + + if (itnBuildNumber > 0 && + buildNumber > 0 && + itnBuildNumber > buildNumber) { + throw new NewBuildException (Integer.toString(itnBuildNumber)); + } + + cheked = true; + } + catch (IOException e) { + throw new SendException(e); + } + catch (NewBuildException e) { + throw new SendException(e); + } + } + }, + new ITask () { + private boolean checked = false; + + public String getDescription() { + return "Checking exception... "; + } + + public boolean isSuccessful() { + return checked; + } + + public void run() { + try { + exceptionBean = ErrorReportSender.checkException(throwable); + newThread = false; + checked = true; + } catch (NoSuchExceptionException e) { + exceptionBean = new ExceptionBean(throwable); + newThread = true; + checked = true; + } catch (Exception e) { + throw new SendException(e); + } + } + }, + + new ITask () { + private boolean checked = false; + + public String getDescription() { + return "Checking thread status..."; + } + + public boolean isSuccessful() { + return checked; + } + + public void run() { + if (! newThread) { + try { + String threadStatus = ITNProxy.getThreadStatus(exceptionBean.getItnThreadId()); + checked = true; + + if (! threadStatus.equals("Open") && + ! threadStatus.equals("Submitted") && + ! threadStatus.equals("More info needed")) { + ErrorReportConfigurable.getInstance().addClosed(exceptionBean.getHashCode(), + Integer.toString(exceptionBean.getItnThreadId())); + throw new ThreadClosedException (threadStatus, exceptionBean.getItnThreadId()); + } + } + catch (IOException e) { + throw new SendException(e); + } + catch (ThreadClosedException e) { + throw new SendException(e); + } + } + } + }, + }; + return prepareTasks; + } + + public ITask [] getDoSteps () { + if (doTasks == null) + doTasks = new ITask [] { + new ITask () { + private boolean authorized = false; + + public String getDescription() { + return "Authorizing... "; + } + + public boolean isSuccessful() { + return authorized; + } + + public void run() { + try { + errorBean.setExceptionHashCode(exceptionBean.getHashCode()); + + String notifierId = null; + + if (notifierBean.getEmail() != null && notifierBean.getEmail().length() > 0) { + notifierId = ErrorReportSender.authorizeEmail(notifierBean.getEmail()); + + authorized = true; + } else if (notifierBean.getItnLogin() != null && + notifierBean.getItnLogin().length() > 0) { + if (newThread) { + int threadId = ITNProxy.postNewThread( + notifierBean.getItnLogin(), + notifierBean.getItnPassword(), + errorBean, exceptionBean, + IdeaLogger.getOurCompilationTimestamp()); + exceptionBean.setItnThreadId(threadId); + } else { + ITNProxy.postNewComment(notifierBean.getItnLogin(), + notifierBean.getItnPassword(), + exceptionBean.getItnThreadId(), + errorBean.getDescription()); + } + notifierId = ErrorReportSender.authorizeEAP(notifierBean.getItnLogin()); + + authorized = true; + } + errorBean.setNotifierId(notifierId); + } catch (Exception e) { + throw new SendException(e); + } + } + }, + new ITask () { + private boolean sent = false; + + public boolean isSuccessful() { + return sent; + } + + public String getDescription() { + return "Sending... "; + } + + public void run() { + exceptionBean.setBuildNumber(Integer.toString(buildNumber)); + exceptionBean.setProductCode(PRODUCT_CODE); + exceptionBean.setScrambled(buildNumber > 0); + exceptionBean.setDate(new Date ()); + + try { + ErrorReportSender.postError(errorBean, exceptionBean); + sent = true; + } catch (Exception e) { + throw new SendException(e); + } + } + } + }; + return doTasks; + } + + public void setErrorBean(ErrorBean error) { + errorBean = error; + } + + public void setNotifierBean(NotifierBean notifierBean) { + this.notifierBean = notifierBean; + } + } + + private SendTask sendTask; + + public void prepareError (Throwable exception) + throws IOException, XmlRpcException, NewBuildException, ThreadClosedException { + HttpConfigurable.getInstance().prepareURL(PREPARE_URL); + + sendTask = new SendTask (exception); + TaskRunner prepareRunner = new TaskRunner(sendTask.getPrepareSteps()); + + try { + prepareRunner.doTasks(); + } catch (IOException e) { + throw e; + } catch (XmlRpcException e) { + throw e; + } catch (NewBuildException e) { + throw e; + } catch (ThreadClosedException e) { + throw e; + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public int sendError (NotifierBean notifierBean, ErrorBean error) + throws XmlRpcException, IOException, NoSuchEAPUserException, InternalEAPException { + + sendTask.setErrorBean (error); + sendTask.setNotifierBean (notifierBean); + TaskRunner taskRunner = new TaskRunner(sendTask.getDoSteps()); + + try { + taskRunner.doTasks(); + return sendTask.getThreadId(); + } catch (IOException e) { + throw e; + } catch (XmlRpcException e) { + throw e; + } catch (NoSuchEAPUserException e) { + throw e; + } catch (InternalEAPException e) { + throw e; + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ErrorBean.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ErrorBean.java new file mode 100644 index 00000000000..8c24c4d8acb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ErrorBean.java @@ -0,0 +1,72 @@ +package com.intellij.errorreport.bean; + +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: May 5, 2003 + * Time: 9:34:26 PM + * To change this template use Options | File Templates. + */ +public class ErrorBean { + private String notifierId; + private String exceptionHashCode; + private Date date; + private String os; + private String lastAction; + private String description; + + public void autoInit () { + os = System.getProperty("os.name"); + date = new Date(); + } + + public String getNotifierId() { + return notifierId; + } + + public void setNotifierId(String notifierId) { + this.notifierId = notifierId; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getOs() { + return os; + } + + public void setOs(String os) { + this.os = os; + } + + public String getLastAction() { + return lastAction; + } + + public void setLastAction(String lastAction) { + this.lastAction = lastAction; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getExceptionHashCode() { + return exceptionHashCode; + } + + public void setExceptionHashCode(String exceptionId) { + exceptionHashCode = exceptionId; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ExceptionBean.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ExceptionBean.java new file mode 100644 index 00000000000..6dde53a3609 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/ExceptionBean.java @@ -0,0 +1,128 @@ +package com.intellij.errorreport.bean; + +import com.intellij.errorreport.Util; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.NoSuchAlgorithmException; +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: May 19, 2003 + * Time: 9:07:26 PM + * To change this template use Options | File Templates. + */ +public class ExceptionBean { + private String hashCode; + private String message; + private Date date; + private String stackTrace; + private int itnThreadId; + private String buildNumber; + private String productCode; + private boolean scrambled; + + public static final int NO_EAP_THREAD = -1; + + private String exceptionClass = ""; + + public String getExceptionClass() { return exceptionClass; } + + protected ExceptionBean (ExceptionBean e) { + hashCode = e.hashCode; + message = e.message; + date = e.date; + stackTrace = e.stackTrace; + itnThreadId = e.itnThreadId; + buildNumber = e.buildNumber; + productCode = e.productCode; + scrambled = e.scrambled; + } + + public ExceptionBean() { + } + + public ExceptionBean (Throwable throwable) { + if (throwable != null) { + exceptionClass = throwable.getClass().getName(); + + message = throwable.getMessage(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + throwable.printStackTrace(new PrintStream (baos, true)); + stackTrace = baos.toString(); + + try { + hashCode = Util.md5(stackTrace, "stack-trace"); + } catch (NoSuchAlgorithmException e) { + hashCode = null; + } + } + } + + public String getStackTrace() { + return stackTrace; + } + + public void setStackTrace(String stackTrace) { + this.stackTrace = stackTrace; + } + + public String getHashCode() { + return hashCode; + } + + public void setHashCode(String hashCode) { + this.hashCode = hashCode; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getBuildNumber() { + return buildNumber; + } + + public void setBuildNumber(String buildNumber) { + this.buildNumber = buildNumber; + } + + public String getProductCode() { + return productCode; + } + + public void setProductCode(String productCode) { + this.productCode = productCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getItnThreadId() { + return itnThreadId; + } + + public void setItnThreadId(int itnThreadId) { + this.itnThreadId = itnThreadId; + } + + public boolean isScrambled() { + return scrambled; + } + + public void setScrambled(boolean scrambled) { + this.scrambled = scrambled; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/NotifierBean.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/NotifierBean.java new file mode 100644 index 00000000000..fb84db64e8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/bean/NotifierBean.java @@ -0,0 +1,47 @@ +package com.intellij.errorreport.bean; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: May 5, 2003 + * Time: 9:36:45 PM + * To change this template use Options | File Templates. + */ +public class NotifierBean { + private String id; + private String email; + private String itnLogin; + private String itnPassword; + + public String getItnPassword() { + return itnPassword; + } + + public void setItnPassword(String eapPassword) { + itnPassword = eapPassword; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getItnLogin() { + return itnLogin; + } + + public void setItnLogin(String itnLogin) { + this.itnLogin = itnLogin; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/InternalEAPException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/InternalEAPException.java new file mode 100644 index 00000000000..439d3d5d2f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/InternalEAPException.java @@ -0,0 +1,14 @@ +package com.intellij.errorreport.error; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 5, 2003 + * Time: 3:13:15 PM + * To change this template use Options | File Templates. + */ +public class InternalEAPException extends Exception { + public InternalEAPException(String message) { + super(message); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NewBuildException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NewBuildException.java new file mode 100644 index 00000000000..edb225a3f61 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NewBuildException.java @@ -0,0 +1,14 @@ +package com.intellij.errorreport.error; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Sep 19, 2003 + * Time: 7:49:19 PM + * To change this template use Options | File Templates. + */ +public class NewBuildException extends Exception { + public NewBuildException(String s) { + super(s); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchEAPUserException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchEAPUserException.java new file mode 100644 index 00000000000..fbf69468d5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchEAPUserException.java @@ -0,0 +1,14 @@ +package com.intellij.errorreport.error; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 5, 2003 + * Time: 2:56:46 PM + * To change this template use Options | File Templates. + */ +public class NoSuchEAPUserException extends Exception { + public NoSuchEAPUserException(String message) { + super(message); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchExceptionException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchExceptionException.java new file mode 100644 index 00000000000..4be6e11e6f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/NoSuchExceptionException.java @@ -0,0 +1,26 @@ +package com.intellij.errorreport.error; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: May 19, 2003 + * Time: 10:46:39 PM + * To change this template use Options | File Templates. + */ +public class NoSuchExceptionException extends Exception { + private static final String NAME = "#com.intellij.errorreport.error.NoSuchExceptionException"; + + public static boolean isException (Throwable e) { + String str1 = e.getMessage(); + if (str1 == null) + str1 = ""; + + String str2 = NAME.substring(1); + + return str1.indexOf(str2) != -1; + } + + public NoSuchExceptionException(String message) { + super(message); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/SendException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/SendException.java new file mode 100644 index 00000000000..00f9aead3f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/error/SendException.java @@ -0,0 +1,14 @@ +package com.intellij.errorreport.error; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 20, 2003 + * Time: 3:15:02 PM + * To change this template use Options | File Templates. + */ +public class SendException extends RuntimeException { + public SendException(Throwable cause) { + super(cause); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/itn/ITNProxy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/itn/ITNProxy.java new file mode 100644 index 00000000000..ad5e966dfb2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/errorreport/itn/ITNProxy.java @@ -0,0 +1,294 @@ +package com.intellij.errorreport.itn; + +import com.intellij.errorreport.bean.ErrorBean; +import com.intellij.errorreport.bean.ExceptionBean; +import com.intellij.errorreport.error.InternalEAPException; +import com.intellij.errorreport.error.NoSuchEAPUserException; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ApplicationInfo; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 4, 2003 + * Time: 8:12:00 PM + * To change this template use Options | File Templates. + */ +public class ITNProxy { + public static final String ENCODE = "UTF8"; + public static final String POST_DELIMETER = "&"; + + public static final String NEW_THREAD_URL = "http://www.intellij.net/trackerRpc/idea/createScr"; + public static final String NEW_COMMENT_URL = "http://www.intellij.net/trackerRpc/idea/createComment"; + public static final String CHECK_THREAD_URL = "http://www.intellij.net/xml/scrToXml.jsp?projectName=idea&publicId="; + public static final String BUILD_NUMBER_URL = "http://www.intellij.net/eap/products/idea/data/build_number.txt"; + + public static final String THREAD_SUBJECT = "[{0}]"; + + + public static int getBuildNumber () throws IOException { + HttpURLConnection connection = (HttpURLConnection)new URL (BUILD_NUMBER_URL).openConnection(); + + connection.setAllowUserInteraction(true); + connection.connect(); + int responseCode = connection.getResponseCode(); + int buildNumber = -1; + + if (responseCode == HttpURLConnection.HTTP_OK) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = connection.getInputStream(); + + int c; + while ((c = is.read()) != -1) { + baos.write (c); + } + + try { + buildNumber = Integer.valueOf(baos.toString().trim()).intValue(); + } catch (NumberFormatException ex) { + // Tibor!!!! :-E + } + } + + connection.disconnect(); + + switch (responseCode) { + case HttpURLConnection.HTTP_OK: + break; + default: + // some problems + throw new IOException("Connection testing failed with HTTP code " + responseCode); + } + + return buildNumber; + } + + public static String getThreadStatus (int threadId) throws IOException { + HttpURLConnection connection = (HttpURLConnection)new URL (CHECK_THREAD_URL + threadId).openConnection(); + + connection.setAllowUserInteraction(true); + connection.connect(); + int responseCode = connection.getResponseCode(); + String threadStatus = ""; + + if (responseCode == HttpURLConnection.HTTP_OK) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = connection.getInputStream(); + + int c; + while ((c = is.read()) != -1) { + baos.write (c); + } + + String result = baos.toString(); + int startIndex = result.indexOf("state=\"") + 7; + int endIndex = result.indexOf("\"", startIndex); + threadStatus = result.substring(startIndex, endIndex); + } + + connection.disconnect(); + + switch (responseCode) { + case HttpURLConnection.HTTP_OK: + break; + default: + // some problems + throw new IOException("Connection testing failed with HTTP code " + responseCode); + } + + return threadStatus; + } + + + private static HttpURLConnection post (String url, Map params) throws IOException, MalformedURLException { + HttpURLConnection connection = (HttpURLConnection) new URL (url).openConnection(); + connection.setRequestMethod("POST"); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + StringBuffer buffer = new StringBuffer(); + Iterator it = params.keySet().iterator(); + while (it.hasNext()) { + String name = (String) it.next(); + if (params.containsKey(name) && params.get(name) != null) + buffer.append(name + "=" + URLEncoder.encode((String) params.get(name), ENCODE) + POST_DELIMETER); + else + throw new IllegalArgumentException(name); + } + connection.setRequestProperty("Content-Length", Integer.toString(buffer.length())); + connection.getOutputStream().write(buffer.toString().getBytes()); + return connection; + } + + public static final String SUN = "Sun"; + public static final String JDK_1_2_2 = "1.2.2"; + public static final String JDK_1_3_0 = "1.3.0"; + public static final String JDK_1_3_1 = "1.3.1"; + public static final String JDK_1_3_1_01 = "1.3.1_01"; + public static final String JDK_1_4_0 = "1.4.0"; + public static final String JDK_1_4_0_01 = "1.4.0_01"; + public static final String JDK_1_4_0_02 = "1.4.0_02"; + public static final String JDK_1_4_1 = "1.4.1"; + public static final String JDK_1_4_2 = "1.4.2"; + + public static final String WINDOWS_XP = "Windows XP"; + public static final String WINDOWS_2000 = "Windows 2000"; + public static final String WINDOWS_NT = "Windows NT"; + public static final String WINDOWS_95 = "Windows 95"; + public static final String WINDOWS_98 = "Windows 98"; + public static final String WINDOWS_ME = "Windows Me"; + public static final String SOLARIS = "Solaris"; + public static final String MAC_OS_X = "Mac Os X"; + public static final String LINUX = "Linux"; + + public static int postNewThread (String userName, String password, ErrorBean error, ExceptionBean e, + String compilationTimestamp) + throws IOException, NoSuchEAPUserException, InternalEAPException { + Map params = new HashMap (); + params.put("username", userName); + params.put("pwd", password); + params.put("_title", MessageFormat.format(THREAD_SUBJECT, + new Object [] {error.getLastAction() == null ? e.getExceptionClass() : + error.getLastAction() + ", " + e.getExceptionClass()})); + ApplicationInfoEx appInfo = + (ApplicationInfoEx) ApplicationManager.getApplication().getComponent( + ApplicationInfo.class); + + String buildNumber = appInfo.getBuildNumber(); + try { + buildNumber = Integer.valueOf(buildNumber).toString(); + } catch(NumberFormatException ex) { + buildNumber = ""; + } + + params.put("_build", buildNumber); + params.put("_description", + (compilationTimestamp != null ? ("Build time: " + compilationTimestamp + "\n") : "") + + error.getDescription() + "\n\n" + e.getStackTrace()); + params.put("addWatch", "true"); + + String jdkVersion = System.getProperty("java.version"); + String jdkVendor = System.getProperty("java.vm.vendor"); + + if (jdkVendor.indexOf(SUN) != -1) { + if (jdkVersion.equals(JDK_1_4_2)) + jdkVersion = "10"; + else if (jdkVersion.equals(JDK_1_4_1)) + jdkVersion = "7"; + else if (jdkVersion.equals(JDK_1_4_0_02)) + jdkVersion = "9"; + else if (jdkVersion.equals(JDK_1_4_0_01)) + jdkVersion = "8"; + else if (jdkVersion.equals(JDK_1_4_0)) + jdkVersion = "6"; + else if (jdkVersion.equals(JDK_1_3_1_01)) + jdkVersion = "5"; + else if (jdkVersion.equals(JDK_1_3_1)) + jdkVersion = "4"; + else if (jdkVersion.equals(JDK_1_3_0)) + jdkVersion = "3"; + else if (jdkVersion.equals(JDK_1_2_2)) + jdkVersion = "2"; + else + jdkVersion = "1"; + } else + jdkVersion = "1"; + + params.put("_jdk", jdkVersion); + + String os = error.getOs(); + if (os == null) + os = ""; + + if (os.indexOf(WINDOWS_XP) != -1) + os = "4"; + else if (os.indexOf(WINDOWS_2000) != -1 || os.indexOf(WINDOWS_NT) != -1) + os = "3"; + else if (os.indexOf(WINDOWS_95) != -1 || os.indexOf(WINDOWS_98) != -1 || os.indexOf(WINDOWS_ME) != -1) + os = "2"; + else if (os.indexOf(SOLARIS) != -1) + os = "7"; + else if (os.indexOf(MAC_OS_X) != -1) + os = "6"; + else if (os.indexOf(LINUX) != -1) + os = "5"; + else + os = "1"; + params.put("_os", os); + + params.put("_visibility", "2"); // public + params.put("command", "createSCR"); + params.put("_type", "1"); // bug + + HttpURLConnection connection = post(NEW_THREAD_URL, params); + int responce = connection.getResponseCode(); + switch (responce) { + case HttpURLConnection.HTTP_OK: + break; + case HttpURLConnection.HTTP_BAD_REQUEST: + case HttpURLConnection.HTTP_NOT_FOUND: + // user not found + throw new NoSuchEAPUserException(userName); + default: + // some problems + throw new InternalEAPException("HTTP Result code: " + responce); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = connection.getInputStream(); + + int c; + while ((c = is.read()) != -1) { + baos.write (c); + } + int threadId; + + try { + threadId = Integer.valueOf(baos.toString().trim()).intValue(); + } catch (NumberFormatException ex) { + // Tibor!!!! :-E + throw new InternalEAPException("ITN returns wrong data"); + } + + return threadId; + } + + public static void postNewComment (String userName, String password, + int threadId, String comment) + throws IOException, InternalEAPException, NoSuchEAPUserException { + Map params = new HashMap (); + params.put("username", userName); + params.put("pwd", password); + params.put("publicId", Integer.toString(threadId)); + params.put("body", comment); + params.put("command", "Submit"); + + HttpURLConnection connection = post(NEW_COMMENT_URL, params); + int responce = connection.getResponseCode(); + switch (responce) { + case HttpURLConnection.HTTP_OK: + break; + case HttpURLConnection.HTTP_BAD_REQUEST: + case HttpURLConnection.HTTP_NOT_FOUND: + // user not found + throw new NoSuchEAPUserException(userName); + default: + // some problems + throw new InternalEAPException("HTTP result code: " + responce); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ConfigurationTypeEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ConfigurationTypeEx.java new file mode 100644 index 00000000000..33c6f4b21e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ConfigurationTypeEx.java @@ -0,0 +1,16 @@ +package com.intellij.execution; + +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +/** + * @author Eugene Zhuravlev + * Date: Apr 19, 2004 + */ +public interface ConfigurationTypeEx extends ConfigurationType{ + RunnerAndConfigurationSettings createConfigurationByLocation(Location location); + boolean isConfigurationByElement(RunConfiguration configuration, Project project, PsiElement element); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExecutionUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExecutionUtil.java new file mode 100644 index 00000000000..a950ff8ca9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExecutionUtil.java @@ -0,0 +1,189 @@ +package com.intellij.execution; + +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.LayeredIcon; +import com.intellij.util.containers.ConvertingIterator; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.HashSet; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + + +public class ExecutionUtil { + private static final Icon INVALID_CONFIGURATOIN = IconLoader.getIcon("/runConfigurations/invalidConfigurationLayer.png"); + + public static final Convertor FILE_OF_CLASS = + new Convertor() { + public VirtualFile convert(final PsiClass psiClass) { + return psiClass.getContainingFile().getVirtualFile(); + } + }; + + public static String getRuntimeQualifiedName(final PsiClass aClass) { + final PsiClass containingClass = aClass.getContainingClass(); + if (containingClass != null) { + final String parentName = getRuntimeQualifiedName(containingClass); + return parentName + "$" + aClass.getName(); + } + else { + return aClass.getQualifiedName(); + } + } + + public static String getPresentableClassName(final String rtClassName, final RunConfigurationModule configurationModule) { + final PsiClass psiClass = configurationModule.findClass(rtClassName); + if (psiClass != null) { + return psiClass.getName(); + } + final int lastDot = rtClassName.lastIndexOf('.'); + if (lastDot == -1 || lastDot == rtClassName.length() - 1) { + return rtClassName; + } + return rtClassName.substring(lastDot + 1, rtClassName.length()); + } + + public static Module findModule(final PsiClass psiClass) { + final Convertor convertor = ConvertingIterator.composition(FILE_OF_CLASS, fileToModule(psiClass.getProject())); + return convertor.convert(psiClass); + } + + public static Convertor fileToModule(final Project project) { + return new Convertor() { + public Module convert(final VirtualFile file) { + return ModuleUtil.getModuleForFile(project, file); + } + }; + } + + public static Collection collectModulesDependsOn(final Collection modules) { + if (modules.size() == 0) return new ArrayList(0); + final HashSet result = new HashSet(); + final Project project = modules.iterator().next().getProject(); + final ModuleManager moduleManager = ModuleManager.getInstance(project); + for (Iterator iterator = modules.iterator(); iterator.hasNext();) { + final Module module = iterator.next(); + result.add(module); + result.addAll(Arrays.asList(moduleManager.getModuleDependentModules(module))); + } + return result; + } + + public static PsiClass findMainClass(final Module module, final String mainClassName) { + final PsiManager psiManager = PsiManager.getInstance(module.getProject()); + return psiManager. + findClass(mainClassName.replace('$', '.'), + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)); + } + + public static boolean isNewName(final String name) { + return name == null || name.startsWith("Unnamed"); + } + + public static Location stepIntoSingleClass(final Location location) { + PsiElement element = location.getPsiElement(); + if (PsiTreeUtil.getParentOfType(element, PsiClass.class) != null) return location; + element = PsiTreeUtil.getParentOfType(element, PsiJavaFile.class); + if (element == null) return location; + final PsiJavaFile psiFile = ((PsiJavaFile)element); + final PsiClass[] classes = psiFile.getClasses(); + if (classes.length != 1) return location; + return PsiLocation.fromPsiElement(classes[0]); + } + + public static String shortenName(final String name, final int toBeAdded) { + if (name == null) return ""; + final int symbols = Math.max(10, 20 - toBeAdded); + if (name.length() < symbols) return name; + else return name.substring(0, symbols) + "..."; + } + + public static String getShortClassName(final String fqName) { + if (fqName == null) return ""; + final int dotIndex = fqName.lastIndexOf('.'); + if (dotIndex == fqName.length() - 1) return ""; + if (dotIndex < 0) return fqName; + return fqName.substring(dotIndex + 1, fqName.length()); + } + + public static void showExecutionErrorMessage(final Throwable e, final String title, final Project project) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + throw new RuntimeException(e.getLocalizedMessage()); + } + final String message = e.getMessage(); + if (message.length() < 100) { + Messages.showErrorDialog(project, message, title); + return; + } + final DialogBuilder builder = new DialogBuilder(project); + builder.setTitle(title); + final JTextArea textArea = new JTextArea(); + textArea.setEditable(false); + textArea.setForeground(UIManager.getColor("Label.foreground")); + textArea.setBackground(UIManager.getColor("Label.background")); + textArea.setFont(UIManager.getFont("Label.font")); + textArea.setText(message); + textArea.setWrapStyleWord(false); + textArea.setLineWrap(true); + final JScrollPane scrollPane = new JScrollPane(textArea); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + final JPanel panel = new JPanel(new BorderLayout(10, 0)); + panel.setPreferredSize(new Dimension(500, 200)); + panel.add(scrollPane, BorderLayout.CENTER); + panel.add(new JLabel(Messages.getErrorIcon()), BorderLayout.WEST); + builder.setCenterPanel(panel); + builder.setButtonsAlignment(SwingConstants.CENTER); + builder.addOkAction(); + builder.show(); + } + + public static Icon getConfigurationIcon(final Project project, final RunConfiguration configuration, final boolean invalid) { + final RunManager runManager = RunManager.getInstance(project); + final Icon icon = configuration.getFactory().getIcon(); + final Icon configurationIcon = runManager.isTemporary(configuration) ? IconLoader.getTransparentIcon(icon, 0.3f) : icon; + if (invalid) { + final LayeredIcon layeredIcon = new LayeredIcon(2); + layeredIcon.setIcon(configurationIcon, 0); + layeredIcon.setIcon(INVALID_CONFIGURATOIN, 1); + return layeredIcon; + } + return configurationIcon; + } + + public static Icon getConfigurationIcon(final Project project, final RunConfiguration configuration) { + try { + configuration.checkConfiguration(); + return getConfigurationIcon(project, configuration, false); + } + catch (RuntimeConfigurationException ex) { + return getConfigurationIcon(project, configuration, true); + } + } + + public static boolean isRunnableClass(final PsiClass aClass) { + if (aClass instanceof PsiAnonymousClass) return false; + if (aClass.isInterface()) return false; + if (!aClass.hasModifierProperty(PsiModifier.PUBLIC)) return false; + if (aClass.hasModifierProperty(PsiModifier.ABSTRACT)) return false; + if (aClass.getContainingClass() != null && !aClass.hasModifierProperty(PsiModifier.STATIC)) return false; + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExternalizablePath.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExternalizablePath.java new file mode 100644 index 00000000000..614398c0fa5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ExternalizablePath.java @@ -0,0 +1,48 @@ +package com.intellij.execution; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Element; + +import java.io.File; + +/** + * @author dyoma + */ +public class ExternalizablePath implements JDOMExternalizable { + private static final String VALUE_ATTRIBUTE = "value"; + + private String myUrl; + + public void readExternal(final Element element) throws InvalidDataException { + final String value = element.getAttributeValue(VALUE_ATTRIBUTE); + myUrl = value != null ? value : ""; + final String protocol = VirtualFileManager.extractProtocol(myUrl); + if (protocol == null) myUrl = urlValue(myUrl); + } + + public void writeExternal(final Element element) throws WriteExternalException { + element.setAttribute(VALUE_ATTRIBUTE, myUrl); + } + + public String getLocalPath() { + return localPathValue(myUrl); + } + + public static String urlValue(String localPath) { + if (localPath == null) return ""; + localPath = localPath.trim(); + if (localPath.length() == 0) return ""; + return VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, localPath.replace(File.separatorChar, '/')); + } + + public static String localPathValue(String url) { + if (url == null) return ""; + url = url.trim(); + if (url.length() == 0) return ""; + return VirtualFileManager.extractPath(url).replace('/', File.separatorChar); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/Location.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/Location.java new file mode 100644 index 00000000000..dc014c6a504 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/Location.java @@ -0,0 +1,57 @@ +package com.intellij.execution; + +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +import java.util.Iterator; + +public abstract class Location { + public static final String LOCATION = "Location"; + + public abstract E getPsiElement(); + public abstract Project getProject(); + public abstract Iterator> getAncestors(Class ancestorClass, boolean strict); + + public OpenFileDescriptor getOpenFileDescriptor() { + final E psiElement = getPsiElement(); + final PsiFile psiFile = psiElement.getContainingFile(); + if (psiFile == null) return null; + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile == null) return null; + return new OpenFileDescriptor(getProject(), virtualFile, psiElement.getTextOffset()); + } + + public Location getParent(final Class parentClass) { + final Iterator> ancestors = getAncestors(PsiElement.class, true); + if (!ancestors.hasNext()) return null; + final Location parent = ancestors.next(); + if (parentClass.isInstance(parent.getPsiElement())) return (Location)parent; + return null; + } + + public Location getAncestorOrSelf(final Class ancestorClass) { + final Iterator> ancestors = getAncestors(ancestorClass, false); + if (!ancestors.hasNext()) return null; + return ancestors.next(); + } + + public Ancestor getParentElement(final Class parentClass) { + return safeGetPsiElement(getParent(parentClass)); + } + + public static T safeGetPsiElement(final Location location) { + return location != null ? location.getPsiElement() : null; + } + + public static T safeCast(final Object obj, final Class expectedClass) { + if (expectedClass.isInstance(obj)) return (T)obj; + return null; + } + + public PsiLocation toPsiLocation() { + return new PsiLocation(getProject(), getPsiElement()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/PsiLocation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/PsiLocation.java new file mode 100644 index 00000000000..649c9cb2d78 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/PsiLocation.java @@ -0,0 +1,84 @@ +package com.intellij.execution; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class PsiLocation extends Location { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.PsiLocation"); + private final E myPsiElement; + private final Project myProject; + + public PsiLocation(final Project project, final E psiElement) { + LOG.assertTrue(psiElement != null); + LOG.assertTrue(project != null); + myPsiElement = psiElement; + myProject = project; + } + + public E getPsiElement() { + return myPsiElement; + } + + public Project getProject() { + return myProject; + } + + public Iterator> getAncestors(final Class ancestorClass, final boolean strict) { + final Ancestor first; + if (!strict && ancestorClass.isInstance(myPsiElement)) first = (Ancestor)myPsiElement; + else first = findNext(myPsiElement, ancestorClass); + return new Iterator>() { + private Ancestor myCurrent = first; + public boolean hasNext() { + return myCurrent != null; + } + + public Location next() { + if (myCurrent == null) throw new NoSuchElementException(); + final PsiLocation psiLocation = new PsiLocation(myProject, myCurrent); + myCurrent = findNext(myCurrent, ancestorClass); + return psiLocation; + } + + public void remove() { + LOG.assertTrue(false); + } + }; + } + + public PsiLocation toPsiLocation() { + return this; + } + + private ElementClass findNext(final PsiElement psiElement, final Class ancestorClass) { + PsiElement element = psiElement; + while ((element = element.getParent()) != null) { + final ElementClass ancestor = safeCast(element, ancestorClass); + if (ancestor != null) return ancestor; + } + return null; + } + + public static Location fromClassQualifiedName(final Project project, final String qualifiedName) { + final PsiClass psiClass = PsiManager.getInstance(project).findClass(qualifiedName.replace('$', '.'), GlobalSearchScope.allScope(project)); + return psiClass != null ? new PsiLocation(project, psiClass) : null; + } + + public static Location fromPsiElement(final Project project, final ElementClass element) { + if (element == null) return null; + return new PsiLocation(project, element); + } + + public static Location fromPsiElement(final ElementClass element) { + if (element == null) return null; + if (!element.isValid()) return null; + return new PsiLocation(element.getProject(), element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunJavaConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunJavaConfiguration.java new file mode 100644 index 00000000000..026ddef96d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunJavaConfiguration.java @@ -0,0 +1,14 @@ +package com.intellij.execution; + +import com.intellij.openapi.project.Project; + +public interface RunJavaConfiguration { + int VM_PARAMETERS_PROPERTY = 0; + int PROGRAM_PARAMETERS_PROPERTY = 1; + int WORKING_DIRECTORY_PROPERTY = 2; + + void setProperty(int property, String value); + String getProperty(int property); + + Project getProject(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManager.java new file mode 100644 index 00000000000..fbb5251ecfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManager.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.project.Project; + +/** + * Manages {@link RunConfiguration}s. + * + * @see ExecutionRegistry + * @see ExecutionManager + */ +public abstract class RunManager { + public static RunManager getInstance(final Project project) { + return project.getComponent(RunManager.class); + } + + public abstract ConfigurationType getActiveConfigurationFactory(); + + public abstract ConfigurationType[] getConfigurationFactories(); + + public abstract RunConfiguration[] getConfigurations(ConfigurationType type); + + public abstract RunConfiguration[] getAllConfigurations(); + + public abstract RunnerAndConfigurationSettings getSelectedConfiguration(ConfigurationType type); + + public abstract RunnerAndConfigurationSettings getSelectedConfiguration(); + + public abstract RunConfiguration getTempConfiguration(); + + public abstract boolean isTemporary(RunConfiguration configuration); + public abstract boolean isTemporary(RunnerAndConfigurationSettings configuration); + + public abstract void makeStable(RunConfiguration configuration); + + public abstract void setActiveConfiguration(RunnerAndConfigurationSettings configuration); + + public abstract void setActiveConfigurationFactory(ConfigurationType activeConfigurationType); + + public abstract void setSelectedConfiguration(RunnerAndConfigurationSettings configuration); + + public abstract void setTemporaryConfiguration(RunnerAndConfigurationSettings tempConfiguration); + + public abstract RunManagerConfig getConfig(); + + public abstract RunnerAndConfigurationSettings createConfiguration(String name, ConfigurationFactory type); + + public abstract RunnerAndConfigurationSettings[] getConfigurationSettings(ConfigurationType type); + + public abstract void addConfiguration(RunnerAndConfigurationSettings settings); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManagerConfig.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManagerConfig.java new file mode 100644 index 00000000000..9d8c5105cfb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RunManagerConfig.java @@ -0,0 +1,31 @@ +package com.intellij.execution; + +import com.intellij.execution.util.StoringPropertyContainer; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.util.config.BooleanProperty; + +public class RunManagerConfig { + private static final BooleanProperty SHOW_SETTINGS = new BooleanProperty("showSettingsBeforeRunnig", true); + private static final BooleanProperty COMPILE_BERFORE_RUNNING = new BooleanProperty("compileBeforeRunning", true); + private StoringPropertyContainer myProperties; + + public RunManagerConfig(PropertiesComponent propertiesComponent) { + myProperties = new StoringPropertyContainer("RunManagerConfig.", propertiesComponent); + } + + public boolean isShowSettingsBeforeRun() { + return SHOW_SETTINGS.value(myProperties); + } + + public void setShowSettingsBeforeRun(final boolean value) { + SHOW_SETTINGS.primSet(myProperties, value); + } + + public boolean isCompileBeforeRunning() { + return COMPILE_BERFORE_RUNNING.value(myProperties); + } + + public void setCompileBeforeRunning(final boolean value) { + COMPILE_BERFORE_RUNNING.primSet(myProperties, value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RuntimeConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RuntimeConfiguration.java new file mode 100644 index 00000000000..39de2eb276f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/RuntimeConfiguration.java @@ -0,0 +1,43 @@ +package com.intellij.execution; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationInfoProvider; +import com.intellij.execution.configurations.RunConfigurationBase; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; + +public abstract class RuntimeConfiguration extends RunConfigurationBase implements Cloneable { + protected RuntimeConfiguration(final String name, final Project project, final ConfigurationFactory factory) { + super(project, factory, name); + } + + public Module[] getModules() { + return null; + } + + public RefactoringElementListener getRefactoringElementListener(final PsiElement element) { + return null; + } + + public void checkConfiguration() throws RuntimeConfigurationException { + } + + + public RuntimeConfiguration clone() { + return (RuntimeConfiguration)super.clone(); + } + + public JDOMExternalizable createRunnerSettings(ConfigurationInfoProvider provider) { + return null; + } + + public SettingsEditor getRunnerSettingsEditor(JavaProgramRunner runner) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/SingleClassConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/SingleClassConfiguration.java new file mode 100644 index 00000000000..2512c02254a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/SingleClassConfiguration.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.psi.PsiClass; + +/** + * @author dyoma + */ +public abstract class SingleClassConfiguration extends ModuleBasedConfiguration { + public SingleClassConfiguration(final String name, final RunConfigurationModule configurationModule, final ConfigurationFactory factory) { + super(name, configurationModule, factory); + } + + public void setMainClass(final PsiClass psiClass) { + setMainClassName(ExecutionUtil.getRuntimeQualifiedName(psiClass)); + setModule(ExecutionUtil.findModule(psiClass)); + } + + public abstract PsiClass getMainClass(); + public abstract void setMainClassName(String qualifiedName); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/TerminateRemoteProcessDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/TerminateRemoteProcessDialog.java new file mode 100644 index 00000000000..bc6673e4e4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/TerminateRemoteProcessDialog.java @@ -0,0 +1,59 @@ +/** + * created at Dec 14, 2001 + * @author Jeka + */ +package com.intellij.execution; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +public class TerminateRemoteProcessDialog extends DialogWrapper { + private JCheckBox myTerminateCheckBox; + private final String mySessionName; + private final boolean myDetachIsDefault; + + public TerminateRemoteProcessDialog(final Project project, final String configurationName, final boolean detachIsDefault) { + super(project, true); + mySessionName = configurationName; + myDetachIsDefault = detachIsDefault; + setTitle("Process \"" + mySessionName + "\" is running"); + setOKButtonText("Disconnect"); + setButtonsAlignment(SwingUtilities.CENTER); + this.init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(), getCancelAction()}; + } + + protected JComponent createNorthPanel() { + final String message; + message = "Disconnect from the process \"" + mySessionName + "\"?"; + final JLabel label = new JLabel(message); + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(label, BorderLayout.CENTER); + final Icon icon = UIManager.getIcon("OptionPane.warningIcon"); + if (icon != null) { + label.setIcon(icon); + label.setIconTextGap(7); + } + return panel; + } + + protected JComponent createCenterPanel() { + final JPanel panel = new JPanel(new BorderLayout()); + myTerminateCheckBox = new JCheckBox("Terminate the process after disconnect"); + myTerminateCheckBox.setMnemonic(KeyEvent.VK_T); + myTerminateCheckBox.setSelected(!myDetachIsDefault); + panel.add(myTerminateCheckBox, BorderLayout.EAST); + return panel; + } + + public boolean forceTermination() { + return myTerminateCheckBox.isSelected(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/BaseRunConfigurationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/BaseRunConfigurationAction.java new file mode 100644 index 00000000000..588533108a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/BaseRunConfigurationAction.java @@ -0,0 +1,111 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.RuntimeConfiguration; +import com.intellij.execution.applet.AppletConfiguration; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.execution.junit.JUnitConfiguration; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; + +abstract class BaseRunConfigurationAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.BaseRunConfigurationAction"); + + protected BaseRunConfigurationAction(final String text, final String description, final Icon icon) { + super(text, description, icon); + } + + public void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final ConfigurationContext context = new ConfigurationContext(dataContext); + final RunnerAndConfigurationSettings configuration = context.getConfiguration(); + if (configuration == null) return; + perform(context); + } + + protected abstract void perform(ConfigurationContext context); + + public void update(final AnActionEvent event){ + final ConfigurationContext context = new ConfigurationContext(event.getDataContext()); + final Presentation presentation = event.getPresentation(); + final RunnerAndConfigurationSettings configuration = context.getConfiguration(); + if (configuration == null){ + presentation.setEnabled(false); + presentation.setVisible(false); + } + else{ + presentation.setEnabled(true); + presentation.setVisible(true); + final String name = suggestRunActionName((RuntimeConfiguration)configuration.getConfiguration()); + updatePresentation(presentation, " " + name, context); + } + } + + public static String suggestRunActionName(final RuntimeConfiguration configuration) { + final ConfigurationAccessor accessor = getAccessor(configuration); + if (!accessor.isGeneratedName()) { + return "\"" + ExecutionUtil.shortenName(configuration.getName(), 0) + "\""; + } else return "\"" + accessor.suggestedName() + "\""; + } + + protected abstract void updatePresentation(Presentation presentation, String actionText, ConfigurationContext context); + + private interface ConfigurationAccessor { + boolean isGeneratedName(); + + String suggestedName(); + } + + private static ConfigurationAccessor getAccessor(final RuntimeConfiguration configuration) { + if (configuration instanceof ApplicationConfiguration) { + final ApplicationConfiguration applicationConfiguration = ((ApplicationConfiguration)configuration); + return new ConfigurationAccessor(){ + public boolean isGeneratedName() { + return applicationConfiguration.isGeneratedName(); + } + + public String suggestedName() { + return ExecutionUtil.shortenName(ExecutionUtil.getShortClassName(applicationConfiguration.MAIN_CLASS_NAME), 6) + ".main()"; + } + }; + } else if (configuration instanceof JUnitConfiguration) { + final JUnitConfiguration jUnitConfiguration = ((JUnitConfiguration)configuration); + return new ConfigurationAccessor() { + public boolean isGeneratedName() { + return jUnitConfiguration.isGeneratedName(); + } + + public String suggestedName() { + return jUnitConfiguration.getTestObject().suggestActionName(); + } + }; + } else if (configuration instanceof AppletConfiguration) { + final AppletConfiguration appletConfiguration = ((AppletConfiguration)configuration); + return new ConfigurationAccessor() { + public boolean isGeneratedName() { + return appletConfiguration.isGeneratedName(); + } + + public String suggestedName() { + return ExecutionUtil.shortenName(ExecutionUtil.getShortClassName(appletConfiguration.MAIN_CLASS_NAME), 0); + } + }; + } else return new ConfigurationAccessor() { + public boolean isGeneratedName() { + return false; + } + + public String suggestedName() { + LOG.error("Should not call"); + return ""; + } + }; + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/ConfigurationContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/ConfigurationContext.java new file mode 100644 index 00000000000..7d1115feb7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/ConfigurationContext.java @@ -0,0 +1,113 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.ConfigurationTypeEx; +import com.intellij.execution.Location; +import com.intellij.execution.PsiLocation; +import com.intellij.execution.RunManager; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; + +public class ConfigurationContext { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.ConfigurationContext"); + private final Location myLocation; + private final DataContext myDataContext; + private RunnerAndConfigurationSettings myConfiguration; + + public ConfigurationContext(final DataContext dataContext) { + myDataContext = dataContext; + final Object location = myDataContext.getData(Location.LOCATION); + if (location != null) { + myLocation = (Location)location; + return; + } + final Project project = (Project)myDataContext.getData(DataConstants.PROJECT); + if (project == null) { + myLocation = null; + return; + } + final PsiElement element = getSelectedPsiElement(dataContext, project); + if (element == null) { + myLocation = null; + return; + } + myLocation = new PsiLocation(project, element); + } + + public RunnerAndConfigurationSettings getConfiguration() { + if (myConfiguration == null) createConfiguration(); + return myConfiguration; + } + + private void createConfiguration() { + LOG.assertTrue(myConfiguration == null); + final Location location = getLocation(); + myConfiguration = location != null ? + new PreferedProducerFind().createConfiguration(location, this) : + null; + } + + private Location getLocation() { + return myLocation; + } + + public RunnerAndConfigurationSettings findExisting() { + final ConfigurationType type = getConfiguration().getType(); + if (!(type instanceof ConfigurationTypeEx)) return null; + final ConfigurationTypeEx factoryEx = (ConfigurationTypeEx)type; + final RunnerAndConfigurationSettings[] configurations = getRunManager().getConfigurationSettings(type); + for (int i = 0; i < configurations.length; i++) { + final RunnerAndConfigurationSettings existingConfiguration = configurations[i]; + if (factoryEx.isConfigurationByElement(existingConfiguration.getConfiguration(), getProject(), myLocation.getPsiElement())){ + return existingConfiguration; + } + } + return null; + } + + private static PsiElement getSelectedPsiElement(final DataContext dataContext, final Project project) { + PsiElement element = null; + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null){ + final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile != null) { + element = psiFile.findElementAt(editor.getCaretModel().getOffset()); + } + } + if (element == null) { + element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + } + if (element == null) { + final VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + if (file != null) { + element = PsiManager.getInstance(project).findFile(file); + } + } + return element; + } + + public RunManager getRunManager() { + return RunManager.getInstance(getProject()); + } + + public Project getProject() { return myLocation.getProject(); } + + public DataContext getDataContext() { + return myDataContext; + } + + public RunnerAndConfigurationSettings getOriginalConfiguration(final ConfigurationType type) { + final RunnerAndConfigurationSettings config = (RunnerAndConfigurationSettings)myDataContext.getData(DataConstantsEx.RUNTIME_CONFIGURATION); + return config != null && type.equals(config.getType()) ? config : null ; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/CreateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/CreateAction.java new file mode 100644 index 00000000000..a76e30c59a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/CreateAction.java @@ -0,0 +1,108 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.RunManager; +import com.intellij.execution.impl.RunDialog; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.actionSystem.Presentation; + +public class CreateAction extends BaseRunConfigurationAction { + public CreateAction() { + super("Create Run Configuration", null, null); + } + + protected void perform(final ConfigurationContext context) { + choosePolicy(context).perform(context); + } + + protected void updatePresentation(final Presentation presentation, final String actionText, final ConfigurationContext context) { + choosePolicy(context).update(presentation, context, actionText); + } + + private BaseCreatePolicy choosePolicy(final ConfigurationContext context) { + final RunnerAndConfigurationSettings configuration = context.findExisting(); + if (configuration == null) return CREATE_AND_EDIT; + final RunManager runManager = context.getRunManager(); + if (runManager.getSelectedConfiguration() != configuration) return SELECT; + if (runManager.isTemporary(configuration.getConfiguration())) return SAVE; + return SELECTED_STABLE; + } + + private static abstract class BaseCreatePolicy { + private final String myName; + + public BaseCreatePolicy(final String name) { + myName = name; + } + + public void update(final Presentation presentation, final ConfigurationContext context, final String actionText) { + updateText(presentation, actionText); + presentation.setIcon(context.getConfiguration().getFactory().getIcon()); + } + + protected void updateText(final Presentation presentation, final String actionText) { + presentation.setText(myName + " " + actionText); + } + + public abstract void perform(ConfigurationContext context); + } + + private static class SelectPolicy extends BaseCreatePolicy { + public SelectPolicy() { + super("Select"); + } + + public void perform(final ConfigurationContext context) { + final RunnerAndConfigurationSettings configuration = context.findExisting(); + if (configuration == null) return; + context.getRunManager().setActiveConfiguration(configuration); + } + } + + private static class CreatePolicy extends BaseCreatePolicy { + public CreatePolicy() { + super("Create"); + } + + public void perform(final ConfigurationContext context) { + final RunManager runManager = context.getRunManager(); + final RunnerAndConfigurationSettings configuration = context.getConfiguration(); + runManager.addConfiguration(configuration); + runManager.setActiveConfiguration(configuration); + } + } + + private static class CreateAndEditPolicy extends CreatePolicy { + protected void updateText(final Presentation presentation, final String actionText) { + presentation.setText("Create " + actionText + "..."); + } + + public void perform(final ConfigurationContext context) { + final RunnerAndConfigurationSettings configuration = context.getConfiguration(); + if (RunDialog.editConfiguration(context.getProject(), configuration, "Create " + configuration.getName())) + super.perform(context); + } + } + + private static class SavePolicy extends BaseCreatePolicy { + public SavePolicy() { + super("Save"); + } + + public void perform(final ConfigurationContext context) { + RunnerAndConfigurationSettings settings = context.findExisting(); + if (settings != null) context.getRunManager().makeStable(settings.getConfiguration()); + } + } + + private static final BaseCreatePolicy CREATE_AND_EDIT = new CreateAndEditPolicy(); + private static final BaseCreatePolicy SELECT = new SelectPolicy(); + private static final BaseCreatePolicy SAVE = new SavePolicy(); + private static final BaseCreatePolicy SELECTED_STABLE = new BaseCreatePolicy("Select") { + public void perform(final ConfigurationContext context) {} + + public void update(final Presentation presentation, final ConfigurationContext context, final String actionText) { + super.update(presentation, context, actionText); + presentation.setVisible(false); + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/EditRunConfigurationsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/EditRunConfigurationsAction.java new file mode 100644 index 00000000000..9ff00d62a76 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/EditRunConfigurationsAction.java @@ -0,0 +1,28 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.impl.EditConfigurationsDialog; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +public class EditRunConfigurationsAction extends AnAction{ + + public void actionPerformed(final AnActionEvent e) { + final Project project = getProject(e); + final EditConfigurationsDialog dialog = new EditConfigurationsDialog(project); + dialog.show(); + } + + private Project getProject(final AnActionEvent e) { + return (Project)e.getDataContext().getData(DataConstants.PROJECT); + } + + public void update(final AnActionEvent e) { + e.getPresentation().setEnabled(getProject(e) != null); + if (ActionPlaces.RUN_CONFIGURATIONS_COMBOBOX.equals(e.getPlace())) { + e.getPresentation().setText("&Edit Configurations"); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/PreferedProducerFind.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/PreferedProducerFind.java new file mode 100644 index 00000000000..c473e24a4c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/PreferedProducerFind.java @@ -0,0 +1,57 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.ConfigurationTypeEx; +import com.intellij.execution.Location; +import com.intellij.execution.RunManager; +import com.intellij.execution.application.ApplicationConfigurationProducer; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.execution.junit.JUnitConfigurationProducer; +import com.intellij.execution.junit.RuntimeConfigurationProducer; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; + +class PreferedProducerFind { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.PreferedProducerFind"); + + public RunnerAndConfigurationSettings createConfiguration(final Location location, final ConfigurationContext context) { + LOG.assertTrue(location != null); + final RuntimeConfigurationProducer preferedProducer = findPreferedProducer(location, context); + if (preferedProducer != null) { + return preferedProducer.getConfiguration(); + } + final ConfigurationType[] factories = RunManager.getInstance(location.getProject()).getConfigurationFactories(); + for(int i = 0; i < factories.length; i++){ + final ConfigurationType type = factories[i]; + if (type instanceof ConfigurationTypeEx) { + final RunnerAndConfigurationSettings configuration = ((ConfigurationTypeEx)type).createConfigurationByLocation(location); + if (configuration != null) { + return configuration; + } + } + } + return null; + } + + public RuntimeConfigurationProducer findPreferedProducer(final Location location, final ConfigurationContext context) { + final ArrayList prototypes = new ArrayList(); + prototypes.addAll(Arrays.asList(JUnitConfigurationProducer.PROTOTYPES)); + prototypes.add(ApplicationConfigurationProducer.PROTOTYPE); + final ArrayList producers = new ArrayList(); + for (Iterator iterator = prototypes.iterator(); iterator.hasNext();) { + final RuntimeConfigurationProducer prototype = iterator.next(); + final RuntimeConfigurationProducer producer = prototype.createProducer(location, context); + if (producer.getConfiguration() != null) { + LOG.assertTrue(producer.getSourceElement() != null, producer.toString()); + producers.add(producer); + } + } + if (producers.size() == 0) return null; + Collections.sort(producers, RuntimeConfigurationProducer.COMPARATOR); + return producers.get(0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunConfigurationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunConfigurationAction.java new file mode 100644 index 00000000000..6a08e3eda9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunConfigurationAction.java @@ -0,0 +1,204 @@ + +package com.intellij.execution.actions; + +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.RunManager; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; + +public class RunConfigurationAction extends ComboBoxAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.RunConfigurationAction"); + private static final Key BUTTON_KEY = Key.create("COMBOBOX_BUTTON"); + + public RunConfigurationAction() { + super(ActionPlaces.RUN_CONFIGURATIONS_COMBOBOX); + } + + public void actionPerformed(final AnActionEvent e) { + final IdeFrame ideFrame = findFrame(e.getDataContext()); + final ComboBoxAction.ComboBoxButton button = (ComboBoxAction.ComboBoxButton)ideFrame.getRootPane().getClientProperty(BUTTON_KEY); + if (button == null || !button.isShowing()) return; + button.showPopup(); + } + + private IdeFrame findFrame(final Component component) { + return IJSwingUtilities.findParentOfType(component, IdeFrame.class); + } + + private IdeFrame findFrame(final DataContext dataContext) { + return findFrame((Component)dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT)); + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (ActionPlaces.MAIN_MENU.equals(e.getPlace())) { + presentation.setDescription("Open run/debug configurations dropdown"); + presentation.setEnabled(findFrame(dataContext) != null); + return; + } + + if (project == null) { + //if (ProjectManager.getInstance().getOpenProjects().length > 0) { + // // do nothing if frame is not active + // return; + //} + + updateButton(null, null, presentation); + presentation.setEnabled(false); + } + else { + final RunManager runManager = RunManager.getInstance(project); + RunnerAndConfigurationSettings selected = runManager.getSelectedConfiguration(); + updateButton(selected == null? null : selected.getConfiguration(), project, presentation); + presentation.setEnabled(true); + } + } + + private void updateButton(final RunConfiguration configuration, final Project project, final Presentation presentation) { + if (project != null && configuration != null) { + presentation.setText(getConfigurationDescription(configuration), false); + setConfigurationIcon(presentation, configuration, project); + } + else { + presentation.setText(" "); + presentation.setIcon(null); + } + } + + private void setConfigurationIcon(final Presentation presentation, final RunConfiguration configuration, final Project project) { + presentation.setIcon(ExecutionUtil.getConfigurationIcon(project, configuration)); + } + + public JComponent createCustomComponent(final Presentation presentation) { + final ComboBoxAction.ComboBoxButton comboboxButton = new ComboBoxAction.ComboBoxButton(presentation) { + protected void updateButtonSize() { + super.updateButtonSize(); + final Dimension preferredSize = getPreferredSize(); + final int width = preferredSize.width; + final int height = preferredSize.height; + if (width > height * 15) { + setPreferredSize(new Dimension(height * 15, height)); + } + } + + public void addNotify() { + super.addNotify(); //To change body of overriden methods use Options | File Templates.; + final IdeFrame frame = findFrame(this); + LOG.assertTrue(frame != null); + frame.getRootPane().putClientProperty(BUTTON_KEY, this); + } + }; + return comboboxButton; + } + + + protected DefaultActionGroup createPopupActionGroup(final JComponent button) { + final DefaultActionGroup allActionsGroup = new DefaultActionGroup(); + final Project project = (Project)DataManager.getInstance().getDataContext(button).getData(DataConstants.PROJECT); + if (project != null) { + final RunManager runManager = RunManager.getInstance(project); + + final ConfigurationType[] types = runManager.getConfigurationFactories(); + for (int i = 0; i < types.length; i++) { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + final RunnerAndConfigurationSettings[] configurations = runManager.getConfigurationSettings(types[i]); + for (int j = 0; j < configurations.length; j++) { + final RunnerAndConfigurationSettings configuration = configurations[j]; + //if (runManager.canRunConfiguration(configuration)) { + final MenuAction action = new MenuAction(configuration, project); + actionGroup.add(action); + //} + } + allActionsGroup.add(actionGroup); + allActionsGroup.addSeparator(); + } + + allActionsGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_RUN_CONFIGURATIONS)); + allActionsGroup.add(new SaveTemporaryAction()); + } + return allActionsGroup; + } + + class SaveTemporaryAction extends AnAction { + public void actionPerformed(final AnActionEvent e) { + final RunManager runManager = RunManager.getInstance(getProject(e)); + runManager.makeStable(runManager.getTempConfiguration()); + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final Project project = getProject(e); + if (project == null) { + disable(presentation); + return; + } + final RunConfiguration tempConfiguration = RunManager.getInstance(project).getTempConfiguration(); + if (tempConfiguration == null) { + disable(presentation); + return; + } + presentation.setText("&Save " + tempConfiguration.getName() + " Configuration"); + presentation.setVisible(true); + presentation.setEnabled(true); + } + + private Project getProject(final AnActionEvent e) { + return (Project)e.getDataContext().getData(DataConstants.PROJECT); + } + + private void disable(final Presentation presentation) { + presentation.setEnabled(false); + presentation.setVisible(false); + } + } + + class MenuAction extends AnAction { + private RunnerAndConfigurationSettings myConfiguration; + private Project myProject; + + public MenuAction(final RunnerAndConfigurationSettings configuration, final Project project) { + myConfiguration = configuration; + myProject = project; + String description = getConfigurationDescription(configuration.getConfiguration()); + if (description == null || description.length() == 0) { + description = " "; + } + final Presentation presentation = getTemplatePresentation(); + presentation.setText(description, false); + updateIcon(presentation); + } + + private void updateIcon(final Presentation presentation) { + setConfigurationIcon(presentation, myConfiguration.getConfiguration(), myProject); + } + + public void actionPerformed(final AnActionEvent e){ + RunManager.getInstance(myProject).setActiveConfiguration(myConfiguration); + updateButton(myConfiguration.getConfiguration(), myProject, e.getPresentation()); + } + + public void update(final AnActionEvent e) { + super.update(e); + updateIcon(e.getPresentation()); + } + } + + private String getConfigurationDescription(final RunConfiguration configuration) { + return configuration.getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunContextAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunContextAction.java new file mode 100644 index 00000000000..6f8da0c1e59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/RunContextAction.java @@ -0,0 +1,40 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.RunManager; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.ui.Messages; + +public class RunContextAction extends BaseRunConfigurationAction { + private final JavaProgramRunner myRunner; + + public RunContextAction(final JavaProgramRunner runner) { + super(runner.getInfo().getStartActionText() + " context configuration", null, runner.getInfo().getIcon()); + myRunner = runner; + } + + protected void perform(final ConfigurationContext context) { + RunnerAndConfigurationSettings configuration = context.findExisting(); + final RunManager runManager = context.getRunManager(); + if (configuration == null) { + configuration = context.getConfiguration(); + if (configuration == null) return; + runManager.setTemporaryConfiguration(configuration); + } + runManager.setActiveConfiguration(configuration); + try { + RunStrategy.getInstance().execute(configuration.getConfiguration(), context.getDataContext(), myRunner, + configuration.getRunnerSettings(myRunner), configuration.getConfigurationSettings(myRunner)); + } + catch (ExecutionException e) { + Messages.showErrorDialog(context.getProject(), e.getMessage(), "Error"); + } + } + + protected void updatePresentation(final Presentation presentation, final String actionText, final ConfigurationContext context) { + presentation.setText(myRunner.getInfo().getStartActionText() + actionText, true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/StopAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/StopAction.java new file mode 100644 index 00000000000..d8cd4266117 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/actions/StopAction.java @@ -0,0 +1,55 @@ +package com.intellij.execution.actions; + +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ + +public class StopAction extends AnAction{ + public void actionPerformed(final AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + if(project == null) return; + + final RunContentDescriptor selectedContent = ExecutionManager.getInstance(project).getContentManager().getSelectedContent(); + + if(selectedContent == null) return; + + final ProcessHandler selectedProcessHandler = selectedContent.getProcessHandler(); + + if(selectedProcessHandler == null) return; + + if(selectedProcessHandler.detachIsDefault()) { + selectedProcessHandler.detachProcess(); + } else { + selectedProcessHandler.destroyProcess(); + } + } + + public void update(final AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + boolean enable = false; + + if(project != null) { + final RunContentDescriptor selectedContent = ExecutionManager.getInstance(project).getContentManager().getSelectedContent(); + if (selectedContent != null) { + final ProcessHandler selectedProcessHandler = selectedContent.getProcessHandler(); + + if(selectedProcessHandler != null) { + enable = !selectedProcessHandler.isProcessTerminating() && !selectedProcessHandler.isProcessTerminated(); + } + } + } + + e.getPresentation().setEnabled(enable); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurable.java new file mode 100644 index 00000000000..1a15dfadb17 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurable.java @@ -0,0 +1,269 @@ +package com.intellij.execution.applet; + +import com.intellij.execution.junit2.configuration.ClassBrowser; +import com.intellij.execution.junit2.configuration.ConfigurationModuleSelector; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.vcs.ui.exclude.ComparablesComparator; +import com.intellij.ui.RawCommandLineEditor; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.table.TableView; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +public class AppletConfigurable extends SettingsEditor { + private JPanel myWholePanel; + private JRadioButton myMainClass; + private JRadioButton myURL; + private JPanel myClassOptions; + private JPanel myHTMLOptions; + private LabeledComponent myPolicyFile; + private LabeledComponent myVMParameters; + private TextFieldWithBrowseButton myClassName; + private TextFieldWithBrowseButton myHtmlFile; + private JTextField myWidth; + private JTextField myHeight; + private LabeledComponent myModule; + private JPanel myTablePlace; + private JButton myAddButton; + private JButton myRemoveButton; + private JLabel myHtmlFileLabel; + private JLabel myClassNameLabel; + private JLabel myWidthLabel; + private JLabel myHeightLabel; + private ButtonGroup myAppletRadioButtonGroup = new ButtonGroup(); + + private final Project myProject; + private final ConfigurationModuleSelector myModuleSelector; + + private static final ColumnInfo[] PARAMETER_COLUMNS = new ColumnInfo[]{ + new MyColumnInfo("Name"){ + public String valueOf(final AppletConfiguration.AppletParameter appletParameter) { + return appletParameter.getName(); + } + + public void setValue(final AppletConfiguration.AppletParameter appletParameter, final String name) { + appletParameter.setName(name); + } + }, + new MyColumnInfo("Value") { + public String valueOf(final AppletConfiguration.AppletParameter appletParameter) { + return appletParameter.getValue(); + } + + public void setValue(final AppletConfiguration.AppletParameter appletParameter, final String value) { + appletParameter.setValue(value); + } + } + }; + private final ListTableModel myParameters = new ListTableModel(PARAMETER_COLUMNS); + private final TableView myTable; + + private void changePanel () { + if (myMainClass.isSelected()) { + myClassOptions.setVisible(true); + myHTMLOptions.setVisible(false); + } else { + myHTMLOptions.setVisible(true); + myClassOptions.setVisible(false); + } + } + + public AppletConfigurable(final Project project) { + myClassNameLabel.setLabelFor(myClassName.getTextField()); + myHtmlFileLabel.setLabelFor(myHtmlFile.getTextField()); + myWidthLabel.setLabelFor(myWidth); + myHeightLabel.setLabelFor(myHeight); + + myProject = project; + myModuleSelector = new ConfigurationModuleSelector(project, getModuleComponent()); + myTablePlace.setLayout(new BorderLayout()); + myTable = new TableView(myParameters); + myTablePlace.add(ScrollPaneFactory.createScrollPane(myTable), BorderLayout.CENTER); + myAppletRadioButtonGroup.add(myMainClass); + myAppletRadioButtonGroup.add(myURL); + getVMParametersComponent().setDialodCaption(myVMParameters.getRawText()); + + myMainClass.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + changePanel(); + } + }); + myURL.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + changePanel(); + } + }); + + getPolicyFileComponent().addBrowseFolderListener("Select applet policy file", null, myProject, + FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()); + getHtmlPathComponent().addBrowseFolderListener("Choose HTML File", null, myProject, + FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()); + ClassBrowser.createAppletClassBrowser(myProject, myModuleSelector).setField(getClassNameComponent()); + + myHTMLOptions.setVisible(false); + + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + addParameter(); + } + }); + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + removeParameter(); + } + }); + } + + private void removeParameter() { + final int selectedRow = myTable.getSelectedRow(); + if (selectedRow < 0 || selectedRow >= myTable.getRowCount()) return; + final ArrayList newItems = + new ArrayList(myParameters.getItems()); + newItems.remove(selectedRow); + myParameters.setItems(newItems); + } + + private void addParameter() { + final ArrayList newItems = + new ArrayList(myParameters.getItems()); + newItems.add(new AppletConfiguration.AppletParameter("newParameter", "")); + myParameters.setItems(newItems); + } + + private JComboBox getModuleComponent() { + return myModule.getComponent(); + } + + private TextFieldWithBrowseButton getPolicyFileComponent() { + return myPolicyFile.getComponent(); + } + + private void getConfigurationTo(final AppletConfiguration configuration) { + configuration.MAIN_CLASS_NAME = toNull(getClassNameComponent().getText()); + configuration.HTML_FILE_NAME = toSystemFormat(getHtmlPathComponent().getText()); + configuration.VM_PARAMETERS = toNull(getVMParametersComponent().getText()); + configuration.setPolicyFile(getPolicyFileComponent().getText()); + myModuleSelector.applyTo(configuration); + try { + configuration.WIDTH = Integer.parseInt(getWidthComponent().getText()); + } + catch (NumberFormatException e) { + } + try { + configuration.HEIGHT = Integer.parseInt(getHeightComponent().getText()); + } + catch (NumberFormatException e) { + } + configuration.HTML_USED = myURL.isSelected(); + if (myTable.getCellEditor() != null) { + myTable.getCellEditor().stopCellEditing(); + } + + configuration.setAppletParameters(myParameters.getItems()); + } + + private JTextField getWidthComponent() { + return myWidth; + } + + private TextFieldWithBrowseButton getClassNameComponent() { + return myClassName; + } + + private TextFieldWithBrowseButton getHtmlPathComponent() { + return myHtmlFile; + } + + private String toNull(String s) { + s = s.trim(); + return s.length() == 0 ? null : s; + } + + private String toSystemFormat(String s) { + s = s.trim(); + return s.length() == 0 ? null : s.replace(File.separatorChar, '/'); + } + + public void applyEditorTo(final AppletConfiguration configuration) { + getConfigurationTo(configuration); + } + + public void resetEditorFrom(final AppletConfiguration configuration) { + getClassNameComponent().setText(configuration.MAIN_CLASS_NAME); + String presentableHtmlName = configuration.HTML_FILE_NAME; + if (presentableHtmlName != null && !presentableHtmlName.toLowerCase().startsWith("http:/")) { + presentableHtmlName = presentableHtmlName.replace('/', File.separatorChar); + } + getHtmlPathComponent().setText(presentableHtmlName); + getPolicyFileComponent().setText(configuration.getPolicyFile()); + getVMParametersComponent().setText(configuration.VM_PARAMETERS); + getWidthComponent().setText(Integer.toString(configuration.WIDTH)); + getHeightComponent().setText(Integer.toString(configuration.HEIGHT)); + + (configuration.HTML_USED ? myURL : myMainClass).setSelected(true); + changePanel(); + + final AppletConfiguration.AppletParameter[] appletParameters = configuration.getAppletParameters(); + if (appletParameters != null) { + myParameters.setItems(Arrays.asList(appletParameters)); + } + myModuleSelector.reset(configuration); + } + + private RawCommandLineEditor getVMParametersComponent() { + return myVMParameters.getComponent(); + } + + private JTextField getHeightComponent() { + return myHeight; + } + + + public JComponent createEditor() { + return myWholePanel; + } + + public void disposeEditor() { + } + + private static abstract class MyColumnInfo extends ColumnInfo { + private static final ComparablesComparator COMPARATOR = new ComparablesComparator(); + + public MyColumnInfo(final String name) { + super(name); + } + + public Comparator getComparator() { + return new Comparator() { + public int compare(final AppletConfiguration.AppletParameter parameter1, + final AppletConfiguration.AppletParameter parameter2) { + return COMPARATOR.compare(valueOf(parameter1), valueOf(parameter2)); + } + }; + } + + public TableCellEditor getEditor(final AppletConfiguration.AppletParameter item) { + final JTextField textField = new JTextField(); + textField.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + return new DefaultCellEditor(textField); + } + + public boolean isCellEditable(final AppletConfiguration.AppletParameter appletParameter) { + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfiguration.java new file mode 100644 index 00000000000..55f4e1ce58e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfiguration.java @@ -0,0 +1,318 @@ +package com.intellij.execution.applet; + +import com.intellij.execution.*; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.TextConsoleBuidlerFactory; +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.execution.junit.RefactoringListeners; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import org.jdom.Element; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class AppletConfiguration extends SingleClassConfiguration { + + public String MAIN_CLASS_NAME; + public String HTML_FILE_NAME; + public boolean HTML_USED; + public int WIDTH; + public int HEIGHT; + public String POLICY_FILE; + public String VM_PARAMETERS; + private AppletParameter[] myAppletParameters; + + public AppletConfiguration(final String name, final Project project, ConfigurationFactory factory) { + super(name, new RunConfigurationModule(project, false), factory); + } + + public RunProfileState getState(final DataContext context, + final RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + final JavaCommandLineState state = new JavaCommandLineState(runnerSettings, configurationSettings) { + private AppletHtmlFile myHtmlURL = null; + + protected JavaParameters createJavaParameters() throws ExecutionException { + final JavaParameters params = new JavaParameters(); + myHtmlURL = getHtmlURL(); + if (myHtmlURL != null) { + final int classPathType = myHtmlURL.isHttp() ? JavaParameters.JDK_ONLY : JavaParameters.JDK_AND_CLASSES_AND_TESTS; + final RunConfigurationModule runConfigurationModule = getConfigurationModule(); + if (runConfigurationModule.getModule() == null) { + throw CantRunException.noModuleConfigured(runConfigurationModule.getModuleName()); + } + params.configureByModule(runConfigurationModule.getModule(), classPathType); + final String policyFileParameter = getPolicyFileParameter(); + if (policyFileParameter != null) { + params.getVMParametersList().add(policyFileParameter); + } + params.getVMParametersList().addParametersString(VM_PARAMETERS); + params.setMainClass("sun.applet.AppletViewer"); + if (params.getJdk().getVersionString().indexOf("1.1") > -1) { + params.getClassPath().add(params.getJdkPath() + File.separator + "lib" + File.separator + "classes.zip"); + } + else { + params.getClassPath().add(params.getJdkPath() + File.separator + "lib" + File.separator + "tools.jar"); + } + params.getProgramParametersList().add(myHtmlURL.getUrl()); + } + return params; + } + + protected OSProcessHandler startProcess() throws ExecutionException { + final OSProcessHandler handler = super.startProcess(); + final AppletHtmlFile htmlUrl = myHtmlURL; + if (htmlUrl != null) { + handler.addProcessListener(new ProcessAdapter() { + public void processTerminated(ProcessEvent event) { + htmlUrl.deleteFile(); + } + }); + } + return handler; + } + }; + state.setConsoleBuilder(TextConsoleBuidlerFactory.getInstance().createBuilder(getProject())); + state.setModulesToCompile(getModules()); + return state; + } + + public SettingsEditor getConfigurationEditor() { + return new AppletConfigurable(getProject()); + } + + private String getPolicyFileParameter() { + if (POLICY_FILE != null && POLICY_FILE.length() > 0) { + return "-Djava.security.policy=" + getPolicyFile(); + } + return null; + } + + public void setPolicyFile(final String localPath) { + POLICY_FILE = ExternalizablePath.urlValue(localPath); + } + + public String getPolicyFile() { + return ExternalizablePath.localPathValue(POLICY_FILE); + } + + public static class AppletParameter { + public String myName; + public String myValue; + + public AppletParameter(final String name, final String value) { + myName = name; + myValue = value; + } + + public String getName() { + return myName; + } + + public void setName(final String name) { + myName = name; + } + + public String getValue() { + return myValue; + } + + public void setValue(final String value) { + myValue = value; + } + + public boolean equals(final Object obj) { + if (!(obj instanceof AppletParameter)) return false; + final AppletParameter second = (AppletParameter)obj; + return Comparing.equal(myName, second.myName) && Comparing.equal(myValue, second.myValue); + } + + public int hashCode() { + return Comparing.hashcode(myName, myValue); + } + } + + public Collection getValidModules() { + return RunConfigurationModule.getModulesForClass(getProject(), MAIN_CLASS_NAME); + } + + public void readExternal(final Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + readModule(parentNode); + final ArrayList parameters = new ArrayList(); + for (Iterator iterator = parentNode.getChildren("parameter").iterator(); iterator.hasNext();) { + final Element element = (Element)iterator.next(); + final String name = element.getAttributeValue("name"); + final String value = element.getAttributeValue("value"); + parameters.add(new AppletParameter(name, value)); + } + myAppletParameters = parameters.toArray(new AppletParameter[parameters.size()]); + } + + public void writeExternal(final Element parentNode) throws WriteExternalException { + writeModule(parentNode); + DefaultJDOMExternalizer.writeExternal(this, parentNode); + if (myAppletParameters != null) { + for (int i = 0; i < myAppletParameters.length; i++) { + final Element element = new Element("parameter"); + parentNode.addContent(element); + element.setAttribute("name", myAppletParameters[i].getName()); + element.setAttribute("value", myAppletParameters[i].getValue()); + } + } + } + + protected ModuleBasedConfiguration createInstance() { + return new AppletConfiguration(getName(), getProject(), AppletConfigurationType.getInstance().getConfigurationFactories()[0]); + } + + public String getGeneratedName() { + if (MAIN_CLASS_NAME == null) return null; + return ExecutionUtil.getPresentableClassName(MAIN_CLASS_NAME, getConfigurationModule()); + } + + public RefactoringElementListener getRefactoringElementListener(final PsiElement element) { + if (HTML_USED) return super.getRefactoringElementListener(element); + return RefactoringListeners.getClassOrPackageListener(element, new RefactoringListeners.SingleClassConfigurationAccessor(this)); + } + + public PsiClass getMainClass() { + return getConfigurationModule().findClass(MAIN_CLASS_NAME); + } + + public void setGeneratedName() { + setName(getGeneratedName()); + } + + public boolean isGeneratedName() { + return Comparing.equal(getName(), getGeneratedName()); + } + + public void setMainClassName(final String qualifiedName) { + final boolean generatedName = isGeneratedName(); + MAIN_CLASS_NAME = qualifiedName; + if (generatedName) setGeneratedName(); + } + + public void checkConfiguration() throws RuntimeConfigurationException { + getConfigurationModule().checkForWarning(); + if (HTML_USED) { + if (HTML_FILE_NAME == null || HTML_FILE_NAME.length() == 0) { + throw new RuntimeConfigurationWarning("Html file not specified"); + } + } + else { + getConfigurationModule().checkClassName(MAIN_CLASS_NAME, "applet class"); + } + } + + public AppletParameter[] getAppletParameters() { + return myAppletParameters; + } + + public void setAppletParameters(final AppletParameter[] appletParameters) { + myAppletParameters = appletParameters; + } + + public void setAppletParameters(final List parameters) { + setAppletParameters(parameters.toArray(new AppletParameter[parameters.size()])); + } + + private AppletHtmlFile getHtmlURL() throws CantRunException { + if (HTML_USED) { + if (HTML_FILE_NAME == null || HTML_FILE_NAME.length() == 0) { + throw new CantRunException("HTML file not specified."); + } + return new AppletHtmlFile(HTML_FILE_NAME, null); + } + else { + if (MAIN_CLASS_NAME == null || MAIN_CLASS_NAME.length() == 0) { + throw new CantRunException("Class not specified."); + } + + // generate html + try { + final File tempFile = File.createTempFile("AppletPage", ".html"); + final FileWriter writer = new FileWriter(tempFile); + writer.write("\n" + + "\n" + + "" + MAIN_CLASS_NAME + "\n" + + "\n" + + "\n"); + final AppletParameter[] appletParameters = getAppletParameters(); + if (appletParameters != null) { + for (int i = 0; i < appletParameters.length; i++) { + final AppletParameter parameter = appletParameters[i]; + writer.write("\n"); + } + } + writer.write("\n\n\n"); + writer.close(); + final String htmlFile = tempFile.getAbsolutePath(); + return new AppletHtmlFile(htmlFile, tempFile); + } + catch (IOException e) { + throw new CantRunException("Failed to generate temporary html wrapper for applet class"); + } + } + } + + private static class AppletHtmlFile { + private final String myHtmlFile; + private final File myFileToDelete; + + protected AppletHtmlFile(final String htmlFile, final File fileToDelete) { + myHtmlFile = htmlFile; + myFileToDelete = fileToDelete; + } + + public String getUrl() { + if (!myHtmlFile.toLowerCase().startsWith("file:/") && !isHttp()) { + try { + return new File(myHtmlFile).toURL().toString(); + } + catch (MalformedURLException ex) { + } + } + return myHtmlFile; + } + + public boolean isHttp() { + final String lowerCaseUrl = myHtmlFile.toLowerCase(); + return lowerCaseUrl.startsWith("http:/") || lowerCaseUrl.startsWith("https:/"); + } + + public void deleteFile() { + if (myFileToDelete != null) { + myFileToDelete.delete(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurationType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurationType.java new file mode 100644 index 00000000000..ca7c00bae11 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/applet/AppletConfigurationType.java @@ -0,0 +1,117 @@ +package com.intellij.execution.applet; + +import com.intellij.execution.ConfigurationTypeEx; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.Location; +import com.intellij.execution.RunManager; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.execution.junit.JUnitUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; + +import javax.swing.*; + +public class AppletConfigurationType implements ConfigurationTypeEx { + private final ConfigurationFactory myFactory; + private static final Icon ICON = IconLoader.getIcon("/runConfigurations/applet.png"); + + /**reflection*/ + AppletConfigurationType() { + myFactory = new ConfigurationFactory(this) { + public RunConfiguration createTemplateConfiguration(Project project) { + return new AppletConfiguration("", project, this); + } + + }; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "Applet"; + } + + public String getConfigurationTypeDescription() { + return "Applet configuration"; + } + + public Icon getIcon() { + return ICON; + } + + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[]{myFactory}; + } + + public RunnerAndConfigurationSettings createConfigurationByLocation(Location location) { + location = ExecutionUtil.stepIntoSingleClass(location); + final Project project = location.getProject(); + final PsiElement element = location.getPsiElement(); + final PsiClass aClass = getAppletClass(element, PsiManager.getInstance(project)); + if (aClass == null) return null; + RunnerAndConfigurationSettings settings = RunManager.getInstance(project).createConfiguration("", getConfigurationFactories()[0]); + final AppletConfiguration configuration = (AppletConfiguration)settings.getConfiguration(); + configuration.MAIN_CLASS_NAME = ExecutionUtil.getRuntimeQualifiedName(aClass); + configuration.setModule(new JUnitUtil.ModuleOfClass(project).convert(aClass)); + configuration.setName(configuration.getGeneratedName()); + return settings; + } + + public boolean isConfigurationByElement(final RunConfiguration configuration, final Project project, final PsiElement element) { + final PsiClass aClass = getAppletClass(element, PsiManager.getInstance(project)); + if (aClass == null) return false; + return Comparing.equal(ExecutionUtil.getRuntimeQualifiedName(aClass), ((AppletConfiguration)configuration).MAIN_CLASS_NAME); + } + + private PsiClass getAppletClass(PsiElement element, final PsiManager manager) { + while (element != null) { + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + if (isAppletClass(aClass, manager)){ + return aClass; + } + } + element = element.getParent(); + } + return null; + } + + private boolean isAppletClass(final PsiClass aClass, final PsiManager manager) { + if (!ExecutionUtil.isRunnableClass(aClass)) return false; + + final Module module = ExecutionUtil.findModule(aClass); + final GlobalSearchScope scope = module != null + ? GlobalSearchScope.moduleWithLibrariesScope(module) + : GlobalSearchScope.projectScope(manager.getProject()); + PsiClass appletClass = manager.findClass("java.applet.Applet", scope); + if (appletClass != null) { + if (aClass.isInheritor(appletClass, true)) return true; + } + appletClass = manager.findClass("javax.swing.JApplet", scope); + if (appletClass != null) { + if (aClass.isInheritor(appletClass, true)) return true; + } + return false; + } + + + public String getComponentName() { + return "Applet"; + } + + public static AppletConfigurationType getInstance() { + return ApplicationManager.getApplication().getComponent(AppletConfigurationType.class); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurable2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurable2.java new file mode 100644 index 00000000000..c9c635aa979 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurable2.java @@ -0,0 +1,56 @@ +package com.intellij.execution.application; + +import com.intellij.execution.junit2.configuration.ClassBrowser; +import com.intellij.execution.junit2.configuration.CommonJavaParameters; +import com.intellij.execution.junit2.configuration.ConfigurationModuleSelector; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; + +import javax.swing.*; + +public class ApplicationConfigurable2 extends SettingsEditor{ + private CommonJavaParameters myCommonJavaParameters; + private LabeledComponent myMainClass; + private LabeledComponent myModule; + private JPanel myWholePanel; + + private final ConfigurationModuleSelector myModuleSelector; + + public ApplicationConfigurable2(final Project project) { + myModuleSelector = new ConfigurationModuleSelector(project, myModule.getComponent()); + ClassBrowser.createApplicationClassBrowser(project, myModuleSelector).setField(getMainClassField()); + } + + public void applyEditorTo(final ApplicationConfiguration configuration){ + myCommonJavaParameters.applyTo(configuration); + myModuleSelector.applyTo(configuration); + configuration.MAIN_CLASS_NAME = getMainClassField().getText(); + } + + public void resetEditorFrom(final ApplicationConfiguration configuration) { + myCommonJavaParameters.reset(configuration); + myModuleSelector.reset(configuration); + getMainClassField().setText(configuration.MAIN_CLASS_NAME); + } + + public TextFieldWithBrowseButton getMainClassField() { + return myMainClass.getComponent(); + } + + public CommonJavaParameters getCommonJavaParameters() { + return myCommonJavaParameters; + } + + public JComponent createEditor() { + return myWholePanel; + } + + public void disposeEditor() { + } + + public String getHelpTopic() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfiguration.java new file mode 100644 index 00000000000..6a1884f538f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfiguration.java @@ -0,0 +1,150 @@ +package com.intellij.execution.application; + +import com.intellij.execution.*; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.TextConsoleBuidlerFactory; +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.execution.junit.RefactoringListeners; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.execution.util.JavaParametersUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import org.jdom.Element; + +import java.util.Collection; + +public class ApplicationConfiguration extends SingleClassConfiguration implements RunJavaConfiguration { + + public String MAIN_CLASS_NAME; + public String VM_PARAMETERS; + public String PROGRAM_PARAMETERS; + public String WORKING_DIRECTORY; + + public ApplicationConfiguration(final String name, final Project project, ApplicationConfigurationType applicationConfigurationType) { + super(name, new RunConfigurationModule(project, true), applicationConfigurationType.getConfigurationFactories()[0]); + } + + public RunProfileState getState(final DataContext context, + final RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + final JavaCommandLineState state = new JavaCommandLineState(runnerSettings, configurationSettings) { + protected JavaParameters createJavaParameters() throws ExecutionException { + final JavaParameters params = new JavaParameters(); + JavaParametersUtil.configureModule(getConfigurationModule(), params, JavaParameters.JDK_AND_CLASSES_AND_TESTS); + JavaParametersUtil.configureConfiguration(params, ApplicationConfiguration.this); + params.setMainClass(MAIN_CLASS_NAME); + return params; + } + }; + state.setConsoleBuilder(TextConsoleBuidlerFactory.getInstance().createBuilder(getProject())); + state.setModulesToCompile(getModules()); + return state; + } + + public SettingsEditor getConfigurationEditor() { + return new ApplicationConfigurable2(getProject()); + } + + public String getGeneratedName() { + if (MAIN_CLASS_NAME == null) { + return null; + } + return ExecutionUtil.getPresentableClassName(MAIN_CLASS_NAME, getConfigurationModule()); + } + + public void setGeneratedName() { + setName(getGeneratedName()); + } + + public RefactoringElementListener getRefactoringElementListener(final PsiElement element) { + return RefactoringListeners. + getClassOrPackageListener(element, new RefactoringListeners.SingleClassConfigurationAccessor(this)); + } + + public PsiClass getMainClass() { + return getConfigurationModule().findClass(MAIN_CLASS_NAME); + } + + public boolean isGeneratedName() { + if (MAIN_CLASS_NAME == null || MAIN_CLASS_NAME.length() == 0) { + return ExecutionUtil.isNewName(getName()); + } + return Comparing.equal(getName(), getGeneratedName()); + } + + public void setMainClassName(final String qualifiedName) { + final boolean generatedName = isGeneratedName(); + MAIN_CLASS_NAME = qualifiedName; + if (generatedName) setGeneratedName(); + } + + public void checkConfiguration() throws RuntimeConfigurationException { + final RunConfigurationModule configurationModule = getConfigurationModule(); + final PsiClass psiClass = configurationModule.checkModuleAndClassName(MAIN_CLASS_NAME, "main class"); + if (ApplicationConfigurationType.findMainMethod(psiClass.findMethodsByName("main", true)) == null) { + throw new RuntimeConfigurationWarning("Main method not found in class " + MAIN_CLASS_NAME); + } + } + + public void setProperty(final int property, final String value) { + switch (property) { + case PROGRAM_PARAMETERS_PROPERTY: + PROGRAM_PARAMETERS = value; + break; + case VM_PARAMETERS_PROPERTY: + VM_PARAMETERS = value; + break; + case WORKING_DIRECTORY_PROPERTY: + WORKING_DIRECTORY = ExternalizablePath.urlValue(value); + break; + default: + throw new RuntimeException("Unknown property: " + property); + } + } + + public String getProperty(final int property) { + switch (property) { + case PROGRAM_PARAMETERS_PROPERTY: + return PROGRAM_PARAMETERS; + case VM_PARAMETERS_PROPERTY: + return VM_PARAMETERS; + case WORKING_DIRECTORY_PROPERTY: + return getWorkingDirectory(); + default: + throw new RuntimeException("Unknown property: " + property); + } + } + + private String getWorkingDirectory() { + return ExternalizablePath.localPathValue(WORKING_DIRECTORY); + } + + public Collection getValidModules() { + return RunConfigurationModule.getModulesForClass(getProject(), MAIN_CLASS_NAME); + } + + protected ModuleBasedConfiguration createInstance() { + return new ApplicationConfiguration(getName(), getProject(), ApplicationConfigurationType.getInstance()); + } + + public void readExternal(final Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + readModule(element); + } + + public void writeExternal(final Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + writeModule(element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationProducer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationProducer.java new file mode 100644 index 00000000000..91db7b1d3f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationProducer.java @@ -0,0 +1,67 @@ +package com.intellij.execution.application; + +import com.intellij.execution.ConfigurationUtil; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.Location; +import com.intellij.execution.actions.ConfigurationContext; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.execution.junit.RuntimeConfigurationProducer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; + +public class ApplicationConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable { + private PsiElement myPsiElement = null; + public static final RuntimeConfigurationProducer PROTOTYPE = new ApplicationConfigurationProducer(); + + public ApplicationConfigurationProducer() { + super(ApplicationConfigurationType.getInstance()); + } + + public PsiElement getSourceElement() { + return myPsiElement; + } + + protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, final ConfigurationContext context) { + location = ExecutionUtil.stepIntoSingleClass(location); + final PsiElement element = location.getPsiElement(); + + PsiElement currentElement = element; + PsiMethod method; + while ((method = findMain(currentElement)) != null) { + final PsiClass aClass = method.getContainingClass(); + if (ConfigurationUtil.MAIN_CLASS.value(aClass)) { + myPsiElement = method; + return createConfiguration(aClass, context); + } + currentElement = method.getParent(); + } + final PsiClass aClass = ApplicationConfigurationType.getMainClass(element); + if (aClass == null) return null; + myPsiElement = aClass; + return createConfiguration(aClass, context); + } + + private RunnerAndConfigurationSettings createConfiguration(final PsiClass aClass, final ConfigurationContext context) { + final Project project = aClass.getProject(); + RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context); + final ApplicationConfiguration configuration = (ApplicationConfiguration)settings.getConfiguration(); + configuration.MAIN_CLASS_NAME = ExecutionUtil.getRuntimeQualifiedName(aClass); + configuration.setName(configuration.getGeneratedName()); + configuration.setModule(ExecutionUtil.findModule(aClass)); + return settings; + } + + private PsiMethod findMain(PsiElement element) { + PsiMethod method; + while ((method = getContainingMethod(element)) != null) + if (ApplicationConfigurationType.isMainMethod(method)) return method; + else element = method.getParent(); + return null; + } + + public int compareTo(final Object o) { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationType.java new file mode 100644 index 00000000000..3f3018f2869 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/application/ApplicationConfigurationType.java @@ -0,0 +1,121 @@ +package com.intellij.execution.application; + +import com.intellij.execution.ConfigurationTypeEx; +import com.intellij.execution.ConfigurationUtil; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.Location; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; + +import javax.swing.*; + +public class ApplicationConfigurationType implements ConfigurationTypeEx { + private final ConfigurationFactory myFactory; + private static final Icon ICON = IconLoader.getIcon("/runConfigurations/application.png"); + + /**reflection*/ + public ApplicationConfigurationType() { + myFactory = new ConfigurationFactory(this) { + public RunConfiguration createTemplateConfiguration(Project project) { + return new ApplicationConfiguration("", project, ApplicationConfigurationType.this); + } + + }; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "Application"; + } + + public String getConfigurationTypeDescription() { + return "Application configuration"; + } + + public Icon getIcon() { + return ICON; + } + + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[]{myFactory}; + } + + public RunnerAndConfigurationSettings createConfigurationByLocation(final Location location) { + return ApplicationConfigurationProducer.PROTOTYPE.createProducer(location, null).getConfiguration(); + } + + public boolean isConfigurationByElement(final RunConfiguration configuration, final Project project, final PsiElement element) { + final PsiClass aClass = getMainClass(element); + if (aClass == null) { + return false; + } + return Comparing.equal(ExecutionUtil.getRuntimeQualifiedName(aClass), ((ApplicationConfiguration)configuration).MAIN_CLASS_NAME); + } + + public static PsiClass getMainClass(PsiElement element) { + while (element != null) { + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + if (findMainInClass(aClass) != null){ + return aClass; + } + } + element = element.getParent(); + } + return null; + } + + + private static PsiMethod findMainInClass(final PsiClass aClass) { + if (!ConfigurationUtil.MAIN_CLASS.value(aClass)) return null; + return findMainMethod(aClass); + } + + public static PsiMethod findMainMethod(final PsiClass aClass) { + final PsiMethod[] mainMethods = aClass.findMethodsByName("main", false); + return findMainMethod(mainMethods); + } + + public static PsiMethod findMainMethod(final PsiMethod[] mainMethods) { + for (int i = 0; i < mainMethods.length; i++) { + final PsiMethod mainMethod = mainMethods[i]; + if (isMainMethod(mainMethod)) return mainMethod; + } + return null; + } + + public static boolean isMainMethod(final PsiMethod method) { + if (method == null) return false; + if (PsiType.VOID != method.getReturnType()) return false; + if (!method.hasModifierProperty(PsiModifier.STATIC)) return false; + if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return false; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 1) return false; + final PsiType type = parameters[0].getType(); + if (!(type instanceof PsiArrayType)) return false; + final PsiType componentType = ((PsiArrayType)type).getComponentType(); + final PsiElementFactory factory = method.getManager().getElementFactory(); + final PsiClassType stringType = factory.createType(factory.createReferenceElementByFQClassName("java.lang.String", method.getResolveScope())); + return stringType.equals(componentType); + } + + + public String getComponentName() { + return "Application"; + } + + public static ApplicationConfigurationType getInstance() { + return ApplicationManager.getApplication().getComponent(ApplicationConfigurationType.class); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/filters/TextConsoleBuilderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/filters/TextConsoleBuilderImpl.java new file mode 100644 index 00000000000..c4911f4a7a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/filters/TextConsoleBuilderImpl.java @@ -0,0 +1,34 @@ +package com.intellij.execution.filters; + +import com.intellij.execution.impl.ConsoleViewImpl; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author dyoma + */ +public class TextConsoleBuilderImpl extends TextConsoleBuilder { + private final Project myProject; + private final ArrayList myFilters = new ArrayList(); + + public TextConsoleBuilderImpl(final Project project) { + myProject = project; + } + + public ConsoleView getConsole() { + final ConsoleViewImpl consoleView = new ConsoleViewImpl(myProject); + for (Iterator iterator = myFilters.iterator(); iterator.hasNext();) { + final Filter filter = iterator.next(); + consoleView.addMessageFilter(filter); + } + return consoleView; + } + + public void addFilter(final Filter filter) { + myFilters.add(filter); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConfigurationSettingsEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConfigurationSettingsEditor.java new file mode 100644 index 00000000000..57e3ad48970 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConfigurationSettingsEditor.java @@ -0,0 +1,205 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.options.*; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.Pair; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.containers.Convertor; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author dyoma + */ +class ConfigurationSettingsEditor extends CompositeSettingsEditor { + private ArrayList> myRunnerEditors = new ArrayList>(); + private RunnersEditorComponent myRunnersComponent; + private RunConfiguration myConfiguration; + private final SettingsEditor myConfigurationEditor; + private SettingsEditorGroup myCompound; + private RunnerAndConfigurationSettings mySettings; + + public CompositeSettingsBuilder getBuilder() { + init(); + return new GroupSettingsBuilder(myCompound); + } + + private void init() { + if (myCompound == null) { + myCompound = new SettingsEditorGroup(); + if (myConfigurationEditor instanceof SettingsEditorGroup) { + SettingsEditorGroup group = (SettingsEditorGroup)myConfigurationEditor; + List>> editors = group.getEditors(); + for (int i = 0; i < editors.size(); i++) { + Pair> pair = editors.get(i); + myCompound.addEditor(pair.getFirst(), new ConfigToSettingsWrapper(pair.getSecond())); + } + } + else { + myCompound.addEditor("Configuration", new ConfigToSettingsWrapper(myConfigurationEditor)); + } + + + myRunnersComponent = new RunnersEditorComponent(); + JavaProgramRunner[] runners = ExecutionRegistry.getInstance().getRegisteredRunners(); + for (int i = 0; i < runners.length; i++) { + JavaProgramRunner runner = runners[i]; + JComponent perRunnerSettings = createCompositePerRunnerSettings(runner); + if (perRunnerSettings != null) { + myRunnersComponent.addRunnerComponent(runner, perRunnerSettings); + } + } + + if (myRunnerEditors.size() > 0) { + myCompound.addEditor("Startup/Connection", new CompositeSettingsEditor(getFactory()) { + public CompositeSettingsBuilder getBuilder() { + return new CompositeSettingsBuilder() { + public Collection> getEditors() { + return myRunnerEditors; + } + + public JComponent createCompoundEditor() { + return myRunnersComponent.getComponent(); + } + }; + } + }); + } + } + } + + private JComponent createCompositePerRunnerSettings(final JavaProgramRunner runner) { + final SettingsEditor configEditor = myConfiguration.getRunnerSettingsEditor(runner); + SettingsEditor runnerEditor; + + try { + runnerEditor = runner.getSettingsEditor(myConfiguration); + } catch(AbstractMethodError error) { + // this is stub code for plugin copatibility! + runnerEditor = null; + } + + if (configEditor == null && runnerEditor == null) return null; + SettingsEditor wrappedConfigEditor = null; + SettingsEditor wrappedRunEditor = null; + if (configEditor != null) { + wrappedConfigEditor = new SettingsEditorWrapper(configEditor, new Convertor() { + public JDOMExternalizable convert(RunnerAndConfigurationSettings configurationSettings) { + return configurationSettings.getConfigurationSettings(runner).getSettings(); + } + }); + myRunnerEditors.add(wrappedConfigEditor); + } + + if (runnerEditor != null) { + wrappedRunEditor = new SettingsEditorWrapper(runnerEditor, new Convertor(){ + public JDOMExternalizable convert(RunnerAndConfigurationSettings configurationSettings) { + return configurationSettings.getRunnerSettings(runner).getData(); + } + }); + myRunnerEditors.add(wrappedRunEditor); + } + + if (wrappedRunEditor != null && wrappedConfigEditor != null) { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(wrappedConfigEditor.getComponent(), BorderLayout.CENTER); + panel.add(wrappedRunEditor.getComponent(), BorderLayout.SOUTH); + return panel; + } + + if (wrappedRunEditor != null) return wrappedRunEditor.getComponent(); + return wrappedConfigEditor.getComponent(); + } + + public ConfigurationSettingsEditor(RunnerAndConfigurationSettings settings) { + super(settings.createFactory()); + myConfigurationEditor = (SettingsEditor)settings.getConfiguration().getConfigurationEditor(); + mySettings = settings; + myConfiguration = mySettings.getConfiguration(); + } + + private static class RunnersEditorComponent { + private static final String NO_RUNNER_COMPONENT = ""; + + private JList myRunnersList; + private JPanel myRunnerPanel; + private final CardLayout myLayout = new CardLayout(); + private final DefaultListModel myListModel = new DefaultListModel(); + private final JLabel myNoRunner = new JLabel("No runner selected"); + private JPanel myRunnersPanel; + + public RunnersEditorComponent() { + myRunnerPanel.setLayout(myLayout); + myRunnerPanel.add(myNoRunner, NO_RUNNER_COMPONENT); + myRunnersList.setModel(myListModel); + myRunnersList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateRunnerComponent(); + } + }); + updateRunnerComponent(); + myRunnersList.setCellRenderer(new ColoredListCellRenderer() { + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + JavaProgramRunner runner = (JavaProgramRunner)value; + RunnerInfo info = runner.getInfo(); + setIcon(info.getIcon()); + append(info.getId(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + }); + } + + private void updateRunnerComponent() { + JavaProgramRunner runner = (JavaProgramRunner)myRunnersList.getSelectedValue(); + myLayout.show(myRunnerPanel, runner != null ? runner.getInfo().getId() : NO_RUNNER_COMPONENT); + myRunnersPanel.revalidate(); + } + + public void addRunnerComponent(JavaProgramRunner runner, JComponent component) { + myRunnerPanel.add(component, runner.getInfo().getId()); + myListModel.addElement(runner); + ListScrollingUtil.ensureSelectionExists(myRunnersList); + } + + public JComponent getComponent() { + return myRunnersPanel; + } + } + + private class ConfigToSettingsWrapper extends SettingsEditor { + private final SettingsEditor myConfigEditor; + + public ConfigToSettingsWrapper(SettingsEditor configEditor) { + myConfigEditor = configEditor; + } + + public void resetEditorFrom(RunnerAndConfigurationSettings configurationSettings) { + myConfigEditor.resetFrom(configurationSettings.getConfiguration()); + } + + public void applyEditorTo(RunnerAndConfigurationSettings configurationSettings) throws ConfigurationException { + myConfigEditor.applyTo(configurationSettings.getConfiguration()); + } + + public JComponent createEditor() { + return myConfigEditor.getComponent(); + } + + public void disposeEditor() { + myConfigEditor.dispose(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleState.java new file mode 100644 index 00000000000..c31b660ec51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleState.java @@ -0,0 +1,86 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.application.ApplicationManager; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +public abstract class ConsoleState { + public static final ConsoleState NOT_STARTED = new ConsoleState(){ + public ConsoleState attachTo(final ConsoleViewImpl console, final ProcessHandler processHandler) { + return new RunningState(console, processHandler); + } + }; + + public ConsoleState dispose() { + return NOT_STARTED; + } + + public boolean isFinished() { + return false; + } + + public boolean isRunning() { + return false; + } + + public void sendUserInput(final String input) throws IOException {} + + public abstract ConsoleState attachTo(ConsoleViewImpl console, ProcessHandler processHandler); + + private static class RunningState extends ConsoleState { + private final ConsoleViewImpl myConsole; + private final ProcessAdapter myProcessListener = new ProcessAdapter() { + public void onTextAvailable(final ProcessEvent event, final Key outputType) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myConsole.print(event.getText(), ConsoleViewContentType.getConsoleViewType(outputType)); + } + }); + } + }; + private final ProcessHandler myProcessHandler; + private final Writer myUserInputWriter; + + public RunningState(final ConsoleViewImpl console, final ProcessHandler processHandler) { + myConsole = console; + myProcessHandler = processHandler; + processHandler.addProcessListener(myProcessListener); + final OutputStream processInput = myProcessHandler.getProcessInput(); + myUserInputWriter = processInput != null ? new OutputStreamWriter(processInput) : null; + } + + public ConsoleState dispose() { + if (myProcessHandler != null) { + myProcessHandler.removeProcessListener(myProcessListener); + } + return NOT_STARTED; + } + + public boolean isFinished() { + return myProcessHandler == null || myProcessHandler.isProcessTerminated(); + } + + public boolean isRunning() { + return myProcessHandler != null && !myProcessHandler.isProcessTerminated(); + } + + public void sendUserInput(final String input) throws IOException { + if (myUserInputWriter == null) + throw new IOException("No process input"); + myUserInputWriter.write(input); + myUserInputWriter.flush(); + } + + public ConsoleState attachTo(final ConsoleViewImpl console, final ProcessHandler processHandler) { + return dispose().attachTo(console, processHandler); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleViewImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleViewImpl.java new file mode 100644 index 00000000000..05dfdb0cc3d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ConsoleViewImpl.java @@ -0,0 +1,740 @@ +package com.intellij.execution.impl; + +import com.intellij.codeInsight.CodeInsightColors; +import com.intellij.execution.filters.*; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.ide.macro.DataAccessor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.actions.DiffActions; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.TypedAction; +import com.intellij.openapi.editor.actionSystem.TypedActionHandler; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.EditorMouseAdapter; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.Alarm; +import com.intellij.util.EditorPopupHandler; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public final class ConsoleViewImpl extends JPanel implements ConsoleView, DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.ConsoleViewImpl"); + + private static final int FLUSH_DELAY = 200; //TODO : make it an option + + private static final Key CONSOLE_VIEW_IN_EDITOR_VIEW = Key.create("CONSOLE_VIEW_IN_EDITOR_VIEW"); + static { + final EditorActionManager actionManager = EditorActionManager.getInstance(); + final TypedAction typedAction = actionManager.getTypedAction(); + typedAction.setupHandler(new MyTypedHandler(typedAction.getHandler())); + } + + private static final Color BACKGROUND_COLOR = Color.white; + private static final TextAttributes HYPERLINK_ATTRIBUTES = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES); + + private final DisposedPsiManagerCheck myPsiDisposedCheck; + private ConsoleState myState = ConsoleState.NOT_STARTED; + + private static class TokenInfo{ + final ConsoleViewContentType contentType; + final int startOffset; + int endOffset; + final TextAttributes attributes; + + public TokenInfo(final ConsoleViewContentType contentType, final int startOffset, final int endOffset) { + this.contentType = contentType; + this.startOffset = startOffset; + this.endOffset = endOffset; + attributes = contentType.getAttributes(); + } + } + + private final Project myProject; + + private boolean myOutputPaused; + + private Editor myEditor; + + private Object LOCK = new Object(); + + private int myContentSize; + private StringBuffer myDeferredOutput = new StringBuffer(); + private StringBuffer myDeferredUserInput = new StringBuffer(); + + private ArrayList myTokens = new ArrayList(); + private final Hyperlinks myHyperlinks = new Hyperlinks(); + + private String myHelpId; + + private Alarm myFlushAlarm = new Alarm(); + + private final Runnable myFlushDeferredRunnable = new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + flushDeferredText(); + } + }; + + private CompositeFilter myMessageFilter = new CompositeFilter(); + + public ConsoleViewImpl(final Project project) { + super(new BorderLayout()); + myPsiDisposedCheck = new DisposedPsiManagerCheck(project); + myProject = project; + + addMessageFilter(new ExceptionFilter(myProject));//TEMP! + } + + public void attachToProcess(final ProcessHandler processHandler){ + myState = myState.attachTo(this, processHandler); + } + + public void clear() { + assertIsDispatchThread(); + + synchronized(LOCK){ + myContentSize = 0; + myDeferredOutput.setLength(0); + myDeferredUserInput.setLength(0); + if (myEditor != null){ + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myHyperlinks.clear(); + myEditor.getMarkupModel().removeAllHighlighters(); + myTokens.clear(); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + myEditor.getDocument().deleteString(0, myEditor.getDocument().getTextLength()); + } + }, null, null); + } + }); + } + } + } + + public void scrollTo(final int offset) { + assertIsDispatchThread(); + if (myEditor == null) return; + if (myState.isFinished() && !hasDeferredOutput()) { + myEditor.getCaretModel().moveToOffset(offset); + myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + } else + myEditor.getScrollingModel().scrollTo(myEditor.offsetToLogicalPosition(offset), ScrollType.MAKE_VISIBLE); + } + + private void assertIsDispatchThread() { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + } + + public void setOutputPaused(final boolean value) { + myOutputPaused = value; + if (!value){ + requestFlushImmediately(); + } + } + + public boolean isOutputPaused() { + return myOutputPaused; + } + + public boolean hasDeferredOutput() { + synchronized(LOCK){ + return myDeferredOutput.length() > 0; + } + } + + public void performWhenNoDeferredOutput(final Runnable runnable) { + //Q: implement in another way without timer? + if (!hasDeferredOutput()){ + runnable.run(); + } + else{ + new Alarm().addRequest( + new Runnable() { + public void run() { + performWhenNoDeferredOutput(runnable); + } + }, + 100 + ); + } + } + + public JComponent getComponent() { + if (myEditor == null){ + myEditor = createEditor(); + requestFlushImmediately(); + add(myEditor.getComponent(), BorderLayout.CENTER); + } + return this; + } + + public void dispose(){ + myState = myState.dispose(); + if (myEditor != null){ + myFlushAlarm.cancelAllRequests(); + EditorFactory.getInstance().releaseEditor(myEditor); + synchronized (LOCK) { + myDeferredOutput.setLength(0); + } + myEditor = null; + } + } + + public void print(String s, final ConsoleViewContentType contentType) { + synchronized(LOCK){ + s = StringUtil.convertLineSeparators(s, "\n"); + myContentSize += s.length(); + myDeferredOutput.append(s); + if (contentType == ConsoleViewContentType.USER_INPUT){ + myDeferredUserInput.append(s); + } + + boolean needNew = true; + if (!myTokens.isEmpty()){ + final TokenInfo lastToken = myTokens.get(myTokens.size() - 1); + if (lastToken.contentType == contentType){ + lastToken.endOffset = myContentSize; // optimization + needNew = false; + } + } + if (needNew){ + myTokens.add(new TokenInfo(contentType, myContentSize - s.length(), myContentSize)); + } + } + + if (s.indexOf('\n') >= 0 || s.indexOf('\r') >= 0){ + if (contentType == ConsoleViewContentType.USER_INPUT){ + flushDeferredUserInput(); + } + } + final Runnable requestFlush = new Runnable() { + public void run() { + if (myFlushAlarm.getActiveRequestCount() == 0) { + myFlushAlarm.addRequest(myFlushDeferredRunnable, FLUSH_DELAY); + } + } + }; + if (EventQueue.isDispatchThread()) requestFlush.run(); + else SwingUtilities.invokeLater(requestFlush); + } + + private void requestFlushImmediately() { + myFlushAlarm.addRequest(new Runnable() { + public void run() { + flushDeferredText(); + } + }, 0); + } + + public int getContentSize() { return myContentSize; } + + public boolean canPause() { + return true; + } + + private void flushDeferredText(){ + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + + synchronized(LOCK){ + if (myOutputPaused) return; + if (myDeferredOutput.length() == 0) return; + } + + if (myEditor != null) { + final String text = myDeferredOutput.substring(0, myDeferredOutput.length()); + myDeferredOutput.setLength(0); + final Document document = myEditor.getDocument(); + final int oldLineCount = document.getLineCount(); + final boolean isAtEndOfDocument = myEditor.getCaretModel().getOffset() == myEditor.getDocument().getTextLength(); + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + document.insertString(document.getTextLength(), text); + } + }, null, null); + } + } + ); + final int newLineCount = document.getLineCount(); + if (oldLineCount < newLineCount){ + myPsiDisposedCheck.performCheck(); + highlightHyperlinks(oldLineCount - 1, newLineCount - 2); + } + + if (isAtEndOfDocument) { + myEditor.getCaretModel().moveToOffset(myEditor.getDocument().getTextLength()); + myEditor.getSelectionModel().removeSelection(); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + } + } + + private void flushDeferredUserInput() { + if (myState.isRunning()){ + synchronized(LOCK){ + final String text = myDeferredUserInput.substring(0, myDeferredUserInput.length()); + final int index = Math.max(text.lastIndexOf('\n'), text.lastIndexOf('\r')); + if (index < 0) return; + try{ + myState.sendUserInput(text.substring(0, index + 1)); + } + catch(IOException e){ + return; + } + myDeferredUserInput.setLength(0); + myDeferredUserInput.append(text.substring(index + 1)); + } + } + } + + public Object getData(final String dataId) { + if (DataConstants.NAVIGATABLE.equals(dataId)){ + if (myEditor == null) { + return null; + } + final LogicalPosition pos = myEditor.getCaretModel().getLogicalPosition(); + final HyperlinkInfo info = getHyperlinkInfoByLineAndCol(pos.line, pos.column); + return info instanceof OpenFileHyperlinkInfo ? ((OpenFileHyperlinkInfo)info).getDescriptor() : null; + } + + if (DataConstants.EDITOR.equals(dataId)) { + return myEditor; + } + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return myHelpId; + } + return null; + } + + public void setHelpId(final String helpId) { + myHelpId = helpId; + } + + public void addMessageFilter(final Filter filter) { + myMessageFilter.addFilter(filter); + } + + public void printHyperlink(final String hyperlinkText, final HyperlinkInfo info) { + if (myEditor == null) return; + print(hyperlinkText, ConsoleViewContentType.NORMAL_OUTPUT); + flushDeferredText(); + final int textLength = myEditor.getDocument().getTextLength(); + addHyperlink(textLength - hyperlinkText.length(), textLength, info); + } + + private Editor createEditor() { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Editor compute() { + final EditorFactory editorFactory = EditorFactory.getInstance(); + final Document editorDocument = editorFactory.createDocument(""); + final EditorEx editor = (EditorEx) editorFactory.createViewer(editorDocument,myProject); + final Highlighter highlighter = new MyHighghlighter(); + editor.setHighlighter(highlighter); + editor.putUserData(CONSOLE_VIEW_IN_EDITOR_VIEW, ConsoleViewImpl.this); + + final EditorSettings editorSettings = editor.getSettings(); + editorSettings.setLineMarkerAreaShown(false); + editorSettings.setLineNumbersShown(false); + editorSettings.setFoldingOutlineShown(false); + editorSettings.setAdditionalPageAtBottom(false); + + final EditorColorsScheme scheme = editor.getColorsScheme(); + scheme.setColor(EditorColors.BACKGROUND_COLOR, BACKGROUND_COLOR); + scheme.setColor(EditorColors.READONLY_BACKGROUND_COLOR, BACKGROUND_COLOR); + scheme.setColor(EditorColors.CARET_ROW_COLOR, null); + scheme.setColor(EditorColors.RIGHT_MARGIN_COLOR, null); + + + editor.addEditorMouseListener(new EditorPopupHandler(){ + public void invokePopup(final EditorMouseEvent event) { + final MouseEvent mouseEvent = event.getMouseEvent(); + popupInvoked(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); + } + }); + + editor.addEditorMouseListener( + new EditorMouseAdapter(){ + public void mouseReleased(final EditorMouseEvent e){ + final MouseEvent mouseEvent = e.getMouseEvent(); + if (!mouseEvent.isPopupTrigger()){ + navigate(e); + } + } + } + ); + + editor.getContentComponent().addMouseMotionListener( + new MouseMotionAdapter(){ + public void mouseMoved(final MouseEvent e){ + final HyperlinkInfo info = getHyperlinkInfoByPoint(e.getPoint()); + if (info != null){ + editor.getContentComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else{ + editor.getContentComponent().setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } + } + } + ); + + setEditorUpActions(editor); + + return editor; + } + }); + } + + private void setEditorUpActions(final Editor editor) { + new EnterHandler().registerCustomShortcutSet(CommonShortcuts.ENTER, editor.getContentComponent()); + registerActionHandler(editor, IdeActions.ACTION_EDITOR_PASTE, new PasteHandler()); + registerActionHandler(editor, IdeActions.ACTION_EDITOR_BACKSPACE, new BackSpaceHandler()); + } + + private void registerActionHandler(final Editor editor, final String actionId, final AnAction action) { + final Keymap keymap=KeymapManager.getInstance().getActiveKeymap(); + final Shortcut[] shortcuts = keymap.getShortcuts(actionId); + action.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), editor.getContentComponent()); + } + + private void popupInvoked(final Component component, final int x, final int y){ + final DefaultActionGroup group = new DefaultActionGroup(); + group.add(new ClearAllAction()); + group.add(new CopyAction()); + group.addSeparator(); + final ActionManager actionManager = ActionManager.getInstance(); + group.add(actionManager.getAction(DiffActions.COMPARE_WITH_CLIPBOARD)); + final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group); + menu.getComponent().show(component, x, y); + } + + private void navigate(final EditorMouseEvent event){ + if (event.getMouseEvent().isPopupTrigger()) return; + final Point p = event.getMouseEvent().getPoint(); + final HyperlinkInfo info = getHyperlinkInfoByPoint(p); + if (info != null){ + info.navigate(myProject); + } + } + + private HyperlinkInfo getHyperlinkInfoByPoint(final Point p){ + final LogicalPosition pos = myEditor.xyToLogicalPosition(new Point(p.x, p.y)); + return getHyperlinkInfoByLineAndCol(pos.line, pos.column); + } + + private HyperlinkInfo getHyperlinkInfoByLineAndCol(final int line, final int col) { + final int offset = myEditor.logicalPositionToOffset(new LogicalPosition(line, col)); + return myHyperlinks.getHyperlinkAt(offset); + } + + private void highlightHyperlinks(final int line1, final int line2){ + if (myMessageFilter != null){ + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + final Document document = myEditor.getDocument(); + final CharSequence chars = document.getCharsSequence(); + for(int line = line1; line <= line2; line++){ + if (line < 0) continue; + final int startOffset = document.getLineStartOffset(line); + int endOffset = document.getLineEndOffset(line); + if (endOffset < document.getTextLength()){ + endOffset++; // add '\n' + } + final String text = chars.subSequence(startOffset, endOffset).toString(); + final Filter.Result result = myMessageFilter.applyFilter(text, endOffset); + if (result != null){ + final int highlightStartOffset = result.highlightStartOffset; + final int highlightEndOffset = result.highlightEndOffset; + final HyperlinkInfo hyperlinkInfo = result.hyperlinkInfo; + addHyperlink(highlightStartOffset, highlightEndOffset, hyperlinkInfo); + } + } + } + } + + private void addHyperlink(final int highlightStartOffset, final int highlightEndOffset, final HyperlinkInfo hyperlinkInfo) { + final RangeHighlighter highlighter = myEditor.getMarkupModel().addRangeHighlighter(highlightStartOffset, + highlightEndOffset, + HighlighterLayer.SELECTION - 1, + HYPERLINK_ATTRIBUTES, + HighlighterTargetArea.EXACT_RANGE); + myHyperlinks.add(highlighter, hyperlinkInfo); + } + + private class ClearAllAction extends AnAction{ + public ClearAllAction(){ + super("Clear All"); + } + + public void actionPerformed(final AnActionEvent e){ + clear(); + } + } + + private class CopyAction extends AnAction{ + public CopyAction(){ + super(myEditor.getSelectionModel().hasSelection() ? "Copy Selected Content" : "Copy Content"); + } + + public void actionPerformed(final AnActionEvent e){ + if (myEditor.getSelectionModel().hasSelection()){ + myEditor.getSelectionModel().copySelectionToClipboard(); + } + else{ + myEditor.getSelectionModel().setSelection(0, myEditor.getDocument().getTextLength()); + myEditor.getSelectionModel().copySelectionToClipboard(); + myEditor.getSelectionModel().removeSelection(); + } + } + } + + private class MyHighghlighter extends DocumentAdapter implements Highlighter { + private boolean myHasEditor; + + public HighlighterIterator createIterator(final int startOffset) { + final int startIndex = findTokenInfoByOffset(myTokens, startOffset); + + return new HighlighterIterator(){ + private int myIndex = startIndex; + + public TextAttributes getTextAttributes() { + return getTokenInfo().attributes; + } + + public int getStart() { + return getTokenInfo().startOffset; + } + + public int getEnd() { + return getTokenInfo().endOffset; + } + + public IElementType getTokenType() { + return null; + } + + public void advance() { + myIndex++; + } + + public void retreat() { + myIndex--; + } + + public boolean atEnd() { + return myIndex < 0 || myIndex >= myTokens.size(); + } + + private TokenInfo getTokenInfo() { + return myTokens.get(myIndex); + } + }; + } + + public void setText(final CharSequence text) { + } + + public void setEditor(final Editor editor) { + LOG.assertTrue(!myHasEditor, "Highlighters cannot be reused with different editors"); + myHasEditor = true; + } + + public void setColorScheme(EditorColorsScheme scheme) { + } + } + + private static int findTokenInfoByOffset(final ArrayList tokens, final int offset) { + int low = 0; + int high = tokens.size() - 1; + + while(low <= high){ + final int mid = (low + high) / 2; + final TokenInfo midVal = tokens.get(mid); + if (offset < midVal.startOffset){ + high = mid - 1; + } + else if (offset >= midVal.endOffset){ + low = mid + 1; + } + else{ + return mid; + } + } + return tokens.size(); + } + + private static class MyTypedHandler implements TypedActionHandler { + private TypedActionHandler myOriginalHandler; + + public MyTypedHandler(final TypedActionHandler originalAction) { + myOriginalHandler = originalAction; + } + + public void execute(final Editor editor, final char charTyped, final DataContext dataContext) { + final ConsoleViewImpl consoleView = editor.getUserData(CONSOLE_VIEW_IN_EDITOR_VIEW); + if (consoleView == null || !consoleView.myState.isRunning()){ + myOriginalHandler.execute(editor, charTyped, dataContext); + } + else{ + final String s = String.valueOf(charTyped); + consoleView.print(s, ConsoleViewContentType.USER_INPUT); + consoleView.flushDeferredText(); + } + } + } + + private static final DataAccessor CONSOLE = new DataAccessor() { + public ConsoleViewImpl getImpl(final DataContext dataContext) throws NoDataException { + return EDITOR.getNotNull(dataContext).getUserData(CONSOLE_VIEW_IN_EDITOR_VIEW); + } + }; + + private static final Condition CONSOLE_IS_RUNNING = new Condition() { + public boolean value(final ConsoleViewImpl consoleView) { + return consoleView.myState.isRunning(); + } + }; + + private static final DataAccessor RUNNINT_CONSOLE =DataAccessor.createConditionalAccessor(CONSOLE, CONSOLE_IS_RUNNING); + + private static abstract class ConsoleAction extends AnAction { + public void actionPerformed(final AnActionEvent e) { + final ConsoleViewImpl console = RUNNINT_CONSOLE.from(e.getDataContext()); + execute(console); + } + + protected abstract void execute(ConsoleViewImpl console); + + public void update(final AnActionEvent e) { + final ConsoleViewImpl console = RUNNINT_CONSOLE.from(e.getDataContext()); + e.getPresentation().setEnabled(console != null); + } + } + + private static class EnterHandler extends ConsoleAction { + public void execute(final ConsoleViewImpl consoleView) { + consoleView.print("\n", ConsoleViewContentType.USER_INPUT); + consoleView.flushDeferredText(); + } + } + + private static class PasteHandler extends ConsoleAction { + public void execute(final ConsoleViewImpl consoleView) { + final Transferable content = CopyPasteManager.getInstance().getContents(); + if (content == null) return; + String s = null; + try { + s = (String)content.getTransferData(DataFlavor.stringFlavor); + } + catch(Exception e) { + consoleView.myEditor.getComponent().getToolkit().beep(); + } + if (s == null) return; + consoleView.print(s, ConsoleViewContentType.USER_INPUT); + consoleView.flushDeferredText(); + } + } + + private static class BackSpaceHandler extends ConsoleAction { + public void execute(final ConsoleViewImpl consoleView) { + final Editor editor = consoleView.myEditor; + final Document document = editor.getDocument(); + final int length = document.getTextLength(); + if (length == 0) return; + + synchronized(consoleView.LOCK){ + if (consoleView.myTokens.size() == 0) return; + final TokenInfo info = consoleView.myTokens.get(consoleView.myTokens.size() - 1); + if (info.contentType != ConsoleViewContentType.USER_INPUT) return; + if (consoleView.myDeferredUserInput.length() == 0) return; + + consoleView.myDeferredUserInput.setLength(consoleView.myDeferredUserInput.length() - 1); + info.endOffset -= 1; + if (info.startOffset == info.endOffset){ + consoleView.myTokens.remove(consoleView.myTokens.size() - 1); + } + consoleView.myContentSize--; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + document.deleteString(length - 1, length); + editor.getCaretModel().moveToOffset(length - 1); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } + }); + } + } + + private static class Hyperlinks { + private static final int NO_INDEX = Integer.MIN_VALUE; + private final Map myHighlighterToMessageInfoMap = new HashMap(); + private int myLastIndex = NO_INDEX; + + public void clear() { + myHighlighterToMessageInfoMap.clear(); + myLastIndex = NO_INDEX; + } + + public HyperlinkInfo getHyperlinkAt(final int offset) { + final Iterator iterator = myHighlighterToMessageInfoMap.keySet().iterator(); + while(iterator.hasNext()){ + final RangeHighlighter highlighter = iterator.next(); + if (containsOffset(offset, highlighter)){ + return myHighlighterToMessageInfoMap.get(highlighter); + } + } + return null; + } + + private boolean containsOffset(final int offset, final RangeHighlighter highlighter) { + return highlighter.getStartOffset() <= offset && offset <= highlighter.getEndOffset(); + } + + public void add(final RangeHighlighter highlighter, final HyperlinkInfo hyperlinkInfo) { + myHighlighterToMessageInfoMap.put(highlighter, hyperlinkInfo); + if (myLastIndex != NO_INDEX && containsOffset(myLastIndex, highlighter)) myLastIndex = NO_INDEX; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/DisposedPsiManagerCheck.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/DisposedPsiManagerCheck.java new file mode 100644 index 00000000000..1745d7e6dc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/DisposedPsiManagerCheck.java @@ -0,0 +1,33 @@ +package com.intellij.execution.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiManager; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class DisposedPsiManagerCheck { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.DisposedPsiManagerCheck"); + private final Throwable myAllocationPlace; + private final Project myProject; + + public DisposedPsiManagerCheck(final Project project) { + myProject = project; + myAllocationPlace = new Throwable(); + } + + public void performCheck() { + final PsiManager psiManager = PsiManager.getInstance(myProject); + if (psiManager == null) log("Is null"); + else if (psiManager.isDisposed()) log("Disposed"); + } + + private void log(final String message) { + final StringWriter stringWriter = new StringWriter(); + final PrintWriter writer = new PrintWriter(stringWriter); + myAllocationPlace.printStackTrace(writer); + LOG.error(message + "\n" + stringWriter.toString()); + writer.close(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/EditConfigurationsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/EditConfigurationsDialog.java new file mode 100644 index 00000000000..e46443de95b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/EditConfigurationsDialog.java @@ -0,0 +1,29 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.RunManager; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; + +public class EditConfigurationsDialog extends SingleConfigurableEditor { + private RunConfigurable myConfigurable; + + public EditConfigurationsDialog(final Project project) { + super(project, new RunConfigurable(project)); + myConfigurable = (RunConfigurable)getConfigurable(); + setTitle("Run/Debug Configurations"); + } + + protected void doOKAction() { + super.doOKAction(); + RunManager.getInstance(getProject()).setActiveConfigurationFactory(myConfigurable.getSelectedConfigType()); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("project.propRunDebug"); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.execution.impl.EditConfigurationsDialog"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionManagerImpl.java new file mode 100644 index 00000000000..75295ba18ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -0,0 +1,136 @@ +package com.intellij.execution.impl; + +import com.intellij.ant.AntConfiguration; +import com.intellij.ant.impl.MapDataContext; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunManagerConfig; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.execution.ui.RunContentManagerImpl; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompileStatusNotification; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dyoma + */ +public class ExecutionManagerImpl extends ExecutionManager implements ProjectComponent { + private final Project myProject; + + private RunContentManagerImpl myContentManager; + + /** + * reflection + */ + ExecutionManagerImpl(final Project project) { + myProject = project; + } + + public void projectOpened() { + ((RunContentManagerImpl)getContentManager()).init(); + } + + public void projectClosed() { + myContentManager.dispose(); + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public RunContentManager getContentManager() { + if (myContentManager == null) { + myContentManager = new RunContentManagerImpl(myProject); + } + return myContentManager; + } + + public ProcessHandler[] getRunningProcesses() { + final List handlers = new ArrayList(); + RunContentDescriptor[] descriptors = myContentManager.getAllDescriptors(); + for (int q = 0; q < descriptors.length; q++) { + RunContentDescriptor descriptor = descriptors[q]; + if (descriptor != null) { + final ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null) { + handlers.add(processHandler); + } + } + } + return handlers.toArray(new ProcessHandler[handlers.size()]); + } + + public void compileAndRun(final Runnable startRunnable, + final RunProfile configuration, + final RunProfileState state) { + final Runnable antAwareRunnable = new Runnable() { + public void run() { + final AntConfiguration antConfiguration = AntConfiguration.getInstance(myProject); + if ((configuration instanceof RunConfiguration) && + antConfiguration.hasTasksToExecuteBeforeRun((RunConfiguration)configuration)) { + final Thread thread = new Thread(new Runnable() { + public void run() { + final DataContext dataContext = MapDataContext.singleData(DataConstants.PROJECT, myProject); + final boolean result = antConfiguration.executeTaskBeforeRun(dataContext, (RunConfiguration)configuration); + if (result) { + ApplicationManager.getApplication().invokeLater(startRunnable); + } + } + }); + thread.start(); + } + else { + startRunnable.run(); + } + } + }; + Module[] modulesToCompile = state.getModulesToCompile(); + if (modulesToCompile == null) modulesToCompile = Module.EMPTY_ARRAY; + if (getConfig().isCompileBeforeRunning() && modulesToCompile.length > 0) { + final CompileStatusNotification callback = new CompileStatusNotification() { + public void finished(final boolean aborted, final int errors, final int warnings) { + if (errors == 0 && !aborted) { + ApplicationManager.getApplication().invokeLater(antAwareRunnable); + } + } + }; + if ("true".equals(System.getProperty("makeProjectOnRun", "false"))) { + // user explicitly requested whole-project make + CompilerManager.getInstance(myProject).make(callback); + } + else { + if (modulesToCompile.length > 0) { + CompilerManager.getInstance(myProject).make(myProject, modulesToCompile, callback); + } + else { + CompilerManager.getInstance(myProject).make(callback); + } + } + } + else { + antAwareRunnable.run(); + } + } + + private RunManagerConfig getConfig() { + return RunManager.getInstance(myProject).getConfig(); + } + + public String getComponentName() { + return "ExecutionManager"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionRegistryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionRegistryImpl.java new file mode 100644 index 00000000000..577a60fe1f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ExecutionRegistryImpl.java @@ -0,0 +1,186 @@ +package com.intellij.execution.impl; + +import com.intellij.debugger.impl.GenericDebuggerRunner; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.actions.RunContextAction; +import com.intellij.execution.actions.RunnerAction; +import com.intellij.execution.configurations.*; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.util.EventDispatcher; + +import java.util.*; + + +public class ExecutionRegistryImpl extends ExecutionRegistry { + private final EventDispatcher myListeners = EventDispatcher.create(Listener.class); + private final List myRunnersOrder = new ArrayList(); + private JavaProgramRunner myDefaultRunner; + private JavaProgramRunner myDebuggerRunner; + public static final String RUN_CONTEXT_GROUP = "RunContextGroup"; + public static final String RUNNERS_GROUP = "RunnerActions"; + private ActionManager myActionManager; + + public ExecutionRegistryImpl(ActionManager actionManager) { + myActionManager = actionManager; + + // default runners + addListener(new BaseRunnerActionListener(RUNNERS_GROUP) { + protected String getActionId(final JavaProgramRunner runner) { + return runner.getInfo().getRunActionId(); + } + + protected AnAction createActionFor(final JavaProgramRunner runner) { + return new RunnerAction(runner); + } + }); + addListener(new BaseRunnerActionListener(RUN_CONTEXT_GROUP) { + protected String getActionId(final JavaProgramRunner runner) { + return runner.getInfo().getRunContextActionId(); + } + + protected AnAction createActionFor(final JavaProgramRunner runner) { + return new RunContextAction(runner); + } + }); + + myDefaultRunner = new DefaultJavaProgramRunner(); + myDebuggerRunner = new GenericDebuggerRunner(); + + registerRunner(myDefaultRunner); + registerRunner(myDebuggerRunner); + } + + public String getComponentName() { + return "ExecutionRegistryImpl"; + } + + public void initComponent() { } + + public synchronized void disposeComponent() { + while (myRunnersOrder.size() > 0) { + final JavaProgramRunner runner = myRunnersOrder.get(myRunnersOrder.size() - 1); + unregisterRunner(runner); + } + myListeners.getMulticaster().onRegisteryDisposed(this); + } + + public void addListener(final Listener listener) { + myListeners.addListener(listener); + } + + public void removeListener(final Listener listener) { + myListeners.removeListener(listener); + } + + public synchronized void registerRunner(final JavaProgramRunner runner) { + if (myRunnersOrder.contains(runner)) return; + myRunnersOrder.add(runner); + myListeners.getMulticaster().onRunnerRegistered(runner); + } + + public synchronized void unregisterRunner(final JavaProgramRunner runner) { + if (!myRunnersOrder.remove(runner)) return; + if (runner == myDefaultRunner) myDefaultRunner = null; + myListeners.getMulticaster().onRunnerUnregistered(runner); + } + + public JavaProgramRunner getDefaultRunner() { + return myDefaultRunner; + } + + public JavaProgramRunner getDebuggerRunner() { + return myDebuggerRunner; + } + + public synchronized JavaProgramRunner[] getRegisteredRunners() { + return myRunnersOrder.toArray(new JavaProgramRunner[myRunnersOrder.size()]); + } + + public interface Listener extends EventListener { + void onRunnerRegistered(JavaProgramRunner runner); + + void onRunnerUnregistered(JavaProgramRunner runner); + + void onRegisteryDisposed(ExecutionRegistryImpl registry); + } + + private abstract class BaseRunnerActionListener implements Listener { + private final Set myRunnersWithActions = new HashSet(); + private final DefaultActionGroup myActionGroup; + + protected BaseRunnerActionListener(final String groupId) { + myActionGroup = (DefaultActionGroup)myActionManager.getAction(groupId); + } + + public void onRegisteryDisposed(final ExecutionRegistryImpl registry) { + registry.removeListener(this); + } + + public void onRunnerRegistered(final JavaProgramRunner runner) { + final String actionId = getActionId(runner); + final ActionManager actionManager = myActionManager; + AnAction action = actionManager.getAction(actionId); + if (action == null) { + action = createActionFor(runner); + myRunnersWithActions.add(runner); + actionManager.registerAction(actionId, action); + } + myActionGroup.add(action); + } + + public void onRunnerUnregistered(final JavaProgramRunner runner) { + final ActionManager actionManager = myActionManager; + final String actionId = getActionId(runner); + myActionGroup.remove(actionManager.getAction(actionId)); + if (!myRunnersWithActions.contains(runner)) return; + actionManager.unregisterAction(actionId); + myRunnersWithActions.remove(runner); + } + + protected abstract String getActionId(JavaProgramRunner runner); + + protected abstract AnAction createActionFor(JavaProgramRunner runner); + } + + public JavaProgramRunner findRunnerById(String id) { + JavaProgramRunner[] registeredRunners = getRegisteredRunners(); + for (int i = 0; i < registeredRunners.length; i++) { + JavaProgramRunner registeredRunner = registeredRunners[i]; + if (Comparing.equal(id, registeredRunner.getInfo().getId())) { + return registeredRunner; + } + } + return null; + } + + private static class DefaultJavaProgramRunner implements JavaProgramRunner { + public JDOMExternalizable createConfigurationData(ConfigurationInfoProvider settingsProvider) { + return null; + } + + public SettingsEditor getSettingsEditor(RunConfiguration configuration) { + return null; + } + + public void patch(JavaParameters javaParameters, RunnerSettings settings) throws ExecutionException { + } + + public AnAction[] createActions(ExecutionResult executionResult) { + return new AnAction[0]; + } + + public RunnerInfo getInfo() { + return RunStrategy.getInstance().getInfo(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunConfigurable.java new file mode 100644 index 00000000000..59aa8892088 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunConfigurable.java @@ -0,0 +1,210 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.RunManager; +import com.intellij.execution.RunManagerConfig; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Key; +import com.intellij.ui.TabbedPaneWrapper; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +class RunConfigurable extends BaseConfigurable { + private final Project myProject; + private final RunDialog myRunDialog; + + private JPanel myPanel; + private TabbedPaneWrapper myTabbedPane; + private ConfigurationTab[] myTabs; + private JCheckBox myCbShowSettingsBeforeRunning; + private JCheckBox myCbCompileBeforeRunning; + private static final Icon ICON = IconLoader.getIcon("/general/configurableRunDebug.png"); + + public RunConfigurable(final Project project) { + myProject = project; + myRunDialog = null; + } + + public RunConfigurable(final Project project, final RunDialog runDialog) { + myProject = project; + myRunDialog = runDialog; + } + + public String getDisplayName() { + return "Run"; + } + + public JComponent createComponent() { + myPanel = new JPanel(new BorderLayout()); + + myTabbedPane = new TabbedPaneWrapper(); + myTabbedPane.installKeyboardNavigation(); + + final ConfigurationType[] factories = getConfigurationFactories(); + myTabs = new ConfigurationTab[factories.length]; + for (int i = 0; i < factories.length; i++) { + final ConfigurationType type = factories[i]; + final ConfigurationTab configurationTab = new ConfigurationTab(type, this); + myTabs[i] = configurationTab; + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); + panel.add(configurationTab.getComponent(), BorderLayout.CENTER); + myTabbedPane.addTab(type.getDisplayName(), panel); + myTabbedPane.setIconAt(i, type.getIcon()); + } + + myPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + + final JPanel bottomPanel = new JPanel(new GridLayout(1, 2, 5, 0)); + myCbShowSettingsBeforeRunning = new JCheckBox("Display settings before running/debugging"); + myCbShowSettingsBeforeRunning.setMnemonic('D'); + bottomPanel.add(myCbShowSettingsBeforeRunning); + + myCbCompileBeforeRunning = new JCheckBox("Make module before running/debugging/reloading"); + myCbCompileBeforeRunning.setMnemonic('M'); + bottomPanel.add(myCbCompileBeforeRunning); + + myPanel.add(bottomPanel, BorderLayout.SOUTH); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + myTabbedPane.addChangeListener(new ChangeListener() { + public void stateChanged(final ChangeEvent e) { + updateDialog(); + } + }); + final ItemListener cbListener = new ItemListener() { + public void itemStateChanged(final ItemEvent e) { + setModified(true); + } + }; + myCbCompileBeforeRunning.addItemListener(cbListener); + myCbShowSettingsBeforeRunning.addItemListener(cbListener); + + updateDialog(); + return myPanel; + } + + public Icon getIcon() { + return ICON; + } + + public void reset() { + for (int i = 0; i < myTabs.length; i++) { + myTabs[i].reset(); + } + + final RunManager manager = getRunManager(); + final RunManagerConfig config = manager.getConfig(); + myCbShowSettingsBeforeRunning.setSelected(config.isShowSettingsBeforeRun()); + myCbCompileBeforeRunning.setSelected(config.isCompileBeforeRunning()); + + final ConfigurationType activeType = manager.getActiveConfigurationFactory(); + final ConfigurationType[] factories = getConfigurationFactories(); + int tabToSelect = 0; + for (int i = 0; i < factories.length; i++) { + if (factories[i].equals(activeType)) { + tabToSelect = i; + break; + } + } + myTabbedPane.setSelectedIndex(tabToSelect); + setModified(false); + } + + public Project getProject() { + return myProject; + } + + public void apply() throws ConfigurationException { + for (int i = 0; i < myTabs.length; i++) { + try { + myTabs[i].apply(); + } + catch (ConfigurationException e) { + myTabbedPane.setSelectedIndex(i); + throw e; + } + } + final RunManager manager = getRunManager(); + manager.setActiveConfigurationFactory(getSelectedConfigType()); + + manager.getConfig().setShowSettingsBeforeRun(myCbShowSettingsBeforeRunning.isSelected()); + manager.getConfig().setCompileBeforeRunning(myCbCompileBeforeRunning.isSelected()); + + setModified(false); + } + + public ConfigurationType getSelectedConfigType() { + return getConfigurationFactories()[myTabbedPane.getSelectedIndex()]; + } + + public boolean isModified() { + if (super.isModified()) return true; + for (int i = 0; i < myTabs.length; i++) { + if (myTabs[i].isModified()) { + return true; + } + } + return false; + } + + public void disposeUIResources() { + for (int i = 0; i < myTabs.length; i++) { + final ConfigurationTab tab = myTabs[i]; + tab.disposeUIResources(); + } + myPanel = null; + } + + private ConfigurationType[] getConfigurationFactories() { + return getRunManager().getConfigurationFactories(); + } + + void updateDialog() { + if (myRunDialog == null) return; + + final StringBuffer buffer = new StringBuffer(); + buffer.append(myRunDialog.getRunnerInfo().getId()); + final ConfigurationTab tab = fromComponent(myTabbedPane.getSelectedComponent()); + if (tab != null) { + final RunnerAndConfigurationSettings configuration = tab.getSelectedConfiguration(); + if (configuration != null) { + buffer.append(" - "); + buffer.append(configuration.getName()); + } + myRunDialog.setOKActionEnabled(tab.canRunConfiguration(configuration)); + } + myRunDialog.setTitle(buffer.toString()); + } + + public static RunConfiguration createSameConfiguration(RunConfiguration configuration, RunManager runManager) { + return runManager.createConfiguration(configuration.getName(), configuration.getFactory()).getConfiguration(); + } + + private RunManagerImpl getRunManager() { + return RunManagerImpl.getInstanceImpl(myProject); + } + + public static ConfigurationTab fromComponent(final JComponent component) { + return (ConfigurationTab)component.getClientProperty(KEY); + } + + static final Key KEY = new Key("configurationTab"); + + public String getHelpTopic() { + return "project.propRunDebug"; + } + + public void clickDefaultButton() { + if (myRunDialog != null) myRunDialog.clickDefaultButton(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunDialog.java new file mode 100644 index 00000000000..248a4182c6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunDialog.java @@ -0,0 +1,98 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; + +import javax.swing.*; +import java.awt.event.ActionEvent; + +public class RunDialog extends DialogWrapper { + private final RunnerInfo myRunnerInfo; + private final Project myProject; + private RunConfigurable myConfigurable; + private JComponent myCenterPanel; + + public RunDialog(final Project project, final RunnerInfo runnerInfo) { + super(project, true); + myProject = project; + myRunnerInfo = runnerInfo; + + final String title = runnerInfo.getId(); + setTitle(title); + + setOKButtonText(runnerInfo.getStartActionText()); + setOKButtonIcon(runnerInfo.getIcon()); + + myConfigurable = new RunConfigurable(project, this); + init(); + myConfigurable.reset(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),new ApplyAction(),getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myRunnerInfo.getHelpId()); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.execution.impl.RunDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCenterPanel); + } + + protected void doOKAction(){ + try{ + myConfigurable.apply(); + } + catch(ConfigurationException e){ + Messages.showMessageDialog(myProject, e.getMessage(), "Invalid Data", Messages.getErrorIcon()); + return; + } + super.doOKAction(); + } + + protected JComponent createCenterPanel() { + myCenterPanel = myConfigurable.createComponent(); + return myCenterPanel; + } + + public void setOKActionEnabled(final boolean isEnabled){ + super.setOKActionEnabled(isEnabled); + } + + public static boolean editConfiguration(final Project project, final RunnerAndConfigurationSettings configuration, final String title) { + final SingleConfigurableEditor dialog = new SingleConfigurableEditor(project, SingleConfigurationConfigurable.editSettings(configuration)); + dialog.setTitle(title); + dialog.show(); + return dialog.isOK(); + } + + private class ApplyAction extends AbstractAction { + public ApplyAction() { + super("&Apply"); + } + + public void actionPerformed(final ActionEvent event) { + try{ + myConfigurable.apply(); + } + catch(ConfigurationException e){ + Messages.showMessageDialog(myProject, e.getMessage(), "Invalid Data", Messages.getErrorIcon()); + } + } + } + + public RunnerInfo getRunnerInfo() { + return myRunnerInfo; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunManagerImpl.java new file mode 100644 index 00000000000..9b0cc9afba9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunManagerImpl.java @@ -0,0 +1,413 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.RunManager; +import com.intellij.execution.RunManagerConfig; +import com.intellij.execution.RuntimeConfiguration; +import com.intellij.execution.configurations.*; +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.execution.util.RefactoringElementListenerComposite; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.listeners.RefactoringElementListenerProvider; +import com.intellij.refactoring.listeners.RefactoringListenerManager; +import com.intellij.util.containers.InternalIterator; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.Convertor; +import com.intellij.ide.util.PropertiesComponent; +import org.jdom.Element; + +import java.util.*; + + +public class RunManagerImpl extends RunManager implements JDOMExternalizable, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.RunManager"); + + private final Project myProject; + + private Map myTypesByName = new LinkedHashMap(); + + private List myConfigurations = new ArrayList(); // template configurations are not included here + private Map myTemplateConfigurationsMap = new HashMap(); + private ConfigurationType myActiveConfigurationType; + private Map mySelectedConfigurations = new HashMap(); + + protected MyRefactoringElementListenerProvider myRefactoringElementListenerProvider; + private RunnerAndConfigurationSettings myTempConfiguration; + + private static final String ACTIVE_TYPE = "activeType"; + private static final String TEMP_CONFIGURATION = "tempConfiguration"; + private static final String CONFIGURATION = "configuration"; + private ConfigurationType[] myTypes; + private final RunManagerConfig myConfig; + + public RunManagerImpl(final Project project, + PropertiesComponent propertiesComponent, + ConfigurationType[] configurationTypes) { + myConfig = new RunManagerConfig(propertiesComponent); + myProject = project; + myRefactoringElementListenerProvider = new MyRefactoringElementListenerProvider(); + initializeConfigurationTypes(configurationTypes); + + for (Iterator iterator = myConfigurations.iterator(); iterator.hasNext();) { + final RunnerAndConfigurationSettings settings = iterator.next(); + RunConfiguration configuration = settings.getConfiguration(); + if (configuration instanceof ModuleBasedConfiguration) { + ((ModuleBasedConfiguration)configuration).init(); + } + } + } + + // separate method needed for tests + public final void initializeConfigurationTypes(final ConfigurationType[] factories) { + LOG.assertTrue(factories != null); + + myTypes = factories; + for (int i = 0; i < factories.length; i++) { + final ConfigurationType type = factories[i]; + myTypesByName.put(type.getComponentName(), type); + } + } + + public void disposeComponent() { } + + public void initComponent() { + } + + public void projectOpened() { + installRefactoringListener(); + } + + // separate method needed for tests + public void installRefactoringListener() { + RefactoringListenerManager.getInstance(myProject).addListenerProvider(myRefactoringElementListenerProvider); + } + + // separate method needed for tests + public void uninstallRefactoringListener() { + RefactoringListenerManager.getInstance(myProject).removeListenerProvider(myRefactoringElementListenerProvider); + } + + public RunnerAndConfigurationSettings createConfiguration(final String name, final ConfigurationFactory factory) { + LOG.assertTrue(name != null); + LOG.assertTrue(factory != null); + RunnerAndConfigurationSettings template = getConfigurationTemplate(factory); + RunConfiguration configuration = factory.createConfiguration(name, template.getConfiguration()); + RunnerAndConfigurationSettings settings = new RunnerAndConfigurationSettings(this, configuration, false); + settings.importRunnerAndConfigurationSettings(template); + return settings; + } + + public void projectClosed() { + uninstallRefactoringListener(); + } + + + public RunManagerConfig getConfig() { + return myConfig; + } + + public ConfigurationType[] getConfigurationFactories() { + return (ConfigurationType[])myTypes.clone(); + } + + /** + * Template configuration is not included + */ + public RunConfiguration[] getConfigurations(final ConfigurationType type) { + LOG.assertTrue(type != null); + + final List array = new ArrayList(); + for (int i = 0; i < myConfigurations.size(); i++) { + final RunConfiguration configuration = myConfigurations.get(i).getConfiguration(); + if (type.equals(configuration.getType())) { + array.add(configuration); + } + } + return array.toArray(new RunConfiguration[array.size()]); + } + + public RunConfiguration[] getAllConfigurations() { + RunConfiguration [] result = new RunConfiguration[myConfigurations.size()]; + int i = 0; + for (Iterator iterator = myConfigurations.iterator(); iterator.hasNext();i++) { + RunnerAndConfigurationSettings settings = iterator.next(); + result[i] = settings.getConfiguration(); + } + + return result; + } + + public RunnerAndConfigurationSettings getSettings(RunConfiguration configuration){ + for (Iterator iterator = myConfigurations.iterator(); iterator.hasNext();) { + RunnerAndConfigurationSettings settings = iterator.next(); + if(settings.getConfiguration() == configuration) return settings; + } + return null; + } + + /** + * Template configuration is not included + */ + public RunnerAndConfigurationSettings[] getConfigurationSettings(final ConfigurationType type) { + LOG.assertTrue(type != null); + + final List array = new ArrayList(); + for (int i = 0; i < myConfigurations.size(); i++) { + final RunnerAndConfigurationSettings configuration = myConfigurations.get(i); + if (type.equals(configuration.getType())) { + array.add(configuration); + } + } + return array.toArray(new RunnerAndConfigurationSettings[array.size()]); + } + + public RunnerAndConfigurationSettings getConfigurationTemplate(final ConfigurationFactory factory) { + RunnerAndConfigurationSettings template = myTemplateConfigurationsMap.get(factory); + if (template == null) { + template = new RunnerAndConfigurationSettings(this, factory.createTemplateConfiguration(myProject), true); + myTemplateConfigurationsMap.put(factory, template); + } + return template; + } + + public void addConfiguration(RunnerAndConfigurationSettings settings) { + myConfigurations.add(settings); + } + + public void removeConfigurations(final ConfigurationType type) { + LOG.assertTrue(type != null); + + //for (Iterator> it = myRunnerPerConfigurationSettings.keySet().iterator(); it.hasNext();) { + // final Pair pair = it.next(); + // if (type.equals(pair.getFirst().getType())) { + // it.remove(); + // } + //} + for (Iterator it = myConfigurations.iterator(); it.hasNext();) { + final RunnerAndConfigurationSettings configuration = it.next(); + if (type.equals(configuration.getType())) { + it.remove(); + } + } + + if (myTempConfiguration != null && type.equals(myTempConfiguration.getType())) { + myTempConfiguration = null; + } + } + + public ConfigurationType getActiveConfigurationFactory() { + return myActiveConfigurationType; + } + + public void setActiveConfigurationFactory(final ConfigurationType activeConfigurationType) { + LOG.assertTrue(activeConfigurationType != null); + myActiveConfigurationType = activeConfigurationType; + } + + public RunnerAndConfigurationSettings getSelectedConfiguration(final ConfigurationType type) { + LOG.assertTrue(type != null); + return mySelectedConfigurations.get(type); + } + + public void setSelectedConfiguration(final RunnerAndConfigurationSettings configuration) { + LOG.assertTrue(configuration != null); + mySelectedConfigurations.put(configuration.getType(), configuration); + } + + public void clearConfigurationSelection(final ConfigurationType configurationType) { + LOG.assertTrue(configurationType != null); + mySelectedConfigurations.remove(configurationType); + } + + public static boolean canRunConfiguration(final RunConfiguration configuration) { + LOG.assertTrue(configuration != null); + try { + configuration.checkConfiguration(); + } + catch (RuntimeConfigurationError er) { + return false; + } + catch (RuntimeConfigurationException e) { + return true; + } + return true; + } + + public void writeExternal(final Element parentNode) throws WriteExternalException { + LOG.assertTrue(parentNode != null); + if (myActiveConfigurationType != null) { + final Element element = new Element(ACTIVE_TYPE); + parentNode.addContent(element); + element.setAttribute("name", myActiveConfigurationType.getComponentName()); + } + + if (myTempConfiguration != null) { + addConfigurationElement(parentNode, myTempConfiguration, TEMP_CONFIGURATION); + } + + for (Iterator iterator = myTemplateConfigurationsMap.values().iterator(); iterator.hasNext();) { + addConfigurationElement(parentNode, iterator.next(), CONFIGURATION); + } + + final List stableConfigurations = getStableConfigurations(); + for (int i = 0; i < stableConfigurations.size(); i++) { + addConfigurationElement(parentNode, stableConfigurations.get(i), CONFIGURATION); + } + } + + private void addConfigurationElement(final Element parentNode, RunnerAndConfigurationSettings template, String elementType) throws WriteExternalException { + final Element configurationElement = new Element(elementType); + parentNode.addContent(configurationElement); + storeConfiguration(configurationElement, template); + } + + private void storeConfiguration(final Element element, final RunnerAndConfigurationSettings configuration) + throws WriteExternalException { + final ConfigurationType type = configuration.getType(); + final boolean isSelected = mySelectedConfigurations.get(type) == configuration; + element.setAttribute("selected", isSelected ? "true" : "false"); + configuration.writeExternal(element); + } + + public void readExternal(final Element parentNode) throws InvalidDataException { + myConfigurations.clear(); + + final List children = parentNode.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + final Element element = (Element)iterator.next(); + final String elementName = element.getName(); + if (ACTIVE_TYPE.equals(elementName)) { + final String typeName = element.getAttributeValue("name"); + if (typeName != null) myActiveConfigurationType = myTypesByName.get(typeName); + } + else { + loadConfiguration(element); + } + } + } + + private void loadConfiguration(final Element element) throws InvalidDataException { + RunnerAndConfigurationSettings configuration = new RunnerAndConfigurationSettings(this); + configuration.readExternal(element); + ConfigurationFactory factory = configuration.getFactory(); + if (factory == null) return; + + if (configuration.isTemplate()) { + myTemplateConfigurationsMap.put(factory, configuration); + } + else { + if ("true".equals(element.getAttributeValue("selected"))) { + mySelectedConfigurations.put(factory.getType(), configuration); + } + if (TEMP_CONFIGURATION.equals(element.getName())) { + myTempConfiguration = configuration; + } + addConfiguration(configuration); + } + } + + + public ConfigurationFactory getFactory(final String typeName, String factoryName) { + final ConfigurationType type = myTypesByName.get(typeName); + if (factoryName == null) { + factoryName = type != null ? type.getConfigurationFactories()[0].getName() : null; + } + final ConfigurationFactory factory = findFactoryOfTypeNameByName(typeName, factoryName); + return factory; + } + + + private ConfigurationFactory findFactoryOfTypeNameByName(final String typeName, final String factoryName) { + return findFactoryOfTypeByName(myTypesByName.get(typeName), factoryName); + } + + private ConfigurationFactory findFactoryOfTypeByName(final ConfigurationType type, final String factoryName) { + if (type == null || factoryName == null) return null; + final ConfigurationFactory[] factories = type.getConfigurationFactories(); + for (int i = 0; i < factories.length; i++) { + final ConfigurationFactory factory = factories[i]; + if (factoryName.equals(factory.getName())) return factory; + } + return null; + } + + public String getComponentName() { + return "RunManager"; + } + + public void setTemporaryConfiguration(final RunnerAndConfigurationSettings tempConfiguration) { + LOG.assertTrue(tempConfiguration != null); + myConfigurations = getStableConfigurations(); + myTempConfiguration = tempConfiguration; + addConfiguration(myTempConfiguration); + setActiveConfiguration(myTempConfiguration); + } + + public void setActiveConfiguration(final RunnerAndConfigurationSettings configuration) { + final ConfigurationType type = configuration.getType(); + setActiveConfigurationFactory(type); + setSelectedConfiguration(configuration); + } + + private List getStableConfigurations() { + final List result = new ArrayList(myConfigurations); + result.remove(myTempConfiguration); + return result; + } + + public boolean isTemporary(final RunConfiguration configuration) { + if (myTempConfiguration == null) return false; + return myTempConfiguration.getConfiguration() == configuration; + } + + public boolean isTemporary(RunnerAndConfigurationSettings settings) { + return settings.equals(myTempConfiguration); + } + + public RunConfiguration getTempConfiguration() { + return myTempConfiguration == null ? null : myTempConfiguration.getConfiguration(); + } + + public void makeStable(final RunConfiguration configuration) { + if (isTemporary(configuration)) { + myTempConfiguration = null; + } + } + + public RunnerAndConfigurationSettings getSelectedConfiguration() { + ConfigurationType activeFactory = getActiveConfigurationFactory(); + return activeFactory != null ? getSelectedConfiguration(activeFactory) : null; + } + + + private class MyRefactoringElementListenerProvider implements RefactoringElementListenerProvider { + public RefactoringElementListener getListener(final PsiElement element) { + RefactoringElementListenerComposite composite = null; + for (int i = 0; i < myConfigurations.size(); i++) { + final RunConfiguration configuration = myConfigurations.get(i).getConfiguration(); + if (configuration instanceof RuntimeConfiguration) { // todo: perhaps better way to handle listeners? + final RefactoringElementListener listener = ((RuntimeConfiguration)configuration).getRefactoringElementListener(element); + if (listener != null) { + if (composite == null) { + composite = new RefactoringElementListenerComposite(); + } + composite.addListener(listener); + } + } + } + return composite; + } + } + + public static RunManagerImpl getInstanceImpl(final Project project) { + return (RunManagerImpl)getInstance(project); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunnerAndConfigurationSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunnerAndConfigurationSettings.java new file mode 100644 index 00000000000..c4d2bd1aace --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/RunnerAndConfigurationSettings.java @@ -0,0 +1,235 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.configurations.*; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * @author dyoma + */ +public class RunnerAndConfigurationSettings implements JDOMExternalizable, Cloneable { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.RunnerAndConfigurationSettings"); + + private static final String RUNNER_ELEMENT = "RunnerSettings"; + private static final String CONFIGURATION_ELEMENT = "ConfigurationWrapper"; + private static final String RUNNER_ID = "RunnerId"; + private static final String CONFIGURATION_TYPE_ATTRIBUTE = "type"; + private static final String FACTORY_NAME_ATTRIBUTE = "factoryName"; + private static final String TEMPLATE_FLAG_ATTRIBUTE = "default"; + + private final RunManagerImpl myManager; + private RunConfiguration myConfiguration; + private boolean myIsTemplate; + + private Map myRunnerSettings = new HashMap(); + private Map myConfigurationPerRunnerSettings = new HashMap(); + + public RunnerAndConfigurationSettings(RunManagerImpl manager) { + myManager = manager; + } + + public RunnerAndConfigurationSettings(RunManagerImpl manager, RunConfiguration configuration, boolean isTemplate) { + myManager = manager; + myConfiguration = configuration; + myIsTemplate = isTemplate; + } + + public ConfigurationFactory getFactory() { + return myConfiguration == null ? null : myConfiguration.getFactory(); + } + + public boolean isTemplate() { + return myIsTemplate; + } + + public RunConfiguration getConfiguration() { + return myConfiguration; + } + + public Factory createFactory() { + return new Factory() { + public RunnerAndConfigurationSettings create() { + RunConfiguration configuration = myConfiguration.getFactory().createConfiguration("", myConfiguration); + RunnerAndConfigurationSettings copy = new RunnerAndConfigurationSettings(myManager, configuration, false); + return copy; + } + }; + } + + public void setName(String name) { + myConfiguration.setName(name); + } + + public String getName() { + return myConfiguration.getName(); + } + + private ConfigurationFactory getFactory(final Element element) { + final String typeName = element.getAttributeValue(CONFIGURATION_TYPE_ATTRIBUTE); + String factoryName = element.getAttributeValue(FACTORY_NAME_ATTRIBUTE); + return myManager.getFactory(typeName, factoryName); + } + + public void readExternal(Element element) throws InvalidDataException { + myIsTemplate = "true".equals(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE)); + final ConfigurationFactory factory = getFactory(element); + if (factory == null) return; + + if (myIsTemplate) { + myConfiguration = myManager.getConfigurationTemplate(factory).getConfiguration(); + } + else { + final String name = element.getAttributeValue("name"); + myConfiguration = myManager.createConfiguration(name, factory).getConfiguration(); + } + + myConfiguration.readExternal(element); + List runners = element.getChildren(RUNNER_ELEMENT); + for (Iterator iterator = runners.iterator(); iterator.hasNext();) { + Element runnerElement = (Element)iterator.next(); + String id = runnerElement.getAttributeValue(RUNNER_ID); + JavaProgramRunner runner = ExecutionRegistry.getInstance().findRunnerById(id); + if (runner != null) { + RunnerSettings settings = new RunnerSettings(runner.createConfigurationData(new InfoProvider(runner)), myConfiguration); + settings.readExternal(runnerElement); + myRunnerSettings.put(runner, settings); + } + } + + List configurations = element.getChildren(CONFIGURATION_ELEMENT); + for (Iterator iterator = configurations.iterator(); iterator.hasNext();) { + Element configurationElement = (Element)iterator.next(); + String id = configurationElement.getAttributeValue(RUNNER_ID); + JavaProgramRunner runner = ExecutionRegistry.getInstance().findRunnerById(id); + if (runner != null) { + ConfigurationPerRunnerSettings settings = new ConfigurationPerRunnerSettings(runner.getInfo(), myConfiguration.createRunnerSettings(new InfoProvider(runner))); + settings.readExternal(configurationElement); + myConfigurationPerRunnerSettings.put(runner, settings); + } + } + } + + public void writeExternal(final Element element) throws WriteExternalException { + final ConfigurationFactory factory = myConfiguration.getFactory(); + + element.setAttribute(TEMPLATE_FLAG_ATTRIBUTE, String.valueOf(myIsTemplate)); + if (!myIsTemplate) { + element.setAttribute("name", myConfiguration.getName()); + } + element.setAttribute(CONFIGURATION_TYPE_ATTRIBUTE, factory.getType().getComponentName()); + element.setAttribute(FACTORY_NAME_ATTRIBUTE, factory.getName()); + myConfiguration.writeExternal(element); + + for (Iterator iterator = myRunnerSettings.keySet().iterator(); iterator.hasNext();) { + JavaProgramRunner runner = iterator.next(); + RunnerSettings settings = myRunnerSettings.get(runner); + Element runnerElement = new Element(RUNNER_ELEMENT); + settings.writeExternal(runnerElement); + element.addContent(runnerElement); + runnerElement.setAttribute(RUNNER_ID, runner.getInfo().getId()); + } + + for (Iterator iterator = myConfigurationPerRunnerSettings.keySet().iterator(); iterator.hasNext();) { + JavaProgramRunner runner = iterator.next(); + ConfigurationPerRunnerSettings settings = myConfigurationPerRunnerSettings.get(runner); + Element runnerElement = new Element(CONFIGURATION_ELEMENT); + settings.writeExternal(runnerElement); + element.addContent(runnerElement); + runnerElement.setAttribute(RUNNER_ID, runner.getInfo().getId()); + } + } + + public RunnerSettings getRunnerSettings(JavaProgramRunner runner) { + RunnerSettings settings = myRunnerSettings.get(runner); + if (settings == null) { + settings = new RunnerSettings(runner.createConfigurationData(new InfoProvider(runner)), myConfiguration); + myRunnerSettings.put(runner, settings); + } + return settings; + } + public ConfigurationPerRunnerSettings getConfigurationSettingsWr(JavaProgramRunner runner) { + return getConfigurationSettings(runner); + } + + public ConfigurationPerRunnerSettings getConfigurationSettings(JavaProgramRunner runner) { + ConfigurationPerRunnerSettings settings = myConfigurationPerRunnerSettings.get(runner); + if (settings == null) { + settings = new ConfigurationPerRunnerSettings(runner.getInfo(), myConfiguration.createRunnerSettings(new InfoProvider(runner))); + myConfigurationPerRunnerSettings.put(runner, settings); + } + return settings; + } + + public ConfigurationType getType() { + return myConfiguration == null ? null : myConfiguration.getType(); + } + + public RunnerAndConfigurationSettings clone() { + RunnerAndConfigurationSettings copy = new RunnerAndConfigurationSettings(myManager, myConfiguration.clone(), false); + copy.importRunnerAndConfigurationSettings(this); + return copy; + } + + public void importRunnerAndConfigurationSettings(RunnerAndConfigurationSettings template) { + try { + for (Iterator iterator = template.myRunnerSettings.keySet().iterator(); iterator.hasNext();) { + JavaProgramRunner runner = iterator.next(); + RunnerSettings data = new RunnerSettings(runner.createConfigurationData(new InfoProvider(runner)), myConfiguration); + myRunnerSettings.put(runner, data); + Element temp = new Element("dummy"); + template.myRunnerSettings.get(runner).writeExternal(temp); + data.readExternal(temp); + } + + for (Iterator iterator = template.myConfigurationPerRunnerSettings.keySet().iterator(); iterator.hasNext();) { + JavaProgramRunner runner = iterator.next(); + ConfigurationPerRunnerSettings data = new ConfigurationPerRunnerSettings(runner.getInfo(), myConfiguration.createRunnerSettings(new InfoProvider(runner))); + myConfigurationPerRunnerSettings.put(runner, data); + Element temp = new Element("dummy"); + template.myConfigurationPerRunnerSettings.get(runner).writeExternal(temp); + data.readExternal(temp); + } + } + catch (WriteExternalException e) { + LOG.error(e); + } + catch (InvalidDataException e) { + LOG.error(e); + } + } + + private class InfoProvider implements ConfigurationInfoProvider { + private JavaProgramRunner myRunner; + + public InfoProvider(JavaProgramRunner runner) { + myRunner = runner; + } + + public JavaProgramRunner getRunner() { + return myRunner; + } + + public RunConfiguration getConfiguration() { + return myConfiguration; + } + + public RunnerSettings getRunnerSettings() { + return RunnerAndConfigurationSettings.this.getRunnerSettings(myRunner); + } + + public ConfigurationPerRunnerSettings getConfigurationSettings() { + return getConfigurationSettingsWr(myRunner); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/SingleConfigurationConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/SingleConfigurationConfigurable.java new file mode 100644 index 00000000000..0fa1b73e304 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/SingleConfigurationConfigurable.java @@ -0,0 +1,253 @@ +package com.intellij.execution.impl; + +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.options.SettingsEditorConfigurable; +import com.intellij.openapi.options.SettingsEditorListener; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + * + * @author dyoma + */ +public final class SingleConfigurationConfigurable extends SettingsEditorConfigurable { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.SingleConfigurationConfigurable"); + private final PlainDocument myNameDocument = new PlainDocument(); + private ValidationResult myLastValidationResult = null; + private boolean myValidationResultValid = false; + private MyValidatableComponent myComponent; + private final String myDisplayName; + private final String myHelpTopic; + private final Icon myIcon; + + private SingleConfigurationConfigurable(RunnerAndConfigurationSettings settings) { + super(new ConfigurationSettingsEditor(settings), settings); + + final Config configuration = (Config)getSettings().getConfiguration(); + myDisplayName = getSettings().getName(); + myHelpTopic = null; //TODO + myIcon = configuration.getType().getIcon(); + + setNameText(configuration.getName()); + myNameDocument.addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + setModified(true); + } + }); + + getEditor().addSettingsEditorListener(new SettingsEditorListener() { + public void stateChanged(SettingsEditor settingsEditor) { + myValidationResultValid = false; + } + }); + } + + public static SingleConfigurationConfigurable editSettings(RunnerAndConfigurationSettings settings) { + SingleConfigurationConfigurable configurable = new SingleConfigurationConfigurable(settings); + configurable.reset(); + return configurable; + } + + public final void applyTo(final RunnerAndConfigurationSettings configuration) throws ConfigurationException { + LOG.assertTrue(configuration != null); + + getEditor().applyTo(configuration); + configuration.setName(getNameText()); + } + + public void apply() throws ConfigurationException { + getSettings().setName(getNameText()); + super.apply(); + } + + public void reset() { + RunnerAndConfigurationSettings configuration = getSettings(); + if (configuration != null) { + setNameText(configuration.getName()); + } + super.reset(); + } + + public final void loadFrom(final RunnerAndConfigurationSettings configuration) { + LOG.assertTrue(configuration != null); + + getEditor().resetFrom(configuration); + setNameText(configuration.getName()); + } + + public final JComponent createComponent() { + if (myComponent == null) { + myComponent = new MyValidatableComponent(); + } + return myComponent.getWholePanel(); + } + + private ValidationResult getValidationResult() { + if (!myValidationResultValid) { + myLastValidationResult = null; + try { + RunnerAndConfigurationSettings snapshot = getSnapshot(); + snapshot.setName(getNameText()); + snapshot.getConfiguration().checkConfiguration(); + } + catch (RuntimeConfigurationException exception) { + myLastValidationResult = exception != null ? new ValidationResult(exception.getLocalizedMessage(), + exception.getTitle(), + exception.getQuickFix()) : null; + } + catch (ConfigurationException e) { + myLastValidationResult = new ValidationResult(e.getLocalizedMessage(), "Invalid Configuration", null); + } + myValidationResultValid = true; + } + return myLastValidationResult; + } + + public final void disposeUIResources() { + super.disposeUIResources(); + myComponent = null; + } + + public final String getNameText() { + try { + return myNameDocument.getText(0, myNameDocument.getLength()); + } + catch (BadLocationException e) { + LOG.error(e); + return ""; + } + } + + public final void addNameListner(DocumentListener listener) { + myNameDocument.addDocumentListener(listener); + } + + public final void setNameText(final String name) { + try { + myNameDocument.replace(0, myNameDocument.getLength(), name, null); + } + catch (BadLocationException e) { + LOG.error(e); + } + } + + public final boolean isValid() { + return getValidationResult() == null; + } + + public final JComponent getNameTextField() { + return myComponent.myNameText; + } + + public String getDisplayName() { + return myDisplayName; + } + + public Icon getIcon() { + return myIcon; + } + + public String getHelpTopic() { + return myHelpTopic; + } + + public Config getConfiguration() { + return (Config)getSettings().getConfiguration(); + } + + public RunnerAndConfigurationSettings getSnapshot() throws ConfigurationException { + return getEditor().getSnapshot(); + } + + private class MyValidatableComponent { + private JLabel myNameLabel; + private JTextField myNameText; + private JComponent myWholePanel; + private JPanel myComponentPlace; + private JPanel myOutlinePanel; + private JLabel myWarningLabel; + private JButton myFixButton; + private Runnable myQuickFix = null; + + public MyValidatableComponent() { + myNameLabel.setLabelFor(myNameText); + myNameText.setDocument(myNameDocument); + + getEditor().addSettingsEditorListener(new SettingsEditorListener() { + public void stateChanged(SettingsEditor settingsEditor) { + updateWarning(); + } + }); + + myWarningLabel.setIcon(IconLoader.getIcon("/runConfigurations/configurationWarning.png")); + + myComponentPlace.setLayout(new BorderLayout(0, 0)); + myComponentPlace.add(getEditorComponent(), BorderLayout.CENTER); + myFixButton.setIcon(IconLoader.getIcon("/actions/quickfixBulb.png")); + updateWarning(); + myFixButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + if (myQuickFix == null) { + return; + } + myQuickFix.run(); + myValidationResultValid = false; + updateWarning(); + } + }); + + } + + public final JComponent getWholePanel() { + return myWholePanel; + } + + public JComponent getEditorComponent() { + return getEditor().getComponent(); + } + + public ValidationResult getValidationResult() { + return SingleConfigurationConfigurable.this.getValidationResult(); + } + + private void updateWarning() { + final ValidationResult configurationException = getValidationResult(); + + if (configurationException != null) { + myOutlinePanel.setVisible(true); + myWarningLabel.setVisible(true); + myWarningLabel.setText("" + configurationException.getTitle() + ": " + + configurationException.getMessage() + ""); + final Runnable quickFix = configurationException.getQuickFix(); + if (quickFix == null) { + myFixButton.setVisible(false); + } + else { + myFixButton.setVisible(true); + myQuickFix = quickFix; + } + + } + else { + myOutlinePanel.setVisible(false); + myWarningLabel.setVisible(false); + myFixButton.setVisible(false); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/TypeTemplatesConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/TypeTemplatesConfigurable.java new file mode 100644 index 00000000000..2064762bd4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/TypeTemplatesConfigurable.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.impl; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditorConfigurable; +import com.intellij.openapi.project.Project; +import com.intellij.ui.TabbedPaneWrapper; + +import javax.swing.*; + +/** + * @author dyoma + */ +class TypeTemplatesConfigurable implements Configurable { + private final RunManagerImpl myRunManager; + private final ConfigurationType myType; + private final Configurable[] myConfigurables; + private TabbedPaneWrapper myTabbedPane; + + public TypeTemplatesConfigurable(final ConfigurationType type, final RunManagerImpl runManager) { + myRunManager = runManager; + myType = type; + myConfigurables = new Configurable[getFactories().length]; + myTabbedPane = new TabbedPaneWrapper(); + } + + private ConfigurationFactory[] getFactories() { + return myType.getConfigurationFactories(); + } + + public String getDisplayName() { + return "Template Settings"; + } + + public Icon getIcon() { + return myType.getIcon(); + } + + public String getHelpTopic() { + final int index = myTabbedPane.getSelectedIndex(); + return myConfigurables[index].getHelpTopic(); + } + + public JComponent createComponent() { + final ConfigurationFactory[] factories = getFactories(); + for (int i = 0; i < factories.length; i++) { + final ConfigurationFactory factory = factories[i]; + final RunnerAndConfigurationSettings template = myRunManager.getConfigurationTemplate(factory); + final Configurable configurable = new TemplateConfigurable(template); + myConfigurables[i] = configurable; + myTabbedPane.addTab(factory.getName(), configurable.getIcon(), configurable.createComponent(), null); + } + return myTabbedPane.getComponent(); + } + + public boolean isModified() { + for (int i = 0; i < myConfigurables.length; i++) { + final Configurable configurable = myConfigurables[i]; + if (configurable.isModified()) return true; + } + return false; + } + + public void apply() throws ConfigurationException { + for (int i = 0; i < myConfigurables.length; i++) { + final Configurable configurable = myConfigurables[i]; + configurable.apply(); + } + } + + public void reset() { + for (int i = 0; i < myConfigurables.length; i++) { + final Configurable configurable = myConfigurables[i]; + configurable.reset(); + } + } + + public void disposeUIResources() { + for (int i = 0; i < myConfigurables.length; i++) { + final Configurable configurable = myConfigurables[i]; + configurable.disposeUIResources(); + myConfigurables[i] = null; + } + myTabbedPane = null; + } + + public static Configurable createConfigurable(final ConfigurationType type, final Project project) { + final ConfigurationFactory[] factories = type.getConfigurationFactories(); + final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project); + return factories.length == 1 + ? (Configurable)new TemplateConfigurable(runManager.getConfigurationTemplate(factories[0])) + : new TypeTemplatesConfigurable(type, runManager); + } + + private static class TemplateConfigurable extends SettingsEditorConfigurable { + private final RunnerAndConfigurationSettings myTemplate; + + public TemplateConfigurable(RunnerAndConfigurationSettings template) { + super(new ConfigurationSettingsEditor(template), template); + myTemplate = template; + } + + public String getDisplayName() { + return myTemplate.getConfiguration().getName(); + } + + public Icon getIcon() { + return myTemplate.getConfiguration().getType().getIcon(); + } + + public String getHelpTopic() { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ValidationResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ValidationResult.java new file mode 100644 index 00000000000..80653a83364 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/impl/ValidationResult.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.impl; + +/** + * @author dyoma + */ +public final class ValidationResult { + private final String myMessage; + private final String myTitle; + private final Runnable myQuickFix; + + public ValidationResult(final String message, final String title, final Runnable quickFix) { + myMessage = message; + myTitle = title; + myQuickFix = quickFix; + } + + public String getMessage() { + return myMessage; + } + + public String getTitle() { + return myTitle; + } + + public Runnable getQuickFix() { + return myQuickFix; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitProcessHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitProcessHandler.java new file mode 100644 index 00000000000..06123c05a54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitProcessHandler.java @@ -0,0 +1,120 @@ +package com.intellij.execution.junit; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.junit2.SegmentedInputStream; +import com.intellij.execution.junit2.segments.DeferedActionsQueue; +import com.intellij.execution.junit2.segments.DispatchListener; +import com.intellij.execution.junit2.segments.PacketExtractorBase; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessTerminatedListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.rt.execution.junit2.segments.PacketProcessor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.nio.charset.Charset; + +/** + * @author dyoma + */ +public class JUnitProcessHandler extends OSProcessHandler { + private final Extractor myOut; + private final Extractor myErr; + private final Charset myCharset; + + public JUnitProcessHandler(final Process process, final String commandLine, final Charset charset) { + super(process, commandLine); + myOut = new Extractor(getProcess().getInputStream()); + myErr = new Extractor(getProcess().getErrorStream()); + myCharset = charset; + } + + protected Reader createProcessOutReader() { + return myOut.getReader(); + } + + protected Reader createProcessErrReader() { + return myErr.getReader(); + } + + public PacketExtractorBase getErr() { + return myErr; + } + + public PacketExtractorBase getOut() { + return myOut; + } + + public Charset getCharset() { + return myCharset; + } + + public static JUnitProcessHandler runJava(final JavaParameters javaParameters) throws ExecutionException { + return runCommandLine(GeneralCommandLine.createFromJavaParameters(javaParameters)); + } + + public static JUnitProcessHandler runCommandLine(final GeneralCommandLine commandLine) throws ExecutionException { + final JUnitProcessHandler processHandler = new JUnitProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(), + commandLine.getCharset()); + ProcessTerminatedListener.attach(processHandler); + return processHandler; + } + + private class Extractor extends PacketExtractorBase { + private final SegmentedInputStream myStream; + + public Extractor(final InputStream stream) { + myStream = new SegmentedInputStream(stream); + } + + public void setPacketProcessor(final PacketProcessor packetProcessor) { + myStream.setEventsDispatcher(new PacketProcessor() { + public void processPacket(final String packet) { + perform(new Runnable() { + public void run() { + packetProcessor.processPacket(packet); + } + }); + } + }); + } + + public void setFulfilledWorkGate(final DeferedActionsQueue fulfilledWorkGate) { + super.setFulfilledWorkGate(new DeferedActionsQueue() { + public void addLast(final Runnable runnable) { + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run() { + fulfilledWorkGate.addLast(runnable); + } + }, ModalityState.NON_MMODAL); + } + + public void setDispactchListener(final DispatchListener listener) { + fulfilledWorkGate.setDispactchListener(listener); + } + }); + } + + public Reader getReader() { + return new Reader() { + public void close() throws IOException { + myStream.close(); + } + + public int read(final char[] cbuf, final int off, final int len) throws IOException { + for (int i = 0; i < len; i++) { + final int aChar = myStream.read(); + if (aChar == -1) return i == 0 ? -1 : i; + cbuf[off + i] = (char)aChar; + } + return len; + } + }; + //return new InputStreamReader(myStream, myCharset); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitUtil.java new file mode 100644 index 00000000000..bde50729b5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/JUnitUtil.java @@ -0,0 +1,296 @@ +package com.intellij.execution.junit; + +import com.intellij.execution.*; +import com.intellij.execution.junit2.info.MethodLocation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Condition; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; + +import java.util.*; + +public class JUnitUtil { + private static final String TESTCASE_CLASS = "junit.framework.TestCase"; + private static final String TEST_INTERFACE = "junit.framework.Test"; + private static final String TESTSUITE_CLASS = "junit.framework.TestSuite"; + private static final String SUITE_METHOD = "suite"; + + public static boolean isSuiteMethod(final PsiMethod psiMethod) { + if (psiMethod == null) return false; + if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false; + if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) return false; + if (psiMethod.isConstructor()) return false; + final PsiType returnType = psiMethod.getReturnType(); + if (!returnType.equalsToText(TEST_INTERFACE) && !returnType.equalsToText(TESTSUITE_CLASS)) return false; + final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + return parameters.length == 0; + } + + public static interface FindCallback { + /** + * Invoked in dispatch thread + */ + void found(PsiClass[] classes); + } + + public static void findTestsWithProgress(final FindCallback callback, final TestClassFilter classFilter) { + if (isSyncSearch()) { + callback.found(ConfigurationUtil.getAllTestClasses(classFilter)); + return; + } + + final PsiClass[][] result = new PsiClass[1][]; + ApplicationManager.getApplication().runProcessWithProgressSynchronously( + new Runnable() { + public void run() { + result[0] = ConfigurationUtil.getAllTestClasses(classFilter); + } + }, + "Searching For Tests...", + true, + classFilter.getProject() + ); + + if (result[0] != null) { + callback.found(result[0]); + } + } + + private static boolean isSyncSearch() { + return ApplicationManager.getApplication().isUnitTestMode(); + } + + public static boolean isTestMethod(final Location location) { + final Location aClass = location.getParent(PsiClass.class); + if (aClass == null) return false; + if (!isTestCaseClass(aClass)) return false; + final PsiMethod psiMethod = location.getPsiElement(); + if (psiMethod.isConstructor()) return false; + if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false; + if (psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) return false; + if (psiMethod.getParameterList().getParameters().length > 0) return false; + if (psiMethod.hasModifierProperty(PsiModifier.STATIC) && SUITE_METHOD.equals(psiMethod.getName())) return false; + final PsiClass testCaseClass; + try { + testCaseClass = getTestCaseClass(location); + } catch (NoJUnitException e) { + return false; + } + if (!psiMethod.getContainingClass().isInheritor(testCaseClass, true)) return false; + return true; + } + + private static boolean isTestCaseInheritor(final PsiClass aClass) { + final PsiClass testCaseClass; + try { + testCaseClass = getTestCaseClass(PsiLocation.fromPsiElement(aClass)); + } + catch (NoJUnitException e) { + return false; + } + return aClass.isInheritor(testCaseClass, true); + } + + /** + * + * @param aClassLocation + * @return true iff aClassLocation can be used as JUnit test class. + */ + public static boolean isTestCaseClass(final Location aClassLocation) { + return isTestCaseClass(aClassLocation.getPsiElement()); + } + + public static boolean isTestCaseClass(final PsiClass psiClass) { + if (!ExecutionUtil.isRunnableClass(psiClass)) return false; + if (isTestCaseInheritor(psiClass)) return true; + + final PsiMethod[] methods = psiClass.findMethodsByName(SUITE_METHOD, false); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (isSuiteMethod(method)) return true; + } + return false; + } + + private static PsiClass getTestCaseClass(final Location location) throws NoJUnitException { + final Location ancestorOrSelf = location.getAncestorOrSelf(PsiClass.class); + final PsiClass aClass = ancestorOrSelf.getPsiElement(); + return getTestCaseClass(ExecutionUtil.findModule(aClass)); + } + + public static PsiClass getTestCaseClass(final Module module) throws NoJUnitException { + if (module == null) throw new NoJUnitException(); + final GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module); + return getTestCaseClass(scope, module.getProject()); + } + + public static PsiClass getTestCaseClass(final SourceScope scope) throws NoJUnitException { + if (scope == null) throw new NoJUnitException(); + return getTestCaseClass(scope.getLibrariesScope(), scope.getProject()); + } + + private static PsiClass getTestCaseClass(final GlobalSearchScope scope, final Project project) throws NoJUnitException { + final PsiClass testCaseClass = PsiManager.getInstance(project).findClass(TESTCASE_CLASS, scope); // TODO do not search in sources; + if (testCaseClass == null) throw new NoJUnitException(); + return testCaseClass; + } + + public static class TestMethodFilter implements Condition { + private final PsiClass myClass; + + public TestMethodFilter(final PsiClass aClass) { + myClass = aClass; + } + + public boolean value(final PsiMethod method) { + return isTestMethod(MethodLocation.elementInClass(method, myClass)); + } + } + + public static PsiClass findPsiClass(final String qualifiedName, final Module module, final Project project, final boolean searchInLibs) { + final GlobalSearchScope scope; + if (module != null) + scope = searchInLibs + ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) + : GlobalSearchScope.moduleWithDependenciesScope(module); + else scope = searchInLibs ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + return PsiManager.getInstance(project).findClass(qualifiedName, scope); + } + + public static PsiPackage getContainingPackage(final PsiClass psiClass) { + return psiClass.getContainingFile().getContainingDirectory().getPackage(); + } + + public static PsiClass getTestClass(final PsiElement element) { + return JUnitConfigurationProducer.getTestClass(PsiLocation.fromPsiElement(element)); + } + + public static PsiMethod getTestMethod(final PsiElement element) { + final PsiManager manager = element.getManager(); + final Location location = PsiLocation.fromPsiElement(manager.getProject(), element); + for (Iterator> iterator = location.getAncestors(PsiMethod.class, false); iterator.hasNext();) { + final Location methodLocation = iterator.next(); + if (isTestMethod(methodLocation)) return methodLocation.getPsiElement(); + } + return null; + } + + /** + * @param collection + * @param comparator returns 0 iff elemets are incomparable. + * @return maximum elements + */ + public static Collection findMaximums(final Collection collection, final Comparator comparator) { + final ArrayList maximums = new ArrayList(); + loop: + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + final T candidate = iterator.next(); + for (Iterator iterator1 = collection.iterator(); iterator1.hasNext();) { + final T element = iterator1.next(); + if (comparator.compare(element, candidate) > 0) continue loop; + } + maximums.add(candidate); + } + return maximums; + } + + public static Map> buildAllDependencies(final Project project) { + final Module[] modules = ModuleManager.getInstance(project).getModules(); + Graph graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return Arrays.asList(modules); + } + + public Iterator getIn(Module module) { + return Arrays.asList(ModuleRootManager.getInstance(module).getDependencies()).iterator(); + } + })); + + Map> result = new HashMap>(); + for (Iterator iterator = graph.getNodes().iterator(); iterator.hasNext();) { + final Module module = iterator.next(); + buildDependenciesForModule(module, graph, result); + } + return result; + } + + private static void buildDependenciesForModule(final Module module, final Graph graph, Map> map) { + final Set deps = new HashSet(); + map.put(module, deps); + + new Object() { + void traverse(Module m) { + for (Iterator iterator = graph.getIn(m); iterator.hasNext();) { + final Module dep = iterator.next(); + if (!deps.contains(dep)) { + deps.add(dep); + traverse(dep); + } + } + } + }.traverse(module); + + graph.getIn(module); + } + + /*public static Map> buildAllDependencies(final Project project) { + final Module[] modules = ModuleManager.getInstance(project).getSortedModules(); + final HashMap> lessers = new HashMap>(); + int prevProcessedCount = 0; + while (modules.length > lessers.size()) { + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + if (lessers.containsKey(module)) continue; + final Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies(); + if (lessers.keySet().containsAll(Arrays.asList(dependencies))) { + final HashSet allDependencies = new HashSet(); + for (int j = 0; j < dependencies.length; j++) { + final Module dependency = dependencies[j]; + allDependencies.add(dependency); + allDependencies.addAll(lessers.get(dependency)); + } + lessers.put(module, allDependencies); + } + } + if (lessers.size() == prevProcessedCount) return null; + prevProcessedCount = lessers.size(); + } + return lessers; + }*/ + + public static class ModuleOfClass implements Convertor { + private final ProjectFileIndex myFileIndex; + + public ModuleOfClass(final ProjectFileIndex fileIndex) { + myFileIndex = fileIndex; + } + + public ModuleOfClass(final Project project) { + this(ProjectRootManager.getInstance(project).getFileIndex()); + } + + public Module convert(final PsiClass psiClass) { + if (psiClass == null || !psiClass.isValid()) return null; + return ModuleUtil.findModuleForPsiElement(psiClass); + } + } + + public static class NoJUnitException extends CantRunException { + public NoJUnitException() { + super("No junit.jar"); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/ModuleBasedConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/ModuleBasedConfiguration.java new file mode 100644 index 00000000000..a9b06e35bf6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/ModuleBasedConfiguration.java @@ -0,0 +1,88 @@ +package com.intellij.execution.junit; + +import com.intellij.execution.RuntimeConfiguration; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.Arrays; +import java.util.Collection; + +public abstract class ModuleBasedConfiguration extends RuntimeConfiguration { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.ModuleBasedConfiguration"); + private final RunConfigurationModule myModule; + + public ModuleBasedConfiguration(final String name, + final RunConfigurationModule configurationModule, final ConfigurationFactory factory) { + super(name, configurationModule.getProject(), factory); + myModule = configurationModule; + } + + public abstract Collection getValidModules(); + + public void setModuleName(final String moduleName) { + myModule.setModuleName(moduleName); + } + + public RunConfigurationModule getConfigurationModule() { + return myModule; + } + + public void init() { + myModule.init(); + } + + public void setModule(final Module module) { + if (module == null) return; + myModule.setModule(module); + } + + public abstract void readExternal(Element element) throws InvalidDataException; + public abstract void writeExternal(Element element) throws WriteExternalException; + + protected void readModule(final Element element) throws InvalidDataException { + myModule.readExternal(element); + } + + protected void writeModule(final Element element) throws WriteExternalException { + myModule.writeExternal(element); + } + + public Collection getAllModules() { + return Arrays.asList(ModuleManager.getInstance(getProject()).getModules()); + } + + protected abstract ModuleBasedConfiguration createInstance(); + + public ModuleBasedConfiguration clone() { + final Element element = new Element("toClone"); + try { + writeExternal(element); + final ModuleBasedConfiguration configuration = createInstance(); + configuration.readExternal(element); + return configuration; + } catch (InvalidDataException e) { + LOG.error(e); + return null; + } catch (WriteExternalException e) { + LOG.error(e); + return null; + } + } + + public Module[] getModules() { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Module[] compute() { + final Module module = getConfigurationModule().getModule(); + return module == null ? null : new Module[] {module}; + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RefactoringListeners.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RefactoringListeners.java new file mode 100644 index 00000000000..4134b94b9ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RefactoringListeners.java @@ -0,0 +1,180 @@ +package com.intellij.execution.junit; + +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.SingleClassConfiguration; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.listeners.RefactoringElementListener; + +public class RefactoringListeners { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.RefactoringListeners"); + public static RefactoringElementListener getListener(final PsiPackage psiPackage, + final Accessor accessor) { + final StringBuffer path = new StringBuffer(); + for (PsiPackage parent = accessor.getPsiElement(); parent != null; parent = parent.getParentPackage()) { + if (parent.equals(psiPackage)) return new RefactorPackage(accessor, path.toString()); + if (path.length() > 0) path.insert(0, '.'); + path.insert(0, parent.getName()); + } + return null; + } + + public static RefactoringElementListener getListeners(final PsiClass psiClass, final Accessor accessor) { + final PsiClass aClass = accessor.getPsiElement(); + if (aClass == null) return null; + final StringBuffer path = new StringBuffer(); + for (PsiClass parent = aClass; parent != null; parent = PsiTreeUtil.getParentOfType(parent, PsiClass.class, true)) { + if (parent.equals(psiClass)) return new RefactorClass(accessor, path.toString()); + if (path.length() > 0) path.insert(0, '$'); + path.insert(0, parent.getName()); + } + return null; + } + + public static RefactoringElementListener getClassOrPackageListener(final PsiElement element, final Accessor accessor) { + if (element instanceof PsiClass) return RefactoringListeners.getListeners((PsiClass)element, accessor); + if (element instanceof PsiPackage) { + final PsiClass aClass = accessor.getPsiElement(); + if (aClass == null) return null; + return RefactoringListeners.getListener((PsiPackage)element, new ClassPackageAccessor(accessor)); + } + return null; + + } + + public interface Accessor { + void setName(String qualifiedName); + T getPsiElement(); + void setPsiElement(T psiElement); + } + + public static class SingleClassConfigurationAccessor implements Accessor { + private final SingleClassConfiguration myConfiguration; + + public SingleClassConfigurationAccessor(final SingleClassConfiguration configuration) { + myConfiguration = configuration; + } + + public PsiClass getPsiElement() { + return myConfiguration.getMainClass(); + } + + public void setPsiElement(final PsiClass psiClass) { + myConfiguration.setMainClass(psiClass); + } + + public void setName(final String qualifiedName) { + myConfiguration.setMainClassName(qualifiedName); + } + } + + private static abstract class RenameElement implements RefactoringElementListener { + private final Accessor myAccessor; + private final String myPath; + + public RenameElement(final Accessor accessor, final String path) { + myAccessor = accessor; + myPath = path; + } + + public void elementMoved(final PsiElement newElement) { + setName((T)newElement); + } + + public void elementRenamed(final PsiElement newElement) { + setName((T)newElement); + } + + private void setName(T newElement) { + String qualifiedName = getQualifiedName(newElement); + if (myPath.length() > 0) { + qualifiedName = qualifiedName + "." + myPath; + newElement = findNewElement(newElement, qualifiedName); + } + if (newElement != null) myAccessor.setPsiElement(newElement); + else myAccessor.setName(qualifiedName); + } + + protected abstract T findNewElement(T newParent, String qualifiedName); + + protected abstract String getQualifiedName(T element); + } + + private static class RefactorPackage extends RenameElement { + public RefactorPackage(final Accessor accessor, final String path) { + super(accessor, path); + } + + public PsiPackage findNewElement(final PsiPackage psiPackage, final String qualifiedName) { + return psiPackage.getManager().findPackage(qualifiedName); + } + + public String getQualifiedName(final PsiPackage psiPackage) { + return psiPackage.getQualifiedName(); + } + } + + private static class RefactorClass extends RenameElement { + public RefactorClass(final Accessor accessor, final String path) { + super(accessor, path); + } + + public PsiClass findNewElement(final PsiClass psiClass, final String qualifiedName) { + return psiClass.getManager().findClass(qualifiedName.replace('$', '.'), + GlobalSearchScope.moduleScope(ExecutionUtil.findModule(psiClass))); + } + + public String getQualifiedName(final PsiClass psiClass) { + return psiClass.getQualifiedName(); + } + } + + private static class ClassPackageAccessor implements RefactoringListeners.Accessor { + private final PsiPackage myContainingPackage; + private final Module myModule; + private final RefactoringListeners.Accessor myAccessor; + private final String myInpackageName; + + public ClassPackageAccessor(final RefactoringListeners.Accessor accessor) { + myAccessor = accessor; + PsiClass aClass = myAccessor.getPsiElement(); + aClass = (PsiClass)aClass.getOriginalElement(); + myContainingPackage = aClass.getContainingFile().getContainingDirectory().getPackage(); + myModule = ExecutionUtil.findModule(aClass); + final String classQName = aClass.getQualifiedName(); + final String classPackageQName = myContainingPackage.getQualifiedName(); + LOG.assertTrue(classQName.startsWith(classPackageQName), classQName + " in package: " + classPackageQName); + final String inpackageName = classQName.substring(classPackageQName.length()); + if (StringUtil.startsWithChar(inpackageName, '.')) + myInpackageName = inpackageName.substring(1); + else + myInpackageName = inpackageName; + } + + public PsiPackage getPsiElement() { + return myContainingPackage; + } + + public void setPsiElement(final PsiPackage psiPackage) { + final String classQName = getClassQName(psiPackage.getQualifiedName()); + final PsiClass newClass = JUnitUtil.findPsiClass(classQName, myModule, psiPackage.getProject(), false); + if (newClass != null) myAccessor.setPsiElement(newClass); + else myAccessor.setName(classQName); + } + + public void setName(final String qualifiedName) { + myAccessor.setName(getClassQName(qualifiedName)); + } + + private String getClassQName(final String packageQName) { + if (packageQName.length() > 0) return packageQName + '.' + myInpackageName; + else return myInpackageName; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RuntimeConfigurationProducer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RuntimeConfigurationProducer.java new file mode 100644 index 00000000000..9d1fecab1a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit/RuntimeConfigurationProducer.java @@ -0,0 +1,80 @@ +package com.intellij.execution.junit; + +import com.intellij.execution.Location; +import com.intellij.execution.RunManager; +import com.intellij.execution.actions.ConfigurationContext; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.impl.RunnerAndConfigurationSettings; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; + +import java.util.Comparator; + +public abstract class RuntimeConfigurationProducer implements Comparable { + public static final Comparator COMPARATOR = new ProducerComparator(); + protected static final int PREFERED = -1; + private final ConfigurationFactory myConfigurationFactory; + private RunnerAndConfigurationSettings myConfiguration; + + public RuntimeConfigurationProducer(final ConfigurationType configurationType) { + myConfigurationFactory = configurationType.getConfigurationFactories()[0]; + } + + public RuntimeConfigurationProducer createProducer(final Location location, final ConfigurationContext context) { + final RuntimeConfigurationProducer result = clone(); + result.myConfiguration = location != null ? result.createConfigurationByElement(location, context) : null; + return result; + } + + public abstract PsiElement getSourceElement(); + + public RunnerAndConfigurationSettings getConfiguration() { + return myConfiguration; + } + + protected abstract RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context); + + public RuntimeConfigurationProducer clone() { + try { + return (RuntimeConfigurationProducer)super.clone(); + } + catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + public RunnerAndConfigurationSettings cloneTemplateConfiguration(final Project project, final ConfigurationContext context) { + if (context != null) { + final RunnerAndConfigurationSettings original = context.getOriginalConfiguration(myConfigurationFactory.getType()); + if (original != null) return original.clone(); + } + return RunManager.getInstance(project).createConfiguration("", myConfigurationFactory); + } + + public static PsiMethod getContainingMethod(PsiElement element) { + while (element != null) + if (element instanceof PsiMethod) break; + else element = element.getParent(); + return (PsiMethod) element; + } + + private static class ProducerComparator implements Comparator { + public int compare(final Object o1, final Object o2) { + final RuntimeConfigurationProducer producer1 = (RuntimeConfigurationProducer)o1; + final RuntimeConfigurationProducer producer2 = (RuntimeConfigurationProducer)o2; + final PsiElement psiElement1 = producer1.getSourceElement(); + final PsiElement psiElement2 = producer2.getSourceElement(); + if (doesContains(psiElement1, psiElement2)) return -PREFERED; + if (doesContains(psiElement2, psiElement1)) return PREFERED; + return producer1.compareTo(producer2); + } + + private boolean doesContains(final PsiElement container, PsiElement element) { + while ((element = element.getParent()) != null) + if (container.equals(element)) return true; + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Filter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Filter.java new file mode 100644 index 00000000000..eedde8f06a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Filter.java @@ -0,0 +1,119 @@ +package com.intellij.execution.junit2; + +import com.intellij.rt.execution.junit2.states.PoolOfTestStates; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public abstract class Filter { + /** + * All instances (and subclasses's instances) should be singletons. + * @see TestProxy#selectChildren + */ + private Filter() { + } + + public abstract boolean shouldAccept(TestProxy test); + + public List select(final List tests) { + final ArrayList result = new ArrayList(); + for (Iterator iterator = tests.iterator(); iterator.hasNext();) { + final TestProxy test = (TestProxy) iterator.next(); + if (shouldAccept(test)) + result.add(test); + } + return result; + } + + public TestProxy detectIn(final Collection collection) { + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + final TestProxy test = (TestProxy) iterator.next(); + if (shouldAccept(test)) + return test; + } + return null; + } + + private Filter not() { + return new NotFilter(this); + } + + private Filter and(final Filter filter) { + return new AndFilter(this, filter); + } + + public static final Filter NO_FILTER = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return true; + } + }; + + public static final Filter DEFECT = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.getState().isDefect(); + } + }; + + public static final Filter NOT_PASSED = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.getState().getMagnitude() > PoolOfTestStates.PASSED_INDEX; + } + }; + + public static final Filter TEST_CASE = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.getInfo().shouldRun(); + } + }; + + public static final Filter IN_PROGRESS = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.getState().isInProgress(); + } + }; + + public static final Filter LEAF = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.isLeaf(); + } + }; + + public static final Filter RUNNING = new Filter() { + public boolean shouldAccept(final TestProxy test) { + return test.getState().getMagnitude() == PoolOfTestStates.RUNNING_INDEX; + } + }; + + public static final Filter NOT_LEAF = LEAF.not(); + public static final Filter RUNNING_LEAF = RUNNING.and(LEAF); + + public static final Filter DEFECTIVE_LEAF = DEFECT.and(LEAF); + + private static class AndFilter extends Filter { + private final Filter myFilter1; + private final Filter myFilter2; + + public AndFilter(final Filter filter1, final Filter filter2) { + myFilter1 = filter1; + myFilter2 = filter2; + } + + public boolean shouldAccept(final TestProxy test) { + return myFilter1.shouldAccept(test) && myFilter2.shouldAccept(test); + } + } + + private static class NotFilter extends Filter { + private final Filter myFilter; + + public NotFilter(final Filter filter) { + myFilter = filter; + } + + public boolean shouldAccept(final TestProxy test) { + return !myFilter.shouldAccept(test); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printable.java new file mode 100644 index 00000000000..8b0a0fee0d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printable.java @@ -0,0 +1,6 @@ +package com.intellij.execution.junit2; + + +public interface Printable { + void printOn(Printer printer); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printer.java new file mode 100644 index 00000000000..5b33d42a069 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/Printer.java @@ -0,0 +1,21 @@ +package com.intellij.execution.junit2; + +import com.intellij.execution.filters.HyperlinkInfo; +import com.intellij.execution.ui.ConsoleViewContentType; + +public interface Printer { + void print(String text, ConsoleViewContentType contentType); + void onNewAvaliable(Printable printable); + void printHyperLink(String text, HyperlinkInfo info); + void mark(); + + interface Intermediate extends Printer, Printable {} + + Intermediate DEAF = new Intermediate() { + public void print(final String text, final ConsoleViewContentType contentType) {} + public void onNewAvaliable(final Printable printable) {} + public void printHyperLink(final String text, final HyperlinkInfo info) {} + public void mark() {} + public void printOn(final Printer printer) {} + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/PushReader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/PushReader.java new file mode 100644 index 00000000000..e89573f5136 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/PushReader.java @@ -0,0 +1,57 @@ +package com.intellij.execution.junit2; + +import gnu.trove.TIntArrayList; + +import java.io.IOException; +import java.io.Reader; + +/** + * @author dyoma + */ +public class PushReader { + private final Reader mySource; + private final TIntArrayList myReadAhead = new TIntArrayList(); + + public PushReader(final Reader source) { + mySource = source; + } + + public int next() throws IOException { + return myReadAhead.isEmpty() ? mySource.read() : myReadAhead.remove(myReadAhead.size() - 1); + } + + public void pushBack(final char[] chars) { + for (int i = chars.length - 1; i >= 0; i--) { + final char aChar = chars[i]; + myReadAhead.add(aChar); + } + } + + public void close() throws IOException { + mySource.close(); + } + + public boolean ready() throws IOException { + return !myReadAhead.isEmpty() || mySource.ready(); + } + + public void pushBack(final int aChar) { + myReadAhead.add(aChar); + } + + public char[] next(final int charCount) throws IOException { + final char[] chars = new char[charCount]; + int offset = 0; + for (; offset < chars.length && offset < myReadAhead.size(); offset++) + chars[offset] = (char)myReadAhead.remove(myReadAhead.size() - 1); + + while (offset < chars.length) { + int bytesRead = mySource.read(chars, offset, chars.length - offset); + if (bytesRead == -1) + throw new IOException ("Unexpected end of pipe"); + offset += bytesRead; + } + + return chars; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/SegmentedInputStream.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/SegmentedInputStream.java new file mode 100644 index 00000000000..7050abc19bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/SegmentedInputStream.java @@ -0,0 +1,115 @@ +package com.intellij.execution.junit2; + +import com.intellij.rt.execution.junit2.segments.Packet; +import com.intellij.rt.execution.junit2.segments.PacketProcessor; +import com.intellij.rt.execution.junit2.segments.SegmentedStream; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class SegmentedInputStream extends InputStream implements SegmentedStream { + private PushReader mySourceStream; + private PacketProcessor myEventsDispatcher; + private int myStartupPassed = 0; + + public SegmentedInputStream(final InputStream sourceStream) { + mySourceStream = new PushReader(new BufferedReader(new InputStreamReader(sourceStream))); + } + + public int read() throws IOException { + if (myStartupPassed < STARTUP_MESSAGE.length()) { + return rawRead(); + } else { + final int result = findNextSymbol(); + return result; + } + } + + private int rawRead() throws IOException { + while(myStartupPassed < STARTUP_MESSAGE.length()) { + final int aChar = readNext(); + if (aChar != STARTUP_MESSAGE.charAt(myStartupPassed)) { + mySourceStream.pushBack(aChar); + mySourceStream.pushBack(STARTUP_MESSAGE.substring(0, myStartupPassed).toCharArray()); + myStartupPassed = 0; + return readNext(); + } + myStartupPassed++; + } + return read(); + } + + private int findNextSymbol() throws IOException { + int nextByte; + while (true) { + nextByte = readNext(); + if (nextByte != SPECIAL_SYMBOL) break; + final boolean packetRead = readControlSequence(); + if (!packetRead) break; + } + return nextByte; + } + + private boolean readControlSequence() throws IOException { + if (readNext() == SPECIAL_SYMBOL) + return false; + final char[] marker = readMarker(); + if(myEventsDispatcher != null) myEventsDispatcher.processPacket(decode(marker)); + return true; + } + + public void setEventsDispatcher(final PacketProcessor eventsDispatcher) { + myEventsDispatcher = eventsDispatcher; + } + + private char[] readMarker() throws IOException { + int nextRead = '0'; + final StringBuffer buffer = new StringBuffer(); + while (nextRead != ' ') { + buffer.append((char)nextRead); + nextRead = readNext(); + } + return readNext(Integer.valueOf(buffer.toString()).intValue()); + } + + private char[] readNext(final int charCount) throws IOException { + return mySourceStream.next(charCount); + } + + private int readNext() throws IOException { + return mySourceStream.next(); + } + + public int available() throws IOException { + return mySourceStream.ready() ? 1 : 0; + } + + public void close() throws IOException { + mySourceStream.close(); + } + + public static String decode(final char[] chars) { + final StringBuffer buffer = new StringBuffer(chars.length); + for (int i = 0; i < chars.length; i++) { + char chr = chars[i]; + final char decodedChar; + if (chr == Packet.ourSpecialSymbol) { + i++; + chr = chars[i]; + if (chr != Packet.ourSpecialSymbol) { + final StringBuffer codeBuffer = new StringBuffer(Packet.CODE_LENGTH); + codeBuffer.append(chr); + for (int j = 1; j < Packet.CODE_LENGTH; j++) + codeBuffer.append(chars[i+j]); + i += Packet.CODE_LENGTH - 1; + decodedChar = (char)Integer.parseInt(codeBuffer.toString()); + } + else decodedChar = chr; + } else decodedChar = chr; + buffer.append(decodedChar); + } + return buffer.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/BrowseModuleValueActionListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/BrowseModuleValueActionListener.java new file mode 100644 index 00000000000..6c392b2d930 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/BrowseModuleValueActionListener.java @@ -0,0 +1,37 @@ +package com.intellij.execution.junit2.configuration; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public abstract class BrowseModuleValueActionListener implements ActionListener { + private TextFieldWithBrowseButton myField; + private final Project myProject; + + protected BrowseModuleValueActionListener(final Project project) { + myProject = project; + } + + public void setField(final TextFieldWithBrowseButton field) { + myField = field; + myField.addActionListener(this); + myField.setButtonEnabled(!myProject.isDefault()); + } + + public void actionPerformed(final ActionEvent e) { + final String text = showDialog(); + if (text != null) myField.getTextField().setText(text); + } + + public String getText() { + return myField.getText(); + } + + public TextFieldWithBrowseButton getField() { return myField; } + + protected abstract String showDialog(); + + public Project getProject() { return myProject; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ClassBrowser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ClassBrowser.java new file mode 100644 index 00000000000..12ab240cf0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ClassBrowser.java @@ -0,0 +1,149 @@ +package com.intellij.execution.junit2.configuration; + +import com.intellij.execution.ConfigurationUtil; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ex.MessagesEx; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; + +public abstract class ClassBrowser extends BrowseModuleValueActionListener { + private final String myTitle; + + public ClassBrowser(final Project project, final String title) { + super(project); + myTitle = title; + } + + protected String showDialog() { + final TreeClassChooserDialog.ClassFilterWithScope classFilter; + try { + classFilter = getFilter(); + } + catch (NoFilterException e) { + final MessagesEx.MessageInfo info = e.getMessageInfo(); + info.showNow(); + return null; + } + final TreeClassChooserDialog dialog = TreeClassChooserDialog. + withInnerClasses(myTitle, getProject(), classFilter.getScope(), classFilter, null); + configureDialog(dialog); + dialog.show(); + final PsiClass psiClass = dialog.getSelectedClass(); + if (psiClass == null) return null; + onClassChoosen(psiClass); + return ExecutionUtil.getRuntimeQualifiedName(psiClass); + } + + protected abstract TreeClassChooserDialog.ClassFilterWithScope getFilter() throws NoFilterException; + + protected void onClassChoosen(final PsiClass psiClass) { } + + private void configureDialog(final TreeClassChooserDialog dialog) { + final String className = getText(); + final PsiClass psiClass = findClass(className); + if (psiClass == null) return; + final PsiDirectory directory = psiClass.getContainingFile().getContainingDirectory(); + if (directory != null) dialog.selectDirectory(directory); + dialog.selectClass(psiClass); + } + + protected abstract PsiClass findClass(String className); + + public static ClassBrowser createApplicationClassBrowser(final Project project, + final ConfigurationModuleSelector moduleSelector) { + final TreeClassChooserDialog.ClassFilter applicationClass = new TreeClassChooserDialog.ClassFilter() { + public boolean isAccepted(final PsiClass aClass) { + return ConfigurationUtil.MAIN_CLASS.value(aClass) && ApplicationConfigurationType.findMainMethod(aClass) != null; + } + }; + return new MainClassBrowser(project, moduleSelector, "Choose Main Class"){ + protected TreeClassChooserDialog.ClassFilter createFilter(final Module module) { + return applicationClass; + } + }; + } + + public static ClassBrowser createAppletClassBrowser(final Project project, + final ConfigurationModuleSelector moduleSelector) { + return new MainClassBrowser(project, moduleSelector, "Choose Applet Class") { + protected TreeClassChooserDialog.ClassFilter createFilter(final Module module) { + final GlobalSearchScope scope = module != null ? + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : + GlobalSearchScope.allScope(myProject); + final PsiClass appletClass = PsiManager.getInstance(project).findClass("java.applet.Applet", scope); + return new TreeClassChooserDialog.InheritanceClassFilter(appletClass, false, false, + ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS); + } + }; + } + + private static abstract class MainClassBrowser extends ClassBrowser { + protected final Project myProject; + private final ConfigurationModuleSelector myModuleSelector; + + public MainClassBrowser(final Project project, + final ConfigurationModuleSelector moduleSelector, + final String title) { + super(project, title); + myProject = project; + myModuleSelector = moduleSelector; + } + + protected PsiClass findClass(final String className) { + return myModuleSelector.findClass(className); + } + + protected TreeClassChooserDialog.ClassFilterWithScope getFilter() throws NoFilterException { + final Module module = myModuleSelector.getModule(); + final GlobalSearchScope scope; + if (module == null) scope = GlobalSearchScope.projectScope(myProject); + else scope = GlobalSearchScope.moduleWithDependenciesScope(module); + final TreeClassChooserDialog.ClassFilter filter = createFilter(module); + return new TreeClassChooserDialog.ClassFilterWithScope() { + public GlobalSearchScope getScope() { + return scope; + } + + public boolean isAccepted(final PsiClass aClass) { + return (filter == null || filter.isAccepted(aClass)); + } + }; + } + + protected TreeClassChooserDialog.ClassFilter createFilter(final Module module) { return null; } + } + + public static class NoFilterException extends Exception { + private MessagesEx.MessageInfo myMessageInfo; + + public NoFilterException(final MessagesEx.MessageInfo messageInfo) { + super(messageInfo.getMessage()); + myMessageInfo = messageInfo; + } + + public MessagesEx.MessageInfo getMessageInfo() { + return myMessageInfo; + } + + public static NoFilterException noJUnitInModule(final Module module) { + return new NoFilterException(new MessagesEx.MessageInfo( + module.getProject(), + "JUnit not found in module \"" + module.getName() + "\"", + "Can't Browse TestCase Inheritors")); + } + + public static NoFilterException moduleDoesntExist(final ConfigurationModuleSelector moduleSelector) { + final Project project = moduleSelector.getProject(); + return new NoFilterException(new MessagesEx.MessageInfo( + project, + "Module \"" + moduleSelector.getModuleName() + "\" does not exist in project \"" + project.getName() + "\"", + "Can't Browse TestCase Inheritors")); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/CommonJavaParameters.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/CommonJavaParameters.java new file mode 100644 index 00000000000..9353d7460b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/CommonJavaParameters.java @@ -0,0 +1,93 @@ +package com.intellij.execution.junit2.configuration; + +import com.intellij.execution.RunJavaConfiguration; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.ui.RawCommandLineEditor; + +import javax.swing.*; +import java.awt.*; + +public class CommonJavaParameters extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.configuration.CommonJavaParameters"); + private static final int[] ourProperties = new int[]{ + RunJavaConfiguration.PROGRAM_PARAMETERS_PROPERTY, + RunJavaConfiguration.VM_PARAMETERS_PROPERTY, + RunJavaConfiguration.WORKING_DIRECTORY_PROPERTY + }; + + private JPanel myWholePanel; + private LabeledComponent myWorkingDirectory; + private LabeledComponent myProgramParameters; + private LabeledComponent myVMParameters; + + private LabeledComponent[] myFields = new LabeledComponent[3]; + + public CommonJavaParameters() { + super(new BorderLayout()); + add(myWholePanel, BorderLayout.CENTER); + copyDialogCaption(myProgramParameters); + copyDialogCaption(myVMParameters); + myWorkingDirectory.getComponent(). + addBrowseFolderListener("Select Working Directory", null, null, + FileChooserDescriptorFactory.createSingleFolderDescriptor()); + + myFields[RunJavaConfiguration.PROGRAM_PARAMETERS_PROPERTY] = myProgramParameters; + myFields[RunJavaConfiguration.VM_PARAMETERS_PROPERTY] = myVMParameters; + myFields[RunJavaConfiguration.WORKING_DIRECTORY_PROPERTY] = myWorkingDirectory; + } + + private void copyDialogCaption(final LabeledComponent component) { + final RawCommandLineEditor rawCommandLineEditor = component.getComponent(); + rawCommandLineEditor.setDialodCaption(component.getRawText()); + component.getLabel().setLabelFor(rawCommandLineEditor.getTextField()); + } + + public String getProgramParametersText() { + return getLabeledComponent(RunJavaConfiguration.PROGRAM_PARAMETERS_PROPERTY).getText(); + } + + public void setProgramParametersText(String textWithMnemonic) { + getLabeledComponent(RunJavaConfiguration.PROGRAM_PARAMETERS_PROPERTY).setText(textWithMnemonic); + copyDialogCaption(myProgramParameters); + } + + public void applyTo(final RunJavaConfiguration configuration) { + for (int i = 0; i < ourProperties.length; i++) { + final int property = ourProperties[i]; + configuration.setProperty(property, getText(property)); + } + } + + public void reset(final RunJavaConfiguration configuration) { + for (int i = 0; i < ourProperties.length; i++) { + final int property = ourProperties[i]; + setText(property, configuration.getProperty(property)); + } + } + + public void setText(final int property, final String value) { + final JComponent component = getLabeledComponent(property).getComponent(); + if (component instanceof TextFieldWithBrowseButton) + ((TextFieldWithBrowseButton)component).setText(value); + else if (component instanceof RawCommandLineEditor) + ((RawCommandLineEditor)component).setText(value); + else LOG.error(component.getClass().getName()); + } + + public String getText(final int property) { + final JComponent component = getLabeledComponent(property).getComponent(); + if (component instanceof TextFieldWithBrowseButton) + return ((TextFieldWithBrowseButton)component).getText(); + else if (component instanceof RawCommandLineEditor) + return ((RawCommandLineEditor)component).getText(); + else LOG.error(component.getClass().getName()); + return ""; + } + + private LabeledComponent getLabeledComponent(final int index) { + return myFields[index]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ConfigurationModuleSelector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ConfigurationModuleSelector.java new file mode 100644 index 00000000000..cae3dc2911e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/ConfigurationModuleSelector.java @@ -0,0 +1,97 @@ +package com.intellij.execution.junit2.configuration; + +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ui.exclude.SortedComboBoxModel; +import com.intellij.psi.PsiClass; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.Convertor; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ConfigurationModuleSelector { + private final Project myProject; + private final JComboBox myModulesList; + private final SortedComboBoxModel myModules = new SortedComboBoxModel(String.CASE_INSENSITIVE_ORDER); + + public ConfigurationModuleSelector(final Project project, final JComboBox modulesList) { + myProject = project; + myModulesList = modulesList; + myModulesList.setModel(myModules); + myModulesList.setRenderer(new DefaultListCellRenderer(){ + public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { + final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + final Module module = ModuleManager.getInstance(project).findModuleByName((String)value); + if (module != null) { + setIcon(module.getModuleType().getNodeIcon(true)); + } + return component; + } + }); + } + + public void applyTo(final ModuleBasedConfiguration configurationModule) { + configurationModule.setModuleName((String)myModulesList.getSelectedItem()); + } + + public void reset(final ModuleBasedConfiguration configuration) { + final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + final List list = new ArrayList(); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + if (isModuleAccepted(module)) list.add(module); + } + setModules(list); + myModules.setSelectedItem(configuration.getConfigurationModule().getModuleName()); + } + + public boolean isModuleAccepted(final Module module) { + return ArrayUtil.find(new ModuleType[]{ModuleType.JAVA, ModuleType.WEB, ModuleType.EJB}, module.getModuleType()) != -1; + } + + public Project getProject() { + return myProject; + } + + public RunConfigurationModule getConfigurationModule() { + final RunConfigurationModule configurationModule = new RunConfigurationModule(getProject(), false); + configurationModule.setModuleName(myModules.getSelectedItem()); + return configurationModule; + } + + private void setModules(final Collection modules) { + myModules.clear(); + myModules.addAll(CollectUtil.COLLECT.toList(modules.iterator(), MODULE_NAME)); + } + + private static final Convertor MODULE_NAME = new Convertor() { + public String convert(final Module module) { + return module.getName(); + } + }; + + public Module getModule() { + final String moduleName = myModules.getSelectedItem(); + if (moduleName == null) { + return null; + } + return ModuleManager.getInstance(myProject).findModuleByName(moduleName); + } + + public PsiClass findClass(final String className) { + return getConfigurationModule().findClass(className); + } + + public String getModuleName() { + final String moduleName = myModules.getSelectedItem(); + return moduleName == null ? "" : moduleName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/RunConfigurationModule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/RunConfigurationModule.java new file mode 100644 index 00000000000..7f9d75fb0b0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/configuration/RunConfigurationModule.java @@ -0,0 +1,143 @@ +package com.intellij.execution.junit2.configuration; + +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.configurations.RuntimeConfigurationError; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.configurations.RuntimeConfigurationWarning; +import com.intellij.execution.junit.JUnitUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.ConvertingIterator; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class RunConfigurationModule implements JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.configuration.RunConfigurationModule"); + private static final String ELEMENT = "module"; + private static final String ATTRIBUTE = "name"; + private String myModuleName = ""; + private final Project myProject; + private final boolean myClassesInLibraries; + + public RunConfigurationModule(final Project project, final boolean classesInLibs) { + myProject = project; + myClassesInLibraries = classesInLibs; + } + + public void readExternal(final Element element) throws InvalidDataException { + final List modules = (List)element.getChildren(ELEMENT); + LOG.assertTrue(modules.size() <= 1); + myModuleName = ""; + if (modules.size() == 1) { + final Element module = modules.get(0); + myModuleName = module.getAttributeValue(ATTRIBUTE); + } + } + + public void writeExternal(final Element parent) throws WriteExternalException { + final Element element = new Element(ELEMENT); + element.setAttribute(ATTRIBUTE, getModuleName()); + parent.addContent(element); + } + + public void init() { + if (getModuleName().trim().length() > 0) return; + final Module[] modules = getModuleManager().getModules(); + if (modules.length > 0) setModuleName(modules[0].getName()); + } + + public Project getProject() { return myProject; } + + public Module getModule() { return findModule(getModuleName()); } + + public Module findModule(final String moduleName) { return getModuleManager().findModuleByName(moduleName); } + + public void setModule(final Module module) { setModuleName(module.getName()); } + + public String getModuleName() { return myModuleName != null ? myModuleName : ""; } + + public void setModuleName(final String moduleName) { + myModuleName = moduleName != null ? moduleName : ""; + } + + private ModuleManager getModuleManager() { + return ModuleManager.getInstance(myProject); + } + + public PsiClass findClass(final String qualifiedName) { + if (qualifiedName == null) return null; + return JUnitUtil.findPsiClass(qualifiedName.replace('$', '.'), getModule(), myProject, myClassesInLibraries); + } + + public static Collection getModulesForClass(final Project project, final String className) { + if (project.isDefault()) return Arrays.asList(ModuleManager.getInstance(project).getModules()); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final PsiClass[] possibleClasses = PsiManager.getInstance(project).findClasses(className, + GlobalSearchScope.projectScope(project)); + final HashSet modules = CollectUtil.SKIP_NULLS.toSet(possibleClasses, + ConvertingIterator.composition(ExecutionUtil.FILE_OF_CLASS, + ExecutionUtil.fileToModule(project))); + if (modules.isEmpty()) { + return Arrays.asList(ModuleManager.getInstance(project).getModules()); + } + else { + return ExecutionUtil.collectModulesDependsOn(modules); + } + } + + public void checkForWarning() throws RuntimeConfigurationException { + final Module module = getModule(); + if (module != null) { + if (ModuleRootManager.getInstance(module).getJdk() == null) { + throw new RuntimeConfigurationWarning("No JDK specified for module \"" + module.getName() + "\""); + } + else { + return; + } + }else { + if (myModuleName == null || myModuleName.trim().length() == 0) { + throw new RuntimeConfigurationError("Module not specified"); + } + else { + throw new RuntimeConfigurationError("Module \"" + myModuleName + "\" doesn't exist in project"); + } + } + } + + public PsiClass checkClassName(final String className, final String expectedClassMessage) throws RuntimeConfigurationException { + if (className == null || className.length() == 0) { + throw new RuntimeConfigurationError("No " + expectedClassMessage + " specified"); + } + return findNotNullClass(className); + } + + public PsiClass findNotNullClass(final String className) throws RuntimeConfigurationWarning { + final PsiClass psiClass = findClass(className); + if (psiClass == null) { + throw new RuntimeConfigurationWarning("Class \"" + className + "\" not found in module \"" + + getModuleName() + "\""); + } + return psiClass; + } + + public PsiClass checkModuleAndClassName(final String className, final String expectedClassMessage) throws RuntimeConfigurationException { + checkForWarning(); + return checkClassName(className, expectedClassMessage); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/info/MethodLocation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/info/MethodLocation.java new file mode 100644 index 00000000000..55a801b5d47 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/info/MethodLocation.java @@ -0,0 +1,70 @@ +package com.intellij.execution.junit2.info; + +import com.intellij.execution.Location; +import com.intellij.execution.PsiLocation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; + +import java.util.Iterator; + +// Author: dyoma + +public class MethodLocation extends Location { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.info.MethodLocation"); + private final Project myProject; + private final E myMethod; + private final Location myClassLocation; + + public MethodLocation(final Project project, final E method, final Location classLocation) { + LOG.assertTrue(method != null); + LOG.assertTrue(classLocation != null); + LOG.assertTrue(project != null); + myProject = project; + myMethod = method; + myClassLocation = classLocation; + } + + public static MethodLocation elementInClass(final T psiElement, final PsiClass psiClass) { + final Location classLocation = PsiLocation.fromPsiElement(psiClass); + return new MethodLocation(classLocation.getProject(), psiElement, classLocation); + } + + public E getPsiElement() { + return myMethod; + } + + public Project getProject() { + return myProject; + } + + public PsiClass getContainingClass() { + return myClassLocation.getPsiElement(); + } + + public Iterator> getAncestors(final Class ancestorClass, + final boolean strict) { + final Iterator> fromClass = myClassLocation.getAncestors(ancestorClass, false); + if (strict) return fromClass; + final Location thisLocation = (Location)(Location)this; + return new Iterator>() { + private boolean myFirstStep = ancestorClass.isInstance(myMethod); + public boolean hasNext() { + return myFirstStep || fromClass.hasNext(); + } + + public Location next() { + final Location location; + if (myFirstStep) {location = thisLocation;} + else {location = fromClass.next();} + myFirstStep = false; + return location; + } + + public void remove() { + LOG.assertTrue(false); + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueue.java new file mode 100644 index 00000000000..74dd1eb41a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueue.java @@ -0,0 +1,7 @@ +package com.intellij.execution.junit2.segments; + +public interface DeferedActionsQueue { + void addLast(Runnable runnable); + + void setDispactchListener(DispatchListener listener); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueueImpl.java new file mode 100644 index 00000000000..3fdcb09b183 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DeferedActionsQueueImpl.java @@ -0,0 +1,33 @@ +package com.intellij.execution.junit2.segments; + +import com.intellij.openapi.diagnostic.Logger; + +import java.awt.*; + +public class DeferedActionsQueueImpl implements DeferedActionsQueue { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.segments.DeferedActionsQueueImpl"); + private DispatchListener myListener = DispatchListener.DEAF; + private int myCounter = 0; + + public void addLast(final Runnable runnable) { + checkIsDispatchThread(); + myListener.onStarted(); + try { + runnable.run(); + } finally{ + myListener.onFinished(); + } + } + + private void checkIsDispatchThread() { + myCounter++; + if (myCounter > 127) { + myCounter = 0; + LOG.assertTrue(EventQueue.isDispatchThread()); + } + } + + public void setDispactchListener(final DispatchListener listener) { + myListener = listener; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DispatchListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DispatchListener.java new file mode 100644 index 00000000000..909b9c787fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/DispatchListener.java @@ -0,0 +1,14 @@ +package com.intellij.execution.junit2.segments; + +public interface DispatchListener { + void onStarted(); + void onFinished(); + + DispatchListener DEAF = new DispatchListener() { + public void onStarted() { + } + + public void onFinished() { + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/InputConsumer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/InputConsumer.java new file mode 100644 index 00000000000..0cc90ff2c00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/InputConsumer.java @@ -0,0 +1,12 @@ +package com.intellij.execution.junit2.segments; + +import com.intellij.execution.ui.ConsoleViewContentType; + +public interface InputConsumer { + class DeafInputConsumer implements InputConsumer { + public void onOutput(final String text, final ConsoleViewContentType contentType) { + } + } + DeafInputConsumer DEAF = new DeafInputConsumer(); + void onOutput(String text, ConsoleViewContentType contentType); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/PacketExtractorBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/PacketExtractorBase.java new file mode 100644 index 00000000000..099aa7347ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/PacketExtractorBase.java @@ -0,0 +1,24 @@ +package com.intellij.execution.junit2.segments; + +import com.intellij.rt.execution.junit2.segments.PacketProcessor; + +/** + * @author dyoma + */ +public abstract class PacketExtractorBase { + private DeferedActionsQueue myFulfilledWorkGate = null; + + public void setFulfilledWorkGate(final DeferedActionsQueue fulfilledWorkGate) { + myFulfilledWorkGate = fulfilledWorkGate; + } + + public abstract void setPacketProcessor(PacketProcessor packetProcessor); + + public void setDispatchListener(final DispatchListener listener) { + myFulfilledWorkGate.setDispactchListener(listener); + } + + protected void perform(final Runnable runnable) { + myFulfilledWorkGate.addLast(runnable); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/SegmentReader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/SegmentReader.java new file mode 100644 index 00000000000..ba835f6737d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/segments/SegmentReader.java @@ -0,0 +1,68 @@ +package com.intellij.execution.junit2.segments; + +import com.intellij.rt.execution.junit2.segments.PoolOfDelimiters; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; + +public class SegmentReader implements PoolOfDelimiters { + private final String myString; + private final char[] myChars; + private int myPosition = 0; + + public SegmentReader(final String packet) { + myString = packet; + myChars = packet.toCharArray(); + } + + public String upTo(final char symbol) { + int position = myPosition; + while (position < myChars.length && myChars[position] != symbol) position++; + final String result = advanceTo(position); + skip(1); + return result; + } + + public void skip(final int count) { + myPosition = Math.min(myChars.length, myPosition + count); + } + + public String upToEnd() { + return advanceTo(myChars.length); + } + + private String advanceTo(final int position) { + final String result = myString.substring(myPosition, position); + myPosition = position; + return result; + } + + public String readLimitedString() { + final int symbolCount = readInt(); + return advanceTo(myPosition + symbolCount); + } + + public int readInt() { + final String intString = upTo(INTEGER_DELIMITER); + return Integer.parseInt(intString); + } + + public char readChar() { + myPosition++; + return myChars[myPosition - 1]; + } + + public boolean isAtEnd() { + return myPosition == myChars.length; + } + + public String[] readStringArray() { + final int count = readInt(); + if (count == 0) return ArrayUtil.EMPTY_STRING_ARRAY; + final ArrayList strings = new ArrayList(count); + for (int i = 0; i < count; i++) { + strings.add(readLimitedString()); + } + return strings.toArray(new String[count]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/DiffHyperlink.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/DiffHyperlink.java new file mode 100644 index 00000000000..d6220390da1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/DiffHyperlink.java @@ -0,0 +1,82 @@ +package com.intellij.execution.junit2.states; + +import com.intellij.execution.filters.HyperlinkInfo; +import com.intellij.execution.junit2.Printable; +import com.intellij.execution.junit2.Printer; +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.segments.ObjectReader; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; + +public class DiffHyperlink implements Printable { + private final String myExpected; + private final String myActual; + private final String myFilePath; + + private final HyperlinkInfo myDiffHyperlink = new HyperlinkInfo() { + public void navigate(final Project project) { + openDiff(project); + } + }; + + public void openDiff(final Project project) { + String expectedTitle = "Expected"; + final DiffContent expectedContent; + final VirtualFile vFile; + if (myFilePath != null && (vFile = LocalFileSystem.getInstance().findFileByPath(myFilePath)) != null) { + expectedContent = DiffContent.fromFile(project, vFile); + expectedTitle += " (" + vFile.getPresentableUrl() + ")"; + } else expectedContent = new SimpleContent(myExpected); + final SimpleDiffRequest diffData = new SimpleDiffRequest(project, "assertEquals(String, String) failed"); + diffData.setContents(expectedContent, new SimpleContent(myActual)); + diffData.setContentTitles(expectedTitle, "Actual"); + diffData.addHint(DiffTool.HINT_SHOW_NOT_MODAL_DIALOG); + diffData.setGroupKey("#com.intellij.execution.junit2.states.ComparisonFailureState$DiffDialog"); + DiffManager.getInstance().getIdeaDiffTool().show(diffData); + } + + public DiffHyperlink(final String expected, final String actual, final String filePath) { + myExpected = expected; + myActual = actual; + myFilePath = filePath == null ? null : filePath.replace(File.separatorChar, '/'); + } + + public String getLeft() { + return myExpected; + } + + public String getRight() { + return myActual; + } + + public void printOn(final Printer printer) { + if (hasMoreThanOneLine(myActual) || hasMoreThanOneLine(myExpected)) { + printer.print(" ", ConsoleViewContentType.ERROR_OUTPUT); + printer.printHyperLink("", myDiffHyperlink); + printer.print(TestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + } else { + printer.print(TestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print("Expected:", ConsoleViewContentType.SYSTEM_OUTPUT); + printer.print(myExpected + TestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print("Actual :", ConsoleViewContentType.SYSTEM_OUTPUT); + printer.print(myActual + TestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + } + } + + private static boolean hasMoreThanOneLine(final String string) { + return string.indexOf('\n') != -1; + } + + public static DiffHyperlink readFrom(final ObjectReader reader) { + final String expected = reader.readLimitedString(); + final String actual = reader.readLimitedString(); + final String fileName = reader.isAtEnd() ? null : reader.readLimitedString(); + return new DiffHyperlink(expected, actual, fileName); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/MethodLineLocation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/MethodLineLocation.java new file mode 100644 index 00000000000..3b7432ecda3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/MethodLineLocation.java @@ -0,0 +1,23 @@ +package com.intellij.execution.junit2.states; + +import com.intellij.execution.Location; +import com.intellij.execution.junit2.info.MethodLocation; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; + +public class MethodLineLocation extends MethodLocation { + private final int myLineNumber; + + public MethodLineLocation(final Project project, final PsiMethod method, final Location classLocation, final int lineNumber) { + super(project, method, classLocation); + myLineNumber = lineNumber; + } + + public OpenFileDescriptor getOpenFileDescriptor() { + final VirtualFile virtualFile = getContainingClass().getContainingFile().getVirtualFile(); + return new OpenFileDescriptor(getProject(), virtualFile, myLineNumber, 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/StackTraceLine.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/StackTraceLine.java new file mode 100644 index 00000000000..3ac9218d449 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/states/StackTraceLine.java @@ -0,0 +1,138 @@ +package com.intellij.execution.junit2.states; + +import com.intellij.execution.Location; +import com.intellij.execution.PsiLocation; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; + +public class StackTraceLine { + private Project myProject; + private String myLine; + + public StackTraceLine(Project project, final String line) { + myProject = project; + myLine = line; + } + + public String getClassName() { + int index = myLine.indexOf("at"); + if (index < 0) return null; + index += "at ".length(); + final int lastDot = getLastDot(); + if (lastDot < 0) return null; + if (lastDot <= index) return null; + return myLine.substring(index, lastDot); + } + + private int getLastDot() { + return myLine.lastIndexOf('.', getOpenBracket()); + } + + private int getOpenBracket() { + return myLine.indexOf('('); + } + + private int getCloseBracket() { + return myLine.indexOf(')'); + } + + public int getLineNumber() throws NumberFormatException { + final int close = getCloseBracket(); + final int lineNumberStart = myLine.lastIndexOf(':') + 1; + if (close < 0 || lineNumberStart < 1) throw new NumberFormatException(myLine); + return Integer.parseInt(myLine.substring(lineNumberStart, close)) - 1; + } + + public OpenFileDescriptor getOpenFileDescriptor(final VirtualFile file) { + final int lineNumber; + try { + lineNumber = getLineNumber(); + } catch(NumberFormatException e) { + return new OpenFileDescriptor(myProject, file); + } + return new OpenFileDescriptor(myProject, file, lineNumber, 0); + } + + public OpenFileDescriptor getOpenFileDescriptor(final Project project) { + final Location location = getMethodLocation(project); + if (location == null) return null; + return getOpenFileDescriptor(location.getPsiElement().getContainingFile().getVirtualFile()); + } + + public String getMethodName() { + final int lastDot = getLastDot(); + if (lastDot == -1) return null; + return myLine.substring(getLastDot() + 1, getOpenBracket()); + } + + public Location getMethodLocation(final Project project) { + String className = getClassName(); + final String methodName = getMethodName(); + if (className == null || methodName == null) return null; + final int lineNumber; + try { + lineNumber = getLineNumber(); + } catch(NumberFormatException e) { + return null; + } + final int dollarIndex = className.indexOf('$'); + if (dollarIndex != -1) className = className.substring(0, dollarIndex); + PsiClass psiClass = findClass(project, className, lineNumber); + if (psiClass == null || (psiClass.getNavigationElement() instanceof PsiCompiledElement)) return null; + psiClass = (PsiClass)psiClass.getNavigationElement(); + final PsiMethod psiMethod = getMethodAtLine(psiClass, methodName, lineNumber); + if (psiMethod != null) { + return new MethodLineLocation(project, psiMethod, PsiLocation.fromPsiElement(psiClass), lineNumber); + } + else { + return null; + } + } + + private PsiClass findClass(final Project project, final String className, final int lineNumber) { + if (project == null) return null; + final PsiManager psiManager = PsiManager.getInstance(project); + if (psiManager == null) return null; + PsiClass psiClass = psiManager.findClass(className, GlobalSearchScope.allScope(project)); + if (psiClass == null || (psiClass.getNavigationElement() instanceof PsiCompiledElement)) return null; + psiClass = (PsiClass)psiClass.getNavigationElement(); + final PsiFile psiFile = psiClass.getContainingFile(); + return PsiTreeUtil.getParentOfType(psiFile.findElementAt(offsetOfLine(psiFile, lineNumber)), PsiClass.class, false); + } + + private static PsiMethod getMethodAtLine(final PsiClass psiClass, final String methodName, final int lineNumber) { + final PsiMethod[] methods; + if ("".equals(methodName)) methods = psiClass.getConstructors(); + else methods = psiClass.findMethodsByName(methodName, true); + if (methods.length == 0) return null; + final PsiFile psiFile = methods[0].getContainingFile(); + final int offset = offsetOfLine(psiFile, lineNumber); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (method.getTextRange().contains(offset)) return method; + } + //if (!methods.hasNext() || location == null) return null; + //return location.getPsiElement(); + + //if ("".equals(methodName)) methods = psiClass.getConstructors(); + //else methods = psiClass.findMethodsByName(methodName, true); + //if (methods.length == 0) return null; + //for (int i = 0; i < methods.length; i++) { + // PsiMethod method = methods[i]; + // if (method.getTextRange().contains(offset)) return method; + //} + return null; + } + + private static int offsetOfLine(final PsiFile psiFile, final int lineNumber) { + final LineTokenizer lineTokenizer = new LineTokenizer(psiFile.textToCharArray(), 0, psiFile.getTextLength()); + for (int i = 0; i < lineNumber; i++) lineTokenizer.advance(); + final int offset = lineTokenizer.getOffset(); + return offset; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/FailedTestsNavigator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/FailedTestsNavigator.java new file mode 100644 index 00000000000..fc425e47fbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/FailedTestsNavigator.java @@ -0,0 +1,149 @@ +package com.intellij.execution.junit2.ui; + +import com.intellij.execution.junit2.Filter; +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.ui.model.JUnitAdapter; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.ide.OccurenceNavigator; +import com.intellij.pom.Navigatable; + +import java.util.List; + +public class FailedTestsNavigator implements OccurenceNavigator, TestProxyClient { + private JUnitRunningModel myModel; + private static final String NEXT_NAME = "Next Failed Test"; + private static final String PREVIOUS_NAME = "Previous Failed Test"; + + public boolean hasNextOccurence() { + return myModel != null ? getNextOccurenceInfo().hasNextOccurence() : false; + } + + public boolean hasPreviousOccurence() { + return myModel != null ? getPreviousOccurenceInfo().hasNextOccurence() : false; + } + + public OccurenceNavigator.OccurenceInfo goNextOccurence() { + final FailedTestInfo result = getNextOccurenceInfo(); + myModel.actuallySelectTest(result.getDefect()); + return result.getOccurenceInfo(); + } + + public OccurenceNavigator.OccurenceInfo goPreviousOccurence() { + final FailedTestInfo result = getPreviousOccurenceInfo(); + myModel.actuallySelectTest(result.getDefect()); + return result.getOccurenceInfo(); + } + + public String getNextOccurenceActionName() { + return NEXT_NAME; + } + + public String getPreviousOccurenceActionName() { + return PREVIOUS_NAME; + } + + public void setModel(final JUnitRunningModel model) { + myModel = model; + myModel.addListener(new JUnitAdapter() { + public void doDispose() { + myModel = null; + } + }); + } + + private FailedTestInfo getNextOccurenceInfo() { + return new NextFailedTestInfo().execute(); + } + + private FailedTestInfo getPreviousOccurenceInfo() { + return new PreviousFailedTestInfo().execute(); + } + + abstract class FailedTestInfo { + private TestProxy myDefect = null; + private List myAllTests; + private List myDefects; + + private TestProxy getDefect() { + return myDefect; + } + + private OccurenceNavigator.OccurenceInfo getOccurenceInfo() { + return new OccurenceNavigator.OccurenceInfo(getSourceLocation(), getDefectNumber(), getDefectsCount()); + } + + private int getDefectNumber() { + return myDefect == null ? getDefectsCount() : myDefects.indexOf(myDefect); + } + + private Navigatable getSourceLocation() { + return TestsUIUtil.getOpenFileDescriptor(myDefect, myModel); + } + + public FailedTestInfo execute() { + final int selectionIndex = calculateSelectionIndex(); + if (selectionIndex == -1) + return this; + final TestProxy defect = findNextDefect(selectionIndex); + if (defect == null) + return this; + if (defect != myModel.getSelectedTest()) { + myDefect = defect; + return this; + } + final int defectIndex = myDefects.indexOf(defect); + if (defectIndex == -1 || defectIndex == getBoundIndex()) + return this; + myDefect = (TestProxy)myDefects.get(nextIndex(defectIndex)); + return this; + } + + private TestProxy findNextDefect(final int startIndex) { + for (int i = nextIndex(startIndex); 0 <= i && i < myAllTests.size(); i = nextIndex(i)) { + final TestProxy nextDefect = myAllTests.get(i); + if (Filter.DEFECTIVE_LEAF.shouldAccept(nextDefect)) + return nextDefect; + } + return null; + } + + protected abstract int nextIndex(int defectIndex); + + protected abstract int getBoundIndex(); + + private int calculateSelectionIndex() { + myAllTests = myModel.getRoot().getAllTests(); + myDefects = Filter.DEFECTIVE_LEAF.select(myAllTests); + final int selectionIndex = myAllTests.indexOf(myModel.getSelectedTest()); + return selectionIndex; + } + + protected int getDefectsCount() { + return myDefects.size(); + } + + private boolean hasNextOccurence() { + return myDefect != null; + } + } + + private class NextFailedTestInfo extends FailedTestInfo { + protected int nextIndex(final int defectIndex) { + return defectIndex + 1; + } + + protected int getBoundIndex() { + return getDefectsCount() - 1; + } + } + + private class PreviousFailedTestInfo extends FailedTestInfo { + protected int nextIndex(final int defectIndex) { + return defectIndex - 1; + } + + protected int getBoundIndex() { + return 0; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/PoolOfTestIcons.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/PoolOfTestIcons.java new file mode 100644 index 00000000000..538461e51da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/PoolOfTestIcons.java @@ -0,0 +1,13 @@ +package com.intellij.execution.junit2.ui; + +import javax.swing.*; + +public interface PoolOfTestIcons { + Icon SKIPPED_ICON = TestsUIUtil.loadIcon("testSkipped"); + Icon PASSED_ICON = TestsUIUtil.loadIcon("testPassed"); + Icon FAILED_ICON = TestsUIUtil.loadIcon("testFailed"); + Icon ERROR_ICON = TestsUIUtil.loadIcon("testError"); + Icon NOT_RAN = TestsUIUtil.loadIcon("testNotRan"); + Icon LOADING_ICON = TestsUIUtil.loadIcon("loadingTree"); + Icon TERMINATED_ICON = TestsUIUtil.loadIcon("testTerminated"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestTreeView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestTreeView.java new file mode 100644 index 00000000000..2cd4dcca417 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestTreeView.java @@ -0,0 +1,84 @@ +package com.intellij.execution.junit2.ui; + +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.ui.actions.ViewAssertEqualsDiffAction; +import com.intellij.execution.junit2.ui.model.JUnitAdapter; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.ui.PopupHandler; +import com.intellij.util.ui.Tree; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.containers.Convertor; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.plaf.TreeUI; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +public class TestTreeView extends Tree implements DataProvider, TestProxyClient { + private JUnitRunningModel myModel; + + public void attachToModel(final JUnitRunningModel model) { + setModel(new DefaultTreeModel(new DefaultMutableTreeNode(model.getRoot()))); + getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + myModel = model; + myModel.addListener(new JUnitAdapter() { + public void doDispose() { + setModel(null); + myModel = null; + } + }); + installHandlers(); + setCellRenderer(new TreeTestRenderer(model.getProperties())); + } + + public void setUI(final TreeUI ui) { + super.setUI(ui); + final int fontHeight = getFontMetrics(getFont()).getHeight(); + final int iconHeight = PoolOfTestIcons.PASSED_ICON.getIconHeight(); + setRowHeight(Math.max(fontHeight, iconHeight) + 2); + setLargeModel(true); + } + + public Object getData(final String dataId) { + final TreePath selectionPath = getSelectionPath(); + if (selectionPath == null) return null; + final TestProxy testProxy = TEST_PROXY.from(selectionPath.getLastPathComponent()); + if (testProxy == null) return null; + return TestsUIUtil.getData(testProxy, dataId, myModel); + } + + private void installHandlers() { + EditSourceOnDoubleClickHandler.install(this); + new TreeSpeedSearch(this, new Convertor() { + public String convert(final TreePath path) { + final TestProxy testProxy = TestProxyClient.TEST_PROXY.from(path.getLastPathComponent()); + if (testProxy == null) return null; + return testProxy.getInfo().getName(); + } + }); + TreeToolTipHandler.install(this); + TreeUtil.installActions(this); + installTestTreePopupHandler(this); + ViewAssertEqualsDiffAction.registerShortcut(this); + } + + public String convertValueToText(final Object value, final boolean selected, + final boolean expanded, final boolean leaf, final int row, + final boolean hasFocus) { + return Formatters.printTest(TEST_PROXY.from(value)); + } + + public static void installTestTreePopupHandler(final JComponent component) { + PopupHandler.installPopupHandler(component, + IdeActions.GROUP_TESTTREE_POPUP, + ActionPlaces.TESTTREE_VIEW_POPUP); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestsUIUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestsUIUtil.java new file mode 100644 index 00000000000..9be49cc0e75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/TestsUIUtil.java @@ -0,0 +1,60 @@ +package com.intellij.execution.junit2.ui; + +import com.intellij.execution.Location; +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.info.PsiLocator; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.pom.Navigatable; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; + +public class TestsUIUtil { + public static final Color PASSED_COLOR = new Color(0, 128, 0); + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.TestsUIUtil"); + + private static final String ICONS_ROOT = "/runConfigurations/"; + + public static Object getData(final TestProxy testProxy, final String dataId, final JUnitRunningModel model) { + final Project project = model.getProject(); + if (testProxy == null) return null; + if (dataId == TestProxy.DATA_CONSTANT) return testProxy; + if (dataId == DataConstants.NAVIGATABLE) return getOpenFileDescriptor(testProxy, model); + final PsiLocator testInfo = testProxy.getInfo(); + if (dataId == DataConstants.PSI_ELEMENT) { + final Location location = testInfo.getLocation(project); + return location != null ? location.getPsiElement() : null; + } + if (dataId == Location.LOCATION) return testInfo.getLocation(project); + return null; + } + + public static Navigatable getOpenFileDescriptor(final TestProxy testProxy, final JUnitRunningModel model) { + final Project project = model.getProject(); + final JUnitConsoleProperties properties = model.getProperties(); + if (testProxy != null) { + final Location location = testProxy.getInfo().getLocation(project); + if (JUnitConsoleProperties.OPEN_FAILURE_LINE.value(properties)) + return testProxy.getState().getDescriptor(location); + else return location != null ? location.getOpenFileDescriptor() : null; + } + return null; + } + + public static Icon loadIcon(final String iconName) { + final String fullIconName = ICONS_ROOT + iconName +".png"; + final Icon icon = IconLoader.getIcon(fullIconName); + final Application application = ApplicationManager.getApplication(); + if (application == null || application.isUnitTestMode()) return new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR)); + LOG.assertTrue(icon != null, fullIconName); + return icon; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/TestTreeExpander.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/TestTreeExpander.java new file mode 100644 index 00000000000..5a54a629c52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/TestTreeExpander.java @@ -0,0 +1,47 @@ +package com.intellij.execution.junit2.ui.actions; + +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.ui.model.JUnitAdapter; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.ide.TreeExpander; + +import javax.swing.*; + +class TestTreeExpander implements TreeExpander { + private JUnitRunningModel myModel; + + public void setModel(final JUnitRunningModel model) { + myModel = model; + model.addListener(new JUnitAdapter() { + public void doDispose() { + myModel = null; + } + }); + } + + public void expandAll() { + final JTree treeView = myModel.getTreeView(); + for (int i = 0; i < treeView.getRowCount(); i++) + treeView.expandRow(i); + } + + public boolean canExpand() { + return treeHasMoreThanOneLevel(); + } + + public void collapseAll() { + final TestProxy root = myModel.getRoot(); + for (int i = 0; i < root.getChildCount(); i++) + myModel.collapse(root.getChildAt(i)); + } + + public boolean canCollapse() { + return treeHasMoreThanOneLevel(); + } + + private boolean treeHasMoreThanOneLevel() { + if (myModel == null) + return false; + return myModel.getRoot().hasChildSuites(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/ToolbarPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/ToolbarPanel.java new file mode 100644 index 00000000000..883c442b3cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/actions/ToolbarPanel.java @@ -0,0 +1,122 @@ +package com.intellij.execution.junit2.ui.actions; + +import com.intellij.execution.Location; +import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.ui.FailedTestsNavigator; +import com.intellij.execution.junit2.ui.TestsUIUtil; +import com.intellij.execution.junit2.ui.model.JUnitAdapter; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; +import com.intellij.execution.junit2.ui.properties.ScrollToTestSourceAction; +import com.intellij.ide.OccurenceNavigator; +import com.intellij.ide.actions.CollapseAllToolbarAction; +import com.intellij.ide.actions.ExpandAllToolbarAction; +import com.intellij.ide.actions.NextOccurenceToolbarAction; +import com.intellij.ide.actions.PreviousOccurenceToolbarAction; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.config.ToggleBooleanProperty; + +import javax.swing.*; +import java.awt.*; + +public class ToolbarPanel extends JPanel implements OccurenceNavigator { + //private final DefaultActionGroup myActions = new DefaultActionGroup(null, false); + private final TestTreeExpander myTreeExpander = new TestTreeExpander(); + private final FailedTestsNavigator myOccurenceNavigator = new FailedTestsNavigator(); + private final ScrollToTestSourceAction myScrollToSource; + + public ToolbarPanel(final JUnitConsoleProperties properties) { + super (new BorderLayout()); + add(new JLabel(IconLoader.getIcon("/general/inactiveSeparator.png")), BorderLayout.WEST); + final DefaultActionGroup actionGroup = new DefaultActionGroup(null, false); + actionGroup.addSeparator(); + actionGroup.add(new ToggleBooleanProperty("Hide Passed", + "Hide passed tests", + TestsUIUtil.loadIcon("hidePassed"), + properties, JUnitConsoleProperties.HIDE_PASSED_TESTS)); + actionGroup.add(new ToggleBooleanProperty("Track Running Test", + "Select currently running test in tree", + TestsUIUtil.loadIcon("trackTests"), + properties, JUnitConsoleProperties.TRACK_RUNNING_TEST)); + actionGroup.addSeparator(); + actionGroup.add(new CollapseAllToolbarAction(myTreeExpander, "Collapse all test suites")); + actionGroup.add(new ExpandAllToolbarAction(myTreeExpander, "Expand all test suites")); + actionGroup.addSeparator(); + actionGroup.add(new PreviousOccurenceToolbarAction(myOccurenceNavigator)); + actionGroup.add(new NextOccurenceToolbarAction(myOccurenceNavigator)); + actionGroup.addSeparator(); + actionGroup.add(new ToggleBooleanProperty("Select First Failed Test When Finished", + null, + TestsUIUtil.loadIcon("selectFirstDefect"), + properties, JUnitConsoleProperties.SELECT_FIRST_DEFECT)); + actionGroup.add(new ToggleBooleanProperty("Scroll to Stacktrace", + "Scroll console to beginning of assertion or exception stacktrace", + IconLoader.getIcon("/runConfigurations/scrollToStackTrace.png"), + properties, JUnitConsoleProperties.SCROLL_TO_STACK_TRACE)); + myScrollToSource = new ScrollToTestSourceAction(properties); + actionGroup.add(myScrollToSource); + actionGroup.add(new ToggleBooleanProperty("Open Source at Exception", + "Go to line which caused exception when opening test source", + IconLoader.getIcon("/runConfigurations/sourceAtException.png"), + properties, JUnitConsoleProperties.OPEN_FAILURE_LINE)); + add(ActionManager.getInstance(). + createActionToolbar(ActionPlaces.TESTTREE_VIEW_TOOLBAR, actionGroup, true). + getComponent(), BorderLayout.CENTER); + } + + public void setModel(final JUnitRunningModel model) { + JUnitActions.installFilterAction(model); + myScrollToSource.setModel(model); + RunningTestTracker.install(model); + myTreeExpander.setModel(model); + myOccurenceNavigator.setModel(model); + JUnitActions.installAutoacrollToFirstDefect(model); + model.addListener(new LvcsLabeler(model)); + model.addListener(new JUnitAdapter() { + public void onTestSelected(final TestProxy test) { + if (test == null) return; + final Project project = model.getProject(); + if (!ScrollToTestSourceAction.isScrollEnabled(model)) return; + final Location location = test.getInfo().getLocation(project); + if (location != null) { + final PsiClass aClass = PsiTreeUtil.getParentOfType(location.getPsiElement(), PsiClass.class, false); + if (aClass != null && "junit.framework.TestSuite".equals(aClass.getQualifiedName())) return; + } + final Navigatable descriptor = TestsUIUtil.getOpenFileDescriptor(test, model); + if (descriptor == null) return; + descriptor.navigate(false); + } + }); + } + + public boolean hasNextOccurence() { + return myOccurenceNavigator.hasNextOccurence(); + } + + public boolean hasPreviousOccurence() { + return myOccurenceNavigator.hasPreviousOccurence(); + } + + public OccurenceNavigator.OccurenceInfo goNextOccurence() { + return myOccurenceNavigator.goNextOccurence(); + } + + public OccurenceNavigator.OccurenceInfo goPreviousOccurence() { + return myOccurenceNavigator.goPreviousOccurence(); + } + + public String getNextOccurenceActionName() { + return myOccurenceNavigator.getNextOccurenceActionName(); + } + + public String getPreviousOccurenceActionName() { + return myOccurenceNavigator.getPreviousOccurenceActionName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/JUnitPropertyListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/JUnitPropertyListener.java new file mode 100644 index 00000000000..712fbdf9264 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/JUnitPropertyListener.java @@ -0,0 +1,8 @@ +package com.intellij.execution.junit2.ui.properties; + + + + +public interface JUnitPropertyListener { + void onChanged(T value); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/ScrollToTestSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/ScrollToTestSourceAction.java new file mode 100644 index 00000000000..d4beaa1d340 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/junit2/ui/properties/ScrollToTestSourceAction.java @@ -0,0 +1,36 @@ +package com.intellij.execution.junit2.ui.properties; + +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.config.AbstractProperty; +import com.intellij.util.config.ToggleBooleanProperty; + +public class ScrollToTestSourceAction extends ToggleBooleanProperty.Disablable { + private JUnitRunningModel myModel; + public ScrollToTestSourceAction(final JUnitConsoleProperties properties) { + super("Auto Scroll to Source", + "Open selected test in editor", + IconLoader.getIcon("/general/autoscrollToSource.png"), + properties, JUnitConsoleProperties.SCROLL_TO_SOURCE); + } + + protected boolean isEnabled() { + final AbstractProperty.AbstractPropertyContainer properties = getProperties(); + final JUnitRunningModel model = myModel; + return isEnabled(properties, model); + } + + private static boolean isEnabled(final AbstractProperty.AbstractPropertyContainer properties, final JUnitRunningModel model) { + if (!JUnitConsoleProperties.TRACK_RUNNING_TEST.value(properties)) return true; + return model != null && !model.getStatus().isRunning(); + } + + public static boolean isScrollEnabled(final JUnitRunningModel model) { + final JUnitConsoleProperties properties = model.getProperties(); + return isEnabled(properties, model) && JUnitConsoleProperties.SCROLL_TO_SOURCE.value(properties); + } + + public void setModel(final JUnitRunningModel model) { + myModel = model; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurable.java new file mode 100644 index 00000000000..15418c60fdc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurable.java @@ -0,0 +1,163 @@ +/* + * Class RemoteConfigurable + * @author Jeka + */ +package com.intellij.execution.remote; + +import com.intellij.execution.configurations.RemoteConnection; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.*; + +public class RemoteConfigurable extends SettingsEditor { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.remote.RemoteConfigurable"); + JPanel myPanel; + private JRadioButton myRbSocket; + private JRadioButton myRbShmem; + private JRadioButton myRbListen; + private JRadioButton myRbAttach; + private JTextField myAddressField; + private JTextField myHostField; + private JTextField myPortField; + private JPanel myShmemPanel; + private JPanel mySocketPanel; + private RemoteConfigurationArguments myHelpArea; + private String myHostName = ""; + + public RemoteConfigurable() { + final ButtonGroup transportGroup = new ButtonGroup(); + transportGroup.add(myRbSocket); + transportGroup.add(myRbShmem); + + final ButtonGroup connectionGroup = new ButtonGroup(); + connectionGroup.add(myRbListen); + connectionGroup.add(myRbAttach); + + final DocumentListener helpTextUpdater = new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + updateHelpText(); + } + }; + myAddressField.getDocument().addDocumentListener(helpTextUpdater); + myHostField.getDocument().addDocumentListener(helpTextUpdater); + myPortField.getDocument().addDocumentListener(helpTextUpdater); + myRbSocket.setSelected(true); + final ActionListener listener = new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final Object source = e.getSource(); + if (source.equals(myRbSocket)) { + myShmemPanel.setVisible(false); + mySocketPanel.setVisible(true); + } + else if (source.equals(myRbShmem)) { + myShmemPanel.setVisible(true); + mySocketPanel.setVisible(false); + } + myPanel.repaint(); + updateHelpText(); + } + }; + myRbShmem.addActionListener(listener); + myRbSocket.addActionListener(listener); + + final ItemListener updateListener = new ItemListener() { + public void itemStateChanged(final ItemEvent e) { + final boolean isAttach = myRbAttach.isSelected(); + + if(!isAttach && myHostField.isEditable()) { + myHostName = myHostField.getText(); + } + + myHostField.setEditable(isAttach); + myHostField.setEnabled(isAttach); + + myHostField.setText(isAttach ? myHostName : "localhost"); + updateHelpText(); + } + }; + myRbAttach.addItemListener(updateListener); + myRbListen.addItemListener(updateListener); + + final FocusListener fieldFocusListener = new FocusAdapter() { + public void focusLost(final FocusEvent e) { + updateHelpText(); + } + }; + myAddressField.addFocusListener(fieldFocusListener); + myPortField.addFocusListener(fieldFocusListener); + } + + public void applyEditorTo(final RemoteConfiguration configuration) { + LOG.assertTrue(configuration != null); + final RemoteConfiguration remoteConfiguration = configuration; + remoteConfiguration.HOST = (myHostField.isEditable() ? myHostField.getText() : myHostName).trim(); + if ("".equals(remoteConfiguration.HOST)) { + remoteConfiguration.HOST = null; + } + remoteConfiguration.PORT = myPortField.getText().trim(); + if ("".equals(remoteConfiguration.PORT)) { + remoteConfiguration.PORT = null; + } + remoteConfiguration.SHMEM_ADDRESS = myAddressField.getText().trim(); + if ("".equals(remoteConfiguration.SHMEM_ADDRESS)) { + remoteConfiguration.SHMEM_ADDRESS = null; + } + remoteConfiguration.USE_SOCKET_TRANSPORT = myRbSocket.isSelected(); + remoteConfiguration.SERVER_MODE = myRbListen.isSelected(); + } + + public void resetEditorFrom(final RemoteConfiguration configuration) { + final RemoteConfiguration remoteConfiguration = configuration; + if (!SystemInfo.isWindows) { + remoteConfiguration.USE_SOCKET_TRANSPORT = true; + myRbShmem.setEnabled(false); + myAddressField.setEditable(false); + } + myAddressField.setText(remoteConfiguration.SHMEM_ADDRESS); + myHostName = remoteConfiguration.HOST; + myHostField.setText(remoteConfiguration.HOST); + myPortField.setText(remoteConfiguration.PORT); + if (remoteConfiguration.USE_SOCKET_TRANSPORT) { + myRbSocket.doClick(); + } + else { + myRbShmem.doClick(); + } + if (remoteConfiguration.SERVER_MODE) { + myRbListen.doClick(); + } + else { + myRbAttach.doClick(); + } + myRbShmem.setEnabled(SystemInfo.isWindows); + } + + public JComponent createEditor() { + return myPanel; + } + + public void disposeEditor() { + } + + private void updateHelpText() { + boolean useSockets = !myRbShmem.isSelected(); + + myHelpArea.updateText(new RemoteConnection( + useSockets, + myHostName, + useSockets ? myPortField.getText().trim() : myAddressField.getText().trim(), + myRbListen.isSelected() + )); + } + + + public String getHelpTopic() { + return "project.runDebugRemote"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfiguration.java new file mode 100644 index 00000000000..89154f944c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfiguration.java @@ -0,0 +1,71 @@ +/* + * @author Jeka + */ +package com.intellij.execution.remote; + +import com.intellij.debugger.engine.RemoteStateState; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.impl.GenericDebuggerRunnerSettings; +import com.intellij.execution.configurations.*; +import com.intellij.execution.junit.ModuleBasedConfiguration; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.Collection; + +public class RemoteConfiguration extends ModuleBasedConfiguration { + + public void writeExternal(final Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public void readExternal(final Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public boolean USE_SOCKET_TRANSPORT; + public boolean SERVER_MODE; + public String SHMEM_ADDRESS; + public String HOST; + public String PORT; + + public RemoteConfiguration(final String name, final Project project, ConfigurationFactory configurationFactory) { + super(name, new RunConfigurationModule(project, true), configurationFactory); + } + + public RemoteConnection createRemoteConnection() { + return new RemoteConnection(USE_SOCKET_TRANSPORT, HOST, USE_SOCKET_TRANSPORT ? PORT : SHMEM_ADDRESS, SERVER_MODE); + } + + public RunProfileState getState(final DataContext context, + final RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + GenericDebuggerRunnerSettings debuggerSettings = ((GenericDebuggerRunnerSettings)runnerSettings.getData()); + debuggerSettings.LOCAL = false; + debuggerSettings.setDebugPort(PORT); + debuggerSettings.setTransport(USE_SOCKET_TRANSPORT ? DebuggerSettings.SOCKET_TRANSPORT : DebuggerSettings.SHMEM_TRANSPORT); + return new RemoteStateState(getProject(), createRemoteConnection(), runnerSettings, configurationSettings); + } + + public SettingsEditor getConfigurationEditor() { + return new RemoteConfigurable(); + } + + protected ModuleBasedConfiguration createInstance() { + return new RemoteConfiguration(getName(), getProject(), RemoteConfigurationType.getInstance().getConfigurationFactories()[0]); + } + + public Collection getValidModules() { + return getAllModules(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurationType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurationType.java new file mode 100644 index 00000000000..abb423d5d08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/remote/RemoteConfigurationType.java @@ -0,0 +1,59 @@ +/* + * Class RemoteConfigurationFactory + * @author Jeka + */ +package com.intellij.execution.remote; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class RemoteConfigurationType implements ConfigurationType { + private final ConfigurationFactory myFactory; + private static final Icon ICON = IconLoader.getIcon("/runConfigurations/remote.png"); + + /**reflection*/ + public RemoteConfigurationType() { + myFactory = new ConfigurationFactory(this) { + public RunConfiguration createTemplateConfiguration(Project project) { + return new RemoteConfiguration("", project, this); + } + + }; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "Remote"; + } + + public String getConfigurationTypeDescription() { + return "Remote debug configuration"; + } + + public Icon getIcon() { + return ICON; + } + + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[]{myFactory}; + } + + public String getComponentName() { + return "Remote"; + } + + public static RemoteConfigurationType getInstance() { + return ApplicationManager.getApplication().getComponent(RemoteConfigurationType.class); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyFactoryImpl.java new file mode 100644 index 00000000000..625871dd9d1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyFactoryImpl.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.runners; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.JavaCommandLine; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.configurations.ParametersList; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.openapi.projectRoots.ex.PathUtilEx; + +public class ProcessProxyFactoryImpl extends ProcessProxyFactory { + public ProcessProxy createCommandLineProxy(final JavaCommandLine javaCmdLine) throws ExecutionException { + ProcessProxyImpl proxy = null; + if (ProcessProxyImpl.useLauncher()) { + try { + proxy = new ProcessProxyImpl(); + final JavaParameters javaParameters = javaCmdLine.getJavaParameters(); + PathUtilEx.addRtJar(javaParameters.getClassPath()); + final ParametersList vmParametersList = javaParameters.getVMParametersList(); + vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_PORT_NUMBER, "" + proxy.getPortNumber()); + vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_LIBRARY, ProcessProxyImpl.getLaunchertLibName()); + javaParameters.getProgramParametersList().prepend(javaParameters.getMainClass()); + javaParameters.setMainClass(ProcessProxyImpl.LAUNCH_MAIN_CLASS); + } + catch (ProcessProxyImpl.NoMoreSocketsException e) { + proxy = null; + } + } + return proxy; + } + + public ProcessProxy getAttachedProxy(final ProcessHandler processHandler) { + return processHandler != null ? processHandler.getUserData(ProcessProxyImpl.KEY) : null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyImpl.java new file mode 100644 index 00000000000..7423ca60f82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/ProcessProxyImpl.java @@ -0,0 +1,107 @@ +package com.intellij.execution.runners; + +import com.intellij.execution.process.ProcessHandler; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.SystemInfo; + +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * @author ven + */ + +class ProcessProxyImpl implements ProcessProxy { + public static final Key KEY = Key.create("ProcessProxyImpl"); + private int myPortNumber; + + private static final int SOCKET_NUMBER_START = 7532; + private static final int SOCKET_NUMBER = 100; + private static final boolean[] ourUsedSockets = new boolean[SOCKET_NUMBER]; + + private PrintWriter myWriter; + private Socket mySocket; + private static final String DONT_USE_LAUNCHER_PROPERTY = "idea.no.launcher"; + public static final String PROPERTY_LIBRARY = "idea.launcher.library"; + public static final String PROPERTY_PORT_NUMBER = "idea.launcher.port"; + public static final String LAUNCH_MAIN_CLASS = "com.intellij.rt.execution.application.AppMain"; + + public int getPortNumber() { + return myPortNumber; + } + + public static class NoMoreSocketsException extends Exception { + } + + public ProcessProxyImpl () throws NoMoreSocketsException { + ServerSocket s; + synchronized (ourUsedSockets) { + for (int j = 0; j < SOCKET_NUMBER; j++) { + if (ourUsedSockets[j]) continue; + try { + s = new ServerSocket(j + SOCKET_NUMBER_START); + s.close(); + myPortNumber = j + SOCKET_NUMBER_START; + ourUsedSockets[j] = true; + + return; + } catch (IOException e) { + continue; + } + } + } + throw new NoMoreSocketsException(); + } + + public void finalize () throws Throwable { + if (myWriter != null) { + myWriter.close(); + } + ourUsedSockets[myPortNumber - SOCKET_NUMBER_START] = false; + super.finalize(); + } + + public void attach(final ProcessHandler processHandler) { + processHandler.putUserData(KEY, this); + } + + private synchronized void writeLine (final String s) { + if (myWriter == null) { + try { + if (mySocket == null) mySocket = new Socket(InetAddress.getByName("localhost"), myPortNumber); + myWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mySocket.getOutputStream()))); + } catch (IOException e) { + return; + } + } + myWriter.println(s); + myWriter.flush(); + } + + public void sendBreak () { + writeLine("BREAK"); + } + + public void sendStop () { + writeLine("STOP"); + } + + public static boolean useLauncher() { + if ("true".equals(System.getProperty(DONT_USE_LAUNCHER_PROPERTY))) { + return false; + } + + if (!SystemInfo.isWindows && !SystemInfo.isLinux) { + return false; + } + return new File(getLaunchertLibName()).exists(); + } + + public static String getLaunchertLibName() { + final String libName = SystemInfo.isWindows ? "breakgen.dll" : "libbreakgen.so"; + return PathManager.getBinPath() + File.separator + libName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RestartAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RestartAction.java new file mode 100644 index 00000000000..961f3f9dfea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RestartAction.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.runners; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; + +import javax.swing.*; + +/** + * @author dyoma + */ +public class RestartAction extends AnAction { + private final RunProfile myProfile; + private ProcessHandler myProcessHandler; + private final JavaProgramRunner myRunner; + private final RunContentDescriptor myDescriptor; + private RunnerSettings myRunnerSettings; + private ConfigurationPerRunnerSettings myConfigurationSettings; + + public RestartAction(final JavaProgramRunner runner, + final RunProfile configuration, + final ProcessHandler processHandler, + final Icon icon, + final RunContentDescriptor descritor, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + super(null, null, icon); + myRunnerSettings = runnerSettings; + myConfigurationSettings = configurationSettings; + getTemplatePresentation().setEnabled(false); + myProfile = configuration; + myProcessHandler = processHandler; + myRunner = runner; + myDescriptor = descritor; + } + + public void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + try { + RunStrategy.getInstance().execute(myProfile, new DataContext() { + public Object getData(final String dataId) { + if (RunStrategy.CONTENT_TO_REUSE.equals(dataId)) return myDescriptor; + return dataContext.getData(dataId); + } + }, myRunner, myRunnerSettings, myConfigurationSettings); + } + catch (ExecutionException e1) { + Messages.showErrorDialog(project, e1.getMessage(), "Restart Error"); + } + } + + public void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + presentation.setText("Rerun " + myProfile.getName()); + final boolean isRunning = myProcessHandler != null && !myProcessHandler.isProcessTerminated(); + if (myProcessHandler != null && !isRunning) { + myProcessHandler = null; // already terminated + } + presentation.setEnabled(!isRunning && RunStrategy.getInstance().canExecute(myProfile, myRunner)); + } + + public void registerShortcut(final JComponent component) { + registerCustomShortcutSet(new CustomShortcutSet(KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_RERUN)), component); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RunContentBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RunContentBuilder.java new file mode 100644 index 00000000000..93489540b49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/runners/RunContentBuilder.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.runners; + +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.CloseAction; +import com.intellij.execution.ui.ExecutionConsole; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author dyoma + */ +public class RunContentBuilder { + public static final Icon DEFAULT_RERUN_ICON = IconLoader.getIcon("/actions/refreshUsages.png"); + private final JavaProgramRunner myRunner; + private final Project myProject; + private final ArrayList myDisposeables = new ArrayList(); + private final ArrayList myRunnerActions = new ArrayList(); + private Icon myRerunIcon = DEFAULT_RERUN_ICON; + private boolean myReuseProhibited = false; + private ExecutionResult myExecutionResult; + private JComponent myComponent; + private RunProfile myRunProfile; + private RunnerSettings myRunnerSettings; + private ConfigurationPerRunnerSettings myConfigurationSettings; + + public RunContentBuilder(final Project project, final JavaProgramRunner runner) { + myProject = project; + myRunner = runner; + } + + public ExecutionResult getExecutionResult() { + return myExecutionResult; + } + + public void setExecutionResult(final ExecutionResult executionResult) { + myExecutionResult = executionResult; + } + + public void setRunProfile(final RunProfile runProfile, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + myRunProfile = runProfile; + myRunnerSettings = runnerSettings; + myConfigurationSettings = configurationSettings; + } + + public void addAction(final AnAction action) { + if (action == null) throw new IllegalArgumentException("action"); + myRunnerActions.add(action); + } + + public RunContentDescriptor createDescriptor() { + if (myExecutionResult == null) throw new IllegalStateException("Missing ExecutionResult"); + if (myRunProfile == null) throw new IllegalStateException("Missing RunProfile"); + + final JPanel panel = new JPanel(new BorderLayout(2, 0)); + panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + final MyRunContentDescriptor contentDescriptor = new MyRunContentDescriptor(myRunProfile, myExecutionResult, myReuseProhibited, panel, myDisposeables.toArray(new Disposeable[myDisposeables.size()])); + + if(!ApplicationManager.getApplication().isUnitTestMode()) { + if (myComponent == null) { + final ExecutionConsole console = myExecutionResult.getExecutionConsole(); + if (console != null) myComponent = console.getComponent(); + } + + if (myComponent != null) panel.add(myComponent, BorderLayout.CENTER); + panel.add(createActionToolbar(contentDescriptor, panel), BorderLayout.WEST); + } + + return contentDescriptor; + } + + private JComponent createActionToolbar(final RunContentDescriptor contentDescriptor, final JComponent component) { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + final RestartAction action = new RestartAction(myRunner, myRunProfile, getProcessHandler(), myRerunIcon, contentDescriptor, myRunnerSettings, myConfigurationSettings); + action.registerShortcut(component); + actionGroup.add(action); + + final AnAction[] profileActions = myExecutionResult.getActions(); + for (int i = 0; i < profileActions.length; i++) { + final AnAction profileAction = profileActions[i]; + actionGroup.add(profileAction); + } + + for (Iterator iterator = myRunnerActions.iterator(); iterator.hasNext();) { + final AnAction anAction = iterator.next(); + if (anAction != null) actionGroup.add(anAction); + else actionGroup.addSeparator(); + } + + final AnAction stopAction = ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM); + actionGroup.add(stopAction); + actionGroup.add(new CloseAction(myRunner, contentDescriptor, myProject)); + return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, false).getComponent(); + } + + public ProcessHandler getProcessHandler() { + return myExecutionResult.getProcessHandler(); + } + + /** + * @param reuseContent see {@link RunContentDescriptor#myContent} + */ + public RunContentDescriptor showRunContent(final RunContentDescriptor reuseContent) { + final RunContentDescriptor descriptor = createDescriptor(); + if(reuseContent != null) descriptor.setAttachedContent(reuseContent.getAttachedContent()); + return descriptor; + } + + private static class MyRunContentDescriptor extends RunContentDescriptor { + private final boolean myReuseProhibited; + private final Disposeable[] myAdditionalDisposables; + + public MyRunContentDescriptor(final RunProfile profile, final ExecutionResult executionResult, final boolean reuseProhibited, final JComponent component, final Disposeable[] additionalDisposables) { + super(executionResult.getExecutionConsole(), executionResult.getProcessHandler(), component, profile.getName()); + myReuseProhibited = reuseProhibited; + myAdditionalDisposables = additionalDisposables; + } + + public boolean isContentReuseProhibited() { + return myReuseProhibited; + } + + public void dispose() { + for (int i = 0; i < myAdditionalDisposables.length; i++) { + final Disposeable disposable = myAdditionalDisposables[i]; + disposable.dispose(); + } + super.dispose(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ui/RunContentManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ui/RunContentManagerImpl.java new file mode 100644 index 00000000000..5adf83dbbff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/ui/RunContentManagerImpl.java @@ -0,0 +1,592 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.execution.ui; + +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.TerminateRemoteProcessDialog; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.impl.ToolWindowManagerImpl; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.ListenerUtil; +import com.intellij.ui.content.*; +import com.intellij.util.EventDispatcher; +import com.intellij.util.concurrency.Semaphore; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.util.*; +import java.util.List; + +public class RunContentManagerImpl implements RunContentManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.ui.RunContentManagerImpl"); + public static final Key DESCRIPTOR_KEY = new Key("Descriptor"); + + private Project myProject; + private final Map myToolwindowIdToContentManagerMap = new HashMap(); + + private final Map myListeners = new com.intellij.util.containers.HashMap(); + private final EventDispatcher myEventDispatcher; + private final LinkedList myToolwindowIdZbuffer = new LinkedList(); + + + public RunContentManagerImpl(Project project) { + myProject = project; + myEventDispatcher = EventDispatcher.create(MyRunContentListener.class); + } + + public void init() { + final JavaProgramRunner[] registeredRunners = ExecutionRegistry.getInstance().getRegisteredRunners(); + for (int idx = 0; idx < registeredRunners.length; idx++) { + registerToolwindow(registeredRunners[idx]); + } + + // To ensure ToolwindowManager had already initialized in its projectOpened. + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerAdapter() { + public void stateChanged() { + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + + Set currentWindows = new HashSet(); + String[] toolWindowIds = toolWindowManager.getToolWindowIds(); + + for (int i = 0; i < toolWindowIds.length; i++) { + currentWindows.add(toolWindowIds[i]); + } + myToolwindowIdZbuffer.retainAll(currentWindows); + + final String activeToolWindowId = toolWindowManager.getActiveToolWindowId(); + if (activeToolWindowId != null) { + if (myToolwindowIdZbuffer.remove(activeToolWindowId)) { + myToolwindowIdZbuffer.addFirst(activeToolWindowId); + } + } + } + }); + } + }); + } + + public void dispose() { + final String[] ids = myToolwindowIdToContentManagerMap.keySet().toArray(new String[myToolwindowIdToContentManagerMap.size()]); + for (int idx = 0; idx < ids.length; idx++) { + unregisterToolwindow(ids[idx]); + } + } + + private void unregisterToolwindow(final String id) { + final ToolWindowManager windowManager = ToolWindowManager.getInstance(myProject); + if (windowManager.getToolWindow(id) == null) return; + windowManager.unregisterToolWindow(id); + final ContentManager manager = myToolwindowIdToContentManagerMap.get(id); + manager.removeAllContents(); + myToolwindowIdToContentManagerMap.remove(id); + myToolwindowIdZbuffer.remove(id); + } + + private void registerToolwindow(final JavaProgramRunner runner) { + final String toolWindowId = runner.getInfo().getToolWindowId(); + final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + if (toolWindowManager.getToolWindow(toolWindowId) != null) { + return; + } + + final ContentManager contentManager = PeerFactory.getInstance().getContentFactory().createContentManager(new TabbedPaneContentUI(), true, myProject); + + class MyDataProvider extends JPanel implements DataProvider { + private int myInsideGetData = 0; + + MyDataProvider () { + super(new BorderLayout()); + add(contentManager.getComponent()); + } + + public Object getData(String dataId) { + myInsideGetData ++; + try { + if(DataConstants.HELP_ID.equals(dataId)) { + return runner.getInfo().getHelpId(); + } + else { + return myInsideGetData == 1 ? DataManager.getInstance().getDataContext(contentManager.getComponent()).getData(dataId) : null; + } + } finally { + myInsideGetData--; + } + } + } + final ToolWindow toolWindow = toolWindowManager.registerToolWindow(toolWindowId, new MyDataProvider(), + ToolWindowAnchor.BOTTOM); + toolWindow.setIcon(runner.getInfo().getToolWindowIcon()); + new ContentManagerWatcher(toolWindow, contentManager); + contentManager.addContentManagerListener(new ContentManagerAdapter() { + public void selectionChanged(final ContentManagerEvent event) { + final Content content = event.getContent(); + final RunContentDescriptor descriptor = content != null ? getRunContentDescriptorByContent(content) : null; + myEventDispatcher.getMulticaster().contentSelected(descriptor, toolWindowId); + } + }); + ((ToolWindowManagerImpl)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerAdapter() { + public void stateChanged() { + + } + }); + ListenerUtil.addFocusListener(contentManager.getComponent(), new FocusAdapter() { + public void focusGained(final FocusEvent e) { + } + }); + myToolwindowIdToContentManagerMap.put(toolWindowId, contentManager); + myToolwindowIdZbuffer.addLast(toolWindowId); + } + + public void toFrontRunContent(final RunnerInfo requestor, final ProcessHandler handler) { + final RunContentDescriptor descriptor = getDescriptorBy(handler, requestor); + if (descriptor == null) { + return; + } + toFrontRunContent(requestor, descriptor); + + } + + + private void toFrontRunContent(final RunnerInfo requestor, final RunContentDescriptor descriptor) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final ContentManager contentManager = getContentManagerForRunner(requestor); + + final Content content = getRunContentByDescriptor(contentManager, descriptor); + + if (contentManager != null) { + contentManager.setSelectedContent(content); + + if (content != null) { + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(requestor.getToolWindowId()); + toolWindow.show(null); + } + } + } + }); + } + + public void toFrontRunContent(final JavaProgramRunner requestor, final RunContentDescriptor descriptor) { + toFrontRunContent(requestor.getInfo(), descriptor); + } + + public void hideRunContent(final JavaProgramRunner requestor, final RunContentDescriptor descriptor) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + final String toolWindowId = requestor.getInfo().getToolWindowId(); + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(toolWindowId); + if (toolWindow == null) return; + toolWindow.show(null); + } + }); + } + + public RunContentDescriptor getSelectedContent(final RunnerInfo info) { + final ContentManager contentManager = getContentManagerForRunner(info); + if (contentManager != null) { + final Content selectedContent = contentManager.getSelectedContent(); + if (selectedContent != null) { + final RunContentDescriptor runContentDescriptorByContent = getRunContentDescriptorByContent(selectedContent); + if (runContentDescriptorByContent != null) { + return runContentDescriptorByContent; + } + } + } + return null; + } + + public RunContentDescriptor getSelectedContent() { + final String activeWindow = myToolwindowIdZbuffer.isEmpty() ? null : myToolwindowIdZbuffer.getFirst(); + + if (activeWindow != null) { + final ContentManager contentManager = myToolwindowIdToContentManagerMap.get(activeWindow); + if (contentManager != null) { + final Content selectedContent = contentManager.getSelectedContent(); + if (selectedContent != null) { + final RunContentDescriptor runContentDescriptorByContent = getRunContentDescriptorByContent(selectedContent); + if (runContentDescriptorByContent != null) { + return runContentDescriptorByContent; + } + } + } + } + return null; + } + + public boolean removeRunContent(final JavaProgramRunner requestor, final RunContentDescriptor descriptor) { + final ContentManager contentManager = getContentManagerForRunner(requestor.getInfo()); + final Content content = getRunContentByDescriptor(contentManager, descriptor); + if (content != null) { + return contentManager.removeContent(content); + } + return false; + } + + public void showRunContent(final JavaProgramRunner requestor, final RunContentDescriptor descriptor) { + if(ApplicationManager.getApplication().isUnitTestMode()) return; + + final RunnerInfo runnerInfo = requestor.getInfo(); + LOG.assertTrue(runnerInfo != null); + final ContentManager contentManager = getContentManagerForRunner(runnerInfo); + RunContentDescriptor oldDescriptor = chooseReuseContentForDescriptor(contentManager, descriptor); + + Content content; + + if(oldDescriptor != null) { + content = (Content)oldDescriptor.getAttachedContent(); + myEventDispatcher.getMulticaster().contentRemoved(oldDescriptor, runnerInfo.getToolWindowId()); + oldDescriptor.dispose(); // is of the same category, can be reused + } + else { + content = createNewContent(contentManager, descriptor, runnerInfo.getToolWindowId()); + } + + content.setComponent(descriptor.getComponent()); + content.putUserData(DESCRIPTOR_KEY, descriptor); + content.setDisplayName(descriptor.getDisplayName()); + descriptor.setAttachedContent(content); + content.getManager().setSelectedContent(content); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(runnerInfo.getToolWindowId()); + toolWindow.activate(null); + } + }); + } + + public RunContentDescriptor getReuseContent(final JavaProgramRunner requestor, DataContext dataContext) { + if(ApplicationManager.getApplication().isUnitTestMode()) return null; + RunContentDescriptor runContentDescriptor = (RunContentDescriptor)dataContext.getData(RunStrategy.CONTENT_TO_REUSE); + + if(runContentDescriptor != null) return runContentDescriptor; + + final RunnerInfo runnerInfo = requestor.getInfo(); + LOG.assertTrue(runnerInfo != null); + final ContentManager contentManager = getContentManagerForRunner(runnerInfo); + + return chooseReuseContentForDescriptor(contentManager, runContentDescriptor); + } + + public void showRunContent(JavaProgramRunner requestor, RunContentDescriptor descriptor, RunContentDescriptor contentToReuse) { + if(contentToReuse != null) { + descriptor.setAttachedContent(contentToReuse.getAttachedContent()); + } + showRunContent(requestor, descriptor); + } + + private RunContentDescriptor chooseReuseContentForDescriptor(final ContentManager contentManager, final RunContentDescriptor descriptor) { + Content content = null; + if (descriptor != null) { + final Content attachedContent = descriptor.getAttachedContent(); + if (attachedContent != null && attachedContent.isValid()) content = attachedContent; + } + if (content == null) { + content = contentManager.getSelectedContent(); + if (content != null && content.isPinned()) content = null; + } + if (content == null || !isTerminated(content)) { + return null; + } + final RunContentDescriptor oldDescriptor = getRunContentDescriptorByContent(content); + if (oldDescriptor != null && !oldDescriptor.isContentReuseProhibited()) { + return oldDescriptor; + } + + return null; + } + + private ContentManager getContentManagerForRunner(final RunnerInfo runnerInfo) { + final ContentManager contentManager = myToolwindowIdToContentManagerMap.get(runnerInfo.getToolWindowId()); + LOG.assertTrue(contentManager != null, "Runner " + runnerInfo.getId() + " is not registered"); + return contentManager; + } + + private Content createNewContent(final ContentManager contentManager, final RunContentDescriptor descriptor, String toolWindowId) { + final String processDisplayName = descriptor.getDisplayName(); + final Content content = PeerFactory.getInstance().getContentFactory().createContent(descriptor.getComponent(), processDisplayName, true); + content.putUserData(DESCRIPTOR_KEY, descriptor); + contentManager.addContent(content); + new CloseListener(content, myProject, processDisplayName, toolWindowId); + return content; + } + + private boolean isTerminated(final Content content) { + final RunContentDescriptor descriptor = getRunContentDescriptorByContent(content); + if (descriptor == null) { + return true; + } + else { + final ProcessHandler processHandler = descriptor.getProcessHandler(); + return processHandler != null ? processHandler.isProcessTerminated() : true; + } + } + + private RunContentDescriptor getRunContentDescriptorByContent(final Content content) { + return (RunContentDescriptor)content.getUserData(DESCRIPTOR_KEY); + } + + private Content getRunContentByDescriptor(final ContentManager contentManager, final RunContentDescriptor descriptor) { + final Content[] contents = contentManager.getContents(); + for (int idx = 0; idx < contents.length; idx++) { + final Content content = contents[idx]; + if (descriptor.equals(content.getUserData(DESCRIPTOR_KEY))) { + return content; + } + } + return null; + } + + public void addRunContentListener(final RunContentListener listener, final RunnerInfo runnerInfo) { + myEventDispatcher.addListener(new MyRunContentListener() { + public void contentSelected(RunContentDescriptor descriptor, String toolwindowId) { + if(toolwindowId.equals(runnerInfo.getToolWindowId())) { + listener.contentSelected(descriptor); + } + } + + public void contentRemoved(RunContentDescriptor descriptor, String toolwindowId) { + if(toolwindowId.equals(runnerInfo.getToolWindowId())) { + listener.contentRemoved(descriptor); + } + } + }); + } + + public void addRunContentListener(final RunContentListener listener) { + MyRunContentListener windowedListener = new MyRunContentListener() { + public void contentSelected(RunContentDescriptor descriptor, String ToolwindowId) { + listener.contentSelected(descriptor); + } + + public void contentRemoved(RunContentDescriptor descriptor, String ToolwindowId) { + listener.contentRemoved(descriptor); + } + }; + myEventDispatcher.addListener(windowedListener); + myListeners.put(listener, windowedListener); + } + + public RunContentDescriptor[] getAllDescriptors() { + final List descriptors = new ArrayList(); + final String[] ids = myToolwindowIdToContentManagerMap.keySet().toArray(new String[myToolwindowIdToContentManagerMap.size()]); + for (int i = 0; i < ids.length; i++) { + final ContentManager contentManager = myToolwindowIdToContentManagerMap.get(ids[i]); + final Content[] contents = contentManager.getContents(); + for (int idx = 0; idx < contents.length; idx++) { + final Content content = contents[idx]; + final RunContentDescriptor descriptor = getRunContentDescriptorByContent(content); + if (descriptor != null) { + descriptors.add(descriptor); + } + } + } + + return descriptors.toArray(new RunContentDescriptor[descriptors.size()]); + } + + public void removeRunContentListener(final RunContentListener listener) { + MyRunContentListener contentListener = myListeners.remove(listener); + myEventDispatcher.removeListener(contentListener); + } + + private RunContentDescriptor getDescriptorBy(ProcessHandler handler, RunnerInfo runnerInfo) { + ContentManager contentManager = getContentManagerForRunner(runnerInfo); + Content[] contents = contentManager.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + RunContentDescriptor runContentDescriptor = (RunContentDescriptor)content.getUserData(DESCRIPTOR_KEY); + if (runContentDescriptor.getProcessHandler() == handler) { + return runContentDescriptor; + } + } + return null; + } + + private class CloseListener extends ContentManagerAdapter implements ProjectManagerListener { + private final Project myProject; + private Content myContent; + private final String myProcessDisplayName; + private final String myToolwindowId; + + public CloseListener(final Content content, final Project project, final String processDisplayName, String toolWindowId) { + myContent = content; + myProject = project; + content.getManager().addContentManagerListener(this); + ProjectManager.getInstance().addProjectManagerListener(this); + myProcessDisplayName = processDisplayName; + myToolwindowId = toolWindowId; + } + + public void contentRemoved(final ContentManagerEvent event) { + final Content content = event.getContent(); + if (content == myContent) { + dispose(); + } + } + + private void dispose() { + if (myContent == null) return; + + final Content content = myContent; + try { + final RunContentDescriptor descriptor = getRunContentDescriptorByContent(content); + + myEventDispatcher.getMulticaster().contentRemoved(descriptor, myToolwindowId); + + descriptor.dispose(); + } + finally { + content.getManager().removeContentManagerListener(this); + ProjectManager.getInstance().removeProjectManagerListener(this); + content.release(); // don't invoke myContent.release() because myContent becomes null after destroyProcess() + myContent = null; + } + } + + public void contentRemoveQuery(final ContentManagerEvent event) { + if (event.getContent() == myContent) { + final boolean canClose = closeQuery(); + if (!canClose) { + event.consume(); + } + } + } + + public void projectOpened(final Project project) { + } + + public void projectClosed(final Project project) { + if (myContent != null && project == myProject) { + myContent.getManager().removeContent(myContent); + dispose(); // Dispose content even if content manager refused to. + } + } + + public boolean canCloseProject(final Project project) { + if (project != myProject) return true; + + if (myContent == null) return true; + + final boolean canClose = closeQuery(); + if (canClose) { + final Content content = myContent; + content.getManager().removeContent(content); + myContent = null; + } + return canClose; + } + + public void projectClosing(final Project project) { + } + + private boolean closeQuery() { + final RunContentDescriptor descriptor = getRunContentDescriptorByContent(myContent); + + if (descriptor == null) { + return true; + } + + final ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler == null || processHandler.isProcessTerminated()) { + return true; + } + + final TerminateRemoteProcessDialog terminateDialog = new TerminateRemoteProcessDialog(myProject, myProcessDisplayName, + processHandler.detachIsDefault()); + terminateDialog.show(); + + if (terminateDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + if (terminateDialog.forceTermination()) { + processHandler.destroyProcess(); + } + else { + processHandler.detachProcess(); + } + waitForProcess(descriptor); + return true; + } + + return false; + } + } + + public void waitForProcess(final RunContentDescriptor descriptor) { + String progressTitle = "Terminating " + "'" + descriptor.getDisplayName() + "'"; + + ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() { + private ProgressIndicator myProgressIndicator; + private Semaphore mySemaphore = new Semaphore(); + + private Thread myWaitThread = new Thread() { + public void run() { + descriptor.getProcessHandler().waitFor(); + mySemaphore.up(); + } + }; + + private Thread myCancelListener = new Thread() { + public void run() { + for(;;) { + if(myProgressIndicator.isCanceled() || !myProgressIndicator.isRunning()) { + mySemaphore.up(); + break; + } + try { + synchronized (this) { + wait(2000); + } + } + catch (InterruptedException e) { + } + } + } + }; + + public void run() { + myProgressIndicator = ProgressManager.getInstance().getProgressIndicator(); + myProgressIndicator.setText("Waiting for VM detach"); + + myWaitThread.start(); + myCancelListener.start(); + + mySemaphore.down(); + mySemaphore.waitFor(); + } + }, progressTitle, true, myProject); + } + + public static interface MyRunContentListener extends EventListener { + void contentSelected(RunContentDescriptor descriptor, String toolwindowId); + void contentRemoved (RunContentDescriptor descriptor, String toolwindowId); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/JavaParametersUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/JavaParametersUtil.java new file mode 100644 index 00000000000..17cf55541c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/JavaParametersUtil.java @@ -0,0 +1,35 @@ +package com.intellij.execution.util; + +import com.intellij.execution.CantRunException; +import com.intellij.execution.RunJavaConfiguration; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.junit2.configuration.RunConfigurationModule; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PathUtil; + +/** + * User: lex + * Date: Nov 26, 2003 + * Time: 10:38:01 PM + */ +public class JavaParametersUtil { + public static void configureConfiguration(final JavaParameters parameters, final RunJavaConfiguration configuration) { + parameters.getProgramParametersList().addParametersString(configuration.getProperty(RunJavaConfiguration.PROGRAM_PARAMETERS_PROPERTY)); + parameters.getVMParametersList().addParametersString(configuration.getProperty(RunJavaConfiguration.VM_PARAMETERS_PROPERTY)); + String workingDirectory = configuration.getProperty(RunJavaConfiguration.WORKING_DIRECTORY_PROPERTY); + if (workingDirectory == null || workingDirectory.trim().length() == 0) { + final VirtualFile projectFile = configuration.getProject().getProjectFile(); + if (projectFile != null) { + workingDirectory = PathUtil.getLocalPath(projectFile.getParent()); + } + } + parameters.setWorkingDirectory(workingDirectory); + } + + public static void configureModule(final RunConfigurationModule runConfigurationModule, final JavaParameters parameters, final int classPathType) throws CantRunException { + if(runConfigurationModule.getModule() == null) { + throw CantRunException.noModuleConfigured(runConfigurationModule.getModuleName()); + } + parameters.configureByModule(runConfigurationModule.getModule(), classPathType); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/RefactoringElementListenerComposite.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/RefactoringElementListenerComposite.java new file mode 100644 index 00000000000..f4a3b0805fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/RefactoringElementListenerComposite.java @@ -0,0 +1,30 @@ +package com.intellij.execution.util; + +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; + +import java.util.ArrayList; + +public class RefactoringElementListenerComposite implements RefactoringElementListener { + private ArrayList myListeners; + + public RefactoringElementListenerComposite(){ + myListeners = new ArrayList(); + } + + public void addListener(final RefactoringElementListener listener){ + myListeners.add(listener); + } + + public void elementMoved(final PsiElement newElement){ + for (int i = 0; i < myListeners.size(); i++) { + myListeners.get(i).elementMoved(newElement); + } + } + + public void elementRenamed(final PsiElement newElement){ + for (int i = 0; i < myListeners.size(); i++) { + (myListeners.get(i)).elementRenamed(newElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/StoringPropertyContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/StoringPropertyContainer.java new file mode 100644 index 00000000000..fa14313830c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/execution/util/StoringPropertyContainer.java @@ -0,0 +1,50 @@ +package com.intellij.execution.util; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.util.config.AbstractProperty; +import com.intellij.util.config.Storage; + +import java.util.HashMap; + +public class StoringPropertyContainer extends AbstractProperty.AbstractPropertyContainer> { + private final HashMap, Boolean> myValues = new HashMap, Boolean>(); + private final Storage myStorage; + + public StoringPropertyContainer(final String groupName, final PropertiesComponent propertiesComponent) { + this(new Storage.PropertiesComponentStorage(groupName, propertiesComponent)); + } + + public StoringPropertyContainer(final Storage storage) { + myStorage = storage; + } + + protected void setValueOf(final AbstractProperty property, final Object value) { + myValues.put(property, (Boolean)value); + onPropertyChanged(property, (Boolean)value); + myStorage.put(property.getName(), stringValue(value)); + } + + private String stringValue(final Object value) { + return value.toString(); + } + + public boolean hasProperty(final AbstractProperty property) { + return myValues.containsKey(property); + } + + protected Object getValueOf(final AbstractProperty property) { + Object value = myValues.get(property); + if (value == null) { + final String stringValue = myStorage.get(property.getName()); + value = stringValue != null ? parseValue(stringValue) : property.getDefault(this); + myValues.put(property, (Boolean)value); + } + return value; + } + + private Boolean parseValue(final String stringValue) { + return Boolean.valueOf(stringValue); + } + + protected void onPropertyChanged(final AbstractProperty property, final T value) {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ApplicabilityFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ApplicabilityFilter.java new file mode 100644 index 00000000000..8ac6f4e26da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ApplicabilityFilter.java @@ -0,0 +1,7 @@ +package com.intellij.featureStatistics; + +import com.intellij.openapi.project.Project; + +public interface ApplicabilityFilter { + boolean isApplicable(String featureId, Project project); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/FeatureUsageTracker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/FeatureUsageTracker.java new file mode 100644 index 00000000000..516a1771cee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/FeatureUsageTracker.java @@ -0,0 +1,187 @@ +package com.intellij.featureStatistics; + +import com.intellij.featureStatistics.ui.ProgressTipPanel; +import com.intellij.ide.TipOfTheDayManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressFunComponentProvider; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class FeatureUsageTracker implements ApplicationComponent, NamedJDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.featureStatistics.FeatureUsageTracker"); + + private static final long DAY = 1000 * 60 * 60 * 24; + private long FIRST_RUN_TIME = 0; + private boolean HAVE_BEEN_SHOWN = false; + + public boolean SHOW_IN_COMPILATION_PROGRESS = true; + public boolean SHOW_IN_OTHER_PROGRESS = true; + private ProductivityFeaturesRegistry myRegistry; + + public static FeatureUsageTracker getInstance() { + return ApplicationManager.getApplication().getComponent(FeatureUsageTracker.class); + } + + public FeatureUsageTracker(ProgressManager progressManager, ProductivityFeaturesRegistry productivityFeaturesRegistry) { + myRegistry = productivityFeaturesRegistry; + progressManager.registerFunComponentProvider(new ProgressFunProvider()); + } + + public String getComponentName() { + return "FeatureUsageStatistics"; + } + + public void initComponent() { } + + private String[] getFeaturesToShow(Project project) { + List result = new ArrayList(); + ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + Set ids = registry.getFeatureIds(); + for (Iterator iterator = ids.iterator(); iterator.hasNext();) { + String id = iterator.next(); + if (isToBeShown(id, project)) { + result.add(id); + } + } + return result.toArray(new String[result.size()]); + } + + private boolean isToBeShown(String featureId, Project project) { + ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + FeatureDescriptor descriptor = registry.getFeatureDescriptor(featureId); + if (!descriptor.isUnused()) return false; + + String[] dependencyFeatures = descriptor.getDependencyFeatures(); + boolean locked = dependencyFeatures.length > 0; + for (int i = 0; locked && i < dependencyFeatures.length; i++) { + if (!registry.getFeatureDescriptor(dependencyFeatures[i]).isUnused()) { + locked = false; + } + } + if (locked) return false; + + ApplicabilityFilter[] filters = registry.getMatchingFilters(featureId); + for (int i = 0; i < filters.length; i++) { + ApplicabilityFilter filter = filters[i]; + if (!filter.isApplicable(featureId, project)) return false; + } + + long current = System.currentTimeMillis(); + long succesive_interval = descriptor.getDaysBetweenSuccesiveShowUps() * DAY + descriptor.getShownCount() * 2; + long firstShowUpInterval = descriptor.getDaysBeforeFirstShowUp() * DAY; + long lastTimeUsed = descriptor.getLastTimeUsed(); + long lastTimeShown = descriptor.getLastTimeShown(); + return lastTimeShown == 0 && firstShowUpInterval + getFirstRunTime() < current || + lastTimeShown > 0 && current - lastTimeShown > succesive_interval && current - lastTimeUsed > succesive_interval; + } + + public long getFirstRunTime() { + if (FIRST_RUN_TIME == 0) { + FIRST_RUN_TIME = System.currentTimeMillis(); + } + return FIRST_RUN_TIME; + } + + public void disposeComponent() { + } + + public String getExternalFileName() { + return "feature.usage.statistics"; + } + + public void readExternal(Element element) throws InvalidDataException { + List featuresList = element.getChildren("feature"); + for (int i = 0; i < featuresList.size(); i++) { + Element featureElement = (Element)featuresList.get(i); + FeatureDescriptor descriptor = myRegistry.getFeatureDescriptor(featureElement.getAttributeValue("id")); + if (descriptor != null) { + descriptor.readStatistics(featureElement); + } + } + + try { + FIRST_RUN_TIME = Long.parseLong(element.getAttributeValue("first-run")); + } + catch (NumberFormatException e) { + FIRST_RUN_TIME = 0; + } + + HAVE_BEEN_SHOWN = Boolean.valueOf(element.getAttributeValue("have-been-shown")).booleanValue(); + SHOW_IN_OTHER_PROGRESS = Boolean.valueOf(element.getAttributeValue("show-in-other", "true")).booleanValue(); + SHOW_IN_COMPILATION_PROGRESS = Boolean.valueOf(element.getAttributeValue("show-in-compilation", "true")).booleanValue(); + } + + public void writeExternal(Element element) throws WriteExternalException { + ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + Set ids = registry.getFeatureIds(); + for (Iterator iterator = ids.iterator(); iterator.hasNext();) { + String id = iterator.next(); + Element featureElement = new Element("feature"); + featureElement.setAttribute("id", id); + FeatureDescriptor descriptor = registry.getFeatureDescriptor(id); + descriptor.writeStatistics(featureElement); + element.addContent(featureElement); + } + + element.setAttribute("first-run", String.valueOf(getFirstRunTime())); + element.setAttribute("have-been-shown", String.valueOf(HAVE_BEEN_SHOWN)); + element.setAttribute("show-in-other", String.valueOf(SHOW_IN_OTHER_PROGRESS)); + element.setAttribute("show-in-compilation", String.valueOf(SHOW_IN_COMPILATION_PROGRESS)); + } + + public void triggerFeatureUsed(String featureId) { + if (ApplicationManager.getApplication().isUnitTestMode()) return; + ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + FeatureDescriptor descriptor = registry.getFeatureDescriptor(featureId); + if (descriptor == null) { + // TODO: LOG.error("Feature '" + featureId +"' must be registered prior triggerFeatureUsed() is called"); + } + else { + descriptor.triggerUsed(); + } + } + + public void triggerFeatureShown(String featureId) { + FeatureDescriptor descriptor = ProductivityFeaturesRegistry.getInstance().getFeatureDescriptor(featureId); + if (descriptor != null) { + descriptor.triggerShown(); + } + } + + private final class ProgressFunProvider implements ProgressFunComponentProvider { + public JComponent getProgressFunComponent(Project project, String processId) { + if ("compilation".equals(processId)) { + if (!SHOW_IN_COMPILATION_PROGRESS) return null; + } + else { + if (!SHOW_IN_OTHER_PROGRESS) return null; + } + + String[] features = getFeaturesToShow(project); + if (features.length > 0) { + if (!HAVE_BEEN_SHOWN) { + HAVE_BEEN_SHOWN = true; + String[] newFeatures = new String[features.length + 1]; + newFeatures[0] = ProductivityFeaturesRegistry.WELCOME; + System.arraycopy(features, 0, newFeatures, 1, features.length); + features = newFeatures; + } + TipOfTheDayManager.getInstance().doNotShowThisTime(); + return new ProgressTipPanel(features, project).getComponent(); + } + return null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/GroupDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/GroupDescriptor.java new file mode 100644 index 00000000000..c5632baabea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/GroupDescriptor.java @@ -0,0 +1,21 @@ +package com.intellij.featureStatistics; + +import org.jdom.Element; + +public class GroupDescriptor { + private String myId; + private String myDisplayName; + + public void readExternal(Element element) { + myId = element.getAttributeValue("id"); + myDisplayName = element.getAttributeValue("name"); + } + + public String getId() { + return myId; + } + + public String getDisplayName() { + return myDisplayName; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java new file mode 100644 index 00000000000..e0473a5d303 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java @@ -0,0 +1,21 @@ +package com.intellij.featureStatistics.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +public class ShowFeatureUsageStatisticsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + new ShowFeatureUsageStatisticsDialog(getProject(e)).show(); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(getProject(e) != null); + } + + private Project getProject(AnActionEvent e) { + return (Project)e.getDataContext().getData(DataConstants.PROJECT); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java new file mode 100644 index 00000000000..c7705c4587b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java @@ -0,0 +1,205 @@ +package com.intellij.featureStatistics.actions; + +import com.intellij.featureStatistics.FeatureDescriptor; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.featureStatistics.ProductivityFeaturesRegistry; +import com.intellij.ide.util.TipUIUtil; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.table.TableView; +import com.intellij.util.text.DateFormatUtil; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.io.StringReader; +import java.util.*; + +public class ShowFeatureUsageStatisticsDialog extends DialogWrapper { + private static final Comparator DISPLAY_NAME_COMPARATOR = new Comparator() { + public int compare(FeatureDescriptor fd1, FeatureDescriptor fd2) { + return fd1.getDisplayName().compareTo(fd2.getDisplayName()); + } + }; + private static final Comparator GROUP_NAME_COMPARATOR = new Comparator() { + public int compare(FeatureDescriptor fd1, FeatureDescriptor fd2) { + return getGroupName(fd1).compareTo(getGroupName(fd2)); + } + }; + private static final Comparator USAGE_COUNT_COMPARATOR = new Comparator() { + public int compare(FeatureDescriptor fd1, FeatureDescriptor fd2) { + return fd1.getUsageCount() - fd2.getUsageCount(); + } + }; + private static final Comparator LAST_USED_COMPARATOR = new Comparator() { + public int compare(FeatureDescriptor fd1, FeatureDescriptor fd2) { + return new Date(fd2.getLastTimeUsed()).compareTo(new Date(fd1.getLastTimeUsed())); + } + }; + private static final Comparator FREQUENCY_COMPARATOR = new Comparator() { + public int compare(FeatureDescriptor fd1, FeatureDescriptor fd2) { + return new Date(fd1.getAverageFrequency()).compareTo(new Date(fd2.getAverageFrequency())); + } + }; + + private static final ColumnInfo DISPLAY_NAME = new ColumnInfo("Feature") { + public String valueOf(FeatureDescriptor featureDescriptor) { + return featureDescriptor.getDisplayName(); + } + + public Comparator getComparator() { + return DISPLAY_NAME_COMPARATOR; + } + }; + private static final ColumnInfo GROUP_NAME = new ColumnInfo("Group") { + public String valueOf(FeatureDescriptor featureDescriptor) { + return getGroupName(featureDescriptor); + } + + public Comparator getComparator() { + return GROUP_NAME_COMPARATOR; + } + }; + private static final ColumnInfo USED_TOTAL = new ColumnInfo("Used") { + public String valueOf(FeatureDescriptor featureDescriptor) { + int count = featureDescriptor.getUsageCount(); + if (count == 0) return "Never"; + if (count == 1) return "Once"; + if (count == 2) return "Twice"; + return String.valueOf(count) + " times"; + } + + public Comparator getComparator() { + return USAGE_COUNT_COMPARATOR; + } + }; + private static final ColumnInfo LAST_USED = new ColumnInfo("Last used") { + public String valueOf(FeatureDescriptor featureDescriptor) { + long tm = featureDescriptor.getLastTimeUsed(); + if (tm <= 0) return "N/A"; + return DateFormatUtil.formatBetweenDates(tm, System.currentTimeMillis()); + } + + public Comparator getComparator() { + return LAST_USED_COMPARATOR; + } + }; + private static final ColumnInfo USAGE_FREQUENCY = new ColumnInfo("Average usage frequency") { + public String valueOf(FeatureDescriptor featureDescriptor) { + long tm = featureDescriptor.getAverageFrequency(); + if (tm <= 0) return "N/A"; + return "Once " + DateFormatUtil.formatBetweenDates(tm, 0); + } + + public Comparator getComparator() { + return FREQUENCY_COMPARATOR; + } + }; + + private static final ColumnInfo[] COLUMNS = new ColumnInfo[]{DISPLAY_NAME, GROUP_NAME, USED_TOTAL, LAST_USED, USAGE_FREQUENCY}; + + public ShowFeatureUsageStatisticsDialog(Project project) { + super(project, true); + setTitle("Productivity Guide"); + setCancelButtonText("Close"); + init(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.featureStatistics.actions.ShowFeatureUsageStatisticsDialog"; + } + + protected Action[] createActions() { + return new Action[] {getCancelAction(), getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("editing.productivityGuide"); + } + + protected JComponent createCenterPanel() { + Splitter splitter = new Splitter(true); + splitter.setShowDividerControls(true); + + ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + Set ids = registry.getFeatureIds(); + ArrayList features = new ArrayList(); + for (Iterator iterator = ids.iterator(); iterator.hasNext();) { + String id = iterator.next(); + features.add(registry.getFeatureDescriptor(id)); + } + final TableView table = new TableView(new ListTableModel(COLUMNS, features, 0)); + + JPanel controlsPanel = new JPanel(new VerticalFlowLayout()); + + + Application app = ApplicationManager.getApplication(); + long uptime = System.currentTimeMillis() - app.getStartTime(); + long idletime = app.getIdleTime(); + controlsPanel.add(new JLabel("IDEA uptime: " + DateFormatUtil.formatDuration(uptime) + ", idle time: " + DateFormatUtil.formatDuration(idletime)), BorderLayout.NORTH); + + final JCheckBox compiler = new JCheckBox("Show productivity hints while compiling"); + compiler.setSelected(FeatureUsageTracker.getInstance().SHOW_IN_COMPILATION_PROGRESS); + compiler.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FeatureUsageTracker.getInstance().SHOW_IN_COMPILATION_PROGRESS = compiler.isSelected(); + } + }); + + final JCheckBox other = new JCheckBox("Show productivity hints during startup or other lengthy processes"); + other.setSelected(FeatureUsageTracker.getInstance().SHOW_IN_OTHER_PROGRESS); + other.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FeatureUsageTracker.getInstance().SHOW_IN_OTHER_PROGRESS = other.isSelected(); + } + }); + + controlsPanel.add(compiler); + controlsPanel.add(other); + + JPanel topPanel = new JPanel(new BorderLayout()); + topPanel.add(controlsPanel, BorderLayout.NORTH); + topPanel.add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER); + + splitter.setFirstComponent(topPanel); + + final JEditorPane browser = new JEditorPane("text/html", ""); + splitter.setSecondComponent(ScrollPaneFactory.createScrollPane(browser)); + + table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + Collection selection = table.getSelection(); + try { + if (selection.isEmpty()) { + browser.read(new StringReader(""), null); + } + else { + FeatureDescriptor feature = (FeatureDescriptor)selection.iterator().next(); + TipUIUtil.openTipInBrowser(feature.getTipFileName(), browser); + } + } + catch (IOException ex) { + } + } + }); + + return splitter; + } + + private static String getGroupName(FeatureDescriptor featureDescriptor) { + return ProductivityFeaturesRegistry.getInstance().getGroupDescriptor(featureDescriptor.getGroupId()).getDisplayName(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/AdaptiveTipDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/AdaptiveTipDialog.java new file mode 100644 index 00000000000..0467ab4fa79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/AdaptiveTipDialog.java @@ -0,0 +1,88 @@ +package com.intellij.featureStatistics.ui; + +import com.intellij.featureStatistics.FeatureDescriptor; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.featureStatistics.ProductivityFeaturesRegistry; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ide.util.TipUIUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.IOException; + +public class AdaptiveTipDialog extends DialogWrapper { + private static final int DEFAULT_WIDTH = 400; + private static final int DEFAULT_HEIGHT = 200; + + private JEditorPane myBrowser; + private String[] myFeatures; + private int myCurrentFeature; + + public AdaptiveTipDialog(Project project, String[] features) { + super(project, false); + myFeatures = features; + myCurrentFeature = 0; + setCancelButtonText("&Close"); + setTitle("Adaptive Tip Of The Day"); + setModal(false); + init(); + selectCurrentFeature(); + } + + private void selectCurrentFeature() { + String id = myFeatures[myCurrentFeature]; + FeatureUsageTracker.getInstance().triggerFeatureShown(id); + + FeatureDescriptor feature = ProductivityFeaturesRegistry.getInstance().getFeatureDescriptor(id); + TipUIUtil.openTipInBrowser(feature.getTipFileName(), myBrowser); + } + + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myBrowser = new JEditorPane("text/html", "Tip go here"); + panel.add(new JScrollPane(myBrowser)); + panel.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); + return panel; + } + + protected Action[] createActions() { + if (myFeatures.length == 1) { + return new Action[] {getCancelAction()}; + } + else { + return new Action[] {new PrevAction(), new NextAction(), getCancelAction()}; + } + } + + private class NextAction extends AbstractAction{ + public NextAction() { + super("&Next Tip"); + } + + public void actionPerformed(ActionEvent e) { + myCurrentFeature++; + if (myCurrentFeature >= myFeatures.length) { + myCurrentFeature = 0; + } + selectCurrentFeature(); + } + } + + private class PrevAction extends AbstractAction{ + public PrevAction() { + super("&Prev Tip"); + } + + public void actionPerformed(ActionEvent e) { + myCurrentFeature--; + if (myCurrentFeature < 0) { + myCurrentFeature = myFeatures.length - 1; + } + selectCurrentFeature(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/ProgressTipPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/ProgressTipPanel.java new file mode 100644 index 00000000000..1df76316176 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/featureStatistics/ui/ProgressTipPanel.java @@ -0,0 +1,153 @@ +package com.intellij.featureStatistics.ui; + +import com.intellij.featureStatistics.FeatureDescriptor; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.featureStatistics.ProductivityFeaturesRegistry; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.ide.util.TipUIUtil; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.Alarm; + +import javax.swing.*; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ProgressTipPanel { + private JEditorPane myBrowser; + private JButton myNextHintButton; + private JButton myPrevHintButton; + private JPanel myPanel; + + private String[] myFeatures; + private Project myProject; + private int myCurrentFeature; + private JLabel myLabel; + + private final Alarm myMarkReadAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private static final int MARK_READ_DELAY = 10 * 1000; + private Runnable myLastRequest; + private JButton myCloseButton; + private JCheckBox myKeepOpen; + private static final String KEEP_OPTION_NAME = "KEEP_PRODUCTIVITY_HINTS"; + private boolean myIsShownIsOwnDialog = false; + + public ProgressTipPanel(String[] features, final Project project) { + myFeatures = features; + myProject = project; + myCurrentFeature = 0; + myBrowser.setContentType("text/html"); + myBrowser.setPreferredSize(new Dimension(500, 200)); + myBrowser.setEditable(false); + myPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + myLabel.setIcon(IconLoader.getIcon("/general/tip.png")); + Font font = myLabel.getFont(); + myLabel.setFont(font.deriveFont(Font.PLAIN, font.getSize() + 4)); + update(); + + myCloseButton.setVisible(false); + + myPanel.addAncestorListener(new AncestorListener() { + public void ancestorAdded(AncestorEvent event) { + } + + public void ancestorRemoved(AncestorEvent event) { + boolean shouldKeep = myKeepOpen.isSelected(); + PropertiesComponent.getInstance().setValue(KEEP_OPTION_NAME, String.valueOf(shouldKeep)); + if (shouldKeep) persist(); + } + + public void ancestorMoved(AncestorEvent event) { + } + }); + + if (myFeatures.length > 1) { + myNextHintButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myCurrentFeature < myFeatures.length - 1) { + myCurrentFeature++; + } + update(); + } + }); + + myPrevHintButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myCurrentFeature > 0) { + myCurrentFeature--; + } + update(); + } + }); + } + else { + myNextHintButton.setVisible(false); + myPrevHintButton.setVisible(false); + } + + myKeepOpen.setSelected(PropertiesComponent.getInstance().isTrueValue(KEEP_OPTION_NAME)); + } + + private void persist() { + if (myIsShownIsOwnDialog) return; + myIsShownIsOwnDialog = true; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new OwnDialog(myProject).show(); + } + }); + } + + private class OwnDialog extends DialogWrapper { + public OwnDialog(Project project) { + super(project, false); + setTitle("Productivity Hints"); + setCancelButtonText("Close"); + init(); + } + + protected JComponent createCenterPanel() { + myKeepOpen.setVisible(false); + myCloseButton.setVisible(true); + myCloseButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + OwnDialog.this.close(OwnDialog.OK_EXIT_CODE); + } + }); + return myPanel; + } + + protected Action[] createActions() { + return new Action[] {}; + } + } + + private void update() { + myPrevHintButton.setEnabled(myCurrentFeature > 0); + myNextHintButton.setEnabled(myCurrentFeature < myFeatures.length - 1); + + final String id = myFeatures[myCurrentFeature]; + + myLastRequest = new Runnable() { + public void run() { + if (myLastRequest == this && !getComponent().isShowing()) return; + FeatureUsageTracker.getInstance().triggerFeatureShown(id); + } + }; + + myMarkReadAlarm.addRequest(myLastRequest, MARK_READ_DELAY, ModalityState.current()); + + FeatureDescriptor feature = ProductivityFeaturesRegistry.getInstance().getFeatureDescriptor(id); + final String tipFileName = feature.getTipFileName(); + TipUIUtil.openTipInBrowser(tipFileName, myBrowser); + } + + public JComponent getComponent() { + return myPanel; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindProgressIndicator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindProgressIndicator.java new file mode 100644 index 00000000000..c1607bb8aea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindProgressIndicator.java @@ -0,0 +1,68 @@ +package com.intellij.find; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ex.StatusBarEx; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author ven + */ +public class FindProgressIndicator extends ProgressWindow { + private StatusBarEx myStatusBar; + private boolean myIsBackground; + + public FindProgressIndicator(Project project, String scopeString) { + super (true, true, project, "Stop"); + setTitle("Searching in "+scopeString+" ..."); + myStatusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(project); + } + + public void background() { + myIsBackground = true; + myStatusBar.addProgress(); + super.background(); + + ToolWindow toolWindow = ToolWindowManager.getInstance(getProject()).getToolWindow(ToolWindowId.FIND); + if (!toolWindow.isActive()) toolWindow.activate(null); + } + + public void setText(String text) { + if (!myIsBackground) { + super.setText(text); + } + else { + myStatusBar.setInfo(text); + } + } + + public void setFraction(double fraction) { + if (!myIsBackground) super.setFraction(fraction); + else { + myStatusBar.setProgressValue(getPercentage(fraction)); + } + } + + public void setText2(String text) { + if (!myIsBackground) super.setText2(text); + } + + public void cancel() { + if (myIsBackground) myStatusBar.hideProgress(); + super.cancel(); + } + + public synchronized void stop() { + if (myIsBackground) myStatusBar.hideProgress(); + super.stop(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindSettings.java new file mode 100644 index 00000000000..48d3cc47ffe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindSettings.java @@ -0,0 +1,76 @@ +package com.intellij.find; + +import com.intellij.openapi.application.ApplicationManager; + +import java.util.ArrayList; + +public abstract class FindSettings{ + + public static FindSettings getInstance() { + return ApplicationManager.getApplication().getComponent(FindSettings.class); + } + + public abstract boolean isSkipResultsWithOneUsage(); + + public abstract void setSkipResultsWithOneUsage(boolean skip); + + public abstract boolean isSearchInNonJavaFiles(); + + public abstract void setSearchInNonJavaFiles(boolean search); + + public abstract String getDefaultScopeName(); + + public abstract void setDefaultScopeName(String scope); + + public abstract boolean isSearchOverloadedMethods(); + + public abstract void setSearchOverloadedMethods (boolean search); + + public abstract boolean isForward(); + + public abstract void setForward(boolean findDirectionForward); + + public abstract boolean isFromCursor(); + + public abstract void setFromCursor(boolean findFromCursor); + + public abstract boolean isGlobal(); + + public abstract void setGlobal(boolean findGlobalScope); + + public abstract boolean isCaseSensitive(); + + public abstract void setCaseSensitive(boolean caseSensitiveSearch); + + public abstract boolean isPreserveCase(); + + public abstract void setPreserveCase(boolean preserveCase); + + public abstract boolean isWholeWordsOnly(); + + public abstract void setWholeWordsOnly(boolean wholeWordsOnly); + + public abstract boolean isRegularExpressions(); + + public abstract void setRegularExpressions(boolean regularExpressions); + + public abstract void addStringToFind(String s); + + public abstract void addStringToReplace(String s); + + public abstract void addDirectory(String s); + + public abstract String[] getRecentFindStrings(); + + public abstract String[] getRecentReplaceStrings(); + + public abstract ArrayList getRecentDirectories(); + + public abstract void setWithSubdirectories(boolean b); + + public abstract void initModelBySetings(FindModel model); + + public abstract String getFileMask(); + + public abstract void setFileMask(String fileMask); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindUtil.java new file mode 100644 index 00000000000..4485e9753b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/FindUtil.java @@ -0,0 +1,607 @@ +package com.intellij.find; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.editor.ex.RangeHighlighterEx; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.LightweightHint; + +import javax.swing.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +/** + * + */ +public class FindUtil { + private static Key KEY = Key.create("FindUtil.KEY"); + private static String UP = "UP"; + private static String DOWN = "DOWN"; + + public static void findWordAtCaret(Project project, Editor editor) { + int caretOffset = editor.getCaretModel().getOffset(); + Document document = editor.getDocument(); + CharSequence text = document.getCharsSequence(); + int start = 0, end = document.getTextLength(); + if (!editor.getSelectionModel().hasSelection()) { + for (int i = caretOffset - 1; i >= 0; i--) { + char c = text.charAt(i); + if (!Character.isJavaIdentifierPart(c)) { + start = i + 1; + break; + } + } + for (int i = caretOffset; i < document.getTextLength(); i++) { + char c = text.charAt(i); + if (!Character.isJavaIdentifierPart(c)) { + end = i; + break; + } + } + } + else { + start = editor.getSelectionModel().getSelectionStart(); + end = editor.getSelectionModel().getSelectionEnd(); + } + if (start >= end) { + return; + } + FindManager findManager = FindManager.getInstance(project); + String s = text.subSequence(start, end).toString(); + FindSettings.getInstance().addStringToFind(s); + findManager.getFindInFileModel().setStringToFind(s); + findManager.setFindWasPerformed(); + FindModel model = new FindModel(); + model.setStringToFind(s); + model.setCaseSensitive(true); + model.setWholeWordsOnly(!editor.getSelectionModel().hasSelection()); + findManager.setFindNextModel(model); + doSearch(project, editor, caretOffset, true, model, true); + } + + public static void find(Project project, Editor editor) { + FindManager findManager = FindManager.getInstance(project); + String s = editor.getSelectionModel().getSelectedText(); + + FindModel model = (FindModel)findManager.getFindInFileModel().clone(); + if (s != null) { + if (s.indexOf('\n') >= 0) { + model.setGlobal(false); + } + else { + model.setStringToFind(s); + model.setGlobal(true); + } + } + else { + model.setGlobal(true); + } + + model.setReplaceState(false); + + if (!findManager.showFindDialog(model)) { + return; + } + + if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { + int offset = model.isForward() + ? editor.getSelectionModel().getSelectionStart() + : editor.getSelectionModel().getSelectionEnd(); + ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + moveCaretAndDontChangeSelection(editor, offset, scrollType); + } + + int offset; + if (model.isGlobal()) { + if (model.isFromCursor()) { + offset = editor.getCaretModel().getOffset(); + } + else { + if (model.isForward()) { + offset = 0; + } + else { + offset = editor.getDocument().getTextLength(); + } + } + } + else { + // in selection + + if (!editor.getSelectionModel().hasSelection()) { + // TODO[anton] actually, this should never happen - Find dialog should not allow such combination + findManager.setFindNextModel(null); + return; + } + + if (model.isForward()) { + offset = editor.getSelectionModel().getSelectionStart(); + } + else { + offset = editor.getSelectionModel().getSelectionEnd(); + } + } + + findManager.setFindNextModel(null); + findManager.getFindInFileModel().copyFrom(model); + doSearch(project, editor, offset, true, model, true); + } + + public static void searchBack(Project project, FileEditor fileEditor) { + if (!(fileEditor instanceof TextEditor)) return; + TextEditor textEditor = (TextEditor)fileEditor; + Editor editor = textEditor.getEditor(); + + FindManager findManager = FindManager.getInstance(project); + if (!findManager.findWasPerformed()) { + find(project, editor); + return; + } + + FindModel model = findManager.getFindNextModel(); + if (model == null) { + model = findManager.getFindInFileModel(); + } + model = (FindModel)model.clone(); + model.setForward(!model.isForward()); + if (!model.isGlobal() && !editor.getSelectionModel().hasSelection()) { + model.setGlobal(true); + } + + int offset; + if (UP.equals(editor.getUserData(KEY)) && !model.isForward()) { + offset = editor.getDocument().getTextLength(); + } + else if (DOWN.equals(editor.getUserData(KEY)) && model.isForward()) { + offset = 0; + } + else { + editor.putUserData(KEY, null); + offset = editor.getCaretModel().getOffset(); + if (!model.isForward()) { + offset--; + } + } + searchAgain(project, editor, offset, model); + } + + public static boolean searchAgain(Project project, FileEditor fileEditor) { + if (!(fileEditor instanceof TextEditor)) return false; + TextEditor textEditor = (TextEditor)fileEditor; + Editor editor = textEditor.getEditor(); + + FindManager findManager = FindManager.getInstance(project); + if (!findManager.findWasPerformed()) { + find(project, editor); + return false; + } + + FindModel model = findManager.getFindNextModel(); + if (model == null) { + model = findManager.getFindInFileModel(); + } + model = (FindModel)model.clone(); + + int offset; + if (DOWN.equals(editor.getUserData(KEY)) && model.isForward()) { + offset = 0; + } + else if (UP.equals(editor.getUserData(KEY)) && !model.isForward()) { + offset = editor.getDocument().getTextLength(); + } + else { + editor.putUserData(KEY, null); + offset = editor.getCaretModel().getOffset(); + if (!model.isForward()) { + offset--; + } + } + return searchAgain(project, editor, offset, model); + } + + private static boolean searchAgain(Project project, Editor editor, int offset, FindModel model) { + if (!model.isGlobal() && !editor.getSelectionModel().hasSelection()) { + model.setGlobal(true); + } + model.setFromCursor(false); + if (model.isReplaceState()) { + model.setPromptOnReplace(true); + model.setReplaceAll(false); + replace(project, editor, offset, model); + return true; + } + else { + doSearch(project, editor, offset, true, model, true); + return false; + } + } + + public static boolean replace(Project project, Editor editor) { + FindManager findManager = FindManager.getInstance(project); + FindModel model = (FindModel)findManager.getFindInFileModel().clone(); + String s = editor.getSelectionModel().getSelectedText(); + if (s != null) { + if (s.indexOf('\n') >= 0) { + model.setGlobal(false); + } + else { + model.setStringToFind(s); + model.setGlobal(true); + } + } + else { + model.setGlobal(true); + } + model.setReplaceState(true); + + if (!findManager.showFindDialog(model)) { + return false; + } + if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { + int offset = model.isForward() + ? editor.getSelectionModel().getSelectionStart() + : editor.getSelectionModel().getSelectionEnd(); + ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + moveCaretAndDontChangeSelection(editor, offset, scrollType); + } + int offset; + if (model.isGlobal()) { + if (model.isFromCursor()) { + offset = editor.getCaretModel().getOffset(); + if (!model.isForward()) { + offset++; + } + } + else { + if (model.isForward()) { + offset = 0; + } + else { + offset = editor.getDocument().getTextLength(); + } + } + } + else { + // in selection + + if (!editor.getSelectionModel().hasSelection()) { + // TODO[anton] actually, this should never happen - Find dialog should not allow such combination + findManager.setFindNextModel(null); + return false; + } + + if (model.isForward()) { + offset = editor.getSelectionModel().getSelectionStart(); + } + else { + offset = editor.getSelectionModel().getSelectionEnd(); + } + } + + if (s != null && editor.getSelectionModel().hasSelection() && s.equals(model.getStringToFind())) { + if (model.isFromCursor() && model.isForward()) { + offset = Math.min(editor.getSelectionModel().getSelectionStart(), offset); + } + else if (model.isFromCursor() && !model.isForward()) { + offset = Math.max(editor.getSelectionModel().getSelectionEnd(), offset); + } + } + findManager.setFindNextModel(null); + findManager.getFindInFileModel().copyFrom(model); + return replace(project, editor, offset, model); + } + + private static boolean replace(Project project, Editor editor, int offset, FindModel model) { + boolean isReplaced = false; + Document document = editor.getDocument(); + int caretOffset = offset; + + if (document.isWritable()) { + document.startGuardedBlockChecking(); + try { + FindManager findManager = FindManager.getInstance(project); + boolean toPrompt = model.isPromptOnReplace(); + model = (FindModel)model.clone(); + while (offset >= 0 && offset < editor.getDocument().getTextLength()) { + caretOffset = offset; + FindResult result = doSearch(project, editor, offset, !isReplaced, model, toPrompt); + if (result == null) { + break; + } + int startResultOffset = result.getStartOffset(); + model.setFromCursor(true); + if (toPrompt) { + int promptResult = findManager.showPromptDialog(model, "Replace"); + if (promptResult == PromptResult.SKIP) { + offset = model.isForward() ? result.getEndOffset() : startResultOffset; + continue; + } + if (promptResult == PromptResult.CANCEL) { + break; + } + if (promptResult == PromptResult.ALL) { + toPrompt = false; + } + } + + int startOffset = result.getStartOffset(), endOffset = result.getEndOffset(); + String foundString = document.getCharsSequence().subSequence(startOffset, endOffset).toString(); + String toReplace = findManager.getStringToReplace(foundString, model); + if (model.isForward()) { + offset = doReplace(document, model, result, toReplace).getEndOffset(); + } + else { + offset = doReplace(document, model, result, toReplace).getStartOffset(); + } + + //[SCR 7258] + if (!isReplaced) { + editor.getCaretModel().moveToOffset(0); + } + + isReplaced = true; + } + } + catch (ReadOnlyFragmentModificationException e) { + EditorActionManager.getInstance().getReadonlyFragmentModificationHandler().handle(e); + } + finally { + document.stopGuardedBlockChecking(); + } + } + else { + editor.getDocument().fireReadOnlyModificationAttempt(); + } + + if (isReplaced) { + editor.getCaretModel().moveToOffset(caretOffset); + } + + return isReplaced; + } + + private static FindResult doSearch(Project project, + final Editor editor, + int offset, + boolean toWarn, + FindModel model, boolean adjustEditor) { + FindManager findManager = FindManager.getInstance(project); + Document document = editor.getDocument(); + + final FindResult result = findManager.findString(document.getCharsSequence(), offset, model); + if (result == null) { + return null; + } + String stringToFind = model.getStringToFind(); + if (stringToFind == null) { + return null; + } + + boolean isFound = result.isStringFound(); + if (!model.isGlobal()) { + if (result.getEndOffset() > editor.getSelectionModel().getSelectionEnd() || + result.getStartOffset() < editor.getSelectionModel().getSelectionStart()) { + isFound = false; + } + } + if (!isFound) { + if (toWarn) { + processNotFound(editor, model.getStringToFind(), model, project); + } + return null; + } + + if (adjustEditor) { + final CaretModel caretModel = editor.getCaretModel(); + final ScrollingModel scrollingModel = editor.getScrollingModel(); + int oldCaretOffset = caretModel.getOffset(); + boolean forward = oldCaretOffset < result.getStartOffset(); + final ScrollType scrollType = forward ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + + if (model.isGlobal()) { + caretModel.moveToOffset(result.getEndOffset()); + editor.getSelectionModel().removeSelection(); + scrollingModel.scrollToCaret(scrollType); + scrollingModel.runActionOnScrollingFinished( + new Runnable() { + public void run() { + scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getStartOffset()), scrollType); + scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getEndOffset()), scrollType); + } + } + ); + } + else { + moveCaretAndDontChangeSelection(editor, result.getStartOffset(), scrollType); + moveCaretAndDontChangeSelection(editor, result.getEndOffset(), scrollType); + } + IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation(); + + EditorColorsManager manager = EditorColorsManager.getInstance(); + TextAttributes selectionAttributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + + if (!model.isGlobal()) { + final RangeHighlighterEx segmentHighlighter = (RangeHighlighterEx)editor.getMarkupModel().addRangeHighlighter( + result.getStartOffset(), + result.getEndOffset(), + HighlighterLayer.SELECTION + 1, + selectionAttributes, HighlighterTargetArea.EXACT_RANGE); + MyListener listener = new MyListener(editor, segmentHighlighter); + editor.getContentComponent().addFocusListener(listener); + caretModel.addCaretListener(listener); + } + else { + editor.getSelectionModel().setSelection(result.getStartOffset(), result.getEndOffset()); + } + } + + return result; + } + + private static class MyListener implements FocusListener, CaretListener { + private Editor myEditor; + private RangeHighlighter mySegmentHighlighter; + + public MyListener(Editor editor, RangeHighlighter segmentHighlighter) { + myEditor = editor; + mySegmentHighlighter = segmentHighlighter; + } + + public void focusGained(FocusEvent e) { +// removeAll(); + } + + public void focusLost(FocusEvent e) { + } + + public void caretPositionChanged(CaretEvent e) { + removeAll(); + } + + private void removeAll() { + myEditor.getMarkupModel().removeHighlighter(mySegmentHighlighter); + myEditor.getContentComponent().addFocusListener(this); + myEditor.getCaretModel().removeCaretListener(this); + } + } + + private static void processNotFound(final Editor editor, String stringToFind, FindModel model, Project project) { + FindResult result; + + String message = "\"" + stringToFind + "\" not found"; + + if (model.isGlobal()) { + final FindModel newModel = (FindModel)model.clone(); + FindManager findManager = FindManager.getInstance(project); + Document document = editor.getDocument(); + if (newModel.isForward()) { + result = findManager.findString(document.getCharsSequence(), 0, model); + } + else { + result = + findManager.findString(document.getCharsSequence(), document.getTextLength(), model); + } + if (result != null && !result.isStringFound()) { + result = null; + } + + FindModel modelForNextSearch = findManager.getFindNextModel(); + if (modelForNextSearch == null) { + modelForNextSearch = findManager.getFindInFileModel(); + } + + if (result != null) { + if (newModel.isForward()) { + AnAction action = ActionManager.getInstance().getAction( + modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_NEXT : IdeActions.ACTION_FIND_PREVIOUS); + String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else { + message += ", perform \"Find Next\" again "; + } + message += " to search from the top"; + editor.putUserData(KEY, DOWN); + } + else { + AnAction action = ActionManager.getInstance().getAction( + modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_PREVIOUS : IdeActions.ACTION_FIND_NEXT); + String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else { + message += ", perform \"Find Previous\" again "; + } + message += " to search from the bottom"; + editor.putUserData(KEY, UP); + } + } + CaretListener listener = new CaretListener() { + public void caretPositionChanged(CaretEvent e) { + editor.putUserData(KEY, null); + editor.getCaretModel().removeCaretListener(this); + } + }; + editor.getCaretModel().addCaretListener(listener); + } + HintManager hintManager = HintManager.getInstance(); + JComponent component = HintUtil.createInformationLabel(message); + final LightweightHint hint = new LightweightHint(component); + hintManager.showEditorHint(hint, editor, HintManager.UNDER, + HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | + HintManager.HIDE_BY_SCROLLING, + 0, false); + } + + private static TextRange doReplace(final Document document, final FindModel model, FindResult result, final String stringToReplace) { + final int startOffset = result.getStartOffset(); + final int endOffset = result.getEndOffset(); + if (stringToReplace == null) return new TextRange(Integer.MAX_VALUE, Integer.MIN_VALUE); + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + document.deleteString(startOffset, endOffset); + //[ven] I doubt converting is a good solution to SCR 21224 + document.insertString(startOffset, StringUtil.convertLineSeparators(stringToReplace)); + } + } + ); + + int newOffset = startOffset + stringToReplace.length(); + + int start = startOffset, end = newOffset; + if (model.isRegularExpressions()) { + String toFind = model.getStringToFind(); + if (model.isForward()) { + if (StringUtil.endsWithChar(toFind, '$')) { + int i = 0; + int length = toFind.length(); + while (i + 2 <= length && toFind.charAt(length - i - 2) == '\\') i++; + if (i % 2 == 0) end++; //This $ is a special symbol in regexp syntax + } + else if (StringUtil.startsWithChar(toFind, '^')) { + while (end < document.getTextLength() && document.getCharsSequence().charAt(end) != '\n') end++; + } + } + else { + if (StringUtil.startsWithChar(toFind, '^')) { + start--; + } + else if (StringUtil.endsWithChar(toFind, '$')) { + while (start >= 0 && document.getCharsSequence().charAt(start) != '\n') start--; + } + } + } + return new TextRange(start, end); + } + + private static void moveCaretAndDontChangeSelection(final Editor editor, int offset, ScrollType scrollType) { + LogicalPosition pos = editor.offsetToLogicalPosition(offset); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getScrollingModel().scrollToCaret(scrollType); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindInPathAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindInPathAction.java new file mode 100644 index 00000000000..5233ede1820 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindInPathAction.java @@ -0,0 +1,26 @@ + +package com.intellij.find.actions; + +import com.intellij.find.findInProject.FindInProjectManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +public class FindInPathAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + FindInProjectManager.getInstance(project).findInProject(dataContext); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + } else { + FindInProjectManager findManager = FindInProjectManager.getInstance(project); + presentation.setEnabled(findManager.isEnabled()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesAction.java new file mode 100644 index 00000000000..58b9f84d69d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesAction.java @@ -0,0 +1,40 @@ +package com.intellij.find.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.usages.UsageTarget; +import com.intellij.usages.UsageView; + +public class FindUsagesAction extends AnAction { + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if(project==null){ + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + UsageTarget[] usageTargets = (UsageTarget[])dataContext.getData(UsageView.USAGE_TARGETS); + if (usageTargets != null) { + usageTargets[0].findUsages(); + } + else { + Messages.showMessageDialog( + project, + "Cannot search for usages.\nPosition to an element which usages you wish to find and try again.", + "Error", + Messages.getErrorIcon() + ); + } + } + + public void update(AnActionEvent event){ + FindUsagesInFileAction.updateFindUsagesAction(event); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesInFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesInFileAction.java new file mode 100644 index 00000000000..8d2ca47706b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/FindUsagesInFileAction.java @@ -0,0 +1,72 @@ +package com.intellij.find.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.jsp.JspFile; +import com.intellij.usages.UsageTarget; +import com.intellij.usages.UsageView; + +public class FindUsagesInFileAction extends AnAction { + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if(project==null){ + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + UsageTarget[] usageTargets = (UsageTarget[])dataContext.getData(UsageView.USAGE_TARGETS); + if (usageTargets != null) { + usageTargets[0].findUsagesInEditor((FileEditor)dataContext.getData(DataConstants.FILE_EDITOR)); + } + else { + Messages.showMessageDialog( + project, + "Cannot search for usages.\nPosition to an element which usages you wish to find and try again.", + "Error", + Messages.getErrorIcon() + ); + } + } + + public void update(AnActionEvent event){ + updateFindUsagesAction(event); + + } + + public static void updateFindUsagesAction(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + boolean enabled = file instanceof PsiJavaFile || file instanceof JspFile || file instanceof XmlFile; + if (!enabled && file!=null) { + FileTypeSupportCapabilities capabilities = file.getFileType().getSupportCapabilities(); + enabled = capabilities!=null && capabilities.hasFindUsages(); + } + presentation.setVisible(enabled); + presentation.setEnabled(enabled); + } + else { + UsageTarget[] target = (UsageTarget[])dataContext.getData(UsageView.USAGE_TARGETS); + presentation.setVisible(true); + presentation.setEnabled(target != null && target.length > 0); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/ReplaceInPathAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/ReplaceInPathAction.java new file mode 100644 index 00000000000..fee5c723822 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/actions/ReplaceInPathAction.java @@ -0,0 +1,27 @@ + +package com.intellij.find.actions; + +import com.intellij.find.replaceInProject.ReplaceInProjectManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +public class ReplaceInPathAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + ReplaceInProjectManager.getInstance(project).replaceInProject(dataContext); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + } + else { + ReplaceInProjectManager replaceManager = ReplaceInProjectManager.getInstance(project); + presentation.setEnabled(replaceManager.isEnabled()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findInProject/FindInProjectManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findInProject/FindInProjectManager.java new file mode 100644 index 00000000000..e7c626f5896 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findInProject/FindInProjectManager.java @@ -0,0 +1,180 @@ +package com.intellij.find.findInProject; + +import com.intellij.find.FindManager; +import com.intellij.find.FindModel; +import com.intellij.find.FindProgressIndicator; +import com.intellij.find.impl.FindInProjectUtil; +import com.intellij.find.replaceInProject.ReplaceInProjectManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.ui.content.Content; +import com.intellij.usageView.*; + +import java.util.ArrayList; + +public class FindInProjectManager implements ProjectComponent { + private Project myProject; + private ArrayList myUsagesContents = new ArrayList(); + private boolean myToOpenInNewTab = false; + private boolean myIsFindInProgress = false; + + public void projectOpened() {} + + public void projectClosed() {} + + public String getComponentName() { + return "FindInProjectManager"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public static FindInProjectManager getInstance(Project project) { + return project.getComponent(FindInProjectManager.class); + } + + public FindInProjectManager(Project project) { + myProject = project; + } + + public void findInProject(DataContext dataContext) { + ArrayList contentsToDelete = new ArrayList(); + for(int i = 0; i < myUsagesContents.size(); i++){ + Content content = (Content)myUsagesContents.get(i); + if (content.getComponent().getParent() == null){ + contentsToDelete.add(content); + } + } + + for(int i = 0; i < contentsToDelete.size(); i++){ + myUsagesContents.remove(contentsToDelete.get(i)); + } + + boolean isOpenInNewTabEnabled; + final boolean[] toOpenInNewTab = new boolean[1]; + Content selectedContent = UsageViewManager.getInstance(myProject).getSelectedContent(true); + if (selectedContent != null && selectedContent.isPinned()) { + toOpenInNewTab[0] = true; + isOpenInNewTabEnabled = false; + } + else { + toOpenInNewTab[0] = myToOpenInNewTab; + isOpenInNewTabEnabled = (UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0); + } + + final FindManager findManager = FindManager.getInstance(myProject); + final FindModel findModel = (FindModel) findManager.getFindInProjectModel().clone(); + findModel.setReplaceState(false); + findModel.setOpenInNewTabVisible(true); + findModel.setOpenInNewTabEnabled(isOpenInNewTabEnabled); + findModel.setOpenInNewTab(toOpenInNewTab[0]); + FindInProjectUtil.setDirectoryName(findModel, dataContext); + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null){ + String s = editor.getSelectionModel().getSelectedText(); + if (s != null && (s.indexOf("\r") == -1) && (s.indexOf("\n") == -1)){ + findModel.setStringToFind(s); + } + } + + if (!findManager.showFindDialog(findModel)){ + findModel.setOpenInNewTabVisible(false); + return; + } + findModel.setOpenInNewTabVisible(false); + final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject); + if (!findModel.isProjectScope() && findModel.getModuleName()==null && psiDirectory == null){ + return; + } + if (isOpenInNewTabEnabled) { + myToOpenInNewTab = toOpenInNewTab[0] = findModel.isOpenInNewTab(); + } + + AsyncFindUsagesCommand command = new AsyncFindUsagesCommand() { + FindProgressIndicator progress; + + public void findUsages(final AsyncFindUsagesProcessListener consumer) { + myIsFindInProgress = true; + findManager.getFindInProjectModel().copyFrom(findModel); + + // [jeka] should use a _copy_ of findModel, because of RefreshCommand, findModel is reused by later FindUsages commands!!!! + final FindModel findModelCopy = (FindModel)findModel.clone(); + progress = new FindProgressIndicator(myProject, FindInProjectUtil.getTitleForScope(findModelCopy)); + final Runnable findUsagesRunnable = new Runnable() { + public void run() { + FindInProjectUtil.findUsages(findModelCopy, psiDirectory, myProject, consumer); + } + }; + + Runnable showUsagesPanelRunnable = new Runnable() { + public void run() { + myIsFindInProgress = false; + if (consumer.getCount()==0) { + if (!progress.isCanceled()) { + String title = "No occurrences of '" + findModel.getStringToFind() + "' found in " + FindInProjectUtil.getTitleForScope(findModelCopy); + + Messages.showMessageDialog( + myProject, + title, + "Find in Path", + Messages.getInformationIcon() + ); + } + } + } + }; + + FindInProjectUtil.runProcessWithProgress(progress, findUsagesRunnable, showUsagesPanelRunnable, myProject); + } + + public void stopAsyncSearch() { + progress.cancel(); + } + }; + + showUsagesPanel( + new FindInProjectViewDescriptor(findModel,command), + toOpenInNewTab[0] + ); + } + + private void showUsagesPanel(final FindInProjectViewDescriptor viewDescriptor, boolean toOpenInNewTab) { + String stringToFind = viewDescriptor.getFindModel().getStringToFind(); + String name = "Search result"; + if (stringToFind != null) { + if (stringToFind.length() > 15) { + stringToFind = stringToFind.substring(0, 15) + "..."; + } + name = "Occurrences of '"+stringToFind + "'"; + } + + if (viewDescriptor.getFindModel().isMultipleFiles() ) { + name += " in " +FindInProjectUtil.getTitleForScope(viewDescriptor.getFindModel()); + } + UsageViewManager.getInstance(myProject).addContent(name, viewDescriptor, true, toOpenInNewTab, true, new ProgressFactory () { + public ProgressIndicator createProgress() { + return new FindProgressIndicator(myProject, FindInProjectUtil.getTitleForScope(viewDescriptor.getFindModel())); + } + + public boolean continueOnCancel() { + return true; + } + }); + } + + public boolean isWorkInProgress() { + return myIsFindInProgress; + } + + public boolean isEnabled () { + return !myIsFindInProgress && !ReplaceInProjectManager.getInstance(myProject).isWorkInProgress(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindClassUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindClassUsagesDialog.java new file mode 100644 index 00000000000..04b69411125 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindClassUsagesDialog.java @@ -0,0 +1,112 @@ + +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; + +public class FindClassUsagesDialog extends FindUsagesDialog { + private StateRestoringCheckBox myCbUsages; + private StateRestoringCheckBox myCbMethodsUsages; + private StateRestoringCheckBox myCbFieldsUsages; + private StateRestoringCheckBox myCbImplementingClasses; + private StateRestoringCheckBox myCbDerivedInterfaces; + private StateRestoringCheckBox myCbDerivedClasses; + + public FindClassUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, boolean isShowInNewTabEnabled, boolean isSingleFile){ + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + public JComponent getPreferredFocusedControl() { + return myCbUsages; + } + + public FindUsagesOptions getShownOptions(){ + FindUsagesOptions options = new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + options.clear(); + options.isUsages = isToChange(myCbUsages); + options.isMethodsUsages = isToChange(myCbMethodsUsages); + options.isFieldsUsages = isToChange(myCbFieldsUsages); + options.isDerivedClasses = isToChange(myCbDerivedClasses); + options.isImplementingClasses = isToChange(myCbImplementingClasses); + options.isDerivedInterfaces = isToChange(myCbDerivedInterfaces); + options.isSearchInNonJavaFiles = isToChange(myCbToSearchInNonJavaFiles); + return options; + } + + public void calcFindUsagesOptions(FindUsagesOptions options) { + super.calcFindUsagesOptions(options); + + if (isToChange(myCbUsages)){ + options.isUsages = isSelected(myCbUsages); + } + if (isToChange(myCbMethodsUsages)){ + options.isMethodsUsages = isSelected(myCbMethodsUsages); + } + if (isToChange(myCbFieldsUsages)){ + options.isFieldsUsages = isSelected(myCbFieldsUsages); + } + if (isToChange(myCbDerivedClasses)){ + options.isDerivedClasses = isSelected(myCbDerivedClasses); + } + if (isToChange(myCbImplementingClasses)){ + options.isImplementingClasses = isSelected(myCbImplementingClasses); + } + if (isToChange(myCbDerivedInterfaces)){ + options.isDerivedInterfaces = isSelected(myCbDerivedInterfaces); + } + options.isSkipImportStatements = false; + options.isCheckDeepInheritance = true; + options.isIncludeInherited = false; + } + + protected JPanel createFindWhatPanel() { + JPanel findWhatPanel = new JPanel(); + + findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); + findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); + + myCbUsages = addCheckboxToPanel("Usages", myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); + + PsiClass psiClass = (PsiClass)getPsiElement(); + myCbMethodsUsages = addCheckboxToPanel("Usages of methods", myFindUsagesOptions.isMethodsUsages, findWhatPanel, true, 'm'); + + if (!psiClass.isAnnotationType()) { + myCbFieldsUsages = addCheckboxToPanel("Usages of fields", myFindUsagesOptions.isFieldsUsages, findWhatPanel, true, 'f'); + if (psiClass.isInterface()){ + myCbImplementingClasses = addCheckboxToPanel("Implementing classes", myFindUsagesOptions.isImplementingClasses, findWhatPanel, true, 'I'); + myCbDerivedInterfaces = addCheckboxToPanel("Derived interfaces", myFindUsagesOptions.isDerivedInterfaces, findWhatPanel, true, 'D'); + } + else if (!psiClass.hasModifierProperty(PsiModifier.FINAL)){ + myCbDerivedClasses = addCheckboxToPanel("Derived classes", myFindUsagesOptions.isDerivedClasses, findWhatPanel, true, 'D'); + } + } + return findWhatPanel; + } + + protected void update() { + if(myCbToSearchInNonJavaFiles != null){ + if (isSelected(myCbUsages)){ + myCbToSearchInNonJavaFiles.makeSelectable(); + } + else{ + myCbToSearchInNonJavaFiles.makeUnselectable(false); + } + } + + boolean hasSelected = isSelected(myCbUsages) || + isSelected(myCbFieldsUsages) || + isSelected(myCbMethodsUsages) || + isSelected(myCbImplementingClasses) || + isSelected(myCbDerivedInterfaces) || + isSelected(myCbDerivedClasses); + setOKActionEnabled(hasSelected); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindMethodUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindMethodUsagesDialog.java new file mode 100644 index 00000000000..f66eb7fe7a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindMethodUsagesDialog.java @@ -0,0 +1,102 @@ +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; + +public class FindMethodUsagesDialog extends FindUsagesDialog { + private StateRestoringCheckBox myCbUsages; + private StateRestoringCheckBox myCbImplementingMethods; + private StateRestoringCheckBox myCbOverridingMethods; + private boolean myHasFindWhatPanel; + + public FindMethodUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, boolean isShowInNewTabEnabled, boolean isSingleFile) { + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + public JComponent getPreferredFocusedControl() { + return myHasFindWhatPanel ? myCbUsages : null; + } + + public FindUsagesOptions getShownOptions() { + FindUsagesOptions options = new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + options.clear(); + options.isUsages = true; + options.isIncludeOverloadUsages = isToChange(myCbIncludeOverloadedMethods); + options.isOverridingMethods = isToChange(myCbOverridingMethods); + options.isImplementingMethods = isToChange(myCbImplementingMethods); + return options; + } + + public void calcFindUsagesOptions(FindUsagesOptions options) { + super.calcFindUsagesOptions(options); + + options.isUsages = isSelected(myCbUsages) || !myHasFindWhatPanel; + if (isToChange(myCbOverridingMethods)) { + options.isOverridingMethods = isSelected(myCbOverridingMethods); + } + if (isToChange(myCbImplementingMethods)) { + options.isImplementingMethods = isSelected(myCbImplementingMethods); + } + options.isCheckDeepInheritance = true; + } + + protected JPanel createFindWhatPanel() { + JPanel findWhatPanel = new JPanel(); + findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); + findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); + + myCbUsages = addCheckboxToPanel("Usages", myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); + + PsiMethod method = (PsiMethod) getPsiElement(); + PsiClass aClass = method.getContainingClass(); + if (!method.isConstructor() && + !method.hasModifierProperty(PsiModifier.STATIC) && + !method.hasModifierProperty(PsiModifier.FINAL) && + !method.hasModifierProperty(PsiModifier.PRIVATE) && + aClass != null && + !(aClass instanceof PsiAnonymousClass) && + !aClass.hasModifierProperty(PsiModifier.FINAL)) { + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + myCbImplementingMethods = addCheckboxToPanel("Implementing methods", myFindUsagesOptions.isImplementingMethods, findWhatPanel, true, 'I'); + } else { + myCbOverridingMethods = addCheckboxToPanel("Overriding methods", myFindUsagesOptions.isOverridingMethods, findWhatPanel, true, 'O'); + } + } else { + myHasFindWhatPanel = false; + return null; + } + myHasFindWhatPanel = true; + return findWhatPanel; + + /*if (method.isConstructor() || + method.hasModifierProperty(PsiModifier.STATIC) || + method.hasModifierProperty(PsiModifier.FINAL) || + method.hasModifierProperty(PsiModifier.PRIVATE) || + aClass == null || + aClass instanceof PsiAnonymousClass || + aClass.hasModifierProperty(PsiModifier.FINAL)){ + myHasFindWhatPanel = false; + return null; + } + else{ + myHasFindWhatPanel = true; + return findWhatPanel; + }*/ + } + + protected void update() { + if (!myHasFindWhatPanel) { + setOKActionEnabled(true); + return; + } else { + + boolean hasSelected = isSelected(myCbUsages) || isSelected(myCbImplementingMethods) || isSelected(myCbOverridingMethods); + setOKActionEnabled(hasSelected); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindPackageUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindPackageUsagesDialog.java new file mode 100644 index 00000000000..8102998b7d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindPackageUsagesDialog.java @@ -0,0 +1,73 @@ + +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; + +public class FindPackageUsagesDialog extends FindUsagesDialog { + private StateRestoringCheckBox myCbUsages; + private StateRestoringCheckBox myCbClassesUsages; + + public FindPackageUsagesDialog(PsiElement element, + Project project, + FindUsagesOptions findUsagesOptions, + boolean toShowInNewTab, + boolean isShowInNewTabEnabled, + boolean isSingleFile) { + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + public JComponent getPreferredFocusedControl() { + return myCbUsages; + } + + public FindUsagesOptions getShownOptions(){ + FindUsagesOptions options = new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + options.clear(); + options.isUsages = true; + options.isClassesUsages = isToChange(myCbClassesUsages); + options.isSearchInNonJavaFiles = isToChange(myCbToSearchInNonJavaFiles); + return options; + } + + public void calcFindUsagesOptions(FindUsagesOptions options) { + super.calcFindUsagesOptions(options); + + options.isUsages = isSelected(myCbUsages); + if (isToChange(myCbClassesUsages)){ + options.isClassesUsages = isSelected(myCbClassesUsages); + } + options.isSkipPackageStatements = false; + options.isSkipImportStatements = false; + } + + protected JPanel createFindWhatPanel() { + JPanel findWhatPanel = new JPanel(); + findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); + findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); + + myCbUsages = addCheckboxToPanel("Usages", myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); + myCbClassesUsages = addCheckboxToPanel("Usages of classes and interfaces", myFindUsagesOptions.isClassesUsages, findWhatPanel, true, 'c'); + + return findWhatPanel; + } + + protected void update() { + if(myCbToSearchInNonJavaFiles != null){ + if (isSelected(myCbUsages)){ + myCbToSearchInNonJavaFiles.makeSelectable(); + } + else{ + myCbToSearchInNonJavaFiles.makeUnselectable(false); + } + } + + boolean hasSelected = isSelected(myCbUsages) || isSelected(myCbClassesUsages); + setOKActionEnabled(hasSelected); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindThrowUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindThrowUsagesDialog.java new file mode 100644 index 00000000000..e14652dad61 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindThrowUsagesDialog.java @@ -0,0 +1,108 @@ + +package com.intellij.find.findUsages; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiThrowStatement; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.psi.impl.search.ThrowSearchUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; + +public class FindThrowUsagesDialog extends FindUsagesDialog { + private StateRestoringCheckBox myCbUsages; + private StateRestoringCheckBox myCbStrict; + private JComboBox myCbExns; + private boolean myHasFindWhatPanel; + private ThrowSearchUtil.Root [] myRoots; + + public FindThrowUsagesDialog(final PsiElement element, + final Project project, + final FindUsagesOptions findUsagesOptions, + final boolean toShowInNewTab, + final boolean isShowInNewTabEnabled, boolean isSingleFile + ){ + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + protected void init () { + // Kludge: myRoots used in super.init, which caller from constructor + myRoots = ThrowSearchUtil.getSearchRoots(myPsiElement); + super.init (); + } + + public JComponent getPreferredFocusedControl() { + return myHasFindWhatPanel ? myCbUsages : null; + } + + public FindUsagesOptions getShownOptions(){ + final FindUsagesOptions options = new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + options.clear(); + options.isUsages = true; + options.isStrictThrowUsages = false; + return options; + } + + protected JComponent createNorthPanel() { + final JComponent panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.anchor = GridBagConstraints.EAST; + myCbExns = new JComboBox (myRoots); + panel.add(myCbExns, gbConstraints); + + return panel; + } + + public void calcFindUsagesOptions(final FindUsagesOptions options) { + super.calcFindUsagesOptions(options); + options.isUsages = isSelected(myCbUsages) || !myHasFindWhatPanel; + options.isStrictThrowUsages = isSelected(myCbStrict); + options.isThrowUsages = true; + } + + protected JPanel createFindWhatPanel() { + final JPanel findWhatPanel = new JPanel(); + findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); + findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); + + myCbUsages = addCheckboxToPanel("Usages" , myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); + myCbStrict = addCheckboxToPanel("Strict search", myFindUsagesOptions.isStrictThrowUsages, findWhatPanel, true, 'S'); + //final ThrowSearchUtil.Root[] searchRoots = ThrowSearchUtil.getSearchRoots(getPsiElement ()); + + //final PsiThrowStatement throwStatement = (PsiThrowStatement)getPsiElement(); + //final boolean exactExnType = ThrowSearchUtil.isExactExnType(throwStatement.getException ()); + //if (exactExnType) { + // myCbStrict.setEnabled(false); + //} + myHasFindWhatPanel = true; + return findWhatPanel; + } + + protected void doOKAction() { + myFindUsagesOptions.myThrowRoot = (ThrowSearchUtil.Root)myCbExns.getSelectedItem(); + super.doOKAction(); + } + + protected void update(){ + if (!myHasFindWhatPanel){ + setOKActionEnabled(true); + return; + } + else{ + myFindUsagesOptions.myThrowRoot = (ThrowSearchUtil.Root)myCbExns.getSelectedItem(); + final boolean hasSelected = isSelected(myCbUsages); + setOKActionEnabled(hasSelected); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesDialog.java new file mode 100644 index 00000000000..a53fccf5ebf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesDialog.java @@ -0,0 +1,339 @@ + +package com.intellij.find.findUsages; + +import com.intellij.find.FindSettings; +import com.intellij.ide.util.scopeChooser.ScopeChooserCombo; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; +import com.intellij.usageView.UsageViewUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public abstract class FindUsagesDialog extends DialogWrapper{ + protected final Project myProject; + protected final PsiElement myPsiElement; + protected final FindUsagesOptions myFindUsagesOptions; + + private final boolean myToShowInNewTab; + private final boolean myIsShowInNewTabEnabled; + private final boolean myIsShowInNewTabVisible; + + private final boolean mySearchInNonJavaFilesAvailable; + + private final boolean mySearchInLibrariesAvailable; + + private JLabel myPromptLabel; + private JCheckBox myCbToOpenInNewTab; + + protected StateRestoringCheckBox myCbToSearchInNonJavaFiles; + protected JCheckBox myCbToSkipResultsWhenOneUsage; + + private ActionListener myUpdateAction; + + protected StateRestoringCheckBox myCbIncludeOverloadedMethods; + private boolean myIncludeOverloadedMethodsAvailable = false; + private ScopeChooserCombo myScopeCombo; + + protected FindUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, + boolean toShowInNewTab, boolean isShowInNewTabEnabled, boolean isSingleFile){ + super(project, true); + myProject = project; + myPsiElement = element; + myFindUsagesOptions = findUsagesOptions; + myToShowInNewTab = toShowInNewTab; + myIsShowInNewTabEnabled = isShowInNewTabEnabled; + myIsShowInNewTabVisible = !isSingleFile; + + if (!isSingleFile){ + if (myPsiElement instanceof PsiClass){ + mySearchInNonJavaFilesAvailable = ((PsiClass)myPsiElement).getQualifiedName() != null; + } + else if (myPsiElement instanceof PsiPackage){ + mySearchInNonJavaFilesAvailable = true; + } + else{ + mySearchInNonJavaFilesAvailable = false; + } + } + else{ + mySearchInNonJavaFilesAvailable = false; + } + + if (!isSingleFile){ + mySearchInLibrariesAvailable = !myPsiElement.getManager().isInProject(myPsiElement); + } + else{ + mySearchInLibrariesAvailable = false; + } + + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod) element; + myIncludeOverloadedMethodsAvailable = MethodSignatureUtil.hasOverloads (method); + } + + myUpdateAction = new ActionListener() { + public void actionPerformed(ActionEvent event) { + update(); + } + }; + + setButtonsMargin(null); + init(); + setOKButtonText("Find"); + setOKButtonIcon(IconLoader.getIcon("/actions/find.png")); + setTitle(isSingleFile ? "Find Usages in File" : "Find Usages"); + update(); + } + + public abstract FindUsagesOptions getShownOptions(); + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected boolean isInFileOnly() { + return !myIsShowInNewTabVisible || PsiSearchScopeUtil.getAccessScope(myPsiElement) instanceof LocalSearchScope; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.anchor = GridBagConstraints.EAST; + myPromptLabel = new JLabel(getLabelText()); + panel.add(myPromptLabel, gbConstraints); + + return panel; + } + + protected String getLabelText() { + return UsageViewUtil.capitalize(UsageViewUtil.getType(myPsiElement)) + " " + UsageViewUtil.getDescriptiveName(myPsiElement); + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + JPanel _panel = new JPanel(new BorderLayout()); + _panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0)); + panel.add(_panel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + + if (myIsShowInNewTabVisible){ + myCbToOpenInNewTab = new JCheckBox("Open in new tab"); + myCbToOpenInNewTab.setMnemonic('t'); + myCbToOpenInNewTab.setSelected(myToShowInNewTab); + myCbToOpenInNewTab.setEnabled(myIsShowInNewTabEnabled); + _panel.add(myCbToOpenInNewTab, BorderLayout.EAST); + } + + JPanel allOptionsPanel = createAllOptionsPanel(); + if(allOptionsPanel != null){ + panel.add(allOptionsPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } + return panel; + } + + protected final PsiElement getPsiElement() { + return myPsiElement; + } + + public final FindUsagesOptions calcFindUsagesOptions() { + calcFindUsagesOptions(myFindUsagesOptions); + return myFindUsagesOptions; + } + + public void calcFindUsagesOptions(FindUsagesOptions options){ + if (myScopeCombo != null) { + options.searchScope = myScopeCombo.getSelectedScope(); + } + else { + options.searchScope = GlobalSearchScope.allScope(myProject); + } + + if (isToChange(myCbToSearchInNonJavaFiles)) { + options.isSearchInNonJavaFiles = isSelected(myCbToSearchInNonJavaFiles); + } + else { + options.isSearchInNonJavaFiles = false; + } + + if (myIncludeOverloadedMethodsAvailable && isToChange(myCbIncludeOverloadedMethods)) { + options.isIncludeOverloadUsages = myCbIncludeOverloadedMethods.isSelected(); + } + else { + options.isIncludeOverloadUsages = false; + } + } + + protected abstract void update(); + + public boolean isShowInSeparateWindow() { + if (myCbToOpenInNewTab == null){ + return false; + } + return myCbToOpenInNewTab.isSelected(); + } + + public boolean isSkipResultsWhenOneUsage(){ + return myCbToSkipResultsWhenOneUsage != null && myCbToSkipResultsWhenOneUsage.isSelected(); + } + + protected void doOKAction() { + if (myScopeCombo != null && myScopeCombo.getSelectedScope() == null) return; + + FindSettings settings = FindSettings.getInstance(); + + if (myScopeCombo != null) { + settings.setDefaultScopeName(myScopeCombo.getSelectedScopeName()); + } + if (mySearchInNonJavaFilesAvailable && myCbToSearchInNonJavaFiles != null && myCbToSearchInNonJavaFiles.isEnabled()){ + settings.setSearchInNonJavaFiles(myCbToSearchInNonJavaFiles.isSelected()); + } + + if (myIncludeOverloadedMethodsAvailable) { + settings.setSearchOverloadedMethods(myCbIncludeOverloadedMethods.isSelected()); + } + if (myCbToSkipResultsWhenOneUsage != null){ + settings.setSkipResultsWithOneUsage(isSkipResultsWhenOneUsage()); + } + + super.doOKAction(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(FindUsagesManager.getHelpID(myPsiElement)); + } + + protected static boolean isToChange(JCheckBox cb) { + if (cb == null){ + return false; + } + return cb.getParent() != null; + } + + protected static boolean isSelected(JCheckBox cb) { + if (cb == null){ + return false; + } + if (cb.getParent() == null) { + return false; + } + return cb.isSelected(); + } + + protected StateRestoringCheckBox addCheckboxToPanel(String name, boolean toSelect, JPanel panel, boolean toUpdate, char mnemonic) { + StateRestoringCheckBox cb = new StateRestoringCheckBox(name); + cb.setMnemonic(mnemonic); + cb.setSelected(toSelect); + panel.add(cb); + if (toUpdate){ + cb.addActionListener(myUpdateAction); + } + return cb; + } + + protected JPanel createAllOptionsPanel(){ + JPanel allOptionsPanel = new JPanel(); + + JPanel findWhatPanel = createFindWhatPanel(); + JPanel usagesOptionsPanel = createUsagesOptionsPanel(); + int grids = 0; + if(findWhatPanel != null){ + grids++; + } + if(usagesOptionsPanel != null){ + grids++; + } + if(grids != 0){ + allOptionsPanel.setLayout(new GridLayout(1, grids, 8, 0)); + if(findWhatPanel != null){ + allOptionsPanel.add(findWhatPanel); + } + if(usagesOptionsPanel != null){ + allOptionsPanel.add(usagesOptionsPanel); + } + } + + JComponent scopePanel = createSearchScopePanel(); + if (scopePanel != null) { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(allOptionsPanel, BorderLayout.CENTER); + panel.add(scopePanel, BorderLayout.SOUTH); + return panel; + } + + return allOptionsPanel; + } + + protected abstract JPanel createFindWhatPanel(); + + protected JPanel createUsagesOptionsPanel() { + JPanel optionsPanel = new JPanel(); + optionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Options")); + optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.Y_AXIS)); + + boolean isEmpty = true; + + if(mySearchInNonJavaFilesAvailable){ + myCbToSearchInNonJavaFiles = addCheckboxToPanel("Search in non-java files", FindSettings.getInstance().isSearchInNonJavaFiles(), optionsPanel, false, 'j'); + isEmpty = false; + } + + if (myIsShowInNewTabVisible){ + myCbToSkipResultsWhenOneUsage = addCheckboxToPanel("Skip results tab with one usage", FindSettings.getInstance().isSkipResultsWithOneUsage(), optionsPanel, false, 'k'); + isEmpty = false; + } + + if (myIncludeOverloadedMethodsAvailable){ + myCbIncludeOverloadedMethods = addCheckboxToPanel("Include overloaded methods", FindSettings.getInstance().isSearchOverloadedMethods(), optionsPanel, false, 'v'); + isEmpty = false; + } + + + if(isEmpty){ + return null; + } + else{ + return optionsPanel; + } + } + + protected JComponent createSearchScopePanel() { + if (isInFileOnly()) return null; + JPanel optionsPanel = new JPanel(new BorderLayout()); + JLabel label = new JLabel("Scope: "); + label.setDisplayedMnemonic('s'); + optionsPanel.add(label, BorderLayout.WEST); + myScopeCombo = new ScopeChooserCombo(myProject, mySearchInLibrariesAvailable, true, FindSettings.getInstance().getDefaultScopeName()); + optionsPanel.add(myScopeCombo, BorderLayout.CENTER); + label.setLabelFor(myScopeCombo.getComboBox()); + return optionsPanel; + } + + protected abstract JComponent getPreferredFocusedControl(); + + public JComponent getPreferredFocusedComponent() { + if (myScopeCombo != null) { + return myScopeCombo.getComboBox(); + } + return getPreferredFocusedControl(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesManager.java new file mode 100644 index 00000000000..006df8b5120 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesManager.java @@ -0,0 +1,892 @@ +package com.intellij.find.findUsages; + +import com.intellij.aspects.psi.PsiPointcut; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.find.impl.HelpID; +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorLocation; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.search.ThrowSearchUtil; +import com.intellij.psi.search.*; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.XmlAttributeDecl; +import com.intellij.psi.xml.XmlElementDecl; +import com.intellij.psi.xml.XmlTag; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.StateRestoringCheckBox; +import com.intellij.ui.content.Content; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewManager; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.usages.*; +import com.intellij.util.Processor; +import com.intellij.util.containers.ContainerUtil; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class FindUsagesManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.find.findParameterUsages.FindUsagesManager"); + + private static HashMap findHandlers = new HashMap(); + + public static final int FROM_START = 0; + public static final int FROM_END = 3; + public static final int AFTER_CARET = 1; + public static final int BEFORE_CARET = 2; + + private static Key KEY_START_USAGE_AGAIN = Key.create("KEY_START_USAGE_AGAIN"); + private Project myProject; + private com.intellij.usages.UsageViewManager myAnotherManager; + private boolean myToOpenInNewTab = false; + private FindUsagesOptions myFindPackageOptions; + private FindUsagesOptions myFindClassOptions; + private FindUsagesOptions myFindMethodOptions; + private FindUsagesOptions myFindVariableOptions; + private FindUsagesOptions myFindPointcutOptions; + + private class LastSearchData { + public SmartPsiElementPointer[] myLastSearchElements = null; + public FindUsagesOptions myLastOptions = null; + } + + public interface FindUsagesHandler extends UsageViewUtil.UsageViewHandler { + boolean canFindUsagesFor(PsiElement element); + + FindUsagesDialog createFindUsagesDialog(PsiElement element, + Project project, + FindUsagesOptions findUsagesOptions, + boolean isSingleFile, + boolean isOpenInNewTab, + boolean isOpenInNewTabEnabled); + + String getHelpId(PsiElement element); + } + + static public class HtmlFindUsagesHandler implements FindUsagesHandler { + private FindUsagesHandler styleHandler; + + public void setStyleHandler(FindUsagesHandler handler) { + styleHandler = handler; + } + + public boolean canFindUsagesFor(PsiElement element) { + boolean result = element instanceof XmlElementDecl || element instanceof XmlAttributeDecl; + + if (!result && styleHandler != null) { + result = styleHandler.canFindUsagesFor(element); + } + return result; + } + + public FindUsagesDialog createFindUsagesDialog(final PsiElement element, + Project project, + FindUsagesOptions findUsagesOptions, + boolean isSingleFile, + boolean isOpenInNewTab, + boolean isOpenInNewTabEnabled) { + if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { + return styleHandler.createFindUsagesDialog(element, project, findUsagesOptions, isSingleFile, isOpenInNewTab, + isOpenInNewTabEnabled); + } + + return new FindUsagesDialog(element,project,findUsagesOptions,isOpenInNewTab,isOpenInNewTabEnabled,isSingleFile) { + private StateRestoringCheckBox myCbUsages; + + public FindUsagesOptions getShownOptions() { + return new FindUsagesOptions(element.getProject(), SearchScopeCache.getInstance(element.getProject())); + } + + protected void update() { + //To change body of implemented methods use File | Settings | File Templates. + } + + protected JPanel createFindWhatPanel() { + JPanel findWhatPanel = new JPanel(); + findWhatPanel.setBorder(IdeBorderFactory.createTitledBorder("Find")); + findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS)); + + myCbUsages = addCheckboxToPanel("Usages", myFindUsagesOptions.isUsages, findWhatPanel, true, 'U'); + return findWhatPanel; + } + + protected JComponent getPreferredFocusedControl() { + return myCbUsages; + } + }; + } + + public String getType(PsiElement element) { + if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { + return styleHandler.getType(element); + } + + if (element instanceof XmlElementDecl || element instanceof XmlTag) { + return "tag"; + } else if (element instanceof XmlAttributeDecl) { + return "attribute"; + } + + return null; + } + + public String getHelpId(PsiElement element) { + if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { + return styleHandler.getHelpId(element); + } + return null; + } + + public String getDescriptiveName(PsiElement element) { + if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { + return styleHandler.getDescriptiveName(element); + } + return ((PsiNamedElement)element).getName(); + } + + public String getNodeText(PsiElement element, boolean useFullName) { + if (styleHandler != null && styleHandler.canFindUsagesFor(element)) { + return styleHandler.getNodeText(element, useFullName); + } + + return ((PsiNamedElement)element).getName(); + } + } + + static { + HtmlFindUsagesHandler handler = new HtmlFindUsagesHandler(); + registerFindHandler(StdFileTypes.HTML, handler); + registerFindHandler(StdFileTypes.XHTML, handler); + registerFindHandler(StdFileTypes.DTD, handler); + registerFindHandler(StdFileTypes.XML, handler); + + UsageViewUtil.registerUsageViewHandler(StdFileTypes.HTML, handler); + UsageViewUtil.registerUsageViewHandler(StdFileTypes.XHTML, handler); + UsageViewUtil.registerUsageViewHandler(StdFileTypes.DTD, handler); + UsageViewUtil.registerUsageViewHandler(StdFileTypes.XML, handler); + } + + private LastSearchData myLastSearchData = new LastSearchData(); + + public FindUsagesManager(Project project, SearchScopeCache searchScopeCache, com.intellij.usages.UsageViewManager anotherManager) { + myProject = project; + myAnotherManager = anotherManager; + + myFindPackageOptions = createFindUsagesOptions(searchScopeCache); + myFindClassOptions = createFindUsagesOptions(searchScopeCache); + myFindMethodOptions = createFindUsagesOptions(searchScopeCache); + myFindVariableOptions = createFindUsagesOptions(searchScopeCache); + myFindPointcutOptions = createFindUsagesOptions(searchScopeCache); + } + + public static void registerFindHandler(FileType fileType, FindUsagesHandler handler) { + findHandlers.put(fileType, handler); + } + + public static FindUsagesHandler getFindHandler(FileType fileType) { + return findHandlers.get(fileType); + } + + private FindUsagesOptions createFindUsagesOptions(SearchScopeCache searchScopeCache) { + FindUsagesOptions findUsagesOptions = new FindUsagesOptions(myProject, searchScopeCache); + findUsagesOptions.isUsages = true; + findUsagesOptions.isIncludeOverloadUsages = false; + findUsagesOptions.isIncludeSubpackages = true; + findUsagesOptions.isReadAccess = true; + findUsagesOptions.isWriteAccess = true; + findUsagesOptions.isCheckDeepInheritance = true; + findUsagesOptions.isSearchInNonJavaFiles = true; + return findUsagesOptions; + } + + public boolean canFindUsages(final PsiElement element) { + if (element == null) { + return false; + } + + if (!((element instanceof PsiDirectory) || + (element instanceof PsiClass) || + (element instanceof PsiVariable) || + (element instanceof PsiPointcutDef) || + (element instanceof PsiPackage) || + (ThrowSearchUtil.isSearchable(element)) || + (element instanceof PsiMethod))) { + PsiFile containingFile = element.getContainingFile(); + FindUsagesHandler handler = (containingFile != null) ? getFindHandler(containingFile.getFileType()) : null; + if (handler != null && handler.canFindUsagesFor(element)) return true; + return false; + } + + if (element instanceof PsiDirectory) { + PsiPackage psiPackage = ((PsiDirectory)element).getPackage(); + if (psiPackage == null) { + return false; + } + return psiPackage.getQualifiedName().length() != 0; + } + + return true; + } + + public void clearFindingNextUsageInFile() { + myLastSearchData.myLastOptions = null; + myLastSearchData.myLastSearchElements = null; + } + + public boolean findNextUsageInFile(FileEditor editor) { + return findUsageInFile(editor, AFTER_CARET); + } + + public boolean findPreviousUsageInFile(FileEditor editor) { + return findUsageInFile(editor, BEFORE_CARET); + } + + private boolean findUsageInFile(FileEditor editor, int direction) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + + SmartPsiElementPointer[] lastSearchElements = myLastSearchData.myLastSearchElements; + if (lastSearchElements == null) return false; + List elements = new ArrayList(); + for (int i = 0; i < lastSearchElements.length; i++) { + SmartPsiElementPointer pointer = lastSearchElements[i]; + PsiElement element = pointer.getElement(); + if (element != null) elements.add(element); + } + if (elements.size() == 0) { + Messages.showMessageDialog(myProject, + "Searched elements have been changed.\n" + + "Cannot search for usages.", + "Cannot Search for Usages", + Messages.getInformationIcon()); + // SCR #10022 + //clearFindingNextUsageInFile(); + return true; + } + + //todo + TextEditor textEditor = (TextEditor)editor; + Document document = textEditor.getEditor().getDocument(); + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if (psiFile == null) return false; + + + PsiElement[] allElements = elements.toArray(new PsiElement[elements.size()]); + FindUsagesOptions options = myLastSearchData.myLastOptions; + + + findUsagesInEditor(allElements, psiFile, direction, options, textEditor); + return true; + } + + + private void initLastSearchElement(final PsiElement[] elements, final FindUsagesOptions findUsagesOptions) { + myLastSearchData.myLastSearchElements = new SmartPsiElementPointer[elements.length]; + for (int i = 0; i < elements.length; i++) { + myLastSearchData.myLastSearchElements[i] = SmartPointerManager.getInstance(myProject) + .createSmartPsiElementPointer(elements[i]); + } + myLastSearchData.myLastOptions = findUsagesOptions; + } + + public void findUsages(PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor) { + PsiElement[] elementsToSearch = null; + if (!canFindUsages(psiElement)) { + return; + } + + + if (psiElement instanceof PsiDirectory) { + PsiPackage psiPackage = ((PsiDirectory)psiElement).getPackage(); + if (psiPackage == null) { + return; + } + psiElement = psiPackage; + } + + boolean isOpenInNewTabEnabled; + boolean toOpenInNewTab; + Content selectedContent = UsageViewManager.getInstance(myProject).getSelectedContent(true); + if (selectedContent != null && selectedContent.isPinned()) { + toOpenInNewTab = true; + isOpenInNewTabEnabled = false; + } + else { + toOpenInNewTab = myToOpenInNewTab; + isOpenInNewTabEnabled = (UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0); + } + + if (psiElement instanceof PsiMethod || psiElement instanceof PsiPointcutDef) { + psiElement = psiElement instanceof PsiMethod + ? + (PsiElement)SuperMethodWarningUtil.checkSuperMethod((PsiMethod)psiElement, "find usages of") + : + (PsiElement)SuperMethodWarningUtil.checkSuperPointcut((PsiPointcutDef)psiElement, + "find usages of"); + } + + if (psiElement == null) return; + final FindUsagesDialog dialog = getFindUsagesDialog(psiElement, scopeFile != null, toOpenInNewTab, isOpenInNewTabEnabled); + if (dialog == null) { + return; + } + dialog.show(); + if (!dialog.isOK()) { + return; + } + if (isOpenInNewTabEnabled) { + myToOpenInNewTab = toOpenInNewTab = dialog.isShowInSeparateWindow(); + } + + FindUsagesOptions findUsagesOptions = dialog.calcFindUsagesOptions(); + + if (scopeFile != null) { + findUsagesOptions = (FindUsagesOptions)findUsagesOptions.clone(); + findUsagesOptions.isDerivedClasses = false; + findUsagesOptions.isDerivedInterfaces = false; + findUsagesOptions.isImplementingClasses = false; + } + + clearFindingNextUsageInFile(); + LOG.assertTrue(psiElement.isValid()); + if (psiElement instanceof PsiParameter) { + final PsiParameter parameter = (PsiParameter)psiElement; + final PsiElement scope = parameter.getDeclarationScope(); + if (scope instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)scope; + if (PsiUtil.canBeOverriden(method)) { + final PsiClass aClass = method.getContainingClass(); + LOG.assertTrue(aClass != null); //Otherwise can not be overriden + final boolean findInInheritors; + if (aClass.isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT)) { + findInInheritors = true; + } + else { + findInInheritors = Messages.showDialog(psiElement.getProject(), + "Do you want to search usages of parameter '" + parameter.getName() + + "' in overriding methods?", + "Search in Overriding Methods", + new String[]{"Yes", "No"}, + 0, + Messages.getQuestionIcon()) == 0; + } + if (findInInheritors) { + elementsToSearch = getParameterElementsToSearch(parameter); + } + } + } + } + else if (psiElement instanceof PsiField) { + final PsiField field = (PsiField)psiElement; + if (field.getContainingClass() != null && field.getType() != null) { + final String propertyName = field.getManager().getCodeStyleManager().variableNameToPropertyName(field.getName(), + VariableKind.FIELD); + PsiMethod getter = PropertyUtil. + findPropertyGetterWithType(propertyName, field.hasModifierProperty(PsiModifier.STATIC), field.getType(), + ContainerUtil.iterate(field.getContainingClass().getMethods())); + PsiMethod setter = PropertyUtil. + findPropertySetterWithType(propertyName, field.hasModifierProperty(PsiModifier.STATIC), field.getType(), + ContainerUtil.iterate(field.getContainingClass().getMethods())); + if (getter != null || setter != null) { + if (Messages.showDialog("Do you want to search for accessors of '" + field.getName() + "'?", "Search Accessors", + new String[]{"Yes", "No"}, 0, + Messages.getQuestionIcon()) == + DialogWrapper.OK_EXIT_CODE) { + final List elements = new ArrayList(); + elements.add(field); + if (getter != null) { + getter = SuperMethodWarningUtil.checkSuperMethod(getter, "find usages of"); + if (getter == null) return; + elements.add(getter); + } + if (setter != null) { + setter = SuperMethodWarningUtil.checkSuperMethod(setter, "find usages of"); + if (setter == null) return; + elements.add(setter); + } + + elementsToSearch = elements.toArray(new PsiElement[elements.size()]); + } + } + } + } + + if (elementsToSearch == null) { + elementsToSearch = new PsiElement[] {psiElement}; + } + + + if (scopeFile == null) { + findUsages(elementsToSearch, dialog.isSkipResultsWhenOneUsage(), + toOpenInNewTab, findUsagesOptions); + } + else { + editor.putUserData(KEY_START_USAGE_AGAIN, null); + findUsagesInEditor(elementsToSearch, scopeFile, FROM_START, findUsagesOptions, editor); + } + } + + private PsiElement[] getParameterElementsToSearch(final PsiParameter parameter) { + final PsiMethod method = (PsiMethod)parameter.getDeclarationScope(); + PsiSearchHelper helper = parameter.getManager().getSearchHelper(); + PsiMethod[] overrides = helper.findOverridingMethods(method, GlobalSearchScope.allScope(myProject), true); + for (int i = 0; i < overrides.length; i++) { + overrides[i] = (PsiMethod)overrides[i].getNavigationElement(); + } + PsiElement[] elementsToSearch = new PsiElement[overrides.length + 1]; + elementsToSearch[0] = parameter; + int idx = method.getParameterList().getParameterIndex(parameter); + for (int i = 0; i < overrides.length; i++) { + elementsToSearch[i + 1] = overrides[i].getParameterList().getParameters()[idx]; + } + return elementsToSearch; + } + + private UsageInfo[] findJoinPointsByPointcut(PsiPointcut pointcut) { + final ArrayList usages = new ArrayList(); + PsiManager psiManager = PsiManager.getInstance(myProject); + PsiSearchHelper psiSearchHelper = psiManager.getSearchHelper(); + + psiSearchHelper.processJoinPointsByPointcut(new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + usages.add(new UsageInfo(element)); + return true; + } + }, pointcut, GlobalSearchScope.projectScope(myProject)); + + return usages.toArray(new UsageInfo[usages.size()]); + } + + public void findPointcutApplications(final PsiPointcut pointcut) { + final UsageInfo[][] usages = new UsageInfo[1][]; + + final Runnable findUsagesRunnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + usages[0] = findJoinPointsByPointcut(pointcut); + } + }); + } + }; + + final FindUsagesCommand findUsagesCommand = new FindUsagesCommand() { + public UsageInfo[] execute(final PsiElement[] elementsToSearch) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (elementsToSearch.length == 1 && + elementsToSearch[0] instanceof PsiPointcut && + elementsToSearch[0].isValid()) { + usages[0] = findJoinPointsByPointcut((PsiPointcut)elementsToSearch[0]); + } + else { + // should not happen + LOG.assertTrue(false); + } + } + }); + return usages[0]; + } + + }; + + if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously(findUsagesRunnable, + "Looking for applications of poincut(TODO)...", true, + myProject)) { + return; + } + + if ((usages[0] != null) && (usages[0].length > 0)) { + FindUsagesViewDescriptor descriptor = new FindUsagesViewDescriptor(pointcut.getParent(), usages[0], + findUsagesCommand, false); //TODO + showUsagesPanel("Applications of pointcut(TODO)", null, descriptor, true, false, false); + } + else { + Messages.showMessageDialog(myProject, "No applications(TODO) found", "Information", + Messages.getInformationIcon()); + } + } + + private UsageSearcher getUsageSearcher(final PsiElement[] elementsToSearch, + final FindUsagesOptions options, + final PsiFile scopeFile) { + return new UsageSearcher() { + public void generate(final Processor processor) { + if (scopeFile != null) { + options.searchScope = new LocalSearchScope(scopeFile); + } + for (int i = 0; i < elementsToSearch.length; i++) { + final PsiElement elementToSearch = elementsToSearch[i]; + if (elementToSearch != null && elementToSearch.isValid()) { + FindUsagesUtil.processUsages(elementToSearch, new Processor() { + public boolean process(UsageInfo usageInfo) { + return processor.process(new UsageInfo2UsageAdapter(usageInfo)); + } + }, options); + } + } + } + }; + } + + private void findUsages(final PsiElement[] elementsToSearch, + final boolean toSkipUsagePanelWhenOneUsage, + final boolean toOpenInNewTab, + final FindUsagesOptions findUsagesOptions) { + PsiElement[] elementsToDisplay = elementsToSearch; + PsiElement psiElement = elementsToSearch[0]; + if (findUsagesOptions.isIncludeOverloadUsages) { + LOG.assertTrue(elementsToSearch.length == 1 && psiElement instanceof PsiMethod); + elementsToDisplay = MethodSignatureUtil.getOverloads((PsiMethod)psiElement); + } + + UsageViewPresentation presentation = createPresentation(psiElement, findUsagesOptions, toOpenInNewTab); + + Factory searcherFactory = new Factory() { + public UsageSearcher create() { + return getUsageSearcher(elementsToSearch, findUsagesOptions, null); + } + }; + + myAnotherManager.searchAndShowUsages(convertTargets(elementsToDisplay), + searcherFactory, !toSkipUsagePanelWhenOneUsage, true, presentation); + } + + private UsageViewPresentation createPresentation(PsiElement psiElement, + final FindUsagesOptions findUsagesOptions, + boolean toOpenInNewTab) { + UsageViewPresentation presentation = new UsageViewPresentation(); + String scopeString = findUsagesOptions.searchScope != null ? findUsagesOptions.searchScope.getDisplayName() : null; + presentation.setScopeText(scopeString); + String usagesString = generateUsagesString(findUsagesOptions, false, true); + presentation.setUsagesString(usagesString); + String title = usagesString + " of " + UsageViewUtil.getShortName(psiElement); + if (scopeString != null) title += " in " + scopeString; + presentation.setTabText(title); + presentation.setTargetsNodeText(UsageViewUtil.capitalize(UsageViewUtil.getType(psiElement))); + presentation.setOpenInNewTab(toOpenInNewTab); + return presentation; + } + + private void findUsagesInEditor(final PsiElement[] elementsToSearch, + final PsiFile scopeFile, + final int direction, + final FindUsagesOptions findUsagesOptions, + FileEditor fileEditor) { + LOG.assertTrue(fileEditor != null); + initLastSearchElement(elementsToSearch, findUsagesOptions); + + clearStatusBar(); + + final FileEditorLocation currentLocation = fileEditor.getCurrentLocation(); + + final UsageSearcher usageSearcher = getUsageSearcher(elementsToSearch, findUsagesOptions, scopeFile); + final boolean[] usagesWereFound = new boolean[]{false}; + + Usage fUsage = findSiblingUsage(usageSearcher, direction, currentLocation, usagesWereFound, fileEditor); + + if (fUsage != null) { + fUsage.navigate(true); + fUsage.selectInEditor(); + } + else if (!usagesWereFound[0]) { + String message = getNoUsagesFoundMessage(elementsToSearch[0]); + + showHintOrStatusBarMessage(message, fileEditor); + } + else { + fileEditor.putUserData(KEY_START_USAGE_AGAIN, "START_AGAIN"); + + showHintOrStatusBarMessage(getSearchAgainMessage(elementsToSearch[0], direction), fileEditor); + } + } + + private String getNoUsagesFoundMessage(PsiElement psiElement) { + String elementType = UsageViewUtil.getType(psiElement); + String elementName = UsageViewUtil.getShortName(psiElement); + String message = "Usages of " + elementType + " " + elementName + " not found"; + return message; + } + + private void clearStatusBar() { + StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); + statusBar.setInfo(""); + } + + private String getSearchAgainMessage(PsiElement element, final int direction) { + String message = getNoUsagesFoundMessage(element); + if (direction == FindUsagesManager.AFTER_CARET) { + AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT); + String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else { + message += ", perform \"Find Next\" again "; + } + message += " to search from the top"; + } + else { + String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText( + ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_PREVIOUS)); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else { + message += ", perform \"Find Previous\" again "; + } + message += " to search from the bottom"; + } + return message; + } + + private void showHintOrStatusBarMessage(String message, FileEditor fileEditor) { + if (fileEditor instanceof TextEditor) { + TextEditor textEditor = (TextEditor)fileEditor; + showEditorHint(message, textEditor.getEditor()); + } + else { + StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); + statusBar.setInfo(message); + } + } + + private Usage findSiblingUsage(final UsageSearcher usageSearcher, + int dir, + final FileEditorLocation currentLocation, + final boolean[] usagesWereFound, + FileEditor fileEditor) { + final Usage[] foundUsage = new Usage[]{null}; + + if (fileEditor.getUserData(KEY_START_USAGE_AGAIN) != null) { + if (dir == AFTER_CARET) dir = FROM_START; + else dir = FROM_END; + } + + final int direction = dir; + + + usageSearcher.generate( + new Processor() { + public boolean process(Usage usage) { + usagesWereFound[0] = true; + + if (direction == FROM_START) { + foundUsage[0] = usage; + return false; + } + else if (direction == FROM_END) { + foundUsage[0] = usage; + } + else if (direction == AFTER_CARET) { + if (usage.getLocation().compareTo(currentLocation) > 0) { + foundUsage[0] = usage; + return false; + } + } + else if (direction == BEFORE_CARET) { + if (usage.getLocation().compareTo(currentLocation) < 0) { + if (foundUsage[0] != null) { + if (foundUsage[0].getLocation().compareTo(usage.getLocation()) < 0) { + foundUsage[0] = usage; + } + } + else { + foundUsage[0] = usage; + } + } + else { + return false; + } + } + + return true; + } + }); + + fileEditor.putUserData(KEY_START_USAGE_AGAIN, null); + + Usage fUsage = foundUsage[0]; + return fUsage; + } + + private UsageTarget[] convertTargets(PsiElement[] elementsToDisplay) { + UsageTarget[] targets = new UsageTarget[elementsToDisplay.length]; + for (int i = 0; i < targets.length; i++) { + PsiElement display = elementsToDisplay[i]; + if (display instanceof NavigationItem) { + final NavigationItem item = (NavigationItem)display; + targets[i] = new PsiElement2UsageTargetAdapter((PsiElement)item); + } + else { + throw new IllegalArgumentException("Wrong usage target:" + display); + } + } + return targets; + } + + private static String generateUsagesString(final FindUsagesOptions selectedOptions, + final boolean useAndWord, + boolean beginWithCapitals) { + String usagesString = ""; + String suffix = useAndWord ? " and " : " or "; + ArrayList strings = new ArrayList(); + FindUsagesOptions localShownFindUsagesOptions = selectedOptions; + if ((selectedOptions.isUsages && localShownFindUsagesOptions.isUsages) + || (selectedOptions.isClassesUsages && localShownFindUsagesOptions.isClassesUsages) + || (selectedOptions.isMethodsUsages && localShownFindUsagesOptions.isMethodsUsages) + || (selectedOptions.isFieldsUsages && localShownFindUsagesOptions.isFieldsUsages)) { + strings.add(beginWithCapitals ? "Usages" : "usages"); + } + if (selectedOptions.isIncludeOverloadUsages && localShownFindUsagesOptions.isIncludeOverloadUsages) { + strings.add(beginWithCapitals ? "Overloaded Methods Usages" : "overloaded methods usages"); + } + if ((selectedOptions.isDerivedClasses && localShownFindUsagesOptions.isDerivedClasses)) { + strings.add(beginWithCapitals ? "Derived Classes" : "derived classes"); + } + if ((selectedOptions.isDerivedInterfaces && localShownFindUsagesOptions.isDerivedInterfaces)) { + strings.add(beginWithCapitals ? "Derived Interfaces" : "derived interfaces"); + } + if ((selectedOptions.isImplementingClasses && localShownFindUsagesOptions.isImplementingClasses)) { + strings.add(beginWithCapitals ? "Implementing Classes" : "implementing classes"); + } + if ((selectedOptions.isImplementingMethods && localShownFindUsagesOptions.isImplementingMethods)) { + strings.add(beginWithCapitals ? "Implementing Methods" : "implementing methods"); + } + if ((selectedOptions.isOverridingMethods && localShownFindUsagesOptions.isOverridingMethods)) { + strings.add(beginWithCapitals ? "Overriding Methods" : "overriding methods"); + } + if (strings.size() == 0) { + strings.add(beginWithCapitals ? "Usages" : "usages"); + } + for (int i = 0; i < strings.size(); i++) { + String s = strings.get(i); + usagesString += (i == strings.size() - 1) ? s : s + suffix; + } + return usagesString; + } + + private void showEditorHint(String message, final Editor editor) { + HintManager hintManager = HintManager.getInstance(); + JComponent component = HintUtil.createInformationLabel(message); + final LightweightHint hint = new LightweightHint(component); + hintManager.showEditorHint(hint, editor, HintManager.UNDER, + HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | + HintManager.HIDE_BY_SCROLLING, + 0, false); + } + + private void showUsagesPanel(String usagesString, + String scopeString, + final FindUsagesViewDescriptor viewDescriptor, + boolean toOpenInNewTab, + boolean showReadAccessIcon, + boolean showWriteAccessIcon) { + String title = usagesString + " of " + UsageViewUtil.getShortName(viewDescriptor.getElement()); + if (scopeString != null) title += " in " + scopeString; + UsageViewManager.getInstance(myProject).addContent(title, viewDescriptor, true, + showReadAccessIcon, showWriteAccessIcon, toOpenInNewTab, true); + } + + public static String getHelpID(PsiElement element) { + String helpID = null; + if (element instanceof PsiPackage) { + helpID = HelpID.FIND_PACKAGE_USAGES; + } + else if (element instanceof PsiClass) { + helpID = HelpID.FIND_CLASS_USAGES; + } + else if (element instanceof PsiMethod) { + helpID = HelpID.FIND_METHOD_USAGES; + } + else if (ThrowSearchUtil.isSearchable(element)) { + helpID = HelpID.FIND_THROW_USAGES; + } + else if (element instanceof PsiField) { + helpID = HelpID.FIND_FIELD_USAGES; + } + else if (element instanceof PsiLocalVariable) { + helpID = HelpID.FIND_VARIABLE_USAGES; + } + else if (element instanceof PsiParameter) { + helpID = HelpID.FIND_PARAMETER_USAGES; + } + else { + final FindUsagesHandler findHandler = getFindHandler(element.getContainingFile().getFileType()); + if (findHandler != null) { + helpID = findHandler.getHelpId(element); + } + } + return helpID; + } + + private FindUsagesDialog getFindUsagesDialog(PsiElement element, + boolean isSingleFile, + boolean isOpenInNewTab, + boolean isOpenInNewTabEnabled) { + if (element instanceof PsiPackage) { + return new FindPackageUsagesDialog(element, myProject, myFindPackageOptions, isOpenInNewTab, + isOpenInNewTabEnabled, isSingleFile); + } + else if (element instanceof PsiClass) { + return new FindClassUsagesDialog(element, myProject, myFindClassOptions, isOpenInNewTab, isOpenInNewTabEnabled, + isSingleFile); + } + else if (element instanceof PsiMethod) { + return new FindMethodUsagesDialog(element, myProject, myFindMethodOptions, isOpenInNewTab, isOpenInNewTabEnabled, + isSingleFile); + } + else if (element instanceof PsiVariable) { + return new FindVariableUsagesDialog(element, myProject, myFindVariableOptions, isOpenInNewTab, + isOpenInNewTabEnabled, isSingleFile); + } + else if (element instanceof PsiPointcutDef) { + return new FindPointcutUsagesDialog(element, myProject, myFindPointcutOptions, isOpenInNewTab, + isOpenInNewTabEnabled, isSingleFile); + } + else if (ThrowSearchUtil.isSearchable(element)) { + return new FindThrowUsagesDialog(element, myProject, myFindPointcutOptions, isOpenInNewTab, + isOpenInNewTabEnabled, isSingleFile); + } + else { + PsiFile containingFile = element.getContainingFile(); + FindUsagesHandler handler = (containingFile != null) ? getFindHandler(containingFile.getFileType()) : null; + if (handler != null) { + return handler.createFindUsagesDialog(element, myProject, createFindUsagesOptions(SearchScopeCache.getInstance(myProject)), + isSingleFile, isOpenInNewTab, isOpenInNewTabEnabled); + } + return null; + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesOptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesOptions.java new file mode 100644 index 00000000000..8b520d83592 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesOptions.java @@ -0,0 +1,79 @@ + +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.psi.impl.search.ThrowSearchUtil; + +/** + * + */ +public class FindUsagesOptions implements Cloneable { + public SearchScope searchScope; + + public boolean isSearchInNonJavaFiles = true; + + public boolean isUsages = false; + public boolean isClassesUsages = false; + public boolean isMethodsUsages = false; + public boolean isFieldsUsages = false; + public boolean isDerivedClasses = false; + public boolean isImplementingClasses = false; + public boolean isDerivedInterfaces = false; + public boolean isOverridingMethods = false; + public boolean isImplementingMethods = false; + public boolean isIncludeSubpackages = true; + public boolean isSkipImportStatements = false; + public boolean isSkipPackageStatements = false; + public boolean isCheckDeepInheritance = true; + public boolean isIncludeInherited = false; + public boolean isReadAccess = false; + public boolean isWriteAccess = false; + public boolean isImplementingPointcuts = false; + public boolean isOverridingPointcuts = false; + public boolean isIncludeOverloadUsages = false; + public boolean isThrowUsages = false; + public boolean isStrictThrowUsages = false; + public ThrowSearchUtil.Root myThrowRoot = null; + + public FindUsagesOptions(final Project project, SearchScopeCache searchScopeCache) { + searchScope = searchScopeCache.getProjectScope(); + } + + public Object clone() { + try{ + return super.clone(); + } + catch(CloneNotSupportedException e){ + return null; + } + } + + public void clear() { + isSearchInNonJavaFiles = false; + isUsages = false; + isClassesUsages = false; + isMethodsUsages = false; + isFieldsUsages = false; + isDerivedClasses = false; + isImplementingClasses = false; + isDerivedInterfaces = false; + isOverridingMethods = false; + isImplementingMethods = false; + isIncludeSubpackages = false; + isSkipImportStatements = false; + isSkipPackageStatements = false; + isCheckDeepInheritance = false; + isIncludeInherited = false; + isReadAccess = false; + isWriteAccess = false; + isImplementingPointcuts = false; + isOverridingPointcuts = false; + isIncludeOverloadUsages = false; + isThrowUsages = false; + isStrictThrowUsages = false; + myThrowRoot = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesUtil.java new file mode 100644 index 00000000000..710f0f72d7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindUsagesUtil.java @@ -0,0 +1,599 @@ + +package com.intellij.find.findUsages; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.j2ee.ejb.EjbUsagesUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.search.ThrowSearchUtil; +import com.intellij.psi.search.*; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.Processor; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class FindUsagesUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.find.findUsages.FindUsagesUtil"); + + public static void processUsages(PsiElement element, final Processor processor, final FindUsagesOptions options) { + if (LOG.isDebugEnabled()){ + LOG.debug("findUsages: element = " + element + ", options = " + options); + } + + if (element instanceof PsiVariable){ + if (options.isReadAccess || options.isWriteAccess){ + if (options.isReadAccess && options.isWriteAccess){ + //todo[myakovlev] this also shows param in javadoc (PsiDocParamRef), but should not + addElementUsages(element, processor, options); + } + else{ + addElementUsages(element, new Processor() { + public boolean process(UsageInfo info) { + boolean isWrite = isAccessedForWriting(info.getElement()); + if (isWrite == options.isWriteAccess) { + if (!processor.process(info)) return false; + } + return true; + } + }, options); + } + } + } + else{ + if (options.isUsages){ + addElementUsages(element, processor, options); + } + } + + if (ThrowSearchUtil.isSearchable (element) && options.isThrowUsages) { + new ThrowSearchUtil (processor, options.myThrowRoot, options).run(); + } + + if (element instanceof PsiPackage && options.isClassesUsages){ + addClassesUsages((PsiPackage)element, processor, options); + } + + if (element instanceof PsiClass && options.isMethodsUsages){ + addMethodsUsages((PsiClass)element, processor, options); + } + + if (element instanceof PsiClass && options.isFieldsUsages){ + addFieldsUsages((PsiClass)element, processor, options); + } + + if (element instanceof PsiClass){ + if (!((PsiClass)element).isInterface()){ + if (options.isDerivedClasses){ + addInheritors((PsiClass)element, processor, options); + } + } + else{ + if (options.isDerivedInterfaces){ + if (options.isImplementingClasses){ + addInheritors((PsiClass)element, processor, options); + } + else{ + addDerivedInterfaces((PsiClass)element, processor, options); + } + } + else if (options.isImplementingClasses){ + addImplementingClasses((PsiClass)element, processor, options); + } + } + } + + if (element instanceof PsiMethod){ + PsiSearchHelper searchHelper = element.getManager().getSearchHelper(); + final PsiMethod psiMethod = (PsiMethod)element; + if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)){ + if (options.isOverridingMethods){ + processOverridingMethods(psiMethod, processor, searchHelper, options); + } + } + else{ + if (options.isImplementingMethods){ + processOverridingMethods(psiMethod, processor, searchHelper, options); + } + } + } + + if (element instanceof PsiPointcutDef){ + PsiSearchHelper searchHelper = element.getManager().getSearchHelper(); + PsiPointcutDef pointcut = (PsiPointcutDef)element; + if (!pointcut.hasModifierProperty(PsiModifier.ABSTRACT)){ + if (options.isOverridingPointcuts){ + PsiPointcutDef[] pointcuts = searchHelper.findOverridingPointcuts(pointcut, options.searchScope, options.isCheckDeepInheritance); + addResults(processor, pointcuts, options, null); + } + } + else{ + if (options.isImplementingPointcuts){ + PsiPointcutDef[] pointcuts = searchHelper.findOverridingPointcuts(pointcut, options.searchScope, options.isCheckDeepInheritance); + addResults(processor, pointcuts, options, null); + } + } + } + + if (options.isSearchInNonJavaFiles && options.searchScope instanceof GlobalSearchScope) { + String stringToSearch = getStringToSearch(element); + RefactoringUtil.UsageInfoFactory factory = new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + return new UsageInfo(usage, startOffset, endOffset, true); + } + }; + RefactoringUtil.processUsagesInNonJavaFiles(element, stringToSearch, (GlobalSearchScope)options.searchScope, processor, factory); + } + } + + private static void processOverridingMethods(final PsiMethod psiMethod, + final Processor processor, + PsiSearchHelper searchHelper, final FindUsagesOptions options) { + searchHelper.processOverridingMethods(new PsiElementProcessor() { + public boolean execute(PsiMethod element) { + addResult(processor, element.getNavigationElement(), options, null); + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, psiMethod, options.searchScope, options.isCheckDeepInheritance); + } + + /** + * @deprecated use processUsages instead. + * @param element + * @param options + * @return + */ + public static UsageInfo[] findUsages(PsiElement element, final FindUsagesOptions options) { + final List results = new ArrayList(); + processUsages(element, new Processor() { + public boolean process(UsageInfo t) { + results.add(t); + return true; + } + }, options); + return results.toArray(new UsageInfo[results.size()]); + } + + public static String getStringToSearch(PsiElement element) { + if (element instanceof PsiDirectory) { // normalize a directory to a corresponding package + element = ((PsiDirectory)element).getPackage(); + } + if (element instanceof PsiPackage){ + return ((PsiPackage)element).getQualifiedName(); + } + else if (element instanceof PsiClass){ + return ((PsiClass)element).getQualifiedName(); + } + else if (element instanceof PsiMethod){ + return ((PsiMethod)element).getName(); + } + else if (element instanceof PsiVariable){ + return ((PsiVariable)element).getName(); + } + else{ + LOG.error("Unknown element type"); + return null; + } + } + + private static void addElementUsages(final PsiElement element, final Processor results, final FindUsagesOptions options) { + if (element instanceof PsiMethod){ + addMethodUsages((PsiMethod)element, results, options, options.searchScope); + } + else{ + PsiSearchHelper helper = element.getManager().getSearchHelper(); + helper.processReferences(new PsiReferenceProcessor() { + public boolean execute(PsiReference ref) { + addResult(results, ref, options, element); + return true; + } + }, element, options.searchScope, false); + } + } + + private static void addMethodUsages(final PsiMethod method, final Processor result, final FindUsagesOptions options, SearchScope searchScope) { + PsiSearchHelper helper = method.getManager().getSearchHelper(); + if (method.isConstructor()) { + if (!options.isIncludeOverloadUsages) { + addConstructorUsages(method, helper, searchScope, result, options); + } else { + PsiMethod[] constructors = method.getContainingClass().getConstructors(); + for (int i = 0; i < constructors.length; i++) { + addConstructorUsages(constructors[i], helper, searchScope, result, options); + } + } + } + else { + helper.processReferencesIncludingOverriding(new PsiReferenceProcessor() { + public boolean execute(PsiReference ref) { + addResult(result, ref, options, method); + return true; + } + }, method, searchScope, !options.isIncludeOverloadUsages); + + PsiReference[] refs = EjbUsagesUtil.findEjbMethodReferences(method, helper, searchScope, !options.isIncludeOverloadUsages); + addResults(result, refs, options, method); + } + } + + private static void addConstructorUsages(PsiMethod method, PsiSearchHelper helper, SearchScope searchScope, final Processor result, final FindUsagesOptions options) { + final PsiClass parentClass = method.getContainingClass(); + if (parentClass == null) return; + + helper.processReferences(new PsiReferenceProcessor() { + public boolean execute(PsiReference ref) { + addResult(result, ref, options, parentClass); + return true; + } + }, method, searchScope, false); + + addImplicitConstructorCalls(method, result, searchScope); + } + + private static void addImplicitConstructorCalls(final PsiMethod constructor, final Processor result, SearchScope searchScope){ + if (constructor.getParameterList().getParameters().length > 0) return; + if (constructor.hasModifierProperty(PsiModifier.PRIVATE)) return; + + PsiClass parentClass = constructor.getContainingClass(); + + final PsiManager manager = constructor.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + helper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + PsiClass inheritor = element; + if (inheritor instanceof PsiAnonymousClass){ + PsiMethod constructor1 = null; + PsiElement parent = inheritor.getParent(); + if (parent instanceof PsiConstructorCall) { + constructor1 = ((PsiConstructorCall)parent).resolveConstructor(); + } + + if (constructor1 != null && manager.areElementsEquivalent(constructor, constructor1)){ + result.process(new UsageInfo(inheritor)); + } + } + else{ + PsiMethod[] constructors = inheritor.getConstructors(); + if (constructors.length == 0){ + result.process(new UsageInfo(inheritor)); // implicit default constructor + } + else{ + for(int j = 0; j < constructors.length; j++){ + PsiMethod superConstructor = constructors[j]; + PsiCodeBlock body = superConstructor.getBody(); + if (body == null) continue; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0){ + PsiStatement firstStatement = statements[0]; + if (firstStatement instanceof PsiExpressionStatement){ + PsiExpression expr = ((PsiExpressionStatement)firstStatement).getExpression(); + if (expr instanceof PsiMethodCallExpression){ + PsiReferenceExpression methodExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); + if (methodExpr.getText().equals("super") || + methodExpr.getText().equals("this")) continue; + } + } + } + result.process(new UsageInfo(superConstructor)); + } + } + } + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, parentClass, searchScope, false); + } + + private static void addClassesUsages(PsiPackage aPackage, Processor results, FindUsagesOptions options) { + PsiSearchHelper helper = aPackage.getManager().getSearchHelper(); + + PsiReference[] refs = helper.findReferences(aPackage, options.searchScope, false); + HashSet filesSet = new HashSet(); + ArrayList files = new ArrayList(); + for(int i = 0; i < refs.length; i++){ + PsiElement ref = refs[i].getElement(); + PsiFile file = ref.getContainingFile(); + if (filesSet.add(file)){ + files.add(file); + } + } + + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null){ + progress.pushState(); + } + + ArrayList classes = new ArrayList(); + addClassesInPackage(aPackage, options.isIncludeSubpackages, classes); + for(int i = 0; i < classes.size(); i++){ + PsiClass aClass = classes.get(i); + if (progress != null){ + StringBuffer buffer = new StringBuffer(100); + buffer.append("Searching for references to class "); + buffer.append(aClass.getName()); + buffer.append("..."); + progress.setText(buffer.toString()); + } + for(int j = 0; j < files.size(); j++){ + ProgressManager.getInstance().checkCanceled(); + PsiFile file = files.get(j); + refs = helper.findReferences(aClass, new LocalSearchScope(file), false); + addResults(results, refs, options, aClass); + } + } + + if (progress != null){ + progress.popState(); + } + } + + private static void addResults(Processor results, PsiReference[] refs, FindUsagesOptions options, PsiElement element) { + for(int i = 0; i < refs.length; i++){ + addResult(results, refs[i], options, element); + } + } + + private static void addClassesInPackage(PsiPackage aPackage, boolean includeSubpackages, ArrayList array) { + PsiDirectory[] dirs = aPackage.getDirectories(); + for(int i = 0; i < dirs.length; i++){ + PsiDirectory dir = dirs[i]; + addClassesInDirectory(dir, includeSubpackages, array); + } + } + + private static void addClassesInDirectory(PsiDirectory dir, boolean includeSubdirs, ArrayList array) { + PsiClass[] classes = dir.getClasses(); + for(int i = 0; i < classes.length; i++){ + array.add(classes[i]); + } + if (includeSubdirs){ + PsiDirectory[] dirs = dir.getSubdirectories(); + for(int i = 0; i < dirs.length; i++){ + addClassesInDirectory(dirs[i], includeSubdirs, array); + } + } + } + + private static void addMethodsUsages(final PsiClass aClass, final Processor results, final FindUsagesOptions options) { + if (!options.isIncludeInherited){ + PsiMethod[] methods = aClass.getMethods(); + for(int i = 0; i < methods.length; i++){ + addMethodUsages(methods[i], results, options, options.searchScope); + } + } + else{ + final PsiManager manager = aClass.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + PsiMethod[] methods = aClass.getAllMethods(); + MethodsLoop: + for(int i = 0; i < methods.length; i++){ + final PsiMethod method = methods[i]; + // filter overriden methods + for(int j = 0; j < i; j++){ + if (MethodSignatureUtil.areSignaturesEqual(method, methods[j])) continue MethodsLoop; + } + final PsiClass methodClass = method.getContainingClass(); + if (methodClass != null && manager.areElementsEquivalent(methodClass, aClass)){ + addMethodUsages(methods[i], results, options, options.searchScope); + } + else{ + helper.processReferencesIncludingOverriding(new PsiReferenceProcessor() { + public boolean execute(PsiReference reference) { + PsiElement refElement = reference.getElement(); + if (refElement instanceof PsiReferenceExpression) { + PsiClass usedClass = getFieldOrMethodAccessedClass((PsiReferenceExpression)refElement, methodClass); + if (usedClass != null) { + if (manager.areElementsEquivalent(usedClass, aClass) || usedClass.isInheritor(aClass, true)) { + addResult(results, refElement, options, method); + } + } + } + return true; + } + }, method, options.searchScope, !options.isIncludeOverloadUsages); + } + } + } + } + + private static void addFieldsUsages(final PsiClass aClass, final Processor results, final FindUsagesOptions options) { + if (!options.isIncludeInherited){ + PsiField[] fields = aClass.getFields(); + for(int i = 0; i < fields.length; i++){ + addElementUsages(fields[i], results, options); + } + } + else{ + final PsiManager manager = aClass.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + PsiField[] fields = aClass.getAllFields(); + FieldsLoop: + for(int i = 0; i < fields.length; i++){ + final PsiField field = fields[i]; + // filter hidden fields + for(int j = 0; j < i; j++){ + if (field.getName().equals(fields[j].getName())) continue FieldsLoop; + } + final PsiClass fieldClass = field.getContainingClass(); + if (fieldClass != null && manager.areElementsEquivalent(fieldClass, aClass)){ + addElementUsages(fields[i], results, options); + } + else{ + helper.processReferences(new PsiReferenceProcessor() { + public boolean execute(PsiReference reference) { + PsiElement refElement = reference.getElement(); + if (refElement instanceof PsiReferenceExpression) { + PsiClass usedClass = getFieldOrMethodAccessedClass((PsiReferenceExpression)refElement, fieldClass); + if (usedClass != null) { + if (manager.areElementsEquivalent(usedClass, aClass) || usedClass.isInheritor(aClass, true)) { + addResult(results, refElement, options, field); + } + } + } + return true; + } + }, field, options.searchScope, false); + } + } + } + } + + private static PsiClass getFieldOrMethodAccessedClass(PsiReferenceExpression ref, PsiClass fieldOrMethodClass) { + PsiElement[] children = ref.getChildren(); + if (children.length > 1 && children[0] instanceof PsiExpression){ + PsiExpression expr = (PsiExpression)children[0]; + PsiType type = expr.getType(); + if (type != null){ + if (!(type instanceof PsiClassType)) return null; + return PsiUtil.resolveClassInType(type); + } + else{ + if (expr instanceof PsiReferenceExpression){ + PsiElement refElement = ((PsiReferenceExpression)expr).resolve(); + if (refElement instanceof PsiClass) return (PsiClass)refElement; + } + return null; + } + } + else{ + PsiManager manager = ref.getManager(); + for(PsiElement parent = ref; parent != null; parent = parent.getParent()){ + if (parent instanceof PsiClass + && (manager.areElementsEquivalent(parent, fieldOrMethodClass) || ((PsiClass)parent).isInheritor(fieldOrMethodClass, true))){ + return (PsiClass)parent; + } + } + } + return null; + } + + private static void addInheritors(PsiClass aClass, final Processor results, final FindUsagesOptions options) { + PsiSearchHelper helper = aClass.getManager().getSearchHelper(); + helper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + addResult(results, element, options, null); + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, aClass, options.searchScope, options.isCheckDeepInheritance); + } + + private static void addDerivedInterfaces(PsiClass anInterface, final Processor results, final FindUsagesOptions options) { + PsiSearchHelper helper = anInterface.getManager().getSearchHelper(); + helper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + addResult(results, element, options, null); + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, anInterface, options.searchScope, options.isCheckDeepInheritance); + } + + private static void addImplementingClasses(PsiClass anInterface, final Processor results, final FindUsagesOptions options) { + PsiSearchHelper helper = anInterface.getManager().getSearchHelper(); + helper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + addResult(results, element, options, null); + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, anInterface, options.searchScope, options.isCheckDeepInheritance); + } + + private static void addResults(Processor total, PsiElement[] part, FindUsagesOptions options, PsiElement refElement) { + for(int i = 0; i < part.length; i++){ + addResult(total, part[i], options, refElement); + } + } + + private static void addResult(Processor total, PsiElement element, FindUsagesOptions options, PsiElement refElement) { + if (filterUsage(element, options, refElement)){ + total.process(new UsageInfo(element)); + } + } + + private static void addResult(Processor results, PsiReference ref, FindUsagesOptions options, PsiElement refElement) { + if (filterUsage(ref.getElement(), options, refElement)){ + TextRange rangeInElement = ref.getRangeInElement(); + results.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false)); + } + } + + private static boolean filterUsage(PsiElement usage, FindUsagesOptions options, PsiElement refElement) { + if (usage instanceof PsiJavaCodeReferenceElement){ + if (refElement instanceof PsiPackage && !options.isIncludeSubpackages){ + if (((PsiJavaCodeReferenceElement)usage).resolve() instanceof PsiPackage){ + PsiElement parent = usage.getParent(); + if (parent instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)parent).resolve() instanceof PsiPackage){ + return false; + } + } + } + + if (!(usage instanceof PsiReferenceExpression)){ + if (options.isSkipImportStatements){ + PsiElement parent = usage.getParent(); + while(parent instanceof PsiJavaCodeReferenceElement){ + parent = parent.getParent(); + } + if (parent instanceof PsiImportStatement){ + return false; + } + } + + if (options.isSkipPackageStatements){ + PsiElement parent = usage.getParent(); + while(parent instanceof PsiJavaCodeReferenceElement){ + parent = parent.getParent(); + } + if (parent instanceof PsiPackageStatement){ + return false; + } + } + } + } + return true; + } + + public static boolean isAccessedForWriting (PsiElement element) { + if (element instanceof PsiReferenceExpression) { + PsiReferenceExpression referent = (PsiReferenceExpression)element; + //[ven] TODO: make a separate highlighting feature + /*if (referent.getParent() instanceof PsiArrayAccessExpression) { + PsiArrayAccessExpression arrayAccess = (PsiArrayAccessExpression)referent.getParent(); + while (arrayAccess.getParent() instanceof PsiArrayAccessExpression) arrayAccess = + (PsiArrayAccessExpression)arrayAccess.getParent(); + return PsiUtil.isAccessedForWriting(arrayAccess); + }*/ + + return PsiUtil.isAccessedForWriting(referent); + } + + return false; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindVariableUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindVariableUsagesDialog.java new file mode 100644 index 00000000000..b478538f2e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/FindVariableUsagesDialog.java @@ -0,0 +1,49 @@ + +package com.intellij.find.findUsages; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.search.SearchScopeCache; + +import javax.swing.*; + +public class FindVariableUsagesDialog extends FindUsagesDialog { + + public FindVariableUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, + boolean toShowInNewTab, boolean isShowInNewTabEnabled, boolean isSingleFile){ + super(element, project, findUsagesOptions, toShowInNewTab, isShowInNewTabEnabled, isSingleFile); + } + + public JComponent getPreferredFocusedControl() { + return myCbToSkipResultsWhenOneUsage; + } + + public FindUsagesOptions getShownOptions(){ + FindUsagesOptions options = new FindUsagesOptions(myProject, SearchScopeCache.getInstance(myProject)); + options.clear(); + options.isReadAccess = false; + options.isWriteAccess = false; + options.isUsages = true; + return options; + } + + public void calcFindUsagesOptions(FindUsagesOptions options) { + super.calcFindUsagesOptions(options); + + options.isReadAccess = true; + options.isWriteAccess = true; + } + + protected JPanel createFindWhatPanel(){ + return null; + } + + protected JPanel createAllOptionsPanel() { + return getPsiElement() instanceof PsiField ? super.createAllOptionsPanel() : createUsagesOptionsPanel(); + } + + protected void update() { + setOKActionEnabled(true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java new file mode 100644 index 00000000000..9c903751b77 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java @@ -0,0 +1,124 @@ +package com.intellij.find.findUsages; + +import com.intellij.find.FindManager; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.usages.UsageTarget; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 17, 2004 + * Time: 4:46:38 PM + * To change this template use File | Settings | File Templates. + */ +public class PsiElement2UsageTargetAdapter implements UsageTarget { + private SmartPsiElementPointer myPointer; + private ItemPresentation myPresentation; + + public PsiElement2UsageTargetAdapter(final PsiElement element) { + myPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); + + if (!(element instanceof NavigationItem)) { + throw new IllegalArgumentException("Element is not a navigation item: " + element); + } + + final NavigationItem navItem = (NavigationItem)element; + final ItemPresentation presentation = navItem.getPresentation(); + + final String nodeText = UsageViewUtil.createNodeText(element, true); + final Icon iconOpen = presentation != null ? presentation.getIcon(true) : null; + final Icon iconClosed = presentation != null ? presentation.getIcon(false) : null; + myPresentation = new ItemPresentation() { + public String getPresentableText() { + return nodeText; + } + + public String getLocationString() { + return null; + } + + public Icon getIcon(boolean open) { + if (!isValid() || presentation == null) { + return open ? iconOpen : iconClosed; + } + else { + return presentation.getIcon(open); + } + } + }; + } + + public String getName() { + return getNavigationItem().getName(); + } + + public ItemPresentation getPresentation() { + return myPresentation; + } + + public void navigate(boolean requestFocus) { + if (!canNavigate()) return; + getNavigationItem().navigate(requestFocus); + } + + public boolean canNavigate() { + return isValid() && getNavigationItem().canNavigate(); + } + + private NavigationItem getNavigationItem() { + return (NavigationItem)myPointer.getElement(); + } + + public FileStatus getFileStatus() { + return isValid() ? getNavigationItem().getFileStatus() : FileStatus.NOT_CHANGED; + } + + public String toString() { + return myPresentation.getPresentableText(); + } + + public void findUsages() { + PsiElement element = myPointer.getElement(); + FindManager.getInstance(element.getProject()).findUsages(element); + } + + public PsiElement getElement() { + return myPointer.getElement(); + } + + public void findUsagesInEditor(FileEditor editor) { + PsiElement element = myPointer.getElement(); + FindManager.getInstance(element.getProject()).findUsagesInEditor(element, editor); + } + + public boolean isValid() { + return myPointer.getElement() != null; + } + + public boolean isReadOnly() { + return isValid() && !myPointer.getElement().isWritable(); + } + + public VirtualFile[] getFiles() { + return isValid() ? new VirtualFile[] {myPointer.getElement().getContainingFile().getVirtualFile()} : null; + } + + public static UsageTarget[] convert(PsiElement[] psiElements) { + UsageTarget[] targets = new UsageTarget[psiElements.length]; + for (int i = 0; i < targets.length; i++) { + targets[i] = new PsiElement2UsageTargetAdapter(psiElements[i]); + } + + return targets; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindDialog.java new file mode 100644 index 00000000000..4e8f8b3dc29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindDialog.java @@ -0,0 +1,798 @@ + +package com.intellij.find.impl; + +import com.intellij.find.FindModel; +import com.intellij.find.FindSettings; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PatternUtil; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.Module; +import com.intellij.psi.PsiDirectory; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.StateRestoringCheckBox; +import com.intellij.util.PatternUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +final class FindDialog extends DialogWrapper { + private ComboBox myInputComboBox; + private ComboBox myReplaceComboBox; + private StateRestoringCheckBox myCbCaseSensitive; + private StateRestoringCheckBox myCbPreserveCase; + private StateRestoringCheckBox myCbWholeWordsOnly; + private StateRestoringCheckBox myCbRegularExpressions; + private JRadioButton myRbGlobal; + private JRadioButton myRbSelectedText; + private JRadioButton myRbForward; + private JRadioButton myRbBackward; + private JRadioButton myRbFromCursor; + private JRadioButton myRbEntireScope; + private JRadioButton myRbProject; + private JRadioButton myRbDirectory; + private JRadioButton myRbModule; + private ComboBox myModuleComboBox; + private ComboBox myDirectoryComboBox; + private StateRestoringCheckBox myCbWithSubdirectories; + private JLabel myReplacePrompt; + private JCheckBox myCbToOpenInNewTab; + private final FindModel myModel; + private FixedSizeButton mySelectDirectoryButton; + private StateRestoringCheckBox useFileFilter; + private ComboBox myFileFilter; + private final Project myProject; + + public FindDialog(Project project, FindModel model){ + super(project, true); + myProject = project; + myModel = model; + + if (myModel.isReplaceState()){ + if (myModel.isMultipleFiles()){ + setTitle("Replace in Project"); + } + else{ + setTitle("Replace Text"); + } + } + else{ + setButtonsMargin(null); + if (myModel.isMultipleFiles()){ + setTitle("Find in Path"); + } + else{ + setTitle("Find Text"); + } + } + setOKButtonText("&Find"); + setOKButtonIcon(IconLoader.getIcon("/actions/find.png")); + init(); + initByModel(); + } + + public JComponent getPreferredFocusedComponent() { + return myInputComboBox; + } + + protected String getDimensionServiceKey() { + return myModel.isReplaceState() ? "replaceTextDialog" : "findTextDialog"; + } + + public JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.anchor = GridBagConstraints.EAST; + JLabel prompt = new JLabel("Text to find:"); + prompt.setDisplayedMnemonic('T'); + panel.add(prompt, gbConstraints); + + myInputComboBox = new ComboBox(300); + initCombobox(myInputComboBox); + + if (myModel.isReplaceState()){ + myReplaceComboBox = new ComboBox(300); + initCombobox(myReplaceComboBox); + final Component editorComponent = myReplaceComboBox.getEditor().getEditorComponent(); + editorComponent.addFocusListener( + new FocusAdapter() { + public void focusGained(FocusEvent e) { + myReplaceComboBox.getEditor().selectAll(); + editorComponent.removeFocusListener(this); + } + } + ); + } + + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + panel.add(myInputComboBox, gbConstraints); + prompt.setLabelFor(myInputComboBox.getEditor().getEditorComponent()); + + if (myModel.isReplaceState()){ + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.weightx = 0; + myReplacePrompt = new JLabel("Replace with:"); + myReplacePrompt.setDisplayedMnemonic('R'); + panel.add(myReplacePrompt, gbConstraints); + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + panel.add(myReplaceComboBox, gbConstraints); + myReplacePrompt.setLabelFor(myReplaceComboBox.getEditor().getEditorComponent()); + } + + return panel; + } + + private void initCombobox(final ComboBox comboBox) { + comboBox.setEditable(true); + comboBox.setMaximumRowCount(8); + + comboBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + validateFindButton(); + } + }); + + Component editorComponent = comboBox.getEditor().getEditorComponent(); + editorComponent.addKeyListener( + new KeyAdapter() { + public void keyReleased(KeyEvent e) { + Object item = comboBox.getEditor().getItem(); + if (item != null && !item.equals(comboBox.getSelectedItem())){ + int caretPosition = getCaretPosition(comboBox); + comboBox.setSelectedItem(item); + setCaretPosition(comboBox, caretPosition); + } + validateFindButton(); + } + } + ); + } + + private static int getCaretPosition(JComboBox comboBox) { + Component editorComponent = comboBox.getEditor().getEditorComponent(); + if (editorComponent instanceof JTextField){ + JTextField textField = (JTextField)editorComponent; + return textField.getCaretPosition(); + } + return 0; + } + + private static void setCaretPosition(JComboBox comboBox, int position) { + Component editorComponent = comboBox.getEditor().getEditorComponent(); + if (editorComponent instanceof JTextField){ + JTextField textField = (JTextField)editorComponent; + textField.setCaretPosition(position); + } + } + + private void validateFindButton() { + if (getStringToFind() == null || getStringToFind().length() == 0){ + setOKActionEnabled(false); + return; + } + if (myRbDirectory != null && myRbDirectory.isSelected() && + (getDirectory() == null || getDirectory().length() == 0)){ + setOKActionEnabled(false); + return; + } + setOKActionEnabled(true); + } + + public JComponent createCenterPanel() { + JPanel optionsPanel = new JPanel(); + optionsPanel.setLayout(new GridBagLayout()); + + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + JPanel topOptionsPanel = new JPanel(); + + topOptionsPanel.setLayout(new GridLayout(1, 2, 8, 0)); + optionsPanel.add(topOptionsPanel, gbConstraints); + + topOptionsPanel.add(createFindOptionsPanel()); + if (!myModel.isMultipleFiles()){ + topOptionsPanel.add(createDirectionPanel()); + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + JPanel bottomOptionsPanel = new JPanel(); + bottomOptionsPanel.setLayout(new GridLayout(1, 2, 8, 0)); + optionsPanel.add(bottomOptionsPanel, gbConstraints); + bottomOptionsPanel.add(createScopePanel()); + bottomOptionsPanel.add(createOriginPanel()); + } + else{ + optionsPanel.add(createGlobalScopePanel(), gbConstraints); + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + optionsPanel.add(createFilterPanel(),gbConstraints); + } + + if (myModel.isOpenInNewTabVisible()){ + JPanel openInNewTabWindowPanel = new JPanel(new BorderLayout()); + myCbToOpenInNewTab = new JCheckBox("Open in new tab"); + myCbToOpenInNewTab.setMnemonic('b'); + myCbToOpenInNewTab.setFocusable(false); + myCbToOpenInNewTab.setSelected(myModel.isOpenInNewTab()); + myCbToOpenInNewTab.setEnabled(myModel.isOpenInNewTabEnabled()); + openInNewTabWindowPanel.add(myCbToOpenInNewTab, BorderLayout.EAST); + optionsPanel.add(openInNewTabWindowPanel, gbConstraints); + } + + return optionsPanel; + } + + private JComponent createFilterPanel() { + JPanel filterPanel = new JPanel(); + filterPanel.setLayout(new BorderLayout()); + filterPanel.setBorder(IdeBorderFactory.createTitledBorder("File name filter")); + + myFileFilter = new ComboBox(100); + initCombobox(myFileFilter); + filterPanel.add(useFileFilter = new StateRestoringCheckBox("File mask"),BorderLayout.WEST); + useFileFilter.setMnemonic('m'); + filterPanel.add(myFileFilter,BorderLayout.CENTER); + myFileFilter.setEditable(true); + myFileFilter.addItem("*.java"); + myFileFilter.addItem("*.xml"); + myFileFilter.addItem("*.jsp"); + myFileFilter.addItem("*.html"); + myFileFilter.addItem("*.properties"); + myFileFilter.setEnabled(false); + + useFileFilter.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (!useFileFilter.isSelected()) { + myFileFilter.setEnabled(false); + } else { + myFileFilter.setEnabled(true); + myFileFilter.getEditor().selectAll(); + myFileFilter.getEditor().getEditorComponent().requestFocusInWindow(); + } + } + } + ); + + return filterPanel; + } + + public void doOKAction(){ + FindModel validateModel = (FindModel)myModel.clone(); + doApply(validateModel); + if (!validateModel.isProjectScope() && myDirectoryComboBox != null && validateModel.getModuleName()==null) { + PsiDirectory directory = FindInProjectUtil.getPsiDirectory(validateModel, myProject); + if (directory == null) { + Messages.showMessageDialog( + myProject, + "Directory " + validateModel.getDirectoryName() + " is not found", + "Error", + Messages.getErrorIcon() + ); + return; + } + } + + if (validateModel.isRegularExpressions()) { + String toFind = validateModel.getStringToFind(); + try { + if (validateModel.isCaseSensitive()){ + Pattern.compile(toFind, Pattern.MULTILINE); + } + else{ + Pattern.compile(toFind, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + } + } + catch(PatternSyntaxException e){ + Messages.showMessageDialog( + myProject, + "Bad pattern \"" + toFind + "\"", + "Information", + Messages.getErrorIcon() + ); + return; + } + } + + myModel.setFileFilter( null ); + + if (useFileFilter!=null && useFileFilter.isSelected() && + myFileFilter.getSelectedItem()!=null + ) { + final String mask = (String)myFileFilter.getSelectedItem(); + + if(mask.length() > 0) { + try { + Pattern.compile(PatternUtil.convertToRegex(mask)); + myModel.setFileFilter( mask ); + } catch(PatternSyntaxException ex) { + Messages.showMessageDialog( + myProject, + "Bad file mask \"" + myFileFilter.getSelectedItem() + "\"", + "Information", + Messages.getErrorIcon() + ); + return; + } + } else { + Messages.showMessageDialog( + myProject, + "Empty file mask", + "Information", + Messages.getErrorIcon() + ); + return; + } + } + + super.doOKAction(); + } + + private JPanel createFindOptionsPanel() { + JPanel findOptionsPanel = new JPanel(); + findOptionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Options")); + findOptionsPanel.setLayout(new BoxLayout(findOptionsPanel, BoxLayout.Y_AXIS)); + + myCbCaseSensitive = new StateRestoringCheckBox("Case sensitive"); + myCbCaseSensitive.setMnemonic('C'); + findOptionsPanel.add(myCbCaseSensitive); + if (myModel.isReplaceState()) { + myCbPreserveCase = new StateRestoringCheckBox("Preserve case"); + myCbPreserveCase.setMnemonic('P'); + findOptionsPanel.add(myCbPreserveCase); + } + myCbWholeWordsOnly = new StateRestoringCheckBox("Whole words only"); + myCbWholeWordsOnly.setMnemonic('W'); + + findOptionsPanel.add(myCbWholeWordsOnly); + + myCbRegularExpressions = new StateRestoringCheckBox("Regular expressions"); + myCbRegularExpressions.setMnemonic('e'); + findOptionsPanel.add(myCbRegularExpressions); + + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateControls(); + } + }; + myCbRegularExpressions.addActionListener(actionListener); + + if (myModel.isReplaceState()) { + myCbCaseSensitive.addActionListener(actionListener); + myCbPreserveCase.addActionListener(actionListener); + } + +// if(isReplaceState) { +// myCbPromptOnReplace = new JCheckBox("Prompt on replace", true); +// myCbPromptOnReplace.setMnemonic('P'); +// findOptionsPanel.add(myCbPromptOnReplace); +// } + return findOptionsPanel; + } + + private void updateControls() { + if (myCbRegularExpressions.isSelected()) { + myCbWholeWordsOnly.makeUnselectable(false); + } else { + myCbWholeWordsOnly.makeSelectable(); + } + if (myModel.isReplaceState()) { + if (myCbRegularExpressions.isSelected() || myCbCaseSensitive.isSelected()) { + myCbPreserveCase.makeUnselectable(false); + } else { + myCbPreserveCase.makeSelectable(); + } + + if (myCbPreserveCase.isSelected()) { + myCbRegularExpressions.makeUnselectable(false); + myCbCaseSensitive.makeUnselectable(false); + } else { + myCbRegularExpressions.makeSelectable(); + myCbCaseSensitive.makeSelectable(); + } + } + + if (!myModel.isMultipleFiles()) { + myRbFromCursor.setEnabled(myRbGlobal.isSelected()); + myRbEntireScope.setEnabled(myRbGlobal.isSelected()); + } + } + + private JPanel createDirectionPanel() { + JPanel directionPanel = new JPanel(); + directionPanel.setBorder(IdeBorderFactory.createTitledBorder("Direction")); + directionPanel.setLayout(new BoxLayout(directionPanel, BoxLayout.Y_AXIS)); + + myRbForward = new JRadioButton("Forward", true); + myRbForward.setMnemonic('o'); + directionPanel.add(myRbForward); + myRbBackward = new JRadioButton("Backward"); + myRbBackward.setMnemonic('B'); + directionPanel.add(myRbBackward); + ButtonGroup bgDirection = new ButtonGroup(); + bgDirection.add(myRbForward); + bgDirection.add(myRbBackward); + + return directionPanel; + } + + private JComponent createGlobalScopePanel() { + JPanel scopePanel = new JPanel(); + scopePanel.setLayout(new GridBagLayout()); + scopePanel.setBorder(IdeBorderFactory.createTitledBorder("Scope")); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = 2; + gbConstraints.weightx = 1; + myRbProject = new JRadioButton("Whole project", true); + myRbProject.setMnemonic('p'); + scopePanel.add(myRbProject, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + gbConstraints.weightx = 0; + gbConstraints.gridwidth = 1; + myRbModule = new JRadioButton("Module: ", false); + myRbModule.setMnemonic('o'); + scopePanel.add(myRbModule, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.gridy = 1; + gbConstraints.weightx = 1; + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + String names[] = new String[modules.length]; + for (int i = 0; i < modules.length; i++) { + names[i] = modules[i].getName(); + } + + Arrays.sort(names,String.CASE_INSENSITIVE_ORDER); + myModuleComboBox = new ComboBox(names, -1); + scopePanel.add(myModuleComboBox, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridy = 2; + gbConstraints.weightx = 0; + gbConstraints.gridwidth = 1; + myRbDirectory = new JRadioButton("Directory: ", false); + myRbDirectory.setMnemonic('D'); + scopePanel.add(myRbDirectory, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.gridy = 2; + gbConstraints.weightx = 1; + + myDirectoryComboBox = new ComboBox(-1); + Component editorComponent = myDirectoryComboBox.getEditor().getEditorComponent(); + if (editorComponent instanceof JTextField) { + JTextField field = (JTextField)editorComponent; + field.setColumns(40); + } + initCombobox(myDirectoryComboBox); + scopePanel.add(myDirectoryComboBox, gbConstraints); + + gbConstraints.weightx = 0; + gbConstraints.gridx = 2; + gbConstraints.insets = new Insets(0, 1, 0, 0); + mySelectDirectoryButton = new FixedSizeButton(myDirectoryComboBox); + TextFieldWithBrowseButton.MyDoClickAction.addTo(mySelectDirectoryButton, myDirectoryComboBox); + mySelectDirectoryButton.setMargin(new Insets(0, 0, 0, 0)); + scopePanel.add(mySelectDirectoryButton, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridy = 3; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = 2; + gbConstraints.insets = new Insets(0, 16, 0, 0); + myCbWithSubdirectories = new StateRestoringCheckBox("Recursively", true); + myCbWithSubdirectories.setSelected(true); + myCbWithSubdirectories.setMnemonic('b'); + scopePanel.add(myCbWithSubdirectories, gbConstraints); + + ButtonGroup bgScope = new ButtonGroup(); + bgScope.add(myRbDirectory); + bgScope.add(myRbProject); + bgScope.add(myRbModule); + + myRbProject.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + validateScopeControls(); + validateFindButton(); + } + }); + + myRbDirectory.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + validateScopeControls(); + validateFindButton(); + myDirectoryComboBox.getEditor().getEditorComponent().requestFocusInWindow(); + } + }); + + myRbModule.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + validateScopeControls(); + validateFindButton(); + myModuleComboBox.requestFocusInWindow(); + } + }); + + mySelectDirectoryButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myProject, descriptor); + if (files.length != 0) { + myDirectoryComboBox.setSelectedItem(files[0].getPresentableUrl()); + validateFindButton(); + } + } + }); + + return scopePanel; + } + + private void validateScopeControls() { + if (myRbProject.isSelected() || myRbModule.isSelected()) { + myCbWithSubdirectories.makeUnselectable(false); + } else { + myCbWithSubdirectories.makeSelectable(); + } + myDirectoryComboBox.setEnabled(myRbDirectory.isSelected()); + mySelectDirectoryButton.setEnabled(myRbDirectory.isSelected()); + + myModuleComboBox.setEnabled(myRbModule.isSelected()); + } + + private JPanel createScopePanel() { + JPanel scopePanel = new JPanel(); + scopePanel.setBorder(IdeBorderFactory.createTitledBorder("Scope")); + scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS)); + + myRbGlobal = new JRadioButton("Global", true); + myRbGlobal.setMnemonic('G'); + scopePanel.add(myRbGlobal); + myRbSelectedText = new JRadioButton("Selected text"); + myRbSelectedText.setMnemonic('S'); + scopePanel.add(myRbSelectedText); + ButtonGroup bgScope = new ButtonGroup(); + bgScope.add(myRbGlobal); + bgScope.add(myRbSelectedText); + + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateControls(); + } + }; + myRbGlobal.addActionListener(actionListener); + myRbSelectedText.addActionListener(actionListener); + + return scopePanel; + } + + private JPanel createOriginPanel() { + JPanel originPanel = new JPanel(); + originPanel.setBorder(IdeBorderFactory.createTitledBorder("Origin")); + originPanel.setLayout(new BoxLayout(originPanel, BoxLayout.Y_AXIS)); + + myRbFromCursor = new JRadioButton("From cursor", true); + myRbFromCursor.setMnemonic('m'); + originPanel.add(myRbFromCursor); + myRbEntireScope = new JRadioButton("Entire scope"); + myRbEntireScope.setMnemonic('n'); + originPanel.add(myRbEntireScope); + ButtonGroup bgOrigin = new ButtonGroup(); + bgOrigin.add(myRbFromCursor); + bgOrigin.add(myRbEntireScope); + + return originPanel; + } + + private String getStringToFind() { + return (String)myInputComboBox.getSelectedItem(); + } + + private String getDirectory() { + if (myDirectoryComboBox == null){ + return null; + } + return (String)myDirectoryComboBox.getSelectedItem(); + } + + private void setStringsToComboBox(String[] strings, ComboBox combo, String s) { + if (combo.getItemCount() > 0){ + combo.removeAllItems(); + } + if (s != null && s.indexOf('\n') < 0 && (strings.length == 0 || !s.equals(strings[strings.length - 1]))) { + combo.addItem(s); + } + for(int i = strings.length - 1; i >= 0; i--){ + combo.addItem(strings[i]); + } + } + + private void setDirectories(ArrayList strings, String directoryName) { + if (myDirectoryComboBox == null){ + return; + } + if (myDirectoryComboBox.getItemCount() > 0){ + myReplaceComboBox.removeAllItems(); + } + if (directoryName != null && directoryName.length() > 0){ + if (strings.contains(directoryName)){ + strings.remove(directoryName); + } + myDirectoryComboBox.addItem(directoryName); + } + for(int i = strings.size() - 1; i >= 0; i--){ + myDirectoryComboBox.addItem(strings.get(i)); + } + if (myDirectoryComboBox.getItemCount() == 0){ + myDirectoryComboBox.addItem(""); + } + } + + public void apply() { + doApply(myModel); + } + + private void doApply(FindModel model) { + FindSettings findSettings = FindSettings.getInstance(); + model.setCaseSensitive(myCbCaseSensitive.isSelected()); + findSettings.setCaseSensitive(myCbCaseSensitive.isSelected()); + if (model.isReplaceState()) { + model.setPreserveCase(myCbPreserveCase.isSelected()); + findSettings.setPreserveCase(myCbPreserveCase.isSelected()); + } + model.setWholeWordsOnly(myCbWholeWordsOnly.isSelected()); + findSettings.setWholeWordsOnly(myCbWholeWordsOnly.isSelected()); + model.setRegularExpressions(myCbRegularExpressions.isSelected()); + findSettings.setRegularExpressions(myCbRegularExpressions.isSelected()); + model.setStringToFind((String)myInputComboBox.getSelectedItem()); + if (model.isReplaceState()){ + model.setPromptOnReplace(true); + model.setReplaceAll(false); + String stringToReplace = (String)myReplaceComboBox.getSelectedItem(); + if (stringToReplace == null){ + stringToReplace = ""; + } + model.setStringToReplace(stringToReplace); + } + if (!model.isMultipleFiles()){ + model.setForward(myRbForward.isSelected()); + findSettings.setForward(myRbForward.isSelected()); + model.setFromCursor(myRbFromCursor.isSelected()); + findSettings.setFromCursor(myRbFromCursor.isSelected()); + model.setGlobal(myRbGlobal.isSelected()); + findSettings.setGlobal(myRbGlobal.isSelected()); + } + else{ + if (myCbToOpenInNewTab != null){ + model.setOpenInNewTab(myCbToOpenInNewTab.isSelected()); + } + model.setWithSubdirectories(myCbWithSubdirectories.isSelected()); + findSettings.setWithSubdirectories(myCbWithSubdirectories.isSelected()); + model.setProjectScope(myRbProject.isSelected()); + model.setDirectoryName(null); + model.setModuleName(null); + + if (myRbDirectory.isSelected()){ + String directory = getDirectory(); + model.setDirectoryName(directory == null ? "" : directory); + if (directory==null) { + //model.setWithSubdirectories(myCbWithSubdirectories.isSelected()); + //findSettings.setWithSubdirectories(myCbWithSubdirectories.isSelected()); + } + } else if (myRbModule.isSelected()) { + model.setModuleName((String)myModuleComboBox.getSelectedItem()); + } + + if (useFileFilter.isSelected()) { + findSettings.setFileMask(model.getFileFilter()); + } else { + findSettings.setFileMask(null); + } + } + } + + private void initByModel() { + myCbCaseSensitive.setSelected(myModel.isCaseSensitive()); + myCbWholeWordsOnly.setSelected(myModel.isWholeWordsOnly()); + myCbRegularExpressions.setSelected(myModel.isRegularExpressions()); + if (!myModel.isMultipleFiles()){ + + if (myModel.isForward()){ + myRbForward.setSelected(true); + } + else{ + myRbBackward.setSelected(true); + } + + if (myModel.isFromCursor()){ + myRbFromCursor.setSelected(true); + } + else{ + myRbEntireScope.setSelected(true); + } + + if (myModel.isGlobal()){ + myRbGlobal.setSelected(true); + } + else{ + myRbSelectedText.setSelected(true); + } + + } + else{ + setDirectories(FindSettings.getInstance().getRecentDirectories(), myModel.getDirectoryName()); + if (myModel.isProjectScope()){ + myRbProject.setSelected(true); + + myCbWithSubdirectories.setEnabled(false); + myDirectoryComboBox.setEnabled(false); + mySelectDirectoryButton.setEnabled(false); + myModuleComboBox.setEnabled(false); + } + else if (myModel.getDirectoryName()!=null) { + myRbDirectory.setSelected(true); + myCbWithSubdirectories.setEnabled(true); + myDirectoryComboBox.setEnabled(true); + mySelectDirectoryButton.setEnabled(true); + myModuleComboBox.setEnabled(false); + } else { + myRbModule.setSelected(true); + + myCbWithSubdirectories.setEnabled(false); + myDirectoryComboBox.setEnabled(false); + mySelectDirectoryButton.setEnabled(false); + myModuleComboBox.setEnabled(true); + myModuleComboBox.setSelectedItem(myModel.getModuleName()); + } + + myCbWithSubdirectories.setSelected(myModel.isWithSubdirectories()); + + if (myModel.getFileFilter()!=null && myModel.getFileFilter().length() > 0) { + myFileFilter.setSelectedItem(myModel.getFileFilter()); + myFileFilter.setEnabled(true); + useFileFilter.setSelected(true); + } + } + + setStringsToComboBox(FindSettings.getInstance().getRecentFindStrings(), myInputComboBox, myModel.getStringToFind()); + if (myModel.isReplaceState()){ + myCbPreserveCase.setSelected(myModel.isPreserveCase()); + setStringsToComboBox(FindSettings.getInstance().getRecentReplaceStrings(), myReplaceComboBox, myModel.getStringToReplace()); + } + updateControls(); + validateFindButton(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindInProjectUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindInProjectUtil.java new file mode 100644 index 00000000000..b9103747ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindInProjectUtil.java @@ -0,0 +1,337 @@ +package com.intellij.find.impl; + +import com.intellij.Patches; +import com.intellij.find.FindManager; +import com.intellij.find.FindModel; +import com.intellij.find.FindResult; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.SmoothProgressAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.usageView.AsyncFindUsagesProcessListener; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.PatternUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class FindInProjectUtil { + + public static void setDirectoryName(FindModel model, DataContext dataContext) { + PsiElement psiElement = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + + String directoryName = null; + + if (psiElement instanceof PsiDirectory) { + directoryName = ((PsiDirectory)psiElement).getVirtualFile().getPresentableUrl(); + } + else { + final PsiFile psiFile = (PsiFile)dataContext.getData(DataConstants.PSI_FILE); + if (psiFile != null) { + PsiDirectory psiDirectory = psiFile.getContainingDirectory(); + if (psiDirectory != null) { + directoryName = psiDirectory.getVirtualFile().getPresentableUrl(); + } + } + } + + Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + if (module != null) { + model.setModuleName(module.getName()); + } + + if (model.getModuleName() == null || dataContext.getData(DataConstants.EDITOR) == null) { + model.setDirectoryName(directoryName); + model.setProjectScope((directoryName == null && module == null) || dataContext.getData(DataConstants.EDITOR) != null); + } + } + + public static PsiDirectory getPsiDirectory(final FindModel findModel, Project project) { + if (findModel.isProjectScope() || findModel.getDirectoryName() == null) { + return null; + } + + final PsiManager psiManager = PsiManager.getInstance(project); + String path = findModel.getDirectoryName().replace(File.separatorChar, '/'); + VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path); + if (virtualFile == null || !virtualFile.isDirectory()) { + if (path.indexOf(JarFileSystem.JAR_SEPARATOR) < 0) { + path = path + JarFileSystem.JAR_SEPARATOR; + } + virtualFile = JarFileSystem.getInstance().findFileByPath(path); + } + if (virtualFile != null) { + return psiManager.findDirectory(virtualFile); + } + else { + return null; + } + } + + private static void addVirtualFilesUnderDirectory(VirtualFile directory, List vFileList, boolean isRecursive, Pattern fileMaskRegExp) { + final VirtualFile[] children = directory.getChildren(); + if (children == null) return; + + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (!child.isDirectory() && + (fileMaskRegExp == null || + fileMaskRegExp.matcher(child.getName()).matches() + ) + ) { + vFileList.add(child); + } + else if (isRecursive) { + addVirtualFilesUnderDirectory(child, vFileList, isRecursive, fileMaskRegExp); + } + } + } + + public static UsageInfo[] findUsages(final FindModel findModel, final PsiDirectory psiDirectory, final Project project) { + class MyAsyncUsageConsumer implements AsyncFindUsagesProcessListener { + final ArrayList usages = new ArrayList(); + + public void foundUsage(UsageInfo info) { + usages.add(info); + } + + public int getCount() { + return usages.size(); + } + + public void findUsagesCompleted() { + } + } + + MyAsyncUsageConsumer consumer = new MyAsyncUsageConsumer(); + findUsages(findModel, psiDirectory, project, consumer); + return consumer.usages.toArray(new UsageInfo[consumer.usages.size()]); + } + + private static Pattern createFileMaskRegExp(FindModel findModel) { + if (findModel.getFileFilter() != null) { + return Pattern.compile(PatternUtil.convertToRegex(findModel.getFileFilter()), Pattern.CASE_INSENSITIVE); + } + else { + return null; + } + } + + public static void findUsages(final FindModel findModel, + final PsiDirectory psiDirectory, + final Project project, + final AsyncFindUsagesProcessListener consumer) { + final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + + final VirtualFile[] virtualFiles = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile[] compute() { + final FileIndex fileIndex = (findModel.getModuleName() == null) ? + (FileIndex)ProjectRootManager.getInstance(project).getFileIndex() : + ModuleRootManager.getInstance(ModuleManager.getInstance(project).findModuleByName(findModel.getModuleName())).getFileIndex(); + + if (psiDirectory == null || (findModel.isWithSubdirectories() && fileIndex.isInContent(psiDirectory.getVirtualFile()))) { + class EnumContentIterator implements ContentIterator { + List myVirtualFiles = new ArrayList(); + Pattern fileMaskRegExp = createFileMaskRegExp(findModel); + + public boolean processFile(VirtualFile fileOrDir) { + if (!fileOrDir.isDirectory() && + (fileMaskRegExp == null || + fileMaskRegExp.matcher(fileOrDir.getName()).matches() + ) + ) { + myVirtualFiles.add(fileOrDir); + } + return true; + } + + public VirtualFile[] getVirtualFiles() { + return myVirtualFiles.toArray(new VirtualFile[myVirtualFiles.size()]); + } + } + final EnumContentIterator iterator = new EnumContentIterator(); + + + if (psiDirectory == null) { + fileIndex.iterateContent(iterator); + } + else { + fileIndex.iterateContentUnderDirectory(psiDirectory.getVirtualFile(), iterator); + } + + return iterator.getVirtualFiles(); + } + else { + List vFileList = new ArrayList(); + VirtualFile virtualFile = psiDirectory.getVirtualFile(); + + addVirtualFilesUnderDirectory(virtualFile, + vFileList, + findModel.isWithSubdirectories(), + createFileMaskRegExp(findModel)); + return vFileList.toArray(new VirtualFile[vFileList.size()]); + } + } + }); + + final FileDocumentManager manager = FileDocumentManager.getInstance(); + try { + for (int i = 0; i < virtualFiles.length; i++) { + ProgressManager.getInstance().checkCanceled(); + final VirtualFile virtualFile = virtualFiles[i]; + final int index = i; + final int occurencesBeforeFileSearch = consumer.getCount(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (virtualFile.isValid()) { + if (FileTypeManager.getInstance().getFileTypeByFile(virtualFile).isBinary()) return; // do not decompile .class files + final Document document = manager.getDocument(virtualFile); + if (document != null) { + addToUsages(project, document, consumer, findModel); + + if (progress != null) { + progress.setFraction((double)index / virtualFiles.length); + String text = "Searching for '" + findModel.getStringToFind() + "' in " + virtualFile.getPresentableUrl() + "..."; + progress.setText(text); + int size = consumer.getCount(); + progress.setText2((size == 0 ? "No" : Integer.toString(size)) + " occurrence" + + (size != 1 ? "s" : "") + " found so far"); + } + } + } + } + }); + + if (occurencesBeforeFileSearch == consumer.getCount()) { + // we have not waited after having found the results so wait a little bit + synchronized (project) { + try { + project.wait(1); + } + catch (InterruptedException ex) { + } + } + } + } + } + catch (ProcessCanceledException e) { + } + + if (progress != null) { + progress.setText("Search completed"); + } + + consumer.findUsagesCompleted(); + } + + private static void addToUsages(Project project, Document document, AsyncFindUsagesProcessListener consumer, FindModel findModel) { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + + if (psiFile != null) { + CharSequence text = document.getCharsSequence(); + int textLength = document.getTextLength(); + if (text != null) { + int offset = 0; + FindManager findManager = FindManager.getInstance(project); + while (offset < textLength) { + FindResult result = findManager.findString(text, offset, findModel); + if (result == null || !result.isStringFound()) break; + + UsageInfo info = new UsageInfo(psiFile, result.getStartOffset(), result.getEndOffset()); + consumer.foundUsage(info); + // we need to sleep a little bit to allow AWT thread to handle added usages + // this is especially important iff number of usages grows very quickly + synchronized (project) { + try { + project.wait(2); + } + catch (InterruptedException ex) { + } + } + + final int prevOffset = offset; + offset = result.getEndOffset(); + + if (prevOffset == offset) { + // for regular expr the size of the match could be zero -> could be infinite loop in finding usages! + ++offset; + } + } + } + } + } + + public static void runProcessWithProgress(final ProgressIndicator progressIndicator, + final Runnable findUsagesRunnable, + final Runnable showResultsRunnable, + Project project) { + + final ProgressIndicator progressIndicator1 = Patches.MAC_HIDE_QUIT_HACK + ? (ProgressIndicator)progressIndicator + : new SmoothProgressAdapter(progressIndicator, project); + Thread thread = new Thread("Process with progress") { + public void run() { + try { + ProgressManager.getInstance().runProcess(findUsagesRunnable, progressIndicator1); + } + catch (ProcessCanceledException e) { + } + + ApplicationManager.getApplication().invokeLater(showResultsRunnable, ModalityState.NON_MMODAL); + } + }; + + synchronized (findUsagesRunnable) { + thread.start(); + try { + findUsagesRunnable.wait(); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + public static String getTitleForScope(final FindModel findModel) { + StringBuffer result = new StringBuffer(); + + if (findModel.isProjectScope()) { + result.append("Project"); + } + else if (findModel.getModuleName() != null) { + result.append("Module " + findModel.getModuleName()); + } + else { + result.append("Directory " + findModel.getDirectoryName()); + } + + if (findModel.getFileFilter() != null) { + result.append(" Files with Mask " + findModel.getFileFilter()); + } + + return result.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindManagerImpl.java new file mode 100644 index 00000000000..6504067ea93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindManagerImpl.java @@ -0,0 +1,474 @@ + +package com.intellij.find.impl; + +import com.intellij.aspects.psi.PsiPointcut; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.codeInsight.highlighting.HighlightManagerImpl; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.find.FindManager; +import com.intellij.find.FindModel; +import com.intellij.find.FindResult; +import com.intellij.find.FindSettings; +import com.intellij.find.findUsages.FindUsagesManager; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.SearchScopeCache; +import com.intellij.ui.LightweightHint; +import com.intellij.util.text.StringSearcher; + +import javax.swing.*; +import java.awt.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class FindManagerImpl extends FindManager implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.find.impl.FindManagerImpl"); + + private FindUsagesManager myFindUsagesManager; + private boolean isFindWasPerformed = false; + private Point myReplaceInFilePromptPos = new Point(-1, -1); + private Point myReplaceInProjectPromptPos = new Point(-1, -1); + private FindModel myFindInProjectModel = new FindModel(); + private FindModel myFindInFileModel = new FindModel(); + private FindModel myFindNextModel = null; + private static FindResultImpl NOT_FOUND_RESULT = new FindResultImpl(); + private Project myProject; + private com.intellij.usages.UsageViewManager myAnotherManager; + private Key HIGHLIGHTER_WAS_NOT_FOUND_KEY = Key.create("com.intellij.find.impl.FindManagerImpl.HighlighterNotFoundKey"); + + public FindManagerImpl(Project project, FindSettings findSettings, SearchScopeCache searchScopeCache, com.intellij.usages.UsageViewManager anotherManager) { + myProject = project; + myAnotherManager = anotherManager; + findSettings.initModelBySetings(myFindInFileModel); + findSettings.initModelBySetings(myFindInProjectModel); + + myFindUsagesManager = new FindUsagesManager(myProject, searchScopeCache, myAnotherManager); + myFindInProjectModel.setMultipleFiles(true); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public int showPromptDialog(final FindModel model, String title) { + PromptDialog promptDialog = new PromptDialog(model, title, myProject) { + public Point getInitialLocation() { + if (model.isMultipleFiles() && myReplaceInProjectPromptPos.x >= 0 && myReplaceInProjectPromptPos.y >= 0){ + return myReplaceInProjectPromptPos; + } + if (!model.isMultipleFiles() && myReplaceInFilePromptPos.x >= 0 && myReplaceInFilePromptPos.y >= 0){ + return myReplaceInFilePromptPos; + } + return null; + } + }; + + promptDialog.show(); + + if (model.isMultipleFiles()){ + myReplaceInProjectPromptPos = promptDialog.getLocation(); + } + else{ + myReplaceInFilePromptPos = promptDialog.getLocation(); + } + return promptDialog.getExitCode(); + } + + public boolean showFindDialog(FindModel model) { + FindDialog findDialog = new FindDialog(myProject, model); + findDialog.show(); + if (!findDialog.isOK()){ + return false; + } + + findDialog.apply(); + String stringToFind = model.getStringToFind(); + if (stringToFind == null || stringToFind.length() == 0){ + return false; + } + FindSettings.getInstance().addStringToFind(stringToFind); + if (!model.isMultipleFiles()){ + setFindWasPerformed(); + } + if (model.isReplaceState()){ + FindSettings.getInstance().addStringToReplace(model.getStringToReplace()); + } + if (model.isMultipleFiles() && !model.isProjectScope()){ + FindSettings.getInstance().addDirectory(model.getDirectoryName()); + } + return true; + } + + public FindModel getFindInFileModel() { + return myFindInFileModel; + } + + public FindModel getFindInProjectModel() { + myFindInProjectModel.setFromCursor(false); + myFindInProjectModel.setForward(true); + myFindInProjectModel.setGlobal(true); + return myFindInProjectModel; + } + + public boolean findWasPerformed() { + return isFindWasPerformed; + } + + public void setFindWasPerformed() { + isFindWasPerformed = true; + myFindUsagesManager.clearFindingNextUsageInFile(); + } + + public FindModel getFindNextModel() { + return myFindNextModel; + } + + public void setFindNextModel(FindModel findNextModel) { + myFindNextModel = findNextModel; + } + + public FindResult findString(CharSequence text, int offset, FindModel model){ + if (LOG.isDebugEnabled()) { + LOG.debug("offset="+offset); + LOG.debug("textlength="+text.length()); + LOG.debug(model.toString()); + } + + while(true){ + FindResult result = doFindString(text, offset, model); + + if (!model.isWholeWordsOnly()) { + return result; + } + if (!result.isStringFound()){ + return result; + } + if (isWholeWord(text, result.getStartOffset(), result.getEndOffset())){ + return result; + } + + if(model.isForward()) offset = result.getStartOffset() + 1; else offset = result.getEndOffset() - 1; + } + } + + private static boolean isWholeWord(CharSequence text, int startOffset, int endOffset) { + boolean isWordStart = startOffset == 0 || !Character.isJavaIdentifierPart(text.charAt(startOffset - 1)); + boolean isWordEnd = endOffset == text.length() || !Character.isJavaIdentifierPart(text.charAt(endOffset)) || + (endOffset > 0 && !Character.isJavaIdentifierPart(text.charAt(endOffset - 1))); + + return isWordStart && isWordEnd; + } + + private static FindResult doFindString(CharSequence text, int offset, FindModel model) { + String toFind = model.getStringToFind(); + if (toFind == null || toFind.length() == 0){ + return NOT_FOUND_RESULT; + } + + if (model.isRegularExpressions()){ + return findStringByRegularExpression(text, offset, model); + } + + StringSearcher searcher = new StringSearcher(toFind); + searcher.setCaseSensitive(model.isCaseSensitive()); + searcher.setForwardDirection(model.isForward()); + int index; + if (model.isForward()){ + final int res = searcher.scan(text.subSequence(offset, text.length())); + index = res < 0 ? -1 : res + offset; + } + else{ + index = searcher.scan(text.subSequence(0, offset)); + } + if (index < 0){ + return NOT_FOUND_RESULT; + } + else{ + return new FindResultImpl(index, index + toFind.length()); + } + } + + private static FindResult findStringByRegularExpression(CharSequence text, int startOffset, FindModel model) { + String toFind = model.getStringToFind(); + + Pattern pattern; + try{ + if (model.isCaseSensitive()){ + pattern = Pattern.compile(toFind, Pattern.MULTILINE); + } + else{ + pattern = Pattern.compile(toFind, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); + } + } + catch(PatternSyntaxException e){ + LOG.error(e); + return null; + } + + Matcher matcher = pattern.matcher(text); + + if (model.isForward()){ + if (matcher.find(startOffset)) { + if (matcher.end() <= text.length()) { + return new FindResultImpl(matcher.start(), matcher.end()); + } + } + return NOT_FOUND_RESULT; + } + else{ + int start = -1, end = -1; + while(matcher.find() && matcher.end() < startOffset){ + start = matcher.start(); + end = matcher.end(); + } + if (start < 0){ + return NOT_FOUND_RESULT; + } + else{ + return new FindResultImpl(start, end); + } + } + } + + public String getStringToReplace(String foundString, FindModel model) { + if (model == null) + return null; + String toReplace = model.getStringToReplace(); + if (!model.isRegularExpressions()) { + if (model.isPreserveCase()) { + return replaceWithCaseRespect (toReplace, foundString); + } + return toReplace; + } + + String toFind = model.getStringToFind(); + + Pattern pattern; + try{ + int flags = Pattern.MULTILINE; + if (!model.isCaseSensitive()) { + flags |= Pattern.CASE_INSENSITIVE; + } + pattern = Pattern.compile(toFind, flags); + } + catch(PatternSyntaxException e){ + return toReplace; + } + + Matcher matcher = pattern.matcher(foundString); + if (matcher.matches()) { + try { + return matcher.replaceAll(StringUtil.unescapeStringCharacters(toReplace)); + } + catch (Exception e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog(myProject, "You have entered malformed replacement string", "Replace Error"); + } + }); + return null; + } + } else { + //Seems like a bug in JDK 1.4 + Messages.showErrorDialog("Unknown Error in Replace", "Internal Error"); + return toReplace; + } + } + + private String replaceWithCaseRespect(String toReplace, String foundString) { + if (foundString.length() == 0 || toReplace.length() == 0) return toReplace; + StringBuffer buffer = new StringBuffer(); + + if (Character.isUpperCase(foundString.charAt(0))) { + buffer.append(Character.toUpperCase(toReplace.charAt(0))); + } else { + buffer.append(Character.toLowerCase(toReplace.charAt(0))); + } + if (toReplace.length() == 1) return buffer.toString(); + + if (foundString.length() == 1) { + buffer.append(toReplace.substring(1)); + return buffer.toString(); + } + + boolean isTailUpper = true; + boolean isTailLower = true; + for (int i = 1; i < foundString.length(); i++) { + isTailUpper &= Character.isUpperCase(foundString.charAt(i)); + isTailLower &= Character.isLowerCase(foundString.charAt(i)); + if (!isTailUpper && !isTailLower) break; + } + + if (isTailUpper) { + buffer.append(toReplace.substring(1).toUpperCase()); + } else if (isTailLower) { + buffer.append(toReplace.substring(1).toLowerCase()); + } else { + buffer.append(toReplace.substring(1)); + } + return buffer.toString(); + } + + public boolean canFindUsages(PsiElement element) { + return myFindUsagesManager.canFindUsages(element); + } + + public void findUsages(PsiElement element) { + myFindUsagesManager.findUsages(element, null, null); + } + + public void findUsagesInEditor(PsiElement element, FileEditor fileEditor) { + if (fileEditor instanceof TextEditor) { + TextEditor textEditor = (TextEditor)fileEditor; + Editor editor = textEditor.getEditor(); + Document document = editor.getDocument(); + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + + myFindUsagesManager.findUsages(element, psiFile, fileEditor); + } + } + + public void findJoinpointsByPointcut(PsiPointcut pointcut) { + myFindUsagesManager.findPointcutApplications(pointcut); + } + + public boolean findNextUsageInEditor(FileEditor fileEditor) { + LOG.assertTrue(fileEditor != null); + + if (fileEditor instanceof TextEditor) { + TextEditor textEditor = (TextEditor)fileEditor; + Editor editor = textEditor.getEditor(); + + FindModel model = getFindNextModel(); + if (model != null && model.searchHighlighters()) { + RangeHighlighter[] highlighters = ((HighlightManagerImpl)HighlightManager.getInstance(myProject)).getHighlighters(editor); + if (highlighters.length > 0) { + return highlightNextHighlighter(highlighters, editor, editor.getCaretModel().getOffset(), true, false); + } + } + } + + return myFindUsagesManager.findNextUsageInFile(fileEditor); + } + + private boolean highlightNextHighlighter(RangeHighlighter[] highlighters, Editor editor, int offset, boolean isForward, boolean secondPass) { + RangeHighlighter highlighterToSelect = null; + Object wasNotFound = editor.getUserData(HIGHLIGHTER_WAS_NOT_FOUND_KEY); + for (int i = 0; i < highlighters.length; i++) { + RangeHighlighter highlighter = highlighters[i]; + int start = highlighter.getStartOffset(); + int end = highlighter.getEndOffset(); + if (highlighter.isValid() && start < end) { + if (isForward && (start > offset || (start == offset && secondPass))) { + if (highlighterToSelect == null || highlighterToSelect.getStartOffset() > start) highlighterToSelect = highlighter; + } + if (!isForward && (end < offset || (end == offset && secondPass))) { + if (highlighterToSelect == null || highlighterToSelect.getEndOffset() < end) highlighterToSelect = highlighter; + } + } + } + if (highlighterToSelect != null) { + editor.getSelectionModel().setSelection(highlighterToSelect.getStartOffset(), highlighterToSelect.getEndOffset()); + editor.getCaretModel().moveToOffset(highlighterToSelect.getStartOffset()); + ScrollType scrollType; + if (!secondPass) { + scrollType = isForward ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + } + else { + scrollType = !isForward ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + } + editor.getScrollingModel().scrollToCaret(scrollType); + editor.putUserData(HIGHLIGHTER_WAS_NOT_FOUND_KEY, null); + return true; + } + + if (wasNotFound == null) { + editor.putUserData(HIGHLIGHTER_WAS_NOT_FOUND_KEY, Boolean.TRUE); + String message = "No more highlights found"; + if (isForward) { + AnAction action=ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT); + String shortcutsText=KeymapUtil.getFirstKeyboardShortcutText(action); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else{ + message += ", perform \"Find Next\" again "; + } + message += " to search from the top"; + } + else { + AnAction action=ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_PREVIOUS); + String shortcutsText=KeymapUtil.getFirstKeyboardShortcutText(action); + if (shortcutsText.length() > 0) { + message += ", press " + shortcutsText; + } + else{ + message += ", perform \"Find Previous\" again "; + } + message += " to search from the bottom"; + } + HintManager hintManager = HintManager.getInstance(); + JComponent component = HintUtil.createInformationLabel(message); + final LightweightHint hint = new LightweightHint(component); + hintManager.showEditorHint(hint, editor, HintManager.UNDER, HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0, false); + return true; + } else if (!secondPass) { + offset = isForward ? 0 : editor.getDocument().getTextLength(); + return highlightNextHighlighter(highlighters, editor, offset, isForward, true); + } + + return false; + } + + public boolean findPreviousUsageInEditor(FileEditor fileEditor) { + LOG.assertTrue(fileEditor != null); + + if (fileEditor instanceof TextEditor) { + TextEditor textEditor = (TextEditor)fileEditor; + Editor editor = textEditor.getEditor(); + + FindModel model = getFindNextModel(); + if (model != null && model.searchHighlighters()) { + RangeHighlighter[] highlighters = ((HighlightManagerImpl)HighlightManager.getInstance(myProject)).getHighlighters(editor); + if (highlighters.length > 0) { + return highlightNextHighlighter(highlighters, editor, editor.getCaretModel().getOffset(), false, false); + } + } + } + + return myFindUsagesManager.findPreviousUsageInFile(fileEditor); + } + + public String getComponentName() { + return "FindManager"; + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindResultImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindResultImpl.java new file mode 100644 index 00000000000..1a8c8407d4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindResultImpl.java @@ -0,0 +1,24 @@ + +package com.intellij.find.impl; + +import com.intellij.find.FindResult; + +public class FindResultImpl extends FindResult { + private boolean isStringFound = true; + + public FindResultImpl(int startOffset, int endOffset) { + super(startOffset, endOffset); + } + + public FindResultImpl() { + super(-1, -1); + isStringFound = false; + } + + public boolean isStringFound() { + return isStringFound; + } +} + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindSettingsImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindSettingsImpl.java new file mode 100644 index 00000000000..f5f32a5d3e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/FindSettingsImpl.java @@ -0,0 +1,220 @@ +package com.intellij.find.impl; + +import com.intellij.find.FindModel; +import com.intellij.find.FindSettings; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.*; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; + +public class FindSettingsImpl extends FindSettings implements ApplicationComponent, JDOMExternalizable{ + public static final String FIND_DIRECTION_FORWARD = "forward"; + public static final String FIND_DIRECTION_BACKWARD = "backward"; + public static final String FIND_ORIGIN_FROM_CURSOR = "from_cursor"; + public static final String FIND_ORIGIN_ENTIRE_SCOPE = "entire_scope"; + public static final String FIND_SCOPE_GLOBAL = "global"; + public static final String FIND_SCOPE_SELECTED = "selected"; + public static final String DEFAULT_SEARCH_SCOPE = "All Project Classes"; + + public static final int MAX_RECENT_SIZE = 30; + + + public boolean isSearchOverloadedMethods() { + return SEARCH_OVERLOADED_METHODS; + } + + public void setSearchOverloadedMethods(boolean search) { + SEARCH_OVERLOADED_METHODS = search; + } + + public boolean SEARCH_OVERLOADED_METHODS = false; + public boolean SEARCH_IN_LIBRARIES = false; + public boolean SEARCH_IN_NON_JAVA_FILES = true; + public boolean SKIP_RESULTS_WHEN_ONE_USAGE = false; + + public String FIND_DIRECTION = FIND_DIRECTION_FORWARD; + public String FIND_ORIGIN = FIND_ORIGIN_FROM_CURSOR; + public String FIND_SCOPE = FIND_SCOPE_GLOBAL; + + public boolean CASE_SENSITIVE_SEARCH = false; + public boolean PRESERVE_CASE_REPLACE = false; + public boolean WHOLE_WORDS_ONLY = false; + public boolean REGULAR_EXPRESSIONS = false; + public boolean WITH_SUBDIRECTORIES = true; + + public String SEARCH_SCOPE = DEFAULT_SEARCH_SCOPE; + public String FILE_MASK; + + public JDOMExternalizableStringList RECENT_FIND_STRINGS = new JDOMExternalizableStringList(); + public JDOMExternalizableStringList RECENT_REPLACE_STRINGS = new JDOMExternalizableStringList(); + public JDOMExternalizableStringList RECENT_DIR_STRINGS = new JDOMExternalizableStringList(); + + public String getComponentName(){ + return "FindSettings"; + } + + public void initComponent() { } + + public void disposeComponent(){ + } + + public void readExternal(Element element) throws InvalidDataException{ + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException{ + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public boolean isSkipResultsWithOneUsage(){ + return SKIP_RESULTS_WHEN_ONE_USAGE; + } + + public void setSkipResultsWithOneUsage(boolean skip){ + this.SKIP_RESULTS_WHEN_ONE_USAGE = skip; + } + + public boolean isSearchInNonJavaFiles(){ + return SEARCH_IN_NON_JAVA_FILES; + } + + public void setSearchInNonJavaFiles(boolean search){ + this.SEARCH_IN_NON_JAVA_FILES = search; + } + + public String getDefaultScopeName() { + return SEARCH_SCOPE; + } + + public void setDefaultScopeName(String scope) { + SEARCH_SCOPE = scope; + } + + public boolean isForward(){ + return FIND_DIRECTION_FORWARD.equals(FIND_DIRECTION); + } + + public void setForward(boolean findDirectionForward){ + FIND_DIRECTION = findDirectionForward ? FIND_DIRECTION_FORWARD : FIND_DIRECTION_BACKWARD; + } + + public boolean isFromCursor(){ + return FIND_ORIGIN_FROM_CURSOR.equals(FIND_ORIGIN); + } + + public void setFromCursor(boolean findFromCursor){ + FIND_ORIGIN = findFromCursor ? FIND_ORIGIN_FROM_CURSOR : FIND_ORIGIN_ENTIRE_SCOPE; + } + + public boolean isGlobal(){ + return FIND_SCOPE_GLOBAL.equals(FIND_SCOPE); + } + + public void setGlobal(boolean findGlobalScope){ + FIND_SCOPE = findGlobalScope ? FIND_SCOPE_GLOBAL : FIND_SCOPE_SELECTED; + } + + public boolean isCaseSensitive(){ + return CASE_SENSITIVE_SEARCH; + } + + public void setCaseSensitive(boolean caseSensitiveSearch){ + this.CASE_SENSITIVE_SEARCH = caseSensitiveSearch; + } + + public boolean isPreserveCase() { + return PRESERVE_CASE_REPLACE; + } + + public void setPreserveCase(boolean preserveCase) { + PRESERVE_CASE_REPLACE = preserveCase; + } + + public boolean isWholeWordsOnly(){ + return WHOLE_WORDS_ONLY; + } + + public void setWholeWordsOnly(boolean wholeWordsOnly){ + this.WHOLE_WORDS_ONLY = wholeWordsOnly; + } + + public boolean isRegularExpressions(){ + return REGULAR_EXPRESSIONS; + } + + public void setRegularExpressions(boolean regularExpressions){ + this.REGULAR_EXPRESSIONS = regularExpressions; + } + + public void setWithSubdirectories(boolean b){ + this.WITH_SUBDIRECTORIES = b; + } + + public boolean isWithSubdirectories(){ + return WITH_SUBDIRECTORIES; + } + + public void initModelBySetings(FindModel model){ + model.setCaseSensitive(isCaseSensitive()); + model.setForward(isForward()); + model.setFromCursor(isFromCursor()); + model.setGlobal(isGlobal()); + model.setRegularExpressions(isRegularExpressions()); + model.setWholeWordsOnly(isWholeWordsOnly()); + model.setWithSubdirectories(isWithSubdirectories()); + model.setFileFilter(FILE_MASK); + } + + private static void addStringToList(String str, List list, int maxSize){ + if(list.contains(str)){ + list.remove(str); + } + list.add(str); + while(list.size() > maxSize){ + list.remove(0); + } + } + + public void addStringToFind(String s){ + if ((s == null) || (s.indexOf('\r') >= 0) || (s.indexOf('\n') >= 0)){ + return; + } + addStringToList(s, RECENT_FIND_STRINGS, MAX_RECENT_SIZE); + } + + public void addStringToReplace(String s) { + if ((s == null) || (s.indexOf('\r') >= 0) || (s.indexOf('\n') >= 0)){ + return; + } + addStringToList(s, RECENT_REPLACE_STRINGS, MAX_RECENT_SIZE); + } + + public void addDirectory(String s) { + if (s == null || s.length() == 0){ + return; + } + addStringToList(s, RECENT_DIR_STRINGS, MAX_RECENT_SIZE); + } + + public String[] getRecentFindStrings(){ + return (String[])RECENT_FIND_STRINGS.toArray(new String[RECENT_FIND_STRINGS.size()]); + } + + public String[] getRecentReplaceStrings(){ + return (String[])RECENT_REPLACE_STRINGS.toArray(new String[RECENT_REPLACE_STRINGS.size()]); + } + + public ArrayList getRecentDirectories(){ + return new ArrayList(RECENT_DIR_STRINGS); + } + + public String getFileMask() { + return FILE_MASK; + } + + public void setFileMask(String _fileMask) { + this.FILE_MASK = _fileMask; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/HelpID.java new file mode 100644 index 00000000000..0318b73448f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/impl/HelpID.java @@ -0,0 +1,18 @@ + +package com.intellij.find.impl; + +/** + * + */ +public interface HelpID { + String FIND_PACKAGE_USAGES = "find.findPackageUsages"; + String FIND_CLASS_USAGES = "find.findClassUsages"; + String FIND_METHOD_USAGES = "find.findMethodUsages"; + String FIND_FIELD_USAGES = "find.findFieldUsages"; + String FIND_VARIABLE_USAGES = "find.findVariableUsages"; + String FIND_PARAMETER_USAGES = "find.findParameterUsages"; + String FIND_THROW_USAGES = "find.findThrowUsages"; + + String FIND_IN_PROJECT = "find.findInProject"; + String REPLACE_IN_PROJECT = "find.findInProject"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/replaceInProject/ReplaceInProjectManager.java new file mode 100644 index 00000000000..94e6fc82a1e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/find/replaceInProject/ReplaceInProjectManager.java @@ -0,0 +1,403 @@ + +package com.intellij.find.replaceInProject; + +import com.intellij.find.*; +import com.intellij.find.findInProject.FindInProjectManager; +import com.intellij.find.impl.FindInProjectUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.usageView.*; + +import javax.swing.*; +import javax.swing.tree.TreePath; + +public class ReplaceInProjectManager implements ProjectComponent { + private Project myProject; + private boolean myIsFindInProgress = false; + + public static ReplaceInProjectManager getInstance(Project project) { + return project.getComponent(ReplaceInProjectManager.class); + } + + public void projectOpened() {} + + public void projectClosed() {} + + public String getComponentName() { + return "ReplaceInProjectManager"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public ReplaceInProjectManager(Project project) { + myProject = project; + } + + public void replaceInProject(DataContext dataContext) { + final FindManager findManager = FindManager.getInstance(myProject); + final FindModel findModel = (FindModel) findManager.getFindInProjectModel().clone(); + findModel.setReplaceState(true); + FindInProjectUtil.setDirectoryName(findModel, dataContext); + + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null){ + String s = editor.getSelectionModel().getSelectedText(); + if (s != null && (s.indexOf("\r") == -1) && (s.indexOf("\n") == -1)){ + findModel.setStringToFind(s); + } + } + if (!findManager.showFindDialog(findModel)){ + return; + } + final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject); + if (!findModel.isProjectScope() && psiDirectory == null && findModel.getModuleName()==null){ + return; + } + + class AsyncFindUsagesCommandImpl implements AsyncFindUsagesCommand { + ReplaceInProjectViewDescriptor viewDescriptor; + UsageView usagesPanel; + ProgressIndicator progress; + + public void findUsages(final AsyncFindUsagesProcessListener consumer) { + progress = new FindProgressIndicator (myProject, FindInProjectUtil.getTitleForScope(findModel)); + final Runnable findUsagesRunnable = new Runnable() { + public void run() { + FindInProjectUtil.findUsages(findManager.getFindInProjectModel(), psiDirectory, myProject, consumer); + } + }; + final Runnable showUsagesPanelRunnable = new Runnable() { + public void run() { + myIsFindInProgress = false; + + if (consumer.getCount()!=0 && findManager.getFindInProjectModel().isPromptOnReplace()){ + replaceWithPrompt(usagesPanel, viewDescriptor); + } + } + }; + + Runnable showUsagesPanelRunnable1 = new Runnable() { + public void run() { + // This is important since not all usages are flushed during async processing! + SwingUtilities.invokeLater(showUsagesPanelRunnable); + } + }; + + myIsFindInProgress = true; + findManager.getFindInProjectModel().copyFrom(findModel); + FindInProjectUtil.runProcessWithProgress(progress, findUsagesRunnable, showUsagesPanelRunnable1, myProject); + } + + public void stopAsyncSearch() { + progress.cancel(); + } + }; + + AsyncFindUsagesCommandImpl findUsagesCommand = new AsyncFindUsagesCommandImpl(); + ReplaceInProjectViewDescriptor viewDescriptor = new ReplaceInProjectViewDescriptor(findModel, findUsagesCommand); + UsageView usagesPanel = showUsagesPanel(viewDescriptor); + + findUsagesCommand.viewDescriptor = viewDescriptor; + findUsagesCommand.usagesPanel = usagesPanel; + } + + private void replaceWithPrompt(final UsageView usageView, final ReplaceInProjectViewDescriptor viewDescriptor) { + final UsageInfo[] usages = usageView.getUsages(); + + if (UsageViewUtil.hasReadOnlyUsages(usages)){ + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + return; + } + + usageView.expandAll(); + for(int i = 0; i < usages.length; i++){ + final PsiFile psiFile = usages[i].getElement().getContainingFile(); + if (!psiFile.isWritable()) continue; + final UsageInfo usageInfo = usages[i]; + + Runnable selectOnEditorRunnable = new Runnable() { + public void run() { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null && + ApplicationManager.getApplication().runReadAction( + new Computable() { + public Boolean compute() { + return virtualFile.isValid() ? Boolean.TRUE : Boolean.FALSE; + } + } + ).booleanValue()) { + int startOffset = usageView.getTextOffset(usageInfo); + int endOffset = usageView.getTextEndOffset(usageInfo); + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (endOffset <= document.getTextLength()) { + OpenFileDescriptor descriptor = new OpenFileDescriptor(myProject, virtualFile, startOffset); + FileEditorManager.getInstance(myProject).openTextEditor(descriptor, false); + descriptor = new OpenFileDescriptor(myProject, virtualFile, endOffset); + Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(descriptor, false); + if (editor != null) { + editor.getSelectionModel().setSelection(startOffset, endOffset); + } + usageView.selectUsage(usageInfo); + } + } + } + }; + CommandProcessor.getInstance().executeCommand(myProject, selectOnEditorRunnable, "Select on Editor", null); + + String title = "Replace Usage " + (i + 1) + " of " + usages.length + " Found"; + + int result = FindManager.getInstance(myProject).showPromptDialog(viewDescriptor.getFindModel(), title); + + if (result == PromptResult.CANCEL){ + return; + } + if (result == PromptResult.SKIP){ + continue; + } + + final int currentNumber = i; + if (result == PromptResult.OK){ + Runnable runnable = new Runnable() { + public void run() { + doReplace(usageView, usages[currentNumber], viewDescriptor); + usageView.removeUsage(usages[currentNumber]); + } + }; + CommandProcessor.getInstance().executeCommand(myProject, runnable, "Replace", null); + if (usageView.getUsagesNodeCount() == 0){ + UsageViewManager.getInstance(myProject).closeContent(usageView); + return; + } + } + + if (result == PromptResult.ALL_IN_THIS_FILE){ + final int[] nextNumber = new int[1]; + Runnable runnable = new Runnable() { + public void run() { + int j = currentNumber; + for(; j < usages.length; j++){ + PsiFile otherPsiFile = usages[j].getElement().getContainingFile(); + if (!otherPsiFile.equals(psiFile)){ + break; + } + doReplace(usageView, usages[j], viewDescriptor); + usageView.removeUsage(usages[j]); + } + if (j >= usages.length){ + UsageViewManager.getInstance(myProject).closeContent(usageView); + } + nextNumber[0] = j; + } + }; + CommandProcessor.getInstance().executeCommand(myProject, runnable, "Replace", null); + if (usageView.getUsagesNodeCount() == 0){ + UsageViewManager.getInstance(myProject).closeContent(usageView); + return; + } + i = nextNumber[0] - 1; + } + + if (result == PromptResult.ALL_FILES){ + /* + Runnable process = new Runnable() { + public void run() { + for(int j = currentNumber; j < usages.length; j++){ + doReplace(usageView, usages[j], viewDescriptor); + } + } + }; + Runnable finishProcess = new Runnable() { + public void run() { + ExternalUISupport.getInstance(myProject).closeContent(usageView); + } + }; + ProgressUtil.runPsiCommandWithProgress(myProject, process, finishProcess, "Replacing...", "Replace", false); + */ + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + for(int j = currentNumber; j < usages.length; j++){ + doReplace(usageView, usages[j], viewDescriptor); + } + UsageViewManager.getInstance(myProject).closeContent(usageView); + } + }, + "Replace", + null + ); + break; + } + } + } + + private UsageView showUsagesPanel(final ReplaceInProjectViewDescriptor viewDescriptor) { + String name = "Search result"; + String stringToFind = viewDescriptor.getFindModel().getStringToFind(); + if (stringToFind != null) { + if (stringToFind.length() > 15) { + stringToFind = stringToFind.substring(0, 15) + "..."; + } + name = "Occurrences of '" + stringToFind + "'"; + if (viewDescriptor.getFindModel().isMultipleFiles() ) { + name += " in " + FindInProjectUtil.getTitleForScope(viewDescriptor.getFindModel()); + } + } + UsageView usagesPanel = UsageViewManager.getInstance(myProject).addContent(name, viewDescriptor, false, false, false, new ProgressFactory() { + public ProgressIndicator createProgress() { + return new FindProgressIndicator(myProject, FindInProjectUtil.getTitleForScope(viewDescriptor.getFindModel())); + } + + public boolean continueOnCancel() { + return true; + } + }); + usagesPanel.addButton(0, new ReplaceSelectedAction(usagesPanel, viewDescriptor)); + addReplaceAllAction(usagesPanel, viewDescriptor); + return usagesPanel; + + } + + private void addReplaceAllAction(final UsageView usageView, final ReplaceInProjectViewDescriptor viewDescriptor) { + final Runnable replaceRunnable = new Runnable() { + public void run() { + doReplace(usageView, usageView.getUsages(), viewDescriptor); + } + }; + usageView.addDoProcessAction(replaceRunnable, "Replace All",null,"&Do Replace All"); + } + + private class ReplaceSelectedAction extends AnAction { + private UsageView myUsagesPanel; + private ReplaceInProjectViewDescriptor myTreeInfo; + + public ReplaceSelectedAction(UsageView usagesPanel, ReplaceInProjectViewDescriptor treeInfo){ + super( + "Rep&lace Selected", + "Replace selected occurrences of \"" + treeInfo.getFindModel().getStringToFind() + "\" to \"" + treeInfo.getFindModel().getStringToReplace() + "\"", + null + ); + myUsagesPanel=usagesPanel; + myTreeInfo=treeInfo; + } + + public void actionPerformed(AnActionEvent event) { + doReplaceSelected(myUsagesPanel, myTreeInfo); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(!myIsFindInProgress); + super.update(e); + } + } + + private void doReplace(UsageView usageView, UsageInfo[] usages, ReplaceInProjectViewDescriptor treeInfo) { + for(int i = 0; i < usages.length; i++){ + doReplace(usageView, usages[i], treeInfo); + } + } + + private void doReplace(final UsageView usageView, final UsageInfo usage, final ReplaceInProjectViewDescriptor treeInfo) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + if (usageView.isExcluded(usage)){ + return; + } + PsiFile file = (PsiFile)usage.getElement(); + Project project = file.getProject(); + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + if (!document.isWritable()) return; + + final int textOffset = usageView.getTextOffset(usage); + if (textOffset < 0 || textOffset >= document.getTextLength()){ + return; + } + final int textEndOffset = usageView.getTextEndOffset(usage); + if (textEndOffset < 0 || textOffset > document.getTextLength()){ + return; + } + FindManager findManager = FindManager.getInstance(myProject); + final CharSequence foundString = document.getCharsSequence().subSequence(textOffset, textEndOffset); + FindResult findResult = findManager.findString(foundString, 0, treeInfo.getFindModel()); + if (findResult == null || !findResult.isStringFound()){ + return; + } + String stringToReplace = findManager.getStringToReplace(foundString.toString(), treeInfo.getFindModel()); + document.replaceString(textOffset, textEndOffset, stringToReplace); + } + }); + } + + private void doReplaceSelected(final UsageView usageView, final ReplaceInProjectViewDescriptor treeInfo) { + TreePath[] paths = usageView.getTree().getSelectionPaths(); + if (paths == null || paths.length == 0){ + return; + } + + final UsageInfo[] usages = usageView.getSelectedUsages(); + if(usages == null){ + return; + } + if (UsageViewUtil.hasReadOnlyUsages(usages)){ + int result = Messages.showOkCancelDialog( + usageView.getTree(), + "Occurrences found in read-only files.\n" + + "The operation will not affect them.\n" + + "Continue anyway?", + "Read-only Files Found", + Messages.getWarningIcon() + ); + if (result != 0){ + return; + } + } + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + doReplace(usageView, usages, treeInfo); + for (int i = 0; i < usages.length; i++) { + usageView.removeUsage(usages[i]); + } + + if (usageView.getUsagesNodeCount() == 0){ + UsageViewManager.getInstance(myProject).closeContent(usageView); + return; + } + usageView.setFocused(); + } + }, + "Replace", + null + ); + } + + public boolean isWorkInProgress() { + return myIsFindInProgress; + } + + public boolean isEnabled () { + return !myIsFindInProgress && !FindInProjectManager.getInstance(myProject).isWorkInProgress(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/HelpManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/HelpManagerImpl.java new file mode 100644 index 00000000000..cc8fe1f1f00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/HelpManagerImpl.java @@ -0,0 +1,97 @@ +package com.intellij.help.impl; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.ui.Messages; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginDescriptor; + +import javax.help.BadIDException; +import javax.help.HelpSet; +import javax.help.HelpSetException; +import java.awt.*; +import java.net.URL; + +public class HelpManagerImpl extends HelpManager implements ApplicationComponent { + private HelpSet myHelpSet = null; + private IdeaHelpBroker myBroker = null; + + public void initComponent() { } + + public void disposeComponent() { + } + + public void invokeHelp(String id) { + if (myHelpSet == null) { + try { + myHelpSet = createHelpSet(); + } catch (Exception ex) { + } + } + if (myHelpSet == null) { + Messages.showMessageDialog("Help not found for " + id, "Help Not Found", Messages.getErrorIcon()); + return; + } + if (myBroker == null) { + myBroker = new IdeaHelpBroker(myHelpSet); + } + + Window activeWindow=KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + myBroker.setActivationWindow(activeWindow); + /* + URL currentURL = myBroker.getCurrentURL(); + System.out.println("currentURL = " + currentURL); + */ + if (id != null) { + try { + myBroker.setCurrentID(id); + } + catch (BadIDException e) { + Messages.showMessageDialog("Help topic \"" + id + "\" not found", "Error", Messages.getErrorIcon()); + return; + } + } + myBroker.setDisplayed(true); + } + + public String getComponentName() { + return "HelpManager"; + } + + private static HelpSet createHelpSet() { + // This is a temporary solution: path to the help should be customized somehow + String urlToHelp = PathManager.getHelpURL() + "/" + "Help.hs"; + + try { + HelpSet helpSet = new HelpSet(null, new URL (urlToHelp)); + + // merge plugins help sets + PluginDescriptor [] pluginDescriptors = PluginManager.getPlugins(); + for (int i = 0; i < pluginDescriptors.length; i++) { + PluginDescriptor pluginDescriptor = pluginDescriptors[i]; + if (pluginDescriptor.getHelpSets() != null && pluginDescriptor.getHelpSets().length > 0) { + for (int j = 0; j < pluginDescriptor.getHelpSets().length; j++) { + PluginDescriptor.HSPath hsPath = pluginDescriptor.getHelpSets()[j]; + + URL hsURL = new URL("jar:file:///" + pluginDescriptor.getPath().getAbsolutePath() + "/help/" + hsPath.getFile() + "!" + hsPath.getPath()); + try { + HelpSet pluginHelpSet = new HelpSet (null, hsURL); + helpSet.add(pluginHelpSet); + } + catch (HelpSetException e) { + e.printStackTrace(); + // damn + } + } + } + } + + return helpSet; + } + catch (Exception ee) { + System.err.println("HelpSet " + urlToHelp + " not found"); + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpBroker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpBroker.java new file mode 100644 index 00000000000..5b7c13e704f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpBroker.java @@ -0,0 +1,742 @@ +package com.intellij.help.impl; + +import com.intellij.util.ImageLoader; + +import javax.help.*; +import javax.help.Map.ID; +import javax.help.UnsupportedOperationException; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Enumeration; +import java.util.Locale; + +/** + * It a dirty patch! Help system is so ugly that it hangs when it open some "external" links. + * To prevent this we open "external" links in nornal WEB browser. + * This is copy-pasted version of DefaultHelpBroker class. + * + * @author Vladimir Kondratyev + */ +class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{ + + private HelpSet myHelpSet=null; + private JFrame myFrame=null; + private JHelp jhelp=null; + private Locale myLocale=null; + private Font myFont=null; + /** + * The container for modally activated help + * @since 1.1 + */ + private JDialog myDialog=null; + /** + * The modal Window that activated help + * @since 1.1 + */ + private Window myOwnerWindow=null; + /** + * The flag for modally activated help. If true, help was activated from + * a modal dialog. Can not be set to true for V1.1. + * @since 1.1 + */ + private boolean myModallyActivated=false; + + /** + * Constructor + */ + + public IdeaHelpBroker(HelpSet hs){ + setHelpSet(hs); + } + + /** + * Returns the default HelpSet + */ + public HelpSet getHelpSet(){ + return myHelpSet; + } + + /** + * Changes the HelpSet for this broker. + * @param hs The HelpSet to set for this broker. + * A null hs is valid parameter. + */ + public void setHelpSet(HelpSet hs){ + // If we already have a jhelp check if the HelpSet has changed. + // If so change the model on the jhelp viewer. + // This could be made smarter to cache the helpmodels per HelpSet + if(hs!=null&&myHelpSet!=hs){ + if(jhelp!=null){ + TextHelpModel model=new DefaultHelpModel(hs); + jhelp.setModel(model); + } + myHelpSet=hs; + + } + } + + + /** + * Gets the locale of this component. + * @return This component's locale. If this component does not + * have a locale, the defaultLocale is returned. + * @see #setLocale + */ + public Locale getLocale(){ + if(myLocale==null){ + return Locale.getDefault(); + } + return myLocale; + } + + /** + * Sets the locale of this HelpBroker. The locale is propagated to + * the presentation. + * @param l The locale to become this component's locale. A null locale + * is the same as the defaultLocale. + * @see #getLocale + */ + public void setLocale(Locale l){ + myLocale=l; + if(jhelp!=null){ + jhelp.setLocale(myLocale); + } + } + + /** + * Gets the font for this HelpBroker. + */ + public Font getFont(){ + createHelpWindow(); + + if(myFont==null){ + return jhelp.getFont(); + } + return myFont; + } + + /** + * Sets the font for this this HelpBroker. + * @param f The font. + */ + public void setFont(Font f){ + myFont=f; + if(jhelp!=null){ + jhelp.setFont(myFont); + } + } + + /** + * Set the currentView to the navigator with the same + * name as the name parameter. + * + * @param name The name of the navigator to set as the + * current view. If nav is null or not a valid Navigator + * in this HelpBroker then an + * IllegalArgumentException is thrown. + * @throws IllegalArgumentException if nav is null or not a valid Navigator. + */ + public void setCurrentView(String name){ + createHelpWindow(); + JHelpNavigator nav=null; + + for(Enumeration e=jhelp.getHelpNavigators(); + e.hasMoreElements();){ + nav=(JHelpNavigator)e.nextElement(); + if(nav.getNavigatorName().equals(name)){ + break; + } + nav=null; + } + + if(nav==null){ + throw new IllegalArgumentException("Invalid view name"); + } + jhelp.setCurrentNavigator(nav); + } + + /** + * Determines the current navigator. + */ + public String getCurrentView(){ + createHelpWindow(); + return jhelp.getCurrentNavigator().getNavigatorName(); + } + + + /** + * Initializes the presentation. + * This method allows the presentation to be initialized but not displayed. + * Typically this would be done in a separate thread to reduce the + * intialization time. + */ + public void initPresentation(){ + createHelpWindow(); + } + + /** + * Displays the presentation to the user. + */ + public void setDisplayed(boolean visible){ + createHelpWindow(); + if(myModallyActivated){ + if(visible){ + myDialog.setLocationRelativeTo(myDialog.getOwner()); + myDialog.show(); + } else{ + myDialog.hide(); + } + } else{ + //myFrame.setLocationRelativeTo(null); + myFrame.setVisible(visible); + myFrame.setState(JFrame.NORMAL); + } + } + + /** + * Determines if the presentation is displayed. + */ + public boolean isDisplayed(){ + if(myModallyActivated){ + if(myDialog!=null){ + return myDialog.isShowing(); + } else{ + return false; + } + } else{ + if(myFrame!=null){ + if(!myFrame.isVisible()){ + return false; + } else{ + return myFrame.getState() == JFrame.NORMAL; + } + } else{ + return false; + } + } + } + + /** + * Requests the presentation be located at a given position. + * This operation may throw an UnsupportedOperationException if the + * underlying implementation does not allow this. + */ + public void setLocation(Point p) throws UnsupportedOperationException{ + createHelpWindow(); + if(myModallyActivated){ + myDialog.setLocation(p); + } else{ + myFrame.setLocation(p); + } + } + + /** + * Requests the location of the presentation. + * @throws UnsupportedOperationException If the underlying implementation + * does not allow this. + * @throws IllegalComponentStateException If the presentation is not + * displayed. + * @return Point the location of the presentation. + */ + public Point getLocation() throws UnsupportedOperationException{ + if(jhelp==null){ + throw new java.awt.IllegalComponentStateException("presentation not displayed"); + } + if(myModallyActivated){ + if(myDialog!=null){ + return myDialog.getLocation(); + } + } else{ + if(myFrame!=null){ + return myFrame.getLocation(); + } + } + return null; + + } + + /** + * Requests the presentation be set to a given size. + * This operation may throw an UnsupportedOperationException if the + * underlying implementation does not allow this. + */ + public void setSize(Dimension d) throws UnsupportedOperationException{ + HELP_WIDTH=d.width; + HELP_HEIGHT=d.height; + createHelpWindow(); + if(myModallyActivated){ + myDialog.setSize(d); + myDialog.validate(); + } else{ + myFrame.setSize(d); + myFrame.validate(); + } + } + + /** + * Requests the size of the presentation. + * @throws UnsupportedOperationException If the underlying implementation + * does not allow this. + * @throws IllegalComponentStateException If the presentation is not + * displayed. + * @return Point the location of the presentation. + */ + public Dimension getSize() throws UnsupportedOperationException{ + if(jhelp==null){ + throw new java.awt.IllegalComponentStateException("presentation not displayed"); + } + if(myModallyActivated){ + if(myDialog!=null){ + return myDialog.getSize(); + } + } else{ + if(myFrame!=null){ + return myFrame.getSize(); + } + } + return null; + } + + /** + * Hides/Shows view. + */ + public void setViewDisplayed(boolean displayed){ + createHelpWindow(); + jhelp.setNavigatorDisplayed(displayed); + } + + /** + * Determines if the current view is visible. + */ + public boolean isViewDisplayed(){ + createHelpWindow(); + return jhelp.isNavigatorDisplayed(); + } + + /** + * Shows this ID as content relative to the (top) HelpSet for the HelpBroker + * instance--HelpVisitListeners are notified. + * + * @param id A string that identifies the topic to show for the loaded (top) HelpSet + * @exception BadIDException The ID is not valid for the HelpSet + */ + public void setCurrentID(String id) throws BadIDException{ + try{ + setCurrentID(ID.create(id,myHelpSet)); + } catch(InvalidHelpSetContextException ex){ + // this should not happen + new Error("internal error?"); + } + } + + /** + * Displays this ID--HelpVisitListeners are notified. + * + * @param id a Map.ID indicating the URL to display + * @exception InvalidHelpSetContextException if the current helpset does not contain + * id.helpset + */ + public void setCurrentID(ID id) throws InvalidHelpSetContextException{ + createJHelp(); + jhelp.getModel().setCurrentID(id); + } + + /** + * Determines which ID is displayed (if any). + */ + public ID getCurrentID(){ + if(jhelp!=null){ + return jhelp.getModel().getCurrentID(); + } else{ + return null; + } + } + + /** + * Displays this URL. + * HelpVisitListeners are notified. + * The currentID changes if there is a mathing ID for this URL + * @param url The url to display. A null URL is a valid url. + */ + public void setCurrentURL(URL url){ + createHelpWindow(); + + jhelp.getModel().setCurrentURL(url); + if(myModallyActivated){ + myDialog.setVisible(true); + myDialog.show(); + } else{ + myFrame.setVisible(true); + myFrame.show(); + } + } + + /** + * Determines which URL is displayed. + */ + public URL getCurrentURL(){ + return jhelp.getModel().getCurrentURL(); + } + + + // Context-Senstive methods + /** + * Enables the Help key on a Component. This method works best when + * the component is the + * rootPane of a JFrame in Swing implementations, or a java.awt.Window + * (or subclass thereof) in AWT implementations. + * This method sets the default + * helpID and HelpSet for the Component and registers keyboard actions + * to trap the "Help" keypress. When the "Help" key is pressed, if the + * object with the current focus has a helpID, the helpID is displayed. + * otherwise the default helpID is displayed. + * + * @param comp the Component to enable the keyboard actions on. + * @param id the default HelpID to be displayed + * @param hs the default HelpSet to be displayed. If hs is null the default HelpSet + * will be assumed. + */ + public void enableHelpKey(Component comp,String id,HelpSet hs){ + if(id==null){ + throw new NullPointerException("id"); + } + CSH.setHelpIDString(comp,id); + if(hs!=null){ + CSH.setHelpSet(comp,hs); + } + if(comp instanceof JComponent){ + JComponent root=(JComponent)comp; + root.registerKeyboardAction(getDisplayHelpFromFocus(), + KeyStroke.getKeyStroke(KeyEvent.VK_HELP,0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + root.registerKeyboardAction(getDisplayHelpFromFocus(), + KeyStroke.getKeyStroke(KeyEvent.VK_F1,0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } else{ + comp.addKeyListener(this); + } + } + + /** + * Invoked when a key is typed. This event occurs when a + * key press is followed by a key release. Not intended to be overridden or extended. + */ + public void keyTyped(KeyEvent e){ + //ignore + } + + /** + * Invoked when a key is pressed. Not intended to be overridden or extended. + */ + public void keyPressed(KeyEvent e){ + //ingore + } + + + /** + * Invoked when a key is released. Not intended to be overridden or extended. + */ + public void keyReleased(KeyEvent e){ + // simulate what is done in JComponents registerKeyboardActions. + int code=e.getKeyCode(); + if(code==KeyEvent.VK_F1||code==KeyEvent.VK_HELP){ + ActionListener al=getDisplayHelpFromFocus(); + al.actionPerformed(new ActionEvent(e.getComponent(), + ActionEvent.ACTION_PERFORMED, + null)); + } + + } + + /** + * Enables help for a Component. This method sets a + * component's helpID and HelpSet. + * + * @param comp the Component to set the id and hs on. + * @param id the String value of an Map.ID. + * @param hs the HelpSet the id is in. If hs is null the default HelpSet + * will be assumed. + */ + public void enableHelp(Component comp,String id,HelpSet hs){ + if(id==null){ + throw new NullPointerException("id"); + } + CSH.setHelpIDString(comp,id); + if(hs!=null){ + CSH.setHelpSet(comp,hs); + } + } + + /** + * Enables help for a MenuItem. This method sets a + * component's helpID and HelpSet. + * + * @param comp the MenuItem to set the id and hs on. + * @param id the String value of an Map.ID. + * @param hs the HelpSet the id is in. If hs is null the default HelpSet + * will be assumed. + */ + public void enableHelp(MenuItem comp,String id,HelpSet hs){ + if(id==null){ + throw new NullPointerException("id"); + } + CSH.setHelpIDString(comp,id); + if(hs!=null){ + CSH.setHelpSet(comp,hs); + } + } + + /** + * Enables help for a Component. This method sets a + * Component's helpID and HelpSet and adds an ActionListener. + * When an action is performed + * it displays the Component's helpID and HelpSet in the default viewer. + * + * @param comp the Component to set the id and hs on. If the Component is not + * a javax.swing.AbstractButton or a + * java.awt.Button an IllegalArgumentException is thrown. + * @param id the String value of an Map.ID. + * @param hs the HelpSet the id is in. If hs is null the default HelpSet + * will be assumed. + * + * @see javax.swing.AbstractButton + * @see java.awt.Button + * @throws IllegalArgumentException if comp is null. + */ + public void enableHelpOnButton(Component comp,String id,HelpSet hs){ + if(!(comp instanceof AbstractButton)&&!(comp instanceof Button)){ + throw new IllegalArgumentException("Invalid Component"); + } + if(id==null){ + throw new NullPointerException("id"); + } + CSH.setHelpIDString(comp,id); + if(hs!=null){ + CSH.setHelpSet(comp,hs); + } + if(comp instanceof AbstractButton){ + AbstractButton button=(AbstractButton)comp; + button.addActionListener(getDisplayHelpFromSource()); + }else{ + Button button=(Button)comp; + button.addActionListener(getDisplayHelpFromSource()); + } + } + + /** + * Enables help for a MenuItem. This method sets a + * Component's helpID and HelpSet and adds an ActionListener. + * When an action is performed + * it displays the Component's helpID and HelpSet in the default viewer. + * + * @param comp the MenuItem to set the id and hs on. If comp is null + * an IllegalAgrumentException is thrown. + * @param id the String value of an Map.ID. + * @param hs the HelpSet the id is in. If hs is null the default HelpSet + * will be assumed. + * @see java.awt.MenuItem + * @throws IllegalArgumentException if comp is null. + */ + public void enableHelpOnButton(MenuItem comp,String id,HelpSet hs){ + if(comp==null){ + throw new IllegalArgumentException("Invalid Component"); + } + if(id==null){ + throw new NullPointerException("id"); + } + CSH.setHelpIDString(comp,id); + if(hs!=null){ + CSH.setHelpSet(comp,hs); + } + comp.addActionListener(getDisplayHelpFromSource()); + } + + /** + * Returns the default DisplayHelpFromFocus listener. + */ + protected ActionListener getDisplayHelpFromFocus(){ + if(displayHelpFromFocus==null){ + displayHelpFromFocus=new CSH.DisplayHelpFromFocus(this); + } + return displayHelpFromFocus; + } + + /** + * Returns the default DisplayHelpFromSource listener. + */ + protected ActionListener getDisplayHelpFromSource(){ + if(displayHelpFromSource==null){ + displayHelpFromSource=new CSH.DisplayHelpFromSource(this); + } + return displayHelpFromSource; + } + + /** + * Set the activation window. If the window is an instance of a + * Dialog and the is modal, modallyActivated help is set to true and + * ownerDialog is set to the window. In all other instances + * modallyActivated is set to false and ownerDialog is set to null. + * @param window the activating window + * @since 1.1 + */ + public void setActivationWindow(Window window){ + if(window!=null&&window instanceof Dialog){ + Dialog tmpDialog=(Dialog)window; + if(tmpDialog.isModal()){ + myOwnerWindow=window; + myModallyActivated=true; + } else{ + myOwnerWindow=null; + myModallyActivated=false; + } + } else{ + myOwnerWindow=null; + myModallyActivated=false; + } + } + + + /** + * Private methods. + */ + private int HELP_WIDTH = (int)(Toolkit.getDefaultToolkit().getScreenSize().width * 0.8); + private int HELP_HEIGHT = (int)(Toolkit.getDefaultToolkit().getScreenSize().height * 0.8); + + private synchronized void createJHelp(){ + if(jhelp==null){ + jhelp=new IdeaJHelp(myHelpSet); + if(myFont!=null){ + jhelp.setFont(myFont); + } + if(myLocale!=null){ + jhelp.setLocale(myLocale); + } + } + } + + private WindowListener dl; + private boolean modalDeactivated=true; + + private synchronized void createHelpWindow(){ + JDialog tmpDialog=null; + Dimension size=null; + Point pos=null; + boolean resize = false; + + createJHelp(); + // Get the title from the HelpSet + String helpTitle=myHelpSet.getTitle(); + + if(myModallyActivated){ + // replace dialog.getOwner() with the following code + Window owner=null; + try{ + Method m=Window.class.getMethod("getOwner",null); + + if(m!=null&&myDialog!=null){ + owner=(Window)m.invoke(myDialog,null); + } + } catch(NoSuchMethodError ex){ + // as in JDK1.1 + } catch(NoSuchMethodException ex){ + // as in JDK1.1 + } catch(java.lang.reflect.InvocationTargetException ex){ + // + } catch(java.lang.IllegalAccessException ex){ + // + } + + if(myDialog==null||owner!=myOwnerWindow||modalDeactivated){ + if(myFrame!=null){ + pos=myFrame.getLocation(); + size=myFrame.getSize(); + myFrame.dispose(); + } + if(myDialog!=null){ + pos=myDialog.getLocation(); + size=myDialog.getSize(); + tmpDialog=myDialog; + } + + myDialog=new JDialog((Dialog)myOwnerWindow,helpTitle); + + // Modal dialogs are really tricky. When the modal dialog + // is dismissed the JDialog will be dismissed as well. + // When that happens we need to make sure the ownerWindow + // is set to null so that a new dialog will be created so + // that events aren't blocked in the HelpViewer. + dl=new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + // JDK1.2.1 bug not closing owned windows + if(myDialog.isShowing()){ + myDialog.hide(); + } + if(myOwnerWindow!=null) + myOwnerWindow.removeWindowListener(dl); + myOwnerWindow=null; + modalDeactivated=true; + } + }; + myOwnerWindow.addWindowListener(dl); + modalDeactivated=false; + + if(size!=null){ + myDialog.setSize(size); + } else{ + myDialog.setSize(HELP_WIDTH,HELP_HEIGHT); + } + if(pos!=null){ + myDialog.setLocation(pos); + } + myDialog.getContentPane().add(jhelp); + if(tmpDialog!=null){ + tmpDialog.dispose(); + } + } + } else{ + if(myFrame==null){ + myFrame=new JFrame(helpTitle); + resize = true; + Image image = ImageLoader.loadFromResource("/icon.png"); + myFrame.setIconImage(image); + WindowListener l=new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + myFrame.setVisible(false); + } + + public void windowClosed(WindowEvent e){ + myFrame.setVisible(false); + } + }; + myFrame.addWindowListener(l); + } else + pos = myFrame.getLocation(); + if(myDialog!=null){ + pos=myDialog.getLocation(); + size=myDialog.getSize(); + myDialog.dispose(); + myDialog=null; + myOwnerWindow=null; + } + if(size!=null){ + myFrame.setSize(size); + } else if (resize) { + myFrame.setSize(HELP_WIDTH,HELP_HEIGHT); + } + if(pos!=null){ + myFrame.setLocation(pos); + } + myFrame.getContentPane().add(jhelp); + myFrame.setTitle(myHelpSet.getTitle()); + } + + } + + // the listeners. + private ActionListener displayHelpFromFocus; + private ActionListener displayHelpFromSource; +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpContentViewUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpContentViewUI.java new file mode 100644 index 00000000000..a9e8050ef21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaHelpContentViewUI.java @@ -0,0 +1,35 @@ +package com.intellij.help.impl; + +import com.intellij.ide.BrowserUtil; + +import javax.help.JHelpContentViewer; +import javax.help.plaf.basic.BasicContentViewerUI; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import java.net.URL; + +/** + * It a dirty patch! Help system is so ugly that it hangs when it open some "external" links. + * To prevent this we open "external" links in nornal WEB browser. + * + * @author Vladimir Kondratyev + */ +class IdeaHelpContentViewUI extends BasicContentViewerUI{ + /** invoked by reflection */ + public static ComponentUI createUI(JComponent x) { + return new IdeaHelpContentViewUI((JHelpContentViewer) x); + } + + public IdeaHelpContentViewUI(JHelpContentViewer contentViewer){ + super(contentViewer); + } + + protected void linkActivated(URL u){ + String url=u.toExternalForm(); + if(url.startsWith("http") || url.startsWith("ftp")){ + BrowserUtil.launchBrowser(url); + }else{ + super.linkActivated(u); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelp.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelp.java new file mode 100644 index 00000000000..d93c92c96b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelp.java @@ -0,0 +1,39 @@ +package com.intellij.help.impl; + +import javax.help.DefaultHelpModel; +import javax.help.HelpSet; +import javax.help.JHelp; +import java.util.Vector; + +/** + * It a dirty patch! Help system is so ugly that it hangs when it open some "external" links. + * To prevent this we open "external" links in nornal WEB browser. + * + * @author Vladimir Kondratyev + */ +class IdeaJHelp extends JHelp{ + /** + * PATCHED VERSION OF SUPER CONSTRUCTOR + */ + public IdeaJHelp(HelpSet hs){ + super(new DefaultHelpModel(hs)); + + navigators=new Vector(); + navDisplayed=true; + + // HERE -- need to do something about doc title changes.... + + this.contentViewer=new IdeaJHelpContentViewer(helpModel); + + setModel(helpModel); + if(helpModel!=null){ + setupNavigators(); + } + + updateUI(); + } + + public void updateUI(){ + setUI(new IdeaHelpUI()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelpContentViewer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelpContentViewer.java new file mode 100644 index 00000000000..3819fcb573a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/help/impl/IdeaJHelpContentViewer.java @@ -0,0 +1,31 @@ +package com.intellij.help.impl; + +import javax.help.JHelpContentViewer; +import javax.help.TextHelpModel; + +/** + * It a dirty patch! Help system is so ugly that it hangs when it open some "external" links. + * To prevent this we open "external" links in nornal WEB browser. + * + * @author Vladimir Kondratyev + */ +class IdeaJHelpContentViewer extends JHelpContentViewer{ + /** + * Creates a JHelp with an specific TextHelpModel as its data model. + * + * @param model The TextHelpModel. A null model is valid. + */ + public IdeaJHelpContentViewer(TextHelpModel model){ + super(model); + } + + /** + * PATCHED VERSION OF SUPER METHDO. + * Replaces the UI with the latest version from the default + * UIFactory. + */ + public void updateUI(){ + setUI(new IdeaHelpContentViewUI(this)); + invalidate(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/CopyPasteManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/CopyPasteManagerEx.java new file mode 100644 index 00000000000..aa7bf76cccf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/CopyPasteManagerEx.java @@ -0,0 +1,501 @@ +package com.intellij.ide; + +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.refactoring.copy.CopyHandler; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.move.MoveHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +public class CopyPasteManagerEx extends CopyPasteManager implements ClipboardOwner, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.CopyPasteManagerEx"); + + private ArrayList myDatas; + private MyData myRecentData; + +// private static long ourWastedMemory = 0; +// private static long ourLastPrintedMemory = 0; +// private static long ourLastPrintTime = 0; +// private static long ourInvokationCounter = 0; + + private ArrayList myListeners = new ArrayList(); + + public CopyPasteManagerEx() { + myDatas = new ArrayList(); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + myDatas = new ArrayList(); + clear(); + } + + public void projectOpened() { + myDatas = new ArrayList(); + } + + public PsiElement[] getElements(boolean[] isCopied) { + try { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + Transferable content = clipboard.getContents(this); + Object transferData; + try { + transferData = content.getTransferData(ourDataFlavor); + } catch (UnsupportedFlavorException e) { + return null; + } catch (IOException e) { + return null; + } + + if (!(transferData instanceof MyData)) { + return null; + } + MyData dataProxy = (MyData) transferData; + if (!Comparing.equal(dataProxy, myRecentData)) { + return null; + } + if (isCopied != null) { + isCopied[0] = myRecentData.isCopied(); + } + return myRecentData.getElements(); + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + return null; + } + } + +// private long getUsedMemory() { +// Runtime runtime = Runtime.getRuntime(); +// long usedMemory = runtime.totalMemory() - runtime.freeMemory(); +// return usedMemory; +// } +// + public void clear() { + myRecentData = null; + setTransferable(new StringSelection("")); + fireContentChanged(); + } + + private void setElements(PsiElement[] elements, boolean copied) { + myRecentData = new MyData(elements, copied); + setTransferable(new MyTransferable(myRecentData)); + fireContentChanged(); + } + + private void setTransferable(Transferable transferable) { + try { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(transferable, this); + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + } + } + + public boolean isCutElement(Object element) { + if (myRecentData == null) return false; + if (myRecentData.isCopied()) return false; + PsiElement[] elements = myRecentData.getElements(); + if (elements == null) return false; + for (int i = 0; i < elements.length; i++) { + if (elements[i] == element) return true; + } + return false; + } + + public abstract static class CopyPasteDelegator { + private Project myProject; + private JComponent myKeyReceiver; + private MyEditable myEditable; + + public CopyPasteDelegator(Project project, JComponent keyReceiver) { + myProject = project; + myKeyReceiver = keyReceiver; + myEditable = new MyEditable(); + } + + protected abstract PsiElement[] getSelectedElements(); + + protected final PsiElement[] getValidSelectedElements() { + PsiElement[] selectedElements = getSelectedElements(); + if (selectedElements == null){ + return null; + } + for (int i = 0; i < selectedElements.length; i++) { + PsiElement element = selectedElements[i]; + if (!element.isValid()) { + return null; + } + } + return selectedElements; + } + + private void updateView() { + myKeyReceiver.repaint(); + } + + public CopyProvider getCopyProvider() { + return myEditable; + } + + public CutProvider getCutProvider() { + return myEditable; + } + + public PasteProvider getPasteProvider() { + return myEditable; + } + + private class MyEditable implements CutProvider, CopyProvider, PasteProvider { + public void performCopy(DataContext dataContext) { + PsiElement[] elements = getValidSelectedElements(); + if (elements == null) { + return; + } + ((CopyPasteManagerEx)CopyPasteManager.getInstance()).setElements(elements, true); + updateView(); + } + + public boolean isCopyEnabled(DataContext dataContext) { + PsiElement[] elements = getValidSelectedElements(); + if (elements == null) { + return false; + } + return CopyHandler.canCopy(elements); + } + + public void performCut(DataContext dataContext) { + PsiElement[] elements = getValidSelectedElements(); + if (elements == null) { + return; + } + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, element); + return; + } + } + ((CopyPasteManagerEx)CopyPasteManager.getInstance()).setElements(elements, false); + updateView(); + } + + public boolean isCutEnabled(DataContext dataContext) { + final PsiElement[] elements = getValidSelectedElements(); + if (elements == null || elements.length == 0) { + return false; + } + return MoveHandler.canMove(elements, null); + } + + public void performPaste(DataContext dataContext) { + final boolean[] isCopied = new boolean[1]; + final PsiElement[] elements = ((CopyPasteManagerEx)CopyPasteManager.getInstance()).getElements(isCopied); + if (elements == null) return; + try { + PsiElement target = (PsiElement)dataContext.getData(DataConstantsEx.PASTE_TARGET_PSI_ELEMENT); + if (isCopied[0]) { + PsiDirectory targetDirectory = target instanceof PsiDirectory ? (PsiDirectory)target : null; + if (CopyHandler.canCopy(elements)) { + CopyHandler.doCopy(elements, targetDirectory); + } + } + else { + if (MoveHandler.canMove(elements, target)) { + MoveHandler.doMove(myProject, elements, target, new MoveCallback() { + public void refactoringCompleted() { + ((CopyPasteManagerEx)CopyPasteManager.getInstance()).clear(); + } + }); + } + } + } + catch (RuntimeException ex) { + throw ex; + } + finally { + updateView(); + } + } + + public boolean isPastePossible(DataContext dataContext) { + return true; + } + + public boolean isPasteEnabled(DataContext dataContext){ + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return false; + } + + Object target = dataContext.getData(DataConstantsEx.PASTE_TARGET_PSI_ELEMENT); + if (target == null) { + return false; + } + PsiElement[] elements = ((CopyPasteManagerEx)CopyPasteManager.getInstance()).getElements(null); + if (elements == null) { + return false; + } + + // disable cross-project paste + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + PsiManager manager = element.getManager(); + if (manager == null || manager.getProject() != project) { + return false; + } + } + + return true; + } + } + } + + private static final DataFlavor ourDataFlavor; + static { + try { + ourDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + MyData.class.getName()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + private static class MyData { + private PsiElement[] myElements; + private boolean myIsCopied; + + public MyData(PsiElement[] elements, boolean copied) { + myElements = elements; + myIsCopied = copied; + } + + public PsiElement[] getElements() { + if (myElements == null) return null; + + int validElementsCount = 0; + + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + if (element.isValid()) { + validElementsCount++; + } + } + + if (validElementsCount == myElements.length) { + return myElements; + } + + PsiElement[] validElements = new PsiElement[validElementsCount]; + int j=0; + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + if (element.isValid()) { + validElements[j++] = element; + } + } + + myElements = validElements; + return myElements; + } + + public boolean isCopied() { + return myIsCopied; + } + } + + public static class MyTransferable implements Transferable { + private MyData myDataProxy; + private static final DataFlavor[] DATA_FLAVOR_ARRAY = new DataFlavor[]{ourDataFlavor}; + + public MyTransferable(MyData data) { + myDataProxy = data; + } + + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (!ourDataFlavor.equals(flavor)) { + return null; + } + return myDataProxy; + } + + public DataFlavor[] getTransferDataFlavors() { + return DATA_FLAVOR_ARRAY; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(ourDataFlavor); + } + + } + + public void lostOwnership(Clipboard clipboard, Transferable contents) { + fireContentChanged(); + } + + private void fireContentChanged() { + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + ContentChangedListener listener = (ContentChangedListener)iterator.next(); + listener.contentChanged(); + } + } + + public void addContentChangedListener(ContentChangedListener listener) { + myListeners.add(listener); + } + + public void removeContentChangedListener(ContentChangedListener listener) { + myListeners.remove(listener); + } + + public String getComponentName() { + return "CopyPasteManager"; + } + + public void setContents(Transferable content) { + addNewContentToStack(content); + + setSystemClipboardContent(content); + + fireContentChanged(); + } + + private void setSystemClipboardContent(Transferable content) { + for (int i = 0; i < 3; i++) { + try { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(content, this); + } catch (IllegalStateException e) { + try { + Thread.sleep(50); + } catch (InterruptedException e1) { + } + continue; + } + break; + } + } + + private void addNewContentToStack(Transferable content) { + try { + String clipString = getStringContent(content); + if (clipString != null) { + Transferable same = null; + for (int i = 0; i < myDatas.size(); i++) { + Transferable old = myDatas.get(i); + if (clipString.equals(getStringContent(old))) { + same = old; + break; + } + } + + if (same == null) { + myDatas.add(0, content); + deleteAfterAllowedMaximum(); + } + else { + moveContentTopStackTop(same); + } + } + } catch (UnsupportedFlavorException e) { + } catch (IOException e) { + } + } + + private String getStringContent(Transferable content) throws UnsupportedFlavorException, IOException { + return (String) content.getTransferData(DataFlavor.stringFlavor); + } + + private void deleteAfterAllowedMaximum() { + int max = UISettings.getInstance().MAX_CLIPBOARD_CONTENTS; + for (int i = myDatas.size() - 1; i >= max; i--) { + myDatas.remove(i); + } + } + + public Transferable getContents() { + Transferable contents = null; + + for (int i = 0; i < 3; i++) { + try { + contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + } catch (IllegalStateException e) { + try { + Thread.sleep(50); + } catch (InterruptedException e1) { + } + continue; + } + break; + } + + return contents; + } + + public Transferable[] getAllContents() { + deleteAfterAllowedMaximum(); + + Transferable content = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + if (content != null) { + try { + String clipString = getStringContent(content); + String datasString = null; + + if (myDatas.size() > 0) { + datasString = getStringContent(myDatas.get(0)); + } + + if (clipString != null && clipString.length() > 0 && !Comparing.equal(clipString, datasString)) { + myDatas.add(0, content); + } + } catch (UnsupportedFlavorException e) { + } catch (IOException e) { + } + } + + return myDatas.toArray(new Transferable[myDatas.size()]); + } + + public void removeContent(Transferable t) { + boolean isCurrentClipboardContent = myDatas.indexOf(t) == 0; + myDatas.remove(t); + if (isCurrentClipboardContent) { + if (myDatas.size() > 0) { + setSystemClipboardContent(myDatas.get(0)); + } + else { + setSystemClipboardContent(new StringSelection("")); + } + } + fireContentChanged(); + } + + public void moveContentTopStackTop(Transferable t) { + setSystemClipboardContent(t); + myDatas.remove(t); + myDatas.add(0, t); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/GeneralSettingsConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/GeneralSettingsConfigurable.java new file mode 100644 index 00000000000..9210fb5643f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/GeneralSettingsConfigurable.java @@ -0,0 +1,275 @@ +package com.intellij.ide; + +import com.intellij.ide.updates.UpdateSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diff.impl.external.DiffOptionsForm; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.SortedMap; +import java.util.Vector; + +public class GeneralSettingsConfigurable extends BaseConfigurable implements ApplicationComponent { + private DiffOptionsForm myDiffOptions; + private MyComponent myComponent; + + public static GeneralSettingsConfigurable getInstance() { + return ApplicationManager.getApplication().getComponent(GeneralSettingsConfigurable.class); + } + + public void initComponent() { } + + public void disposeComponent() { } + + public void apply() { + GeneralSettings settings = GeneralSettings.getInstance(); + + settings.setBrowserPath(myComponent.myBrowserPathField.getText()); + settings.setReopenLastProject(myComponent.myChkReopenLastProject.isSelected()); + settings.setSyncOnFrameActivation(myComponent.myChkSyncOnFrameActivation.isSelected()); + settings.setSaveOnFrameDeactivation(myComponent.myChkSaveOnFrameDeactivation.isSelected()); + settings.setUseUTFGuessing(myComponent.myChkUTFGuessing.isSelected()); + settings.setUseDefaultBrowser(myComponent.myUseSystemDefaultBrowser.isSelected()); + + // AutoSave in inactive + + settings.setAutoSaveIfInactive(myComponent.myChkAutoSaveIfInactive.isSelected()); + try { + int newInactiveTimeout = Integer.parseInt(myComponent.myTfInactiveTimeout.getText()); + if (newInactiveTimeout > 0) { + settings.setInactiveTimeout(newInactiveTimeout); + } + } + catch (NumberFormatException e) { + } + + // + + settings.setCharsetName((String)myComponent.myCharsetNameCombo.getSelectedItem()); + if (!FileTypeManagerEx.getInstanceEx().isIgnoredFilesListEqualToCurrent(myComponent.myIgnoreFilesField.getText())) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + FileTypeManagerEx.getInstanceEx().setIgnoredFilesList(myComponent.myIgnoreFilesField.getText()); + } + }); + } + getDiffOptions().apply(); + UpdateSettings updateSettings = UpdateSettings.getInstance(); + + if (myComponent.myRbCheckAutomatically.isSelected()) { + updateSettings.CHECK_UPDATES = true; + updateSettings.ASK_USER = false; + } + else if (myComponent.myRbAskBeforeCheck.isSelected()) { + updateSettings.CHECK_UPDATES = true; + updateSettings.ASK_USER = true; + } + else { + updateSettings.CHECK_UPDATES = false; + updateSettings.ASK_USER = false; + } + } + + public boolean isModified() { + boolean isModified = false; + GeneralSettings settings = GeneralSettings.getInstance(); + isModified |= !compareStrings(settings.getBrowserPath(), myComponent.myBrowserPathField.getText()); + isModified |= settings.isReopenLastProject() != myComponent.myChkReopenLastProject.isSelected(); + isModified |= settings.isSyncOnFrameActivation() != myComponent.myChkSyncOnFrameActivation.isSelected(); + isModified |= settings.isSaveOnFrameDeactivation() != myComponent.myChkSaveOnFrameDeactivation.isSelected(); + isModified |= settings.isAutoSaveIfInactive() != myComponent.myChkAutoSaveIfInactive.isSelected(); + isModified |= settings.isUseUTFGuessing() != myComponent.myChkUTFGuessing.isSelected(); + isModified |= settings.isUseDefaultBrowser() != myComponent.myUseSystemDefaultBrowser.isSelected(); + + int inactiveTimeout = -1; + try { + inactiveTimeout = Integer.parseInt(myComponent.myTfInactiveTimeout.getText()); + } + catch (NumberFormatException e) { + } + isModified |= inactiveTimeout > 0 && settings.getInactiveTimeout() != inactiveTimeout; + + isModified |= !compareStrings(settings.getCharsetName(), (String)myComponent.myCharsetNameCombo.getSelectedItem()); + isModified |= !FileTypeManagerEx.getInstanceEx().isIgnoredFilesListEqualToCurrent(myComponent.myIgnoreFilesField.getText()); + UpdateSettings updateSettings = UpdateSettings.getInstance(); + isModified |= updateSettings.CHECK_UPDATES == myComponent.myRbNeverCheck.isSelected(); + isModified |= updateSettings.ASK_USER != myComponent.myRbAskBeforeCheck.isSelected(); + + return isModified || getDiffOptions().isModified(); + } + + private static boolean compareStrings(String string1, String string2) { + if (string1 == null) { + string1 = ""; + } + if (string2 == null) { + string2 = ""; + } + return string1.equals(string2); + } +//---------------------------------------------- + public JComponent createComponent() { + +// optionGroup.add(getDiffOptions().getPanel()); + myComponent = new MyComponent(); + myComponent.myDiffOptionsPanel.setLayout(new BorderLayout()); + myComponent.myDiffOptionsPanel.add(getDiffOptions().createComponent(), BorderLayout.CENTER); + + // AutoSave if inactive + + myComponent.myChkAutoSaveIfInactive.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + myComponent.myTfInactiveTimeout.setEditable(myComponent.myChkAutoSaveIfInactive.isSelected()); + } + }); + + + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); + myComponent.myBrowserPathField.addBrowseFolderListener("Select Path to Browser", null, null, descriptor); + + myComponent.myIgnoreFilesField.setText("skdjf arfgvkbdfugbvr"); + Vector charsets = new Vector(); + charsets.add("System Default"); + SortedMap avaliableCharsets = Charset.availableCharsets(); + for (Iterator iterator = avaliableCharsets.keySet().iterator(); iterator.hasNext();) { + String name = (String)iterator.next(); + if (!name.startsWith("UTF-16")) { + charsets.add(name); + } + } + + myComponent.myCharsetNameCombo.setModel(new DefaultComboBoxModel(charsets)); + + return myComponent.myPanel; + } +//-------------------------------------------------------- + public String getDisplayName() { + return "General"; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableGeneral.png"); + } + + public void reset() { + GeneralSettings settings = GeneralSettings.getInstance(); + myComponent.myBrowserPathField.setText(settings.getBrowserPath()); + myComponent.myChkReopenLastProject.setSelected(settings.isReopenLastProject()); + myComponent.myChkSyncOnFrameActivation.setSelected(settings.isSyncOnFrameActivation()); + myComponent.myChkSaveOnFrameDeactivation.setSelected(settings.isSaveOnFrameDeactivation()); + + myComponent.myChkAutoSaveIfInactive.setSelected(settings.isAutoSaveIfInactive()); + myComponent.myTfInactiveTimeout.setText(Integer.toString(settings.getInactiveTimeout())); + myComponent.myTfInactiveTimeout.setEditable(settings.isAutoSaveIfInactive()); + + myComponent.myIgnoreFilesField.setText(FileTypeManagerEx.getInstanceEx().getIgnoredFilesList()); + myComponent.myCharsetNameCombo.setSelectedItem(settings.getCharsetName()); + myComponent.myChkUTFGuessing.setSelected(settings.isUseUTFGuessing()); + getDiffOptions().reset(); + UpdateSettings updateSettings = UpdateSettings.getInstance(); + if (updateSettings.CHECK_UPDATES) { + if (updateSettings.ASK_USER) { + myComponent.myRbAskBeforeCheck.setSelected(true); + } + else { + myComponent.myRbCheckAutomatically.setSelected(true); + } + } + else { + myComponent.myRbNeverCheck.setSelected(true); + } + + if (settings.isUseDefaultBrowser()) { + myComponent.myUseSystemDefaultBrowser.setSelected(true); + } + else { + myComponent.myUseUserDefinedBrowser.setSelected(true); + } + myComponent.updateBrowserField(); + } + + public void disposeUIResources() { + myComponent = null; + } + + public String getHelpTopic() { + return "preferences.general"; + } + + public String getComponentName() { + return "GeneralSettingsConfigurable"; + } + + private static class MyComponent { + JPanel myPanel; + private TextFieldWithBrowseButton myBrowserPathField; + private JTextField myIgnoreFilesField; + private JCheckBox myChkReopenLastProject; + private JCheckBox myChkSyncOnFrameActivation; + private JCheckBox myChkSaveOnFrameDeactivation; + private JCheckBox myChkAutoSaveIfInactive; + private JTextField myTfInactiveTimeout; + private JComboBox myCharsetNameCombo; + private JCheckBox myChkUTFGuessing; + private JPanel myDiffOptionsPanel; + private JRadioButton myRbAskBeforeCheck; + private JRadioButton myRbCheckAutomatically; + private JRadioButton myRbNeverCheck; + private JRadioButton myUseSystemDefaultBrowser; + private JRadioButton myUseUserDefinedBrowser; + + public MyComponent() { + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbAskBeforeCheck); + buttonGroup.add(myRbCheckAutomatically); + buttonGroup.add(myRbNeverCheck); + + ButtonGroup browserGroup = new ButtonGroup(); + browserGroup.add(myUseSystemDefaultBrowser); + browserGroup.add(myUseUserDefinedBrowser); + + if (BrowserUtil.canStartDefaultBrowser()) { + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateBrowserField(); + } + }; + myUseSystemDefaultBrowser.addActionListener(actionListener); + myUseUserDefinedBrowser.addActionListener(actionListener); + } + else { + myUseSystemDefaultBrowser.setVisible(false); + myUseUserDefinedBrowser.setVisible(false); + } + } + + private void updateBrowserField() { + if (!BrowserUtil.canStartDefaultBrowser()) { + return; + } + myBrowserPathField.getTextField().setEnabled(myUseUserDefinedBrowser.isSelected()); + myBrowserPathField.getButton().setEnabled(myUseUserDefinedBrowser.isSelected()); + } + + } + + + private DiffOptionsForm getDiffOptions() { + if (myDiffOptions == null) myDiffOptions = new DiffOptionsForm(); + return myDiffOptions; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IconUtilEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IconUtilEx.java new file mode 100644 index 00000000000..7c90397186a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IconUtilEx.java @@ -0,0 +1,126 @@ +package com.intellij.ide; + +import com.intellij.j2ee.j2eeDom.ejb.CmpField; +import com.intellij.j2ee.j2eeDom.ejb.CmrField; +import com.intellij.j2ee.j2eeDom.ejb.Ejb; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiModifierList; +import com.intellij.psi.util.PsiUtil; +import com.intellij.ui.RowIcon; +import com.intellij.util.IconUtil; +import com.intellij.util.Icons; + +import javax.swing.*; + +public class IconUtilEx { + public static Icon getEmptyIcon(boolean showVisibility) { + RowIcon baseIcon = new RowIcon(2); + EmptyIcon emptyIcon = Icons.CLASS_ICON != null + ? EmptyIcon.create(Icons.CLASS_ICON.getIconWidth(), Icons.CLASS_ICON.getIconHeight()) + : null; + baseIcon.setIcon(emptyIcon, 0); + if (showVisibility) { + emptyIcon = Icons.PUBLIC_ICON != null ? EmptyIcon.create(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight()) : null; + baseIcon.setIcon(emptyIcon, 1); + } + return baseIcon; + } + + public static Icon getIcon(Object object, int flags, Project project) { + if (object instanceof PsiElement) { + PsiElement element = (PsiElement)object; + return element.getIcon(flags); + } + else if (object instanceof VirtualFile) { + VirtualFile file = (VirtualFile)object; + return IconUtil.getIcon(file, flags, project); + } + else if (object instanceof Module) { + return getIcon((Module)object, flags); + } + else if (object instanceof Ejb) { + return Icons.EJB_ICON; + } + else if (object instanceof CmpField) { + return Icons.EJB_CMP_FIELD_ICON; + } + else if (object instanceof CmrField) { + return Icons.EJB_CMR_FIELD_ICON; + } + else { + throw new IllegalArgumentException("Wrong object type"); + } + } + + public static void setVisibilityIcon(PsiModifierList modifierList, RowIcon baseIcon) { + if (modifierList != null) { + if (modifierList.hasModifierProperty(PsiModifier.PUBLIC)) { + setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PUBLIC, baseIcon); + } + else if (modifierList.hasModifierProperty(PsiModifier.PRIVATE)) { + setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PRIVATE, baseIcon); + } + else if (modifierList.hasModifierProperty(PsiModifier.PROTECTED)) { + setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PROTECTED, baseIcon); + } + else if (modifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { + setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL, baseIcon); + } + else { + Icon emptyIcon = EmptyIcon.create(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight()); + baseIcon.setIcon(emptyIcon, 1); + } + } + else { + if (Icons.PUBLIC_ICON != null) { + Icon emptyIcon = EmptyIcon.create(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight()); + baseIcon.setIcon(emptyIcon, 1); + } + } + } + + public static void setVisibilityIcon(int accessLevel, RowIcon baseIcon) { + Icon icon; + switch (accessLevel) { + case PsiUtil.ACCESS_LEVEL_PUBLIC: + icon = Icons.PUBLIC_ICON; + break; + case PsiUtil.ACCESS_LEVEL_PROTECTED: + icon = Icons.PROTECTED_ICON; + break; + case PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL: + icon = Icons.PACKAGE_LOCAL_ICON; + break; + case PsiUtil.ACCESS_LEVEL_PRIVATE: + icon = Icons.PRIVATE_ICON; + break; + default: + { + if (Icons.PUBLIC_ICON != null) { + icon = EmptyIcon.create(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight()); + } + else { + return; + } + } + } + baseIcon.setIcon(icon, 1); + } + + public static Icon getIcon(Module module, int flags) { + return getModuleTypeIcon(module.getModuleType(), flags); + } + + public static Icon getModuleTypeIcon(final ModuleType moduleType, int flags) { + return moduleType.getNodeIcon((flags & Iconable.ICON_FLAG_OPEN) != 0); + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeEventQueue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeEventQueue.java new file mode 100644 index 00000000000..a391d86cc82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeEventQueue.java @@ -0,0 +1,396 @@ +package com.intellij.ide; + +import com.intellij.Patches; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher; +import com.intellij.openapi.keymap.impl.IdeMouseEventDispatcher; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.util.Alarm; +import com.intellij.util.containers.HashMap; + +import java.awt.*; +import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Field; +import java.util.ArrayList; + +/** + * @author Vladimir Kondratyev + * @author Anton Katilin + */ +public class IdeEventQueue extends EventQueue { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.IdeEventQueue"); + + private static IdeEventQueue ourInstance; + + /** Adding/Removing of "idle" listeners should be thread safe. */ + private final Object myLock; + +// Overriden in Fabrique + protected final ArrayList myIdleListeners; + protected final ArrayList myActivityListeners; + private final Alarm myIdleRequestsAlarm; + private final Alarm myIdleTimeCounterAlarm; + private long myIdleTime; + private final HashMap myListener2Request; // IdleListener -> MyFireIdleRequest + private final HashMap myListener2Timeout; // IdleListener -> java.lang.Integer + + + private final IdeKeyEventDispatcher myKeyEventDispatcher; + private final IdeMouseEventDispatcher myMouseEventDispatcher; + private final IdePopupManager myPopupManager; + + private EventDispatcher myDispatcher; + private EventDispatcher myDefaultEventDispatcher; + + private boolean mySuspendMode; + /** + * We exit from suspend mode when focus owner changes and no more WindowEvent.WINDOW_OPENED events + * in the queue. If WINDOW_OPENED event does exists in the queus then we restart the alarm. + */ + private Component myFocusOwner; + private final Runnable myExitSuspendModeRunnable; + /** + * We exit from suspend mode when this alarm is triggered and no mode WindowEvent.WINDOW_OPENED + * events in the queue. If WINDOW_OPENED event does exist then we restart the alarm. + */ + private final Alarm mySuspendModeAlarm; + /** + * Counter of processed events. It is used to assert that data context lives only inside single + * Swing event. + */ + private int myEventCount; + + private boolean myIsInInputEvent = false; + private AWTEvent myCurrentEvent = null; + private long myLastActiveTime; + + public static IdeEventQueue getInstance() { + if (ourInstance == null) { + ourInstance = new IdeEventQueue(); + } + return ourInstance; + } + + public static void setInstance(IdeEventQueue instance) { + ourInstance = instance; + } + + protected IdeEventQueue() { + myLock = new Object(); + myIdleListeners = new ArrayList(2); + myActivityListeners = new ArrayList(2); + myIdleRequestsAlarm = new Alarm(); + myIdleTimeCounterAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + addIdleTimeCounterRequest(); + myListener2Request = new HashMap(); + myListener2Timeout = new HashMap(); + myKeyEventDispatcher = new IdeKeyEventDispatcher(); + myMouseEventDispatcher = new IdeMouseEventDispatcher(); + myPopupManager = new IdePopupManager(); + myExitSuspendModeRunnable = new ExitSuspendModeRunnable(); + mySuspendModeAlarm = new Alarm(); + + final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + keyboardFocusManager.addPropertyChangeListener( + "permanentFocusOwner", + new PropertyChangeListener() { + public void propertyChange(final PropertyChangeEvent e) { + final Application application = ApplicationManager.getApplication(); + if(application == null){ + // We can get focus event before application is initialized + return; + } + application.assertIsDispatchThread(); + final Window focusedWindow = keyboardFocusManager.getFocusedWindow(); + final Component focusOwner = keyboardFocusManager.getFocusOwner(); + if ( + mySuspendMode && + focusedWindow != null && + focusOwner != null && + focusOwner != myFocusOwner && + !(focusOwner instanceof Window) + ) { + exitSuspendMode(); + } + } + } + ); + } + + private void addIdleTimeCounterRequest() { + myIdleTimeCounterAlarm.cancelAllRequests(); + myLastActiveTime = System.currentTimeMillis(); + myIdleTimeCounterAlarm.addRequest(new Runnable() { + public void run() { + myIdleTime += (System.currentTimeMillis() - myLastActiveTime); + addIdleTimeCounterRequest(); + } + }, 20000, ModalityState.NON_MMODAL); + } + + public boolean isWaitingForSecondKeyStroke() { + return myKeyEventDispatcher.isWaitingForSecondKeyStroke(); + } + + private void enterSuspendMode() { + mySuspendMode = true; + myFocusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + mySuspendModeAlarm.cancelAllRequests(); + mySuspendModeAlarm.addRequest(myExitSuspendModeRunnable, 750); + } + + /** + * Exits supend mode and pumps all suspended events. + */ + private void exitSuspendMode() { + if (peekEvent(WindowEvent.WINDOW_OPENED) != null) { + // We have to exit from suspend mode (focus owner changes or alarm is triggered) but + // WINDOW_OPENED isn't dispatched yet. In this case we have to restart the alarm until + // all WINDOW_OPENED event will be processed. + mySuspendModeAlarm.cancelAllRequests(); + mySuspendModeAlarm.addRequest(myExitSuspendModeRunnable, 250); + } + else { + // Now we can pump all suspended events. + mySuspendMode = false; + myFocusOwner = null; // to prevent memory leaks + } + } + + public void addIdleListener(final Runnable runnable, final int timeout) { + LOG.assertTrue(runnable != null); + LOG.assertTrue(timeout > 0); + synchronized (myLock) { + myIdleListeners.add(runnable); + final MyFireIdleRequest request = new MyFireIdleRequest(runnable); + myListener2Request.put(runnable, request); + myListener2Timeout.put(runnable, new Integer(timeout)); + myIdleRequestsAlarm.addRequest(request, timeout); + } + } + + public void removeIdleListener(final Runnable runnable) { + LOG.assertTrue(runnable != null); + synchronized (myLock) { + final boolean wasRemoved = myIdleListeners.remove(runnable); + LOG.assertTrue(wasRemoved, "unknown runnable: " + runnable); + + final MyFireIdleRequest request = (MyFireIdleRequest)myListener2Request.remove(runnable); + LOG.assertTrue(request != null); + myIdleRequestsAlarm.cancelRequest(request); + + final Integer timeout = (Integer)myListener2Timeout.remove(runnable); + LOG.assertTrue(timeout != null); + } + } + + public void addActivityListener(final Runnable runnable) { + LOG.assertTrue(runnable != null); + synchronized (myLock) { + myActivityListeners.add(runnable); + } + } + + public void removeActivityListener(final Runnable runnable) { + LOG.assertTrue(runnable != null); + synchronized (myLock) { + final boolean wasRemoved = myActivityListeners.remove(runnable); + LOG.assertTrue(wasRemoved, "unknown runnable: " + runnable); + } + } + + public void setDispatcher(final EventDispatcher dispatcher) { + myDispatcher = dispatcher; + } + + public void setDefaultEventDispatcher(final EventDispatcher dispatcher) { + myDefaultEventDispatcher = dispatcher; + } + + public int getEventCount() { + return myEventCount; + } + + public boolean isInInputEvent(){ + return myIsInInputEvent; + } + + public AWTEvent getTrueCurrentEvent() { + return myCurrentEvent; + } + + public void postEvent(final AWTEvent e) { + // [vova] sometime people call SwingUtilities.invokeLater(null). To + // find such situations we will specially check InvokationEvents + try { + if (e instanceof InvocationEvent) { + final Field field = InvocationEvent.class.getDeclaredField("runnable"); + field.setAccessible(true); + final Object runnable = field.get(e); + if (runnable == null) { + throw new IllegalStateException("InvocationEvent contains null runnable: " + e); + } + } + } + catch (final Exception exc) { + throw new Error(exc); + } + super.postEvent(e); + } + + public void dispatchEvent(final AWTEvent e) { + boolean wasInputEvent = myIsInInputEvent; + myIsInInputEvent = (e instanceof InputEvent) || (e instanceof InputMethodEvent) || (e instanceof WindowEvent) || (e instanceof ActionEvent); + AWTEvent oldEvent = myCurrentEvent; + myCurrentEvent = e; + + try{ + _dispatchEvent(e); + } + finally{ + myIsInInputEvent = wasInputEvent; + myCurrentEvent = oldEvent; + } + } + + private void _dispatchEvent(final AWTEvent e) { + + myEventCount++; + + if (!myPopupManager.isPopupActive()) { + // Suspend keyboard events (if any) + if (e instanceof KeyEvent) { + if (mySuspendMode) { + return; + } + else { + if (peekEvent(WindowEvent.WINDOW_OPENED) != null) { + enterSuspendMode(); + return; + } + } + } + } + + // Process "idle" and "activity" listeners + + if ((e instanceof KeyEvent) || (e instanceof MouseEvent)) { + synchronized (myLock) { + myIdleRequestsAlarm.cancelAllRequests(); + for (int i = 0; i < myIdleListeners.size(); i++) { + final Runnable runnable = (Runnable)myIdleListeners.get(i); + final MyFireIdleRequest request = (MyFireIdleRequest)myListener2Request.get(runnable); + LOG.assertTrue(request != null, "There is no request for " + runnable); + final Integer timeout = (Integer)myListener2Timeout.get(runnable); + LOG.assertTrue(timeout != null); + myIdleRequestsAlarm.addRequest(request, timeout.intValue(), ModalityState.NON_MMODAL); + } + + if ( + KeyEvent.KEY_PRESSED == e.getID() || + KeyEvent.KEY_TYPED == e.getID() || + MouseEvent.MOUSE_PRESSED == e.getID() || + MouseEvent.MOUSE_RELEASED == e.getID() || + MouseEvent.MOUSE_CLICKED == e.getID() + ) { + addIdleTimeCounterRequest(); + for (int i = 0; i < myActivityListeners.size(); i++) { + final Runnable runnable = (Runnable)myActivityListeners.get(i); + runnable.run(); + } + } + } + } + + if (myPopupManager.isPopupActive() && myPopupManager.dispatch(e)) { + return; + } + + if (myDispatcher != null && myDispatcher.dispatch(e)) { + return; + } + + if ((e instanceof InputEvent) && Patches.SPECIAL_WINPUT_METHOD_PROCESSING) { + final InputEvent inputEvent = (InputEvent)e; + if (!inputEvent.getComponent().isShowing()) { + return; + } + } + + if (e instanceof ComponentEvent) { + WindowManagerEx.getInstanceEx().dispatchComponentEvent((ComponentEvent)e); + } + + if (e instanceof KeyEvent) { + if (!myKeyEventDispatcher.dispatchKeyEvent((KeyEvent)e)) { + defaultDispatchEvent(e); + } + else { + ((KeyEvent)e).consume(); + defaultDispatchEvent(e); + } + } + else if (e instanceof MouseEvent) { + if (!myMouseEventDispatcher.dispatchMouseEvent((MouseEvent)e)) { + defaultDispatchEvent(e); + } + } + else { + defaultDispatchEvent(e); + } + } + + protected void defaultDispatchEvent(final AWTEvent e) { + try { + if (myDefaultEventDispatcher != null && myDefaultEventDispatcher.dispatch(e)) { + return; + } + super.dispatchEvent(e); + } + catch (Throwable exc) { + LOG.error("Error during dispatching of " + e, exc); + } + } + + public interface EventDispatcher { + boolean dispatch(AWTEvent e); + } + + private final class MyFireIdleRequest implements Runnable { + private final Runnable myRunnable; + + public MyFireIdleRequest(final Runnable runnable) { + myRunnable = runnable; + } + + public void run() { + myRunnable.run(); + synchronized (myLock) { + final Integer timeout = (Integer)myListener2Timeout.get(myRunnable); + LOG.assertTrue(timeout != null); + myIdleRequestsAlarm.addRequest(this, timeout.intValue(), ModalityState.NON_MMODAL); + } + } + } + + private final class ExitSuspendModeRunnable implements Runnable { + public void run() { + if (mySuspendMode) { + exitSuspendMode(); + } + } + } + + public long getIdleTime() { + return myIdleTime; + } + + public IdePopupManager getPopupManager() { + return myPopupManager; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopup.java new file mode 100644 index 00000000000..4451c1c9134 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopup.java @@ -0,0 +1,10 @@ +package com.intellij.ide; + +import java.awt.*; + +public interface IdePopup { + + Component getComponent(); + boolean dispatch(AWTEvent event); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopupManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopupManager.java new file mode 100644 index 00000000000..c1891ced13a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdePopupManager.java @@ -0,0 +1,42 @@ +package com.intellij.ide; + +import com.intellij.openapi.diagnostic.Logger; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +public final class IdePopupManager implements IdeEventQueue.EventDispatcher { + private static final Logger LOG = Logger.getInstance("com.intellij.ide.IdePopupManager"); + + private IdePopup myActivePopup; + + boolean isPopupActive() { + if (myActivePopup != null) { + if (!myActivePopup.getComponent().isShowing()) { + myActivePopup = null; + LOG.error("Popup is set up as active but not showing"); + } + } + return myActivePopup != null; + } + + public boolean dispatch(AWTEvent e) { + LOG.assertTrue(isPopupActive()); + + if ((e instanceof KeyEvent) || (e instanceof MouseEvent) || (e instanceof MouseWheelEvent)) { + return myActivePopup.dispatch(e); + } + + return false; + } + + public void setActivePopup(IdePopup popup) { + myActivePopup = popup; + } + + public void resetActivePopup() { + myActivePopup = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeView.java new file mode 100644 index 00000000000..b73852f04ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/IdeView.java @@ -0,0 +1,9 @@ +package com.intellij.ide; + +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; + +public interface IdeView { + void selectElement(PsiElement element); + PsiDirectory[] getDirectories(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/MacOSApplicationProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/MacOSApplicationProvider.java new file mode 100644 index 00000000000..94e3052657d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/MacOSApplicationProvider.java @@ -0,0 +1,100 @@ +package com.intellij.ide; + +import com.apple.eawt.Application; +import com.apple.eawt.ApplicationAdapter; +import com.apple.eawt.ApplicationEvent; +import com.intellij.ide.actions.AboutAction; +import com.intellij.ide.actions.OpenFileAction; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.options.ex.IdeConfigurablesGroup; +import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.SystemInfo; + +import java.io.File; + +/** + * @author max + */ +public class MacOSApplicationProvider implements ApplicationComponent { + public String getComponentName() { + return "MACOSApplicationProvider"; + } + + public MacOSApplicationProvider() { + if (SystemInfo.isMac) { + try { + Worker.initMacApplication(); + } + catch (NoClassDefFoundError e) { + } + } + } + + public void initComponent() { } + + public void disposeComponent() { + } + + private static class Worker { + public static void initMacApplication() { + Application application = new Application(); + application.addApplicationListener(new ApplicationAdapter() { + public void handleAbout(ApplicationEvent applicationEvent) { + AboutAction.showAbout(); + applicationEvent.setHandled(true); + } + + public void handlePreferences(ApplicationEvent applicationEvent) { + Project project = getProject(); + + if (project == null) { + project = ProjectManager.getInstance().getDefaultProject(); + } + + ConfigurableGroup[] group = new ConfigurableGroup[]{ + new ProjectConfigurablesGroup(project), + new IdeConfigurablesGroup() + }; + + ShowSettingsUtil.getInstance().showSettingsDialog(getProject(), group); + applicationEvent.setHandled(true); + } + + public void handleQuit(ApplicationEvent applicationEvent) { + ApplicationManagerEx.getApplicationEx().exit(); + } + + public void handleOpenFile(ApplicationEvent applicationEvent) { + Project project = getProject(); + String filename = applicationEvent.getFilename(); + if (filename == null) return; + + File file = new File(filename); + if (OpenFileAction.isProjectFile(file)) { + ProjectUtil.openProject(file.getAbsolutePath(), null, false); + } + else if (project != null && file.exists()) { + OpenFileAction.openFile(filename, project); + applicationEvent.setHandled(true); + } + } + }); + + application.addAboutMenuItem(); + application.addPreferencesMenuItem(); + application.setEnabledAboutMenu(true); + application.setEnabledPreferencesMenu(true); + } + + private static Project getProject() { + return (Project)DataManager.getInstance().getDataContext().getData(DataConstants.PROJECT); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/PasteProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/PasteProvider.java new file mode 100644 index 00000000000..74676d4f00b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/PasteProvider.java @@ -0,0 +1,14 @@ +package com.intellij.ide; + +import com.intellij.openapi.actionSystem.DataContext; + +public interface PasteProvider { + void performPaste(DataContext dataContext); + + /** + * Should perform fast and memory cheap negation. May return incorrect true. + * See #12326 + */ + boolean isPastePossible(DataContext dataContext); + boolean isPasteEnabled(DataContext dataContext); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/RecentProjectsManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/RecentProjectsManager.java new file mode 100644 index 00000000000..5c7a6f1db6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/RecentProjectsManager.java @@ -0,0 +1,210 @@ +package com.intellij.ide; + +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Separator; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; + +public class RecentProjectsManager implements ApplicationComponent, JDOMExternalizable { + private ArrayList myRecentProjects = new ArrayList(); + private String myLastProjectPath; + private static final int MAX_RECENT_PROJECTS = 15; + + public RecentProjectsManager(ProjectManager projectManager) { + projectManager.addProjectManagerListener(new MyProjectManagerListener()); + } + + public static RecentProjectsManager getInstance() { + return ApplicationManager.getApplication().getComponent(RecentProjectsManager.class); + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void readExternal(Element element) throws InvalidDataException { + for (Iterator i=element.getChildren().iterator();i.hasNext();) { + Element e=(Element)i.next(); + if ("last_project".equals(e.getName())) { + myLastProjectPath = e.getAttributeValue("path"); + } + + if ("project".equals(e.getName())) { + String path = e.getAttributeValue("path"); + File file = new File(path); + if (file.exists()) { + myRecentProjects.add(path); + } + } + } + if (myLastProjectPath != null) { + File file = new File(myLastProjectPath); + if (!file.exists()) { + myLastProjectPath = null; + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + validateRecentProjects(); + if (myLastProjectPath != null) { + Element e = new Element("last_project"); + e.setAttribute("path", myLastProjectPath); + element.addContent(e); + } + for (int i = 0; i < myRecentProjects.size(); i++) { + String path = myRecentProjects.get(i); + Element e = new Element("project"); + e.setAttribute("path", path); + element.addContent(e); + } + } + + private void validateRecentProjects() { + for (Iterator i = myRecentProjects.iterator(); i.hasNext();) { + String s = (String)i.next(); + if (s == null || !(new File(s).exists())) { + i.remove(); + } + } + while (myRecentProjects.size() > MAX_RECENT_PROJECTS) { + myRecentProjects.remove(myRecentProjects.size() - 1); + } + } + + public String getLastProjectPath() { + return myLastProjectPath; + } + + public void updateLastProjectPath() { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length == 0) { + myLastProjectPath = null; + } else { + myLastProjectPath = getProjectPath(openProjects[openProjects.length - 1]); + } + } + + public String getComponentName() { + return "RecentProjectsManager"; + } + + private void removePath(String path) { + if (SystemInfo.isFileSystemCaseSensitive) { + myRecentProjects.remove(path); + } + else { + Iterator i = myRecentProjects.iterator(); + while (i.hasNext()) { + String p = i.next(); + if (path.equalsIgnoreCase(p)) { + i.remove(); + } + } + } + } + + public AnAction[] getRecentProjectsActions() { + validateRecentProjects(); + + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + + ArrayList actions = new ArrayList(); + outer: for (int i = 0; i < myRecentProjects.size(); i++) { + String projectPath = myRecentProjects.get(i).toString(); + + for (int j = 0; j < openProjects.length; j++) { + Project openProject = openProjects[j]; + if (projectPath.equals(getProjectPath(openProject))) { + continue outer; + } + } + + actions.add(new ReopenProjectAction(projectPath)); + } + + + if (actions.size() == 0) { + return new AnAction[0]; + } + + ArrayList list = new ArrayList(); + for (int i = 0; i < actions.size(); i++) { + AnAction action = actions.get(i); + list.add(action); + } + AnAction clearListAction = new AnAction("Clear List") { + public void actionPerformed(AnActionEvent e) { + myRecentProjects.clear(); + } + }; + list.add(Separator.getInstance()); + list.add(clearListAction); + return list.toArray(new AnAction[list.size()]); + } + + public String[] getRecentProjectPaths() { + validateRecentProjects(); + return myRecentProjects.toArray(new String[myRecentProjects.size()]); + } + + private class MyProjectManagerListener implements ProjectManagerListener{ + + public void projectOpened(Project project) { + String path = getProjectPath(project); + myLastProjectPath = path; + removePath(path); + myRecentProjects.add(0, path); + } + + public boolean canCloseProject(Project project) { + return true; + } + + public void projectClosing(Project project) { + } + + public void projectClosed(Project project) { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length > 0) { + String path = getProjectPath(openProjects[openProjects.length - 1]); + myLastProjectPath = path; + removePath(path); + myRecentProjects.add(0, path); + } + } + } + + private static String getProjectPath(Project project) { + return project.getProjectFilePath(); + } + + private class ReopenProjectAction extends AnAction { + private final String myProjectPath; + + public ReopenProjectAction(String projectPath) { + myProjectPath = projectPath; + getTemplatePresentation().setText(projectPath, false); + } + + public void actionPerformed(AnActionEvent e) { + ProjectUtil.openProject(myProjectPath, (Project)e.getDataContext().getData(DataConstants.PROJECT), false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SaveAndSyncHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SaveAndSyncHandler.java new file mode 100644 index 00000000000..1df05e428a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SaveAndSyncHandler.java @@ -0,0 +1,227 @@ +package com.intellij.ide; + +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.application.impl.LaterInvocatorEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.Alarm; + +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class SaveAndSyncHandler implements ApplicationComponent,PropertyChangeListener{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.SaveAndSyncHandler"); + + private boolean myShouldSynchronize; + private final Alarm mySyncAlarm; + private Runnable myIdleListener; + private PropertyChangeListener myGeneralSettingsListener; + private Set myActivationActions = new HashSet(); + private Set myDeactivationActions = new HashSet(); + + public static SaveAndSyncHandler getInstance() { + return ApplicationManager.getApplication().getComponent(SaveAndSyncHandler.class); + } + + public SaveAndSyncHandler(final FileDocumentManager fileDocumentManager, final GeneralSettings generalSettings){ + myShouldSynchronize = false; + mySyncAlarm = new Alarm(); + + KeyboardFocusManager focusManager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); + focusManager.addPropertyChangeListener("activeWindow",this); + focusManager.addPropertyChangeListener("focusedWindow",this); + focusManager.addPropertyChangeListener("focusOwner",this); + + myIdleListener=new Runnable(){ + public void run(){ + if (generalSettings.isAutoSaveIfInactive() && canSyncOrSave()) { + fileDocumentManager.saveAllDocuments(); + } + } + }; + + IdeEventQueue.getInstance().addIdleListener( + myIdleListener, + generalSettings.getInactiveTimeout()*1000 + ); + + myGeneralSettingsListener=new PropertyChangeListener(){ + public void propertyChange(PropertyChangeEvent e){ + if(GeneralSettings.PROP_INACTIVE_TIMEOUT.equals(e.getPropertyName())){ + IdeEventQueue eventQueue=IdeEventQueue.getInstance(); + eventQueue.removeIdleListener(myIdleListener); + Integer timeout=(Integer)e.getNewValue(); + eventQueue.addIdleListener(myIdleListener,timeout.intValue()*1000); + } + } + }; + generalSettings.addPropertyChangeListener(myGeneralSettingsListener); + + registerActivationAction(new Runnable() { + public void run() { + refreshFiles(); + } + }, true); + registerActivationAction(new Runnable() { + public void run() { + saveProjectsAndDocuments(); + } + }, false); + } + + public String getComponentName() { + return "SaveAndSyncHandler"; + } + + public void initComponent() { } + + public void disposeComponent() { + GeneralSettings.getInstance().removePropertyChangeListener(myGeneralSettingsListener); + IdeEventQueue.getInstance().removeIdleListener(myIdleListener); + } + + private boolean canSyncOrSave(){ + if (LaterInvocatorEx.isInModalContext()) return false; + if (ProgressManager.getInstance().hasModalProgressIndicator()) return false; + /* + if (ProjectManagerEx.getInstanceEx().isOpeningProject()) return false; + */ + return true; + } + + public void propertyChange(PropertyChangeEvent e) { + KeyboardFocusManager focusManager = (KeyboardFocusManager)e.getSource(); + Window activeWindow = focusManager.getActiveWindow(); + + if (activeWindow != null) { + mySyncAlarm.cancelAllRequests(); + if (myShouldSynchronize) { + myShouldSynchronize = false; + if (canSyncOrSave()) { + synchronizeOnActivation(); + } + } + return; + } + else{ + mySyncAlarm.cancelAllRequests(); + mySyncAlarm.addRequest( + new Runnable() { + public void run() { + myShouldSynchronize=true; + if (canSyncOrSave()) { + synchronizeOnDeactivation(); + } + } + }, + 200 + ); + } + } + + public synchronized void registerActivationAction(Runnable action, boolean onActivation) { + final HashSet newContainer = new HashSet(Math.max(myActivationActions.size(), myDeactivationActions.size())); + newContainer.add(action); + if (onActivation) { + newContainer.addAll(myActivationActions); + myActivationActions = newContainer; + } + else { + newContainer.addAll(myDeactivationActions); + myDeactivationActions = newContainer; + } + } + public synchronized void unregisterActivationAction(Runnable action, boolean onActivation) { + if (onActivation) { + final HashSet newContainer = new HashSet(myActivationActions); + newContainer.remove(action); + myActivationActions = newContainer; + } + else { + final HashSet newContainer = new HashSet(myDeactivationActions); + newContainer.remove(action); + myDeactivationActions = newContainer; + } + } + + private void synchronizeOnDeactivation(){ + for (Iterator iterator = myDeactivationActions.iterator(); iterator.hasNext();) { + Runnable action = (Runnable)iterator.next(); + action.run(); + } + } + + private void saveProjectsAndDocuments() { + if(LOG.isDebugEnabled()){ + LOG.debug("enter: save()"); + } + if(GeneralSettings.getInstance().isSaveOnFrameDeactivation()){ + FileDocumentManager.getInstance().saveAllDocuments(); + } + Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects(); + for (int i = 0; i < openProjects.length; i++) { + Project project = openProjects[i]; + if(LOG.isDebugEnabled()){ + LOG.debug("save project: "+project); + } + project.save(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("save application settings"); + } + ApplicationManagerEx.getApplicationEx().saveSettings(); + if(LOG.isDebugEnabled()){ + LOG.debug("exit: save()"); + } + } + + private void synchronizeOnActivation(){ + for (Iterator iterator = myActivationActions.iterator(); iterator.hasNext();) { + Runnable action = (Runnable)iterator.next(); + action.run(); + } + } + + private void refreshFiles() { + if(LOG.isDebugEnabled()){ + LOG.debug("enter: synchronize()"); + } + if (GeneralSettings.getInstance().isSyncOnFrameActivation()) { + if (LOG.isDebugEnabled()) { + LOG.debug("refresh VFS"); + } + VirtualFileManager.getInstance().refresh(true); + }else{ // referesh only opened files + Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects(); + for (int i = 0; i < openProjects.length; i++) { + Project project = openProjects[i]; + VirtualFile[] file=FileEditorManager.getInstance(project).getSelectedFiles(); + for (int j = 0; j < file.length; j++) { + if (LOG.isDebugEnabled()) { + LOG.debug("refresh file: "+file); + } + file[j].refresh(true, false); + } + } + } + if(LOG.isDebugEnabled()){ + LOG.debug("exit: synchronize()"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SwingCleanuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SwingCleanuper.java new file mode 100644 index 00000000000..78bb954046c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/SwingCleanuper.java @@ -0,0 +1,159 @@ +package com.intellij.ide; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.util.Alarm; + +import javax.swing.FocusManager; +import javax.swing.*; +import javax.swing.plaf.basic.BasicPopupMenuUI; +import javax.swing.text.JTextComponent; +import java.awt.*; +import java.awt.dnd.DragGestureRecognizer; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * This class listens event from ProjectManager and cleanup some + * internal Swing references. + * + * @author Vladimir Kondratyev + */ +public final class SwingCleanuper implements ApplicationComponent{ + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.SwingCleanuper"); + + private final Alarm myAlarm; + + /** Invoked by reflection + * @param projectManager */ + SwingCleanuper(ProjectManager projectManager){ + myAlarm=new Alarm(); + + projectManager.addProjectManagerListener( + new ProjectManagerAdapter(){ + public void projectOpened(final Project project) { + myAlarm.cancelAllRequests(); + } + // Swing keeps references to the last focused component inside DefaultKeyboardFocusManager.realOppositeComponent + // which is used to compose next focus event. Actually this component could be an editors or a tool window. To fix this + // memory leak we (if the project was closed and a new one was not opened yet) request focus to the status bar and after + // the focus events have passed the queue, we put 'null' to the DefaultKeyboardFocusManager.realOppositeComponent field. + public void projectClosed(final Project project){ + myAlarm.cancelAllRequests(); + myAlarm.addRequest( + new Runnable() { + public void run() { + // request focus into some focusable somponent inside IdeFrame + final IdeFrame frame; + final Window window=KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + if(window instanceof IdeFrame){ + frame=(IdeFrame)window; + }else{ + frame=(IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class,window); + } + if(frame!=null){ + ((JComponent)frame.getStatusBar()).requestFocus(); + } + + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + + // KeyboardFocusManager.newFocusOwner + try{ + final Field newFocusOwnerField = KeyboardFocusManager.class.getDeclaredField("newFocusOwner"); + newFocusOwnerField.setAccessible(true); + newFocusOwnerField.set(null, null); + } + catch(final Exception exc){ + LOG.error(exc); + } + + // Clear "realOppositeComponent", "realOppositeWindow" + + final KeyboardFocusManager focusManager = FocusManager.getCurrentKeyboardFocusManager(); + if (focusManager instanceof DefaultKeyboardFocusManager) { + try { + final Field realOppositeComponentField = DefaultKeyboardFocusManager.class.getDeclaredField("realOppositeComponent"); + realOppositeComponentField.setAccessible(true); + realOppositeComponentField.set(focusManager, null); + + final Field realOppositeWindowField = DefaultKeyboardFocusManager.class.getDeclaredField("realOppositeWindow"); + realOppositeWindowField.setAccessible(true); + realOppositeWindowField.set(focusManager, null); + } catch(Exception e){ + LOG.error(e); + } + } + + // Memory leak on static field in BasicPopupMenuUI + + try { + final Field menuKeyboardHelperField = BasicPopupMenuUI.class.getDeclaredField("menuKeyboardHelper"); + menuKeyboardHelperField.setAccessible(true); + final Object helperObject = menuKeyboardHelperField.get(null); + + if (null != helperObject) { + final Field lastFocusedField = helperObject.getClass().getDeclaredField("lastFocused"); + lastFocusedField.setAccessible(true); + lastFocusedField.set(helperObject, null); + } + } + catch (Exception e) { + LOG.error(e); + } + + // Memory leak on javax.swing.TransferHandler$SwingDragGestureRecognizer.component + + try{ + final Field recognizerField = TransferHandler.class.getDeclaredField("recognizer"); + recognizerField.setAccessible(true); + final Object recognizerObject = recognizerField.get(null); + if(recognizerObject!=null){ // that is memory leak + final Method setComponentMethod = DragGestureRecognizer.class.getDeclaredMethod( + "setComponent", + new Class[]{Component.class} + ); + setComponentMethod.invoke(recognizerObject,new Object[]{null}); + } + }catch (Exception e){ + LOG.error(e); + } + try { + fixJTextComponentMemoryLeak(); + } catch(Exception e) { + LOG.error(e); + } + } + } + ); + } + }, + 2500 + ); + } + } + ); + } + + public final void disposeComponent(){} + + public final String getComponentName(){ + return "SwingCleanuper"; + } + + public final void initComponent() { } + + private static void fixJTextComponentMemoryLeak() throws NoSuchFieldException, IllegalAccessException { + final Field focusedComponentField = JTextComponent.class.getDeclaredField("focusedComponent"); + focusedComponentField.setAccessible(true); + final JTextComponent component = (JTextComponent)focusedComponentField.get(null); + if (component != null && !component.isDisplayable()){ + focusedComponentField.set(null, null); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/TipOfTheDayManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/TipOfTheDayManager.java new file mode 100644 index 00000000000..f6c12a4d737 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/TipOfTheDayManager.java @@ -0,0 +1,64 @@ +package com.intellij.ide; + +import com.intellij.ide.util.TipDialog; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.startup.StartupManager; + +public class TipOfTheDayManager implements ApplicationComponent, ProjectManagerListener { + private boolean myDoNotShowThisTime = false; + private boolean myVeryFirstProjectOpening = true; + + public static TipOfTheDayManager getInstance() { + return ApplicationManager.getApplication().getComponent(TipOfTheDayManager.class); + } + + + public TipOfTheDayManager(ProjectManager projectManager) { + projectManager.addProjectManagerListener(this); + } + + public String getComponentName() { + return "TipOfTheDayManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + ProjectManager.getInstance().removeProjectManagerListener(this); + } + + public void projectOpened(Project project) { + if (!myVeryFirstProjectOpening || !GeneralSettings.getInstance().showTipsOnStartup()) { + return; + } + + myVeryFirstProjectOpening = false; + + StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() { + public void run() { + if (myDoNotShowThisTime) return; + new TipDialog().show(); + } + }); + } + + public void doNotShowThisTime() { + myDoNotShowThisTime = true; + } + + public boolean canCloseProject(Project project) { + return true; + } + + public void projectClosed(Project project) { + + } + + public void projectClosing(Project project) { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacro.java new file mode 100644 index 00000000000..fc0485911fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacro.java @@ -0,0 +1,225 @@ +package com.intellij.ide.actionMacro; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.TypedAction; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author max + */ +public class ActionMacro implements JDOMExternalizable { + private String myName; + + private ArrayList myActions = new ArrayList(); + public static final String MACRO_ACTION_PREFIX = "Macro."; + + public ActionMacro() { + } + + public ActionMacro(String name) { + myName = name; + } + + public String getName() { + return myName; + } + + public void setName(String name) { + myName = name; + } + + public ActionDescriptor[] getActions() { + return myActions.toArray(new ActionDescriptor[myActions.size()]); + } + + public void readExternal(Element macro) throws InvalidDataException { + setName(macro.getAttributeValue("name")); + List actions = macro.getChildren(); + for (Iterator iterator = actions.iterator(); iterator.hasNext();) { + Element action = (Element)iterator.next(); + if ("typing".equals(action.getName())) { + myActions.add(new TypedDescriptor(action.getAttributeValue("text"))); + } + else if ("action".equals(action.getName())) { + myActions.add(new IdActionDescriptor(action.getAttributeValue("id"))); + } + } + } + + public void writeExternal(Element macro) throws WriteExternalException { + macro.setAttribute("name", myName); + final ActionDescriptor[] actions = getActions(); + for (int i = 0; i < actions.length; i++) { + ActionDescriptor action = actions[i]; + Element actionNode; + if (action instanceof TypedDescriptor) { + actionNode = new Element("typing"); + actionNode.setAttribute("text", ((TypedDescriptor)action).getText()); + } + else { + actionNode = new Element("action"); + actionNode.setAttribute("id", ((IdActionDescriptor)action).getActionId()); + } + macro.addContent(actionNode); + } + } + + public String toString() { + return myName; + } + + protected Object clone() { + ActionMacro copy = new ActionMacro(myName); + for (int i = 0; i < myActions.size(); i++) { + ActionDescriptor action = myActions.get(i); + copy.myActions.add((ActionDescriptor)action.clone()); + } + + return copy; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ActionMacro)) return false; + + final ActionMacro actionMacro = (ActionMacro)o; + + if (!myActions.equals(actionMacro.myActions)) return false; + if (!myName.equals(actionMacro.myName)) return false; + + return true; + } + + public int hashCode() { + int result; + result = myName.hashCode(); + result = 29 * result + myActions.hashCode(); + return result; + } + + public void deleteAction(int idx) { + myActions.remove(idx); + } + + public void appendAction(String actionId) { + myActions.add(new IdActionDescriptor(actionId)); + } + + public void appendKeytyped(char c) { + ActionDescriptor lastAction = myActions.size() > 0 ? myActions.get(myActions.size() - 1) : null; + if (lastAction instanceof TypedDescriptor) { + ((TypedDescriptor)lastAction).addChar(c); + } + else { + myActions.add(new TypedDescriptor(c)); + } + } + + public String getActionId() { + return MACRO_ACTION_PREFIX + myName; + } + + public interface ActionDescriptor { + Object clone(); + + void playBack(DataContext context); + } + + public static class TypedDescriptor implements ActionDescriptor { + private String myText; + + public TypedDescriptor(String text) { + myText = text; + } + + public TypedDescriptor(char c) { + myText = String.valueOf(c); + } + + public void addChar(char c) { + myText = myText + c; + } + + public String getText() { + return myText; + } + + public Object clone() { + return new TypedDescriptor(myText); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TypedDescriptor)) return false; + return myText.equals(((TypedDescriptor)o).myText); + } + + public int hashCode() { + return myText.hashCode(); + } + + public String toString() { + return "Typing: \"" + myText + "\""; + } + + public void playBack(DataContext context) { + Editor editor = (Editor)context.getData(DataConstants.EDITOR); + final TypedAction typedAction = EditorActionManager.getInstance().getTypedAction(); + char chars[] = myText.toCharArray(); + for (int i = 0; i < chars.length; i++) { + typedAction.actionPerformed(editor, chars[i], context); + } + } + } + + public static class IdActionDescriptor implements ActionDescriptor { + private String actionId; + + public IdActionDescriptor(String id) { + this.actionId = id; + } + + public String getActionId() { + return actionId; + } + + public String toString() { + return "Action: " + actionId; + } + + public Object clone() { + return new IdActionDescriptor(actionId); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof IdActionDescriptor)) return false; + return actionId.equals(((IdActionDescriptor)o).actionId); + } + + public int hashCode() { + return actionId.hashCode(); + } + + public void playBack(DataContext context) { + AnAction action = ActionManager.getInstance().getAction(getActionId()); + if (action == null) return; + Presentation presentation = (Presentation)action.getTemplatePresentation().clone(); + AnActionEvent event = new AnActionEvent(null, context, "MACRO_PLAYBACK", presentation, ActionManager.getInstance(), 0); + action.update(event); + if (!presentation.isEnabled()) { + return; + } + action.actionPerformed(event); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurable.java new file mode 100644 index 00000000000..95d4f8e5b78 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurable.java @@ -0,0 +1,51 @@ +package com.intellij.ide.actionMacro; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; + +import javax.swing.Icon; +import javax.swing.JComponent; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 21, 2003 + * Time: 10:38:42 PM + * To change this template use Options | File Templates. + */ +public class ActionMacroConfigurable implements Configurable { + private ActionMacroConfigurationPanel myPanel; + + public String getDisplayName() { + return "Edit Macros"; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + myPanel = new ActionMacroConfigurationPanel(); + return myPanel.getPanel(); + } + + public void apply() throws ConfigurationException { + myPanel.apply(); + } + + public void reset() { + myPanel.reset(); + } + + public boolean isModified() { + return myPanel.isModified(); + } + + public void disposeUIResources() { + myPanel = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurationPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurationPanel.java new file mode 100644 index 00000000000..d0327819020 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroConfigurationPanel.java @@ -0,0 +1,155 @@ +package com.intellij.ide.actionMacro; + +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ListUtil; +import com.intellij.util.containers.HashSet; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Enumeration; +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 22, 2003 + * Time: 4:01:10 PM + * To change this template use Options | File Templates. + */ +public class ActionMacroConfigurationPanel { + private JPanel myPanel; + private JButton myDeleteButton; + private JButton myRenameButton; + private JButton myExcludeActionButton; + private JList myMacrosList; + private JList myMacroActionsList; + + final DefaultListModel myMacrosModel = new DefaultListModel(); + private ActionMacro mySelectedMacro; + + public ActionMacroConfigurationPanel() { + ListUtil.addRemoveListener(myDeleteButton, myMacrosList); + + myMacrosList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myMacroActionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + myMacrosList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + final int selIndex = myMacrosList.getSelectedIndex(); + if (selIndex == -1) { + ((DefaultListModel) myMacroActionsList.getModel()).removeAllElements(); + myExcludeActionButton.setEnabled(false); + myRenameButton.setEnabled(false); + } else { + myRenameButton.setEnabled(true); + initActionList((ActionMacro)myMacrosModel.getElementAt(selIndex)); + } + } + }); + + myMacroActionsList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + final int selIdx = myMacroActionsList.getSelectedIndex(); + myExcludeActionButton.setEnabled(selIdx != -1); + } + }); + + myExcludeActionButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + final int selIndex = myMacrosList.getSelectedIndex(); + + if (selIndex != -1) { + final ActionMacro macro = (ActionMacro)myMacrosModel.getElementAt(selIndex); + macro.deleteAction(myMacroActionsList.getSelectedIndex()); + } + ListUtil.removeSelectedItems(myMacroActionsList); + } + }); + + myRenameButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + final int selIndex = myMacrosList.getSelectedIndex(); + if (selIndex == -1) return; + final ActionMacro macro = (ActionMacro) myMacrosModel.getElementAt(selIndex); + final String newName = Messages.showInputDialog(myPanel, "Enter New Name", "Rename Macro", + Messages.getQuestionIcon(), macro.getName(), null); + if (newName != null) { + macro.setName(newName); + myMacrosList.repaint(); + } + } + }); + } + + public void reset() { + final ActionMacro[] allMacros = ActionMacroManager.getInstance().getAllMacros(); + for (int i = 0; i < allMacros.length; i++) { + ActionMacro macro = allMacros[i]; + myMacrosModel.addElement(macro.clone()); + } + myMacrosList.setModel(myMacrosModel); + ListScrollingUtil.ensureSelectionExists(myMacrosList); + } + + public void apply() { + final ActionMacroManager manager = ActionMacroManager.getInstance(); + ActionMacro[] macros = manager.getAllMacros(); + HashSet removedIds = new HashSet(); + for (int i = 0; i < macros.length; i++) { + removedIds.add(macros[i].getActionId()); + } + + manager.removeAllMacros(); + + final Enumeration newMacros = myMacrosModel.elements(); + while (newMacros.hasMoreElements()) { + ActionMacro macro = (ActionMacro) newMacros.nextElement(); + manager.addMacro(macro); + removedIds.remove(macro.getActionId()); + } + manager.registerActions(); + + for (Iterator iterator = removedIds.iterator(); iterator.hasNext();) { + String id = iterator.next(); + Keymap[] allKeymaps = KeymapManagerEx.getInstanceEx().getAllKeymaps(); + for (int i = 0; i < allKeymaps.length; i++) { + Keymap keymap = allKeymaps[i]; + keymap.removeAllActionShortcuts(id); + } + } + } + + public boolean isModified() { + final ActionMacro[] allMacros = ActionMacroManager.getInstance().getAllMacros(); + if (allMacros.length != myMacrosModel.getSize()) return true; + for (int i = 0; i < allMacros.length; i++) { + ActionMacro macro = allMacros[i]; + ActionMacro newMacro = (ActionMacro) myMacrosModel.get(i); + if (!macro.equals(newMacro)) return true; + } + return false; + } + + private void initActionList(ActionMacro macro) { + mySelectedMacro = macro; + DefaultListModel actionModel = new DefaultListModel(); + final ActionMacro.ActionDescriptor[] actions = macro.getActions(); + for (int i = 0; i < actions.length; i++) { + ActionMacro.ActionDescriptor action = actions[i]; + actionModel.addElement(action); + } + myMacroActionsList.setModel(actionModel); + ListScrollingUtil.ensureSelectionExists(myMacroActionsList); + } + + public JPanel getPanel() { + return myPanel; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroManager.java new file mode 100644 index 00000000000..2372a07ea00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/ActionMacroManager.java @@ -0,0 +1,302 @@ +package com.intellij.ide.actionMacro; + +import com.intellij.ide.DataManager; +import com.intellij.ide.IdeEventQueue; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.AnActionListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.awt.*; +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +/** + * @author max + */ +public class ActionMacroManager implements ExportableApplicationComponent, NamedJDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actionMacro.ActionMacroManager"); + + private boolean myIsRecording; + private ActionManagerEx myActionManager; + private ActionMacro myLastMacro; + private ActionMacro myRecordingMacro; + private ArrayList myMacros = new ArrayList(); + private String myLastMacroName = null; + private boolean myIsPlaying = false; + + public ActionMacroManager(ActionManagerEx actionManagerEx) { + myActionManager = actionManagerEx; + myActionManager.addAnActionListener(new AnActionListener() { + public void beforeActionPerformed(AnAction action, DataContext dataContext) { + if (myIsRecording) { + String id = myActionManager.getId(action); + if (id != null && !"StartStopMacroRecording".equals(id)) { + myRecordingMacro.appendAction(id); + } + } + } + + public void beforeEditorTyping(char c, DataContext dataContext) { + if (myIsRecording) { + myRecordingMacro.appendKeytyped(c); + } + } + }); + + registerActions(); + } + + public void readExternal(Element element) throws InvalidDataException { + myMacros = new ArrayList(); + final List macros = element.getChildren("macro"); + for (Iterator iterator = macros.iterator(); iterator.hasNext();) { + Element macroElement = (Element)iterator.next(); + ActionMacro macro = new ActionMacro(); + macro.readExternal(macroElement); + myMacros.add(macro); + } + } + + public String getExternalFileName() { + return "macros"; + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Macros"; + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myMacros.size(); i++) { + ActionMacro macro = myMacros.get(i); + Element macroElement = new Element("macro"); + macro.writeExternal(macroElement); + element.addContent(macroElement); + } + } + + public static ActionMacroManager getInstance() { + return ApplicationManager.getApplication().getComponent(ActionMacroManager.class); + } + + public String getComponentName() { + return "ActionMacroManager"; + } + + public void initComponent() { } + + public void startRecording(String macroName) { + LOG.assertTrue(!myIsRecording); + myIsRecording = true; + myRecordingMacro = new ActionMacro(macroName); + } + + public void stopRecording(Project project) { + LOG.assertTrue(myIsRecording); + myIsRecording = false; + String macroName; + do { + macroName = Messages.showInputDialog(project, + "Enter macro name. Leave blank if macro is temporary.", + "Enter Macro Name", + Messages.getQuestionIcon()); + if (macroName == null) { + myRecordingMacro = null; + return; + } + + if ("".equals(macroName)) macroName = null; + } + while (macroName != null && !checkCanCreateMacro(macroName)); + + myLastMacro = myRecordingMacro; + addRecordedMacroWithName(macroName); + registerActions(); + } + + private void addRecordedMacroWithName(String macroName) { + if (macroName != null) { + myRecordingMacro.setName(macroName); + myMacros.add(myRecordingMacro); + myRecordingMacro = null; + } + else { + for (int i = 0; i < myMacros.size(); i++) { + ActionMacro macro = myMacros.get(i); + if ("".equals(macro.getName())) { + myMacros.set(i, myRecordingMacro); + myRecordingMacro = null; + break; + } + } + if (myRecordingMacro != null) { + myMacros.add(myRecordingMacro); + myRecordingMacro = null; + } + } + } + + public void playbackLastMacro() { + if (myLastMacro != null) { + playbackMacro(myLastMacro); + } + } + + private void playbackMacro(ActionMacro macro) { + myIsPlaying = true; + try { + ActionMacro.ActionDescriptor[] actions = macro.getActions(); + for (int i = 0; i < actions.length; i++) { + // Right thing here. If some macro changes the context (like transferes focus) we should use changed one. + actions[i].playBack(DataManager.getInstance().getDataContext()); + pumpEvents(); + } + myLastMacro = macro; + } + finally{ + myIsPlaying = false; + } + } + + private void pumpEvents() { + IdeEventQueue eventQueue = IdeEventQueue.getInstance(); + while (true) { + AWTEvent event = eventQueue.peekEvent(); + if (event == null) return; + try { + AWTEvent event1 = eventQueue.getNextEvent(); + eventQueue.dispatchEvent(event1); + } + catch (Exception e) { + LOG.error(e); //? + } + } + } + + public boolean isRecording() { + return myIsRecording; + } + + public void disposeComponent() { + } + + public ActionMacro[] getAllMacros() { + return myMacros.toArray(new ActionMacro[myMacros.size()]); + } + + public void removeAllMacros() { + if (myLastMacro != null) { + myLastMacroName = myLastMacro.getName(); + myLastMacro = null; + } + myMacros = new ArrayList(); + } + + public void addMacro(ActionMacro macro) { + myMacros.add(macro); + if (myLastMacroName != null && myLastMacroName.equals(macro.getName())) { + myLastMacro = macro; + myLastMacroName = null; + } + } + + public void playMacro(ActionMacro macro) { + playbackMacro(macro); + myLastMacro = macro; + } + + public boolean hasRecentMacro() { + return myLastMacro != null; + } + + public void registerActions() { + unregisterActions(); + HashSet registeredIds = new HashSet(); // to prevent exception if 2 or more targets have the same name + + ActionMacro[] macros = getAllMacros(); + for (int i = 0; i < macros.length; i++) { + final ActionMacro macro = macros[i]; + String actionId = macro.getActionId(); + + if (!registeredIds.contains(actionId)) { + registeredIds.add(actionId); + myActionManager.registerAction(actionId, new InvokeMacroAction(macro)); + } + } + } + + public void unregisterActions() { + + // unregister Tool actions + String[] oldIds = myActionManager.getActionIds(ActionMacro.MACRO_ACTION_PREFIX); + for (int i = 0; i < oldIds.length; i++) { + String oldId = oldIds[i]; + myActionManager.unregisterAction(oldId); + } + } + + public boolean checkCanCreateMacro(String name) { + final ActionManagerEx actionManager = (ActionManagerEx)ActionManager.getInstance(); + final String actionId = ActionMacro.MACRO_ACTION_PREFIX + name; + if (actionManager.getAction(actionId) != null) { + if (Messages.showYesNoDialog("There is already a macro called '" + name + "'. Overwrite it?", + "Macro Name Already Used", + Messages.getWarningIcon()) != 0) { + return false; + } + actionManager.unregisterAction(actionId); + removeMacro(name); + } + + return true; + } + + private void removeMacro(String name) { + for (int i = 0; i < myMacros.size(); i++) { + ActionMacro macro = myMacros.get(i); + if (name.equals(macro.getName())) { + myMacros.remove(i); + break; + } + } + } + + public boolean isPlaying() { + return myIsPlaying; + } + + private static class InvokeMacroAction extends AnAction { + private final ActionMacro myMacro; + + InvokeMacroAction(ActionMacro macro) { + myMacro = macro; + getTemplatePresentation().setText(macro.getName(), false); + } + + public void actionPerformed(AnActionEvent e) { + ActionMacroManager.getInstance().playMacro(myMacro); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(!ActionMacroManager.getInstance().isPlaying() && + e.getDataContext().getData(DataConstants.EDITOR) != null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/EditMacrosDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/EditMacrosDialog.java new file mode 100644 index 00000000000..7dc7e8bd90c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/EditMacrosDialog.java @@ -0,0 +1,21 @@ +package com.intellij.ide.actionMacro; + +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 22, 2003 + * Time: 3:30:56 PM + * To change this template use Options | File Templates. + */ +public class EditMacrosDialog extends SingleConfigurableEditor { + public EditMacrosDialog(Project project) { + super(project, new ActionMacroConfigurable()); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.ide.actionMacro.EditMacrosDialog"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/EditMacrosAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/EditMacrosAction.java new file mode 100644 index 00000000000..bf531745e8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/EditMacrosAction.java @@ -0,0 +1,21 @@ +package com.intellij.ide.actionMacro.actions; + +import com.intellij.ide.actionMacro.EditMacrosDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 22, 2003 + * Time: 3:33:04 PM + * To change this template use Options | File Templates. + */ +public class EditMacrosAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + EditMacrosDialog dialog = new EditMacrosDialog((Project)e.getDataContext().getData(DataConstants.PROJECT)); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/MacrosGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/MacrosGroup.java new file mode 100644 index 00000000000..25f7d137b2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/MacrosGroup.java @@ -0,0 +1,29 @@ +package com.intellij.ide.actionMacro.actions; + +import com.intellij.ide.actionMacro.ActionMacro; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; + +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jul 22, 2003 + * Time: 5:46:17 PM + * To change this template use Options | File Templates. + */ +public class MacrosGroup extends ActionGroup { + public AnAction[] getChildren(AnActionEvent e) { + ArrayList actions = new ArrayList(); + final ActionManagerEx actionManager = ((ActionManagerEx) ActionManager.getInstance()); + String[] ids = actionManager.getActionIds(ActionMacro.MACRO_ACTION_PREFIX); + + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + actions.add(actionManager.getAction(id)); + } + + return actions.toArray(new AnAction[actions.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java new file mode 100644 index 00000000000..a6e78386bd2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java @@ -0,0 +1,21 @@ +package com.intellij.ide.actionMacro.actions; + +import com.intellij.ide.actionMacro.ActionMacroManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; + +/** + * @author max + */ +public class PlaybackLastMacroAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + ActionMacroManager.getInstance().playbackLastMacro(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled( + !ActionMacroManager.getInstance().isPlaying() && + ActionMacroManager.getInstance().hasRecentMacro() && e.getDataContext().getData(DataConstants.EDITOR) != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java new file mode 100644 index 00000000000..e51f1a19b92 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java @@ -0,0 +1,27 @@ +package com.intellij.ide.actionMacro.actions; + +import com.intellij.ide.actionMacro.ActionMacroManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * @author max + */ +public class StartStopMacroRecordingAction extends AnAction { + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(e.getDataContext().getData(DataConstants.EDITOR) != null); + e.getPresentation().setText(ActionMacroManager.getInstance().isRecording() ? "Stop Macro Recording" : "Start Macro Recording"); + } + + public void actionPerformed(AnActionEvent e) { + if (!ActionMacroManager.getInstance().isRecording() ) { + final ActionMacroManager manager = ActionMacroManager.getInstance(); + manager.startRecording(""); + } + else { + ActionMacroManager.getInstance().stopRecording((Project) e.getDataContext().getData(DataConstants.PROJECT)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AboutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AboutAction.java new file mode 100644 index 00000000000..ed530138a23 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AboutAction.java @@ -0,0 +1,291 @@ +package com.intellij.ide.actions; + +import com.intellij.Patches; +import com.intellij.ide.BrowserUtil; +import com.intellij.ide.DataManager; +import com.intellij.ide.license.LicenseManager; +import com.intellij.ide.license.ui.LicenseUrls; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.ui.AnimatingSurface; +import com.intellij.util.ImageLoader; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.Calendar; +import java.util.Properties; + +public class AboutAction extends AnAction { + private static final String[] months = new String[]{"January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December"}; + + public void update(AnActionEvent e) { + e.getPresentation().setVisible(!SystemInfo.isMacSystemMenu); + } + + public void actionPerformed(AnActionEvent e) { + Window window = WindowManager.getInstance().suggestParentWindow((Project)e.getDataContext().getData(DataConstants.PROJECT)); + + showAboutDialog(window); + } + + public static void showAbout() { + Window window = WindowManager.getInstance().suggestParentWindow( + (Project)DataManager.getInstance().getDataContext().getData(DataConstants.PROJECT)); + + showAboutDialog(window); + } + + private static void showAboutDialog(Window window) { + ApplicationInfoEx appInfo = (ApplicationInfoEx)ApplicationInfo.getInstance(); + JPanel mainPanel = new JPanel(new BorderLayout()); + final JComponent closeListenerOwner; + if (appInfo.showLicenseeInfo()) { + final Image image = ImageLoader.loadFromResource(appInfo.getAboutLogoUrl()); + final InfoSurface infoSurface = new InfoSurface(image); + infoSurface.setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null))); + mainPanel.add(infoSurface, BorderLayout.NORTH); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + infoSurface.start(); + } + }); + closeListenerOwner = infoSurface; + } + else { + mainPanel.add(new JLabel(IconLoader.getIcon(appInfo.getAboutLogoUrl())), BorderLayout.NORTH); + closeListenerOwner = mainPanel; + } + + final JDialog dialog; + if (window instanceof Dialog) { + dialog = new JDialog((Dialog)window); + } + else { + dialog = new JDialog((Frame)window); + } + dialog.setUndecorated(true); + dialog.setContentPane(mainPanel); + dialog.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) { + dialog.dispose(); + } + } + }); + + final long showTime = System.currentTimeMillis(); + final long delta = Patches.APPLE_BUG_ID_3716865 ? 100 : 0; + + dialog.addWindowFocusListener(new WindowFocusListener() { + public void windowGainedFocus(WindowEvent e) {} + + public void windowLostFocus(WindowEvent e) { + long eventTime = System.currentTimeMillis(); + if (eventTime - showTime > delta && e.getOppositeWindow() != e.getWindow()) { + dialog.dispose(); + } + } + }); + + closeListenerOwner.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (!e.isConsumed()) { + dialog.dispose(); + e.consume(); + } + } + }); + + dialog.pack(); + + dialog.setLocationRelativeTo(window); + dialog.setVisible(true); + } + + private static class InfoSurface extends AnimatingSurface { + final Color col = new Color(69, 86, 156, 200); + final Color linkCol = new Color(255, 255, 128, 200); + final int UP = 0; + final int DOWN = 1; + private Image myImage; + private float myAlpha; + private int myAlphaDirection = UP; + private Font myFont; + private Font myBoldFont; + private String q[] = new String[12]; + private int linkY; + private int linkWidth; + private boolean inLink = false; + + public InfoSurface(Image image) { + myImage = image; + + + myAlpha = 0f; + setOpaque(true); + setBackground(col); + ApplicationInfoEx ideInfo = (ApplicationInfoEx)ApplicationInfo.getInstance(); + Calendar cal = ideInfo.getBuildDate(); + q[0] = ideInfo.getFullApplicationName(); + q[1] = "Build #" + ideInfo.getBuildNumber(); + q[2] = "Built on " + months[cal.get(Calendar.MONTH)] + " " + cal.get(Calendar.DATE) + ", " + + cal.get(Calendar.YEAR); + q[3] = LicenseManager.getInstance().licensedToMessage(); + q[4] = LicenseManager.getInstance().licensedRestrictionsMessage(); + q[5] = ""; + { + final Properties properties = System.getProperties(); + q[6] = "JDK: " + properties.getProperty("java.version", "unknown"); + q[7] = "VM: " + properties.getProperty("java.vm.name", "unknown"); + q[8] = "Vendor: " + properties.getProperty("java.vendor", "unknown"); + } + q[9] = ""; + q[10] = "JetBrains s.r.o."; + q[11] = LicenseUrls.getCompanyUrl(); + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent event) { + if (inLink) { + event.consume(); + BrowserUtil.launchBrowser(LicenseUrls.getCompanyUrl()); + } + } + }); + addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent event) { + if ( + event.getPoint().x > 20 && event.getPoint().y >= linkY && + event.getPoint().x < 20 + linkWidth && event.getPoint().y < linkY + 10 + ) { + if (!inLink) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + inLink = true; + } + } + else { + if (inLink) { + setCursor(Cursor.getDefaultCursor()); + inLink = false; + } + } + } + }); + } + + public class TextRenderer { + private final int xBase; + private final int yBase; + private final int w; + private final int h; + private final Graphics2D g2; + + private int x = 0, y = 0; + private FontMetrics fontmetrics; + private int fontAscent; + private int fontHeight; + private Font font; + + public class Overflow extends Exception { } + + public TextRenderer(final int xBase, final int yBase, final int w, final int h, final Graphics2D g2) { + this.xBase = xBase; + this.yBase = yBase; + this.w = w; + this.h = h; + this.g2 = g2; + g2.fillRect(xBase, yBase, w, h); + g2.draw3DRect(xBase, yBase, w, h, true); + } + + + + public void render(int indentX, int indentY, String[] q) throws Overflow { + x = indentX; + y = indentY; + g2.setColor(Color.white); + for (int i = 0; i < q.length; i++) { + final String s = q[i]; + setFont (i == 0 || i >= q.length - 2 ? myBoldFont : myFont); + if (i == q.length - 1) { + g2.setColor(linkCol); + linkY = yBase + y - fontAscent; + FontMetrics metrics = g2.getFontMetrics(font); + linkWidth = metrics.stringWidth (s); + } + for (int j = 0; j != s.length (); ++ j) { + final char c = s.charAt (j); + final int cW = fontmetrics.charWidth(c); + if (x +cW >= w) { + lineFeed(indentX); + } + g2.drawChars (new char[]{c}, 0, 1, xBase + x, yBase + y); + x += cW; + } + lineFeed (indentX); + } + } + + private void lineFeed(int indent) throws Overflow { + x = indent; + y += fontHeight; + if (y + fontHeight >= h) + throw new Overflow(); + } + + private void setFont(Font font) { + this.font = font; + fontmetrics = g2.getFontMetrics(font); + g2.setFont (font); + fontAscent = fontmetrics.getAscent(); + fontHeight = fontmetrics.getHeight(); + } + } + + public void render(int w, int h, Graphics2D g2) { + AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, myAlpha); + g2.setComposite(ac); + + Font labelFont = UIManager.getFont("Label.font"); + Loop: + for (int labelSize = 10; labelSize != 6; labelSize -= 1) { + g2.setPaint(col); + g2.drawImage(myImage, 0, 0, this); + g2.setColor(col); + int startY = (int)(-250 * (1.0f - myAlpha) + 20); + TextRenderer renderer = new TextRenderer(15, startY, 190, 250, g2); + g2.setComposite(AlphaComposite.Src); + myFont = labelFont.deriveFont(Font.PLAIN, labelSize); + myBoldFont = labelFont.deriveFont(Font.BOLD, labelSize+1); + try { + renderer.render (20, 25, q); + break; + } + catch (TextRenderer.Overflow _) { + continue Loop; + } + } + } + + public void reset(int w, int h) { } + + public void step(int w, int h) { + if (myAlphaDirection == UP) { + if ((myAlpha += 0.2) > .99) { + myAlphaDirection = DOWN; + myAlpha = 1.0f; + } + } + else if (myAlphaDirection == DOWN) { + stop(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ActivateToolWindowAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ActivateToolWindowAction.java new file mode 100644 index 00000000000..995b054c4ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ActivateToolWindowAction.java @@ -0,0 +1,89 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; + +import javax.swing.*; +import java.awt.event.KeyEvent; + +public class ActivateToolWindowAction extends AnAction { + private String myToolWindowId; + + /** + * Creates an action which activates tool window with specified toolWindowId. + */ + protected ActivateToolWindowAction(final String toolWindowId, final String text, final Icon icon){ + super(text, "Activate "+toolWindowId+" window", icon); + myToolWindowId=toolWindowId; + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + ToolWindow toolWindow=ToolWindowManager.getInstance(project).getToolWindow(myToolWindowId); + presentation.setEnabled(toolWindow!=null&&toolWindow.isAvailable()); + presentation.setVisible(toolWindow!=null); + } + + public void actionPerformed(AnActionEvent e){ + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + windowManager.getToolWindow(myToolWindowId).activate(null); + } + + public String getToolWindowId() { + return myToolWindowId; + } + + /** + * This is the "rule" method constructs ID of the action for activating tool window + * with specified ID. + * @param id id of tool window to be activated. + */ + public static String getActionIdForToolWindow(String id){ + return "Activate"+id.replaceAll(" ","")+"ToolWindow"; + } + + /** + * @return mnemonic for action if it has Alt+digit/Meta+digit shortcut. + * Otherwise the method returns -1. Meta mask is OK for + * Mac OS X user, because Alt+digit types strange characters into the + * editor. + */ + public static int getMnemonicForToolWindow(String id){ + Keymap activeKeymap=KeymapManager.getInstance().getActiveKeymap(); + Shortcut[] shortcuts = activeKeymap.getShortcuts(getActionIdForToolWindow(id)); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + KeyStroke keyStroke = ((KeyboardShortcut)shortcut).getFirstKeyStroke(); + int modifiers=keyStroke.getModifiers(); + if ( + (modifiers == (KeyEvent.ALT_DOWN_MASK|KeyEvent.ALT_MASK)) || + (modifiers == KeyEvent.ALT_MASK) || + (modifiers == KeyEvent.ALT_DOWN_MASK) || + (modifiers == (KeyEvent.META_DOWN_MASK|KeyEvent.META_MASK)) || + (modifiers == KeyEvent.META_MASK) || + (modifiers == KeyEvent.META_DOWN_MASK) + ) { + int keyCode = keyStroke.getKeyCode(); + if (KeyEvent.VK_0 <= keyCode && keyCode <= KeyEvent.VK_9) { + char c = (char) ('0' + keyCode - KeyEvent.VK_0); + return (int)c; + } + } + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AssociateFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AssociateFileType.java new file mode 100644 index 00000000000..9f646079016 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/AssociateFileType.java @@ -0,0 +1,34 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.ex.FileTypeChooser; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public class AssociateFileType extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + FileTypeChooser.associateFileType(file.getName()); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + DataContext dataContext = e.getDataContext(); + VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + boolean haveSmthToDo; + if (project == null || file == null || file.isDirectory()) { + haveSmthToDo = false; + } + else { + haveSmthToDo = FileTypeManager.getInstance().getFileTypeByFile(file) == StdFileTypes.UNKNOWN; + } + presentation.setVisible(haveSmthToDo || ActionPlaces.MAIN_MENU.equals(e.getPlace())); + presentation.setEnabled(haveSmthToDo); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BackAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BackAction.java new file mode 100644 index 00000000000..6acc03b1407 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BackAction.java @@ -0,0 +1,24 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +public class BackAction extends AnAction{ + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + IdeDocumentHistory.getInstance(project).back(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(IdeDocumentHistory.getInstance(project).isBackAvailable()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BaseNavigateToSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BaseNavigateToSourceAction.java new file mode 100644 index 00000000000..acee1292cb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/BaseNavigateToSourceAction.java @@ -0,0 +1,117 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; + +public abstract class BaseNavigateToSourceAction extends AnAction { + public static final String SOURCE_NAVIGATOR = "sourceNavigator"; + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.BaseNavigateToSourceAction"); + private final boolean myFocusEditor; + + public BaseNavigateToSourceAction(boolean focusEditor) { + myFocusEditor = focusEditor; + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Navigatable navigatable = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + navigatable.navigate(myFocusEditor); + } + + + public void update(AnActionEvent event){ + DataContext dataContext = event.getDataContext(); + Navigatable navigatable = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + event.getPresentation().setEnabled(navigatable != null && navigatable.canNavigate()); + } + + private static void navigate(DataContext dataContext, OpenFileDescriptor descriptor, boolean focusEditor) { + SourceNavigator.fromContext(dataContext).navigate(descriptor, focusEditor); + } + + public static abstract class SourceNavigator { + public abstract void navigate(OpenFileDescriptor descriptor, boolean focusEditor); + public abstract boolean canNavigateTo(OpenFileDescriptor descriptor); + + public static SourceNavigator fromContext(DataContext dataContext) { + SourceNavigator sourceNavigator = (SourceNavigator)dataContext.getData(SOURCE_NAVIGATOR); + if (sourceNavigator != null) return sourceNavigator; + Boolean isLockedValue = (Boolean)dataContext.getData(DataConstantsEx.SOURCE_NAVIGATION_LOCKED); + boolean isLocked = isLockedValue != null && isLockedValue.booleanValue(); + if (isLocked) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + return editor != null ? new EditorNavigator(editor) : DISABLED_NAVIGATOR; + } + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return DISABLED_NAVIGATOR; + return new DefaultNavigator(project); + } + } + + private static final SourceNavigator DISABLED_NAVIGATOR = new SourceNavigator() { + public void navigate(OpenFileDescriptor descriptor, boolean focusEditor) { + LOG.error(String.valueOf(descriptor.getFile())); + } + + public boolean canNavigateTo(OpenFileDescriptor descriptor) { + return false; + } + }; + + private static class DefaultNavigator extends SourceNavigator { + private final Project myProject; + + public DefaultNavigator(Project project) { + myProject = project; + } + + public void navigate(OpenFileDescriptor descriptor, boolean focusEditor) { + FileEditorManager.getInstance(myProject).openTextEditor(descriptor, focusEditor); + } + + public boolean canNavigateTo(OpenFileDescriptor descriptor) { + FileEditorProviderManager providerManager = FileEditorProviderManager.getInstance(); + return descriptor != null && providerManager.getProviders(myProject, descriptor.getFile()).length > 0; + } + } + + private static class EditorNavigator extends SourceNavigator { + private final Editor myEditor; + + public EditorNavigator(Editor editor) { + myEditor = editor; + } + + public boolean canNavigateTo(OpenFileDescriptor descriptor) { + if (descriptor == null) return false; + return descriptor.getFile() == FileDocumentManager.getInstance().getFile(myEditor.getDocument()); + } + + public void navigate(OpenFileDescriptor descriptor, boolean focusEditor) { + Document document = myEditor.getDocument(); + LogicalPosition position; + int offset = descriptor.getOffset(); + if (offset < 0) + position = new LogicalPosition(Math.min(document.getLineCount() - 1, descriptor.getLine()), + descriptor.getColumn()); + else + position = myEditor.offsetToLogicalPosition(Math.min(document.getTextLength(), offset)); + myEditor.getCaretModel().moveToLogicalPosition(position); + myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChangeSplitterOrientationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChangeSplitterOrientationAction.java new file mode 100644 index 00000000000..f3aeeff9aac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChangeSplitterOrientationAction.java @@ -0,0 +1,33 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; + +import javax.swing.*; + +/** + * @author Vladimir Kondratyev + */ +public final class ChangeSplitterOrientationAction extends AnAction{ + public void actionPerformed(final AnActionEvent event) { + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + fileEditorManager.changeSplitterOrientation (); + } + + public void update(final AnActionEvent event) { + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final Presentation presentation = event.getPresentation(); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setText("Change Splitter Orientations"); + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + presentation.setEnabled (fileEditorManager.isInSplitter()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChooseComponentsToExportDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChooseComponentsToExportDialog.java new file mode 100644 index 00000000000..4a11a7943e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ChooseComponentsToExportDialog.java @@ -0,0 +1,196 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.FieldPanel; +import com.intellij.ide.util.ElementsChooser; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.*; +import java.util.List; + +public class ChooseComponentsToExportDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ChooseComponentsToExportDialog"); + + private ElementsChooser myChooser; + private FieldPanel myPathPanel; + private ActionListener myBrowseAction; + public static final String DEFAULT_PATH = FileUtil.toSystemDependentName(PathManager.getConfigPath()+"/"+"settings.jar"); + private final boolean myShowFilePath; + private final String myDescription; + + public ChooseComponentsToExportDialog(List components, + Map> fileToComponents, + boolean showFilePath, final String title, String description) { + super(false); + myDescription = description; + myShowFilePath = showFilePath; + Map componentToContainingListElement = new LinkedHashMap(); + + for (int i = 0; i < components.size(); i++) { + ExportableApplicationComponent component = components.get(i); + if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) { + ComponentElementProperties componentElementProperties = new ComponentElementProperties(); + componentElementProperties.addComponent(component); + + componentToContainingListElement.put(component, componentElementProperties); + } + } + final Set componentElementProperties = new LinkedHashSet(componentToContainingListElement.values()); + myChooser = new ElementsChooser(); + for (Iterator iterator = componentElementProperties.iterator(); iterator.hasNext();) { + ComponentElementProperties elementProperties = (ComponentElementProperties)iterator.next(); + myChooser.addElement(elementProperties, true, elementProperties); + } + + myBrowseAction = new ActionListener() { + public void actionPerformed(ActionEvent e) { + String oldPath = myPathPanel.getText(); + String path = chooseSettingsFile(oldPath, getWindow(), "Export File Location", "Choose export file path or directory where to create new file"); + if (path == null) return; + myPathPanel.setText(FileUtil.toSystemDependentName(path)); + } + }; + + myPathPanel = new FieldPanel("Export settings to:", null, myBrowseAction, null); + myPathPanel.setText(DEFAULT_PATH); + + setTitle(title); + init(); + } + + private boolean addToExistingListElement(ExportableApplicationComponent component, + Map componentToContainingListElement, + Map> fileToComponents) { + final File[] exportFiles = component.getExportFiles(); + File file = null; + for (int i = 0; i < exportFiles.length; i++) { + File exportFile = exportFiles[i]; + final Set tiedComponents = fileToComponents.get(exportFile); + + for (Iterator iterator = tiedComponents.iterator(); iterator.hasNext();) { + ExportableApplicationComponent tiedComponent = (ExportableApplicationComponent)iterator.next(); + if (tiedComponent == component) continue; + final ComponentElementProperties elementProperties = componentToContainingListElement.get(tiedComponent); + if (elementProperties != null && !exportFile.equals(file)) { + LOG.assertTrue(file == null, "Component "+component+" serialize itself into "+file+" and "+exportFile); + // found + elementProperties.addComponent(component); + componentToContainingListElement.put(component, elementProperties); + file = exportFile; + } + } + } + return file != null; + } + + public static String chooseSettingsFile(String oldPath, Component parent, final String title, final String description) { + FileChooserDescriptor chooserDescriptor; + chooserDescriptor = new FileChooserDescriptor(true, true, true, true, false, false); + chooserDescriptor.setDescription(description); + chooserDescriptor.setHideIgnored(false); + chooserDescriptor.setTitle(title); + + VirtualFile initialDir; + if (oldPath != null) { + final File oldFile = new File(oldPath); + initialDir = LocalFileSystem.getInstance().findFileByIoFile(oldFile); + if (initialDir == null && oldFile.getParentFile() != null) { + initialDir = LocalFileSystem.getInstance().findFileByIoFile(oldFile.getParentFile()); + } + } + else { + initialDir = null; + } + final VirtualFile[] files = FileChooser.chooseFiles(parent, chooserDescriptor, initialDir); + if (files.length == 0) { + return null; + } + VirtualFile file = files[0]; + String path; + if (file.isDirectory()) { + String defaultName = new File(DEFAULT_PATH).getName(); + path = file.getPath() + "/" + defaultName; + } + else { + path = file.getPath(); + } + return path; + } + + public JComponent getPreferredFocusedComponent() { + return myPathPanel.getTextField(); + } + + protected JComponent createNorthPanel() { + return new JLabel(myDescription); + } + + protected JComponent createCenterPanel() { + return myChooser; + } + + protected JComponent createSouthPanel() { + final JComponent buttons = super.createSouthPanel(); + if (!myShowFilePath) return buttons; + final JPanel panel = new JPanel(new VerticalFlowLayout()); + panel.add(myPathPanel); + panel.add(buttons); + return panel; + } + + Set getExportableComponents() { + final List markedElements = myChooser.getMarkedElements(); + final Set components = new HashSet(); + for (int i = 0; i < markedElements.size(); i++) { + ComponentElementProperties elementProperties = markedElements.get(i); + components.addAll(elementProperties.myComponents); + } + return components; + } + + private static class ComponentElementProperties implements ElementsChooser.ElementProperties { + private final Set myComponents = new HashSet(); + + private boolean addComponent(ExportableApplicationComponent component) { + return myComponents.add(component); + } + + public Icon getIcon() { + return null; + } + + public Color getColor() { + return null; + } + + public String toString() { + String result = ""; + for (Iterator iterator = myComponents.iterator(); iterator.hasNext();) { + ExportableApplicationComponent component = (ExportableApplicationComponent)iterator.next(); + result += (result.length() == 0 ? "" : ", ") + component.getPresentableName(); + } + return result; + } + } + + File getExportFile() { + return new File(myPathPanel.getText()); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.ide.actions.ChooseComponentsToExportDialog"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloneElementAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloneElementAction.java new file mode 100644 index 00000000000..f9d98807362 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloneElementAction.java @@ -0,0 +1,35 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.copy.CopyHandler; + +public class CloneElementAction extends CopyElementAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CloneElementAction"); + + protected void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) { + LOG.assertTrue(elements.length == 1); + CopyHandler.doClone(elements[0]); + } + + protected void updateForEditor(DataContext dataContext, Presentation presentation) { + super.updateForEditor(dataContext, presentation); + presentation.setVisible(false); + } + + protected void updateForToolWindow(String id, DataContext dataContext,Presentation presentation) { + // work only with single selection + PsiElement[] elements = (PsiElement[])dataContext.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + presentation.setEnabled(elements != null && elements.length == 1 && CopyHandler.canCopy(elements)); + presentation.setVisible(true); + + if (!ToolWindowId.COMMANDER.equals(id)) { + presentation.setVisible(false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseActiveTabAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseActiveTabAction.java new file mode 100644 index 00000000000..6bd9614fe52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseActiveTabAction.java @@ -0,0 +1,22 @@ +package com.intellij.ide.actions; + +import com.intellij.ui.content.ContentManagerUtil; +import com.intellij.ui.content.ContentManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; + +public class CloseActiveTabAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(e.getDataContext(), true); + if (contentManager != null && contentManager.canCloseContents()) { + contentManager.removeContent(contentManager.getSelectedContent()); + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + ContentManager contentManager=ContentManagerUtil.getContentManagerFromContext(event.getDataContext(), true); + presentation.setEnabled(contentManager != null && contentManager.canCloseContents()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsAction.java new file mode 100644 index 00000000000..5d9631fb090 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsAction.java @@ -0,0 +1,38 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public class CloseAllEditorsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable(){ + public void run() { + FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); + VirtualFile selectedFile = editorManager.getSelectedFiles()[0]; + VirtualFile[] openFiles = editorManager.getSiblings(selectedFile); + for (int i = 0; i < openFiles.length; i++) { + editorManager.closeFile(openFiles[i]); + } + } + }, "Close All Editors", null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(FileEditorManager.getInstance(project).getSelectedFiles().length > 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java new file mode 100644 index 00000000000..b829d7df3ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java @@ -0,0 +1,40 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public class CloseAllEditorsButActiveAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + FileEditorManagerEx fileEditorManager=FileEditorManagerEx.getInstanceEx(project); + VirtualFile selectedFile=fileEditorManager.getSelectedFiles()[0]; + VirtualFile[] siblings = fileEditorManager.getSiblings(selectedFile); + for(int i=0;i 1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllUnmodifiedEditorsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllUnmodifiedEditorsAction.java new file mode 100644 index 00000000000..3694b0d3bac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseAllUnmodifiedEditorsAction.java @@ -0,0 +1,68 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.EditorComposite; +import com.intellij.openapi.fileEditor.impl.EditorsSplitters; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vcs.FileStatus; + +import java.util.ArrayList; + +public class CloseAllUnmodifiedEditorsAction extends AnAction { + + private ArrayList> getFilesToClose (final AnActionEvent event) { + final ArrayList> res = new ArrayList>(); + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); + final EditorWindow[] windows = editorManager.getWindows (); + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(project); + if (fileStatusManager != null) { + for (int i = 0; i != windows.length; ++ i) { + final EditorWindow window = windows [i]; + final EditorComposite [] editors = window.getEditors (); + for (int j = 0; j < editors.length; j++) { + final EditorComposite editor = editors [j]; + if (!editorManager.isChanged (editor)) { + res.add (Pair.create (editor, window)); + } + } + } + } + return res; + } + + + public void actionPerformed(final AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable(){ + public void run() { + final ArrayList> filesToClose = getFilesToClose (e); + for (int i = 0; i != filesToClose.size (); ++ i) { + final Pair we = filesToClose.get(i); + we.getSecond ().closeFile (we.getFirst ().getFile ()); + } + } + }, "Close All Unmodified Editors", null + ); + } + + public void update(final AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(getFilesToClose (event).size () > 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseEditorAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseEditorAction.java new file mode 100644 index 00000000000..9cb126b80d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseEditorAction.java @@ -0,0 +1,40 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; + +public class CloseEditorAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + CommandProcessor.getInstance().executeCommand( + project, new Runnable(){ + public void run() { + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + final EditorWindow currentWindow = fileEditorManager.getCurrentWindow (); + if (currentWindow != null) { + currentWindow.closeFile(currentWindow.getSelectedFile()); + } + } + }, "Close Active Editor", null + ); + } + + public void update(final AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace())) { + presentation.setText("Close"); + } + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + presentation.setEnabled(fileEditorManager.getCurrentWindow() != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseProjectAction.java new file mode 100644 index 00000000000..7c6b72ef649 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseProjectAction.java @@ -0,0 +1,27 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +/** + * + */ +public class CloseProjectAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + ProjectUtil.closeProject(project); + RecentProjectsManager.getInstance().updateLastProjectPath(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseTabToolbarAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseTabToolbarAction.java new file mode 100644 index 00000000000..b025df6dff6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseTabToolbarAction.java @@ -0,0 +1,17 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.util.IconLoader; + +public abstract class CloseTabToolbarAction extends AnAction { + public CloseTabToolbarAction() { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_ACTIVE_TAB)); + Presentation presentation = getTemplatePresentation(); + presentation.setIcon(IconLoader.getIcon("/actions/cancel.png")); + presentation.setText("Close"); + presentation.setDescription(null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseWindowAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseWindowAction.java new file mode 100644 index 00000000000..0774982ed9c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CloseWindowAction.java @@ -0,0 +1,52 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.wm.impl.IdeFrame; + +import java.awt.*; +import java.awt.event.WindowEvent; + +/** + * @author Vladimir Kondratyev + */ +public class CloseWindowAction extends AnAction{ + public CloseWindowAction(){ + setEnabledInModalContext(true); + } + + private Window getWindow(){ + Window focusedWindow=KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + if(!(focusedWindow instanceof Dialog) && !(focusedWindow instanceof Frame)){ + return null; + } + if(focusedWindow instanceof Dialog){ + Dialog dialog=(Dialog)focusedWindow; + if(!dialog.isUndecorated()){ + return focusedWindow; + }else{ + return null; + } + }else if(!(focusedWindow instanceof IdeFrame)){ + Frame frame=(Frame)focusedWindow; + if(!frame.isUndecorated()){ + return focusedWindow; + }else{ + return null; + } + }else{ + return null; + } + } + + public void actionPerformed(AnActionEvent e){ + Window window=getWindow(); + WindowEvent event=new WindowEvent(window,WindowEvent.WINDOW_CLOSING); + window.dispatchEvent(event); + } + + public void update(AnActionEvent e){ + super.update(e); + e.getPresentation().setEnabled(getWindow()!=null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CodeEditorActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CodeEditorActionGroup.java new file mode 100644 index 00000000000..5305c1e8e4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CodeEditorActionGroup.java @@ -0,0 +1,22 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; + +public class CodeEditorActionGroup extends DefaultActionGroup { + public CodeEditorActionGroup() { + super(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + return; + } + boolean active = ToolWindowManager.getInstance(project).isEditorComponentActive(); + presentation.setVisible(active); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CollapseAllAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CollapseAllAction.java new file mode 100644 index 00000000000..7e99c60ee59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CollapseAllAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.TreeExpander; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; + +public class CollapseAllAction extends TreeCollapseAllActionBase { + protected TreeExpander getExpander(DataContext dataContext) { + TreeExpander treeExpander = (TreeExpander)dataContext.getData(DataConstantsEx.TREE_EXPANDER); + return treeExpander; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CommanderViewActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CommanderViewActionGroup.java new file mode 100644 index 00000000000..2a458322507 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CommanderViewActionGroup.java @@ -0,0 +1,24 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; + +public class CommanderViewActionGroup extends DefaultActionGroup { + public CommanderViewActionGroup() { + super(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + return; + } + String id = ToolWindowManager.getInstance(project).getActiveToolWindowId(); + boolean isCommanderActive = ToolWindowId.COMMANDER.equals(id); + presentation.setVisible(isCommanderActive); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ContextHelpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ContextHelpAction.java new file mode 100644 index 00000000000..97545dae7f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ContextHelpAction.java @@ -0,0 +1,42 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class ContextHelpAction extends AnAction { + private static final Icon myIcon=IconLoader.getIcon("/actions/help.png"); + private final String myHelpID; + + public ContextHelpAction() { + this(null); + } + + public ContextHelpAction(String helpID) { + myHelpID = helpID; + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + String helpId = myHelpID == null ? (String)dataContext.getData(DataConstantsEx.HELP_ID) : myHelpID; + if (helpId != null) { + HelpManager.getInstance().invokeHelp(helpId); + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + if (ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + DataContext dataContext = event.getDataContext(); + String helpId = myHelpID == null ? (String)dataContext.getData(DataConstantsEx.HELP_ID) : myHelpID; + presentation.setEnabled(helpId != null); + } + else { + presentation.setIcon(myIcon); + presentation.setText("Help"); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyAction.java new file mode 100644 index 00000000000..732c695e193 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyAction.java @@ -0,0 +1,25 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.CopyProvider; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; + +public class CopyAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + CopyProvider provider = (CopyProvider)dataContext.getData(DataConstantsEx.COPY_PROVIDER); + if (provider == null) return; + provider.performCopy(dataContext); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + CopyProvider provider = (CopyProvider)dataContext.getData(DataConstantsEx.COPY_PROVIDER); + presentation.setEnabled(provider != null && provider.isCopyEnabled(dataContext)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyElementAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyElementAction.java new file mode 100644 index 00000000000..3723afb4ab3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyElementAction.java @@ -0,0 +1,114 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.refactoring.copy.CopyHandler; + +public class CopyElementAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + }}, "", null + ); + + PsiElement[] elements; + PsiDirectory defaultTargetDirectory; + if (ToolWindowManager.getInstance(project).isEditorComponentActive()) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + PsiClass aClass = getTopLevelClass(editor, project); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + elements = new PsiElement[]{aClass}; + if (aClass == null || !CopyHandler.canCopy(elements)) { + elements = new PsiElement[]{file}; + } + defaultTargetDirectory = file.getContainingDirectory(); + } + else { + Object element = dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT); + defaultTargetDirectory = element instanceof PsiDirectory ? (PsiDirectory)element : null; + elements = (PsiElement[])dataContext.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + } + + doCopy(elements, defaultTargetDirectory); + } + + protected void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) { + CopyHandler.doCopy(elements, defaultTargetDirectory); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + if (ToolWindowManager.getInstance(project).isEditorComponentActive()) { + updateForEditor(dataContext, presentation); + } + else { + String id = ToolWindowManager.getInstance(project).getActiveToolWindowId(); + updateForToolWindow(id, dataContext, presentation); + } + } + + protected void updateForEditor(DataContext dataContext, Presentation presentation) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + + PsiClass topLevelClass = getTopLevelClass(editor, project); + boolean result = topLevelClass != null && CopyHandler.canCopy(new PsiElement[]{topLevelClass}); + + if (!result) { + result = CopyHandler.canCopy(new PsiElement[]{file}); + } + + presentation.setEnabled(result); + presentation.setVisible(true); + } + + protected void updateForToolWindow(String toolWindowId, DataContext dataContext,Presentation presentation) { + PsiElement[] elements = (PsiElement[])dataContext.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + presentation.setEnabled(elements != null && CopyHandler.canCopy(elements)); + presentation.setVisible(true); + } + + private PsiClass getTopLevelClass(final Editor editor, final Project project) { + int offset = editor.getCaretModel().getOffset(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null) return null; + PsiElement element = file.findElementAt(offset); + if (element == null) element = file; + + while (true) { + if (element instanceof PsiFile) break; + if (element instanceof PsiClass && element.getParent() instanceof PsiFile) break; + element = element.getParent(); + } + if (element instanceof PsiJavaFile) { + PsiClass[] classes = ((PsiJavaFile)element).getClasses(); + if (classes.length > 0) { + element = classes[0]; + } + } + return element instanceof PsiClass ? (PsiClass)element : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyPathsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyPathsAction.java new file mode 100644 index 00000000000..b572d8ef66a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CopyPathsAction.java @@ -0,0 +1,44 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.vfs.VirtualFile; + +import java.awt.datatransfer.StringSelection; + +public class CopyPathsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final VirtualFile[] vfa = getFiles(e); + if (vfa == null || vfa.length <= 0) { + return; + } + CopyPasteManager.getInstance().setContents(new StringSelection(getPaths(vfa))); + } + + private String getPaths(VirtualFile[] vfa) { + final StringBuffer buf = new StringBuffer(vfa.length * 64); + for (int idx = 0; idx < vfa.length; idx++) { + if (idx > 0) { + buf.append("\n"); + } + buf.append(vfa[idx].getPresentableUrl()); + } + return buf.toString(); + } + + public void update(AnActionEvent event){ + final VirtualFile[] files = getFiles(event); + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(files != null && files.length > 0); + presentation.setText((files != null && files.length == 1)? "Copy Path" : "Copy Paths"); + } + + private VirtualFile[] getFiles(AnActionEvent e) { + return (VirtualFile[])e.getDataContext().getData(DataConstants.VIRTUAL_FILE_ARRAY); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateClassAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateClassAction.java new file mode 100644 index 00000000000..d78815dd889 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateClassAction.java @@ -0,0 +1,69 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.IdeView; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.util.Icons; +import com.intellij.util.IncorrectOperationException; + +public class CreateClassAction extends CreateElementActionBase { + public CreateClassAction() { + super("Create New Class", "Create New Class", Icons.CLASS_ICON); + } + + protected PsiElement[] invokeDialog(Project project, PsiDirectory directory) { + CreateElementActionBase.MyInputValidator validator = new CreateElementActionBase.MyInputValidator(project, directory); + Messages.showInputDialog(project, "Enter a new class name:", "New Class", Messages.getQuestionIcon(), "", validator); + return validator.getCreatedElements(); + } + + protected String getCommandName() { + return "Create class"; + } + + protected void checkBeforeCreate(String newName, PsiDirectory directory) throws IncorrectOperationException { + directory.checkCreateClass(newName); + } + + protected String getErrorTitle() { + return "Cannot Create Class"; + } + + public void update(AnActionEvent e) { + super.update(e); + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Presentation presentation = e.getPresentation(); + if (presentation.isEnabled()) { + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + PsiDirectory[] dirs = view.getDirectories(); + for (int i = 0; i < dirs.length; i++) { + PsiDirectory dir = dirs[i]; + if (projectFileIndex.isInSourceContent(dir.getVirtualFile()) && dir.getPackage() != null) { + return; + } + } + + presentation.setEnabled(false); + presentation.setVisible(false); + } + } + + protected String getActionName(PsiDirectory directory, String newName) { + return "Creating class " + directory.getPackage().getQualifiedName() + "." + newName; + } + + protected PsiElement[] create(String newName, PsiDirectory directory) throws IncorrectOperationException { + return new PsiElement[]{directory.createClass(newName)}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java new file mode 100644 index 00000000000..e3e5b12363d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java @@ -0,0 +1,209 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.Icons; + +import java.io.File; +import java.util.StringTokenizer; + +public class CreateDirectoryOrPackageAction extends AnAction { + public CreateDirectoryOrPackageAction() { + super("Create new directory or package", "Create new directory or package", null); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + PsiDirectory directory = PackageUtil.getOrChooseDirectory(view); + + if (directory == null) return; + boolean isDirectory = directory.getPackage() == null; + + MyInputValidator validator = new MyInputValidator(project, directory, isDirectory); + Messages.showInputDialog(project, + "Enter new " + (isDirectory ? "directory" : "package") + " name:", + "New " + (isDirectory ? "Directory" : "Package"), + Messages.getQuestionIcon(), + "", + validator); + + if (validator.myCreatedElement == null) return; + + view.selectElement(validator.myCreatedElement); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final PsiDirectory[] directories = view.getDirectories(); + if (directories.length == 0){ + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + presentation.setVisible(true); + presentation.setEnabled(true); + + boolean isPackage = false; + for (int i = 0; i < directories.length; i++) { + if (directories[i].getPackage() != null) { + isPackage = true; + break; + } + } + + if (isPackage) { + presentation.setText("Package"); + presentation.setIcon(Icons.PACKAGE_ICON); + } + else { + presentation.setText("Directory"); + presentation.setIcon(Icons.DIRECTORY_OPEN_ICON); + } + } + + protected class MyInputValidator implements InputValidator { + private Project myProject; + private PsiDirectory myDirectory; + private boolean myIsDirectory; + private PsiElement myCreatedElement = null; + + public MyInputValidator(Project project, PsiDirectory directory, boolean isDirectory) { + myProject = project; + myDirectory = directory; + myIsDirectory = isDirectory; + } + + public boolean checkInput(String inputString){ + return true; + } + + public boolean canClose(String inputString){ + final String subDirName = inputString; + + if (subDirName.length() == 0) { + Messages.showMessageDialog(myProject,"A name should be specified", "Error", Messages.getErrorIcon()); + return false; + } + + //[ven] valentin thinks this is too restrictive + /*if (!myIsDirectory) { + PsiNameHelper helper = PsiManager.getInstance(myProject).getNameHelper(); + if (!helper.isQualifiedName(subDirName)) { + Messages.showMessageDialog(myProject, "A valid package name should be specified", "Error", Messages.getErrorIcon()); + return false; + } + }*/ + + final boolean multiCreation = !myIsDirectory && subDirName.indexOf('.') != -1; + if (!multiCreation) { + try { + myDirectory.checkCreateSubdirectory(subDirName); + } + catch (IncorrectOperationException ex) { + Messages.showMessageDialog( + myProject, + CreateElementActionBase.filterMessage(ex.getMessage()), + "Error", + Messages.getErrorIcon()); + return false; + } + } + + Runnable command = new Runnable() { + public void run() { + final Runnable run = new Runnable() { + public void run() { + LvcsAction lvcsAction = LvcsAction.EMPTY; + try { + String actionName = myIsDirectory ? + "Creating directory " + myDirectory.getVirtualFile().getPresentableUrl() + File.separator + subDirName + : "Creating package " + myDirectory.getPackage().getQualifiedName() + "." + subDirName; + + String directoryPath = myDirectory.getVirtualFile().getPath() + "/" + subDirName; + + lvcsAction = LocalVcs.getInstance(myProject).startAction(actionName, directoryPath, false); + + final PsiDirectory createdDir; + if (myIsDirectory) { + createdDir = myDirectory.createSubdirectory(subDirName); + } + else { + StringTokenizer tokenizer = new StringTokenizer(subDirName, "."); + PsiDirectory dir = myDirectory; + while(tokenizer.hasMoreTokens()) { + String packName = tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) { + PsiDirectory existingDir = dir.findSubdirectory(packName); + if (existingDir != null) { + dir = existingDir; + continue; + } + } + dir = dir.createSubdirectory(packName); + } + createdDir = dir; + } + + + myCreatedElement = createdDir; + + } catch (final IncorrectOperationException ex) { + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run() { + Messages.showMessageDialog( + myProject, + CreateElementActionBase.filterMessage(ex.getMessage()), + "Error", + Messages.getErrorIcon() + ); + } + }); + return; + } + finally { + lvcsAction.finish(); + } + } + }; + ApplicationManager.getApplication().runWriteAction(run); + } + }; + CommandProcessor.getInstance().executeCommand(myProject, command, "Create " + (myIsDirectory ? "directory" : "package"), null); + + return myCreatedElement != null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateElementActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateElementActionBase.java new file mode 100644 index 00000000000..fe51ff0cd83 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateElementActionBase.java @@ -0,0 +1,168 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; + +public abstract class CreateElementActionBase extends AnAction { + protected CreateElementActionBase(String text, String description, Icon icon) { + super(text, description, icon); + } + + /** + * @return created elements. Never null. + */ + protected abstract PsiElement[] invokeDialog(Project project, PsiDirectory directory); + + protected abstract void checkBeforeCreate(String newName, PsiDirectory directory) throws IncorrectOperationException; + + /** + * @return created elements. Never null. + */ + protected abstract PsiElement[] create(String newName, PsiDirectory directory) throws Exception; + + protected abstract String getErrorTitle(); + + protected abstract String getCommandName(); + + protected abstract String getActionName(PsiDirectory directory, String newName); + + public final void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + + final IdeView view = (IdeView) dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null) { + return; + } + + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + + final PsiDirectory dir = PackageUtil.getOrChooseDirectory(view); + if (dir == null) return; + final PsiElement[] createdElements = invokeDialog(project, dir); + + for (int i = 0; i < createdElements.length; i++) { + view.selectElement(createdElements[i]); + } + } + + public void update(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Presentation presentation = e.getPresentation(); + + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final IdeView view = (IdeView) dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null || view.getDirectories().length == 0) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + presentation.setVisible(true); + presentation.setEnabled(true); + } + + protected static String filterMessage(String message) { + if (message == null) return null; + final String ioExceptionPrefix = "java.io.IOException:"; + if (message.startsWith(ioExceptionPrefix)) { + message = message.substring(ioExceptionPrefix.length()); + } + return message; + } + + protected class MyInputValidator implements InputValidator { + private final Project myProject; + private final PsiDirectory myDirectory; + private PsiElement[] myCreatedElements; + + public MyInputValidator(final Project project, final PsiDirectory directory) { + myProject = project; + myDirectory = directory; + myCreatedElements = PsiElement.EMPTY_ARRAY; + } + + public boolean checkInput(final String inputString) { + return true; + } + + public boolean canClose(final String inputString) { + if (inputString.length() == 0) { + Messages.showMessageDialog(myProject, "A name should be specified", "Error", Messages.getErrorIcon()); + return false; + } + + try { + checkBeforeCreate(inputString, myDirectory); + } catch (IncorrectOperationException e) { + Messages.showMessageDialog( + myProject, + filterMessage(e.getMessage()), + getErrorTitle(), + Messages.getErrorIcon() + ); + return false; + } + + final LocalVcs lvcs = LocalVcs.getInstance(myProject); + + final Exception[] exception = new Exception[1]; + + final Runnable command = new Runnable() { + public void run() { + final Runnable run = new Runnable() { + public void run() { + LvcsAction action = LvcsAction.EMPTY; + try { + action = lvcs.startAction(getActionName(myDirectory, inputString), "", false); + myCreatedElements = create(inputString, myDirectory); + } catch (Exception ex) { + exception[0] = ex; + return; + } finally { + action.finish(); + } + } + }; + ApplicationManager.getApplication().runWriteAction(run); + } + }; + CommandProcessor.getInstance().executeCommand(myProject, command, getCommandName(), null); + + if (exception[0] != null){ + Messages.showMessageDialog( + myProject, + filterMessage(exception[0].getMessage()), + getErrorTitle(), + Messages.getErrorIcon() + ); + + } + + return myCreatedElements.length != 0; + } + + public final PsiElement[] getCreatedElements() { + return myCreatedElements; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateFileAction.java new file mode 100644 index 00000000000..c27b03b82ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CreateFileAction.java @@ -0,0 +1,76 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.ex.FileTypeChooser; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.util.Icons; +import com.intellij.util.IncorrectOperationException; + +import java.io.File; + +public class CreateFileAction extends CreateElementActionBase { + public CreateFileAction() { + super("Create New File", "Create New File", Icons.CUSTOM_FILE_ICON); + } + + protected PsiElement[] invokeDialog(final Project project, PsiDirectory directory) { + CreateElementActionBase.MyInputValidator validator = new MyValidator(project, directory); + Messages.showInputDialog(project, "Enter a new file name:", "New File", Messages.getQuestionIcon(), null, validator); + return validator.getCreatedElements(); + } + + protected void checkBeforeCreate(String newName, PsiDirectory directory) throws IncorrectOperationException { + directory.checkCreateFile(newName); + } + + protected PsiElement[] create(String newName, PsiDirectory directory) throws IncorrectOperationException { + return new PsiElement[]{directory.createFile(newName)}; + } + + protected String getActionName(PsiDirectory directory, String newName) { + return "Creating file " + directory.getVirtualFile().getPresentableUrl() + File.separator + newName; + } + + protected String getErrorTitle() { + return "Cannot Create File"; + } + + protected String getCommandName() { + return "Create file"; + } + + private class MyValidator extends CreateElementActionBase.MyInputValidator { + private final Project myProject; + + public boolean checkInput(String inputString) { + return true; + } + + public boolean canClose(String inputString) { + String fileName = inputString; + + if (fileName.length() == 0) { + return super.canClose(inputString); + } +// 27.05.03 [dyoma] investigating the reason... +// FileTypeManagerEx fileTypeManager = FileTypeManagerEx.getInstanceEx(); +// if (fileTypeManager.getExtension(fileName).length()==0) { +// Messages.showMessageDialog(myProject, "Cannot create file with no extension", "Error", Messages.getErrorIcon()); +// return false; +// } + + FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(fileName); + if (type == null) return false; + + return super.canClose(inputString); + } + + public MyValidator(Project project, PsiDirectory directory){ + super(project, directory); + myProject = project; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CutAction.java new file mode 100644 index 00000000000..9705f7cd549 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/CutAction.java @@ -0,0 +1,25 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.CutProvider; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; + +public class CutAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + CutProvider provider = (CutProvider)dataContext.getData(DataConstantsEx.CUT_PROVIDER); + if (provider == null) return; + provider.performCut(dataContext); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + CutProvider provider = (CutProvider)dataContext.getData(DataConstantsEx.CUT_PROVIDER); + presentation.setEnabled(provider != null && provider.isCutEnabled(dataContext)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/DeleteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/DeleteAction.java new file mode 100644 index 00000000000..a6e8c2fe1f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/DeleteAction.java @@ -0,0 +1,63 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.DeleteProvider; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.event.KeyEvent; + +public class DeleteAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.DeleteAction"); + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + DeleteProvider provider = getDeleteProvider(dataContext); + if (provider == null) return; + try { + provider.deleteElement(dataContext); + } + catch (Throwable t) { + if (t instanceof StackOverflowError){ + t.printStackTrace(); + } + LOG.error(t); + } + } + + protected DeleteProvider getDeleteProvider(DataContext dataContext) { + return (DeleteProvider)dataContext.getData(DataConstantsEx.DELETE_ELEMENT_PROVIDER); + } + + public void update(AnActionEvent event){ + String place = event.getPlace(); + Presentation presentation = event.getPresentation(); + if (ActionPlaces.PROJECT_VIEW_POPUP.equals(place) || ActionPlaces.COMMANDER_POPUP.equals(place)) + presentation.setText("_Delete..."); + else + presentation.setText("_Delete"); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + DeleteProvider provider = getDeleteProvider(dataContext); + if (event.getInputEvent() instanceof KeyEvent) { + Object component = dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT); + if (component instanceof JTextComponent) provider = null; // Do not override text deletion + } + presentation.setEnabled(provider != null && provider.canDeleteElement(dataContext)); + } + + public DeleteAction(String text, String description, Icon icon) { + super(text, description, icon); + } + + public DeleteAction() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditFileTemplatesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditFileTemplatesAction.java new file mode 100644 index 00000000000..eb74006a78e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditFileTemplatesAction.java @@ -0,0 +1,18 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.fileTemplates.ui.ConfigureTemplatesDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +public class EditFileTemplatesAction extends AnAction{ + public EditFileTemplatesAction(String text) { + super(text); + } + + public void actionPerformed(AnActionEvent e){ + ConfigureTemplatesDialog dialog = new ConfigureTemplatesDialog((Project)e.getDataContext().getData(DataConstants.PROJECT)); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditSourceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditSourceAction.java new file mode 100644 index 00000000000..17dee87659c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/EditSourceAction.java @@ -0,0 +1,10 @@ + +package com.intellij.ide.actions; + + + +public class EditSourceAction extends BaseNavigateToSourceAction { + public EditSourceAction() { + super(true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExitAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExitAction.java new file mode 100644 index 00000000000..f5ba257f195 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExitAction.java @@ -0,0 +1,17 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.util.SystemInfo; + +public class ExitAction extends AnAction { + public void update(AnActionEvent e) { + e.getPresentation().setVisible(!SystemInfo.isMacSystemMenu); + } + + public void actionPerformed(AnActionEvent e) { + ApplicationManagerEx.getApplicationEx().exit(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExpandAllAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExpandAllAction.java new file mode 100644 index 00000000000..4bea5429a66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExpandAllAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.TreeExpander; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; + +public class ExpandAllAction extends TreeExpandAllActionBase { + protected TreeExpander getExpander(DataContext dataContext) { + TreeExpander treeExpander = (TreeExpander)dataContext.getData(DataConstantsEx.TREE_EXPANDER); + return treeExpander; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportSettingsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportSettingsAction.java new file mode 100644 index 00000000000..68e92751ac2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportSettingsAction.java @@ -0,0 +1,98 @@ +/** + * @author cdr + */ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.ZipUtil; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.*; +import java.util.jar.JarOutputStream; + +public class ExportSettingsAction extends AnAction { + static final String SETTINGS_JAR_MARKER = "IntelliJ IDEA Global Settings"; + + public void actionPerformed(AnActionEvent e) { + List exportableComponents = new ArrayList(); + Map> fileToComponents = getRegisteredComponentsAndFiles(exportableComponents); + + final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(exportableComponents, fileToComponents, true, + "Select Components to Export", + "Please check all components to export:"); + dialog.show(); + if (!dialog.isOK()) return; + Set markedComponents = dialog.getExportableComponents(); + if (markedComponents.size() == 0) return; + Set exportFiles = new HashSet(); + for (Iterator iterator = markedComponents.iterator(); iterator.hasNext();) { + ExportableApplicationComponent component = (ExportableApplicationComponent)iterator.next(); + final File[] files = component.getExportFiles(); + exportFiles.addAll(Arrays.asList(files)); + } + + ApplicationManager.getApplication().saveSettings(); + + try { + final File saveFile = dialog.getExportFile(); + if (saveFile.exists()) { + final int ret = Messages.showOkCancelDialog("Overwrite '"+FileUtil.toSystemDependentName(saveFile.getPath())+"'?", + "File Already Exists", Messages.getWarningIcon()); + if (ret != 0) return; + } + final JarOutputStream output = new JarOutputStream(new FileOutputStream(saveFile)); + final File configPath = new File(PathManager.getConfigPath()); + final HashSet writtenItemRelativePaths = new HashSet(); + for (Iterator iterator = exportFiles.iterator(); iterator.hasNext();) { + File file = iterator.next(); + final String relativePath = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(configPath, file)); + if (file.exists()) { + ZipUtil.addFileOrDirRecursively(output, saveFile, file, relativePath, null, writtenItemRelativePaths); + } + } + final File magicFile = new File(FileUtil.getTempDirectory(), SETTINGS_JAR_MARKER); + magicFile.createNewFile(); + magicFile.deleteOnExit(); + ZipUtil.addFileToZip(output, magicFile, SETTINGS_JAR_MARKER, writtenItemRelativePaths, null); + output.close(); + Messages.showMessageDialog("Settings exported successfully.\n" + + "You can import the settings using 'File|Import Settings' feature.", + "Export Successful", Messages.getInformationIcon()); + } + catch (IOException e1) { + Messages.showErrorDialog("Error writing settings.\n\n"+e1.toString(),"Error Writing File"); + } + } + + public static Map> getRegisteredComponentsAndFiles(List exportableComponents) { + final Class[] interfaces = ApplicationManager.getApplication().getComponentInterfaces(); + Map> fileToComponents = new HashMap>(); + for (int i = 0; i < interfaces.length; i++) { + final Class anInterface = interfaces[i]; + final Object component = ApplicationManager.getApplication().getComponent(anInterface); + if (component instanceof ExportableApplicationComponent) { + ExportableApplicationComponent exportable = (ExportableApplicationComponent)component; + exportableComponents.add(exportable); + final File[] exportFiles = exportable.getExportFiles(); + for (int j = 0; j < exportFiles.length; j++) { + File exportFile = exportFiles[j]; + Set componentsTied = fileToComponents.get(exportFile); + if (componentsTied == null) { + componentsTied = new HashSet(); + fileToComponents.put(exportFile, componentsTied); + } + componentsTied.add(exportable); + } + } + } + return fileToComponents; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileAction.java new file mode 100644 index 00000000000..8177cbd25e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileAction.java @@ -0,0 +1,42 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.ExporterToTextFile; +import com.intellij.ide.util.ExportToFileUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +public class ExportToTextFileAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + ExporterToTextFile exporterToTextFile = getExporter(dataContext); + if (project == null || exporterToTextFile == null) return; + if (!exporterToTextFile.canExport()) return; + + export(project, exporterToTextFile); + } + + public void export(Project project, ExporterToTextFile exporter) { + final ExportToFileUtil.ExportDialogBase dlg = new ExportToFileUtil.ExportDialogBase(project, exporter); + + dlg.show(); + if (!dlg.isOK()) { + return; + } + + ExportToFileUtil.exportTextToFile(project, dlg.getFileName(), dlg.getText()); + exporter.exportedTo(dlg.getFileName()); + } + + protected ExporterToTextFile getExporter(DataContext dataContext) { + ExporterToTextFile exporterToTextFile = (ExporterToTextFile)dataContext.getData(DataConstants.EXPORTER_TO_TEXT_FILE); + return exporterToTextFile; + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + ExporterToTextFile exporterToTextFile = getExporter(dataContext); + presentation.setEnabled(dataContext.getData(DataConstants.PROJECT) != null && exporterToTextFile != null && exporterToTextFile.canExport()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileToolbarAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileToolbarAction.java new file mode 100644 index 00000000000..bb0d6871c0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExportToTextFileToolbarAction.java @@ -0,0 +1,19 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.ExporterToTextFile; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; + +public class ExportToTextFileToolbarAction extends ExportToTextFileAction { + private ExporterToTextFile myExporterToTextFile; + + public ExportToTextFileToolbarAction(ExporterToTextFile exporterToTextFile) { + myExporterToTextFile = exporterToTextFile; + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_EXPORT_TO_TEXT_FILE)); + } + + protected ExporterToTextFile getExporter(DataContext dataContext) { + return myExporterToTextFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExternalJavaDocAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExternalJavaDocAction.java new file mode 100644 index 00000000000..e41b16f7092 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ExternalJavaDocAction.java @@ -0,0 +1,66 @@ +package com.intellij.ide.actions; + +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.jsp.JspFile; + +public class ExternalJavaDocAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return; + } + + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if (element == null) { + Messages.showMessageDialog( + project, + "Please select the element for which you wish to view the documentation", + "No Element Selected", + Messages.getErrorIcon() + ); + return; + } + + + PsiFile context = (PsiFile)dataContext.getData(DataConstants.PSI_FILE); + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + PsiElement originalElement = (context!=null && editor!=null)? context.findElementAt(editor.getCaretModel().getOffset()):null; + try { + element.putUserData(JavaDocManager.ORIGINAL_ELEMENT_KEY,originalElement); + } catch(RuntimeException ex) { + // some UserDataHolder does not support putUserData, e.g. PsiPackage + // tolerate it + } + + JavaDocManager.getInstance(project).openJavaDoc(element); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + boolean enabled = file instanceof PsiJavaFile || + file instanceof JspFile || + file!=null && JavaDocManager.getInstance(project).getProvider(file.getFileType())!=null; + presentation.setEnabled(enabled); + presentation.setVisible(enabled); + } + else{ + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + presentation.setEnabled(element != null); + presentation.setVisible(true); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ForwardAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ForwardAction.java new file mode 100644 index 00000000000..c45863f15c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ForwardAction.java @@ -0,0 +1,24 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +public class ForwardAction extends AnAction{ + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + IdeDocumentHistory.getInstance(project).forward(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + presentation.setEnabled(IdeDocumentHistory.getInstance(project).isForwardAvailable()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoActionBase.java new file mode 100644 index 00000000000..7618cd695bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoActionBase.java @@ -0,0 +1,46 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.gotoByName.ChooseByNamePopup; +import com.intellij.ide.util.gotoByName.GotoSymbolModel; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; + +/** + * Author: msk + */ +public abstract class GotoActionBase extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.GotoActionBase"); + + protected static Class myInAction = null; + + public final void actionPerformed(AnActionEvent e) { + LOG.assertTrue (!getClass ().equals (myInAction)); + try { + myInAction = getClass(); + gotoActionPerformed (e); + } + catch (Throwable t) { + myInAction = null; + } + } + + protected abstract void gotoActionPerformed(AnActionEvent e); + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(!getClass ().equals (myInAction) && project != null); + } + + + //protected abstract void navigateToFile(Project project, PsiElement element); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoClassAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoClassAction.java new file mode 100644 index 00000000000..8878f14886e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoClassAction.java @@ -0,0 +1,42 @@ +package com.intellij.ide.actions; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.ide.util.gotoByName.ChooseByNamePopup; +import com.intellij.ide.util.gotoByName.GotoClassModel2; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.impl.EditorHistoryManager; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + +public class GotoClassAction extends GotoActionBase { + public void gotoActionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.class"); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, new GotoClassModel2(project)); + + popup.invoke(new ChooseByNameBase.Callback() { + public void onClose () { + if (GotoClassAction.class.equals (myInAction)) + myInAction = null; + } + public void elementChosen(Object element) { + ((NavigationItem)element).navigate(true); + } + }, ModalityState.current(), true); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoFileAction.java new file mode 100644 index 00000000000..1a5c4276f2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoFileAction.java @@ -0,0 +1,43 @@ + +package com.intellij.ide.actions; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.ide.util.gotoByName.ChooseByNamePopup; +import com.intellij.ide.util.gotoByName.GotoFileModel; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +/** + * @author Eugene Belyaev + */ +public class GotoFileAction extends GotoActionBase { + public void gotoActionPerformed(AnActionEvent e) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file"); + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project)); + popup.invoke(new ChooseByNameBase.Callback() { + public void onClose () { + if (GotoFileAction.class.equals (myInAction)) + myInAction = null; + } + public void elementChosen(Object element){ + final PsiFile file = (PsiFile)element; + if (file != null){ + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + OpenFileDescriptor descriptor=new OpenFileDescriptor(project, file.getVirtualFile()); + FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + } + }, ModalityState.NON_MMODAL); + } + } + }, ModalityState.current(), true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoLineAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoLineAction.java new file mode 100644 index 00000000000..88b8a7a113e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoLineAction.java @@ -0,0 +1,42 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.util.GotoLineNumberDialog; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; + +public class GotoLineAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + CommandProcessor processor = CommandProcessor.getInstance(); + processor.executeCommand( + project, new Runnable(){ + public void run() { + GotoLineNumberDialog dialog = new GotoLineNumberDialog(project, editor); + dialog.show(); + IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation(); + } + }, + "Go to Line", + null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + presentation.setEnabled(editor != null); + presentation.setVisible(editor != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoSymbolAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoSymbolAction.java new file mode 100644 index 00000000000..9167666cd05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/GotoSymbolAction.java @@ -0,0 +1,34 @@ +package com.intellij.ide.actions; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.ide.util.gotoByName.ChooseByNamePopup; +import com.intellij.ide.util.gotoByName.GotoSymbolModel2; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; + +public class GotoSymbolAction extends GotoActionBase { + + public void gotoActionPerformed(AnActionEvent e) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.symbol"); + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, new GotoSymbolModel2(project)); + popup.invoke(new ChooseByNameBase.Callback() { + public void onClose () + { + if (GotoSymbolAction.class.equals (myInAction)) + myInAction = null; + } + public void elementChosen(Object element) { + ((NavigationItem)element).navigate(true); + } + }, ModalityState.current(), true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HelpTopicsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HelpTopicsAction.java new file mode 100644 index 00000000000..ba222917880 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HelpTopicsAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.help.HelpManager; + +public class HelpTopicsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + HelpManager.getInstance().invokeHelp(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideAllToolWindowsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideAllToolWindowsAction.java new file mode 100644 index 00000000000..f8c75f9a1ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideAllToolWindowsAction.java @@ -0,0 +1,56 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; + +public class HideAllToolWindowsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + + ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project); + + // to clear windows stack + toolWindowManager.clearSideStack(); + //toolWindowManager.activateEditorComponent(); + + String[] ids = toolWindowManager.getToolWindowIds(); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + ToolWindow toolWindow = toolWindowManager.getToolWindow(id); + if (toolWindow.isVisible()) { + toolWindow.hide(null); + } + } + toolWindowManager.activateEditorComponent(); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + String[] ids = toolWindowManager.getToolWindowIds(); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + if (toolWindowManager.getToolWindow(id).isVisible()) { + presentation.setEnabled(true); + return; + } + } + + presentation.setEnabled(false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideToolWindowAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideToolWindowAction.java new file mode 100644 index 00000000000..c2fafe706ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/HideToolWindowAction.java @@ -0,0 +1,50 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; + +public class HideToolWindowAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + + ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project); + String id = toolWindowManager.getActiveToolWindowId(); + if (id == null) { + id = toolWindowManager.getLastActiveToolWindowId(); + } + toolWindowManager.getToolWindow(id).hide(null); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project); + String id = toolWindowManager.getActiveToolWindowId(); + if (id != null) { + presentation.setEnabled(true); + return; + } + + id = toolWindowManager.getLastActiveToolWindowId(); + if (id == null) { + presentation.setEnabled(false); + return; + } + + ToolWindow toolWindow = toolWindowManager.getToolWindow(id); + presentation.setEnabled(toolWindow.isVisible()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ImportSettingsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ImportSettingsAction.java new file mode 100644 index 00000000000..b10202bc1ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ImportSettingsAction.java @@ -0,0 +1,136 @@ +/** + * @author cdr + */ +package com.intellij.ide.actions; + +import com.intellij.ide.startup.StartupActionScriptManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.ZipUtil; + +import java.awt.*; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +public class ImportSettingsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Component component = (Component)dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT); + final String path = ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, + "Import File Location", + "Choose import file path or directory where the file located"); + if (path == null) return; + + try { + final File saveFile = new File(path); + final ZipFile zipFile = new ZipFile(saveFile); + + final ZipEntry magicEntry = zipFile.getEntry(ExportSettingsAction.SETTINGS_JAR_MARKER); + if (magicEntry == null) { + Messages.showErrorDialog("This file contains no settings to import.\n" + + "Please make sure you have generated the file using 'File|Export Settings' feature.", "Invalid File"); + return; + } + + final ArrayList registeredComponents = new ArrayList(); + final Map> filesToComponents = ExportSettingsAction.getRegisteredComponentsAndFiles(registeredComponents); + List components = getComponentsStored(saveFile, registeredComponents); + final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(components, filesToComponents, false, + "Select Components to Import", + "Please check all components to import:"); + dialog.show(); + if (!dialog.isOK()) return; + final Set chosenComponents = dialog.getExportableComponents(); + Set relativeNamesToExtract = new HashSet(); + for (Iterator iterator = chosenComponents.iterator(); iterator.hasNext();) { + ExportableApplicationComponent chosenComponent = (ExportableApplicationComponent)iterator.next(); + final File[] exportFiles = chosenComponent.getExportFiles(); + for (int j = 0; j < exportFiles.length; j++) { + File exportFile = exportFiles[j]; + final File configPath = new File(PathManager.getConfigPath()); + final String relativePath = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(configPath, exportFile)); + relativeNamesToExtract.add(relativePath); + } + } + + final File tempFile = new File(PathManagerEx.getPluginTempPath() + "/" + saveFile.getName()); + FileUtil.copy(saveFile, tempFile); + File outDir = new File(PathManager.getConfigPath()); + final MyFilenameFilter filenameFilter = new MyFilenameFilter(relativeNamesToExtract); + StartupActionScriptManager.ActionCommand unzip = new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter); + StartupActionScriptManager.addActionCommand(unzip); + // remove temp file + StartupActionScriptManager.ActionCommand deleteTemp = new StartupActionScriptManager.DeleteCommand(tempFile); + StartupActionScriptManager.addActionCommand(deleteTemp); + + final int ret = Messages.showOkCancelDialog("Settings imported successfully. You have to restart IDEA to reload the settings." + + "\nShutdown Intellij IDEA?", "Restart Needed", Messages.getQuestionIcon()); + if (ret == 0) { + ApplicationManager.getApplication().exit(); + } + } + catch (ZipException e1) { + Messages.showErrorDialog("Error reading file.\nThere was " +e1.getMessage() +"\n\n" + + "Please make sure you have generated the file using 'File|Export Settings' feature." + , "Invalid File"); + } + catch (IOException e1) { + Messages.showErrorDialog("Error reading file.\n\n"+e1.getMessage(),"Error Reading File"); + } + } + + private static List getComponentsStored(File zipFile, + ArrayList registeredComponents) + throws IOException { + final File configPath = new File(PathManager.getConfigPath()); + + final ArrayList components = new ArrayList(); + for (int i = 0; i < registeredComponents.size(); i++) { + ExportableApplicationComponent component = registeredComponents.get(i); + final File[] exportFiles = component.getExportFiles(); + for (int j = 0; j < exportFiles.length; j++) { + File exportFile = exportFiles[j]; + String relativePath = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(configPath, exportFile)); + if (exportFile.isDirectory()) relativePath += "/"; + if (ZipUtil.isZipContainsEntry(zipFile, relativePath)) { + components.add(component); + break; + } + } + } + return components; + } + + private static class MyFilenameFilter implements FilenameFilter, Serializable { + private final Set myRelativeNamesToExtract; + public MyFilenameFilter(Set relativeNamesToExtract) { + myRelativeNamesToExtract = relativeNamesToExtract; + } + + public boolean accept(File dir, String name) { + if (name.equals(ExportSettingsAction.SETTINGS_JAR_MARKER)) return false; + final File configPath = new File(PathManager.getConfigPath()); + final String relativePath = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(configPath, new File(dir, name))); + for (Iterator iterator = myRelativeNamesToExtract.iterator(); iterator.hasNext();) { + String allowedRelPath = (String)iterator.next(); + if (relativePath.startsWith(allowedRelPath)) return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastEditAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastEditAction.java new file mode 100644 index 00000000000..ae326e03a8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastEditAction.java @@ -0,0 +1,30 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; + +public class JumpToLastEditAction extends AnAction{ + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + IdeDocumentHistory.getInstance(project).navigatePreviousChange(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null){ + presentation.setEnabled(false); + return; + } + presentation.setEnabled(IdeDocumentHistory.getInstance(project).isNavigatePreviousChangeAvailable()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastWindowAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastWindowAction.java new file mode 100644 index 00000000000..69a26ab9ffd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/JumpToLastWindowAction.java @@ -0,0 +1,34 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; + +public class JumpToLastWindowAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(project); + String id = manager.getLastActiveToolWindowId(); + if(id==null||!manager.getToolWindow(id).isAvailable()){ + return; + } + manager.getToolWindow(id).activate(null); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + ToolWindowManagerEx manager=(ToolWindowManagerEx)ToolWindowManager.getInstance(project); + String id = manager.getLastActiveToolWindowId(); + presentation.setEnabled(id != null && manager.getToolWindow(id).isAvailable()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewElementAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewElementAction.java new file mode 100644 index 00000000000..d5f34530354 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewElementAction.java @@ -0,0 +1,53 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.IdeView; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionListPopup; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.ui.ListPopup; + +import javax.swing.*; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +public class NewElementAction extends AnAction { + private final Map myAction2presentationMap = new HashMap(); + + public void actionPerformed(final AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + ListPopup popup = ActionListPopup.createListPopup("New", getGroup(), dataContext, false, false); + KeyboardFocusManager focusManager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); + JComponent focusOwner=(JComponent)focusManager.getFocusOwner(); + Point location = ShowPopupMenuAction.getPopupLocation(focusOwner, dataContext); + SwingUtilities.convertPointToScreen(location, focusOwner); + popup.show(location.x, location.y); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + IdeView ideView = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + if (ideView == null) { + presentation.setEnabled(false); + return; + } + try { + final boolean groupEmpty = ActionListPopup.isGroupEmpty(getGroup(), event, myAction2presentationMap); + presentation.setEnabled(!groupEmpty); + } + finally { + myAction2presentationMap.clear(); + } + } + + private DefaultActionGroup getGroup() { + return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_NEW); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewProjectAction.java new file mode 100644 index 00000000000..b7abef83404 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NewProjectAction.java @@ -0,0 +1,17 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +/** + * + */ +public class NewProjectAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + ProjectUtil.createNewProject((Project)e.getDataContext().getData(DataConstants.PROJECT)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceAction.java new file mode 100644 index 00000000000..7afdd32301b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceAction.java @@ -0,0 +1,18 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.OccurenceNavigator; + +public class NextOccurenceAction extends OccurenceNavigatorActionBase { + protected String getDescription(OccurenceNavigator navigator) { + return navigator.getNextOccurenceActionName(); + } + + protected OccurenceNavigator.OccurenceInfo go(OccurenceNavigator navigator) { + return navigator.goNextOccurence(); + } + + protected boolean hasOccurenceToGo(OccurenceNavigator navigator) { + return navigator.hasNextOccurence(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceToolbarAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceToolbarAction.java new file mode 100644 index 00000000000..34dfae0fd83 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextOccurenceToolbarAction.java @@ -0,0 +1,20 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.OccurenceNavigator; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; + +public class NextOccurenceToolbarAction extends NextOccurenceAction { + private OccurenceNavigator myNavigator; + + public NextOccurenceToolbarAction(OccurenceNavigator navigator) { + myNavigator = navigator; + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_OCCURENCE)); + } + + protected OccurenceNavigator getNavigator(DataContext dataContext) { + return myNavigator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextSplitAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextSplitAction.java new file mode 100644 index 00000000000..581d14f86f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextSplitAction.java @@ -0,0 +1,39 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowManager; + +import javax.swing.*; + +public class NextSplitAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable(){ + public void run() { + final FileEditorManagerEx manager = FileEditorManagerEx.getInstanceEx(project); + manager.setCurrentWindow(manager.getNextWindow(manager.getCurrentWindow())); + } + }, "Go to next split", null + ); + } + + public void update(final AnActionEvent event){ + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final Presentation presentation = event.getPresentation(); + if (project == null) { + presentation.setEnabled(false); + return; + } + final FileEditorManagerEx manager = FileEditorManagerEx.getInstanceEx(project); + final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + presentation.setEnabled (toolWindowManager.isEditorComponentActive() && manager.isInSplitter() && manager.getCurrentWindow() != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextTabAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextTabAction.java new file mode 100644 index 00000000000..b90c6850b33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/NextTabAction.java @@ -0,0 +1,14 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.ArrayUtil; + +public class NextTabAction extends TabNavigationActionBase { + public NextTabAction () { super (+1); } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OccurenceNavigatorActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OccurenceNavigatorActionBase.java new file mode 100644 index 00000000000..2e977c483ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OccurenceNavigatorActionBase.java @@ -0,0 +1,131 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.OccurenceNavigator; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.pom.Navigatable; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerUtil; + +import javax.swing.*; +import java.awt.*; +import java.util.LinkedList; + +abstract class OccurenceNavigatorActionBase extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + + OccurenceNavigator navigator = getNavigator(e.getDataContext()); + if (navigator == null) { + return; + } + OccurenceNavigator.OccurenceInfo occurenceInfo = go(navigator); + if (occurenceInfo == null) { + return; + } + Navigatable descriptor = occurenceInfo.getNavigateable(); + if (descriptor != null) descriptor.navigate(false); + if(occurenceInfo.getOccurenceNumber()==-1||occurenceInfo.getOccurencesCount()==-1){ + return; + } + WindowManager.getInstance().getStatusBar(project).setInfo("Occurrence "+occurenceInfo.getOccurenceNumber()+" of "+occurenceInfo.getOccurencesCount()); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + // make it invisible only in main menu to avoid initial invisibility in toolbars + presentation.setVisible(!ActionPlaces.MAIN_MENU.equals(event.getPlace())); + return; + } + OccurenceNavigator navigator = getNavigator(event.getDataContext()); + if (navigator == null) { + presentation.setEnabled(false); + // make it invisible only in main menu to avoid initial invisibility in toolbars + presentation.setVisible(!ActionPlaces.MAIN_MENU.equals(event.getPlace())); + return; + } + presentation.setVisible(true); + presentation.setEnabled(hasOccurenceToGo(navigator)); + presentation.setText(getDescription(navigator)); + } + + protected abstract OccurenceNavigator.OccurenceInfo go(OccurenceNavigator navigator); + + protected abstract boolean hasOccurenceToGo(OccurenceNavigator navigator); + + protected abstract String getDescription(OccurenceNavigator navigator); + + protected OccurenceNavigator getNavigator(DataContext dataContext) { + ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(dataContext, false); + if (contentManager != null) { + Content content = contentManager.getSelectedContent(); + if (content == null) return null; + JComponent component = content.getComponent(); + return findNavigator(component); + } + + OccurenceNavigator occurenceNavigator = (OccurenceNavigator)getOccurenceNavigatorFromContext(dataContext); + return occurenceNavigator; + } + + private OccurenceNavigator findNavigator(JComponent parent) { + LinkedList queue = new LinkedList(); + queue.addLast(parent); + for (; !queue.isEmpty(); ) { + JComponent component = queue.removeFirst(); + if (component instanceof OccurenceNavigator) return (OccurenceNavigator) component; + if (component instanceof JTabbedPane) { + queue.addLast((JComponent) ((JTabbedPane) component).getSelectedComponent()); + } + else { + for (int i = 0; i < component.getComponentCount(); i++) { + Component child = component.getComponent(i); + if (!(child instanceof JComponent)) continue; + queue.addLast((JComponent) child); + } + } + } + return null; + } + + private static Component getOccurenceNavigatorFromContext(DataContext dataContext) { + Window window = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow(); + + if (window != null) { + Component component = window.getFocusOwner(); + for (Component c = component; c != null; c = c.getParent()) { + if (c instanceof OccurenceNavigator) { + return c; + } + } + } + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + + ToolWindowManagerEx mgr = ToolWindowManagerEx.getInstanceEx(project); + if (!mgr.isEditorComponentActive()) { + return null; + } + + String id = mgr.getLastActiveToolWindowId(); + if (id == null) { + return null; + } + + Component component = mgr.getToolWindow(id).getComponent(); + return component instanceof OccurenceNavigator ? component : null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OnlineDocAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OnlineDocAction.java new file mode 100644 index 00000000000..9d4a47f9d8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OnlineDocAction.java @@ -0,0 +1,14 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +/** + * @author Vladimir Kondratyev + */ +public class OnlineDocAction extends AnAction{ + public void actionPerformed(AnActionEvent e) { + BrowserUtil.launchBrowser("http://www.jetbrains.com/idea/documentation"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenFileAction.java new file mode 100644 index 00000000000..d941977f619 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenFileAction.java @@ -0,0 +1,161 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.ex.FileTypeChooser; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.WindowManager; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileView; +import java.io.File; + +public class OpenFileAction extends AnAction { + private String getLastFilePath(Project project) { + return PropertiesComponent.getInstance(project).getValue("last_opened_file_path"); + } + + private void setLastFilePath(Project project, String path) { + PropertiesComponent.getInstance(project).setValue("last_opened_file_path", path); + } + + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + + String lastFilePath = getLastFilePath(project); + String path = lastFilePath != null ? lastFilePath : RecentProjectsManager.getInstance().getLastProjectPath(); + JFileChooser fileChooser = new JFileChooser(path); + FileView fileView = new FileView() { + public Icon getIcon(File f) { + if (f.isDirectory()) return super.getIcon(f); + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(f.getName()); + return fileType.getIcon(); + } + }; + fileChooser.setFileView(fileView); + fileChooser.setMultiSelectionEnabled(true); + fileChooser.setAcceptAllFileFilterUsed(false); + fileChooser.setDialogTitle("Open File"); + + class TypeFilter extends FileFilter { + private FileType myType; + + public TypeFilter(FileType fileType) { + myType = fileType; + myDescription = myType.getDescription(); + } + + public boolean accept(File f) { + if (f.isDirectory()) return true; + FileType type = FileTypeManager.getInstance().getFileTypeByFileName(f.getName()); + return myType == type; + } + + public String getDescription() { + return myDescription; + } + + private String myDescription; + } + + FileFilter allFilesFilter = new FileFilter() { + public boolean accept(File f) { + return true; + } + + public String getDescription() { + return "All file types"; + } + }; + + fileChooser.addChoosableFileFilter(new TypeFilter(StdFileTypes.JAVA)); + fileChooser.addChoosableFileFilter(new TypeFilter(StdFileTypes.JSP)); + fileChooser.addChoosableFileFilter(new TypeFilter(StdFileTypes.XML)); + fileChooser.addChoosableFileFilter(new TypeFilter(StdFileTypes.HTML)); + fileChooser.addChoosableFileFilter(new TypeFilter(StdFileTypes.PLAIN_TEXT)); + fileChooser.addChoosableFileFilter(allFilesFilter); + + fileChooser.setFileFilter(allFilesFilter); + + if (fileChooser.showOpenDialog(WindowManager.getInstance().suggestParentWindow(project)) != + JFileChooser.APPROVE_OPTION) { + return; + } + File [] files = fileChooser.getSelectedFiles(); + if (files == null) return; + + for (int i = 0; i < files.length; i++) { + File file = files[i]; + + setLastFilePath(project, file.getParent()); + if (isProjectFile(file)) { + int answer = Messages.showYesNoDialog(project, + file.getName() + + " is an IDEA project file.\nWould you like to open this project?", + "Open Project", + Messages.getQuestionIcon()); + if (answer == 0) { + ProjectUtil.openProject(file.getAbsolutePath(), project, false); + return; + } + } + + FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(file.getName()); + if (type == null) return; + + String absolutePath = file.getAbsolutePath(); + openFile(absolutePath, project); + } + } + + public static void openFile(String absolutePath, final Project project) { + String correctPath = absolutePath.replace(File.separatorChar, '/'); + final VirtualFile[] virtualFiles = new VirtualFile[1]; + final String correctPath1 = correctPath; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + virtualFiles[0] = LocalFileSystem.getInstance().refreshAndFindFileByPath(correctPath1); + } + }); + if (virtualFiles[0] == null) return; + + FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + if (editorProviderManager.getProviders(project, virtualFiles[0]).length == 0) { + Messages.showMessageDialog(project, + "Files of this type cannot be opened in IDEA", + "Cannot Open File", + Messages.getErrorIcon()); + return; + } + + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFiles[0]); + FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + } + + public static boolean isProjectFile(File file) { + return FileTypeManager.getInstance().getFileTypeByFileName(file.getName()) == StdFileTypes.IDEA_PROJECT; + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenProjectAction.java new file mode 100644 index 00000000000..282b451106e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OpenProjectAction.java @@ -0,0 +1,51 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.util.Icons; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileView; +import java.awt.*; +import java.io.File; + +public class OpenProjectAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + JFileChooser fileChooser = new JFileChooser(RecentProjectsManager.getInstance().getLastProjectPath()); + FileView fileView = new FileView() { + public Icon getIcon(File f) { + if (f.isDirectory()) return super.getIcon(f); + if (f.isFile() && f.getName().toLowerCase().endsWith(".ipr")) { + return Icons.PROJECT_ICON; + } + return super.getIcon(f); + } + }; + fileChooser.setFileView(fileView); + fileChooser.setAcceptAllFileFilterUsed(false); + fileChooser.setDialogTitle("Open Project"); + fileChooser.setFileFilter( + new FileFilter() { + public boolean accept(File f) { + return f.isDirectory() || f.getAbsolutePath().endsWith(".ipr"); + } + + public String getDescription() { + return "Project files (*.ipr)"; + } + } + ); + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + Window window = WindowManager.getInstance().suggestParentWindow(project); + if (fileChooser.showOpenDialog(window) != JFileChooser.APPROVE_OPTION) return; + File file = fileChooser.getSelectedFile(); + if (file == null) return; + ProjectUtil.openProject(file.getAbsolutePath(), project, false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OtherGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OtherGroup.java new file mode 100644 index 00000000000..c3e09251677 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/OtherGroup.java @@ -0,0 +1,17 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ActionManager; + +public class OtherGroup extends DefaultActionGroup { + public OtherGroup() { + super(); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + presentation.setVisible(getChildrenCount() > 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PasteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PasteAction.java new file mode 100644 index 00000000000..cccf66bac95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PasteAction.java @@ -0,0 +1,25 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.PasteProvider; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; + +public class PasteAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + PasteProvider provider = (PasteProvider)dataContext.getData(DataConstantsEx.PASTE_PROVIDER); + if (provider == null || !provider.isPasteEnabled(dataContext)) return; + provider.performPaste(dataContext); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + + PasteProvider provider = (PasteProvider)dataContext.getData(DataConstantsEx.PASTE_PROVIDER); + presentation.setEnabled(provider != null && provider.isPastePossible(dataContext)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PinActiveTabAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PinActiveTabAction.java new file mode 100644 index 00000000000..0cbbe10bcc6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PinActiveTabAction.java @@ -0,0 +1,89 @@ +package com.intellij.ide.actions; + +import com.intellij.ui.content.ContentManagerUtil; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.wm.ToolWindowManager; + +public class PinActiveTabAction extends ToggleAction { + /** + * @return selected editor or null + */ + private VirtualFile getFile(final DataContext context){ + Project project = (Project)context.getData(DataConstants.PROJECT); + if(project == null){ + return null; + } + + // To provide file from editor manager, editor component should be active + if(!ToolWindowManager.getInstance(project).isEditorComponentActive()){ + return null; + } + + FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + VirtualFile[] selectedFiles = fileEditorManager.getSelectedFiles(); + if(selectedFiles.length != 0){ + return selectedFiles[0]; + } + else{ + return null; + } + } + + /** + * @return selected content or null + */ + private Content getContent(final DataContext context){ + ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(context, true); + if (contentManager == null){ + return null; + } + return contentManager.getSelectedContent(); + } + + public boolean isSelected(AnActionEvent e) { + DataContext context = e.getDataContext(); + VirtualFile file = getFile(context); + if(file != null){ + // 1. Check editor + final Project project = (Project)context.getData(DataConstants.PROJECT); + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + return fileEditorManager.getCurrentWindow().isFilePinned(file); + } + else{ + // 2. Check content + final Content content = getContent(context); + if(content != null){ + return content.isPinned(); + } + else{ + return false; + } + } + } + + public void setSelected(AnActionEvent e, boolean state) { + DataContext context = e.getDataContext(); + VirtualFile file = getFile(context); + if(file != null){ + // 1. Check editor + Project project = (Project)context.getData(DataConstants.PROJECT); + FileEditorManagerEx.getInstanceEx(project).getCurrentWindow ().setFilePinned(file, state); + } + else{ + Content content = getContent(context); // at this point content cannot be null + content.setPinned(state); + } + } + + public void update(AnActionEvent e){ + super.update(e); + Presentation presentation = e.getPresentation(); + DataContext context = e.getDataContext(); + presentation.setEnabled(getFile(context) != null || getContent(context) != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PrevSplitAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PrevSplitAction.java new file mode 100644 index 00000000000..6dfcf137567 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PrevSplitAction.java @@ -0,0 +1,39 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowManager; + +import javax.swing.*; + +public class PrevSplitAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + final CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable(){ + public void run() { + final FileEditorManagerEx manager = FileEditorManagerEx.getInstanceEx(project); + manager.setCurrentWindow(manager.getPrevWindow(manager.getCurrentWindow())); + } + }, "Go to prev split", null + ); + } + + public void update(final AnActionEvent event){ + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final Presentation presentation = event.getPresentation(); + if (project == null) { + presentation.setEnabled(false); + return; + } + final FileEditorManagerEx manager = FileEditorManagerEx.getInstanceEx(project); + final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + presentation.setEnabled (toolWindowManager.isEditorComponentActive() && manager.isInSplitter() && manager.getCurrentWindow() != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceAction.java new file mode 100644 index 00000000000..a9e64239e5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceAction.java @@ -0,0 +1,18 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.OccurenceNavigator; + +public class PreviousOccurenceAction extends OccurenceNavigatorActionBase { + protected String getDescription(OccurenceNavigator navigator) { + return navigator.getPreviousOccurenceActionName(); + } + + protected OccurenceNavigator.OccurenceInfo go(OccurenceNavigator navigator) { + return navigator.goPreviousOccurence(); + } + + protected boolean hasOccurenceToGo(OccurenceNavigator navigator) { + return navigator.hasPreviousOccurence(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceToolbarAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceToolbarAction.java new file mode 100644 index 00000000000..3ffd32b90c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousOccurenceToolbarAction.java @@ -0,0 +1,20 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.OccurenceNavigator; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; + +public class PreviousOccurenceToolbarAction extends PreviousOccurenceAction { + private OccurenceNavigator myNavigator; + + public PreviousOccurenceToolbarAction(OccurenceNavigator navigator) { + myNavigator = navigator; + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_OCCURENCE)); + } + + protected OccurenceNavigator getNavigator(DataContext dataContext) { + return myNavigator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousTabAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousTabAction.java new file mode 100644 index 00000000000..06e9ee2caed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/PreviousTabAction.java @@ -0,0 +1,14 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.ArrayUtil; + +public class PreviousTabAction extends TabNavigationActionBase { + public PreviousTabAction () { super (-1); } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java new file mode 100644 index 00000000000..e6074e8bc9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java @@ -0,0 +1,54 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +/** + * @author max + */ +public class QuickChangeCodeStyleSchemeAction extends QuickSwitchSchemeAction { + protected void fillActions(Project project, DefaultActionGroup group) { + final CodeStyleSettingsManager manager = CodeStyleSettingsManager.getInstance(project); + if (manager.PER_PROJECT_SETTINGS != null) { + group.add(new AnAction("", "", + manager.USE_PER_PROJECT_SETTINGS ? ourCurrentAction : ourNotCurrentAction) { + public void actionPerformed(AnActionEvent e) { + manager.USE_PER_PROJECT_SETTINGS = true; + } + }); + } + + final CodeStyleScheme[] schemes = CodeStyleSchemes.getInstance().getSchemes(); + final CodeStyleScheme currentScheme = CodeStyleSchemes.getInstance().getCurrentScheme(); + + for (int i = 0; i < schemes.length; i++) { + final CodeStyleScheme scheme = schemes[i]; + group.add(new AnAction(scheme.getName(), "", + scheme == currentScheme && !manager.USE_PER_PROJECT_SETTINGS + ? ourCurrentAction + : ourNotCurrentAction) { + public void actionPerformed(AnActionEvent e) { + CodeStyleSchemes.getInstance().setCurrentScheme(scheme); + manager.USE_PER_PROJECT_SETTINGS = false; + EditorFactory.getInstance().refreshAllEditors(); + } + }); + } + } + + protected boolean isEnabled() { + return CodeStyleSchemes.getInstance().getSchemes().length > 1; + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(e.getDataContext().getData(DataConstants.PROJECT) != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeColorSchemeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeColorSchemeAction.java new file mode 100644 index 00000000000..bf8950a0587 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeColorSchemeAction.java @@ -0,0 +1,38 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.project.Project; + +/** + * @author max + */ +public class QuickChangeColorSchemeAction extends QuickSwitchSchemeAction { + protected void fillActions(Project project, DefaultActionGroup group) { + final EditorColorsScheme[] schemes = EditorColorsManager.getInstance().getAllSchemes(); + EditorColorsScheme current = EditorColorsManager.getInstance().getGlobalScheme(); + for (int i = 0; i < schemes.length; i++) { + final EditorColorsScheme scheme = schemes[i]; + group.add(new AnAction(scheme.getName(), "", scheme == current ? ourCurrentAction : ourNotCurrentAction) { + public void actionPerformed(AnActionEvent e) { + EditorColorsManager.getInstance().setGlobalScheme(scheme); + Editor[] editors = EditorFactory.getInstance().getAllEditors(); + for (int i = 0; i < editors.length; i++) { + EditorEx editor = (EditorEx) editors[i]; + editor.reinitSettings(); + } + } + }); + } + } + + protected boolean isEnabled() { + return EditorColorsManager.getInstance().getAllSchemes().length > 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeKeymapAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeKeymapAction.java new file mode 100644 index 00000000000..4b1a69456e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeKeymapAction.java @@ -0,0 +1,32 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.project.Project; + +/** + * @author max + */ +public class QuickChangeKeymapAction extends QuickSwitchSchemeAction { + protected void fillActions(Project project, DefaultActionGroup group) { + final KeymapManagerEx manager = (KeymapManagerEx) KeymapManager.getInstance(); + final Keymap[] keymaps = manager.getAllKeymaps(); + final Keymap current = manager.getActiveKeymap(); + for (int i = 0; i < keymaps.length; i++) { + final Keymap keymap = keymaps[i]; + group.add(new AnAction(keymap.getPresentableName(), "", keymap == current ? ourCurrentAction : ourNotCurrentAction) { + public void actionPerformed(AnActionEvent e) { + manager.setActiveKeymap(keymap); + } + }); + } + } + + protected boolean isEnabled() { + return ((KeymapManagerEx) KeymapManager.getInstance()).getAllKeymaps().length > 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeLookAndFeel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeLookAndFeel.java new file mode 100644 index 00000000000..f54bd7f9e99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeLookAndFeel.java @@ -0,0 +1,33 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.ui.LafManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.project.Project; + +import javax.swing.*; + +/** + * @author max + */ +public class QuickChangeLookAndFeel extends QuickSwitchSchemeAction { + protected void fillActions(Project project, DefaultActionGroup group) { + final LafManager manager = LafManager.getInstance(); + final UIManager.LookAndFeelInfo[] lfs = manager.getInstalledLookAndFeels(); + final UIManager.LookAndFeelInfo current = manager.getCurrentLookAndFeel(); + for (int i = 0; i < lfs.length; i++) { + final UIManager.LookAndFeelInfo lf = lfs[i]; + group.add(new AnAction(lf.getName(), "", lf == current ? ourCurrentAction : ourNotCurrentAction) { + public void actionPerformed(AnActionEvent e) { + manager.setCurrentLookAndFeel(lf); + manager.updateUI(); + } + }); + } + } + + protected boolean isEnabled() { + return LafManager.getInstance().getInstalledLookAndFeels().length > 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeSchemesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeSchemesAction.java new file mode 100644 index 00000000000..e02eec3725e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickChangeSchemesAction.java @@ -0,0 +1,27 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.project.Project; + +/** + * @author max + */ +public class QuickChangeSchemesAction extends QuickSwitchSchemeAction { + protected void fillActions(Project project, DefaultActionGroup group) { + final AnAction[] actions = getGroup().getChildren(null); + for (int i = 0; i < actions.length; i++) { + group.add(actions[i]); + } + } + + protected boolean isEnabled() { + return true; + } + + private DefaultActionGroup getGroup() { + return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_CHANGE_SCHEME); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickSwitchSchemeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickSwitchSchemeAction.java new file mode 100644 index 00000000000..9ad9ef228ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/QuickSwitchSchemeAction.java @@ -0,0 +1,72 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionListPopup; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.ui.ListPopup; + +import javax.swing.*; +import java.awt.*; + +/** + * @author max + */ +public abstract class QuickSwitchSchemeAction extends AnAction { + protected static final Icon ourCurrentAction = IconLoader.getIcon("/diff/currentLine.png"); + protected static final Icon ourNotCurrentAction = EmptyIcon.create(ourCurrentAction.getIconWidth(), ourCurrentAction.getIconHeight()); + + public void actionPerformed(AnActionEvent e) { + Project project = (Project) e.getDataContext().getData(DataConstants.PROJECT); + DefaultActionGroup group = new DefaultActionGroup(); + fillActions(project, group); + showPopup(e, group); + } + + protected abstract void fillActions(Project project, DefaultActionGroup group); + + private void showPopup(AnActionEvent e, DefaultActionGroup group) { + final ListPopup popup = ActionListPopup.createListPopup(e.getPresentation().getText(), group, e.getDataContext(), true, true); + + Rectangle r = getFocusedWindowRect(e); + popup.getWindow().pack(); + Dimension popupSize = popup.getSize(); + int x = r.x + r.width / 2 - popupSize.width / 2; + int y = r.y + r.height / 2 - popupSize.height / 2; + + popup.show(x, y); + } + + private Rectangle getFocusedWindowRect(final AnActionEvent e) { + Project project = (Project) e.getDataContext().getData(DataConstants.PROJECT); + Window window = null; + Component focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent(project); + if (focusedComponent != null) { + if (focusedComponent instanceof Window) { + window = (Window) focusedComponent; + } else { + window = SwingUtilities.getWindowAncestor(focusedComponent); + } + } + if (window == null) { + window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + } + + Rectangle r; + if (window != null) { + r = window.getBounds(); + } else { + r = WindowManagerEx.getInstanceEx().getScreenBounds(); + } + return r; + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(isEnabled()); + } + + protected abstract boolean isEnabled(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RecentProjectsGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RecentProjectsGroup.java new file mode 100644 index 00000000000..41b639d2009 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RecentProjectsGroup.java @@ -0,0 +1,18 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.RecentProjectsManager; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; + +public class RecentProjectsGroup extends ActionGroup { + public AnAction[] getChildren(AnActionEvent e) { + return RecentProjectsManager.getInstance().getRecentProjectsActions(); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + presentation.setEnabled(RecentProjectsManager.getInstance().getRecentProjectsActions().length > 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RedoAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RedoAction.java new file mode 100644 index 00000000000..baa13c235fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RedoAction.java @@ -0,0 +1,50 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.project.Project; + +public class RedoAction extends AnAction { + public RedoAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + + Project project = getProject(editor, dataContext); + UndoManager undoManager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance(); + undoManager.redo(editor); + } + + private Project getProject(FileEditor editor, DataContext dataContext) { + final Project project; + if (editor instanceof TextEditor){ + project = ((TextEditor)editor).getEditor().getProject(); + } + else { + project = (Project)dataContext.getData(DataConstants.PROJECT); + } + return project; + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + + // do not allow global redo in dialogs + if (editor == null && dataContext.getData(DataConstants.IS_MODAL_CONTEXT) == Boolean.TRUE){ + presentation.setEnabled(false); + return; + } + + Project project = getProject(editor, dataContext); + UndoManager undoManager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance(); + boolean b = undoManager.isRedoAvailable(editor); + presentation.setEnabled(b); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RefreshAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RefreshAction.java new file mode 100644 index 00000000000..70bef767109 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RefreshAction.java @@ -0,0 +1,9 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class RefreshAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ReloadFromDiskAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ReloadFromDiskAction.java new file mode 100644 index 00000000000..60444c6abf0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ReloadFromDiskAction.java @@ -0,0 +1,72 @@ + + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; + +public class ReloadFromDiskAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) return; + final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile == null) return; + + int res = Messages.showOkCancelDialog( + project, + "Reload \"" + psiFile.getVirtualFile().getPresentableUrl() + "\" from disk and lose all changes?", + "Reload File", + Messages.getWarningIcon() + ); + if (res != 0) return; + + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + PsiManager.getInstance(project).reloadFromDisk(psiFile); + CommandProcessor.getInstance().markCurrentCommandAsComplex(project); + } + } + ); + } + }, + "Reload from Disk", + null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null){ + presentation.setEnabled(false); + return; + } + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null){ + presentation.setEnabled(false); + return; + } + Document document = editor.getDocument(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (psiFile == null || psiFile.getVirtualFile() == null){ + presentation.setEnabled(false); + return; + } + presentation.setEnabled(document.getModificationStamp() != psiFile.getVirtualFile().getModificationStamp()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RestoreDefaultLayoutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RestoreDefaultLayoutAction.java new file mode 100644 index 00000000000..1785533b6c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RestoreDefaultLayoutAction.java @@ -0,0 +1,29 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.DesktopLayout; + +/** + * @author Vladimir Kondratyev + */ +public final class RestoreDefaultLayoutAction extends AnAction{ + public void actionPerformed(AnActionEvent e){ + Project project=(Project)e.getDataContext().getData(DataConstants.PROJECT); + if(project==null){ + return; + } + DesktopLayout layout=WindowManagerEx.getInstanceEx().getLayout(); + ToolWindowManagerEx.getInstanceEx(project).setLayout(layout); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + presentation.setEnabled((Project)event.getDataContext().getData(DataConstants.PROJECT)!=null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RunGcAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RunGcAction.java new file mode 100644 index 00000000000..f84b3d9d1fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/RunGcAction.java @@ -0,0 +1,20 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class RunGcAction extends AnAction{ + public void actionPerformed(AnActionEvent e){ + /* + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project != null){ + ((PsiManagerImpl)PsiManager.getInstance(project)).getMemoryManager().releaseCodeBlocks(); + } + */ + System.gc(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveAllAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveAllAction.java new file mode 100644 index 00000000000..c3adc2fc469 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveAllAction.java @@ -0,0 +1,12 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; + +public class SaveAllAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + ApplicationManager.getApplication().saveAll(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveFileAsTemplateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveFileAsTemplateAction.java new file mode 100644 index 00000000000..dc695afab35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SaveFileAsTemplateAction.java @@ -0,0 +1,93 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable; +import com.intellij.ide.fileTemplates.ui.ConfigureTemplatesDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.LwRootContainer; +import org.apache.tools.ant.filters.StringInputStream; +import org.jdom.Attribute; +import org.jdom.Document; + +import java.io.CharArrayWriter; + +public class SaveFileAsTemplateAction extends AnAction{ + public void actionPerformed(AnActionEvent e){ + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + String fileText = (String)dataContext.getData(DataConstants.FILE_TEXT); + VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + String extension = file.getExtension(); + String nameWithoutExtension = file.getNameWithoutExtension(); + AllFileTemplatesConfigurable fileTemplateOptions = new AllFileTemplatesConfigurable(); + ConfigureTemplatesDialog dialog = new ConfigureTemplatesDialog(project, fileTemplateOptions); + PsiFile psiFile = (PsiFile)dataContext.getData(DataConstants.PSI_FILE); + if(psiFile instanceof PsiJavaFile){ + PsiJavaFile javaFile = (PsiJavaFile)psiFile; + String packageName = javaFile.getPackageName(); + if ((packageName != null)&&(packageName.length() > 0)){ + fileText = StringUtil.replace(fileText, packageName, "${PACKAGE_NAME}"); + } + PsiClass[] classes = javaFile.getClasses(); + PsiClass psiClass = null; + if((classes != null) && (classes.length > 0)){ + for (int i = 0; i < classes.length; i++){ + PsiClass aClass = classes[i]; + if(nameWithoutExtension.equals(aClass.getName())){ + psiClass = aClass; + break; + } + } + } + if(psiClass != null){ + //todo[myakovlev] ? PsiIdentifier nameIdentifier = psiClass.getNameIdentifier(); + fileText = StringUtil.replace(fileText, nameWithoutExtension,"${NAME}"); + } + } + else if (StdFileTypes.GUI_DESIGNER_FORM.equals(FileTypeManager.getInstance().getFileTypeByFile(file))) { + LwRootContainer rootContainer = null; + try { + rootContainer = Utils.getRootContainer(fileText, null); + } + catch (Exception ignored) { + } + if (rootContainer != null && rootContainer.getClassToBind() != null) { + try { + Document document = JDOMUtil.loadDocument(new StringInputStream(fileText)); + + Attribute attribute = document.getRootElement().getAttribute("bind-to-class"); + attribute.detach(); + + CharArrayWriter writer = new CharArrayWriter(); + JDOMUtil.writeDocument(document, writer, CodeStyleSettingsManager.getSettings(project).getLineSeparator()); + + fileText = writer.toString(); + } + catch (Exception ignored) { + } + } + } + fileTemplateOptions.createNewTemplate(nameWithoutExtension, extension, fileText); + dialog.show(); + } + + public void update(AnActionEvent e){ + DataContext dataContext = e.getDataContext(); + VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + String fileText = (String)dataContext.getData(DataConstants.FILE_TEXT); + e.getPresentation().setEnabled((fileText != null) && (file != null)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchAgainAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchAgainAction.java new file mode 100644 index 00000000000..3758f2f8675 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchAgainAction.java @@ -0,0 +1,47 @@ +package com.intellij.ide.actions; + +import com.intellij.find.FindManager; +import com.intellij.find.FindUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; + +public class SearchAgainAction extends AnAction { + public SearchAgainAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + if(FindManager.getInstance(project).findNextUsageInEditor(editor)) { + return; + } + FindUtil.searchAgain(project, editor); + } + }, + "Find Next", + null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + presentation.setEnabled(editor != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchBackAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchBackAction.java new file mode 100644 index 00000000000..00bfbb3fc6d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SearchBackAction.java @@ -0,0 +1,47 @@ +package com.intellij.ide.actions; + +import com.intellij.find.FindManager; +import com.intellij.find.FindUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; + +public class SearchBackAction extends AnAction { + public SearchBackAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + project, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + if(FindManager.getInstance(project).findPreviousUsageInEditor(editor)) { + return; + } + FindUtil.searchBack(project, editor); + } + }, + "Find Previous", + null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + final FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + presentation.setEnabled(editor != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectAllAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectAllAction.java new file mode 100644 index 00000000000..294a65e6718 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectAllAction.java @@ -0,0 +1,34 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; + +public class SelectAllAction extends AnAction { + public SelectAllAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) return; + CommandProcessor processor = CommandProcessor.getInstance(); + processor.executeCommand( + (Project)dataContext.getData(DataConstants.PROJECT), new Runnable(){ + public void run() { + editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength()); + } + }, + "Select All", + null + ); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Editor editor = (Editor)event.getDataContext().getData(DataConstants.EDITOR); + presentation.setEnabled(editor != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInAction.java new file mode 100644 index 00000000000..4cbf31379be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInAction.java @@ -0,0 +1,110 @@ +package com.intellij.ide.actions; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.SelectInManager; +import com.intellij.ide.SelectInTarget; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ListPopup; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; + +public class SelectInAction extends AnAction { + + public void actionPerformed(AnActionEvent e) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.select.in"); + SelectInContext context = SelectInContext.createContext(e); + if (context == null) return; + invoke(context); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + SelectInContext context = SelectInContext.createContext(event); + if (context == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + } else { + presentation.setEnabled(true); + presentation.setVisible(true); + } + } + + public void invoke(SelectInContext context) { + final SelectInTarget[] targetVector = context.getTargets(); + + final JList list; + final Runnable runnable; + + if (targetVector.length > 0) { + list = new JList(targetVector); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setCellRenderer(new MyListCellRenderer()); + + runnable = new MyRunnable(context, list); + } + else { + list = new JList(new String[] {"No targets available in this context"}); + //list.setSelectionModel(ListSelectionModel.SINGLE_SELECTION); + + runnable = new Runnable() { + public void run() { + // empty runnable + } + }; + } + ListPopup listPopup = new ListPopup( + " Select Target ", + list, + runnable, + context.getProject() + ); + Point p = context.getPoint(); + + listPopup.show(p.x, p.y); + } + + private static final class MyListCellRenderer extends ColoredListCellRenderer{ + private final SimpleTextAttributes myAttributes; + + public MyListCellRenderer(){ + myAttributes=SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES; + } + + protected void customizeCellRenderer( + JList list, + Object value, + int index, + boolean selected, + boolean hasFocus + ){ + append(value.toString(),myAttributes); + } + } + + private static class MyRunnable implements Runnable { + private final JList myList; + private final SelectInContext myContext; + + public MyRunnable(SelectInContext context, JList list) { + myContext = context; + myList = list; + } + + public void run() { + SelectInTarget selected = (SelectInTarget)myList.getSelectedValue(); + if (selected == null) { + // this can be if you click item with Ctrl pressed + return; + } + SelectInManager selectInManager = myContext.getManager(); + selectInManager.moveToTop(selected); + myContext.selectIn(selected); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInContext.java new file mode 100644 index 00000000000..273f6076e58 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SelectInContext.java @@ -0,0 +1,260 @@ +package com.intellij.ide.actions; + +import com.intellij.execution.Location; +import com.intellij.ide.SelectInManager; +import com.intellij.ide.SelectInTarget; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.impl.LoadTextUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.InputEvent; +import java.util.ArrayList; + +abstract class SelectInContext { + private final PopupLocation myPopupLocation; + private final PsiFile myPsiFile; + + protected SelectInContext(PopupLocation popupLocation, PsiFile psiFile) { + myPopupLocation = popupLocation; + myPsiFile = psiFile; + } + + public SelectInManager getManager() { return SelectInManager.getInstance(getProject()); } + public Project getProject() { return myPsiFile.getProject(); } + public SelectInTarget[] getTargets() { return getTargets(myPsiFile); } + public Point getPoint() { return myPopupLocation.getPoint(); } + protected PsiFile getPsiFile() { return myPsiFile; } + + public abstract void selectIn(SelectInTarget selected); + + public static SelectInContext createContext(AnActionEvent event) { + DataContext dataContext = event.getDataContext(); + SelectInContext result = createEditorContext(dataContext); + if (result != null) return result; + + JComponent sourceComponent = getEventComponent(event); + if (sourceComponent == null) return null; + ComponentCenterLocation popupLocation = new ComponentCenterLocation(sourceComponent); + + SelectInContext psiContext = createPsiContext(event, popupLocation); + if (psiContext != null) return psiContext; + + Navigatable descriptor = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + if (!(descriptor instanceof OpenFileDescriptor)) return null; + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + return OpenFileDescriptorContext.create(project, popupLocation, (OpenFileDescriptor)descriptor); + } + + private static SelectInContext createEditorContext(DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR); + if (project == null || editor == null) return null; + VirtualFile file = FileEditorManagerEx.getInstanceEx(project).getFile(editor); + if (file == null) return null; + final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (psiFile == null) return null; + if (editor instanceof TextEditor) { + return new TextEditorContext((TextEditor)editor, psiFile); + } + else { + return new SimpleContext(new ComponentCenterLocation(editor.getComponent()), psiFile); + } + } + + private static SelectInContext createPsiContext(AnActionEvent event, PopupLocation popupLocation) { + final DataContext dataContext = event.getDataContext(); + PsiElement psiElement = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if (psiElement == null || !psiElement.isValid()) { + return null; + } + PsiFile psiFile = psiElement.getContainingFile(); + if (psiFile == null) { + return null; + } + return new SimpleContext(popupLocation, psiFile, psiElement); + } + + private static JComponent getEventComponent(AnActionEvent event) { + InputEvent inputEvent = event.getInputEvent(); + Object source; + if (inputEvent != null && (source = inputEvent.getSource()) instanceof JComponent) { + return (JComponent)source; + } + else { + return Location.safeCast(event.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT), JComponent.class); + } + } + + protected SelectInTarget[] getTargets(PsiFile psiFile) { + ArrayList result = new ArrayList(); + final SelectInTarget[] targets = getManager().getTargets(); + for (int i = 0; i < targets.length; i++) { + SelectInTarget target = targets[i]; + if (target.canSelect(psiFile)) { + result.add(target); + } + } + if (result.size() > 1) { + final String activeToolWindowId = ToolWindowManager.getInstance(getProject()).getActiveToolWindowId(); + if (activeToolWindowId != null) { + SelectInTarget firstTarget = result.get(0); + if (activeToolWindowId.equals(firstTarget.getToolWindowId())) { + boolean shouldMoveToBottom = true; + if (ToolWindowId.PROJECT_VIEW.equals(activeToolWindowId)) { + final String currentMinorViewId = ProjectView.getInstance(getProject()).getCurrentViewId(); + shouldMoveToBottom = (currentMinorViewId != null) && currentMinorViewId.equals(firstTarget.getMinorViewId()); + } + if (shouldMoveToBottom) { + result.remove(0); + result.add(firstTarget); + } + } + } + } + return result.toArray(new SelectInTarget[result.size()]); + } + + private interface PopupLocation { + Point getPoint(); + } + + private static class ComponentCenterLocation implements PopupLocation { + private final JComponent myComponent; + + public ComponentCenterLocation(JComponent component) { + myComponent = component; + } + + public Point getPoint() { + + JViewport viewport = IJSwingUtilities.findParentOfType(myComponent, JViewport.class); + JComponent component; + if (viewport != null) { + component = viewport; + } + else { + component = myComponent; + } + Point p = new Point(component.getWidth() / 2, component.getHeight() / 2); + SwingUtilities.convertPointToScreen(p, component); + return p; + } + } + + private static class EditorCaretLocation implements PopupLocation { + private final Editor editor; + + public EditorCaretLocation(Editor editor) { + this.editor = editor; + } + + public Point getPoint() { + Point p; + Rectangle visibleArea = editor.getScrollingModel().getVisibleArea(); + p = editor.logicalPositionToXY(editor.getCaretModel().getLogicalPosition()); + if (!visibleArea.contains(p)) p = visibleArea.getLocation(); + SwingUtilities.convertPointToScreen(p, editor.getContentComponent()); + return p; + } + } + + private static class TextEditorContext extends SelectInContext { + private final TextEditor myEditor; + + public TextEditorContext(TextEditor editor, PsiFile psiFile) { + super(new EditorCaretLocation(editor.getEditor()), psiFile); + myEditor = editor; + } + + public void selectIn(final SelectInTarget selected) { + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + Runnable runnable = new Runnable() { + public void run() { + PsiElement element = getPsiFile(); + Editor editor = myEditor.getEditor(); + final int offset = editor.getCaretModel().getOffset(); + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + PsiElement e = getPsiFile().findElementAt(offset); + if (e != null) { + element = e; + } + selected.select(element, true); + } + }; + commandProcessor.executeCommand(getProject(), runnable, "Select in " + selected, null); + } + } + + private static class OpenFileDescriptorContext extends SelectInContext { + private final OpenFileDescriptor myDescriptor; + + public OpenFileDescriptorContext(PopupLocation popupLocation, PsiFile psiFile, OpenFileDescriptor descriptor) { + super(popupLocation, psiFile); + myDescriptor = descriptor; + } + + public void selectIn(SelectInTarget selected) { + PsiElement psiElement; + if (myDescriptor.getOffset() >= 0) psiElement = findElementAt(myDescriptor.getOffset()); + else { + String text = LoadTextUtil.loadText(myDescriptor.getFile(), new String[1]).toString(); + psiElement = findElementAt(StringUtil.lineColToOffset(text, myDescriptor.getLine(), myDescriptor.getColumn())); + } + selected.select(psiElement, true); + } + + private PsiElement findElementAt(int offset) { + PsiElement psiElement = getPsiFile().findElementAt(offset); + return psiElement != null ? psiElement : getPsiFile(); + } + + public static SelectInContext create(Project project, PopupLocation popupLocation, OpenFileDescriptor descriptor) { + if (descriptor == null) return null; + VirtualFile file = descriptor.getFile(); + if (file == null || !file.isValid()) return null; + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (psiFile == null) return null; + return new OpenFileDescriptorContext(popupLocation, psiFile, descriptor); + } + } + + private static class SimpleContext extends SelectInContext { + private final PsiElement myElementToSelect; + + public SimpleContext(PopupLocation popupLocation, PsiFile psiFile) { + this(popupLocation, psiFile, psiFile); + } + + public SimpleContext(PopupLocation popupLocation, PsiFile psiFile, PsiElement elementToSelect) { + super(popupLocation, psiFile); + myElementToSelect = elementToSelect; + } + + public void selectIn(SelectInTarget selected) { + selected.select(myElementToSelect, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowModulePropertiesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowModulePropertiesAction.java new file mode 100644 index 00000000000..811ca7c2c02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowModulePropertiesAction.java @@ -0,0 +1,37 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; + +/** + * @author Eugene Zhuravlev + * Date: Feb 8, 2004 + */ +public class ShowModulePropertiesAction extends AnAction{ + + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstantsEx.PROJECT); + if (project == null) { + return; + } + final Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + if (module == null) { + return; + } + ModulesConfigurator.showDialog(project, module.getName(), null, false); + } + + public void update(AnActionEvent e) { + super.update(e); + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstantsEx.PROJECT); + final Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + e.getPresentation().setVisible(project != null && module != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowPopupMenuAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowPopupMenuAction.java new file mode 100644 index 00000000000..8c389c757c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowPopupMenuAction.java @@ -0,0 +1,105 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.impl.EditorComponentImpl; +import com.intellij.openapi.editor.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; + +/** + * @author Vladimir Kondratyev + */ +public class ShowPopupMenuAction extends AnAction{ + public ShowPopupMenuAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(AnActionEvent e){ + KeyboardFocusManager focusManager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); + Component focusOwner=focusManager.getFocusOwner(); + Point popupMenuPoint = getPopupLocation(focusOwner, e.getDataContext()); + + focusOwner.dispatchEvent( + new MouseEvent( + focusOwner, + MouseEvent.MOUSE_PRESSED, + System.currentTimeMillis(),0, + popupMenuPoint.x, + popupMenuPoint.y, + 1, + true + ) + ); + } + + /** + * @return location as close as possible to the action origin. Method has special handling of + * the following components:
    + * - caret offset for editor
    + * - current selected node for tree
    + * - current selected row for list
    + *
    + * The returned point is in focusOwner coordinate system. + * + * @exception java.lang.IllegalArgumentException if focusOwner + * is null + */ + public static Point getPopupLocation(Component focusOwner, DataContext dataContext) { + if (focusOwner == null) { + throw new IllegalArgumentException("focusOwner cannot be null"); + } + final Rectangle visibleRect; + if(focusOwner instanceof JComponent){ + visibleRect = ((JComponent)focusOwner).getVisibleRect(); + } + else{ + visibleRect = new Rectangle(0, 0, focusOwner.getWidth(), focusOwner.getHeight()); + } + Point popupMenuPoint=null; + + if(focusOwner instanceof EditorComponentImpl){ // Editor + Editor editor=(Editor)dataContext.getData(DataConstants.EDITOR); + LogicalPosition logicalPosition=editor.getCaretModel().getLogicalPosition(); + Point p=editor.logicalPositionToXY(logicalPosition); + if(visibleRect.contains(p)){ + popupMenuPoint= p; + } + }else if(focusOwner instanceof JList){ // JList + JList list=(JList)focusOwner; + int firstVisibleIndex=list.getFirstVisibleIndex(); + int lastVisibleIndex=list.getLastVisibleIndex(); + int[] selectedIndices=list.getSelectedIndices(); + for(int i=0;i= 0; i--){ // reverse order of files + VirtualFile file = files[i]; + if(ArrayUtil.find(selectedFiles, file) != 0 && editorProviderManager.getProviders(project, file).length > 0){ + // 1. do not put currently selected file + // 2. do not include file with no corresponding editor providers + model.addElement(file); + } + } + final JList list = new JList(model); + list.addKeyListener( + new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + int index = list.getSelectedIndex(); + if (index == -1 || index >= list.getModel().getSize()){ + return; + } + Object[] values = list.getSelectedValues(); + for (int i = 0; i < values.length; i++) { + VirtualFile file=(VirtualFile)values[i]; + model.removeElement(file); + if(model.getSize() > 0) { + if(model.getSize()==index){ + list.setSelectedIndex(model.getSize()-1); + } else if (model.getSize() > index) { + list.setSelectedIndex(index); + } + }else{ + list.clearSelection(); + } + EditorHistoryManager.getInstance(project).removeFile(file); + } + } + } + } + ); + Runnable runnable = new Runnable() { + public void run() { + int index = list.getSelectedIndex(); + if (index == -1 || index >= list.getModel().getSize()){ + return; + } + VirtualFile file = (VirtualFile)list.getSelectedValue(); + FileEditorManager.getInstance(project).openFile(file, true); + } + }; + + if (list.getModel().getSize() == 0) { + list.clearSelection(); + } + new MyListSpeedSearch(list); + + Window window = null; + + Component focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent(project); + if(focusedComponent!=null){ + if(focusedComponent instanceof Window){ + window=(Window)focusedComponent; + }else{ + window=SwingUtilities.getWindowAncestor(focusedComponent); + } + } + if (window == null) { + window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + } + + Rectangle r; + if (window != null) { + r = window.getBounds(); + } + else { + r = WindowManagerEx.getInstanceEx().getScreenBounds(); + } + + ListPopup popup = new MyListPopup(list, runnable, project); + + if (model.getSize() > 0) { + Dimension listPreferredSize = list.getPreferredSize(); + list.setVisibleRowCount(0); + Dimension viewPreferredSize = new Dimension(listPreferredSize.width, Math.min(listPreferredSize.height, r.height - 20)); + ((JViewport)list.getParent()).setPreferredSize(viewPreferredSize); + } + + popup.getWindow().pack(); + Dimension popupSize=popup.getSize(); + int x = r.x + r.width/2 - popupSize.width/2; + int y = r.y + r.height/2 - popupSize.height/2; + + popup.show(x,y); + } + + private static class MyListPopup extends ListPopup { + public MyListPopup(JList list, Runnable runnable, Project project) { + super(" Recent Files ", list, runnable, project); + list.setCellRenderer(new RecentFilesRenderer(project)); + } + + // TODO[anton,vova] use actions and local shortcuts instead + protected KeyStroke[] getAdditionalSelectKeystrokes() { + Shortcut[] shortcuts=KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_EDIT_SOURCE); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + return new KeyStroke[] {((KeyboardShortcut)shortcut).getFirstKeyStroke()}; + } + } + return new KeyStroke[0]; + } + } + + private static class RecentFilesRenderer extends ColoredListCellRenderer { + private final Project myProject; + + public RecentFilesRenderer(Project project) { + myProject = project; + } + + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + if (value instanceof VirtualFile) { + VirtualFile virtualFile = (VirtualFile)value; + String name = virtualFile.getName(); + setIcon(IconUtilEx.getIcon(virtualFile, Iconable.ICON_FLAG_READ_STATUS, myProject)); + FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(virtualFile); + TextAttributes attributes = new TextAttributes(fileStatus.getColor(), null, null, EffectType.LINE_UNDERSCORE, + Font.PLAIN); + append(name, SimpleTextAttributes.fromTextAttributes(attributes)); + } + } + } + + private static class MyListSpeedSearch extends ListSpeedSearch { + public MyListSpeedSearch(JList list) { + super(list); + } + + protected String getElementText(Object element) { + return element instanceof VirtualFile ? ((VirtualFile)element).getName() : null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsAction.java new file mode 100644 index 00000000000..27a3fb468d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsAction.java @@ -0,0 +1,27 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.options.ex.IdeConfigurablesGroup; +import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; + +public class ShowSettingsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + project = ProjectManager.getInstance().getDefaultProject(); + } + + ConfigurableGroup[] group = new ConfigurableGroup[]{ + new ProjectConfigurablesGroup(project), + new IdeConfigurablesGroup() + }; + + ShowSettingsUtil.getInstance().showSettingsDialog(project, group); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsUtilImpl.java new file mode 100644 index 00000000000..c4833ed4751 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowSettingsUtilImpl.java @@ -0,0 +1,120 @@ +package com.intellij.ide.actions; + +import com.intellij.application.options.CodeStyleSchemesConfigurable; +import com.intellij.application.options.ProjectCodeStyleConfigurable; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.options.ex.ControlPanelSettingsEditor; +import com.intellij.openapi.options.ex.ExplorerSettingsEditor; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +import java.awt.*; + +/** + * @author max + */ +public class ShowSettingsUtilImpl extends ShowSettingsUtil implements ApplicationComponent { + private static final String PREFER_CLASSIC_OPTIONS_EDITOR = "PREFER_CLASSIC_OPTIONS_EDITOR"; + + public void showSettingsDialog(Project project, ConfigurableGroup[] group) { + if ("true".equals(PropertiesComponent.getInstance().getValue(PREFER_CLASSIC_OPTIONS_EDITOR))) { + showExplorerOptions(project, group); + } + else { + showControlPanelOptions(project, group, null); + } + } + + public void showControlPanelOptions(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) { + PropertiesComponent.getInstance().setValue(PREFER_CLASSIC_OPTIONS_EDITOR, "false"); + + ControlPanelSettingsEditor editor = new ControlPanelSettingsEditor(project, groups, preselectedConfigurable); + editor.show(); + } + + public void showExplorerOptions(Project project, ConfigurableGroup[] group) { + PropertiesComponent.getInstance().setValue(PREFER_CLASSIC_OPTIONS_EDITOR, "true"); + ExplorerSettingsEditor editor = new ExplorerSettingsEditor(project, group); + editor.show(); + } + + public boolean editConfigurable(Project project, Configurable configurable) { + final SingleConfigurableEditor configurableEditor = new SingleConfigurableEditor(project, configurable); + configurableEditor.show(); + return configurableEditor.isOK(); + } + + public boolean editConfigurable(Project project, String dimensionServiceKey, Configurable configurable) { + final SingleConfigurableEditor configurableEditor = new SingleConfigurableEditor(project, configurable, dimensionServiceKey); + configurableEditor.show(); + return configurableEditor.isOK(); + } + + public boolean editConfigurable(Component parent, Configurable configurable) { + final SingleConfigurableEditor configurableEditor = new SingleConfigurableEditor(parent, configurable); + configurableEditor.show(); + return configurableEditor.isOK(); + } + + public boolean editConfigurable(Component parent, String dimensionServiceKey,Configurable configurable) { + final SingleConfigurableEditor configurableEditor = new SingleConfigurableEditor(parent, configurable, dimensionServiceKey); + configurableEditor.show(); + return configurableEditor.isOK(); + } + + public boolean editConfigurable(Project project, Configurable configurable, Runnable advancedInitialization) { + SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable); + advancedInitialization.run(); + editor.show(); + return editor.isOK(); + } + + /** + * Shows code style settings sutable for the project passed. I.e. it shows project code style page if one + * is configured to use own code style scheme or global one in other case. + * @param project + * @return Returns true if settings were modified during editing session. + */ + public boolean showCodeStyleSettings(Project project, final Class pageToSelect) { + CodeStyleSettingsManager settingsManager = CodeStyleSettingsManager.getInstance(project); + boolean usePerProject = settingsManager.USE_PER_PROJECT_SETTINGS; + CodeStyleSettings savedSettings = (CodeStyleSettings)settingsManager.getCurrentSettings().clone(); + if (usePerProject) { + final ProjectCodeStyleConfigurable configurable = ProjectCodeStyleConfigurable.getInstance(project); + Runnable selectPage = new Runnable() { + public void run() { + if (pageToSelect != null) { + configurable.selectPage(pageToSelect); + } + } + }; + editConfigurable(project, configurable, selectPage); + } + else { + final CodeStyleSchemesConfigurable configurable = CodeStyleSchemesConfigurable.getInstance(); + Runnable selectPage = new Runnable() { + public void run() { + if (pageToSelect != null) { + configurable.selectPage(pageToSelect); + } + } + }; + editConfigurable(project, configurable, selectPage); + } + + return !savedSettings.equals(settingsManager.getCurrentSettings()); + } + + public String getComponentName() { + return "ShowSettingsUtil"; + } + + public void initComponent() {} + public void disposeComponent() {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowTipsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowTipsAction.java new file mode 100644 index 00000000000..c9fb4718992 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ShowTipsAction.java @@ -0,0 +1,17 @@ +package com.intellij.ide.actions; + +import com.intellij.ide.util.TipDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class ShowTipsAction extends AnAction { + private static TipDialog ourTipDialog; + + public void actionPerformed(AnActionEvent e) { + if (ourTipDialog != null && ourTipDialog.isVisible()) { + ourTipDialog.dispose(); + } + ourTipDialog = new TipDialog(); + ourTipDialog.show(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitAction.java new file mode 100644 index 00000000000..1ba9e63a1a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitAction.java @@ -0,0 +1,40 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +/** + * @author Vladimir Kondratyev + */ +public abstract class SplitAction extends AnAction{ + private final int myOrientation; + + protected SplitAction(final int orientation){ + myOrientation = orientation; + } + + public void actionPerformed(final AnActionEvent event) { + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + fileEditorManager.createSplitter (myOrientation); + } + + public void update(final AnActionEvent event) { + final Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + final Presentation presentation = event.getPresentation(); + presentation.setText (myOrientation == SwingConstants.VERTICAL ? "Split Vertically" : "Split Horizontally"); + if (project == null) { + presentation.setEnabled(false); + return; + } + final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + presentation.setEnabled(fileEditorManager.hasOpenedFile ()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitHorizontalAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitHorizontalAction.java new file mode 100644 index 00000000000..8e0fcda6a5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitHorizontalAction.java @@ -0,0 +1,14 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; + +import javax.swing.*; + +/** + * @author Vladimir Kondratyev + */ +public final class SplitHorizontalAction extends SplitAction{ + public SplitHorizontalAction() { + super(SwingConstants.VERTICAL); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitVerticalAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitVerticalAction.java new file mode 100644 index 00000000000..dd22d08f609 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SplitVerticalAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.actions; + +import javax.swing.*; + +/** + * @author Vladimir Kondratyev + */ +public final class SplitVerticalAction extends SplitAction{ + public SplitVerticalAction() { + super(SwingConstants.HORIZONTAL); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/StoreDefaultLayoutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/StoreDefaultLayoutAction.java new file mode 100644 index 00000000000..f65e67e3d2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/StoreDefaultLayoutAction.java @@ -0,0 +1,29 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.DesktopLayout; + +/** + * @author Vladimir Kondratyev + */ +public class StoreDefaultLayoutAction extends AnAction{ + public void actionPerformed(AnActionEvent e){ + Project project=(Project)e.getDataContext().getData(DataConstants.PROJECT); + if(project==null){ + return; + } + DesktopLayout layout=ToolWindowManagerEx.getInstanceEx(project).getLayout(); + WindowManagerEx.getInstanceEx().setLayout(layout); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + presentation.setEnabled((Project)event.getDataContext().getData(DataConstants.PROJECT)!=null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SwapPanelsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SwapPanelsAction.java new file mode 100644 index 00000000000..d1f708a8063 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SwapPanelsAction.java @@ -0,0 +1,30 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.commander.Commander; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; + +public class SwapPanelsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + Commander.getInstance(project).swapPanels(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + String id = windowManager.getActiveToolWindowId(); + presentation.setEnabled(ToolWindowId.COMMANDER.equals(id)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SyncViewsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SyncViewsAction.java new file mode 100644 index 00000000000..11e4d49f7d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SyncViewsAction.java @@ -0,0 +1,33 @@ + +package com.intellij.ide.actions; + +import com.intellij.ide.commander.Commander; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; + +public class SyncViewsAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + Commander.getInstance(project).syncViews(); + } + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + String id = windowManager.getActiveToolWindowId(); + boolean value=ToolWindowId.COMMANDER.equals(id); + presentation.setEnabled(value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SynchronizeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SynchronizeAction.java new file mode 100644 index 00000000000..c8e99103d41 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/SynchronizeAction.java @@ -0,0 +1,36 @@ + +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFileManager; + +public class SynchronizeAction extends AnAction { + private final boolean myAsynchronous; + + public SynchronizeAction() { + this(true); + } + + public SynchronizeAction(boolean asynchronous) { + myAsynchronous = asynchronous; + } + + public void actionPerformed(AnActionEvent e) { + FileDocumentManager.getInstance().saveAllDocuments(); + final VirtualFileManager vfMan = VirtualFileManager.getInstance(); + Runnable synchronizeRunnable = new Runnable() { + public void run() { + vfMan.refresh(myAsynchronous); + } + }; + if (myAsynchronous) { + ApplicationManager.getApplication().runReadAction(synchronizeRunnable); + } + else { + ApplicationManager.getApplication().runWriteAction(synchronizeRunnable); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TabNavigationActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TabNavigationActionBase.java new file mode 100644 index 00000000000..c53aa3ed566 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TabNavigationActionBase.java @@ -0,0 +1,86 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.ArrayUtil; + +abstract class TabNavigationActionBase extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.TabNavigationActionBase"); + + private final int myDir; + + TabNavigationActionBase (final int dir) { + LOG.assertTrue (dir == 1 || dir == -1); + myDir = dir; + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return; + } + + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + + if (windowManager.isEditorComponentActive()) { + doNavigate(project); + return; + } + + ContentManager contentManager = (ContentManager)dataContext.getData(DataConstantsEx.CONTENT_MANAGER); + if (contentManager == null) return; + doNavigate(contentManager); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + presentation.setEnabled(false); + if (project == null) { + return; + } + final ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + if (windowManager.isEditorComponentActive()) { + final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); + final EditorWindow currentWindow = editorManager.getCurrentWindow (); + if (currentWindow != null) { + final VirtualFile[] files = currentWindow.getFiles(); + presentation.setEnabled(files.length > 1); + } + return; + } + + ContentManager contentManager = (ContentManager)dataContext.getData(DataConstantsEx.CONTENT_MANAGER); + presentation.setEnabled(contentManager != null && contentManager.getContentCount() > 1); + } + + private void doNavigate(ContentManager contentManager) { + contentManager.selectPreviousContent(); + } + + private void doNavigate(Project project) { + VirtualFile selectedFile = FileEditorManager.getInstance(project).getSelectedFiles()[0]; + navigateImpl(project, selectedFile, myDir); + } + + public static void navigateImpl(Project project, VirtualFile selectedFile, final int dir){ + LOG.assertTrue (dir == 1 || dir == -1); + final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); + final EditorWindow currentWindow = editorManager.getCurrentWindow (); + final VirtualFile[] files = currentWindow.getFiles(); + int index = ArrayUtil.find(files, selectedFile); + LOG.assertTrue(index != -1); + editorManager.openFile(files[(index + files.length + dir) % files.length], false); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TemplateProjectPropertiesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TemplateProjectPropertiesAction.java new file mode 100644 index 00000000000..9f49bc0533c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/TemplateProjectPropertiesAction.java @@ -0,0 +1,18 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; + +public class TemplateProjectPropertiesAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject(); + ShowSettingsUtil.getInstance().showSettingsDialog(defaultProject, new ConfigurableGroup[]{ + new ProjectConfigurablesGroup(defaultProject) + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleDockModeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleDockModeAction.java new file mode 100644 index 00000000000..83001f5d822 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleDockModeAction.java @@ -0,0 +1,60 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ToolWindowType; +import com.intellij.openapi.wm.ToolWindow; + +public class ToggleDockModeAction extends ToggleAction{ + + public boolean isSelected(AnActionEvent event){ + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return false; + } + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + String id=windowManager.getActiveToolWindowId(); + if(id==null){ + return false; + } + return ToolWindowType.DOCKED==windowManager.getToolWindow(id).getType(); + } + + public void setSelected(AnActionEvent event,boolean flag){ + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + String id=windowManager.getActiveToolWindowId(); + if(id==null){ + return; + } + ToolWindow toolWindow=windowManager.getToolWindow(id); + ToolWindowType type=toolWindow.getType(); + if(ToolWindowType.DOCKED==type){ + toolWindow.setType(ToolWindowType.SLIDING, null); + } else if(ToolWindowType.SLIDING==type){ + toolWindow.setType(ToolWindowType.DOCKED, null); + } + } + + public void update(AnActionEvent event){ + super.update(event); + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + ToolWindowManager mgr=ToolWindowManager.getInstance(project); + String id=mgr.getActiveToolWindowId(); + if(id==null){ + presentation.setEnabled(false); + return; + } + ToolWindow toolWindow=mgr.getToolWindow(id); + presentation.setEnabled(toolWindow.isAvailable()&&ToolWindowType.FLOATING!=toolWindow.getType()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFloatingModeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFloatingModeAction.java new file mode 100644 index 00000000000..51e3fe71fcc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFloatingModeAction.java @@ -0,0 +1,56 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ToolWindowType; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; + +public class ToggleFloatingModeAction extends ToggleAction{ + + public boolean isSelected(AnActionEvent event){ + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return false; + } + ToolWindowManager windowManager = ToolWindowManager.getInstance(project); + String id=windowManager.getActiveToolWindowId(); + if(id==null){ + return false; + } + return ToolWindowType.FLOATING==windowManager.getToolWindow(id).getType(); + } + + public void setSelected(AnActionEvent event,boolean flag){ + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + String id=ToolWindowManager.getInstance(project).getActiveToolWindowId(); + if(id==null){ + return; + } + ToolWindowManagerEx mgr=ToolWindowManagerEx.getInstanceEx(project); + ToolWindowEx toolWindow=(ToolWindowEx)mgr.getToolWindow(id); + ToolWindowType type=toolWindow.getType(); + if(ToolWindowType.FLOATING==type){ + toolWindow.setType(toolWindow.getInternalType(), null); + }else{ + toolWindow.setType(ToolWindowType.FLOATING, null); + } + } + + public void update(AnActionEvent event){ + super.update(event); + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + ToolWindowManager mgr=ToolWindowManager.getInstance(project); + String id=mgr.getActiveToolWindowId(); + presentation.setEnabled(id!=null&&mgr.getToolWindow(id).isAvailable()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFullScreenModeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFullScreenModeAction.java new file mode 100644 index 00000000000..1b16b664ec1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/actions/ToggleFullScreenModeAction.java @@ -0,0 +1,98 @@ +package com.intellij.ide.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ToolWindowType; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.IdeFrame; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +public final class ToggleFullScreenModeAction extends ToggleAction{ + private static final String PROP_BOUNDS_BEFORE_FULL_SCREEN="boundsBeforeFullScreen"; + + private static IdeFrame getFrame(AnActionEvent e){ + WindowManagerEx windowManagerEx=WindowManagerEx.getInstanceEx(); + Project project=(Project)e.getDataContext().getData(DataConstants.PROJECT); + return windowManagerEx.getFrame(project); + } + + public boolean isSelected(AnActionEvent e){ + IdeFrame frame=getFrame(e); + return frame.getGraphicsConfiguration().getDevice().getFullScreenWindow()==frame; + } + + public void setSelected(AnActionEvent e,boolean state){ + // Hide all all visible floating tool windows. + Project project=(Project)e.getDataContext().getData(DataConstants.PROJECT); + if(project!=null){ + ToolWindowManager toolWindowManager=ToolWindowManager.getInstance(project); + String[] ids=toolWindowManager.getToolWindowIds(); + for(int i=0;i filesList = new ArrayList(); + VirtualFile[] files=(VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + for(int i=0;files!=null&&i0); + } + + public void actionPerformed(final AnActionEvent e){ + ApplicationManager.getApplication().runWriteAction( + new Runnable(){ + public void run(){ + // Save all documents. We won't be able to save changes to the files that became read-only afterwards. + FileDocumentManager.getInstance().saveAllDocuments(); + + try{ + VirtualFile[] files=getFiles(e.getDataContext()); + for(int i=0;i ourId2Text; + static{ + ourId2Text = new HashMap(); + ourId2Text.put(ToolWindowId.COMMANDER, new MyDescriptor("&Commander", IconLoader.getIcon("/general/toolWindowCommander.png"))); + ourId2Text.put(ToolWindowId.MESSAGES_WINDOW, new MyDescriptor("&Messages", IconLoader.getIcon("/general/toolWindowMessages.png"))); + ourId2Text.put(ToolWindowId.PROJECT_VIEW, new MyDescriptor("&Project", IconLoader.getIcon("/general/toolWindowProject.png"))); + ourId2Text.put(ToolWindowId.STRUCTURE_VIEW, new MyDescriptor("&Structure", IconLoader.getIcon("/general/toolWindowStructure.png"))); + ourId2Text.put(ToolWindowId.ANT_BUILD, new MyDescriptor("Ant &Build", IconLoader.getIcon("/general/toolWindowAnt.png"))); + ourId2Text.put(ToolWindowId.DEBUG, new MyDescriptor("Debug", IconLoader.getIcon("/general/toolWindowDebugger.png"))); + ourId2Text.put(ToolWindowId.RUN, new MyDescriptor("&Run", IconLoader.getIcon("/general/toolWindowRun.png"))); + ourId2Text.put(ToolWindowId.FIND, new MyDescriptor("F&ind", IconLoader.getIcon("/general/toolWindowFind.png"))); + ourId2Text.put(ToolWindowId.CVS, new MyDescriptor("C&VS", IconLoader.getIcon("/general/toolWindowCvs.png"))); + ourId2Text.put(ToolWindowId.HIERARCHY, new MyDescriptor("Hierarch&y", IconLoader.getIcon("/general/toolWindowHierarchy.png"))); + ourId2Text.put(ToolWindowId.TODO_VIEW, new MyDescriptor("TODO", IconLoader.getIcon("/general/toolWindowTodo.png"))); + ourId2Text.put(ToolWindowId.INSPECTION, new MyDescriptor("I&nspection", IconLoader.getIcon("/general/toolWindowInspection.png"))); + ourId2Text.put(ToolWindowId.ASPECTS_VIEW, new MyDescriptor("Aspects", IconLoader.getIcon("/general/toolWindowInspection.png"))); + } + + private final ArrayList myChildren; + private final MyToolWindowManagerListener myToolWindowManagerListener; + + public ToolWindowsGroup(ProjectManager projectManager){ + myChildren = new ArrayList(); + myToolWindowManagerListener=new MyToolWindowManagerListener(); + projectManager.addProjectManagerListener(new MyProjectManagerListener()); + } + + public AnAction[] getChildren(AnActionEvent e){ + return myChildren.toArray(new AnAction[myChildren.size()]); + } + + /** + * Registers action that activates tool window with specified id. + */ + private void addActionForToolWindow(final String id){ + // Check that tool window with the same ID isn't already registered + for(Iterator i=myChildren.iterator();i.hasNext();){ + ActivateToolWindowAction action=(ActivateToolWindowAction)i.next(); + if(action.getToolWindowId().equals(id)){ + return; + } + } + // Register an action for activating this tool window + final MyDescriptor descriptor = ourId2Text.get(id); + + final String text = descriptor != null ? descriptor.myText : id; + final Icon icon = descriptor != null ? descriptor.myIcon : null; + + ActivateToolWindowAction action = new ActivateToolWindowAction(id, text, icon); + ActionManager.getInstance().registerAction(ActivateToolWindowAction.getActionIdForToolWindow(id),action); + myChildren.add(action); + Collections.sort(myChildren,MyActionComparator.ourInstance); + } + + private final class MyProjectManagerListener extends ProjectManagerAdapter{ + public void projectClosed(Project project){ + ToolWindowManagerEx.getInstanceEx(project).removeToolWindowManagerListener(myToolWindowManagerListener); + } + + public void projectOpened(Project project){ + final ToolWindowManagerEx toolWindowManager=ToolWindowManagerEx.getInstanceEx(project); + final String[] ids=toolWindowManager.getToolWindowIds(); + for(int i=0;i getValidEditorBookmarks() { + return myEditorBookmarks.getValidBookmarks(); + } + + public List getValidCommanderBookmarks() { + return myCommanderBookmarks.getValidBookmarks(); + } + + public EditorBookmark findEditorBookmark(Document document, int lineIndex) { + myEditorBookmarks.removeInvalidBookmarks(); + return myEditorBookmarks.findByDocumnetLine(document, lineIndex); + } + + public EditorBookmark findNumberedEditorBookmark(int number) { + myEditorBookmarks.removeInvalidBookmarks(); + return myEditorBookmarks.findByNumber(number); + } + + public CommanderBookmark findCommanderBookmark(PsiElement element) { + myCommanderBookmarks.removeInvalidBookmarks(); + return myCommanderBookmarks.findByPsiElement(element); + } + + public void removeBookmark(Bookmark bookmark) { + if (bookmark == null) return; + selectBookmarksOfSameType(bookmark).removeBookmark(bookmark); + } + + public void readExternal(Element element) throws InvalidDataException { + for (Iterator iterator = element.getChildren().iterator(); iterator.hasNext();) { + Element bookmarkElement = (Element)iterator.next(); + + if (BookmarksCollection.ForEditors.ELEMENT_NAME.equals(bookmarkElement.getName())) { + myEditorBookmarks.readBookmark(bookmarkElement, myProject); + } + else if (BookmarksCollection.ForPsiElements.ELEMENT_NAME.equals(bookmarkElement.getName())) { + myCommanderBookmarks.readBookmark(bookmarkElement, myProject); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + myEditorBookmarks.writeBookmarks(element); + myCommanderBookmarks.writeBookmarks(element); + } + + /** + * Try to move bookmark one position up in the list + * + * @return bookmark list after moving + */ + public List moveBookmarkUp(Bookmark bookmark) { + BookmarksCollection bookmarks = selectBookmarksOfSameType(bookmark); + return bookmarks.moveUp(bookmark); + } + + private BookmarksCollection selectBookmarksOfSameType(Bookmark bookmark) { + if (bookmark instanceof EditorBookmark) return myEditorBookmarks; + if (bookmark instanceof CommanderBookmark) return myCommanderBookmarks; + if (bookmark == null) { + LOG.error("null"); + } + else { + LOG.error(bookmark.getClass().getName()); + } + return null; + } + + /** + * Try to move bookmark one position down in the list + * + * @return bookmark list after moving + */ + public List moveBookmarkDown(Bookmark bookmark) { + BookmarksCollection bookmarks = selectBookmarksOfSameType(bookmark); + return bookmarks.moveDown(bookmark); + } + + public EditorBookmark getNextBookmark(Editor editor, boolean isWrapped) { + EditorBookmark[] bookmarksForDocument = getBookmarksForDocument(editor.getDocument()); + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + for (int i = 0; i < bookmarksForDocument.length; i++) { + EditorBookmark bookmark = bookmarksForDocument[i]; + if (bookmark.getLineIndex() > lineNumber) return bookmark; + } + if (isWrapped && bookmarksForDocument.length > 0) { + return bookmarksForDocument[0]; + } + return null; + } + + public EditorBookmark getPreviousBookmark(Editor editor, boolean isWrapped) { + EditorBookmark[] bookmarksForDocument = getBookmarksForDocument(editor.getDocument()); + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + for (int i = bookmarksForDocument.length - 1; i >= 0; i--) { + EditorBookmark bookmark = bookmarksForDocument[i]; + if (bookmark.getLineIndex() < lineNumber) return bookmark; + } + if (isWrapped && bookmarksForDocument.length > 0) { + return bookmarksForDocument[bookmarksForDocument.length - 1]; + } + return null; + } + + private EditorBookmark[] getBookmarksForDocument(Document document) { + ArrayList bookmarksVector = new ArrayList(); + List validEditorBookmarks = getValidEditorBookmarks(); + for (Iterator iterator = validEditorBookmarks.iterator(); iterator.hasNext();) { + EditorBookmark bookmark = iterator.next(); + if (document.equals(bookmark.getDocument())) { + bookmarksVector.add(bookmark); + } + } + EditorBookmark[] bookmarks = bookmarksVector.toArray(new EditorBookmark[bookmarksVector.size()]); + Arrays.sort(bookmarks, new Comparator() { + public int compare(Object o1, Object o2) { + EditorBookmark bookmark1 = (EditorBookmark)o1; + EditorBookmark bookmark2 = (EditorBookmark)o2; + return bookmark1.getLineIndex() - bookmark2.getLineIndex(); + } + }); + return bookmarks; + } + + private class MyEditorMouseListener extends EditorMouseAdapter { + public void mouseClicked(final EditorMouseEvent e) { + if (e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA) return; + if (e.getMouseEvent().isPopupTrigger()) return; + if ((e.getMouseEvent().getModifiers() & MouseEvent.CTRL_MASK) == 0) return; + + Editor editor = e.getEditor(); + int line = editor.xyToLogicalPosition(new Point(e.getMouseEvent().getX(), e.getMouseEvent().getY())).line; + if (line < 0) return; + + Document document = editor.getDocument(); + + EditorBookmark bookmark = findEditorBookmark(document, line); + if (bookmark == null) { + addEditorBookmark(document, line, EditorBookmark.NOT_NUMBERED); + } + else { + removeBookmark(bookmark); + } + e.consume(); + } + } + + public String getComponentName() { + return "BookmarkManager"; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/BookmarksDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/BookmarksDialog.java new file mode 100644 index 00000000000..577b02cd489 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/BookmarksDialog.java @@ -0,0 +1,364 @@ +package com.intellij.ide.bookmarks; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.ItemRemovable; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.*; + +abstract class BookmarksDialog extends DialogWrapper{ + private MyModel myModel; + protected Table myTable; + private JButton myGotoButton = new JButton("Go to"); + private JButton myRemoveButton = new JButton("Remove"); + private JButton myRemoveAllButton = new JButton("Remove All"); + private JButton myMoveUpButton = new JButton("Move Up"); + private JButton myMoveDownButton = new JButton("Move Down"); + private JButton myCloseButton = new JButton("Close"); + protected BookmarkManager myBookmarkManager; + + protected class MyModel extends DefaultTableModel implements ItemRemovable { + public MyModel() { + super(new Object[0][], new Object[] {"Bookmark","Description"}); + } + + public boolean isCellEditable(int row, int column) { + return column == 1; // description + } + + public void setValueAt(Object aValue, int row, int column) { + if (column == 1) { + getBookmarkWrapper(row).getBookmark().setDescription((String)aValue); + } + super.setValueAt(aValue, row, column); + myTable.repaint(); + } + + public Object getValueAt(int row, int column) { + switch (column) { + case 0: + return getBookmarkWrapper(row).myDisplayText; + case 1: + return getBookmarkWrapper(row).getBookmark().getDescription(); + default: + return super.getValueAt(row, column); + } + } + + public BookmarkWrapper getBookmarkWrapper(int row) { + return (BookmarkWrapper)super.getValueAt(row, 0); + } + } + + BookmarksDialog(BookmarkManager bookmarkManager) { + super(bookmarkManager.getProject(), true); + myBookmarkManager = bookmarkManager; + myModel = new MyModel(); + myTable = new Table(myModel); + } + + protected Border createContentPaneBorder(){ + return null; + } + + protected JComponent createSouthPanel(){ + return null; + } + + protected JComponent createCenterPanel(){ + myTable.setColumnSelectionAllowed(false); + myTable.setPreferredScrollableViewportSize(new Dimension(500, 200)); + JScrollPane tableScrollPane = ScrollPaneFactory.createScrollPane(myTable); + + myTable.getColumnModel().getColumn(0).setPreferredWidth(400); + myTable.getColumnModel().getColumn(1).setPreferredWidth(100); + + myTable.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + handle(e); + } + + public void keyPressed(KeyEvent e) { + handle(e); + } + + private void handle(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) { + myCloseButton.doClick(); + } + else if (e.getKeyCode() == KeyEvent.VK_ENTER && e.getModifiers() == 0) { + myGotoButton.doClick(); + } + } + }); + + JPanel panel=new JPanel(new GridBagLayout()); + GridBagConstraints constr; + + constr = new GridBagConstraints(); + constr.weightx = 1; + constr.weighty = 1; + constr.insets = new Insets(5, 5, 5, 0); + constr.fill = GridBagConstraints.BOTH; + constr.anchor = GridBagConstraints.WEST; + panel.add(tableScrollPane, constr); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.insets = new Insets(5, 0, 0, 0); + constr.anchor = GridBagConstraints.NORTH; + panel.add(createRightButtonPane(), constr); + + addListeners(); + + DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() { + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ) { + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + BookmarkWrapper bookmarkWrapper = myModel.getBookmarkWrapper(row); + setIcon(bookmarkWrapper.getBookmark().getIcon()); + return component; + } + }; + myTable.getColumnModel().getColumn(0).setCellRenderer(renderer); + + return panel; + } + + // buttons + protected JPanel createRightButtonPane() { + JPanel pane = new JPanel(new GridBagLayout()); + + GridBagConstraints constr = new GridBagConstraints(); + constr.insets = new Insets(0, 5, 5, 5); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.weightx = 1.0; + pane.add(myGotoButton, constr); + constr.gridy = 2; + pane.add(myMoveUpButton, constr); + constr.gridy = 3; + pane.add(myMoveDownButton, constr); + constr.gridy = 4; + pane.add(myRemoveButton, constr); + constr.gridy = 5; + pane.add(myRemoveAllButton, constr); + constr.gridy = 6; + pane.add(myCloseButton, constr); + + myGotoButton.setMnemonic('G'); + myMoveUpButton.setMnemonic('u'); + myMoveDownButton.setMnemonic('d'); + myRemoveButton.setMnemonic('R'); + myRemoveAllButton.setMnemonic('A'); + myCloseButton.setMnemonic('C'); + + return pane; + } + + private static class BookmarkWrapper { + private Bookmark myBookmark; + private String myDisplayText; + + BookmarkWrapper(Bookmark bookmark) { + myBookmark = bookmark; + myDisplayText = bookmark.toString(); + } + + public String toString() { + return myDisplayText; + } + + public Bookmark getBookmark() { + return myBookmark; + } + } + + protected void fillList(java.util.List bookmarks, Bookmark defaultSelectedBookmark) { + while (myModel.getRowCount() > 0){ + myModel.removeRow(0); + } + for(int i = 0; i < bookmarks.size(); i++){ + Bookmark bookmark = bookmarks.get(i); + myModel.addRow(new Object[] {new BookmarkWrapper(bookmark), null}); + if (i == 0 || bookmark == defaultSelectedBookmark) { + myTable.getSelectionModel().setSelectionInterval(i, i); + } + } + final int index = myTable.getSelectionModel().getMinSelectionIndex(); + if (index >= 0) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myTable.scrollRectToVisible(myTable.getCellRect(index, 0, true)); + } + }); + } + enableButtons(); + } + + protected void addListeners() { + myTable.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + myGotoButton.doClick(); + } + } + } + ); + + myTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + enableButtons(); + } + } + ); + + myGotoButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopCellEditing(); + if (getSelectedBookmark() == null) return; + gotoSelectedBookmark(true); + } + } + ); + + myRemoveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopCellEditing(); + removeSelectedBookmark(); + myTable.requestFocus(); + } + } + ); + + myRemoveAllButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopCellEditing(); + while (myModel.getRowCount() > 0) { + Bookmark bookmark = myModel.getBookmarkWrapper(0).getBookmark(); + myBookmarkManager.removeBookmark(bookmark); + myModel.removeRow(0); + } + myTable.clearSelection(); + enableButtons(); + myTable.requestFocus(); + } + } + ); + + myMoveUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopCellEditing(); + Bookmark bookmark = getSelectedBookmark(); + fillList(myBookmarkManager.moveBookmarkUp(bookmark), bookmark); + myTable.requestFocus(); + } + } + ); + + myMoveDownButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopCellEditing(); + Bookmark bookmark = getSelectedBookmark(); + fillList(myBookmarkManager.moveBookmarkDown(bookmark), bookmark); + myTable.requestFocus(); + } + } + ); + + myCloseButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + close(CANCEL_EXIT_CODE); + } + } + ); + + ShortcutSet shortcutSet = ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(); + new AnAction() { + public void actionPerformed(AnActionEvent e){ + myGotoButton.doClick(); + } + }.registerCustomShortcutSet(shortcutSet, getRootPane()); + + getRootPane().registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + removeSelectedBookmark(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW + ); + + getRootPane().setDefaultButton(myGotoButton); + } + + private void removeSelectedBookmark() { + Bookmark selectedBookmark = getSelectedBookmark(); + if (selectedBookmark != null){ + myBookmarkManager.removeBookmark(selectedBookmark); + TableUtil.removeSelectedItems(myTable); + enableButtons(); + } + } + + protected void enableButtons() { + int selectedIndex = myTable.getSelectionModel().getMinSelectionIndex(); + myRemoveButton.setEnabled(selectedIndex != -1); + myRemoveAllButton.setEnabled(myModel.getRowCount() > 0); + myGotoButton.setEnabled(selectedIndex != -1); + myMoveUpButton.setEnabled(selectedIndex > 0); + myMoveDownButton.setEnabled(selectedIndex != -1 && selectedIndex < myModel.getRowCount() - 1); + } + + abstract protected void gotoSelectedBookmark(boolean closeWindow); + + protected Bookmark getSelectedBookmark() { + int selectedIndex = myTable.getSelectionModel().getMinSelectionIndex(); + if (selectedIndex == -1 || selectedIndex >= myModel.getRowCount()) return null; + return myModel.getBookmarkWrapper(selectedIndex).getBookmark(); + } + + protected void dispose() { + stopCellEditing(); + super.dispose(); + } + + private void stopCellEditing() { + if (myTable.isEditing()) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + } + + public JComponent getPreferredFocusedComponent() { + return myTable; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/CommanderBookmarksDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/CommanderBookmarksDialog.java new file mode 100644 index 00000000000..f89fc3c022f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/CommanderBookmarksDialog.java @@ -0,0 +1,48 @@ +package com.intellij.ide.bookmarks; + +import com.intellij.ide.commander.Commander; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiElement; + +public class CommanderBookmarksDialog extends BookmarksDialog { + private Project myProject; + + private CommanderBookmarksDialog(BookmarkManager bookmarkManager) { + super(bookmarkManager); + myProject = bookmarkManager.getProject(); + setHorizontalStretch(0.75f); + init(); + } + + protected void gotoSelectedBookmark(boolean closeWindow) { + + CommanderBookmark bookmark = (CommanderBookmark)getSelectedBookmark(); + final PsiElement element = bookmark.getPsiElement(); + + ToolWindowManager windowManager=ToolWindowManager.getInstance(myProject); + windowManager.getToolWindow(ToolWindowId.COMMANDER).activate( + new Runnable(){ + public void run(){ + Commander.getInstance(myProject).enterElementInActivePanel(element); + } + } + ); + + if (closeWindow){ + close(CANCEL_EXIT_CODE); + } + } + + public static void execute(BookmarkManager manager, Bookmark currentBookmark) { + BookmarksDialog dialog = new CommanderBookmarksDialog(manager); + dialog.setTitle("Project Elements Bookmarks"); + dialog.fillList(manager.getValidCommanderBookmarks(), currentBookmark); + dialog.show(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.ide.bookmarks.CommanderBookmarksDialog"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/EditorBookmarksDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/EditorBookmarksDialog.java new file mode 100644 index 00000000000..23cae02ec07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/EditorBookmarksDialog.java @@ -0,0 +1,76 @@ +package com.intellij.ide.bookmarks; + +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class EditorBookmarksDialog extends BookmarksDialog { + private JButton myViewSourceButton; + + private EditorBookmarksDialog(BookmarkManager bookmarkManager) { + super(bookmarkManager); + myViewSourceButton = new JButton("View Source"); + init(); + } + + protected void addListeners(){ + super.addListeners(); + myViewSourceButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (getSelectedBookmark() == null) return; + gotoSelectedBookmark(false); + myTable.requestFocus(); + } + }); + } + + protected void enableButtons() { + super.enableButtons(); + myViewSourceButton.setEnabled(getSelectedBookmark() != null); + } + + protected void gotoSelectedBookmark(boolean closeWindow) { + EditorBookmark bookmark = (EditorBookmark)getSelectedBookmark(); + if (bookmark == null) return; + final Project project = myBookmarkManager.getProject(); + OpenFileDescriptor editSourceDescriptor = bookmark.getOpenFileDescriptor(); + if (editSourceDescriptor == null) return; + FileEditorManager.getInstance(project).openTextEditor(editSourceDescriptor, false); + + if (closeWindow){ + close(CANCEL_EXIT_CODE); + } + } + + protected JPanel createRightButtonPane() { + JPanel panel = super.createRightButtonPane(); + + GridBagConstraints constr = new GridBagConstraints(); + constr.insets = new Insets(0, 5, 5, 5); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.weightx = 1.0; + constr.gridy = 1; + panel.add(myViewSourceButton, constr); + myViewSourceButton.setMnemonic('V'); + + return panel; + } + + public static void execute(BookmarkManager manager, Bookmark currentBookmark) { + BookmarksDialog dialog = new EditorBookmarksDialog(manager); + dialog.setTitle("Editor Bookmarks"); + dialog.fillList(manager.getValidEditorBookmarks(), currentBookmark); + dialog.show(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.ide.bookmarks.EditorBookmarksDialog"; + } +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/GotoBookmarkActionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/GotoBookmarkActionBase.java new file mode 100644 index 00000000000..fbea902fada --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/GotoBookmarkActionBase.java @@ -0,0 +1,39 @@ +package com.intellij.ide.bookmarks.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.ide.bookmarks.EditorBookmark; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiFile; + +abstract class GotoBookmarkActionBase extends BaseCodeInsightAction implements CodeInsightActionHandler{ + protected CodeInsightActionHandler getHandler() { + return this; + } + + public void invoke(Project project, final Editor editor, PsiFile file) { + if (ToolWindowManager.getInstance(project).isEditorComponentActive()) { + final EditorBookmark bookmark = getBookmarkToGo(project, editor); + if (bookmark == null) return; + if (bookmark.getLineIndex() >= editor.getDocument().getLineCount()) return; + LogicalPosition pos = new LogicalPosition(bookmark.getLineIndex(), 0); + editor.getSelectionModel().removeSelection(); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getScrollingModel().scrollTo(new LogicalPosition(bookmark.getLineIndex(), 0), ScrollType.CENTER); + } + } + + public boolean startInWriteAction() { + return true; + } + + protected final boolean isValidForFile(Project project, Editor editor, PsiFile file) { + return getBookmarkToGo(project, editor) != null; + } + + abstract protected EditorBookmark getBookmarkToGo(Project project, Editor editor); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/NextBookmarkAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/NextBookmarkAction.java new file mode 100644 index 00000000000..10945babb89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/NextBookmarkAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.bookmarks.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.ide.bookmarks.BookmarkManager; +import com.intellij.ide.bookmarks.EditorBookmark; +import com.intellij.openapi.project.Project; + +public class NextBookmarkAction extends GotoBookmarkActionBase { + protected EditorBookmark getBookmarkToGo(Project project, Editor editor) { + return BookmarkManager.getInstance(project).getNextBookmark(editor, true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/PreviousBookmarkAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/PreviousBookmarkAction.java new file mode 100644 index 00000000000..f6b748c5fac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/PreviousBookmarkAction.java @@ -0,0 +1,12 @@ +package com.intellij.ide.bookmarks.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.ide.bookmarks.BookmarkManager; +import com.intellij.ide.bookmarks.EditorBookmark; +import com.intellij.openapi.project.Project; + +public class PreviousBookmarkAction extends GotoBookmarkActionBase { + protected EditorBookmark getBookmarkToGo(Project project, Editor editor) { + return BookmarkManager.getInstance(project).getPreviousBookmark(editor, true); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/ToggleBookmarkAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/ToggleBookmarkAction.java new file mode 100644 index 00000000000..b58471e95c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/bookmarks/actions/ToggleBookmarkAction.java @@ -0,0 +1,88 @@ +package com.intellij.ide.bookmarks.actions; + +import com.intellij.ide.bookmarks.BookmarkManager; +import com.intellij.ide.bookmarks.EditorBookmark; +import com.intellij.ide.commander.Commander; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiElement; + +public class ToggleBookmarkAction extends AnAction { + public ToggleBookmarkAction() { + super("Toggle Bookmark"); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + BookmarkManager bookmarkManager = BookmarkManager.getInstance(project); + + if (ToolWindowManager.getInstance(project).isEditorComponentActive()) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + // toggle editor bookmark if editor is active + if (editor != null) { + EditorBookmark bookmark = bookmarkManager.findEditorBookmark(editor.getDocument(), editor.getCaretModel().getLogicalPosition().line); + if (bookmark == null) { + bookmarkManager.addEditorBookmark(editor.getDocument(), editor.getCaretModel().getLogicalPosition().line, EditorBookmark.NOT_NUMBERED); + } + else { + bookmarkManager.removeBookmark(bookmark); + } + } + return; + } + String id=ToolWindowManager.getInstance(project).getActiveToolWindowId(); + if (ToolWindowId.PROJECT_VIEW.equals(id)) { + PsiElement element = ProjectView.getInstance(project).getParentOfCurrentSelection(); + if (element != null) { + bookmarkManager.addCommanderBookmark(element); + } + return; + } + if (id.equals(ToolWindowId.COMMANDER)) { + Object element = Commander.getInstance(project).getActivePanel().getBuilder().getParentElement(); + if (element instanceof PsiElement) { + bookmarkManager.addCommanderBookmark((PsiElement)element); + } + return; + } + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + String s = "Toggle Bookmark"; + + DataContext dataContext = event.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + presentation.setText(s); + return; + } + + if (ToolWindowManager.getInstance(project).isEditorComponentActive()) { + presentation.setEnabled(dataContext.getData(DataConstants.EDITOR) != null); + presentation.setText(s); + return; + } + + ProjectView projectView = ProjectView.getInstance(project); + presentation.setText("Set Bookmark"); + String id=ToolWindowManager.getInstance(project).getActiveToolWindowId(); + if (ToolWindowId.PROJECT_VIEW.equals(id)) { + presentation.setEnabled(projectView.getParentOfCurrentSelection() != null); + } + else if (ToolWindowId.COMMANDER.equals(id)) { + boolean value=Commander.getInstance(project).getActivePanel().getBuilder().getParentElement() instanceof PsiElement; + presentation.setEnabled(value); + } + else { + presentation.setEnabled(false); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/AbstractListBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/AbstractListBuilder.java new file mode 100644 index 00000000000..3b4d7c5073e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/AbstractListBuilder.java @@ -0,0 +1,424 @@ +package com.intellij.ide.commander; + +import com.intellij.ide.projectView.impl.nodes.BasePsiNode; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * @author Eugene Belyaev + */ +public abstract class AbstractListBuilder { + protected final Project myProject; + protected final JList myList; + private final DefaultListModel myModel; + private final AbstractTreeStructure myTreeStructure; + private final Comparator myComparator; + + protected JLabel myParentTitle = null; + private boolean myIsDisposed; + private AbstractTreeNode myCurrentParent = null; + private final AbstractTreeNode myShownRoot; + + AbstractListBuilder( + final Project project, + final JList list, + final DefaultListModel model, + final AbstractTreeStructure treeStructure, + final Comparator comparator, + final boolean showRoot + ) { + myProject = project; + myList = list; + myModel = model; + myTreeStructure = treeStructure; + myComparator = comparator; + + final Object rootElement = myTreeStructure.getRootElement(); + final Object[] rootChildren = myTreeStructure.getChildElements(rootElement); + + if (!showRoot && rootChildren.length == 1) { + myShownRoot = (AbstractTreeNode)rootChildren[0]; + } + else { + myShownRoot = (AbstractTreeNode)rootElement; + } + } + + public final void setParentTitle(final JLabel parentTitle) { + myParentTitle = parentTitle; + } + + final void drillDown() { + final Object value = myList.getSelectedValue(); + if (value instanceof AbstractTreeNode) { + try { + final AbstractTreeNode node = (AbstractTreeNode)value; + buildList(node); + ListScrollingUtil.ensureSelectionExists(myList); + } + finally { + updateParentTitle(); + } + } + else { // an element that denotes parent + goUp(); + } + } + + final void goUp() { + if (myCurrentParent == myShownRoot.getParent()) { + return; + } + final AbstractTreeNode element = myCurrentParent.getParent(); + if (element == null) { + return; + } + + try { + AbstractTreeNode oldParent = myCurrentParent; + + buildList((AbstractTreeNode)element); + + for (int i = 0; i < myModel.size(); i++) { + if (myModel.getElementAt(i) instanceof NodeDescriptor) { + final NodeDescriptor desc = (NodeDescriptor)myModel.getElementAt(i); + final Object elem = desc.getElement(); + if (oldParent.equals(elem)) { + ListScrollingUtil.selectItem(myList, i); + break; + } + } + } + } + finally { + updateParentTitle(); + } + } + + public final void selectElement(final PsiElement element) { + if (element == null) { + return; + } + + try { + AbstractTreeNode node = goDownToElement(element, BasePsiNode.getVirtualFile(element)); + if (node == null) return; + AbstractTreeNode parentElement = node.getParent(); + if (parentElement == null) return; + + buildList(parentElement); + + for (int i = 0; i < myModel.size(); i++) { + if (myModel.getElementAt(i) instanceof AbstractTreeNode) { + final AbstractTreeNode desc = (AbstractTreeNode)myModel.getElementAt(i); + if (desc.getValue() instanceof StructureViewTreeElement) { + StructureViewTreeElement treeelement = (StructureViewTreeElement)desc.getValue(); + if (element.equals(treeelement.getValue())) { + ListScrollingUtil.selectItem(myList, i); + break; + } + } + else { + if (element.equals(desc.getValue())) { + ListScrollingUtil.selectItem(myList, i); + break; + } + } + } + } + } + finally { + updateParentTitle(); + } + } + + public final void enterElement(final Object element, VirtualFile file) { + try { + AbstractTreeNode lastPathNode = null; + lastPathNode = goDownToElement(element, file); + if (lastPathNode == null) return; + buildList(lastPathNode); + ListScrollingUtil.ensureSelectionExists(myList); + } + finally { + updateParentTitle(); + } + } + + private AbstractTreeNode goDownToElement(final Object element, VirtualFile file) { + return goDownToNode((AbstractTreeNode)myTreeStructure.getRootElement(), element, file); + } + + public final void enterElement(final AbstractTreeNode element) { + try { + buildList(element); + ListScrollingUtil.ensureSelectionExists(myList); + } + finally { + updateParentTitle(); + } + } + + private AbstractTreeNode goDownToNode(AbstractTreeNode lastPathNode, final Object lastPathElement, VirtualFile file) { + if (file == null) return lastPathNode; + AbstractTreeNode found = lastPathNode; + while (found != null) { + if (Comparing.equal(lastPathNode.getValue(), lastPathElement)) { + break; + } + else { + found = findInChildren(lastPathNode, file, lastPathElement); + if (found != null) { + lastPathNode = found; + } + } + } + return lastPathNode; + } + + private AbstractTreeNode findInChildren(AbstractTreeNode rootElement, VirtualFile file, Object element) { + Object[] childElements = getChildren(rootElement); + List nodes = getAllAcceptableNodes(childElements, file); + if (nodes.size() == 1) return nodes.get(0); + if (nodes.size() == 0) return null; + if (!file.isDirectory()) { + return performDeepSearch(nodes.toArray(), element); + } + else { + return nodes.get(0); + } + } + + private AbstractTreeNode performDeepSearch(Object[] nodes, Object element) { + for (int i = 0; i < nodes.length; i++) { + AbstractTreeNode node = (AbstractTreeNode)nodes[i]; + if (nodeIsAcceptableForElement(node, element)) return node; + AbstractTreeNode nodeResult = performDeepSearch(getChildren(node), element); + if (nodeResult != null) { + return nodeResult; + } + } + return null; + } + + protected abstract boolean nodeIsAcceptableForElement(AbstractTreeNode node, Object element); + + protected abstract List getAllAcceptableNodes(Object[] childElements, VirtualFile file); + + private NodeDescriptor createDescriptor(final Object element) { + final Object parent = myTreeStructure.getParentElement(element); + NodeDescriptor parentDescriptor = null; + if (parent != null) { + parentDescriptor = createDescriptor(parent); + } + return myTreeStructure.createDescriptor(element, parentDescriptor); + } + + public void dispose() { + myIsDisposed = true; + } + + private void buildList(final AbstractTreeNode parentElement) { + myCurrentParent = parentElement; + final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + alarm.addRequest( + new Runnable() { + public void run() { + myList.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + 200 + ); + + final Object[] children = getChildren(parentElement); + myModel.removeAllElements(); + if (shouldAddTopElement()) { + myModel.addElement("[ .. ]"); + } + + for (int i = 0; i < children.length; i++) { + AbstractTreeNode child = (AbstractTreeNode)children[i]; + child.update(); + } + if (myComparator != null) { + Arrays.sort(children, myComparator); + } + for (int i = 0; i < children.length; i++) { + myModel.addElement(children[i]); + } + + final int n = alarm.cancelAllRequests(); + if (n == 0) { + alarm.addRequest( + new Runnable() { + public void run() { + myList.setCursor(Cursor.getDefaultCursor()); + } + }, + 0 + ); + } + } + + private boolean shouldAddTopElement() { + return myCurrentParent != myShownRoot; + } + + private Object[] getChildren(final AbstractTreeNode parentElement) { + if (parentElement == null) { + return new Object[]{myTreeStructure.getRootElement()}; + } + else { + return myTreeStructure.getChildElements(parentElement); + } + } + + protected final void updateList() { + if (myIsDisposed || myCurrentParent == null) { + return; + } + myTreeStructure.commit(); + + final AbstractTreeNode initialParentDescriptor = myCurrentParent; + AbstractTreeNode parentDescriptor = initialParentDescriptor; + + while (true) { + parentDescriptor.update(); + if (parentDescriptor.getValue() != null) break; + parentDescriptor = parentDescriptor.getParent(); + } + + final Object[] children = getChildren(parentDescriptor); + final com.intellij.util.containers.HashMap elementToIndexMap = new com.intellij.util.containers.HashMap(); + for (int i = 0; i < children.length; i++) { + elementToIndexMap.put(children[i], new Integer(i)); + } + + final List resultDescriptors = new ArrayList(); + final Object[] listChildren = myModel.toArray(); + for (int i = 0; i < listChildren.length; i++) { + final Object child = listChildren[i]; + if (!(child instanceof NodeDescriptor)) { + continue; + } + final NodeDescriptor descriptor = (NodeDescriptor)child; + descriptor.update(); + final Object newElement = descriptor.getElement(); + final Integer index = (newElement != null) ? (Integer)elementToIndexMap.get(newElement) : null; + if (index != null) { + resultDescriptors.add(descriptor); + descriptor.setIndex(index.intValue()); + elementToIndexMap.remove(newElement); + } + } + + for (Iterator iterator = elementToIndexMap.keySet().iterator(); iterator.hasNext();) { + final Object child = iterator.next(); + final Integer index = (Integer)elementToIndexMap.get(child); + final NodeDescriptor childDescr = myTreeStructure.createDescriptor(child, parentDescriptor); + childDescr.setIndex(index.intValue()); + childDescr.update(); + resultDescriptors.add(childDescr); + } + + final SelectionInfo selection = storeSelection(); + if (myComparator != null) { + Collections.sort(resultDescriptors, myComparator); + } + myModel.removeAllElements(); + if (shouldAddTopElement()) { + myModel.addElement("[ .. ]"); + } + for (int i = 0; i < resultDescriptors.size(); i++) { + final NodeDescriptor descriptor = (NodeDescriptor)resultDescriptors.get(i); + myModel.addElement(descriptor); + } + restoreSelection(selection); + updateParentTitle(); + } + + private static final class SelectionInfo { + public final ArrayList mySelectedObjects; + public final Object myLeadSelection; + public final int myLeadSelectionIndex; + + public SelectionInfo(final ArrayList selectedObjects, final int leadSelectionIndex, final Object leadSelection) { + myLeadSelection = leadSelection; + myLeadSelectionIndex = leadSelectionIndex; + mySelectedObjects = selectedObjects; + } + }; + + private SelectionInfo storeSelection() { + final ListSelectionModel selectionModel = myList.getSelectionModel(); + final ArrayList selectedObjects = new ArrayList(); + final int[] selectedIndices = myList.getSelectedIndices(); + final int leadSelectionIndex = selectionModel.getLeadSelectionIndex(); + Object leadSelection = null; + for (int i = 0; i < selectedIndices.length; i++) { + final int index = selectedIndices[i]; + if (index < myList.getModel().getSize()) { + final Object o = myModel.get(index); + selectedObjects.add(o); + if (index == leadSelectionIndex) { + leadSelection = o; + } + } + } + return new SelectionInfo(selectedObjects, leadSelectionIndex, leadSelection); + } + + private void restoreSelection(final SelectionInfo selection) { + final ArrayList selectedObjects = selection.mySelectedObjects; + int leadIndex = -1; + + final ListSelectionModel selectionModel = myList.getSelectionModel(); + + selectionModel.clearSelection(); + if (selectedObjects.size() > 0) { + for (int i = 0; i < selectedObjects.size(); i++) { + final Object o = selectedObjects.get(i); + final int index = myModel.indexOf(o); + if (index > -1) { + selectionModel.addSelectionInterval(index, index); + if (o == selection.myLeadSelection) { + leadIndex = index; + } + } + } + + if (selectionModel.getMinSelectionIndex() == -1) { + final int toSelect = Math.min(selection.myLeadSelectionIndex, myModel.size() - 1); + if (toSelect >= 0) { + myList.setSelectedIndex(toSelect); + } + } + else if (leadIndex != -1) { + selectionModel.setLeadSelectionIndex(leadIndex); + } + } + } + + public final Object getParentElement() { + return myCurrentParent; + } + + protected abstract void updateParentTitle(); + + public final void buildRoot() { + buildList(myShownRoot); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ColoredCommanderRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ColoredCommanderRenderer.java new file mode 100644 index 00000000000..063a6e7d39c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ColoredCommanderRenderer.java @@ -0,0 +1,55 @@ +package com.intellij.ide.commander; + +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; + +final class ColoredCommanderRenderer extends ColoredListCellRenderer { + private static final Icon ourUpLevelIcon = IconLoader.getIcon("/nodes/upLevel.png"); + private CommanderPanel myCommanderPanel; + + public ColoredCommanderRenderer(final CommanderPanel commanderPanel) { + if (commanderPanel == null){ + throw new IllegalArgumentException("commanderPanel cannot be null"); + } + myCommanderPanel = commanderPanel; + } + + public Component getListCellRendererComponent(final JList list, final Object value, final int index, boolean selected, boolean hasFocus){ + hasFocus = selected; // border around inactive items + + final Commander commander = myCommanderPanel.getCommander(); + if (commander != null && !commander.isPanelActive(myCommanderPanel)) { + selected = false; + } + + return super.getListCellRendererComponent(list, value, index, selected, hasFocus); + } + + protected void customizeCellRenderer(final JList list, final Object value, final int index, final boolean selected, final boolean hasFocus) { + Color color = UIManager.getColor("List.foreground"); + if (value instanceof NodeDescriptor) { + final NodeDescriptor descriptor = (NodeDescriptor)value; + setIcon(descriptor.getClosedIcon()); + final Color elementColor = descriptor.getColor(); + if (elementColor != null) { + color = elementColor; + } + } + else { + setIcon(ourUpLevelIcon); + } + append(value.toString(), new SimpleTextAttributes(Font.PLAIN, color)); + if (value instanceof PsiDirectoryNode) { + String locationString = ((PsiDirectoryNode)value).getPresentation().getLocationString(); + if (locationString != null && locationString.length() > 0) { + append(" (" + locationString + ")", SimpleTextAttributes.GRAY_ATTRIBUTES); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/Commander.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/Commander.java new file mode 100644 index 00000000000..879419fa04c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/Commander.java @@ -0,0 +1,490 @@ +package com.intellij.ide.commander; + +import com.intellij.ide.SelectInManager; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure; +import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; +import com.intellij.ide.projectView.impl.nodes.BasePsiNode; +import com.intellij.ide.util.treeView.AlphaComparator; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.*; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.*; +import com.intellij.usageView.UsageViewUtil; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev + */ +public class Commander extends JPanel implements JDOMExternalizable, DataProvider, ProjectComponent { + private Project myProject; + private CommanderPanel myLeftPanel; + private CommanderPanel myRightPanel; + private Splitter mySplitter; + private ListSelectionListener mySelectionListener; + private ListDataListener myListDataListener; + public boolean MOVE_FOCUS = true; // internal option: move focus to editor when class/file/...etc. is created + private Element myElement; + private FocusWatcher myFocusWatcher; + private CommanderHistory myHistory; + + public Commander(final Project project, KeymapManager keymapManager) { + super(new BorderLayout()); + myProject = project; + + final AbstractAction backAction = new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + myHistory.back(); + } + }; + final AbstractAction fwdAction = new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + myHistory.forward(); + } + }; + final ActionMap actionMap = getActionMap(); + actionMap.put("backCommand", backAction); + actionMap.put("forwardCommand", fwdAction); + final KeyStroke[] backStrokes = getKeyStrokes(IdeActions.ACTION_GOTO_BACK, keymapManager); + for (int idx = 0; idx < backStrokes.length; idx++) { + KeyStroke stroke = backStrokes[idx]; + //getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(stroke, "backCommand"); + //getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "backCommand"); + registerKeyboardAction(backAction, "backCommand", stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); + registerKeyboardAction(backAction, "backCommand", stroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + final KeyStroke[] fwdStrokes = getKeyStrokes(IdeActions.ACTION_GOTO_FORWARD, keymapManager); + for (int idx = 0; idx < fwdStrokes.length; idx++) { + KeyStroke stroke = fwdStrokes[idx]; + //getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(stroke, "forwardCommand"); + //getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "forwardCommand"); + registerKeyboardAction(fwdAction, "forwardCommand", stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); + registerKeyboardAction(fwdAction, "forwardCommand", stroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + myHistory = new CommanderHistory(this); + } + + public static Commander getInstance(final Project project) { + return project.getComponent(Commander.class); + } + + public CommanderHistory getCommandHistory() { + return myHistory; + } + + public void initComponent() { + } + + private void processConfigurationElement() { + if (myElement == null) return; + + Element element; + + element = myElement.getChild("leftPanel"); + if (element != null) { + final PsiElement parentElement = readParentElement(element); + if (parentElement != null) { + myLeftPanel.getBuilder().enterElement(parentElement, BasePsiNode.getVirtualFile(parentElement)); + } + } + + element = myElement.getChild("rightPanel"); + if (element != null) { + final PsiElement parentElement = readParentElement(element); + if (parentElement != null) { + myRightPanel.getBuilder().enterElement(parentElement, BasePsiNode.getVirtualFile(parentElement)); + } + } + + element = myElement.getChild("splitter"); + if (element != null) { + final String attribute = element.getAttributeValue("proportion"); + if (attribute != null) { + try { + final float proportion = Float.valueOf(attribute).floatValue(); + if (proportion >= 0 && proportion <= 1) { + mySplitter.setProportion(proportion); + } + } catch (NumberFormatException e) { + } + } + } + + element = myElement.getChild("OPTION"); + if (element != null) { + MOVE_FOCUS = !"false".equals(element.getAttributeValue("MOVE_FOCUS")); + } + + myLeftPanel.setActive(false); + myRightPanel.setActive(false); + + myElement = null; + } + + private KeyStroke[] getKeyStrokes(String actionId, KeymapManager keymapManager) { + final Shortcut[] shortcuts = keymapManager.getActiveKeymap().getShortcuts(actionId); + final java.util.List strokes = new ArrayList(); + for (int i = 0; i < shortcuts.length; i++) { + final Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + strokes.add(((KeyboardShortcut)shortcut).getFirstKeyStroke()); + } + } + return strokes.toArray(new KeyStroke[strokes.size()]); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.COMMANDER); + } + + public void projectOpened() { + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + setupImpl(); + } + }); + } + + public void setupImpl() { + mySelectionListener = new ListSelectionListener() { + public void valueChanged(final ListSelectionEvent e) { + updateToolWindowTitle(); + } + }; + myListDataListener = new ListDataListener() { + public void intervalAdded(final ListDataEvent e) { + updateToolWindowTitle(); + } + + public void intervalRemoved(final ListDataEvent e) { + updateToolWindowTitle(); + } + + public void contentsChanged(final ListDataEvent e) { + updateToolWindowTitle(); + } + }; + myFocusWatcher = new FocusWatcher(); + + myLeftPanel = createPanel(); + myRightPanel = createPanel(); + + mySplitter = new Splitter(); + mySplitter.setFirstComponent(myLeftPanel); + mySplitter.setSecondComponent(myRightPanel); + + add(mySplitter, BorderLayout.CENTER); + + processConfigurationElement(); + myElement = null; + + myFocusWatcher.install(this); + + setupToolWindow(); + } + + protected void setupToolWindow() { + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(ToolWindowId.COMMANDER, this, ToolWindowAnchor.RIGHT); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowCommander.png")); + SelectInManager.getInstance(myProject).addTarget(new CommanderSelectInTarget(myProject)); + } + + + private CommanderPanel createPanel() { + final CommanderPanel panel = new CommanderPanel(myProject, this); + final ProjectAbstractTreeStructureBase treeStructure = createProjectTreeStructure(); + final ProjectListBuilder builder = new ProjectListBuilder(myProject, panel, treeStructure, AlphaComparator.INSTANCE, true); + panel.setBuilder(builder); + + panel.getList().addFocusListener(new FocusAdapter() { + public void focusGained(final FocusEvent e) { + updateToolWindowTitle(panel); + } + }); + panel.getList().getSelectionModel().addListSelectionListener(mySelectionListener); + panel.getList().getModel().addListDataListener(myListDataListener); + + return panel; + } + + protected AbstractProjectTreeStructure createProjectTreeStructure() { + return new AbstractProjectTreeStructure(myProject) { + public boolean isShowMembers() { + return true; + } + + public boolean isHideEmptyMiddlePackages() { + return false; + } + + public boolean isFlattenPackages() { + return false; + } + + public boolean isAbbreviatePackageNames() { + return false; + } + + public boolean isShowLibraryContents() { + return false; + } + + public boolean isShowModules() { + return false; + } + }; + } + + /** + * invoked in AWT thread + */ + private void updateToolWindowTitle() { + final CommanderPanel panel = getActivePanel(); + updateToolWindowTitle(panel); + } + + protected void updateToolWindowTitle(final CommanderPanel activePanel) { + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.COMMANDER); + if (toolWindow == null) return; + + String title = null; + final PsiElement element = activePanel.getSelectedElement(); + if (element != null) { + // todo!!! + if (!element.isValid()) return; + if (element instanceof PsiDirectory) { + final PsiDirectory directory = (PsiDirectory) element; + title = UsageViewUtil.getPackageName(directory, true); + } else if (element instanceof PsiFile) { + final PsiFile file = (PsiFile) element; + title = file.getVirtualFile().getPresentableUrl(); + } else if (element instanceof PsiClass) { + final PsiClass psiClass = (PsiClass) element; + title = psiClass.getQualifiedName(); + } else if (element instanceof PsiMethod) { + final PsiMethod method = (PsiMethod) element; + final PsiClass aClass = method.getContainingClass(); + if (aClass != null) { + title = aClass.getQualifiedName(); + } else { + title = method.toString(); + } + } else if (element instanceof PsiField) { + final PsiField field = (PsiField) element; + final PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + title = aClass.getQualifiedName(); + } else { + title = field.toString(); + } + } else { + final PsiFile file = element.getContainingFile(); + if (file != null) { + title = file.getVirtualFile().getPresentableUrl(); + } else { + title = element.toString(); + } + } + } + + toolWindow.setTitle(title); + } + + public boolean isLeftPanelActive() { + return isPanelActive(myLeftPanel); + } + + boolean isPanelActive(final CommanderPanel panel) { + return panel.getList() == myFocusWatcher.getFocusedComponent(); + } + + public void selectElementInLeftPanel(final PsiElement element) { + myLeftPanel.getBuilder().selectElement(element); + if (!isPanelActive(myLeftPanel)) { + switchActivePanel(); + } + } + + public void selectElementInRightPanel(final PsiElement element) { + myRightPanel.getBuilder().selectElement(element); + if (!isPanelActive(myRightPanel)) { + switchActivePanel(); + } + } + + public void switchActivePanel() { + final CommanderPanel activePanel = getActivePanel(); + final CommanderPanel inactivePanel = getInactivePanel(); + inactivePanel.setActive(true); + activePanel.setActive(false); + IdeFocusTraversalPolicy.getPreferredFocusedComponent(inactivePanel).requestFocus(); + } + + public void enterElementInActivePanel(final PsiElement element) { + final CommanderPanel activePanel; + if (isLeftPanelActive()) { + activePanel = myLeftPanel; + } else { + activePanel = myRightPanel; + } + activePanel.getBuilder().enterElement(element, BasePsiNode.getVirtualFile(element)); + } + + public void swapPanels() { + mySplitter.swapComponents(); + + final CommanderPanel tmpPanel = myLeftPanel; + myLeftPanel = myRightPanel; + myRightPanel = tmpPanel; + } + + public void syncViews() { + final CommanderPanel activePanel; + final CommanderPanel passivePanel; + if (isLeftPanelActive()) { + activePanel = myLeftPanel; + passivePanel = myRightPanel; + } else { + activePanel = myRightPanel; + passivePanel = myLeftPanel; + } + ProjectViewNode element = (ProjectViewNode)activePanel.getBuilder().getParentElement(); + passivePanel.getBuilder().enterElement(element); + } + + public CommanderPanel getActivePanel() { + return isLeftPanelActive() ? myLeftPanel : myRightPanel; + } + + public CommanderPanel getInactivePanel() { + return !isLeftPanelActive() ? myLeftPanel : myRightPanel; + } + + public Object getData(final String dataId) { + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return HelpID.COMMANDER; + } else if (DataConstantsEx.PROJECT.equals(dataId)) { + return myProject; + } else if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) { + final Object element = getInactivePanel().getBuilder().getParentElement(); + return (element instanceof PsiElement) && ((PsiElement)element).isValid()? element : null; + } else if (DataConstantsEx.SECONDARY_PSI_ELEMENT.equals(dataId)) { + final PsiElement selectedElement = getInactivePanel().getSelectedElement(); + return selectedElement != null && selectedElement.isValid() ? selectedElement : null; + } else { + return getActivePanel().getDataImpl(dataId); + } + } + + public void writeExternal(final Element element) throws WriteExternalException { + if (myLeftPanel == null || myRightPanel == null) { + return; + } + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + Element e = new Element("leftPanel"); + element.addContent(e); + writePanel(myLeftPanel, e); + e = new Element("rightPanel"); + element.addContent(e); + writePanel(myRightPanel, e); + e = new Element("splitter"); + element.addContent(e); + e.setAttribute("proportion", Float.toString(mySplitter.getProportion())); + if (!MOVE_FOCUS) { + e = new Element("OPTION"); + element.addContent(e); + e.setAttribute("MOVE_FOCUS", "false"); + } + } + + private static void writePanel(final CommanderPanel panel, final Element element) { + /*TODO[anton,vova]: it's a patch!!!*/ + final AbstractListBuilder builder = panel.getBuilder(); + if (builder == null) return; + + final Object parentElement = builder.getParentElement(); + if (parentElement instanceof PsiDirectory) { + final PsiDirectory directory = (PsiDirectory) parentElement; + element.setAttribute("url", directory.getVirtualFile().getUrl()); + } + else if (parentElement instanceof PsiClass) { + for (PsiElement e = (PsiElement) parentElement; e != null; e = e.getParent()) { + if (e instanceof PsiClass) { + final String qualifiedName = ((PsiClass) e).getQualifiedName(); + if (qualifiedName != null) { + element.setAttribute("class", qualifiedName); + break; + } + } + } + } + } + + public void readExternal(final Element element) throws InvalidDataException { + myElement = element; + } + + private PsiElement readParentElement(final Element element) { + if (element.getAttributeValue("url") != null) { + final String url = element.getAttributeValue("url"); + final VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); + return file != null ? PsiManager.getInstance(myProject).findDirectory(file) : null; + } else if (element.getAttributeValue("class") != null) { + final String className = element.getAttributeValue("class"); + return className != null ? PsiManager.getInstance(myProject).findClass(className) : null; + } + return null; + } + + public void disposeComponent() { + if (myLeftPanel == null) { + // not opened project (default?) + return; + } + myLeftPanel.dispose(); + myRightPanel.dispose(); + myHistory.clearHistory(); + myProject = null; + } + + public String getComponentName() { + return "Commander"; + } + + public CommanderPanel getRightPanel() { + return myRightPanel; + } + + public CommanderPanel getLeftPanel() { + return myLeftPanel; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderHistory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderHistory.java new file mode 100644 index 00000000000..2f6382e3acb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderHistory.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.commander; + +import com.intellij.psi.PsiElement; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +/** + * @author Eugene Zhuravlev + * Date: Oct 14, 2004 + */ +public class CommanderHistory { + public static final int HISTORY_LIMIT = 2*30; // elements are saved in pairs + private final Commander myCommander; + private final List myHistory = new ArrayList(); + private int myCurrentCommandIndex = 0; + private boolean myStateLoggingEnabled = true; + + public CommanderHistory(Commander commander) { + myCommander = commander; + } + + public void clearHistory() { + myHistory.clear(); + myCurrentCommandIndex = 0; + } + + public void saveState(final PsiElement element, boolean isElementExpanded, final boolean isLeftPanel) { + if (!myStateLoggingEnabled) { + return; + } + if (myCurrentCommandIndex >=0 && myCurrentCommandIndex < myHistory.size() - 1) { + myHistory.subList(myCurrentCommandIndex + 1, myHistory.size()).clear(); + } + if (myHistory.size() == HISTORY_LIMIT) { + myHistory.remove(0); + } + myHistory.add(new HistoryState(element, isElementExpanded, isLeftPanel)); + myCurrentCommandIndex = myHistory.size() - 1; + } + + public void back() { + if (applyState(getHistoryState(myCurrentCommandIndex - 1))) { + myCurrentCommandIndex--; + } + } + + public void forward() { + if (applyState(getHistoryState(myCurrentCommandIndex + 1))) { + myCurrentCommandIndex++; + } + } + + private boolean applyState(HistoryState state) { + myStateLoggingEnabled = false; + try { + if (state != null) { + final PsiElement element = state.getElement(); + final boolean shouldOpenInLeftPanel = state.isInLeftPanel(); + if (state.isElementExpanded()) { + final boolean isLeftPanelCurrentlyActive = myCommander.isLeftPanelActive(); + if ((shouldOpenInLeftPanel && !isLeftPanelCurrentlyActive) || (!shouldOpenInLeftPanel && isLeftPanelCurrentlyActive)) { + myCommander.switchActivePanel(); + } + myCommander.enterElementInActivePanel(element); + } + else { + if (shouldOpenInLeftPanel) { + myCommander.selectElementInLeftPanel(element); + } + else { + myCommander.selectElementInRightPanel(element); + } + } + return true; + } + } + finally { + myStateLoggingEnabled = true; + } + return false; + } + + private HistoryState getHistoryState(int index) { + if (index >= 0 && index < myHistory.size()) { + return myHistory.get(index); + } + return null; + } + + private static final class HistoryState { + private final PsiElement myElement; + private final boolean myElementExpanded; + private final boolean myIsLeftPanel; + + public HistoryState(PsiElement element, boolean isElementExpanded, boolean isLeftPanel) { + myElement = element; + myElementExpanded = isElementExpanded; + myIsLeftPanel = isLeftPanel; + } + + public boolean isInLeftPanel() { + return myIsLeftPanel; + } + + public boolean isElementExpanded() { + return myElementExpanded; + } + + public PsiElement getElement() { + return myElement; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderPanel.java new file mode 100644 index 00000000000..17fce765d54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderPanel.java @@ -0,0 +1,515 @@ +package com.intellij.ide.commander; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.DeleteProvider; +import com.intellij.ide.IdeView; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.DeleteHandler; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.ide.util.EditorHelper; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.ui.*; + +import javax.swing.*; +import javax.swing.border.BevelBorder; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev + */ +public class CommanderPanel extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.commander.CommanderPanel"); + + private static final Color DARK_BLUE = new Color(55, 85, 134); + private static final Color DARK_BLUE_BRIGHTER = new Color(58, 92, 149); + private static final Color DARK_BLUE_DARKER = new Color(38, 64, 106); + + private Project myProject; + private AbstractListBuilder myBuilder; + private JPanel myTitlePanel; + private JLabel myParentTitle; + protected final JList myList; + private final DefaultListModel myModel; + + private final Commander myCommander; + private CopyPasteManagerEx.CopyPasteDelegator myCopyPasteDelegator; + protected final ListSpeedSearch myListSpeedSearch; + private final IdeView myIdeView = new MyIdeView(); + private final MyDeleteElementProvider myDeleteElementProvider = new MyDeleteElementProvider(); + + public CommanderPanel(final Project project, final Commander commander) { + super(new BorderLayout()); + myProject = project; + myModel = new DefaultListModel(); + myList = new JList(myModel); + myList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + myCommander = commander; + + if (commander != null) { + myCopyPasteDelegator = new CopyPasteManagerEx.CopyPasteDelegator(myProject, myList) { + protected PsiElement[] getSelectedElements() { + return CommanderPanel.this.getSelectedElements(); + } + }; + } + + myListSpeedSearch = new ListSpeedSearch(myList); + + ListScrollingUtilEx.installActions(myList); + + myList.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + if (myBuilder == null) return; + myBuilder.buildRoot(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SLASH, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), + JComponent.WHEN_FOCUSED + ); + + myList.getInputMap(JComponent.WHEN_FOCUSED).put( + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), + "DrillDown" + ); + myList.getInputMap(JComponent.WHEN_FOCUSED).put( + KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), + "DrillDown" + ); + myList.getActionMap().put( + "DrillDown", + new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + drillDown(); + } + } + ); + myList.addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { + drillDown(); + } + } + }); + myList.getInputMap(JComponent.WHEN_FOCUSED).put( + KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), + "GoUp" + ); + myList.getInputMap(JComponent.WHEN_FOCUSED).put( + KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), + "GoUp" + ); + myList.getActionMap().put( + "GoUp", + new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + goUp(); + } + } + ); + + myList.getActionMap().put( + "selectAll", + new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + } + } + ); + + + myList.addMouseListener( + new PopupHandler() { + public void invokePopup(final Component comp, final int x, final int y) { + CommanderPanel.this.invokePopup(comp, x, y); + } + } + ); + + myList.addKeyListener( + new KeyAdapter() { + public void keyPressed(final KeyEvent e) { + if (KeyEvent.VK_ESCAPE == e.getKeyCode()) { + if (e.isConsumed()) return; + final CopyPasteManagerEx copyPasteManager = (CopyPasteManagerEx)CopyPasteManager.getInstance(); + final boolean[] isCopied = new boolean[1]; + if (copyPasteManager.getElements(isCopied) != null && !isCopied[0]) { + copyPasteManager.clear(); + e.consume(); + } + } + } + } + ); + + myList.addFocusListener( + new FocusAdapter() { + public void focusGained(final FocusEvent e) { + setActive(true); + } + + public void focusLost(final FocusEvent e) { + setActive(false); + } + } + ); + + new ListToolTipHandler(myList); + } + + private void updateHistory(boolean elementExpanded) { + if (myCommander != null) { + myCommander.getCommandHistory().saveState(getSelectedElement(), elementExpanded, myCommander.isLeftPanelActive()); + } + } + + final JList getList() { + return myList; + } + + public final DefaultListModel getModel() { + return myModel; + } + + public void goUp() { + if (myBuilder == null) { + return; + } + updateHistory(true); + myBuilder.goUp(); + updateHistory(false); + } + + public void drillDown() { + if (topElementIsSelected()){ + goUp(); + return; + } + + if (getSelectedValue() == null) { + return; + } + + final AbstractTreeNode element = getSelectedNode(); + if (element.getChildren().size() == 0) { + if (!shouldDrillDownOnEmptyElement(element.getValue())) { + Object selectedValue = getSelectedValue(); + if (selectedValue instanceof Navigatable && ((Navigatable)selectedValue).canNavigate()) { + ((Navigatable)selectedValue).navigate(true); + onNavigatePerformed(); + return; + } else { + return; + } + } + } + + if (myBuilder == null) { + return; + } + updateHistory(false); + myBuilder.drillDown(); + updateHistory(true); + } + + protected boolean shouldDrillDownOnEmptyElement(final Object value) { + return true; + } + + private boolean topElementIsSelected() { + int[] selectedIndices = myList.getSelectedIndices(); + return selectedIndices.length == 1 && selectedIndices[0] == 0 && (myModel.getElementAt(selectedIndices[0]) instanceof String); + } + + protected void onNavigatePerformed() { + + } + + public final void setBuilder(final AbstractListBuilder builder) { + myBuilder = builder; + removeAll(); + + myTitlePanel = new JPanel(new BorderLayout()); + myTitlePanel.setBackground(UIManager.getColor("control")); + myTitlePanel.setOpaque(true); + + myParentTitle = new MyTitleLabel(myTitlePanel); + myParentTitle.setText(" "); + myParentTitle.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myParentTitle.setForeground(Color.black); + myParentTitle.setUI(new RightAlignedLabelUI()); + final JPanel panel1 = new JPanel(new BorderLayout()); + panel1.setOpaque(false); + panel1.add(Box.createHorizontalStrut(10), BorderLayout.WEST); + panel1.add(myParentTitle, BorderLayout.CENTER); + myTitlePanel.add(panel1, BorderLayout.CENTER); + + add(myTitlePanel, BorderLayout.NORTH); + final JScrollPane scrollPane = new JScrollPane(myList); + scrollPane.getVerticalScrollBar().setFocusable(false); // otherwise the scrollbar steals focus and panel switching with tab is broken + scrollPane.getHorizontalScrollBar().setFocusable(false); + add(scrollPane, BorderLayout.CENTER); + + myBuilder.setParentTitle(myParentTitle); + + // TODO[vova,anton] it seems that the code below performs double focus request. Is it OK? + myTitlePanel.addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + myList.requestFocus(); + } + + public void mousePressed(final MouseEvent e) { + myList.requestFocus(); + } + }); + } + + public final AbstractListBuilder getBuilder() { + return myBuilder; + } + + public final PsiElement getSelectedElement() { + Object value = getValueAtIndex(getSelectedNode()); + return (PsiElement)(value instanceof PsiElement ? value : null); + } + + public final PsiElement getSelectedElement(int index) { + Object elementAtIndex = myModel.getElementAt(index); + Object value = getValueAtIndex(elementAtIndex instanceof AbstractTreeNode ? (AbstractTreeNode)elementAtIndex : null); + return (PsiElement)(value instanceof PsiElement ? value : null); + } + + private AbstractTreeNode getSelectedNode(){ + if (myBuilder == null) return null; + final int[] indices = myList.getSelectedIndices(); + if (indices.length != 1) return null; + int index = indices[0]; + if (index >= myModel.getSize()) return null; + Object elementAtIndex = myModel.getElementAt(index); + return elementAtIndex instanceof AbstractTreeNode ? (AbstractTreeNode)elementAtIndex : null; + } + + + + public Object getSelectedValue() { + return getValueAtIndex(getSelectedNode()); + } + + private PsiElement[] getSelectedElements() { + if (myBuilder == null) return null; + final int[] indices = myList.getSelectedIndices(); + + final ArrayList elements = new ArrayList(); + for (int i = 0; i < indices.length; i++) { + final PsiElement element = getSelectedElement(indices[i]); + if (element != null) { + elements.add(element); + } + } + + return elements.toArray(new PsiElement[elements.size()]); + } + + private Object getValueAtIndex(AbstractTreeNode node) { + if (node == null) return null; + Object value = node.getValue(); + if (value instanceof TreeElement){ + return ((StructureViewTreeElement)value).getValue(); + } + return value; + } + + final void setActive(final boolean active) { + if (active) { + myTitlePanel.setBackground(DARK_BLUE); + myTitlePanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, DARK_BLUE_BRIGHTER, DARK_BLUE_DARKER)); + myParentTitle.setForeground(Color.white); + } + else { + final Color color = UIManager.getColor("Panel.background"); + LOG.assertTrue(color != null); + myTitlePanel.setBackground(color); + myTitlePanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, color.brighter(), color.darker())); + myParentTitle.setForeground(Color.black); + } + } + + public final Commander getCommander() { + return myCommander; + } + + private void invokePopup(final Component c, final int x, final int y) { + if (myCommander == null) return; + if (myBuilder == null) return; + + if (myList.getSelectedIndices().length <= 1) { + final int popupIndex = myList.locationToIndex(new Point(x, y)); + if (popupIndex >= 0) { + myList.setSelectedIndex(popupIndex); + myList.requestFocus(); + } + } + + final ActionManager actionManager = ActionManager.getInstance(); + final ActionGroup group = (ActionGroup)actionManager.getAction(IdeActions.GROUP_COMMANDER_POPUP); + final ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.COMMANDER_POPUP, group); + popupMenu.getComponent().show(c, x, y); + } + + public final void dispose() { + if (myBuilder != null) { + myBuilder.dispose(); + myBuilder = null; + } + myProject = null; + } + + public final void setTitlePanelVisible(final boolean flag) { + myTitlePanel.setVisible(flag); + } + + public final Object getDataImpl(final String dataId) { + if (myBuilder == null) return null; + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + final PsiElement selectedElement = getSelectedElement(); + return (selectedElement != null && selectedElement.isValid())? selectedElement : null; + } + if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return filterInvalidElements(getSelectedElements()); + } + else if (DataConstantsEx.PASTE_TARGET_PSI_ELEMENT.equals(dataId)) { + final Object element = myBuilder.getParentElement(); + return (element instanceof PsiElement) && ((PsiElement)element).isValid() ? element : null; + } + else if (DataConstants.NAVIGATABLE.equals(dataId)) { + return createEditSourceDescriptor(); + } + else if (DataConstantsEx.COPY_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator != null ? myCopyPasteDelegator.getCopyProvider() : null; + } + else if (DataConstantsEx.CUT_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator != null ? myCopyPasteDelegator.getCutProvider() : null; + } + else if (DataConstantsEx.PASTE_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator != null ? myCopyPasteDelegator.getPasteProvider() : null; + } + else if (DataConstantsEx.IDE_VIEW.equals(dataId)) { + return myIdeView; + } + else if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return myDeleteElementProvider; + } + return null; + } + + private static PsiElement[] filterInvalidElements(final PsiElement[] elements) { + if (elements == null || elements.length == 0) { + return elements; + } + final java.util.List validElements = new ArrayList(elements.length); + for (int idx = 0; idx < elements.length; idx++) { + final PsiElement element = elements[idx]; + if (element.isValid()) { + validElements.add(element); + } + } + return (validElements.size() == elements.length)? elements : validElements.toArray(new PsiElement[validElements.size()]); + } + + protected final Navigatable createEditSourceDescriptor() { + return EditSourceUtil.getDescriptor(getSelectedElement()); + } + + private static final class MyTitleLabel extends JLabel { + private final JPanel myPanel; + + public MyTitleLabel(final JPanel panel) { + myPanel = panel; + } + + public void setText(String text) { + super.setText(text); + if (text != null && text.trim().length() == 0) { + text = null; + } + if (myPanel != null) { + myPanel.setToolTipText(text); + } + } + } + + private final class MyDeleteElementProvider implements DeleteProvider { + public void deleteElement(final DataContext dataContext) { + final com.intellij.openapi.localVcs.LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, + "Deleting"); + try { + final PsiElement[] elements = getSelectedElements(); + DeleteHandler.deletePsiElement(elements, myProject); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + } + + public boolean canDeleteElement(final DataContext dataContext) { + final PsiElement[] elements = getSelectedElements(); + return DeleteHandler.shouldEnableDeleteAction(elements); + } + } + + private final class MyIdeView implements IdeView { + public void selectElement(final PsiElement element) { + final PsiElement psiElement = (PsiElement)element; + final boolean isDirectory = psiElement instanceof PsiDirectory; + if (!isDirectory) { + EditorHelper.openInEditor(psiElement); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myBuilder.selectElement(psiElement); + if (!isDirectory) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (Commander.getInstance(myProject).MOVE_FOCUS) { + ToolWindowManager.getInstance(myProject).activateEditorComponent(); + } + } + }); + } + } + }, ModalityState.NON_MMODAL); + } + + private PsiDirectory getDirectory() { + if (myBuilder == null) return null; + final Object parentElement = myBuilder.getParentElement(); + if (parentElement instanceof AbstractTreeNode) { + final AbstractTreeNode parentNode = ((AbstractTreeNode)parentElement); + if (!(parentNode.getValue() instanceof PsiDirectory)) return null; + return (PsiDirectory)parentNode.getValue(); + } else { + return null; + } + } + + public PsiDirectory[] getDirectories() { + PsiDirectory directory = getDirectory(); + return directory == null ? PsiDirectory.EMPTY_ARRAY : new PsiDirectory[] {directory}; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderSelectInTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderSelectInTarget.java new file mode 100644 index 00000000000..59a254ada0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/CommanderSelectInTarget.java @@ -0,0 +1,75 @@ +package com.intellij.ide.commander; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.ide.SelectInTarget; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + +final class CommanderSelectInTarget implements SelectInTarget { + private final Project myProject; + + public CommanderSelectInTarget(final Project project) { + myProject = project; + } + + public String toString() { + return "Commander"; + } + + public boolean canSelect(final PsiFile file) { + return file.getManager().isInProject(file); + } + + public void select(PsiElement element, boolean requestFocus) { + while (true) { + if (element instanceof PsiFile) { + break; + } + if (element instanceof PsiClass && element.getParent() instanceof PsiFile) { + break; + } + element = element.getParent(); + } + if (element instanceof PsiAspectFile) { + final PsiAspect[] aspects = ((PsiAspectFile) element).getAspects(); + if (aspects.length > 0) { + element = aspects[0]; + } + } + else if (element instanceof PsiJavaFile) { + final PsiClass[] classes = ((PsiJavaFile)element).getClasses(); + if (classes.length > 0) { + element = classes[0]; + } + } + + final PsiElement _element = element.getOriginalElement(); + final Commander commander = Commander.getInstance(myProject); + final ToolWindowManager windowManager=ToolWindowManager.getInstance(myProject); + final Runnable runnable = new Runnable() { + public void run() { + commander.selectElementInLeftPanel(_element); + } + }; + if (requestFocus) { + windowManager.getToolWindow(ToolWindowId.COMMANDER).activate(runnable); + } + else { + runnable.run(); + } + } + + public String getToolWindowId() { + return ToolWindowId.COMMANDER; + } + + public String getMinorViewId() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/HelpID.java new file mode 100644 index 00000000000..d3909418214 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/HelpID.java @@ -0,0 +1,5 @@ +package com.intellij.ide.commander; + +interface HelpID { + String COMMANDER = "viewingStructure.commander"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ProjectListBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ProjectListBuilder.java new file mode 100644 index 00000000000..3c6485814f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/commander/ProjectListBuilder.java @@ -0,0 +1,229 @@ +package com.intellij.ide.commander; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; +import com.intellij.usageView.UsageViewUtil; + +import java.util.Comparator; +import java.util.List; +import java.util.ArrayList; + +public class ProjectListBuilder extends AbstractListBuilder { + private final MyPsiTreeChangeListener myPsiTreeChangeListener; + private final MyFileStatusListener myFileStatusListener; + private int myUpdateCount = 0; + private final CopyPasteManager.ContentChangedListener myCopyPasteListener; + + public ProjectListBuilder(final Project project, + final CommanderPanel panel, + final AbstractTreeStructure treeStructure, + final Comparator comparator, + final boolean showRoot) { + super(project, panel.getList(), panel.getModel(), treeStructure, comparator, showRoot); + myList.setCellRenderer(new ColoredCommanderRenderer(panel)); + + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); + myFileStatusListener = new MyFileStatusListener(); + FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener); + myCopyPasteListener = new MyCopyPasteListener(); + CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener); + buildRoot(); + } + + protected void updateParentTitle() { + if (myParentTitle == null) return; + + Object parentElement = getParentElement(); + if (parentElement instanceof PsiFile) { + parentElement = ((PsiFile)parentElement).getContainingDirectory(); + } + if (!(parentElement instanceof PsiElement)) { + myParentTitle.setText(null); + } + else { + final String text; + if (parentElement instanceof PsiDirectory){ + text = UsageViewUtil.getPackageName((PsiDirectory)parentElement, true); + } + else{ + text = UsageViewUtil.getLongName((PsiElement)parentElement); + } + myParentTitle.setText(text); + } + } + + protected boolean nodeIsAcceptableForElement(AbstractTreeNode node, Object element) { + return Comparing.equal(node.getValue(), element); + } + + protected List getAllAcceptableNodes(final Object[] childElements, VirtualFile file) { + ArrayList result = new ArrayList(); + + for (int i = 0; i < childElements.length; i++) { + ProjectViewNode childElement = (ProjectViewNode)childElements[i]; + if (childElement.contains(file)) result.add(childElement); + } + + return result; + } + + public void dispose() { + super.dispose(); + PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener); + FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener); + CopyPasteManager.getInstance().removeContentChangedListener(myCopyPasteListener); + } + + public void addUpdateRequest() { + myUpdateCount++; + final int count = myUpdateCount; + final Runnable updater = new Runnable() { + public void run() { + if (myUpdateCount != count || myProject.isDisposed()) return; + updateList(); + } + }; + final Application app = ApplicationManager.getApplication(); + if (app.isUnitTestMode()) { + updater.run(); + } + else { + app.invokeLater(updater, ModalityState.current()); + } + } + + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void childRemoved(final PsiTreeChangeEvent event) { + final PsiElement child = event.getOldChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getParent()); + } + + public void childAdded(final PsiTreeChangeEvent event) { + final PsiElement child = event.getNewChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getParent()); + } + + public void childReplaced(final PsiTreeChangeEvent event) { + final PsiElement oldChild = event.getOldChild(); + final PsiElement newChild = event.getNewChild(); + if (oldChild instanceof PsiWhiteSpace && newChild instanceof PsiWhiteSpace) return; //optimization + if (oldChild instanceof PsiCodeBlock && newChild instanceof PsiCodeBlock) return; //optimization + childrenChanged(event.getParent()); + } + + public void childMoved(final PsiTreeChangeEvent event) { + childrenChanged(event.getOldParent()); + childrenChanged(event.getNewParent()); + } + + public void childrenChanged(final PsiTreeChangeEvent event) { + childrenChanged(event.getParent()); + } + + private void childrenChanged(PsiElement parent) { + while(true){ + if (parent == null) break; + if (parent instanceof PsiCodeBlock) break; + if (parent instanceof PsiFile){ + parent = ((PsiFile)parent).getContainingDirectory(); + if (parent == null) break; + } + + if (parent instanceof PsiMethod + || parent instanceof PsiField + || parent instanceof PsiClass + || parent instanceof PsiFile + || parent instanceof PsiDirectory) break; + parent = parent.getParent(); + } + + if (parent == null) { + return; + } + final Object element = getParentElement(); + if (element instanceof PsiElement){ + if (!((PsiElement)element).isValid()){ + addUpdateRequest(); + return; + } + PsiElement psiElement = (PsiElement)element; + PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiFile){ + pparent = pparent.getParent(); + } + if (psiElement.equals(pparent)){ + addUpdateRequest(); + return; + } + while(true){ + if (psiElement == null) return; + if (psiElement.equals(parent)){ + addUpdateRequest(); + return; + } + psiElement = psiElement.getParent(); + } + } + } + + public void propertyChanged(final PsiTreeChangeEvent event) { + final String propertyName = event.getPropertyName(); + final PsiElement element = event.getElement(); + if (propertyName.equals(PsiTreeChangeEvent.PROP_ROOTS)) { + addUpdateRequest(); + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_WRITABLE)){ + childrenChanged(element); + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_NAME) || propertyName.equals(PsiTreeChangeEvent.PROP_DIRECTORY_NAME)){ + childrenChanged(element); + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_TYPES)){ + addUpdateRequest(); + } + } + } + + private final class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { + addUpdateRequest(); + } + + public void fileStatusChanged(final VirtualFile vFile) { + final PsiManager manager = PsiManager.getInstance(myProject); + + if (vFile.isDirectory()) { + final PsiDirectory directory = manager.findDirectory(vFile); + if (directory != null) { + myPsiTreeChangeListener.childrenChanged(directory.getParent()); + } + } + else { + final PsiFile file = manager.findFile(vFile); + if (file != null){ + myPsiTreeChangeListener.childrenChanged(file.getContainingDirectory()); + } + } + } + } + + private final class MyCopyPasteListener implements CopyPasteManager.ContentChangedListener { + public void contentChanged() { + addUpdateRequest(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElement.java new file mode 100644 index 00000000000..af61948f01f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public abstract class ErrorTreeElement { + private final ErrorTreeElementKind myKind; + + protected ErrorTreeElement() { + this(ErrorTreeElementKind.GENERIC); + } + + protected ErrorTreeElement(ErrorTreeElementKind kind) { + myKind = kind; + } + + public ErrorTreeElementKind getKind() { + return myKind; + } + + public abstract String[] getText(); + + public abstract Object getData(); + + public final String toString() { + String[] text = getText(); + return text != null && text.length > 0? text[0] : ""; + } + + public abstract String getExportTextPrefix(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElementKind.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElementKind.java new file mode 100644 index 00000000000..ac3290bfe84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeElementKind.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.util.ui.MessageCategory; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class ErrorTreeElementKind { + public static final ErrorTreeElementKind INFO = new ErrorTreeElementKind("INFO", "Information: "); + public static final ErrorTreeElementKind ERROR = new ErrorTreeElementKind("ERROR", "Error: "); + public static final ErrorTreeElementKind WARNING = new ErrorTreeElementKind("WARNING", "Warning: "); + public static final ErrorTreeElementKind GENERIC = new ErrorTreeElementKind("GENERIC", ""); + + private final String myText; + private final String myPresentableText; + + private ErrorTreeElementKind(String text, String presentableText) { + myText = text; + myPresentableText = presentableText; + } + + public String toString() { + return myText; // for debug purposes + } + + public String getPresentableText() { + return myPresentableText; + } + + public static ErrorTreeElementKind convertMessageFromCompilerErrorType(int type) { + switch(type) { + case MessageCategory.ERROR : return ERROR; + case MessageCategory.WARNING : return WARNING; + case MessageCategory.INFORMATION : return INFO; + case MessageCategory.STATISTICS : return INFO; + case MessageCategory.SIMPLE : return GENERIC; + default : return GENERIC; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeNodeDescriptor.java new file mode 100644 index 00000000000..7d239ee53f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorTreeNodeDescriptor.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class ErrorTreeNodeDescriptor extends NodeDescriptor{ + private final ErrorTreeElement myElement; + + public ErrorTreeNodeDescriptor(Project project, NodeDescriptor parentDescriptor, ErrorTreeElement element) { + super(project, parentDescriptor); + myElement = element; + } + + public boolean update() { + return false; + } + + public ErrorTreeElement getElement() { + return myElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewStructure.java new file mode 100644 index 00000000000..0bfa9656dc7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewStructure.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.pom.Navigatable; +import com.intellij.util.ArrayUtil; + +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class ErrorViewStructure extends AbstractTreeStructure { + private final ErrorTreeElement myRoot = new MyRootElement(); + private final List myGroupNames = new ArrayList(); + private final Map myGroupNameToElementMap = new HashMap(); + private final Map> myGroupNameToMessagesMap = new HashMap>(); + private final Map> mySimpleMessages = new HashMap>(); + + private static final ErrorTreeElementKind[] ourMessagesOrder = new ErrorTreeElementKind[] { + ErrorTreeElementKind.INFO, ErrorTreeElementKind.ERROR, ErrorTreeElementKind.WARNING, ErrorTreeElementKind.GENERIC + }; + private final Project myProject; + + public ErrorViewStructure(Project project) { + myProject = project; + } + + public Object getRootElement() { + return myRoot; + } + + public Object[] getChildElements(Object element) { + if (element == myRoot) { + final List children = new ArrayList(); + // simple messages + for (int idx = 0; idx < ourMessagesOrder.length; idx++) { + final ErrorTreeElementKind kind = ourMessagesOrder[idx]; + if (ErrorTreeElementKind.WARNING.equals(kind)) { + if (ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) { + continue; + } + } + final List elems = mySimpleMessages.get(kind); + if (elems != null) { + children.addAll(elems); + } + } + // files + for (Iterator it = myGroupNames.iterator(); it.hasNext();) { + final GroupingElement groupingElement = myGroupNameToElementMap.get(it.next()); + if (shouldShowFileElement(groupingElement)) { + children.add(groupingElement); + } + } + return (Object[])children.toArray(new Object[children.size()]); + } + else if (element instanceof GroupingElement) { + final List children = myGroupNameToMessagesMap.get(((GroupingElement)element).getName()); + if (children != null && children.size() > 0) { + if (ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) { + final List filtered = new ArrayList(children.size()); + for (Iterator it = children.iterator(); it.hasNext();) { + final NavigatableMessageElement navigatableMessageElement = it.next(); + if (ErrorTreeElementKind.WARNING.equals(navigatableMessageElement.getKind())) { + continue; + } + filtered.add(navigatableMessageElement); + } + return filtered.toArray(); + } + return children.toArray(); + } + } + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + private boolean shouldShowFileElement(GroupingElement groupingElement) { + if (!ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) { + return getChildCount(groupingElement) > 0; + } + final List children = myGroupNameToMessagesMap.get(groupingElement.getName()); + if (children != null && children.size() > 0) { + for (Iterator it = children.iterator(); it.hasNext();) { + final NavigatableMessageElement child = it.next(); + if (!ErrorTreeElementKind.WARNING.equals(child.getKind())) { + return true; + } + } + } + return false; + } + + public Object getParentElement(Object element) { + if (element instanceof GroupingElement || element instanceof SimpleMessageElement) { + return myRoot; + } + if (element instanceof NavigatableMessageElement) { + return ((NavigatableMessageElement)element).getParent(); + } + return null; + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + return new ErrorTreeNodeDescriptor(myProject, parentDescriptor, (ErrorTreeElement)element); + } + + public final void commit() { + } + + public final boolean hasSomethingToCommit() { + return false; + } + + public void addMessage(ErrorTreeElementKind kind, String[] text, VirtualFile file, int line, int column, Object data) { + if (file != null) { + addNavigatableMessage(file.getPresentableUrl(), new OpenFileDescriptor(myProject, file, line, column), kind, text, data, NewErrorTreeViewPanel.createExportPrefix(line), NewErrorTreeViewPanel.createRendererPrefix(line, column)); + } + else { + addSimpleMessage(kind, text, data); + } + } + + public void addMessage(ErrorTreeElementKind kind, String[] text, Object data) { + addSimpleMessage(kind, text, data); + } + + public void addNavigatableMessage(String groupName, Navigatable navigatable, final ErrorTreeElementKind kind, final String[] message, final Object data, String exportText, String rendererTextPrefix) { + List elements = myGroupNameToMessagesMap.get(groupName); + if (elements == null) { + elements = new ArrayList(); + myGroupNameToMessagesMap.put(groupName, elements); + } + elements.add(new NavigatableMessageElement( + kind, + getGroupingElement(groupName, data), + message, navigatable, exportText, rendererTextPrefix) + ); + } + + private void addSimpleMessage(final ErrorTreeElementKind kind, final String[] text, final Object data) { + List elements = mySimpleMessages.get(kind); + if (elements == null) { + elements = new ArrayList(); + mySimpleMessages.put(kind, elements); + } + elements.add(new SimpleMessageElement(kind, text, data)); + } + + private GroupingElement getGroupingElement(String groupName, Object data) { + GroupingElement element = myGroupNameToElementMap.get(groupName); + if (element == null) { + element = new GroupingElement(groupName, data); + myGroupNames.add(groupName); + myGroupNameToElementMap.put(groupName, element); + } + return element; + } + + public int getChildCount(GroupingElement groupingElement) { + final List children = myGroupNameToMessagesMap.get(groupingElement.getName()); + return children != null? children.size() : 0; + } + + public void clear() { + myGroupNames.clear(); + myGroupNameToElementMap.clear(); + myGroupNameToMessagesMap.clear(); + mySimpleMessages.clear(); + } + + public ErrorTreeElement getFirstMessage(ErrorTreeElementKind kind) { + if (ErrorTreeElementKind.WARNING.equals(kind) && ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) { + return null; // no warnings are available + } + final List simpleMessages = mySimpleMessages.get(kind); + if (simpleMessages != null && simpleMessages.size() > 0) { + return simpleMessages.get(0); + } + for (Iterator it = myGroupNames.iterator(); it.hasNext();) { + final String path = it.next(); + final List messages = myGroupNameToMessagesMap.get(path); + for (Iterator messageIterator = messages.iterator(); messageIterator.hasNext();) { + final NavigatableMessageElement navigatableMessageElement = messageIterator.next(); + if (kind.equals(navigatableMessageElement.getKind())) { + return navigatableMessageElement; + } + } + } + return null; + } + + private static class MyRootElement extends ErrorTreeElement { + public String[] getText() { + return null; + } + + public Object getData() { + return null; + } + + public String getExportTextPrefix() { + return ""; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewTreeBuilder.java new file mode 100644 index 00000000000..f1ff86f04e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/ErrorViewTreeBuilder.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class ErrorViewTreeBuilder extends AbstractTreeBuilder{ + public ErrorViewTreeBuilder(JTree tree, DefaultTreeModel treeModel, AbstractTreeStructure treeStructure) { + super(tree, treeModel, treeStructure, null); + } + + public void updateFromRoot() { + myUpdater.cancelAllRequests(); + super.updateFromRoot(); + } + + public void updateTree() { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public void updateTree(Runnable runAferUpdate) { + myUpdater.runAfterUpdate(runAferUpdate); + updateTree(); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + final ErrorTreeElement element = (ErrorTreeElement)nodeDescriptor.getElement(); + if (element instanceof GroupingElement) { + return ((ErrorViewStructure)myTreeStructure).getChildCount((GroupingElement)element) > 0; + } + return false; + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + return nodeDescriptor.getParentDescriptor() == null || nodeDescriptor.getElement() instanceof GroupingElement; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/GroupingElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/GroupingElement.java new file mode 100644 index 00000000000..fa35f0d59b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/GroupingElement.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class GroupingElement extends ErrorTreeElement { + private final String[] myText; + private final Object myData; + + public GroupingElement(VirtualFile file) { + this(file.getPresentableUrl(), null); + } + + public GroupingElement(String name, Object data) { + super(ErrorTreeElementKind.GENERIC); + myText = new String[] {name}; + myData = data; + } + + public GroupingElement(VirtualFile file, Object data) { + this(file.getPresentableUrl(), data); + } + + public Object getData() { + return myData; + } + + public String[] getText() { + return myText; + } + + public String getName() { + return myText[0]; + } + + public String getExportTextPrefix() { + return ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NavigatableMessageElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NavigatableMessageElement.java new file mode 100644 index 00000000000..f1ca97a539f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NavigatableMessageElement.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.pom.Navigatable; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class NavigatableMessageElement extends ErrorTreeElement{ + private final GroupingElement myParent; + private final String[] myMessage; + private Navigatable myNavigatable; + private String myExportText; + private String myRendererTextPrefix; + + public NavigatableMessageElement(ErrorTreeElementKind kind, + GroupingElement parent, + String[] message, + Navigatable navigatable, + String exportText, + String rendererTextPrefix) { + super(kind); + myParent = parent; + myMessage = message; + myNavigatable = navigatable; + myExportText = exportText; + myRendererTextPrefix = rendererTextPrefix; + } + + public Navigatable getNavigatable() { + return myNavigatable; + } + + public String[] getText() { + return myMessage; + } + + public Object getData() { + return myParent.getData(); + } + + public GroupingElement getParent() { + return myParent; + } + + public String getExportTextPrefix() { + return getKind().getPresentableText() + myExportText; + } + + public String getRendererTextPrefix() { + return myRendererTextPrefix; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java new file mode 100644 index 00000000000..fc485596963 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java @@ -0,0 +1,88 @@ +package com.intellij.ide.errorTreeView; + +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.MultilineTreeCellRenderer; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; + +/** + * + */ +public class NewErrorTreeRenderer extends MultilineTreeCellRenderer { + + private static Icon ourFileIcon = IconLoader.getIcon("/fileTypes/java.png"); + private static Icon ourErrorIcon = IconLoader.getIcon("/compiler/error.png"); + private static Icon ourWarningIcon = IconLoader.getIcon("/compiler/warning.png"); + private static Icon ourInfoIcon = IconLoader.getIcon("/compiler/information.png"); + + private NewErrorTreeRenderer() { + } + + public static JScrollPane install(JTree tree) { + return MultilineTreeCellRenderer.installRenderer(tree, new NewErrorTreeRenderer()); + } + + protected void initComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + final ErrorTreeElement element = getElement(value); + if(element instanceof GroupingElement) { + setFont(getFont().deriveFont(Font.BOLD)); + } + + if(element instanceof SimpleMessageElement || element instanceof NavigatableMessageElement) { + String prefix = element.getKind().getPresentableText(); + + if (element instanceof NavigatableMessageElement) { + prefix += ((NavigatableMessageElement)element).getRendererTextPrefix() + " "; + } + + setText(element.getText(), prefix); + } + else if (element != null){ + String[] text = element.getText(); + if (text == null) { + text = ArrayUtil.EMPTY_STRING_ARRAY; + } + if(text.length > 0 && text[0] == null) { + text[0] = ""; + } + setText(text, null); + } + + Icon icon = null; + + if (element instanceof GroupingElement) { + if (ourFileIcon != null) { + icon = ourFileIcon; + } + } + else if (element instanceof SimpleMessageElement || element instanceof NavigatableMessageElement) { + ErrorTreeElementKind kind = element.getKind(); + if (ErrorTreeElementKind.ERROR.equals(kind)) { + icon = ourErrorIcon; + } + else if (ErrorTreeElementKind.WARNING.equals(kind)) { + icon = ourWarningIcon; + } + else if (ErrorTreeElementKind.INFO.equals(kind)) { + icon = ourInfoIcon; + } + } + + setIcon(icon); + } + + private static ErrorTreeElement getElement(Object value) { + if (!(value instanceof DefaultMutableTreeNode)) { + return null; + } + final Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); + if (!(userObject instanceof ErrorTreeNodeDescriptor)) { + return null; + } + return ((ErrorTreeNodeDescriptor)userObject).getElement(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java new file mode 100644 index 00000000000..a72dc14df66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java @@ -0,0 +1,514 @@ +package com.intellij.ide.errorTreeView; + +import com.intellij.ide.ExporterToTextFile; +import com.intellij.ide.OccurenceNavigator; +import com.intellij.ide.OccurenceNavigatorSupport; +import com.intellij.ide.TreeExpander; +import com.intellij.ide.actions.*; +import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration; +import com.intellij.ide.errorTreeView.impl.ErrorViewTextExporter; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.pom.Navigatable; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.MessageView; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class NewErrorTreeViewPanel extends JPanel implements DataProvider, OccurenceNavigator, ErrorTreeView { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.errorTreeView.NewErrorTreeViewPanel"); + private String myProgressText = ""; + private final boolean myCreateExitAction; + private ErrorViewStructure myErrorViewStructure; + private ErrorViewTreeBuilder myBuilder; + + public static interface ProcessController { + void stopProcess(); + + boolean isProcessStopped(); + } + + private ActionToolbarEx myLeftToolbar; + private ActionToolbarEx myRightToolbar; + private TreeExpander myTreeExpander = new MyTreeExpander(); + private ExporterToTextFile myExporterToTextFile; + protected Project myProject; + private String myHelpId; + protected Tree myTree; + private JPanel myMessagePanel; + private ProcessController myProcessController; + + private JLabel myProgressTextLabel; + private JLabel myProgressStatisticsLabel; + private JPanel myProgressPanel; + + private AutoScrollToSourceHandler myAutoScrollToSourceHandler; + private MyOccurenceNavigatorSupport myOccurenceNavigatorSupport; + + public NewErrorTreeViewPanel(Project project, String helpId) { + this(project, helpId, true); + } + + public NewErrorTreeViewPanel(Project project, String helpId, boolean createExitAction) { + this(project, helpId, createExitAction, true); + } + + public NewErrorTreeViewPanel(Project project, String helpId, boolean createExitAction, boolean createToolbar) { + myProject = project; + myHelpId = helpId; + myCreateExitAction = createExitAction; + setLayout(new BorderLayout()); + + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return ErrorTreeViewConfiguration.getInstance(myProject).isAutoscrollToSource(); + } + + protected void setAutoScrollMode(boolean state) { + ErrorTreeViewConfiguration.getInstance(myProject).setAutoscrollToSource(state); + } + }; + + myMessagePanel = new JPanel(new BorderLayout()); + + myErrorViewStructure = new ErrorViewStructure(project); + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + root.setUserObject(myErrorViewStructure.createDescriptor(myErrorViewStructure.getRootElement(), null)); + final DefaultTreeModel treeModel = new DefaultTreeModel(root); + myTree = new Tree(treeModel) { + public void setRowHeight(int i) { + super.setRowHeight(0); + // this is needed in order to make UI calculate the height for each particular row + } + }; + myBuilder = new ErrorViewTreeBuilder(myTree, treeModel, myErrorViewStructure); + + myExporterToTextFile = new ErrorViewTextExporter(myErrorViewStructure); + myOccurenceNavigatorSupport = new MyOccurenceNavigatorSupport(myTree); + + myAutoScrollToSourceHandler.install(myTree); + TreeUtil.installActions(myTree); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.setLargeModel(true); + myTree.setLargeModel(true); + + JScrollPane scrollPane = NewErrorTreeRenderer.install(myTree); + myMessagePanel.add(scrollPane, BorderLayout.CENTER); + + if (createToolbar) { + add(createToolbarPanel(), BorderLayout.WEST); + } + + add(myMessagePanel, BorderLayout.CENTER); + + myTree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + navigateToSource(false); + } + } + }); + + myTree.addMouseListener(new PopupHandler() { + public void invokePopup(Component comp, int x, int y) { + popupInvoked(comp, x, y); + } + }); + + EditSourceOnDoubleClickHandler.install(myTree); + } + + public Object getData(String dataId) { + if (DataConstants.NAVIGATABLE.equals(dataId)) { + final NavigatableMessageElement selectedMessageElement = getSelectedMessageElement(); + return (selectedMessageElement != null)? selectedMessageElement.getNavigatable() : null; + } + else if (DataConstants.HELP_ID.equals(dataId)) { + return myHelpId; + } + else if (DataConstantsEx.TREE_EXPANDER.equals(dataId)) { + return myTreeExpander; + } + else if (DataConstants.EXPORTER_TO_TEXT_FILE.equals(dataId)) { + return myExporterToTextFile; + } + else if (CURRENT_EXCEPTION_DATA.equals(dataId)) { + NavigatableMessageElement selectedMessageElement = getSelectedMessageElement(); + return selectedMessageElement != null? selectedMessageElement.getData() : null; + } + return null; + } + + public void selectFirstMessage() { + final ErrorTreeElement firstError = myErrorViewStructure.getFirstMessage(ErrorTreeElementKind.ERROR); + if (firstError != null) { + selectElement(firstError); + if (shouldShowFirstErrorInEditor()) { + navigateToSource(false); + } + } + else { + ErrorTreeElement firstWarning = myErrorViewStructure.getFirstMessage(ErrorTreeElementKind.WARNING); + if (firstWarning != null) { + selectElement(firstWarning); + } + else { + TreeUtil.selectFirstNode(myTree); + } + } + } + + private void selectElement(final ErrorTreeElement element) { + myBuilder.updateFromRoot(); + DefaultMutableTreeNode node = myBuilder.getNodeForElement(element); + if (node == null) { + myBuilder.buildNodeForElement(element); + node = myBuilder.getNodeForElement(element); + } + LOG.assertTrue(node != null); + TreeNode[] pathToRoot = ((DefaultTreeModel)myTree.getModel()).getPathToRoot(node); + TreeUtil.selectPath(myTree, new TreePath(pathToRoot)); + } + + protected boolean shouldShowFirstErrorInEditor() { + return false; + } + public void clearMessages() { + myErrorViewStructure.clear(); + myBuilder.updateTree(); + } + + public void addMessage(int type, String[] text, VirtualFile file, int line, int column, Object data) { + myErrorViewStructure.addMessage(ErrorTreeElementKind.convertMessageFromCompilerErrorType(type), text, file, line, column, data); + myBuilder.updateTree(); + } + + public void addMessage(int type, String[] text, String groupName, Navigatable navigatable, String exportTextPrefix, String rendererTextPrefix, Object data) { + myErrorViewStructure.addNavigatableMessage(groupName, navigatable, ErrorTreeElementKind.convertMessageFromCompilerErrorType(type), text, data, exportTextPrefix, rendererTextPrefix); + myBuilder.updateTree(); + } + + public static String createExportPrefix(int line) { + return line < 0? "" : "line (" + line + ")"; + } + + public static String createRendererPrefix(int line, int column) { + return line < 0? "" : "(" + line + ", " + column + ")"; + } + + public JComponent getComponent() { + return this; + } + + private NavigatableMessageElement getSelectedMessageElement() { + final ErrorTreeElement selectedElement = getSelectedErrorTreeElement(); + return selectedElement instanceof NavigatableMessageElement? (NavigatableMessageElement)selectedElement : null; + } + + public ErrorTreeElement getSelectedErrorTreeElement() { + ErrorTreeNodeDescriptor treeNodeDescriptor = getSelectedNodeDescriptor(); + if (treeNodeDescriptor == null) return null; + + return treeNodeDescriptor.getElement(); + } + + public ErrorTreeNodeDescriptor getSelectedNodeDescriptor() { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode lastPathNode = (DefaultMutableTreeNode)path.getLastPathComponent(); + Object userObject = lastPathNode.getUserObject(); + if (!(userObject instanceof ErrorTreeNodeDescriptor)) { + return null; + } + ErrorTreeNodeDescriptor treeNodeDescriptor = (ErrorTreeNodeDescriptor)userObject; + return treeNodeDescriptor; + } + + private void navigateToSource(final boolean focusEditor) { + NavigatableMessageElement element = getSelectedMessageElement(); + if (element == null) { + return; + } + element.getNavigatable().navigate(focusEditor); + } + + public String getQualifiedName(final VirtualFile file) { + return file.getPresentableUrl(); + } + + private void popupInvoked(Component component, int x, int y) { + final TreePath path = myTree.getLeadSelectionPath(); + if (path == null) { + return; + } + DefaultActionGroup group = new DefaultActionGroup(); + if (getData(DataConstants.NAVIGATABLE) != null) { + group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); + } + addExtraPopupMenuActions(group); + + ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.COMPILER_MESSAGES_POPUP, group); + menu.getComponent().show(component, x, y); + } + + protected void addExtraPopupMenuActions(DefaultActionGroup group) { + } + + public void setProcessController(ProcessController controller) { + myProcessController = controller; + } + + public void stopProcess() { + myProcessController.stopProcess(); + } + + public boolean canControlProcess() { + return myProcessController != null; + } + + public boolean isProcessStopped() { + return myProcessController.isProcessStopped(); + } + + public void close() { + MessageView messageView = myProject.getComponent(MessageView.class); + Content content = messageView.getContent(this); + if (content != null) { + messageView.removeContent(content); + } + } + + public void setProgressStatistics(final String s) { + initProgressPanel(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myProgressStatisticsLabel.setText(s); + } + }); + } + + public void setProgressText(final String s) { + initProgressPanel(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myProgressText = s; + myProgressTextLabel.setText(myProgressText); + } + }); + } + + public void setFraction(final double fraction) { + initProgressPanel(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myProgressTextLabel.setText(myProgressText + " " + (int)(fraction * 100 + 0.5) + "%"); + } + }); + } + + private void initProgressPanel() { + if (myProgressPanel == null) { + myProgressPanel = new JPanel(new GridLayout(1, 2)); + myProgressStatisticsLabel = new JLabel(); + myProgressPanel.add(myProgressStatisticsLabel); + myProgressTextLabel = new JLabel(); + myProgressPanel.add(myProgressTextLabel); + myMessagePanel.add(myProgressPanel, BorderLayout.SOUTH); + myMessagePanel.validate(); + } + } + + public void collapseAll() { + TreeUtil.collapseAll(myTree, 2); + } + + + public void expandAll() { + TreePath[] selectionPaths = myTree.getSelectionPaths(); + TreePath leadSelectionPath = myTree.getLeadSelectionPath(); + int row = 0; + while (row < myTree.getRowCount()) { + myTree.expandRow(row); + row++; + } + + if (selectionPaths != null) { + // restore selection + myTree.setSelectionPaths(selectionPaths); + } + if (leadSelectionPath != null) { + // scroll to lead selection path + myTree.scrollPathToVisible(leadSelectionPath); + } + } + + private JPanel createToolbarPanel() { + AnAction closeMessageViewAction = new CloseTabToolbarAction() { + public void actionPerformed(AnActionEvent e) { + close(); + } + }; + + DefaultActionGroup leftUpdateableActionGroup = new DefaultActionGroup(); + leftUpdateableActionGroup.add(new StopAction()); + if (myCreateExitAction) { + leftUpdateableActionGroup.add(closeMessageViewAction); + } + leftUpdateableActionGroup.add(new PreviousOccurenceToolbarAction(this)); + leftUpdateableActionGroup.add(new NextOccurenceToolbarAction(this)); + leftUpdateableActionGroup.add(new ExportToTextFileToolbarAction(myExporterToTextFile)); + leftUpdateableActionGroup.add(new ToolbarHelpAction(myHelpId)); + + DefaultActionGroup rightUpdateableActionGroup = new DefaultActionGroup(); + fillRightToolbarGroup(rightUpdateableActionGroup); + + JPanel toolbarPanel = new JPanel(new GridLayout(1, 2)); + final ActionManager actionManager = ActionManager.getInstance(); + myLeftToolbar = + (ActionToolbarEx)actionManager.createActionToolbar(ActionPlaces.COMPILER_MESSAGES_TOOLBAR, leftUpdateableActionGroup, false); + toolbarPanel.add(myLeftToolbar.getComponent()); + myRightToolbar = + (ActionToolbarEx)actionManager.createActionToolbar(ActionPlaces.COMPILER_MESSAGES_TOOLBAR, rightUpdateableActionGroup, false); + toolbarPanel.add(myRightToolbar.getComponent()); + + return toolbarPanel; + } + + protected void fillRightToolbarGroup(DefaultActionGroup group) { + group.add(new ExpandAllToolbarAction(myTreeExpander)); + group.add(new CollapseAllToolbarAction(myTreeExpander)); + group.add(new HideWarningsAction()); + group.add(myAutoScrollToSourceHandler.createToggleAction()); + } + + public OccurenceInfo goNextOccurence() { + return myOccurenceNavigatorSupport.goNextOccurence(); + } + + public OccurenceInfo goPreviousOccurence() { + return myOccurenceNavigatorSupport.goPreviousOccurence(); + } + + public boolean hasNextOccurence() { + return myOccurenceNavigatorSupport.hasNextOccurence(); + } + + public boolean hasPreviousOccurence() { + return myOccurenceNavigatorSupport.hasPreviousOccurence(); + } + + public String getNextOccurenceActionName() { + return myOccurenceNavigatorSupport.getNextOccurenceActionName(); + } + + public String getPreviousOccurenceActionName() { + return myOccurenceNavigatorSupport.getPreviousOccurenceActionName(); + } + + private class StopAction extends AnAction { + public StopAction() { + super("Stop", null, IconLoader.getIcon("/actions/suspend.png")); + } + + public void actionPerformed(AnActionEvent e) { + if (canControlProcess()) { + stopProcess(); + } + myLeftToolbar.updateActions(); + myRightToolbar.updateActions(); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + presentation.setEnabled(canControlProcess() && !isProcessStopped()); + } + } + + private class HideWarningsAction extends ToggleAction { + public HideWarningsAction() { + super("Hide warnings", null, IconLoader.getIcon("/compiler/hideWarnings.png")); + } + + public boolean isSelected(AnActionEvent event) { + return ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + final ErrorTreeViewConfiguration configuration = ErrorTreeViewConfiguration.getInstance(myProject); + final boolean hideWarnings = configuration.isHideWarnings(); + if (hideWarnings != flag) { + configuration.setHideWarnings(flag); + myBuilder.updateTree(); + } + } + } + + private class MyTreeExpander implements TreeExpander { + public void expandAll() { + NewErrorTreeViewPanel.this.expandAll(); + } + + public boolean canExpand() { + return true; + } + + public void collapseAll() { + NewErrorTreeViewPanel.this.collapseAll(); + } + + public boolean canCollapse() { + return true; + } + } + + private class MyOccurenceNavigatorSupport extends OccurenceNavigatorSupport { + public MyOccurenceNavigatorSupport(final Tree tree) { + super(tree); + } + + protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) { + Object userObject = node.getUserObject(); + if (!(userObject instanceof ErrorTreeNodeDescriptor)) { + return null; + } + final ErrorTreeNodeDescriptor descriptor = (ErrorTreeNodeDescriptor)userObject; + final ErrorTreeElement element = descriptor.getElement(); + if (element instanceof NavigatableMessageElement) { + return ((NavigatableMessageElement)element).getNavigatable(); + } + return null; + } + + public String getNextOccurenceActionName() { + return "Next Message"; + } + + public String getPreviousOccurenceActionName() { + return "Previous Message"; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/SimpleMessageElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/SimpleMessageElement.java new file mode 100644 index 00000000000..9153b0e7e9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/SimpleMessageElement.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 12, 2004 + */ +public class SimpleMessageElement extends ErrorTreeElement{ + private final String[] myMessage; + private final Object myData; + + public SimpleMessageElement(ErrorTreeElementKind kind, String[] text, Object data) { + super(kind); + myMessage = text; + myData = data; + } + + public String[] getText() { + return myMessage; + } + + public Object getData() { + return myData; + } + + public String getExportTextPrefix() { + return ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestErrorViewAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestErrorViewAction.java new file mode 100644 index 00000000000..2969569f7fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestErrorViewAction.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.MessageView; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 13, 2004 + */ +public abstract class TestErrorViewAction extends AnAction{ + private static final int MESSAGE_COUNT = 1000; + private long myMillis = 0L; + private int myMessageCount = 0; + + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + final ErrorTreeView view = createView(project); + openView(project, view.getComponent()); + myMillis = 0L; + myMessageCount = 0; + new Thread() { + public void run() { + for (int idx = 0; idx < MESSAGE_COUNT; idx++) { + addMessage(view, new String[] {"This is a warning test message" + idx + " line1", "This is a warning test message" + idx + " line2"}, MessageCategory.WARNING); + } + while (getMessageCount() < MESSAGE_COUNT) { + try { + Thread.sleep(100); + } + catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + String statistics = "Duration = " + myMillis; + addMessage(view, new String[] {statistics}, MessageCategory.STATISTICS); + System.out.println(statistics); + while (getMessageCount() < MESSAGE_COUNT + 1) { + try { + Thread.sleep(100); + } + catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + System.out.println("Expected " + (MESSAGE_COUNT + 1) + " messages;"); + } + }.start(); + } + + public synchronized int getMessageCount() { + return myMessageCount; + } + + public synchronized void incMessageCount() { + myMessageCount++; + } + + private void addMessage(final ErrorTreeView view, final String[] message, final int type) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final long start = System.currentTimeMillis(); + view.addMessage(type, message, null, -1, -1, null); + final long duration = System.currentTimeMillis() - start; + myMillis += duration; + incMessageCount(); + } + }, ModalityState.NON_MMODAL); + } + + protected abstract ErrorTreeView createView(Project project); + protected abstract String getContentName(); + + protected void openView(Project project, JComponent component) { + final MessageView messageView = project.getComponent(MessageView.class); + final Content content = PeerFactory.getInstance().getContentFactory().createContent(component, getContentName(), true); + messageView.addContent(content); + messageView.setSelectedContent(content); + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.MESSAGES_WINDOW); + if (toolWindow != null) { + toolWindow.activate(null); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestNewErrorViewAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestNewErrorViewAction.java new file mode 100644 index 00000000000..8d7bd74dd47 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/actions/TestNewErrorViewAction.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.errorTreeView.actions; + +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.openapi.project.Project; +import com.intellij.util.ui.ErrorTreeView; + +/** + * @author Eugene Zhuravlev + * Date: Nov 13, 2004 + */ +public class TestNewErrorViewAction extends TestErrorViewAction{ + protected ErrorTreeView createView(Project project) { + return new NewErrorTreeViewPanel(project, null); + } + + protected String getContentName() { + return "NewView"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorTreeViewConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorTreeViewConfiguration.java new file mode 100644 index 00000000000..92e37eaf3eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorTreeViewConfiguration.java @@ -0,0 +1,60 @@ +package com.intellij.ide.errorTreeView.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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 org.jdom.Element; + +public class ErrorTreeViewConfiguration implements JDOMExternalizable, ProjectComponent { + public boolean IS_AUTOSCROLL_TO_SOURCE = false; + public boolean HIDE_WARNINGS = false; + + public static ErrorTreeViewConfiguration getInstance(Project project) { + return project.getComponent(ErrorTreeViewConfiguration.class); + } + + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getComponentName() { + return "ErrorTreeViewConfiguration"; + } + + public boolean isAutoscrollToSource() { + return IS_AUTOSCROLL_TO_SOURCE; + } + + public void setAutoscrollToSource(boolean autoscroll) { + IS_AUTOSCROLL_TO_SOURCE = autoscroll; + } + + public boolean isHideWarnings() { + return HIDE_WARNINGS; + } + + public void setHideWarnings(boolean value) { + HIDE_WARNINGS = value; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java new file mode 100644 index 00000000000..cd978bfe2ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java @@ -0,0 +1,106 @@ +package com.intellij.ide.errorTreeView.impl; + +import com.intellij.ide.ExporterToTextFile; +import com.intellij.ide.errorTreeView.ErrorTreeElement; +import com.intellij.ide.errorTreeView.ErrorViewStructure; +import com.intellij.ide.errorTreeView.NavigatableMessageElement; + +import javax.swing.*; +import javax.swing.event.ChangeListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.TooManyListenersException; + +/** + * + */ +public class ErrorViewTextExporter implements ExporterToTextFile { + private JCheckBox myCbShowDetails; + private ErrorViewStructure myStructure; + private ChangeListener myChangeListener; + + public ErrorViewTextExporter(ErrorViewStructure treeStructure) { + myStructure = treeStructure; + myCbShowDetails = new JCheckBox("Details"); + myCbShowDetails.setSelected(true); + myCbShowDetails.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myChangeListener.stateChanged(null); + } + }); + } + + public JComponent getSettingsEditor() { + return myCbShowDetails; + } + + public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { + if (myChangeListener != null) throw new TooManyListenersException(); + myChangeListener = listener; + } + + public void removeSettingsChangedListener(ChangeListener listener) { + myChangeListener = null; + } + + public String getReportText() { + StringBuffer buffer = new StringBuffer(); + getReportText(buffer, (ErrorTreeElement)myStructure.getRootElement(), myCbShowDetails.isSelected(), 0); + return buffer.toString(); + } + + public String getDefaultFilePath() { + return ""; + } + + public void exportedTo(String filePath) { + } + + public boolean canExport() { + return true; + } + + private void getReportText(StringBuffer buffer, final ErrorTreeElement element, boolean withUsages, final int indent) { + final String newline = System.getProperty("line.separator"); + Object[] children = myStructure.getChildElements(element); + for (int idx = 0; idx < children.length; idx++) { + final Object child = children[idx]; + if(!(child instanceof ErrorTreeElement)){ + continue; + } + if(!withUsages && child instanceof NavigatableMessageElement){ + continue; + } + final ErrorTreeElement childElement = (ErrorTreeElement)child; + if (buffer.length() > 0) { + buffer.append(newline); + } + shift(buffer, indent); + exportElement(childElement, buffer, indent, newline); + getReportText(buffer, childElement, withUsages, indent + 4); + } + } + + public void exportElement(ErrorTreeElement element, final StringBuffer buffer, int baseIntent, final String newline) { + final int startLength = buffer.length(); + buffer.append(element.getKind().getPresentableText()); + buffer.append(element.getExportTextPrefix()); + final int localIndent = startLength - buffer.length(); + + final String[] text = element.getText(); + if (text != null && text.length > 0) { + buffer.append(text[0]); + for (int i = 1; i < text.length; i++) { + buffer.append(newline); + shift(buffer, baseIntent + localIndent); + buffer.append(text[i]); + } + } + } + + private void shift(StringBuffer buffer, int indent) { + for(int i=0; i 0 && properties.getProperty(s) == null) references.add(s); + } + } + } + + + /** + * Removes each two leading '\', removes leading $, removes {} + * Examples: + * $qqq -> qqq + * \$qqq -> qqq if dummy attributes are collected too, null otherwise + * \\$qqq -> qqq + * ${qqq} -> qqq + */ + private static String referenceToAttribute(String attrib, boolean includeDummies){ + while (attrib.startsWith("\\\\")){ + attrib = attrib.substring(2); + } + if (attrib.startsWith("\\$")){ + if (includeDummies) { + attrib = attrib.substring(1); + } else return null; + } + LOG.assertTrue(StringUtil.startsWithChar(attrib, '$'), "Invalid attribute: " + attrib); + attrib = attrib.substring(1); + if (StringUtil.startsWithChar(attrib, '{')) { + String cleanAttribute = null; + for (int i = 1; i < attrib.length(); i++) { + char currChar = attrib.charAt(i); + if (currChar == '{' || currChar == '.') { + // Invalid match + cleanAttribute = null; + break; + } + else if (currChar == '}') { + // Valid match + cleanAttribute = attrib.substring(1, i); + break; + } + } + attrib = cleanAttribute; + } + else { + for (int i = 0; i < attrib.length(); i++) { + char currChar = attrib.charAt(i); + if (currChar == '{' || currChar == '}' || currChar == '.') { + attrib = attrib.substring(0, i); + break; + } + } + } + return attrib; + } + + public static String mergeTemplate(Map attributes, String content) throws IOException{ + initVelocity(); + VelocityContext context = new VelocityContext(); + Iterator names = attributes.keySet().iterator(); + while (names.hasNext()){ + String name = (String)names.next(); + context.put(name, attributes.get(name)); + } + return mergeTemplate(content, context); + } + + public static String mergeTemplate(Properties attributes, String content) throws IOException{ + initVelocity(); + VelocityContext context = new VelocityContext(); + Enumeration names = attributes.propertyNames(); + while (names.hasMoreElements()){ + String name = (String)names.nextElement(); + context.put(name, attributes.getProperty(name)); + } + return mergeTemplate(content, context); + } + + private static String mergeTemplate(String templateContent, final VelocityContext context) throws IOException{ + initVelocity(); + StringWriter stringWriter = new StringWriter(); + try { + Velocity.evaluate(context, stringWriter, "", templateContent); + } catch (VelocityException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog("Error parsing file template", "Velocity Error"); + } + }); + } + return stringWriter.toString(); + } + + public static FileTemplate cloneTemplate(FileTemplate template){ + FileTemplateImpl templateImpl = (FileTemplateImpl) template; + return (FileTemplate)templateImpl.clone(); + } + + public static void copyTemplate(FileTemplate src, FileTemplate dest){ + dest.setExtension(src.getExtension()); + dest.setName(src.getName()); + dest.setText(src.getText()); + dest.setAdjust(src.isAdjust()); + } + + private static synchronized void initVelocity(){ + try{ + if (!ourVelocityInitialized){ + LogSystem emptyLogSystem = new LogSystem(){ + public void init(RuntimeServices runtimeServices) throws Exception{ + } + + public void logVelocityMessage(int i, String s){ + //todo[myakovlev] log somethere? + } + }; + + //todo[myakovlev] since Velocity does not use "file.resource.loader.path" property, these lines can be deleted + File modifiedPatternsPath = new File(PathManager.getConfigPath()); + modifiedPatternsPath = new File(modifiedPatternsPath, "fileTemplates"); + modifiedPatternsPath = new File(modifiedPatternsPath, "includes"); + + Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, emptyLogSystem); + Velocity.setProperty(Velocity.RESOURCE_LOADER, "file,class"); + //todo[myakovlev] implement my oun Loader, with ability to load templates from classpath + Velocity.setProperty("file.resource.loader.class", MyFileResourceLoader.class.getName()); + Velocity.setProperty("class.resource.loader.class", MyClasspathResourceLoader.class.getName()); + Velocity.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, modifiedPatternsPath.getAbsolutePath()); + Velocity.setProperty(Velocity.INPUT_ENCODING, FileTemplate.ourEncoding); + Velocity.init(); + ourVelocityInitialized = true; + } + } + catch (Exception e){ + LOG.error("Unable to init Velocity", e); + } + } + + public static boolean createFromTemplate(final PsiElement[] myCreatedElement, final FileTemplate template, final String fileName, Properties props, final Project project, final PsiDirectory directory) throws Exception{ + if (template == null){ + throw new IllegalArgumentException("template cannot be null"); + } + FileTemplateManager.getInstance().addRecentName(template.getName()); + String mergedText; + + //Set escaped references to dummy values to remove leading "\" (if not already explicitely set) + String[] dummyRefs = calculateAttributes(template.getText(), props, true); + for (int i = 0; i < dummyRefs.length; i++) { + String dummyRef = dummyRefs[i]; + props.setProperty(dummyRef, ""); + } + + try{ + if (template.isJavaClassTemplate()){ + String packageName = props.getProperty(PACKAGE_ATTR); + if(packageName == null || packageName.length() == 0){ + props = new Properties(props); + props.setProperty(PACKAGE_ATTR, PACKAGE_ATTR); + } + } + mergedText = template.getText(props); + } + catch (Exception e){ + throw e; + } + final String templateText = StringUtil.convertLineSeparators(mergedText); + final Exception[] commandException = new Exception[1]; + CommandProcessor.getInstance().executeCommand(project, new Runnable(){ + public void run(){ + final Runnable run = new Runnable(){ + public void run(){ + try{ + FileType fileType = FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()); + if (fileType.equals(StdFileTypes.JAVA)) { + String extension = template.getExtension(); + myCreatedElement[0] = createClassOrInterface(project, directory, templateText, template.isAdjust(), extension); + } + else if (fileType.equals(StdFileTypes.ASPECT)) { + myCreatedElement[0] = createAspect(project, directory, templateText, template.isAdjust()); + } + else{ + myCreatedElement[0] = createPsiFile(project, directory, templateText, fileName, template.getExtension()); + } + } + catch (Exception ex){ + commandException[0] = ex; + } + } + }; + ApplicationManager.getApplication().runWriteAction(run); + } + }, "Create "+ (template.isJavaClassTemplate() ? "Class" : "File") +" From Template", null); + if(commandException[0] != null){ + throw commandException[0]; + } + return true; + } + + public static PsiAspect createAspect(Project project, PsiDirectory directory, String content, boolean reformat) throws IncorrectOperationException { + String extension = StdFileTypes.ASPECT.getDefaultExtension(); + PsiAspectFile file = (PsiAspectFile) PsiManager.getInstance(project).getElementFactory().createFileFromText("myaspect." + extension, content); + PsiAspect[] aspects = file.getAspects(); + if (aspects == null || aspects.length == 0) { + throw new IncorrectOperationException("This template did not produce an aspect!"); + } + PsiAspect aspect = aspects[0]; + if (reformat) { + CodeStyleManager.getInstance(project).reformat(file); + } + String fileName = aspect.getName() + "." + extension; + directory.checkCreateFile(fileName); + file = (PsiAspectFile) file.setName(fileName); + file = (PsiAspectFile) directory.add(file); + return file.getAspects()[0]; + } + + public static PsiClass createClassOrInterface(Project project, + PsiDirectory directory, + String content, + boolean reformat, + String extension) throws IncorrectOperationException{ + if (extension == null) extension = StdFileTypes.JAVA.getDefaultExtension(); + PsiJavaFile psiJavaFile = (PsiJavaFile)PsiManager.getInstance(project).getElementFactory().createFileFromText("myclass" + "." + extension, content); + PsiClass[] classes = psiJavaFile.getClasses(); + if(classes == null || classes.length == 0){ + throw new IncorrectOperationException("This template did not produce Java class nor interface!"); + } + PsiClass createdClass = classes[0]; + if(reformat){ + CodeStyleManager.getInstance(project).reformat(psiJavaFile); + } + String className = createdClass.getName(); + String fileName = className + "." + extension; + if(createdClass.isInterface()){ + directory.checkCreateInterface(className); + } + else{ + directory.checkCreateClass(className); + } + psiJavaFile = (PsiJavaFile)psiJavaFile.setName(fileName); + psiJavaFile = (PsiJavaFile) directory.add(psiJavaFile); + + return psiJavaFile.getClasses()[0]; + } + + private static PsiFile createPsiFile(Project project, PsiDirectory directory, String content, String fileName, String extension) throws IncorrectOperationException{ + directory.checkCreateFile(fileName + "." + extension); + PsiFile file = PsiManager.getInstance(project).getElementFactory().createFileFromText(fileName + "." + extension, content); + file = (PsiFile)directory.add(file); + return file; + } + + public static String indent(String methodText, Project project, FileType fileType) { + int indent = CodeStyleSettingsManager.getSettings(project).getIndentSize(fileType); + StringBuffer buf = new StringBuffer(); + for(int i = 0; i < indent; i++) buf.append(' '); + + return methodText.replaceAll("\n", "\n" + buf.toString()); + } + + public static class MyClasspathResourceLoader extends ClasspathResourceLoader{ + private static final String INCLUDES_PATH = "fileTemplates/includes/"; + + public synchronized InputStream getResourceStream(String name) throws ResourceNotFoundException{ + InputStream resourceStream = super.getResourceStream(INCLUDES_PATH + name + ".ft"); + return resourceStream; + } + } + + public static class MyFileResourceLoader extends FileResourceLoader{ + public void init(ExtendedProperties configuration){ + super.init(configuration); + + File modifiedPatternsPath = new File(PathManager.getConfigPath()); + modifiedPatternsPath = new File(modifiedPatternsPath, "fileTemplates"); + modifiedPatternsPath = new File(modifiedPatternsPath, "includes"); + + try{ + Field pathsField = FileResourceLoader.class.getDeclaredField("paths"); + pathsField.setAccessible(true); + Vector paths = (Vector)pathsField.get(this); + paths.removeAllElements(); + paths.addElement(modifiedPatternsPath.getAbsolutePath()); + if(ApplicationManager.getApplication().isUnitTestMode()){ + File file1 = new File(PathManagerEx.getTestDataPath()); + File testsDir = new File(new File(file1, "ide"), "fileTemplates"); + paths.add(testsDir.getAbsolutePath()); + } + } + catch (Exception e){ + throw new RuntimeException(e); + } + } + } + + public static void setClassAndMethodNameProperties (Properties properties, PsiClass aClass, PsiMethod method) { + String className = aClass.getQualifiedName(); + if (className == null) className = ""; + properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, className); + + String methodName = method.getName(); + if (methodName == null) methodName = ""; + properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); + } + + public static void setPackageNameAttribute (Properties properties, PsiDirectory directory) { + PsiPackage aPackage = directory.getPackage(); + if (aPackage != null) { + String packageName = aPackage.getQualifiedName(); + if (packageName.length() > 0) { + properties.setProperty(FileTemplate.ATTRIBUTE_PACKAGE_NAME, packageName); + return; + } + } + properties.setProperty(FileTemplate.ATTRIBUTE_PACKAGE_NAME, FileTemplate.ATTRIBUTE_PACKAGE_NAME); + } + + public static boolean canCreateFromTemplate (PsiDirectory[] dirs, FileTemplate template) { + FileType fileType = FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()); + if (fileType.equals(StdFileTypes.UNKNOWN)) return false; + if ( + template.isJavaClassTemplate() || + fileType.equals(StdFileTypes.GUI_DESIGNER_FORM) + ){ + for (int i = 0; i < dirs.length; i++) { + PsiDirectory dir = dirs[i]; + if (dir.getPackage() != null) return true; + } + return false; + } + return true; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java new file mode 100644 index 00000000000..02851e1a2c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java @@ -0,0 +1,238 @@ +package com.intellij.ide.fileTemplates.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.actions.EditFileTemplatesAction; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog; +import com.intellij.ide.fileTemplates.ui.SelectTemplateDialog; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import org.apache.velocity.runtime.parser.ParseException; + +import java.util.*; + +public class CreateFromTemplateGroup extends ActionGroup{ + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.actions.CreateFromTemplateGroup"); + + public void update(AnActionEvent event){ + super.update(event); + Presentation presentation = event.getPresentation(); + FileTemplate[] allTemplates = FileTemplateManager.getInstance().getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++){ + FileTemplate template = allTemplates[i]; + if(canCreateFromTemplate(event, template)){ + presentation.setEnabled(true); + return; + } + } + presentation.setEnabled(false); + } + + public AnAction[] getChildren(AnActionEvent e){ + FileTemplateManager manager = FileTemplateManager.getInstance(); + FileTemplate[] templates; + templates = manager.getAllTemplates(); + List result = new ArrayList(); + + boolean showAll = templates.length <= FileTemplateManager.RECENT_TEMPLATES_SIZE; + if (!showAll) { + List recentNames = manager.getRecentNames(); + templates = new FileTemplate[recentNames.size()]; + int i = 0; + for (Iterator iterator = recentNames.iterator(); iterator.hasNext(); i++) { + String name = (String)iterator.next(); + templates[i] = FileTemplateManager.getInstance().getTemplate(name); + } + } + + Arrays.sort(templates, new Comparator() { + public int compare(FileTemplate template1, FileTemplate template2) { + // java first + if (template1.isJavaClassTemplate() && !template2.isJavaClassTemplate()) { + return -1; + } + if (template2.isJavaClassTemplate() && !template1.isJavaClassTemplate()) { + return 1; + } + + // group by type + int i = template1.getExtension().compareTo(template2.getExtension()); + if (i != 0) { + return i; + } + + // group by name if same type + return template1.getName().compareTo(template2.getName()); + } + }); + + for (int i = 0; i < templates.length; i++){ + FileTemplate template = templates[i]; + if(canCreateFromTemplate(e, template)){ + CreateFromTemplateAction action = new CreateFromTemplateAction(template); + result.add(action); + } + } + + if (!result.isEmpty()) { + if (!showAll) { + result.add(new CreateFromTemplatesAction("From File Template ...")); + } + + result.add(Separator.getInstance()); + result.add(new EditFileTemplatesAction("Edit File Templates...")); + } + + return result.toArray(new AnAction[result.size()]); +} + + private boolean canCreateFromTemplate(AnActionEvent e, FileTemplate template){ + DataContext dataContext = e.getDataContext(); + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null) return false; + + PsiDirectory[] dirs = view.getDirectories(); + if (dirs.length == 0) return false; + + return FileTemplateUtil.canCreateFromTemplate(dirs, template); + } + + private class CreateFromTemplatesAction extends AnAction{ + + public CreateFromTemplatesAction(String title){ + super(title); + } + + public final void actionPerformed(AnActionEvent e){ + DataContext dataContext = e.getDataContext(); + + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null) { + return; + } + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + PsiDirectory dir = PackageUtil.getOrChooseDirectory(view); + if (dir == null) return; + + FileTemplate[] allTemplates = FileTemplateManager.getInstance().getAllTemplates(); + List available = new ArrayList(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplate template = allTemplates[i]; + if (canCreateFromTemplate(e, template)) { + available.add(template); + } + } + + SelectTemplateDialog dialog = new SelectTemplateDialog(project, dir); + dialog.show(); + FileTemplate selectedTemplate = dialog.getSelectedTemplate(); + if(selectedTemplate != null){ + PsiElement createdElement = showCreateFromTemplateDialog(project, dir, selectedTemplate); + if (createdElement != null){ + view.selectElement(createdElement); + } + } + } + + } + + private PsiElement showCreateFromTemplateDialog(Project project, PsiDirectory directory, FileTemplate template){ + CreateFromTemplateDialog dialog; + try{ + dialog = new CreateFromTemplateDialog(project, directory, template); + } + catch (ParseException ex){ + String message = "Unable to parse template \""+template.getName()+"\""; + message += "\nError message: "+ ex.getMessage(); + Messages.showMessageDialog(project, message, "Invalid Template", Messages.getErrorIcon()); + LOG.debug(message); + LOG.debug(ex); + return null; + } + if(needToShowDialog(template)){ + dialog.show(); + return dialog.getCreatedElement(); + } + else{ + Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(); + Properties properties = new Properties(defaultProperties); + String fileName = null; + LOG.assertTrue(template.isJavaClassTemplate()); + if(template.isJavaClassTemplate()){ + String packageName = directory.getPackage().getQualifiedName(); + properties.setProperty(FileTemplateUtil.PACKAGE_ATTR, packageName); + } + PsiElement[] element = new PsiElement[1]; + try{ + FileTemplateUtil.createFromTemplate(element, template, fileName, properties, project, directory); + } + catch (Exception e){ + Messages.showMessageDialog(project, e.getMessage(), "Cannot Create " + (template.isJavaClassTemplate() ? "Class" : "File"), Messages.getErrorIcon()); + } + return element[0]; + } + } + + /** + * @return false if all template attributes can be defined. + */ + private boolean needToShowDialog(FileTemplate template){ + if(template == null) return false; + if(!template.isJavaClassTemplate()) return true; //Will show filename attribute + + Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(); + defaultProperties.put(FileTemplateUtil.PACKAGE_ATTR, FileTemplateUtil.PACKAGE_ATTR); + + try { + return template.getUnsetAttributes(defaultProperties).length > 0; + } catch (ParseException e) { + throw new RuntimeException("Unable to parse template \""+template.getName()+"\"", e); + } + } + + + private class CreateFromTemplateAction extends AnAction{ + private FileTemplate myTemplate; + + public CreateFromTemplateAction(FileTemplate template){ + super(template.getName(), null, FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()).getIcon()); + myTemplate = template; + } + + public final void actionPerformed(AnActionEvent e){ + DataContext dataContext = e.getDataContext(); + + IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + if (view == null) { + return; + } + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + + FileTemplateManager.getInstance().addRecentName(myTemplate.getName()); + PsiDirectory dir = PackageUtil.getOrChooseDirectory(view); + if (dir == null) return; + PsiElement createdElement = showCreateFromTemplateDialog(project, dir, myTemplate); + if (createdElement != null){ + view.selectElement(createdElement); + } + } + + public void update(AnActionEvent e){ + super.update(e); + Presentation presentation = e.getPresentation(); + boolean isEnabled = canCreateFromTemplate(e, myTemplate); + presentation.setEnabled(isEnabled); + presentation.setVisible(isEnabled); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java new file mode 100644 index 00000000000..43c83a9f811 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java @@ -0,0 +1,725 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.*; +import com.intellij.j2ee.J2EEFileTemplateNames; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; + +/* + * @author: MYakovlev + * Date: Jul 26, 2002 + * Time: 12:44:56 PM + */ + +public class AllFileTemplatesConfigurable implements Configurable, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable"); + + private JPanel myMainPanel; + private FileTemplateTab myCurrentTab; + + private FileTemplateTab myTemplatesList; + private FileTemplateTab myPatternsList; + private FileTemplateTab myCodeTemplatesList; + private FileTemplateTab myJ2eeTemplatesList; + private JComponent myToolBar; + private TabbedPaneWrapper myTabbedPane; + private FileTemplateConfigurable myEditor; + private boolean myModified = false; + protected JComponent myEditorComponent; + + private final static int TEMPLATE_ID = 0; + private final static int PATTERN_ID = 1; + private final static int CODE_ID = 2; + private final static int J2EE_ID = 3; + + + private static final Icon ourIcon = IconLoader.getIcon("/general/fileTemplates.png"); + + private FileTemplateTab[] myTabs; + private static final String TEMPLATES_TITLE = "Templates"; + private static final String INCLUDES_TITLE = "Includes"; + private static final String CODE_TITLE = "Code"; + private static final String J2EE_TITLE = "J2EE"; + + public void disposeComponent() { + } + + public void initComponent() { } + + public Icon getIcon() { + return ourIcon; + } + + public String getComponentName() { + return "FileTemplateOptions"; + } + + private void onRemove() { + myCurrentTab.removeSelected(); + myModified = true; + } + + private void onAdd() { + createTemplate("Unnamed", "java", ""); + } + + private FileTemplate createTemplate(String prefName, String extension, String content) { + FileTemplate[] templates = myCurrentTab.getTemplates(); + ArrayList names = new ArrayList(templates.length); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + names.add(template.getName()); + } + String name = prefName; + int i = 0; + while (names.contains(name)) { + name = prefName + " (" + (++i) + ")"; + } + FileTemplate newTemplate = new FileTemplateImpl(content, name, extension); + myCurrentTab.addTemplate(newTemplate); + myModified = true; + myCurrentTab.selectTemplate(newTemplate); + fireListChanged(); + myEditor.focusToNameField(); + return newTemplate; + } + + private void onClone() { + FileTemplate selected = myCurrentTab.getSelectedTemplate(); + if (selected == null) return; + + final FileTemplate[] templates = myCurrentTab.getTemplates(); + ArrayList names = new ArrayList(templates.length); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + names.add(template.getName()); + } + String name1String = "Copy "; + String name2String = "of " + selected.getName(); + String name = name1String + name2String; + int i = 0; + while (names.contains(name)) { + name = name1String + (++i) + " " + name2String; + } + FileTemplate newTemplate = new FileTemplateImpl(selected.getText(), name, selected.getExtension()); + myCurrentTab.addTemplate(newTemplate); + myModified = true; + myCurrentTab.selectTemplate(newTemplate); + fireListChanged(); + } + + public String getDisplayName() { + return "File Templates"; + } + + public String getHelpTopic() { + int index = myTabbedPane.getSelectedIndex(); + switch (index) { + case 0: + return "fileTemplates.templates"; + case 1: + return "fileTemplates.includes"; + case 2: + return "fileTemplates.code"; + case 3: + return "fileTemplates.j2ee"; + default: + throw new IllegalStateException("wrong index: " + index); + } + } + + public JComponent createComponent() { + myTemplatesList = new FileTemplateTabAsList(TEMPLATES_TITLE) { + public void onTemplateSelected() { + onListSelectionChanged(); + } + }; + myPatternsList = new FileTemplateTabAsList(INCLUDES_TITLE) { + public void onTemplateSelected() { + onListSelectionChanged(); + } + }; + myCodeTemplatesList = new FileTemplateTabAsList(CODE_TITLE) { + public void onTemplateSelected() { + onListSelectionChanged(); + } + }; + myCurrentTab = myTemplatesList; + myJ2eeTemplatesList = new FileTemplateTabAsTree(J2EE_TITLE) { + public void onTemplateSelected() { + onListSelectionChanged(); + } + + protected FileTemplateTabAsTree.TreeNode initModel() { + ArrayList categories = new ArrayList(); + categories.add(new TreeNode("EJB", ModuleType.EJB.getNodeIcon(true), new TreeNode[]{ + new TreeNode("Java code templates", StdFileTypes.JAVA.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.ENTITY_CLASS_BMP_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.ENTITY_CLASS_CMP_1x_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.ENTITY_CLASS_CMP_2x_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.ENTITY_HOME_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.ENTITY_LOCAL_HOME_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.LOCAL_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.REMOTE_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.SESSION_CLASS_STATEFUL_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.SESSION_CLASS_STATELESS_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.SESSION_HOME_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.SESSION_LOCAL_HOME_INTERFACE_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.MESSAGE_CLASS_TEMPLATE), + }), + new TreeNode("Deployment descriptors", StdFileTypes.XML.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.EJB_JAR_XML_1_1), + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.EJB_JAR_XML_2_0), + }), + })); + categories.add(new TreeNode("Application", ModuleType.J2EE_APPLICATION.getNodeIcon(true), new TreeNode[]{ + new TreeNode("Deployment descriptors", StdFileTypes.XML.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.APPLICATION_XML_1_2), + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.APPLICATION_XML_1_3), + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.APPLICATION_XML_1_4), + }), + })); + categories.add(new TreeNode("Web", ModuleType.WEB.getNodeIcon(true), new TreeNode[]{ + new TreeNode("Java code templates", StdFileTypes.JAVA.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.SERVLET_CLASS_TEMPLATE), + new TreeNode(StdFileTypes.JAVA.getIcon(), J2EEFileTemplateNames.FILTER_CLASS_TEMPLATE), + }), + new TreeNode("Deployment descriptors", StdFileTypes.XML.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.WEB_XML_22), + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.WEB_XML_23), + new TreeNode(StdFileTypes.XML.getIcon(), J2EEFileTemplateNames.WEB_XML_24), + }), + new TreeNode("Jsp files", StdFileTypes.JSP.getIcon(), new TreeNode[]{ + new TreeNode(StdFileTypes.JSP.getIcon(), J2EEFileTemplateNames.JSP_FILE) + }), + })); + + FileTemplateGroupDescriptorFactory[] templateGroupFactories = (FileTemplateGroupDescriptorFactory[])ApplicationManager.getApplication().getComponents(FileTemplateGroupDescriptorFactory.class); + for (int i = 0; i < templateGroupFactories.length; i++) { + FileTemplateGroupDescriptor fileTemplatesDescriptor = templateGroupFactories[i].getFileTemplatesDescriptor(); + if (fileTemplatesDescriptor != null) { + categories.add(createNode(fileTemplatesDescriptor)); + } + } + + return new TreeNode("ROOT", null, categories.toArray(new TreeNode[categories.size()])); + } + }; + myTabs = new FileTemplateTab[]{myTemplatesList, myPatternsList, myCodeTemplatesList, myJ2eeTemplatesList}; + myTabbedPane = new TabbedPaneWrapper(); + myTabbedPane.installKeyboardNavigation(); + myTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + for (int i = 0; i < myTabs.length; i++) { + FileTemplateTab tab = myTabs[i]; + myTabbedPane.addTab(tab.getTitle(), new JScrollPane(tab.getComponent())); + } + + myTabbedPane.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + onTabChanged(); + } + }); + + DefaultActionGroup group = new DefaultActionGroup(); + AnAction removeAction = new AnAction("Remove Template", null, IconLoader.getIcon("/general/remove.png")) { + public void actionPerformed(AnActionEvent e) { + onRemove(); + } + + public void update(AnActionEvent e) { + super.update(e); + FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); + e.getPresentation().setEnabled(selectedItem != null && !isInternalTemplate(selectedItem.getName(), myCurrentTab.getTitle())); + } + }; + AnAction addAction = new AnAction("Create Template", null, IconLoader.getIcon("/general/add.png")) { + public void actionPerformed(AnActionEvent e) { + onAdd(); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(!(myCurrentTab == myCodeTemplatesList || myCurrentTab == myJ2eeTemplatesList)); + } + }; + AnAction cloneAction = new AnAction("Copy Template", null, IconLoader.getIcon("/actions/copy.png")) { + public void actionPerformed(AnActionEvent e) { + onClone(); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(myCurrentTab != myCodeTemplatesList + && myCurrentTab != myJ2eeTemplatesList + && myCurrentTab.getSelectedTemplate() != null); + } + }; + AnAction resetAction = new AnAction("Reset To Default", null, IconLoader.getIcon("/actions/reset.png")) { + public void actionPerformed(AnActionEvent e) { + onReset(); + } + + public void update(AnActionEvent e) { + super.update(e); + FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); + FileTemplateManager manager = FileTemplateManager.getInstance(); + e.getPresentation().setEnabled(selectedItem != null + && !selectedItem.isDefault() + && + manager.getDefaultTemplate(selectedItem.getName(), selectedItem.getExtension()) != + null); + } + }; + group.add(addAction); + group.add(removeAction); + group.add(cloneAction); + group.add(resetAction); + addAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myCurrentTab.getComponent()); + removeAction.registerCustomShortcutSet(CommonShortcuts.DELETE, + myCurrentTab.getComponent()); + + myToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(); + + myEditor = new FileTemplateConfigurable(); + + myEditor.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + onEditorChanged(); + } + }); + myMainPanel = new JPanel(new GridBagLayout()) { + public void doLayout() { + doMainPanelLayout(); + } + }; + // Layout manager is ignored + myMainPanel.add(myToolBar, + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); + myMainPanel.add(myTabbedPane.getComponent(), + new GridBagConstraints(0, 1, 1, 1, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, + new Insets(2, 2, 2, 2), 0, 0)); + myEditorComponent = myEditor.createComponent(); + myMainPanel.add(myEditorComponent, + new GridBagConstraints(1, 0, 1, 2, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(2, 2, 2, 2), 0, 0)); + + myMainPanel.setMinimumSize(new Dimension(400, 300)); + myMainPanel.setPreferredSize(new Dimension(700, 500)); + return myMainPanel; + } + + private FileTemplateTabAsTree.TreeNode createNode(FileTemplateDescriptor descriptor) { + if (descriptor instanceof FileTemplateGroupDescriptor) { + FileTemplateDescriptor[] children = ((FileTemplateGroupDescriptor)descriptor).getTemplates(); + FileTemplateTabAsTree.TreeNode[] nodes = new FileTemplateTabAsTree.TreeNode[children.length]; + for (int i = 0; i < nodes.length; i++) { + nodes[i] = createNode(children[i]); + } + return new FileTemplateTabAsTree.TreeNode(((FileTemplateGroupDescriptor)descriptor).getTitle(), descriptor.getIcon(), nodes); + } + + return new FileTemplateTabAsTree.TreeNode(descriptor.getIcon(), descriptor.getFileName()); + } + + private void onReset() { + FileTemplate selected = myCurrentTab.getSelectedTemplate(); + if (selected != null) { + if (Messages.showOkCancelDialog("Reset to original template?", "Reset Template", Messages.getQuestionIcon()) != + DialogWrapper.OK_EXIT_CODE) { + return; + } + FileTemplateImpl template = (FileTemplateImpl)selected; + + template.resetToDefault(); + myEditor.reset(); + myModified = true; + } + } + + private void onEditorChanged() { + fireListChanged(); + } + + + private void onTabChanged() { + int selectedIndex = myTabbedPane.getSelectedIndex(); + if (0 <= selectedIndex && selectedIndex < myTabs.length) { + myCurrentTab = myTabs[selectedIndex]; + } + onListSelectionChanged(); + } + + private void onListSelectionChanged() { + FileTemplate selectedValue = myCurrentTab.getSelectedTemplate(); + FileTemplate prevTemplate = myEditor == null ? null : myEditor.getTemplate(); + if (prevTemplate != selectedValue) { + //selection has changed + if (myEditor.isModified()) { + try { + myModified = true; + myEditor.apply(); + fireListChanged(); + } + catch (ConfigurationException e) { + LOG.error(e); + } + } + if (selectedValue == null) { + myEditor.setTemplate(null, FileTemplateManager.getInstance().getDefaultTemplateDescription()); + } + else { + selectTemplate(selectedValue); + } + } + } + + private void selectTemplate(FileTemplate template) { + VirtualFile defDesc = null; + if (myCurrentTab == myTemplatesList) { + defDesc = FileTemplateManager.getInstance().getDefaultTemplateDescription(); + } + else if (myCurrentTab == myPatternsList) { + defDesc = FileTemplateManager.getInstance().getDefaultIncludeDescription(); + } + if (myEditor.getTemplate() != template) { + myEditor.setTemplate(template, defDesc); + final boolean isInternal = isInternalTemplate(template.getName(), myCurrentTab.getTitle()); + myEditor.setShowInternalMessage(isInternal ? " " : null); + myEditor.setShowAdjustCheckBox(myTemplatesList == myCurrentTab); + } + } + + // internal template could not be removed and should be rendered bold + public static boolean isInternalTemplate(String templateName, String templateTabTitle) { + if (templateName == null) return false; + if (Comparing.strEqual(templateTabTitle, TEMPLATES_TITLE)) { + return Comparing.strEqual(templateName, FileTemplateManager.INTERNAL_CLASS_TEMPLATE_NAME) || + Comparing.strEqual(templateName, FileTemplateManager.INTERNAL_INTERFACE_TEMPLATE_NAME) || + Comparing.strEqual(templateName, FileTemplateManager.INTERNAL_ENUM_TEMPLATE_NAME) || + Comparing.strEqual(templateName, FileTemplateManager.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME); + } + if (Comparing.strEqual(templateTabTitle, CODE_TITLE)) { + return true; + } + if (Comparing.strEqual(templateTabTitle, J2EE_TITLE)) { + return true; + } + if (Comparing.strEqual(templateTabTitle, INCLUDES_TITLE)) { + return Comparing.strEqual(templateName, FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); + } + + return false; + } + + private void doMainPanelLayout() { + Dimension toolbarPreferredSize = myToolBar.getPreferredSize(); + Dimension mainPanelSize = myMainPanel.getSize(); + Dimension scrollPanePreferedSize = myTabbedPane.getComponent().getPreferredSize(); + if (mainPanelSize.width < 1 || mainPanelSize.height < 1) { + return; + } + int leftWidth = scrollPanePreferedSize.width; + leftWidth = Math.min(leftWidth, mainPanelSize.width / 5); + leftWidth = Math.max(leftWidth, 300); //to prevent tabs from scrolling + //todo[myakovlev] Calculate tabs preferred size + leftWidth = Math.max(leftWidth, toolbarPreferredSize.width); + int x = 2; + int y = 2; + int width = toolbarPreferredSize.width; + int height = toolbarPreferredSize.height; + myToolBar.setBounds(x, y, width, height); + y += height + 2; + width = leftWidth + 2; + height = Math.max(1, mainPanelSize.height - 2 - y); + myTabbedPane.getComponent().setBounds(x, y, width, height); + x += width + 4; + y = 2; + width = Math.max(1, mainPanelSize.width - 2 - x); + height = Math.max(1, mainPanelSize.height - 2 - y); + myEditorComponent.setBounds(x, y, width, height); + myEditorComponent.revalidate(); + } + + private void initLists() { + FileTemplateManager templateManager = FileTemplateManager.getInstance(); + FileTemplate[] templates = templateManager.getAllTemplates(); + FileTemplate[] internals = templateManager.getInternalTemplates(); + FileTemplate[] templatesAndInternals = ArrayUtil.mergeArrays(internals, templates, FileTemplate.class); + myTemplatesList.init(templatesAndInternals); + myPatternsList.init(templateManager.getAllPatterns()); + myCodeTemplatesList.init(templateManager.getAllCodeTemplates()); + myJ2eeTemplatesList.init(templateManager.getAllJ2eeTemplates()); + } + + public boolean isModified() { + return myModified || myEditor.isModified(); + } + + /** + * If apply is acceptable, returns true. If no, returns false and fills error string. + */ + public boolean canApply(final boolean showErrorDialog, String[] errorString) { + for (int i = 0; i < myTabs.length; i++) { + FileTemplateTab list = myTabs[i]; + if (!canApply(showErrorDialog, errorString, list)) return false; + } + return true; + } + + public boolean canApply(final boolean showErrorDialog, String[] errorString, FileTemplateTab list) { + final FileTemplate[] templates = myCurrentTab.getTemplates(); + ArrayList allNames = new ArrayList(); + FileTemplate itemWithError = null; + String errorMessage = null; + String errorTitle = null; + boolean errorInName = true; + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + boolean isClassTemplate = Comparing.strEqual(template.getName(), + FileTemplateManager.INTERNAL_CLASS_TEMPLATE_NAME); + boolean isInterfaceTemplate = Comparing.strEqual(template.getName(), + FileTemplateManager.INTERNAL_INTERFACE_TEMPLATE_NAME); + if (isClassTemplate || isInterfaceTemplate) continue; + String currName = template.getName(); + String currExt = template.getExtension(); + if (currName.length() == 0) { + itemWithError = template; + errorMessage = "Please specify a name for this template"; + errorTitle = "Template Name Not Specified"; + errorString[0] = "Please specify template name"; + break; + } + if (allNames.contains(currName)) { + itemWithError = template; + errorMessage = "Please specify a different name for this template"; + errorTitle = "Template already exists"; + errorString[0] = "Template with such name already exists. Please specify a different template name"; + break; + } + if (currExt.length() == 0) { + itemWithError = template; + errorMessage = "Please specify an extension for this template"; + errorTitle = "Template Extension Not Specified"; + errorString[0] = "Please specify template extension"; + errorInName = false; + break; + } + allNames.add(currName); + } + if (itemWithError == null) { + return true; + } + else { + final String _errorString = errorMessage; + final String _errorTitle = errorTitle; + final boolean _errorInName = errorInName; + myTabbedPane.setSelectedIndex(Arrays.asList(myTabs).indexOf(list)); + selectTemplate(itemWithError); + list.selectTemplate(itemWithError); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (showErrorDialog) { + Messages.showMessageDialog(myMainPanel, _errorString, _errorTitle, Messages.getErrorIcon()); + } + if (_errorInName) { + myEditor.focusToNameField(); + } + else { + myEditor.focusToExtensionField(); + } + } + }); + return false; + } + } + + private void fireListChanged() { + myCurrentTab.fireDataChanged(); + if (myMainPanel != null) { + myMainPanel.revalidate(); + } + } + + public void apply() throws ConfigurationException { + if (myEditor != null && myEditor.isModified()) { + myModified = true; + myEditor.apply(); + } + String[] errorString = new String[1]; + if (!canApply(false, errorString)) { + throw new ConfigurationException(errorString[0]); + } + + // Apply templates + ArrayList newModifiedItems = new ArrayList(); + FileTemplate[] templates = myTemplatesList.getTemplates(); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + newModifiedItems.add(template); + } + FileTemplateManager templatesManager = FileTemplateManager.getInstance(); + apply(newModifiedItems, myTemplatesList.savedTemplates, TEMPLATE_ID, templatesManager.getAllTemplates()); + + // Apply patterns + newModifiedItems = new ArrayList(); + templates = myPatternsList.getTemplates(); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + newModifiedItems.add(template); + } + apply(newModifiedItems, myPatternsList.savedTemplates, PATTERN_ID, templatesManager.getAllPatterns()); + + //Apply code templates + newModifiedItems = new ArrayList(); + templates = myCodeTemplatesList.getTemplates(); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + newModifiedItems.add(template); + } + apply(newModifiedItems, myCodeTemplatesList.savedTemplates, CODE_ID, templatesManager.getAllCodeTemplates()); + + //Apply J2EE templates + newModifiedItems = new ArrayList(); + templates = myJ2eeTemplatesList.getTemplates(); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + newModifiedItems.add(template); + } + apply(newModifiedItems, myJ2eeTemplatesList.savedTemplates, J2EE_ID, templatesManager.getAllJ2eeTemplates()); + + FileTemplateManager.getInstance().saveAll(); + + if (myEditor != null) { + myModified = false; + fireListChanged(); + reset(); + } + } + + private static void removeTemplate(FileTemplate aTemplate, int listId, boolean fromDiskOnly) { + FileTemplateManager manager = FileTemplateManager.getInstance(); + if (listId == AllFileTemplatesConfigurable.TEMPLATE_ID) { + if (!aTemplate.isInternal()) { + manager.removeTemplate(aTemplate, fromDiskOnly); + } else { + manager.removeInternal(aTemplate); + } + } + else if (listId == PATTERN_ID) { + manager.removePattern(aTemplate, fromDiskOnly); + } + else if (listId == CODE_ID) { + manager.removeCodeTemplate(aTemplate, fromDiskOnly); + } + else if (listId == J2EE_ID) { + manager.removeJ2eeTemplate(aTemplate, fromDiskOnly); + } + } + + private static void apply(ArrayList newModifiedItems, + Map savedTemplate2ModifiedTemplate, + int listId, + FileTemplate[] templates) { + FileTemplateManager templatesManager = FileTemplateManager.getInstance(); + if (listId == TEMPLATE_ID) { + FileTemplate[] internals = templatesManager.getInternalTemplates(); + templates = ArrayUtil.mergeArrays(internals, templates, FileTemplate.class); + } + ArrayList savedTemplates = new ArrayList(); + // Delete removed and fill savedTemplates + for (int i = 0; i < templates.length; i++) { + FileTemplate aTemplate = templates[i]; + FileTemplate aModifiedTemplate = (FileTemplate)savedTemplate2ModifiedTemplate.get(aTemplate); + if (newModifiedItems.contains(aModifiedTemplate)) { + savedTemplates.add(aTemplate); + } + else { + removeTemplate(aTemplate, listId, false); + savedTemplate2ModifiedTemplate.remove(aTemplate); + } + } + // Now all removed templates deleted from table, savedTemplates contains all templates in table + for (Iterator iterator = savedTemplates.iterator(); iterator.hasNext();) { + FileTemplate aTemplate = (FileTemplate)iterator.next(); + FileTemplate aModifiedTemplate = (FileTemplate)savedTemplate2ModifiedTemplate.get(aTemplate); + LOG.assertTrue(aModifiedTemplate != null); + aTemplate.setAdjust(aModifiedTemplate.isAdjust()); + if (!aModifiedTemplate.isDefault()) { + FileTemplateUtil.copyTemplate(aModifiedTemplate, aTemplate); + } + else { + if (!aTemplate.isDefault()) { + removeTemplate(aTemplate, listId, true); + } + } + } + + // Add new templates to table + for (Iterator iterator = newModifiedItems.iterator(); iterator.hasNext();) { + FileTemplate aModifiedTemplate = (FileTemplate)iterator.next(); + LOG.assertTrue(aModifiedTemplate != null); + if (!savedTemplate2ModifiedTemplate.containsValue(aModifiedTemplate)) { + if (listId == AllFileTemplatesConfigurable.TEMPLATE_ID) { + templatesManager.addTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); + } + else if (listId == AllFileTemplatesConfigurable.PATTERN_ID) { + templatesManager.addPattern(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); + } + else if (listId == CODE_ID) { + templatesManager.addCodeTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); + } + else if (listId == J2EE_ID) { + templatesManager.addJ2eeTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); + } + } + } + } + + public void reset() { + myEditor.reset(); + initLists(); + myModified = false; + } + + public void disposeUIResources() { + if (myEditor != null) { + myEditor.disposeUIResources(); + myEditor = null; + myEditorComponent = null; + } + myMainPanel = null; + } + + public JComponent getPreferredFocusedComponent() { + return myCurrentTab.getComponent(); + } + + public void createNewTemplate(String preferredName, String extension, String text) { + createTemplate(preferredName, extension, text); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java new file mode 100644 index 00000000000..bd48835e389 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java @@ -0,0 +1,388 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.codeInsight.template.impl.TemplateColors; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.lexer.CompositeLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.MergingLexerAdapter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.util.LexerHighlighter; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.io.IOException; +import java.util.Vector; + +/* + * @author: MYakovlev + * Date: Jul 26, 2002 + * Time: 12:46:00 PM + */ + +public class FileTemplateConfigurable implements Configurable { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable"); + + private JPanel myMainPanel; + private FileTemplate myTemplate; + private Editor myTemplateEditor; + private JTextField myNameField; + private JTextField myExtensionField; + private JCheckBox myAdjustBox; + private JPanel myTopPanel; + private Splitter mySplitter; + private JEditorPane myDescriptionComponent; + private boolean myModified = false; + private Vector myChangeListeners = new Vector(); + private VirtualFile myDefaultDescription; + + public FileTemplate getTemplate() { + return myTemplate; + } + + public void setTemplate(FileTemplate template, VirtualFile defaultDescription) { + myDefaultDescription = defaultDescription; + myTemplate = template; + reset(); + myNameField.selectAll(); + myExtensionField.selectAll(); + } + + public void setShowInternalMessage(String message) { + if (message == null) { + myTopPanel.removeAll(); + myTopPanel.add(new JLabel("Name:"), + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 2), 0, 0)); + myTopPanel.add(myNameField, + new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0)); + myTopPanel.add(new JLabel("Extension:"), + new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 2, 0, 2), 0, 0)); + myTopPanel.add(myExtensionField, + new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); + myExtensionField.setColumns(7); + } + else { + myTopPanel.removeAll(); + myTopPanel.add(new JLabel(message), + new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + myTopPanel.add(Box.createVerticalStrut(myNameField.getPreferredSize().height), + new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } + myMainPanel.revalidate(); + myTopPanel.repaint(); + } + + public void setShowAdjustCheckBox(boolean show) { + myAdjustBox.setEnabled(show); + } + + public String getDisplayName() { + return "File Templates"; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + myMainPanel = new JPanel(new GridBagLayout()); + myTemplateEditor = createEditor(); + myNameField = new JTextField(); + myExtensionField = new JTextField(); + mySplitter = new Splitter(true, 0.66f); + + myDescriptionComponent = new JEditorPane("text/html", ""); + myDescriptionComponent.setEditable(false); +// myDescriptionComponent.setMargin(new Insets(2, 2, 2, 2)); + +// myDescriptionComponent = new JLabel(); +// myDescriptionComponent.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); +// myDescriptionComponent.setVerticalAlignment(SwingConstants.TOP); + + myAdjustBox = new JCheckBox("Reformat according to style"); + myTopPanel = new JPanel(new GridBagLayout()); + + JPanel secondPanel = new JPanel(new GridBagLayout()); + secondPanel.add(new JLabel("Description:"), + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, + new Insets(0, 0, 2, 0), 0, 0)); + secondPanel.add(new JScrollPane(myDescriptionComponent), + new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(2, 0, 0, 0), 0, 0)); + + myMainPanel.add(myTopPanel, + new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0)); + myMainPanel.add(myAdjustBox, + new GridBagConstraints(0, 1, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0)); + myMainPanel.add(mySplitter, + new GridBagConstraints(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(2, 0, 0, 0), 0, 0)); + mySplitter.setFirstComponent(myTemplateEditor.getComponent()); + mySplitter.setSecondComponent(secondPanel); + setShowInternalMessage(null); + myTemplateEditor.getDocument().addDocumentListener(new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + onTextChanged(); + } + }); + myNameField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + onNameChanged(); + } + }); + myExtensionField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + onNameChanged(); + } + }); + return myMainPanel; + } + + private static Editor createEditor() { + EditorFactory editorFactory = EditorFactory.getInstance(); + Document doc = editorFactory.createDocument(""); + Editor editor = editorFactory.createEditor(doc); + + EditorSettings editorSettings = editor.getSettings(); + editorSettings.setVirtualSpace(false); + editorSettings.setLineMarkerAreaShown(false); + editorSettings.setLineNumbersShown(false); + editorSettings.setFoldingOutlineShown(false); + editorSettings.setAdditionalColumnsCount(3); + editorSettings.setAdditionalLinesCount(3); + + EditorColorsScheme scheme = editor.getColorsScheme(); + scheme.setColor(EditorColors.CARET_ROW_COLOR, null); + + return editor; + } + + private void onTextChanged() { + myModified = true; + } + + public String getNameValue() { + return myNameField.getText(); + } + + public String getExtensionValue() { + return myExtensionField.getText(); + } + + private void onNameChanged() { + ChangeEvent event = new ChangeEvent(this); + for (int i = 0; i < myChangeListeners.size(); i++) { + ChangeListener changeListener = (ChangeListener)myChangeListeners.elementAt(i); + changeListener.stateChanged(event); + } + } + + public void addChangeListener(ChangeListener listener) { + if (!myChangeListeners.contains(listener)) { + myChangeListeners.add(listener); + } + } + + public void removeChangeListener(ChangeListener listener) { + myChangeListeners.remove(listener); + } + + public boolean isModified() { + if (myModified) { + return true; + } + String name = (myTemplate == null) ? "" : myTemplate.getName(); + String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); + if (!Comparing.equal(name, myNameField.getText())) { + return true; + } + if (!Comparing.equal(extension, myExtensionField.getText())) { + return true; + } + if (myTemplate != null) { + if (myTemplate.isAdjust() != myAdjustBox.isSelected()) { + return true; + } + } + return false; + } + + public void apply() throws ConfigurationException { + if (myTemplate != null) { + myTemplate.setText(myTemplateEditor.getDocument().getText()); + String name = myNameField.getText(); + String extension = myExtensionField.getText(); + int lastDotIndex = extension.lastIndexOf("."); + if (lastDotIndex >= 0) { + name = name + extension.substring(0, lastDotIndex + 1); + extension = extension.substring(lastDotIndex + 1); + } + myTemplate.setName(name); + myTemplate.setExtension(extension); + myTemplate.setAdjust(myAdjustBox.isSelected()); + } + myModified = false; + } + + public void reset() { + final String text = (myTemplate == null) ? "" : myTemplate.getText(); + String name = (myTemplate == null) ? "" : myTemplate.getName(); + String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); + String description = (myTemplate == null) ? "" : myTemplate.getDescription(); + if (description == null) { + description = ""; + } + if ((description.length() == 0) && (myDefaultDescription != null)) { + try { + description = new String(myDefaultDescription.contentsToCharArray()); + } + catch (IOException e) { + LOG.error(e); + } + } + boolean adjust = (myTemplate == null) ? false : myTemplate.isAdjust(); + setHighlighter(); + myNameField.setText(name); + myExtensionField.setText(extension); + myAdjustBox.setSelected(adjust); + String desc = description.length() > 0 ? description : ""; + + // [myakovlev] do not delete these stupid lines! Or you get Exception! + myDescriptionComponent.setContentType("text/plain"); + myDescriptionComponent.setEditable(true); + myDescriptionComponent.setText(desc); + myDescriptionComponent.setContentType("text/html"); + myDescriptionComponent.setText(desc); + myDescriptionComponent.setCaretPosition(0); + myDescriptionComponent.setEditable(false); + + CommandProcessor.getInstance().executeCommand(null, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myTemplateEditor.getDocument().replaceString(0, myTemplateEditor.getDocument().getTextLength(), text); + } + }); + } + }, + "", + null); + UndoManager.getGlobalInstance().clearUndoRedoQueue(TextEditorProvider.getInstance().getTextEditor(myTemplateEditor)); + myNameField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); + myExtensionField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); + myModified = false; + } + + public void disposeUIResources() { + myMainPanel = null; + if (myTemplateEditor != null) { + EditorFactory.getInstance().releaseEditor(myTemplateEditor); + myTemplateEditor = null; + } + } + + private void setHighlighter() { + FileType fileType; + if (myTemplate != null) { + String extension = myTemplate.getExtension(); + fileType = FileTypeManager.getInstance().getFileTypeByExtension(extension); + } + else { + fileType = StdFileTypes.PLAIN_TEXT; + } + + FileHighlighter originalHighlighter = fileType.getHighlighter(null); + LexerHighlighter highlighter = new LexerHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme()); + ((EditorEx)myTemplateEditor).setHighlighter(highlighter); + ((EditorEx)myTemplateEditor).repaint(0, myTemplateEditor.getDocument().getTextLength()); + } + + private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{FileTemplateTokenType.TEXT}); + + private static class TemplateHighlighter extends FileHighlighterBase { + private Lexer myLexer; + private FileHighlighter myOriginalHighlighter; + + public TemplateHighlighter(FileHighlighter original) { + myOriginalHighlighter = original; + Lexer originalLexer = original.getHighlightingLexer(); + Lexer templateLexer = new FileTemplateTextLexer(); + templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE); + + myLexer = new CompositeLexer(originalLexer, templateLexer) { + protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) { + if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) { + return type2; + } + else { + return type1; + } + } + }; + } + + public Lexer getHighlightingLexer() { + return myLexer; + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (tokenType == FileTemplateTokenType.MACRO) { + return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); + } + else if (tokenType == FileTemplateTokenType.DIRECTIVE) { + return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); + } + + return myOriginalHighlighter.getTokenHighlights(tokenType); + } + } + + + public void focusToNameField() { + myNameField.selectAll(); + myNameField.requestFocus(); + } + + public void focusToExtensionField() { + myExtensionField.selectAll(); + myExtensionField.requestFocus(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateDescriptionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateDescriptionImpl.java new file mode 100644 index 00000000000..1b020aeb265 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateDescriptionImpl.java @@ -0,0 +1,20 @@ +package com.intellij.ide.fileTemplates.impl; + +import javax.swing.*; + +/** + * author: lesya + */ +public class FileTemplateDescriptionImpl { + private final String myTitle; + private final Icon myIcon; + + public FileTemplateDescriptionImpl(String title, Icon icon) { + myTitle = title; + myIcon = icon; + } + + protected FileTemplateTabAsTree.TreeNode createTreeNode(){ + return new FileTemplateTabAsTree.TreeNode(myIcon, myTitle); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java new file mode 100644 index 00000000000..5ead52edbd8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java @@ -0,0 +1,363 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.ArrayUtil; +import org.apache.velocity.runtime.parser.ParseException; + +import java.io.*; +import java.util.Map; +import java.util.Properties; + +/** + * @author MYakovlev + * Date: Jul 24, 2002 + */ +public class FileTemplateImpl implements FileTemplate, Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateImpl"); + + private VirtualFile myDescription; + private String myContent; + private String myName; + private String myExtension; + private File myTemplateFile; // file to save in + private VirtualFile myTemplateURL; + boolean myRenamed = false; + private boolean myModified = false; + private boolean myReadOnly = false; + private boolean myAdjust = true; + + + private boolean myIsInternal = false; + + /** Creates new template. This template is marked as 'new', i.e. it will be saved to new file at IDEA end. */ + FileTemplateImpl(String content, String name, String extension){ + if(content != null){ + content = StringUtil.convertLineSeparators(content); + } + myContent = content; + myName = replaceFileSeparatorChar(name); + myExtension = extension; + myModified = true; + } + + FileTemplateImpl(File templateFile, String name, String extension, boolean isReadOnly) { + myTemplateFile = templateFile; + myName = replaceFileSeparatorChar(name); + myExtension = extension; + myModified = false; + myReadOnly = isReadOnly; + } + + FileTemplateImpl(VirtualFile templateURL, String name, String extension) { + myTemplateURL = templateURL; + myName = name; + myExtension = extension; + myModified = false; + myReadOnly = true; + } + + public Object clone(){ + try{ + FileTemplate clon = (FileTemplate)super.clone(); + return clon; + } + catch (CloneNotSupportedException e){ + // Should not be here + throw new RuntimeException(e); + } + } + + public String[] getUnsetAttributes(Properties properties) throws ParseException{ + String content; + try{ + content = getContent(); + } + catch (IOException e){ + LOG.error("Unable to read template \""+myName+"\"", e); + return ArrayUtil.EMPTY_STRING_ARRAY; + } + return FileTemplateUtil.calculateAttributes(content, properties, false); + } + + public boolean isDefault(){ + return myReadOnly; + } + + public String getDescription(){ + try{ + return myDescription != null ? new String(myDescription.contentsToCharArray()) : ""; + } + catch (IOException e){ + LOG.error(e); + } + return ""; + } + + void setDescription(VirtualFile file){ + myDescription = file; + } + + public String getName(){ + return myName; + } + + public boolean isJavaClassTemplate(){ + FileType fileType = FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(myExtension); + return fileType.equals(StdFileTypes.JAVA) || fileType.equals(StdFileTypes.ASPECT); + } + + public String getExtension(){ + return myExtension; + } + + public String getText(){ + String text = ""; + try{ + text = getContent(); + } + catch (IOException e){ + LOG.error("Unable to read template \""+myName+"\"", e); + } + return text; + } + + public void setText(String text){ + // for read-only template we will save it later in user-defined templates + if(text == null){ + text = ""; + } + text = StringUtil.convertLineSeparators(text); + if(text.equals(getText())){ + return; + } + myContent = text; + myModified = true; + if(myReadOnly){ + myTemplateFile = null; + myTemplateURL = null; + myReadOnly = false; + } + } + + boolean isModified(){ + return myModified; + } + + /** Read template from file. */ + private String readExternal(File file) throws IOException{ + FileInputStream inputStream = new FileInputStream(file); + String result = readExternal(inputStream); + inputStream.close(); + return result; + } + + /** Read template from URL. */ + private String readExternal(VirtualFile url) throws IOException{ + InputStream inputStream = url.getInputStream(); + String result = readExternal(inputStream); + inputStream.close(); + return result; + } + + /** Read template from stream. Stream does not closed after reading. */ + private String readExternal(InputStream inputStream) throws IOException{ + StringWriter wr = new StringWriter(); + Reader fr = new InputStreamReader(inputStream, ourEncoding); + BufferedReader br = new BufferedReader(fr); + int currChar; + do{ + currChar = br.read(); + if (currChar != -1){ + wr.write(currChar); + } + } + while (currChar != -1); + br.close(); + fr.close(); + return wr.toString(); + } + + /** Removes template file. + */ + void removeFromDisk() { + if(myReadOnly){ + return; + } + else if(myTemplateFile != null){ + if(myTemplateFile.delete()){ + myModified = false; + } + } + } + + /** Save template to file. If template is new, it is saved to specified directory. Otherwise it is saved to file from which it was read. + * If template was not modified, it is not saved. + */ + void writeExternal(File defaultDir) throws IOException{ + if(!myModified){ + if(!myRenamed){ + return; + } + } + if(myRenamed){ + LOG.assertTrue(myTemplateFile != null); + LOG.assertTrue(myTemplateFile.delete()); + myTemplateFile = null; + myRenamed = false; + } + File templateFile = myReadOnly ? null : myTemplateFile; + if(templateFile == null){ + LOG.assertTrue(defaultDir.isDirectory()); + templateFile = new File(defaultDir, myName+"."+myExtension); + } + FileOutputStream fileOutputStream = new FileOutputStream(templateFile); + OutputStreamWriter outputStreamWriter; + try{ + outputStreamWriter = new OutputStreamWriter(fileOutputStream, ourEncoding); + } + catch (UnsupportedEncodingException e){ + Messages.showMessageDialog("Unable to save File Template \""+getName()+"\" using " + ourEncoding, "Error", Messages.getErrorIcon()); + outputStreamWriter = new OutputStreamWriter(fileOutputStream); + } + String content = getContent(); + Project project = ProjectManagerEx.getInstanceEx().getDefaultProject(); + String lineSeparator = CodeStyleSettingsManager.getSettings(project).getLineSeparator(); + + if (!lineSeparator.equals("\n")){ + content = StringUtil.convertLineSeparators(content, lineSeparator); + } + + outputStreamWriter.write(content); + outputStreamWriter.close(); + fileOutputStream.close(); + +// StringReader reader = new StringReader(getContent()); +// FileWriter fileWriter = new FileWriter(templateFile); +// BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); +// for(int currChar = reader.read(); currChar != -1; currChar = reader.read()){ +// bufferedWriter.write(currChar); +// } +// bufferedWriter.close(); +// fileWriter.close(); + myModified = false; + myTemplateFile = templateFile; + } + + public String getText(Map attributes) throws IOException{ + return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getContent())); + } + + public String getText(Properties attributes) throws IOException{ + return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getContent())); + } + + public String toString(){ + return getName(); + } + + private String getContent() throws IOException{ + if(myContent == null){ + if(myTemplateFile != null){ + myContent = StringUtil.convertLineSeparators(readExternal(myTemplateFile)); + } + else if(myTemplateURL != null){ + myContent = StringUtil.convertLineSeparators(readExternal(myTemplateURL)); + } + else{ + myContent = ""; + } + } + return myContent; + } + + void invalidate(){ + if(!myReadOnly){ + if(myTemplateFile != null || myTemplateURL != null){ + myContent = null; + } + } + } + + boolean isNew(){ + return myTemplateFile == null && myTemplateURL == null; + } + + public void setName(String name){ + if(name == null){ + name = ""; + } + else { + name = replaceFileSeparatorChar(name.trim()); + } + if(!myName.equals(name)){ + LOG.assertTrue(!myReadOnly); + myName = name; + myRenamed = true; + myModified = true; + } + } + + public void setExtension(String extension){ + if(extension == null){ + extension = ""; + } + extension = extension.trim(); + if(!myExtension.equals(extension)){ + LOG.assertTrue(!myReadOnly); + myExtension = extension; + myRenamed = true; + myModified = true; + } + } + + public boolean isAdjust(){ + return myAdjust; + } + + public void setAdjust(boolean adjust){ + myAdjust = adjust; + } + + public void resetToDefault() { + LOG.assertTrue(!isDefault()); + VirtualFile file = FileTemplateManager.getInstance().getDefaultTemplate(myName, myExtension); + if (file == null) return; + try { + String text = readExternal(file); + setText(text); + myReadOnly = true; + } catch (IOException e) { + LOG.error ("Error reading template"); + } + } + + private String replaceFileSeparatorChar(String s) { + StringBuffer buffer = new StringBuffer(); + char[] chars = s.toCharArray(); + for (int i = 0; i < chars.length; i++) { + if (chars[i] == File.separatorChar) buffer.append("$"); + else buffer.append(chars[i]); + } + return buffer.toString(); + } + + public void setInternal(boolean isInternal) { + myIsInternal = true; + } + + public boolean isInternal() { + return myIsInternal; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java new file mode 100644 index 00000000000..79711e63129 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -0,0 +1,871 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.plugins.PluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Element; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.text.DateFormat; +import java.util.*; + +/** + * @author MYakovlev + * Date: Jul 24 + * @author 2002 + */ +public class FileTemplateManagerImpl extends FileTemplateManager implements ExportableApplicationComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl"); + private static final String DEFAULT_TEMPLATE_EXTENSION = "ft"; + private static final String DEFAULT_TEMPLATES_TOP_DIR = "fileTemplates"; + private static final String INTERNAL_DIR = "internal"; + private static final String INCLUDES_DIR = "includes"; + private static final String CODETEMPLATES_DIR = "code"; + private static final String J2EE_TEMPLATES_DIR = "j2ee"; + + private String myDefaultTemplatesDir = "."; + private String myTemplatesDir = "fileTemplates"; + private MyTemplates myTemplates; + private RecentTemplatesManager myRecentList = new RecentTemplatesManager(); + private boolean myInvalidated = true; + private FileTemplateManagerImpl myInternalTemplatesManager; + private FileTemplateManagerImpl myPatternsManager; + private FileTemplateManagerImpl myCodeTemplatesManager; + private FileTemplateManagerImpl myJ2eeTemplatesManager; + private VirtualFile myDefaultDescription; + + private static VirtualFile[] ourTopDirs; + private VirtualFileManager myVirtualFileManager; + private FileTypeManagerEx myTypeManager; + + public FileTemplateManagerImpl(VirtualFileManager virtualFileManager, FileTypeManagerEx fileTypeManagerEx) { + myVirtualFileManager = virtualFileManager; + myTypeManager = fileTypeManagerEx; + myInternalTemplatesManager = new FileTemplateManagerImpl(INTERNAL_DIR, + myTemplatesDir + File.separator + INTERNAL_DIR, myVirtualFileManager, myTypeManager); + myPatternsManager = new FileTemplateManagerImpl(INCLUDES_DIR, myTemplatesDir + File.separator + INCLUDES_DIR, myVirtualFileManager, myTypeManager); + myCodeTemplatesManager = new FileTemplateManagerImpl(CODETEMPLATES_DIR, + myTemplatesDir + File.separator + CODETEMPLATES_DIR, myVirtualFileManager, myTypeManager); + myJ2eeTemplatesManager = new FileTemplateManagerImpl(J2EE_TEMPLATES_DIR, + myTemplatesDir + File.separator + J2EE_TEMPLATES_DIR, myVirtualFileManager, myTypeManager); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + migrateTemplatesFromBuild915(); + } + }); + } + }); + } + + private FileTemplateManagerImpl(String defaultTemplatesDir, + String templatesDir, + VirtualFileManager virtualFileManager, + FileTypeManagerEx fileTypeManagerEx) { + myDefaultTemplatesDir = defaultTemplatesDir; + myTemplatesDir = templatesDir; + myVirtualFileManager = virtualFileManager; + myTypeManager = fileTypeManagerEx; + } + + public File[] getExportFiles() { + return new File[]{getParentDirectory(false), PathManager.getDefaultOptionsFile()}; + } + + public String getPresentableName() { + return "File templates"; + } + + public FileTemplate[] getAllTemplates() { + revalidate(); + ensureTemplatesAreLoaded(); + return myTemplates.getAllTemplates(); + } + + public FileTemplate getTemplate(String templateName) { + ensureTemplatesAreLoaded(); + return myTemplates.findByName(templateName); + } + + public FileTemplate addTemplate(String name, String extension) { + revalidate(); + ensureTemplatesAreLoaded(); + LOG.assertTrue(name != null); + LOG.assertTrue(name.length() > 0); + LOG.assertTrue(myTemplates.findByName(name) == null, "Duplicate template " + name); + + FileTemplate fileTemplate = new FileTemplateImpl("", name, extension); + myTemplates.addTemplate(fileTemplate); + return fileTemplate; + } + + public void removeTemplate(FileTemplate template, boolean fromDiskOnly) { + ensureTemplatesAreLoaded(); + myTemplates.removeTemplate(template); + try { + ((FileTemplateImpl) template).removeFromDisk(); + } catch (Exception e) { + LOG.error("Unable to remove template", e); + } + + if (!fromDiskOnly) { + myDeletedTemplatesManager.addName(template.getName() + "." + template.getExtension() + "." + + DEFAULT_TEMPLATE_EXTENSION); + } + + revalidate(); + } + + public void removeInternal(FileTemplate template) { + LOG.assertTrue(myInternalTemplatesManager != null); + myInternalTemplatesManager.removeTemplate(template, true); + } + + public Properties getDefaultProperties() { + Properties props = new Properties(); + + Date date = new Date(); + props.setProperty("DATE", DateFormat.getDateInstance().format(date)); + props.setProperty("TIME", DateFormat.getTimeInstance().format(date)); + Calendar calendar = Calendar.getInstance(); + props.setProperty("YEAR", Integer.toString(calendar.get(Calendar.YEAR))); + props.setProperty("MONTH", Integer.toString(calendar.get(Calendar.MONTH) + 1)); //to correct Calendar bias to 0 + props.setProperty("DAY", Integer.toString(calendar.get(Calendar.DAY_OF_MONTH))); + props.setProperty("HOUR", Integer.toString(calendar.get(Calendar.HOUR_OF_DAY))); + props.setProperty("MINUTE", Integer.toString(calendar.get(Calendar.MINUTE))); + + props.setProperty("USER", System.getProperty("user.name")); + + return props; + } + + private File getParentDirectory(boolean create) { + File configPath = new File(PathManager.getConfigPath()); + File templatesPath = new File(configPath, myTemplatesDir); + if (!templatesPath.exists()) { + if (create) { + final boolean created = templatesPath.mkdirs(); + LOG.assertTrue(created, "Cannot create directory: " + templatesPath.getAbsolutePath()); + } + } + return templatesPath; + } + + private void ensureTemplatesAreLoaded() { + if (!myInvalidated) { + return; + } + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + loadTemplates(); + } + }); + } + + private void loadTemplates() { + VirtualFile[] defaultTemplates = getDefaultTemplates(); + for (int i = 0; i < defaultTemplates.length; i++) { + VirtualFile file = defaultTemplates[i]; + if (file.getName().equals("default.html")) { + myDefaultDescription = file; //todo[myakovlev] + } + } + + File templateDir = getParentDirectory(false); + File[] files = templateDir.listFiles(); + if (files == null) { + files = new File[0]; + } + + if (myTemplates == null) { + myTemplates = new MyTemplates(); + } + List existingTemplates = new ArrayList(); + // Read user-defined templates + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isDirectory()) { + continue; + } + String name = file.getName(); + String extension = myTypeManager.getExtension(name); + name = name.substring(0, name.length() - extension.length() - 1); + FileTemplate existing = myTemplates.findByName(name); + if (existing == null || existing.isDefault()) { + if (existing != null) { + myTemplates.removeTemplate(existing); + } + FileTemplateImpl fileTemplate = new FileTemplateImpl(file, name, extension, false); + //fileTemplate.setDescription(myDefaultDescription); default description will be shown + myTemplates.addTemplate(fileTemplate); + existingTemplates.add(fileTemplate); + } else { + // it is a user-defined template, revalidate it + LOG.assertTrue(!((FileTemplateImpl) existing).isModified()); + ((FileTemplateImpl) existing).invalidate(); + existingTemplates.add(existing); + } + } + LOG.debug("FileTemplateManagerImpl.loadTemplates() reading default templates..."); + // Read default templates + for (int i = 0; i < defaultTemplates.length; i++) { + VirtualFile file = defaultTemplates[i]; + String name = file.getName(); //name.extension.ft , e.g. "NewClass.java.ft" + String extension = myTypeManager.getExtension(name); + name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft" + if (extension.equals("html")) { + continue; + } + LOG.assertTrue(extension.equals(DEFAULT_TEMPLATE_EXTENSION), + file.toString() + " should have *." + DEFAULT_TEMPLATE_EXTENSION + " extension!"); + extension = myTypeManager.getExtension(name); + name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass" extension="java" + FileTemplate aTemplate = myTemplates.findByName(name); + if (aTemplate == null) { + FileTemplate fileTemplate = new FileTemplateImpl(file, name, extension); + myTemplates.addTemplate(fileTemplate); + aTemplate = fileTemplate; + } + VirtualFile description = getDescriptionForTemplate(file); + if (description != null) { + ((FileTemplateImpl) aTemplate).setDescription(description); + } + /*else{ + ((FileTemplateImpl)aTemplate).setDescription(myDefaultDescription); + }*/ + } + FileTemplate[] allTemplates = myTemplates.getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplateImpl template = (FileTemplateImpl) allTemplates[i]; + if (!template.isDefault()) { + if (!existingTemplates.contains(template)) { + if (!template.isNew()) { + myTemplates.removeTemplate(template); + template.removeFromDisk(); + } + } + } + } + + myInvalidated = false; + } + + + private void saveTemplates() { + try { + saveTemplates_(); + if (myInternalTemplatesManager != null) { + myInternalTemplatesManager.saveTemplates(); + } + if (myPatternsManager != null) { + myPatternsManager.saveTemplates(); + } + if (myCodeTemplatesManager != null) { + myCodeTemplatesManager.saveTemplates(); + } + if (myJ2eeTemplatesManager != null) { + myJ2eeTemplatesManager.saveTemplates(); + } + } catch (IOException e) { + LOG.error("Unable to save templates", e); + } + } + + private void saveTemplates_() throws IOException { + if (myTemplates == null) { + return; + } + FileTemplate[] allTemplates = myTemplates.getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplateImpl fileTemplate = (FileTemplateImpl) allTemplates[i]; + if (fileTemplate.isModified()) { + fileTemplate.writeExternal(getParentDirectory(true)); + } + } + } + + public List getRecentNames() { + ensureTemplatesAreLoaded(); + validateRecentNames(); + return myRecentList.getRecentNames(RECENT_TEMPLATES_SIZE); + } + + public void addRecentName(String name) { + myRecentList.addName(name); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public String getComponentName() { + return "FileTemplateManager"; + } + + private MyDeletedTemplatesManager myDeletedTemplatesManager = new MyDeletedTemplatesManager(); + + public void readExternal(Element element) throws InvalidDataException { + Element deletedTemplatesElement = element.getChild("deleted_templates"); + if (deletedTemplatesElement != null) { + myDeletedTemplatesManager.readExternal(deletedTemplatesElement); + } + + Element deletedIncludesElement = element.getChild("deleted_includes"); + if (deletedIncludesElement != null) { + myPatternsManager.myDeletedTemplatesManager.readExternal(deletedIncludesElement); + } + + Element recentElement = element.getChild("recent_templates"); + if (recentElement != null) { + myRecentList.readExternal(recentElement); + } + + Element templatesElement = element.getChild("templates"); + if (templatesElement != null) { + revalidate(); + FileTemplate[] internals = getInternalTemplates(); + List children = templatesElement.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element child = (Element) iterator.next(); + String name = child.getAttributeValue("name"); + boolean reformat = "true".equals(child.getAttributeValue("reformat")); + if (child.getName().equals("internal_template")) { + for (int i = 0; i < internals.length; i++) { + FileTemplate internal = internals[i]; + if (name.equals(internal.getName())) internal.setAdjust(reformat); + } + } else if (child.getName().equals("template")) { + FileTemplate template = getTemplate(name); + if (template != null) { + template.setAdjust(reformat); + } + } + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + saveTemplates(); + validateRecentNames(); + + Element deletedTemplatesElement = new Element("deleted_templates"); + element.addContent(deletedTemplatesElement); + myDeletedTemplatesManager.writeExternal(deletedTemplatesElement); + + Element deletedIncludesElement = new Element("deleted_includes"); + element.addContent(deletedIncludesElement); + myPatternsManager.myDeletedTemplatesManager.writeExternal(deletedIncludesElement); + + Element recentElement = new Element("recent_templates"); + element.addContent(recentElement); + myRecentList.writeExternal(recentElement); + + Element templatesElement = new Element("templates"); + element.addContent(templatesElement); + revalidate(); + FileTemplate[] internals = getInternalTemplates(); + for (int i = 0; i < internals.length; i++) { + templatesElement.addContent(createElement(internals[i], true)); + } + + FileTemplate[] allTemplates = getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplate fileTemplate = allTemplates[i]; + templatesElement.addContent(createElement(fileTemplate, false)); + } + } + + private static Element createElement(FileTemplate template, boolean isInternal) { + Element templateElement = new Element(isInternal ? "internal_template" : "template"); + templateElement.setAttribute("name", template.getName()); + templateElement.setAttribute("reformat", Boolean.toString(template.isAdjust())); + return templateElement; + } + + private void validateRecentNames() { + if (myTemplates != null) { + List allNames = new ArrayList(myTemplates.size()); + FileTemplate[] allTemplates = myTemplates.getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplate fileTemplate = allTemplates[i]; + allNames.add(fileTemplate.getName()); + } + myRecentList.validateNames(allNames); + } + } + + private void revalidate() { + saveAll(); + myInvalidated = true; + if (myTemplates != null) { + FileTemplate[] allTemplates = myTemplates.getAllTemplates(); + for (int i = 0; i < allTemplates.length; i++) { + FileTemplateImpl fileTemplate = (FileTemplateImpl) allTemplates[i]; + fileTemplate.invalidate(); + } + } + } + + public void saveAll() { + saveTemplates(); + } + + public FileTemplate[] getInternalTemplates() { + FileTemplate[] result = new FileTemplate[4]; + result[0] = getInternalTemplate(INTERNAL_CLASS_TEMPLATE_NAME); + result[1] = getInternalTemplate(INTERNAL_INTERFACE_TEMPLATE_NAME); + result[2] = getInternalTemplate(INTERNAL_ENUM_TEMPLATE_NAME); + result[3] = getInternalTemplate(INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME); + return result; + } + + public FileTemplate getInternalTemplate(String templateName) { + LOG.assertTrue(myInternalTemplatesManager != null); + String actualTemplateName = ApplicationManager.getApplication().isUnitTestMode() ? templateName + "ForTest" : templateName; + FileTemplateImpl template = (FileTemplateImpl) myInternalTemplatesManager.getTemplate(actualTemplateName); + + if (template == null) { + String text; + if (!ApplicationManager.getApplication().isUnitTestMode()) { + text = getDefaultClassTemplateText(templateName); + } else { + text = getTestClassTemplateText(templateName); + } + + text = StringUtil.convertLineSeparators(text); + text = StringUtil.replace(text, "$NAME$", "${NAME}"); + text = StringUtil.replace(text, "$PACKAGE_NAME$", "${PACKAGE_NAME}"); + text = StringUtil.replace(text, "$DATE$", "${DATE}"); + text = StringUtil.replace(text, "$TIME$", "${TIME}"); + text = StringUtil.replace(text, "$USER$", "${USER}"); + + template = (FileTemplateImpl) myInternalTemplatesManager.addTemplate(actualTemplateName, "java"); + template.setText(text); + } + + template.setInternal(true); + return template; + } + + private String getTestClassTemplateText(String templateName) { + return "package $PACKAGE_NAME$;\npublic " + internalTemplateToSubject(templateName) + " $NAME$ { }"; + } + + public String internalTemplateToSubject(String templateName) { + return INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME.equals(templateName) ? "@interface" : templateName.toLowerCase(); + } + + private String getDefaultClassTemplateText(String templateName) { + return "/*\n" + + " * Created by IntelliJ IDEA.\n" + + " * User: $USER$\n" + + " * Date: $DATE$\n" + + " * Time: $TIME$\n" + + " */\n" + + "package $PACKAGE_NAME$;\n" + + "public " + internalTemplateToSubject(templateName) + " $NAME$ { }"; + } + + public FileTemplate getCodeTemplate(String templateName) { + return getTemplateFromManager(templateName, myCodeTemplatesManager, "Code"); + } + + public FileTemplate getJ2eeTemplate(String templateName) { + return getTemplateFromManager(templateName, myJ2eeTemplatesManager, "J2EE"); + } + + private FileTemplate getTemplateFromManager(String templateName, + FileTemplateManagerImpl templatesManager, + String templateType) { + LOG.assertTrue(templatesManager != null); + String name = templateName; + String extension = myTypeManager.getExtension(name); + name = name.substring(0, name.length() - extension.length() - 1); + FileTemplate template = templatesManager.getTemplate(name); + if (template != null) { + if (extension.equals(template.getExtension())) { + return template; + } + } else { + VirtualFile[] defaultTemplates = templatesManager.getDefaultTemplates(); + String message = "Unable to find " + templateType + " Template '" + templateName + "' ! Default " + templateType + + " Templates are: "; + if (defaultTemplates != null) { + for (int i = 0; i < defaultTemplates.length; i++) { + VirtualFile defaultTemplate = defaultTemplates[i]; + if (i != 0) { + message += ", "; + } + message += defaultTemplate.getPresentableUrl(); + } + } + LOG.error(message); + } + return null; + } + + + private VirtualFile getDescriptionForTemplate(VirtualFile vfile) { + if (vfile != null) { + VirtualFile parent = vfile.getParent(); + String name = vfile.getName(); //name.extension.ft , f.e. "NewClass.java.ft" + String extension = myTypeManager.getExtension(name); + if (extension.equals(DEFAULT_TEMPLATE_EXTENSION)) { + name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft" + VirtualFile descFile = parent.findChild(name + ".html"); + if (descFile != null && descFile.isValid()) { + return descFile; + } + } + } + return null; + } + + private static List listDir(VirtualFile vfile) { + List result = new ArrayList(); + if (vfile != null && vfile.isDirectory()) { + VirtualFile[] children = vfile.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (!child.isDirectory()) { + result.add(child); + } + } + } + return result; + } + + private static boolean isAspectTemplate(VirtualFile file) { + return file.getNameWithoutExtension().endsWith(".aj"); + } + + private void removeDeletedTemplates(Set files) { + boolean aspectsEnabled = ApplicationManagerEx.getApplicationEx().isAspectJSupportEnabled(); + Set removedSet = new HashSet(); + + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + VirtualFile file = iterator.next(); + String nameWithExtension = file.getName(); + if (!aspectsEnabled && isAspectTemplate(file) || myDeletedTemplatesManager.contains(nameWithExtension)) { + removedSet.add(file); + } + } + + files.removeAll(removedSet); + } + + private VirtualFile getDefaultFromManager(String name, String extension, FileTemplateManagerImpl manager) { + if (manager == null) return null; + VirtualFile[] files = manager.getDefaultTemplates(); + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + if (DEFAULT_TEMPLATE_EXTENSION.equals(file.getExtension())) { + String fullName = file.getNameWithoutExtension(); //Strip .ft + if (fullName != null && fullName.equals(name + "." + extension)) return file; + } + } + return null; + } + + public VirtualFile getDefaultTemplate(String name, String extension) { + VirtualFile result; + if ((result = getDefaultFromManager(name, extension, this)) != null) return result; + if ((result = getDefaultFromManager(name, extension, myInternalTemplatesManager)) != null) return result; + if ((result = getDefaultFromManager(name, extension, myPatternsManager)) != null) return result; + if ((result = getDefaultFromManager(name, extension, myJ2eeTemplatesManager)) != null) return result; + return getDefaultFromManager(name, extension, myCodeTemplatesManager); + } + + private VirtualFile[] getDefaultTemplates() { + if (myDefaultTemplatesDir == null || myDefaultTemplatesDir.length() == 0) { + return VirtualFile.EMPTY_ARRAY; + } + VirtualFile[] topDirs = getTopTemplatesDir(); + if (LOG.isDebugEnabled()) { + String message = "Top dirs found: "; + for (int i = 0; i < topDirs.length; i++) { + VirtualFile topDir = topDirs[i]; + message += (i > 0 ? ", " : "") + topDir.getPresentableUrl(); + } + LOG.debug(message); + } + Set templatesList = new HashSet(); + for (int i = 0; i < topDirs.length; i++) { + VirtualFile topDir = topDirs[i]; + VirtualFile parentDir = myDefaultTemplatesDir.equals(".") ? topDir : topDir.findChild(myDefaultTemplatesDir); + if (parentDir != null) { + templatesList.addAll(listDir(parentDir)); + } + } + removeDeletedTemplates(templatesList); + + return (VirtualFile[]) templatesList.toArray(new VirtualFile[templatesList.size()]); + } + + private VirtualFile[] getTopTemplatesDir() { + if (ourTopDirs != null) { + return ourTopDirs; + } + + Set dirList = new HashSet(); + + appendDefaultTemplatesFromClassloader(FileTemplateManagerImpl.class.getClassLoader(), dirList); + PluginDescriptor[] plugins = PluginManager.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + PluginDescriptor plugin = plugins[i]; + appendDefaultTemplatesFromClassloader(plugin.getLoader(), dirList); + } + + ourTopDirs = dirList.toArray(new VirtualFile[dirList.size()]); + return ourTopDirs; + } + + private void appendDefaultTemplatesFromClassloader(ClassLoader classLoader, Set dirList) { + try { + Enumeration systemResources = classLoader.getResources(DEFAULT_TEMPLATES_TOP_DIR); + if (systemResources != null && systemResources.hasMoreElements()) { + Set urls = new HashSet(); + while (systemResources.hasMoreElements()) { + URL nextURL = (URL) systemResources.nextElement(); + if (!urls.contains(nextURL)) { + urls.add(nextURL); + VirtualFile dir = VfsUtil.findFileByURL(nextURL, myVirtualFileManager); + LOG.assertTrue(dir != null, + "Cannot find file by URL: " + nextURL); + LOG.debug("Top directory: " + dir.getPresentableUrl()); + dirList.add(dir); + } + } + } + } catch (IOException e) { + LOG.error(e); + } + } + + public FileTemplate[] getAllPatterns() { + LOG.assertTrue(myPatternsManager != null); + return myPatternsManager.getAllTemplates(); + } + + public FileTemplate addPattern(String name, String extension) { + LOG.assertTrue(myPatternsManager != null); + return myPatternsManager.addTemplate(name, extension); + } + + public void removePattern(FileTemplate template, boolean fromDiskOnly) { + LOG.assertTrue(myPatternsManager != null); + myPatternsManager.removeTemplate(template, fromDiskOnly); + } + + public FileTemplate[] getAllCodeTemplates() { + LOG.assertTrue(myCodeTemplatesManager != null); + return myCodeTemplatesManager.getAllTemplates(); + } + + public FileTemplate[] getAllJ2eeTemplates() { + LOG.assertTrue(myJ2eeTemplatesManager != null); + return myJ2eeTemplatesManager.getAllTemplates(); + } + + public FileTemplate addCodeTemplate(String name, String extension) { + LOG.assertTrue(myCodeTemplatesManager != null); + return myCodeTemplatesManager.addTemplate(name, extension); + } + + public FileTemplate addJ2eeTemplate(String name, String extension) { + LOG.assertTrue(myJ2eeTemplatesManager != null); + return myJ2eeTemplatesManager.addTemplate(name, extension); + } + + public void removeCodeTemplate(FileTemplate template, boolean fromDiskOnly) { + LOG.assertTrue(myCodeTemplatesManager != null); + myCodeTemplatesManager.removeTemplate(template, fromDiskOnly); + } + + public void removeJ2eeTemplate(FileTemplate template, boolean fromDiskOnly) { + LOG.assertTrue(myJ2eeTemplatesManager != null); + myJ2eeTemplatesManager.removeTemplate(template, fromDiskOnly); + } + + public VirtualFile getDefaultTemplateDescription() { + return myDefaultDescription; + } + + public VirtualFile getDefaultIncludeDescription() { + return myPatternsManager.myDefaultDescription; + } + + private static class MyTemplates { + private List myTemplatesList = new ArrayList(); + + public int size() { + return myTemplatesList.size(); + } + + public void removeTemplate(FileTemplate template) { + myTemplatesList.remove(template); + } + + public FileTemplate[] getAllTemplates() { + return myTemplatesList.toArray(new FileTemplate[myTemplatesList.size()]); + } + + public FileTemplate findByName(String name) { + for (Iterator iterator = myTemplatesList.iterator(); iterator.hasNext();) { + FileTemplate template = (FileTemplate) iterator.next(); + if (template.getName().equals(name)) { + return template; + } + } + return null; + } + + public void addTemplate(FileTemplate newTemplate) { + for (Iterator iterator = myTemplatesList.iterator(); iterator.hasNext();) { + FileTemplate template = (FileTemplate) iterator.next(); + if (template == newTemplate) { + return; + } + if (template.getName().compareToIgnoreCase(newTemplate.getName()) > 0) { + myTemplatesList.add(myTemplatesList.indexOf(template), newTemplate); + return; + } + } + myTemplatesList.add(newTemplate); + } + } + + static class MyDeletedTemplatesManager implements JDOMExternalizable { + public JDOMExternalizableStringList DELETED_DEFAULT_TEMPLATES = new JDOMExternalizableStringList(); + + public void addName(String nameWithExtension) { + if (nameWithExtension != null) { + DELETED_DEFAULT_TEMPLATES.remove(nameWithExtension); + DELETED_DEFAULT_TEMPLATES.add(nameWithExtension); + } + } + + public boolean contains(String nameWithExtension) { + return DELETED_DEFAULT_TEMPLATES.contains(nameWithExtension); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + } + + public static class RecentTemplatesManager implements JDOMExternalizable { + public JDOMExternalizableStringList RECENT_TEMPLATES = new JDOMExternalizableStringList(); + + public void addName(String name) { + if (name != null) { + RECENT_TEMPLATES.remove(name); + RECENT_TEMPLATES.add(name); + } + } + + public List getRecentNames(int max) { + int size = RECENT_TEMPLATES.size(); + int resultSize = Math.min(max, size); + return RECENT_TEMPLATES.subList(size - resultSize, size); + } + + public void validateNames(List validNames) { + RECENT_TEMPLATES.retainAll(validNames); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + } + + + private static final Map old2NewNames = new com.intellij.util.containers.HashMap(); + + static { + old2NewNames.put("NewClass", "Class"); + old2NewNames.put("NewInterface", "Interface"); + old2NewNames.put("CatchBody", "Catch Statement Body"); + old2NewNames.put("ImplementedFunction", "Implemented Method Body"); + old2NewNames.put("OverridenFunction", "Overriden Method Body"); + old2NewNames.put("FromUsageFunction", "New Method Body"); + } + + private static boolean userWasAsked = false; + private static boolean shouldConvert = false; + private static boolean wasConverted = false; + + // migrate templates to the build 915+ format + // return migrated templates + private void migrateTemplatesFromBuild915() { + + if (myInternalTemplatesManager != null) { + userWasAsked = false; + shouldConvert = false; + wasConverted = false; + myInternalTemplatesManager.migrateTemplatesFromBuild915(); + myCodeTemplatesManager.migrateTemplatesFromBuild915(); + if (wasConverted) { + saveAll(); + } + } else { + final FileTemplate[] templates = getAllTemplates(); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + final String name = template.getName(); + final String extension = template.getExtension(); + final String newName = old2NewNames.get(name); + if (newName != null && !template.isDefault() && getDefaultTemplate(newName, extension) != null) { + if (!userWasAsked) { + final int ret = + Messages.showOkCancelDialog("Convert file templates to the new format?", + "Old File Templates Found", Messages.getQuestionIcon()); + userWasAsked = true; + shouldConvert = ret == 0; + } + if (shouldConvert) { + final FileTemplate defaultTemplate = myTemplates.findByName(newName); + if (defaultTemplate != null) { + // avoid duplicates + myTemplates.removeTemplate(defaultTemplate); + } + // load text from file before delete + template.getText(); + template.setName(newName); + + wasConverted = true; + } + } + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java new file mode 100644 index 00000000000..e8e7391da3a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java @@ -0,0 +1,60 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateUtil; + +import javax.swing.*; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Alexey Kudravtsev + */ +abstract class FileTemplateTab { + public Map savedTemplates; + private final String myTitle; + + protected FileTemplateTab(String title) { + myTitle = title; + } + + public abstract JComponent getComponent(); + + public abstract FileTemplate getSelectedTemplate(); + + public abstract void selectTemplate(FileTemplate template); + + public abstract void removeSelected(); + public abstract void onTemplateSelected(); + + public void init(FileTemplate[] templates) { + FileTemplate oldSelection = getSelectedTemplate(); + FileTemplate newSelection = null; + Map templatesToSave = new LinkedHashMap(); + for (int i = 0; i < templates.length; i++) { + FileTemplate aTemplate = templates[i]; + FileTemplate copy = FileTemplateUtil.cloneTemplate(aTemplate); + templatesToSave.put(aTemplate, copy); + if (savedTemplates != null && savedTemplates.get(aTemplate) == oldSelection) { + newSelection = copy; + } + } + savedTemplates = templatesToSave; + initSelection(newSelection); + } + + protected abstract void initSelection(FileTemplate selection); + + public abstract void fireDataChanged(); + + public FileTemplate[] getTemplates() { + return savedTemplates.values().toArray(new FileTemplate[savedTemplates.values().size()]); + } + + public abstract void addTemplate(FileTemplate newTemplate); + + public String getTitle() { + return myTitle; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java new file mode 100644 index 00000000000..684e0ff8b13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java @@ -0,0 +1,120 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.openapi.fileTypes.FileTypeManager; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.util.ArrayList; +import java.util.List; +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +/** + * @author Alexey Kudravtsev + */ +abstract class FileTemplateTabAsList extends FileTemplateTab { + private JList myList = new JList(); + private MyListModel myModel; + + public FileTemplateTabAsList(String title) { + super(title); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myList.setCellRenderer(new MyListCellRenderer()); + myList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + onTemplateSelected(); + } + }); + } + + private class MyListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Icon icon = null; + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof FileTemplate) { + FileTemplate template = (FileTemplate) value; + icon = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension()).getIcon(); + setText(template.getName()); + setFont(getFont().deriveFont(AllFileTemplatesConfigurable.isInternalTemplate(template.getName(), getTitle()) ? Font.BOLD : Font.PLAIN)); + if (!template.isDefault()) { + Color foreground = new Color(0, 0, 210); + if (!isSelected) { + super.setForeground(foreground); + } + } + } + super.setIcon(icon); + return this; + } + } + + public void removeSelected() { + final FileTemplate selectedTemplate = getSelectedTemplate(); + if (selectedTemplate == null) return; + DefaultListModel model = (DefaultListModel) myList.getModel(); + int selectedIndex = myList.getSelectedIndex(); + model.remove(selectedIndex); + if (model.size() > 0) { + myList.setSelectedIndex(Math.min(selectedIndex, model.size() - 1)); + } + onTemplateSelected(); +// myModified = true; +// fireListChanged(); +// onListSelectionChanged(); + } + + private class MyListModel extends DefaultListModel { + public void fireListDataChanged() { + int size = getSize(); + if (size > 0) { + fireContentsChanged(this, 0, size - 1); + } + } + } + + protected void initSelection(FileTemplate selection) { + myModel = new MyListModel(); + myList.setModel(myModel); + final FileTemplate[] templates = savedTemplates.values().toArray(new FileTemplate[savedTemplates.values().size()]); + for (int i = 0; i < templates.length; i++) { + FileTemplate template = templates[i]; + myModel.addElement(template); + } + if (selection != null) { + selectTemplate(selection); + } + else if (myList.getModel().getSize() > 0) myList.setSelectedIndex(0); + } + + public void fireDataChanged() { + myModel.fireListDataChanged(); + } + + public FileTemplate[] getTemplates() { + final int size = myModel.getSize(); + List templates = new ArrayList(size); + for (int i =0; i 127){ + if (Character.isJavaIdentifierStart(yy_lookahead)){ + yy_lookahead = 'A'; + } + else if (Character.isJavaIdentifierPart(yy_lookahead)){ + yy_lookahead = '9'; + } + else{ + yy_lookahead = '#'; + } + } + } + else{ + yy_lookahead = YYEOF; + } + yy_next_state = YY_F; + if (YYEOF != yy_lookahead) { + yy_next_state = yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]]; + } + if (YY_F != yy_next_state) { + yy_state = yy_next_state; + yy_initial = false; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + } + else { + if (YYEOF == yy_lookahead && true == yy_initial) { + myTokenType = null; return; + } + else if (YY_NO_STATE == yy_last_accept_state) { + throw (new Error("Lexical Error: Unmatched Input.")); + } + else { + yy_buffer_index = yy_buffer_end; + yy_anchor = yy_acpt[yy_last_accept_state]; + if (0 != (YY_END & yy_anchor)) { + --yy_buffer_end; + } + if (0 != (YY_START & yy_anchor)) { + ++yy_buffer_start; + } + switch (yy_last_accept_state) { + case 1: + { myTokenType = FileTemplateTokenType.TEXT; return; } + case -2: + break; + case 2: + { myTokenType = FileTemplateTokenType.DIRECTIVE; return; } + case -3: + break; + case 3: + { myTokenType = FileTemplateTokenType.MACRO; return; } + case -4: + break; + case 5: + { myTokenType = FileTemplateTokenType.TEXT; return; } + case -5: + break; + case 6: + { myTokenType = FileTemplateTokenType.MACRO; return; } + case -6: + break; + case 8: + { myTokenType = FileTemplateTokenType.TEXT; return; } + case -7: + break; + default: + yy_error(YY_E_INTERNAL,false); + case -1: + } + yy_initial = true; + yy_state = yy_state_dtrans[yy_lexical_state]; + yy_next_state = YY_NO_STATE; + yy_last_accept_state = YY_NO_STATE; + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java new file mode 100644 index 00000000000..00a196e8366 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java @@ -0,0 +1,9 @@ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.psi.tree.IElementType; + +interface FileTemplateTokenType { + IElementType TEXT = new IElementType("TEXT"); + IElementType MACRO = new IElementType("MACRO"); + IElementType DIRECTIVE = new IElementType("DIRECTIVE"); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java new file mode 100644 index 00000000000..2dd583dc6d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java @@ -0,0 +1,38 @@ +package com.intellij.ide.fileTemplates.ui; + +import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.DimensionService; + +import java.awt.*; + +/* + * @author: MYakovlev + * Date: Oct 18, 2002 + * Time: 1:31:37 PM + */ + +public class ConfigureTemplatesDialog extends SingleConfigurableEditor{ + private static final String DIMENSION_KEY = "#com.intellij.ide.fileTemplates.ConfigureTemplatesDialog"; + + public ConfigureTemplatesDialog(Project project){ + this(project, new AllFileTemplatesConfigurable()); + } + + public ConfigureTemplatesDialog(Project project, AllFileTemplatesConfigurable fileTemplatesConfigurable){ + super(project, fileTemplatesConfigurable); + initSize(); + } + + protected String getDimensionServiceKey(){ + return DIMENSION_KEY; + } + + private void initSize(){ + Dimension size = DimensionService.getInstance().getSize(DIMENSION_KEY); + if (size == null){ + DimensionService.getInstance().setSize(DIMENSION_KEY, new Dimension(700, 500)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java new file mode 100644 index 00000000000..ff90237f02c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java @@ -0,0 +1,100 @@ +package com.intellij.ide.fileTemplates.ui; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import org.apache.velocity.runtime.parser.ParseException; + +import javax.swing.*; +import java.awt.*; +import java.util.Properties; + +public class CreateFromTemplateDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog"); + protected PsiDirectory myDirectory; + protected Project myProject; + protected PsiElement myCreatedElement; + protected CreateFromTemplatePanel myAttrPanel; + protected JComponent myAttrComponent; + protected FileTemplate myTemplate; + + public CreateFromTemplateDialog(Project project, PsiDirectory directory, FileTemplate template) throws ParseException { + super(project, true); + LOG.assertTrue(directory != null, "Directory cannot be null"); + LOG.assertTrue(template != null, "Template cannot be null"); + myDirectory = directory; + myProject = project; + myTemplate = template; + setTitle("New " + template.getName()); + + PsiPackage aPackage = myDirectory.getPackage(); + String packageName = aPackage == null ? "" : aPackage.getQualifiedName(); + Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(); + defaultProperties.setProperty(FileTemplateUtil.PACKAGE_ATTR, packageName); + myAttrPanel = new CreateFromTemplatePanel(myTemplate, defaultProperties); + myAttrComponent = myAttrPanel.getComponent(); + init(); + } + + public PsiElement getCreatedElement(){ + return myCreatedElement; + } + + protected void doOKAction(){ + if(myTemplate == null){ + return; + } + String fileName = null; + Properties props = myAttrPanel.getProperties(); + if (!myTemplate.isJavaClassTemplate()){ + fileName = myAttrPanel.getFileName(); + if (fileName.length() == 0){ + Messages.showMessageDialog(myAttrComponent, "Please enter a file name", "Error", Messages.getErrorIcon()); + return; + } + } + PsiElement[] element = new PsiElement[1]; + try{ + if(FileTemplateUtil.createFromTemplate(element, myTemplate, fileName, props, myProject, myDirectory)){ + myCreatedElement = element[0]; + super.doOKAction(); + } + } + catch (Exception e){ + showErrorMessage(myAttrComponent, myTemplate, e); + } + } + + private static void showErrorMessage(Component parentComponent, FileTemplate template, Exception e){ + Messages.showMessageDialog(parentComponent, filterMessage(e.getMessage()), "Cannot Create " + (template.isJavaClassTemplate() ? "Class" : "File"), Messages.getErrorIcon()); + } + + private static String filterMessage(String message){ + if (message == null) return null; + String ioExceptionPrefix = "java.io.IOException:"; + if (message.startsWith(ioExceptionPrefix)){ + message = message.substring(ioExceptionPrefix.length()); + } + return message; + } + + protected JComponent createCenterPanel(){ + myAttrPanel.ensureFitToScreen(200, 200); + JPanel centerPanel = new JPanel(new GridBagLayout()); + centerPanel.add(myAttrComponent, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0)); + //centerPanel.setBorder(BorderFactory.createCompoundBorder(new TitledBorder("Attributes"), BorderFactory.createEmptyBorder(0, 4, 2, 4))); + return centerPanel; + } + + public JComponent getPreferredFocusedComponent(){ + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myAttrComponent); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplatePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplatePanel.java new file mode 100644 index 00000000000..a4920100668 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/CreateFromTemplatePanel.java @@ -0,0 +1,149 @@ +package com.intellij.ide.fileTemplates.ui; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.util.ArrayUtil; +import org.apache.velocity.runtime.parser.ParseException; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Properties; + +/* + * @author: MYakovlev + */ + +public class CreateFromTemplatePanel{ + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.ui.CreateFromTemplatePanel"); + + private FileTemplate myTemplate; + private JPanel myMainPanel; + private JPanel myAttrPanel; + private JLabel myFilenameLabel = new JLabel("File name:"); + private JTextField myFilenameField = new JTextField(); + private Properties myPredefinedProperties = new Properties(); + private ArrayList> myAttributes = new ArrayList>(); + + private int myLastRow = 0; + + private int myHorisontalMargin = -1; + private int myVerticalMargin = -1; + + public CreateFromTemplatePanel(FileTemplate template, Properties predefinedProperties){ + myTemplate = template; + myPredefinedProperties = predefinedProperties; + } + +/* + public void disposeUIResources(){ + myMainPanel = null; + myAttrPanel = null; + myAttributes = null; + } +*/ + + public JComponent getComponent() throws ParseException { + if (myMainPanel == null){ + myMainPanel = new JPanel(new GridBagLayout()){ + public Dimension getPreferredSize(){ + return getMainPanelPreferredSize(super.getPreferredSize()); + } + }; + myAttrPanel = new JPanel(new GridBagLayout()); + JPanel myScrollPanel = new JPanel(new GridBagLayout()); + updateShown(); + + myScrollPanel.setBorder(null); + myScrollPanel.add(myAttrPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); + myScrollPanel.add(new JPanel(), new GridBagConstraints(0, 1, 1, 1, 0.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0)); + JScrollPane attrScroll = new JScrollPane(myScrollPanel); + attrScroll.setViewportBorder(null); + + myMainPanel.add(attrScroll, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0)); + } + return myMainPanel; + } + + public void ensureFitToScreen(int horisontalMargin, int verticalMargin){ + myHorisontalMargin = horisontalMargin; + myVerticalMargin = verticalMargin; + } + + private Dimension getMainPanelPreferredSize(Dimension superPreferredSize){ + if((myHorisontalMargin > 0) && (myVerticalMargin > 0)){ + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension preferredSize = superPreferredSize; + Dimension maxSize = new Dimension(screenSize.width - myHorisontalMargin, screenSize.height - myVerticalMargin); + int width = Math.min(preferredSize.width, maxSize.width); + int height = Math.min(preferredSize.height, maxSize.height); + if(height < preferredSize.height){ + width = Math.min(width + 50, maxSize.width); // to disable horizontal scroller + } + preferredSize = new Dimension(width, height); + return preferredSize; + } + else{ + return superPreferredSize; + } + } + + private void updateShown() throws ParseException{ + String[] attributes = ArrayUtil.EMPTY_STRING_ARRAY; + ParseException thrownException = null; + + try { + attributes = myTemplate.getUnsetAttributes(myPredefinedProperties); + Arrays.sort(attributes); + } + catch (ParseException e) { + thrownException = e; + } + + Insets insets = new Insets(2, 2, 2, 2); + myAttrPanel.add(Box.createHorizontalStrut(200), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0)); + if(!myTemplate.isJavaClassTemplate()){ + myAttrPanel.add(myFilenameLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, insets, 0, 0)); + myAttrPanel.add(myFilenameField, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, insets, 0, 0)); + } + else{ + myAttrPanel.remove(myFilenameLabel); + myAttrPanel.remove(myFilenameField); + } + + for (int i = 0; i < attributes.length; i++){ + String attribute = attributes[i]; + JLabel label = new JLabel(attribute.replace('_', ' ') + ":"); + JTextField field = new JTextField(); + myAttributes.add(new Pair (attribute, field)); + myAttrPanel.add(label, new GridBagConstraints(0, myLastRow*2+3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, insets, 0, 0)); + myAttrPanel.add(field, new GridBagConstraints(0, myLastRow*2+4, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, insets, 0, 0)); + myLastRow++; + } + + myAttrPanel.repaint(); + myAttrPanel.revalidate(); + myMainPanel.revalidate(); + if(thrownException != null){ + throw thrownException; + } + } + + public String getFileName(){ + String fileName = myFilenameField.getText(); + return fileName == null ? "" : fileName; + } + + public Properties getProperties(){ + Properties result = (Properties) myPredefinedProperties.clone(); + for (Iterator> i = myAttributes.iterator(); i.hasNext();) { + Pair pair = i.next(); + result.put(pair.first, pair.second.getText()); + } + return result; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java new file mode 100644 index 00000000000..44da640e158 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java @@ -0,0 +1,100 @@ +package com.intellij.ide.fileTemplates.ui; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.psi.PsiDirectory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +/* + * @author: MYakovlev + * Date: Aug 22, 2002 + * Time: 1:31:43 PM + */ +public class SelectTemplateDialog extends DialogWrapper{ + private JComboBox myCbxTemplates; + private FileTemplate mySelectedTemplate; + private Project myProject; + private PsiDirectory myDirectory; + + public SelectTemplateDialog(Project project, PsiDirectory directory){ + super(project, true); + myDirectory = directory; + myProject = project; + setTitle("Select Template"); + init(); + } + + protected JComponent createCenterPanel(){ + loadCombo(); + + JButton editTemplatesButton = new FixedSizeButton(myCbxTemplates); + + JPanel centerPanel = new JPanel(new GridBagLayout()); + JLabel selectTemplateLabel = new JLabel("Name:"); + + centerPanel.add(selectTemplateLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); + centerPanel.add(myCbxTemplates, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 50, 0)); + centerPanel.add(editTemplatesButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); + + editTemplatesButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + onEditTemplates(); + } + }); + + return centerPanel; + } + + private void loadCombo(){ + DefaultComboBoxModel model = new DefaultComboBoxModel(); + FileTemplate[] allTemplates = FileTemplateManager.getInstance().getAllTemplates(); + PsiDirectory[] dirs = {myDirectory}; + for (int i = 0; i < allTemplates.length; i++) { + FileTemplate template = allTemplates[i]; + if (FileTemplateUtil.canCreateFromTemplate(dirs, template)) { + model.addElement(template); + } + } + if(myCbxTemplates == null){ + myCbxTemplates = new JComboBox(model); + } + else{ + Object selected = myCbxTemplates.getSelectedItem(); + myCbxTemplates.setModel(model); + if(selected != null){ + myCbxTemplates.setSelectedItem(selected); + } + } + } + + public FileTemplate getSelectedTemplate(){ + return mySelectedTemplate; + } + + protected void doOKAction(){ + mySelectedTemplate = (FileTemplate)myCbxTemplates.getSelectedItem(); + super.doOKAction(); + } + + public void doCancelAction(){ + mySelectedTemplate = null; + super.doCancelAction(); + } + + public JComponent getPreferredFocusedComponent(){ + return myCbxTemplates; + } + + private void onEditTemplates(){ + new ConfigureTemplatesDialog(myProject).show(); + loadCombo(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyBrowserManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyBrowserManager.java new file mode 100644 index 00000000000..aff06957d09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyBrowserManager.java @@ -0,0 +1,78 @@ +package com.intellij.ide.hierarchy; + +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.ide.util.treeView.AlphaComparator; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.SourceComparator; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.TabbedPaneContentUI; +import org.jdom.Element; + +import java.util.Comparator; + +public final class HierarchyBrowserManager implements JDOMExternalizable, ProjectComponent { + public boolean IS_AUTOSCROLL_TO_SOURCE; + public boolean SORT_ALPHABETICALLY; + public boolean HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED; + private final Project myProject; + private ContentManager myContentManager; + + public HierarchyBrowserManager(final Project project) { + myProject = project; + } + + public final void disposeComponent() { + } + + public final void initComponent() { } + + public final void projectOpened() { + myContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(new TabbedPaneContentUI(), true, myProject); + final ToolWindowManager toolWindowManager=ToolWindowManager.getInstance(myProject); + final ToolWindow toolWindow=toolWindowManager.registerToolWindow(ToolWindowId.HIERARCHY, myContentManager.getComponent(),ToolWindowAnchor.RIGHT); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowHierarchy.png")); + new ContentManagerWatcher(toolWindow,myContentManager); + } + + public final void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.HIERARCHY); + myContentManager = null; + } + + public final ContentManager getContentManager() { + return myContentManager; + } + + public static HierarchyBrowserManager getInstance(final Project project) { + return project.getComponent(HierarchyBrowserManager.class); + } + + public final Comparator getComparator() { + if (SORT_ALPHABETICALLY) { + return AlphaComparator.INSTANCE; + } + else { + return SourceComparator.INSTANCE; + } + } + + public final String getComponentName() { + return "HierarchyBrowserManager"; + } + + public final void readExternal(final Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public final void writeExternal(final Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeDescriptor.java new file mode 100644 index 00000000000..a8fb875a55c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeDescriptor.java @@ -0,0 +1,78 @@ +package com.intellij.ide.hierarchy; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.SmartElementDescriptor; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.util.CompositeAppearance; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.usageView.UsageTreeColors; +import com.intellij.usageView.UsageTreeColorsScheme; + +import javax.swing.*; + +public abstract class HierarchyNodeDescriptor extends SmartElementDescriptor { + protected static final Icon BASE_POINTER_ICON = IconLoader.getIcon("/hierarchy/base.png"); + protected CompositeAppearance myHighlightedText; + private Object[] myCachedChildren = null; + protected final boolean myIsBase; + + protected HierarchyNodeDescriptor(final Project project, final NodeDescriptor parentDescriptor, final PsiElement element, final boolean isBase) { + super(project, parentDescriptor, element); + myHighlightedText = new CompositeAppearance(); + myName = ""; + myIsBase = isBase; + } + + public final Object getElement() { + return this; + } + + public abstract boolean isValid(); + + public final Object[] getCachedChildren() { + return myCachedChildren; + } + + public final void setCachedChildren(final Object[] cachedChildren) { + myCachedChildren = cachedChildren; + } + + protected final boolean isMarkReadOnly() { + return true; + } + + protected final boolean isMarkModified() { + return true; + } + + protected static final String getPackageName(final PsiClass psiClass) { + final PsiFile file = psiClass.getContainingFile(); + if (file instanceof PsiJavaFile){ + return ((PsiJavaFile)file).getPackageName(); + } + else{ + return null; + } + } + + public final CompositeAppearance getHighlightedText() { + return myHighlightedText; + } + + protected static TextAttributes getInvalidPrefixAttributes() { + return UsageTreeColorsScheme.getInstance().getScheme().getAttributes(UsageTreeColors.INVALID_PREFIX); + } + + protected static TextAttributes getUsageCountPrefixAttributes() { + return UsageTreeColorsScheme.getInstance().getScheme().getAttributes(UsageTreeColors.NUMBER_OF_USAGES); + } + + protected static TextAttributes getPackageNameAttributes() { + return getUsageCountPrefixAttributes(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java new file mode 100644 index 00000000000..3b9bd11629f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java @@ -0,0 +1,26 @@ +package com.intellij.ide.hierarchy; + +import com.intellij.ui.ColoredTreeCellRenderer; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; + +public final class HierarchyNodeRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, + final int row, final boolean hasFocus) { + if (value instanceof DefaultMutableTreeNode) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + final Object object = node.getUserObject(); + if (object instanceof HierarchyNodeDescriptor) { + final HierarchyNodeDescriptor descriptor = (HierarchyNodeDescriptor)object; + descriptor.getHighlightedText().customize(this); + if (expanded){ + setIcon(descriptor.getOpenIcon()); + } + else{ + setIcon(descriptor.getClosedIcon()); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java new file mode 100644 index 00000000000..2e7e056db8a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java @@ -0,0 +1,171 @@ +package com.intellij.ide.hierarchy; + +import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.TreeBuilderUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiTreeChangeAdapter; +import com.intellij.psi.PsiTreeChangeEvent; +import com.intellij.psi.PsiTreeChangeListener; + +import javax.swing.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Comparator; + +public final class HierarchyTreeBuilder extends AbstractTreeBuilder { + private final Project myProject; + + private final MyTreeSelectionListener mySelectionListener; + private final MyTreeExpansionListener myTreeExpansionListener; + private final PsiTreeChangeListener myPsiTreeChangeListener; + private final MyFileStatusListener myFileStatusListener; + private final MyProjectManagerListener myProjectManagerListener; + + public HierarchyTreeBuilder(final Project project, + final JTree tree, + final DefaultTreeModel treeModel, + final HierarchyTreeStructure treeStructure, + final Comparator comparator + ) { + super(tree, treeModel, treeStructure, comparator); + myProject = project; + + mySelectionListener = new MyTreeSelectionListener(); + myTreeExpansionListener = new MyTreeExpansionListener(); + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + myFileStatusListener = new MyFileStatusListener(); + myProjectManagerListener = new MyProjectManagerListener(); + + initRootNode(); + tree.addTreeSelectionListener(mySelectionListener); + tree.addTreeExpansionListener(myTreeExpansionListener); + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); + FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener); + + ProjectManager.getInstance().addProjectManagerListener(myProject, myProjectManagerListener); + } + + public final Object storeExpandedAndSelectedInfo() { + final ArrayList pathsToExpand = new ArrayList(); + final ArrayList selectionPaths = new ArrayList(); + TreeBuilderUtil.storePaths(this, myRootNode, pathsToExpand, selectionPaths, true); + return new Pair(pathsToExpand, selectionPaths); + } + + public final void restoreExpandedAndSelectedInfo(final Object info) { + final Pair pair = (Pair)info; + TreeBuilderUtil.restorePaths(this, (ArrayList)pair.first, (ArrayList)pair.second, true); + } + + protected boolean isAlwaysShowPlus(final NodeDescriptor nodeDescriptor) { + return myTreeStructure instanceof CallerMethodsTreeStructure; + } + + protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) { + if (nodeDescriptor instanceof HierarchyNodeDescriptor) { + return false; + } + return true; + } + + protected final boolean isSmartExpand() { + return false; + } + + protected final boolean isDisposeOnCollapsing(final NodeDescriptor nodeDescriptor) { + return false; // prevents problems with building descriptors for invalidated elements + } + + public final void dispose() { + if (!isDisposed()) { // because can be called both externally and via my ProjectManagerListener, don't know what will happen earlier + super.dispose(); + myTree.removeTreeSelectionListener(mySelectionListener); + myTree.removeTreeExpansionListener(myTreeExpansionListener); + PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener); + FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener); + ProjectManager.getInstance().removeProjectManagerListener(myProject, myProjectManagerListener); + } + } + + private final class MyTreeSelectionListener implements TreeSelectionListener { + public final void valueChanged(final TreeSelectionEvent e) { + updateSelected(); + } + }; + + private final class MyTreeExpansionListener implements TreeExpansionListener { + public final void treeCollapsed(final TreeExpansionEvent event) { + updateSelected(); + } + + public final void treeExpanded(final TreeExpansionEvent event) { + updateSelected(); + } + }; + + private void updateSelected() { + final TreePath path = myTree.getSelectionPath(); + if (path == null) return; + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + final Object object = node.getUserObject(); + if (!(object instanceof HierarchyNodeDescriptor)) return; + } + + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public final void childAdded(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void childRemoved(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void childReplaced(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void childMoved(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void childrenChanged(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void propertyChanged(final PsiTreeChangeEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + } + + private final class MyFileStatusListener implements FileStatusListener { + public final void fileStatusesChanged() { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public final void fileStatusChanged(final VirtualFile virtualFile) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + } + + private final class MyProjectManagerListener extends ProjectManagerAdapter{ + public void projectClosed(final Project project){ + dispose(); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeStructure.java new file mode 100644 index 00000000000..193bb06d13f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/HierarchyTreeStructure.java @@ -0,0 +1,124 @@ +package com.intellij.ide.hierarchy; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.util.ArrayUtil; + +import java.awt.*; + +public abstract class HierarchyTreeStructure extends AbstractTreeStructure { + protected HierarchyNodeDescriptor myBaseDescriptor; + private HierarchyNodeDescriptor myRoot; + protected final Project myProject; + + protected HierarchyTreeStructure(final Project project, final HierarchyNodeDescriptor baseDescriptor) { + myBaseDescriptor = baseDescriptor; + myProject = project; + myRoot = myBaseDescriptor; + } + + public final HierarchyNodeDescriptor getBaseDescriptor() { + return myBaseDescriptor; + } + + protected final void setBaseElement(final HierarchyNodeDescriptor baseElement) { + myBaseDescriptor = baseElement; + myRoot = myBaseDescriptor; + while(myRoot.getParentDescriptor() != null){ + myRoot = (HierarchyNodeDescriptor)myRoot.getParentDescriptor(); + } + } + + public final NodeDescriptor createDescriptor(final Object element, final NodeDescriptor parentDescriptor) { + if (element instanceof HierarchyNodeDescriptor) { + return (HierarchyNodeDescriptor)element; + } + else if (element instanceof String) { + return new TextInfoNodeDescriptor(parentDescriptor, (String)element, myProject); + } + else { + return null; + } + } + + public final boolean isToBuildChildrenInBackground(final Object element) { + if (element instanceof HierarchyNodeDescriptor){ + final HierarchyNodeDescriptor descriptor = (HierarchyNodeDescriptor)element; + final Object[] cachedChildren = descriptor.getCachedChildren(); + if (cachedChildren == null && descriptor.isValid()){ + return true; + } + } + return false; + } + + public final Object[] getChildElements(final Object element) { + if (element instanceof HierarchyNodeDescriptor) { + final HierarchyNodeDescriptor descriptor = (HierarchyNodeDescriptor)element; + final Object[] cachedChildren = descriptor.getCachedChildren(); + if (cachedChildren == null) { + if (!descriptor.isValid()){ //invalid + descriptor.setCachedChildren(ArrayUtil.EMPTY_OBJECT_ARRAY); + } + else{ + descriptor.setCachedChildren(buildChildren(descriptor)); + } + } + else{ +/* + for(int i = 0; i < cachedChildren.length; i++){ + Object child = cachedChildren[i]; + if (child instanceof HierarchyElement){ + if (!((HierarchyElement)child).getPsiClass().isValid()){ + hierarchyElement.setCachedChildren(new Object[0]); //? + break; + } + } + } +*/ + } + return descriptor.getCachedChildren(); + } + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public final Object getParentElement(final Object element) { + if (element instanceof HierarchyNodeDescriptor) { + return ((HierarchyNodeDescriptor)element).getParentDescriptor(); + } + + return null; + } + + public final void commit() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + } + + public final boolean hasSomethingToCommit() { + return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments(); + } + + protected abstract Object[] buildChildren(HierarchyNodeDescriptor descriptor); + + public final Object getRootElement() { + return myRoot; + } + + private static final class TextInfoNodeDescriptor extends NodeDescriptor { + public TextInfoNodeDescriptor(final NodeDescriptor parentDescriptor, final String text, final Project project) { + super(project, parentDescriptor); + myName = text; + myColor = Color.red; + } + + public final Object getElement() { + return myName; + } + + public final boolean update() { + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseCallHierarchyAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseCallHierarchyAction.java new file mode 100644 index 00000000000..eb3985f6d7e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseCallHierarchyAction.java @@ -0,0 +1,95 @@ +package com.intellij.ide.hierarchy.actions; + +import com.intellij.ide.hierarchy.HierarchyBrowserManager; +import com.intellij.ide.hierarchy.call.CallHierarchyBrowser; +import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; + +import java.awt.*; + +public final class BrowseCallHierarchyAction extends AnAction { + public final void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + + PsiDocumentManager.getInstance(project).commitAllDocuments(); // prevents problems with smart pointers creation + + final PsiMethod method = getMethod(dataContext); + if (method == null) return; + final CallHierarchyBrowser hierarchyBrowser = new CallHierarchyBrowser(project, method); + + final Content content; + + final HierarchyBrowserManager hierarchyBrowserManager = project.getComponent(HierarchyBrowserManager.class); + + final ContentManager contentManager = hierarchyBrowserManager.getContentManager(); + final Content selectedContent = contentManager.getSelectedContent(); + if (selectedContent != null && !selectedContent.isPinned()) { + content = selectedContent; + final Component component = content.getComponent(); + if (component instanceof CallHierarchyBrowser) { + ((CallHierarchyBrowser)component).dispose(); + } + content.setComponent(hierarchyBrowser); + } + else { + content = PeerFactory.getInstance().getContentFactory().createContent(hierarchyBrowser, null, true); + contentManager.addContent(content); + contentManager.addContentManagerListener(new ContentManagerAdapter() { + public void contentRemoved(final ContentManagerEvent event) { + final Content content = event.getContent(); + final Component component = content.getComponent(); + if (component instanceof CallHierarchyBrowser) { + ((CallHierarchyBrowser)component).dispose(); + content.release(); + } + } + }); + } + contentManager.setSelectedContent(content); + hierarchyBrowser.setContent(content); + + final String name = method.getName(); + content.setDisplayName(name); + + final Runnable runnable = new Runnable() { + public void run() { + final String typeName = CallerMethodsTreeStructure.TYPE; + hierarchyBrowser.changeView(typeName); + } + }; + ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.HIERARCHY).activate(runnable); + } + + public final void update(final AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + presentation.setText("Browse Call Hierarchy"); + } + + final DataContext dataContext = event.getDataContext(); + final PsiMethod method = getMethod(dataContext); + presentation.setEnabled(method != null); + } + + private static PsiMethod getMethod(final DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + + final PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + return PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseMethodHierarchyAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseMethodHierarchyAction.java new file mode 100644 index 00000000000..cef0bc88486 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseMethodHierarchyAction.java @@ -0,0 +1,135 @@ +package com.intellij.ide.hierarchy.actions; + +import com.intellij.ide.hierarchy.HierarchyBrowserManager; +import com.intellij.ide.hierarchy.method.MethodHierarchyBrowser; +import com.intellij.ide.hierarchy.method.MethodHierarchyTreeStructure; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; + +import java.awt.*; + +public final class BrowseMethodHierarchyAction extends AnAction { + public final void actionPerformed(final AnActionEvent e){ + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + PsiDocumentManager.getInstance(project).commitAllDocuments(); // prevents problems with smart pointers creation + final PsiMethod method = getMethod(dataContext); + final MethodHierarchyBrowser hierarchyBrowser = new MethodHierarchyBrowser(project, method); + + final Content content; + + final HierarchyBrowserManager hierarchyBrowserManager = project.getComponent(HierarchyBrowserManager.class); + + final ContentManager contentManager = hierarchyBrowserManager.getContentManager(); + final Content selectedContent = contentManager.getSelectedContent(); + if (selectedContent != null && !selectedContent.isPinned()) { + content = selectedContent; + final Component component = content.getComponent(); + if (component instanceof MethodHierarchyBrowser) { + ((MethodHierarchyBrowser)component).dispose(); + } + content.setComponent(hierarchyBrowser); + } + else { + content = PeerFactory.getInstance().getContentFactory().createContent(hierarchyBrowser, null, true); + contentManager.addContent(content); + contentManager.addContentManagerListener(new ContentManagerAdapter() { + public void contentRemoved(final ContentManagerEvent event){ + final Content content = event.getContent(); + final Component component = content.getComponent(); + if (component instanceof MethodHierarchyBrowser) { + ((MethodHierarchyBrowser)component).dispose(); + content.release(); + } + } + }); + } + contentManager.setSelectedContent(content); + hierarchyBrowser.setContent(content); + + final String name = method.getName(); + content.setDisplayName(name); + + final Runnable runnable = new Runnable() { + public void run(){ + final String typeName = MethodHierarchyTreeStructure.TYPE; + hierarchyBrowser.changeView(typeName); + } + }; + ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.HIERARCHY).activate(runnable); + } + + public final void update(final AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + presentation.setText("Browse Method Hierarchy"); + } + presentation.setEnabled(getMethod(event.getDataContext()) != null); + } + + private static PsiMethod getMethod(final DataContext dataContext){ + final PsiMethod method = getMethodImpl(dataContext); + if ( + method != null && + method.getContainingClass() != null && + !method.hasModifierProperty(PsiModifier.PRIVATE) && + !method.hasModifierProperty(PsiModifier.STATIC) + ){ + return method; + } + else { + return null; + } + } + + private static PsiMethod getMethodImpl(final DataContext dataContext){ + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); + + if (method != null) { + return method; + } + + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor == null) { + return null; + } + + final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile == null) { + return null; + } + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final int offset = editor.getCaretModel().getOffset(); + if (offset < 1) { + return null; + } + + element = psiFile.findElementAt(offset); + if (!(element instanceof PsiWhiteSpace)) { + return null; + } + + element = psiFile.findElementAt(offset - 1); + if (!(element instanceof PsiJavaToken) || ((PsiJavaToken)element).getTokenType() != JavaTokenType.SEMICOLON) { + return null; + } + + return PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseTypeHierarchyAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseTypeHierarchyAction.java new file mode 100644 index 00000000000..77f7bddf727 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/actions/BrowseTypeHierarchyAction.java @@ -0,0 +1,135 @@ +package com.intellij.ide.hierarchy.actions; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.ide.hierarchy.HierarchyBrowserManager; +import com.intellij.ide.hierarchy.type.SubtypesHierarchyTreeStructure; +import com.intellij.ide.hierarchy.type.TypeHierarchyBrowser; +import com.intellij.ide.hierarchy.type.TypeHierarchyTreeStructure; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspFile; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; + +import java.awt.*; + +public final class BrowseTypeHierarchyAction extends AnAction { + public final void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + + PsiDocumentManager.getInstance(project).commitAllDocuments(); // prevents problems with smart pointers creation + + final PsiClass psiClass = getPsiClass(dataContext); + if (psiClass == null) return; + final TypeHierarchyBrowser hierarchyBrowser = new TypeHierarchyBrowser(project, psiClass); + + final Content content; + + final HierarchyBrowserManager hierarchyBrowserManager = project.getComponent(HierarchyBrowserManager.class); + + final ContentManager contentManager = hierarchyBrowserManager.getContentManager(); + final Content selectedContent = contentManager.getSelectedContent(); + if (selectedContent != null && !selectedContent.isPinned()) { + content = selectedContent; + final Component component = content.getComponent(); + if (component instanceof TypeHierarchyBrowser) { + ((TypeHierarchyBrowser)component).dispose(); + } + content.setComponent(hierarchyBrowser); + } + else { + content = PeerFactory.getInstance().getContentFactory().createContent(hierarchyBrowser, null, true); + contentManager.addContent(content); + contentManager.addContentManagerListener(new ContentManagerAdapter() { + public void contentRemoved(final ContentManagerEvent event) { + final Content content = event.getContent(); + final Component component = content.getComponent(); + if (component instanceof TypeHierarchyBrowser) { + ((TypeHierarchyBrowser)component).dispose(); + content.release(); + } + } + }); + } + contentManager.setSelectedContent(content); + hierarchyBrowser.setContent(content); + + final String name = psiClass.getName(); + content.setDisplayName(name); + + final Runnable runnable = new Runnable() { + public void run() { + final String typeName = psiClass.isInterface() ? SubtypesHierarchyTreeStructure.TYPE : TypeHierarchyTreeStructure.TYPE; + hierarchyBrowser.changeView(typeName); + }}; + ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.HIERARCHY).activate(runnable); +// new Alarm().addRequest(runnable, 300); + } + + public final void update(final AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) { + presentation.setText("Browse Type Hierarchy"); + } + + final DataContext dataContext = event.getDataContext(); + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + final boolean enabled = file instanceof PsiJavaFile || file instanceof JspFile; + presentation.setVisible(enabled); + presentation.setEnabled(enabled); + } + else { + final boolean enabled = getPsiClass(dataContext) != null; + presentation.setEnabled(enabled); + presentation.setVisible(enabled); + } + } + + private static PsiClass getPsiClass(final DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null) return null; + + final int offset = editor.getCaretModel().getOffset(); + PsiElement element = file.findElementAt(offset); + while (element != null) { + if (element instanceof PsiFile) { + if (!(element instanceof PsiJavaFile)) return null; + if (element instanceof PsiAspectFile) { + final PsiAspect[] aspects = ((PsiAspectFile) element).getAspects(); + return aspects.length == 1 ? aspects[0] : null; + } + final PsiClass[] classes = ((PsiJavaFile)element).getClasses(); + return classes.length == 1 ? classes[0] : null; + } + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) { + return (PsiClass)element; + } + element = element.getParent(); + } + + return null; + } + else { + final PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + return element instanceof PsiClass ? (PsiClass)element : null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyBrowser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyBrowser.java new file mode 100644 index 00000000000..fdde5381e68 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyBrowser.java @@ -0,0 +1,573 @@ +package com.intellij.ide.hierarchy.call; + +import com.intellij.ide.actions.CloseTabToolbarAction; +import com.intellij.ide.actions.ToolbarHelpAction; +import com.intellij.ide.hierarchy.*; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.ui.content.Content; +import com.intellij.util.Alarm; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.util.*; + +public final class CallHierarchyBrowser extends JPanel implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.hierarchy.call.CallHierarchyBrowser"); + + static final String SCOPE_PROJECT = "Project"; + static final String SCOPE_ALL = "All"; + static final String SCOPE_CLASS = "This Class"; + + private final static String HELP_ID = "viewingStructure.callHierarchy"; + + private Content myContent; + private final Project myProject; + private final Hashtable myBuilders = new Hashtable(); + private final Hashtable myType2TreeMap = new Hashtable(); + private final Hashtable myType2ScopeMap = new Hashtable(); + + private final RefreshAction myRefreshAction = new RefreshAction(); + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + private SmartPsiElementPointer mySmartPsiElementPointer; + private final CardLayout myCardLayout; + private final JPanel myTreePanel; + private String myCurrentViewType; + + private final AutoScrollToSourceHandler myAutoScrollToSourceHandler; + + private static final String CALL_HIERARCHY_BROWSER_DATA_CONSTANT = "com.intellij.ide.hierarchy.call.CallHierarchyBrowser"; + + public CallHierarchyBrowser(final Project project, final PsiMethod method) { + myProject = project; + + myType2ScopeMap.put(CallerMethodsTreeStructure.TYPE, SCOPE_PROJECT); + myType2ScopeMap.put(CalleeMethodsTreeStructure.TYPE, SCOPE_PROJECT); + + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE; + } + + protected void setAutoScrollMode(final boolean state) { + HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE = state; + } + }; + + setHierarchyBase(method); + setLayout(new BorderLayout()); + + final ActionToolbar toolbar = createToolbar(); + add(toolbar.getComponent(), BorderLayout.NORTH); + + myCardLayout = new CardLayout(); + myTreePanel = new JPanel(myCardLayout); + + myType2TreeMap.put(CalleeMethodsTreeStructure.TYPE, createTree()); + myType2TreeMap.put(CallerMethodsTreeStructure.TYPE, createTree()); + + final Enumeration keys = myType2TreeMap.keys(); + while (keys.hasMoreElements()) { + final Object key = keys.nextElement(); + final JTree tree = myType2TreeMap.get(key); + myTreePanel.add(new JScrollPane(tree), key); + } + add(myTreePanel, BorderLayout.CENTER); + } + + private JTree createTree() { + final Tree tree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode(""))); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + tree.setToggleClickCount(-1); + tree.setCellRenderer(new HierarchyNodeRenderer()); + tree.putClientProperty("JTree.lineStyle", "Angled"); + + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_CALL_HIERARCHY_POPUP); + PopupHandler.installPopupHandler(tree, group, ActionPlaces.CALL_HIERARCHY_VIEW_POPUP, ActionManager.getInstance()); + EditSourceOnDoubleClickHandler.install(tree); + + final ShortcutSet shortcutSet = ActionManager.getInstance().getAction(IdeActions.ACTION_REFRESH).getShortcutSet(); + myRefreshAction.registerCustomShortcutSet(shortcutSet, tree); + + final BaseOnThisMethodAction baseOnThisMethodAction = new BaseOnThisMethodAction(); + baseOnThisMethodAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_CALL_HIERARCHY).getShortcutSet(), tree); + + new TreeSpeedSearch(tree); + TreeUtil.installActions(tree); + TreeToolTipHandler.install(tree); + myAutoScrollToSourceHandler.install(tree); + return tree; + } + + private void setHierarchyBase(final PsiMethod method) { + mySmartPsiElementPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(method); + } + + public final void setContent(final Content content) { + myContent = content; + } + + private void restoreCursor() { + /*int n =*/ myAlarm.cancelAllRequests(); +// if (n == 0) { + setCursor(Cursor.getDefaultCursor()); +// } + } + + private void setWaitCursor() { + myAlarm.addRequest( + new Runnable() { + public void run() { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + 100 + ); + } + + public final void changeView(final String typeName) { + myCurrentViewType = typeName; + + final PsiElement element = mySmartPsiElementPointer.getElement(); + if (!(element instanceof PsiMethod)) { + return; + } + final PsiMethod method = (PsiMethod)element; + + if (myContent != null) { + myContent.setDisplayName(typeName + method.getName()); + } + + myCardLayout.show(myTreePanel, typeName); + + if (!myBuilders.containsKey(typeName)) { + setWaitCursor(); + + // create builder + final JTree tree = myType2TreeMap.get(typeName); + final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode("")); + tree.setModel(model); + + final HierarchyTreeStructure structure; + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (CallerMethodsTreeStructure.TYPE.equals(typeName)) { + structure = new CallerMethodsTreeStructure(myProject, method, getCurrentScopeType()); + } + else if (CalleeMethodsTreeStructure.TYPE.equals(typeName)) { + structure = new CalleeMethodsTreeStructure(myProject, method, getCurrentScopeType()); + } + else { + LOG.error("unexpected type: " + typeName); + return; + } + final Comparator comparator = HierarchyBrowserManager.getInstance(myProject).getComparator(); + final HierarchyTreeBuilder builder = new HierarchyTreeBuilder(myProject, tree, model, structure, comparator); + + myBuilders.put(typeName, builder); + + final HierarchyNodeDescriptor baseDescriptor = structure.getBaseDescriptor(); + builder.buildNodeForElement(baseDescriptor); + final DefaultMutableTreeNode node = builder.getNodeForElement(baseDescriptor); + final TreePath path = new TreePath(node.getPath()); + tree.expandPath(path); + TreeUtil.selectPath(tree, path); + + restoreCursor(); + } + + getCurrentTree().requestFocus(); + } + + private ActionToolbar createToolbar() { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + + actionGroup.add(new ViewCallerMethodsHierarchyAction()); + actionGroup.add(new ViewCalleeMethodsHierarchyAction()); + actionGroup.add(new AlphaSortAction()); + actionGroup.add(new ChangeScopeAction()); + actionGroup.add(myRefreshAction); + actionGroup.add(myAutoScrollToSourceHandler.createToggleAction()); + actionGroup.add(new CloseAction()); + actionGroup.add(new ToolbarHelpAction(HELP_ID)); + + final ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.CALL_HIERARCHY_VIEW_TOOLBAR, + actionGroup, true); + return toolBar; + } + + private abstract class ChangeViewTypeActionBase extends ToggleAction { + public ChangeViewTypeActionBase(final String shortDescription, final String longDescription, final Icon icon) { + super(shortDescription, longDescription, icon); + } + + public final boolean isSelected(final AnActionEvent event) { + return getTypeName().equals(myCurrentViewType); + } + + protected abstract String getTypeName(); + + public final void setSelected(final AnActionEvent event, final boolean flag) { + if (flag) { +// setWaitCursor(); + // invokeLater is called to update state of button before long tree building operation + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(getTypeName()); + } + }); + } + } + + public final void update(final AnActionEvent event) { + super.update(event); + setEnabled(isValidBase()); + } + }; + + final class ViewCallerMethodsHierarchyAction extends ChangeViewTypeActionBase { + public ViewCallerMethodsHierarchyAction() { + super("Caller Methods Hierarchy", "Caller Methods Hierarchy", IconLoader.getIcon("/hierarchy/caller.png")); + } + + protected final String getTypeName() { + return CallerMethodsTreeStructure.TYPE; + } + }; + + final class ViewCalleeMethodsHierarchyAction extends ChangeViewTypeActionBase { + public ViewCalleeMethodsHierarchyAction() { + super("Callee Methods Hierarchy", "Callee Methods Hierarchy", IconLoader.getIcon("/hierarchy/callee.png")); + } + + protected final String getTypeName() { + return CalleeMethodsTreeStructure.TYPE; + } + }; + + final class RefreshAction extends AnAction { + public RefreshAction() { + super("Refresh", "Refresh", IconLoader.getIcon("/actions/sync.png")); + } + + public final void actionPerformed(final AnActionEvent e) { + if (!isValidBase()) return; + + final Object[] storedInfo = new Object[1]; + if (myCurrentViewType != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewType); + storedInfo[0] = builder.storeExpandedAndSelectedInfo(); + } + + final PsiMethod base = (PsiMethod)mySmartPsiElementPointer.getElement(); + final String[] name = new String[]{myCurrentViewType}; + dispose(); + setHierarchyBase(base); + validate(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(name[0]); + if (storedInfo != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewType); + builder.restoreExpandedAndSelectedInfo(storedInfo[0]); + } + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + private boolean isValidBase() { + final PsiElement element = mySmartPsiElementPointer.getElement(); + return element instanceof PsiMethod && element.isValid(); + } + + private JTree getCurrentTree() { + if (myCurrentViewType == null) return null; + return myType2TreeMap.get(myCurrentViewType); + } + + private String getCurrentScopeType() { + if (myCurrentViewType == null) return null; + return myType2ScopeMap.get(myCurrentViewType); + } + + public final class CloseAction extends CloseTabToolbarAction { + public final void actionPerformed(final AnActionEvent e) { + myContent.getManager().removeContent(myContent); + } + } + + private PsiElement getSelectedTargetElement() { + final DefaultMutableTreeNode node = getSelectedNode(); + if (node == null) return null; + final Object userObject = node.getUserObject(); + if (!(userObject instanceof CallHierarchyNodeDescriptor)) return null; + final PsiElement element = ((CallHierarchyNodeDescriptor)userObject).getTargetElement(); + return element; + } + + private PsiMethod getSelectedMethod() { + final PsiElement enclosingElement = getSelectedEnclosingElement(); + return enclosingElement instanceof PsiMethod ? (PsiMethod)enclosingElement : null; + } + + private PsiElement getSelectedEnclosingElement() { + final DefaultMutableTreeNode node = getSelectedNode(); + if (node == null) return null; + final Object userObject = node.getUserObject(); + if (!(userObject instanceof CallHierarchyNodeDescriptor)) return null; + final PsiElement enclosingElement = ((CallHierarchyNodeDescriptor)userObject).getEnclosingElement(); + return enclosingElement; + } + + private DefaultMutableTreeNode getSelectedNode() { + final JTree tree = getCurrentTree(); + if (tree == null) return null; + final TreePath path = tree.getSelectionPath(); + if (path == null) return null; + final Object lastPathComponent = path.getLastPathComponent(); + if (!(lastPathComponent instanceof DefaultMutableTreeNode)) return null; + return (DefaultMutableTreeNode)lastPathComponent; + } + + private PsiMethod[] getSelectedMethods() { + JTree tree = getCurrentTree(); + if (tree == null) return PsiMethod.EMPTY_ARRAY; + TreePath[] paths = tree.getSelectionPaths(); + ArrayList psiMethods = new ArrayList(); + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + Object node = path.getLastPathComponent(); + if (!(node instanceof DefaultMutableTreeNode)) continue; + Object userObject = ((DefaultMutableTreeNode)node).getUserObject(); + if (!(userObject instanceof CallHierarchyNodeDescriptor)) continue; + PsiElement enclosingElement = ((CallHierarchyNodeDescriptor)userObject).getEnclosingElement(); + if (!(enclosingElement instanceof PsiMethod)) continue; + psiMethods.add((PsiMethod)enclosingElement); + } + return psiMethods.toArray(new PsiMethod[psiMethods.size()]); + } + + public final Object getData(final String dataId) { + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + return getSelectedEnclosingElement(); + } + if (DataConstants.NAVIGATABLE.equals(dataId)) { + final PsiElement targetElement = getSelectedTargetElement(); + if (targetElement == null) { + return null; + } + return EditSourceUtil.getDescriptor(targetElement); + } + else if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return null; + } + else if (CALL_HIERARCHY_BROWSER_DATA_CONSTANT.equals(dataId)) { + return this; + } + else if (DataConstantsEx.HELP_ID.equals(dataId)) { + return HELP_ID; + } + else if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return getSelectedMethods(); + } + return null; + } + + public final void dispose() { + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.dispose(); + } + myBuilders.clear(); + } + + private final class AlphaSortAction extends ToggleAction { + public AlphaSortAction() { + super("Sort Alphabetically", "Sort Alphabetically", IconLoader.getIcon("/objectBrowser/sorted.png")); + } + + public final boolean isSelected(final AnActionEvent event) { + return HierarchyBrowserManager.getInstance(myProject).SORT_ALPHABETICALLY; + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + final HierarchyBrowserManager hierarchyBrowserManager = HierarchyBrowserManager.getInstance(myProject); + hierarchyBrowserManager.SORT_ALPHABETICALLY = flag; + final Comparator comparator = hierarchyBrowserManager.getComparator(); + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.setNodeDescriptorComparator(comparator); + } + } + + public final void update(final AnActionEvent event) { + super.update(event); + event.getPresentation().setEnabled(isValidBase()); + } + } + + public static final class BaseOnThisMethodAction extends AnAction { + public BaseOnThisMethodAction() { + super("Base on This Method"); + } + + public final void actionPerformed(final AnActionEvent event) { + final DataContext dataContext = event.getDataContext(); + final CallHierarchyBrowser browser = (CallHierarchyBrowser)dataContext.getData( + CALL_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) return; + + final PsiMethod method = browser.getSelectedMethod(); + if (method == null) return; + + final String[] name = new String[]{browser.myCurrentViewType}; + browser.dispose(); + browser.setHierarchyBase(method); + browser.validate(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + browser.changeView(name[0]); + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + + registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_CALL_HIERARCHY).getShortcutSet(), null); + + final DataContext dataContext = event.getDataContext(); + final CallHierarchyBrowser browser = (CallHierarchyBrowser)dataContext.getData(CALL_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final PsiMethod method = browser.getSelectedMethod(); + if (method == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + presentation.setVisible(true); + + if (!method.equals(browser.mySmartPsiElementPointer.getElement()) && + method.isValid() + ) { + presentation.setEnabled(true); + } + else { + presentation.setEnabled(false); + } + } + } + + private final class ChangeScopeAction extends ComboBoxAction { + public final void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) return; + + presentation.setText(getCurrentScopeType()); + } + + protected final DefaultActionGroup createPopupActionGroup(final JComponent button) { + final DefaultActionGroup group = new DefaultActionGroup(); + + group.add(new MenuAction(SCOPE_PROJECT)); + group.add(new MenuAction(SCOPE_ALL)); + group.add(new MenuAction(SCOPE_CLASS)); + + return group; + } + + public final JComponent createCustomComponent(final Presentation presentation) { + final JPanel panel = new JPanel(new GridBagLayout()); + panel.add(new JLabel("Scope:"), + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.BOTH, + new Insets(0, 5, 0, 0), 0, 0)); + panel.add(super.createCustomComponent(presentation), + new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + return panel; + } + + private final class MenuAction extends AnAction { + private final String myScopeType; + + public MenuAction(final String scopeType) { + super(scopeType); + myScopeType = scopeType; + } + + public final void actionPerformed(final AnActionEvent e) { + myType2ScopeMap.put(myCurrentViewType, myScopeType); + + // invokeLater is called to update state of button before long tree building operation + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (!isValidBase()) return; + LOG.assertTrue(myCurrentViewType != null); + + final Object[] storedInfo = new Object[1]; + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewType); + storedInfo[0] = builder.storeExpandedAndSelectedInfo(); + + final PsiMethod base = (PsiMethod)mySmartPsiElementPointer.getElement(); + final String[] name = new String[]{myCurrentViewType}; + + builder.dispose(); + myBuilders.remove(myCurrentViewType); + + setHierarchyBase(base); + validate(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(name[0]); + if (storedInfo != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewType); + builder.restoreExpandedAndSelectedInfo(storedInfo[0]); + } + } + }); + } + }); + + } + } + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java new file mode 100644 index 00000000000..2e0a61a77fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java @@ -0,0 +1,139 @@ +package com.intellij.ide.hierarchy.call; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.util.CompositeAppearance; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.LayeredIcon; + +import javax.swing.*; +import java.awt.*; + +public final class CallHierarchyNodeDescriptor extends HierarchyNodeDescriptor { + private int myUsageCount = 1; + private final static Class[] ourEnclosingElementClasses = new Class[]{PsiMethod.class, PsiClass.class, JspFile.class}; + + public CallHierarchyNodeDescriptor( + final Project project, + final HierarchyNodeDescriptor parentDescriptor, + final PsiElement element, + final boolean isBase + ){ + super(project, parentDescriptor, element, isBase); + } + + /** + * @return PsiMethod or PsiClass or JspFile + */ + public final PsiElement getEnclosingElement(){ + return getEnclosingElement(myElement); + } + + static PsiElement getEnclosingElement(final PsiElement element){ + return PsiTreeUtil.getParentOfType(element, ourEnclosingElementClasses, false); + } + + public final void incrementUsageCount(){ + myUsageCount++; + } + + /** + * Element for OpenFileDescriptor + */ + public final PsiElement getTargetElement(){ + return myElement; + } + + public final boolean isValid(){ + final PsiElement element = getEnclosingElement(); + return element != null && element.isValid(); + } + + public final boolean update(){ + final CompositeAppearance oldText = myHighlightedText; + final Icon oldOpenIcon = myOpenIcon; + + int flags = Iconable.ICON_FLAG_VISIBILITY; + if (isMarkReadOnly()) { + flags |= Iconable.ICON_FLAG_READ_STATUS; + } + + boolean changes = super.update(); + + final PsiElement enclosingElement = getEnclosingElement(); + + if (enclosingElement == null) { + final String invalidPrefix = "[Invalid] "; + if (!myHighlightedText.getText().startsWith(invalidPrefix)) { + myHighlightedText.getBeginning().addText(invalidPrefix, HierarchyNodeDescriptor.getInvalidPrefixAttributes()); + } + return true; + } + + myOpenIcon = enclosingElement.getIcon(flags); + if (changes && myIsBase) { + final LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(myOpenIcon, 0); + icon.setIcon(BASE_POINTER_ICON, 1, -BASE_POINTER_ICON.getIconWidth() / 2, 0); + myOpenIcon = icon; + } + myClosedIcon = myOpenIcon; + + myHighlightedText = new CompositeAppearance(); + TextAttributes mainTextAttributes = null; + if (myColor != null) { + mainTextAttributes = new TextAttributes(myColor, null, null, null, Font.PLAIN); + } + if (enclosingElement instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)enclosingElement; + final StringBuffer buffer = new StringBuffer(128); + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null) { + buffer.append(ClassPresentationUtil.getNameForClass(containingClass, false)); + buffer.append('.'); + } + final String methodText = PsiFormatUtil.formatMethod( + method, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + buffer.append(methodText); + + myHighlightedText.getEnding().addText(buffer.toString(), mainTextAttributes); + } + else if (enclosingElement instanceof JspFile) { + final JspFile file = (JspFile)enclosingElement; + myHighlightedText.getEnding().addText(file.getName(), mainTextAttributes); + } + else { + myHighlightedText.getEnding().addText(ClassPresentationUtil.getNameForClass((PsiClass)enclosingElement, false), mainTextAttributes); + } + if (myUsageCount > 1) { + myHighlightedText.getEnding().addText(" (" + myUsageCount + " usages)", HierarchyNodeDescriptor.getUsageCountPrefixAttributes()); + } + if (!(enclosingElement instanceof JspFile)) { + final String packageName = getPackageName(enclosingElement instanceof PsiMethod ? ((PsiMethod)enclosingElement).getContainingClass() : (PsiClass)enclosingElement); + myHighlightedText.getEnding().addText(" (" + packageName + ")", HierarchyNodeDescriptor.getPackageNameAttributes()); + } + myName = myHighlightedText.getText(); + + if ( + !Comparing.equal(myHighlightedText, oldText) || + !Comparing.equal(myOpenIcon, oldOpenIcon) + ){ + changes = true; + } + return changes; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CalleeMethodsTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CalleeMethodsTreeStructure.java new file mode 100644 index 00000000000..0c2772e5377 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CalleeMethodsTreeStructure.java @@ -0,0 +1,117 @@ +package com.intellij.ide.hierarchy.call; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; + +public final class CalleeMethodsTreeStructure extends HierarchyTreeStructure { + public static final String TYPE = "Callees Of "; + private final String myScopeType; + + /** + * Should be called in read action + */ + public CalleeMethodsTreeStructure(final Project project, final PsiMethod method, final String scopeType) { + super(project, new CallHierarchyNodeDescriptor(project, null, method, true)); + myScopeType = scopeType; + } + + protected final Object[] buildChildren(final HierarchyNodeDescriptor descriptor) { + final PsiElement enclosingElement = ((CallHierarchyNodeDescriptor)descriptor).getEnclosingElement(); + if (!(enclosingElement instanceof PsiMethod)) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + final PsiMethod method = (PsiMethod)enclosingElement; + + final ArrayList methods = new ArrayList(); + + final PsiCodeBlock body = method.getBody(); + if (body != null) { + visitor(body, methods); + } + + final PsiMethod baseMethod = (PsiMethod)((CallHierarchyNodeDescriptor)getBaseDescriptor()).getTargetElement(); + final PsiClass baseClass = baseMethod.getContainingClass(); + + final HashMap methodToDescriptorMap = new HashMap(); + + final ArrayList result = new ArrayList(); + + for (int i = 0; i < methods.size(); i++) { + final PsiMethod calledMethod = (PsiMethod)methods.get(i); + + if (CallHierarchyBrowser.SCOPE_CLASS.equals(myScopeType)) { + if (!PsiTreeUtil.isAncestor(baseClass, calledMethod, true)) { + continue; + } + } + else if (CallHierarchyBrowser.SCOPE_PROJECT.equals(myScopeType)) { + if (!calledMethod.getManager().isInProject(calledMethod)) { + continue; + } + } + + CallHierarchyNodeDescriptor d = (CallHierarchyNodeDescriptor)methodToDescriptorMap.get(calledMethod); + if (d == null) { + d = new CallHierarchyNodeDescriptor(myProject, descriptor, calledMethod, false); + methodToDescriptorMap.put(calledMethod, d); + result.add(d); + } + else { + d.incrementUsageCount(); + } + } + + // also add overriding methods as children + final PsiSearchHelper searchHelper = method.getManager().getSearchHelper(); + final PsiMethod[] overridingMethods = searchHelper.findOverridingMethods(method, GlobalSearchScope.projectScope(myProject), true); + for (int i = 0; i < overridingMethods.length; i++) { + final PsiMethod overridingMethod = overridingMethods[i]; + final CallHierarchyNodeDescriptor node = new CallHierarchyNodeDescriptor(myProject, descriptor, overridingMethod, false); + if (!result.contains(node)) result.add(node); + } + +/* + // show method implementations in EJB Class + final PsiMethod[] ejbImplementations = EjbUtil.findEjbImplementations(method, null); + for (int i = 0; i < ejbImplementations.length; i++) { + PsiMethod ejbImplementation = ejbImplementations[i]; + result.add(new CallHierarchyNodeDescriptor(myProject, descriptor, ejbImplementation, false)); + } +*/ + return result.toArray(new Object[result.size()]); + } + + + private void visitor(final PsiElement element, final ArrayList methods) { + final PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + final PsiElement child = children[i]; + visitor(child, methods); + if (child instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)child; + final PsiReferenceExpression methodExpression = callExpression.getMethodExpression(); + final PsiMethod method = (PsiMethod)methodExpression.resolve(); + if (method != null) { + methods.add(method); + } + } + else if (child instanceof PsiNewExpression) { + final PsiNewExpression newExpression = (PsiNewExpression)child; + final PsiMethod method = newExpression.resolveConstructor(); + if (method != null) { + methods.add(method); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java new file mode 100644 index 00000000000..054fe09765c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java @@ -0,0 +1,108 @@ +package com.intellij.ide.hierarchy.call; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ArrayUtil; + +import java.util.Collection; + +public final class CallerMethodsTreeStructure extends HierarchyTreeStructure { + public static final String TYPE = "Callers Of "; + private final String myScopeType; + + /** + * Should be called in read action + */ + public CallerMethodsTreeStructure(final Project project, final PsiMethod method, final String scopeType) { + super(project, new CallHierarchyNodeDescriptor(project, null, method, true)); + myScopeType = scopeType; + } + + protected final Object[] buildChildren(final HierarchyNodeDescriptor descriptor) { + final PsiElement enclosingElement = ((CallHierarchyNodeDescriptor)descriptor).getEnclosingElement(); + if (!(enclosingElement instanceof PsiMethod)) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + final PsiMethod method = (PsiMethod)enclosingElement; + + final PsiSearchHelper searchHelper = method.getManager().getSearchHelper(); + + SearchScope searchScope = GlobalSearchScope.projectScope(myProject); + if (CallHierarchyBrowser.SCOPE_CLASS.equals(myScopeType)) { + final PsiMethod baseMethod = (PsiMethod)((CallHierarchyNodeDescriptor)getBaseDescriptor()).getTargetElement(); + final PsiClass containingClass = baseMethod.getContainingClass(); + searchScope = new LocalSearchScope(containingClass); + } + else if (CallHierarchyBrowser.SCOPE_ALL.equals(myScopeType)) { + searchScope = GlobalSearchScope.allScope(myProject); + } + + PsiMethod methodToFind = method; + final PsiMethod deepestSuperMethod = PsiSuperMethodUtil.findDeepestSuperMethod(method); + if (deepestSuperMethod != null) { + methodToFind = deepestSuperMethod; + } + + final HashMap methodToDescriptorMap = new HashMap(); + + final PsiReference[] refs = searchHelper.findReferencesIncludingOverriding(methodToFind, searchScope, true); + for (int i = 0; i < refs.length; i++) { + final PsiReference reference = refs[i]; + + if (reference instanceof PsiReferenceExpression){ + final PsiExpression qualifier = ((PsiReferenceExpression)reference).getQualifierExpression(); + if (qualifier instanceof PsiSuperExpression) { // filter super.foo() call inside foo() and similar cases (bug 8411) + final PsiClass superClass = PsiUtil.resolveClassInType(qualifier.getType()); + final PsiClass methodClass = method.getContainingClass(); + if (methodClass != null && methodClass.isInheritor(superClass, true)) { + continue; + } + } + } + else { + if (!(reference instanceof PsiElement)){ + continue; + } + + final PsiElement parent = ((PsiElement)reference).getParent(); + if (parent instanceof PsiNewExpression){ + if (((PsiNewExpression)parent).getClassReference() != reference){ + continue; + } + } + else if (parent instanceof PsiAnonymousClass){ + if (((PsiAnonymousClass)parent).getBaseClassReference() != reference){ + continue; + } + } + else { + continue; + } + } + + final PsiElement element = reference.getElement(); + final PsiElement key = CallHierarchyNodeDescriptor.getEnclosingElement(element); + + CallHierarchyNodeDescriptor d = (CallHierarchyNodeDescriptor)methodToDescriptorMap.get(key); + if (d == null) { + d = new CallHierarchyNodeDescriptor(myProject, descriptor, element, false); + methodToDescriptorMap.put(key, d); + } + else { + d.incrementUsageCount(); + } + } + + final Collection descriptors = methodToDescriptorMap.values(); + return descriptors.toArray(new Object[descriptors.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/ImplementMethodAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/ImplementMethodAction.java new file mode 100644 index 00000000000..353f496dc49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/ImplementMethodAction.java @@ -0,0 +1,18 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.openapi.actionSystem.Presentation; + +public final class ImplementMethodAction extends OverrideImplementMethodAction { + protected final void update(final Presentation presentation, final int toImplement, final int toOverride) { + if (toImplement > 0) { + presentation.setEnabled(true); + presentation.setVisible(true); + presentation.setText(toImplement == 1 ? "Implement Method" : "Implement Methods"); + } + else { + presentation.setEnabled(false); + presentation.setVisible(false); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyBrowser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyBrowser.java new file mode 100644 index 00000000000..006deeaae09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyBrowser.java @@ -0,0 +1,510 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.ide.actions.CloseTabToolbarAction; +import com.intellij.ide.actions.ToolbarHelpAction; +import com.intellij.ide.hierarchy.*; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.ui.content.Content; +import com.intellij.util.Alarm; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.util.*; + +public final class MethodHierarchyBrowser extends JPanel implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.hierarchy.method.MethodHierarchyBrowser"); + + private final static String HELP_ID = "viewingStructure.methodHierarchy"; + + private Content myContent; + private final Project myProject; + private final Hashtable myBuilders = new Hashtable(); + private final Hashtable myTrees = new Hashtable(); + + private final RefreshAction myRefreshAction = new RefreshAction(); + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + private SmartPsiElementPointer mySmartPsiElementPointer; + private final CardLayout myCardLayout; + private final JPanel myTreePanel; + private String myCurrentViewName; + + private final AutoScrollToSourceHandler myAutoScrollToSourceHandler; + + static final String METHOD_HIERARCHY_BROWSER_DATA_CONSTANT = "com.intellij.ide.hierarchy.type.MethodHierarchyBrowser"; + + public MethodHierarchyBrowser(final Project project, final PsiMethod method) { + myProject = project; + + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE; + } + + protected void setAutoScrollMode(final boolean state) { + HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE = state; + } + }; + + setHierarchyBase(method); + setLayout(new BorderLayout()); + + final ActionToolbar toolbar = createToolbar(); + add(toolbar.getComponent(), BorderLayout.NORTH); + + myCardLayout = new CardLayout(); + myTreePanel = new JPanel(myCardLayout); + myTrees.put(MethodHierarchyTreeStructure.TYPE, createTree()); + final Enumeration keys = myTrees.keys(); + while (keys.hasMoreElements()) { + final Object key = keys.nextElement(); + final JTree tree = myTrees.get(key); + myTreePanel.add(new JScrollPane(tree), key); + } + add(myTreePanel, BorderLayout.CENTER); + + add(createLegendPanel(), BorderLayout.SOUTH); + } + + private JPanel createLegendPanel() { + final JPanel panel = new JPanel(new GridBagLayout()); + + JLabel label; + final GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(3, 5, 0, 5), 0, 0); + + label = + new JLabel("method is defined in the class", IconLoader.getIcon("/hierarchy/methodDefined.png"), + SwingConstants.LEFT); + label.setUI(new MultiLineLabelUI()); + label.setIconTextGap(10); + panel.add(label, gc); + + gc.gridy++; + label = + new JLabel("method is not defined in the class but defined in superclass", + IconLoader.getIcon("/hierarchy/methodNotDefined.png"), SwingConstants.LEFT); + label.setUI(new MultiLineLabelUI()); + label.setIconTextGap(10); + panel.add(label, gc); + + gc.gridy++; + label = + new JLabel("method should be defined since the class is not abstract", + IconLoader.getIcon("/hierarchy/shouldDefineMethod.png"), SwingConstants.LEFT); + label.setUI(new MultiLineLabelUI()); + label.setIconTextGap(10); + panel.add(label, gc); + + return panel; + } + + private JTree createTree() { + final Tree tree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode(""))); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + tree.setToggleClickCount(-1); + tree.setCellRenderer(new HierarchyNodeRenderer()); + tree.putClientProperty("JTree.lineStyle", "Angled"); + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_METHOD_HIERARCHY_POPUP); + PopupHandler.installPopupHandler(tree, group, ActionPlaces.METHOD_HIERARCHY_VIEW_POPUP, ActionManager.getInstance()); + EditSourceOnDoubleClickHandler.install(tree); + + final ShortcutSet shortcutSet = ActionManager.getInstance().getAction(IdeActions.ACTION_REFRESH).getShortcutSet(); + myRefreshAction.registerCustomShortcutSet(shortcutSet, tree); + + final BaseOnThisMethodAction baseOnThisMethodAction = new BaseOnThisMethodAction(); + baseOnThisMethodAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_METHOD_HIERARCHY).getShortcutSet(), tree); + + new TreeSpeedSearch(tree); + TreeUtil.installActions(tree); + TreeToolTipHandler.install(tree); + myAutoScrollToSourceHandler.install(tree); + return tree; + } + + private void setHierarchyBase(final PsiMethod method) { + mySmartPsiElementPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(method); + } + + public final void setContent(final Content content) { + myContent = content; + } + + private void restoreCursor() { + /*int n =*/ myAlarm.cancelAllRequests(); +// if (n == 0) { + setCursor(Cursor.getDefaultCursor()); +// } + } + + private void setWaitCursor() { + myAlarm.addRequest( + new Runnable() { + public void run() { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + 100 + ); + } + + public final void changeView(final String typeName) { + myCurrentViewName = typeName; + + final PsiElement element = mySmartPsiElementPointer.getElement(); + if (!(element instanceof PsiMethod)) { + return; + } + final PsiMethod method = (PsiMethod)element; + + if (myContent != null) { + myContent.setDisplayName(typeName + method.getName()); + } + + myCardLayout.show(myTreePanel, typeName); + + if (!myBuilders.containsKey(typeName)) { + setWaitCursor(); + + // create builder + final JTree tree = myTrees.get(typeName); + final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode("")); + tree.setModel(model); + + final HierarchyTreeStructure structure; + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (MethodHierarchyTreeStructure.TYPE.equals(typeName)) { + structure = new MethodHierarchyTreeStructure(myProject, method); + } + else { + LOG.error("unexpected type: " + typeName); + return; + } + final Comparator comparator = HierarchyBrowserManager.getInstance(myProject).getComparator(); + final HierarchyTreeBuilder builder = new HierarchyTreeBuilder(myProject, tree, model, structure, comparator); + + myBuilders.put(typeName, builder); + + final HierarchyNodeDescriptor baseDescriptor = structure.getBaseDescriptor(); + builder.buildNodeForElement(baseDescriptor); + final DefaultMutableTreeNode node = builder.getNodeForElement(baseDescriptor); + final TreePath path = new TreePath(node.getPath()); + tree.expandPath(path); + TreeUtil.selectPath(tree, path); + + restoreCursor(); + } + + getCurrentTree().requestFocus(); + } + + private ActionToolbar createToolbar() { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + + actionGroup.add(new AlphaSortAction()); + actionGroup.add(new ShowImplementationsOnlyAction()); + actionGroup.add(myRefreshAction); + actionGroup.add(myAutoScrollToSourceHandler.createToggleAction()); + actionGroup.add(new CloseAction()); + actionGroup.add(new ToolbarHelpAction(HELP_ID)); + + final ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.METHOD_HIERARCHY_VIEW_TOOLBAR, + actionGroup, true); + return toolBar; + } + + final class RefreshAction extends AnAction { + public RefreshAction() { + super("Refresh", "Refresh", IconLoader.getIcon("/actions/sync.png")); + } + + public final void actionPerformed(final AnActionEvent e) { + if (!isValidBase()) return; + + final Object[] storedInfo = new Object[1]; + if (myCurrentViewName != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + storedInfo[0] = builder.storeExpandedAndSelectedInfo(); + } + + final PsiMethod base = (PsiMethod)mySmartPsiElementPointer.getElement(); + final String[] name = new String[]{myCurrentViewName}; + dispose(); + setHierarchyBase(base); + validate(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(name[0]); + if (storedInfo != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + builder.restoreExpandedAndSelectedInfo(storedInfo[0]); + } + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + private boolean isValidBase() { + final PsiElement element = mySmartPsiElementPointer.getElement(); + return element instanceof PsiMethod && element.isValid(); + } + + final class ShowImplementationsOnlyAction extends ToggleAction { + public ShowImplementationsOnlyAction() { + super("Hide classes where the method is legally not implemented", null, IconLoader.getIcon("/ant/filter.png")); // TODO[anton] use own icon!!! + } + + public final boolean isSelected(final AnActionEvent event) { + return HierarchyBrowserManager.getInstance(myProject).HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED; + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + HierarchyBrowserManager.getInstance(myProject).HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED = flag; + + final Object[] storedInfo = new Object[1]; + if (myCurrentViewName != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + storedInfo[0] = builder.storeExpandedAndSelectedInfo(); + } + + final PsiMethod base = (PsiMethod)mySmartPsiElementPointer.getElement(); + final String[] name = new String[]{myCurrentViewName}; + dispose(); + setHierarchyBase(base); + validate(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(name[0]); + if (storedInfo != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + builder.restoreExpandedAndSelectedInfo(storedInfo[0]); + } + } + }); + } + + public final void update(final AnActionEvent event) { + super.update(event); + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + private JTree getCurrentTree() { + if (myCurrentViewName == null) return null; + final JTree tree = myTrees.get(myCurrentViewName); + return tree; + } + + public final class CloseAction extends CloseTabToolbarAction { + public final void actionPerformed(final AnActionEvent e) { + myContent.getManager().removeContent(myContent); + } + } + + private PsiElement getSelectedElement() { + final DefaultMutableTreeNode node = getSelectedNode(); + if (node == null) return null; + final Object userObject = node.getUserObject(); + if (!(userObject instanceof MethodHierarchyNodeDescriptor)) return null; + final PsiElement element = ((MethodHierarchyNodeDescriptor)userObject).getTargetElement(); + return element; + } + + private PsiMethod[] getSelectedMethods() { + MethodHierarchyNodeDescriptor[] descriptors = getSelectedDescriptors(); + ArrayList psiElements = new ArrayList(); + for (int i = 0; i < descriptors.length; i++) { + MethodHierarchyNodeDescriptor descriptor = descriptors[i]; + PsiElement element = descriptor.getTargetElement(); + if (!(element instanceof PsiMethod)) continue; + psiElements.add((PsiMethod)element); + } + return psiElements.toArray(new PsiMethod[psiElements.size()]); + } + + private DefaultMutableTreeNode getSelectedNode() { + final JTree tree = getCurrentTree(); + if (tree == null) return null; + final TreePath path = tree.getSelectionPath(); + if (path == null) return null; + final Object lastPathComponent = path.getLastPathComponent(); + if (!(lastPathComponent instanceof DefaultMutableTreeNode)) return null; + return (DefaultMutableTreeNode)lastPathComponent; + } + + public final Object getData(final String dataId) { + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + return getSelectedElement(); + } + else if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return null; + } + else if (METHOD_HIERARCHY_BROWSER_DATA_CONSTANT.equals(dataId)) { + return this; + } + else if (DataConstantsEx.HELP_ID.equals(dataId)) { + return HELP_ID; + } + else if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return getSelectedMethods(); + } + return null; + } + + public final void dispose() { + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.dispose(); + } + myBuilders.clear(); + } + + private final class AlphaSortAction extends ToggleAction { + public AlphaSortAction() { + super("Sort Alphabetically", "Sort Alphabetically", IconLoader.getIcon("/objectBrowser/sorted.png")); + } + + public final boolean isSelected(final AnActionEvent event) { + return HierarchyBrowserManager.getInstance(myProject).SORT_ALPHABETICALLY; + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + final HierarchyBrowserManager hierarchyBrowserManager = HierarchyBrowserManager.getInstance(myProject); + hierarchyBrowserManager.SORT_ALPHABETICALLY = flag; + final Comparator comparator = hierarchyBrowserManager.getComparator(); + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.setNodeDescriptorComparator(comparator); + } + } + + public final void update(final AnActionEvent event) { + super.update(event); + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + public static final class BaseOnThisMethodAction extends AnAction { + public BaseOnThisMethodAction() { + super("Base on This Method"); + } + + public final void actionPerformed(final AnActionEvent event) { + final DataContext dataContext = event.getDataContext(); + final MethodHierarchyBrowser browser = (MethodHierarchyBrowser)dataContext.getData( + METHOD_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) return; + + final PsiElement selectedElement = browser.getSelectedElement(); + if (!(selectedElement instanceof PsiMethod)) { + return; + } + final PsiMethod method = (PsiMethod)selectedElement; + + final String[] name = new String[]{browser.myCurrentViewName}; + browser.dispose(); + browser.setHierarchyBase(method); + browser.validate(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + browser.changeView(name[0]); + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + + registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_METHOD_HIERARCHY).getShortcutSet(), null); + + final DataContext dataContext = event.getDataContext(); + final MethodHierarchyBrowser browser = (MethodHierarchyBrowser)dataContext.getData( + METHOD_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + final PsiElement selectedElement = browser.getSelectedElement(); + if (!(selectedElement instanceof PsiMethod)) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + presentation.setVisible(true); + + final PsiMethod method = (PsiMethod)selectedElement; + if (!method.equals(browser.mySmartPsiElementPointer.getElement()) && + method.isValid() + ) { + presentation.setEnabled(true); + } + else { + presentation.setEnabled(false); + } + } + } + + public final MethodHierarchyNodeDescriptor[] getSelectedDescriptors() { + final JTree tree = getCurrentTree(); + if (tree == null) { + return new MethodHierarchyNodeDescriptor[0]; + } + final TreePath[] paths = tree.getSelectionPaths(); + if (paths == null) { + return new MethodHierarchyNodeDescriptor[0]; + } + final ArrayList list = new ArrayList(paths.length); + for (int i = 0; i < paths.length; i++) { + final TreePath path = paths[i]; + final Object lastPathComponent = path.getLastPathComponent(); + if (lastPathComponent instanceof DefaultMutableTreeNode) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)lastPathComponent; + final Object userObject = node.getUserObject(); + if (userObject instanceof MethodHierarchyNodeDescriptor) { + list.add((MethodHierarchyNodeDescriptor)userObject); + } + } + } + return list.toArray(new MethodHierarchyNodeDescriptor[list.size()]); + } + + public final PsiMethod getBaseMethod() { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + final MethodHierarchyTreeStructure treeStructure = (MethodHierarchyTreeStructure)builder.getTreeStructure(); + + final PsiMethod baseMethod = treeStructure.getBaseMethod(); + return baseMethod; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java new file mode 100644 index 00000000000..7ce3462d650 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java @@ -0,0 +1,165 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.util.CompositeAppearance; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.ui.LayeredIcon; +import com.intellij.ui.RowIcon; + +import javax.swing.*; +import java.awt.*; + +public final class MethodHierarchyNodeDescriptor extends HierarchyNodeDescriptor { + private static final Icon METHOD_DEFINED_ICON = IconLoader.getIcon("/hierarchy/methodDefined.png"); + private static final Icon METHOD_NOT_DEFINED_ICON = IconLoader.getIcon("/hierarchy/methodNotDefined.png"); + private static final Icon SHOULD_DEFINE_METHOD_ICON = IconLoader.getIcon("/hierarchy/shouldDefineMethod.png"); + + private Icon myRawIcon; + private Icon myStateIcon; + private MethodHierarchyTreeStructure myTreeStructure; + + public MethodHierarchyNodeDescriptor( + final Project project, + final HierarchyNodeDescriptor parentDescriptor, + final PsiClass aClass, + final boolean isBase, + final MethodHierarchyTreeStructure treeStructure + ){ + super(project, parentDescriptor, aClass, isBase); + myTreeStructure = treeStructure; + } + + public final void setTreeStructure(final MethodHierarchyTreeStructure treeStructure) { + myTreeStructure = treeStructure; + } + + private PsiMethod getMethod(final PsiClass aClass, final boolean checkBases) { + return MethodHierarchyUtil.findBaseMethodInClass(myTreeStructure.getBaseMethod(), aClass, checkBases); + } + + public final PsiClass getPsiClass() { + return (PsiClass)myElement; + } + + /** + * Element for OpenFileDescriptor + */ + public final PsiElement getTargetElement() { + final PsiClass aClass = getPsiClass(); + if (aClass == null) return null; + final PsiMethod method = getMethod(aClass, false); + if (method != null) return method; + return getPsiClass(); + } + + public final boolean isValid() { + final PsiClass aClass = getPsiClass(); + return aClass != null && aClass.isValid(); + } + + public final boolean update() { + int flags = Iconable.ICON_FLAG_VISIBILITY; + if (isMarkReadOnly()){ + flags |= Iconable.ICON_FLAG_READ_STATUS; + } + + boolean changes = super.update(); + + final PsiClass psiClass = getPsiClass(); + + if (psiClass == null){ + final String invalidPrefix = "[Invalid] "; + if (!myHighlightedText.getText().startsWith(invalidPrefix)) { + myHighlightedText.getBeginning().addText(invalidPrefix, HierarchyNodeDescriptor.getInvalidPrefixAttributes()); + } + return true; + } + + final Icon newRawIcon = psiClass.getIcon(flags); + final Icon newStateIcon = calculateState(psiClass); + + if (newRawIcon != myRawIcon || newStateIcon != myStateIcon) { + changes = true; + + myRawIcon = newRawIcon; + myStateIcon = newStateIcon; + + myOpenIcon = myRawIcon; + + if (myIsBase) { + final LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(myOpenIcon, 0); + icon.setIcon(BASE_POINTER_ICON, 1, -BASE_POINTER_ICON.getIconWidth() / 2, 0); + myOpenIcon = icon; + } + + if (myStateIcon != null) { + final RowIcon icon = new RowIcon(2); + icon.setIcon(myStateIcon, 0); + icon.setIcon(myOpenIcon, 1); + myOpenIcon = icon; + } + + myClosedIcon = myOpenIcon; + } + + final CompositeAppearance oldText = myHighlightedText; + + myHighlightedText = new CompositeAppearance(); + TextAttributes classNameAttributes = null; + if (myColor != null) { + classNameAttributes = new TextAttributes(myColor, null, null, null, Font.PLAIN); + } + myHighlightedText.getEnding().addText(ClassPresentationUtil.getNameForClass(psiClass, false), classNameAttributes); + myHighlightedText.getEnding().addText(" (" + getPackageName(psiClass) + ")", HierarchyNodeDescriptor.getPackageNameAttributes()); + myName = myHighlightedText.getText(); + + if (!Comparing.equal(myHighlightedText, oldText)) { + changes = true; + } + return changes; + } + + private Icon calculateState(final PsiClass psiClass) { + final PsiMethod method = getMethod(psiClass, false); + if (method != null) { + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + return null; + } + return METHOD_DEFINED_ICON; + } + + if (myTreeStructure.isSuperClassForBaseClass(psiClass)) { + return METHOD_NOT_DEFINED_ICON; + } + + final boolean isAbstractClass = psiClass.hasModifierProperty(PsiModifier.ABSTRACT); + + // was it implemented is in superclasses? + final PsiMethod baseClassMethod = getMethod(psiClass, true); + + final boolean hasBaseImplementation; + if (baseClassMethod == null) { + hasBaseImplementation = false; + } + else { + hasBaseImplementation = !baseClassMethod.hasModifierProperty(PsiModifier.ABSTRACT); + } + + if (hasBaseImplementation || isAbstractClass) { + return METHOD_NOT_DEFINED_ICON; + } + else { + return SHOULD_DEFINE_METHOD_ICON; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java new file mode 100644 index 00000000000..d151c7ac996 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java @@ -0,0 +1,241 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.ide.hierarchy.HierarchyBrowserManager; +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; + +import java.util.ArrayList; +import java.util.Arrays; + +public final class MethodHierarchyTreeStructure extends HierarchyTreeStructure { + public static final String TYPE = "Method hierarchy for "; + private final SmartPsiElementPointer myMethod; + + /** + * Should be called in read action + */ + public MethodHierarchyTreeStructure(final Project project, final PsiMethod method) { + super(project, null); + myBaseDescriptor = buildHierarchyElement(project, method); + ((MethodHierarchyNodeDescriptor)myBaseDescriptor).setTreeStructure(this); + myMethod = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(method); + setBaseElement(myBaseDescriptor); //to set myRoot + } + + private HierarchyNodeDescriptor buildHierarchyElement(final Project project, final PsiMethod method) { + final PsiClass suitableBaseClass = findSuitableBaseClass(method); + + HierarchyNodeDescriptor descriptor = null; + final ArrayList superClasses = createSuperClasses(suitableBaseClass); + + if (!suitableBaseClass.equals(method.getContainingClass())) { + superClasses.add(0, suitableBaseClass); + } + + // remove from the top of the branch the classes that contain no 'method' + for(int i = superClasses.size() - 1; i >= 0; i--){ + final PsiClass psiClass = (PsiClass)superClasses.get(i); + + if (MethodHierarchyUtil.findBaseMethodInClass(method, psiClass, false) == null) { + superClasses.remove(i); + } + else { + break; + } + } + + for(int i = superClasses.size() - 1; i >= 0; i--){ + final PsiClass superClass = (PsiClass)superClasses.get(i); + final HierarchyNodeDescriptor newDescriptor = new MethodHierarchyNodeDescriptor(project, descriptor, superClass, false, MethodHierarchyTreeStructure.this); + if (descriptor != null){ + descriptor.setCachedChildren(new HierarchyNodeDescriptor[] {newDescriptor}); + } + descriptor = newDescriptor; + } + final HierarchyNodeDescriptor newDescriptor = new MethodHierarchyNodeDescriptor(project, descriptor, method.getContainingClass(), true, MethodHierarchyTreeStructure.this); + if (descriptor != null) { + descriptor.setCachedChildren(new HierarchyNodeDescriptor[] {newDescriptor}); + } + return newDescriptor; + } + + private static ArrayList createSuperClasses(PsiClass aClass) { + if (!aClass.isValid()) { + return new ArrayList(); + } + + final ArrayList superClasses = new ArrayList(); + while (!isJavaLangObject(aClass)) { + final PsiClass aClass1 = aClass; + final PsiClass[] superTypes = aClass1.getSupers(); + PsiClass superType = null; + // find class first + for (int i = 0; i < superTypes.length; i++) { + final PsiClass type = superTypes[i]; + if (!type.isInterface() && !isJavaLangObject(type)) { + superType = type; + break; + } + } + // if we haven't found a class, try to find an interface + if (superType == null) { + for (int i = 0; i < superTypes.length; i++) { + final PsiClass type = superTypes[i]; + if (!isJavaLangObject(type)) { + superType = type; + break; + } + } + } + if (superType == null) break; + if (superClasses.contains(superType)) break; + superClasses.add(superType); + aClass = superType; + } + + return superClasses; + } + + private static boolean isJavaLangObject(final PsiClass aClass) { + return "java.lang.Object".equals(aClass.getQualifiedName()); + } + + private static PsiClass findSuitableBaseClass(final PsiMethod method) { + final PsiClass containingClass = method.getContainingClass(); + + if (containingClass instanceof PsiAnonymousClass) { + return containingClass; + } + + final PsiClass superClass = containingClass.getSuperClass(); + if (superClass == null) { + return containingClass; + } + + final boolean isContainingClassesMethod = MethodHierarchyUtil.findBaseMethodInClass(method, superClass, true) != null; + + if (!isContainingClassesMethod) { + final PsiClass[] interfaces = containingClass.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + final PsiClass anInterface = interfaces[i]; + if (MethodHierarchyUtil.findBaseMethodInClass(method, anInterface, true) != null) { + return anInterface; + } + } + } + + return containingClass; + } + + public final PsiMethod getBaseMethod() { + final PsiElement element = myMethod.getElement(); + return element instanceof PsiMethod ? (PsiMethod)element : null; + } + + + protected final Object[] buildChildren(final HierarchyNodeDescriptor descriptor) { + final PsiClass psiClass = ((MethodHierarchyNodeDescriptor)descriptor).getPsiClass(); + + final PsiClass[] subclasses = getSubclasses(psiClass); + + final ArrayList descriptors = new ArrayList(subclasses.length); + for (int i = 0; i < subclasses.length; i++) { + final PsiClass aClass = subclasses[i]; + if (HierarchyBrowserManager.getInstance(myProject).HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED) { + if (shouldHideClass(aClass)) { + continue; + } + } + + final MethodHierarchyNodeDescriptor d = new MethodHierarchyNodeDescriptor(myProject, descriptor, aClass, false, this); + descriptors.add(d); + } + return descriptors.toArray(new HierarchyNodeDescriptor[descriptors.size()]); + } + + private PsiClass[] getSubclasses(final PsiClass psiClass) { + if (psiClass instanceof PsiAnonymousClass) { + return PsiClass.EMPTY_ARRAY; + } + if (psiClass.hasModifierProperty(PsiModifier.FINAL)) { + return PsiClass.EMPTY_ARRAY; + } + + final PsiSearchHelper helper = PsiManager.getInstance(myProject).getSearchHelper(); + + final ArrayList classes = new ArrayList(Arrays.asList(helper.findInheritors(psiClass, GlobalSearchScope.allScope(myProject), false))); + + final EjbClassRole role = J2EERolesUtil.getEjbRole(psiClass); + if (role != null && role.isDeclarationRole()) { + final PsiClass[] implementations = role.findImplementations(); + classes.addAll(Arrays.asList(implementations)); + } + + return (PsiClass[])classes.toArray(new PsiClass[classes.size()]); + } + + private boolean shouldHideClass(final PsiClass psiClass) { + final PsiMethod method = getMethod(psiClass, false); + if (method != null) { + return false; + } + + if (isSuperClassForBaseClass(psiClass)) { + return false; + } + + final boolean isAbstract = psiClass.hasModifierProperty(PsiModifier.ABSTRACT); + + // was it implemented is in superclasses? + final PsiMethod baseClassMethod = getMethod(psiClass, true); + + final boolean hasBaseImplementation; + if (baseClassMethod == null) { + hasBaseImplementation = false; + } + else { + hasBaseImplementation = !baseClassMethod.hasModifierProperty(PsiModifier.ABSTRACT); + } + + if (hasBaseImplementation || isAbstract) { + // check inherited classes + + final PsiClass[] subclasses = getSubclasses(psiClass); + for (int i = 0; i < subclasses.length; i++) { + final PsiClass subclass = subclasses[i]; + if (!shouldHideClass(subclass)) { + return false; + } + } + return true; + } + else { + // should define method + return false; + } + } + + private PsiMethod getMethod(final PsiClass aClass, final boolean checkBases) { + return MethodHierarchyUtil.findBaseMethodInClass(getBaseMethod(), aClass, checkBases); + } + + boolean isSuperClassForBaseClass(final PsiClass aClass) { + final PsiMethod baseMethod = getBaseMethod(); + if (baseMethod == null) { + return false; + } + final PsiClass baseClass = baseMethod.getContainingClass(); + if (baseClass == null) { + return false; + } + // NB: parameters here are at CORRECT places!!! + final boolean isInheritor = baseClass.isInheritor(aClass, true); + return isInheritor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyUtil.java new file mode 100644 index 00000000000..661e5e1e9e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/MethodHierarchyUtil.java @@ -0,0 +1,65 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.containers.HashMap; + +import java.util.Map; + +final class MethodHierarchyUtil { + public static PsiMethod findBaseMethodInClass(final PsiMethod derivedMethod, final PsiClass aClass, final boolean checkBases) { + if (derivedMethod == null) return null; // base method is invalid + + final EjbClassRole role = J2EERolesUtil.getEjbRole(aClass); + + if (role == null || role.isDeclarationRole()) { + final Map substitutors = new HashMap(); + final PsiClass derivedClass = derivedMethod.getContainingClass(); + final PsiMethod[] methods = aClass.findMethodsByName(derivedMethod.getName(), checkBases); + for (int i = 0; i < methods.length; i++) { + final PsiMethod baseMethod = methods[i]; + if (baseMethod.getParameterList().getParameters().length == derivedMethod.getParameterList().getParameters().length) { + PsiSubstitutor substitutor = substitutors.get(baseMethod.getContainingClass()); + if (substitutor == null) { + substitutor = TypeConversionUtil.getClassSubstitutor(baseMethod.getContainingClass(), derivedMethod.getContainingClass(), PsiSubstitutor.EMPTY); + substitutors.put(baseMethod.getContainingClass(), substitutor); + } + if (substitutor == null) substitutor = PsiSubstitutor.EMPTY; + if (MethodSignatureUtil.findMethodBySignature(derivedClass, baseMethod.getSignature(substitutor), false) == derivedMethod) return baseMethod; + } + } + + return null; + } + else { + final PsiMethod[] methods = aClass.getMethods(); + for (int j = 0; j < methods.length; j++) { + final PsiMethod ejbMethod = methods[j]; + final EjbMethodRole methodRole = J2EERolesUtil.getEjbRole(ejbMethod); + if (methodRole == null) continue; + + final PsiMethod[] declarations = EjbUtil.findEjbDeclarations(ejbMethod); + for (int k = 0; k < declarations.length; k++) { + final PsiMethod declaration = declarations[k]; + if (declaration.equals(derivedMethod)) return ejbMethod; + + final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(declaration); + for (int i = 0; i < superMethods.length; i++) { + final PsiMethod superMethod = superMethods[i]; + if (declaration.equals(superMethod)) return ejbMethod; + } + } + } + } + + return aClass.findMethodBySignature(derivedMethod, checkBases); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java new file mode 100644 index 00000000000..bbaaa8c929f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java @@ -0,0 +1,120 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.codeInsight.generation.OverrideImplementUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.IncorrectOperationException; + +abstract class OverrideImplementMethodAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.hierarchy.method.OverrideImplementMethodAction"); + + public final void actionPerformed(final AnActionEvent event) { + final DataContext dataContext = event.getDataContext(); + final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)dataContext.getData(MethodHierarchyBrowser.METHOD_HIERARCHY_BROWSER_DATA_CONSTANT); + if (methodHierarchyBrowser == null) return; + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + + final String commandName = event.getPresentation().getText(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + + try{ + final MethodHierarchyNodeDescriptor[] selectedDescriptors = methodHierarchyBrowser.getSelectedDescriptors(); + for (int i = 0; i < selectedDescriptors.length; i++) { + OverrideImplementUtil.overrideOrImplement(selectedDescriptors[i].getPsiClass(), methodHierarchyBrowser.getBaseMethod()); + } + + ToolWindowManager.getInstance(project).activateEditorComponent(); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + }, commandName, null); + } + }); + } + + public final void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final DataContext dataContext = e.getDataContext(); + + final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)dataContext.getData(MethodHierarchyBrowser.METHOD_HIERARCHY_BROWSER_DATA_CONSTANT); + if (methodHierarchyBrowser == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + final MethodHierarchyNodeDescriptor[] selectedDescriptors = methodHierarchyBrowser.getSelectedDescriptors(); + int toImplement = 0; + int toOverride = 0; + + for (int i = 0; i < selectedDescriptors.length; i++) { + final MethodHierarchyNodeDescriptor descriptor = selectedDescriptors[i]; + if (canImplementOverride(descriptor, methodHierarchyBrowser, true)) { + if (toOverride > 0) { + // no mixed actions allowed + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + toImplement++; + } + else if (canImplementOverride(descriptor, methodHierarchyBrowser, false)) { + if (toImplement > 0) { + // no mixed actions allowed + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + toOverride++; + } + else { + // no action is applicable to this node + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + } + + presentation.setVisible(true); + + update(presentation, toImplement, toOverride); + } + + protected abstract void update(Presentation presentation, int toImplement, int toOverride); + + private static boolean canImplementOverride(final MethodHierarchyNodeDescriptor descriptor, final MethodHierarchyBrowser methodHierarchyBrowser, final boolean toImplement) { + final PsiClass psiClass = descriptor.getPsiClass(); + if (psiClass == null) return false; + final PsiMethod baseMethod = methodHierarchyBrowser.getBaseMethod(); + final MethodSignature signature = MethodSignatureUtil.createMethodSignature(baseMethod.getName(), baseMethod.getParameterList(), baseMethod.getTypeParameterList(), PsiSubstitutor.EMPTY); + + final MethodSignature[] allOriginalSignatures = toImplement ? OverrideImplementUtil.getMethodSignaturesToImplement(psiClass) : OverrideImplementUtil.getMethodSignaturesToOverride(psiClass); + for (int i = 0; i < allOriginalSignatures.length; i++) { + final MethodSignature originalSignature = allOriginalSignatures[i]; + if (originalSignature.equals(signature)) { + return true; + } + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideMethodAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideMethodAction.java new file mode 100644 index 00000000000..f4a2d8cdb12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/method/OverrideMethodAction.java @@ -0,0 +1,18 @@ +package com.intellij.ide.hierarchy.method; + +import com.intellij.openapi.actionSystem.Presentation; + +public final class OverrideMethodAction extends OverrideImplementMethodAction { + protected final void update(final Presentation presentation, final int toImplement, final int toOverride) { + if (toOverride > 0) { + presentation.setEnabled(true); + presentation.setVisible(true); + presentation.setText(toOverride == 1 ? "Override Method" : "Override Methods"); + } + else { + presentation.setEnabled(false); + presentation.setVisible(false); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SubtypesHierarchyTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SubtypesHierarchyTreeStructure.java new file mode 100644 index 00000000000..e738908dedd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SubtypesHierarchyTreeStructure.java @@ -0,0 +1,40 @@ +package com.intellij.ide.hierarchy.type; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.util.ArrayUtil; + +public class SubtypesHierarchyTreeStructure extends HierarchyTreeStructure { + public static final String TYPE = "Subtypes of "; + + protected SubtypesHierarchyTreeStructure(final Project project, final HierarchyNodeDescriptor descriptor) { + super(project, descriptor); + } + + public SubtypesHierarchyTreeStructure(final Project project, final PsiClass psiClass) { + super(project, new TypeHierarchyNodeDescriptor(project, null, psiClass, true)); + } + + protected final Object[] buildChildren(final HierarchyNodeDescriptor descriptor) { + final PsiClass psiClass = ((TypeHierarchyNodeDescriptor)descriptor).getPsiClass(); + if ("java.lang.Object".equals(psiClass.getQualifiedName())) { + return new Object[]{"All classes are derived from java.lang.Object"}; + } + if (psiClass instanceof PsiAnonymousClass) return ArrayUtil.EMPTY_OBJECT_ARRAY; + if (psiClass.hasModifierProperty(PsiModifier.FINAL)) return ArrayUtil.EMPTY_OBJECT_ARRAY; + final PsiSearchHelper helper = PsiManager.getInstance(myProject).getSearchHelper(); + final PsiClass[] classes = helper.findInheritors(psiClass, GlobalSearchScope.allScope(myProject), false); + final HierarchyNodeDescriptor[] descriptors = new HierarchyNodeDescriptor[classes.length]; + for (int i = 0; i < classes.length; i++) { + descriptors[i] = new TypeHierarchyNodeDescriptor(myProject, descriptor, classes[i], false); + } + return descriptors; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SupertypesHierarchyTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SupertypesHierarchyTreeStructure.java new file mode 100644 index 00000000000..9a83f6d4be8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/SupertypesHierarchyTreeStructure.java @@ -0,0 +1,29 @@ +package com.intellij.ide.hierarchy.type; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; + +public final class SupertypesHierarchyTreeStructure extends HierarchyTreeStructure { + public static final String TYPE = "Supertypes of "; + + public SupertypesHierarchyTreeStructure(final Project project, final PsiClass aClass) { + super(project, new TypeHierarchyNodeDescriptor(project, null, aClass, true)); + } + + protected final Object[] buildChildren(final HierarchyNodeDescriptor descriptor) { + final PsiClass psiClass = ((TypeHierarchyNodeDescriptor)descriptor).getPsiClass(); + final PsiClass[] supers = psiClass.getSupers(); + final int supersLength = psiClass.isInterface() ? supers.length - 1 : supers.length; + final HierarchyNodeDescriptor[] descriptors = new HierarchyNodeDescriptor[supersLength]; + PsiClass objectClass = PsiManager.getInstance(myProject).findClass("java.lang.Object", psiClass.getResolveScope()); + for (int i = 0, j = 0; i < supers.length; i++) { + if (!psiClass.isInterface() || !supers[i].equals(objectClass)) { + descriptors[j++] = new TypeHierarchyNodeDescriptor(myProject, descriptor, supers[i], false); + } + } + return descriptors; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyBrowser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyBrowser.java new file mode 100644 index 00000000000..971e74edf5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyBrowser.java @@ -0,0 +1,514 @@ +package com.intellij.ide.hierarchy.type; + +import com.intellij.ide.DeleteProvider; +import com.intellij.ide.actions.CloseTabToolbarAction; +import com.intellij.ide.actions.ToolbarHelpAction; +import com.intellij.ide.hierarchy.*; +import com.intellij.ide.util.DeleteHandler; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.ui.content.Content; +import com.intellij.util.Alarm; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.util.*; + +public final class TypeHierarchyBrowser extends JPanel implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.hierarchy.type.TypeHierarchyBrowser"); + + private final static String HELP_ID = "viewingStructure.classHierarchy"; + + private Content myContent; + private final Project myProject; + private final Hashtable myBuilders = new Hashtable(); + private final Hashtable myTrees = new Hashtable(); + + private final RefreshAction myRefreshAction = new RefreshAction(); + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + private SmartPsiElementPointer mySmartPsiElementPointer; + private boolean myIsInterface; + private final ActionToolbar myToolbar; + private final CardLayout myCardLayout; + private final JPanel myTreePanel; + private String myCurrentViewName; + + private final AutoScrollToSourceHandler myAutoScrollToSourceHandler; + private final MyDeleteProvider myDeleteElementProvider = new MyDeleteProvider(); + + private boolean myCachedIsValidBase = false; + + private static final String TYPE_HIERARCHY_BROWSER_DATA_CONSTANT = "com.intellij.ide.hierarchy.type.TypeHierarchyBrowser"; + + public TypeHierarchyBrowser(final Project project, final PsiClass psiClass) { + myProject = project; + + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE; + } + + protected void setAutoScrollMode(final boolean state) { + HierarchyBrowserManager.getInstance(myProject).IS_AUTOSCROLL_TO_SOURCE = state; + } + }; + + setHierarchyBase(psiClass); + setLayout(new BorderLayout()); + + myToolbar = createToolbar(); + add(myToolbar.getComponent(), BorderLayout.NORTH); + + myCardLayout = new CardLayout(); + myTreePanel = new JPanel(myCardLayout); + myTrees.put(TypeHierarchyTreeStructure.TYPE, createTree()); + myTrees.put(SupertypesHierarchyTreeStructure.TYPE, createTree()); + myTrees.put(SubtypesHierarchyTreeStructure.TYPE, createTree()); + final Enumeration keys = myTrees.keys(); + while (keys.hasMoreElements()) { + final Object key = keys.nextElement(); + final JTree tree = myTrees.get(key); + myTreePanel.add(new JScrollPane(tree), key); + } + add(myTreePanel, BorderLayout.CENTER); + } + + private JTree createTree() { + final Tree tree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode(""))); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + tree.setToggleClickCount(-1); + tree.setCellRenderer(new HierarchyNodeRenderer()); + tree.putClientProperty("JTree.lineStyle", "Angled"); + EditSourceOnDoubleClickHandler.install(tree); + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_TYPE_HIERARCHY_POPUP); + PopupHandler.installPopupHandler(tree, group, ActionPlaces.TYPE_HIERARCHY_VIEW_POPUP, ActionManager.getInstance()); + + myRefreshAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_REFRESH).getShortcutSet(), tree); + + final BaseOnThisTypeAction baseOnThisTypeAction = new BaseOnThisTypeAction(); + baseOnThisTypeAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_TYPE_HIERARCHY).getShortcutSet(), tree); + + new TreeSpeedSearch(tree); + TreeUtil.installActions(tree); + TreeToolTipHandler.install(tree); + myAutoScrollToSourceHandler.install(tree); + return tree; + } + + private void setHierarchyBase(final PsiClass psiClass) { + mySmartPsiElementPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(psiClass); + myIsInterface = psiClass.isInterface(); + } + + public final void setContent(final Content content) { + myContent = content; + } + + private void restoreCursor() { + /*int n =*/ myAlarm.cancelAllRequests(); +// if (n == 0) { + setCursor(Cursor.getDefaultCursor()); +// } + } + + private void setWaitCursor() { + myAlarm.addRequest( + new Runnable() { + public void run() { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + 100 + ); + } + + public final void changeView(final String typeName) { + myCurrentViewName = typeName; + + final PsiElement element = mySmartPsiElementPointer.getElement(); + if (!(element instanceof PsiClass)) { + return; + } + final PsiClass psiClass = (PsiClass)element; + + if (myContent != null) { + myContent.setDisplayName(typeName + ClassPresentationUtil.getNameForClass(psiClass, false)); + } + + myCardLayout.show(myTreePanel, typeName); + + if (!myBuilders.containsKey(typeName)) { + setWaitCursor(); + + // create builder + final JTree tree = myTrees.get(typeName); + final DefaultTreeModel model = /*(DefaultTreeModel)tree.getModel()*/ new DefaultTreeModel( + new DefaultMutableTreeNode("")); + tree.setModel(model); + + final HierarchyTreeStructure structure; + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (SupertypesHierarchyTreeStructure.TYPE.equals(typeName)) { + structure = new SupertypesHierarchyTreeStructure(myProject, psiClass); + } + else if (SubtypesHierarchyTreeStructure.TYPE.equals(typeName)) { + structure = new SubtypesHierarchyTreeStructure(myProject, psiClass); + } + else if (TypeHierarchyTreeStructure.TYPE.equals(typeName)) { + structure = new TypeHierarchyTreeStructure(myProject, psiClass); + } + else { + LOG.error("unexpected type: " + typeName); + return; + } + final Comparator comparator = HierarchyBrowserManager.getInstance(myProject).getComparator(); + final HierarchyTreeBuilder builder = new HierarchyTreeBuilder(myProject, tree, model, structure, comparator); + + myBuilders.put(typeName, builder); + + final HierarchyNodeDescriptor baseDescriptor = structure.getBaseDescriptor(); + builder.buildNodeForElement(baseDescriptor); + final DefaultMutableTreeNode node = builder.getNodeForElement(baseDescriptor); + final TreePath path = new TreePath(node.getPath()); + tree.expandPath(path); + TreeUtil.selectPath(tree, path); + + restoreCursor(); + } + + getCurrentTree().requestFocus(); + } + + private ActionToolbar createToolbar() { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + actionGroup.add(new ViewClassHierarchyAction()); + actionGroup.add(new ViewSupertypesHierarchyAction()); + actionGroup.add(new ViewSubtypesHierarchyAction()); + actionGroup.add(new AlphaSortAction()); + actionGroup.add(myRefreshAction); + actionGroup.add(myAutoScrollToSourceHandler.createToggleAction()); + actionGroup.add(new CloseAction()); + actionGroup.add(new ToolbarHelpAction(HELP_ID)); + + final ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TYPE_HIERARCHY_VIEW_TOOLBAR, + actionGroup, true); + return toolBar; + } + + private abstract class ChangeViewTypeActionBase extends ToggleAction { + public ChangeViewTypeActionBase(final String shortDescription, final String longDescription, final Icon icon) { + super(shortDescription, longDescription, icon); + } + + public final boolean isSelected(final AnActionEvent event) { + return getTypeName().equals(myCurrentViewName); + } + + protected abstract String getTypeName(); + + public final void setSelected(final AnActionEvent event, final boolean flag) { + if (flag) { +// setWaitCursor(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(getTypeName()); + } + }); + } + } + + public void update(final AnActionEvent event) { + super.update(event); + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + final class ViewSubtypesHierarchyAction extends ChangeViewTypeActionBase { + public ViewSubtypesHierarchyAction() { + super("Subtypes Hierarchy", "Subtypes Hierarchy", IconLoader.getIcon("/hierarchy/subtypes.png")); + } + + protected final String getTypeName() { + return SubtypesHierarchyTreeStructure.TYPE; + } + } + + final class ViewSupertypesHierarchyAction extends ChangeViewTypeActionBase { + public ViewSupertypesHierarchyAction() { + super("Supertypes Hierarchy", "Supertypes Hierarchy", IconLoader.getIcon("/hierarchy/supertypes.png")); + } + + protected final String getTypeName() { + return SupertypesHierarchyTreeStructure.TYPE; + } + } + + final class ViewClassHierarchyAction extends ChangeViewTypeActionBase { + public ViewClassHierarchyAction() { + super("Class Hierarchy", "Class Hierarchy", IconLoader.getIcon("/hierarchy/class.png")); + } + + protected final String getTypeName() { + return TypeHierarchyTreeStructure.TYPE; + } + + public final void update(final AnActionEvent event) { + super.update(event); + event.getPresentation().setVisible(!myIsInterface); + } + } + + final class RefreshAction extends AnAction { + public RefreshAction() { + super("Refresh", "Refresh", IconLoader.getIcon("/actions/sync.png")); + } + + public final void actionPerformed(final AnActionEvent e) { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + if (!isValidBase()) return; + + final Object[] storedInfo = new Object[1]; + if (myCurrentViewName != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + storedInfo[0] = builder.storeExpandedAndSelectedInfo(); + } + + final PsiClass base = (PsiClass)mySmartPsiElementPointer.getElement(); + final String[] name = new String[]{myCurrentViewName}; + dispose(); + setHierarchyBase(base); + validate(); + if (myIsInterface && TypeHierarchyTreeStructure.TYPE.equals(name)) { + name[0] = SubtypesHierarchyTreeStructure.TYPE; + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + changeView(name[0]); + if (storedInfo != null) { + final HierarchyTreeBuilder builder = myBuilders.get(myCurrentViewName); + builder.restoreExpandedAndSelectedInfo(storedInfo[0]); + } + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + private boolean isValidBase() { + if (PsiDocumentManager.getInstance(myProject).getUncommittedDocuments().length > 0) { + return myCachedIsValidBase; + } + + final PsiElement element = mySmartPsiElementPointer.getElement(); + myCachedIsValidBase = element instanceof PsiClass && element.isValid(); + return myCachedIsValidBase; + } + + private JTree getCurrentTree() { + if (myCurrentViewName == null) return null; + final JTree tree = myTrees.get(myCurrentViewName); + return tree; + } + + public final class CloseAction extends CloseTabToolbarAction { + public final void actionPerformed(final AnActionEvent e) { + myContent.getManager().removeContent(myContent); + } + } + + private PsiClass getSelectedClass() { + final TreePath path = getSelectedPath(); + return extractPsiClass(path); + } + + private PsiClass extractPsiClass(final TreePath path) { + if (path == null) return null; + final Object lastPathComponent = path.getLastPathComponent(); + if (!(lastPathComponent instanceof DefaultMutableTreeNode)) return null; + final Object userObject = ((DefaultMutableTreeNode)lastPathComponent).getUserObject(); + if (!(userObject instanceof TypeHierarchyNodeDescriptor)) return null; + final PsiClass aClass = ((TypeHierarchyNodeDescriptor)userObject).getPsiClass(); + return aClass; + } + + private TreePath getSelectedPath() { + final JTree tree = getCurrentTree(); + if (tree == null) return null; + return tree.getSelectionPath(); + } + + + private PsiClass[] getSelectedClasses() { + JTree currentTree = getCurrentTree(); + if (currentTree == null) return PsiClass.EMPTY_ARRAY; + TreePath[] paths = currentTree.getSelectionPaths(); + ArrayList psiClasses = new ArrayList(); + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + PsiClass psiClass = extractPsiClass(path); + if (psiClass == null) continue; + psiClasses.add(psiClass); + } + return psiClasses.toArray(new PsiClass[psiClasses.size()]); + } + + public final Object getData(final String dataId) { + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + return getSelectedClass(); + } else if (DataConstants.NAVIGATABLE.equals(dataId)) { + return getSelectedClass(); + } + else if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return myDeleteElementProvider; + } + else if (TYPE_HIERARCHY_BROWSER_DATA_CONSTANT.equals(dataId)) { + return this; + } + else if (DataConstantsEx.HELP_ID.equals(dataId)) { + return HELP_ID; + } + else if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return getSelectedClasses(); + } + return null; + } + + public final void dispose() { + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.dispose(); + } + myBuilders.clear(); + } + + private final class AlphaSortAction extends ToggleAction { + public AlphaSortAction() { + super("Sort Alphabetically", "Sort Alphabetically", IconLoader.getIcon("/objectBrowser/sorted.png")); + } + + public final boolean isSelected(final AnActionEvent event) { + return HierarchyBrowserManager.getInstance(myProject).SORT_ALPHABETICALLY; + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + final HierarchyBrowserManager hierarchyBrowserManager = HierarchyBrowserManager.getInstance(myProject); + hierarchyBrowserManager.SORT_ALPHABETICALLY = flag; + final Comparator comparator = hierarchyBrowserManager.getComparator(); + final Collection builders = myBuilders.values(); + for (Iterator iterator = builders.iterator(); iterator.hasNext();) { + final HierarchyTreeBuilder builder = iterator.next(); + builder.setNodeDescriptorComparator(comparator); + } + } + + public final void update(final AnActionEvent event) { + super.update(event); + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(isValidBase()); + } + } + + public static final class BaseOnThisTypeAction extends AnAction { + public final void actionPerformed(final AnActionEvent event) { + final DataContext dataContext = event.getDataContext(); + final TypeHierarchyBrowser browser = (TypeHierarchyBrowser)dataContext.getData( + TYPE_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) return; + + final PsiClass selectedClass = browser.getSelectedClass(); + if (selectedClass == null) return; + final String[] name = new String[]{browser.myCurrentViewName}; + browser.dispose(); + browser.setHierarchyBase(selectedClass); + browser.validate(); + if (browser.myIsInterface && TypeHierarchyTreeStructure.TYPE.equals(name)) { + name[0] = SubtypesHierarchyTreeStructure.TYPE; + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + browser.changeView(name[0]); + } + }); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_TYPE_HIERARCHY).getShortcutSet(), null); + + final DataContext dataContext = event.getDataContext(); + final TypeHierarchyBrowser browser = (TypeHierarchyBrowser)dataContext.getData(TYPE_HIERARCHY_BROWSER_DATA_CONSTANT); + if (browser == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + presentation.setVisible(true); + + final PsiClass selectedClass = browser.getSelectedClass(); + if (selectedClass != null && + !selectedClass.equals(browser.mySmartPsiElementPointer.getElement()) && + !"java.lang.Object".equals(selectedClass.getQualifiedName()) && + selectedClass.isValid() + ) { + presentation.setText("Base on This " + (selectedClass.isInterface() ? "Interface" : "Class")); + presentation.setEnabled(true); + } + else { + presentation.setEnabled(false); + } + } + } + + private final class MyDeleteProvider implements DeleteProvider { + public final void deleteElement(final DataContext dataContext) { + final PsiClass aClass = getSelectedClass(); + if (aClass == null || aClass instanceof PsiAnonymousClass) return; + final com.intellij.openapi.localVcs.LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, + "Deleting class " + + aClass.getQualifiedName()); + try { + final PsiElement[] elements = new PsiElement[]{aClass}; + DeleteHandler.deletePsiElement(elements, myProject); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + } + + public final boolean canDeleteElement(final DataContext dataContext) { + final PsiClass aClass = getSelectedClass(); + if (aClass == null || aClass instanceof PsiAnonymousClass) { + return false; + } + final PsiElement[] elements = new PsiElement[]{aClass}; + return DeleteHandler.shouldEnableDeleteAction(elements); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyNodeDescriptor.java new file mode 100644 index 00000000000..6e08f18243e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyNodeDescriptor.java @@ -0,0 +1,67 @@ +package com.intellij.ide.hierarchy.type; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.util.CompositeAppearance; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.PsiClass; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.ui.LayeredIcon; + +import java.awt.*; + +public final class TypeHierarchyNodeDescriptor extends HierarchyNodeDescriptor { + public TypeHierarchyNodeDescriptor(final Project project, final HierarchyNodeDescriptor parentDescriptor, final PsiClass psiClass, final boolean isBase) { + super(project, parentDescriptor, psiClass, isBase); + } + + public final PsiClass getPsiClass() { + return (PsiClass)myElement; + } + + public final boolean isValid() { + final PsiClass aClass = getPsiClass(); + return aClass != null && aClass.isValid(); + } + + public final boolean update() { + boolean changes = super.update(); + + if (myElement == null){ + final String invalidPrefix = "[Invalid] "; + if (!myHighlightedText.getText().startsWith(invalidPrefix)) { + myHighlightedText.getBeginning().addText(invalidPrefix, HierarchyNodeDescriptor.getInvalidPrefixAttributes()); + } + return true; + } + + if (changes && myIsBase) { + final LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(myOpenIcon, 0); + icon.setIcon(BASE_POINTER_ICON, 1, -BASE_POINTER_ICON.getIconWidth() / 2, 0); + myOpenIcon = icon; + myClosedIcon = myOpenIcon; + } + + final PsiClass psiClass = getPsiClass(); + + final CompositeAppearance oldText = myHighlightedText; + + myHighlightedText = new CompositeAppearance(); + + TextAttributes classNameAttributes = null; + if (myColor != null) { + classNameAttributes = new TextAttributes(myColor, null, null, null, Font.PLAIN); + } + myHighlightedText.getEnding().addText(ClassPresentationUtil.getNameForClass(psiClass, false), classNameAttributes); + myHighlightedText.getEnding().addText(" (" + getPackageName(psiClass) + ")", HierarchyNodeDescriptor.getPackageNameAttributes()); + myName = myHighlightedText.getText(); + + if (!Comparing.equal(myHighlightedText, oldText)) { + changes = true; + } + return changes; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyTreeStructure.java new file mode 100644 index 00000000000..bab3a3017ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/hierarchy/type/TypeHierarchyTreeStructure.java @@ -0,0 +1,59 @@ +package com.intellij.ide.hierarchy.type; + +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; + +import java.util.ArrayList; + +public final class TypeHierarchyTreeStructure extends SubtypesHierarchyTreeStructure { + public static final String TYPE = "Class hierarchy for "; + + public TypeHierarchyTreeStructure(final Project project, final PsiClass aClass) { + super(project, buildHierarchyElement(project, aClass)); + setBaseElement(myBaseDescriptor); //to set myRoot + } + + private static HierarchyNodeDescriptor buildHierarchyElement(final Project project, final PsiClass aClass) { + HierarchyNodeDescriptor descriptor = null; + final PsiClass[] superClasses = createSuperClasses(aClass); + for(int i = superClasses.length - 1; i >= 0; i--){ + final PsiClass superClass = superClasses[i]; + final HierarchyNodeDescriptor newDescriptor = new TypeHierarchyNodeDescriptor(project, descriptor, superClass, false); + if (descriptor != null){ + descriptor.setCachedChildren(new HierarchyNodeDescriptor[] {newDescriptor}); + } + descriptor = newDescriptor; + } + final HierarchyNodeDescriptor newDescriptor = new TypeHierarchyNodeDescriptor(project, descriptor, aClass, true); + if (descriptor != null) { + descriptor.setCachedChildren(new HierarchyNodeDescriptor[] {newDescriptor}); + } + return newDescriptor; + } + + private static PsiClass[] createSuperClasses(PsiClass aClass) { + if (!aClass.isValid()) return PsiClass.EMPTY_ARRAY; + if (aClass.isInterface()) return PsiClass.EMPTY_ARRAY; + + final ArrayList superClasses = new ArrayList(); + while (!"java.lang.Object".equals(aClass.getQualifiedName())) { + final PsiClass aClass1 = aClass; + final PsiClass[] superTypes = aClass1.getSupers(); + PsiClass superType = null; + for (int i = 0; i < superTypes.length; i++) { + final PsiClass type = superTypes[i]; + if (!type.isInterface()) { + superType = type; + break; + } + } + if (superType == null) break; + if (superClasses.contains(superType)) break; + superClasses.add(superType); + aClass = superType; + } + + return superClasses.toArray(new PsiClass[superClasses.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ArchiveFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ArchiveFileType.java new file mode 100644 index 00000000000..eb2ef7983cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ArchiveFileType.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.file.PsiBinaryFileImpl; + +import javax.swing.*; + +public class ArchiveFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/archive.png"); + + public String getName() { + return "ARCHIVE"; + } + + public String getDescription() { + return "Archive files"; + } + + public String getDefaultExtension() { + return null; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return true; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return null; + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiBinaryFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return null; + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/DTDFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/DTDFileType.java new file mode 100644 index 00000000000..59f1a35ba34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/DTDFileType.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.xml.XmlFileImpl; + +import javax.swing.*; + +public class DTDFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/xml.png"); + + public String getName() { + return "DTD"; + } + + public String getDescription() { + return "XML Document Type Definition"; + } + + public String getDefaultExtension() { + return "dtd"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + //TODO: should be antoher? + return new XmlFileHighlighter(true); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, text, startOffset, endOffset, StdFileTypes.DTD); + } + + private FileTypeSupportCapabilities mySupportCapabilities = new FileTypeSupportCapabilities() { + public boolean hasCompletion() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean hasValidation() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean hasFindUsages() { + return true; + } + + public boolean hasNavigation() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean hasRename() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + }; + + public FileTypeSupportCapabilities getSupportCapabilities() { + return mySupportCapabilities; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/GuiFormFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/GuiFormFileType.java new file mode 100644 index 00000000000..78590ce3283 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/GuiFormFileType.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; + +import javax.swing.*; + +public class GuiFormFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/uiForm.png"); + + public String getName() { + return "GUI_DESIGNER_FORM"; + } + + public String getDescription() { + return "GUI Designer form"; + } + + public String getDefaultExtension() { + return "form"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return "UTF-8"; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, this, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HighlighterFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HighlighterFactory.java new file mode 100644 index 00000000000..a83a236bc4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HighlighterFactory.java @@ -0,0 +1,69 @@ +package com.intellij.ide.highlighter; + +import com.intellij.ide.highlighter.custom.CustomFileHighlighter; +import com.intellij.ide.highlighter.custom.SyntaxTable; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.util.LexerHighlighter; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.PlainFileHighlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiManager; + +public class HighlighterFactory { + public static LexerHighlighter createJavaHighlighter(EditorColorsScheme settings, LanguageLevel languageLevel){ + return createHighlighter(new JavaFileHighlighter(languageLevel), settings); + } + + public static LexerHighlighter createHTMLHighlighter(EditorColorsScheme settings){ + FileHighlighter highlighter = new HtmlFileHighlighter(); + return createHighlighter(highlighter, settings); + } + + public static LexerHighlighter createHighlighter(FileHighlighter highlighter, EditorColorsScheme settings) { + return new LexerHighlighter(highlighter, settings); + } + + public static LexerHighlighter createXMLHighlighter(EditorColorsScheme settings){ + return createHighlighter(new XmlFileHighlighter(), settings); + } + + public static LexerHighlighter createJSPHighlighter(EditorColorsScheme settings, Project project){ + final LanguageLevel languageLevel = project != null ? PsiManager.getInstance(project).getEffectiveLanguageLevel() : LanguageLevel.HIGHEST; + return createHighlighter(new JspFileHighlighter(languageLevel), settings); + } + + public static LexerHighlighter createJSPHighlighter(EditorColorsScheme settings, LanguageLevel languageLevel){ + return createHighlighter(new JspFileHighlighter(languageLevel), settings); + } + + public static LexerHighlighter createCustomHighlighter(SyntaxTable syntaxTable, EditorColorsScheme settings){ + return createHighlighter(new CustomFileHighlighter(syntaxTable), settings); + } + + public static LexerHighlighter createHighlighter(Project project, String fileName) { + return createHighlighter(EditorColorsManager.getInstance().getGlobalScheme(), fileName, project); + } + + public static LexerHighlighter createHighlighter(Project project, VirtualFile file) { + return createHighlighter(project, file.getFileType()); + } + + public static LexerHighlighter createHighlighter(Project project, FileType fileType) { + return createHighlighter(fileType, EditorColorsManager.getInstance().getGlobalScheme(), project); + } + + public static LexerHighlighter createHighlighter(EditorColorsScheme settings, String fileName, Project project) { + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName); + return createHighlighter(fileType, settings, project); + } + + public static LexerHighlighter createHighlighter(FileType fileType, EditorColorsScheme settings, Project project) { + FileHighlighter highlighter = fileType.getHighlighter(project); + return createHighlighter(highlighter != null ? highlighter : new PlainFileHighlighter(), settings); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileHighlighter.java new file mode 100644 index 00000000000..3f489ac1cde --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileHighlighter.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.lexer.HtmlHighlightingLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighterBase; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; + +public class HtmlFileHighlighter extends FileHighlighterBase { + private static Map keys1; + private static Map keys2; + + static { + keys1 = new HashMap(); + keys2 = new HashMap(); + + keys1.put(XmlTokenType.XML_COMMENT_START, HighlighterColors.HTML_COMMENT); + keys1.put(XmlTokenType.XML_COMMENT_END, HighlighterColors.HTML_COMMENT); + keys1.put(XmlTokenType.XML_COMMENT_CHARACTERS, HighlighterColors.HTML_COMMENT); + + keys1.put(XmlTokenType.XML_START_TAG_START, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_END_TAG_START, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_TAG_END, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_EMPTY_ELEMENT_END, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_TAG_NAME, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.TAG_WHITE_SPACE, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_NAME, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, HighlighterColors.HTML_TAG); + keys1.put(XmlTokenType.XML_EQ, HighlighterColors.HTML_TAG); + + keys2.put(XmlTokenType.XML_TAG_NAME, HighlighterColors.HTML_TAG_NAME); + keys2.put(XmlTokenType.XML_NAME, HighlighterColors.HTML_ATTRIBUTE_NAME); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, HighlighterColors.HTML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, HighlighterColors.HTML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, HighlighterColors.HTML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_EQ, HighlighterColors.HTML_ATTRIBUTE_NAME); + + keys1.put(XmlTokenType.XML_BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); + } + + public Lexer getHighlightingLexer() { + return new HtmlHighlightingLexer(); + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(keys1.get(tokenType), keys2.get(tokenType)); + } + + public static final void registerEmbeddedTokenAttributes(Map _keys1, + Map _keys2) { + if (_keys1 != null) { + for (Iterator iterator = _keys1.keySet().iterator(); iterator.hasNext();) { + IElementType iElementType = iterator.next(); + keys1.put(iElementType,_keys1.get(iElementType)); + } + } + + if (_keys2 != null) { + for (Iterator iterator = _keys2.keySet().iterator(); iterator.hasNext();) { + IElementType iElementType = iterator.next(); + keys2.put(iElementType,_keys2.get(iElementType)); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileType.java new file mode 100644 index 00000000000..f70f7cfc98e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/HtmlFileType.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.impl.xml.XmlStructureViewTreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.html.HtmlFileImpl; + +import javax.swing.*; + +public class HtmlFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/html.png"); + + public String getName() { + return "HTML"; + } + + public String getDescription() { + return "HTML files"; + } + + public String getDefaultExtension() { + return "html"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return new HtmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new HtmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new HtmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, text, startOffset, endOffset, StdFileTypes.HTML); + } + + private static FileTypeSupportCapabilities capabilities = new FileTypeSupportCapabilities() { + public boolean hasCompletion() { + return true; + } + + public boolean hasValidation() { + return true; + } + + public boolean hasFindUsages() { + return true; + } + + public boolean hasNavigation() { + return true; + } + + public boolean hasRename() { + return true; + } + }; + + public FileTypeSupportCapabilities getSupportCapabilities() { + return capabilities; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return new XmlStructureViewTreeModel((XmlFile)PsiManager.getInstance(project).findFile(file)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaClassFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaClassFileType.java new file mode 100644 index 00000000000..fd88ebb7665 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaClassFileType.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.compiled.ClsFileImpl; + +import javax.swing.*; + +public class JavaClassFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/javaClass.png"); + + public String getName() { + return "CLASS"; + } + + public String getDescription() { + return "Java class files"; + } + + public String getDefaultExtension() { + return "class"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return true; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return new JavaFileHighlighter(LanguageLevel.HIGHEST); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (fileIndex.isInLibraryClasses(file)) { + // skip inners & anonymous + String name = file.getName(); + int dotIndex = name.lastIndexOf('.'); + if (dotIndex < 0) dotIndex = name.length(); + int index = name.lastIndexOf('$', dotIndex); + if (index >= 0) return null; + + return new ClsFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + return null; + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return null; + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileHighlighter.java new file mode 100644 index 00000000000..fb1a7c1d8ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileHighlighter.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.lexer.JavaHighlightingLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighterBase; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaElementType; +import com.intellij.psi.xml.XmlTokenType; + +import java.util.HashMap; +import java.util.Map; + +public class JavaFileHighlighter extends FileHighlighterBase { + private static Map ourMap1; + private static Map ourMap2; + + private LanguageLevel myLanguageLevel; + + public JavaFileHighlighter(LanguageLevel languageLevel) { + myLanguageLevel = languageLevel; + } + + static { + ourMap1 = new HashMap(); + ourMap2 = new HashMap(); + + fillMap(ourMap1, JavaTokenType.KEYWORD_BIT_SET, HighlighterColors.JAVA_KEYWORD); + fillMap(ourMap1, JavaTokenType.OPERATION_BIT_SET, HighlighterColors.JAVA_OPERATION_SIGN); + fillMap(ourMap1, JavaTokenType.OPERATION_BIT_SET, HighlighterColors.JAVA_OPERATION_SIGN); + + IElementType[] javadoc = IElementType.enumerate(new IElementType.Predicate() { + public boolean matches(IElementType type) { + return !(type instanceof IJavaElementType); + } + }); + + for (int i = 0; i < javadoc.length; i++) { + IElementType type = javadoc[i]; + ourMap1.put(type, HighlighterColors.JAVA_DOC_COMMENT); + } + + ourMap1.put(JavaTokenType.INTEGER_LITERAL, HighlighterColors.JAVA_NUMBER); + ourMap1.put(JavaTokenType.LONG_LITERAL, HighlighterColors.JAVA_NUMBER); + ourMap1.put(JavaTokenType.FLOAT_LITERAL, HighlighterColors.JAVA_NUMBER); + ourMap1.put(JavaTokenType.DOUBLE_LITERAL, HighlighterColors.JAVA_NUMBER); + ourMap1.put(JavaTokenType.STRING_LITERAL, HighlighterColors.JAVA_STRING); + ourMap1.put(StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN, HighlighterColors.JAVA_VALID_STRING_ESCAPE); + ourMap1.put(StringEscapesTokenTypes.INVALID_STRING_ESCAPE_TOKEN, HighlighterColors.JAVA_INVALID_STRING_ESCAPE); + ourMap1.put(JavaTokenType.CHARACTER_LITERAL, HighlighterColors.JAVA_STRING); + + ourMap1.put(JavaTokenType.LPARENTH, HighlighterColors.JAVA_PARENTHS); + ourMap1.put(JavaTokenType.RPARENTH, HighlighterColors.JAVA_PARENTHS); + + ourMap1.put(JavaTokenType.LBRACE, HighlighterColors.JAVA_BRACES); + ourMap1.put(JavaTokenType.RBRACE, HighlighterColors.JAVA_BRACES); + + ourMap1.put(JavaTokenType.LBRACKET, HighlighterColors.JAVA_BRACKETS); + ourMap1.put(JavaTokenType.RBRACKET, HighlighterColors.JAVA_BRACKETS); + + ourMap1.put(JavaTokenType.COMMA, HighlighterColors.JAVA_COMMA); + ourMap1.put(JavaTokenType.DOT, HighlighterColors.JAVA_DOT); + ourMap1.put(JavaTokenType.SEMICOLON, HighlighterColors.JAVA_SEMICOLON); + + //ourMap1[JavaTokenType.BOOLEAN_LITERAL] = HighlighterColors.JAVA_KEYWORD; + //ourMap1[JavaTokenType.NULL_LITERAL] = HighlighterColors.JAVA_KEYWORD; + ourMap1.put(JavaTokenType.C_STYLE_COMMENT, HighlighterColors.JAVA_BLOCK_COMMENT); + ourMap1.put(JavaTokenType.DOC_COMMENT, HighlighterColors.JAVA_DOC_COMMENT); + ourMap1.put(JavaTokenType.END_OF_LINE_COMMENT, HighlighterColors.JAVA_LINE_COMMENT); + ourMap1.put(JavaTokenType.BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); + + ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, HighlighterColors.JAVA_DOC_COMMENT); + ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, HighlighterColors.JAVA_DOC_TAG); + + IElementType[] javaDocMarkup = new IElementType[]{XmlTokenType.XML_START_TAG_START, + XmlTokenType.XML_END_TAG_START, + XmlTokenType.XML_TAG_END, + XmlTokenType.XML_EMPTY_ELEMENT_END, + XmlTokenType.TAG_WHITE_SPACE, + XmlTokenType.XML_TAG_NAME, + XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, + XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, + XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, + XmlTokenType.XML_EQ}; + + for (int i = 0; i < javaDocMarkup.length; i++) { + IElementType idx = javaDocMarkup[i]; + ourMap1.put(idx, HighlighterColors.JAVA_DOC_COMMENT); + ourMap2.put(idx, HighlighterColors.JAVA_DOC_MARKUP); + } + } + + public Lexer getHighlightingLexer() { + return new JavaHighlightingLexer(myLanguageLevel); + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(ourMap1.get(tokenType), ourMap2.get(tokenType)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileType.java new file mode 100644 index 00000000000..c1f827459f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/JavaFileType.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.impl.java.JavaFileTreeModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiJavaFileImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; +import com.intellij.psi.impl.source.codeStyle.java.JavaAdapter; + +import javax.swing.*; + +public class JavaFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/java.png"); + + public String getName() { + return "JAVA"; + } + + public String getDescription() { + return "Java source files"; + } + + public String getDefaultExtension() { + return "java"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + LanguageLevel level = project != null ? PsiManager.getInstance(project).getEffectiveLanguageLevel() : LanguageLevel.HIGHEST; + return new JavaFileHighlighter(level); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (fileIndex.isInSource(file)) { + return new PsiJavaFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiJavaFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return new JavaAdapter() { + protected FileType getFileType() { + return JavaFileType.this; + } + }; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (!(psiFile instanceof PsiJavaFile)) return null; + return new JavaFileTreeModel((PsiJavaFile)psiFile); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ModuleFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ModuleFileType.java new file mode 100644 index 00000000000..2ac9eb464b3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ModuleFileType.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; + +import javax.swing.*; + +public class ModuleFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/nodes/ideaModule.png"); + + public String getName() { + return "IDEA_MODULE"; + } + + public String getDescription() { + return "Idea Module"; + } + + public String getDefaultExtension() { + return "iml"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return true; + } + + public String getCharset(VirtualFile file) { + return "UTF-8"; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, this, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ProjectFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ProjectFileType.java new file mode 100644 index 00000000000..1fbdd6d0f1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/ProjectFileType.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; + +import javax.swing.*; + +public class ProjectFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/nodes/ideaProject.png"); + + public String getName() { + return "IDEA_PROJECT"; + } + + public String getDescription() { + return "Idea Project"; + } + + public String getDefaultExtension() { + return "ipr"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return true; + } + + public String getCharset(VirtualFile file) { + return "UTF-8"; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, this, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/UnknownFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/UnknownFileType.java new file mode 100644 index 00000000000..64fd896824d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/UnknownFileType.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; + +import javax.swing.*; + +public class UnknownFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/unknown.png"); + + public String getName() { + return "UNKNOWN"; + } + + public String getDescription() { + return "UNKNOWN"; + } + + public String getDefaultExtension() { + return null; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return true; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return null; + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return null; + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return null; + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/WorkspaceFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/WorkspaceFileType.java new file mode 100644 index 00000000000..223b578bcf1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/WorkspaceFileType.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; + +import javax.swing.*; + +public class WorkspaceFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/nodes/ideaWorkspace.png"); + + public String getName() { + return "IDEA_WORKSPACE"; + } + + public String getDescription() { + return "Idea Workspace"; + } + + public String getDefaultExtension() { + return "iws"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return true; + } + + public String getCharset(VirtualFile file) { + return "UTF-8"; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, this, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XHtmlFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XHtmlFileType.java new file mode 100644 index 00000000000..e937b79389d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XHtmlFileType.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.xml.XmlFileImpl; + +import javax.swing.*; + +public class XHtmlFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/xhtml.png"); + + public String getName() { + return "XHTML"; + } + + public String getDescription() { + return "XHTML files"; + } + + public String getDefaultExtension() { + return "xhtml"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(false,true); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, text, startOffset, endOffset, StdFileTypes.XHTML); + } + + private static FileTypeSupportCapabilities capabilities = new FileTypeSupportCapabilities() { + public boolean hasCompletion() { + return true; + } + + public boolean hasValidation() { + return true; + } + + public boolean hasFindUsages() { + return true; + } + + public boolean hasNavigation() { + return true; + } + + public boolean hasRename() { + return true; + } + }; + + public FileTypeSupportCapabilities getSupportCapabilities() { + return capabilities; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileHighlighter.java new file mode 100644 index 00000000000..adb91358ee2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileHighlighter.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.lexer.Lexer; +import com.intellij.lexer.XmlHighlightingLexer; +import com.intellij.lexer.DtdHighlightingLexer; +import com.intellij.lexer.XHtmlHighlightingLexer; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighterBase; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; + +public class XmlFileHighlighter extends FileHighlighterBase { + private static Map keys1; + private static Map keys2; + + static { + keys1 = new HashMap(); + keys2 = new HashMap(); + + keys1.put(XmlTokenType.XML_DATA_CHARACTERS, HighlighterColors.XML_TAG_DATA); + + keys1.put(XmlTokenType.XML_COMMENT_START, HighlighterColors.XML_COMMENT); + keys1.put(XmlTokenType.XML_COMMENT_END, HighlighterColors.XML_COMMENT); + keys1.put(XmlTokenType.XML_COMMENT_CHARACTERS, HighlighterColors.XML_COMMENT); + + keys1.put(XmlTokenType.XML_START_TAG_START, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_END_TAG_START, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_TAG_END, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_EMPTY_ELEMENT_END, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_TAG_NAME, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.TAG_WHITE_SPACE, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_NAME, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, HighlighterColors.XML_TAG); + keys1.put(XmlTokenType.XML_EQ, HighlighterColors.XML_TAG); + + keys2.put(XmlTokenType.XML_TAG_NAME, HighlighterColors.XML_TAG_NAME); + keys2.put(XmlTokenType.XML_NAME, HighlighterColors.XML_ATTRIBUTE_NAME); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, HighlighterColors.XML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, HighlighterColors.XML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, HighlighterColors.XML_ATTRIBUTE_VALUE); + keys2.put(XmlTokenType.XML_EQ, HighlighterColors.XML_ATTRIBUTE_NAME); + + keys1.put(XmlTokenType.XML_BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); + + keys1.put(XmlTokenType.XML_DECL_START, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_DECL_START, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_DECL_END, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_DECL_END, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_DOCTYPE_END, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_DOCTYPE_END, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_DOCTYPE_START, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_DOCTYPE_START, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_ATTLIST_DECL_START, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_ATTLIST_DECL_START, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_ELEMENT_DECL_START, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_ELEMENT_DECL_START, HighlighterColors.XML_TAG_NAME); + + keys1.put(XmlTokenType.XML_ENTITY_DECL_START, HighlighterColors.XML_PROLOGUE); + keys2.put(XmlTokenType.XML_ENTITY_DECL_START, HighlighterColors.XML_TAG_NAME); + } + + private boolean myIsDtd; + private boolean myIsXHtml; + + public XmlFileHighlighter() { + this(false); + } + + public XmlFileHighlighter(boolean dtd) { + myIsDtd = dtd; + } + + public XmlFileHighlighter(boolean dtd, boolean xhtml) { + myIsDtd = dtd; + myIsXHtml = xhtml; + } + + public Lexer getHighlightingLexer() { + if (myIsDtd) { + return new DtdHighlightingLexer(); + } else if (myIsXHtml) { + return new XHtmlHighlightingLexer(); + } else { + return new XmlHighlightingLexer(); + } + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(keys1.get(tokenType), keys2.get(tokenType)); + } + + public static final void registerEmbeddedTokenAttributes(Map _keys1, + Map _keys2) { + if (_keys1!=null) { + for (Iterator iterator = _keys1.keySet().iterator(); iterator.hasNext();) { + IElementType iElementType = iterator.next(); + keys1.put(iElementType,_keys1.get(iElementType)); + } + } + + if (_keys2!=null) { + for (Iterator iterator = _keys2.keySet().iterator(); iterator.hasNext();) { + IElementType iElementType = iterator.next(); + keys2.put(iElementType,_keys2.get(iElementType)); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileType.java new file mode 100644 index 00000000000..b0ecfed9cd2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/XmlFileType.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.codeFormatting.xml.XmlPseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.impl.xml.XmlStructureViewTreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade; +import com.intellij.psi.impl.source.codeStyle.java.JavaAdapter; +import com.intellij.psi.impl.source.xml.XmlFileImpl; + +import javax.swing.*; + +public class XmlFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/xml.png"); + + public String getName() { + return "XML"; + } + + public String getDescription() { + return "XML files"; + } + + public String getDefaultExtension() { + return "xml"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return new XmlFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new XmlFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, text, startOffset, endOffset, StdFileTypes.XML); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + if (CodeFormatterFacade.USE_NEW_CODE_FORMATTER <= 0) { + return new JavaAdapter() { + protected FileType getFileType() { + return XmlFileType.this; + } + }; + } + else { + return new XmlPseudoTextBuilder(); + } + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return new XmlStructureViewTreeModel((XmlFile)PsiManager.getInstance(project).findFile(file)); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java new file mode 100644 index 00000000000..a88022c17b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/AbstractCustomLexer.java @@ -0,0 +1,108 @@ +package com.intellij.ide.highlighter.custom; + +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.ide.highlighter.custom.tokens.TokenInfo; +import com.intellij.ide.highlighter.custom.tokens.TokenParser; +import com.intellij.lexer.Lexer; + +/** + * @author dsl + */ +public abstract class AbstractCustomLexer implements Lexer { + protected char[] myBuffer = new char[0]; + protected int myStartOffset = 0; + protected int myEndOffset = 0; + private static final short START_STATE = (short) 0; + private final TokenParser[] myTokenParsers; + private final int mySmartUpdateShift; + private TokenInfo myCurrentToken; + private int myPosition; + + public AbstractCustomLexer(TokenParser[] tokenParsers) { + myTokenParsers = tokenParsers; + + int smartUpdateShift = 0; + for (int i = 0; i < myTokenParsers.length; i++) { + TokenParser tokenParser = myTokenParsers[i]; + smartUpdateShift = Math.max(smartUpdateShift, tokenParser.getSmartUpdateShift()); + } + mySmartUpdateShift = smartUpdateShift; + } + + public void start(char[] buffer) { + start(buffer, 0, buffer.length, START_STATE); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + start(buffer, startOffset, endOffset, START_STATE); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myBuffer = buffer; + myStartOffset = startOffset; + myEndOffset = endOffset; + myPosition = myStartOffset; + myCurrentToken = new TokenInfo(); + for (int i = 0; i < myTokenParsers.length; i++) { + TokenParser tokenParser = myTokenParsers[i]; + tokenParser.setBuffer(myBuffer, myStartOffset, myEndOffset); + } + advance(); + } + + public int getState() { + return 0; + } + + public int getLastState() { + return 0; + } + + public IElementType getTokenType() { + return myCurrentToken.getType(); + } + + public int getTokenStart() { + return myCurrentToken.getStart(); + } + + public int getTokenEnd() { + return myCurrentToken.getEnd(); + } + + public void advance() { + if (myPosition >= myEndOffset) { + myCurrentToken.updateData(myPosition, myPosition, null); + return; + } + boolean tokenFound = false; + for (int i = 0; i < myTokenParsers.length; i++) { + TokenParser tokenParser = myTokenParsers[i]; + if (tokenParser.hasToken(myPosition)) { + tokenParser.getTokenInfo(myCurrentToken); + tokenFound = true; + break; + } + } + + if (!tokenFound) { + myCurrentToken.updateData(myPosition, myPosition + 1, CustomHighlighterTokenType.CHARACTER); + } + myPosition = myCurrentToken.getEnd(); + } + + public char[] getBuffer() { + return myBuffer; + } + + public int getBufferEnd() { + return myEndOffset; + } + + public int getSmartUpdateShift() { + return mySmartUpdateShift; + } + + public abstract Object clone(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileHighlighter.java new file mode 100644 index 00000000000..8a6dceb65d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileHighlighter.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.highlighter.custom; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighterBase; +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +import java.util.HashMap; +import java.util.Map; + +public class CustomFileHighlighter extends FileHighlighterBase { + private static Map ourKeys; + private SyntaxTable myTable; + + public CustomFileHighlighter(SyntaxTable table) { + myTable = table; + } + + static { + ourKeys = new HashMap(); + + ourKeys.put(CustomHighlighterTokenType.KEYWORD_1, CustomHighlighterColors.CUSTOM_KEYWORD1_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.KEYWORD_2, CustomHighlighterColors.CUSTOM_KEYWORD2_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.KEYWORD_3, CustomHighlighterColors.CUSTOM_KEYWORD3_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.KEYWORD_4, CustomHighlighterColors.CUSTOM_KEYWORD4_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.NUMBER, CustomHighlighterColors.CUSTOM_NUMBER_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.STRING, CustomHighlighterColors.CUSTOM_STRING_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterColors.CUSTOM_LINE_COMMENT_ATTRIBUTES); + ourKeys.put(CustomHighlighterTokenType.MULTI_LINE_COMMENT, + CustomHighlighterColors.CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES); + } + + public Lexer getHighlightingLexer() { + return new CustomFileTypeLexer(myTable); + } + + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(ourKeys.get(tokenType)); + } + + public static Map getKeys() { + return ourKeys; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileTypeLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileTypeLexer.java new file mode 100644 index 00000000000..b21e755b64c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomFileTypeLexer.java @@ -0,0 +1,81 @@ +package com.intellij.ide.highlighter.custom; + +import com.intellij.ide.highlighter.custom.tokens.*; +import com.intellij.ide.highlighter.custom.impl.CustomFileTypeEditor; +import com.intellij.psi.CustomHighlighterTokenType; + +import java.util.ArrayList; +import java.util.Set; + +/** + * @author dsl + */ +public final class CustomFileTypeLexer extends AbstractCustomLexer { + private final SyntaxTable myTable; + + public CustomFileTypeLexer(SyntaxTable table) { + super(buildTokenParsers(table)); + myTable = table; + } + + + public Object clone() { + CustomFileTypeLexer lexer = new CustomFileTypeLexer(myTable); + lexer.start(myBuffer, myStartOffset, myEndOffset); + return lexer; + } + + private static TokenParser[] buildTokenParsers(SyntaxTable table) { + final WhitespaceParser whitespaceParser = new WhitespaceParser(); + final LineCommentParser lineCommentParser = LineCommentParser.create(table.getLineComment()); + final MultilineCommentParser multilineCommentParser = + MultilineCommentParser.create(table.getStartComment(), table.getEndComment()); + final NumberParser numberParser = new NumberParser(table.getNumPostfixChars(), table.isIgnoreCase()); + final HexNumberParser hexNumberParser = HexNumberParser.create(table.getHexPrefix()); + final KeywordParser keywordParser = new KeywordParser( + new Set[]{table.getKeywords1(), table.getKeywords2(), table.getKeywords3(), table.getKeywords4()}, + table.isIgnoreCase()); + final IdentifierParser identifierParser = new IdentifierParser(); + + final QuotedStringParser quotedStringParser = new QuotedStringParser("\""); + + final QuotedStringParser quotedStringParser2 = new QuotedStringParser("\'"); + + ArrayList tokenParsers = new ArrayList(); + tokenParsers.add(whitespaceParser); + tokenParsers.add(quotedStringParser); + tokenParsers.add(quotedStringParser2); + if (lineCommentParser != null) { + tokenParsers.add(lineCommentParser); + } + if (multilineCommentParser != null) { + tokenParsers.add(multilineCommentParser); + } + tokenParsers.add(numberParser); + if (hexNumberParser != null) { + tokenParsers.add(hexNumberParser); + } + tokenParsers.add(keywordParser); + tokenParsers.add(identifierParser); + + if (table.isHasBraces()) { + tokenParsers.add(new BraceTokenParser("{", CustomHighlighterTokenType.L_BRACE)); + tokenParsers.add(new BraceTokenParser("}", CustomHighlighterTokenType.R_BRACE)); + } + + if (table.isHasParens()) { + tokenParsers.add(new BraceTokenParser("(", CustomHighlighterTokenType.L_PARENTH)); + tokenParsers.add(new BraceTokenParser(")", CustomHighlighterTokenType.R_PARENTH)); + } + + if (table.isHasBrackets()) { + tokenParsers.add(new BraceTokenParser("[", CustomHighlighterTokenType.L_BRACKET)); + tokenParsers.add(new BraceTokenParser("]", CustomHighlighterTokenType.R_BRACKET)); + } + + final TokenParser[] tokenParserArray = (TokenParser[]) tokenParsers.toArray(new TokenParser[tokenParsers.size()]); + return tokenParserArray; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomHighlighterColors.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomHighlighterColors.java new file mode 100644 index 00000000000..b636d88653a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/CustomHighlighterColors.java @@ -0,0 +1,14 @@ +package com.intellij.ide.highlighter.custom; + +import com.intellij.openapi.editor.colors.TextAttributesKey; + +public interface CustomHighlighterColors { + TextAttributesKey CUSTOM_KEYWORD1_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_KEYWORD1_ATTRIBUTES"); + TextAttributesKey CUSTOM_KEYWORD2_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_KEYWORD2_ATTRIBUTES"); + TextAttributesKey CUSTOM_KEYWORD3_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_KEYWORD3_ATTRIBUTES"); + TextAttributesKey CUSTOM_KEYWORD4_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_KEYWORD4_ATTRIBUTES"); + TextAttributesKey CUSTOM_NUMBER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_NUMBER_ATTRIBUTES"); + TextAttributesKey CUSTOM_STRING_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_STRING_ATTRIBUTES"); + TextAttributesKey CUSTOM_LINE_COMMENT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_LINE_COMMENT_ATTRIBUTES"); + TextAttributesKey CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/PosBufferTokenizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/PosBufferTokenizer.java new file mode 100644 index 00000000000..1d03deb5861 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/PosBufferTokenizer.java @@ -0,0 +1,358 @@ +package com.intellij.ide.highlighter.custom; + + +public class PosBufferTokenizer { + private char buffer[]; + + // Temp buffer. + private char buf[] = new char[20]; + + private int peekc = NEED_CHAR; + + private static final int NEED_CHAR = Integer.MAX_VALUE; + + private boolean pushedBack; + //private boolean forceLower; + + private byte ctype[] = new byte[256]; + private static final byte CT_WHITESPACE = 1; + private static final byte CT_DIGIT = 2; + private static final byte CT_ALPHA = 4; + private static final byte CT_QUOTE = 8; + private static final byte CT_POSTFIX = 16; + + public int ttype = TT_NOTHING; + + public static final int TT_EOF = -1; + public static final int TT_EOL = '\n'; + public static final int TT_NUMBER = -2; + public static final int TT_WORD = -3; + public static final int TT_QUOTE = -5; + public static final int TT_WHITESPACE = -6; + private static final int TT_NOTHING = -4; + + private String hexPrefix; + + private Object lock; + + private int bufferEnd; + + private int pos; + + public String sval; + public int startOffset; + public int endOffset; + + private boolean myIgnoreCase; + + public PosBufferTokenizer() { + wordChars('a', 'z'); + wordChars('A', 'Z'); + wordChars(128 + 32, 255); + whitespaceChars(0, ' '); + parseNumbers(); + } + + public void start(char[] buffer, int from, int to) { + if (buffer == null) { + throw new NullPointerException(); + } + + this.lock = this; + this.buffer = buffer; + + if (to < from) { + throw new IllegalArgumentException(); + } + + pos = from; + bufferEnd = to; + } + + public void resetSyntax() { + for (int i = ctype.length; --i >= 0;) { + ctype[i] = 0; + } + } + + public void wordChars(int low, int hi) { + if (low < 0) { + low = 0; + } + if (hi >= ctype.length) { + hi = ctype.length - 1; + } + while (low <= hi) { + ctype[low++] |= CT_ALPHA; + } + } + + public void whitespaceChars(int low, int hi) { + if (low < 0) { + low = 0; + } + if (hi >= ctype.length) { + hi = ctype.length - 1; + } + while (low <= hi) { + ctype[low++] = CT_WHITESPACE; + } + } + + public void ordinaryChars(int low, int hi) { + if (low < 0) { + low = 0; + } + if (hi >= ctype.length) { + hi = ctype.length - 1; + } + while (low <= hi) { + ctype[low++] = 0; + } + } + + public void ordinaryChar(int ch) { + if (ch >= 0 && ch < ctype.length) { + ctype[ch] = 0; + } + } + + public void quoteChar(int ch) { + if (ch >= 0 && ch < ctype.length) { + ctype[ch] = CT_QUOTE; + } + } + + public void parseNumbers() { + for (int i = '0'; i <= '9'; i++) { + ctype[i] |= CT_DIGIT; + } + ctype['.'] |= CT_DIGIT; + } + + /** Read the next character */ + private int read() { + synchronized (lock) { + if (buffer == null) { + throw new NullPointerException(); + } + if (pos < 0) { + pos = 0; + } + if (pos >= bufferEnd) { + // We need pos to be "bufferEnd + 1" in order to drop + // unnecessary checks for determining endOffset. + if (pos == bufferEnd) pos++; + return -1; + } else { + return buffer[pos++]; + } + } + } + + public void skipToEol() { + int c; + do { + c = read(); + } while (c != '\r' && c != '\n' && c != -1); + pos--; + peekc = NEED_CHAR; + } + + public void skipToChar(char c) { + int d; + do { + d = read(); + } while (d != c && d != -1); + peekc = NEED_CHAR; + } + + public void skipToStr(String s) { + int c = 0; + while (c != -1) { + skipToChar(s.charAt(0)); + int i = 1; + do { + if (i == s.length()) return; + c = read(); + if (c != s.charAt(i++)) { + break; + } + } while (c != -1); + peekc = NEED_CHAR; + } + } + + public int nextToken() { + if (pushedBack) { + pushedBack = false; + return ttype; + } + byte ct[] = ctype; + sval = null; + + startOffset = 0; + endOffset = 0; + + int c = peekc; + + if (c < 0) { + c = NEED_CHAR; + } + + if (c == NEED_CHAR) { + c = read(); + if (c < 0) + return ttype = TT_EOF; + } + + // Just to be safe + ttype = c; + + // Set peekc so that the next invocation of nextToken will read + // another character unless peekc is reset in this invocation + peekc = NEED_CHAR; + + int ctype = c < 256 ? ct[c] : CT_ALPHA; + + if (isWhiteSpace(c)) { + startOffset = pos - 1; + do { + c = read(); + if (c >= 0) { + ctype = c < 256 ? ct[c] : CT_ALPHA; + } else { + break; + } + } while (isWhiteSpace(c)); + peekc = c; + endOffset = pos - 1; + return ttype = TT_WHITESPACE; + } + + if ((ctype & CT_DIGIT) != 0) { + startOffset = pos - 1; + + if (hexPrefix != null) { + for (int i = 0; i < hexPrefix.length(); i++) { + if (c == hexPrefix.charAt(i)) { + c = read(); + } else { + break; + } + } + } + do { + c = read(); + if (c < 0) break; + ctype = c < 256 ? ct[c] : CT_ALPHA; + if (!('0' <= c && c <= '9') && c != '.' && (ctype & CT_POSTFIX) == 0) { + break; + } + } while (c != -1); + peekc = c; + endOffset = pos - 1; + return ttype = TT_NUMBER; + } + + if ((ctype & CT_ALPHA) != 0) { + int i = 0; + do { + if (i >= buf.length) { + char nb[] = new char[buf.length * 2]; + System.arraycopy(buf, 0, nb, 0, buf.length); + buf = nb; + } + buf[i++] = (char) c; + c = read(); + ctype = c < 0 ? CT_WHITESPACE : c < 256 ? ct[c] : CT_ALPHA; + // To support keywords like 'font-size' + if (c == '-') ctype = CT_ALPHA; + } while ((ctype & (CT_ALPHA | CT_DIGIT)) != 0); + peekc = c; + startOffset = pos - i - 1; + endOffset = pos - 1; + sval = String.copyValueOf(buf, 0, i); + if (myIgnoreCase) { + sval = sval.toLowerCase(); + } + return ttype = TT_WORD; + } + + if ((ctype & CT_QUOTE) != 0) { + startOffset = pos - 1; + ttype = c; + int prev; + int d = -1; + do { + prev = d; + d = read(); + // Check for escape symbol. + if (d == ttype && prev != '\\') break; + } while (d != '\r' && d != '\n' && d != -1); + endOffset = (d == ttype)?pos:pos - 1; + if (d != ttype) { + peekc = d; + } else { + peekc = NEED_CHAR; + } + return ttype = TT_QUOTE; + } + + startOffset = pos - 1; + endOffset = pos; + + return ttype = c; + } + + private boolean isWhiteSpace(int c) { + return c == ' ' || c == '\t' || c == '\n'; + } + + public void pushBack() { + if (ttype != TT_NOTHING) /* No-op if nextToken() not called */ + pushedBack = true; + } + + public int getPos() { + if (pos > bufferEnd) { + return bufferEnd; + } + return pos; + } + + public void setHexPrefix(String hexPrefix) { + this.hexPrefix = hexPrefix; + for (char c = 'a'; c <= 'f'; c++) ctype[c] |= CT_POSTFIX; + for (char c = 'A'; c <= 'F'; c++) ctype[c] |= CT_POSTFIX; + } + + public void setNumPostifxChars(String numPostfixChars) { + if (numPostfixChars == null) return; + for (int i = 0; i < numPostfixChars.length(); i++) { + int ch = numPostfixChars.charAt(i); + if (ch >= 0 && ch < ctype.length) { + ctype[ch] |= CT_POSTFIX; + } + } + } + + public void setIgnoreCase(boolean ignoreCase) { + myIgnoreCase = ignoreCase; + } + + public boolean matchString(String s, int from) { + for (int i = from; i < s.length(); i++) { + int c = peekc; + if (peekc == NEED_CHAR) { + c = read(); + } + if (c != s.charAt(i)) { + peekc = c; + return false; + } + peekc = NEED_CHAR; + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTable.java new file mode 100644 index 00000000000..972cee874b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTable.java @@ -0,0 +1,184 @@ +package com.intellij.ide.highlighter.custom; + +import java.util.Set; +import java.util.TreeSet; + +/** + * @author Yura Cangea + * @version 1.0 + */ +public class SyntaxTable implements Cloneable { + private Set myKeywords1; + private Set myKeywords2; + private Set myKeywords3; + private Set myKeywords4; + + private String myLineComment; + private String myStartComment; + private String myEndComment; + + private String myHexPrefix; + private String myNumPostfixChars; + + private boolean myIgnoreCase; + private boolean myHasBraces; + private boolean myHasBrackets; + private boolean myHasParens; + + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- + + public SyntaxTable() { + myKeywords1 = new TreeSet(); + myKeywords2 = new TreeSet(); + myKeywords3 = new TreeSet(); + myKeywords4 = new TreeSet(); + } + + protected Object clone() throws CloneNotSupportedException { + SyntaxTable cl = (SyntaxTable) super.clone(); + cl.myKeywords1 = new TreeSet(myKeywords1); + cl.myKeywords2 = new TreeSet(myKeywords2); + cl.myKeywords3 = new TreeSet(myKeywords3); + cl.myKeywords4 = new TreeSet(myKeywords4); + + return cl; + } + + // ------------------------------------------------------------------------- + // Public interface + // ------------------------------------------------------------------------- + + public void addKeyword1(String keyword) { + myKeywords1.add(keyword); + } + + public Set getKeywords1() { + return myKeywords1; + } + + public void addKeyword2(String keyword) { + myKeywords2.add(keyword); + } + + public Set getKeywords2() { + return myKeywords2; + } + + public void addKeyword3(String keyword) { + myKeywords3.add(keyword); + } + + public Set getKeywords3() { + return myKeywords3; + } + + public void addKeyword4(String keyword) { + myKeywords4.add(keyword); + } + + public Set getKeywords4() { + return myKeywords4; + } + + public String getLineComment() { + return myLineComment; + } + + public void setLineComment(String lineComment) { + this.myLineComment = lineComment; + } + + public String getStartComment() { + return myStartComment; + } + + public void setStartComment(String startComment) { + this.myStartComment = startComment; + } + + public String getEndComment() { + return myEndComment; + } + + public void setEndComment(String endComment) { + this.myEndComment = endComment; + } + + public String getHexPrefix() { + return myHexPrefix; + } + + public void setHexPrefix(String hexPrefix) { + this.myHexPrefix = hexPrefix; + } + + public String getNumPostfixChars() { + return myNumPostfixChars; + } + + public void setNumPostfixChars(String numPostfixChars) { + this.myNumPostfixChars = numPostfixChars; + } + + public boolean isIgnoreCase() { + return myIgnoreCase; + } + + public void setIgnoreCase(boolean ignoreCase) { + myIgnoreCase = ignoreCase; + } + + public boolean isHasBraces() { + return myHasBraces; + } + + public void setHasBraces(boolean hasBraces) { + myHasBraces = hasBraces; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SyntaxTable)) return false; + + final SyntaxTable syntaxTable = (SyntaxTable)o; + + if (myIgnoreCase != syntaxTable.myIgnoreCase) return false; + if (myEndComment != null ? !myEndComment.equals(syntaxTable.myEndComment) : syntaxTable.myEndComment != null) return false; + if (myHexPrefix != null ? !myHexPrefix.equals(syntaxTable.myHexPrefix) : syntaxTable.myHexPrefix != null) return false; + if (!myKeywords1.equals(syntaxTable.myKeywords1)) return false; + if (!myKeywords2.equals(syntaxTable.myKeywords2)) return false; + if (!myKeywords3.equals(syntaxTable.myKeywords3)) return false; + if (!myKeywords4.equals(syntaxTable.myKeywords4)) return false; + if (myLineComment != null ? !myLineComment.equals(syntaxTable.myLineComment) : syntaxTable.myLineComment != null) return false; + if (myNumPostfixChars != null ? !myNumPostfixChars.equals(syntaxTable.myNumPostfixChars) : syntaxTable.myNumPostfixChars != null) return false; + if (myStartComment != null ? !myStartComment.equals(syntaxTable.myStartComment) : syntaxTable.myStartComment != null) return false; + + if (myHasBraces != syntaxTable.myHasBraces) return false; + if (myHasBrackets != syntaxTable.myHasBrackets) return false; + if (myHasParens != syntaxTable.myHasParens) return false; + + return true; + } + + public int hashCode() { + return myKeywords1.hashCode(); + } + + public boolean isHasBrackets() { + return myHasBrackets; + } + + public boolean isHasParens() { + return myHasParens; + } + + public void setHasBrackets(boolean hasBrackets) { + myHasBrackets = hasBrackets; + } + + public void setHasParens(boolean hasParens) { + myHasParens = hasParens; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTableLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTableLexer.java new file mode 100644 index 00000000000..54f90d255d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/SyntaxTableLexer.java @@ -0,0 +1,193 @@ +package com.intellij.ide.highlighter.custom; + +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.lexer.Lexer; +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * @author Yura Cangea + * @version 1.0 + */ +public class SyntaxTableLexer implements Lexer { + private SyntaxTable table; + + private PosBufferTokenizer tokenizer; + + private IElementType tokenType; + private int tokenStart; + private int tokenEnd; + + private String lineComment; + private String startComment; + private String endComment; + + private char[] buffer; + private int startOffset; + private int endOffset; + + private boolean firstCall; + + public SyntaxTableLexer(SyntaxTable table) { + this.table = table; + + tokenizer = new PosBufferTokenizer(); + tokenizer.setIgnoreCase(table.isIgnoreCase()); + + tokenizer.setHexPrefix(table.getHexPrefix()); + tokenizer.setNumPostifxChars(table.getNumPostfixChars()); + + tokenizer.ordinaryChar('/'); + tokenizer.ordinaryChar('.'); + tokenizer.quoteChar('"'); + tokenizer.quoteChar('\''); + tokenizer.wordChars('_', '_'); + + lineComment = table.getLineComment(); + startComment = table.getStartComment(); + endComment = table.getEndComment(); + } + + public void start(char[] buffer) { + start(buffer, 0, buffer.length, (short) 0); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + start(buffer, startOffset, endOffset, (short) 0); + } + + public void start(char[] buffer, int startOffset, int endOffset, + int initialState) { + this.buffer = buffer; + this.startOffset = startOffset; + this.endOffset = endOffset; + + tokenType = null; + + tokenizer.start(buffer, startOffset, endOffset); + + firstCall = true; + } + + private void parseToken() { + String st = null; + while (true) { + int ttype = tokenizer.nextToken(); + + switch (ttype) { + case PosBufferTokenizer.TT_EOF: + tokenStart = endOffset; + tokenEnd = endOffset; + tokenType = null; + return; + + case PosBufferTokenizer.TT_WHITESPACE: + tokenType = CustomHighlighterTokenType.WHITESPACE; + break; + + case PosBufferTokenizer.TT_WORD: + st = tokenizer.sval; + if (table.getKeywords1().contains(st)) { + tokenType = CustomHighlighterTokenType.KEYWORD_1; + } else if (table.getKeywords2().contains(st)) { + tokenType = CustomHighlighterTokenType.KEYWORD_2; + } else if (table.getKeywords3().contains(st)) { + tokenType = CustomHighlighterTokenType.KEYWORD_3; + } else if (table.getKeywords4().contains(st)) { + tokenType = CustomHighlighterTokenType.KEYWORD_4; + } else { + tokenType = CustomHighlighterTokenType.IDENTIFIER; + } + break; + + case PosBufferTokenizer.TT_NUMBER: + tokenType = CustomHighlighterTokenType.NUMBER; + break; + + case PosBufferTokenizer.TT_QUOTE: + tokenType = CustomHighlighterTokenType.STRING; + break; + + default: + // Line comment + if (lineComment != null && !"".equals(lineComment.trim())) { + if (ttype == lineComment.charAt(0) && tokenizer.matchString(lineComment, 1)) { + tokenType = CustomHighlighterTokenType.LINE_COMMENT; + tokenStart = tokenizer.getPos() - lineComment.length(); + tokenizer.skipToEol(); + tokenEnd = tokenizer.getPos(); + return; + } + } + + // Block comment + if (startComment != null && !"".equals(startComment.trim())) { + if (ttype == startComment.charAt(0) && tokenizer.matchString(startComment, 1)) { + tokenType = CustomHighlighterTokenType.MULTI_LINE_COMMENT; + tokenStart = tokenizer.getPos() - startComment.length(); + tokenizer.skipToStr(endComment); + tokenEnd = tokenizer.getPos(); + return; + } + } + tokenType = CustomHighlighterTokenType.CHARACTER; + break; + } + tokenStart = tokenizer.startOffset; + tokenEnd = tokenizer.endOffset; + return; + } + } + + + public IElementType getTokenType() { + if (firstCall) { + advance(); + } + return tokenType; + } + + public int getTokenStart() { + return tokenStart; + } + + public int getTokenEnd() { + return tokenEnd; + } + + public void advance() { + if (firstCall) { + firstCall = false; + } + parseToken(); + } + + // Number of characters to shift back from the change start to reparse. + public int getSmartUpdateShift() { + return 0; + } + + public char[] getBuffer() { + return buffer; + } + + public int getBufferEnd() { + return endOffset; + } + + public int getState() { + // No state. + return 0; + } + + public int getLastState() { + return 0; + } + + public Object clone() { + SyntaxTableLexer lexer = new SyntaxTableLexer(table); + lexer.start(buffer, startOffset, endOffset); + + return lexer; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java new file mode 100644 index 00000000000..ae9a09fa2fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java @@ -0,0 +1,66 @@ +package com.intellij.ide.highlighter.custom.impl; + +import com.intellij.codeInsight.highlighting.BraceMatchingUtil; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Dec 6, 2004 + * Time: 8:36:58 PM + * To change this template use File | Settings | File Templates. + */ +class CustomFileTypeBraceMatcher implements BraceMatchingUtil.BraceMatcher { + public int getTokenGroup(IElementType tokenType) { + return 777; + } + + public boolean isLBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) { + final IElementType tokenType = iterator.getTokenType(); + + return tokenType == CustomHighlighterTokenType.L_BRACKET || + tokenType == CustomHighlighterTokenType.L_PARENTH || + tokenType == CustomHighlighterTokenType.L_BRACE; + } + + public boolean isRBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) { + final IElementType tokenType = iterator.getTokenType(); + + return tokenType == CustomHighlighterTokenType.R_BRACKET || + tokenType == CustomHighlighterTokenType.R_PARENTH || + tokenType == CustomHighlighterTokenType.R_BRACE; + } + + public boolean isPairBraces(IElementType tokenType, IElementType tokenType2) { + return (tokenType == CustomHighlighterTokenType.L_BRACE && tokenType2 == CustomHighlighterTokenType.R_BRACE) || + (tokenType == CustomHighlighterTokenType.R_BRACE && tokenType2 == CustomHighlighterTokenType.L_BRACE) || + (tokenType == CustomHighlighterTokenType.L_BRACKET && tokenType2 == CustomHighlighterTokenType.R_BRACKET) || + (tokenType == CustomHighlighterTokenType.R_BRACKET && tokenType2 == CustomHighlighterTokenType.L_BRACKET) || + (tokenType == CustomHighlighterTokenType.L_PARENTH && tokenType2 == CustomHighlighterTokenType.R_PARENTH) || + (tokenType == CustomHighlighterTokenType.R_PARENTH && tokenType2 == CustomHighlighterTokenType.L_PARENTH); + } + + public boolean isStructuralBrace(HighlighterIterator iterator, CharSequence text, FileType fileType) { + final IElementType type = iterator.getTokenType(); + return type == CustomHighlighterTokenType.L_BRACE || type == CustomHighlighterTokenType.R_BRACE; + } + + public IElementType getTokenType(char ch, HighlighterIterator iterator) { + if (!(iterator.getTokenType() instanceof CustomHighlighterTokenType.CustomElementType)) { + return null; + } + + if (ch == '}') return CustomHighlighterTokenType.R_BRACE; + if (ch == '{') return CustomHighlighterTokenType.L_BRACE; + + if (ch == ']') return CustomHighlighterTokenType.R_BRACKET; + if (ch == '[') return CustomHighlighterTokenType.L_BRACKET; + if (ch == ')') return CustomHighlighterTokenType.R_PARENTH; + if (ch == '(') return CustomHighlighterTokenType.L_PARENTH; + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java new file mode 100644 index 00000000000..f55c651c187 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java @@ -0,0 +1,315 @@ +package com.intellij.ide.highlighter.custom.impl; + +import com.intellij.ide.highlighter.custom.SyntaxTable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.ui.DialogButtonGroup; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ListUtil; +import com.intellij.ui.TabbedPaneWrapper; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Iterator; + +/** + * @author Yura Cangea, dsl + */ +public class CustomFileTypeEditor extends SettingsEditor { + private JTextField myFileTypeName = new JTextField(26); + private JTextField myFileTypeDescr = new JTextField(26); + private JCheckBox myIgnoreCase = new JCheckBox("Ignore case"); + + private JCheckBox mySupportBraces = new JCheckBox("Support paired braces"); + private JCheckBox mySupportBrackets = new JCheckBox("Support paired brackets"); + private JCheckBox mySupportParens = new JCheckBox("Support paired parens"); + + private JTextField myLineComment = new JTextField(20); + private JTextField myBlockCommentStart = new JTextField(20); + private JTextField myBlockCommentEnd = new JTextField(20); + private JTextField myHexPrefix = new JTextField(20); + private JTextField myNumPostfixes = new JTextField(20); + + private JList[] myKeywordsLists = new JList[]{new JList(), new JList(), new JList(), new JList()}; + private DefaultListModel[] myKeywordModels = new DefaultListModel[]{new DefaultListModel(), new DefaultListModel(), new DefaultListModel(), new DefaultListModel()}; + private JButton[] myAddKeywordButtons = new JButton[4]; + private JButton[] myRemoveKeywordButtons = new JButton[4]; + + public CustomFileTypeEditor() { + } + + public void resetEditorFrom(CustomFileType fileType) { + myFileTypeName.setText(fileType.getName()); + myFileTypeDescr.setText(fileType.getDescription()); + + SyntaxTable table = fileType.getSyntaxTable(); + + if (table != null) { + myLineComment.setText(table.getLineComment()); + myBlockCommentEnd.setText(table.getEndComment()); + myBlockCommentStart.setText(table.getStartComment()); + myHexPrefix.setText(table.getHexPrefix()); + myNumPostfixes.setText(table.getNumPostfixChars()); + myIgnoreCase.setSelected(table.isIgnoreCase()); + + mySupportBraces.setSelected(table.isHasBraces()); + mySupportBrackets.setSelected(table.isHasBrackets()); + mySupportParens.setSelected(table.isHasParens()); + + for (Iterator i = table.getKeywords1().iterator(); i.hasNext();) { + myKeywordModels[0].addElement(i.next()); + } + for (Iterator i = table.getKeywords2().iterator(); i.hasNext();) { + myKeywordModels[1].addElement(i.next()); + } + for (Iterator i = table.getKeywords3().iterator(); i.hasNext();) { + myKeywordModels[2].addElement(i.next()); + } + for (Iterator i = table.getKeywords4().iterator(); i.hasNext();) { + myKeywordModels[3].addElement(i.next()); + } + } + } + + public void applyEditorTo(CustomFileType type) throws ConfigurationException { + if (myFileTypeName.getText().trim().length() == 0) { + throw new ConfigurationException("Name cannot be empty", "Error"); + } else if (myFileTypeDescr.getText().trim().length() == 0) { + myFileTypeDescr.setText(myFileTypeName.getText()); + } + type.setName(myFileTypeName.getText()); + type.setDescription(myFileTypeDescr.getText()); + type.setSyntaxTable(getSyntaxTable()); + } + + public JComponent createEditor() { + JComponent panel = createCenterPanel(); + initGui(); + for (int i = 0; i < myKeywordsLists.length; i++) { + myKeywordsLists[i].setModel(myKeywordModels[i]); + } + return panel; + } + + public void disposeEditor() { + } + + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + JPanel fileTypePanel = new JPanel(new BorderLayout()); + JPanel _panel0 = new JPanel(new BorderLayout()); + JPanel info = new JPanel(new GridBagLayout()); + GridBagConstraints gc = new GridBagConstraints(); + gc.gridx = 0; + gc.gridy = 0; + gc.anchor = GridBagConstraints.WEST; + gc.fill = GridBagConstraints.HORIZONTAL; + info.add(new JLabel("Name: "), gc); + gc.gridx = 1; + gc.gridy = 0; + info.add(myFileTypeName); + gc.gridx = 0; + gc.gridy = 2; + info.add(new JLabel("Description: "), gc); + gc.gridx = 1; + gc.gridy = 2; + info.add(myFileTypeDescr, gc); + gc.gridx = 0; + gc.gridy = 3; + _panel0.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + _panel0.add(info, BorderLayout.WEST); + fileTypePanel.add(_panel0, BorderLayout.NORTH); + + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Syntax Highlighting")); + JPanel highlighterPanel = panel1; + highlighterPanel.setLayout(new BorderLayout()); + JPanel panel2 = new JPanel(); + panel2.setBorder(IdeBorderFactory.createTitledBorder("Options")); + JPanel commentsAndNumbersPanel = panel2; + commentsAndNumbersPanel.setLayout(new GridBagLayout()); + + JPanel _panel1 = new JPanel(new BorderLayout()); + gc = new GridBagConstraints(); + gc.fill = GridBagConstraints.HORIZONTAL; + gc.anchor = GridBagConstraints.WEST; + gc.gridx = 0; + gc.gridy = 0; + commentsAndNumbersPanel.add(new JLabel("Line comment: "), gc); + gc.gridx = 1; + commentsAndNumbersPanel.add(myLineComment, gc); + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(new JLabel("Block comment start: "), gc); + gc.gridx = 1; + commentsAndNumbersPanel.add(myBlockCommentStart, gc); + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(new JLabel("Block comment end: "), gc); + gc.gridx = 1; + commentsAndNumbersPanel.add(myBlockCommentEnd, gc); + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(new JLabel("Hex prefix: "), gc); + gc.gridx = 1; + commentsAndNumbersPanel.add(myHexPrefix, gc); + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(new JLabel("Number postfixes: "), gc); + gc.gridx = 1; + commentsAndNumbersPanel.add(myNumPostfixes, gc); + + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(mySupportBraces, gc); + + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(mySupportBrackets, gc); + + gc.gridx = 0; + gc.gridy++; + commentsAndNumbersPanel.add(mySupportParens, gc); + + _panel1.add(commentsAndNumbersPanel, BorderLayout.WEST); + + + highlighterPanel.add(_panel1, BorderLayout.NORTH); + + TabbedPaneWrapper tabbedPaneWrapper = new TabbedPaneWrapper(); + tabbedPaneWrapper.addTab("1", createKeywordsPanel(0)); + tabbedPaneWrapper.addTab("2", createKeywordsPanel(1)); + tabbedPaneWrapper.addTab("3", createKeywordsPanel(2)); + tabbedPaneWrapper.addTab("4", createKeywordsPanel(3)); + + highlighterPanel.add(tabbedPaneWrapper.getComponent(), BorderLayout.CENTER); + highlighterPanel.add(myIgnoreCase, BorderLayout.SOUTH); + + fileTypePanel.add(highlighterPanel, BorderLayout.CENTER); + + panel.add(fileTypePanel); + + for (int i = 0; i < myKeywordsLists.length; i++) { + final int idx = i; + myKeywordsLists[i].addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) edit(idx); + } + }); + } + + + return panel; + } + + private JPanel createKeywordsPanel(final int index) { + JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createTitledBorder("Keywords")); + JPanel keywordsPanel = panel; + keywordsPanel.setLayout(new BorderLayout()); + + keywordsPanel.add(new JScrollPane(myKeywordsLists[index]), BorderLayout.CENTER); + + DialogButtonGroup buttonGroup = new DialogButtonGroup(); + buttonGroup.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0)); + + myAddKeywordButtons[index] = new JButton("Add..."); + myAddKeywordButtons[index].setMnemonic('A'); + myAddKeywordButtons[index].addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ModifyKeywordDialog dialog = new ModifyKeywordDialog(myAddKeywordButtons[index], ""); + dialog.show(); + if (dialog.isOK()) { + String keywordName = dialog.getKeywordName(); + if (!myKeywordModels[index].contains(keywordName)) myKeywordModels[index].addElement(keywordName); + } + } + }); + buttonGroup.addButton(myAddKeywordButtons[index]); + + myRemoveKeywordButtons[index] = new JButton("Remove"); + myRemoveKeywordButtons[index].setMnemonic('R'); + myRemoveKeywordButtons[index].addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ListUtil.removeSelectedItems(myKeywordsLists[index]); + } + }); + + buttonGroup.addButton(myRemoveKeywordButtons[index]); + + keywordsPanel.add(buttonGroup, BorderLayout.EAST); + return keywordsPanel; + } + + private void edit(int index) { + if (myKeywordsLists[index].getSelectedIndex() == -1) return; + ModifyKeywordDialog dialog = new ModifyKeywordDialog(myKeywordsLists[index], (String) myKeywordsLists[index].getSelectedValue()); + dialog.show(); + if (dialog.isOK()) { + myKeywordModels[index].setElementAt(dialog.getKeywordName(), myKeywordsLists[index].getSelectedIndex()); + } + } + + public SyntaxTable getSyntaxTable() { + SyntaxTable syntaxTable = new SyntaxTable(); + syntaxTable.setLineComment(myLineComment.getText()); + syntaxTable.setStartComment(myBlockCommentStart.getText()); + syntaxTable.setEndComment(myBlockCommentEnd.getText()); + syntaxTable.setHexPrefix(myHexPrefix.getText()); + syntaxTable.setNumPostfixChars(myNumPostfixes.getText()); + + boolean ignoreCase = myIgnoreCase.isSelected(); + syntaxTable.setIgnoreCase(ignoreCase); + + syntaxTable.setHasBraces(mySupportBraces.isSelected()); + syntaxTable.setHasBrackets(mySupportBrackets.isSelected()); + syntaxTable.setHasParens(mySupportParens.isSelected()); + + for (int i = 0; i < myKeywordModels[0].size(); i++) { + if (ignoreCase) { + syntaxTable.addKeyword1(((String) myKeywordModels[0].getElementAt(i)).toLowerCase()); + } else { + syntaxTable.addKeyword1((String) myKeywordModels[0].getElementAt(i)); + } + } + for (int i = 0; i < myKeywordModels[1].size(); i++) { + if (ignoreCase) { + syntaxTable.addKeyword2(((String) myKeywordModels[1].getElementAt(i)).toLowerCase()); + } else { + syntaxTable.addKeyword2((String) myKeywordModels[1].getElementAt(i)); + } + } + for (int i = 0; i < myKeywordModels[2].size(); i++) { + if (ignoreCase) { + syntaxTable.addKeyword3(((String) myKeywordModels[2].getElementAt(i)).toLowerCase()); + } else { + syntaxTable.addKeyword3((String) myKeywordModels[2].getElementAt(i)); + } + } + for (int i = 0; i < myKeywordModels[3].size(); i++) { + if (ignoreCase) { + syntaxTable.addKeyword4(((String) myKeywordModels[3].getElementAt(i)).toLowerCase()); + } else { + syntaxTable.addKeyword4((String) myKeywordModels[3].getElementAt(i)); + } + } + return syntaxTable; + } + + // ------------------------------------------------------------------------- + // Helper methods + // ------------------------------------------------------------------------- + + private void initGui() { + myIgnoreCase.setMnemonic('I'); + mySupportBraces.setMnemonic('r'); + mySupportBrackets.setMnemonic('c'); + mySupportParens.setMnemonic('p'); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java new file mode 100644 index 00000000000..f8a85441b75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java @@ -0,0 +1,73 @@ +package com.intellij.ide.highlighter.custom.impl; + +import com.intellij.codeInsight.editorActions.TypedHandler; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Dec 6, 2004 + * Time: 8:34:21 PM + * To change this template use File | Settings | File Templates. + */ +class CustomFileTypeQuoteHandler implements TypedHandler.QuoteHandler { + public boolean isClosingQuote(HighlighterIterator iterator, int offset) { + final IElementType tokenType = iterator.getTokenType(); + + if (tokenType == CustomHighlighterTokenType.STRING || + tokenType == CustomHighlighterTokenType.CHARACTER){ + int start = iterator.getStart(); + int end = iterator.getEnd(); + return end - start >= 1 && offset == end - 1; + } + return false; + } + + public boolean isOpeningQuote(HighlighterIterator iterator, int offset) { + final IElementType tokenType = iterator.getTokenType(); + + if (tokenType == CustomHighlighterTokenType.STRING || + tokenType == CustomHighlighterTokenType.CHARACTER){ + int start = iterator.getStart(); + return offset == start; + } + return false; + } + + public boolean hasNonClosedLiteral(Editor editor, HighlighterIterator iterator, int offset) { + try { + Document doc = editor.getDocument(); + CharSequence chars = doc.getCharsSequence(); + int lineEnd = doc.getLineEndOffset(doc.getLineNumber(offset)); + + while (!iterator.atEnd() && iterator.getStart() < lineEnd) { + IElementType tokenType = iterator.getTokenType(); + + if (tokenType == CustomHighlighterTokenType.STRING || + tokenType == CustomHighlighterTokenType.CHARACTER) { + + if (iterator.getStart() >= iterator.getEnd() - 1 || + chars.charAt(iterator.getEnd() - 1) != '\"' && chars.charAt(iterator.getEnd() - 1) != '\'') { + return true; + } + } + iterator.advance(); + } + } finally { + while(iterator.getStart() != offset) iterator.retreat(); + } + + return false; + } + + public boolean isInsideLiteral(HighlighterIterator iterator) { + final IElementType tokenType = iterator.getTokenType(); + + return tokenType == CustomHighlighterTokenType.STRING || + tokenType == CustomHighlighterTokenType.CHARACTER; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java new file mode 100644 index 00000000000..1148b7f723b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/impl/ModifyKeywordDialog.java @@ -0,0 +1,67 @@ +package com.intellij.ide.highlighter.custom.impl; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Yura Cangea + */ +public class ModifyKeywordDialog extends DialogWrapper { + private JTextField myKeywordName = new JTextField(); + + public ModifyKeywordDialog(Component parent, String initialValue) { + super(parent, false); + if (initialValue == null || "".equals(initialValue)) { + setTitle("Add New Keyword"); + } else { + setTitle("Edit Keyword"); + } + init(); + myKeywordName.setText(initialValue); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gc = new GridBagConstraints(); + gc.gridx = 0; + gc.gridy = 0; + gc.weightx = 0; + gc.insets = new Insets(5, 0, 5, 5); + panel.add(new JLabel("Keyword: "), gc); + + gc = new GridBagConstraints(); + gc.gridx = 1; + gc.gridy = 0; + gc.weightx = 1; + gc.fill = GridBagConstraints.HORIZONTAL; + gc.gridwidth = 2; + gc.insets = new Insets(0, 0, 5, 0); + panel.add(myKeywordName, gc); + + panel.setPreferredSize(new Dimension(220, 40)); + return panel; + } + + protected JComponent createCenterPanel() { + return null; + } + + protected void doOKAction() { + if (myKeywordName.getText().trim().length() == 0) { + Messages.showMessageDialog(getContentPane(), "Keyword cannot be empty", "Error", Messages.getErrorIcon()); + return; + } + super.doOKAction(); + } + + public JComponent getPreferredFocusedComponent() { + return myKeywordName; + } + + public String getKeywordName() { + return myKeywordName.getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BaseTokenParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BaseTokenParser.java new file mode 100644 index 00000000000..fbfe982c665 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BaseTokenParser.java @@ -0,0 +1,22 @@ +package com.intellij.ide.highlighter.custom.tokens; + + +/** + * @author dsl + */ +public abstract class BaseTokenParser implements TokenParser { + protected char[] myBuffer; + protected int myStartOffset; + protected int myEndOffset; + protected final TokenInfo myTokenInfo = new TokenInfo(); + + public void setBuffer(char[] buffer, int startOffset, int endOffset) { + myBuffer = buffer; + myStartOffset = startOffset; + myEndOffset = endOffset; + } + + public void getTokenInfo(TokenInfo info) { + info.updateData(myTokenInfo); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java new file mode 100644 index 00000000000..16ca26680f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java @@ -0,0 +1,20 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.tree.IElementType; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Dec 6, 2004 + * Time: 7:40:12 PM + * To change this template use File | Settings | File Templates. + */ +public class BraceTokenParser extends PrefixedTokenParser { + public BraceTokenParser(String prefix, IElementType tokenType) { + super(prefix, tokenType); + } + + protected int getTokenEnd(int position) { + return position; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java new file mode 100644 index 00000000000..a0ce2bb8595 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/HexNumberParser.java @@ -0,0 +1,33 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; + +/** + * @author dsl + */ +public class HexNumberParser extends PrefixedTokenParser { + private HexNumberParser(String prefix) { + super(prefix, CustomHighlighterTokenType.NUMBER); + } + + protected int getTokenEnd(int position) { + for (; position < myEndOffset; position++) { + if (!isHexDigit(myBuffer[position])) break; + } + return position; + } + + public static boolean isHexDigit(char c) { + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); + } + + public static HexNumberParser create(String prefix) { + if (prefix == null) return null; + final String trimmedPrefix = prefix.trim(); + if (trimmedPrefix.length() > 0) { + return new HexNumberParser(prefix); + } else { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java new file mode 100644 index 00000000000..e7e5b1c4a07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/IdentifierParser.java @@ -0,0 +1,32 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * @author dsl + */ +public class IdentifierParser extends BaseTokenParser { + public IdentifierParser() { + } + + public boolean hasToken(int position) { + if (!Character.isJavaIdentifierStart(myBuffer[position])) return false; + final int start = position; + for (position++; position < myEndOffset; position++) { + final char c = myBuffer[position]; + if (!isIdentifierPart(c)) break; + } + IElementType tokenType = CustomHighlighterTokenType.IDENTIFIER; + myTokenInfo.updateData(start, position, tokenType); + return true; + } + + private boolean isIdentifierPart(final char c) { + return Character.isJavaIdentifierPart(c) || c == '-'; + } + + public int getSmartUpdateShift() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/KeywordParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/KeywordParser.java new file mode 100644 index 00000000000..df625a0630f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/KeywordParser.java @@ -0,0 +1,107 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.CustomHighlighterTokenType; +import com.intellij.psi.tree.IElementType; + +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author dsl + */ +public class KeywordParser extends BaseTokenParser { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.highlighter.custom.tokens.KeywordParser"); + private final HashSet[] myKeywordSets = new HashSet[CustomHighlighterTokenType.KEYWORD_TYPE_COUNT]; + private final int mySmartUpdateShift; + private final boolean myIgnoreCase; + private BitSet myFirstCharacters = new BitSet(); + private BitSet myCharacters = new BitSet(); + + public KeywordParser(Set[] keywordSets, boolean ignoreCase) { + LOG.assertTrue(keywordSets.length == myKeywordSets.length); + myIgnoreCase = ignoreCase; + int maxLength = 0; + for (int i = 0; i < keywordSets.length; i++) { + Set keywordSet = keywordSets[i]; + myKeywordSets[i] = getKeywordSet(keywordSet); + for (Iterator iterator = keywordSet.iterator(); iterator.hasNext();) { + String s = (String) iterator.next(); + maxLength = Math.max(maxLength, s.length()); + + final char firstChar = s.charAt(0); + if (ignoreCase) { + myFirstCharacters.set(Character.toUpperCase(firstChar), Character.toUpperCase(firstChar) + 1); + myFirstCharacters.set(Character.toLowerCase(firstChar), Character.toLowerCase(firstChar) + 1); + } else { + myFirstCharacters.set(firstChar, firstChar + 1); + } + for (int j = 0; j < s.length(); j++) { + final char currentChar = s.charAt(j); + if (ignoreCase) { + myCharacters.set(Character.toUpperCase(currentChar), Character.toUpperCase(currentChar) + 1); + myCharacters.set(Character.toLowerCase(currentChar), Character.toLowerCase(currentChar) + 1); + } + else { + myCharacters.set(currentChar, currentChar + 1); + } + } + } + } + mySmartUpdateShift = maxLength; + } + + private HashSet getKeywordSet(Set keywordSet) { + if (!myIgnoreCase) { + return new HashSet(keywordSet); + } else { + final HashSet result = new HashSet(); + for (Iterator iterator = keywordSet.iterator(); iterator.hasNext();) { + String s = (String) iterator.next(); + result.add(s.toUpperCase()); + } + return result; + } + } + + + public boolean hasToken(int position) { + if (!myFirstCharacters.get(myBuffer[position])) return false; + final int start = position; + for (position++; position < myEndOffset; position++) { + final char c = myBuffer[position]; + if (!myCharacters.get(c)) { + if (Character.isJavaIdentifierPart(c)) return false; + break; + } + } + + final String keyword = new String(myBuffer, start, position - start); + String testKeyword = myIgnoreCase ? keyword.toUpperCase() : keyword; + for (int i = 0; i < myKeywordSets.length; i++) { + HashSet keywordSet = myKeywordSets[i]; + if (keywordSet.contains(testKeyword)) { + myTokenInfo.updateData(start, position, getToken(i)); + return true; + } + } + + return false; + } + + private static IElementType getToken(int keywordSetIndex) { + switch(keywordSetIndex) { + case 0: return CustomHighlighterTokenType.KEYWORD_1; + case 1: return CustomHighlighterTokenType.KEYWORD_2; + case 2: return CustomHighlighterTokenType.KEYWORD_3; + case 3: return CustomHighlighterTokenType.KEYWORD_4; + } + return null; + } + + public int getSmartUpdateShift() { + return mySmartUpdateShift; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java new file mode 100644 index 00000000000..a17c2b32c11 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/LineCommentParser.java @@ -0,0 +1,29 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; + + +/** + * @author dsl + */ +public class LineCommentParser extends PrefixedTokenParser { + private LineCommentParser(String prefix) { + super(prefix, CustomHighlighterTokenType.LINE_COMMENT); + } + + protected int getTokenEnd(int position) { + for (; position < myEndOffset; position++) { + if (myBuffer[position] == '\n') break; + } + return position; + } + + public static LineCommentParser create(String prefix) { + final String trimmedPrefix = prefix.trim(); + if (!"".equals(trimmedPrefix)) { + return new LineCommentParser(prefix); + } else { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java new file mode 100644 index 00000000000..ffe4b1e4419 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/MultilineCommentParser.java @@ -0,0 +1,39 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; + +/** + * @author dsl + */ +public class MultilineCommentParser extends PrefixedTokenParser { + private final char[] myEndDelimiter; + + private MultilineCommentParser(String startDelimiter, String endDelimiter) { + super(startDelimiter, CustomHighlighterTokenType.MULTI_LINE_COMMENT); + myEndDelimiter = endDelimiter.toCharArray(); + } + + protected int getTokenEnd(int position) { + for (; position < myEndOffset; position++) { + // todo: implement KMP + int pos = position; + int i; + for (i = 0; i < myEndDelimiter.length && pos < myEndOffset; i++, pos++) { + if (myBuffer[pos] != myEndDelimiter[i]) break; + } + if (i == myEndDelimiter.length) return pos; + } + return position; + } + + public static MultilineCommentParser create(String startDelimiter, String endDelimiter) { + if(startDelimiter == null || endDelimiter == null) return null; + final String trimmedStart = startDelimiter.trim(); + final String trimmedEnd = endDelimiter.trim(); + if (trimmedStart.length() > 0 && trimmedEnd.length() > 0) { + return new MultilineCommentParser(trimmedStart, trimmedEnd); + } else { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/NumberParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/NumberParser.java new file mode 100644 index 00000000000..e30a2dab6f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/NumberParser.java @@ -0,0 +1,75 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; + +/** + * @author dsl + */ +public final class NumberParser extends BaseTokenParser { + private final String mySuffices; + private final boolean myIgnoreCase; + + public NumberParser(String suffices, boolean ignoreCase) { + myIgnoreCase = ignoreCase; + if (!myIgnoreCase) { + mySuffices = suffices; + } else { + mySuffices = suffices.toLowerCase().concat(suffices.toUpperCase()); + } + } + + public boolean hasToken(int position) { + final int start = position; + final char startChar = myBuffer[start]; + if(!isDigit(startChar)) return false; + for (position++; position < myEndOffset; position++) { + if (!isDigit(myBuffer[position])) break; + } + + if (position < myEndOffset && myBuffer[position] == '.') { + final int dotPosition = position; + position++; + + if (position < myEndOffset && !isDigit(myBuffer[position])) { + position = dotPosition; + } else { + // after decimal point + for (; position < myEndOffset; position++) { + if (!isDigit(myBuffer[position])) break; + } + if (position < myEndOffset) { + final char finalChar = myBuffer[position]; + if (!isNumberTail(finalChar) && !isDelimiter(finalChar)) { + position = dotPosition; + } + } + } + } + while(position < myEndOffset && isNumberTail(myBuffer[position])) { + position++; + } + + myTokenInfo.updateData(start, position, CustomHighlighterTokenType.NUMBER); + return true; + } + + public int getSmartUpdateShift() { + return 2; // if previous character was a dec point + } + + static boolean isDigit(char c) { + return c >= '0' && c <= '9'; + } + + private boolean isDelimiter(char c) { + return !Character.isLetter(c); + } + + private boolean isSuffix(char c) { + return mySuffices != null && mySuffices.indexOf(c) >= 0; + } + + private boolean isNumberTail(char c) { + return /*Character.isLetter(c) ||*/ isSuffix(c); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java new file mode 100644 index 00000000000..94d13611785 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/PrefixedTokenParser.java @@ -0,0 +1,34 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.tree.IElementType; + +/** + * @author dsl + */ +public abstract class PrefixedTokenParser extends BaseTokenParser { + private char[] myPrefix; + private final IElementType myTokenType; + + public PrefixedTokenParser(String prefix, IElementType tokenType) { + myTokenType = tokenType; + myPrefix = prefix.toCharArray(); + } + + public final boolean hasToken(int position) { + final int start = position; + int i; + for (i = 0; i < myPrefix.length && position < myEndOffset; i++, position++) { + if (myPrefix[i] != myBuffer[position]) break; + } + if (i < myPrefix.length) return false; + int end = getTokenEnd(position); + myTokenInfo.updateData(start, end, myTokenType); + return true; + } + + public int getSmartUpdateShift() { + return myPrefix.length; + } + + protected abstract int getTokenEnd(int position); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java new file mode 100644 index 00000000000..8653c7c09a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/QuotedStringParser.java @@ -0,0 +1,26 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.CustomHighlighterTokenType; + +/** + * @author dsl + */ +public class QuotedStringParser extends PrefixedTokenParser { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.highlighter.custom.tokens.QuotedStringParser"); + private char myQuote; + + public QuotedStringParser(String quote) { + super(quote, CustomHighlighterTokenType.STRING); + LOG.assertTrue(quote.length() == 1); + myQuote = quote.charAt(0); + } + + protected int getTokenEnd(int position) { + for(; position < myEndOffset; position++) { + if(myBuffer[position] == myQuote) return position + 1; + if(myBuffer[position] == '\n') return position; + } + return position; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenInfo.java new file mode 100644 index 00000000000..bc21f9ea74c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenInfo.java @@ -0,0 +1,36 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.tree.IElementType; + +/** + * @author dsl + */ +public class TokenInfo { + private int myStart; + private int myEnd; + private IElementType myType; + + public int getStart() { + return myStart; + } + + public int getEnd() { + return myEnd; + } + + public IElementType getType() { + return myType; + } + + public void updateData(int tokenStart, int tokenEnd, IElementType tokenType) { + myStart = tokenStart; + myEnd = tokenEnd; + myType = tokenType; + } + + public void updateData(TokenInfo info) { + myStart = info.myStart; + myEnd = info.myEnd; + myType = info.myType; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenParser.java new file mode 100644 index 00000000000..22579443e4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/TokenParser.java @@ -0,0 +1,13 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.ide.highlighter.custom.tokens.TokenInfo; + +/** + * @author dsl + */ +public interface TokenParser { + void setBuffer(char[] buffer, int startOffset, int endOffset); + boolean hasToken(int position); + void getTokenInfo(TokenInfo info); + int getSmartUpdateShift(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java new file mode 100644 index 00000000000..b7e9559feba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/highlighter/custom/tokens/WhitespaceParser.java @@ -0,0 +1,22 @@ +package com.intellij.ide.highlighter.custom.tokens; + +import com.intellij.psi.CustomHighlighterTokenType; + + +/** + * @author dsl + */ +public class WhitespaceParser extends BaseTokenParser { + + public boolean hasToken(int position) { + if (!Character.isWhitespace(myBuffer[position])) return false; + int start = position; + for (position++; position < myEndOffset && Character.isWhitespace(myBuffer[position]); position++) ; + myTokenInfo.updateData(start, position, CustomHighlighterTokenType.WHITESPACE); + return true; + } + + public int getSmartUpdateShift() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/CommonActionsManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/CommonActionsManagerImpl.java new file mode 100644 index 00000000000..0b04d4ccd0f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/CommonActionsManagerImpl.java @@ -0,0 +1,79 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.*; +import com.intellij.ide.actions.*; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.AutoScrollToSourceHandler; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 20, 2004 + * Time: 9:42:34 PM + * To change this template use File | Settings | File Templates. + */ +public class CommonActionsManagerImpl extends CommonActionsManager implements ApplicationComponent { + public AnAction createPrevOccurenceAction(OccurenceNavigator navigator) { + return new PreviousOccurenceToolbarAction(navigator); + } + + public AnAction createNextOccurenceAction(OccurenceNavigator navigator) { + return new NextOccurenceToolbarAction(navigator); + } + + public AnAction createExpandAllAction(TreeExpander expander) { + return new ExpandAllToolbarAction(expander); + } + + public AnAction createCollapseAllAction(TreeExpander expander) { + return new CollapseAllToolbarAction(expander); + } + + public AnAction createHelpAction(String helpId) { + return new HelpAction(helpId); + } + + public AnAction installAutoscrollToSourceHandler(Project project, JTree tree, final AutoScrollToSourceOptionProvider optionProvider) { + AutoScrollToSourceHandler handler = new AutoScrollToSourceHandler(project) { + public boolean isAutoScrollMode() { + return optionProvider.isAutoScrollMode(); + } + + public void setAutoScrollMode(boolean state) { + optionProvider.setAutoScrollMode(state); + } + }; + handler.install(tree); + return handler.createToggleAction(); + } + + public AnAction createExportToTextFileAction(ExporterToTextFile exporter) { + return new ExportToTextFileToolbarAction(exporter); + } + + public String getComponentName() { + return "CommonActionsManager"; + } + public void initComponent() {} + public void disposeComponent() {} + + private static final class HelpAction extends AnAction { + private String myHelpId; + + private HelpAction(String helpId) { + super("Help", null, IconLoader.getIcon("/actions/help.png")); + myHelpId = helpId; + } + + public void actionPerformed(AnActionEvent e) { + HelpManager.getInstance().invokeHelp(myHelpId); // + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ContentManagerWatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ContentManagerWatcher.java new file mode 100644 index 00000000000..6927d4871bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ContentManagerWatcher.java @@ -0,0 +1,64 @@ +package com.intellij.ide.impl; + +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ContentManagerWatcher { + private final ToolWindow myToolWindow; + private final ContentManager myContentManager; + private final PropertyChangeListener myPropertyChangeListener; + + public ContentManagerWatcher(ToolWindow toolWindow,ContentManager contentManager) { + myToolWindow = toolWindow; + myContentManager = contentManager; + myToolWindow.setAvailable(contentManager.getContentCount()>0,null); + + myPropertyChangeListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + if (Content.PROP_DISPLAY_NAME.equals(e.getPropertyName())) { + updateTitle(); + } + } + }; + + contentManager.addContentManagerListener( + new ContentManagerAdapter(){ + public void selectionChanged(ContentManagerEvent e) { + updateTitle(); + } + + public void contentAdded(ContentManagerEvent e) { + e.getContent().addPropertyChangeListener(myPropertyChangeListener); + myToolWindow.setAvailable(true,null); + } + + public void contentRemoved(ContentManagerEvent e) { + e.getContent().removePropertyChangeListener(myPropertyChangeListener); + myToolWindow.setAvailable(myContentManager.getContentCount()>0,null); + } + } + ); + + // Synchonize title with current state of manager + + for(int i=0;i myDataConstantToRuleMap = new java.util.HashMap(); + private WindowManagerEx myWindowManager; + + public DataManagerImpl() { + registerRules(); + } + + public void initComponent() { } + + public void disposeComponent() { } + + private Object getData(String dataId, final Component focusedComponent) { + for (Component c = focusedComponent; c != null; c = c.getParent()) { + final DataProvider dataProvider = getDataProvider(c); + if (dataProvider == null) continue; + + Object data = getDataFromProvider(dataProvider, dataId, new HashSet()); + if (data != null) return data; + } + + return null; + } + + private Object getDataFromProvider(final DataProvider provider, String dataId, final Set alreadyComputedIds) { + if (alreadyComputedIds.contains(dataId)) return null; + + alreadyComputedIds.add(dataId); + try { + Object data = provider.getData(dataId); + if (data != null) return validated(data, dataId, provider); + + GetDataRule dataRule = getDataRule(dataId); + if (dataRule != null) { + data = dataRule.getData(new DataProvider() { + public Object getData(String dataId) { + return getDataFromProvider(provider, dataId, alreadyComputedIds); + } + }); + + if (data != null) return validated(data, dataId, provider); + } + + return null; + } + finally { + alreadyComputedIds.remove(dataId); + } + } + + private DataProvider getDataProvider(Component c) { + DataProvider dataProvider = null; + if (c instanceof DataProvider) { + dataProvider = (DataProvider)c; + } + return dataProvider; + } + + public GetDataRule getDataRule(String dataId) { + return myDataConstantToRuleMap.get(dataId); + } + + private Object validated(Object data, String dataId, Object dataSource) { + Object invalidData = DataValidator.findInvalidData(dataId, data); + if (invalidData != null) { + LOG.assertTrue(false, "Data isn't valid. " + dataId + "=" + invalidData + " Provided by: " + dataSource.getClass().getName() + " (" + dataSource.toString()+")"); + } + return data; + } + + public DataContext getDataContext(Component component) { + return new MyDataContext(component); + } + + public DataContext getDataContext(Component component, int x, int y) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if ( + x < 0 || x >= component.getWidth() || + y < 0 || y >= component.getHeight() + ) { + throw new IllegalArgumentException("wrong point: x=" + x + "; y=" + y); + } + + // Point inside JTabbedPane has special meaning. If point is inside tab bounds then + // we construct DataContext by the component which corresponds to the (x, y) tab. + if (component instanceof JTabbedPane) { + JTabbedPane tabbedPane = (JTabbedPane)component; + int index = tabbedPane.getUI().tabForCoordinate(tabbedPane, x, y); + return getDataContext(index != -1 ? tabbedPane.getComponentAt(index) : tabbedPane); + } + else { + return getDataContext(component); + } + } + + public void setWindowManager(WindowManagerEx windowManager) { + myWindowManager = windowManager; + } + + public DataContext getDataContext() { + return getDataContext(getFocusedComponent()); + } + + public DataContext getDataContextTest(Component component) { + DataContext dataContext = getDataContext(component); + if (myWindowManager == null) { + return dataContext; + } + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Component focusedComponent = myWindowManager.getFocusedComponent(project); + if (focusedComponent != null) { + dataContext = getDataContext(focusedComponent); + } + return dataContext; + } + + private Component getFocusedComponent() { + if (myWindowManager == null) { + return null; + } + Window activeWindow = myWindowManager.getMostRecentFocusedWindow(); + if (activeWindow == null) { + return null; + } + // try to find first parent window that has focus + Window window = activeWindow; + Component focusedComponent = null; + while (window != null) { + focusedComponent = myWindowManager.getFocusedComponent(window); + if (focusedComponent != null) { + break; + } + window = window.getOwner(); + } + if (focusedComponent == null) { + focusedComponent = activeWindow; + } + return focusedComponent; + } + + private void registerRules() { + myDataConstantToRuleMap.put(DataConstants.PSI_FILE, new PsiFileRule()); + myDataConstantToRuleMap.put(DataConstantsEx.PASTE_TARGET_PSI_ELEMENT, new PasteTargetRule()); + myDataConstantToRuleMap.put(DataConstantsEx.COPY_PROVIDER, new CopyProviderRule()); + myDataConstantToRuleMap.put(DataConstantsEx.CUT_PROVIDER, new CutProviderRule()); + myDataConstantToRuleMap.put(DataConstantsEx.PASTE_PROVIDER, new PasteProviderRule()); + myDataConstantToRuleMap.put(DataConstantsEx.PROJECT_FILE_DIRECTORY, new ProjectFileDirectoryRule()); + myDataConstantToRuleMap.put(DataConstants.NAVIGATABLE, new NavigatableRule()); + myDataConstantToRuleMap.put(DataConstants.VIRTUAL_FILE_ARRAY, new VirtualFileArrayRule()); + myDataConstantToRuleMap.put(DataConstants.VIRTUAL_FILE, new VirtualFileRule()); + myDataConstantToRuleMap.put(DataConstants.FILE_TEXT, new FileTextRule()); + myDataConstantToRuleMap.put(DataConstants.FILE_EDITOR, new FileEditorRule()); + myDataConstantToRuleMap.put(DataConstants.MODULE, new ModuleRule()); + myDataConstantToRuleMap.put(UsageView.USAGE_TARGETS, new UsageTargetsRule()); + } + + public String getComponentName() { + return "DataManager"; + } + + public class MyDataContext implements DataContext { + private int myEventCount; + // To prevent memory leak we have to wrap passed component into + // the weak reference. For example, Swing often remembers menu items + // that have DataContext as a field. + private final WeakReference myRef; + + public MyDataContext(final Component component) { + myEventCount = -1; + myRef = new WeakReference(component); + } + + public void setEventCount(int eventCount) { + myEventCount = eventCount; + } + + public Object getData(String dataId) { + int currentEventCount = IdeEventQueue.getInstance().getEventCount(); + if (myEventCount != -1 && myEventCount != currentEventCount) { + /* + throw new IllegalStateException( + "cannot share data context between Swing events; initial event count = " + + myEventCount + "; current event count = " + currentEventCount + ); + */ + LOG.assertTrue(false, + "cannot share data context between Swing events; initial event count = " + myEventCount + + "; current event count = " + + currentEventCount); + } + + Component _component = myRef.get(); + if (DataConstants.IS_MODAL_CONTEXT.equals(dataId)) { + if (_component != null) { + return IdeKeyEventDispatcher.isModalContext(_component) ? Boolean.TRUE : Boolean.FALSE; + } + else { + return null; + } + } + else if (DataConstantsEx.CONTEXT_COMPONENT.equals(dataId)) { + return _component; + } + else if (DataConstantsEx.MODALITY_STATE.equals(dataId)) { + return _component != null ? ModalityState.stateForComponent(_component) : ModalityState.NON_MMODAL; + } + else{ + return DataManagerImpl.this.getData(dataId, _component); + } + } + + public String toString() { + return "component=" + String.valueOf(myRef.get()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/DataValidator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/DataValidator.java new file mode 100644 index 00000000000..9c76551f8d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/DataValidator.java @@ -0,0 +1,65 @@ +package com.intellij.ide.impl; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; + +public abstract class DataValidator { + + Logger LOG = Logger.getInstance("#com.intellij.ide.impl.DataValidator"); + + private static final HashMap ourValidators = new HashMap(); + private static final DataValidator VIRTUAL_FILE_VALIDATOR = new DataValidator() { + public VirtualFile findInvalid(VirtualFile file) { + return file.isValid() ? null : file; + } + }; + private static final DataValidator PSI_ELEMENT_VALIDATOR = new DataValidator() { + public PsiElement findInvalid(PsiElement psiElement) { + return psiElement.isValid() ? null : psiElement; + } + }; + + public abstract T findInvalid(T data); + + public static DataValidator getValidator(String dataId) { + return ourValidators.get(dataId); + } + + public static Object findInvalidData(String dataId, Object data) { + if (data == null) return null; + DataValidator validator = getValidator(dataId); + if (validator != null) return validator.findInvalid(data); + return null; + } + + static { + ourValidators.put(DataConstants.VIRTUAL_FILE, VIRTUAL_FILE_VALIDATOR); + ourValidators.put(DataConstants.VIRTUAL_FILE_ARRAY, new ArrayValidator(VIRTUAL_FILE_VALIDATOR)); + ourValidators.put(DataConstants.PSI_ELEMENT, PSI_ELEMENT_VALIDATOR); + ourValidators.put(DataConstantsEx.PSI_ELEMENT_ARRAY, new ArrayValidator(PSI_ELEMENT_VALIDATOR)); + ourValidators.put(DataConstants.PSI_FILE, PSI_ELEMENT_VALIDATOR); + } + + private static class ArrayValidator extends DataValidator { + private final DataValidator myElementValidator; + + public ArrayValidator(DataValidator elementValidator) { + myElementValidator = elementValidator; + } + + public T findInvalid(Object object) { + Object[] array = (Object[])object; + for (int i = 0; i < array.length; i++) { + T element = (T)array[i]; + LOG.assertTrue(element != null); + T invalid = myElementValidator.findInvalid(element); + if (invalid != null) return invalid; + } + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/EditorHighlighterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/EditorHighlighterImpl.java new file mode 100644 index 00000000000..70da415093b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/EditorHighlighterImpl.java @@ -0,0 +1,140 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.EditorHighlighter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +/** + * @author MYakovlev + * Date: Jul 1, 2002 + */ +public class EditorHighlighterImpl extends EditorHighlighter implements ProjectComponent, FocusListener, CaretListener{ + private Project myProject; + private RangeHighlighter mySegmentHighlighter; + private Editor myEditor; + + public EditorHighlighterImpl(Project project){ + myProject = project; + } + + public void projectOpened(){ + } + + public void projectClosed(){ + } + + public String getComponentName(){ + return "EditorHighlighter"; + } + + public void initComponent() { } + + public void disposeComponent(){ + releaseAll(); + } + + public void selectInEditor(VirtualFile file, int startOffset, int endOffset, boolean toSelectLine, boolean toUseNormalSelection){ + releaseAll(); + openEditor(file, endOffset); + Editor editor = openEditor(file, startOffset); + + if(toUseNormalSelection && editor != null) { + DocumentEx doc = (DocumentEx) editor.getDocument(); + if (toSelectLine){ + int lineNumber = doc.getLineNumber(startOffset); + if (lineNumber >= 0 && lineNumber < doc.getLineCount()) { + editor.getSelectionModel().setSelection(doc.getLineStartOffset(lineNumber), doc.getLineEndOffset(lineNumber) + doc.getLineSeparatorLength(lineNumber)); + } + } + else { + editor.getSelectionModel().setSelection(startOffset, endOffset); + } + return; + } + + TextAttributes selectionAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + + if (editor != null){ + releaseAll(); + + if (toSelectLine){ + DocumentEx doc = (DocumentEx) editor.getDocument(); + int lineNumber = doc.getLineNumber(startOffset); + if (lineNumber >= 0 && lineNumber < doc.getLineCount()){ + mySegmentHighlighter = editor.getMarkupModel().addRangeHighlighter(doc.getLineStartOffset(lineNumber), + doc.getLineEndOffset(lineNumber) + doc.getLineSeparatorLength(lineNumber), + HighlighterLayer.LAST + 1, + selectionAttributes, HighlighterTargetArea.EXACT_RANGE); + } + } + else{ + mySegmentHighlighter = editor.getMarkupModel().addRangeHighlighter(startOffset, + endOffset, + HighlighterLayer.LAST + 1, + selectionAttributes, HighlighterTargetArea.EXACT_RANGE); + } + myEditor = editor; + myEditor.getContentComponent().addFocusListener(this); + myEditor.getCaretModel().addCaretListener(this); + } + } + + public void focusGained(FocusEvent e) { + releaseAll(); + } + + public void focusLost(FocusEvent e) { + } + + public void caretPositionChanged(CaretEvent e) { + releaseAll(); + } + + private void releaseAll() { + if (mySegmentHighlighter != null && myEditor != null){ + myEditor.getMarkupModel().removeHighlighter(mySegmentHighlighter); + myEditor.getContentComponent().removeFocusListener(this); + myEditor.getCaretModel().removeCaretListener(this); + mySegmentHighlighter = null; + myEditor = null; + } + } + + private Editor openEditor(VirtualFile file, int textOffset){ + if (file == null || !isValid(file)){ + return null; + } + OpenFileDescriptor descriptor = new OpenFileDescriptor(myProject, file, textOffset); + return FileEditorManager.getInstance(myProject).openTextEditor(descriptor, false); + } + + private static boolean isValid(final VirtualFile file){ + final boolean[] ret = new boolean[1]; + ApplicationManager.getApplication().runReadAction( + new Runnable(){ + public void run(){ + ret[0] = file.isValid(); + } + } + ); + return ret[0]; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/PackageViewSelectInTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/PackageViewSelectInTarget.java new file mode 100644 index 00000000000..a05e2c95b56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/PackageViewSelectInTarget.java @@ -0,0 +1,73 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.PackageViewPane; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class PackageViewSelectInTarget extends ProjectViewSelectInTarget { + public PackageViewSelectInTarget(Project project) { + super(project); + } + + public String toString() { + return "Packages"; + } + + public boolean canSelect(PsiFile file) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final VirtualFile vFile = getCorrespondingVirtualFile(file); + + if (vFile == null) { + return false; + } + + return fileIndex.isInSourceContent(vFile) || isInLibraryContentOnly(vFile); + } + + public void select(PsiElement element, boolean requestFocus) { + final ProjectView projectView = ProjectView.getInstance(myProject); + if (!projectView.isShowLibraryContents(getMinorViewId())) { + if (isInLibraryContentOnly(getCorrespondingVirtualFile(element))) { + projectView.setShowLibraryContents(true, getMinorViewId()); // turn the filter on in order to show the file in the view + } + } + super.select(element, requestFocus); + } + + private boolean isInLibraryContentOnly(final VirtualFile vFile) { + if (vFile == null) { + return false; + } + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + return (projectFileIndex.isInLibraryClasses(vFile) || projectFileIndex.isInLibrarySource(vFile)) && !projectFileIndex.isInSourceContent(vFile); + } + + private VirtualFile getCorrespondingVirtualFile(PsiElement psiElement) { + final VirtualFile vFile; + if (psiElement instanceof PsiFile) { + vFile = ((PsiFile)psiElement).getVirtualFile(); + } + else { + final PsiFile psiFile = psiElement.getContainingFile(); + if (psiFile == null) { + vFile = null; + } + else { + vFile = psiFile.getVirtualFile(); + } + } + if (vFile == null || !vFile.isValid()) { + return null; + } + return vFile; + } + + public String getMinorViewId() { + return PackageViewPane.ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java new file mode 100644 index 00000000000..b314bf9abad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java @@ -0,0 +1,38 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.projectView.impl.ProjectViewPane; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; + +public class ProjectPaneSelectInTarget extends ProjectViewSelectInTarget { + public ProjectPaneSelectInTarget(Project project) { + super(project); + } + + public String toString() { + return "Project"; + } + + public boolean canSelect(PsiFile file) { + if (file.getManager().isInProject(file)) { + return true; + } + + final VirtualFile vFile = file.getVirtualFile(); + if (vFile != null && vFile.isValid()) { + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); + if (projectFileIndex.isInLibraryClasses(vFile) || projectFileIndex.isInLibrarySource(vFile)) { + return true; + } + } + + return false; + } + + public String getMinorViewId() { + return ProjectViewPane.ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectUtil.java new file mode 100644 index 00000000000..8150eba8f74 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectUtil.java @@ -0,0 +1,215 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.util.projectWizard.AddModuleWizard; +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.GeneralSettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.diagnostic.Logger; +import org.jdom.JDOMException; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; + +/** + * @author Eugene Belyaev + */ +public class ProjectUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.impl.ProjectUtil"); + + public static void createNewProject(Project projectToClose) { + AddModuleWizard dialog = new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER); + dialog.show(); + if (!dialog.isOK()) { + return; + } + + final ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); + final String projectFilePath = dialog.getNewProjectFilePath(); + + final Project newProject = projectManager.newProject(projectFilePath, true, false); + + final ProjectJdk jdk = dialog.getNewProjectJdk(); + if (jdk != null) { + CommandProcessor.getInstance().executeCommand(newProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + ProjectRootManager.getInstance(newProject).setProjectJdk(jdk); + } + }); + } + }, null, null); + } + + newProject.save(); + + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length > 0) { + int exitCode = Messages.showDialog( + "Would you like to open the project in a new frame?", + "New Project", + new String[]{"_Yes", "_No"}, + 1, + Messages.getQuestionIcon() + ); + if (exitCode == 1) { // "No" option + closeProject(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1]); + } + } + + final ModuleBuilder moduleBuilder = dialog.getModuleBuilder(); + if (moduleBuilder != null) { + Exception ex = ApplicationManager.getApplication().runWriteAction(new Computable() { + public Exception compute() { + try { + final ModifiableModuleModel moduleModel = ModuleManager.getInstance(newProject).getModifiableModel(); + final Module module = moduleBuilder.createModule(moduleModel); + if (module != null) { + moduleModel.commitAssertingNoCircularDependency(); + } + return null; + } + catch (Exception e) { + return e; + } + } + }); + if (ex != null) { + Messages.showErrorDialog("Error adding module to project: " + ex.getMessage(), "Add Module"); + } + } + else { + StartupManager.getInstance(newProject).registerPostStartupActivity(new Runnable() { + public void run() { + // ensure the dialog is shown after all startup activities are done + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ModulesConfigurator.showDialog(newProject, null, null, true); + } + }); + } + }); + } + + updateLastProjectLocation(projectFilePath); + + projectManager.openProject(newProject); + } + + private static void updateLastProjectLocation(final String projectFilePath) { + File lastProjectLocation = new File(projectFilePath).getParentFile(); + if (lastProjectLocation == null) { // the immediate parent of the ipr file + return; + } + lastProjectLocation = lastProjectLocation.getParentFile(); // the candidate directory to be saved + if (lastProjectLocation == null) { + return; + } + try { + lastProjectLocation = lastProjectLocation.getCanonicalFile(); + } + catch (IOException e) { + LOG.info(e); + return ; + } + GeneralSettings.getInstance().setLastProjectLocation(lastProjectLocation.getPath().replace(File.separatorChar, '/')); + } + + /** + * @param project cannot be null + */ + public static boolean closeProject(Project project) { + if (project == null) { + throw new IllegalArgumentException("project cannot be null"); + } + + if (!ProjectManagerEx.getInstanceEx().closeProject(project)) return false; + ((ProjectEx)project).dispose(); + return true; + } + + public static Project openProject(final String path, Project projectToClose, boolean forceOpenInNewFrame) { + File file = new File(path); + if (!file.exists()) { + Messages.showMessageDialog("Cannot load " + path + ". The file does not exist.", "Error", Messages.getErrorIcon()); + return null; + } + + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + for (int i = 0; i < openProjects.length; i++) { + Project project = openProjects[i]; + if (Comparing.equal(path, project.getProjectFilePath())) { + return project; + } + } + + if (!forceOpenInNewFrame && openProjects.length > 0) { + int exitCode = Messages.showDialog( + "Would you like to open the project in a new frame?", + "Open Project", + new String[]{"_Yes", "_No", "Cancel"}, + 1, + Messages.getQuestionIcon() + ); + if (exitCode == 1) { // "No" option + if(!closeProject(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1])) return null; + } + else if (exitCode != 0) { // not "Yes" + return null; + } + } + + ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); + Project project = null; + try { + project = projectManager.loadProject(path); + projectManager.openProject(project); + } + catch (IOException e) { + Messages.showMessageDialog("Cannot load project: " + e.getMessage(), "Cannot Load Project", + Messages.getErrorIcon()); + } + catch (JDOMException e) { + Messages.showMessageDialog("Project file is corrupted", "Cannot Load Project", Messages.getErrorIcon()); + } + catch (InvalidDataException e) { + Messages.showMessageDialog("Project file is corrupted", "Cannot Load Project", Messages.getErrorIcon()); + } + return project; + } + + public static String mainModulePathByProjectPath(String path) { + int dotIdx = path.lastIndexOf('.'); + final String filePath = dotIdx >= 0 ? path.substring(0, dotIdx) + ".iml" : ""; + return filePath; + } + + public static String getInitialModuleRootPath(String projectFilePath) { + return new File(projectFilePath).getParentFile().getAbsolutePath(); + } + + public static String getInitialModuleLocation(final String projectFilePath) { + int dotIdx = projectFilePath.lastIndexOf('.'); + final String filePath = dotIdx >= 0 ? projectFilePath.substring(0, dotIdx) + ".iml" : ""; + return filePath; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectViewSelectInTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectViewSelectInTarget.java new file mode 100644 index 00000000000..22e2158d3da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/ProjectViewSelectInTarget.java @@ -0,0 +1,62 @@ +package com.intellij.ide.impl; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.ide.SelectInTarget; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + +public abstract class ProjectViewSelectInTarget implements SelectInTarget { + protected Project myProject; + + public ProjectViewSelectInTarget(Project project) { + myProject = project; + } + + public void select(PsiElement element, final boolean requestFocus) { + while (true) { + if (element instanceof PsiFile) break; + if (element instanceof PsiClass && element.getParent() instanceof PsiFile) break; + element = element.getParent(); + } + if (element instanceof PsiAspectFile) { + PsiAspect[] aspects = ((PsiAspectFile) element).getAspects(); + if (aspects.length > 0) { + element = aspects[0]; + } + } + else if (element instanceof PsiJavaFile) { + PsiClass[] classes = ((PsiJavaFile)element).getClasses(); + if (classes.length > 0) { + element = classes[0]; + } + } + final ProjectView projectView = ProjectView.getInstance(myProject); + final PsiElement _element1 = element.getOriginalElement(); + ToolWindowManager windowManager=ToolWindowManager.getInstance(myProject); + final Runnable runnable = new Runnable() { + public void run() { + if (requestFocus) { + projectView.changeView(getMinorViewId()); + } + projectView.selectPsiElement(_element1, requestFocus); + } + }; + if (requestFocus) { + windowManager.getToolWindow(ToolWindowId.PROJECT_VIEW).activate(runnable); + } + else { + runnable.run(); + } + } + + public String getToolWindowId() { + return ToolWindowId.PROJECT_VIEW; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewSelectInTarget.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewSelectInTarget.java new file mode 100644 index 00000000000..fb8588f649c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewSelectInTarget.java @@ -0,0 +1,79 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.SelectInTarget; +import com.intellij.ide.structureView.StructureView; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.psi.xml.XmlFile; + +public class StructureViewSelectInTarget implements SelectInTarget { + private Project myProject; + + public StructureViewSelectInTarget(Project project) { + myProject = project; + } + + + public String toString() { + return "File Structure"; + } + + /** + * This is called in an atomic action + */ + public boolean canSelect(PsiFile file) { + StructureView structureView = getStructureView(); + if (file == null || structureView == null || !FileEditorManager.getInstance(myProject).getSelectedEditor(file.getVirtualFile()).equals(structureView.getFileEditor())) { + return false; + } + return (file instanceof PsiJavaFile || file instanceof XmlFile) && file.isValid(); + } + + public void select(PsiElement element, final boolean requestFocus) { + PsiElement targetElement = element; + while (true) { + if (targetElement instanceof PsiClass && !(targetElement instanceof PsiAnonymousClass)) break; + if (targetElement instanceof PsiMethod) { + if (!(targetElement.getParent() instanceof PsiAnonymousClass)) break; + } + if (targetElement == null || targetElement instanceof PsiField || targetElement instanceof PsiFile) break; + targetElement = targetElement.getParent(); + } + if (targetElement == null) return; + final PsiElement theElement = targetElement; + + final StructureView structureView = getStructureView(); + ToolWindowManager windowManager=ToolWindowManager.getInstance(element.getProject()); + final Runnable runnable = new Runnable() { + public void run() { + VirtualFile virtualFile = theElement.getContainingFile().getVirtualFile(); + FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(virtualFile); + structureView.select(theElement, editor,requestFocus); + } + }; + if (requestFocus) { + windowManager.getToolWindow(ToolWindowId.STRUCTURE_VIEW).activate(runnable); + } + else { + runnable.run(); + } + } + + private StructureView getStructureView() { + return StructureViewFactory.getInstance(myProject).getStructureView(); + } + + public String getToolWindowId() { + return ToolWindowId.STRUCTURE_VIEW; + } + + public String getMinorViewId() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewWrapper.java new file mode 100644 index 00000000000..81cd56300a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/StructureViewWrapper.java @@ -0,0 +1,189 @@ +package com.intellij.ide.impl; + +import com.intellij.ide.structureView.StructureView; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.impl.StructureViewFactoryImpl; +import com.intellij.ide.structureView.newStructureView.StructureViewComponent; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiManager; +import com.intellij.util.Alarm; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; + +/** + * @author Eugene Belyaev + */ +public class StructureViewWrapper implements StructureView { + private Project myProject; + private FileEditor myFileEditor; + + private StructureViewComponent myStructureView; + + private JPanel myPanel; + + private FileEditorManagerListener myEditorManagerListener; + + private Alarm myAlarm; + + private StructureViewFactoryImpl myStructureViewFactory; + private FileTypeListener myFileTypeListener; + + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- + + public StructureViewWrapper(Project project) { + myProject = project; + myPanel = new JPanel(new BorderLayout()); + myPanel.setBackground(UIManager.getColor("Tree.textBackground")); + + myAlarm = new Alarm(); + + myStructureViewFactory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject); + + getComponent().addHierarchyListener(new HierarchyListener() { + public void hierarchyChanged(HierarchyEvent e) { + if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { + rebuild(); + } + } + }); + + myEditorManagerListener = new FileEditorManagerAdapter() { + public void selectionChanged(final FileEditorManagerEvent event) { + final FileEditor newEditor = event.getNewEditor(); + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + final PsiManager psiManager = PsiManager.getInstance(myProject); + myAlarm.cancelAllRequests(); + myAlarm.addRequest( + new Runnable() { + public void run() { + if (psiManager.isDisposed()) { + return; // project may have been closed + } + setFileEditor(newEditor); + if (myStructureViewFactory.AUTOSCROLL_FROM_SOURCE && myStructureView != null) { + FileEditor newEditor = event.getNewEditor(); + myStructureView.scrollToElementAtCaret(newEditor); + } + } + }, 400 + ); + } + }; + FileEditorManager.getInstance(project).addFileEditorManagerListener(myEditorManagerListener); + + myFileTypeListener = new FileTypeListener() { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(FileTypeEvent event){ + //VirtualFile[] files = FileEditorManager.getInstance(myProject).getSelectedFiles(); + //PsiFile psiFile = files.length != 0 ? PsiManager.getInstance(myProject).findFile(files[0]) : null; + //setFileEditor(psiFile); + } + }; + FileTypeManager.getInstance().addFileTypeListener(myFileTypeListener); + } + + // ------------------------------------------------------------------------- + // StructureView interface implementation + // ------------------------------------------------------------------------- + + public JComponent getComponent() { + return myPanel; + } + + public void dispose() { + myFileEditor = null; + FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myEditorManagerListener); + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + rebuild(); + } + + public boolean select(Object element, FileEditor fileEditor, boolean requestFocus) { + if (myStructureView != null) { + if (!Comparing.equal(myStructureView.getFileEditor(), fileEditor)){ + setFileEditor(fileEditor); + rebuild(); + } + return myStructureView.select(element, requestFocus); + } else { + return false; + } + } + + public FileEditor getFileEditor() { + return myFileEditor; + } + + // ------------------------------------------------------------------------- + // Helper methods + // ------------------------------------------------------------------------- + + + public void setFileEditor(FileEditor fileEditor) { + if (myFileEditor != null? !myFileEditor.equals(fileEditor) : fileEditor != null) { + myFileEditor = fileEditor; + rebuild(); + } + } + + public void rebuild() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + boolean hadFocus = myStructureView != null && IJSwingUtilities.hasFocus2(myStructureView.getComponent()); + if (myStructureView != null) { + myStructureView.dispose(); + myStructureView = null; + } + myPanel.removeAll(); + + if (!isStructureViewShowing()) { + return; + } + + if (myFileEditor!=null && myFileEditor.isValid()) { + StructureViewModel structureViewModel = myFileEditor.getStructureViewModel(); + if (structureViewModel != null) { + myStructureView = new StructureViewComponent(myFileEditor, structureViewModel, myProject); + myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER); + if (hadFocus) { + IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent()).requestFocus(); + } + myStructureView.centerSelectedRow(); + } + } + if (myStructureView == null) { + myPanel.add(new JLabel("Nothing to show in the Structure View", JLabel.CENTER), BorderLayout.CENTER); + } + + myPanel.validate(); + myPanel.repaint(); + } + + protected boolean isStructureViewShowing() { + ToolWindowManager windowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow=windowManager.getToolWindow(ToolWindowId.STRUCTURE_VIEW); + if (toolWindow!=null) { // it means that window is registered + return toolWindow.isVisible(); + } + return false; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CopyProviderRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CopyProviderRule.java new file mode 100644 index 00000000000..5c4fb9a47c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CopyProviderRule.java @@ -0,0 +1,15 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.CopyProvider; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.actionSystem.DataProvider; + +public class CopyProviderRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); + if (editor == null) return null; + CopyProvider copyProvider = editor.getCopyProvider(); + return copyProvider; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CutProviderRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CutProviderRule.java new file mode 100644 index 00000000000..0d38ca8b74e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/CutProviderRule.java @@ -0,0 +1,15 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.CutProvider; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.actionSystem.DataProvider; + +public class CutProviderRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); + if (editor == null) return null; + CutProvider cutProvider = editor.getCutProvider(); + return cutProvider; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileEditorRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileEditorRule.java new file mode 100644 index 00000000000..9a8a088e69b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileEditorRule.java @@ -0,0 +1,19 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; + +public class FileEditorRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + final Editor element = (Editor)dataProvider.getData(DataConstants.EDITOR); + if (element == null) { + return null; + } + + TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(element); + return textEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileTextRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileTextRule.java new file mode 100644 index 00000000000..91d05a5a536 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/FileTextRule.java @@ -0,0 +1,32 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Aug 16, 2002 + * Time: 1:49:57 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.awt.*; + +public class FileTextRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + VirtualFile virtualFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); + if (virtualFile == null) return null; + Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + if (project == null) return null; + + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document == null) return null; + return document.getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/GetDataRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/GetDataRule.java new file mode 100644 index 00000000000..cbbff0ac651 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/GetDataRule.java @@ -0,0 +1,7 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataProvider; + +public interface GetDataRule { + Object getData(DataProvider dataProvider); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ModuleRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ModuleRule.java new file mode 100644 index 00000000000..be965546ec3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ModuleRule.java @@ -0,0 +1,43 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; + +/** + * @author Eugene Zhuravlev + * Date: Feb 10, 2004 + */ +public class ModuleRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + Object moduleContext = dataProvider.getData(DataConstantsEx.MODULE_CONTEXT); + if (moduleContext != null) { + return moduleContext; + } + Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + if (project == null) { + PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + if (element == null || !element.isValid()) return null; + project = element.getProject(); + } + VirtualFile virtualFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); + if (virtualFile == null) { + GetDataRule dataRule = ((DataManagerImpl)DataManager.getInstance()).getDataRule(DataConstants.VIRTUAL_FILE); + if (dataRule != null) { + virtualFile = (VirtualFile)dataRule.getData(dataProvider); + } + } + + if (virtualFile == null || project == null) { + return null; + } + + return VfsUtil.getModuleForFile(project, virtualFile); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/NavigatableRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/NavigatableRule.java new file mode 100644 index 00000000000..798162c5145 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/NavigatableRule.java @@ -0,0 +1,29 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.DataManager; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +import java.awt.*; + +public class NavigatableRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + OpenFileDescriptor openFileDescriptor = (OpenFileDescriptor)dataProvider.getData(DataConstants.OPEN_FILE_DESCRIPTOR); + if (openFileDescriptor != null) return openFileDescriptor; + + Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + if (project == null && dataProvider instanceof Component){ + project = (Project)DataManager.getInstance().getDataContext((Component)dataProvider).getData(DataConstants.PROJECT); + } + if (project == null) { return null; } + + PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + if (element == null) return null; + + return EditSourceUtil.getDescriptor(element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteProviderRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteProviderRule.java new file mode 100644 index 00000000000..663e31ae59d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteProviderRule.java @@ -0,0 +1,15 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.ide.PasteProvider; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.actionSystem.DataProvider; + +public class PasteProviderRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); + if (editor == null) return null; + PasteProvider pasteProvider = editor.getPasteProvider(); + return pasteProvider; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteTargetRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteTargetRule.java new file mode 100644 index 00000000000..045cf0372c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PasteTargetRule.java @@ -0,0 +1,11 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; + +public class PasteTargetRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + Object data = dataProvider.getData(DataConstants.PSI_ELEMENT); + return data; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java new file mode 100644 index 00000000000..fcf1508da43 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java @@ -0,0 +1,27 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Eugene Zhuravlev + * Date: Feb 10, 2004 + */ +public class ProjectFileDirectoryRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + VirtualFile dir = (VirtualFile)dataProvider.getData(DataConstantsEx.PROJECT_FILE_DIRECTORY); + if (dir == null) { + final Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + if (project != null) { + final VirtualFile projectFile = project.getProjectFile(); + if (projectFile != null && projectFile.isValid()) { + dir = projectFile.getParent(); + } + } + } + return dir; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PsiFileRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PsiFileRule.java new file mode 100644 index 00000000000..1702ba96a30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/PsiFileRule.java @@ -0,0 +1,15 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class PsiFileRule implements GetDataRule { + public Object getData(DataProvider dataProvider) { + final PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + if (element == null) return null; + if (element instanceof PsiFile) return element; + return element.getContainingFile(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java new file mode 100644 index 00000000000..05c1c9411e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java @@ -0,0 +1,165 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.usages.Usage; +import com.intellij.usages.UsageTarget; +import com.intellij.usages.UsageView; +import com.intellij.usages.rules.UsageInFile; +import com.intellij.usages.rules.UsageInFiles; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class VirtualFileArrayRule implements GetDataRule { + public Object getData(final DataProvider dataProvider) { + // Try to detect multiselection. + + Project project = (Project)dataProvider.getData(DataConstants.PROJECT_CONTEXT); + if (project != null) { + return ProjectRootManager.getInstance(project).getContentRoots(); + } + + Module[] selectedModules = (Module[])dataProvider.getData(DataConstants.MODULE_CONTEXT_ARRAY); + if ((selectedModules != null) && (selectedModules.length > 0)) { + return getFilesFromModules(selectedModules); + } + + Module selectedModule = (Module)dataProvider.getData(DataConstants.MODULE_CONTEXT); + if ((selectedModule != null)) { + return ModuleRootManager.getInstance(selectedModule).getContentRoots(); + } + + PsiElement[] psiElements = (PsiElement[])dataProvider.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + if (psiElements != null && psiElements.length != 0) { + return getFilesFromPsiElements(psiElements); + } + + // VirtualFile -> VirtualFile[] + VirtualFile vFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); + if (vFile != null) { + return new VirtualFile[]{vFile}; + } + + // + + PsiFile psiFile = (PsiFile)dataProvider.getData(DataConstants.PSI_FILE); + if (psiFile != null && psiFile.getVirtualFile() != null) { + return new VirtualFile[]{psiFile.getVirtualFile()}; + } + + PsiElement elem = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + if (elem != null) { + return getFilesFromPsiElement(elem); + } + + Usage[] usages = (Usage[])dataProvider.getData(UsageView.USAGES); + UsageTarget[] usageTargets = (UsageTarget[])dataProvider.getData(UsageView.USAGE_TARGETS); + if (usages != null || usageTargets != null) { + return getFilesFromUsages(usages, usageTargets); + } + + + return null; + } + + private VirtualFile[] getFilesFromUsages(Usage[] usages, UsageTarget[] usageTargets) { + Set result = new HashSet(); + + if (usages != null) { + for (int i = 0; i < usages.length; i++) { + Usage usage = usages[i]; + if (usage instanceof UsageInFile) { + UsageInFile usageInFile = (UsageInFile)usage; + result.add(usageInFile.getFile()); + } + + if (usage instanceof UsageInFiles) { + UsageInFiles usageInFiles = (UsageInFiles)usage; + result.addAll(Arrays.asList(usageInFiles.getFiles())); + } + } + } + + if (usageTargets != null) { + for (int i = 0; i < usageTargets.length; i++) { + UsageTarget usageTarget = usageTargets[i]; + VirtualFile[] files = usageTarget.getFiles(); + if (files != null) { + result.addAll(Arrays.asList(files)); + } + } + } + + return result.toArray(new VirtualFile[result.size()]); + } + + private Object getFilesFromPsiElement(PsiElement elem) { + if (elem instanceof PsiFile) { + VirtualFile virtualFile = ((PsiFile)elem).getVirtualFile(); + return virtualFile != null ? new VirtualFile[]{virtualFile} : null; + } + else if (elem instanceof PsiDirectory) { + return new VirtualFile[]{((PsiDirectory)elem).getVirtualFile()}; + } + else { + PsiFile file = elem.getContainingFile(); + return file != null && file.getVirtualFile() != null ? new VirtualFile[]{file.getVirtualFile()} : null; + } + } + + private Object getFilesFromPsiElements(PsiElement[] psiElements) { + HashSet files = new HashSet(); + for (int i = 0; i < psiElements.length; i++) { + PsiElement elem = psiElements[i]; + if (elem instanceof PsiDirectory) { + files.add(((PsiDirectory)elem).getVirtualFile()); + } + else if (elem instanceof PsiFile) { + VirtualFile virtualFile = ((PsiFile)elem).getVirtualFile(); + if (virtualFile != null) { + files.add(virtualFile); + } + } + else if (elem instanceof PsiPackage) { + PsiDirectory[] dirs = ((PsiPackage)elem).getDirectories(); + for (int j = 0; j < dirs.length; j++) { + files.add(dirs[j].getVirtualFile()); + } + } + else { + PsiFile file = elem.getContainingFile(); + if (file != null) { + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + files.add(virtualFile); + } + } + } + } + VirtualFile[] result = files.toArray(new VirtualFile[files.size()]); + files.clear(); + return result; + } + + private Object getFilesFromModules(Module[] selectedModules) { + ArrayList result = new ArrayList(); + for (int i = 0; i < selectedModules.length; i++) { + Module selectedModule = selectedModules[i]; + result.addAll(Arrays.asList(ModuleRootManager.getInstance(selectedModule).getContentRoots())); + } + return result.toArray(new VirtualFile[result.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileRule.java new file mode 100644 index 00000000000..9c24e67d995 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/impl/dataRules/VirtualFileRule.java @@ -0,0 +1,60 @@ +package com.intellij.ide.impl.dataRules; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class VirtualFileRule implements GetDataRule { + public Object getData(final DataProvider dataProvider) { + // Try to detect multiselection. + + PsiElement[] psiElements = (PsiElement[])dataProvider.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + if (psiElements != null) { + for (int i = 0; i < psiElements.length; i++) { + PsiElement elem = psiElements[i]; + if (elem instanceof PsiDirectory) { + VirtualFile file = ((PsiDirectory)elem).getVirtualFile(); + return file; + } + else { + PsiFile containingFile = elem.getContainingFile(); + if (containingFile != null) { + VirtualFile file = containingFile.getVirtualFile(); + return file; + } + } + } + } + + + VirtualFile[] virtualFiles = (VirtualFile[])dataProvider.getData(DataConstants.VIRTUAL_FILE_ARRAY); + if (virtualFiles != null && virtualFiles.length == 1) { + return virtualFiles[0]; + } + + // + + PsiFile psiFile = (PsiFile)dataProvider.getData(DataConstants.PSI_FILE); + if (psiFile != null) { + return psiFile.getVirtualFile(); + } + PsiElement elem = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + if (elem == null) { + return null; + } + if (elem instanceof PsiFile) { + return ((PsiFile)elem).getVirtualFile(); + } + else if (elem instanceof PsiDirectory) { + return ((PsiDirectory)elem).getVirtualFile(); + } + else { + PsiFile file = elem.getContainingFile(); + return file != null ? file.getVirtualFile() : null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathEntryMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathEntryMacro.java new file mode 100644 index 00000000000..0461ed13359 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathEntryMacro.java @@ -0,0 +1,30 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Eugene Belyaev + */ +public final class ClasspathEntryMacro extends Macro { + public String getName() { + return "ClasspathEntry"; + } + + public String getDescription() { + return "Entry in the classpath the element belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + final VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + if (file == null) return null; + final VirtualFile classRoot = ProjectRootManager.getInstance(project).getFileIndex().getClassRootForFile(file); + if (classRoot == null) return null; + return getPath(classRoot); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathMacro.java new file mode 100644 index 00000000000..a2674a4323c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ClasspathMacro.java @@ -0,0 +1,23 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; + +public final class ClasspathMacro extends Macro { + public String getName() { + return "Classpath"; + } + + public String getDescription() { + return "Project's classpath"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + return ProjectRootsTraversing.collectRoots(project, ProjectRootsTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ColumnNumberMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ColumnNumberMacro.java new file mode 100644 index 00000000000..a06f0c77f2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ColumnNumberMacro.java @@ -0,0 +1,20 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; + +public final class ColumnNumberMacro extends Macro { + public String getName() { + return "ColumnNumber"; + } + + public String getDescription() { + return "Column number"; + } + + public String expand(DataContext dataContext) { + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + return editor != null ? String.valueOf(editor.getCaretModel().getLogicalPosition().column + 1) : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/DataAccessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/DataAccessor.java new file mode 100644 index 00000000000..61ea06dd12a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/DataAccessor.java @@ -0,0 +1,165 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.Convertor; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +public abstract class DataAccessor { + public static final DataAccessor PROJECT = new SimpleDataAccessor(DataConstants.PROJECT); + public static final DataAccessor EDITOR = new SimpleDataAccessor(DataConstants.EDITOR); + + public static final DataAccessor PSI_MANAGER = new DataAccessor() { + public PsiManager getImpl(DataContext dataContext) throws NoDataException { + return PsiManager.getInstance(PROJECT.getNotNull(dataContext)); + } + }; + + public static final DataAccessor FILE_EDITOR_MANAGER = new DataAccessor() { + public FileEditorManager getImpl(DataContext dataContext) throws NoDataException { + return FileEditorManager.getInstance(PROJECT.getNotNull(dataContext)); + } + }; + + public static final DataAccessor PSI_FILE = new DataAccessor() { + public PsiFile getImpl(DataContext dataContext) throws NoDataException { + return PSI_MANAGER.getNotNull(dataContext).findFile(VIRTUAL_FILE.getNotNull(dataContext)); + } + }; + + public static final DataAccessor PSI_ELEMENT = new SimpleDataAccessor(DataConstants.PSI_ELEMENT); + public static final DataAccessor PSI_ELEMENT_ARRAY = new SimpleDataAccessor(DataConstantsEx.PSI_ELEMENT_ARRAY); + + public static final DataAccessor VIRTUAL_FILE = new SimpleDataAccessor(DataConstants.VIRTUAL_FILE); + public static final DataAccessor VIRTUAL_FILE_ARRAY = new SimpleDataAccessor(DataConstants.VIRTUAL_FILE_ARRAY); + + public static final DataAccessor VIRTUAL_DIR_OR_PARENT = new DataAccessor() { + public VirtualFile getImpl(DataContext dataContext) throws NoDataException { + VirtualFile virtualFile = VIRTUAL_FILE.getNotNull(dataContext); + return virtualFile.isDirectory() ? virtualFile : virtualFile.getParent(); + } + }; + + public static final DataAccessor FILE_PACKAGE = new DataAccessor() { + public PsiPackage getImpl(DataContext dataContext) throws NoDataException { + PsiFile psiFile = PSI_FILE.getNotNull(dataContext); + PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + if (containingDirectory == null || !containingDirectory.isValid()) return null; + return containingDirectory.getPackage(); + } + }; + + public static final DataAccessor PSI_JAVA_FILE = SubClassDataAccessor.create(PSI_FILE, PsiJavaFile.class); + + public static final DataAccessor PROJECT_FILE_PATH = new DataAccessor() { + public String getImpl(DataContext dataContext) throws NoDataException { + Project project = PROJECT.getNotNull(dataContext); + return project.getProjectFilePath(); + } + }; + public static final DataAccessor PROJECT_EX = new SubClassDataAccessor(PROJECT, ProjectEx.class); + + public final T from(DataContext dataContext) { + try { + return getNotNull(dataContext); + } catch(NoDataException e) { + return null; + } + } + + protected abstract T getImpl(DataContext dataContext) throws NoDataException; + + public final T getNotNull(DataContext dataContext) throws NoDataException { + T data = getImpl(dataContext); + if (data == null) throw new NoDataException(toString()); + return data; + } + + public static DataAccessor createConvertor(final DataAccessor original, + final Convertor convertor) { + return new DataAccessor(){ + public T getImpl(DataContext dataContext) throws NoDataException { + return convertor.convert(original.getNotNull(dataContext)); + } + }; + } + + public static DataAccessor/**/ createArrayConvertor(final DataAccessor/**/ original, final Convertor convertor, final Class aClass) { + return new DataAccessor/**/() { + public Object /*T[]*/ getImpl(DataContext dataContext) throws NoDataException { + ArrayList converted = CollectUtil.SKIP_NULLS.toList((Object[])original.getNotNull(dataContext), convertor); + return converted.toArray((Object[]/*T[]*/)Array.newInstance(aClass, converted.size())); + } + }; + } + + public static DataAccessor createConditionalAccessor(DataAccessor accessor, Condition condition) { + return new ConditionalDataAccessor(accessor, condition); + } + + public static class SimpleDataAccessor extends DataAccessor { + private final String myDataConstant; + + public SimpleDataAccessor(String dataConstant) { + myDataConstant = dataConstant; + } + + public T getImpl(DataContext dataContext) throws NoDataException { + T data = (T)dataContext.getData(myDataConstant); + if (data == null) throw new NoDataException(myDataConstant); + return data; + } + } + + public static class SubClassDataAccessor extends DataAccessor { + private final DataAccessor myOriginal; + private final Class mySubClass; + + private SubClassDataAccessor(DataAccessor original, Class subClass) { + myOriginal = original; + mySubClass = subClass; + } + + public Sub getImpl(DataContext dataContext) throws NoDataException { + Object data = myOriginal.getNotNull(dataContext); + if (!mySubClass.isInstance(data)) return null; + return (Sub)data; + } + + public static DataAccessor create(DataAccessor accessor, Class subClass) { + return new SubClassDataAccessor(accessor, subClass); + } + } + + private static class ConditionalDataAccessor extends DataAccessor { + private final DataAccessor myOriginal; + private final Condition myCondition; + + public ConditionalDataAccessor(DataAccessor original, Condition condition) { + myOriginal = original; + myCondition = condition; + } + + public T getImpl(DataContext dataContext) throws NoDataException { + T value = myOriginal.getNotNull(dataContext); + return myCondition.value(value) ? value : null; + } + } + + public static class NoDataException extends Exception { + public NoDataException(String missingData) { + super("No data: " + missingData); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileClassMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileClassMacro.java new file mode 100644 index 00000000000..42eac64aaef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileClassMacro.java @@ -0,0 +1,46 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaFile; + +public final class FileClassMacro extends Macro { + public String getName() { + return "FileClass"; + } + + public String getDescription() { + return "Class name"; + } + + public String expand(DataContext dataContext) { + //Project project = (Project)dataContext.getData(DataConstants.PROJECT); + //if (project == null) { + // return null; + //} + //VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + //if (file == null) { + // return null; + //} + //PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + //if (!(psiFile instanceof PsiJavaFile)) { + // return null; + //} + final PsiJavaFile javaFile = DataAccessor.PSI_JAVA_FILE.from(dataContext); + if (javaFile == null) return null; + PsiClass[] classes = javaFile.getClasses(); + if (classes.length == 1) { + return classes[0].getQualifiedName(); + } + String fileName = javaFile.getVirtualFile().getNameWithoutExtension(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + String name = aClass.getName(); + if (fileName.equals(name)) { + return aClass.getQualifiedName(); + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirMacro.java new file mode 100644 index 00000000000..f1705ea75bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirMacro.java @@ -0,0 +1,29 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.vfs.VirtualFile; + +public final class FileDirMacro extends Macro { + public String getName() { + return "FileDir"; + } + + public String getDescription() { + return "File directory"; + } + + public String expand(DataContext dataContext) { + //Project project = (Project)dataContext.getData(DataConstants.PROJECT); + //if (project == null) return null; + //VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + //if (file == null) return null; + //if (!file.isDirectory()) { + // file = file.getParent(); + // if (file == null) return null; + //} + VirtualFile dir = DataAccessor.VIRTUAL_DIR_OR_PARENT.from(dataContext); + if (dir == null) return null; + return getPath(dir); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java new file mode 100644 index 00000000000..99c7718d4c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java @@ -0,0 +1,34 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; + +public class FileDirRelativeToProjectRootMacro extends Macro { + public String getName() { + return "FileDirRelativeToProjectRoot"; + } + + public String getDescription() { + return "File dir relative to the project root the file belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + if (!file.isDirectory()) { + file = file.getParent(); + if (file == null) return null; + } + + final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(file); + if (contentRoot == null) return null; + return FileUtil.getRelativePath(getIOFile(contentRoot), getIOFile(file)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro2.java new file mode 100644 index 00000000000..d25e4bbed9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FileDirRelativeToProjectRootMacro2 extends FileDirRelativeToProjectRootMacro { + public String getName() { + return "/FileDirRelativeToProjectRoot"; + } + + public String getDescription() { + return "File dir relative to the project root the file belongs to (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java new file mode 100644 index 00000000000..6a76afa32d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java @@ -0,0 +1,33 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; + +public class FileDirRelativeToSourcepathMacro extends Macro { + public String getName() { + return "FileDirRelativeToSourcepath"; + } + + public String getDescription() { + return "File dir relative to the sourcepath the file belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + if (!file.isDirectory()) { + file = file.getParent(); + if (file == null) return null; + } + final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); + if (sourceRoot == null) return null; + return FileUtil.getRelativePath(getIOFile(sourceRoot), getIOFile(file)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro2.java new file mode 100644 index 00000000000..2eb71a1359a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FileDirRelativeToSourcepathMacro2 extends FileDirRelativeToSourcepathMacro { + public String getName() { + return "/FileDirRelativeToSourcepath"; + } + + public String getDescription() { + return "File dir relative to the sourcepath the file belongs to (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileExtMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileExtMacro.java new file mode 100644 index 00000000000..b207dc64634 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileExtMacro.java @@ -0,0 +1,22 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.vfs.VirtualFile; + +public final class FileExtMacro extends Macro { + public String getName() { + return "FileExt"; + } + + public String getDescription() { + return "File extension"; + } + + public String expand(DataContext dataContext) { + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null ) return null; + return file.getExtension(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileFQPackage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileFQPackage.java new file mode 100644 index 00000000000..e2418140547 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileFQPackage.java @@ -0,0 +1,20 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiPackage; + +public class FileFQPackage extends Macro { + public String expand(DataContext dataContext) throws Macro.ExecutionCancelledException { + PsiPackage aPackage = DataAccessor.FILE_PACKAGE.from(dataContext); + if (aPackage == null) return null; + return aPackage.getQualifiedName(); + } + + public String getDescription() { + return "File fully qualified package"; + } + + public String getName() { + return "FileFQPackage"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameMacro.java new file mode 100644 index 00000000000..1156e10490c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameMacro.java @@ -0,0 +1,22 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.vfs.VirtualFile; + +public class FileNameMacro extends Macro { + public String getName() { + return "FileName"; + } + + public String getDescription() { + return "File name"; + } + + public String expand(DataContext dataContext) { + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + return file.getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameWithoutExtension.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameWithoutExtension.java new file mode 100644 index 00000000000..37b506541fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileNameWithoutExtension.java @@ -0,0 +1,22 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.vfs.VirtualFile; + + +public final class FileNameWithoutExtension extends FileNameMacro { + public String getName() { + return "FileNameWithoutExtension"; + } + + public String getDescription() { + return "File name without extension"; + } + + public String expand(DataContext dataContext) { + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + return file.getNameWithoutExtension(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePackageMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePackageMacro.java new file mode 100644 index 00000000000..bce52696bba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePackageMacro.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiPackage; + +public final class FilePackageMacro extends Macro { + public String getName() { + return "FilePackage"; + } + + public String getDescription() { + return "File package"; + } + + public String expand(DataContext dataContext) { + PsiPackage aPackage = DataAccessor.FILE_PACKAGE.from(dataContext); + if (aPackage == null) return null; + return aPackage.getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathMacro.java new file mode 100644 index 00000000000..b3dc4c0a29c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathMacro.java @@ -0,0 +1,22 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.vfs.VirtualFile; + +public final class FilePathMacro extends Macro { + public String getName() { + return "FilePath"; + } + + public String getDescription() { + return "File path"; + } + + public String expand(DataContext dataContext) { + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + return getPath(file); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java new file mode 100644 index 00000000000..b832ac6a678 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java @@ -0,0 +1,29 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; + +public class FilePathRelativeToProjectRootMacro extends Macro { + public String getName() { + return "FilePathRelativeToProjectRoot"; + } + + public String getDescription() { + return "File path relative to the project root the file belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(file); + if (contentRoot == null) return null; + return FileUtil.getRelativePath(getIOFile(contentRoot), getIOFile(file)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro2.java new file mode 100644 index 00000000000..8e7320ea7c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FilePathRelativeToProjectRootMacro2 extends FilePathRelativeToProjectRootMacro { + public String getName() { + return "/FilePathRelativeToProjectRoot"; + } + + public String getDescription() { + return "File path relative to the project root the file belongs to (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java new file mode 100644 index 00000000000..f79271c81aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java @@ -0,0 +1,29 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; + +public class FilePathRelativeToSourcepathMacro extends Macro { + public String getName() { + return "FilePathRelativeToSourcepath"; + } + + public String getDescription() { + return "File path relative to the sourcepath the file belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); + if (sourceRoot == null) return null; + return FileUtil.getRelativePath(getIOFile(sourceRoot), getIOFile(file)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro2.java new file mode 100644 index 00000000000..299ab9b004d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FilePathRelativeToSourcepathMacro2 extends FilePathRelativeToSourcepathMacro { + public String getName() { + return "/FilePathRelativeToSourcepath"; + } + + public String getDescription() { + return "File path relative to the sourcepath the file belongs to (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro.java new file mode 100644 index 00000000000..e427450072c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro.java @@ -0,0 +1,35 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VfsUtil; + +import java.io.File; + +public class FileRelativeDirMacro extends Macro { + public String getName() { + return "FileRelativeDir"; + } + + public String getDescription() { + return "File directory relative to the project file"; + } + + public String expand(DataContext dataContext) { + //Project project = (Project)dataContext.getData(DataConstants.PROJECT); + //if (project == null) return null; + //VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + //if (file == null) return null; + //if (!file.isDirectory()){ + // file = file.getParent(); + // if (file == null) return null; + //} + String path = DataAccessor.PROJECT_FILE_PATH.from(dataContext); + if (path == null) return null; + VirtualFile dir = DataAccessor.VIRTUAL_DIR_OR_PARENT.from(dataContext); + if (dir == null) return null; + return FileUtil.getRelativePath(new File(path), VfsUtil.virtualToIoFile(dir)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro2.java new file mode 100644 index 00000000000..4100dc3a124 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativeDirMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FileRelativeDirMacro2 extends FileRelativeDirMacro { + public String getName() { + return "/FileRelativeDir"; + } + + public String getDescription() { + return "File directory relative to the project file (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro.java new file mode 100644 index 00000000000..59d6c446774 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro.java @@ -0,0 +1,27 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VfsUtil; + +import java.io.File; + +public class FileRelativePathMacro extends Macro { + public String getName() { + return "FileRelativePath"; + } + + public String getDescription() { + return "File path relative to the project file"; + } + + public String expand(DataContext dataContext) { + String path = DataAccessor.PROJECT_FILE_PATH.from(dataContext); + if (path == null) return null; + VirtualFile file = DataAccessor.VIRTUAL_FILE.from(dataContext); + if (file == null) return null; + return FileUtil.getRelativePath(new File(path), VfsUtil.virtualToIoFile(file)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro2.java new file mode 100644 index 00000000000..e1f2c8a7246 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/FileRelativePathMacro2.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +import java.io.File; + +public final class FileRelativePathMacro2 extends FileRelativePathMacro { + public String getName() { + return "/FileRelativePath"; + } + + public String getDescription() { + return "File path relative to the project file (with forward slashes)"; + } + + public String expand(DataContext dataContext) { + String s = super.expand(dataContext); + return s != null ? s.replace(File.separatorChar, '/') : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JavaDocPathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JavaDocPathMacro.java new file mode 100644 index 00000000000..bc6a6256fff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JavaDocPathMacro.java @@ -0,0 +1,32 @@ +package com.intellij.ide.macro; + +import com.intellij.javadoc.JavadocConfiguration; +import com.intellij.javadoc.JavadocGenerationManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; + +import java.io.File; + +public final class JavaDocPathMacro extends Macro { + public String getName() { + return "JavaDocPath"; + } + + public String getDescription() { + return "JavaDoc output directory"; + } + + public String expand(DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + JavadocGenerationManager manager = project.getComponent(JavadocGenerationManager.class); + if (manager == null) { + return null; + } + final JavadocConfiguration configuration = manager.getConfiguration(); + return configuration.OUTPUT_DIRECTORY == null ? null : configuration.OUTPUT_DIRECTORY.replace('/', File.separatorChar); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JdkPathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JdkPathMacro.java new file mode 100644 index 00000000000..100a8716ec6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/JdkPathMacro.java @@ -0,0 +1,37 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ex.PathUtilEx; +import com.intellij.util.PathUtil; + +import java.io.File; + +public final class JdkPathMacro extends Macro { + public String getName() { + return "JDKPath"; + } + + public String getDescription() { + return "JDK path"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + final ProjectJdk anyJdk = PathUtilEx.getAnyJdk(project); + if (anyJdk == null) { + return null; + } + String jdkHomePath = PathUtil.getLocalPath(anyJdk.getHomeDirectory()); + if (jdkHomePath != null) { + jdkHomePath = jdkHomePath.replace('/', File.separatorChar); + } + return jdkHomePath; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/LineNumberMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/LineNumberMacro.java new file mode 100644 index 00000000000..e0d34f16d28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/LineNumberMacro.java @@ -0,0 +1,29 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowManager; + +public final class LineNumberMacro extends Macro { + public String getName() { + return "LineNumber"; + } + + public String getDescription() { + return "Line number"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + if (ToolWindowManager.getInstance(project).isEditorComponentActive()){ + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null){ + return String.valueOf(editor.getCaretModel().getLogicalPosition().line + 1); + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/Macro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/Macro.java new file mode 100644 index 00000000000..68b79079f75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/Macro.java @@ -0,0 +1,64 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; + +public abstract class Macro { + public static final class ExecutionCancelledException extends Exception { + } + + protected String myCachedPreview; + + public abstract String getName(); + public abstract String getDescription(); + public abstract String expand(DataContext dataContext) throws ExecutionCancelledException; + + public void cachePreview(DataContext dataContext) { + try{ + myCachedPreview = expand(dataContext); + } + catch(ExecutionCancelledException e){ + myCachedPreview = ""; + } + } + + public final String preview() { + return myCachedPreview; + } + + /** + * @return never null + */ + static String getPath(VirtualFile file) { + return file.getPath().replace('/', File.separatorChar); + } + + static File getIOFile(VirtualFile file) { + return new File(getPath(file)); + } + + public static class Silent extends Macro { + private final Macro myDelegate; + private final String myValue; + + public Silent(Macro delegate, String value) { + myDelegate = delegate; + myValue = value; + } + + public String expand(DataContext dataContext) throws ExecutionCancelledException { + return myValue; + } + + public String getDescription() { + return myDelegate.getDescription(); + } + + public String getName() { + return myDelegate.getName(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacroManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacroManager.java new file mode 100644 index 00000000000..e4e1954abf7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacroManager.java @@ -0,0 +1,142 @@ + +package com.intellij.ide.macro; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ConvertingIterator; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.HashMap; + +import java.io.File; +import java.util.Iterator; + +public final class MacroManager implements ApplicationComponent { + private final HashMap myMacrosMap = new HashMap(); + + public static MacroManager getInstance() { + return ApplicationManager.getApplication().getComponent(MacroManager.class); + } + + private MacroManager() { + registerMacro(new ClasspathMacro()); + registerMacro(new SourcepathMacro()); + registerMacro(new FileDirMacro()); + registerMacro(new FileExtMacro()); + registerMacro(new FileNameMacro()); + registerMacro(new FileNameWithoutExtension()); + registerMacro(new FilePackageMacro()); + registerMacro(new FileFQPackage()); + registerMacro(new FileClassMacro()); + registerMacro(new FilePathMacro()); + registerMacro(new FileDirRelativeToProjectRootMacro()); + registerMacro(new FilePathRelativeToProjectRootMacro()); + registerMacro(new FileDirRelativeToSourcepathMacro()); + registerMacro(new FilePathRelativeToSourcepathMacro()); + registerMacro(new JdkPathMacro()); + registerMacro(new OutputPathMacro()); + registerMacro(new PromptMacro()); + registerMacro(new SourcepathEntryMacro()); + registerMacro(new ClasspathEntryMacro()); + registerMacro(new ProjectFilePathMacro()); + registerMacro(new ProjectFileDirMacro()); + registerMacro(new ProjectNameMacro()); + registerMacro(new ProjectPathMacro()); + registerMacro(new FileRelativePathMacro()); + registerMacro(new FileRelativeDirMacro()); + registerMacro(new JavaDocPathMacro()); + registerMacro(new LineNumberMacro()); + registerMacro(new ColumnNumberMacro()); + if (File.separatorChar != '/') { + registerMacro(new FileDirRelativeToProjectRootMacro2()); + registerMacro(new FilePathRelativeToProjectRootMacro2()); + registerMacro(new FileDirRelativeToSourcepathMacro2()); + registerMacro(new FilePathRelativeToSourcepathMacro2()); + registerMacro(new FileRelativeDirMacro2()); + registerMacro(new FileRelativePathMacro2()); + } + } + + public void disposeComponent() { + } + + public void initComponent() { } + + private void registerMacro(Macro macro) { + myMacrosMap.put(macro.getName(), macro); + } + + public Iterator getMacros() { + return myMacrosMap.values().iterator(); + } + + public void cacheMacrosPreview(DataContext dataContext) { + dataContext = getCorrectContext(dataContext); + Iterator macros = getMacros(); + while (macros.hasNext()) { + Macro macro = macros.next(); + macro.cachePreview(dataContext); + } + } + + private DataContext getCorrectContext(DataContext dataContext) { + if (dataContext.getData(DataConstants.FILE_EDITOR) != null) return dataContext; + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return dataContext; + FileEditorManager editorManager = FileEditorManager.getInstance(project); + VirtualFile[] files = editorManager.getSelectedFiles(); + if (files.length == 0) return dataContext; + FileEditor fileEditor = editorManager.getSelectedEditor(files[0]); + return fileEditor == null ? dataContext : + DataManager.getInstance().getDataContext(fileEditor.getComponent()); + } + + /** + * Expands all macros that are found in the str. + */ + public String expandMacrosInString(String str, boolean firstQueueExpand, DataContext dataContext) throws Macro.ExecutionCancelledException { + return expandMacroSet(str, firstQueueExpand, dataContext, getMacros()); + } + + private String expandMacroSet(String str, + boolean firstQueueExpand, DataContext dataContext, Iterator macros + ) throws Macro.ExecutionCancelledException { + if (str == null) return null; + while (macros.hasNext()) { + Macro macro = macros.next(); + if (macro instanceof SecondQueueExpandMacro && firstQueueExpand) continue; + String name = "$" + macro.getName() + "$"; + if (str.indexOf(name) >= 0) { + String expanded = macro.expand(dataContext); + if (expanded == null) { + expanded = ""; + } + str = StringUtil.replace(str, name, expanded); + } + } + return str; + } + + public String expandSilentMarcos(String str, boolean firstQueueExpand, DataContext dataContext) throws Macro.ExecutionCancelledException { + return expandMacroSet(str, firstQueueExpand, dataContext, + ConvertingIterator.create(getMacros(), new Convertor() { + public Macro convert(Macro macro) { + if (macro instanceof PromptMacro) + return new Macro.Silent(macro, ""); + return macro; + } + })); + } + + public String getComponentName() { + return "MacroManager"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacrosDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacrosDialog.java new file mode 100644 index 00000000000..41074cfdf8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/MacrosDialog.java @@ -0,0 +1,208 @@ +package com.intellij.ide.macro; + +import com.intellij.ant.impl.MapDataContext; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.CollectUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +public final class MacrosDialog extends DialogWrapper { + private final DefaultListModel myMacrosModel; + private final JList myMacrosList; + private final JTextArea myPreviewTextarea; + + public MacrosDialog(Project project) { + super(project, true); + MacroManager.getInstance().cacheMacrosPreview(MapDataContext.singleData(DataConstants.PROJECT, project)); + setTitle("Macros"); + setOKButtonText("Insert"); + + myMacrosModel = new DefaultListModel(); + myMacrosList = new JList(myMacrosModel); + myPreviewTextarea = new JTextArea(); + + init(); + } + + public MacrosDialog(Component parent) { + super(parent, true); + MacroManager.getInstance().cacheMacrosPreview(DataManager.getInstance().getDataContext(parent)); + setTitle("Macros"); + setOKButtonText("Insert"); + + myMacrosModel = new DefaultListModel(); + myMacrosList = new JList(myMacrosModel); + myPreviewTextarea = new JTextArea(); + + init(); + } + + protected void init() { + super.init(); + + ArrayList macros = CollectUtil.COLLECT.toList(MacroManager.getInstance().getMacros()); + Collections.sort(macros, new Comparator() { + public int compare(Object o1, Object o2) { + String name1 = ((Macro)o1).getName(); + String name2 = ((Macro)o2).getName(); + if (!StringUtil.startsWithChar(name1, '/')) { + name1 = ZERO + name1; + } + if (!StringUtil.startsWithChar(name2, '/')) { + name2 = ZERO + name2; + } + return name1.compareToIgnoreCase(name2); + } + private final String ZERO = new String(new char[] {0}); + }); + for (Iterator iterator = macros.iterator(); iterator.hasNext();) { + Macro macro = iterator.next(); + myMacrosModel.addElement(new MacroWrapper(macro)); + } + + addListeners(); + if (myMacrosModel.size() > 0){ + myMacrosList.setSelectedIndex(0); + } + else{ + setOKActionEnabled(false); + } + } + + protected Action[] createActions() { + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("preferences.externalToolsMacro"); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.ide.macro.MacrosDialog"; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints constr; + + // list label + constr = new GridBagConstraints(); + constr.gridy = 0; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 5, 0, 5); + panel.add(new JLabel("Macros:"), constr); + + // macros list + constr = new GridBagConstraints(); + constr.gridy = 1; + constr.weightx = 1; + constr.weighty = 1; + constr.insets = new Insets(0, 5, 0, 5); + constr.fill = GridBagConstraints.BOTH; + constr.anchor = GridBagConstraints.WEST; + panel.add(new JScrollPane(myMacrosList), constr); + myMacrosList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myMacrosList.setPreferredSize(null); + + // preview label + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 2; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 5, 0, 5); + panel.add(new JLabel("Macro preview:"), constr); + + // preview + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 3; + constr.weightx = 1; + constr.weighty = 1; + constr.fill = GridBagConstraints.BOTH; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(0, 5, 5, 5); + panel.add(new JScrollPane(myPreviewTextarea), constr); + myPreviewTextarea.setEditable(false); + myPreviewTextarea.setLineWrap(true); + myPreviewTextarea.setPreferredSize(null); + + panel.setPreferredSize(new Dimension(400, 500)); + + return panel; + } + + protected JComponent createNorthPanel() { + return null; + } + + /** + * Macro info shown in list + */ + private static final class MacroWrapper { + private final Macro myMacro; + + public MacroWrapper(Macro macro) { + myMacro = macro; + } + + public String toString() { + return myMacro.getName() + " - " + myMacro.getDescription(); + } + } + + private void addListeners() { + myMacrosList.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + Macro macro = getSelectedMacro(); + if (macro == null){ + myPreviewTextarea.setText(""); + setOKActionEnabled(false); + } + else{ + myPreviewTextarea.setText(macro.preview()); + setOKActionEnabled(true); + } + } + } + ); + + // doubleclick support + myMacrosList.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if ((e.getClickCount() == 2) && (getSelectedMacro() != null)){ + close(OK_EXIT_CODE); + } + } + } + ); + + } + + public Macro getSelectedMacro() { + MacroWrapper macroWrapper = (MacroWrapper)myMacrosList.getSelectedValue(); + if (macroWrapper != null){ + return macroWrapper.myMacro; + } + return null; + } + + public JComponent getPreferredFocusedComponent() { + return myMacrosList; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/OutputPathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/OutputPathMacro.java new file mode 100644 index 00000000000..81be71433f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/OutputPathMacro.java @@ -0,0 +1,60 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.io.File; + +public final class OutputPathMacro extends Macro { + public String getName() { + return "OutputPath"; + } + + public String getDescription() { + return "Output path"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + + VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + if (file != null) { + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + Module module = projectFileIndex.getModuleForFile(file); + if (module != null){ + boolean isTest = projectFileIndex.isInTestSourceContent(file); + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + String outputPathUrl = isTest ? moduleRootManager.getCompilerOutputPathForTestsUrl() : moduleRootManager.getCompilerOutputPathUrl(); + if (outputPathUrl == null) return null; + return VirtualFileManager.extractPath(outputPathUrl).replace('/', File.separatorChar); + } + } + + Module[] allModules = ModuleManager.getInstance(project).getSortedModules(); + if (allModules.length == 0) { + return null; + } + String[] paths = CompilerPathsEx.getOutputPaths(allModules); + final StringBuffer outputPath = new StringBuffer(); + for (int idx = 0; idx < paths.length; idx++) { + String path = paths[idx]; + if (idx > 0) { + outputPath.append(File.pathSeparator); + } + outputPath.append(path); + } + return outputPath.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFileDirMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFileDirMacro.java new file mode 100644 index 00000000000..378e539edbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFileDirMacro.java @@ -0,0 +1,29 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; + +public final class ProjectFileDirMacro extends Macro { + public String getName() { + return "ProjectFileDir"; + } + + public String getDescription() { + return "The directory of the project file"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile projectFile = project.getProjectFile(); + if (projectFile == null) { + return null; + } + VirtualFile dir = projectFile.getParent(); + return dir.getPath().replace('/',File.separatorChar); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFilePathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFilePathMacro.java new file mode 100644 index 00000000000..7e4a712e133 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectFilePathMacro.java @@ -0,0 +1,17 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; + +public final class ProjectFilePathMacro extends Macro { + public String getName() { + return "ProjectFilePath"; + } + + public String getDescription() { + return "The path of the project file"; + } + + public String expand(DataContext dataContext) { + return DataAccessor.PROJECT_FILE_PATH.from(dataContext); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectNameMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectNameMacro.java new file mode 100644 index 00000000000..fc493b0c4a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectNameMacro.java @@ -0,0 +1,28 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; + +import java.io.File; + +public final class ProjectNameMacro extends Macro { + public String getName() { + return "ProjectName"; + } + + public String getDescription() { + return "The name of the project file without extension"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + String path = project.getProjectFilePath(); + File file = new File(path); + if (!file.exists() || !file.isFile()) return null; + String name = file.getName(); + int index = name.lastIndexOf('.'); + return index >= 0 ? name.substring(0, index) : name; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectPathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectPathMacro.java new file mode 100644 index 00000000000..c8d937aaa99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/ProjectPathMacro.java @@ -0,0 +1,23 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; + +public final class ProjectPathMacro extends Macro { + public String getName() { + return "Projectpath"; + } + + public String getDescription() { + return "Project paths"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + return ProjectRootsTraversing.collectRoots(project, ProjectRootsTraversing.PROJECT_SOURCES).getPathsString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/PromptMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/PromptMacro.java new file mode 100644 index 00000000000..4d608522fa5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/PromptMacro.java @@ -0,0 +1,24 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.ui.Messages; + +public final class PromptMacro extends Macro implements SecondQueueExpandMacro { + public String getName() { + return "Prompt"; + } + + public String getDescription() { + return "Displays a string input dialog"; + } + + public String expand(DataContext dataContext) throws ExecutionCancelledException { + String userInput = Messages.showInputDialog("Enter parameters:", "Input", Messages.getQuestionIcon()); + if (userInput == null) throw new ExecutionCancelledException(); + return userInput; + } + + public void cachePreview(DataContext dataContext) { + myCachedPreview = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SecondQueueExpandMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SecondQueueExpandMacro.java new file mode 100644 index 00000000000..ae2a6c8574c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SecondQueueExpandMacro.java @@ -0,0 +1,4 @@ +package com.intellij.ide.macro; + +public interface SecondQueueExpandMacro { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathEntryMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathEntryMacro.java new file mode 100644 index 00000000000..8dd6dcc9c0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathEntryMacro.java @@ -0,0 +1,31 @@ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Eugene Belyaev + */ +public final class SourcepathEntryMacro extends Macro { + public String getName() { + return "SourcepathEntry"; + } + + public String getDescription() { + return "Entry in the sourcepath the element belongs to"; + } + + public String expand(final DataContext dataContext) { + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); + if (file == null) return null; + final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); + if (sourceRoot == null) return null; + return getPath(sourceRoot); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathMacro.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathMacro.java new file mode 100644 index 00000000000..5ddf9995120 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/macro/SourcepathMacro.java @@ -0,0 +1,23 @@ + +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; + +public final class SourcepathMacro extends Macro { + public String getName() { + return "Sourcepath"; + } + + public String getDescription() { + return "Project's sourcepath"; + } + + public String expand(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + return ProjectRootsTraversing.collectRoots(project, ProjectRootsTraversing.PROJECT_SOURCES).getPathsString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/AvailablePluginsTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/AvailablePluginsTableModel.java new file mode 100644 index 00000000000..e54a86425b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/AvailablePluginsTableModel.java @@ -0,0 +1,44 @@ +package com.intellij.ide.plugins; + +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 10, 2003 + * Time: 7:26:23 PM + * To change this template use Options | File Templates. + */ +public class AvailablePluginsTableModel extends PluginTableModel { + public static final int COLUMN_COUNT = PluginManagerColumnInfo.COLUMNS.length; + + public AvailablePluginsTableModel(CategoryNode root, SortableProvider sortableProvider) { + super (new PluginManagerColumnInfo [] { + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_NAME, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_STATUS, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_INSTALLED_VERSION, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_VERSION, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DATE, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_SIZE, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_DOWNLOADS, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_CATEGORY, sortableProvider) + }, sortableProvider); + + view = new ArrayList(); + makeView (root); + + sortByColumn(sortableProvider.getSortColumn()); + } + + private void makeView(CategoryNode start) { + if (start.getPlugins() != null && start.getPlugins().size() > 0) { + view.addAll(start.getPlugins()); + } + + if (start.getChildren() != null && start.getChildren().size() > 0) + for (int i = 0; i < start.getChildren().size(); i++) { + CategoryNode categoryNode = start.getChildren().get(i); + makeView(categoryNode); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/InstalledPluginsTableModel.java new file mode 100644 index 00000000000..973ab4e8f27 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -0,0 +1,23 @@ +package com.intellij.ide.plugins; + +import java.util.Arrays; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 26, 2003 + * Time: 3:51:58 PM + * To change this template use Options | File Templates. + */ +public class InstalledPluginsTableModel extends PluginTableModel { + public InstalledPluginsTableModel(SortableProvider sortableProvider) { + super(new PluginManagerColumnInfo [] { + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_NAME, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_VERSION, sortableProvider), + new PluginManagerColumnInfo(PluginManagerColumnInfo.COLUMN_STATE, sortableProvider) + }, sortableProvider); + + view = Arrays.asList(PluginManager.getPlugins()); + sortByColumn(sortableProvider.getSortColumn()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginDescriptorComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginDescriptorComparator.java new file mode 100644 index 00000000000..96660f2774e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginDescriptorComparator.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.plugins; + +import com.intellij.util.containers.HashMap; +import gnu.trove.TObjectIntHashMap; + +import java.util.Comparator; +import java.util.Map; +import java.util.Stack; + +/** + * @author Eugene Zhuravlev + * Date: Aug 3, 2004 + */ +public class PluginDescriptorComparator implements Comparator{ + private final TObjectIntHashMap myIdToNumberMap = new TObjectIntHashMap(); + private int myAvailableNumber = 0; + + public PluginDescriptorComparator(PluginDescriptor[] descriptors) throws Exception{ + final Map idToDescriptorMap = new HashMap(); + for (int idx = 0; idx < descriptors.length; idx++) { + final PluginDescriptor descriptor = descriptors[idx]; + idToDescriptorMap.put(descriptor.getId(), descriptor); + } + final Stack visited = new Stack(); + for (int idx = 0; idx < descriptors.length && myIdToNumberMap.size() != descriptors.length; idx++) { + assignNumbers(descriptors[idx].getId(), idToDescriptorMap, visited); + visited.clear(); + } + } + + private void assignNumbers(String id, Map idToDescriptorMap, Stack visited) throws Exception { + visited.push(id); + try { + final String[] parentIds = idToDescriptorMap.get(id).getDependentPluginIds(); + for (int idx = 0; idx < parentIds.length; idx++) { + final String parentId = parentIds[idx]; + if (visited.contains(parentId)) { + throw new Exception("Plugins should not have cyclic dependencies:\n" + id + "->" + parentId + "->...->" + id ); + } + } + for (int idx = 0; idx < parentIds.length; idx++) { + assignNumbers(parentIds[idx], idToDescriptorMap, visited); + } + if (!myIdToNumberMap.contains(id)) { + myIdToNumberMap.put(id, myAvailableNumber++); + } + } + finally { + visited.pop(); + } + } + + public int compare(PluginDescriptor d1, PluginDescriptor d2) { + return myIdToNumberMap.get(d1.getId()) - myIdToNumberMap.get(d2.getId()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginInstaller.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginInstaller.java new file mode 100644 index 00000000000..04095fac8e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginInstaller.java @@ -0,0 +1,174 @@ +package com.intellij.ide.plugins; + +import com.intellij.ide.startup.StartupActionScriptManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.util.io.ZipUtil; + +import javax.swing.*; +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Nov 29, 2003 + * Time: 9:15:30 PM + * To change this template use Options | File Templates. + */ +public class PluginInstaller { + private static final Object lock = new Object(); + + public static boolean prepareToInstall (List plugins) { + ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + + long total = 0; + for (int i = 0; i < plugins.size(); i++) { + PluginNode pluginNode = plugins.get(i); + total += Long.valueOf(pluginNode.getSize()).longValue(); + } + + long count = 0; + boolean result = false; + + for (int i = 0; i < plugins.size(); i++) { + PluginNode pluginNode = plugins.get(i); + pi.setText(pluginNode.getName()); + + try { + result |= prepareToInstall(pluginNode, true, count, total); + } catch (IOException e) { + throw new RuntimeException (e); + } + count += Integer.valueOf(pluginNode.getSize()).intValue(); + } + return result; + } + + public static boolean prepareToInstall (PluginNode pluginNode, boolean packet, long count, long available) throws IOException { + // check for dependent plugins at first. + if (pluginNode.getDepends() != null && pluginNode.getDepends().size() > 0) { + // prepare plugins list for install + + List depends = new ArrayList (); + for (int i = 0; i < pluginNode.getDepends().size(); i++) { + String depPluginName = pluginNode.getDepends().get(i); + + if (PluginManager.isPluginInstalled(depPluginName)) + // ignore installed plugins + continue; + + PluginNode depPlugin = new PluginNode(depPluginName); + depPlugin.setSize("-1"); + + depends.add(depPlugin); + + } + + if (! prepareToInstall(depends)) + return false; + } + + synchronized (lock) { + if (PluginManager.isPluginInstalled(pluginNode.getName())) { + // add command to delete the 'action script' file + PluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginNode.getName()); + + StartupActionScriptManager.ActionCommand deleteOld = new StartupActionScriptManager.DeleteCommand(pluginDescriptor.getPath()); + StartupActionScriptManager.addActionCommand(deleteOld); + } + // download plugin + File file = RepositoryHelper.downloadPlugin(pluginNode, packet, count, available); + if (file == null) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Plugin " + pluginNode.getName() + " was not installed."); + return false; + } + + if (file.getName().endsWith(".jar")) { + // add command to copy file to the IDEA/plugins path + StartupActionScriptManager.ActionCommand copyPlugin = new StartupActionScriptManager.CopyCommand(file, + new File (PathManager.getPluginsPath() + + File.separator + file.getName())); + StartupActionScriptManager.addActionCommand(copyPlugin); + } else { + // add command to unzip file to the IDEA/plugins path + String unzipPath; + if (ZipUtil.isZipContainsFolder(file)) + unzipPath = PathManager.getPluginsPath(); + else + unzipPath = PathManager.getPluginsPath() + File.separator + pluginNode.getName(); + + StartupActionScriptManager.ActionCommand unzip = new StartupActionScriptManager.UnzipCommand(file, new File (unzipPath)); + StartupActionScriptManager.addActionCommand(unzip); + } + + // add command to remove temp plugin file + StartupActionScriptManager.ActionCommand deleteTemp = new StartupActionScriptManager.DeleteCommand(file); + StartupActionScriptManager.addActionCommand(deleteTemp); + + pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED); + } + + return true; + } + /** + * Install plugin into a temp direcotry + * Append 'action script' file with installing actions + * + * @param pluginNode Plugin to install + */ + public static boolean prepareToInstall (PluginNode pluginNode) throws IOException { + return prepareToInstall(pluginNode, false, 0, 0); + } + + public static void prepareToUninstall (String pluginName) throws IOException { + synchronized (lock) { + if (PluginManager.isPluginInstalled(pluginName)) { + // add command to delete the 'action script' file + PluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginName); + + StartupActionScriptManager.ActionCommand deleteOld = new StartupActionScriptManager.DeleteCommand(pluginDescriptor.getPath()); + StartupActionScriptManager.addActionCommand(deleteOld); + } + } + } + + public static void initPluginClasses () { + synchronized(lock) { + File file = new File (getPluginClassesPath()); + if (file.exists()) + file.delete(); + } + } + + private static String getPluginClassesPath() { + return PathManagerEx.getPluginTempPath() + File.separator + "plugin.classes"; + } + + public static Map loadPluginClasses () throws IOException, ClassNotFoundException { + synchronized(lock) { + File file = new File (getPluginClassesPath()); + if (file.exists()) { + ObjectInputStream ois = new ObjectInputStream (new FileInputStream (file)); + return (Map)ois.readObject(); + } else { + return new HashMap (); + } + } + } + + public static void savePluginClasses (Map classes) throws IOException { + synchronized(lock) { + File file = new File (getPluginClassesPath()); + + ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream(file, false)); + oos.writeObject(classes); + oos.close(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManager.java new file mode 100644 index 00000000000..1fa2a9fd9bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManager.java @@ -0,0 +1,584 @@ +package com.intellij.ide.plugins; + +import com.intellij.ide.plugins.cl.IdeaClassLoader; +import com.intellij.ide.plugins.cl.PluginClassLoader; +import com.intellij.ide.startup.StartupActionScriptManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; +import com.intellij.util.text.StringTokenizer; +import org.jdom.Element; +import sun.reflect.Reflection; + +import javax.swing.*; +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * @author mike + */ +public class PluginManager { + //Logger is lasy-initialized in order not to use it outside the appClassLoader + private static Logger ourLogger = null; + + private static Logger getLogger() { + if (ourLogger == null) { + ourLogger = Logger.getInstance("#com.intellij.ide.plugins.PluginManager"); + } + return ourLogger; + } + + private static String[] ourArguments; + private static String ourMainClass; + private static String ourMethodName; + + private static PluginDescriptor[] ourPlugins; + private static Map ourPluginClasses; + private static final String TOOLS_JAR = "tools.jar"; + private static final String EXTENSIONS_DIR = "ext"; + + + public PluginManager() { + } + + public static void main(final String[] args, final String mainClass, final String methodName) { + main(args, mainClass, methodName, new ArrayList()); + } + + public static void main(final String[] args, final String mainClass, final String methodName, List classpathElements) { + ourArguments = args; + ourMainClass = mainClass; + ourMethodName = methodName; + + final PluginManager pluginManager = new PluginManager(); + pluginManager.bootstrap(classpathElements); + } + + /** + * do not call this method during bootstrap, should be called in a copy of PluginManager, loaded by IdeaClassLoader + */ + public static PluginDescriptor[] getPlugins() { + if (ourPlugins == null) { + final PluginDescriptor[] pluginDescriptors = loadDescriptors(); + + final Map idToDescriptorMap = new HashMap(); + for (int idx = 0; idx < pluginDescriptors.length; idx++) { + final PluginDescriptor descriptor = pluginDescriptors[idx]; + idToDescriptorMap.put(descriptor.getId(), descriptor); + } + // sort descriptors according to plugin dependencies + Arrays.sort(pluginDescriptors, getPluginDescriptorComparator(idToDescriptorMap)); + + final Class callerClass = Reflection.getCallerClass(1); + final ClassLoader parentLoader = callerClass.getClassLoader(); + for (int idx = 0; idx < pluginDescriptors.length; idx++) { + final PluginDescriptor pluginDescriptor = pluginDescriptors[idx]; + final List classPath = pluginDescriptor.getClassPath(); + final String[] dependentPluginIds = pluginDescriptor.getDependentPluginIds(); + final ClassLoader[] parentLoaders = dependentPluginIds.length > 0? getParentLoaders(idToDescriptorMap, dependentPluginIds): new ClassLoader[] {parentLoader}; + final PluginClassLoader pluginClassLoader = createPluginClassLoader((File[])classPath.toArray(new File[classPath.size()]), pluginDescriptor.getName(), parentLoaders, pluginDescriptor.getPath()); + pluginDescriptor.setLoader(pluginClassLoader); + } + ourPlugins = pluginDescriptors; + } + return ourPlugins; + } + + private static Comparator getPluginDescriptorComparator(Map idToDescriptorMap) { + final Graph graph = createPluginIdGraph(idToDescriptorMap); + final DFSTBuilder builder = new DFSTBuilder(graph); + /* + if (!builder.isAcyclic()) { + final Pair circularDependency = builder.getCircularDependency(); + throw new Exception("Cyclic dependencies between plugins are not allowed: \"" + circularDependency.getFirst() + "\" and \"" + circularDependency.getSecond() + ""); + } + */ + final Comparator idComparator = builder.comparator(); + return new Comparator() { + public int compare(PluginDescriptor o1, PluginDescriptor o2) { + return idComparator.compare(o1.getId(), o2.getId()); + } + }; + } + + private static Graph createPluginIdGraph(final Map idToDescriptorMap) { + final String[] ids = idToDescriptorMap.keySet().toArray(new String[idToDescriptorMap.size()]); + return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return Arrays.asList(ids); + } + + public Iterator getIn(String pluginId) { + final PluginDescriptor descriptor = idToDescriptorMap.get(pluginId); + return Arrays.asList(descriptor.getDependentPluginIds()).iterator(); + } + })); + } + + private static ClassLoader[] getParentLoaders(Map idToDescriptorMap, String[] pluginIds) { + final List classLoaders = new ArrayList(); + for (int idx = 0; idx < pluginIds.length; idx++) { + final String id = pluginIds[idx]; + PluginDescriptor pluginDescriptor = idToDescriptorMap.get(id); + if (pluginDescriptor == null) { + getLogger().assertTrue(false, "Plugin not found: " + id); + } + final PluginClassLoader loader = pluginDescriptor.getLoader(); + if (loader == null) { + getLogger().assertTrue(false, "Plugin class loader should be initialized for plugin " + id); + } + classLoaders.add(loader); + } + return classLoaders.toArray(new ClassLoader[classLoaders.size()]); + } + + /** + * Called via reflection + */ + protected static void start() { + try { + ThreadGroup threadGroup = new ThreadGroup("Idea Thread Group") { + public void uncaughtException(Thread t, Throwable e) { + getLogger().error(e); + } + }; + + Runnable runnable = new Runnable() { + public void run() { + try { + Class aClass = Class.forName(ourMainClass); + final Method method = aClass.getDeclaredMethod(ourMethodName, new Class[]{(ArrayUtil.EMPTY_STRING_ARRAY).getClass()}); + method.setAccessible(true); + + method.invoke(null, new Object[]{ourArguments}); + } + catch (Exception e) { + e.printStackTrace(); + getLogger().error(e); + } + } + }; + + new Thread(threadGroup, runnable, "Idea Main Thread").start(); + } + catch (Exception e) { + getLogger().error(e); + } + } + + private static PluginDescriptor[] loadDescriptors() { + if (isLoadingOfExternalPluginsDisabled()) { + return PluginDescriptor.EMPTY_ARRAY; + } + + final List result = new ArrayList(); + + loadDescriptors(PathManager.getPluginsPath(), result); + loadDescriptors(PathManager.getPreinstalledPluginsPath(), result); + + String errorMessage = filterBadPlugins(result); + + PluginDescriptor[] pluginDescriptors = result.toArray(new PluginDescriptor[result.size()]); + try { + Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors)); + } + catch (Exception e) { + errorMessage = "Error loading plugins:\n" + e.getMessage() + "\nPlugins were not loaded.\nCorrect the above error and restart IDEA."; + pluginDescriptors = PluginDescriptor.EMPTY_ARRAY; + } + if (errorMessage != null) { + JOptionPane.showMessageDialog(null, errorMessage, "Plugin Error", JOptionPane.ERROR_MESSAGE); + } + return pluginDescriptors; + } + + private static String filterBadPlugins(List result) { + final Map idToDescriptorMap = new HashMap(); + final StringBuffer message = new StringBuffer(); + boolean pluginsWithoutIdFound = false; + for (Iterator it = result.iterator(); it.hasNext();) { + final PluginDescriptor descriptor = (PluginDescriptor)it.next(); + String id = descriptor.getId(); + if (id == null || id.length() == 0) { + pluginsWithoutIdFound = true; + it.remove(); + } + else if (idToDescriptorMap.containsKey(id)) { + if (message.length() > 0) { + message.append("\n"); + } + message.append("Duplicate plugin id: "); + message.append(id); + it.remove(); + } + else { + idToDescriptorMap.put(id, descriptor); + } + } + for (Iterator it = result.iterator(); it.hasNext();) { + final PluginDescriptor pluginDescriptor = (PluginDescriptor)it.next(); + final String[] dependentPluginIds = pluginDescriptor.getDependentPluginIds(); + for (int idx = 0; idx < dependentPluginIds.length; idx++) { + final String dependentPluginId = dependentPluginIds[idx]; + if (!idToDescriptorMap.containsKey(dependentPluginId)) { + if (message.length() > 0) { + message.append("\n"); + } + message.append("Plugin \""); + message.append(pluginDescriptor.getId()); + message.append("\" was not loaded: required plugin \""); + message.append(dependentPluginId); + message.append("\" not found."); + it.remove(); + break; + } + } + } + if (pluginsWithoutIdFound) { + if (message.length() > 0) { + message.append("\n"); + } + message.append("There were plugins without id found, all such plugins were skipped."); + } + if (message.length() > 0) { + message.insert(0, "Problems found loading plugins:\n"); + return message.toString(); + } + return null; + } + + private static void loadDescriptors(String pluginsPath, List result) { + final File pluginsHome = new File(pluginsPath); + final File[] files = pluginsHome.listFiles(); + if (files!= null && files.length > 0) { + for (int i = 0; i < files.length; i++) { + final PluginDescriptor descriptor = loadDescriptor(files[i]); + if (descriptor != null && !result.contains(descriptor)) { + result.add(descriptor); + } + } + } + } + + private static PluginDescriptor loadDescriptor(final File file) { + PluginDescriptor descriptor = null; + + if (file.isDirectory()) { + File descriptorFile = new File(file, "META-INF" + File.separator + "plugin.xml"); + if (descriptorFile.exists()) { + descriptor = new PluginDescriptor(file); + + try { + descriptor.readExternal(JDOMUtil.loadDocument(descriptorFile).getRootElement()); + } + catch (Exception e) { + System.err.println("Cannot load: " + descriptorFile.getAbsolutePath()); + e.printStackTrace(); + } + } + else { + File libDir = new File(file, "lib"); + if (!libDir.isDirectory()) { + return null; + } + final File[] files = libDir.listFiles(); + if (files == null || files.length == 0) { + return null; + } + for (int i = 0; i < files.length; i++) { + final File f = files[i]; + if (!f.isFile()) { + continue; + } + final String lowercasedName = f.getName().toLowerCase(); + if (lowercasedName.endsWith(".jar") || lowercasedName.endsWith(".zip")) { + PluginDescriptor descriptor1 = loadDescriptorFromJar(f); + if (descriptor1 != null) { + if (descriptor != null) { + getLogger().info("Cannot load " + file + " because two or more plugin.xml's detected"); + return null; + } + descriptor = descriptor1; + descriptor.setPath(file); + } + } + } + } + } + else if (file.getName().endsWith(".jar")) { + descriptor = loadDescriptorFromJar(file); + } + + return descriptor; + } + + private static PluginDescriptor loadDescriptorFromJar(File file) { + PluginDescriptor descriptor = null; + try { + ZipFile zipFile = new ZipFile(file); + + try { + final ZipEntry entry = zipFile.getEntry("META-INF/plugin.xml"); + if (entry != null) { + descriptor = new PluginDescriptor(file); + + final InputStream inputStream = zipFile.getInputStream(entry); + final Element rootElement = JDOMUtil.loadDocument(inputStream).getRootElement(); + inputStream.close(); + descriptor.readExternal(rootElement); + } + } + finally { + zipFile.close(); + } + } + catch (Exception e) { + getLogger().info("Cannot load " + file, e); + } + return descriptor; + } + + protected void bootstrap(List classpathElements) { + try { + addParentClasspath(classpathElements); + addIDEALibraries(classpathElements); + addAdditionalClassPath(classpathElements); + } + catch (IllegalArgumentException e) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), e.getMessage(), "Error", JOptionPane.INFORMATION_MESSAGE); + System.exit(1); + } + catch (MalformedURLException e) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), e.getMessage(), "Error", JOptionPane.INFORMATION_MESSAGE); + System.exit(1); + } + + try { + IdeaClassLoader newClassLoader = new IdeaClassLoader(classpathElements, null); + + // prepare plugins + if (!isLoadingOfExternalPluginsDisabled()) { + PluginInstaller.initPluginClasses (); + StartupActionScriptManager.executeActionScript(); + } + + Thread.currentThread().setContextClassLoader(newClassLoader); + + final Class mainClass = Class.forName(getClass().getName(), true, newClassLoader); + + Field field = mainClass.getDeclaredField("ourMainClass"); + field.setAccessible(true); + field.set(null, ourMainClass); + + field = mainClass.getDeclaredField("ourMethodName"); + field.setAccessible(true); + field.set(null, ourMethodName); + + field = mainClass.getDeclaredField("ourArguments"); + field.setAccessible(true); + field.set(null, ourArguments); + + final Method startMethod = mainClass.getDeclaredMethod("start", new Class[]{}); + startMethod.setAccessible(true); + startMethod.invoke(null, ArrayUtil.EMPTY_OBJECT_ARRAY); + } + catch (Exception e) { + Logger logger = getLogger(); + if (logger == null) + e.printStackTrace(System.err); + else + logger.error(e); + } + } + + private static PluginClassLoader createPluginClassLoader(final File[] classPath, final String pluginName, final ClassLoader[] parentLoaders, File pluginRoot) { + try { + final List urls = new ArrayList(classPath.length); + for (int idx = 0; idx < classPath.length; idx++) { + urls.add(classPath[idx].toURL()); + } + return new PluginClassLoader(urls, parentLoaders, pluginName, pluginRoot); + } + catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + + + private void addParentClasspath(List aClasspathElements) throws MalformedURLException { + final ClassLoader loader = getClass().getClassLoader(); + if (loader instanceof URLClassLoader) { + URLClassLoader urlClassLoader = (URLClassLoader)loader; + aClasspathElements.addAll(Arrays.asList(urlClassLoader.getURLs())); + } + else { + try { + Class antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader"); + if (antClassLoaderClass.isInstance(loader)) { + final String classpath = (String)antClassLoaderClass.getDeclaredMethod("getClasspath", new Class[0]).invoke(loader, ArrayUtil.EMPTY_OBJECT_ARRAY); + final StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false); + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken(); + aClasspathElements.add(new File(token).toURL()); + } + } + else { + getLogger().error("Unknown classloader: " + loader.getClass().getName()); + } + } + catch (ClassCastException e) { + getLogger().error("Unknown classloader: " + e.getMessage()); + } + catch (ClassNotFoundException e) { + getLogger().error("Unknown classloader: " + loader.getClass().getName()); + } + catch (NoSuchMethodException e) { + getLogger().error("Unknown classloader: " + e.getMessage()); + } + catch (IllegalAccessException e) { + getLogger().error("Unknown classloader: " + e.getMessage()); + } + catch (InvocationTargetException e) { + getLogger().error("Unknown classloader: " + e.getMessage()); + } + } + } + + private void addIDEALibraries(List classpathElements) { + final String ideaHomePath = PathManager.getHomePath(); + addJreLibraries(ideaHomePath, classpathElements); + addAllFromLibFolder(ideaHomePath, classpathElements); + } + + public static void addJreLibraries(final String aIdeaHomePath, List classPath) { + try { + final String libPath = aIdeaHomePath + File.separator + "jre" + File.separator + "lib" + File.separator; + File toolsFile = new File(libPath + TOOLS_JAR); + if (!toolsFile.exists()) { + toolsFile = null; + } + if (toolsFile != null) { + classPath.add(toolsFile.toURL()); + } + final File[] extFiles = new File(libPath + EXTENSIONS_DIR).listFiles(); + if (extFiles != null) { + for (int idx = 0; idx < extFiles.length; idx++) { + File extFile = extFiles[idx]; + if (isJarOrZip(extFile)) { + classPath.add(extFile.toURL()); + } + } + } + } + catch (MalformedURLException e) { + getLogger().error(e); + + } + } + + public static void addAllFromLibFolder(final String aFolderPath, List classPath) { + try { + final Class aClass = PluginManager.class; + final String selfRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); + + final URL selfRootUrl = new File(selfRoot).getAbsoluteFile().toURL(); + classPath.add(selfRootUrl); + + final File libFolder = new File(aFolderPath + File.separator + "lib"); + addLibraries(classPath, libFolder, selfRootUrl); + + final File antLib = new File(new File(libFolder, "ant"), "lib"); + addLibraries(classPath, antLib, selfRootUrl); + } + catch (MalformedURLException e) { + getLogger().error(e); + } + } + + private static void addLibraries(List classPath, File fromDir, final URL selfRootUrl) throws MalformedURLException { + final File[] files = fromDir.listFiles(); + if (files != null) { + for (int idx = 0; idx < files.length; idx++) { + final File file = files[idx]; + if (!isJarOrZip(file)) { + continue; + } + final URL url = file.toURL(); + if (selfRootUrl.equals(url)) { + continue; + } + classPath.add(url); + } + } + } + + private static boolean isJarOrZip(File file) { + if (file.isDirectory()) { + return false; + } + final String name = file.getName().toLowerCase(); + return name.endsWith(".jar") || name.endsWith(".zip"); + } + + private void addAdditionalClassPath(List classPath) { + try { + final StringTokenizer tokenizer = new StringTokenizer(System.getProperty("idea.additional.classpath", ""), File.pathSeparator, false); + while (tokenizer.hasMoreTokens()) { + String pathItem = tokenizer.nextToken(); + classPath.add(new File(pathItem).toURL()); + } + } + catch (MalformedURLException e) { + getLogger().error(e); + } + } + + private static boolean isLoadingOfExternalPluginsDisabled() { + return !"true".equalsIgnoreCase(System.getProperty("idea.plugins.load", "true")); + } + + public static boolean isPluginInstalled (String name) { + return (getPlugin(name) != null); + } + + public static PluginDescriptor getPlugin (String name) { + final PluginDescriptor[] plugins = getPlugins(); + for (int i = 0; i < plugins.length; i++) { + final PluginDescriptor plugin = plugins[i]; + if (name.equals(plugin.getName())) { + return plugin; + } + } + return null; + } + + public static void addPluginClass (String className, String pluginName) { + if (ourPluginClasses == null) { + ourPluginClasses = new HashMap (); + } + ourPluginClasses.put(className, pluginName); + } + + public static boolean isPluginClass (String className) { + return getPluginByClassName(className) != null; + } + + public static String getPluginByClassName (String className) { + return ourPluginClasses != null? ourPluginClasses.get(className) : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerColumnInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerColumnInfo.java new file mode 100644 index 00000000000..811895ae7ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerColumnInfo.java @@ -0,0 +1,385 @@ +package com.intellij.ide.plugins; + +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.SortableColumnModel; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.ui.SortableColumnModel; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; +import java.awt.*; +import java.text.SimpleDateFormat; +import java.util.Comparator; +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 11, 2003 + * Time: 2:55:50 PM + * To change this template use Options | File Templates. + */ +class PluginManagerColumnInfo extends ColumnInfo { + public static final int COLUMN_NAME = 0; + public static final int COLUMN_STATUS = 1; + public static final int COLUMN_INSTALLED_VERSION = 2; + public static final int COLUMN_VERSION = 3; + public static final int COLUMN_DATE = 4; + public static final int COLUMN_SIZE = 5; + public static final int COLUMN_DOWNLOADS = 6; + public static final int COLUMN_CATEGORY = 7; + public static final int COLUMN_STATE = 8; + + public static final String [] COLUMNS = {"Name", "Status", "Installed", "Version", "Date", "Size", "Downloads", "Category", "State"}; + public static final int [] PREFERRED_WIDTH = {300, 80, 80, 80, 80, 80, 80, 80, 80}; + + private int columnIdx; + private SortableProvider mySortableProvider; + + public PluginManagerColumnInfo(int columnIdx, SortableProvider sortableProvider) { + super(COLUMNS [columnIdx]); + this.columnIdx = columnIdx; + mySortableProvider = sortableProvider; + } + + public Object valueOf(Object o) { + if (o instanceof CategoryNode) { + switch (columnIdx) { + case COLUMN_NAME: + return ((CategoryNode)o).getName(); + default: + return ""; + } + } else if (o instanceof PluginNode) { + PluginNode plugin = ((PluginNode)o); + switch (columnIdx) { + case COLUMN_NAME: + return plugin.getName(); + case COLUMN_INSTALLED_VERSION: + PluginDescriptor existing = PluginManager.getPlugin(plugin.getName()); + if (existing == null) + return "n/a"; + else + return existing.getVersion(); + case COLUMN_VERSION: + if (plugin.getVersion() == null) + return "n/a"; + else + return plugin.getVersion(); + case COLUMN_STATUS: + return PluginNode.STATUS_NAMES[getRealNodeState(plugin)]; + case COLUMN_SIZE: + return plugin.getSize(); + case COLUMN_DOWNLOADS: + return plugin.getDownloads(); + case COLUMN_DATE: + if (plugin.getDate() != null) + return new SimpleDateFormat ("MMM dd, yyyy HH:mm").format( + new Date (Long.valueOf(plugin.getDate()).longValue())); + else + return "n/a"; + case COLUMN_CATEGORY: + return ((CategoryNode)plugin.getParent()).getName(); + default: + return "?"; + } + } else if (o instanceof PluginDescriptor) { + switch(columnIdx) { + case COLUMN_NAME: + return ((PluginDescriptor) o).getName(); + case COLUMN_VERSION: + case COLUMN_INSTALLED_VERSION: + return ((PluginDescriptor) o).getVersion(); + case COLUMN_STATE: + return ((PluginDescriptor) o).isDeleted() ? + "Will be removed after restart" : + "Installed"; + default: + return "?"; + } + } else + return null; + } + + public static int compareVersion (String v1, String v2) { + if (v1 == null && v2 == null) + return 0; + else if (v1 == null && v2 != null) + return -1; + else if (v1 != null && v2 == null) + return 1; + + String [] part1 = v1.split("\\."); + String [] part2 = v2.split("\\."); + + int idx = 0; + for (; idx < part1.length && idx < part2.length; idx++) { + String p1 = part1[idx]; + String p2 = part2[idx]; + + int cmp; + if (p1.matches("\\d+") && p2.matches("\\d+")) { + cmp = new Integer(p1).compareTo(new Integer(p2)); + } else { + cmp = part1 [idx].compareTo(part2[idx]); + } + if (cmp != 0) + return cmp; + } + + if (part1.length == part2.length) + return 0; + else if (part1.length > idx) + return 1; + else + return -1; + } + + public Comparator getComparator() { + switch (columnIdx) { + case COLUMN_NAME: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return p1.getName().compareToIgnoreCase(p2.getName()); + } else if (o1 instanceof PluginDescriptor && o2 instanceof PluginDescriptor) { + PluginDescriptor p1 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o1 : o2); + PluginDescriptor p2 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o2 : o1); + + return p1.getName().compareToIgnoreCase(p2.getName()); + } else + return 0; + } + }; + case COLUMN_INSTALLED_VERSION: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + PluginDescriptor pd1 = PluginManager.getPlugin(p1.getName()); + PluginDescriptor pd2 = PluginManager.getPlugin(p2.getName()); + + if (pd1 == null && pd2 == null) + return 0; + else if (pd1 != null && pd2 == null) + return 1; + else if (pd1 == null && pd2 != null) + return -1; + else if (pd1 != null && pd2 != null) + return compareVersion(pd1.getVersion(), pd2.getVersion()); + + return compareVersion(p1.getVersion(), p2.getVersion()); + } else + return 0; + } + }; + case COLUMN_VERSION: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return compareVersion(p1.getVersion(), p2.getVersion()); + } else if (o1 instanceof PluginDescriptor && o2 instanceof PluginDescriptor) { + PluginDescriptor p1 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o1 : o2); + PluginDescriptor p2 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o2 : o1); + + return compareVersion(p1.getVersion(), p2.getVersion()); + } else + return 0; + } + }; + case COLUMN_STATUS: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return PluginNode.getStatusName(PluginManagerColumnInfo.getRealNodeState(p1)).compareTo( + PluginNode.getStatusName(PluginManagerColumnInfo.getRealNodeState(p2))); + } else + return 0; + } + }; + case COLUMN_SIZE: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return new Long (p1.getSize()).compareTo(new Long(p2.getSize())); + } else + return 0; + } + }; + case COLUMN_DOWNLOADS: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return new Long (p1.getDownloads()).compareTo(new Long (p2.getDownloads())); + } else + return 0; + } + }; + case COLUMN_DATE: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + if (p1.getDate() != null && p2.getDate() != null) + return new Long (p1.getDate()).compareTo(new Long (p2.getDate())); + else if (p1.getDate() != null && p2.getDate() == null) + return 1; + else if (p1.getDate() == null && p2.getDate() != null) + return -1; + else if (p1.getDate() == null && p2.getDate() == null) + return 0; + else + return 0; + } else + return 0; + } + }; + case COLUMN_CATEGORY: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginNode && o2 instanceof PluginNode) { + PluginNode p1 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o1 : o2); + PluginNode p2 = (PluginNode)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginNode)o2 : o1); + + return p1.getParent().getName().compareToIgnoreCase(p2.getParent().getName()); + } else + return 0; + } + }; + case COLUMN_STATE: + return new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof PluginDescriptor && o2 instanceof PluginDescriptor) { + PluginDescriptor p1 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o1 : o2); + PluginDescriptor p2 = (PluginDescriptor)(mySortableProvider.getSortOrder() == SortableColumnModel.SORT_ASCENDING ? (PluginDescriptor)o2 : o1); + + if (p1.isDeleted() == p2.isDeleted()) + return 0; + else if (p1.isDeleted() && ! p2.isDeleted()) + return -1; + else + return 1; + } else + return 0; + } + }; + default: + return new Comparator () { + public int compare(Object o, Object o1) { + return 0; + } + }; + } + } + + public static int getRealNodeState (PluginNode node) { + if (node.getStatus() == PluginNode.STATUS_DOWNLOADED) + return PluginNode.STATUS_DOWNLOADED; + else if (node.getStatus() == PluginNode.STATUS_DELETED) + return PluginNode.STATUS_DELETED; + else if (node.getStatus() == PluginNode.STATUS_CART) + return PluginNode.STATUS_CART; + + PluginDescriptor existing = PluginManager.getPlugin(node.getName()); + + if (existing == null) + return PluginNode.STATUS_MISSING; + + int state = compareVersion(node.getVersion(), existing.getVersion()); + + if (state == 0) + return PluginNode.STATUS_CURRENT; + else if (state >= 1) + return PluginNode.STATUS_OUT_OF_DATE; + else if (state <= -1) { + // version of installed plugin is more then version of repository plugin + // That status should be appeared on Plugin Developer's IDEA + return PluginNode.STATUS_NEWEST; + } + + return PluginNode.STATUS_UNKNOWN; + } + + private static final Color RED_COLOR = new Color (255, 231, 227); + private static final Color GREEN_COLOR = new Color (232, 243, 221); + + public TableCellRenderer getRenderer(Object o) { + return new DefaultTableCellRenderer () { + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + + if (column == COLUMN_NAME) { + // add icon + setIcon(IconLoader.getIcon("/nodes/plugin.png")); + } + + if (! isSelected) { + if (table.getModel() instanceof InstalledPluginsTableModel) { + PluginDescriptor descriptor = ((PluginTable)table).getObjectAt(row); + if (descriptor.isDeleted()) + setBackground(Color.lightGray); + else + setBackground(Color.white); + } else if (table.getModel() instanceof AvailablePluginsTableModel) { + PluginNode node = ((PluginTable)table).getObjectAt(row); + + switch (PluginManagerColumnInfo.getRealNodeState(node)) { + case PluginNode.STATUS_OUT_OF_DATE: + setBackground(RED_COLOR); + break; + case PluginNode.STATUS_CURRENT: + setBackground(GREEN_COLOR); + break; + default: + setBackground(Color.white); + } + } + } + + return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } + }; + } + + public Class getColumnClass() { + switch (columnIdx) { + case COLUMN_NAME: + case COLUMN_STATUS: + case COLUMN_INSTALLED_VERSION: + case COLUMN_VERSION: + case COLUMN_DATE: + case COLUMN_CATEGORY: + case COLUMN_STATE: + return String.class; + case COLUMN_SIZE: + case COLUMN_DOWNLOADS: + return Integer.class; + default: + return String.class; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerConfigurable.java new file mode 100644 index 00000000000..147aa01db47 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerConfigurable.java @@ -0,0 +1,153 @@ +package com.intellij.ide.plugins; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.util.ui.SortableColumnModel; +import org.jdom.Element; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Oct 26, 2003 + * Time: 9:30:44 PM + * To change this template use Options | File Templates. + */ +public class PluginManagerConfigurable extends BaseConfigurable implements JDOMExternalizable, ApplicationComponent { + public int AVAILABLE_SORT_COLUMN = 0; + public int INSTALLED_SORT_COLUMN = 0; + public int CART_SORT_COLUMN = 0; + public int AVAILABLE_SORT_COLUMN_ORDER = SortableColumnModel.SORT_ASCENDING; + public int INSTALLED_SORT_COLUMN_ORDER = SortableColumnModel.SORT_ASCENDING; + public int CART_SORT_COLUMN_ORDER = SortableColumnModel.SORT_ASCENDING; + + public boolean EXPANDED = false; + public String FIND = ""; + public boolean TREE_VIEW = false; + + private PluginManagerMain myPluginManagerMain; + + public static PluginManagerConfigurable getInstance() { + return ApplicationManager.getApplication().getComponent(PluginManagerConfigurable.class); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public String getComponentName() { + return "PluginManagerConfigurable"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "Plugins"; + } + + public void reset() { + //To change body of implemented methods use Options | File Templates. + } + + public String getHelpTopic() { + return "preferences.pluginManager"; + } + + public void disposeUIResources() { + myPluginManagerMain = null; + } + + public JComponent createComponent() { + if (myPluginManagerMain == null) { + myPluginManagerMain = new PluginManagerMain(new MyAvailableProvider(), new MyInstalledProvider(), new MyCartProvider()); + } + + return myPluginManagerMain.getMainPanel(); + } + + public void apply() throws ConfigurationException { + if (myPluginManagerMain.isRequireShutdown()) { + if (Messages.showYesNoDialog("You need to shut down IDEA to activate changes in plugins. Would you like do it now?", "Plugins", Messages.getQuestionIcon()) == 0) { + ApplicationManagerEx.getApplicationEx().exit(); + } + else { + myPluginManagerMain.ignoreChages (); + } + } + } + + public boolean isModified() { + return myPluginManagerMain != null? myPluginManagerMain.isRequireShutdown() : false; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/pluginManager.png"); + } + + private class MyAvailableProvider implements SortableProvider { + public int getSortOrder() { + return AVAILABLE_SORT_COLUMN_ORDER; + } + + public int getSortColumn() { + return AVAILABLE_SORT_COLUMN; + } + + public void setSortOrder(int sortOrder) { + AVAILABLE_SORT_COLUMN_ORDER = sortOrder; + } + + public void setSortColumn(int sortColumn) { + AVAILABLE_SORT_COLUMN = sortColumn; + } + } + + private class MyInstalledProvider implements SortableProvider { + public int getSortOrder() { + return INSTALLED_SORT_COLUMN_ORDER; + } + + public int getSortColumn() { + return INSTALLED_SORT_COLUMN; + } + + public void setSortOrder(int sortOrder) { + INSTALLED_SORT_COLUMN_ORDER = sortOrder; + } + + public void setSortColumn(int sortColumn) { + INSTALLED_SORT_COLUMN = sortColumn; + } + } + + private class MyCartProvider implements SortableProvider { + public int getSortOrder() { + return CART_SORT_COLUMN_ORDER; + } + + public int getSortColumn() { + return CART_SORT_COLUMN; + } + + public void setSortOrder(int sortOrder) { + CART_SORT_COLUMN_ORDER = sortOrder; + } + + public void setSortColumn(int sortColumn) { + CART_SORT_COLUMN = sortColumn; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerMain.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerMain.java new file mode 100644 index 00000000000..b648353fc28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginManagerMain.java @@ -0,0 +1,942 @@ +package com.intellij.ide.plugins; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.SpeedSearchBase; +import com.intellij.ui.TableUtil; +import com.intellij.util.net.HTTPProxySettingsDialog; +import com.intellij.util.net.IOExceptionDialog; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLFrameHyperlinkEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipException; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 25, 2003 + * Time: 9:47:59 PM + * To change this template use Options | File Templates. + */ +public class PluginManagerMain { + private static Logger LOG = Logger.getInstance("#com.intellij.ide.plugins.PluginManagerMain"); + + public static final int INSTALLED_TAB = 0; + public static final int AVAILABLE_TAB = 1; + //public static final int CART_TAB = 2; + + public static final String TEXT_PREFIX = ""; + public static final String TEXT_SUFIX = ""; + + public static final String HTML_PREFIX = ""; + public static final String HTML_SUFIX = ""; + + public static final String NOT_SPECIFIED = "(not specified)"; + + public static final String INSTALLED_TAB_NAME = "Installed"; + + private JPanel myToolbarPanel; + private JPanel main; + private JLabel myVendorLabel; + private JLabel myVendorEmailLabel; + private JLabel myVendorUrlLabel; + private JLabel myPluginUrlLabel; + private JEditorPane myDescriptionTextArea; + private JEditorPane myChangeNotesTextArea; + private JTabbedPane tabs; + private JScrollPane installedScrollPane; + private JScrollPane availableScrollPane; + //private JScrollPane cartScrollPane; + + // actions + //private AnAction groupByCategoryAction; + //private ExpandAllToolbarAction myExpandAllToolbarAction; + //private CollapseAllToolbarAction myCollapseAllToolbarAction; + //private AnAction addPluginToCartAction; + //private AnAction removePluginFromCartAction; + private AnAction syncAction; + private AnAction updatePluginsAction; + //private AnAction findPluginsAction; + private AnAction installPluginAction; + private AnAction uninstallPluginAction; + + private PluginTable installedPluginTable; + private PluginTable availablePluginTable; + //private PluginTable cartTable; + + private ActionToolbarEx toolbar; + + private CategoryNode root; + + private boolean requireShutdown = false; + + private DefaultActionGroup actionGroup; + private JButton myHttpProxySettingsButton; + private final SortableProvider myAvailableProvider; + private final SortableProvider myInstalledProvider; + private final SortableProvider myCartProvider; + + private void pluginInfoUpdate (Object plugin) { + if (plugin instanceof PluginDescriptor) { + PluginDescriptor pluginDescriptor = (PluginDescriptor)plugin; + + myVendorLabel.setText(pluginDescriptor.getVendor()); + + if (pluginDescriptor.getDescription() != null) { + myDescriptionTextArea.setText(TEXT_PREFIX + pluginDescriptor.getDescription().trim() + TEXT_SUFIX); + myDescriptionTextArea.setCaretPosition(0); + } else { + myDescriptionTextArea.setText(""); + } + + if (pluginDescriptor.getChangeNotes() != null) { + myChangeNotesTextArea.setText(TEXT_PREFIX + pluginDescriptor.getChangeNotes().trim() + TEXT_SUFIX); + myChangeNotesTextArea.setCaretPosition(0); + } else { + myChangeNotesTextArea.setText(""); + } + + final String email = pluginDescriptor.getVendorEmail(); + if (email != null && email.trim().length() > 0) { + myVendorEmailLabel.setText(HTML_PREFIX + email.trim() + HTML_SUFIX); + myVendorEmailLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myVendorEmailLabel.setText(NOT_SPECIFIED); + myVendorEmailLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + final String url = pluginDescriptor.getVendorUrl(); + if (url != null && url.trim().length() > 0) { + myVendorUrlLabel.setText(HTML_PREFIX + url.trim() + HTML_SUFIX); + myVendorUrlLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myVendorUrlLabel.setText(NOT_SPECIFIED); + myVendorUrlLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + final String homePage = pluginDescriptor.getUrl(); + if (homePage != null && homePage.trim().length() > 0) { + myPluginUrlLabel.setText(HTML_PREFIX + homePage + HTML_SUFIX); + myPluginUrlLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myPluginUrlLabel.setText(NOT_SPECIFIED); + myPluginUrlLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + } else if (plugin instanceof PluginNode) { + PluginNode pluginNode = (PluginNode)plugin; + + myVendorLabel.setText(pluginNode.getVendor()); + + if (pluginNode.getDescription() != null) { + myDescriptionTextArea.setText(TEXT_PREFIX + pluginNode.getDescription().trim() + TEXT_SUFIX); + myDescriptionTextArea.setCaretPosition(0); + } else { + myDescriptionTextArea.setText(""); + } + + if (pluginNode.getChangeNotes() != null) { + myChangeNotesTextArea.setText(TEXT_PREFIX + pluginNode.getChangeNotes().trim() + TEXT_SUFIX); + myChangeNotesTextArea.setCaretPosition(0); + } else { + myChangeNotesTextArea.setText(""); + } + + final String email = pluginNode.getVendorEmail(); + if (email != null && email.trim().length() > 0) { + myVendorEmailLabel.setText(HTML_PREFIX + email.trim() + HTML_SUFIX); + myVendorEmailLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myVendorEmailLabel.setText(NOT_SPECIFIED); + myVendorEmailLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + final String url = pluginNode.getVendorUrl(); + if (url != null && url.trim().length() > 0) { + myVendorUrlLabel.setText(HTML_PREFIX + url.trim() + HTML_SUFIX); + myVendorUrlLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myVendorUrlLabel.setText(NOT_SPECIFIED); + myVendorUrlLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + final String homePage = pluginNode.getUrl(); + if (homePage != null && homePage.trim().length() > 0) { + myPluginUrlLabel.setText(HTML_PREFIX + homePage + HTML_SUFIX); + myPluginUrlLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + } + else { + myPluginUrlLabel.setText(NOT_SPECIFIED); + myPluginUrlLabel.setCursor(new Cursor (Cursor.DEFAULT_CURSOR)); + } + + } else { + myVendorLabel.setText(NOT_SPECIFIED); + myVendorEmailLabel.setText(NOT_SPECIFIED); + myVendorUrlLabel.setText(NOT_SPECIFIED); + myDescriptionTextArea.setText(""); + myChangeNotesTextArea.setText(""); + myPluginUrlLabel.setText(NOT_SPECIFIED); + } + } + + public PluginManagerMain(SortableProvider availableProvider, SortableProvider installedProvider, SortableProvider cartProvider) { + myAvailableProvider = availableProvider; + myInstalledProvider = installedProvider; + myCartProvider = cartProvider; + myToolbarPanel.setLayout(new BorderLayout()); + toolbar = (ActionToolbarEx)ActionManagerEx.getInstance().createActionToolbar("PluginManaer", getActionGroup(), true); + + myToolbarPanel.add(toolbar.getComponent(), BorderLayout.WEST); + + myDescriptionTextArea.setContentType("text/html"); + myDescriptionTextArea.addHyperlinkListener(new MyHyperlinkListener()); + + myChangeNotesTextArea.setContentType("text/html"); + myChangeNotesTextArea.addHyperlinkListener(new MyHyperlinkListener()); + + installedPluginTable = new PluginTable(new InstalledPluginsTableModel(myInstalledProvider)); + + installedScrollPane.getViewport().setBackground(installedPluginTable.getBackground()); + installedScrollPane.getViewport().setView(installedPluginTable); + installedPluginTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + pluginInfoUpdate(installedPluginTable.getSelectedObject()); + toolbar.updateActions(); + } + }); + PopupHandler.installUnknownPopupHandler(installedPluginTable, getActionGroup(), ActionManager.getInstance()); + tabs.setTitleAt(INSTALLED_TAB, INSTALLED_TAB_NAME + " (" + installedPluginTable.getRowCount() + ")"); + + /* + cartTable = new PluginTable(new ShoppingCartTableModel( + PluginManagerConfigurable.getInstance().getCartSortableProvider())); + cartScrollPane.getViewport().setBackground(cartTable.getBackground()); + cartScrollPane.getViewport().setView(cartTable); + cartTable.getSelectionModel().addListSelectionListener(new ListSelectionListener () { + public void valueChanged(ListSelectionEvent e) { + pluginInfoUpdate(cartTable.getSelectedObject()); + } + }); + */ + + tabs.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + if (tabs.getSelectedIndex() == INSTALLED_TAB) { + pluginInfoUpdate(installedPluginTable.getSelectedObject()); + } + else if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + pluginInfoUpdate(null); + + // load plugin list, if required + loadAvailablePlugins(true); + if (availablePluginTable != null) { + pluginInfoUpdate(availablePluginTable.getSelectedObject()); + } + + /* + } else if (tabs.getSelectedIndex() == CART_TAB) { + pluginInfoUpdate(null); + + // show cart tab + pluginInfoUpdate(cartTable.getSelectedObject()); + */ + } + toolbar.updateActions(); + } + }); + + myHttpProxySettingsButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog(); + settingsDialog.pack(); + settingsDialog.show(); + } + }); + /* + httpProxySettingsLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); + httpProxySettingsLabel.addMouseListener(new MouseAdapter () { + public void mouseClicked(MouseEvent e) { + HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog(); + settingsDialog.pack(); + settingsDialog.show(); + } + }); + */ + + myVendorEmailLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + myVendorEmailLabel.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String email = null; + + if (tabs.getSelectedIndex() == INSTALLED_TAB) { + PluginDescriptor pluginDescriptor = installedPluginTable.getSelectedObject(); + if (pluginDescriptor != null) { + email = pluginDescriptor.getVendorEmail(); + } + } + else if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + if (pluginNode != null) { + email = pluginNode.getVendorEmail(); + } + /* + } else if (tabs.getSelectedIndex() == CART_TAB) { + PluginNode pluginNode = cartTable.getSelectedObject(); + if (pluginNode != null) + email = pluginNode.getVendorEmail(); + */ + } + + if (email != null && email.trim().length() > 0) { + try { + BrowserUtil.launchBrowser("mailto:" + email.trim()); + } + catch (IllegalThreadStateException ex) { + // not a problem + } + } + } + }); + + myVendorUrlLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + myVendorUrlLabel.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String url = null; + + if (tabs.getSelectedIndex() == INSTALLED_TAB) { + PluginDescriptor pluginDescriptor = installedPluginTable.getSelectedObject(); + if (pluginDescriptor != null) { + url = pluginDescriptor.getVendorUrl(); + } + } + else if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + if (pluginNode != null) { + url = pluginNode.getVendorUrl(); + } + /* + } else if (tabs.getSelectedIndex() == CART_TAB) { + PluginNode pluginNode = cartTable.getSelectedObject(); + if (pluginNode != null) + url = pluginNode.getVendorUrl(); + */ + } + + if (url != null && url.trim().length() > 0) { + BrowserUtil.launchBrowser(url.trim()); + } + } + }); + + myPluginUrlLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + myPluginUrlLabel.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String url = null; + + if (tabs.getSelectedIndex() == INSTALLED_TAB) { + PluginDescriptor pluginDescriptor = installedPluginTable.getSelectedObject(); + if (pluginDescriptor != null) { + url = pluginDescriptor.getUrl(); + } + } + else if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + if (pluginNode != null) { + url = pluginNode.getUrl(); + } + /* + } else if (tabs.getSelectedIndex() == CART_TAB) { + PluginNode pluginNode = cartTable.getSelectedObject(); + if (pluginNode != null) + url = pluginNode.getUrl(); + */ + } + + if (url != null && url.trim().length() > 0) { + BrowserUtil.launchBrowser(url.trim()); + } + } + }); + + new SpeedSearchBase>(installedPluginTable) { + public int getSelectedIndex() { + return installedPluginTable.getSelectedRow(); + } + + public Object[] getAllElements() { + return installedPluginTable.getElements(); + } + + public String getElementText(Object element) { + return ((PluginDescriptor)element).getName(); + } + + public void selectElement(Object element, String selectedText) { + for (int i = 0; i < installedPluginTable.getRowCount(); i++) { + if (installedPluginTable.getObjectAt(i).getName().equals(((PluginDescriptor)element).getName())) { + installedPluginTable.setRowSelectionInterval(i, i); + TableUtil.scrollSelectionToVisible(installedPluginTable); + break; + } + } + } + }; + } + + private void loadAvailablePlugins (boolean askForDownload) { + try { + if (root == null) { + if (askForDownload) { + if (Messages.showYesNoDialog(main, "Latest information from the Plugin Repository is required.\n" + + "Would you like to download it?", "Plugins", + Messages.getQuestionIcon()) != 0) { + tabs.setSelectedIndex(INSTALLED_TAB); + return; + } + } + + root = loadPluginList(); + if (root == null) { + Messages.showErrorDialog(getMainPanel(), "List of plugins was not loaded.", "Plugins"); + tabs.setSelectedIndex(INSTALLED_TAB); + + return; + } + + availablePluginTable = new PluginTable( + new AvailablePluginsTableModel(root, myAvailableProvider) + ); + availablePluginTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + pluginInfoUpdate(availablePluginTable.getSelectedObject()); + toolbar.updateActions(); + } + }); + ActionGroup group = getActionGroup(); + PopupHandler.installUnknownPopupHandler(availablePluginTable, group, ActionManager.getInstance()); + availableScrollPane.getViewport().setBackground(availablePluginTable.getBackground()); + availableScrollPane.getViewport().setView(availablePluginTable); + + tabs.setTitleAt(AVAILABLE_TAB, "Available (" + availablePluginTable.getRowCount() + ")"); + + availablePluginTable.requestFocus(); + + new SpeedSearchBase>(availablePluginTable) { + public int getSelectedIndex() { + return availablePluginTable.getSelectedRow(); + } + + public Object[] getAllElements() { + return availablePluginTable.getElements(); + } + + public String getElementText(Object element) { + return ((PluginNode)element).getName(); + } + + public void selectElement(Object element, String selectedText) { + for (int i = 0; i < availablePluginTable.getRowCount(); i++) { + if (availablePluginTable.getObjectAt(i).getName().equals(((PluginNode)element).getName())) { + availablePluginTable.setRowSelectionInterval(i, i); + TableUtil.scrollSelectionToVisible(availablePluginTable); + break; + } + } + } + }; + } + } catch (RuntimeException ex) { + ex.printStackTrace(); + Messages.showErrorDialog(getMainPanel(), "Available plugins list is not loaded", "Error"); + } + } + + private ActionGroup getActionGroup () { + if (actionGroup == null) { + actionGroup = new DefaultActionGroup(); + + /* + groupByCategoryAction = new ToggleAction("Group by category", + "Group plugins by category", + IconLoader.getIcon("/_cvs/showAsTree.png")) { + public boolean isSelected(AnActionEvent e) { + return PluginManagerConfigurable.getInstance().TREE_VIEW; + } + + public void setSelected(AnActionEvent e, boolean state) { + PluginManagerConfigurable.getInstance().TREE_VIEW = state; + // @todo switch table and tree view + } + }; + actionGroup.add(groupByCategoryAction); + actionGroup.addSeparator(); + */ + + //myExpandAllToolbarAction = new ExpandAllToolbarAction(myTreeTable); + //actionGroup.add(myExpandAllToolbarAction); + //myCollapseAllToolbarAction = new CollapseAllToolbarAction(myTreeTable); + //actionGroup.add(myCollapseAllToolbarAction); + + /* + addPluginToCartAction = new AnAction ("Add Plugin to \"Shopping Cart\"", + "Add Plugin to \"Shopping Cart\"", + IconLoader.getIcon("/actions/include.png")) { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + boolean enabled = false; + + if (tabs.getSelectedIndex() == AVAILABLE_TAB && availablePluginTable != null) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + + if (pluginNode != null) { + int status = PluginManagerColumnInfo.getRealNodeState(pluginNode); + if (status == PluginNode.STATUS_MISSING || + status == PluginNode.STATUS_NEWEST || + status == PluginNode.STATUS_OUT_OF_DATE || + status == PluginNode.STATUS_UNKNOWN) { + enabled = true; + } + } + } + + presentation.setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + if (pluginNode != null) { + int state = PluginManagerColumnInfo.getRealNodeState(pluginNode); + if (state == PluginNode.STATUS_MISSING || + state == PluginNode.STATUS_NEWEST || + state == PluginNode.STATUS_OUT_OF_DATE || + state == PluginNode.STATUS_UNKNOWN) { + ((ShoppingCartTableModel)cartTable.getModel ()).add(pluginNode); + tabs.setTitleAt(CART_TAB, "Shopping Cart (" + cartTable.getRowCount() + ")"); + } + } + } + } + }; + actionGroup.add(addPluginToCartAction); + + removePluginFromCartAction = new AnAction ("Delete Plugin from \"Shopping Cart\"", + "Delete Plugin from \"Shopping Cart\"", + IconLoader.getIcon("/actions/exclude.png")) { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + boolean enabled = false; + + if (tabs.getSelectedIndex() == CART_TAB) { + PluginNode pluginNode = cartTable.getSelectedObject(); + + if (pluginNode != null) { + int status = PluginManagerColumnInfo.getRealNodeState(pluginNode); + if (status == PluginNode.STATUS_CART) { + enabled = true; + } + } + } + + presentation.setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + if (tabs.getSelectedIndex() == CART_TAB) { + PluginNode pluginNode = cartTable.getSelectedObject(); + if (pluginNode != null) { + int state = PluginManagerColumnInfo.getRealNodeState(pluginNode); + if (state == PluginNode.STATUS_CART) { + ((ShoppingCartTableModel)cartTable.getModel ()).remove(pluginNode); + tabs.setTitleAt(CART_TAB, "Shopping Cart (" + cartTable.getRowCount() + ")"); + } + } + } + } + }; + actionGroup.add(removePluginFromCartAction); + actionGroup.addSeparator(); + */ + + syncAction = new AnAction("Synchronize with Plugin Repository", "Synchronize with Plugin Repository", + IconLoader.getIcon("/actions/sync.png")) { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + boolean enabled = false; + + if (tabs.getSelectedIndex() == AVAILABLE_TAB) { + enabled = true; + } + + presentation.setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + root = null; + pluginInfoUpdate(null); + loadAvailablePlugins(false); + } + }; + syncAction.registerCustomShortcutSet( + new CustomShortcutSet (KeymapManager.getInstance().getActiveKeymap().getShortcuts("Synchronize")), main); + actionGroup.add(syncAction); + + updatePluginsAction = new AnAction("Update Installed Plugins", "Update Installed Plugins", + IconLoader.getIcon("/actions/refresh.png")) { + + public void actionPerformed(AnActionEvent e) { + if (availablePluginTable == null) { + loadAvailablePlugins(true); + } + + if (root != null) + do { + try { + List updateList = new ArrayList(); + checkForUpdate(updateList, root); + + if (updateList.size() == 0) { + Messages.showMessageDialog(main, + "Nothing to update", "Plugin Manager", Messages.getInformationIcon()); + break; + } + else { + String list = ""; + for (int i = 0; i < updateList.size(); i++) { + PluginNode pluginNode = updateList.get(i); + list += pluginNode.getName() + "\n"; + } + + if (Messages.showYesNoDialog(main, + "Plugin(s) can be updated: \n" + list + + "Would you like to update them?", + "Update Installed Plugins", Messages.getQuestionIcon()) == 0) { + if (downloadPlugins(updateList)) { + availablePluginTable.updateUI(); + + requireShutdown = true; + } + } + break; + } + } + catch (IOException e1) { + if (!IOExceptionDialog.showErrorDialog(e1, "Update Installed Plugins", "Plugins updating failed")) { + break; + } + else { + LOG.error(e1); + } + } + } + while (true); + } + }; + actionGroup.add(updatePluginsAction); + + //findPluginsAction = new AnAction("Find", "Find Plugins", IconLoader.getIcon("/actions/find.png")) { + // public void actionPerformed(AnActionEvent e) { + // Messages.showMessageDialog(main, "Sorry, not implemented yet.", "Find Plugins", Messages.getWarningIcon()); + + /* + PluginManagerConfigurable.getInstance().FIND = JOptionPane.showInputDialog( + JOptionPane.getRootFrame(), "Find:", + PluginManagerConfigurable.getInstance().FIND != null ? PluginManagerConfigurable.getInstance().FIND : ""); + if (PluginManagerConfigurable.getInstance().FIND == null || + PluginManagerConfigurable.getInstance().FIND.trim().length() == 0) { + return; + } + else { + PluginNode pluginNode = find(myRoot, + myCurrentNode, + PluginManagerConfigurable.getInstance().FIND.trim()); + if (pluginNode == null) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Nothing was found for '" + PluginManagerConfigurable.getInstance().FIND + + "'", + "Find plugin", JOptionPane.INFORMATION_MESSAGE); + } + } + */ + // } + //}; + //findPluginsAction.registerCustomShortcutSet( + // new CustomShortcutSet (KeymapManager.getInstance().getActiveKeymap().getShortcuts("Find")), main); + //actionGroup.add(findPluginsAction); + + installPluginAction = new AnAction("Download and Install Plugin", + "Download and Install Plugin", + IconLoader.getIcon("/actions/install.png")) { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + boolean enabled = false; + + if (tabs.getSelectedIndex() == AVAILABLE_TAB && availablePluginTable != null) { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + + if (pluginNode != null) { + int status = PluginManagerColumnInfo.getRealNodeState(pluginNode); + if (status == PluginNode.STATUS_MISSING || + status == PluginNode.STATUS_NEWEST || + status == PluginNode.STATUS_OUT_OF_DATE || + status == PluginNode.STATUS_UNKNOWN) { + enabled = true; + } + } + } + + presentation.setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + do { + try { + PluginNode pluginNode = availablePluginTable.getSelectedObject(); + + if (Messages.showYesNoDialog(main, + "Would you like to download and install plugin \"" + pluginNode.getName() + "\"?", + "Download and Install Plugin", Messages.getQuestionIcon()) == 0) { + if (downloadPlugin(pluginNode)) { + requireShutdown = true; + availablePluginTable.updateUI(); + } + } + break; + } + catch (IOException e1) { + if (!IOExceptionDialog.showErrorDialog(e1, "Download and Install Plugin", "Plugin download failed")) { + break; + } + else { + LOG.error(e1); + } + } + } + while (true); + } + }; + actionGroup.add(installPluginAction); + + uninstallPluginAction = new AnAction("Uninstall Plugin", + "Uninstall Plugin", + IconLoader.getIcon("/actions/uninstall.png")) { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + boolean enabled = false; + + if (installedPluginTable != null && tabs.getSelectedIndex() == INSTALLED_TAB) { + PluginDescriptor pluginDescriptor = installedPluginTable.getSelectedObject(); + + if (pluginDescriptor != null && ! pluginDescriptor.isDeleted()) { + enabled = true; + } + } + presentation.setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + String pluginName = null; + + if (tabs.getSelectedIndex() == INSTALLED_TAB) { + PluginDescriptor pluginDescriptor = installedPluginTable.getSelectedObject(); + if (pluginDescriptor != null) { + if (Messages.showYesNoDialog(main, "Do you really want to uninstall plugin \"" + + pluginDescriptor.getName() + "\"?", "Plugin Uninstall", + Messages.getQuestionIcon()) == 0) { + pluginName = pluginDescriptor.getName(); + pluginDescriptor.setDeleted(true); + } + } + } + + if (pluginName != null) { + try { + PluginInstaller.prepareToUninstall(pluginName); + + requireShutdown = true; + + installedPluginTable.updateUI(); + + /* + Messages.showMessageDialog(main, + "Plugin \'" + pluginName + + "\' is uninstalled but still running. You will " + + "need to restart IDEA to deactivate it.", + "Plugin Uninstalled", + Messages.getInformationIcon()); + */ + } + catch (IOException e1) { + LOG.equals(e1); + } + } + } + }; + actionGroup.add(uninstallPluginAction); + } + + return actionGroup; + } + + public JPanel getMainPanel() { + return main; + } + + private class MyHyperlinkListener implements HyperlinkListener { + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + JEditorPane pane = (JEditorPane)e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e; + HTMLDocument doc = (HTMLDocument)pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + } + else { + BrowserUtil.launchBrowser(e.getURL().toString()); + } + + } + } + } + + private CategoryNode loadPluginList() { + StatusProcess statusProcess = new StatusProcess(); + do { + boolean canceled = ApplicationManager.getApplication().runProcessWithProgressSynchronously( + statusProcess, "Downloading List of Plugins", true, null); + if (canceled && statusProcess.getException() != null) { + if (statusProcess.getException() instanceof IOException) { + if (! IOExceptionDialog.showErrorDialog((IOException)statusProcess.getException(), "Plugin Manager", "Could not download a list of plugins")) { + break; + } + } else + throw new RuntimeException(statusProcess.getException()); + } else { + break; + } + } + while (true); + + if (statusProcess != null) { + return statusProcess.getRoot(); + } + else { + return null; + } + } + + public Object getSelectedPlugin () { + switch (tabs.getSelectedIndex()) { + case INSTALLED_TAB: + return installedPluginTable.getSelectedObject(); + case AVAILABLE_TAB: + return availablePluginTable.getSelectedObject(); + /* + case CART_TAB: + return cartTable.getSelectedObject(); + */ + default: + return null; + } + } + + private void checkForUpdate(List updateList, CategoryNode categoryNode) + throws IOException { + for (int i = 0; i < categoryNode.getPlugins().size(); i++) { + PluginNode pluginNode = categoryNode.getPlugins().get(i); + if (PluginManagerColumnInfo.getRealNodeState(pluginNode) == PluginNode.STATUS_OUT_OF_DATE) { + updateList.add(pluginNode); + } + } + + if (categoryNode.getChildCount() > 0) { + for (int i = 0; i < categoryNode.getChildren().size(); i++) { + CategoryNode node = categoryNode.getChildren().get(i); + checkForUpdate(updateList, node); + } + } + } + + private boolean downloadPlugins (final List plugins) throws IOException { + final boolean[] result = new boolean[1]; + try { + ApplicationManager.getApplication().runProcessWithProgressSynchronously( + new Runnable () { + public void run() { + result[0] = PluginInstaller.prepareToInstall(plugins); + } + }, "Download Plugins", true, null); + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof IOException) + throw (IOException)e.getCause(); + else + throw e; + } + return result[0]; + } + + private boolean downloadPlugin (final PluginNode pluginNode) throws IOException { + final boolean[] result = new boolean[1]; + try { + ApplicationManager.getApplication().runProcessWithProgressSynchronously( + new Runnable () { + public void run() { + ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + + pi.setText(pluginNode.getName()); + + try { + result[0] = PluginInstaller.prepareToInstall(pluginNode); + } catch (ZipException e) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Plugin \"" + pluginNode.getName() + "\" has problems in ZIP archive and will be not installed.", + "Installing Plugin", JOptionPane.ERROR_MESSAGE, Messages.getErrorIcon()); + } catch (IOException e) { + throw new RuntimeException (e); + } + } + }, "Download Plugin \"" + pluginNode.getName() + "\"", true, null); + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof IOException) + throw (IOException)e.getCause(); + else + throw e; + } + + return result[0]; + } + + public boolean isRequireShutdown() { + return requireShutdown; + } + + public void ignoreChages() { + requireShutdown = false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginNode.java new file mode 100644 index 00000000000..1f5cef0b33b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginNode.java @@ -0,0 +1,281 @@ +package com.intellij.ide.plugins; + +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.Enumeration; +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Mar 27, 2003 + * Time: 10:07:29 PM + * To change this template use Options | File Templates. + */ +public class PluginNode implements TreeNode { + public static final int STATUS_UNKNOWN = 0; + public static final int STATUS_OUT_OF_DATE = 1; + public static final int STATUS_MISSING = 2; + public static final int STATUS_CURRENT = 3; + public static final int STATUS_NEWEST = 4; + public static final int STATUS_DOWNLOADED = 5; + public static final int STATUS_DELETED = 6; + public static final int STATUS_CART = 7; + + public static final String [] STATUS_NAMES = { + "Unknown", + "Out of date", + "Not installed", + "Installed", + "Newest", + "Downloaded", // downloaded, but not activated + "Uninstalled", // uninstalled, but not activated + "Shopping Cart" // added to the Shopping Cart + }; + + private CategoryNode parent; + + private String name; + private String version; + private String vendor; + private String description; + private String sinceBuild; + private String changeNotes; + private String downloads; + private String size; + private String vendorEmail; + private String vendorUrl; + private String url; + private String date; + private List depends; + + private int status = STATUS_UNKNOWN; + private boolean loaded = false; + + public PluginNode() { + } + + public PluginNode(String name) { + this.name = name; + } + + public String getChangeNotes() { return changeNotes; } + + public void setChangeNotes(String changeNotes) { this.changeNotes = changeNotes; } + + /** + * Returns the child TreeNode at index + * childIndex. + */ + public TreeNode getChildAt(int childIndex) { + return null; + } + + /** + * Returns the number of children TreeNodes the receiver + * contains. + */ + public int getChildCount() { + return 0; + } + + /** + * Returns the parent TreeNode of the receiver. + */ + public CategoryNode getParent() { + return parent; + } + + /** + * Returns the index of node in the receivers children. + * If the receiver does not contain node, -1 will be + * returned. + */ + public int getIndex(TreeNode node) { + return 0; + } + + /** + * Returns true if the receiver allows children. + */ + public boolean getAllowsChildren() { + return false; + } + + /** + * Returns true if the receiver is a leaf. + */ + public boolean isLeaf() { + return true; + } + + /** + * @return Returns the children of the receiver as an Enumeration. + */ + public Enumeration children() { + return null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * Be carefull when comparing Plugins versions. Use + * PluginManagerColumnInfo.compareVersion() for version comparing. + * + * @return Return plugin version + */ + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSinceBuild() { + return sinceBuild; + } + + public void setSinceBuild(String sinceBuild) { + this.sinceBuild = sinceBuild; + } + + public void setParent(CategoryNode parent) { + this.parent = parent; + } + + /** + * In complex environment use PluginManagerColumnInfo.getRealNodeState () method instead. + * @return Status of plugin + */ + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getStatusName () { + return STATUS_NAMES [status]; + } + + public static String getStatusName (int status) { + return STATUS_NAMES [status]; + } + + public String toString() { + return getName(); + } + + public boolean isLoaded() { + return loaded; + } + + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public String getDownloads() { return downloads; } + + public void setDownloads(String downloads) { this.downloads = downloads; } + + public String getSize() { return size; } + + public void setSize(String size) { this.size = size; } + + public String getVendorEmail() { + return vendorEmail; + } + + public void setVendorEmail(String vendorEmail) { + this.vendorEmail = vendorEmail; + } + + public String getVendorUrl() { + return vendorUrl; + } + + public void setVendorUrl(String vendorUrl) { + this.vendorUrl = vendorUrl; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public TreePath getPath() { + List nodes = new ArrayList (); + nodes.add(this); + CategoryNode start = (CategoryNode)getParent(); + + while (start != null) { + nodes.add(0, start); + start = (CategoryNode)start.getParent(); + } + + TreePath path = new TreePath(nodes.toArray()); + return path; + } + + public int hashCode() { + return name.hashCode(); + } + + public boolean equals(Object object) { + if (object instanceof PluginNode) { + return name.equals(((PluginNode)object).getName()); + } else + return false; + } + + public List getDepends() { + return depends; + } + + public void setDepends(List depends) { + this.depends = depends; + } + + public void addDepends (String depends) { + if (this.depends == null) + this.depends = new ArrayList (); + + this.depends.add(depends); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTable.java new file mode 100644 index 00000000000..8fd4deddcf9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTable.java @@ -0,0 +1,72 @@ +package com.intellij.ide.plugins; + +import com.intellij.util.ui.SortableColumnModel; +import com.intellij.util.ui.Table; +import com.intellij.ui.table.TableHeaderRenderer; + +import javax.swing.*; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 11, 2003 + * Time: 4:19:20 PM + * To change this template use Options | File Templates. + */ +public class PluginTable extends Table { + public PluginTable(final PluginTableModel model) { + super(model); + + JTableHeader tableHeader = getTableHeader(); + tableHeader.setDefaultRenderer(new TableHeaderRenderer (model)); + tableHeader.addMouseListener(new MouseAdapter () { + public void mouseClicked(MouseEvent e) { + int column = getTableHeader().getColumnModel().getColumnIndexAtX(e.getX()); + + if (model.sortableProvider.getSortColumn() == column) { + if (model.sortableProvider.getSortOrder() == SortableColumnModel.SORT_DESCENDING) + model.sortableProvider.setSortOrder(SortableColumnModel.SORT_ASCENDING); + else + model.sortableProvider.setSortOrder(SortableColumnModel.SORT_DESCENDING); + } else { + model.sortableProvider.setSortOrder(SortableColumnModel.SORT_ASCENDING); + model.sortableProvider.setSortColumn(column); + } + + model.sortByColumn (column); + + getTableHeader().updateUI(); + } + }); + tableHeader.setReorderingAllowed(false); + + for (int i = 0; i < model.getColumnCount(); i++) { + TableColumn column = getColumnModel().getColumn(i); + column.setCellRenderer(model.getColumnInfos() [i].getRenderer(null)); + //column.setPreferredWidth(PluginManagerColumnInfo.PREFERRED_WIDTH [i]); + } + + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + setShowGrid(false); + } + + public T getObjectAt (int row) { + return ((PluginTableModel )getModel()).getObjectAt(row); + } + + public T getSelectedObject () { + T o = null; + if (getSelectedRowCount() > 0) { + o = getObjectAt(getSelectedRow()); + } + return o; + } + + public Object [] getElements () { + return ((PluginTableModel)getModel()).view.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTableModel.java new file mode 100644 index 00000000000..d52a902a3d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/PluginTableModel.java @@ -0,0 +1,73 @@ +package com.intellij.ide.plugins; + +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.SortableColumnModel; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.SortableColumnModel; + +import javax.swing.table.AbstractTableModel; +import java.util.Collections; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 26, 2003 + * Time: 4:16:50 PM + * To change this template use Options | File Templates. + */ +abstract public class PluginTableModel extends AbstractTableModel implements SortableColumnModel { + protected PluginManagerColumnInfo [] columns; + protected SortableProvider sortableProvider; + protected List view; + + public PluginTableModel(PluginManagerColumnInfo[] columns, SortableProvider sortableProvider) { + this.columns = columns; + this.sortableProvider = sortableProvider; + } + + public int getColumnCount() { + return columns.length; + } + + public ColumnInfo[] getColumnInfos() { + return columns; + } + + public boolean isSortable() { + return true; + } + + public void setSortable(boolean aBoolean) { + // do nothing cause it's always sortable + } + + public String getColumnName(int column) { + return columns[column].getName(); + } + + public int getSortedColumnIndex() { + return sortableProvider.getSortColumn(); + } + + public int getSortingType() { + return sortableProvider.getSortOrder(); + } + + public T getObjectAt (int row) { + return (T)view.get(row); + } + + public int getRowCount() { + return view.size(); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + return columns[columnIndex].valueOf(getObjectAt(rowIndex)); + } + + public void sortByColumn(int columnIndex) { + Collections.sort(view, columns[columnIndex].getComparator()); + fireTableDataChanged(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryContentHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryContentHandler.java new file mode 100644 index 00000000000..cafb6a5319a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryContentHandler.java @@ -0,0 +1,116 @@ +package com.intellij.ide.plugins; + +import org.xml.sax.SAXException; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; + +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Mar 28, 2003 + * Time: 12:57:45 AM + * To change this template use Options | File Templates. + */ +class RepositoryContentHandler extends DefaultHandler { + public static final String CATEGORY = "category"; + public static final String IDEA_PLUGIN = "idea-plugin"; + public static final String NAME = "name"; + public static final String DESCRIPTION = "description"; + public static final String VERSION = "version"; + public static final String VENDOR = "vendor"; + public static final String EMAIL = "email"; + public static final String URL = "url"; + public static final String IDEA_VERSION = "idea-version"; + public static final String SINCE_BUILD = "since-build"; + public static final String CHNAGE_NOTES = "change-notes"; + private static final String DEPENDS = "depends"; + + private CategoryNode currentCategory; + private PluginNode currentPlugin; + private String currentValue; + + public InputSource resolveEntity(String publicId, String systemId) throws SAXException { + /* + if (systemId != null && systemId.equals(RepositoryHelper.REPOSITORY_LIST_SYSTEM_ID)) { + String location = ExternalResourceManager.getInstance().getResourceLocation(systemId); + try { + return new InputSource (new java.net.URL (location).openStream()); + } + catch (IOException e) { + return super.resolveEntity(publicId, systemId); + } + } else + */ + //try { + return super.resolveEntity(publicId, systemId); + //} + //catch (IOException e) { + // throw new SAXException(e); + //} + } + + public void startDocument() + throws SAXException { + currentCategory = new CategoryNode(); + currentCategory .setName(""); + } + + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) + throws SAXException { + if (qName.equals(CATEGORY)) { + CategoryNode categoryNode = new CategoryNode(); + categoryNode.setName (atts.getValue(NAME)); + categoryNode.setParent(currentCategory); + + currentCategory.addChild(categoryNode); + currentCategory = categoryNode; + } else if (qName.equals(IDEA_PLUGIN)) { + currentPlugin = new PluginNode(); + currentPlugin.setParent(currentCategory); + currentPlugin.setDownloads(atts.getValue("downloads")); + currentPlugin.setSize(atts.getValue("size")); + currentPlugin.setUrl (atts.getValue("url")); + currentPlugin.setDate (atts.getValue("date")); + currentCategory.addPlugin(currentPlugin); + } else if (qName.equals(IDEA_VERSION)) { + currentPlugin.setSinceBuild(atts.getValue(SINCE_BUILD)); + } else if (qName.equals(VENDOR)) { + currentPlugin.setVendorEmail(atts.getValue(EMAIL)); + currentPlugin.setVendorUrl(atts.getValue(URL)); + } + currentValue = ""; + } + + public void endElement(String namespaceURI, String localName, + String qName) + throws SAXException { + if (qName.equals(NAME)) + currentPlugin.setName(currentValue); + else if (qName.equals(DESCRIPTION)) + currentPlugin.setDescription(currentValue); + else if (qName.equals(VERSION)) + currentPlugin.setVersion(currentValue); + else if (qName.equals(VENDOR)) { + currentPlugin.setVendor(currentValue); + } else if (qName.equals(DEPENDS)) { + currentPlugin.addDepends(currentValue); + } else if (qName.equals(CHNAGE_NOTES)) + currentPlugin.setChangeNotes(currentValue); + else if (qName.equals(CATEGORY)) + currentCategory = (CategoryNode) currentCategory.getParent(); + currentValue = ""; + } + + public void characters(char ch[], int start, int length) + throws SAXException { + currentValue += new String (ch, start, length); + } + + public CategoryNode getRoot() { + return currentCategory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryHelper.java new file mode 100644 index 00000000000..41c9358b8c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/RepositoryHelper.java @@ -0,0 +1,238 @@ +package com.intellij.ide.plugins; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressStream; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.diagnostic.Logger; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Mar 28, 2003 + * Time: 12:56:26 AM + * To change this template use Options | File Templates. + */ +public class RepositoryHelper { + //private static final Logger LOG = com.intellij.openapi.diagnostic.Logger.getInstance("#com.intellij.ide.plugins.RepositoryHelper"); + public static final String REPOSITORY_HOST = "http://plugins.intellij.net"; + //public static final String REPOSITORY_HOST = "http://unit-038:8080/plug"; + public static final String REPOSITORY_LIST_URL = REPOSITORY_HOST + "/plugins/list/"; + public static final String DOWNLOAD_URL = REPOSITORY_HOST + "/pluginManager?action=download&id="; + public static final String REPOSITORY_LIST_SYSTEM_ID = REPOSITORY_HOST + "/plugin-repository.dtd"; + + private static final String FILENAME = "filename=\""; + + private static class InputStreamGetter implements Runnable { + private InputStream is; + private URLConnection urlConnection; + + public InputStream getIs() { + return is; + } + + public InputStreamGetter(URLConnection urlConnection) { + this.urlConnection = urlConnection; + } + + public void run() { + try { + is = urlConnection.getInputStream(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public static CategoryNode makeCategoryTree (String url) + throws SAXException, ParserConfigurationException, IOException { + final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + + if (pi.isCanceled()) + return null; + + RepositoryContentHandler handler = new RepositoryContentHandler(); + SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); + HttpURLConnection connection = (HttpURLConnection)new URL (url).openConnection(); + try { + if (pi.isCanceled()) + return null; + + pi.setText("Waiting for reply from " + RepositoryHelper.REPOSITORY_HOST); + + InputStreamGetter getter = new InputStreamGetter(connection); + final Thread thread = new Thread (getter, "InputStreamGetter"); + thread.start(); + + while (! pi.isCanceled()) { + try { + thread.join(50); + pi.setFraction(System.currentTimeMillis()); + if (! thread.isAlive()) + break; + } + catch (InterruptedException e) { + return null; + } + } + + InputStream is = getter.getIs(); + if (is == null) + return null; + + pi.setText("Downloading List of Plugins"); + File temp = File.createTempFile("temp", "", new File (PathManagerEx.getPluginTempPath())); + try { + FileOutputStream fos = new FileOutputStream(temp, false); + ProgressStream ps = new ProgressStream(is, + ProgressManager.getInstance().getProgressIndicator()); + byte [] buffer = new byte [1024]; + do { + int size = ps.read(buffer); + if (size == -1) + break; + fos.write(buffer, 0, size); + } while (true); + fos.close(); + + parser.parse(temp, handler); + } finally { + temp.delete(); + } + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof InterruptedException) + return null; + else + throw e; + } + + return handler.getRoot(); + } + + private static InputStream getConnectionInputStream (URLConnection connection) { + final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + + pi.setText("Connecting..."); + InputStreamGetter getter = new InputStreamGetter(connection); + final Thread thread = new Thread (getter, "InputStreamGetter"); + thread.start(); + + while (! pi.isCanceled()) { + try { + thread.join(50); + + if (! thread.isAlive()) + break; + } + catch (InterruptedException e) { + return null; + } + } + + return getter.getIs(); + } + + public static File downloadPlugin (PluginNode pluginNode, boolean packet, long count, long available) throws IOException { + ApplicationInfoEx ideInfo = (ApplicationInfoEx)ApplicationInfo.getInstance(); + String buildNumber = ""; + try { + buildNumber = Integer.valueOf(ideInfo.getBuildNumber()).toString(); + } catch (NumberFormatException e) { + buildNumber = "3000"; + } + + String url = DOWNLOAD_URL + + URLEncoder.encode(pluginNode.getName(), "UTF8") + + "&build=" + buildNumber; + HttpURLConnection connection = (HttpURLConnection)new URL (url).openConnection(); + final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + + InputStream is = getConnectionInputStream(connection); + + if (is == null) + return null; + + pi.setText("Downloading plugin '" + pluginNode.getName() + "'"); + File file = File.createTempFile("plugin", "download", + new File (PathManagerEx.getPluginTempPath())); + FileOutputStream fos = new FileOutputStream(file, false); + + int responseCode = connection.getResponseCode(); + switch (responseCode) { + case HttpURLConnection.HTTP_OK: + break; + default: + // some problems + throw new IOException("Connection failed with HTTP code " + responseCode); + } + + if (pluginNode.getSize().equals("-1")) { + if (connection.getContentLength() == -1) + pi.setIndeterminate(true); + else + pluginNode.setSize(Integer.toString(connection.getContentLength())); + } + + boolean cleanFile = true; + + try { + is = new ProgressStream(packet ? count : 0, packet ? available : Integer.valueOf(pluginNode.getSize()).intValue(), + is, pi); + int c; + while ((c = is.read()) != -1) { + if (pi.isCanceled()) + throw new RuntimeException(new InterruptedException()); + + fos.write(c); + } + + cleanFile = false; + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof InterruptedException) + return null; + else + throw e; + } finally { + fos.close(); + if (cleanFile) + file.delete(); + } + + String fileName = null; + String contentDisposition = connection.getHeaderField("Content-Disposition"); + if (contentDisposition == null) { + // try to find filename in URL + String usedURL = connection.getURL().toString(); + int startPos = usedURL.lastIndexOf("/"); + + fileName = usedURL.substring(startPos + 1); + + } else { + int startIdx = contentDisposition.indexOf(FILENAME); + if (startIdx != -1) + fileName = contentDisposition.substring(startIdx + FILENAME.length(), contentDisposition.length() - 1); + else + throw new IllegalArgumentException(contentDisposition); + } + + connection.disconnect(); + + File newFile = new File (file.getParentFile(), fileName); + file.renameTo(newFile); + + return newFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/SortableProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/SortableProvider.java new file mode 100644 index 00000000000..3cc2f481004 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/SortableProvider.java @@ -0,0 +1,15 @@ +package com.intellij.ide.plugins; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 26, 2003 + * Time: 4:31:57 PM + * To change this template use Options | File Templates. + */ +public interface SortableProvider { + int getSortOrder (); + void setSortOrder (int sortOrder); + int getSortColumn (); + void setSortColumn (int sortColumn); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/cl/PluginClassLoader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/cl/PluginClassLoader.java new file mode 100644 index 00000000000..e0c2af065a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/plugins/cl/PluginClassLoader.java @@ -0,0 +1,136 @@ +/* + * @author: Eugene Zhuravlev + * Date: Mar 6, 2003 + * Time: 12:10:11 PM + */ +package com.intellij.ide.plugins.cl; + +import com.intellij.ide.plugins.PluginManager; +import sun.misc.CompoundEnumeration; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Enumeration; +import java.util.List; + +public class PluginClassLoader extends IdeaClassLoader{ + private final ClassLoader[] myParents; + private final String myPluginName; + private final File myLibDirectory; + + public PluginClassLoader(List urls, ClassLoader[] parents, String pluginName, File pluginRoot) { + super(urls, null); + myParents = parents; + myPluginName = pluginName; + + final File file = new File(pluginRoot, "lib"); + myLibDirectory = file.exists()? file : null; + } + + // changed sequence in which classes are searched, this is essential if plugin uses library, a different version of which + // is used in IDEA. + protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + PluginManager.addPluginClass(c.getName(), myPluginName); + } + catch (ClassNotFoundException e) { + for (int idx = 0; idx < myParents.length; idx++) { + try { + c = myParents[idx].loadClass(name); + break; + } + catch (ClassNotFoundException ignoreAndContinue) { + } + } + if (c == null) { + throw new ClassNotFoundException(name); + } + } + } + if (resolve) { + resolveClass(c); + } + + + return c; + } + + public URL findResource(final String name) { + final URL resource = super.findResource(name); + if (resource != null) { + return resource; + } + for (int idx = 0; idx < myParents.length; idx++) { + final URL parentResource = fetchResource(myParents[idx], name); + if (parentResource != null) { + return parentResource; + } + } + return null; + } + + public Enumeration findResources(final String name) throws IOException { + final Enumeration[] resources = new Enumeration[myParents.length + 1]; + resources[0] = super.findResources(name); + for (int idx = 0; idx < myParents.length; idx++) { + resources[idx + 1] = fetchResources(myParents[idx], name); + } + return new CompoundEnumeration(resources); + } + + protected String findLibrary(String libName) { + if (myLibDirectory == null) { + return null; + } + final File libraryFile = new File(myLibDirectory, System.mapLibraryName(libName)); + return libraryFile.exists()? libraryFile.getAbsolutePath() : null; + } + + + private URL fetchResource(ClassLoader cl, String resourceName) { + //protected URL findResource(String s) + try { + final Method findResourceMethod = cl.getClass().getDeclaredMethod("findResource", new Class[] {String.class}); + findResourceMethod.setAccessible(true); + return (URL)findResourceMethod.invoke(cl, new Object[] {resourceName}); + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private Enumeration fetchResources(ClassLoader cl, String resourceName) { + //protected Enumeration findResources(String s) throws IOException + try { + final Method findResourceMethod = getFindResourceMethod(cl.getClass()); + if (findResourceMethod == null) { + return null; + } + findResourceMethod.setAccessible(true); + return (Enumeration)findResourceMethod.invoke(cl, new Object[] {resourceName}); + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private Method getFindResourceMethod(final Class clClass) { + try { + return clClass.getDeclaredMethod("findResources", new Class[] {String.class}); + } + catch (NoSuchMethodException e) { + final Class superclass = clClass.getSuperclass(); + if (superclass == null || superclass.equals(Object.class)) { + return null; + } + return getFindResourceMethod(superclass); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/BaseProjectTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/BaseProjectTreeBuilder.java new file mode 100644 index 00000000000..cf3a9ac53f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/BaseProjectTreeBuilder.java @@ -0,0 +1,118 @@ +package com.intellij.ide.projectView; + +import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public abstract class BaseProjectTreeBuilder extends AbstractTreeBuilder { + protected final Project myProject; + + public BaseProjectTreeBuilder(Project project, JTree tree, DefaultTreeModel treeModel, ProjectAbstractTreeStructureBase treeStructure, Comparator comparator) { + super(tree, treeModel, treeStructure, comparator); + myProject = project; + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return ((AbstractTreeNode)nodeDescriptor).isAlwaysShowPlus(); + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + return nodeDescriptor.getParentDescriptor() == null; + } + + protected final void expandNodeChildren(final DefaultMutableTreeNode node) { + Object element = ((NodeDescriptor)node.getUserObject()).getElement(); + VirtualFile[] virtualFiles = getFilesToRefresh(element); + super.expandNodeChildren(node); + for (int i = 0; i < virtualFiles.length; i++) { + VirtualFile virtualFile = virtualFiles[i]; + virtualFile.refresh(true, false); + } + } + + protected static final VirtualFile[] getFilesToRefresh(Object element) { + final VirtualFile virtualFile; + if (element instanceof PsiDirectory){ + virtualFile = ((PsiDirectory)element).getVirtualFile(); + } + else if (element instanceof PsiFile){ + virtualFile = ((PsiFile)element).getVirtualFile(); + } + else{ + virtualFile = null; + } + return virtualFile != null ? new VirtualFile[]{virtualFile} : VirtualFile.EMPTY_ARRAY; + } + + public List getOrBuildChildren(AbstractTreeNode parent) { + buildNodeForElement(parent); + + DefaultMutableTreeNode node = getNodeForElement(parent); + myTree.expandPath(new TreePath(node.getPath())); + //expandNodeChildren(node); + + if (node == null) { + return new ArrayList(); + } + + List result = new ArrayList(); + for (int i = 0; i < node.getChildCount(); i++) { + javax.swing.tree.TreeNode childAt = node.getChildAt(i); + DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode)childAt; + if (defaultMutableTreeNode.getUserObject() instanceof AbstractTreeNode) { + ProjectViewNode treeNode = (ProjectViewNode)defaultMutableTreeNode.getUserObject(); + result.add(treeNode); + } + } + + return result; + } + + public void hideChildrenFor(AbstractTreeNode node) { + DefaultMutableTreeNode treeNode = getNodeForElement(node); + if (treeNode != null){ + getTree().collapsePath(new TreePath(treeNode.getPath())); + } + } + + public void select(Object element, VirtualFile file, boolean requestFocus, BaseProjectTreeBuilder treeBuilder) { + AbstractTreeNode node = select((AbstractTreeNode)getTreeStructure().getRootElement(), file, element); + TreeUtil.selectInTree(getNodeForElement(node), requestFocus, getTree()); + } + + private AbstractTreeNode select(AbstractTreeNode current, VirtualFile file, Object element) { + if (Comparing.equal(current.getValue(), element)) return current; + + if (current instanceof ProjectViewNode && !(((ProjectViewNode)current).contains(file))) return null; + + List kids = getOrBuildChildren(current); + for (int i = 0; i < kids.size(); i++) { + AbstractTreeNode node = kids.get(i); + AbstractTreeNode result = select(node, file, element); + if (result != null) { + return result; + } + else { + hideChildrenFor(node); + } + } + + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/CompositePsiClasChildrenSource.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/CompositePsiClasChildrenSource.java new file mode 100644 index 00000000000..20feeb8c2ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/CompositePsiClasChildrenSource.java @@ -0,0 +1,21 @@ +package com.intellij.ide.projectView; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; + +import java.util.List; + +public class CompositePsiClasChildrenSource implements PsiClassChildrenSource { + private final PsiClassChildrenSource[] mySources; + + public CompositePsiClasChildrenSource(PsiClassChildrenSource[] sources) { + mySources = sources; + } + + public void addChildren(PsiClass psiClass, List children) { + for (int i = 0; i < mySources.length; i++) { + PsiClassChildrenSource source = mySources[i]; + source.addChildren(psiClass, children); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/HelpID.java new file mode 100644 index 00000000000..32de563dcb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/HelpID.java @@ -0,0 +1,5 @@ +package com.intellij.ide.projectView; + +public interface HelpID { + String PROJECT_VIEWS = "viewingStructure.projectViews"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectView.java new file mode 100644 index 00000000000..fb4de0c7443 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectView.java @@ -0,0 +1,59 @@ +package com.intellij.ide.projectView; + +import com.intellij.ide.projectView.impl.AbstractProjectViewPane; +import com.intellij.ide.projectView.impl.ModuleGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; + +public abstract class ProjectView { + public static ProjectView getInstance(Project project) { + return project.getComponent(ProjectView.class); + } + + public abstract void select(Object element, VirtualFile file, boolean requestFocus); + + public abstract PsiElement getParentOfCurrentSelection(); + + public abstract void changeView(String viewId); + + public abstract void changeView(); + + public abstract void refresh(); + + public abstract boolean isAutoscrollToSource(String paneId); + + public abstract boolean isFlattenPackages(String paneId); + + public abstract boolean isShowMembers(String paneId); + + public abstract boolean isHideEmptyMiddlePackages(String paneId); + + public abstract void setHideEmptyPackages(boolean hideEmptyPackages, String paneId); + + public abstract boolean isShowLibraryContents(String paneId); + + public abstract void setShowLibraryContents(boolean showLibraryContents, String paneId); + + public abstract boolean isShowModules(String paneId); + + public abstract void setShowModules(boolean showModules, String paneId); + + public abstract void addProjectPane(final AbstractProjectViewPane pane); + + public abstract void removeProjectPane(AbstractProjectViewPane instance); + + public abstract AbstractProjectViewPane getProjectViewPaneById(String id); + + public abstract boolean isAutoscrollFromSource(String paneId); + + public abstract boolean isAbbreviatePackageNames(String paneId); + + public abstract void setAbbreviatePackageNames(boolean abbreviatePackageNames, String paneId); + + public abstract String getCurrentViewId(); + + public abstract void selectPsiElement(PsiElement element, boolean requestFocus); + + public abstract void selectModuleGroup(ModuleGroup moduleGroup, boolean requestFocus); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java new file mode 100644 index 00000000000..e3a149ba308 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java @@ -0,0 +1,96 @@ +package com.intellij.ide.projectView; + +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.psi.*; + +import javax.swing.tree.DefaultMutableTreeNode; + +public abstract class ProjectViewPsiTreeChangeListener extends PsiTreeChangeAdapter { + protected abstract AbstractTreeUpdater getUpdater(); + + protected abstract boolean isFlattenPackages(); + + protected abstract DefaultMutableTreeNode getRootNode(); + + public final void childRemoved(PsiTreeChangeEvent event) { + PsiElement child = event.getOldChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getParent()); + } + + public final void childAdded(PsiTreeChangeEvent event) { + PsiElement child = event.getNewChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getParent()); + } + + public final void childReplaced(PsiTreeChangeEvent event) { + PsiElement oldChild = event.getOldChild(); + PsiElement newChild = event.getNewChild(); + if (oldChild instanceof PsiWhiteSpace && newChild instanceof PsiWhiteSpace) return; //optimization + if (oldChild instanceof PsiCodeBlock && newChild instanceof PsiCodeBlock) return; //optimization + childrenChanged(event.getParent()); + } + + public final void childMoved(PsiTreeChangeEvent event) { + childrenChanged(event.getOldParent()); + childrenChanged(event.getNewParent()); + } + + public final void childrenChanged(PsiTreeChangeEvent event) { + childrenChanged(event.getParent()); + } + + private void childrenChanged(PsiElement parent) { + if (parent instanceof PsiDirectory && isFlattenPackages()){ + getUpdater().addSubtreeToUpdate(getRootNode()); + return; + } + + while(true){ + if (parent == null) break; + if (parent instanceof PsiCodeBlock) break; + if (parent instanceof PsiFile){ + parent = ((PsiFile)parent).getContainingDirectory(); + if (parent == null) break; + } + + if (getUpdater().addSubtreeToUpdateByElement(parent)){ + break; + } + + if (parent instanceof PsiMethod + || parent instanceof PsiField + || parent instanceof PsiClass + || parent instanceof PsiFile + || parent instanceof PsiDirectory) break; + parent = parent.getParent(); + } + } + + public final void propertyChanged(PsiTreeChangeEvent event) { + String propertyName = event.getPropertyName(); + PsiElement element = event.getElement(); + DefaultMutableTreeNode rootNode = getRootNode(); + AbstractTreeUpdater updater = getUpdater(); + if (propertyName.equals(PsiTreeChangeEvent.PROP_ROOTS)) { + updater.addSubtreeToUpdate(rootNode); + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_WRITABLE)){ + if (!updater.addSubtreeToUpdateByElement(element) && element instanceof PsiJavaFile) { + updater.addSubtreeToUpdateByElement(((PsiJavaFile)element).getContainingDirectory()); + } + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_NAME) || propertyName.equals(PsiTreeChangeEvent.PROP_DIRECTORY_NAME)){ + if (element instanceof PsiDirectory && isFlattenPackages()){ + updater.addSubtreeToUpdate(rootNode); + return; + } + + updater.addSubtreeToUpdateByElement(element); + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_TYPES)){ + updater.addSubtreeToUpdate(rootNode); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/PsiClassChildrenSource.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/PsiClassChildrenSource.java new file mode 100644 index 00000000000..78e74a396da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/PsiClassChildrenSource.java @@ -0,0 +1,55 @@ +package com.intellij.ide.projectView; + +import com.intellij.aspects.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; + +import java.util.Arrays; +import java.util.List; + +public interface PsiClassChildrenSource { + void addChildren(PsiClass psiClass, List children); + + PsiClassChildrenSource NONE = new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, List children) { } + }; + + PsiClassChildrenSource METHODS = new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, List children) { + children.addAll(Arrays.asList(psiClass.getMethods())); + } + }; + + PsiClassChildrenSource FIELDS = new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, List children) { + children.addAll(Arrays.asList(psiClass.getFields())); + } + }; + + PsiClassChildrenSource CLASSES = new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, List children) { + children.addAll(Arrays.asList(psiClass.getInnerClasses())); + } + }; + + PsiClassChildrenSource ASPECT_CHILDREN = new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, List children) { + if (!(psiClass instanceof PsiAspect)) return; + PsiAspect aspect = (PsiAspect)psiClass; + PsiAdvice[] advices = aspect.getAdvices(); + PsiIntertypeDeclaration[] intertypeDeclarations = aspect.getIntertypeDeclarations(); + PsiIntroduction[] introductions = aspect.getIntroductions(); + PsiPointcutDef[] pointcutDefs = aspect.getPointcutDefs(); + children.addAll(Arrays.asList(advices)); + children.addAll(Arrays.asList(intertypeDeclarations)); + children.addAll(Arrays.asList(introductions)); + children.addAll(Arrays.asList(pointcutDefs)); + } + }; + + PsiClassChildrenSource DEFAULT_CHILDREN = new CompositePsiClasChildrenSource( + new PsiClassChildrenSource[]{CLASSES, + METHODS, + FIELDS, + ASPECT_CHILDREN}); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ChangeProjectViewAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ChangeProjectViewAction.java new file mode 100644 index 00000000000..80c788203d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ChangeProjectViewAction.java @@ -0,0 +1,32 @@ +package com.intellij.ide.projectView.actions; + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; + +public final class ChangeProjectViewAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + return; + } + ProjectView projectView = ProjectView.getInstance(project); + projectView.changeView(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null){ + presentation.setEnabled(false); + return; + } + String id = ToolWindowManager.getInstance(project).getActiveToolWindowId(); + presentation.setEnabled(ToolWindowId.PROJECT_VIEW.equals(id)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ProjectViewActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ProjectViewActionGroup.java new file mode 100644 index 00000000000..cc1f286bdd2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/actions/ProjectViewActionGroup.java @@ -0,0 +1,24 @@ +package com.intellij.ide.projectView.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; + +public final class ProjectViewActionGroup extends DefaultActionGroup { + public ProjectViewActionGroup() { + super(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + return; + } + String id = ToolWindowManager.getInstance(project).getActiveToolWindowId(); + boolean isProjectViewActive = ToolWindowId.PROJECT_VIEW.equals(id); + presentation.setVisible(isProjectViewActive); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectTreeStructure.java new file mode 100644 index 00000000000..48c03716af7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectTreeStructure.java @@ -0,0 +1,46 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; + +public abstract class AbstractProjectTreeStructure extends ProjectAbstractTreeStructureBase implements ViewSettings { + + private AbstractTreeNode myRoot; + + public AbstractProjectTreeStructure(Project project) { + super(project); + myRoot = new ProjectViewProjectNode(myProject, this); + } + + interface RootCreator { + AbstractTreeNode createRoot(Project project, ViewSettings settings); + } + + protected AbstractProjectTreeStructure(Project project, final RootCreator rootCreator) { + super(project); + myRoot = rootCreator.createRoot(project, this); + } + + public abstract boolean isShowMembers(); + + public final Object getRootElement() { + return myRoot; + } + + + public final void commit() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + } + + public final boolean hasSomethingToCommit() { + return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments(); + } + + public boolean isStructureView() { + return false; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java new file mode 100644 index 00000000000..38d576d2080 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java @@ -0,0 +1,280 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.DataManager; +import com.intellij.ide.SelectInManager; +import com.intellij.ide.impl.ProjectViewSelectInTarget; +import com.intellij.ide.projectView.BaseProjectTreeBuilder; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.AlphaComparator; +import com.intellij.ide.util.treeView.TreeBuilderUtil; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.StringTokenizer; + +public abstract class AbstractProjectViewPSIPane extends AbstractProjectViewPane { + protected JScrollPane myComponent; + + protected AbstractProjectViewPSIPane(Project project) { + super(project); + myExpandedElements.registerExpandedElementProvider(new ClassUrl(null, null)); + myExpandedElements.registerExpandedElementProvider(new ModuleUrl(null, null)); + myExpandedElements.registerExpandedElementProvider(new DirectoryUrl(null, null)); + } + + protected final void initPSITree() { + myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.expandPath(new TreePath(myTree.getModel().getRoot())); + myTree.setSelectionPath(new TreePath(myTree.getModel().getRoot())); + + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_PROJECT_VIEW_POPUP); + PopupHandler.installPopupHandler(myTree, group, ActionPlaces.PROJECT_VIEW_POPUP, ActionManager.getInstance()); + + EditSourceOnDoubleClickHandler.install(myTree); + + TreeToolTipHandler.install(myTree); + TreeUtil.installActions(myTree); + + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + fireTreeChangeListener(); + } + }); + myTree.getModel().addTreeModelListener(new TreeModelListener() { + public void treeNodesChanged(TreeModelEvent e) { + fireTreeChangeListener(); + } + + public void treeNodesInserted(TreeModelEvent e) { + fireTreeChangeListener(); + } + + public void treeNodesRemoved(TreeModelEvent e) { + fireTreeChangeListener(); + } + + public void treeStructureChanged(TreeModelEvent e) { + fireTreeChangeListener(); + } + }); + + new MySpeedSearch(myTree); + + myTree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (KeyEvent.VK_ENTER == e.getKeyCode()) { + + DataContext dataContext = DataManager.getInstance().getDataContext(myTree); + Navigatable navigatable = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(false); + } + } + else if (KeyEvent.VK_ESCAPE == e.getKeyCode()) { + if (e.isConsumed()) return; + CopyPasteManagerEx copyPasteManager = (CopyPasteManagerEx)CopyPasteManager.getInstance(); + boolean[] isCopied = new boolean[1]; + if (copyPasteManager.getElements(isCopied) != null && !isCopied[0]) { + copyPasteManager.clear(); + e.consume(); + } + } + } + }); + + myExpandedElements.restoreExpandedElements(this, myProject); + } + + public final void expand(Object[] path) { + myTreeBuilder.buildNodeForPath(path); + DefaultMutableTreeNode node = myTreeBuilder.getNodeForPath(path); + if (node == null) { + if (path.length != 0) { + expand(path[path.length - 1]); + } + return; + } + TreePath treePath = new TreePath(node.getPath()); + myTree.expandPath(treePath); + } + + public final void expand(Object element) { + myTreeBuilder.buildNodeForElement(element); + DefaultMutableTreeNode node = myTreeBuilder.getNodeForElement(element); + if (node == null) { + return; + } + TreePath treePath = new TreePath(node.getPath()); + myTree.expandPath(treePath); + } + + public final void dispose() { + myTreeBuilder.dispose(); + } + + public final void updateFromRoot(boolean restoreExpandedPaths) { + final ArrayList pathsToExpand = new ArrayList(); + final ArrayList selectionPaths = new ArrayList(); + if (restoreExpandedPaths) { + TreeBuilderUtil.storePaths(myTreeBuilder, (DefaultMutableTreeNode)myTree.getModel().getRoot(), pathsToExpand, selectionPaths, true); + } + myTreeBuilder.updateFromRoot(); + if (restoreExpandedPaths) { + myTree.setSelectionPaths(new TreePath[0]); + TreeBuilderUtil.restorePaths(myTreeBuilder, pathsToExpand, selectionPaths, true); + } + } + + public void select(Object element, VirtualFile file, boolean requestFocus) { + myTreeBuilder.select(element, file, requestFocus, myTreeBuilder); + } + + public final void selectModule(Module module, boolean requestFocus) { + } + + public final TreePath[] getSelectionPaths() { + return myTree.getSelectionPaths(); + } + + public final void installAutoScrollToSourceHandler(AutoScrollToSourceHandler autoScrollToSourceHandler) { + autoScrollToSourceHandler.install(myTree); + } + + public void initTree() { + DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(null); + DefaultTreeModel treeModel = new DefaultTreeModel(rootNode); + myTree = createTree(treeModel); + myComponent = new JScrollPane(myTree); + myComponent.setBorder(BorderFactory.createEmptyBorder()); + myTreeStructure = createStructure(); + myTreeBuilder = createBuilder(treeModel); + + SelectInManager selectInManager = SelectInManager.getInstance(myProject); + selectInManager.addTarget(createSelectInTarget()); + + initPSITree(); + } + + protected abstract ProjectViewSelectInTarget createSelectInTarget(); + + protected BaseProjectTreeBuilder createBuilder(DefaultTreeModel treeModel) { + return new ProjectTreeBuilder(myProject, myTree, treeModel, AlphaComparator.INSTANCE, + (ProjectAbstractTreeStructureBase)myTreeStructure) { + protected AbstractTreeUpdater createUpdater() { + return createTreeUpdater(this); + } + + }; + } + + protected abstract ProjectAbstractTreeStructureBase createStructure(); + + protected abstract ProjectViewTree createTree(DefaultTreeModel treeModel); + + public void projectOpened() { + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + initTree(); + final ProjectView projectView = + ProjectView.getInstance(myProject); + projectView.addProjectPane(AbstractProjectViewPSIPane.this); + } + }); + } + + public void projectClosed() { + dispose(); + } + + public void initComponent() { } + + public void disposeComponent() { + + } + + protected abstract AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder); + + public JTree getTree() { + return myTree; + } + + + protected static final class MySpeedSearch extends TreeSpeedSearch { + MySpeedSearch(Tree tree) { + super(tree); + } + + protected boolean isMatchingElement(Object element, String pattern) { + Object userObject = ((DefaultMutableTreeNode)((TreePath)element).getLastPathComponent()).getUserObject(); + if (userObject instanceof PsiDirectoryNode) { + String str = getElementText(element); + if (str == null) return false; + str = str.toLowerCase(); + if (pattern.indexOf('.') >= 0) { + return compare(str, pattern); + } + StringTokenizer tokenizer = new StringTokenizer(str, "."); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if (compare(token, pattern)) { + return true; + } + } + return false; + } + else { + return super.isMatchingElement(element, pattern); + } + } + } + + public JComponent getComponent() { + return myComponent; + } + + public void readExternal(Element viewElement) throws InvalidDataException { + myExpandedElements.readExternal(viewElement); + } + + public void writeExternal(Element viewElement) { + new ExpandedElements(getExpandedUrls()).writeExternal(viewElement); + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java new file mode 100644 index 00000000000..1b2dd35b9f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java @@ -0,0 +1,167 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.BaseProjectTreeBuilder; +import com.intellij.ide.projectView.impl.nodes.PackageElement; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import com.intellij.ui.AutoScrollFromSourceHandler; +import com.intellij.ui.AutoScrollToSourceHandler; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.List; + + +public abstract class AbstractProjectViewPane implements JDOMExternalizable, DataProvider { + protected final Project myProject; + protected Runnable myTreeChangeListener; + protected ProjectViewTree myTree; + protected AbstractTreeStructure myTreeStructure; + protected BaseProjectTreeBuilder myTreeBuilder; + protected final ExpandedElements myExpandedElements = new ExpandedElements(); + + protected final void fireTreeChangeListener() { + if (myTreeChangeListener != null) myTreeChangeListener.run(); + } + + public final void setTreeChangeListener(Runnable listener) { + myTreeChangeListener = listener; + } + public final void removeTreeChangeListener() { + myTreeChangeListener = null; + } + + protected AbstractProjectViewPane(Project project) { + myProject = project; + } + + public abstract String getTitle(); + public abstract Icon getIcon(); + public abstract String getId(); + public abstract JComponent getComponent(); + public JComponent getComponentToFocus() { + return myTree; + } + public abstract void expand(final Object[] path); + public abstract void expand(final Object element); + public abstract void dispose(); + public abstract void updateFromRoot(boolean restoreExpandedPaths); + public abstract void select(Object element, VirtualFile file, boolean requestFocus); + + public abstract TreePath[] getSelectionPaths(); + public abstract void installAutoScrollToSourceHandler(AutoScrollToSourceHandler autoScrollToSourceHandler); + + public void installAutoScrollFromSourceHandler(AutoScrollFromSourceHandler autoScrollFromSourceHandler) { + autoScrollFromSourceHandler.install(); + } + + protected final List getExpandedUrls(){ + return myExpandedElements.getExpandedUrls(myTree, myProject); + } + + public void addToolbarActions(DefaultActionGroup actionGroup) { + } + public Object getData(String dataId) { + if (DataConstants.NAVIGATABLE.equals(dataId)){ + Object selectedElement = getSelectedElement(); + if (selectedElement instanceof Navigatable){ + return selectedElement; + } + } + return null; + } + + // used for sorting tabs in the tabbed pane + public int getWeight() { + return 0; + } + + public final TreePath getSelectedPath() { + final TreePath[] paths = getSelectionPaths(); + if (paths != null && paths.length == 1) return paths[0]; + return null; + } + + public final NodeDescriptor getSelectedDescriptor() { + final DefaultMutableTreeNode node = getSelectedNode(); + if (node == null) return null; + Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + return (NodeDescriptor)userObject; + } + return null; + } + public final DefaultMutableTreeNode getSelectedNode() { + TreePath path = getSelectedPath(); + if (path == null) { + return null; + } + Object lastPathComponent = path.getLastPathComponent(); + if (!(lastPathComponent instanceof DefaultMutableTreeNode)) { + return null; + } + return (DefaultMutableTreeNode)lastPathComponent; + } + + public final Object getSelectedElement() { + final Object[] elements = getSelectedElements(); + if (elements.length == 1) return elements[0]; + return null; + } + public final PsiElement[] getSelectedPSIElements() { + final Object[] elements = getSelectedElements(); + List psiElements = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + if (element instanceof PsiElement) { + psiElements.add((PsiElement)element); + } else if (element instanceof PackageElement) { + PsiPackage aPackage = ((PackageElement)element).getPackage(); + if (aPackage != null) { + psiElements.add(aPackage); + } + } + } + return psiElements.toArray(new PsiElement[psiElements.size()]); + } + public final Object[] getSelectedElements() { + TreePath[] paths = getSelectionPaths(); + if (paths == null) return PsiElement.EMPTY_ARRAY; + ArrayList list = new ArrayList(paths.length); + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + Object lastPathComponent = path.getLastPathComponent(); + if (lastPathComponent instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)lastPathComponent; + Object userObject = node.getUserObject(); + if (userObject instanceof AbstractTreeNode) { + AbstractTreeNode descriptor = (AbstractTreeNode)userObject; + Object element = descriptor.getValue(); + list.add(element); + } else if (userObject instanceof NodeDescriptor) { + NodeDescriptor descriptor = (NodeDescriptor)userObject; + Object element = descriptor.getElement(); + list.add(element); + } + + } + } + return list.toArray(new Object[list.size()]); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractUrl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractUrl.java new file mode 100644 index 00000000000..4be5a17fe2c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/AbstractUrl.java @@ -0,0 +1,39 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.project.Project; +import org.jdom.Element; + +/** + * @author cdr + */ +public abstract class AbstractUrl { + protected final String url; + protected final String moduleName; + private final String myType; + + protected AbstractUrl(String url, String moduleName, String type) { + myType = type; + this.url = url == null ? "" : url; + this.moduleName = moduleName; + } + + public void write(Element element) { + element.setAttribute("url", url); + if (moduleName != null) { + element.setAttribute("module", moduleName); + } + element.setAttribute("type", myType); + } + + public abstract Object[] createPath(Project project); + + // return null if cannot recognize the element + public AbstractUrl checkMyUrl(String type, String moduleName, String url){ + if (type.equals(myType)) { + return createUrl(moduleName, url); + } + return null; + } + protected abstract AbstractUrl createUrl(String moduleName, String url); + public abstract AbstractUrl createUrlByElement(Object element); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java new file mode 100644 index 00000000000..179bab85d30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java @@ -0,0 +1,65 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.ClassTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaFile; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class ClassesTreeStructureProvider implements TreeStructureProvider, ProjectComponent { + private final Project myProject; + + public ClassesTreeStructureProvider(Project project) { + myProject = project; + } + + public Collection modify(AbstractTreeNode parent, Collection children, ViewSettings settings) { + ArrayList result = new ArrayList(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + ProjectViewNode treeNode = (ProjectViewNode)iterator.next(); + Object o = treeNode.getValue(); + if (o instanceof PsiJavaFile) { + PsiJavaFile psiJavaFile = ((PsiJavaFile)o); + PsiClass[] classes = psiJavaFile.getClasses(); + if (classes.length != 0) { + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + result.add(new ClassTreeNode(myProject,aClass, ((ProjectViewNode)parent).getSettings())); + } + } + else { + result.add(treeNode); + } + } + else { + result.add(treeNode); + } + } + return result; + } + + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "ClassesTreeStructureProvider"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/DirectoryUrl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/DirectoryUrl.java new file mode 100644 index 00000000000..7fbc7ba5eca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/DirectoryUrl.java @@ -0,0 +1,48 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; + +/** + * @author cdr + */ +public class DirectoryUrl extends AbstractUrl { + private static final String ELEMENT_TYPE = "directory"; + + public DirectoryUrl(String url, String moduleName) { + super(url, moduleName,ELEMENT_TYPE); + } + + public Object[] createPath(Project project) { + final Module module = moduleName != null ? ModuleManager.getInstance(project).findModuleByName(moduleName) : null; + if (module == null) return null; + final VirtualFileManager virtualFileManager = VirtualFileManager.getInstance(); + VirtualFile file = virtualFileManager.findFileByUrl(url); + if (file == null) return null; + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(file); + if (directory == null) return null; + return new Object[]{directory}; + } + + protected AbstractUrl createUrl(String moduleName, String url) { + return new DirectoryUrl(url, moduleName); + } + + public AbstractUrl createUrlByElement(Object element) { + if (element instanceof PsiDirectory) { + Project project = ((PsiDirectory)element).getProject(); + final VirtualFile virtualFile = ((PsiDirectory)element).getVirtualFile(); + if (virtualFile == null) return null; + final Module module = ModuleUtil.getModuleForFile(project, virtualFile); + if (module == null) return null; + return new DirectoryUrl(virtualFile.getUrl(), module.getName()); + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/FormMergerTreeStructureProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/FormMergerTreeStructureProvider.java new file mode 100644 index 00000000000..39fa575b06a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/FormMergerTreeStructureProvider.java @@ -0,0 +1,82 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.Form; +import com.intellij.ide.projectView.impl.nodes.FormNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; + +import java.util.*; + +public class FormMergerTreeStructureProvider implements TreeStructureProvider, ProjectComponent{ + private final Project myProject; + + public FormMergerTreeStructureProvider(Project project) { + myProject = project; + } + + public Collection modify(AbstractTreeNode parent, Collection children, ViewSettings settings) { + if (parent.getValue() instanceof Form) return children; + ArrayList result = new ArrayList(); + ProjectViewNode[] copy = children.toArray(new ProjectViewNode[children.size()]); + for (int i = 0; i < copy.length; i++) { + ProjectViewNode element = copy[i]; + if (element.getValue() instanceof PsiClass){ + PsiClass aClass = ((PsiClass)element.getValue()); + PsiFile[] forms = aClass.getManager().getSearchHelper().findFormsBoundToClass(aClass.getQualifiedName()); + Collection formNodes = findFormsIn(children, forms); + if (formNodes.size() > 0) { + Collection formFiles = convertToFiles(formNodes); + Collection subNodes = new ArrayList(formNodes); + subNodes.add(element); + result.add(new FormNode(myProject, new Form(aClass, formFiles), settings, subNodes)); + children.remove(element); + children.removeAll(formNodes); + } + } + } + result.addAll(children); + return result; + } + + private Collection convertToFiles(Collection formNodes) { + ArrayList psiFiles = new ArrayList(); + for (Iterator iterator = formNodes.iterator(); iterator.hasNext();) { + AbstractTreeNode treeNode = iterator.next(); + psiFiles.add((PsiFile)treeNode.getValue()); + } + return psiFiles; + } + + private Collection findFormsIn(Collection children, PsiFile[] forms) { + ArrayList result = new ArrayList(); + HashSet psiFiles = new HashSet(Arrays.asList(forms)); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + ProjectViewNode treeNode = (ProjectViewNode)iterator.next(); + if (psiFiles.contains(treeNode.getValue())) result.add(treeNode); + } + return result; + } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void disposeComponent() { + } + + public String getComponentName() { + return "FormNodesProvider"; + } + + public void initComponent() { + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleGroup.java new file mode 100644 index 00000000000..7650faf1bd1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleGroup.java @@ -0,0 +1,54 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.List; +import java.util.ArrayList; + +public class ModuleGroup { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.ModuleGroup"); + private final String myName; + + public ModuleGroup(String name) { + LOG.assertTrue(name != null); + myName = name; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ModuleGroup)) return false; + + final ModuleGroup moduleGroup = (ModuleGroup)o; + + if (!myName.equals(moduleGroup.myName)) return false; + + return true; + } + + public int hashCode() { + return myName.hashCode(); + } + + public String getName() { + return myName; + } + + public Module[] modulesInGroup(Project project) { + final Module[] modules = ModuleManager.getInstance(project).getModules(); + List result = new ArrayList(); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + String group = ModuleManager.getInstance(project).getModuleGroup(module); + if (myName.equals(group)) { + result.add(module); + } + } + return result.toArray(new Module[result.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleUrl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleUrl.java new file mode 100644 index 00000000000..811a8af1d67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ModuleUrl.java @@ -0,0 +1,34 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; + +/** + * @author cdr + */ +public class ModuleUrl extends AbstractUrl { + private static final String ELEMENT_TYPE = "module"; + + public ModuleUrl(String url, String moduleName) { + super(url, moduleName,ELEMENT_TYPE); + } + + public Object[] createPath(Project project) { + final Module module = moduleName != null ? ModuleManager.getInstance(project).findModuleByName(moduleName) : null; + if (module == null) return null; + return new Object[]{module}; + } + + protected AbstractUrl createUrl(String moduleName, String url) { + return new ModuleUrl(url, moduleName); + } + + public AbstractUrl createUrlByElement(Object element) { + if (element instanceof Module) { + Module module = (Module)element; + return new ModuleUrl("", module.getName()); + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModuleToGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModuleToGroup.java new file mode 100644 index 00000000000..1470812478b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModuleToGroup.java @@ -0,0 +1,63 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MoveModuleToGroup extends ActionGroup { + public void update(AnActionEvent e){ + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstantsEx.PROJECT); + final Module[] modules = (Module[])dataContext.getData(DataConstantsEx.MODULE_CONTEXT_ARRAY); + boolean active = project != null && modules != null && modules.length != 0; + e.getPresentation().setVisible(active); + } + + public AnAction[] getChildren(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstantsEx.PROJECT); + final Module[] modules = (Module[])dataContext.getData(DataConstantsEx.MODULE_CONTEXT_ARRAY); + + String originalModuleGroup = null; + boolean allModulesInSameGroup = true; + for (int i = 0; i < modules.length; i++) { + final Module child = modules[i]; + String group = ModuleManager.getInstance(project).getModuleGroup(child); + if (originalModuleGroup == null) { + originalModuleGroup = group; + } + if (!Comparing.strEqual(group, originalModuleGroup)) { + allModulesInSameGroup = false; + } + } + + List result = new ArrayList(); + Module[] allModules = ModuleManager.getInstance(project).getModules(); + Set groups = new HashSet(); + for (int i = 0; i < allModules.length; i++) { + final Module child = allModules[i]; + String group = ModuleManager.getInstance(project).getModuleGroup(child); + if (group != null && !group.equals(originalModuleGroup) && groups.add(group)) { + result.add(new MoveModulesToGroupAction(modules, group, group)); + } + } + result.add(Separator.getInstance()); + + if (allModulesInSameGroup && originalModuleGroup != null) { + result.add(new MoveModulesToGroupAction(modules, "", "Outside Any Group")); + } + result.add(new MoveModulesToGroupAction(modules, null, "New Group...")); + return result.toArray(new AnAction[result.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModulesToGroupAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModulesToGroupAction.java new file mode 100644 index 00000000000..1a71a742d5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/MoveModulesToGroupAction.java @@ -0,0 +1,57 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; + +public class MoveModulesToGroupAction extends AnAction { + private final Module[] myModules; + private final String myGroupName; + + public MoveModulesToGroupAction(Module[] modules, String groupName, String title) { + super(title); + myModules = modules; + myGroupName = groupName; + Presentation presentation = getTemplatePresentation(); + String description = groupName == null ? "Create new module group" + : "Move "+whatToMove()+" to the group '"+groupName+"'"; + presentation.setDescription(description); + } + + private String whatToMove() { + String what = myModules.length == 1 ? "module '"+myModules[0].getName() +"'" : "modules"; + return what; + } + + public void actionPerformed(AnActionEvent e) { + String group = myGroupName; + if (myGroupName == null) { + String message = "Specify group the "+whatToMove()+" will be shown under.\n\n" + + "Leave the name blank to move module outside any group." + ; + group = Messages.showInputDialog(message, "Module Group", Messages.getQuestionIcon()); + if (group == null) return; + } + Project project = myModules[0].getProject(); + if ("".equals(group.trim())) { + group = null; + } + for (int i = 0; i < myModules.length; i++) { + final Module module = myModules[i]; + ModuleManagerImpl.getInstanceImpl(project).setModuleGroup(module, group); + } + ProjectView.getInstance(project).getProjectViewPaneById(ProjectViewPane.ID).updateFromRoot(true); + ProjectView.getInstance(project).getProjectViewPaneById(PackageViewPane.ID).updateFromRoot(true); + if (group != null) { + ProjectView.getInstance(project).selectModuleGroup(new ModuleGroup(group), true); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/PackageViewPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/PackageViewPane.java new file mode 100644 index 00000000000..7d19b7dac68 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/PackageViewPane.java @@ -0,0 +1,215 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.impl.PackageViewSelectInTarget; +import com.intellij.ide.impl.ProjectViewSelectInTarget; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.nodes.PackageElement; +import com.intellij.ide.projectView.impl.nodes.PackageUtil; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiPackage; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.util.HashSet; +import java.util.Set; + +public final class PackageViewPane extends AbstractProjectViewPSIPane implements ProjectComponent { + public static final String ID = "PackagesPane"; + private static final Icon ICON = IconLoader.getIcon("/general/packagesTab.png"); + + public PackageViewPane(Project project) { + super(project); + myExpandedElements.registerExpandedElementProvider(new PackageUrl(null,null)); + } + + public String getTitle() { + return "Packages"; + } + + public Icon getIcon() { + return ICON; + } + + public String getId() { + return ID; + } + + public AbstractTreeStructure getTreeStructure() { + return myTreeStructure; + } + + private final class ShowModulesAction extends ToggleAction { + private ShowModulesAction() { + super("Show Modules", "Show/Hide Modules", IconLoader.getIcon("/objectBrowser/showModules.png")); + } + + public boolean isSelected(AnActionEvent event) { + return ProjectView.getInstance(myProject).isShowModules(getId()); + } + + public void setSelected(AnActionEvent event, boolean flag) { + final ProjectViewImpl projectView = (ProjectViewImpl)ProjectView.getInstance(myProject); + projectView.setShowModules(flag, getId()); + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + final ProjectViewImpl projectView = (ProjectViewImpl)ProjectView.getInstance(myProject); + presentation.setVisible(projectView.getCurrentProjectViewPane() == PackageViewPane.this); + } + } + + private final class ShowLibraryContentsAction extends ToggleAction { + private ShowLibraryContentsAction() { + super("Show Libraries Contents", "Show/Hide Library Contents", IconLoader.getIcon("/objectBrowser/showLibraryContents.png")); + } + + public boolean isSelected(AnActionEvent event) { + return ProjectView.getInstance(myProject).isShowLibraryContents(getId()); + } + + public void setSelected(AnActionEvent event, boolean flag) { + final ProjectViewImpl projectView = (ProjectViewImpl)ProjectView.getInstance(myProject); + projectView.setShowLibraryContents(flag, getId()); + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + final ProjectViewImpl projectView = (ProjectViewImpl)ProjectView.getInstance(myProject); + presentation.setVisible(projectView.getCurrentProjectViewPane() == PackageViewPane.this); + } + } + + public void addToolbarActions(DefaultActionGroup actionGroup) { + actionGroup.add(new ShowModulesAction()); + actionGroup.add(new ShowLibraryContentsAction()); + } + + protected AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder) { + return new PackageViewTreeUpdater(treeBuilder); + } + + protected ProjectViewSelectInTarget createSelectInTarget() { + return new PackageViewSelectInTarget(myProject); + } + + protected ProjectAbstractTreeStructureBase createStructure() { + return new ProjectTreeStructure(myProject, ID); + } + + protected ProjectViewTree createTree(DefaultTreeModel treeModel) { + return new ProjectViewTree(treeModel) { + public String toString() { + return getTitle() + " " + super.toString(); + } + + public DefaultMutableTreeNode getSelectedNode() { + return PackageViewPane.this.getSelectedNode(); + } + }; + } + + public String getComponentName() { + return "PackagesPane"; + } + + public int getWeight() { + return 1; + } + + private final class PackageViewTreeUpdater extends AbstractTreeUpdater { + private PackageViewTreeUpdater(final AbstractTreeBuilder treeBuilder) { + super(treeBuilder); + } + + public boolean addSubtreeToUpdateByElement(Object element) { + // should convert PsiDirectories into PackageElements + if (element instanceof PsiDirectory) { + PsiDirectory dir = (PsiDirectory)element; + final PsiPackage aPackage = dir.getPackage(); + if (ProjectView.getInstance(myProject).isShowModules(getId())) { + Module[] modules = getModulesFor(dir); + boolean rv = false; + for (int idx = 0; idx < modules.length; idx++) { + rv |= addPackageElementToUpdate(aPackage, modules[idx]); + } + return rv; + } + else { + return addPackageElementToUpdate(aPackage, null); + } + } + + return super.addSubtreeToUpdateByElement(element); + } + + private boolean addPackageElementToUpdate(final PsiPackage aPackage, Module module) { + final ProjectTreeStructure packageTreeStructure = (ProjectTreeStructure)myTreeStructure; + PsiPackage packageToUpdateFrom = aPackage; + if (!packageTreeStructure.isFlattenPackages() && packageTreeStructure.isHideEmptyMiddlePackages()) { + // optimization: this check makes sense only if flattenPackages == false && HideEmptyMiddle == true + while (packageToUpdateFrom != null && packageToUpdateFrom.isValid() && PackageUtil.isPackageEmpty(packageToUpdateFrom, module, true, false)) { + packageToUpdateFrom = packageToUpdateFrom.getParentPackage(); + } + } + boolean addedOk; + while (!(addedOk = super.addSubtreeToUpdateByElement(getTreeElementToUpdateFrom(packageToUpdateFrom, module)))) { + if (packageToUpdateFrom == null) { + break; + } + packageToUpdateFrom = packageToUpdateFrom.getParentPackage(); + } + return addedOk; + } + + private Object getTreeElementToUpdateFrom(PsiPackage packageToUpdateFrom, Module module) { + if (packageToUpdateFrom == null || !packageToUpdateFrom.isValid() || "".equals(packageToUpdateFrom.getQualifiedName())) { + return module == null ? myTreeStructure.getRootElement() : module; + } + else { + return new PackageElement(module, packageToUpdateFrom, false); + } + } + + private Module[] getModulesFor(PsiDirectory dir) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final VirtualFile vFile = dir.getVirtualFile(); + final Set modules = new HashSet(); + final Module module = fileIndex.getModuleForFile(vFile); + if (module != null) { + modules.add(module); + } + if (fileIndex.isInLibrarySource(vFile) || fileIndex.isInLibraryClasses(vFile)) { + final OrderEntry[] orderEntries = fileIndex.getOrderEntriesForFile(vFile); + if (orderEntries.length == 0) { + return Module.EMPTY_ARRAY; + } + for (int j = 0; j < orderEntries.length; j++) { + modules.add(orderEntries[j].getOwnerModule()); + } + } + return modules.toArray(new Module[modules.size()]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectAbstractTreeStructureBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectAbstractTreeStructureBase.java new file mode 100644 index 00000000000..f90486726b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectAbstractTreeStructureBase.java @@ -0,0 +1,34 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.util.treeView.AbstractTreeStructureBase; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.util.Arrays; +import java.util.List; + +public abstract class ProjectAbstractTreeStructureBase extends AbstractTreeStructureBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.AbstractProjectTreeStructure"); + + private List myProviders; + + protected ProjectAbstractTreeStructureBase(Project project) { + super(project); + } + + public List getProviders() { + if (myProviders == null) { + return (List)myProject.getPicoContainer().getComponentInstancesOfType(TreeStructureProvider.class); + } + else { + return myProviders; + } + } + + public void setProviders(TreeStructureProvider[] treeStructureProviders) { + myProviders = treeStructureProviders == null ? null : Arrays.asList(treeStructureProviders); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java new file mode 100644 index 00000000000..92e9714865c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeBuilder.java @@ -0,0 +1,96 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.BaseProjectTreeBuilder; +import com.intellij.ide.projectView.ProjectViewPsiTreeChangeListener; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.util.Comparator; + +public class ProjectTreeBuilder extends BaseProjectTreeBuilder { + private final ProjectViewPsiTreeChangeListener myPsiTreeChangeListener; + private final ModuleRootListener myModuleRootListener; + private final MyFileStatusListener myFileStatusListener; + + private final MyCopyPasteListener myCopyPasteListener; + + public ProjectTreeBuilder(final Project project, JTree tree, DefaultTreeModel treeModel, Comparator comparator, ProjectAbstractTreeStructureBase treeStructure) { + super(project, tree, treeModel, treeStructure, comparator); + myPsiTreeChangeListener = new ProjectViewPsiTreeChangeListener(){ + protected DefaultMutableTreeNode getRootNode(){ + return myRootNode; + } + + protected AbstractTreeUpdater getUpdater(){ + return myUpdater; + } + + protected boolean isFlattenPackages(){ + return ((AbstractProjectTreeStructure)getTreeStructure()).isFlattenPackages(); + } + }; + myModuleRootListener = new ModuleRootListener() { + public void beforeRootsChange(ModuleRootEvent event) { + } + public void rootsChanged(ModuleRootEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + }; + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); + ProjectRootManager.getInstance(myProject).addModuleRootListener(myModuleRootListener); + myFileStatusListener = new MyFileStatusListener(); + FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener); + myCopyPasteListener = new MyCopyPasteListener(); + CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener); + initRootNode(); + } + + public final void dispose() { + super.dispose(); + PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener); + ProjectRootManager.getInstance(myProject).removeModuleRootListener(myModuleRootListener); + FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener); + CopyPasteManager.getInstance().removeContentChangedListener(myCopyPasteListener); + } + + private final class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public void fileStatusChanged(VirtualFile vFile) { + PsiElement element; + PsiManager psiManager = PsiManager.getInstance(myProject); + if (vFile.isDirectory()) { + element = psiManager.findDirectory(vFile); + } + else { + element = psiManager.findFile(vFile); + } + + if (!myUpdater.addSubtreeToUpdateByElement(element) && element instanceof PsiJavaFile) { + myUpdater.addSubtreeToUpdateByElement(((PsiJavaFile)element).getContainingDirectory()); + } + } + } + + private final class MyCopyPasteListener implements CopyPasteManager.ContentChangedListener { + public void contentChanged() { + myUpdater.addSubtreeToUpdate(myRootNode); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeStructure.java new file mode 100644 index 00000000000..8c8421471b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectTreeStructure.java @@ -0,0 +1,55 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode; +import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; + +/** + * @author ven + * */ + +class ProjectTreeStructure extends AbstractProjectTreeStructure { + + protected String myId; + + public ProjectTreeStructure(Project project, final String ID) { + super(project, new RootCreator() { + public AbstractTreeNode createRoot(Project project, ViewSettings settings) { + return ProjectTreeStructure.createRoot(project, ID, settings); + } + }); + myId = ID; + } + + private static AbstractTreeNode createRoot(final Project project, final String id, ViewSettings settings) { + if (PackageViewPane.ID.equals(id)) return new PackageViewProjectNode(project, settings); + else return new ProjectViewProjectNode(project, settings); + } + + public boolean isFlattenPackages() { + return ProjectView.getInstance(myProject).isFlattenPackages(myId); + } + + public boolean isShowMembers() { + return ProjectView.getInstance(myProject).isShowMembers(myId); + } + + public boolean isHideEmptyMiddlePackages() { + return ProjectView.getInstance(myProject).isHideEmptyMiddlePackages(myId); + } + + public boolean isAbbreviatePackageNames() { + return ProjectView.getInstance(myProject).isAbbreviatePackageNames(myId); + } + + public boolean isShowLibraryContents() { + return ProjectView.getInstance(myProject).isShowLibraryContents(myId); + } + + public boolean isShowModules() { + return ProjectView.getInstance(myProject).isShowModules(myId); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java new file mode 100644 index 00000000000..e61793067de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -0,0 +1,1189 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.*; +import com.intellij.ide.impl.StructureViewWrapper; +import com.intellij.ide.projectView.BaseProjectTreeBuilder; +import com.intellij.ide.projectView.HelpID; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode; +import com.intellij.ide.projectView.impl.nodes.PackageElement; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.util.DeleteHandler; +import com.intellij.ide.util.EditorHelper; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.ModuleListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.refactoring.rename.RenameHandlerRegistry; +import com.intellij.ui.AutoScrollFromSourceHandler; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.ListPopup; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.Alarm; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IJSwingUtilities; +import org.jdom.Attribute; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.util.*; +import java.util.List; + +public final class ProjectViewImpl extends ProjectView implements JDOMExternalizable, ProjectComponent { + private CopyPasteManagerEx.CopyPasteDelegator myCopyPasteDelegator; + private boolean isInitialized; + private Project myProject; + + // + options + private Map myFlattenPackages = new HashMap(); + private static final boolean ourFlattenPackagesDefaults = false; + private Map myShowMembers = new HashMap(); + private static final boolean ourShowMembersDefaults = false; + private Map myShowModules = new HashMap(); + private static final boolean ourShowModulesDefaults = true; + private Map myShowLibraryContents = new HashMap(); + private static final boolean ourShowLibraryContentsDefaults = false; + private Map myHideEmptyPackages = new HashMap(); + private static final boolean ourHideEmptyPackagesDefaults = true; + private Map myAbbreviatePackageNames = new HashMap(); + private static final boolean ourAbbreviatePackagesDefaults = false; + private Map myAutoscrollToSource = new HashMap(); + private static final boolean ourAutoscrollToSourceDefaults = false; + private Map myAutoscrollFromSource = new HashMap(); + private static final boolean ourAutoscrollFromSourceDefaults = false; + private Map myShowStructure = new HashMap(); + private static final boolean ourShowStructureDefaults = false; + + private String myCurrentViewId; + private float mySplitterProportion = 0.5f; + // - options + + + private AutoScrollToSourceHandler myAutoScrollToSourceHandler; + private AutoScrollFromSourceHandler myAutoScrollFromSourceHandler; + private ActionToolbar myToolBar; + private TabbedPaneWrapper myTabbedPane; + + private final IdeView myIdeView = new MyIdeView(); + private final MyDeletePSIElementProvider myDeletePSIElementProvider = new MyDeletePSIElementProvider(); + private final ModuleDeleteProvider myDeleteModuleProvider = new ModuleDeleteProvider(); + + private JPanel myStructurePanel; + private MyStructureViewWrapper myStructureViewWrapper; + private Splitter mySplitter; + + private MyPanel myPanel; + private final Map myId2Pane = new HashMap(); + private final List myUninitializedPanes = new ArrayList(); + + private static final String PROJECT_VIEW_DATA_CONSTANT = "com.intellij.ide.projectView.impl.ProjectViewImpl"; + private DefaultActionGroup myActionGroup; + private final Runnable myTreeChangeListener; + private final ModuleListener myModulesListener; + private String mySavedPaneId; + private static final Icon COMPACT_EMPTY_MIDDLE_PACKAGES_ICON = IconLoader.getIcon("/objectBrowser/compactEmptyPackages.png"); + private static final Icon HIDE_EMPTY_MIDDLE_PACKAGES_ICON = IconLoader.getIcon("/objectBrowser/hideEmptyPackages.png"); + + public ProjectViewImpl(Project project) { + myProject = project; + myTreeChangeListener = new Runnable() { + public void run() { + updateToolWindowTitle(); + } + }; + myModulesListener = new ModuleListener() { + public void moduleRemoved(Project project, Module module) { + updateAllBuilders(); + } + + public void modulesRenamed(Project project, List modules) { + updateAllBuilders(); + } + + public void moduleAdded(Project project, Module module) { + updateAllBuilders(); + } + + public void beforeModuleRemoved(Project project, Module module) { + } + }; + + myPanel = new MyPanel(); + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler(myProject) { + protected boolean isAutoScrollMode() { + return isAutoscrollToSource(myCurrentViewId); + } + + protected void setAutoScrollMode(boolean state) { + setAutoscrollToSource(state, myCurrentViewId); + } + }; + myAutoScrollFromSourceHandler = new AutoScrollFromSourceHandler(myProject) { + private Alarm myAlarm = new Alarm(); + private FileEditorManagerAdapter myEditorManagerListener; + + public void install() { + myEditorManagerListener = new FileEditorManagerAdapter() { + public void selectionChanged(final FileEditorManagerEvent event) { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + public void run() { + if(myProject.isDisposed()) return; + if (isAutoscrollFromSource(getCurrentViewId())) { + FileEditor newEditor = event.getNewEditor(); + if (newEditor instanceof TextEditor) { + Editor editor = ((TextEditor)newEditor).getEditor(); + selectElementAtCaretNotLosingFocus(editor); + } + } + } + }, 400); + } + }; + FileEditorManager.getInstance(myProject).addFileEditorManagerListener(myEditorManagerListener); + } + + private void selectElementAtCaretNotLosingFocus(Editor editor) { + if (IJSwingUtilities.hasFocus(getCurrentProjectViewPane().getComponentToFocus())) return; + PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); + if (file == null) return; + final SelectInTarget[] targets = SelectInManager.getInstance(myProject).getTargets(); + for (int i = 0; i < targets.length; i++) { + SelectInTarget target = targets[i]; + if (!ToolWindowId.PROJECT_VIEW.equals(target.getToolWindowId())) continue; + String compatiblePaneViewId = target.getMinorViewId(); + if (!Comparing.strEqual(compatiblePaneViewId, getCurrentViewId())) continue; + if (!target.canSelect(file)) continue; + final int offset = editor.getCaretModel().getOffset(); + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + PsiElement e = file.findElementAt(offset); + if (e == null) { + e = file; + } + target.select(e, false); + break; + } + } + + public void dispose() { + if (myEditorManagerListener != null) { + FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myEditorManagerListener); + } + } + + protected boolean isAutoScrollMode() { + return isAutoscrollFromSource(myCurrentViewId); + } + + protected void setAutoScrollMode(boolean state) { + setAutoscrollFromSource(state, myCurrentViewId); + if (state) { + final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); + if (editor != null) { + selectElementAtCaretNotLosingFocus(editor); + } + } + } + }; + } + + public void disposeComponent() { + myAutoScrollFromSourceHandler.dispose(); + } + + public void initComponent() { } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.PROJECT_VIEW); + ModuleManager.getInstance(myProject).removeModuleListener(myModulesListener); + dispose(); + } + + public void projectOpened() { + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + setupImpl(); + } + }); + } + + public synchronized void addProjectPane(final AbstractProjectViewPane pane) { + myUninitializedPanes.add(pane); + if (isInitialized) { + doAddUninitializedPanes(); + } + if (myCurrentViewId == null || myCurrentViewId.equals(pane.getId())) { + changeView(pane.getId()); + } + selectSavedPane(); + } + + private void selectSavedPane() { + AbstractProjectViewPane pane = getProjectViewPaneById(mySavedPaneId); + if (pane != null) { + changeView(mySavedPaneId); + } + } + + public synchronized void removeProjectPane(AbstractProjectViewPane pane) { + //assume we are completely initialized here + String idToRemove = pane.getId(); + if (myId2Pane.remove(idToRemove) == null) return; + pane.removeTreeChangeListener(); + final int i = myTabbedPane.indexOfComponent(pane.getComponent()); + myTabbedPane.removeTabAt(i); + if (idToRemove.equals(myCurrentViewId)) { + myCurrentViewId = myId2Pane.keySet().toArray(ArrayUtil.EMPTY_STRING_ARRAY)[0]; + } + } + + private synchronized void doAddUninitializedPanes() { + for (int i = 0; i < myUninitializedPanes.size(); i++) { + AbstractProjectViewPane pane = myUninitializedPanes.get(i); + doAddPane(pane); + } + createToolbarActions(); + myUninitializedPanes.clear(); + selectSavedPane(); + } + + private void doAddPane(AbstractProjectViewPane newPane) { + int componentIndexToInsertBefore = -1; + final List initializedPanes = new ArrayList(myId2Pane.values()); + for (int i = 0; i < myTabbedPane.getTabCount(); i++) { + final JComponent component = myTabbedPane.getComponentAt(i); + AbstractProjectViewPane pane = null; + for (int j = 0; j < initializedPanes.size(); j++) { + AbstractProjectViewPane nextPane = initializedPanes.get(j); + if (nextPane.getComponent() == component) { + pane = nextPane; + break; + } + } + if (pane.getWeight() > newPane.getWeight()) { + componentIndexToInsertBefore = i; + break; + } + } + myId2Pane.put(newPane.getId(), newPane); + if (componentIndexToInsertBefore == -1) { + myTabbedPane.addTab(newPane.getTitle(), newPane.getIcon(), newPane.getComponent(), null); + } + else { + myTabbedPane.insertTab(newPane.getTitle(), newPane.getIcon(), newPane.getComponent(), null, componentIndexToInsertBefore); + } + newPane.setTreeChangeListener(myTreeChangeListener); + newPane.installAutoScrollToSourceHandler(myAutoScrollToSourceHandler); + newPane.installAutoScrollFromSourceHandler(myAutoScrollFromSourceHandler); + } + + private void setupImpl() { + myTabbedPane = new TabbedPaneWrapper(); + myTabbedPane.installKeyboardNavigation(); + + mySplitter = new Splitter(true); + mySplitter.setHonorComponentsMinimumSize(true); + mySplitter.setFirstComponent(myTabbedPane.getComponent()); + myStructurePanel = new JPanel(new BorderLayout()); + myStructureViewWrapper = new MyStructureViewWrapper(); + myStructureViewWrapper.setFileEditor(null); + myStructurePanel.add(myStructureViewWrapper.getComponent()); + mySplitter.setSecondComponent(myStructurePanel); + myPanel.add(mySplitter, BorderLayout.CENTER); + + myActionGroup = new DefaultActionGroup(); + createToolbarActions(); + + myToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.PROJECT_VIEW_TOOLBAR, myActionGroup, true); + JComponent toolbarComponent = myToolBar.getComponent(); + myPanel.add(toolbarComponent, BorderLayout.NORTH); + + mySplitter.setProportion(mySplitterProportion); + myStructurePanel.setVisible(isShowStructure()); + + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.PROJECT_VIEW, getComponent(), ToolWindowAnchor.LEFT); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowProject.png")); + + //todo tree ? + myCopyPasteDelegator = new CopyPasteManagerEx.CopyPasteDelegator(myProject, myPanel) { + protected PsiElement[] getSelectedElements() { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + return viewPane != null ? viewPane.getSelectedPSIElements() : null; + } + }; + + // important - should register listener in the end in order to prevent its work during setup + myTabbedPane.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + final Collection panes = myId2Pane.values(); + for (Iterator iterator = panes.iterator(); iterator.hasNext();) { + AbstractProjectViewPane pane = iterator.next(); + if (pane.getComponent() == myTabbedPane.getSelectedComponent()) { + changeView(pane.getId()); + break; + } + } + } + }); + ModuleManager.getInstance(myProject).addModuleListener(myModulesListener); + isInitialized = true; + doAddUninitializedPanes(); + changeView(getCurrentViewId()); + } + + private void createToolbarActions() { + myActionGroup.removeAll(); + myActionGroup.add(new PaneOptionAction(myFlattenPackages, "Flatten Packages", "Flatten Packages", IconLoader.getIcon("/objectBrowser/flattenPackages.png"), ourFlattenPackagesDefaults) { + public void setSelected(AnActionEvent event, boolean flag) { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + final SelectionInfo selectionInfo = SelectionInfo.create(viewPane); + + super.setSelected(event, flag); + + selectionInfo.apply(viewPane); + } + }); + + class FlattenPackagesDependableAction extends PaneOptionAction { + public FlattenPackagesDependableAction(Map optionsMap, final String text, final String description, final Icon icon, boolean optionDefaultValue) { + super(optionsMap, text, description, icon, optionDefaultValue); + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + presentation.setEnabled(isFlattenPackages(myCurrentViewId)); + } + } + myActionGroup.add(new HideEmptyMiddlePackagesAction()); + myActionGroup.add(new FlattenPackagesDependableAction(myAbbreviatePackageNames, "Abbreviate Qualified Package Names", "Abbreviate Qualified Package Names", IconLoader.getIcon("/objectBrowser/abbreviatePackageNames.png"), ourAbbreviatePackagesDefaults) { + public boolean isSelected(AnActionEvent event) { + return super.isSelected(event) && isAbbreviatePackageNames(myCurrentViewId); + } + }); + myActionGroup.add(new PaneOptionAction(myShowMembers, "Show Members", "Show/Hide Members", IconLoader.getIcon("/objectBrowser/showMembers.png"), ourShowMembersDefaults)); + myActionGroup.add(myAutoScrollToSourceHandler.createToggleAction()); + myActionGroup.add(myAutoScrollFromSourceHandler.createToggleAction()); + myActionGroup.add(new ShowStructureAction()); + final List panes = new ArrayList(myId2Pane.values()); + for (int i = 0; i < panes.size(); i++) { + AbstractProjectViewPane projectViewPane = panes.get(i); + projectViewPane.addToolbarActions(myActionGroup); + } + } + + public AbstractProjectViewPane getProjectViewPaneById(String id) { + return myId2Pane.get(id); + } + + public AbstractProjectViewPane getCurrentProjectViewPane() { + return getProjectViewPaneById(myCurrentViewId); + } + + public void refresh() { + AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane(); + if (currentProjectViewPane != null) { + // may be null for e.g. default project + currentProjectViewPane.updateFromRoot(false); + } + } + + public void select(final Object element, VirtualFile file, boolean requestFocus) { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + if (viewPane != null) { + viewPane.select(element, file, requestFocus); + } + } + + private void dispose() { + myProject = null; + myStructureViewWrapper.dispose(); + myStructureViewWrapper = null; + } + + private JComponent getComponent() { + return myPanel; + } + + void updateAllBuilders() { + final Collection panes = myId2Pane.values(); + for (Iterator iterator = panes.iterator(); iterator.hasNext();) { + AbstractProjectViewPane projectViewPane = iterator.next(); + projectViewPane.updateFromRoot(false); + } + } + + public String getCurrentViewId() { + return myCurrentViewId; + } + + private void updateToolWindowTitle() { + ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW); + if (toolWindow == null) return; + + final PsiElement element = (PsiElement)myPanel.getData(DataConstants.PSI_ELEMENT); + String title; + if (element != null) { + // todo!!! + if (element instanceof PsiDirectory) { + PsiDirectory directory = (PsiDirectory)element; + PsiPackage aPackage = directory.getPackage(); + if (aPackage != null) { + title = aPackage.getQualifiedName(); + } + else { + title = directory.getVirtualFile().getPresentableUrl(); + } + } + else if (element instanceof PsiFile) { + PsiFile file = (PsiFile)element; + title = file.getVirtualFile().getPresentableUrl(); + } + else if (element instanceof PsiClass) { + PsiClass psiClass = (PsiClass)element; + title = psiClass.getQualifiedName(); + } + else if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + PsiClass aClass = method.getContainingClass(); + if (aClass != null) { + title = aClass.getQualifiedName(); + } + else { + title = method.toString(); + } + } + else if (element instanceof PsiField) { + PsiField field = (PsiField)element; + PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + title = aClass.getQualifiedName(); + } + else { + title = field.toString(); + } + } + else if (element instanceof PsiPackage) { + title = ((PsiPackage)element).getQualifiedName(); + } + else { + PsiFile file = element.getContainingFile(); + if (file != null) { + title = file.getVirtualFile().getPresentableUrl(); + } + else { + title = element.toString(); + } + } + } + else { + title = ""; + if (myProject != null) { + title = myProject.getProjectFile() != null ? myProject.getProjectFile().getPresentableUrl() : ""; + } + } + + toolWindow.setTitle(title); + } + + public PsiElement getParentOfCurrentSelection() { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + if (viewPane == null) { + return null; + } + TreePath path = viewPane.getSelectedPath(); + if (path == null) { + return null; + } + path = path.getParentPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + NodeDescriptor descriptor = (NodeDescriptor)userObject; + Object element = descriptor.getElement(); + if (element instanceof PsiElement) { + PsiElement psiElement = (PsiElement)element; + if (!psiElement.isValid()) return null; + return psiElement; + } + else { + return null; + } + } + return null; + } + + + private class PaneOptionAction extends ToggleAction { + private final Map myOptionsMap; + private final boolean myOptionDefaultValue; + + PaneOptionAction(Map optionsMap, final String text, final String description, final Icon icon, boolean optionDefaultValue) { + super(text, description, icon); + myOptionsMap = optionsMap; + myOptionDefaultValue = optionDefaultValue; + } + + public boolean isSelected(AnActionEvent event) { + return getPaneOptionValue(myOptionsMap, myCurrentViewId, myOptionDefaultValue); + } + + public void setSelected(AnActionEvent event, boolean flag) { + setPaneOption(myOptionsMap, flag, myCurrentViewId, true); + } + } + + private final class ShowStructureAction extends ToggleAction { + ShowStructureAction() { + super("Show Structure", "Show structure view", IconLoader.getIcon("/objectBrowser/showStructure.png")); + } + + public boolean isSelected(AnActionEvent event) { + return isShowStructure(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + showOrHideStructureView(flag); + } + } + + private void showOrHideStructureView(boolean toShow) { + boolean hadFocus = IJSwingUtilities.hasFocus2(getComponent()); + + myStructurePanel.setVisible(toShow); + setShowStructure(toShow, myCurrentViewId); + + if (hadFocus) { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + if (viewPane != null) { + viewPane.getComponent().requestFocus(); + } + } + + if (toShow) { + VirtualFile[] files = FileEditorManager.getInstance(myProject).getSelectedFiles(); + PsiFile psiFile = files.length != 0 ? PsiManager.getInstance(myProject).findFile(files[0]) : null; + myStructureViewWrapper.setFileEditor(null); + } + } + + public void changeView() { + final class ViewWrapper { + AbstractProjectViewPane myViewPane; + + ViewWrapper(AbstractProjectViewPane viewPane) { + myViewPane = viewPane; + } + + public String toString() { + return myViewPane.getTitle(); + } + } + + final List views = new ArrayList(); + final Collection panes = myId2Pane.values(); + ViewWrapper viewToSelect = null; + for (Iterator iterator = panes.iterator(); iterator.hasNext();) { + final AbstractProjectViewPane pane = iterator.next(); + final ViewWrapper wrapper = new ViewWrapper(pane); + if (viewToSelect == null) { + if (!pane.getId().equals(getCurrentViewId())) { + viewToSelect = wrapper; + } + } + views.add(wrapper); + } + + final JList list = new JList(views.toArray(new Object[views.size()])); + Runnable runnable = new Runnable() { + public void run() { + if (list.getSelectedIndex() < 0) return; + ViewWrapper viewWrapper = (ViewWrapper)list.getSelectedValue(); + changeView(viewWrapper.myViewPane.getId()); + } + }; + + if (viewToSelect != null) { + list.setSelectedValue(viewToSelect, true); + } + Dimension size = getComponent().getSize(); + Point loc = getComponent().getLocationOnScreen(); + ListPopup popup = new ListPopup(" Views ", list, runnable, myProject); + popup.show(loc.x + size.width / 2 - popup.getSize().width / 2, loc.y + size.height / 2 - popup.getSize().height / 2); + } + + public void setCurrentViewId(String viewId) { + myCurrentViewId = viewId; + } + + public void changeView(String viewId) { + if (viewId != null) { + setCurrentViewId(viewId); + final AbstractProjectViewPane pane = getProjectViewPaneById(viewId); + if (pane != null) { + final JComponent component = pane.getComponent(); + myTabbedPane.setSelectedComponent(component); + pane.getComponentToFocus().requestFocus(); + updateToolWindowTitle(); + showOrHideStructureView(isShowStructure()); + } + } + } + + private final class MyDeletePSIElementProvider implements DeleteProvider { + public boolean canDeleteElement(DataContext dataContext) { + final PsiElement[] elements = getElementsToDelete(); + return DeleteHandler.shouldEnableDeleteAction(elements); + } + + public void deleteElement(DataContext dataContext) { + List allElements = Arrays.asList(getElementsToDelete()); + List validElements = new ArrayList(); + for (Iterator iterator = allElements.iterator(); iterator.hasNext();) { + PsiElement psiElement = iterator.next(); + if (psiElement != null && psiElement.isValid()) validElements.add(psiElement); + } + final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]); + + LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, "Deleting"); + try { + DeleteHandler.deletePsiElement(elements, myProject); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + } + + private PsiElement[] getElementsToDelete() { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + PsiElement[] elements = viewPane.getSelectedPSIElements(); + for (int idx = 0; idx < elements.length; idx++) { + final PsiElement element = elements[idx]; + if (element instanceof PsiDirectory) { + final VirtualFile virtualFile = ((PsiDirectory)element).getVirtualFile(); + final String path = virtualFile.getPath(); + if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { // if is jar-file root + final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath( + path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length())); + if (vFile != null) { + final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); + if (psiFile != null) { + elements[idx] = psiFile; + } + } + } + } + } + return elements; + } + + } + + public String getComponentName() { + return "ProjectView"; + } + + private final class MyStructureViewWrapper extends StructureViewWrapper { + MyStructureViewWrapper() { + super(myProject); + } + + protected boolean isStructureViewShowing() { + return myStructurePanel.isVisible(); + } + } + + private final class MyPanel extends JPanel implements DataProvider { + MyPanel() { + super(new BorderLayout()); + } + + private Object getSelectedNodeElement() { + final AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane(); + if (currentProjectViewPane == null) { // can happen if not initialized yet + return null; + } + DefaultMutableTreeNode node = currentProjectViewPane.getSelectedNode(); + if (node == null) { + return null; + } + Object userObject = node.getUserObject(); + if (userObject instanceof AbstractTreeNode){ + return ((AbstractTreeNode)userObject).getValue(); + } + if (!(userObject instanceof NodeDescriptor)) { + return null; + } + return ((NodeDescriptor)userObject).getElement(); + } + + public Object getData(String dataId) { + final AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane(); + if (currentProjectViewPane != null) { + final Object paneSpecificData = currentProjectViewPane.getData(dataId); + if (paneSpecificData != null) return paneSpecificData; + } + + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + final PsiElement psiElement; + Object element = getSelectedNodeElement(); + if (element instanceof PsiElement) { + psiElement = (PsiElement)element; + } + else if (element instanceof PackageElement) { + psiElement = ((PackageElement)element).getPackage(); + } + else { + psiElement = null; + } + return psiElement != null && psiElement.isValid() ? psiElement : null; + } + if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (currentProjectViewPane == null) { + return null; + } + final List elements = new ArrayList(Arrays.asList(currentProjectViewPane.getSelectedPSIElements())); + for (Iterator it = elements.iterator(); it.hasNext();) { + PsiElement psiElement = it.next(); + if (!psiElement.isValid()) { + it.remove(); + } + } + return elements.toArray(new PsiElement[elements.size()]); + } + if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) { + /* + DefaultMutableTreeNode node = getCurrentProjectViewPane().getSelectedNode(); + if (node == null) { + return null; + } + if (node.getUserObject() instanceof DirectoryNodeDescriptor) { + final PsiDirectory dir = ((DirectoryNodeDescriptor)node.getUserObject()).getDirectory(); + return dir.getParentDirectory(); + } + node = (DefaultMutableTreeNode)node.getParent(); + if (node == null) { + return null; + } + Object userObject = node.getUserObject(); + if (!(userObject instanceof NodeDescriptor)) { + return null; + } + Object element = ((NodeDescriptor)userObject).getElement(); + if (!(element instanceof PsiElement)) { + return null; + } + PsiElement psiElement = (PsiElement)element; + return psiElement.isValid() ? psiElement : null; + */ + // [dsl] in Project View we do not have any specific target psi element + // we only guess + return null; + } + if (DataConstantsEx.CUT_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getCutProvider(); + } + if (DataConstantsEx.COPY_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getCopyProvider(); + } + if (DataConstantsEx.PASTE_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getPasteProvider(); + } + if (DataConstantsEx.IDE_VIEW.equals(dataId)) { + return myIdeView; + } + if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return getSelectedNodeElement() instanceof Module ? (DeleteProvider)myDeleteModuleProvider : myDeletePSIElementProvider; + } + if (DataConstantsEx.HELP_ID.equals(dataId)) { + return HelpID.PROJECT_VIEWS; + } + if (PROJECT_VIEW_DATA_CONSTANT.equals(dataId)) { + return ProjectViewImpl.this; + } + if (DataConstantsEx.PROJECT_CONTEXT.equals(dataId)) { + Object selected = getSelectedNodeElement(); + return selected instanceof Project ? selected : null; + } + if (DataConstantsEx.MODULE_CONTEXT.equals(dataId)) { + Object selected = getSelectedNodeElement(); + return selected instanceof Module ? selected : null; + } + if (DataConstantsEx.MODULE_CONTEXT_ARRAY.equals(dataId)) { + return getSelectedModules(); + } + + return null; + } + + private Module[] getSelectedModules() { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + if (viewPane == null) return null; + final Object[] elements = viewPane.getSelectedElements(); + ArrayList result = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + if (element instanceof Module) { + result.add((Module)element); + } + else if (element instanceof ModuleGroup) { + Module[] modules = ((ModuleGroup)element).modulesInGroup(myProject); + result.addAll(Arrays.asList(modules)); + } + } + if (result.isEmpty()) { + return null; + } + else { + return result.toArray(new Module[result.size()]); + } + } + } + + private final class MyIdeView implements IdeView { + public void selectElement(PsiElement element) { + ProjectViewImpl.this.selectPsiElement(element, true); + if (element instanceof PsiElement) { + final PsiElement psiElement = (PsiElement)element; + final boolean isDirectory = psiElement instanceof PsiDirectory; + if (!isDirectory) { + Editor editor = EditorHelper.openInEditor(psiElement); + if (editor != null) { + ToolWindowManager.getInstance(myProject).activateEditorComponent(); + } + } + } + } + + public PsiDirectory[] getDirectories() { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + DefaultMutableTreeNode node = viewPane != null ? viewPane.getSelectedNode() : null; + + while (true) { + if (node == null) { + break; + } + final Object userObject = node.getUserObject(); + if (userObject instanceof PsiDirectoryNode || + userObject instanceof ProjectViewModuleNode) { + break; + } + node = (DefaultMutableTreeNode)node.getParent(); + } + + if (node == null) { + return PsiDirectory.EMPTY_ARRAY; + } + final Object userObject = node.getUserObject(); + if (userObject instanceof PsiDirectoryNode) { + PsiDirectory directory = ((PsiDirectoryNode)userObject).getValue(); + if (directory != null) { + return new PsiDirectory[]{directory}; + } + } + else if (userObject instanceof ProjectViewModuleNode) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(((ProjectViewModuleNode)userObject).getValue()); + final VirtualFile[] sourceRoots = moduleRootManager.getSourceRoots(); + List dirs = new ArrayList(sourceRoots.length); + final PsiManager psiManager = PsiManager.getInstance(myProject); + for (int idx = 0; idx < sourceRoots.length; idx++) { + final VirtualFile sourceRoot = sourceRoots[idx]; + final PsiDirectory directory = psiManager.findDirectory(sourceRoot); + if (directory != null) { + dirs.add(directory); + } + } + return dirs.toArray(new PsiDirectory[dirs.size()]); + } + + return PsiDirectory.EMPTY_ARRAY; + } + } + + public void selectPsiElement(PsiElement element, boolean requestFocus) { + if (element == null) return; + if (element instanceof PsiDirectory) { + select(element, ((PsiDirectory)element).getVirtualFile() , requestFocus); + } else { + select(element, element.getContainingFile().getVirtualFile(), requestFocus); + } + + } + + + private void readOption(Element node, Map options) { + if (node == null) return; + List attributes = node.getAttributes(); + for (Iterator iterator1 = attributes.iterator(); iterator1.hasNext();) { + Attribute attribute = (Attribute)iterator1.next(); + options.put(attribute.getName(), "true".equals(attribute.getValue()) ? Boolean.TRUE : Boolean.FALSE); + } + } + + private void writeOption(Element parentNode, Map optionsForPanes, String optionName) { + Element e = new Element(optionName); + for (Iterator> iterator = optionsForPanes.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + e.setAttribute(entry.getKey(), entry.getValue().booleanValue() ? "true" : "false"); + } + + parentNode.addContent(e); + } + + public void readExternal(Element parentNode) { + Element navigatorElement = parentNode.getChild("navigator"); + if (navigatorElement != null) { + mySavedPaneId = navigatorElement.getAttributeValue("currentView"); + readOption(navigatorElement.getChild("flattenPackages"), myFlattenPackages); + readOption(navigatorElement.getChild("showMembers"), myShowMembers); + readOption(navigatorElement.getChild("showModules"), myShowModules); + readOption(navigatorElement.getChild("showLibraryContents"), myShowLibraryContents); + readOption(navigatorElement.getChild("hideEmptyPackages"), myHideEmptyPackages); + readOption(navigatorElement.getChild("abbreviatePackageNames"), myAbbreviatePackageNames); + readOption(navigatorElement.getChild("showStructure"), myShowStructure); + readOption(navigatorElement.getChild("autoscrollToSource"), myAutoscrollToSource); + readOption(navigatorElement.getChild("autoscrollFromSource"), myAutoscrollFromSource); + + try { + mySplitterProportion = Float.parseFloat(navigatorElement.getAttributeValue("splitterProportion")); + } + catch (NumberFormatException e) { + mySplitterProportion = 0.5f; + } + } + } + + public void writeExternal(Element parentNode) { + Element navigatorElement = new Element("navigator"); + if (getCurrentViewId() != null) { + navigatorElement.setAttribute("currentView", getCurrentViewId()); + } + writeOption(navigatorElement, myFlattenPackages, "flattenPackages"); + writeOption(navigatorElement, myShowMembers, "showMembers"); + writeOption(navigatorElement, myShowModules, "showModules"); + writeOption(navigatorElement, myShowLibraryContents, "showLibraryContents"); + writeOption(navigatorElement, myHideEmptyPackages, "hideEmptyPackages"); + writeOption(navigatorElement, myAbbreviatePackageNames, "abbreviatePackageNames"); + writeOption(navigatorElement, myShowStructure, "showStructure"); + writeOption(navigatorElement, myAutoscrollToSource, "autoscrollToSource"); + writeOption(navigatorElement, myAutoscrollFromSource, "autoscrollFromSource"); + + navigatorElement.setAttribute("splitterProportion", Float.toString(getSplitterProportion())); + parentNode.addContent(navigatorElement); + } + + private float getSplitterProportion() { + return mySplitter != null ? mySplitter.getProportion() : mySplitterProportion; + } + + public boolean isAutoscrollToSource(String paneId) { + return getPaneOptionValue(myAutoscrollToSource, paneId, ourAutoscrollToSourceDefaults); + } + + public void setAutoscrollToSource(boolean autoscrollMode, String paneId) { + myAutoscrollToSource.put(paneId, autoscrollMode ? Boolean.TRUE : Boolean.FALSE); + } + + public boolean isAutoscrollFromSource(String paneId) { + return getPaneOptionValue(myAutoscrollFromSource, paneId, ourAutoscrollFromSourceDefaults); + } + + public void setAutoscrollFromSource(boolean autoscrollMode, String paneId) { + setPaneOption(myAutoscrollFromSource, autoscrollMode, paneId, false); + } + + public boolean isFlattenPackages(String paneId) { + return getPaneOptionValue(myFlattenPackages, paneId, ourFlattenPackagesDefaults); + } + + public void setFlattenPackages(boolean flattenPackages, String paneId) { + setPaneOption(myFlattenPackages, flattenPackages, paneId, true); + } + + public boolean isShowMembers(String paneId) { + return getPaneOptionValue(myShowMembers, paneId, ourShowMembersDefaults); + } + + public boolean isHideEmptyMiddlePackages(String paneId) { + return getPaneOptionValue(myHideEmptyPackages, paneId, ourHideEmptyPackagesDefaults); + } + + public boolean isAbbreviatePackageNames(String paneId) { + return getPaneOptionValue(myAbbreviatePackageNames, paneId, ourAbbreviatePackagesDefaults); + } + + public void setShowMembers(boolean showMembers, String paneId) { + setPaneOption(myShowMembers, showMembers, paneId, true); + } + + public boolean isShowLibraryContents(String paneId) { + return getPaneOptionValue(myShowLibraryContents, paneId, ourShowLibraryContentsDefaults); + } + + public void setShowLibraryContents(boolean showLibraryContents, String paneId) { + setPaneOption(myShowLibraryContents, showLibraryContents, paneId, true); + } + + public boolean isShowModules(String paneId) { + return getPaneOptionValue(myShowModules, paneId, ourShowModulesDefaults); + } + + public void setShowModules(boolean showModules, String paneId) { + setPaneOption(myShowModules, showModules, paneId, true); + } + + public void setHideEmptyPackages(boolean hideEmptyPackages, String paneId) { + setPaneOption(myHideEmptyPackages, hideEmptyPackages, paneId, true); + } + + public void setAbbreviatePackageNames(boolean abbreviatePackageNames, String paneId) { + setPaneOption(myAbbreviatePackageNames, abbreviatePackageNames, paneId, true); + } + + private void setPaneOption(Map optionsMap, boolean value, String paneId, final boolean updatePane) { + optionsMap.put(paneId, value ? Boolean.TRUE : Boolean.FALSE); + if (updatePane) { + final AbstractProjectViewPane pane = myId2Pane.get(paneId); + if (pane != null) { + pane.updateFromRoot(false); + } + } + } + + private boolean getPaneOptionValue(Map optionsMap, String paneId, boolean defaultValue) { + final Boolean value = optionsMap.get(paneId); + return value == null ? defaultValue : value.booleanValue(); + } + + public boolean isShowStructure() { + Boolean status = myShowStructure.get(getCurrentViewId()); + return status == null ? ourShowStructureDefaults : status.booleanValue(); + } + + public void setShowStructure(boolean showStructure, String paneId) { + myShowStructure.put(paneId, showStructure ? Boolean.TRUE : Boolean.FALSE); + } + + static { + RenameHandlerRegistry.getInstance().registerHandler(RenameModuleHandler.INSTANCE); + } + + private class HideEmptyMiddlePackagesAction extends PaneOptionAction { + + public HideEmptyMiddlePackagesAction() { + super(myHideEmptyPackages, "", "", null, ourHideEmptyPackagesDefaults); + } + + public void setSelected(AnActionEvent event, boolean flag) { + final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); + final SelectionInfo selectionInfo = SelectionInfo.create(viewPane); + + super.setSelected(event, flag); + + selectionInfo.apply(viewPane); + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + if (isFlattenPackages(myCurrentViewId)){ + presentation.setText("Hide Empty Middle Packages"); + presentation.setDescription("Show/Hide Empty Middle Packages"); + presentation.setIcon(HIDE_EMPTY_MIDDLE_PACKAGES_ICON); + } + else { + presentation.setText("Compact Empty Middle Packages"); + presentation.setDescription("Show/Compact Empty Middle Packages"); + presentation.setIcon(COMPACT_EMPTY_MIDDLE_PACKAGES_ICON); + } + } + } + + private static class SelectionInfo { + + private final Object[] myElements; + + private SelectionInfo(Object[] elements) { + myElements = elements; + } + + public void apply(final AbstractProjectViewPane viewPane) { + if (viewPane == null) { + return; + } + final BaseProjectTreeBuilder treeBuilder = viewPane.myTreeBuilder; + final ProjectViewTree tree = viewPane.myTree; + final DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel(); + final List paths = new ArrayList(myElements.length); + for (int idx = 0; idx < myElements.length; idx++) { + final Object element = myElements[idx]; + DefaultMutableTreeNode node = treeBuilder.getNodeForElement(element); + if (node == null) { + treeBuilder.buildNodeForElement(element); + node = treeBuilder.getNodeForElement(element); + } + if (node != null) { + paths.add(new TreePath(treeModel.getPathToRoot(node))); + } + } + if (paths.size() > 0) { + tree.setSelectionPaths(paths.toArray(new TreePath[paths.size()])); + } + } + + public static SelectionInfo create(final AbstractProjectViewPane viewPane) { + List selectedElements = Collections.EMPTY_LIST; + if (viewPane != null) { + final TreePath[] selectionPaths = viewPane.getSelectionPaths(); + if (selectionPaths != null) { + selectedElements = new ArrayList(); + for (int idx = 0; idx < selectionPaths.length; idx++) { + TreePath path = selectionPaths[idx]; + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + final NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + selectedElements.add(descriptor.getElement()); + } + } + } + return new SelectionInfo(selectedElements.toArray()); + } + } + + public void selectModuleGroup(ModuleGroup moduleGroup, boolean b) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewPane.java new file mode 100644 index 00000000000..cd37d1eedc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewPane.java @@ -0,0 +1,106 @@ +/** + * @author cdr + */ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.impl.ProjectPaneSelectInTarget; +import com.intellij.ide.impl.ProjectViewSelectInTarget; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.TreeViewUtil; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiDirectory; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +public final class ProjectViewPane extends AbstractProjectViewPSIPane implements ProjectComponent { + + public static final String ID = "ProjectPane"; + private static final Icon ICON = IconLoader.getIcon("/general/projectTab.png"); + + public ProjectViewPane(Project project) { + super(project); + } + + public String getTitle() { + return "Project"; + } + + public String getId() { + return ID; + } + + public Icon getIcon() { + return ICON; + } + + + protected ProjectViewSelectInTarget createSelectInTarget() { + return new ProjectPaneSelectInTarget(myProject); + } + + protected AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder) { + return new ProjectViewTreeUpdater(treeBuilder); + } + + protected ProjectAbstractTreeStructureBase createStructure() { + return new ProjectTreeStructure(myProject, ID); + } + + protected ProjectViewTree createTree(DefaultTreeModel treeModel) { + return new ProjectViewTree(treeModel) { + public String toString() { + return getTitle() + " " + super.toString(); + } + + public DefaultMutableTreeNode getSelectedNode() { + return ProjectViewPane.this.getSelectedNode(); + } + }; + } + + public String getComponentName() { + return "ProjectPane"; + } + + + // should be first + public int getWeight() { + return 0; + } + + private final class ProjectViewTreeUpdater extends AbstractTreeUpdater { + private ProjectViewTreeUpdater(final AbstractTreeBuilder treeBuilder) { + super(treeBuilder); + } + + public boolean addSubtreeToUpdateByElement(Object element) { + if (element instanceof PsiDirectory) { + final PsiDirectory dir = (PsiDirectory)element; + final ProjectTreeStructure treeStructure = (ProjectTreeStructure)myTreeStructure; + PsiDirectory dirToUpdateFrom = dir; + if (!treeStructure.isFlattenPackages() && treeStructure.isHideEmptyMiddlePackages()) { + // optimization: this check makes sense only if flattenPackages == false && HideEmptyMiddle == true + while (dirToUpdateFrom != null && dirToUpdateFrom.getPackage() != null && TreeViewUtil.isEmptyMiddlePackage(dirToUpdateFrom, true)) { + dirToUpdateFrom = dirToUpdateFrom.getParentDirectory(); + } + } + boolean addedOk; + while (!(addedOk = super.addSubtreeToUpdateByElement(dirToUpdateFrom == null? myTreeStructure.getRootElement() : dirToUpdateFrom))) { + if (dirToUpdateFrom == null) { + break; + } + dirToUpdateFrom = dirToUpdateFrom.getParentDirectory(); + } + return addedOk; + } + + return super.addSubtreeToUpdateByElement(element); + } + + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewTree.java new file mode 100644 index 00000000000..ed5c9ae5ccd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/ProjectViewTree.java @@ -0,0 +1,34 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.util.ui.Tree; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeModel; + +/** + * @author Eugene Zhuravlev + * Date: Sep 17, 2003 + * Time: 7:44:22 PM + */ +public abstract class ProjectViewTree extends Tree { + protected ProjectViewTree(TreeModel newModel) { + super(newModel); + setCellRenderer(new NodeRenderer()); + } + + public final int getToggleClickCount() { + DefaultMutableTreeNode node = getSelectedNode(); + if (node != null) { + Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + NodeDescriptor descriptor = (NodeDescriptor)userObject; + if (!descriptor.expandOnDoubleClick()) return -1; + } + } + return super.getToggleClickCount(); + } + + public abstract DefaultMutableTreeNode getSelectedNode(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/RenameModuleHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/RenameModuleHandler.java new file mode 100644 index 00000000000..8842b4ea397 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/RenameModuleHandler.java @@ -0,0 +1,110 @@ +package com.intellij.ide.projectView.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleWithNameAlreadyExists; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleCircularDependencyException; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.rename.RenameHandler; + +/** + * @author dsl + */ +public class RenameModuleHandler implements RenameHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.actions.RenameModuleHandler"); + static final RenameModuleHandler INSTANCE = new RenameModuleHandler(); + + private RenameModuleHandler() { + + } + + public boolean isAvailableOnDataContext(DataContext dataContext) { + Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + return module != null; + } + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + LOG.assertTrue(false); + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + LOG.assertTrue(dataContext != null); + final Module module = (Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT); + LOG.assertTrue(module != null); + Messages.showInputDialog(project, + "Enter new module name", + "Rename Module", + Messages.getQuestionIcon(), + module.getName(), + new MyInputValidator(project, module)); + } + + private static class MyInputValidator implements InputValidator { + private final Project myProject; + private final Module myModule; + + public MyInputValidator(Project project, Module module) { + myProject = project; + myModule = module; + } + + public boolean checkInput(String inputString) { + return true; + } + + public boolean canClose(final String inputString) { + final ModifiableModuleModel modifiableModel = ModuleManager.getInstance(myProject).getModifiableModel(); + try { + modifiableModel.renameModule(myModule, inputString); + } + catch (ModuleWithNameAlreadyExists moduleWithNameAlreadyExists) { + Messages.showErrorDialog(myProject, "Module named '" + inputString + "' already exists", + "Rename Module"); + return false; + } + final Ref success = Ref.create(Boolean.TRUE); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + modifiableModel.commit(); + } + catch (final ModuleCircularDependencyException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog(myProject, "Renaming module '" + myModule.getName() + "' to '" + + inputString + + "'\n" + + "will introduce circular dependency between \n" + + "modules '" + e.getModuleName1() + "' and '" + + e.getModuleName2() + + "'", + "Rename Module"); + } + }); + modifiableModel.dispose(); + success.set(Boolean.FALSE); + return; + } + } + }); + } + }, "Renaming module " + myModule.getName(), null); + return success.get().booleanValue(); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java new file mode 100644 index 00000000000..8851191fdd6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.IconUtilEx; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; + +public abstract class AbstractModuleNode extends ProjectViewNode { + public AbstractModuleNode(Project project, Module value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public void update(PresentationData presentation) { + if (getValue().isDisposed()) { + setValue(null); + return; + } + presentation.setPresentableText(getValue().getName()); + presentation.setOpenIcon(IconUtilEx.getIcon(getValue(), Iconable.ICON_FLAG_OPEN)); + presentation.setClosedIcon(IconUtilEx.getIcon(getValue(), Iconable.ICON_FLAG_CLOSED)); + } + + + public String getTestPresentation() { + return "Module"; + } + + public boolean contains(VirtualFile file) { + return PackageUtil.moduleContainsFile(getValue(), file, getSettings(), false) || + PackageUtil.moduleContainsFile(getValue(), file, getSettings(), true); + } + + public abstract Collection getChildren(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java new file mode 100644 index 00000000000..d1dd17d4a13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.ModuleGroup; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Icons; + +import java.util.*; + +public abstract class AbstractProjectNode extends ProjectViewNode { + public AbstractProjectNode(Project project, Project value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public abstract Collection getChildren(); + + protected Collection modulesAndGroups(Module[] modules) { + Map> groups = new HashMap>(); + List nonGroupedModules = new ArrayList(Arrays.asList(modules)); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + String group = ModuleManager.getInstance(getProject()).getModuleGroup(module); + if (group != null) { + List moduleList = groups.get(group); + if (moduleList == null) { + moduleList = new ArrayList(); + groups.put(group, moduleList); + } + moduleList.add(module); + nonGroupedModules.remove(module); + } + } + String[] groupArray = groups.keySet().toArray(ArrayUtil.EMPTY_STRING_ARRAY); + List result = new ArrayList(); + for (int j = 0; j < groupArray.length; j++) { + final String name = groupArray[j]; + result.add(new ModuleGroupNode(getProject(), new ModuleGroup(name), getSettings(), getModuleNodeClass())); + } + result.addAll(ProjectViewNode.wrap(nonGroupedModules, getProject(), getModuleNodeClass(), getSettings())); + return result; + } + + protected abstract Class getModuleNodeClass(); + + public void update(PresentationData presentation) { + presentation.setIcons(Icons.PROJECT_ICON); + final VirtualFile projectFile = getProject().getProjectFile(); + presentation.setPresentableText(projectFile != null ? projectFile.getName() : ""); + } + + public String getTestPresentation() { + return "Project"; + } + + public boolean contains(VirtualFile file) { + ProjectFileIndex index = ProjectRootManager.getInstance(getProject()).getFileIndex(); + return index.isInContent(file) || index.isInLibraryClasses(file) || index.isInLibrarySource(file); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/BasePsiNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/BasePsiNode.java new file mode 100644 index 00000000000..9656e70f60a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/BasePsiNode.java @@ -0,0 +1,115 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; + +import javax.swing.*; +import java.util.Collection; +import java.util.ArrayList; + +public abstract class BasePsiNode extends ProjectViewNode { + static private final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.nodes.BasePsiNode"); + + private SmartPsiElementPointer mySmartPointer; + + protected BasePsiNode(Project project, Type value, ViewSettings viewSettings) { + super(project, value, viewSettings); + mySmartPointer = SmartPointerManager.getInstance(getProject()).createSmartPsiElementPointer(getValue()); + } + + public final Collection getChildren() { + Type value = getValue(); + if (value == null) return new ArrayList(); + boolean valid = value.isValid(); + if (!LOG.assertTrue(valid)) { + return null; + } + return getChildrenImpl(); + } + + protected abstract Collection getChildrenImpl(); + + protected boolean isMarkReadOnly() { + return getParentValue() instanceof PsiDirectory; + } + + public FileStatus getFileStatus() { + if (getParentValue() instanceof PsiDirectory) { + VirtualFile file = getVirtualFileForValue(); + if (file != null) { + return FileStatusManager.getInstance(getProject()).getStatus(file); + } + } + return FileStatus.NOT_CHANGED; + + } + + private VirtualFile getVirtualFileForValue() { + Type value = getValue(); + if (value == null) return null; + if (value instanceof PsiDirectory) { + return ((PsiDirectory)value).getVirtualFile(); + } + else { + PsiFile containingFile = value.getContainingFile(); + if (containingFile == null) { + return null; + } + else { + return containingFile.getVirtualFile(); + } + } + } + // Should be called in atomic action + + protected abstract void updateImpl(PresentationData data); + + + public void update(PresentationData data) { + setValue((Type)mySmartPointer.getElement()); + if (getValue() == null) return; + + int flags = Iconable.ICON_FLAG_VISIBILITY; + if (isMarkReadOnly()) { + flags |= Iconable.ICON_FLAG_READ_STATUS; + } + + Icon icon = getValue().getIcon(flags); + data.setClosedIcon(icon); + data.setOpenIcon(icon); + data.setLocationString(myLocationString); + data.setPresentableText(myName); + updateImpl(data); + } + + public boolean contains(VirtualFile file) { + PsiFile containingFile = getValue().getContainingFile(); + return containingFile.getVirtualFile().equals(file); + } + + public void navigate(boolean requestFocus) { + if (canNavigate()) { + ((NavigationItem)getValue()).navigate(requestFocus); + } + } + + public boolean canNavigate() { + return getValue() instanceof NavigationItem; + } + + public static VirtualFile getVirtualFile(PsiElement element) { + return element instanceof PsiDirectory + ? ((PsiDirectory)element).getVirtualFile() + : element.getContainingFile().getVirtualFile(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java new file mode 100644 index 00000000000..f33b6c342aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ClassTreeNode.java @@ -0,0 +1,70 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.PsiClassChildrenSource; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class ClassTreeNode extends BasePsiNode{ + public ClassTreeNode(Project project, PsiClass value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public Collection getChildrenImpl() { + PsiClass parent = getValue(); + final ArrayList treeNodes = new ArrayList(); + + ArrayList result = new ArrayList(); + if (getSettings().isShowMembers()) { + PsiClassChildrenSource.DEFAULT_CHILDREN.addChildren((PsiClass)parent, result); + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + PsiElement psiElement = iterator.next(); + psiElement.accept(new PsiElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitClass(PsiClass aClass) { + treeNodes.add(new ClassTreeNode(getProject(), aClass, getSettings())); + } + + public void visitMethod(PsiMethod method) { + treeNodes.add(new PsiMethodNode(getProject(), method, getSettings())); + } + + public void visitField(PsiField field) { + treeNodes.add(new PsiFieldNode(getProject(), field, getSettings())); + } + }); + } + } + return treeNodes; + } + + public void updateImpl(PresentationData data) { + data.setPresentableText(getValue().getName()); + } + + public boolean isTopLevel() { + if (getValue() == null) return false; + return getValue().getParent() instanceof PsiFile; + } + + + public boolean expandOnDoubleClick() { + return false; + } + + public PsiClass getPsiClass() { + return getValue(); + } + + public boolean isAlwaysExpand() { + return getParentValue() instanceof PsiFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/Form.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/Form.java new file mode 100644 index 00000000000..187ff4ca9af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/Form.java @@ -0,0 +1,54 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.pom.Navigatable; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +public class Form implements Navigatable{ + private final Collection myFormFiles; + private final PsiClass myClassToBind; + + public Form(PsiClass classToBind, Collection formFiles) { + myClassToBind = classToBind; + myFormFiles = new HashSet(formFiles); + } + + public boolean equals(Object object) { + if (object instanceof Form){ + Form form = (Form)object; + return myFormFiles.equals(form.myFormFiles) && myClassToBind.equals(form.myClassToBind); + } else { + return false; + } + } + + public int hashCode() { + return myFormFiles.hashCode() ^ myClassToBind.hashCode(); + } + + public String getName() { + return myClassToBind.getName(); + } + + public void navigate(boolean requestFocus) { + for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { + PsiFile psiFile = iterator.next(); + if (psiFile instanceof Navigatable && ((Navigatable)psiFile).canNavigate()) { + ((Navigatable)psiFile).navigate(requestFocus); + } + } + } + + public boolean canNavigate() { + for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { + PsiFile psiFile = iterator.next(); + if (psiFile instanceof Navigatable && ((Navigatable)psiFile).canNavigate()) return true; + } + return false; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/FormNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/FormNode.java new file mode 100644 index 00000000000..19f3b33cb60 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/FormNode.java @@ -0,0 +1,50 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; +import java.util.Iterator; + +public class FormNode extends ProjectViewNode
    { + private final Collection myChildren; + public FormNode(Project project, Form value, ViewSettings viewSettings, + Collection children) { + super(project, value, viewSettings); + myChildren = children; + } + + public Collection getChildren() { + return myChildren; + } + + public String getTestPresentation() { + return "Form:" + getValue().getName(); + } + + public boolean contains(VirtualFile file) { + for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { + ProjectViewNode treeNode = (ProjectViewNode)iterator.next(); + if (treeNode.contains(file)) return true; + } + return false; + } + + public void update(PresentationData presentation) { + presentation.setPresentableText(getValue().getName()); + presentation.setIcons(StdFileTypes.GUI_DESIGNER_FORM.getIcon()); + } + + public void navigate(final boolean requestFocus) { + getValue().navigate(requestFocus); + } + + public boolean canNavigate() { + return getValue().canNavigate(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java new file mode 100644 index 00000000000..ff850ab34dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java @@ -0,0 +1,35 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.openapi.module.Module; + +/** + * @author Eugene Zhuravlev + * Date: Sep 17, 2003 + * Time: 7:08:03 PM + */ +public final class LibraryGroupElement { + private final Module myModule; + + public LibraryGroupElement(Module module) { + myModule = module; + } + + public Module getModule() { + return myModule; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LibraryGroupElement)) return false; + + final LibraryGroupElement libraryGroupElement = (LibraryGroupElement)o; + + if (!myModule.equals(libraryGroupElement.myModule)) return false; + + return true; + } + + public int hashCode() { + return myModule.hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java new file mode 100644 index 00000000000..059c5868797 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java @@ -0,0 +1,83 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.util.Icons; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class LibraryGroupNode extends ProjectViewNode { + + public LibraryGroupNode(Project project, LibraryGroupElement value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public Collection getChildren() { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(getValue().getModule()); + final List children = new ArrayList(); + final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); + for (int idx = 0; idx < orderEntries.length; idx++) { + final OrderEntry orderEntry = orderEntries[idx]; + if (orderEntry instanceof LibraryOrderEntry) { + final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry; + final Library library = libraryOrderEntry.getLibrary(); + if (library == null) { + continue; + } + final String libraryName = library.getName(); + if (libraryName == null || libraryName.length() == 0) { + addLibraryChildren(orderEntry, children, getProject(), this); + } + else { + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(getValue(), orderEntry), getSettings())); + } + } + else if (orderEntry instanceof JdkOrderEntry) { + final ProjectJdk jdk = ((JdkOrderEntry)orderEntry).getJdk(); + if (jdk != null) { + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(getValue(), orderEntry), getSettings())); + } + } + } + return children; + } + + public static void addLibraryChildren(final OrderEntry entry, final List children, Project project, ProjectViewNode node) { + final PsiManager psiManager = PsiManager.getInstance(project); + final VirtualFile[] files = entry.getFiles(OrderRootType.CLASSES); + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = files[idx]; + final PsiDirectory psiDir = psiManager.findDirectory(file); + if (psiDir == null) { + continue; + } + children.add(new PsiDirectoryNode(project, psiDir, node.getSettings())); + } + } + + + public String getTestPresentation() { + return "Libraries"; + } + + public boolean contains(VirtualFile file) { + return someChildContainsFile(file); + } + + public void update(PresentationData presentation) { + presentation.setPresentableText("Libraries"); + presentation.setIcons(Icons.LIBRARY_ICON); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ModuleGroupNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ModuleGroupNode.java new file mode 100644 index 00000000000..98a86d80fa4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ModuleGroupNode.java @@ -0,0 +1,57 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.ModuleGroup; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.util.Arrays; +import java.util.Collection; + +public class ModuleGroupNode extends ProjectViewNode { + + private static final Icon OPEN_ICON = IconLoader.getIcon("/actions/newFolder.png"); + private static final Icon CLOSED_ICON = OPEN_ICON; + private final Class myModuleNodeClass; + + public ModuleGroupNode(final Project project, + final ModuleGroup value, + final ViewSettings viewSettings, + final Class moduleNodeClass) { + super(project, value, viewSettings); + myModuleNodeClass = moduleNodeClass; + } + + public Collection getChildren() { + Module[] modules = getValue().modulesInGroup(getProject()); + return ProjectViewNode.wrap(Arrays.asList(modules), getProject(), myModuleNodeClass, getSettings()); + } + + public boolean hasDescription() { + return true; + } + + public String getDescription() { + return "Module Group"; + } + + public boolean contains(VirtualFile file) { + return someChildContainsFile(file); + } + + public void update(PresentationData presentation) { + presentation.setPresentableText(getValue().getName()); + presentation.setOpenIcon(OPEN_ICON); + presentation.setClosedIcon(CLOSED_ICON); + } + + public String getTestPresentation() { + return "Group: " + getValue().getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java new file mode 100644 index 00000000000..777196c39c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java @@ -0,0 +1,49 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.openapi.roots.OrderEntry; + +/** + * @author Eugene Zhuravlev + * Date: Sep 17, 2003 + * Time: 7:08:30 PM + */ +public final class NamedLibraryElement { + private final LibraryGroupElement myParent; + private final OrderEntry myEntry; + + public NamedLibraryElement(LibraryGroupElement parent, OrderEntry entry) { + myParent = parent; + myEntry = entry; + } + + public LibraryGroupElement getParent() { + return myParent; + } + + public String getName() { + return myEntry.getPresentableName(); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NamedLibraryElement)) return false; + + final NamedLibraryElement namedLibraryElement = (NamedLibraryElement)o; + + if (!myEntry.equals(namedLibraryElement.myEntry)) return false; + if (!myParent.equals(namedLibraryElement.myParent)) return false; + + return true; + } + + public int hashCode() { + int result; + result = myParent.hashCode(); + result = 29 * result + myEntry.hashCode(); + return result; + } + + public OrderEntry getOrderEntry() { + return myEntry; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java new file mode 100644 index 00000000000..1c596f8e242 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java @@ -0,0 +1,77 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.JdkOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class NamedLibraryElementNode extends ProjectViewNode{ + + private static final Icon LIB_ICON_OPEN = IconLoader.getIcon("/nodes/ppLibOpen.png"); + private static final Icon LIB_ICON_CLOSED = IconLoader.getIcon("/nodes/ppLibClosed.png"); + + public NamedLibraryElementNode(Project project, NamedLibraryElement value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public Collection getChildren() { + final List children = new ArrayList(); + LibraryGroupNode.addLibraryChildren(getValue().getOrderEntry(), children, getProject(), this); + return children; + } + + public String getTestPresentation() { + return "Library: " + getValue().getName(); + } + + private static Icon getJdkIcon(JdkOrderEntry entry, boolean isExpanded) { + final ProjectJdk jdk = entry.getJdk(); + if (jdk == null) { + return CellAppearanceUtils.GENERIC_JDK_ICON; + } + return isExpanded? jdk.getSdkType().getIconForExpandedTreeNode() : jdk.getSdkType().getIcon(); + } + + public String getName() { + return getValue().getName(); + } + + public boolean contains(VirtualFile file) { + return orderEntryContainsFile(getValue().getOrderEntry(), file); + + } + + public static boolean orderEntryContainsFile(OrderEntry orderEntry, VirtualFile file) { + VirtualFile[] files = orderEntry.getFiles(OrderRootType.CLASSES); + for (int i = 0; i < files.length; i++) { + VirtualFile virtualFile = files[i]; + boolean ancestor = VfsUtil.isAncestor(virtualFile, file, false); + if (ancestor) return true; + } + + return false; + } + + public void update(PresentationData presentation) { + presentation.setPresentableText(getValue().getName()); + final OrderEntry orderEntry = getValue().getOrderEntry(); + presentation.setOpenIcon((orderEntry instanceof JdkOrderEntry)? getJdkIcon(((JdkOrderEntry)orderEntry), true) : LIB_ICON_OPEN); + presentation.setClosedIcon((orderEntry instanceof JdkOrderEntry)? getJdkIcon(((JdkOrderEntry)orderEntry), false) : LIB_ICON_CLOSED); + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElement.java new file mode 100644 index 00000000000..3a38165b3b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElement.java @@ -0,0 +1,54 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.openapi.module.Module; +import com.intellij.psi.PsiPackage; + +/** + * @author Eugene Zhuravlev + * Date: Sep 19, 2003 + * Time: 3:51:02 PM + */ +public final class PackageElement { + private final Module myModule; + private final PsiPackage myElement; + private final boolean myIsLibraryElement; + + public PackageElement(Module module, PsiPackage element, boolean isLibraryElement) { + myModule = module; + myElement = element; + myIsLibraryElement = isLibraryElement; + } + + public Module getModule() { + return myModule; + } + + public PsiPackage getPackage() { + return myElement; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PackageElement)) return false; + + final PackageElement packageElement = (PackageElement)o; + + if (myIsLibraryElement != packageElement.myIsLibraryElement) return false; + if (myElement != null ? !myElement.equals(packageElement.myElement) : packageElement.myElement != null) return false; + if (myModule != null ? !myModule.equals(packageElement.myModule) : packageElement.myModule != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myModule != null ? myModule.hashCode() : 0); + result = 29 * result + (myElement != null ? myElement.hashCode() : 0); + result = 29 * result + (myIsLibraryElement ? 1 : 0); + return result; + } + + public boolean isLibraryElement() { + return myIsLibraryElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElementNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElementNode.java new file mode 100644 index 00000000000..b4d8ea4405e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageElementNode.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.TreeViewUtil; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class PackageElementNode extends ProjectViewNode { + protected static final Icon PACKAGE_OPEN_ICON = IconLoader.getIcon("/nodes/packageOpen.png"); + protected static final Icon PACKAGE_CLOSED_ICON = IconLoader.getIcon("/nodes/packageClosed.png"); + + public PackageElementNode(final Project project, + final PackageElement value, + final ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public boolean contains(final VirtualFile file) { + if (!isUnderContent(file)) { + return false; + } + + final PsiDirectory[] directories = getValue().getPackage().getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (VfsUtil.isAncestor(directory.getVirtualFile(), file, false)) return true; + } + return false; + } + + private boolean isUnderContent(final VirtualFile file) { + final Module module = getValue().getModule(); + if (module == null) { + return PackageUtil.projectContainsFile(getProject(), file, getSettings(), isLibraryElement()); + } + else { + return PackageUtil.moduleContainsFile(module, file, getSettings(), isLibraryElement()); + } + } + + private boolean isLibraryElement() { + return getValue().isLibraryElement(); + } + + public Collection getChildren() { + final List children = new ArrayList(); + + final PackageElement value = getValue(); + final Module module = value.getModule(); + final PsiPackage aPackage = value.getPackage(); + + if (!getSettings().isFlattenPackages()) { + + final PsiPackage[] subpackages = PackageUtil.getSubpackages(aPackage, module, myProject, isLibraryElement()); + for (int idx = 0; idx < subpackages.length; idx++) { + PackageUtil.addPackageAsChild(children, subpackages[idx], module, getSettings(), isLibraryElement()); + } + } + // process only files in package's drectories + final GlobalSearchScope scopeToShow = PackageUtil.getScopeToShow(myProject, module, isLibraryElement()); + final PsiDirectory[] dirs = aPackage.getDirectories(scopeToShow); + for (int idx = 0; idx < dirs.length; idx++) { + final PsiDirectory dir = dirs[idx]; + children.addAll(PackageUtil.getDirectoryChildren(dir, getSettings(), false)); + } + return children; + } + + + public void update(final PresentationData presentation) { + if (getValue() != null && getValue().getPackage().isValid()) { + updateValidData(presentation); + } + else { + setValue(null); + } + } + + private void updateValidData(final PresentationData presentation) { + final PsiPackage aPackage = getValue().getPackage(); + + if (!getSettings().isFlattenPackages()) { + if (getSettings().isHideEmptyMiddlePackages()) { + if (PackageUtil.isPackageEmpty(aPackage, getValue().getModule(), true, isLibraryElement())) { + setValue(null); + return; + } + } + } + + if (showFwName(aPackage)) { + presentation.setPresentableText((getSettings().isAbbreviatePackageNames() + ? TreeViewUtil.calcAbbreviatedPackageFQName(aPackage) + : aPackage.getQualifiedName())); + } + else { + if (!(getParentValue() instanceof PackageElement)) { + presentation.setPresentableText(aPackage.getQualifiedName()); + } + else { + final PsiPackage parentPackageInTree = ((PackageElement)getParentValue()).getPackage(); + PsiPackage parentPackage = aPackage.getParentPackage(); + final StringBuffer buf = new StringBuffer(); + buf.append(aPackage.getName()); + while (parentPackage != null && !parentPackage.equals(parentPackageInTree)) { + buf.insert(0, "."); + buf.insert(0, parentPackage.getName()); + parentPackage = parentPackage.getParentPackage(); + } + presentation.setPresentableText(buf.toString()); + } + } + + presentation.setOpenIcon(PackageUtil.PACKAGE_OPEN_ICON); + presentation.setClosedIcon(PackageUtil.PACKAGE_CLOSED_ICON); + } + + private boolean showFwName(final PsiPackage aPackage) { + final boolean showFqName; + if (!getSettings().isFlattenPackages()) { + showFqName = false; + } + else { + showFqName = aPackage.getQualifiedName().length() > 0; + } + return showFqName; + } + + public String getTestPresentation() { + return "PsiPackage: " + getValue().getPackage().getQualifiedName(); + } + + public boolean isFQNameShown() { + return getValue() == null ? false : showFwName(getValue().getPackage()); + } + + public boolean valueIsCut() { + return getValue() != null && CopyPasteManager.getInstance().isCutElement(getValue().getPackage()); + } + + public VirtualFile[] getVirtualFiles() { + final PsiDirectory[] directories = getValue().getPackage().getDirectories(PackageUtil.getScopeToShow(getProject(), getValue().getModule(), isLibraryElement())); + final VirtualFile[] result = new VirtualFile[directories.length]; + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + result[i] = directory.getVirtualFile(); + } + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageUtil.java new file mode 100644 index 00000000000..4d6bbcd3095 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageUtil.java @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.TreeViewUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.LayeredIcon; +import com.intellij.util.Icons; + +import javax.swing.*; +import java.util.*; + +public class PackageUtil { + protected static final Icon PACKAGE_OPEN_ICON = IconLoader.getIcon("/nodes/packageOpen.png"); + protected static final Icon PACKAGE_CLOSED_ICON = IconLoader.getIcon("/nodes/packageClosed.png"); + protected static final Icon TREE_CLOSED_ICON = Icons.DIRECTORY_CLOSED_ICON; + protected static final Icon TREE_OPEN_ICON = Icons.DIRECTORY_OPEN_ICON; + private static final Icon LOCKED_ICON = IconLoader.getIcon("/nodes/locked.png"); + static private final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode"); + + public static PsiPackage[] getSubpackages(PsiPackage aPackage, + Module module, + final Project project, + final boolean searchInLibraries) { + final GlobalSearchScope scopeToShow = getScopeToShow(project, module, searchInLibraries); + final PsiDirectory[] dirs = aPackage.getDirectories(scopeToShow); + final Set subpackages = new HashSet(); + for (int idx = 0; idx < dirs.length; idx++) { + PsiDirectory dir = dirs[idx]; + final PsiDirectory[] subdirectories = dir.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + PsiDirectory subdirectory = subdirectories[i]; + final PsiPackage psiPackage = subdirectory.getPackage(); + if (psiPackage != null) { + final String name = psiPackage.getName(); + // skip "default" subpackages as they should be attributed to other modules + // this is the case when contents of one module is nested into contents of another + if (name != null && !"".equals(name)) { + subpackages.add(psiPackage); + } + } + } + } + return subpackages.toArray(new PsiPackage[subpackages.size()]); + } + + public static void addPackageAsChild(final Collection children, + final PsiPackage aPackage, + Module module, + ViewSettings settings, + final boolean inLibrary) { + final boolean shouldSkipPackage = settings.isHideEmptyMiddlePackages() + && isPackageEmpty(aPackage, module, + false, + inLibrary); + final Project project = aPackage.getManager().getProject(); + if (!shouldSkipPackage) { + children.add(new PackageElementNode(project, + new PackageElement(module, aPackage, inLibrary), settings)); + } + if (settings.isFlattenPackages() || shouldSkipPackage) { + final PsiPackage[] subpackages = PackageUtil.getSubpackages(aPackage, module, project, inLibrary); + for (int idx = 0; idx < subpackages.length; idx++) { + addPackageAsChild(children, subpackages[idx], module, settings, inLibrary); + } + } + } + + public static boolean isPackageEmpty(PsiPackage aPackage, + Module module, + boolean strictlyEmpty, + final boolean inLibrary) { + final Project project = aPackage.getManager().getProject(); + final GlobalSearchScope scopeToShow = getScopeToShow(project, module, inLibrary); + final PsiDirectory[] dirs = aPackage.getDirectories(scopeToShow); + for (int idx = 0; idx < dirs.length; idx++) { + final PsiDirectory dir = dirs[idx]; + if (dir.getChildren().length == 0) return true; + if (!TreeViewUtil.isEmptyMiddlePackage(dir, strictlyEmpty)) { + return false; + } + } + return true; + } + + public static GlobalSearchScope getScopeToShow(final Project project, final Module module, boolean forLibraries) { + if (module != null) { + if (forLibraries) { + return new ModuleLibrariesSearchScope(module); + } + else { + return GlobalSearchScope.moduleScope(module); + } + } + else { + if (forLibraries) { + return new ProjectLibrariesSearchScope(project); + } + else { + return GlobalSearchScope.projectScope(project); + } + } + } + + + public static boolean isPackageDefault(PsiPackage directoryPackage) { + final String qName = directoryPackage.getQualifiedName(); + return qName == null || qName.length() == 0; + } + + public static Collection createPackageViewChildrenOnFiles(final List sourceRoots, + final Project project, + final ViewSettings settings, + final Module module, + final boolean inLibrary) { + final PsiManager psiManager = PsiManager.getInstance(project); + + final List children = new ArrayList(); + final Set topLevelPackages = new HashSet(); + + for (Iterator it = sourceRoots.iterator(); it.hasNext();) { + final VirtualFile root = it.next(); + final PsiDirectory directory = psiManager.findDirectory(root); + if (directory == null) { + continue; + } + final PsiPackage directoryPackage = directory.getPackage(); + if (directoryPackage == null || isPackageDefault(directoryPackage)) { + // add subpackages + final PsiDirectory[] subdirectories = directory.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + final PsiPackage aPackage = subdirectories[i].getPackage(); + if (aPackage != null && !isPackageDefault(aPackage)) { + topLevelPackages.add(aPackage); + } + } + // add non-dir items + children.addAll(getDirectoryChildren(directory, settings, false)); + } + else { + topLevelPackages.add(directoryPackage); + } + } + + for (Iterator it = topLevelPackages.iterator(); it.hasNext();) { + addPackageAsChild(children, it.next(), module, settings, inLibrary); + } + + return children; + } + + public static boolean moduleContainsFile(final Module module, VirtualFile file, ViewSettings settings, boolean isLibraryElement) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + if (isLibraryElement) { + OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); + for (int i = 0; i < orderEntries.length; i++) { + OrderEntry orderEntry = orderEntries[i]; + if (NamedLibraryElementNode.orderEntryContainsFile(orderEntry, file)) { + return orderEntry instanceof ModuleJdkOrderEntry || orderEntry instanceof LibraryOrderEntry; + } + } + return false; + } + else { + return moduleRootManager.getFileIndex().isInContent(file); + } + } + + public static boolean projectContainsFile(final Project project, VirtualFile file, ViewSettings settings, boolean isLibraryElement) { + final Module[] modules = ModuleManager.getInstance(project).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + if (moduleContainsFile(module, file, settings, isLibraryElement)) return true; + } + return false; + } + + public static boolean isSourceRoot(final PsiDirectory psiDirectory) { + return psiDirectory.getVirtualFile().equals( + ProjectRootManager.getInstance(psiDirectory.getManager().getProject()).getFileIndex() + .getSourceRootForFile(psiDirectory.getVirtualFile())); + } + + public static boolean isPackage(final PsiDirectory psiDirectory) { + return psiDirectory.getPackage() != null; + } + + public static boolean isFQNameShown(final PsiDirectory value, final Object parentValue, final ViewSettings settings) { + if (value == null) return false; + + if (parentValue instanceof Project) { + return false; + } + else { + if (settings.isFlattenPackages()) { + return !isSourceRoot(value) && isPackage(value) && value.getPackage().getQualifiedName().length() > 0; + } + else { + return false; + } + } + } + + public static void updatePsiDirectoryData(final PresentationData data, + final Project project, + final PsiDirectory psiDirectory, + final ViewSettings settings, + final Object parentValue, + final AbstractTreeNode node) { + final VirtualFile directoryFile = psiDirectory.getVirtualFile(); + boolean withComment = isModuleContentRoot(directoryFile, project) || isLibraryRoot(directoryFile, project); + updateDefault(data, psiDirectory, settings, parentValue, node); + if (withComment) { + data.setLocationString(directoryFile.getPresentableUrl()); + } + } + + private static void updateDefault(PresentationData data, + final PsiDirectory psiDirectory, + final ViewSettings settings, + final Object parentValue, + final AbstractTreeNode node) { + PsiPackage aPackage = psiDirectory.getPackage(); + final VirtualFile virtualFile = psiDirectory.getVirtualFile(); + + if (isPackage(psiDirectory) && !isSourceRoot(psiDirectory) && !settings.isFlattenPackages() && settings.isHideEmptyMiddlePackages()) { + if (TreeViewUtil.isEmptyMiddlePackage(psiDirectory, true)) { + node.setValue(null); + return; + } + } + + final boolean isWritable = virtualFile.isWritable(); + + final String name; + if (parentValue instanceof Project) { + name = psiDirectory.getVirtualFile().getPresentableUrl(); + } + else { + + if (isFQNameShown(psiDirectory, parentValue, settings)) { + name = (settings.isAbbreviatePackageNames() + ? TreeViewUtil.calcAbbreviatedPackageFQName(aPackage) + : aPackage.getQualifiedName()); + } + else { + if (!isSourceRoot(psiDirectory) && aPackage != null && aPackage.getQualifiedName().length() > 0 && + parentValue instanceof PsiDirectory) { + final PsiPackage parentPackageInTree = ((PsiDirectory)parentValue).getPackage(); + PsiPackage parentPackage = aPackage.getParentPackage(); + final StringBuffer buf = new StringBuffer(); + buf.append(aPackage.getName()); + while (parentPackage != null && !parentPackage.equals(parentPackageInTree)) { + final String parentPackageName = parentPackage.getName(); + if (parentPackageName == null || "".equals(parentPackageName)) { + break; // reached default package + } + buf.insert(0, "."); + buf.insert(0, parentPackageName); + parentPackage = parentPackage.getParentPackage(); + } + name = buf.toString(); + } + else { + name = psiDirectory.getName(); + } + } + } + + final String packagePrefix = isSourceRoot(psiDirectory) && aPackage != null ? aPackage.getQualifiedName() : ""; + + data.setPresentableText(name); + data.setLocationString(packagePrefix); + + if (isPackage(psiDirectory)) { + data.setOpenIcon(addReadMark(PACKAGE_OPEN_ICON, isWritable)); + data.setClosedIcon(addReadMark(PACKAGE_CLOSED_ICON, isWritable)); + } + else { + data.setOpenIcon(addReadMark(TREE_OPEN_ICON, isWritable)); + data.setClosedIcon(addReadMark(TREE_CLOSED_ICON, isWritable)); + } + } + + public static boolean isModuleContentRoot(VirtualFile directoryFile, Project project) { + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final VirtualFile contentRootForFile = projectFileIndex.getContentRootForFile(directoryFile); + return directoryFile.equals(contentRootForFile); + } + + public static boolean isLibraryRoot(VirtualFile directoryFile, Project project) { + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (projectFileIndex.isInLibraryClasses(directoryFile)) { + final VirtualFile parent = directoryFile.getParent(); + return parent == null || !projectFileIndex.isInLibraryClasses(parent); + } + return false; + } + + protected static Icon addReadMark(Icon originalIcon, boolean isWritable) { + if (isWritable) { + return originalIcon; + } + else { + LayeredIcon icon = new LayeredIcon(2); + icon.setIcon(originalIcon, 0); + icon.setIcon(LOCKED_ICON, 1); + return icon; + } + } + + public static Collection getDirectoryChildren(final PsiDirectory psiDirectory, + final ViewSettings settings, + boolean withSubDirectories) { + final List children = new ArrayList(); + final Project project = psiDirectory.getManager().getProject(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final Module module = fileIndex.getModuleForFile(psiDirectory.getVirtualFile()); + final ModuleFileIndex moduleFileIndex = module == null ? null : ModuleRootManager.getInstance(module).getFileIndex(); + if (!settings.isFlattenPackages() || psiDirectory.getPackage() == null) { + processPsiDirectoryChildren(psiDirectory, psiDirectory.getChildren(), children, fileIndex, moduleFileIndex, settings, + withSubDirectories); + } + else { // source directory in "flatten packages" mode + final PsiDirectory parentDir = psiDirectory.getParentDirectory(); + if (parentDir == null || parentDir.getPackage() == null /*|| !rootDirectoryFound(parentDir)*/ && withSubDirectories) { + addAllSubpackages(children, psiDirectory, moduleFileIndex, settings); + } + PsiDirectory[] subdirs = psiDirectory.getSubdirectories(); + for (int i = 0; i < subdirs.length; i++) { + PsiDirectory subdir = subdirs[i]; + if (subdir.getPackage() != null) { + continue; + } + if (moduleFileIndex != null) { + if (!moduleFileIndex.isInContent(subdir.getVirtualFile())) { + continue; + } + } + if (withSubDirectories) { + children.add(new PsiDirectoryNode(project, subdir, settings)); + } + } + processPsiDirectoryChildren(psiDirectory, psiDirectory.getFiles(), children, fileIndex, moduleFileIndex, settings, + withSubDirectories); + } + return children; + } + + // used only for non-flatten packages mode + private static void processPsiDirectoryChildren(final PsiDirectory psiDir, + PsiElement[] children, + List container, + ProjectFileIndex projectFileIndex, + ModuleFileIndex moduleFileIndex, + ViewSettings viewSettings, + boolean withSubDirectories) { + for (int idx = 0; idx < children.length; idx++) { + PsiElement child = children[idx]; + LOG.assertTrue(child.isValid()); + + final VirtualFile vFile; + if (child instanceof PsiFile) { + vFile = ((PsiFile)child).getVirtualFile(); + addNode(moduleFileIndex, projectFileIndex, psiDir, vFile, container, PsiFileNode.class, child, viewSettings); + } + else if (child instanceof PsiDirectory) { + if (withSubDirectories) { + PsiDirectory dir = (PsiDirectory)child; + vFile = dir.getVirtualFile(); + if (vFile != null && !vFile.equals(projectFileIndex.getSourceRootForFile(vFile))) { // if is not a source root + if (viewSettings.isHideEmptyMiddlePackages() && dir.getPackage() != null && TreeViewUtil.isEmptyMiddlePackage(dir, true)) { + processPsiDirectoryChildren(dir, dir.getChildren(), container, projectFileIndex, moduleFileIndex, viewSettings, + withSubDirectories); // expand it recursively + continue; + } + } + addNode(moduleFileIndex, projectFileIndex, psiDir, vFile, container, PsiDirectoryNode.class, child, viewSettings); + } + } + else { + LOG.assertTrue(false, "Either PsiFile or PsiDirectory expected as a child of " + child.getParent() + ", but was " + child); + continue; + } + } + } + + private static void addNode(ModuleFileIndex moduleFileIndex, + ProjectFileIndex projectFileIndex, + PsiDirectory psiDir, + VirtualFile vFile, + List container, + Class nodeClass, + PsiElement element, + final ViewSettings settings) { + if (vFile == null) { + return; + } + // this check makes sense for classes not in library content only + if (moduleFileIndex != null && !moduleFileIndex.isInContent(vFile)) { + return; + } + final boolean childInLibraryClasses = projectFileIndex.isInLibraryClasses(vFile); + if (!projectFileIndex.isInSourceContent(vFile)) { + if (childInLibraryClasses) { + final VirtualFile psiDirVFile = psiDir.getVirtualFile(); + final boolean parentInLibraryContent = + projectFileIndex.isInLibraryClasses(psiDirVFile) || projectFileIndex.isInLibrarySource(psiDirVFile); + if (!parentInLibraryContent) { + return; + } + } + } + if (childInLibraryClasses && !projectFileIndex.isInContent(vFile) && projectFileIndex.isJavaSourceFile(vFile)) { + return; // skip java sources in classpath + } + + try { + container.add(ProjectViewNode.createTreeNode(nodeClass, element.getManager().getProject(), element, settings)); + } + catch (Exception e) { + LOG.error(e); + } + } + + // used only in flatten packages mode + private static void addAllSubpackages(List container, + PsiDirectory dir, + ModuleFileIndex moduleFileIndex, + ViewSettings viewSettings) { + final Project project = dir.getManager().getProject(); + PsiDirectory[] subdirs = dir.getSubdirectories(); + for (int i = 0; i < subdirs.length; i++) { + PsiDirectory subdir = subdirs[i]; + if (subdir.getPackage() == null) { + continue; + } + if (moduleFileIndex != null) { + if (!moduleFileIndex.isInContent(subdir.getVirtualFile())) { + continue; + } + } + if (viewSettings.isHideEmptyMiddlePackages()) { + if (!TreeViewUtil.isEmptyMiddlePackage(subdir, false)) { + + container.add(new PsiDirectoryNode(project, subdir, viewSettings)); + } + } + else { + container.add(new PsiDirectoryNode(project, subdir, viewSettings)); + } + addAllSubpackages(container, subdir, moduleFileIndex, viewSettings); + } + } + + private static class ModuleLibrariesSearchScope extends GlobalSearchScope { + private final Module myModule; + + public ModuleLibrariesSearchScope(final Module module) { + myModule = module; + } + + public boolean contains(VirtualFile file) { + final OrderEntry orderEntry = ModuleRootManager.getInstance(myModule).getFileIndex().getOrderEntryForFile(file); + return orderEntry instanceof JdkOrderEntry || orderEntry instanceof LibraryOrderEntry; + } + + public int compare(VirtualFile file1, VirtualFile file2) { + final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(myModule).getFileIndex(); + return fileIndex.getOrderEntryForFile(file1).compareTo(fileIndex.getOrderEntryForFile(file2)); + } + + public boolean isSearchInModuleContent(Module aModule) { + return false; + } + + public boolean isSearchInLibraries() { + return true; + } + } + + private static class ProjectLibrariesSearchScope extends GlobalSearchScope { + private final Project myProject; + + public ProjectLibrariesSearchScope(final Project project) { + myProject = project; + } + + private Module[] getModules(final Project project) { + return ModuleManager.getInstance(project).getModules(); + } + + public boolean contains(VirtualFile file) { + final Module[] modules = getModules(myProject); + for (int i = 0; i < modules.length; i++) { + Module module1 = modules[i]; + final OrderEntry orderEntryForFile = ModuleRootManager.getInstance(module1).getFileIndex().getOrderEntryForFile(file); + if (orderEntryForFile instanceof ModuleJdkOrderEntry || orderEntryForFile instanceof LibraryOrderEntry) return true; + } + return false; + } + + public int compare(VirtualFile file1, VirtualFile file2) { + final Module[] modules = getModules(myProject); + for (int i = 0; i < modules.length; i++) { + Module module1 = modules[i]; + final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module1).getFileIndex(); + final OrderEntry orderEntry1 = fileIndex.getOrderEntryForFile(file1); + if (orderEntry1 != null) { + final OrderEntry orderEntry2 = fileIndex.getOrderEntryForFile(file2); + if (orderEntry2 != null) { + return orderEntry1.compareTo(orderEntry2); + } + else { + return 0; + } + } + } + return 0; + } + + public boolean isSearchInModuleContent(Module aModule) { + return false; + } + + public boolean isSearchInLibraries() { + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewLibrariesNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewLibrariesNode.java new file mode 100644 index 00000000000..29bc3e2b698 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewLibrariesNode.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Icons; +import com.intellij.projectView.LibrariesElement; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class PackageViewLibrariesNode extends ProjectViewNode{ + public PackageViewLibrariesNode(final Project project, Module module, final ViewSettings viewSettings) { + super(project, new LibrariesElement(module, project), viewSettings); + } + + public boolean contains(final VirtualFile file) { + return someChildContainsFile(file); + } + + public Collection getChildren() { + final ArrayList roots = new ArrayList(); + if (getValue().getModule() == null) { + final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + addModuleLibraryRoots(ModuleRootManager.getInstance(module), roots); + } + + } else { + addModuleLibraryRoots(ModuleRootManager.getInstance(getValue().getModule()), roots); + } + return PackageUtil.createPackageViewChildrenOnFiles(roots, getProject(), getSettings(), null, true); + } + + private static void addModuleLibraryRoots(ModuleRootManager moduleRootManager, List roots) { + final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); + for (int idx = 0; idx < orderEntries.length; idx++) { + final OrderEntry orderEntry = orderEntries[idx]; + if (!(orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry)) { + continue; + } + final VirtualFile[] files = orderEntry.getFiles(OrderRootType.CLASSES); + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + if (file.getFileSystem() instanceof JarFileSystem && file.getParent() != null) { + // skip entries inside jars + continue; + } + roots.add(file); + } + } + } + + public void update(final PresentationData presentation) { + presentation.setPresentableText("Libraries"); + presentation.setIcons(Icons.LIBRARY_ICON); + } + + public String getTestPresentation() { + return "Libraries"; + } + + public boolean shouldUpdateData() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java new file mode 100644 index 00000000000..fd22cca9784 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; + +import java.util.Arrays; +import java.util.Collection; + +public class PackageViewModuleNode extends AbstractModuleNode{ + public PackageViewModuleNode(Project project, Module value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public PackageViewModuleNode(Project project, Object value, ViewSettings viewSettings) { + this(project, (Module)value, viewSettings); + } + + public Collection getChildren() { + final Collection result = PackageUtil.createPackageViewChildrenOnFiles(Arrays.asList(ModuleRootManager.getInstance(getValue()).getSourceRoots()), myProject, getSettings(), getValue(), false); + if (getSettings().isShowLibraryContents()) { + result.add(new PackageViewLibrariesNode(getProject(), getValue(),getSettings())); + } + return result; + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewProjectNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewProjectNode.java new file mode 100644 index 00000000000..12b5e7cb6c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PackageViewProjectNode.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiDirectory; + +import java.util.*; + +public class PackageViewProjectNode extends AbstractProjectNode { + public PackageViewProjectNode(Project project, ViewSettings viewSettings) { + super(project, project, viewSettings); + } + + public Collection getChildren() { + if (getSettings().isShowModules()) { + final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + return modulesAndGroups(modules); + } + else { + final List sourceRoots = new ArrayList(); + final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject); + sourceRoots.addAll(Arrays.asList(projectRootManager.getContentSourceRoots())); + + final PsiManager psiManager = PsiManager.getInstance(myProject); + final List children = new ArrayList(); + final Set topLevelPackages = new HashSet(); + final ProjectFileIndex projectFileIndex = projectRootManager.getFileIndex(); + + for (Iterator it = sourceRoots.iterator(); it.hasNext();) { + final VirtualFile root = it.next(); + final PsiDirectory directory = psiManager.findDirectory(root); + if (directory == null) { + continue; + } + final PsiPackage directoryPackage = directory.getPackage(); + if (directoryPackage == null || PackageUtil.isPackageDefault(directoryPackage)) { + // add subpackages + final PsiDirectory[] subdirectories = directory.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + final PsiPackage aPackage = subdirectories[i].getPackage(); + if (aPackage != null && !PackageUtil.isPackageDefault(aPackage)) { + topLevelPackages.add(aPackage); + } + } + // add non-dir items + children.addAll(PackageUtil.getDirectoryChildren(directory, getSettings(), false)); + } + else { + // this is the case when a source root has pakage prefix assigned + topLevelPackages.add(directoryPackage); + } + } + + for (Iterator it = topLevelPackages.iterator(); it.hasNext();) { + PackageUtil.addPackageAsChild(children, it.next(), null, getSettings(), false); + } + + if (getSettings().isShowLibraryContents()) { + children.add(new PackageViewLibrariesNode(getProject(), null, getSettings())); + } + + return children; + } + + + } + + protected Class getModuleNodeClass() { + return PackageViewModuleNode.class; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java new file mode 100644 index 00000000000..2cbaf9b0353 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java @@ -0,0 +1,53 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleFileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ProjectViewModuleNode extends AbstractModuleNode { + + static private final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode"); + + public ProjectViewModuleNode(Project project, Module value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public ProjectViewModuleNode(Project project, Object value, ViewSettings viewSettings) { + this(project, (Module)value, viewSettings); + } + + public Collection getChildren() { + ModuleRootManager rootManager = ModuleRootManager.getInstance(getValue()); + ModuleFileIndex moduleFileIndex = rootManager.getFileIndex(); + + final VirtualFile[] contentRoots = rootManager.getContentRoots(); + final List children = new ArrayList(contentRoots.length + 1); + final PsiManager psiManager = PsiManager.getInstance(getProject()); + for (int idx = 0; idx < contentRoots.length; idx++) { + final VirtualFile contentRoot = contentRoots[idx]; + + LOG.assertTrue(contentRoot.isDirectory()); + + if (!moduleFileIndex.isInContent(contentRoot)) continue; + + final PsiDirectory psiDirectory = psiManager.findDirectory(contentRoot); + LOG.assertTrue(psiDirectory != null); + + children.add(new PsiDirectoryNode(getProject(), psiDirectory, getSettings())); + } + children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings())); + return children; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java new file mode 100644 index 00000000000..b3ff619e436 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -0,0 +1,26 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; + +import java.util.Collection; + +public class ProjectViewProjectNode extends AbstractProjectNode { + + public ProjectViewProjectNode(Project project, ViewSettings viewSettings) { + super(project, project, viewSettings); + } + + public Collection getChildren() { + final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + return modulesAndGroups(modules); + } + + protected Class getModuleNodeClass() { + return ProjectViewModuleNode.class; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java new file mode 100644 index 00000000000..fbd810e0876 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -0,0 +1,50 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; + +import java.util.Collection; + +public class PsiDirectoryNode extends BasePsiNode { + + public PsiDirectoryNode(Project project, PsiDirectory value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public PsiDirectoryNode(Project project, Object value, ViewSettings viewSettings) { + this(project, (PsiDirectory)value, viewSettings); + } + + public void updateImpl(PresentationData data) { + PackageUtil.updatePsiDirectoryData(data, getProject(), getValue(), getSettings(), getParentValue(), this); + + } + + public Collection getChildrenImpl() { + return PackageUtil.getDirectoryChildren(getValue(), getSettings(), true); + } + + + public String getTestPresentation() { + return "PsiDirectory: " + getValue().getName(); + } + + protected String getRootName() { + return getValue().getVirtualFile().getPresentableUrl(); + } + + public boolean isFQNameShown() { + + return PackageUtil.isFQNameShown(getValue(), getParentValue(), getSettings()); + + } + + public boolean contains(VirtualFile file) { + return VfsUtil.isAncestor(getValue().getVirtualFile(), file, false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFieldNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFieldNode.java new file mode 100644 index 00000000000..507d601c2db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFieldNode.java @@ -0,0 +1,34 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; + +import java.util.Collection; + +public class PsiFieldNode extends BasePsiNode{ + + public PsiFieldNode(Project project, PsiField value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public Collection getChildrenImpl() { + return null; + } + + public void updateImpl(PresentationData data) { + String name = PsiFormatUtil.formatVariable( + (PsiField)getValue(), + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_INITIALIZER, + PsiSubstitutor.EMPTY); + int c = name.indexOf('\n'); + if (c > -1) { + name = name.substring(0, c - 1); + } + data.setPresentableText(name); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java new file mode 100644 index 00000000000..d05084910f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java @@ -0,0 +1,44 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.IconUtilEx; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + +import java.util.ArrayList; +import java.util.Collection; + +public class PsiFileNode extends BasePsiNode{ + + public PsiFileNode(Project project, PsiFile value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public PsiFileNode(Project project, Object value, ViewSettings viewSettings) { + this(project, (PsiFile)value, viewSettings); + } + + public Collection getChildrenImpl() { + if (getSettings().isStructureView() && getValue() instanceof PsiJavaFile){ + PsiClass[] classes = ((PsiJavaFile)getValue()).getClasses(); + ArrayList result = new ArrayList(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + result.add(new ClassTreeNode(getProject(), aClass, getSettings())); + } + return result; + } else { + return null; + } + } + + public void updateImpl(PresentationData data) { + data.setPresentableText(getValue().getName()); + data.setIcons(IconUtilEx.getIcon(getValue(), Iconable.ICON_FLAG_READ_STATUS, getProject())); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiMethodNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiMethodNode.java new file mode 100644 index 00000000000..dad9998ca1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/projectView/impl/nodes/PsiMethodNode.java @@ -0,0 +1,41 @@ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; + +import java.util.Collection; + +public class PsiMethodNode extends BasePsiNode{ + public PsiMethodNode(Project project, PsiMethod value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + public Collection getChildrenImpl() { + return null; + } + + public void updateImpl(PresentationData data) { + String name = PsiFormatUtil.formatMethod( + getValue(), + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + int c = name.indexOf('\n'); + if (c > -1) { + name = name.substring(0, c - 1); + } + data.setPresentableText(name); + } + + public boolean isConstructor() { + final PsiMethod psiMethod = (getValue()); + if (psiMethod == null) return false; + return psiMethod.isConstructor(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/CacheUpdater.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/CacheUpdater.java new file mode 100644 index 00000000000..1c0563c5090 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/CacheUpdater.java @@ -0,0 +1,10 @@ +package com.intellij.ide.startup; + +import com.intellij.openapi.vfs.VirtualFile; + +public interface CacheUpdater { + VirtualFile[] queryNeededFiles(); + void processFile(FileContent fileContent); + void updatingDone(); + void canceled(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileContent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileContent.java new file mode 100644 index 00000000000..91e3baedf6e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileContent.java @@ -0,0 +1,75 @@ +package com.intellij.ide.startup; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.UserDataHolder; +import com.intellij.openapi.vfs.VirtualFile; +import gnu.trove.THashMap; + +import java.io.IOException; + +/** + * @author max + */ +public class FileContent implements UserDataHolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.startup.FileContent"); + + private VirtualFile myVirtualFile; + private byte[] myCachedBytes; + private THashMap myUserMap = null; + private boolean myGetBytesCalled = false; + + public FileContent(VirtualFile virtualFile) { + myVirtualFile = virtualFile; + } + + public byte[] getBytes() throws IOException { + myGetBytesCalled = true; + if (myCachedBytes == null) { + myCachedBytes = myVirtualFile.contentsToByteArray(); + } + + return myCachedBytes; + } + + public byte[] getPhysicalBytes() throws IOException { + if (myGetBytesCalled) { + LOG.error("getPhysicalBytes() called after getBytes() for " + myVirtualFile); + } + + if (myCachedBytes == null) { + myCachedBytes = myVirtualFile.physicalContentsToByteArray(); + } + + return myCachedBytes; + } + + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + public T getUserData(Key key){ + synchronized(this){ + if (myUserMap == null) return null; + return (T)myUserMap.get(key); + } + } + + public void putUserData(Key key, T value){ + synchronized(this){ + if (myUserMap == null){ + if (value == null) return; + myUserMap = new THashMap(1); + } + if (value != null){ + myUserMap.put(key, value); + } + else{ + myUserMap.remove(key); + if (myUserMap.size() == 0){ + myUserMap = null; + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileSystemSynchronizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileSystemSynchronizer.java new file mode 100644 index 00000000000..bb42afe9929 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/FileSystemSynchronizer.java @@ -0,0 +1,188 @@ +package com.intellij.ide.startup; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.*; + +/** + * @author max + */ +public class FileSystemSynchronizer { + private final static Logger LOG = Logger.getInstance("#com.intellij.ide.startup.FileSystemSynchronizer"); + + private ArrayList myUpdaters = new ArrayList(); + private LinkedHashSet myFilesToUpdate = new LinkedHashSet(); + private Collection/**/[] myUpdateSets; + + private boolean myIsCancelable = false; + + public void registerCacheUpdater(CacheUpdater cacheUpdater) { + myUpdaters.add(cacheUpdater); + } + + public void setCancelable(boolean isCancelable) { + myIsCancelable = isCancelable; + } + + public void execute() { + /* + long time1 = System.currentTimeMillis(); + */ + + if (!myIsCancelable) { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null){ + indicator.startNonCancelableSection(); + } + } + + try { + if (myUpdateSets == null) { // collectFilesToUpdate() was not executed before + if (collectFilesToUpdate() == 0) return; + } + + updateFiles(); + } + catch(ProcessCanceledException e){ + for (Iterator iterator = myUpdaters.iterator(); iterator.hasNext();) { + CacheUpdater updater = iterator.next(); + if (updater != null) { + updater.canceled(); + } + } + throw e; + } + finally { + if (!myIsCancelable) { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null){ + indicator.finishNonCancelableSection(); + } + } + } + + /* + long time2 = System.currentTimeMillis(); + System.out.println("synchronizer.execute() in " + (time2 - time1) + " ms"); + */ + } + + public int collectFilesToUpdate() { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.pushState(); + indicator.setText("Scanning files..."); + } + + myUpdateSets = new Collection[myUpdaters.size()]; + for (int i = 0; i < myUpdaters.size(); i++) { + CacheUpdater updater = myUpdaters.get(i); + try { + VirtualFile[] updaterFiles = updater.queryNeededFiles(); + Collection localSet = new LinkedHashSet(Arrays.asList(updaterFiles)); + myFilesToUpdate.addAll(localSet); + myUpdateSets[i] = localSet; + } + catch(ProcessCanceledException e){ + throw e; + } + catch (Exception e) { + LOG.error(e); + myUpdateSets[i] = new ArrayList(); + } + } + + if (indicator != null) { + indicator.popState(); + } + + if (myFilesToUpdate.size() == 0) { + updatingDone(); + } + + return myFilesToUpdate.size(); + } + + private void updateFiles() { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.pushState(); + indicator.setText("Parsing files. Please wait..."); + } + + int totalFiles = myFilesToUpdate.size(); + int count = 0; + + for (Iterator iterator = myFilesToUpdate.iterator(); iterator.hasNext();) { + VirtualFile file = iterator.next(); + + if (indicator != null) { + indicator.setFraction(((double)++count) / totalFiles); + indicator.setText2(file.getPresentableUrl()); + } + + FileContent content = new FileContent(file); + for (int i = 0; i < myUpdaters.size(); i++) { + CacheUpdater updater = myUpdaters.get(i); + if (myUpdateSets[i].remove(file)) { + try { + updater.processFile(content); + } + catch(ProcessCanceledException e){ + throw e; + } + catch (Exception e) { + LOG.error(e); + } + + if (myUpdateSets[i].isEmpty()) { + try { + updater.updatingDone(); + } + catch(ProcessCanceledException e){ + throw e; + } + catch (Exception e) { + LOG.error(e); + } + + myUpdaters.set(i, null); + } + } + } + } + + updatingDone(); + + if (indicator != null) { + indicator.popState(); + } + } + + private void updatingDone() { + for (int i = 0; i < myUpdaters.size(); i++) { + CacheUpdater updater = myUpdaters.get(i); + try { + if (updater != null) updater.updatingDone(); + } + catch(ProcessCanceledException e){ + throw e; + } + catch (Exception e) { + LOG.error(e); + } + } + + dropUpdaters(); + } + + private void dropUpdaters() { + myUpdaters.clear(); + myFilesToUpdate.clear(); + myUpdateSets = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupActionScriptManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupActionScriptManager.java new file mode 100644 index 00000000000..f94166bc617 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupActionScriptManager.java @@ -0,0 +1,209 @@ +/** + * @author cdr + */ +package com.intellij.ide.startup; + +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.ZipUtil; + +import javax.swing.*; +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class StartupActionScriptManager { + private static final String ACTION_SCRIPT_FILE = "action.script"; + + public static synchronized void executeActionScript() throws IOException { + List commands = loadActionScript(); + + for (int i = 0; i < commands.size(); i++) { + ActionCommand actionCommand = commands.get(i); + System.out.println("Execute " + actionCommand); + actionCommand.execute(); + } + commands.clear(); + + saveActionScript(commands); + } + + public static synchronized void addActionCommand(ActionCommand command) throws IOException { + final List commands = loadActionScript(); + commands.add(command); + saveActionScript(commands); + } + + private static String getActionScriptPath() { + String systemPath = PathManagerEx.getPluginTempPath(); + String filePath = systemPath + File.separator + ACTION_SCRIPT_FILE; + return filePath; + } + + private static List loadActionScript() throws IOException { + File file = new File(getActionScriptPath()); + if (file.exists()) { + ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); + try { + List commands = (List)ois.readObject(); + ois.close(); + + return commands; + } + catch (ClassNotFoundException e) { + // problem with scrambled code + // fas fixed, but still appear because corrupted file still exists + // return empty list. + System.err.println("Internal IDEA file was corrupted. Problem is fixed.\n" + + "If some plugins has been installed/uninstalled, please " + + "re-install/-uninstall them."); + return new ArrayList(); + } + } + else { + return new ArrayList(); + } + } + + private static void saveActionScript(List commands) throws IOException { + File temp = new File(PathManagerEx.getPluginTempPath()); + if (!temp.exists()) { + temp.mkdirs(); + } + + File file = new File(getActionScriptPath()); + ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file, false)); + oos.writeObject(commands); + oos.close(); + } + + private static boolean canCreateFile(File file) { + if (file.exists()) { + return file.canWrite(); + } + else { + try { + file.createNewFile(); + file.delete(); + return true; + } + catch (IOException e) { + return false; + } + } + } + + public interface ActionCommand { + void execute() throws IOException; + } + + public static class CopyCommand implements Serializable, ActionCommand { + private static final String action = "copy"; + private File mySource; + private File myDestination; + + public CopyCommand(File source, File destination) { + myDestination = destination; + mySource = source; + } + + public String toString() { + return action + "[" + mySource.getAbsolutePath() + + (myDestination == null ? "" : ", " + myDestination.getAbsolutePath()) + "]"; + } + + public void execute() throws IOException { + // create dirs for destination + File parentFile = myDestination.getParentFile(); + if (! parentFile.exists()) + if (! myDestination.getParentFile().mkdirs()) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Cannot create parent directory [" + parentFile.getAbsolutePath() + + "] of " + myDestination.getAbsolutePath() + "
    " + + "Please, check your access rights on folder
    " + + parentFile.getParent(), "Installing Plugin", + JOptionPane.ERROR_MESSAGE); + } + + if (!mySource.exists()) { + System.err.println("Source file " + mySource.getAbsolutePath() + " does not exist for action " + this); + } + else if (!canCreateFile(myDestination)) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Cannot copy " + mySource.getAbsolutePath() + "
    to
    " + + myDestination.getAbsolutePath() + "
    " + + "Please, check your access rights on folder
    " + + myDestination.getParent(), "Installing Plugin", + JOptionPane.ERROR_MESSAGE); + } + else { + FileUtil.copy(mySource, myDestination); + } + } + + } + + public static class UnzipCommand implements Serializable, ActionCommand { + private static final String action = "unzip"; + private File mySource; + private FilenameFilter myFilenameFilter; + private File myDestination; + + public UnzipCommand(File source, File destination) { + this(source, destination, null); + } + + public UnzipCommand(File source, File destination, FilenameFilter filenameFilter) { + myDestination = destination; + mySource = source; + myFilenameFilter = filenameFilter; + } + + public String toString() { + return action + "[" + mySource.getAbsolutePath() + + (myDestination == null ? "" : ", " + myDestination.getAbsolutePath()) + "]"; + } + + public void execute() throws IOException { + if (!mySource.exists()) { + System.err.println("Source file " + mySource.getAbsolutePath() + " does not exist for action " + this); + } + else if (!canCreateFile(myDestination)) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Cannot unzip " + mySource.getAbsolutePath() + "
    to
    " + + myDestination.getAbsolutePath() + "
    " + + "Please, check your access rights on folder
    " + + myDestination, "Installing Plugin", + JOptionPane.ERROR_MESSAGE); + } + else { + ZipUtil.extract(mySource, myDestination, myFilenameFilter); + } + } + + } + + public static class DeleteCommand implements Serializable, ActionCommand { + private static final String action = "delete"; + private File mySource; + + public DeleteCommand(File source) { + mySource = source; + } + + public String toString() { + return action + "[" + mySource.getAbsolutePath() + "]"; + } + + public void execute() throws IOException { + if (!FileUtil.delete(mySource)) { + System.err.println("Action " + this + " failed."); + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + "Cannot delete " + mySource.getAbsolutePath() + "
    " + + "Please, check your access rights on folder
    " + + mySource.getAbsolutePath(), "Installing Plugin", + JOptionPane.ERROR_MESSAGE); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupManagerEx.java new file mode 100644 index 00000000000..04e35e4c4a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/StartupManagerEx.java @@ -0,0 +1,18 @@ +package com.intellij.ide.startup; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; + +/** + * @author mike + */ +public abstract class StartupManagerEx extends StartupManager { + public abstract boolean startupActivityRunning(); + public abstract boolean startupActivityPassed(); + public abstract void registerPreStartupActivity(Runnable runnable); // should be used only to register to FileSystemSynchronizer! + public abstract FileSystemSynchronizer getFileSystemSynchronizer(); + + public static StartupManagerEx getInstanceEx(Project project) { + return (StartupManagerEx)getInstance(project); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/impl/StartupManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/impl/StartupManagerImpl.java new file mode 100644 index 00000000000..4a30be699d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/startup/impl/StartupManagerImpl.java @@ -0,0 +1,130 @@ +package com.intellij.ide.startup.impl; + +import com.intellij.ide.startup.FileSystemSynchronizer; +import com.intellij.ide.startup.StartupManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author mike + */ +public class StartupManagerImpl extends StartupManagerEx implements ProjectComponent { + private List myActivities = new ArrayList(); + private List myPostStartupActivities = new ArrayList(); + private List myPreStartupActivities = new ArrayList(); + + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.startup.impl.StartupManagerImpl"); + + private FileSystemSynchronizer myFileSystemSynchronizer = new FileSystemSynchronizer(); + private boolean myStartupActivityRunning = false; + private boolean myStartupActivityPassed = false; + + private Project myProject; + + public StartupManagerImpl(Project project) { + myProject = project; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public String getComponentName() { + return "StartupManager"; + } + + public void registerStartupActivity(Runnable runnable) { + myActivities.add(runnable); + } + + public void registerPostStartupActivity(Runnable runnable) { + myPostStartupActivities.add(runnable); + } + + public boolean startupActivityRunning() { + return myStartupActivityRunning; + } + + public boolean startupActivityPassed() { + return myStartupActivityPassed; + } + + public void registerPreStartupActivity(Runnable runnable) { + myPreStartupActivities.add(runnable); + } + + public FileSystemSynchronizer getFileSystemSynchronizer() { + return myFileSystemSynchronizer; + } + + public void runStartupActivities() { + ApplicationManager.getApplication().runReadAction( + new Runnable() { + public void run() { + runActivities(myPreStartupActivities); + myFileSystemSynchronizer.execute(); + myFileSystemSynchronizer = null; + myStartupActivityRunning = true; + runActivities(myActivities); + + myStartupActivityRunning = false; + myStartupActivityPassed = true; + } + } + ); + } + + public void runPostStartupActivities() { + ApplicationManager.getApplication().assertIsDispatchThread(); + runActivities(myPostStartupActivities); + } + + private void runActivities(final List activities) { + try { + for (Iterator iterator = activities.iterator(); iterator.hasNext();) { + Runnable runnable = iterator.next(); + try { + runnable.run(); + } + catch (Exception ex) { + LOG.error(ex); + } + } + } + finally { + activities.clear(); + } + } + + public void runWhenProjectIsInitialized(final Runnable action) { + final Runnable runnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(action); + } + }; + + if (myProject.isInitialized()) { + runnable.run(); + } + else { + registerPostStartupActivity(new Runnable(){ + public void run() { + runnable.run(); + } + }); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureView.java new file mode 100644 index 00000000000..eb81f988179 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureView.java @@ -0,0 +1,13 @@ +package com.intellij.ide.structureView; + +import com.intellij.openapi.fileEditor.FileEditor; + +public interface StructureView { + int SORT_ALPHA = 0; + int SORT_SOURCE = 1; + int SORT_ALPHA_VISIBILITY = 2; + int SORT_VISIBILITY = 3; + + boolean select(Object element, FileEditor fileEditor, boolean requestFocus); + FileEditor getFileEditor(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewExtension.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewExtension.java new file mode 100644 index 00000000000..f6f5e881a21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewExtension.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView; + +import com.intellij.psi.PsiElement; + +public interface StructureViewExtension { + StructureViewTreeElement[] getChildren(PsiElement parent); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewFactory.java new file mode 100644 index 00000000000..218771424cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/StructureViewFactory.java @@ -0,0 +1,23 @@ +package com.intellij.ide.structureView; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +import java.util.List; + +/** + * @author Eugene Belyaev + */ +public abstract class StructureViewFactory { + public static StructureViewFactory getInstance(Project project) { + return project.getComponent(StructureViewFactory.class); + } + + public abstract StructureView getStructureView(); + + public abstract void registerExtension(Class type, StructureViewExtension extension); + public abstract void unregisterExtension(Class type, StructureViewExtension extension); + + public abstract List getAllExtensions(Class type); + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java new file mode 100644 index 00000000000..ef6eb6aebc6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java @@ -0,0 +1,148 @@ +package com.intellij.ide.structureView.impl; + +import com.intellij.openapi.util.Condition; +import com.intellij.psi.*; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.PsiUtil; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * @deprecated use conflict-filter processor with dublicates resolver {@link com.intellij.psi.scope.processor.ConflictFilterProcessor} + */ +public class AddAllMembersProcessor extends BaseScopeProcessor { + private ArrayList myAllMembers; + private PsiClass myPsiClass; + private Map myMethodsBySignature = new com.intellij.util.containers.HashMap(); + private MemberFilter myFilter; + + public AddAllMembersProcessor(ArrayList allMembers, PsiClass psiClass) { + this(allMembers, psiClass, ALL_ACCESSIBLE); + } + + public AddAllMembersProcessor(ArrayList allMembers, PsiClass psiClass, MemberFilter filter) { + for (Iterator iterator = allMembers.iterator(); iterator.hasNext();) { + PsiElement psiElement = (PsiElement) iterator.next(); + if (psiElement instanceof PsiMethod) + mapMethodBySignature((PsiMethod) psiElement); + } + myAllMembers = allMembers; + myPsiClass = psiClass; + myFilter = filter; + } + + public void handleEvent(PsiScopeProcessor.Event event, Object associated) { + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + PsiMember member = (PsiMember)element; + if (!isInteresting(element)) + return true; + if (myPsiClass.isInterface() && isObjectMember(element)) + return true; + if (!myAllMembers.contains(member) && myFilter.isVisible(member, myPsiClass)) { + if (member instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)member; + if (shouldAdd(psiMethod)) { + mapMethodBySignature(psiMethod); + myAllMembers.add(psiMethod); + } + } else myAllMembers.add(member); + } + return true; + } + + private boolean isObjectMember(PsiElement element) { + if (!(element instanceof PsiMethod)) + return false; + return ((PsiMethod) element).getContainingClass().getQualifiedName().equals(Object.class.getName()); + } + + private void mapMethodBySignature(PsiMethod psiMethod) { + myMethodsBySignature.put(psiMethod.getSignature(PsiSubstitutor.EMPTY), psiMethod); + } + + private boolean shouldAdd(PsiMethod psiMethod) { + MethodSignature signature = psiMethod.getSignature(PsiSubstitutor.EMPTY); + PsiMethod previousMethod = (PsiMethod) myMethodsBySignature.get(signature); + if (previousMethod == null) + return true; + if (isInheritor(psiMethod, previousMethod)) { + myAllMembers.remove(previousMethod); + return true; + } + return false; + } + + private boolean isInteresting(PsiElement element) { + return element instanceof PsiMethod || + element instanceof PsiField || + element instanceof PsiClass; + } + + public static boolean isInheritor(PsiMethod method, PsiMethod baseMethod) { + if (isStatic(method) || isStatic(baseMethod)) + return false; + return method.getContainingClass().isInheritor(baseMethod.getContainingClass(), true); + } + + public static boolean isStatic(PsiMethod method) { + return method.hasModifierProperty(PsiModifier.STATIC); + } + + public static abstract class MemberFilter { + public boolean isVisible(PsiMember element, PsiClass psiClass) { + if (isInheritedConstructor(element, psiClass)) + return false; + if (!PsiUtil.isAccessible(element, psiClass, null)) + return false; + + return isVisible(element); + } + + public Condition visibleInClass(final PsiClass psiClass) { + return new Condition() { + public boolean value(PsiMember psiElement) { + return isVisible(psiElement, psiClass); + } + }; + } + + private boolean isInheritedConstructor(PsiMember member, PsiClass psiClass) { + if (!(member instanceof PsiMethod)) + return false; + PsiMethod method = (PsiMethod)member; + return method.isConstructor() && method.getContainingClass() != psiClass; + } + + public ArrayList copyVisible(List list) { + ArrayList result = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + PsiElement psiElement = iterator.next(); + if (psiElement instanceof PsiModifierListOwner && !isVisible((PsiModifierListOwner) psiElement)) + continue; + result.add(psiElement); + } + return result; + } + + protected abstract boolean isVisible(PsiModifierListOwner member); + } + + public static final MemberFilter ALL_ACCESSIBLE = new MemberFilter() { + protected boolean isVisible(PsiModifierListOwner member) { + return true; + } + }; + + public static final MemberFilter PUBLIC_ONLY = new MemberFilter() { + protected boolean isVisible(PsiModifierListOwner member) { + return member.hasModifierProperty(PsiModifier.PUBLIC); + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureNodeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureNodeRenderer.java new file mode 100644 index 00000000000..45462dd423c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureNodeRenderer.java @@ -0,0 +1,139 @@ +package com.intellij.ide.structureView.impl; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.roots.ui.util.CellAppearance; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.roots.ui.util.CompositeAppearance; +import com.intellij.openapi.roots.ui.util.ModifiableCellAppearance; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; + +public class StructureNodeRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus + ) { + forNodeDescriptorInTree(value, expanded).customize(this); + } + + public static CellAppearance forNodeDescriptorInTree(Object node, boolean expanded) { + NodeDescriptor descriptor = getNodeDescriptor(node); + if (descriptor == null) return CellAppearanceUtils.EMPTY; + String name = descriptor.toString(); + Object psiElement = descriptor.getElement(); + ModifiableCellAppearance result; + if (psiElement instanceof PsiElement && !((PsiElement)psiElement).isValid()) { + result = CompositeAppearance.single(name); + } else { + PsiClass psiClass = getContainingClass(psiElement); + if (isInheritedMember(node, psiClass) && psiClass != null) { + CompositeAppearance.DequeEnd ending = new CompositeAppearance().getEnding(); + ending.addText(name, applyDeprecation(psiElement, SimpleTextAttributes.DARK_TEXT)); + ending.addComment(psiClass.getName(), applyDeprecation(psiClass, SimpleTextAttributes.GRAY_ATTRIBUTES)); + result = ending.getAppearance(); + } + else { + SimpleTextAttributes textAttributes = applyDeprecation(psiElement, SimpleTextAttributes.REGULAR_ATTRIBUTES); + result = CompositeAppearance.single(name, textAttributes); + } + } + + Icon icon = expanded ? descriptor.getOpenIcon() : descriptor.getClosedIcon(); + result.setIcon(icon); + return result; + } + + public static CellAppearance forElementInClass(PsiMember psiMember, PsiClass psiClass) { + boolean isOwnMethod = psiMember.getContainingClass().getQualifiedName().equals(psiClass.getQualifiedName()); + String name = getNameOf(psiMember); + psiMember.getIcon(Iconable.ICON_FLAG_VISIBILITY); + if (isOwnMethod) { + return CompositeAppearance.single(name, applyDeprecation(psiMember, SimpleTextAttributes.REGULAR_ATTRIBUTES)); + } else { + CompositeAppearance.DequeEnd ending = new CompositeAppearance().getEnding(); + ending.addText(name, applyDeprecation(psiMember, SimpleTextAttributes.DARK_TEXT)); + ending.addComment(psiClass.getName(), applyDeprecation(psiClass, SimpleTextAttributes.GRAY_ATTRIBUTES)); + return ending.getAppearance(); + } + } + + public static String getNameOf(PsiElement psiElement) { + if (psiElement instanceof PsiMethod) + return PsiFormatUtil.formatMethod((PsiMethod)psiElement, + PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + return psiElement.toString(); + } + + + private static boolean isInheritedMember(Object node, PsiClass psiClass) { + PsiClass treeParentClass = getTreeParentClass(node); + return treeParentClass != psiClass; + } + + public static SimpleTextAttributes applyDeprecation(Object value, SimpleTextAttributes nameAttributes) { + return isDeprecated(value) ? makeStrikeout(nameAttributes) : nameAttributes; + } + + private static SimpleTextAttributes makeStrikeout(SimpleTextAttributes nameAttributes) { + return new SimpleTextAttributes(nameAttributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT, nameAttributes.getFgColor()); + } + + public static boolean isDeprecated(Object psiElement) { + if (psiElement instanceof PsiDocCommentOwner) + return ((PsiDocCommentOwner) psiElement).isDeprecated(); + return false; + } + + public static PsiClass getContainingClass(Object element) { + if (element instanceof PsiMember) + return ((PsiMember) element).getContainingClass(); + if (element instanceof PsiClass) { + PsiElement parent = ((PsiClass) element).getParent(); + return (PsiClass) (parent instanceof PsiClass ? parent : null); + } + return null; + } + + public static PsiClass getTreeParentClass(Object value) { + if (!(value instanceof TreeNode)) + return null; + for (TreeNode treeNode = ((TreeNode) value).getParent(); treeNode != null; treeNode = treeNode.getParent()) { + Object element = getElement(treeNode); + if (element instanceof PsiClass) + return (PsiClass) element; + } + return null; + } + + private static NodeDescriptor getNodeDescriptor(Object value) { + if (value instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + return (NodeDescriptor)userObject; + } + } + return null; + } + + private static Object getElement(Object node) { + NodeDescriptor descriptor = getNodeDescriptor(node); + return descriptor == null ? null : descriptor.getElement(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureTreeBuilder.java new file mode 100644 index 00000000000..b1cbe145501 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureTreeBuilder.java @@ -0,0 +1,162 @@ +package com.intellij.ide.structureView.impl; + +import com.intellij.ide.impl.StructureViewWrapper; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +final class StructureTreeBuilder extends AbstractTreeBuilder { + private final Project myProject; + private final PsiFile myFile; + +// private boolean myGroupOverridingMethods; +// private boolean myGroupImplementingMethods; + + private final MyCopyPasteListener myCopyPasteListener; + private final PsiTreeChangeListener myPsiTreeChangeListener; + private final StructureViewWrapper myWrapper; + + public StructureTreeBuilder(Project project, + JTree tree, + DefaultTreeModel treeModel, + PsiFile file, + AbstractTreeStructure treeStructure, + StructureViewWrapper wrapper) { + super( + tree, + treeModel, + treeStructure, null + ); + + myProject = project; + myFile = file; + myWrapper = wrapper; + + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); + + myCopyPasteListener = new MyCopyPasteListener(); + CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener); + + initRootNode(); + } + + public void dispose() { + PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener); + CopyPasteManager.getInstance().removeContentChangedListener(myCopyPasteListener); + super.dispose(); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return false; + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + return true; + } + + protected boolean isSmartExpand() { + return false; + } + + protected final AbstractTreeUpdater createUpdater(){ + return new AbstractTreeUpdater(this){ + protected void updateSubtree(DefaultMutableTreeNode node){ + if (!myFile.isValid()) { + myWrapper.rebuild(); + return; + } + Module module = ModuleUtil.findModuleForPsiElement(myFile); + if (module != null && module.isDisposed()) return; + + super.updateSubtree(node); + } + }; + } + + + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void childRemoved(PsiTreeChangeEvent event) { + PsiElement child = event.getOldChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getFile(), event.getParent()); + } + + public void childAdded(PsiTreeChangeEvent event) { + PsiElement child = event.getNewChild(); + if (child instanceof PsiWhiteSpace) return; //optimization + childrenChanged(event.getFile(), event.getParent()); + } + + public void childReplaced(PsiTreeChangeEvent event) { + PsiElement oldChild = event.getOldChild(); + PsiElement newChild = event.getNewChild(); + if (oldChild instanceof PsiWhiteSpace && newChild instanceof PsiWhiteSpace) return; //optimization + if (oldChild instanceof PsiCodeBlock && newChild instanceof PsiCodeBlock) return; //optimization + childrenChanged(event.getFile(), event.getParent()); + } + + public void childMoved(PsiTreeChangeEvent event) { + childrenChanged(event.getFile(), event.getOldParent()); + childrenChanged(event.getFile(), event.getNewParent()); + } + + public void childrenChanged(PsiTreeChangeEvent event) { + childrenChanged(event.getFile(), event.getParent()); + } + + private void childrenChanged(PsiFile file, PsiElement parent) { + if (!myFile.isValid()) { + myUpdater.cancelAllRequests(); + return; + } + + if (!myFile.equals(file)){ + myUpdater.addSubtreeToUpdate(myRootNode); + return; + } + + // See SCR 8388 + myUpdater.addSubtreeToUpdate(myRootNode); + return; + + } + + public void propertyChanged(PsiTreeChangeEvent event) { + String propertyName = event.getPropertyName(); + PsiElement element = event.getElement(); + if (propertyName.equals(PsiTreeChangeEvent.PROP_WRITABLE)){ + if (element.equals(myFile)){ + myUpdater.addSubtreeToUpdate(myRootNode); + } + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_NAME)){ + if (element.equals(myFile)){ + myUpdater.addSubtreeToUpdate(myRootNode); + } + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_TYPES)){ + myUpdater.addSubtreeToUpdate(myRootNode); + } + else{ + myUpdater.addSubtreeToUpdate(myRootNode); + } + } + } + + private final class MyCopyPasteListener implements CopyPasteManager.ContentChangedListener { + public void contentChanged() { + myUpdater.addSubtreeToUpdate(myRootNode); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java new file mode 100644 index 00000000000..a7666734df5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewFactoryImpl.java @@ -0,0 +1,98 @@ +package com.intellij.ide.structureView.impl; + +import com.intellij.ide.SelectInManager; +import com.intellij.ide.impl.StructureViewSelectInTarget; +import com.intellij.ide.impl.StructureViewWrapper; +import com.intellij.ide.structureView.StructureView; +import com.intellij.ide.structureView.StructureViewExtension; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.*; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Eugene Belyaev + */ +public final class StructureViewFactoryImpl extends StructureViewFactory implements JDOMExternalizable, ProjectComponent { + public boolean AUTOSCROLL_MODE = true; + public boolean AUTOSCROLL_FROM_SOURCE = false; + + private Project myProject; + private StructureViewWrapper myStructureViewWrapper; + + private final MultiValuesMap, StructureViewExtension> myExtensions = new MultiValuesMap, StructureViewExtension>(); + + public StructureViewFactoryImpl(Project project) { + myProject = project; + } + + public StructureView getStructureView() { + return myStructureViewWrapper; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectOpened() { + myStructureViewWrapper = new StructureViewWrapper(myProject); + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run(){ + ToolWindowManager toolWindowManager=ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow=toolWindowManager.registerToolWindow(ToolWindowId.STRUCTURE_VIEW,myStructureViewWrapper.getComponent(),ToolWindowAnchor.LEFT); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowStructure.png")); + SelectInManager.getInstance(myProject).addTarget(new StructureViewSelectInTarget(myProject)); + } + }); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.STRUCTURE_VIEW); + myStructureViewWrapper.dispose(); + myStructureViewWrapper=null; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public String getComponentName() { + return "StructureViewFactory"; + } + + + public void registerExtension(Class type, StructureViewExtension extension) { + myExtensions.put(type, extension); + } + + public void unregisterExtension(Class type, StructureViewExtension extension) { + myExtensions.remove(type, extension); + } + + public List getAllExtensions(Class type) { + ArrayList result = new ArrayList(); + + for (Iterator> iterator = myExtensions.keySet().iterator(); iterator.hasNext();) { + Class registeregType = iterator.next(); + if (registeregType.isAssignableFrom(type)) result.addAll(myExtensions.get(registeregType)); + } + return result; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewState.java new file mode 100644 index 00000000000..a23fd63dc5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/StructureViewState.java @@ -0,0 +1,30 @@ +package com.intellij.ide.structureView.impl; + + + +/** + * @author Yura Cangea + */ +public final class StructureViewState { + private Object[] myExpandedElements; + private Object[] mySelectedElements; + + public StructureViewState() { + } + + public Object[] getExpandedElements() { + return myExpandedElements; + } + + public void setExpandedElements(Object[] expandedElements) { + myExpandedElements = expandedElements; + } + + public Object[] getSelectedElements() { + return mySelectedElements; + } + + public void setSelectedElements(Object[] selectedElements) { + mySelectedElements = selectedElements; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/VisibilityComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/VisibilityComparator.java new file mode 100644 index 00000000000..7fe966feb87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/VisibilityComparator.java @@ -0,0 +1,41 @@ +package com.intellij.ide.structureView.impl; + +import com.intellij.ide.structureView.impl.java.AccessLevelProvider; +import com.intellij.ide.util.treeView.AlphaComparator; +import com.intellij.ide.util.treeView.SourceComparator; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.Comparator; + +public class VisibilityComparator implements Comparator { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.structureView.impl.VisibilityComparator"); + private static final int GROUP_ACCESS_SUBLEVEL = 1; + public static Comparator THEN_SOURCE = new VisibilityComparator(SourceComparator.INSTANCE); + public static Comparator THEN_ALPHA = new VisibilityComparator(AlphaComparator.INSTANCE); + + private Comparator myNextComparator; + public static final int UNKNOWN_ACCESS_LEVEL = -1; + + public VisibilityComparator(Comparator comparator) { + myNextComparator = comparator; + } + + public int compare(Object descriptor1, Object descriptor2) { + int accessLevel1 = getAccessLevel(descriptor1); + int accessLevel2 = getAccessLevel(descriptor2); + if (accessLevel1 == accessLevel2) { + return myNextComparator.compare(descriptor1, descriptor2); + } + return accessLevel2 - accessLevel1; + } + + private int getAccessLevel(Object element) { + if (element instanceof AccessLevelProvider) { + return ((AccessLevelProvider)element).getAccessLevel() * (GROUP_ACCESS_SUBLEVEL + 1) + ((AccessLevelProvider)element).getSubLevel(); + } + else { + LOG.assertTrue(false, element.getClass().getName()); + return UNKNOWN_ACCESS_LEVEL; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java new file mode 100644 index 00000000000..630067988b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.common; + +import com.intellij.ide.structureView.StructureViewExtension; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiElement; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +public abstract class PsiTreeElementBase implements StructureViewTreeElement, ItemPresentation { + public ItemPresentation getPresentation() { + return this; + } + + public abstract PsiElement getElement(); + + public Icon getIcon(boolean open) { + return getElement().getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS); + } + + public Object getValue() { + return getElement(); + } + + public String getLocationString() { + return null; + } + + public String toString() { + return getElement().toString(); + } + + public final StructureViewTreeElement[] getChildren() { + List result = new ArrayList(); + StructureViewTreeElement[] baseChildren = getChildrenBase(); + result.addAll(Arrays.asList(baseChildren)); + StructureViewFactory structureViewFactory = StructureViewFactory.getInstance(getElement().getProject()); + List allExtensions = structureViewFactory.getAllExtensions(getElement().getClass()); + for (Iterator iterator = allExtensions.iterator(); iterator.hasNext();) { + StructureViewExtension extension = iterator.next(); + StructureViewTreeElement[] children = extension.getChildren(getElement()); + if (children != null){ + result.addAll(Arrays.asList(children)); + } + } + return result.toArray(new StructureViewTreeElement[result.size()]); + } + + public abstract StructureViewTreeElement[] getChildrenBase(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/AccessLevelProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/AccessLevelProvider.java new file mode 100644 index 00000000000..f7faed5b8c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/AccessLevelProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.java; + +public interface AccessLevelProvider { + int getAccessLevel(); + int getSubLevel(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/FieldsFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/FieldsFilter.java new file mode 100644 index 00000000000..d475fc0076d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/FieldsFilter.java @@ -0,0 +1,23 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.ActionPresentation; +import com.intellij.ide.util.treeView.smartTree.ActionPresentationData; +import com.intellij.ide.util.treeView.smartTree.Filter; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.openapi.util.IconLoader; + +public class FieldsFilter implements Filter{ + public static final String ID = "SHOW_FIELDS"; + + public boolean isVisible(TreeElement treeNode) { + return !(treeNode instanceof PsiFieldTreeElement); + } + + public ActionPresentation getPresentation() { + return new ActionPresentationData("Show Fields", null, IconLoader.getIcon("/nodes/field.png")); + } + + public String getName() { + return ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/InheritedMembersFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/InheritedMembersFilter.java new file mode 100644 index 00000000000..f1d0e7098c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/InheritedMembersFilter.java @@ -0,0 +1,30 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.ActionPresentation; +import com.intellij.ide.util.treeView.smartTree.ActionPresentationData; +import com.intellij.ide.util.treeView.smartTree.Filter; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.openapi.util.IconLoader; + +public class InheritedMembersFilter implements Filter { + public static final String ID = "SHOW_INHERITED"; + + public InheritedMembersFilter() { + } + public boolean isVisible(TreeElement treeNode) { + if (treeNode instanceof JavaClassTreeElementBase) { + return !((JavaClassTreeElementBase)treeNode).isInherited(); + } + else { + return true; + } + } + + public ActionPresentation getPresentation() { + return new ActionPresentationData("Show Inherited", null, IconLoader.getIcon("/hierarchy/supertypes.png")); + } + + public String getName() { + return ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java new file mode 100644 index 00000000000..33711928a9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java @@ -0,0 +1,72 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.impl.AddAllMembersProcessor; +import com.intellij.psi.*; +import com.intellij.psi.scope.util.PsiScopesUtil; + +import java.util.*; + +public class JavaClassTreeElement extends JavaClassTreeElementBase { + private final PsiClass myClass; + + public JavaClassTreeElement(PsiClass aClass, boolean inherited) { + super(inherited); + myClass = aClass; + } + + public StructureViewTreeElement[] getChildrenBase() { + Collection classChildren = getClassChildren(); + return classChildren.toArray(new StructureViewTreeElement[classChildren.size()]); + } + + public Collection getClassChildren() { + ArrayList array = new ArrayList(); + + List ownChildren = Arrays.asList(myClass.getChildren()); + ArrayList inherited = new ArrayList(ownChildren); + PsiScopesUtil.processScope(myClass, new AddAllMembersProcessor(inherited, myClass, new AddAllMembersProcessor.MemberFilter() { + protected boolean isVisible(PsiModifierListOwner member) { + return true; + } + }), PsiSubstitutor.UNKNOWN, null, myClass); + + for (Iterator iterator = inherited.iterator(); iterator.hasNext();) { + PsiElement child = (PsiElement)iterator.next(); + if (child instanceof PsiClass || child instanceof PsiMethod || child instanceof PsiField) { + if (child instanceof PsiClass) { + array.add(new JavaClassTreeElement((PsiClass)child, !ownChildren.contains(child))); + } + else { + addMemeber(child, array, !ownChildren.contains(child)); + } + } + } + return array; + } + + private void addMemeber(PsiElement child, ArrayList array, boolean inherited) { + if (child instanceof PsiField) { + array.add(new PsiFieldTreeElement((PsiField)child, inherited)); + } + else { + array.add(new PsiMethodTreeElement((PsiMethod)child, inherited)); + } + } + + public String getPresentableText() { + return myClass.getName(); + } + + public PsiElement getElement() { + return myClass; + } + + public boolean isPublic() { + if (myClass.getParent() instanceof PsiFile){ + return true; + } else { + return super.isPublic(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java new file mode 100644 index 00000000000..7f4eec48ab8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java @@ -0,0 +1,43 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.ide.structureView.impl.common.PsiTreeElementBase; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiModifierListOwner; +import com.intellij.psi.util.PsiUtil; + +import javax.swing.*; + +public abstract class JavaClassTreeElementBase extends PsiTreeElementBase implements + AccessLevelProvider { + protected final boolean myIsInherited; + + protected JavaClassTreeElementBase(boolean isInherited) { + myIsInherited = isInherited; + } + + public boolean isInherited() { + return myIsInherited; + } + + public boolean isPublic() { + PsiElement element = getElement(); + if (element instanceof PsiModifierListOwner) { + return ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.PUBLIC); + } + else { + return true; + } + } + + public int getAccessLevel() { + return PsiUtil.getAccessLevel(((PsiModifierListOwner)getElement()).getModifierList()); + } + + public int getSubLevel() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java new file mode 100644 index 00000000000..edd17f201eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java @@ -0,0 +1,52 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaFile; + +import javax.swing.*; +import java.util.ArrayList; + +public class JavaFileTreeElement implements StructureViewTreeElement, ItemPresentation { + + private final PsiJavaFile myFile; + + public JavaFileTreeElement(PsiJavaFile file) { + myFile = file; + } + + public StructureViewTreeElement[] getChildren() { + PsiClass[] classes = myFile.getClasses(); + ArrayList result = new ArrayList(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + result.add(new JavaClassTreeElement(aClass, false)); + } + return result.toArray(new StructureViewTreeElement[result.size()]); + } + + public ItemPresentation getPresentation() { + return this; + } + + public Icon getIcon(boolean open) { + return myFile.getVirtualFile().getFileType().getIcon(); + } + + public String getLocationString() { + return null; + } + + public String getPresentableText() { + return myFile.getName(); + } + + public Object getValue() { + return myFile; + } + + public String toString() { + return getPresentableText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java new file mode 100644 index 00000000000..84fc6db93e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java @@ -0,0 +1,57 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.smartTree.Filter; +import com.intellij.ide.util.treeView.smartTree.Grouper; +import com.intellij.ide.util.treeView.smartTree.Sorter; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; + +public class JavaFileTreeModel implements StructureViewModel { + private final PsiJavaFile myFile; + + public JavaFileTreeModel(PsiJavaFile file) { + myFile = file; + } + + public Filter[] getFilters() { + return new Filter[]{new InheritedMembersFilter(), + new FieldsFilter(), + new PublicElementsFilter()}; + } + + public Grouper[] getGroupers() { + return new Grouper[]{new SuperTypesGrouper(), new PropertiesGrouper()}; + } + + public StructureViewTreeElement getRoot() { + return new JavaFileTreeElement(myFile); + } + + public Sorter[] getSorters() { + return new Sorter[]{KindSorter.INSTANCE, Sorter.ALPHA_SORTER}; + } + + public Object getCurrentEditorElement() { + final Editor editor = FileEditorManager.getInstance(myFile.getProject()).getSelectedTextEditor(); + final Document document = FileDocumentManager.getInstance().getDocument(myFile.getVirtualFile()); + if (!Comparing.equal(editor.getDocument(), document)) return null; + + final int offset = editor.getCaretModel().getOffset(); + PsiElement element = myFile.findElementAt(offset); + while (!isSutable(element)) { + if (element == null) return null; + element = element.getParent(); + } + return element; + } + + private boolean isSutable(final PsiElement element) { + return element instanceof PsiClass || element instanceof PsiMethod || element instanceof PsiField; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/KindSorter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/KindSorter.java new file mode 100644 index 00000000000..5e9b362ebdc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/KindSorter.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.ActionPresentation; +import com.intellij.ide.util.treeView.smartTree.Sorter; + +import java.util.Comparator; + +public class KindSorter implements Sorter { + public static final Sorter INSTANCE = new KindSorter(); + + public static final String ID = "KIND"; + private static final Comparator COMPARATOR = new Comparator() { + public int compare(final Object o1, final Object o2) { + + int weight1 = getWeight(o1); + int weight2 = getWeight(o2); + + return weight1 - weight2; + } + + private int getWeight(final Object value1) { + if (value1 instanceof JavaClassTreeElement) { + return 1; + } + else if (value1 instanceof PsiFieldTreeElement) { + return 2; + } + else if (value1 instanceof PsiMethodTreeElement) { + return 3; + } + else { + return 4; + } + } + }; + + public Comparator getComparator() { + return COMPARATOR; + } + + public ActionPresentation getPresentation() { + return null; + } + + public String getName() { + return ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertiesGrouper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertiesGrouper.java new file mode 100644 index 00000000000..4dde266d074 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertiesGrouper.java @@ -0,0 +1,39 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiElement; + +import java.util.*; + +public class PropertiesGrouper implements Grouper{ + public static final String ID = "SHOW_PROPERTIES"; + + public Collection group(Collection children) { + Map result = new HashMap(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Object o = iterator.next(); + if (o instanceof JavaClassTreeElementBase){ + PsiElement element = ((JavaClassTreeElementBase)o).getElement(); + PropertyGroup group = PropertyGroup.createOn(element); + if (group != null) { + PropertyGroup existing = (PropertyGroup)result.get(group); + if (existing != null){ + existing.copyAccessorsFrom(group); + } else { + result.put(group, group); + } + } + } + } + return result.values(); + } + + public ActionPresentation getPresentation() { + return new ActionPresentationData("Show Properties", null, IconLoader.getIcon("/nodes/property.png")); + } + + public String getName() { + return ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertyGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertyGroup.java new file mode 100644 index 00000000000..0f956d719ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PropertyGroup.java @@ -0,0 +1,170 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.Group; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.*; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.Icons; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; + +import javax.swing.*; + +public class PropertyGroup implements Group, ItemPresentation, AccessLevelProvider { + private final String myPropertyName; + private final PsiType myPropertyType; + + private PsiField myField; + private PsiMethod myGetter; + private PsiMethod mySetter; + public static final Icon PROPERTY_READ_ICON = loadIcon("/nodes/propertyRead.png"); + public static final Icon PROPERTY_READ_STATIC_ICON = loadIcon("/nodes/propertyReadStatic.png"); + public static final Icon PROPERTY_WRITE_ICON = loadIcon("/nodes/propertyWrite.png"); + public static final Icon PROPERTY_WRITE_STATIC_ICON = loadIcon("/nodes/propertyWriteStatic.png"); + public static final Icon PROPERTY_READ_WRITE_ICON = loadIcon("/nodes/propertyReadWrite.png"); + public static final Icon PROPERTY_READ_WRITE_STATIC_ICON = loadIcon("/nodes/propertyReadWriteStatic.png"); + + private PropertyGroup(String propertyName, PsiType propertyType) { + myPropertyName = propertyName; + myPropertyType = propertyType; + } + + public static final PropertyGroup createOn(PsiElement object) { + if (object instanceof PsiField) { + PsiField field = ((PsiField)object); + PropertyGroup group = new PropertyGroup(PropertyUtil.suggestPropertyName(field.getProject(), field), field.getType()); + group.setField(field); + return group; + } + else if (object instanceof PsiMethod) { + PsiMethod method = (PsiMethod)object; + if (PropertyUtil.isSimplePropertyGetter(method)) { + PropertyGroup group = new PropertyGroup(PropertyUtil.getPropertyNameByGetter(method), method.getReturnType()); + group.setGetter(method); + return group; + } + else if (PropertyUtil.isSimplePropertySetter(method)) { + PropertyGroup group = new PropertyGroup(PropertyUtil.getPropertyNameBySetter(method), method.getParameterList().getParameters()[0].getType()); + group.setSetter(method); + return group; + } + } + return null; + } + + public boolean contains(TreeElement object) { + if (object instanceof JavaClassTreeElementBase){ + PropertyGroup objectGroup = createOn(((JavaClassTreeElementBase)object).getElement()); + return equals(objectGroup); + } + return false; + } + + public ItemPresentation getPresentation() { + return this; + } + + public Icon getIcon(boolean open) { + return Icons.PROPERTY_ICON; + } + + public String getLocationString() { + return null; + } + + public String getPresentableText() { + return myPropertyName + ":" + myPropertyType.getPresentableText(); + } + + public String toString() { + return myPropertyName; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PropertyGroup)) return false; + + final PropertyGroup propertyGroup = (PropertyGroup)o; + + if (myPropertyName != null ? !myPropertyName.equals(propertyGroup.myPropertyName) : propertyGroup.myPropertyName != null) return false; + if (myPropertyType != null ? !myPropertyType.equals(propertyGroup.myPropertyType) : propertyGroup.myPropertyType != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myPropertyName != null ? myPropertyName.hashCode() : 0); + result = 29 * result + (myPropertyType != null ? myPropertyType.hashCode() : 0); + return result; + } + + public Object getValue() { + return this; + } + + public String getGetterName() { + return PropertyUtil.suggestGetterName(myPropertyName, myPropertyType); + } + + public int getAccessLevel() { + int result = PsiUtil.ACCESS_LEVEL_PRIVATE; + if (myGetter != null) + result = Math.max(result, PsiUtil.getAccessLevel(myGetter.getModifierList())); + if (mySetter != null) + result = Math.max(result, PsiUtil.getAccessLevel(mySetter.getModifierList())); + if (myField != null) + result = Math.max(result, PsiUtil.getAccessLevel(myField.getModifierList())); + return result; + } + + public int getSubLevel() { + return 0; + } + + public PsiClass getParentClass() { + return null; + } + + public void setField(PsiField field) { + myField = field; + } + + public void setGetter(PsiMethod getter) { + myGetter = getter; + } + + public void setSetter(PsiMethod setter) { + mySetter = setter; + } + + public PsiField getField() { + return myField; + } + + public PsiMethod getGetter() { + return myGetter; + } + + public PsiMethod getSetter() { + return mySetter; + } + + public void copyAccessorsFrom(PropertyGroup group) { + if (group.getGetter() != null) setGetter(group.getGetter()); + if (group.getSetter() != null) setSetter(group.getSetter()); + if (group.getField() != null) setField(group.getField()); + } + + private static Icon loadIcon(String resourceName) { + Icon icon = IconLoader.getIcon(resourceName); + Application application = ApplicationManager.getApplication(); + if (icon == null && (application != null && application.isUnitTestMode())) { + return new ImageIcon(); + } + return icon; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiFieldTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiFieldTreeElement.java new file mode 100644 index 00000000000..21d3d68abdb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiFieldTreeElement.java @@ -0,0 +1,35 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; + +public class PsiFieldTreeElement extends JavaClassTreeElementBase{ + private final PsiField myField; + + public PsiFieldTreeElement(PsiField field, boolean isInherited) { + super(isInherited); + myField = field; + } + + public StructureViewTreeElement[] getChildrenBase() { + return new StructureViewTreeElement[0]; + } + + public ItemPresentation getPresentation() { + return this; + } + + public PsiElement getElement() { + return myField; + } + + public String getPresentableText() { + return myField.getName(); + } + + public PsiField getField() { + return myField; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java new file mode 100644 index 00000000000..b85934e57d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java @@ -0,0 +1,41 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; + +public class PsiMethodTreeElement extends JavaClassTreeElementBase { + private final PsiMethod myMethod; + + public PsiMethodTreeElement(PsiMethod method, boolean isInherited) { + super(isInherited); + myMethod = method; + } + + public StructureViewTreeElement[] getChildrenBase() { + return new StructureViewTreeElement[0]; + } + + public ItemPresentation getPresentation() { + return this; + } + + public PsiElement getElement() { + return myMethod; + } + + public String getPresentableText() { + return PsiFormatUtil.formatMethod( + myMethod, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + } + + public PsiMethod getMethod() { + return myMethod; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PublicElementsFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PublicElementsFilter.java new file mode 100644 index 00000000000..410a349f534 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/PublicElementsFilter.java @@ -0,0 +1,28 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.ActionPresentation; +import com.intellij.ide.util.treeView.smartTree.ActionPresentationData; +import com.intellij.ide.util.treeView.smartTree.Filter; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.openapi.util.IconLoader; + +public class PublicElementsFilter implements Filter{ + public static final String ID = "SHOW_NON_PUBLIC"; + + public boolean isVisible(TreeElement treeNode) { + if (treeNode instanceof JavaClassTreeElementBase) { + return ((JavaClassTreeElementBase)treeNode).isPublic(); + } + else { + return true; + } + } + + public ActionPresentation getPresentation() { + return new ActionPresentationData("Show non-public", null, IconLoader.getIcon("/nodes/c_private.png")); + } + + public String getName() { + return ID; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypeGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypeGroup.java new file mode 100644 index 00000000000..ad88043d800 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypeGroup.java @@ -0,0 +1,93 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.Group; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiUtil; + +import javax.swing.*; +import java.lang.ref.WeakReference; + +public class SuperTypeGroup implements Group, ItemPresentation, AccessLevelProvider{ + private final PsiClass mySuperClass; + private final boolean myOverrides; + + public SuperTypeGroup(PsiClass superClass, boolean overrides) { + myOverrides = overrides; + mySuperClass = superClass; + } + + public boolean contains(TreeElement o) { + if (o instanceof PsiMethodTreeElement) { + PsiMethod method = ((PsiMethodTreeElement)o).getMethod(); + WeakReference ref = method.getUserData(SuperTypesGrouper.SUPER_METHOD_KEY); + if (ref == null) return false; + PsiMethod superMethod = ref.get(); + if (superMethod == null) return false; + PsiClass superClass = superMethod.getContainingClass(); + if (!superClass.equals(mySuperClass)) return false; + boolean overrides = SuperTypesGrouper.methodOverridesSuper(method, superMethod); + if (overrides != myOverrides) return false; + method.putUserData(SuperTypesGrouper.SUPER_METHOD_KEY, null); + return true; + } + else { + return false; + } + + } + + public ItemPresentation getPresentation() { + return this; + } + + public Icon getIcon(boolean open) { + return mySuperClass.getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS); + } + + public String getLocationString() { + return null; + } + + public String getPresentableText() { + return toString(); + } + + public String toString() { + return mySuperClass.getName(); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SuperTypeGroup)) return false; + + final SuperTypeGroup superTypeGroup = (SuperTypeGroup)o; + + if (myOverrides != superTypeGroup.myOverrides) return false; + if (mySuperClass != null ? !mySuperClass.equals(superTypeGroup.mySuperClass) : superTypeGroup.mySuperClass != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (mySuperClass != null ? mySuperClass.hashCode() : 0); + result = 29 * result + (myOverrides ? 1 : 0); + return result; + } + + public Object getValue() { + return this; + } + + public int getAccessLevel() { + return PsiUtil.getAccessLevel(mySuperClass.getModifierList()); + } + + public int getSubLevel() { + return 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypesGrouper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypesGrouper.java new file mode 100644 index 00000000000..b6906cb44a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/java/SuperTypesGrouper.java @@ -0,0 +1,60 @@ +package com.intellij.ide.structureView.impl.java; + +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.util.PsiSuperMethodUtil; + +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +public class SuperTypesGrouper implements Grouper{ + public static final Key SUPER_METHOD_KEY = Key.create("StructureTreeBuilder.SUPER_METHOD_KEY"); + public static final String ID = "SHOW_INTERFACES"; + + public Collection group(Collection children) { + Collection groups = new HashSet(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Object child = iterator.next(); + if (child instanceof PsiMethodTreeElement) { + PsiMethod method = ((PsiMethodTreeElement)child).getMethod(); + PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method); + + if (superMethods.length > 0) { + PsiMethod superMethod = superMethods[0]; + method.putUserData(SUPER_METHOD_KEY, new WeakReference(superMethod)); + PsiClass superClass = superMethod.getContainingClass(); + boolean overrides = methodOverridesSuper(method, superMethod); + groups.add(new SuperTypeGroup(superClass, overrides)); + } + } + } + return groups; + } + + static boolean methodOverridesSuper(PsiMethod method, PsiMethod superMethod) { + boolean overrides = false; + if (method.hasModifierProperty(PsiModifier.ABSTRACT)){ + overrides = true; + } + else if (!superMethod.hasModifierProperty(PsiModifier.ABSTRACT)){ + overrides = true; + } + return overrides; + + } + + public ActionPresentation getPresentation() { + return new ActionPresentationData("Group Methods by Defining Type", null, IconLoader.getIcon("/general/implementingMethod.png")); + } + + public String getName() { + return ID; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlFileTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlFileTreeElement.java new file mode 100644 index 00000000000..05dbdc06bac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlFileTreeElement.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.xml; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.impl.common.PsiTreeElementBase; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; + +public class XmlFileTreeElement extends PsiTreeElementBase { + private final XmlFile myFile; + + public XmlFileTreeElement(XmlFile file) { + myFile = file; + } + + public StructureViewTreeElement[] getChildrenBase() { + XmlDocument document = myFile.getDocument(); + if (document != null) { + return new StructureViewTreeElement[]{new XmlTagTreeElement(document.getRootTag())}; + } + return new StructureViewTreeElement[0]; + } + + public PsiElement getElement() { + return myFile; + } + + public String getPresentableText() { + return myFile.getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlStructureViewTreeModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlStructureViewTreeModel.java new file mode 100644 index 00000000000..a70fe05d595 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlStructureViewTreeModel.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.xml; + +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.psi.xml.XmlFile; + +public class XmlStructureViewTreeModel implements StructureViewModel{ + private final XmlFile myFile; + + public XmlStructureViewTreeModel(XmlFile file) { + myFile = file; + } + + public StructureViewTreeElement getRoot() { + return new XmlFileTreeElement(myFile); + } + + public Grouper[] getGroupers() { + return new Grouper[0]; + } + + public Sorter[] getSorters() { + return new Sorter[0]; + } + + public Filter[] getFilters() { + return new Filter[0]; + } + + public Object getCurrentEditorElement() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlTagTreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlTagTreeElement.java new file mode 100644 index 00000000000..fedd26f790f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/impl/xml/XmlTagTreeElement.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.structureView.impl.xml; + +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.impl.common.PsiTreeElementBase; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; + +public class XmlTagTreeElement extends PsiTreeElementBase{ + private final XmlTag myTag; + + public XmlTagTreeElement(XmlTag tag) { + myTag = tag; + } + + public StructureViewTreeElement[] getChildrenBase() { + XmlTag[] subTags = myTag.getSubTags(); + StructureViewTreeElement[] result = new StructureViewTreeElement[subTags.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new XmlTagTreeElement(subTags[i]); + } + return result; + } + + public PsiElement getElement() { + return myTag; + } + + public String getPresentableText() { + return myTag.getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java new file mode 100644 index 00000000000..6b146b85a21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -0,0 +1,588 @@ +package com.intellij.ide.structureView.newStructureView; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.DataManager; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.impl.StructureViewFactoryImpl; +import com.intellij.ide.structureView.impl.StructureViewState; +import com.intellij.ide.structureView.impl.java.KindSorter; +import com.intellij.ide.util.treeView.*; +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.ui.*; +import com.intellij.util.Alarm; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +public class StructureViewComponent extends JPanel implements TreeActionsOwner, DataProvider { + private static Logger LOG = Logger.getInstance("#com.intellij.ide.structureView.newStructureView.StructureViewComponent"); + + private AbstractTreeBuilder myAbstractTreeBuilder; + private final Collection myActiveActions = new HashSet(); + private FileEditor myFileEditor; + private final TreeModelWrapper myTreeModelWrapper; + + + private StructureViewState myStructureViewState; + private boolean myAutoscrollFeedback; + + private final Alarm myAutoscrollAlarm = new Alarm(); + + private final CopyPasteManagerEx.CopyPasteDelegator myCopyPasteDelegator; + private final MyAutoScrollToSourceHandler myAutoScrollToSourceHandler; + private final AutoScrollFromSourceHandler myAutoScrollFromSourceHandler; + + private static final Key STRUCTURE_VIEW_STATE_KEY = Key.create("STRUCTURE_VIEW_STATE"); + private final Project myProject; + private final StructureViewModel myTreeModel; + + + public StructureViewComponent(FileEditor editor, StructureViewModel structureViewModel, Project project) { + super(new BorderLayout()); + myProject = project; + myFileEditor = editor; + myTreeModel = structureViewModel; + myTreeModelWrapper = new TreeModelWrapper(myTreeModel, this); + SmartTreeStructure treeStructure = new SmartTreeStructure(project, myTreeModelWrapper); + JTree tree = new JTree(new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement()))); + myAbstractTreeBuilder = new AbstractTreeBuilder(tree, + (DefaultTreeModel)tree.getModel(), + treeStructure, null) { + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return ((AbstractTreeNode)nodeDescriptor).isAlwaysShowPlus(); + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + return ((AbstractTreeNode)nodeDescriptor).isAlwaysExpand(); + } + }; + myAbstractTreeBuilder.updateFromRoot(); + add(new JScrollPane(myAbstractTreeBuilder.getTree()), BorderLayout.CENTER); + + myAbstractTreeBuilder.getTree().setCellRenderer(new NodeRenderer()); + + myAutoScrollToSourceHandler = new MyAutoScrollToSourceHandler(myProject); + myAutoScrollFromSourceHandler = new MyAutoScrollFromSourceHandler(myProject); + + JComponent toolbarComponent = + ActionManager.getInstance().createActionToolbar(ActionPlaces.STRUCTURE_VIEW_TOOLBAR, + createActionGroup(), + true) + .getComponent(); + add(toolbarComponent, BorderLayout.NORTH); + + installTree(); + + myCopyPasteDelegator = new CopyPasteManagerEx.CopyPasteDelegator(myProject, getTree()) { + protected PsiElement[] getSelectedElements() { + return StructureViewComponent.this.getSelectedPsiElements(); + } + }; + + } + + private void installTree() { + getTree().getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + myAutoScrollToSourceHandler.install(getTree()); + myAutoScrollFromSourceHandler.install(); + + TreeToolTipHandler.install(getTree()); + TreeUtil.installActions(getTree()); + new TreeSpeedSearch(getTree()); + + addTreeKeyListener(); + addTreeMouseListeners(); + + restoreStructureViewState(); + + } + + private PsiElement[] getSelectedPsiElements() { + return filterPsiElements(getSelectedElements()); + + } + + private PsiElement[] filterPsiElements(Object[] selectedElements) { + ArrayList psiElements = new ArrayList(); + + if (selectedElements == null) return null; + for (int i = 0; i < selectedElements.length; i++) { + Object selectedElement = selectedElements[i]; + if (selectedElement instanceof PsiElement) psiElements.add((PsiElement)selectedElement); + } + return psiElements.toArray(new PsiElement[psiElements.size()]); + } + + private Object[] getSelectedElements() { + return convertPathsToValues(getTree().getSelectionPaths()); + } + + private Object[] convertPathsToValues(TreePath[] selectionPaths) { + if (selectionPaths != null) { + Object[] result = new Object[selectionPaths.length]; + + for (int i = 0; i < selectionPaths.length; i++) { + TreePath selectionPath = selectionPaths[i]; + Object value = ((AbstractTreeNode)((DefaultMutableTreeNode)selectionPath.getLastPathComponent()).getUserObject()).getValue(); + if (value instanceof TreeElement) { + value = ((StructureViewTreeElement)value).getValue(); + } + result[i] = value; + } + return result; + } + else { + return null; + } + } + + private void addTreeMouseListeners() { + EditSourceOnDoubleClickHandler.install(getTree()); + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_STRUCTURE_VIEW_POPUP); + PopupHandler.installPopupHandler(getTree(), group, ActionPlaces.STRUCTURE_VIEW_POPUP, ActionManager.getInstance()); + } + + private void addTreeKeyListener() { + getTree().addKeyListener( + new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (KeyEvent.VK_ENTER == e.getKeyCode()) { + DataContext dataContext = DataManager.getInstance().getDataContext(getTree()); + Navigatable navigatable = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(false); + } + } + else if (KeyEvent.VK_ESCAPE == e.getKeyCode()) { + if (e.isConsumed()) return; + CopyPasteManagerEx copyPasteManager = (CopyPasteManagerEx)CopyPasteManager.getInstance(); + boolean[] isCopied = new boolean[1]; + if (copyPasteManager.getElements(isCopied) != null && !isCopied[0]) { + copyPasteManager.clear(); + e.consume(); + } + } + } + }); + } + + public void saveStructureViewState() { + myStructureViewState = new StructureViewState(); + myStructureViewState.setExpandedElements(getExpandedPsiElements()); + myStructureViewState.setSelectedElements(getSelectedPsiElements()); + myFileEditor.putUserData(STRUCTURE_VIEW_STATE_KEY, myStructureViewState); + } + + private Object[] getExpandedPsiElements() { + ArrayList paths = new ArrayList(); + TreeUtil.collectExpandedPaths(getTree(), paths); + return filterPsiElements(convertPathsToValues(paths.toArray(new TreePath[paths.size()]))); + } + + + public void restoreStructureViewState() { + myStructureViewState = myFileEditor.getUserData(STRUCTURE_VIEW_STATE_KEY); + if (myStructureViewState != null) { + expandStoredElements(); + selectStoredElenents(); + myFileEditor.putUserData(STRUCTURE_VIEW_STATE_KEY, null); + myStructureViewState = null; + } + else { + TreeUtil.expand(getTree(), 3); + } + } + + private void selectStoredElenents() { + Object[] selectedPsiElements = null; + + if (myStructureViewState != null) { + selectedPsiElements = myStructureViewState.getSelectedElements(); + } + + if (selectedPsiElements == null) { + getTree().setSelectionPath(new TreePath(getRootNode().getPath())); + } + else { + for (int i = 0; i < selectedPsiElements.length; i++) { + Object element = selectedPsiElements[i]; + if (element instanceof PsiElement && !((PsiElement)element).isValid()) continue; + DefaultMutableTreeNode node = myAbstractTreeBuilder.getNodeForElement(element); + if (node != null) { + getTree().addSelectionPath(new TreePath(node.getPath())); + } + } + } + } + + private DefaultMutableTreeNode getRootNode() { + return (DefaultMutableTreeNode)getTree().getModel().getRoot(); + } + + private void expandStoredElements() { + Object[] expandedPsiElements = null; + + if (myStructureViewState != null) { + expandedPsiElements = myStructureViewState.getExpandedElements(); + } + + if (expandedPsiElements == null) { + getTree().expandPath(new TreePath(getRootNode().getPath())); + } + else { + for (int i = 0; i < expandedPsiElements.length; i++) { + Object element = expandedPsiElements[i]; + if (element instanceof PsiElement && !((PsiElement)element).isValid()) continue; + expandPathToElement(element); + } + } + } + + private ActionGroup createActionGroup() { + DefaultActionGroup result = new DefaultActionGroup(); + Sorter[] sorters = myTreeModel.getSorters(); + for (int i = 0; i < sorters.length; i++) { + final Sorter sorter = sorters[i]; + if (shouldBeShown(sorter)) { + result.add(new TreeActionWrapper(sorter, this)); + } + } + if (sorters.length > 0) result.addSeparator(); + + Grouper[] groupers = myTreeModel.getGroupers(); + for (int i = 0; i < groupers.length; i++) { + result.add(new TreeActionWrapper(groupers[i], this)); + } + Filter[] filters = myTreeModel.getFilters(); + for (int i = 0; i < filters.length; i++) { + result.add(new TreeActionWrapper(filters[i], this)); + } + + result.addSeparator(); + + result.add(myAutoScrollToSourceHandler.createToggleAction()); + result.add(myAutoScrollFromSourceHandler.createToggleAction()); + + + return result; + } + + private boolean shouldBeShown(final Sorter sorter) { + return !sorter.getName().equals(KindSorter.ID); + } + + public FileEditor getFileEditor() { + return null; + } + + private DefaultMutableTreeNode expandPathToElement(Object element) { + ArrayList pathToElement = getPathToElement(element); + + if (pathToElement.isEmpty()) return null; + + JTree tree = myAbstractTreeBuilder.getTree(); + DefaultMutableTreeNode currentTreeNode = ((DefaultMutableTreeNode)tree.getModel().getRoot()); + pathToElement.remove(0); + while (!pathToElement.isEmpty() && currentTreeNode != null) { + AbstractTreeNode topPathElement = pathToElement.get(0); + pathToElement.remove(0); + TreePath treePath = new TreePath(currentTreeNode.getPath()); + if (!tree.isExpanded(treePath)) tree.expandPath(treePath); + currentTreeNode = findInChildren(currentTreeNode, topPathElement); + } + return currentTreeNode; + } + + public boolean select(Object element, boolean requestFocus) { + DefaultMutableTreeNode currentTreeNode = expandPathToElement(element); + + if (currentTreeNode != null) { + TreeUtil.selectInTree(currentTreeNode, requestFocus, getTree()); + myAutoScrollToSourceHandler.setShouldAutoScroll(false); + TreePath path = new TreePath(currentTreeNode.getPath()); + TreeUtil.showRowCentered(getTree(), getTree().getRowForPath(path), false); + myAutoScrollToSourceHandler.setShouldAutoScroll(true); + centerSelectedRow(); + } + return true; + } + + private ArrayList getPathToElement(Object element) { + ArrayList result = new ArrayList(); + addToPath((AbstractTreeNode)myAbstractTreeBuilder.getTreeStructure().getRootElement(), element, result, new HashSet()); + return result; + } + + private boolean addToPath(AbstractTreeNode rootElement, Object element, ArrayList result, Collection processedElements) { + + final Object rootValue = rootElement.getValue(); + if (rootValue instanceof TreeElement) { + Object value = ((StructureViewTreeElement) rootValue).getValue(); + if (processedElements.contains(value)){ + return false; + } + else { + processedElements.add(value); + } + + if (Comparing.equal(value, element)){ + result.add(0, rootElement); + return true; + } + } + + Collection children = rootElement.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + AbstractTreeNode child = iterator.next(); + if (addToPath(child, element, result, new HashSet())) { + result.add(0, rootElement); + return true; + } + } + + return false; + } + + private DefaultMutableTreeNode findInChildren(DefaultMutableTreeNode currentTreeNode, AbstractTreeNode topPathElement) { + for (int i = 0; i < currentTreeNode.getChildCount(); i++) { + TreeNode child = currentTreeNode.getChildAt(i); + if (((DefaultMutableTreeNode)child).getUserObject().equals(topPathElement)) return (DefaultMutableTreeNode)child; + } + return null; + } + + public void scrollToElementAtCaret(final FileEditor editor) { + if (myAutoscrollFeedback) { + myAutoscrollFeedback = false; + return; + } + + if (myFileEditor == null || !Comparing.equal(myFileEditor, editor)) return; + + StructureViewFactoryImpl structureViewFactory + = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject); + + if (!structureViewFactory.AUTOSCROLL_FROM_SOURCE) return; + + myAutoscrollAlarm.cancelAllRequests(); + myAutoscrollAlarm.addRequest( + new Runnable() { + public void run() { + if (myAbstractTreeBuilder == null) return; + selectViewableElement(); + } + }, 1000 + ); + } + + private void selectViewableElement() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + final Object currentEditorElement = myTreeModel.getCurrentEditorElement(); + if (currentEditorElement != null) { + select(currentEditorElement, false); + } + } + + + public JComponent getComponent() { + return this; + } + + public void dispose() { + LOG.assertTrue(EventQueue.isDispatchThread(), Thread.currentThread().getName()); + + saveStructureViewState(); + + if (myAbstractTreeBuilder != null) { + myAbstractTreeBuilder.dispose(); + myAbstractTreeBuilder = null; + } + + myFileEditor = null; + myAutoScrollFromSourceHandler.dispose(); + + } + + public void centerSelectedRow() { + TreePath path = getTree().getSelectionPath(); + if (path == null) return; + myAutoScrollToSourceHandler.setShouldAutoScroll(false); + TreeUtil.showRowCentered(getTree(), getTree().getRowForPath(path), false); + myAutoScrollToSourceHandler.setShouldAutoScroll(true); + } + + public void setActionActive(String name, boolean state) { + saveStructureViewState(); + if (state) { + myActiveActions.add(name); + } + else { + myActiveActions.remove(name); + } + ((SmartTreeStructure)myAbstractTreeBuilder.getTreeStructure()).rebuildTree(); + myAbstractTreeBuilder.updateFromRoot(); + restoreStructureViewState(); + } + + public boolean isActionActive(String name) { + return myActiveActions.contains(name); + } + + public AbstractTreeStructure getTreeStructure() { + return myAbstractTreeBuilder.getTreeStructure(); + } + + public JTree getTree() { + return myAbstractTreeBuilder.getTree(); + } + + private final class MyAutoScrollToSourceHandler extends AutoScrollToSourceHandler { + private boolean myShouldAutoScroll = true; + + public MyAutoScrollToSourceHandler(Project project) { + super(project); + } + + public void setShouldAutoScroll(boolean shouldAutoScroll) { + myShouldAutoScroll = shouldAutoScroll; + } + + protected boolean isAutoScrollMode() { + return myShouldAutoScroll && ((StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject)).AUTOSCROLL_MODE; + } + + protected void setAutoScrollMode(boolean state) { + ((StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject)).AUTOSCROLL_MODE = state; + } + + protected void scrollToSource(JTree tree) { + myAutoscrollFeedback = true; + + Navigatable editSourceDescriptor = (Navigatable)DataManager.getInstance().getDataContext(getTree()) + .getData(DataConstants.NAVIGATABLE); + if (myFileEditor != null && editSourceDescriptor != null && editSourceDescriptor.canNavigate()) { + editSourceDescriptor.navigate(false); + } + } + } + + private class MyAutoScrollFromSourceHandler extends AutoScrollFromSourceHandler { + private CaretListener myEditorCaretListener; + + private MyAutoScrollFromSourceHandler(Project project) { + super(project); + } + + public void install() { + addEditorCaretListener(); + } + + public void dispose() { + EditorFactory.getInstance().getEventMulticaster().removeCaretListener(myEditorCaretListener); + } + + private void addEditorCaretListener() { + myEditorCaretListener = new CaretListener() { + public void caretPositionChanged(final CaretEvent e) { + Editor editor = e.getEditor(); + FileEditor fileEditor = getFileEditorForEditor(editor); + scrollToElementAtCaret(fileEditor); + } + + private FileEditor getFileEditorForEditor(Editor editor) { + VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument()); + if (file == null) return null; + return FileEditorManager.getInstance(myProject).getSelectedEditor(file); + } + }; + EditorFactory.getInstance().getEventMulticaster().addCaretListener(myEditorCaretListener); + } + + protected boolean isAutoScrollMode() { + StructureViewFactoryImpl structureViewFactory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject); + return structureViewFactory.AUTOSCROLL_FROM_SOURCE; + } + + protected void setAutoScrollMode(boolean state) { + StructureViewFactoryImpl structureViewFactory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject); + structureViewFactory.AUTOSCROLL_FROM_SOURCE = state; + Editor selectedTextEditor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); + VirtualFile file = FileDocumentManager.getInstance().getFile(selectedTextEditor.getDocument()); + if (file != null) { + if (state) scrollToElementAtCaret(FileEditorManager.getInstance(myProject).getSelectedEditor(file)); + } + } + } + + public Object getData(String dataId) { + if (DataConstants.PSI_ELEMENT.equals(dataId)) { + TreePath path = getSelectedPath(); + if (path == null) return null; + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + Object element = descriptor.getElement(); + //if (element instanceof PropertyElement) { + // PsiElement[] elements = ((PropertyElement)element).getPsiElements(); + // if (elements[0].isValid()) return elements[0]; + //} + if (!(element instanceof PsiElement)) return null; + if (!((PsiElement)element).isValid()) return null; + return element; + } + else if (DataConstantsEx.PSI_ELEMENT_ARRAY.equals(dataId)) { + return getSelectedElements(); + } + else if (DataConstants.FILE_EDITOR.equals(dataId)) { + return myFileEditor; + } + else if (DataConstantsEx.CUT_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getCutProvider(); + } + else if (DataConstantsEx.COPY_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getCopyProvider(); + } + else if (DataConstantsEx.PASTE_PROVIDER.equals(dataId)) { + return myCopyPasteDelegator.getPasteProvider(); + } + else if (DataConstantsEx.NAVIGATABLE.equals(dataId)) { + Object[] selectedElements = getSelectedElements(); + if (selectedElements == null || selectedElements.length == 0) return null; + if (selectedElements[0] instanceof Navigatable) return selectedElements[0]; + return null; + } + return null; + } + + private TreePath getSelectedPath() { + return getTree().getSelectionPath(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionWrapper.java new file mode 100644 index 00000000000..beb61ebe87e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionWrapper.java @@ -0,0 +1,33 @@ +package com.intellij.ide.structureView.newStructureView; + +import com.intellij.ide.util.treeView.smartTree.ActionPresentation; +import com.intellij.ide.util.treeView.smartTree.TreeAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; + +public class TreeActionWrapper extends ToggleAction{ + private final TreeAction myAction; + private final TreeActionsOwner myStructureView; + + + public TreeActionWrapper(TreeAction action, TreeActionsOwner structureView) { + myAction = action; + myStructureView = structureView; + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + ActionPresentation actionPresentation = myAction.getPresentation(); + presentation.setIcon(actionPresentation.getIcon()); + presentation.setText(actionPresentation.getText()); + } + + public boolean isSelected(AnActionEvent e) { + return myStructureView.isActionActive(myAction.getName()); + } + + public void setSelected(AnActionEvent e, boolean state) { + myStructureView.setActionActive(myAction.getName(), state); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionsOwner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionsOwner.java new file mode 100644 index 00000000000..f484b3da640 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeActionsOwner.java @@ -0,0 +1,7 @@ +package com.intellij.ide.structureView.newStructureView; + +public interface TreeActionsOwner { + void setActionActive(String name, boolean state); + + boolean isActionActive(String name); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeModelWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeModelWrapper.java new file mode 100644 index 00000000000..338b976db2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/structureView/newStructureView/TreeModelWrapper.java @@ -0,0 +1,49 @@ +package com.intellij.ide.structureView.newStructureView; + +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; + +import java.util.ArrayList; + +public class TreeModelWrapper implements StructureViewModel { + private final StructureViewModel myModel; + private final TreeActionsOwner myStructureView; + + public TreeModelWrapper(StructureViewModel model, TreeActionsOwner structureView) { + myModel = model; + myStructureView = structureView; + } + + public StructureViewTreeElement getRoot() { + return myModel.getRoot(); + } + + public Grouper[] getGroupers() { + ArrayList filtered = filter(myModel.getGroupers()); + return filtered.toArray(new Grouper[filtered.size()]); + } + + private ArrayList filter(Object[] actions) { + ArrayList filtered = new ArrayList(); + for (int i = 0; i < actions.length; i++) { + TreeAction grouper = (TreeAction)actions[i]; + if (myStructureView.isActionActive(grouper.getName())) filtered.add(grouper); + } + return filtered; + } + + public Sorter[] getSorters() { + ArrayList filtered = filter(myModel.getSorters()); + return filtered.toArray(new Sorter[filtered.size()]); + } + + public Filter[] getFilters() { + ArrayList filtered = filter(myModel.getFilters()); + return filtered.toArray(new Filter[filtered.size()]); + } + + public Object getCurrentEditorElement() { + return myModel.getCurrentEditorElement(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/AllTodosTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/AllTodosTreeBuilder.java new file mode 100644 index 00000000000..57391e14cdd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/AllTodosTreeBuilder.java @@ -0,0 +1,37 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.ide.todo; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; + +public class AllTodosTreeBuilder extends TodoTreeBuilder{ + public AllTodosTreeBuilder(JTree tree,DefaultTreeModel treeModel,Project project){ + super(tree,treeModel,project); + } + + protected TodoTreeStructure createTreeStructure(){ + return new AllTodosTreeStructure(myProject); + } + + void rebuildCache(){ + myFileTree.clear(); + myDirtyFileSet.clear(); + myFile2Highlighter.clear(); + + TodoTreeStructure treeStructure=getTodoTreeStructure(); + PsiFile[] psiFiles= mySearchHelper.findFilesWithTodoItems(); + for(int i=0;i 0) + ); + return accept; + } + + public boolean getIsPackagesShown() { + return myArePackagesShown; + } + + Object getFirstSelectableElement() { + return ((ToDoRootNode)myRootElement).getSummaryNode(); + } + + protected AbstractTreeNode createRootElement() { + return new ToDoRootNode(myProject, new Object(), + myBuilder, mySummaryElement); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosPanel.java new file mode 100644 index 00000000000..c26d3e1c297 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosPanel.java @@ -0,0 +1,81 @@ +package com.intellij.ide.todo; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; +import com.intellij.openapi.fileEditor.FileEditorManagerEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.ui.content.Content; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; + +/** + * @author Vladimir Kondratyev + */ +abstract class CurrentFileTodosPanel extends TodoPanel{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.todo.CurrentFileTodosPanel"); + + private MyFileEditorManagerListener myFileEditorManagerListener; + + public CurrentFileTodosPanel(Project project,TodoPanelSettings settings,Content content){ + super(project,settings,true,content); + FileEditorManager fileEditorManager=FileEditorManager.getInstance(project); + VirtualFile[] files=fileEditorManager.getSelectedFiles(); + PsiFile psiFile = files.length != 0 ? PsiManager.getInstance(myProject).findFile(files[0]) : null; + setFile(psiFile); + myFileEditorManagerListener=new MyFileEditorManagerListener(); + fileEditorManager.addFileEditorManagerListener(myFileEditorManagerListener); + } + + void dispose(){ + // It's important to remove this listener. It prevents invocation of setFile method after the tree builder + // is disposed. + FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myFileEditorManagerListener); + super.dispose(); + } + + private void setFile(PsiFile file){ + // setFile method is invoked in LaterInvocatorEx so PsiManager + // can be already dispoded, so we need to check this before using it. + if(isDisposed()){ + return; + } + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + CurrentFileTodosTreeBuilder builder = (CurrentFileTodosTreeBuilder)myTodoTreeBuilder; + builder.setFile(file); + if(myTodoTreeBuilder.isUpdatable()){ + Object selectableElement = builder.getTodoTreeStructure().getFirstSelectableElement(); + if(selectableElement != null){ + builder.buildNodeForElement(selectableElement); + DefaultMutableTreeNode node = builder.getNodeForElement(selectableElement); + LOG.assertTrue(node != null); + myTodoTreeBuilder.getTree().getSelectionModel().setSelectionPath(new TreePath(node.getPath())); + } + } + } + + private boolean isDisposed() { + return myProject == null || PsiManager.getInstance(myProject).isDisposed(); + } + + private final class MyFileEditorManagerListener extends FileEditorManagerAdapter{ + public void selectionChanged(FileEditorManagerEvent e){ + VirtualFile file=e.getNewFile(); + final PsiFile psiFile=file != null ? PsiManager.getInstance(myProject).findFile(file) : null; + // This invokeLater is required. The problem is setFile does a commit to PSI, but setFile is + // invoked inside PSI change event. It causes an Exception like "Changes to PSI are not allowed inside event processing" + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run(){ + setFile(psiFile); + } + }); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeBuilder.java new file mode 100644 index 00000000000..a7699136a36 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeBuilder.java @@ -0,0 +1,44 @@ +package com.intellij.ide.todo; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; + +/** + * @author Vladimir Kondratyev + */ +public class CurrentFileTodosTreeBuilder extends TodoTreeBuilder{ + public CurrentFileTodosTreeBuilder(JTree tree,DefaultTreeModel treeModel,Project project){ + super(tree,treeModel,project); + } + + protected TodoTreeStructure createTreeStructure(){ + return new CurrentFileTodosTreeStructure(myProject); + } + + void rebuildCache(){ + myFileTree.clear(); + myDirtyFileSet.clear(); + myFile2Highlighter.clear(); + + CurrentFileTodosTreeStructure treeStructure=(CurrentFileTodosTreeStructure)myTreeStructure; + PsiFile psiFile=treeStructure.getFile(); + if(treeStructure.accept(psiFile)){ + myFileTree.add(psiFile.getVirtualFile()); + } + + treeStructure.validateCache(); + } + + /** + * @see com.intellij.ide.todo.CurrentFileTodosTreeStructure#setFile + */ + public void setFile(PsiFile file){ + CurrentFileTodosTreeStructure treeStructure=(CurrentFileTodosTreeStructure)myTreeStructure; + treeStructure.setFile(file); + rebuildCache(); + updateTree(false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeStructure.java new file mode 100644 index 00000000000..8a85ef23ee1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/CurrentFileTodosTreeStructure.java @@ -0,0 +1,89 @@ +package com.intellij.ide.todo; + +import com.intellij.ide.todo.nodes.SingleFileToDoNode; +import com.intellij.ide.todo.nodes.ToDoRootNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; + +public final class CurrentFileTodosTreeStructure extends TodoTreeStructure{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.todo.CurrentFileTodosTreeStructure"); + private static final Object[] ourEmptyArray=new Object[]{}; + + /** + * Current VirtualFile for which the structure is built. If myFile is null + * then the structure is empty (contains only root node). + */ + private PsiFile myFile; + + public CurrentFileTodosTreeStructure(Project project){ + super(project); + } + + protected void validateCache(){ + super.validateCache(); + if(myFile!=null && !myFile.isValid()){ + VirtualFile vFile=myFile.getVirtualFile(); + if(vFile.isValid()){ + myFile=PsiManager.getInstance(myProject).findFile(vFile); + }else{ + myFile=null; + } + } + } + + PsiFile getFile(){ + return myFile; + } + + /** + * Sets file for which the structure is built. Alter this method is invoked caches should + * be validated. + */ + public void setFile(PsiFile file){ + myFile=file; + myRootElement = createRootElement(); + } + + public boolean accept(PsiFile psiFile){ + if(myFile==null||!myFile.equals(psiFile)||!myFile.isValid()){ + return false; + } + return (myTodoFilter!=null&&myTodoFilter.accept(mySearchHelper,psiFile))|| + (myTodoFilter==null&&mySearchHelper.getTodoItemsCount(psiFile)>0); + } + + boolean isAutoExpandNode(NodeDescriptor descriptor){ + Object element=descriptor.getElement(); + if(element==myFile){ + return true; + }else{ + return super.isAutoExpandNode(descriptor); + } + } + + Object getFirstSelectableElement(){ + if (myRootElement instanceof SingleFileToDoNode){ + return ((SingleFileToDoNode)myRootElement).getFileNode(); + } else { + return null; + } + } + + public boolean getIsPackagesShown() { + return myArePackagesShown; + } + + protected AbstractTreeNode createRootElement() { + if (myFile == null) { + return new ToDoRootNode(myProject, new Object(), myBuilder, mySummaryElement); + } else { + return new SingleFileToDoNode(myProject, myFile, myBuilder); + } + + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/FileTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/FileTree.java new file mode 100644 index 00000000000..55a37605e46 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/FileTree.java @@ -0,0 +1,177 @@ +package com.intellij.ide.todo; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +final class FileTree{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.todo.FileTree"); + /** + * The ArrayList contains PsiFiles and PsiDirectories. + * Note that all these PsiDirectories has hildren. It means that these directory is only key + * in this map. + */ + private final HashMap> myDirectory2Children; + private final HashSet myFiles; + + FileTree(){ + myDirectory2Children=new HashMap>(); + myFiles=new HashSet(); + } + + void add(VirtualFile file){ + if(myFiles.contains(file)){ + return; + } + + myFiles.add(file); + VirtualFile dir=file.getParent(); + LOG.assertTrue(dir!=null); + ArrayList children=myDirectory2Children.get(dir); + if(children!=null){ + LOG.assertTrue(!children.contains(file)); + children.add(file); + return; + }else{ + children=new ArrayList(2); + children.add(file); + myDirectory2Children.put(dir,children); + } + + VirtualFile parent=dir.getParent(); + while(parent!=null){ + children=myDirectory2Children.get(parent); + if(children!=null){ + if((!children.contains(dir))){ + children.add(dir); + } + return; + }else{ + children=new ArrayList(2); + children.add(dir); + myDirectory2Children.put(parent,children); + } + dir=parent; + parent=parent.getParent(); + } + } + + void removeFile(VirtualFile file){ + if(!myFiles.contains(file)){ + return; + } + + myFiles.remove(file); + ArrayList dirsToBeRemoved=null; + for(Iterator i=myDirectory2Children.keySet().iterator();i.hasNext();){ + VirtualFile _directory=i.next(); + ArrayList children=myDirectory2Children.get(_directory); + LOG.assertTrue(children!=null); + if(children.contains(file)){ + children.remove(file); + if(children.size()==0){ + if(dirsToBeRemoved==null){ + dirsToBeRemoved=new ArrayList(2); + } + dirsToBeRemoved.add(_directory); // we have to remove empty _directory + } + } + } + // We have remove also all removed (empty) directories + if(dirsToBeRemoved!=null){ + LOG.assertTrue(dirsToBeRemoved.size()>0); + for(int i=0;ipsiDirectory from the tree. The directory should be empty, + * otherwise the method thows java.lang.IllegalArgumentException + */ + private void removeDir(VirtualFile psiDirectory){ + if(!myDirectory2Children.containsKey(psiDirectory)){ + throw new IllegalArgumentException("directory is not in the tree: "+psiDirectory); + } + ArrayList children=myDirectory2Children.remove(psiDirectory); + if(children==null){ + throw new IllegalArgumentException("directory has no children list: "+psiDirectory); + } + if(children.size()>0){ + throw new IllegalArgumentException("directory isn't empty: "+psiDirectory); + } + // + ArrayList dirsToBeRemoved=null; + for(Iterator i=myDirectory2Children.keySet().iterator();i.hasNext();){ + VirtualFile _directory=i.next(); + children=myDirectory2Children.get(_directory); + LOG.assertTrue(children!=null); + if(children.contains(psiDirectory)){ + children.remove(psiDirectory); + if(children.size()==0){ + if(dirsToBeRemoved==null){ + dirsToBeRemoved=new ArrayList(2); + } + dirsToBeRemoved.add(_directory); // we have remove empty _directory + } + } + } + // + if(dirsToBeRemoved!=null){ + for(int i=0;i getFileIterator(){ + return myFiles.iterator(); + } + + /** + * @return all files (in depth) located under specified psiDirectory. + * Please note that returned fiels can be invalid. + */ + ArrayList getFiles(VirtualFile dir){ + ArrayList filesList=new ArrayList(); + collectFiles(dir,filesList); + return filesList; + } + + private void collectFiles(VirtualFile dir,ArrayList filesList){ + ArrayList children=myDirectory2Children.get(dir); + if(children==null){ + return; + }else{ + for(int i=0;i myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class); + + public static final String PROP_TODO_PATTERNS = "todoPatterns"; + public static final String PROP_TODO_FILTERS = "todoFilters"; + + /** + * Invoked by reflection + */ + TodoConfiguration() { + myTodoPatterns = new TodoPattern[]{ + new TodoPattern("\\btodo\\b.*", TodoAttributes.createDefault(), false) + }; + myTodoFilters = new TodoFilter[]{}; + } + + public static TodoConfiguration getInstance() { + return ApplicationManager.getApplication().getComponent(TodoConfiguration.class); + } + + public String getComponentName() { + return "TodoConfiguration"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public TodoPattern[] getTodoPatterns() { + return myTodoPatterns; + } + + public void setTodoPatterns(TodoPattern[] patterns) { + TodoPattern[] oldPatterns = myTodoPatterns; + myTodoPatterns = patterns; + myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldPatterns, patterns)); + } + + /** + * @return TodoFilter with specified name. Method returns + * null if there is no filter with name. + */ + public TodoFilter getTodoFilter(String name) { + for (int i = 0; i < myTodoFilters.length; i++) { + TodoFilter filter = myTodoFilters[i]; + if (filter.getName().equals(name)) { + return filter; + } + } + return null; + } + + /** + * @return all TodoFilters. + */ + public TodoFilter[] getTodoFilters() { + return myTodoFilters; + } + + public void setTodoFilters(TodoFilter[] filters) { + TodoFilter[] oldFilters = myTodoFilters; + myTodoFilters = filters; + myPropertyChangeMulticaster.getMulticaster().propertyChange(new PropertyChangeEvent(this, PROP_TODO_FILTERS, oldFilters, filters)); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeMulticaster.addListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeMulticaster.removeListener(listener); + } + + public void dispatchPendingEvent(PropertyChangeListener listener) { + myPropertyChangeMulticaster.dispatchPendingEvent(listener); + } + + public void readExternal(Element element) throws InvalidDataException { + ArrayList patternsList = new ArrayList(); + ArrayList filtersList = new ArrayList(); + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element child = (Element)i.next(); + if ("pattern".equals(child.getName())) { + TodoPattern pattern = new TodoPattern(); + pattern.readExternal(child); + patternsList.add(pattern); + } + else if ("filter".equals(child.getName())) { + TodoPattern[] patterns = (TodoPattern[])patternsList.toArray(new TodoPattern[patternsList.size()]); + TodoFilter filter = new TodoFilter(); + filter.readExternal(child, patterns); + filtersList.add(filter); + } + } + setTodoPatterns((TodoPattern[])patternsList.toArray(new TodoPattern[patternsList.size()])); + setTodoFilters((TodoFilter[])filtersList.toArray(new TodoFilter[filtersList.size()])); + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myTodoPatterns.length; i++) { + TodoPattern pattern = myTodoPatterns[i]; + Element child = new Element("pattern"); + pattern.writeExternal(child); + element.addContent(child); + } + for (int i = 0; i < myTodoFilters.length; i++) { + TodoFilter filter = myTodoFilters[i]; + Element child = new Element("filter"); + filter.writeExternal(child, myTodoPatterns); + element.addContent(child); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFileDirComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFileDirComparator.java new file mode 100644 index 00000000000..c143d2172c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFileDirComparator.java @@ -0,0 +1,52 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.ide.todo; + +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; + +import java.util.Comparator; + +public final class TodoFileDirComparator implements Comparator{ + public static final TodoFileDirComparator ourInstance=new TodoFileDirComparator(); + + private TodoFileDirComparator(){} + + public int compare(Object obj1,Object obj2){ + if((obj1 instanceof PsiFileNode)&&(obj2 instanceof PsiFileNode)){ + return compareFiles(((PsiFileNode)obj1).getValue(),((PsiFileNode)obj2).getValue()); + }else if((obj1 instanceof PsiFileNode)&&(obj2 instanceof PsiDirectoryNode)){ + return 1; + }else if((obj1 instanceof PsiDirectoryNode)&&(obj2 instanceof PsiFileNode)){ + return -1; + }else if((obj1 instanceof PsiDirectoryNode)&&(obj2 instanceof PsiDirectoryNode)){ + PsiDirectory psiDirectory1=((PsiDirectoryNode)obj1).getValue(); + PsiPackage psiPackage1=psiDirectory1.getPackage(); + PsiDirectory psiDirectory2=((PsiDirectoryNode)obj2).getValue(); + PsiPackage psiPackage2=psiDirectory2.getPackage(); + if(psiPackage1!=null&&psiPackage2==null){ + return -1; + }else if(psiPackage1==null&&psiPackage2!=null){ + return 1; + }else if(psiPackage1!=null){ + return psiPackage1.getQualifiedName().compareTo(psiPackage2.getQualifiedName()); + }else{ + String path1=psiDirectory1.getVirtualFile().getPath().toLowerCase(); + String path2=psiDirectory2.getVirtualFile().getPath().toLowerCase(); + return path1.compareTo(path2); + } + }else{ + throw new IllegalArgumentException(obj1.getClass().getName()+","+obj2.getClass().getName()); + } + } + + private static int compareFiles(PsiFile psiFile1,PsiFile psiFile2){ + String path1=psiFile1.getVirtualFile().getPath().toLowerCase(); + String path2=psiFile2.getVirtualFile().getPath().toLowerCase(); + return path1.compareTo(path2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFilter.java new file mode 100644 index 00000000000..c32b1f7b7a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoFilter.java @@ -0,0 +1,196 @@ +package com.intellij.ide.todo; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.TodoPattern; +import org.jdom.Element; + +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +public class TodoFilter implements Cloneable{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.todo.TodoFilter"); + + private String myName; + // TODO[vova] use array for storing TodoPatterns. Perhaps it's better... + private HashSet myTodoPatterns; + + /** + * Creates filter with empty name and empty set of patterns. + */ + public TodoFilter(){ + setName(""); + myTodoPatterns=new HashSet(1); + } + + /** + * @return true if and only if specified psiFile has + * TodoItems accepted by the filter. + */ + public boolean accept(PsiSearchHelper searchHelper,PsiFile psiFile){ + for(Iterator i=iterator();i.hasNext();){ + TodoPattern todoPattern=(TodoPattern)i.next(); + if(searchHelper.getTodoItemsCount(psiFile,todoPattern)>0){ + return true; + } + } + return false; + } + + /** + * @return filter's name. That is not null string. + */ + public String getName(){ + return myName; + } + + public void setName(String name){ + LOG.assertTrue(name!=null); + myName=name; + } + + /** + * @return true if and only if filters contains specified pattern. + */ + public boolean contains(TodoPattern pattern){ + return myTodoPatterns.contains(pattern); + } + + /** + * Adds specified pattern to the set of containing patterns. + */ + public void addTodoPattern(TodoPattern pattern){ + LOG.assertTrue(!myTodoPatterns.contains(pattern)); + myTodoPatterns.add(pattern); + } + + /** + * Adds specified pattern from the set of containing patterns. + */ + public void removeTodoPattern(TodoPattern pattern){ + LOG.assertTrue(myTodoPatterns.contains(pattern)); + myTodoPatterns.remove(pattern); + } + + /** + * @return iterator of containing patterns. + */ + public Iterator iterator(){ + return myTodoPatterns.iterator(); + } + + /** + * @return true if and only if filter contains no TodoPatterns. + */ + public boolean isEmpty(){ + return myTodoPatterns.size()==0; + } + + /** + * @return index of specified pattern in the array of patterns. + * Returns -1 if pattern not found. + */ + private static int getPatterIndex(TodoPattern pattern,TodoPattern[] patterns){ + for(int i=0;ipatterns.length-1){ + continue; + } + TodoPattern pattern=patterns[index]; + if(myTodoPatterns.contains(pattern)){ + continue; + } + myTodoPatterns.add(pattern); + }catch(NumberFormatException exc){ + continue; + } + } + } + + /** + * @param element in which all data will be stored + * @param patterns all available patterns + */ + public void writeExternal(Element element,TodoPattern[] patterns){ + element.setAttribute("name",myName); + for(Iterator i=myTodoPatterns.iterator();i.hasNext();){ + TodoPattern pattern=(TodoPattern)i.next(); + int index=getPatterIndex(pattern,patterns); + LOG.assertTrue(index!=-1); + Element child=new Element("pattern"); + child.setAttribute("index",Integer.toString(index)); + element.addContent(child); + } + } + + public int hashCode(){ + int hashCode=myName.hashCode(); + for(Iterator i=myTodoPatterns.iterator();i.hasNext();){ + TodoPattern todoPattern=(TodoPattern)i.next(); + hashCode+=todoPattern.hashCode(); + } + return hashCode; + } + + public boolean equals(Object obj){ + if(!(obj instanceof TodoFilter)){ + return false; + } + TodoFilter filter=(TodoFilter)obj; + + if(!myName.equals(filter.myName)){ + return false; + } + + if(myTodoPatterns.size()!=filter.myTodoPatterns.size()){ + return false; + } + + for(Iterator i=myTodoPatterns.iterator();i.hasNext();){ + TodoPattern pattern=(TodoPattern)i.next(); + if(!filter.contains(pattern)){ + return false; + } + } + + return true; + } + + public TodoFilter clone(){ + try{ + TodoFilter filter = (TodoFilter)super.clone(); + filter.myTodoPatterns=new HashSet(myTodoPatterns); + return filter; + }catch(CloneNotSupportedException e){ + LOG.error(e); + return null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanel.java new file mode 100644 index 00000000000..95e0a4da62b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanel.java @@ -0,0 +1,586 @@ +package com.intellij.ide.todo; + +import com.intellij.ide.OccurenceNavigator; +import com.intellij.ide.TreeExpander; +import com.intellij.ide.actions.*; +import com.intellij.ide.todo.configurable.TodoConfigurable; +import com.intellij.ide.todo.nodes.TodoDirNode; +import com.intellij.ide.todo.nodes.TodoFileNode; +import com.intellij.ide.todo.nodes.TodoItemNode; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.impl.ActionButton; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.openapi.wm.impl.VisibilityWatcher; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.content.Content; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * @author Vladimir Kondratyev + */ +abstract class TodoPanel extends JPanel implements OccurenceNavigator, DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.todo.TodoPanel"); + private static final VirtualFile[] ourEmptyArray = new VirtualFile[]{}; + + protected Project myProject; + private final TodoPanelSettings mySettings; + private final boolean myCurrentFileMode; + private Content myContent; + + private final Tree myTree; + private final MyTreeExpander myTreeExpander; + private final MyOccurenceNavigator myOccurenceNavigator; + protected final TodoTreeBuilder myTodoTreeBuilder; + private MyVisibilityWatcher myVisibilityWatcher; + + /** + * @param currentFileMode if true then view doesn't have "Group By Packages" and "Flatten Packages" + * actions. + */ + public TodoPanel(Project project, + TodoPanelSettings settings, + boolean currentFileMode, + Content content) { + super(new BorderLayout()); + myProject = project; + mySettings = settings; + myCurrentFileMode = currentFileMode; + myContent = content; + + DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode()); + myTree = new Tree(model); + myTreeExpander = new MyTreeExpander(); + myOccurenceNavigator = new MyOccurenceNavigator(); + initUI(); + myTodoTreeBuilder = createTreeBuilder(myTree, model, myProject); + updateTodoFilter(); + myTodoTreeBuilder.setShowPackages(mySettings.arePackagesShown()); + myTodoTreeBuilder.setFlattenPackages(mySettings.areFlattenPackages()); + + myVisibilityWatcher = new MyVisibilityWatcher(); + myVisibilityWatcher.install(this); + } + + protected abstract TodoTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project); + + private void initUI() { + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setShowsRootHandles(true); + myTree.setRootVisible(false); + myTree.setCellRenderer(new TodoCompositeRenderer()); + EditSourceOnDoubleClickHandler.install(myTree); + + DefaultActionGroup group = new DefaultActionGroup(); + group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); + group.addSeparator(); + group.add(ActionManager.getInstance().getAction(IdeActions.GROUP_VERSION_CONTROLS)); + PopupHandler.installPopupHandler(myTree, group, ActionPlaces.TODO_VIEW_POPUP, ActionManager.getInstance()); + + myTree.addKeyListener( + new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (!e.isConsumed() && KeyEvent.VK_ENTER == e.getKeyCode()) { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return; + } + NodeDescriptor desciptor = (NodeDescriptor)((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject(); + if (!(desciptor instanceof TodoItemNode)) { + return; + } + Navigatable navigatable = (Navigatable)getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(false); + } + } + } + } + ); + add(new JScrollPane(myTree), BorderLayout.CENTER); + + // Create tool bars and register custom shortcuts + + JPanel toolBarPanel = new JPanel(new GridLayout()); + + DefaultActionGroup leftGroup = new DefaultActionGroup(); + leftGroup.add(new PreviousOccurenceToolbarAction(myOccurenceNavigator)); + leftGroup.add(new NextOccurenceToolbarAction(myOccurenceNavigator)); + leftGroup.add(new ToolbarHelpAction("find.todoList")); + toolBarPanel.add( + ActionManager.getInstance().createActionToolbar(ActionPlaces.TODO_VIEW_TOOLBAR, leftGroup, false).getComponent()); + + DefaultActionGroup rightGroup = new DefaultActionGroup(); + ExpandAllToolbarAction expandAllAction = new ExpandAllToolbarAction(myTreeExpander); + expandAllAction.registerCustomShortcutSet(expandAllAction.getShortcutSet(), myTree); + rightGroup.add(expandAllAction); + + CollapseAllToolbarAction collapseAllAction = new CollapseAllToolbarAction(myTreeExpander); + collapseAllAction.registerCustomShortcutSet(collapseAllAction.getShortcutSet(), myTree); + rightGroup.add(collapseAllAction); + + if (!myCurrentFileMode) { + MyShowPackagesAction showPackagesAction = new MyShowPackagesAction(); + showPackagesAction.registerCustomShortcutSet( + new CustomShortcutSet( + KeyStroke.getKeyStroke(KeyEvent.VK_P, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK)), + myTree); + rightGroup.add(showPackagesAction); + + MyFlattenPackagesAction flattenPackagesAction = new MyFlattenPackagesAction(); + flattenPackagesAction.registerCustomShortcutSet( + new CustomShortcutSet( + KeyStroke.getKeyStroke(KeyEvent.VK_F, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK)), + myTree); + rightGroup.add(flattenPackagesAction); + } + + MyAutoScrollToSourceHandler autoScrollToSourceHandler = new MyAutoScrollToSourceHandler(); + autoScrollToSourceHandler.install(myTree); + rightGroup.add(autoScrollToSourceHandler.createToggleAction()); + + MySetTodoFilterAction setTodoFilterAction = new MySetTodoFilterAction(); + rightGroup.add(setTodoFilterAction); + toolBarPanel.add( + ActionManager.getInstance().createActionToolbar(ActionPlaces.TODO_VIEW_TOOLBAR, rightGroup, false).getComponent()); + + add(toolBarPanel, BorderLayout.WEST); + } + + void dispose() { + myTodoTreeBuilder.dispose(); + myVisibilityWatcher.deinstall(this); + myVisibilityWatcher = null; + myProject = null; + } + + void rebuildCache() { + myTodoTreeBuilder.rebuildCache(); + } + + /** + * Immediately updates tree. + */ + void updateTree() { + myTodoTreeBuilder.updateTree(false); + } + + /** + * Updates current filter. If previously set filter was removed then empty filter is set. + * + * @see com.intellij.ide.todo.TodoTreeBuilder#setTodoFilter + */ + void updateTodoFilter() { + TodoFilter filter = TodoConfiguration.getInstance().getTodoFilter(mySettings.getTodoFilterName()); + setTodoFilter(filter); + } + + /** + * Sets specified TodoFilter. The method also updates window's title. + * + * @see com.intellij.ide.todo.TodoTreeBuilder#setTodoFilter + */ + private void setTodoFilter(TodoFilter filter) { + // Clear name of current filter if it was removed from configuration. + String filterName = filter != null ? filter.getName() : null; + mySettings.setTodoFilterName(filterName); + // Update filter + myTodoTreeBuilder.setTodoFilter(filter); + // Update content's title + myContent.setDescription(filterName); + } + + /** + * @return list of all selected virtual files. + */ + private VirtualFile getSelectedFile() { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + LOG.assertTrue(node != null); + if(node.getUserObject() == null){ + return null; + } + PsiFile[] psiFiles = myTodoTreeBuilder.getFilesForNode(node); + if (psiFiles.length > 0) { + return psiFiles[0].getVirtualFile(); + } + else { + return null; + } + } + + private PsiElement getSelectedElement() { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + Object userObject = node.getUserObject(); + if (userObject instanceof TodoDirNode) { + TodoDirNode descriptor = (TodoDirNode)userObject; + return descriptor.getValue(); + } + else if (userObject instanceof TodoFileNode) { + TodoFileNode descriptor = (TodoFileNode)userObject; + return descriptor.getValue(); + } + else { + VirtualFile file = getSelectedFile(); + if (file != null) { + return PsiManager.getInstance(myProject).findFile(file); + } + } + return null; + } + + public Object getData(String dataId) { + if (DataConstants.NAVIGATABLE.equals(dataId)) { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + NodeDescriptor userObject = (NodeDescriptor)node.getUserObject(); + if (userObject == null) { + return null; + } + Object element = userObject.getElement(); + if (!((element instanceof SmartTodoItemPointer) || (element instanceof PsiFile))) { // allow user to use F4 only on files an TODOs + return null; + } + SmartTodoItemPointer pointer = myTodoTreeBuilder.getFirstPointerForElement(element); + if (pointer != null) { + return new OpenFileDescriptor(myProject, pointer.getTodoItem().getFile().getVirtualFile(), + pointer.getRangeMarker().getStartOffset() + ); + } + else { + return null; + } + } + else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + return getSelectedFile(); + } + else if (DataConstants.PSI_ELEMENT.equals(dataId)) { + return getSelectedElement(); + } + else if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + VirtualFile file = getSelectedFile(); + if (file != null) { + return new VirtualFile[]{file}; + } + else { + return ourEmptyArray; + } + } + else if (DataConstantsEx.HELP_ID.equals(dataId)) { + return "find.todoList"; + } + return null; + } + + public OccurenceNavigator.OccurenceInfo goPreviousOccurence() { + return myOccurenceNavigator.goPreviousOccurence(); + } + + public String getNextOccurenceActionName() { + return myOccurenceNavigator.getNextOccurenceActionName(); + } + + public OccurenceNavigator.OccurenceInfo goNextOccurence() { + return myOccurenceNavigator.goNextOccurence(); + } + + public boolean hasNextOccurence() { + return myOccurenceNavigator.hasNextOccurence(); + } + + public String getPreviousOccurenceActionName() { + return myOccurenceNavigator.getPreviousOccurenceActionName(); + } + + public boolean hasPreviousOccurence() { + return myOccurenceNavigator.hasPreviousOccurence(); + } + + private final class MyTreeExpander implements TreeExpander { + public boolean canCollapse() { + return true; + } + + public boolean canExpand() { + return true; + } + + public void collapseAll() { + myTodoTreeBuilder.collapseAll(); + } + + public void expandAll() { + myTodoTreeBuilder.expandAll(); + } + } + + /** + * Provides support for "auto scroll to source" functionnality. + */ + private final class MyAutoScrollToSourceHandler extends AutoScrollToSourceHandler { + public MyAutoScrollToSourceHandler() { + super(myProject); + } + + protected boolean isAutoScrollMode() { + return mySettings.isAutoScrollToSource(); + } + + protected void setAutoScrollMode(boolean state) { + mySettings.setAutoScrollToSource(state); + } + } + + /** + * Provides support for "Ctrl+Alt+Up/Down" navigation. + */ + private final class MyOccurenceNavigator implements OccurenceNavigator { + public boolean hasNextOccurence() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + return getNextPointer() != null; + } + + public boolean hasPreviousOccurence() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + return getPreviousPointer() != null; + } + + public OccurenceNavigator.OccurenceInfo goNextOccurence() { + return goToPointer(getNextPointer()); + } + + public OccurenceNavigator.OccurenceInfo goPreviousOccurence() { + return goToPointer(getPreviousPointer()); + } + + public String getNextOccurenceActionName() { + return "Next TODO"; + } + + public String getPreviousOccurenceActionName() { + return "Previous TODO"; + } + + private OccurenceNavigator.OccurenceInfo goToPointer(SmartTodoItemPointer pointer) { + LOG.assertTrue(pointer != null); + DefaultMutableTreeNode node = myTodoTreeBuilder.getNodeForElement(pointer); + if (node == null) { + myTodoTreeBuilder.buildNodeForElement(pointer); + node = myTodoTreeBuilder.getNodeForElement(pointer); + if (node == null) { + // TODO[vova] it seems that this check isn't required any more bacause it was side effect of SCR#7063 + // TODO[vova] try to remove this check in Aurora + return null; + } + } + TreeUtil.selectPath(myTree, new TreePath(node.getPath())); + return new OccurenceInfo( + new OpenFileDescriptor(myProject, pointer.getTodoItem().getFile().getVirtualFile(), + pointer.getRangeMarker().getStartOffset()), + -1, + -1 + ); + } + + private SmartTodoItemPointer getNextPointer() { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + NodeDescriptor userObject = (NodeDescriptor)node.getUserObject(); + if (userObject == null) { + return null; + } + Object element = userObject.getElement(); + SmartTodoItemPointer pointer; + if (element instanceof SmartTodoItemPointer) { + pointer = myTodoTreeBuilder.getNextPointer((SmartTodoItemPointer)element); + } + else { + pointer = myTodoTreeBuilder.getFirstPointerForElement(element); + } + return pointer; + } + + private SmartTodoItemPointer getPreviousPointer() { + TreePath path = myTree.getSelectionPath(); + if (path == null) { + return null; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + NodeDescriptor userObject = (NodeDescriptor)node.getUserObject(); + if (userObject == null) { + return null; + } + Object element = userObject.getElement(); + SmartTodoItemPointer pointer; + if (element instanceof SmartTodoItemPointer) { + pointer = myTodoTreeBuilder.getPreviousPointer((SmartTodoItemPointer)element); + } + else { + Object sibling = myTodoTreeBuilder.getPreviousSibling(element); + if (sibling == null) { + return null; + } + pointer = myTodoTreeBuilder.getLastPointerForElement(sibling); + } + return pointer; + } + } + + private final class MyShowPackagesAction extends ToggleAction { + public MyShowPackagesAction() { + super("Group By Packages", null, IconLoader.getIcon("/toolbar/folders.png")); + } + + public boolean isSelected(AnActionEvent e) { + return mySettings.arePackagesShown(); + } + + public void setSelected(AnActionEvent e, boolean state) { + mySettings.setShownPackages(state); + myTodoTreeBuilder.setShowPackages(state); + } + } + + private final class MyFlattenPackagesAction extends ToggleAction { + public MyFlattenPackagesAction() { + super("Flatten Packages", null, IconLoader.getIcon("/objectBrowser/flattenPackages.png")); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(mySettings.arePackagesShown()); + } + + public boolean isSelected(AnActionEvent e) { + return mySettings.areFlattenPackages(); + } + + public void setSelected(AnActionEvent e, boolean state) { + mySettings.setAreFlattenPackages(state); + myTodoTreeBuilder.setFlattenPackages(state); + } + } + + private final class MySetTodoFilterAction extends AnAction implements CustomComponentAction { + public MySetTodoFilterAction() { + super("Filter TODO Items", null, IconLoader.getIcon("/ant/filter.png")); + } + + public void actionPerformed(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + JComponent button = (JComponent)presentation.getClientProperty("button"); + DefaultActionGroup group = createPopupActionGroup(); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.TODO_VIEW_TOOLBAR, + group); + popupMenu.getComponent().show(button, button.getWidth(), 0); + } + + public JComponent createCustomComponent(Presentation presentation) { + ActionButton button = new ActionButton( + this, + presentation, + ActionPlaces.TODO_VIEW_TOOLBAR, + ActionToolbarEx.DEFAULT_MINIMUM_BUTTON_SIZE + ); + presentation.putClientProperty("button", button); + return button; + } + + private DefaultActionGroup createPopupActionGroup() { + TodoFilter[] filters = TodoConfiguration.getInstance().getTodoFilters(); + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new TodoFilterApplier("Show All", "Show All TODO Items", null)); + for (int i = 0; i < filters.length; i++) { + TodoFilter filter = filters[i]; + group.add(new TodoFilterApplier(filter.getName(), null, filter)); + } + group.addSeparator(); + group.add( + new AnAction("Edit Filters", "Edit Filters", IconLoader.getIcon("/general/projectProperties.png")) { + public void actionPerformed(AnActionEvent e) { + ShowSettingsUtil.getInstance().editConfigurable(myProject, TodoConfigurable.getInstance()); + } + } + ); + return group; + } + + private final class TodoFilterApplier extends ToggleAction { + private TodoFilter myFilter; + + /** + * @param text action's text. + * @param description action's description. + * @param filter filter to be applied. null value means "empty" filter. + */ + public TodoFilterApplier(String text, String description, TodoFilter filter) { + super(null, description, null); + getTemplatePresentation().setText(text, false); + myFilter = filter; + } + + public void update(AnActionEvent e) { + super.update(e); + if (myFilter != null) { + e.getPresentation().setEnabled(!myFilter.isEmpty()); + } + } + + public boolean isSelected(AnActionEvent e) { + return Comparing.equal(myFilter != null ? myFilter.getName() : null, mySettings.getTodoFilterName()); + } + + public void setSelected(AnActionEvent e, boolean state) { + if (state) { + setTodoFilter(myFilter); + } + } + } + } + + private final class MyVisibilityWatcher extends VisibilityWatcher { + public void visibilityChanged() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + myTodoTreeBuilder.setUpdatable(isShowing()); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanelSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanelSettings.java new file mode 100644 index 00000000000..77e689f2f57 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoPanelSettings.java @@ -0,0 +1,82 @@ +package com.intellij.ide.todo; + +import org.jdom.Element; + +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +class TodoPanelSettings{ + private boolean myArePackagesShown; + private boolean myAreFlattenPackages; + private boolean myIsAutoScrollToSource; + private String myTodoFilterName; + + public void readExternal(Element e){ + for(Iterator i=e.getChildren().iterator();i.hasNext();){ + Element child=(Element)i.next(); + if("are-packages-shown".equals(child.getName())){ + myArePackagesShown=Boolean.valueOf(child.getAttributeValue("value")).booleanValue(); + }if("flatten-packages".equals(child.getName())){ + myAreFlattenPackages=Boolean.valueOf(child.getAttributeValue("value")).booleanValue(); + }else if("is-autoscroll-to-source".equals(child.getName())){ + myIsAutoScrollToSource=Boolean.valueOf(child.getAttributeValue("value")).booleanValue(); + }else if("todo-filter".equals(child.getName())){ + myTodoFilterName=child.getAttributeValue("name"); + } + } + } + + public void writeExternal(Element e){ + Element areArePackagesShownElement=new Element("are-packages-shown"); + areArePackagesShownElement.setAttribute("value",myArePackagesShown?Boolean.TRUE.toString():Boolean.FALSE.toString()); + e.addContent(areArePackagesShownElement); + + Element areAreFlattenPackagesElement=new Element("flatten-packages"); + areAreFlattenPackagesElement.setAttribute("value",myAreFlattenPackages?Boolean.TRUE.toString():Boolean.FALSE.toString()); + e.addContent(areAreFlattenPackagesElement); + + Element isAutoScrollModeElement=new Element("is-autoscroll-to-source"); + isAutoScrollModeElement.setAttribute("value",myIsAutoScrollToSource?Boolean.TRUE.toString():Boolean.FALSE.toString()); + e.addContent(isAutoScrollModeElement); + + if(myTodoFilterName!=null){ + Element todoFilterElement=new Element("todo-filter"); + todoFilterElement.setAttribute("name",myTodoFilterName); + e.addContent(todoFilterElement); + } + } + + boolean arePackagesShown(){ + return myArePackagesShown; + } + + public void setShownPackages(boolean state){ + myArePackagesShown=state; + } + + boolean areFlattenPackages(){ + return myAreFlattenPackages; + } + + void setAreFlattenPackages(boolean state){ + myAreFlattenPackages=state; + } + + boolean isAutoScrollToSource(){ + return myIsAutoScrollToSource; + } + + void setAutoScrollToSource(boolean state){ + myIsAutoScrollToSource=state; + } + + String getTodoFilterName(){ + return myTodoFilterName; + } + + void setTodoFilterName(String todoFilterName){ + myTodoFilterName=todoFilterName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeBuilder.java new file mode 100644 index 00000000000..b9cdfba4e4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeBuilder.java @@ -0,0 +1,694 @@ +package com.intellij.ide.todo; + +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.ide.todo.nodes.*; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.TreeBuilderUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.TodoItem; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.usageView.UsageTreeColorsScheme; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +public abstract class TodoTreeBuilder extends AbstractTreeBuilder { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.todo.TodoTreeBuilder"); + protected final Project myProject; + + /** + * All files that have TODO items are presented as tree. This tree help a lot + * to separate these files by directories. + */ + protected final FileTree myFileTree; + /** + * This set contains "dirty" files. File is "dirty" if it's currently not nkown + * whether the file contains TODO item or not. To determine this it's necessary + * to perform some (perhaps, CPU expensive) operation. These "dirty" files are + * validated in validateCache() method. + */ + protected final HashSet myDirtyFileSet; + + protected final com.intellij.util.containers.HashMap myFile2Highlighter; + + protected final PsiSearchHelper mySearchHelper; + /** + * If this flag is false then the updateTree() method does nothing. But when + * the flag becomes true and myDirtyFileSet isn't empty the update is invoked. + * This is done for optimization reasons: if TodoPane is not visible then + * updates isn't invoked. + */ + private boolean myUpdatable; + + /** Updates tree if containing files change VCS status. */ + private final MyFileStatusListener myFileStatusListener; + + TodoTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project) { + super(tree, treeModel, null, MyComparator.ourInstance); + myProject = project; + + myFileTree = new FileTree(); + myDirtyFileSet = new HashSet(); + + myFile2Highlighter = new com.intellij.util.containers.HashMap(); + + PsiManager psiManager = PsiManager.getInstance(myProject); + mySearchHelper = psiManager.getSearchHelper(); + psiManager.addPsiTreeChangeListener(new MyPsiTreeChangeListener()); + + myFileStatusListener = new MyFileStatusListener(); + + myUpdater.setDelay(1500); + } + + /** + * Initializes the builder. Subclasses should don't forget to call this method after constuctor has + * been invoked. + */ + public final void init() { + TodoTreeStructure todoTreeStructure = createTreeStructure(); + myTreeStructure = todoTreeStructure; + todoTreeStructure.setTreeBuilder(this); + + rebuildCache(); + initRootNode(); + + Object selectableElement = todoTreeStructure.getFirstSelectableElement(); + if (selectableElement != null) { + buildNodeForElement(selectableElement); + DefaultMutableTreeNode node = getNodeForElement(selectableElement); + myTree.getSelectionModel().setSelectionPath(new TreePath(node.getPath())); + } + + FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener); + } + + final public void dispose() { + FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener); + super.dispose(); + } + + final boolean isUpdatable() { + return myUpdatable; + } + + /** + * Sets whenther the builder updates the tree when data change. + */ + final void setUpdatable(boolean updatable) { + if (myUpdatable != updatable) { + myUpdatable = updatable; + if (myUpdatable) { + updateTree(false); + } + } + } + + protected abstract TodoTreeStructure createTreeStructure(); + + public final TodoTreeStructure getTodoTreeStructure() { + return (TodoTreeStructure)myTreeStructure; + } + + final protected AbstractTreeUpdater createUpdater() { + return new AbstractTreeUpdater(this) { + protected void updateSubtree(DefaultMutableTreeNode node) { + if (!myDirtyFileSet.isEmpty()) { // suppress redundant cache validations + validateCache(); + getTodoTreeStructure().validateCache(); + } + super.updateSubtree(node); + } + }; + } + + /** + * @return read-only iterator of all current PSI files that can contain TODOs. + * Don't invoke its remove method. For "removing" use markFileAsDirty method. + * Note, that next() method of iterator can return null elements. + * These null elements correspond to the invalid PSI files (PSI file cannot be found by + * virtual file, or virtual file is invalid). + * The reason why we return such "dirty" iterator is the peformance. + */ + public Iterator getAllFiles() { + final Iterator iterator = myFileTree.getFileIterator(); + return new Iterator() { + public boolean hasNext() { + return iterator.hasNext(); + } + + public Object next() { + VirtualFile vFile = iterator.next(); + if (vFile == null || !vFile.isValid()) { + return null; + } + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); + if (psiFile == null || !psiFile.isValid()) { + return null; + } + return psiFile; + } + + public void remove() { + throw new IllegalArgumentException(); + } + }; + } + + /** + * @return read-only iterator of all valid PSI files that can have TODO items + * and which are located under specified psiDirctory. + * @see com.intellij.ide.todo.FileTree#getFiles(VirtualFile) + */ + public Iterator getFiles(PsiDirectory psiDirectory) { + ArrayList files = myFileTree.getFiles(psiDirectory.getVirtualFile()); + ArrayList psiFileList = new ArrayList(files.size()); + PsiManager psiManager = PsiManager.getInstance(myProject); + for (int i = 0; i < files.size(); i++) { + VirtualFile file = files.get(i); + if (file.isValid()) { + PsiFile psiFile = psiManager.findFile(file); + if (psiFile != null) { + psiFileList.add(psiFile); + } + } + } + return psiFileList.iterator(); + } + + /** + * @return true if specified psiFile can contains too items. + * It means that file is in "dirty" file set or in "current" file set. + */ + private boolean canContainTodoItems(PsiFile psiFile) { + VirtualFile vFile = psiFile.getVirtualFile(); + return myFileTree.contains(vFile) || myDirtyFileSet.contains(vFile); + } + + /** + * Marks specified PsiFile as dirty. It means that file is being add into "dirty" file set. + * It presents in current file set also but the next validateCache call will validate this + * "dirty" file. This method should be invoked when any modifications inside the file + * have happend. + */ + private void markFileAsDirty(PsiFile psiFile) { + LOG.assertTrue(psiFile != null); + VirtualFile vFile = psiFile.getVirtualFile(); + if (vFile != null) { // If PSI file isn't valid then its VirtualFile can be null + if (myDirtyFileSet.contains(vFile)) { + return; + } + else { + myDirtyFileSet.add(vFile); + } + } + } + + /** + * Clear and rebuild whole the caches. It means that after rebuilding all caches are valid. + */ + abstract void rebuildCache(); + + private void validateCache() { + TodoTreeStructure treeStructure = getTodoTreeStructure(); + // First of all we need to update "dirty" file set. + for (Iterator i = myDirtyFileSet.iterator(); i.hasNext();) { + VirtualFile file = (VirtualFile)i.next(); + PsiFile psiFile = file.isValid() ? PsiManager.getInstance(myProject).findFile(file) : null; + if (psiFile == null || !treeStructure.accept(psiFile)) { + if (myFileTree.contains(file)) { + myFileTree.removeFile(file); + if (myFile2Highlighter.containsKey(file)) { // highlighter isn't needed any more + myFile2Highlighter.remove(file); + } + } + } + else { // file is valid and contains TODO items + myFileTree.removeFile(file); + myFileTree.add(file); // file can be moved. remove/add calls move it to another place + if (myFile2Highlighter.containsKey(file)) { // update highlighter's text + Document document = PsiDocumentManager.getInstance(myProject).getDocument(psiFile); + Highlighter highlighter = myFile2Highlighter.get(file); + highlighter.setText(document.getCharsSequence()); + } + } + i.remove(); + } + LOG.assertTrue(myDirtyFileSet.size() == 0); + // Now myDirtyFileSet should be empty + } + + protected boolean isAutoExpandNode(NodeDescriptor descriptor) { + return getTodoTreeStructure().isAutoExpandNode(descriptor); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return getTodoTreeStructure().needLoadingNode(nodeDescriptor); + } + + /** + * @return first SmartTodoItemPointer that is the children (in depth) of the specified element. + * If element itself is a TodoItem then the method returns the element. + */ + SmartTodoItemPointer getFirstPointerForElement(Object element) { + if (element instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)element; + } + else { + Object[] children = myTreeStructure.getChildElements(element); + if (children.length == 0) { + return null; + } + Object firstChild = children[0]; + if (firstChild instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)firstChild; + } + else { + return getFirstPointerForElement(firstChild); + } + } + } + + /** + * @return last SmartTodoItemPointer that is the children (in depth) of the specified element. + * If element itself is a TodoItem then the method returns the element. + */ + SmartTodoItemPointer getLastPointerForElement(Object element) { + if (element instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)element; + } + else { + Object[] children = myTreeStructure.getChildElements(element); + if (children.length == 0) { + return null; + } + Object firstChild = children[children.length - 1]; + if (firstChild instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)firstChild; + } + else { + return getLastPointerForElement(firstChild); + } + } + } + + protected final void updateTree(boolean later) { + if (myUpdatable) { + myUpdater.addSubtreeToUpdate(myRootNode); + if (!later) { + myUpdater.performUpdate(); + } + } + } + + PsiFile[] getFilesForNode(DefaultMutableTreeNode node) { + Object obj = node.getUserObject(); + if ( + (obj instanceof ToDoRootNode) || + (obj instanceof SummaryNode) || + (obj instanceof TodoDirNode) + ) { + HashSet files = new HashSet(); + NodeDescriptor descriptor = (NodeDescriptor)obj; + collectFilesForElement(descriptor.getElement(), files); + return files.toArray(new PsiFile[files.size()]); + } + else if (obj instanceof TodoFileNode) { + PsiFile psiFile = ((TodoFileNode)obj).getValue(); + return new PsiFile[]{psiFile}; + } + else if (obj instanceof TodoItemNode) { + SmartTodoItemPointer pointer = (((TodoItemNode)obj).getValue()); + return new PsiFile[]{pointer.getTodoItem().getFile()}; + } + else { + throw new IllegalArgumentException(String.valueOf(obj)); + } + } + + private void collectFilesForElement(Object element, HashSet files) { + Object[] children = myTreeStructure.getChildElements(element); + for (int i = 0; i < children.length; i++) { + Object child = children[i]; + if (child instanceof TodoItem) { + continue; + } + else if (child instanceof PsiFile) { + files.add((PsiFile)child); + } + else { + collectFilesForElement(child, files); + } + } + } + + void collapseAll() { + int row = myTree.getRowCount() - 1; + while (row > 0) { + myTree.collapseRow(row); + row--; + } + } + + void expandAll() { + for (int i = 0; i < myTree.getRowCount(); i++) { + myTree.expandRow(i); + } + } + + /** + * Sets whether packages are shown or not. + */ + void setShowPackages(boolean state) { + getTodoTreeStructure().setShownPackages(state); + ArrayList pathsToExpand = new ArrayList(); + ArrayList pathsToSelect = new ArrayList(); + TreeBuilderUtil.storePaths(this, myRootNode, pathsToExpand, pathsToSelect, true); + myTree.clearSelection(); + getTodoTreeStructure().validateCache(); + updateTree(false); + TreeBuilderUtil.restorePaths(this, pathsToExpand, pathsToSelect, true); + } + + /** + * @param state if true then view is in "flatten packages" mode. + */ + void setFlattenPackages(boolean state) { + ArrayList pathsToExpand = new ArrayList(); + ArrayList pathsToSelect = new ArrayList(); + TreeBuilderUtil.storePaths(this, myRootNode, pathsToExpand, pathsToSelect, true); + myTree.clearSelection(); + TodoTreeStructure todoTreeStructure = getTodoTreeStructure(); + todoTreeStructure.setFlattenPackages(state); + todoTreeStructure.validateCache(); + updateTree(false); + TreeBuilderUtil.restorePaths(this, pathsToExpand, pathsToSelect, true); + } + + /** + * Sets new TodoFilter, rebuild whole the caches and immediately update the tree. + * + * @see com.intellij.ide.todo.TodoTreeStructure#setTodoFilter + */ + void setTodoFilter(TodoFilter filter) { + getTodoTreeStructure().setTodoFilter(filter); + rebuildCache(); + updateTree(false); + } + + /** + * @return next TodoItem for the passed pointer. Returns null + * if the pointer is the last todo item in the tree. + */ + SmartTodoItemPointer getNextPointer(SmartTodoItemPointer pointer) { + Object sibling = getNextSibling(pointer); + if (sibling == null) { + return null; + } + if (sibling instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)sibling; + } + else { + return getFirstPointerForElement(sibling); + } + } + + /** + * @return next sibling of the passed element. If there is no sibling then + * returns null. + */ + Object getNextSibling(Object obj) { + Object parent = myTreeStructure.getParentElement(obj); + if (parent == null) { + return null; + } + Object[] children = myTreeStructure.getChildElements(parent); + int idx = -1; + for (int i = 0; i < children.length; i++) { + if (obj.equals(children[i])) { + idx = i; + break; + } + } + if (idx == -1) { + return null; + } + if (idx < children.length - 1) { + return children[idx + 1]; + } + // passed object is the last in the list. In this case we have to return first child of the + // next parent's sibling. + return getNextSibling(parent); + } + + /** + * @return next SmartTodoItemPointer for the passed pointer. Returns null + * if the pointer is the last todo item in the tree. + */ + SmartTodoItemPointer getPreviousPointer(SmartTodoItemPointer pointer) { + Object sibling = getPreviousSibling(pointer); + if (sibling == null) { + return null; + } + if (sibling instanceof SmartTodoItemPointer) { + return (SmartTodoItemPointer)sibling; + } + else { + return getLastPointerForElement(sibling); + } + } + + /** + * @return previous sibling of the element of passed type. If there is no sibling then + * returns null. + */ + Object getPreviousSibling(Object obj) { + Object parent = myTreeStructure.getParentElement(obj); + if (parent == null) { + return null; + } + Object[] children = myTreeStructure.getChildElements(parent); + int idx = -1; + for (int i = 0; i < children.length; i++) { + if (obj.equals(children[i])) { + idx = i; + + break; + } + } + if (idx == -1) { + return null; + } + if (idx > 0) { + return children[idx - 1]; + } + // passed object is the first in the list. In this case we have to return last child of the + // previous parent's sibling. + return getPreviousSibling(parent); + } + + /** + * @return Highlighter for the specified psiFile. Highlighters are + * lazy created and initialized. + */ + public Highlighter getHighlighter(PsiFile psiFile, Document document) { + VirtualFile file = psiFile.getVirtualFile(); + if (myFile2Highlighter.containsKey(file)) { + return myFile2Highlighter.get(file); + } + else { + Highlighter highlighter = HighlighterFactory.createHighlighter(UsageTreeColorsScheme.getInstance().getScheme(), file.getName(), myProject); + highlighter.setText(document.getCharsSequence()); + myFile2Highlighter.put(file, highlighter); + return highlighter; + } + } + + private static final class MyComparator implements Comparator { + public static final Comparator ourInstance = new MyComparator(); + + private MyComparator() {} + + public int compare(NodeDescriptor descriptor1, NodeDescriptor descriptor2) { + int weight1 = getWeight(descriptor1); + int weight2 = getWeight(descriptor2); + if (weight1 != weight2) { + return weight1 - weight2; + } + else { + return descriptor1.getIndex() - descriptor2.getIndex(); + } + } + + private int getWeight(NodeDescriptor descriptor) { + if (descriptor instanceof SummaryNode) { + return 0; + } + else if (descriptor instanceof TodoDirNode) { + return 1; + } + else if (descriptor instanceof TodoFileNode) { + return 2; + } + else if (descriptor instanceof TodoItemNode) { + return 3; + } + else { + throw new IllegalArgumentException(descriptor.getClass().getName()); + } + } + } + + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void childAdded(PsiTreeChangeEvent e) { + // If local modification + if (e.getFile() != null) { + markFileAsDirty(e.getFile()); + updateTree(true); + return; + } + // If added element if PsiFile and it doesn't contains TODOs, then do nothing + PsiElement child = e.getChild(); + if (!(child instanceof PsiFile)) { + return; + } + PsiFile psiFile = (PsiFile)e.getChild(); + markFileAsDirty(psiFile); + updateTree(true); + } + + public void beforeChildRemoval(PsiTreeChangeEvent e) { + // If local midification + if (e.getFile() != null) { + markFileAsDirty(e.getFile()); + updateTree(true); + return; + } + // + PsiElement child = e.getChild(); + if (child instanceof PsiFile) { // file will be removed + PsiFile psiFile = (PsiFile)child; + markFileAsDirty(psiFile); + updateTree(true); + } + else if (child instanceof PsiDirectory) { // directory will be removed + PsiDirectory psiDirectory = (PsiDirectory)child; + for (Iterator i = getAllFiles(); i.hasNext();) { + PsiFile psiFile = (PsiFile)i.next(); + if (psiFile == null) { // skip invalid PSI files + continue; + } + if (PsiTreeUtil.isAncestor(psiDirectory, psiFile, true)) { + markFileAsDirty(psiFile); + } + } + updateTree(true); + } + } + + public void childMoved(PsiTreeChangeEvent e) { + if (e.getFile() != null) { // local change + markFileAsDirty(e.getFile()); + updateTree(true); + return; + } + else if (e.getChild() instanceof PsiFile) { // file was moved + PsiFile psiFile = (PsiFile)e.getChild(); + if (!canContainTodoItems(psiFile)) { // moved file doesn't contain TODOs + return; + } + markFileAsDirty(psiFile); + updateTree(true); + } + else if (e.getChild() instanceof PsiDirectory) { // directory was moved. mark all its files as dirty. + PsiDirectory psiDirectory = (PsiDirectory)e.getChild(); + boolean shouldUpdate = false; + for (Iterator i = getAllFiles(); i.hasNext();) { + PsiFile psiFile = (PsiFile)i.next(); + if (psiFile == null) { // skip invalid PSI files + continue; + } + if (PsiTreeUtil.isAncestor(psiDirectory, psiFile, true)) { + markFileAsDirty(psiFile); + shouldUpdate = true; + } + } + if (shouldUpdate) { + updateTree(true); + } + } + } + + public void childrenChanged(PsiTreeChangeEvent e) { + markFileAsDirty(e.getFile()); + updateTree(true); + } + + public void propertyChanged(PsiTreeChangeEvent e) { + String propertyName = e.getPropertyName(); + if (propertyName.equals(PsiTreeChangeEvent.PROP_ROOTS)) { // rebuild all tree when source roots were changed + myUpdater.runBeforeUpdate( + new Runnable() { + public void run() { + rebuildCache(); + } + } + ); + updateTree(true); + } + else if (PsiTreeChangeEvent.PROP_WRITABLE.equals(propertyName)) { + PsiFile psiFile = (PsiFile)e.getElement(); + if (!canContainTodoItems(psiFile)) { // don't do anything if file cannot contain todos + return; + } + updateTree(true); + } + else if (PsiTreeChangeEvent.PROP_FILE_NAME.equals(propertyName)) { + PsiFile psiFile = (PsiFile)e.getElement(); + if (!canContainTodoItems(psiFile)) { + return; + } + updateTree(true); + } + else if (PsiTreeChangeEvent.PROP_DIRECTORY_NAME.equals(propertyName)) { + PsiDirectory psiDirectory = (PsiDirectory)e.getElement(); + Iterator iterator = getFiles(psiDirectory); + if (iterator.hasNext()) { + updateTree(true); + } + } + } + } + + private final class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { + updateTree(true); + } + + public void fileStatusChanged(VirtualFile virtualFile) { + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(virtualFile); + if (psiFile != null && canContainTodoItems(psiFile)) { + updateTree(true); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeStructure.java new file mode 100644 index 00000000000..05d03f52c9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoTreeStructure.java @@ -0,0 +1,230 @@ +package com.intellij.ide.todo; + +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; +import com.intellij.ide.todo.nodes.SummaryNode; +import com.intellij.ide.todo.nodes.TodoItemNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeStructureBase; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.TodoPattern; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Vladimir Kondratyev + */ +public abstract class TodoTreeStructure extends AbstractTreeStructureBase implements ToDoSettings{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.todo.TodoTreeStructure"); + + protected TodoTreeBuilder myBuilder; + protected AbstractTreeNode myRootElement; + protected final ToDoSummary mySummaryElement; + + protected boolean myFlattenPackages; + protected boolean myArePackagesShown; + + /** + * Don't use this maps directly! + */ + private final HashMap myElement2Children; + private final HashMap myElement2Parent; + + protected final PsiManager myPsiManager; + protected final PsiSearchHelper mySearchHelper; + /** + * Current TodoFilter. If no filter is set then this field is null. + */ + protected TodoFilter myTodoFilter; + private static final ArrayList EMPTY_TREE_STRUCTURE_PROVIDERS = new ArrayList(); + + public TodoTreeStructure(Project project){ + super(project); + myArePackagesShown=true; + mySummaryElement=new ToDoSummary(this); + myElement2Children=new HashMap(); + myElement2Parent=new HashMap(); + myPsiManager=PsiManager.getInstance(project); + mySearchHelper=myPsiManager.getSearchHelper(); + } + + final void setTreeBuilder(TodoTreeBuilder builder){ + myBuilder=builder; + myRootElement=createRootElement(); + } + + protected abstract AbstractTreeNode createRootElement(); + + public abstract boolean accept(PsiFile psiFile); + + /** + * Validate whole the cache + */ + protected void validateCache(){ + myElement2Children.clear(); + myElement2Parent.clear(); + } + + public final boolean isPackagesShown(){ + return myArePackagesShown; + } + + final void setShownPackages(boolean state){ + myArePackagesShown=state; + } + + public final boolean areFlattenPackages(){ + return myFlattenPackages; + } + + final void setFlattenPackages(boolean state){ + myFlattenPackages=state; + } + + /** + * Sets new TodoFilter. null is acceptable value. It means + * that there is no any filtration of TodoItem>/code>s. + */ + final void setTodoFilter(TodoFilter todoFilter){ + myTodoFilter=todoFilter; + } + + /** + * @return first element that can be selected in the tree. The method can returns null. + */ + abstract Object getFirstSelectableElement(); + + /** + * @return number of PsiFiles located under specified element in the tree. + */ + public final int getFileCount(Object element){ + LOG.assertTrue(element!=null); + int count=0; + if(element instanceof PsiFile){ + count=1; + }else if(element instanceof PsiDirectory){ + Iterator iterator = myBuilder.getFiles((PsiDirectory)element); + while(iterator.hasNext()){ + PsiFile psiFile = iterator.next(); + if(accept(psiFile)){ + count++; + } + } + }else if(element instanceof ToDoSummary){ + for(Iterator i=myBuilder.getAllFiles();i.hasNext();){ + PsiFile psiFile=(PsiFile)i.next(); + if(psiFile==null){ // skip invalid PSI files + continue; + } + if(accept(psiFile)){ + count++; + } + } + }else{ + throw new IllegalArgumentException("unknown element: "+element); + } + return count; + } + + /** + * @return number of TodoItems located under specified element in the tree. + */ + public final int getTodoItemCount(Object element){ + int count=0; + if(element instanceof PsiFile){ + PsiFile psiFile=(PsiFile)element; + if(myTodoFilter!=null){ + for(Iterator i=myTodoFilter.iterator();i.hasNext();){ + TodoPattern pattern=(TodoPattern)i.next(); + count+=mySearchHelper.getTodoItemsCount(psiFile,pattern); + } + }else{ + count=mySearchHelper.getTodoItemsCount(psiFile); + } + }else if(element instanceof PsiDirectory){ + Iterator iterator = myBuilder.getFiles((PsiDirectory)element); + while(iterator.hasNext()){ + PsiFile psiFile = iterator.next(); + count+=getTodoItemCount(psiFile); + } + }else if(element instanceof ToDoSummary){ + for(Iterator i=myBuilder.getAllFiles();i.hasNext();){ + count+=getTodoItemCount(i.next()); + } + }else{ + throw new IllegalArgumentException("unknown element: "+element); + } + return count; + } + + boolean isAutoExpandNode(NodeDescriptor descriptor){ + Object element=descriptor.getElement(); + if(element==getRootElement()){ + return true; + }else if(element==mySummaryElement){ + return true; + }else{ + return false; + } + } + + boolean needLoadingNode(NodeDescriptor descriptor){ + Object element=descriptor.getElement(); + if(element == getRootElement()){ + return true; + }else if(element instanceof SummaryNode){ + return true; + }else if(element instanceof PsiDirectoryNode){ + return true; + }else if(element instanceof PsiFileNode){ + return mySearchHelper.getTodoItemsCount(((PsiFileNode)element).getValue())>0; + }else if(element instanceof TodoItemNode){ + return false; + }else{ + throw new IllegalArgumentException(element.getClass().getName()); + } + } + + public final void commit() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + } + + public boolean hasSomethingToCommit() { + return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments(); + } + + public final Object getRootElement(){ + return myRootElement; + } + + public ToDoSettings getSettings() { + return this; + } + + public boolean getIsFlattenPackages() { + return myFlattenPackages; + } + + public PsiSearchHelper getSearchHelper() { + return mySearchHelper; + } + + public TodoFilter getTodoFilter() { + return myTodoFilter; + } + + public List getProviders() { + return EMPTY_TREE_STRUCTURE_PROVIDERS; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoView.java new file mode 100644 index 00000000000..9b9d99e732b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/TodoView.java @@ -0,0 +1,275 @@ +package com.intellij.ide.todo; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.TabbedPaneContentUI; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +public class TodoView implements ProjectComponent,JDOMExternalizable{ + private final Project myProject; + private MyPropertyChangeListener myPropertyChangeListener; + private MyFileTypeListener myFileTypeListener; + + private ContentManager myContentManager; + private CurrentFileTodosPanel myCurrentFileTodos; + private TodoPanel myAllTodos; + + private int mySelectedIndex; + private TodoPanelSettings myCurrentPanelSettings; + private TodoPanelSettings myAllPanelSettings; + + /* Invoked by reflection */ + TodoView(Project project){ + myProject=project; + myCurrentPanelSettings=new TodoPanelSettings(); + myAllPanelSettings=new TodoPanelSettings(); + } + + public void readExternal(Element element) throws InvalidDataException{ + mySelectedIndex=0; + try{ + mySelectedIndex=Integer.parseInt(element.getAttributeValue("selected-index")); + }catch(NumberFormatException ignored){} + + for(Iterator i=element.getChildren().iterator();i.hasNext();){ + Element child=(Element)i.next(); + if("todo-panel".equals(child.getName())){ + String id=child.getAttributeValue("id"); + if("selected-file".equals(id)){ + myCurrentPanelSettings.readExternal(child); + }else if("all".equals(id)){ + myAllPanelSettings.readExternal(child); + }else{ + throw new IllegalArgumentException("unknown id: "+id); + } + } + } + } + + public void writeExternal(Element element) throws WriteExternalException{ + if(myContentManager!=null){ // all panel were constructed + Content content=myContentManager.getSelectedContent(); + element.setAttribute("selected-index",Integer.toString(myContentManager.getIndexOfContent(content))); + } + + Element selectedFileElement=new Element("todo-panel"); + selectedFileElement.setAttribute("id","selected-file"); + myCurrentPanelSettings.writeExternal(selectedFileElement); + element.addContent(selectedFileElement); + + Element allElement=new Element("todo-panel"); + allElement.setAttribute("id","all"); + myAllPanelSettings.writeExternal(allElement); + element.addContent(allElement); + } + + public void disposeComponent(){} + + public String getComponentName(){ + return "TodoView"; + } + + public void initComponent(){} + + public void projectClosed(){ + TodoConfiguration.getInstance().removePropertyChangeListener(myPropertyChangeListener); + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + if(myAllTodos!=null){ // Panels can be null if project was closed before starup activities run + myCurrentFileTodos.dispose(); + myAllTodos.dispose(); + ToolWindowManager toolWindowManager=ToolWindowManager.getInstance(myProject); + toolWindowManager.unregisterToolWindow(ToolWindowId.TODO_VIEW); + } + } + + public void projectOpened(){ + myPropertyChangeListener=new MyPropertyChangeListener(); + TodoConfiguration.getInstance().addPropertyChangeListener(myPropertyChangeListener); + + myFileTypeListener=new MyFileTypeListener(); + FileTypeManager.getInstance().addFileTypeListener(myFileTypeListener); + + StartupManager startupManager=StartupManager.getInstance(myProject); + // it causes building caches for TODOs + startupManager.registerPostStartupActivity( + new Runnable(){ + public void run(){ + // Create panels + + Content allTodosContent=PeerFactory.getInstance().getContentFactory().createContent(null,"Project",false); + myAllTodos=new TodoPanel(myProject,myAllPanelSettings,false,allTodosContent){ + protected TodoTreeBuilder createTreeBuilder(JTree tree,DefaultTreeModel treeModel,Project project){ + AllTodosTreeBuilder builder=new AllTodosTreeBuilder(tree,treeModel,project); + builder.init(); + return builder; + } + }; + allTodosContent.setComponent(myAllTodos); + + Content currentFileTodosContent=PeerFactory.getInstance().getContentFactory().createContent(null,"Current File",false); + myCurrentFileTodos=new CurrentFileTodosPanel(myProject,myCurrentPanelSettings,currentFileTodosContent){ + protected TodoTreeBuilder createTreeBuilder(JTree tree,DefaultTreeModel treeModel,Project project){ + CurrentFileTodosTreeBuilder builder=new CurrentFileTodosTreeBuilder(tree,treeModel,project); + builder.init(); + return builder; + } + }; + currentFileTodosContent.setComponent(myCurrentFileTodos); + + // Register tool window + + myContentManager=PeerFactory.getInstance().getContentFactory().createContentManager(new TabbedPaneContentUI(),false, myProject); + myContentManager.addContent(allTodosContent); + myContentManager.addContent(currentFileTodosContent); + Content content=myContentManager.getContent(mySelectedIndex); + myContentManager.setSelectedContent(content); + ToolWindowManager toolWindowManager=ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow=toolWindowManager.registerToolWindow( + ToolWindowId.TODO_VIEW, + myContentManager.getComponent(), + ToolWindowAnchor.BOTTOM + ); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowTodo.png")); + new TodoContentManagerWatcher(toolWindow,myContentManager); + } + } + ); + } + + + + private final class MyPropertyChangeListener implements PropertyChangeListener{ + /** + * If patterns have been changed the filtes can be touched also. But we have to update + * filters after caches are rebuilded. Therefore if myRebuildInProgress + * is true then it is deferred update of filters. + */ + private boolean myRebuildInProgress; + + public void propertyChange(PropertyChangeEvent e){ + if (TodoConfiguration.PROP_TODO_PATTERNS.equals(e.getPropertyName())) { + myRebuildInProgress = true; + // this invokeLater guaranties that this code will be invoked after + // PSI gets the same event. + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + // [vova] It's very important to pass null as project. Each TODO view shows own progress + // window. It causes frame switching. + final ProgressWindow progressWindow = new ProgressWindow(false, null); + progressWindow.setTitle("Looking for TODOs..."); + progressWindow.setText("Please wait..."); + final Runnable process = new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + PsiSearchHelper searchHelper = PsiManager.getInstance(myProject).getSearchHelper(); + searchHelper.findFilesWithTodoItems(); + } + }); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + updateFilters(); + myRebuildInProgress = false; + } + }, ModalityState.NON_MMODAL); + } + }; + Thread thread = new Thread(new Runnable() { + public void run() { + ProgressManager.getInstance().runProcess(process, progressWindow); + } + }, "Todo finder"); + thread.start(); + } + }); + } + else if (TodoConfiguration.PROP_TODO_FILTERS.equals(e.getPropertyName())) { + if (!myRebuildInProgress) { + updateFilters(); + } + } + } + + private void updateFilters(){ + myCurrentFileTodos.updateTodoFilter(); + myAllTodos.updateTodoFilter(); + } + } + + private final class MyFileTypeListener implements FileTypeListener{ + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(FileTypeEvent e){ + // this invokeLater guaranties that this code will be invoked after + // PSI gets the same event. + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run(){ + // [vova] It's very important to pass null as project. Each TODO view shows own progress + // window. It causes frame switching. + final ProgressWindow progressWindow=new ProgressWindow(false,null); + progressWindow.setTitle("Looking for TODOs..."); + progressWindow.setText("Please wait..."); + final Runnable process=new Runnable(){ + public void run(){ + if (myAllTodos == null) return; + + ApplicationManager.getApplication().runReadAction( + new Runnable(){ + public void run(){ + myAllTodos.rebuildCache(); + myCurrentFileTodos.rebuildCache(); + } + } + ); + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run(){ + myAllTodos.updateTree(); + myCurrentFileTodos.updateTree(); + } + }, ModalityState.NON_MMODAL); + } + }; + Thread thread=new Thread( + new Runnable(){ + public void run(){ + ProgressManager.getInstance().runProcess(process,progressWindow); + } + }, "Todo finder" + ); + thread.start(); + } + }); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FilterDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FilterDialog.java new file mode 100644 index 00000000000..e2662da60fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FilterDialog.java @@ -0,0 +1,199 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.ide.todo.TodoFilter; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.search.TodoPattern; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.util.List; + +/** + * @author Vladimir Kondratyev + */ +class FilterDialog extends DialogWrapper { + private TodoFilter myFilter; + private int myFilterIndex; + private List myPatterns; + private List myFilters; + private MyModel myModel; + + private JTextField myNameField; + private Table myTable; + + /** + * @param parent parent component. + * @param filter filter to be edited. + * @param filterIndex index of filter in the filters. This parameter is + * needed to not compare filter with itself when validating. + * @param filters all already configured filters. This parameter is used to + * @param patterns all patterns available in this filter. + */ + public FilterDialog(Component parent, + TodoFilter filter, + int filterIndex, + List filters, + List patterns) { + super(parent, true); + myFilter = filter; + myFilterIndex = filterIndex; + myPatterns = patterns; + myFilters = filters; + myNameField = new JTextField(filter.getName()); + myModel = new MyModel(); + myTable = new Table(myModel); + init(); + } + + protected void doOKAction() { + + // Validate filter name + + myFilter.setName(myNameField.getText().trim()); + if (myFilter.getName().length() == 0) { + Messages.showMessageDialog(myTable, + "Filter name should be specified", + "Error", + Messages.getErrorIcon()); + return; + } + for (int i = 0; i < myFilters.size(); i++) { + TodoFilter filter = myFilters.get(i); + if (myFilterIndex != i && myFilter.getName().equals(filter.getName())) { + Messages.showMessageDialog(myTable, + "Filter with the same name already exists", + "Error", + Messages.getErrorIcon()); + return; + } + } + + // Validate that at least one pettern is selected + + if (myFilter.isEmpty()) { + Messages.showMessageDialog(myTable, + "Filter should contain at least one pattern", + "Error", + Messages.getErrorIcon()); + return; + } + + super.doOKAction(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("preferences.externalToolsFilters"); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + JLabel nameLabel = new JLabel("Name:"); + panel.add(nameLabel, + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 10), 0, 0)); + panel.add(myNameField, + new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0)); + + JPanel patternsPanel = new JPanel(new GridBagLayout()); + Border border = IdeBorderFactory.createTitledBorder("Patterns"); + patternsPanel.setBorder(border); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + scrollPane.setPreferredSize(new Dimension(550, myTable.getRowHeight() * 10)); + patternsPanel.add(scrollPane, + new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + // Column "Available" + + int width = (new JCheckBox()).getPreferredSize().width; + TableColumn availableColumn = myTable.getColumnModel().getColumn(0); + availableColumn.setPreferredWidth(width); + availableColumn.setMaxWidth(width); + availableColumn.setMinWidth(width); + + // + + panel.add(patternsPanel, + new GridBagConstraints(0, 1, 2, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + return panel; + } + + private final class MyModel extends AbstractTableModel { + private final String[] ourColumnNames = new String[]{" ", "Pattern", }; + private final Class[] ourColumnClasses = new Class[]{Boolean.class, String.class}; + + public String getColumnName(int column) { + return ourColumnNames[column]; + } + + public Class getColumnClass(int column) { + return ourColumnClasses[column]; + } + + public int getColumnCount() { + return 2; + } + + public int getRowCount() { + return myPatterns.size(); + } + + public Object getValueAt(int row, int column) { + TodoPattern pattern = myPatterns.get(row); + switch (column) { + case 0: + { // "Available" column + return myFilter.contains(pattern) ? Boolean.TRUE : Boolean.FALSE; + } + case 1: + { // "Pattern" column + return pattern.getPatternString(); + } + default: + { + throw new IllegalArgumentException(); + } + } + } + + public void setValueAt(Object value, int row, int column) { + switch (column) { + case 0: + { + TodoPattern pattern = myPatterns.get(row); + if (((Boolean)value).booleanValue()) { + myFilter.addTodoPattern(pattern); + } + else { + myFilter.removeTodoPattern(pattern); + } + break; + } + default: + { + throw new IllegalArgumentException(); + } + } + } + + public boolean isCellEditable(int row, int column) { + return column == 0; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FiltersTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FiltersTableModel.java new file mode 100644 index 00000000000..d9666a74bf3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/FiltersTableModel.java @@ -0,0 +1,62 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.ide.todo.TodoFilter; +import com.intellij.psi.search.TodoPattern; +import com.intellij.util.ui.ItemRemovable; + +import javax.swing.table.AbstractTableModel; +import java.util.Iterator; +import java.util.List; + +final class FiltersTableModel extends AbstractTableModel implements ItemRemovable{ + private final String[] ourColumnNames=new String[]{"Name","Patterns"}; + private final Class[] ourColumnClasses=new Class[]{String.class,String.class}; + + private List myFilters; + + public FiltersTableModel(List filters){ + myFilters=filters; + } + + public String getColumnName(int column){ + return ourColumnNames[column]; + } + + public Class getColumnClass(int column){ + return ourColumnClasses[column]; + } + + public int getColumnCount(){ + return 2; + } + + public int getRowCount(){ + return myFilters.size(); + } + + public Object getValueAt(int row,int column){ + TodoFilter filter=myFilters.get(row); + switch(column){ + case 0:{ // "Name" column + return filter.getName(); + }case 1:{ + StringBuffer sb=new StringBuffer(); + for(Iterator i=filter.iterator();i.hasNext();){ + TodoPattern pattern=(TodoPattern)i.next(); + sb.append(pattern.getPatternString()); + if(i.hasNext()){ + sb.append(" | "); + } + } + return sb.toString(); + }default:{ + throw new IllegalArgumentException(); + } + } + } + + public void removeRow(int index){ + myFilters.remove(index); + fireTableRowsDeleted(index,index); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternDialog.java new file mode 100644 index 00000000000..2b05f0badd1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternDialog.java @@ -0,0 +1,112 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.application.options.colors.ColorAndFontDescription; +import com.intellij.application.options.colors.ColorAndFontDescriptionPanel; +import com.intellij.application.options.colors.TextAttributesDescription; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.search.TodoAttributes; +import com.intellij.psi.search.TodoPattern; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +class PatternDialog extends DialogWrapper{ + private TodoPattern myPattern; + + private JComboBox myIconComboBox; + private JCheckBox myCaseSensitiveCheckBox; + private JTextField myPatternStringField; + private ColorAndFontDescriptionPanel myColorAndFontDescriptionPanel; + private ColorAndFontDescription myColorAndFontDescription; + + public PatternDialog(Component parent,TodoPattern pattern){ + super(parent,true); + myPattern=pattern; + myIconComboBox=new JComboBox( + new Icon[]{TodoAttributes.DEFAULT_ICON,TodoAttributes.QUESTION_ICON,TodoAttributes.IMPORTANT_ICON} + ); + myIconComboBox.setSelectedItem(pattern.getAttributes().getIcon()); + myIconComboBox.setRenderer(new TodoTypeListCellRenderer()); + myCaseSensitiveCheckBox=new JCheckBox("Case Sensitive",pattern.isCaseSensitive()); + myPatternStringField=new JTextField(pattern.getPatternString()); + + myColorAndFontDescriptionPanel = new ColorAndFontDescriptionPanel(); + + TextAttributes attributes = myPattern.getAttributes().getTextAttributes(); + + myColorAndFontDescription = new TextAttributesDescription(null, null, attributes, null, EditorColorsManager.getInstance().getGlobalScheme()) { + public void apply(EditorColorsScheme scheme) { + + } + + public boolean isErrorStripeEnabled() { + return true; + } + }; + + myColorAndFontDescriptionPanel.reset(myColorAndFontDescription); + + init(); + } + + public JComponent getPreferredFocusedComponent(){ + return myPatternStringField; + } + + protected void doOKAction(){ + myPattern.setPatternString(myPatternStringField.getText().trim()); + myPattern.setCaseSensitive(myCaseSensitiveCheckBox.isSelected()); + myPattern.getAttributes().setIcon((Icon)myIconComboBox.getSelectedItem()); + + myColorAndFontDescriptionPanel.apply(myColorAndFontDescription, null); + super.doOKAction(); + } + + protected JComponent createCenterPanel(){ + JPanel panel=new JPanel(new GridBagLayout()); + + GridBagConstraints gb = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,5,10),0,0); + + JLabel patternLabel=new JLabel("Pattern:"); + panel.add(patternLabel, gb); + Dimension oldPreferredSize=myPatternStringField.getPreferredSize(); + myPatternStringField.setPreferredSize(new Dimension(300,oldPreferredSize.height)); + gb.gridx = 1; + gb.gridwidth = GridBagConstraints.REMAINDER; + gb.weightx = 1; + panel.add(myPatternStringField,gb); + + JLabel iconLabel=new JLabel("Icon:"); + gb.gridy++; + gb.gridx = 0; + gb.gridwidth = 1; + gb.weightx = 0; + panel.add(iconLabel, gb); + + gb.gridx = 1; + gb.fill = GridBagConstraints.NONE; + gb.gridwidth = GridBagConstraints.REMAINDER; + gb.weightx = 0; + panel.add(myIconComboBox, gb); + + gb.gridy++; + gb.gridx = 0; + gb.fill = GridBagConstraints.HORIZONTAL; + gb.gridwidth = GridBagConstraints.REMAINDER; + gb.weightx = 1; + panel.add(myCaseSensitiveCheckBox, gb); + + gb.gridy++; + gb.gridx = 0; + gb.gridwidth = GridBagConstraints.REMAINDER; + gb.weightx = 1; + panel.add(myColorAndFontDescriptionPanel, gb); + return panel; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternsTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternsTableModel.java new file mode 100644 index 00000000000..8ca1a00bd5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/PatternsTableModel.java @@ -0,0 +1,73 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.psi.search.TodoPattern; +import com.intellij.util.ui.ItemRemovable; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import java.util.List; + +final class PatternsTableModel extends AbstractTableModel implements ItemRemovable{ + private final String[] ourColumnNames=new String[]{"Icon","Case Sensitive","Pattern",}; + private final Class[] ourColumnClasses=new Class[]{Icon.class,Boolean.class,String.class}; + + private List myPatterns; + + public PatternsTableModel(List patterns){ + myPatterns=patterns; + } + + public String getColumnName(int column){ + return ourColumnNames[column]; + } + + public Class getColumnClass(int column){ + return ourColumnClasses[column]; + } + + public int getColumnCount(){ + return 3; + } + + public int getRowCount(){ + return myPatterns.size(); + } + + public Object getValueAt(int row,int column){ + TodoPattern pattern=myPatterns.get(row); + switch(column){ + case 0:{ // "Icon" column + return pattern.getAttributes().getIcon(); + }case 1:{ // "Case Sensitive" column + return pattern.isCaseSensitive()?Boolean.TRUE:Boolean.FALSE; + }case 2:{ // "Pattern" column + return pattern.getPatternString(); + }default:{ + throw new IllegalArgumentException(); + } + } + } + + public void setValueAt(Object value,int row,int column){ + TodoPattern pattern=myPatterns.get(row); + switch(column){ + case 0:{ + pattern.getAttributes().setIcon((Icon)value); + break; + }case 1:{ + pattern.setCaseSensitive(((Boolean)value).booleanValue()); + break; + }case 2:{ + pattern.setPatternString(((String)value).trim()); + break; + }default:{ + throw new IllegalArgumentException(); + } + } + } + + public void removeRow(int index){ + myPatterns.remove(index); + fireTableRowsDeleted(index,index); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoConfigurable.java new file mode 100644 index 00000000000..3162ad8e3f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoConfigurable.java @@ -0,0 +1,543 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.ide.todo.TodoConfiguration; +import com.intellij.ide.todo.TodoFilter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.search.TodoAttributes; +import com.intellij.psi.search.TodoPattern; +import com.intellij.ui.PanelWithButtons; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vladimir Kondratyev + */ +public class TodoConfigurable extends BaseConfigurable implements ApplicationComponent { + /* + * UI resources + */ + private JPanel myPanel; + private JTable myPatternsTable; + private JTable myFiltersTable; + private JButton myAddPatternButton; + private JButton myEditPatternButton; + private JButton myRemovePatternButton; + private JButton myAddFilterButton; + private JButton myEditFilterButton; + private JButton myRemoveFilterButton; + + private List myPatterns; + private PatternsTableModel myPatternsModel; + private List myFilters; + private FiltersTableModel myFiltersModel; + + /** + * Invoked by reflection + */ + private TodoConfigurable() { + myPatterns = new ArrayList(); + myFilters = new ArrayList(); + myFiltersModel = new FiltersTableModel(myFilters); + myPatternsModel = new PatternsTableModel(myPatterns); + } + + private boolean arePatternsModified() { + TodoConfiguration todoConfiguration = TodoConfiguration.getInstance(); + TodoPattern[] initialPatterns = todoConfiguration.getTodoPatterns(); + if (initialPatterns.length != myPatterns.size()) { + return true; + } + for (int i = 0; i < initialPatterns.length; i++) { + TodoPattern initialPattern = initialPatterns[i]; + if (!myPatterns.contains(initialPattern)) { + return true; + } + } + return false; + } + + private boolean areFiltersModified() { + TodoConfiguration todoConfiguration = TodoConfiguration.getInstance(); + TodoFilter[] initialFilters = todoConfiguration.getTodoFilters(); + if (initialFilters.length != myFilters.size()) { + return true; + } + for (int i = 0; i < initialFilters.length; i++) { + TodoFilter initialFilter = initialFilters[i]; + if (!myFilters.contains(initialFilter)) { + return true; + } + } + return false; + } + + public boolean isModified() { + // This method is always invoked before close configuration dialog or leave "ToDo" page. + // So it's a good place to commit all changes. + stopEditing(); + return arePatternsModified() || areFiltersModified(); + } + + public void apply() throws ConfigurationException { + stopEditing(); + if (arePatternsModified()) { + TodoPattern[] patterns = myPatterns.toArray(new TodoPattern[myPatterns.size()]); + TodoConfiguration.getInstance().setTodoPatterns(patterns); + } + if (areFiltersModified()) { + TodoFilter[] filters = myFilters.toArray(new TodoFilter[myFilters.size()]); + TodoConfiguration.getInstance().setTodoFilters(filters); + } + } + + public void disposeComponent() {} + + public String getComponentName() { + return "TodoConfigurable"; + } + + public void initComponent() {} + + public void disposeUIResources() { + myPanel = null; + myPatternsModel.removeTableModelListener(myPatternsTable); + myPatternsTable = null; + + myAddPatternButton = null; + myEditPatternButton = null; + myRemovePatternButton = null; + + myFiltersModel.removeTableModelListener(myFiltersTable); + myFiltersTable = null; + + myAddFilterButton = null; + myEditFilterButton = null; + myRemoveFilterButton = null; + } + + public JComponent createComponent() { + // Panel with patterns + + PanelWithButtons patternsPanel = new PanelWithButtons() { + { + initPanel(); + } + + protected String getLabelText() { + return "Patterns:"; + } + + protected JComponent createMainComponent() { + // JTable with TodoPaterns + + myPatternsTable = new Table(myPatternsModel); + myPatternsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // Column "Icon" + + JComboBox todoTypeCombo = new JComboBox( + new Icon[]{TodoAttributes.DEFAULT_ICON, TodoAttributes.QUESTION_ICON, TodoAttributes.IMPORTANT_ICON} + ); + todoTypeCombo.setRenderer(new TodoTypeListCellRenderer()); + TableColumn typeColumn = myPatternsTable.getColumnModel().getColumn(0); + DefaultCellEditor todoTypeEditor = new DefaultCellEditor(todoTypeCombo); + todoTypeEditor.setClickCountToStart(1); + typeColumn.setCellEditor(todoTypeEditor); + TodoTypeTableCellRenderer todoTypeRenderer = new TodoTypeTableCellRenderer(); + typeColumn.setCellRenderer(todoTypeRenderer); + + int width = myPatternsTable.getFontMetrics(myPatternsTable.getFont()).stringWidth( + myPatternsTable.getColumnName(0)) + + 10; + typeColumn.setPreferredWidth(width); + typeColumn.setMaxWidth(width); + typeColumn.setMinWidth(width); + + // Column "Case Sensitive" + + TableColumn todoCaseSensitiveColumn = myPatternsTable.getColumnModel().getColumn(1); + width = myPatternsTable.getFontMetrics(myPatternsTable.getFont()).stringWidth(myPatternsTable.getColumnName(1)) + + 10; + todoCaseSensitiveColumn.setPreferredWidth(width); + todoCaseSensitiveColumn.setMaxWidth(width); + todoCaseSensitiveColumn.setMinWidth(width); + + // Column "Pattern" + + TodoPatternTableCellRenderer todoPatternRenderer = new TodoPatternTableCellRenderer(myPatterns); + TableColumn patternColumn = myPatternsTable.getColumnModel().getColumn(2); + patternColumn.setCellRenderer(todoPatternRenderer); + + + ((DefaultCellEditor)myPatternsTable.getDefaultEditor(String.class)).setClickCountToStart(2); + JScrollPane myPatternsScroll = ScrollPaneFactory.createScrollPane(myPatternsTable); +// myPatternsScroll.getViewport().add(myPatternsTable); + myPatternsScroll.setPreferredSize(new Dimension(-1, myPatternsTable.getRowHeight() * 12)); + + return myPatternsScroll; + } + + protected JButton[] createButtons() { + myAddPatternButton = new JButton("Add..."); + myAddPatternButton.setMnemonic('A'); + myAddPatternButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopEditing(); + TodoPattern pattern = new TodoPattern(); + PatternDialog dialog = new PatternDialog(myPanel, pattern); + dialog.setTitle("Add Pattern"); + dialog.show(); + if (!dialog.isOK()) { + return; + } + myPatterns.add(pattern); + int index = myPatterns.size() - 1; + myPatternsModel.fireTableRowsInserted(index, index); + myPatternsTable.getSelectionModel().setSelectionInterval(index, index); + myPatternsTable.scrollRectToVisible(myPatternsTable.getCellRect(index, 0, true)); + } + } + ); + + myEditPatternButton = new JButton("Edit..."); + myEditPatternButton.setMnemonic('e'); + myEditPatternButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + editSelectedPattern(); + } + } + ); + + myRemovePatternButton = new JButton("Remove"); + myRemovePatternButton.setMnemonic('R'); + myRemovePatternButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopEditing(); + int selectedIndex = myPatternsTable.getSelectedRow(); + if (selectedIndex < 0 || selectedIndex >= myPatternsModel.getRowCount()) { + return; + } + TodoPattern patternToBeRemoved = myPatterns.get(selectedIndex); + TableUtil.removeSelectedItems(myPatternsTable); + for (int i = 0; i < myFilters.size(); i++) { + TodoFilter filter = myFilters.get(i); + if (filter.contains(patternToBeRemoved)) { + filter.removeTodoPattern(patternToBeRemoved); + myFiltersModel.fireTableRowsUpdated(i, i); + } + } + } + } + ); + + return new JButton[]{myAddPatternButton, myEditPatternButton, myRemovePatternButton}; + } + }; + + // double click in "Patterns" table should also start editing of selected pattern + + myPatternsTable.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + editSelectedPattern(); + } + } + } + ); + + // synchonizes selection in the "Patterns" table with buttons states + + myPatternsTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) { + return; + } + updateButtonsState(); + } + } + ); + + + // Panel with filters + + PanelWithButtons filtersPanel = new PanelWithButtons() { + { + initPanel(); + } + + protected String getLabelText() { + return "Filters:"; + } + + protected JComponent createMainComponent() { + myFiltersTable = new Table(myFiltersModel); + myFiltersTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + JScrollPane myFiltersScroll = ScrollPaneFactory.createScrollPane(myFiltersTable); +// myFiltersScroll.getViewport().add(myFiltersTable); + myFiltersScroll.setPreferredSize(new Dimension(-1, myPatternsTable.getRowHeight() * 12)); + + // Column "Name" + + TableColumn nameColumn = myFiltersTable.getColumnModel().getColumn(0); + int width = + myPatternsTable.getColumnModel().getColumn(0).getPreferredWidth()/*typeColumn*/ + + myPatternsTable.getColumnModel().getColumn(1).getPreferredWidth()/*todoCaseSensitiveColumn*/; + nameColumn.setPreferredWidth(width); + nameColumn.setMaxWidth(width); + nameColumn.setMinWidth(width); + nameColumn.setCellRenderer(new MyFilterNameTableCellRenderer()); + + return myFiltersScroll; + } + + protected JButton[] createButtons() { + myAddFilterButton = new JButton("Add..."); + myAddFilterButton.setMnemonic('d'); + myAddFilterButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopEditing(); + TodoFilter filter = new TodoFilter(); + FilterDialog dialog = new FilterDialog(myPanel, filter, -1, myFilters, myPatterns); + dialog.setTitle("Add Filter"); + dialog.show(); + int exitCode = dialog.getExitCode(); + if (DialogWrapper.OK_EXIT_CODE == exitCode) { + myFilters.add(filter); + int index = myFilters.size() - 1; + myFiltersModel.fireTableRowsInserted(index, index); + myFiltersTable.getSelectionModel().setSelectionInterval(index, index); + myFiltersTable.scrollRectToVisible(myFiltersTable.getCellRect(index, 0, true)); + } + } + } + ); + + myEditFilterButton = new JButton("Edit..."); + myEditFilterButton.setMnemonic('t'); + myEditFilterButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + editSelectedFilter(); + } + } + ); + + myRemoveFilterButton = new JButton("Remove"); + myRemoveFilterButton.setMnemonic('m'); + myRemoveFilterButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + stopEditing(); + TableUtil.removeSelectedItems(myFiltersTable); + } + } + ); + + return new JButton[]{myAddFilterButton, myEditFilterButton, myRemoveFilterButton}; + } + }; + + + // double click in "Filters" table should also start editing of selected filter + + myFiltersTable.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + editSelectedFilter(); + } + } + } + ); + + // synchonizes selection in the "Filters" table with buttons states + + myFiltersTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) { + return; + } + updateButtonsState(); + } + } + ); + + // + myPanel = new JPanel(new GridBagLayout()); + myPanel.add(patternsPanel, + new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, + new Insets(5, 2, 4, 2), 0, 0)); + myPanel.add(filtersPanel, + new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, + new Insets(5, 2, 4, 2), 0, 0)); + + myPanel.setPreferredSize( + new Dimension( + Math.max(700, myPanel.getPreferredSize().width), + myPanel.getPreferredSize().height + ) + ); + return myPanel; + } + + private void editSelectedPattern() { + stopEditing(); + int selectedIndex = myPatternsTable.getSelectedRow(); + if (selectedIndex < 0 || selectedIndex >= myPatternsModel.getRowCount()) { + return; + } + TodoPattern sourcePattern = myPatterns.get(selectedIndex); + TodoPattern pattern = sourcePattern.clone(); + PatternDialog dialog = new PatternDialog(TodoConfigurable.this.myPanel, pattern); + dialog.setTitle("Edit Pattern"); + dialog.show(); + if (!dialog.isOK()) { + return; + } + myPatterns.set(selectedIndex, pattern); + myPatternsModel.fireTableRowsUpdated(selectedIndex, selectedIndex); + myPatternsTable.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + // Update model with patterns + for (int i = 0; i < myFilters.size(); i++) { + TodoFilter filter = myFilters.get(i); + if (filter.contains(sourcePattern)) { + filter.removeTodoPattern(sourcePattern); + filter.addTodoPattern(pattern); + myFiltersModel.fireTableRowsUpdated(i, i); + } + } + } + + private void editSelectedFilter() { + stopEditing(); + int selectedIndex = myFiltersTable.getSelectedRow(); + if (selectedIndex < 0 || selectedIndex >= myFiltersModel.getRowCount()) { + return; + } + TodoFilter sourceFilter = myFilters.get(selectedIndex); + TodoFilter filter = sourceFilter.clone(); + FilterDialog dialog = new FilterDialog(TodoConfigurable.this.myPanel, filter, selectedIndex, myFilters, myPatterns); + dialog.setTitle("Edit Filter"); + dialog.show(); + int exitCode = dialog.getExitCode(); + if (DialogWrapper.OK_EXIT_CODE == exitCode) { + myFilters.set(selectedIndex, filter); + myFiltersModel.fireTableRowsUpdated(selectedIndex, selectedIndex); + myFiltersTable.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + } + } + + private void stopEditing() { + if (myPatternsTable.isEditing()) { + TableCellEditor editor = myPatternsTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + if (myFiltersTable.isEditing()) { + TableCellEditor editor = myFiltersTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + } + + private void updateButtonsState() { + int selectedPatternIndex = myPatternsTable.getSelectedRow(); + myEditPatternButton.setEnabled(selectedPatternIndex != -1); + myRemovePatternButton.setEnabled(selectedPatternIndex != -1); + + int selectedFilterIndex = myFiltersTable.getSelectedRow(); + myEditFilterButton.setEnabled(selectedFilterIndex != -1); + myRemoveFilterButton.setEnabled(selectedFilterIndex != -1); + } + + public String getDisplayName() { + return "TODO"; + } + + public String getHelpTopic() { + return "preferences.toDoOptions"; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableTodo.png"); + } + + public void reset() { + // Patterns + myPatterns.clear(); + TodoConfiguration todoConfiguration = TodoConfiguration.getInstance(); + TodoPattern[] patterns = todoConfiguration.getTodoPatterns(); + for (int i = 0; i < patterns.length; i++) { + myPatterns.add(patterns[i].clone()); + } + myPatternsModel.fireTableDataChanged(); + // Filters + myFilters.clear(); + TodoFilter[] filters = todoConfiguration.getTodoFilters(); + for (int i = 0; i < filters.length; i++) { + myFilters.add(filters[i].clone()); + } + myFiltersModel.fireTableDataChanged(); + // + updateButtonsState(); + } + + public static TodoConfigurable getInstance() { + return ApplicationManager.getApplication().getComponent(TodoConfigurable.class); + } + + private final class MyFilterNameTableCellRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + TodoFilter filter = myFilters.get(row); + if (isSelected) { + setForeground(UIManager.getColor("Table.selectionForeground")); + } + else { + if (filter.isEmpty()) { + setForeground(Color.RED); + } + else { + setForeground(UIManager.getColor("Table.foreground")); + } + } + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoPatternTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoPatternTableCellRenderer.java new file mode 100644 index 00000000000..a41a2549ddc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoPatternTableCellRenderer.java @@ -0,0 +1,39 @@ +package com.intellij.ide.todo.configurable; + +import com.intellij.psi.search.TodoPattern; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; +import java.util.*; +import java.util.List; + +final class TodoPatternTableCellRenderer extends DefaultTableCellRenderer{ + private List myPatterns; + + public TodoPatternTableCellRenderer(List patterns){ + myPatterns=patterns; + } + + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ){ + super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column); + TodoPattern pattern=myPatterns.get(row); + if(isSelected){ + setForeground(UIManager.getColor("Table.selectionForeground")); + }else{ + if(pattern.getPattern()==null){ + setForeground(Color.RED); + }else{ + setForeground(UIManager.getColor("Table.foreground")); + } + } + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeListCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeListCellRenderer.java new file mode 100644 index 00000000000..9e0fd130b17 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeListCellRenderer.java @@ -0,0 +1,23 @@ +package com.intellij.ide.todo.configurable; + +import javax.swing.*; +import java.awt.*; + +final class TodoTypeListCellRenderer extends DefaultListCellRenderer{ + public TodoTypeListCellRenderer(){ + setHorizontalAlignment(JLabel.CENTER); + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus + ){ + super.getListCellRendererComponent(list,null,index,isSelected,cellHasFocus); + Icon attributes=(Icon)value; + setIcon(attributes); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeTableCellRenderer.java new file mode 100644 index 00000000000..faa2f025394 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/configurable/TodoTypeTableCellRenderer.java @@ -0,0 +1,25 @@ +package com.intellij.ide.todo.configurable; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; + +final class TodoTypeTableCellRenderer extends DefaultTableCellRenderer{ + public TodoTypeTableCellRenderer(){ + setHorizontalAlignment(JLabel.CENTER); + } + + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ){ + super.getTableCellRendererComponent(table,null,isSelected,hasFocus,row,column); + Icon attributes=(Icon)value; + setIcon(attributes); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/BaseToDoNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/BaseToDoNode.java new file mode 100644 index 00000000000..27d5e485870 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/BaseToDoNode.java @@ -0,0 +1,27 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.todo.ToDoSettings; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.todo.TodoTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public abstract class BaseToDoNode extends AbstractTreeNode { + protected final ToDoSettings myToDoSettings; + protected final TodoTreeBuilder myBuilder; + + protected BaseToDoNode(Project project, Value value, TodoTreeBuilder builder) { + super(project, value); + myBuilder = builder; + myToDoSettings = myBuilder.getTodoTreeStructure(); + } + + public boolean contains(VirtualFile file) { + return false; + } + + protected TodoTreeStructure getTreeStructure() { + return myBuilder.getTodoTreeStructure(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SingleFileToDoNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SingleFileToDoNode.java new file mode 100644 index 00000000000..5d8cc30aed6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SingleFileToDoNode.java @@ -0,0 +1,31 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +public class SingleFileToDoNode extends BaseToDoNode{ + private final Set myFileNode = Collections.singleton(new TodoFileNode(getProject(), getValue(), myBuilder, true)); + + public SingleFileToDoNode(Project project, PsiFile value, TodoTreeBuilder builder) { + super(project, value, builder); + } + + public Collection getChildren() { + return new ArrayList(myFileNode); + } + + public void update(PresentationData presentation) { + } + + public Object getFileNode() { + return myFileNode; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SummaryNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SummaryNode.java new file mode 100644 index 00000000000..af05f987557 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/SummaryNode.java @@ -0,0 +1,81 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.todo.ToDoSummary; +import com.intellij.ide.todo.TodoFileDirComparator; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +public class SummaryNode extends BaseToDoNode { + + public SummaryNode(Project project, ToDoSummary value, TodoTreeBuilder builder) { + super(project, value, builder); + } + + public Collection getChildren() { + ArrayList children = new ArrayList(); + + if (myToDoSettings.getIsPackagesShown()) { + for (Iterator i = myBuilder.getAllFiles(); i.hasNext();) { + final PsiFile psiFile = (PsiFile)i.next(); + if (psiFile == null) { // skip invalid PSI files + continue; + } + final VirtualFile virtualFile = psiFile.getVirtualFile(); + final VirtualFile contentRoot = ProjectRootManager.getInstance(getProject()).getFileIndex().getContentRootForFile(virtualFile); + if (contentRoot != null) { + final PsiDirectory projectRoot = PsiManager.getInstance(getProject()).findDirectory(contentRoot); + TodoDirNode projectRootNode = new TodoDirNode(getProject(), projectRoot, myBuilder); + if (projectRoot != null && !children.contains(projectRootNode)) { + children.add(projectRootNode); + } + } + } + } + else { + for (Iterator i = myBuilder.getAllFiles(); i.hasNext();) { + final PsiFile psiFile = (PsiFile)i.next(); + if (psiFile == null) { // skip invalid PSI files + continue; + } + TodoFileNode fileNode = new TodoFileNode(getProject(), psiFile, myBuilder, false); + if (getTreeStructure().accept(psiFile) && !children.contains(fileNode)) { + children.add(fileNode); + } + } + } + Collections.sort(children, TodoFileDirComparator.ourInstance); + return children; + + } + + public void update(PresentationData presentation) { + StringBuffer sb = new StringBuffer(); + int todoItemCount = getValue().getTodoItemCount(); + sb.append("Found ").append(todoItemCount).append(" TODO item"); + if (todoItemCount != 1) { + sb.append('s'); + } + int fileCount = getValue().getFileCount(); + sb.append(" in ").append(fileCount).append(" file"); + if (fileCount != 1) { + sb.append('s'); + } + presentation.setPresentableText(sb.toString()); + } + + public String getTestPresentation() { + return "Summary"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/ToDoRootNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/ToDoRootNode.java new file mode 100644 index 00000000000..5c819cc29a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/ToDoRootNode.java @@ -0,0 +1,40 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.todo.ToDoSummary; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +public final class ToDoRootNode extends BaseToDoNode{ + private SummaryNode mySummaryNode; + + public ToDoRootNode(Project project, Object value, TodoTreeBuilder builder, ToDoSummary summary) { + super(project, value, builder); + mySummaryNode = new SummaryNode(getProject(), summary, myBuilder); + } + + public boolean contains(VirtualFile file) { + return false; + } + + public Collection getChildren() { + return new ArrayList(Collections.singleton(mySummaryNode)); + } + + public void update(PresentationData presentation) { + } + + public Object getSummaryNode() { + return mySummaryNode; + } + + public String getTestPresentation() { + return "Root"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoDirNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoDirNode.java new file mode 100644 index 00000000000..dde8fdda71a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoDirNode.java @@ -0,0 +1,184 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.projectView.impl.nodes.PackageUtil; +import com.intellij.ide.todo.HighlightedRegionProvider; +import com.intellij.ide.todo.TodoFileDirComparator; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.todo.TodoTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.HighlightedRegion; +import com.intellij.usageView.UsageTreeColors; +import com.intellij.usageView.UsageTreeColorsScheme; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +public final class TodoDirNode extends PsiDirectoryNode implements HighlightedRegionProvider { + private final ArrayList myHighlightedRegions; + private final TodoTreeBuilder myBuilder; + + + public TodoDirNode(Project project, + PsiDirectory directory, + TodoTreeBuilder builder) { + super(project, directory, ViewSettings.DEFAULT); + myBuilder = builder; + myHighlightedRegions = new ArrayList(2); + } + + public ArrayList getHighlightedRegions() { + return myHighlightedRegions; + } + + public void updateImpl(PresentationData data) { + super.updateImpl(data); + int fileCount = getStructure().getFileCount(getValue()); + if (getValue() == null || !getValue().isValid() || fileCount == 0) { + setValue(null); + return; + } + + PsiPackage aPackage = getValue().getPackage(); + String newName; + if (PackageUtil.isPackage(getValue())) { + if (getStructure().areFlattenPackages()) { + newName = aPackage.getQualifiedName(); + if (newName.length() == 0) { // default package + newName = getValue().getName(); + } + } + else { + newName = getValue().getName(); + } + } + else { + VirtualFile directory = getValue().getVirtualFile(); + boolean isProjectRoot = !ProjectRootManager.getInstance(getProject()).getFileIndex().isInContent(directory); + newName = isProjectRoot ? getValue().getVirtualFile().getPresentableUrl() : getValue().getName(); + } + + StringBuffer sb = new StringBuffer(newName); + int nameEndOffset = newName.length(); + int todoItemCount = getStructure().getTodoItemCount(getValue()); + sb.append(" ( ").append(todoItemCount).append(" item"); + if (todoItemCount > 1) { + sb.append('s'); + } + sb.append(" in " + fileCount).append(" file"); + if (fileCount > 1) { + sb.append('s'); + } + sb.append(" )"); + newName = sb.toString(); + + myHighlightedRegions.clear(); + + TextAttributes textAttributes = new TextAttributes(); + Color newColor = FileStatusManager.getInstance(getProject()).getStatus(getValue().getVirtualFile()).getColor(); + + if (((CopyPasteManagerEx)CopyPasteManager.getInstance()).isCutElement(getValue())) { + newColor = CopyPasteManager.CUT_COLOR; + } + textAttributes.setForegroundColor(newColor); + myHighlightedRegions.add(new HighlightedRegion(0, nameEndOffset, textAttributes)); + + EditorColorsScheme colorsScheme = UsageTreeColorsScheme.getInstance().getScheme(); + myHighlightedRegions.add( + new HighlightedRegion(nameEndOffset, newName.length(), colorsScheme.getAttributes(UsageTreeColors.NUMBER_OF_USAGES))); + data.setPresentableText(newName); + + + data.setPresentableText(newName); + } + + private TodoTreeStructure getStructure() { + return myBuilder.getTodoTreeStructure(); + } + + public Collection getChildrenImpl() { + ArrayList children = new ArrayList(); + final PsiDirectory psiDirectory = getValue(); + if (!getStructure().getIsFlattenPackages() || psiDirectory.getPackage() == null) { + final Iterator iterator = myBuilder.getFiles(psiDirectory); + while (iterator.hasNext()) { + final PsiFile psiFile = iterator.next(); + // Add files + final PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + TodoFileNode todoFileNode = new TodoFileNode(getProject(), psiFile, myBuilder, false); + if (psiDirectory.equals(containingDirectory) && !children.contains(todoFileNode)) { + children.add(todoFileNode); + continue; + } + // Add directories (find first ancestor directory that is in our psiDirectory) + PsiDirectory _dir = psiFile.getContainingDirectory(); + while (_dir != null) { + final PsiDirectory parentDirectory = _dir.getParentDirectory(); + TodoDirNode todoDirNode = new TodoDirNode(getProject(), _dir, myBuilder); + if (parentDirectory != null && psiDirectory.equals(parentDirectory) && !children.contains(todoDirNode)) { + children.add(todoDirNode); + break; + } + _dir = parentDirectory; + } + } + Collections.sort(children, TodoFileDirComparator.ourInstance); + } + else { // flatten packages + final PsiDirectory parentDirectory = psiDirectory.getParentDirectory(); + if ( + parentDirectory == null || + parentDirectory.getPackage() == null || + !ProjectRootManager.getInstance(getProject()).getFileIndex().isInContent(parentDirectory.getVirtualFile()) + ) { + final Iterator iterator = myBuilder.getFiles(psiDirectory); + while (iterator.hasNext()) { + final PsiFile psiFile = iterator.next(); + // Add files + TodoFileNode todoFileNode = new TodoFileNode(getProject(), psiFile, myBuilder, false); + if (psiDirectory.equals(psiFile.getContainingDirectory()) && !children.contains(todoFileNode)) { + children.add(todoFileNode); + continue; + } + // Add directories + final PsiDirectory _dir = psiFile.getContainingDirectory(); + TodoDirNode todoDirNode = new TodoDirNode(getProject(), _dir, myBuilder); + if (PsiTreeUtil.isAncestor(psiDirectory, _dir, true) && !children.contains(todoDirNode)) { + children.add(todoDirNode); + continue; + } + } + } + else { + final Iterator iterator = myBuilder.getFiles(psiDirectory); + while (iterator.hasNext()) { + final PsiFile psiFile = iterator.next(); + final PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + TodoFileNode todoFileNode = new TodoFileNode(getProject(), psiFile, myBuilder, false); + if (psiDirectory.equals(containingDirectory) && !children.contains(todoFileNode)) { + children.add(todoFileNode); + } + } + } + Collections.sort(children, TodoFileDirComparator.ourInstance); + } + return children; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoFileNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoFileNode.java new file mode 100644 index 00000000000..303be4f182c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoFileNode.java @@ -0,0 +1,147 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; +import com.intellij.ide.todo.*; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.TodoItem; +import com.intellij.ui.HighlightedRegion; +import com.intellij.usageView.UsageTreeColors; +import com.intellij.usageView.UsageTreeColorsScheme; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +public final class TodoFileNode extends PsiFileNode implements HighlightedRegionProvider{ + private final TodoTreeBuilder myBuilder; + private final ArrayList myHighlightedRegions; + private final boolean mySingleFileMode; + + static private final Logger LOG = Logger.getInstance("#com.intellij.ide.todo.nodes.TodoFileNode"); + + public TodoFileNode(Project project, + PsiFile file, + TodoTreeBuilder treeBuilder, + boolean singleFileMode){ + super(project,file,ViewSettings.DEFAULT); + myBuilder=treeBuilder; + myHighlightedRegions=new ArrayList(2); + mySingleFileMode=singleFileMode; + } + + public ArrayList getHighlightedRegions(){ + return myHighlightedRegions; + } + + public Collection getChildrenImpl() { + if (!mySingleFileMode) { + return createGeneralList(); + } else { + return createListForSingleFile(); + + } + + } + + private Collection createListForSingleFile() { + TodoItem[] items=myBuilder.getTodoTreeStructure().getSearchHelper().findTodoItems(getValue()); + ArrayList children=new ArrayList(items.length); + for(int i=0;i createGeneralList() { + ArrayList children = new ArrayList(); + + PsiFile psiFile = getValue(); + final TodoItem[] items = myBuilder.getTodoTreeStructure().getSearchHelper().findTodoItems(psiFile); + for (int i = 0; i < items.length; i++) { + final TodoItem todoItem = items[i]; + final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); + LOG.assertTrue(todoItem.getTextRange().getEndOffset() < document.getTextLength() + 1); + final SmartTodoItemPointer pointer = new SmartTodoItemPointer(todoItem, document); + TodoFilter todoFilter = getToDoFilter(); + if (todoFilter != null) { + if (todoFilter.contains(todoItem.getPattern())) { + children.add(new TodoItemNode(getProject(), pointer, myBuilder)); + } + } else { + children.add(new TodoItemNode(getProject(), pointer, myBuilder)); + } + } + Collections.sort(children, SmartTodoItemPointerComparator.ourInstance); + return children; + } + + private TodoFilter getToDoFilter() { + return myBuilder.getTodoTreeStructure().getTodoFilter(); + } + + public void updateImpl(PresentationData data) { + super.updateImpl(data); + String newName; + if(myBuilder.getTodoTreeStructure().isPackagesShown()){ + newName=getValue().getName(); + }else{ + newName=mySingleFileMode ? getValue().getName() : getValue().getVirtualFile().getPresentableUrl(); + } + + int nameEndOffset=newName.length(); + int todoItemCount=myBuilder.getTodoTreeStructure().getTodoItemCount(getValue()); + StringBuffer sb=new StringBuffer(newName); + sb.append(" ( "); + if(mySingleFileMode){ + if(todoItemCount==0){ + sb.append("no items found"); + }else{ + sb.append("found ").append(todoItemCount).append(" item"); + if(todoItemCount>1){ + sb.append('s'); + } + } + }else{ + sb.append(todoItemCount).append(" item"); + if(todoItemCount>1){ + sb.append('s'); + } + } + sb.append(" )"); + newName=sb.toString(); + + myHighlightedRegions.clear(); + + TextAttributes textAttributes=new TextAttributes(); + textAttributes.setForegroundColor(myColor); + myHighlightedRegions.add(new HighlightedRegion(0,nameEndOffset,textAttributes)); + + EditorColorsScheme colorsScheme=UsageTreeColorsScheme.getInstance().getScheme(); + myHighlightedRegions.add( + new HighlightedRegion(nameEndOffset,newName.length(),colorsScheme.getAttributes(UsageTreeColors.NUMBER_OF_USAGES)) + ); + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoItemNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoItemNode.java new file mode 100644 index 00000000000..71ca5164338 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/todo/nodes/TodoItemNode.java @@ -0,0 +1,144 @@ +package com.intellij.ide.todo.nodes; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.todo.HighlightedRegionProvider; +import com.intellij.ide.todo.SmartTodoItemPointer; +import com.intellij.ide.todo.TodoTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.search.TodoItem; +import com.intellij.ui.HighlightedRegion; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; + +public final class TodoItemNode extends BaseToDoNode implements HighlightedRegionProvider{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.toDo.TodoItemNodeDescriptor"); + + private final ArrayList myHighlightedRegions; + + public TodoItemNode(Project project, + SmartTodoItemPointer value, + TodoTreeBuilder builder) { + super(project, value, builder); + RangeMarker rangeMarker = getValue().getRangeMarker(); + LOG.assertTrue(rangeMarker.isValid()); + + myHighlightedRegions=new ArrayList(); + + } + + public ArrayList getHighlightedRegions(){ + return myHighlightedRegions; + } + + public Collection getChildren() { + return new ArrayList(); + } + + public void update(PresentationData presentation) { + TodoItem todoItem=getValue().getTodoItem(); + RangeMarker myRangeMarker=getValue().getRangeMarker(); + if(!todoItem.getFile().isValid()||!myRangeMarker.isValid()){ + setValue(null); + return; + } + + myHighlightedRegions.clear(); + + // Update name + + Document document=getValue().getDocument(); + CharSequence chars = document.getCharsSequence(); + int startOffset=myRangeMarker.getStartOffset(); + int endOffset=myRangeMarker.getEndOffset(); + + LOG.assertTrue(startOffset>-1); + LOG.assertTrue(startOffset-1); + LOG.assertTrue(endOffset-1); + LOG.assertTrue(lineNumber-1); + LOG.assertTrue(lineStartOffset<=startOffset); + LOG.assertTrue(lineStartOffset-1); + + // skip all white space characters + + while(chars.charAt(lineStartOffset) == '\t' || chars.charAt(lineStartOffset)==' '){ + lineStartOffset++; + } + + int lineEndOffset = document.getLineEndOffset(lineNumber); + LOG.assertTrue(lineEndOffset>=0); + LOG.assertTrue(lineEndOffset<=document.getTextLength()); + + String lineColumnPrefix="("+(lineNumber+1)+", "+(columnNumber+1)+") "; + + String highlightedText = chars.subSequence(lineStartOffset, Math.min(lineEndOffset, chars.length())).toString();; + + String newName=lineColumnPrefix+highlightedText; + + // Update icon + + Icon newIcon=todoItem.getPattern().getAttributes().getIcon(); + + // Update highlighted regions + + myHighlightedRegions.clear(); + Highlighter highlighter = myBuilder.getHighlighter(todoItem.getFile(),document); + HighlighterIterator iterator=highlighter.createIterator(lineStartOffset); + while(!iterator.atEnd()){ + int start=Math.max(iterator.getStart(),lineStartOffset); + int end=Math.min(iterator.getEnd(),lineEndOffset); + if(lineEndOffset 0) { + try { + _fontSize = new Integer(temp).intValue(); + } + catch (NumberFormatException ex) { + } + if (_fontSize <= 0) { + _fontSize = settings.FONT_SIZE; + } + } + else { + _fontSize = settings.FONT_SIZE; + } + boolean shouldUpdateUI = false; + String _fontFace = (String)myComponent.myFontCombo.getSelectedItem(); + LafManager lafManager = LafManager.getInstance(); + if (_fontSize != settings.FONT_SIZE || !settings.FONT_FACE.equals(_fontFace)) { + settings.FONT_SIZE = _fontSize; + settings.FONT_FACE = _fontFace; + shouldUpdateUI = true; + } + settings.ANIMATE_WINDOWS = myComponent.myAnimateWindowsCheckBox.isSelected(); + boolean update = settings.SHOW_WINDOW_SHORTCUTS != myComponent.myWindowShortcutsCheckBox.isSelected(); + settings.SHOW_WINDOW_SHORTCUTS = myComponent.myWindowShortcutsCheckBox.isSelected(); + update |= settings.HIDE_TOOL_STRIPES != (!myComponent.myShowToolStripesCheckBox.isSelected()); + settings.HIDE_TOOL_STRIPES = !myComponent.myShowToolStripesCheckBox.isSelected(); + update |= settings.ALWAYS_SHOW_WINDOW_BUTTONS != myComponent.myAlwaysShowWindowButtonsCheckBox.isSelected(); + settings.ALWAYS_SHOW_WINDOW_BUTTONS = myComponent.myAlwaysShowWindowButtonsCheckBox.isSelected(); + update |= settings.SHOW_MEMORY_INDICATOR != myComponent.myShowMemoryIndicatorCheckBox.isSelected(); + settings.SHOW_MEMORY_INDICATOR = myComponent.myShowMemoryIndicatorCheckBox.isSelected(); + update |= settings.CYCLE_SCROLLING != myComponent.myCycleScrollingCheckBox.isSelected(); + settings.CYCLE_SCROLLING = myComponent.myCycleScrollingCheckBox.isSelected(); + if (settings.OVERRIDE_NONIDEA_LAF_FONTS != myComponent.myOverrideLAFFonts.isSelected()) { + shouldUpdateUI = true; + } + settings.OVERRIDE_NONIDEA_LAF_FONTS = myComponent.myOverrideLAFFonts.isSelected(); + update |= settings.SCROLL_TAB_LAYOUT_IN_EDITOR != myComponent.myScrollTabLayoutInEditorCheckBox.isSelected(); + settings.SCROLL_TAB_LAYOUT_IN_EDITOR = myComponent.myScrollTabLayoutInEditorCheckBox.isSelected(); + + final int tabPlacement = ((Integer)myComponent.myEditorTabPlacement.getSelectedItem()).intValue(); + update |= tabPlacement != settings.EDITOR_TAB_PLACEMENT; + settings.EDITOR_TAB_PLACEMENT = tabPlacement; + + settings.MOVE_MOUSE_ON_DEFAULT_BUTTON = myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected(); + + boolean hide = myComponent.myHideKnownExtensions.isSelected(); + update |= hide != settings.HIDE_KNOWN_EXTENSION_IN_TABS; + settings.HIDE_KNOWN_EXTENSION_IN_TABS = hide; + + boolean shouldRepaintUI = false; + if ( + settings.ANTIALIASING_IN_EDITOR != myComponent.myAntialiasingInEditorCheckBox.isSelected() + ) { + settings.ANTIALIASING_IN_EDITOR = myComponent.myAntialiasingInEditorCheckBox.isSelected(); + update = shouldRepaintUI = true; + } + + if (!myComponent.myLafComboBox.getSelectedItem().equals(lafManager.getCurrentLookAndFeel())) { + update = shouldUpdateUI = true; + lafManager.setCurrentLookAndFeel((UIManager.LookAndFeelInfo)myComponent.myLafComboBox.getSelectedItem()); + } + + if (shouldUpdateUI) { + lafManager.updateUI(); + } + + if (shouldRepaintUI) { + lafManager.repaintUI(); + } + + if (WindowManagerEx.getInstanceEx().isAlphaModeSupported()) { + int delay = -1; + try { + delay = Integer.parseInt(myComponent.myAlphaModeDelayTextField.getText()); + } + catch (NumberFormatException ignored) { + } + float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f; + if ( + myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.ENABLE_ALPHA_MODE || + delay != -1 && delay != settings.ALPHA_MODE_DELAY || + ratio != settings.ALPHA_MODE_RATIO + ) { + update = true; + settings.ENABLE_ALPHA_MODE = myComponent.myEnableAlphaModeCheckBox.isSelected(); + settings.ALPHA_MODE_DELAY = delay; + settings.ALPHA_MODE_RATIO = ratio; + } + } + + if (update) { + settings.fireUISettingsChanged(); + } + myComponent.updateCombo(); + } + + public void reset() { + UISettings settings = UISettings.getInstance(); + + myComponent.myFontCombo.setSelectedItem(settings.FONT_FACE); + myComponent.myFontSizeCombo.setSelectedItem(Integer.toString(settings.FONT_SIZE)); + myComponent.myAnimateWindowsCheckBox.setSelected(settings.ANIMATE_WINDOWS); + myComponent.myWindowShortcutsCheckBox.setSelected(settings.SHOW_WINDOW_SHORTCUTS); + myComponent.myShowToolStripesCheckBox.setSelected(!settings.HIDE_TOOL_STRIPES); + myComponent.myAlwaysShowWindowButtonsCheckBox.setSelected(settings.ALWAYS_SHOW_WINDOW_BUTTONS); + myComponent.myShowMemoryIndicatorCheckBox.setSelected(settings.SHOW_MEMORY_INDICATOR); + myComponent.myCycleScrollingCheckBox.setSelected(settings.CYCLE_SCROLLING); + myComponent.myScrollTabLayoutInEditorCheckBox.setSelected(settings.SCROLL_TAB_LAYOUT_IN_EDITOR); + myComponent.myEditorTabPlacement.setSelectedItem(new Integer(settings.EDITOR_TAB_PLACEMENT)); + myComponent.myHideKnownExtensions.setSelected(settings.HIDE_KNOWN_EXTENSION_IN_TABS); + myComponent.myAntialiasingInEditorCheckBox.setSelected(settings.ANTIALIASING_IN_EDITOR); + myComponent.myMoveMouseOnDefaultButtonCheckBox.setSelected(settings.MOVE_MOUSE_ON_DEFAULT_BUTTON); + myComponent.myLafComboBox.setSelectedItem(LafManager.getInstance().getCurrentLookAndFeel()); + myComponent.myOverrideLAFFonts.setSelected(settings.OVERRIDE_NONIDEA_LAF_FONTS); + + boolean alphaModeEnabled = WindowManagerEx.getInstanceEx().isAlphaModeSupported(); + if (alphaModeEnabled) { + myComponent.myEnableAlphaModeCheckBox.setSelected(settings.ENABLE_ALPHA_MODE); + } + else { + myComponent.myEnableAlphaModeCheckBox.setSelected(false); + } + myComponent.myEnableAlphaModeCheckBox.setEnabled(alphaModeEnabled); + myComponent.myAlphaModeDelayTextField.setText(Integer.toString(settings.ALPHA_MODE_DELAY)); + myComponent.myAlphaModeDelayTextField.setEnabled(alphaModeEnabled && settings.ENABLE_ALPHA_MODE); + int ratio = (int)(settings.ALPHA_MODE_RATIO * 100f); + myComponent.myAlphaModeRatioSlider.setValue(ratio); + myComponent.myAlphaModeRatioSlider.setToolTipText(ratio + "%"); + myComponent.myAlphaModeRatioSlider.setEnabled(alphaModeEnabled && settings.ENABLE_ALPHA_MODE); + myComponent.updateCombo(); + } + + public boolean isModified() { + UISettings settings = UISettings.getInstance(); + + boolean isModified = false; + isModified |= !Comparing.equal(myComponent.myFontCombo.getSelectedItem(), settings.FONT_FACE); + isModified |= !Comparing.equal(myComponent.myFontSizeCombo.getEditor().getItem(), Integer.toString(settings.FONT_SIZE)); + isModified |= myComponent.myAnimateWindowsCheckBox.isSelected() != settings.ANIMATE_WINDOWS; + isModified |= myComponent.myWindowShortcutsCheckBox.isSelected() != settings.SHOW_WINDOW_SHORTCUTS; + isModified |= myComponent.myShowToolStripesCheckBox.isSelected() == settings.HIDE_TOOL_STRIPES; + isModified |= myComponent.myAlwaysShowWindowButtonsCheckBox.isSelected() != settings.ALWAYS_SHOW_WINDOW_BUTTONS; + isModified |= myComponent.myShowMemoryIndicatorCheckBox.isSelected() != settings.SHOW_MEMORY_INDICATOR; + isModified |= myComponent.myCycleScrollingCheckBox.isSelected() != settings.CYCLE_SCROLLING; + isModified |= myComponent.myScrollTabLayoutInEditorCheckBox.isSelected() != settings.SCROLL_TAB_LAYOUT_IN_EDITOR; + isModified |= myComponent.myOverrideLAFFonts.isSelected() != settings.OVERRIDE_NONIDEA_LAF_FONTS; + + int tabPlacement = ((Integer)myComponent.myEditorTabPlacement.getSelectedItem()).intValue(); + isModified |= tabPlacement != settings.EDITOR_TAB_PLACEMENT; + isModified |= myComponent.myHideKnownExtensions.isSelected() != settings.HIDE_KNOWN_EXTENSION_IN_TABS; + + isModified |= myComponent.myAntialiasingInEditorCheckBox.isSelected() != settings.ANTIALIASING_IN_EDITOR; + isModified |= myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected() != settings.MOVE_MOUSE_ON_DEFAULT_BUTTON; + isModified |= + !myComponent.myLafComboBox.getSelectedItem().equals(LafManager.getInstance().getCurrentLookAndFeel()); + if (WindowManagerEx.getInstanceEx().isAlphaModeSupported()) { + isModified |= myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.ENABLE_ALPHA_MODE; + int delay = -1; + try { + delay = Integer.parseInt(myComponent.myAlphaModeDelayTextField.getText()); + } + catch (NumberFormatException ignored) { + } + if (delay != -1) { + isModified |= delay != settings.ALPHA_MODE_DELAY; + } + float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f; + isModified |= ratio != settings.ALPHA_MODE_RATIO; + } + return isModified; + } + + public void disposeUIResources() { +// if (myComponent == null) + myComponent = null; + } + + + public String getHelpTopic() { + return "preferences.lookFeel"; + } + + public String getComponentName() { + return "UISettingsConfigurable"; + } + + private static final class MyLafComboBoxRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + UIManager.LookAndFeelInfo laf = (UIManager.LookAndFeelInfo)value; + return super.getListCellRendererComponent(list, laf.getName(), index, isSelected, cellHasFocus); + } + } + + private static final class MyTabsPlacementComboBoxRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + int tabPlacement = ((Integer)value).intValue(); + String text; + if (UISettings.TABS_NONE == tabPlacement) { + text = "None"; + } + else if (SwingConstants.TOP == tabPlacement) { + text = "Top"; + } + else if (SwingConstants.LEFT == tabPlacement) { + text = "Left"; + } + else if (SwingConstants.BOTTOM == tabPlacement) { + text = "Bottom"; + } + else if (SwingConstants.RIGHT == tabPlacement) { + text = "Right"; + } + else { + throw new IllegalArgumentException("unknown tabPlacement: " + tabPlacement); + } + return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus); + } + } + + private static class MyComponent { + JPanel myPanel; + private JComboBox myFontCombo; + private JComboBox myFontSizeCombo; + private JCheckBox myAnimateWindowsCheckBox; + private JCheckBox myWindowShortcutsCheckBox; + private JCheckBox myShowToolStripesCheckBox; + private JCheckBox myAlwaysShowWindowButtonsCheckBox; + private JCheckBox myShowMemoryIndicatorCheckBox; + private JComboBox myLafComboBox; + private JCheckBox myCycleScrollingCheckBox; + private JCheckBox myScrollTabLayoutInEditorCheckBox; + private JComboBox myEditorTabPlacement; + private JCheckBox myAntialiasingInEditorCheckBox; + private JCheckBox myMoveMouseOnDefaultButtonCheckBox; + private JCheckBox myEnableAlphaModeCheckBox; + private JTextField myAlphaModeDelayTextField; + private JSlider myAlphaModeRatioSlider; + private JLabel myFontSizeLabel; + private JLabel myFontNameLabel; + private JPanel myTransparencyPanel; + private JCheckBox myOverrideLAFFonts; + private JLabel myIDEALafFont; + private JCheckBox myHideKnownExtensions; + + public MyComponent() { + ActionListener updater = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateCombo(); + } + }; + myLafComboBox.addActionListener(updater); + myOverrideLAFFonts.addActionListener(updater); + myIDEALafFont.setPreferredSize(new Dimension(myIDEALafFont.getPreferredSize().width, + myOverrideLAFFonts.getPreferredSize().height)); + } + + public void updateCombo() { + UIManager.LookAndFeelInfo selectedLAF = (UIManager.LookAndFeelInfo)myLafComboBox.getSelectedItem(); + boolean isIdeaLAFSelected = selectedLAF.getName().startsWith("IDEA"); + + myIDEALafFont.setVisible(isIdeaLAFSelected); + myOverrideLAFFonts.setVisible(!isIdeaLAFSelected); + boolean enableChooser = isIdeaLAFSelected || myOverrideLAFFonts.isSelected(); + + myFontCombo.setEnabled(enableChooser); + myFontSizeCombo.setEnabled(enableChooser); + myFontNameLabel.setEnabled(enableChooser); + myFontSizeLabel.setEnabled(enableChooser); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/LafManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/LafManager.java new file mode 100644 index 00000000000..e26977481fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/LafManager.java @@ -0,0 +1,536 @@ +package com.intellij.ide.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.ui.IdeaBlueMetalTheme; +import com.intellij.ui.SideBorder2; +import com.intellij.ui.plaf.beg.*; +import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.EventListenerList; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.FontUIResource; +import javax.swing.plaf.metal.DefaultMetalTheme; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.text.DefaultEditorKit; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; + +/** + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public final class LafManager implements ApplicationComponent,JDOMExternalizable{ + private static final Logger LOG=Logger.getInstance("#com.intellij.ide.ui.LafManager"); + + /** + * One of the possible values of -Didea.popup.weight property. Heavy weight means + * that all popups are shown inside the window. Under UNIXes it's possible to configure + * window manager "Focus follows mouse with Auto Raise". In this case popup window will + * be immediately closed after showing. + */ + private static final String HEAVY_WEIGHT_POPUP="heavy"; + /** + * One of the possible values of -Didea.popup.weight property. Medium weight means + * that popup will be shouw inside the paren't JLayeredPane if it can be fit to it. + * Otherwise popup will be shown in the window. This mode is defaut for the Swing but + * it's very slow (much slower then heavy weight popups). + */ + private static final String MEDIUM_WEIGHT_POPUP="medium"; + + private final EventListenerList myListenerList; + private UIManager.LookAndFeelInfo[] myLafs; + private UIManager.LookAndFeelInfo myCurrentLaf; + + private static String[] ourPatcheableFontResources = new String[]{ + "Button.font", "ToggleButton.font", "RadioButton.font", "CheckBox.font", "ColorChooser.font", "ComboBox.font", + "Label.font", "List.font", "MenuBar.font", "MenuItem.font", "MenuItem.acceleratorFont", "RadioButtonMenuItem.font", + "CheckBoxMenuItem.font", "Menu.font", "PopupMenu.font", "OptionPane.font", "Panel.font", "ProgressBar.font", + "ScrollPane.font", "Viewport.font", "TabbedPane.font", "Table.font", "TableHeader.font", "TextField.font", + "PasswordField.font", "TextArea.font", "TextPane.font", "EditorPane.font", "TitledBorder.font", "ToolBar.font", + "ToolTip.font", "Tree.font" + }; + private HashMap> myStoredDefaults = new HashMap>(); + private UISettings myUiSettings; + + public static LafManager getInstance(){ + return ApplicationManager.getApplication().getComponent(LafManager.class); + } + + /** invoked by reflection + * @param uiSettings */ + LafManager(UISettings uiSettings){ + myUiSettings = uiSettings; + myListenerList=new EventListenerList(); + + IdeaLookAndFeelInfo ideaLaf=new IdeaLookAndFeelInfo(); + UIManager.LookAndFeelInfo[] installedLafs=UIManager.getInstalledLookAndFeels(); + + // Get all installed LAFs + myLafs=new UIManager.LookAndFeelInfo[1+installedLafs.length]; + myLafs[0]=ideaLaf; + System.arraycopy(installedLafs,0,myLafs,1,installedLafs.length); + Arrays.sort(myLafs,new MyComparator()); + + // Setup current LAF. Unfortunately it's system depended. + myCurrentLaf=getDefaultLaf(); + } + + /** + * Adds specified listener + */ + public void addLafManagerListener(final LafManagerListener l){ + if (l == null) { + throw new IllegalArgumentException("l cannot be null"); + } + myListenerList.add(LafManagerListener.class, l); + } + + /** + * Removes specified listener + */ + public void removeLafManagerListener(final LafManagerListener l){ + if (l == null) { + throw new IllegalArgumentException("l cannot be null"); + } + myListenerList.remove(LafManagerListener.class, l); + } + + private void fireLookAndFeelChanged(){ + LafManagerListener[] listeners = (LafManagerListener[])myListenerList.getListeners(LafManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].lookAndFeelChanged(this); + } + } + + public String getComponentName(){ + return "LafManager"; + } + + public void initComponent() { + setCurrentLookAndFeel(findLaf(myCurrentLaf.getClassName())); // set IDEA's default LAF + updateUI(); + } + + public void disposeComponent(){} + + public void readExternal(Element element) { + String className=null; + for(Iterator i=element.getChildren().iterator();i.hasNext();){ + Element child=(Element)i.next(); + if("laf".equals(child.getName())){ + className=child.getAttributeValue("class-name"); + break; + } + } + + UIManager.LookAndFeelInfo laf=findLaf(className); + // If LAF is undefined (wrong class name or something else) we have set default LAF anyway. + if(laf==null){ + laf=getDefaultLaf(); + } + + myCurrentLaf=laf; + } + + public void writeExternal(Element element) { + if(myCurrentLaf.getClassName()!=null){ + Element child=new Element("laf"); + child.setAttribute("class-name",myCurrentLaf.getClassName()); + element.addContent(child); + } + } + + public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){ + return (UIManager.LookAndFeelInfo[])myLafs.clone(); + } + + public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){ + return myCurrentLaf; + } + + public boolean isUnderAquaLookAndFeel() { + return "Mac OS X".equals(getCurrentLookAndFeel().getName()); + } + + /** + * @return default LookAndFeelInfo for the running OS. For Win32 and + * Linux the method returns IDEA LAF, for Mac OS X it returns Aqua + */ + private UIManager.LookAndFeelInfo getDefaultLaf(){ + if(SystemInfo.isMac){ + UIManager.LookAndFeelInfo laf=findLaf(UIManager.getSystemLookAndFeelClassName()); + LOG.assertTrue(laf!=null); + return laf; + } + else{ + return findLaf(null); + } + } + + /** + * Finds LAF by its class name. null argument means that IDEA's default LAF + * will be returned. + */ + private UIManager.LookAndFeelInfo findLaf(String className){ + for(int i=0;iUISettings. + */ + public void updateUI(){ + UIDefaults lookAndFeelDefaults=UIManager.getLookAndFeelDefaults(); + initInputMapDefaults(lookAndFeelDefaults); + if (shouldPatchLAFFonts()) { + storeOriginalFontDefaults(lookAndFeelDefaults); + initFontDefaults(lookAndFeelDefaults); + } + else { + restoreOriginalFontDefaults(lookAndFeelDefaults); + } + + Frame[] frames=Frame.getFrames(); + for(int i=0;i lfDefaults = myStoredDefaults.get(lf); + if (lfDefaults != null) { + for (int i = 0; i < ourPatcheableFontResources.length; i++) { + String resource = ourPatcheableFontResources[i]; + defaults.put(resource, lfDefaults.get(resource)); + } + } + } + + private void storeOriginalFontDefaults(UIDefaults defaults) { + UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel(); + HashMap lfDefaults = myStoredDefaults.get(lf); + if (lfDefaults == null) { + lfDefaults = new HashMap(); + for (int i = 0; i < ourPatcheableFontResources.length; i++) { + String resource = ourPatcheableFontResources[i]; + lfDefaults.put(resource, defaults.get(resource)); + } + myStoredDefaults.put(lf, lfDefaults); + } + } + + private boolean shouldPatchLAFFonts() { + return getCurrentLookAndFeel().getName().startsWith("IDEA") || UISettings.getInstance().OVERRIDE_NONIDEA_LAF_FONTS; + } + + private void updateUI(Window window){ + if(!window.isDisplayable()){ + return; + } + SwingUtilities.updateComponentTreeUI(window); + Window[] children=window.getOwnedWindows(); + for(int i=0;iPropertyChangeListener + * into UIManager + * + * @author Vladimir Kondratyev + */ +public interface LafManagerListener extends EventListener{ + void lookAndFeelChanged(LafManager source); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettings.java new file mode 100644 index 00000000000..22eb2f48a1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettings.java @@ -0,0 +1,195 @@ +package com.intellij.ide.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.*; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; + +public class UISettings implements NamedJDOMExternalizable, ApplicationComponent { + private EventListenerList myListenerList; + + public String FONT_FACE; + public int FONT_SIZE; + public int RECENT_FILES_LIMIT = 15; + public int EDITOR_TAB_LIMIT = 10; + public boolean ANIMATE_WINDOWS = true; + public int ANIMATION_SPEED = 2000; // Pixels per second + public boolean SHOW_WINDOW_SHORTCUTS = true; + public boolean HIDE_TOOL_STRIPES = false; + public boolean SHOW_MEMORY_INDICATOR = true; + public boolean SHOW_MAIN_TOOLBAR = true; + public boolean SHOW_STATUS_BAR = true; + public boolean ALWAYS_SHOW_WINDOW_BUTTONS = false; + public boolean CYCLE_SCROLLING = true; + public boolean SCROLL_TAB_LAYOUT_IN_EDITOR = false; + public int EDITOR_TAB_PLACEMENT = 1; + public boolean HIDE_KNOWN_EXTENSION_IN_TABS = false; + public boolean CLOSE_NON_MODIFIED_FILES_FIRST = false; + public boolean ANTIALIASING_IN_EDITOR; + public boolean MOVE_MOUSE_ON_DEFAULT_BUTTON = false; + public boolean ENABLE_ALPHA_MODE = false; + public int ALPHA_MODE_DELAY = 1500; + public float ALPHA_MODE_RATIO = .5f; + public int MAX_CLIPBOARD_CONTENTS = 5; + public boolean OVERRIDE_NONIDEA_LAF_FONTS = false; + + /** + * Defines whether asterisk is shown on modified editor tab or not + */ + public boolean MARK_MODIFIED_TABS_WITH_ASTERISK = false; + + /** + * Not tabbed pane + */ + public static final int TABS_NONE = 0; + + /** Invoked by reflection */ + UISettings(){ + myListenerList=new EventListenerList(); + ANTIALIASING_IN_EDITOR = SystemInfo.isMac; + setSystemFontFaceAndSize(); + } + + public void initComponent() { } + + public void disposeComponent() {} + + public void addUISettingsListener(UISettingsListener listener){ + myListenerList.add(UISettingsListener.class,listener); + } + + /** + * Notifies all registered listeners that UI settings has been changed. + */ + public void fireUISettingsChanged(){ + UISettingsListener[] listeners=(UISettingsListener[])myListenerList.getListeners(UISettingsListener.class); + for(int i=0;i1.0f){ + ALPHA_MODE_RATIO=0.5f; + } + + setSystemFontFaceAndSize(); + // 1. Sometimes system font cannot display standard ASCI symbols. If so we have + // find any other suitable font withing "preferred" fonts first. + boolean fontIsValid = isValidFont(new Font(FONT_FACE, Font.PLAIN, FONT_SIZE)); + if(!fontIsValid){ + final String[] preferredFonts = new String[]{"dialog", "Arial", "Tahoma"}; + for(int i = 0; i < preferredFonts.length; i++){ + if(isValidFont(new Font(preferredFonts[i], Font.PLAIN, FONT_SIZE))){ + FONT_FACE = preferredFonts[i]; + fontIsValid = true; + break; + } + } + + // 2. If all preferred fonts are not valid in current environment + // we have to find first valid font (if any) + if(!fontIsValid){ + Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); + for(int i = 0; i < fonts.length; i++){ + if(isValidFont(fonts[i])){ + FONT_FACE = fonts[i].getName(); + break; + } + } + } + } + + if (MAX_CLIPBOARD_CONTENTS <= 0) { + MAX_CLIPBOARD_CONTENTS = 5; + } + } + + private static boolean isValidFont(final Font font){ + return + font.canDisplay('a') && + font.canDisplay('z') && + font.canDisplay('A') && + font.canDisplay('Z') && + font.canDisplay('0') && + font.canDisplay('1'); + } + + /** + * Under Win32 it's possible to determine face and size of default fount. + */ + private void setSystemFontFaceAndSize(){ + if(FONT_FACE == null || FONT_SIZE <= 0){ + if(SystemInfo.isWindows){ + Font font=(Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); + if(font != null){ + FONT_FACE = font.getName(); + FONT_SIZE = font.getSize(); + }else{ + setDefaultFontSettings(); + } + }else{ // UNIXes go here + setDefaultFontSettings(); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + // Don't save face and size of font if it they don't differ from system settings + Font font=(Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); + if(SystemInfo.isWindows && font!=null && FONT_FACE.equals(font.getName()) && FONT_SIZE==font.getSize()){ + String oldFontFace=FONT_FACE; + int oldFontSize=FONT_SIZE; + FONT_FACE=null; + FONT_SIZE=-1; + try{ + DefaultJDOMExternalizer.writeExternal(this, element); + }finally{ + FONT_FACE=oldFontFace; + FONT_SIZE=oldFontSize; + } + }else{ + DefaultJDOMExternalizer.writeExternal(this, element); + } + } + + public String getComponentName() { + return "UISettings"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettingsListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettingsListener.java new file mode 100644 index 00000000000..46dc55a0224 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/ui/UISettingsListener.java @@ -0,0 +1,10 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.ide.ui; + +import java.util.EventListener; + +public interface UISettingsListener extends EventListener{ + void uiSettingsChanged(UISettings source); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/updates/UpdateChecker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/updates/UpdateChecker.java new file mode 100644 index 00000000000..acd2c28d835 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/updates/UpdateChecker.java @@ -0,0 +1,135 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Oct 31, 2002 + * Time: 6:33:01 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.ide.updates; + +import com.intellij.ide.license.LicenseManager; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import org.jdom.Document; + +import javax.swing.*; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * XML sample: + * + * 456 + * New Intellij IDEA Version + * + * New version of IntelliJ IDEA is available. + * Please visit http://www.intellij.com/ for more info. + * + * + */ +final class UpdateChecker { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.updates.UpdateChecker"); + + private static final int MIN = 1000 * 60; + private static final long CHECK_INTERVAL = MIN * 60 * 24 * 2; + private static final URL UPDATE_URL; + + static { + URL url = null; + try { + url = new URL("http://www.jetbrains.com/updates/update.xml"); + } + catch (MalformedURLException e) { + LOG.error(e); + } + + UPDATE_URL = url; + } + + public static void checkForUpdates() { + if (!LicenseManager.getInstance().shouldCheckForUpdates()) { + return; + } + if (LOG.isDebugEnabled()) { + LOG.debug("enter: checkForUpdates()"); + } + final UpdateSettings settings = UpdateSettings.getInstance(); + if (settings == null) return; + if (UPDATE_URL == null) return; + + final long timeDelta = System.currentTimeMillis() - settings.LAST_TIME_CHECKED; + if (Math.abs(timeDelta) < CHECK_INTERVAL) return; + + if (!settings.ASK_USER && !settings.CHECK_UPDATES) return; + + if (settings.ASK_USER) { + final ConfirmUpdateDialog confirmUpdateDialog = new ConfirmUpdateDialog(); + confirmUpdateDialog.show(); + settings.CHECK_UPDATES = confirmUpdateDialog.getExitCode() == ConfirmUpdateDialog.OK_EXIT_CODE; + settings.ASK_USER = !confirmUpdateDialog.getCheckBox().isSelected(); + if (confirmUpdateDialog.getExitCode() != ConfirmUpdateDialog.OK_EXIT_CODE) return; + } + + new Thread(new Runnable() { + public void run() { + final Document document; + try { + document = loadVersionInfo(); + } + catch (Throwable t) { + LOG.debug(t); + return; + } + + final String message = document.getRootElement().getChild("message").getTextTrim(); + final String title = document.getRootElement().getChild("title").getTextTrim(); + final String availBuild = document.getRootElement().getChild("build").getTextTrim(); + final String ourBuild = ApplicationInfo.getInstance().getBuildNumber().trim(); + + if (LOG.isDebugEnabled()) { + LOG.debug("build available:'" + availBuild + "' ourBuild='" + ourBuild + "' "); + } + + try { + final int iAvailBuild = Integer.parseInt(availBuild); + final int iOurBuild = Integer.parseInt(ourBuild); + if (iAvailBuild > iOurBuild) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + final UpdateAvailDialog dialog = new UpdateAvailDialog(title, message.trim()); + dialog.show(); + } + }); + } + + } + catch (Throwable t) { + LOG.debug(t); + return; + } + + settings.LAST_TIME_CHECKED = System.currentTimeMillis(); + } + }, "UpdateCheckingThread").start(); + + } + + private static Document loadVersionInfo() throws Exception { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: loadVersionInfo(UPDATE_URL='" + UPDATE_URL + "' )"); + } + final InputStream inputStream = UPDATE_URL.openStream(); + final Document document; + try { + document = JDOMUtil.loadDocument(inputStream); + } + finally { + inputStream.close(); + } + + return document; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteDialog.java new file mode 100644 index 00000000000..c26db08d890 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteDialog.java @@ -0,0 +1,143 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.help.HelpManager; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author dsl + */ +public class DeleteDialog extends DialogWrapper { + private final PsiElement[] myElements; + private final Callback myCallback; + + private StateRestoringCheckBox myCbSearchInComments; + private StateRestoringCheckBox myCbSearchInNonJava; + private JCheckBox myCbSafeDelete; + + public interface Callback { + void run(DeleteDialog dialog); + } + + public DeleteDialog(Project project, PsiElement[] elements, Callback callback) { + super(project, true); + myElements = elements; + myCallback = callback; + + setTitle(SafeDeleteHandler.REFACTORING_NAME); + init(); + } + + public boolean isSearchInComments() { + return myCbSearchInComments.isSelected(); + } + + public boolean isSearchInNonJava() { + return myCbSearchInNonJava.isSelected(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction()/*, getHelpAction()*/}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.SAFE_DELETE); + } + + protected JComponent createNorthPanel() { + final JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints gbc = new GridBagConstraints(); + + final String warningMessage = DeleteUtil.generateWarningMessage("Delete", myElements); + + gbc.insets = new Insets(4, 8, 4, 8); + gbc.weighty = 1; + gbc.weightx = 1; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.WEST; + panel.add(new JLabel(warningMessage), gbc); + + gbc.gridy++; + gbc.gridx = 0; + gbc.weightx = 0.0; + gbc.gridwidth = 1; + gbc.insets = new Insets(4, 8, 0, 8); + myCbSafeDelete = new JCheckBox("Safe delete (with usage search)"); + myCbSafeDelete.setMnemonic('F'); + panel.add(myCbSafeDelete, gbc); + + gbc.gridy++; + gbc.gridx = 0; + gbc.weightx = 0.0; + gbc.gridwidth = 1; + gbc.insets = new Insets(0, 8, 4, 8); + myCbSearchInComments = new StateRestoringCheckBox("Search in comments and strings"); + myCbSearchInComments.setMnemonic('S'); + panel.add(myCbSearchInComments, gbc); + + gbc.gridx++; + myCbSearchInNonJava = new StateRestoringCheckBox("Search in non-java files"); + myCbSearchInNonJava.setMnemonic('e'); + panel.add(myCbSearchInNonJava, gbc); + + final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance(); + myCbSafeDelete.setSelected(refactoringSettings.SAFE_DELETE_WHEN_DELETE); + myCbSearchInComments.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS); + myCbSearchInNonJava.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA); + + myCbSafeDelete.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateControls(); + } + }); + updateControls(); + return panel; + } + + private void updateControls() { + if(myCbSafeDelete.isSelected()) { + myCbSearchInComments.makeSelectable(); + myCbSearchInNonJava.makeSelectable(); + } + else { + myCbSearchInComments.makeUnselectable(false); + myCbSearchInNonJava.makeUnselectable(false); + } + } + + protected JComponent createCenterPanel() { + return null; + } + + + protected void doOKAction() { + final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance(); + refactoringSettings.SAFE_DELETE_WHEN_DELETE = myCbSafeDelete.isSelected(); + if (myCbSafeDelete.isSelected()) { + if (myCallback != null) { + myCallback.run(this); + } else { + super.doOKAction(); + } + refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS = isSearchInComments(); + refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA = isSearchInNonJava(); + } + else { + super.doOKAction(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteHandler.java new file mode 100644 index 00000000000..cfd5314f7f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteHandler.java @@ -0,0 +1,269 @@ +package com.intellij.ide.util; + +import com.intellij.ide.DeleteProvider; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.ex.MessagesEx; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiCompiledElement; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.io.ReadOnlyAttributeUtil; + +import java.io.IOException; +import java.util.ArrayList; + +public class DeleteHandler { + public static class DefaultDeleteProvider implements DeleteProvider { + public boolean canDeleteElement(DataContext dataContext) { + if ((Project)dataContext.getData(DataConstants.PROJECT) == null) return false; + final PsiElement[] elements = getPsiElements(dataContext); + if (elements == null) return false; + return DeleteHandler.shouldEnableDeleteAction(elements); + } + + private PsiElement[] getPsiElements(DataContext dataContext) { + PsiElement[] elements = (PsiElement[])dataContext.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + if (elements == null) { + final Object data = dataContext.getData(DataConstants.PSI_ELEMENT); + if (data != null) { + elements = new PsiElement[]{(PsiElement)data}; + } + else { + final Object data1 = dataContext.getData(DataConstants.PSI_FILE); + if (data1 != null) { + elements = new PsiElement[]{(PsiFile)data1}; + } + } + } + return elements; + } + + public void deleteElement(DataContext dataContext) { + PsiElement[] elements = getPsiElements(dataContext); + if (elements == null) return; + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(project, "Deleting"); + try { + DeleteHandler.deletePsiElement(elements, project); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(project, action); + } + } + + } + + + public static void deletePsiElement(final PsiElement[] elementsToDelete, final Project project) { + if (elementsToDelete == null || elementsToDelete.length == 0) return; + + final PsiElement[] elements = DeleteUtil.filterElements(elementsToDelete); + + boolean safeDeleteApplicable = true; + for (int i = 0; i < elements.length && safeDeleteApplicable; i++) { + PsiElement element = elements[i]; + safeDeleteApplicable = element.isWritable() && SafeDeleteProcessor.validElement(element); + } + + if (safeDeleteApplicable) { + DeleteDialog dialog = new DeleteDialog(project, elements, new DeleteDialog.Callback() { + public void run(final DeleteDialog dialog) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return; + } + } + SafeDeleteProcessor.createInstance(project, new Runnable() { + public void run() { + dialog.close(DeleteDialog.CANCEL_EXIT_CODE); + } + }, elements, dialog.isSearchInComments(), dialog.isSearchInNonJava(), true).run(null); + } + } + ); + dialog.show(); + if (!dialog.isOK()) return; + } + else { + String warningMessage = DeleteUtil.generateWarningMessage("Delete", elements); + + int defaultOption; + + boolean anyDirectories = false; + String directoryName = null; + for (int i = 0; i < elementsToDelete.length; i++) { + PsiElement psiElement = elementsToDelete[i]; + if (psiElement instanceof PsiDirectory) { + anyDirectories = true; + directoryName = ((PsiDirectory)psiElement).getName(); + break; + } + } + if (anyDirectories) { + if (elements.length == 1) { + warningMessage += "\nAll files and subdirectories in \"" + directoryName + + "\" will be deleted.\nYou will not be able to undo this operation!"; + } + else { + warningMessage += + "\nAll files and subdirectories in the selected directory(s) will be deleted.\nYou will not be able to undo this operation!"; + } + defaultOption = -1; + } + else { + defaultOption = 0; + } + + int result = Messages.showDialog(project, warningMessage, "Delete", new String[]{"OK", "Cancel"}, defaultOption, + Messages.getQuestionIcon()); + if (result != 0) return; + } + + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + for (int i = 0; i < elements.length; i++) { + final PsiElement elementToDelete = elements[i]; + + if (elementToDelete instanceof PsiDirectory) { + VirtualFile virtualFile = ((PsiDirectory)elementToDelete).getVirtualFile(); + if (virtualFile.getFileSystem() instanceof LocalFileSystem) { + + ArrayList readOnlyFiles = new ArrayList(); + getReadOnlyVirtualFiles(virtualFile, readOnlyFiles); + + if (readOnlyFiles.size() > 0) { + int _result = Messages.showOkCancelDialog( + project, + "Directory " + virtualFile.getPresentableUrl() + " contains read-only file(s). Delete it anyway?", + "Delete", + Messages.getQuestionIcon() + ); + if (_result != 0) continue; + + boolean success = true; + for (int j = 0; j < readOnlyFiles.size(); j++) { + VirtualFile file = (VirtualFile)readOnlyFiles.get(j); + success = clearReadOnlyFlag(file, project); + if (!success) break; + } + if (!success) continue; + + } + + } + } + else if (!elementToDelete.isWritable()) { + final PsiFile file = elementToDelete.getContainingFile(); + if (file != null) { + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile.getFileSystem() instanceof LocalFileSystem) { + int _result = MessagesEx.fileIsReadOnly(project, virtualFile) + .setTitle("Delete") + .appendMessage(" Delete it anyway?") + .askOkCancel(); + if (_result != 0) continue; + + boolean success = clearReadOnlyFlag(virtualFile, project); + if (!success) continue; + } + } + } + + try { + elementToDelete.checkDelete(); + } + catch (IncorrectOperationException ex) { + Messages.showMessageDialog(project, ex.getMessage(), "Error", Messages.getErrorIcon()); + continue; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + elementToDelete.delete(); + } + catch (final IncorrectOperationException ex) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(project, ex.getMessage(), "Error", Messages.getErrorIcon()); + } + }); + } + } + }); + } + } + }, + "Delete", + null + ); + } + + private static boolean clearReadOnlyFlag(final VirtualFile virtualFile, final Project project) { + final boolean[] success = new boolean[1]; + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + Runnable action = new Runnable() { + public void run() { + try { + ReadOnlyAttributeUtil.setReadOnlyAttribute(virtualFile, false); + success[0] = true; + } + catch (IOException e1) { + Messages.showMessageDialog(project, e1.getMessage(), "Error", Messages.getErrorIcon()); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + "", + null + ); + return success[0]; + } + + /** + * Fills readOnlyFiles with VirtualFiles + */ + private static void getReadOnlyVirtualFiles(VirtualFile file, ArrayList readOnlyFiles) { + if (!file.isWritable()) { + readOnlyFiles.add(file); + } + if (file.isDirectory()) { + VirtualFile[] children = file.getChildren(); + for (int i = 0; i < children.length; i++) { + getReadOnlyVirtualFiles(children[i], readOnlyFiles); + } + } + } + + public static boolean shouldEnableDeleteAction(PsiElement[] elements) { + if (elements == null || elements.length == 0) return false; + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (element instanceof PsiCompiledElement) { + return false; + } + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteUtil.java new file mode 100644 index 00000000000..3aa26e0fda5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DeleteUtil.java @@ -0,0 +1,163 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author dsl + */ +public class DeleteUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.DeleteUtil"); + public static void appendMessage(int count, String singleName, String multipleName, StringBuffer buffer) { + if (count > 0) { + if (buffer.length() > 0) { + buffer.append(" and "); + } + buffer.append(count); + buffer.append(' '); + if (count == 1) { + buffer.append(singleName); + } + else { + buffer.append(multipleName); + } + } + } + + public static PsiElement[] filterElements(PsiElement[] elements) { + if (LOG.isDebugEnabled()) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + LOG.debug("element = "+element); + } + } + + ArrayList filteredElements = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + filteredElements.add(element); + } + + int previousSize; + do { + previousSize = filteredElements.size(); + outer: for (Iterator iterator1 = filteredElements.iterator(); iterator1.hasNext();) { + PsiElement element1 = (PsiElement)iterator1.next(); + for (Iterator iterator2 = filteredElements.iterator(); iterator2.hasNext();) { + PsiElement element2 = (PsiElement)iterator2.next(); + if (element1 == element2) continue; + if (PsiTreeUtil.isAncestor(element1, element2, false)) { + if (LOG.isDebugEnabled()) { + LOG.debug("removing " + element2); + } + filteredElements.remove(element2); + break outer; + } + } + } + } while (filteredElements.size() != previousSize); + + if (LOG.isDebugEnabled()) { + for (Iterator iterator = filteredElements.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement)iterator.next(); + LOG.debug("filtered element = "+element); + } + } + + return (PsiElement[])filteredElements.toArray(new PsiElement[filteredElements.size()]); + } + + public static String generateWarningMessage(String actionName, final PsiElement[] elements) { + int methods = 0; + int fields = 0; + int interfaces = 0; + int classes = 0; + int files = 0; + int directories = 0; + int packages = 0; + int packageDirectories = 0; + String[] objName = new String[] { "", "", "" }; + + for (int i = 0; i < elements.length; i++) { + final PsiElement elementToDelete = elements[i]; + + if (elementToDelete instanceof PsiMethod) { + objName[0] = ((PsiMethod)elementToDelete).getName(); + objName[1] = "method"; + methods++; + } + else if (elementToDelete instanceof PsiField) { + objName[0] = ((PsiField)elementToDelete).getName(); + objName[1] = "field"; + fields++; + } + else if (elementToDelete instanceof PsiClass) { + objName[0] = ((PsiClass)elementToDelete).getName(); + if (((PsiClass)elementToDelete).isInterface()) { + objName[1] = "interface"; + interfaces++; + } + else { + objName[1] = "class"; + classes++; + } + } + else if (elementToDelete instanceof PsiFile) { + objName[0] = ((PsiFile)elementToDelete).getName(); + objName[1] = "file"; + files++; + } + else if (elementToDelete instanceof PsiDirectory) { + directories = processDirectory(elementToDelete, objName, directories); + } + else if (elementToDelete instanceof PsiPackage) { + final PsiPackage psiPackage = (PsiPackage)elementToDelete; + final String name = psiPackage.getName(); + final PsiDirectory[] psiDirectories = psiPackage.getDirectories(); + final int count = psiDirectories.length; + objName[1] = "package"; + objName[0] = name; + objName[2] = " " + buildDirectoryMessage(count); + packages += 1; + packageDirectories += count; + } + } + + String warningMessage = actionName + " "; + if (elements.length == 1) { + warningMessage += objName[1] + " \"" + objName[0] + "\"" + objName[2] + "?"; + } + else { + StringBuffer buffer = new StringBuffer(); + appendMessage(directories, "directory", "directories", buffer); + appendMessage(files, "file", "files", buffer); + appendMessage(classes, "class", "classes", buffer); + appendMessage(interfaces, "interface", "interfaces", buffer); + appendMessage(methods, "method", "methods", buffer); + appendMessage(fields, "field", "fields", buffer); + if (packages > 0) { + appendMessage(packages, "package", "packages", buffer); + buffer.append(' '); + buffer.append(buildDirectoryMessage(packageDirectories)); + } + buffer.append('?'); + warningMessage += buffer.toString(); + } + return warningMessage; + } + + private static String buildDirectoryMessage(final int count) { + return "(" + count + " " + (count == 1 ? "directory" : "directories") + ")"; + } + + private static int processDirectory(final PsiElement elementToDelete, String[] objName, int directories) { + objName[0] = ((PsiDirectory)elementToDelete).getName(); + objName[1] = "directory"; + directories++; + return directories; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooser.java new file mode 100644 index 00000000000..397f63b6f39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooser.java @@ -0,0 +1,343 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiRootPackageType; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public class DirectoryChooser extends DialogWrapper { + private final DirectoryChooserView myView; + + public DirectoryChooser(Project project){ + this(project, new DirectoryChooserModuleTreeView(project)); + } + + public DirectoryChooser(Project project, DirectoryChooserView view){ + super(project, true); + myView = view; + init(); + } + + + protected JComponent createCenterPanel(){ + final Runnable runnable = new Runnable() { + public void run() { + enableButtons(); + } + }; + myView.onSelectionChange(runnable); + final JComponent component = myView.getComponent(); + final JScrollPane jScrollPane = new JScrollPane(component); + int prototypeWidth = component.getFontMetrics(component.getFont()).stringWidth("X:\\1234567890\\1234567890\\com\\company\\system\\subsystem"); + jScrollPane.setPreferredSize(new Dimension(Math.max(300, prototypeWidth),300)); + + installEnterAction(component); + + return jScrollPane; + } + + private void installEnterAction(final JComponent component) { + final KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0); + final InputMap inputMap = component.getInputMap(); + final ActionMap actionMap = component.getActionMap(); + final Object oldActionKey = inputMap.get(enterKeyStroke); + final Action oldAction = oldActionKey != null ? actionMap.get(oldActionKey) : null; + inputMap.put(enterKeyStroke, "clickButton"); + actionMap.put("clickButton", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (isOKActionEnabled()) { + doOKAction(); + } + else if (oldAction != null) { + oldAction.actionPerformed(e); + } + } + }); + } + + protected String getDimensionServiceKey() { + return "chooseDestDirectoryDialog"; + } + + private String[] splitPath(String path) { + ArrayList list = new ArrayList(); + int index = 0; + int nextSeparator; + while ((nextSeparator = path.indexOf(File.separatorChar, index)) != -1) { + list.add(path.substring(index, nextSeparator)); + index = nextSeparator + 1; + } + list.add(path.substring(index, path.length())); + return list.toArray(new String[list.size()]); + } + + private void buildFragments() { + ArrayList pathes = new ArrayList(); + for (int i = 0; i < myView.getItemsSize(); i++) { + ItemWrapper item = myView.getItemByIndex(i); + pathes.add(splitPath(item.getPresentableUrl())); + } + FragmentBuilder headBuilder = new FragmentBuilder(pathes){ + protected void append(String fragment, StringBuffer buffer) { + buffer.append(mySeparator); + buffer.append(fragment); + } + + protected int getFragmentIndex(String[] path, int index) { + return path.length > index ? index : -1; + } + }; + String commonHead = headBuilder.execute(); + final int headLimit = headBuilder.getIndex(); + FragmentBuilder tailBuilder = new FragmentBuilder(pathes){ + protected void append(String fragment, StringBuffer buffer) { + buffer.insert(0, fragment + mySeparator); + } + + protected int getFragmentIndex(String[] path, int index) { + int result = path.length - 1 - index; + return result > headLimit ? result : -1; + } + }; + String commonTail = tailBuilder.execute(); + int tailLimit = tailBuilder.getIndex(); + for (int i = 0; i < myView.getItemsSize(); i++) { + ItemWrapper item = myView.getItemByIndex(i); + String special = concat(pathes.get(i), headLimit, tailLimit); + item.setFragments(createFragments(commonHead, special, commonTail)); + } + } + + private String concat(String[] strings, int headLimit, int tailLimit) { + if (strings.length <= headLimit + tailLimit) return null; + StringBuffer buffer = new StringBuffer(); + String separator = ""; + for (int i = headLimit; i < strings.length - tailLimit; i++) { + buffer.append(separator); + buffer.append(strings[i]); + separator = File.separator; + } + return buffer.toString(); + } + + private PathFragment[] createFragments(String head, String special, String tail) { + ArrayList list = new ArrayList(3); + if (head != null) { + if (special != null || tail != null) list.add(new PathFragment(head + File.separatorChar, true)); + else return new PathFragment[]{new PathFragment(head, true)}; + } + if (special != null) { + if (tail != null) list.add(new PathFragment(special + File.separatorChar, false)); + else list.add(new PathFragment(special, false)); + } + if (tail != null) list.add(new PathFragment(tail, true)); + return list.toArray(new PathFragment[list.size()]); + } + + private static abstract class FragmentBuilder { + private final ArrayList myPathes; + private final StringBuffer myBuffer = new StringBuffer(); + private int myIndex; + protected String mySeparator = ""; + + public FragmentBuilder(ArrayList pathes) { + myPathes = pathes; + myIndex = 0; + } + + public int getIndex() { return myIndex; } + + public String execute() { + while (true) { + String commonHead = getCommonFragment(myIndex); + if (commonHead == null) break; + append(commonHead, myBuffer); + mySeparator = File.separator; + myIndex++; + } + return myIndex > 0 ? myBuffer.toString() : null; + } + + protected abstract void append(String fragment, StringBuffer buffer); + + private String getCommonFragment(int count) { + String commonFragment = null; + for (Iterator iterator = myPathes.iterator(); iterator.hasNext();) { + String[] path = iterator.next(); + int index = getFragmentIndex(path, count); + if (index == -1) return null; + if (commonFragment == null) { + commonFragment = path[index]; + continue; + } + if (!Comparing.strEqual(commonFragment, path[index], SystemInfo.isFileSystemCaseSensitive)) return null; + } + return commonFragment; + } + + protected abstract int getFragmentIndex(String[] path, int index); + } + + public class ItemWrapper { + final PsiDirectory myDirectory; + private PathFragment[] myFragments; + private final String myPostfix; + + ItemWrapper(PsiDirectory directory, String postfix) { + myDirectory = directory; + myPostfix = postfix != null && postfix.length() > 0 ? postfix : null; + } + + public PathFragment[] getFragments() { return myFragments; } + + public void setFragments(PathFragment[] fragments) { + myFragments = fragments; + } + + public Icon getIcon(FileIndex fileIndex) { + if (myDirectory != null) { + VirtualFile virtualFile = myDirectory.getVirtualFile(); + if (fileIndex.isInTestSourceContent(virtualFile)){ + return CellAppearanceUtils.TEST_SOURCE_FOLDER; + } + else if (fileIndex.isInSourceContent(virtualFile)){ + return CellAppearanceUtils.SOURCE_FOLDERS_ICON; + } + } + return CellAppearanceUtils.FOLDER_ICON; + } + + public String getPresentableUrl() { + String directoryUrl = myDirectory != null ? myDirectory.getVirtualFile().getPresentableUrl() : ""; + return myPostfix != null ? directoryUrl + myPostfix : directoryUrl; + } + + public PsiDirectory getDirectory() { + return myDirectory; + } + } + + public JComponent getPreferredFocusedComponent(){ + return myView.getComponent(); + } + + public void fillList(PsiDirectory[] directories, PsiDirectory defaultSelection, Project project, String postfixToShow) { + fillList(directories, defaultSelection, project, postfixToShow, null); + } + + public void fillList(PsiDirectory[] directories, PsiDirectory defaultSelection, Project project, Map postfixes) { + fillList(directories, defaultSelection, project, null, postfixes); + } + + void fillList(PsiDirectory[] directories, PsiDirectory defaultSelection, Project project, String postfixToShow, Map postfixes) { + if (myView.getItemsSize() > 0){ + myView.clearItems(); + } + if (defaultSelection == null && directories.length > 0) { + defaultSelection = directories[0]; + } + int selectionIndex = -1; + for(int i = 0; i < directories.length; i++){ + PsiDirectory directory = directories[i]; + if (directory.equals(defaultSelection)) { + selectionIndex = i; + break; + } + } + if (selectionIndex < 0 && directories.length == 1) { + selectionIndex = 0; + } + + if (selectionIndex < 0) { + // find source root corresponding to defaultSelection + PsiDirectory[] sourceDirectories = PsiManager.getInstance(project).getRootDirectories(PsiRootPackageType.SOURCE_PATH); + for(int i = 0; i < sourceDirectories.length; i++){ + PsiDirectory directory = sourceDirectories[i]; + if (isParent(defaultSelection, directory)) { + defaultSelection = directory; + break; + } + } + } + + for(int i = 0; i < directories.length; i++){ + PsiDirectory directory = directories[i]; + final String postfixForDirectory; + if (postfixes == null) { + postfixForDirectory = postfixToShow; + } + else { + postfixForDirectory = postfixes.get(directory); + } + final ItemWrapper itemWrapper = new ItemWrapper(directory, postfixForDirectory); + myView.addItem(itemWrapper); + if (selectionIndex < 0 && isParent(directory, defaultSelection)) { + selectionIndex = i; + } + } + buildFragments(); + myView.listFilled(); + if (directories.length > 0) { + myView.selectItemByIndex(selectionIndex); + } + else { + myView.clearSelection(); + } + enableButtons(); + myView.getComponent().repaint(); + } + + private boolean isParent(PsiDirectory directory, PsiDirectory parentCandidate) { + while (directory != null) { + if (directory.equals(parentCandidate)) return true; + directory = directory.getParentDirectory(); + } + return false; + } + + private void enableButtons() { + setOKActionEnabled(myView.getSelectedItem() != null); + } + + public PsiDirectory getSelectedDirectory() { + ItemWrapper wrapper = myView.getSelectedItem(); + if (wrapper == null) return null; + return wrapper.myDirectory; + } + + + public static class PathFragment { + private final String myText; + private final boolean myCommon; + + public PathFragment(String text, boolean isCommon) { + myText = text; + myCommon = isCommon; + } + + public String getText() { + return myText; + } + + public boolean isCommon() { + return myCommon; + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserModuleTreeView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserModuleTreeView.java new file mode 100644 index 00000000000..1e6aaff46cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserModuleTreeView.java @@ -0,0 +1,175 @@ +package com.intellij.ide.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiDirectory; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.Tree; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.*; +import java.util.*; + +/** + * @author dsl + */ +public class DirectoryChooserModuleTreeView implements DirectoryChooserView { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.DirectoryChooserModuleTreeView"); + + private final Tree myTree; + private final List myItems = new ArrayList(); + private final Map myItemNodes = new HashMap(); + private final Map myModuleNodes = new HashMap(); + private final DefaultMutableTreeNode myRootNode; + private ProjectFileIndex myFileIndex; + + public DirectoryChooserModuleTreeView(Project project) { + myRootNode = new DefaultMutableTreeNode(); + myTree = new Tree(myRootNode); + myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + myFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.setCellRenderer(new MyTreeCellRenderer()); + new TreeSpeedSearch(myTree) { + public boolean isMatchingElement(Object element, String pattern) { + if (element instanceof TreePath) { + final Object userObject = ((DefaultMutableTreeNode)((TreePath)element).getLastPathComponent()).getUserObject(); + if (userObject instanceof Module) { + return ((Module)userObject).getName().toLowerCase().startsWith(pattern.toLowerCase()); + } + } + return false; + } + }; + } + + public void clearItems() { + myRootNode.removeAllChildren(); + myItems.clear(); + myItemNodes.clear(); + myModuleNodes.clear(); + } + + public JComponent getComponent() { + return myTree; + } + + public void onSelectionChange(final Runnable runnable) { + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + runnable.run(); + } + }); + } + + public DirectoryChooser.ItemWrapper getItemByIndex(int i) { + return myItems.get(i); + } + + public void clearSelection() { + myTree.clearSelection(); + } + + public void selectItemByIndex(int selectionIndex) { + if (selectionIndex < 0) { + myTree.clearSelection(); + } else { + final DirectoryChooser.ItemWrapper itemWrapper = myItems.get(selectionIndex); + final DefaultMutableTreeNode node = myItemNodes.get(itemWrapper); + final TreePath treePath = expandNode(node); + myTree.setSelectionPath(treePath); + myTree.scrollPathToVisible(treePath); + } + } + + private TreePath expandNode(final DefaultMutableTreeNode node) { + final TreeNode[] path = node.getPath(); + final TreePath treePath = new TreePath(path); + TreePath expandPath = treePath; + if (myTree.getModel().isLeaf(expandPath.getLastPathComponent())) { + expandPath = expandPath.getParentPath(); + } + myTree.expandPath(expandPath); + return treePath; + } + + public void addItem(DirectoryChooser.ItemWrapper itemWrapper) { + myItems.add(itemWrapper); + final PsiDirectory directory = itemWrapper.getDirectory(); + final Module module = myFileIndex.getModuleForFile(directory.getVirtualFile()); + DefaultMutableTreeNode node = myModuleNodes.get(module); + if (node == null) { + node = new DefaultMutableTreeNode(module, true); + final Enumeration enumeration = myRootNode.children(); + + final int index = Collections.binarySearch(Collections.list(enumeration), node, new Comparator() { + public int compare(DefaultMutableTreeNode node1, DefaultMutableTreeNode node2) { + return ((Module)node1.getUserObject()).getName().compareTo(((Module)node2.getUserObject()).getName()); + } + }); + final int insertionPoint = -(index+1); + LOG.assertTrue(0 <= insertionPoint && insertionPoint <= myRootNode.getChildCount()); + myRootNode.insert(node, insertionPoint); + ((DefaultTreeModel)myTree.getModel()).nodeStructureChanged(myRootNode); + myModuleNodes.put(module, node); + } + final DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(itemWrapper, false); + myItemNodes.put(itemWrapper, itemNode); + node.add(itemNode); + ((DefaultTreeModel)myTree.getModel()).nodeStructureChanged(node); + } + + public void listFilled() { + if (myModuleNodes.size() == 1) { + final Iterator iterator = myItemNodes.values().iterator(); + if (iterator.hasNext()){ + final DefaultMutableTreeNode node = iterator.next(); + expandNode(node); + } + } + } + + public int getItemsSize() { + return myItems.size(); + } + + public DirectoryChooser.ItemWrapper getSelectedItem() { + final TreePath selectionPath = myTree.getSelectionPath(); + if (selectionPath == null) return null; + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPath.getLastPathComponent(); + return node.getUserObject() instanceof DirectoryChooser.ItemWrapper ? (DirectoryChooser.ItemWrapper)node.getUserObject() : null; + } + + + private class MyTreeCellRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer(JTree tree, Object nodeValue, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + final Object value = ((DefaultMutableTreeNode)nodeValue).getUserObject(); + if (value instanceof DirectoryChooser.ItemWrapper) { + DirectoryChooser.ItemWrapper wrapper = (DirectoryChooser.ItemWrapper)value; + DirectoryChooser.PathFragment[] fragments = wrapper.getFragments(); + for (int i = 0; i < fragments.length; i++) { + DirectoryChooser.PathFragment fragment = fragments[i]; + append(fragment.getText(), fragment.isCommon() ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + } + setIcon(wrapper.getIcon(myFileIndex)); + } + else if (value instanceof Module) { + final Module module = (Module)value; + append(module.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + setIcon(IconUtilEx.getIcon(module, expanded ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED)); + } + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserView.java new file mode 100644 index 00000000000..e559f2607cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryChooserView.java @@ -0,0 +1,28 @@ +package com.intellij.ide.util; + +import javax.swing.*; + +/** + * @author dsl + */ +public interface DirectoryChooserView { + JComponent getComponent(); + + void onSelectionChange(Runnable runnable); + + DirectoryChooser.ItemWrapper getItemByIndex(int i); + + void clearSelection(); + + void selectItemByIndex(int selectionIndex); + + void addItem(DirectoryChooser.ItemWrapper itemWrapper); + + void listFilled(); + + void clearItems(); + + int getItemsSize(); + + DirectoryChooser.ItemWrapper getSelectedItem(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryUtil.java new file mode 100644 index 00000000000..ccbc36cc868 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/DirectoryUtil.java @@ -0,0 +1,85 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.util.IncorrectOperationException; + +import java.io.File; +import java.util.StringTokenizer; + +public class DirectoryUtil { + + + /** + * Creates the directory with the given path via PSI, including any + * necessary but nonexistent parent directories. Must be run in write action. + * @param path directory path in the local file system; separators must be '/' + * @return true if path exists or has been created as the result of this method call; false otherwise + */ + public static PsiDirectory mkdirs(PsiManager manager, String path) throws IncorrectOperationException{ + if (File.separatorChar != '/') { + if (path.indexOf(File.separatorChar) != -1) { + throw new IllegalArgumentException("separators must be '/'; path is " + path); + } + } + + String existingPath = path; + + PsiDirectory directory = null; + + // find longest existing path + while (existingPath.length() > 0) { + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(existingPath); + if (file != null) { + directory = manager.findDirectory(file); + if (directory == null) { + return null; + } + break; + } + + if (StringUtil.endsWithChar(existingPath, '/')) { + existingPath = existingPath.substring(0, existingPath.length() - 1); + if (SystemInfo.isWindows && existingPath.length() == 2 && existingPath.charAt(1) == ':') { + return null; + } + } + + int index = existingPath.lastIndexOf('/'); + if (index == -1) { + // nothing to do more + return null; + } + + existingPath = existingPath.substring(0, index); + } + + if (directory == null) { + return null; + } + + if (existingPath.equals(path)) { + return directory; + } + + String postfix = path.substring(existingPath.length() + 1, path.length()); + StringTokenizer tokenizer = new StringTokenizer(postfix, "/"); + while (tokenizer.hasMoreTokens()) { + String name = tokenizer.nextToken(); + + PsiDirectory subdirectory = directory.createSubdirectory(name); + if (subdirectory == null) { + return null; + } + + directory = subdirectory; + } + + return directory; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditSourceUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditSourceUtil.java new file mode 100644 index 00000000000..7eb05275a5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditSourceUtil.java @@ -0,0 +1,35 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class EditSourceUtil { + public static Navigatable getDescriptor(final PsiElement element) { + if (element == null) { + return null; + } + if (!element.isValid()) { + return null; + } + + PsiElement navigationElement = element.getNavigationElement(); + + PsiFile psiFile = navigationElement instanceof PsiFile ? (PsiFile)navigationElement : navigationElement.getContainingFile(); + if (psiFile == null) { + return null; + } + + int offset = -1; + if (!(navigationElement instanceof PsiFile)) { + offset = navigationElement.getTextOffset(); + } + VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile == null) { + return null; + } + return new OpenFileDescriptor(element.getProject(), virtualFile, offset); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditorHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditorHelper.java new file mode 100644 index 00000000000..18b5303ff9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/EditorHelper.java @@ -0,0 +1,27 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class EditorHelper { + public static Editor openInEditor(PsiElement element) { + PsiFile file; + int offset; + if (element instanceof PsiFile){ + file = (PsiFile)element; + offset = -1; + } + else{ + file = element.getContainingFile(); + offset = element.getTextOffset(); + } + + OpenFileDescriptor descriptor = new OpenFileDescriptor(element.getProject(), file.getVirtualFile(), offset); + Project project = element.getProject(); + return FileEditorManager.getInstance(project).openTextEditor(descriptor, false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ElementsChooser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ElementsChooser.java new file mode 100644 index 00000000000..97a3f254ab0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ElementsChooser.java @@ -0,0 +1,401 @@ +package com.intellij.ide.util; + +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.*; +import java.util.List; + +public class ElementsChooser extends JPanel { + private JTable myTable = null; + private MyTableModel myTableModel = null; + private boolean myColorUnmarkedElements = true; + private List> myListeners = new ArrayList>(); + private Map myElementToPropertiesMap = new HashMap(); + + public ElementsChooser() { + this(null, false); + } + + public static interface ElementsMarkListener { + void elementMarkChanged(T element, boolean isMarked); + } + + public ElementsChooser(List elements, boolean marked) { + super(new BorderLayout()); + + myTableModel = new MyTableModel(); + myTable = new Table(myTableModel); + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.setTableHeader(null); + myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + myTable.setColumnSelectionAllowed(false); + JScrollPane pane = ScrollPaneFactory.createScrollPane(myTable); + pane.setPreferredSize(new Dimension(100, 155)); + int width = new JCheckBox().getPreferredSize().width; + TableColumnModel columnModel = myTable.getColumnModel(); + + TableColumn checkMarkColumn = columnModel.getColumn(myTableModel.CHECK_MARK); + checkMarkColumn.setPreferredWidth(width); + checkMarkColumn.setMaxWidth(width); + checkMarkColumn.setCellRenderer(new CheckMarkColumnCellRenderer(myTable.getDefaultRenderer(Boolean.class))); + columnModel.getColumn(myTableModel.ELEMENT).setCellRenderer(new MyElementColumnCellRenderer()); + + add(pane, BorderLayout.CENTER); + myTable.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + final int[] selectedRows = myTable.getSelectedRows(); + boolean currentlyMarked = true; + for (int idx = 0; idx < selectedRows.length; idx++) { + currentlyMarked = myTableModel.isElementMarked(selectedRows[idx]); + if (!currentlyMarked) { + break; + } + } + myTableModel.setMarked(selectedRows, !currentlyMarked); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), + JComponent.WHEN_FOCUSED + ); + + setElements(elements, marked); + } + + private int[] mySavedSelection = null; + public void saveSelection() { + mySavedSelection = myTable.getSelectedRows(); + } + + public void restoreSelection() { + if (mySavedSelection != null) { + TableUtil.selectRows(myTable, mySavedSelection); + mySavedSelection = null; + } + } + + public boolean isColorUnmarkedElements() { + return myColorUnmarkedElements; + } + + public void setColorUnmarkedElements(boolean colorUnmarkedElements) { + myColorUnmarkedElements = colorUnmarkedElements; + } + + public void addElementsMarkListener(ElementsMarkListener listener) { + myListeners.add(listener); + } + + public void removeElementsMarkListener(ElementsMarkListener listener) { + myListeners.remove(listener); + } + + public void addListSelectionListener(ListSelectionListener listener) { + myTable.getSelectionModel().addListSelectionListener(listener); + } + public void removeListSelectionListener(ListSelectionListener listener) { + myTable.getSelectionModel().removeListSelectionListener(listener); + } + + public void addElement(T element, final boolean isMarked) { + addElement(element, isMarked, null); + } + + public static interface ElementProperties { + Icon getIcon(); + Color getColor(); + } + public void addElement(T element, final boolean isMarked, ElementProperties elementProperties) { + myTableModel.addElement(element, isMarked); + myElementToPropertiesMap.put(element, elementProperties); + final int row = myTableModel.getRowCount() - 1; + myTable.getSelectionModel().setSelectionInterval(row, row); + myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true)); + myTable.requestFocus(); + } + + public void setElements(List elements, boolean marked) { + myTableModel.clear(); + myTableModel.addElements(elements, marked); + } + + public T getSelectedElement() { + final int selectedRow = myTable.getSelectedRow(); + return selectedRow < 0? null : myTableModel.getElementAt(selectedRow); + } + + public List getSelectedElements() { + final List elements = new ArrayList(); + final int[] selectedRows = myTable.getSelectedRows(); + for (int idx = 0; idx < selectedRows.length; idx++) { + int selectedRow = selectedRows[idx]; + if (selectedRow < 0) { + continue; + } + elements.add(myTableModel.getElementAt(selectedRow)); + } + return elements; + } + + public void selectElements(List elements) { + if (elements.size() == 0) { + myTable.clearSelection(); + return; + } + final int[] rows = new int[elements.size()]; + int index = 0; + for (Iterator it = elements.iterator(); it.hasNext();) { + rows[index++] = myTableModel.getElementRow(it.next()); + } + TableUtil.selectRows(myTable, rows); + } + + public List getMarkedElements() { + final int count = myTableModel.getRowCount(); + List elements = new ArrayList(); + for (int idx = 0; idx < count; idx++) { + final T element = myTableModel.getElementAt(idx); + if (myTableModel.isElementMarked(idx)) { + elements.add(element); + } + } + return elements; + } + + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + myTable.setRowSelectionAllowed(enabled); + myTableModel.fireTableDataChanged(); + } + + public void stopEditing() { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + + public JComponent getComponent() { + return myTable; + } + + public void setAllElementsMarked(boolean marked) { + final int[] rows = new int[myTableModel.getRowCount()]; + for (int idx = 0; idx < rows.length; idx++) { + rows[idx] = idx; + } + myTableModel.setMarked(rows, marked); + } + + private void notifyElementMarked(T element, boolean isMarked) { + final Object[] listeners = myListeners.toArray(); + for (int i = 0; i < listeners.length; i++) { + ElementsMarkListener listener = (ElementsMarkListener)listeners[i]; + listener.elementMarkChanged(element, isMarked); + } + } + + public void clear() { + myTableModel.clear(); + myElementToPropertiesMap.clear(); + } + + public int getElementCount() { + return myTableModel.getRowCount(); + } + + public T getElementAt(int row) { + return myTableModel.getElementAt(row); + } + + private final class MyTableModel extends AbstractTableModel { + private final List myElements = new ArrayList(); + private final Map myMarkedMap = new HashMap(); + public final int CHECK_MARK = 0; + public final int ELEMENT = 1; + + public T getElementAt(int index) { + return myElements.get(index); + } + + public boolean isElementMarked(int index) { + final T element = myElements.get(index); + final Boolean isMarked = myMarkedMap.get(element); + return isMarked.booleanValue(); + } + + protected void addElement(T element, boolean isMarked) { + myElements.add(element); + myMarkedMap.put(element, isMarked? Boolean.TRUE : Boolean.FALSE); + int row = myElements.size() - 1; + fireTableRowsInserted(row, row); + } + + protected void addElements(List elements, boolean isMarked) { + if (elements == null || elements.size() == 0) { + return; + } + for (Iterator it = elements.iterator(); it.hasNext();) { + final T element = it.next(); + myElements.add(element); + myMarkedMap.put(element, isMarked? Boolean.TRUE : Boolean.FALSE); + } + fireTableRowsInserted(myElements.size() - elements.size(), myElements.size() - 1); + } + + public void removeElement(T element) { + final boolean reallyRemoved = myElements.remove(element); + if (reallyRemoved) { + myMarkedMap.remove(element); + fireTableDataChanged(); + } + } + + public int getElementRow(T element) { + return myElements.indexOf(element); + } + + public void removeRows(int[] rows) { + final List toRemove = new ArrayList(); + for (int idx = 0; idx < rows.length; idx++) { + final T element = myElements.get(rows[idx]); + toRemove.add(element); + myMarkedMap.remove(element); + } + myElements.removeAll(toRemove); + fireTableDataChanged(); + } + + public int getRowCount() { + return myElements.size(); + } + + public int getColumnCount() { + return 2; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + T element = myElements.get(rowIndex); + if (columnIndex == ELEMENT) { + return element; + } + if (columnIndex == CHECK_MARK) { + return myMarkedMap.get(element); + } + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (columnIndex == CHECK_MARK) { + setMarked(rowIndex, ((Boolean)aValue).booleanValue()); + } + } + + private void setMarked(int rowIndex, final boolean marked) { + final T element = myElements.get(rowIndex); + final Boolean newValue = marked? Boolean.TRUE : Boolean.FALSE; + final Boolean prevValue = myMarkedMap.put(element, newValue); + fireTableRowsUpdated(rowIndex, rowIndex); + if (!newValue.equals(prevValue)) { + notifyElementMarked(element, marked); + } + } + + private void setMarked(int[] rows, final boolean marked) { + if (rows == null || rows.length == 0) { + return; + } + int firstRow = Integer.MAX_VALUE; + int lastRow = Integer.MIN_VALUE; + final Boolean newValue = marked? Boolean.TRUE : Boolean.FALSE; + for (int idx = 0; idx < rows.length; idx++) { + final int row = rows[idx]; + final T element = myElements.get(row); + final Boolean prevValue = myMarkedMap.put(element, newValue); + if (!newValue.equals(prevValue)) { + notifyElementMarked(element, newValue.booleanValue()); + } + firstRow = Math.min(firstRow, row); + lastRow = Math.max(lastRow, row); + } + fireTableRowsUpdated(firstRow, lastRow); + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECK_MARK) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + if (ElementsChooser.this.isEnabled()) { + return (columnIndex == CHECK_MARK); + } + return false; + } + + public void clear() { + myElements.clear(); + myMarkedMap.clear(); + fireTableDataChanged(); + } + } + + protected String getItemText(T value) { + return value != null ? value.toString() : ""; + } + + private class MyElementColumnCellRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + final Color color = UIManager.getColor("Table.focusCellBackground"); + UIManager.put("Table.focusCellBackground", table.getSelectionBackground()); + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setText(getItemText((T)value)); + if (component instanceof JLabel) { + ((JLabel)component).setBorder(noFocusBorder); + } + UIManager.put("Table.focusCellBackground", color); + final MyTableModel model = (MyTableModel)table.getModel(); + component.setEnabled(ElementsChooser.this.isEnabled() && (myColorUnmarkedElements? model.isElementMarked(row) : true)); + ElementProperties properties = myElementToPropertiesMap.get(value); + if (properties != null) { + if (component instanceof JLabel) { + ((JLabel)component).setIcon(properties.getIcon()); + } + component.setForeground(properties.getColor()); + } + else { + if (component instanceof JLabel) { + ((JLabel)component).setIcon(null); + } + component.setForeground(UIManager.getColor("Table.cellForeground")); + } + return component; + } + } + + private class CheckMarkColumnCellRenderer extends DefaultTableCellRenderer { + private TableCellRenderer myDelegate; + + public CheckMarkColumnCellRenderer(TableCellRenderer delegate) { + myDelegate = delegate; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + component.setEnabled(ElementsChooser.this.isEnabled()); + return component; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ExportToFileUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ExportToFileUtil.java new file mode 100644 index 00000000000..5a35cd3fd9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/ExportToFileUtil.java @@ -0,0 +1,212 @@ +package com.intellij.ide.util; + +import com.intellij.ide.ExporterToTextFile; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.WindowManager; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.TooManyListenersException; + +public class ExportToFileUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.ExportToFileUtil"); + + public static void exportTextToFile(Project project, String fileName, String textToExport) { + String prepend = ""; + File file = new File(fileName); + if (file.exists()) { + int result = Messages.showDialog( + project, + "File " + fileName + " already exists\nDo you want overwrite it or to append?", + "Warning", + new String[]{"Overwrite", "Append", "Cancel"}, + 0, + Messages.getWarningIcon() + ); + + if (result != 1 && result != 0) return; + if (result == 1) { + char[] buf = new char[(int)file.length()]; + try { + FileReader reader = new FileReader(fileName); + try { + reader.read(buf, 0, (int)file.length()); + prepend = new String(buf) + System.getProperty("line.separator"); + } + finally { + reader.close(); + } + } + catch (IOException e) { + } + } + } + + try { + FileWriter writer = new FileWriter(fileName); + try { + writer.write(prepend + textToExport); + } + finally { + writer.close(); + } + } + catch (IOException e) { + Messages.showMessageDialog( + project, + "Error writing to file: " + fileName, + "Error", + Messages.getErrorIcon() + ); + } + } + + public static class ExportDialogBase extends DialogWrapper { + private Project myProject; + private ExporterToTextFile myExporter; + protected JTextArea myTextArea; + protected JScrollPane myTextScrollPane; + protected JTextField myTfFile; + protected JButton myFileButton; + + public ExportDialogBase(Project project, ExporterToTextFile exporter) { + super(project, true); + myProject = project; + myExporter = exporter; + + myTfFile = new JTextField(); + myFileButton = new FixedSizeButton(myTfFile); + + setHorizontalStretch(1.5f); + setTitle("Export Preview"); + setOKButtonText("Save"); + setButtonsMargin(null); + init(); + try { + myExporter.addSettingsChangedListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + initText(); + } + }); + } + catch (TooManyListenersException e) { + LOG.error(e); + } + initText(); + } + + private void initText() { + myTextArea.setText(myExporter.getReportText()); + myTextArea.getCaret().setDot(0); + } + + protected JComponent createCenterPanel() { + myTextArea = new JTextArea(); + myTextArea.setEditable(false); + myTextScrollPane = new JScrollPane(myTextArea); + myTextScrollPane.setPreferredSize(new Dimension(400, 300)); + return myTextScrollPane; + } + + protected JComponent createNorthPanel() { + JPanel filePanel = createFilePanel(myTfFile, myFileButton); + JComponent settingsPanel = myExporter.getSettingsEditor(); + if (settingsPanel == null) return filePanel; + JPanel northPanel = new JPanel(new BorderLayout()); + northPanel.add(filePanel, BorderLayout.NORTH); + northPanel.add(settingsPanel, BorderLayout.CENTER); + return northPanel; + } + + protected JPanel createFilePanel(JTextField textField, JButton button) { + JPanel panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + JLabel promptLabel = new JLabel("Export to file: "); + gbConstraints.weightx = 0; + panel.add(promptLabel, gbConstraints); + gbConstraints.weightx = 1; + panel.add(textField, gbConstraints); + gbConstraints.fill = 0; + gbConstraints.weightx = 0; + gbConstraints.insets = new Insets(0, 0, 0, 0); + panel.add(button, gbConstraints); + + String defaultFilePath = myExporter.getDefaultFilePath(); + defaultFilePath = ((ProjectEx)myProject).getExpandMacroReplacements() + .substitute(defaultFilePath, SystemInfo.isFileSystemCaseSensitive).replace('/', File.separatorChar); + textField.setText(defaultFilePath); + + button.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + browseFile(); + } + } + ); + + return panel; + } + + protected void browseFile() { + JFileChooser chooser = new JFileChooser(); + if (myTfFile != null) { + chooser.setCurrentDirectory(new File(myTfFile.getText())); + } + chooser.showOpenDialog(WindowManager.getInstance().suggestParentWindow(myProject)); + if (chooser.getSelectedFile() != null) { + myTfFile.setText(chooser.getSelectedFile().getAbsolutePath()); + } + } + + public String getText() { + return myTextArea.getText(); + } + + public void setFileName(String s) { + myTfFile.setText(s); + } + + public String getFileName() { + return myTfFile.getText(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), new CopyToClipboardAction(), getCancelAction()}; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.ide.util.ExportDialog"; + } + + protected class CopyToClipboardAction extends AbstractAction { + public CopyToClipboardAction() { + super("&Copy"); + putValue(AbstractAction.SHORT_DESCRIPTION, "Copy text to clipboard"); + } + + public void actionPerformed(ActionEvent e) { + String s = StringUtil.convertLineSeparators(myTextArea.getText(), "\n"); + CopyPasteManager.getInstance().setContents(new StringSelection(s)); + } + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FQNameCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FQNameCellRenderer.java new file mode 100644 index 00000000000..17534a26704 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FQNameCellRenderer.java @@ -0,0 +1,65 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; + +public class FQNameCellRenderer extends SimpleColoredComponent implements ListCellRenderer{ + private Font FONT; + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.FQNameCellRenderer"); + private static final Icon ourStaticThingIcon = IconLoader.getIcon("/nodes/static.png"); + + public FQNameCellRenderer() { + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + FONT = new Font(scheme.getEditorFontName(), Font.PLAIN, scheme.getEditorFontSize()); + setOpaque(true); + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus){ + + clear(); + + if (value instanceof PsiClass) { + PsiClass aClass = (PsiClass)value; + setIcon(aClass.getIcon(0)); + SimpleTextAttributes attributes; + if (aClass.getQualifiedName() != null) { + if (aClass.isDeprecated()) { + attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_STRIKEOUT, null); + } + else { + attributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; + } + append(aClass.getQualifiedName(), attributes); + } + } else { + LOG.assertTrue(value instanceof String); + String qName = (String)value; + append(qName, SimpleTextAttributes.REGULAR_ATTRIBUTES); + setIcon(ourStaticThingIcon); + } + + setFont(FONT); + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } + else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FileStructureDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FileStructureDialog.java new file mode 100644 index 00000000000..7592690b451 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/FileStructureDialog.java @@ -0,0 +1,293 @@ + +package com.intellij.ide.util; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.ide.commander.CommanderPanel; +import com.intellij.ide.commander.ProjectListBuilder; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.smartTree.SmartTreeStructure; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.pom.Navigatable; +import com.intellij.psi.*; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.SpeedSearchBase; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +public class FileStructureDialog extends DialogWrapper { + private final Editor myEditor; + private Navigatable myNavigatable; + private final Project myProject; + private MyCommanderPanel myCommanderPanel; + private final TreeModel myTreeModel; + + private static final String ourPropertyKey = "FileStructure.narrowDown"; + private boolean myShouldNarrowDown = false; + + public FileStructureDialog(TreeModel structureViewModel, Editor editor, Project project, Navigatable navigatable) { + super(project, true); + myProject = project; + myEditor = editor; + myNavigatable = navigatable; + myTreeModel = structureViewModel; + + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument()); + + final PsiElement elementAtCursor = getElementAtCursor(psiFile); + + //myDialog.setUndecorated(true); + init(); + + if (elementAtCursor != null) { + if (elementAtCursor instanceof PsiClass) { + myCommanderPanel.getBuilder().enterElement(elementAtCursor, ((PsiClass)elementAtCursor).getContainingFile().getVirtualFile()); + } + else { + myCommanderPanel.getBuilder().selectElement(elementAtCursor); + } + } + + AnAction editSourceAction = ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE); + editSourceAction.registerCustomShortcutSet(editSourceAction.getShortcutSet(), myCommanderPanel); + + } + + protected Border createContentPaneBorder(){ + return null; + } + + protected void dispose() { + myCommanderPanel.dispose(); + super.dispose(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.ide.util.FileStructureDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCommanderPanel); + } + + private PsiElement getElementAtCursor(final PsiFile psiFile) { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + PsiElement element = psiFile.findElementAt(myEditor.getCaretModel().getOffset()); + for (; element != null; element = element.getParent()) { + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + PsiElement parent = method.getParent(); + if (parent instanceof PsiClass) { + PsiClass psiClass = (PsiClass)parent; + String name = psiClass.getQualifiedName(); + if (name == null) continue; + return method; + } + } + else if (element instanceof PsiField) { + PsiField field = (PsiField)element; + PsiElement parent = field.getParent(); + if (parent instanceof PsiClass) { + PsiClass psiClass = (PsiClass)parent; + String name = psiClass.getQualifiedName(); + if (name == null) continue; + return field; + } + } + else if (element instanceof PsiClass) { + PsiClass psiClass = (PsiClass)element; + String name = psiClass.getQualifiedName(); + if (name == null) continue; + return psiClass; + } + } + return null; + } + + protected JComponent createCenterPanel() { + myCommanderPanel = new MyCommanderPanel(myProject); + + PsiElement parent = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument()); + if (parent instanceof PsiJavaFile) { + PsiClass[] classes = ((PsiJavaFile)parent).getClasses(); + if (classes.length == 1) { + parent = classes[0]; + } + } + if (parent instanceof PsiAspectFile) { + PsiAspect[] aspects = ((PsiAspectFile) parent).getAspects(); + if (aspects.length == 1) { + parent = aspects[0]; + } + } + + AbstractTreeStructure treeStructure = new MyStructureTreeStructure(); + myCommanderPanel.setBuilder(new ProjectListBuilder(myProject, myCommanderPanel, treeStructure, null, false){ + protected boolean nodeIsAcceptableForElement(AbstractTreeNode node, Object element) { + return Comparing.equal(((StructureViewTreeElement)node.getValue()).getValue(), element); + } + + protected List getAllAcceptableNodes(final Object[] childElements, VirtualFile file) { + ArrayList result = new ArrayList(); + for (int i = 0; i < childElements.length; i++) { + result.add((AbstractTreeNode)childElements[i]); + } + return result; + } + }); + myCommanderPanel.setTitlePanelVisible(false); + + //ShortcutSet shortcutSet = ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(); + //new AnAction() { + // public void actionPerformed(AnActionEvent e){ + // myCommanderPanel.performEditSourceAction(); + // } + //}.registerCustomShortcutSet(shortcutSet, myCommanderPanel); + myCommanderPanel.setPreferredSize(new Dimension(400,500)); + + JPanel panel = new JPanel(new GridBagLayout()); + final JCheckBox checkBox = new JCheckBox("Narrow down the list on typing"); + checkBox.setSelected("true".equals(PropertiesComponent.getInstance().getValue(ourPropertyKey))); + checkBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e){ + myShouldNarrowDown = checkBox.isSelected(); + PropertiesComponent.getInstance().setValue(ourPropertyKey, myShouldNarrowDown ? "true" : "false"); + + ProjectListBuilder builder = (ProjectListBuilder)myCommanderPanel.getBuilder(); + if (builder == null) { + return; + } + builder.addUpdateRequest(); + } + }); + checkBox.setMnemonic('N'); + checkBox.setFocusable(false); + + panel.add(checkBox, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0,5,0,5),0,0)); + panel.add(myCommanderPanel, new GridBagConstraints(0,1,1,1,1,1,GridBagConstraints.WEST,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0)); + + return panel; + } + + protected JComponent createSouthPanel() { + return null; + } + + public CommanderPanel getPanel() { + return myCommanderPanel; + } + + private class MyCommanderPanel extends CommanderPanel implements DataProvider { + protected boolean shouldDrillDownOnEmptyElement(final Object value) { + return false; + } + + public MyCommanderPanel(Project _project) { + super(_project, null); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myListSpeedSearch.addChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt){ + ProjectListBuilder builder = (ProjectListBuilder)getBuilder(); + if (builder == null) { + return; + } + builder.addUpdateRequest(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run(){ + int index = myList.getSelectedIndex(); + if (index != -1 && index < myList.getModel().getSize()) { + myList.clearSelection(); + ListScrollingUtil.selectItem(myList, index); + } + else { + ListScrollingUtil.ensureSelectionExists(myList); + } + } + }); + } + }); + + + } + + protected void onNavigatePerformed() { + close(CANCEL_EXIT_CODE); + } + + public Object getData(String dataId) { + Object selectedElement = myCommanderPanel.getSelectedValue(); + + if (selectedElement instanceof TreeElement) selectedElement = ((StructureViewTreeElement)selectedElement).getValue(); + + if (DataConstants.NAVIGATABLE.equals(dataId)) { + return selectedElement instanceof Navigatable ? selectedElement : myNavigatable; + } + return getDataImpl(dataId); + } + + public String getEnteredPrefix(){ + return myListSpeedSearch.getEnteredPrefix(); + } + } + + private class MyStructureTreeStructure extends SmartTreeStructure { + public MyStructureTreeStructure() { + super(myProject, myTreeModel); + } + + public Object[] getChildElements(Object element){ + Object[] childElements = super.getChildElements(element); + + if (!myShouldNarrowDown) { + return childElements; + } + + String enteredPrefix = myCommanderPanel.getEnteredPrefix(); + if (enteredPrefix == null) { + return childElements; + } + + ArrayList filteredElements = new ArrayList(childElements.length); + SpeedSearchBase.SpeedSearchComparator speedSearchComparator = new SpeedSearchBase.SpeedSearchComparator(); + + for (int i = 0; i < childElements.length; i++) { + Object child = childElements[i]; + if (child instanceof AbstractTreeNode) { + Object value = ((AbstractTreeNode)child).getValue(); + if (value instanceof TreeElement) { + String name = ((TreeElement)value).getPresentation().getPresentableText(); + if (name == null) { + continue; + } + if (!speedSearchComparator.doCompare(enteredPrefix, name)) { + continue; + } + } + } + filteredElements.add(child); + } + return filteredElements.toArray(new Object[filteredElements.size()]); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/GotoLineNumberDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/GotoLineNumberDialog.java new file mode 100644 index 00000000000..cbdf9542909 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/GotoLineNumberDialog.java @@ -0,0 +1,98 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.*; + +public class GotoLineNumberDialog extends DialogWrapper { + private JLabel myLabel; + private JTextField myField; + private Editor myEditor; + + public GotoLineNumberDialog(Project project, Editor editor){ + super(project, true); + myEditor = editor; + setTitle("Go to Line"); + init(); + } + + protected void doOKAction(){ + int lineNumber = getLineNumber(); + if (lineNumber <= 0) return; + int columnNumber = getColumnNumber(myEditor.getCaretModel().getLogicalPosition().column); + myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(lineNumber - 1, columnNumber - 1)); + myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + myEditor.getSelectionModel().removeSelection(); + super.doOKAction(); + } + + private int getColumnNumber(int defaultValue) { + String text = getText(); + int columnIndex = text.indexOf(':'); + if (columnIndex == -1) return defaultValue; + try { + return Integer.parseInt(text.substring(columnIndex + 1)); + } catch (NumberFormatException e) {} + return defaultValue; + } + + private int getLineNumber() { + try { + String text = getText(); + int columnIndex = text.indexOf(':'); + text = columnIndex == -1 ? text : text.substring(0, columnIndex); + return Integer.parseInt(text); + } catch (NumberFormatException e) { + return -1; + } + } + + public JComponent getPreferredFocusedComponent() { + return myField; + } + + protected JComponent createCenterPanel() { + return null; + } + + private String getText() { + return myField.getText(); + } + + protected JComponent createNorthPanel() { + class MyTextField extends JTextField { + public MyTextField() { + super(""); + } + + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + return new Dimension(200, d.height); + } + } + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 0, 8, 0); + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.anchor = GridBagConstraints.EAST; + myLabel = new JLabel("Line number: "); + panel.add(myLabel, gbConstraints); + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + myField = new MyTextField(); + panel.add(myField, gbConstraints); + myField.setToolTipText("Syntax: [:]"); + + return panel; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/JavaUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/JavaUtil.java new file mode 100644 index 00000000000..648c60d1218 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/JavaUtil.java @@ -0,0 +1,193 @@ +package com.intellij.ide.util; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class JavaUtil { + + public static List> suggestRoots(File dir) { + ArrayList> foundDirectories = new ArrayList>(); + try{ + suggestRootsImpl(dir, dir, foundDirectories); + } + catch(PathFound found){ + } + return foundDirectories; + } + + private static class PathFound extends Exception { + public File myDirectory; + + public PathFound(File directory) { + myDirectory = directory; + } + } + + private static void suggestRootsImpl(File base, File dir, ArrayList> foundDirectories) throws PathFound { + if (!dir.isDirectory()) { + return; + } + FileTypeManager typeManager = FileTypeManager.getInstance(); + if (typeManager.isFileIgnored(dir.getName())) { + return; + } + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator != null) { + if (progressIndicator.isCanceled()) { + return; + } + progressIndicator.setText2(dir.getPath()); + } + + File[] list = dir.listFiles(); + if (list == null || list.length == 0) { + return; + } + for(int i = 0; i < list.length; i++) { + File child = list[i]; + if (child.isFile()) { + FileType type = typeManager.getFileTypeByFileName(child.getName()); + if (StdFileTypes.JAVA == type) { + if (progressIndicator != null && progressIndicator.isCanceled()) { + return; + } + Pair root = suggestRootForJavaFile(child); + if (root != null) { + String packagePrefix = getPackagePrefix(base, root); + if (packagePrefix == null) { + foundDirectories.add(root); + } + else { + foundDirectories.add(Pair.create(base, packagePrefix)); + } + throw new PathFound(root.getFirst()); + } + else { + return; + } + } + } + } + + for(int i = 0; i < list.length; i++) { + File child = list[i]; + if (child.isDirectory()){ + try{ + suggestRootsImpl(base, child, foundDirectories); + } + catch(PathFound found){ + if (!found.myDirectory.equals(child)) { + throw found; + } + } + } + } + } + + private static String getPackagePrefix(File base, Pair root) { + String result = ""; + for (File parent = base; parent != null; parent = parent.getParentFile()) { + if (parent.equals(root.getFirst())) { + return root.getSecond() + (root.getSecond().length() > 0 && result.length() > 0 ? "." : "") + result; + } + result = parent.getName() + (result.length() > 0 ? "." : "") + result; + } + return null; + } + + + private static Pair suggestRootForJavaFile(File javaFile) { + if (!javaFile.isFile()) return null; + + try{ + Reader reader = new BufferedReader(new FileReader(javaFile)); + char[] chars = new char[(int)javaFile.length()]; + int count = 0; + for(; ;){ + int n = reader.read(chars, count, chars.length - count); + if (n <= 0) break; + count += n; + } + reader.close(); + if (count != chars.length){ + char[] newChars = new char[count]; + System.arraycopy(chars, 0, newChars, 0, count); + chars = newChars; + } + + String packageName = getPackageStatement(chars); + if (packageName != null){ + File root = javaFile.getParentFile(); + int index = packageName.length(); + while(index > 0){ + int index1 = packageName.lastIndexOf('.', index - 1); + String token = packageName.substring(index1 + 1, index); + String dirName = root.getName(); + if (!SystemInfo.isFileSystemCaseSensitive){ + token = token.toLowerCase(); + dirName = dirName.toLowerCase(); + } + if (!dirName.equals(token)){ + return Pair.create(root, packageName.substring(0, index)); + } + String parent = root.getParent(); + if (parent == null){ + return null; + } + root = new File(parent); + index = index1; + } + return Pair.create(root, ""); + } + } + catch(IOException e){ + return null; + } + + return null; + } + + private static String getPackageStatement(char[] text){ + Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3); + lexer.start(text); + skipWhiteSpaceAndComments(lexer); + if (lexer.getTokenType() != JavaTokenType.PACKAGE_KEYWORD) return ""; + lexer.advance(); + skipWhiteSpaceAndComments(lexer); + StringBuffer buffer = new StringBuffer(); + while(true){ + if (lexer.getTokenType() != JavaTokenType.IDENTIFIER) break; + buffer.append(text, lexer.getTokenStart(), lexer.getTokenEnd() - lexer.getTokenStart()); + lexer.advance(); + skipWhiteSpaceAndComments(lexer); + if (lexer.getTokenType() != JavaTokenType.DOT) break; + buffer.append('.'); + lexer.advance(); + skipWhiteSpaceAndComments(lexer); + } + String packageName = buffer.toString(); + if (packageName.length() == 0 || StringUtil.endsWithChar(packageName, '.')) return null; + return packageName; + } + + private static void skipWhiteSpaceAndComments(Lexer lexer){ + while(JavaTokenType.WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(lexer.getTokenType())) { + lexer.advance(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberChooser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberChooser.java new file mode 100644 index 00000000000..860aba0326d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberChooser.java @@ -0,0 +1,933 @@ +package com.intellij.ide.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.j2ee.j2eeDom.ejb.CmpField; +import com.intellij.j2ee.j2eeDom.ejb.CmrField; +import com.intellij.j2ee.j2eeDom.ejb.EntityBean; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.Icons; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.ref.WeakReference; +import java.util.*; +import java.util.List; + +public class MemberChooser extends DialogWrapper { + protected Tree myTree; + private DefaultTreeModel myTreeModel; + private JCheckBox myCopyJavadocCheckbox; + private JCheckBox myInsertOverrideAnnotationCheckbox; + + private ArrayList mySelectedNodes = new ArrayList(); + + private boolean mySorted = false; + private boolean myShowClasses = true; + private boolean myAllowEmptySelection = false; + private boolean myAllowMultiSelection; + private final boolean myIsInsertOverrideVisible; + + protected Object[] myElements; + private HashMap myNodeToParentMap = new HashMap(); + private HashMap myElementToNodeMap = new HashMap(); + private ArrayList myClassNodes = new ArrayList(); + private WeakReference[] mySelectedElements; + + private final static String PROP_SORTED = "MemberChooser.sorted"; + private final static String PROP_SHOWCLASSES = "MemberChooser.showClasses"; + private final static String PROP_COPYJAVADOC = "MemberChooser.copyJavadoc"; + private final static String PROP_INSERT_OVERRIDE = "MemberChooser.insertOverride"; + + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.MemberChooser"); + + public MemberChooser(Object[] elements, + boolean allowEmptySelection, + boolean allowMultiSelection, + Project project) { + this(elements, allowEmptySelection, allowMultiSelection, project, false); + } + + public MemberChooser(Object[] elements, + boolean allowEmptySelection, + boolean allowMultiSelection, + Project project, + boolean isInsertOverrideVisible) { + super(project, true); + myElements = elements; + myAllowEmptySelection = allowEmptySelection; + myAllowMultiSelection = allowMultiSelection; + myIsInsertOverrideVisible = isInsertOverrideVisible; + myTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode())); + resetData(); + init(); + } + + protected void resetData() { + mySelectedNodes = new ArrayList(); + + myNodeToParentMap = new HashMap(); + myElementToNodeMap = new HashMap(); + myClassNodes = new ArrayList(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + myTreeModel = buildModel(); + } + }); + myTree.setModel(myTreeModel); + expandAll(); + myCopyJavadocCheckbox = new JCheckBox("Copy JavaDoc"); + if (myIsInsertOverrideVisible) { + myInsertOverrideAnnotationCheckbox = new JCheckBox("Insert @Override"); + } + } + + /** + * should be invoked in read action + */ + private DefaultTreeModel buildModel() { + DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(); + Map map = new HashMap(); + + for (int i = 0; i < myElements.length; i++) { + Object object = myElements[i]; + if (object instanceof PsiElement) { + final PsiElement psiElement = (PsiElement)object; + LOG.assertTrue(psiElement instanceof PsiMember); + final PsiClass psiClass = ((PsiMember)psiElement).getContainingClass(); + ElementNode classNode = (ElementNode)map.get(psiClass); + if (classNode == null) { + classNode = new ElementNode(psiClass, myClassNodes.size() * (i + 1)); + formatNode(classNode); + rootNode.add(classNode); + map.put(psiClass, classNode); + myClassNodes.add(classNode); + } + ElementNode memberNode = new ElementNode(psiElement, myClassNodes.size() * (i + 1) + classNode.getChildCount()); + formatNode(memberNode); + classNode.add(memberNode); + myNodeToParentMap.put(memberNode, classNode); + myElementToNodeMap.put(psiElement, memberNode); + } + else if (object instanceof CandidateInfo) { + PsiElement element = ((CandidateInfo)object).getElement(); + PsiClass aClass = (PsiClass)element.getParent(); + //A class cannot inherit from the same class/interface twice with different substitutors + ElementNode classNode = (ElementNode)map.get(aClass); + if (classNode == null) { + PsiSubstitutor substitutor = ((CandidateInfo)object).getSubstitutor(); + CandidateInfo info = new CandidateInfo(aClass, substitutor); + classNode = new GenericElementNode(info, myClassNodes.size() * (i + 1)); + formatNode(classNode); + rootNode.add(classNode); + map.put(aClass, classNode); + myClassNodes.add(classNode); + } + ElementNode memberNode = new GenericElementNode((CandidateInfo)object, + myClassNodes.size() * (i + 1) + classNode.getChildCount()); + formatNode(memberNode); + classNode.add(memberNode); + myNodeToParentMap.put(memberNode, classNode); + myElementToNodeMap.put(object, memberNode); + } + + else if (object instanceof CmpField) { + CmpField field = (CmpField)object; + final EntityBean bean = field.getEntityBean(); + EntityBeanNode beanNode = (EntityBeanNode)map.get(bean); + + if (beanNode == null) { + beanNode = new EntityBeanNode(bean); + rootNode.add(beanNode); + map.put(bean, beanNode); + } + + CmpFieldNode fieldNode = new CmpFieldNode(field); + beanNode.add(fieldNode); + myNodeToParentMap.put(fieldNode, beanNode); + myElementToNodeMap.put(field, fieldNode); + } + else if (object instanceof CmrField) { + CmrField field = (CmrField)object; + final EntityBean bean = field.getEntityBean(); + EntityBeanNode beanNode = (EntityBeanNode)map.get(bean); + + if (beanNode == null) { + beanNode = new EntityBeanNode(bean); + rootNode.add(beanNode); + map.put(bean, beanNode); + } + + CmrFieldNode fieldNode = new CmrFieldNode(field); + beanNode.add(fieldNode); + myNodeToParentMap.put(fieldNode, beanNode); + myElementToNodeMap.put(field, fieldNode); + } + } + return new DefaultTreeModel(rootNode); + } + + public void selectElements(Object[] elements) { + ArrayList selectionPaths = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)myElementToNodeMap.get(element); + if (treeNode != null) { + selectionPaths.add(new TreePath(treeNode.getPath())); + } + } + myTree.setSelectionPaths((TreePath[])selectionPaths.toArray(new TreePath[selectionPaths.size()])); + } + + + protected Action[] createActions() { + if (myAllowEmptySelection) { + return new Action[]{getOKAction(), new SelectNoneAction(), getCancelAction()}; + } + else { + return new Action[]{getOKAction(), getCancelAction()}; + } + } + + protected JComponent createSouthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + JPanel optionsPanel = new JPanel(new VerticalFlowLayout()); + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + myTree.requestFocus(); + } + }; + + if (myIsInsertOverrideVisible) { + myInsertOverrideAnnotationCheckbox.setMnemonic('O'); + myInsertOverrideAnnotationCheckbox.setSelected("true".equals(PropertiesComponent.getInstance().getValue(PROP_INSERT_OVERRIDE))); + myInsertOverrideAnnotationCheckbox.addActionListener(actionListener); + optionsPanel.add(myInsertOverrideAnnotationCheckbox); + } + + myCopyJavadocCheckbox.setMnemonic('J'); + myCopyJavadocCheckbox.setSelected("true".equals(PropertiesComponent.getInstance().getValue(PROP_COPYJAVADOC))); + myCopyJavadocCheckbox.addActionListener(actionListener); + optionsPanel.add(myCopyJavadocCheckbox); + + + + panel.add( + optionsPanel, + new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, + new Insets(0, 0, 0, 5), 0, 0) + ); + + if (myElements == null || myElements.length == 0) { + setOKActionEnabled(false); + } + panel.add( + super.createSouthPanel(), + new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0) + ); + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + // Toolbar + + DefaultActionGroup group = new DefaultActionGroup(); + + SortEmAction sortAction = new SortEmAction(); + sortAction.registerCustomShortcutSet( + new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.ALT_MASK)), myTree); + setSorted("true".equals(PropertiesComponent.getInstance().getValue(PROP_SORTED))); + group.add(sortAction); + + ShowClassesAction showClassesAction = new ShowClassesAction(); + showClassesAction.registerCustomShortcutSet( + new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.ALT_MASK)), myTree); + setShowClasses("true".equals(PropertiesComponent.getInstance().getValue(PROP_SHOWCLASSES))); + group.add(showClassesAction); + + ExpandAllAction expandAllAction = new ExpandAllAction(); + expandAllAction.registerCustomShortcutSet( + new CustomShortcutSet( + KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK)), + myTree); + group.add(expandAllAction); + + CollapseAllAction collapseAllAction = new CollapseAllAction(); + collapseAllAction.registerCustomShortcutSet( + new CustomShortcutSet( + KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK)), + myTree); + group.add(collapseAllAction); + + panel.add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(), + BorderLayout.NORTH); + + // Tree + + myTree.setCellRenderer(new CellRenderer()); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.addKeyListener(new TreeKeyListener()); + myTree.addTreeSelectionListener(new MyTreeSelectionListener()); + + if (!myAllowMultiSelection) { + myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + } + + if (((DefaultMutableTreeNode)myTreeModel.getRoot()).getChildCount() > 0) { + myTree.expandRow(0); + myTree.setSelectionRow(1); + } + expandAll(); + new TreeSpeedSearch(myTree, new Convertor() { + public String convert(TreePath path) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)(path).getLastPathComponent(); + if (node instanceof ElementNode) { + ElementNode elementNode = (ElementNode)node; + PsiElement psiElement = elementNode.getElement(); + if (psiElement instanceof PsiClass) return null; + return elementNode.getText(); + } + return null; + } + }); + myTree.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + if (myTree.getPathForLocation(e.getX(), e.getY()) != null) { + doOKAction(); + } + } + } + } + ); + TreeToolTipHandler.install(myTree); + TreeUtil.installActions(myTree); + JScrollPane scrollPane = new JScrollPane(myTree); + scrollPane.setPreferredSize(new Dimension(350, 450)); + panel.add(scrollPane, BorderLayout.CENTER); + + return panel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.ide.util.MemberChooser"; + } + + public JComponent getPreferredFocusedComponent() { + return myTree; + } + + private List getSelectedElementsList() { + if (getExitCode() != OK_EXIT_CODE) { + return null; + } + if (mySelectedElements == null) { + return null; + } + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < mySelectedElements.length; i++) { + Object element = mySelectedElements[i].get(); + if (element != null) arrayList.add(element); + } + return arrayList; + } + + public Object[] getSelectedElements() { + List list = getSelectedElementsList(); + if (list == null) return null; + return list.toArray(new Object[list.size()]); + } + + public Object[] getSelectedElements(Object[] a) { + List list = getSelectedElementsList(); + if (list == null) return null; + return list.toArray(a); + } + + public boolean areElementsSelected() { + return mySelectedElements != null && mySelectedElements.length > 0; + } + + public void setCopyJavadocVisible(boolean state) { + myCopyJavadocCheckbox.setVisible(state); + } + + public boolean isCopyJavadoc() { + return myCopyJavadocCheckbox.isSelected(); + } + + public boolean isInsertOverrideAnnotation () { + return myIsInsertOverrideVisible && myInsertOverrideAnnotationCheckbox.isSelected(); + } + + private boolean isSorted() { + return mySorted; + } + + private void setSorted(boolean sorted) { + if (mySorted == sorted) return; + mySorted = sorted; + + Pair pair = storeSelection(); + + DefaultMutableTreeNode root = (DefaultMutableTreeNode)myTreeModel.getRoot(); + Enumeration children = root.children(); + while (children.hasMoreElements()) { + DefaultMutableTreeNode classNode = (DefaultMutableTreeNode)children.nextElement(); + sortNode(classNode, sorted); + myTreeModel.nodeStructureChanged(classNode); + } + + restoreSelection(pair); + } + + private void sortNode(DefaultMutableTreeNode node, boolean sorted) { + ArrayList arrayList = new ArrayList(); + Enumeration children = node.children(); + while (children.hasMoreElements()) { + arrayList.add(children.nextElement()); + } + + Collections.sort(arrayList, sorted ? (Comparator)new AlphaComparator() : new OrderComparator()); + + node.removeAllChildren(); + for (int i = 0; i < arrayList.size(); i++) { + node.add((MutableTreeNode)arrayList.get(i)); + } + } + + private void setShowClasses(boolean showClasses) { + myShowClasses = showClasses; + + Pair selection = storeSelection(); + + DefaultMutableTreeNode root = (DefaultMutableTreeNode)myTreeModel.getRoot(); + if (!myShowClasses || myClassNodes.size() == 0) { + List otherObjects = new ArrayList(); + Enumeration children = root.children(); + ElementNode newRoot = new AllClassesNode(); + while (children.hasMoreElements()) { + final DefaultMutableTreeNode nextElement = (DefaultMutableTreeNode)children.nextElement(); + if (!(nextElement instanceof ElementNode)) { + otherObjects.add(nextElement); + continue; + } + ElementNode classNode = (ElementNode)nextElement; + Enumeration memberNodes = classNode.children(); + ArrayList memberNodesArray = new ArrayList(); + while (memberNodes.hasMoreElements()) { + memberNodesArray.add(memberNodes.nextElement()); + } + for (int i = 0; i < memberNodesArray.size(); i++) { + ElementNode memberNode = (ElementNode)memberNodesArray.get(i); + newRoot.add(memberNode); + } + } + root.removeAllChildren(); + for (Iterator iterator = otherObjects.iterator(); iterator.hasNext();) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)iterator.next(); + root.add(node); + } + sortNode(newRoot, mySorted); + if (newRoot.children().hasMoreElements()) root.add(newRoot); + } + else { + Enumeration children = root.children(); + if (children.hasMoreElements()) { + DefaultMutableTreeNode allClassesNode = (DefaultMutableTreeNode)children.nextElement(); + Enumeration memberNodes = allClassesNode.children(); + ArrayList arrayList = new ArrayList(); + while (memberNodes.hasMoreElements()) { + arrayList.add(memberNodes.nextElement()); + } + for (int i = 0; i < arrayList.size(); i++) { + DefaultMutableTreeNode memberNode = (DefaultMutableTreeNode)arrayList.get(i); + DefaultMutableTreeNode classNode = (DefaultMutableTreeNode)myNodeToParentMap.get(memberNode); + classNode.add(memberNode); + } + } + root.removeAllChildren(); + for (int i = 0; i < myClassNodes.size(); i++) { + DefaultMutableTreeNode classNode = (DefaultMutableTreeNode)myClassNodes.get(i); + root.add(classNode); + } + } + myTreeModel.nodeStructureChanged(root); + + expandAll(); + + restoreSelection(selection); + } + + private Pair storeSelection() { + ArrayList selectedNodes = new ArrayList(); + TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + selectedNodes.add(paths[i].getLastPathComponent()); + } + } + TreePath leadSelectionPath = myTree.getLeadSelectionPath(); + return new Pair(leadSelectionPath != null ? leadSelectionPath.getLastPathComponent() : null, selectedNodes); + } + + + private void restoreSelection(Pair pair) { + ArrayList selectedNodes = (ArrayList)pair.second; + + DefaultMutableTreeNode root = (DefaultMutableTreeNode)myTreeModel.getRoot(); + + ArrayList toSelect = new ArrayList(); + for (int i = 0; i < selectedNodes.size(); i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectedNodes.get(i); + if (root.isNodeDescendant(node)) { + toSelect.add(new TreePath(node.getPath())); + } + } + + if (toSelect.size() > 0) { + myTree.setSelectionPaths((TreePath[])toSelect.toArray(new TreePath[toSelect.size()])); + } + + DefaultMutableTreeNode leadNode = (DefaultMutableTreeNode)pair.first; + if (leadNode != null) { + myTree.setLeadSelectionPath(new TreePath(leadNode.getPath())); + } + } + + protected void doOKAction() { + super.doOKAction(); + } + + private void updateSelectedElements() { + Set set = new LinkedHashSet(); + for (int i = 0; i < mySelectedNodes.size(); i++) { + final Object o = mySelectedNodes.get(i); + if (o instanceof GenericElementNode) { + set.add(((GenericElementNode)o).getCandidateInfo()); + } + else if (o instanceof ElementNode) { + PsiElement element = ((ElementNode)o).getElement(); + if (element != null) set.add(element); + } + else if (o instanceof CmpFieldNode) { + set.add(((CmpFieldNode)o).getField()); + } + else if (o instanceof CmrFieldNode) { + set.add(((CmrFieldNode)o).getField()); + } + } + mySelectedElements = new WeakReference[set.size()]; + int i = 0; + for (Iterator it = set.iterator(); it.hasNext(); i++) { + mySelectedElements[i] = new WeakReference(it.next()); + } + } + + protected void dispose() { + PropertiesComponent instance = PropertiesComponent.getInstance(); + instance.setValue(PROP_SORTED, isSorted() ? "true" : "false"); + instance.setValue(PROP_SHOWCLASSES, myShowClasses ? "true" : "false"); + instance.setValue(PROP_COPYJAVADOC, myCopyJavadocCheckbox.isSelected() ? "true" : "false"); + if (myIsInsertOverrideVisible) { + instance.setValue(PROP_INSERT_OVERRIDE, myInsertOverrideAnnotationCheckbox.isSelected() ? "true" : "false"); + } + + getContentPane().removeAll(); + mySelectedNodes.clear(); + myElements = null; + super.dispose(); + } + + private class MyTreeSelectionListener implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent e) { + TreePath[] paths = e.getPaths(); + if (paths == null) return; + for (int i = 0; i < paths.length; i++) { + Object node = paths[i].getLastPathComponent(); + if (node instanceof ElementNode && ((ElementNode)node).getElement() instanceof PsiClass) continue; + if (e.isAddedPath(i)) { + if (!mySelectedNodes.contains(node)) { + mySelectedNodes.add(node); + } + } + else { + mySelectedNodes.remove(node); + } + } + updateSelectedElements(); + + } + } + + /** + * should be invoked in run action + */ + private static void formatNode(ElementNode node) { + final PsiElement element = node.getElement(); + if (element instanceof PsiClass) { + node.setText(PsiFormatUtil.formatClass((PsiClass)element, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_FQ_NAME)); + node.setIcon(element.getIcon(0)); + } + else if (element instanceof PsiMethod) { + int methodOptions = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | + PsiFormatUtil.SHOW_PARAMETERS; + int paramOptions = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER; + node.setText(PsiFormatUtil.formatMethod((PsiMethod)element, PsiSubstitutor.EMPTY, methodOptions, paramOptions)); + node.setIcon(element.getIcon(Iconable.ICON_FLAG_VISIBILITY)); + } + else if (element instanceof PsiField) { + int options = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER; + node.setText(PsiFormatUtil.formatVariable((PsiField)element, options, PsiSubstitutor.EMPTY)); + node.setIcon(element.getIcon(Iconable.ICON_FLAG_VISIBILITY)); + } + } + + private void expandAll() { + Enumeration children = ((DefaultMutableTreeNode)myTreeModel.getRoot()).children(); + while (children.hasMoreElements()) { + DefaultMutableTreeNode child = (DefaultMutableTreeNode)children.nextElement(); + myTree.expandPath(new TreePath(child.getPath())); + } + } + + private void collapseAll() { + Enumeration children = ((DefaultMutableTreeNode)myTreeModel.getRoot()).children(); + while (children.hasMoreElements()) { + DefaultMutableTreeNode child = (DefaultMutableTreeNode)children.nextElement(); + myTree.collapsePath(new TreePath(child.getPath())); + } + } + + private static class ElementNode extends DefaultMutableTreeNode { + private Icon myIcon; + private String myText; + protected PsiElement myElement; + private int myOrder; + private boolean myIsDeprecated; + + private boolean isDeprecated() { + return myIsDeprecated; + } + + public ElementNode(PsiElement element, int order) { + myElement = element; + myOrder = order; + myIsDeprecated = element instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)element).isDeprecated(); + } + + public Icon getIcon() { + return myIcon; + } + + public void setIcon(Icon icon) { + myIcon = icon; + } + + public String getText() { + return myText; + } + + public void setText(String text) { + myText = text; + } + + public PsiElement getElement() { + return myElement; + } + + public int getOrder() { + return myOrder; + } + } + + private static class GenericElementNode extends ElementNode { + public CandidateInfo getCandidateInfo() { + return myCandidate; + } + + private CandidateInfo myCandidate; + + public GenericElementNode(CandidateInfo info, int order) { + super(info.getElement(), order); + myCandidate = info; + } + + public String getText() { + PsiSubstitutor substitutor = myCandidate.getSubstitutor(); + if (substitutor == PsiSubstitutor.EMPTY) return super.getText(); + + if (myElement instanceof PsiClass) { + PsiType classType = myElement.getManager().getElementFactory().createType((PsiClass)myElement, substitutor); + return PsiFormatUtil.formatType(classType, 0, PsiSubstitutor.EMPTY); + } + else if (myElement instanceof PsiMethod) { + int methodOptions = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | + PsiFormatUtil.SHOW_PARAMETERS; + int paramOptions = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER; + return PsiFormatUtil.formatMethod((PsiMethod)myElement, substitutor, methodOptions, paramOptions); + } + else { + return super.getText(); + } + } + } + + private static class EntityBeanNode extends DefaultMutableTreeNode { + private Icon myIcon; + private String myText; + + public EntityBeanNode(EntityBean bean) { + myText = bean.getName(); + myIcon = IconUtilEx.getIcon(bean, 0, null); + } + + public Icon getIcon() { + return myIcon; + } + + public String getText() { + return myText; + } + } + + private static class CmpFieldNode extends DefaultMutableTreeNode { + private Icon myIcon; + private String myText; + private CmpField myField; + + public CmpFieldNode(CmpField field) { + myField = field; + myText = field.getName(); + myIcon = IconUtilEx.getIcon(field, 0, null); + } + + public Icon getIcon() { + return myIcon; + } + + public String getText() { + return myText; + } + + public CmpField getField() { + return myField; + } + } + + private static class CmrFieldNode extends DefaultMutableTreeNode { + private Icon myIcon; + private String myText; + private CmrField myField; + + public CmrFieldNode(CmrField field) { + myField = field; + myText = field.getName(); + myIcon = IconUtilEx.getIcon(field, 0, null); + } + + public Icon getIcon() { + return myIcon; + } + + public String getText() { + return myText; + } + + public CmrField getField() { + return myField; + } + } + + private static class AllClassesNode extends ElementNode { + public AllClassesNode() { + super(null, 0); + } + + public String getText() { + return "All classes"; + } + + public PsiElement getElement() { + return null; + } + } + + private class CellRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, + boolean leaf, int row, boolean hasFocus) { + SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, + tree.getForeground()); + if (value instanceof ElementNode) { + ElementNode node = (ElementNode)value; + if (node.isDeprecated()) { + attributes = + new SimpleTextAttributes( + node.isDeprecated() ? SimpleTextAttributes.STYLE_STRIKEOUT : SimpleTextAttributes.STYLE_PLAIN, + tree.getForeground()); + } + append(node.getText(), attributes); + setIcon(node.getIcon()); + } + else if (value instanceof CmpFieldNode) { + CmpFieldNode node = (CmpFieldNode)value; + append(node.getText(), attributes); + setIcon(node.getIcon()); + } + else if (value instanceof CmrFieldNode) { + CmrFieldNode node = (CmrFieldNode)value; + append(node.getText(), attributes); + setIcon(node.getIcon()); + } + else if (value instanceof EntityBeanNode) { + EntityBeanNode node = (EntityBeanNode)value; + append(node.getText(), attributes); + setIcon(node.getIcon()); + } + } + } + + private class SelectNoneAction extends AbstractAction { + public SelectNoneAction() { + super("Select &None"); + } + + public void actionPerformed(ActionEvent e) { + myTree.clearSelection(); + doOKAction(); + } + } + + private class TreeKeyListener extends KeyAdapter { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + TreePath path = myTree.getLeadSelectionPath(); + if (path == null) return; + if (path.getLastPathComponent() instanceof ElementNode) { + ElementNode node = (ElementNode)path.getLastPathComponent(); + if (node.getElement() instanceof PsiClass) return; + } + doOKAction(); + e.consume(); + } + else if (e.getKeyCode() == KeyEvent.VK_INSERT) { + TreePath path = myTree.getLeadSelectionPath(); + if (path == null) return; + if (path.getLastPathComponent() instanceof ElementNode) { + ElementNode node = (ElementNode)path.getLastPathComponent(); + if (node.getElement() instanceof PsiClass) return; + if (!mySelectedNodes.contains(node)) { + if (node.getNextNode() != null) { + myTree.setSelectionPath(new TreePath(node.getNextNode().getPath())); + } + } + else { + if (node.getNextNode() != null) { + myTree.removeSelectionPath(new TreePath(node.getPath())); + myTree.setSelectionPath(new TreePath(node.getNextNode().getPath())); + myTree.repaint(); + } + } + e.consume(); + } + } + } + } + + private class SortEmAction extends ToggleAction { + public SortEmAction() { + super("Sort Alphabetically", "Sort Alphabetically", IconLoader.getIcon("/objectBrowser/sorted.png")); + } + + public boolean isSelected(AnActionEvent event) { + return isSorted(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + setSorted(flag); + } + } + + private class ShowClassesAction extends ToggleAction { + public ShowClassesAction() { + super("Show Classes", "Show Classes", Icons.CLASS_ICON); + } + + public boolean isSelected(AnActionEvent event) { + return myShowClasses; + } + + public void setSelected(AnActionEvent event, boolean flag) { + setShowClasses(flag); + } + + public void update(AnActionEvent e) { + super.update(e); + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myClassNodes.size() > 1); + } + } + + private class ExpandAllAction extends AnAction { + public ExpandAllAction() { + super("Expand All", "Expand All", IconLoader.getIcon("/actions/expandall.png")); + } + + public void actionPerformed(AnActionEvent e) { + expandAll(); + } + } + + private class CollapseAllAction extends AnAction { + public CollapseAllAction() { + super("Collapse All", "Collapse All", IconLoader.getIcon("/actions/collapseall.png")); + } + + public void actionPerformed(AnActionEvent e) { + collapseAll(); + } + } + + private static class AlphaComparator implements Comparator { + public int compare(Object o, Object o1) { + return ((ElementNode)o).getText().compareToIgnoreCase(((ElementNode)o1).getText()); + } + } + + private static class OrderComparator implements Comparator { + public int compare(Object o1, Object o2) { + return ((ElementNode)o1).getOrder() - ((ElementNode)o2).getOrder(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberContainerCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberContainerCellRenderer.java new file mode 100644 index 00000000000..551a32b971d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/MemberContainerCellRenderer.java @@ -0,0 +1,43 @@ +package com.intellij.ide.util; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; + +import javax.swing.*; + +public class MemberContainerCellRenderer extends PsiClassListCellRenderer{ + private final boolean myShowMethodNames; + + public MemberContainerCellRenderer(boolean showMethodNames) { + myShowMethodNames = showMethodNames; + } + + public String getElementText(PsiElement element) { + String text = super.getElementText(fetchContainer(element)); + if (myShowMethodNames) { + final int options = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS; + text += "."+PsiFormatUtil.formatMethod((PsiMethod)element, PsiSubstitutor.EMPTY, options, PsiFormatUtil.SHOW_TYPE); + } + return text; + } + + protected Icon getIcon(PsiElement element) { + return super.getIcon(myShowMethodNames ? element : fetchContainer(element)); + } + + private PsiElement fetchContainer(PsiElement element){ + if (element instanceof PsiMember) { + PsiMethod method = (PsiMethod)element; + PsiClass aClass = method.getContainingClass(); + if (aClass == null) { + return method.getContainingFile(); + } + else { + return aClass; + } + } + else { + throw new IllegalArgumentException("unknown value: " + element); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/NavigationItemListCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/NavigationItemListCellRenderer.java new file mode 100644 index 00000000000..dd49843417e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/NavigationItemListCellRenderer.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; +import java.util.Comparator; + +public class NavigationItemListCellRenderer extends ColoredListCellRenderer{ + protected void customizeCellRenderer( + JList list, + Object value, + int index, + boolean selected, + boolean hasFocus + ){ + if (value instanceof NavigationItem) { + NavigationItem element = (NavigationItem)value; + ItemPresentation presentation = element.getPresentation(); + String name = presentation.getPresentableText(); + Color color = list.getForeground(); + FileStatus status = element.getFileStatus(); + if (status != FileStatus.NOT_CHANGED) { + color = status.getColor(); + } + + append(name,new SimpleTextAttributes(Font.PLAIN, color)); + setIcon(presentation.getIcon(false)); + + String containerText = presentation.getLocationString(); + + if (containerText != null && containerText.length() > 0){ + append(" " + containerText, new SimpleTextAttributes(Font.PLAIN, Color.GRAY)); + } + } + else { + setIcon(IconUtilEx.getEmptyIcon(false)); + append(value == null ? "" : value.toString(), new SimpleTextAttributes(Font.PLAIN, list.getForeground())); + } + } + + public Comparator getComparator(){ + return new Comparator() { + public int compare(Object o1, Object o2) { + return getText(o1).compareTo(getText(o2)); + } + + private String getText(Object o){ + if (o instanceof NavigationItem){ + NavigationItem element = (NavigationItem)o; + ItemPresentation presentation = element.getPresentation(); + String elementText = presentation.getLocationString(); + String containerText = presentation.getLocationString(); + return containerText != null ? elementText + " " + containerText : elementText; + } + else{ + return o.toString(); + } + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageChooserDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageChooserDialog.java new file mode 100644 index 00000000000..be17f90c648 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageChooserDialog.java @@ -0,0 +1,331 @@ +package com.intellij.ide.util; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.PsiPackage; +import com.intellij.util.ui.Tree; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.Convertor; +import com.intellij.util.ui.tree.TreeUtil; +import com.intellij.util.ui.Tree; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.util.Comparator; +import java.util.Enumeration; + +public class PackageChooserDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.PackageChooserDialog"); + + private Tree myTree; + private DefaultTreeModel myModel; + private PsiPackage mySelectedPackage = null; + private Project myProject; + private String myTitle; + private static final Icon PACKAGE_OPEN_ICON = IconLoader.getIcon("/nodes/packageOpen.png"); + private static final Icon PACKAGE_CLOSED_ICON = IconLoader.getIcon("/nodes/packageClosed.png"); + + public PackageChooserDialog(String title, Project project) { + super(project, true); + setTitle(title); + myTitle = title; + myProject = project; + init(); + } + + protected JComponent createCenterPanel(){ + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + + + myModel = new DefaultTreeModel(new DefaultMutableTreeNode()); + createTreeModel(); + myTree = new Tree(myModel); + + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setCellRenderer( + new DefaultTreeCellRenderer() { + public Component getTreeCellRendererComponent( + JTree tree, Object value, + boolean sel, + boolean expanded, + boolean leaf, int row, + boolean hasFocus + ){ + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + setIcon(expanded ? PACKAGE_OPEN_ICON : PACKAGE_CLOSED_ICON); + + if (value instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + Object object = node.getUserObject(); + if (object instanceof PsiPackage) { + String name = ((PsiPackage)object).getName(); + if (name != null && name.length() > 0) { + setText(name); + } + else { + setText(""); + } + } + } + return this; + } + } + ); + + myTree.setBorder(BorderFactory.createEtchedBorder()); + JScrollPane scrollPane = new JScrollPane(myTree); + scrollPane.setPreferredSize(new Dimension(500,300)); + + new TreeSpeedSearch(myTree, new Convertor() { + public String convert(TreePath path) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + Object object = node.getUserObject(); + if (object instanceof PsiPackage) return ((PsiPackage)object).getName(); + else return ""; + } + }); + + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + PsiPackage selection = getTreeSelection(); + if (selection != null) { + String name = selection.getQualifiedName(); + setTitle(myTitle + " - " + ("".equals(name) ? "" : name)); + } + else { + setTitle(myTitle); + } + } + }); + + panel.add(scrollPane, BorderLayout.CENTER); + DefaultActionGroup group = createActionGroup(myTree); + + ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); + panel.add(toolBar.getComponent(), BorderLayout.NORTH); + toolBar.getComponent().setAlignmentX(JComponent.LEFT_ALIGNMENT); + + return panel; + } + + private DefaultActionGroup createActionGroup(JComponent component) { + final DefaultActionGroup group = new DefaultActionGroup(); + final DefaultActionGroup temp = new DefaultActionGroup(); + NewPackageAction newPackageAction = new NewPackageAction(); + newPackageAction.enableInModalConext(); + newPackageAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_NEW_ELEMENT).getShortcutSet(), component); + temp.add(newPackageAction); + group.add(temp); + return group; + } + + protected void doOKAction(){ + mySelectedPackage = getTreeSelection(); + super.doOKAction(); + } + + public String getDimensionServiceKey(){ + return "#com.intellij.ide.util.PackageChooserDialog"; + } + + public JComponent getPreferredFocusedComponent(){ + return myTree; + } + + public PsiPackage getSelectedPackage(){ + return mySelectedPackage; + } + + public void selectPackage(final String qualifiedName) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + DefaultMutableTreeNode node = findNodeForPackage(qualifiedName); + if (node != null) { + TreePath path = new TreePath(node.getPath()); + TreeUtil.selectPath(myTree, path); + } + } + }, ModalityState.stateForComponent(getRootPane())); + } + + private PsiPackage getTreeSelection() { + if (myTree == null) return null; + TreePath path = myTree.getSelectionPath(); + if (path == null) return null; + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + return (PsiPackage)node.getUserObject(); + } + + private void createTreeModel() { + final PsiManager psiManager = PsiManager.getInstance(myProject); + final FileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + projectFileIndex.iterateContent( + new ContentIterator() { + public boolean processFile(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory() && projectFileIndex.isInSourceContent(fileOrDir)){ + PsiPackage aPackage = psiManager.findDirectory(fileOrDir).getPackage(); + if (aPackage != null){ + addPackage(aPackage); + } + } + return true; + } + } + ); + + TreeUtil.sort(myModel, new Comparator() { + public int compare(Object o1, Object o2) { + DefaultMutableTreeNode n1 = (DefaultMutableTreeNode) o1; + DefaultMutableTreeNode n2 = (DefaultMutableTreeNode) o2; + PsiNamedElement element1 = (PsiNamedElement) n1.getUserObject(); + PsiNamedElement element2 = (PsiNamedElement) n2.getUserObject(); + return element1.getName().compareToIgnoreCase(element2.getName()); + } + }); + } + + private void addPackage(PsiPackage aPackage) { + if (findNodeForPackage(aPackage.getQualifiedName()) == null) { + PsiPackage parentPackage = aPackage.getParentPackage(); + if (parentPackage == null) { + if (aPackage.getQualifiedName().equals("")) { + ((DefaultMutableTreeNode)myModel.getRoot()).setUserObject(aPackage); + } + else { + PsiPackage defaultPackage = PsiManager.getInstance(myProject).findPackage(""); + addPackage(defaultPackage); + DefaultMutableTreeNode defaultPackageNode = findNodeForPackage(""); + LOG.assertTrue(defaultPackageNode != null); + defaultPackageNode.add(new DefaultMutableTreeNode(aPackage)); + } + } + else { + addPackage(parentPackage); + DefaultMutableTreeNode node = findNodeForPackage(parentPackage.getQualifiedName()); + if (node != null) { + node.add(new DefaultMutableTreeNode(aPackage)); + } + } + } + } + + private DefaultMutableTreeNode findNodeForPackage(String qualifiedPackageName) { + DefaultMutableTreeNode root = (DefaultMutableTreeNode)myModel.getRoot(); + Enumeration enumeration = root.depthFirstEnumeration(); + while (enumeration.hasMoreElements()) { + Object o = enumeration.nextElement(); + if (o instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)o; + PsiPackage nodePackage = (PsiPackage)node.getUserObject(); + if (nodePackage != null) { + if (Comparing.equal(nodePackage.getQualifiedName(), qualifiedPackageName)) return node; + } + } + } + return null; + } + + private void createNewPackage() { + final PsiPackage selectedPackage = getTreeSelection(); + if (selectedPackage == null) return; + + final String newPackageName = Messages.showInputDialog(myProject, "Enter a new package name:", "New Package", Messages.getQuestionIcon()); + if (newPackageName == null) return; + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + + try { + String newQualifiedName = selectedPackage.getQualifiedName(); + if (!Comparing.strEqual(newQualifiedName,"")) newQualifiedName += "."; + newQualifiedName += newPackageName; + final PsiDirectory dir = PackageUtil.findOrCreateDirectoryForPackage(myProject, newQualifiedName, null, false); + if (dir == null) return; + final PsiPackage newPackage = dir.getPackage(); + + DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getSelectionPath().getLastPathComponent(); + final DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(); + newChild.setUserObject(newPackage); + node.add(newChild); + + final DefaultTreeModel model = (DefaultTreeModel)myTree.getModel(); + model.nodeStructureChanged(node); + + final TreePath selectionPath = myTree.getSelectionPath(); + TreePath path; + if (selectionPath == null) { + path = new TreePath(newChild.getPath()); + } else { + path = selectionPath.pathByAddingChild(newChild); + } + myTree.setSelectionPath(path); + myTree.scrollPathToVisible(path); + myTree.expandPath(path); + + } + catch (IncorrectOperationException e) { + Messages.showMessageDialog( + getContentPane(), + e.getMessage(), + "Error", + Messages.getErrorIcon() + ); + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + } + } + }; + ApplicationManager.getApplication().runReadAction(action); + } + }, + "Create new package", + null); + } + + private class NewPackageAction extends AnAction { + public NewPackageAction() { + super("New Package...", "Create new package", IconLoader.getIcon("/actions/newFolder.png")); + } + + public void actionPerformed(AnActionEvent e) { + createNewPackage(); + } + + public void update(AnActionEvent event) { + Presentation presentation = event.getPresentation(); + presentation.setEnabled(getTreeSelection() != null); + } + + public void enableInModalConext() { + setEnabledInModalContext(true); + } + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageUtil.java new file mode 100644 index 00000000000..2d69de7c485 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PackageUtil.java @@ -0,0 +1,322 @@ +package com.intellij.ide.util; + +import com.intellij.ide.IdeView; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleFileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiRootPackageType; +import com.intellij.util.ActionRunner; +import com.intellij.util.Degenerator; +import com.intellij.util.IncorrectOperationException; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class PackageUtil { + private static final Logger LOG = Logger.getInstance("com.intellij.ide.util.PackageUtil"); + + /** + * @deprecated + */ + public static PsiDirectory findOrCreateDirectoryForPackage(Project project, + String packageName, + PsiDirectory baseDir, + boolean askUserToCreate) throws IncorrectOperationException { + + PsiDirectory psiDirectory = null; + + if (!"".equals(packageName)) { + PsiPackage rootPackage = findLongestExistingPackage(project, packageName); + if (rootPackage != null) { + int beginIndex = rootPackage.getQualifiedName().length() + 1; + packageName = beginIndex < packageName.length() ? packageName.substring(beginIndex) : ""; + String postfixToShow = packageName.replace('.', File.separatorChar); + if (packageName.length() > 0) { + postfixToShow = File.separatorChar + postfixToShow; + } + psiDirectory = selectDirectory(project, rootPackage.getDirectories(), baseDir, postfixToShow); + if (psiDirectory == null) return null; + } + } + + if (psiDirectory == null) { + PsiDirectory[] sourceDirectories = PsiManager.getInstance(project).getRootDirectories(PsiRootPackageType.SOURCE_PATH); + psiDirectory = selectDirectory(project, sourceDirectories, baseDir, + File.separatorChar + packageName.replace('.', File.separatorChar)); + if (psiDirectory == null) return null; + } + + String restOfName = packageName; + boolean askedToCreate = false; + while (restOfName.length() > 0) { + final String name = getLeftPart(restOfName); + PsiDirectory foundExistingDirectory = psiDirectory.findSubdirectory(name); + if (foundExistingDirectory == null) { + if (!askedToCreate && askUserToCreate) { + int toCreate = Messages.showYesNoDialog(project, + "Package " + packageName + " does not exist.\nDo you want to create it?", + "Package Not Found", + Messages.getQuestionIcon()); + if (toCreate != 0) { + return null; + } + askedToCreate = true; + } + psiDirectory = createSubdirectory(psiDirectory, name, project); + } + else { + psiDirectory = foundExistingDirectory; + } + restOfName = cutLeftPart(restOfName); + } + return psiDirectory; + } + + private static PsiDirectory createSubdirectory(final PsiDirectory oldDirectory, + final String name, Project project) throws IncorrectOperationException { + final PsiDirectory[] psiDirectory = new PsiDirectory[1]; + final IncorrectOperationException[] exception = new IncorrectOperationException[1]; + + CommandProcessor.getInstance().executeCommand(project, new Runnable(){ + public void run() { + psiDirectory[0] = ApplicationManager.getApplication().runWriteAction(new Computable() { + public PsiDirectory compute() { + try { + return oldDirectory.createSubdirectory(name); + } + catch (IncorrectOperationException e) { + exception[0] = e; + return null; + } + } + }); + } + }, "Create New Subdirectory", null); + + if (exception[0] != null) throw exception[0]; + + return psiDirectory[0]; + } + + public static PsiDirectory findOrCreateDirectoryForPackage(Module module, + String packageName, + PsiDirectory baseDir, + boolean askUserToCreate) throws IncorrectOperationException { + final Project project = module.getProject(); + PsiDirectory psiDirectory = null; + if (!"".equals(packageName)) { + PsiPackage rootPackage = findLongestExistingPackage(module, packageName); + if (rootPackage != null) { + int beginIndex = rootPackage.getQualifiedName().length() + 1; + packageName = beginIndex < packageName.length() ? packageName.substring(beginIndex) : ""; + String postfixToShow = packageName.replace('.', File.separatorChar); + if (packageName.length() > 0) { + postfixToShow = File.separatorChar + postfixToShow; + } + PsiDirectory[] moduleDirectories = getPackageDirectoriesInModule(rootPackage, module); + psiDirectory = selectDirectory(project, moduleDirectories, baseDir, postfixToShow); + if (psiDirectory == null) return null; + } + } + + if (psiDirectory == null) { + if (!ModuleUtil.checkSourceRootsConfigured(module)) return null; + final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(); + List directoryList = new ArrayList(); + for (int i = 0; i < sourceRoots.length; i++) { + VirtualFile sourceRoot = sourceRoots[i]; + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(sourceRoot); + if (directory != null) { + directoryList.add(directory); + } + } + PsiDirectory[] sourceDirectories = directoryList.toArray(new PsiDirectory[directoryList.size()]); + psiDirectory = selectDirectory(project, sourceDirectories, baseDir, + File.separatorChar + packageName.replace('.', File.separatorChar)); + if (psiDirectory == null) return null; + } + + String restOfName = packageName; + boolean askedToCreate = false; + while (restOfName.length() > 0) { + final String name = getLeftPart(restOfName); + PsiDirectory foundExistingDirectory = psiDirectory.findSubdirectory(name); + if (foundExistingDirectory == null) { + if (!askedToCreate && askUserToCreate) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + askedToCreate = true; + } + else { + int toCreate = Messages.showYesNoDialog(project, + "Package " + packageName + " does not exist.\nDo you want to create it?", + "Package not found", + Messages.getQuestionIcon()); + if (toCreate != 0) { + return null; + } + } + askedToCreate = true; + } + + final PsiDirectory psiDirectory1 = psiDirectory; + try { + psiDirectory = ActionRunner.runInsideWriteAction(new ActionRunner.InterruptibleRunnableWithResult() { + public PsiDirectory run() throws Exception { + return psiDirectory1.createSubdirectory(name); + } + }); + } + catch (Exception e) { + if (e instanceof IncorrectOperationException) { + throw (IncorrectOperationException)e; + } + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } + LOG.error(e); + Degenerator.unableToDegenerateMarker(); + } + + } + else { + psiDirectory = foundExistingDirectory; + } + restOfName = cutLeftPart(restOfName); + } + return psiDirectory; + } + + private static PsiDirectory[] getPackageDirectoriesInModule(PsiPackage rootPackage, Module module) { + PsiManager manager = PsiManager.getInstance(module.getProject()); + final String packageName = rootPackage.getQualifiedName(); + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final ModuleFileIndex moduleFileIndex = moduleRootManager.getFileIndex(); + final VirtualFile[] directories = moduleFileIndex.getDirectoriesByPackageName(packageName, false); + List moduleDirectoryList = new ArrayList(); + for (int i = 0; i < directories.length; i++) { + VirtualFile directory = directories[i]; + moduleDirectoryList.add(manager.findDirectory(directory)); + } + + return moduleDirectoryList.toArray(new PsiDirectory[moduleDirectoryList.size()]); + } + + private static PsiPackage findLongestExistingPackage(Project project, String packageName) { + PsiManager manager = PsiManager.getInstance(project); + String nameToMatch = packageName; + while (true) { + PsiPackage aPackage = manager.findPackage(nameToMatch); + if (aPackage != null && isWritablePackage(aPackage)) return aPackage; + int lastDotIndex = nameToMatch.lastIndexOf("."); + if (lastDotIndex >= 0) { + nameToMatch = nameToMatch.substring(0, lastDotIndex); + } else { + return null; + } + } + } + + private static boolean isWritablePackage(PsiPackage aPackage) { + PsiDirectory[] directories = aPackage.getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (directory.isValid() && directory.isWritable()) { + return true; + } + } + return false; + } + + private static PsiDirectory getWritableDirectory(VirtualFile[] vFiles, PsiManager manager) { + for (int i = 0; i < vFiles.length; i++) { + PsiDirectory directory = manager.findDirectory(vFiles[i]); + if (directory != null && directory.isValid() && directory.isWritable()) { + return directory; + } + } + return null; + } + + private static PsiPackage findLongestExistingPackage(Module module, String packageName) { + final ModuleFileIndex moduleFileIndex = ModuleRootManager.getInstance(module).getFileIndex(); + final PsiManager manager = PsiManager.getInstance(module.getProject()); + + String nameToMatch = packageName; + while (true) { + VirtualFile[] vFiles = moduleFileIndex.getDirectoriesByPackageName(nameToMatch, false); + PsiDirectory directory = getWritableDirectory(vFiles, manager); + if (directory != null) return directory.getPackage(); + + int lastDotIndex = nameToMatch.lastIndexOf("."); + if (lastDotIndex >= 0) { + nameToMatch = nameToMatch.substring(0, lastDotIndex); + } else { + return null; + } + } + } + + private static String getLeftPart(String packageName) { + int index = packageName.indexOf('.'); + return index > -1 ? packageName.substring(0, index) : packageName; + } + + private static String cutLeftPart(String packageName) { + int index = packageName.indexOf('.'); + return index > -1 ? packageName.substring(index + 1) : ""; + } + + public static PsiDirectory selectDirectory(Project project, + PsiDirectory[] packageDirectories, + PsiDirectory defaultDirectory, + String postfixToShow) { + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + + ArrayList possibleDirs = new ArrayList(); + for (int i = 0; i < packageDirectories.length; i++) { + PsiDirectory dir = packageDirectories[i]; + if (!dir.isValid()) continue; + if (!dir.isWritable()) continue; + if (possibleDirs.contains(dir)) continue; + if (!projectFileIndex.isInContent(dir.getVirtualFile())) continue; + possibleDirs.add(dir); + } + + if (possibleDirs.size() == 0) return null; + if (possibleDirs.size() == 1) return possibleDirs.get(0); + + if (ApplicationManager.getApplication().isUnitTestMode()) return possibleDirs.get(0); + + DirectoryChooser chooser = new DirectoryChooser(project); + chooser.setTitle("Choose Destination Directory"); + chooser.fillList(possibleDirs.toArray(new PsiDirectory[possibleDirs.size()]), defaultDirectory, project, postfixToShow); + chooser.show(); + return chooser.isOK() ? chooser.getSelectedDirectory() : null; + } + + public static PsiDirectory getOrChooseDirectory(IdeView view) { + PsiDirectory[] dirs = view.getDirectories(); + if (dirs.length == 0) return null; + if (dirs.length == 1) { + return dirs[0]; + } + else { + Project project = dirs[0].getProject(); + return selectDirectory(project, dirs, null, ""); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PropertiesComponentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PropertiesComponentImpl.java new file mode 100644 index 00000000000..924e45a0ac7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PropertiesComponentImpl.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.Iterator; + +public class PropertiesComponentImpl extends PropertiesComponent implements JDOMExternalizable, ProjectComponent, ApplicationComponent { + private HashMap myMap = new HashMap(); + + + public String getComponentName() { + return "PropertiesComponent"; + } + + PropertiesComponentImpl() {} + + public void disposeComponent() {} + public void initComponent() {} + public void projectClosed() {} + public void projectOpened() {} + public void moduleAdded() {} + + public void readExternal(Element parentNode) throws InvalidDataException { + for (Iterator iterator = parentNode.getChildren("property").iterator(); iterator.hasNext();) { + Element e = (Element)iterator.next(); + + String name = e.getAttributeValue("name"); + String value = e.getAttributeValue("value"); + + if (name != null) { + myMap.put(name, value); + } + } + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + for(Iterator iterator = myMap.keySet().iterator(); iterator.hasNext();){ + String key = (String)iterator.next(); + String value = myMap.get(key); + if (value != null) { + Element element = new Element("property"); + element.setAttribute("name", key); + element.setAttribute("value", value); + parentNode.addContent(element); + } + } + } + + public String getValue(String name) { + return myMap.get(name); + } + + public void setValue(String name, String value) { + myMap.put(name, value); + } + + public boolean isTrueValue(String name) { + return Boolean.valueOf(getValue(name)).booleanValue(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiClassListCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiClassListCellRenderer.java new file mode 100644 index 00000000000..cbac1d07898 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiClassListCellRenderer.java @@ -0,0 +1,28 @@ +package com.intellij.ide.util; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.presentation.java.ClassPresentationUtil; + +public class PsiClassListCellRenderer extends PsiElementListCellRenderer { + public String getElementText(PsiElement element) { + return ClassPresentationUtil.getNameForClass((PsiClass)element, false); + } + + protected String getContainerText(PsiElement element) { + PsiFile file = element.getContainingFile(); + if (file instanceof PsiJavaFile) { + PsiJavaFile javaFile = (PsiJavaFile)file; + String packageName = javaFile.getPackageName(); + if (packageName.length() == 0) return null; + return "(" + packageName + ")"; + } + return null; + } + + protected int getIconFlags() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiElementListCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiElementListCellRenderer.java new file mode 100644 index 00000000000..e40bc860a09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/PsiElementListCellRenderer.java @@ -0,0 +1,94 @@ +package com.intellij.ide.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ListSpeedSearch; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; +import java.util.Comparator; + +public abstract class PsiElementListCellRenderer extends ColoredListCellRenderer{ + protected void customizeCellRenderer( + JList list, + Object value, + int index, + boolean selected, + boolean hasFocus + ){ + if (value instanceof PsiElement){ + PsiElement element = (PsiElement)value; + String name = getElementText(element); + Color color = list.getForeground(); + PsiFile psiFile = element.getContainingFile(); + if (psiFile != null) { + VirtualFile vFile = psiFile.getVirtualFile(); + if (vFile != null) { + FileStatus status = FileStatusManager.getInstance(psiFile.getProject()).getStatus(vFile); + color = status.getColor(); + } + } + append(name,new SimpleTextAttributes(Font.PLAIN, color)); + setIcon(element.getIcon(getIconFlags())); + + String containerText = getContainerText(element); + if (containerText != null){ + append(" " + containerText, new SimpleTextAttributes(Font.PLAIN, Color.GRAY)); + } + } + else{ + setIcon(IconUtilEx.getEmptyIcon(false)); + append(value == null ? "" : value.toString(), new SimpleTextAttributes(Font.PLAIN, list.getForeground())); + } + } + + + public abstract String getElementText(PsiElement element); + + protected abstract String getContainerText(PsiElement element); + + protected abstract int getIconFlags(); + + protected Icon getIcon(PsiElement element){ + return element.getIcon(getIconFlags()); + } + + public Comparator getComparator(){ + return new Comparator() { + public int compare(Object o1, Object o2) { + return getText(o1).compareTo(getText(o2)); + } + + private String getText(Object o){ + if (o instanceof PsiElement){ + PsiElement element = (PsiElement)o; + String elementText = getElementText(element); + String containerText = getContainerText(element); + return containerText != null ? elementText + " " + containerText : elementText; + } + else{ + return o.toString(); + } + } + }; + } + + public void installSpeedSearch(JList list){ + new ListSpeedSearch(list){ + protected String getElementText(Object o){ + if (o instanceof PsiElement){ + return PsiElementListCellRenderer.this.getElementText((PsiElement)o); + } + else{ + return o.toString(); + } + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodOrPointcutWarningDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodOrPointcutWarningDialog.java new file mode 100644 index 00000000000..af8bd451fbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodOrPointcutWarningDialog.java @@ -0,0 +1,86 @@ + +package com.intellij.ide.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +//TODO: review title and text!!! +class SuperMethodOrPointcutWarningDialog extends DialogWrapper { + public static final int NO_EXIT_CODE=NEXT_USER_EXIT_CODE+1; + private String myName; + private boolean myIsPointcut; + private String myClassName; + private String myActionString; + private boolean myIsSuperAbstract; + private boolean myIsParentInterface; + private boolean myIsContainedInInterface; + private boolean myIsContainedInAspect; + + public SuperMethodOrPointcutWarningDialog(Project project, String name, boolean isPointcut, String className, String actionString, boolean isSuperAbstract, boolean isParentInterface, boolean isContainedInInterface, boolean isContainedInAspect) { + super(project, true); + myName = name; + myIsPointcut = isPointcut; + myClassName = className; + myActionString = actionString; + myIsSuperAbstract = isSuperAbstract; + myIsParentInterface = isParentInterface; + myIsContainedInInterface = isContainedInInterface; + myIsContainedInAspect = isContainedInAspect; + setTitle("Warning"); + setButtonsAlignment(SwingUtilities.CENTER); + setOKButtonText("&Yes"); + init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),new NoAction(),getCancelAction()}; + } + + public JComponent createNorthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); + Icon icon = UIManager.getIcon("OptionPane.warningIcon"); + if (icon != null){ + JLabel iconLabel = new JLabel(UIManager.getIcon("OptionPane.questionIcon")); + panel.add(iconLabel, BorderLayout.WEST); + } + JPanel labelsPanel = new JPanel(new GridLayout(3, 1, 0, 0)); + labelsPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 10)); + String classType = myIsContainedInAspect ? "aspect" : (myIsParentInterface ? "interface" : "class"); + String methodOrPointcut = myIsPointcut ? "pointcut" : "method"; + labelsPanel.add(new JLabel(capitalize(methodOrPointcut + " " + myName))); + if (myIsContainedInInterface || !myIsSuperAbstract){ + labelsPanel.add(new JLabel("overrides " + methodOrPointcut + " of " + classType + " " + myClassName + ".")); + } + else{ + labelsPanel.add(new JLabel("implements " + methodOrPointcut + " of " + classType + " " + myClassName + ".")); + } + String s = "Do you want to " + myActionString + " the " + methodOrPointcut + " from " + (myIsParentInterface ? "" : "base ") + classType + "?"; + labelsPanel.add(new JLabel(s)); + panel.add(labelsPanel, BorderLayout.CENTER); + return panel; + } + + public static String capitalize(String text) { + return Character.toUpperCase(text.charAt(0)) + text.substring(1); + } + + public JComponent createCenterPanel() { + return null; + } + + private class NoAction extends AbstractAction { + public NoAction() { + super("&No"); + } + + public void actionPerformed(ActionEvent e) { + close(NO_EXIT_CODE); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodWarningUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodWarningUtil.java new file mode 100644 index 00000000000..759e20df20f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/SuperMethodWarningUtil.java @@ -0,0 +1,59 @@ +package com.intellij.ide.util; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.usageView.UsageViewUtil; + +public class SuperMethodWarningUtil { + public static PsiMethod checkSuperMethod(final PsiMethod method, String actionString) { + PsiClass aClass = method.getContainingClass(); + if (aClass == null) return method; + + PsiMethod superMethod = PsiSuperMethodUtil.findDeepestSuperMethod(method); + if (superMethod == null) return method; + + PsiClass containingClass = superMethod.getContainingClass(); + + SuperMethodOrPointcutWarningDialog dialog = new SuperMethodOrPointcutWarningDialog(method.getProject(), + UsageViewUtil.getDescriptiveName(method), + false, containingClass.getQualifiedName(), + actionString, + containingClass.isInterface() || superMethod.hasModifierProperty(PsiModifier.ABSTRACT), + containingClass.isInterface(), + aClass.isInterface(), containingClass instanceof PsiAspect); + dialog.show(); + + if (dialog.getExitCode() == SuperMethodOrPointcutWarningDialog.OK_EXIT_CODE) return superMethod; + if (dialog.getExitCode() == SuperMethodOrPointcutWarningDialog.NO_EXIT_CODE) return method; + + return null; + } + + public static PsiPointcutDef checkSuperPointcut(final PsiPointcutDef pointcut, String actionString) { + PsiClass aClass = pointcut.getContainingClass(); + if (aClass == null) return pointcut; + + PsiPointcutDef superPointcut = PsiSuperMethodUtil.findDeepestSuperPointcut(pointcut); + if (superPointcut == null) return pointcut; + + PsiClass containingClass = superPointcut.getContainingClass(); + + SuperMethodOrPointcutWarningDialog dialog = new SuperMethodOrPointcutWarningDialog(pointcut.getProject(), + UsageViewUtil.getDescriptiveName(pointcut), + true, containingClass.getQualifiedName(), + actionString, + containingClass.isInterface() || superPointcut.hasModifierProperty(PsiModifier.ABSTRACT), + containingClass.isInterface(), + aClass.isInterface(), containingClass instanceof PsiAspect); + dialog.show(); + + if (dialog.getExitCode() == SuperMethodOrPointcutWarningDialog.OK_EXIT_CODE) return superPointcut; + if (dialog.getExitCode() == SuperMethodOrPointcutWarningDialog.NO_EXIT_CODE) return pointcut; + + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipDialog.java new file mode 100644 index 00000000000..dc6dbf0658b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipDialog.java @@ -0,0 +1,56 @@ + +package com.intellij.ide.util; + +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.event.ActionEvent; + +public class TipDialog extends DialogWrapper{ + private TipPanel myTipPanel; + + public TipDialog(){ + super(true); + setModal(false); + setTitle("Tip of the Day"); + setCancelButtonText("&Close"); + myTipPanel = new TipPanel(); + myTipPanel.nextTip(); + setHorizontalStretch(1.33f); + setVerticalStretch(1.25f); + init(); + } + + protected Action[] createActions(){ + return new Action[]{new PreviousTipAction(),new NextTipAction(),getCancelAction()}; + } + + protected JComponent createCenterPanel(){ + return myTipPanel; + } + + public void dispose(){ + super.dispose(); + } + + private class PreviousTipAction extends AbstractAction{ + public PreviousTipAction(){ + super("&Previous Tip"); + } + + public void actionPerformed(ActionEvent e){ + myTipPanel.prevTip(); + } + } + + private class NextTipAction extends AbstractAction{ + public NextTipAction(){ + super("&Next Tip"); + putValue(DialogWrapper.DEFAULT_ACTION,Boolean.TRUE); + } + + public void actionPerformed(ActionEvent e){ + myTipPanel.nextTip(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipPanel.java new file mode 100644 index 00000000000..9e3c550fb6c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipPanel.java @@ -0,0 +1,158 @@ +package com.intellij.ide.util; + +import com.intellij.ide.GeneralSettings; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.JDOMUtil; +import org.jdom.Document; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Iterator; + +public class TipPanel extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.TipPanel"); + private static final int DEFAULT_WIDTH = 400; + private static final int DEFAULT_HEIGHT = 200; + private JCheckBox myCheckBox; + private JEditorPane browser; + private ArrayList myTipPaths = new ArrayList(); + + public TipPanel() { + setLayout(new BorderLayout()); + JLabel jlabel = new JLabel(IconLoader.getIcon("/general/tip.png")); + jlabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + JLabel jlabel1 = new JLabel("Did you know ... ?"); + Font font = jlabel1.getFont(); + jlabel1.setFont(font.deriveFont(Font.PLAIN, font.getSize() + 4)); + JPanel jpanel = new JPanel(); + jpanel.setLayout(new BorderLayout()); + jpanel.add(jlabel, BorderLayout.WEST); + jpanel.add(jlabel1, BorderLayout.CENTER); + jpanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); + add(jpanel, BorderLayout.NORTH); + browser = new JEditorPane(); + browser.setEditable(false); + browser.setEditorKit(new HTMLEditorKit()); + browser.setBackground(Color.white); + browser.addHyperlinkListener( + new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + //TODO: Open url in browser + } + } + } + ); + JScrollPane scrollPane = new JScrollPane(browser); + add(scrollPane, BorderLayout.CENTER); + myCheckBox = new JCheckBox("Show Tips on Startup", true); + myCheckBox.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + final GeneralSettings settings = GeneralSettings.getInstance(); + myCheckBox.setSelected(settings.showTipsOnStartup()); + myCheckBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + settings.setShowTipsOnStartup(e.getStateChange() == ItemEvent.SELECTED); + } + }); + add(myCheckBox, BorderLayout.SOUTH); + try { + readTips(); + } + catch (Exception exception) { + + } + } + + public Dimension getPreferredSize() { + return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); + } + + public void prevTip() { + if (myTipPaths.size() == 0) { + browser.setText("Tips not found. Make sure you installed IntelliJ IDEA correctly."); + return; + } + GeneralSettings settings = GeneralSettings.getInstance(); + int lastTip = settings.getLastTip(); + + String path; + lastTip--; + if (lastTip <= 0) { + path = (String) myTipPaths.get(myTipPaths.size() - 1); + lastTip = myTipPaths.size(); + } + else { + path = (String) myTipPaths.get(lastTip - 1); + } + + setTip(path, lastTip, browser, settings); + } + + private void setTip (String path, int lastTip, JEditorPane browser, GeneralSettings settings) { + TipUIUtil.openTipInBrowser(path, browser); + + settings.setLastTip(lastTip); + } + + public void nextTip() { + if (myTipPaths.size() == 0) { + browser.setText("Tips not found. Make sure you installed IntelliJ IDEA correctly."); + return; + } + GeneralSettings settings = GeneralSettings.getInstance(); + int lastTip = settings.getLastTip(); + String path; + lastTip++; + if (lastTip - 1 >= myTipPaths.size()) { + path = (String) myTipPaths.get(0); + lastTip = 1; + } + else { + path = (String) myTipPaths.get(lastTip - 1); + } + + setTip(path, lastTip, browser, settings); + /* + try { + String appName = ApplicationUtil.getApplicationName(); + String tipsPath = ResourceUtil.getHomePath() + File.separator + "help" + File.separator + appName + File.separator + "tips" + File.separator; + File file = new File(tipsPath + "tip" + lastTip + ".html"); + if (!file.exists()) { + if (lastTip == 1) { + browser.setText("Tips not found. Make sure you installed IntelliJ IDEA correctly."); + return; + } + lastTip = 1; + file = new File(tipsPath + "tip" + lastTip + ".html"); + if (!file.exists()) { + browser.setText("Tips not found. Make sure you installed IntelliJ IDEA correctly."); + return; + } + } + browser.setPage(file.toURL()); + settings.setLastTip(lastTip); + } + catch (IOException ex) { + ex.printStackTrace(); + } + */ + } + + private void readTips() throws Exception { + String tipsURL = "/tips/" + "tips.xml"; + Document document = JDOMUtil.loadDocument(getClass().getResource(tipsURL).openStream()); + if (document == null) return; + for (Iterator iterator = document.getRootElement().getChildren("tip").iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + myTipPaths.add(element.getAttributeValue("file")); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipUIUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipUIUtil.java new file mode 100644 index 00000000000..c140602d09c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TipUIUtil.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util; + +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.util.SystemInfo; + +import javax.swing.*; +import javax.swing.text.html.HTMLDocument; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URL; +import java.text.MessageFormat; + +/** + * @author dsl + */ +public class TipUIUtil { + private static final String SHORTCUT_ENTITY = "&shortcut:"; + + public static void openTipInBrowser(String tipPath, JEditorPane browser) { + String fileURL = "/tips/" + tipPath; + + /* TODO: detect that file is not present + if (!file.exists()) { + browser.read(new StringReader("Tips for '" + feature.getDisplayName() + "' not found. Make sure you installed IntelliJ IDEA correctly."), null); + return; + } + */ + try { + URL url = TipUIUtil.class.getResource(fileURL); + if (url == null) { + setCantReadText(browser); + return; + } + + final InputStream inputStream = url.openStream(); + final InputStreamReader reader = new InputStreamReader(inputStream); + StringBuffer text = new StringBuffer(); + char[] buf = new char[5000]; + while (reader.ready()) { + final int length = reader.read(buf); + if (length == -1) break; + text.append(buf, 0, length); + } + reader.close(); + updateShortcuts(text); + browser.read(new StringReader(text.toString()), null); + ((HTMLDocument)browser.getDocument()).setBase(url); + } + catch (IOException e) { + setCantReadText(browser); + } + } + + private static void setCantReadText(JEditorPane browser) { + try { + browser.read(new StringReader("Unable to read Tip Of The Day. Make sure IntelliJ IDEA is installed properly."), null); + } + catch (IOException e1) { + // Can't be + } + } + + public static final String FONT = SystemInfo.isMac ? "Courier" : "Verdana"; + public static final String COLOR = "#993300"; + public static final String SIZE = SystemInfo.isMac ? "4" : "3"; + public static final String SHORTCUT_HTML_TEMPLATE = "{0}"; + + private static void updateShortcuts(StringBuffer text) { + int lastIndex = 0; + while(true) { + lastIndex = text.indexOf(SHORTCUT_ENTITY, lastIndex); + if (lastIndex < 0) return; + final int actionIdStart = lastIndex + SHORTCUT_ENTITY.length(); + int actionIdEnd = text.indexOf(";", actionIdStart); + if (actionIdEnd < 0) { + return; + } + final String actionId = text.substring(actionIdStart, actionIdEnd); + final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId); + String shortcutText = ""; + for (int i = 0; i < shortcuts.length; i++) { + final Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + shortcutText = KeymapUtil.getShortcutText(shortcut); + } + } + final String replacement = MessageFormat.format(SHORTCUT_HTML_TEMPLATE, new Object[]{shortcutText}); + text.replace(lastIndex, actionIdEnd + 1, replacement); + lastIndex += replacement.length(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TreeClassChooserDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TreeClassChooserDialog.java new file mode 100644 index 00000000000..a8f7ac1f2dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/TreeClassChooserDialog.java @@ -0,0 +1,386 @@ +package com.intellij.ide.util; + +import com.intellij.ide.projectView.BaseProjectTreeBuilder; +import com.intellij.ide.projectView.PsiClassChildrenSource; +import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure; +import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; +import com.intellij.ide.projectView.impl.ProjectTreeBuilder; +import com.intellij.ide.projectView.impl.nodes.ClassTreeNode; +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.ide.util.gotoByName.ChooseByNamePanel; +import com.intellij.ide.util.gotoByName.GotoClassModel; +import com.intellij.ide.util.treeView.AlphaComparator; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.containers.FilteringIterator; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Iterator; + +public class TreeClassChooserDialog extends DialogWrapper { + private Tree myTree; + private DefaultTreeModel myModel; + private PsiClass mySelectedClass = null; + private Project myProject; + private BaseProjectTreeBuilder myBuilder; + private TabbedPaneWrapper myTabbedPane; + private ChooseByNamePanel myGotoByNamePanel; + private GlobalSearchScope myScope; + private ClassFilter myClassFilter; + private final PsiClass myInitialClass; + private final PsiClassChildrenSource myClassChildrens; + + public static interface ClassFilter { + boolean isAccepted(PsiClass aClass); + } + + public static interface ClassFilterWithScope extends ClassFilter { + GlobalSearchScope getScope(); + } + + public static class InheritanceClassFilter implements ClassFilter { + private final PsiClass myBase; + private final boolean myAcceptsSelf; + private final boolean myAcceptsInner; + private final Condition myAddtionalCondition; + + public InheritanceClassFilter(PsiClass base, boolean acceptsSelf, boolean acceptInner) { + this(base, acceptsSelf, acceptInner, FilteringIterator.alwaysTrueCondition(PsiClass.class)); + } + + public InheritanceClassFilter(PsiClass base, boolean acceptsSelf, boolean acceptInner, + Condition addtionalCondition + ) { + myAcceptsSelf = acceptsSelf; + myAcceptsInner = acceptInner; + myAddtionalCondition = addtionalCondition; + myBase = base; + } + + public boolean isAccepted(PsiClass aClass) { + if (!myAcceptsInner && !(aClass.getParent() instanceof PsiJavaFile)) return false; + if (!myAddtionalCondition.value(aClass)) return false; + if (myBase == null) return true; + return myAcceptsSelf ? + InheritanceUtil.isInheritorOrSelf(aClass, myBase, true) : + aClass.isInheritor(myBase, true); + } + } + + public TreeClassChooserDialog(String title, Project project) { + this( + title, + project, + null + ); + } + + public TreeClassChooserDialog(String title, Project project, PsiClass initialClass) { + this( + title, + project, + GlobalSearchScope.projectScope(project), + null, + initialClass + ); + } + + public TreeClassChooserDialog( + String title, + Project project, + GlobalSearchScope scope, + ClassFilter classFilter, + PsiClass initialClass + ){ + this(title, project, scope, classFilter, initialClass, PsiClassChildrenSource.NONE); + } + + private TreeClassChooserDialog (String title, + Project project, + GlobalSearchScope scope, + ClassFilter classFilter, PsiClass initialClass, PsiClassChildrenSource classChildrens) { + super(project, true); + myScope = scope; + myClassFilter = classFilter; + myInitialClass = initialClass; + myClassChildrens = classChildrens; + setTitle(title); + myProject = project; + init(); + if (initialClass != null) { + selectClass(initialClass); + } + + handleSelectionChanged(); + } + + public static TreeClassChooserDialog withInnerClasses(String title, Project project, GlobalSearchScope scope, + final ClassFilter classFilter, PsiClass initialClass) { + return new TreeClassChooserDialog(title, project, scope, classFilter, initialClass, new PsiClassChildrenSource() { + public void addChildren(PsiClass psiClass, java.util.List children) { + ArrayList innerClasses = new ArrayList(); + PsiClassChildrenSource.CLASSES.addChildren(psiClass, innerClasses); + for (Iterator iterator = innerClasses.iterator(); iterator.hasNext();) { + PsiElement innerClass = iterator.next(); + if (classFilter.isAccepted((PsiClass)innerClass)) children.add(innerClass); + } + } + }); + } + + protected JComponent createCenterPanel() { + myModel = new DefaultTreeModel(new DefaultMutableTreeNode()); + myTree = new Tree(myModel); + + ProjectAbstractTreeStructureBase treeStructure = new AbstractProjectTreeStructure( + myProject) { + public boolean isFlattenPackages() { + return false; + } + + public boolean isShowMembers() { + return myClassChildrens != PsiClassChildrenSource.NONE; + } + + public boolean isHideEmptyMiddlePackages() { + return true; + } + + + protected boolean isAcceptedNotClass(PsiElement child) { + return !(child instanceof PsiFile); + } + + public boolean isAbbreviatePackageNames() { + return false; + } + + public boolean isShowLibraryContents() { + return false; + } + + public boolean isShowModules() { + return false; + } + }; + myBuilder = new ProjectTreeBuilder(myProject, myTree, myModel, AlphaComparator.INSTANCE, treeStructure); + + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.expandRow(0); + myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + myTree.setCellRenderer(new NodeRenderer()); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + + JScrollPane scrollPane = new JScrollPane(myTree); + scrollPane.setPreferredSize(new Dimension(500, 300)); + + myTree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (KeyEvent.VK_ENTER == e.getKeyCode()) { + doOKAction(); + } + } + }); + + myTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + TreePath path = myTree.getPathForLocation(e.getX(), e.getY()); + if (path != null && myTree.isPathSelected(path)) { + doOKAction(); + } + } + } + }); + + myTree.addTreeSelectionListener( + new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + handleSelectionChanged(); + } + } + ); + + new TreeSpeedSearch(myTree); + + myTabbedPane = new TabbedPaneWrapper(); + + final JPanel dummyPanel = new JPanel(new BorderLayout()); + String name = null; + if (myInitialClass != null) { + name = myInitialClass.getName(); + } + myGotoByNamePanel = new ChooseByNamePanel(myProject, new MyGotoClassModel(), name) { + protected void close(boolean isOk) { + super.close(isOk); + + if (isOk) { + doOKAction(); + } + else { + doCancelAction(); + } + } + + protected void initUI(Callback callback, ModalityState modalityState, boolean allowMultipleSelection) { + super.initUI(callback, modalityState, allowMultipleSelection); + dummyPanel.add(myGotoByNamePanel.getPanel(), BorderLayout.CENTER); + IdeFocusTraversalPolicy.getPreferredFocusedComponent(myGotoByNamePanel.getPanel()).requestFocus(); + } + + protected void choosenElementMightChange() { + handleSelectionChanged(); + } + }; + + myTabbedPane.addTab("Search by Name", dummyPanel); + myTabbedPane.addTab("Project", scrollPane); + + myGotoByNamePanel.invoke(new MyCallback(), getModalityState(), false); + + myTabbedPane.installKeyboardNavigation(); + + myTabbedPane.addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent e) { + handleSelectionChanged(); + } + } + ); + + return myTabbedPane.getComponent(); + } + + private void handleSelectionChanged(){ + PsiClass selection = calcSelectedClass(); + setOKActionEnabled(selection != null); + } + + protected void doOKAction() { + mySelectedClass = calcSelectedClass(); + if (mySelectedClass == null) return; + super.doOKAction(); + } + + public PsiClass getSelectedClass() { + return mySelectedClass; + } + + public void selectClass(final PsiClass aClass) { + selectElementInTree(aClass); + } + + public void selectDirectory(final PsiDirectory directory) { + selectElementInTree(directory); + } + + private void selectElementInTree(final PsiElement element) { + if (element == null) + throw new IllegalArgumentException("aClass cannot be null"); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myBuilder == null) return; + myBuilder.buildNodeForElement(element); + DefaultMutableTreeNode node = myBuilder.getNodeForElement(element); + if (node != null) { + final TreePath treePath = new TreePath(node.getPath()); + myTree.expandPath(treePath); + TreeUtil.selectPath(myTree, treePath); + } + } + }, getModalityState()); + } + + private ModalityState getModalityState() { + return ModalityState.stateForComponent(getRootPane()); + } + + private PsiClass calcSelectedClass() { + if (myTabbedPane.getSelectedIndex() == 0) { + return (PsiClass)myGotoByNamePanel.getChosenElement(); + } + else { + TreePath path = myTree.getSelectionPath(); + if (path == null) return null; + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + Object userObject = node.getUserObject(); + if (!(userObject instanceof ClassTreeNode)) return null; + ClassTreeNode descriptor = (ClassTreeNode)userObject; + return descriptor.getPsiClass(); + } + } + + + protected void dispose() { + if (myBuilder != null) { + myBuilder.dispose(); + myBuilder = null; + } + super.dispose(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.ide.util.TreeClassChooserDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return myGotoByNamePanel.getPreferredFocusedComponent(); + } + + private class MyGotoClassModel extends GotoClassModel { + public MyGotoClassModel() { + super(myProject); + } + + public Object[] getElementsByName(final String name, final boolean checkBoxState) { + final PsiManager manager = PsiManager.getInstance(myProject); + PsiClass[] classes = manager.getShortNamesCache().getClassesByName(name, myScope); + + ArrayList list = new ArrayList(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + if (myClassFilter != null && !myClassFilter.isAccepted(aClass)) continue; + list.add(aClass); + } + return list.toArray(new PsiClass[list.size()]); + } + + public String getPromptText() { + return null; + } + } + + private class MyCallback extends ChooseByNameBase.Callback { + public void elementChosen(Object element) { + mySelectedClass = (PsiClass)element; + close(OK_EXIT_CODE); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameBase.java new file mode 100644 index 00000000000..7b0145acb19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -0,0 +1,912 @@ +package com.intellij.ide.util.gotoByName; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.psi.PsiElement; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ListScrollingUtilEx; +import com.intellij.util.Alarm; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public abstract class ChooseByNameBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.ChooseByNameBase"); + + protected final Project myProject; + protected final ChooseByNameModel myModel; + protected final String myInitialText; + + protected Component myPreviouslyFocusedComponent; + + protected JPanelProvider myTextFieldPanel;// Located in the layered pane + protected JTextField myTextField; + protected JPanel myCardContainer; + protected CardLayout myCard; + protected JCheckBox myCheckBox; + protected int myExactPrefixLen; + + protected JScrollPane myListScrollPane; // Located in the layered pane + protected JList myList; + private DefaultListModel myListModel; + private ArrayList> myHistory; + private ArrayList> myFuture; + + protected Callback myActionListener; + + protected final Alarm myAlarm = new Alarm(); + protected boolean myListIsUpToDate = false; + protected boolean myDisposedFlag = false; + + private String[][] myNames = new String[2][]; + private CalcElementsThread myCalcElementsThread; + private static int VISIBLE_LIST_SIZE_LIMIT = 10; + private static final int MAXIMUM_LIST_SIZE_LIMIT = 30; + private int myMaximumListSizeLimit = MAXIMUM_LIST_SIZE_LIMIT; + private static final String NOT_FOUND_MESSAGE_CARD = "syslib"; + private static final String NOT_FOUND_CARD = "nfound"; + private static final String CHECK_BOX_CARD = "chkbox"; + static final int REBUILD_DELAY = 100; + + private static class IgnoreCaseComparator implements Comparator { + public int compare(String a, String b) { + return a.compareToIgnoreCase(b); + } + } + + private static final Comparator UCS_COMPARATOR = new IgnoreCaseComparator(); + + public static abstract class Callback { + public abstract void elementChosen(Object element); + public void onClose() { } + } + + /** + * @param initialText initial text which will be in the lookup text field + */ + protected ChooseByNameBase(Project project, ChooseByNameModel model, String initialText) { + myProject = project; + myModel = model; + myInitialText = initialText; + myExactPrefixLen = 0; + } + + public void invoke(final Callback callback, final ModalityState modalityState, boolean allowMultipleSelection) { + initUI(callback, modalityState, allowMultipleSelection); + } + + public class JPanelProvider extends JPanel implements DataProvider { + LightweightHint myHint = null; + boolean myFocusRequested = false; + + JPanelProvider(LayoutManager mgr) { + super(mgr); + } + + JPanelProvider() { + } + + public Object getData(String dataId) { + if (dataId.equals(DataConstants.PSI_ELEMENT)) { + Object element = getChosenElement(); + + if (element != null && element instanceof PsiElement) { + return element; + } + } + + return null; + } + + public void registerHint(LightweightHint h) { + myHint = h; + } + + public boolean focusRequested() { + boolean focusRequested = myFocusRequested; + + myFocusRequested = false; + + return focusRequested; + } + + public void requestFocus() { + myFocusRequested = true; + } + + public void unregisterHint() { + myHint = null; + } + + public void hideHint() { + if (myHint != null) { + myHint.hide(); + } + } + } + + + + protected void setCheckbox () { + + } + + protected void setSysLibMessage () { + + } + + /** + * @param callback + * @param modalityState - if not null rebuilds list in given {@link ModalityState} + * @param allowMultipleSelection + */ + protected void initUI(final Callback callback, final ModalityState modalityState, boolean allowMultipleSelection) { + myActionListener = callback; + //myTextFieldPanel = new JPanelProvider(new GridBagLayout()); + myTextFieldPanel = new JPanelProvider(); + myTextFieldPanel.setLayout(new BoxLayout(myTextFieldPanel, BoxLayout.Y_AXIS)); + final JPanel hBox = new JPanel(); + hBox.setLayout(new BoxLayout(hBox, BoxLayout.X_AXIS)); + + if (myModel.getPromptText() != null) { + JLabel label = new JLabel(" " + myModel.getPromptText()); + label.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + hBox.add(label); + } + + myCard = new CardLayout(); + myCardContainer = new JPanel(myCard); + + final JPanel checkBoxPanel = new JPanel(); + checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.X_AXIS)); + + checkBoxPanel.add (new JLabel (" (")); + myCheckBox = new JCheckBox(myModel.getCheckBoxName() + " )"); + myCheckBox.setMnemonic(myModel.getCheckBoxMnemonic()); + myCheckBox.setSelected(myModel.loadInitialCheckBoxState()); + checkBoxPanel.add (myCheckBox); + + + myCardContainer.add(checkBoxPanel, CHECK_BOX_CARD); + myCardContainer.add(new JLabel(" (" + myModel.getNotInMessage() + ")"), NOT_FOUND_MESSAGE_CARD); + myCardContainer.add(new JLabel(" (no matches found)" ), NOT_FOUND_CARD); + myCard.show(myCardContainer, CHECK_BOX_CARD); + + //myCaseCheckBox = new JCheckBox("Ignore case"); + //myCaseCheckBox.setMnemonic('g'); + //myCaseCheckBox.setSelected(true); + + //myCamelCheckBox = new JCheckBox("Camel words"); + //myCamelCheckBox.setMnemonic('w'); + //myCamelCheckBox.setSelected(true); + + if (isCheckboxVisible()) { + hBox.add(myCardContainer); + //hBox.add(myCheckBox); + //hBox.add(myCaseCheckBox); + //hBox.add(myCamelCheckBox); + } + myTextFieldPanel.add(hBox); + + myHistory = new ArrayList>(); + myFuture = new ArrayList>(); + myTextField = new MyTextField(); + myTextField.setText(myInitialText); + + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + Font editorFont = new Font(scheme.getEditorFontName(), Font.PLAIN, scheme.getEditorFontSize()); + myTextField.setFont(editorFont); + myTextFieldPanel.add(myTextField, + new GridBagConstraints(0, 1, 3, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + + if (isCloseByFocusLost()) { + myTextField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + if (!myTextFieldPanel.focusRequested()) { + close(false); + myTextFieldPanel.hideHint(); + } + } + }); + } + + myCheckBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + ensureNamesLoaded(myCheckBox.isSelected()); + rebuildList(0, REBUILD_DELAY, null, ModalityState.current()); + } + }); + myCheckBox.setFocusable(false); + + myTextField.getDocument().addDocumentListener(new DocumentAdapter() { + protected void textChanged(DocumentEvent e) { + rebuildList(0, REBUILD_DELAY, null, ModalityState.current()); + choosenElementMightChange(); + } + }); + + myTextField.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (myListScrollPane.isVisible()) { + if (e.getKeyCode() == KeyEvent.VK_DOWN) { + ListScrollingUtilEx.moveDown(myList, e.getModifiersEx()); + } + else if (e.getKeyCode() == KeyEvent.VK_UP) { + ListScrollingUtilEx.moveUp(myList, e.getModifiersEx()); + } + else if (e.getKeyCode() == KeyEvent.VK_PAGE_UP) { + ListScrollingUtil.movePageUp(myList); + } + else if (e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) { + ListScrollingUtil.movePageDown(myList); + } + else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + if (myList.getSelectedValue() instanceof ExtraElem) { + myMaximumListSizeLimit += MAXIMUM_LIST_SIZE_LIMIT; + rebuildList(myList.getSelectedIndex(), REBUILD_DELAY, null, ModalityState.current()); + e.consume(); + } + } + } + } + }); + + myTextField.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + close(true); + } + }); + + myListModel = new DefaultListModel(); + myList = new JList(myListModel); + myList.setFocusable(false); + myList.setSelectionMode(allowMultipleSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : + ListSelectionModel.SINGLE_SELECTION); + myList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (!myTextField.hasFocus()) { + myTextField.requestFocus(); + } + + if (e.getClickCount() == 2) { + if (myList.getSelectedValue() instanceof ExtraElem) { + myMaximumListSizeLimit += MAXIMUM_LIST_SIZE_LIMIT; + rebuildList(myList.getSelectedIndex(), REBUILD_DELAY, null, ModalityState.current()); + e.consume(); + } + else + close(true); + } + } + }); + myList.setCellRenderer(myModel.getListCellRenderer()); + myList.setFont(editorFont); + + myList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + choosenElementMightChange(); + } + }); + + myListScrollPane = new JScrollPane(myList); + + if (!"Motif".equals(UIManager.getLookAndFeel().getID())) { + LookAndFeel.installBorder(myTextFieldPanel, "PopupMenu.border"); + } + LookAndFeel.installColorsAndFont(myTextFieldPanel, "PopupMenu.background", "PopupMenu.foreground", "PopupMenu.font"); + LookAndFeel.installColorsAndFont(myCheckBox, "PopupMenu.background", "PopupMenu.foreground", "PopupMenu.font"); + + showTextFieldPanel(); + + ensureNamesLoaded(myCheckBox.isSelected()); + + if (modalityState != null) { + rebuildList(0, 0, null, modalityState); + } + } + + private synchronized void ensureNamesLoaded(boolean checkboxState) { + int index = checkboxState ? 1 : 0; + if (myNames[index] != null) return; + + Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, myTextField); + //LOG.assertTrue (myTextField != null); + //LOG.assertTrue (window != null); + Window ownerWindow = null; + if (window != null) { + window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + ownerWindow = window.getOwner(); + if (ownerWindow != null) { + ownerWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + } + myNames[index] = myModel.getNames(checkboxState); + + if (window != null) { + window.setCursor(Cursor.getDefaultCursor()); + if (ownerWindow != null) { + ownerWindow.setCursor(Cursor.getDefaultCursor()); + } + } + } + + protected abstract boolean isCheckboxVisible(); + + protected abstract boolean isShowListForEmptyPattern(); + + protected abstract boolean isCloseByFocusLost(); + + private void showTextFieldPanel() { + final JLayeredPane layeredPane = getLayeredPane(); + final Dimension preferredTextFieldPanelSize = myTextFieldPanel.getPreferredSize(); + final int x = (layeredPane.getWidth() - preferredTextFieldPanelSize.width) / 2; + final int paneHeight = layeredPane.getHeight(); + final int y = paneHeight / 3 - preferredTextFieldPanelSize.height / 2; + + + myTextFieldPanel.setBounds(x, y, preferredTextFieldPanelSize.width, preferredTextFieldPanelSize.height); + layeredPane.add(myTextFieldPanel, new Integer(500)); + layeredPane.moveToFront(myTextFieldPanel); + VISIBLE_LIST_SIZE_LIMIT = Math.max + (10, (paneHeight - (y + preferredTextFieldPanelSize.height)) / (preferredTextFieldPanelSize.height / 2) - 1); + + // I'm registering KeyListener to close popup only by KeyTyped event. + // If react on KeyPressed then sometime KeyTyped goes into underlying myEditor. + // It causes typing of Enter into it. + myTextFieldPanel.registerKeyboardAction(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + close(false); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + myList.registerKeyboardAction(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + close(false); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + myPreviouslyFocusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent(myProject); + if (myTextField.requestFocusInWindow()) { + myTextField.requestFocus(); + } + + myTextFieldPanel.validate(); + myTextFieldPanel.paintImmediately(0, 0, myTextFieldPanel.getWidth(), myTextFieldPanel.getHeight()); + } + + private JLayeredPane getLayeredPane() { + JLayeredPane layeredPane; + final Window window = WindowManager.getInstance().suggestParentWindow(myProject); + if (window instanceof JFrame) { + layeredPane = ((JFrame)window).getLayeredPane(); + } + else if (window instanceof JDialog) { + layeredPane = ((JDialog)window).getLayeredPane(); + } + else { + throw new IllegalStateException("cannot find parent window: project=" + myProject + + (myProject != null ? "; open=" + myProject.isOpen() : "") + + "; window=" + window); + } + return layeredPane; + } + + protected final Object myRebuildMutex = new Object (); + + protected void rebuildList(final int pos, final int delay, final Runnable postRunnable, final ModalityState modalityState) { + myListIsUpToDate = false; + myAlarm.cancelAllRequests(); + choosenElementMightChange(); + tryToCancel(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final String text = myTextField.getText(); + if (!isShowListForEmptyPattern() && (text == null || text.trim().length() == 0)) { + myListModel.clear(); + hideList(); + return; + } + final Runnable request = new Runnable() { + public void run() { + final Runnable request = this; + LOG.info ("Rebuild " + hashCode() + " started"); + final CalcElementsCallback callback = new CalcElementsCallback() { + public void run(final ArrayList elements) { + synchronized (myRebuildMutex) { + LOG.info ("Rebuild callback " + hashCode() + " of " + request.hashCode() + " started"); + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myDisposedFlag) { + LOG.info ("Rebuild callback " + hashCode() + " of " + request.hashCode() + " disposed"); + return; + } + + setElementsToList(pos, elements); + + myListIsUpToDate = true; + choosenElementMightChange(); + + if (postRunnable != null) { + postRunnable.run(); + } + LOG.info ("Rebuild callback " + hashCode () + " of " + request.hashCode () + " finished"); + } + } + }; + + tryToCancel(); + + myCalcElementsThread = new CalcElementsThread(text, myCheckBox.isSelected(), callback, modalityState); + myCalcElementsThread.setCanCancel(postRunnable == null); + myCalcElementsThread.start(); + } + }; + + if (delay > 0) { + LOG.info ("Rebuild " + this + " posted with delay " + delay, new Throwable ()); + myAlarm.addRequest(request, delay); + } + else { + LOG.info ("Rebuild " + this + " posted", new Throwable ()); + request.run(); + } + } + }, modalityState); + } + + private void tryToCancel() { + if (myCalcElementsThread != null) { + myCalcElementsThread.cancel(); + myCalcElementsThread = null; + } + } + + private void setElementsToList(int pos, ArrayList elements) { + if (myDisposedFlag) return; + myListModel.clear(); + if (elements.size() == 0) { + myTextField.setForeground(Color.red); + hideList(); + return; + } + + myTextField.setForeground(UIManager.getColor("TextField.foreground")); + for (int i = 0; i < elements.size(); i++) { + myListModel.addElement(elements.get(i)); + } + //if (isTooLong){ + // myListModel.addElement("..."); + //} + ListScrollingUtil.selectItem(myList, Math.min (pos, myListModel.size () - 1)); + myList.setVisibleRowCount(Math.min(VISIBLE_LIST_SIZE_LIMIT, myList.getModel().getSize())); + showList(); + } + + protected abstract void showList(); + + protected abstract void hideList(); + + protected abstract void close(boolean isOk); + + public Object getChosenElement() { + final Object[] elements = getChosenElements(); + return (elements != null && elements.length == 1) ? elements[0] : null; + } + + protected Object[] getChosenElements() { + if (myListIsUpToDate) { + final List values = new ArrayList(Arrays.asList(myList.getSelectedValues())); + values.remove(OUR_EXTRA_ELEMENT); + return values.toArray(new Object[values.size()]); + } + + final String text = myTextField.getText(); + final boolean checkBoxState = myCheckBox.isSelected(); + ensureNamesLoaded(checkBoxState); + final String[] names = checkBoxState ? myNames[1] : myNames[0]; + Object uniqueElement = null; + for (int i = 0; names != null && i < names.length; i++) { + final String name = names[i]; + if (name.equalsIgnoreCase(text)) { + final Object[] elements = myModel.getElementsByName(name, checkBoxState); + if (elements.length > 1) return null; + if (elements.length == 0) continue; + if (uniqueElement != null) return null; + uniqueElement = elements[0]; + } + } + return uniqueElement == null ? ArrayUtil.EMPTY_OBJECT_ARRAY : new Object[] {uniqueElement}; + } + + protected void choosenElementMightChange() { + } + + public static boolean isMyComponent(final Component component) { + return component instanceof MyTextField; + } + + private final class MyTextField extends JTextField { + private final KeyStroke myCompletionKeyStroke; + private final KeyStroke forwardStroke; + private final KeyStroke backStroke; + + public MyTextField() { + super(40); + enableEvents(KeyEvent.KEY_EVENT_MASK); + myCompletionKeyStroke = getShortcut(IdeActions.ACTION_CODE_COMPLETION); + forwardStroke = getShortcut(IdeActions.ACTION_GOTO_FORWARD); + backStroke = getShortcut(IdeActions.ACTION_GOTO_BACK); + + } + + private KeyStroke getShortcut(String actionCodeCompletion) { + final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionCodeCompletion); + for (int i = 0; i < shortcuts.length; i++) { + final Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + return ((KeyboardShortcut)shortcut).getFirstKeyStroke(); + } + } + return null; + } + + protected void processKeyEvent(KeyEvent e) { + { + final int caretPosition = getCaretPosition(); + if (getCaretPosition() < myExactPrefixLen) { + myExactPrefixLen = caretPosition; + } + } + + final KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e); + if (myCompletionKeyStroke != null && keyStroke.equals(myCompletionKeyStroke)) { + e.consume(); + final String pattern = myTextField.getText(); + final String oldText = myTextField.getText(); + final int oldPos = myList.getSelectedIndex(); + myHistory.add(Pair.create(oldText, new Integer(oldPos))); + final Runnable postRunnable = new Runnable() { + public void run() { + fillInCommonPrefix(pattern); + } + }; + rebuildList(0, 0, postRunnable, ModalityState.current()); + return; + } + if (backStroke != null && keyStroke.equals(backStroke)) { + e.consume(); + if (myHistory.size() != 0) { + final String oldText = myTextField.getText(); + final int oldPos = myList.getSelectedIndex(); + //final String pattern = myTextField.getText(); + //final Object current = myList.getSelectedValue(); + final Pair last = myHistory.remove(myHistory.size() - 1); + myTextField.setText(last.first); + myFuture.add(Pair.create(oldText, new Integer(oldPos))); + rebuildList(0, 0, null, ModalityState.current()); + //myList.setSelectedIndex(last.second.intValue()); + } + return; + } + if (forwardStroke != null && keyStroke.equals(forwardStroke)) { + e.consume(); + if (myFuture.size() != 0) { + final String oldText = myTextField.getText(); + final int oldPos = myList.getSelectedIndex(); + final Pair next = myFuture.remove(myFuture.size() - 1); + myTextField.setText(next.first); + myHistory.add(Pair.create(oldText, new Integer(oldPos))); + rebuildList(0, 0, null, ModalityState.current()); + //myList.setSelectedIndex(next.second.intValue()); + } + return; + } + super.processKeyEvent(e); + } + + private void fillInCommonPrefix(final String pattern) { + final ArrayList list = new ArrayList(); + getNamesByPattern(myCheckBox.isSelected(), null, list, pattern); + + if (pattern.indexOf('*') >= 0) return; //TODO: support '*' + final String oldText = myTextField.getText(); + final int oldPos = myList.getSelectedIndex(); + + final String newPattern; + { + String commonPrefix = null; + if (list.size() != 0) { + for (int i = 0; i < list.size(); i++) { + final String string = list.get(i).toLowerCase(); + if (commonPrefix == null) { + commonPrefix = string; + } + else { + while (commonPrefix.length() > 0) { + if (string.startsWith(commonPrefix)) { + break; + } + commonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1); + } + if (commonPrefix.length() == 0) break; + } + } + commonPrefix = list.get(0).substring(0, commonPrefix.length()); + for (int i = 1; i < list.size(); i++) { + final String string = list.get(i).substring(0, commonPrefix.length()); + if (!string.equals(commonPrefix)) { + commonPrefix = commonPrefix.toLowerCase(); + break; + } + } + } + if (commonPrefix == null) commonPrefix = ""; + newPattern = commonPrefix; + } + myHistory.add(Pair.create(oldText, new Integer(oldPos))); + myTextField.setText(newPattern); + myTextField.setCaretPosition(newPattern.length()); + + rebuildList(0, REBUILD_DELAY, null, ModalityState.current()); + } + } + + private static class ExtraElem { + public String toString () { return "..."; } + } + private static final ExtraElem OUR_EXTRA_ELEMENT = new ExtraElem(); + + private class CalcElementsThread extends Thread { + private final String myPattern; + private boolean myCheckboxState; + private final CalcElementsCallback myCallback; + private final ModalityState myModalityState; + + //private boolean myIsTooLong; + private ArrayList myElements = null; + + private volatile boolean [] myCancelled = new boolean[]{false}; + private boolean myCanCancel = true; + //private boolean endsWithSpace; + //private boolean noUpperCase; + + public CalcElementsThread(String pattern, boolean checkboxState, CalcElementsCallback callback, ModalityState modalityState) { + myPattern = pattern; + myCheckboxState = checkboxState; + myCallback = callback; + myModalityState = modalityState; + } + + public void run() { + final ArrayList elements = new ArrayList(); + Runnable action = new Runnable() { + public void run() { + try { + ensureNamesLoaded(myCheckboxState); + addElementsByPattern(elements, myPattern); + } + catch (ProcessCanceledException e) { + } + } + }; + ApplicationManager.getApplication().runReadAction(action); + + if (myCancelled[0]) return; + + if (elements.size() == 0 && !myCheckboxState) { + myCard.show(myCardContainer, NOT_FOUND_MESSAGE_CARD); + myCheckboxState = true; + ApplicationManager.getApplication().runReadAction(action); + } else { + myCard.show(myCardContainer, CHECK_BOX_CARD); + } + if (elements.size() == 0) + myCard.show(myCardContainer, NOT_FOUND_CARD); + + myElements = elements; + + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myCallback.run(myElements); + } + }, myModalityState); + } + + public void setCanCancel(boolean canCancel) { + myCanCancel = canCancel; + } + + + private void addElementsByPattern(ArrayList elementsArray, String pattern) { //throws ProcessCanceledException { + ArrayList namesList = new ArrayList(); + boolean ov = getNamesByPattern(myCheckboxState, myCancelled, namesList, pattern); + if (myCancelled[0]) + throw new ProcessCanceledException(); + Collections.sort(namesList, UCS_COMPARATOR); + + All: + for (int i = 0; i < namesList.size(); i++) { + if (myCancelled[0]) + throw new ProcessCanceledException(); + final Object o = namesList.get(i); + final String name = (String)o; + final Object[] elements = myModel.getElementsByName(name, myCheckboxState); + for (int j = 0; j < elements.length; j++) { + final Object element = elements[j]; + elementsArray.add(element); + if (elementsArray.size() >= myMaximumListSizeLimit) { + ov = true; + break All; + } + + } + + } + + if (ov) { + elementsArray.add(OUR_EXTRA_ELEMENT); + } + } + + public void cancel() { + if (myCanCancel) { + myCancelled[0] = true; + } + } + } + + private boolean getNamesByPattern(final boolean checkboxState, + final boolean[] cancelled, + final ArrayList list, + final String pattern) throws ProcessCanceledException { + if (!isShowListForEmptyPattern()) { + LOG.assertTrue(pattern.length() > 0); + } + + boolean ov = false; + final String[] names = checkboxState ? myNames[1] : myNames[0]; + final Pair pref_regex = buildRegexp(pattern); + final String regex = pref_regex.getSecond(); + + try { + final Pattern compiledPattern = Pattern.compile(regex); + final Matcher matcher = compiledPattern.matcher(""); + for (int i = 0; i < names.length; i++) { + if (cancelled != null && cancelled[0]) { + throw new ProcessCanceledException(); + } + final String name = names[i]; + if (matcher.reset(name).matches()) { + list.add(name); + } + } + } + catch (PatternSyntaxException e) { + } + + return ov; + } + + private static boolean containsOnlyUppercaseLetters(String s) { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c != '*' && !Character.isUpperCase(c)) return false; + } + return true; + } + + private Pair buildRegexp(String pattern) { + String pref; + { + final int len = pattern.length (); + int i = 0; + while (i != len && (Character.isLetterOrDigit(pattern.charAt(i)) && (i == 0 || !Character.isUpperCase(pattern.charAt(i))))) + ++ i; + pref = pattern.substring(0,i); + } + + + { + final int eol = pattern.indexOf ('\n'); + if (eol != -1) + pattern = pattern.substring (0, eol); + } + if (pattern.length () >= 80) + pattern = pattern.substring (0, 80); + + final StringBuffer buffer = new StringBuffer(); + boolean lastIsUppercase = false; + final boolean endsWithSpace = StringUtil.endsWithChar(pattern, ' '); + final boolean uppercaseOnly = containsOnlyUppercaseLetters(pattern); + pattern = pattern.trim(); + myExactPrefixLen = Math.min(myExactPrefixLen, pattern.length()); + for (int i = 0; i != myExactPrefixLen; ++i) { + final char c = pattern.charAt(i); + if (Character.isLetterOrDigit(c)) { + buffer.append(c); + } + else { + buffer.append("\\u"); + buffer.append(Integer.toHexString(c + 0x20000).substring(1)); + } + } + for (int i = myExactPrefixLen; i < pattern.length(); i++) { + final char c = pattern.charAt(i); + lastIsUppercase = false; + if (Character.isLetterOrDigit(c)) { + // This logic allows to use uppercase letters only to catch the name like PDM for PsiDocumentManager + if (Character.isUpperCase(c)) { + if (!uppercaseOnly) { + buffer.append('('); + } + if (i > 0) buffer.append("[a-z0-9]*"); + buffer.append(c); + if (!uppercaseOnly) { + buffer.append('|'); + buffer.append(Character.toLowerCase(c)); + buffer.append(')'); + } + lastIsUppercase = true; + } + else if (Character.isLowerCase(c)) { + buffer.append('['); + buffer.append(c); + buffer.append('|'); + buffer.append(Character.toUpperCase(c)); + buffer.append(']'); + } + else { + buffer.append(c); + } + } + else if (c == '*') { + buffer.append(".*"); + } + else { + buffer.append("\\u"); + buffer.append(Integer.toHexString(c + 0x20000).substring(1)); + } + } + + if (!endsWithSpace) { + buffer.append(".*"); + } + else if (lastIsUppercase) { + buffer.append("[a-z0-9]*"); + } + + final String regex = buffer.toString(); + return Pair.create (pref, regex); + } + + private static interface CalcElementsCallback { + void run(ArrayList elements); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameModel.java new file mode 100644 index 00000000000..074fb3de39d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNameModel.java @@ -0,0 +1,21 @@ + +package com.intellij.ide.util.gotoByName; + +import javax.swing.*; + +public interface ChooseByNameModel { + String getPromptText(); + + String getNotInMessage(); + String getNotFoundMessage(); + String getCheckBoxName(); + char getCheckBoxMnemonic(); + boolean loadInitialCheckBoxState(); + void saveInitialCheckBoxState(boolean state); + + ListCellRenderer getListCellRenderer(); + + String[] getNames(boolean checkBoxState); + Object[] getElementsByName(String name, boolean checkBoxState); + String getElementName(Object element); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePanel.java new file mode 100644 index 00000000000..eb1d1e8363b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePanel.java @@ -0,0 +1,57 @@ +package com.intellij.ide.util.gotoByName; + +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; + +public class ChooseByNamePanel extends ChooseByNameBase { + private JPanel myPanel; + + public ChooseByNamePanel(Project project, ChooseByNameModel model, String initialText){ + super(project, model, initialText); + } + + protected void initUI(ChooseByNameBase.Callback callback, ModalityState modalityState, boolean allowMultipleSelection) { + super.initUI(callback, modalityState, allowMultipleSelection); + + //myTextFieldPanel.setBorder(new EmptyBorder(0,0,0,0)); + myTextFieldPanel.setBorder(null); + + myPanel = new JPanel(new GridBagLayout()); + + myPanel.add(myTextFieldPanel, new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)); + myPanel.add(myListScrollPane, new GridBagConstraints(0,1,1,1,1,1,GridBagConstraints.WEST,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0)); + } + + public JComponent getPreferredFocusedComponent() { + return myTextField; + } + + protected void showList(){ + } + + protected void hideList(){ + } + + protected void close(boolean isOk) { + } + + protected boolean isShowListForEmptyPattern() { + return true; + } + + protected boolean isCloseByFocusLost() { + return false; + } + + protected boolean isCheckboxVisible(){ + return false; + } + + public JPanel getPanel(){ + return myPanel; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java new file mode 100644 index 00000000000..c6f9a93fe75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java @@ -0,0 +1,155 @@ +package com.intellij.ide.util.gotoByName; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; + +import javax.swing.*; +import java.awt.*; + +public class ChooseByNamePopup extends ChooseByNameBase{ + private static final Key CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY = new Key("ChooseByNamePopup"); + private ChooseByNamePopup(final Project project, final ChooseByNameModel model, final String initialText) { + super(project, model, initialText); + } + + protected void initUI(final ChooseByNameBase.Callback callback, final ModalityState modalityState, boolean allowMultipleSelection) { + super.initUI(callback, modalityState, allowMultipleSelection); + //LaterInvocatorEx.enterModal(myTextFieldPanel); + if (myInitialText != null) { + rebuildList(0, 0, null, ModalityState.current()); + } + } + + protected boolean isCheckboxVisible() { + return true; + } + + protected boolean isShowListForEmptyPattern(){ + return false; + } + + protected boolean isCloseByFocusLost(){ + return true; + } + + protected void showList() { + final JLayeredPane layeredPane = myTextField.getRootPane().getLayeredPane(); + final Rectangle bounds = myTextFieldPanel.getBounds(); + bounds.y += myTextFieldPanel.getHeight(); + final Dimension preferredScrollPaneSize = myListScrollPane.getPreferredSize(); + preferredScrollPaneSize.width = Math.max(myTextFieldPanel.getWidth(), preferredScrollPaneSize.width); + if (bounds.y + preferredScrollPaneSize.height > layeredPane.getHeight()){ // clip scroll pane + preferredScrollPaneSize.height = layeredPane.getHeight() - bounds.y; + } + + { + if(preferredScrollPaneSize.width > layeredPane.getWidth() - bounds.x){ + bounds.x = layeredPane.getX() + Math.max (1, layeredPane.getWidth()-preferredScrollPaneSize.width); + if(preferredScrollPaneSize.width > layeredPane.getWidth() - bounds.x){ + preferredScrollPaneSize.width = layeredPane.getWidth() - bounds.x; + } + } + } + + myListScrollPane.setBounds(bounds.x, bounds.y, preferredScrollPaneSize.width, preferredScrollPaneSize.height); + + layeredPane.add(myListScrollPane, new Integer(600)); + layeredPane.moveToFront(myListScrollPane); + myListScrollPane.validate(); + myListScrollPane.setVisible(true); + } + + protected void hideList() { + if (myListScrollPane.isVisible()){ + myListScrollPane.setVisible(false); + } + } + + protected void close(final boolean isOk) { + if (myDisposedFlag){ + return; + } + + if (isOk){ + myModel.saveInitialCheckBoxState(myCheckBox.isSelected()); + + final Object[] chosenElements = getChosenElements(); + for (int i = 0; i < chosenElements.length; i++) { + myActionListener.elementChosen(chosenElements[i]); + } + + if (chosenElements.length > 0){ + final String enteredText = myTextField.getText().toLowerCase(); + if (enteredText.indexOf('*') >= 0) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.wildcards"); + } + else { + for (int i = 0; i < chosenElements.length; i++) { + final String choosenElementText = myModel.getElementName(chosenElements[i]).toLowerCase(); + if (!choosenElementText.startsWith(enteredText)) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.camelprefix"); + break; + } + } + } + } + else{ + return; + } + } + + myDisposedFlag = true; + myAlarm.cancelAllRequests(); + myProject.putUserData(CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY, null); + + //LaterInvocatorEx.leaveModal(myTextFieldPanel); + + cleanupUI(); + myActionListener.onClose (); + } + + private void cleanupUI() { + JLayeredPane layeredPane; + try { + // Return focus back to the previous focused component if we need to do it and + // previous focused componen is showing. + if ( + (myPreviouslyFocusedComponent instanceof JComponent) && + myPreviouslyFocusedComponent.isShowing() + ){ + final JComponent _component = (JComponent)myPreviouslyFocusedComponent; + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(_component); + } + if (myPreviouslyFocusedComponent != null) { + myPreviouslyFocusedComponent.requestFocus(); + } + + layeredPane = myTextFieldPanel.getRootPane().getLayeredPane(); + layeredPane.remove(myListScrollPane); + layeredPane.remove(myTextFieldPanel); + } + finally { + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(null); + } + layeredPane.validate(); + layeredPane.repaint(); + } + + public static ChooseByNamePopup createPopup(final Project project, final ChooseByNameModel model) { + final ChooseByNamePopup newPopup; + final ChooseByNamePopup oldPopup = project.getUserData(CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY); + if (oldPopup != null) { + final String initialText = oldPopup.myTextField.getText(); + oldPopup.close(false); + newPopup = new ChooseByNamePopup(project, model, initialText); + } else { + newPopup = new ChooseByNamePopup(project, model, null); + } + + project.putUserData(CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY, newPopup); + return newPopup; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java new file mode 100644 index 00000000000..9ea04058ef4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.ide.util.NavigationItemListCellRenderer; +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.util.*; + +public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel { + protected final Project myProject; + private final ChooseByNameContributor[] myContributors; + + protected ContributorsBasedGotoByModel(Project project, ChooseByNameContributor[] contributors) { + myProject = project; + myContributors = contributors; + } + + public ListCellRenderer getListCellRenderer() { + return new NavigationItemListCellRenderer(); + } + + public String[] getNames(boolean checkBoxState) { + Set names = new HashSet(); + for (int i = 0; i < myContributors.length; i++) { + ChooseByNameContributor contributor = myContributors[i]; + names.addAll(Arrays.asList(contributor.getNames(myProject, checkBoxState))); + } + + return names.toArray(new String[names.size()]); + } + + public Object[] getElementsByName(String name, boolean checkBoxState) { + List items = new ArrayList(); + for (int i = 0; i < myContributors.length; i++) { + ChooseByNameContributor contributor = myContributors[i]; + items.addAll(Arrays.asList(contributor.getItemsByName(name, myProject, checkBoxState))); + } + return items.toArray(); + } + + public String getElementName(Object element) { + return ((NavigationItem)element).getName(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java new file mode 100644 index 00000000000..f94c2fae75f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.Arrays; + +public class DefaultClassNavigationContributor implements ChooseByNameContributor { + public DefaultClassNavigationContributor() { + } + + public String[] getNames(Project project, boolean includeNonProjectItems) { + return PsiManager.getInstance(project).getShortNamesCache().getAllClassNames(includeNonProjectItems); + } + + public NavigationItem[] getItemsByName(String name, Project project, boolean includeNonProjectItems) { + final GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + return filterUnshowable(PsiManager.getInstance(project).getShortNamesCache().getClassesByName(name, scope)); + } + + private static NavigationItem[] filterUnshowable(PsiClass[] items) { + ArrayList list = new ArrayList(items.length); + for (int i = 0; i < items.length; i++) { + PsiClass item = items[i]; + if (item.getContainingFile().getVirtualFile() == null) continue; + list.add(item); + } + return (NavigationItem[])list.toArray(new NavigationItem[list.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java new file mode 100644 index 00000000000..f598dfdb321 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class DefaultSymbolNavigationContributor implements ChooseByNameContributor { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor"); + public DefaultSymbolNavigationContributor() { + } + + public String[] getNames(Project project, boolean includeNonProjectItems) { + PsiShortNamesCache cache = PsiManager.getInstance(project).getShortNamesCache(); + HashSet set = new HashSet(); + cache.getAllMethodNames(includeNonProjectItems, set); + cache.getAllFieldNames(includeNonProjectItems, set); + cache.getAllClassNames(includeNonProjectItems, set); + return set.toArray(new String[set.size()]); + } + + public NavigationItem[] getItemsByName(String name, Project project, boolean includeNonProjectItems) { + GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + PsiShortNamesCache cache = PsiManager.getInstance(project).getShortNamesCache(); + + PsiMethod[] methods = cache.getMethodsByName(name, scope); + methods = filterInheritedMethods(methods); + PsiField[] fields = cache.getFieldsByName(name, scope); + PsiClass[] classes = cache.getClassesByName(name, scope); + + List result = new ArrayList(); + result.addAll(Arrays.asList(methods)); + result.addAll(Arrays.asList(fields)); + result.addAll(Arrays.asList(classes)); + filterOutNonOpenable(result); + PsiMember[] array = result.toArray(new PsiMember[result.size()]); + Arrays.sort(array, MyComparator.INSTANCE); + return array; + } + + private void filterOutNonOpenable(List members) { + ListIterator it = members.listIterator(); + while (it.hasNext()) { + PsiMember member = it.next(); + if (isNonOpenable(member)) { + it.remove(); + } + } + } + + private boolean isNonOpenable(PsiMember member) { + return member.getContainingFile().getVirtualFile() == null; + } + + private PsiMethod[] filterInheritedMethods(PsiMethod[] methods) { + ArrayList list = new ArrayList(); + for(int i = 0; i < methods.length; i++){ + PsiMethod method = methods[i]; + if (method.isConstructor()) continue; + PsiMethod[] supers = PsiSuperMethodUtil.findSuperMethods(method); + if (supers.length > 0) continue; + list.add(method); + } + return list.toArray(new PsiMethod[list.size()]); + } + + private static class MyComparator implements Comparator{ + public static final MyComparator INSTANCE = new MyComparator(); + + private final GotoSymbolCellRenderer myRenderer = new GotoSymbolCellRenderer(); + + public int compare(Object o1, Object o2) { + if (o1 == o2) return 0; + + PsiElement element1 = (PsiElement)o1; + PsiElement element2 = (PsiElement)o2; + + PsiModifierList modifierList1 = ((PsiModifierListOwner)element1).getModifierList(); + PsiModifierList modifierList2 = ((PsiModifierListOwner)element2).getModifierList(); + int level1 = PsiUtil.getAccessLevel(modifierList1); + int level2 = PsiUtil.getAccessLevel(modifierList2); + if (level1 != level2) return level2 - level1; + + int kind1 = getElementTypeLevel(element1); + int kind2 = getElementTypeLevel(element2); + if (kind1 != kind2) return kind1 - kind2; + + if (element1 instanceof PsiMethod){ + LOG.assertTrue(element2 instanceof PsiMethod); + PsiParameter[] parms1 = ((PsiMethod)element1).getParameterList().getParameters(); + PsiParameter[] parms2 = ((PsiMethod)element2).getParameterList().getParameters(); + + if (parms1.length != parms2.length) return parms1.length - parms2.length; + } + + String text1 = myRenderer.getElementText(element1); + String text2 = myRenderer.getElementText(element2); + if (!text1.equals(text2)) return text1.compareTo(text2); + + String containerText1 = myRenderer.getContainerText(element1); + String containerText2 = myRenderer.getContainerText(element2); + if (containerText1 == null) containerText1 = ""; + if (containerText2 == null) containerText2 = ""; + return containerText1.compareTo(containerText2); + } + + private int getElementTypeLevel(PsiElement element){ + if (element instanceof PsiMethod){ + return 1; + } + else if (element instanceof PsiField){ + return 2; + } + else if (element instanceof PsiClass){ + return 3; + } + else{ + LOG.error(element.toString()); + return 0; + } + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoClassModel2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoClassModel2.java new file mode 100644 index 00000000000..80088382b39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoClassModel2.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.navigation.ChooseByNameRegistry; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; + +public class GotoClassModel2 extends ContributorsBasedGotoByModel { + public GotoClassModel2(Project project) { + super(project, ChooseByNameRegistry.getInstance().getClassModelContributors()); + } + + public String getPromptText() { + return "Enter class name:"; + } + + public String getCheckBoxName() { + return "Include non-project classes"; + } + + public String getNotInMessage() { + return "no matches found in project"; + } + + public String getNotFoundMessage() { + return "no matches found"; + } + + public char getCheckBoxMnemonic() { + // Some combination like Alt+N, Ant+O, etc are a dead sysmbols, therefore + // we have to change mnemonics for Mac users. + return SystemInfo.isMac?'I':'n'; + } + + public boolean loadInitialCheckBoxState() { + PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject); + if ("true".equals(propertiesComponent.getValue("GoToClass.toSaveIncludeLibraries"))){ + return "true".equals(propertiesComponent.getValue("GoToClass.includeLibraries")); + } + else{ + return false; + } + } + + public void saveInitialCheckBoxState(boolean state) { + PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject); + if ("true".equals(propertiesComponent.getValue("GoToClass.toSaveIncludeLibraries"))){ + propertiesComponent.setValue("GoToClass.includeLibraries", state ? "true" : "false"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java new file mode 100644 index 00000000000..dc7f3c83861 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java @@ -0,0 +1,21 @@ +package com.intellij.ide.util.gotoByName; + +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.psi.*; + +class GotoFileCellRenderer extends PsiElementListCellRenderer{ + public String getElementText(PsiElement element) { + final PsiFile file = (PsiFile)element; + return file.getName(); + } + + protected String getContainerText(PsiElement element) { + PsiFile file = (PsiFile)element; + String path = "(" + file.getContainingDirectory().getVirtualFile().getPresentableUrl() + ")"; + return path; + } + + protected int getIconFlags() { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileModel.java new file mode 100644 index 00000000000..27dff422ff7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoFileModel.java @@ -0,0 +1,92 @@ + +package com.intellij.ide.util.gotoByName; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; + +import java.util.ArrayList; + +public class GotoFileModel implements ChooseByNameModel{ + private final Project myProject; + + public GotoFileModel(Project project) { + myProject = project; + } + + public String getPromptText() { + return "Enter file name:"; + } + + public String getCheckBoxName() { + return "Include java files"; + } + + public char getCheckBoxMnemonic() { + return 'j'; + } + + public String getNotInMessage() { + return "no non-.java files found"; + } + + public String getNotFoundMessage() { + return "no files found"; + } + public boolean loadInitialCheckBoxState() { + PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject); + return "true".equals(propertiesComponent.getValue("GoToClass.includeJavaFiles")); + } + + public void saveInitialCheckBoxState(boolean state) { + PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject); + propertiesComponent.setValue("GoToClass.includeJavaFiles", state ? "true" : "false"); + } + + public PsiElementListCellRenderer getListCellRenderer() { + return new GotoFileCellRenderer(); + } + + public String[] getNames(boolean checkBoxState) { + String[] fileNames = PsiManager.getInstance(myProject).getShortNamesCache().getAllFileNames(); + + ArrayList array = new ArrayList(); + for(int i = 0; i < fileNames.length; i++){ + String fileName = fileNames[i]; + FileType type = FileTypeManager.getInstance().getFileTypeByFileName(fileName); + if (type.isBinary()) continue; + //if (!checkBoxState && (type == FileType.JAVA || type == FileType.CLASS)) continue; + if (type == StdFileTypes.CLASS) continue; + array.add(fileName); + } + + return (String[])array.toArray(new String[array.size()]); + } + + public Object[] getElementsByName(final String name, final boolean checkBoxState) { + PsiFile[] psiFiles = PsiManager.getInstance(myProject).getShortNamesCache().getFilesByName(name); + if (checkBoxState){ + return psiFiles; + } + else{ + ArrayList list = new ArrayList(); + for(int i = 0; i < psiFiles.length; i++){ + PsiFile file = psiFiles[i]; + if (file instanceof PsiJavaFile) continue; + list.add(file); + } + return (PsiFile[])list.toArray(new PsiFile[list.size()]); + } + } + + public String getElementName(final Object element) { + if (!(element instanceof PsiFile)) return null; + return ((PsiFile)element).getName(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolCellRenderer.java new file mode 100644 index 00000000000..fed8cbd6770 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolCellRenderer.java @@ -0,0 +1,21 @@ +package com.intellij.ide.util.gotoByName; + +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; + +public class GotoSymbolCellRenderer extends PsiElementListCellRenderer { + protected int getIconFlags() { + return Iconable.ICON_FLAG_VISIBILITY; + } + + public String getElementText(PsiElement element){ + return SymbolPresentationUtil.getSymbolPresentableText(element); + } + + public String getContainerText(PsiElement element){ + return SymbolPresentationUtil.getSymbolContainerText(element); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java new file mode 100644 index 00000000000..80b92cc4303 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ide.util.gotoByName; + +import com.intellij.navigation.ChooseByNameRegistry; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; + +public class GotoSymbolModel2 extends ContributorsBasedGotoByModel { + public GotoSymbolModel2(Project project) { + super(project, ChooseByNameRegistry.getInstance().getSymbolModelContributors()); + } + + public String getPromptText() { + return "Enter symbol name:"; + } + + public String getCheckBoxName() { + return "Include non-project symbols"; + } + + public String getNotInMessage() { + return "no matches found in project"; + } + + public String getNotFoundMessage() { + return "no matches found"; + } + + public char getCheckBoxMnemonic() { + // Some combination like Alt+N, Ant+O, etc are a dead sysmbols, therefore + // we have to change mnemonics for Mac users. + return SystemInfo.isMac?'I':'n'; + } + + public boolean loadInitialCheckBoxState() { + return false; + } + + public void saveInitialCheckBoxState(boolean state) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/JdkChooserPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/JdkChooserPanel.java new file mode 100644 index 00000000000..7fd2204cbea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/JdkChooserPanel.java @@ -0,0 +1,194 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import gnu.trove.TIntArrayList; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class JdkChooserPanel extends JPanel { + private JList myList = null; + private DefaultListModel myListModel = null; + private ProjectJdk myCurrentJdk; + + public JdkChooserPanel() { + super(new BorderLayout()); + myListModel = new DefaultListModel(); + myList = new JList(myListModel); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myList.setCellRenderer(new ProjectJdkRenderer()); + myList.setPrototypeCellValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + fillList(); + + myList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + myCurrentJdk = (ProjectJdk)myList.getSelectedValue(); + } + }); + myList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + editJdkTable(); + } + } + }); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(new JScrollPane(myList), BorderLayout.CENTER); + add(panel, BorderLayout.CENTER); + if (myListModel.getSize() > 0) { + myList.setSelectedIndex(0); + } + } + + public ProjectJdk getChosenJdk() { + return myCurrentJdk; + } + + public void editJdkTable() { + ProjectJdksEditor editor = new ProjectJdksEditor((ProjectJdk)myList.getSelectedValue(), myList); + editor.show(); + if (editor.isOK()) { + ProjectJdk selectedJdk = editor.getSelectedJdk(); + Object[] selectedValues = selectedJdk != null ? new Object[]{selectedJdk} : myList.getSelectedValues(); + fillList(); + // restore selection + TIntArrayList list = new TIntArrayList(); + for (int i = 0; i < selectedValues.length; i++) { + int idx = myListModel.indexOf(selectedValues[i]); + if (idx >= 0) { + list.add(idx); + } + } + final int[] indicesToSelect = list.toNativeArray(); + if (indicesToSelect.length > 0) { + myList.setSelectedIndices(indicesToSelect); + } + else if (myList.getModel().getSize() > 0) { + myList.setSelectedIndex(0); + } + + myCurrentJdk = (ProjectJdk)myList.getSelectedValue(); + } + } + + public JList getPreferredFocusedComponent() { + return myList; + } + + void fillList() { + myListModel.clear(); + ProjectJdkTable jdkTable = ProjectJdkTable.getInstance(); + ProjectJdk[] jdks = jdkTable.getAllJdks(); + for (int i = 0; i < jdks.length; i++) { + ProjectJdk projectJdk = jdks[i]; + myListModel.addElement(projectJdk); + } + } + + public JComponent getDefaultFocusedComponent() { + return myList; + } + + public void selectJdk(ProjectJdk defaultJdk) { + final int index = myListModel.indexOf(defaultJdk); + if (index >= 0) { + myList.setSelectedIndex(index); + } + } + + public static class ProjectJdkRenderer extends ColoredListCellRenderer { + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + if (value instanceof ProjectJdk) { + CellAppearanceUtils.forJdk((ProjectJdk)value, false).customize(this); + } + else if (value != null) { + final String str = value.toString(); + if (str != null) { + append(str, SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES); + } + } + } + } + + public static ProjectJdk showDialog(final Component parent) { + return showDialog(null, parent, null); + } + + public static ProjectJdk showDialog(String title, final Component parent, ProjectJdk jdkToSelect) { + final JdkChooserPanel jdkChooserPanel = new JdkChooserPanel(); + final MyDialog dialog = jdkChooserPanel.new MyDialog(parent); + if (title != null) { + dialog.setTitle(title); + } + if (jdkToSelect != null) { + jdkChooserPanel.selectJdk(jdkToSelect); + } + dialog.show(); + return dialog.isOK() ? jdkChooserPanel.getChosenJdk() : null; + } + + public class MyDialog extends DialogWrapper implements ListSelectionListener { + + public MyDialog(Component parent) { + super(parent, true); + setTitle("Select JDK"); + init(); + myList.addListSelectionListener(this); + updateOkButton(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.ide.util.projectWizard.JdkChooserPanel.MyDialog"; + } + + public void valueChanged(ListSelectionEvent e) { + updateOkButton(); + } + + private void updateOkButton() { + setOKActionEnabled(myList.getSelectedValue() != null); + } + + protected void dispose() { + myList.removeListSelectionListener(this); + super.dispose(); + } + + protected JComponent createCenterPanel() { + return JdkChooserPanel.this; + } + + protected Action[] createActions() { + return new Action[]{new ConfigureAction(), getOKAction(), getCancelAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myList; + } + + private final class ConfigureAction extends AbstractAction { + public ConfigureAction() { + super("Configure..."); + putValue(Action.MNEMONIC_KEY, new Integer('E')); + } + + public void actionPerformed(ActionEvent e) { + editJdkTable(); + } + } + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleCreationPromptStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleCreationPromptStep.java new file mode 100644 index 00000000000..d3097314987 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleCreationPromptStep.java @@ -0,0 +1,66 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemListener; + +/** + * @author Eugene Zhuravlev + * Date: Jan 21, 2004 + */ +public class ModuleCreationPromptStep extends ModuleWizardStep { + private static final Icon NEW_PROJECT_ICON = IconLoader.getIcon("/newprojectwizard.png"); + private JPanel myPanel; + private JRadioButton myRbCreateSingle; + private JRadioButton myRbCreateMultiple; + + public ModuleCreationPromptStep() { + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + final String promptText = + "A functional IDEA project must have at least one module. In most cases, one module would be quite enough.\n" + + "To quickly create a single-module project and start working right away, select the \"Create single-module project\" option.\n" + + "For creating a more complex project, with multiple modules, use the \"Create/configure multi-module project\" option."; + final JLabel promptLabel = new JLabel(promptText); + promptLabel.setUI(new MultiLineLabelUI()); + myPanel.add(promptLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 8, 10), 0, 0)); + + myRbCreateSingle = new JRadioButton("Create single-module project", true); + myRbCreateSingle.setMnemonic('s'); + myRbCreateMultiple = new JRadioButton("Create/configure multi-module project"); + myRbCreateMultiple.setMnemonic('m'); + myPanel.add(myRbCreateSingle, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 6, 0, 6), 0, 0)); + myPanel.add(myRbCreateMultiple, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 6, 0, 6), 0, 0)); + + ButtonGroup group = new ButtonGroup(); + group.add(myRbCreateSingle); + group.add(myRbCreateMultiple); + + } + + public String getHelpId() { + return "project.new.page3"; + } + + public JComponent getComponent() { + return myPanel; + } + + public void updateDataModel() { + } + + public Icon getIcon() { + return NEW_PROJECT_ICON; + } + + public boolean isCreateModule() { + return myRbCreateSingle.isSelected(); + } + + public void addCreateModuleChoiceListener(ItemListener listener) { + myRbCreateSingle.addItemListener(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleTypeStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleTypeStep.java new file mode 100644 index 00000000000..5e4994d9ca8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ModuleTypeStep.java @@ -0,0 +1,317 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.ide.util.BrowseFilesListener; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.ModuleTypeManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.FieldPanel; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.EventDispatcher; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.EventListener; + +/** + * @author Eugene Zhuravlev + * Date: Dec 29, 2003 + */ +public class ModuleTypeStep extends ModuleWizardStep { + private JPanel myPanel; + private JRadioButton myRbCreateNewModule; + private JRadioButton myRbImportModule; + private JRadioButton myRbImportForeignModule; + private JComboBox myCbForeignModuleType; + private FieldPanel myModulePathFieldPanel; + private JList myTypesList; + private JEditorPane myModuleDescriptionPane; + + private ModuleType myModuleType = ModuleType.JAVA; + private Runnable myDoubleClickAction = null; + + final EventDispatcher myEventDispatcher = EventDispatcher.create(UpdateListener.class); + private final ButtonGroup myButtonGroup; + + public static interface UpdateListener extends EventListener{ + void moduleTypeSelected(ModuleType type); + void importModuleOptionSelected(boolean selected); + } + + public ModuleTypeStep(boolean createNewProject) { + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + + myModuleDescriptionPane = new JEditorPane(); + myModuleDescriptionPane.setContentType("text/html"); + myModuleDescriptionPane.setEditable(false); + + final ModuleType[] allModuleTypes = ModuleTypeManager.getInstance().getRegisteredTypes(); + + myTypesList = new JList(allModuleTypes); + myTypesList.setSelectionModel(new PermanentSingleSelectionModel()); + myTypesList.setCellRenderer(new ModuleTypesListCellRenderer()); + myTypesList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) { + return; + } + final ModuleType typeSelected = (ModuleType)myTypesList.getSelectedValue(); + myModuleType = typeSelected; + myModuleDescriptionPane.setText(""+typeSelected.getDescription()+""); + myEventDispatcher.getMulticaster().moduleTypeSelected(typeSelected); + } + }); + myTypesList.setSelectedIndex(0); + myTypesList.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2){ + if (myDoubleClickAction != null) { + if (myTypesList.getSelectedValue() != null) { + myDoubleClickAction.run(); + } + } + } + } + } + ); + + myRbCreateNewModule = new JRadioButton("Create new module", true); + myRbCreateNewModule.setMnemonic('C'); + myRbImportModule = new JRadioButton("Import existing module"); + myRbImportModule.setMnemonic('I'); + myRbImportForeignModule = new JRadioButton("Import module from"); + myRbImportForeignModule.setMnemonic('m'); + myCbForeignModuleType = new JComboBox(new String[]{"Eclipse project"}); + myCbForeignModuleType.setEnabled(false); + myButtonGroup = new ButtonGroup(); + myButtonGroup.add(myRbCreateNewModule); + myButtonGroup.add(myRbImportModule); + myButtonGroup.add(myRbImportForeignModule); + ModulesRbListener listener = new ModulesRbListener(); + myRbCreateNewModule.addItemListener(listener); + myRbImportForeignModule.addItemListener(listener); + myRbImportModule.addItemListener(listener); + + JTextField tfModuleFilePath = new JTextField(); + myModulePathFieldPanel = createFieldPanel(tfModuleFilePath, "Path to IDEA module file (.iml):", new BrowseFilesListener(tfModuleFilePath, "Select IDEA module file (.iml) to import", null, new ModuleFileChooserDescriptor())); + myModulePathFieldPanel.setEnabled(false); + + if (createNewProject) { + final JLabel moduleTypeLabel = new JLabel("Select module type:"); + moduleTypeLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myPanel.add(moduleTypeLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + } + else { + myPanel.add(myRbCreateNewModule, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 8, 10), 0, 0)); + } + final JLabel descriptionLabel = new JLabel("Description:"); + descriptionLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myPanel.add(descriptionLabel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + + final JScrollPane typesListScrollPane = ScrollPaneFactory.createScrollPane(myTypesList); + final Dimension preferredSize = calcTypeListPreferredSize(allModuleTypes); + typesListScrollPane.setPreferredSize(preferredSize); + typesListScrollPane.setMinimumSize(preferredSize); + myPanel.add(typesListScrollPane, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.2, (createNewProject? 1.0 : 0.0), GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, createNewProject? 10 : 30, 0, 10), 0, 0)); + + final JScrollPane descriptionScrollPane = ScrollPaneFactory.createScrollPane(myModuleDescriptionPane); + descriptionScrollPane.setPreferredSize(new Dimension(preferredSize.width * 3, preferredSize.height)); + myPanel.add(descriptionScrollPane, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.8, (createNewProject? 1.0 : 0.0), GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 10), 0, 0)); + + if (!createNewProject) { + myPanel.add(myRbImportModule, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(16, 10, 0, 10), 0, 0)); + myPanel.add(myModulePathFieldPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 30, 0, 10), 0, 0)); + + myPanel.add(myRbImportForeignModule, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(16, 10, 0, 10), 0, 0)); + myPanel.add(myCbForeignModuleType, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 30, 8, 10), 0, 0)); + } + } + + private Dimension calcTypeListPreferredSize(final ModuleType[] allModuleTypes) { + int width = 0; + int height = 0; + final FontMetrics fontMetrics = myTypesList.getFontMetrics(myTypesList.getFont()); + final int fontHeight = fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent(); + for (int idx = 0; idx < allModuleTypes.length; idx++) { + final ModuleType type = allModuleTypes[idx]; + final Icon icon = type.getBigIcon(); + final int iconHeight = icon != null? icon.getIconHeight(): 0; + final int iconWidth = icon != null? icon.getIconWidth(): 0; + height += Math.max(iconHeight, fontHeight) + 6; + width = Math.max(width, iconWidth + fontMetrics.stringWidth(type.getName()) + 10); + } + return new Dimension(width, height); + } + + public String getHelpId() { + return "project.creatingModules.page1"; + } + + public void setModuleListDoubleClickAction(Runnable runnable) { + myDoubleClickAction = runnable; + } + + public JComponent getComponent() { + return myPanel; + } + + public Icon getIcon() { + return ICON; + } + + public boolean validate() { + if (myRbImportModule.isSelected()) { + final String path = myModulePathFieldPanel.getText().trim(); + if (path.length() == 0) { + Messages.showErrorDialog("Please specify path to IDEA module file (.iml)", "Module File Path Not Specified"); + myModulePathFieldPanel.getTextField().requestFocus(); + return false; + } + final File file = new File(path); + if (!file.exists()) { + Messages.showErrorDialog("The specified path to module file does not exist", "Module File Does Not Exist"); + myModulePathFieldPanel.getTextField().requestFocus(); + return false; + } + if (!StdFileTypes.IDEA_MODULE.equals(FileTypeManager.getInstance().getFileTypeByFileName(file.getName()))) { + Messages.showErrorDialog("The \"" + path + "\"\nis not an IDEA module file (.iml)", "Incorrect File Type"); + myModulePathFieldPanel.getTextField().requestFocus(); + return false; + } + } + return true; + } + + public boolean isNextButtonEnabled() { + return !myRbImportModule.isSelected(); + } + public boolean isCreateNewModule() { + return myRbCreateNewModule.isSelected(); + } + public boolean isImportExistingModule() { + return myRbImportModule.isSelected(); + } + public boolean isImportForeignModule() { + return myRbImportForeignModule.isSelected(); + } + + public String getModuleFilePath() { + return myModulePathFieldPanel.getText().trim().replace(File.separatorChar, '/'); + } + + public ModuleType getModuleType() { + return myModuleType; + } + + public void addUpdateListener(UpdateListener listener) { + myEventDispatcher.addListener(listener); + } + + public void removeUpdateListener(UpdateListener listener) { + myEventDispatcher.removeListener(listener); + } + + public void updateDataModel() { + } + + public JComponent getPreferredFocusedComponent() { + return myTypesList; + } + + private class ModulesRbListener implements ItemListener { + public void itemStateChanged(ItemEvent e) { + final JComponent toFocus; + ButtonModel selection = myButtonGroup.getSelection(); + setControlsEnabled(selection); + if (selection == myRbCreateNewModule.getModel()) { + toFocus = myTypesList; + myEventDispatcher.getMulticaster().importModuleOptionSelected(false); + } + else if (selection == myRbImportModule.getModel()) { // import existing + toFocus = myModulePathFieldPanel.getTextField(); + myEventDispatcher.getMulticaster().importModuleOptionSelected(true); + } + else if (selection == myRbImportForeignModule.getModel()) { + myEventDispatcher.getMulticaster().importModuleOptionSelected(false); + toFocus = myCbForeignModuleType; + } + else { + toFocus = null; + } + + if (toFocus != null) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + toFocus.requestFocus(); + } + }); + } + } + } + + private void setControlsEnabled(ButtonModel selection) { + boolean newModuleEnabled = selection == myRbCreateNewModule.getModel(); + myTypesList.setEnabled(newModuleEnabled); + myModuleDescriptionPane.setEnabled(newModuleEnabled); + + boolean importModuleEnabled = selection == myRbImportModule.getModel(); + myModulePathFieldPanel.setEnabled(importModuleEnabled); + + boolean importForeignModuleEnabled = selection == myRbImportForeignModule.getModel(); + myCbForeignModuleType.setEnabled(importForeignModuleEnabled); + } + + private static class ModuleFileChooserDescriptor extends FileChooserDescriptor { + public ModuleFileChooserDescriptor() { + super(true, false, false, false, false, false); + setHideIgnored(false); + } + + public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + final boolean isVisible = super.isFileVisible(file, showHiddenFiles); + if (!isVisible || file.isDirectory()) { + return isVisible; + } + return StdFileTypes.IDEA_MODULE.equals(FileTypeManager.getInstance().getFileTypeByFile(file)); + } + } + + private static class ModuleTypesListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + final JLabel rendererComponent = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + final ModuleType moduleType = (ModuleType)value; + rendererComponent.setIcon(moduleType.getBigIcon()); + rendererComponent.setText(moduleType.getName()); + return rendererComponent; + } + } + + private static class PermanentSingleSelectionModel extends DefaultListSelectionModel { + public PermanentSingleSelectionModel() { + super.setSelectionMode(SINGLE_SELECTION); + } + + public final void setSelectionMode(int selectionMode) { + } + + public final void removeSelectionInterval(int index0, int index1) { + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NameLocationStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NameLocationStep.java new file mode 100644 index 00000000000..5cc1618d581 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NameLocationStep.java @@ -0,0 +1,287 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.ide.util.BrowseFilesListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.FieldPanel; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Dec 29, 2003 + */ +public class NameLocationStep extends ModuleWizardStep { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.projectWizard.NameLocationStep"); + private JPanel myPanel; + private NamePathComponent myNamePathComponent; + private final WizardContext myWizardContext; + private final JavaModuleBuilder myBuilder; + private final ModulesProvider myModulesProvider; + private final Icon myIcon; + private final String myHelpId; + private static final String MODULE_FILE_EXTENSION = ".iml"; + private boolean myModuleFileDirectoryChangedByUser = false; + private JTextField myTfModuleFilePath; + private boolean myFirstTimeInitializationDone = false; + + public NameLocationStep(WizardContext wizardContext, JavaModuleBuilder builder, + ModulesProvider modulesProvider, + Icon icon, + String helpId) { + myWizardContext = wizardContext; + myBuilder = builder; + myModulesProvider = modulesProvider; + myIcon = icon; + myHelpId = helpId; + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + + final String text; + final ModuleType moduleType = builder.getModuleType(); + if (ModuleType.J2EE_APPLICATION.equals(moduleType)) { + text = "Please specify module name"; + } + else { + text = "Please specify module name and module content root.\nA module content root is a directory where the files that belong to the module are stored."; + } + final JLabel textLabel = new JLabel(text); + textLabel.setUI(new MultiLineLabelUI()); + myPanel.add(textLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 8, 10), 0, 0)); + + myNamePathComponent = new NamePathComponent("Module name:", "Module content root:", 'M', 'r', "Select Module Content Root", ""); + if (ModuleType.J2EE_APPLICATION.equals(moduleType)) { + myNamePathComponent.setPathComponentVisible(false); + } + + myPanel.add(myNamePathComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 0, 10), 0, 0)); + + final JLabel label = new JLabel("Module file will be saved in:"); + //label.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myPanel.add(label, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 1.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(30, 10, 0, 10), 0, 0)); + + myTfModuleFilePath = new JTextField(); + myTfModuleFilePath.setEditable(false); + final Insets borderInsets = myTfModuleFilePath.getBorder().getBorderInsets(myTfModuleFilePath); + myTfModuleFilePath.setBorder(BorderFactory.createEmptyBorder(borderInsets.top, borderInsets.left, borderInsets.bottom, borderInsets.right)); + final FieldPanel fieldPanel = createFieldPanel(myTfModuleFilePath, null, null); + myPanel.add(fieldPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 10, 0), 0, 0)); + + JButton browseButton = new JButton("Change Directory..."); + browseButton.addActionListener(new BrowseModuleFileDirectoryListener(myTfModuleFilePath)); + myPanel.add(browseButton, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 10), 0, 0)); + + final DocumentListener documentListener = new DocumentAdapter() { + protected void textChanged(DocumentEvent e) { + updateModuleFilePathField(); + } + }; + myNamePathComponent.getNameComponent().getDocument().addDocumentListener(documentListener); + myNamePathComponent.getPathComponent().getDocument().addDocumentListener(documentListener); + myNamePathComponent.getPathComponent().getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + myWizardContext.requestWizardButtonsUpdate(); + } + }); + } + + private String suggestModuleName(ModuleType moduleType) { + if (moduleType.equals(ModuleType.J2EE_APPLICATION)) { + return "MyApplication"; + } + if (moduleType.equals(ModuleType.EJB)) { + return "MyEjb"; + } + if (moduleType.equals(ModuleType.WEB)) { + return "MyWebApp"; + } + return "untitled"; + } + + public void updateStep() { + super.updateStep(); + + // initial UI settings + if (!myFirstTimeInitializationDone) { + myFirstTimeInitializationDone = true; + if (myWizardContext.isCreatingNewProject()) { + setSyncEnabled(false); + } + else { // project already exists + final VirtualFile projectFile = myWizardContext.getProject().getProjectFile(); + final String projectFileDirectory = (projectFile != null) ? VfsUtil.virtualToIoFile(projectFile).getParent() : null; + if (projectFileDirectory != null) { + final String name = ProjectWizardUtil.findNonExistingFileName(projectFileDirectory, suggestModuleName(myBuilder.getModuleType()), ""); + setModuleName(name); + setContentEntryPath(projectFileDirectory + File.separatorChar + name); + } + } + } + + if (myWizardContext.isCreatingNewProject()) { // creating new project + // in this mode we depend on the settings of the "project name" step + if (!isPathChangedByUser()) { + setContentEntryPath(myWizardContext.getProjectFileDirectory().replace('/', File.separatorChar)); + } + if (!isNameChangedByUser()) { + setModuleName(myWizardContext.getProjectName()); + } + } + } + + public JComponent getComponent() { + return myPanel; + } + + public String getModuleName() { + return myNamePathComponent.getNameValue(); + } + + public void setModuleName(String name) { + myNamePathComponent.setNameValue(name); + } + + public String getContentEntryPath() { + final String path = myNamePathComponent.getPath(); + return path.length() == 0? null : path; + } + + public void setContentEntryPath(String path) { + myNamePathComponent.setPath(path); + } + + public String getModuleFilePath() { + return getModuleFileDirectory() + "/" + myNamePathComponent.getNameValue() + MODULE_FILE_EXTENSION; + } + + public boolean isSyncEnabled() { + return myNamePathComponent.isSyncEnabled(); + } + + public void setSyncEnabled(boolean isSyncEnabled) { + myNamePathComponent.setSyncEnabled(isSyncEnabled); + } + + private String getModuleFileDirectory() { + return myTfModuleFilePath.getText().trim().replace(File.separatorChar, '/'); + } + + public boolean validate() { + final String moduleName = getModuleName(); + if (moduleName.length() == 0) { + Messages.showErrorDialog(myNamePathComponent.getNameComponent(), "Please specify module name", "Module Name Not Specified"); + return false; + } + if (isAlreadyExists(moduleName)) { + Messages.showErrorDialog("Module with name \"" + moduleName + "\" already exists in the project", "Module Already Exists"); + return false; + } + final String moduleLocation = getModuleFileDirectory(); + if (moduleLocation.length() == 0) { + Messages.showErrorDialog(myNamePathComponent.getPathComponent(), "Please specify module file location", "Module File Location Not Specified"); + return false; + } + + if (!ModuleType.J2EE_APPLICATION.equals(myBuilder.getModuleType())) { + final String contentEntryPath = getContentEntryPath(); + if (contentEntryPath != null) { + // the check makes sence only for non-null module root + Module[] modules = myModulesProvider.getModules(); + for (int j = 0; j < modules.length; j++) { + final Module module = modules[j]; + ModuleRootModel rootModel = myModulesProvider.getRootModel(module); + LOG.assertTrue(rootModel != null); + final VirtualFile[] moduleContentRoots = rootModel.getContentRoots(); + final String moduleContentRoot = contentEntryPath.replace(File.separatorChar, '/'); + for (int k = 0; k < moduleContentRoots.length; k++) { + final VirtualFile root = moduleContentRoots[k]; + if (moduleContentRoot.equals(root.getPath())) { + Messages.showErrorDialog(myNamePathComponent.getPathComponent(), "Content root \"" + contentEntryPath + "\" already defined for module \"" + module.getName() + "\".\nTwo modules in a project cannot share the same content root.", "Module Content Root Already Exists"); + return false; + } + } + } + if (!ProjectWizardUtil.createDirectoryIfNotExists("The module content root\n", contentEntryPath, myNamePathComponent.isPathChangedByUser())) { + return false; + } + } + } + final String moduleFileDirectory = getModuleFileDirectory(); + if (!ProjectWizardUtil.createDirectoryIfNotExists("The module file directory\n", moduleFileDirectory, myModuleFileDirectoryChangedByUser)) { + return false; + } + return true; + } + + public void updateDataModel() { + myBuilder.setName(getModuleName()); + myBuilder.setModuleFilePath(getModuleFilePath()); + myBuilder.setContentEntryPath(getContentEntryPath()); + } + + public JComponent getPreferredFocusedComponent() { + return myNamePathComponent.getNameComponent(); + } + + private boolean isAlreadyExists(String moduleName) { + final Module[] modules = myModulesProvider.getModules(); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + if (moduleName.equals(module.getName())) { + return true; + } + } + return false; + } + + private void updateModuleFilePathField() { + if (!myModuleFileDirectoryChangedByUser) { + final String dir = myNamePathComponent.getPath().replace('/', File.separatorChar); + myTfModuleFilePath.setText(dir); + } + } + + public boolean isNameChangedByUser() { + return myNamePathComponent.isNameChangedByUser(); + } + + public boolean isPathChangedByUser() { + return myNamePathComponent.isPathChangedByUser(); + } + + private class BrowseModuleFileDirectoryListener extends BrowseFilesListener { + public BrowseModuleFileDirectoryListener(final JTextField textField) { + super(textField, "Select Module File Location", "The module file will be saved in selected directory", BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR); + } + + public void actionPerformed(ActionEvent e) { + final String pathBefore = myTfModuleFilePath.getText().trim(); + super.actionPerformed(e); + final String path = myTfModuleFilePath.getText().trim(); + if (!path.equals(pathBefore)) { + myModuleFileDirectoryChangedByUser = true; + } + } + } + + public Icon getIcon() { + return myIcon; + } + + public String getHelpId() { + return myHelpId; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NamePathComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NamePathComponent.java new file mode 100644 index 00000000000..33cd89b9b7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/NamePathComponent.java @@ -0,0 +1,234 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.ide.util.BrowseFilesListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.FieldPanel; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Dec 30, 2003 + */ +public class NamePathComponent extends JPanel{ + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.projectWizard.NamePathComponent"); + + private JTextField myTfName; + private JTextField myTfPath; + private boolean myIsNameChangedByUser = false; + private boolean myIsPathChangedByUser = false; + private boolean myIsPathNameSyncEnabled = true; + private boolean myIsNamePathSyncEnabled = true; + private boolean myIsSyncEnabled = true; + + private FieldPanel myPathPanel; + private JLabel myNameLabel; + + public NamePathComponent(String nameLabelText, String pathLabelText, char nameMnemonic, char locationMnemonic, final String pathChooserTitle, final String pathChooserDescription) { + this(nameLabelText, pathLabelText, nameMnemonic, locationMnemonic, pathChooserTitle, pathChooserDescription, true); + } + + public NamePathComponent(String nameLabelText, String pathLabelText, char nameMnemonic, char locationMnemonic, final String pathChooserTitle, final String pathChooserDescription, boolean hideIgnored) { + super(new GridBagLayout()); + + myTfName = new JTextField(); + myTfName.setDocument(new NameFieldDocument()); + myTfName.setPreferredSize(new Dimension(200, myTfName.getPreferredSize().height)); + + myTfPath = new JTextField(); + myTfPath.setDocument(new PathFieldDocument()); + myTfPath.setPreferredSize(new Dimension(200, myTfPath.getPreferredSize().height)); + + myNameLabel = new JLabel(nameLabelText); + myNameLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myNameLabel.setDisplayedMnemonic(nameMnemonic); + myNameLabel.setLabelFor(myTfName); + this.add(myNameLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + + this.add(myTfName, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 8, 0), 0, 0)); + // todo: review texts + final FileChooserDescriptor chooserDescriptor = (FileChooserDescriptor)BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR.clone(); + chooserDescriptor.setHideIgnored(hideIgnored); + final BrowseFilesListener browseButtonActionListener = new BrowseFilesListener(myTfPath, pathChooserTitle, pathChooserDescription, chooserDescriptor) { + public void actionPerformed(ActionEvent e) { + super.actionPerformed(e); + myIsPathChangedByUser = true; + } + }; + myPathPanel = new FieldPanel(myTfPath, pathLabelText, null, browseButtonActionListener, null); + final JLabel locationLabel = myPathPanel.getFieldLabel(); + locationLabel.setDisplayedMnemonic(locationMnemonic); + locationLabel.setLabelFor(myTfPath); + locationLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + this.add(myPathPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 0, 0, 0), 0, 0)); + } + + public String getNameValue() { + return myTfName.getText().trim(); + } + + public void setNameValue(String name) { + final boolean isNameChangedByUser = myIsNameChangedByUser; + setNamePathSyncEnabled(false); + try { + myTfName.setText(name); + } + finally { + myIsNameChangedByUser = isNameChangedByUser; + setNamePathSyncEnabled(true); + } + } + + public String getPath() { + return myTfPath.getText().trim().replace(File.separatorChar, '/'); + } + + public void setPath(String path) { + final boolean isPathChangedByUser = myIsPathChangedByUser; + setPathNameSyncEnabled(false); + try { + myTfPath.setText(path); + } + finally { + myIsPathChangedByUser = isPathChangedByUser; + setPathNameSyncEnabled(true); + } + } + + public JTextField getNameComponent() { + return myTfName; + } + + public JTextField getPathComponent() { + return myTfPath; + } + + public void setPathComponentVisible(boolean visible) { + myPathPanel.setVisible(visible); + } + + public void setNameComponentVisible(boolean visible) { + myTfName.setVisible(visible); + myNameLabel.setVisible(visible); + } + + public boolean isNameChangedByUser() { + return myIsNameChangedByUser; + } + + public boolean isPathChangedByUser() { + return myIsPathChangedByUser; + } + + public boolean isSyncEnabled() { + return myIsSyncEnabled; + } + + public void setSyncEnabled(boolean isSyncEnabled) { + myIsSyncEnabled = isSyncEnabled; + } + + private boolean isPathNameSyncEnabled() { + if (!isSyncEnabled()) { + return false; + } + return myIsPathNameSyncEnabled; + } + + private void setPathNameSyncEnabled(boolean isPathNameSyncEnabled) { + myIsPathNameSyncEnabled = isPathNameSyncEnabled; + } + + private boolean isNamePathSyncEnabled() { + if (!isSyncEnabled()) { + return false; + } + return myIsNamePathSyncEnabled; + } + + private void setNamePathSyncEnabled(boolean isNamePathSyncEnabled) { + myIsNamePathSyncEnabled = isNamePathSyncEnabled; + } + + private class NameFieldDocument extends PlainDocument { + public NameFieldDocument() { + addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + myIsNameChangedByUser = true; + syncNameAndPath(); + } + }); + } + + public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { + boolean ok = true; + for (int idx = 0; idx < str.length() && ok; idx++) { + char ch = str.charAt(idx); + ok = ch != File.separatorChar && ch != '\\' && ch != '/' && ch != '|' && ch != ':'; + } + if (ok) { + super.insertString(offs, str, a); + } + } + + private void syncNameAndPath() { + if (isNamePathSyncEnabled() && !myIsPathChangedByUser) { + try { + setPathNameSyncEnabled(false); + final String name = getText(0, getLength()); + final String path = myTfPath.getText().trim(); + final int lastSeparatorIndex = path.lastIndexOf(File.separator); + if (lastSeparatorIndex >= 0) { + setPath(path.substring(0, lastSeparatorIndex + 1) + name); + } + } + catch (BadLocationException e) { + LOG.error(e); + } + finally { + setPathNameSyncEnabled(true); + } + } + } + } + + private class PathFieldDocument extends PlainDocument { + public PathFieldDocument() { + addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + myIsPathChangedByUser = true; + syncPathAndName(); + } + }); + } + + private void syncPathAndName() { + if (isPathNameSyncEnabled() && !myIsNameChangedByUser) { + try { + setNamePathSyncEnabled(false); + final String path = getText(0, getLength()); + final int lastSeparatorIndex = path.lastIndexOf(File.separator); + if (lastSeparatorIndex >= 0 && (lastSeparatorIndex + 1) < path.length()) { + setNameValue(path.substring(lastSeparatorIndex + 1)); + } + } + catch (BadLocationException e) { + LOG.error(e); + } + finally { + setNamePathSyncEnabled(true); + } + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/OutputPathsStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/OutputPathsStep.java new file mode 100644 index 00000000000..5567a4c1129 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/OutputPathsStep.java @@ -0,0 +1,72 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.ide.util.projectWizard.j2ee.WebModuleBuilder; +import com.intellij.openapi.util.text.StringUtil; + +import javax.swing.*; +import java.awt.*; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Jan 22, 2004 + */ +public class OutputPathsStep extends ModuleWizardStep{ + private final JavaModuleBuilder myDescriptor; + private final Icon myIcon; + private final String myHelpId; + private final NameLocationStep myNameLocationStep; + private JPanel myPanel; + private NamePathComponent myNamePathComponent; + + public OutputPathsStep(NameLocationStep nameLocationStep, JavaModuleBuilder descriptor, Icon icon, String helpId) { + myDescriptor = descriptor; + myIcon = icon; + myHelpId = helpId; + myNameLocationStep = nameLocationStep; + myNamePathComponent = new NamePathComponent("", "Select compiler output path:", 'q', 'o', "Select compiler output path", "", false); + myNamePathComponent.setNameComponentVisible(false); + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + myPanel.add(myNamePathComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 6, 0, 6), 0, 0)); + } + + public JComponent getComponent() { + return myPanel; + } + + public void updateDataModel() { + myDescriptor.setCompilerOutputPath(myNamePathComponent.getPath()); + } + + public void updateStep() { + if (!myNamePathComponent.isPathChangedByUser()) { + final String contentEntryPath = myDescriptor.getContentEntryPath(); + if (contentEntryPath != null) { + String path = null; + if (myDescriptor instanceof WebModuleBuilder) { + final String explodedPath = ((WebModuleBuilder)myDescriptor).explodedDirPath; + if (explodedPath != null) { + path = explodedPath + "/WEB-INF/classes"; + } + } + if (path == null) { + path = StringUtil.endsWithChar(contentEntryPath, '/') ? contentEntryPath + "classes" : contentEntryPath + "/classes"; + } + myNamePathComponent.setPath(path.replace('/', File.separatorChar)); + } + } + } + + public boolean isStepVisible() { + return myNameLocationStep.getContentEntryPath() != null; + } + + public Icon getIcon() { + return myIcon; + } + + public String getHelpId() { + return myHelpId; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectJdkStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectJdkStep.java new file mode 100644 index 00000000000..8b06d6c8466 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectJdkStep.java @@ -0,0 +1,104 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Eugene Zhuravlev + * Date: Jan 21, 2004 + */ +public class ProjectJdkStep extends ModuleWizardStep { + private static final Icon NEW_PROJECT_ICON = IconLoader.getIcon("/newprojectwizard.png"); + private JdkChooserPanel myJdkChooser; + private JPanel myPanel; + + public ProjectJdkStep() { + myJdkChooser = new JdkChooserPanel(); + + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + + final JLabel label = new JLabel("Please select project JDK.\nThis JDK will be used by default by all project modules."); + label.setUI(new MultiLineLabelUI()); + myPanel.add(label, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 8, 10), 0, 0)); + + final JLabel jdklabel = new JLabel("Project JDK: "); + jdklabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myPanel.add(jdklabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + + myPanel.add(myJdkChooser, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 10, 10, 5), 0, 0)); + JButton configureButton = new JButton("Configure..."); + configureButton.setMnemonic('C'); + myPanel.add(configureButton, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 0, 10, 5), 0, 0)); + + ProjectJdk defaultJdk = getDefaultJdk(); + if(defaultJdk != null) { + myJdkChooser.selectJdk(defaultJdk); + } + + configureButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myJdkChooser.editJdkTable(); + } + }); + } + + public JComponent getPreferredFocusedComponent() { + return myJdkChooser.getPreferredFocusedComponent(); + } + + public String getHelpId() { + return "project.new.page2"; + } + + public JComponent getComponent() { + return myPanel; + } + + public void updateDataModel() { + } + + public ProjectJdk getJdk() { + return myJdkChooser.getChosenJdk(); + } + + public Icon getIcon() { + return NEW_PROJECT_ICON; + } + + private static ProjectJdk getDefaultJdk() { + Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject(); + return ProjectRootManagerEx.getInstanceEx(defaultProject).getProjectJdk(); + } + + + public boolean validate() { + final ProjectJdk jdk = myJdkChooser.getChosenJdk(); + if (jdk == null) { + int result = Messages.showOkCancelDialog( + "Do you want to create a project with no JDK assigned?\n"+ + "JDK is required for compiling, debugging and running applications\n"+ + "as well as for standard JDK classes resolution.", + "No JDK Specified", + Messages.getWarningIcon() + ); + if(result != 0) { + return false; + } + } + return true; + } + + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectNameStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectNameStep.java new file mode 100644 index 00000000000..be0e24ccf5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectNameStep.java @@ -0,0 +1,120 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ide.GeneralSettings; + +import javax.swing.*; +import java.awt.*; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Jan 21, 2004 + */ +public class ProjectNameStep extends ModuleWizardStep { + private static final Icon NEW_PROJECT_ICON = IconLoader.getIcon("/newprojectwizard.png"); + private static final String PROJECT_FILE_EXTENSION = ".ipr"; + private NamePathComponent myNamePathComponent; + private JPanel myPanel; + private final WizardContext myWizardContext; + + public ProjectNameStep(WizardContext wizardContext) { + myWizardContext = wizardContext; + myNamePathComponent = new NamePathComponent("Name:", "Project file location:", 'a', 'l', "Select project file directory", "Project file will be stored in this directory"); + + final String projectsStorePath = getDefaultProjectsStorePath(); + final String initialProjectName = ProjectWizardUtil.findNonExistingFileName(projectsStorePath, "untitled", ""); + myNamePathComponent.setPath(projectsStorePath + File.separator + initialProjectName); + myNamePathComponent.setNameValue(initialProjectName); + + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + + ApplicationInfo info = ApplicationManager.getApplication().getComponent(ApplicationInfo.class); + String appName = info.getVersionName(); + myPanel.add(new JLabel("Please enter a project name to create a new " + appName + " project."), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 8, 10), 0, 0)); + + myPanel.add(myNamePathComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 8, 10), 0, 0)); + } + + public JComponent getPreferredFocusedComponent() { + return myNamePathComponent.getNameComponent(); + } + + public String getHelpId() { + return "project.new.page1"; + } + + public JComponent getComponent() { + return myPanel; + } + + public void updateDataModel() { + myWizardContext.setProjectName(getProjectName()); + myWizardContext.setProjectFileDirectory(getProjectFileDirectory()); + } + + public Icon getIcon() { + return NEW_PROJECT_ICON; + } + + private String getDefaultProjectsStorePath() { + final String lastProjectLocation = GeneralSettings.getInstance().getLastProjectLocation(); + if (lastProjectLocation != null) { + return lastProjectLocation.replace('/', File.separatorChar); + } + final String userHome = System.getProperty("user.home"); + return userHome.replace('/', File.separatorChar) + File.separator + "IdeaProjects"; + } + + + public boolean validate() { + String name = myNamePathComponent.getNameValue(); + if (name.length() == 0 ) { + final ApplicationInfo info = ApplicationManager.getApplication().getComponent(ApplicationInfo.class); + final String message = "Enter a file name to create a new " + info.getVersionName() + " project"; + Messages.showMessageDialog(myPanel, message, "Error", Messages.getErrorIcon()); + return false; + } + + final String projectFileDirectory = getProjectFileDirectory(); + if (projectFileDirectory.length() == 0) { + Messages.showMessageDialog(myPanel, "Enter project file location", "Error", Messages.getErrorIcon()); + return false; + } + + final boolean shouldPromptCreation = myNamePathComponent.isPathChangedByUser(); + if (!ProjectWizardUtil.createDirectoryIfNotExists("The project file directory\n", projectFileDirectory, shouldPromptCreation)) { + return false; + } + + boolean shouldContinue = true; + final File projectFile = new File(getProjectFilePath()); + if (projectFile.exists()) { + int answer = Messages.showYesNoDialog( + "The project file \n'" + projectFile.getAbsolutePath()+ "'\nalready exists.\nWould you like to overwrite it?", + "File Already Exists", + Messages.getQuestionIcon() + ); + shouldContinue = (answer == 0); + } + + return shouldContinue; + } + + public String getProjectFilePath() { + return getProjectFileDirectory() + "/" + myNamePathComponent.getNameValue()/*myTfProjectName.getText().trim()*/ + PROJECT_FILE_EXTENSION; + } + + public String getProjectFileDirectory() { + return myNamePathComponent.getPath(); + } + + public String getProjectName() { + return myNamePathComponent.getNameValue(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java new file mode 100644 index 00000000000..5a8be157f53 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardStepFactoryImpl.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 6, 2004 + */ +public class ProjectWizardStepFactoryImpl extends ProjectWizardStepFactory implements ApplicationComponent{ + + public ModuleWizardStep createNameAndLocationStep(WizardContext wizardContext, JavaModuleBuilder builder, ModulesProvider modulesProvider, Icon icon, String helpId) { + return new NameLocationStep(wizardContext, builder, modulesProvider, icon, helpId); + } + + public ModuleWizardStep createOutputPathPathsStep(ModuleWizardStep nameAndLocationStep, JavaModuleBuilder builder, Icon icon, String helpId) { + return new OutputPathsStep((NameLocationStep)nameAndLocationStep, builder, icon, helpId); + } + + public ModuleWizardStep createSourcePathsStep(ModuleWizardStep nameAndLocationStep, JavaModuleBuilder builder, Icon icon, String helpId) { + return new SourcePathsStep((NameLocationStep)nameAndLocationStep, builder, icon, helpId); + } + + + public String getComponentName() { + return "ProjectWizardStepFactory"; + } + + public void initComponent() { } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java new file mode 100644 index 00000000000..fb5b461ae8a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java @@ -0,0 +1,37 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.ui.Messages; + +import java.io.File; + +/** + * @author cdr + */ +public class ProjectWizardUtil { + public static String findNonExistingFileName(String searchDirectory, String preferredName, String extension){ + for (int idx = 0; ; idx++){ + final String fileName = (idx > 0? preferredName + idx : preferredName) + extension; + if(!new File(searchDirectory + File.separator + fileName).exists()) { + return fileName; + } + } + } + + public static boolean createDirectoryIfNotExists(final String promptPrefix, String directoryPath, boolean promptUser) { + File dir = new File(directoryPath); + if (!dir.exists()) { + if (promptUser) { + final int answer = Messages.showOkCancelDialog(promptPrefix + "\"" + dir.getPath() + "\"\ndoes not exist. It will be created by IDEA.", "Directory Does Not Exist", Messages.getQuestionIcon()); + if (answer != 0) { + return false; + } + } + final boolean ok = dir.mkdirs(); + if (!ok) { + Messages.showErrorDialog("Failed to create directory \"" + dir.getPath() + "\"", "Error"); + return false; + } + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/SourcePathsStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/SourcePathsStep.java new file mode 100644 index 00000000000..dd40a2c1303 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/SourcePathsStep.java @@ -0,0 +1,463 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.ide.util.BrowseFilesListener; +import com.intellij.ide.util.ElementsChooser; +import com.intellij.ide.util.JavaUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.FieldPanel; +import com.intellij.util.concurrency.SwingWorker; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Jan 6, 2004 + */ +public class SourcePathsStep extends ModuleWizardStep { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.projectWizard.SourcePathsStep"); + + private final NameLocationStep myNameLocationStep; + private final JavaModuleBuilder myBuilder; + private final Icon myIcon; + private final String myHelpId; + private JPanel myPanel; + private JPanel myContentPanel; + private static final String CREATE_SOURCE_PANEL = "create_source"; + private static final String CHOOSE_SOURCE_PANEL = "choose_source"; + private String myCurrentMode; + private ElementsChooser> mySourcePathsChooser; + private static final List> EMPTY_STRING_STRING_ARRAY = Collections.EMPTY_LIST; + private String myCurrentContentEntryPath = null; + private JRadioButton myRbCreateSource; + private JRadioButton myRbNoSource; + private JTextField myTfSourceDirectoryName; + private JTextField myTfFullPath; + private static final String PROGRESS_PANEL = "progress_panel"; + private JLabel myProgressLabel; + private JLabel myProgressLabel2; + private ProgressIndicator myProgressIndicator = null; + + public SourcePathsStep(NameLocationStep nameLocationStep, JavaModuleBuilder builder, Icon icon, String helpId) { + myNameLocationStep = nameLocationStep; + myBuilder = builder; + myIcon = icon; + myHelpId = helpId; + myPanel = new JPanel(new GridBagLayout()); + myPanel.setBorder(BorderFactory.createEtchedBorder()); + + myContentPanel = new JPanel(new CardLayout()); + myPanel.add(myContentPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + myContentPanel.add(createComponentForEmptyRootCase(), CREATE_SOURCE_PANEL); + myContentPanel.add(createComponentForChooseSources(), CHOOSE_SOURCE_PANEL); + + final JPanel progressPanel = new JPanel(new GridBagLayout()); + myProgressLabel = new JLabel(); + //myProgressLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + progressPanel.add(myProgressLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 0, 10), 0, 0)); + + myProgressLabel2 = new JLabel(); + //myProgressLabel2.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + progressPanel.add(myProgressLabel2, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 0, 10), 0, 0)); + + JButton stopButton = new JButton("Stop Searching"); + stopButton.setMnemonic('S'); + stopButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cancelSourcesSearch(); + } + }); + progressPanel.add(stopButton, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 2, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 10), 0, 0)); + + myContentPanel.add(progressPanel, PROGRESS_PANEL); + } + + private JComponent createComponentForEmptyRootCase() { + final JPanel panel = new JPanel(new GridBagLayout()); + final String text = + "Please specify a directory where Java source files for your project can be found.\n" + + "This path should correspond to default (root, unnamed) package.\n" + + "Note: the program will recognize only those Java source files, that are located under this directory."; + + final JLabel label = new JLabel(text); + label.setUI(new MultiLineLabelUI()); + panel.add(label, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + + myRbCreateSource = new JRadioButton("Create source directory", true); + myRbCreateSource.setMnemonic('C'); + panel.add(myRbCreateSource, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + + myTfSourceDirectoryName = new JTextField(suggestSourceDirectoryName()); + final JLabel srcPathLabel = new JLabel("Enter relative path to module content root (example: java" + File.separator + "src):"); + panel.add(srcPathLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 30, 0, 0), 0, 0)); + final FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); + chooserDescriptor.setIsTreeRootVisible(true); + final FieldPanel fieldPanel = createFieldPanel(myTfSourceDirectoryName, null, new BrowsePathListener(myTfSourceDirectoryName, chooserDescriptor)); + panel.add(fieldPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 30, 0, 10), 0, 0)); + + myRbNoSource = new JRadioButton("Do not create source directory", true); + myRbNoSource.setMnemonic('D'); + panel.add(myRbNoSource, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + + final JLabel fullPathLabel = new JLabel("The following directory will be marked as a source directory:"); + panel.add(fullPathLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(8, 10, 0, 10), 0, 0)); + + myTfFullPath = new JTextField(); + myTfFullPath.setEditable(false); + final Insets borderInsets = myTfFullPath.getBorder().getBorderInsets(myTfFullPath); + myTfFullPath.setBorder(BorderFactory.createEmptyBorder(borderInsets.top, borderInsets.left, borderInsets.bottom, borderInsets.right)); + panel.add(myTfFullPath, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 8, 10), 0, 0)); + + ButtonGroup group = new ButtonGroup(); + group.add(myRbCreateSource); + group.add(myRbNoSource); + myTfSourceDirectoryName.getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + updateFullPathField(); + } + }); + + myRbCreateSource.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + final boolean enabled = e.getStateChange() == ItemEvent.SELECTED; + srcPathLabel.setEnabled(enabled); + fieldPanel.setEnabled(enabled); + fullPathLabel.setVisible(enabled); + myTfFullPath.setVisible(enabled); + if (enabled) { + myTfSourceDirectoryName.requestFocus(); + } + } + }); + return panel; + } + + protected String suggestSourceDirectoryName() { + return "src"; + } + + private void updateFullPathField() { + final String sourceDirectoryPath = getSourceDirectoryPath(); + if (sourceDirectoryPath != null) { + myTfFullPath.setText(sourceDirectoryPath.replace('/', File.separatorChar)); + } + else { + myTfFullPath.setText(""); + } + } + + private JComponent createComponentForChooseSources() { + final JPanel panel = new JPanel(new GridBagLayout()); + mySourcePathsChooser = new ElementsChooser>() { + public String getItemText(Pair pair) { + if ("".equals(pair.second)) return pair.first; + return pair.first + " (" + pair.second + ")"; + } + }; + final String text = + "Java source files for your module have been found. Please choose directories that will\n" + + "be marked as source paths. These paths correspond to default (root, unnamed) packages.\n" + + "Note: the program will recognize only those Java source files, that are located under source directories."; + final JLabel label = new JLabel(text); + label.setUI(new MultiLineLabelUI()); + panel.add(label, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(8, 10, 0, 10), 0, 0)); + panel.add(mySourcePathsChooser, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(8, 10, 8, 10), 0, 0)); + + final JButton markAllButton = new JButton("Mark All"); + markAllButton.setMnemonic('M'); + panel.add(markAllButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 10, 8, 2), 0, 0)); + + final JButton unmarkAllButton = new JButton("Unmark All"); + unmarkAllButton.setMnemonic('U'); + panel.add(unmarkAllButton, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 8, 10), 0, 0)); + + markAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + mySourcePathsChooser.setAllElementsMarked(true); + } + }); + unmarkAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + mySourcePathsChooser.setAllElementsMarked(false); + } + }); + + return panel; + } + + public JComponent getComponent() { + return myPanel; + } + + public JComponent getPreferredFocusedComponent() { + return myRbCreateSource.isSelected()? myTfSourceDirectoryName : mySourcePathsChooser.getComponent(); + } + + public void onStepLeaving() { + if (isSourcesSearchInProgress()) { + cancelSourcesSearch(); + } + } + + public void updateDataModel() { + List> paths = null; + if (CHOOSE_SOURCE_PANEL.equals(myCurrentMode)) { + final List> selectedElements = mySourcePathsChooser.getMarkedElements(); + if (selectedElements.size() > 0) { + paths = new ArrayList>(selectedElements.size()); + + for (Iterator> iterator = selectedElements.iterator(); iterator.hasNext();) { + final Pair path = iterator.next(); + paths.add(Pair.create(path.first.replace(File.separatorChar, '/'), path.second)); + } + } + } + else { + if (myRbCreateSource.isSelected()) { + final String sourceDirectoryPath = getSourceDirectoryPath(); + if (sourceDirectoryPath != null) { + paths = Collections.singletonList(Pair.create(sourceDirectoryPath, "")); + } + } + } + if (paths != null) { + myBuilder.setSourcePaths(paths); + } + else { + myBuilder.setSourcePaths(new ArrayList>()); + } + } + + public boolean validate() { + if (isSourcesSearchInProgress()) { + final int answer = Messages.showDialog(myPanel, "IDEA is currently searching for sources. Would you like to stop the search?", "Question", new String[] {"Continue Searching", "Stop Searching"}, 0, Messages.getWarningIcon()); + if (answer == 1) { // terminate + cancelSourcesSearch(); + } + return false; + } + if (CREATE_SOURCE_PANEL.equals(myCurrentMode) && myRbCreateSource.isSelected()) { + final String sourceDirectoryPath = getSourceDirectoryPath(); + final String relativePath = myTfSourceDirectoryName.getText().trim(); + if (relativePath.length() == 0) { + String text = "Relative path to sources is empty.\n" + + "Would you like to mark the module content root\n" + + "\"" + sourceDirectoryPath + "\"\n" + + "as a source directory?"; + final int answer = Messages.showDialog(myTfSourceDirectoryName, text, "Mark Source Directory", new String[] {"Mark", "Do Not Mark", "Cancel"}, 0, Messages.getQuestionIcon()); + if (answer == 2) { + return false; // cancel + } + if (answer == 1) { // don't mark + myRbNoSource.doClick(); + } + } + if (sourceDirectoryPath != null) { + final File rootDir = new File(myBuilder.getContentEntryPath()); + final File srcDir = new File(sourceDirectoryPath); + try { + if (!FileUtil.isAncestor(rootDir, srcDir, false)) { + Messages.showErrorDialog(myTfSourceDirectoryName, "Source directory should be under module content root directory", "Error"); + return false; + } + } + catch (IOException e) { + Messages.showErrorDialog(myTfSourceDirectoryName, e.getMessage(), "Error"); + return false; + } + srcDir.mkdirs(); + } + } + return true; + } + + private void cancelSourcesSearch() { + if (myProgressIndicator != null) { + myProgressIndicator.cancel(); + } + } + + public synchronized boolean isSourcesSearchInProgress() { + return myProgressIndicator != null && myProgressIndicator.isRunning(); + } + + private String getSourceDirectoryPath() { + final String contentEntryPath = myBuilder.getContentEntryPath(); + final String dirName = myTfSourceDirectoryName.getText().trim().replace(File.separatorChar, '/'); + if (contentEntryPath != null) { + return dirName.length() > 0? contentEntryPath + "/" + dirName : contentEntryPath; + } + return null; + } + + public void updateStep() { + final String contentEntryPath = myBuilder.getContentEntryPath(); + if (isContentEntryChanged()) { + final MyProgressIndicator progress = new MyProgressIndicator(); + progress.setText("Searching for sources in " + myBuilder.getContentEntryPath().replace('/', File.separatorChar) + ". Please wait."); + ((CardLayout)myContentPanel.getLayout()).show(myContentPanel, PROGRESS_PANEL); + myContentPanel.revalidate(); + myProgressIndicator = progress; + new SwingWorker() { + public Object construct() { + final Ref>> foundPaths = Ref.create(null); + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + foundPaths.set(calcSourcePaths(contentEntryPath)); + } + }, progress); + return foundPaths.get(); + } + + public void finished() { + myProgressIndicator = null; + final List> foundPaths = (List>)get(); + if (foundPaths.size() > 0) { + myCurrentMode = CHOOSE_SOURCE_PANEL; + mySourcePathsChooser.setElements(foundPaths, true); + } + else { + myCurrentMode = CREATE_SOURCE_PANEL; + updateFullPathField(); + } + updateStepUI(progress.isCanceled()? null : myBuilder.getContentEntryPath()); + } + }.start(); + } + else { + updateStepUI(contentEntryPath); + } + } + + private void updateStepUI(final String contentEntryPath) { + myCurrentContentEntryPath = contentEntryPath; + ((CardLayout)myContentPanel.getLayout()).show(myContentPanel, myCurrentMode); + myContentPanel.revalidate(); + } + + protected boolean isContentEntryChanged() { + final String contentEntryPath = myBuilder.getContentEntryPath(); + return myCurrentContentEntryPath == null? contentEntryPath != null : !myCurrentContentEntryPath.equals(contentEntryPath); + } + + private List> calcSourcePaths(String contentEntryPath) { + if (contentEntryPath == null) { + return EMPTY_STRING_STRING_ARRAY; + } + final File entryFile = new File(contentEntryPath); + if (!entryFile.exists()) { + return EMPTY_STRING_STRING_ARRAY; + } + final File[] children = entryFile.listFiles(); + if (children == null || children.length == 0) { + return EMPTY_STRING_STRING_ARRAY; + } + final List> suggestedRoots = JavaUtil.suggestRoots(entryFile); + final java.util.List> paths = new ArrayList>(); + for (int idx = 0; idx < suggestedRoots.size(); idx++) { + final Pair suggestedRoot = suggestedRoots.get(idx); + try { + if (FileUtil.isAncestor(entryFile, suggestedRoot.first, false)) { + paths.add(Pair.create(suggestedRoot.first.getCanonicalPath(), suggestedRoot.second)); + } + } + catch (IOException e) { + LOG.info(e); + } + } + return paths; + } + + protected void setSourceDirectoryName(String name) { + name = name == null? "" : name.trim(); + myTfSourceDirectoryName.setText(name); + } + + private class BrowsePathListener extends BrowseFilesListener { + private final FileChooserDescriptor myChooserDescriptor; + private final JTextField myField; + + public BrowsePathListener(JTextField textField, final FileChooserDescriptor chooserDescriptor) { + super(textField, "Select source directory", "", chooserDescriptor); + myChooserDescriptor = chooserDescriptor; + myField = textField; + } + + private VirtualFile getContentEntryDir() { + final String contentEntryPath = myBuilder.getContentEntryPath(); + if (contentEntryPath != null) { + return ApplicationManager.getApplication().runWriteAction(new Computable() { + public VirtualFile compute() { + return LocalFileSystem.getInstance().refreshAndFindFileByPath(contentEntryPath); + } + }); + } + return null; + } + + public void actionPerformed(ActionEvent e) { + final VirtualFile contentEntryDir = getContentEntryDir(); + if (contentEntryDir != null) { + myChooserDescriptor.setRoot(contentEntryDir); + final String textBefore = myField.getText().trim(); + super.actionPerformed(e); + if (!textBefore.equals(myField.getText().trim())) { + final String fullPath = myField.getText().trim().replace(File.separatorChar, '/'); + final VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(fullPath); + LOG.assertTrue(fileByPath != null); + myField.setText(VfsUtil.getRelativePath(fileByPath, contentEntryDir, File.separatorChar)); + } + } + } + } + + private class MyProgressIndicator extends ProgressIndicatorBase { + public void setText(String text) { + super.setText(text); + myProgressLabel.setText(text); + } + + public void setText2(String text) { + super.setText2(text); + myProgressLabel2.setText(text); + } + } + + public boolean isStepVisible() { + return myNameLocationStep.getContentEntryPath() != null; + } + + public Icon getIcon() { + return myIcon; + } + + public String getHelpId() { + return myHelpId; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ToolbarPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ToolbarPanel.java new file mode 100644 index 00000000000..48d32d0cf4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/projectWizard/ToolbarPanel.java @@ -0,0 +1,26 @@ +package com.intellij.ide.util.projectWizard; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.ActionToolbar; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Zhuravlev + * Date: Jan 22, 2004 + */ +public class ToolbarPanel extends JPanel{ + public ToolbarPanel(JComponent contentComponent, ActionGroup actions) { + super(new GridBagLayout()); + this.setBorder(BorderFactory.createLoweredBevelBorder()); + if (contentComponent.getBorder() != null) { + contentComponent.setBorder(BorderFactory.createEmptyBorder()); + } + final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true); + this.add(actionToolbar.getComponent(), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + this.add(contentComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/PackageSetChooserCombo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/PackageSetChooserCombo.java new file mode 100644 index 00000000000..d157e90a3e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/PackageSetChooserCombo.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util.scopeChooser; + +import com.intellij.openapi.project.Project; +import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.ui.ComboboxWithBrowseButton; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class PackageSetChooserCombo extends ComboboxWithBrowseButton { + private Project myProject; + + public PackageSetChooserCombo(final Project project, String preselect) { + final JComboBox combo = getComboBox(); + myProject = project; + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + NamedScope scope = (NamedScope)combo.getSelectedItem(); + ScopeChooserDialog dlg = new ScopeChooserDialog(myProject, DependencyValidationManager.getInstance(project)); + if (scope != null) { + dlg.setSelectedScope(scope.getName()); + } + dlg.show(); + rebuild(); + selectScope(dlg.getSelectedScope()); + } + }); + + combo.setRenderer(new DefaultListCellRenderer() { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setText(value == null ? "" : ((NamedScope)value).getName()); + return this; + } + }); + + rebuild(); + + selectScope(preselect); + } + + private void selectScope(String preselect) { + final JComboBox combo = getComboBox(); + if (preselect != null) { + DefaultComboBoxModel model = (DefaultComboBoxModel)combo.getModel(); + for (int i = 0; i < model.getSize(); i++) { + NamedScope descriptor = (NamedScope)model.getElementAt(i); + if (preselect.equals(descriptor.getName())) { + combo.setSelectedIndex(i); + break; + } + } + } + } + + private void rebuild() { + getComboBox().setModel(createModel()); + } + + private DefaultComboBoxModel createModel() { + DependencyValidationManager manager = DependencyValidationManager.getInstance(myProject); + return new DefaultComboBoxModel(manager.getScopes()); + } + + public NamedScope getSelectedScope() { + JComboBox combo = getComboBox(); + int idx = combo.getSelectedIndex(); + if (idx < 0) return null; + return (NamedScope)combo.getSelectedItem(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java new file mode 100644 index 00000000000..04ae6db5534 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util.scopeChooser; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.psi.search.scope.packageSet.NamedScopeManager; +import com.intellij.ui.ComboboxWithBrowseButton; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageView; +import com.intellij.usageView.UsageViewManager; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; +import java.util.List; + +public class ScopeChooserCombo extends ComboboxWithBrowseButton { + private Project myProject; + private boolean mySuggestSearchInLibs; + private boolean myPrevSearchFiles; + + public ScopeChooserCombo(final Project project, boolean suggestSearchInLibs, boolean prevSearchWholeFiles, String preselect) { + mySuggestSearchInLibs = suggestSearchInLibs; + myPrevSearchFiles = prevSearchWholeFiles; + final JComboBox combo = getComboBox(); + myProject = project; + addActionListener(createScopeChooserListener()); + + combo.setRenderer(new DefaultListCellRenderer() { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setText(((ScopeDescriptor)value).getDisplay()); + return this; + } + }); + + rebuildModel(); + + selectScope(preselect); + } + + private void selectScope(String preselect) { + if (preselect != null) { + final JComboBox combo = getComboBox(); + DefaultComboBoxModel model = (DefaultComboBoxModel)combo.getModel(); + for (int i = 0; i < model.getSize(); i++) { + ScopeDescriptor descriptor = (ScopeDescriptor)model.getElementAt(i); + if (preselect.equals(descriptor.getDisplay())) { + combo.setSelectedIndex(i); + break; + } + } + } + } + + protected ActionListener createScopeChooserListener() { + return new ActionListener() { + public void actionPerformed(ActionEvent e) { + ScopeChooserDialog dlg = new ScopeChooserDialog(myProject, NamedScopeManager.getInstance(myProject)); + String selection = getSelectedScopeName(); + if (selection != null) { + dlg.setSelectedScope(selection); + } + dlg.show(); + rebuildModel(); + selectScope(dlg.getSelectedScope()); + } + }; + } + + protected void rebuildModel() { + getComboBox().setModel(createModel()); + } + + protected static class ScopeDescriptor { + private SearchScope myScope; + + public ScopeDescriptor(SearchScope scope) { + myScope = scope; + } + + public String getDisplay() { + return myScope.getDisplayName(); + } + + public SearchScope getScope() { + return myScope; + } + } + + private DefaultComboBoxModel createModel() { + DefaultComboBoxModel model = new DefaultComboBoxModel(); + createPredefinedScopeDescriptors(model); + + NamedScopeManager scopeManager = NamedScopeManager.getInstance(myProject); + NamedScope[] scopes = scopeManager.getScopes(); + for (int i = 0; i < scopes.length; i++) { + NamedScope scope = scopes[i]; + model.addElement(new ScopeDescriptor(GlobalSearchScope.filterScope(myProject, scope, true))); + } + + return model; + } + + protected void createPredefinedScopeDescriptors(DefaultComboBoxModel model) { + model.addElement(new ScopeDescriptor(GlobalSearchScope.projectScope(myProject))); + if (mySuggestSearchInLibs) { + model.addElement(new ScopeDescriptor(GlobalSearchScope.allScope(myProject))); + } + model.addElement(new ScopeDescriptor(GlobalSearchScope.projectProductionScope(myProject, true))); + model.addElement(new ScopeDescriptor(GlobalSearchScope.projectTestScope(myProject, true))); + + FileEditorManager fileEditorManager = FileEditorManager.getInstance(getProject()); + if (fileEditorManager.getSelectedTextEditor() != null) { + model.addElement(new ScopeDescriptor(new LocalSearchScope(PsiDocumentManager.getInstance(getProject()).getPsiFile( + fileEditorManager.getSelectedTextEditor().getDocument()), "Current File"))); + + if (fileEditorManager.getSelectedTextEditor().getSelectionModel().hasSelection()) { + PsiElement[] elements = CodeInsightUtil.findStatementsInRange( + PsiDocumentManager.getInstance(getProject()).getPsiFile(fileEditorManager.getSelectedTextEditor().getDocument()), + fileEditorManager.getSelectedTextEditor().getSelectionModel().getSelectionStart(), + fileEditorManager.getSelectedTextEditor().getSelectionModel().getSelectionEnd() + ); + + if (elements != null) { + model.addElement(new ScopeDescriptor(new LocalSearchScope(elements, "Selection"))); + } + } + } + + UsageView selection = UsageViewManager.getInstance(getProject()).getSelectedUsageView(); + + if (selection != null && !selection.isInAsyncUpdate()) { + final UsageInfo[] infos = selection.getUsages(); + if (infos != null) { + final java.util.List results = new ArrayList(infos.length); + + if (myPrevSearchFiles) { + final Set files = new HashSet(); + for (int i = 0; i < infos.length; i++) { + UsageInfo info = infos[i]; + if (!selection.isExcluded(info)) { + PsiElement psiElement = info.getElement(); + if (psiElement != null && psiElement.isValid()) { + PsiFile psiFile = psiElement.getContainingFile(); + if (psiFile != null) { + VirtualFile file = psiFile.getVirtualFile(); + if (file != null) files.add(file); + } + } + } + } + if (files.size() > 0) { + model.addElement(new ScopeDescriptor(new GlobalSearchScope() { + public String getDisplayName() { + return "Files in Previous Search Result"; + } + + public boolean contains(VirtualFile file) { + return files.contains(file); + } + + public int compare(VirtualFile file1, VirtualFile file2) { + return 0; + } + + public boolean isSearchInModuleContent(Module aModule) { + return true; + } + + public boolean isSearchInLibraries() { + return true; + } + })); + } + } + else { + for (int i = 0; i < infos.length; ++i) { + if (!selection.isExcluded(infos[i]) && + infos[i].getElement() != null && + infos[i].getElement().isValid() + ) { + results.add(infos[i].getElement()); + } + } + + if (results.size() > 0) { + model.addElement(new ScopeDescriptor(new LocalSearchScope(results.toArray(new PsiElement[results.size()]), + "Previous Search Results"))); + } + } + } + } + + model.addElement(new ClassHierarchyScopeDescriptor()); + } + + class ClassHierarchyScopeDescriptor extends ScopeDescriptor { + private SearchScope myCachedScope; + + public ClassHierarchyScopeDescriptor() { + super(null); + } + + public String getDisplay() { + return "Class Hierarchy"; + } + + public SearchScope getScope() { + if (myCachedScope == null) { + TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Base Class of the Hierarchy to Search In", + getProject(), + GlobalSearchScope.allScope(getProject()), + null, + null); + + chooser.show(); + + PsiClass aClass = chooser.getSelectedClass(); + if (aClass == null) return null; + + List classesToSearch = new LinkedList(); + classesToSearch.add(aClass); + + final PsiManager psiManager = PsiManager.getInstance(myProject); + final GlobalSearchScope searchScope = GlobalSearchScope.allScope(myProject); + + final PsiClass[] descendants = psiManager.getSearchHelper().findInheritors(aClass, + searchScope, + true); + + classesToSearch.addAll(Arrays.asList(descendants)); + + myCachedScope = new LocalSearchScope(classesToSearch.toArray(new PsiElement[classesToSearch.size()]), + "Hierarchy of " + aClass.getQualifiedName()); + } + + return myCachedScope; + } + } + + public SearchScope getSelectedScope() { + JComboBox combo = getComboBox(); + int idx = combo.getSelectedIndex(); + if (idx < 0) return null; + return ((ScopeDescriptor)combo.getSelectedItem()).getScope(); + } + + public String getSelectedScopeName() { + JComboBox combo = getComboBox(); + int idx = combo.getSelectedIndex(); + if (idx < 0) return null; + return ((ScopeDescriptor)combo.getSelectedItem()).getDisplay(); + } + + public Project getProject() { + return myProject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java new file mode 100644 index 00000000000..a6f983d8a06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util.scopeChooser; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.packageDependencies.DependencyUISettings; +import com.intellij.packageDependencies.ui.*; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.scope.packageSet.*; +import com.intellij.ui.*; +import com.intellij.util.Alarm; +import com.intellij.util.ui.tree.TreeUtil; +import com.intellij.util.ui.Tree; + +import javax.swing.*; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.event.DocumentEvent; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +public class ScopeEditorPanel { + private JPanel myButtonsPanel; + private JTextField myNameField; + private JTextField myPatternField; + private JPanel myTreeToolbar; + private Tree myPackageTree; + private JPanel myPanel; + private JPanel myTreePanel; + private JLabel myMatchingCountLabel; + + private final Project myProject; + private TreeExpantionMonitor myTreeExpantionMonitor; + private TreeModelBuilder.Marker myTreeMarker; + private PackageSet myCurrentScope = null; + private boolean myIsInUpdate = false; + private String myErrorMessage; + private Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + private ScopeChooserPanel.ScopeDescriptor myDescriptor; + private boolean myIsFirstUpdate = true; + private JLabel myCaretPositionLabel; + private int myCaretPosition = 0; + + public ScopeEditorPanel(Project project, final NamedScopesHolder holder) { + myProject = project; + myButtonsPanel.add(createActionsPanel()); + + myPackageTree = new Tree(); + myTreePanel.setLayout(new BorderLayout()); + myTreePanel.add(ScrollPaneFactory.createScrollPane(myPackageTree), BorderLayout.CENTER); + + myTreeToolbar.setLayout(new BorderLayout()); + myTreeToolbar.add(createTreeToolbar(), BorderLayout.WEST); + + myTreeExpantionMonitor = TreeExpantionMonitor.install(myPackageTree); + + myTreeMarker = new TreeModelBuilder.Marker() { + public boolean isMarked(PsiFile file) { + return myCurrentScope == null ? false : myCurrentScope.contains(file, holder); + } + }; + + myPatternField.getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + onTextChange(); + } + }); + + myPatternField.addCaretListener(new CaretListener() { + public void caretUpdate(CaretEvent e) { + myCaretPosition = e.getDot(); + updateCaretPositionText(); + } + }); + + myPatternField.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent e) { + myCaretPositionLabel.setVisible(true); + } + + public void focusLost(FocusEvent e) { + myCaretPositionLabel.setVisible(false); + } + }); + + updateTreeModel(); + + initTree(myPackageTree); + } + + private void updateCaretPositionText() { + if (myErrorMessage != null) { + myCaretPositionLabel.setText("pos:" + (myCaretPosition + 1)); + } + else { + myCaretPositionLabel.setText(""); + } + } + + public JPanel getPanel() { + return myPanel; + } + + private void onTextChange() { + if (!myIsInUpdate) { + myCurrentScope = null; + try { + myCurrentScope = PackageSetFactory.getInstance().compile(myPatternField.getText()); + myErrorMessage = null; + rebuild(false); + } + catch (ParsingException e) { + myErrorMessage = e.getMessage(); + showErrorMessage(); + } + } + else { + myErrorMessage = null; + } + } + + private void showErrorMessage() { + myMatchingCountLabel.setText(StringUtil.capitalize(myErrorMessage)); + myMatchingCountLabel.setForeground(Color.red); + myMatchingCountLabel.setToolTipText(myErrorMessage); + } + + private JComponent createActionsPanel() { + JButton include = new JButton("Include"); + JButton includeRec = new JButton("Include Recursively"); + JButton exclude = new JButton("Exclude"); + JButton excludeRec = new JButton("Exclude Recursively"); + + JPanel buttonsPanel = new JPanel(new VerticalFlowLayout()); + buttonsPanel.add(include); + buttonsPanel.add(includeRec); + buttonsPanel.add(exclude); + buttonsPanel.add(excludeRec); + + include.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + includeSelected(false); + } + }); + includeRec.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + includeSelected(true); + } + }); + exclude.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + excludeSelected(false); + } + }); + excludeRec.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + excludeSelected(true); + } + }); + + return buttonsPanel; + } + + private void excludeSelected(boolean recurse) { + PackageSet selected = getSelectedSet(recurse); + if (selected == null) return; + selected = new ComplementPackageSet(selected); + if (myCurrentScope == null) { + myCurrentScope = selected; + } + else { + myCurrentScope = new IntersectionPackageSet(myCurrentScope, selected); + } + rebuild(true); + } + + private void includeSelected(boolean recurse) { + PackageSet selected = getSelectedSet(recurse); + if (selected == null) return; + + if (myCurrentScope == null) { + myCurrentScope = selected; + } + else { + myCurrentScope = new UnionPackageSet(myCurrentScope, selected); + } + rebuild(true); + } + + private PackageSet getSelectedSet(boolean recursively) { + int[] rows = myPackageTree.getSelectionRows(); + if (rows == null || rows.length != 1) return null; + PackageDependenciesNode node = (PackageDependenciesNode)myPackageTree.getPathForRow(rows[0]).getLastPathComponent(); + if (node instanceof ModuleNode) { + if (!recursively) return null; + return new PatternPackageSet("*..*", getSelectedScopeType(node), ((ModuleNode)node).getModuleName()); + } + else if (node instanceof PackageNode) { + String pattern = ((PackageNode)node).getPackageQName(); + if (pattern != null) { + pattern += recursively ? "..*" : ".*"; + } + else { + pattern = recursively ? "*..*" : "*"; + } + + return getPatternSet(node, pattern); + } + else if (node instanceof FileNode) { + if (recursively) return null; + FileNode fNode = (FileNode)node; + String fqName = fNode.getFQName(); + if (fqName != null) return getPatternSet(node, fqName); + } + else if (node instanceof GeneralGroupNode) { + return new PatternPackageSet("*..*", getSelectedScopeType(node), null); + } + + return null; + } + + private PackageSet getPatternSet(PackageDependenciesNode node, String pattern) { + String scope = getSelectedScopeType(node); + String modulePattern = getSelectedModulePattern(node); + + return new PatternPackageSet(pattern, scope, modulePattern); + } + + private String getSelectedModulePattern(PackageDependenciesNode node) { + ModuleNode moduleParent = getModuleParent(node); + String modulePattern = null; + if (moduleParent != null) { + modulePattern = moduleParent.getModuleName(); + } + return modulePattern; + } + + private String getSelectedScopeType(PackageDependenciesNode node) { + GeneralGroupNode groupParent = getGroupParent(node); + String scope = PatternPackageSet.SCOPE_ANY; + if (groupParent != null) { + String name = groupParent.toString(); + if (TreeModelBuilder.PRODUCTION_NAME.equals(name)) { + scope = PatternPackageSet.SCOPE_SOURCE; + } + else if (TreeModelBuilder.TEST_NAME.equals(name)) { + scope = PatternPackageSet.SCOPE_TEST; + } + else if (TreeModelBuilder.LIBRARY_NAME.equals(name)) { + scope = PatternPackageSet.SCOPE_LIBRARY; + } + } + return scope; + } + + private GeneralGroupNode getGroupParent(PackageDependenciesNode node) { + if (node instanceof GeneralGroupNode) return (GeneralGroupNode)node; + if (node == null || node instanceof RootNode) return null; + return getGroupParent((PackageDependenciesNode)node.getParent()); + } + + private ModuleNode getModuleParent(PackageDependenciesNode node) { + if (node instanceof ModuleNode) return (ModuleNode)node; + if (node == null || node instanceof RootNode) return null; + return getModuleParent((PackageDependenciesNode)node.getParent()); + } + + private JComponent createTreeToolbar() { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new FlattenPackagesAction()); + group.add(new ShowFilesAction()); + group.add(new ShowModulesAction()); + group.add(new GroupByScopeTypeAction()); + group.add(new FilterLegalsAction()); + + ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); + return toolbar.getComponent(); + } + + public void rebuild(final boolean updateText) { + myUpdateAlarm.cancelAllRequests(); + myUpdateAlarm.addRequest(new Runnable() { + public void run() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (updateText && myCurrentScope != null) { + myIsInUpdate = true; + myPatternField.setText(myCurrentScope.getText()); + myIsInUpdate = false; + } + updateTreeModel(); + } + }); + } + }, 300); + } + + private void initTree(Tree tree) { + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.setCellRenderer(new MyTreeCellRenderer()); + tree.setRootVisible(false); + tree.setShowsRootHandles(true); + tree.putClientProperty("JTree.lineStyle", "Angled"); + + TreeToolTipHandler.install(tree); + TreeUtil.installActions(tree); + SmartExpander.installOn(tree); + new TreeSpeedSearch(tree); + } + + private void updateTreeModel() { + myTreeExpantionMonitor.freeze(); + TreeModelBuilder.TreeModel model = TreeModelBuilder.createTreeModel(myProject, myIsFirstUpdate, false, myTreeMarker); + myIsFirstUpdate = false; + + if (myErrorMessage == null) { + myMatchingCountLabel.setText("Scope contains " + model.getMarkedFileCount() + " of total " + model.getTotalFileCount() + " java files"); + myMatchingCountLabel.setForeground(new JLabel().getForeground()); + } + else { + showErrorMessage(); + } + + myPackageTree.setModel(model); + myTreeExpantionMonitor.restore(); + } + + public boolean checkCurrentScopeValid(boolean showMessage) { + if (myCurrentScope == null) { + if (showMessage) { + Messages.showErrorDialog(myPanel, "Correct pattern syntax errors first", "Syntax Error"); + } + return false; + } + return true; + } + + public boolean commit() { + if (!checkCurrentScopeValid(true)) return false; + + rebuild(false); + myDescriptor.setName(myNameField.getText()); + myDescriptor.setSet(myCurrentScope); + return true; + } + + public void reset(ScopeChooserPanel.ScopeDescriptor descriptor) { + myDescriptor = descriptor; + myNameField.setText(descriptor.getName()); + myCurrentScope = descriptor.getSet(); + myPatternField.setText(myCurrentScope == null ? "" : myCurrentScope.getText()); + rebuild(false); + } + + private static class MyTreeCellRenderer extends DefaultTreeCellRenderer { + private static final Color WHOLE_INCLUDED = new Color(10, 119, 0); + private static final Color PARTIAL_INCLUDED = new Color(0, 50, 160); + + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + PackageDependenciesNode node = (PackageDependenciesNode)value; + if (expanded) { + setIcon(node.getOpenIcon()); + } + else { + setIcon(node.getClosedIcon()); + } + + if (!sel && node.hasMarked() && !DependencyUISettings.getInstance().UI_FILTER_LEGALS) { + setForeground(node.hasUnmarked() ? PARTIAL_INCLUDED : WHOLE_INCLUDED); + } + + return this; + } + } + + private final class FlattenPackagesAction extends ToggleAction { + FlattenPackagesAction() { + super("Flatten Packages", "Flatten Packages", IconLoader.getIcon("/objectBrowser/flattenPackages.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_FLATTEN_PACKAGES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_FLATTEN_PACKAGES = flag; + rebuild(true); + } + } + + private final class ShowFilesAction extends ToggleAction { + ShowFilesAction() { + super("Show Files", "Show/Hide Files", IconLoader.getIcon("/fileTypes/java.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_SHOW_FILES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_SHOW_FILES = flag; + rebuild(true); + } + } + + private final class GroupByScopeTypeAction extends ToggleAction { + GroupByScopeTypeAction() { + super("Group by Scope Type", "Group by Scope Type (production, test, libraries)", IconLoader.getIcon("/nodes/testSourceFolder.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_GROUP_BY_SCOPE_TYPE; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_GROUP_BY_SCOPE_TYPE = flag; + rebuild(true); + } + } + + private final class ShowModulesAction extends ToggleAction { + ShowModulesAction() { + super("Show Modules", "Show/Hide Modules", IconLoader.getIcon("/objectBrowser/showModules.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_SHOW_MODULES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_SHOW_MODULES = flag; + rebuild(true); + } + } + + private final class FilterLegalsAction extends ToggleAction { + FilterLegalsAction() { + super("Show Included Only", "Show only files included to the current scope selected", IconLoader.getIcon("/ant/filter.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_FILTER_LEGALS; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_FILTER_LEGALS = flag; + rebuild(true); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeBuilder.java new file mode 100644 index 00000000000..eb4cfc27aad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeBuilder.java @@ -0,0 +1,802 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.LoadingNode; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.StatusBarProgress; +import com.intellij.util.Alarm; +import com.intellij.util.concurrency.WorkerThread; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import com.intellij.util.enumeration.EnumerationCopy; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.tree.*; +import java.awt.*; +import java.util.*; +import java.util.List; + +public abstract class AbstractTreeBuilder { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.AbstractTreeBuilder"); + + protected final JTree myTree; + protected final DefaultTreeModel myTreeModel; + protected AbstractTreeStructure myTreeStructure; + + protected AbstractTreeUpdater myUpdater; + + private Comparator myNodeDescriptorComparator; + private final Comparator myNodeComparator = new Comparator() { + public int compare(TreeNode n1, TreeNode n2) { + if (n1 instanceof LoadingNode || n2 instanceof LoadingNode) return 0; + NodeDescriptor nodeDescriptor1 = (NodeDescriptor)((DefaultMutableTreeNode)n1).getUserObject(); + NodeDescriptor nodeDescriptor2 = (NodeDescriptor)((DefaultMutableTreeNode)n2).getUserObject(); + return (myNodeDescriptorComparator != null)? myNodeDescriptorComparator.compare(nodeDescriptor1, nodeDescriptor2) : nodeDescriptor1.getIndex() - nodeDescriptor2.getIndex(); + } + }; + + protected final DefaultMutableTreeNode myRootNode; + + private final HashMap myElementToNodeMap = new HashMap(); + protected final HashSet myUnbuiltNodes = new HashSet(); + private final TreeExpansionListener myExpansionListener; + + private WorkerThread myWorker = null; + private final ProgressIndicator myProgress = new StatusBarProgress(); + + private static final int WAIT_CURSOR_DELAY = 100; + + private boolean myDisposed = false; + private static final AbstractTreeNodeWrapper TREE_NODE_WRAPPER = new AbstractTreeNodeWrapper(null); + + public AbstractTreeBuilder(JTree tree, DefaultTreeModel treeModel, + AbstractTreeStructure treeStructure, Comparator comparator) { + myTree = tree; + myTreeModel = treeModel; + myRootNode = (DefaultMutableTreeNode)treeModel.getRoot(); + myTreeStructure = treeStructure; + myNodeDescriptorComparator = comparator; + + myExpansionListener = new MyExpansionListener(); + myTree.addTreeExpansionListener(myExpansionListener); + + myUpdater = createUpdater(); + } + + protected AbstractTreeUpdater createUpdater() { + return new AbstractTreeUpdater(this); + } + + public void dispose() { + LOG.assertTrue(!myDisposed); + myDisposed = true; + myTree.removeTreeExpansionListener(myExpansionListener); + disposeNode(myRootNode); + myElementToNodeMap.clear(); + myUpdater.cancelAllRequests(); + if (myWorker != null) { + myWorker.dispose(true); + } + myProgress.cancel(); + } + + public boolean isDisposed() { + return myDisposed; + } + + protected abstract boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor); + + protected abstract boolean isAutoExpandNode(NodeDescriptor nodeDescriptor); + + protected boolean isDisposeOnCollapsing(NodeDescriptor nodeDescriptor) { + return true; + } + + protected boolean isSmartExpand() { + return true; + } + + protected void expandNodeChildren(final DefaultMutableTreeNode node) { + myTreeStructure.commit(); + myUpdater.addSubtreeToUpdate(node); + myUpdater.performUpdate(); + } + + public final AbstractTreeStructure getTreeStructure() { + return myTreeStructure; + } + + public final JTree getTree() { + return myTree; + } + + public final DefaultMutableTreeNode getNodeForElement(Object element) { + //DefaultMutableTreeNode node = (DefaultMutableTreeNode)myElementToNodeMap.get(element); + DefaultMutableTreeNode node = getFirstNode(element); + if (node != null) { + LOG.assertTrue(TreeUtil.isAncestor(myRootNode, node)); + LOG.assertTrue(myRootNode == myTreeModel.getRoot()); + } + return node; + } + + public final DefaultMutableTreeNode getNodeForPath(Object[] path) { + DefaultMutableTreeNode node = null; + for (int idx = 0; idx < path.length; idx++) { + final Object pathElement = path[idx]; + node = (node == null) ? getFirstNode(pathElement) : findNodeForChildElement(node, pathElement); + if (node == null) { + break; + } + } + return node; + } + + public final void buildNodeForElement(Object element) { + myUpdater.performUpdate(); + DefaultMutableTreeNode node = getNodeForElement(element); + if (node == null) { + final List elements = new ArrayList(); + while (true) { + element = myTreeStructure.getParentElement(element); + if (element == null) { + break; + } + elements.add(0, element); + } + + for (int i = 0; i < elements.size(); i++) { + final Object element1 = elements.get(i); + node = getNodeForElement(element1); + if (node != null) { + myTree.expandPath(new TreePath(node.getPath())); + } + } + } + } + + public final void buildNodeForPath(Object[] path) { + myUpdater.performUpdate(); + DefaultMutableTreeNode node = null; + for (int idx = 0; idx < path.length; idx++) { + final Object pathElement = path[idx]; + node = node == null ? getFirstNode(pathElement) : findNodeForChildElement(node, pathElement); + if (node != null) { + myTree.expandPath(new TreePath(node.getPath())); + } + } + } + + public final void setNodeDescriptorComparator(Comparator nodeDescriptorComparator) { + myNodeDescriptorComparator = nodeDescriptorComparator; + ArrayList pathsToExpand = new ArrayList(); + ArrayList selectionPaths = new ArrayList(); + TreeBuilderUtil.storePaths(this, myRootNode, pathsToExpand, selectionPaths, false); + resortChildren(myRootNode); + myTreeModel.nodeStructureChanged(myRootNode); + TreeBuilderUtil.restorePaths(this, pathsToExpand, selectionPaths, false); + } + + private void resortChildren(DefaultMutableTreeNode node) { + ArrayList childNodes = TreeUtil.childrenToArray(node); + node.removeAllChildren(); + Collections.sort(childNodes, myNodeComparator); + for (int i = 0; i < childNodes.size(); i++) { + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)childNodes.get(i); + node.add(childNode); + resortChildren(childNode); + } + } + + protected final void initRootNode() { + Object rootElement = myTreeStructure.getRootElement(); + NodeDescriptor nodeDescriptor = myTreeStructure.createDescriptor(rootElement, null); + myRootNode.setUserObject(nodeDescriptor); + nodeDescriptor.update(); + if (rootElement != null) { + //myElementToNodeMap.put(rootElement, myRootNode); + createMapping(rootElement, myRootNode); + } + addLoadingNode(myRootNode); + boolean willUpdate = false; + if (isAutoExpandNode(nodeDescriptor)) { + willUpdate = myUnbuiltNodes.contains(myRootNode); + myTree.expandPath(new TreePath(myRootNode.getPath())); + } + if (!willUpdate) { + updateNodeChildren(myRootNode); + } + if (myRootNode.getChildCount() == 0) { + myTreeModel.nodeChanged(myRootNode); + } + } + +// Made non-final for Fabrique + public void updateFromRoot() { + updateSubtree(myRootNode); + } + +// Made non-final for Fabrique + protected void updateSubtree(DefaultMutableTreeNode node) { + if (!(node.getUserObject() instanceof NodeDescriptor)) return; + updateNode(node); + updateNodeChildren(node); + } + +// Made non-final for Fabrique + protected void updateNode(DefaultMutableTreeNode node) { + if (!(node.getUserObject() instanceof NodeDescriptor)) return; + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + Object prevElement = descriptor.getElement(); + if (prevElement == null) return; + boolean changes = descriptor.update(); + if (descriptor.getElement() == null) { + LOG.assertTrue(false, + "element == null, updateSubtree should be invoked for parent! builder=" + this + + ", prevElement = " + prevElement + + ", node = " + node); + } + if (changes) { + updateNodeImageAndPosition(node); + } + } + + private void updateNodeChildren(final DefaultMutableTreeNode node) { + myTreeStructure.commit(); + boolean wasExpanded = myTree.isExpanded(new TreePath(node.getPath())); + final boolean wasLeaf = node.getChildCount() == 0; + + final NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + if (descriptor == null) return; + + if (myUnbuiltNodes.contains(node)) { + if (isAlwaysShowPlus(descriptor)) return; // check for isAlwaysShowPlus is important for e.g. changing Show Members state! + + Object element = descriptor.getElement(); + if (myTreeStructure.isToBuildChildrenInBackground(element)) return; //? + + Object[] children = myTreeStructure.getChildElements(descriptor.getElement()); + if (children.length == 0) { + for (int i = 0; i < node.getChildCount(); i++) { + if (node.getChildAt(i) instanceof LoadingNode) { + myTreeModel.removeNodeFromParent((MutableTreeNode)node.getChildAt(i)); + break; + } + } + myUnbuiltNodes.remove(node); + } + return; + } + + Object element = descriptor.getElement(); + if (myTreeStructure.isToBuildChildrenInBackground(element)) { + Runnable updateRunnable = new Runnable() { + public void run() { + descriptor.update(); + Object element = descriptor.getElement(); + if (element == null) return; + + myTreeStructure.getChildElements(element); // load children + } + }; + + Runnable postRunnable = new Runnable() { + public void run() { + descriptor.update(); + Object element = descriptor.getElement(); + if (element != null) { + myUnbuiltNodes.remove(node); + myUpdater.addSubtreeToUpdateByElement(element); + myUpdater.performUpdate(); + + for (int i = 0; i < node.getChildCount(); i++) { + TreeNode child = node.getChildAt(i); + if (child instanceof LoadingNode) { + if (TreeBuilderUtil.isNodeOrChildSelected(myTree, node)) { + myTree.addSelectionPath(new TreePath(myTreeModel.getPathToRoot(node))); + } + myTreeModel.removeNodeFromParent((MutableTreeNode)child); + break; + } + } + } + } + }; + + String text = " searching..."; + for (int i = 0; i < node.getChildCount(); i++) { + TreeNode child = node.getChildAt(i); + if (child instanceof LoadingNode && text.equals(((LoadingNode)child).getUserObject())) { + return; + } + } + LoadingNode loadingNode = new LoadingNode(text); + myTreeModel.insertNodeInto(loadingNode, node, node.getChildCount()); // 2 loading nodes - only one will be removed + + addTaskToWorker(updateRunnable, true, postRunnable); + + return; + } + + Object[] children = myTreeStructure.getChildElements(descriptor.getElement()); + Map elementToIndexMap = new LinkedHashMap(); + for (int i = 0; i < children.length; i++) { + Object child = children[i]; + elementToIndexMap.put(child, new Integer(i)); + } + + ArrayList childNodes = TreeUtil.childrenToArray(node); + for (int i = 0; i < childNodes.size(); i++) { + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)childNodes.get(i); + if (childNode instanceof LoadingNode) continue; + NodeDescriptor childDescr = (NodeDescriptor)childNode.getUserObject(); + if (childDescr == null) { + boolean isInMap = myElementToNodeMap.containsValue(childNode); + LOG.error("childDescr == null, builder=" + this + ", childNode=" + childNode.getClass() + ", isInMap = " + isInMap + ", node = " + node); + continue; + } + Object oldElement = childDescr.getElement(); + if (oldElement == null){ + LOG.error("oldElement == null, builder=" + this + ", childDescr=" + childDescr); + continue; + } + boolean changes = childDescr.update(); + Object newElement = childDescr.getElement(); + Integer index = newElement != null ? elementToIndexMap.get(newElement) : null; + if (index != null) { + if (childDescr.getIndex() != index.intValue()) { + changes = true; + } + childDescr.setIndex(index.intValue()); + } + if (newElement != null && changes) { + updateNodeImageAndPosition(childNode); + } + if (!oldElement.equals(newElement)) { + removeMapping(oldElement, childNode); + if (newElement != null) { + createMapping(newElement, childNode); + } + } + + if (index == null) { + int selectedIndex = -1; + if (TreeBuilderUtil.isNodeOrChildSelected(myTree, childNode)) { + selectedIndex = node.getIndex(childNode); + } + + myTreeModel.removeNodeFromParent(childNode); + disposeNode(childNode); + + if (selectedIndex >= 0) { + if (node.getChildCount() > 0) { + if (node.getChildCount() > selectedIndex) { + TreeNode newChildNode = node.getChildAt(selectedIndex); + myTree.addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChildNode))); + } + else { + TreeNode newChild = node.getChildAt(node.getChildCount() - 1); + myTree.addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChild))); + } + } + else { + myTree.addSelectionPath(new TreePath(myTreeModel.getPathToRoot(node))); + } + } + } + else { + elementToIndexMap.remove(newElement); + updateNodeChildren(childNode); + } + + if (node.equals(myRootNode)) { + myTreeModel.nodeChanged(myRootNode); + } + } + + ArrayList nodesToInsert = new ArrayList(); + for (Iterator iterator = elementToIndexMap.keySet().iterator(); iterator.hasNext();) { + Object child = iterator.next(); + Integer index = elementToIndexMap.get(child); + final NodeDescriptor childDescr = myTreeStructure.createDescriptor(child, descriptor); + if (childDescr == null) { + LOG.error("childDescr == null, treeStructure = " + myTreeStructure + ", child = " + child); + continue; + } + childDescr.setIndex(index.intValue()); + childDescr.update(); + if (childDescr.getElement() == null) { + LOG.error("childDescr.getElement() == null, child = " + child + ", builder = " + this); + continue; + } + final DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(childDescr); + nodesToInsert.add(childNode); + createMapping(child, childNode); + } + + insertNodesInto(nodesToInsert, node); + + for (int i = 0; i < nodesToInsert.size(); i++) { + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)nodesToInsert.get(i); + addLoadingNode(childNode); + updateNodeChildren(childNode); + } + + if (wasExpanded) { + myTree.expandPath(new TreePath(node.getPath())); + } + + if (wasExpanded || wasLeaf) { + final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + alarm.addRequest( + new Runnable() { + public void run() { + myTree.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + WAIT_CURSOR_DELAY + ); + + if (wasLeaf && isAutoExpandNode(descriptor)) { + myTree.expandPath(new TreePath(node.getPath())); + } + + ArrayList nodes = TreeUtil.childrenToArray(node); + for (int i = 0; i < nodes.size(); i++) { + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)nodes.get(i); + if (childNode instanceof LoadingNode) continue; + NodeDescriptor childDescr = (NodeDescriptor)childNode.getUserObject(); + if (isAutoExpandNode(childDescr)) { + myTree.expandPath(new TreePath(childNode.getPath())); + } + } + + int n = alarm.cancelAllRequests(); + if (n == 0) { + myTree.setCursor(Cursor.getDefaultCursor()); + } + } + + } + + private void addLoadingNode(DefaultMutableTreeNode node) { + final NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + if (!isAlwaysShowPlus(descriptor)) { + Object element = descriptor.getElement(); + if (myTreeStructure.isToBuildChildrenInBackground(element)) { + final boolean[] hasNoChildren = new boolean[1]; + Runnable runnable = new Runnable() { + public void run() { + descriptor.update(); + Object element = descriptor.getElement(); + if (element == null) return; + + Object[] children = myTreeStructure.getChildElements(element); + hasNoChildren[0] = children.length == 0; + } + }; + + Runnable postRunnable = new Runnable() { + public void run() { + if (hasNoChildren[0]) { + descriptor.update(); + Object element = descriptor.getElement(); + if (element != null) { + DefaultMutableTreeNode node = getNodeForElement(element); + if (node != null) { + myTree.expandPath(new TreePath(node.getPath())); + } + } + } + } + }; + + addTaskToWorker(runnable, false, postRunnable); + } + else { + Object[] children = myTreeStructure.getChildElements(descriptor.getElement()); + if (children.length == 0) return; + } + } + + myTreeModel.insertNodeInto(new LoadingNode(), node, 0); + myUnbuiltNodes.add(node); + } + + protected void addTaskToWorker(final Runnable runnable, boolean first, final Runnable postRunnable) { + Runnable runnable1 = new Runnable() { + public void run() { + try { + ProgressManager.getInstance().runProcess( + new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(runnable); + if (postRunnable != null) { + ApplicationManager.getApplication().invokeLater(postRunnable); + } + } + }, + myProgress + ); + } + catch (ProcessCanceledException e) { + } + } + }; + + if (myWorker == null || myWorker.isDisposed()) { + myWorker = new WorkerThread("AbstractTreeBuilder.Worker"); + myWorker.start(); + if (first) { + myWorker.addTaskFirst(runnable1); + } + else { + myWorker.addTask(runnable1); + } + myWorker.dispose(false); + } + else { + if (first) { + myWorker.addTaskFirst(runnable1); + } + else { + myWorker.addTask(runnable1); + } + } + } + + private void updateNodeImageAndPosition(final DefaultMutableTreeNode node) { + if (!(node.getUserObject() instanceof NodeDescriptor)) return; + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + if (descriptor.getElement() == null) return; + DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)node.getParent(); + if (parentNode != null) { + int oldIndex = parentNode.getIndex(node); + + int newIndex = 0; + for (int i = 0; i < parentNode.getChildCount(); i++) { + TreeNode node1 = parentNode.getChildAt(i); + if (node == node1) continue; + if (myNodeComparator.compare(node, node1) > 0) newIndex++; + } + + if (oldIndex != newIndex) { + ArrayList pathsToExpand = new ArrayList(); + ArrayList selectionPaths = new ArrayList(); + TreeBuilderUtil.storePaths(this, node, pathsToExpand, selectionPaths, false); + myTreeModel.removeNodeFromParent(node); + myTreeModel.insertNodeInto(node, parentNode, newIndex); + TreeBuilderUtil.restorePaths(this, pathsToExpand, selectionPaths, false); + } + else { + myTreeModel.nodeChanged(node); + } + } + else { + myTreeModel.nodeChanged(node); + } + } + + private void insertNodesInto(ArrayList nodes, DefaultMutableTreeNode parentNode) { + if (nodes.size() == 0) return; + nodes = (ArrayList)nodes.clone(); + Collections.sort(nodes, myNodeComparator); + int[] indices = new int[nodes.size()]; + for (int i = 0; i < nodes.size(); i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)nodes.get(i); + int index = getIndexToInsert(node, parentNode); + indices[i] = index; + parentNode.insert(node, index); + } + myTreeModel.nodesWereInserted(parentNode, indices); + } + + private int getIndexToInsert(DefaultMutableTreeNode node, DefaultMutableTreeNode parentNode) { + ArrayList arrayList = TreeUtil.childrenToArray(parentNode); + arrayList.add(node); + Collections.sort(arrayList, myNodeComparator); + return arrayList.indexOf(node); + } + + private void disposeNode(DefaultMutableTreeNode node) { + if (node.getChildCount() > 0) { + for (DefaultMutableTreeNode _node = (DefaultMutableTreeNode)node.getFirstChild(); + _node != null; + _node = _node.getNextSibling()) { + disposeNode(_node); + } + } + if (node instanceof LoadingNode) return; + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + final Object element = descriptor.getElement(); + removeMapping(element, node); + node.setUserObject(null); + node.removeAllChildren(); + } + + private class MyExpansionListener implements TreeExpansionListener { + public void treeExpanded(TreeExpansionEvent event) { + TreePath path = event.getPath(); + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (!myUnbuiltNodes.contains(node)) return; + myUnbuiltNodes.remove(node); + final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + alarm.addRequest( + new Runnable() { + public void run() { + myTree.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + }, + WAIT_CURSOR_DELAY + ); + + expandNodeChildren(node); + + for (int i = 0; i < node.getChildCount(); i++) { + if (node.getChildAt(i) instanceof LoadingNode) { + myTreeModel.removeNodeFromParent((MutableTreeNode)node.getChildAt(i)); + break; + } + } + + int n = alarm.cancelAllRequests(); + if (n == 0) { + myTree.setCursor(Cursor.getDefaultCursor()); + } + + if (isSmartExpand() && node.getChildCount() == 1) { // "smart" expand + TreeNode childNode = node.getChildAt(0); + final TreePath childPath = path.pathByAddingChild(childNode); + myTree.expandPath(childPath); + } + } + + public void treeCollapsed(TreeExpansionEvent e) { + TreePath path = e.getPath(); + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (isSelectionInside(node)) { + // when running outside invokeLater, in EJB view just collapsed node get expanded again (bug 4585) + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myTree.addSelectionPath(new TreePath(myTreeModel.getPathToRoot(node))); + } + }); + } + if (!(node.getUserObject() instanceof NodeDescriptor)) return; + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + if (isDisposeOnCollapsing(descriptor)) { + removeChildren(node); + addLoadingNode(node); + if (node.equals(myRootNode)) { + myTree.addSelectionPath(new TreePath(myRootNode.getPath())); + } + else { + myTreeModel.reload(node); + } + } + } + + private void removeChildren(DefaultMutableTreeNode node) { + EnumerationCopy copy = new EnumerationCopy(node.children()); + while (copy.hasMoreElements()) { + disposeNode((DefaultMutableTreeNode)copy.nextElement()); + } + node.removeAllChildren(); + myTreeModel.nodeStructureChanged(node); + } + + private boolean isSelectionInside(DefaultMutableTreeNode parent) { + TreePath path = new TreePath(myTreeModel.getPathToRoot(parent)); + TreePath[] paths = myTree.getSelectionPaths(); + if (paths == null) return false; + for (int i = 0; i < paths.length; i++) { + TreePath path1 = paths[i]; + if (path.isDescendant(path1)) return true; + } + return false; + } + } + + private void createMapping(Object element, DefaultMutableTreeNode node) { + if (!myElementToNodeMap.containsKey(element)) { + myElementToNodeMap.put(element, node); + } + else { + final Object value = myElementToNodeMap.get(element); + final List nodes; + if (value instanceof DefaultMutableTreeNode) { + nodes = new ArrayList(); + nodes.add((DefaultMutableTreeNode)value); + myElementToNodeMap.put(element, nodes); + } + else { + nodes = (List)value; + } + nodes.add(node); + } + } + + private void removeMapping(Object element, DefaultMutableTreeNode node) { + final Object value = myElementToNodeMap.get(element); + if (value == null) { + return; + } + if (value instanceof DefaultMutableTreeNode) { + if (value.equals(node)) { + myElementToNodeMap.remove(element); + } + } + else { + List nodes = (List)value; + final boolean reallyRemoved = nodes.remove(node); + if (reallyRemoved) { + if (nodes.size() == 0) { + myElementToNodeMap.remove(element); + } + } + } + } + + private DefaultMutableTreeNode getFirstNode(Object element) { + final Object value = findNodeByElement(element); + if (value == null) { + return null; + } + if (value instanceof DefaultMutableTreeNode) { + return (DefaultMutableTreeNode)value; + } + final List nodes = (List)value; + return nodes.size() > 0 ? nodes.get(0) : null; + } + + private Object findNodeByElement(Object element) { + if (myElementToNodeMap.containsKey(element)){ + return myElementToNodeMap.get(element); + } + + TREE_NODE_WRAPPER.setValue(element); + return myElementToNodeMap.get(TREE_NODE_WRAPPER); + } + + private DefaultMutableTreeNode findNodeForChildElement(DefaultMutableTreeNode parentNode, Object element) { + final Object value = myElementToNodeMap.get(element); + if (value == null) { + return null; + } + + if (value instanceof DefaultMutableTreeNode) { + final DefaultMutableTreeNode elementNode = (DefaultMutableTreeNode)value; + return parentNode.equals(elementNode.getParent()) ? elementNode : null; + } + + final List allNodesForElement = (List)value; + for (Iterator it = allNodesForElement.iterator(); it.hasNext();) { + final DefaultMutableTreeNode elementNode = it.next(); + if (parentNode.equals(elementNode.getParent())) { + return elementNode; + } + } + + return null; + } + + private static class AbstractTreeNodeWrapper extends AbstractTreeNode { + public AbstractTreeNodeWrapper(Object element) { + super(null, element); + } + + public Collection getChildren() { + return null; + } + + public void update(PresentationData presentation) { + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructure.java new file mode 100644 index 00000000000..c3db7db6e0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructure.java @@ -0,0 +1,16 @@ +package com.intellij.ide.util.treeView; + +public abstract class AbstractTreeStructure { + public abstract Object getRootElement(); + public abstract Object[] getChildElements(Object element); + public abstract Object getParentElement(Object element); + + public abstract NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor); + + public abstract void commit(); + public abstract boolean hasSomethingToCommit(); + + public boolean isToBuildChildrenInBackground(Object element){ + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java new file mode 100644 index 00000000000..4842fc8f9ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java @@ -0,0 +1,54 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public abstract class AbstractTreeStructureBase extends AbstractTreeStructure { + protected final Project myProject; + + static private final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.AbstractTreeStructureBase"); + + + protected AbstractTreeStructureBase(Project project) { + myProject = project; + } + + public Object[] getChildElements(Object element) { + LOG.assertTrue(element instanceof AbstractTreeNode, element.getClass().getName()); + AbstractTreeNode treeNode = ((AbstractTreeNode)element); + Collection elements = treeNode.getChildren(); + List providers = getProviders(); + ArrayList modified = elements != null ? new ArrayList(elements) : new ArrayList(); + for (Iterator iterator = providers.iterator(); iterator.hasNext();) { + TreeStructureProvider provider = (TreeStructureProvider)iterator.next(); + modified = new ArrayList(provider.modify(treeNode, modified, ViewSettings.DEFAULT)); + } + elements = modified; + for (Iterator iterator = elements.iterator(); iterator.hasNext();) { + AbstractTreeNode node = iterator.next(); + node.setParent(treeNode); + } + return (Object[])modified.toArray(new Object[modified.size()]); + } + + public Object getParentElement(Object element) { + if (element instanceof AbstractTreeNode){ + return ((AbstractTreeNode)element).getParent(); + } else { + return null; + } + } + + public NodeDescriptor createDescriptor(final Object element, final NodeDescriptor parentDescriptor) { + return ((AbstractTreeNode)element); + } + + public abstract List getProviders(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeUpdater.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeUpdater.java new file mode 100644 index 00000000000..fc94fadc4ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AbstractTreeUpdater.java @@ -0,0 +1,133 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.Alarm; + +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Iterator; +import java.util.LinkedList; + +public class AbstractTreeUpdater { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.AbstractTreeUpdater"); + + private int myDelay = 300; + + private final Alarm myAlarm = new Alarm(); + private LinkedList myNodesToUpdate = new LinkedList(); + private final AbstractTreeBuilder myTreeBuilder; + private Runnable myRunAfterUpdate; + private Runnable myRunBeforeUpdate; + + public AbstractTreeUpdater(AbstractTreeBuilder treeBuilder) { + myTreeBuilder = treeBuilder; + } + + /** + * @param delay update delay in milliseconds. + */ + public void setDelay(int delay) { + myDelay = delay; + } + + public void addSubtreeToUpdate(DefaultMutableTreeNode rootNode) { + if (LOG.isDebugEnabled()) { + LOG.debug("addSubtreeToUpdate:" + rootNode); + } + + for (Iterator iterator = myNodesToUpdate.iterator(); iterator.hasNext();) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) iterator.next(); + if (rootNode.isNodeAncestor(node)){ + return; + } + else if (node.isNodeAncestor(rootNode)){ + iterator.remove(); + } + } + myNodesToUpdate.add(rootNode); + + myAlarm.cancelAllRequests(); + myAlarm.addRequest( + new Runnable() { + public void run() { + if (myTreeBuilder.isDisposed()) return; + + if (myTreeBuilder.getTreeStructure().hasSomethingToCommit()) { + myAlarm.addRequest(this, myDelay); + return; + } + + myTreeBuilder.getTreeStructure().commit(); + //if (myAlarm.getActiveRequestCount() > 0) return; // do not update if commit caused some changes + try { + performUpdate(); + } catch(RuntimeException e) { + LOG.error(myTreeBuilder.getClass().getName(), e); + } + } + }, + myDelay, + ModalityState.stateForComponent(myTreeBuilder.getTree()) + ); + } + + protected void updateSubtree(DefaultMutableTreeNode node) { + myTreeBuilder.updateSubtree(node); + } + + public void performUpdate() { + if (myRunBeforeUpdate != null){ + myRunBeforeUpdate.run(); + } + + while(myNodesToUpdate.size() > 0){ + DefaultMutableTreeNode node = (DefaultMutableTreeNode) myNodesToUpdate.removeFirst(); + updateSubtree(node); + } + + if (myRunAfterUpdate != null) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + synchronized (this) { + if (myRunAfterUpdate != null) { + myRunAfterUpdate.run(); + myRunAfterUpdate = null; + } + } + } + }); + } + } + + public boolean addSubtreeToUpdateByElement(Object element) { + if (LOG.isDebugEnabled()) { + LOG.debug("addSubtreeToUpdateByElement:" + element); + } + + DefaultMutableTreeNode node = myTreeBuilder.getNodeForElement(element); + if (node != null){ + addSubtreeToUpdate(node); + return true; + } + else{ + return false; + } + } + + public boolean hasRequestsForUpdate() { + return myAlarm.getActiveRequestCount() > 0; + } + + public void cancelAllRequests(){ + myAlarm.cancelAllRequests(); + } + + public synchronized void runAfterUpdate(final Runnable runnable) { + myRunAfterUpdate = runnable; + } + + public synchronized void runBeforeUpdate(final Runnable runnable) { + myRunBeforeUpdate = runnable; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AlphaComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AlphaComparator.java new file mode 100644 index 00000000000..9489bebaf4d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/AlphaComparator.java @@ -0,0 +1,58 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.projectView.impl.nodes.*; +import com.intellij.ide.structureView.impl.java.PropertyGroup; + +import java.util.Comparator; + +public class AlphaComparator implements Comparator{ + public static final AlphaComparator INSTANCE = new AlphaComparator(); + + protected AlphaComparator() { + } + + public int compare(NodeDescriptor nodeDescriptor1, NodeDescriptor nodeDescriptor2) { + int weight1 = getWeight(nodeDescriptor1); + int weight2 = getWeight(nodeDescriptor2); + if (weight1 != weight2) { + return weight1 - weight2; + } + String s1 = nodeDescriptor1.toString(); + String s2 = nodeDescriptor2.toString(); + if (s1 == null) return s2 == null ? 0 : -1; + if (s2 == null) return +1; + return s1.compareToIgnoreCase(s2); + } + + protected int getWeight(NodeDescriptor descriptor) { + if (descriptor instanceof PsiDirectoryNode) { + return ((PsiDirectoryNode)descriptor).isFQNameShown() ? 7 : 0; + } + + if (descriptor instanceof PackageElementNode) { + return 0; + } + + if (descriptor instanceof PackageViewLibrariesNode) { + return 6; + } + + // show module groups before other modules + if (descriptor instanceof ModuleGroupNode) { + return 0; + } + if (descriptor instanceof PsiFileNode || descriptor instanceof ClassTreeNode) { + return 2; + } + if (descriptor instanceof PsiMethodNode) { + return ((PsiMethodNode)descriptor).isConstructor() ? 4 : 5; + } + if (descriptor.getElement() instanceof PropertyGroup) { + return 6; + } + if (descriptor instanceof PsiFieldNode) { + return 7; + } + return 3; //?? + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/IndexComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/IndexComparator.java new file mode 100644 index 00000000000..5c40a7596ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/IndexComparator.java @@ -0,0 +1,20 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Aug 30, 2002 + */ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.util.treeView.NodeDescriptor; + +import java.util.Comparator; + +public class IndexComparator implements Comparator { + public static final IndexComparator INSTANCE = new IndexComparator(); + + private IndexComparator() {} + + public int compare(NodeDescriptor nodeDescriptor1, NodeDescriptor nodeDescriptor2) { + return nodeDescriptor1.getIndex() - nodeDescriptor2.getIndex(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SmartElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SmartElementDescriptor.java new file mode 100644 index 00000000000..db5a901e505 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SmartElementDescriptor.java @@ -0,0 +1,63 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; + +import javax.swing.*; +import java.awt.*; + +public class SmartElementDescriptor extends NodeDescriptor{ + protected PsiElement myElement; + private SmartPsiElementPointer mySmartPointer; + + public SmartElementDescriptor(Project project, NodeDescriptor parentDescriptor, PsiElement element) { + super(project, parentDescriptor); + myElement = element; + mySmartPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(element); + } + + public Object getElement() { + return myElement; + } + + protected boolean isMarkReadOnly() { + return getParentDescriptor() instanceof PsiDirectoryNode; + } + + protected boolean isMarkModified() { + return getParentDescriptor() instanceof PsiDirectoryNode; + } + + // Should be called in atomic action + public boolean update() { + myElement = mySmartPointer.getElement(); + if (myElement == null) return true; + int flags = Iconable.ICON_FLAG_VISIBILITY; + if (isMarkReadOnly()){ + flags |= Iconable.ICON_FLAG_READ_STATUS; + } + Icon icon = myElement.getIcon(flags); + Color color = null; + + if (isMarkModified() ){ + color = FileStatusManager.getInstance(myProject).getStatus(myElement.getContainingFile().getVirtualFile()).getColor(); + } + if (((CopyPasteManagerEx)CopyPasteManager.getInstance()).isCutElement(myElement)) { + color = CopyPasteManager.CUT_COLOR; + } + + boolean changes = !Comparing.equal(icon, myOpenIcon) || !Comparing.equal(color, myColor); + myOpenIcon = icon; + myClosedIcon = myOpenIcon; + myColor = color; + return changes; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SourceComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SourceComparator.java new file mode 100644 index 00000000000..873245b35f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/SourceComparator.java @@ -0,0 +1,46 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.ide.projectView.impl.nodes.ClassTreeNode; +import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; + +import java.util.Comparator; + +public class SourceComparator implements Comparator{ + public static final SourceComparator INSTANCE = new SourceComparator(); + + private SourceComparator() { + } + + public int compare(NodeDescriptor nodeDescriptor1, NodeDescriptor nodeDescriptor2) { + int weight1 = getWeight(nodeDescriptor1); + int weight2 = getWeight(nodeDescriptor2); + if (weight1 != weight2) { + return weight1 - weight2; + } + if (!(nodeDescriptor1.getParentDescriptor() instanceof ProjectViewProjectNode)){ + if (nodeDescriptor1 instanceof PsiDirectoryNode || nodeDescriptor1 instanceof PsiFileNode){ + return nodeDescriptor1.toString().compareToIgnoreCase(nodeDescriptor2.toString()); + } + if (nodeDescriptor1 instanceof ClassTreeNode && nodeDescriptor2 instanceof ClassTreeNode){ + if (((ClassTreeNode)nodeDescriptor1).isTopLevel()){ + return nodeDescriptor1.toString().compareToIgnoreCase(nodeDescriptor2.toString()); + } + } + } + int index1 = nodeDescriptor1.getIndex(); + int index2 = nodeDescriptor2.getIndex(); + if (index1 == index2) return 0; + return index1 < index2 ? -1 : +1; + } + + private static int getWeight(NodeDescriptor descriptor) { + if (descriptor instanceof PsiDirectoryNode) { + return ((PsiDirectoryNode)descriptor).isFQNameShown() ? 7 : 0; + } + else { + return 2; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeBuilderUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeBuilderUtil.java new file mode 100644 index 00000000000..1e99d513c08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeBuilderUtil.java @@ -0,0 +1,79 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.*; +import java.util.ArrayList; +import java.util.Iterator; + +public class TreeBuilderUtil { + public static void storePaths(AbstractTreeBuilder treeBuilder, DefaultMutableTreeNode root, ArrayList pathsToExpand, ArrayList selectionPaths, boolean storeElementsOnly) { + JTree tree = treeBuilder.getTree(); + TreePath path = new TreePath(root.getPath()); + if (tree.isPathSelected(path)){ + selectionPaths.add(storeElementsOnly ? ((NodeDescriptor)root.getUserObject()).getElement() : path); + } + if (tree.isExpanded(path) || root.getChildCount() == 0){ + pathsToExpand.add(storeElementsOnly ? ((NodeDescriptor)root.getUserObject()).getElement() : path); + _storePaths(tree, root, pathsToExpand, selectionPaths, storeElementsOnly); + } + } + + private static void _storePaths(JTree tree, DefaultMutableTreeNode root, ArrayList pathsToExpand, ArrayList selectionPaths, boolean storeElementsOnly) { + ArrayList childNodes = TreeUtil.childrenToArray(root); + for(Iterator iterator = childNodes.iterator(); iterator.hasNext();){ + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)iterator.next(); + TreePath path = new TreePath(childNode.getPath()); + if (tree.isPathSelected(path)){ + selectionPaths.add(storeElementsOnly ? ((NodeDescriptor)childNode.getUserObject()).getElement() : path); + } + if (tree.isExpanded(path) || childNode.getChildCount() == 0){ + pathsToExpand.add(storeElementsOnly && childNode.getUserObject() instanceof NodeDescriptor ? ((NodeDescriptor)childNode.getUserObject()).getElement() : path); + _storePaths(tree, childNode, pathsToExpand, selectionPaths, storeElementsOnly); + } + } + } + + public static void restorePaths(AbstractTreeBuilder treeBuilder, ArrayList pathsToExpand, ArrayList selectionPaths, boolean elementsOnly) { + JTree tree = treeBuilder.getTree(); + if (!elementsOnly){ + for(int i = 0; i < pathsToExpand.size(); i++){ + TreePath path = (TreePath)pathsToExpand.get(i); + tree.expandPath(path); + } + tree.addSelectionPaths((TreePath[])selectionPaths.toArray(new TreePath[selectionPaths.size()])); + } + else{ + for(int i = 0; i < pathsToExpand.size(); i++){ + Object element = pathsToExpand.get(i); + treeBuilder.buildNodeForElement(element); + DefaultMutableTreeNode node = treeBuilder.getNodeForElement(element); + if (node != null){ + tree.expandPath(new TreePath(node.getPath())); + } + } + for(int i = 0; i < selectionPaths.size(); i++){ + Object element = selectionPaths.get(i); + DefaultMutableTreeNode node = treeBuilder.getNodeForElement(element); + if (node != null){ + DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel(); + tree.addSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + } + } + } + } + + public static boolean isNodeOrChildSelected(JTree tree, DefaultMutableTreeNode node){ + TreePath[] selectionPaths = tree.getSelectionPaths(); + if (selectionPaths == null || selectionPaths.length == 0) return false; + + TreePath path = new TreePath(node.getPath()); + for(int i = 0; i < selectionPaths.length; i++){ + TreePath selectionPath = selectionPaths[i]; + if (path.isDescendant(selectionPath)) return true; + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeViewUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeViewUtil.java new file mode 100644 index 00000000000..02a112d30a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/TreeViewUtil.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ide.util.treeView; + +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; + +/** + * @author Eugene Zhuravlev + * Date: Oct 6, 2004 + */ +public class TreeViewUtil { + + public static String calcAbbreviatedPackageFQName(PsiPackage aPackage) { + + class Abbreviator { + static final int SUBPACKAGE_LIMIT = 2; + boolean shouldAbbreviateName(PsiPackage p) {return scanPackages(p, 1);} + boolean scanPackages(PsiPackage p, int packageNameOccurrencesFound) { + final PsiPackage[] subPackages = p.getSubPackages(); + packageNameOccurrencesFound += subPackages.length; + if (packageNameOccurrencesFound > SUBPACKAGE_LIMIT) { + return true; + } + for (int idx = 0; idx < subPackages.length; idx++) { + if (scanPackages(subPackages[idx], packageNameOccurrencesFound)) { + return true; + } + } + return false; + } + }; + + final Abbreviator abbreviator = new Abbreviator(); + final StringBuffer name = new StringBuffer(aPackage.getName()); + for (PsiPackage parentPackage = aPackage.getParentPackage(); parentPackage != null; parentPackage = parentPackage.getParentPackage()) { + final String packageName = parentPackage.getName(); + if (packageName == null || packageName.length() == 0) { + break; // reached default package + } + name.insert(0, "."); + if (packageName.length() > 2 && abbreviator.shouldAbbreviateName(parentPackage)) { + name.insert(0, packageName.substring(0, 1)); + } + else { + name.insert(0, packageName); + } + } + return name.toString(); + } + + /** + * a directory is considered "empty" if it has at least one child and all its children are only directories + * @param strictlyEmpty if true, the package is considered empty if it has only 1 child and this child is a directory + * otherwise the package is considered as empty if all direct children that it has are directories + */ + public static final boolean isEmptyMiddlePackage(PsiDirectory dir, boolean strictlyEmpty) { + final PsiElement[] children = dir.getChildren(); + if (children.length == 0) { + return false; + } + final int subpackagesCount = getSubpackagesCount(dir); + return strictlyEmpty? children.length == 1 && (children.length == subpackagesCount) : (children.length == subpackagesCount); + } + + private static int getSubpackagesCount(PsiDirectory dir) { + int count = 0; + final PsiDirectory[] subdirs = dir.getSubdirectories(); + for (int idx = 0; idx < subdirs.length; idx++) { + final PsiDirectory subdir = subdirs[idx]; + count += subdir.getPackage() != null? 1 : 0; + } + return count; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/XmlDoctypeNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/XmlDoctypeNodeDescriptor.java new file mode 100644 index 00000000000..bcad40400b0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/XmlDoctypeNodeDescriptor.java @@ -0,0 +1,14 @@ +package com.intellij.ide.util.treeView; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; + +/** + * @author Mike + */ +public class XmlDoctypeNodeDescriptor extends SmartElementDescriptor { + public XmlDoctypeNodeDescriptor(Project project, NodeDescriptor parentDescriptor, PsiElement element) { + super(project, parentDescriptor, element); + myName = "DOCTYPE"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java new file mode 100644 index 00000000000..97ce763c0c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java @@ -0,0 +1,180 @@ +package com.intellij.ide.util.treeView.smartTree; + +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; + +import java.util.*; + +abstract class CachingChildrenTreeNode extends AbstractTreeNode { + private List myChildren; + protected final TreeModel myTreeModel; + + public CachingChildrenTreeNode(Project project, Value value, TreeModel treeModel) { + super(project, value); + myTreeModel = treeModel; + } + + public Collection getChildren() { + ensureChildrenAreInitialized(); + return new ArrayList(myChildren); + } + + private void ensureChildrenAreInitialized() { + if (myChildren == null) { + myChildren = new ArrayList(); + rebuildSubtree(); + } + } + + public void addSubElement(CachingChildrenTreeNode node) { + ensureChildrenAreInitialized(); + myChildren.add(node); + node.setParent(this); + } + + public void setChildren(Collection children) { + clearChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + AbstractTreeNode node = iterator.next(); + myChildren.add((CachingChildrenTreeNode)node); + node.setParent(this); + } + } + + private static class CompositeComparator implements Comparator { + private final Sorter[] mySorters; + + public CompositeComparator(final Sorter[] sorters) { + mySorters = sorters; + } + + public int compare(final AbstractTreeNode o1, final AbstractTreeNode o2) { + final Object value1 = o1.getValue(); + final Object value2 = o2.getValue(); + for (int i = 0; i < mySorters.length; i++) { + Sorter sorter = mySorters[i]; + final int result = sorter.getComparator().compare(value1, value2); + if (result != 0) return result; + } + return 0; + } + } + + public void sortChildren(Sorter[] sorters) { + Collections.sort(myChildren, new CompositeComparator(sorters)); + + for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { + CachingChildrenTreeNode child = iterator.next(); + if (child instanceof GroupWrapper) { + child.sortChildren(sorters); + } + } + + } + + public void filterChildren(Filter[] filters) { + Collection children = getChildren(); + for (int i = 0; i < filters.length; i++) { + Filter filter = filters[i]; + for (Iterator eachNode = children.iterator(); eachNode.hasNext();) { + TreeElementWrapper eachChild = (TreeElementWrapper)eachNode.next(); + if (!filter.isVisible(eachChild.getValue())) { + eachNode.remove(); + } + } + } + setChildren(children); + } + + public void groupChildren(Grouper[] groupers) { + for (int i = 0; i < groupers.length; i++) { + Grouper grouper = groupers[i]; + groupElements(grouper); + } + } + + public void groupElements(Grouper grouper) { + + ArrayList ungrouped = new ArrayList(); + Collection children = getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + CachingChildrenTreeNode node = (CachingChildrenTreeNode)iterator.next(); + if (node instanceof TreeElementWrapper) { + ungrouped.add(node); + } else { + node.groupElements(grouper); + } + } + + processUngrouped(ungrouped, grouper); + + + Collection result = new ArrayList(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + AbstractTreeNode child = iterator.next(); + AbstractTreeNode parent = child.getParent(); + if (parent != this){ + if (!result.contains(parent)) result.add(parent); + } else { + result.add(child); + } + } + setChildren(result); + } + + private void processUngrouped(ArrayList ungrouped, + Grouper grouper) { + Collection ungroupedObjects = collectValues(ungrouped); + Collection groups = grouper.group(ungroupedObjects); + + Map groupNodes = createGroupNodes(groups); + + for (Iterator eachGroup = groups.iterator(); eachGroup.hasNext();) { + Group group = eachGroup.next(); + for (Iterator eachUngrNode = ungrouped.iterator(); eachUngrNode.hasNext();) { + AbstractTreeNode node = eachUngrNode.next(); + if (group.contains((TreeElement)node.getValue())) { + GroupWrapper groupWrapper = groupNodes.get(group); + groupWrapper.addSubElement((CachingChildrenTreeNode)node); + node.setParent(groupWrapper); + eachUngrNode.remove(); + } + } + } + } + + private Collection collectValues(ArrayList ungrouped) { + ArrayList objects = new ArrayList(); + for (Iterator iterator = ungrouped.iterator(); iterator.hasNext();) { + objects.add((TreeElement)iterator.next().getValue()); + } + return objects; + } + + private Map createGroupNodes(Collection groups) { + com.intellij.util.containers.HashMap result = new com.intellij.util.containers.HashMap(); + for (Iterator iterator = groups.iterator(); iterator.hasNext();) { + Group group = iterator.next(); + result.put(group, new GroupWrapper(getProject(), group, myTreeModel)); + } + return result; + } + + + private void rebuildSubtree() { + initChildren(); + performTreeActions(); + } + + protected abstract void performTreeActions(); + + protected abstract void initChildren(); + + protected void clearChildren() { + myChildren.clear(); + } + + public void rebuildChildren() { + myChildren = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java new file mode 100644 index 00000000000..e460d7a13b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java @@ -0,0 +1,26 @@ +package com.intellij.ide.util.treeView.smartTree; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +class GroupWrapper extends CachingChildrenTreeNode { + public GroupWrapper(Project project, Group value, TreeModel treeModel) { + super(project, value, treeModel); + } + + public boolean contains(VirtualFile file) { + return false; + } + + public void update(PresentationData presentation) { + presentation.updateFrom(getValue().getPresentation()); + } + + public void initChildren() { + clearChildren(); + } + + protected void performTreeActions() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java new file mode 100644 index 00000000000..947a3db5c84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java @@ -0,0 +1,53 @@ +package com.intellij.ide.util.treeView.smartTree; + +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; + +public class SmartTreeStructure extends AbstractTreeStructure { + + private final TreeModel myModel; + private final Project myProject; + private TreeElementWrapper myRootElementWrapper; + + public SmartTreeStructure(Project project, TreeModel model) { + myModel = model; + myProject = project; + + } + + public void commit() { + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + return ((AbstractTreeNode)element); + } + + public Object[] getChildElements(Object element) { + return ((AbstractTreeNode)element).getChildren().toArray(); + } + + public Object getParentElement(Object element) { + return ((AbstractTreeNode)element).getParent(); + } + + public Object getRootElement() { + if (myRootElementWrapper == null){ + myRootElementWrapper = createTree(); + } + return myRootElementWrapper; + } + + private TreeElementWrapper createTree() { + return new TreeElementWrapper(myProject, myModel.getRoot(), myModel); + } + + public boolean hasSomethingToCommit() { + return false; + } + + public void rebuildTree() { + ((CachingChildrenTreeNode)getRootElement()).rebuildChildren(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java new file mode 100644 index 00000000000..97b672e228a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java @@ -0,0 +1,34 @@ +package com.intellij.ide.util.treeView.smartTree; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +class TreeElementWrapper extends CachingChildrenTreeNode{ + public TreeElementWrapper(Project project, TreeElement value, TreeModel treeModel) { + super(project, value, treeModel); + } + + public void initChildren() { + clearChildren(); + TreeElement[] children = getValue().getChildren(); + for (int i = 0; i < children.length; i++) { + TreeElementWrapper childNode = new TreeElementWrapper(getProject(), children[i], myTreeModel); + addSubElement(childNode); + } + } + + public boolean contains(VirtualFile file) { + return false; + } + + public void update(PresentationData presentation) { + presentation.updateFrom(getValue().getPresentation()); + } + + protected void performTreeActions() { + filterChildren(myTreeModel.getFilters()); + groupChildren(myTreeModel.getGroupers()); + sortChildren(myTreeModel.getSorters()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/CommandLineApplication.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/CommandLineApplication.java new file mode 100644 index 00000000000..d604b0aced2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/CommandLineApplication.java @@ -0,0 +1,68 @@ +package com.intellij.idea; + +import com.intellij.diagnostic.DialogAppender; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.vfs.local.win32.FileWatcher; +import org.apache.log4j.Appender; +import org.apache.log4j.Category; + +import java.awt.*; +import java.util.Enumeration; + +public abstract class CommandLineApplication { + private static final Logger LOG = Logger.getInstance("#com.intellij.idea.CommandLineApplication"); + protected static CommandLineApplication ourInstance = null; + + static { + System.setProperty(FileWatcher.PROPERTY_WATCHER_DISABLED, "true"); + + final Category category = Category.getRoot(); + final Enumeration enumeration = category.getAllAppenders(); + while (enumeration.hasMoreElements()) { + Object o = enumeration.nextElement(); + if (o instanceof DialogAppender) { + category.removeAppender((Appender)o); + break; + } + } + } + + protected CommandLineApplication() {} + + protected CommandLineApplication(boolean isInternal, boolean isUnitTestMode, String componentsDescriptor) { + this(isInternal, isUnitTestMode, componentsDescriptor, "idea"); + } + + protected CommandLineApplication(boolean isInternal, boolean isUnitTestMode, String componentsDescriptor, String appName) { + LOG.assertTrue(ourInstance == null, "Only one instance allowed."); + ourInstance = this; + ApplicationManagerEx.createApplication(componentsDescriptor, isInternal, isUnitTestMode, appName); + } + + public Object getData(String dataId) { + return null; + } + + public static class MyDataManagerImpl extends DataManagerImpl { + public MyDataManagerImpl() {} + + public DataContext getDataContext() { + return new DataContext() { + public Object getData(String dataId) { + return ourInstance.getData(dataId); + } + }; + } + + public DataContext getDataContext(Component component) { + return getDataContext(); + } + + public DataContext getDataContext(Component component, int x, int y) { + return getDataContext(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaApplication.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaApplication.java new file mode 100644 index 00000000000..6d1d6e24906 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaApplication.java @@ -0,0 +1,134 @@ +package com.intellij.idea; + +import com.intellij.ide.DataManager; +import com.intellij.ide.GeneralSettings; +import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.ide.plugins.PluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.ui.Splash; +import org.jdom.Element; + +import java.io.IOException; + + +public class IdeaApplication { + private static final Logger LOG = Logger.getInstance("#com.intellij.idea.IdeaApplication"); + + private Splash mySplash; + private String[] myArgs; + private boolean myPerformProjectLoad = true; + private static IdeaApplication ourInstance; + + protected IdeaApplication(Splash splash, String[] args) { + LOG.assertTrue(ourInstance == null); + ourInstance = this; + mySplash = splash; + myArgs = args; + + boolean isInternal = "true".equals(System.getProperty("idea.is.internal")); + ApplicationManagerEx.createApplication("componentSets/IdeaComponents", isInternal, false, "idea"); + } + + public static IdeaApplication getInstance() { + return ourInstance; + } + + public void run() { + ApplicationEx app = ApplicationManagerEx.getApplicationEx(); + try { + app.load(PathManager.getOptionsPath()); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (InvalidDataException e) { + e.printStackTrace(); + } + + registerActions(); + + // Event queue should not be changed during initialization of application components. + // It also cannot be changed before initialization of application components because IdeEventQueue uses other + // application components. So it is proper to perform replacement only here. + app.setupIdeQueue(IdeEventQueue.getInstance()); + + app.invokeLater(new Runnable() { + public void run() { + mySplash.dispose(); + mySplash = null; // Allow GC collect the splash window + + if (myPerformProjectLoad) { + loadProject(); + } + } + }, ModalityState.NON_MMODAL); + } + + private void registerActions() { + final PluginDescriptor[] plugins = PluginManager.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + PluginDescriptor plugin = plugins[i]; + + final Element e = plugin.getActionsDescriptionElement(); + if (e != null) { + ActionManagerEx.getInstanceEx().processActionsElement(e, plugin.getLoader()); + } + } + } + + private void loadProject() { + GeneralSettings generalSettings = GeneralSettings.getInstance(); + + String projectFile = null; + if (myArgs != null && myArgs.length > 0) { + if (myArgs[0] != null && myArgs[0].endsWith(".ipr")) { + projectFile = myArgs[0]; + } + } + + if (projectFile != null) { + ProjectUtil.openProject(projectFile, null, false); + }else if (generalSettings.isReopenLastProject()) { + String lastProjectPath = RecentProjectsManager.getInstance().getLastProjectPath(); + if (lastProjectPath != null) { + ProjectUtil.openProject(lastProjectPath, null, false); + }else{ + // This is VERY BAD code. IONA wants to open their project wizard + // on startup. They replace NEW_PROJECT action and we have to invoke + // this action by ID. PLEASE, DO NOT COPY THIS CODE, DO NOT INVOKE + // ACTION BY THIS WAY!!!!!!!!!!! + AnAction newProjectAction=ActionManager.getInstance().getAction(IdeActions.ACTION_NEW_PROJECT); + AnActionEvent event=new AnActionEvent( + null, + DataManager.getInstance().getDataContext(), + ActionPlaces.MAIN_MENU, + newProjectAction.getTemplatePresentation(), + ActionManager.getInstance(), + 0 + ); + newProjectAction.update(event); + if(newProjectAction.getTemplatePresentation().isEnabled()){ + newProjectAction.actionPerformed(event); + } + } + } + } + + public String[] getCommandLineArguments() { + return myArgs; + } + + public void setPerformProjectLoad(boolean performProjectLoad) { + myPerformProjectLoad = performProjectLoad; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaLogger.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaLogger.java new file mode 100644 index 00000000000..e71a751a26e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaLogger.java @@ -0,0 +1,158 @@ +package com.intellij.idea; + +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.application.impl.ApplicationImpl; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.ApplicationInfoProvider; +import com.intellij.openapi.diagnostic.Logger; +import org.apache.log4j.Level; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; + +/** + * @author Mike + */ +public class IdeaLogger extends Logger { + private static ApplicationInfoProvider ourApplicationInfoProvider = getIdeaInfoProvider(); + + public static String ourLastActionId = ""; + + private org.apache.log4j.Logger myLogger; + /** If not null - it means that errors occurred and it is the first of them. */ + public static Exception ourErrorsOccurred; + + public static String getOurCompilationTimestamp() { + return ourCompilationTimestamp; + } + + private static String ourCompilationTimestamp; + + static { + InputStream stream = Logger.class.getResourceAsStream("/.compilation-timestamp"); + if (stream != null) { + LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream)); + try { + String s = reader.readLine(); + if (s != null) { + ourCompilationTimestamp = s.trim(); + } + } + catch (IOException e) { + } + finally { + try { + stream.close(); + } + catch (IOException e) { + } + } + } + } + + IdeaLogger(org.apache.log4j.Logger logger) { + myLogger = logger; + } + + public boolean isDebugEnabled() { + return myLogger.isDebugEnabled(); + } + + public void debug(String message) { + myLogger.debug(message); + } + + public void debug(Throwable t) { + myLogger.debug("", t); + } + + public void error(String message, Throwable t, String[] details) { + t.printStackTrace(); + String detailString = ""; + for (int i = 0; i < details.length; i++) { + String detail = details[i]; + detailString += (detail + "\n"); + } + + if (ourErrorsOccurred == null) { + String s = ((message != null) && (message.length() > 0)) ? "Error message is '" + message + "'" : ""; + String mess = "Logger errors occurred. See IDEA logs for details. " + s; + ourErrorsOccurred = new Exception(mess + (detailString.length() > 0 ? "\nDetails: " + detailString : ""), t); + } + + myLogger.error(message + (detailString.length() > 0 ? "\nDetails: " + detailString : "")); + logErrorHeader(); + if (t.getCause() != null) { + myLogger.error("Original exception: ", t.getCause()); + } + myLogger.error(message + (detailString.length() > 0 ? "\nDetails: " + detailString : ""), t); + } + + private void logErrorHeader() { + final String info = ourApplicationInfoProvider.getInfo(); + + if (info != null) { + myLogger.error(info); + } + + if (ourCompilationTimestamp != null) { + myLogger.error("Internal version. Compiled " + ourCompilationTimestamp); + } + + myLogger.error("JDK: " + System.getProperties().getProperty("java.version", "unknown")); + myLogger.error("VM: " + System.getProperties().getProperty("java.vm.name", "unknown")); + myLogger.error("Vendor: " + System.getProperties().getProperty("java.vendor", "unknown")); + myLogger.error("OS: " + System.getProperties().getProperty("os.name", "unknown")); + + ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); + if (application != null && application.isComponentsCreated()) { + final String lastPreformedActionId = ourLastActionId; + if (lastPreformedActionId != null) { + myLogger.error("Last Action: " + lastPreformedActionId); + } + + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + if (commandProcessor != null) { + final String currentCommandName = commandProcessor.getCurrentCommandName(); + if (currentCommandName != null) { + myLogger.error("Current Command: " + currentCommandName); + } + } + } + } + + public void info(String message) { + myLogger.info(message); + } + + public void info(String message, Throwable t) { + myLogger.info(message, t); + } + + public static void setApplicationInfoProvider(ApplicationInfoProvider aProvider) { + ourApplicationInfoProvider = aProvider; + } + + private static ApplicationInfoProvider getIdeaInfoProvider() { + return new ApplicationInfoProvider() { + public String getInfo() { + ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); + if (application != null && application.isComponentsCreated()) { + if (application.hasComponent(ApplicationInfo.class)) { + ApplicationInfoEx ideInfo = (ApplicationInfoEx)application.getComponent(ApplicationInfo.class); + return ideInfo.getFullApplicationName() + " " + "Build #" + ideInfo.getBuildNumber(); + } + } + return null; + } + }; + } + + public void setLevel(Level level) { + myLogger.setLevel(level); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaTestApplication.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaTestApplication.java new file mode 100644 index 00000000000..f3e2938f69e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/IdeaTestApplication.java @@ -0,0 +1,32 @@ +package com.intellij.idea; + +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.util.InvalidDataException; + +import java.io.IOException; + +public class IdeaTestApplication extends CommandLineApplication { + private DataProvider myDataContext; + + private IdeaTestApplication() { + super(false, true, "componentSets/IdeaTestComponents"); + } + + public void setDataProvider(DataProvider dataContext) { + myDataContext = dataContext; + } + + public Object getData(String dataId) { + return myDataContext == null ? null : myDataContext.getData(dataId); + } + + public synchronized static IdeaTestApplication getInstance() throws IOException, InvalidDataException { + if (ourInstance == null) { + //Logger.setFactory(LoggerFactory.getInstance()); + new IdeaTestApplication(); + ApplicationManagerEx.getApplicationEx().load(null); + } + return (IdeaTestApplication)ourInstance; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/Launcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/Launcher.java new file mode 100644 index 00000000000..e1fd71324f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/Launcher.java @@ -0,0 +1,51 @@ +package com.intellij.idea; + +import java.io.*; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 4, 2005 + * Time: 10:06:20 PM + * To change this template use File | Settings | File Templates. + */ +public class Launcher { + public static void main(String[] args) throws InterruptedException { + String javaVmExecutablePath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; + String classpath = System.getProperty("java.class.path"); + try { + final Process process = Runtime.getRuntime().exec("cmd " + javaVmExecutablePath + " -cp " + classpath + " com.intellij.idea.Main"); + new Thread(new Redirector(process.getErrorStream(), System.err)).start(); + new Thread(new Redirector(process.getInputStream(), System.out)).start(); + process.waitFor(); + } catch (IOException e) { + System.out.println("Can't launch java VM executable: " + e.getMessage()); + e.printStackTrace(); + } + System.out.println("Launcher exited"); + } + + private static class Redirector implements Runnable { + private InputStream myInput; + private PrintStream myOutput; + + public Redirector(InputStream input, PrintStream output) { + myInput = input; + myOutput = output; + } + + public void run() { + Reader reader = new InputStreamReader(myInput); + do { + int ch = 0; + try { + ch = reader.read(); + } catch (IOException e) { + e.printStackTrace(); + } + if (ch == -1) break; + myOutput.print((char) ch); + } while (true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/LoggerFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/LoggerFactory.java new file mode 100644 index 00000000000..c3d485b7547 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/LoggerFactory.java @@ -0,0 +1,120 @@ +package com.intellij.idea; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.apache.log4j.LogManager; +import org.apache.log4j.xml.DOMConfigurator; + +import java.io.File; +import java.io.StringReader; + +public class LoggerFactory implements Logger.Factory { + private static final String SYSTEM_MACRO = "$SYSTEM_DIR$"; + private static final String APPLICATION_MACRO = "$APPLICATION_DIR$"; + private static final String COMMENT_LINE_FOR_TEST_MODE_MACRO = "$COMMENT_LINE_FOR_TEST_MODE$"; + private static final String LOGDIR_MACRO = "$LOG_DIR$"; + + private boolean myInitialized = false; + + private static final LoggerFactory ourInstance = new LoggerFactory(); + public static final String LOG_DIR = "log"; + + public static LoggerFactory getInstance() { + return ourInstance; + } + + private LoggerFactory() { + } + + public Logger getLoggerInstance(String name) { + synchronized (this) { + try { + if (!isInitialized()) { + init(); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return new IdeaLogger(org.apache.log4j.Logger.getLogger(name)); + } + } + + private void init() { + try { + /* + //debug code. Don't delete. + ClassLoader classLoader = Logger.class.getClassLoader(); + if (!(classLoader.getClass().getName().startsWith("com.intellij"))) { + System.err.println("Logger shouldn't be used outside the PluginManager"); + Thread.dumpStack(); + } + */ + + System.setProperty("log4j.defaultInitOverride", "true"); + String fileName = PathManager.getBinPath() + File.separator + "log.xml"; + File logXmlFile = new File(fileName); + if (!logXmlFile.exists()) { + throw new RuntimeException("log.xml file does not exist! Path: [" + fileName + "]"); + } + String text = new String(FileUtil.loadFileText(logXmlFile)); + text = StringUtil.replace(text, SYSTEM_MACRO, StringUtil.replace(PathManager.getSystemPath(), "\\", "\\\\")); + text = StringUtil.replace(text, APPLICATION_MACRO, StringUtil.replace(PathManager.getHomePath(), "\\", "\\\\")); + text = StringUtil.replace(text, LOGDIR_MACRO, StringUtil.replace(LOG_DIR, "\\", "\\\\")); + + if ("true".equals(System.getProperty("idea.test.test_mode"))) { + text = commentTestModeLines(text); + } + + File file = new File(new File(PathManager.getSystemPath()), LOG_DIR); + file.mkdirs(); + + DOMConfigurator domConfigurator = new DOMConfigurator(); + try { + domConfigurator.doConfigure(new StringReader(text), LogManager.getLoggerRepository()); + } + catch (ClassCastException e) { + // shit :-E + System.out.println("log.xml content:\n" + text); + throw e; + } + myInitialized = true; + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private boolean isInitialized() { + return myInitialized; + } + + private static String commentTestModeLines(String text) { + String result = text; + int index = text.indexOf(COMMENT_LINE_FOR_TEST_MODE_MACRO); + if (index != -1) { + String str1 = result.substring(0, index); + String str2 = result.substring(index); + int firstLineChar = Math.max(str1.lastIndexOf('\n'), str1.lastIndexOf('\r')); + int lastLineChar = str2.indexOf('\n'); + int lastLineChar2 = str2.indexOf('\r'); + if (lastLineChar == -1) { + lastLineChar = lastLineChar2; + } + else if (lastLineChar2 != -1) { + lastLineChar = Math.min(lastLineChar, lastLineChar2); + } + if (firstLineChar != -1) { + str1 = str1.substring(0, firstLineChar); + } + if (lastLineChar != -1) { + str2 = str2.substring(lastLineChar); + } + result = commentTestModeLines(str1) + commentTestModeLines(str2); + } + return result; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/SocketLock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/SocketLock.java new file mode 100644 index 00000000000..65853a8ece8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/idea/SocketLock.java @@ -0,0 +1,169 @@ +package com.intellij.idea; + +import com.intellij.diagnostic.ReportMessages; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author mike + */ +public class SocketLock { + private static final Logger LOG = Logger.getInstance("#com.intellij.idea.SocketLock"); + private static final int SOCKET_NUMBER_START = 6942; + private static final int SOCKET_NUMBER_END = SOCKET_NUMBER_START + 50; + + private ServerSocket mySocket; + private List myLockedPaths = new ArrayList(); + private boolean myIsDialogShown = false; + + public SocketLock() { + } + + public synchronized void dispose() { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: destroyProcess()"); + } + try { + mySocket.close(); + mySocket = null; + } + catch (IOException e) { + LOG.debug(e); + } + } + + public synchronized boolean lock(String path) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: lock(path='" + path + "')"); + } + + acquireSocket(); + if (mySocket == null) { + if (!myIsDialogShown) { + JOptionPane.showMessageDialog( + JOptionPane.getRootFrame(), + "IDEA was unable to create a local connection in order to check whether\n" + + "other instance of IDEA is currently running on the same machine.\n" + + "Running multiple instances of IDEA on the same machine may cause unpredictable\n" + + "results because of sharing system folders.\n" + + "Please troubleshoot your TCP/IP configuration and/or local firewall settings.\n" + + ReportMessages.getReportAddress() + "\n" + + "and attach the " + PathManager.getSystemPath() + "/log/idea.log file".replace('/', File.separatorChar), + "Warning", + JOptionPane.WARNING_MESSAGE + ); + myIsDialogShown = true; + } + return true; + } + + for (int i = SOCKET_NUMBER_START; i < SOCKET_NUMBER_END; i++) { + if (i == mySocket.getLocalPort()) continue; + List lockedList = readLockedList(i); + if (lockedList.contains(path)) return false; + } + + myLockedPaths.add(path); + + return true; + } + + public synchronized void unlock(String path) { + myLockedPaths.remove(path); + } + + private List readLockedList(int i) { + List result = new ArrayList(); + + try { + try { + ServerSocket serverSocket = new ServerSocket(i); + serverSocket.close(); + return result; + } + catch (IOException e) { + } + + Socket socket = new Socket("localhost", i); + DataInputStream in = new DataInputStream(socket.getInputStream()); + + while (true) { + try { + result.add(in.readUTF()); + } + catch (IOException e) { + break; + } + } + + in.close(); + } + catch (IOException e) { + LOG.debug(e); + } + + return result; + } + + private void acquireSocket() { + if (mySocket != null) return; + + for (int i = SOCKET_NUMBER_START; i < SOCKET_NUMBER_END; i++) { + try { + mySocket = new ServerSocket(i); + break; + } + catch (IOException e) { + LOG.info(e); + continue; + } + } + + new Thread(new MyRunnable(), "Lock thread").start(); + + return; + } + + private synchronized void writeLockedPaths(Socket socket) { + try { + DataOutputStream out = new DataOutputStream(socket.getOutputStream()); + for (Iterator iterator = myLockedPaths.iterator(); iterator.hasNext();) { + String path = (String)iterator.next(); + out.writeUTF(path); + } + out.close(); + } + catch (IOException e) { + LOG.debug(e); + } + } + + private class MyRunnable implements Runnable { + public void run() { + try { + while (true) { + try { + final Socket socket = mySocket.accept(); + writeLockedPaths(socket); + } + catch (IOException e) { + LOG.debug(e); + } + } + } + catch (Throwable e) { + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Edge.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Edge.java new file mode 100644 index 00000000000..3d9847fe67b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Edge.java @@ -0,0 +1,15 @@ +package com.intellij.internal.diGraph; + + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Mar 25, 2003 + * Time: 3:48:44 PM + * To change this template use Options | File Templates. + */ + +public interface Edge { + NODE_TYPE beg(); + NODE_TYPE end(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Node.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Node.java new file mode 100644 index 00000000000..e259616663a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/Node.java @@ -0,0 +1,18 @@ +package com.intellij.internal.diGraph; + +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 19:39:49 + * To change this template use Options | File Templates. + */ +public interface Node { + Iterator inIterator(); + Iterator outIterator(); + + int inDeg(); + int outDeg(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/GlobalAnalyzer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/GlobalAnalyzer.java new file mode 100644 index 00000000000..96db79ee123 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/GlobalAnalyzer.java @@ -0,0 +1,92 @@ +package com.intellij.internal.diGraph.analyzer; + +import com.intellij.openapi.util.Pair; + +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 20:23:16 + * To change this template use Options | File Templates. + */ +public class GlobalAnalyzer { + + private static boolean stepOneEnd(MarkedNode currNode, LinkedList worklist, OneEndFunctor functor) { + boolean result = false; + + for (Iterator i = currNode.outIterator(); i.hasNext();) { + MarkedEdge currEdge = (MarkedEdge)i.next(); + MarkedNode nextNode = (MarkedNode)currEdge.end(); + Mark theMark = functor.compute(currNode.getMark(), currEdge.getMark(), nextNode.getMark()); + if (!theMark.coincidesWith(nextNode.getMark())) { + result = true; + nextNode.setMark(theMark); + worklist.addFirst(nextNode); + } + } + + return result; + } + + private static boolean stepTwoEnds(final MarkedNode currNode, final LinkedList worklist, final TwoEndsFunctor functor) { + boolean result = false; + + for (Iterator i = currNode.outIterator(); i.hasNext();) { + final MarkedEdge currEdge = (MarkedEdge)i.next(); + final MarkedNode nextNode = (MarkedNode)currEdge.end(); + final Pair markPair = functor.compute(currNode.getMark(), currEdge.getMark(), nextNode.getMark()); + + final Mark leftMark = markPair.getFirst(); + final Mark rightMark = markPair.getSecond(); + + if (!leftMark.coincidesWith(currNode.getMark())) { + result = true; + currNode.setMark(leftMark); + worklist.addFirst(currNode); + } + + if (!rightMark.coincidesWith(nextNode.getMark())) { + result = true; + nextNode.setMark(rightMark); + worklist.addFirst(nextNode); + } + } + + return result; + } + + public static boolean doOneEnd(final LinkedList init, final OneEndFunctor functor) { + boolean result = false; + + final LinkedList worklist = new LinkedList(); + + for (Iterator i = init.iterator(); i.hasNext();) { + result = stepOneEnd(i.next(), worklist, functor) || result; + } + + while (worklist.size() > 0) { + result = stepOneEnd(worklist.removeFirst(), worklist, functor) || result; + } + + return result; + } + + public static boolean doTwoEnds(final LinkedList init, final TwoEndsFunctor functor) { + boolean result = false; + + final LinkedList worklist = new LinkedList(); + + for (Iterator i = init.iterator(); i.hasNext();) { + result = stepTwoEnds(i.next(), worklist, functor) || result; + } + + while (worklist.size() > 0) { + result = stepTwoEnds(worklist.removeFirst(), worklist, functor) || result; + } + + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/Mark.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/Mark.java new file mode 100644 index 00000000000..52dc262840e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/Mark.java @@ -0,0 +1,14 @@ +package com.intellij.internal.diGraph.analyzer; + +import com.intellij.internal.typeDeducer.Type; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 10.06.2003 + * Time: 23:40:39 + * To change this template use Options | File Templates. + */ +public interface Mark { + boolean coincidesWith(Mark x); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedEdge.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedEdge.java new file mode 100644 index 00000000000..0b70c6ef6b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedEdge.java @@ -0,0 +1,15 @@ +package com.intellij.internal.diGraph.analyzer; + +import com.intellij.internal.diGraph.Edge; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 22:29:04 + * To change this template use Options | File Templates. + */ +public interface MarkedEdge extends Edge { + Mark getMark(); + void setMark(Mark x); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedNode.java new file mode 100644 index 00000000000..091519f07bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/MarkedNode.java @@ -0,0 +1,15 @@ +package com.intellij.internal.diGraph.analyzer; + +import com.intellij.internal.diGraph.Node; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 22:25:27 + * To change this template use Options | File Templates. + */ +public interface MarkedNode extends Node { + Mark getMark(); + void setMark(Mark x); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/OneEndFunctor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/OneEndFunctor.java new file mode 100644 index 00000000000..e3ec4c7bb09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/OneEndFunctor.java @@ -0,0 +1,12 @@ +package com.intellij.internal.diGraph.analyzer; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 22:32:42 + * To change this template use Options | File Templates. + */ +public interface OneEndFunctor { + Mark compute(Mark from, Mark edge, Mark to); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/TwoEndsFunctor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/TwoEndsFunctor.java new file mode 100644 index 00000000000..75d2d66724d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/analyzer/TwoEndsFunctor.java @@ -0,0 +1,14 @@ +package com.intellij.internal.diGraph.analyzer; + +import com.intellij.openapi.util.Pair; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 18.12.2003 + * Time: 19:00:35 + * To change this template use Options | File Templates. + */ +public interface TwoEndsFunctor { + Pair compute(Mark from, Mark edge, Mark to); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/EdgeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/EdgeImpl.java new file mode 100644 index 00000000000..c1544fc8269 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/EdgeImpl.java @@ -0,0 +1,45 @@ +package com.intellij.internal.diGraph.impl; + +import com.intellij.internal.diGraph.Edge; +import com.intellij.internal.diGraph.Node; +import com.intellij.internal.diGraph.analyzer.MarkedEdge; +import com.intellij.internal.diGraph.analyzer.Mark; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 23:38:12 + * To change this template use Options | File Templates. + */ +public class EdgeImpl implements MarkedEdge { + NodeImpl myBeg; + NodeImpl myEnd; + + public EdgeImpl() { + } + + public EdgeImpl(NodeImpl from, NodeImpl to) { + myBeg = from; + myEnd = to; + + from.myOut.add(this); + to.myIn.add(this); + } + + public Node beg() { + return myBeg; + } + + public Node end() { + return myEnd; + } + + public Mark getMark(){ + return null; + } + + public void setMark(Mark x){ + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/NodeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/NodeImpl.java new file mode 100644 index 00000000000..f9b3f6fa2ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/diGraph/impl/NodeImpl.java @@ -0,0 +1,74 @@ +package com.intellij.internal.diGraph.impl; + +import com.intellij.internal.diGraph.Node; +import com.intellij.internal.diGraph.Edge; +import com.intellij.internal.diGraph.analyzer.MarkedNode; +import com.intellij.internal.diGraph.analyzer.Mark; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.HashSet; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 21.06.2003 + * Time: 23:35:24 + * To change this template use Options | File Templates. + */ +public class NodeImpl implements MarkedNode { + LinkedList myIn; + LinkedList myOut; + + public NodeImpl() { + myIn = new LinkedList(); + myOut = new LinkedList(); + } + + public NodeImpl(EdgeImpl[] in, EdgeImpl[] out) { + myIn = new LinkedList(); + myOut = new LinkedList(); + + for (int i = 0; i < (in == null ? 0 : in.length); i++) { + myIn.add(in[i]); + in[i].myEnd = this; + } + + for (int i = 0; i < (out == null ? 0 : out.length); i++) { + myOut.add(out[i]); + out[i].myBeg = this; + } + } + + public NodeImpl(LinkedList in, LinkedList out) { + myIn = in == null ? new LinkedList() : in; + myOut = out == null ? new LinkedList() : out; + + for (Iterator i = myIn.iterator(); i.hasNext();) ((EdgeImpl) i.next()).myEnd = this; + for (Iterator i = myOut.iterator(); i.hasNext();) ((EdgeImpl) i.next()).myBeg = this; + } + + public Iterator inIterator() { + return myIn.iterator(); + } + + public Iterator outIterator() { + return myOut.iterator(); + } + + public int inDeg() { + return myIn.size(); + } + + public int outDeg() { + return myOut.size(); + } + + public Mark getMark() { + return null; + } + + public void setMark(Mark x) { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/DecodeBytesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/DecodeBytesAction.java new file mode 100644 index 00000000000..5c38c35c02e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/DecodeBytesAction.java @@ -0,0 +1,10 @@ +package com.intellij.internal.encodings; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class DecodeBytesAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + new EncodingViewer().show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/EncodingViewer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/EncodingViewer.java new file mode 100644 index 00000000000..0ed113b7887 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/encodings/EncodingViewer.java @@ -0,0 +1,89 @@ +package com.intellij.internal.encodings; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Arrays; + +public class EncodingViewer extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.internal.encodings.EncodingViewer"); + private JPanel myPanel; + private JTextField myText; + private JComboBox myEncoding; + private JButton myLoadFile; + private byte[] myBytes; + + public EncodingViewer() { + super(false); + initEncodings(); + myLoadFile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myPanel, descriptor); + if (files.length != 0) { + loadFrom(files[0]); + } + } + }); + init(); + } + + protected String getDimensionServiceKey() { + return "EncodingViewer"; + } + + private void loadFrom(VirtualFile virtualFile) { + try { + myBytes = virtualFile.physicalContentsToByteArray(); + } catch (IOException e) { + LOG.error(e); + return; + } + refreshText(); + } + + private void refreshText() { + String selectedCharset = getSelectedCharset(); + if (myBytes == null || selectedCharset == null) return; + try { + myText.setText(new String(myBytes, selectedCharset)); + } catch (UnsupportedEncodingException e) { + LOG.error(e); + } + } + + private String getSelectedCharset() { + return ((Charset) myEncoding.getSelectedItem()).name(); + } + + private void initEncodings() { + Charset[] availableCharsets = CharsetToolkit.getAvailableCharsets(); + myEncoding.setModel(new DefaultComboBoxModel(availableCharsets)); + int defaultIndex = Arrays.asList(availableCharsets).indexOf(CharsetToolkit.getDefaultSystemCharset()); + myEncoding.setSelectedIndex(defaultIndex); + myEncoding.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() != ItemEvent.SELECTED) return; + refreshText(); + } + }); + } + + protected JComponent createCenterPanel() { + return myPanel; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/PsiViewerDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/PsiViewerDialog.java new file mode 100644 index 00000000000..c74d7e1fc8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/PsiViewerDialog.java @@ -0,0 +1,265 @@ +/** + * class PsiViewerDialog + * created Aug 25, 2001 + * @author Jeka + */ +package com.intellij.internal.psiView; + +import com.intellij.ide.highlighter.custom.impl.CustomFileType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiManager; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +public class PsiViewerDialog extends DialogWrapper { + private Project myProject; + + private Tree myTree; + private ViewerTreeBuilder myTreeBuilder; + + private Editor myEditor; + private String myLastParsedText = null; + + private JRadioButton myRbMethod; + private JRadioButton myRbCodeBlock; + private JRadioButton myRbExpression; + private JRadioButton[] myFileTypeButtons; + private FileType[] myFileTypes; + + private JCheckBox myShowWhiteSpacesBox; + + private JPanel myStructureTreePanel; + private JPanel myTextPanel; + private JPanel myPanel; + private JPanel myChoicesPanel; + + public PsiViewerDialog(Project project,boolean modal) { + super(project, true); + setTitle("PSI Viewer"); + myProject = project; + myTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode())); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + myTree.updateUI(); + ToolTipManager.sharedInstance().registerComponent(myTree); + TreeUtil.installActions(myTree); + new TreeSpeedSearch(myTree); + myTreeBuilder = new ViewerTreeBuilder(project, myTree); + + myTree.addTreeSelectionListener(new MyTreeSelectionListener()); + + JScrollPane scrollPane = new JScrollPane(myTree); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(scrollPane, BorderLayout.CENTER); + myStructureTreePanel.setLayout(new BorderLayout()); + myStructureTreePanel.add(panel, BorderLayout.CENTER); + + setModal(modal); + setOKButtonText("&Build PSI Tree"); + init(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.internal.psiView.PsiViewerDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return myEditor.getContentComponent(); + } + + protected void init() { + EditorFactory editorFactory = EditorFactory.getInstance(); + Document document = editorFactory.createDocument(""); + myEditor = editorFactory.createEditor(document, myProject); + myEditor.getSettings().setFoldingOutlineShown(false); + + FileType[] fileTypes = FileTypeManager.getInstance().getRegisteredFileTypes(); + List customFileTypes = new ArrayList(); + + for (int i = 0; i < fileTypes.length; i++) { + FileType fileType = fileTypes[i]; + + if (fileType != StdFileTypes.GUI_DESIGNER_FORM && + fileType != StdFileTypes.IDEA_MODULE && + fileType != StdFileTypes.IDEA_PROJECT && + fileType != StdFileTypes.IDEA_WORKSPACE && + fileType != StdFileTypes.ARCHIVE && + fileType != StdFileTypes.UNKNOWN && + fileType != StdFileTypes.PLAIN_TEXT && + !(fileType instanceof CustomFileType)&& + !fileType.isBinary() && + !fileType.isReadOnly() + ) { + customFileTypes.add(fileType); + } + } + + myFileTypes = customFileTypes.toArray(new FileType[customFileTypes.size()]); + myFileTypeButtons = new JRadioButton[myFileTypes.length]; + + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbMethod); + bg.add(myRbCodeBlock); + bg.add(myRbExpression); + + Box choicesBox = Box.createHorizontalBox(); + + for (int i = 0; i < myFileTypes.length; i++) { + FileType fileType = myFileTypes[i]; + JRadioButton button = new JRadioButton(fileType.getName()+" file"); + bg.add(button); + choicesBox.add(button); + myFileTypeButtons[i] = button; + } + + myRbExpression.setSelected(true); + + myChoicesPanel.setLayout(new BorderLayout()); + myChoicesPanel.add(choicesBox, BorderLayout.CENTER); + + final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure(); + myShowWhiteSpacesBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + treeStructure.setShowWhiteSpaces(myShowWhiteSpacesBox.isSelected()); + myTreeBuilder.updateFromRoot(); + } + }); + myTextPanel.setLayout(new BorderLayout()); + myTextPanel.add(myEditor.getComponent(), BorderLayout.CENTER); + + super.init(); + } + + protected JComponent createCenterPanel() { + return myPanel; + } + + protected void doOKAction() { + final String text = myEditor.getDocument().getText(); + if ("".equals(text.trim())) { + return; + } + myLastParsedText = text; + final PsiManager psiManager = PsiManager.getInstance(myProject); + PsiElement rootElement = null; + try { + PsiElementFactory factory = psiManager.getElementFactory(); + if (myRbMethod.isSelected()) { + rootElement = factory.createMethodFromText(text, null); + } + else if (myRbCodeBlock.isSelected()) { + rootElement = factory.createCodeBlockFromText(text, null); + } + else if (myRbExpression.isSelected()) { + rootElement = factory.createExpressionFromText(text, null); + } + else { + for (int i = 0; i < myFileTypeButtons.length; i++) { + JRadioButton fileTypeButton = myFileTypeButtons[i]; + + if (fileTypeButton.isSelected()) { + rootElement = factory.createFileFromText("Dummy."+myFileTypes[i].getDefaultExtension(), text); + } + } + } + } + catch (IncorrectOperationException e1) { + rootElement = null; + Messages.showMessageDialog( + myProject, + e1.getMessage(), + "Error", + Messages.getErrorIcon() + ); + } + ViewerTreeStructure structure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure(); + structure.setRootPsiElement(rootElement); + + myTreeBuilder.updateFromRoot(); + myTree.setRootVisible(true); + myTree.expandRow(0); + myTree.setRootVisible(false); + } + + private class MyTreeSelectionListener implements TreeSelectionListener { + private TextAttributes myAttributes; + private RangeHighlighter myHighlighter; + + public MyTreeSelectionListener() { + myAttributes = new TextAttributes(); + myAttributes.setBackgroundColor(new Color(0, 0, 128)); + myAttributes.setForegroundColor(Color.white); + } + + public void valueChanged(TreeSelectionEvent e) { + if (!myEditor.getDocument().getText().equals(myLastParsedText)) return; + TreePath path = myTree.getSelectionPath(); + if (path == null){ + clearSelection(); + } + else{ + clearSelection(); + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject(); + Object elementObject = descriptor.getElement(); + if (elementObject instanceof PsiElement) { + PsiElement element = (PsiElement)elementObject; + TextRange range = element.getTextRange(); + int start = range.getStartOffset(); + int end = range.getEndOffset(); + final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure(); + PsiElement rootPsiElement = treeStructure.getRootPsiElement(); + if (rootPsiElement != null) { + int baseOffset = rootPsiElement.getTextRange().getStartOffset(); + start -= baseOffset; + end -= baseOffset; + } + myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.CARET_ROW + 1, myAttributes, HighlighterTargetArea.EXACT_RANGE); + } + } + } + + private void clearSelection() { + if (myHighlighter != null) { + myEditor.getMarkupModel().removeHighlighter(myHighlighter); + myHighlighter = null; + } + } + } + + protected void dispose() { + super.dispose(); + + EditorFactory.getInstance().releaseEditor(myEditor); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerAction.java new file mode 100644 index 00000000000..2250b4a55cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerAction.java @@ -0,0 +1,19 @@ +/** + * class ViewerAction + * created Aug 27, 2001 + * @author Jeka + */ +package com.intellij.internal.psiView; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; + +public class ViewerAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + PsiViewerDialog dialog = new PsiViewerDialog(project,false); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerNodeDescriptor.java new file mode 100644 index 00000000000..9aab84ab38b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerNodeDescriptor.java @@ -0,0 +1,28 @@ +/** + * class ViewerNodeDescriptor + * created Aug 25, 2001 + * @author Jeka + */ +package com.intellij.internal.psiView; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +public class ViewerNodeDescriptor extends NodeDescriptor { + private PsiElement myElement; + + public ViewerNodeDescriptor(Project project, PsiElement element, NodeDescriptor parentDescriptor) { + super(project, parentDescriptor); + myElement = element; + myName = myElement.toString(); + } + + public boolean update() { + return false; + } + + public Object getElement() { + return myElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeBuilder.java new file mode 100644 index 00000000000..607b5d736da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeBuilder.java @@ -0,0 +1,34 @@ +/** + * class ViewerTreeBuilder + * created Aug 25, 2001 + * @author Jeka + */ +package com.intellij.internal.psiView; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.IndexComparator; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; + +public class ViewerTreeBuilder extends AbstractTreeBuilder { + public ViewerTreeBuilder(Project project, JTree tree) { + super(tree, (DefaultTreeModel)tree.getModel(), new ViewerTreeStructure(project), IndexComparator.INSTANCE); + initRootNode(); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return false; + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + Object element = nodeDescriptor.getElement(); + Object rootElement = myTreeStructure.getRootElement(); + if (rootElement.equals(element)) return true; + NodeDescriptor parent = nodeDescriptor.getParentDescriptor(); + if (parent != null && rootElement.equals(parent.getElement())) return true; + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeStructure.java new file mode 100644 index 00000000000..8a2b4103da5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/internal/psiView/ViewerTreeStructure.java @@ -0,0 +1,111 @@ +/** + * class ViewerTreeStructure + * created Aug 25, 2001 + * @author Jeka + */ +package com.intellij.internal.psiView; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.List; + +public class ViewerTreeStructure extends AbstractTreeStructure { + + private boolean myShowWhiteSpaces = true; + + private Project myProject; + private PsiElement myRootPsiElement = null; + private Object myRootElement = new Object(); + + public ViewerTreeStructure(Project project) { + myProject = project; + } + + public void setRootPsiElement(PsiElement rootPsiElement) { + myRootPsiElement = rootPsiElement; + } + + public PsiElement getRootPsiElement() { + return myRootPsiElement; + } + + public Object getRootElement() { + return myRootElement; + } + + public Object[] getChildElements(final Object element) { + if (myRootElement == element) { + if (myRootPsiElement == null) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + return myRootPsiElement instanceof PsiFile ? ((PsiFile)myRootPsiElement).getPsiRoots() : new Object[]{myRootPsiElement}; + } + final Object[][] children = new Object[1][]; + children[0] = ArrayUtil.EMPTY_OBJECT_ARRAY; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + PsiElement[] elementChildren = ((PsiElement)element).getChildren(); + if (elementChildren.length > 0) { + List childrenList = new ArrayList(elementChildren.length); + for (int idx = 0; idx < elementChildren.length; idx++) { + PsiElement psiElement = elementChildren[idx]; + if (!myShowWhiteSpaces && psiElement instanceof PsiWhiteSpace) { + continue; + } + childrenList.add(psiElement); + } + elementChildren = childrenList.toArray(new PsiElement[childrenList.size()]); + } + children[0] = elementChildren; + } + }); + return children[0]; + } + + public Object getParentElement(Object element) { + return null; + //if (element == myRootElement) { + // return null; + //} + //if (element == myRootPsiElement) { + // return myRootElement; + //} + //PsiElement parent = ((PsiElement)element).getParent(); + //return parent; + } + + public void commit() { + } + + public boolean hasSomethingToCommit() { + return false; + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + if (element == myRootElement) { + return new NodeDescriptor(myProject, null) { + public boolean update() { + return false; + } + public Object getElement() { + return myRootElement; + } + }; + } + return new ViewerNodeDescriptor(myProject, (PsiElement)element, parentDescriptor); + } + + public boolean isShowWhiteSpaces() { + return myShowWhiteSpaces; + } + + public void setShowWhiteSpaces(boolean showWhiteSpaces) { + myShowWhiteSpaces = showWhiteSpaces; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/AddEditRemovePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/AddEditRemovePanel.java new file mode 100644 index 00000000000..1f4a82e5887 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/AddEditRemovePanel.java @@ -0,0 +1,183 @@ +package com.intellij.j2ee.extResources; + +import com.intellij.ui.PanelWithButtons; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.border.EtchedBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +/** + * @author mike + */ +public abstract class AddEditRemovePanel extends PanelWithButtons { + JPanel myPanel; + private JTable myTable; + private JButton myAddButton; + private JButton myEditButton; + private JButton myRemoveButton; + private TableModel myModel; + private List myData; + private AbstractTableModel myTableModel; + + public AddEditRemovePanel(String labelText, TableModel model, List data) { + myModel = model; + myData = data; + + initPanel(); + updateButtons(); + + setBorder(BorderFactory.createTitledBorder(new EtchedBorder(),labelText)); + } + + protected String getLabelText(){ + return null; + } + + protected JComponent createMainComponent(){ + myTableModel = new AbstractTableModel() { + public int getRowCount(){ + return myData != null ? myData.size() : 0; + } + + public int getColumnCount(){ + return myModel.getColumnCount(); + } + + public String getColumnName(int column){ + return myModel.getColumnName(column); + } + + public Class getColumnClass(int columnIndex){ + return String.class; + } + + public Object getValueAt(int rowIndex, int columnIndex){ + return myModel.getField(myData.get(rowIndex), columnIndex); + } + }; + + myTable = new Table(myTableModel); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e){ + if (e.getClickCount() == 2) doEdit(); + } + }); + + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e){ + updateButtons(); + } + }); + + JScrollPane scrollpane = ScrollPaneFactory.createScrollPane(myTable); + + return scrollpane; + } + + protected JButton[] createButtons(){ +// myAddPatternButton = new JButton("Add..."); + myAddButton.setMnemonic(getAddMnemonic()); + myAddButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + doAdd(); + } + } + ); + +// myEditButton = new JButton("Edit"); + myEditButton.setMnemonic(getEditMnemonic()); + myEditButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + doEdit(); + } + } + ); + +// myRemoveButton = new JButton("Remove"); + myRemoveButton.setMnemonic(getRemoveMnemonic()); + myRemoveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + doRemove(); + } + } + ); + + return new JButton[]{myAddButton, myEditButton, myRemoveButton}; + } + + protected void doAdd() { + Object o = addItem(); + if (o == null) return; + + myData.add(o); + int index = myData.size() - 1; + myTableModel.fireTableRowsInserted(index, index); + myTable.setRowSelectionInterval(index, index); + } + + protected abstract Object addItem(); + protected abstract boolean removeItem(Object o); + protected abstract Object editItem(Object o); + + protected abstract char getRemoveMnemonic(); + protected abstract char getEditMnemonic(); + protected abstract char getAddMnemonic(); + + protected void doEdit() { + int selected = myTable.getSelectedRow(); + Object o = editItem(myData.get(selected)); + if (o != null) myData.set(selected, o); + + myTableModel.fireTableRowsUpdated(selected, selected); + } + + protected void doRemove() { + int selected = myTable.getSelectedRow(); + if (!removeItem(myData.get(selected))) return; + + + myData.remove(selected); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsDeleted(selected, selected); + if (selected >= myData.size()) { + selected--; + } + if (selected >= 0) { + myTable.setRowSelectionInterval(selected, selected); + } + } + + public void setData(java.util.List data) { + myData = data; + myTableModel.fireTableDataChanged(); + } + + public void setRenderer(int index, TableCellRenderer renderer) { + myTable.getColumn(myModel.getColumnName(index)).setCellRenderer(renderer); + } + + private void updateButtons() { + myEditButton.setEnabled(myTable.getSelectedRowCount() == 1); + myRemoveButton.setEnabled(myTable.getSelectedRowCount() == 1); + } + + public static interface TableModel { + int getColumnCount(); + String getColumnName(int columnIndex); + Object getField(Object o, int columnIndex); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/EditLocationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/EditLocationDialog.java new file mode 100644 index 00000000000..959f0382583 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/EditLocationDialog.java @@ -0,0 +1,105 @@ +package com.intellij.j2ee.extResources; + +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +public class EditLocationDialog extends DialogWrapper { + + private JTextField myTfUrl; + private JTextField myTfPath; + private FixedSizeButton myBtnBrowseLocalPath; + private Project myProject; + private boolean myShowPath; + + public EditLocationDialog(Project project, boolean showPath) { + super(project, true); + myProject = project; + myShowPath = showPath; + init(); + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + panel.add( + new JLabel("URI:"), + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 3, 5), 0, 0) + ); + panel.add( + myTfUrl, + new GridBagConstraints(0, 1, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0) + ); + + myTfUrl.setPreferredSize(new Dimension(350, myTfUrl.getPreferredSize().height)); + + if (myShowPath) { + panel.add( + new JLabel("Path:"), + new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 3, 5), 0, 0) + ); + panel.add( + myTfPath, + new GridBagConstraints(0, 3, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 10, 0), 0, 0) + ); + panel.add( + myBtnBrowseLocalPath, + new GridBagConstraints(1, 3, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 10, 5), 0, 0) + ); + + // + TextFieldWithBrowseButton.MyDoClickAction.addTo(myBtnBrowseLocalPath, myTfPath); + myBtnBrowseLocalPath.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent ignored) { + FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, false, false, false, false); + VirtualFile[] files = FileChooser.chooseFiles(myProject, descriptor); + if (files.length != 0) { + myTfPath.setText(files[0].getPath().replace('/', File.separatorChar)); + } + } + } + ); + } + + // + + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myTfUrl; + } + + public ExternalResourceConfigurable.Pair getPair() { + String path = myTfPath.getText().trim(); + String url = myTfUrl.getText().trim(); + return new ExternalResourceConfigurable.Pair(url, path); + } + + protected void init() { + setTitle("External Resource"); + myTfUrl = new JTextField(); + myTfPath = new JTextField(); + myBtnBrowseLocalPath = new FixedSizeButton(myTfPath); + super.init(); + } + + /** + * Initializes editor with the passed data. + */ + public void init(ExternalResourceConfigurable.Pair pair) { + myTfUrl.setText(pair.myString1); + myTfPath.setText(pair.myString2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceConfigurable.java new file mode 100644 index 00000000000..4132685aefe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceConfigurable.java @@ -0,0 +1,254 @@ +package com.intellij.j2ee.extResources; + +import com.intellij.j2ee.openapi.ex.ExternalResourceManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.LocalFileSystem; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; + +public class ExternalResourceConfigurable extends BaseConfigurable implements ApplicationComponent { + private JPanel myPanel; + private ArrayList myPairs; + private ArrayList myIgnoredUrls; + private AddEditRemovePanel myExtPanel; + private AddEditRemovePanel myIgnorePanel; + + public ExternalResourceConfigurable() { + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public String getDisplayName() { + return "Resources"; + } + + public JComponent createComponent() { + myPanel = new JPanel(new GridBagLayout()); + + myExtPanel = new AddEditRemovePanel("Configure External Resources:", new ExtUrlsTableModel(), myPairs) { + protected Object addItem() { + return addExtLocation(); + } + + protected boolean removeItem(Object o) { + setModified(true); + return true; + } + + protected Object editItem(Object o) { + return editExtLocation(o); + } + + protected char getAddMnemonic(){ + return 'A'; + } + + protected char getEditMnemonic(){ + return 'E'; + } + + protected char getRemoveMnemonic(){ + return 'R'; + } + }; + + myExtPanel.setRenderer(1, new PathRenderer()); + + myIgnorePanel = new AddEditRemovePanel("Configure Ignored Resources:", new IgnoredUrlsModel(), myIgnoredUrls) { + protected Object addItem() { + return addIgnoreLocation(); + } + + protected boolean removeItem(Object o) { + setModified(true); + return true; + } + + protected Object editItem(Object o) { + return editIgnoreLocation(o); + } + + protected char getAddMnemonic(){ + return 'd'; + } + + protected char getEditMnemonic(){ + return 't'; + } + + protected char getRemoveMnemonic(){ + return 'm'; + } + }; + + myPanel.add(myExtPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(5, 2, 4, 2), 0, 0)); + myPanel.add(myIgnorePanel, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(5, 2, 4, 2), 0, 0)); + + return myPanel; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableExternalResources.png"); + } + + public void apply() { + ExternalResourceManagerEx manager = ExternalResourceManagerEx.getInstanceEx(); + + manager.clearAllResources(); + for (int i = 0; i < myPairs.size(); i++) { + Pair pair = (Pair)myPairs.get(i); + manager.addResource(pair.myString1, pair.myString2.replace('\\', '/')); + } + + for (int i = 0; i < myIgnoredUrls.size(); i++) { + String url = (String)myIgnoredUrls.get(i); + manager.addIgnoredResource(url); + } + } + + public void reset() { + myPairs = new ArrayList(); + ExternalResourceManagerEx manager = ExternalResourceManagerEx.getInstanceEx(); + + String[] urls = manager.getAvailableUrls(); + for (int i = 0; i < urls.length; i++) { + String loc = manager.getResourceLocation(urls[i]); + myPairs.add(new Pair(urls[i], loc)); + } + + Collections.sort(myPairs); + + myIgnoredUrls = new ArrayList(); + final String[] ignoredResources = manager.getIgnoredResources(); + for (int i = 0; i < ignoredResources.length; i++) { + String ignoredResource = ignoredResources[i]; + myIgnoredUrls.add(ignoredResource); + } + + Collections.sort(myIgnoredUrls); + + myExtPanel.setData(myPairs); + myIgnorePanel.setData(myIgnoredUrls); + + setModified(false); + } + + public void disposeUIResources() { + myPanel = null; + } + + public String getHelpTopic() { + return "preferences.externalResources"; + } + + private Object addExtLocation() { + EditLocationDialog dialog = new EditLocationDialog(null, true); + dialog.show(); + if (!dialog.isOK()) return null; + setModified(true); + return dialog.getPair(); + } + + private Object editExtLocation(Object o) { + EditLocationDialog dialog = new EditLocationDialog(null, true); + dialog.init((Pair)o); + dialog.show(); + if (!dialog.isOK()) return null; + setModified(true); + return dialog.getPair(); + } + + private Object addIgnoreLocation() { + EditLocationDialog dialog = new EditLocationDialog(null, false); + dialog.show(); + if (!dialog.isOK()) return null; + setModified(true); + return dialog.getPair().myString1; + } + + private Object editIgnoreLocation(Object o) { + EditLocationDialog dialog = new EditLocationDialog(null, false); + dialog.init(new Pair(o.toString(), o.toString())); + dialog.show(); + if (!dialog.isOK()) return null; + setModified(true); + return dialog.getPair().myString1; + } + + + public String getComponentName() { + return "ExternalResourceConfigurable"; + } + + private class PathRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + final String loc = value.toString().replace('\\', '/'); + setForeground(LocalFileSystem.getInstance().findFileByPath(loc) != null ? Color.black : new Color(210, 0, 0)); + return this; + } + } + + public static class Pair implements Comparable { + String myString1; + String myString2; + + public Pair(String string1, String string2) { + myString1 = string1; + myString2 = string2; + } + + public int compareTo(Object o) { + return myString1.compareTo(((Pair)o).myString1); + } + } + + private class IgnoredUrlsModel implements AddEditRemovePanel.TableModel { + private final String[] myNames = {"URI"}; + + public int getColumnCount() { + return myNames.length; + } + + public Object getField(Object o, int columnIndex) { + return o; + } + + public String getColumnName(int column) { + return myNames[column]; + } + } + + private class ExtUrlsTableModel implements AddEditRemovePanel.TableModel { + final String[] myNames = {"URI", "Location"}; + + public int getColumnCount() { + return myNames.length; + } + + public Object getField(Object o, int columnIndex) { + final Pair pair = (Pair)o; + switch (columnIndex) { + case 0: + return pair.myString1; + case 1: + return pair.myString2; + } + + return ""; + } + + public String getColumnName(int column) { + return myNames[column]; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceListener.java new file mode 100644 index 00000000000..92c38ae0f58 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/extResources/ExternalResourceListener.java @@ -0,0 +1,8 @@ +package com.intellij.j2ee.extResources; + +/** + * @author mike + */ +public interface ExternalResourceListener { + void externalResourceChanged(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildInstructionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildInstructionBase.java new file mode 100644 index 00000000000..bb6773b0a80 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildInstructionBase.java @@ -0,0 +1,37 @@ +/** + * @author cdr + */ +package com.intellij.j2ee.make; + +import com.intellij.openapi.module.Module; + +public abstract class BuildInstructionBase implements BuildInstruction, Cloneable { + private final String myOutputRelativePath; + private final Module myModule; + + protected BuildInstructionBase(String outputRelativePath, Module module) { + myOutputRelativePath = outputRelativePath; + myModule = module; + } + + public String getOutputRelativePath() { + return myOutputRelativePath; + } + + public Module getModule() { + return myModule; + } + + public BuildInstructionBase clone() { + try { + return (BuildInstructionBase)super.clone(); + } + catch (CloneNotSupportedException e) { + return null; + } + } + + public boolean isExternalDependencyInstruction() { + return getOutputRelativePath().startsWith(".."); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildRecipeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildRecipeImpl.java new file mode 100644 index 00000000000..e3bd26f5e2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/BuildRecipeImpl.java @@ -0,0 +1,71 @@ +/** + * @author cdr + */ +package com.intellij.j2ee.make; + +import com.intellij.openapi.module.Module; +import com.intellij.util.Degenerator; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.List; + +public class BuildRecipeImpl implements BuildRecipe { + private final List myInstructions = new ArrayList(); + + public void addInstruction(BuildInstruction instruction) { + myInstructions.add(instruction); + } + + public boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder){ + try { + return visitInstructionsWithExceptions(visitor, reverseOrder); + } + catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } + Degenerator.unableToDegenerateMarker(); + return false; + } + } + public boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception { + for (int i = reverseOrder ? myInstructions.size()-1 : 0; + reverseOrder ? i>=0 : i < myInstructions.size(); + i += reverseOrder ? -1 : 1) { + BuildInstruction instruction = myInstructions.get(i); + if (!instruction.accept(visitor)) { + return false; + } + } + return true; + } + + public void addAll(BuildRecipe buildRecipe) { + buildRecipe.visitInstructions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws RuntimeException { + addInstruction(instruction); + return true; + } + }, false); + } + + public void addFileCopyInstruction(File file, + boolean isDirectory, Module module, + String outputRelativePath, + FileFilter fileFilter) { + if (fileFilter == null || fileFilter.accept(file)) { + addInstruction(new FileCopyInstructionImpl(file, isDirectory, module, MakeUtil.trimForwardSlashes(outputRelativePath))); + } + } + + public String toString() { + String s = "Build recipe:"; + for (int i = 0; i < myInstructions.size(); i++) { + BuildInstruction buildInstruction = myInstructions.get(i); + s += "\n" + buildInstruction + "; "; + } + return s; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/FileCopyInstructionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/FileCopyInstructionImpl.java new file mode 100644 index 00000000000..3668845f787 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/FileCopyInstructionImpl.java @@ -0,0 +1,144 @@ +package com.intellij.j2ee.make; + +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.util.io.ZipUtil; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarOutputStream; + +public class FileCopyInstructionImpl extends BuildInstructionBase implements FileCopyInstruction { + private File myFile; + private boolean myIsDirectory; + // for a directory keep the subset of changed files that need to be copied + private List myChangedSet; + + public FileCopyInstructionImpl(File source, + boolean isDirectory, + Module module, + String outputRelativePath) { + super(outputRelativePath, module); + setFile(source, isDirectory); + } + + public void addFilesToExploded(CompileContext context, + File outputDir, + Set writtenPaths, + FileFilter fileFilter) throws IOException { + if (myChangedSet == null) { + final File to = MakeUtil.canonicalRelativePath(outputDir, getOutputRelativePath()); + // todo check for recursive copying + if (!MakeUtil.checkFileExists(getFile(), context)) return; + MakeUtil.getInstance().copyFile(getFile(), to, context, writtenPaths, fileFilter); + } + else { + for (int i = 0; i < myChangedSet.size(); i++) { + FileCopyInstructionImpl singleFileCopyInstruction = myChangedSet.get(i); + singleFileCopyInstruction.addFilesToExploded(context, outputDir, writtenPaths, fileFilter); + } + } + } + + public boolean accept(BuildInstructionVisitor visitor) throws Exception { + return visitor.visitFileCopyInstruction(this); + } + + public File findFileByRelativePath(String relativePath) { + if (!relativePath.startsWith(getOutputRelativePath())) return null; + final String pathFromFile = relativePath.substring(getOutputRelativePath().length()); + if (!myIsDirectory) { + return pathFromFile.equals("") ? myFile : null; + } + final File file = MakeUtil.canonicalRelativePath(myFile, pathFromFile); + + return file.exists() ? file : null; + } + + public void addFilesToJar(CompileContext context, + File jarFile, + JarOutputStream outputStream, + BuildRecipe dependencies, + Set writtenRelativePaths, + FileFilter fileFilter) throws IOException { + final String outputRelativePath = getOutputRelativePath(); + + File file = getFile(); + if (isExternalDependencyInstruction()) { + // copy dependent file along with jar file + final File toFile = MakeUtil.canonicalRelativePath(jarFile, outputRelativePath); + MakeUtil.getInstance().copyFile(file, toFile, context, new HashSet(), fileFilter); + dependencies.addInstruction(this); + } + else { + boolean ok = ZipUtil.addFileOrDirRecursively(outputStream, jarFile, file, outputRelativePath, fileFilter, writtenRelativePaths); + if (!ok) { + MakeUtil.reportRecursiveCopying(context, file.getPath(), jarFile.getPath(), "", + "Please setup jar file location outside directory '" + file.getPath() + "'."); + } + } + } + + public String toString() { + if (myChangedSet == null) { + String s = "Copy "+getFile(); + if (getModule() != null) { + s += "(from '"+ModuleUtil.getModuleNameInReadAction(getModule())+"')"; + } + s += "->"+getOutputRelativePath(); + return s; + } + else { + String s = "Copy (Incr "+myFile+")"; + for (int i = 0; i < myChangedSet.size(); i++) { + FileCopyInstructionImpl fileCopyInstruction = myChangedSet.get(i); + s += fileCopyInstruction +", "; + } + return s; + } + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FileCopyInstruction)) return false; + + final FileCopyInstruction item = (FileCopyInstruction) o; + + if (getFile() != null ? !getFile().equals(item.getFile()) : item.getFile() != null) return false; + + return true; + } + + public int hashCode() { + return getFile() != null ? getFile().hashCode() : 0; + } + + public File getFile() { + return myFile; + } + + public boolean isDirectory() { + return myIsDirectory; + } + + public void setFile(File file, boolean isDirectory) { + myFile = file; + myIsDirectory = isDirectory; + } + + // incremental compiler integration support + // instruction implementation should only process the intersection of files it owns and files passed in this method + public void addFileToChangedSet(FileCopyInstructionImpl item) { + myChangedSet.add(item); + } + + public void clearChangedSet() { + myChangedSet = new ArrayList(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/IgnoredFileFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/IgnoredFileFilter.java new file mode 100644 index 00000000000..2461a359696 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/IgnoredFileFilter.java @@ -0,0 +1,22 @@ +/** + * @author cdr + */ +package com.intellij.j2ee.make; + +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; + +import java.io.File; +import java.io.FileFilter; + +public class IgnoredFileFilter implements FileFilter { + public boolean accept(File file) { + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + final String name = file.getName(); + return !fileTypeManager.isFileIgnored(name) + && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_PROJECT + && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_MODULE + && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_WORKSPACE + ; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/J2EEModuleBuildInstructionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/J2EEModuleBuildInstructionImpl.java new file mode 100644 index 00000000000..08f4de3579a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/J2EEModuleBuildInstructionImpl.java @@ -0,0 +1,203 @@ +package com.intellij.j2ee.make; + +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.Degenerator; +import com.intellij.util.PathUtil; +import com.intellij.util.io.ZipUtil; +import gnu.trove.THashSet; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Set; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +public class J2EEModuleBuildInstructionImpl extends BuildInstructionBase implements J2EEModuleBuildInstruction { + private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.make.J2EEModuleBuildInstructionImpl"); + + private final ModuleBuildProperties myBuildProperties; + + public J2EEModuleBuildInstructionImpl(ModuleBuildProperties moduleToBuild, String outputRelativePath) { + super(outputRelativePath, moduleToBuild.getModule()); + myBuildProperties = moduleToBuild; + LOG.assertTrue(!isExternalDependencyInstruction()); + } + + public void addFilesToExploded(final CompileContext context, + final File outputDir, + final Set writtenPaths, + final FileFilter fileFilter) throws IOException { + //todo optmization: cache created directory and issue single FileCopy on it + final File target = MakeUtil.canonicalRelativePath(outputDir, getOutputRelativePath()); + final BuildRecipe buildRecipe = getChildInstructions(context); + try { + if (myBuildProperties.isExplodedEnabled()) { + File fromFile = new File(myBuildProperties.getExplodedPath()); + MakeUtil.getInstance().copyFile(fromFile, target, context, writtenPaths, fileFilter); + // copy dependencies + buildRecipe.visitInstructionsWithExceptions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws Exception { + if (instruction.isExternalDependencyInstruction()) { + instruction.addFilesToExploded(context, target, writtenPaths, fileFilter); + } + return true; + } + }, false); + } + else { + buildRecipe.visitInstructionsWithExceptions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws Exception { + instruction.addFilesToExploded(context, target, writtenPaths, fileFilter); + return true; + } + }, false); + } + } + catch (Exception e) { + if (e instanceof IOException) throw (IOException)e; + if (e instanceof RuntimeException) throw (RuntimeException)e; + Degenerator.unableToDegenerateMarker(); + return; + } + } + + public boolean accept(BuildInstructionVisitor visitor) throws Exception { + return visitor.visitJ2EEModuleBuildInstruction(this); + } + + public void addFilesToJar(final CompileContext context, + final File jarFile, + final JarOutputStream outputStream, + BuildRecipe dependencies, + final Set writtenRelativePaths, + final FileFilter fileFilter) throws IOException { + // create temp jars, and add these into upper level jar + // todo optimization: cache created jars + final File tempFile; + final BuildRecipe childDependencies = new BuildRecipeImpl(); + if (myBuildProperties.isJarEnabled()) { + tempFile = new File(myBuildProperties.getJarPath()); + final BuildRecipe childModuleRecipe = getChildInstructions(context); + childModuleRecipe.visitInstructions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws RuntimeException { + if (instruction.isExternalDependencyInstruction()) { + childDependencies.addInstruction(instruction); + } + return true; + } + }, false); + } + else { + String moduleName = ModuleUtil.getModuleNameInReadAction(getModule()); + tempFile = File.createTempFile(moduleName+"___",".tmp"); + tempFile.deleteOnExit(); + makeJar(context, tempFile, childDependencies, fileFilter); + } + ZipUtil.addFileToZip(outputStream, tempFile, getOutputRelativePath(), writtenRelativePaths, fileFilter); + try { + childDependencies.visitInstructionsWithExceptions(new BuildInstructionVisitor() { + public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws Exception { + File file = instruction.getFile(); + String dependencyRelativePath = PathUtil.getCanonicalPath(MakeUtil.appendToPath(getOutputRelativePath(), instruction.getOutputRelativePath())); + + ZipUtil.addFileToZip(outputStream, file, dependencyRelativePath, writtenRelativePaths, fileFilter); + return true; + } + + public boolean visitJarAndCopyBuildInstruction(JarAndCopyBuildInstruction instruction) throws Exception { + if (instruction.getJarFile() == null) { + File tempJar = File.createTempFile("___",".tmp"); + tempJar.deleteOnExit(); + instruction.makeJar(context, tempJar, fileFilter); + } + File jarFile = instruction.getJarFile(); + String dependencyRelativePath = PathUtil.getCanonicalPath(MakeUtil.appendToPath(getOutputRelativePath(), instruction.getOutputRelativePath())); + + ZipUtil.addFileToZip(outputStream, jarFile, dependencyRelativePath, writtenRelativePaths, fileFilter); + return true; + } + }, false); + } + catch (Exception e) { + if (e instanceof IOException) throw (IOException)e; + if (e instanceof RuntimeException) throw (RuntimeException)e; + Degenerator.unableToDegenerateMarker(); + return; + } + } + + // return jarFile and possible jars linked via manifest + public void makeJar(final CompileContext context, + final File jarFile, + final BuildRecipe dependencies, + final FileFilter fileFilter) throws IOException { + final BuildRecipe buildRecipe = getChildInstructions(context); + final Manifest manifest = MakeUtil.getInstance().createManifest(buildRecipe); + if (manifest == null) { + context.addMessage(CompilerMessageCategory.WARNING, "Using user supplied manifest.mf",null,-1,-1); + } + FileUtil.createParentDirs(jarFile); + final JarOutputStream jarOutputStream = manifest == null ? + new JarOutputStream(new FileOutputStream(jarFile)) : + new JarOutputStream(new FileOutputStream(jarFile), manifest); + + final Set tempWrittenRelativePaths = new THashSet(); + try { + buildRecipe.visitInstructionsWithExceptions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws IOException { + instruction.addFilesToJar(context, jarFile, jarOutputStream, dependencies, tempWrittenRelativePaths, fileFilter); + return true; + } + }, false); + } + catch (Exception e) { + if (e instanceof IOException) throw (IOException)e; + if (e instanceof RuntimeException) throw (RuntimeException)e; + Degenerator.unableToDegenerateMarker(); + return; + } + finally { + jarOutputStream.close(); + } + } + + public BuildRecipe getChildInstructions(CompileContext context) { + return ModuleBuilder.getInstance(getModule()).getModuleBuildInstructions(context); + } + + public ModuleBuildProperties getBuildProperties() { + return myBuildProperties; + } + + public String toString() { + String s = "J2EE build instruction: "; + s += ModuleUtil.getModuleNameInReadAction(getModule()); + s += "->"+getOutputRelativePath(); + return s; + } + + public File findFileByRelativePath(String relativePath) { + if (!relativePath.startsWith(getOutputRelativePath())) return null; + final String pathFromFile = relativePath.substring(getOutputRelativePath().length()); + final Ref file = new Ref(); + final BuildRecipe buildRecipe = getChildInstructions(null); + buildRecipe.visitInstructions(new BuildInstructionVisitor() { + public boolean visitInstruction(BuildInstruction instruction) throws RuntimeException { + final File found = instruction.findFileByRelativePath(pathFromFile); + if (found != null) { + file.set(found); + return false; + } + return true; + } + }, false); + return file.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/JarAndCopyBuildInstructionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/JarAndCopyBuildInstructionImpl.java new file mode 100644 index 00000000000..6e7cc969de7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/make/JarAndCopyBuildInstructionImpl.java @@ -0,0 +1,114 @@ +package com.intellij.j2ee.make; + +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.ZipUtil; +import gnu.trove.THashSet; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +/** + * Created by IntelliJ IDEA. + * User: cdr + * Date: Jun 21, 2004 + * Time: 4:08:34 PM + * To change this template use File | Settings | File Templates. + */ +public class JarAndCopyBuildInstructionImpl extends FileCopyInstructionImpl implements JarAndCopyBuildInstruction { + private File myJarFile; + + public JarAndCopyBuildInstructionImpl(Module module, + File directoryToJar, + String outputRelativePath) { + super(directoryToJar, false, module, outputRelativePath); + } + + public void addFilesToExploded(CompileContext context, + File outputDir, + Set writtenPaths, + FileFilter fileFilter) throws IOException { + //todo optmization: cache created jar and issue single FileCopy on it + final File jarFile = MakeUtil.canonicalRelativePath(outputDir, getOutputRelativePath()); + + makeJar(context, jarFile, fileFilter); + writtenPaths.add(myJarFile.getPath()); + } + + public void addFilesToJar(CompileContext context, + File jarFile, + JarOutputStream outputStream, + BuildRecipe dependencies, + Set writtenRelativePaths, + FileFilter fileFilter) throws IOException { + // create temp jars, and add these into upper level jar + // todo optimization: cache created jars + final String moduleName = getModule() == null ? "jar" : ModuleUtil.getModuleNameInReadAction(getModule()); + final File tempFile = File.createTempFile(moduleName+"___",".tmp"); + makeJar(context, tempFile, fileFilter); + + final String outputRelativePath = getOutputRelativePath(); + + File file = getJarFile(); + if (isExternalDependencyInstruction()) { + // copy dependent file along with jar file + final File toFile = MakeUtil.canonicalRelativePath(jarFile, outputRelativePath); + MakeUtil.getInstance().copyFile(file, toFile, context, new HashSet(), fileFilter); + dependencies.addInstruction(this); + } + else { + ZipUtil.addFileToZip(outputStream, file, outputRelativePath, writtenRelativePaths, fileFilter); + } + } + + public void makeJar(CompileContext context, File jarFile, FileFilter fileFilter) throws IOException { + if (jarFile.equals(myJarFile)) return; + if (myJarFile != null) { + // optimization: file already jarred, copy it over + MakeUtil.getInstance().copyFile(myJarFile, jarFile, context, null, fileFilter); + } + else { + FileUtil.createParentDirs(jarFile); + Manifest manifest = new Manifest(); + ManifestBuilder.setGlobalAttributes(manifest.getMainAttributes()); + + final JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(jarFile), manifest); + try { + boolean ok = ZipUtil.addDirToZipRecursively(jarOutputStream, jarFile, getFile(), "", fileFilter, new THashSet()); + if (!ok) { + String dirPath = getFile().getPath(); + MakeUtil.reportRecursiveCopying(context, dirPath, jarFile.getPath(), "", + "Please setup jar file location outside directory '" + dirPath + "'."); + } + } + finally { + jarOutputStream.close(); + } + } + myJarFile = jarFile; + } + + + public boolean accept(BuildInstructionVisitor visitor) throws Exception { + return visitor.visitJarAndCopyBuildInstruction(this); + } + + public String toString() { + String s = "JAR and copy: "; + s += getFile(); + s += "->"+getOutputRelativePath(); + return s; + } + + public File getJarFile() { + return myJarFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/J2EEModuleContainerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/J2EEModuleContainerImpl.java new file mode 100644 index 00000000000..e3356b48c20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/J2EEModuleContainerImpl.java @@ -0,0 +1,352 @@ +package com.intellij.j2ee.module; + +import com.intellij.j2ee.ex.J2EEModulePropertiesEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.watcher.ModuleRootsWatcher; +import com.intellij.openapi.roots.watcher.ModuleRootsWatcherFactory; +import com.intellij.openapi.util.*; +import com.intellij.util.ExternalizableString; +import org.jdom.Element; + +import java.util.*; + +/** + * @author Alexey Kudravtsev + */ +public abstract class J2EEModuleContainerImpl + extends J2EEModulePropertiesEx implements JDOMExternalizable, ModuleByNameProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.module.J2EEModuleContainerImpl"); + + private J2EEModuleContainerImpl myModifiableModel; + protected final Module myParentModule; + private final Set myContents = new LinkedHashSet(); + + /** + * @deprecated + */ + private ModuleRootsWatcher myModuleRootsWatcher; + private Map myOrderInfo; + private static final String NAME_ATTRIBUTE_NAME = "name"; + private static final String LEVEL_ATTRIBUTE_NAME = "level"; + private static final String TYPE_ATTRIBUTE_NAME = "type"; + private static final String CONTAINER_ELEMENT_NAME = "containerElement"; + private static final String MODULE_TYPE = "module"; + private static final String LIBRARY_TYPE = "library"; + private static final String URL_ELEMENT_NAME = "url"; + + protected J2EEModuleContainerImpl(Module module) { + LOG.assertTrue(module != null); + myParentModule = module; + } + + protected void initContainer() { + if (myModuleRootsWatcher != null) { + migrateRootsWatcher(); + } + } + + private void migrateRootsWatcher() { + final Set keys = myOrderInfo.keySet(); + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + ExternalizableString key = (ExternalizableString)iterator.next(); + final OrderEntryInfo orderEntryInfo = myOrderInfo.get(key); + if (!orderEntryInfo.copy) continue; + final OrderEntry orderEntry = myModuleRootsWatcher.find(getModule(), key); + if (orderEntry == null) continue; + final ContainerElement containerElement; + if (orderEntry instanceof ModuleOrderEntry) { + final Module module = ((ModuleOrderEntry)orderEntry).getModule(); + if (module == null) continue; + containerElement = new ModuleLinkImpl(module, getModule()); + containerElement.setPackagingMethod(getModule().getModuleType().equals(ModuleType.EJB) + ? J2EEPackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST + : J2EEPackagingMethod.COPY_FILES); + } + else if (orderEntry instanceof LibraryOrderEntry) { + final Library library = ((LibraryOrderEntry)orderEntry).getLibrary(); + if (library == null) continue; + containerElement = new LibraryLinkImpl(library, getModule()); + containerElement.setPackagingMethod(getModule().getModuleType().equals(ModuleType.EJB) + ? J2EEPackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST + : J2EEPackagingMethod.COPY_FILES); + } + else { + LOG.error("invalid type " + orderEntry); + continue; + } + containerElement.setURI(orderEntryInfo.URI); + final Map attributes = orderEntryInfo.getAttributes(); + for (Iterator iterator1 = attributes.keySet().iterator(); iterator1.hasNext();) { + String name = (String)iterator1.next(); + String value = attributes.get(name); + containerElement.setAttribute(name, value); + } + containerElement.setURI(orderEntryInfo.URI); + addElement(containerElement); + } + + + } + + public void readExternal(Element element) throws InvalidDataException { + clearContainer(); + final List children = element.getChildren(CONTAINER_ELEMENT_NAME); + for (int i = 0; i < children.size(); i++) { + Element child = (Element)children.get(i); + final String type = child.getAttributeValue(TYPE_ATTRIBUTE_NAME); + ContainerElement containerElement = null; + if (MODULE_TYPE.equals(type)) { + String moduleName = child.getAttributeValue(NAME_ATTRIBUTE_NAME); + if (moduleName != null) { + containerElement = new ModuleLinkImpl(moduleName, getModule()); + } + } + else if (LIBRARY_TYPE.equals(type)) { + Library library = findLibrary(child); + if (library != null) { + containerElement = new LibraryLinkImpl(library, getModule()); + } + else { + String libraryLevel = child.getAttributeValue(LEVEL_ATTRIBUTE_NAME); + if (LibraryLink.MODULE_LEVEL.equals(libraryLevel)) { + containerElement = new LibraryLinkImpl(null, getModule()); + } + } + } + else { + throw new InvalidDataException("invalid type: " + type + " " + child); + } + if (containerElement != null) { + containerElement.readExternal(child); + addElement(containerElement); + } + + } + if (children.size() == 0) { + readPlainOldWatcherEntries(element); + } + } + + private Library findLibrary(Element child) { + String libraryName = child.getAttributeValue(NAME_ATTRIBUTE_NAME); + String libraryLevel = child.getAttributeValue(LEVEL_ATTRIBUTE_NAME); + if (LibraryLink.MODULE_LEVEL.equals(libraryLevel)) { + Element urlElement = child.getChild(URL_ELEMENT_NAME); + if (urlElement == null) return null; + return LibraryLink.findModuleLibrary(getModule(), urlElement.getText()); + } + else { + return LibraryLink.findLibrary(libraryName, libraryLevel, getModule().getProject()); + } + + } + + private static class ExternalizableStringFactory implements Factory { + private int seed; + + public ExternalizableString create() { + return new ExternalizableString("" + seed++); + } + + private void expandSeed(ExternalizableString orderEntryKey) { + try { + int i = Integer.parseInt(orderEntryKey.value); + seed = Math.max(i + 1, seed); + } + catch (NumberFormatException e) { + // must be syntetic entry + } + } + } + + /** + * @deprecated + */ + private void readPlainOldWatcherEntries(Element element) throws InvalidDataException { + final Element watcher = element.getChild("orderEntriesWatcher"); + if (watcher == null) { + return; + } + final ExternalizableStringFactory factory = new ExternalizableStringFactory(); + myModuleRootsWatcher = ModuleRootsWatcherFactory.create(factory); + myModuleRootsWatcher.readExternal(watcher); + myOrderInfo = new HashMap(); + final Element infoRoot = element.getChild("order-entry-info"); + if (infoRoot != null) { + final List infos = infoRoot.getChildren("info"); + for (int i = 0; i < infos.size(); i++) { + Element info = (Element)infos.get(i); + final Element keyElement = info.getChild("key"); + final ExternalizableString key = new ExternalizableString(""); + key.readExternal(keyElement); + final Element valueElement = info.getChild("value"); + final OrderEntryInfo value = new OrderEntryInfo(); + value.readExternal(valueElement); + // the only situation we want to change seed + factory.expandSeed(key); + + myOrderInfo.put(key, value); + } + } + + } + + public void writeExternal(Element element) throws WriteExternalException { + if (!isActive()) return; + + for (Iterator iterator = myContents.iterator(); iterator.hasNext();) { + ContainerElement containerElement = (ContainerElement)iterator.next(); + final Element child = new Element(CONTAINER_ELEMENT_NAME); + if (containerElement instanceof ModuleLink) { + child.setAttribute(TYPE_ATTRIBUTE_NAME, MODULE_TYPE); + child.setAttribute(NAME_ATTRIBUTE_NAME, ((ModuleLink)containerElement).getName()); + } + else if (containerElement instanceof LibraryLink) { + child.setAttribute(TYPE_ATTRIBUTE_NAME, LIBRARY_TYPE); + LibraryLink libraryLink = (LibraryLink)containerElement; + String level = libraryLink.getLevel(); + child.setAttribute(LEVEL_ATTRIBUTE_NAME, level); + } + else { + throw new WriteExternalException("invalid type: " + child); + } + containerElement.writeExternal(child); + element.addContent(child); + } + } + + protected boolean isActive() { + return getInstance(getModule()) == this; + } + + public ModuleLink[] getContainingModules() { + + final List moduleLinks = new ArrayList(); + + ContainerElement[] elements = getElements(); + for (int i = 0; i < elements.length; i++) { + ContainerElement element = elements[i]; + if (element instanceof ModuleLink) { + moduleLinks.add((ModuleLink)element); + } + } + + return moduleLinks.toArray(new ModuleLink[moduleLinks.size()]); + } + + public LibraryLink[] getContainingLibraries() { + final List libraryLinks = new ArrayList(); + ContainerElement[] elements = getElements(); + for (int i = 0; i < elements.length; i++) { + ContainerElement element = elements[i]; + if (element instanceof LibraryLink) { + libraryLinks.add((LibraryLink)element); + } + } + return libraryLinks.toArray(new LibraryLink[libraryLinks.size()]); + } + + public ContainerElement[] getElements() { + return getElements(this); + } + + public ContainerElement[] getElements(ModuleByNameProvider provider) { + ArrayList result = new ArrayList(); + for (Iterator iterator = myContents.iterator(); iterator.hasNext();) { + ContainerElement containerElement = (ContainerElement)iterator.next(); + if (((ResolvableElement)containerElement).resolveElement(provider)) { + result.add(containerElement); + } + } + return result.toArray(new ContainerElement[result.size()]); + } + + public void setElements(ContainerElement[] elements) { + clearContainer(); + myContents.addAll(Arrays.asList(elements)); + } + + public void removeModule(Module module) { + for (Iterator iterator = myContents.iterator(); iterator.hasNext();) { + ContainerElement element = (ContainerElement)iterator.next(); + if (element instanceof ModuleLink && ((ModuleLink)element).getModule() == module) { + myContents.remove(element); + break; + } + } + } + + + public Module getModule() { + return myParentModule; + } + + private void clearContainer() { + myContents.clear(); + } + + public void startEdit(ModifiableRootModel rootModel) { + myModifiableModel = createInstance(rootModel); + myModifiableModel.copyFrom(this, rootModel); + + myModifiableModel.initModifiableModel(); + } + + protected abstract void initModifiableModel(); + + protected abstract J2EEModuleContainerImpl createInstance(ModifiableRootModel rootModel); + + protected void copyFrom(J2EEModuleContainer from, ModifiableRootModel rootModel) { + copyContainerInfoFrom((J2EEModuleContainerImpl)from); + } + + public final J2EEModuleContainer getModifiableModel() { + return myModifiableModel; + } + + public void commit(ModifiableRootModel model) throws ConfigurationException { + if (isModified(model)) { + final J2EEModuleContainerImpl modified = (J2EEModuleContainerImpl)getModifiableModel(); + copyContainerInfoFrom(modified); + containedEntriesChanged(); + } + } + + public boolean isModified(ModifiableRootModel model) { + final J2EEModuleContainer modified = getModifiableModel(); + final ContainerElement[] modifiedElements = modified.getElements(); + + return !Arrays.equals(modifiedElements, getElements()); + } + + private void copyContainerInfoFrom(J2EEModuleContainerImpl from) { + clearContainer(); + final ContainerElement[] elements = from.getElements(); + for (int i = 0; i < elements.length; i++) { + final ContainerElement element = elements[i]; + addElement(element.clone()); + } + } + + public void addElement(ContainerElement element) { + myContents.add(element); + } + + public Module findModule(final String name) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Module compute() { + return ModuleManager.getInstance(getModule().getProject()).findModuleByName(name); + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/LibraryLinkImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/LibraryLinkImpl.java new file mode 100644 index 00000000000..5cde6fb1662 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/LibraryLinkImpl.java @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.j2ee.module; + +import com.intellij.j2ee.make.MakeUtil; +import com.intellij.j2ee.serverInstances.ApplicationServersManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.PathUtil; +import org.jdom.Element; + +import java.io.File; +import java.util.*; + +public class LibraryLinkImpl extends LibraryLink implements ResolvableElement{ + private static final Map methodToDescriptionForDirs = new HashMap(); + private static final Map methodToDescriptionForFiles = new HashMap(); + private static final String URL_ELEMENT_NAME = "url"; + + static { + methodToDescriptionForDirs.put(J2EEPackagingMethod.DO_NOT_PACKAGE, "Do not package"); + methodToDescriptionForDirs.put(J2EEPackagingMethod.COPY_FILES, "Copy directories to"); + methodToDescriptionForDirs.put(J2EEPackagingMethod.JAR_AND_COPY_FILE, "JAR dirs and copy file to"); + methodToDescriptionForDirs.put(J2EEPackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST, "JAR dirs, link via manifest and copy to"); + methodToDescriptionForFiles.put(J2EEPackagingMethod.DO_NOT_PACKAGE, "Do not package"); + methodToDescriptionForFiles.put(J2EEPackagingMethod.COPY_FILES, "Copy files to"); + methodToDescriptionForFiles.put(J2EEPackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST, "Link via manifest and copy files to"); + } + + interface LibraryInfo extends JDOMExternalizable { + String getName(); + + List getUrls(); + + String getLevel(); + + Library getLibrary(); + + void addUrl(String url); + } + + private class LibraryInfoImpl implements LibraryInfo { + private final List myUrls = new ArrayList(); + + public String getName() { + return null; + } + + public List getUrls() { + return myUrls; + } + + public String getLevel() { + return MODULE_LEVEL; + } + + public void addUrl(String url) { + myUrls.clear(); + myUrls.add(url); + } + + public Library getLibrary() { + return null; + } + + public void readExternal(Element element) throws InvalidDataException { + myUrls.clear(); + final List urls = element.getChildren(URL_ELEMENT_NAME); + for (int i = 0; i < urls.size(); i++) { + Element url = (Element)urls.get(i); + myUrls.add(url.getText()); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myUrls.size(); i++) { + final String url = myUrls.get(i); + final Element urlElement = new Element(URL_ELEMENT_NAME); + urlElement.setText(url); + element.addContent(urlElement); + } + } + } + + private class LibraryInfoBasedOnLibrary implements LibraryInfo { + private final Library myLibrary; + + private LibraryInfoBasedOnLibrary(Library library) { + myLibrary = library; + } + + public String getName() { + return myLibrary.getName(); + } + + public List getUrls() { + return Arrays.asList(myLibrary.getUrls(OrderRootType.CLASSES)); + } + + public String getLevel() { + if (myLibrary.getTable() == null) { + return MODULE_LEVEL; + } + else { + return myLibrary.getTable().getTableLevel(); + } + } + + public Library getLibrary() { + return myLibrary; + } + + public void addUrl(String url) { + } + + public void readExternal(Element element) throws InvalidDataException { + } + + public void writeExternal(Element element) throws WriteExternalException { + String name = getName(); + if (name == null) { + List urls = getUrls(); + for (int i = 0; i < urls.size(); i++) { + final String url = urls.get(i); + final Element urlElement = new Element(URL_ELEMENT_NAME); + urlElement.setText(url); + element.addContent(urlElement); + } + } + else { + element.setAttribute("name", name); + } + } + } + + private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.module.LibraryLink"); + private LibraryInfo myLibraryInfo; + + public LibraryLinkImpl(Library library, Module parentModule) { + super(parentModule); + if (library == null) { + myLibraryInfo = new LibraryInfoImpl(); + } + else { + myLibraryInfo = new LibraryInfoBasedOnLibrary(library); + } + + } + + public Library getLibrary() { + return myLibraryInfo.getLibrary(); + } + + public String toString() { + return "Library Link: " + getPresentableName() + " -> " + getURI(); + } + + public String getPresentableName() { + if (getName() != null) return getName(); + List urls = myLibraryInfo.getUrls(); + if (urls.size() == 0) return "Empty Library"; + final String url = urls.get(0); + final String path = PathUtil.toPresentableUrl(url); + + return FileUtil.toSystemDependentName(path); + } + + public String getDescription() { + String levelName = myLibraryInfo.getLevel(); + if (levelName.equals(MODULE_LEVEL)) { + return "Module Library"; + } + else if (LibraryTablesRegistrar.APPLICATION_LEVEL.equals(levelName)) { + return "Global Library"; + } + else if (LibraryTablesRegistrar.PROJECT_LEVEL.equals(levelName)) { + return "Project Library"; + } + else if (ApplicationServersManager.APPLICATION_SERVER_MODULE_LIBRARIES.equals(levelName)) { + return "Application Server Library"; + } + else { + return "???"; + } + } + + public String getDescriptionForPackagingMethod(J2EEPackagingMethod method) { + if (hasDirectoriesOnly()) { + return methodToDescriptionForDirs.get(method); + } + else { + return methodToDescriptionForFiles.get(method); + } + } + + public void addUrl(String url) { + myLibraryInfo.addUrl(url); + } + + public List getUrls() { + return myLibraryInfo.getUrls(); + } + + public boolean equalsIgnoreAttributes(ContainerElement otherElement) { + if (!(otherElement instanceof LibraryLink)) return false; + final LibraryLink otherLibraryLink = (LibraryLink)otherElement; + if (!Comparing.strEqual(getName(), otherLibraryLink.getName())) return false; + if (!getUrls().equals(otherLibraryLink.getUrls())) return false; + return true; + } + + public String getSingleFileName() { + // non-module-level libs can contain multiple files + final String table = getLevel(); + if (!MODULE_LEVEL.equals(table)) return null; + + List urls = getUrls(); + if (urls.size() != 1) return null; + File file = new File(PathUtil.toPresentableUrl(urls.get(0))); + return file.getName(); + } + + public boolean hasDirectoriesOnly() { + List urls = getUrls(); + boolean hasDirsOnly = true; + for (int i = 0; i < urls.size(); i++) { + final String url = urls.get(i); + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); + VirtualFile localFile = file == null ? null : + LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(PathUtil.getLocalPath(file))); + if (localFile != null && !localFile.isDirectory()) { + hasDirsOnly = false; + break; + } + } + return hasDirsOnly; + } + + public String getName() { + return myLibraryInfo.getName(); + } + + public String getLevel() { + return myLibraryInfo.getLevel(); + } + + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + myLibraryInfo.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + myLibraryInfo.writeExternal(element); + } + + public boolean resolveElement(ModuleByNameProvider provider) { + if (getLibrary() != null){ + return true; + } + if (!MODULE_LEVEL.equals(getLevel())){ + return false; + } + + List urls = getUrls(); + if (urls.size() != 1){ + return false; + } + + String url = urls.get(0); + + Module[] modules = getAllDependentModules(); + for (int i = 0; i < modules.length; i++) { + Library moduleLibrary = findModuleLibrary(modules[i], url); + if (moduleLibrary != null){ + myLibraryInfo = new LibraryInfoBasedOnLibrary(moduleLibrary); + return true; + } + } + + return false; + + } + + protected Module[] getAllDependentModules() { + HashSet result = new HashSet(); + Module parentModule = getParentModule(); + addDependencies(parentModule, result); + + return new ArrayList(result).toArray(new Module[result.size()]); + } + + protected void addDependencies(Module module, HashSet result) { + if (result.contains(module)) return; + result.add(module); + Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies(); + for (int i = 0; i < dependencies.length; i++) { + addDependencies(dependencies[i], result); + } + } + + public LibraryLink clone() { + LibraryLink libraryLink = MakeUtil.getInstance().createLibraryLink(getLibrary(), getParentModule()); + Element temp = new Element("temp"); + try { + writeExternal(temp); + libraryLink.readExternal(temp); + } + catch (Exception e) { + LOG.error(e); + } + return libraryLink; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ModuleLinkImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ModuleLinkImpl.java new file mode 100644 index 00000000000..9b54ad2e1da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ModuleLinkImpl.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.j2ee.module; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +public class ModuleLinkImpl extends ModuleLink implements ResolvableElement { + + private Module myModule; + private String myModuleName; + private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.module.ModuleLink"); + + static { + methodToDescription.put(J2EEPackagingMethod.DO_NOT_PACKAGE, "Do not package"); + methodToDescription.put(J2EEPackagingMethod.COPY_FILES, "Copy module output to"); + methodToDescription.put(J2EEPackagingMethod.JAR_AND_COPY_FILE, "JAR module output and copy file to"); + methodToDescription.put(J2EEPackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST, "JAR module, link via manifest and copy to"); + methodToDescription.put(J2EEPackagingMethod.INCLUDE_MODULE_IN_BUILD, "Include module in build"); + } + + public ModuleLinkImpl(Module module, Module parentModule) { + super(parentModule); + LOG.assertTrue(module != null); + myModule = module; + } + + public ModuleLinkImpl(String moduleName, Module parentModule) { + super(parentModule); + myModuleName = moduleName; + } + + private Module getModule(ModuleByNameProvider provider) { + if (myModule != null && myModule.isDisposed()) { + myModule = null; + } + if (myModule == null) { + myModule = provider.findModule(myModuleName); + } + return myModule; + } + + public Module getModule() { + if (myModule != null && myModule.isDisposed()) { + myModule = null; + } + if (myModule == null) { + myModule = ApplicationManager.getApplication().runReadAction(new Computable() { + public Module compute() { + return ModuleManager.getInstance(getParentModule().getProject()).findModuleByName(myModuleName); + } + }); + } + return myModule; + } + + public String toString() { + return "Module Link: " + getName() + "->" + getURI(); + } + + public boolean equalsIgnoreAttributes(ContainerElement otherElement) { + if (!(otherElement instanceof ModuleLink)) return false; + return Comparing.strEqual(((ModuleLink)otherElement).getName(), getName()); + } + + public String getId() { + return getId(getModule()); + } + + public String getPresentableName() { + return getName(); + } + + public String getDescription() { + final Module module = getModule(); + return module == null ? "" : module.getModuleType().getName(); + } + + public String getDescriptionForPackagingMethod(J2EEPackagingMethod method) { + return methodToDescription.get(method); + } + + public boolean resolveElement(ModuleByNameProvider provider) { + return getModule(provider) != null; + } + + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + migratePackagingMethods(); + } + + private void migratePackagingMethods() { + if (getPackagingMethod() == J2EEPackagingMethod.COPY_CLASSES) { + setPackagingMethod(J2EEPackagingMethod.COPY_FILES); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + element.setAttribute("name", getName()); + } + + public String getName() { + if (myModule == null) { + return myModuleName; + } + else { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return myModule.getName(); + } + }); + } + } + + public ModuleLink clone() { + ModuleLink moduleLink = new ModuleLinkImpl(getName(), getParentModule()); + Element temp = new Element("temp"); + try { + writeExternal(temp); + moduleLink.readExternal(temp); + } + catch (Exception e) { + LOG.error(e); + } + return moduleLink; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/OrderEntryInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/OrderEntryInfo.java new file mode 100644 index 00000000000..216377a2fd4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/OrderEntryInfo.java @@ -0,0 +1,85 @@ +package com.intellij.j2ee.module; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.JDOMExternalizer; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author cdr + * @deprecated + */ +class OrderEntryInfo implements JDOMExternalizable { + public boolean copy; + public String URI=""; + private Map attributes = new HashMap(); + + public void writeExternal(Element element) throws WriteExternalException { + JDOMExternalizer.write(element,"copy",copy); + JDOMExternalizer.write(element,"URI",URI); + writeAttributes(element); + } + + private void writeAttributes(Element element) { + if (attributes.size() == 0) return; + Element root = new Element("attributes"); + element.addContent(root); + Set names = attributes.keySet(); + for (Iterator iterator = names.iterator(); iterator.hasNext();) { + String name = iterator.next(); + String value = attributes.get(name); + Element attr = new Element("attribute"); + attr.setAttribute("name",name); + attr.setAttribute("value",value); + root.addContent(attr); + } + } + private void readAttributes(Element element) { + Element attrs = element.getChild("attributes"); + if (attrs == null) return; + List roots = attrs.getChildren("attribute"); + if (roots.size() == 0) return; + for (int i = 0; i < roots.size(); i++) { + Element attr = (Element)roots.get(i); + String name = attr.getAttributeValue("name"); + String value = attr.getAttributeValue("value"); + attributes.put(name, value); + } + } + + public void readExternal(Element element) throws InvalidDataException { + copy = JDOMExternalizer.readBoolean(element,"copy"); + URI = JDOMExternalizer.readString(element,"URI"); + readAttributes(element); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof OrderEntryInfo)) return false; + + final OrderEntryInfo orderEntryInfo = (OrderEntryInfo)o; + + if (copy != orderEntryInfo.copy) return false; + if (URI != null ? !URI.equals(orderEntryInfo.URI) : orderEntryInfo.URI != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = copy ? 1 : 0; + result = 29 * result + (URI != null ? URI.hashCode() : 0); + return result; + } + + public Map getAttributes() { + return attributes; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ResolvableElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ResolvableElement.java new file mode 100644 index 00000000000..6b759c8ceb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/ResolvableElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.j2ee.module; + +public interface ResolvableElement { + boolean resolveElement(ModuleByNameProvider provider); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/TransactionalEditable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/TransactionalEditable.java new file mode 100644 index 00000000000..1a0013d33fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/TransactionalEditable.java @@ -0,0 +1,14 @@ +package com.intellij.j2ee.module; + +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.options.ConfigurationException; + +public interface TransactionalEditable { + void startEdit(ModifiableRootModel rootModel); + + J2EEModuleContainer getModifiableModel(); + + void commit(ModifiableRootModel model) throws ConfigurationException; + + boolean isModified(ModifiableRootModel model); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/view/common/editor/SplitterProportionsData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/view/common/editor/SplitterProportionsData.java new file mode 100644 index 00000000000..95854c5aed4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/module/view/common/editor/SplitterProportionsData.java @@ -0,0 +1,84 @@ +/** + * @author cdr + */ +package com.intellij.j2ee.module.view.common.editor; + +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.Comparing; +import com.intellij.util.text.StringTokenizer; +import org.jdom.Element; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class SplitterProportionsData implements JDOMExternalizable{ + private List proportions = new ArrayList(); + private static final String DATA_VERSION = "1"; + + public void saveSplitterProportions(Component root) { + proportions.clear(); + doSaveSplitterProportions(root); + } + private void doSaveSplitterProportions(Component root) { + if (root instanceof Splitter) { + Float prop = new Float(((Splitter)root).getProportion()); + proportions.add(prop); + } + if (root instanceof Container) { + Component[] children = ((Container)root).getComponents(); + for (int i = 0; i < children.length; i++) { + Component child = children[i]; + doSaveSplitterProportions(child); + } + } + } + + public void restoreSplitterProportions(Component root) { + restoreSplitterProportions(root, 0); + } + + private int restoreSplitterProportions(Component root, int index) { + if (root instanceof Splitter) { + if (proportions.size() <= index) return index; + ((Splitter)root).setProportion(proportions.get(index++).floatValue()); + } + if (root instanceof Container) { + Component[] children = ((Container)root).getComponents(); + for (int i = 0; i < children.length; i++) { + Component child = children[i]; + index = restoreSplitterProportions(child, index); + } + } + return index; + } + + public void readExternal(Element element) throws InvalidDataException { + proportions.clear(); + String prop = element.getAttributeValue("proportions"); + String version = element.getAttributeValue("version"); + if (prop != null && Comparing.equal(version, DATA_VERSION)) { + StringTokenizer tokenizer = new StringTokenizer(prop, ","); + while (tokenizer.hasMoreTokens()) { + String p = tokenizer.nextToken(); + proportions.add(Float.valueOf(p)); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + StringBuffer result = new StringBuffer(); + String sep = ""; + for (int i = 0; i < proportions.size(); i++) { + Float proportion = proportions.get(i); + result.append(sep); + result.append(proportion); + sep = ","; + } + element.setAttribute("proportions", result.toString()); + element.setAttribute("version", DATA_VERSION); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/ex/ExternalResourceManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/ex/ExternalResourceManagerEx.java new file mode 100644 index 00000000000..f11da94c5ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/ex/ExternalResourceManagerEx.java @@ -0,0 +1,27 @@ +package com.intellij.j2ee.openapi.ex; + +import com.intellij.j2ee.ExternalResourceManager; +import com.intellij.j2ee.extResources.ExternalResourceListener; + +/** + * author: lesya + */ +public abstract class ExternalResourceManagerEx extends ExternalResourceManager { + public static ExternalResourceManagerEx getInstanceEx(){ + return (ExternalResourceManagerEx)getInstance(); + } + + public abstract String[] getAvailableUrls(); + + public abstract void clearAllResources(); + + public abstract void addIgnoredResource(String url); + + public abstract boolean isIgnoredResource(String url); + + public abstract String[] getIgnoredResources(); + + public abstract void addExteralResourceListener(ExternalResourceListener listener); + + public abstract void removeExternalResourceListener(ExternalResourceListener listener); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/ExternalResourceManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/ExternalResourceManagerImpl.java new file mode 100644 index 00000000000..c8791fedda7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/ExternalResourceManagerImpl.java @@ -0,0 +1,255 @@ +package com.intellij.j2ee.openapi.impl; + +import com.intellij.application.options.PathMacros; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.j2ee.extResources.ExternalResourceListener; +import com.intellij.j2ee.openapi.ex.ExternalResourceManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.util.*; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.xml.util.XmlUtil; +import org.jdom.Element; + +import java.io.File; +import java.util.*; + +/** + * @author mike + */ +public class ExternalResourceManagerImpl extends ExternalResourceManagerEx implements JDOMExternalizable, ApplicationComponent, ModificationTracker { + + private static final String J2EE_1_3 = "http://java.sun.com/dtd/"; + private static final String J2EE_1_2 = "http://java.sun.com/j2ee/dtds/"; + private static final String J2EE_NS = "http://java.sun.com/xml/ns/j2ee/"; + private static final String IBM_NS = "http://www.ibm.com/webservices/xsd/"; + + private Map myResources = new com.intellij.util.containers.HashMap(); + private Set myIgnoredResources = new HashSet(); + private Map myStdResources = new com.intellij.util.containers.HashMap(); + private List myListeners = new ArrayList(); + private long myModificationCount = 0; + private PathMacros myPathMacros; + + public ExternalResourceManagerImpl(PathMacros pathMacros) { + addInternalResource(J2EE_1_3 + "connector_1_0.dtd", "connector_1_0.dtd"); + addInternalResource(J2EE_1_3 + "jspxml.xsd", "jspxml.xsd"); + addInternalResource(J2EE_1_3 + "jspxml.dtd", "jspxml.dtd"); + addInternalResource(XmlUtil.JSP_NAMESPACE,"jspxml.xsd"); + addInternalResource("http://java.sun.com/products/jsp/dtd/jsp_1_0.dtd","jspxml.dtd"); + + addInternalResource(J2EE_1_3 + "web-jsptaglibrary_1_2.dtd", "web-jsptaglibrary_1_2.dtd"); + addInternalResource(J2EE_1_3 + "web-app_2_3.dtd", "web-app_2_3.dtd"); + addInternalResource(J2EE_1_3 + "application-client_1_3.dtd", "application-client_1_3.dtd"); + addInternalResource(J2EE_1_3 + "application_1_3.dtd", "application_1_3.dtd"); + addInternalResource(J2EE_1_3 + "ejb-jar_2_0.dtd", "ejb-jar_2_0.dtd"); + addInternalResource(J2EE_1_3 + "logger.dtd", "logger.dtd"); + + addInternalResource(J2EE_1_2 + "application-client_1_2.dtd", "application-client_1_2.dtd"); + addInternalResource(J2EE_1_2 + "application_1_2.dtd", "application_1_2.dtd"); + addInternalResource(J2EE_1_2 + "ejb-jar_1_1.dtd","ejb-jar_1_1.dtd"); + addInternalResource(J2EE_1_2 + "web-app_2_2.dtd","web-app_2_2.dtd"); + addInternalResource(J2EE_1_2 + "web-jsptaglibrary_1_1.dtd","web-jsptaglibrary_1_1.dtd"); + addInternalResource(IBM_NS + "j2ee_web_services_client_1_1.xsd","j2ee_web_services_client_1_1.xsd"); + + + addInternalResource("http://www.w3.org/2001/XMLSchema", "XMLSchema.xsd"); + addInternalResource("http://www.w3.org/2001/XMLSchema-instance", "XMLSchema-instance.xsd"); + addInternalResource("http://www.w3.org/2001/xml.xsd","xml.xsd"); + addInternalResource("http://www.w3.org/1999/xhtml","xhtml1.dtd"); + addInternalResource("http://www.w3.org/1999/xhtml","xhtml1.dtd"); + + addInternalResource("http://www.w3.org/TR/html4/strict.dtd","xhtml1-strict.dtd"); + addInternalResource("http://www.w3.org/TR/html4/loose.dtd","xhtml1-transitional.dtd"); + addInternalResource("http://www.w3.org/TR/html4/frameset.dtd","xhtml1-frameset.dtd"); + addInternalResource("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd","xhtml1-strict.dtd"); + addInternalResource("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd","xhtml1-transitional.dtd"); + addInternalResource("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd","xhtml1-strict.dtd"); + + addInternalResource(J2EE_NS + "web-app_2_4.xsd","web-app_2_4.xsd"); + addInternalResource(J2EE_NS + "ejb-jar_2_1.xsd","ejb-jar_2_1.xsd"); + addInternalResource(J2EE_NS + "connector_1_5.xsd","connector_1_5.xsd"); + addInternalResource(J2EE_NS + "jsp_2_0.xsd","jsp_2_0.xsd"); + addInternalResource(J2EE_NS + "j2ee_1_4.xsd","j2ee_1_4.xsd"); + addInternalResource(J2EE_NS + "application-client_1_4.xsd","application-client_1_4.xsd"); + addInternalResource(J2EE_NS + "application_1_4.xsd","application_1_4.xsd"); + addInternalResource(J2EE_NS + "web-jsptaglibrary_2_0.xsd","web-jsptaglibrary_2_0.xsd"); + + // Plugins DTDs // stathik + addInternalResource("http://plugins.intellij.net/plugin.dtd", + "plugin.dtd"); + addInternalResource("http://plugins.intellij.net/plugin-repository.dtd", + "plugin-repository.dtd"); + myPathMacros = pathMacros; + } + + private static String getFile(String name, Class klass) { + String path = FileUtil.unquote(klass.getResource(name).toString()); + // this is done by FileUtil for windows + path = path.replace('\\','/'); + return path; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + private void addInternalResource(String resource, String fileName) { + addStdResource(resource, "/standardSchemas/" + fileName); + } + + public void addStdResource(String resource, String fileName){ + addStdResource(resource, fileName, getClass()); + } + + public void addStdResource(String resource, String fileName, Class klass) { + myStdResources.put(resource, getFile(fileName, klass)); + } + + public String getResourceLocation(String url) { + String result = myResources.get(url); + + if (result == null) { + result = myStdResources.get(url); + } + if (result == null) { + result = url; + } + + return result; + } + + public String[] getResourceUrls(FileType fileType) { + final List result = new LinkedList(); + final Set keySet = myResources.keySet(); + + for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { + String key = iterator.next(); + String resource = myResources.get(key); + + if (fileType!=null) { + String defaultExtension = fileType.getDefaultExtension(); + + if (resource.endsWith(defaultExtension) && + resource.length() > defaultExtension.length() && + resource.charAt(resource.length()-defaultExtension.length()-1) == '.' + ) { + result.add(key); + } + } else { + result.add(key); + } + } + + return result.toArray(new String[result.size()]); + } + + public void addResource(String url, String location) { + myResources.put(url, location); + myModificationCount++; + fireExternalResourceChanged(); + } + + public void removeResource(String url) { + myResources.remove(url); + myModificationCount++; + fireExternalResourceChanged(); + } + + public String[] getAvailableUrls() { + final Set set = myResources.keySet(); + return set.toArray(new String[set.size()]); + } + + public void clearAllResources() { + myResources.clear(); + myIgnoredResources.clear(); + myModificationCount++; + fireExternalResourceChanged(); + } + + public void addIgnoredResource(String url) { + myIgnoredResources.add(url); + myModificationCount++; + fireExternalResourceChanged(); + } + + public boolean isIgnoredResource(String url) { + return myIgnoredResources.contains(url); + } + + public String[] getIgnoredResources() { + return myIgnoredResources.toArray(new String[myIgnoredResources.size()]); + } + + public long getModificationCount() { + return myModificationCount; + } + + public void readExternal(Element element) throws InvalidDataException { + final ExpandMacroToPathMap macroExpands = new ExpandMacroToPathMap(); + myPathMacros.addMacroExpands(macroExpands); + macroExpands.substitute(element, SystemInfo.isFileSystemCaseSensitive); + + myModificationCount++; + for (Iterator iterator = element.getChildren("resource").iterator(); iterator.hasNext();) { + Element e = (Element)iterator.next(); + addResource(e.getAttributeValue("url"), e.getAttributeValue("location").replace('/', File.separatorChar)); + } + + for (Iterator i = element.getChildren("ignored-resource").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + addIgnoredResource(e.getAttributeValue("url")); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + final String[] urls = getAvailableUrls(); + for (int i = 0; i < urls.length; i++) { + String url = urls[i]; + String location = getResourceLocation(url); + + final Element e = new Element("resource"); + + e.setAttribute("url", url); + e.setAttribute("location", location.replace(File.separatorChar, '/')); + element.addContent(e); + } + + final String[] ignoredResources = getIgnoredResources(); + for (int i = 0; i < ignoredResources.length; i++) { + String ignoredResource = ignoredResources[i]; + + final Element e = new Element("ignored-resource"); + + e.setAttribute("url", ignoredResource); + element.addContent(e); + } + + final ReplacePathToMacroMap macroReplacements = new ReplacePathToMacroMap(); + PathMacros.getInstance().addMacroReplacements(macroReplacements); + macroReplacements.substitute(element, SystemInfo.isFileSystemCaseSensitive); + } + + public String getComponentName() { + return "ExternalResourceManagerImpl"; + } + + public void addExteralResourceListener(ExternalResourceListener listener) { + myListeners.add(listener); + } + + public void removeExternalResourceListener(ExternalResourceListener listener) { + myListeners.remove(listener); + } + + private void fireExternalResourceChanged() { + ExternalResourceListener[] listeners = myListeners.toArray(new ExternalResourceListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + ExternalResourceListener listener = listeners[i]; + listener.externalResourceChanged(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/LibrariesManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/LibrariesManagerImpl.java new file mode 100644 index 00000000000..eb11b5b98f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/openapi/impl/LibrariesManagerImpl.java @@ -0,0 +1,55 @@ +package com.intellij.j2ee.openapi.impl; + +import com.intellij.j2ee.LibrariesManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.text.StringTokenizer; + +/** + * author: lesya + */ +public class LibrariesManagerImpl extends LibrariesManager implements ApplicationComponent { + public String getComponentName() { + return "LabraryManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public boolean isClassAvailableInLibrary(Library library, String fqn) { + final String[] urls = library.getUrls(OrderRootType.CLASSES); + return isClassAvailable(urls, fqn); + } + + public boolean isClassAvailable(final String[] urls, String fqn) { + for (int i = 0; i < urls.length; i++) { + String url = urls[i]; + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); + if (file == null) continue; + if (file.getFileSystem() != JarFileSystem.getInstance() && !file.isDirectory()) { + file = JarFileSystem.getInstance().findFileByPath(file.getPath() + JarFileSystem.JAR_SEPARATOR); + } + if (file == null) continue; + if (findInFile(file, new StringTokenizer(fqn, "."))) return true; + } + return false; + } + + private static boolean findInFile(VirtualFile root, final StringTokenizer filePath) { + if (!filePath.hasMoreTokens()) return true; + String name = filePath.nextToken(); + if (!filePath.hasMoreTokens()) { + name += ".class"; + } + final VirtualFile child = root.findChild(name); + if (child != null) return findInFile(child, filePath); + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/run/localRun/EnvVariablesTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/run/localRun/EnvVariablesTable.java new file mode 100644 index 00000000000..fedae573acd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/j2ee/run/localRun/EnvVariablesTable.java @@ -0,0 +1,203 @@ +package com.intellij.j2ee.run.localRun; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.table.TableView; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.util.List; + +public class EnvVariablesTable extends Observable { + private final List myVariables = new ArrayList(); + private final JPanel myPanel = new JPanel(new BorderLayout()); + + private ColumnInfo NAME = new ColumnInfo("Name") { + public String valueOf(EnvironmentVariable environmentVariable) { + return environmentVariable.getName(); + } + + public Class getColumnClass() { + return String.class; + } + + public boolean isCellEditable(EnvironmentVariable environmentVariable) { + return environmentVariable.getNameIsWriteable(); + } + + public void setValue(EnvironmentVariable environmentVariable, String s) { + if (s.equals(valueOf(environmentVariable))) { + return; + } + environmentVariable.setName(s); + setModified(); + } + }; + + private ColumnInfo VALUE = new ColumnInfo("Value") { + public String valueOf(EnvironmentVariable environmentVariable) { + return environmentVariable.getValue(); + } + + public Class getColumnClass() { + return String.class; + } + + public boolean isCellEditable(EnvironmentVariable environmentVariable) { + return !environmentVariable.getIsPredefined(); + } + + public void setValue(EnvironmentVariable environmentVariable, String s) { + if (s.equals(valueOf(environmentVariable))) { + return; + } + environmentVariable.setValue(s); + setModified(); + } + + }; + private final TableView myTableVeiw; + private boolean myIsEnabled = true; + + public EnvVariablesTable(List variables) { + myVariables.addAll(variables); + myTableVeiw = new TableView(new ListTableModel((new ColumnInfo[]{NAME, VALUE}))); + myTableVeiw.getTableViewModel().setSortable(false); + myPanel.add(ScrollPaneFactory.createScrollPane(myTableVeiw.getComponent()), BorderLayout.CENTER); + JComponent toolbarComponent = createToolbar(); + myPanel.add(toolbarComponent, BorderLayout.NORTH); + myTableVeiw.getComponent().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + + private void setModified() { + setChanged(); + notifyObservers(); + } + + + private JComponent createToolbar() { + DefaultActionGroup actions = new DefaultActionGroup(); + actions.add(new AddAction()); + actions.add(new DeleteAction()); + JComponent toolbarComponent = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true).getComponent(); + return toolbarComponent; + } + + public JComponent getComponent() { + return myPanel; + } + + public void setEnabled() { + myTableVeiw.getComponent().setEnabled(true); + myIsEnabled = true; + } + + public void setDisabled() { + myTableVeiw.getComponent().setEnabled(false); + myIsEnabled = false; + + } + + public void setValues(List envVariables) { + myVariables.clear(); + myVariables.addAll(envVariables); + myTableVeiw.getTableViewModel().setItems(envVariables); + } + + public List getEnvironmentVariables() { + return myVariables; + } + + public void refreshValues() { + myTableVeiw.getComponent().repaint(); + } + + private final class DeleteAction extends AnAction { + public DeleteAction() { + super("Delete", null, IconLoader.getIcon("/general/remove.png")); + } + + public void update(AnActionEvent e) { + EnvironmentVariable selection = getSelection(); + Presentation presentation = e.getPresentation(); + presentation.setEnabled(selection != null && myIsEnabled && !selection.getIsPredefined()); + } + + public void actionPerformed(AnActionEvent e) { + myTableVeiw.stopEditing(); + setModified(); + EnvironmentVariable selected = getSelection(); + if (selected != null) { + int selectedIndex = myVariables.indexOf(selected); + myVariables.remove(selected); + myTableVeiw.getTableViewModel().setItems(myVariables); + + int prev = selectedIndex - 1; + if (prev >= 0) { + myTableVeiw.getComponent().getSelectionModel().setSelectionInterval(prev, prev); + } + else if (selectedIndex < myVariables.size()) { + myTableVeiw.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + } + } + + } + + } + + private final class AddAction extends AnAction { + public AddAction() { + super("Add", null, IconLoader.getIcon("/general/add.png")); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myIsEnabled); + } + + public void actionPerformed(AnActionEvent e) { + myTableVeiw.stopEditing(); + setModified(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myVariables.add(new EnvironmentVariable(getUniqueName(), "", false)); + myTableVeiw.getTableViewModel().setItems(myVariables); + myTableVeiw.getComponent().editCellAt(0, myVariables.size() - 1); + } + }); + } + + private String getUniqueName() { + Set names = collectAllNames(); + for (int i = 2; ; i++) { + String newName = "EnvVar" + i; + if (names.contains(newName)) continue; + return newName; + } + } + + private Set collectAllNames() { + HashSet result = new HashSet(); + for (Iterator iterator = myVariables.iterator(); iterator.hasNext();) { + EnvironmentVariable environmentVariable = (EnvironmentVariable)iterator.next(); + result.add(environmentVariable.getName()); + } + return result; + } + } + + private EnvironmentVariable getSelection() { + int selIndex = myTableVeiw.getComponent().getSelectionModel().getMinSelectionIndex(); + if (selIndex < 0) { + return null; + } + else { + return myVariables.get(selIndex); + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/GenerateJavadocDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/GenerateJavadocDialog.java new file mode 100644 index 00000000000..2587f57b236 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/GenerateJavadocDialog.java @@ -0,0 +1,152 @@ +package com.intellij.javadoc; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +final class GenerateJavadocDialog extends DialogWrapper { + private JRadioButton myForProjectRadio; + private JRadioButton myForPackageRadio; + private JCheckBox myIncludeSubpackagesCheckBox; + private final String myPackageName; + private final JavadocConfigurable myConfigurable; + private final Project myProject; + + GenerateJavadocDialog(String packageName, Project project, JavadocConfiguration configuration) { + super(project, true); + myProject = project; + + myConfigurable = configuration.createConfigurable(); + + setOKButtonText("&Start"); + myPackageName = "".equals(packageName) ? "" : packageName; + setTitle("Generate JavaDoc"); + init(); + myConfigurable.reset(); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(4,8,8,0)); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridy = 0; + gbConstraints.gridx = 0; + gbConstraints.gridwidth = 3; + gbConstraints.gridheight = 1; + gbConstraints.weightx = 1; + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.insets = new Insets(0,0,0,0); + + myForProjectRadio = new JRadioButton("Whole project"); + myForProjectRadio.setMnemonic('w'); + panel.add(myForProjectRadio, gbConstraints); + + myForPackageRadio = new JRadioButton("Package"+ (myPackageName != null ? " \"" + myPackageName + "\"" : "")); + myForPackageRadio.setMnemonic('p'); + gbConstraints.gridy++; + gbConstraints.insets = new Insets(0,0,0,0); + panel.add(myForPackageRadio, gbConstraints); + + myIncludeSubpackagesCheckBox = new JCheckBox("Include subpackages"); + gbConstraints.gridy++; + gbConstraints.insets = new Insets(0,20,0,0); + panel.add(myIncludeSubpackagesCheckBox, gbConstraints); + + + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myForProjectRadio); + buttonGroup.add(myForPackageRadio); + + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + myIncludeSubpackagesCheckBox.setEnabled(myForPackageRadio.isSelected()); + } + }; + + myForProjectRadio.addActionListener(actionListener); + myForPackageRadio.addActionListener(actionListener); + + return panel; + } + + protected JComponent createCenterPanel() { + JPanel pane = new JPanel(new BorderLayout()); + pane.setBorder(IdeBorderFactory.createTitledBorder("Settings")); + pane.add(myConfigurable.createComponent(), BorderLayout.CENTER); + return pane; + } + + void reset() { + myForPackageRadio.setEnabled(myPackageName != null); + myForPackageRadio.setSelected(myPackageName != null); + myForProjectRadio.setEnabled(true); + myForProjectRadio.setSelected(myPackageName == null); + myIncludeSubpackagesCheckBox.setSelected(myPackageName != null); + myIncludeSubpackagesCheckBox.setEnabled(myPackageName != null && myForPackageRadio.isSelected()); + } + + boolean isGenerationForProject() { + return myForProjectRadio.isSelected(); + } + + boolean isGenerationForPackage() { + return myForPackageRadio.isSelected(); + } + + boolean isGenerationWithSubpackages() { + return isGenerationForPackage() && myIncludeSubpackagesCheckBox.isSelected(); + } + + protected void doOKAction() { + if (checkOutputDirectory(myConfigurable.getOutputDir())) { + myConfigurable.apply(); + close(OK_EXIT_CODE); + } + } + + private boolean checkOutputDirectory(String outputDirectory) { + if (outputDirectory == null || outputDirectory.trim().length() == 0) { + Messages.showMessageDialog(myProject, "Output directory is not specified.", "Error", Messages.getErrorIcon()); + return false; + } + + File outputDir = new File(outputDirectory); + if (!outputDir.exists()){ + int choice = Messages.showOkCancelDialog( + myProject, + "Output directory \"" + outputDirectory + "\" does not exist\nDo you want to create it?", + "JavaDoc", + Messages.getWarningIcon() + ); + if (choice != 0) return false; + if (!outputDir.mkdirs()){ + Messages.showMessageDialog( + myProject, + "Creation of \"" + outputDirectory + "\" failed.", + "Error", + Messages.getErrorIcon() + ); + return false; + } + } + else if (!outputDir.isDirectory()){ + Messages.showMessageDialog( + myProject, + "\"" + outputDirectory + "\" is not a directory.", + "Error", + Messages.getErrorIcon() + ); + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfigurable.java new file mode 100644 index 00000000000..e2327994e35 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfigurable.java @@ -0,0 +1,140 @@ +package com.intellij.javadoc; + +import com.intellij.openapi.options.Configurable; + +import javax.swing.*; +import java.io.File; + +final class JavadocConfigurable implements Configurable { + private JavadocGenerationPanel myPanel; + private JavadocConfiguration myConfiguration; + + public JavadocConfigurable(JavadocConfiguration configuration) { + myConfiguration = configuration; + } + + public JComponent createComponent() { + myPanel = new JavadocGenerationPanel(); + return myPanel.myPanel; + } + + public void applyTo(JavadocConfiguration configuration) { + final JavadocConfiguration javadocConfiguration = configuration; + javadocConfiguration.OUTPUT_DIRECTORY = toSystemIndependentFormat(myPanel.myTfOutputDir.getText()); + javadocConfiguration.OTHER_OPTIONS = convertString(myPanel.myOtherOptionsField.getText()); + javadocConfiguration.HEAP_SIZE = convertString(myPanel.myHeapSizeField.getText()); + javadocConfiguration.OPEN_IN_BROWSER = myPanel.myOpenInBrowserCheckBox.isSelected(); + javadocConfiguration.OPTION_SCOPE = convertString(myPanel.getScope()); + javadocConfiguration.OPTION_HIERARCHY = myPanel.myHierarchy.isSelected(); + javadocConfiguration.OPTION_NAVIGATOR = myPanel.myNavigator.isSelected(); + javadocConfiguration.OPTION_INDEX = myPanel.myIndex.isSelected(); + javadocConfiguration.OPTION_SEPARATE_INDEX = myPanel.mySeparateIndex.isSelected(); + javadocConfiguration.OPTION_DOCUMENT_TAG_USE = myPanel.myTagUse.isSelected(); + javadocConfiguration.OPTION_DOCUMENT_TAG_AUTHOR = myPanel.myTagAuthor.isSelected(); + javadocConfiguration.OPTION_DOCUMENT_TAG_VERSION = myPanel.myTagVersion.isSelected(); + javadocConfiguration.OPTION_DOCUMENT_TAG_DEPRECATED = myPanel.myTagDeprecated.isSelected(); + javadocConfiguration.OPTION_DEPRECATED_LIST = myPanel.myDeprecatedList.isSelected(); + } + + public void loadFrom(JavadocConfiguration configuration) { + final JavadocConfiguration javadocConfiguration = configuration; + myPanel.myTfOutputDir.setText(toUserSystemFormat(javadocConfiguration.OUTPUT_DIRECTORY)); + myPanel.myOtherOptionsField.setText(javadocConfiguration.OTHER_OPTIONS); + myPanel.myHeapSizeField.setText(javadocConfiguration.HEAP_SIZE); + myPanel.myOpenInBrowserCheckBox.setSelected(javadocConfiguration.OPEN_IN_BROWSER); + myPanel.setScope(javadocConfiguration.OPTION_SCOPE); + myPanel.myHierarchy.setSelected(javadocConfiguration.OPTION_HIERARCHY); + myPanel.myNavigator.setSelected(javadocConfiguration.OPTION_NAVIGATOR); + myPanel.myIndex.setSelected(javadocConfiguration.OPTION_INDEX); + myPanel.mySeparateIndex.setSelected(javadocConfiguration.OPTION_SEPARATE_INDEX); + myPanel.myTagUse.setSelected(javadocConfiguration.OPTION_DOCUMENT_TAG_USE); + myPanel.myTagAuthor.setSelected(javadocConfiguration.OPTION_DOCUMENT_TAG_AUTHOR); + myPanel.myTagVersion.setSelected(javadocConfiguration.OPTION_DOCUMENT_TAG_VERSION); + myPanel.myTagDeprecated.setSelected(javadocConfiguration.OPTION_DOCUMENT_TAG_DEPRECATED); + myPanel.myDeprecatedList.setSelected(javadocConfiguration.OPTION_DEPRECATED_LIST); + + myPanel.mySeparateIndex.setEnabled(myPanel.myIndex.isSelected()); + myPanel.myDeprecatedList.setEnabled(myPanel.myTagDeprecated.isSelected()); + } + + public boolean isModified() { + boolean isModified; + + final JavadocConfiguration configuration = myConfiguration; + isModified = !compareStrings(myPanel.myTfOutputDir.getText(), toUserSystemFormat(configuration.OUTPUT_DIRECTORY)); + isModified |= !compareStrings(myPanel.myOtherOptionsField.getText(), configuration.OTHER_OPTIONS); + isModified |= !compareStrings(myPanel.myHeapSizeField.getText(), configuration.HEAP_SIZE); + isModified |= myPanel.myOpenInBrowserCheckBox.isSelected() != configuration.OPEN_IN_BROWSER; + isModified |= !compareStrings(myPanel.getScope(), (configuration.OPTION_SCOPE == null ? "protected" : configuration.OPTION_SCOPE)); + isModified |= myPanel.myHierarchy.isSelected() != configuration.OPTION_HIERARCHY; + isModified |= myPanel.myNavigator.isSelected() != configuration.OPTION_NAVIGATOR; + isModified |= myPanel.myIndex.isSelected() != configuration.OPTION_INDEX; + isModified |= myPanel.mySeparateIndex.isSelected() != configuration.OPTION_SEPARATE_INDEX; + isModified |= myPanel.myTagUse.isSelected() != configuration.OPTION_DOCUMENT_TAG_USE; + isModified |= myPanel.myTagAuthor.isSelected() != configuration.OPTION_DOCUMENT_TAG_AUTHOR; + isModified |= myPanel.myTagVersion.isSelected() != configuration.OPTION_DOCUMENT_TAG_VERSION; + isModified |= myPanel.myTagDeprecated.isSelected() != configuration.OPTION_DOCUMENT_TAG_DEPRECATED; + isModified |= myPanel.myDeprecatedList.isSelected() != configuration.OPTION_DEPRECATED_LIST; + + return isModified; + } + + public final void apply() { + applyTo(myConfiguration); + } + + public void reset() { + loadFrom(myConfiguration); + } + + private static boolean compareStrings(String string1, String string2) { + if (string1 == null) { + string1 = ""; + } + if (string2 == null) { + string2 = ""; + } + return string1.equals(string2); + } + + public void disposeUIResources() { + myPanel = null; + } + + private static String convertString(String s) { + if (s != null && s.trim().length() == 0) { + return null; + } + return s; + } + + private static String toSystemIndependentFormat(String directory) { + if (directory.length() == 0) { + return null; + } + return directory.replace(File.separatorChar, '/'); + } + + private static String toUserSystemFormat(String directory) { + if (directory == null) { + return ""; + } + return directory.replace('/', File.separatorChar); + } + + public String getDisplayName() { + return null; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return "project.propJavaDoc"; + } + + public String getOutputDir() { + return myPanel.myTfOutputDir.getText(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfiguration.java new file mode 100644 index 00000000000..4daca8fb1c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocConfiguration.java @@ -0,0 +1,315 @@ +package com.intellij.javadoc; + +import com.intellij.execution.CantRunException; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.RegexpFilter; +import com.intellij.execution.filters.TextConsoleBuidlerFactory; +import com.intellij.execution.filters.TextConsoleBuilder; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessTerminatedListener; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ex.PathUtilEx; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.ProjectRootsTraversing; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.util.PathUtil; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Eugene Zhuravlev + * Date: Apr 24, 2004 + */ +public class JavadocConfiguration implements RunProfile, JDOMExternalizable{ + public String OUTPUT_DIRECTORY; + public String OPTION_SCOPE = "protected"; + public boolean OPTION_HIERARCHY = true; + public boolean OPTION_NAVIGATOR = true; + public boolean OPTION_INDEX = true; + public boolean OPTION_SEPARATE_INDEX = true; + public boolean OPTION_DOCUMENT_TAG_USE = false; + public boolean OPTION_DOCUMENT_TAG_AUTHOR = false; + public boolean OPTION_DOCUMENT_TAG_VERSION = false; + public boolean OPTION_DOCUMENT_TAG_DEPRECATED = true; + public boolean OPTION_DEPRECATED_LIST = true; + public String OTHER_OPTIONS = ""; + public String HEAP_SIZE; + public boolean OPEN_IN_BROWSER = true; + + private final Project myProject; + private GenerationOptions myGenerationOptions; + + public static final class GenerationOptions { + public final String packageFQName; + public final PsiDirectory directoryFrom; + public final boolean isGenerationForPackage; + public final boolean isGenerationWithSubpackages; + + public GenerationOptions(String packageFQName, PsiDirectory directory, boolean generationForPackage, boolean generationWithSubpackages) { + this.packageFQName = packageFQName; + this.directoryFrom = directory; + isGenerationForPackage = generationForPackage; + isGenerationWithSubpackages = generationWithSubpackages; + } + } + + public void setGenerationOptions(GenerationOptions generationOptions) { + myGenerationOptions = generationOptions; + } + + public JavadocConfiguration(Project project) { + myProject = project; + } + + public RunProfileState getState(DataContext context, + RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + return new MyJavaCommandLineState(myProject, myGenerationOptions); + } + + public String getName() { + return "Javadoc"; + } + + public void checkConfiguration() throws RuntimeConfigurationException { + if (myGenerationOptions == null) { + throw new RuntimeConfigurationError("Generation options for javadoc not specified"); + } + } + + public JavadocConfigurable createConfigurable() { + return new JavadocConfigurable(this); + } + + public Module[] getModules() { + return null; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + private class MyJavaCommandLineState extends CommandLineState { + private final GenerationOptions myGenerationOptions; + private final Project myProject; + + public MyJavaCommandLineState(Project project, GenerationOptions generationOptions) { + super(null, null); + myGenerationOptions = generationOptions; + myProject = project; + TextConsoleBuilder builder = TextConsoleBuidlerFactory.getInstance().createBuilder(project); + builder.addFilter(new RegexpFilter(project, "$FILE_PATH$:$LINE$:[^\\^]+\\^")); + builder.addFilter(new RegexpFilter(project, "$FILE_PATH$:$LINE$: warning - .+$")); + setConsoleBuilder(builder); + } + + protected GeneralCommandLine createCommandLine() throws ExecutionException { + final GeneralCommandLine cmdLine = new GeneralCommandLine(); + final ProjectJdk jdk = PathUtilEx.getAnyJdk(myProject); + setupExeParams(jdk, cmdLine); + setupProgramParameters(cmdLine); + return cmdLine; + } + + + private void setupExeParams(final ProjectJdk jdk, GeneralCommandLine cmdLine) throws ExecutionException { + final String jdkPath = jdk != null? PathUtil.getLocalPath(jdk.getHomeDirectory()) : null; + if (jdkPath == null) { + throw new CantRunException("JDK path is not specified\nCannot generate JavaDoc"); + } + String versionString = jdk.getVersionString(); + if (HEAP_SIZE != null && HEAP_SIZE.trim().length() != 0) { + if (versionString.indexOf("1.1") > -1) { + cmdLine.getParametersList().prepend("-J-mx" + HEAP_SIZE + "m"); + } + else { + cmdLine.getParametersList().prepend("-J-Xmx" + HEAP_SIZE + "m"); + } + } + cmdLine.setWorkingDirectory(null); + cmdLine.setExePath(jdkPath.replace('/', File.separatorChar) + File.separator + "bin" + File.separator + (SystemInfo.isWindows ? "javadoc.exe" : "javadoc")); + } + + private void setupProgramParameters(final GeneralCommandLine cmdLine) throws CantRunException { + final ParametersList parameters = cmdLine.getParametersList(); + + if (OPTION_SCOPE != null) { + parameters.add("-" + OPTION_SCOPE); + } + + if (!OPTION_HIERARCHY) { + parameters.add("-notree"); + } + + if (!OPTION_NAVIGATOR) { + parameters.add("-nonavbar"); + } + + if (!OPTION_INDEX) { + parameters.add("-noindex"); + } + else if (OPTION_SEPARATE_INDEX) { + parameters.add("-splitindex"); + } + + if (OPTION_DOCUMENT_TAG_USE) { + parameters.add("-use"); + } + + if (OPTION_DOCUMENT_TAG_AUTHOR) { + parameters.add("-author"); + } + + if (OPTION_DOCUMENT_TAG_VERSION) { + parameters.add("-version"); + } + + if (!OPTION_DOCUMENT_TAG_DEPRECATED) { + parameters.add("-nodeprecated"); + } + else if (!OPTION_DEPRECATED_LIST) { + parameters.add("-nodeprecatedlist"); + } + + parameters.addParametersString(OTHER_OPTIONS); + + String classPath = ProjectRootsTraversing.collectRoots(myProject, ProjectRootsTraversing.PROJECT_LIBRARIES).getPathsString(); + if (classPath.length() >0) { + parameters.add("-classpath"); + parameters.add(classPath); + } + + parameters.add("-sourcepath"); + parameters.add(ProjectRootsTraversing.collectRoots(myProject, ProjectRootsTraversing.PROJECT_SOURCES).getPathsString()); + + if (OUTPUT_DIRECTORY != null) { + parameters.add("-d"); + parameters.add(OUTPUT_DIRECTORY.replace('/', File.separatorChar)); + } + + final Collection packages = new HashSet(); + ApplicationManager.getApplication().runReadAction( + new Runnable(){ + public void run() { + FileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + VirtualFile startingFile = null; + if (myGenerationOptions.isGenerationForPackage) { + if (!myGenerationOptions.isGenerationWithSubpackages) { + packages.add(myGenerationOptions.packageFQName); + return; + } + startingFile = myGenerationOptions.directoryFrom.getVirtualFile(); + } + MyContentIterator contentIterator = new MyContentIterator(myProject, packages); + if (startingFile == null) { + fileIndex.iterateContent(contentIterator); + } + else { + fileIndex.iterateContentUnderDirectory(startingFile, contentIterator); + } + } + } + ); + if (packages.size() == 0) { + throw new CantRunException("Selected package(s) contain no Java classes"); + } + parameters.addAll(new ArrayList(packages)); + } + + protected OSProcessHandler startProcess() throws ExecutionException { + final OSProcessHandler handler = super.startProcess(); + ProcessTerminatedListener.attach(handler, myProject, "\njavadoc exited with exit code $EXIT_CODE$\n"); + handler.addProcessListener(new ProcessAdapter() { + public void processTerminated(ProcessEvent event) { + if (!handler.isProcessTerminating() && OPEN_IN_BROWSER) { + String url = OUTPUT_DIRECTORY + File.separator + "index.html"; + if (new File(url).exists() && event.getExitCode() == 0) { + BrowserUtil.launchBrowser(url); + } + } + } + }); + return handler; + } + } + + private static class MyContentIterator implements ContentIterator { + private final PsiManager myPsiManager; + private final Collection myPackages; + + public MyContentIterator(Project project, Collection packages) { + myPsiManager = PsiManager.getInstance(project); + myPackages = packages; + } + + public boolean processFile(VirtualFile fileOrDir) { + if (!(fileOrDir.getFileSystem() instanceof LocalFileSystem)) { + return true; + } + final PsiDirectory directory = getPsiDirectory(fileOrDir); + if (directory == null) { + if (!StdFileTypes.JAVA.equals(FileTypeManager.getInstance().getFileTypeByFile(fileOrDir))) { + return true; + } + PsiPackage psiPackage = getPsiPackage(fileOrDir.getParent()); + if (psiPackage != null && psiPackage.getQualifiedName().length() == 0) { + myPackages.add(PathUtil.getLocalPath(fileOrDir)); + } + return true; + } + else if (!dirContainsJavaFiles(directory)) { + return true; + } + PsiPackage psiPackage = directory.getPackage(); + if (psiPackage == null) { + return true; + } + myPackages.add(psiPackage.getQualifiedName()); + return true; + } + + private PsiDirectory getPsiDirectory(VirtualFile fileOrDir) { + return fileOrDir != null ? myPsiManager.findDirectory(fileOrDir) : null; + } + + private PsiPackage getPsiPackage(VirtualFile dir) { + PsiDirectory directory = getPsiDirectory(dir); + return directory != null ? directory.getPackage() : null; + } + } + + private static boolean dirContainsJavaFiles(PsiDirectory dir) { + PsiFile[] files = dir.getFiles(); + for(int i = 0; i < files.length; i++){ + if (files[i] instanceof PsiJavaFile) { + return true; + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationManager.java new file mode 100644 index 00000000000..e92bbeaf44e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationManager.java @@ -0,0 +1,92 @@ +package com.intellij.javadoc; + +import com.intellij.ant.impl.MapDataContext; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiDirectory; +import org.jdom.Element; + +import java.awt.*; + +public final class JavadocGenerationManager implements JDOMExternalizable, ProjectComponent { + private final Project myProject; + private final JavadocConfiguration myConfiguration; + + public static JavadocGenerationManager getInstance(Project project) { + return project.getComponent(JavadocGenerationManager.class); + } + + JavadocGenerationManager(Project project) { + myProject = project; + myConfiguration = new JavadocConfiguration(project); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void generateJavadoc(final PsiDirectory directory, DataContext dataContext) { + Component component = (Component)dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT); + final String packageFQName = + directory != null && directory.getPackage() != null ? + directory.getPackage().getQualifiedName() : + null; + + final GenerateJavadocDialog dialog = new GenerateJavadocDialog(packageFQName, myProject, myConfiguration); + dialog.reset(); + dialog.show(); + if (!dialog.isOK()) { + return; + } + if (component != null) { + dataContext = DataManager.getInstance().getDataContext(component); + } + else { + dataContext = MapDataContext.singleData(DataConstants.PROJECT, myProject); + } + + myConfiguration.setGenerationOptions(new JavadocConfiguration.GenerationOptions(packageFQName, directory, dialog.isGenerationForPackage(), + dialog.isGenerationWithSubpackages())); + try { + RunStrategy.getInstance().executeDefault(myConfiguration, dataContext); + } + catch (ExecutionException e) { + ExecutionUtil.showExecutionErrorMessage(e, "Error", myProject); + } + } + + + public String getComponentName() { + return "JavadocGenerationManager"; + } + + public void readExternal(Element element) throws InvalidDataException { + myConfiguration.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + myConfiguration.writeExternal(element); + } + + public JavadocConfiguration getConfiguration() { + return myConfiguration; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationPanel.java new file mode 100644 index 00000000000..e77537d6f11 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/JavadocGenerationPanel.java @@ -0,0 +1,114 @@ +package com.intellij.javadoc; + +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.Hashtable; + +final class JavadocGenerationPanel extends JPanel { + JPanel myPanel; + TextFieldWithBrowseButton myTfOutputDir; + JTextField myOtherOptionsField; + JTextField myHeapSizeField; + private JSlider myScopeSlider; + JCheckBox myHierarchy; + JCheckBox myNavigator; + JCheckBox myIndex; + JCheckBox mySeparateIndex; + JCheckBox myTagUse; + JCheckBox myTagAuthor; + JCheckBox myTagVersion; + JCheckBox myTagDeprecated; + JCheckBox myDeprecatedList; + JCheckBox myOpenInBrowserCheckBox; + + JavadocGenerationPanel() { + myTfOutputDir.addBrowseFolderListener("Browse Output directory", null, null, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + + + myIndex.addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent e) { + mySeparateIndex.setEnabled(myIndex.isSelected()); + } + } + ); + + myTagDeprecated.addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent e) { + myDeprecatedList.setEnabled(myTagDeprecated.isSelected()); + } + } + ); + + Hashtable labelTable = new Hashtable(); + labelTable.put(new Integer(1), new JLabel("public")); + labelTable.put(new Integer(2), new JLabel("protected")); + labelTable.put(new Integer(3), new JLabel("package")); + labelTable.put(new Integer(4), new JLabel("private")); + + myScopeSlider.setMaximum(4); + myScopeSlider.setMinimum(1); + myScopeSlider.setValue(1); + myScopeSlider.setLabelTable(labelTable); + myScopeSlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); + myScopeSlider.setPreferredSize(new Dimension(80, 50)); + myScopeSlider.setPaintLabels(true); + myScopeSlider.setSnapToTicks(true); + myScopeSlider.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + handleSlider(); + } + }); + + } + private void handleSlider() { + int value = myScopeSlider.getValue(); + + Dictionary labelTable = myScopeSlider.getLabelTable(); + for (Enumeration enumeration = labelTable.keys(); enumeration.hasMoreElements();) { + Integer key = (Integer)enumeration.nextElement(); + JLabel label = (JLabel)labelTable.get(key); + label.setForeground(key.intValue() <= value ? Color.black : new Color(100, 100, 100)); + } + } + + void setScope(String scope) { + if ("public".equals(scope)) { + myScopeSlider.setValue(1); + } + else if ("package".equals(scope)) { + myScopeSlider.setValue(3); + } + else if ("private".equals(scope)) { + myScopeSlider.setValue(4); + } + else { + myScopeSlider.setValue(2); + } + handleSlider(); + } + + String getScope() { + switch (myScopeSlider.getValue()) { + case 1: + return "public"; + case 2: + return "protected"; + case 3: + return "package"; + case 4: + return "private"; + default: + return null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/actions/GenerateJavadocAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/actions/GenerateJavadocAction.java new file mode 100644 index 00000000000..4ac9c01cd90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/javadoc/actions/GenerateJavadocAction.java @@ -0,0 +1,51 @@ +package com.intellij.javadoc.actions; + +import com.intellij.javadoc.JavadocGenerationManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; + +public final class GenerateJavadocAction extends AnAction{ + + public void actionPerformed(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final PsiDirectory dir = getDirectoryFromContext(dataContext); + JavadocGenerationManager.getInstance(project).generateJavadoc(dir, dataContext); + } + + public void update(AnActionEvent event){ + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(event.getDataContext().getData(DataConstants.PROJECT) != null); + } + + private static PsiDirectory getDirectoryFromContext(final DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + final Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + if (editor != null){ + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile != null) return psiFile.getContainingDirectory(); + } else { + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + if (element != null) { + if (element instanceof PsiDirectory) return (PsiDirectory)element; + else{ + PsiFile psiFile = element.getContainingFile(); + if (psiFile != null) return psiFile.getContainingDirectory(); + } + } else { + //This is the case with GUI designer + VirtualFile virtualFile = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + if (virtualFile != null && virtualFile.isValid()) { + PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); + if (psiFile != null) return psiFile.getContainingDirectory(); + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/jsp/impl/TldTagDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/jsp/impl/TldTagDescriptor.java new file mode 100644 index 00000000000..823318ae4ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/jsp/impl/TldTagDescriptor.java @@ -0,0 +1,141 @@ +package com.intellij.jsp.impl; + +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.util.XmlUtil; +import com.intellij.psi.xml.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.j2ee.openapi.impl.ExternalResourceManagerImpl; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Jan 11, 2005 + * Time: 8:55:41 PM + * To change this template use File | Settings | File Templates. + */ +public class TldTagDescriptor implements XmlElementDescriptor { + private XmlTag myTag; + private String myName; + private XmlAttributeDescriptor[] myAttributeDescriptors; + private TldDescriptor myNsDescriptor; + + public TldTagDescriptor() {} + + public TldTagDescriptor(XmlTag tag) { + init(tag); + } + + public String getQualifiedName() { + return getName(); + } + + public String getDefaultName() { + return getName(); + } + + //todo: refactor to support full DTD spec + public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { + return new XmlElementDescriptor[0]; + } + + public XmlElementDescriptor getElementDescriptor(XmlTag childTag) { + return null; + } + + public XmlAttributeDescriptor[] getAttributesDescriptors() { + if (myAttributeDescriptors==null) { + final XmlTag[] subTags = myTag.findSubTags("attribute", null); + myAttributeDescriptors = new XmlAttributeDescriptor[subTags.length]; + + for (int i = 0; i < subTags.length; i++) { + myAttributeDescriptors[i] = new TldAttributeDescriptor(subTags[i]); + } + } + return myAttributeDescriptors; + } + + public XmlAttributeDescriptor getAttributeDescriptor(String attributeName) { + final XmlAttributeDescriptor[] attributesDescriptors = getAttributesDescriptors(); + + for (int i = 0; i < attributesDescriptors.length; i++) { + final XmlAttributeDescriptor attributesDescriptor = attributesDescriptors[i]; + + if (attributesDescriptor.getName().equals(attributeName)) { + return attributesDescriptor; + } + } + return null; + } + + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) { + return getAttributeDescriptor(attribute.getName()); + } + + public XmlNSDescriptor getNSDescriptor() { + if (myNsDescriptor==null) { + final PsiFile file = myTag.getContainingFile(); + if(!(file instanceof XmlFile)) return null; + final XmlDocument document = ((XmlFile)file).getDocument(); + myNsDescriptor = (TldDescriptor) document.getMetaData(); + } + + return myNsDescriptor; + } + + public int getContentType() { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + + public PsiElement getDeclaration() { + return myTag; + } + + public boolean processDeclarations(PsiElement context, + PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastElement, + PsiElement place) { + return true; + } + + public String getName(PsiElement context) { + String value = getName(); + + if(context instanceof XmlElement){ + final XmlTag tag = PsiTreeUtil.getParentOfType(context, XmlTag.class, false); + + if(tag != null){ + final String namespacePrefix = tag.getPrefixByNamespace( ((TldDescriptor)getNSDescriptor()).getUri() ); + if(namespacePrefix != null && namespacePrefix.length() > 0) + value = namespacePrefix + ":" + XmlUtil.findLocalNameByQualifiedName(value); + } + } + + return value; + } + + public String getName() { + if (myName == null) { + final XmlTag firstSubTag = myTag.findFirstSubTag("name"); + myName = (firstSubTag!=null)?firstSubTag.getValue().getText():null; + } + return myName; + } + + public void init(PsiElement element) { + if (myTag!=element && myTag!=null) { + myNsDescriptor = null; + } + myTag = (XmlTag)element; + } + + public Object[] getDependences() { + return new Object[]{myTag, ExternalResourceManagerImpl.getInstance()}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/BaseHtmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/BaseHtmlLexer.java new file mode 100644 index 00000000000..cc50eedd2ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/BaseHtmlLexer.java @@ -0,0 +1,214 @@ +package com.intellij.lexer; + +import com.intellij.psi.impl.source.parsing.ParseUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +import java.util.HashMap; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Oct 7, 2004 + * Time: 2:29:06 PM + * To change this template use File | Settings | File Templates. + */ +abstract class BaseHtmlLexer implements Lexer { + private Lexer baseLexer; + protected static final int BASE_STATE_MASK = 0xF; + private static final int SEEN_STYLE = 0x10; + private static final int SEEN_TAG = 0x20; + private static final int SEEN_SCRIPT = 0x40; + private static final int SEEN_ATTRIBUTE = 0x80; + protected static final int BASE_STATE_SHIFT = 8; + + private boolean seenTag; + private boolean seenAttribute; + private boolean seenStyle; + private boolean seenScript; + private boolean caseInsensitive; + + interface TokenHandler { + void handleElement(Lexer lexer); + } + + class XmlNameHandler implements TokenHandler { + + public void handleElement(Lexer lexer) { + final char ch = lexer.getBuffer()[lexer.getTokenStart()]; + + if (ch!='s' && ch!='o' && + (!caseInsensitive || (ch!='S' && ch!='O') ) + ) { + return; // optimization + } + + String name = ParseUtil.getTokenText(lexer); + if (caseInsensitive) name = name.toLowerCase(); + + boolean style = name.equals("style"); + boolean script = name.equals("script") || name.startsWith("on"); + + if (style || script) { + // encountered tag name in end of tag + if (seenTag) { + seenTag = false; + return; + } + + seenStyle = style; + seenScript = script; + + final int state = getState() & BASE_STATE_MASK; + + if (!isHtmlTagState(state)) { + seenAttribute=true; + } + } else if (seenAttribute) { + seenStyle = false; // does this is valid branch? + seenScript = false; + seenAttribute=false; + } + } + } + + class XmlAttributeValueEndHandler implements TokenHandler { + public void handleElement(Lexer lexer) { + if (seenAttribute) { + seenStyle = false; + seenScript = false; + } + } + } + + class XmlTagClosedHandler implements TokenHandler { + public void handleElement(Lexer lexer) { + if (seenAttribute) { + seenScript=false; + seenStyle=false; + + seenAttribute=false; + } else { + if (seenStyle || seenScript) { + seenTag=true; + } + } + } + } + + class XmlTagEndHandler implements TokenHandler { + public void handleElement(Lexer lexer) { + seenStyle=false; + seenScript=false; + } + } + + private HashMap tokenHandlers = new HashMap(); + + protected BaseHtmlLexer(Lexer _baseLexer, boolean _caseInsensitive) { + baseLexer = _baseLexer; + caseInsensitive = _caseInsensitive; + + XmlNameHandler value = new XmlNameHandler(); + tokenHandlers.put(XmlTokenType.XML_NAME,value); + tokenHandlers.put(XmlTokenType.XML_TAG_NAME,value); + tokenHandlers.put(XmlTokenType.XML_TAG_END,new XmlTagClosedHandler()); + tokenHandlers.put(XmlTokenType.XML_END_TAG_START,new XmlTagEndHandler()); + tokenHandlers.put(XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER,new XmlAttributeValueEndHandler()); + } + + protected void registerHandler(IElementType elementType, TokenHandler value) { + tokenHandlers.put(elementType,value); + } + + public void start(char[] buffer) { + start(buffer,0, buffer.length); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + start(buffer,startOffset,endOffset,0); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + seenScript = (initialState & SEEN_SCRIPT)!=0; + seenStyle = (initialState & SEEN_STYLE)!=0; + seenTag = (initialState & SEEN_TAG)!=0; + seenAttribute = (initialState & SEEN_ATTRIBUTE)!=0; + + baseLexer.start(buffer, startOffset, endOffset, initialState & BASE_STATE_MASK); + } + + public void advance() { + baseLexer.advance(); + IElementType type = getTokenType(); + TokenHandler tokenHandler = tokenHandlers.get(type); + if (tokenHandler!=null) tokenHandler.handleElement(this); + } + + public char[] getBuffer() { + return baseLexer.getBuffer(); + } + + public int getBufferEnd() { + return baseLexer.getBufferEnd(); + } + + public int getSmartUpdateShift() { + return baseLexer.getSmartUpdateShift(); + } + + public Object clone() { + try { + BaseHtmlLexer clone = (BaseHtmlLexer)super.clone(); + clone.baseLexer = (Lexer)baseLexer.clone(); + } + catch (CloneNotSupportedException e) { + } + return null; + } + + public IElementType getTokenType() { + return baseLexer.getTokenType(); + } + + public int getTokenStart() { + return baseLexer.getTokenStart(); + } + + public int getTokenEnd() { + return baseLexer.getTokenEnd(); + } + + public int getLastState() { + return baseLexer.getLastState() << 4; + } + + public int getState() { + int state = baseLexer.getState(); + + state |= ((seenScript)?SEEN_SCRIPT:0); + state |= ((seenTag)?SEEN_TAG:0); + state |= ((seenStyle)?SEEN_STYLE:0); + state |= ((seenAttribute)?SEEN_ATTRIBUTE:0); + + return state; + } + + protected final boolean hasSeenStyle() { + return seenStyle; + } + + protected final boolean hasSeenAttribute() { + return seenAttribute; + } + + protected final boolean hasSeenTag() { + return seenTag; + } + + protected boolean hasSeenScript() { + return seenScript; + } + + protected abstract boolean isHtmlTagState(int state); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/DtdHighlightingLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/DtdHighlightingLexer.java new file mode 100644 index 00000000000..820cfba1788 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/DtdHighlightingLexer.java @@ -0,0 +1,96 @@ +package com.intellij.lexer; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +/** + * @author mike + */ +public class DtdHighlightingLexer implements Lexer { + private static final Logger LOG = Logger.getInstance("#com.intellij.lexer.XmlHighlightingLexer"); + + private Lexer myLexer; + + public DtdHighlightingLexer() { + myLexer = new OldXmlLexer(); + } + + public void advance() { + myLexer.advance(); + } + + public Object clone() { + try { + DtdHighlightingLexer lexer = (DtdHighlightingLexer)super.clone(); + lexer.myLexer = (XmlLexer)myLexer.clone(); + return lexer; + } + catch (CloneNotSupportedException e) { + LOG.error(e); + return null; + } + } + + public char[] getBuffer() { + return myLexer.getBuffer(); + } + + public int getBufferEnd() { + return myLexer.getBufferEnd(); + } + + public int getSmartUpdateShift() // number of characters to shift back from the change start to reparse + { + return myLexer.getSmartUpdateShift(); + } + + public int getState() { + return myLexer.getState(); + } + + public int getLastState() { + return myLexer.getLastState(); + } + + public int getTokenEnd() { + return myLexer.getTokenEnd(); + } + + public int getTokenStart() { + return myLexer.getTokenStart(); + } + + public IElementType getTokenType() { + IElementType tokenType = myLexer.getTokenType(); + + if (tokenType == null) return tokenType; + + if (tokenType != XmlTokenType.XML_COMMENT_CHARACTERS && + tokenType != XmlTokenType.XML_COMMENT_END && + tokenType != XmlTokenType.XML_COMMENT_START && + tokenType != XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER) { + + // TODO: do not know when this happens! + switch (getState()) { + case _XmlLexer.DOCTYPE: + tokenType = XmlTokenType.XML_DECL_START; + break; + } + } + + return tokenType; + } + + public void start(char[] buffer) { + myLexer.start(buffer); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + myLexer.start(buffer, startOffset, endOffset); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myLexer.start(buffer, startOffset, endOffset, initialState); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/EscapedJavaLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/EscapedJavaLexer.java new file mode 100644 index 00000000000..f0db55545c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/EscapedJavaLexer.java @@ -0,0 +1,157 @@ + +package com.intellij.lexer; + +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * Used to process scriptlet code in JSP attribute values like this: + * attribute="<%=texts.get(\"Blabla\")%>" + */ +public class EscapedJavaLexer implements Lexer, Cloneable{ + private char mySurroundingQuote; + private JavaLexer myJavaLexer; + + private char[] myBuffer; + private int myBufferEnd; + private int myCurOffset; + private IElementType myTokenType = null; + private int myTokenEnd; + private static final int END_STATE = 10; + + public EscapedJavaLexer(char surroundingQuote, LanguageLevel languageLevel) { + mySurroundingQuote = surroundingQuote; + myJavaLexer = new JavaLexer(languageLevel); + } + + public char getSurroundingQuote() { + return mySurroundingQuote; + } + + public void setSurroundingQuote(char surroundingQuote) { + mySurroundingQuote = surroundingQuote; + } + + public Object clone() { + try{ + EscapedJavaLexer clone = (EscapedJavaLexer)super.clone(); + clone.myJavaLexer = (JavaLexer)clone.myJavaLexer.clone(); + return clone; + } + catch(CloneNotSupportedException e){ + return null; + } + } + + public void start(char[] buffer) { + start(buffer, 0, buffer.length); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + myBuffer = buffer; + myCurOffset = startOffset; + myTokenEnd = startOffset; + myBufferEnd = endOffset; + myTokenType = null; + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + start(buffer, 0, buffer.length); + } + + public int getState() { + return 0; + } + + public int getLastState() { + return 0; + } + + public IElementType getTokenType() { + locateToken(); + return myTokenType; + } + + public final int getTokenStart(){ + locateToken(); + return myCurOffset; + } + + public final int getTokenEnd(){ + locateToken(); + return myTokenEnd; + } + + public final void advance(){ + locateToken(); + myTokenType = null; + myCurOffset = myTokenEnd; + } + + public final char[] getBuffer(){ + return myBuffer; + } + + public final int getBufferEnd(){ + return myBufferEnd; + } + + public int getSmartUpdateShift() { + return myJavaLexer.getSmartUpdateShift(); + } + + private void locateToken(){ + if (myTokenType != null) return; + if (myCurOffset >= myBufferEnd) return; + + int state = 0; // 0 -- start/end + // 1 -- start of escape in the string start + // 2 -- escape start inside string + // 3 -- inside string + // 4 -- error + int offset = myCurOffset; + do{ + char c = myBuffer[offset]; + switch(c){ + case '\\': + state += state % 2 == 0 ? 1 : -1; + if(state % 5 == 0) state = 4; + case '"': + case '\'': + if((state == 1 || state == 2) && c == mySurroundingQuote){ + state = 6 - state * 3 ; + offset++; + break; + } + default: + offset+=state > 0 ? 1 : 0; + break; + case '\n': + case '\r': + state = 0; // break string at the end of line + //offset++; + break; + } + if(offset == myBufferEnd - 1) state = 0; + switch (state){ + case 0: + if(offset == myCurOffset){ + myJavaLexer.start(myBuffer, myCurOffset, myBufferEnd); + myTokenType = myJavaLexer.getTokenType(); + myTokenEnd = myJavaLexer.getTokenEnd(); + } + else { + myTokenType = myTokenType = mySurroundingQuote == '"' ? JavaTokenType.STRING_LITERAL : JavaTokenType.CHARACTER_LITERAL; + myTokenEnd = offset; + } + break; + case 4: + myTokenType = JavaTokenType.BAD_CHARACTER; + myTokenEnd = offset; + state = 0; + } + } + while (state > 0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlHighlightingLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlHighlightingLexer.java new file mode 100644 index 00000000000..05eae1fe4fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlHighlightingLexer.java @@ -0,0 +1,182 @@ +package com.intellij.lexer; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.diagnostic.Logger; + +public class HtmlHighlightingLexer extends BaseHtmlLexer { + private static final Logger LOG = Logger.getInstance("#com.intellij.lexer.HtmlHighlightingLexer"); + + private static final TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{ + XmlTokenType.XML_COMMENT_CHARACTERS, + XmlTokenType.XML_WHITE_SPACE, + XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, + }); + + private static final int EMBEDDED_LEXER_ON = 0x1 << BASE_STATE_SHIFT; + private static final int EMBEDDED_LEXER_STATE_SHIFT = BASE_STATE_SHIFT + 1; + + private Lexer embeddedLexer; + private Lexer styleLexer; + private Lexer scriptLexer; + private boolean hasNoEmbeddments; + private static FileType ourStyleFileType; + private static FileType ourScriptFileType; + private static final int MAX_EMBEDDED_LEXER_STATE = 16; + private static final int MAX_EMBEDDED_LEXER_SHIFT = 4; + + // Handles following + class XmlEmbeddmentHandler implements TokenHandler { + public void handleElement(Lexer lexer) { + if (!hasSeenStyle() && !hasSeenScript() || hasNoEmbeddments) return; + final IElementType tokenType = lexer.getTokenType(); + + if ((tokenType==XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN && hasSeenAttribute()) || + (tokenType==XmlTokenType.XML_DATA_CHARACTERS && hasSeenTag()) || + tokenType==XmlTokenType.XML_COMMENT_CHARACTERS && hasSeenTag() + ) { + setEmbeddedLexer(); + } + } + } + + public HtmlHighlightingLexer() { + this(new _HtmlLexer(),true); + } + + protected HtmlHighlightingLexer(Lexer lexer, boolean caseInsensitive) { + super(new MergingLexerAdapter(lexer,TOKENS_TO_MERGE),caseInsensitive); + + XmlEmbeddmentHandler value = new XmlEmbeddmentHandler(); + registerHandler(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN,value); + registerHandler(XmlTokenType.XML_DATA_CHARACTERS,value); + registerHandler(XmlTokenType.XML_COMMENT_CHARACTERS,value); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + super.start(buffer, startOffset, endOffset, initialState); + + if ((initialState & EMBEDDED_LEXER_ON)!=0) { + int state = initialState >> EMBEDDED_LEXER_STATE_SHIFT; + LOG.assertTrue(hasSeenStyle() || hasSeenScript()); + setEmbeddedLexer(); + embeddedLexer.start(buffer,startOffset,endOffset,state); + } else { + embeddedLexer = null; + } + } + + private void setEmbeddedLexer() { + Lexer newLexer = null; + if (hasSeenStyle()) { + if (styleLexer==null) { + styleLexer = (ourStyleFileType!=null)? ourStyleFileType.getHighlighter(null).getHighlightingLexer():null; + if (styleLexer!=null) { + LOG.assertTrue(styleLexer.getLastState() < MAX_EMBEDDED_LEXER_STATE); + } + } + + newLexer = styleLexer; + } else if (hasSeenScript()) { + if (scriptLexer==null) { + scriptLexer = (ourScriptFileType!=null)? ourScriptFileType.getHighlighter(null).getHighlightingLexer():null; + if (scriptLexer!=null) { + LOG.assertTrue(scriptLexer.getLastState() < MAX_EMBEDDED_LEXER_STATE); + } + } + newLexer = scriptLexer; + } + + if (newLexer!=null) { + embeddedLexer = newLexer; + embeddedLexer.start( + getBuffer(), + HtmlHighlightingLexer.super.getTokenStart(), + HtmlHighlightingLexer.super.getTokenEnd()); + } + } + + public void advance() { + if (embeddedLexer!=null) { + embeddedLexer.advance(); + if (embeddedLexer.getTokenType()==null) { + embeddedLexer=null; + } + } + + if (embeddedLexer==null) { + super.advance(); + } + } + + public IElementType getTokenType() { + if (embeddedLexer!=null) { + return embeddedLexer.getTokenType(); + } else { + IElementType tokenType = super.getTokenType(); + + // TODO: fix no DOCTYPE highlighting + if (tokenType == null) return tokenType; + + if (tokenType==XmlTokenType.XML_NAME) { + // we need to convert single xml_name for tag name and attribute name into to separate + // lex types for the highlighting! + final int state = getState() & BASE_STATE_MASK; + + if (isHtmlTagState(state)) { + tokenType = XmlTokenType.XML_TAG_NAME; + } + } else if (tokenType == XmlTokenType.XML_WHITE_SPACE) { + tokenType = (getState()!=0)?XmlTokenType.TAG_WHITE_SPACE:XmlTokenType.XML_REAL_WHITE_SPACE; + } + return tokenType; + } + } + + public int getTokenStart() { + if (embeddedLexer!=null) { + return embeddedLexer.getTokenStart(); + } else { + return super.getTokenStart(); + } + } + + public int getTokenEnd() { + if (embeddedLexer!=null) { + return embeddedLexer.getTokenEnd(); + } else { + return super.getTokenEnd(); + } + } + + public static final void registerStyleFileType(FileType fileType) { + ourStyleFileType = fileType; + } + + public static void registerScriptFileType(FileType _scriptFileType) { + ourScriptFileType = _scriptFileType; + } + + public int getLastState() { + return super.getLastState() << (((hasNoEmbeddments)?0:MAX_EMBEDDED_LEXER_SHIFT) + 1); + } + + public int getState() { + int state = super.getState(); + + state |= ((embeddedLexer!=null)?EMBEDDED_LEXER_ON:0); + if (embeddedLexer!=null) state |= (embeddedLexer.getState() << EMBEDDED_LEXER_STATE_SHIFT); + + return state; + } + + protected boolean isHtmlTagState(int state) { + return state == _HtmlLexer.START_TAG_NAME || state == _HtmlLexer.END_TAG_NAME; + } + + public void setHasNoEmbeddments(boolean hasNoEmbeddments) { + this.hasNoEmbeddments = hasNoEmbeddments; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlLexer.java new file mode 100644 index 00000000000..0604adcd955 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/HtmlLexer.java @@ -0,0 +1,110 @@ +package com.intellij.lexer; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.psi.impl.source.tree.ElementType; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Oct 7, 2004 + * Time: 5:17:07 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlLexer extends BaseHtmlLexer { + private static IElementType styleElementType; + private static IElementType inlineStyleElementType; + + private IElementType myTokenType; + private int myTokenStart; + private int myTokenEnd; + private boolean mySkippingTokens; + + public void start(char[] buffer) { + myTokenType = null; + super.start(buffer); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + myTokenType = null; + super.start(buffer, startOffset, endOffset); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myTokenType = null; + super.start(buffer, startOffset, endOffset, initialState); + } + + public void advance() { + myTokenType = null; + super.advance(); + } + + public IElementType getTokenType() { + if (myTokenType!=null) return myTokenType; + IElementType tokenType = super.getTokenType(); + if (mySkippingTokens) return tokenType; + + myTokenStart = super.getTokenStart(); + myTokenEnd = super.getTokenEnd(); + + if (hasSeenStyle() && hasSeenTag() && styleElementType!=null && + (tokenType == XmlTokenType.XML_DATA_CHARACTERS || + tokenType == XmlTokenType.XML_COMMENT_START || + tokenType == ElementType.WHITE_SPACE + )) { + assert hasSeenTag(); + + mySkippingTokens = true; + // we need to advance till the end of tag + int lastState = 0; + int lastStart = 0; + while(hasSeenStyle()) { + lastState = super.getState(); + myTokenEnd = super.getTokenEnd(); + lastStart = super.getTokenStart(); + if (myTokenEnd == getBufferEnd()) break; + super.advance(); + } + + super.start(getBuffer(),lastStart,getBufferEnd(),lastState); + super.getTokenType(); + mySkippingTokens = false; + tokenType = styleElementType; + } else if (inlineStyleElementType!=null && tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN && hasSeenStyle() && hasSeenAttribute()) { + tokenType = inlineStyleElementType; + } + return myTokenType = tokenType; + } + + public HtmlLexer() { + this(new _HtmlLexer(),true); + } + + protected HtmlLexer(Lexer _baseLexer, boolean _caseInsensitive) { + super(_baseLexer,_caseInsensitive); + } + + public static final void setStyleElementTypes(IElementType _styleElementType,IElementType _inlineStyleElementType) { + styleElementType = _styleElementType; + inlineStyleElementType = _inlineStyleElementType; + } + + protected boolean isHtmlTagState(int state) { + return state == _HtmlLexer.START_TAG_NAME || state == _HtmlLexer.END_TAG_NAME; + } + + public int getTokenStart() { + if (myTokenType!=null) { + return myTokenStart; + } + return super.getTokenStart(); + } + + public int getTokenEnd() { + if (myTokenType!=null) { + return myTokenEnd; + } + return super.getTokenEnd(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaDocLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaDocLexer.java new file mode 100644 index 00000000000..98ca3fe479e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaDocLexer.java @@ -0,0 +1,16 @@ +package com.intellij.lexer; + +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +public class JavaDocLexer extends MergingLexerAdapter { + private static final TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{ + JavaDocTokenType.DOC_COMMENT_DATA, + JavaDocTokenType.DOC_SPACE + }); + + public JavaDocLexer() { + super(new _JavaDocLexer(), TOKENS_TO_MERGE); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaHighlightingLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaHighlightingLexer.java new file mode 100644 index 00000000000..44e1e1f403d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaHighlightingLexer.java @@ -0,0 +1,35 @@ +package com.intellij.lexer; + +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; + + +/** + * @author max + */ +public class JavaHighlightingLexer extends LayeredLexer { + public JavaHighlightingLexer(LanguageLevel languageLevel) { + super(new JavaLexer(languageLevel)); + registerSelfStoppingLayer(new StringLiteralLexer('\"'), + new IElementType[]{JavaTokenType.STRING_LITERAL}, + new IElementType[0]); + + registerSelfStoppingLayer(new StringLiteralLexer('\''), + new IElementType[]{JavaTokenType.CHARACTER_LITERAL}, + new IElementType[0]); + + + LayeredLexer docLexer = new LayeredLexer(new JavaDocLexer()); + + HtmlHighlightingLexer lexer = new HtmlHighlightingLexer(); + lexer.setHasNoEmbeddments(true); + docLexer.registerLayer(lexer, + new IElementType[]{JavaDocTokenType.DOC_COMMENT_DATA}); + + registerSelfStoppingLayer(docLexer, + new IElementType[]{JavaTokenType.DOC_COMMENT}, + new IElementType[]{JavaDocTokenType.DOC_COMMENT_END}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaLexer.java new file mode 100644 index 00000000000..b08f3fe3581 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/JavaLexer.java @@ -0,0 +1,398 @@ +package com.intellij.lexer; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +public class JavaLexer implements Lexer, Cloneable { + + private JavaLexer(boolean isAssertKeywordEnabled, boolean isJDK15, boolean escapeTokensInXml) { + myTable = isAssertKeywordEnabled ? + (isJDK15 ? ourTableWithAssertAndJDK15 : ourTableWithAssert) : + (isJDK15 ? ourTableWithJDK15 : ourTableWithoutAssert); + myJLexlexer = escapeTokensInXml ? + (Lexer)new _XmlEscapedJavaLexer(isAssertKeywordEnabled, isJDK15) : + new _JavaLexer(isAssertKeywordEnabled, isJDK15); + } + + public JavaLexer(LanguageLevel level, boolean escapeTokensInXml) { + this(level.hasAssertKeyword(), level.hasEnumKeywordAndAutoboxing(), escapeTokensInXml); + } + + public JavaLexer(LanguageLevel level) { + this(level.hasAssertKeyword(), level.hasEnumKeywordAndAutoboxing(), false); + } + + private char[] myBuffer; + private int myBufferIndex; + private int myBufferEndOffset; + IElementType myTokenType; + private Lexer myJLexlexer; + + //Positioned after the last symbol of the current token + private int myTokenEndOffset; + + private static class HashTable { + static final int NUM_ENTRIES = 9999; + private static final Logger LOG = Logger.getInstance("com.intellij.Lexer.JavaLexer"); + + char[][] myTable = new char[NUM_ENTRIES][];; + IElementType[] myKeywords = new IElementType[NUM_ENTRIES]; + + void add(String s, IElementType tokenType) { + char[] chars = s.toCharArray(); + int hashCode = chars[0] * 2; + for (int j = 1; j < chars.length; j++) { + hashCode += chars[j]; + } + int modHashCode = hashCode % NUM_ENTRIES; + LOG.assertTrue(myTable[modHashCode] == null); + + myTable[modHashCode] = chars; + myKeywords[modHashCode] = tokenType; + } + + boolean contains(int hashCode, char[] buffer, int offset, int len) { + int modHashCode = hashCode % NUM_ENTRIES; + char[] kwd = myTable[modHashCode]; + if (kwd == null) return false; + for (int j = 0; j < kwd.length; j++) { + if (buffer[j + offset] != kwd[j]) return false; + } + return true; + } + + IElementType getTokenType(int hashCode) { + return myKeywords[hashCode % NUM_ENTRIES]; + } + + public HashTable(boolean isAssertKeywordEnabled, boolean isJDK15) { + if (isAssertKeywordEnabled) { + add("assert", JavaTokenType.ASSERT_KEYWORD); + } + if (isJDK15) { + add("enum", JavaTokenType.ENUM_KEYWORD); + } + add("abstract", JavaTokenType.ABSTRACT_KEYWORD); + add("default", JavaTokenType.DEFAULT_KEYWORD); + add("if", JavaTokenType.IF_KEYWORD); + add("private", JavaTokenType.PRIVATE_KEYWORD); + add("this", JavaTokenType.THIS_KEYWORD); + add("boolean", JavaTokenType.BOOLEAN_KEYWORD); + add("do", JavaTokenType.DO_KEYWORD); + add("implements", JavaTokenType.IMPLEMENTS_KEYWORD); + add("protected", JavaTokenType.PROTECTED_KEYWORD); + add("throw", JavaTokenType.THROW_KEYWORD); + add("break", JavaTokenType.BREAK_KEYWORD); + add("double", JavaTokenType.DOUBLE_KEYWORD); + add("import", JavaTokenType.IMPORT_KEYWORD); + add("public", JavaTokenType.PUBLIC_KEYWORD); + add("throws", JavaTokenType.THROWS_KEYWORD); + add("byte", JavaTokenType.BYTE_KEYWORD); + add("else", JavaTokenType.ELSE_KEYWORD); + add("instanceof", JavaTokenType.INSTANCEOF_KEYWORD); + add("return", JavaTokenType.RETURN_KEYWORD); + add("transient", JavaTokenType.TRANSIENT_KEYWORD); + add("case", JavaTokenType.CASE_KEYWORD); + add("extends", JavaTokenType.EXTENDS_KEYWORD); + add("int", JavaTokenType.INT_KEYWORD); + add("short", JavaTokenType.SHORT_KEYWORD); + add("try", JavaTokenType.TRY_KEYWORD); + add("catch", JavaTokenType.CATCH_KEYWORD); + add("final", JavaTokenType.FINAL_KEYWORD); + add("interface", JavaTokenType.INTERFACE_KEYWORD); + add("static", JavaTokenType.STATIC_KEYWORD); + add("void", JavaTokenType.VOID_KEYWORD); + add("char", JavaTokenType.CHAR_KEYWORD); + add("finally", JavaTokenType.FINALLY_KEYWORD); + add("long", JavaTokenType.LONG_KEYWORD); + add("strictfp", JavaTokenType.STRICTFP_KEYWORD); + add("volatile", JavaTokenType.VOLATILE_KEYWORD); + add("class", JavaTokenType.CLASS_KEYWORD); + add("float", JavaTokenType.FLOAT_KEYWORD); + add("native", JavaTokenType.NATIVE_KEYWORD); + add("super", JavaTokenType.SUPER_KEYWORD); + add("while", JavaTokenType.WHILE_KEYWORD); + add("const", JavaTokenType.CONST_KEYWORD); + add("for", JavaTokenType.FOR_KEYWORD); + add("new", JavaTokenType.NEW_KEYWORD); + add("switch", JavaTokenType.SWITCH_KEYWORD); + add("continue", JavaTokenType.CONTINUE_KEYWORD); + add("goto", JavaTokenType.GOTO_KEYWORD); + add("package", JavaTokenType.PACKAGE_KEYWORD); + add("synchronized", JavaTokenType.SYNCHRONIZED_KEYWORD); + add("true", JavaTokenType.TRUE_KEYWORD); + add("false", JavaTokenType.FALSE_KEYWORD); + add("null", JavaTokenType.NULL_KEYWORD); + } + } + + private final HashTable myTable; + private final static HashTable ourTableWithoutAssert = new HashTable(false, false); + private final static HashTable ourTableWithAssert = new HashTable(true, false); + private final static HashTable ourTableWithAssertAndJDK15 = new HashTable(true, true); + private final static HashTable ourTableWithJDK15 = new HashTable(false, true); + + public final void start(char[] buffer) { + start(buffer, 0, buffer.length); + } + + public final void start(char[] buffer, int startOffset, int endOffset) { + myBuffer = buffer; + myBufferIndex = startOffset; + myBufferEndOffset = endOffset; + myTokenType = null; + myTokenEndOffset = startOffset; + } + + public final void start(char[] buffer, int startOffset, int endOffset, int initialState) { + start(buffer, startOffset, endOffset); + } + + public int getState() { + return 0; + } + + public int getLastState() { + return 0; + } + + public final IElementType getTokenType() { + locateToken(); + + return myTokenType; + } + + public final int getTokenStart() { + return myBufferIndex; + } + + public final int getTokenEnd() { + locateToken(); + return myTokenEndOffset; + } + + + public final void advance() { + locateToken(); + myTokenType = null; + } + + protected final void locateToken() { + if (myTokenType != null) return; + _locateToken(); + } + + public final void _locateToken() { + + if (myTokenEndOffset == myBufferEndOffset) { + myTokenType = null; + myBufferIndex = myBufferEndOffset; + return; + } + + myBufferIndex = myTokenEndOffset; + + char c = myBuffer[myBufferIndex]; + switch (c) { + default: + jlexLocateToken(); + break; + + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + myTokenType = JavaTokenType.WHITE_SPACE; + myTokenEndOffset = getWhitespaces(myBufferIndex + 1); + break; + + case '/': { + if (myBufferIndex + 1 >= myBufferEndOffset) { + myTokenType = JavaTokenType.DIV; + myTokenEndOffset = myBufferEndOffset; + } + else if (myBuffer[myBufferIndex + 1] == '/') { + myTokenType = JavaTokenType.END_OF_LINE_COMMENT; + myTokenEndOffset = getLineTerminator(myBufferIndex + 2); + } + else if (myBuffer[myBufferIndex + 1] == '*') { + if (myBufferIndex + 2 >= myBufferEndOffset || myBuffer[myBufferIndex + 2] != '*') { + myTokenType = JavaTokenType.C_STYLE_COMMENT; + myTokenEndOffset = getClosingComment(myBufferIndex + 2); + } + else { + myTokenType = JavaTokenType.DOC_COMMENT; + myTokenEndOffset = getDocClosingComment(myBufferIndex + 3); + } + } + else if ((c > 127) && Character.isJavaIdentifierStart(c)) { + myTokenEndOffset = getIdentifier(myBufferIndex + 1); + } + else { + jlexLocateToken(); + } + break; + } + + case '"': + case '\'': + myTokenType = c == '"' ? JavaTokenType.STRING_LITERAL : JavaTokenType.CHARACTER_LITERAL; + myTokenEndOffset = getClosingParenthesys(myBufferIndex + 1, c); + } + + if (myTokenEndOffset > myBufferEndOffset) { + myTokenEndOffset = myBufferEndOffset; + } + } + + private int getWhitespaces(int pos) { + if (pos >= myBufferEndOffset) return myBufferEndOffset; + char c = myBuffer[pos]; + + while (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f') { + pos++; + if (pos == myBufferEndOffset) return pos; + c = myBuffer[pos]; + } + + return pos; + } + + private void jlexLocateToken() { + myJLexlexer.start(myBuffer, myBufferIndex, myBufferEndOffset); + myTokenEndOffset = myJLexlexer.getTokenEnd(); + myTokenType = myJLexlexer.getTokenType(); + } + + + private int getClosingParenthesys(int offset, char c) { + int pos = offset; + if (pos >= myBufferEndOffset) return myBufferEndOffset; + char cur = myBuffer[pos]; + while (true) { + while (cur != c && cur != '\n' && cur != '\r' && cur != '\\') { + pos++; + if (pos >= myBufferEndOffset) return myBufferEndOffset; + cur = myBuffer[pos]; + } + + if (cur == '\\') { + pos += 2; + if (pos >= myBufferEndOffset) return myBufferEndOffset; + cur = myBuffer[pos]; + } else if (cur == c) { + break; + } else { + pos--; + break; + } + } + + return pos + 1; + } + + private int getDocClosingComment(int offset) { + if (offset < myBufferEndOffset && myBuffer[offset] == '/') return offset + 1; + int pos = offset; + while (pos < myBufferEndOffset - 1 && (myBuffer[pos] != '*' || myBuffer[pos + 1] != '/')) { + pos++; + } + return pos + 2; + } + + private int getClosingComment(int offset) { + int pos = offset; + + while (pos < myBufferEndOffset - 1 && (myBuffer[pos] != '*' || myBuffer[pos + 1] != '/')) pos++; + + return pos + 2; + } + + private int getLineTerminator(int offset) { + int pos = offset; + while (pos < myBufferEndOffset && myBuffer[pos] != '\n' && myBuffer[pos] != '\r') { + pos++; + } + + return pos; + } + + private int getIdentifier(int offset) { + int len = 0; + int hashCode = myBuffer[offset - 1] * 2; + + + if (offset + len < myBufferEndOffset) { + char c = myBuffer[offset + len]; + while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') + || c == '_' || c == '$' || ((c > 127) && Character.isJavaIdentifierPart(c))) { + len++; + hashCode += c; + + if (offset + len == myBufferEndOffset) break; + c = myBuffer[offset + len]; + } + } + + if (myTable.contains(hashCode, myBuffer, offset - 1, len + 1)) { + myTokenType = myTable.getTokenType(hashCode); + } else { + myTokenType = JavaTokenType.IDENTIFIER; + } + + return offset + len; + } + + public final char[] getBuffer() { + return myBuffer; + } + + public final int getBufferEnd() { + return myBufferEndOffset; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + + public static void main(String[] args) { + BufferedReader reader; + + try { + reader = new BufferedReader(new FileReader(args[0])); + String s; + StringBuffer buf = new StringBuffer(); + while ((s = reader.readLine()) != null) { + buf.append(s + "\n"); + } + + char[] cbuf = buf.toString().toCharArray(); + + JavaLexer lexer = new JavaLexer(LanguageLevel.JDK_1_5); + lexer.start(cbuf, 0, cbuf.length); + while (lexer.getTokenType() != null) { + lexer.advance(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); //To change body of catch statement use Options | File Templates. + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use Options | File Templates. + } + } + + public int getSmartUpdateShift() { + return 2; // to handle ... correctly + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/OldXmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/OldXmlLexer.java new file mode 100644 index 00000000000..fd154174406 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/OldXmlLexer.java @@ -0,0 +1,24 @@ +package com.intellij.lexer; + +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: Sep 9, 2004 + * Time: 8:27:43 PM + * To change this template use File | Settings | File Templates. + */ +public class OldXmlLexer extends MergingLexerAdapter { + private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{ + XmlTokenType.XML_DATA_CHARACTERS, + XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, + XmlTokenType.XML_PI_TARGET, + }); + + public OldXmlLexer() { + super(new _OldXmlLexer(), TOKENS_TO_MERGE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/StringLiteralLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/StringLiteralLexer.java new file mode 100644 index 00000000000..4c04037ad61 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/StringLiteralLexer.java @@ -0,0 +1,188 @@ +package com.intellij.lexer; + +import com.intellij.ide.highlighter.custom.tokens.HexNumberParser; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; + +/** + * @author max + */ +public class StringLiteralLexer implements Lexer, Cloneable { + private static final Logger LOG = Logger.getInstance("#com.intellij.lexer.StringLiteralLexer"); + + private static final short BEFORE_FIRST_QUOTE = 0; + private static final short AFTER_FIRST_QUOTE = 1; + private static final short AFTER_LAST_QUOTE = 2; + private static final short LAST_STATE = AFTER_LAST_QUOTE; + + private char[] myBuffer; + private int myStart; + private int myEnd; + private int myState; + private int myLastState; + private int myBufferEnd; + private char myQuoteChar; + + public StringLiteralLexer(char quoteChar) { + myQuoteChar = quoteChar; + } + + public void start(char[] buffer) { + start(buffer, 0, buffer.length); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myBuffer = buffer; + myStart = startOffset; + myState = initialState; + myLastState = initialState; + myBufferEnd = endOffset; + myEnd = locateToken(myStart); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + start(buffer, startOffset, endOffset, BEFORE_FIRST_QUOTE); + } + + public int getState() { + return myLastState; + } + + public int getLastState() { + return LAST_STATE; + } + + public IElementType getTokenType() { + if (myStart >= myEnd) return null; + + if (myBuffer[myStart] != '\\') return JavaTokenType.STRING_LITERAL; + + if (myStart + 1 >= myEnd) return StringEscapesTokenTypes.INVALID_STRING_ESCAPE_TOKEN; + if (myBuffer[myStart + 1] == 'u') { + for(int i = myStart + 2; i < myStart + 6; i++) { + if (i >= myEnd || !HexNumberParser.isHexDigit(myBuffer[i])) return StringEscapesTokenTypes.INVALID_STRING_ESCAPE_TOKEN; + } + return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN; + } + + switch (myBuffer[myStart + 1]) { + case 'n': + case 'r': + case 'b': + case 't': + case 'f': + case '\'': + case '\"': + case '\\': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN; + } + + return StringEscapesTokenTypes.INVALID_STRING_ESCAPE_TOKEN; + } + + public int getTokenStart() { + return myStart; + } + + public int getTokenEnd() { + return myEnd; + } + + private int locateToken(int start) { + if (start == myBufferEnd) { + myState = AFTER_LAST_QUOTE; + } + if (myState == AFTER_LAST_QUOTE) return start; + int i = start; + if (myBuffer[i] == '\\') { + LOG.assertTrue(myState == AFTER_FIRST_QUOTE); + i++; + if (i == myBufferEnd || myBuffer[i] == '\n') { + myState = AFTER_LAST_QUOTE; + return i; + } + + if (myBuffer[i] >= '0' && myBuffer[i] <= '7') { + char first = myBuffer[i]; + i++; + if (i < myBufferEnd && myBuffer[i] >= '0' && myBuffer[i] <= '7') { + i++; + if (i < myBufferEnd && first <= '3' && myBuffer[i] >= '0' && myBuffer[i] <= '7') { + i++; + } + } + return i; + } + + if (myBuffer[i] == 'u') { + i++; + for (; i < start + 6; i++) { + if (i == myBufferEnd || + myBuffer[i] == '\n' || + myBuffer[i] == myQuoteChar) { + return i; + } + } + return i; + } else { + return i + 1; + } + } else { + LOG.assertTrue(myState == AFTER_FIRST_QUOTE || myBuffer[i] == myQuoteChar); + while (i < myBufferEnd) { + if (myBuffer[i] == '\\') { + return i; + } + if (myBuffer[i] == '\n') { + myState = AFTER_LAST_QUOTE; + return i; + } + if (myState == AFTER_FIRST_QUOTE && myBuffer[i] == myQuoteChar) { + myState = AFTER_LAST_QUOTE; + return i + 1; + } + i++; + myState = AFTER_FIRST_QUOTE; + } + } + + return i; + } + + public void advance() { + myLastState = myState; + myStart = myEnd; + myEnd = locateToken(myStart); + } + + public char[] getBuffer() { + return myBuffer; + } + + public int getBufferEnd() { + return myBufferEnd; + } + + public int getSmartUpdateShift() { + return 6; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + LOG.error(e); + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlHighlightingLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlHighlightingLexer.java new file mode 100644 index 00000000000..8bfd1249b6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlHighlightingLexer.java @@ -0,0 +1,11 @@ +package com.intellij.lexer; + +public class XHtmlHighlightingLexer extends HtmlHighlightingLexer { + public XHtmlHighlightingLexer() { + super(new XmlLexer(),false); + } + + protected boolean isHtmlTagState(int state) { + return state == _XmlLexer.TAG || state == _XmlLexer.END_TAG; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlLexer.java new file mode 100644 index 00000000000..73903a7d66d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XHtmlLexer.java @@ -0,0 +1,18 @@ +package com.intellij.lexer; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Oct 7, 2004 + * Time: 5:17:07 PM + * To change this template use File | Settings | File Templates. + */ +public class XHtmlLexer extends HtmlLexer { + public XHtmlLexer() { + super(new XmlLexer(),false); + } + + protected boolean isHtmlTagState(int state) { + return state == _XmlLexer.TAG; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlHighlightingLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlHighlightingLexer.java new file mode 100644 index 00000000000..2af8fefab39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlHighlightingLexer.java @@ -0,0 +1,116 @@ +package com.intellij.lexer; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; + +/** + * @author mike + */ +public class XmlHighlightingLexer implements Lexer { + private static final Logger LOG = Logger.getInstance("#com.intellij.lexer.XmlHighlightingLexer"); + + private XmlLexer myLexer = new XmlLexer(); + + public XmlHighlightingLexer() { + } + + public void advance() { + myLexer.advance(); + } + + public Object clone() { + try { + XmlHighlightingLexer lexer = (XmlHighlightingLexer)super.clone(); + lexer.myLexer = (XmlLexer)myLexer.clone(); + return lexer; + } + catch (CloneNotSupportedException e) { + LOG.error(e); + return null; + } + } + + public char[] getBuffer() { + return myLexer.getBuffer(); + } + + public int getBufferEnd() { + return myLexer.getBufferEnd(); + } + + public int getSmartUpdateShift() // number of characters to shift back from the change start to reparse + { + return myLexer.getSmartUpdateShift(); + } + + public int getState() { + return myLexer.getState(); + } + + public int getLastState() { + return myLexer.getLastState(); + } + + public int getTokenEnd() { + return myLexer.getTokenEnd(); + } + + public int getTokenStart() { + return myLexer.getTokenStart(); + } + + public IElementType getTokenType() { + IElementType tokenType = myLexer.getTokenType(); + + if (tokenType == null) return tokenType; + + int state = getState() & 0xF; + + tokenType = fixWrongTokenTypes(tokenType, state); + if (tokenType != XmlTokenType.XML_COMMENT_CHARACTERS && + tokenType != XmlTokenType.XML_COMMENT_END && + tokenType != XmlTokenType.XML_COMMENT_START && + tokenType != XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER) { + + // TODO: do not know when this happens! + switch (state) { + case _XmlLexer.DOCTYPE: + tokenType = XmlTokenType.XML_DECL_START; + break; + } + } + + return tokenType; + } + + static IElementType fixWrongTokenTypes(IElementType tokenType, final int state) { + if (tokenType == XmlTokenType.XML_NAME) { + if (state == _XmlLexer.TAG || state == _XmlLexer.END_TAG) { + // translate XML names for tags into XmlTagName + tokenType = XmlTokenType.XML_TAG_NAME; + } + } else if (tokenType == XmlTokenType.XML_WHITE_SPACE) { + switch (state) { + case _XmlLexer.ATTR_LIST: + case _XmlLexer.ATTR: + tokenType = XmlTokenType.TAG_WHITE_SPACE; break; + default: + tokenType = XmlTokenType.XML_REAL_WHITE_SPACE; break; + } + } + return tokenType; + } + + public void start(char[] buffer) { + myLexer.start(buffer); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + myLexer.start(buffer, startOffset, endOffset); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myLexer.start(buffer, startOffset, endOffset, initialState); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlLexer.java new file mode 100644 index 00000000000..080ecf947f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/XmlLexer.java @@ -0,0 +1,17 @@ +package com.intellij.lexer; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlTokenType; + +public class XmlLexer extends MergingLexerAdapter { + private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(new IElementType[]{ + XmlTokenType.XML_DATA_CHARACTERS, + XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, + XmlTokenType.XML_PI_TARGET, + }); + + public XmlLexer() { + super(new _XmlLexer(), TOKENS_TO_MERGE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_HtmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_HtmlLexer.java new file mode 100644 index 00000000000..f850121f967 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_HtmlLexer.java @@ -0,0 +1,567 @@ +/* It's an automatically generated code. Do not modify it. */ +package com.intellij.lexer; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.*; +import com.intellij.psi.xml.*; + + +public class _HtmlLexer implements Lexer, Cloneable { + private static final int YY_F = -1; + private static final int YY_NO_STATE = -1; + private static final int YY_NOT_ACCEPT = 0; + private static final int YY_START = 1; + private static final int YY_END = 2; + private static final int YY_NO_ANCHOR = 4; + private static final char YYEOF = '\uFFFF'; + + private IElementType myTokenType; + private int myState; + public final void start(char[] buffer){ + start(buffer, 0, buffer.length); + } + public final void start(char[] buffer, int startOffset, int endOffset){ + start(buffer, startOffset, endOffset, (short)YYINITIAL); + } + public final void start(char[] buffer, int startOffset, int endOffset, int initialState){ + yy_buffer = buffer; + yy_buffer_index = startOffset; + yy_buffer_length = endOffset; + yy_lexical_state = initialState; + myTokenType = null; + myState = initialState; + } + public final int getState(){ + return myState; + } + public final int getLastState() { + return LAST_STATE; + } + public final IElementType getTokenType(){ + locateToken(); + return myTokenType; + } + public final int getTokenStart(){ + if (myTokenType != null){ + return yy_buffer_start; + } + else{ + return yy_buffer_index; + } + } + public final int getTokenEnd(){ + locateToken(); + return yy_buffer_end; + } + public final void advance(){ + locateToken(); + myTokenType = null; + myState = yy_lexical_state; + } + public final char[] getBuffer(){ + return yy_buffer; + } + public final int getBufferEnd(){ + return yy_buffer_length; + } + protected final void locateToken(){ + if (myTokenType != null) return; + _locateToken(); + } + private boolean checkAhead(String text){ + int index = yy_buffer_index; + for(int i = 0; i < text.length(); i++){ + if (index >= yy_buffer_length) return false; + if (yy_buffer[index++] != text.charAt(i)) return false; + } + return true; + } + public int getSmartUpdateShift() { + return 8; // to handle " 127){ + if (Character.isJavaIdentifierStart(yy_lookahead)){ + yy_lookahead = 'A'; + } + else if (Character.isJavaIdentifierPart(yy_lookahead)){ + yy_lookahead = '9'; + } + else{ + yy_lookahead = '#'; + } + } + } + else{ + yy_lookahead = YYEOF; + } + yy_next_state = YY_F; + if (YYEOF != yy_lookahead) { + yy_next_state = yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]]; + } + if (YY_F != yy_next_state) { + yy_state = yy_next_state; + yy_initial = false; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + } + else { + if (YYEOF == yy_lookahead && true == yy_initial) { + myTokenType = null; return; + } + else if (YY_NO_STATE == yy_last_accept_state) { + throw (new Error("Lexical Error: Unmatched Input.")); + } + else { + yy_buffer_index = yy_buffer_end; + yy_anchor = yy_acpt[yy_last_accept_state]; + if (0 != (YY_END & yy_anchor)) { + --yy_buffer_end; + } + if (0 != (YY_START & yy_anchor)) { + ++yy_buffer_start; + } + switch (yy_last_accept_state) { + case 0: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -2: + break; + case 1: + { myTokenType = XmlTokenType.XML_WHITE_SPACE; return; } + case -3: + break; + case 2: + { myTokenType = XmlTokenType.XML_START_TAG_START; yy_lexical_state = START_TAG_NAME; return; } + case -4: + break; + case 4: + { myTokenType = XmlTokenType.XML_END_TAG_START; yy_lexical_state = END_TAG_NAME; return; } + case -5: + break; + case 5: + { myTokenType = XmlTokenType.XML_COMMENT_START; yy_lexical_state = COMMENT; return; } + case -6: + break; + case 6: + { myTokenType = XmlTokenType.XML_DOCTYPE_START; yy_lexical_state = DOC_TYPE; return; } + case -7: + break; + case 7: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -8: + break; + case 8: + { myTokenType = XmlTokenType.XML_DOCTYPE_END; yy_lexical_state = YYINITIAL; return; } + case -9: + break; + case 9: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -10: + break; + case 10: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -11: + break; + case 11: + { myTokenType = XmlTokenType.XML_DOCTYPE_PUBLIC; return; } + case -12: + break; + case 12: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -13: + break; + case 13: + { myTokenType = XmlTokenType.XML_COMMENT_END; yy_lexical_state = YYINITIAL; return; } + case -14: + break; + case 14: + { myTokenType = XmlTokenType.XML_NAME; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -15: + break; + case 15: + { yy_lexical_state = YYINITIAL; --yy_buffer_index; break; } + case -16: + break; + case 16: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -17: + break; + case 17: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -18: + break; + case 18: + { yy_lexical_state = YYINITIAL; --yy_buffer_index; } + case -19: + break; + case 19: + { myTokenType = XmlTokenType.XML_EQ; yy_lexical_state = ATTRIBUTE_VALUE_START; return; } + case -20: + break; + case 20: + { myTokenType = XmlTokenType.XML_TAG_END; yy_lexical_state = YYINITIAL; return; } + case -21: + break; + case 21: + { myTokenType = XmlTokenType.XML_EMPTY_ELEMENT_END; yy_lexical_state = YYINITIAL; return; } + case -22: + break; + case 22: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -23: + break; + case 23: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = ATTRIBUTE_VALUE_DQ; return; } + case -24: + break; + case 24: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = ATTRIBUTE_VALUE_SQ; return; } + case -25: + break; + case 25: + { myTokenType = XmlTokenType.XML_TAG_END; yy_lexical_state = YYINITIAL; return; } + case -26: + break; + case 26: + { myTokenType = XmlTokenType.XML_EMPTY_ELEMENT_END; yy_lexical_state = YYINITIAL; return; } + case -27: + break; + case 27: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -28: + break; + case 28: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -29: + break; + case 29: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -30: + break; + case 30: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -31: + break; + case 31: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -32: + break; + case 32: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -33: + break; + case 33: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -34: + break; + case 34: + { myTokenType = XmlTokenType.XML_WHITE_SPACE; return; } + case -35: + break; + case 36: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -36: + break; + case 37: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -37: + break; + case 38: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -38: + break; + case 39: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -39: + break; + case 40: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -40: + break; + case 41: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -41: + break; + case 42: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -42: + break; + case 43: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -43: + break; + case 45: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -44: + break; + case 46: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -45: + break; + case 47: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -46: + break; + case 49: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -47: + break; + case 51: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -48: + break; + case 53: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -49: + break; + case 55: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -50: + break; + default: + yy_error(YY_E_INTERNAL,false); + case -1: + } + yy_initial = true; + yy_state = yy_state_dtrans[yy_lexical_state]; + yy_next_state = YY_NO_STATE; + yy_last_accept_state = YY_NO_STATE; + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_JavaLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_JavaLexer.java new file mode 100644 index 00000000000..5b780269c77 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_JavaLexer.java @@ -0,0 +1,1873 @@ +/* It's an automatically generated code. Do not modify it. */ +package com.intellij.lexer; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; + + +class _JavaLexer implements Lexer, Cloneable { + private static final int YY_F = -1; + private static final int YY_NO_STATE = -1; + private static final int YY_NOT_ACCEPT = 0; + private static final int YY_START = 1; + private static final int YY_END = 2; + private static final int YY_NO_ANCHOR = 4; + private static final char YYEOF = '\uFFFF'; + + private IElementType myTokenType; + private boolean myAssertKeywordEnabled; + private boolean myJdk15Enabled; + public _JavaLexer(boolean isAssertKeywordEnabled, boolean jdk15Enabled){ + myAssertKeywordEnabled = isAssertKeywordEnabled; + myJdk15Enabled = jdk15Enabled; + } + public final void start(char[] buffer){ + start(buffer, 0, buffer.length); + } + public final void start(char[] buffer, int startOffset, int endOffset){ + yy_buffer = buffer; + yy_buffer_index = startOffset; + yy_buffer_length = endOffset; + myTokenType = null; + } + public final void start(char[] buffer, int startOffset, int endOffset, int initialState){ + start(buffer, startOffset, endOffset); + } + public final int getState(){ + return 0; + } + public final int getLastState() { + return 0; + } + public final IElementType getTokenType(){ + locateToken(); + return myTokenType; + } + public final int getTokenStart(){ + if (myTokenType != null){ + return yy_buffer_start; + } + else{ + return yy_buffer_index; + } + } + public final int getTokenEnd(){ + locateToken(); + return yy_buffer_end; + } + public final void advance(){ + locateToken(); + myTokenType = null; + } + public final char[] getBuffer(){ + return yy_buffer; + } + public final int getBufferEnd(){ + return yy_buffer_length; + } + protected final void locateToken(){ + if (myTokenType != null) return; + _locateToken(); + } + public int getSmartUpdateShift() { + return 1; + } + public Object clone() { + try{ + return super.clone(); + } + catch(CloneNotSupportedException e){ + return null; + } + } + private int yy_buffer_index; + private int yy_buffer_start; + private int yy_buffer_end; + private char yy_buffer[]; + private int yy_buffer_length; + private int yy_lexical_state; + + public _JavaLexer () { + yy_lexical_state = YYINITIAL; + + myTokenType = null; + } + + private boolean yy_eof_done = false; + public static final short YYINITIAL = 0; + public static final short LAST_STATE = 1; + private static final int yy_state_dtrans[] = { + 0 + }; + private static final int YY_E_INTERNAL = 0; + private static final int YY_E_MATCH = 1; + private java.lang.String yy_error_string[] = { + "Error: Internal error.\n", + "Error: Unmatched input.\n" + }; + private void yy_error (int code,boolean fatal) { + java.lang.System.out.print(yy_error_string[code]); + java.lang.System.out.flush(); + if (fatal) { + throw new Error("Fatal Error.\n"); + } + } +private static int [][] unpackFromString(int size1, int size2, String st) + { + int colonIndex = -1; + String lengthString; + int sequenceLength = 0; + int sequenceInteger = 0; + int commaIndex; + String workString; + int res[][] = new int[size1][size2]; + for (int i= 0; i < size1; i++) + for (int j= 0; j < size2; j++) + { + if (sequenceLength == 0) + { + commaIndex = st.indexOf(','); + if (commaIndex == -1) + workString = st; + else + workString = st.substring(0, commaIndex); + st = st.substring(commaIndex+1); + colonIndex = workString.indexOf(':'); + if (colonIndex == -1) + { + res[i][j] = Integer.parseInt(workString); + } + else + { + lengthString = workString.substring(colonIndex+1); + sequenceLength = Integer.parseInt(lengthString); + workString = workString.substring(0,colonIndex); + sequenceInteger = Integer.parseInt(workString); + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + else + { + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + return res; + } + private static final int yy_acpt[] = { + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR + }; + private static final int yy_cmap[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 0, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 3, 4, 0, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 18, 18, 18, 18, 18, 18, + 19, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 27, 27, 28, 29, 30, 5, + 5, 5, 5, 5, 31, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 32, 5, 5, 33, 34, 35, 36, 5, + 0, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 5, 46, 47, 48, 49, 50, + 51, 5, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 0 + + }; + private static final int yy_rmap[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 1, 1, 9, 10, 1, 11, 12, + 13, 14, 1, 1, 15, 16, 1, 1, + 1, 1, 1, 17, 1, 18, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 19, 20, 21, 1, 1, 1, 22, + 1, 1, 1, 23, 5, 1, 1, 1, + 24, 1, 5, 25, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 26, 5, + 5, 5, 27, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 28, 1, 29, + 1, 30, 1, 31, 32, 33, 34, 35, + 36, 37, 38, 1, 1, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 42, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230 + }; + private static final int yy_nxt[][] = unpackFromString(231,65, +"1,2:2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,113:2,18,19,20,21,22,23,24,5:6,25,1,26,27,290,228,229,111,230,180,231,5,119,5,232,5,182,5,291,292,266,183,5,233,267,5:3,28,29,30,31,-1:66,2:2,-1:85,32,-1:41,4:2,-1,4,110,4:29,118,4:30,-1:5,5,-1:11,5:3,-1:7,5:6,-1:4,5:24,-1:27,33,-1:48,34,-1:15,35,-1:41,8:2,-1,8:5,112,8:25,120,8:30,-1:23,36,-1:53,37,-1:10,38,-1:55,39,-1:8,40,-1:56,109,-1,41:3,-1:56,42,-1:4,43,-1:6,44,-1:56,181,-1,121:2,117,-1:8,114,122,45,46,127,-1:7,114,122,45,-1:4,46,-1:10,127,-1:28,47,48,-1:64,49,-1:64,50,-1:64,53,-1:38,54,-1:19,41:3,-1:8,114,122,45,-1:9,114,122,45,-1:22,115:11,56,115:53,43:2,-1,43:62,-1:23,57,-1:46,5,-1:11,5:3,-1:7,5:6,-1:4,5:18,244,5:5,-1:4,116:11,56,116:4,124,116:48,-1:5,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,301,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,167,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,92,5:7,-1:19,55,-1:54,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,294,5:8,51,5:10,-1:19,181,-1,113:3,-1:8,114,122,45,46,-1:8,114,122,45,-1:4,46,-1:17,115:11,125,115:53,116:11,129,116:53,-1:15,181,-1,117:3,-1:8,114,122,45,-1:9,114,122,45,-1:22,4:2,-1,4:62,-1:5,5,-1:11,5:3,-1:7,5:6,-1:4,5:5,52,5:5,269,130,5:11,-1:4,8:2,-1,8:62,-1:15,181,-1,121:2,117,-1:8,114,122,45,46,-1:8,114,122,45,-1:4,46,-1:29,131,-1,131,-1:2,131:3,-1:8,114,-1,45,-1:9,114,-1,45,-1:22,115:11,125,115:4,123,115:48,-1:5,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,58,5:8,-1:21,127:3,-1:7,127:4,46,-1:5,127:6,-1:4,46,-1:34,128:3,-1:8,114,122,45,-1:9,114,122,45,-1:22,116:11,129,116:4,124,116:48,-1:5,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,313,59,5:6,-1:21,131:3,-1:8,114,-1,45,-1:9,114,-1,45,-1:27,5,-1:11,5:3,-1:7,5:6,-1:4,5:20,60,5:3,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,309,5:17,143,5:3,61,5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,62,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,63,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,64,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,65,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:11,66,5:12,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,67,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:6,68,5:17,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,69,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,70,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,71,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:3,72,5:20,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:9,73,5:14,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,74,5:16,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,75,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,76,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,77,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,78,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,79,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,80,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,81,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:20,82,5:3,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,83,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,84,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,85,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,86,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,87,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,88,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,89,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,90,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,91,5:16,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,93,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,94,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,95,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:22,96,5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,97,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,98,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,99,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,100,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:14,101,5:9,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,102,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,103,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:3,104,5:20,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,105,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,106,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:5,107,5:18,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:3,108,5:20,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,237,5:7,238,5,239,5:2,126,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,270,5:3,132,5:13,191,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,192,5:7,133,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,134,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,135,195,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,136,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,137,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:18,138,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,139,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,140,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,141,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,142,5:6,203,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,144,5,300,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,145,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,146,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,147,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,148,281,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,149,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,150,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,151,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,152,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,153,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,154,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,155,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,156,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,157,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,158,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:19,159,5:4,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,160,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,161,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,162,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,163,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,164,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,165,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:3,166,5:20,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:6,168,5:17,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,169,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,170,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:18,171,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:5,172,5:18,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,173,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,174,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,175,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,176,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,177,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,178,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,179,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,293,5,234,5:6,184,5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,185,5:6,186,5:2,235,5:2,236,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,187,5,188,5:8,295,5:2,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,189,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,190,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,193,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,194,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,196,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,197,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,198,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,199,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,200,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,201,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:14,202,5:9,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,204,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,205,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5,206,5:22,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,310,5:2,207,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,208,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,209,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:18,210,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,211,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,212,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,213,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:18,214,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,215,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,216,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,217,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,218,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,219,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,220,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,221,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,222,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,223,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,224,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,225,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,226,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:23,227,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,240,5:9,273,241,5,274,5,317,5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,242,5:16,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,243,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:14,245,5:9,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,246,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5,247,5:22,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,248,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,249,5:14,299,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,250,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:10,251,5:13,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,252,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,253,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:9,254,5:14,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:19,255,5:4,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,256,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,257,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,258,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,259,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:5,260,5:18,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,261,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,262,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,263,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,264,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,265,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5,307,5:14,268,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,296,5:14,297,5:2,271,5:5,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,272,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,275,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:5,276,5:18,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,277,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,278,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,279,5:4,308,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,280,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:8,282,5:15,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,283,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,284,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,285,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,286,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:11,287,5:12,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,288,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,289,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:16,298,5:7,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,302,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,303,5:11,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:4,304,5:19,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,305,5:23,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:13,306,5:10,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:17,311,5:6,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:15,312,5:8,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:7,314,5:16,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:2,315,5:21,-1:9,5,-1:11,5:3,-1:7,5:6,-1:4,5:12,316,5:11,-1:4"); + public void _locateToken () + { + char yy_lookahead; + int yy_anchor = YY_NO_ANCHOR; + int yy_state = yy_state_dtrans[yy_lexical_state]; + int yy_next_state = YY_NO_STATE; + int yy_last_accept_state = YY_NO_STATE; + boolean yy_initial = true; + int yy_this_accept; + + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + while (true) { + if (yy_buffer_index < yy_buffer_length){ + yy_lookahead = yy_buffer[yy_buffer_index++]; + if (yy_lookahead < 0 || yy_lookahead > 127){ + if (Character.isJavaIdentifierStart(yy_lookahead)){ + yy_lookahead = 'A'; + } + else if (Character.isJavaIdentifierPart(yy_lookahead)){ + yy_lookahead = '9'; + } + else{ + yy_lookahead = '#'; + } + } + } + else{ + yy_lookahead = YYEOF; + } + yy_next_state = YY_F; + if (YYEOF != yy_lookahead) { + yy_next_state = yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]]; + } + if (YY_F != yy_next_state) { + yy_state = yy_next_state; + yy_initial = false; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + } + else { + if (YYEOF == yy_lookahead && true == yy_initial) { + myTokenType = null; return; + } + else if (YY_NO_STATE == yy_last_accept_state) { + throw (new Error("Lexical Error: Unmatched Input.")); + } + else { + yy_buffer_index = yy_buffer_end; + yy_anchor = yy_acpt[yy_last_accept_state]; + if (0 != (YY_END & yy_anchor)) { + --yy_buffer_end; + } + if (0 != (YY_START & yy_anchor)) { + ++yy_buffer_start; + } + switch (yy_last_accept_state) { + case 1: + { myTokenType = JavaTokenType.BAD_CHARACTER; return; } + case -2: + break; + case 2: + { myTokenType = JavaTokenType.WHITE_SPACE; return; } + case -3: + break; + case 3: + { myTokenType = JavaTokenType.EXCL; return; } + case -4: + break; + case 4: + { myTokenType = JavaTokenType.STRING_LITERAL; return; } + case -5: + break; + case 5: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -6: + break; + case 6: + { myTokenType = JavaTokenType.PERC; return; } + case -7: + break; + case 7: + { myTokenType = JavaTokenType.AND; return; } + case -8: + break; + case 8: + { myTokenType = JavaTokenType.CHARACTER_LITERAL; return; } + case -9: + break; + case 9: + { myTokenType = JavaTokenType.LPARENTH; return; } + case -10: + break; + case 10: + { myTokenType = JavaTokenType.RPARENTH; return; } + case -11: + break; + case 11: + { myTokenType = JavaTokenType.ASTERISK; return; } + case -12: + break; + case 12: + { myTokenType = JavaTokenType.PLUS; return; } + case -13: + break; + case 13: + { myTokenType = JavaTokenType.COMMA; return; } + case -14: + break; + case 14: + { myTokenType = JavaTokenType.MINUS; return; } + case -15: + break; + case 15: + { myTokenType = JavaTokenType.DOT; return; } + case -16: + break; + case 16: + { myTokenType = JavaTokenType.DIV; return; } + case -17: + break; + case 17: + { myTokenType = JavaTokenType.INTEGER_LITERAL; return; } + case -18: + break; + case 18: + { myTokenType = JavaTokenType.COLON; return; } + case -19: + break; + case 19: + { myTokenType = JavaTokenType.SEMICOLON; return; } + case -20: + break; + case 20: + { myTokenType = JavaTokenType.LT; return; } + case -21: + break; + case 21: + { myTokenType = JavaTokenType.EQ; return; } + case -22: + break; + case 22: + { myTokenType = JavaTokenType.GT; return; } + case -23: + break; + case 23: + { myTokenType = JavaTokenType.QUEST; return; } + case -24: + break; + case 24: + { myTokenType = JavaTokenType.AT; return; } + case -25: + break; + case 25: + { myTokenType = JavaTokenType.LBRACKET; return; } + case -26: + break; + case 26: + { myTokenType = JavaTokenType.RBRACKET; return; } + case -27: + break; + case 27: + { myTokenType = JavaTokenType.XOR; return; } + case -28: + break; + case 28: + { myTokenType = JavaTokenType.LBRACE; return; } + case -29: + break; + case 29: + { myTokenType = JavaTokenType.OR; return; } + case -30: + break; + case 30: + { myTokenType = JavaTokenType.RBRACE; return; } + case -31: + break; + case 31: + { myTokenType = JavaTokenType.TILDE; return; } + case -32: + break; + case 32: + { myTokenType = JavaTokenType.NE; return; } + case -33: + break; + case 33: + { myTokenType = JavaTokenType.PERCEQ; return; } + case -34: + break; + case 34: + { myTokenType = JavaTokenType.ANDAND; return; } + case -35: + break; + case 35: + { myTokenType = JavaTokenType.ANDEQ; return; } + case -36: + break; + case 36: + { myTokenType = JavaTokenType.ASTERISKEQ; return; } + case -37: + break; + case 37: + { myTokenType = JavaTokenType.PLUSPLUS; return; } + case -38: + break; + case 38: + { myTokenType = JavaTokenType.PLUSEQ; return; } + case -39: + break; + case 39: + { myTokenType = JavaTokenType.MINUSMINUS; return; } + case -40: + break; + case 40: + { myTokenType = JavaTokenType.MINUSEQ; return; } + case -41: + break; + case 41: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -42: + break; + case 42: + { myTokenType = JavaTokenType.C_STYLE_COMMENT; return; } + case -43: + break; + case 43: + { myTokenType = JavaTokenType.END_OF_LINE_COMMENT; return; } + case -44: + break; + case 44: + { myTokenType = JavaTokenType.DIVEQ; return; } + case -45: + break; + case 45: + { myTokenType = JavaTokenType.FLOAT_LITERAL; return; } + case -46: + break; + case 46: + { myTokenType = JavaTokenType.LONG_LITERAL; return; } + case -47: + break; + case 47: + { myTokenType = JavaTokenType.LTLT; return; } + case -48: + break; + case 48: + { myTokenType = JavaTokenType.LE; return; } + case -49: + break; + case 49: + { myTokenType = JavaTokenType.EQEQ; return; } + case -50: + break; + case 50: + { myTokenType = JavaTokenType.XOREQ; return; } + case -51: + break; + case 51: + { myTokenType = JavaTokenType.DO_KEYWORD; return; } + case -52: + break; + case 52: + { myTokenType = JavaTokenType.IF_KEYWORD; return; } + case -53: + break; + case 53: + { myTokenType = JavaTokenType.OREQ; return; } + case -54: + break; + case 54: + { myTokenType = JavaTokenType.OROR; return; } + case -55: + break; + case 55: + { myTokenType = JavaTokenType.ELLIPSIS; return; } + case -56: + break; + case 56: + { myTokenType = JavaTokenType.DOC_COMMENT; return; } + case -57: + break; + case 57: + { myTokenType = JavaTokenType.LTLTEQ; return; } + case -58: + break; + case 58: + { myTokenType = JavaTokenType.FOR_KEYWORD; return; } + case -59: + break; + case 59: + { myTokenType = JavaTokenType.INT_KEYWORD; return; } + case -60: + break; + case 60: + { myTokenType = JavaTokenType.NEW_KEYWORD; return; } + case -61: + break; + case 61: + { myTokenType = JavaTokenType.TRY_KEYWORD; return; } + case -62: + break; + case 62: + { myTokenType = JavaTokenType.BYTE_KEYWORD; return; } + case -63: + break; + case 63: + { myTokenType = JavaTokenType.CASE_KEYWORD; return; } + case -64: + break; + case 64: + { myTokenType = JavaTokenType.CHAR_KEYWORD; return; } + case -65: + break; + case 65: + { myTokenType = JavaTokenType.ELSE_KEYWORD; return; } + case -66: + break; + case 66: + { myTokenType = myJdk15Enabled ? JavaTokenType.ENUM_KEYWORD : JavaTokenType.IDENTIFIER; return; } + case -67: + break; + case 67: + { myTokenType = JavaTokenType.GOTO_KEYWORD; return; } + case -68: + break; + case 68: + { myTokenType = JavaTokenType.LONG_KEYWORD; return; } + case -69: + break; + case 69: + { myTokenType = JavaTokenType.NULL_KEYWORD; return; } + case -70: + break; + case 70: + { myTokenType = JavaTokenType.THIS_KEYWORD; return; } + case -71: + break; + case 71: + { myTokenType = JavaTokenType.TRUE_KEYWORD; return; } + case -72: + break; + case 72: + { myTokenType = JavaTokenType.VOID_KEYWORD; return; } + case -73: + break; + case 73: + { myTokenType = JavaTokenType.BREAK_KEYWORD; return; } + case -74: + break; + case 74: + { myTokenType = JavaTokenType.CATCH_KEYWORD; return; } + case -75: + break; + case 75: + { myTokenType = JavaTokenType.CLASS_KEYWORD; return; } + case -76: + break; + case 76: + { myTokenType = JavaTokenType.CONST_KEYWORD; return; } + case -77: + break; + case 77: + { myTokenType = JavaTokenType.FALSE_KEYWORD; return; } + case -78: + break; + case 78: + { myTokenType = JavaTokenType.FINAL_KEYWORD; return; } + case -79: + break; + case 79: + { myTokenType = JavaTokenType.FLOAT_KEYWORD; return; } + case -80: + break; + case 80: + { myTokenType = JavaTokenType.SHORT_KEYWORD; return; } + case -81: + break; + case 81: + { myTokenType = JavaTokenType.SUPER_KEYWORD; return; } + case -82: + break; + case 82: + { myTokenType = JavaTokenType.THROW_KEYWORD; return; } + case -83: + break; + case 83: + { myTokenType = JavaTokenType.WHILE_KEYWORD; return; } + case -84: + break; + case 84: + { myTokenType = myAssertKeywordEnabled ? JavaTokenType.ASSERT_KEYWORD : JavaTokenType.IDENTIFIER; return; } + case -85: + break; + case 85: + { myTokenType = JavaTokenType.DOUBLE_KEYWORD; return; } + case -86: + break; + case 86: + { myTokenType = JavaTokenType.IMPORT_KEYWORD; return; } + case -87: + break; + case 87: + { myTokenType = JavaTokenType.NATIVE_KEYWORD; return; } + case -88: + break; + case 88: + { myTokenType = JavaTokenType.PUBLIC_KEYWORD; return; } + case -89: + break; + case 89: + { myTokenType = JavaTokenType.RETURN_KEYWORD; return; } + case -90: + break; + case 90: + { myTokenType = JavaTokenType.STATIC_KEYWORD; return; } + case -91: + break; + case 91: + { myTokenType = JavaTokenType.SWITCH_KEYWORD; return; } + case -92: + break; + case 92: + { myTokenType = JavaTokenType.THROWS_KEYWORD; return; } + case -93: + break; + case 93: + { myTokenType = JavaTokenType.BOOLEAN_KEYWORD; return; } + case -94: + break; + case 94: + { myTokenType = JavaTokenType.DEFAULT_KEYWORD; return; } + case -95: + break; + case 95: + { myTokenType = JavaTokenType.EXTENDS_KEYWORD; return; } + case -96: + break; + case 96: + { myTokenType = JavaTokenType.FINALLY_KEYWORD; return; } + case -97: + break; + case 97: + { myTokenType = JavaTokenType.PACKAGE_KEYWORD; return; } + case -98: + break; + case 98: + { myTokenType = JavaTokenType.PRIVATE_KEYWORD; return; } + case -99: + break; + case 99: + { myTokenType = JavaTokenType.ABSTRACT_KEYWORD; return; } + case -100: + break; + case 100: + { myTokenType = JavaTokenType.CONTINUE_KEYWORD; return; } + case -101: + break; + case 101: + { myTokenType = JavaTokenType.STRICTFP_KEYWORD; return; } + case -102: + break; + case 102: + { myTokenType = JavaTokenType.VOLATILE_KEYWORD; return; } + case -103: + break; + case 103: + { myTokenType = JavaTokenType.INTERFACE_KEYWORD; return; } + case -104: + break; + case 104: + { myTokenType = JavaTokenType.PROTECTED_KEYWORD; return; } + case -105: + break; + case 105: + { myTokenType = JavaTokenType.TRANSIENT_KEYWORD; return; } + case -106: + break; + case 106: + { myTokenType = JavaTokenType.IMPLEMENTS_KEYWORD; return; } + case -107: + break; + case 107: + { myTokenType = JavaTokenType.INSTANCEOF_KEYWORD; return; } + case -108: + break; + case 108: + { myTokenType = JavaTokenType.SYNCHRONIZED_KEYWORD; return; } + case -109: + break; + case 110: + { myTokenType = JavaTokenType.STRING_LITERAL; return; } + case -110: + break; + case 111: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -111: + break; + case 112: + { myTokenType = JavaTokenType.CHARACTER_LITERAL; return; } + case -112: + break; + case 113: + { myTokenType = JavaTokenType.INTEGER_LITERAL; return; } + case -113: + break; + case 114: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -114: + break; + case 115: + { myTokenType = JavaTokenType.C_STYLE_COMMENT; return; } + case -115: + break; + case 116: + { myTokenType = JavaTokenType.DOC_COMMENT; return; } + case -116: + break; + case 118: + { myTokenType = JavaTokenType.STRING_LITERAL; return; } + case -117: + break; + case 119: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -118: + break; + case 120: + { myTokenType = JavaTokenType.CHARACTER_LITERAL; return; } + case -119: + break; + case 121: + { myTokenType = JavaTokenType.INTEGER_LITERAL; return; } + case -120: + break; + case 122: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -121: + break; + case 123: + { myTokenType = JavaTokenType.C_STYLE_COMMENT; return; } + case -122: + break; + case 124: + { myTokenType = JavaTokenType.DOC_COMMENT; return; } + case -123: + break; + case 126: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -124: + break; + case 127: + { myTokenType = JavaTokenType.INTEGER_LITERAL; return; } + case -125: + break; + case 128: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -126: + break; + case 130: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -127: + break; + case 131: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -128: + break; + case 132: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -129: + break; + case 133: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -130: + break; + case 134: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -131: + break; + case 135: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -132: + break; + case 136: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -133: + break; + case 137: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -134: + break; + case 138: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -135: + break; + case 139: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -136: + break; + case 140: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -137: + break; + case 141: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -138: + break; + case 142: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -139: + break; + case 143: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -140: + break; + case 144: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -141: + break; + case 145: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -142: + break; + case 146: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -143: + break; + case 147: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -144: + break; + case 148: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -145: + break; + case 149: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -146: + break; + case 150: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -147: + break; + case 151: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -148: + break; + case 152: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -149: + break; + case 153: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -150: + break; + case 154: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -151: + break; + case 155: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -152: + break; + case 156: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -153: + break; + case 157: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -154: + break; + case 158: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -155: + break; + case 159: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -156: + break; + case 160: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -157: + break; + case 161: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -158: + break; + case 162: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -159: + break; + case 163: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -160: + break; + case 164: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -161: + break; + case 165: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -162: + break; + case 166: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -163: + break; + case 167: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -164: + break; + case 168: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -165: + break; + case 169: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -166: + break; + case 170: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -167: + break; + case 171: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -168: + break; + case 172: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -169: + break; + case 173: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -170: + break; + case 174: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -171: + break; + case 175: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -172: + break; + case 176: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -173: + break; + case 177: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -174: + break; + case 178: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -175: + break; + case 179: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -176: + break; + case 180: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -177: + break; + case 181: + { myTokenType = JavaTokenType.DOUBLE_LITERAL; return; } + case -178: + break; + case 182: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -179: + break; + case 183: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -180: + break; + case 184: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -181: + break; + case 185: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -182: + break; + case 186: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -183: + break; + case 187: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -184: + break; + case 188: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -185: + break; + case 189: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -186: + break; + case 190: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -187: + break; + case 191: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -188: + break; + case 192: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -189: + break; + case 193: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -190: + break; + case 194: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -191: + break; + case 195: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -192: + break; + case 196: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -193: + break; + case 197: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -194: + break; + case 198: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -195: + break; + case 199: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -196: + break; + case 200: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -197: + break; + case 201: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -198: + break; + case 202: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -199: + break; + case 203: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -200: + break; + case 204: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -201: + break; + case 205: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -202: + break; + case 206: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -203: + break; + case 207: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -204: + break; + case 208: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -205: + break; + case 209: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -206: + break; + case 210: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -207: + break; + case 211: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -208: + break; + case 212: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -209: + break; + case 213: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -210: + break; + case 214: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -211: + break; + case 215: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -212: + break; + case 216: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -213: + break; + case 217: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -214: + break; + case 218: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -215: + break; + case 219: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -216: + break; + case 220: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -217: + break; + case 221: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -218: + break; + case 222: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -219: + break; + case 223: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -220: + break; + case 224: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -221: + break; + case 225: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -222: + break; + case 226: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -223: + break; + case 227: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -224: + break; + case 228: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -225: + break; + case 229: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -226: + break; + case 230: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -227: + break; + case 231: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -228: + break; + case 232: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -229: + break; + case 233: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -230: + break; + case 234: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -231: + break; + case 235: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -232: + break; + case 236: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -233: + break; + case 237: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -234: + break; + case 238: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -235: + break; + case 239: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -236: + break; + case 240: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -237: + break; + case 241: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -238: + break; + case 242: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -239: + break; + case 243: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -240: + break; + case 244: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -241: + break; + case 245: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -242: + break; + case 246: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -243: + break; + case 247: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -244: + break; + case 248: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -245: + break; + case 249: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -246: + break; + case 250: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -247: + break; + case 251: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -248: + break; + case 252: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -249: + break; + case 253: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -250: + break; + case 254: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -251: + break; + case 255: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -252: + break; + case 256: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -253: + break; + case 257: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -254: + break; + case 258: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -255: + break; + case 259: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -256: + break; + case 260: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -257: + break; + case 261: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -258: + break; + case 262: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -259: + break; + case 263: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -260: + break; + case 264: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -261: + break; + case 265: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -262: + break; + case 266: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -263: + break; + case 267: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -264: + break; + case 268: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -265: + break; + case 269: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -266: + break; + case 270: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -267: + break; + case 271: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -268: + break; + case 272: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -269: + break; + case 273: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -270: + break; + case 274: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -271: + break; + case 275: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -272: + break; + case 276: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -273: + break; + case 277: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -274: + break; + case 278: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -275: + break; + case 279: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -276: + break; + case 280: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -277: + break; + case 281: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -278: + break; + case 282: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -279: + break; + case 283: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -280: + break; + case 284: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -281: + break; + case 285: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -282: + break; + case 286: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -283: + break; + case 287: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -284: + break; + case 288: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -285: + break; + case 289: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -286: + break; + case 290: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -287: + break; + case 291: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -288: + break; + case 292: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -289: + break; + case 293: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -290: + break; + case 294: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -291: + break; + case 295: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -292: + break; + case 296: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -293: + break; + case 297: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -294: + break; + case 298: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -295: + break; + case 299: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -296: + break; + case 300: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -297: + break; + case 301: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -298: + break; + case 302: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -299: + break; + case 303: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -300: + break; + case 304: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -301: + break; + case 305: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -302: + break; + case 306: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -303: + break; + case 307: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -304: + break; + case 308: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -305: + break; + case 309: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -306: + break; + case 310: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -307: + break; + case 311: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -308: + break; + case 312: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -309: + break; + case 313: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -310: + break; + case 314: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -311: + break; + case 315: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -312: + break; + case 316: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -313: + break; + case 317: + { myTokenType = JavaTokenType.IDENTIFIER; return; } + case -314: + break; + default: + yy_error(YY_E_INTERNAL,false); + case -1: + } + yy_initial = true; + yy_state = yy_state_dtrans[yy_lexical_state]; + yy_next_state = YY_NO_STATE; + yy_last_accept_state = YY_NO_STATE; + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_OldXmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_OldXmlLexer.java new file mode 100644 index 00000000000..e3cc5ab6a55 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_OldXmlLexer.java @@ -0,0 +1,1638 @@ +/* It's an automatically generated code. Do not modify it. */ +package com.intellij.lexer; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.*; + + +public class _OldXmlLexer implements Lexer, Cloneable { + private static final int YY_F = -1; + private static final int YY_NO_STATE = -1; + private static final int YY_NOT_ACCEPT = 0; + private static final int YY_START = 1; + private static final int YY_END = 2; + private static final int YY_NO_ANCHOR = 4; + private static final char YYEOF = '\uFFFF'; + + private IElementType myTokenType; + private int myState; + public final void start(char[] buffer){ + start(buffer, 0, buffer.length); + } + public final void start(char[] buffer, int startOffset, int endOffset){ + start(buffer, startOffset, endOffset, (short)YYINITIAL); + } + public final void start(char[] buffer, int startOffset, int endOffset, int initialState){ + yy_buffer = buffer; + yy_buffer_index = startOffset; + yy_buffer_length = endOffset; + yy_lexical_state = initialState; + myTokenType = null; + myState = initialState; + } + public final int getState(){ + return myState; + } + public final int getLastState() { + return LAST_STATE; + } + public final IElementType getTokenType(){ + locateToken(); + return myTokenType; + } + public final int getTokenStart(){ + if (myTokenType != null){ + return yy_buffer_start; + } + else{ + return yy_buffer_index; + } + } + public final int getTokenEnd(){ + locateToken(); + return yy_buffer_end; + } + public final void advance(){ + locateToken(); + myTokenType = null; + myState = (short)yy_lexical_state; + } + public final char[] getBuffer(){ + return yy_buffer; + } + public final int getBufferEnd(){ + return yy_buffer_length; + } + protected final void locateToken(){ + if (myTokenType != null) return; + _locateToken(); + } + public int getSmartUpdateShift() { + return 10; + } + public Object clone() { + try{ + return super.clone(); + } + catch(CloneNotSupportedException e){ + return null; + } + } + private int yy_buffer_index; + private int yy_buffer_start; + private int yy_buffer_end; + private char yy_buffer[]; + private int yy_buffer_length; + private int yy_lexical_state; + + public _OldXmlLexer () { + yy_lexical_state = YYINITIAL; + + myTokenType = null; + } + + private boolean yy_eof_done = false; + public static final short PROCESSING_INSTRUCTION = 11; + public static final short DECL_ATTR_VALUE_DQ = 3; + public static final short DECL_ATTR = 2; + public static final short ATTRIBUTE_VALUE_START = 8; + public static final short DECL_ATTR_VALUE_SQ = 4; + public static final short ATTRIBUTE_VALUE_DQ = 9; + public static final short DECL = 1; + public static final short ATTRIBUTE_VALUE_SQ = 10; + public static final short DOCTYPE_EXTERNAL_ID = 13; + public static final short CDATA = 17; + public static final short COMMENT = 7; + public static final short TAG_NAME = 5; + public static final short DOCTYPE_MARKUP = 14; + public static final short DOCTYPE_MARKUP_DQ = 15; + public static final short YYINITIAL = 0; + public static final short TAG_ATTRIBUTES = 6; + public static final short DOCTYPE = 12; + public static final short DOCTYPE_MARKUP_SQ = 16; + public static final short LAST_STATE = 18; + private static final int yy_state_dtrans[] = { + 0, + 204, + 206, + 25, + 27, + 207, + 208, + 34, + 214, + 215, + 216, + 217, + 218, + 219, + 222, + 243, + 244, + 245 + }; + private static final int YY_E_INTERNAL = 0; + private static final int YY_E_MATCH = 1; + private java.lang.String yy_error_string[] = { + "Error: Internal error.\n", + "Error: Unmatched input.\n" + }; + private void yy_error (int code,boolean fatal) { + java.lang.System.out.print(yy_error_string[code]); + java.lang.System.out.flush(); + if (fatal) { + throw new Error("Fatal Error.\n"); + } + } + private static int [][] unpackFromString(int size1, int size2, String st) + { + int colonIndex = -1; + String lengthString; + int sequenceLength = 0; + int sequenceInteger = 0; + int commaIndex; + String workString; + int res[][] = new int[size1][size2]; + for (int i= 0; i < size1; i++) + for (int j= 0; j < size2; j++) + { + if (sequenceLength == 0) + { + commaIndex = st.indexOf(','); + if (commaIndex == -1) + workString = st; + else + workString = st.substring(0, commaIndex); + st = st.substring(commaIndex+1); + colonIndex = workString.indexOf(':'); + if (colonIndex == -1) + { + res[i][j] = Integer.parseInt(workString); + } + else + { + lengthString = workString.substring(colonIndex+1); + sequenceLength = Integer.parseInt(lengthString); + workString = workString.substring(0,colonIndex); + sequenceInteger = Integer.parseInt(workString); + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + else + { + res[i][j] = sequenceInteger; + sequenceLength--; + } + } + return res; + } + private static final int yy_acpt[] = { + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NOT_ACCEPT, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR, + YY_NO_ANCHOR + }; + private static final int yy_cmap[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 3, 4, 5, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 18, 19, 20, 21, 22, 23, + 0, 24, 25, 26, 27, 28, 29, 18, + 18, 30, 18, 18, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 18, 18, + 41, 42, 18, 43, 0, 44, 0, 18, + 0, 45, 45, 45, 45, 45, 45, 18, + 18, 18, 18, 18, 46, 47, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 48, 18, 18, 0, 49, 0, 0, 0 + + }; + private static final int yy_rmap[] = { + 0, 1, 2, 3, 4, 1, 5, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 6, 1, 1, 1, 1, + 1, 7, 1, 8, 1, 9, 10, 1, + 1, 1, 11, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 12, 1, + 1, 12, 12, 1, 1, 1, 13, 3, + 1, 1, 1, 1, 1, 1, 14, 1, + 1, 1, 1, 1, 14, 14, 1, 14, + 14, 1, 1, 1, 15, 1, 16, 1, + 1, 1, 1, 17, 13, 1, 18, 19, + 19, 19, 19, 19, 19, 20, 21, 13, + 13, 13, 22, 23, 24, 25, 13, 26, + 13, 20, 20, 20, 20, 20, 27, 28, + 29, 3, 3, 3, 30, 31, 32, 33, + 3, 34, 35, 21, 21, 21, 21, 21, + 36, 37, 38, 35, 39, 40, 41, 42, + 43, 44, 15, 15, 15, 15, 15, 45, + 46, 47, 48, 49, 50, 51, 52, 53, + 54, 16, 16, 16, 16, 16, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 68, 70, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230 + + }; + private static final int yy_nxt[][] = unpackFromString(231,50, + "1,2:2,1:3,84,3,1:12,4,1:29,-1:51,2:2,-1:52,103,-1:12,121,-1:5,121:19,-1:2,121:4,-1:4,136,-1:12,5,-1:6,6,-1:74,178,-1:15,19:2,-1,19:2,-1:5,19:19,-1:2,19:4,-1,92:4,26,92,253,263,92:12,334,92:29,93:6,254,264,28,93:11,335,93:29,-1:14,29:2,-1,29:2,-1:5,29:19,-1:2,29:4,-1:15,30:2,-1,30:2,-1:5,30:19,-1:2,30:4,-1,94:6,255,265,94:6,164,94:5,297,94:29,-1:14,46:2,-1,46:2,-1:5,46:19,-1:2,46:4,-1:19,83,-1:5,83:19,-1:2,83:4,-1:15,62:2,-1,62:2,-1:5,62:19,-1:2,62:4,-1,76:4,-1,76:45,78:8,-1,78:41,-1:14,83:2,-1,83:2,7,-1:4,83:19,-1:2,83:4,-1:4,205,-1:12,5,-1:33,92:4,-1,92:45,93:8,-1,93:41,94:14,209,94:35,-1:14,46:2,-1,46:2,-1:5,46:2,49,46:16,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:18,68,-1:2,62:4,-1,76:4,-1,76:9,100:2,76,100:2,138,76:4,100:19,76:2,100:4,76,78:8,-1,78:5,101:2,78,101:2,153,78:4,101:19,78:2,101:4,78,-1:17,151,-1:30,163,-1,92:4,-1,92:9,110:2,92,110:2,87,92:4,110:19,92:2,110:4,92,93:8,-1,93:5,111:2,93,111:2,105,93:4,111:19,93:2,111:4,93,94:14,211,112,94,112:2,123,94:4,112:19,94:2,112:4,94,-1:14,46:2,-1,46:2,-1:5,46:8,50,46:10,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:18,69,-1:2,62:4,-1,76:4,-1,76:9,118:2,76,118:2,139,76:4,118:19,76:2,118:4,76,78:8,-1,78:5,119:2,78,119:2,154,78:4,119:19,78:2,119:4,78,-1:14,121:2,-1,121:2,8,-1:4,121:19,-1:2,121:4,-1:4,205,-1:46,92:4,-1,92:9,128:2,92,128:2,88,92:4,128:19,92:2,128:4,92,93:8,-1,93:5,129:2,93,129:2,106,93:4,129:19,93:2,129:4,93,94:14,212,130,94,130:2,124,94:4,130:19,94:2,130:4,94,-1:14,62:2,-1,62:2,-1:5,62:2,71,62:16,-1:2,62:4,-1,76:4,-1,76:12,133,76,140,76:30,78:8,-1,78:8,134,78,155,78:30,-1:3,246,-1:60,168,-1:9,170,-1:2,172,174,-1:4,176,-1:9,177,-1:28,21,-1:27,92:4,-1,92:12,143,92,89,92:30,93:8,-1,93:8,144,93,107,93:30,94:14,209,94:2,145,94,125,94:30,-1:22,45,-1:41,62:2,-1,62:2,-1:5,62:8,72,62:10,-1:2,62:4,-1,76:4,-1,76:12,148,76,141,76:4,148:6,76:15,148,76:4,78:8,-1,78:8,149,78,156,78:4,149:6,78:15,149,78:4,-1:44,247,-1:22,151,-1,9,-1:52,33,-1:27,92:4,-1,92:12,158,92,90,92:4,158:6,92:15,158,92:4,93:8,-1,93:8,159,93,108,93:4,159:6,93:15,159,93:4,94:14,209,94:2,160,94,126,94:4,160:6,94:15,160,94:4,76:4,-1,76:38,142,76:6,78:8,-1,78:34,157,78:6,-1:17,179,-1:6,179:6,-1:15,179,-1:4,94:14,210,94:35,92:4,-1,92:38,91,92:6,93:8,-1,93:34,109,93:6,94:14,209,94:28,127,94:6,-1:14,10,-1:57,39,-1:66,257,-1:10,220:4,51,220:45,-1:34,180,-1:15,221:8,52,221:41,-1:31,181,-1,266,-1:45,223,224,-1:4,225,-1,226,-1:46,273,-1:41,182,-1:70,183,-1:19,179,-1,11,-1:4,179:6,-1:15,179,-1:30,280,-1:51,185,-1:48,298,-1:68,188,-1:34,189,-1:50,191,-1:47,286,-1:43,288,-1:27,12,-1:77,192,-1:61,193,-1:35,194,-1:59,198,-1:46,199,-1:47,200,-1:58,13,-1:37,201,-1:43,202,-1:64,14,-1:38,15,-1:60,16,-1:44,203,-1:58,17,-1:39,18,-1:16,85,2:2,85:3,104,3,85:10,19,85,122,85,20,137,19:19,85:2,19:4,85,-1:14,168,-1:28,177,-1:6,85,2:2,85,22,85,104,3,23,85:11,122,24,85:29,2:2,85:3,104,3,85:10,29,85,86,85:3,29:19,85:2,29:4,85:2,2:2,85:3,104,3,85:8,152,85,30,85,86,31,32,85,30:19,85:2,30:4,85,94:14,-1,94:35,-1:22,35,-1:27,94:14,83,112,94,112:2,123,94:4,112:19,94:2,112:4,94:15,121,130,94,130:2,124,94:4,130:19,94:2,130:4,94:15,10,94:35,85,2:2,85,36,85,104,3,37,85:7,169,85:3,86,85,38,85:27,40:4,41,40,95,113,40:12,86,40:29,42:6,96,114,43,42:11,86,42:29,44:6,97,115,44:12,131,44:2,146,44:26,85,2:2,85:3,104,3,85:10,46,85,122,85,47,85,46:11,314,46:2,321,46:4,48,85,46:4,85:2,2:2,85,171,85,104,3,173,85:11,122,85,47,85:20,48,85:7,2:2,85,53,175,54,55,56,57,58,59,60,61,62:2,85,62:2,63,256,85,64,65,250,62:3,305,62:6,315,62:2,322,62:4,85,66,62:4,67,-1:30,228,-1:51,229,-1:43,230,-1:51,231,-1:35,168,-1:9,170,-1:3,174,-1:4,176,-1:9,177,-1:47,232,-1:43,233,-1:41,302,-1:58,234,-1:41,235,-1:52,236,-1:58,258,-1:36,70,-1:52,237,-1:47,240,-1:45,73,-1:62,241,-1:39,74,-1:50,242,-1:48,75,-1:22,76:4,77,76,251,261,76:12,332,76:29,78:6,252,262,79,78:11,333,78:29,80:6,102,120,80:12,135,80:23,150,80:5,-1:14,248,-1:28,177,-1:28,81,-1:41,82,-1:49,46:2,-1,46:2,-1:5,46:6,98,46:12,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:9,99,62:9,-1:2,62:4,-1,76:4,-1,76:13,100,76:5,100:19,76:2,100:4,76,78:8,-1,78:9,101,78:5,101:19,78:2,101:4,78,92:4,-1,92:13,110,92:5,110:19,92:2,110:4,92,93:8,-1,93:9,111,93:5,111:19,93:2,111:4,93,94:14,209,94:3,112,94:5,112:19,94:2,112:4,94,-1:3,227,-1:85,184,-1:40,239,-1:33,46:2,-1,46:2,-1:5,46:4,116,46:14,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:15,117,62:3,-1:2,62:4,-1,76:4,-1,268,76:12,118,76:5,118:19,76:2,118:4,76,78:5,269,78:2,-1,78:9,119,78:5,119:19,78:2,119:4,78,92:4,-1,270,92:12,128,92:5,128:19,92:2,128:4,92,93:5,271,93:2,-1,93:9,129,93:5,129:19,93:2,129:4,93,94:5,272,94:8,209,94:3,130,94:5,130:19,94:2,130:4,94,-1:39,186,-1:24,62:2,-1,62:2,-1:5,62:6,132,62:12,-1:2,62:4,-1,76:4,-1,76:12,133,76:30,275,76,78:8,-1,78:8,134,78:30,276,78,92:4,-1,92:12,143,92:30,277,92,93:8,-1,93:8,144,93:30,278,93,94:14,209,94:2,145,94:30,285,94,-1:39,187,-1:24,62:2,-1,62:2,-1:5,62:4,147,62:14,-1:2,62:4,-1,76:4,-1,76:12,148,76:6,148:6,76:15,148,76:4,78:8,-1,78:8,149,78:6,149:6,78:15,149,78:4,92:4,-1,92:12,158,92:6,158:6,92:15,158,92:4,93:8,-1,93:8,159,93:6,159:6,93:15,159,93:4,94:14,213,94:28,327,94:6,-1:39,190,-1:10,76:4,-1,76:19,161,76:25,78:8,-1,78:15,162,78:25,92:4,-1,92:19,165,92:25,93:8,-1,93:15,166,93:25,94:14,209,94:2,160,94:6,160:6,94:15,160,94:4,-1:39,195,-1:10,94:14,209,94:9,167,94:25,-1:39,196,-1:49,197,-1:49,238,-1:24,46:2,-1,46:2,-1:5,46:7,249,46:11,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:11,260,62:7,-1:2,62:4,-1,76:4,-1,76:34,281,76:10,78:8,-1,78:30,282,78:10,92:4,-1,92:34,283,92:10,93:8,-1,93:30,284,93:10,94:3,279,94:10,209,94:35,-1:24,289,-1:39,46:2,-1,46:2,-1:5,46:15,259,46:3,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:7,267,62:11,-1:2,62:4,-1,94:14,209,94:24,287,94:10,-1:24,290,-1:39,62:2,-1,62:2,-1:5,62:15,274,62:3,-1:2,62:4,-1:15,46:2,-1,46:2,-1:5,46,291,46:17,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:8,292,62:10,-1:2,62:4,-1,76:4,-1,76:19,293,76:25,78:8,-1,78:15,294,78:25,92:4,-1,92:19,295,92:25,93:8,-1,93:15,296,93:25,94:14,209,94:9,301,94:25,-1:14,46:2,-1,46:2,-1:5,46:14,299,46:4,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62,300,62:17,-1:2,62:4,-1:15,62:2,-1,62:2,-1:5,62:14,303,62:4,-1:2,62:4,-1:15,46:2,-1,46:2,-1:5,46:16,304,46:2,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:16,312,62:2,-1:2,62:4,-1,76:4,-1,76:22,306,76:22,78:8,-1,78:18,307,78:22,92:4,-1,92:22,308,92:22,93:8,-1,93:18,309,93:22,94:14,209,94:12,310,94:22,-1:14,46:2,-1,46:2,-1:5,46:18,311,-1:2,46:4,-1:15,62:2,-1,62:2,-1:5,62:18,313,-1:2,62:4,-1,76:4,-1,76:21,316,76:23,78:8,-1,78:17,317,78:23,92:4,-1,92:21,318,92:23,93:8,-1,93:17,319,93:23,94:14,209,94:11,320,94:23,76:4,-1,76:38,323,76:6,78:8,-1,78:34,324,78:6,92:4,-1,92:38,325,92:6,93:8,-1,93:34,326,93:6,76:3,328,-1,76:45,78:3,329,78:4,-1,78:41,92:3,330,-1,92:45,93:3,331,93:4,-1,93:41"); + public void _locateToken () + { + char yy_lookahead; + int yy_anchor = YY_NO_ANCHOR; + int yy_state = yy_state_dtrans[yy_lexical_state]; + int yy_next_state = YY_NO_STATE; + int yy_last_accept_state = YY_NO_STATE; + boolean yy_initial = true; + int yy_this_accept; + + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + while (true) { + if (yy_buffer_index < yy_buffer_length){ + yy_lookahead = yy_buffer[yy_buffer_index++]; + if (yy_lookahead < 0 || yy_lookahead > 127){ + if (Character.isJavaIdentifierStart(yy_lookahead)){ + yy_lookahead = 'A'; + } + else if (Character.isJavaIdentifierPart(yy_lookahead)){ + yy_lookahead = '9'; + } + else{ + yy_lookahead = '#'; + } + } + } + else{ + yy_lookahead = YYEOF; + } + yy_next_state = YY_F; + if (YYEOF != yy_lookahead) { + yy_next_state = yy_nxt[yy_rmap[yy_state]][yy_cmap[yy_lookahead]]; + } + if (YY_F != yy_next_state) { + yy_state = yy_next_state; + yy_initial = false; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + yy_buffer_end = yy_buffer_index; + } + } + else { + if (YYEOF == yy_lookahead && true == yy_initial) { + myTokenType = null; return; + } + else if (YY_NO_STATE == yy_last_accept_state) { + throw (new Error("Lexical Error: Unmatched Input.")); + } + else { + yy_buffer_index = yy_buffer_end; + yy_anchor = yy_acpt[yy_last_accept_state]; + if (0 != (YY_END & yy_anchor)) { + --yy_buffer_end; + } + if (0 != (YY_START & yy_anchor)) { + ++yy_buffer_start; + } + switch (yy_last_accept_state) { + case 1: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -2: + break; + case 2: + { myTokenType = XmlTokenType.XML_WHITE_SPACE; return; } + case -3: + break; + case 3: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -4: + break; + case 4: + { myTokenType = XmlTokenType.XML_START_TAG_START; yy_lexical_state = TAG_NAME; return; } + case -5: + break; + case 5: + { myTokenType = XmlTokenType.XML_END_TAG_START; yy_lexical_state = TAG_NAME; return; } + case -6: + break; + case 6: + { myTokenType = XmlTokenType.XML_PI_START; yy_lexical_state = PROCESSING_INSTRUCTION; return; } + case -7: + break; + case 7: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -8: + break; + case 8: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -9: + break; + case 9: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -10: + break; + case 10: + { myTokenType = XmlTokenType.XML_COMMENT_START; yy_lexical_state = COMMENT; return; } + case -11: + break; + case 11: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -12: + break; + case 12: + { myTokenType = XmlTokenType.XML_DECL_START; yy_lexical_state = DECL; return; } + case -13: + break; + case 13: + { myTokenType = XmlTokenType.XML_ENTITY_DECL_START; yy_lexical_state = DOCTYPE_MARKUP; return;} + case -14: + break; + case 14: + { myTokenType = XmlTokenType.XML_ATTLIST_DECL_START; yy_lexical_state = DOCTYPE_MARKUP; return;} + case -15: + break; + case 15: + { myTokenType = XmlTokenType.XML_DOCTYPE_START; yy_lexical_state = DOCTYPE; return; } + case -16: + break; + case 16: + { myTokenType = XmlTokenType.XML_ELEMENT_DECL_START; yy_lexical_state = DOCTYPE_MARKUP; return;} + case -17: + break; + case 17: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -18: + break; + case 18: + { myTokenType = XmlTokenType.XML_NOTATION_DECL_START; yy_lexical_state = DOCTYPE_MARKUP; return;} + case -19: + break; + case 19: + { myTokenType = XmlTokenType.XML_NAME; yy_lexical_state = DECL_ATTR; return; } + case -20: + break; + case 20: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; yy_lexical_state = YYINITIAL; return;} + case -21: + break; + case 21: + { myTokenType = XmlTokenType.XML_DECL_END; yy_lexical_state = YYINITIAL; return;} + case -22: + break; + case 22: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = DECL_ATTR_VALUE_DQ; return;} + case -23: + break; + case 23: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = DECL_ATTR_VALUE_SQ; return;} + case -24: + break; + case 24: + { myTokenType = XmlTokenType.XML_EQ; return;} + case -25: + break; + case 25: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -26: + break; + case 26: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = DECL; return;} + case -27: + break; + case 27: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -28: + break; + case 28: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = DECL; return;} + case -29: + break; + case 29: + { myTokenType = XmlTokenType.XML_TAG_NAME; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -30: + break; + case 30: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -31: + break; + case 31: + { myTokenType = XmlTokenType.XML_EQ; yy_lexical_state = ATTRIBUTE_VALUE_START; return; } + case -32: + break; + case 32: + { myTokenType = XmlTokenType.XML_TAG_END; yy_lexical_state = YYINITIAL; return; } + case -33: + break; + case 33: + { myTokenType = XmlTokenType.XML_EMPTY_ELEMENT_END; yy_lexical_state = YYINITIAL; return; } + case -34: + break; + case 34: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -35: + break; + case 35: + { myTokenType = XmlTokenType.XML_COMMENT_END; yy_lexical_state = YYINITIAL; return; } + case -36: + break; + case 36: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = ATTRIBUTE_VALUE_DQ; return; } + case -37: + break; + case 37: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = ATTRIBUTE_VALUE_SQ; return; } + case -38: + break; + case 38: + { myTokenType = XmlTokenType.XML_TAG_END; yy_lexical_state = YYINITIAL; return; } + case -39: + break; + case 39: + { myTokenType = XmlTokenType.XML_EMPTY_ELEMENT_END; yy_lexical_state = YYINITIAL; return; } + case -40: + break; + case 40: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -41: + break; + case 41: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -42: + break; + case 42: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -43: + break; + case 43: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = TAG_ATTRIBUTES; return; } + case -44: + break; + case 44: + { myTokenType = XmlTokenType.XML_PI_TARGET; return; } + case -45: + break; + case 45: + { myTokenType = XmlTokenType.XML_PI_END; yy_lexical_state = YYINITIAL; return; } + case -46: + break; + case 46: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -47: + break; + case 47: + { myTokenType = XmlTokenType.XML_DOCTYPE_END; yy_lexical_state = YYINITIAL; return; } + case -48: + break; + case 48: + { myTokenType = XmlTokenType.XML_MARKUP_START; yy_lexical_state = DOCTYPE_MARKUP; return;} + case -49: + break; + case 49: + { myTokenType = XmlTokenType.XML_DOCTYPE_PUBLIC; yy_lexical_state = DOCTYPE_EXTERNAL_ID; return; } + case -50: + break; + case 50: + { myTokenType = XmlTokenType.XML_DOCTYPE_SYSTEM; yy_lexical_state = DOCTYPE_EXTERNAL_ID; return; } + case -51: + break; + case 51: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -52: + break; + case 52: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -53: + break; + case 53: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = DOCTYPE_MARKUP_DQ; return; } + case -54: + break; + case 54: + { myTokenType = XmlTokenType.XML_PERCENT; return;} + case -55: + break; + case 55: + { myTokenType = XmlTokenType.XML_AMP; return;} + case -56: + break; + case 56: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yy_lexical_state = DOCTYPE_MARKUP_SQ; return; } + case -57: + break; + case 57: + { myTokenType = XmlTokenType.XML_LEFT_PAREN; return;} + case -58: + break; + case 58: + { myTokenType = XmlTokenType.XML_RIGHT_PAREN; return;} + case -59: + break; + case 59: + { myTokenType = XmlTokenType.XML_STAR; return;} + case -60: + break; + case 60: + { myTokenType = XmlTokenType.XML_PLUS; return;} + case -61: + break; + case 61: + { myTokenType = XmlTokenType.XML_COMMA; return;} + case -62: + break; + case 62: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -63: + break; + case 63: + { myTokenType = XmlTokenType.XML_SEMI; return;} + case -64: + break; + case 64: + { myTokenType = XmlTokenType.XML_TAG_END; return;} + case -65: + break; + case 65: + { myTokenType = XmlTokenType.XML_QUESTION; return;} + case -66: + break; + case 66: + { myTokenType = XmlTokenType.XML_MARKUP_END; yy_lexical_state = DOCTYPE; return;} + case -67: + break; + case 67: + { myTokenType = XmlTokenType.XML_BAR; return;} + case -68: + break; + case 68: + { myTokenType = XmlTokenType.XML_CONTENT_ANY; return;} + case -69: + break; + case 69: + { myTokenType = XmlTokenType.XML_CONTENT_EMPTY; return;} + case -70: + break; + case 70: + { myTokenType = XmlTokenType.XML_ATT_FIXED; return;} + case -71: + break; + case 71: + { myTokenType = XmlTokenType.XML_DOCTYPE_PUBLIC; return; } + case -72: + break; + case 72: + { myTokenType = XmlTokenType.XML_DOCTYPE_SYSTEM; return; } + case -73: + break; + case 73: + { myTokenType = XmlTokenType.XML_PCDATA; return;} + case -74: + break; + case 74: + { myTokenType = XmlTokenType.XML_ATT_IMPLIED; return;} + case -75: + break; + case 75: + { myTokenType = XmlTokenType.XML_ATT_REQUIRED; return;} + case -76: + break; + case 76: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -77: + break; + case 77: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = DOCTYPE_MARKUP; return; } + case -78: + break; + case 78: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -79: + break; + case 79: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yy_lexical_state = DOCTYPE_MARKUP; return; } + case -80: + break; + case 80: + {myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -81: + break; + case 81: + {myTokenType = XmlTokenType.XML_CDATA_END; yy_lexical_state = YYINITIAL; return; } + case -82: + break; + case 82: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -83: + break; + case 84: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -84: + break; + case 85: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -85: + break; + case 86: + { myTokenType = XmlTokenType.XML_START_TAG_START; yy_lexical_state = TAG_NAME; return; } + case -86: + break; + case 87: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -87: + break; + case 88: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -88: + break; + case 89: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -89: + break; + case 90: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -90: + break; + case 91: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -91: + break; + case 92: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -92: + break; + case 93: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -93: + break; + case 94: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -94: + break; + case 95: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -95: + break; + case 96: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -96: + break; + case 97: + { myTokenType = XmlTokenType.XML_PI_TARGET; return; } + case -97: + break; + case 98: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -98: + break; + case 99: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -99: + break; + case 100: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -100: + break; + case 101: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -101: + break; + case 102: + {myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -102: + break; + case 104: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -103: + break; + case 105: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -104: + break; + case 106: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -105: + break; + case 107: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -106: + break; + case 108: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -107: + break; + case 109: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -108: + break; + case 110: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -109: + break; + case 111: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -110: + break; + case 112: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -111: + break; + case 113: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -112: + break; + case 114: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -113: + break; + case 115: + { myTokenType = XmlTokenType.XML_PI_TARGET; return; } + case -114: + break; + case 116: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -115: + break; + case 117: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -116: + break; + case 118: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -117: + break; + case 119: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -118: + break; + case 120: + {myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -119: + break; + case 122: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -120: + break; + case 123: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -121: + break; + case 124: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -122: + break; + case 125: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -123: + break; + case 126: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -124: + break; + case 127: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -125: + break; + case 128: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -126: + break; + case 129: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -127: + break; + case 130: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -128: + break; + case 131: + { myTokenType = XmlTokenType.XML_PI_TARGET; return; } + case -129: + break; + case 132: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -130: + break; + case 133: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -131: + break; + case 134: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -132: + break; + case 135: + {myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -133: + break; + case 137: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -134: + break; + case 138: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -135: + break; + case 139: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -136: + break; + case 140: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -137: + break; + case 141: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -138: + break; + case 142: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -139: + break; + case 143: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -140: + break; + case 144: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -141: + break; + case 145: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -142: + break; + case 146: + { myTokenType = XmlTokenType.XML_PI_TARGET; return; } + case -143: + break; + case 147: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -144: + break; + case 148: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -145: + break; + case 149: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -146: + break; + case 150: + {myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; } + case -147: + break; + case 152: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -148: + break; + case 153: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -149: + break; + case 154: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; } + case -150: + break; + case 155: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -151: + break; + case 156: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; } + case -152: + break; + case 157: + {myTokenType = XmlTokenType.XML_CDATA_START; yy_lexical_state = CDATA; return; } + case -153: + break; + case 158: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -154: + break; + case 159: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -155: + break; + case 160: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -156: + break; + case 161: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -157: + break; + case 162: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -158: + break; + case 164: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -159: + break; + case 165: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -160: + break; + case 166: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -161: + break; + case 167: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -162: + break; + case 169: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -163: + break; + case 171: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -164: + break; + case 173: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -165: + break; + case 175: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -166: + break; + case 249: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -167: + break; + case 250: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -168: + break; + case 251: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -169: + break; + case 252: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -170: + break; + case 253: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -171: + break; + case 254: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -172: + break; + case 255: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -173: + break; + case 256: + { myTokenType = XmlTokenType.XML_BAD_CHARACTER; return; } + case -174: + break; + case 259: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -175: + break; + case 260: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -176: + break; + case 261: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -177: + break; + case 262: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -178: + break; + case 263: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -179: + break; + case 264: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -180: + break; + case 265: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -181: + break; + case 267: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -182: + break; + case 268: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -183: + break; + case 269: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -184: + break; + case 270: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -185: + break; + case 271: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -186: + break; + case 272: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -187: + break; + case 274: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -188: + break; + case 275: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -189: + break; + case 276: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -190: + break; + case 277: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -191: + break; + case 278: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -192: + break; + case 279: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -193: + break; + case 281: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -194: + break; + case 282: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -195: + break; + case 283: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -196: + break; + case 284: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -197: + break; + case 285: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -198: + break; + case 287: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -199: + break; + case 291: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -200: + break; + case 292: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -201: + break; + case 293: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -202: + break; + case 294: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -203: + break; + case 295: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -204: + break; + case 296: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -205: + break; + case 297: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -206: + break; + case 299: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -207: + break; + case 300: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -208: + break; + case 301: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -209: + break; + case 303: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -210: + break; + case 304: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -211: + break; + case 305: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -212: + break; + case 306: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -213: + break; + case 307: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -214: + break; + case 308: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -215: + break; + case 309: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -216: + break; + case 310: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -217: + break; + case 311: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -218: + break; + case 312: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -219: + break; + case 313: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -220: + break; + case 314: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -221: + break; + case 315: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -222: + break; + case 316: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -223: + break; + case 317: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -224: + break; + case 318: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -225: + break; + case 319: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -226: + break; + case 320: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -227: + break; + case 321: + { myTokenType = XmlTokenType.XML_NAME; return; } + case -228: + break; + case 322: + { myTokenType = XmlTokenType.XML_NAME; return;} + case -229: + break; + case 323: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -230: + break; + case 324: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -231: + break; + case 325: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -232: + break; + case 326: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -233: + break; + case 327: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; } + case -234: + break; + case 328: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -235: + break; + case 329: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -236: + break; + case 330: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -237: + break; + case 331: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -238: + break; + case 332: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -239: + break; + case 333: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; } + case -240: + break; + case 334: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -241: + break; + case 335: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return;} + case -242: + break; + default: + yy_error(YY_E_INTERNAL,false); + case -1: + } + yy_initial = true; + yy_state = yy_state_dtrans[yy_lexical_state]; + yy_next_state = YY_NO_STATE; + yy_last_accept_state = YY_NO_STATE; + yy_buffer_start = yy_buffer_index; + yy_this_accept = yy_acpt[yy_state]; + if (YY_NOT_ACCEPT != yy_this_accept) { + yy_last_accept_state = yy_state; + } + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_XmlLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_XmlLexer.java new file mode 100644 index 00000000000..58875ead167 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/lexer/_XmlLexer.java @@ -0,0 +1,845 @@ +/* The following code was generated by JFlex 1.4 on 1/13/05 11:58 AM */ + +/* It's an automatically generated code. Do not modify it. */ + package com.intellij.lexer; + + import com.intellij.psi.tree.IElementType; + import com.intellij.psi.*; + import com.intellij.psi.xml.*; + + + /** +* This class is a scanner generated by +* JFlex 1.4 +* on 1/13/05 11:58 AM from the specification file +* _XmlLexer.flex +*/ + public class _XmlLexer implements Lexer, Cloneable { + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int PROCESSING_INSTRUCTION = 9; + public static final int ATTR_LIST = 4; + public static final int END_TAG = 2; + public static final int ATTR_VALUE_DQ = 7; + public static final int DTD_MARKUP = 6; + public static final int CDATA = 11; + public static final int ATTR = 5; + public static final int TAG = 1; + public static final int YYINITIAL = 0; + public static final int ATTR_VALUE_START = 6; + public static final int COMMENT = 3; + public static final int DOCTYPE = 10; + public static final int ATTR_VALUE_SQ = 8; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\2\3\1\0\2\3\22\0\1\3\1\7\1\51\1\34\2\0"+ + "\1\17\1\52\5\0\1\5\1\4\1\54\12\2\1\1\1\22\1\6"+ + "\1\55\1\16\1\53\1\0\1\13\1\46\1\11\1\12\1\42\1\36"+ + "\2\1\1\50\2\1\1\47\1\44\1\1\1\37\1\41\2\1\1\43"+ + "\1\14\1\45\3\1\1\40\1\1\1\10\1\0\1\15\1\0\1\1"+ + "\1\0\1\23\1\32\4\36\1\20\4\1\1\20\1\33\1\31\1\25"+ + "\1\24\1\27\1\1\1\26\1\21\1\30\2\1\1\35\2\1\uff85\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\3\0\1\1\3\0\2\2\3\0\1\3\1\4\1\5"+ + "\2\6\1\7\1\6\1\10\1\6\1\11\1\1\1\0"+ + "\1\12\3\13\1\14\1\15\1\16\3\2\1\17\2\2"+ + "\1\20\1\6\1\21\1\6\1\22\2\21\2\6\1\3"+ + "\1\0\1\23\1\24\7\0\1\25\2\0\2\2\1\26"+ + "\1\0\1\27\1\0\2\21\1\0\1\2\5\0\1\30"+ + "\10\0\1\31\4\2\2\21\1\32\1\33\2\0\1\34"+ + "\2\0\1\33\1\2\1\33\1\2\2\21\2\0\2\2"+ + "\2\21\2\0\2\2\1\35\1\36\2\0\2\2\2\0"+ + "\2\2\1\37\1\40\2\37"; + + private static int [] zzUnpackAction() { + int [] result = new int[128]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\56\0\134\0\212\0\270\0\346\0\u0114\0\u0142"+ + "\0\u0170\0\u019e\0\u01cc\0\u01fa\0\u0228\0\u0256\0\u0284\0\u02b2"+ + "\0\u0228\0\u02e0\0\u030e\0\u0228\0\u033c\0\u036a\0\u0398\0\u03c6"+ + "\0\u03f4\0\u0228\0\u030e\0\u02b2\0\u0228\0\u0228\0\u0228\0\u0422"+ + "\0\u0450\0\u02b2\0\u0228\0\u047e\0\u04ac\0\u04da\0\u0508\0\u0536"+ + "\0\u0564\0\u0228\0\u0592\0\u05c0\0\u05ee\0\u061c\0\u064a\0\u0678"+ + "\0\u0228\0\u0228\0\u06a6\0\u06d4\0\u0702\0\u0730\0\u075e\0\u078c"+ + "\0\u07ba\0\u0228\0\u07e8\0\u0816\0\u0844\0\u0872\0\u0228\0\u0564"+ + "\0\u0228\0\u08a0\0\u08ce\0\u08fc\0\u05ee\0\u0228\0\u061c\0\u092a"+ + "\0\u0958\0\u0986\0\u09b4\0\u0228\0\u09e2\0\u0a10\0\u0a3e\0\u0a6c"+ + "\0\u0a9a\0\u0ac8\0\u0af6\0\u0b24\0\u0228\0\u0b52\0\u0b80\0\u0bae"+ + "\0\u0bdc\0\u0c0a\0\u0c38\0\u0228\0\u0228\0\u0c66\0\u0c94\0\u0228"+ + "\0\u0cc2\0\u0cf0\0\u0422\0\u0d1e\0\u047e\0\u0d4c\0\u0d7a\0\u0da8"+ + "\0\u0dd6\0\u0e04\0\u0e32\0\u0e60\0\u0e8e\0\u0ebc\0\u0eea\0\u0f18"+ + "\0\u0f46\0\u0f74\0\u0536\0\u0536\0\u0fa2\0\u0fd0\0\u0ffe\0\u102c"+ + "\0\u105a\0\u1088\0\u10b6\0\u10e4\0\u0228\0\u0228\0\u0422\0\u047e"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[128]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\3\15\1\16\2\15\1\17\10\15\1\20\36\15\1\21"+ + "\1\22\1\21\1\16\2\21\1\23\2\21\4\22\1\21"+ + "\1\24\1\20\2\22\1\21\11\22\1\21\14\22\3\21"+ + "\1\25\2\21\1\26\1\21\1\16\2\21\1\23\2\21"+ + "\4\26\1\21\1\24\1\20\2\26\1\21\11\26\1\21"+ + "\14\26\5\21\5\27\1\30\50\27\1\21\1\31\1\21"+ + "\1\16\2\21\1\23\2\21\4\31\2\21\1\20\2\31"+ + "\1\21\11\31\1\21\14\31\5\21\3\32\1\16\2\32"+ + "\1\33\10\32\1\34\31\32\1\35\1\36\2\32\1\37"+ + "\6\21\1\23\10\21\1\20\36\21\6\40\1\41\10\40"+ + "\1\42\31\40\1\43\4\40\6\44\1\45\10\44\1\42"+ + "\32\44\1\43\3\44\1\21\1\46\4\21\1\23\2\21"+ + "\4\46\2\21\1\20\2\46\1\21\11\46\1\21\14\46"+ + "\2\21\1\47\3\21\1\50\1\21\1\16\2\21\1\23"+ + "\1\21\1\51\4\50\1\21\1\52\1\20\2\50\1\21"+ + "\11\50\1\21\4\50\1\53\1\50\1\54\5\50\1\55"+ + "\1\56\3\21\15\15\1\57\40\15\61\0\1\16\61\0"+ + "\1\60\43\0\1\61\1\62\2\0\1\63\7\0\4\63"+ + "\3\0\1\64\1\63\1\0\1\65\3\63\1\66\1\63"+ + "\1\67\2\63\1\70\14\63\6\0\2\22\1\0\2\22"+ + "\3\0\4\22\3\0\2\22\1\0\11\22\1\0\14\22"+ + "\14\0\1\71\64\0\1\72\40\0\2\26\1\0\2\26"+ + "\3\0\4\26\3\0\2\26\1\0\11\26\1\0\14\26"+ + "\5\0\5\27\1\73\55\27\1\74\50\27\1\0\2\31"+ + "\1\0\2\31\3\0\4\31\3\0\2\31\1\0\11\31"+ + "\1\0\14\31\5\0\17\40\1\0\31\40\1\0\13\40"+ + "\1\75\7\40\1\0\31\40\1\0\4\40\17\44\1\0"+ + "\32\44\1\0\12\44\1\76\7\44\1\0\32\44\1\0"+ + "\3\44\1\0\2\46\1\0\2\46\3\0\4\46\3\0"+ + "\2\46\1\0\11\46\1\0\14\46\23\0\1\77\40\0"+ + "\2\50\1\0\2\50\3\0\4\50\3\0\2\50\1\0"+ + "\11\50\1\0\14\50\5\0\15\100\1\101\33\100\1\102"+ + "\4\100\1\0\2\50\1\0\2\50\3\0\4\50\3\0"+ + "\2\50\1\0\11\50\1\0\10\50\1\103\3\50\6\0"+ + "\2\50\1\0\2\50\3\0\4\50\3\0\2\50\1\0"+ + "\11\50\1\0\3\50\1\104\10\50\5\0\51\105\1\106"+ + "\4\105\52\107\1\106\3\107\15\0\1\110\45\0\1\111"+ + "\2\0\1\112\1\0\1\113\44\0\2\63\1\0\2\63"+ + "\3\0\4\63\3\0\2\63\1\114\11\63\1\0\14\63"+ + "\6\0\2\63\1\0\2\63\3\0\4\63\3\0\1\63"+ + "\1\115\1\114\11\63\1\0\14\63\6\0\2\63\1\0"+ + "\2\63\3\0\4\63\3\0\2\63\1\114\1\63\1\116"+ + "\6\63\1\117\1\0\14\63\6\0\2\63\1\0\2\63"+ + "\3\0\4\63\3\0\2\63\1\114\5\63\1\120\3\63"+ + "\1\0\14\63\6\0\2\63\1\0\2\63\3\0\4\63"+ + "\3\0\2\63\1\114\7\63\1\121\1\63\1\0\14\63"+ + "\7\0\1\122\32\0\1\123\25\0\1\111\2\0\1\112"+ + "\45\0\5\27\1\124\66\27\1\125\37\27\5\40\1\126"+ + "\2\40\1\127\6\40\1\0\31\40\1\0\4\40\5\44"+ + "\1\130\2\44\1\131\6\44\1\0\32\44\1\0\3\44"+ + "\51\102\1\100\4\102\1\0\2\50\1\0\2\50\3\0"+ + "\4\50\3\0\2\50\1\0\11\50\1\0\11\50\1\132"+ + "\2\50\6\0\2\50\1\0\2\50\3\0\4\50\3\0"+ + "\2\50\1\0\11\50\1\0\6\50\1\133\5\50\23\0"+ + "\1\134\44\0\1\135\61\0\1\136\103\0\1\137\17\0"+ + "\2\63\1\0\2\63\3\0\4\63\3\0\2\63\1\140"+ + "\11\63\1\0\14\63\6\0\2\63\1\0\2\63\3\0"+ + "\4\63\3\0\2\63\1\114\2\63\1\141\6\63\1\0"+ + "\14\63\6\0\2\63\1\0\2\63\3\0\4\63\3\0"+ + "\2\63\1\114\1\63\1\115\7\63\1\0\14\63\6\0"+ + "\2\63\1\0\2\63\3\0\4\63\3\0\2\63\1\114"+ + "\2\63\1\64\6\63\1\0\14\63\6\0\2\63\1\0"+ + "\2\63\3\0\4\63\3\0\2\63\1\114\3\63\1\117"+ + "\5\63\1\0\14\63\7\0\1\122\17\0\1\140\35\0"+ + "\1\142\6\0\3\142\7\0\1\142\6\0\1\142\3\0"+ + "\1\142\3\0\1\142\3\0\1\142\7\0\16\27\1\0"+ + "\37\27\5\40\1\143\11\40\1\0\31\40\1\0\15\40"+ + "\1\144\5\40\1\0\31\40\1\0\4\40\5\44\1\145"+ + "\11\44\1\0\32\44\1\0\14\44\1\146\5\44\1\0"+ + "\32\44\1\0\3\44\1\0\2\50\1\0\2\50\3\0"+ + "\4\50\3\0\2\50\1\0\11\50\1\0\12\50\1\147"+ + "\1\50\6\0\2\50\1\0\2\50\3\0\3\50\1\150"+ + "\3\0\2\50\1\0\11\50\1\0\14\50\17\0\1\151"+ + "\54\0\1\152\45\0\2\63\1\0\2\63\3\0\4\63"+ + "\3\0\2\63\1\114\3\63\1\115\5\63\1\0\14\63"+ + "\7\0\1\142\6\0\3\142\6\0\1\140\1\142\6\0"+ + "\1\142\3\0\1\142\3\0\1\142\3\0\1\142\7\0"+ + "\12\40\1\153\4\40\1\0\31\40\1\0\4\40\12\44"+ + "\1\154\4\44\1\0\32\44\1\0\3\44\1\0\2\50"+ + "\1\0\2\50\3\0\4\50\3\0\2\50\1\0\11\50"+ + "\1\0\13\50\1\155\6\0\2\50\1\0\2\50\3\0"+ + "\4\50\3\0\2\50\1\0\11\50\1\0\5\50\1\156"+ + "\6\50\20\0\1\157\56\0\1\160\41\0\13\40\1\161"+ + "\3\40\1\0\31\40\1\0\4\40\13\44\1\162\3\44"+ + "\1\0\32\44\1\0\3\44\1\0\2\50\1\0\2\50"+ + "\3\0\1\163\3\50\3\0\2\50\1\0\11\50\1\0"+ + "\14\50\6\0\2\50\1\0\2\50\3\0\4\50\3\0"+ + "\2\50\1\0\11\50\1\0\7\50\1\164\4\50\21\0"+ + "\1\165\101\0\1\166\15\0\14\40\1\167\2\40\1\0"+ + "\31\40\1\0\4\40\14\44\1\170\2\44\1\0\32\44"+ + "\1\0\3\44\13\0\1\171\103\0\1\172\14\0\13\40"+ + "\1\173\3\40\1\0\31\40\1\0\4\40\13\44\1\174"+ + "\3\44\1\0\32\44\1\0\3\44\10\0\1\175\107\0"+ + "\1\176\13\0\10\40\1\177\6\40\1\0\31\40\1\0"+ + "\4\40\10\44\1\200\6\44\1\0\32\44\1\0\3\44"; + + private static int [] zzUnpackTrans() { + int [] result = new int[4370]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + private static final char[] EMPTY_BUFFER = new char[0]; + private static final int YYEOF = -1; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\3\0\1\1\3\0\2\1\3\0\1\11\3\1\1\11"+ + "\2\1\1\11\3\1\1\0\1\1\1\11\2\1\3\11"+ + "\3\1\1\11\6\1\1\11\5\1\1\0\2\11\7\0"+ + "\1\11\2\0\2\1\1\11\1\0\1\11\1\0\2\1"+ + "\1\0\1\11\5\0\1\11\10\0\1\11\6\1\2\11"+ + "\2\0\1\11\2\0\6\1\2\0\4\1\2\0\4\1"+ + "\2\0\2\1\2\0\2\1\2\11\2\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[128]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = EMPTY_BUFFER; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + private IElementType myTokenType; + private int myPrevState = YYINITIAL; + private int myState = YYINITIAL; + + public _XmlLexer(){ + this((java.io.Reader)null); + } + + public final void start(char[] buffer){ + start(buffer, 0, buffer.length); + } + + public final void start(char[] buffer, int startOffset, int endOffset){ + start(buffer, startOffset, endOffset, (short)YYINITIAL); + } + + public final void start(char[] buffer, int startOffset, int endOffset, int initialState){ + zzBuffer = buffer; + zzCurrentPos = zzMarkedPos = zzStartRead = startOffset; + zzPushbackPos = 0; + zzAtEOF = false; + zzEndRead = endOffset; + myTokenType = null; + yybegin(initialState & 15); + myPrevState = (initialState >> 4) & 15; + packState(); + } + + public final int getState(){ + return myState; + } + + private void packState() { + myState = ((myPrevState & 15) << 4) | (zzLexicalState & 15); + } + + public final int getLastState() { + return 11; + } + + public final IElementType getTokenType(){ + locateToken(); + return myTokenType; + } + + public final int getTokenStart(){ + locateToken(); + return zzStartRead - zzPushbackPos; + } + + public final int getTokenEnd(){ + return getTokenStart() + yylength(); + } + + public final void advance(){ + locateToken(); + myTokenType = null; + packState(); + } + + public final char[] getBuffer(){ + return zzBuffer; + } + + public final int getBufferEnd(){ + return zzEndRead; + } + + protected final void locateToken(){ + if (myTokenType != null) return; + try{ + _locateToken(); + } + catch(java.io.IOException ioe){} + } + + public int getSmartUpdateShift() { + return 10; + } + + private int popState(){ + final int prev = myPrevState; + myPrevState = YYINITIAL; + return prev; + } + + private void pushState(int state){ + myPrevState = state; + } + + public Object clone() { + try{ + return super.clone(); + } + catch(CloneNotSupportedException e){ + return null; + } + } + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public _XmlLexer(java.io.Reader in) { + myTokenType = null; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public _XmlLexer(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 140) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() { + if (!zzEOFDone) { + zzEOFDone = true; + + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + public void _locateToken() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 30: + { myTokenType = XmlTokenType.XML_DOCTYPE_SYSTEM; return; + } + case 33: break; + case 24: + { myTokenType = XmlTokenType.XML_ENTITY_REF_TOKEN; return; + } + case 34: break; + case 21: + { myTokenType = XmlTokenType.XML_EMPTY_ELEMENT_END; yybegin(YYINITIAL); return; + } + case 35: break; + case 27: + { myTokenType = XmlTokenType.XML_COMMENT_START; yybegin(COMMENT); return; + } + case 36: break; + case 10: + { myTokenType = XmlTokenType.XML_NAME; yybegin(ATTR); return; + } + case 37: break; + case 28: + { myTokenType = XmlTokenType.XML_CHAR_ENTITY_REF; return; + } + case 38: break; + case 26: + { myTokenType = XmlTokenType.XML_CDATA_END; yybegin(YYINITIAL); return; + } + case 39: break; + case 1: + { myTokenType = XmlTokenType.XML_COMMENT_CHARACTERS; return; + } + case 40: break; + case 29: + { myTokenType = XmlTokenType.XML_DOCTYPE_PUBLIC; return; + } + case 41: break; + case 13: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yybegin(ATTR_VALUE_SQ); return; + } + case 42: break; + case 12: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; yybegin(ATTR_VALUE_DQ); return; + } + case 43: break; + case 6: + { if(yystate() == YYINITIAL){ + myTokenType = XmlTokenType.XML_BAD_CHARACTER; + return; + } + else yybegin(popState()); yypushback(yylength()); + } + case 44: break; + case 32: + { myTokenType = XmlTokenType.XML_DOCTYPE_START; yybegin(DOCTYPE); return; + } + case 45: break; + case 23: + { myTokenType = XmlTokenType.XML_MARKUP; return; + } + case 46: break; + case 16: + { myTokenType = XmlTokenType.XML_NAME; yybegin(ATTR_LIST); pushState(PROCESSING_INSTRUCTION); return; + } + case 47: break; + case 8: + { myTokenType = XmlTokenType.XML_TAG_END; yybegin(YYINITIAL); return; + } + case 48: break; + case 14: + { myTokenType = XmlTokenType.XML_EQ; return; + } + case 49: break; + case 31: + { myTokenType = XmlTokenType.XML_CDATA_START; yybegin(CDATA); return; + } + case 50: break; + case 5: + { myTokenType = XmlTokenType.XML_START_TAG_START; yybegin(TAG); return; + } + case 51: break; + case 18: + { myTokenType = XmlTokenType.XML_DOCTYPE_END; yybegin(YYINITIAL); return; + } + case 52: break; + case 7: + { myTokenType = XmlTokenType.XML_NAME; yybegin(ATTR_LIST); pushState(TAG); return; + } + case 53: break; + case 25: + { myTokenType = XmlTokenType.XML_COMMENT_END; yybegin(YYINITIAL); return; + } + case 54: break; + case 9: + { myTokenType = XmlTokenType.XML_NAME; return; + } + case 55: break; + case 19: + { myTokenType = XmlTokenType.XML_PI_START; yybegin(PROCESSING_INSTRUCTION); return; + } + case 56: break; + case 11: + { yybegin(ATTR_LIST); yypushback(yylength()); + } + case 57: break; + case 2: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; return; + } + case 58: break; + case 4: + { myTokenType = XmlTokenType.XML_WHITE_SPACE; return; + } + case 59: break; + case 15: + { myTokenType = XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; yybegin(ATTR_LIST); return; + } + case 60: break; + case 17: + { myTokenType = XmlTokenType.XML_NAME; return; + } + case 61: break; + case 3: + { myTokenType = XmlTokenType.XML_DATA_CHARACTERS; return; + } + case 62: break; + case 22: + { myTokenType = XmlTokenType.XML_PI_END; yybegin(YYINITIAL); return; + } + case 63: break; + case 20: + { myTokenType = XmlTokenType.XML_END_TAG_START; yybegin(END_TAG); return; + } + case 64: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + return; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionButtonLook.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionButtonLook.java new file mode 100644 index 00000000000..ac52ff80604 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionButtonLook.java @@ -0,0 +1,32 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.actionSystem.ActionButtonComponent; +import com.intellij.openapi.actionSystem.impl.IdeaActionButtonLook; + +import javax.swing.*; +import java.awt.*; + +public abstract class ActionButtonLook { + public static final ActionButtonLook IDEA_LOOK = new IdeaActionButtonLook(); + + public void paintBackground(Graphics g, ButtonType button) { + paintBackground(g, button, getState(button)); + } + + public void paintBorder(Graphics g, ButtonType button) { + paintBorder(g, button, getState(button)); + } + + public abstract void paintBackground(Graphics g, JComponent component, int state); + + public abstract void paintBorder(Graphics g, JComponent component, int state); + + protected int getState(ActionButtonComponent button) { // Do NOT inline this method. + // Because of compiler bug upcast from ButtonType to ActionButtonComponent is important + return button.getPopState(); + } + + public abstract void paintIcon(Graphics g, ActionButtonComponent actionButton, Icon icon); + + public abstract void paintIconAt(Graphics g, ActionButtonComponent button, Icon icon, int x, int y); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java new file mode 100644 index 00000000000..9df5997397a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java @@ -0,0 +1,70 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DataContext; +import org.jdom.Element; + +import javax.swing.*; +import java.util.Comparator; + +public abstract class ActionManagerEx extends ActionManager{ + public static ActionManagerEx getInstanceEx(){ + return (ActionManagerEx)getInstance(); + } + + public abstract void addTimerListener(int delay, TimerListener listener); + public abstract void removeTimerListener(TimerListener listener); + + /** + * @return all action ids which have the specified prefix. + */ + public abstract String[] getActionIds(String idPrefix); + + /** + * @param element XML element for actions tag. + * @param loader + */ + public abstract void processActionsElement(Element element, ClassLoader loader); + + public abstract void addAnActionListener(AnActionListener listener); + public abstract void removeAnActionListener(AnActionListener listener); + public abstract void fireBeforeActionPerformed(AnAction action, DataContext dataContext); + public abstract void fireBeforeEditorTyping(char c, DataContext dataContext); + /** + * For logging purposes + */ + public abstract String getLastPreformedActionId(); + + /** + * Comparator compares action ids (String) on order of action registration. + * @return a negative integer if action that corresponds to the first id was registered earler than the action that corresponds + * to the second id; zero if both ids are equal; a positive number otherwise. + */ + public abstract Comparator getRegistrationOrderComparator(); + + public abstract String[] getConfigurableGroups(); + + /** + * Similar to {@link javax.swing.KeyStroke#getKeyStroke(String)} but allows keys in lower case. + * I.e. "control x" is accepted and interpreted as "control X". + * @return null if string cannot be parsed. + */ + public static KeyStroke getKeyStroke(String s) { + KeyStroke result = null; + try { + result = KeyStroke.getKeyStroke(s); + } catch (Exception ex) { + } + + if (result == null && s != null && s.length() >= 2 && s.charAt(s.length() - 2) == ' ') { + try { + String s1 = s.substring(0, s.length() - 1) + Character.toUpperCase(s.charAt(s.length() - 1)); + result = KeyStroke.getKeyStroke(s1); + } catch (Exception ex) { + } + } + + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/AnActionListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/AnActionListener.java new file mode 100644 index 00000000000..c34d23d3f28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/AnActionListener.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 15, 2002 + * Time: 9:58:27 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DataContext; + +public interface AnActionListener { + void beforeActionPerformed(AnAction action, DataContext dataContext); + void beforeEditorTyping(char c, DataContext dataContext); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java new file mode 100644 index 00000000000..d299da8547c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java @@ -0,0 +1,78 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.actionSystem.DataConstants; + +public interface DataConstantsEx extends DataConstants { + /** + * Returns com.intellij.psi.PsiElement + */ + String TARGET_PSI_ELEMENT = "psi.TargetElement"; + /** + * Returns com.intellij.psi.PsiElement + */ + String PASTE_TARGET_PSI_ELEMENT = "psi.pasteTargetElement"; + /** + * Returns com.intellij.usageView.UsageView + */ + String USAGE_VIEW = "usageView"; + /** + * Returns com.intellij.codeInspection.ui.InsepctionResultsView + */ + String INSPECTION_VIEW = "inspectionView"; + /** + * Returns com.intellij.psi.PsiElement[] + */ + String PSI_ELEMENT_ARRAY = "psi.Element.array"; + /** + * Returns com.intellij.ide.CopyProvider + */ + String COPY_PROVIDER = "copyProvider"; + /** + * Returns com.intellij.ide.CutProvider + */ + String CUT_PROVIDER = "cutProvider"; + /** + * Returns com.intellij.ide.PasteProvider + */ + String PASTE_PROVIDER = "pasteProvider"; + /** + * Returns com.intellij.ide.IdeView + */ + String IDE_VIEW = "IDEView"; + /** + * Returns com.intellij.ide.DeleteProvider + */ + String DELETE_ELEMENT_PROVIDER = "deleteElementProvider"; + /** + * Returns TreeExpander + */ + String TREE_EXPANDER = "treeExpander"; + /** + * Returns ContentManager + */ + String CONTENT_MANAGER = "contentManager"; + + /** + * Returns java.awt.Component + */ + String CONTEXT_COMPONENT = "contextComponent"; + /** + * Returns RuntimeConfiguration + */ + String RUNTIME_CONFIGURATION = "runtimeConfiguration"; + + /** Returns PsiElement */ + String SECONDARY_PSI_ELEMENT = "secondaryPsiElement"; + + /** + * Returns project file directory + */ + String PROJECT_FILE_DIRECTORY = "context.ProjectFileDirectory"; + + String MODALITY_STATE = "ModalityState"; + + /** + * returns Boolean + */ + String SOURCE_NAVIGATION_LOCKED = "sourceNavigationLocked"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickList.java new file mode 100644 index 00000000000..ea6ee3fdd3a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickList.java @@ -0,0 +1,147 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class QuickList { + public static final String QUICK_LIST_PREFIX = "QuickList."; + public static final String SEPARATOR_ID = QUICK_LIST_PREFIX + "$Separator$"; + + private static final String ID_TAG = "id"; + private static final String READONLY_TAG = "readonly"; + private static final String ACTION_TAG = "action"; + private static final String DISPLAY_NAME_TAG = "display"; + private static final String DESCRIPTION_TAG = "description"; + + + private String myDisplayName; + private String myDescription; + private String[] myActionIds; + private String[] myDefaultIds; + private boolean myReadonly; + + /** + * With read external to be called immediately after in mind + */ + QuickList() {} + + public QuickList(String displayName, String description, String[] actionIds, boolean isReadonly) { + this(displayName, description, actionIds, ArrayUtil.EMPTY_STRING_ARRAY, isReadonly); + } + + public QuickList(String displayName, String description, String[] actionIds, String[] defaultIds, boolean isReadonly) { + myDisplayName = displayName == null ? "" : displayName; + myDescription = description == null ? "" : description; + myActionIds = actionIds; + myDefaultIds = defaultIds; + myReadonly = isReadonly; + } + + public String getDisplayName() { + return myDisplayName; + } + + public boolean isReadonly() { + return myReadonly; + } + + public String getDescription() { + return myDescription; + } + + public String[] getActionIds() { + return myActionIds; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof QuickList)) return false; + + final QuickList quickList = (QuickList)o; + + if (!Arrays.equals(myActionIds, quickList.myActionIds)) return false; + if (!myDescription.equals(quickList.myDescription)) return false; + if (!myDisplayName.equals(quickList.myDisplayName)) return false; + + return true; + } + + public int hashCode() { + return 29 * myDisplayName.hashCode() + myDescription.hashCode(); + + } + + public String getActionId() { + return QUICK_LIST_PREFIX + getDisplayName(); + } + + public Map> getShortcutMap(final List keymaps) { + Map> listShortcuts = new HashMap>(); + String actionId = getActionId(); + for (int i = 0; i < keymaps.size(); i++) { + Keymap keymap = keymaps.get(i); + Shortcut[] shortcuts = keymap.getShortcuts(actionId); + if (shortcuts.length > 0) { + listShortcuts.put(keymap, new ArrayList(Arrays.asList(shortcuts))); + } + } + return listShortcuts; + } + + public void unregisterAllShortcuts(final List keymaps) { + for (int i = 0; i < keymaps.size(); i++) { + Keymap keymap = keymaps.get(i); + keymap.removeAllActionShortcuts(getActionId()); + } + } + + public void registerShortcuts(Map> shortcutMap, final List keymaps) { + String actionId = getActionId(); + for (int i = 0; i < keymaps.size(); i++) { + Keymap keymap = keymaps.get(i); + ArrayList shortcuts = shortcutMap.get(keymap); + if (shortcuts != null) { + for (int j = 0; j < shortcuts.size(); j++) { + Shortcut shortcut = shortcuts.get(j); + keymap.addShortcut(actionId, shortcut); + } + } + } + } + + public void writeExternal(Element groupElement) { + groupElement.setAttribute(DISPLAY_NAME_TAG, getDisplayName()); + groupElement.setAttribute(DESCRIPTION_TAG, getDescription()); + groupElement.setAttribute(READONLY_TAG, String.valueOf(isReadonly())); + + String[] actionIds = getActionIds(); + for (int j = 0; j < actionIds.length; j++) { + String actionId = actionIds[j]; + Element actionElement = new Element(ACTION_TAG); + actionElement.setAttribute(ID_TAG, actionId); + groupElement.addContent(actionElement); + } + } + + public void readExternal(Element element) { + myDisplayName = element.getAttributeValue(DISPLAY_NAME_TAG); + myDescription = element.getAttributeValue(DESCRIPTION_TAG); + myReadonly = Boolean.valueOf(element.getAttributeValue(READONLY_TAG)).booleanValue(); + List ids = new ArrayList(); + List actions = element.getChildren(ACTION_TAG); + for (int j = 0; j < actions.size(); j++) { + Element actionElement = (Element)actions.get(j); + ids.add(actionElement.getAttributeValue(ID_TAG)); + } + myActionIds = ids.toArray(new String[ids.size()]); + myDefaultIds = ArrayUtil.EMPTY_STRING_ARRAY; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickListsManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickListsManager.java new file mode 100644 index 00000000000..dd02a2c7c4d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/QuickListsManager.java @@ -0,0 +1,200 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.ide.actions.QuickSwitchSchemeAction; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.diagnostic.Logger; +import org.jdom.Element; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * @author max + */ +public class QuickListsManager implements ExportableApplicationComponent, NamedJDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.ex.QuickListsManager"); + + private final List myQuickLists = new ArrayList(); + private static final String LIST_TAG = "list"; + private ActionManager myActionManager; + private DataManager myDataManager; + + public static QuickListsManager getInstance() { + return ApplicationManager.getApplication().getComponent(QuickListsManager.class); + } + + public QuickListsManager(ActionManagerEx actionManagerEx, DataManager dataManager) { + myActionManager = actionManagerEx; + myDataManager = dataManager; + + String[] groups = actionManagerEx.getConfigurableGroups(); + for (int i = 0; i < groups.length; i++) { + String groupId = groups[i]; + ActionGroup group = (ActionGroup)actionManagerEx.getAction(groupId); + registerQuickList(group); + } + registerActions(); + } + + public String getComponentName() { + return "QuickListsManager"; + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Quick lists"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public String getExternalFileName() { + return "quicklists"; + } + + public void readExternal(Element element) throws InvalidDataException { + List groups = element.getChildren(LIST_TAG); + for (int i = 0; i < groups.size(); i++) { + Element groupElement = (Element)groups.get(i); + QuickList list = new QuickList(); + list.readExternal(groupElement); + registerQuickList(list, true); + } + registerActions(); + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myQuickLists.size(); i++) { + QuickList list = myQuickLists.get(i); + Element groupElement = new Element(LIST_TAG); + list.writeExternal(groupElement); + element.addContent(groupElement); + } + } + + public QuickList[] getAllQuickLists() { + return myQuickLists.toArray(new QuickList[myQuickLists.size()]); + } + + public void removeAllQuickLists() { + myQuickLists.clear(); + } + + public void registerQuickList(ActionGroup group) { + Presentation presentation = group.getTemplatePresentation(); + registerQuickList(group, presentation.getText(), presentation.getDescription(), false); + } + + public void registerQuickList(ActionGroup group, String name, String description, boolean deleteable) { + AnAction[] actions = group.getChildren(new AnActionEvent(null, myDataManager.getDataContext(), "QUICK_LIST_MANAGER", group.getTemplatePresentation(), myActionManager, 0)); + String[] ids = new String[actions.length]; + for (int i = 0; i < actions.length; i++) { + AnAction action = actions[i]; + if (action instanceof Separator) { + ids[i] = QuickList.SEPARATOR_ID; + } + else { + ids[i] = myActionManager.getId(action); + if (ids[i] == null) { + LOG.error("Cannot find id for action: " + action); + ids[i] = QuickList.SEPARATOR_ID; + } + } + } + + registerQuickList(new QuickList(name, description, ids, !deleteable), false); + } + + public void registerQuickList(QuickList list, boolean replaceExisting) { + int replaceIdx = -1; + for (int i = 0; i < myQuickLists.size(); i++) { + QuickList quickList = myQuickLists.get(i); + if (list.getActionId().equals(quickList.getActionId())) { + replaceIdx = i; + break; + } + } + + if (replaceIdx != -1) { + if (replaceExisting) { + myQuickLists.set(replaceIdx, list); + } + } + else { + myQuickLists.add(list); + } + } + + public void registerActions() { + unregisterActions(); + HashSet registeredIds = new HashSet(); // to prevent exception if 2 or more targets have the same name + + ActionManager actionManager = myActionManager; + for (int i = 0; i < myQuickLists.size(); i++) { + QuickList list = myQuickLists.get(i); + String actionId = list.getActionId(); + + if (!registeredIds.contains(actionId)) { + registeredIds.add(actionId); + actionManager.registerAction(actionId, new InvokeQuickListAction(list)); + } + } + } + + public void unregisterActions() { + ActionManagerEx actionManager = (ActionManagerEx)myActionManager; + + String[] oldIds = actionManager.getActionIds(QuickList.QUICK_LIST_PREFIX); + for (int i = 0; i < oldIds.length; i++) { + String oldId = oldIds[i]; + actionManager.unregisterAction(oldId); + } + } + + private static class InvokeQuickListAction extends QuickSwitchSchemeAction { + private QuickList myQuickList; + + public InvokeQuickListAction(QuickList quickList) { + myQuickList = quickList; + getTemplatePresentation().setDescription(myQuickList.getDescription()); + getTemplatePresentation().setText(myQuickList.getDisplayName(), false); + } + + protected void fillActions(Project project, DefaultActionGroup group) { + String[] actionIds = myQuickList.getActionIds(); + ActionManager actionManager = ActionManagerEx.getInstance(); + for (int i = 0; i < actionIds.length; i++) { + String actionId = actionIds[i]; + if (QuickList.SEPARATOR_ID.equals(actionId)) { + group.addSeparator(); + } + else { + AnAction action = actionManager.getAction(actionId); + if (action != null) { + group.add(action); + } + } + } + } + + protected boolean isEnabled() { + return true; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/TimerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/TimerListener.java new file mode 100644 index 00000000000..908e8236b46 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/ex/TimerListener.java @@ -0,0 +1,8 @@ +package com.intellij.openapi.actionSystem.ex; + +import com.intellij.openapi.application.ModalityState; + +public interface TimerListener { + ModalityState getModalityState(); + void run(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButton.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButton.java new file mode 100644 index 00000000000..5677c909fef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButton.java @@ -0,0 +1,280 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.impl.IdeFrame; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ActionButton extends JComponent implements ActionButtonComponent { + private static final Insets ICON_INSETS = new Insets(2, 2, 2, 2); + + private static final Icon ourEmptyIcon = EmptyIcon.create(18, 18); + + private Dimension myMinimumButtonSize; + private PropertyChangeListener myActionButtonSynchronizer; + private Icon myDisabledIcon; + private Icon myIcon; + protected Presentation myPresentation; + protected AnAction myAction; + private String myPlace; + private ActionButtonLook myLook = ActionButtonLook.IDEA_LOOK; + protected boolean myMouseDown; + protected boolean myRollover; + private static boolean ourGlobalMouseDown = false; + + public ActionButton( + final AnAction action, + final Presentation presentation, + final String place, + final Dimension minimumSize + ) { + if (minimumSize == null) { + throw new IllegalArgumentException("minimumSize cannot be null"); + } + setMinimumButtonSize(minimumSize); + myRollover = false; + myMouseDown = false; + myAction = action; + myPresentation = presentation; + myPlace = place; + setFocusable(false); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + myMinimumButtonSize = minimumSize; + } + + public void setMinimumButtonSize(Dimension size) { + if (size == null) { + throw new IllegalArgumentException("size cannot be null"); + } + myMinimumButtonSize = size; + } + + public void paintChildren(Graphics g) {} + + public int getPopState() { + if (myAction instanceof ToggleAction) { + Boolean selected = (Boolean)myPresentation.getClientProperty(ToggleAction.SELECTED_PROPERTY); + boolean flag1 = selected != null && selected.booleanValue(); + return getPopState(flag1); + } + else { + return getPopState(false); + } + } + + protected boolean isButtonEnabled() { + return myPresentation.isEnabled(); + } + + protected void onMousePresenceChanged(boolean setInfo) { + IdeFrame frame = (IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class, this); + if (frame != null) { + frame.getStatusBar().setInfo(setInfo ? myPresentation.getDescription() : null); + } + } + + protected void performAction(MouseEvent e) { + AnActionEvent event = new AnActionEvent( + e, + DataManager.getInstance().getDataContext(), + myPlace, + myPresentation, + ActionManager.getInstance(), + e.getModifiers() + ); + myAction.update(event); + if (isButtonEnabled()) { + ActionManagerEx.getInstanceEx().fireBeforeActionPerformed(myAction, event.getDataContext()); + Component component = ((Component)event.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT)); + if (component != null && !component.isShowing()) { + return; + } + myAction.actionPerformed(event); + } + } + + public void removeNotify() { + if (myActionButtonSynchronizer != null) { + myPresentation.removePropertyChangeListener(myActionButtonSynchronizer); + myActionButtonSynchronizer = null; + } + super.removeNotify(); + } + + public void addNotify() { + super.addNotify(); + if (myActionButtonSynchronizer == null) { + myActionButtonSynchronizer = new ActionButtonSynchronizer(); + myPresentation.addPropertyChangeListener(myActionButtonSynchronizer); + } + updateToolTipText(); + updateIcon(); + } + + public void setToolTipText(String s) { + String tooltipText = AnAction.createTooltipText(s, myAction); + super.setToolTipText(tooltipText.length() > 0 ? tooltipText : null); + } + + public Dimension getPreferredSize() { + Icon icon = getIcon(); + if ( + icon.getIconWidth() < myMinimumButtonSize.width && + icon.getIconHeight() < myMinimumButtonSize.height + ) { + return myMinimumButtonSize; + } + else { + return new Dimension( + icon.getIconWidth() + ICON_INSETS.left + ICON_INSETS.right, + icon.getIconHeight() + ICON_INSETS.top + ICON_INSETS.bottom + ); + } + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + /** + * @return button's icon. Icon depends on action's state. It means that the method returns + * disabled icon if action is disabled. If the action's icon is null then it returns + * an empty icon. + */ + protected Icon getIcon() { + Icon icon = isButtonEnabled() ? myIcon : myDisabledIcon; + if (icon == null) { + icon = ourEmptyIcon; + } + return icon; + } + + private void updateIcon() { + myIcon = myPresentation.getIcon(); + if (myPresentation.getDisabledIcon() != null) { // set disabled icon if it is specified + myDisabledIcon = myPresentation.getDisabledIcon(); + } + else { + myDisabledIcon = IconLoader.getDisabledIcon(myIcon); + } + } + + private void setDisabledIcon(Icon icon) { + myDisabledIcon = icon; + } + + void updateToolTipText() { + setToolTipText(myPresentation.getText()); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + ActionButtonLook look = getButtonLook(); + look.paintBackground(g, this); + look.paintIcon(g, this, getIcon()); + look.paintBorder(g, this); + } + + private ActionButtonLook getButtonLook() { + return myLook; + } + + public void setLook(ActionButtonLook look) { + if (look != null) { + myLook = look; + } + else { + myLook = ActionButtonLook.IDEA_LOOK; + } + repaint(); + } + + protected void processMouseEvent(MouseEvent e) { + super.processMouseEvent(e); + if (e.isConsumed()) return; + boolean flag = e.isMetaDown(); + switch (e.getID()) { + case MouseEvent.MOUSE_PRESSED: + { + if (flag || !isButtonEnabled()) return; + myMouseDown = true; + ourGlobalMouseDown = true; + repaint(); + break; + } + + case MouseEvent.MOUSE_RELEASED: + { + if (flag || !isButtonEnabled()) return; + myMouseDown = false; + ourGlobalMouseDown = false; + if (myRollover) { + performAction(e); + } + repaint(); + break; + } + + case MouseEvent.MOUSE_ENTERED: + { + if (!myMouseDown && ourGlobalMouseDown) break; + myRollover = true; + repaint(); + onMousePresenceChanged(true); + break; + } + + case MouseEvent.MOUSE_EXITED: + { + myRollover = false; + if (!myMouseDown && ourGlobalMouseDown) break; + repaint(); + onMousePresenceChanged(false); + break; + } + } + } + + protected int getPopState(boolean isPushed) { + if (isPushed || myRollover && myMouseDown && isButtonEnabled()) { + return PUSHED; + } + else { + return !myRollover || !isButtonEnabled() ? NORMAL : POPPED; + } + } + + private class ActionButtonSynchronizer implements PropertyChangeListener { + public void propertyChange(PropertyChangeEvent e) { + String propertyName = e.getPropertyName(); + if (Presentation.PROP_TEXT.equals(propertyName)) { + updateToolTipText(); + } + else if (Presentation.PROP_ENABLED.equals(propertyName)) { + repaint(); + } + else if (Presentation.PROP_ICON.equals(propertyName)) { + updateIcon(); + repaint(); + } + else if (Presentation.PROP_DISABLED_ICON.equals(propertyName)) { + setDisabledIcon(myPresentation.getDisabledIcon()); + repaint(); + } + else if (Presentation.PROP_VISIBLE.equals(propertyName)) { + } + else if ("selected".equals(propertyName)) { + repaint(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButtonWithText.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButtonWithText.java new file mode 100644 index 00000000000..266661180aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionButtonWithText.java @@ -0,0 +1,80 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +public class ActionButtonWithText extends ActionButton { + private static final int ICON_TEXT_SPACE = 2; + + public ActionButtonWithText(final AnAction action, + final Presentation presentation, + final String place, + final Dimension minimumSize) { + super(action, presentation, place, minimumSize); + setFont(UIManager.getFont("Label.font")); + } + + public Dimension getPreferredSize() { + final Dimension preferredSize = new Dimension(super.getPreferredSize()); + final String text = getText(); + final FontMetrics fontMetrics = getFontMetrics(getFont()); + preferredSize.width += ICON_TEXT_SPACE; + preferredSize.width += fontMetrics.stringWidth(text); + return preferredSize; + } + + public void paintComponent(Graphics g) { + final String text = getText(); + final Icon icon = getIcon(); + final FontMetrics fontMetrics = getFontMetrics(getFont()); + int x = (int)Math.ceil((getWidth() - icon.getIconWidth() - fontMetrics.stringWidth(text)) / 2); + int y = (int)Math.ceil((getHeight() - icon.getIconHeight()) / 2); + ActionButtonLook look = ActionButtonLook.IDEA_LOOK; + look.paintBackground(g, this); + look.paintIconAt(g, this, icon, x, y); + look.paintBorder(g, this); + final int textHeight = fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent(); + + g.setColor(isButtonEnabled() ? UIManager.getColor("Label.foreground") : UIManager.getColor("textInactiveText")); + final int iconTextDifference = (int)Math.ceil((icon.getIconHeight() - textHeight) / 2); + final int textStartX = x + icon.getIconWidth() + ICON_TEXT_SPACE; + g.drawString(text, textStartX, y + iconTextDifference + fontMetrics.getMaxAscent()); + final int mnemonicIndex = getMnemonicCharIndex(text); + if (mnemonicIndex >= 0) { + final char[] chars = text.toCharArray(); + final int startX = textStartX + fontMetrics.charsWidth(chars, 0, mnemonicIndex); + final int startY = y + iconTextDifference + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent(); + final int endX = startX + fontMetrics.charWidth(text.charAt(mnemonicIndex)); + g.drawLine(startX, startY, endX, startY); + } + } + + private int getMnemonicCharIndex(String text) { + final ShortcutSet shortcutSet = myAction.getShortcutSet(); + final Shortcut[] shortcuts = shortcutSet.getShortcuts(); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + KeyboardShortcut keyboardShortcut = (KeyboardShortcut)shortcut; + if (keyboardShortcut.getSecondKeyStroke() == null) { // we are interested only in "mnemonic-like" shortcuts + final KeyStroke keyStroke = keyboardShortcut.getFirstKeyStroke(); + final int modifiers = keyStroke.getModifiers(); + if ((modifiers & KeyEvent.ALT_MASK) != 0) { + return (keyStroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED)? text.indexOf(keyStroke.getKeyChar()) : text.indexOf(KeyEvent.getKeyText(keyStroke.getKeyCode())); + } + } + } + } + return -1; + } + + private String getText() { + final String text = myPresentation.getText(); + return text != null? text : ""; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java new file mode 100644 index 00000000000..3024d9b950c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -0,0 +1,719 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.idea.IdeaLogger; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.AnActionListener; +import com.intellij.openapi.actionSystem.ex.TimerListener; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.ide.DataManager; +import gnu.trove.THashMap; +import org.jdom.Element; +import org.picocontainer.defaults.ConstructorInjectionComponentAdapter; + +import javax.swing.*; +import javax.swing.Timer; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; + +public final class ActionManagerImpl extends ActionManagerEx implements JDOMExternalizable, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl"); + private final Object myLock = new Object(); + private THashMap myId2Action; + private THashMap myId2Index; + private THashMap myAction2Id; + private ArrayList myNotRegisteredInternalActionIds; + private final Map myRunnable2Timer = new HashMap(); + private int myRegisteredActionsCount; + private ArrayList myActionListeners; + private AnActionListener[] myCachedActionListeners; + private String myLastPreformedActionId; + private KeymapManager myKeymapManager; + private DataManager myDataManager; + + ActionManagerImpl(KeymapManager keymapManager, DataManager dataManager) { + myId2Action = new THashMap(); + myId2Index = new THashMap(); + myAction2Id = new THashMap(); + myNotRegisteredInternalActionIds = new ArrayList(); + myActionListeners = new ArrayList(); + myCachedActionListeners = null; + myKeymapManager = keymapManager; + myDataManager = dataManager; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public void addTimerListener(int delay, final TimerListener listener) { + Timer timer = new Timer(delay, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + ModalityState modalityState = listener.getModalityState(); + if (modalityState == null) return; + if (!ModalityState.current().dominates(modalityState)) { + listener.run(); + } + } + }); + synchronized (myRunnable2Timer) { + myRunnable2Timer.put(listener, timer); + } + timer.setRepeats(true); + timer.start(); + } + + public void removeTimerListener(TimerListener listener) { + synchronized (myRunnable2Timer) { + Timer timer = myRunnable2Timer.get(listener); + if (timer != null) { + timer.stop(); + myRunnable2Timer.remove(listener); + } + else { + LOG.error("removeTimerListener for not registered"); + } + } + } + + public ActionPopupMenu createActionPopupMenu(String place, ActionGroup group) { + return new ActionPopupMenuImpl(place, group); + } + + public ActionToolbar createActionToolbar(final String place, final ActionGroup group, final boolean horizontal) { + return new ActionToolbarImpl(place, group, horizontal, myDataManager, this, (KeymapManagerEx)myKeymapManager); + } + + + public void readExternal(Element element) { + final ClassLoader classLoader = this.getClass().getClassLoader(); + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element children = (Element)i.next(); + if ("actions".equals(children.getName())) { + processActionsElement(children, classLoader); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + throw new WriteExternalException(); + } + + public AnAction getAction(String id) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: getAction(" + id + ")"); + } + if (id == null) { + throw new IllegalArgumentException("id cannot be null"); + } + return getActionImpl(id, false); + } + + private AnAction getActionImpl(String id, boolean canReturnStub) { + AnAction action = (AnAction)myId2Action.get(id); + if (!canReturnStub && (action instanceof ActionStub)) { + action = convert((ActionStub)action); + } + return action; + } + + /** + * Converts action's stub to normal action. + */ + private AnAction convert(ActionStub stub) { + synchronized (myLock) { + LOG.assertTrue(myAction2Id.contains(stub)); + myAction2Id.remove(stub); + + LOG.assertTrue(myId2Action.contains(stub.getId())); + + AnAction action = (AnAction)myId2Action.remove(stub.getId()); + LOG.assertTrue(action != null); + LOG.assertTrue(action.equals(stub)); + + Object obj; + String className = stub.getClassName(); + try { + obj = Class.forName(className, true, stub.getLoader()).newInstance(); + } + catch (ClassNotFoundException e) { + throw new IllegalStateException("class with name \"" + className + "\" not found"); + } + catch (Exception e) { + throw new IllegalStateException("cannot create class \"" + className + "\""); + } + + if (!(obj instanceof AnAction)) { + throw new IllegalStateException("class with name \"" + className + "\" should be instance of " + AnAction.class.getName()); + } + + stub.initAction((AnAction)obj); + ((AnAction)obj).getTemplatePresentation().setText(stub.getText()); + + myId2Action.put(stub.getId(), obj); + myAction2Id.put(obj, stub.getId()); + + return (AnAction)obj; + } + } + + + public String getId(AnAction action) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: getId(" + action + ")"); + } + if (action == null) { + throw new IllegalArgumentException("action cannot be null"); + } + LOG.assertTrue(!(action instanceof ActionStub)); + synchronized (myLock) { + return (String)myAction2Id.get(action); + } + } + + public String[] getActionIds(String idPrefix) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: getActionIds(" + idPrefix + ")"); + } + if (idPrefix == null) { + LOG.error("idPrefix cannot be null"); + return null; + } + synchronized (myLock) { + ArrayList idList = new ArrayList(); + for (Iterator i = myId2Action.keySet().iterator(); i.hasNext();) { + String id = (String)i.next(); + if (id.startsWith(idPrefix)) { + idList.add(id); + } + } + return (String[])idList.toArray(new String[idList.size()]); + } + } + + /** + * @return instance of ActionGroup or ActionStub. The method never returns real subclasses + * of AnAction. + */ + private AnAction processActionElement(Element element, final ClassLoader loader) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processActionElement(" + element.getName() + ")"); + } + if (!"action".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return null; + } + String className = element.getAttributeValue("class"); + if (className == null || className.length() == 0) { + LOG.error("action element should have specified \"class\" attribute"); + return null; + } + // read ID and register loaded action + String id = element.getAttributeValue("id"); + if (id == null || id.length() == 0) { + LOG.error("ID of the action cannot be an empty string"); + return null; + } + if (Boolean.valueOf(element.getAttributeValue("internal")).booleanValue() && !ApplicationManagerEx.getApplicationEx().isInternal()) { + myNotRegisteredInternalActionIds.add(id); + return null; + } + + // text + String text = element.getAttributeValue("text"); + if (text == null) { + LOG.error("'text' attribute is mandatory (action ID=" + id + ")"); + return null; + } + ActionStub stub = new ActionStub(className, id, text, loader); + Presentation presentation = stub.getTemplatePresentation(); + presentation.setText(text); + // description + String description = element.getAttributeValue("description"); + presentation.setDescription(description); + // icon + String iconPath = element.getAttributeValue("icon"); + if (iconPath != null) { + try { + final Class actionClass = Class.forName(className, true, loader); + presentation.setIcon(IconLoader.getIcon(iconPath, actionClass)); + } + catch (ClassNotFoundException ignored) { + } + } + // process all links and key bindings if any + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element e = (Element)i.next(); + if ("add-to-group".equals(e.getName())) { + processAddToGroupNode(stub, e); + } + else if ("keyboard-shortcut".equals(e.getName())) { + processKeyboardShortcutNode(e, id); + } + else if ("mouse-shortcut".equals(e.getName())) { + processMouseShortcutNode(e, id); + } + else { + LOG.error("unexpected name of element \"" + e.getName() + "\""); + return null; + } + } + // register action + registerAction(id, stub); + return stub; + } + + private AnAction processGroupElement(Element element, final ClassLoader loader) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processGroupElement(" + element.getName() + ")"); + } + if (!"group".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return null; + } + String className = element.getAttributeValue("class"); + if (className == null) { // use default group if class isn't specified + className = DefaultActionGroup.class.getName(); + } + try { + Class aClass = Class.forName(className, true, loader); + Object obj = new ConstructorInjectionComponentAdapter(className, aClass).getComponentInstance(ApplicationManager.getApplication().getPicoContainer()); + + if (!(obj instanceof ActionGroup)) { + LOG.error("class with name \"" + className + "\" should be instance of " + ActionGroup.class.getName()); + return null; + } + if (element.getChildren().size() > 0) { + if (!(obj instanceof DefaultActionGroup)) { + LOG.error("class with name \"" + className + "\" should be instance of " + DefaultActionGroup.class.getName() + + " because there are children specified"); + return null; + } + } + ActionGroup group = (ActionGroup)obj; + // read ID and register loaded group + String id = element.getAttributeValue("id"); + if (id != null && id.length() == 0) { + LOG.error("ID of the group cannot be an empty string"); + return null; + } + if (Boolean.valueOf(element.getAttributeValue("internal")).booleanValue() && !ApplicationManagerEx.getApplicationEx().isInternal()) { + myNotRegisteredInternalActionIds.add(id); + return null; + } + + if (id != null) { + registerAction(id, group); + } + // text + Presentation presentation = group.getTemplatePresentation(); + String text = element.getAttributeValue("text"); + presentation.setText(text); + // description + String description = element.getAttributeValue("description"); + presentation.setDescription(description); + // icon + String iconPath = element.getAttributeValue("icon"); + if (iconPath != null) { + presentation.setIcon(IconLoader.getIcon(iconPath)); + } + // popup + String popup = element.getAttributeValue("popup"); + if (popup != null) { + group.setPopup(Boolean.valueOf(popup).booleanValue()); + } + // process all group's children. There are other groups, actions, references and links + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element child = (Element)i.next(); + String name = child.getName(); + if ("action".equals(name)) { + AnAction action = processActionElement(child, loader); + if (action != null) { + LOG.assertTrue((action instanceof ActionGroup) || (action instanceof ActionStub)); + ((DefaultActionGroup)group).add(action); + } + } + else if ("separator".equals(name)) { + processSeparatorNode((DefaultActionGroup)group, child); + } + else if ("group".equals(name)) { + AnAction action = processGroupElement(child, loader); + if (action != null) { + ((DefaultActionGroup)group).add(action); + } + } + else if ("add-to-group".equals(name)) { + processAddToGroupNode(group, child); + } + else if ("reference".equals(name)) { + AnAction action = processReferenceElement(child); + if (action != null) { + ((DefaultActionGroup)group).add(action); + } + } + else { + LOG.error("unexpected name of element \"" + name + "\n"); + return null; + } + } + return group; + } + catch (ClassNotFoundException e) { + LOG.error("class with name \"" + className + "\" not found"); + return null; + } + catch (Exception e) { + LOG.error("cannot create class \"" + className + "\"", e); + return null; + } + } + + /** + * @param element description of link + */ + private void processAddToGroupNode(AnAction action, Element element) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processAddToGroupNode(" + action + "," + element.getName() + ")"); + } + + // Real subclasses of AnAction should not be here + LOG.assertTrue((action instanceof ActionGroup) || (action instanceof ActionStub) || (action instanceof Separator)); + + if (!"add-to-group".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return; + } + String groupId = element.getAttributeValue("group-id"); + if (groupId == null || groupId.length() == 0) { + LOG.error("attribute \"group-id\" should be defined"); + return; + } + AnAction parentGroup = getActionImpl(groupId, true); + if (parentGroup == null) { + LOG.error("action with id \"" + groupId + "\" isn't registered; action will be added to the \"Other\" group"); + parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true); + } + if (!(parentGroup instanceof DefaultActionGroup)) { + LOG.error("action with id \"" + groupId + "\" should be instance of " + DefaultActionGroup.class.getName()); + return; + } + String anchorStr = element.getAttributeValue("anchor"); + if (anchorStr == null || groupId.length() == 0) { + LOG.error("attribute \"anchor\" should be defined"); + return; + } + Anchor anchor; + if ("first".equalsIgnoreCase(anchorStr)) { + anchor = Anchor.FIRST; + } + else if ("last".equalsIgnoreCase(anchorStr)) { + anchor = Anchor.LAST; + } + else if ("before".equalsIgnoreCase(anchorStr)) { + anchor = Anchor.BEFORE; + } + else if ("after".equalsIgnoreCase(anchorStr)) { + anchor = Anchor.AFTER; + } + else { + LOG.error("anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\""); + return; + } + String relativeToActionId = element.getAttributeValue("relative-to-action"); + if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) { + LOG.error("\"relative-to-action\" cannot be null if anchor is \"after\" or \"before\""); + return; + } + ((DefaultActionGroup)parentGroup).add(action, new Constraints(anchor, relativeToActionId)); + } + + /** + * @param parentGroup group wich is the parent of the separator. It can be null in that + * case separator will be added to group described in the subelement. + * @param element XML element which represent separator. + */ + private void processSeparatorNode(DefaultActionGroup parentGroup, Element element) { + if (!"separator".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return; + } + Separator separator = Separator.getInstance(); + if (parentGroup != null) { + parentGroup.add(separator); + } + // try to find inner tag + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element child = (Element)i.next(); + if ("add-to-group".equals(child.getName())) { + processAddToGroupNode(separator, child); + } + } + } + + private void processKeyboardShortcutNode(Element element, String actionId) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processKeyboardShortcutNode(" + element.getName() + ")"); + } + + String firstStrokeString = element.getAttributeValue("first-keystroke"); + if (firstStrokeString == null) { + LOG.error("\"first-keystroke\" attribute must be specified for action with id=" + actionId); + return; + } + KeyStroke firstKeyStroke = getKeyStroke(firstStrokeString); + if (firstKeyStroke == null) { + LOG.error("\"first-keystroke\" attribute has invalid value for action with id=" + actionId); + return; + } + + KeyStroke secondKeyStroke = null; + String secondStrokeString = element.getAttributeValue("second-keystroke"); + if (secondStrokeString != null) { + secondKeyStroke = getKeyStroke(secondStrokeString); + if (secondKeyStroke == null) { + LOG.error("\"second-keystroke\" attribute has invalid value for action with id=" + actionId); + return; + } + } + + String keymapName = element.getAttributeValue("keymap"); + if (keymapName == null || keymapName.trim().length() == 0) { + LOG.error("attribute \"keymap\" should be defined"); + return; + } + Keymap keymap = myKeymapManager.getKeymap(keymapName); + if (keymap == null) { + LOG.error("keymap \"" + keymapName + "\" not found"); + return; + } + + keymap.addShortcut(actionId, new KeyboardShortcut(firstKeyStroke, secondKeyStroke)); + } + + private void processMouseShortcutNode(Element element, String actionId) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processMouseShortcutNode(" + element.getName() + ")"); + } + + String keystrokeString = element.getAttributeValue("keystroke"); + if (keystrokeString == null || keystrokeString.trim().length() == 0) { + LOG.error("\"keystroke\" attribute must be specified for action with id=" + actionId); + return; + } + MouseShortcut shortcut; + try { + shortcut = KeymapUtil.parseMouseShortcut(keystrokeString); + } + catch (Exception ex) { + LOG.error("\"keystroke\" attribute has invalid value for action with id=" + actionId); + return; + } + + String keymapName = element.getAttributeValue("keymap"); + if (keymapName == null || keymapName.length() == 0) { + LOG.error("attribute \"keymap\" should be defined"); + return; + } + Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName); + if (keymap == null) { + LOG.error("keymap \"" + keymapName + "\" not found"); + return; + } + + keymap.addShortcut(actionId, shortcut); + } + + private AnAction processReferenceElement(Element element) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processReferenceElement(" + element.getName() + ")"); + } + if (!"reference".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return null; + } + String ref = element.getAttributeValue("ref"); + + if (ref==null) { + // support old style references by id + ref = element.getAttributeValue("id"); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("ref=\"" + ref + "\""); + } + if (ref == null || ref.length() == 0) { + LOG.error("ID of reference element should be defined"); + return null; + } + + AnAction action = getActionImpl(ref, true); + + if (action == null) { + if (!myNotRegisteredInternalActionIds.contains(ref)) { + LOG.error("action specified by reference isn't registered (ID=" + ref + ")"); + } + return null; + } + LOG.assertTrue((action instanceof ActionGroup) || (action instanceof ActionStub)); + return action; + } + + public void processActionsElement(Element element, ClassLoader loader) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processActionsNode(" + element.getName() + ")"); + } + if (!"actions".equals(element.getName())) { + LOG.error("unexpected name of element \"" + element.getName() + "\""); + return; + } + synchronized (myLock) { + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element child = (Element)i.next(); + String name = child.getName(); + if ("action".equals(name)) { + AnAction action = processActionElement(child, loader); + if (action != null) { + LOG.assertTrue((action instanceof ActionGroup) || (action instanceof ActionStub)); + } + } + else if ("group".equals(name)) { + processGroupElement(child, loader); + } + else if ("separator".equals(name)) { + processSeparatorNode(null, child); + } + else { + LOG.error("unexpected name of element \"" + name + "\n"); + } + } + } + } + + public void registerAction(String actionId, AnAction action) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: registerAction(" + action + ")"); + } + if (action == null) { + LOG.error("action cannot be null"); + return; + } + if (actionId == null) { + LOG.error("action's id cannot be null"); + return; + } + synchronized (myLock) { + if (myId2Action.containsKey(actionId)) { + LOG.error("action with the ID \"" + actionId + "\" was already registered. Registered action is " + myId2Action.get(actionId)); + return; + } + if (myAction2Id.containsKey(action)) { + LOG.error("action was already registered for another ID. ID is " + myAction2Id.get(action)); + return; + } + myId2Action.put(actionId, action); + myId2Index.put(actionId, new Integer(myRegisteredActionsCount++)); + myAction2Id.put(action, actionId); + + action.registerCustomShortcutSet(new ProxyShortcutSet(actionId, myKeymapManager), null); + } + } + + public void unregisterAction(String actionId) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: unregisterAction(" + actionId + ")"); + } + if (actionId == null) { + LOG.error("id cannot be null"); + return; + } + synchronized (myLock) { + if (!myId2Action.containsKey(actionId)) { + if (LOG.isDebugEnabled()) { + LOG.debug("action with ID " + actionId + " wasn't registered"); + return; + } + } + AnAction oldValue = (AnAction)myId2Action.remove(actionId); + myAction2Id.remove(oldValue); + myId2Index.remove(actionId); + } + } + + public String getComponentName() { + return "ActionManager"; + } + + public Comparator getRegistrationOrderComparator() { + return new Comparator() { + public int compare(Object o1, Object o2) { + String id1 = (String)o1; + String id2 = (String)o2; + + Integer index1Obj = (Integer)myId2Index.get(id1); + int index1 = index1Obj != null ? index1Obj.intValue() : -1; + + Integer index2Obj = (Integer)myId2Index.get(id2); + int index2 = index2Obj != null ? index2Obj.intValue() : -1; + + return index1 - index2; + } + }; + } + + public String[] getConfigurableGroups() { + return new String[]{IdeActions.GROUP_MAIN_TOOLBAR, IdeActions.GROUP_EDITOR_POPUP}; + } + + private AnActionListener[] getActionListeners() { + if (myCachedActionListeners == null) { + myCachedActionListeners = (AnActionListener[])myActionListeners.toArray(new AnActionListener[myActionListeners.size()]); + } + + return myCachedActionListeners; + } + + public void addAnActionListener(AnActionListener listener) { + myActionListeners.add(listener); + myCachedActionListeners = null; + } + + public void removeAnActionListener(AnActionListener listener) { + myActionListeners.remove(listener); + myCachedActionListeners = null; + } + + public void fireBeforeActionPerformed(AnAction action, DataContext dataContext) { + if (action != null) { + myLastPreformedActionId = getId(action); + IdeaLogger.ourLastActionId = myLastPreformedActionId; + } + AnActionListener[] listeners = getActionListeners(); + for (int i = 0; i < listeners.length; i++) { + listeners[i].beforeActionPerformed(action, dataContext); + } + } + + public void fireBeforeEditorTyping(char c, DataContext dataContext) { + AnActionListener[] listeners = getActionListeners(); + for (int i = 0; i < listeners.length; i++) { + listeners[i].beforeEditorTyping(c, dataContext); + } + } + + public String getLastPreformedActionId() { + return myLastPreformedActionId; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenu.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenu.java new file mode 100644 index 00000000000..c5f5eeb0ca9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenu.java @@ -0,0 +1,192 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.ui.plaf.beg.IdeaMenuUI; + +import javax.swing.*; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public final class ActionMenu extends JMenu{ + private String myPlace; + private DataContext myContext; + private ActionGroup myGroup; + private PresentationFactory myPresentationFactory; + private Presentation myPresentation; + /** + * Defines whether menu shows its mnemonic or not. + */ + private boolean myMnemonicEnabled; + private MenuItemSynchronizer myMenuItemSynchronizer; + /** + * This is PATCH!!! + * Do not remove this STUPID code. Otherwise you will lose all keyboard navigation + * at JMenuBar. + */ + private StubItem myStubItem; + + public ActionMenu(DataContext context,String place,ActionGroup group, PresentationFactory presentationFactory){ + myContext=context; + myPlace=place; + myGroup=group; + myPresentationFactory=presentationFactory; + myPresentation=myPresentationFactory.getPresentation(group); + init(); + } + + public void addNotify(){ + super.addNotify(); + if(myMenuItemSynchronizer==null){ + myMenuItemSynchronizer=new MenuItemSynchronizer(); + myGroup.addPropertyChangeListener(myMenuItemSynchronizer); + myPresentation.addPropertyChangeListener(myMenuItemSynchronizer); + } + } + + public void removeNotify(){ + if(myMenuItemSynchronizer!=null){ + myGroup.removePropertyChangeListener(myMenuItemSynchronizer); + myPresentation.removePropertyChangeListener(myMenuItemSynchronizer); + myMenuItemSynchronizer=null; + } + super.removeNotify(); + } + + public void updateUI(){ + JPopupMenu popupMenu=getPopupMenu(); + if(popupMenu!=null){ + popupMenu.updateUI(); + } + setUI(IdeaMenuUI.createUI(this)); + setFont(UIManager.getFont("Menu.font")); + } + + private void init(){ + myMnemonicEnabled=true; + boolean macSystemMenu = SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU; + + myStubItem= macSystemMenu ? null : new StubItem(); + addStubItem(); + addMenuListener(new MenuListenerImpl()); + setBorderPainted(false); + + setVisible(myPresentation.isVisible()); + setEnabled(myPresentation.isEnabled()); + setMnemonic(myPresentation.getMnemonic()); + setText(myPresentation.getText()); + updateIcon(); + setMnemonic(myPresentation.getMnemonic()); + } + + private void addStubItem() { + if (myStubItem != null) { + add(myStubItem); + } + } + + public void setMnemonicEnabled(boolean enable){ + myMnemonicEnabled=enable; + setMnemonic(myPresentation.getMnemonic()); + } + + public void setMnemonic(int mnemonic){ + if(myMnemonicEnabled){ + super.setMnemonic(mnemonic); + }else{ + super.setMnemonic(0); + } + } + + private void updateIcon(){ + Presentation presentation=myPresentation; + Icon icon=presentation.getIcon(); + setIcon(icon); + if(presentation.getDisabledIcon()!=null){ + setDisabledIcon(presentation.getDisabledIcon()); + }else{ + setDisabledIcon(IconLoader.getDisabledIcon(icon)); + } + } + + public void menuSelectionChanged(boolean isIncluded){ + super.menuSelectionChanged(isIncluded); + IdeFrame frame = (IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class, this); + if (frame != null) { + StatusBar statusBar = frame.getStatusBar(); + if(isIncluded){ + statusBar.setInfo(myPresentation.getDescription()); + }else{ + statusBar.setInfo(null); + } + } + } + + private class MenuListenerImpl implements MenuListener { + public void menuCanceled(MenuEvent e){ + clearItems(); + addStubItem(); + } + + public void menuDeselected(MenuEvent e){ + clearItems(); + addStubItem(); + } + + + public void menuSelected(MenuEvent e){ + fillMenu(); + } + } + + private void clearItems() { + if (SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU) { + Component[] menuComponents = getMenuComponents(); + for (int i = 0; i < menuComponents.length; i++) { + Component menuComponent = menuComponents[i]; + if (menuComponent instanceof ActionMenu) { + ((ActionMenu)menuComponent).clearItems(); + } + else if (menuComponent instanceof ActionMenuItem) { + ((ActionMenuItem)menuComponent).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F24, 0)); + } + } + } + + removeAll(); + validate(); + } + + private void fillMenu() { + DataContext context = myContext != null ? myContext : DataManager.getInstance().getDataContext(); + Utils.fillMenu(myGroup,ActionMenu.this, myPresentationFactory, context,myPlace); + } + + private class MenuItemSynchronizer implements PropertyChangeListener{ + public void propertyChange(PropertyChangeEvent e){ + String name=e.getPropertyName(); + if(Presentation.PROP_VISIBLE.equals(name)){ + ActionMenu.this.setVisible(myPresentation.isVisible()); + }else if(Presentation.PROP_ENABLED.equals(name)){ + ActionMenu.this.setEnabled(myPresentation.isEnabled()); + }else if(Presentation.PROP_MNEMONIC_KEY.equals(name)){ + ActionMenu.this.setMnemonic(myPresentation.getMnemonic()); + }else if(Presentation.PROP_TEXT.equals(name)){ + ActionMenu.this.setText(myPresentation.getText()); + }else if(Presentation.PROP_ICON.equals(name)||Presentation.PROP_DISABLED_ICON.equals(name)){ + updateIcon(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java new file mode 100644 index 00000000000..6f76ad53211 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -0,0 +1,194 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.ui.plaf.beg.BegMenuItemUI; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ActionMenuItem extends JMenuItem{ + private static final Icon ourCheckedIcon = IconLoader.getIcon("/actions/check.png"); + private static final Icon ourUncheckedIcon = EmptyIcon.create(18, 18); + + private final AnAction myAction; + private final Presentation myPresentation; + private final String myPlace; + private final DataContext myContext; + private final AnActionEvent myEvent; + private MenuItemSynchronizer myMenuItemSynchronizer; + + public ActionMenuItem(AnAction action, Presentation presentation, String place, DataContext context){ + myAction=action; + myPresentation=presentation; + myPlace=place; + myContext=context; + myEvent = new AnActionEvent( + null, + context, + place, + myPresentation, + ActionManager.getInstance(), + 0 + ); + addActionListener(new ActionTransmitter()); + setBorderPainted(false); + init(); + } + + /** + * We have to make this method public to allow BegMenuItemUI to invoke it. + */ + public void fireActionPerformed(ActionEvent event){ + super.fireActionPerformed(event); + } + + public void addNotify(){ + super.addNotify(); + if(myMenuItemSynchronizer==null){ + myMenuItemSynchronizer=new MenuItemSynchronizer(); + myPresentation.addPropertyChangeListener(myMenuItemSynchronizer); + } + init(); + } + + public void removeNotify(){ + if(myMenuItemSynchronizer!=null){ + myPresentation.removePropertyChangeListener(myMenuItemSynchronizer); + myMenuItemSynchronizer=null; + } + super.removeNotify(); + } + + private void init(){ + setVisible(myPresentation.isVisible()); + setEnabled(myPresentation.isEnabled()); + setMnemonic(myPresentation.getMnemonic()); + setText(myPresentation.getText()); + updateIcon(); + String id = ActionManager.getInstance().getId(myAction); + if(id!=null){ + Shortcut[] shortcuts=KeymapManager.getInstance().getActiveKeymap().getShortcuts(id); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + if (shortcut instanceof KeyboardShortcut) { + setAccelerator(((KeyboardShortcut)shortcut).getFirstKeyStroke()); + break; + } + } + } + } + + public void updateUI() { + setUI(BegMenuItemUI.createUI(this)); + } + + /** + * Updates long description of action at the status bar. + */ + public void menuSelectionChanged(boolean isIncluded){ + super.menuSelectionChanged(isIncluded); + IdeFrame frame = (IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class, this); + if (frame != null) { + StatusBar statusBar = frame.getStatusBar(); + if(isIncluded){ + statusBar.setInfo(myPresentation.getDescription()); + }else{ + statusBar.setInfo(null); + } + } + } + + public String getFirstShortcutText(){ + return KeymapUtil.getFirstKeyboardShortcutText(myAction); + } + + private final class ActionTransmitter implements ActionListener { + /** + * @return whether the component in Swing tree or not. This method is more + * weak then {@link Component#isShowing() } + */ + private final boolean isInTree(final Component component){ + if(component instanceof Window){ + return component.isShowing(); + } + else{ + Window windowAncestor = SwingUtilities.getWindowAncestor(component); + return windowAncestor != null && windowAncestor.isShowing(); + } + } + + public void actionPerformed(final ActionEvent e){ + AnActionEvent event=new AnActionEvent( + new MouseEvent(ActionMenuItem.this,MouseEvent.MOUSE_PRESSED,0,e.getModifiers(),getWidth()/2,getHeight()/2,1,false), + myContext, + myPlace, + myPresentation, + ActionManager.getInstance(), + e.getModifiers() + ); + myAction.update(event); + if(myPresentation.isEnabled()){ + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + actionManager.fireBeforeActionPerformed(myAction, myContext); + Component component = ((Component)event.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT)); + if (component != null && !isInTree(component)) { + return; + } + myAction.actionPerformed(event); + } + } + } + + private void updateIcon(){ + if(myAction instanceof ToggleAction){ + ToggleAction stateAction=(ToggleAction)myAction; + if(stateAction.isSelected(myEvent)){ + setIcon(ourCheckedIcon); + setDisabledIcon(IconLoader.getDisabledIcon(ourCheckedIcon)); + }else{ + setIcon(ourUncheckedIcon); + setDisabledIcon(IconLoader.getDisabledIcon(ourUncheckedIcon)); + } + }else{ + Icon icon=myPresentation.getIcon(); + setIcon(icon); + if(myPresentation.getDisabledIcon()!=null){ + setDisabledIcon(myPresentation.getDisabledIcon()); + }else{ + setDisabledIcon(IconLoader.getDisabledIcon(icon)); + } + } + } + + private final class MenuItemSynchronizer implements PropertyChangeListener{ + public void propertyChange(PropertyChangeEvent e){ + String name=e.getPropertyName(); + if(Presentation.PROP_VISIBLE.equals(name)){ + ActionMenuItem.this.setVisible(myPresentation.isVisible()); + }else if(Presentation.PROP_ENABLED.equals(name)){ + ActionMenuItem.this.setEnabled(myPresentation.isEnabled()); + updateIcon(); + }else if(Presentation.PROP_MNEMONIC_KEY.equals(name)){ + ActionMenuItem.this.setMnemonic(myPresentation.getMnemonic()); + }else if(Presentation.PROP_TEXT.equals(name)){ + ActionMenuItem.this.setText(myPresentation.getText()); + }else if(Presentation.PROP_ICON.equals(name)||Presentation.PROP_DISABLED_ICON.equals(name)){ + updateIcon(); + }else if("selected".equals(name)){ + updateIcon(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java new file mode 100644 index 00000000000..55e614d2cc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java @@ -0,0 +1,132 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionPopupMenu; +import com.intellij.openapi.actionSystem.DataContext; + +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ActionPopupMenuImpl implements ActionPopupMenu{ + private MyMenu myMenu; + + public ActionPopupMenuImpl(String place,ActionGroup group){ + myMenu=new MyMenu(place,group); + } + + public JPopupMenu getComponent(){ + return myMenu; + } + + private static class MyMenu extends JPopupMenu{ + private String myPlace; + private ActionGroup myGroup; + private DataContext myContext; + private PresentationFactory myPresentationFactory; + + public MyMenu(String place,ActionGroup group){ + myPlace=place; + myGroup=group; + myPresentationFactory=new PresentationFactory(); + addPopupMenuListener(new MyPopupMenuListener()); + } + + public void show(final Component component, int x, int y) { + if(!component.isShowing()){ + throw new IllegalArgumentException("component must be shown on the screen"); + } + + removeAll(); + + // Fill menu. Only after filling menu has non zero size. + + int x2 = Math.min(Math.max(0, x),component.getWidth()-1); // fit x into [0, width-1] + int y2 = Math.min(Math.max(0, y),component.getHeight()-1); // fit y into [0, height-1] + + myContext = DataManager.getInstance().getDataContext(component, x2, y2); + Utils.fillMenu(myGroup, this, myPresentationFactory, myContext, myPlace); + if (getComponentCount() == 0) { + return; + } + Dimension preferredSize=getPreferredSize(); + + // Translate (x,y) into screen coordinate syetem + + int _x,_y; // these are screen coordinates of clicked point + Point p=component.getLocationOnScreen(); + _x=p.x+x; + _y=p.y+y; + + // Determine graphics device which contains our point + + GraphicsConfiguration targetGraphicsConfiguration=null; + GraphicsEnvironment env=GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] devices=env.getScreenDevices(); + for(int i=0;i 0) { + targetGraphicsConfiguration = env.getDefaultScreenDevice().getDefaultConfiguration(); + } + if(targetGraphicsConfiguration==null){ + throw new IllegalStateException( + "It's impossible to determine target graphics environment for point ("+_x+","+_y+")" + ); + } + + // Determine real client area of target graphics configuration + + Insets insets=Toolkit.getDefaultToolkit().getScreenInsets(targetGraphicsConfiguration); + Rectangle targetRectangle=targetGraphicsConfiguration.getBounds(); + targetRectangle.x+=insets.left; + targetRectangle.y+=insets.top; + targetRectangle.width-=insets.left+insets.right; + targetRectangle.height-=insets.top+insets.bottom; + + // Fit popup into targetRectangle. + // The algorithm is the following: + // First of all try to move menu up on its height. If menu left-top corder + // is inside screen bounds after that, then OK. Otherwise, if menu is too high + // (left-top corner is outside of screen bounds) then try to move menu up on + // not visible visible area heigh. + + if(_x+preferredSize.width>targetRectangle.x+targetRectangle.width){ + x-=preferredSize.width; + } + if(_y+preferredSize.height>targetRectangle.y+targetRectangle.height){ + int invisibleHeight=_y+preferredSize.height-targetRectangle.y-targetRectangle.height; + y-=invisibleHeight; + } + + super.show(component, x, y); + } + + private class MyPopupMenuListener implements PopupMenuListener{ + public void popupMenuCanceled(PopupMenuEvent e){ + MyMenu.this.removeAll(); + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e){ + MyMenu.this.removeAll(); + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent e){ + MyMenu.this.removeAll(); + Utils.fillMenu(myGroup, MyMenu.this, myPresentationFactory, myContext, myPlace); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java new file mode 100644 index 00000000000..0d7736191e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -0,0 +1,561 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.TimerListener; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.ex.KeymapManagerListener; +import com.intellij.openapi.keymap.ex.WeakKeymapManagerListener; +import com.intellij.openapi.wm.ex.ActionToolbarEx; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +/** extended by fabrique */ +public class ActionToolbarImpl extends JPanel implements ActionToolbarEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionToolbarImpl"); + + /** + * This array contains Rectangles which define bounds of the corresponding + * components in the toolbar. This list can be considerer as a cache of the + * Rectangle objects that are used in calculation of preferred sizes and + * layouting of components. + */ + private final ArrayList myComponentBounds; + + /** protected for fabrique */ + protected Dimension myMinimumButtonSize; + /** + * @see ActionToolbarEx#getLayoutPolicy() + */ + private int myLayoutPolicy; + private int myOrientation; + private final ActionGroup myActionGroup; + private final String myPlace; + private final boolean myBorderVisible; + private final MyKeymapManagerListener myKeymapManagerListener; + private final MyTimerListener myTimerListener; + private ArrayList myNewVisibleActions; + private ArrayList myVisibleActions; + /** protected for fabrique */ + protected final PresentationFactory myPresentationFactory; + /** + * @see ActionToolbarEx#adjustTheSameSize(boolean) + */ + private boolean myAdjustTheSameSize; + + private ActionButtonLook myButtonLook = null; + private DataManager myDataManager; + private ActionManager myActionManager; + + public ActionToolbarImpl(final String place, + final ActionGroup actionGroup, + final boolean horizontal, + DataManager dataManager, + ActionManagerEx actionManager, KeymapManagerEx keymapManager) { + super(null); + myActionManager = actionManager; + myComponentBounds = new ArrayList(); + setMinimumButtonSize(DEFAULT_MINIMUM_BUTTON_SIZE); + setLayoutPolicy(NOWRAP_LAYOUT_POLICY); + setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + myBorderVisible = false; + myPlace = place; + myActionGroup = actionGroup; + myPresentationFactory = new PresentationFactory(); + myKeymapManagerListener = new MyKeymapManagerListener(); + myTimerListener = new MyTimerListener(); + myVisibleActions = new ArrayList(); + myNewVisibleActions = new ArrayList(); + myDataManager = dataManager; + + setLayout(new BorderLayout()); + setOrientation(horizontal ? SwingConstants.HORIZONTAL : SwingConstants.VERTICAL); + updateActions(); + // + keymapManager.addKeymapManagerListener(new WeakKeymapManagerListener(keymapManager, myKeymapManagerListener)); + actionManager.addTimerListener(500, new WeakTimerListener(actionManager, myTimerListener)); + // If the panel doesn't handle mouse event then it will be passed to its parent. + // It means that if the panel is in slidindg mode then the focus goes to the editor + // and panel will be automatically hidden. + enableEvents(MouseEvent.MOUSE_MOTION_EVENT_MASK | MouseEvent.MOUSE_EVENT_MASK); + } + + public JComponent getComponent() { + return this; + } + + public int getLayoutPolicy() { + return myLayoutPolicy; + } + + public void setLayoutPolicy(final int layoutPolicy) { + if (layoutPolicy != NOWRAP_LAYOUT_POLICY && layoutPolicy != WRAP_LAYOUT_POLICY) { + throw new IllegalArgumentException("wrong layoutPolicy: " + layoutPolicy); + } + myLayoutPolicy = layoutPolicy; + } + + public void setButtonLook(final ActionButtonLook buttonLook) { + myButtonLook = buttonLook; + myVisibleActions.clear(); + updateActions(); + } + + public void paint(final Graphics g) { + super.paint(g); + + // TODO[vova,anton] implement painting when tool bar has vertical orientation + // BTW it's a bit strange :) Toolbar has 4 sides fo border :) + if (myBorderVisible) { + g.setColor(UIManager.getColor("Separator.highlight")); + g.drawLine(0, 0, getWidth() - 1, 0); + g.setColor(UIManager.getColor("Separator.shadow")); + g.drawLine(0, getHeight() - 1, getWidth() - 1, getHeight() - 1); + } + } + + private void fillToolBar(final ArrayList actions) { + for (int i = 0; i < actions.size(); i++) { + final AnAction action = actions.get(i); + if (action instanceof Separator) { + if (i > 0 && i < actions.size() - 1) { + add(new MySeparator()); + } + } + else if (action instanceof CustomComponentAction) { + add(((CustomComponentAction)action).createCustomComponent(myPresentationFactory.getPresentation(action))); + } + else { + add(createToolbarButton(action)); + } + } + } + + private ActionButton createToolbarButton(final AnAction action) { + if (action.displayTextInToolbar()) { + return new ActionButtonWithText(action, myPresentationFactory.getPresentation(action), myPlace, + ActionToolbarEx.DEFAULT_MINIMUM_BUTTON_SIZE); + } + + final ActionButton actionButton = new ActionButton(action, + myPresentationFactory.getPresentation(action), + myPlace, + myMinimumButtonSize); + actionButton.setLook(myButtonLook); + return actionButton; + } + + public void doLayout() { + if (!isValid()) { + calculateBounds(); + } + final int componentCount = getComponentCount(); + LOG.assertTrue(componentCount <= myComponentBounds.size()); + for (int i = componentCount - 1; i >= 0; i--) { + final Component component = getComponent(i); + component.setBounds(myComponentBounds.get(i)); + } + } + + public void validate() { + if (!isValid()) { + calculateBounds(); + super.validate(); + } + } + + /** + * @return maximum button width + */ + private int getMaxButtonWidth() { + int width = 0; + for (int i = 0; i < getComponentCount(); i++) { + final Dimension dimension = getComponent(i).getPreferredSize(); + width = Math.max(width, dimension.width); + } + return width; + } + + /** + * @return maximum button height + */ + public int getMaxButtonHeight() { + int height = 0; + for (int i = 0; i < getComponentCount(); i++) { + final Dimension dimension = getComponent(i).getPreferredSize(); + height = Math.max(height, dimension.height); + } + return height; + } + + private void calculateBoundsNowrapImpl() { + final int componentCount = getComponentCount(); + LOG.assertTrue(componentCount <= myComponentBounds.size()); + + final int width = getWidth(); + final int height = getHeight(); + + if (myAdjustTheSameSize) { + final int maxWidth = getMaxButtonWidth(); + final int maxHeight = getMaxButtonHeight(); + + if (myOrientation == SwingConstants.HORIZONTAL) { + int xOffset = 0; + for (int i = 0; i < componentCount; i++) { + final Rectangle r = myComponentBounds.get(i); + r.setBounds(xOffset, (height - maxHeight) / 2, maxWidth, maxHeight); + xOffset += maxWidth; + } + } + else { + int yOffset = 0; + for (int i = 0; i < componentCount; i++) { + final Rectangle r = myComponentBounds.get(i); + r.setBounds((width - maxWidth) / 2, yOffset, maxWidth, maxHeight); + yOffset += maxHeight; + } + } + } + else { + if (myOrientation == SwingConstants.HORIZONTAL) { + final int maxHeight = getMaxButtonHeight(); + int xOffset = 0; + final int yOffset = 0; + for (int i = 0; i < componentCount; i++) { + final Component component = getComponent(i); + final Dimension d = component.getPreferredSize(); + final Rectangle r = myComponentBounds.get(i); + r.setBounds(xOffset, yOffset + (maxHeight - d.height) / 2, d.width, d.height); + xOffset += d.width; + } + } + else { + final int maxWidth = getMaxButtonWidth(); + final int xOffset = 0; + int yOffset = 0; + for (int i = 0; i < componentCount; i++) { + final Component component = getComponent(i); + final Dimension d = component.getPreferredSize(); + final Rectangle r = myComponentBounds.get(i); + r.setBounds(xOffset + (maxWidth - d.width) / 2, yOffset, d.width, d.height); + yOffset += d.height; + } + } + } + } + + private void calculateBoundsWrapImpl() { + // We have to gracefull handle case when toolbar was not layed out yet. + // In this case we calculate bounds as it is a NOWRAP toolbar. + if (getWidth() == 0 || getHeight() == 0) { + final int oldLayoutPolicy = myLayoutPolicy; + myLayoutPolicy = ActionToolbarEx.NOWRAP_LAYOUT_POLICY; + try { + calculateBoundsNowrapImpl(); + } + finally { + myLayoutPolicy = oldLayoutPolicy; + } + return; + } + + final int componentCount = getComponentCount(); + LOG.assertTrue(componentCount <= myComponentBounds.size()); + + if (myAdjustTheSameSize) { + if (myOrientation == SwingConstants.HORIZONTAL) { + final int maxWidth = getMaxButtonWidth(); + final int maxHeight = getMaxButtonHeight(); + + // Lay components out + int xOffset = 0; + int yOffset = 0; + // Calculate max size of a row. It's not possible to make more then 3 row toolbar + final int maxRowWidth = Math.max(getWidth(), componentCount * maxWidth / 3); + for (int i = 0; i < componentCount; i++) { + if (xOffset + maxWidth > maxRowWidth) { // place component at new row + xOffset = 0; + yOffset += maxHeight; + } + + final Rectangle bounds = myComponentBounds.get(i); + bounds.setBounds(xOffset, maxWidth, yOffset, maxHeight); + + xOffset += maxWidth; + } + } + else { + final int maxWidth = getMaxButtonWidth(); + final int maxHeight = getMaxButtonHeight(); + + // Lay components out + int xOffset = 0; + int yOffset = 0; + // Calculate max size of a row. It's not possible to make more then 3 column toolbar + final int maxRowHeight = Math.max(getHeight(), componentCount * myMinimumButtonSize.height / 3); + for (int i = 0; i < componentCount; i++) { + if (yOffset + maxHeight > maxRowHeight) { // place component at new row + yOffset = 0; + xOffset += maxWidth; + } + + final Rectangle bounds = myComponentBounds.get(i); + bounds.setBounds(xOffset, maxWidth, yOffset, maxHeight); + + yOffset += maxHeight; + } + } + } + else { + if (myOrientation == SwingConstants.HORIZONTAL) { + // Calculate row height + int rowHeight = 0; + final Dimension[] dims = new Dimension[componentCount]; // we will use this dimesions later + for (int i = 0; i < componentCount; i++) { + dims[i] = getComponent(i).getPreferredSize(); + final int height = dims[i].height; + rowHeight = Math.max(rowHeight, height); + } + + // Lay components out + int xOffset = 0; + int yOffset = 0; + // Calculate max size of a row. It's not possible to make more then 3 row toolbar + final int maxRowWidth = Math.max(getWidth(), componentCount * myMinimumButtonSize.width / 3); + for (int i = 0; i < componentCount; i++) { + final Dimension d = dims[i]; + if (xOffset + d.width > maxRowWidth) { // place component at new row + xOffset = 0; + yOffset += rowHeight; + } + + final Rectangle bounds = myComponentBounds.get(i); + bounds.setBounds(xOffset, yOffset + (rowHeight - d.height) / 2, d.width, d.height); + + xOffset += d.width; + } + } + else { + // Calculate row width + int rowWidth = 0; + final Dimension[] dims = new Dimension[componentCount]; // we will use this dimesions later + for (int i = 0; i < componentCount; i++) { + dims[i] = getComponent(i).getPreferredSize(); + final int width = dims[i].width; + rowWidth = Math.max(rowWidth, width); + } + + // Lay components out + int xOffset = 0; + int yOffset = 0; + // Calculate max size of a row. It's not possible to make more then 3 column toolbar + final int maxRowHeight = Math.max(getHeight(), componentCount * myMinimumButtonSize.height / 3); + for (int i = 0; i < componentCount; i++) { + final Dimension d = dims[i]; + if (yOffset + d.height > maxRowHeight) { // place component at new row + yOffset = 0; + xOffset += rowWidth; + } + + final Rectangle bounds = myComponentBounds.get(i); + bounds.setBounds(xOffset + (rowWidth - d.width) / 2, yOffset, d.width, d.height); + + yOffset += d.height; + } + } + } + } + + /** + * Calculates bounds of all the components in the toolbar + */ + private void calculateBounds() { + // Ensure that myComponentBounds has enoungh elements + final int componentCount = getComponentCount(); + if (componentCount > myComponentBounds.size()) { + for (int i = componentCount - myComponentBounds.size() - 1; i >= 0; i--) { + myComponentBounds.add(new Rectangle()); + } + } + + if (myLayoutPolicy == NOWRAP_LAYOUT_POLICY) { + calculateBoundsNowrapImpl(); + } + else if (myLayoutPolicy == WRAP_LAYOUT_POLICY) { + calculateBoundsWrapImpl(); + } + else { + throw new IllegalStateException("unknonw layoutPolicy: " + myLayoutPolicy); + } + } + + public Dimension getPreferredSize() { + calculateBounds(); + final int componentCount = getComponentCount(); + LOG.assertTrue(componentCount <= myComponentBounds.size()); + if (componentCount == 0) { + return new Dimension(0, 0); + } + + int xLeft = Integer.MAX_VALUE; + int yTop = Integer.MAX_VALUE; + int xRight = Integer.MIN_VALUE; + int yBottom = Integer.MIN_VALUE; + for (int i = componentCount - 1; i >= 0; i--) { + final Rectangle bounds = myComponentBounds.get(i); + xLeft = Math.min(xLeft, bounds.x); + yTop = Math.min(yTop, bounds.y); + xRight = Math.max(xRight, bounds.x + bounds.width); + yBottom = Math.max(yBottom, bounds.y + bounds.height); + } + return new Dimension(xRight - xLeft, yBottom - yTop); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + private final class MySeparator extends JComponent { + private final Dimension mySize; + + public MySeparator() { + if (myOrientation == SwingConstants.HORIZONTAL) { + mySize = new Dimension(6, 24); + } + else { + mySize = new Dimension(24, 6); + } + } + + public Dimension getPreferredSize() { + return mySize; + } + + protected void paintComponent(final Graphics g) { + g.setColor(UIManager.getColor("Separator.shadow")); + if (getParent() != null) { + if (myOrientation == SwingConstants.HORIZONTAL) { + g.drawLine(3, 2, 3, getParent().getSize().height - 2); + } + else { + g.drawLine(2, 3, getParent().getSize().width - 2, 3); + } + } + } + } + + private final class MyKeymapManagerListener implements KeymapManagerListener { + public void activeKeymapChanged(final Keymap keymap) { + final int componentCount = getComponentCount(); + for (int i = 0; i < componentCount; i++) { + final Component component = getComponent(i); + if (component instanceof ActionButton) { + ((ActionButton)component).updateToolTipText(); + } + } + } + } + + private final class MyTimerListener implements TimerListener { + public ModalityState getModalityState() { + return ModalityState.stateForComponent(ActionToolbarImpl.this); + } + + public void run() { + if (!ActionToolbarImpl.this.isShowing()) { + return; + } + + // do not update when a popup menu is shown (if popup menu contains action which is also in the toolbar, it should not be enabled/disabled) + final MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); + final MenuElement[] selectedPath = menuSelectionManager.getSelectedPath(); + if (selectedPath.length > 0) { + return; + } + + // don't update toolbar if there is currently active modal dialog + + final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + if (window instanceof Dialog) { + final Dialog dialog = (Dialog)window; + if (dialog.isModal() && !SwingUtilities.isDescendingFrom(ActionToolbarImpl.this, dialog)) { + return; + } + } + + updateActions(); + } + } + + public void adjustTheSameSize(final boolean value) { + if (myAdjustTheSameSize == value) { + return; + } + myAdjustTheSameSize = value; + revalidate(); + } + + public void setMinimumButtonSize(final Dimension size) { + if (size == null) { + throw new IllegalArgumentException("size cannot be null"); + } + myMinimumButtonSize = size; + for (int i = getComponentCount() - 1; i >= 0; i--) { + final Component component = getComponent(i); + if (component instanceof ActionButton) { + final ActionButton button = (ActionButton)component; + button.setMinimumButtonSize(size); + } + } + revalidate(); + } + + public void setOrientation(final int orientation) { + if (SwingConstants.HORIZONTAL != orientation && SwingConstants.VERTICAL != orientation) { + throw new IllegalArgumentException("wrong orientation: " + orientation); + } + myOrientation = orientation; + } + + public void updateActions() { + myNewVisibleActions.clear(); + final DataContext dataContext = ((DataManagerImpl)myDataManager).getDataContextTest(this); + + Utils.expandActionGroup(myActionGroup, myNewVisibleActions, myPresentationFactory, dataContext, myPlace, myActionManager); + + if (!myNewVisibleActions.equals(myVisibleActions)) { + // should rebuild UI + + final boolean changeBarVisibility = myNewVisibleActions.size() == 0 || myVisibleActions.size() == 0; + + final ArrayList temp = myVisibleActions; + myVisibleActions = myNewVisibleActions; + myNewVisibleActions = temp; + + removeAll(); + fillToolBar(myVisibleActions); + + if (changeBarVisibility) { + revalidate(); + } + else { + final Container parent = getParent(); + if (parent != null) { + parent.invalidate(); + parent.validate(); + } + } + repaint(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/EmptyIcon.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/EmptyIcon.java new file mode 100644 index 00000000000..fc7335bc433 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/EmptyIcon.java @@ -0,0 +1,46 @@ + +package com.intellij.openapi.actionSystem.impl; + +import javax.swing.*; +import java.awt.*; + +public class EmptyIcon implements Icon { + private final int myWidth; + private final int myHeight; + + private EmptyIcon(int width, int height) { + myWidth = width; + myHeight = height; + } + + public int getIconWidth() { + return myWidth; + } + + public int getIconHeight() { + return myHeight; + } + + public void paintIcon(Component component, Graphics g, int i, int j) { + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof EmptyIcon)) return false; + + final EmptyIcon icon = (EmptyIcon)o; + + if (myHeight != icon.myHeight) return false; + if (myWidth != icon.myWidth) return false; + + return true; + } + + public int hashCode() { + return myWidth + myHeight; + } + + public static EmptyIcon create(int width, int height) { + return new EmptyIcon(width, height); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/IdeaActionButtonLook.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/IdeaActionButtonLook.java new file mode 100644 index 00000000000..81103d62e30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/IdeaActionButtonLook.java @@ -0,0 +1,59 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.ActionButtonComponent; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; + +import javax.swing.*; +import java.awt.*; + +/** + * @author max + */ +public class IdeaActionButtonLook extends ActionButtonLook { + public void paintBackground(Graphics g, JComponent component, int state) { + Dimension dimension = component.getSize(); + if (state != ActionButtonComponent.NORMAL) { + if (state == ActionButtonComponent.POPPED) { + g.setColor(new Color(181, 190, 214)); + g.fillRect(0, 0, dimension.width, dimension.height); + } + else { + g.setColor(new Color(130, 146, 185)); + g.fillRect(0, 0, dimension.width, dimension.height); + } + } + if (state == ActionButtonComponent.PUSHED) { + g.setColor(new Color(130, 146, 185)); + g.fillRect(0, 0, dimension.width, dimension.height); + } + } + + public void paintBorder(Graphics g, JComponent component, int state) { + if (state == ActionButtonComponent.NORMAL) return; + Rectangle rectangle = new Rectangle(component.getWidth(), component.getHeight()); + Color color = new Color(8, 36, 107); + g.setColor(color); + g.drawLine(rectangle.x, rectangle.y, rectangle.x, (rectangle.y + rectangle.height) - 1); + g.drawLine(rectangle.x, rectangle.y, (rectangle.x + rectangle.width) - 1, rectangle.y); + g.drawLine((rectangle.x + rectangle.width) - 1, rectangle.y, (rectangle.x + rectangle.width) - 1, + (rectangle.y + rectangle.height) - 1); + g.drawLine(rectangle.x, (rectangle.y + rectangle.height) - 1, (rectangle.x + rectangle.width) - 1, + (rectangle.y + rectangle.height) - 1); + } + + public void paintIcon(Graphics g, ActionButtonComponent actionButton, Icon icon) { + int width = icon.getIconWidth(); + int height = icon.getIconHeight(); + int x = (int)Math.ceil((actionButton.getWidth() - width) / 2); + int y = (int)Math.ceil((actionButton.getHeight() - height) / 2); + paintIconAt(g, actionButton, icon, x, y); + } + + public void paintIconAt(Graphics g, ActionButtonComponent button, Icon icon, int x, int y) { + if (button.getPopState() == ActionButtonComponent.PUSHED) { + x++; + y++; + } + icon.paintIcon(null, g, x, y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/PresentationFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/PresentationFactory.java new file mode 100644 index 00000000000..3f207cde337 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/PresentationFactory.java @@ -0,0 +1,27 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.Presentation; + +import java.util.WeakHashMap; + +public class PresentationFactory { + private WeakHashMap myAction2Presentation; + + public PresentationFactory() { + myAction2Presentation = new WeakHashMap(); + } + + public final Presentation getPresentation(AnAction action){ + if (action == null) { + throw new IllegalArgumentException("action cannot be null"); + } + Presentation presentation = (Presentation)myAction2Presentation.get(action); + if (presentation == null){ + presentation = (Presentation)action.getTemplatePresentation().clone(); + myAction2Presentation.put(action, presentation); + } + return presentation; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ProxyShortcutSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ProxyShortcutSet.java new file mode 100644 index 00000000000..300d5832f89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/ProxyShortcutSet.java @@ -0,0 +1,27 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.actionSystem.ShortcutSet; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; + +/** + * Please do not use this class outside impl package!!! + * Please do not use this class even if you managed to make it public!!! + * Thank you in advance. + * The UI Engineers. + */ +final class ProxyShortcutSet implements ShortcutSet { + private final String myActionId; + private KeymapManager myKeymapManager; + + public ProxyShortcutSet(String actionId, KeymapManager keymapManager) { + myActionId = actionId; + myKeymapManager = keymapManager; + } + + public Shortcut[] getShortcuts() { + Keymap keymap=myKeymapManager.getActiveKeymap(); + return keymap.getShortcuts(myActionId); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/StubItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/StubItem.java new file mode 100644 index 00000000000..4eef7b5f4ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/StubItem.java @@ -0,0 +1,14 @@ +package com.intellij.openapi.actionSystem.impl; + +import javax.swing.*; +import java.awt.*; + +public class StubItem extends JMenuItem { + public StubItem(){ + setEnabled(false); + } + + public Dimension getPreferredSize() { + return new Dimension(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/Utils.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/Utils.java new file mode 100644 index 00000000000..b7fa4a86d2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/actionSystem/impl/Utils.java @@ -0,0 +1,158 @@ +package com.intellij.openapi.actionSystem.impl; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class Utils{ + private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.actionSystem.impl.Utils"); + + public static void handleUpdateException(AnAction action,Presentation presentation,Exception exc){ + String id=ActionManagerEx.getInstance().getId(action); + if(id!=null){ + LOG.error("update failed for AnAction with ID="+id,exc); + }else{ + LOG.error("update failed for ActionGroup: "+action+"["+presentation.getText()+"]",exc); + } + } + + /** + * @param actionManager + * @param list this list contains expanded actions. + */ + public static void expandActionGroup(ActionGroup group, + ArrayList list, + PresentationFactory presentationFactory, + DataContext context, + String place, ActionManager actionManager){ + Presentation presentation = presentationFactory.getPresentation(group); + AnActionEvent e = new AnActionEvent( + null, + context, + place, + presentation, + actionManager, + 0 + ); + try{ + group.update(e); + }catch(Exception exc){ + handleUpdateException(group,presentation,exc); + return; + } + + if(!presentation.isVisible()){ // don't process invisible groups + return; + } + AnAction[] children=group.getChildren(e); + for(int i=0;i myListeners = new ArrayList(); + private ApplicationListener[] myCachedListeners; + + private boolean myTestModeFlag = false; + + private String myComponentsDescriptor; + + private boolean myIsInternal = false; + private static boolean ourSaveSettingsInProgress = false; + private static final String APPLICATION_LAYER = "application-components"; + private String myName; + + private ReentrantWriterPreferenceReadWriteLock myActionsLock = new ReentrantWriterPreferenceReadWriteLock(); + private Stack myWriteActionsStack = new Stack(); + private Thread myExceptionalThreadWithReadAccess = null; + private int myInEditorPaintCounter = 0; + private final boolean myAspectJSupportEnabled = "enabled".equals(System.getProperty("idea.aspectj.support")); + private long myStartTime = 0; + private boolean myDoNotSave = false; + private boolean myIsWaitingForWriteAction = false; + private boolean myDispatchThreadAssertionsValid = false; + + public ApplicationImpl(String componentsDescriptor, boolean isInternal, boolean isUnitTestMode, String appName) { + getPicoContainer().registerComponentInstance(ApplicationEx.class, this); + + myStartTime = System.currentTimeMillis(); + myName = appName; + ApplicationManagerEx.setApplication(this); + myComponentsDescriptor = componentsDescriptor; + myIsInternal = isInternal; + myTestModeFlag = isUnitTestMode; + + loadApplicationComponents(); + + if (SystemInfo.isMac) { + registerShutdownHook(); + } + } + + private void registerShutdownHook() { + ShutDownTracker.getInstance(); // Necessary to avoid creating an instance while already shutting down. + + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + public void run() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + saveAll(); + dispose(); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + } + })); + } + + public String getComponentsDescriptor() { + return myComponentsDescriptor; + } + + public String getName() { + return myName; + } + + private void loadApplicationComponents() { + loadComponentsConfiguration(APPLICATION_LAYER); + + if (shouldLoadPlugins()) { + final PluginDescriptor[] plugins = PluginManager.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + PluginDescriptor plugin = plugins[i]; + if (!shouldLoadPlugin(plugin)) continue; + final Element appComponents = plugin.getAppComponents(); + if (appComponents != null) { + loadComponentsConfiguration(appComponents, plugin); + } + } + } + } + + public boolean isInternal() { + return myIsInternal; + } + + public boolean isUnitTestMode() { + return myTestModeFlag; + } + + public boolean isAspectJSupportEnabled() { + return myAspectJSupportEnabled || isUnitTestMode(); + } + + public boolean shouldLoadPlugins() { + final String loadPlugins = System.getProperty("idea.load.plugins"); + return !isUnitTestMode() && (loadPlugins == null || "true".equals(loadPlugins)); + } + + public boolean shouldLoadPlugin(PluginDescriptor descriptor) { + final String loadPluginCategory = System.getProperty("idea.load.plugins.category"); + return loadPluginCategory == null || loadPluginCategory.equals(descriptor.getCategory()); + } + + private static Thread ourDispatchThread = null; + + public boolean isDispatchThread() { + return isDispatchThread(Thread.currentThread()); + } + + /** + * @fabrique + */ + protected boolean isDispatchThread(Thread currentThread) { + if (!myDispatchThreadAssertionsValid) return EventQueue.isDispatchThread(); + + if (ourDispatchThread == null && EventQueue.isDispatchThread()) { + ourDispatchThread = Thread.currentThread(); + } + + if (ourDispatchThread == currentThread) return true; + + if (ourDispatchThread != null && !ourDispatchThread.isAlive()) { + ourDispatchThread = null; + return isDispatchThread(currentThread); + } + + return false; + } + + public void setupIdeQueue(EventQueue queue) { + Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue); + myDispatchThreadAssertionsValid = true; + } + + private void save(String path) throws IOException { + deleteBackupFiles(path); + backupFiles(path); + + Class[] componentClasses = getComponentInterfaces(); + + com.intellij.util.containers.HashMap fileNameToRootElementMap = new com.intellij.util.containers.HashMap(); + + for (int i = 0; i < componentClasses.length; i++) { + Class componentClass = componentClasses[i]; + Object component = getComponent(componentClass); + + String fileName; + if (component instanceof NamedJDOMExternalizable) { + fileName = ((NamedJDOMExternalizable)component).getExternalFileName() + ".xml"; + } + else { + fileName = PathManager.DEFAULT_OPTIONS_FILE_NAME + ".xml"; + } + + Element root = getRootElement(fileNameToRootElementMap, fileName); + try { + Element node = serializeComponent((BaseComponent)component); + if (node != null) { + root.addContent(node); + } + } + catch (Exception e) { + LOG.error(e); + } + } + + for (Iterator iterator = fileNameToRootElementMap.keySet().iterator(); iterator.hasNext();) { + String fileName = iterator.next(); + Element root = fileNameToRootElementMap.get(fileName); + + try { + JDOMUtil.writeDocument(new Document(root), path + File.separatorChar + fileName, CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + catch (IOException e) { + LOG.error(e); + } + } + + deleteBackupFiles(path); + } + + private static void backupFiles(String path) throws IOException { + String[] list = new File(path).list(); + for (int i = 0; i < list.length; i++) { + String name = list[i]; + if (name.toLowerCase().endsWith(".xml")) { + File file = new File(path + File.separatorChar + name); + File newFile = new File(path + File.separatorChar + name + "~"); + if (!file.renameTo(newFile)) { + throw new IOException("Cannot rename file " + file.getPath() + " to " + newFile.getPath()); + } + } + } + } + + private static Element getRootElement(Map fileNameToRootElementMap, String fileName) { + Element root = fileNameToRootElementMap.get(fileName); + if (root == null) { + root = new Element("application"); + fileNameToRootElementMap.put(fileName, root); + } + return root; + } + + private static void deleteBackupFiles(String path) throws IOException { + String[] list = new File(path).list(); + for (int i = 0; i < list.length; i++) { + String name = list[i]; + if (StringUtil.endsWithChar(name.toLowerCase(), '~')) { + File file = new File(path + File.separatorChar + name); + if (!file.delete()) { + throw new IOException("Cannot delete file " + file.getPath()); + } + } + } + } + + public void load(String path) throws IOException, InvalidDataException { + try { + if (path == null) return; + loadConfiguration(path); + } + finally { + initComponents(); + clearDomMap(); + } + } + + private void loadConfiguration(String path) { + clearDomMap(); + + File configurationDir = new File(path); + if (!configurationDir.exists()) return; + + Set names = new HashSet(Arrays.asList(configurationDir.list())); + + for (Iterator i = names.iterator(); i.hasNext();) { + String name = i.next(); + if (name.endsWith(".xml")) { + String backupName = name + "~"; + if (names.contains(backupName)) i.remove(); + } + } + + for (Iterator i = names.iterator(); i.hasNext();) { + String name = i.next(); + if (!name.endsWith(".xml") && !name.endsWith(".xml~")) continue; // see SCR #12791 + final String filePath = path + File.separatorChar + name; + File file = new File(filePath); + if (!file.exists() || !file.isFile()) continue; + + try { + loadFile(filePath); + } + catch (Exception e) { + //OK here. Just drop corrupted settings. + } + } + } + + private void loadFile(String filePath) throws JDOMException, InvalidDataException, IOException { + Document document = JDOMUtil.loadDocument(new File(filePath)); + if (document == null) { + throw new InvalidDataException(); + } + + Element root = document.getRootElement(); + if (root == null || !"application".equals(root.getName())) { + throw new InvalidDataException(); + } + + final List additionalFiles = new ArrayList(); + synchronized (this) { + List children = root.getChildren("component"); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + + String name = element.getAttributeValue("name"); + if (name == null || name.length() == 0) { + String className = element.getAttributeValue("class"); + if (className == null) { + throw new InvalidDataException(); + } + name = className.substring(className.lastIndexOf('.') + 1); + } + + convertComponents(root, filePath, additionalFiles); + + addConfiguration(name, element); + } + } + + for (Iterator iterator = additionalFiles.iterator(); iterator.hasNext();) { + String additionalPath = iterator.next(); + loadFile(additionalPath); + } + } + + private static void convertComponents(Element root, String filePath, final List additionalFiles) {// Converting components + final String additionalFilePath; + additionalFilePath = Convertor34.convertLibraryTable34(root, filePath); + if (additionalFilePath != null) { + additionalFiles.add(additionalFilePath); + } + // Additional converors here probably, adding new files to load + // to aditionalFiles + } + + public void dispose() { + Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects(); + final boolean[] canClose = new boolean[] { true }; + for (int i = 0; i < openProjects.length; i++) { + final Project project = openProjects[i]; + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(project, new Runnable() { + public void run() { + FileDocumentManager.getInstance().saveAllDocuments(); + if (!ProjectManagerEx.getInstanceEx().closeProject(project)) { + canClose[0] = false; + } + } + }, "Exit", null); + if (!canClose[0]) break; + ((ProjectEx)project).dispose(); + } + + if (canClose[0]) { + fireApplicationExiting(); + disposeComponents(); + } + } + + public boolean runProcessWithProgressSynchronously(final Runnable process, + String progressTitle, + boolean canBeCanceled, + Project project) { + return runProcessWithProgressSynchronously(process, progressTitle, canBeCanceled, project, true); + } + + public boolean runProcessWithProgressSynchronously(final Runnable process, + String progressTitle, + boolean canBeCanceled, + Project project, + boolean smoothProgress) { + assertIsDispatchThread(); + + if (myExceptionalThreadWithReadAccess != null) { + process.run(); + return true; + } + + if (Patches.MAC_HIDE_QUIT_HACK) { + smoothProgress = false; + } + + final ProgressWindow progressWindow = new ProgressWindow(canBeCanceled, project); + progressWindow.setTitle(progressTitle); + final BlockingProgressIndicator progress = smoothProgress + ? new SmoothProgressAdapter(progressWindow, project) + : (BlockingProgressIndicator)progressWindow; + + class MyThread extends Thread{ + private final Runnable myProcess; + + public MyThread() { + super("Process with Progress"); + myProcess = process; + } + + public void run() { + if (myExceptionalThreadWithReadAccess != this) { + if (myExceptionalThreadWithReadAccess == null){ + LOG.error("myExceptionalThreadWithReadAccess = null!"); + } + else{ + LOG.error("myExceptionalThreadWithReadAccess != thread, process = " + ((MyThread)myExceptionalThreadWithReadAccess).myProcess); + } + } + + try { + ProgressManager.getInstance().runProcess(myProcess, progress); + } + catch (ProcessCanceledException e) { + } + } + } + final MyThread thread = new MyThread(); + try { + myExceptionalThreadWithReadAccess = thread; + + final boolean[] threadStarted = new boolean[] { false }; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (myExceptionalThreadWithReadAccess != thread) { + if (myExceptionalThreadWithReadAccess == null){ + LOG.error("myExceptionalThreadWithReadAccess = null!"); + } + else{ + LOG.error("myExceptionalThreadWithReadAccess != thread, process = " + ((MyThread)myExceptionalThreadWithReadAccess).myProcess); + } + } + + thread.start(); + threadStarted[0] = true; + } + }); + + progress.startBlocking(); + LOG.assertTrue(threadStarted[0]); + LOG.assertTrue(!smoothProgress || !progress.isRunning()); + } + finally { + myExceptionalThreadWithReadAccess = null; + } + + return !progress.isCanceled(); + } + + public void invokeLater(Runnable runnable) { + LaterInvocatorEx.invokeLater(runnable); + } + + public void invokeLater(Runnable runnable, ModalityState state) { + LaterInvocatorEx.invokeLater(runnable, state); + } + + public void invokeAndWait(Runnable runnable, ModalityState modalityState) { + if (isDispatchThread()) { + LOG.error("invokeAndWait should not be called from event queue thread"); + runnable.run(); + return; + } + + Thread currentThread = Thread.currentThread(); + if (myExceptionalThreadWithReadAccess == currentThread) { //OK if we're in exceptional thread. + LaterInvocatorEx.invokeAndWait(runnable, modalityState); + return; + } + + if (myActionsLock.isReadLockAcquired(currentThread)) { + final Throwable stack = new Throwable(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + LOG.error("Calling invokeAndWait from read-action leads to possible deadlock.", stack); + } + }); + if (myIsWaitingForWriteAction) return; // The deadlock indeed. Do not perform request or we'll stall here immediately. + } + + LaterInvocatorEx.invokeAndWait(runnable, modalityState); + } + + public ModalityState getCurrentModalityState() { + Object[] entities = LaterInvocatorEx.getCurrentModalEntities(); + return entities.length > 0 ? new ModalityStateEx(entities) : getNoneModalityState(); + } + + public ModalityState getModalityStateForComponent(Component c) { + Window window = c instanceof Window ? (Window)c : SwingUtilities.windowForComponent(c); + if (window == null) return getNoneModalityState(); //? + return LaterInvocatorEx.modalityStateForWindow(window); + } + + public ModalityState getDefaultModalityState() { + if (EventQueue.isDispatchThread()) { + return getCurrentModalityState(); + } + else { + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null) { + return progress.getModalityState(); + } + else { + return getNoneModalityState(); + } + } + } + + public ModalityState getNoneModalityState() { + if (MODALITY_STATE_NONE == null) { + MODALITY_STATE_NONE = new ModalityStateEx(ArrayUtil.EMPTY_OBJECT_ARRAY); + } + return MODALITY_STATE_NONE; + } + + public long getStartTime() { + return myStartTime; + } + + public long getIdleTime() { + return IdeEventQueue.getInstance().getIdleTime(); + } + + public void exit() { + if (SystemInfo.isMac) { + if (!canExit()) return; + new Thread(new Runnable() { + public void run() { + System.exit(0); + } + }).start(); + } + else { + Runnable runnable = new Runnable() { + public void run() { + saveAll(); + + if (!canExit()) return; + + dispose(); + + System.exit(0); + } + }; + if (!isDispatchThread()) { + invokeLater(runnable, ModalityState.NON_MMODAL); + } + else { + runnable.run(); + } + } + } + + private boolean canExit() { + ApplicationListener[] listeners = getListeners(); + + for (int i = 0; i < listeners.length; i++) { + ApplicationListener applicationListener = listeners[i]; + if (!applicationListener.canExitApplication()) return false; + } + + ProjectManagerEx projectManager = (ProjectManagerEx)ProjectManager.getInstance(); + Project[] projects = projectManager.getOpenProjects(); + for (int i = 0; i < projects.length; i++) { + Project project = projects[i]; + if (!projectManager.canClose(project)) return false; + } + + return true; + } + + public void runReadAction(final Runnable action) { + boolean isExceptionalThread = myExceptionalThreadWithReadAccess != null && + Thread.currentThread() == myExceptionalThreadWithReadAccess; + + if (!isExceptionalThread) { + while (true) { + try { + myActionsLock.readLock().acquire(); + } + catch (InterruptedException e) { + throw new RuntimeInterruptedException(e); + } + break; + } + } + + try { + action.run(); + } + finally { + if (!isExceptionalThread) { + myActionsLock.readLock().release(); + } + } + } + + public T runReadAction(final Computable computation) { + final Ref ref = Ref.create(null); + runReadAction(new Runnable() { + public void run() { + ref.set(computation.compute()); + } + }); + return ref.get(); + } + + public void runWriteAction(final Runnable action) { + assertCanRunWriteAction(); + + fireBeforeWriteActionStart(action); + + myIsWaitingForWriteAction = true; + try { + while (true) { + try { + myActionsLock.writeLock().acquire(); + } + catch (InterruptedException e) { + throw new RuntimeInterruptedException(e); + } + break; + } + } + finally { + myIsWaitingForWriteAction = false; + } + + fireWriteActionStarted(action); + + try { + synchronized (myWriteActionsStack) { + myWriteActionsStack.push(action); + } + action.run(); + } + finally { + synchronized (myWriteActionsStack) { + myWriteActionsStack.pop(); + } + fireWriteActionFinished(action); + myActionsLock.writeLock().release(); + } + } + + public T runWriteAction(final Computable computation) { + final Ref ref = Ref.create(null); + runWriteAction(new Runnable() { + public void run() { + ref.set(computation.compute()); + } + }); + return ref.get(); + } + + public Object getCurrentWriteAction(Class actionClass) { + synchronized (myWriteActionsStack) { + for (int i = myWriteActionsStack.size() - 1; i >= 0; i--) { + Object action = myWriteActionsStack.get(i); + if (actionClass == null || actionClass.isAssignableFrom(action.getClass())) return action; + } + } + return null; + } + + public void assertReadAccessAllowed() { + if (!isReadAccessAllowed()) { + LOG.error("Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())", + new String[]{"Current thread: "+Thread.currentThread()}); + } + } + + public boolean isReadAccessAllowed() { + Thread currentThread = Thread.currentThread(); + if (ourDispatchThread == currentThread) { + //TODO! + /* + IdeEventQueue eventQueue = IdeEventQueue.getInstance(); //TODO: cache? + if (!eventQueue.isInInputEvent() && !LaterInvocatorEx.isInMyRunnable() && !myInEditorPaint) { + LOG.error("Read access from event dispatch thread is allowed only inside input event processing or LaterInvocatorEx.invokeLater"); + } + */ + } + else { + if (myExceptionalThreadWithReadAccess == currentThread) return true; + if (myActionsLock.isReadLockAcquired(currentThread)) return true; + if (myActionsLock.isWriteLockAcquired(currentThread)) return true; + if (isDispatchThread(currentThread)) return true; + + return false; + } + + return true; + } + + public void assertReadAccessToDocumentsAllowed() { + /* TODO + Thread currentThread = Thread.currentThread(); + if (ourDispatchThread != currentThread) { + if (myExceptionalThreadWithReadAccess == currentThread) return; + if (myActionsLock.isReadLockAcquired(currentThread)) return; + if (myActionsLock.isWriteLockAcquired(currentThread)) return; + if (isDispatchThread(currentThread)) return; + LOG.error( + "Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())"); + } + */ + } + + /** + * Overriden in Visual Fabrique + */ + protected void assertCanRunWriteAction() { + if (!isDispatchThread()) { + LOG.error("Write access is allowed from event dispatch thread only"); + } + /* + else{ + if (!IdeEventQueue.getInstance().isInInputEvent() && !LaterInvocatorEx.isInMyRunnable()) { + LOG.error("Write actions are allowed only inside input event processing or LaterInvocatorEx.invokeLater"); + } + } + */ + } + + public void assertIsDispatchThread() { + if (myDispatchThreadAssertionsValid && !isDispatchThread() && !EventQueue.isDispatchThread()) { // Last one to be completely sure. + LOG.error("Access is allowed from event dispatch thread only. Current thread=" + Thread.currentThread() + ", ourDispatch=" + ourDispatchThread); + } + } + + public void assertWriteAccessAllowed() { + LOG.assertTrue(isWriteAccessAllowed(), + "Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())"); + } + + public boolean isWriteAccessAllowed() { + return myActionsLock.isWriteLockAcquired(Thread.currentThread()); + } + + public void editorPaintStart() { + myInEditorPaintCounter++; + } + + public void editorPaintFinish() { + myInEditorPaintCounter--; + LOG.assertTrue(myInEditorPaintCounter >= 0); + } + + public void addApplicationListener(ApplicationListener l) { + synchronized (myListeners) { + myListeners.add(l); + myCachedListeners = null; + } + } + + public void removeApplicationListener(ApplicationListener l) { + synchronized (myListeners) { + myListeners.remove(l); + myCachedListeners = null; + } + } + + private void fireApplicationExiting() { + ApplicationListener[] listeners = myListeners.toArray(new ApplicationListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + ApplicationListener applicationListener = listeners[i]; + applicationListener.applicationExiting(); + } + } + + private void fireBeforeWriteActionStart(Object action) { + ApplicationListener[] listeners = getListeners(); + + for (int i = 0; i < listeners.length; i++) { + listeners[i].beforeWriteActionStart(action); + } + } + + private void fireWriteActionStarted(Object action) { + ApplicationListener[] listeners = getListeners(); + + for (int i = 0; i < listeners.length; i++) { + listeners[i].writeActionStarted(action); + } + } + + private void fireWriteActionFinished(Object action) { + ApplicationListener[] listeners = getListeners(); + + for (int i = 0; i < listeners.length; i++) { + listeners[i].writeActionFinished(action); + } + } + + private ApplicationListener[] getListeners() { + ApplicationListener[] listeners; + synchronized (myListeners) { + if (myCachedListeners == null) { + myCachedListeners = myListeners.toArray(new ApplicationListener[myListeners.size()]); + } + listeners = myCachedListeners; + } + + return listeners; + } + + protected Element getDefaults(BaseComponent component) throws IOException, JDOMException, InvalidDataException { + InputStream stream = getDefaultsInputStream(component); + + if (stream != null) { + Document document = null; + try { + document = JDOMUtil.loadDocument(stream); + } + finally { + stream.close(); + } + if (document == null) { + throw new InvalidDataException(); + } + Element root = document.getRootElement(); + if (root == null || !"component".equals(root.getName())) { + throw new InvalidDataException(); + } + return root; + } + return null; + } + + protected ComponentManagerImpl getParentComponentManager() { + return null; + } + + private static InputStream getDefaultsInputStream(BaseComponent component) { + return DecodeDefaultsUtil.getDefaultsInputStream(component); + } + + public void saveSettings() { + if (myDoNotSave) return; + + ShutDownTracker.getInstance().registerStopperThread(Thread.currentThread()); + + try { + if (!ourSaveSettingsInProgress) { + ourSaveSettingsInProgress = true; + final String optionsPath = PathManager.getOptionsPath(); + File file = new File(optionsPath); + if (!file.exists()) { + file.mkdirs(); + } + + try { + save(optionsPath); + } + catch (final Throwable ex) { + ex.printStackTrace(); + invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Could not save application settings: " + ex.getLocalizedMessage(), "Error", Messages.getErrorIcon()); + } + }); + } + finally { + ourSaveSettingsInProgress = false; + } + } + + saveSettingsSavingComponents(); + } + finally { + ShutDownTracker.getInstance().unregisterStopperThread(Thread.currentThread()); + } + } + + public void saveAll() { + if (myDoNotSave) return; + + FileDocumentManager.getInstance().saveAllDocuments(); + + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + for (int i = 0; i < openProjects.length; i++) { + ProjectEx project = (ProjectEx)openProjects[i]; + project.save(); + } + + saveSettings(); + } + + public void doNotSave() { + myDoNotSave = true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ApplicationInfoImpl.java new file mode 100644 index 00000000000..b95b3890c3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -0,0 +1,166 @@ + +package com.intellij.openapi.application.impl; + +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Document; +import org.jdom.Element; + +import java.util.Calendar; +import java.util.GregorianCalendar; + +/** + * + */ +public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExternalizable, ApplicationComponent { + private final static String BUILD_STUB = "__BUILD_NUMBER__"; + private String myVersionName = null; + private String myMajorVersion = null; + private String myMinorVersion = null; + private String myBuildNumber = null; + private String myLogoUrl = null; + private String myAboutLogoUrl = null; + private Calendar myBuildDate = null; + private String myPackageCode = null; + private boolean myShowLicensee = true; + + public void initComponent() { } + + public void disposeComponent() { + } + + public Calendar getBuildDate() { + return myBuildDate; + } + + public String getBuildNumber() { + return myBuildNumber; + } + + public String getMajorVersion() { + return myMajorVersion; + } + + public String getMinorVersion() { + return myMinorVersion; + } + + public String getVersionName() { + return myVersionName; + } + + public String getLogoUrl() { + return myLogoUrl; + } + + public String getAboutLogoUrl() { + return myAboutLogoUrl; + } + + public String getPackageCode() { + return myPackageCode; + } + + public String getFullApplicationName() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getVersionName()); + buffer.append(" "); + if (getMajorVersion() != null){ + buffer.append(getMajorVersion()); + } + else { + String bn = getBuildNumber(); + if (!BUILD_STUB.equals(bn)) { + buffer.append('#'); + buffer.append(bn); + } + else { + buffer.append("DevVersion"); + } + } + if (getMinorVersion() != null && getMinorVersion().length() > 0){ + buffer.append("."); + buffer.append(getMinorVersion()); + } + return buffer.toString(); + } + + public boolean showLicenseeInfo() { + return myShowLicensee; + } + + public static ApplicationInfoEx getShadowInstance() { + ApplicationInfoImpl instance = new ApplicationInfoImpl(); + try { + Document doc = JDOMUtil.loadDocument(ApplicationInfoImpl.class.getResourceAsStream("/idea/" + COMPONENT_NAME + ".xml")); + instance.readExternal(doc.getRootElement()); + } + catch (Exception e) { + e.printStackTrace(); + } + return instance; + } + + public void readExternal(Element parentNode) throws InvalidDataException { + Element versionElement = parentNode.getChild("version"); + if (versionElement != null) { + myMajorVersion = versionElement.getAttributeValue("major"); + myMinorVersion = versionElement.getAttributeValue("minor"); + myVersionName = versionElement.getAttributeValue("name"); + } + + Element buildElement = parentNode.getChild("build"); + if (buildElement != null) { + myBuildNumber = buildElement.getAttributeValue("number"); + String dateString = buildElement.getAttributeValue("date"); + int year = 0; + int month = 0; + int day = 0; + try { + year = new Integer(dateString.substring(0, 4)).intValue(); + month = new Integer(dateString.substring(4, 6)).intValue(); + day = new Integer(dateString.substring(6, 8)).intValue(); + } + catch (Exception ex) { + } + if (month > 0) { + month--; + } + myBuildDate = new GregorianCalendar(year, month, day); + } + + Element logoElement = parentNode.getChild("logo"); + if (logoElement != null) { + myLogoUrl = logoElement.getAttributeValue("url"); + } + + Element aboutLogoElement = parentNode.getChild("about"); + if (aboutLogoElement != null) { + myAboutLogoUrl = aboutLogoElement.getAttributeValue("url"); + } + + Element packageElement = parentNode.getChild("package"); + if (packageElement != null) { + myPackageCode = packageElement.getAttributeValue("code"); + } + + Element showLicensee = parentNode.getChild("licensee"); + if (showLicensee != null) { + myShowLicensee = Boolean.valueOf(showLicensee.getAttributeValue("show")).booleanValue(); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + throw new WriteExternalException(); + } + + + public String getComponentName() { + return COMPONENT_NAME; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/LaterInvocatorEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/LaterInvocatorEx.java new file mode 100644 index 00000000000..2914ef749b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/LaterInvocatorEx.java @@ -0,0 +1,234 @@ +package com.intellij.openapi.application.impl; + +import com.intellij.ide.IdeEventQueue; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ModalityStateListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.EventDispatcher; +import com.intellij.util.ArrayUtil; +import com.intellij.util.concurrency.Semaphore; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Stack; + +public class LaterInvocatorEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.LaterInvocatorEx"); + + private static final Object LOCK = new Object(); + private static final IdeEventQueue ourEventQueue = IdeEventQueue.getInstance(); + + private static class RunnableInfo { + final Runnable runnable; + final ModalityState modalityState; + + public RunnableInfo(Runnable runnable, ModalityState modalityState) { + this.runnable = runnable; + this.modalityState = modalityState; + } + } + + private static ArrayList ourModalEntities = new ArrayList(); + private static final ArrayList ourQueue = new ArrayList(); + private static int ourQueueSkipCount = 0; // optimization + private static final Runnable ourFlushQueueRunnable = new FlushQueue(); + + private static Stack ourEventStack = new Stack(); + + static boolean IS_TEST_MODE = false; + + private static EventDispatcher ourModalityStateMulticaster = EventDispatcher.create(ModalityStateListener.class); + + public static void addModalityStateListener(ModalityStateListener listener){ + ourModalityStateMulticaster.addListener(listener); + } + + public static void removeModalityStateListener(ModalityStateListener listener){ + ourModalityStateMulticaster.removeListener(listener); + } + + static ModalityStateEx modalityStateForWindow(Window window){ + int index = ourModalEntities.indexOf(window); + if (index < 0){ + Window owner = window.getOwner(); + if (owner == null) return (ModalityStateEx)ApplicationManager.getApplication().getNoneModalityState(); + ModalityStateEx ownerState = modalityStateForWindow(owner); + if (window instanceof Dialog && ((Dialog)window).isModal()) { + return ownerState.appendEnitity(window); + } + else{ + return ownerState; + } + } + + ArrayList result = new ArrayList(); + for (int i = 0; i < ourModalEntities.size(); i++) { + Object entity = ourModalEntities.get(i); + if (entity instanceof Window){ + result.add((Window)entity); + } + } + return new ModalityStateEx(result.toArray()); + } + + public static void invokeLater(Runnable runnable) { + ModalityState modalityState = ModalityState.defaultModalityState(); + invokeLater(runnable, modalityState); + } + + public static void invokeLater(Runnable runnable, ModalityState modalityState) { + LOG.assertTrue(modalityState != null); + synchronized (LOCK) { + ourQueue.add(new RunnableInfo(runnable, modalityState)); + } + requestFlush(); + } + + public static void invokeAndWait(final Runnable runnable, ModalityState modalityState) { + LOG.assertTrue(modalityState != null); + LOG.assertTrue(!isDispatchThread()); + + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + Runnable runnable1 = new Runnable() { + public void run() { + try { + runnable.run(); + } + finally { + semaphore.up(); + } + } + }; + invokeLater(runnable1, modalityState); + semaphore.waitFor(); + } + + public static void enterModal(Object modalEnity) { + if (!IS_TEST_MODE) { + LOG.assertTrue(isDispatchThread(), "enterModal() should be invoked in event-dispatch thread"); + } + LOG.info("enterModal:" + modalEnity); + + if (!IS_TEST_MODE) { + ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(); + } + + ourModalEntities.add(modalEnity); + } + + public static void leaveModal(Object modalEntity) { + if (!IS_TEST_MODE) { + LOG.assertTrue(isDispatchThread(), "leaveModal() should be invoked in event-dispatch thread"); + } + LOG.info("leaveModal:" + modalEntity); + + if (!IS_TEST_MODE) { + ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(); + } + + boolean removed = ourModalEntities.remove(modalEntity); + LOG.assertTrue(removed); + ourQueueSkipCount = 0; + requestFlush(); + } + + static void leaveAllModals() { + LOG.assertTrue(IS_TEST_MODE); + + /* + if (!IS_TEST_MODE) { + ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(); + } + */ + + ourModalEntities.clear(); + ourQueueSkipCount = 0; + requestFlush(); + } + + public static Object[] getCurrentModalEntities() { + ApplicationManager.getApplication().assertIsDispatchThread(); + //TODO! + //LOG.assertTrue(IdeEventQueue.getInstance().isInInputEvent() || isInMyRunnable()); + + return ourModalEntities.toArray(ArrayUtil.EMPTY_OBJECT_ARRAY); + } + + public static boolean isInModalContext() { + if (!IS_TEST_MODE) { + LOG.assertTrue(isDispatchThread()); + } + + return !ourModalEntities.isEmpty(); + } + + private static boolean isDispatchThread() { + return ApplicationManager.getApplication().isDispatchThread(); + } + + public static boolean isInMyRunnable() { + // speed + //LOG.assertTrue(EventQueue.isDispatchThread()); + + if (ourEventStack.isEmpty()) return false; + AWTEvent top = ourEventStack.peek(); + return ourEventQueue.getTrueCurrentEvent() == top; + } + + private static void requestFlush() { + SwingUtilities.invokeLater(ourFlushQueueRunnable); + } + + private static Runnable pollNext() { + synchronized (LOCK) { + ModalityStateEx currentModality = (ModalityStateEx)(ourModalEntities.size() > 0 + ? new ModalityStateEx(ourModalEntities.toArray(ArrayUtil.EMPTY_OBJECT_ARRAY)) + : ApplicationManager.getApplication().getNoneModalityState()); + + while(ourQueueSkipCount < ourQueue.size()){ + RunnableInfo info = ourQueue.get(ourQueueSkipCount); + if (!currentModality.dominates(info.modalityState)) { + ourQueue.remove(ourQueueSkipCount); + return info.runnable; + } + ourQueueSkipCount++; + } + + return null; + } + } + + private static Object RUN_LOCK = new Object(); + + private static class FlushQueue implements Runnable { + public void run() { + Runnable runnable = pollNext(); + if (runnable != null) { + synchronized (RUN_LOCK) { // necessary only because of switching to our own event queue + AWTEvent event = ourEventQueue.getTrueCurrentEvent(); + ourEventStack.push(event); + int stackSize = ourEventStack.size(); + + try { + runnable.run(); + } + catch (Throwable t) { + if (t instanceof StackOverflowError){ + t.printStackTrace(); + } + LOG.error(t); + } + finally { + LOG.assertTrue(ourEventStack.size() == stackSize); + ourEventStack.pop(); + } + } + + requestFlush(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ModalityStateEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ModalityStateEx.java new file mode 100644 index 00000000000..9af3f43e3c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/application/impl/ModalityStateEx.java @@ -0,0 +1,71 @@ +package com.intellij.openapi.application.impl; + +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.progress.ProgressIndicator; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +public class ModalityStateEx extends ModalityState { + private static final WeakReference[] EMPTY_REFS_ARRAY = new WeakReference[0]; + + private final WeakReference[] myModalEntities; + + ModalityStateEx(Object[] modalEntities) { + if (modalEntities.length > 0) { + myModalEntities = new WeakReference[modalEntities.length]; + for (int i = 0; i < modalEntities.length; i++) { + Object entity = modalEntities[i]; + myModalEntities[i] = new WeakReference(entity); + } + } + else{ + myModalEntities = EMPTY_REFS_ARRAY; + } + } + + public ModalityState appendProgress(ProgressIndicator progress){ + return appendEnitity(progress); + } + + ModalityStateEx appendEnitity(Object anEntity){ + ArrayList list = new ArrayList(); + for (int i = 0; i < myModalEntities.length; i++) { + Object entity = myModalEntities[i].get(); + if (entity == null) continue; + list.add(entity); + } + list.add(anEntity); + return new ModalityStateEx(list.toArray()); + } + + private static boolean contains(WeakReference[] array, Object o){ + for (int i = 0; i < array.length; i++) { + Object o1 = array[i].get(); + if (o1 == null) continue; + if (o1.equals(o)) return true; + } + return false; + } + + public boolean dominates(ModalityState anotherState){ + for (int i = 0; i < myModalEntities.length; i++) { + Object entity = myModalEntities[i].get(); + if (entity == null) continue; + if (!contains(((ModalityStateEx)anotherState).myModalEntities, entity)) return true; // I have entity which is absent in anotherState + } + return false; + } + + public String toString() { + if (myModalEntities.length == 0) return "ModalityState.NON_MODAL"; + StringBuffer buffer = new StringBuffer(); + buffer.append("ModalityState:"); + for (int i = 0; i < myModalEntities.length; i++) { + Object entity = myModalEntities[i].get(); + if (i > 0) buffer.append(", "); + buffer.append(entity); + } + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/CommandProcessorEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/CommandProcessorEx.java new file mode 100644 index 00000000000..ab982fd45c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/CommandProcessorEx.java @@ -0,0 +1,9 @@ +package com.intellij.openapi.command; + +/** + * @author max + */ +public abstract class CommandProcessorEx extends CommandProcessor { + public abstract void enterModal(); + public abstract void leaveModal(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandMerger.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandMerger.java new file mode 100644 index 00000000000..21aebacb1a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandMerger.java @@ -0,0 +1,200 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.diff.FragmentContent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.EditorEventMulticaster; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.util.Comparing; + +import java.util.*; + +/** + * author: lesya + */ + +class CommandMerger { + private final UndoManagerImpl myManager; + private Object myLastGroupId = null; + private boolean myIsComplex = false; + private boolean myOnlyUndoTransparents = true; + private boolean myHasUndoTransparents = false; + private String myCommandName = null; + private ArrayList myCurrentActions = new ArrayList(); + private Set myAffectedDocuments = new HashSet(); + private DocumentAdapter myDocumentListener; + private EditorAndState myStateBefore; + private EditorAndState myStateAfter; + private UndoConfirmationPolicy myUndoConfirmationPolicy = UndoConfirmationPolicy.DEFAULT; + + public CommandMerger(UndoManagerImpl manager, EditorFactory editorFactory) { + myManager = manager; + EditorEventMulticaster eventMulticaster = editorFactory.getEventMulticaster(); + myDocumentListener = new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + Document document = e.getDocument(); + if (myManager.isActive() && !myManager.isUndoInProgress() && !myManager.isRedoInProgress()) { + myManager.getRedoStacksHolder().getStack(document).clear(); + } + } + }; + eventMulticaster.addDocumentListener(myDocumentListener); + } + + public void dispose() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + eventMulticaster.removeDocumentListener(myDocumentListener); + } + + public void add(UndoableAction action, boolean isUndoTransparent) { + if (!isUndoTransparent) myOnlyUndoTransparents = false; + if (isUndoTransparent) myHasUndoTransparents = true; + myCurrentActions.add(action); + myAffectedDocuments.addAll(Arrays.asList(action.getAffectedDocuments())); + myIsComplex |= action.isComplex() || affectsMultipleDocs(); + } + + private boolean affectsMultipleDocs() { + if (myAffectedDocuments.size() < 2) return false; + int count = 0; + for (Iterator iterator = myAffectedDocuments.iterator(); iterator.hasNext();) { + DocumentReference docRef = iterator.next(); + if (docRef.getFile() != null) { + count++; + } + else { + Document doc = docRef.getDocument(); + if (doc != null && doc.getUserData(FragmentContent.FRAGMENT_COPY) == Boolean.TRUE) continue; + count++; + } + } + + return count > 1; + } + + public void commandFinished(String commandName, Object groupId, CommandMerger nextCommandToMerge) { + if (!shouldMerge(groupId, nextCommandToMerge)) { + flushCurrentCommand(); + myManager.compact(); + } + merge(nextCommandToMerge); + + myLastGroupId = groupId; + if (myCommandName == null) myCommandName = commandName; + } + + private boolean shouldMerge(Object groupId, CommandMerger nextCommandToMerge) { + if (myOnlyUndoTransparents && myHasUndoTransparents || + nextCommandToMerge.myOnlyUndoTransparents && nextCommandToMerge.myHasUndoTransparents) { + return true; + } + if (myIsComplex || nextCommandToMerge.isComplex()) return false; + + return (groupId != null && Comparing.equal(myLastGroupId, groupId)); + } + + boolean isComplex() { + return myIsComplex; + } + + private void merge(CommandMerger nextCommandToMerge) { + setBeforeState(nextCommandToMerge.myStateBefore); + myCurrentActions.addAll(nextCommandToMerge.myCurrentActions); + myAffectedDocuments.addAll(nextCommandToMerge.myAffectedDocuments); + myIsComplex |= nextCommandToMerge.myIsComplex; + myOnlyUndoTransparents &= nextCommandToMerge.myOnlyUndoTransparents; + myHasUndoTransparents |= nextCommandToMerge.myHasUndoTransparents; + myStateAfter = nextCommandToMerge.myStateAfter; + mergeUndoConfirmationPolicy(nextCommandToMerge.getUndoConfirmationPolicy()); + } + + public UndoConfirmationPolicy getUndoConfirmationPolicy() { + return myUndoConfirmationPolicy; + } + + public void flushCurrentCommand() { + if (!isEmpty()) { + int commandCounter = myManager.getCommandCounterAndInc(); + UndoableGroup undoableGroup = new UndoableGroup(myCommandName, myIsComplex, myManager.getProject(), + myStateBefore, myStateAfter, commandCounter, myUndoConfirmationPolicy); + undoableGroup.addTailActions(myCurrentActions); + addToAllStacks(undoableGroup); + } + + reset(); + } + + private void addToAllStacks(UndoableGroup commandInfo) { + for (Iterator iterator = myAffectedDocuments.iterator(); iterator.hasNext();) { + DocumentReference document = iterator.next(); + myManager.getUndoStacksHolder().addToLocalStack(document, commandInfo); + } + + if (myIsComplex) { + myManager.getUndoStacksHolder().addToGlobalStack(commandInfo); + } + } + + public void undoOrRedo(FileEditor editor, boolean isUndo) { + flushCurrentCommand(); + UndoOrRedo.execute(myManager, editor, isUndo); + } + + public boolean isEmpty() { + return myCurrentActions.isEmpty(); + } + + public boolean isEmpty(DocumentReference doc) { + for (int i = 0; i < myCurrentActions.size(); i++) { + UndoableAction action = myCurrentActions.get(i); + if (new HashSet(Arrays.asList(action.getAffectedDocuments())).contains(doc)) { + return false; + } + } + + return true; + } + + public void reset() { + myCurrentActions = new ArrayList(); + myAffectedDocuments = new HashSet(); + myLastGroupId = null; + myIsComplex = false; + myOnlyUndoTransparents = true; + myHasUndoTransparents = false; + myCommandName = null; + myStateAfter = null; + myStateBefore = null; + myUndoConfirmationPolicy = UndoConfirmationPolicy.DEFAULT; + } + + public void setBeforeState(EditorAndState state) { + if (myStateBefore == null || isEmpty()) { + myStateBefore = state; + } + } + + public void setAfterState(EditorAndState state) { + myStateAfter = state; + } + + public Collection getAffectedDocuments() { + return myAffectedDocuments; + } + + public void mergeUndoConfirmationPolicy(UndoConfirmationPolicy undoConfirmationPolicy){ + if (myUndoConfirmationPolicy == UndoConfirmationPolicy.DEFAULT){ + myUndoConfirmationPolicy = undoConfirmationPolicy; + } else if (myUndoConfirmationPolicy == UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION){ + if (undoConfirmationPolicy == UndoConfirmationPolicy.REQUEST_CONFIRMATION){ + myUndoConfirmationPolicy = UndoConfirmationPolicy.REQUEST_CONFIRMATION; + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandProcessorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandProcessorImpl.java new file mode 100644 index 00000000000..9fde1da99c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CommandProcessorImpl.java @@ -0,0 +1,260 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandListener; +import com.intellij.openapi.command.CommandProcessorEx; +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.command.undo.DummyComplexUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Stack; + +/** + * + */ +public class CommandProcessorImpl extends CommandProcessorEx implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.impl.CommandProcessorImpl"); + + private static class CommandDescriptor { + public Runnable myCommand; + public Project myProject; + public String myName; + public Object myGroupId; + public UndoConfirmationPolicy myUndoConfirmationPolicy; + + public CommandDescriptor(Runnable command, + Project project, + String name, + Object groupId, + UndoConfirmationPolicy undoConfirmationPolicy) { + myCommand = command; + myProject = project; + myName = name; + myGroupId = groupId; + myUndoConfirmationPolicy = undoConfirmationPolicy; + } + } + + private CommandDescriptor myCurrentCommand = null; + private Stack myInterruptedCommands = new Stack(); + +// private HashMap myStatisticsMap = new HashMap(); // command name --> count + + private ArrayList myListeners = new ArrayList(); + + private int myUndoTransparentCount = 0; + + public CommandProcessorImpl() { + /* + if (Diagnostic.STATISTICS_LOG_TRACE_ENABLED){ + Application.getInstance().addApplicationListener( + new ApplicationAdapter(){ + public void applicationExiting(ApplicationEvent event){ + Util.writeStatisticsLog(myStatisticsMap); + } + } + ); + } + */ + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void executeCommand(Runnable runnable, String name, Object groupId) { + executeCommand(null, runnable, name, groupId); + } + + public void executeCommand(Project project, Runnable runnable, String name, Object groupId) { + executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT); + } + + public void executeCommand(Project project, + final Runnable command, + final String name, + final Object groupId, + UndoConfirmationPolicy undoConfirmationPolicy) { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + + if (LOG.isDebugEnabled()) { + LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId); + } + if (myCurrentCommand != null) { + command.run(); + return; + } + try { + myCurrentCommand = new CommandDescriptor(command, project, name, groupId, undoConfirmationPolicy); + fireCommandStarted(); + command.run(); + } + catch (Exception e) { + LOG.error(e); + } + finally { + _fireCommandFinished(); + } + } + + private void _fireCommandFinished() { + try { + fireBeforeCommandFinished(); + fireCommandFinished(); + } + finally { + myCurrentCommand = null; + } + } + + public void enterModal() { + myInterruptedCommands.push(myCurrentCommand); + if (myCurrentCommand != null) { + _fireCommandFinished(); + } + } + + public void leaveModal() { + LOG.assertTrue(myCurrentCommand == null); + myCurrentCommand = myInterruptedCommands.pop(); + if (myCurrentCommand != null) { + fireCommandStarted(); + } + } + + public void setCurrentCommandName(String name) { + LOG.assertTrue(myCurrentCommand != null); + myCurrentCommand.myName = name; + } + + public void setCurrentCommandGroupId(Object groupId) { + LOG.assertTrue(myCurrentCommand != null); + myCurrentCommand.myGroupId = groupId; + } + + public Runnable getCurrentCommand() { + return myCurrentCommand != null ? myCurrentCommand.myCommand : null; + } + + public String getCurrentCommandName() { + if (myCurrentCommand != null) return myCurrentCommand.myName; + if (myInterruptedCommands.size() > 0) { + final CommandDescriptor command = myInterruptedCommands.peek(); + return command != null ? command.myName : null; + } + return null; + } + + public Project getCurrentCommandProject() { + return myCurrentCommand != null ? myCurrentCommand.myProject : null; + } + + public void addCommandListener(CommandListener listener) { + myListeners.add(listener); + } + + public void removeCommandListener(CommandListener listener) { + myListeners.remove(listener); + } + + public void runUndoTransparentAction(Runnable action) { + if (myUndoTransparentCount == 0) fireUndoTransparentStarted(); + myUndoTransparentCount++; + try { + action.run(); + } + finally { + myUndoTransparentCount--; + if (myUndoTransparentCount == 0) fireUndoTransparentFinished(); + } + } + + public boolean isUndoTransparentActionInProgress() { + return myUndoTransparentCount > 0; + } + + public void markCurrentCommandAsComplex(Project project) { + UndoManager manager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance(); + manager.undoableActionPerformed(new DummyComplexUndoableAction()); + } + + private void fireCommandStarted() { + CommandEvent event = new CommandEvent(this, myCurrentCommand.myCommand, myCurrentCommand.myProject, myCurrentCommand.myUndoConfirmationPolicy); + CommandListener[] listeners = myListeners.toArray(new CommandListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + CommandListener listener = listeners[i]; + try { + listener.commandStarted(event); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + private void fireBeforeCommandFinished() { + CommandEvent event = new CommandEvent(this, myCurrentCommand.myCommand, myCurrentCommand.myName, + myCurrentCommand.myGroupId, myCurrentCommand.myProject, myCurrentCommand.myUndoConfirmationPolicy); + CommandListener[] listeners = myListeners.toArray(new CommandListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + CommandListener listener = listeners[i]; + try { + listener.beforeCommandFinished(event); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + private void fireCommandFinished() { + CommandEvent event = new CommandEvent(this, myCurrentCommand.myCommand, myCurrentCommand.myName, + myCurrentCommand.myGroupId, myCurrentCommand.myProject, myCurrentCommand.myUndoConfirmationPolicy); + CommandListener[] listeners = myListeners.toArray(new CommandListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + CommandListener listener = listeners[i]; + try { + listener.commandFinished(event); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + private void fireUndoTransparentStarted() { + CommandListener[] listeners = myListeners.toArray(new CommandListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + CommandListener listener = listeners[i]; + try { + listener.undoTransparentActionStarted(); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + private void fireUndoTransparentFinished() { + CommandListener[] listeners = myListeners.toArray(new CommandListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + CommandListener listener = listeners[i]; + try { + listener.undoTransparentActionFinished(); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + public String getComponentName() { + return "CommandProcessor"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CurrentEditorProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CurrentEditorProvider.java new file mode 100644 index 00000000000..ad4c3dcfc21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/CurrentEditorProvider.java @@ -0,0 +1,10 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.fileEditor.FileEditor; + +/** + * @author max + */ +public interface CurrentEditorProvider { + FileEditor getCurrentEditor(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentEditingUndoProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentEditingUndoProvider.java new file mode 100644 index 00000000000..feaa22c4a9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentEditingUndoProvider.java @@ -0,0 +1,137 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.NonUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.EditorEventMulticaster; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiExternalChangeAction; + +/** + * author: lesya + */ +class DocumentEditingUndoProvider { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.openapi.command.impl.DocumentEditingUndoProvider"); + + private MyEditorDocumentListener myDocumentListener; + private Project myProject; + + public DocumentEditingUndoProvider(Project project, EditorFactory editorFactory) { + myDocumentListener = new MyEditorDocumentListener(); + myProject = project; + + EditorEventMulticaster eventMulticaster = editorFactory.getEventMulticaster(); + eventMulticaster.addDocumentListener(myDocumentListener); + } + + public void dispose() { + EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); + eventMulticaster.removeDocumentListener(myDocumentListener); + } + + private class MyEditorDocumentListener extends DocumentAdapter { + public void documentChanged(final DocumentEvent e) { + final Document document = e.getDocument(); + if (allEditorsAreViewersFor(document)) return; + UndoManagerImpl undoManager = getUndoManager(); + if (externalChanges()) { + createNonUndoableAction(document); + } + else { + LOG.assertTrue( + undoManager.isInsideCommand(), + "Undoable actions allowed inside commands only (see com.intellij.openapi.command.CommandProcessor.executeCommand())" + ); + if (undoManager.isActive()) { + createUndoableEditorChangeAction(e); + } + else { + createNonUndoableAction(document); + } + } + } + + private boolean allEditorsAreViewersFor(Document document) { + Editor[] editors = EditorFactory.getInstance().getEditors(document); + if (editors.length == 0) return false; + for (int i = 0; i < editors.length; i++) { + Editor editor = editors[i]; + if (!editor.isViewer()) return false; + } + return true; + } + + private void createUndoableEditorChangeAction(final DocumentEvent e) { + if (LOG.isDebugEnabled()) { + LOG.debug("document changed:"); + LOG.debug(" offset:" + e.getOffset()); + LOG.debug(" old fragment:" + e.getOldFragment()); + LOG.debug(" new fragment:" + e.getNewFragment()); + } + + EditorChangeAction action = new EditorChangeAction((DocumentEx)e.getDocument(), e.getOffset(), + e.getOldFragment(), e.getNewFragment(), e.getOldTimeStamp(), myProject); + + getUndoManager().undoableActionPerformed(action); + } + + private void createNonUndoableAction(final Document document) { + UndoManagerImpl undoManager = getUndoManager(); + if (undoManager.undoableActionsForDocumentAreEmpty(DocumentReferenceByDocument.createDocumentReference(document))) { + return; + } + undoManager.undoableActionPerformed( + new NonUndoableAction() { + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[]{DocumentReferenceByDocument.createDocumentReference(document)}; + } + + public boolean isComplex() { + return false; + } + } + ); + } + + private boolean externalChanges() { + return ApplicationManager.getApplication().getCurrentWriteAction(PsiExternalChangeAction.class) != null; + } + } + + private UndoManagerImpl getUndoManager() { + return (UndoManagerImpl)(myProject == null ? UndoManager.getGlobalInstance() : UndoManager.getInstance(myProject)); + } + + static class EditorPosition { + int line; + int col; + final float scrollProportion; + + public EditorPosition(int line, int col, float scrollProportion) { + this.line = line; + this.col = col; + this.scrollProportion = scrollProportion; + } + + public boolean equals(Object obj) { + if (obj instanceof EditorPosition) { + EditorPosition position = (EditorPosition)obj; + return position.line == line && position.col == col; + } + return false; + } + + public int hashCode() { + return line + col; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByDocument.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByDocument.java new file mode 100644 index 00000000000..db425e7cb59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByDocument.java @@ -0,0 +1,40 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author max + */ +public class DocumentReferenceByDocument extends DocumentReference { + private Document myDocument; + + private DocumentReferenceByDocument(Document document) { + myDocument = document; + } + + public VirtualFile getFile() { + return FileDocumentManager.getInstance().getFile(myDocument); + } + + public Document getDocument() { + return myDocument; + } + + protected String getUrl() { + VirtualFile file = getFile(); + if (file == null) return null; + return file.getUrl(); + } + + public void beforeFileDeletion(VirtualFile file) { + } + + public static DocumentReference createDocumentReference(Document document) { + final VirtualFile file = FileDocumentManager.getInstance().getFile(document); + if (file != null) return new DocumentReferenceByVirtualFile(file); + return new DocumentReferenceByDocument(document); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByVirtualFile.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByVirtualFile.java new file mode 100644 index 00000000000..c910688fe91 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DocumentReferenceByVirtualFile.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author max + */ +public class DocumentReferenceByVirtualFile extends DocumentReference { + private VirtualFile myFile; + private String myUrl = null; + + public DocumentReferenceByVirtualFile(VirtualFile file) { + myFile = file; + } + + public void beforeFileDeletion(VirtualFile file) { + if (myFile != file) return; + if (!myFile.isValid()) return; + myUrl = file.getUrl(); + } + + protected String getUrl() { + if (myFile.isValid()) + return myFile.getUrl(); + else + return myUrl; + } + + public VirtualFile getFile() { + return myFile; + } + + public Document getDocument() { + return FileDocumentManager.getInstance().getDocument(myFile); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DummyProject.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DummyProject.java new file mode 100644 index 00000000000..700cc248abf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/DummyProject.java @@ -0,0 +1,93 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.components.BaseComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.PomModel; +import com.intellij.util.ArrayUtil; +import org.picocontainer.PicoContainer; + +/** + * @author max + */ +public class DummyProject extends UserDataHolderBase implements Project { + private static DummyProject ourInstance; + + public static Project getInstance() { + if (ourInstance == null) { + ourInstance = new DummyProject(); + } + return ourInstance; + } + + private DummyProject() { + } + + public VirtualFile getProjectFile() { + return null; + } + + public String getName() { + return null; + } + + public String getProjectFilePath() { + return null; + } + + public VirtualFile getWorkspaceFile() { + return null; + } + + public void save() { + } + + public BaseComponent getComponent(String name) { + return null; + } + + public T getComponent(Class interfaceClass) { + return null; + } + + public Class[] getComponentInterfaces() { + return new Class[0]; + } + + public boolean hasComponent(Class interfaceClass) { + return false; + } + + public T[] getComponents(Class baseInterfaceClass) { + return ArrayUtil.emptyArray(); + } + + public PicoContainer getPicoContainer() { + throw new UnsupportedOperationException("getPicoContainer is not implement in : " + getClass()); + } + + public T getComponent(Class interfaceClass, T defaultImplementation) { + return null; + } + + public boolean isDisposed() { + return false; + } + + public boolean isOpen() { + return false; + } + + public boolean isInitialized() { + return false; + } + + public boolean isDefault() { + return false; + } + + public PomModel getModel() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorAndState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorAndState.java new file mode 100644 index 00000000000..5010f1a154a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorAndState.java @@ -0,0 +1,27 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditor; + +import java.lang.ref.WeakReference; + +class EditorAndState { + private final FileEditorState myState; + private final WeakReference myEditor; + + public EditorAndState(FileEditor editor, FileEditorState state) { + myEditor = new WeakReference(editor); + myState = state; + } + + /** + * @return may be null + */ + public FileEditor getEditor() { + return myEditor.get(); + } + + public FileEditorState getState() { + return myState; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorChangeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorChangeAction.java new file mode 100644 index 00000000000..2866cdc3190 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/EditorChangeAction.java @@ -0,0 +1,72 @@ + +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; + +class EditorChangeAction implements UndoableAction { + private DocumentEx myDocument; + private int myOffset; + private CharSequence myOldString; + private CharSequence myNewString; + private long myTimeStamp; + private final Project myProject; + + public EditorChangeAction(DocumentEx document, int offset, + CharSequence oldString, CharSequence newString, + long oldTimeStamp, Project project) { + myDocument = document; + myOffset = offset; + myOldString = oldString; + if (myOldString == null) + myOldString = ""; + myNewString = newString; + if (myNewString == null) + myNewString = ""; + myTimeStamp = oldTimeStamp; + myProject = project; + } + + public void undo() { + exchangeStrings(myNewString, myOldString); + myDocument.setModificationStamp(myTimeStamp); + fileFileStatusChanged(); + } + + private void fileFileStatusChanged() { + if (myProject == null) return; + VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument); + if (file == null) return; + FileStatusManager.getInstance(myProject).fileStatusChanged(file); + } + + private void exchangeStrings(CharSequence newString, CharSequence oldString) { + if (newString.length() > 0 && oldString.length() == 0){ + myDocument.deleteString(myOffset, myOffset + newString.length()); + } + else if (oldString.length() > 0 && newString.length() == 0){ + myDocument.insertString(myOffset, oldString); + } + else if (oldString.length() > 0 && newString.length() > 0){ + myDocument.replaceString(myOffset, myOffset + newString.length(), oldString); + } + } + + public void redo() { + exchangeStrings(myOldString, myNewString); + } + + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[]{DocumentReferenceByDocument.createDocumentReference(myDocument)}; + } + + public boolean isComplex() { + return false; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FileOperationsUndoProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FileOperationsUndoProvider.java new file mode 100644 index 00000000000..b10f365be25 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FileOperationsUndoProvider.java @@ -0,0 +1,419 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.localVcs.changes.LocalVcsChanges; +import com.intellij.localVcs.changes.LvcsChange; +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.undo.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.*; + +import java.io.IOException; +import java.util.*; + +/** + * author: lesya + */ + +class FileOperationsUndoProvider implements VirtualFileListener, LocalVcsItemsLocker { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.impl.FileOperationsUndoProvider"); + private final UndoManagerImpl myUndoManager; + private final Project myProject; + private boolean myCommandStarted; + private Collection myLockedRevisions = new HashSet(); + private final Key DELETE_UNDOABLE_ACTION_KEY = new Key("DeleteUndoableAction"); + + private static class CompositeUndoableAction implements UndoableAction, Disposeable { + private final List myActions = new ArrayList(); + + public CompositeUndoableAction addAction(MyUndoableAction action) { + myActions.add(action); + return this; + } + + public void undo() throws UnexpectedUndoException { + for (Iterator each = myActions.iterator(); each.hasNext();) { + UndoableAction undoableAction = (UndoableAction)each.next(); + undoableAction.undo(); + } + } + + public void redo() throws UnexpectedUndoException { + for (int i = myActions.size() - 1; i >= 0; i--) { + UndoableAction undoableAction = myActions.get(i); + undoableAction.redo(); + } + } + + public DocumentReference[] getAffectedDocuments() { + ArrayList result = new ArrayList(); + for (Iterator each = myActions.iterator(); each.hasNext();) { + UndoableAction undoableAction = (UndoableAction)each.next(); + result.addAll(Arrays.asList(undoableAction.getAffectedDocuments())); + } + return result.toArray(new DocumentReference[result.size()]); + } + + public boolean isComplex() { + return true; + } + + public void dispose() { + for (Iterator each = myActions.iterator(); each.hasNext();) { + Disposeable undoableAction = (Disposeable)each.next(); + undoableAction.dispose(); + } + + } + + public boolean isEmpty() { + return myActions.isEmpty(); + } + + public void actionCompleted() { + for (Iterator each = myActions.iterator(); each.hasNext();) { + MyUndoableAction action = (MyUndoableAction)each.next(); + action.actionCompleted(); + } + } + } + + public FileOperationsUndoProvider(UndoManager undoManager, Project project) { + myUndoManager = (UndoManagerImpl)undoManager; + myProject = project; + if (myProject != null) { + virtualFileManager().addVirtualFileListener(this); + + if (LocalVcs.getInstance(myProject) != null) { + LocalVcs.getInstance(myProject).getLocalVcsPurgingProvider().registerLocker(this); + } + } + } + + public void dispose() { + if (myProject != null) { + virtualFileManager().removeVirtualFileListener(this); + + if (LocalVcs.getInstance(myProject) != null) { + LocalVcs.getInstance(myProject).getLocalVcsPurgingProvider().unregisterLocker(this); + } + } + } + + + private VirtualFileManager virtualFileManager() { + return VirtualFileManager.getInstance(); + } + + public void propertyChanged(VirtualFilePropertyEvent event) { + undoableActionPerformed(event); + } + + public void contentsChanged(VirtualFileEvent event) { + } + + public void fileCreated(VirtualFileEvent event) { + if (event.getRequestor() == null) { + createNonUndoableAction(event.getFile(), true); + } + else { + undoableActionPerformed(event); + } + } + + public void fileDeleted(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + try { + CompositeUndoableAction deleteUndoableAction = file.getUserData(DELETE_UNDOABLE_ACTION_KEY); + if (deleteUndoableAction == null) return; + deleteUndoableAction.actionCompleted(); + myUndoManager.undoableActionPerformed(deleteUndoableAction); + } + finally { + file.putUserData(DELETE_UNDOABLE_ACTION_KEY, null); + } + } + + public void fileMoved(VirtualFileMoveEvent event) { + undoableActionPerformed(event); + } + + public void beforePropertyChange(VirtualFilePropertyEvent event) { + } + + public void beforeContentsChange(VirtualFileEvent event) { + if (event.getRequestor() == null) { + createNonUndoableAction(event.getFile(), false); + } + } + + public void beforeFileDeletion(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + if (event.getRequestor() == null) { + createNonUndoableAction(file, true); + } + else { + CompositeUndoableAction undoableAction = createUndoableAction(file); + if (!undoableAction.isEmpty()) { + file.putUserData(DELETE_UNDOABLE_ACTION_KEY, undoableAction); + } + + } + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + } + + private void createNonUndoableAction(final VirtualFile vFile, final boolean isComplex) { + if (getLocalVcs() == null || !getLocalVcs().isUnderVcs(vFile)) { + return; + } + + DocumentReference oldRef = myUndoManager.findInvalidatedReferenceByUrl(vFile.getUrl()); + final DocumentReference newRef = new DocumentReferenceByVirtualFile(vFile); + + createNonUndoableAction(vFile, newRef, isComplex); + + if ((oldRef != null) && !oldRef.equals(newRef)) { + createNonUndoableAction(vFile, oldRef, isComplex); + } + + } + + private void createNonUndoableAction(final VirtualFile vFile, + final DocumentReference newRef, + final boolean isComplex) { + if (getLocalVcs() == null || !getLocalVcs().isUnderVcs(vFile) || + myUndoManager.undoableActionsForDocumentAreEmpty(newRef)) { + return; + } + + myUndoManager.undoableActionPerformed(new NonUndoableAction() { + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[]{newRef}; + } + + public boolean isComplex() { + return isComplex; + } + }); + } + + + private void undoableActionPerformed(final VirtualFile vFile) { + CompositeUndoableAction compositeUndoableAction = createUndoableAction(vFile); + if (!compositeUndoableAction.isEmpty()) { + myUndoManager.undoableActionPerformed(compositeUndoableAction); + } + } + + private CompositeUndoableAction createUndoableAction(final VirtualFile vFile) { + CompositeUndoableAction compositeUndoableAction = new CompositeUndoableAction(); + + if (myCommandStarted && (getLocalVcs() != null) && getLocalVcs().isAvailable()) { + addActionForFileTo(compositeUndoableAction, vFile); + } + return compositeUndoableAction; + } + + private void addActionForFileTo(CompositeUndoableAction compositeUndoableAction, final VirtualFile vFile) { + if (!getLocalVcs().isUnderVcs(vFile)) return; + final String filePath = vFile.getPath(); + final boolean isDirectory = vFile.isDirectory(); + final LvcsRevision afterActionPerformedRevision = getCurrentRevision(filePath, isDirectory); + if (afterActionPerformedRevision == null) return; + synchronized (myLockedRevisions) { + myLockedRevisions.add(afterActionPerformedRevision.getItem()); + } + MyUndoableAction action = new MyUndoableAction(vFile, filePath, isDirectory, afterActionPerformedRevision); + compositeUndoableAction.addAction(action); + + VirtualFile[] children = vFile.getChildren(); + if (children == null) return; + for (int i = 0; i < children.length; i++) { + addActionForFileTo(compositeUndoableAction, children[i]); + } + + } + + private LvcsRevision getCurrentRevision(String filePath, boolean isDir) { + LocalVcs vcs = getLocalVcs(); + LvcsObject lvcsFile = isDir ? (LvcsObject)vcs.findDirectory(filePath, true) : vcs.findFile(filePath, true); + if (lvcsFile == null) return null; + LvcsRevision revision = lvcsFile.getRevision(); + return revision; + } + + private LocalVcs getLocalVcs() { + return LocalVcs.getInstance(myProject); + } + + private void undoableActionPerformed(VirtualFileEvent event) { + undoableActionPerformed(event.getFile()); + } + + private List getChanges(LvcsRevision requestedRevision, boolean isDir) { + List changes = getChanges(requestedRevision, + getCurrentRevision(getUpToDatePathFor(requestedRevision), isDir)); + return filterOnlyGlobalChanges(changes); + } + + private List filterOnlyGlobalChanges(List changes) { + ArrayList result = new ArrayList(); + for (Iterator iterator = changes.iterator(); iterator.hasNext();) { + LvcsChange lvcsChange = (LvcsChange)iterator.next(); + if (lvcsChange.getChangeType() != LvcsChange.CONTENT_CHANGED) result.add(lvcsChange); + } + return result; + } + + private String getUpToDatePathFor(LvcsRevision requestedRevision) { + LvcsRevision current = requestedRevision; + while (current.getNextRevision() != null) current = current.getNextRevision(); + return current.getAbsolutePath(); + } + + private List getChanges(LvcsRevision requestedRevision, LvcsRevision lastRevision) { + if (lastRevision == null || requestedRevision == null) { + return new ArrayList(); + } + return + createChangesFromRevisions(collectRevisionsFromTo(requestedRevision, lastRevision)); + } + + private List createChangesFromRevisions(ArrayList revisions) { + return LocalVcsChanges.getChanges(revisions); + } + + private ArrayList collectRevisionsFromTo(LvcsRevision requestedRevision, LvcsRevision lastRevision) { + ArrayList revisions = new ArrayList(); + + revisions.add(requestedRevision); + + LvcsRevision currentRevision = requestedRevision; + + while (!currentRevision.equals(lastRevision)) { + currentRevision = currentRevision.getNextRevision(); + LOG.assertTrue(!currentRevision.getItem().isPurged()); + revisions.add(currentRevision); + } + return revisions; + } + + public void commandStarted(Project project) { + if (myProject == project) { + myCommandStarted = true; + } + } + + public void commandFinished(Project project) { + if (myProject == project) { + myCommandStarted = false; + } + } + + private class MyUndoableAction implements UndoableAction, Disposeable { + private LvcsRevision myBeforeUndoRevision; + private LvcsRevision myAfterActionPerformedRevision; + + private VirtualFile myFile; + private final String myFilePath; + private final boolean myDirectory; + + public MyUndoableAction(VirtualFile file, + String filePath, + boolean directory, + LvcsRevision afterActionPerformedRevision) { + myFile = file; + myFilePath = filePath; + myDirectory = directory; + myAfterActionPerformedRevision = afterActionPerformedRevision; + } + + public void dispose() { + synchronized (myLockedRevisions) { + if (myBeforeUndoRevision != null) myLockedRevisions.remove(myBeforeUndoRevision.getItem()); + if (myAfterActionPerformedRevision != null) myLockedRevisions.remove(myAfterActionPerformedRevision.getItem()); + } + } + + public void undo() throws UnexpectedUndoException { + myBeforeUndoRevision = getCurrentRevision(myFilePath, myDirectory); + if (myBeforeUndoRevision == null) return; + try { + rollbackTo(myAfterActionPerformedRevision); + myBeforeUndoRevision = myBeforeUndoRevision.getNextRevision(); + if (myBeforeUndoRevision != null) { + synchronized (myLockedRevisions) { + myLockedRevisions.add(myBeforeUndoRevision.getItem()); + } + } + } + catch (final IOException e) { + myBeforeUndoRevision = null; + Application application = ApplicationManager.getApplication(); + if (!application.isUnitTestMode()) { + Runnable showDialogAction = new Runnable() { + public void run() { + Messages.showErrorDialog("Cannot undo: " + e.getLocalizedMessage(), "Cannot Undo"); + } + }; + + if (application.isDispatchThread()) { + showDialogAction.run(); + } + else { + application.invokeLater(showDialogAction); + } + } + else { + throw new RuntimeException(e); + } + return; + } + + } + + public void redo() throws UnexpectedUndoException { + try { + rollbackTo(myBeforeUndoRevision); + } + catch (IOException e) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { + Messages.showErrorDialog("Cannot redo: " + e.getLocalizedMessage(), "Cannot Redo"); + } + else { + throw new RuntimeException(e); + } + } + } + + private void rollbackTo(final LvcsRevision currentRevision) throws IOException { + if (currentRevision == null) return; + LocalVcsChanges.rollback(getChanges(currentRevision, myDirectory)); + } + + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[]{new DocumentReferenceByVirtualFile(myFile)}; + } + + public boolean isComplex() { + return true; + } + + public void actionCompleted() { + myAfterActionPerformedRevision = myAfterActionPerformedRevision.findLatestRevision(); + } + } + + public boolean itemCanBePurged(LvcsRevision revision) { + synchronized (myLockedRevisions) { + return !myLockedRevisions.contains(revision.getItem()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FocusBasedCurrentEditorProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FocusBasedCurrentEditorProvider.java new file mode 100644 index 00000000000..2ed7e03a205 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/FocusBasedCurrentEditorProvider.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.fileEditor.FileEditor; + +/** + * @author max + */ +class FocusBasedCurrentEditorProvider implements CurrentEditorProvider { + public FileEditor getCurrentEditor() { + return (FileEditor)DataManager.getInstance().getDataContext().getData(DataConstants.FILE_EDITOR); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Redo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Redo.java new file mode 100644 index 00000000000..0fc31148560 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Redo.java @@ -0,0 +1,40 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.fileEditor.FileEditor; + +/** + * author: lesya + */ +class Redo extends UndoOrRedo{ + public Redo(UndoManagerImpl manager, FileEditor editor) { + super(manager, editor); + } + + protected UndoRedoStacksHolder getStackHolder() { + return myManager.getRedoStacksHolder(); + } + + protected UndoRedoStacksHolder getReverseStackHolder() { + return myManager.getUndoStacksHolder(); + } + + protected String getActionName() { + return "Redo"; + } + + protected void performAction() { + myUndoableGroup.redo(); + } + + protected EditorAndState getBeforeState() { + return myUndoableGroup.getStateBefore(); + } + + protected EditorAndState getAfterState() { + return myUndoableGroup.getStateAfter(); + } + + protected void setBeforeState(EditorAndState state) { + myUndoableGroup.setStateBefore(state); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Undo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Undo.java new file mode 100644 index 00000000000..7e117644093 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/Undo.java @@ -0,0 +1,40 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.fileEditor.FileEditor; + +/** + * author: lesya + */ +class Undo extends UndoOrRedo{ + public Undo(UndoManagerImpl manager, FileEditor editor) { + super(manager, editor); + } + + protected UndoRedoStacksHolder getStackHolder() { + return myManager.getUndoStacksHolder(); + } + + protected UndoRedoStacksHolder getReverseStackHolder() { + return myManager.getRedoStacksHolder(); + } + + protected String getActionName() { + return "Undo"; + } + + protected void performAction() { + myUndoableGroup.undo(); + } + + protected EditorAndState getBeforeState() { + return myUndoableGroup.getStateAfter(); + } + + protected EditorAndState getAfterState() { + return myUndoableGroup.getStateBefore(); + } + + protected void setBeforeState(EditorAndState state) { + myUndoableGroup.setStateAfter(state); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoManagerImpl.java new file mode 100644 index 00000000000..cf2b7e39b1b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -0,0 +1,537 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.command.*; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.NonUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class UndoManagerImpl extends UndoManager implements ProjectComponent, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.impl.UndoManagerImpl"); + + public static final int GLOBAL_UNDO_LIMIT = 10; + public static final int LOCAL_UNDO_LIMIT = 100; + public static final int COMMANDS_TO_KEEP_LIVE_QUEUES = 100; + public static final int COMMAND_TO_RUN_COMPACT = 20; + public static final int FREE_QUEUES_LIMIT = 30; + + private ProjectEx myProject; + + private int myCommandLevel = 0; + + private static final int NONE = 0; + private static final int UNDO = 1; + private static final int REDO = 2; + private int myCurrentOperationState = NONE; + + private CommandMerger myLastMerger; + + private CommandListener myCommandListener; + + private final UndoRedoStacksHolder myUndoStacksHolder = new UndoRedoStacksHolder(); + private final UndoRedoStacksHolder myRedoStacksHolder = new UndoRedoStacksHolder(); + + + DocumentEditingUndoProvider myDocumentEditingUndoProvider; + private CommandMerger myCurrentMerger; + private CurrentEditorProvider myCurrentEditorProvider; + private FileOperationsUndoProvider myFileOperationUndoProvider; + + private Project myCurrentActionProject = DummyProject.getInstance(); + private int myCommandCounter = 1; + private MyBeforeDeletionListener myBeforeFileDeletionListener; + private CommandProcessor myCommandProcessor; + private EditorFactory myEditorFactory; + private VirtualFileManager myVirtualFileManager; + private StartupManager myStartupManager; + + public UndoManagerImpl(Project project, + Application application, + CommandProcessor commandProcessor, + EditorFactory editorFactory, + VirtualFileManager virtualFileManager, + StartupManager startupManager) { + myProject = (ProjectEx)project; + myCommandProcessor = commandProcessor; + myEditorFactory = editorFactory; + myVirtualFileManager = virtualFileManager; + myStartupManager = startupManager; + + init(application); + } + + public UndoManagerImpl(Application application, + CommandProcessor commandProcessor, + EditorFactory editorFactory, + VirtualFileManager virtualFileManager) { + myProject = null; + myCommandProcessor = commandProcessor; + myEditorFactory = editorFactory; + myVirtualFileManager = virtualFileManager; + + init(application); + } + + private void init(Application application) { + if (myProject == null || application.isUnitTestMode() && !myProject.isDefault() && !myProject.isDummy()) { + initialize(); + } + } + + public String getComponentName() { + return "UndoManager"; + } + + public Project getProject() { + return myProject; + } + + public void initComponent() { } + + private void initialize() { + + Runnable initAction = new Runnable() { + public void run() { + runStartupActivity(); + } + }; + if (myProject != null) { + myStartupManager.registerStartupActivity(initAction); + } + else { + initAction.run(); + } + + } + + /** @fabrique **/ + public void runStartupActivity() { + myCurrentEditorProvider = new FocusBasedCurrentEditorProvider(); + myCommandListener = new CommandAdapter() { + private boolean myFakeCommandStarted = false; + + public void commandStarted(CommandEvent event) { + onCommandStarted(event.getProject(), event.getUndoConfirmationPolicy()); + } + + public void commandFinished(CommandEvent event) { + onCommandFinished(event.getProject(), event.getCommandName(), event.getCommandGroupId()); + } + + public void undoTransparentActionStarted() { + if (!isInsideCommand()) { + myFakeCommandStarted = true; + onCommandStarted(myProject, UndoConfirmationPolicy.DEFAULT); + } + } + + public void undoTransparentActionFinished() { + if (myFakeCommandStarted) { + myFakeCommandStarted = false; + onCommandFinished(myProject, "", null); + } + } + }; + myCommandProcessor.addCommandListener(myCommandListener); + + myDocumentEditingUndoProvider = new DocumentEditingUndoProvider(myProject, myEditorFactory); + myLastMerger = new CommandMerger(this, myEditorFactory); + myFileOperationUndoProvider = new FileOperationsUndoProvider(this, myProject); + myBeforeFileDeletionListener = new MyBeforeDeletionListener(); + myVirtualFileManager.addVirtualFileListener(myBeforeFileDeletionListener); + } + + public void onCommandFinished(final Project project, + final String commandName, + final Object commandGroupId) { + commandFinished(commandName, commandGroupId); + if (myCommandLevel == 0) { + myFileOperationUndoProvider.commandFinished(project); + myCurrentActionProject = DummyProject.getInstance(); + } + LOG.assertTrue(myCommandLevel == 0 || !(myCurrentActionProject instanceof DummyProject)); + } + + private void onCommandStarted(final Project project, UndoConfirmationPolicy undoConfirmationPolicy) { + if (myCommandLevel == 0) { + myFileOperationUndoProvider.commandStarted(project); + myCurrentActionProject = project; + } + + commandStarted(undoConfirmationPolicy); + + LOG.assertTrue(myCommandLevel == 0 || !(myCurrentActionProject instanceof DummyProject)); + } + + public void dropHistory() { + // Run dummy command in order to drop all mergers... + CommandProcessor.getInstance().executeCommand(myProject, EmptyRunnable.getInstance(), "Dummy", null); + + LOG.assertTrue(myCommandLevel == 0); + + myUndoStacksHolder.dropHistory(); + myRedoStacksHolder.dropHistory(); + } + + public void disposeComponent() { + if (myCommandListener != null) { + myCommandProcessor.removeCommandListener(myCommandListener); + myDocumentEditingUndoProvider.dispose(); + myLastMerger.dispose(); + myFileOperationUndoProvider.dispose(); + } + myVirtualFileManager.removeVirtualFileListener(myBeforeFileDeletionListener); + myProject = null; + } + + public void setCurrentEditorProvider(CurrentEditorProvider currentEditorProvider) { + myCurrentEditorProvider = currentEditorProvider; + } + + public void projectOpened() { + initialize(); + } + + public void projectClosed() { + } + + public void clearUndoRedoQueue(FileEditor editor) { + LOG.assertTrue(myCommandLevel == 0); + myLastMerger.flushCurrentCommand(); + disposeCurrentMerger(); + + myUndoStacksHolder.clearEditorStack(editor); + myRedoStacksHolder.clearEditorStack(editor); + } + + public void clearUndoRedoQueue(Document document) { + clearUndoRedoQueue(DocumentReferenceByDocument.createDocumentReference(document)); + } + + public void clearUndoRedoQueue(DocumentReference docRef) { + myLastMerger.flushCurrentCommand(); + disposeCurrentMerger(); + + myUndoStacksHolder.clearFileQueue(docRef); + myRedoStacksHolder.clearFileQueue(docRef); + } + + public void clearUndoRedoQueue(VirtualFile file) { + clearUndoRedoQueue(new DocumentReferenceByVirtualFile(file)); + } + + public void compact() { + if (myCurrentOperationState == NONE && myCommandCounter % COMMAND_TO_RUN_COMPACT == 0) { + doCompact(); + } + } + + private void doCompact() { + Set docsOnHold = new HashSet(myUndoStacksHolder.getAffectedDocuments()); + docsOnHold.addAll(myRedoStacksHolder.getAffectedDocuments()); + + docsOnHold.removeAll(myUndoStacksHolder.getDocsInGlobalQueue()); + docsOnHold.removeAll(myRedoStacksHolder.getDocsInGlobalQueue()); + + Set openedDocs = new HashSet(); + for (Iterator iterator = docsOnHold.iterator(); iterator.hasNext();) { + DocumentReference docRef = iterator.next(); + final VirtualFile file = docRef.getFile(); + if (file != null) { + if (myProject != null && FileEditorManager.getInstance(myProject).isFileOpen(file)) { + openedDocs.add(docRef); + } + } + else { + Document document = docRef.getDocument(); + if (document != null && EditorFactory.getInstance().getEditors(document, myProject).length > 0) { + openedDocs.add(docRef); + } + } + } + docsOnHold.removeAll(openedDocs); + + if (docsOnHold.size() <= FREE_QUEUES_LIMIT) return; + + final DocumentReference[] freeDocs = docsOnHold.toArray(new DocumentReference[docsOnHold.size()]); + Arrays.sort(freeDocs, new Comparator() { + public int compare(DocumentReference docRef1, DocumentReference docRef2) { + return getRefAge(docRef1) - getRefAge(docRef2); + } + }); + + for (int i = 0; i < freeDocs.length - FREE_QUEUES_LIMIT; i++) { + DocumentReference doc = freeDocs[i]; + if (getRefAge(doc) + COMMANDS_TO_KEEP_LIVE_QUEUES > myCommandCounter) break; + clearUndoRedoQueue(doc); + } + } + + private int getRefAge(DocumentReference ref) { + return Math.max(myUndoStacksHolder.getYoungestCommandAge(ref), + myRedoStacksHolder.getYoungestCommandAge(ref)); + } + + public void undoableActionPerformed(UndoableAction action) { + if (myCurrentOperationState != NONE) return; + + if (myCommandLevel == 0) { + LOG.assertTrue(action instanceof NonUndoableAction, + "Undoable actions allowed inside commands only (see com.intellij.openapi.command.CommandProcessor.executeCommand())"); + commandStarted(UndoConfirmationPolicy.DEFAULT); + myCurrentMerger.add(action, false); + commandFinished("", null); + return; + } + + myCurrentMerger.add(action, CommandProcessor.getInstance().isUndoTransparentActionInProgress()); + } + + public boolean isUndoInProgress() { + return myCurrentOperationState == UNDO; + } + + public boolean isRedoInProgress() { + return myCurrentOperationState == REDO; + } + + public void undo(FileEditor editor) { + LOG.assertTrue(isUndoAvailable(editor)); + myCurrentOperationState = UNDO; + undoOrRedo(editor); + } + + public void redo(FileEditor editor) { + LOG.assertTrue(isRedoAvailable(editor)); + myCurrentOperationState = REDO; + undoOrRedo(editor); + } + + private void undoOrRedo(final FileEditor editor) { + final RuntimeException[] exception = new RuntimeException[1]; + Runnable executeUndoOrRedoAction = new Runnable() { + public void run() { + try { + if (isUndoInProgress()) { + myLastMerger.undoOrRedo(editor, true); + } + else { + myLastMerger.undoOrRedo(editor, false); + } + } + catch (RuntimeException ex) { + exception[0] = ex; + } + finally { + myCurrentOperationState = NONE; + } + } + }; + + CommandProcessor.getInstance().executeCommand(myProject, executeUndoOrRedoAction, + isUndoInProgress() ? "Undo" : "Redo", null, myLastMerger.getUndoConfirmationPolicy()); + if (exception[0] != null) throw exception[0]; + } + + public boolean isUndoAvailable(FileEditor editor) { + if (editor != null) { + if (editor instanceof TextEditor) { + Editor activeEditor = ((TextEditor)editor).getEditor(); + if (activeEditor.isViewer()) { + return false; + } + } + + Document[] documents = TextEditorProvider.getDocuments(editor); + if (documents == null || documents.length == 0) return false; + + for (int i = 0; i < documents.length; i++) { + Document document = documents[i]; + if (!myLastMerger.isEmpty(DocumentReferenceByDocument.createDocumentReference(document))) + return true; + + LinkedList localStack = getUndoStacksHolder().getStack(document); + if (!localStack.isEmpty()){ + return true; + } + } + + return false; + + } + else { + if ((myLastMerger != null) && myLastMerger.isComplex() && !myLastMerger.isEmpty()) return true; + return !myUndoStacksHolder.getGlobalStack().isEmpty(); + } + } + + public boolean isRedoAvailable(FileEditor editor) { + if (editor != null) { + if (editor instanceof TextEditor) { + Editor activeEditor = ((TextEditor)editor).getEditor(); + if (activeEditor.isViewer()) { + return false; + } + } + Document[] documents = TextEditorProvider.getDocuments(editor); + if (documents == null || documents.length == 0){ + return false; + } + + for (int i = 0; i < documents.length; i++) { + Document document = documents[i]; + LinkedList localStack = getRedoStacksHolder().getStack(document); + if (!localStack.isEmpty()){ + return true; + } + } + + + return false; + } + else { + return !myRedoStacksHolder.getGlobalStack().isEmpty(); + } + } + + public boolean isActive() { + return Comparing.equal(myProject, myCurrentActionProject); + } + + private void commandStarted(UndoConfirmationPolicy undoConfirmationPolicy) { + if (myCommandLevel == 0) { + myCurrentMerger = new CommandMerger(this, EditorFactory.getInstance()); + } + LOG.assertTrue(myCurrentMerger != null, String.valueOf(myCommandLevel)); + myCurrentMerger.setBeforeState(getCurrentState()); + myCurrentMerger.mergeUndoConfirmationPolicy(undoConfirmationPolicy); + + myCommandLevel++; + } + + private EditorAndState getCurrentState() { + FileEditor editor = myCurrentEditorProvider.getCurrentEditor(); + if (editor == null) { + return null; + } + return new EditorAndState(editor, editor.getState(FileEditorStateLevel.UNDO)); + } + + private void commandFinished(String commandName, Object groupId) { + if (myCommandLevel == 0) return; // possible if command listener is added within command + myCommandLevel--; + if (myCommandLevel > 0) return; + myCurrentMerger.setAfterState(getCurrentState()); + myLastMerger.commandFinished(commandName, groupId, myCurrentMerger); + + disposeCurrentMerger(); + } + + private void disposeCurrentMerger() { + LOG.assertTrue(myCommandLevel == 0); + if (myCurrentMerger != null) { + myCurrentMerger.dispose(); + myCurrentMerger = null; + } + } + + public UndoRedoStacksHolder getUndoStacksHolder() { + return myUndoStacksHolder; + } + + public UndoRedoStacksHolder getRedoStacksHolder() { + return myRedoStacksHolder; + } + + public boolean isInsideCommand() { + return myCommandLevel > 0; + } + + public boolean undoableActionsForDocumentAreEmpty(DocumentReference docRef) { + if (myCurrentMerger != null && !myCurrentMerger.isEmpty(docRef)) return false; + if (myLastMerger != null && !myLastMerger.isEmpty(docRef)) return false; + if (!myUndoStacksHolder.getStack(docRef).isEmpty()) return false; + LinkedList globalStack = myUndoStacksHolder.getGlobalStack(); + for (Iterator each = globalStack.iterator(); each.hasNext();) { + Collection affectedDocuments = ((UndoableGroup)each.next()).getAffectedDocuments(); + if (affectedDocuments.contains(docRef)) return false; + } + return true; + } + + public int getCommandCounterAndInc() { + return ++myCommandCounter; + } + + public DocumentReference findInvalidatedReferenceByUrl(String url) { + DocumentReference result = findInvalidatedReferenceByUrl(myUndoStacksHolder.getAffectedDocuments(), url); + if (result != null) return result; + result = findInvalidatedReferenceByUrl(myRedoStacksHolder.getAffectedDocuments(), url); + if (result != null) return result; + result = findInvalidatedReferenceByUrl(myRedoStacksHolder.getGlobalStackAffectedDocuments(), url); + if (result != null) return result; + if (myLastMerger != null) { + result = findInvalidatedReferenceByUrl(myLastMerger.getAffectedDocuments(), url); + if (result != null) return result; + } + if (myCurrentMerger != null) { + result = findInvalidatedReferenceByUrl(myCurrentMerger.getAffectedDocuments(), url); + if (result != null) return result; + } + return null; + } + + private DocumentReference findInvalidatedReferenceByUrl(Collection collection, String url) { + for (Iterator each = collection.iterator(); each.hasNext();) { + DocumentReference documentReference = (DocumentReference)each.next(); + if (documentReference.equalsByUrl(url)) return documentReference; + } + return null; + + } + + + private class MyBeforeDeletionListener extends VirtualFileAdapter { + public void beforeFileDeletion(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + beforeFileDeletion(file, myUndoStacksHolder.getAffectedDocuments()); + beforeFileDeletion(file, myUndoStacksHolder.getGlobalStackAffectedDocuments()); + beforeFileDeletion(file, myRedoStacksHolder.getAffectedDocuments()); + beforeFileDeletion(file, myRedoStacksHolder.getGlobalStackAffectedDocuments()); + if (myLastMerger != null) beforeFileDeletion(file, myLastMerger.getAffectedDocuments()); + if (myCurrentMerger != null) beforeFileDeletion(file, myCurrentMerger.getAffectedDocuments()); + } + + private void beforeFileDeletion(VirtualFile file, Collection docs) { + for (Iterator iterator = docs.iterator(); iterator.hasNext();) { + DocumentReference documentReference = (DocumentReference)iterator.next(); + documentReference.beforeFileDeletion(file); + } + + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoOrRedo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoOrRedo.java new file mode 100644 index 00000000000..d6b935077e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoOrRedo.java @@ -0,0 +1,259 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.NonUndoableAction; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * author: lesya + */ +abstract class UndoOrRedo { + protected final UndoManagerImpl myManager; + private final FileEditor myEditor; + protected final UndoableGroup myUndoableGroup; + + public UndoOrRedo(UndoManagerImpl manager, FileEditor editor) { + myManager = manager; + myEditor = editor; + myUndoableGroup = (UndoableGroup)getStack().getLast(); + } + + protected abstract UndoRedoStacksHolder getStackHolder(); + + protected abstract UndoRedoStacksHolder getReverseStackHolder(); + + protected abstract String getActionName(); + + protected abstract EditorAndState getBeforeState(); + + protected abstract EditorAndState getAfterState(); + + protected abstract void performAction(); + + protected abstract void setBeforeState(EditorAndState state); + + private Collection collectReadOnlyDocuments() { + Collection affectedDocument = myUndoableGroup.getAffectedDocuments(); + Collection readOnlyDocs = new ArrayList(); + for (Iterator iterator = affectedDocument.iterator(); iterator.hasNext();) { + DocumentReference ref = iterator.next(); + if (ref instanceof DocumentReferenceByDocument) { + Document doc = ref.getDocument(); + if (doc != null && !doc.isWritable()) readOnlyDocs.add(doc); + } + } + return readOnlyDocs; + } + + private Collection collectReadOnlyAffectedFiles() { + Collection affectedDocument = myUndoableGroup.getAffectedDocuments(); + Collection readOnlyFiles = new ArrayList(); + for (Iterator each = affectedDocument.iterator(); each.hasNext();) { + DocumentReference documentReference = (DocumentReference)each.next(); + VirtualFile file = documentReference.getFile(); + if ((file != null) && file.isValid() && !file.isWritable()) { + readOnlyFiles.add(file); + } + } + return readOnlyFiles; + } + + public void execute() { + if (containsAnotherChanges() || containsNonUndoableActions()) { + reportCannotUndo(); + return; + } + + if (myUndoableGroup.askConfirmation()) { + if (canceledByUser()) { + return; + } + } + else { + if (restore(getBeforeState())) { + setBeforeState(new EditorAndState(myEditor, myEditor.getState(FileEditorStateLevel.UNDO))); + return; + } + } + + Collection readOnlyFiles = collectReadOnlyAffectedFiles(); + if (!readOnlyFiles.isEmpty()) { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt(readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()])); + return; + } + + Collection readOnlyDocuments = collectReadOnlyDocuments(); + if (!readOnlyDocuments.isEmpty()) { + for (Iterator iterator = readOnlyDocuments.iterator(); iterator.hasNext();) { + Document document = iterator.next(); + document.fireReadOnlyModificationAttempt(); + } + return; + } + + removeLastFromMyStacks(); + addLastToReverseStacks(); + + performAction(); + + restore(getAfterState()); + } + + private boolean containsNonUndoableActions() { + final UndoableAction[] actions = myUndoableGroup.getActions(); + for (int i = 0; i < actions.length; i++) { + if (actions[i] instanceof NonUndoableAction) return true; + } + return false; + } + + private boolean restore(EditorAndState pair) { + if (myEditor == null || pair == null || pair.getEditor() == null) { + return false; + } + + // we cannot simply compare editors here because of the following scenario: + // 1. make changes in editor for file A + // 2. move caret + // 3. close editor + // 4. re-open editor for A via Ctrl-E + // 5. undo -> position is not affected, because instance created in step 4 is not the same!!! + if (!myEditor.getClass().equals(pair.getEditor().getClass())) { + return false; + } + + // If current editor state isn't equals to remembered state then + // we have to try to restore previous state. But sometime it's + // not possible to restore it. For example, it's not possible to + // restore scroll proportion if editor doesn not have scrolling any more. + FileEditorState currentState = myEditor.getState(FileEditorStateLevel.UNDO); + if (currentState.equals(pair.getState())) { + return false; + } + + myEditor.setState(pair.getState()); + return true; + } + + private boolean canceledByUser() { + String actionText = getActionName() + " " + myUndoableGroup.getCommandName(); + if (actionText.length() > 80) { + actionText = actionText.substring(0, 80) + "... "; + } + + return Messages.showOkCancelDialog(myManager.getProject(), actionText + "?", getActionName(), + Messages.getQuestionIcon()) != DialogWrapper.OK_EXIT_CODE; + } + + private void addLastToReverseStacks() { + Collection stacks = getStacks(getReverseStackHolder()); + for (Iterator i = stacks.iterator(); i.hasNext();) { + LinkedList linkedList = (LinkedList)i.next(); + linkedList.addLast(myUndoableGroup); + } + if (myUndoableGroup.isComplex()) { + getReverseStackHolder().getGlobalStack().addLast(myUndoableGroup); + } + } + + private Collection getDocumentsReferences() { + return myUndoableGroup.getAffectedDocuments(); + } + + private void removeLastFromMyStacks() { + for (Iterator i = getStacks().iterator(); i.hasNext();) { + LinkedList linkedList = (LinkedList)i.next(); + linkedList.removeLast(); + } + if (myUndoableGroup.isComplex()) { + getStackHolder().getGlobalStack().removeLast(); + } + } + + private void reportCannotUndo() { + if (ApplicationManager.getApplication().isUnitTestMode()) { + throw new RuntimeException("Files changed"); + } + + Messages.showMessageDialog(myManager.getProject(), "Cannot undo. Some files were changed", "Undo", + Messages.getErrorIcon()); + } + + private boolean containsAnotherChanges() { + for (Iterator each = getStacks().iterator(); each.hasNext();) { + LinkedList linkedList = each.next(); + if (linkedList.isEmpty()) continue; + if (!linkedList.getLast().equals(myUndoableGroup)) return true; + } + return (myUndoableGroup.isComplex() && !getStackHolder().getGlobalStack().getLast().equals(myUndoableGroup)); + + } + + private Collection getStacks() { + return getStacks(getStackHolder()); + } + + private Collection getStacks(UndoRedoStacksHolder stackHolder) { + ArrayList result = new ArrayList(); + for (Iterator i = getDocumentsReferences().iterator(); i.hasNext();) { + result.add(stackHolder.getStack(i.next())); + } + return result; + } + + + private LinkedList getStack() { + if (myEditor == null) { + return getStackHolder().getGlobalStack(); + } + else { + long recentDocumentTimeStamp = -1; + LinkedList result = null; + Document[] documents = TextEditorProvider.getDocuments(myEditor); + for (int i = 0; i < documents.length; i++) { + Document document = documents[i]; + LinkedList stack = getStackHolder().getStack(document); + if (!stack.isEmpty()) { + long modificationStamp = document.getModificationStamp(); + if (recentDocumentTimeStamp < modificationStamp) { + result = stack; + recentDocumentTimeStamp = modificationStamp; + } + } + } + if (result != null) { + return result; + } + else { + throw new RuntimeException("Cannot find stack"); + } + } + } + + public static void execute(UndoManagerImpl manager, FileEditor editor, boolean isUndo) { + if (isUndo) { + new Undo(manager, editor).execute(); + } + else { + new Redo(manager, editor).execute(); + } + } + +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java new file mode 100644 index 00000000000..d773c9e0e94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java @@ -0,0 +1,137 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.util.Key; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Set; + +/** + * author: lesya + */ + +class UndoRedoStacksHolder { + private HashMap> myStackOwnerToStack = new HashMap>(); + private LinkedList myGlobalStack = new LinkedList(); + + private final Key> STACK_IN_DOCUMENT_KEY = Key.create("STACK_IN_DOCUMENT_KEY"); + + public LinkedList getStack(Document document) { + return getStack(DocumentReferenceByDocument.createDocumentReference(document)); + } + + public LinkedList getStack(DocumentReference docRef) { + if (docRef == null) { + throw new IllegalArgumentException("docRef cannot be null"); + } + + LinkedList result; + if (docRef.getFile() != null) { + result = myStackOwnerToStack.get(docRef); + if (result == null) { + result = new LinkedList(); + myStackOwnerToStack.put(docRef, result); + } + } + else { + result = docRef.getDocument().getUserData(STACK_IN_DOCUMENT_KEY); + if (result == null) { + result = new LinkedList(); + docRef.getDocument().putUserData(STACK_IN_DOCUMENT_KEY, result); + } + } + + return result; + } + + public void clearFileQueue(DocumentReference docRef) { + final LinkedList queue = getStack(docRef); + clear(queue); + if (docRef.getFile() != null) { + myStackOwnerToStack.remove(docRef); + } + else { + docRef.getDocument().putUserData(STACK_IN_DOCUMENT_KEY, null); + } + } + + private void clear(LinkedList stack) { + for (Iterator each = stack.iterator(); each.hasNext();) { + UndoableGroup undoableGroup = (UndoableGroup)each.next(); + undoableGroup.dispose(); + } + stack.clear(); + } + + public LinkedList getGlobalStack() { + return myGlobalStack; + } + + public void clearGlobalStack() { + myGlobalStack.clear(); + } + + public void addToLocalStack(DocumentReference docRef, UndoableGroup commandInfo) { + addToStack(getStack(docRef), commandInfo, UndoManagerImpl.LOCAL_UNDO_LIMIT); + } + + public void addToGlobalStack(UndoableGroup commandInfo) { + addToStack(getGlobalStack(), commandInfo, UndoManagerImpl.GLOBAL_UNDO_LIMIT); + } + + private void addToStack(LinkedList stack, UndoableGroup commandInfo, int limit) { + stack.addLast(commandInfo); + while (stack.size() > limit) { + UndoableGroup undoableGroup = (UndoableGroup)stack.removeFirst(); + undoableGroup.dispose(); + } + } + + public void clearEditorStack(FileEditor editor) { + Document[] documents = TextEditorProvider.getDocuments(editor); + for (int i = 0; i < documents.length; i++) { + clear(getStack(DocumentReferenceByDocument.createDocumentReference(documents[i]))); + } + + } + + public Set getAffectedDocuments() { + return myStackOwnerToStack.keySet(); + } + + public Set getDocsInGlobalQueue() { + HashSet result = new HashSet(); + for (Iterator iterator = getGlobalStack().iterator(); iterator.hasNext();) { + UndoableGroup group = iterator.next(); + result.addAll(group.getAffectedDocuments()); + } + return result; + } + + public int getYoungestCommandAge(DocumentReference docRef) { + final LinkedList stack = getStack(docRef); + if (stack.isEmpty()) return 0; + return Math.max(stack.getFirst().getCommandCounter(), stack.getLast().getCommandCounter()); + } + + public Collection getGlobalStackAffectedDocuments() { + Collection result = new HashSet(); + for (Iterator each = myGlobalStack.iterator(); each.hasNext();) { + UndoableGroup undoableGroup = (UndoableGroup)each.next(); + result.addAll(undoableGroup.getAffectedDocuments()); + } + return result; + } + + public void dropHistory() { + clearGlobalStack(); + myStackOwnerToStack.clear(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoableGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoableGroup.java new file mode 100644 index 00000000000..a7fd033ea21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/impl/UndoableGroup.java @@ -0,0 +1,180 @@ +package com.intellij.openapi.command.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.command.undo.UnexpectedUndoException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; + +import java.util.*; + +/** + * @author max + */ +class UndoableGroup { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.impl.UndoableGroup"); + + private String myCommandName; + private boolean myComplex; + private int myCommandCounter; + private ArrayList myActions; + private EditorAndState myStateBefore; + private EditorAndState myStateAfter; + private Project myProject; + private final UndoConfirmationPolicy myUndoConfirmationPolicy; + + public UndoableGroup(String commandName, boolean isComplex, Project project, EditorAndState stateBefore, EditorAndState stateAfter, int commandCounter, + UndoConfirmationPolicy undoConfirmationPolicy) { + myCommandName = commandName; + myComplex = isComplex; + myCommandCounter = commandCounter; + myActions = new ArrayList(); + myProject = project; + myStateBefore = stateBefore; + myStateAfter = stateAfter; + myUndoConfirmationPolicy = undoConfirmationPolicy; + } + + public boolean isComplex() { + return myComplex; + } + + public UndoableAction[] getActions() { + return myActions.toArray(new UndoableAction[myActions.size()]); + } + + public void addTailActions(Collection actions) { + myActions.addAll(actions); + } + + private Iterator reverseIterator(final ListIterator iter) { + return new Iterator() { + public boolean hasNext() { + return iter.hasPrevious(); + } + + public UndoableAction next() { + return iter.previous(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + private void undoOrRedo(final boolean isUndo) { + LvcsAction actionStarted = LvcsAction.EMPTY; + if (myProject != null) { + LocalVcs lvcs = LocalVcs.getInstance(myProject); + if (isComplex() && lvcs != null) { + actionStarted = lvcs.startAction(actionName(isUndo) + " " + myCommandName, "", false); + } + } + try { + performWritableUndoOrRedoAction(isUndo); + } finally { + actionStarted.finish(); + } + } + + private void performWritableUndoOrRedoAction(final boolean isUndo) { + final Iterator each = isUndo ? reverseIterator(myActions.listIterator(myActions.size())) : myActions.iterator(); + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + String message = "Cannot " + actionName(isUndo); + + while (each.hasNext()) { + UndoableAction undoableAction = each.next(); + try { + if (isUndo) + undoableAction.undo(); + else + undoableAction.redo(); + } catch (UnexpectedUndoException e) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { + if (e.getMessage() != null) { + message += ".\n" + e.getMessage(); + } + Messages.showMessageDialog(myProject, message, message, Messages.getErrorIcon()); + } else { + LOG.error(e); + } + } + } + } + } + ); + } + + private String actionName(final boolean isUndo) { + return isUndo ? "Undo" : "Redo"; + } + + public void undo() { + undoOrRedo(true); + } + + public void redo() { + undoOrRedo(false); + } + + public Collection getAffectedDocuments() { + Set result = new HashSet(); + for (Iterator iterator = myActions.iterator(); iterator.hasNext();) { + UndoableAction action = (UndoableAction) iterator.next(); + result.addAll(new ArrayList(Arrays.asList(action.getAffectedDocuments()))); + } + return result; + } + + public EditorAndState getStateBefore() { + return myStateBefore; + } + + public EditorAndState getStateAfter() { + return myStateAfter; + } + + public void setStateBefore(EditorAndState stateBefore) { + myStateBefore = stateBefore; + } + + public void setStateAfter(EditorAndState stateAfter) { + myStateAfter = stateAfter; + } + + public void dispose() { + for (Iterator each = myActions.iterator(); each.hasNext();) { + UndoableAction undoableAction = (UndoableAction) each.next(); + if (undoableAction instanceof Disposeable) ((Disposeable) undoableAction).dispose(); + + } + } + + public String getCommandName() { + return myCommandName; + } + + public int getCommandCounter() { + return myCommandCounter; + } + + public boolean askConfirmation() { + if (myUndoConfirmationPolicy == UndoConfirmationPolicy.REQUEST_CONFIRMATION){ + return true; + } else if (myUndoConfirmationPolicy == UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION){ + return false; + } else { + return isComplex() || (getAffectedDocuments().size() > 1); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/DocumentReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/DocumentReference.java new file mode 100644 index 00000000000..94b868e91a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/DocumentReference.java @@ -0,0 +1,43 @@ +package com.intellij.openapi.command.undo; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author max + */ +public abstract class DocumentReference { + public int hashCode() { + VirtualFile file = getFile(); + return file != null ? file.hashCode() : getDocument().hashCode(); + } + + public boolean equals(Object object) { + if (!(object instanceof DocumentReference)) return false; + VirtualFile file1 = getFile(); + VirtualFile file2 = ((DocumentReference) object).getFile(); + if (file1 != null) return file1.equals(file2); + if (file2 != null) return file2.equals(file1); + + return getDocument().equals(((DocumentReference) object).getDocument()); + } + + public abstract VirtualFile getFile(); + public abstract Document getDocument(); + public abstract void beforeFileDeletion(VirtualFile file); + + protected abstract String getUrl(); + + public boolean equalsByUrl(String url) { + VirtualFile file = getFile(); + if (file == null) return false; + if (file.isValid()) return false; + String url1 = getUrl(); + if ((url1 == null) || (url == null)) return false; + if (SystemInfo.isFileSystemCaseSensitive) + return url.equals(url1); + else + return url.compareToIgnoreCase(url1) == 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/NonUndoableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/NonUndoableAction.java new file mode 100644 index 00000000000..1da78ce0a28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/NonUndoableAction.java @@ -0,0 +1,17 @@ + +package com.intellij.openapi.command.undo; + +import com.intellij.openapi.diagnostic.Logger; + +public abstract class NonUndoableAction implements UndoableAction{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.undo.NonUndoableAction"); + + public final void undo() throws UnexpectedUndoException { + LOG.assertTrue(false); + } + + public void redo() throws UnexpectedUndoException { + LOG.assertTrue(false); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoManager.java new file mode 100644 index 00000000000..9ea29b54409 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoManager.java @@ -0,0 +1,34 @@ + +package com.intellij.openapi.command.undo; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public abstract class UndoManager { + public static UndoManager getInstance(Project project) { + return project.getComponent(UndoManager.class); + } + + public static UndoManager getGlobalInstance() { + return ApplicationManager.getApplication().getComponent(UndoManager.class); + } + + public abstract void undoableActionPerformed(UndoableAction action); + + public abstract boolean isUndoInProgress(); + public abstract boolean isRedoInProgress(); + + public abstract void undo(FileEditor editor); + public abstract void redo(FileEditor editor); + public abstract boolean isUndoAvailable(FileEditor editor); + public abstract boolean isRedoAvailable(FileEditor editor); + + public abstract void clearUndoRedoQueue(VirtualFile file); + public abstract void clearUndoRedoQueue(FileEditor editor); + public abstract void clearUndoRedoQueue(Document document); + + public abstract void dropHistory(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoableAction.java new file mode 100644 index 00000000000..27b3a151b39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UndoableAction.java @@ -0,0 +1,28 @@ + +package com.intellij.openapi.command.undo; + + + +public interface UndoableAction { + /** + * Undoes this action. + * This method should not be invoked when any of its affected documents + * were changed. + * @see #getAffectedDocuments() + */ + void undo() throws UnexpectedUndoException; + void redo() throws UnexpectedUndoException; + + /** + * Returns array of documents that are "affected" by this action. + * If the returned value is null, all documents are "affected". + * The action can be undone iff all of its affected documents are either + * not affected by any of further actions or all of such actions are undone. + */ + DocumentReference[] getAffectedDocuments(); + + /** + * Returns true if undoing of any command containing this action requires a confirmation dialog. + */ + boolean isComplex(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UnexpectedUndoException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UnexpectedUndoException.java new file mode 100644 index 00000000000..08af0010a1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/command/undo/UnexpectedUndoException.java @@ -0,0 +1,8 @@ + +package com.intellij.openapi.command.undo; + +public class UnexpectedUndoException extends Exception{ + public UnexpectedUndoException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompileContextEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompileContextEx.java new file mode 100644 index 00000000000..6873afc8d74 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompileContextEx.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.compiler.ex; + +import com.intellij.compiler.make.DependencyCache; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerMessage; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + +public interface CompileContextEx extends CompileContext { + DependencyCache getDependencyCache(); + + VirtualFile getSourceFileByOutputFile(VirtualFile outputFile); + + void addMessage(CompilerMessage message); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompilerPathsEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompilerPathsEx.java new file mode 100644 index 00000000000..81d83d512f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/compiler/ex/CompilerPathsEx.java @@ -0,0 +1,163 @@ +package com.intellij.openapi.compiler.ex; + +import com.intellij.openapi.compiler.CompilerPaths; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Computable; +import com.intellij.util.PathUtil; +import com.intellij.util.containers.OrderedSet; +import gnu.trove.TObjectHashingStrategy; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; + +public class CompilerPathsEx extends CompilerPaths { + + public static class FileVisitor { + protected void accept(final VirtualFile file, final String fileRoot, final String filePath) { + if (file.isDirectory()) { + acceptDirectory(file, fileRoot, filePath); + } + else { + acceptFile(file, fileRoot, filePath); + } + } + + protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { + } + + protected void acceptDirectory(final VirtualFile file, final String fileRoot, final String filePath) { + final VirtualFile[] children = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile[] compute() { + return file.getChildren(); + } + }); + for (int idx = 0; idx < children.length; idx++) { + final VirtualFile child = children[idx]; + final String name = child.getName(); + final StringBuffer buf = new StringBuffer(filePath.length() + "/".length() + name.length()); + buf.append(filePath).append("/").append(name); + accept(child, fileRoot, buf.toString()); + } + } + } + + public static void visitFiles(final VirtualFile[] directories, final FileVisitor visitor) { + for (int idx = 0; idx < directories.length; idx++) { + final VirtualFile outputDir = directories[idx]; + final String path = ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return outputDir.getPath(); + } + }); + visitor.accept(outputDir, path, path); + } + } + + public static Set getOutputFiles(final Project project) { + final Set result = new HashSet(); + final VirtualFile[] outputDirectories = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile[] compute() { + return CompilerPathsEx.getOutputDirectories(ModuleManager.getInstance(project).getModules()); + } + }); + visitFiles(outputDirectories, new FileVisitor() { + protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { + if (!(file.getFileSystem() instanceof JarFileSystem)){ + result.add(filePath); + } + } + }); + return result; + } + + public static String getCompilationClasspath(Module module) { + final StringBuffer classpathBuffer = new StringBuffer(); + final OrderEntry[] orderEntries = getSortedOrderEntries(module); + for (int i = 0; i < orderEntries.length; i++) { + final OrderEntry orderEntry = orderEntries[i]; + final VirtualFile[] files = orderEntry.getFiles(OrderRootType.COMPILATION_CLASSES); + for (int j = 0; j < files.length; j++) { + final String path = PathUtil.getLocalPath(files[j]); + if (path == null) { + continue; + } + if (classpathBuffer.length() > 0) { + classpathBuffer.append(File.pathSeparatorChar); + } + classpathBuffer.append(path); + } + } + return classpathBuffer.toString(); + } + + private static OrderEntry[] getSortedOrderEntries(Module module) { + //return ModuleRootManager.getInstance(module).getOrderEntries(); + // TODO: this is a patch for SCR 36800, After J2EE Compiler copying mechanizm is fixed, + // TODO: remove all the code below and uncomment the line above + final OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); + final List result = new ArrayList(); + final List moduleOrderEntries = new ArrayList(); + int insertIndex = 0; + for (int idx = 0; idx < orderEntries.length; idx++) { + OrderEntry orderEntry = orderEntries[idx]; + if (orderEntry instanceof ModuleOrderEntry) { + moduleOrderEntries.add(orderEntry); + } + else { + result.add(orderEntry); + if (orderEntry instanceof ModuleSourceOrderEntry) { + insertIndex = result.size() - 1; + } + } + } + if (moduleOrderEntries.size() > 0) { + result.addAll(insertIndex, moduleOrderEntries); + } + return result.toArray(new OrderEntry[result.size()]); + } + + public static String[] getOutputPaths(Module[] modules) { + final Set outputPaths = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + + String outputPathUrl = moduleRootManager.getCompilerOutputPathUrl(); + if (outputPathUrl != null) { + outputPaths.add(VirtualFileManager.extractPath(outputPathUrl).replace('/', File.separatorChar)); + } + + String outputPathForTestsUrl = moduleRootManager.getCompilerOutputPathForTestsUrl(); + if (outputPathForTestsUrl != null) { + outputPaths.add(VirtualFileManager.extractPath(outputPathForTestsUrl).replace('/', File.separatorChar)); + } + } + return outputPaths.toArray(new String[outputPaths.size()]); + } + + public static VirtualFile[] getOutputDirectories(final Module[] modules) { + final Set dirs = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); + for (int idx = 0; idx < modules.length; idx++) { + Module module = modules[idx]; + final VirtualFile outputDir = getModuleOutputDirectory(module, false); + if (outputDir != null) { + dirs.add(outputDir); + } + VirtualFile testsOutputDir = getModuleOutputDirectory(module, true); + if (testsOutputDir != null) { + dirs.add(testsOutputDir); + } + } + return dirs.toArray(new VirtualFile[dirs.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentManagerEx.java new file mode 100644 index 00000000000..04a5a574593 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentManagerEx.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.components.ex; + +import com.intellij.openapi.components.ComponentManager; +import org.jdom.Element; + +import java.io.InputStream; +import java.util.Map; + +/** + * @author max + */ +public interface ComponentManagerEx extends ComponentManager { + void registerComponent(Class interfaceClass, Class implementationClass); + void registerComponent(Class interfaceClass, Class implementationClass, Map options); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentRegistrar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentRegistrar.java new file mode 100644 index 00000000000..a948e081fed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/ex/ComponentRegistrar.java @@ -0,0 +1,9 @@ +package com.intellij.openapi.components.ex; + + +/** + * @author mike + */ +public interface ComponentRegistrar { + void registerComponents(ComponentManagerEx manager); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/impl/ComponentManagerImpl.java new file mode 100644 index 00000000000..3aed64a6d0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/components/impl/ComponentManagerImpl.java @@ -0,0 +1,539 @@ +package com.intellij.openapi.components.impl; + +import com.intellij.diagnostic.PluginException; +import com.intellij.ide.plugins.PluginDescriptor; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.application.ex.DecodeDefaultsUtil; +import com.intellij.openapi.components.BaseComponent; +import com.intellij.openapi.components.SettingsSavingComponent; +import com.intellij.openapi.components.LoadCancelledException; +import com.intellij.openapi.components.ex.ComponentManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.*; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jdom.Document; +import org.picocontainer.*; +import org.picocontainer.defaults.*; +import com.intellij.util.containers.HashMap; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.util.*; + +/** + * @author mike + */ +public abstract class ComponentManagerImpl extends UserDataHolderBase implements ComponentManagerEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentManager"); + + //todo: Introduce ComponentDescriptor instead of three maps + private Map myInterfaceToLockMap = new HashMap(); + private Map myInterfaceToClassMap = new HashMap(); + private Map myInterfaceToOptionsMap = new HashMap(); + + private ArrayList myComponentInterfaces = new ArrayList(); // keeps order of component's registration + + private boolean myComponentsCreated = false; + + private Map myInterfaceToComponentMap = new HashMap(); + + private Map myNameToConfiguration = new HashMap(); + private Map myNameToComponent = new HashMap(); + private Map myInitializedComponents = new HashMap(); + private Set myInitializingComponents = new HashSet(); + private Set myLazyComponents = new HashSet(); + + private static Map ourDescriptorToRootMap = new HashMap(); + private MutablePicoContainer myPicoContainer; + + protected void initComponents() { + createComponents(); + getComponents(false); + } + + public boolean isComponentsCreated() { + return myComponentsCreated; + } + + private void createComponents() { + try { + final Class[] componentInterfaces = getComponentInterfaces(); + for (int i = 0; i < componentInterfaces.length; i++) { + Class componentInterface = componentInterfaces[i]; + if (!myLazyComponents.contains(componentInterface)) { + try { + createComponent(componentInterface); + } + catch (LoadCancelledException e) { + throw e; + } + catch (Exception e) { + LOG.error(e); + } + } + } + } + finally { + myComponentsCreated = true; + } + + } + + private BaseComponent createComponent(Class componentInterface) { + Class componentClass = myInterfaceToClassMap.get(componentInterface); + final BaseComponent component = instantiateComponent(componentClass); + myInterfaceToComponentMap.put(componentInterface, component); + + if (component == null) { + LOG.error("ComponentSetup.execute() for component " + componentInterface.getName() + " returned null"); + return null; + } + + final String componentName = component.getComponentName(); + if (componentName == null) { + LOG.error("Component name is null: " + component.getClass().getName()); + } + + if (myNameToComponent.containsKey(componentName)) { + BaseComponent loadedComponent = myNameToComponent.get(componentName); + // component may have been already loaded by PicoContainer, so fire error only if components are really different + if (!component.equals(loadedComponent)) { + LOG.error("Component name collision: " + componentName + " " + loadedComponent.getClass() + " and " + component.getClass()); + } + } + else { + myNameToComponent.put(componentName, component); + } + + return component; + } + + protected void disposeComponents() { + final BaseComponent[] components = getComponents(false); + + for (int i = 0; i < components.length; i++) { + BaseComponent component = components[i]; + try { + component.disposeComponent(); + } + catch (Throwable e) { + LOG.error(e); + } + } + + myComponentsCreated = false; + } + + public T getComponentFromContainer(Class interfaceClass) { + synchronized (this) { + final BaseComponent initializedComponent = myInitializedComponents.get(interfaceClass); + if (initializedComponent != null) return (T)initializedComponent; + } + + //if (!myComponentsCreated) { + // LOG.error("Component requests are not allowed before they are created"); + //} + + if (!myInterfaceToClassMap.containsKey(interfaceClass)) { + return null; + } + + Object lock = getLock(interfaceClass); + + synchronized (lock) { + if (myLazyComponents.contains(interfaceClass)) { + createComponent(interfaceClass); + myLazyComponents.remove(interfaceClass); + } + + BaseComponent component = myInterfaceToComponentMap.get(interfaceClass); + if (component == null) { + component = createComponent(interfaceClass); + } + if (component == null) { + LOG.error("Cant create " + interfaceClass); + return null; + } + + synchronized (this) { + if (myInitializingComponents.contains(component)) { + LOG.error("Component " + interfaceClass + " is being requested during its own initializing procedure"); + return (T)component; + } + + myInitializingComponents.add(component); + } + + try { + //initComponent(component, interfaceClass); + } + finally { + synchronized (this) { + myInitializingComponents.remove(component); + myInitializedComponents.put(interfaceClass, component); + } + } + return (T)component; + } + } + + public T getComponent(Class interfaceClass) { + return getComponent(interfaceClass, null); + } + + public T getComponent(Class interfaceClass, T defaultImplementation) { + final T fromContainer = getComponentFromContainer(interfaceClass); + if (fromContainer != null) return fromContainer; + if (defaultImplementation != null) return defaultImplementation; + return null; + } + + private void initComponent(BaseComponent component, Class componentClass) { + if (component instanceof JDOMExternalizable) { + initJdomExternalizable(componentClass, component); + } + component.initComponent(); + } + + + protected synchronized Object getLock(Class componentClass) { + Object lock; + lock = myInterfaceToLockMap.get(componentClass); + if (lock == null) { + myInterfaceToLockMap.put(componentClass, lock = new Object()); + } + return lock; + } + + public synchronized void registerComponent(Class interfaceClass, Class implementationClass) { + registerComponent(interfaceClass, implementationClass, null); + } + + public synchronized void registerComponent(Class interfaceClass, Class implementationClass, Map options, boolean plugin, boolean lazy) { + if (myInterfaceToClassMap.get(interfaceClass) != null) { + if (plugin) { + throw new Error("ComponentSetup for component " + interfaceClass.getName() + " already registered"); + } + else { + LOG.error("ComponentSetup for component " + interfaceClass.getName() + " already registered"); + } + } + + getPicoContainer().registerComponentImplementation(implementationClass, implementationClass); + + myInterfaceToClassMap.put(interfaceClass, implementationClass); + myComponentInterfaces.add(interfaceClass); + myInterfaceToOptionsMap.put(interfaceClass, options); + if (lazy) { + myLazyComponents.add(interfaceClass); + } + } + + public synchronized void registerComponent(Class interfaceClass, Class implementationClass, Map options) { + registerComponent(interfaceClass, implementationClass, options, false, false); + } + + public synchronized Class[] getComponentInterfaces() { + return myComponentInterfaces.toArray(new Class[myComponentInterfaces.size()]); + } + + public boolean hasComponent(Class interfaceClass) { + return myInterfaceToClassMap.containsKey(interfaceClass); + } + + protected BaseComponent[] getComponents(boolean includeLazyComponents) { + Class[] componentClasses = getComponentInterfaces(); + ArrayList components = new ArrayList(componentClasses.length); + for (int i = 0; i < componentClasses.length; i++) { + Class interfaceClass = componentClasses[i]; + if (includeLazyComponents || !myLazyComponents.contains(interfaceClass)) { + BaseComponent component = (BaseComponent)getComponent(interfaceClass); + if (component != null) components.add(component); + } + } + return components.toArray(new BaseComponent[components.size()]); + } + + public T[] getComponents(Class baseInterfaceClass) { + Class[] componentClasses; + synchronized (this) { + ArrayList array = new ArrayList(); + Iterator iter = myComponentInterfaces.iterator(); + while (iter.hasNext()) { + Class componentClass = iter.next(); + if (baseInterfaceClass.isAssignableFrom(componentClass)) { + array.add(componentClass); + } + } + componentClasses = array.toArray(new Class[array.size()]); + } + T[] components = (T[])Array.newInstance(baseInterfaceClass, componentClasses.length); + for (int i = 0; i < componentClasses.length; i++) { + components[i] = (T)getComponent(componentClasses[i]); + } + return components; + } + + protected void initJdomExternalizable(Class componentClass, BaseComponent component) { + doInitJdomExternalizable(componentClass, component); + } + + public final void doInitJdomExternalizable(Class componentClass, BaseComponent component) { + try { + Element element = getDefaults(component); + + if (element != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Loading defaults for " + componentClass.getName()); + } + ((JDOMExternalizable)component).readExternal(element); + } + } + catch (Exception e) { + LOG.error("Cannot load defaults for " + componentClass.getName(), e); + } + + Element element = getConfiguration(component.getComponentName()); + + if (element != null) { + try { + if (LOG.isDebugEnabled()) { + LOG.debug("Loading configuration for " + componentClass.getName()); + } + ((JDOMExternalizable)component).readExternal(element); + } + catch (InvalidDataException e) { + synchronized (this) { + myInterfaceToComponentMap.remove(componentClass); + } + throw new InvalidComponentDataException(e); + } + removeConfiguration(component.getComponentName()); + } + } + + protected static Element serializeComponent(BaseComponent component) { + try { + Element node = null; + + if (component instanceof JDOMExternalizable) { + Element element = new Element("component"); + + element.setAttribute("name", component.getComponentName()); + + try { + ((JDOMExternalizable)component).writeExternal(element); + node = element; + } +// catch (JDOMException exception) { +// LOG.error(exception); +// } + catch (WriteExternalException ex) { + } + } + + return node; + } + catch (Throwable e) { // Request #12351 + LOG.error(e); + return null; + } + } + + protected final BaseComponent instantiateComponent(Class componentClass) { + return (BaseComponent)getPicoContainer().getComponentInstance(componentClass); + } + + protected abstract Element getDefaults(BaseComponent component) throws IOException, JDOMException, InvalidDataException; + + protected abstract ComponentManagerImpl getParentComponentManager(); + + + public MutablePicoContainer getPicoContainer() { + if (myPicoContainer == null) { + if (getParentComponentManager() != null) { + myPicoContainer = new DefaultPicoContainer(new MyComponentAdapterFactory(), getParentComponentManager().getPicoContainer()); + } + else { + myPicoContainer = new DefaultPicoContainer(new MyComponentAdapterFactory()); + } + } + return myPicoContainer; + } + + protected static class InvalidComponentDataException extends RuntimeException { + public InvalidComponentDataException(InvalidDataException exception) { + super(exception); + } + } + + protected void clearDomMap() { + myNameToConfiguration = new HashMap(); + } + + protected synchronized void addConfiguration(String componentName, Element configuration) { + myNameToConfiguration.put(componentName, configuration); + } + + protected synchronized Set getConfigurationNames() { + return myNameToConfiguration.keySet(); + } + + protected synchronized Element getConfiguration(String name) { + if (myNameToConfiguration == null) return null; + + return myNameToConfiguration.get(name); + } + + protected synchronized void removeConfiguration(String name) { + myNameToConfiguration.remove(name); + } + + public BaseComponent getComponent(String name) { + return myNameToComponent.get(name); + } + + protected Map getComponentOptions(Class componentInterfaceClass) { + return myInterfaceToOptionsMap.get(componentInterfaceClass); + } + + public void loadComponentsConfiguration(String layer) { + loadComponentsConfiguration(ApplicationManagerEx.getApplicationEx().getComponentsDescriptor(), layer); + } + + private void loadComponentsConfiguration(String descriptor, String layer) { + loadComponentsConfiguration(descriptor, layer, new ArrayList()); + } + + private void loadComponentsConfiguration(String descriptor, String layer, ArrayList loadedIncludes) { + try { + Element root = ourDescriptorToRootMap.get(descriptor); + if (root == null) { + InputStream inputStream = DecodeDefaultsUtil.getDefaultsInputStream(this, descriptor); + LOG.assertTrue(inputStream != null, "Defaults not found:" + descriptor); + final Document document = JDOMUtil.loadDocument(inputStream); + inputStream.close(); + + root = document.getRootElement(); + ourDescriptorToRootMap.put(descriptor, root); + } + + List includes = root.getChildren("include"); + if (includes != null) { + for (Iterator iterator = includes.iterator(); iterator.hasNext();) { + Element includeElement = (Element)iterator.next(); + String includeName = includeElement.getAttributeValue("name"); + + if (includeName != null && !loadedIncludes.contains(includeName)) { + loadedIncludes.add(includeName); + loadComponentsConfiguration(includeName, layer, loadedIncludes); + } + } + } + + loadComponentsConfiguration(root.getChild(layer)); + } + catch (Exception e) { + LOG.error(e); + } + } + + public void loadComponentsConfiguration(final Element element) { + loadComponentsConfiguration(element, null); + } + + public void loadComponentsConfiguration(final Element element, PluginDescriptor descriptor) { + if (element == null) return; + + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + try { + Element child = (Element)i.next(); + if ("component".equals(child.getName())) { + String interfaceClass = child.getChildText("interface-class"); + String implClass = child.getChildText("implementation-class"); + + if (interfaceClass == null) interfaceClass = implClass; + + Map options = null; + + final List optionElements = child.getChildren("option"); + if (optionElements.size() != 0) { + options = new HashMap(); + for (Iterator j = optionElements.iterator(); j.hasNext();) { + Element e = (Element)j.next(); + String name = e.getAttributeValue("name"); + String value = e.getAttributeValue("value"); + options.put(name, value); + } + } + + if (!isComponentSuitable(options)) continue; + + ClassLoader loader = null; + if (descriptor != null) { + loader = descriptor.getLoader(); + } + if (loader == null) { + loader = getClass().getClassLoader(); + } + registerComponent(Class.forName(interfaceClass, true, loader), Class.forName(implClass, true, loader), options, true, + isTrue(options, "lazy")); + } + } + catch (Exception e) { + if (descriptor != null) { + LOG.error(new PluginException(e, descriptor)); + } + else { + LOG.error(e); + } + } + catch (Error e) { + if (descriptor != null) { + LOG.error(new PluginException(e, descriptor)); + } + else { + throw e; + } + } + } + } + + protected boolean isComponentSuitable(Map options) { + return !isTrue(options, "internal") || ApplicationManagerEx.getApplicationEx().isInternal(); + } + + private boolean isTrue(Map options, final String option) { + return options != null && options.containsKey(option) && "true".equals(options.get(option)); + } + + protected void saveSettingsSavingComponents() { + Object[] components = getComponents(SettingsSavingComponent.class); + for (int i = 0; i < components.length; i++) { + Object component = components[i]; + if (component instanceof SettingsSavingComponent) { + ((SettingsSavingComponent)component).save(); + } + } + } + + private class MyComponentAdapterFactory implements ComponentAdapterFactory { + public ComponentAdapter createComponentAdapter(final Object componentKey, Class componentImplementation, Parameter[] parameters) + throws PicoIntrospectionException, + AssignabilityRegistrationException, + NotConcreteRegistrationException { + + DecoratingComponentAdapter initializingAdapter = new DecoratingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters, true)) { + public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException { + Object componentInstance = super.getComponentInstance(picoContainer); + initComponent((BaseComponent)componentInstance, (Class)componentKey); + return componentInstance; + } + }; + + return new CachingComponentAdapter(initializingAdapter); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/BaseDiffAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/BaseDiffAction.java new file mode 100644 index 00000000000..c3d3a96ff7d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/BaseDiffAction.java @@ -0,0 +1,94 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.ide.macro.DataAccessor; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.impl.external.DiffManagerImpl; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.containers.Convertor; + +abstract class BaseDiffAction extends AnAction { + protected static final Convertor SOURCE_ELEMENT = new Convertor() { + public PsiElement convert(PsiElement psiElement) { + if (psiElement == null || !psiElement.isValid()) return null; + PsiElement navigationElement = psiElement.getNavigationElement(); + if (navigationElement != null) psiElement = navigationElement; + PsiElement parent = psiElement.getParent(); + if (parent instanceof PsiFile) psiElement = parent; + return psiElement.getNavigationElement(); + } + }; + + protected static final DataAccessor PRIMARY_SOURCES = + DataAccessor.createArrayConvertor(DataAccessor.PSI_ELEMENT_ARRAY, SOURCE_ELEMENT, PsiElement.class); + + protected static final DataAccessor PRIMARY_SOURCE = + DataAccessor.createConvertor(PRIMARY_SOURCES, new Convertor() { + public PsiElement convert(PsiElement[] psiElements) { + return psiElements.length == 1 ? psiElements[0] : null; + } + }); + + public void actionPerformed(AnActionEvent e) { + DiffRequest diffData; + try { + diffData = getDiffData(e.getDataContext()); + } + catch (DataAccessor.NoDataException e1) { + diffData = null; + } + if (diffData == null) return; + final DiffContent[] contents = diffData.getContents(); + final FileDocumentManager documentManager = FileDocumentManager.getInstance(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + if (content.getFile() != null) documentManager.saveDocument(content.getDocument()); + } + } + }); + DiffManager.getInstance().getDiffTool().show(diffData); + } + + public void update(AnActionEvent e) { + DiffRequest diffData; + try { + diffData = getDiffData(e.getDataContext()); + } + catch (DataAccessor.NoDataException e1) { + diffData = null; + } + boolean enabled; + if (diffData == null || diffData.getContents() == null) enabled = false; + else enabled = DiffManager.getInstance().getDiffTool().canShow(diffData); + Presentation presentation = e.getPresentation(); + presentation.setEnabled(enabled); + if (enabled) presentation.setVisible(true); + else disableAction(presentation); + } + + protected void disableAction(Presentation presentation) {} + + protected abstract DiffRequest getDiffData(DataContext dataContext) throws DataAccessor.NoDataException; + + protected static VirtualFile getDocumentFile(Document document) { + return FileDocumentManager.getInstance().getFile(document); + } + + protected static String getContentTitle(Document document) { + VirtualFile editorFile = getDocumentFile(document); + if (editorFile == null || !editorFile.isValid()) return "Editor"; + return editorFile.getPresentableUrl(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java new file mode 100644 index 00000000000..b991ea869aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java @@ -0,0 +1,77 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; + +public class CompareClipboardWithSelection extends BaseDiffAction { + + protected DiffRequest getDiffData(DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) return null; + Object editorData = dataContext.getData(DataConstants.EDITOR); + Editor editor = editorData != null ? + (Editor)editorData : + FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) return null; + if (!editor.getSelectionModel().hasSelection()) return null; + return new ClipboardSelectionContents(editor, project); + } + + private static class ClipboardSelectionContents extends DiffRequest { + private DiffContent[] myContents = null; + private final Editor myEditor; + + public ClipboardSelectionContents(Editor editor, Project project) { + super(project); + myEditor = editor; + } + + public String[] getContentTitles() { + return new String[]{"Clipboard", "Selection from " + getContentTitle(getDocument())}; + } + + public DiffContent[] getContents() { + if (myContents != null) return myContents; + DiffContent clipboardContent = createClipboardContent(); + if (clipboardContent == null) return null; + myContents = new DiffContent[2]; + myContents[0] = clipboardContent; + + SelectionModel selectionModel = myEditor.getSelectionModel(); + TextRange range = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); + myContents[1] = new FragmentContent(DocumentContent.fromDocument(getProject(), getDocument()), + range, getProject(), getDocumentFile(getDocument())); + return myContents; + } + + private Document getDocument() { + return myEditor.getDocument(); + } + + public String getWindowTitle() { + return "Clipboard vs " + getContentTitle(getDocument()); + } + + private DiffContent createClipboardContent() { + Transferable content = CopyPasteManager.getInstance().getContents(); + String text; + try { + text = (String) (content.getTransferData(DataFlavor.stringFlavor)); + } catch (Exception e) { + return null; + } + return text != null ? new SimpleContent(text) : null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFileWithEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFileWithEditor.java new file mode 100644 index 00000000000..fac325c5648 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFileWithEditor.java @@ -0,0 +1,110 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.ide.macro.DataAccessor; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffContentUtil; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DocumentContent; +import com.intellij.openapi.diff.ex.DiffContentFactory; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.text.ElementPresentation; + +public class CompareFileWithEditor extends BaseDiffAction { + private static final DataAccessor EDITING_DOCUMENT = new DataAccessor() { + public Document getImpl(DataContext dataContext) throws NoDataException { + VirtualFile[] selectedFiles = FILE_EDITOR_MANAGER.getNotNull(dataContext).getSelectedFiles(); + if (selectedFiles.length == 0) return null; + if (!DiffContentUtil.isTextFile(selectedFiles[0])) return null; + return FileDocumentManager.getInstance().getDocument(selectedFiles[0]); + } + }; + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + FileEditorContents diffData; + try { + diffData = getDiffData(e.getDataContext()); + } + catch (DataAccessor.NoDataException e1) { + presentation.setText("Compare with Editor"); + presentation.setEnabled(false); + return; + } + String singular = diffData.getElementPresentation().getKind().getSingular(true); + presentation.setText("Compare " + singular + " with Editor"); + presentation.setEnabled(true); + } + + protected FileEditorContents getDiffData(DataContext dataContext) throws DataAccessor.NoDataException { + if (!checkSelection(dataContext)) throw new DataAccessor.NoDataException("Wrong selection"); + Project project = DataAccessor.PROJECT.getNotNull(dataContext); + PsiElement element = PRIMARY_SOURCE.getNotNull(dataContext); + PsiFile psiFile = element.getContainingFile(); + if (psiFile != null) element = psiFile; + Document document = EDITING_DOCUMENT.getNotNull(dataContext); + if (isSameFile(document, element)) throw new DataAccessor.NoDataException("Same file"); + DiffContent diffContent = DiffContentFactory.fromPsiElement(element); + if (diffContent == null || diffContent.getDocument() == null) + throw new DataAccessor.NoDataException("No content"); + return new FileEditorContents(document, element, project); + } + + private boolean isSameFile(Document document, PsiElement element) { + VirtualFile documentFile = FileDocumentManager.getInstance().getFile(document); + PsiFile elementPsiFile = element.getContainingFile(); + VirtualFile elementFile = elementPsiFile != null ? elementPsiFile.getVirtualFile() : null; + + if (documentFile != null && documentFile.isValid() && + documentFile.equals(elementFile)) return true; + return false; + } + + private boolean checkSelection(DataContext dataContext) { + VirtualFile[] virtualFiles = DataAccessor.VIRTUAL_FILE_ARRAY.from(dataContext); + if (virtualFiles != null && virtualFiles.length != 1) return false; + PsiElement[] psiElements = DataAccessor.PSI_ELEMENT_ARRAY.from(dataContext); + if (psiElements != null && psiElements.length != 1) return false; + return true; + } + + protected void disableAction(Presentation presentation) { + presentation.setVisible(false); + } + + private static class FileEditorContents extends DiffRequest { + private final PsiElement myPsiElement; + private final Document myDocument; + + public FileEditorContents(Document document, PsiElement psiElement, Project project) { + super(project); + myDocument = document; + myPsiElement = psiElement; + } + + public String[] getContentTitles() { + VirtualFile documentFile = getDocumentFile(myDocument); + String documentTitle = documentFile != null ? ElementPresentation.forVirtualFile(documentFile).getNameWithFQComment() : "Editor"; + return new String[]{getElementPresentation().getNameWithFQComment(), documentTitle}; + } + + protected ElementPresentation getElementPresentation() { + return ElementPresentation.forElement(myPsiElement); + } + + public DiffContent[] getContents() { + return new DiffContent[]{DiffContentFactory.fromPsiElement(myPsiElement), DocumentContent.fromDocument(getProject(), myDocument)}; + } + + public String getWindowTitle() { + return getElementPresentation().getQualifiedName() + " vs " + getContentTitle(myDocument); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFiles.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFiles.java new file mode 100644 index 00000000000..9aeaa0c2c3a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/CompareFiles.java @@ -0,0 +1,78 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.ide.macro.DataAccessor; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.SimpleDiffRequest; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.ex.DiffContentFactory; +import com.intellij.openapi.diff.impl.external.DiffManagerImpl; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.text.ElementPresentation; + +public class CompareFiles extends BaseDiffAction { + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + PsiElement[] elements; + try { + elements = ELEMENTS_TO_COMPARE.getNotNull(e.getDataContext()); + } + catch (DataAccessor.NoDataException e1) { + presentation.setVisible(false); + return; + } + DiffRequest diffRequest = getDiffRequest(elements); + if (diffRequest == null) { + presentation.setVisible(false); + return; + } + ElementPresentation presentation1 = ElementPresentation.forElement(elements[0]); + ElementPresentation presentation2 = ElementPresentation.forElement(elements[1]); + ElementPresentation.Noun firstKind = presentation1.getKind(); + ElementPresentation.Noun secondKind = presentation2.getKind(); + if (firstKind.equals(secondKind)) { + presentation.setText("Co_mpare Two " + firstKind.getPlural(true)); + } else presentation.setText("Co_mpare " + firstKind.getSingular(true) + " with " + secondKind.getSingular(true)); + presentation.setVisible(true); + presentation.setEnabled(DiffManager.getInstance().getDiffTool().canShow(diffRequest)); + } + + protected DiffRequest getDiffData(DataContext dataContext) throws DataAccessor.NoDataException { + return getDiffRequest(ELEMENTS_TO_COMPARE.getNotNull(dataContext)); + } + + private DiffRequest getDiffRequest(PsiElement[] elements) { + ElementPresentation presentation1 = ElementPresentation.forElement(elements[0]); + ElementPresentation presentation2 = ElementPresentation.forElement(elements[1]); + String title = presentation1.getQualifiedName() + " vs " + presentation2.getQualifiedName(); + SimpleDiffRequest diffRequest = DiffContentFactory.comparePsiElements(elements[0], elements[1], title); + if (diffRequest == null) return null; + diffRequest.setContentTitles(presentation1.getNameWithFQComment(), presentation2.getNameWithFQComment()); + return diffRequest; + } + + private static final DataAccessor SECONDARY_SOURCE = + DataAccessor.createConvertor(new DataAccessor() { + public PsiElement getImpl(DataContext dataContext) { + return (PsiElement)dataContext.getData(DataConstantsEx.SECONDARY_PSI_ELEMENT); + } + }, SOURCE_ELEMENT); + + private static final DataAccessor ELEMENTS_TO_COMPARE = new DataAccessor() { + public PsiElement[] getImpl(DataContext dataContext) throws NoDataException { + PsiElement[] primaryElements = PRIMARY_SOURCES.from(dataContext); + if (primaryElements != null && primaryElements.length == 2) + return primaryElements; + PsiElement secondaryElement = SECONDARY_SOURCE.getNotNull(dataContext); + PsiElement primaryElement = PRIMARY_SOURCE.getNotNull(dataContext); + if (primaryElement == secondaryElement || + PsiTreeUtil.isAncestor(primaryElement, secondaryElement, false) || + PsiTreeUtil.isAncestor(secondaryElement, primaryElement, false)) return null; + return new PsiElement[]{primaryElement, secondaryElement}; + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffActions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffActions.java new file mode 100644 index 00000000000..75eed9ae32c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffActions.java @@ -0,0 +1,8 @@ +package com.intellij.openapi.diff.actions; + +/** + * @author dyoma + */ +public interface DiffActions { + String COMPARE_WITH_CLIPBOARD = "CompareClipboardWithSelection"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffWalkerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffWalkerAction.java new file mode 100644 index 00000000000..6a505df83d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/DiffWalkerAction.java @@ -0,0 +1,34 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.util.FocusDiffSide; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; + +abstract class DiffWalkerAction extends AnAction { + public void actionPerformed(AnActionEvent event) { + FocusDiffSide side = DiffUtil.getFocusDiffSide(event.getDataContext()); + if (side == null) return; + int line = getLineNumberToGo(side); + Editor editor = side.getEditor(); + if (line >= 0 && editor != null) { + LogicalPosition pos = new LogicalPosition(line, 0); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + } + + public void update(AnActionEvent event) { + FocusDiffSide side = DiffUtil.getFocusDiffSide(event.getDataContext()); + Presentation presentation = event.getPresentation(); + if (side == null) { + presentation.setEnabled(false); + } else presentation.setEnabled(getLineNumberToGo(side) >= 0); + } + + protected abstract int getLineNumberToGo(FocusDiffSide side); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java new file mode 100644 index 00000000000..dd168cef34f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.diff.ex.DiffPanelEx; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.util.Map; + +public class IgnoreWhiteSpacesAction extends ComboBoxAction { + private final Map myActions = new HashMap(); + private static final ComparisonPolicy[] ourActionOrder = new ComparisonPolicy[]{ + ComparisonPolicy.DEFAULT, + ComparisonPolicy.TRIM_SPACE, + ComparisonPolicy.IGNORE_SPACE}; + private final DiffPanelEx myDiffPanel; + + public IgnoreWhiteSpacesAction(DiffPanelEx diffPanel) { + myActions.put(ComparisonPolicy.DEFAULT, new IgnoringPolicyAction("Do not ignore", ComparisonPolicy.DEFAULT)); + myActions.put(ComparisonPolicy.TRIM_SPACE, new IgnoringPolicyAction("Leading and trailing", ComparisonPolicy.TRIM_SPACE)); + myActions.put(ComparisonPolicy.IGNORE_SPACE, new IgnoringPolicyAction("All", ComparisonPolicy.IGNORE_SPACE)); + myDiffPanel = diffPanel; + } + + protected DefaultActionGroup createPopupActionGroup(JComponent button) { + DefaultActionGroup actionGroup = new DefaultActionGroup(); + for (int i = 0; i < ourActionOrder.length; i++) { + ComparisonPolicy comparisonPolicy = ourActionOrder[i]; + actionGroup.add(myActions.get(comparisonPolicy)); + } + return actionGroup; + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + DiffPanelEx diffPanel = myDiffPanel; + if (diffPanel != null && diffPanel.getComponent().isDisplayable()) { + AnAction actoin = myActions.get(diffPanel.getComparisonPolicy()); + Presentation templatePresentation = actoin.getTemplatePresentation(); + presentation.setIcon(templatePresentation.getIcon()); + presentation.setText(templatePresentation.getText()); + presentation.setEnabled(true); + } else { + presentation.setIcon(null); + presentation.setText(""); + presentation.setEnabled(false); + } + } + + private class IgnoringPolicyAction extends AnAction { + private final ComparisonPolicy myPolicy; + + public IgnoringPolicyAction(String text, ComparisonPolicy policy) { + super(text); + myPolicy = policy; + } + + public void actionPerformed(AnActionEvent e) { + myDiffPanel.setComparisonPolicy(myPolicy); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeActionGroup.java new file mode 100644 index 00000000000..2106ab9388d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeActionGroup.java @@ -0,0 +1,56 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; + +public class MergeActionGroup extends ActionGroup { + private final MergeOperations myOperations; + + public MergeActionGroup(DiffPanelImpl diffPanel, FragmentSide side) { + myOperations = new MergeOperations(diffPanel, side); + } + + public AnAction[] getChildren(AnActionEvent e) { + ArrayList operations = myOperations.getOperations(); + AnAction[] actions = new AnAction[operations.size() + 2]; + actions[0] = new SelectSuggestionAction(myOperations); + actions[1] = Separator.getInstance(); + for (int i = 2; i < actions.length; i++) + actions[i] = new OperationAction(operations.get(i - 2)); + return actions; + } + + private static class SelectSuggestionAction extends AnAction { + private final MergeOperations myOperations; + + public SelectSuggestionAction(MergeOperations operations) { + super("Select Change", "Select changed text in this version and corresponding in other", null); + myOperations = operations; + } + + public void actionPerformed(AnActionEvent e) { + myOperations.selectSuggestion(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myOperations.getCurrentFragment() != null); + } + } + + public static class OperationAction extends AnAction { + private final MergeOperations.Operation myOperation; + + public OperationAction(MergeOperations.Operation operation) { + super(operation.getName(), null, operation.getGlutterIcon()); + myOperation = operation; + } + + public void actionPerformed(AnActionEvent e) { + myOperation.perform((Project) e.getDataContext().getData(DataConstants.PROJECT)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeFilesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeFilesAction.java new file mode 100644 index 00000000000..f4256ae525a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeFilesAction.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.DiffRequestFactory; +import com.intellij.openapi.diff.MergeRequest; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.peer.PeerFactory; + +import java.io.IOException; + +public class MergeFilesAction extends AnAction{ + public void update(AnActionEvent e) { + DataContext context = e.getDataContext(); + Project project = (Project)context.getData(DataConstants.PROJECT); + if (project == null){ + e.getPresentation().setEnabled(false); + return; + } + VirtualFile[] files = (VirtualFile[])context.getData(DataConstants.VIRTUAL_FILE_ARRAY); + if (files == null || files.length != 3){ + e.getPresentation().setEnabled(false); + } + } + + public void actionPerformed(AnActionEvent e) { + DataContext context = e.getDataContext(); + VirtualFile[] files = (VirtualFile[])context.getData(DataConstants.VIRTUAL_FILE_ARRAY); + if (files == null || files.length != 3){ + return; + } + + DiffRequestFactory diffRequestFactory = PeerFactory.getInstance().getDiffRequestFactory(); + + VirtualFile file = files[1]; + try { + String originalText = createValidContent(new String(file.contentsToCharArray())); + String leftText = new String(files[0].contentsToCharArray()); + String rightText = new String(files[2].contentsToCharArray()); + + Project project = (Project)context.getData(DataConstants.PROJECT); + final MergeRequest diffData = diffRequestFactory.createMergeRequest(leftText, rightText, originalText, file, project); + diffData.setVersionTitles(new String[]{files[0].getPresentableUrl(), + files[1].getPresentableUrl(), + files[2].getPresentableUrl()}); + diffData.setWindowTitle("Merge"); + diffData.setHelpId("cvs.merge"); + DiffManager.getInstance().getDiffTool().show(diffData); + } + catch (IOException e1) { + Messages.showErrorDialog("Cannot load file: " + e1.getLocalizedMessage(), "Merge"); + } + } + private String createValidContent(String str) { + String[] strings = LineTokenizer.tokenize(str.toCharArray(), false, false); + StringBuffer result = new StringBuffer(); + for (int i = 0; i < strings.length; i++) { + String string = strings[i]; + if (i != 0) result.append('\n'); + result.append(string); + } + return result.toString(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeOperations.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeOperations.java new file mode 100644 index 00000000000..f65afb5c362 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/MergeOperations.java @@ -0,0 +1,177 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.fragments.Fragment; +import com.intellij.openapi.diff.impl.fragments.FragmentList; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.GutterActionRenderer; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; + +public class MergeOperations { + private final DiffPanelImpl myDiffPanel; + private final FragmentSide mySide; + private static final ArrayList NO_OPERATIONS = new ArrayList(0); + private static final Condition NOT_EQUAL_FRAGMENT = new Condition() { + public boolean value(Fragment fragment) { + return fragment.getType() != null; + } + }; + + public MergeOperations(DiffPanelImpl diffPanel, FragmentSide side) { + myDiffPanel = diffPanel; + mySide = side; + } + + public ArrayList getOperations() { + Fragment fragment = getCurrentFragment(); + if (fragment == null) return NO_OPERATIONS; + ArrayList operations = new ArrayList(3); + TextRange range = fragment.getRange(mySide); + if (range.getLength() > 0) { + if (isWritable(mySide)) operations.add(removeOperation(range, getDocument())); + TextRange otherRange = fragment.getRange(mySide.otherSide()); + boolean otherIsWritable = isWritable(mySide.otherSide()); + if (otherIsWritable) operations.add(insertOperation(range, otherRange.getEndOffset(), getDocument(), getOtherDocument())); + if (otherRange.getLength() > 0 && otherIsWritable) operations.add(replaceOperation(range, otherRange, getDocument(), getOtherDocument())); + } + return operations; + } + + private boolean isWritable(FragmentSide side) { + Editor editor = myDiffPanel.getEditor(side); + return !editor.isViewer() && editor.getDocument().isWritable(); + } + + public void selectSuggestion() { + Fragment fragment = getCurrentFragment(); + if (fragment == null) return; + setSelection(fragment, mySide); + setSelection(fragment, mySide.otherSide()); + } + + private void setSelection(Fragment fragment, FragmentSide side) { + TextRange range = fragment.getRange(side); + if (range.getLength() > 0) + myDiffPanel.getEditor(side).getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + } + + private static Operation replaceOperation(TextRange range, TextRange otherRange, Document document, Document otherDocument) { + Operation operation = new Operation("Replace", GutterActionRenderer.REPLACE_ARROW); + operation.addModification(replaceModification(range, document, otherRange, otherDocument)); + return operation; + } + + public static Operation mostSensible(Document document, Document otherDocument, TextRange range, TextRange otherRange) { + if (!document.isWritable() && !otherDocument.isWritable()) return null; + if (range.getLength() != 0) { + if (otherDocument.isWritable()) + return otherRange.getLength() != 0 ? + replaceOperation(range, otherRange, document, otherDocument) : + insertOperation(range, otherRange.getEndOffset(), document, otherDocument); + else return otherRange.getLength() == 0 ? removeOperation(range, document) : null; + } + return null; + } + + private static Runnable replaceModification(TextRange range, Document document, + final TextRange otherRange, final Document otherDocument) { + final String replacement = getSubstring(document, range); + return new Runnable() { + public void run() { + otherDocument.replaceString(otherRange.getStartOffset(), otherRange.getEndOffset(), replacement); + } + }; + } + + private static Operation insertOperation(TextRange range, int offset, Document document, Document otherDocument) { + Operation operation = new Operation("Insert", GutterActionRenderer.REPLACE_ARROW); + operation.addModification(insertModification(range, document, offset, otherDocument)); + return operation; + } + + private static Runnable insertModification(TextRange range, Document document, + final int offset, final Document otherDocument) { + final String insertion = getSubstring(document, range); + return new Runnable(){ + public void run() { + otherDocument.insertString(offset, insertion); + } + }; + } + + private static String getSubstring(Document document, TextRange range) { + return document.getText().substring(range.getStartOffset(), range.getEndOffset()); + } + + private Document getOtherDocument() { + return myDiffPanel.getEditor(mySide.otherSide()).getDocument(); + } + + private static Operation removeOperation(TextRange range, Document document) { + Operation operation = new Operation("Remove", GutterActionRenderer.REMOVE_CROSS); + operation.addModification(removeModification(range, document)); + return operation; + } + + private static Runnable removeModification(final TextRange range, final Document document) { + return new Runnable(){ + public void run() { + document.deleteString(range.getStartOffset(), range.getEndOffset()); + } + }; + } + + private Document getDocument() { + return myDiffPanel.getEditor(mySide).getDocument(); + } + + public Fragment getCurrentFragment() { + FragmentList fragments = myDiffPanel.getFragments(); + int caretPosition = myDiffPanel.getEditor(mySide).getCaretModel().getOffset(); + return fragments.getFragmentAt(caretPosition, mySide, NOT_EQUAL_FRAGMENT); + } + + public static class Operation { + private final String myName; + private final ArrayList myModifications = new ArrayList(); + private final Icon myGlutterIcon; + + public Operation(String name, Icon icon) { + myName = name; + myGlutterIcon = icon; + } + + public Icon getGlutterIcon() { + return myGlutterIcon; + } + + public String getName() { + return myName; + } + + private void addModification(Runnable modification) { + myModifications.add(modification); + } + + public void perform(final Project project) { + for (Iterator iterator = myModifications.iterator(); iterator.hasNext();) { + final Runnable modification = iterator.next(); + ApplicationManager.getApplication().runWriteAction(new Runnable(){ + public void run() { + CommandProcessor.getInstance().executeCommand(project, modification, getName(), null); + } + }); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/NextDiffAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/NextDiffAction.java new file mode 100644 index 00000000000..b28ee57f714 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/NextDiffAction.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.diff.impl.util.FocusDiffSide; +import com.intellij.openapi.editor.Editor; + +public class NextDiffAction extends DiffWalkerAction { + public static AnAction find() { + return ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_DIFF); + } + + protected int getLineNumberToGo(FocusDiffSide side) { + if (side == null) return -1; + Editor editor = side.getEditor(); + if (editor == null) return -1; + int gotoLine = -1; + int[] fragmentBeginnings = side.getFragmentStartingLines(); + if (fragmentBeginnings == null) return -1; + for (int i = fragmentBeginnings.length - 1; i >= 0; i--) { + int line = fragmentBeginnings[i]; + if (line > editor.getCaretModel().getLogicalPosition().line) { + gotoLine = line; + } + } + return gotoLine; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/PreviousDiffAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/PreviousDiffAction.java new file mode 100644 index 00000000000..3afc3d39171 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/actions/PreviousDiffAction.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.diff.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.diff.impl.util.FocusDiffSide; +import com.intellij.openapi.editor.Editor; + +public class PreviousDiffAction extends DiffWalkerAction { + public static AnAction find() { + return ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_DIFF); + } + + protected int getLineNumberToGo(FocusDiffSide side) { + if (side == null) return -1; + Editor editor = side.getEditor(); + if (editor == null) return -1; + int[] fragmentBeginnings = side.getFragmentStartingLines(); + int gotoLine = -1; + if (fragmentBeginnings == null) return -1; + for (int i = 0; i < fragmentBeginnings.length; i++) { + int line = fragmentBeginnings[i]; + if (line < editor.getCaretModel().getLogicalPosition().line) { + gotoLine = line; + } + } + return gotoLine; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffContentFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffContentFactory.java new file mode 100644 index 00000000000..c6d28de758e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffContentFactory.java @@ -0,0 +1,46 @@ +package com.intellij.openapi.diff.ex; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.FragmentContent; +import com.intellij.openapi.diff.SimpleContent; +import com.intellij.openapi.diff.SimpleDiffRequest; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +public class DiffContentFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.ex.DiffContentFactory"); + + private DiffContentFactory() {} + + public static DiffContent fromPsiElement(PsiElement psiElement) { + if (psiElement instanceof PsiFile) { + return DiffContent.fromFile(psiElement.getProject(), ((PsiFile)psiElement).getVirtualFile()); + } else if (psiElement instanceof PsiDirectory) { + return DiffContent.fromFile(psiElement.getProject(), ((PsiDirectory)psiElement).getVirtualFile()); + } + PsiFile containingFile = psiElement.getContainingFile(); + if (containingFile == null) { + String text = psiElement.getText(); + return text != null ? new SimpleContent(text) : null; + } + DiffContent wholeFileContent = DiffContent.fromFile(psiElement.getProject(), containingFile.getVirtualFile()); + if (wholeFileContent == null) return null; + Project project = psiElement.getProject(); + return new FragmentContent(wholeFileContent, psiElement.getTextRange(), project); + } + + public static SimpleDiffRequest comparePsiElements(PsiElement psiElement1, PsiElement psiElement2, String title) { + if (!psiElement1.isValid() || !psiElement2.isValid()) return null; + Project project = psiElement1.getProject(); + LOG.assertTrue(project == psiElement2.getProject()); + DiffContent content1 = fromPsiElement(psiElement1); + DiffContent content2 = fromPsiElement(psiElement2); + if (content1 == null || content2 == null) return null; + SimpleDiffRequest diffRequest = new SimpleDiffRequest(project, title); + diffRequest.setContents(content1, content2); + return diffRequest; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffFragment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffFragment.java new file mode 100644 index 00000000000..504b3060ce6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffFragment.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.diff.ex; + +public class DiffFragment { + private final String myText1; + private final String myText2; + private boolean myIsModified; + + public DiffFragment(String text1, String text2) { + myText1 = text1; + myText2 = text2; + myIsModified = (text1 == null || text2 == null || !text1.equals(text2)); + } + + /** + * Makes sence if both texts are not null + * @return true if both texts are considered modified, false otherwise + */ + public boolean isModified() { + return myIsModified; + } + + public void setModified(boolean modified) { + myIsModified = modified; + } + + /** + * null if absent + */ + public String getText1() { + return myText1; + } + + /** + * null if absent + */ + public String getText2() { + return myText2; + } + + /** + * Same as {@link #isModified()}, but doesn't require texts checked for null. + * @return true iff both texts are present and {@link #isModified()} + */ + public boolean isChange() { + return myText1 != null && myText2 != null && isModified(); + } + + /** + * @return true iff both texts are present and not {@link #isModified()} + */ + public boolean isEqual() { + return myText1 != null && myText2 != null && !isModified(); + } + + public static DiffFragment unchanged(String text1, String text2) { + DiffFragment result = new DiffFragment(text1, text2); + result.setModified(false); + return result; + } + + public boolean isOneSide() { + return myText1 == null || myText2 == null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelEx.java new file mode 100644 index 00000000000..ab94a10a5b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelEx.java @@ -0,0 +1,25 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jul 31, 2002 + * Time: 3:02:52 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.diff.ex; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diff.DiffPanel; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.editor.Editor; + +public interface DiffPanelEx extends DiffPanel, Disposeable { + Editor getEditor1(); + Editor getEditor2(); + + DiffPanelOptions getOptions(); + + void setComparisonPolicy(ComparisonPolicy comparisonPolicy); + + ComparisonPolicy getComparisonPolicy(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelOptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelOptions.java new file mode 100644 index 00000000000..5ec1962fbbc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffPanelOptions.java @@ -0,0 +1,89 @@ +package com.intellij.openapi.diff.ex; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.DiffSideView; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.ui.DialogWrapperDialog; +import com.intellij.openapi.ui.DialogWrapper; + +import java.awt.*; + +/** + * @author dyoma + */ +public class DiffPanelOptions { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.ex.DiffPanelOptions"); + private final DiffPanelImpl myDiffPanel; + private boolean myRequestFocusOnNewContent = true; + private ShowSourcePolicy myShowSourcePolicy = ShowSourcePolicy.DEFAULT; + + public DiffPanelOptions(DiffPanelImpl diffPanel) { + myDiffPanel = diffPanel; + } + + public void onNewContent(DiffSideView currentSide) { + if (myRequestFocusOnNewContent) + currentSide.getFocusableComponent().requestFocus(); + } + + public void setRequestFocusOnNewContent(boolean requestFocusOnNewContent) { + myRequestFocusOnNewContent = requestFocusOnNewContent; + } + + public void setShowSourcePolicy(ShowSourcePolicy showSourcePolicy) { + if (showSourcePolicy == null) { + LOG.error(""); + return; + } + myShowSourcePolicy = showSourcePolicy; + } + + public void showSource(OpenFileDescriptor descriptor) { + myShowSourcePolicy.showSource(descriptor, myDiffPanel); + } + + public static interface ShowSourcePolicy { + void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel); + + ShowSourcePolicy DONT_SHOW = new ShowSourcePolicy() { + public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) {} + }; + + ShowSourcePolicy OPEN_EDITOR = new ShowSourcePolicy() { + public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) { + FileEditorManager.getInstance(diffPanel.getProject()).openTextEditor(descriptor, true); + } + }; + + ShowSourcePolicy OPEN_EDITOR_AND_CLOSE_DIFF = new ShowSourcePolicy() { + public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) { + OPEN_EDITOR.showSource(descriptor, diffPanel); + if (diffPanel.getOwnerWindow() == null) return; + diffPanel.dispose(); + + if (!dialogWrapperClose(diffPanel.getOwnerWindow())) { + diffPanel.getOwnerWindow().setVisible(false); + diffPanel.getOwnerWindow().dispose(); + } + } + + private boolean dialogWrapperClose(Window window) { + if (!(window instanceof DialogWrapperDialog)) return false; + DialogWrapperDialog dlg = (DialogWrapperDialog)window; + dlg.getDialogWrapper().close(DialogWrapper.OK_EXIT_CODE); + return true; + } + }; + + ShowSourcePolicy DEFAULT = new ShowSourcePolicy() { + public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) { + Window window = diffPanel.getOwnerWindow(); + if (window == null) return; + else if (window instanceof Frame) OPEN_EDITOR.showSource(descriptor, diffPanel); + else OPEN_EDITOR_AND_CLOSE_DIFF.showSource(descriptor, diffPanel); + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffStatusBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffStatusBar.java new file mode 100644 index 00000000000..6b50671fcb5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/ex/DiffStatusBar.java @@ -0,0 +1,115 @@ +package com.intellij.openapi.diff.ex; + +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.vcs.checkin.DifferenceType; +import com.intellij.openapi.vcs.checkin.ex.DifferenceTypeEx; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +/** + * @author Yura Cangea + */ +public class DiffStatusBar extends JPanel { + public static final java.util.List DEFAULT_TYPES = + Arrays.asList( + new LegendTypeDescriptor[]{ + (DifferenceTypeEx)DifferenceType.MODIFIED, + (DifferenceTypeEx)DifferenceType.INSERTED, + (DifferenceTypeEx)DifferenceType.DELETED}); + + private final Collection myLabels = new ArrayList(); + + private final JLabel myTextLabel = new JLabel("", JLabel.CENTER); + private static final int COMP_HEIGHT = 40; + private EditorColorsScheme myColorScheme = null; + + public DiffStatusBar(java.util.List types) { + for (Iterator iterator = types.iterator(); iterator.hasNext();) { + LegendTypeDescriptor differenceType = iterator.next(); + addDiffType(differenceType); + } + initGui(); + setBorder(BorderFactory.createLineBorder(Color.GRAY)); + } + + private void addDiffType(final LegendTypeDescriptor diffType){ + addComponent(diffType); + } + + private void addComponent(final LegendTypeDescriptor diffType) { + JComponent component = new JPanel() { + public void paint(Graphics g) { + setBackground(UIManager.getColor("TableHeader.background")); + super.paint(g); + FontMetrics metrics = getFontMetrics(getFont()); + + EditorColorsScheme colorScheme = myColorScheme != null + ? myColorScheme + : EditorColorsManager.getInstance().getGlobalScheme(); + g.setColor(diffType.getLegendColor(colorScheme)); + g.fill3DRect(10, (getHeight() - 10) / 2, 35, 10, true); + + Font font = g.getFont(); + if (font.getStyle() != Font.PLAIN) { + font = font.deriveFont(Font.PLAIN); + } + g.setFont(font); + g.setColor(UIManager.getColor("Label.foreground")); + int textBaseline = (getHeight() - metrics.getHeight()) / 2 + metrics.getAscent(); + g.drawString(diffType.getDisplayName(), 67, textBaseline); + } + }; + component.setMinimumSize(new Dimension(0, COMP_HEIGHT)); + component.setPreferredSize(new Dimension(0, COMP_HEIGHT)); + component.setSize(new Dimension(0, COMP_HEIGHT)); + myLabels.add(component); + } + + public Dimension getMinimumSize() { + Dimension p = super.getPreferredSize(); + Dimension m = super.getMinimumSize(); + return new Dimension(m.width, p.height); + } + + public Dimension getMaximumSize() { + Dimension p = super.getPreferredSize(); + Dimension m = super.getMaximumSize(); + return new Dimension(m.width, p.height); + } + + public void setText(String text) { + myTextLabel.setText(text); + } + + private void initGui() { + setLayout(new BorderLayout()); + Border emptyBorder = BorderFactory.createEmptyBorder(3, 2, 5, 2); + setBorder(emptyBorder); + + add(myTextLabel, BorderLayout.WEST); + JPanel panel = new JPanel(new GridLayout(1, myLabels.size(), 0, 0)); + for (Iterator each = myLabels.iterator(); each.hasNext();) { + panel.add((JComponent) each.next()); + } + + add(panel, BorderLayout.CENTER); + } + + public void setColorScheme(EditorColorsScheme colorScheme) { + EditorColorsScheme oldScheme = myColorScheme; + myColorScheme = colorScheme; + if (oldScheme != colorScheme) repaint(); + } + + public interface LegendTypeDescriptor { + String getDisplayName(); + Color getLegendColor(EditorColorsScheme colorScheme); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ComparisonPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ComparisonPolicy.java new file mode 100644 index 00000000000..a1cc4c80ba4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ComparisonPolicy.java @@ -0,0 +1,221 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.highlighting.Util; +import com.intellij.openapi.diff.impl.processing.DiffCorrection; +import com.intellij.openapi.diff.impl.processing.Formatting; +import com.intellij.openapi.diff.impl.processing.Word; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.diff.Diff; + +public abstract class ComparisonPolicy { + public DiffFragment[] buildFragments(String[] strings1, String[] strings2) { + DiffFragmentBuilder builder = new DiffFragmentBuilder(strings1, strings2); + Object[] wrappers1 = getWrappers(strings1); + Object[] wrappers2 = getWrappers(strings2); + Diff.Change change = Diff.buildChanges(wrappers1, wrappers2); + return DiffFragmentBuilder.buildFragments(builder, Util.concatEquals(change, wrappers1, wrappers2)); + } + + public DiffFragment[] buildDiffFragmentsFromLines(String[] lines1, String[] lines2) { + DiffFragmentBuilder builder = new DiffFragmentBuilder(lines1, lines2); + Object[] wrappers1 = getLineWrappers(lines1); + Object[] wrappers2 = getLineWrappers(lines2); + Diff.Change change = Diff.buildChanges(wrappers1, wrappers2); + return DiffFragmentBuilder.buildFragments(builder, change); + } + + public static final ComparisonPolicy DEFAULT = new ComparisonPolicy() { + protected Object[] getWrappers(String[] strings) { + return strings; + } + + protected Object[] getLineWrappers(String[] lines) { + return lines; + } + + public DiffFragment createFragment(Word word1, Word word2) { + return createFragment(word1.getText(), word2.getText()); + } + + public String toString() { + return "DEFAULT"; + } + }; + + public static final ComparisonPolicy TRIM_SPACE = new ComparisonPolicy() { + protected Object[] getLineWrappers(String[] lines) { + return trimStrings(lines); + } + + public DiffFragment createFragment(Word word1, Word word2) { + String text1 = word1.getText(); + String text2 = word2.getText(); + if (word1.isWhitespace() && word2.isWhitespace() && + word1.atEndOfLine() && word2.atEndOfLine()) + return DiffFragment.unchanged(text1, text2); + return createFragment(text1, text2); + } + + protected Object[] getWrappers(String[] strings) { + Object[] result = new Object[strings.length]; + boolean atBeginning = true; + for (int i = 0; i < strings.length; i++) { + String string = strings[i]; + String wrapper = atBeginning ? trimLeading(string) : string; + if (StringUtil.endsWithChar(wrapper, '\n')) { + atBeginning = true; + wrapper = trimTrailing(wrapper); + } + else { + atBeginning = false; + } + result[i] = wrapper; + } + return result; + } + + private String trimLeading(String string) { + int index = 0; + while (index < string.length() && Character.isWhitespace(string.charAt(index))) index++; + return string.substring(index); + } + + private String trimTrailing(String string) { + int index = string.length() - 1; + while (index >= 0 && Character.isWhitespace(string.charAt(index))) index--; + return string.substring(0, index + 1); + } + + public String toString() { + return "TRIM"; + } + }; + + public static final ComparisonPolicy IGNORE_SPACE = new IgnoreSpacePolicy(); + + private static String toNotNull(String text) { + return text == null ? "" : text; + } + + protected abstract Object[] getWrappers(String[] strings); + + protected abstract Object[] getLineWrappers(String[] lines); + + protected Object[] trimStrings(String[] strings) { + Object[] result = new Object[strings.length]; + for (int i = 0; i < strings.length; i++) { + String string = strings[i]; + result[i] = string.trim(); + } + return result; + } + + public DiffFragment createFragment(String text1, String text2) { + text1 = toNull(text1); + text2 = toNull(text2); + if (text1 == null && text2 == null) return new DiffFragment("", ""); + DiffFragment result = new DiffFragment(text1, text2); + if (text1 != null && text2 != null) { + result.setModified(!getWrapper(text1).equals(getWrapper(text2))); + } + return result; + } + + private String toNull(String text1) { + return text1 == null || text1.length() == 0 ? null : text1; + } + + private Object getWrapper(String text) { + return getWrappers(new String[]{text})[0]; + } + + public boolean isEqual(DiffFragment fragment) { + if (fragment.isOneSide()) return false; + Object[] wrappers = getLineWrappers(new String[]{fragment.getText1(), fragment.getText2()}); + return Comparing.equal(wrappers[0], wrappers[1]); + } + + public Word createFormatting(String text, TextRange textRange) { + return new Formatting(text, textRange); + } + + public abstract DiffFragment createFragment(Word word1, Word word2); + + private static class IgnoreSpacePolicy extends ComparisonPolicy implements DiffCorrection.FragmentProcessor { + protected Object[] getLineWrappers(String[] lines) { + Object[] result = new Object[lines.length]; + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + result[i] = getWrapper(line); + } + return result; + } + + public DiffFragment[] buildFragments(String[] strings1, String[] strings2) { + DiffFragment[] fragments = super.buildFragments(strings1, strings2); + DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector(); + collector.processAll(fragments, this); + return collector.toArray(); + } + + private Object getWrapper(String line) { + line = line.trim(); + char[] chars = new char[line.length()]; + line.getChars(0, line.length(), chars, 0); + char[] result = new char[chars.length]; + int resultLength = 0; + for (int i = 0; i < chars.length; i++) { + char aChar = chars[i]; + if (Character.isWhitespace(aChar)) continue; + result[resultLength] = aChar; + resultLength++; + } + return new String(result, 0, resultLength); + } + + public DiffFragment createFragment(Word word1, Word word2) { + String text1 = word1.getText(); + String text2 = word2.getText(); + return word1.isWhitespace() && word2.isWhitespace() ? + DiffFragment.unchanged(text1, text2) : + createFragment(text1, text2); + } + + public DiffFragment createFragment(String text1, String text2) { + String toCompare1 = toNotNull(text1); + String toCompare2 = toNotNull(text2); + if (getWrapper(toCompare1).equals(getWrapper(toCompare2))) + return DiffFragment.unchanged(toCompare1, toCompare2); + return new DiffFragment(text1, text2); + } + + protected Object[] getWrappers(String[] strings) { + return trimStrings(strings); + } + + public String toString() { + return "IGNORE"; + } + + public void process(DiffFragment fragment, DiffCorrection.FragmentsCollector collector) { + if (fragment.isEqual()) { + collector.add(fragment); + return; + } + if (fragment.isOneSide()) { + FragmentSide side = FragmentSide.chooseSide(fragment); + String text = side.getText(fragment); + String trimed = text.trim(); + if (trimed.length() == 0) { + collector.add(side.createFragment(text, "", false)); + return; + } + } + collector.add(fragment); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ContentChangeListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ContentChangeListener.java new file mode 100644 index 00000000000..ef0697b5636 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/ContentChangeListener.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.diff.impl; + + + +public interface ContentChangeListener { + void onContentChangedIn(EditorSource source); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/CurrentLineMarker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/CurrentLineMarker.java new file mode 100644 index 00000000000..5fd198cd164 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/CurrentLineMarker.java @@ -0,0 +1,58 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.RangeHighlighter; + +public class CurrentLineMarker implements CaretListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.CurrentLineMarker"); + private Editor myEditor; + private RangeHighlighter myHighlighter = null; + public static final int LAYER = HighlighterLayer.CARET_ROW + 1; + + public void attach(EditorSource editorSource) { + if (myEditor != null) hide(); + myEditor = editorSource.getEditor(); + if (myEditor == null) return; + final CaretModel caretModel = myEditor.getCaretModel(); + caretModel.addCaretListener(this); + editorSource.addDisposable(new Disposeable() { + public void dispose() { + caretModel.removeCaretListener(CurrentLineMarker.this); + } + }); + } + + public void set() { + if (myEditor == null) return; + hide(); + myHighlighter = myEditor.getMarkupModel().addLineHighlighter(myEditor.getCaretModel().getLogicalPosition().line, LAYER, null); + if (myHighlighter != null) { + //myHighlighter.setGutterIconRenderer(new GutterIconRenderer() { + // public Icon getIcon() { + // return CURRENT_LINE_MARKER_ICON; + // } + //}); + } + } + + private boolean isHiden() { return myHighlighter == null; } + + void hide() { + if (myHighlighter != null) { + LOG.assertTrue(myEditor != null); + myEditor.getMarkupModel().removeHighlighter(myHighlighter); + myHighlighter = null; + } + } + + public void caretPositionChanged(CaretEvent e) { + if (isHiden()) return; + set(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java new file mode 100644 index 00000000000..cd779698722 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java @@ -0,0 +1,170 @@ +/* + * Class DiffFragmentBuilder + * @author Jeka + */ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.util.diff.Diff; + +import java.util.LinkedList; +import java.util.List; + +/** + Builds a sequesnce of DiffFragment objects thus diffing 2 files + Parses the output of CVS 'diff' command assumed to be in the RCS Normal Format + Format of the output chunks for the command: 'diff file1 file2': + change-command + < from-file-line + < from-file-line... + --- + > to-file-line + > to-file-line... + + Where: + Change-Command -> Line a Range + Change-Command -> Range c Range + Change-Command -> Range d Line + Range -> Line , Line + Range -> Line + Line -> number-of-line + + The commands are: + a: append a range of lines from the file2 after line Line of the file1 + c: change the range of lines in the file1 to the range from file2 + d: Delete the lines in range Range from the file1; line Line is where they would have appeared in the file2 had they not been deleted + */ +public class DiffFragmentBuilder { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.DiffFragmentBuilder"); + + public static interface Range { + int getStart(); + + int getEnd(); + } + + private final String[] mySource1; + private final String[] mySource2; + private int myLastLine1 = 1; + private int myLastLine2 = 1; + private final List myData = new LinkedList(); + + public DiffFragmentBuilder(String[] source1, String[] source2) { + mySource1 = source1; + mySource2 = source2; + init(); + } + + private DiffFragment[] getFragments() { + return myData.toArray(new DiffFragment[myData.size()]); + } + + private void finish() { + String text1 = null, text2 = null; + if (myLastLine1 <= mySource1.length) { + text1 = concatinate(mySource1, myLastLine1, mySource1.length); + } + if (myLastLine2 <= mySource2.length) { + text2 = concatinate((mySource2), myLastLine2, mySource2.length); + } + if (text1 != null || text2 != null) { + myData.add(DiffFragment.unchanged(text1, text2)); + } + } + + private void init() { + myData.clear(); + myLastLine1 = myLastLine2 = 1; + } + + private void append(int line, Range range) { + LOG.debug("DiffFragmentBuilder.append(" + line + "," + range + "), modified:"); + String text1 = null, text2 = null; + int start = range.getStart(); + int end = range.getEnd(); + if (myLastLine1 <= line) { + text1 = concatinate(mySource1, myLastLine1, line); + } + if (myLastLine2 < start) { + text2 = concatinate(mySource2, myLastLine2, start - 1); + } + if (text1 != null || text2 != null) { + myData.add(DiffFragment.unchanged(text1, text2)); + } + myData.add(new DiffFragment(null, concatinate(mySource2, start, end))); + myLastLine1 = line + 1; + myLastLine2 = end + 1; + } + + private void change(Range range1, Range range2) { + LOG.debug("DiffFragmentBuilder.change(" + range1 + "," + range2 + ")"); + + String text1 = null, text2 = null; + int start1 = range1.getStart(); + int end1 = range1.getEnd(); + int start2 = range2.getStart(); + int end2 = range2.getEnd(); + if (myLastLine1 < start1) { + text1 = concatinate(mySource1, myLastLine1, start1 - 1); + } + if (myLastLine2 < start2) { + text2 = concatinate(mySource2, myLastLine2, start2 - 1); + } + if (text1 != null || text2 != null) { + myData.add(DiffFragment.unchanged(text1, text2)); + } + myData.add(new DiffFragment(concatinate(mySource1, start1, end1), + concatinate(mySource2, start2, end2))); + myLastLine1 = end1 + 1; + myLastLine2 = end2 + 1; + } + + private void delete(Range range, int line) { + LOG.debug("DiffFragmentBuilder.delete(" + range + "," + line + ")"); + + String text1 = null, text2 = null; + int start = range.getStart(); + int end = range.getEnd(); + if (myLastLine1 < start) { + text1 = concatinate(mySource1, myLastLine1, start - 1); + } + if (myLastLine2 <= line) { + text2 = concatinate(mySource2, myLastLine2, line); + } + if (text1 != null || text2 != null) { + myData.add(DiffFragment.unchanged(text1, text2)); + } + myData.add(new DiffFragment(concatinate(mySource1, start, end), null)); + myLastLine1 = end + 1; + myLastLine2 = line + 1; + } + + private String concatinate(String[] strings, int start, int end) { + StringBuffer buffer = new StringBuffer(); + for (int i = start - 1; i < end; i++) buffer.append(strings[i]); + return buffer.toString(); + } + + public static DiffFragment[] buildFragments(DiffFragmentBuilder builder, Diff.Change change) { + while (change != null) { + if (change.inserted > 0 && change.deleted > 0) { + builder.change( + new DiffRange(change.line0 + 1, change.line0 + change.deleted), + new DiffRange(change.line1 + 1, change.line1 + change.inserted) + ); + } + else if (change.inserted > 0) { + builder.append(change.line0, new DiffRange(change.line1 + 1, change.line1 + change.inserted)); + } + else if (change.deleted > 0) { + builder.delete(new DiffRange(change.line0 + 1, change.line0 + change.deleted), change.line1); + } + change = change.link; + } + builder.finish(); + + return builder.getFragments(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactory.java new file mode 100644 index 00000000000..05e612321c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactory.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.editor.ex.Highlighter; + +public interface DiffHighliterFactory { + Highlighter createHighlighter(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactoryImpl.java new file mode 100644 index 00000000000..9c40aaaf3a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffHighliterFactoryImpl.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; + +public class DiffHighliterFactoryImpl implements DiffHighliterFactory { + private final Project myProject; + private final FileType myFileType; + + public DiffHighliterFactoryImpl(FileType fileType, Project project) { + myFileType = fileType; + myProject = project; + } + + public Highlighter createHighlighter() { + return (myFileType == null || myProject == null) ? + null : HighlighterFactory.createHighlighter(myProject, myFileType); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffPanelImpl.java new file mode 100644 index 00000000000..e12d679382a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffPanelImpl.java @@ -0,0 +1,326 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffToolbar; +import com.intellij.openapi.diff.DiffViewer; +import com.intellij.openapi.diff.actions.IgnoreWhiteSpacesAction; +import com.intellij.openapi.diff.actions.MergeActionGroup; +import com.intellij.openapi.diff.actions.NextDiffAction; +import com.intellij.openapi.diff.actions.PreviousDiffAction; +import com.intellij.openapi.diff.ex.DiffPanelEx; +import com.intellij.openapi.diff.ex.DiffPanelOptions; +import com.intellij.openapi.diff.impl.fragments.FragmentList; +import com.intellij.openapi.diff.impl.highlighting.DiffPanelState; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint; +import com.intellij.openapi.diff.impl.splitter.LineBlocks; +import com.intellij.openapi.diff.impl.util.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollingModel; +import com.intellij.openapi.editor.event.VisibleAreaListener; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.editor.ex.FoldingModelEx; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; +import com.intellij.ui.PopupHandler; + +import javax.swing.*; +import java.awt.*; +import java.security.InvalidParameterException; + +public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSidesContainer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.DiffPanelImpl"); + + private final DiffSplitter mySplitter; + private final DiffPanelOutterComponent myPanel; + + private final Window myOwnerWindow; + private final DiffPanelOptions myOptions; + + private final DiffPanelState myData; + + private final Rediffers myDiffUpdater; + private final DiffSideView myLeftSide; + private final DiffSideView myRightSide; + private DiffSideView myCurrentSide; + private LineBlocks myLineBlocks = LineBlocks.EMPTY; + private final SyncScrollSupport myScrollSupport = new SyncScrollSupport(); + private final FontSizeSynchronizer myFontSizeSynchronizer = new FontSizeSynchronizer(); + private final DiffRequest.ToolbarAddons TOOL_BAR = new DiffRequest.ToolbarAddons() { + public void customize(DiffToolbar toolbar) { + ActionManager actionManager = ActionManager.getInstance(); + toolbar.addAction(actionManager.getAction(IdeActions.ACTION_COPY)); + toolbar.addAction(actionManager.getAction(IdeActions.ACTION_FIND)); + toolbar.addAction(PreviousDiffAction.find()); + toolbar.addAction(NextDiffAction.find()); + toolbar.addSeparator(); + toolbar.addAction(new LabelAction("Ignore whitespace: ")); + toolbar.addAction(new IgnoreWhiteSpacesAction(DiffPanelImpl.this)); + } + }; + private boolean myDisposed = false; + + public DiffPanelImpl(final Window owner, Project project, boolean enableToolbar) { + myOptions = new DiffPanelOptions(this); + myPanel = new DiffPanelOutterComponent(TextDiffType.DIFF_TYPES, TOOL_BAR); + myPanel.disableToolbar(!enableToolbar); + if (enableToolbar) myPanel.resetToolbar(); + myOwnerWindow = owner; + myLeftSide = new DiffSideView("left...", this); + myRightSide = new DiffSideView("right...", this); + myLeftSide.becomeMaster(); + myDiffUpdater = new Rediffers(this); + + myData = new DiffPanelState(this, project); + mySplitter = new DiffSplitter(myLeftSide.getComponent(), myRightSide.getComponent(), + new DiffDividerPaint(this, FragmentSide.SIDE1)); + myPanel.insertDiffComponent(mySplitter, new MyScrollingPanel()); + myPanel.setDataProvider(new MyDataProvider()); + } + + public Editor getEditor1() { + return myLeftSide.getEditor(); + } + + public Editor getEditor2() { + if (myDisposed) LOG.error("Disposed"); + Editor editor = myRightSide.getEditor(); + if (editor != null) return editor; + if (myData.getContent2() == null) LOG.error("No content 2"); + return editor; + } + + public void setContents(DiffContent content1, DiffContent content2) { + LOG.assertTrue(!myDisposed); + myData.setContents(content1, content2); + Project project = myData.getProject(); + FileType[] types = DiffUtil.chooseContentTypes(new DiffContent[]{content1, content2}); + myLeftSide.setHighlighterFactory(createHighlighter(types[0], project)); + myRightSide.setHighlighterFactory(createHighlighter(types[1], project)); + rediff(); + myPanel.requestScrollEditors(); + } + + private DiffHighliterFactory createHighlighter(FileType contentType, Project project) { + return new DiffHighliterFactoryImpl(contentType, project); + } + + void rediff() { + setLineBlocks(myData.updateEditors()); + } + + public void setTitle1(String title) { + myLeftSide.setTitle(title); + } + + public void setTitle2(String title) { + myRightSide.setTitle(title); + } + + private void setLineBlocks(LineBlocks blocks) { + myLineBlocks = blocks; + mySplitter.redrawDiffs(); + updateStatusBar(); + } + + public void invalidateDiff() { + setLineBlocks(LineBlocks.EMPTY); + myData.removeActions(); + } + + public FragmentList getFragments() { + return myData.getFragmentList(); + } + + private int[] getFragmentBeginnings() { + return getFragmentBeginnings(myCurrentSide.getSide()); + } + + int[] getFragmentBeginnings(FragmentSide side) { + return getLineBlocks().getBegginings(side); + } + + public void dispose() { + myDisposed = true; + myDiffUpdater.dispose(); + myScrollSupport.dispose(); + myData.dispose(); + myPanel.cancelScrollEditors(); + } + + public JComponent getComponent() { + return myPanel; + } + + private void updateStatusBar() { + int differentLineBlocks = getLineBlocks().getCount(); + String text; + if (differentLineBlocks > 1) { + text = differentLineBlocks + " differences"; + } + else if (differentLineBlocks == 1) { + text = "1 difference"; + } + else { + text = "No differences"; + } + myPanel.setStatusBarText(text); + } + + public boolean hasDifferences() { + return getLineBlocks().getCount() > 0; + } + + public JComponent getPreferredFocusedComponent() { + return myCurrentSide.getFocusableComponent(); + } + + public ComparisonPolicy getComparisonPolicy() { + return myData.getComparisonPolicy(); + } + + public void setComparisonPolicy(ComparisonPolicy comparisonPolicy) { + myData.setComparisonPolicy(comparisonPolicy); + rediff(); + } + + public Rediffers getDiffUpdater() { + return myDiffUpdater; + } + + public void onContentChangedIn(EditorSource source) { + myDiffUpdater.contentRemoved(source); + final EditorEx editor = source.getEditor(); + if (source.getSide() == FragmentSide.SIDE1 && editor != null) { + editor.setVerticalScrollbarOrientation(EditorEx.VERTICAL_SCROLLBAR_LEFT); + } + DiffSideView viewSide = getSideView(source.getSide()); + viewSide.setEditorSource(source); + myScrollSupport.dispose(); + if (editor == null) { + rediff(); + return; + } + PopupHandler.installUnknownPopupHandler(editor.getContentComponent(), new MergeActionGroup(this, source.getSide()), ActionManager.getInstance()); + myDiffUpdater.contentAdded(source); + editor.getSettings().setLineNumbersShown(true); + editor.getSettings().setFoldingOutlineShown(false); + ((FoldingModelEx)editor.getFoldingModel()).setFoldingEnabled(false); + ((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true); + + Editor editor1 = getEditor(FragmentSide.SIDE1); + Editor editor2 = getEditor(FragmentSide.SIDE2); + if (editor1 != null && editor2 != null) { + myScrollSupport.install(new EditingSides[]{this}); + } + + final VisibleAreaListener visibleAreaListener = mySplitter.getVisibleAreaListener(); + final ScrollingModel scrollingModel = editor.getScrollingModel(); + scrollingModel.addVisibleAreaListener(visibleAreaListener); + myFontSizeSynchronizer.synchronize(editor); + source.addDisposable(new Disposeable() { + public void dispose() { + myFontSizeSynchronizer.stopSynchronize(editor); + } + }); + source.addDisposable(new Disposeable() { + public void dispose() { + scrollingModel.removeVisibleAreaListener(visibleAreaListener); + } + }); + } + + public void setCurrentSide(DiffSideView viewSide) { + LOG.assertTrue(viewSide != myCurrentSide); + LOG.assertTrue(viewSide != null); + if (myCurrentSide != null) myCurrentSide.beSlave(); + myCurrentSide = viewSide; + } + + private DiffSideView getCurrentSide() { return myCurrentSide; } + + public Project getProject() { + return myData.getProject(); + } + + public void showSource(OpenFileDescriptor descriptor) { + myOptions.showSource(descriptor); + } + + public DiffPanelOptions getOptions() { + return myOptions; + } + + public Editor getEditor(FragmentSide side) { + return getSideView(side).getEditor(); + } + + private DiffSideView getSideView(FragmentSide side) { + if (side == FragmentSide.SIDE1) { + return myLeftSide; + } + else if (side == FragmentSide.SIDE2) return myRightSide; + throw new InvalidParameterException(String.valueOf(side)); + } + + public LineBlocks getLineBlocks() { return myLineBlocks; } + + public void setDiffRequest(DiffRequest data) { + setContents(data.getContents()[0], data.getContents()[1]); + setTitle1(data.getContentTitles()[0]); + setTitle2(data.getContentTitles()[1]); + setWindowTitle(myOwnerWindow, data.getWindowTitle()); + data.customizeToolbar(myPanel.resetToolbar()); + myPanel.registerToolbarActions(); + } + + private void setWindowTitle(Window window, String title) { + if (window instanceof JDialog) { + ((JDialog)window).setTitle(title); + } + else if (window instanceof JFrame) ((JFrame)window).setTitle(title); + } + + public static DiffPanelImpl fromDataContext(DataContext dataContext) { + DiffViewer viewer = (DiffViewer)dataContext.getData(DataConstants.DIFF_VIEWER); + return viewer instanceof DiffPanelImpl ? (DiffPanelImpl)viewer : null; + } + + public Window getOwnerWindow() { + return myOwnerWindow; + } + + private class MyScrollingPanel implements DiffPanelOutterComponent.ScrollingPanel { + + public void scrollEditors() { + getOptions().onNewContent(myCurrentSide); + int[] fragments = getFragmentBeginnings(); + if (fragments.length > 0) myCurrentSide.scrollToFirstDiff(fragments[0]); + } + } + + private class MyDataProvider implements DataProvider { + private final FocusDiffSide myFocusDiffSide = new FocusDiffSide() { + public Editor getEditor() { + return getCurrentSide().getEditor(); + } + + public int[] getFragmentStartingLines() { + return getFragmentBeginnings(); + } + }; + + public Object getData(String dataId) { + if (DataConstants.DIFF_VIEWER.equals(dataId)) return DiffPanelImpl.this; + if (FocusDiffSide.FOCUSED_DIFF_SIDE.equals(dataId)) return myCurrentSide == null ? null : myFocusDiffSide; + return null; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffRange.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffRange.java new file mode 100644 index 00000000000..1e444414b9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffRange.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.diff.impl; + + + +/** + * @author Jeka + */ +public class DiffRange implements DiffFragmentBuilder.Range { + private final int myStart; + private final int myEnd; + + public DiffRange(int start, int end) { + myStart = start; + myEnd = end; + } + + public int getStart() { + return myStart; + } + + public int getEnd() { + return myEnd; + } + + public String toString() { + return "DiffRange: " + myStart + "," + myEnd; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSideView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSideView.java new file mode 100644 index 00000000000..82d6221f53d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSideView.java @@ -0,0 +1,227 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.LabeledEditor; +import com.intellij.openapi.diff.impl.util.SyncScrollSupport; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.event.EditorMouseAdapter; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.editor.event.EditorMouseEventArea; +import com.intellij.openapi.editor.event.EditorMouseMotionAdapter; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +public class DiffSideView { + private final JComponent MOCK_COMPONENT = new JPanel(); + { + MOCK_COMPONENT.setFocusable(true); + } + + private static final DiffHighliterFactory DUMMY_HIGHLIGHTER_FACTORY = new DiffHighliterFactoryImpl(null, null); + private final LabeledEditor myPanel = new LabeledEditor(); + + private final DiffSidesContainer myContainer; + private final CurrentLineMarker myLineMarker = new CurrentLineMarker(); + + private DiffHighliterFactory myHighlighterFactory = DUMMY_HIGHLIGHTER_FACTORY; + private EditorSource myEditorSource = EditorSource.NULL; + private boolean myIsMaster = false; + private String myTitle; + + public DiffSideView(String title, DiffSidesContainer container) { + myTitle = title; + myContainer = container; + insertComponent(MOCK_COMPONENT); + } + + public JComponent getComponent() { + return myPanel; + } + + public void setEditorSource(EditorSource source) { + MyState state = new MyState(); + myEditorSource = source; + myLineMarker.attach(myEditorSource); + Editor editor = myEditorSource.getEditor(); + if (editor == null) { + insertComponent(MOCK_COMPONENT); + return; + } + editor.getScrollingModel().scrollHorizontally(0); + insertComponent(editor.getComponent()); + applyHighlighter(); + setMouseListeners(source); + MyEditorFocusListener.install(this); + + state.restore(); + } + + private void insertComponent(JComponent component) { + myPanel.setComponent(component, myTitle); + } + + public void setHighlighterFactory(DiffHighliterFactory highlighterFactory) { + myHighlighterFactory = highlighterFactory; + applyHighlighter(); + } + + private void applyHighlighter() { + EditorEx editor = myEditorSource.getEditor(); + if (editor == null) return; + Highlighter highlighter = myHighlighterFactory.createHighlighter(); + if (highlighter != null) editor.setHighlighter(highlighter); + editor.getColorsScheme().setColor(EditorColors.CARET_ROW_COLOR, null); + } + + public void setTitle(String title) { + myTitle = title; + Editor editor = getEditor(); + if (editor == null) return; + boolean readonly = editor.isViewer() || !editor.getDocument().isWritable(); + myPanel.updateTitle(myTitle, readonly); + } + + private void setMouseListeners(EditorSource source) { + DiffContent content = source.getContent(); + MouseLineNumberListener.install(content, source, myContainer); + } + + public void beSlave() { + myIsMaster = false; + myLineMarker.hide(); + } + + private static class MouseLineNumberListener { + private static final Cursor HAND__CURSOR = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + private final Editor myEditor; + private final DiffSidesContainer myContainer; + private final DiffContent myContent; + private final Project myProject; + + private final EditorMouseAdapter myMouseListener = new EditorMouseAdapter() { + public void mouseReleased(EditorMouseEvent e) { + if (!isInMyArea(e)) return; + OpenFileDescriptor descriptor = getOpenFileDescriptor(e); + if (descriptor == null) return; + myContainer.showSource(descriptor); + } + }; + + private OpenFileDescriptor getOpenFileDescriptor(EditorMouseEvent e) { + int offset = myEditor.logicalPositionToOffset(myEditor.xyToLogicalPosition(e.getMouseEvent().getPoint())); + return myContent.getOpenFileDescriptor(offset); + } + + private boolean isInMyArea(EditorMouseEvent e) { + return e.getArea() == EditorMouseEventArea.LINE_NUMBERS_AREA; + } + + private final EditorMouseMotionAdapter myMouseMotionListener = new EditorMouseMotionAdapter() { + public void mouseMoved(EditorMouseEvent e) { + if (!isInMyArea(e)) return; + Cursor cursor = getOpenFileDescriptor(e) != null ? HAND__CURSOR : Cursor.getDefaultCursor(); + e.getMouseEvent().getComponent().setCursor(cursor); + myEditor.getContentComponent().setCursor(cursor); + } + }; + + public MouseLineNumberListener(DiffContent content, Editor editor, DiffSidesContainer container, Project project) { + myEditor = editor; + myContainer = container; + myContent = content; + myProject = project; + } + + public static void install(DiffContent content, EditorSource source, DiffSidesContainer container) { + final Editor editor = source.getEditor(); + Project project = container.getProject(); + if (project == null) return; + final MouseLineNumberListener listener = new MouseLineNumberListener(content, editor, container, project); + editor.addEditorMouseListener(listener.myMouseListener); + editor.addEditorMouseMotionListener(listener.myMouseMotionListener); + source.addDisposable(new Disposeable() { + public void dispose() { + editor.removeEditorMouseListener(listener.myMouseListener); + editor.removeEditorMouseMotionListener(listener.myMouseMotionListener); + } + }); + } + + } + + private static class MyEditorFocusListener extends FocusAdapter { + private final DiffSideView mySideView; + + private MyEditorFocusListener(DiffSideView sideView) { + mySideView = sideView; + } + + public void focusGained(FocusEvent e) { + mySideView.becomeMaster(); + } + + public static MyEditorFocusListener install(DiffSideView sideView) { + final MyEditorFocusListener listener = new MyEditorFocusListener(sideView); + final JComponent focusableComponent = sideView.getFocusableComponent(); + focusableComponent.addFocusListener(listener); + sideView.myEditorSource.addDisposable(new Disposeable() { + public void dispose() { + focusableComponent.removeFocusListener(listener); + } + }); + return listener; + } + } + + public JComponent getFocusableComponent() { + Editor editor = getEditor(); + return editor != null ? editor.getContentComponent() : MOCK_COMPONENT; + } + + public void becomeMaster() { + if (myIsMaster) return; + myIsMaster = true; + myContainer.setCurrentSide(this); + beMaster(); + } + + private void beMaster() { + myLineMarker.set(); + } + + public void scrollToFirstDiff(int logicalLine) { + Editor editor = myEditorSource.getEditor(); + SyncScrollSupport.scrollEditor(editor, logicalLine); + } + + public Editor getEditor() { + return myEditorSource.getEditor(); + } + + public FragmentSide getSide() { + return myEditorSource.getSide(); + } + + private class MyState { + private final boolean isFocused; + public MyState() { + isFocused = IJSwingUtilities.hasFocus(getFocusableComponent()); + } + + public void restore() { + if (isFocused) getFocusableComponent().requestFocus(); + if (myIsMaster) beMaster(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSidesContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSidesContainer.java new file mode 100644 index 00000000000..21ca98d77ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSidesContainer.java @@ -0,0 +1,10 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; + +public interface DiffSidesContainer { + void setCurrentSide(DiffSideView viewSide); + Project getProject(); + void showSource(OpenFileDescriptor descriptor); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSplitter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSplitter.java new file mode 100644 index 00000000000..b2d46f5ce22 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffSplitter.java @@ -0,0 +1,43 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint; +import com.intellij.openapi.editor.event.VisibleAreaEvent; +import com.intellij.openapi.editor.event.VisibleAreaListener; +import com.intellij.openapi.ui.Splitter; + +import javax.swing.*; +import java.awt.*; + +class DiffSplitter extends Splitter { + private final DiffDividerPaint myPaint; + + private final VisibleAreaListener myVisibleAreaListener = new VisibleAreaListener() { + public void visibleAreaChanged(VisibleAreaEvent e) { + redrawDiffs(); + } + }; + + public DiffSplitter(JComponent component1, JComponent component2, DiffDividerPaint dividerPaint) { + myPaint = dividerPaint; + setDividerWidth(30); + setFirstComponent(component1); + setSecondComponent(component2); + } + + protected Splitter.Divider createDivider() { + return new Divider(){ + public void paint(Graphics g) { + super.paint(g); + myPaint.paint(g, this); + } + }; + } + + public void redrawDiffs() { + getDivider().repaint(); + } + + public VisibleAreaListener getVisibleAreaListener() { + return myVisibleAreaListener; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarComponent.java new file mode 100644 index 00000000000..3cf5fbe3ca9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarComponent.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.diff.DiffRequest; + +import javax.swing.*; +import java.awt.*; + +public class DiffToolbarComponent extends JPanel { + private final JComponent myWholeComponent; + private DiffToolbarImpl myToolbar; + + public DiffToolbarComponent(final JComponent wholeComponent) { + super(new BorderLayout()); + myWholeComponent = wholeComponent; + } + + public void resetToolbar(DiffRequest.ToolbarAddons toolBar) { + if (myToolbar != null) remove(myToolbar.getComponent()); + myToolbar = new DiffToolbarImpl(); + myToolbar.reset(toolBar); + myToolbar.registerKeyboardActions(myWholeComponent); + add(myToolbar.getComponent(), BorderLayout.CENTER); + revalidate(); + repaint(); + } + + public DiffToolbarImpl getToolbar() { + return myToolbar; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarImpl.java new file mode 100644 index 00000000000..93c5b71e1d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffToolbarImpl.java @@ -0,0 +1,71 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffToolbar; +import com.intellij.openapi.wm.ex.ActionToolbarEx; + +import javax.swing.*; + +public class DiffToolbarImpl implements DiffToolbar { + private final DefaultActionGroup myActionGroup = new DefaultActionGroup(); + private ActionToolbarEx myActionToolbar; + + public void registerKeyboardActions(JComponent registerActionsTo) { + AnAction[] actions = getAllActions(); + for (int i = 0; i < actions.length; i++) { + AnAction action = actions[i]; + action.registerCustomShortcutSet(action.getShortcutSet(), registerActionsTo); + } + } + + public AnAction[] getAllActions() { + return myActionGroup.getChildren(null); + } + + public boolean removeActionById(String actionId) { + AnAction[] allActions = getAllActions(); + for (int i = 0; i < allActions.length; i++) { + AnAction action = allActions[i]; + if (actionId.equals(ActionManager.getInstance().getId(action))) { + removeAction(action); + return true; + } + } + return false; + } + + public void removeAction(AnAction action) { + myActionGroup.remove(action); + updateToolbar(); + } + + public JComponent getComponent() { + if (myActionToolbar == null) + myActionToolbar = (ActionToolbarEx)ActionManager.getInstance(). + createActionToolbar(ActionPlaces.UNKNOWN, myActionGroup, true); + return myActionToolbar.getComponent(); + } + + public void addAction(AnAction action) { + myActionGroup.add(action); + updateToolbar(); + } + + private void updateToolbar() { + if (myActionToolbar != null) myActionToolbar.updateActions(); + } + + public void addSeparator() { + myActionGroup.addSeparator(); + updateToolbar(); + } + + public void reset(DiffRequest.ToolbarAddons toolBar) { + myActionGroup.removeAll(); + toolBar.customize(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffUtil.java new file mode 100644 index 00000000000..dcc57040f5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffUtil.java @@ -0,0 +1,76 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffContentUtil; +import com.intellij.openapi.diff.LineTokenizer; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.external.DiffManagerImpl; +import com.intellij.openapi.diff.impl.util.FocusDiffSide; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.util.ImageLoader; + +public class DiffUtil { + public static FrameWrapper initDiffFrame(FrameWrapper frameWrapper, final DiffPanelImpl diffPanel) { + Project project = diffPanel.getProject(); + frameWrapper.setComponent(diffPanel.getComponent()); + frameWrapper.setData(DataConstants.PROJECT, project); + frameWrapper.setImage(ImageLoader.loadFromResource("/diff/Diff.png")); + frameWrapper.setPreferredFocusedComponent(diffPanel.getPreferredFocusedComponent()); + frameWrapper.closeOnEsc(); + frameWrapper.addDisposable(diffPanel); + return frameWrapper; + } + + public static FocusDiffSide getFocusDiffSide(DataContext dataContext) { + return (FocusDiffSide)dataContext.getData(FocusDiffSide.FOCUSED_DIFF_SIDE); + } + + public static String[] convertToLines(String text) { + return new LineTokenizer(text).execute(); + } + + public static FileType[] chooseContentTypes(DiffContent[] contents) { + FileType commonType = StdFileTypes.PLAIN_TEXT; + for (int i = 0; i < contents.length; i++) { + FileType contentType = contents[i].getContentType(); + if (DiffContentUtil.isTextType(contentType)) commonType = contentType; + } + FileType[] result = new FileType[contents.length]; + for (int i = 0; i < contents.length; i++) { + FileType contentType = contents[i].getContentType(); + result[i] = DiffContentUtil.isTextType(contentType) ? contentType : commonType; + } + return result; + } + + public static boolean isWriatable(DiffContent content) { + Document document = content.getDocument(); + return document != null && document.isWritable(); + } + + public static int getTextLength(String text) { + return text != null ? text.length() : 0; + } + + public static boolean isEmpty(DiffFragment fragment) { + return getTextLength(fragment.getText1()) == 0 && + getTextLength(fragment.getText2()) == 0; + } + + public static EditorEx createEditor(Document document, Project project, boolean isViewer) { + EditorFactory factory = EditorFactory.getInstance(); + EditorEx editor = (EditorEx)(isViewer + ? factory.createViewer(document, project) + : factory.createEditor(document, project)); + editor.putUserData(DiffManagerImpl.EDITOR_IS_DIFF_KEY, Boolean.TRUE); + editor.getGutterComponentEx().revalidateMarkup(); + return editor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffVersionComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffVersionComponent.java new file mode 100644 index 00000000000..6fb2e8bf915 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/DiffVersionComponent.java @@ -0,0 +1,8 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; + +public interface DiffVersionComponent { + void addDisposable(Disposeable disposeable); + void removeContent(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditingSides.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditingSides.java new file mode 100644 index 00000000000..a02c3ba3880 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditingSides.java @@ -0,0 +1,10 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.splitter.LineBlocks; +import com.intellij.openapi.editor.Editor; + +public interface EditingSides { + Editor getEditor(FragmentSide side); + LineBlocks getLineBlocks(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditorSource.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditorSource.java new file mode 100644 index 00000000000..09c656e48e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/EditorSource.java @@ -0,0 +1,34 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.editor.ex.EditorEx; + +public interface EditorSource { + FragmentSide getSide(); + DiffContent getContent(); + + EditorSource NULL = new EditorSource() { + public EditorEx getEditor() { + return null; + } + + public void addDisposable(Disposeable disposeable) { + Logger.getInstance("#com.intellij.openapi.diff.impl.EditorSource").assertTrue(false); + } + + public FragmentSide getSide() { + return null; + } + + public DiffContent getContent() { + return null; + } + }; + + EditorEx getEditor(); + + void addDisposable(Disposeable disposeable); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/FrameWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/FrameWrapper.java new file mode 100644 index 00000000000..89fa0f80781 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/FrameWrapper.java @@ -0,0 +1,153 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.DimensionService; +import com.intellij.util.ImageLoader; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public class FrameWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.FrameWrapper"); + private String myDimensionKey = null; + private JComponent myComponent = null; + private JComponent myPreferedFocus = null; + private String myTitle = ""; + private Image myImage = ImageLoader.loadFromResource("/icon.png"); + private boolean myCloseOnEsc = false; + private JFrame myFrame; + private final Map myDatas = new HashMap(); + private final ArrayList myDisposables = new ArrayList(); + + public FrameWrapper(String dimensionServiceKey) { + myDimensionKey = dimensionServiceKey; + } + + public void setDimensionKey(String dimensionKey) { myDimensionKey = dimensionKey; } + + public void setData(String dataId, Object data) { myDatas.put(dataId, data); } + + public void show() { + final JFrame frame = getFrame(); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + WindowAdapter focusListener = new WindowAdapter() { + public void windowOpened(WindowEvent e) { + if (myPreferedFocus != null) + myPreferedFocus.requestFocusInWindow(); + } + }; + frame.addWindowListener(focusListener); + if (myCloseOnEsc) addDisposeOnEsc(frame); + frame.getContentPane().add(myComponent, BorderLayout.CENTER); + frame.setTitle(myTitle); + frame.setIconImage(myImage); + loadFrameState(myDimensionKey, frame); + frame.setVisible(true); + } + + private static void addDisposeOnEsc(final WindowType frame) { + frame.getRootPane().registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); + MenuElement[] selectedPath = menuSelectionManager.getSelectedPath(); + if (selectedPath.length > 0) { // hide popup menu if any + menuSelectionManager.clearSelectedPath(); + } + else { + frame.dispose(); + } + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW + ); + } + + public JFrame getFrame() { + if (myFrame == null) { + myFrame = new MyJFrame(); + } + return myFrame; + } + + public void setComponent(JComponent component) { myComponent = component; } + + public void setPreferredFocusedComponent(JComponent preferedFocus) { myPreferedFocus = preferedFocus; } + + public void closeOnEsc() { myCloseOnEsc = true; } + + public void setImage(Image image) { myImage = image; } + + private void loadFrameState(String dimensionKey, JFrame frame) { + final Point location; + final Dimension size; + final int extendedState; + DimensionService dimensionService = DimensionService.getInstance(); + if (dimensionKey == null || dimensionService == null) { + location = null; + size = null; + extendedState = -1; + } else { + location = dimensionService.getLocation(dimensionKey); + size = dimensionService.getSize(dimensionKey); + extendedState = dimensionService.getExtendedState(dimensionKey); + } + + if (size != null) { + if (location != null) frame.setLocation(location); + frame.setSize(size); + frame.getRootPane().revalidate(); + } + else { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + frame.pack(); + int height = Math.min(screenSize.height - 40, frame.getHeight()); + int width = Math.min(screenSize.width - 20, frame.getWidth()); + frame.setBounds(10, 10, width, height); + } + + if (extendedState == JFrame.ICONIFIED || extendedState == JFrame.MAXIMIZED_BOTH) { + frame.setExtendedState(extendedState); + } + } + + private void saveFrameState(String dimensionKey, JFrame frame) { + DimensionService dimensionService = DimensionService.getInstance(); + if (dimensionKey == null || dimensionService == null) return; + dimensionService.setLocation(dimensionKey, frame.getLocation()); + dimensionService.setSize(dimensionKey, frame.getSize()); + dimensionService.setExtendedState(dimensionKey, frame.getExtendedState()); + } + + public void setTitle(String title) { myTitle = title; } + + public void addDisposable(Disposeable disposeable) { + LOG.assertTrue(!myDisposables.contains(disposeable)); + myDisposables.add(disposeable); + } + + private class MyJFrame extends JFrame implements DataProvider { + public MyJFrame() throws HeadlessException {} + + public void dispose() { + saveFrameState(myDimensionKey, this); + for (Iterator iterator = myDisposables.iterator(); iterator.hasNext();) { + Disposeable disposeable = iterator.next(); + disposeable.dispose(); + } + super.dispose(); + } + + public Object getData(String dataId) { + return myDatas.get(dataId); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/Rediffers.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/Rediffers.java new file mode 100644 index 00000000000..68dcb2cae7e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/Rediffers.java @@ -0,0 +1,98 @@ +package com.intellij.openapi.diff.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Alarm; +import com.intellij.util.containers.HashMap; + +import java.util.Iterator; + +public class Rediffers { + private final HashMap myRediffers = new HashMap(); + private final DiffPanelImpl myPanel; + private final Alarm myAlarm = new Alarm(); + private final Runnable myUpdateRequest = new Runnable() { + public void run() { + if (myDisposed) return; + updateNow(); + } + }; + private boolean myDisposed = false; + + public Rediffers(DiffPanelImpl panel) { + myPanel = panel; + } + + public void dispose() { + for (Iterator iterator = myRediffers.values().iterator(); iterator.hasNext();) { + Rediff rediff = iterator.next(); + rediff.stopListen(); + } + myRediffers.clear(); + myAlarm.cancelAllRequests(); + myDisposed = true; + } + + public void contentRemoved(EditorSource source) { + Rediff rediff = myRediffers.remove(source); + if (rediff != null) rediff.stopListen(); + } + + public void contentAdded(final EditorSource source) { + Editor editor = source.getEditor(); + Rediff rediff = new Rediff(editor.getDocument()); + myRediffers.put(source, rediff); + rediff.startListen(); + source.addDisposable(new Disposeable() { + public void dispose() { + contentRemoved(source); + } + }); + } + + public void updateNow() { + myPanel.rediff(); + myAlarm.cancelAllRequests(); + } + + private void requestRediff() { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(myUpdateRequest, 300); + } + + private class Rediff implements DocumentListener, Disposeable { + private final Document myDocument; + private boolean myLinstening = false; + + public Rediff(Document document) { + myDocument = document; + } + + public void beforeDocumentChange(DocumentEvent event) {} + + public void documentChanged(DocumentEvent event) { + int newLines = StringUtil.getLineBreakCount(event.getNewFragment()); + int oldLines = StringUtil.getLineBreakCount(event.getOldFragment()); + if (newLines != oldLines) myPanel.invalidateDiff(); + requestRediff(); + } + + public void stopListen() { + if (myLinstening) myDocument.removeDocumentListener(this); + myLinstening = false; + } + + public void startListen() { + if (!myLinstening) myDocument.addDocumentListener(this); + myLinstening = true; + } + + public void dispose() { + stopListen(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/TwoSidesContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/TwoSidesContainer.java new file mode 100644 index 00000000000..abb0d6aa7f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/TwoSidesContainer.java @@ -0,0 +1,6 @@ +package com.intellij.openapi.diff.impl; + + + +public interface TwoSidesContainer extends DiffSidesContainer, EditingSides { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BaseExternalTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BaseExternalTool.java new file mode 100644 index 00000000000..300b3e0d868 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BaseExternalTool.java @@ -0,0 +1,88 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffTool; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.config.AbstractProperty; +import com.intellij.util.config.BooleanProperty; +import com.intellij.util.config.StringProperty; + +import java.io.File; +import java.io.IOException; + +abstract class BaseExternalTool implements DiffTool { + private final BooleanProperty myEnableProperty; + private final StringProperty myToolProperty; + + protected BaseExternalTool(BooleanProperty enableProperty, StringProperty toolProperty) { + myEnableProperty = enableProperty; + myToolProperty = toolProperty; + } + + public boolean canShow(DiffRequest request) { + AbstractProperty.AbstractPropertyContainer config = DiffManagerImpl.getInstanceEx().getProperties(); + if (!myEnableProperty.value(config)) return false; + String path = getToolPath(); + if (path == null || path.length() == 0) return false; + DiffContent[] contents = request.getContents(); + if (contents.length != 2) return false; + if (externalize(request, 0) == null) return false; + if (externalize(request, 1) == null) return false; + return true; + } + + protected abstract ContentExternalizer externalize(DiffRequest request, int index); + + private String getToolPath() { + return myToolProperty.get(DiffManagerImpl.getInstanceEx().getProperties()); + } + + public void show(DiffRequest request) { + //ArrayList commandLine = new ArrayList(); + GeneralCommandLine commandLine = new GeneralCommandLine(); + commandLine.setExePath(getToolPath()); + try { + commandLine.addParameter(convertToPath(request, 0)); + commandLine.addParameter(convertToPath(request, 1)); + Runtime.getRuntime().exec(commandLine.getCommands()); + } catch (IOException e) { + ExecutionUtil.showExecutionErrorMessage(new ExecutionException(e.getMessage()), "Can't Launch Diff Tool", request.getProject()); + } + } + + private String convertToPath(DiffRequest request, int index) throws IOException { + return externalize(request, index).getContentFile().getAbsolutePath(); + } + + protected VirtualFile getLocalFile(VirtualFile file) { + if (file != null && (file.getFileSystem() instanceof LocalFileSystem)) return file; + return null; + } + + protected interface ContentExternalizer { + File getContentFile() throws IOException; + } + + protected static class LocalFileExternalizer implements ContentExternalizer { + private final File myFile; + + public LocalFileExternalizer(File file) { + myFile = file; + } + + public File getContentFile() { + return myFile; + } + + public static LocalFileExternalizer tryCreate(VirtualFile file) { + if (file == null || !file.isValid()) return null; + if (!(file.getFileSystem() instanceof LocalFileSystem)) return null; + return new LocalFileExternalizer(new File(file.getPath().replace('/', File.separatorChar))); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java new file mode 100644 index 00000000000..23b2aa84e4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java @@ -0,0 +1,45 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffTool; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; +import java.util.Arrays; + +class BinaryDiffTool implements DiffTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.external.BinaryDiffTool"); + public static final DiffTool INSTANCE = new BinaryDiffTool(); + public void show(DiffRequest data) { + DiffContent[] contents = data.getContents(); + try { + compareBinaryFiles(contents[0].getBytes(), contents[1].getBytes()); + } + catch (IOException e) { + LOG.error(e); + } + } + + private static void compareBinaryFiles(byte[] currentContent, byte[] upToDateContent) { + if (Arrays.equals(currentContent, upToDateContent)) { + Messages.showMessageDialog("Binary files are identical", "Files Are Identical", Messages.getInformationIcon()); + } + else { + Messages.showMessageDialog("Binary files are different", "Files Are Different", Messages.getInformationIcon()); + } + } + + public boolean canShow(DiffRequest data) { + DiffContent[] contents = data.getContents(); + if (contents.length != 2) return false; + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + VirtualFile file = content.getFile(); + if (file != null && file.isDirectory()) return false; + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/CompositeDiffTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/CompositeDiffTool.java new file mode 100644 index 00000000000..5e44fa50365 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/CompositeDiffTool.java @@ -0,0 +1,48 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffTool; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +class CompositeDiffTool implements DiffTool { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.external.CompositeDiffTool"); + private final List myTools; + + public CompositeDiffTool(List tools) { + myTools = new ArrayList(tools); + } + + public void show(DiffRequest data) { + checkDiffData(data); + DiffTool tool = chooseTool(data); + if (tool != null) tool.show(data); + else LOG.error("Can't show"); + } + + public boolean canShow(DiffRequest data) { + checkDiffData(data); + return chooseTool(data) != null; + } + + private DiffTool chooseTool(DiffRequest data) { + for (Iterator iterator = myTools.iterator(); iterator.hasNext();) { + DiffTool tool = iterator.next(); + if (tool.canShow(data)) return tool; + } + return null; + } + + private void checkDiffData(DiffRequest data) { + LOG.assertTrue(data != null); + DiffContent[] contents = data.getContents(); + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + LOG.assertTrue(content != null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffManagerImpl.java new file mode 100644 index 00000000000..eba995fefcc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffManagerImpl.java @@ -0,0 +1,135 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.DiffPanel; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffTool; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.mergeTool.MergeTool; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.MarkupEditorFilter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.config.*; +import com.intellij.execution.configurations.GeneralCommandLine; +import org.jdom.Element; + +import java.awt.*; +import java.util.ArrayList; + +public class DiffManagerImpl extends DiffManager implements JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.external.DiffManagerImpl"); + private static final Externalizer TOOL_PATH_UPDATE = new Externalizer() { + private static final String NEW_VALUE = "newValue"; + public String readValue(Element dataElement) { + String path = dataElement.getAttributeValue(NEW_VALUE); + if (path != null) return path; + String prevValue = dataElement.getAttributeValue(VALUE_ATTRIBUTE); + return prevValue != null ? GeneralCommandLine.quote(prevValue.trim()) : null; + } + + public void writeValue(Element dataElement, String path) { + dataElement.setAttribute(VALUE_ATTRIBUTE, path); + dataElement.setAttribute(NEW_VALUE, path); + } + }; + static final StringProperty FOLDERS_TOOL = new StringProperty("foldersTool", ""); + static final StringProperty FILES_TOOL = new StringProperty("filesTool", ""); + static final BooleanProperty ENABLE_FOLDERS = new BooleanProperty( + "enableFolders", false); + static final BooleanProperty ENABLE_FILES = new BooleanProperty( + "enableFiles", false); + + private final ExternalizablePropertyContainer myProperties; + private final ArrayList myAdditionTools = new ArrayList(); + public static final DiffTool INTERNAL_DIFF = new FrameDiffTool(); + + public static final Key EDITOR_IS_DIFF_KEY = new Key("EDITOR_IS_DIFF_KEY"); + private static final MarkupEditorFilter DIFF_EDITOR_FILTER = new MarkupEditorFilter() { + public boolean avaliableIn(Editor editor) { + return editor.getUserData(EDITOR_IS_DIFF_KEY) != null; + } + }; + + public DiffManagerImpl() { + myProperties = new ExternalizablePropertyContainer(); + myProperties.registerProperty(ENABLE_FOLDERS); + myProperties.registerProperty(FOLDERS_TOOL, TOOL_PATH_UPDATE); + myProperties.registerProperty(ENABLE_FILES); + myProperties.registerProperty(FILES_TOOL, TOOL_PATH_UPDATE); + } + + public DiffTool getIdeaDiffTool() { return INTERNAL_DIFF; } + + public DiffTool getDiffTool() { + DiffTool[] standardTools = new DiffTool[]{ + ExtCompareFolders.INSTANCE, + ExtCompareFiles.INSTANCE, + INTERNAL_DIFF, + new MergeTool(), + BinaryDiffTool.INSTANCE + }; + ArrayList allTools = new ArrayList(myAdditionTools); + for (int i = 0; i < standardTools.length; i++) { + DiffTool standardTool = standardTools[i]; + allTools.add(standardTool); + } + return new CompositeDiffTool(allTools); + } + + public boolean registerDiffTool(DiffTool tool) throws NullPointerException { + if (tool == null) throw new NullPointerException("tool==null"); + if (myAdditionTools.contains(tool)) return false; + myAdditionTools.add(tool); + return true; + } + + public void unregisterDiffTool(DiffTool tool) { + myAdditionTools.remove(tool); + LOG.assertTrue(!myAdditionTools.contains(tool)); + } + + public MarkupEditorFilter getDiffEditorFilter() { + return DIFF_EDITOR_FILTER; + } + + public DiffPanel createDiffPanel(Window window, Project project) { + return new DiffPanelImpl(window, project, true); + } + + public static DiffManagerImpl getInstanceEx() { + return (DiffManagerImpl)ApplicationManager.getApplication().getComponent(DiffManager.class); + } + + public void readExternal(Element element) throws InvalidDataException { + myProperties.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + myProperties.writeExternal(element); + } + + AbstractProperty.AbstractPropertyContainer getProperties() { return myProperties; } + + public static DiffPanel createDiffPanel(DiffRequest data, Window window) { + DiffPanel diffPanel = null; + try { + diffPanel = DiffManager.getInstance().createDiffPanel(window, data.getProject()); + int contentCount = data.getContents().length; + LOG.assertTrue(contentCount == 2, String.valueOf(contentCount)); + LOG.assertTrue(data.getContentTitles().length == contentCount); + diffPanel.setDiffRequest(data); + return diffPanel; + } + catch (RuntimeException e) { + if (diffPanel != null) diffPanel.dispose(); + throw e; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffOptionsForm.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffOptionsForm.java new file mode 100644 index 00000000000..ad40631479b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/DiffOptionsForm.java @@ -0,0 +1,109 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.ui.TextComponentAccessor; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.util.config.AbstractProperty; +import com.intellij.util.config.BooleanProperty; +import com.intellij.util.config.StringProperty; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class DiffOptionsForm { + private JComponent myPanel; + // Garbage + private JCheckBox myEnableFolders; + private JCheckBox myEnableFiles; + private TextFieldWithBrowseButton myFoldersTool; + private TextFieldWithBrowseButton myFilesTool; + + private final ToolPath[] myTools = new ToolPath[2]; + + public DiffOptionsForm() { + myTools[0] = new ToolPath(myEnableFolders, myFoldersTool, + DiffManagerImpl.FOLDERS_TOOL, DiffManagerImpl.ENABLE_FOLDERS); + myTools[1] = new ToolPath(myEnableFiles, myFilesTool, DiffManagerImpl.FILES_TOOL, + DiffManagerImpl.ENABLE_FILES); + } + + public JComponent createComponent() { + return myPanel; + } + + public boolean isModified() { + for (int i = 0; i < myTools.length; i++) { + ToolPath tool = myTools[i]; + if (tool.isModifier()) return true; + } + return false; + } + + public void apply() { + for (int i = 0; i < myTools.length; i++) { + ToolPath tool = myTools[i]; + tool.apply(); + } + } + + public void reset() { + for (int i = 0; i < myTools.length; i++) { + ToolPath tool = myTools[i]; + tool.reset(); + } + } + + private static class ToolPath { + private final JCheckBox myCheckBox; + private final TextFieldWithBrowseButton myTextField; + private final StringProperty myPathProperty; + private final BooleanProperty myEnabledProperty; + + public ToolPath(JCheckBox checkBox, TextFieldWithBrowseButton textField, + StringProperty pathProperty, BooleanProperty enabledProperty) { + myCheckBox = checkBox; + myTextField = textField; + myPathProperty = pathProperty; + myEnabledProperty = enabledProperty; + final ButtonModel model = myCheckBox.getModel(); + model.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateEnabledEffect(); + } + }); + myTextField.addBrowseFolderListener("Select External Diff Program", null, null, + FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(), + TextComponentAccessor.TEXT_FIELD_SELECTED_TEXT); + } + + private void updateEnabledEffect() { + myTextField.setEditable(isEnabled()); + } + + public boolean isModifier() { + AbstractProperty.AbstractPropertyContainer properties = getProperties(); + return !myTextField.getText().equals(myPathProperty.get(properties)) || + isEnabled() != myEnabledProperty.value(properties); + } + + private boolean isEnabled() { + return myCheckBox.getModel().isSelected(); + } + + private AbstractProperty.AbstractPropertyContainer getProperties() { + return DiffManagerImpl.getInstanceEx().getProperties(); + } + + public void apply() { + myPathProperty.set(getProperties(), myTextField.getText()); + myEnabledProperty.primSet(getProperties(), isEnabled()); + } + + public void reset() { + myTextField.setText(myPathProperty.get(getProperties())); + myCheckBox.getModel().setSelected(myEnabledProperty.value(getProperties())); + updateEnabledEffect(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java new file mode 100644 index 00000000000..859d02e41d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java @@ -0,0 +1,106 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +class ExtCompareFiles extends BaseExternalTool { + public static final BaseExternalTool INSTANCE = new ExtCompareFiles(); + private ExtCompareFiles() { + super(DiffManagerImpl.ENABLE_FILES, DiffManagerImpl.FILES_TOOL); + } + + public boolean canShow(DiffRequest request) { + DiffContent[] contents = request.getContents(); + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + VirtualFile file = getLocalFile(content.getFile()); + if (file != null && file.isDirectory()) return false; + if (canExternalizeAsFile(file)) continue; + if (DiffUtil.isWriatable(content)) return false; + } + return super.canShow(request); + } + + protected BaseExternalTool.ContentExternalizer externalize(final DiffRequest request, final int index) { + VirtualFile file = getLocalFile(request.getContents()[index].getFile()); + if (canExternalizeAsFile(file)) return LocalFileExternalizer.tryCreate(file); + return new MyContentExternalizer(request, index); + } + + private boolean canExternalizeAsFile(VirtualFile file) { + if (file == null || file.isDirectory()) return false; + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + if (fileType.isBinary() && fileType != StdFileTypes.UNKNOWN) return false; + return true; + } + + private static class MyContentExternalizer implements BaseExternalTool.ContentExternalizer { + private final DiffRequest myRequest; + private final int myIndex; + public static final String STD_PREFIX = "IJDiff"; + + public MyContentExternalizer(DiffRequest request, int index) { + myRequest = request; + myIndex = index; + } + + public File getContentFile() throws IOException { + String extension = chooseExtension(); + String name = chooseName(); + if (name.length() <= 3) name = "___" + name; + File tempFile; + try { + tempFile = File.createTempFile(name, extension); + } + catch (IOException e) { + tempFile = File.createTempFile(STD_PREFIX, extension); + } + FileOutputStream stream = null; + try { + stream = new FileOutputStream(tempFile); + stream.write(getContent().getBytes()); + } finally { + if (stream != null) stream.close(); + } + return tempFile; + } + + private String chooseName() { + String title = myRequest.getContentTitles()[myIndex]; + char[] chars = title.toCharArray(); + for (int i = 0; i < chars.length; i++) { + char aChar = chars[i]; + if (!Character.isLetterOrDigit(aChar)) chars[i] = '_'; + } + return new String(chars); + } + + private String chooseExtension() { + DiffContent content = getContent(); + VirtualFile contentFile = content.getFile(); + String extension; + if (contentFile != null) { + extension = "." + contentFile.getExtension(); + } + else { + FileType contentType = content.getContentType(); + if (contentType == null) contentType = DiffUtil.chooseContentTypes(myRequest.getContents())[myIndex]; + extension = contentType != null ? "." + contentType.getDefaultExtension() : null; + } + return extension; + } + + private DiffContent getContent() { + return myRequest.getContents()[myIndex]; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java new file mode 100644 index 00000000000..ee789ad1b66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.vfs.VirtualFile; + +class ExtCompareFolders extends BaseExternalTool { + public static final BaseExternalTool INSTANCE = new ExtCompareFolders(); + private ExtCompareFolders() { + super(DiffManagerImpl.ENABLE_FOLDERS, DiffManagerImpl.FOLDERS_TOOL); + } + + protected BaseExternalTool.ContentExternalizer externalize(DiffRequest request, int index) { + VirtualFile file = request.getContents()[index].getFile(); + if (!isLocalDirectory(file)) return null; + return LocalFileExternalizer.tryCreate(file); + } + + private boolean isLocalDirectory(VirtualFile file) { + file = getLocalFile(file); + return file != null && file.isDirectory(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/FrameDiffTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/FrameDiffTool.java new file mode 100644 index 00000000000..ab7d8152676 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/external/FrameDiffTool.java @@ -0,0 +1,110 @@ +package com.intellij.openapi.diff.impl.external; + +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffPanel; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffTool; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.FrameWrapper; +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.ex.MessagesEx; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; + +// Author: dyoma + +class FrameDiffTool implements DiffTool { + public void show(DiffRequest request) { + Collection hints = request.getHints(); + boolean shouldOpenDialog = shouldOpenDialog(hints); + if (shouldOpenDialog) { + DialogBuilder builder = new DialogBuilder(request.getProject()); + DiffPanelImpl diffPanel = createDiffPanelIfShouldShow(request, builder.getWindow()); + if (diffPanel == null) return; + builder.setCenterPanel(diffPanel.getComponent()); + builder.addDisposable(diffPanel); + builder.setPreferedFocusComponent(diffPanel.getPreferredFocusedComponent()); + builder.removeAllActions(); + builder.setTitle(request.getWindowTitle()); + builder.setDimensionServiceKey(request.getGroupKey()); + showDiffDialog(builder, hints); + } else { + FrameWrapper frameWrapper = new FrameWrapper(request.getGroupKey()); + DiffPanelImpl diffPanel = createDiffPanelIfShouldShow(request, frameWrapper.getFrame()); + if (diffPanel == null) return; + frameWrapper.setTitle(request.getWindowTitle()); + DiffUtil.initDiffFrame(frameWrapper, diffPanel); + frameWrapper.show(); + } + } + + private DiffPanelImpl createDiffPanelIfShouldShow(DiffRequest request, Window window) { + DiffPanelImpl diffPanel = (DiffPanelImpl)DiffManagerImpl.createDiffPanel(request, window); + if (checkNoDifferenceAndNotify(diffPanel, request)) { + diffPanel.dispose(); + diffPanel = null; + } + return diffPanel; + } + + private void showDiffDialog(DialogBuilder builder, Collection hints) { + builder.showModal(!hints.contains(DiffTool.HINT_SHOW_NOT_MODAL_DIALOG)); + } + + private boolean shouldOpenDialog(Collection hints) { + if (hints.contains(DiffTool.HINT_SHOW_MODAL_DIALOG)) return true; + if (hints.contains(DiffTool.HINT_SHOW_NOT_MODAL_DIALOG)) return true; + if (hints.contains(DiffTool.HINT_SHOW_FRAME)) return false; + return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow() instanceof JDialog; + } + + private boolean checkNoDifferenceAndNotify(DiffPanel diffPanel, DiffRequest data) { + if (!diffPanel.hasDifferences()) { + return !askForceOpenDiff(data); + } + return false; + } + + private boolean askForceOpenDiff(DiffRequest data) { + String title1 = data.getContentTitles()[0]; + String title2 = data.getContentTitles()[1]; + byte[] bytes1; + byte[] bytes2; + try { + bytes1 = data.getContents()[0].getBytes(); + bytes2 = data.getContents()[1].getBytes(); + } + catch (IOException e) { + MessagesEx.error(data.getProject(), e.getMessage()).showNow(); + return false; + } + String message; + if (Arrays.equals(bytes1, bytes2)) + message = title1 + " and " + title2 + " are identical"; + else + message = title1 + " and " + title2 + " have differences only in line separators"; + Messages.showInfoMessage(data.getProject(), message, "No Differences"); + return false; + //return Messages.showDialog(data.getProject(), message + "\nShow diff anyway?", "No Differences", new String[]{"Yes", "No"}, 1, + // Messages.getQuestionIcon()) == 0; + } + + public boolean canShow(DiffRequest data) { + DiffContent[] contents = data.getContents(); + if (contents.length != 2) return false; + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + if (content.isBinary()) return false; + VirtualFile file = content.getFile(); + if (file != null && file.isDirectory()) return false; + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/Fragment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/Fragment.java new file mode 100644 index 00000000000..090e061dd43 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/Fragment.java @@ -0,0 +1,18 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diff.impl.highlighting.DiffMarkup; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; + +public interface Fragment { + TextDiffType getType(); + TextRange getRange(FragmentSide side); + + Fragment shift(TextRange range1, TextRange range2, int startingLine1, int startingLine2); + + void highlight(DiffMarkup appender1, DiffMarkup appender2, boolean isLast); + + Fragment getSubfragmentAt(int offset, FragmentSide side, Condition condition); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentList.java new file mode 100644 index 00000000000..f40c88f119e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentList.java @@ -0,0 +1,37 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.containers.EmptyIterator; + +import java.util.Iterator; + +public interface FragmentList { + FragmentList shift(TextRange rangeShift1, TextRange rangeShift2, + int startLine1, int startLine2); + + FragmentList EMPTY = new FragmentList() { + public FragmentList shift(TextRange rangeShift1, TextRange rangeShift2, int startLine1, int startLine2) { + return EMPTY; + } + + public boolean isEmpty() { + return true; + } + + public Iterator iterator() { + return new EmptyIterator(); + } + + public Fragment getFragmentAt(int offset, FragmentSide side, Condition condition) { + return null; + } + }; + + boolean isEmpty(); + + Iterator iterator(); + + Fragment getFragmentAt(int offset, FragmentSide side, Condition condition); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentListImpl.java new file mode 100644 index 00000000000..af336a3e68c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/FragmentListImpl.java @@ -0,0 +1,87 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +public class FragmentListImpl implements FragmentList { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.fragments.FragmentList"); + private final ArrayList myFragments; + + private FragmentListImpl(ArrayList sortedFragments) { + myFragments = (ArrayList)sortedFragments; + } + + private void init() { + Collections.sort(myFragments, FRAGMENT_COMPARATOR); + myFragments.trimToSize(); + } + + public static FragmentList fromList(ArrayList fragments) { + FragmentListImpl fragmentList = new FragmentListImpl(fragments); + fragmentList.init(); + return fragmentList; + } + + public FragmentList shift(TextRange rangeShift1, TextRange rangeShift2, + int startLine1, int startLine2) { + return new FragmentListImpl(shift(myFragments, rangeShift1, rangeShift2, startLine1, startLine2)); + } + + public boolean isEmpty() { + return myFragments.isEmpty(); + } + + public Iterator iterator() { + return myFragments.iterator(); + } + + public Fragment getFragmentAt(int offset, FragmentSide side, Condition condition) { + for (Iterator iterator = iterator(); iterator.hasNext();) { + Fragment fragment = iterator.next(); + TextRange range = fragment.getRange(side); + if (range.getStartOffset() <= offset && + range.getEndOffset() > offset && + condition.value(fragment)) return fragment.getSubfragmentAt(offset, side, condition); + } + return null; + } + + public static ArrayList shift(ArrayList fragments, TextRange rangeShift1, TextRange rangeShift2, + int startLine1, int startLine2) { + ArrayList newFragments = new ArrayList(fragments.size()); + for (Iterator iterator = fragments.iterator(); iterator.hasNext();) { + Fragment fragment = iterator.next(); + newFragments.add(fragment.shift(rangeShift1, rangeShift2, startLine1, startLine2)); + } + return newFragments; + } + + private static final Comparator FRAGMENT_COMPARATOR = new Comparator() { + public int compare(Fragment fragment1, Fragment fragment2) { + int result = compareBySide(fragment1, fragment2, FragmentSide.SIDE1); + int check = compareBySide(fragment1, fragment2, FragmentSide.SIDE2); + LOG.assertTrue(result == 0 || check == 0 || sign(result) == sign(check)); + return result; + } + }; + + private static int sign(int n) { + if (n == 0) + return 0; + else + return n > 0 ? 1 : -1; + } + + private static int compareBySide(Fragment fragment1, Fragment fragment2, FragmentSide side) { + int start1 = fragment1.getRange(side).getStartOffset(); + int start2 = fragment2.getRange(side).getStartOffset(); + return start1 - start2; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/InlineFragment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/InlineFragment.java new file mode 100644 index 00000000000..9a7ee890092 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/InlineFragment.java @@ -0,0 +1,51 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.DiffMarkup; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; + +import java.security.InvalidParameterException; + +public class InlineFragment implements Fragment { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.fragments.InlineFragment"); + private final TextRange myRange1; + private final TextRange myRange2; + private final TextDiffType myType; + + public InlineFragment(TextDiffType type, TextRange range1, TextRange range2) { + myType = type; + myRange1 = range1; + myRange2 = range2; + } + + public TextDiffType getType() { + return myType; + } + + public TextRange getRange(FragmentSide side) { + if (side == FragmentSide.SIDE1) return myRange1; + if (side == FragmentSide.SIDE2) return myRange2; + throw new InvalidParameterException(String.valueOf(side)); + } + + public Fragment shift(TextRange range1, TextRange range2, int startingLine1, int startingLine2) { + return new InlineFragment(myType, + LineFragment.shiftRange(range1, myRange1), + LineFragment.shiftRange(range2, myRange2)); + } + + public void highlight(DiffMarkup appender1, DiffMarkup appender2, boolean isLast) { + appender1.highlightText(this, true); + appender2.highlightText(this, true); + } + + public Fragment getSubfragmentAt(int offset, FragmentSide side, Condition condition) { + LOG.assertTrue(getRange(side).getStartOffset() <= offset && + offset < getRange(side).getEndOffset() && + condition.value(this)); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineBlock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineBlock.java new file mode 100644 index 00000000000..fe84bf1f04f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineBlock.java @@ -0,0 +1,55 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diff.impl.util.TextDiffType; + +import java.util.Comparator; + +public class LineBlock { + private final int myStartingLine1; + private final int myModifiedLines1; + private final int myStartingLine2; + private final int myModifiedLines2; + private final TextDiffType myType; + + public LineBlock(int startingLine1, int modifiedLines1, int startingLine2, int modifiedLines2, TextDiffType blockType) { + myStartingLine1 = startingLine1; + myModifiedLines1 = modifiedLines1; + myStartingLine2 = startingLine2; + myModifiedLines2 = modifiedLines2; + myType = blockType; + } + + public int getModifiedLines1() { + return myModifiedLines1; + } + + public int getStartingLine1() { + return myStartingLine1; + } + + public int getStartingLine2() { + return myStartingLine2; + } + + public int getModifiedLines2() { + return myModifiedLines2; + } + + protected int getEndLine1() { + return myStartingLine1 + myModifiedLines1; + } + + protected int getEndLine2() { + return myStartingLine2 + myModifiedLines2; + } + + public static final Comparator COMPARATOR = new Comparator() { + public int compare(LineBlock block1, LineBlock block2) { + return block1.getStartingLine1() - block2.getStartingLine1(); + } + }; + + public TextDiffType getType() { + return myType; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineFragment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineFragment.java new file mode 100644 index 00000000000..25c73edb01e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/fragments/LineFragment.java @@ -0,0 +1,179 @@ +package com.intellij.openapi.diff.impl.fragments; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffColors; +import com.intellij.openapi.diff.actions.MergeOperations; +import com.intellij.openapi.diff.impl.highlighting.DiffMarkup; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; + +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Iterator; + +public class LineFragment extends LineBlock implements Fragment { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.fragments.LineFragment"); + private final TextRange myRange1; + private final TextRange myRange2; + private FragmentList myChildren; + private boolean myHasLineChildren; + + public LineFragment(int startingLine1, int modifiedLines1, + int startingLine2, int modifiedLines2, + TextDiffType blockType, TextRange range1, TextRange range2) { + this(startingLine1, modifiedLines1, + startingLine2, modifiedLines2, + blockType, range1, range2, FragmentList.EMPTY); + } + + private LineFragment(int startingLine1, int modifiedLines1, + int startingLine2, int modifiedLines2, + TextDiffType blockType, TextRange range1, TextRange range2, FragmentList children) { + super(startingLine1, modifiedLines1, startingLine2, modifiedLines2, blockType); + LOG.assertTrue(modifiedLines1 > 0 || modifiedLines2 > 0); + myRange1 = range1; + myRange2 = range2; + myChildren = children; + checkChildren(myChildren.iterator()); + } + + + public TextRange getRange(FragmentSide side) { + if (side == FragmentSide.SIDE1) return myRange1; + if (side == FragmentSide.SIDE2) return myRange2; + throw new InvalidParameterException(String.valueOf(side)); + } + + public Fragment shift(TextRange range1, TextRange range2, int startingLine1, int startingLine2) { + return new LineFragment(startingLine1 + getStartingLine1(), getModifiedLines1(), + startingLine2 + getStartingLine2(), getModifiedLines2(), + getType(), shiftRange(range1, myRange1), shiftRange(range2, myRange2), + myChildren.shift(range1, range2, startingLine1, startingLine2)); + } + + static TextRange shiftRange(TextRange shift, TextRange range) { + int start = shift.getStartOffset(); + int newEnd = start + range.getEndOffset(); + int newStart = start + range.getStartOffset(); + LOG.assertTrue(newStart <= shift.getEndOffset()); + LOG.assertTrue(newEnd <= shift.getEndOffset()); + return new TextRange(newStart, newEnd); + } + + public void highlight(DiffMarkup wrapper1, DiffMarkup wrapper2, boolean isLast) { + addModifyActions(wrapper1, wrapper2); + if (myChildren.isEmpty()) { + wrapper1.highlightText(this, false); + wrapper2.highlightText(this, false); + } + else { + for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { + Fragment fragment = iterator.next(); + fragment.highlight(wrapper1, wrapper2, !iterator.hasNext()); + } + } + if (isEqual() && isLast) return; + addBottomLine(wrapper1, getEndLine1()); + addBottomLine(wrapper2, getEndLine2()); + } + + private void addModifyActions(DiffMarkup wrapper, DiffMarkup otherWrapper) { + if (isEqual()) return; + if (myHasLineChildren) return; + TextRange range = getRange(wrapper.getSide()); + TextRange otherRange = getRange(wrapper.getSide().otherSide()); + Document document = wrapper.getDocument(); + Document otherDocument = otherWrapper.getDocument(); + wrapper.addAction(MergeOperations.mostSensible(document, otherDocument, range, otherRange), range.getStartOffset()); + otherWrapper.addAction(MergeOperations.mostSensible(otherDocument, document, otherRange, range), otherRange.getStartOffset()); + } + + private void addBottomLine(DiffMarkup appender, int endLine) { + if (endLine <= 0) return; + TextRange range = getRange(appender.getSide()); + appender.addLineMarker(endLine - 1, getRangeType(range)); + } + + private TextAttributesKey getRangeType(TextRange range) { + if (range.getLength() == 0) return DiffColors.DIFF_DELETED; + return getType() == null ? null : DiffColors.DIFF_MODIFIED; + } + + public boolean isOneSide() { + return myRange1.getLength() == 0 || myRange2.getLength() == 0; + } + + public boolean isEqual() { + return getType() == null; + } + + public Fragment getSubfragmentAt(int offset, FragmentSide side, Condition condition) { + Fragment childFragment = myChildren.getFragmentAt(offset, side, condition); + return childFragment != null ? childFragment : this; + } + + public String getText(String text, FragmentSide side) { + TextRange range = getRange(side); + return text.substring(range.getStartOffset(), range.getEndOffset()); + } + + + public void addAllDescendantsTo(ArrayList descendants) { + if (myChildren == null) return; + for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { + Fragment fragment = iterator.next(); + if (fragment instanceof LineFragment) { + LineFragment lineFragment = (LineFragment)fragment; + descendants.add(lineFragment); + lineFragment.addAllDescendantsTo(descendants); + } + } + } + + public void setChildren(ArrayList fragments) { + LOG.assertTrue(myChildren == FragmentList.EMPTY); + ArrayList shifted = + FragmentListImpl.shift(fragments, myRange1, myRange2, getStartingLine1(), getStartingLine2()); + if (shifted.size() == 0) return; + Fragment firstChild = shifted.get(0); + if (shifted.size() == 1 && isSameRanges(firstChild)) { + if (!(firstChild instanceof LineFragment)) return; + LineFragment lineFragment = (LineFragment)firstChild; + myChildren = lineFragment.myChildren; + } else myChildren = FragmentListImpl.fromList(shifted); + checkChildren(myChildren.iterator()); + } + + private void checkChildren(Iterator iterator) { + if (myChildren.isEmpty()) { + myHasLineChildren = false; + return; + } + boolean hasLineChildren = false; + boolean hasInlineChildren = false; + for (; iterator.hasNext();) { + Fragment fragment = iterator.next(); + boolean lineChild = fragment instanceof LineFragment; + hasLineChildren |= lineChild; + hasInlineChildren |= !lineChild; + if (lineChild) { + LineFragment lineFragment = (LineFragment)fragment; + LOG.assertTrue(getStartingLine1() != lineFragment.getStartingLine1() || + getModifiedLines1() != lineFragment.getModifiedLines1() || + getStartingLine2() != lineFragment.getStartingLine2() || + getModifiedLines2() != lineFragment.getModifiedLines2()); + } + } + LOG.assertTrue(hasLineChildren ^ hasInlineChildren); + myHasLineChildren = hasLineChildren; + } + + private boolean isSameRanges(Fragment fragment) { + return getRange(FragmentSide.SIDE1).equals(fragment.getRange(FragmentSide.SIDE1)) && + getRange(FragmentSide.SIDE2).equals(fragment.getRange(FragmentSide.SIDE2)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/BufferedStringList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/BufferedStringList.java new file mode 100644 index 00000000000..f0166b53e2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/BufferedStringList.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import java.util.ArrayList; + +class BufferedStringList { + private final ArrayList myStrings = new ArrayList(); + private final StringBuffer myLast = new StringBuffer(); + + public void add(String string) { + flushLast(); + myStrings.add(string); + } + + public void appendToLast(String string) { + myLast.append(string); + } + + public void flushLast() { + if (myLast.length() > 0) { + myStrings.add(myLast.toString()); + myLast.setLength(0); + } + } + + public String[] toArray() { + flushLast(); + return myStrings.toArray(new String[myStrings.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java new file mode 100644 index 00000000000..87ffea02c95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java @@ -0,0 +1,199 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffColors; +import com.intellij.openapi.diff.actions.MergeActionGroup; +import com.intellij.openapi.diff.actions.MergeOperations; +import com.intellij.openapi.diff.impl.EditorSource; +import com.intellij.openapi.diff.impl.fragments.Fragment; +import com.intellij.openapi.diff.impl.util.GutterActionRenderer; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.containers.HashSet; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public abstract class DiffMarkup implements EditorSource { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.openapi.diff.impl.highlighting.EditorTextAppender"); + private static final int LAYER = HighlighterLayer.SELECTION - 1; + + private final ArrayList myHighLighters = new ArrayList(); + private final HashSet myActionHighlighters = new HashSet(); + private final Project myProject; + private final ArrayList myDisposables = new ArrayList(); + private boolean myDisposed = false; + + protected DiffMarkup(Project project) { + myProject = project; + } + + private MarkupModel getMarkupModel() { + Editor editor = getEditor(); + return editor == null ? null : editor.getMarkupModel(); + } + + public void highlightText(Fragment fragment, boolean drawBorder) { + TextDiffType type = fragment.getType(); + if (type == null) return; + TextRange range = fragment.getRange(getSide()); + TextAttributes attributes = type.getTextAttributes(getEditor()); + RangeHighlighter rangeMarker; + if (!drawBorder && range.getLength() == 0) return; + if (drawBorder && range.getLength() == 0) { + rangeMarker = getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getStartOffset(), LAYER, + new TextAttributes(null, null, attributes.getBackgroundColor(), + EffectType.BOXED, 0), + HighlighterTargetArea.EXACT_RANGE); + } + else { + rangeMarker = getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), LAYER, + attributes, HighlighterTargetArea.EXACT_RANGE); + } + Color stripeBarColor = attributes.getErrorStripeColor(); + if (stripeBarColor != null) rangeMarker.setErrorStripeMarkColor(stripeBarColor); + saveHighlighter(rangeMarker); + } + + public void addLineMarker(int line, TextAttributesKey type) { + RangeHighlighter marker = createLineMarker(type, line); + if (marker == null) return; + saveHighlighter(marker); + marker.setLineMarkerRenderer(LineRenderer.bottom()); + } + + private RangeHighlighter createLineMarker(TextAttributesKey type, int line) { + RangeHighlighter marker; + Color color = getLineSeparatorColorForType(type); + RangeHighlighter lastHighlighter = getLastHighlighter(); + if (lastHighlighter != null && + lastHighlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE && + SeparatorPlacement.BOTTOM == lastHighlighter.getLineSeparatorPlacement()) { + int lastLine = getDocument().getLineNumber(lastHighlighter.getStartOffset()); + LOG.assertTrue(lastLine <= line); + if (lastLine == line) { + Color lastLineColor = lastHighlighter.getLineSeparatorColor(); + if (color == Color.GRAY || lastLineColor != Color.GRAY) { + return null; + } + else { + removeHighlighter(lastHighlighter); + } + } + } + marker = getMarkupModel().addLineHighlighter(line, LAYER, null); +// saveHighlighter(marker); + marker.setLineSeparatorColor(color); + marker.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM); + // TODO[dyoma] type should be policy + if (type == DiffColors.DIFF_DELETED) marker.setErrorStripeMarkColor(color); + return marker; + } + + private void removeHighlighter(RangeHighlighter highlighter) { + getMarkupModel().removeHighlighter(highlighter); + myHighLighters.remove(highlighter); + myActionHighlighters.remove(highlighter); + } + + private Color getLineSeparatorColorForType(TextAttributesKey type) { + LOG.assertTrue(type == DiffColors.DIFF_DELETED || type == DiffColors.DIFF_MODIFIED || type == null); + if (type == null || type == DiffColors.DIFF_MODIFIED) return Color.GRAY; + return TextDiffType.DELETED.getTextBackground(getEditor()); + } + + private RangeHighlighter getLastHighlighter() { + int size = myHighLighters.size(); + return size > 0 ? myHighLighters.get(size - 1) : null; + } + + private void saveHighlighter(RangeHighlighter marker) { + LOG.assertTrue(marker != null); + myHighLighters.add(marker); + } + + public Document getDocument() { + return getEditor().getDocument(); + } + + public void addAction(final MergeOperations.Operation operation, int lineStartOffset) { + RangeHighlighter highlighter = createAction(operation, lineStartOffset); + if (highlighter != null) { + myActionHighlighters.add(highlighter); + } + } + + private RangeHighlighter createAction(final MergeOperations.Operation operation, int lineStartOffset) { + if (operation == null) return null; + RangeHighlighter highlighter = + getMarkupModel().addRangeHighlighter(lineStartOffset, lineStartOffset, + HighlighterLayer.ADDITIONAL_SYNTAX, + new TextAttributes(null, null, null, null, 0), + HighlighterTargetArea.LINES_IN_RANGE); + final MergeActionGroup.OperationAction action = new MergeActionGroup.OperationAction(operation); + highlighter.setGutterIconRenderer(new GutterActionRenderer(action)); + return highlighter; + } + + public void resetHighlighters() { + removeHighlighters(myHighLighters); + removeHighlighters(myActionHighlighters); + } + + private void removeHighlighters(Collection highlighters) { + MarkupModel markupModel = getMarkupModel(); + if (markupModel != null) { + for (Iterator iterator = highlighters.iterator(); iterator.hasNext();) { + RangeHighlighter highlighter = iterator.next(); + markupModel.removeHighlighter(highlighter); + } + } + highlighters.clear(); + } + + protected Project getProject() { + return myProject; + } + + protected void disposeEditor() { + resetHighlighters(); + for (Iterator iterator = myDisposables.iterator(); iterator.hasNext();) { + Disposeable disposeable = iterator.next(); + disposeable.dispose(); + } + myDisposables.clear(); + } + + public void addDisposable(Disposeable disposeable) { + myDisposables.add(disposeable); + } + + public String getText() { + return getDocument().getText(); + } + + protected final boolean isDisposed() { return myDisposed; } + + public final void dispose() { + if (isDisposed()) return; + doDispose(); + myDisposed = true; + } + + protected void doDispose() { + disposeEditor(); + } + + public void removeActions() { + removeHighlighters(myActionHighlighters); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java new file mode 100644 index 00000000000..66e03a6efe1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.impl.ContentChangeListener; +import com.intellij.openapi.project.Project; + +public class DiffPanelState extends SimpleDiffPanelState { + public DiffPanelState(ContentChangeListener changeListener, Project project) { + super(createEditorWrapper(project, changeListener, FragmentSide.SIDE1), + createEditorWrapper(project, changeListener, FragmentSide.SIDE2), project); + } + + private static EditorPlaceHolder createEditorWrapper(Project project, ContentChangeListener changeListener, FragmentSide side) { + EditorPlaceHolder editorWrapper = new EditorPlaceHolder(side, project); + editorWrapper.addListener(changeListener); + return editorWrapper; + } + + public void setContents(final DiffContent content1, final DiffContent content2) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myAppender1.setContent(content1); + myAppender2.setContent(content2); + } + }); + } + + public DiffContent getContent2() { + return myAppender2.getContent(); + } + + public void removeActions() { + myAppender1.removeActions(); + myAppender2.removeActions(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java new file mode 100644 index 00000000000..dded561af16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java @@ -0,0 +1,72 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.impl.ContentChangeListener; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.DiffVersionComponent; +import com.intellij.openapi.diff.impl.util.ContentDocumentListener; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.project.Project; + +class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.highlighting.EditorWrapper"); + private EditorEx myEditor; + private DiffContent myContent; + private final FragmentSide mySide; + private ContentChangeListener myListener = null; + + public EditorPlaceHolder(FragmentSide side, Project project) { + super(project); + mySide = side; + resetHighlighters(); + } + + public void addListener(ContentChangeListener listener) { + LOG.assertTrue(myListener == null); + myListener = listener; + } + + protected void doDispose() { + LOG.assertTrue(!isDisposed()); + super.doDispose(); + fireContentChanged(); + } + + private void fireContentChanged() { + myListener.onContentChangedIn(this); + } + + public void setContent(final DiffContent content) { + disposeEditor(); + myContent = content; + if (myContent != null) { + Document document = myContent.getDocument(); + final EditorFactory editorFactory = EditorFactory.getInstance(); + myEditor = DiffUtil.createEditor(document, getProject(), false); + addDisposable(new Disposeable() { + public void dispose() { + editorFactory.releaseEditor(myEditor); + myEditor = null; + } + }); + ContentDocumentListener.install(myContent, this); + } + fireContentChanged(); + } + + public EditorEx getEditor() { return myEditor; } + + public FragmentSide getSide() { return mySide; } + + public DiffContent getContent() { + return myContent; + } + + public void removeContent() { + setContent(null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java new file mode 100644 index 00000000000..54a42287ee0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java @@ -0,0 +1,85 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; + +import java.security.InvalidParameterException; + +public abstract class FragmentSide { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.highlighting.FragmentSide"); + public abstract String getText(DiffFragment fragment); + public abstract DiffFragment createFragment(String text, String otherText, boolean modified); + public abstract FragmentSide otherSide(); + public abstract int getIndex(); + public abstract int getMergeIndex(); + + public String getOtherText(DiffFragment fragment) { + return otherSide().getText(fragment); + } + + public InvalidParameterException invalidException() { + return new InvalidParameterException(String.valueOf(this)); + } + + public static final FragmentSide SIDE1 = new FragmentSide() { + public String getText(DiffFragment fragment) { + return fragment.getText1(); + } + + public DiffFragment createFragment(String text, String otherText, boolean modified) { + DiffFragment fragment = new DiffFragment(text, otherText); + if (!fragment.isOneSide()) fragment.setModified(modified); + return fragment; + } + + public FragmentSide otherSide() { + return SIDE2; + } + + public int getIndex() { + return 0; + } + + public int getMergeIndex() { + return 0; + } + }; + + public static final FragmentSide SIDE2 = new FragmentSide() { + public String getText(DiffFragment fragment) { + return fragment.getText2(); + } + + public DiffFragment createFragment(String text, String otherText, boolean modified) { + DiffFragment fragment = new DiffFragment(otherText, text); + if (!fragment.isOneSide()) fragment.setModified(modified); + return fragment; + } + + public FragmentSide otherSide() { + return SIDE1; + } + + public int getIndex() { + return 1; + } + + public int getMergeIndex() { + return 2; + } + }; + + public static FragmentSide chooseSide(DiffFragment oneSide) { + LOG.assertTrue(oneSide.isOneSide()); + LOG.assertTrue(oneSide.getText1() != oneSide.getText2()); + return oneSide.getText1() == null ? SIDE2 : SIDE1; + } + + public static FragmentSide fromIndex(int index) { + switch (index) { + case 0: return SIDE1; + case 1: return SIDE2; + default: throw new InvalidParameterException(String.valueOf(index)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineBlockDivider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineBlockDivider.java new file mode 100644 index 00000000000..568a6169b0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineBlockDivider.java @@ -0,0 +1,35 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.util.text.StringUtil; + +public abstract class LineBlockDivider { + public abstract DiffFragment[][] divide(DiffFragment[] lineBlock); + + public static final LineBlockDivider SINGLE_SIDE = new LineBlockDivider() { + public DiffFragment[][] divide(DiffFragment[] lineBlock) { + List2D result = new List2D(); + FragmentSide currentSide = null; + boolean isNewLineLast = true; + for (int i = 0; i < lineBlock.length; i++) { + DiffFragment fragment = lineBlock[i]; + if (!fragment.isOneSide()) { + if (currentSide != null && isNewLineLast) result.newRow(); + isNewLineLast = StringUtil.endsWithChar(fragment.getText1(), '\n') && StringUtil.endsWithChar(fragment.getText2(), '\n'); + currentSide = null; + } else { + FragmentSide side = FragmentSide.chooseSide(fragment); + if (currentSide != side) { + if (isNewLineLast) { + result.newRow(); + currentSide = side; + } else currentSide = null; + } + isNewLineLast = StringUtil.endsWithChar(side.getText(fragment), '\n'); + } + result.add(fragment); + } + return result.toArray(); + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineRenderer.java new file mode 100644 index 00000000000..fbe0ce39ced --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/LineRenderer.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.markup.LineMarkerRenderer; + +import java.awt.*; + +public class LineRenderer implements LineMarkerRenderer { + private final boolean myDrawBottom; + + private LineRenderer(boolean drawBottom) { + myDrawBottom = drawBottom; + } + + public void paint(Editor editor, Graphics g, Rectangle r) { + g.setColor(Color.GRAY); + int y = r.y - 1; + if (myDrawBottom) y += r.height + editor.getLineHeight(); + g.drawLine(0, y, ((EditorEx)editor).getGutterComponentEx().getWidth(), y); + } + + public static LineMarkerRenderer bottom() { + return new LineRenderer(true); + } + + public static LineMarkerRenderer top() { + return new LineRenderer(false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/List2D.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/List2D.java new file mode 100644 index 00000000000..cb8f88d8a75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/List2D.java @@ -0,0 +1,47 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.diff.ex.DiffFragment; + +import java.util.ArrayList; +import java.util.List; + +class List2D { + private final ArrayList myRows = new ArrayList(); + private ArrayList myCurrentRow = null; + + public void add(DiffFragment element) { + ensureRowExists(); + myCurrentRow.add(element); + } + + private void ensureRowExists() { + if (myCurrentRow == null) { + myCurrentRow = new ArrayList(); + myRows.add(myCurrentRow); + } + } + + public void newRow() { + myCurrentRow = null; + } + + // + public DiffFragment[][] toArray() { + + DiffFragment[][] result = new DiffFragment[myRows.size()][]; + for (int i = 0; i < result.length; i++) { + List row = myRows.get(i); + result[i] = new DiffFragment[row.size()]; + System.arraycopy(row.toArray(), 0, result[i], 0, row.size()); + } + return result; + } + + public void addAll(DiffFragment[] line) { + ensureRowExists(); + for (int i = 0; i < line.length; i++) { + DiffFragment value = line[i]; + myCurrentRow.add(value); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java new file mode 100644 index 00000000000..27c8f9dcd5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java @@ -0,0 +1,91 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.fragments.FragmentList; +import com.intellij.openapi.diff.impl.fragments.FragmentListImpl; +import com.intellij.openapi.diff.impl.fragments.LineFragment; +import com.intellij.openapi.diff.impl.processing.TextCompareProcessor; +import com.intellij.openapi.diff.impl.splitter.LineBlocks; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Iterator; + +public class SimpleDiffPanelState implements Disposeable { + private ComparisonPolicy myComparisonPolicy = ComparisonPolicy.DEFAULT; + protected final DiffMarkupType myAppender1; + protected final DiffMarkupType myAppender2; + private FragmentList myFragmentList = FragmentList.EMPTY; + private final Project myProject; + + public SimpleDiffPanelState(DiffMarkupType diffMarkup1, DiffMarkupType diffMarkup2, Project project) { + myAppender1 = diffMarkup1; + myAppender2 = diffMarkup2; + myProject = project; + } + + public void setComparisonPolicy(ComparisonPolicy comparisonPolicy) { + myComparisonPolicy = comparisonPolicy; + } + + public ComparisonPolicy getComparisonPolicy() { + return myComparisonPolicy; + } + + public void dispose() { + myAppender1.dispose(); + myAppender2.dispose(); + } + + private LineBlocks addMarkup(final ArrayList lines) { + resetMarkup(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (Iterator iterator = lines.iterator(); iterator.hasNext();) { + LineFragment line = iterator.next(); + line.highlight(myAppender1, myAppender2, !iterator.hasNext()); + } + } + }); + ArrayList allLineFragments = new ArrayList(); + for (Iterator iterator = lines.iterator(); iterator.hasNext();) { + LineFragment lineFragment = iterator.next(); + allLineFragments.add(lineFragment); + lineFragment.addAllDescendantsTo(allLineFragments); + } + myFragmentList = FragmentListImpl.fromList(allLineFragments); + return LineBlocks.fromLineFragments(allLineFragments); + } + + private void resetMarkup() { + ApplicationManager.getApplication().runWriteAction(new ResetMarkupRunnable(this)); + } + + public LineBlocks updateEditors() { + if (myAppender1.getEditor() == null || myAppender2.getEditor() == null) { + resetMarkup(); + return LineBlocks.EMPTY; + } + + return addMarkup(new TextCompareProcessor(myComparisonPolicy).process(myAppender1.getText(), myAppender2.getText())); + } + + public Project getProject() { return myProject; } + + public FragmentList getFragmentList() { return myFragmentList; } + + private static class ResetMarkupRunnable implements Runnable { + private final SimpleDiffPanelState myState; + + public ResetMarkupRunnable(SimpleDiffPanelState state) { + myState = state; + } + + public void run() { + myState.myAppender1.resetHighlighters(); + myState.myAppender2.resetHighlighters(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/Util.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/Util.java new file mode 100644 index 00000000000..b1b68224385 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/highlighting/Util.java @@ -0,0 +1,327 @@ +package com.intellij.openapi.diff.impl.highlighting; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.diff.Diff; +import gnu.trove.TIntHashSet; + +import java.util.StringTokenizer; + +public class Util { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.highlighting.Util"); + private static final String DELIMITERS = " \n\r\t(){}[],./?`~!@#$%^&*-=+|\\;:'\"<>"; + public static final TIntHashSet DELIMITERS_SET = new TIntHashSet(); + + static { + char[] delimiters = Util.DELIMITERS.toCharArray(); + for (int i = 0; i < delimiters.length; i++) { + char delimiter = delimiters[i]; + Util.DELIMITERS_SET.add(delimiter); + } + } + + static String[] splitByWord(String string) { + BufferedStringList stringList = new BufferedStringList(); + StringTokenizer tokenizer = new StringTokenizer(string, DELIMITERS, true); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if (token.length() == 1 && DELIMITERS_SET.contains(token.charAt(0))) { + char delimiter = token.charAt(0); + if (delimiter == '\n') { + stringList.appendToLast(token); + stringList.flushLast(); + continue; + } + if (Character.isWhitespace(delimiter)) { + stringList.appendToLast(token); + continue; + } + } + stringList.add(token); + } + return stringList.toArray(); + } + + static boolean isSpaceOnly(DiffFragment fragment) { + return isSpaceOnly(fragment.getText1()) && isSpaceOnly(fragment.getText2()); + } + + private static boolean isSpaceOnly(String string) { + if (string == null) return true; + for (int i = 0; i < string.length(); i++) if (!Character.isWhitespace(string.charAt(i))) return false; + return true; + } + + static DiffFragment[] splitByLines(DiffFragment fragment) { + String[] lines1 = splitByLines(fragment.getText1()); + String[] lines2 = splitByLines(fragment.getText2()); + if (lines1 != null && lines2 != null) + LOG.assertTrue(lines1.length == lines2.length, "1:<" + fragment.getText1() + "> 2:<" + fragment.getText2() + ">"); + int length = lines1 == null ? lines2.length : lines1.length; + DiffFragment[] lines = new DiffFragment[length]; + for (int i = 0; i < lines.length; i++) { + lines[i] = new DiffFragment(lines1 == null? null : lines1[i], lines2 == null ? null : lines2[i]); + } + return lines; + } + + private static String[] splitByLines(String string) { + if (string == null) return null; + if (string.indexOf('\n') == -1) return new String[]{string}; + String[] strings = string.split("\n", -1); + for (int i = 0; i < strings.length - 1; i++) { + strings[i] += "\n"; + } + if (StringUtil.endsWithChar(string, '\n')) { + String[] result = new String[strings.length - 1]; + System.arraycopy(strings, 0, result, 0, strings.length - 1); + return result; + } + return strings; + } + + public static DiffFragment[][] splitByUnchangedLines(DiffFragment[] fragments) { + List2D result = new List2D(); + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (!fragment.isEqual()) { + result.add(fragment); + continue; + } + String text1 = fragment.getText1(); + String text2 = fragment.getText2(); + if (StringUtil.endsWithChar(text1, '\n') && StringUtil.endsWithChar(text2, '\n')) { + result.add(fragment); + result.newRow(); + continue; + } + while (true) { + int newLine1 = text1.indexOf('\n'); + int newLine2 = text2.indexOf('\n'); + if (newLine1 == -1 || newLine2 == -1) { + result.add(DiffFragment.unchanged(text1, text2)); + break; + } + result.add(DiffFragment.unchanged(text1.substring(0, newLine1 + 1), text2.substring(0, newLine2 + 1))); + result.newRow(); + text1 = text1.substring(newLine1 + 1); + text2 = text2.substring(newLine2 + 1); + int length1 = text1.length(); + int length2 = text2.length(); + if (length1 == 0 || length2 == 0) { + if (length1 != 0 || length2 != 0) + result.add(DiffFragment.unchanged(text1, text2)); + break; + } + } + } + return result.toArray(); + } + + public static Diff.Change concatEquals(Diff.Change change, Object[] left, Object[] right) { + MyChange startChange = new MyChange(0, 0, 0, 0); + MyChange lastChange = startChange; + while (change != null) { + if (change.inserted > 0 && change.deleted > 0) { + lastChange = lastChange.copyNext(change); + } else if (change.inserted > 0) { + int shift = calcShift(right, lastChange.getEnd2(), change.line1, change.inserted); + lastChange = lastChange.copyNext(change, shift); + } else if (change.deleted > 0) { + int shift = calcShift(left, lastChange.getEnd1(), change.line0, change.deleted); + lastChange = lastChange.copyNext(change, shift); + } else { + LOG.assertTrue(false); + } + change = change.link; + } + return concatSingleSide(startChange.link); + } + + private static Diff.Change concatSingleSide(Diff.Change change) { + MyChange startChange = new MyChange(0, 0, 0, 0); + MyChange lastChange = startChange; + MyChange prevChange = null; + while (change != null) { + if (prevChange == null || (change.inserted > 0 && change.deleted > 0)) { + prevChange = lastChange; + lastChange = lastChange.copyNext(change); + } else { + MyChange newChange = null; + if (change.deleted == 0 && lastChange.deleted == 0 && change.line1 == lastChange.getEnd2()) { + newChange = new MyChange(lastChange.line0, lastChange.line1, 0, lastChange.inserted + change.inserted); + } else if (change.inserted == 0 && lastChange.inserted == 0 && change.line0 == lastChange.getEnd1()) { + newChange = new MyChange(lastChange.line0, lastChange.line1, lastChange.deleted + change.deleted, 0); + } + if (newChange != null) { + prevChange.setNext(newChange); + lastChange = newChange; + } else { + prevChange = lastChange; + lastChange = lastChange.copyNext(change); + } + } + change = change.link; + } + return startChange.link; + } + + static int calcShift(Object[] list, int limit, int start, int length) { + int shift = start - limit; + for (int i = 0; i < shift; i++) { + if (!list[limit + i].equals(list[start + length - shift + i])) return 0; + } + return -shift; + } + + public static DiffFragment unite(DiffFragment fragment1, DiffFragment fragment2) { + LOG.assertTrue(isSameType(fragment1, fragment2)); + if (!fragment1.isOneSide()) { + String unitedText1 = fragment1.getText1() + fragment2.getText1(); + String unitedText2 = fragment1.getText2() + fragment2.getText2(); + LOG.assertTrue(fragment1.isEqual() == fragment2.isEqual()); + return fragment1.isEqual() ? DiffFragment.unchanged(unitedText1, unitedText2) : + new DiffFragment(unitedText1, unitedText2); + } + FragmentSide side = FragmentSide.chooseSide(fragment1); + return side.createFragment(side.getText(fragment1) + side.getText(fragment2), null, fragment1.isModified()); + } + + public static boolean isSameType(DiffFragment fragment1, DiffFragment fragment2) { + if (fragment1.isEqual()) return fragment2.isEqual(); + if (fragment1.isChange()) return fragment2.isChange(); + if (fragment1.getText1() == null) return fragment2.getText1() == null; + if (fragment1.getText2() == null) return fragment2.getText2() == null; + LOG.assertTrue(false); + return false; + } + + public static String getText(DiffFragment[] fragments, FragmentSide side) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + String text = side.getText(fragment); + if (text != null) buffer.append(text); + } + return buffer.toString(); + } + + public static DiffFragment concatenate(DiffFragment[] line) { + return concatenate(line, 0, line.length); + } + + public static DiffFragment concatenate(DiffFragment[] line, int from, int to) { + StringBuffer buffer1 = new StringBuffer(); + StringBuffer buffer2 = new StringBuffer(); + boolean isEqual = true; + for (int j = from; j < to; j++) { + DiffFragment fragment = line[j]; + isEqual &= fragment.isEqual(); + String text1 = fragment.getText1(); + String text2 = fragment.getText2(); + if (text1 != null) buffer1.append(text1); + if (text2 != null) buffer2.append(text2); + } + String text1 = notEmptyContent(buffer1); + String text2 = notEmptyContent(buffer2); + return isEqual ? DiffFragment.unchanged(text1, text2) : new DiffFragment(text1, text2); + } + + private static String notEmptyContent(StringBuffer buffer) { + return buffer.length() > 0 ? buffer.toString() : null; + } + + public static DiffFragment[][] uniteFormattingOnly(DiffFragment[][] lines) { + List2D result = new List2D(); + for (int i = 0; i < lines.length; i++) { + DiffFragment[] line = lines[i]; + if (!areEqual(line) && areEqualOrFormatting(line)) result.addAll(line); + else { + result.newRow(); + result.addAll(line); + result.newRow(); + } + } + return result.toArray(); + } + + private static boolean areEqualOrFormatting(DiffFragment[] fragments) { + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (fragment.isEqual()) continue; + for (int side = 0; side < 2; side++) { + String text = FragmentSide.fromIndex(side).getText(fragment); + if (text == null || text.trim().length() == 0) continue; + return false; + } + } + return true; + } + + private static boolean areEqual(DiffFragment[] fragments) { + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (!fragment.isEqual()) return false; + } + return true; + } + + public static DiffFragment[] cutFirst(DiffFragment[] fragments) { + int nullCount = 0; + for (int sideIndex = 0; sideIndex < 2; sideIndex++) { + FragmentSide side = FragmentSide.fromIndex(sideIndex); + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (fragment == null) continue; + String text = side.getText(fragment); + if (text == null || text.length() == 0) continue; + text = text.length() > 1 ? text.substring(1) : null; + String otherText = side.getOtherText(fragment); + if (otherText == null && text == null) { + fragments[i] = null; + nullCount++; + } else fragments[i] = side.createFragment(text, otherText, fragment.isModified()); + break; + } + } + if (nullCount == 0) return fragments; + DiffFragment[] result = new DiffFragment[fragments.length - nullCount]; + int dstIndex = 0; + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (fragment == null) continue; + result[dstIndex] = fragment; + dstIndex++; + } + return result; + } + + private static class MyChange extends Diff.Change { + public MyChange(int line0, int line1, int deleted, int inserted) { + super(line0, line1, deleted, inserted, null); + } + + public MyChange copyNext(Diff.Change change) { + return copyNext(change, 0); + } + + public MyChange copyNext(Diff.Change change, int shift) { + MyChange result = new MyChange(change.line0 + shift, change.line1 + shift, change.deleted, change.inserted); + setNext(result); + return result; + } + + public void setNext(MyChange change) { + link = change; + } + + public int getEnd1() { + return line0 + deleted; + } + + public int getEnd2() { + return line1 + inserted; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/Change.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/Change.java new file mode 100644 index 00000000000..074c3a64069 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/Change.java @@ -0,0 +1,251 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.DocumentUtil; +import com.intellij.openapi.diff.impl.util.GutterActionRenderer; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; + +public abstract class Change { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.Change"); + + private void apply(FragmentSide original) { + FragmentSide targetSide = original.otherSide(); + RangeMarker originalRangeMarker = getRangeMarker(original); + RangeMarker rangeMarker = getRangeMarker(targetSide); + + if (originalRangeMarker != null && rangeMarker != null) { + getType().apply(originalRangeMarker, rangeMarker); + if (isValid()) { + removeFromList(); + } + } + } + + protected abstract void removeFromList(); + + public void addMarkup(Editor[] editors) { + LOG.assertTrue(editors.length == 2); + highligth(editors, FragmentSide.SIDE1); + highligth(editors, FragmentSide.SIDE2); + } + + private void highligth(Editor[] editors, FragmentSide side) { + getHighlighterHolder(side).highlight(getChangeSide(side), editors[side.getIndex()], this.getType()); + } + + private void updateHighlighter(FragmentSide side) { + getHighlighterHolder(side).updateHighlighter(getChangeSide(side), this.getType()); + } + + private Project getProject() { return getChangeList().getProject(); } + + public abstract ChangeType.ChangeSide getChangeSide(FragmentSide side); + + public abstract ChangeType getType(); + + public abstract ChangeList getChangeList(); + + private HightlighterHolder getHighlighterHolder(FragmentSide side) { + return getChangeSide(side).getHighlighterHolder(); + } + + private RangeMarker getRangeMarker(FragmentSide side) { + ChangeType.ChangeSide changeSide = getChangeSide(side); + LOG.assertTrue(changeSide != null); + return changeSide.getRange(); + } + + public abstract void onRemovedFromList(); + + public abstract boolean isValid(); + + public static void apply(final Change change, final FragmentSide fromSide) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(change.getProject(), new Runnable() { + public void run() { + change.apply(fromSide); + } + }, null, "MergeApply"); + } + }); + } + + public void updateMarkup() { + updateHighlighter(FragmentSide.SIDE1); + updateHighlighter(FragmentSide.SIDE2); + } + + public boolean canHasActions(FragmentSide fromSide) { + FragmentSide targetSide = fromSide.otherSide(); + Document targetDocument = getChangeList().getDocument(targetSide); + if (!targetDocument.isWritable()) return false; + Editor targetEditor = getHighlighterHolder(targetSide).getEditor(); + if (targetEditor.isViewer()) return false; + return true; + } + + public static class ChangeOrder implements Comparator { + private final FragmentSide myMainSide; + + public ChangeOrder(FragmentSide mainSide) { + myMainSide = mainSide; + } + + public int compare(Change change, Change change1) { + int result1 = compareSide(change, change1, myMainSide); + if (result1 != 0) return result1; + return compareSide(change, change1, myMainSide.otherSide()); + } + + private int compareSide(Change change, Change change1, FragmentSide side) { + return DocumentUtil.RANGE_ORDER.compare(change.getRangeMarker(side), change1.getRangeMarker(side)); + } + } + + protected static class HightlighterHolder implements ChangeType.MarkupHolder { + private static final RangeHighlighter[] NO_HIGHLIGHTERS = new RangeHighlighter[0]; + private Editor myEditor; + private final ArrayList myHighlighters = new ArrayList(3); + private RangeHighlighter myMainHighlighter = null; + private AnAction[] myActions; + private RangeHighlighter[] myActionHighlighters = NO_HIGHLIGHTERS; + + public void highlight(ChangeType.ChangeSide changeSide, Editor editor, ChangeType type) { + LOG.assertTrue(myEditor == null || editor == myEditor); + removeHighlighters(); + myEditor = editor; + setHighlighter(changeSide, type); + } + + private MarkupModel getMarkupModel() { + return myEditor.getMarkupModel(); + } + + private void highlighterCreated(RangeHighlighter highlighter, TextAttributes attrs) { + if (attrs != null) { + highlighter.setErrorStripeMarkColor(attrs.getErrorStripeColor()); + } + myHighlighters.add(highlighter); + } + + public RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType) { + RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null); + if (highlighter == null) return null; + highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor)); + highlighterCreated(highlighter, diffType.getTextAttributes(myEditor)); + return highlighter; + } + + public RangeHighlighter addRangeHighlighter(int start, int end, int layer, TextDiffType type, HighlighterTargetArea targetArea) { + if (getMarkupModel().getDocument().getTextLength() == 0) return null; + TextAttributes attributes = type.getTextAttributes(myEditor); + RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea); + highlighterCreated(highlighter, attributes); + return highlighter; + } + + private void setHighlighter(ChangeType.ChangeSide changeSide, ChangeType type) { + myMainHighlighter = type.addMarker(changeSide, this); + updateAction(); + } + + public Editor getEditor() { + return myEditor; + } + + public void removeHighlighters() { + if (myEditor == null) { + LOG.assertTrue(myHighlighters.size() == 0); + LOG.assertTrue(myMainHighlighter == null); + return; + } + MarkupModel markupModel = myEditor.getMarkupModel(); + for (Iterator iterator = myHighlighters.iterator(); iterator.hasNext();) { + RangeHighlighter highlighter = iterator.next(); + markupModel.removeHighlighter(highlighter); + iterator.remove(); + } + removeActionHighlighters(); + myMainHighlighter = null; + } + + private void removeActionHighlighters() { + MarkupModel markupModel = myEditor.getMarkupModel(); + for (int i = 0; i < myActionHighlighters.length; i++) { + markupModel.removeHighlighter(myActionHighlighters[i]); + } + myActionHighlighters = NO_HIGHLIGHTERS; + } + + public void setActions(AnAction[] action) { + myActions = action; + updateAction(); + } + + private void updateAction() { + removeActionHighlighters(); + if (myMainHighlighter != null && myActions != null && myActions.length > 0) { + myActionHighlighters = new RangeHighlighter[myActions.length]; + for (int i = 0; i < myActionHighlighters.length; i++) { + RangeHighlighter highlighter = cloneMainHighlighter(myMainHighlighter); + highlighter.setGutterIconRenderer(new GutterActionRenderer(myActions[i])); + myActionHighlighters[i] = highlighter; + } + } + } + + private RangeHighlighter cloneMainHighlighter(RangeHighlighter mainHighlighter) { + LOG.assertTrue(mainHighlighter != null); + RangeHighlighter highlighter = myEditor.getMarkupModel().addRangeHighlighter(mainHighlighter.getStartOffset(), mainHighlighter.getEndOffset(), mainHighlighter.getLayer(), + null, mainHighlighter.getTargetArea()); + // TODO[dyoma] copy greedyToLeft and greedyToRight + return highlighter; + } + + public void updateHighlighter(ChangeType.ChangeSide changeSide, ChangeType type) { + LOG.assertTrue(myEditor != null); + removeHighlighters(); + setHighlighter(changeSide, type); + } + } + + protected static class Side extends ChangeType.ChangeSide { + private final FragmentSide mySide; + private final DiffRangeMarker myRange; + private final HightlighterHolder myHighlighterHolder = new HightlighterHolder(); + + public Side(FragmentSide side, DiffRangeMarker rangeMarker) { + mySide = side; + myRange = rangeMarker; + } + + public FragmentSide getFragmentSide() { + return mySide; + } + + public DiffRangeMarker getRange() { + return myRange; + } + + public HightlighterHolder getHighlighterHolder() { + return myHighlighterHolder; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeCounter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeCounter.java new file mode 100644 index 00000000000..a4f2f1d2d33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeCounter.java @@ -0,0 +1,74 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; + +import java.util.ArrayList; +import java.util.Iterator; + +public class ChangeCounter implements ChangeList.Listener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.ChangeCounter"); + private static final Key ourKey = Key.create("ChangeCounter"); + private final MergeList myMergeList; + private final ArrayList myListeners = new ArrayList(); + private int myChangeCounter = 0; + private int myConflictCounter = 0; + + private ChangeCounter(MergeList mergeList) { + myMergeList = mergeList; + myMergeList.addListener(this); + updateCounters(); + } + + public void onChangeRemoved(ChangeList source) { + updateCounters(); + } + + public void addListener(Listener listener) { myListeners.add(listener); } + public void removeListener(Listener listener) { LOG.assertTrue(myListeners.remove(listener)); } + + private void updateCounters() { + int conflictCounter = 0; + int changeCounter = 0; + Iterator allChanges = myMergeList.getAllChanges(); + while (allChanges.hasNext()) { + Change change = allChanges.next(); + if (MergeList.NOT_CONFLICTS.value(change)) changeCounter++; + else conflictCounter++; + } + if (myChangeCounter != changeCounter || myConflictCounter != conflictCounter) { + myChangeCounter = changeCounter; + myConflictCounter = conflictCounter; + fireCountersChanged(); + } + } + + private void fireCountersChanged() { + Listener[] listeners = myListeners.toArray(new Listener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + Listener listener = listeners[i]; + listener.onCountersChanged(this); + } + } + + public int getChangeCounter() { + return myChangeCounter; + } + + public int getConflictCounter() { + return myConflictCounter; + } + + public static ChangeCounter getOrCreate(MergeList mergeList) { + ChangeCounter data = mergeList.getUserData(ourKey); + if (data == null) { + data = new ChangeCounter(mergeList); + mergeList.putUserData(ourKey, data); + } + return data; + } + + public interface Listener { + void onCountersChanged(ChangeCounter counter); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java new file mode 100644 index 00000000000..267ac64a980 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java @@ -0,0 +1,213 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.splitter.LineBlocks; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class ChangeList { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.ChangeList"); + private static final Comparator CHANGE_ORDER = new SimpleChange.ChangeOrder(FragmentSide.SIDE1); + + private final Document[] myDocuments = new Document[2]; + private final Parent myParent; + private final ArrayList myListeners = new ArrayList(); + private ArrayList myChanges; + + public ChangeList(Document base, Document version, Parent parent) { + myDocuments[0] = base; + myDocuments[1] = version; + myParent = parent; + } + + public void addListener(Listener listener) { + myListeners.add(listener); + } + + public void removeListener(Listener listener) { + LOG.assertTrue(myListeners.remove(listener)); + } + + public void setChanges(ArrayList changes) { + if (myChanges != null) { + HashSet newChanges = new HashSet(changes); + LOG.assertTrue(newChanges.size() == changes.size()); + for (Iterator iterator = myChanges.iterator(); iterator.hasNext();) { + Change oldChange = iterator.next(); + if (!newChanges.contains(oldChange)) { + iterator.remove(); + oldChange.onRemovedFromList(); + } + } + } + for (Iterator iterator = changes.iterator(); iterator.hasNext();) { + Change change = iterator.next(); + LOG.assertTrue(change.isValid()); + } + myChanges = new ArrayList(changes); + } + + public Project getProject() { return myParent.getProject(); } + + public List getChanges() { + return Collections.unmodifiableList(myChanges); + } + + public static ChangeList build(Document base, Document version, Parent parent) { + ChangeList result = new ChangeList(base, version, parent); + ArrayList changes = result.buildChanges(); + Collections.sort(changes, CHANGE_ORDER); + result.setChanges(changes); + return result; + } + + public void setMarkup(final Editor base, final Editor version) { + Editor[] editors = new Editor[]{base, version}; + for (Iterator iterator = myChanges.iterator(); iterator.hasNext();) { + Change change = iterator.next(); + change.addMarkup(editors); + } + } + + public void updateMarkup() { + for (Iterator iterator = myChanges.iterator(); iterator.hasNext();) { + Change change = iterator.next(); + change.updateMarkup(); + } + } + + public Document getDocument(FragmentSide side) { + return myDocuments[side.getIndex()]; + } + + private ArrayList buildChanges() { + Document base = getDocument(FragmentSide.SIDE1); + String[] baseLines = DiffUtil.convertToLines(base.getText()); + Document version = getDocument(FragmentSide.SIDE2); + String[] versionLines = DiffUtil.convertToLines(version.getText()); + DiffFragment[] fragments = ComparisonPolicy.DEFAULT.buildDiffFragmentsFromLines(baseLines, versionLines); + final ArrayList result = new ArrayList(); + new DiffFragmemntsEnumerator(fragments, base, version) { + protected void process(DiffFragment fragment) { + if (fragment.isEqual()) return; + Context context = getContext(); + TextRange range1 = context.createRange(FragmentSide.SIDE1); + TextRange range2 = context.createRange(FragmentSide.SIDE2); + result.add(new SimpleChange(ChangeType.fromDiffFragment(context.getFragment()), range1, range2, ChangeList.this)); + } + }.execute(); + return result; + } + + public Change getChange(int index) { + return myChanges.get(index); + } + + private static abstract class DiffFragmemntsEnumerator { + private final DiffFragment[] myFragments; + private final Context myContext; + + public DiffFragmemntsEnumerator(DiffFragment[] fragments, Document document1, Document document2) { + myContext = new Context(document1, document2); + myFragments = fragments; + } + + public void execute() { + for (int i = 0; i < myFragments.length; i++) { + DiffFragment fragment = myFragments[i]; + myContext.myFragment = fragment; + process(fragment); + String text1 = fragment.getText1(); + String text2 = fragment.getText2(); + myContext.myStarts[0] += DiffUtil.getTextLength(text1); + myContext.myStarts[1] += DiffUtil.getTextLength(text2); + myContext.myLines[0] += countLines(text1); + myContext.myLines[1] += countLines(text2); + } + } + + private int countLines(String text) { + if (text == null) return 0; + char[] chars = text.toCharArray(); + int counter = 0; + for (int i = 0; i < chars.length; i++) { + char aChar = chars[i]; + if (aChar == '\n') counter++; + } + return counter; + } + + protected Context getContext() { + return myContext; + } + + protected abstract void process(DiffFragment fragment); + } + + public static class Context { + private final Document[] myDocuments = new Document[2]; + private DiffFragment myFragment; + private final int[] myStarts = new int[]{0, 0}; + private final int[] myLines = new int[]{0, 0}; + + public Context(Document document1, Document document2) { + myDocuments[0] = document1; + myDocuments[1] = document2; + } + + public DiffFragment getFragment() { + return myFragment; + } + + public int getStart(FragmentSide side) { + return myStarts[side.getIndex()]; + } + + public int getEnd(FragmentSide side) { + return getStart(side) + DiffUtil.getTextLength(side.getText(myFragment)); + } + + public TextRange createRange(FragmentSide side) { + return new TextRange(getStart(side), getEnd(side)); + } + } + + public int getCount() { + return myChanges.size(); + } + + public LineBlocks getLineBlocks() { + return LineBlocks.fromChanges(myChanges); + } + + public void remove(Change change) { + LOG.assertTrue(myChanges.remove(change), change.toString()); + change.onRemovedFromList(); + fireOnChangeRemoved(); + } + + private void fireOnChangeRemoved() { + Listener[] listeners = myListeners.toArray(new Listener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + Listener listener = listeners[i]; + listener.onChangeRemoved(this); + } + } + + public interface Parent { + Project getProject(); + } + + public interface Listener { + void onChangeRemoved(ChangeList source); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java new file mode 100644 index 00000000000..8bc13676701 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java @@ -0,0 +1,131 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.highlighting.LineRenderer; +import com.intellij.openapi.diff.impl.util.DocumentUtil; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.SeparatorPlacement; +import com.intellij.openapi.util.TextRange; + +import java.awt.*; + +public class ChangeType { + private static final int LAYER = HighlighterLayer.SELECTION - 1; + private static final ChangeType INSERT = new ChangeType(TextDiffType.INSERT); + private static final ChangeType DELETED = new ChangeType(TextDiffType.DELETED); + private static final ChangeType CHANGE = new ChangeType(TextDiffType.CHANGED); + static final ChangeType CONFLICT = new ChangeType(TextDiffType.CONFLICT); + + private final TextDiffType myDiffType; + + private ChangeType(TextDiffType diffType) { + myDiffType = diffType; + } + + public RangeHighlighter addMarker(ChangeSide changeSide, MarkupHolder markup) { + String text = changeSide.getText(); + if (text != null && text.length() > 0) return addBlock(text, changeSide, markup, myDiffType); + else return addLine(markup, changeSide.getStartLine(), myDiffType, SeparatorPlacement.TOP); + } + + public TextDiffType getTypeKey() { + return myDiffType; + } + + public TextDiffType getTextDiffType() { return getTypeKey(); } + + private RangeHighlighter addBlock(String text, ChangeSide changeSide, MarkupHolder markup, TextDiffType diffType) { + int length = text.length(); + int start = changeSide.getStart(); + int end = start + length; + RangeHighlighter highlighter = markup.addRangeHighlighter( + start, end, ChangeType.LAYER, diffType, HighlighterTargetArea.EXACT_RANGE); + highlighter.setLineSeparatorPlacement(SeparatorPlacement.TOP); + highlighter.setLineMarkerRenderer(LineRenderer.top()); + highlighter.setLineSeparatorColor(Color.GRAY); + if (text.charAt(length - 1) == '\n') end--; + highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE); + highlighter.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM); + highlighter.setLineSeparatorColor(Color.GRAY); + highlighter.setLineMarkerRenderer(LineRenderer.bottom()); + return highlighter; + } + + private static RangeHighlighter addLine(MarkupHolder markup, int line, TextDiffType type, SeparatorPlacement placement) { + RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type); + if (highlighter == null) return null; + highlighter.setLineSeparatorPlacement(placement); + return highlighter; + } + + public static ChangeType fromDiffFragment(DiffFragment fragment) { + if (fragment.getText1() == null) return INSERT; + if (fragment.getText2() == null) return DELETED; + return CHANGE; + } + + public static ChangeType fromRanges(TextRange left, TextRange right) { + if (left.getLength() == 0) return INSERT; + if (right.getLength() == 0) return DELETED; + return CHANGE; + } + + public void apply(RangeMarker original, RangeMarker target) { + Document document = target.getDocument(); + if (DocumentUtil.isEmpty(original)) { + int offset = target.getStartOffset(); + document.deleteString(offset, target.getEndOffset()); + } + String text = DocumentUtil.getText(original); + int startOffset = target.getStartOffset(); + if (DocumentUtil.isEmpty(target)) { + document.insertString(startOffset, text); + } else { + document.replaceString(startOffset, target.getEndOffset(), text); + } + } + + public String toString() { + return myDiffType.getDisplayName(); + } + + public interface MarkupHolder { + RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType); + RangeHighlighter addRangeHighlighter(int start, int end, int layer, TextDiffType type, HighlighterTargetArea targetArea); + } + + public static abstract class ChangeSide { + public int getStart() { + return getRange().getStartOffset(); + } + + public int getStartLine() { + return DocumentUtil.getStartLine(getRange()); + } + + public String getText() { + return DocumentUtil.getText(getRange()); + } + + public int getEndLine() { + return DocumentUtil.getEndLine(getRange()); + } + + public abstract DiffRangeMarker getRange(); + + public abstract Change.HightlighterHolder getHighlighterHolder(); + + public boolean contains(int offset) { + return getStart() <= offset && offset < getEnd(); + } + + public int getEnd() { + return getRange().getEndOffset(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ConflictChange.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ConflictChange.java new file mode 100644 index 00000000000..63e01ff7f91 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ConflictChange.java @@ -0,0 +1,52 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.util.TextRange; + +class ConflictChange extends Change implements DiffRangeMarker.RangeInvalidListener { + private Side myOriginalSide; + private MergeConflict myConflict; + + public ConflictChange(MergeConflict conflict, FragmentSide mergeSide, TextRange range) { + myConflict = conflict; + myOriginalSide = new Side(mergeSide, new DiffRangeMarker(conflict.getOriginalDocument(mergeSide), range, this)); + } + + protected void removeFromList() { + myConflict.conflictRemoved(); + myConflict = null; + } + + public ChangeType.ChangeSide getChangeSide(FragmentSide side) { + return isBranch(side) ? myOriginalSide : (ChangeType.ChangeSide)myConflict; + } + + private boolean isBranch(FragmentSide side) { + return MergeList.BRANCH_SIDE == side; + } + + public Change.Side getOriginalSide() { + return myOriginalSide; + } + + public ChangeType getType() { return ChangeType.CONFLICT; } + + public ChangeList getChangeList() { + return myConflict.getMergeList().getChanges(myOriginalSide.getFragmentSide()); + } + + public void onRemovedFromList() { + myConflict.onChangeRemoved(myOriginalSide.getFragmentSide(), this); + myOriginalSide.getRange().removeListener(this); + myConflict = null; + myOriginalSide = null; + } + + public boolean isValid() { + return myConflict != null; + } + + public void onRangeInvalidated() { + removeFromList(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/DiffRangeMarker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/DiffRangeMarker.java new file mode 100644 index 00000000000..be30a1f9ed0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/DiffRangeMarker.java @@ -0,0 +1,87 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.impl.RangeMarkerImpl; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; + +class DiffRangeMarker extends RangeMarkerImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.DiffRangeMarker"); + private RangeInvalidListener myListener; + + public DiffRangeMarker(Document document, TextRange range, RangeInvalidListener listener) { + this(document, range.getStartOffset(), range.getEndOffset(), listener); + } + + private DiffRangeMarker(Document document, int start, int end, RangeInvalidListener listener) { + super(document, start, end); + myListener = listener; + if (myListener != null) InvalidRangeDispatcher.addClient(document); + } + + public void documentChanged(DocumentEvent e) { + super.documentChanged(e); + if (!isValid() && myListener != null) InvalidRangeDispatcher.notify(e.getDocument(), myListener); + } + + public void removeListener(RangeInvalidListener listener) { + LOG.assertTrue(myListener == listener || myListener == null); + myListener = null; + InvalidRangeDispatcher.removeClient(getDocument()); + } + + public interface RangeInvalidListener { + void onRangeInvalidated(); + } + + private static class InvalidRangeDispatcher extends DocumentAdapter { + private static final Key KEY = Key.create("deferedNotifier"); + private final ArrayList myDeferedNotifications = new ArrayList(); + private int myClientCount = 0; + + public void documentChanged(DocumentEvent e) { + if (myDeferedNotifications.size() == 0) return; + RangeInvalidListener[] notifications = myDeferedNotifications.toArray( + new RangeInvalidListener[myDeferedNotifications.size()]); + myDeferedNotifications.clear(); + for (int i = 0; i < notifications.length; i++) { + RangeInvalidListener notification = notifications[i]; + notification.onRangeInvalidated(); + } + } + + public static void notify(Document document, RangeInvalidListener listener) { + InvalidRangeDispatcher notifier = document.getUserData(KEY); + notifier.myDeferedNotifications.add(listener); + } + + public static void addClient(Document document) { + InvalidRangeDispatcher notifier = document.getUserData(KEY); + if (notifier == null) { + notifier = new InvalidRangeDispatcher(); + document.putUserData(KEY, notifier); + document.addDocumentListener(notifier); + } + notifier.myClientCount++; + } + + public static void removeClient(Document document) { + InvalidRangeDispatcher notifier = document.getUserData(KEY); + notifier.onClientRemoved(document); + } + + private void onClientRemoved(Document document) { + myClientCount--; + LOG.assertTrue(myClientCount >= 0); + if (myClientCount == 0) { + document.putUserData(KEY, null); + document.removeDocumentListener(this); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilder.java new file mode 100644 index 00000000000..2da335d25b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilder.java @@ -0,0 +1,304 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.ContextLogger; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; +import java.util.List; + +class MergeBuilder { + //private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.MergeBuilder"); + private final ContextLogger LOG; + private final int[] myProcessed = new int[]{0, 0, 0}; + private final ArrayList myResult = new ArrayList(); + private final EqualPair[] myPairs = new EqualPair[2]; + + public MergeBuilder(ContextLogger log) { + LOG = log; + } + + public void add(TextRange base, TextRange version, FragmentSide side) { + LOG.assertTrue(base.getLength() == version.getLength()); + myPairs[side.getIndex()] = new EqualPair(base.getStartOffset(), + version.getStartOffset(), base.getLength(), side, LOG); + if (myPairs[side.otherSide().getIndex()] == null) return; + if (myPairs[0].baseStartFrom(myProcessed) && myPairs[1].baseStartFrom(myProcessed)) { + processInsertOrConflict(); + return; + } + if (processNoIntersection()) return; + for (int i = 0; i < myPairs.length; i++) { + EqualPair pair = myPairs[i]; + if (pair.startsFrom(myProcessed)) { + processDeleteOrChange(FragmentSide.fromIndex(i).otherSide()); + return; + } + } + if (!removeSingleSideBase()) return; + LOG.assertTrue(myPairs[0].getBase() == myPairs[1].getBase()); + LOG.assertTrue(myPairs[0].getBase() > myProcessed[1]); + addMergeFragment(myPairs[0].processVersion(myProcessed), + proccesBaseChange(myPairs[0]), + myPairs[1].processVersion(myProcessed)); + skipProcessed(); + } + + private boolean processNoIntersection() { + FragmentSide firstSide = getFirstSide(); + int firstIndex = firstSide.getIndex(); + if (myPairs[firstIndex].getBaseEnd() <= myPairs[firstSide.otherSide().getIndex()].getBase()) { + myPairs[firstIndex] = null; + return true; + } + return false; + } + + private boolean removeSingleSideBase() { + FragmentSide firstSide = getFirstSide(); + int firstIndex = firstSide.getIndex(); + int singleSideDelta = myPairs[firstSide.otherSide().getIndex()].getBase() - myPairs[firstIndex].getBase(); + if (singleSideDelta >= myPairs[firstIndex].getLength()) { + LOG.notTested(); + myPairs[firstIndex] = null; + return false; + } + if (!myPairs[firstIndex].cutHead(singleSideDelta)) { + LOG.notTested(); + myPairs[firstIndex] = null; + return false; + } + return true; + } + + private FragmentSide getFirstSide() { + return myPairs[0].getBase() < myPairs[1].getBase() ? FragmentSide.SIDE1 : FragmentSide.SIDE2; + } + + private void processDeleteOrChange(FragmentSide side) { + EqualPair workingPair = myPairs[side.getIndex()]; + EqualPair otherPair = myPairs[side.otherSide().getIndex()]; + LOG.assertTrue(!workingPair.baseStartFrom(myProcessed) && + otherPair.baseStartFrom(myProcessed)); + TextRange versionChange = workingPair.processVersion(myProcessed); + TextRange baseChange = new TextRange(myProcessed[1], workingPair.getBase()); + int changeLength = workingPair.getBase() - myProcessed[1]; + myProcessed[1] += changeLength; + myProcessed[otherPair.getSide().getMergeIndex()] += changeLength; + myProcessed[side.getMergeIndex()] = workingPair.getVersion(); + boolean stillValid = otherPair.cutHead(changeLength); + LOG.assertTrue(stillValid); + myResult.add(MergeFragment.notConflict(baseChange, versionChange, side)); + skipProcessed(); + } + + private TextRange proccesBaseChange(EqualPair workingPair) { + int base = workingPair.getBase(); + TextRange change = new TextRange(myProcessed[1], base); + int otherBase = myPairs[workingPair.getSide().otherSide().getIndex()].getBase(); + LOG.assertTrue(otherBase >= base); + myProcessed[1] = base; + return change; + } + + private void processInsertOrConflict() { + boolean leftVersionProcessed = myPairs[0].versionStartsFrom(myProcessed); + boolean rightVersionProcessed = myPairs[1].versionStartsFrom(myProcessed); + TextRange emptyBase = new TextRange(myProcessed[1], myProcessed[1]); + if (!leftVersionProcessed && rightVersionProcessed) { + addMergeFragment(myPairs[0].processVersion(myProcessed), emptyBase, null); + } else if (!rightVersionProcessed && leftVersionProcessed) { + addMergeFragment(null, emptyBase, myPairs[1].processVersion(myProcessed)); + } else if (!leftVersionProcessed && !rightVersionProcessed) { + addMergeFragment(myPairs[0].processVersion(myProcessed), emptyBase, myPairs[1].processVersion(myProcessed)); + } + skipProcessed(); + } + + private void addMergeFragment(TextRange left, TextRange base, TextRange right) { + myResult.add(new MergeFragment(new TextRange[]{left, base, right})); + } + + private void skipProcessed() { + LOG.assertTrue(myProcessed[0] == myPairs[0].getVersion()); + LOG.assertTrue(myProcessed[2] == myPairs[1].getVersion()); + LOG.assertTrue(myPairs[0].getBase() == myPairs[1].getBase()); + LOG.assertTrue(myPairs[0].getBase() == myProcessed[1]); + int processedDelta = Math.min(myPairs[0].getBaseEnd(), myPairs[1].getBaseEnd()) - myProcessed[1]; + LOG.assertTrue(processedDelta > 0); + for (int i = 0; i < myProcessed.length; i++) myProcessed[i] += processedDelta; + for (int i = 0; i < myPairs.length; i++) + if (!myPairs[i].cutHead(processedDelta)) myPairs[i] = null; + LOG.assertTrue(myPairs[0] == null || myPairs[1] == null); + } + + public List finish(int leftLength, int baseLength, int rightLength) { + int[] lengths = new int[]{leftLength, baseLength, rightLength}; + if (isProcessedUpto(lengths)) return myResult; + int[] afterEnds = new int[3]; + for (int i = 0; i < lengths.length; i++) afterEnds[i] = lengths[i] + 1; + FragmentSide notProcessedSide = getNotProcessedSide(); + if (notProcessedSide == null) { + addTailChange(lengths); + return myResult; + } + myPairs[notProcessedSide.getIndex()].grow(1); + FragmentSide processedSide = notProcessedSide.otherSide(); + add(createRange(lengths, afterEnds, 1), + createRange(lengths, afterEnds, processedSide.getMergeIndex()), processedSide); + if (!isProcessedUpto(afterEnds)) + add(createRange(lengths, afterEnds, 1), + createRange(lengths, afterEnds, notProcessedSide.getMergeIndex()), + notProcessedSide); + LOG.assertTrue(isProcessedUpto(afterEnds)); + return myResult; + } + + private TextRange createRange(int[] starts, int[] ends, int column) { + return new TextRange(starts[column], ends[column]); + } + + private void addTailChange(int[] lengths) { + TextRange[] tailChange = new TextRange[3]; + for (int i = 0; i < tailChange.length; i++) { + if (i != 1 && myProcessed[i] == lengths[i]) tailChange[i] = null; + else tailChange[i] = new TextRange(myProcessed[i], lengths[i]); + } + myResult.add(new MergeFragment(tailChange)); + } + + private FragmentSide getNotProcessedSide() { + EqualPair left = myPairs[0]; + EqualPair right = myPairs[1]; + LOG.assertTrue(left == null || right == null); + if (left != null) return FragmentSide.SIDE1; + if (right != null) return FragmentSide.SIDE2; + return null; + } + + private boolean isProcessedUpto(int[] lengths) { + for (int i = 0; i < lengths.length; i++) { + int length = lengths[i]; + if (length != myProcessed[i]) return false; + } + return true; + } + + private static class EqualPair { + private final ContextLogger LOG; + private int myVersionStart; + private int myBaseStart; + private int myLength; + private final FragmentSide mySide; + + public EqualPair(int baseStart, int versionStart, int length, FragmentSide side, ContextLogger log) { + LOG = log; + myBaseStart = baseStart; + myVersionStart = versionStart; + myLength = length; + mySide = side; + } + + public boolean startsFrom(int[] bound) { + return versionStartsFrom(bound) && baseStartFrom(bound); + } + + public boolean versionStartsFrom(int[] bound) { + return myVersionStart == bound[mySide.getMergeIndex()]; + } + + public boolean baseStartFrom(int[] bound) { + return myBaseStart == bound[1]; + } + + public int getBaseEnd() { + return myBaseStart + myLength; + } + + public int getVersion() { + return myVersionStart; + } + + public TextRange processVersion(int[] processed) { + TextRange change = new TextRange(processed[mySide.getMergeIndex()], getVersion()); + processed[mySide.getMergeIndex()] = getVersion(); + return change; + } + + public boolean cutHead(int processedDelta) { + LOG.assertTrue(myLength >= processedDelta); + myBaseStart += processedDelta; + myVersionStart += processedDelta; + myLength -= processedDelta; + return myLength > 0; + } + + public int getBase() { + return myBaseStart; + } + + public int getLength() { + return myLength; + } + + public FragmentSide getSide() { + return mySide; + } + + public void grow(int delta) { + myLength += delta; + } + } + + public static class MergeFragment { + private final TextRange[] myRanges; + + public MergeFragment(TextRange[] ranges) { + myRanges = ranges; + } + + public TextRange[] getRanges() { + return myRanges; + } + + public boolean equals(Object obj) { + if (!(obj instanceof MergeFragment)) return false; + MergeFragment other = (MergeFragment)obj; + for (int i = 0; i < myRanges.length; i++) { + TextRange range = myRanges[i]; + if (!Comparing.equal(range, other.myRanges[i])) return false; + } + return true; + } + + public int hashCode() { + int result = 0; + for (int i = 0; i < myRanges.length; i++) { + TextRange range = myRanges[i]; + result ^= range == null ? i : range.hashCode(); + } + return result; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("<"); + for (int i = 0; i < myRanges.length; i++) { + TextRange range = myRanges[i]; + buffer.append(range != null ? range.toString() : "-----"); + if (i != myRanges.length - 1) buffer.append(", "); + } + buffer.append(">"); + return buffer.toString(); + } + + public static MergeFragment notConflict(TextRange baseChange, TextRange versionChange, FragmentSide versionSide) { + TextRange[] ranges = new TextRange[3]; + ranges[1] = baseChange; + ranges[versionSide.getMergeIndex()] = versionChange; + ranges[versionSide.otherSide().getMergeIndex()] = null; + return new MergeFragment(ranges); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeConflict.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeConflict.java new file mode 100644 index 00000000000..2d1557715a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeConflict.java @@ -0,0 +1,66 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.TextRange; + +class MergeConflict extends ChangeType.ChangeSide implements DiffRangeMarker.RangeInvalidListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.MergeConflict"); + private final Change.HightlighterHolder myCommonHightlighterHolder = new Change.HightlighterHolder(); + private final MergeList myMergeList; + private final DiffRangeMarker myCommonRange; + private ConflictChange[] myChanges; + + private MergeConflict(TextRange commonRange, MergeList mergeList) { + myCommonRange = new DiffRangeMarker(mergeList.getBaseDocument(),commonRange, this); + myMergeList = mergeList; + } + + public Change.HightlighterHolder getHighlighterHolder() { + return myCommonHightlighterHolder; + } + + public DiffRangeMarker getRange() { + return myCommonRange; + } + + public static Change[] createChanges(TextRange leftMarker, TextRange baseMarker, TextRange rightMarker, MergeList mergeList) { + MergeConflict conflict = new MergeConflict(baseMarker, mergeList); + return conflict.createChanges(leftMarker, rightMarker); + } + + private Change[] createChanges(TextRange leftMarker, TextRange rightMarker) { + LOG.assertTrue(myChanges == null); + myChanges = new ConflictChange[]{new ConflictChange(this, FragmentSide.SIDE1, leftMarker), + new ConflictChange(this, FragmentSide.SIDE2, rightMarker)}; + return myChanges; + } + + public void conflictRemoved() { + for (int i = 0; i < myChanges.length; i++) { + ConflictChange change = myChanges[i]; + change.getOriginalSide().getHighlighterHolder().removeHighlighters(); + } + myCommonHightlighterHolder.removeHighlighters(); + myMergeList.removeChanges(myChanges); + myCommonRange.removeListener(this); + } + + public Document getOriginalDocument(FragmentSide mergeSide) { + return myMergeList.getChanges(mergeSide).getDocument(MergeList.BRANCH_SIDE); + } + + public void onRangeInvalidated() { + conflictRemoved(); + } + + public void onChangeRemoved(FragmentSide mergeSide, ConflictChange conflictChange) { + LOG.assertTrue(myChanges[mergeSide.getIndex()] == conflictChange); + myChanges[mergeSide.getIndex()] = null; + } + + public MergeList getMergeList() { + return myMergeList; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java new file mode 100644 index 00000000000..2da1a2b2a65 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java @@ -0,0 +1,240 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; +import com.intellij.openapi.diff.impl.processing.DiffPolicy; +import com.intellij.openapi.diff.impl.util.ContextLogger; +import com.intellij.openapi.diff.impl.util.GutterActionRenderer; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; +import com.intellij.util.containers.FilteringIterator; +import com.intellij.util.containers.SequenceIterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class MergeList implements ChangeList.Parent, UserDataHolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.MergeList"); + private final Project myProject; + private final ChangeList[] myChanges = new ChangeList[2]; + private final UserDataHolderBase myDataHolder = new UserDataHolderBase(); + public static final FragmentSide BRANCH_SIDE = FragmentSide.SIDE2; + public static final FragmentSide BASE_SIDE = FragmentSide.SIDE1; + public static final String MERGE_LIST = "mergeList"; + + private MergeList(Project project, Document left, Document base, Document right) { + myProject = project; + myChanges[0] = new ChangeList(base, left, this); + myChanges[1] = new ChangeList(base, right, this); + } + + public static MergeList create(Project project, Document left, Document base, Document right) { + MergeList mergeList = new MergeList(project, left, base, right); + String leftText = left.getText(); + String baseText = base.getText(); + String rightText = right.getText(); + ContextLogger logger = new ContextLogger(LOG, new ContextLogger.SimpleContext(new Object[]{ + "Left\n" + leftText, + "\nBase\n"+baseText, + "\nRight\n" + rightText + })); + List fragmentList = processText(leftText, baseText, rightText, logger); + + ArrayList leftChanges = new ArrayList(); + ArrayList rightChanges = new ArrayList(); + for (Iterator iterator = fragmentList.iterator(); iterator.hasNext();) { + MergeBuilder.MergeFragment mergeFragment = iterator.next(); + final TextRange[] ranges = mergeFragment.getRanges(); + logger.assertTrue(ranges[1] != null); + if (ranges[0] == null) { + if (ranges[2] == null){ + LOG.assertTrue(false, "Left Text: " + leftText + "\n" + "Right Text: " + rightText + "\nBase Text: " + baseText); + } + rightChanges.add(SimpleChange.fromRanges(ranges[1], ranges[2], mergeList.myChanges[1])); + } + else if (ranges[2] == null) { + if (ranges[0] == null){ + LOG.assertTrue(false, "Left Text: " + leftText + "\n" + "Right Text: " + rightText + "\nBase Text: " + baseText); + } + leftChanges.add(SimpleChange.fromRanges(ranges[1], ranges[0], mergeList.myChanges[0])); + } + else { + Change[] changes = MergeConflict.createChanges(ranges[0], ranges[1], ranges[2], mergeList); + leftChanges.add(changes[0]); + rightChanges.add(changes[1]); + } + } + mergeList.myChanges[0].setChanges(leftChanges); + mergeList.myChanges[1].setChanges(rightChanges); + return mergeList; + } + + private static List processText(String leftText, + String baseText, + String rightText, + ContextLogger logger) { + DiffFragment[] leftFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, leftText); + DiffFragment[] rightFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, rightText); + int[] leftOffsets = new int[]{0, 0}; + int[] rightOffsets = new int[]{0, 0}; + int leftIndex = 0; + int rightIndex = 0; + MergeBuilder builder = new MergeBuilder(logger); + while (leftIndex < leftFragments.length || rightIndex < rightFragments.length) { + FragmentSide side; + TextRange[] equalRanges = new TextRange[2]; + if (leftOffsets[0] < rightOffsets[0] && leftIndex < leftFragments.length) { + side = FragmentSide.SIDE1; + getEqualRanges(leftFragments[leftIndex], leftOffsets, equalRanges); + leftIndex++; + } else if (rightIndex < rightFragments.length) { + side = FragmentSide.SIDE2; + getEqualRanges(rightFragments[rightIndex], rightOffsets, equalRanges); + rightIndex++; + } else break; + if (equalRanges[0] != null && equalRanges[1] != null) builder.add(equalRanges[0], equalRanges[1], side); + else logger.assertTrue(equalRanges[0] == null && equalRanges[1] == null); + } + List fragmentList = builder.finish(leftText.length(), baseText.length(), + rightText.length()); + return fragmentList; + } + + private static void getEqualRanges(DiffFragment fragment, int[] leftOffsets, TextRange[] equalRanges) { + int baseLength = getTextLength(fragment.getText1()); + int versionLength = getTextLength(fragment.getText2()); + if (fragment.isEqual()) { + equalRanges[0] = new TextRange(leftOffsets[0], leftOffsets[0] + baseLength); + equalRanges[1] = new TextRange(leftOffsets[1], leftOffsets[1] + versionLength); + } else { + equalRanges[0] = null; + equalRanges[1] = null; + } + leftOffsets[0] += baseLength; + leftOffsets[1] += versionLength; + } + + private static int getTextLength(String text1) { + return text1 != null ? text1.length() : 0; + } + + public static MergeList create(DiffRequest data) { + DiffContent[] contents = data.getContents(); + return create(data.getProject(), contents[0].getDocument(), contents[1].getDocument(), contents[2].getDocument()); + } + + public void setMarkups(Editor left, Editor base, Editor right) { + myChanges[0].setMarkup(base, left); + myChanges[1].setMarkup(base, right); + addActions(FragmentSide.SIDE1); + addActions(FragmentSide.SIDE2); + } + + public Iterator getAllChanges() { + return SequenceIterator.create(myChanges[0].getChanges().iterator(), + FilteringIterator.create(myChanges[1].getChanges().iterator(), NOT_CONFLICTS)); + } + + public void addListener(ChangeList.Listener listener) { + for (int i = 0; i < myChanges.length; i++) { + ChangeList changeList = myChanges[i]; + changeList.addListener(listener); + } + } + + public void removeListener(ChangeList.Listener listener) { + for (int i = 0; i < myChanges.length; i++) { + ChangeList changeList = myChanges[i]; + changeList.removeListener(listener); + } + } + + private void addActions(final FragmentSide side) { + ChangeList changeList = myChanges[side.getIndex()]; + final FragmentSide originalSide = BRANCH_SIDE; + for (int i = 0; i < changeList.getCount(); i++) { + final Change change = changeList.getChange(i); + if (!change.canHasActions(originalSide)) continue; + AnAction applyAction = new AnAction("Apply change", null, GutterActionRenderer.REPLACE_ARROW) { + public void actionPerformed(AnActionEvent e) { + apply(change); + } + }; + AnAction ignoreAction = new AnAction("Ignore change", null, GutterActionRenderer.REMOVE_CROSS) { + public void actionPerformed(AnActionEvent e) { + change.removeFromList(); + } + }; + change.getChangeSide(originalSide).getHighlighterHolder().setActions(new AnAction[]{applyAction, ignoreAction}); + } + } + + private void apply(final Change change) { + Change.apply(change, BRANCH_SIDE); + } + + public ChangeList getChanges(final FragmentSide changesSide) { + return myChanges[changesSide.getIndex()]; + } + + public void removeChanges(Change[] changes) { + for (int i = 0; i < changes.length; i++) { + Change change = changes[i]; + myChanges[i].remove(change); + } + } + + public Document getBaseDocument() { + Document document = myChanges[0].getDocument(BASE_SIDE); + LOG.assertTrue(document == myChanges[1].getDocument(BASE_SIDE)); + return document; + } + + public static MergeList fromDataContext(DataContext dataContext) { + MergeList mergeList = (MergeList)dataContext.getData(MERGE_LIST); + if (mergeList != null) return mergeList; + MergePanel2 mergePanel = MergePanel2.fromDataContext(dataContext); + return mergePanel == null ? null : mergePanel.getMergeList(); + } + + public static final Condition NOT_CONFLICTS = new Condition() { + public boolean value(Change change) { + return !(change instanceof ConflictChange); + } + }; + + public Project getProject() { + return myProject; + } + + public T getUserData(Key key) { + return myDataHolder.getUserData(key); + } + + public void putUserData(Key key, T value) { + myDataHolder.putUserData(key, value); + } + + public FragmentSide getSideOf(ChangeList source) { + for (int i = 0; i < myChanges.length; i++) { + ChangeList changeList = myChanges[i]; + if (changeList == source) return FragmentSide.fromIndex(i); + } + return null; + } + + public void updateMarkup() { + myChanges[0].updateMarkup(); + myChanges[1].updateMarkup(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeSearchHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeSearchHelper.java new file mode 100644 index 00000000000..8a2a1e556bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/MergeSearchHelper.java @@ -0,0 +1,79 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.util.Key; + +import java.util.Iterator; + +public class MergeSearchHelper { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.MergeSearchHelper"); + private static final Key[] ourMergeListKeys = new Key[]{Key.create("leftMergeSearchHelper"), + Key.create("centerMergeSearchHelper"), + Key.create("rightMergeSearchHelper")}; + private final MergeList myMergeList; + private final int myIndex; + + private MergeSearchHelper(MergeList mergeList, int index) { + myMergeList = mergeList; + myIndex = index; + } + + private static MergeSearchHelper forMergeList(MergeList mergeList, int contentIndex) { + Key key = (Key)ourMergeListKeys[contentIndex]; + MergeSearchHelper helper = mergeList.getUserData(key); + if (helper == null) { + helper = new MergeSearchHelper(mergeList, contentIndex); + mergeList.putUserData(key, helper); + } + return helper; + } + + public static Change findChangeAt(EditorMouseEvent e, MergePanel2 mergePanel, int index) { + Editor editor = e.getEditor(); + LOG.assertTrue(editor == mergePanel.getEditor(index)); + LogicalPosition logicalPosition = editor.xyToLogicalPosition(e.getMouseEvent().getPoint()); + int offset = editor.logicalPositionToOffset(logicalPosition); + return forMergeList(mergePanel.getMergeList(), index).findChangeAt(offset); + } + + private Change findChangeAt(int offset) { + for (int i = 0; i < 2; i++) { + Change change = changeAtOffset(myMergeList.getChanges(FragmentSide.fromIndex(i)).getChanges().iterator(), offset); + if (change != null) return change; + } + return null; + } + + private Change changeAtOffset(Iterator iterator, int offset) { + while (iterator.hasNext()) { + Change change = iterator.next(); + FragmentSide side = chooseInterestedSide(change); + if (side == null) continue; + if (change.getChangeSide(side).contains(offset)) return change; + } + return null; + + } + + private FragmentSide chooseInterestedSide(Change change) { + if (myIndex == 1) return MergeList.BASE_SIDE; + if (myIndex == 0) + if (change.getChangeList() != myMergeList.getChanges(FragmentSide.SIDE1)) return null; + if (myIndex == 2) + if (change.getChangeList() != myMergeList.getChanges(FragmentSide.SIDE2)) return null; + return MergeList.BRANCH_SIDE; + } + + public static Change findChangeAt(CaretEvent e, MergePanel2 mergePanel, int index) { + Editor editor = e.getEditor(); + LOG.assertTrue(editor == mergePanel.getEditor(index)); + return forMergeList(mergePanel.getMergeList(), index). + findChangeAt(editor.logicalPositionToOffset(e.getNewPosition())); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/SimpleChange.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/SimpleChange.java new file mode 100644 index 00000000000..5cd215d1965 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/SimpleChange.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.diff.impl.incrementalMerge; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.util.TextRange; + +class SimpleChange extends Change implements DiffRangeMarker.RangeInvalidListener{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.Change"); + private final ChangeType myType; + private final Side[] mySides; + private final ChangeList myChangeList; + + public SimpleChange(ChangeType type, TextRange range1, TextRange range2, ChangeList changeList) { + LOG.assertTrue(range1 != null); + LOG.assertTrue(range2 != null); + mySides = new Side[]{createSide(changeList, range1, FragmentSide.SIDE1), + createSide(changeList, range2, FragmentSide.SIDE2)}; + myType = type; + myChangeList = changeList; + } + + private Change.Side createSide(ChangeList changeList, TextRange range1, FragmentSide side) { + return new Change.Side(side, new DiffRangeMarker(changeList.getDocument(side), range1, this)); + } + + protected void removeFromList() { + myChangeList.remove(this); + } + + public ChangeType.ChangeSide getChangeSide(FragmentSide side) { + return mySides[side.getIndex()]; + } + + public ChangeType getType() { + return myType; + } + + public ChangeList getChangeList() { + return myChangeList; + } + + public void onRemovedFromList() { + for (int i = 0; i < mySides.length; i++) { + Change.Side side = mySides[i]; + side.getRange().removeListener(this); + side.getHighlighterHolder().removeHighlighters(); + mySides[i] = null; + } + } + + public boolean isValid() { + LOG.assertTrue((mySides[0] == null) == (mySides[1] == null)); + return mySides[0] != null; + } + + public void onRangeInvalidated() { + myChangeList.remove(this); + } + + public static Change fromRanges(TextRange baseRange, TextRange versionRange, ChangeList changeList) { + ChangeType type = ChangeType.fromRanges(baseRange, versionRange); + return new SimpleChange(type, baseRange, versionRange, changeList); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java new file mode 100644 index 00000000000..a01d86a2258 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.diff.impl.incrementalMerge.ui; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diff.impl.incrementalMerge.Change; +import com.intellij.openapi.diff.impl.incrementalMerge.MergeList; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FilteringIterator; + +import java.util.ArrayList; +import java.util.Iterator; + +public class ApplyNonConflicts extends AnAction { + public ApplyNonConflicts() { + super("Apply all non-conflicting changes", null, IconLoader.getIcon("/diff/applyNotConflicts.png")); + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + ArrayList notConflicts = ContainerUtil.collect(getNotConflicts(dataContext)); + for (Iterator iterator = notConflicts.iterator(); iterator.hasNext();) { + Change change = iterator.next(); + Change.apply(change, MergeList.BRANCH_SIDE); + } + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(getNotConflicts(e.getDataContext()).hasNext()); + } + + private Iterator getNotConflicts(DataContext dataContext) { + MergeList mergeList = MergeList.fromDataContext(dataContext); + if (mergeList == null) return new ArrayList(1).iterator(); + return FilteringIterator.create(mergeList.getAllChanges(), MergeList.NOT_CONFLICTS); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java new file mode 100644 index 00000000000..e20b63e4bff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/EditorPlace.java @@ -0,0 +1,146 @@ +package com.intellij.openapi.diff.impl.incrementalMerge.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ex.EditorEx; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +public class EditorPlace extends JComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.ui.EditorPlace"); + private final ComponentState myState; + private final ArrayList myListeners = new ArrayList(); + private Editor myEditor = null; + + public EditorPlace(ComponentState state) { + myState = state; + setLayout(new BorderLayout()); + } + + public void addNotify() { + if (myEditor != null) { + super.addNotify(); + return; + } + createEditor(); + super.addNotify(); + revalidate(); + } + + private void createEditor() { + LOG.assertTrue(myEditor == null); + myEditor = myState.createEditor(); + if (myEditor == null) return; + add(myEditor.getComponent(), BorderLayout.CENTER); + fireEditorCreated(); + } + + public void addListener(EditorListener listener) { + myListeners.add(listener); + } + + private void fireEditorCreated() { + EditorListener[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + EditorListener listener = listeners[i]; + listener.onEditorCreated(this); + } + } + + private void fireEditorReleased(Editor releasedEditor) { + EditorListener[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + EditorListener listener = listeners[i]; + listener.onEditorReleased(releasedEditor); + } + } + + private EditorListener[] getListeners() { + EditorListener[] listeners = new EditorListener[myListeners.size()]; + myListeners.toArray(listeners); + return listeners; + } + + public void removeNotify() { + removeEditor(); + super.removeNotify(); + } + + private void removeEditor() { + if (myEditor != null) { + Editor releasedEditor = myEditor; + remove(myEditor.getComponent()); + getEditorFactory().releaseEditor(myEditor); + myEditor = null; + fireEditorReleased(releasedEditor); + } + } + + public Editor getEditor() { + return myEditor; + } + + public void setDocument(Document document) { + if (document == getDocument()) return; + removeEditor(); + myState.setDocument(document); + createEditor(); + } + + private Document getDocument() { + return myState.getDocument(); + } + + public ComponentState getState() { + return myState; + } + + public static abstract class ComponentState { + private Document myDocument; + public abstract Editor createEditor(); + + public void setDocument(Document document) { + myDocument = document; + } + + public Document getDocument() { + return myDocument; + } + + public abstract void updateValue(Editor editor, ViewProperty property, T value); + } + + public interface EditorListener { + void onEditorCreated(EditorPlace place); + void onEditorReleased(Editor releasedEditor); + } + + private static EditorFactory getEditorFactory() { + return EditorFactory.getInstance(); + } + + public JComponent getContentComponent() { + return myEditor == null ? null : myEditor.getContentComponent(); + } + + public static abstract class ViewProperty { + private final T myDefault; + + protected ViewProperty(T aDefault) { + myDefault = aDefault; + } + + public void updateEditor(Editor editor, T value, ComponentState state) { + if (editor == null) return; + if (value == null) value = myDefault; + EditorEx editorEx = (EditorEx)editor; + doUpdateEditor(editorEx, value, state); + } + + protected abstract void doUpdateEditor(EditorEx editorEx, T value, ComponentState state); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java new file mode 100644 index 00000000000..33eb5840fde --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java @@ -0,0 +1,519 @@ +package com.intellij.openapi.diff.impl.incrementalMerge.ui; + +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffToolbar; +import com.intellij.openapi.diff.DiffViewer; +import com.intellij.openapi.diff.actions.NextDiffAction; +import com.intellij.openapi.diff.actions.PreviousDiffAction; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.EditingSides; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.incrementalMerge.ChangeCounter; +import com.intellij.openapi.diff.impl.incrementalMerge.ChangeList; +import com.intellij.openapi.diff.impl.incrementalMerge.MergeList; +import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint; +import com.intellij.openapi.diff.impl.splitter.LineBlocks; +import com.intellij.openapi.diff.impl.util.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.editor.ex.FoldingModelEx; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import gnu.trove.TIntHashSet; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +public class MergePanel2 implements DiffViewer { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2"); + private static final EditorPlace.ViewProperty EDITOR_SCHEME = new EditorPlace.ViewProperty( + null) { + public void doUpdateEditor(EditorEx editorEx, EditorColorsScheme scheme, EditorPlace.ComponentState state) { + if (scheme != null) editorEx.setColorsScheme(scheme); + } + }; + public static final EditorPlace.ViewProperty LINE_NUMBERS = new EditorPlace.ViewProperty( + Boolean.TRUE) { + public void doUpdateEditor(EditorEx editorEx, Boolean aBoolean, EditorPlace.ComponentState state) { + editorEx.getSettings().setLineNumbersShown(aBoolean.booleanValue()); + } + }; + public static final EditorPlace.ViewProperty LINE_MARKERS_AREA = new EditorPlace.ViewProperty( + Boolean.TRUE) { + public void doUpdateEditor(EditorEx editorEx, Boolean aBoolean, EditorPlace.ComponentState state) { + editorEx.getSettings().setLineMarkerAreaShown(aBoolean.booleanValue()); + } + }; + public static final EditorPlace.ViewProperty ADDITIONAL_LINES = new EditorPlace.ViewProperty(null) { + public void doUpdateEditor(EditorEx editorEx, Integer integer, EditorPlace.ComponentState state) { + if (integer != null) editorEx.getSettings().setAdditionalLinesCount(integer.intValue()); + } + }; + public static final EditorPlace.ViewProperty ADDITIONAL_COLUMNS = new EditorPlace.ViewProperty( + null) { + public void doUpdateEditor(EditorEx editorEx, Integer integer, EditorPlace.ComponentState state) { + if (integer != null) editorEx.getSettings().setAdditionalColumnsCount(integer.intValue()); + } + }; + public static final EditorPlace.ViewProperty HIGHLIGHTER_SETTINGS = new EditorPlace.ViewProperty( + null) { + public void doUpdateEditor(EditorEx editorEx, EditorColorsScheme settings, EditorPlace.ComponentState state) { + if (settings == null) settings = EditorColorsManager.getInstance().getGlobalScheme(); + DiffEditorState editorState = (DiffEditorState)state; + editorEx.setHighlighter( + HighlighterFactory.createHighlighter(editorState.getFileType(), settings, editorState.getProject())); + } + }; + private static final Collection ALL_PROPERTIES = Arrays.asList(new EditorPlace.ViewProperty[]{ + ADDITIONAL_COLUMNS, ADDITIONAL_LINES, EDITOR_SCHEME, HIGHLIGHTER_SETTINGS, + LINE_MARKERS_AREA, LINE_NUMBERS}); + + private final DiffPanelOutterComponent myPanel; + private DiffRequest myData; + private MergeList myMergeList; + private boolean myDuringCreation = false; + private final SyncScrollSupport myScrollSupport = new SyncScrollSupport(); + private final DiffDivider[] myDividers = new DiffDivider[]{new DiffDivider(FragmentSide.SIDE2), + new DiffDivider(FragmentSide.SIDE1)}; + + private final LabeledComponent[] myEditorsPanels = new LabeledComponent[EDITORS_COUNT]; + private final EditorPlace.EditorListener myPlaceListener = new EditorPlace.EditorListener() { + public void onEditorCreated(EditorPlace place) { + if (myDuringCreation) return; + disposeMergeList(); + myDuringCreation = true; + try { + tryInitView(); + } + finally { + myDuringCreation = false; + } + } + + public void onEditorReleased(Editor releasedEditor) { + LOG.assertTrue(!myDuringCreation); + disposeMergeList(); + } + }; + public static final int EDITORS_COUNT = 3; + private static final DiffRequest.ToolbarAddons TOOLBAR = new DiffRequest.ToolbarAddons() { + public void customize(DiffToolbar toolbar) { + ActionManager actionManager = ActionManager.getInstance(); + toolbar.addAction(actionManager.getAction(IdeActions.ACTION_COPY)); + toolbar.addAction(actionManager.getAction(IdeActions.ACTION_FIND)); + toolbar.addAction(PreviousDiffAction.find()); + toolbar.addAction(NextDiffAction.find()); + toolbar.addSeparator(); + toolbar.addAction(new OpenPartialDiffAction(1, 0, IconLoader.getIcon("/diff/leftDiff.png"))); + toolbar.addAction(new OpenPartialDiffAction(1, 2, IconLoader.getIcon("/diff/rightDiff.png"))); + toolbar.addAction(new OpenPartialDiffAction(0, 2, IconLoader.getIcon("/diff/branchDiff.png"))); + toolbar.addSeparator(); + toolbar.addAction(new ApplyNonConflicts()); + } + }; + private final DividersRepainter myDividersRepainter = new DividersRepainter(); + private StatusUpdater myStatusUpdater; + + public MergePanel2() { + ArrayList editorPlaces = new ArrayList(); + for (int i = 0; i < EDITORS_COUNT; i++) { + EditorPlace editorPlace = new EditorPlace(new DiffEditorState(i)); + editorPlaces.add(editorPlace); + editorPlace.addListener(myPlaceListener); + myEditorsPanels[i] = new LabeledComponent(); + myEditorsPanels[i].setLabelLocation(BorderLayout.NORTH); + myEditorsPanels[i].setComponent(editorPlace); + } + FontSizeSynchronizer.attachTo(editorPlaces); + myPanel = new DiffPanelOutterComponent(TextDiffType.MERGE_TYPES, TOOLBAR); + myPanel.insertDiffComponent(new ThreePanels(myEditorsPanels, myDividers), new MyScrollingPanel()); + myPanel.setDataProvider(new MyDataProvider()); + } + + public Editor getEditor(int index) { + return getEditorPlace(index).getEditor(); + } + + public FileType getContentType() { + return myData == null ? StdFileTypes.PLAIN_TEXT : getContentType(myData); + } + + public String getVersionTitle(int index) { + return myEditorsPanels[index].getRawText(); + } + + public EditorPlace getEditorPlace(int index) { + return (EditorPlace)myEditorsPanels[index].getComponent(); + } + + private void createMergeList() { + if (myData == null) return; + DiffContent[] contents = myData.getContents(); + for (int i = 0; i < EDITORS_COUNT; i++) { + getEditorPlace(i).setDocument(contents[i].getDocument()); + } + tryInitView(); + } + + private void tryInitView() { + if (!hasAllEditors()) return; + if (myMergeList != null) return; + myMergeList = MergeList.create(myData); + myMergeList.addListener(myDividersRepainter); + myStatusUpdater = StatusUpdater.install(myMergeList, myPanel); + Editor left = getEditor(0); + Editor base = getEditor(1); + Editor right = getEditor(2); + myMergeList.setMarkups(left, base, right); + EditingSides[] sides = new EditingSides[]{new MyEditingSides(FragmentSide.SIDE1), + new MyEditingSides(FragmentSide.SIDE2)}; + myScrollSupport.install(sides); + for (int i = 0; i < myDividers.length; i++) { + myDividers[i].listenEditors(sides[i]); + } + myPanel.requestScrollEditors(); + } + + private void disposeMergeList() { + if (myMergeList == null) return; + if (myStatusUpdater != null) { + myStatusUpdater.dispose(myMergeList); + myStatusUpdater = null; + } + myMergeList.removeListener(myDividersRepainter); + + myMergeList = null; + for (int i = 0; i < myDividers.length; i++) { + myDividers[i].stopListenEditors(); + } + } + + public void setDiffRequest(DiffRequest data) { + setTitle(data.getWindowTitle()); + disposeMergeList(); + for (int i = 0; i < EDITORS_COUNT; i++) { + getEditorPlace(i).setDocument(null); + } + LOG.assertTrue(!myDuringCreation); + myDuringCreation = true; + try { + myData = data; + String[] titles = myData.getContentTitles(); + for (int i = 0; i < myEditorsPanels.length; i++) { + LabeledComponent editorsPanel = myEditorsPanels[i]; + editorsPanel.getLabel().setText(titles[i]); + } + createMergeList(); + data.customizeToolbar(myPanel.resetToolbar()); + myPanel.registerToolbarActions(); + } + finally { + myDuringCreation = false; + } + } + + private void setTitle(String windowTitle) { + JDialog parent = getDialogWrapperParent(); + if (parent == null) return; + parent.setTitle(windowTitle); + } + + private JDialog getDialogWrapperParent() { + Component panel = myPanel; + while (panel != null){ + if (panel instanceof JDialog) return (JDialog)panel; + panel = panel.getParent(); + } + return null; + } + + public JComponent getComponent() { + return myPanel; + } + + public JComponent getPreferredFocusedComponent() { + return getEditorPlace(1).getContentComponent(); + } + + private boolean hasAllEditors() { + for (int i = 0; i < EDITORS_COUNT; i++) { + if (getEditor(i) == null) return false; + } + return true; + } + + private class MyEditingSides implements EditingSides { + private final FragmentSide mySide; + + public MyEditingSides(FragmentSide side) { + mySide = side; + } + + public Editor getEditor(FragmentSide side) { + return MergePanel2.this.getEditor(mySide.getIndex() + side.getIndex()); + } + + public LineBlocks getLineBlocks() { + return myMergeList.getChanges(mySide).getLineBlocks(); + } + } + + private class MyScrollingPanel implements DiffPanelOutterComponent.ScrollingPanel { + public void scrollEditors() { + Editor centerEditor = getEditor(1); + JComponent centerComponent = centerEditor.getContentComponent(); + if (centerComponent.isShowing()) centerComponent.requestFocus(); + int[] toLeft = getPrimaryBegginings(myDividers[0].getPaint()); + int[] toRight = getPrimaryBegginings(myDividers[1].getPaint()); + int line; + if (toLeft.length > 0 && toRight.length > 0) { + line = Math.min(toLeft[0], toRight[0]); + } + else if (toLeft.length > 0) { + line = toLeft[0]; + } + else if (toRight.length > 0) { + line = toRight[0]; + } + else { + return; + } + SyncScrollSupport.scrollEditor(centerEditor, line); + } + + private int[] getPrimaryBegginings(DiffDividerPaint paint) { + FragmentSide primarySide = paint.getLeftSide(); + LOG.assertTrue(getEditor(1) == paint.getSides().getEditor(primarySide)); + return paint.getSides().getLineBlocks().getBegginings(primarySide); + } + } + + private class DiffEditorState extends EditorPlace.ComponentState { + private final HashMap myProperties = new HashMap(); + private final int myIndex; + + public DiffEditorState(int index) { + myIndex = index; + } + + public Editor createEditor() { + Document document = getDocument(); + if (document == null) return null; + Project project = myData.getProject(); + EditorEx editor; + editor = DiffUtil.createEditor(document, project, myIndex != 1); + + if (editor == null) return editor; + //FileType type = getFileType(); + //editor.setHighlighter(HighlighterFactory.createHighlighter(project, type)); + if (myIndex == 0) editor.setVerticalScrollbarOrientation(EditorEx.VERTICAL_SCROLLBAR_LEFT); + if (myIndex != 1) ((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true); + editor.getSettings().setFoldingOutlineShown(false); + ((FoldingModelEx)editor.getFoldingModel()).setFoldingEnabled(false); + HashSet notProcessedDefaults = new HashSet(ALL_PROPERTIES); + for (Iterator iterator = myProperties.keySet().iterator(); iterator.hasNext();) { + EditorPlace.ViewProperty viewProperty = iterator.next(); + notProcessedDefaults.remove(viewProperty); + viewProperty.updateEditor(editor, myProperties.get(viewProperty), this); + } + for (Iterator iterator = notProcessedDefaults.iterator(); iterator.hasNext();) { + EditorPlace.ViewProperty viewProperty = iterator.next(); + viewProperty.updateEditor(editor, null, this); + } + return editor; + } + + public void updateValue(Editor editor, EditorPlace.ViewProperty property, T value) { + myProperties.put(property, value); + property.updateEditor(editor, value, this); + } + + public FileType getFileType() { + return getContentType(); + } + + public Project getProject() { + return myData == null ? null : myData.getProject(); + } + } + + private static FileType getContentType(DiffRequest diffData) { + FileType contentType = diffData.getContents()[1].getContentType(); + if (contentType == null) contentType = StdFileTypes.PLAIN_TEXT; + return contentType; + } + + private class MyDataProvider implements DataProvider { + public Object getData(String dataId) { + if (FocusDiffSide.FOCUSED_DIFF_SIDE.equals(dataId)) { + int index = getFocusedEditorIndex(); + if (index < 0) return null; + switch (index) { + case 0: + return new BranchFocusedSide(FragmentSide.SIDE1); + case 1: + return new MergeFocusedSide(); + case 2: + return new BranchFocusedSide(FragmentSide.SIDE2); + } + } + else if (DataConstants.DIFF_VIEWER.equals(dataId)) return MergePanel2.this; + return null; + } + + private int getFocusedEditorIndex() { + for (int i = 0; i < EDITORS_COUNT; i++) { + Editor editor = getEditor(i); + if (editor == null) continue; + if (editor.getContentComponent().isFocusOwner()) return i; + } + return -1; + } + } + + private class BranchFocusedSide implements FocusDiffSide { + private final FragmentSide mySide; + + public BranchFocusedSide(FragmentSide side) { + mySide = side; + } + + public Editor getEditor() { + return MergePanel2.this.getEditor(mySide.getMergeIndex()); + } + + public int[] getFragmentStartingLines() { + return myMergeList.getChanges(mySide).getLineBlocks().getBegginings(MergeList.BRANCH_SIDE); + } + } + + private class MergeFocusedSide implements FocusDiffSide { + public Editor getEditor() { + return MergePanel2.this.getEditor(1); + } + + public int[] getFragmentStartingLines() { + TIntHashSet beginnings = new TIntHashSet(); + for (int i = 0; i < 2; i++) { + FragmentSide branchSide = FragmentSide.fromIndex(i); + beginnings.addAll(myMergeList.getChanges(branchSide).getLineBlocks().getBegginings(MergeList.BASE_SIDE)); + } + int[] result = beginnings.toArray(); + Arrays.sort(result); + return result; + } + } + + public static MergePanel2 fromDataContext(DataContext dataContext) { + DiffViewer diffComponent = (DiffViewer)dataContext.getData(DataConstants.DIFF_VIEWER); + return diffComponent instanceof MergePanel2 ? (MergePanel2)diffComponent : null; + } + + public MergeList getMergeList() { + return myMergeList; + } + + public void setEditorProperty(EditorPlace.ViewProperty property, T value) { + for (int i = 0; i < EDITORS_COUNT; i++) { + EditorPlace editorPlace = getEditorPlace(i); + editorPlace.getState().updateValue(editorPlace.getEditor(), property, value); + } + } + + public void setColorScheme(EditorColorsScheme scheme) { + setEditorProperty(MergePanel2.EDITOR_SCHEME, scheme); + myPanel.setColorScheme(scheme); + } + + private class DividersRepainter implements ChangeList.Listener { + public void onChangeRemoved(ChangeList source) { + FragmentSide side = myMergeList.getSideOf(source); + myDividers[side.getIndex()].repaint(); + } + } + + private static class StatusUpdater implements ChangeCounter.Listener { + private final DiffPanelOutterComponent myPanel; + + private StatusUpdater(DiffPanelOutterComponent panel) { + myPanel = panel; + } + + public void onCountersChanged(ChangeCounter counter) { + int changes = counter.getChangeCounter(); + int conflicts = counter.getConflictCounter(); + String text; + if (changes == 0 && conflicts == 0) { + text = "All conflicts resolved"; + } + else { + text = stringRepresentation(changes, "change", "changes") + ". " + + stringRepresentation(conflicts, "conflict", "conflicts"); + } + myPanel.setStatusBarText(text); + } + + private String stringRepresentation(int number, String singular, String plural) { + switch (number) { + case 0: + return "No " + plural; + case 1: + return "One " + singular; + default: + return number + " " + plural; + } + } + + public void dispose(MergeList mergeList) { + LOG.assertTrue(mergeList != null); + ChangeCounter.getOrCreate(mergeList).removeListener(this); + } + + public static StatusUpdater install(MergeList mergeList, DiffPanelOutterComponent panel) { + ChangeCounter counters = ChangeCounter.getOrCreate(mergeList); + StatusUpdater updater = new StatusUpdater(panel); + counters.addListener(updater); + updater.onCountersChanged(counters); + return updater; + } + } + + public static class AsComponent extends JPanel { + private final MergePanel2 myMergePanel = new MergePanel2(); + + public AsComponent() { + super(new BorderLayout()); + add(myMergePanel.getComponent(), BorderLayout.CENTER); + } + + public MergePanel2 getMergePanel() { + return myMergePanel; + } + + public boolean isToolbarEnabled() { + return myMergePanel.myPanel.isToolbarEnabled(); + } + + public void setToolbarEnabled(boolean enabled) { + myMergePanel.myPanel.disableToolbar(!enabled); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/OpenPartialDiffAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/OpenPartialDiffAction.java new file mode 100644 index 00000000000..a6982b4b8a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/incrementalMerge/ui/OpenPartialDiffAction.java @@ -0,0 +1,69 @@ +package com.intellij.openapi.diff.impl.incrementalMerge.ui; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DocumentContent; +import com.intellij.openapi.diff.SimpleDiffRequest; +import com.intellij.openapi.diff.impl.external.DiffManagerImpl; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; + +import javax.swing.*; + +class OpenPartialDiffAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.ui.OpenPartialDiffAction"); + private final int myLeftIndex; + private final int myRightIndex; + + public OpenPartialDiffAction(int leftIndex, int rightIndex, Icon icon) { + super("", null, icon); + myLeftIndex = leftIndex; + myRightIndex = rightIndex; + } + + public void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + MergePanel2 mergePanel = MergePanel2.fromDataContext(dataContext); + Project project = projectFromDataContext(dataContext); + Editor leftEditor = mergePanel.getEditor(myLeftIndex); + Editor rightEditor = mergePanel.getEditor(myRightIndex); + FileType type = mergePanel.getContentType(); + SimpleDiffRequest diffData = new SimpleDiffRequest(project, composeName(mergePanel)); + diffData.setContents(new DocumentContent(project, leftEditor.getDocument(), type), new DocumentContent(project, rightEditor.getDocument(), type)); + diffData.setContentTitles(mergePanel.getVersionTitle(myLeftIndex), mergePanel.getVersionTitle(myRightIndex)); + LOG.assertTrue(DiffManagerImpl.INTERNAL_DIFF.canShow(diffData)); + DiffManagerImpl.INTERNAL_DIFF.show(diffData); + } + + public void update(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + MergePanel2 mergePanel = MergePanel2.fromDataContext(dataContext); + Project project = projectFromDataContext(dataContext); + Presentation presentation = e.getPresentation(); + if (mergePanel == null || project == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + presentation.setVisible(true); + Editor leftEditor = mergePanel.getEditor(myLeftIndex); + Editor rightEditor = mergePanel.getEditor(myRightIndex); + if (leftEditor == null || rightEditor == null) { + presentation.setEnabled(false); + return; + } + presentation.setText(composeName(mergePanel)); + presentation.setEnabled(true); + } + + private String composeName(MergePanel2 mergePanel2) { + String left = mergePanel2.getVersionTitle(myLeftIndex); + String right = mergePanel2.getVersionTitle(myRightIndex); + return "Compare " + left + " and " + right; + } + + private Project projectFromDataContext(DataContext dataContext) { + return (Project)dataContext.getData(DataConstants.PROJECT); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java new file mode 100644 index 00000000000..447caddd71b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.diff.impl.mergeTool; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffRequestFactory; +import com.intellij.openapi.diff.MergeRequest; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; +import java.io.OutputStream; + +public class DiffRequestFactoryImpl implements DiffRequestFactory { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.mergeTool.DiffRequestFactoryImpl"); + + public MergeRequest createMergeRequest(String leftText, String rightText, String originalContent, VirtualFile file, Project project) { + final Document document = FileDocumentManager.getInstance().getDocument(file); + return new MergeRequestImpl(leftText, createMergeVersion(file, document, originalContent), rightText, project); + } + + private MergeVersion createMergeVersion(VirtualFile file, + final Document document, + final String centerText) { + if (document != null) { + return new MergeVersion.MergeDocumentVersion(document, centerText); + } + else { + return new MyMergeVersion(centerText, file); + } + } + + private class MyMergeVersion implements MergeVersion { + private final String myCenterText; + private final VirtualFile myFile; + + public MyMergeVersion(String centerText, VirtualFile file) { + myCenterText = centerText; + myFile = file; + } + + public FileType getContentType() { + return FileTypeManager.getInstance().getFileTypeByFile(myFile); + } + + public byte[] getBytes() throws IOException { + return myCenterText.getBytes(myFile.getCharset().name()); + } + + public VirtualFile getFile() { + return myFile; + } + + public Document createWorkingDocument(Project project) { + return EditorFactory.getInstance().createDocument(myCenterText); + } + + + public void applyText(final String text, final Project project) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + storeChangedContent(text); + } + + }, "Writing to File", null); + } + }); + } + + private void storeChangedContent(String text) { + OutputStream outputStream = null; + byte[] bytes = null; + try { + bytes = text.getBytes(myFile.getCharset().name()); + outputStream = myFile.getOutputStream(this); + } + catch (IOException e) { + LOG.error(e); + } + try { + outputStream.write(bytes); + } + catch (IOException e) { + LOG.error(e); + } + finally { + try { + outputStream.close(); + } + catch (IOException e) { + LOG.error(e); + } + } + } + + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java new file mode 100644 index 00000000000..4aa5cdc063f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java @@ -0,0 +1,150 @@ +package com.intellij.openapi.diff.impl.mergeTool; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.MergeRequest; +import com.intellij.openapi.diff.SimpleContent; +import com.intellij.openapi.diff.impl.incrementalMerge.ChangeCounter; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.io.IOException; + +public class MergeRequestImpl extends MergeRequest { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.mergeTool.MergeData"); + private final DiffContent[] myDiffContents = new DiffContent[3]; + private String myWindowTitle = null; + private String[] myVersionTitles = null; + private int myResult; + private String myHelpId; + + public MergeRequestImpl(String left, MergeVersion base, String right, Project project) { + super(project); + myDiffContents[0] = new SimpleContent(left); + myDiffContents[1] = new MergeContent(base); + myDiffContents[2] = new SimpleContent(right); + } + + public DiffContent[] getContents() { return myDiffContents; } + + public String[] getContentTitles() { return myVersionTitles; } + public void setVersionTitles(String[] versionTitles) { myVersionTitles = versionTitles; } + + public String getWindowTitle() { return myWindowTitle; } + public void setWindowTitle(String windowTitle) { myWindowTitle = windowTitle; } + + public void setResult(int result) { + if (result == DialogWrapper.OK_EXIT_CODE) getMergeContent().applyChanges(); + myResult = result; + } + + public int getResult() { return myResult; } + + private MergeContent getMergeContent() { return (MergeContent)myDiffContents[1]; } + + public DiffContent getResultContent() { return getMergeContent(); } + + public void setActions(final DialogBuilder builder, MergePanel2 mergePanel) { + builder.addOkAction().setText("Apply"); + builder.addCancelAction(); + builder.setCancelOperation(new Runnable() { + public void run() { + if (Messages.showYesNoDialog(getProject(), + "Are you sure you want to exit without applying changes?", + "Cancel Visual Merge", + Messages.getQuestionIcon()) == 0) { + builder.getDialogWrapper().close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + }); + new AllResolvedListener(mergePanel, builder.getDialogWrapper()); + } + + public String getHelpId() { + return myHelpId; + } + + public void setHelpId(String helpId) { + myHelpId = helpId; + } + + private class MergeContent extends DiffContent { + private final MergeVersion myTarget; + private final Document myWorikingDocument; + + public MergeContent(MergeVersion target) { + myTarget = target; + myWorikingDocument = myTarget.createWorkingDocument(getProject()); + LOG.assertTrue(myWorikingDocument.isWritable()); + } + + public void applyChanges() { + myTarget.applyText(myWorikingDocument.getText(), getProject()); + } + + public Document getDocument() { return myWorikingDocument; } + + public OpenFileDescriptor getOpenFileDescriptor(int offset) { + VirtualFile file = getFile(); + if (file == null) return null; + return new OpenFileDescriptor(getProject(), file, offset); + } + + public VirtualFile getFile() { + return myTarget.getFile(); + } + + public FileType getContentType() { + return myTarget.getContentType(); + } + + public byte[] getBytes() throws IOException { + return myTarget.getBytes(); + } + } + + private class AllResolvedListener implements ChangeCounter.Listener, Runnable { + private final MergePanel2 myMergePanel; + private final DialogWrapper myDialogWrapper; + private boolean myWasInvoked = false; + + public AllResolvedListener(MergePanel2 mergePanel, DialogWrapper dialogWrapper) { + myMergePanel = mergePanel; + myDialogWrapper = dialogWrapper; + ChangeCounter.getOrCreate(myMergePanel.getMergeList()).addListener(this); + } + + public void run() { + if (myWasInvoked) return; + if (!getWholePanel().isDisplayable()) return; + myWasInvoked = true; + ChangeCounter.getOrCreate(myMergePanel.getMergeList()).removeListener(this); + int doApply = Messages.showDialog(getProject(), + "All changes have been processed.\nWould you like to save changes and finish merging?", + "All Changes Processed", + new String[]{"Save and &Finish", "&Continue"}, 0, + Messages.getQuestionIcon()); + if (doApply != 0) return; + myDialogWrapper.close(DialogWrapper.OK_EXIT_CODE); + } + + private JComponent getWholePanel() { + return myMergePanel.getComponent(); + } + + public void onCountersChanged(ChangeCounter counter) { + if (myWasInvoked) return; + if (counter.getChangeCounter() != 0 || counter.getConflictCounter() != 0) return; + ApplicationManager.getApplication().invokeLater(this); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeTool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeTool.java new file mode 100644 index 00000000000..0e4ab1fdaa7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeTool.java @@ -0,0 +1,53 @@ +package com.intellij.openapi.diff.impl.mergeTool; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.diff.impl.FrameWrapper; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; +import com.intellij.openapi.ui.DialogBuilder; + +public class MergeTool implements DiffTool { + public void show(DiffRequest data) { + if (data instanceof MergeRequest) { + showDialog((MergeRequestImpl)data); + return; + } + FrameWrapper frameWrapper = new FrameWrapper(data.getGroupKey()); + DiffViewer mergePanel = createMergeComponent(data); + frameWrapper.setComponent(mergePanel.getComponent()); + frameWrapper.setPreferredFocusedComponent(mergePanel.getPreferredFocusedComponent()); + frameWrapper.closeOnEsc(); + frameWrapper.setTitle(data.getWindowTitle()); + frameWrapper.setData(DataConstants.PROJECT, data.getProject()); + frameWrapper.show(); + } + + private MergePanel2 createMergeComponent(DiffRequest data) { + MergePanel2 mergePanel = new MergePanel2(); + mergePanel.setDiffRequest(data); + return mergePanel; + } + + private void showDialog(MergeRequestImpl data) { + DialogBuilder builder = new DialogBuilder(data.getProject()); + builder.setDimensionServiceKey(data.getGroupKey()); + builder.setTitle(data.getWindowTitle()); + MergePanel2 mergePanel = createMergeComponent(data); + builder.setCenterPanel(mergePanel.getComponent()); + builder.setPreferedFocusComponent(mergePanel.getPreferredFocusedComponent()); + data.setActions(builder, mergePanel); + builder.setHelpId(data.getHelpId()); + int result = builder.show(); + data.setResult(result); + } + + public boolean canShow(DiffRequest data) { + DiffContent[] contents = data.getContents(); + if (contents.length != 3) return false; + for (int i = 0; i < contents.length; i++) { + DiffContent content = contents[i]; + if (content.getDocument() == null) return false; + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeVersion.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeVersion.java new file mode 100644 index 00000000000..ec17d9cbf73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/mergeTool/MergeVersion.java @@ -0,0 +1,98 @@ +package com.intellij.openapi.diff.impl.mergeTool; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.impl.DocumentReferenceByDocument; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.NonUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.util.DocumentUtil; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; + +public interface MergeVersion { + Document createWorkingDocument(Project project); + + void applyText(String text, Project project); + + VirtualFile getFile(); + + byte[] getBytes() throws IOException; + + FileType getContentType(); + + class MergeDocumentVersion implements MergeVersion { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.mergeTool.MergeVersion.MergeDocumentVersion"); + private final Document myDocument; + private final String myOriginalText; + + public MergeDocumentVersion(Document document, String originalText) { + LOG.assertTrue(originalText != null); + LOG.assertTrue(document != null); + LOG.assertTrue(document.isWritable()); + myDocument = document; + myOriginalText = originalText; + } + + public Document createWorkingDocument(final Project project) { + final Document workingDocument = DocumentUtil.createCopy(myDocument, project); + LOG.assertTrue(workingDocument != myDocument); + workingDocument.setReadOnly(false); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + setDocumentText(workingDocument, myOriginalText, "initMergeContent", project); + UndoManager.getInstance(project).undoableActionPerformed(new NonUndoableAction() { + public boolean isComplex() { + return false; + } + + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[]{DocumentReferenceByDocument.createDocumentReference(workingDocument)}; + } + }); + } + }); + return workingDocument; + } + + public void applyText(final String text, final Project project) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + setDocumentText(myDocument, text, "Merge", project); + } + }); + } + + public VirtualFile getFile() { + return FileDocumentManager.getInstance().getFile(myDocument); + } + + public byte[] getBytes() throws IOException { + VirtualFile file = getFile(); + if (file != null) return file.contentsToByteArray(); + return myDocument.getText().getBytes(); + } + + public FileType getContentType() { + VirtualFile file = getFile(); + if (file == null) return StdFileTypes.PLAIN_TEXT; + return FileTypeManager.getInstance().getFileTypeByFile(file); + } + + private void setDocumentText(final Document document, final String startingText, String name, Project project) { + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + document.replaceString(0, document.getTextLength(), startingText); + } + }, name, null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/ByWord.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/ByWord.java new file mode 100644 index 00000000000..f267a8494f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/ByWord.java @@ -0,0 +1,354 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.highlighting.Util; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.diff.Diff; + +import java.util.ArrayList; + +class ByWord implements DiffPolicy{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.ByWord"); + private final ComparisonPolicy myComparisonPolicy; + + public ByWord(ComparisonPolicy comparisonPolicy) { + myComparisonPolicy = comparisonPolicy; + } + + public DiffFragment[] buildFragments(String text1, String text2) { + Word[] words1 = buildWords(text1, myComparisonPolicy); + Word[] words2 = buildWords(text2, myComparisonPolicy); + Diff.Change change = Diff.buildChanges(words1, words2); + change = Util.concatEquals(change, words1, words2); + if (Math.max(countNotWhitespaces(words1), countNotWhitespaces(words2)) > 0 && countEqual(change, words1, words2) == 0) + return new DiffFragment[]{myComparisonPolicy.createFragment(text1, text2)}; + FragmentBuilder result = new FragmentBuilder(words1, words2, myComparisonPolicy, text1, text2); + FragmentBuilder.Version version1 = result.getVersion1(); + FragmentBuilder.Version version2 = result.getVersion2(); + while (change != null) { + if (change.line0 > version1.getCurrentWordIndex()) { + processEquals(change.line0, change.line1, result); + } + if (change.inserted == 0) { + processOneside(version1, change.deleted); + } else if (change.deleted == 0) { + processOneside(version2, change.inserted); + } else { + String prefix1 = version1.getCurrentWordPrefix(); + String prefix2 = version2.getCurrentWordPrefix(); + if (prefix1.length() > 0 || prefix2.length() > 0) + result.add(myComparisonPolicy.createFragment(prefix1, prefix2)); + result.addChangedWords(change.deleted, change.inserted); + } + change = change.link; + } + processEquals(words1.length, words2.length, result); + result.addTails(); + DiffFragment[] fragments = result.getFragments(); + DiffFragment firstFragment = fragments[0]; + if (DiffUtil.isEmpty(firstFragment)) { + DiffFragment[] newFragments = new DiffFragment[fragments.length - 1]; + System.arraycopy(fragments, 1, newFragments, 0, newFragments.length); + fragments = newFragments; + } + return fragments; + } + + private int countNotWhitespaces(Word[] words) { + int counter = 0; + for (int i = 0; i < words.length; i++) { + Word word = words[i]; + if (!word.isWhitespace()) counter++; + } + return counter; + } + + private int countEqual(Diff.Change change, Word[] words1, Word[] words2) { + int counter = 0; + int position1 = 0; + int position2 = 0; + while (change != null) { + if (change.line0 > position1) { + int same = change.line0 - position1; + LOG.assertTrue(same == change.line1 - position2); + for (int i = 0; i < same; i++) { + if (!words1[position1 + i].isWhitespace() && !words2[position2 + i].isWhitespace()) counter++; + } + position1 += same; + position2 += same; + } + position1 += change.deleted; + position2 += change.inserted; + change = change.link; + } + int tailCount = words1.length - position1; + LOG.assertTrue(tailCount == words2.length - position2); + while (tailCount > 0) { + if (!words1[words1.length - tailCount].isWhitespace() && + !words2[words2.length - tailCount].isWhitespace()) counter++; + tailCount--; + } + return counter; + } + + private void processOneside(FragmentBuilder.Version version, int wordCount) { + String prefix = version.getCurrentWordPrefix(); + version.addOneSide(prefix, wordCount); + } + + private void processEquals(int changed1, int changed2, FragmentBuilder result) { + while (result.getVersion1().getCurrentWordIndex() < changed1) { + result.processEqual(); + } + LOG.assertTrue(changed2 == result.getVersion2().getCurrentWordIndex()); + } + + static Word[] buildWords(String text, ComparisonPolicy policy) { + ArrayList words = new ArrayList(); + if (text.length() == 0 || !Character.isWhitespace(text.charAt(0))) + words.add(policy.createFormatting(text, new TextRange(0, 0))); + int start = 0; + boolean withinFormatting = true; + for (int i = 0; i < text.length(); i++) { + char nextChar = text.charAt(i); + boolean isWhitespace = Character.isWhitespace(nextChar); + if (withinFormatting) { + if (isWhitespace) continue; + if (start != -1 && start < i) words.add(policy.createFormatting(text, new TextRange(start, i))); + start = -1; + withinFormatting = false; + } + if (nextChar == '\n') { + if (start != -1) words.add(new Word(text, new TextRange(start, i))); + start = i; + withinFormatting = true; + } else if (Util.DELIMITERS_SET.contains(nextChar)) { + if (start != -1) { + words.add(new Word(text, new TextRange(start, i))); + start = -1; + } + } else { + if (start == -1) start = i; + } + } + if (start != -1) { + TextRange range = new TextRange(start, text.length()); + Word lastWord = withinFormatting ? policy.createFormatting(text, range) : new Word(text, range); + words.add(lastWord); + } + return words.toArray(new Word[words.size()]); + } + + private static class FragmentBuilder { + private final ArrayList myFragments = new ArrayList(); + private final Version myVersion1; + private final Version myVersion2; + private final DiffPolicy.ByChar BY_CHAR; + private final DiffCorrection.ChangedSpace CORRECTION; + private final ComparisonPolicy myComparisonPolicy; + + public FragmentBuilder(Word[] words1, Word[] words2, ComparisonPolicy comparisonPolicy, String text1, String text2) { + myVersion1 = new Version(words1, text1, this, true); + myVersion2 = new Version(words2, text2, this, false); + BY_CHAR = new ByChar(comparisonPolicy); + CORRECTION = new DiffCorrection.ChangedSpace(comparisonPolicy); + myComparisonPolicy = comparisonPolicy; + } + + public DiffFragment[] getFragments() { + return myFragments.toArray(new DiffFragment[myFragments.size()]); + } + + public Version getVersion1() { return myVersion1; } + + public Version getVersion2() { return myVersion2; } + + private void addAll(DiffFragment[] fragments) { + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + add(fragment); + } + } + + private void add(DiffFragment fragment) { + String text1 = fragment.getText1(); + String text2 = fragment.getText2(); + if (text1 != null) myVersion1.addOffset(text1.length()); + if (text2 != null) myVersion2.addOffset(text2.length()); + if (fragment.isEqual() && myFragments.size() > 0) { + int lastIndex = myFragments.size() - 1; + DiffFragment prevFragment = myFragments.get(lastIndex); + if (prevFragment.isEqual()) { + myFragments.remove(lastIndex); + fragment = DiffFragment.unchanged(prevFragment.getText1() + fragment.getText1(), + prevFragment.getText2() + fragment.getText2()); + } + } + myFragments.add(fragment); + } + + private void addEqual(Word word1, Word word2) { + addAll(CORRECTION.correct(new DiffFragment[]{myComparisonPolicy.createFragment(word1, word2)})); + } + + public void processEqual() { + Word word1 = myVersion1.getCurrentWord(); + Word word2 = myVersion2.getCurrentWord(); + addAll(fragmentsByChar(myVersion1.getCurrentWordPrefix(), myVersion2.getCurrentWordPrefix())); + addEqual(word1, word2); + addPostfixes(); + myVersion1.incCurrentWord(); + myVersion2.incCurrentWord(); + } + + private DiffFragment[] fragmentsByChar(String text1, String text2) { + DiffFragment[] fragments = BY_CHAR.buildFragments(myVersion1.getPrevChar() + text1, + myVersion2.getPrevChar() + text2); + return Util.cutFirst(fragments); + } + + private void addPostfixes() { + String postfix1 = myVersion1.getCurrentWordPostfixAndOneMore(); + String postfix2 = myVersion2.getCurrentWordPostfixAndOneMore(); + int length1 = postfix1.length(); + int length2 = postfix2.length(); + DiffFragment wholePostfix = myComparisonPolicy.createFragment(postfix1, postfix2); + if (wholePostfix.isEqual()) { + add(DiffFragment.unchanged(cutLast(postfix1, length1), cutLast(postfix2, length2))); + return; + } + if (length1 > 0 || length2 > 0) { + DiffFragment[] fragments = BY_CHAR.buildFragments(postfix1, postfix2); + DiffFragment firstFragment = fragments[0]; + if (firstFragment.isEqual()) { + add(myComparisonPolicy.createFragment(cutLast(firstFragment.getText1(), length1), + cutLast(firstFragment.getText2(), length2))); + //add(firstFragment); + } + } + } + + private String cutLast(String text, int length) { + if (text.length() < length) return text; + else return text.substring(0, text.length() - 1); + } + + private void addOneSide(String text, FragmentSide side) { + DiffFragment fragment = side.createFragment(text, null, false); + add(myComparisonPolicy.createFragment(fragment.getText1(), fragment.getText2())); + } + + public void addChangedWords(int wordCount1, int wordCount2) { + add(new DiffFragment(myVersion1.getWordSequence(wordCount1), myVersion2.getWordSequence(wordCount2))); + myVersion1.incCurrentWord(wordCount1); + myVersion2.incCurrentWord(wordCount2); + } + + public void addTails() { + String tail1 = myVersion1.getNotProcessedTail(); + String tail2 = myVersion2.getNotProcessedTail(); + if (tail1.length() == 0 && tail2.length() == 0) return; + DiffFragment[] fragments = fragmentsByChar(tail1, tail2); + if (myFragments.size() > 0) { + DiffFragment lastFragment = myFragments.get(myFragments.size() - 1); + if (lastFragment.isChange()) { + int oneSideCount = 0; + while (oneSideCount < fragments.length && fragments[oneSideCount].isOneSide()) oneSideCount++; + if (oneSideCount > 0) { + myFragments.remove(myFragments.size() - 1); + DiffFragment[] onesideFragments = new DiffFragment[oneSideCount]; + DiffFragment[] otherFragments = new DiffFragment[fragments.length - oneSideCount]; + System.arraycopy(fragments, 0, onesideFragments, 0, oneSideCount); + System.arraycopy(fragments, oneSideCount, otherFragments, 0, otherFragments.length); + DiffFragment startingOneSides = UniteSameType.uniteAll(onesideFragments); + if (startingOneSides.isOneSide()) { + myFragments.add(lastFragment); + add(startingOneSides); + } else { + lastFragment = Util.unite(lastFragment, startingOneSides); + myFragments.add(lastFragment); + } + fragments = otherFragments; + } + } + } + addAll(fragments); + } + + public static class Version { + private final Word[] myWords; + private int myCurrentWord = 0; + private int myOffset = 0; + private final String myText; + private final FragmentBuilder myBuilder; + private final FragmentSide mySide; + + public Version(Word[] words, String text, FragmentBuilder builder, boolean delete) { + myWords = words; + myText = text; + myBuilder = builder; + mySide = delete ? FragmentSide.SIDE1 : FragmentSide.SIDE2; + } + + public int getProcessedOffset() { + return myOffset; + } + + public int getCurrentWordIndex() { + return myCurrentWord; + } + + public void addOffset(int offset) { + myOffset += offset; + } + + public void incCurrentWord() { + incCurrentWord(1); + } + + public String getWordSequence(int wordCount) { + int start = myWords[myCurrentWord].getStart(); + int end = myWords[myCurrentWord+wordCount-1].getEnd(); + return myText.substring(start, end); + } + + public void incCurrentWord(int inserted) { + myCurrentWord += inserted; + } + + public Word getCurrentWord() { + return myWords[myCurrentWord]; + } + + public String getCurrentWordPrefix() { + return getCurrentWord().getPrefix(getProcessedOffset()); + } + + public String getCurrentWordPostfixAndOneMore() { + int nextStart = myCurrentWord < myWords.length - 1 ? myWords[myCurrentWord + 1].getStart() : myText.length(); + Word word = getCurrentWord(); + String postfix = myText.substring(word.getEnd(), nextStart); + return postfix + (nextStart == myText.length() ? '\n' : myText.charAt(nextStart)); + } + + public String getNotProcessedTail() { + LOG.assertTrue(myCurrentWord == myWords.length); + return myText.substring(myOffset, myText.length()); + } + + public char getPrevChar() { + return myOffset == 0 ? '\n' : myText.charAt(myOffset - 1); + } + + public void addOneSide(String prefix, int wordCount) { + if (prefix.length() > 0) myBuilder.addOneSide(prefix, mySide); + myBuilder.addOneSide(getWordSequence(wordCount), mySide); + incCurrentWord(wordCount); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffCorrection.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffCorrection.java new file mode 100644 index 00000000000..23ae9e5a70a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffCorrection.java @@ -0,0 +1,248 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.LineTokenizer; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.DiffUtil; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.highlighting.Util; +import com.intellij.openapi.util.text.StringUtil; + +import java.util.ArrayList; + +public interface DiffCorrection { + DiffFragment[] correct(DiffFragment[] fragments); + + class TrueLineBlocks implements DiffCorrection, FragmentProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.DiffCorrection.TrueLineBlocks"); + private final DiffPolicy myDiffPolicy; + private final ComparisonPolicy myComparisonPolicy; + + public TrueLineBlocks(ComparisonPolicy comparisonPolicy) { + myDiffPolicy = new DiffPolicy.LineBlocks(comparisonPolicy); + myComparisonPolicy = comparisonPolicy; + } + + public DiffFragment[] correct(DiffFragment[] fragments) { + FragmentsCollector collector = new FragmentsCollector(); + collector.processAll(fragments, this); + return collector.toArray(); + } + + public void process(DiffFragment fragment, FragmentsCollector collector) { + if (!fragment.isEqual()) { + if (myComparisonPolicy.isEqual(fragment)) + fragment = myComparisonPolicy.createFragment(fragment.getText1(), fragment.getText2()); + collector.add(fragment); + } else { + String[] lines1 = new LineTokenizer(fragment.getText1()).execute(); + String[] lines2 = new LineTokenizer(fragment.getText2()).execute(); + LOG.assertTrue(lines1.length == lines2.length); + for (int i = 0; i < lines1.length; i++) + collector.addAll(myDiffPolicy.buildFragments(lines1[i], lines2[i])); + } + } + + public DiffFragment[] correctAndNormalize(DiffFragment[] fragments) { + return Normalize.INSTANCE.correct(correct(fragments)); + } + } + + class ChangedSpace implements DiffCorrection, FragmentProcessor { + private final DiffPolicy myDiffPolicy; + private final ComparisonPolicy myComparisonPolicy; + + public ChangedSpace(ComparisonPolicy policy) { + myComparisonPolicy = policy; + myDiffPolicy = new DiffPolicy.ByChar(myComparisonPolicy); + } + + public void process(DiffFragment fragment, FragmentsCollector collector) { + if (!fragment.isChange()) { + collector.add(fragment); + return; + } + String text1 = fragment.getText1(); + String text2 = fragment.getText2(); + while (StringUtil.startsWithChar(text1, '\n') || StringUtil.startsWithChar(text2, '\n')) { + String newLine1 = null; + String newLine2 = null; + if (StringUtil.startsWithChar(text1, '\n')) { + newLine1 = "\n"; + text1 = text1.substring(1); + } + if (StringUtil.startsWithChar(text2, '\n')) { + newLine2 = "\n"; + text2 = text2.substring(1); + } + collector.add(new DiffFragment(newLine1, newLine2)); + } + String spaces1 = leadingSpaces(text1); + String spaces2 = leadingSpaces(text2); + if (spaces1.length() == 0 && spaces2.length() == 0) { + DiffFragment trailing = myComparisonPolicy.createFragment(text1, text2); + collector.add(trailing); + return; + } + collector.addAll(myDiffPolicy.buildFragments(spaces1, spaces2)); + DiffFragment textFragment = myComparisonPolicy.createFragment(text1.substring(spaces1.length(), text1.length()), + text2.substring(spaces2.length(), text2.length())); + collector.add(textFragment); + } + + private String leadingSpaces(String text) { + int i = 0; + while (i < text.length() && text.charAt(i) == ' ') i++; + return text.substring(0, i); + } + + public DiffFragment[] correct(DiffFragment[] fragments) { + FragmentsCollector collector = new FragmentsCollector(); + collector.processAll(fragments, this); + return collector.toArray(); + } + } + + interface FragmentProcessor { + void process(DiffFragment fragment, Collector collector); + } + + class BaseFragmentRunner { + private final ArrayList myItems = new ArrayList(); + private int myIndex = 0; + private DiffFragment[] myFragments; + + public void add(DiffFragment fragment) { + actualAdd(fragment); + } + + protected final void actualAdd(DiffFragment fragment) { + if (DiffUtil.isEmpty(fragment)) return; + myItems.add(fragment); + } + + public DiffFragment[] toArray() { + return myItems.toArray(new DiffFragment[myItems.size()]); + } + + protected int getIndex() { return myIndex; } + + public DiffFragment[] getFragments() { return myFragments; } + + public void processAll(DiffFragment[] fragments, FragmentProcessor processor) { + myFragments = fragments; + for (;myIndex < myFragments.length; myIndex++) { + DiffFragment fragment = myFragments[myIndex]; + processor.process(fragment, (ActualRunner)this); + } + } + + } + + class FragmentsCollector extends BaseFragmentRunner { + public void addAll(DiffFragment[] fragments) { + for (int i = 0; i < fragments.length; i++) { + add(fragments[i]); + } + } + } + + class FragmentBuffer extends BaseFragmentRunner { + private int myMark = -1; + private int myMarkMode = -1; + + public void markIfNone(int mode) { + if (mode == myMarkMode || myMark == -1) { + if (myMark == -1) myMark = getIndex(); + } else { + flushMarked(); + myMark = getIndex(); + } + myMarkMode = mode; + } + + public void add(DiffFragment fragment) { + flushMarked(); + super.add(fragment); + } + + protected void flushMarked() { + if (myMark != -1) { + actualAdd(Util.concatenate(getFragments(), myMark, getIndex())); + myMark = -1; + } + } + + public void processAll(DiffFragment[] fragments, FragmentProcessor processor) { + super.processAll(fragments, processor); + flushMarked(); + } + } + + class ConcatenateSingleSide implements DiffCorrection, FragmentProcessor { + public static final DiffCorrection INSTANCE = new ConcatenateSingleSide(); + private static final int DEFAULT_MODE = 1; + + public DiffFragment[] correct(DiffFragment[] fragments) { + FragmentBuffer buffer = new FragmentBuffer(); + buffer.processAll(fragments, this); + return buffer.toArray(); + } + + public void process(DiffFragment fragment, FragmentBuffer buffer) { + if (fragment.isOneSide()) buffer.markIfNone(DEFAULT_MODE); + else buffer.add(fragment); + } + } + + class UnitEquals implements DiffCorrection, FragmentProcessor { + public static final DiffCorrection INSTANCE = new UnitEquals(); + private static final int EQUAL_MODE = 1; + private static final int FORMATTING_MODE = 2; + + public DiffFragment[] correct(DiffFragment[] fragments) { + FragmentBuffer buffer = new FragmentBuffer(); + buffer.processAll(fragments, this); + return buffer.toArray(); + } + + public void process(DiffFragment fragment, FragmentBuffer buffer) { + if (fragment.isEqual()) buffer.markIfNone(EQUAL_MODE); + else if (ComparisonPolicy.TRIM_SPACE.isEqual(fragment)) buffer.markIfNone(FORMATTING_MODE); + else buffer.add(fragment); + } + } + + class Normalize implements DiffCorrection { + public static final DiffCorrection INSTANCE = new Normalize(); + + private Normalize() {} + + public DiffFragment[] correct(DiffFragment[] fragments) { + return UnitEquals.INSTANCE.correct(ConcatenateSingleSide.INSTANCE.correct(fragments)); + } + } + + class ConnectSingleSideToChange implements DiffCorrection, FragmentProcessor { + public static final ConnectSingleSideToChange INSTANCE = new ConnectSingleSideToChange(); + private static final int CHANGE = 1; + + public DiffFragment[] correct(DiffFragment[] fragments) { + FragmentBuffer buffer = new FragmentBuffer(); + buffer.processAll(fragments, this); + return buffer.toArray(); + } + + public void process(DiffFragment fragment, FragmentBuffer buffer) { + if (fragment.isEqual()) buffer.add(fragment); + else if (fragment.isOneSide()) { + String text = FragmentSide.chooseSide(fragment).getText(fragment); + if (StringUtil.endsWithChar(text, '\n')) + buffer.add(fragment); + else + buffer.markIfNone(CHANGE); + } else buffer.markIfNone(CHANGE); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffFragmentsProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffFragmentsProcessor.java new file mode 100644 index 00000000000..33e6276e9fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffFragmentsProcessor.java @@ -0,0 +1,17 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.fragments.LineFragment; + +import java.util.ArrayList; + +class DiffFragmentsProcessor { + public ArrayList process(DiffFragment[] fragments) { + LineFragmentsCollector collector = new LineFragmentsCollector(); + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + collector.addDiffFragment(fragment); + } + return collector.getFragments(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffPolicy.java new file mode 100644 index 00000000000..99710468fe4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/DiffPolicy.java @@ -0,0 +1,48 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.DiffUtil; + +public interface DiffPolicy { + DiffFragment[] buildFragments(String text1, String text2); + + DiffPolicy LINES_WO_FORMATTING = new LineBlocks(ComparisonPolicy.IGNORE_SPACE); + DiffPolicy DEFAULT_LINES = new LineBlocks(ComparisonPolicy.DEFAULT); + + class LineBlocks implements DiffPolicy { + private final ComparisonPolicy myComparisonPolicy; + + public LineBlocks(ComparisonPolicy comparisonPolicy) { + myComparisonPolicy = comparisonPolicy; + } + + public DiffFragment[] buildFragments(String text1, String text2) { + String[] strings1 = DiffUtil.convertToLines(text1); + String[] strings2 = DiffUtil.convertToLines(text2); + return myComparisonPolicy.buildDiffFragmentsFromLines(strings1, strings2); + } + + } + + class ByChar implements DiffPolicy { + private final ComparisonPolicy myComparisonPolicy; + + public ByChar(ComparisonPolicy comparisonPolicy) { + myComparisonPolicy = comparisonPolicy; + } + + public DiffFragment[] buildFragments(String text1, String text2) { + return myComparisonPolicy.buildFragments(splitByChar(text1), splitByChar(text2)); + } + + private String[] splitByChar(String text) { + String[] result = new String[text.length()]; + for (int i = 0; i < result.length; i++) { + result[i] = text.substring(i, i + 1); + } + return result; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Formatting.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Formatting.java new file mode 100644 index 00000000000..3f4b45de3ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Formatting.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.util.TextRange; + +public class Formatting extends Word { + public Formatting(String text, TextRange range) { + super(text, range); + } + + public int hashCode() { + return -1; + } + + public boolean equals(Object obj) { + return obj instanceof Formatting; + } + + public boolean isWhitespace() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/FragmentsCollector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/FragmentsCollector.java new file mode 100644 index 00000000000..026175ef037 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/FragmentsCollector.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.fragments.Fragment; +import com.intellij.openapi.diff.impl.fragments.InlineFragment; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; + +class FragmentsCollector { + private final ArrayList myFragments = new ArrayList(); + private int myOffset1 = 0; + private int myOffset2 = 0; + + public Fragment addDiffFragment(DiffFragment fragment) { + int length1 = LineFragmentsCollector.getLength(fragment.getText1()); + int length2 = LineFragmentsCollector.getLength(fragment.getText2()); + InlineFragment inlineFragment = new InlineFragment(LineFragmentsCollector.getType(fragment), + new TextRange(myOffset1, myOffset1 + length1), + new TextRange(myOffset2, myOffset2 + length2)); + myFragments.add(inlineFragment); + myOffset1 += length1; + myOffset2 += length2; + return inlineFragment; + } + + public ArrayList getFragments() { return myFragments; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java new file mode 100644 index 00000000000..3ab1b551a50 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java @@ -0,0 +1,65 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.fragments.LineFragment; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; + +class LineFragmentsCollector { + private final ArrayList myLineFragments = new ArrayList(); + private int myLine1 = 0; + private int myLine2 = 0; + private int myOffset1 = 0; + private int myOffset2 = 0; + + private LineFragment addFragment(TextDiffType type, String text1, String text2) { + int lines1 = countLines(text1); + int lines2 = countLines(text2); + int endOffset1 = myOffset1 + getLength(text1); + int endOffset2 = myOffset2 + getLength(text2); + LineFragment lineFragment = new LineFragment(myLine1, lines1, myLine2, lines2, type, + new TextRange(myOffset1, endOffset1), + new TextRange(myOffset2, endOffset2)); + myLine1 += lines1; + myLine2 += lines2; + myOffset1 = endOffset1; + myOffset2 = endOffset2; + myLineFragments.add(lineFragment); + return lineFragment; + } + + public LineFragment addDiffFragment(DiffFragment fragment) { + return addFragment(getType(fragment), fragment.getText1(), fragment.getText2()); + } + + static int getLength(String text) { + return text == null ? 0 : text.length(); + } + + private static int countLines(String text) { + if (text == null) return 0; + int count = 0; + char[] chars = text.toCharArray(); + for (int i = 0; i < chars.length; i++) { + char aChar = chars[i]; + if (aChar == '\n') count++; + } + if (chars[chars.length - 1] != '\n') count++; + return count; + } + + public ArrayList getFragments() { + return myLineFragments; + } + + static TextDiffType getType(DiffFragment fragment) { + TextDiffType type; + if (fragment.getText1() == null) type = TextDiffType.INSERT; + else if (fragment.getText2() == null) type = TextDiffType.DELETED; + else if (fragment.isModified()) type = TextDiffType.CHANGED; + else type = null; + return type; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java new file mode 100644 index 00000000000..971ecfdbfd7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.util.text.StringUtil; + +class PreferWholeLines implements DiffCorrection { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.PreferWholeLines"); + public static final DiffCorrection INSTANCE = new PreferWholeLines(); + public DiffFragment[] correct(DiffFragment[] fragments) { + for (int i = 1; i < fragments.length - 1; i++) { + DiffFragment fragment = fragments[i]; + if (!fragment.isOneSide()) continue; + DiffFragment nextFragment = fragments[i + 1]; + FragmentSide side = FragmentSide.chooseSide(fragment); + LOG.assertTrue(!nextFragment.isOneSide(), + "<" + side.getText(fragment) + "> <" + side.getOtherText(nextFragment) + ">"); + if (StringUtil.startsWithChar(side.getText(fragment), '\n') && + StringUtil.startsWithChar(side.getText(nextFragment), '\n') && + StringUtil.startsWithChar(side.getOtherText(nextFragment), '\n')) { + DiffFragment previous = fragments[i - 1]; + previous = side.createFragment(side.getText(previous) + "\n", + side.getOtherText(previous) + "\n", + previous.isModified()); + fragments[i - 1] = previous; + fragment = side.createFragment(side.getText(fragment).substring(1) + "\n", + side.getOtherText(fragment), + fragment.isModified()); + fragments[i] = fragment; + nextFragment = side.createFragment(side.getText(nextFragment).substring(1), + side.getOtherText(nextFragment).substring(1), + nextFragment.isModified()); + fragments[i + 1] = nextFragment; + } + } + return fragments; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java new file mode 100644 index 00000000000..e3cb9de5c93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.fragments.Fragment; +import com.intellij.openapi.diff.impl.fragments.LineFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.highlighting.LineBlockDivider; +import com.intellij.openapi.diff.impl.highlighting.Util; + +import java.util.ArrayList; +import java.util.Iterator; + +public class TextCompareProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor"); + private final ComparisonPolicy myComparisonPolicy; + + public TextCompareProcessor(ComparisonPolicy comparisonPolicy) { + myComparisonPolicy = comparisonPolicy; + } + + public ArrayList process(String text1, String text2) { + DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(text1, text2); + DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy). + correctAndNormalize(woFormattingBlocks); + ArrayList lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments); + for (Iterator iterator = lineBlocks.iterator(); iterator.hasNext();) { + LineFragment lineBlock = iterator.next(); + if (lineBlock.isOneSide() || lineBlock.isEqual()) continue; + String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1); + String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2); + ArrayList subFragments = findSubFragments(subText1, subText2); + lineBlock.setChildren(new ArrayList(subFragments)); + } + return lineBlocks; + } + + private ArrayList findSubFragments(String text1, String text2) { + DiffFragment[] fragments = new ByWord(myComparisonPolicy).buildFragments(text1, text2); + fragments = DiffCorrection.ConnectSingleSideToChange.INSTANCE.correct(fragments); + fragments = UniteSameType.INSTANCE.correct(fragments); + fragments = PreferWholeLines.INSTANCE.correct(fragments); + fragments = UniteSameType.INSTANCE.correct(fragments); + DiffFragment[][] lines = Util.splitByUnchangedLines(fragments); + lines = Util.uniteFormattingOnly(lines); + + LineFragmentsCollector collector = new LineFragmentsCollector(); + for (int i = 0; i < lines.length; i++) { + DiffFragment[] line = lines[i]; + DiffFragment[][] subLines = LineBlockDivider.SINGLE_SIDE.divide(line); + subLines = Util.uniteFormattingOnly(subLines); + for (int j = 0; j < subLines.length; j++) { + DiffFragment[] subLineFragments = subLines[j]; + LineFragment subLine = collector.addDiffFragment(Util.concatenate(subLineFragments)); + if (!subLine.isOneSide()) { + subLine.setChildren(processInlineFragments(subLineFragments)); + } + } + } + return collector.getFragments(); + } + + private ArrayList processInlineFragments(DiffFragment[] subLineFragments) { + LOG.assertTrue(subLineFragments.length > 0); + FragmentsCollector result = new FragmentsCollector(); + for (int i = 0; i < subLineFragments.length; i++) { + DiffFragment fragment = subLineFragments[i]; + result.addDiffFragment(fragment); + } + return result.getFragments(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/UniteSameType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/UniteSameType.java new file mode 100644 index 00000000000..76937c09f70 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/UniteSameType.java @@ -0,0 +1,63 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.ex.DiffFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.highlighting.Util; + +class UniteSameType implements DiffCorrection { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.UniteSameType"); + public static final DiffCorrection INSTANCE = new UniteSameType(); + public DiffFragment[] correct(DiffFragment[] fragments) { + return unitSameTypes(covertSequentialOneSideToChange(unitSameTypes(fragments))); + } + + private DiffFragment[] unitSameTypes(DiffFragment[] fragments) { + if (fragments.length < 2) return fragments; + DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector(); + DiffFragment previous = fragments[0]; + for (int i = 1; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (!fragment.isOneSide() && fragment.getText1().length() == 0 && fragment.getText2().length() == 0) continue; + if (Util.isSameType(previous, fragment)) { + previous = Util.unite(previous, fragment); + } else { + collector.add(previous); + previous = fragment; + } + } + collector.add(previous); + return collector.toArray(); + } + + private DiffFragment[] covertSequentialOneSideToChange(DiffFragment[] fragments) { + if (fragments.length < 2) return fragments; + DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector(); +// DiffFragment previous = fragments[0]; + DiffFragment previous = null; + for (int i = 0; i < fragments.length; i++) { + DiffFragment fragment = fragments[i]; + if (fragment.isOneSide()) { + if (previous == null) previous = fragment; + else { + FragmentSide side = FragmentSide.chooseSide(fragment); + String previousText = side.getText(previous); + if (previousText == null) previousText = ""; + previous = side.createFragment(previousText + side.getText(fragment), side.getOtherText(previous), true); + } + } else { + if (previous != null) collector.add(previous); + previous = null; + collector.add(fragment); + } + } + if (previous != null) collector.add(previous); + return collector.toArray(); + } + + public static DiffFragment uniteAll(DiffFragment[] fragments) { + fragments = INSTANCE.correct(fragments); + LOG.assertTrue(fragments.length == 1); + return fragments[0]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Word.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Word.java new file mode 100644 index 00000000000..46d6a7eddb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/processing/Word.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.diff.impl.processing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; + +public class Word { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Word"); + private final String myText; + private final TextRange myRange; + + public Word(String text, TextRange range) { + myText = text; + myRange = range; + LOG.assertTrue(myRange.getStartOffset() >= 0); + LOG.assertTrue(myRange.getEndOffset() >= myRange.getStartOffset(), myRange.toString()); + } + + public int hashCode() { + return getText().hashCode(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Word)) return false; + Word other = (Word)obj; + return getText().equals(other.getText()); + } + + public String getText() { + return myText.substring(myRange.getStartOffset(), myRange.getEndOffset()); + } + + public String getPrefix(int fromPosition) { + LOG.assertTrue(fromPosition >= 0, "" + fromPosition); + int wordStart = myRange.getStartOffset(); + LOG.assertTrue(fromPosition <= wordStart, "" + fromPosition + " " + wordStart); + return myText.substring(fromPosition, wordStart); + } + + public int getEnd() { + return myRange.getEndOffset(); + } + + public int getStart() { + return myRange.getStartOffset(); + } + + public String toString() { + return getText(); + } + + public boolean isWhitespace() { + return false; + } + + public boolean atEndOfLine() { + int start = myRange.getStartOffset(); + if (start == 0) return true; + if (myText.charAt(start - 1) == '\n') return true; + int end = myRange.getEndOffset(); + if (end == myText.length()) return true; + if (myText.charAt(end) == '\n') return true; + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/settings/DiffColorsForm.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/settings/DiffColorsForm.java new file mode 100644 index 00000000000..672256f4fb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/settings/DiffColorsForm.java @@ -0,0 +1,374 @@ +package com.intellij.openapi.diff.impl.settings; + +import com.intellij.application.options.colors.ClickNavigator; +import com.intellij.application.options.colors.ColorAndFontOptions; +import com.intellij.application.options.colors.ColorAndFontPanel; +import com.intellij.application.options.colors.EditorSchemeAttributeDescriptor; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.SimpleContent; +import com.intellij.openapi.diff.impl.incrementalMerge.Change; +import com.intellij.openapi.diff.impl.incrementalMerge.MergeList; +import com.intellij.openapi.diff.impl.incrementalMerge.MergeSearchHelper; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.EditorPlace; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.*; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; + +public class DiffColorsForm { + private MergePanel2.AsComponent myMergePanelComponent; + private LabeledComponent myBackgoundColorPanelComponent; + private JList myOptionsList; + private JComponent myWholePanel; + private LabeledComponent myStripeMarkColorComponent; + + private static final Comparator TEXT_DIFF_TYPE_COMPARATOR = new Comparator() { + public int compare(TextDiffType textDiffType, TextDiffType textDiffType1) { + return textDiffType.getDisplayName().compareToIgnoreCase(textDiffType1.getDisplayName()); + } + }; + private final SortedListModel myOptionsModel = new SortedListModel(TEXT_DIFF_TYPE_COMPARATOR); + private final ListSelectionListener myOptionSelectionListener = new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + TextDiffType selection = getSelectedOption(); + ColorPanel background = getBackgroundColorPanel(); + ColorPanel stripeMark = getStripeMarkColorPanel(); + if (selection == null) { + background.setEnabled(false); + stripeMark.setEnabled(false); + } else { + background.setEnabled(true); + stripeMark.setEnabled(true); + MyColorAndFontDescription description = getSelectedDescription(); + if (description != null) { + background.setSelectedColor(description.getBackgroundColor()); + stripeMark.setSelectedColor(description.getStripeMarkColor()); + } + } + } + }; + private final MyTabImpl myMyTab; + private final HashMap myDescriptions = new HashMap(); + private EditorColorsScheme myScheme = null; + private boolean myDefault; + + private TextDiffType getSelectedOption() { + return (TextDiffType)myOptionsList.getSelectedValue(); + } + + public DiffColorsForm() { + myMyTab = new MyTabImpl(myWholePanel); + + myOptionsList.setCellRenderer(new OptionsReneder()); + myOptionsList.setModel(myOptionsModel); + + MergePanel2 mergePanel = getMergePanel(); + mergePanel.setEditorProperty(MergePanel2.LINE_NUMBERS, Boolean.FALSE); + mergePanel.setEditorProperty(MergePanel2.LINE_MARKERS_AREA, Boolean.FALSE); + mergePanel.setEditorProperty(MergePanel2.ADDITIONAL_LINES, new Integer(1)); + mergePanel.setEditorProperty(MergePanel2.ADDITIONAL_COLUMNS, new Integer(1)); + for (int i = 0; i < MergePanel2.EDITORS_COUNT; i++) { + final EditorMouseListener motionListener = new EditorMouseListener(i); + final EditorClickListener clickListener = new EditorClickListener(i); + mergePanel.getEditorPlace(i).addListener(new EditorPlace.EditorListener() { + public void onEditorCreated(EditorPlace place) { + Editor editor = place.getEditor(); + editor.addEditorMouseMotionListener(motionListener); + editor.addEditorMouseListener(clickListener); + editor.getCaretModel().addCaretListener(clickListener); + } + + public void onEditorReleased(Editor releasedEditor) { + releasedEditor.removeEditorMouseMotionListener(motionListener); + releasedEditor.removeEditorMouseListener(clickListener); + } + }); + Editor editor = mergePanel.getEditor(i); + if (editor != null) { + editor.addEditorMouseMotionListener(motionListener); + editor.addEditorMouseListener(clickListener); + } + } + ListSelectionModel selectionModel = myOptionsList.getSelectionModel(); + selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + selectionModel.addListSelectionListener(myOptionSelectionListener); + + getBackgroundColorPanel().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + MyColorAndFontDescription selectedDescription = getSelectedDescription(); + ColorPanel colorPanel = getBackgroundColorPanel(); + if (!checkModifiableScheme()) { + colorPanel.setSelectedColor(selectedDescription.getBackgroundColor()); + return; + } + selectedDescription.setBackgroundColor(colorPanel.getSelectedColor()); + selectedDescription.apply(myScheme); + updatePreview(); + } + }); + getStripeMarkColorPanel().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + MyColorAndFontDescription selectedDescription = getSelectedDescription(); + ColorPanel colorPanel = getStripeMarkColorPanel(); + if (!checkModifiableScheme()) { + colorPanel.setSelectedColor(selectedDescription.getStripeMarkColor()); + return; + } + selectedDescription.setStripeMarkColor(colorPanel.getSelectedColor()); + selectedDescription.apply(myScheme); + updatePreview(); + } + }); + } + + private boolean checkModifiableScheme() { + if (myDefault) ColorAndFontPanel.showReadOnlyMessage(myWholePanel); + return !myDefault; + } + + private MyColorAndFontDescription getSelectedDescription() { + TextDiffType selection = getSelectedOption(); + if (selection == null) return null; + return myDescriptions.get(selection.getAttributesKey().getExternalName()); + } + + private void updatePreview() { + MergeList mergeList = getMergePanel().getMergeList(); + if (mergeList != null) mergeList.updateMarkup(); + myMergePanelComponent.repaint(); + } + + public void setMergeRequest(Project project) { + getMergePanel().setDiffRequest(new SampleMerge(project)); + } + + private ColorPanel getBackgroundColorPanel() { + return myBackgoundColorPanelComponent.getComponent(); + } + + private ColorPanel getStripeMarkColorPanel() { + return myStripeMarkColorComponent.getComponent(); + } + + private MergePanel2 getMergePanel() { + return myMergePanelComponent.getMergePanel(); + } + + public void setScheme(EditorColorsScheme scheme, boolean isDefault) { + myDefault = isDefault; + myScheme = scheme; + getMergePanel().setColorScheme(scheme); + } + + public void setColorScheme(final EditorColorsScheme highlighterSettings) { + getMergePanel().setEditorProperty(MergePanel2.HIGHLIGHTER_SETTINGS, highlighterSettings); + } + + public JComponent getComponent() { + return myMyTab; + } + + public static void addSchemeDescriptions(ArrayList descriptions, EditorColorsScheme scheme) { + for (Iterator iterator = TextDiffType.MERGE_TYPES.iterator(); iterator.hasNext();) { + TextDiffType diffType = iterator.next(); + descriptions.add(new MyColorAndFontDescription(diffType, scheme)); + } + } + + private class EditorMouseListener extends EditorMouseMotionAdapter { + private final int myIndex; + + public EditorMouseListener(int index) { + myIndex = index; + } + + public void mouseMoved(EditorMouseEvent e) { + MergePanel2 mergePanel = getMergePanel(); + Editor editor = mergePanel.getEditor(myIndex); + if (MergeSearchHelper.findChangeAt(e, mergePanel, myIndex) != null) ClickNavigator.setHandCursor(editor); + } + } + + private class EditorClickListener extends EditorMouseAdapter implements CaretListener { + private final int myIndex; + + public EditorClickListener(int i) { + myIndex = i; + } + + public void mouseClicked(EditorMouseEvent e) { + select(MergeSearchHelper.findChangeAt(e, getMergePanel(), myIndex)); + } + + private void select(Change change) { + if (change == null) return; + ListScrollingUtil.selectItem(myOptionsList, change.getType().getTextDiffType()); + } + + public void caretPositionChanged(CaretEvent e) { + select(MergeSearchHelper.findChangeAt(e, getMergePanel(), myIndex)); + } + } + + private class MyTabImpl extends JPanel implements ColorAndFontPanel.MyTab { + public MyTabImpl(JComponent component) { + super(new BorderLayout()); + add(component, BorderLayout.CENTER); + } + + public void fillOptionsList(ColorAndFontOptions options, String category) { + myOptionsModel.clear(); + myDescriptions.clear(); + HashMap typesByKey = ContainerUtil.assignKeys(TextDiffType.MERGE_TYPES.iterator(), TextDiffType.ATTRIBUTES_KEY); + for (int i = 0; i < options.getCurrentDescriptions().length; i++) { + EditorSchemeAttributeDescriptor description = options.getCurrentDescriptions()[i]; + TextAttributesKey type = TextAttributesKey.find(description.getType()); + if (description.getGroup() == ColorAndFontOptions.DIFF_GROUP && + typesByKey.keySet().contains(type)) { + myOptionsModel.add(typesByKey.get(type)); + myDescriptions.put(type.getExternalName(), (MyColorAndFontDescription)description); + } + } + ListScrollingUtil.ensureSelectionExists(myOptionsList); + } + + public void processListValueChanged() { + updatePreview(); + } + + public void updateDescription(ColorAndFontOptions options) {} + } + + private static class OptionsReneder extends ColoredListCellRenderer { + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + TextDiffType diffType = (TextDiffType)value; + append(diffType.getDisplayName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + } + + private static class SampleMerge extends DiffRequest { + public SampleMerge(Project project) { + super(project); + } + + public DiffContent[] getContents() { + return new DiffContent[]{createContent(LEFT_TEXT), createContent(CENTER_TEXT), createContent(RIGHT_TEXT)}; + } + + private SimpleContent createContent(String text) { + return new SimpleContent(text, StdFileTypes.JAVA); + } + + public String[] getContentTitles() { return new String[]{"", "", ""}; } + public String getWindowTitle() { return "Merge Color Options"; } + } + + private static final String LEFT_TEXT = "class MyClass {\n" + + " int value;\n" + + "\n" + + " void leftOnly() {}\n" + + "\n" + + " void foo() {\n" + + " // Left changes\n" + + " }\n" + + "}"; + private static final String CENTER_TEXT = "class MyClass {\n" + + " int value;\n" + + "\n" + + " void foo() {\n" + + " }\n" + + "\n" + + " void removedFromLeft() {}\n" + + "}"; + private static final String RIGHT_TEXT = "class MyClass {\n" + + " long value;\n" + + "\n" + + " void foo() {\n" + + " // Left changes\n" + + " }\n" + + "\n" + + " void removedFromLeft() {}\n" + + "}"; + + private static class MyColorAndFontDescription implements EditorSchemeAttributeDescriptor { + private Color myBackgroundColor; + private Color myStripebarColor; + private Color myOriginalBackground; + private Color myOriginalStripebar; + private final EditorColorsScheme myScheme; + private final TextDiffType myDiffType; + + public MyColorAndFontDescription(TextDiffType diffType, EditorColorsScheme scheme) { + myScheme = scheme; + myDiffType = diffType; + TextAttributes attrs = diffType.getTextAttributes(myScheme); + myBackgroundColor = attrs.getBackgroundColor(); + myStripebarColor = attrs.getErrorStripeColor(); + myOriginalBackground = myBackgroundColor; + myOriginalStripebar = myStripebarColor; + } + + public void apply(EditorColorsScheme scheme) { + TextAttributesKey key = myDiffType.getAttributesKey(); + TextAttributes attrs = new TextAttributes(null, myBackgroundColor, null, EffectType.BOXED, 0); + attrs.setErrorStripeColor(myStripebarColor); + scheme.setAttributes(key, attrs); + } + + public String getGroup() { + return ColorAndFontOptions.DIFF_GROUP; + } + + public EditorColorsScheme getScheme() { + return myScheme; + } + + public String getType() { + return myDiffType.getAttributesKey().getExternalName(); + } + + public boolean isModified() { + TextAttributes attrs = myDiffType.getTextAttributes(myScheme); + return !Comparing.equal(myOriginalBackground, attrs.getBackgroundColor()) || + !Comparing.equal(myOriginalStripebar, attrs.getErrorStripeColor()); + } + + public void setBackgroundColor(Color selectedColor) { + myBackgroundColor = selectedColor; + } + + public Color getBackgroundColor() { + return myBackgroundColor; + } + + public void setStripeMarkColor(Color selectedColor) { + myStripebarColor = selectedColor; + } + + public Color getStripeMarkColor() { + return myStripebarColor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java new file mode 100644 index 00000000000..23d5430be36 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.diff.impl.splitter; + +import com.intellij.openapi.diff.impl.EditingSides; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; + +import javax.swing.*; +import java.awt.*; + +public class DiffDividerPaint { + private final EditingSides mySides; + private final FragmentSide myLeftSide; + + public DiffDividerPaint(EditingSides sides, FragmentSide leftSide) { + mySides = sides; + myLeftSide = leftSide; + } + + public void paint(Graphics g, JComponent component) { + if (!hasAllEditors()) return; + int width = component.getWidth(); + int height = component.getHeight(); + int editorHeight = mySides.getEditor(myLeftSide).getComponent().getHeight(); + DividerPoligon.paintPoligons(DividerPoligon.createVisiblePoligons(mySides, myLeftSide), + (Graphics2D)g.create(0, height - editorHeight, width, editorHeight), + width); + } + + public EditingSides getSides() { + return mySides; + } + + public FragmentSide getLeftSide() { + return myLeftSide; + } + + private boolean hasAllEditors() { + return mySides.getEditor(FragmentSide.SIDE1) != null && mySides.getEditor(FragmentSide.SIDE2) != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java new file mode 100644 index 00000000000..fd95a9400f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java @@ -0,0 +1,109 @@ +package com.intellij.openapi.diff.impl.splitter; + +import com.intellij.openapi.diff.impl.EditingSides; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.util.Comparing; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +class DividerPoligon { + private final Color myColor; + private final int myStart1; + private final int myStart2; + private final int myEnd1; + private final int myEnd2; + + public DividerPoligon(int start1, int start2, int end1, int end2, Color color) { + myStart1 = start1; + myStart2 = start2; + myEnd1 = end1; + myEnd2 = end2; + myColor = color; + } + + private void paint(Graphics2D g, int width) { + g.setColor(myColor); + g.fill(new Polygon(new int[]{0, 0, width, width}, new int[]{myStart1, myEnd1, myEnd2, myStart2}, 4)); + g.setColor(Color.GRAY); + g.drawLine(0, myStart1, width, myStart2); + g.drawLine(0, myEnd1, width, myEnd2); + } + + public int hashCode() { + return myStart1 ^ myStart2 ^ myEnd1 ^ myEnd2; + } + + public boolean equals(Object obj) { + if (!(obj instanceof DividerPoligon)) return false; + DividerPoligon other = (DividerPoligon)obj; + return myStart1 == other.myStart1 && + myStart2 == other.myStart2 && + myEnd1 == other.myEnd1 && + myEnd2 == other.myEnd2 && Comparing.equal(myColor, other.myColor); + } + + public String toString() { + return "<" + myStart1 + ", " + myEnd1 + " : " + myStart2 + ", " + myEnd2 + "> " + myColor; + } + + Color getColor() { return myColor; } + + public static void paintPoligons(ArrayList poligons, Graphics2D g, int width) { + //Composite composite = g.getComposite(); + //g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f)); + for (Iterator iterator = poligons.iterator(); iterator.hasNext();) { + DividerPoligon poligon = iterator.next(); + poligon.paint(g, width); + } + //g.setComposite(composite); + } + + public static ArrayList createVisiblePoligons(EditingSides sides, FragmentSide left) { + Editor editor1 = sides.getEditor(left); + Editor editor2 = sides.getEditor(left.otherSide()); + LineBlocks lineBlocks = sides.getLineBlocks(); + Trapezium visibleArea = new Trapezium(getVisibleInterval(editor1), + getVisibleInterval(editor2)); + Interval indecies = lineBlocks.getVisibleIndecies(visibleArea); + Transformation[] transformations = new Transformation[]{getTransformation(editor1), + getTransformation(editor2)}; + ArrayList poligons = new ArrayList(); + for (int i = indecies.getStart(); i < indecies.getEnd(); i++) { + Trapezium trapezium = lineBlocks.getTrapezium(i); + TextDiffType type = lineBlocks.getType(i); + if (type == null) continue; + Color color = type.getPoligonColor(editor1); + poligons.add(createPoligon(transformations, trapezium, color, left)); + } + return poligons; + } + + private static Transformation getTransformation(Editor editor) { +// return new LinearTransformation(editor.getScrollingModel().getVerticalScrollOffset(), editor.getLineHeight()); + return new FoldingTransformation(editor); + } + + private static DividerPoligon createPoligon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left) { + Interval base1 = trapezium.getBase(left); + Interval base2 = trapezium.getBase(left.otherSide()); + Transformation leftTransform = transformations[left.getIndex()]; + Transformation rightTransform = transformations[left.otherSide().getIndex()]; + int start1 = leftTransform.transform(base1.getStart()); + int end1 = leftTransform.transform(base1.getEnd()); + int start2 = rightTransform.transform(base2.getStart()); + int end2 = rightTransform.transform(base2.getEnd()); + return new DividerPoligon(start1, start2, end1, end2, color); + } + + static Interval getVisibleInterval(Editor editor1) { + int offset = editor1.getScrollingModel().getVerticalScrollOffset(); + LogicalPosition logicalPosition = editor1.xyToLogicalPosition(new Point(0, offset)); + int line = logicalPosition.line; + return new Interval(line, editor1.getComponent().getHeight() / editor1.getLineHeight() + 1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/FoldingTransformation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/FoldingTransformation.java new file mode 100644 index 00000000000..ddb495bab52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/FoldingTransformation.java @@ -0,0 +1,74 @@ +package com.intellij.openapi.diff.impl.splitter; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.LogicalPosition; +import gnu.trove.TIntArrayList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +public class FoldingTransformation implements Transformation { + private final Editor myEditor; + private final ArrayList myCollapsed = new ArrayList(); + private final int[] myFoldBeginings; + private static final Comparator FOLD_REGIONS_COMPARATOR = new Comparator(){ + public int compare(FoldRegion foldRegion, FoldRegion foldRegion1) { + return foldRegion.getStartOffset() - foldRegion1.getStartOffset(); + } + }; + + public FoldingTransformation(Editor editor) { + myEditor = editor; + FoldRegion[] foldRegions = myEditor.getFoldingModel().getAllFoldRegions(); + Arrays.sort(foldRegions, FOLD_REGIONS_COMPARATOR); + TIntArrayList foldBeginings = new TIntArrayList(); + for (int i = 0; i < foldRegions.length; i++) { + FoldRegion foldRegion = foldRegions[i]; + if (!foldRegion.isValid() || foldRegion.isExpanded()) continue; + foldBeginings.add(getStartLine(foldRegion)); + myCollapsed.add(foldRegion); + } + myFoldBeginings = foldBeginings.toNativeArray(); + } + + private int getStartLine(FoldRegion foldRegion) { + return myEditor.offsetToLogicalPosition(foldRegion.getStartOffset()).line; +// return ((FoldRegionImpl)foldRegion).getStartLine(); + } + + public int transform(int line) { + FoldRegion foldRegion = findFoldRegion(line); + int yOffset = 0; + if (foldRegion != null) { + int startLine = getStartLine(foldRegion); + yOffset = (int)((double)(line - startLine) / getLineLength(foldRegion) * myEditor.getLineHeight()); + line = startLine; + } + yOffset += myEditor.logicalPositionToXY(new LogicalPosition(line, 0)).y; + return yOffset - myEditor.getScrollingModel().getVerticalScrollOffset(); + } + + private int getLineLength(FoldRegion foldRegion) { + return getEndLine(foldRegion) - getStartLine(foldRegion); + } + + private int getEndLine(FoldRegion foldRegion) { + return myEditor.offsetToLogicalPosition(foldRegion.getEndOffset()).line; +// return ((FoldRegionImpl)foldRegion).getEndLine(); + } + + private FoldRegion findFoldRegion(int line) { + int index = Arrays.binarySearch(myFoldBeginings, line); + FoldRegion region; + if (index >= 0) region = myCollapsed.get(index); + else { + index = -index - 1; + if (index == 0) return null; + region = myCollapsed.get(index - 1); + } + if (getEndLine(region) < line) return null; + return region; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Interval.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Interval.java new file mode 100644 index 00000000000..17f57ae9353 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Interval.java @@ -0,0 +1,72 @@ +package com.intellij.openapi.diff.impl.splitter; + +import java.util.Comparator; + +public class Interval { + public static final Comparator START_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof Interval) return ((Interval) o1).compareToStart((Integer) o2); + return -((Interval) o2).compareToStart((Integer) o1); + } + }; + + public static final Comparator END_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof Interval) return ((Interval) o1).compareToEnd((Integer) o2); + return -((Interval)o2).compareToEnd((Integer) o1); + } + }; + private final int myStart; + private final int myLength; + + public Interval(int start, int length) { + myStart = start; + myLength = length; + } + + public int getEnd() { + return myStart + myLength; + } + + public int getStart() { + return myStart; + } + + private int compareToStart(Integer start) { + return myStart - start.intValue(); + } + + private int compareToEnd(Integer end) { + return getEnd() - end.intValue(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Interval)) return false; + Interval other = (Interval) obj; + return myStart == other.myStart && myLength == other.myLength; + } + + public int hashCode() { + return myStart ^ (myLength << 20); + } + + public String toString() { + return "[" + myStart + ", " + getEnd() + ")"; + } + + public static Interval fromTo(int start, int end) { + return new Interval(start, end - start); + } + + public int getLength() { + return myLength; + } + + public static Interval toInf(int start) { + return Interval.fromTo(start, Integer.MAX_VALUE); + } + + public boolean contains(int location) { + return (location > myStart && location < getEnd()) || location == myStart; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LineBlocks.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LineBlocks.java new file mode 100644 index 00000000000..e654ddc6e1d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LineBlocks.java @@ -0,0 +1,206 @@ +package com.intellij.openapi.diff.impl.splitter; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.fragments.LineBlock; +import com.intellij.openapi.diff.impl.fragments.LineFragment; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.incrementalMerge.Change; +import com.intellij.openapi.diff.impl.util.TextDiffType; +import com.intellij.util.containers.IntArrayList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; + +public class LineBlocks { + public static final LineBlocks EMPTY = new LineBlocks(SimpleIntervalProvider.EMPTY, new TextDiffType[0]); + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.splitter.LineBlocks"); + private final IntervalsProvider myIntervalsProvider; + private final TextDiffType[] myTypes; + + private LineBlocks(IntervalsProvider intervalsProvider, TextDiffType[] types) { + myIntervalsProvider = intervalsProvider; + myTypes = types; + } + + public Interval getVisibleIndecies(Trapezium visibleArea) { + Interval visible1 = visibleArea.getBase1(); + Interval visible2 = visibleArea.getBase2(); + Interval[] intervals1 = getIntervals(FragmentSide.SIDE1); + Interval[] intervals2 = getIntervals(FragmentSide.SIDE2); + int index = Math.min(getMaxStartedIndex(intervals1, visible1.getStart()), + getMaxStartedIndex(intervals2, visible2.getStart())); + int lastIndex = Math.max(getMinNotStartedIndex(intervals1, visible1.getEnd()), + getMinNotStartedIndex(intervals2, visible2.getEnd())); + return Interval.fromTo(index, lastIndex); + } + + public Trapezium getTrapezium(int index) { + return new Trapezium(getIntervals(FragmentSide.SIDE1)[index], + getIntervals(FragmentSide.SIDE2)[index]); + } + + public TextDiffType getType(int index) { + return myTypes[index]; + } + + public int getCount() { + return getBegginings(FragmentSide.SIDE1).length; + } + + public int[] getBegginings(FragmentSide side) { + IntArrayList result = new IntArrayList(getIntervals(side).length); + int previousBeginning = Integer.MIN_VALUE; + Interval[] sideIntervals = getIntervals(side); + for (int i = 0; i < sideIntervals.length; i++) { + int start = sideIntervals[i].getStart(); + if (start != previousBeginning) result.add(start); + previousBeginning = start; + } + return result.toArray(); + } + + static int getMaxStartedIndex(Interval[] intervals, int start) { + int index = getMinIndex(intervals, start, Interval.START_COMPARATOR); + for (int i = index; i > 0; i--) + if (intervals[i-1].getEnd() <= start) return i; + return 0; + } + + static int getMinNotStartedIndex(Interval[] intervals, int end) { + int index = getMinIndex(intervals, end, Interval.END_COMPARATOR); + for (int i = index; i < intervals.length; i++) + if (intervals[i].getStart() >= end) return i; + return intervals.length; + } + + private static int getMinIndex(Interval[] intervals, int start, Comparator comparator) { + int index = Arrays.binarySearch(intervals, new Integer(start), comparator); + return index >= 0 ? index : -index - 1; + } + + public int transform(FragmentSide masterSide, int location) { + return transform(location, getIntervals(masterSide), getIntervals(masterSide.otherSide())); + } + + public Interval[] getIntervals(FragmentSide side) { + return myIntervalsProvider.getIntervals(side); + } + + private int transform(int location, Interval[] domain, Interval[] range) { + if (domain.length == 0) { + LOG.assertTrue(range.length == 0, "" + range.length); + return location; + } + int count = getIntervals(FragmentSide.SIDE1).length; + LOG.assertTrue(count == getIntervals(FragmentSide.SIDE2).length); + int index = getMaxStartedIndex(domain, location); + Interval leftInterval; + Interval rightInterval; + if (index == 0) { + if (domain[0].contains(location)) { + leftInterval = domain[0]; + rightInterval = range[0]; + } else { + leftInterval = Interval.fromTo(0, domain[0].getStart()); + rightInterval = Interval.fromTo(0, range[0].getStart()); + } + } else if (index == count) { + leftInterval = Interval.toInf(domain[count - 1].getEnd()); + rightInterval = Interval.toInf(range[count - 1].getEnd()); + } else { + if (domain[index].contains(location)) { + leftInterval = domain[index]; + rightInterval = range[index]; + } else { + leftInterval = Interval.fromTo(domain[index - 1].getEnd(), domain[index].getStart()); + rightInterval = Interval.fromTo(range[index - 1].getEnd(), range[index].getStart()); + } + } + return LinearTransformation.oneToOne(location, leftInterval.getStart(), rightInterval); + } + + public static LineBlocks fromLineFragments(ArrayList lines) { + ArrayList filtered = new ArrayList(); + for (Iterator iterator = lines.iterator(); iterator.hasNext();) { + LineFragment fragment = iterator.next(); + if (fragment.getType() != null) filtered.add(fragment); + } + return createLineBlocks(filtered.toArray(new LineBlock[filtered.size()])); + } + + static LineBlocks createLineBlocks(LineBlock[] blocks) { + Arrays.sort(blocks, LineBlock.COMPARATOR); + Interval[] intervals1 = new Interval[blocks.length]; + Interval[] intervals2 = new Interval[blocks.length]; + TextDiffType[] types = new TextDiffType[blocks.length]; + for (int i = 0; i < blocks.length; i++) { + LineBlock block = blocks[i]; + intervals1[i] = new Interval(block.getStartingLine1(), block.getModifiedLines1()); + intervals2[i] = new Interval(block.getStartingLine2(), block.getModifiedLines2()); + types[i] = block.getType(); + } + return create(intervals1, intervals2, types); + } + + private static LineBlocks create(Interval[] intervals1, Interval[] intervals2, TextDiffType[] types) { + return new LineBlocks(new SimpleIntervalProvider(intervals1, intervals2), types); + } + + public static LineBlocks fromChanges(ArrayList changes) { + ArrayList intervals1 = new ArrayList(); + ArrayList intervals2 = new ArrayList(); + ArrayList types = new ArrayList(); + //int prevEnd1 = 0; + //int prevEnd2 = 0; + for (Iterator iterator = changes.iterator(); iterator.hasNext();) { + Change change = iterator.next(); + int start1 = change.getChangeSide(FragmentSide.SIDE1).getStartLine(); + int start2 = change.getChangeSide(FragmentSide.SIDE2).getStartLine(); + //if (start1 != prevEnd1 || start2 != prevEnd2) { + // intervals1.add(Interval.fromTo(prevEnd1, start1)); + // intervals2.add(Interval.fromTo(prevEnd2, start2)); + // types.add(null); + //} + int end1 = change.getChangeSide(FragmentSide.SIDE1).getEndLine(); + intervals1.add(Interval.fromTo(start1, end1)); + int end2 = change.getChangeSide(FragmentSide.SIDE2).getEndLine(); + intervals2.add(Interval.fromTo(start2, end2)); + types.add(change.getType().getTypeKey()); + //prevEnd1 = end1; + //prevEnd2 = end2; + } + //LOG.assertTrue(prevEnd1 < length1 && prevEnd2 < length2); + //if (prevEnd1 != length1 || prevEnd2 != length2) { + // intervals1.add(Interval.fromTo(prevEnd1, length1)); + // intervals2.add(Interval.fromTo(prevEnd2, length2)); + // types.add(null); + //} + + return create(intervals1.toArray(new Interval[intervals1.size()]), + intervals2.toArray(new Interval[intervals2.size()]), types.toArray(new TextDiffType[types.size()])); + } + + public TextDiffType[] getTypes() { + return myTypes; + } + + public interface IntervalsProvider { + Interval[] getIntervals(FragmentSide side); + } + + public static class SimpleIntervalProvider implements IntervalsProvider { + private final Interval[][] myIntervals = new Interval[2][]; + public static final IntervalsProvider EMPTY = new SimpleIntervalProvider(new Interval[0], new Interval[0]); + + public SimpleIntervalProvider(Interval[] intervals1, Interval[] intervals2) { + myIntervals[0] = intervals1; + myIntervals[1] = intervals2; + } + + public Interval[] getIntervals(FragmentSide side) { + return myIntervals[side.getIndex()]; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LinearTransformation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LinearTransformation.java new file mode 100644 index 00000000000..6f8c9486096 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/LinearTransformation.java @@ -0,0 +1,24 @@ +package com.intellij.openapi.diff.impl.splitter; + +class LinearTransformation implements Transformation { + private final int myK; + private final int myX0; + + public LinearTransformation(int offset, int lineHeight) { + myK = lineHeight; + myX0 = -offset; + } + + public int transform(int line) { + return linear(line, myX0, myK); + } + + private static int linear(int x, int x0, int k) { + return k*x + x0; + } + + public static int oneToOne(int x, int x0, Interval range) { + if (range.getLength() == 0) return range.getStart(); + return range.getStart() + Math.min(x - x0, range.getLength() - 1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Transformation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Transformation.java new file mode 100644 index 00000000000..88d369afaee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Transformation.java @@ -0,0 +1,5 @@ +package com.intellij.openapi.diff.impl.splitter; + +public interface Transformation { + int transform(int line); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Trapezium.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Trapezium.java new file mode 100644 index 00000000000..1044998278a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/splitter/Trapezium.java @@ -0,0 +1,41 @@ +package com.intellij.openapi.diff.impl.splitter; + +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; + +class Trapezium { + private final Interval myBase1; + private final Interval myBase2; + + public Trapezium(int start1, int length1, int start2, int length2) { + this(new Interval(start1, length1), new Interval(start2, length2)); + } + + public Trapezium(Interval base1, Interval base2) { + myBase1 = base1; + myBase2 = base2; + } + + public Interval getBase1() { return myBase1; } + + public Interval getBase2() { return myBase2; } + + public Interval getBase(FragmentSide side) { + if (FragmentSide.SIDE1 == side) return getBase1(); + if (FragmentSide.SIDE2 == side) return getBase2(); + throw side.invalidException(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Trapezium)) return false; + Trapezium other = (Trapezium) obj; + return myBase1.equals(other.myBase1) && myBase2.equals(other.myBase2); + } + + public int hashCode() { + return myBase1.hashCode() ^ myBase2.hashCode(); + } + + public String toString() { + return "{" + myBase1 + ", " + myBase2 + "}"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContentDocumentListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContentDocumentListener.java new file mode 100644 index 00000000000..efd9c83d587 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContentDocumentListener.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diff.DiffContent; +import com.intellij.openapi.diff.impl.DiffVersionComponent; + +public class ContentDocumentListener implements DiffContent.Listener { + private final DiffVersionComponent myDiffComponent; + + private ContentDocumentListener(DiffVersionComponent diffComponent) { + myDiffComponent = diffComponent; + } + + public static void install(final DiffContent content, DiffVersionComponent component) { + final ContentDocumentListener listener = new ContentDocumentListener(component); + content.onAssigned(true); + content.addListener(listener); + Disposeable disposeable = new Disposeable() { + public void dispose() { + content.onAssigned(false); + } + }; + component.addDisposable(disposeable); + } + + public void contentInvalid() { + myDiffComponent.removeContent(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContextLogger.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContextLogger.java new file mode 100644 index 00000000000..9d0d4170a20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ContextLogger.java @@ -0,0 +1,89 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; + +public class ContextLogger { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.ContextLogger"); + private final Logger myLogger; + private final Context myInfo; + private boolean myFirstError = true; + + public ContextLogger(Logger logger, Object context) { + this(logger, new SimpleContext(context)); + } + + public ContextLogger(Logger logger, Context context) { + myLogger = logger; + myInfo = context; + } + + public ContextLogger(String info) { + this(LOG, info); + assertTrue(isTestMode()); + } + + public void assertTrue(boolean condition) { + assertTrue(condition, ""); + } + + public void assertTrue(boolean condition, String message) { + if (condition) return; + logError("Assertion: " + message); + } + + private void logError(String message) { + if (myFirstError) { + myLogger.error(message, myInfo.getDetails()); + myFirstError = false; + } else myLogger.error(message); + } + + private boolean isTestMode() { + Application application = ApplicationManager.getApplication(); + return application == null || application.isUnitTestMode(); + } + + public void notImplemented() { + throwTestException("Not implemented"); + } + + private void throwTestException(String message) { + if (isTestMode()) throw new RuntimeException(message); + else logError(message); + } + + public void notTested() { + throwTestException("Not Tested"); + } + + public void error(String message) { + logError(message); + } + + public interface Context { + String[] getDetails(); + } + + public static class SimpleContext implements Context { + private final Object[] myContext; + + public SimpleContext(Object obj) { + this(new Object[]{obj}); + } + + public SimpleContext(Object[] data) { + myContext = data; + } + + public String[] getDetails() { + String[] result = new String[myContext.length]; + for (int i = 0; i < myContext.length; i++) { + Object object = myContext[i]; + result[i] = String.valueOf(object); + } + return result; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffDivider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffDivider.java new file mode 100644 index 00000000000..0bb0319c032 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffDivider.java @@ -0,0 +1,70 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.EditingSides; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.VisibleAreaEvent; +import com.intellij.openapi.editor.event.VisibleAreaListener; + +import javax.swing.*; +import java.awt.*; + +public class DiffDivider extends JComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.DiffDivider"); + private final Editor[] myEditors = new Editor[2]; + private final FragmentSide myLeftSide; + private DiffDividerPaint myPaint = null; + private static final int ourWidth = 30; + + private final VisibleAreaListener myVisibleAreaListener = new VisibleAreaListener() { + public void visibleAreaChanged(VisibleAreaEvent e) { + repaint(); + } + }; + + public DiffDivider(FragmentSide leftSide) { + myLeftSide = leftSide; + } + + public Dimension getPreferredSize() { + return new Dimension(ourWidth, 1); + } + + public void paint(Graphics g) { + super.paint(g); + if (myPaint != null) myPaint.paint(g, this); + } + + public DiffDividerPaint getPaint() { + return myPaint; + } + + public void stopListenEditors() { + for (int i = 0; i < myEditors.length; i++) { + Editor editor = myEditors[i]; + if (editor != null) { + editor.getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener); + myEditors[i] = null; + } + } + myPaint = null; + myEditors[0] = null; + myEditors[1] = null; + } + + public void listenEditors(EditingSides sides) { + stopListenEditors(); + LOG.assertTrue(sides != null); + myPaint = new DiffDividerPaint(sides, myLeftSide); + myEditors[0] = sides.getEditor(FragmentSide.SIDE1); + myEditors[1] = sides.getEditor(FragmentSide.SIDE2); + LOG.assertTrue((myEditors[0] != null) && (myEditors[1] != null), + String.valueOf(myEditors[1]) + " " + String.valueOf(myEditors[1])); + for (int i = 0; i < myEditors.length; i++) { + Editor editor = myEditors[i]; + editor.getScrollingModel().addVisibleAreaListener(myVisibleAreaListener); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java new file mode 100644 index 00000000000..78d5f34888d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java @@ -0,0 +1,150 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diff.DiffRequest; +import com.intellij.openapi.diff.DiffToolbar; +import com.intellij.openapi.diff.ex.DiffStatusBar; +import com.intellij.openapi.diff.impl.DiffToolbarComponent; +import com.intellij.openapi.editor.colors.EditorColorsScheme; + +import javax.swing.*; +import java.awt.*; +import java.util.List; + +public class DiffPanelOutterComponent extends JPanel implements DataProvider { + private final DiffStatusBar myStatusBar; + private final DiffToolbarComponent myToolbar; + private final DiffRequest.ToolbarAddons myDefaultActions; + private DataProvider myDataProvider = null; + private DeferScrollToFirstDiff myScrollState = NO_SCROLL_NEEDED; + private ScrollingPanel myScrollingPanel = null; + + public DiffPanelOutterComponent(List diffTypes, DiffRequest.ToolbarAddons defaultActions) { + super(new BorderLayout()); + myStatusBar = new DiffStatusBar(diffTypes); + add(myStatusBar, BorderLayout.SOUTH); + myDefaultActions = defaultActions; + myToolbar = new DiffToolbarComponent(this); + disableToolbar(false); + } + + public DiffToolbar resetToolbar() { + myToolbar.resetToolbar(myDefaultActions); + return myToolbar.getToolbar(); + } + + public void insertDiffComponent(JComponent component, ScrollingPanel scrollingPanel) { + add(component, BorderLayout.CENTER); + setScrollingPanel(scrollingPanel); + } + + public void setDataProvider(DataProvider dataProvider) { + myDataProvider = dataProvider; + } + + public void setStatusBarText(String text) { + myStatusBar.setText(text); + } + + public Object getData(String dataId) { + if (DataConstantsEx.SOURCE_NAVIGATION_LOCKED.equals(dataId)) return Boolean.TRUE; + if (myDataProvider == null) return null; + if (dataId == DataConstants.EDITOR) { + FocusDiffSide side = (FocusDiffSide)myDataProvider.getData(FocusDiffSide.FOCUSED_DIFF_SIDE); + if (side != null) return side.getEditor(); + } + return myDataProvider.getData(dataId); + } + + public void setScrollingPanel(ScrollingPanel scrollingPanel) { + myScrollingPanel = scrollingPanel; + } + + public void requestScrollEditors() { + myScrollState = SCROLL_WHEN_POSSIBLE; + tryScrollNow(); + } + + private void tryScrollNow() { + if (myScrollingPanel == null) return; + myScrollState.deferScroll(this); + } + + private void performScroll() { + DeferScrollToFirstDiff newState = myScrollState.scrollNow(myScrollingPanel, this); + if (newState != null) myScrollState = newState; + } + + public void addNotify() { + super.addNotify(); + tryScrollNow(); + } + + public void setBounds(int x, int y, int width, int height) { + super.setBounds(x, y, width, height); + tryScrollNow(); + } + + protected void validateTree() { + super.validateTree(); + tryScrollNow(); + } + + public void cancelScrollEditors() { + myScrollState = NO_SCROLL_NEEDED; + } + + private interface DeferScrollToFirstDiff { + DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component); + + void deferScroll(DiffPanelOutterComponent outter); + } + + public interface ScrollingPanel { + void scrollEditors(); + } + + private static final DeferScrollToFirstDiff NO_SCROLL_NEEDED = new DeferScrollToFirstDiff() { + public DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component) { + return NO_SCROLL_NEEDED; + } + + public void deferScroll(DiffPanelOutterComponent outter) { } + }; + + private static final DeferScrollToFirstDiff SCROLL_WHEN_POSSIBLE = new DeferScrollToFirstDiff() { + public DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component) { + if (!component.isDisplayable()) return null; + panel.scrollEditors(); + return NO_SCROLL_NEEDED; + } + + public void deferScroll(final DiffPanelOutterComponent outter) { + if (!outter.isDisplayable()) return; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + outter.performScroll(); + } + }); + } + }; + + public void disableToolbar(boolean disable) { + if (disable && isToolbarEnabled()) remove(myToolbar); + else if (myToolbar.getParent() == null) add(myToolbar, BorderLayout.NORTH); + } + + public boolean isToolbarEnabled() { + return myToolbar.getParent() != null; + } + + public void registerToolbarActions() { + myToolbar.getToolbar().registerKeyboardActions(this); + } + + public void setColorScheme(EditorColorsScheme scheme) { + myStatusBar.setColorScheme(scheme); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DocumentUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DocumentUtil.java new file mode 100644 index 00000000000..da5f8f258fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/DocumentUtil.java @@ -0,0 +1,51 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; + +import java.util.Comparator; + +public class DocumentUtil { + public static final Comparator RANGE_ORDER = new Comparator() { + public int compare(RangeMarker rangeMarker, RangeMarker rangeMarker1) { + return rangeMarker.getStartOffset() - rangeMarker1.getStartOffset(); + } + }; + + public static String getText(RangeMarker range) { + return range.getDocument().getText().substring(range.getStartOffset(), range.getEndOffset()); + } + + public static boolean isEmpty(RangeMarker rangeMarker) { + return rangeMarker.getStartOffset() == rangeMarker.getEndOffset(); + } + + public static int getStartLine(RangeMarker range) { + return range.getDocument().getLineNumber(range.getStartOffset()); + } + + public static int getEndLine(RangeMarker range) { + Document document = range.getDocument(); + int endOffset = range.getEndOffset(); + if (document.getTextLength() == endOffset) return document.getLineCount(); + return document.getLineNumber(endOffset); + } + + public static int getLength(RangeMarker rangeMarker) { + return rangeMarker.getEndOffset() - rangeMarker.getStartOffset(); + } + + public static Document createCopy(Document document, Project project) { + if (document == null) return null; + if (project != null) { + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + PsiFile psiFile = documentManager.getPsiFile(document); + if (psiFile != null) return documentManager.getDocument(psiFile.createPseudoPhysicalCopy()); + } + return EditorFactory.getInstance().createDocument(document.getText()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FocusDiffSide.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FocusDiffSide.java new file mode 100644 index 00000000000..ce96d293f0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FocusDiffSide.java @@ -0,0 +1,9 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.editor.Editor; + +public interface FocusDiffSide { + String FOCUSED_DIFF_SIDE = "focusedDiffSide"; + Editor getEditor(); + int[] getFragmentStartingLines(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FontSizeSynchronizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FontSizeSynchronizer.java new file mode 100644 index 00000000000..4840dd7815b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/FontSizeSynchronizer.java @@ -0,0 +1,76 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.incrementalMerge.ui.EditorPlace; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.util.containers.HashSet; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class FontSizeSynchronizer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.FontSizeSynchronizer"); + private final Collection myEditors = new HashSet(); + private final MyFontSizeListener myFontSizeListener = new MyFontSizeListener(); + private int myLastFontSize = -1; + + public void synchronize(EditorEx editor) { + LOG.assertTrue(!myEditors.contains(editor)); + editor.addPropertyChangeListener(myFontSizeListener); + myEditors.add(editor); + if (myLastFontSize != -1) myFontSizeListener.updateEditor(editor); + } + + public void stopSynchronize(EditorEx editor) { + LOG.assertTrue(myEditors.contains(editor)); + editor.removePropertyChangeListener(myFontSizeListener); + myEditors.remove(editor); + } + + public static void attachTo(ArrayList editorPlaces) { + final FontSizeSynchronizer synchronizer = new FontSizeSynchronizer(); + for (Iterator iterator = editorPlaces.iterator(); iterator.hasNext();) { + EditorPlace editorPlace = iterator.next(); + editorPlace.addListener(new EditorPlace.EditorListener() { + public void onEditorCreated(EditorPlace place) { + synchronizer.synchronize((EditorEx)place.getEditor()); + } + + public void onEditorReleased(Editor releasedEditor) { + synchronizer.stopSynchronize((EditorEx)releasedEditor); + } + }); + EditorEx editor = (EditorEx)editorPlace.getEditor(); + if (editor != null) synchronizer.synchronize(editor); + } + + } + + private class MyFontSizeListener implements PropertyChangeListener { + private boolean myDuringUpdate = false; + public void propertyChange(PropertyChangeEvent evt) { + if (myDuringUpdate) return; + if (!EditorEx.PROP_FONT_SIZE.equals(evt.getPropertyName())) return; + if (evt.getOldValue().equals(evt.getNewValue())) return; + myLastFontSize = ((Integer)evt.getNewValue()).intValue(); + for (Iterator iterator = myEditors.iterator(); iterator.hasNext();) { + Editor editor = iterator.next(); + if (editor == null || editor == evt.getSource()) continue; + updateEditor((EditorEx)editor); + } + } + + public void updateEditor(EditorEx editor) { + try { + myDuringUpdate = true; + editor.setFontSize(myLastFontSize); + } finally { + myDuringUpdate = false; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/GutterActionRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/GutterActionRenderer.java new file mode 100644 index 00000000000..71ec548bb6c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/GutterActionRenderer.java @@ -0,0 +1,22 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.editor.markup.GutterIconRenderer; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class GutterActionRenderer extends GutterIconRenderer { + private final AnAction myAction; + public static final Icon REPLACE_ARROW = IconLoader.getIcon("/diff/arrow.png"); + public static final Icon REMOVE_CROSS = IconLoader.getIcon("/diff/remove.png"); + + public GutterActionRenderer(AnAction action) { + myAction = action; + } + + public Icon getIcon() { return myAction.getTemplatePresentation().getIcon(); } + public AnAction getClickAction() { return myAction; } + public String getTooltipText() { return myAction.getTemplatePresentation().getText(); } + public boolean isNavigateAction() { return true; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/LabeledEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/LabeledEditor.java new file mode 100644 index 00000000000..e45f8160d83 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/LabeledEditor.java @@ -0,0 +1,34 @@ +package com.intellij.openapi.diff.impl.util; + +import javax.swing.*; +import java.awt.*; + +public class LabeledEditor extends JPanel { + private final JLabel myLabel = new JLabel(); + + public LabeledEditor() { + super(new BorderLayout()); + } + + private String addReadOnly(String title, boolean readonly) { + if (readonly) title += " (Read-only)"; + return title; + } + + public void setComponent(JComponent component, String title) { + removeAll(); + add(component, BorderLayout.CENTER); + add(myLabel, BorderLayout.NORTH); + setLabelTitle(title); + revalidate(); + } + + private void setLabelTitle(String title) { + myLabel.setText(title); + myLabel.setToolTipText(title); + } + + public void updateTitle(String title, boolean readonly) { + setLabelTitle(addReadOnly(title, readonly)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java new file mode 100644 index 00000000000..5589327c52c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java @@ -0,0 +1,158 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.EditingSides; +import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ScrollingModel; +import com.intellij.openapi.editor.event.VisibleAreaEvent; +import com.intellij.openapi.editor.event.VisibleAreaListener; +import com.intellij.openapi.util.Pair; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +public class SyncScrollSupport implements Disposeable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.SyncScrollSupport"); + private boolean myDuringVerticalScroll = false; + private final ArrayList myScrollers = new ArrayList(); + + public void install(EditingSides[] sideContainers) { + dispose(); + Editor[] editors = new Editor[sideContainers.length + 1]; + editors[0] = sideContainers[0].getEditor(FragmentSide.SIDE1); + for (int i = 0; i < sideContainers.length; i++) { + EditingSides sideContainer = sideContainers[i]; + LOG.assertTrue(sideContainer.getEditor(FragmentSide.SIDE1) == editors[i]); + editors[i + 1] = sideContainer.getEditor(FragmentSide.SIDE2); + } + if (editors.length == 3) install3(editors, sideContainers); + else if (editors.length == 2) install2(editors, sideContainers); + else LOG.error(String.valueOf(editors.length)); + } + + public void dispose() { + for (Iterator iterator = myScrollers.iterator(); iterator.hasNext();) { + ScrollListener scrollListener = iterator.next(); + scrollListener.dispose(); + } + myScrollers.clear(); + } + + private void install2(Editor[] editors, EditingSides[] sideContainers) { + addSlavesScroller(editors[0], new Pair[]{new Pair(FragmentSide.SIDE1, sideContainers[0])}); + addSlavesScroller(editors[1], new Pair[]{new Pair(FragmentSide.SIDE2, sideContainers[0])}); + } + + private void install3(Editor[] editors, EditingSides[] sideContainers) { + addSlavesScroller(editors[0], new Pair[]{new Pair(FragmentSide.SIDE1, sideContainers[0]), + new Pair(FragmentSide.SIDE1, sideContainers[1])}); + addSlavesScroller(editors[1], new Pair[]{new Pair(FragmentSide.SIDE2, sideContainers[0]), + new Pair(FragmentSide.SIDE1, sideContainers[1])}); + addSlavesScroller(editors[2], new Pair[]{new Pair(FragmentSide.SIDE2, sideContainers[1]), + new Pair(FragmentSide.SIDE2, sideContainers[0])}); + } + + private void addSlavesScroller(Editor editor, Pair[] contexts) { + ScrollListener scroller = new ScrollListener(contexts, editor); + scroller.install(); + myScrollers.add(scroller); + } + + private class ScrollListener implements VisibleAreaListener, Disposeable { + private final Pair[] myScrollContexts; + private final Editor myEditor; + + public ScrollListener(Pair[] scrollContexts, Editor editor) { + myScrollContexts = scrollContexts; + myEditor = editor; + install(); + } + + public void install() { + myEditor.getScrollingModel().addVisibleAreaListener(this); + } + + public void dispose() { + myEditor.getScrollingModel().removeVisibleAreaListener(this); + } + + public void visibleAreaChanged(VisibleAreaEvent e) { + if (myDuringVerticalScroll) return; + Rectangle newRectangle = e.getNewRectangle(); + Rectangle oldRectangle = e.getOldRectangle(); + if (newRectangle == null || oldRectangle == null) return; + myDuringVerticalScroll = true; + try { + for (int i = 0; i < myScrollContexts.length; i++) { + Pair context = (Pair)myScrollContexts[i]; + syncVerticalScroll(context, newRectangle, oldRectangle); + syncHorizontalScroll(context, newRectangle, oldRectangle); + } + } + finally { myDuringVerticalScroll = false; } + } + } + + private static void syncHorizontalScroll(Pair context, Rectangle newRectangle, Rectangle oldRectangle) { + int newScrollOffset = newRectangle.x; + if (newScrollOffset == oldRectangle.x) return; + EditingSides sidesContainer = context.getSecond(); + FragmentSide masterSide = context.getFirst(); + Editor slaveEditor = sidesContainer.getEditor(masterSide.otherSide()); + if (slaveEditor == null) return; + + ScrollingModel scrollingModel = slaveEditor.getScrollingModel(); + scrollingModel.disableAnimation(); + scrollingModel.scrollHorizontally(newScrollOffset); + scrollingModel.enableAnimation(); + } + + private static void syncVerticalScroll(Pair context, Rectangle newRectangle, Rectangle oldRectangle) { + if (newRectangle.y == oldRectangle.y && newRectangle.height == oldRectangle.height) return; + EditingSides sidesContainer = context.getSecond(); + FragmentSide masterSide = context.getFirst(); + + Editor master = sidesContainer.getEditor(masterSide); + Editor slave = sidesContainer.getEditor(masterSide.otherSide()); + + if (master == null || slave == null) return; + + Rectangle viewRect = master.getScrollingModel().getVisibleArea(); + int middleY = viewRect.height / 3; + + int materVerticalScrollOffset = master.getScrollingModel().getVerticalScrollOffset(); + int slaveVerticalScrollOffset = slave.getScrollingModel().getVerticalScrollOffset(); + + LogicalPosition masterPos = master.xyToLogicalPosition(new Point(viewRect.x, materVerticalScrollOffset + middleY)); + int masterCenterLine = masterPos.line; + int scrollToLine = sidesContainer.getLineBlocks().transform(masterSide, masterCenterLine) + 1; + int actualLine = scrollToLine - 1; + + + slave.getScrollingModel().disableAnimation(); + + if (scrollToLine <= 0) { + int offset = newRectangle.y - oldRectangle.y; + slave.getScrollingModel().scrollVertically(slaveVerticalScrollOffset + offset); + } + + int correction = (materVerticalScrollOffset + middleY) % master.getLineHeight(); + int scrollOffset = actualLine * slave.getLineHeight() - middleY; + slave.getScrollingModel().scrollVertically(scrollOffset + correction); + + slave.getScrollingModel().enableAnimation(); + } + + public static void scrollEditor(Editor editor, int logicalLine) { + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalLine, 0)); + ScrollingModel scrollingModel = editor.getScrollingModel(); + scrollingModel.disableAnimation(); + scrollingModel.scrollToCaret(ScrollType.CENTER); + scrollingModel.enableAnimation(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/TextDiffType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/TextDiffType.java new file mode 100644 index 00000000000..7f91726b35c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/TextDiffType.java @@ -0,0 +1,67 @@ +package com.intellij.openapi.diff.impl.util; + +import com.intellij.openapi.diff.DiffColors; +import com.intellij.openapi.diff.ex.DiffStatusBar; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.util.containers.Convertor; + +import java.awt.*; +import java.util.Arrays; +import java.util.List; + +public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor { + public static final TextDiffType INSERT = new TextDiffType("Inserted", DiffColors.DIFF_INSERTED); + public static final TextDiffType CHANGED = new TextDiffType("Changed", DiffColors.DIFF_MODIFIED); + public static final TextDiffType DELETED = new TextDiffType("Deleted", DiffColors.DIFF_DELETED); + public static final TextDiffType CONFLICT = new TextDiffType("Conflict", DiffColors.DIFF_CONFLICT); + + public static final TextDiffType NONE = new TextDiffType("None", null); + + public static final List DIFF_TYPES = Arrays.asList(new TextDiffType[]{DELETED, CHANGED, INSERT}); + public static final List MERGE_TYPES = Arrays.asList(new TextDiffType[]{DELETED, CHANGED, INSERT, CONFLICT}); + private final TextAttributesKey myAttributesKey; + private final String myDisplayName; + public static final Convertor ATTRIBUTES_KEY = new Convertor() { + public TextAttributesKey convert(TextDiffType textDiffType) { + return textDiffType.getAttributesKey(); + } + }; + + public TextDiffType(String displayName, TextAttributesKey attrubutesKey) { + myAttributesKey = attrubutesKey; + myDisplayName = displayName; + } + + public String getDisplayName() { + return myDisplayName; + } + + public Color getLegendColor(EditorColorsScheme colorScheme) { + TextAttributes attributes = getTextAttributes(colorScheme); + return attributes != null ? attributes.getBackgroundColor() : null; + } + + public TextAttributesKey getAttributesKey() { + return myAttributesKey; + } + + public TextAttributes getTextAttributes(EditorColorsScheme scheme) { + return scheme.getAttributes(myAttributesKey); + } + + public Color getPoligonColor(Editor editor1) { + return getLegendColor(editor1.getColorsScheme()); + } + + public TextAttributes getTextAttributes(Editor editor1) { + return getTextAttributes(editor1.getColorsScheme()); + } + + public Color getTextBackground(Editor editor) { + TextAttributes attributes = getTextAttributes(editor); + return attributes != null ? attributes.getBackgroundColor() : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ThreePanels.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ThreePanels.java new file mode 100644 index 00000000000..2b2000dc277 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/diff/impl/util/ThreePanels.java @@ -0,0 +1,47 @@ +package com.intellij.openapi.diff.impl.util; + +import javax.swing.*; + +public class ThreePanels extends JPanel { + private final JComponent[] myDividers; + private final JComponent[] myPanels; + + public ThreePanels(JComponent[] panels, JComponent[] dividers) { + myDividers = dividers; + myPanels = panels; + addAll(dividers); + addAll(panels); + } + + private void addAll(JComponent[] components) { + for (int i = 0; i < components.length; i++) { + JComponent component = components[i]; + add(component, -1); + } + } + + public void doLayout() { + int width = getWidth(); + int height = getHeight(); + int dividersTotalWidth = 0; + for (int i = 0; i < myDividers.length; i++) { + JComponent divider = myDividers[i]; + dividersTotalWidth += divider.getPreferredSize().width; + } + int panelWidth = (width - dividersTotalWidth) / 3; + int x = 0; + for (int i = 0; i < myPanels.length; i++) { + JComponent panel = myPanels[i]; + panel.setBounds(x, 0, panelWidth, height); + panel.validate(); + x += panelWidth; + if (i < myDividers.length) { + JComponent divider = myDividers[i]; + int dividerWidth = divider.getPreferredSize().width; + divider.setBounds(x, 0, dividerWidth, height); + divider.validate(); + x += dividerWidth; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/BackspaceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/BackspaceAction.java new file mode 100644 index 00000000000..b83ac7ca6e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/BackspaceAction.java @@ -0,0 +1,86 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 8:26:04 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.editor.ex.DocumentEx; + +public class BackspaceAction extends EditorAction { + public BackspaceAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP); + final SelectionModel selectionModel = editor.getSelectionModel(); + if (selectionModel.hasBlockSelection()) { + final LogicalPosition start = selectionModel.getBlockStart(); + final LogicalPosition end = selectionModel.getBlockEnd(); + int column = Math.min(start.column, end.column); + int startLine = Math.min(start.line, end.line); + int endLine = Math.max(start.line, end.line); + EditorModificationUtil.deleteBlockSelection(editor); + if (column > 0) { + for (int i = startLine; i <= endLine; i++) { + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column)); + doBackSpaceAtCaret(editor); + } + } + final int newColumn = Math.max(column - 1, 0); + selectionModel.setBlockSelection(new LogicalPosition(startLine, newColumn), new LogicalPosition(endLine, newColumn)); + return; + } + + doBackSpaceAtCaret(editor); + } + } + + public static void doBackSpaceAtCaret(Editor editor) { + if(editor.getSelectionModel().hasSelection()) { + int newOffset = editor.getSelectionModel().getSelectionStart(); + editor.getCaretModel().moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + EditorModificationUtil.deleteSelectedText(editor); + return; + } + + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + int colNumber = editor.getCaretModel().getLogicalPosition().column; + Document document = editor.getDocument(); + if(colNumber > 0) { + if(EditorModificationUtil.calcAfterLineEnd(editor) > 0) { + int columnShift = -1; + editor.getCaretModel().moveCaretRelatively(columnShift, 0, false, false, true); + } + else { + int offset = editor.getCaretModel().getOffset(); + editor.getCaretModel().moveToOffset(offset-1); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + document.deleteString(offset-1, offset); + } + } + else if(lineNumber > 0) { + int separatorLength = ((DocumentEx) document).getLineSeparatorLength(lineNumber - 1); + int lineEnd = document.getLineEndOffset(lineNumber - 1) + separatorLength; + editor.getCaretModel().moveToOffset(lineEnd - separatorLength); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + document.deleteString(lineEnd - separatorLength, lineEnd); + // Do not group delete newline and other deletions. + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.setCurrentCommandGroupId(null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CopyAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CopyAction.java new file mode 100644 index 00000000000..a72365bc19f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CopyAction.java @@ -0,0 +1,29 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 5:37:50 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class CopyAction extends EditorAction { + public CopyAction() { + super(new Handler()); + } + + public static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + if (!editor.getSelectionModel().hasSelection() && !editor.getSelectionModel().hasBlockSelection()) { + editor.getSelectionModel().selectLineAtCaret(); + } + editor.getSelectionModel().copySelectionToClipboard(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutAction.java new file mode 100644 index 00000000000..63def96841b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutAction.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 6:41:17 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class CutAction extends EditorAction { + public CutAction() { + super(new Handler()); + } + + public static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + if(!editor.getSelectionModel().hasSelection()) { + editor.getSelectionModel().selectLineAtCaret(); + } + editor.getSelectionModel().copySelectionToClipboard(); + EditorModificationUtil.deleteSelectedText(editor); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutLineEndAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutLineEndAction.java new file mode 100644 index 00000000000..458fba7b7a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/CutLineEndAction.java @@ -0,0 +1,72 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:29:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; + +public class CutLineEndAction extends EditorAction { + public CutLineEndAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + final Document doc = editor.getDocument(); + if (doc.getLineCount() == 0) return; + int caretOffset = editor.getCaretModel().getOffset(); + int lineEndOffset = doc.getLineEndOffset(doc.getLineNumber(caretOffset)); + + if (caretOffset >= lineEndOffset) return; + + copyToClipboard(doc, caretOffset, lineEndOffset, dataContext, editor); + + doc.deleteString(caretOffset, lineEndOffset); + } + + private void copyToClipboard(final Document doc, + int caretOffset, + int lineEndOffset, + DataContext dataContext, + Editor editor) { + String s = doc.getCharsSequence().subSequence(caretOffset, lineEndOffset).toString(); + + s = StringUtil.convertLineSeparators(s, "\n"); + StringSelection contents = new StringSelection(s); + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + Clipboard clipboard = editor.getComponent().getToolkit().getSystemClipboard(); + clipboard.setContents(contents, defaultClipboardOwner); + } + else { + CopyPasteManager.getInstance().setContents(contents); + } + } + } + + private static class ClipboardObserver implements ClipboardOwner { + public void lostOwnership(Clipboard clipboard, Transferable contents) { + } + } + + private static ClipboardOwner defaultClipboardOwner = new ClipboardObserver(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteAction.java new file mode 100644 index 00000000000..ae99b555342 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteAction.java @@ -0,0 +1,105 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 8:20:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class DeleteAction extends EditorAction { + public DeleteAction() { + super(new Handler()); + } + + public static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP); + SelectionModel selectionModel = editor.getSelectionModel(); + if (selectionModel.hasBlockSelection()) { + final LogicalPosition start = selectionModel.getBlockStart(); + final LogicalPosition end = selectionModel.getBlockEnd(); + if (start.column == end.column) { + int column = start.column; + int startLine = Math.min(start.line, end.line); + int endLine = Math.max(start.line, end.line); + for (int i = startLine; i <= endLine; i++) { + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column)); + deleteCharAtCaret(editor); + } + selectionModel.setBlockSelection(new LogicalPosition(startLine, column), new LogicalPosition(endLine, column)); + return; + } + EditorModificationUtil.deleteBlockSelection(editor); + } + else if (!selectionModel.hasSelection()) { + deleteCharAtCaret(editor); + } else { + EditorModificationUtil.deleteSelectedText(editor); + } + } + } + + private static int getCaretLineLength(Editor editor) { + Document document = editor.getDocument(); + if(document.getLineCount() == 0) + return 0; + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + if(lineNumber >= document.getLineCount()) { + return 0; + } + else { + return document.getLineEndOffset(lineNumber) - document.getLineStartOffset(lineNumber); + } + } + + private static int getCaretLineStart(Editor editor) { + Document document = editor.getDocument(); + if(document.getLineCount() == 0) + return 0; + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + if(lineNumber >= document.getLineCount()) { + return document.getLineStartOffset(document.getLineCount() - 1); + } + else { + return document.getLineStartOffset(lineNumber); + } + } + + private static void deleteCharAtCaret(Editor editor) { + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + int afterLineEnd = EditorModificationUtil.calcAfterLineEnd(editor); + Document document = editor.getDocument(); + if(afterLineEnd < 0) { + int offset = editor.getCaretModel().getOffset(); + document.deleteString(offset, offset + 1); + return; + } + if(lineNumber + 1 >= document.getLineCount()) + return; + + // Do not group delete newline and other deletions. + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.setCurrentCommandGroupId(null); + + int nextLineStart = document.getLineStartOffset(lineNumber + 1); + int nextLineEnd = document.getLineEndOffset(lineNumber + 1); + if(nextLineEnd - nextLineStart > 0) { + StringBuffer buf = new StringBuffer(); + for(int i=0; i= document.getLineCount()) + return; + + if (lineNumber == document.getLineCount() - 1){ + if (document.getLineCount() > 0 && lineNumber > 0){ + int start = document.getLineEndOffset(lineNumber - 1); + int end = document.getLineEndOffset(lineNumber) + ((DocumentEx) document).getLineSeparatorLength(lineNumber); + document.deleteString(start, end); + LogicalPosition pos = new LogicalPosition(lineNumber - 1, logicalPosition.column); + editor.getCaretModel().moveToLogicalPosition(pos); + } + else{ + document.deleteString(0, document.getTextLength()); + editor.getCaretModel().moveToOffset(0); + } + } + else{ + VisualPosition caretPosition = editor.getCaretModel().getVisualPosition(); + VisualPosition thisLineVisible = new VisualPosition(caretPosition.line, 0); + LogicalPosition thisLineLogical = editor.visualToLogicalPosition(thisLineVisible); + VisualPosition nextLineVisible = new VisualPosition(caretPosition.line + 1, 0); + LogicalPosition nextLineLogical = editor.visualToLogicalPosition(nextLineVisible); + + int startOffset = editor.logicalPositionToOffset(thisLineLogical); + int endOffset = editor.logicalPositionToOffset(nextLineLogical); + + document.deleteString(startOffset, endOffset); + } + + editor.getCaretModel().moveToLogicalPosition(logicalPosition); + editor.getSelectionModel().removeSelection(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordEndAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordEndAction.java new file mode 100644 index 00000000000..23dc767a8bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordEndAction.java @@ -0,0 +1,61 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 7:18:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class DeleteToWordEndAction extends EditorAction { + public DeleteToWordEndAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP); + deleteToWordEnd(editor); + } + } + + private static void deleteToWordEnd(Editor editor) { + int startOffset = editor.getCaretModel().getOffset(); + int endOffset = getWordEndOffset(editor, startOffset); + if(endOffset > startOffset) { + Document document = editor.getDocument(); + document.deleteString(startOffset, endOffset); + } + } + + private static int getWordEndOffset(Editor editor, int offset) { + Document document = editor.getDocument(); + CharSequence text = document.getCharsSequence(); + if(offset >= document.getTextLength() - 1) + return offset; + int newOffset = offset + 1; + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + int maxOffset = document.getLineEndOffset(lineNumber); + if(newOffset > maxOffset) { + if(lineNumber+1 >= document.getLineCount()) + return offset; + maxOffset = document.getLineEndOffset(lineNumber+1); + } + boolean camel = editor.getSettings().isCamelWords(); + for (; newOffset < maxOffset; newOffset++) { + if (EditorActionUtil.isWordEnd(text.charAt(newOffset - 1), text.charAt(newOffset), camel) || + EditorActionUtil.isWordStart(text.charAt(newOffset - 1), text.charAt(newOffset), camel)) { + break; + } + } + return newOffset; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordStartAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordStartAction.java new file mode 100644 index 00000000000..6c5465977f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DeleteToWordStartAction.java @@ -0,0 +1,37 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 7:18:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.actionSystem.DataContext; + +public class DeleteToWordStartAction extends EditorAction { + public DeleteToWordStartAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP); + deleteToWordStart(editor); + } + } + + private static void deleteToWordStart(Editor editor) { + int endOffset = editor.getCaretModel().getOffset(); + EditorActionUtil.moveCaretToPreviousWord(editor, false); + int startOffset = editor.getCaretModel().getOffset(); + Document document = editor.getDocument(); + document.deleteString(startOffset, endOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DuplicateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DuplicateAction.java new file mode 100644 index 00000000000..e337951c33b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/DuplicateAction.java @@ -0,0 +1,55 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 7:18:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.editor.ex.DocumentEx; + +public class DuplicateAction extends EditorAction { + public DuplicateAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + duplicateLineOrSelectedBlockAtCaret(editor); + } + } + + private static void duplicateLineOrSelectedBlockAtCaret(Editor editor) { + Document document = editor.getDocument(); + if(editor.getSelectionModel().hasSelection()) { + int start = editor.getSelectionModel().getSelectionStart(); + int end = editor.getSelectionModel().getSelectionEnd(); + String s = document.getCharsSequence().subSequence(start, end).toString(); + document.insertString(end, s); + editor.getCaretModel().moveToOffset(end+s.length()); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + editor.getSelectionModel().setSelection(end, end+s.length()); + } + else { + VisualPosition caret = editor.getCaretModel().getVisualPosition(); + LogicalPosition lineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line, 0)); + LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0)); + + int start = editor.logicalPositionToOffset(lineStart); + int end = editor.logicalPositionToOffset(nextLineStart); + String s = document.getCharsSequence().subSequence(start, end).toString(); + if(((DocumentEx) document).getLineSeparatorLength(nextLineStart.line - 1) == 0) { + s = "\n"+s; + } + document.insertString(end, s); + editor.getCaretModel().moveCaretRelatively(0, 1, false, false, true); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EditorActionUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EditorActionUtil.java new file mode 100644 index 00000000000..1c0ed46fcb5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -0,0 +1,434 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 6, 2002 + * Time: 4:54:58 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; + +import java.awt.*; + +public class EditorActionUtil { + protected static final Object EDIT_COMMAND_GROUP = Key.create("EditGroup"); + protected static final Object DELETE_COMMAND_GROUP = Key.create("DeleteGroup"); + + public static void scrollRelatively(Editor editor, int lineShift) { + if (lineShift != 0) { + editor.getScrollingModel().scrollVertically( + editor.getScrollingModel().getVerticalScrollOffset() + lineShift * editor.getLineHeight() + ); + } + + Rectangle viewRectangle = editor.getScrollingModel().getVisibleArea(); + int lineNumber = editor.getCaretModel().getVisualPosition().line; + if (viewRectangle != null) { + VisualPosition startPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y)); + int start = startPos.line + 1; + VisualPosition endPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y + viewRectangle.height)); + int end = endPos.line - 2; + if (lineNumber < start) { + editor.getCaretModel().moveCaretRelatively(0, start - lineNumber, false, false, true); + } + else if (lineNumber > end) { + editor.getCaretModel().moveCaretRelatively(0, end - lineNumber, false, false, true); + } + } + } + + public static void moveCaretRelativelyAndScroll(Editor editor, + int columnShift, + int lineShift, + boolean withSelection) { + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + VisualPosition pos = editor.getCaretModel().getVisualPosition(); + Point caretLocation = editor.visualPositionToXY(pos); + int caretVShift = caretLocation.y - viewRect.y; + + editor.getCaretModel().moveCaretRelatively(columnShift, lineShift, withSelection, false, false); + + //editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + VisualPosition caretPos = editor.getCaretModel().getVisualPosition(); + Point caretLocation2 = editor.visualPositionToXY(caretPos); + editor.getScrollingModel().scrollVertically(caretLocation2.y - caretVShift); + } + + public static void indentLine(Project project, Editor editor, int lineNumber, int indent) { + EditorSettings editorSettings = editor.getSettings(); + Document document = editor.getDocument(); + int spacesEnd = 0; + int lineStart = 0; + if (lineNumber < document.getLineCount()) { + lineStart = document.getLineStartOffset(lineNumber); + int lineEnd = document.getLineEndOffset(lineNumber); + spacesEnd = lineStart; + CharSequence text = document.getCharsSequence(); + for (; spacesEnd <= lineEnd; spacesEnd++) { + if (spacesEnd == lineEnd) { + break; + } + char c = text.charAt(spacesEnd); + if (c != '\t' && c != ' ') { + break; + } + } + } + int oldLength = editor.offsetToLogicalPosition(spacesEnd).column; + + int newLength = oldLength + indent; + if (newLength < 0) { + newLength = 0; + } + StringBuffer buf = new StringBuffer(newLength); + int tabSize = editorSettings.getTabSize(project); + for (int i = 0; i < newLength;) { + if (tabSize > 0 && editorSettings.isUseTabCharacter(project) && i + tabSize <= newLength) { + buf.append('\t'); + i += tabSize; + } + else { + buf.append(' '); + i++; + } + } + + int newCaretOffset = editor.getCaretModel().getOffset(); + if (newCaretOffset >= spacesEnd) { + newCaretOffset += buf.length() - (spacesEnd - lineStart); + } + + if (buf.length() > 0) { + if (spacesEnd > lineStart) { + document.replaceString(lineStart, spacesEnd, buf.toString()); + } + else { + document.insertString(lineStart, buf.toString()); + } + } + else { + if (spacesEnd > lineStart) { + document.deleteString(lineStart, spacesEnd); + } + } + + editor.getCaretModel().moveToOffset(newCaretOffset); + } + + public static boolean isWordStart(char first, char second, boolean isCamel) { + final boolean firstIsIdentifierPart = Character.isJavaIdentifierPart(first); + final boolean secondIsIdentifierPart = Character.isJavaIdentifierPart(second); + if (!firstIsIdentifierPart && secondIsIdentifierPart) { + return true; + } + + if (isCamel) { + if (firstIsIdentifierPart && secondIsIdentifierPart && + (Character.isLowerCase(first) && Character.isUpperCase(second) || first == '_' && second != '_')) { + return true; + } + } + + return (Character.isWhitespace(first) || firstIsIdentifierPart) && + !Character.isWhitespace(second) && !secondIsIdentifierPart; + } + + public static boolean isWordEnd(char first, char second, boolean isCamel) { + final boolean firstIsIdentifiePart = Character.isJavaIdentifierPart(first); + final boolean secondIsIdentifierPart = Character.isJavaIdentifierPart(second); + if (firstIsIdentifiePart && !secondIsIdentifierPart) { + return true; + } + + if (isCamel) { + if (firstIsIdentifiePart && secondIsIdentifierPart && + (Character.isLowerCase(first) && Character.isUpperCase(second) || first != '_' && second == '_')) { + return true; + } + } + + return !Character.isWhitespace(first) && !firstIsIdentifiePart && + (Character.isWhitespace(second) || secondIsIdentifierPart); + } + + public static void moveCaretToLineStart(Editor editor, boolean isWithSelection) { + Document document = editor.getDocument(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + + int columnNumber = editor.getCaretModel().getLogicalPosition().column; + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + + VisualPosition visCaret = editor.getCaretModel().getVisualPosition(); + while (lineNumber >= 0 && editor.logicalToVisualPosition(new LogicalPosition(lineNumber, 0)).line == visCaret.line) lineNumber--; + lineNumber++; + + EditorSettings editorSettings = editor.getSettings(); + if (!editorSettings.isSmartHome()) { + LogicalPosition pos = new LogicalPosition(lineNumber, 0); + editor.getCaretModel().moveToLogicalPosition(pos); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + return; + } + + int offset = editor.getCaretModel().getOffset(); + if (lineNumber >= document.getLineCount() || offset >= document.getTextLength()) { + int newColNumber = 0; + if (columnNumber == 0) { + newColNumber = findSmartIndent(editor, offset); + } + LogicalPosition pos = new LogicalPosition(lineNumber, newColNumber); + editor.getCaretModel().moveToLogicalPosition(pos); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + return; + } + + int start = findFirstNonspaceOffsetOnTheLine(document, lineNumber); + int lineEnd = document.getLineEndOffset(lineNumber); + if (lineNumber > 0 && lineEnd == start && columnNumber == 0) { + int newColNumber = findSmartIndent(editor, offset); + LogicalPosition pos = new LogicalPosition(lineNumber, newColNumber); + editor.getCaretModel().moveToLogicalPosition(pos); + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + return; + } + + int lineStart = document.getLineStartOffset(lineNumber); + int newOffset = lineStart; + if (start < offset || columnNumber == 0) { + newOffset = start; + } + editor.getCaretModel().moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } + + private static int findSmartIndent(Editor editor, int offset) { + int nonSpaceLineNumber = findFirstNonspaceLineBack(editor.getDocument(), offset); + if (nonSpaceLineNumber >= 0) { + int newOffset = findFirstNonspaceOffsetOnTheLine(editor.getDocument(), nonSpaceLineNumber); + return editor.offsetToLogicalPosition(newOffset).column; + } + return 0; + } + + private static int findFirstNonspaceLineBack(Document document, int offset) { + CharSequence text = document.getCharsSequence(); + int foundOffset = offset - 1; + for (; foundOffset > 0; foundOffset--) { + char c = text.charAt(foundOffset); + if (c != ' ' && c != '\t' && c != '\r' && c != '\n') { + break; + } + } + if (foundOffset == -1) { + return -1; + } + else { + return document.getLineNumber(foundOffset); + } + } + + private static int findFirstNonspaceOffsetOnTheLine(Document document, int lineNumber) { + int lineStart = document.getLineStartOffset(lineNumber); + int lineEnd = document.getLineEndOffset(lineNumber); + CharSequence text = document.getCharsSequence(); + int start = lineStart; + for (; start < lineEnd; start++) { + char c = text.charAt(start); + if (c != ' ' && c != '\t') { + return start; + } + } + return lineEnd; + } + + public static void moveCaretToLineEnd(Editor editor, boolean isWithSelection) { + Document document = editor.getDocument(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + if (lineNumber >= document.getLineCount()) { + LogicalPosition pos = new LogicalPosition(lineNumber, 0); + editor.getCaretModel().moveToLogicalPosition(pos); + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + return; + } + VisualPosition visCaret = editor.getCaretModel().getVisualPosition(); + visCaret = new VisualPosition(visCaret.line, EditorUtil.getLastVisualLineColumnNumber(editor, visCaret.line)); + + LogicalPosition logLineEnd = editor.visualToLogicalPosition(visCaret); + int offset = editor.logicalPositionToOffset(logLineEnd); + lineNumber = logLineEnd.line; + int newOffset = offset; + + CharSequence text = document.getCharsSequence(); + for (int i = newOffset - 1; i >= document.getLineStartOffset(lineNumber); i--) { + if (text.charAt(i) != ' ' && text.charAt(i) != '\t') { + break; + } + newOffset = i; + } + + if (newOffset == editor.getCaretModel().getOffset()) { + newOffset = offset; + } + + editor.getCaretModel().moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } + + public static void moveCaretToNextWord(Editor editor, boolean isWithSelection) { + Document document = editor.getDocument(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + + int offset = caretModel.getOffset(); + CharSequence text = document.getCharsSequence(); + if (offset == document.getTextLength() - 1) { + return; + } + int newOffset = offset + 1; + int lineNumber = caretModel.getLogicalPosition().line; + if (lineNumber >= document.getLineCount()) return; + int maxOffset = document.getLineEndOffset(lineNumber); + if (newOffset > maxOffset) { + if (lineNumber + 1 >= document.getLineCount()) { + return; + } + maxOffset = document.getLineEndOffset(lineNumber + 1); + } + boolean camel = editor.getSettings().isCamelWords(); + for (; newOffset < maxOffset; newOffset++) { + if (isWordStart(text.charAt(newOffset - 1), text.charAt(newOffset), camel)) { + break; + } + } + caretModel.moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } + + private static void setupSelection(Editor editor, + boolean isWithSelection, + int selectionStart, LogicalPosition blockSelectionStart) { + if (isWithSelection) { + if (editor.isColumnMode()) { + editor.getSelectionModel().setBlockSelection(blockSelectionStart, editor.getCaretModel().getLogicalPosition()); + } + else { + editor.getSelectionModel().setSelection(selectionStart, editor.getCaretModel().getOffset()); + } + } + else { + editor.getSelectionModel().removeSelection(); + } + } + + public static void moveCaretToPreviousWord(Editor editor, boolean isWithSelection) { + Document document = editor.getDocument(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + + int offset = editor.getCaretModel().getOffset(); + if (offset == 0) return; + + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + CharSequence text = document.getCharsSequence(); + int newOffset = offset - 1; + int minOffset = lineNumber > 0 ? document.getLineEndOffset(lineNumber - 1) : 0; + boolean camel = editor.getSettings().isCamelWords(); + for (; newOffset > minOffset; newOffset--) { + if (isWordStart(text.charAt(newOffset - 1), text.charAt(newOffset), camel)) break; + } + editor.getCaretModel().moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } + + public static void moveCaretPageUp(Editor editor, boolean isWithSelection) { + int lineHeight = editor.getLineHeight(); + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + int linesIncrement = viewRect.height / lineHeight; + editor.getScrollingModel().scrollVertically(viewRect.y - viewRect.y % lineHeight - linesIncrement * lineHeight); + int lineShift = -linesIncrement; + editor.getCaretModel().moveCaretRelatively(0, lineShift, isWithSelection, editor.isColumnMode(), true); + } + + public static void moveCaretPageDown(Editor editor, boolean isWithSelection) { + int lineHeight = editor.getLineHeight(); + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + int linesIncrement = viewRect.height / lineHeight; + int allowedBottom = ((EditorEx)editor).getContentSize().height - viewRect.height; + editor.getScrollingModel().scrollVertically( + Math.min(allowedBottom, viewRect.y - viewRect.y % lineHeight + linesIncrement * lineHeight)); + editor.getCaretModel().moveCaretRelatively(0, linesIncrement, isWithSelection, editor.isColumnMode(), true); + } + + public static void moveCaretPageTop(Editor editor, boolean isWithSelection) { + int lineHeight = editor.getLineHeight(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + int lineNumber = viewRect.y / lineHeight; + if (viewRect.y % lineHeight > 0) { + lineNumber++; + } + VisualPosition pos = new VisualPosition(lineNumber, editor.getCaretModel().getVisualPosition().column); + editor.getCaretModel().moveToVisualPosition(pos); + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } + + public static void moveCaretPageBottom(Editor editor, boolean isWithSelection) { + int lineHeight = editor.getLineHeight(); + SelectionModel selectionModel = editor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + CaretModel caretModel = editor.getCaretModel(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : caretModel.getLogicalPosition(); + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + int lineNumber = (viewRect.y + viewRect.height) / lineHeight - 1; + VisualPosition pos = new VisualPosition(lineNumber, editor.getCaretModel().getVisualPosition().column); + editor.getCaretModel().moveToVisualPosition(pos); + setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EmacsStyleIndentAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EmacsStyleIndentAction.java new file mode 100644 index 00000000000..a851d4a078d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EmacsStyleIndentAction.java @@ -0,0 +1,74 @@ + +package com.intellij.openapi.editor.actions; + +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.generation.AutoIndentLinesHandler; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.IncorrectOperationException; +import com.intellij.ide.util.JavaUtil; + +public class EmacsStyleIndentAction extends BaseCodeInsightAction{ + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.actions.EmacsStyleIndentAction"); + + protected CodeInsightActionHandler getHandler() { + return new Handler(); + } + + public boolean startInWriteAction() { + return false; + } + + protected boolean isValidForFile(final Project project, final Editor editor, final PsiFile file) { + return file.canContainJavaCode() || file instanceof XmlFile; + } + + //---------------------------------------------------------------------- + private static class Handler implements CodeInsightActionHandler { + + public void invoke(final Project project, final Editor editor, final PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + if (!file.isWritable()){ + (editor.getDocument()).fireReadOnlyModificationAttempt(); + return; + } + + final Document document = editor.getDocument(); + final int startOffset = editor.getCaretModel().getOffset(); + final int line = editor.offsetToLogicalPosition(startOffset).line; + final int col = editor.getCaretModel().getLogicalPosition().column; + final int lineStart = document.getLineStartOffset(line); + final int initLineEnd = document.getLineEndOffset(line); + try{ + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + final int newPos = codeStyleManager.adjustLineIndent(file, lineStart); + final int newCol = newPos - lineStart; + final int lineInc = document.getLineEndOffset(line) - initLineEnd; + if (newCol >= col + lineInc) { + final LogicalPosition pos = new LogicalPosition(line, newCol); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + + public boolean startInWriteAction() { + return true; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EnterAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EnterAction.java new file mode 100644 index 00000000000..e5f3475b000 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EnterAction.java @@ -0,0 +1,82 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:35:30 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +public class EnterAction extends EditorAction { + public EnterAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandName("Typing"); + insertNewLineAtCaret(editor); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + return !editor.isOneLineMode(); + } + } + + private static void insertNewLineAtCaret(Editor editor) { + if(!editor.isInsertMode()) { + if(editor.getCaretModel().getLogicalPosition().line < editor.getDocument().getLineCount()-1) { + LogicalPosition pos = new LogicalPosition(editor.getCaretModel().getLogicalPosition().line+1, 0); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + return; + } + EditorModificationUtil.deleteSelectedText(editor); + // Smart indenting here: + Document document = editor.getDocument(); + CharSequence text = document.getCharsSequence(); + + int indentLineNum = editor.getCaretModel().getLogicalPosition().line; + int lineLength = 0; + if (document.getLineCount() > 0) { + for(;indentLineNum >= 0; indentLineNum--) { + lineLength = document.getLineEndOffset(indentLineNum) - document.getLineStartOffset(indentLineNum); + if(lineLength > 0) + break; + } + } else { + indentLineNum = -1; + } + + int colNumber = editor.getCaretModel().getLogicalPosition().column; + StringBuffer buf = new StringBuffer(); + if(indentLineNum >= 0) { + int lineStartOffset = document.getLineStartOffset(indentLineNum); + for(int i = 0; i < lineLength; i++) { + char c = text.charAt(lineStartOffset + i); + if(c != ' ' && c != '\t') { + break; + } + if(i >= colNumber) { + break; + } + buf.append(c); + } + } + int caretOffset = editor.getCaretModel().getOffset(); + String s = "\n"+buf; + document.insertString(caretOffset, s); + editor.getCaretModel().moveToOffset(caretOffset + s.length()); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EscapeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EscapeAction.java new file mode 100644 index 00000000000..2b8badc6fcb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/EscapeAction.java @@ -0,0 +1,34 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 15, 2002 + * Time: 8:25:25 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class EscapeAction extends EditorAction { + public EscapeAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getSelectionModel().removeSelection(); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + SelectionModel selectionModel = editor.getSelectionModel(); + return dataContext.getData(DataConstants.IS_MODAL_CONTEXT) != Boolean.TRUE && + (selectionModel.hasSelection() || selectionModel.hasBlockSelection()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindAction.java new file mode 100644 index 00000000000..1adce3ac6c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindAction.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.editor.actions; + +import com.intellij.find.FindUtil; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.project.Project; + +public class FindAction extends EditorAction { + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + FindUtil.find(project, editor); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + return project != null; + } + } + + public FindAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindWordAtCaretAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindWordAtCaretAction.java new file mode 100644 index 00000000000..0475af508e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/FindWordAtCaretAction.java @@ -0,0 +1,36 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 18, 2002 + * Time: 5:49:15 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.find.FindUtil; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; + +public class FindWordAtCaretAction extends EditorAction { + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + FindUtil.findWordAtCaret(project, editor); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + return project != null; + } + } + + public FindWordAtCaretAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/IndentSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/IndentSelectionAction.java new file mode 100644 index 00000000000..ad25eb1d611 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/IndentSelectionAction.java @@ -0,0 +1,69 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 10:29:01 PM + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +public class IndentSelectionAction extends EditorAction { + public IndentSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + indentSelection(editor, project); + } + } + + public void update(Editor editor, Presentation presentation, DataContext dataContext) { + presentation.setEnabled(isEnabled(editor)); + } + + private boolean isEnabled(Editor editor) { + return editor.getSelectionModel().hasSelection() && !editor.isOneLineMode(); + } + + private static void indentSelection(Editor editor, Project project) { + if(!editor.getSelectionModel().hasSelection()) + return; + + int oldSelectionStart = editor.getSelectionModel().getSelectionStart(); + int oldSelectionEnd = editor.getSelectionModel().getSelectionEnd(); + + Document document = editor.getDocument(); + int startIndex = document.getLineNumber(oldSelectionStart); + if(startIndex == -1) { + startIndex = document.getLineCount() - 1; + } + int endIndex = document.getLineNumber(oldSelectionEnd); + if(endIndex > 0 && document.getLineStartOffset(endIndex) == oldSelectionEnd) { + endIndex --; + } + if(endIndex == -1) { + endIndex = document.getLineCount() - 1; + } + VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); + final FileType fileType = vFile == null ? null : FileTypeManager.getInstance().getFileTypeByFile(vFile); + int blockIndent = CodeStyleSettingsManager.getSettings(project).getIndentSize(fileType); + for(int i=startIndex; i<=endIndex; i++) { + EditorActionUtil.indentLine(project, editor, i, blockIndent); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/JoinLinesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/JoinLinesAction.java new file mode 100644 index 00000000000..3f780b365e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/JoinLinesAction.java @@ -0,0 +1,61 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 20, 2002 + * Time: 6:21:42 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.editor.ex.DocumentEx; + +public class JoinLinesAction extends EditorAction { + public JoinLinesAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + final DocumentEx doc = (DocumentEx) editor.getDocument(); + + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + int startLine = caretPosition.line; + int endLine = startLine + 1; + if (editor.getSelectionModel().hasSelection()) { + startLine = doc.getLineNumber(editor.getSelectionModel().getSelectionStart()); + endLine = doc.getLineNumber(editor.getSelectionModel().getSelectionEnd()); + if (doc.getLineStartOffset(endLine) == editor.getSelectionModel().getSelectionEnd()) endLine--; + } + + int caretRestoreOffset = -1; + + for (int i = startLine; i < endLine; i++) { + if (i >= doc.getLineCount() - 1) break; + CharSequence text = doc.getCharsSequence(); + int end = doc.getLineEndOffset(startLine) + doc.getLineSeparatorLength(startLine); + int start = end - doc.getLineSeparatorLength(startLine); + while (start > 0 && (text.charAt(start) == ' ' || text.charAt(start) == '\t')) start--; + if (caretRestoreOffset == -1) caretRestoreOffset = start + 1; + while (end < doc.getTextLength() && (text.charAt(end) == ' ' || text.charAt(end) == '\t')) end++; + doc.replaceString(start, end, " "); + } + + if (editor.getSelectionModel().hasSelection()) { + editor.getCaretModel().moveToOffset(editor.getSelectionModel().getSelectionEnd()); + } else { + if (caretRestoreOffset != -1) { + editor.getCaretModel().moveToOffset(caretRestoreOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndAction.java new file mode 100644 index 00000000000..ca3c9dd91a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:29:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class LineEndAction extends EditorAction { + public LineEndAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToLineEnd(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndWithSelectionAction.java new file mode 100644 index 00000000000..f5c07ed8869 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineEndWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:29:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class LineEndWithSelectionAction extends EditorAction { + public LineEndWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToLineEnd(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartAction.java new file mode 100644 index 00000000000..9c35e61bb2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:29:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class LineStartAction extends EditorAction { + public LineStartAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToLineStart(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartWithSelectionAction.java new file mode 100644 index 00000000000..cb20f671c6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/LineStartWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:29:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class LineStartWithSelectionAction extends EditorAction { + public LineStartWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToLineStart(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownAction.java new file mode 100644 index 00000000000..6ab1939ad5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownAction.java @@ -0,0 +1,30 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretDownAction extends EditorAction { + public MoveCaretDownAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getCaretModel().moveCaretRelatively(0, 1, false, false, true); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + return !editor.isOneLineMode(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java new file mode 100644 index 00000000000..77c787070e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretDownWithSelectionAction extends EditorAction { + public MoveCaretDownWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getCaretModel().moveCaretRelatively(0, 1, true, editor.isColumnMode(), true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftAction.java new file mode 100644 index 00000000000..dc3688fb0bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftAction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretLeftAction extends EditorAction { + public MoveCaretLeftAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + int columnShift = -1; + editor.getCaretModel().moveCaretRelatively(columnShift, 0, false, false, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java new file mode 100644 index 00000000000..9fa71f8a8e6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretLeftWithSelectionAction extends EditorAction { + public MoveCaretLeftWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + int columnShift = -1; + editor.getCaretModel().moveCaretRelatively(columnShift, 0, true, editor.isColumnMode(), true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightAction.java new file mode 100644 index 00000000000..dae2d23be79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretRightAction extends EditorAction { + public MoveCaretRightAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getCaretModel().moveCaretRelatively(1, 0, false, false, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java new file mode 100644 index 00000000000..de6cfc93832 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretRightWithSelectionAction extends EditorAction { + public MoveCaretRightWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getCaretModel().moveCaretRelatively(1, 0, true, editor.isColumnMode(), true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpAction.java new file mode 100644 index 00000000000..f988e187129 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpAction.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretUpAction extends EditorAction { + public MoveCaretUpAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + int lineShift = -1; + editor.getCaretModel().moveCaretRelatively(0, lineShift, false, false, true); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + return !editor.isOneLineMode(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java new file mode 100644 index 00000000000..a4327ad28ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:58:23 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class MoveCaretUpWithSelectionAction extends EditorAction { + public MoveCaretUpWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + int lineShift = -1; + editor.getCaretModel().moveCaretRelatively(0, lineShift, true, editor.isColumnMode(), true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownAndScrollAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownAndScrollAction.java new file mode 100644 index 00000000000..8d81f533356 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownAndScrollAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:20:22 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class MoveDownAndScrollAction extends EditorAction { + public MoveDownAndScrollAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretRelativelyAndScroll(editor, 0, 1, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownWithSelectionAndScrollAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownWithSelectionAndScrollAction.java new file mode 100644 index 00000000000..503db83d9cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveDownWithSelectionAndScrollAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:20:22 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class MoveDownWithSelectionAndScrollAction extends EditorAction { + public MoveDownWithSelectionAndScrollAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretRelativelyAndScroll(editor, 0, 1, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpAndScrollAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpAndScrollAction.java new file mode 100644 index 00000000000..bb73279631c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpAndScrollAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:20:22 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class MoveUpAndScrollAction extends EditorAction { + public MoveUpAndScrollAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretRelativelyAndScroll(editor, 0, -1, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpWithSelectionAndScrollAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpWithSelectionAndScrollAction.java new file mode 100644 index 00000000000..6aea7c98be5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MoveUpWithSelectionAndScrollAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:20:22 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class MoveUpWithSelectionAndScrollAction extends EditorAction { + public MoveUpWithSelectionAndScrollAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretRelativelyAndScroll(editor, 0, -1, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MultiplePasteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MultiplePasteAction.java new file mode 100644 index 00000000000..4d9b059dd48 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/MultiplePasteAction.java @@ -0,0 +1,252 @@ +package com.intellij.openapi.editor.actions; + +import com.intellij.ide.CopyPasteManagerEx; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.text.DefaultEditorKit; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.*; +import java.io.IOException; +import java.util.ArrayList; + +/** + * @author max + */ +public class MultiplePasteAction extends AnAction { + private static final Icon textIcon = IconLoader.getIcon("/fileTypes/text.png"); + + public MultiplePasteAction() { + setEnabledInModalContext(true); + } + + public void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + Component focusedComponent = (Component)dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT); + Editor editor = (Editor)dataContext.getData(DataConstants.EDITOR); + + if (!(focusedComponent instanceof JComponent)) return; + + final Chooser chooser = new Chooser(project); + + if (chooser.myAllContents.length > 0) { + chooser.show(); + } + else { + chooser.close(Chooser.CANCEL_EXIT_CODE); + } + + if (chooser.isOK()) { + final int selectedIndex = chooser.getSelectedIndex(); + ((CopyPasteManagerEx)CopyPasteManager.getInstance()).moveContentTopStackTop(chooser.myAllContents[selectedIndex]); + + if (editor != null) { + if (!editor.getDocument().isWritable()) { + editor.getDocument().fireReadOnlyModificationAttempt(); + return; + } + + final AnAction pasteAction = ActionManager.getInstance().getAction(IdeActions.ACTION_PASTE); + AnActionEvent newEvent = new AnActionEvent(e.getInputEvent(), + DataManager.getInstance().getDataContext(focusedComponent), + e.getPlace(), e.getPresentation(), + ActionManager.getInstance(), + e.getModifiers()); + pasteAction.actionPerformed(newEvent); + } + else { + final Action pasteAction = ((JComponent)focusedComponent).getActionMap().get(DefaultEditorKit.pasteAction); + if (pasteAction != null) { + pasteAction.actionPerformed(new ActionEvent(focusedComponent, ActionEvent.ACTION_PERFORMED, "")); + } + } + } + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(isEnabled(e.getDataContext())); + } + + private boolean isEnabled(DataContext dataContext) { + Object component = dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT); + if (!(component instanceof JComponent)) return false; + if (dataContext.getData(DataConstants.EDITOR) != null) return true; + Action pasteAction = ((JComponent)component).getActionMap().get(DefaultEditorKit.pasteAction); + return pasteAction != null; + } + + private static class Chooser extends DialogWrapper { + private JList myList; + private Transferable[] myAllContents; + private Editor myViewer; + private Splitter mySplitter; + private Project myProject; + + public Chooser(Project project) { + super(project, true); + myProject = project; + + setOKButtonText("OK"); + setTitle("Choose Content to Paste"); + + init(); + } + + public JComponent getPreferredFocusedComponent() { + return myList; + } + + protected JComponent createCenterPanel() { + myList = new JList(); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + rebuildListContent(); + + myList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.isConsumed() || e.getClickCount() != 2 || e.isPopupTrigger()) return; + close(OK_EXIT_CODE); + } + }); + + myList.setCellRenderer(new MyListCellRenderer()); + + if (myAllContents.length > 0) { + myList.setSelectedIndex(0); + } + + myList.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + int selectedIndex = getSelectedIndex(); + int size = myAllContents.length; + ((CopyPasteManagerEx)CopyPasteManager.getInstance()).removeContent(myAllContents[selectedIndex]); + rebuildListContent(); + if (size == 1) { + close(CANCEL_EXIT_CODE); + return; + } + myList.setSelectedIndex(Math.min(selectedIndex, myAllContents.length - 1)); + } + else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + close(OK_EXIT_CODE); + } + } + }); + + mySplitter = new Splitter(true); + mySplitter.setFirstComponent(new JScrollPane(myList)); + mySplitter.setSecondComponent(new JPanel()); + updateViewerForSelection(); + + myList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateViewerForSelection(); + } + }); + + mySplitter.setPreferredSize(new Dimension(500, 500)); + + return mySplitter; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.openapi.editor.actions.MultiplePasteAction.Chooser"; + } + + private void updateViewerForSelection() { + if (myAllContents.length == 0) return; + + try { + Transferable content = myAllContents[getSelectedIndex()]; + String fullString = (String)content.getTransferData(DataFlavor.stringFlavor); + fullString = StringUtil.convertLineSeparators(fullString); + Document doc = EditorFactory.getInstance().createDocument(fullString); + if (myViewer != null) { + EditorFactory.getInstance().releaseEditor(myViewer); + } + + myViewer = EditorFactory.getInstance().createViewer(doc, myProject); + myViewer.getComponent().setPreferredSize(new Dimension(300, 500)); + myViewer.getSettings().setFoldingOutlineShown(false); + myViewer.getSettings().setLineNumbersShown(false); + myViewer.getSettings().setLineMarkerAreaShown(false); + mySplitter.setSecondComponent(myViewer.getComponent()); + mySplitter.revalidate(); + } + catch (UnsupportedFlavorException e1) { + } + catch (IOException e1) { + } + } + + protected void dispose() { + super.dispose(); + if (myViewer != null) { + EditorFactory.getInstance().releaseEditor(myViewer); + myViewer = null; + } + } + + private void rebuildListContent() { + Transferable[] allContents = CopyPasteManager.getInstance().getAllContents(); + ArrayList contents = new ArrayList(); + ArrayList shortened = new ArrayList(); + for (int i = 0; i < allContents.length; i++) { + Transferable content = allContents[i]; + try { + String fullString = (String)content.getTransferData(DataFlavor.stringFlavor); + if (fullString != null) { + fullString = StringUtil.convertLineSeparators(fullString, "\n"); + contents.add(content); + int lastNewLineIdx = fullString.indexOf('\n'); + shortened.add(lastNewLineIdx == -1 ? fullString : fullString.substring(0, lastNewLineIdx) + " ..."); + } + } + catch (UnsupportedFlavorException e) { + } + catch (IOException e) { + } + } + + myAllContents = contents.toArray(new Transferable[contents.size()]); + myList.setListData(shortened.toArray(new String[shortened.size()])); + } + + private int getSelectedIndex() { + if (myList.getSelectedIndex() == -1) return 0; + return myList.getSelectedIndex(); + } + + private class MyListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setIcon(textIcon); + setText((String)value); + return this; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordAction.java new file mode 100644 index 00000000000..c7486c3ed4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:49:27 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class NextWordAction extends EditorAction { + public NextWordAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToNextWord(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordWithSelectionAction.java new file mode 100644 index 00000000000..9393907ab5c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/NextWordWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:49:27 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +public class NextWordWithSelectionAction extends EditorAction { + public NextWordWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToNextWord(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomAction.java new file mode 100644 index 00000000000..5a6e386518c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:07:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageBottomAction extends EditorAction { + public PageBottomAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageBottom(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomWithSelectionAction.java new file mode 100644 index 00000000000..54d44e935a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageBottomWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:07:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageBottomWithSelectionAction extends EditorAction { + public PageBottomWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageBottom(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownAction.java new file mode 100644 index 00000000000..f2aa2a6c7de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 3:16:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageDownAction extends EditorAction { + public static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageDown(editor, false); + } + } + + public PageDownAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownWithSelectionAction.java new file mode 100644 index 00000000000..8499b4b9dfe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageDownWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 3:16:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageDownWithSelectionAction extends EditorAction { + public static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageDown(editor, true); + } + } + + public PageDownWithSelectionAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopAction.java new file mode 100644 index 00000000000..f8b18639f81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:07:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageTopAction extends EditorAction { + public PageTopAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageTop(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopWithSelectionAction.java new file mode 100644 index 00000000000..ac6e6ac1381 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageTopWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:07:02 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageTopWithSelectionAction extends EditorAction { + public PageTopWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageTop(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpAction.java new file mode 100644 index 00000000000..bd932ce8124 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 3:16:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageUpAction extends EditorAction { + public static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageUp(editor, false); + } + } + + public PageUpAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpWithSelectionAction.java new file mode 100644 index 00000000000..a65a9851356 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PageUpWithSelectionAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 3:16:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PageUpWithSelectionAction extends EditorAction { + public static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretPageUp(editor, true); + } + } + + public PageUpWithSelectionAction() { + super(new Handler()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteAction.java new file mode 100644 index 00000000000..3c29a6cc70f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteAction.java @@ -0,0 +1,32 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 7:50:36 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.editor.ex.EditorEx; + +public class PasteAction extends EditorAction { + public PasteAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + if (editor.isColumnMode()) { + EditorModificationUtil.pasteFromClipboardAsBlock(editor); + } else { + editor.putUserData(EditorEx.LAST_PASTED_REGION, EditorModificationUtil.pasteFromClipboard(editor)); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteFromX11Action.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteFromX11Action.java new file mode 100644 index 00000000000..24630dfb29b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PasteFromX11Action.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.SystemInfo; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.Transferable; + +/** + * Author: msk + */ +public class PasteFromX11Action extends EditorAction { + public PasteFromX11Action() { + super(new Handler()); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(SystemInfo.isUnix); + } + + public static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + final Clipboard clip = editor.getComponent ().getToolkit ().getSystemSelection(); + if (clip != null) { + final Transferable res = clip.getContents(null); + editor.putUserData(EditorEx.LAST_PASTED_REGION, EditorModificationUtil.pasteFromTransferrable(res, editor)); + } + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordAction.java new file mode 100644 index 00000000000..27980f717f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:49:27 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class PreviousWordAction extends EditorAction { + public PreviousWordAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToPreviousWord(editor, false); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordWithSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordWithSelectionAction.java new file mode 100644 index 00000000000..cead2dc0e16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/PreviousWordWithSelectionAction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 6:49:27 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + + +public class PreviousWordWithSelectionAction extends EditorAction { + public PreviousWordWithSelectionAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.moveCaretToPreviousWord(editor, true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ReplaceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ReplaceAction.java new file mode 100644 index 00000000000..0638c13127f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ReplaceAction.java @@ -0,0 +1,37 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 18, 2002 + * Time: 5:49:15 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.find.FindUtil; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.project.Project; + +public class ReplaceAction extends EditorAction { + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + FindUtil.replace(project, editor); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + Project project = (Project) DataManager.getInstance().getDataContext(editor.getComponent()).getData(DataConstants.PROJECT); + return project != null; + } + } + + public ReplaceAction() { + super(new Handler()); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollDownAction.java new file mode 100644 index 00000000000..48819d23385 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollDownAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 10:55:09 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class ScrollDownAction extends EditorAction { + public ScrollDownAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, 1); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollToCenterAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollToCenterAction.java new file mode 100644 index 00000000000..12d4f7a4256 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollToCenterAction.java @@ -0,0 +1,27 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 16, 2002 + * Time: 2:28:05 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class ScrollToCenterAction extends EditorAction { + public ScrollToCenterAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollUpAction.java new file mode 100644 index 00000000000..a86467c9986 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/ScrollUpAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 10:55:09 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class ScrollUpAction extends EditorAction { + public ScrollUpAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, -1); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectLineAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectLineAction.java new file mode 100644 index 00000000000..64c995965a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectLineAction.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 22, 2002 + * Time: 10:43:26 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class SelectLineAction extends EditorAction { + public SelectLineAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + editor.getSelectionModel().selectLineAtCaret(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectWordAtCaretAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectWordAtCaretAction.java new file mode 100644 index 00000000000..2799c5c78ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SelectWordAtCaretAction.java @@ -0,0 +1,59 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 7:40:40 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.codeInsight.editorActions.SelectWordUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; +import java.util.List; + +public class SelectWordAtCaretAction extends EditorAction { + public SelectWordAtCaretAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + int caretOffset = editor.getCaretModel().getOffset(); + Document document = editor.getDocument(); + if (lineNumber >= document.getLineCount()) { + return; + } + CharSequence text = document.getCharsSequence(); + + boolean camel = editor.getSettings().isCamelWords(); + List ranges = new ArrayList(); + + int textLength = document.getTextLength(); + if (caretOffset == textLength) caretOffset--; + + SelectWordUtil.addWordSelection(camel, text, caretOffset, ranges); + + if (ranges.size() == 0) return; + + int startWordOffset = Math.max(0, ranges.get(0).getStartOffset()); + int endWordOffset = Math.min(ranges.get(0).getEndOffset(), document.getTextLength()); + + if (camel && ranges.size() == 2 && editor.getSelectionModel().getSelectionStart() == startWordOffset && + editor.getSelectionModel().getSelectionEnd() == endWordOffset) { + startWordOffset = Math.max(0, ranges.get(1).getStartOffset()); + endWordOffset = Math.min(ranges.get(1).getEndOffset(), document.getTextLength()); + } + + editor.getSelectionModel().setSelection(startWordOffset, endWordOffset); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SplitLineAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SplitLineAction.java new file mode 100644 index 00000000000..3aada900f29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/SplitLineAction.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +/** + * @author max + */ +public class SplitLineAction extends EditorAction { + public SplitLineAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public boolean isEnabled(Editor editor, DataContext dataContext) { + return getEnterHandler().isEnabled(editor, dataContext); + } + + public void executeWriteAction(Editor editor, DataContext dataContext) { + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + + getEnterHandler().execute(editor, dataContext); + + editor.getCaretModel().moveToLogicalPosition(caretPosition); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + + private EditorActionHandler getEnterHandler() { + return EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/StartNewLineAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/StartNewLineAction.java new file mode 100644 index 00000000000..79904e1a8b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/StartNewLineAction.java @@ -0,0 +1,40 @@ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; + +/** + * @author max + */ +public class StartNewLineAction extends EditorAction { + public StartNewLineAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public boolean isEnabled(Editor editor, DataContext dataContext) { + return getEnterHandler().isEnabled(editor, dataContext); + } + + public void executeWriteAction(Editor editor, DataContext dataContext) { + if (editor.getDocument().getLineCount() != 0) { + editor.getSelectionModel().removeSelection(); + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + int lineEndOffset = editor.getDocument().getLineEndOffset(caretPosition.line); + editor.getCaretModel().moveToOffset(lineEndOffset); + } + + getEnterHandler().execute(editor, dataContext); + } + + private EditorActionHandler getEnterHandler() { + return EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TabAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TabAction.java new file mode 100644 index 00000000000..ed85a506017 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/TabAction.java @@ -0,0 +1,80 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 13, 2002 + * Time: 9:51:34 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +public class TabAction extends EditorAction { + public TabAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + public void executeWriteAction(Editor editor, DataContext dataContext) { + CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.EDIT_COMMAND_GROUP); + CommandProcessor.getInstance().setCurrentCommandName("Typing"); + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + insertTabAtCaret(editor, project); + } + + public boolean isEnabled(Editor editor, DataContext dataContext) { + return !editor.isOneLineMode(); + } + } + + private static void insertTabAtCaret(Editor editor, Project project) { + int columnNumber = editor.getCaretModel().getLogicalPosition().column; + + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + + VirtualFile vFile = FileDocumentManager.getInstance().getFile(editor.getDocument()); + final FileType fileType = vFile == null ? null : FileTypeManager.getInstance().getFileTypeByFile(vFile); + + int tabSize = settings.getIndentSize(fileType); + int spacesToAddCount = tabSize - columnNumber % tabSize; + + boolean useTab = editor.getSettings().isUseTabCharacter(project); + + CharSequence chars = editor.getDocument().getCharsSequence(); + if (useTab && settings.isSmartTabs(fileType)) { + int offset = editor.getCaretModel().getOffset(); + while (offset > 0) { + offset--; + if (chars.charAt(offset) == '\t') continue; + if (chars.charAt(offset) == '\n') break; + useTab = false; + break; + } + } + + if(useTab) { + EditorModificationUtil.insertStringAtCaret(editor, "\t"); + } + else { + StringBuffer buffer = new StringBuffer(); + for(int i=0; i 0 && document.getLineStartOffset(endIndex) == oldSelectionEnd && endIndex > startIndex) { + endIndex --; + } + if(endIndex == -1) { + endIndex = document.getLineCount() - 1; + } + + if (startIndex < 0 || endIndex < 0) return; + + VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); + final FileType fileType = vFile == null ? null : FileTypeManager.getInstance().getFileTypeByFile(vFile); + + int blockIndent = CodeStyleSettingsManager.getSettings(project).getIndentSize(fileType); + for(int i=startIndex; i<=endIndex; i++) { + EditorActionUtil.indentLine(project, editor, i, -blockIndent); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/UnselectWordAtCaretAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/UnselectWordAtCaretAction.java new file mode 100644 index 00000000000..a02007fb15b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/actions/UnselectWordAtCaretAction.java @@ -0,0 +1,25 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: May 14, 2002 + * Time: 7:40:40 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.actionSystem.DataContext; + +public class UnselectWordAtCaretAction extends EditorAction { + public UnselectWordAtCaretAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + public void execute(Editor editor, DataContext dataContext) { + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/ex/DefaultColorSchemesManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/ex/DefaultColorSchemesManager.java new file mode 100644 index 00000000000..103bacd562d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/ex/DefaultColorSchemesManager.java @@ -0,0 +1,65 @@ +package com.intellij.openapi.editor.colors.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author max + */ +public class DefaultColorSchemesManager implements ApplicationComponent, JDOMExternalizable { + private ArrayList mySchemes; + + public String getComponentName() { + return "DefaultColorSchemesManager"; + } + + public DefaultColorSchemesManager() { + mySchemes = new ArrayList(); + } + + public static DefaultColorSchemesManager getInstance() { + return ApplicationManager.getApplication().getComponent(DefaultColorSchemesManager.class); + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void readExternal(Element element) throws InvalidDataException { + List schemes = element.getChildren("scheme"); + for (Iterator iterator = schemes.iterator(); iterator.hasNext();) { + Element schemeElement = (Element) iterator.next(); + DefaultColorsScheme newScheme = new DefaultColorsScheme(this); + newScheme.readExternal(schemeElement); + mySchemes.add(newScheme); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + throw new WriteExternalException(); + } + + public DefaultColorsScheme[] getAllSchemes() { + return (DefaultColorsScheme[]) mySchemes.toArray(new DefaultColorsScheme[mySchemes.size()]); + } + + public EditorColorsScheme getScheme(String name) { + for (int i = 0; i < mySchemes.size(); i++) { + DefaultColorsScheme scheme = (DefaultColorsScheme) mySchemes.get(i); + if (name.equals(scheme.getName())) return scheme; + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java new file mode 100644 index 00000000000..a97fee05b5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java @@ -0,0 +1,295 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.editor.colors.impl; + +import com.intellij.codeInsight.CodeInsightColors; +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.awt.*; +import java.util.*; +import java.util.List; + +public abstract class AbstractColorsScheme implements EditorColorsScheme, JDOMExternalizable { + private static final int LATEST_VERSION = 1; + + protected EditorColorsScheme myParentScheme; + + protected int myEditorFontSize; + protected float myLineSpacing; + + protected Map myValuesMap = new HashMap(); + // version influences XML format and triggers migration + private int myVersion; + + protected Map myColorsMap = new HashMap(); + protected Map myAttributesMap = new HashMap(); + + private static final String DEFAULT_FONT_NAME = "Courier"; + protected static final String EDITOR_FONT_NAME = "EDITOR_FONT_NAME"; + protected static final String SCHEME_NAME = "SCHEME_NAME"; + protected DefaultColorSchemesManager myDefaultColorSchemesManager; + + protected AbstractColorsScheme(EditorColorsScheme parentScheme, DefaultColorSchemesManager defaultColorSchemesManager) { + myParentScheme = parentScheme; + myDefaultColorSchemesManager = defaultColorSchemesManager; + } + + public AbstractColorsScheme(DefaultColorSchemesManager defaultColorSchemesManager) { + myDefaultColorSchemesManager = defaultColorSchemesManager; + } + + public abstract void setAttributes(TextAttributesKey key, TextAttributes attributes); + public abstract TextAttributes getAttributes(TextAttributesKey key); + + public abstract void setColor(ColorKey key, Color color); + public abstract Color getColor(ColorKey key); + + public abstract String getName(); + + public abstract void setFont(EditorFontType key, Font font); + + public abstract Object clone(); + + public void setEditorFontName(String fontName) { + myValuesMap.put(EDITOR_FONT_NAME, fontName); + initFonts(); + } + + public void setEditorFontSize(int fontSize) { + myEditorFontSize = fontSize; + initFonts(); + } + + public void setLineSpacing(float lineSpacing) { + myLineSpacing = lineSpacing; + } + + public Font getFont(EditorFontType key) { + return (Font)myValuesMap.get(key); + } + + public void setName(String name) { + myValuesMap.put(SCHEME_NAME, name); + } + + public String getEditorFontName() { + String fontName = (String)myValuesMap.get(EDITOR_FONT_NAME); + return fontName == null ? AbstractColorsScheme.DEFAULT_FONT_NAME : fontName; + } + + public int getEditorFontSize() { + return myEditorFontSize; + } + + public float getLineSpacing() { + return myLineSpacing <= 0?1f:myLineSpacing; + } + + protected void initFonts() { + String editorFontName = getEditorFontName(); + int editorFontSize = getEditorFontSize(); + + Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize); + Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize); + Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize); + Font boldItalicFont = new Font(editorFontName, Font.BOLD + Font.ITALIC, editorFontSize); + + myValuesMap.put(EditorFontType.PLAIN, plainFont); + myValuesMap.put(EditorFontType.BOLD, boldFont); + myValuesMap.put(EditorFontType.ITALIC, italicFont); + myValuesMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont); + } + + public String toString() { + return getName(); + } + + public void readExternal(Element parentNode) throws InvalidDataException { + if ("scheme".equals(parentNode.getName())) { + readScheme(parentNode); + } else { + for (Iterator iterator = parentNode.getChildren("scheme").iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + readScheme(element); + } + } + initFonts(); + } + + private void readScheme(Element node) throws InvalidDataException { + if ("scheme".equals(node.getName())) { + setName(node.getAttributeValue("name")); + myVersion = Integer.parseInt(node.getAttributeValue("version", "0")); + String isDefaultScheme = node.getAttributeValue("default_scheme"); + if (isDefaultScheme == null || "false".equals(isDefaultScheme)) { + String parentSchemeName = node.getAttributeValue("parent_scheme"); + if (parentSchemeName == null) parentSchemeName = "Default"; + myParentScheme = myDefaultColorSchemesManager.getScheme(parentSchemeName); + } + + for (Iterator iterator = node.getChildren().iterator(); iterator.hasNext();) { + Element childNode = (Element)iterator.next(); + if ("option".equals(childNode.getName())) { + readSettings(childNode); + } else if ("colors".equals(childNode.getName())) { + readColors(childNode); + } else if ("attributes".equals(childNode.getName())) { + readAttributes(childNode); + } + } + initFonts(); + } + } + + protected void migrateFromOldVersions() { + if (myVersion == 0) { + myVersion = LATEST_VERSION; + migrateFromVersion0(); + } + } + + private void migrateFromVersion0() { + Map attributesToErrorStripe = new HashMap(); + attributesToErrorStripe.put(CodeInsightColors.ERRORS_ATTRIBUTES, Color.red); + attributesToErrorStripe.put(CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES, Color.red); + attributesToErrorStripe.put(CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES, Color.yellow); + attributesToErrorStripe.put(CodeInsightColors.DEPRECATED_ATTRIBUTES, Color.yellow); + attributesToErrorStripe.put(CodeInsightColors.WARNINGS_ATTRIBUTES, Color.yellow); + for (Iterator> iterator = attributesToErrorStripe.entrySet().iterator(); iterator.hasNext();) { + final Map.Entry entry = iterator.next(); + TextAttributesKey key = entry.getKey(); + Color color = entry.getValue(); + + TextAttributes attributes = getAttributes(key); + attributes.setErrorStripeColor(color); + } + } + + private void readAttributes(Element childNode) throws InvalidDataException { + for (Iterator iterator = childNode.getChildren("option").iterator(); iterator.hasNext();) { + Element e = (Element)iterator.next(); + TextAttributesKey name = TextAttributesKey.find(e.getAttributeValue("name")); + TextAttributes attr = new TextAttributes(); + Element value = e.getChild("value"); + attr.readExternal(value); + myAttributesMap.put(name, attr); + } + } + + private void readColors(Element childNode) { + for (Iterator iterator = childNode.getChildren("option").iterator(); iterator.hasNext();) { + Element colorElement = (Element)iterator.next(); + + ColorKey name = ColorKey.find(colorElement.getAttributeValue("name")); + String value = colorElement.getAttributeValue("value"); + if (value == null || "".equals(value.trim())) { + myColorsMap.put(name, null); + } else { + try { + myColorsMap.put(name, new Color(Integer.parseInt(value, 16))); + } catch (NumberFormatException e) { + continue; + } + } + } + } + + private void readSettings(Element childNode) { + String name = childNode.getAttributeValue("name"); + String value = childNode.getAttributeValue("value"); + if ("LINE_SPACING".equals(name)) { + myLineSpacing = Float.parseFloat(value); + } else if ("EDITOR_FONT_SIZE".equals(name)) { + myEditorFontSize = Integer.parseInt(value); + } else if ("EDITOR_FONT_NAME".equals(name)) { + setEditorFontName(value); + } + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + parentNode.setAttribute("name", getName()); + parentNode.setAttribute("version", ""+myVersion); + + if (myParentScheme != null) { + parentNode.setAttribute("parent_scheme", myParentScheme.getName()); + } + + Element element = new Element("option"); + element.setAttribute("name", "LINE_SPACING"); + element.setAttribute("value", String.valueOf(getLineSpacing())); + parentNode.addContent(element); + + element = new Element("option"); + element.setAttribute("name", "EDITOR_FONT_SIZE"); + element.setAttribute("value", String.valueOf(getEditorFontSize())); + parentNode.addContent(element); + + element = new Element("option"); + element.setAttribute("name", "EDITOR_FONT_NAME"); + element.setAttribute("value", getEditorFontName()); + parentNode.addContent(element); + + Element colorElements = new Element("colors"); + Element attrElements = new Element("attributes"); + + writeColors(colorElements); + writeAttributes(attrElements); + + parentNode.addContent(colorElements); + parentNode.addContent(attrElements); + } + + private void writeAttributes(Element attrElements) throws WriteExternalException { + Element element; + List list = new ArrayList(myAttributesMap.keySet()); + Collections.sort(list); + Iterator itr = list.iterator(); + + while (itr.hasNext()) { + TextAttributesKey key = itr.next(); + TextAttributes value = myAttributesMap.get(key); + if (myParentScheme != null) { + if (value.equals(myParentScheme.getAttributes(key))) { + continue; + } + } + element = new Element("option"); + element.setAttribute("name", key.getExternalName()); + Element valueElement = new Element("value"); + value.writeExternal(valueElement); + element.addContent(valueElement); + attrElements.addContent(element); + } + } + + private void writeColors(Element colorElements) { + List list = new ArrayList(myColorsMap.keySet()); + Collections.sort(list); + + for (Iterator itr = list.iterator(); itr.hasNext();) { + ColorKey key = itr.next(); + Color value = myColorsMap.get(key); + if (myParentScheme != null) { + if (Comparing.equal(myParentScheme.getColor(key), value)) { + continue; + } + } + Element element = new Element("option"); + element.setAttribute("name", key.getExternalName()); + element.setAttribute("value", value != null? Integer.toString(value.getRGB() & 0xFFFFFF, 16) : ""); + colorElements.addContent(element); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/DefaultColorsScheme.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/DefaultColorsScheme.java new file mode 100644 index 00000000000..2727a704725 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/DefaultColorsScheme.java @@ -0,0 +1,63 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.editor.colors.impl; + +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.InvalidDataException; +import org.jdom.Element; + +import java.awt.*; + +public class DefaultColorsScheme extends AbstractColorsScheme { + private String myName; + + public DefaultColorsScheme(DefaultColorSchemesManager defaultColorSchemesManager) { + super(null, defaultColorSchemesManager); + } + + public TextAttributes getAttributes(TextAttributesKey key) { + if (key == null) return null; + TextAttributes attrs = myAttributesMap.get(key); + return attrs != null ? attrs : key.getDefaultAttributes(); + } + + public Color getColor(ColorKey key) { + if (key == null) return null; + Color color = myColorsMap.get(key); + return color != null ? color : key.getDefaultColor(); + } + + public void readExternal(Element parentNode) throws InvalidDataException { + super.readExternal(parentNode); + myName = parentNode.getAttributeValue("name"); + } + + public String getName() { + return myName; + } + + public void setAttributes(TextAttributesKey key, TextAttributes attributes) { + } + + public void setColor(ColorKey key, Color color) { + } + + public void setFont(EditorFontType key, Font font) { + } + + public Object clone() { + EditorColorsScheme newScheme = new EditorColorsSchemeImpl(this, myDefaultColorSchemesManager); + newScheme.setEditorFontSize(myEditorFontSize); + newScheme.setLineSpacing(myLineSpacing); + newScheme.setEditorFontName((String)myValuesMap.get(EDITOR_FONT_NAME)); + newScheme.setName("Default"); + return newScheme; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java new file mode 100644 index 00000000000..fd6d032c64e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java @@ -0,0 +1,295 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.editor.colors.impl; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.EditorColorsListener; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.UniqueFileNamesProvider; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.*; + +public class EditorColorsManagerImpl extends EditorColorsManager implements NamedJDOMExternalizable, + ExportableApplicationComponent { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.openapi.editor.colors.impl.EditorColorsManagerImpl"); + + private Map mySchemesMap = new com.intellij.util.containers.HashMap(); + private Collection myListeners = new ArrayList(); + + private EditorColorsScheme myGlobalScheme; + + private static final String NODE_NAME = "global_color_scheme"; + private static final String SCHEME_NODE_NAME = "scheme"; + + private String myGlobalSchemeName; + public boolean USE_ONLY_MONOSPACED_FONTS = true; + private DefaultColorSchemesManager myDefaultColorSchemesManager; + + public EditorColorsManagerImpl(DefaultColorSchemesManager defaultColorSchemesManager) { + myDefaultColorSchemesManager = defaultColorSchemesManager; + addDefaultSchemes(); + loadAllSchemes(); + setGlobalScheme(myDefaultColorSchemesManager.getAllSchemes()[0]); + } + + // ------------------------------------------------------------------------- + // ApplicationComponent interface implementation + // ------------------------------------------------------------------------- + + public void disposeComponent() { + } + + public void initComponent() { + } + + // ------------------------------------------------------------------------- + // Schemes manipulation routines + // ------------------------------------------------------------------------- + + public void addColorsScheme(EditorColorsScheme scheme) { + if (!isDefaultScheme(scheme) && scheme.getName().trim().length() > 0) { + mySchemesMap.put(scheme.getName(), scheme); + } + } + + public void removeAllSchemes() { + mySchemesMap.clear(); + addDefaultSchemes(); + } + + private void addDefaultSchemes() { + DefaultColorsScheme[] allDefaultSchemes = myDefaultColorSchemesManager.getAllSchemes(); + for (int i = 0; i < allDefaultSchemes.length; i++) { + DefaultColorsScheme defaultScheme = allDefaultSchemes[i]; + mySchemesMap.put(defaultScheme.getName(), defaultScheme); + } + } + + // ------------------------------------------------------------------------- + // Getters & Setters + // ------------------------------------------------------------------------- + + public EditorColorsScheme[] getAllSchemes() { + ArrayList schemes = new ArrayList(mySchemesMap.values()); + Collections.sort(schemes, new Comparator() { + public int compare(Object o1, Object o2) { + EditorColorsScheme s1 = (EditorColorsScheme)o1; + EditorColorsScheme s2 = (EditorColorsScheme)o2; + + if (isDefaultScheme(s1) && !isDefaultScheme(s2)) return -1; + if (!isDefaultScheme(s1) && isDefaultScheme(s2)) return 1; + + return s1.getName().compareToIgnoreCase(s2.getName()); + } + }); + + return schemes.toArray(new EditorColorsScheme[schemes.size()]); + } + + public void setGlobalScheme(EditorColorsScheme scheme) { + myGlobalScheme = scheme == null ? DefaultColorSchemesManager.getInstance().getAllSchemes()[0] : scheme; + fireChanges(scheme); + } + + public EditorColorsScheme getGlobalScheme() { + return myGlobalScheme; + } + + public EditorColorsScheme getScheme(String schemeName) { + return mySchemesMap.get(schemeName); + } + + private void fireChanges(EditorColorsScheme scheme) { + EditorColorsListener[] colorsListeners = myListeners.toArray(new EditorColorsListener[myListeners.size()]); + for (int i = 0; i < colorsListeners.length; i++) { + EditorColorsListener colorsListener = colorsListeners[i]; + colorsListener.globalSchemeChange(scheme); + } + } + + // ------------------------------------------------------------------------- + // Routines responsible for loading & saving colors schemes. + // ------------------------------------------------------------------------- + + private void loadAllSchemes() { + File[] files = getSchemeFiles(); + for (int i = 0; i < files.length; i++) { + try { + addColorsScheme(loadScheme(files[i])); + } + catch (Exception e) { + Messages.showErrorDialog("Error reading color scheme from " + files[i].getName(), "Corrupted File"); + } + } + } + + public void saveAllSchemes() throws IOException { + File dir = getColorsDir(true); + if (dir == null) return; + + File[] oldFiles = getSchemeFiles(); + + int size = mySchemesMap.values().size(); + ArrayList filePaths = new ArrayList(); + ArrayList documents = new ArrayList(); + + UniqueFileNamesProvider namesProvider = new UniqueFileNamesProvider(); + Iterator itr = mySchemesMap.values().iterator(); + for (int i = 0; i < size; i++) { + AbstractColorsScheme scheme = (AbstractColorsScheme)itr.next(); + if (scheme instanceof DefaultColorsScheme) continue; + + Element root = new Element(SCHEME_NODE_NAME); + try { + scheme.writeExternal(root); + } + catch (WriteExternalException e) { + LOG.error(e); + return; + } + + String filePath = dir.getAbsolutePath() + File.separator + namesProvider.suggestName(scheme.getName()) + ".xml"; + + documents.add(new Document(root)); + filePaths.add(filePath); + } + + JDOMUtil.updateFileSet(oldFiles, + filePaths.toArray(new String[filePaths.size()]), + documents.toArray(new Document[documents.size()]), CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + + private static EditorColorsScheme loadScheme(File file) throws InvalidDataException, JDOMException, IOException { + Document document = JDOMUtil.loadDocument(file); + + if (document == null) throw new InvalidDataException(); + Element root = document.getRootElement(); + + if (root == null || !SCHEME_NODE_NAME.equals(root.getName())) { + throw new InvalidDataException(); + } + + EditorColorsSchemeImpl scheme = new EditorColorsSchemeImpl(null, DefaultColorSchemesManager.getInstance()); + scheme.readExternal(root); + + return scheme; + } + + private File[] getSchemeFiles() { + File colorsDir = getColorsDir(true); + if (colorsDir == null) { + return new File[0]; + } + + File[] files = colorsDir.listFiles(new FileFilter() { + public boolean accept(File file) { + return !file.isDirectory() && file.getName().toLowerCase().endsWith(".xml"); + } + }); + if (files == null) { + LOG.error("Cannot read directory: " + colorsDir.getAbsolutePath()); + return new File[0]; + } + return files; + } + + private static File getColorsDir(boolean create) { + String directoryPath = PathManager.getConfigPath() + File.separator + "colors"; + File directory = new File(directoryPath); + if (!directory.exists()) { + if (!create) return null; + if (!directory.mkdir()) { + LOG.error("Cannot create directory: " + directory.getAbsolutePath()); + return null; + } + } + return directory; + } + + + public void addEditorColorsListener(EditorColorsListener listener) { + myListeners.add(listener); + } + + public void removeEditorColorsListener(EditorColorsListener listener) { + myListeners.remove(listener); + } + + public void setUseOnlyMonospacedFonts(boolean b) { + USE_ONLY_MONOSPACED_FONTS = b; + } + + public boolean isUseOnlyMonospacedFonts() { + return USE_ONLY_MONOSPACED_FONTS; + } + + public String getExternalFileName() { + return "colors.scheme"; + } + + public File[] getExportFiles() { + return new File[]{getColorsDir(true), PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Color schemes"; + } + + public void readExternal(Element parentNode) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, parentNode); + Element element = parentNode.getChild(NODE_NAME); + if (element != null) { + String name = element.getAttributeValue("name"); + if (name != null && !"".equals(name.trim())) { + myGlobalSchemeName = name; + } + } + + initGlobalScheme(); + } + + private void initGlobalScheme() { + if (myGlobalSchemeName != null) { + setGlobalSchemeByName(myGlobalSchemeName); + } + else { + setGlobalScheme(myDefaultColorSchemesManager.getAllSchemes()[0]); + } + } + + private void setGlobalSchemeByName(String schemeName) { + setGlobalScheme(mySchemesMap.get(schemeName)); + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, parentNode); + if (myGlobalScheme != null) { + Element element = new Element(NODE_NAME); + element.setAttribute("name", myGlobalScheme.getName()); + parentNode.addContent(element); + } + } + + public boolean isDefaultScheme(EditorColorsScheme scheme) { + return scheme instanceof DefaultColorsScheme; + } + + public String getComponentName() { + return "EditorColorsManagerImpl"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java new file mode 100644 index 00000000000..b63ead28c99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java @@ -0,0 +1,74 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.editor.colors.impl; + +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.util.containers.HashMap; + +import java.awt.*; +import java.util.Map; + +public class EditorColorsSchemeImpl extends AbstractColorsScheme { + + public EditorColorsSchemeImpl(EditorColorsScheme parenScheme, DefaultColorSchemesManager defaultColorSchemesManager) { + super(parenScheme, defaultColorSchemesManager); + } + + // ------------------------------------------------------------------------- + // Getters & Setters + // ------------------------------------------------------------------------- + public void setAttributes(TextAttributesKey key, TextAttributes attributes) { + myAttributesMap.put(key, attributes); + } + + public void setColor(ColorKey key, Color color) { + myColorsMap.put(key, color); + } + + public void setFont(EditorFontType key, Font font) { + myValuesMap.put(key, font); + } + + public TextAttributes getAttributes(TextAttributesKey key) { + migrateFromOldVersions(); + if (myAttributesMap.containsKey(key)) { + return myAttributesMap.get(key); + } else { + return myParentScheme.getAttributes(key); + } + } + + public Color getColor(ColorKey key) { + migrateFromOldVersions(); + if (myColorsMap.containsKey(key)) { + return myColorsMap.get(key); + } else { + return myParentScheme.getColor(key); + } + } + + public String getName() { + return (String)myValuesMap.get(SCHEME_NAME); + } + + public Object clone() { + EditorColorsSchemeImpl newScheme = new EditorColorsSchemeImpl(myParentScheme, DefaultColorSchemesManager.getInstance()); + newScheme.myEditorFontSize = myEditorFontSize; + newScheme.myLineSpacing = myLineSpacing; + + Map newValuesMap = new HashMap(myValuesMap); + Map newAttributesMap = new HashMap(myAttributesMap); + Map newColorsMap = new HashMap(myColorsMap); + newScheme.myValuesMap = newValuesMap; + newScheme.myAttributesMap = newAttributesMap; + newScheme.myColorsMap = newColorsMap; + + return newScheme; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/DocumentEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/DocumentEx.java new file mode 100644 index 00000000000..e1855ffac07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/DocumentEx.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.editor.ex; + + +import com.intellij.openapi.editor.Document; + +public interface DocumentEx extends Document { + void stripTrailingSpaces(boolean inChangedLinesOnly); + void setStripTrailingSpacesEnabled(boolean isEnabled); + + int getLineSeparatorLength(int line); + + LineIterator createLineIterator(); + + void setModificationStamp(long modificationStamp); + + void addEditReadOnlyListener(EditReadOnlyListener listener); + + void removeEditReadOnlyListener(EditReadOnlyListener listener); + + void replaceText(CharSequence chars, long newModificationStamp); + + int getListenersCount(); + + void suppressGuardedExceptions(); + void unSuppressGuardedExceptions(); +} + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditReadOnlyListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditReadOnlyListener.java new file mode 100644 index 00000000000..64e2a339eef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditReadOnlyListener.java @@ -0,0 +1,9 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.Document; + +import java.util.EventListener; + +public interface EditReadOnlyListener extends EventListener { + void readOnlyModificationAttempt(Document document); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEventMulticasterEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEventMulticasterEx.java new file mode 100644 index 00000000000..9f97a3a330f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEventMulticasterEx.java @@ -0,0 +1,19 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.event.EditorEventMulticaster; + +import java.beans.PropertyChangeListener; + +public interface EditorEventMulticasterEx extends EditorEventMulticaster{ + void addErrorStripeListener(ErrorStripeListener listener); + void removeErrorStripeListener(ErrorStripeListener listener); + + void addEditReadOnlyListener(EditReadOnlyListener listener); + void removeEditReadOnlyListener(EditReadOnlyListener listener); + + void addPropertyChangeListener(PropertyChangeListener listener); + void removePropertyChangeListener(PropertyChangeListener listener); + + void addFocusChangeListner(FocusChangeListener listener); + void removeFocusChangeListner(FocusChangeListener listener); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEx.java new file mode 100644 index 00000000000..398be8e0a56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorEx.java @@ -0,0 +1,99 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.ide.CopyProvider; +import com.intellij.ide.CutProvider; +import com.intellij.ide.DeleteProvider; +import com.intellij.ide.PasteProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; + +public interface EditorEx extends Editor { + String PROP_INSERT_MODE = "insertMode"; + String PROP_COLUMN_MODE = "columnMode"; + String PROP_FONT_SIZE = "fontSize"; + Key LAST_PASTED_REGION = Key.create("LAST_PASTED_REGION"); + + EditorGutterComponentEx getGutterComponentEx(); + + Highlighter getHighlighter(); + + void setHighlighter(Highlighter highlighter); + + void setColorsScheme(EditorColorsScheme scheme); + + void setInsertMode(boolean val); + + void setColumnMode(boolean val); + + void setBlockSelectionMode(boolean isBlockSelectionMode); + + void setLastColumnNumber(int val); + + int getLastColumnNumber(); + + int VERTICAL_SCROLLBAR_LEFT = 0; + int VERTICAL_SCROLLBAR_RIGHT = 1; + + void setVerticalScrollbarOrientation(int type); + + void setVerticalScrollbarVisible(boolean b); + + void setHorizontalScrollbarVisible(boolean b); + + CutProvider getCutProvider(); + + CopyProvider getCopyProvider(); + + PasteProvider getPasteProvider(); + + DeleteProvider getDeleteProvider(); + + void repaint(int startOffset, int endOffset); + + void reinitSettings(); + + void addPropertyChangeListener(PropertyChangeListener listener); + + void removePropertyChangeListener(PropertyChangeListener listener); + + int getMaxWidthInRange(int startOffset, int endOffset); + + void stopOptimizedScrolling(); + + void setCaretVisible(boolean b); + + void addFocusListener(FocusChangeListener listener); + + void setOneLineMode(boolean b); + + JScrollPane getScrollPane(); + + boolean isRendererMode(); + + void setRendererMode(boolean isRendererMode); + + void setFile(VirtualFile vFile); + + DataContext getDataContext(); + + boolean processKeyTyped(KeyEvent e); + + void setFontSize(int fontSize); + + Color getBackroundColor(); + + void setBackgroundColor(Color color); + + void resetBackgourndColor(); + + Dimension getContentSize(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java new file mode 100644 index 00000000000..7c4d77e7267 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java @@ -0,0 +1,22 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.EditorGutter; +import com.intellij.openapi.editor.FoldRegion; + +import javax.swing.*; +import java.awt.*; + +public abstract class EditorGutterComponentEx extends JComponent implements EditorGutter { + + public abstract boolean isFoldingOutlineShown(); + + public abstract boolean isLineMarkersShown(); + + public abstract FoldRegion findFoldingAnchorAt(int x, int y); + + public abstract int getWhitespaceSeparatorOffset(); + + public abstract Color getFoldingColor(boolean isActive); + + public abstract void revalidateMarkup(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorMarkupModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorMarkupModel.java new file mode 100644 index 00000000000..1f51dacddab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorMarkupModel.java @@ -0,0 +1,18 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.LineMarkerRenderer; +import com.intellij.openapi.editor.markup.ErrorStripeRenderer; + +public interface EditorMarkupModel extends MarkupModel { + Editor getEditor(); + + void setErrorStripeVisible(boolean val); + + void setErrorStripeRenderer(ErrorStripeRenderer renderer); + ErrorStripeRenderer getErrorStripeRenderer(); + + void addErrorMarkerListener(ErrorStripeListener listener); + void removeErrorMarkerListener(ErrorStripeListener listener); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java new file mode 100644 index 00000000000..dbb4e9e477b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -0,0 +1,281 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.io.File; + +public class EditorSettingsExternalizable implements NamedJDOMExternalizable, ExportableApplicationComponent, Cloneable { + //Q: make it interface? + private static class OptionSet implements Cloneable { + public String LINE_SEPARATOR; + public boolean IS_VIRTUAL_SPACE = true; + public boolean IS_CARET_INSIDE_TABS; + public String STRIP_TRAILING_SPACES = "Changed"; + public boolean IS_CARET_BLINKING = true; + public int CARET_BLINKING_PERIOD = 500; + public boolean IS_RIGHT_MARGIN_SHOWN = true; + public boolean ARE_LINE_NUMBERS_SHOWN = false; + public boolean IS_FOLDING_OUTLINE_SHOWN = true; + + public boolean SMART_HOME = true; + + public boolean IS_BLOCK_CURSOR = false; + public boolean IS_WHITESPACES_SHOWN = false; + public boolean IS_ANIMATED_SCROLLING = true; + public boolean IS_CAMEL_WORDS = false; + public boolean ADDITIONAL_PAGE_AT_BOTTOM = false; + + public boolean IS_DND_ENABLED = true; + public boolean IS_WHEEL_FONTCHANGE_ENABLED = true; + public boolean IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = true; + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + } + + private OptionSet myOptions = new OptionSet(); + + private int myBlockIndent; + //private int myTabSize = 4; + //private boolean myUseTabCharacter = false; + + private int myAdditionalLinesCount = 10; + private int myAdditinalColumnsCount = 20; + private boolean myLineMarkerAreaShown = true; + + public static final String STRIP_TRAILING_SPACES_NONE = "None"; + public static final String STRIP_TRAILING_SPACES_CHANGED = "Changed"; + public static final String STRIP_TRAILING_SPACES_WHOLE = "Whole"; + + + public static String DEFAULT_FONT_NAME = "Courier"; + + public static EditorSettingsExternalizable getInstance() { + return ApplicationManager.getApplication().getComponent(EditorSettingsExternalizable.class); + } + + public EditorSettingsExternalizable() { + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(myOptions, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(myOptions, element); + } + + public String getExternalFileName() { + return "editor"; + } + + public boolean isRightMarginShown() { + return myOptions.IS_RIGHT_MARGIN_SHOWN; + } + + public void setRightMarginShown(boolean val) { + myOptions.IS_RIGHT_MARGIN_SHOWN = val; + } + + public boolean isLineNumbersShown() { + return myOptions.ARE_LINE_NUMBERS_SHOWN; + } + + public void setLineNumbersShown(boolean val) { + myOptions.ARE_LINE_NUMBERS_SHOWN = val; + } + + public int getAdditionalLinesCount() { + return myAdditionalLinesCount; + } + + public void setAdditionalLinesCount(int additionalLinesCount) { + myAdditionalLinesCount = additionalLinesCount; + } + + public int getAdditinalColumnsCount() { + return myAdditinalColumnsCount; + } + + public void setAdditionalColumnsCount(int additinalColumnsCount) { + myAdditinalColumnsCount = additinalColumnsCount; + } + + public boolean isLineMarkerAreaShown() { + return myLineMarkerAreaShown; + } + + public void setLineMarkerAreaShown(boolean lineMarkerAreaShown) { + myLineMarkerAreaShown = lineMarkerAreaShown; + } + + public boolean isFoldingOutlineShown() { + return myOptions.IS_FOLDING_OUTLINE_SHOWN; + } + + public void setFoldingOutlineShown(boolean val) { + myOptions.IS_FOLDING_OUTLINE_SHOWN = val; + } + + public boolean isBlockCursor() { + return myOptions.IS_BLOCK_CURSOR; + } + + public void setBlockCursor(boolean val) { + myOptions.IS_BLOCK_CURSOR = val; + } + + public int getBlockIndent() { + return myBlockIndent; + } + + public void setBlockIndent(int blockIndent) { + myBlockIndent = blockIndent; + } + + public boolean isSmartHome() { + return myOptions.SMART_HOME; + } + + public void setSmartHome(boolean val) { + myOptions.SMART_HOME = val; + } + + public boolean isVirtualSpace() { + return myOptions.IS_VIRTUAL_SPACE; + } + + public void setVirtualSpace(boolean val) { + myOptions.IS_VIRTUAL_SPACE = val; + } + + public boolean isCaretInsideTabs() { + return myOptions.IS_CARET_INSIDE_TABS; + } + + public void setCaretInsideTabs(boolean val) { + myOptions.IS_CARET_INSIDE_TABS = val; + } + + public boolean isBlinkCaret() { + return myOptions.IS_CARET_BLINKING; + } + + public void setBlinkCaret(boolean blinkCaret) { + myOptions.IS_CARET_BLINKING = blinkCaret; + } + + public int getBlinkPeriod() { + return myOptions.CARET_BLINKING_PERIOD; + } + + public void setBlinkPeriod(int blinkInterval) { + myOptions.CARET_BLINKING_PERIOD = blinkInterval; + } + + public String getStripTrailingSpaces() { + return myOptions.STRIP_TRAILING_SPACES; + } // TODO: move to CodeEditorManager or something else + + public void setStripTrailingSpaces(String stripTrailingSpaces) { + myOptions.STRIP_TRAILING_SPACES = stripTrailingSpaces; + } + + public Object clone() { + EditorSettingsExternalizable copy = new EditorSettingsExternalizable(); + copy.myOptions = (OptionSet) myOptions.clone(); + copy.myBlockIndent = myBlockIndent; + //copy.myTabSize = myTabSize; + //copy.myUseTabCharacter = myUseTabCharacter; + copy.myAdditionalLinesCount = myAdditionalLinesCount; + copy.myAdditinalColumnsCount = myAdditinalColumnsCount; + copy.myLineMarkerAreaShown = myLineMarkerAreaShown; + + return copy; + } + + public String getComponentName() { + return "EditorSettings"; + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Editor settings"; + } + + public boolean isWhitespacesShown() { + return myOptions.IS_WHITESPACES_SHOWN; + } + + public void setWhitespacesShown(boolean val) { + myOptions.IS_WHITESPACES_SHOWN = val; + } + + public boolean isSmoothScrolling() { + return myOptions.IS_ANIMATED_SCROLLING; + } + + public void setSmoothScrolling(boolean val){ + myOptions.IS_ANIMATED_SCROLLING = val; + } + + public boolean isCamelWords() { + return myOptions.IS_CAMEL_WORDS; + } + + public void setCamelWords(boolean val) { + myOptions.IS_CAMEL_WORDS = val; + } + + public boolean isAdditionalPageAtBottom() { + return myOptions.ADDITIONAL_PAGE_AT_BOTTOM; + } + + public void setAdditionalPageAtBottom(boolean val) { + myOptions.ADDITIONAL_PAGE_AT_BOTTOM = val; + } + + public boolean isDndEnabled() { + return myOptions.IS_DND_ENABLED; + } + + public void setDndEnabled(boolean val) { + myOptions.IS_DND_ENABLED = val; + } + + public boolean isWheelFontChangeEnabled() { + return myOptions.IS_WHEEL_FONTCHANGE_ENABLED; + } + + public void setWheelFontChangeEnabled(boolean val) { + myOptions.IS_WHEEL_FONTCHANGE_ENABLED = val; + } + + public boolean isMouseClickSelectionHonorsCamelWords() { + return myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS; + } + + public void setMouseClickSelectionHonorsCamelWords(boolean val) { + myOptions.IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS = val; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeAdapter.java new file mode 100644 index 00000000000..f7dc0f2c2ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeAdapter.java @@ -0,0 +1,10 @@ +package com.intellij.openapi.editor.ex; + +/** + * @author max + */ +public abstract class ErrorStripeAdapter implements ErrorStripeListener { + + public void errorMarkerClicked(ErrorStripeEvent e) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeEvent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeEvent.java new file mode 100644 index 00000000000..7aaba7beda8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeEvent.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.RangeHighlighter; + +import java.awt.event.MouseEvent; +import java.util.EventObject; + +public class ErrorStripeEvent extends EventObject { + private final MouseEvent myMouseEvent; + private final RangeHighlighter myHighlighter; + + public ErrorStripeEvent(Editor editor, MouseEvent mouseEvent, RangeHighlighter highlighter) { + super(editor); + myMouseEvent = mouseEvent; + myHighlighter = highlighter; + } + + public Editor getEditor() { + return (Editor) getSource(); + } + + public MouseEvent getMouseEvent() { + return myMouseEvent; + } + + public RangeHighlighter getHighlighter() { + return myHighlighter; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeListener.java new file mode 100644 index 00000000000..22cd783be88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/ErrorStripeListener.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.editor.ex; + +import java.util.EventListener; + +public interface ErrorStripeListener extends EventListener { + void errorMarkerClicked(ErrorStripeEvent e); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FocusChangeListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FocusChangeListener.java new file mode 100644 index 00000000000..1eaad226bbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FocusChangeListener.java @@ -0,0 +1,13 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.Editor; + +import java.util.EventListener; + +/** + * @author max + */ +public interface FocusChangeListener extends EventListener { + void focusGained(Editor editor); + void focusLost(Editor editor); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FoldingModelEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FoldingModelEx.java new file mode 100644 index 00000000000..f0da76d94b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/FoldingModelEx.java @@ -0,0 +1,19 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.FoldingModel; + +import java.awt.*; + +/** + * @author max + */ +public interface FoldingModelEx extends FoldingModel { + void setFoldingEnabled(boolean isEnabled); + boolean isFoldingEnabled(); + + FoldRegion getFoldingPlaceholderAt(Point p); + FoldRegion[] getAllFoldRegionsIncludingInvalid(); + + boolean intersectsRegion(int startOffset, int endOffset); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/Highlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/Highlighter.java new file mode 100644 index 00000000000..905a3791877 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/Highlighter.java @@ -0,0 +1,12 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentListener; + +public interface Highlighter extends DocumentListener { + HighlighterIterator createIterator(int startOffset); + void setText(CharSequence text); + void setEditor(Editor editor); + void setColorScheme(EditorColorsScheme scheme); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/HighlighterIterator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/HighlighterIterator.java new file mode 100644 index 00000000000..484207f6191 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/HighlighterIterator.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.psi.tree.IElementType; + + +public interface HighlighterIterator { + TextAttributes getTextAttributes(); + int getStart(); + int getEnd(); + IElementType getTokenType(); + void advance(); + void retreat(); + boolean atEnd(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/LineIterator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/LineIterator.java new file mode 100644 index 00000000000..1e6a1affcc9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/LineIterator.java @@ -0,0 +1,14 @@ +package com.intellij.openapi.editor.ex; + +/** + * + */ +public interface LineIterator { + void start(int startOffset); + int getStart(); + int getEnd(); + int getSeparatorLength(); + int getLineNumber(); + void advance(); + boolean atEnd(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/MarkupModelEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/MarkupModelEx.java new file mode 100644 index 00000000000..07470511b94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/MarkupModelEx.java @@ -0,0 +1,12 @@ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; + +/** + * @author max + */ +public interface MarkupModelEx extends MarkupModel { + RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/RangeHighlighterEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/RangeHighlighterEx.java new file mode 100644 index 00000000000..857e80394a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/RangeHighlighterEx.java @@ -0,0 +1,16 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 10, 2002 + * Time: 5:54:59 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.ex; + +import com.intellij.openapi.editor.markup.RangeHighlighter; + +public interface RangeHighlighterEx extends RangeHighlighter { + boolean isAfterEndOfLine(); + void setAfterEndOfLine(boolean val); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EditorUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EditorUtil.java new file mode 100644 index 00000000000..4b6299ca0e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -0,0 +1,186 @@ +package com.intellij.openapi.editor.ex.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.editor.impl.IterationState; + +import java.awt.*; + +public class EditorUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.EditorUtil"); + + public static int getLastVisualLineColumnNumber(Editor editor, int line) { + VisualPosition visStart = new VisualPosition(line, 0); + LogicalPosition logStart = editor.visualToLogicalPosition(visStart); + int lastLogLine = logStart.line; + while (lastLogLine < editor.getDocument().getLineCount() - 1) { + VisualPosition tryVisible; + logStart = new LogicalPosition(logStart.line + 1, logStart.column); + tryVisible = editor.logicalToVisualPosition(logStart); + if (tryVisible.line != visStart.line) break; + lastLogLine = logStart.line; + } + + int lastLine = editor.getDocument().getLineCount() - 1; + if (lastLine < 0) { + return 0; + } + return editor.offsetToVisualPosition(editor.getDocument().getLineEndOffset(Math.min(lastLogLine, lastLine))).column; + } + + public static float calcVerticalScrollProportion(Editor editor) { + Rectangle viewRect = editor.getScrollingModel().getVisibleAreaOnScrollingFinished(); + if (viewRect.height == 0) { + return 0; + } + LogicalPosition pos = editor.getCaretModel().getLogicalPosition(); + Point location = editor.logicalPositionToXY(pos); + return (location.y - viewRect.y) / (float) viewRect.height; + } + + public static void setVerticalScrollProportion(Editor editor, float proportion) { + Rectangle viewRect = editor.getScrollingModel().getVisibleArea(); + LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition(); + Point caretLocation = editor.logicalPositionToXY(caretPosition); + int yPos = caretLocation.y; + yPos -= viewRect.height * proportion; + editor.getScrollingModel().scrollVertically(yPos); + } + + public static void fillVirtualSpaceUntil(Editor editor, int columnNumber, int lineNumber) { + int offset = editor.logicalPositionToOffset(new LogicalPosition(lineNumber, columnNumber)); + int afterLineEnd = EditorModificationUtil.calcAfterLineEnd(editor); + if (afterLineEnd > 0) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < afterLineEnd; i++) { + buf.append(' '); + } + editor.getDocument().insertString(offset, buf.toString()); + } + } + + public static int calcOffset(Editor editor, CharSequence text, int start, int end, int columnNumber, int tabSize) { + // If all tabs here goes before any other chars in the line we may use an optimization here. + boolean useOptimization = true; + boolean hasNonTabs = false; + for (int i = start; i < end; i++) { + if (text.charAt(i) == '\t') { + if (hasNonTabs) { + useOptimization = false; + break; + } + } else { + hasNonTabs = true; + } + } + + if (editor == null || useOptimization) { + int shift = 0; + int offset = start; + for (; offset < end && offset + shift < start + columnNumber; offset++) { + if (text.charAt(offset) == '\t') { + shift += (getTabLength(offset + shift - start, tabSize) - 1); + } + } + if (offset + shift > start + columnNumber) { + offset--; + } + + return offset; + } + + EditorImpl editorImpl = (EditorImpl) editor; + int offset = start; + IterationState state = new IterationState(editorImpl, offset, false); + int fontType = state.getMergedAttributes().getFontType(); + int column = 0; + int x = 0; + int spaceSize = editorImpl.getSpaceWidth(fontType); + while (column < columnNumber) { + if (offset >= state.getEndOffset()) { + state.advance(); + + fontType = state.getMergedAttributes().getFontType(); + } + + char c = offset < end ? text.charAt(offset++) : ' '; + if (c == '\t') { + int prevX = x; + x = editorImpl.nextTabStop(x); + column += (x - prevX) / spaceSize; + } else { + x += editorImpl.charWidth(fontType, c); + column++; + } + } + + if (column > columnNumber) offset--; + + return offset; + } + + private static int getTabLength(int colNumber, int tabSize) { + if (tabSize <= 0) { + tabSize = 1; + } + return tabSize - colNumber % tabSize; + } + + public static int calcColumnNumber(Editor editor, CharSequence text, int start, int offset, int tabSize) { + boolean useOptimization = true; + boolean hasNonTabs = false; + for (int i = start; i < offset; i++) { + if (text.charAt(i) == '\t') { + if (hasNonTabs) { + useOptimization = false; + break; + } + } else { + hasNonTabs = true; + } + } + + if (editor == null || useOptimization) { + int shift = 0; + + for (int i = start; i < offset; i++) { + char c = text.charAt(i); + LOG.assertTrue(c != '\n' && c != '\r'); + if (c == '\t') { + shift += (getTabLength(i + shift - start, tabSize) - 1); + } + } + return offset - start + shift; + } + + EditorImpl editorImpl = (EditorImpl) editor; + IterationState state = new IterationState(editorImpl, start, false); + int fontType = state.getMergedAttributes().getFontType(); + int column = 0; + int x = 0; + int spaceSize = editorImpl.getSpaceWidth(fontType); + for (int i = start; i < offset; i++) { + if (i >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + char c = text.charAt(i); + if (c == '\t') { + int prevX = x; + x = editorImpl.nextTabStop(x); + column += (x - prevX) / spaceSize; + } else { + x += editorImpl.charWidth(fontType, c); + column++; + } + } + + return column; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EmptyHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EmptyHighlighter.java new file mode 100644 index 00000000000..6733998a044 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/EmptyHighlighter.java @@ -0,0 +1,79 @@ +package com.intellij.openapi.editor.ex.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.psi.tree.IElementType; + +public class EmptyHighlighter extends DocumentAdapter implements Highlighter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.EmptyHighlighter"); + + private TextAttributes myAttributes; + private int myTextLength = 0; + private boolean myHasEditor = false; + + public EmptyHighlighter(TextAttributes attributes) { + myAttributes = attributes; + } + + public void setAttributes(TextAttributes attributes) { + myAttributes = attributes; + } + + public void setText(CharSequence text) { + myTextLength = text.length(); + } + + public void setEditor(Editor editor) { + LOG.assertTrue(!myHasEditor, "Highlighters cannot be reused with different editors"); + myHasEditor = true; + } + + public void setColorScheme(EditorColorsScheme scheme) { + setAttributes(scheme.getAttributes(HighlighterColors.TEXT)); + } + + public void documentChanged(DocumentEvent e) { + myTextLength += e.getNewLength() - e.getOldLength(); + } + + public HighlighterIterator createIterator(int startOffset) { + return new HighlighterIterator(){ + private int index = 0; + + public TextAttributes getTextAttributes() { + return myAttributes; + } + + public int getStart() { + return 0; + } + + public int getEnd() { + return myTextLength; + } + + public void advance() { + index++; + } + + public void retreat(){ + index--; + } + + public boolean atEnd() { + return index != 0; + } + + public IElementType getTokenType(){ + return IElementType.find((short)0); + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/LexerHighlighter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/LexerHighlighter.java new file mode 100644 index 00000000000..28bd309690b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/LexerHighlighter.java @@ -0,0 +1,231 @@ +package com.intellij.openapi.editor.ex.util; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.text.CharArrayUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * + */ +public class LexerHighlighter extends DocumentAdapter implements Highlighter { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.LexerHighlighter"); + private Editor myEditor; + private Lexer myLexer; + private Map myAttributesMap; + private SegmentArrayWithData mySegments = new SegmentArrayWithData(); + private FileHighlighter myHighlighter; + private EditorColorsScheme myScheme; + + public LexerHighlighter(FileHighlighter highlighter, EditorColorsScheme scheme) { + myScheme = scheme; + myLexer = highlighter.getHighlightingLexer(); + myAttributesMap = new HashMap(); + myHighlighter = highlighter; + } + + public Lexer getLexer() { + return myLexer; + } + + public void setEditor(Editor editor) { + LOG.assertTrue(myEditor == null, "Highlighters cannot be reused with different editors"); + myEditor = editor; + } + + public void setColorScheme(EditorColorsScheme scheme) { + myScheme = scheme; + myAttributesMap.clear(); + } + + public HighlighterIterator createIterator(int startOffset) { + return new HighlighterIteratorImpl(mySegments, startOffset); + } + + private long packData(IElementType tokenType, int state) { + return tokenType.getIndex() | (((long)state) << 16); + } + + private int unpackState(long data) { + return (int)(data >> 16); + } + + private IElementType unpackToken(long data) { + return IElementType.find((short)(data & 0xFFFF)); + } + + public synchronized void documentChanged(DocumentEvent e) { + Document document = e.getDocument(); + if(mySegments.getSegmentCount() == 0 || myLexer.getSmartUpdateShift() < 0) { + setText(document.getCharsSequence()); + return; + } + CharSequence text = document.getCharsSequence(); + int oldStartOffset = e.getOffset(); + + int startIndex = Math.max(0, mySegments.findSegmentIndex(oldStartOffset) - 2); + int startOffset = mySegments.getSegmentStart(startIndex); + + long data = mySegments.getSegmentData(startIndex); + final int lexerState = unpackState(data); + + int newEndOffset = e.getOffset() + e.getNewLength(); + + myLexer.start(CharArrayUtil.fromSequence(text), startOffset, text.length(), lexerState); + SegmentArrayWithData insertSegments = new SegmentArrayWithData(); + int oldEndIndex = -1; + int insertSegmentCount = 0; + int repaintEnd = -1; + + int lastTokenStart = -1; + while(myLexer.getTokenType() != null) { + int tokenStart = myLexer.getTokenStart(); + if (tokenStart == lastTokenStart) { + throw new IllegalStateException("Error while updating lexer: " + e + " document text: " + e.getDocument().getText()); + } + + lastTokenStart = tokenStart; + + int tokenEnd = myLexer.getTokenEnd(); + data = packData(myLexer.getTokenType(), myLexer.getState()); + if(tokenStart >= newEndOffset) { + int shiftedTokenStart = tokenStart - e.getNewLength() + e.getOldLength(); + int index = mySegments.findSegmentIndex(shiftedTokenStart); + if (mySegments.getSegmentStart(index) == shiftedTokenStart && mySegments.getSegmentData(index) == data) { + repaintEnd = tokenStart; + oldEndIndex = index; + break; + } + } + insertSegments.setElementAt(insertSegmentCount, tokenStart, tokenEnd, data); + insertSegmentCount++; + myLexer.advance(); + } + + if(repaintEnd == -1) { + repaintEnd = text.length(); + } + + if (oldEndIndex < 0){ + oldEndIndex = mySegments.getSegmentCount(); + } + mySegments.shiftSegments(oldEndIndex, e.getNewLength() - e.getOldLength()); + mySegments.remove(startIndex, oldEndIndex); + mySegments.insert(insertSegments, startIndex); + + int lastDocOffset = e.getDocument().getTextLength(); + checkUpdateCorrect(lastDocOffset); + + if (insertSegmentCount == 0 || + oldEndIndex == startIndex + 1 && insertSegmentCount == 1 && data == mySegments.getSegmentData(startIndex)) { + return; + } + + ((EditorEx) myEditor).repaint(startOffset, repaintEnd); + } + + private void checkUpdateCorrect(int lastDocOffset) { + /* + int lastLexerOffset = mySegments.getSegmentEnd(mySegments.getSegmentCount() - 1); + if (lastDocOffset != lastLexerOffset) { + LOG.error("Lexer update failed: lastDocOffset = " + lastDocOffset + ", lastLexerOffset = " + lastLexerOffset); + } + */ + } + + public void setText(CharSequence text) { + int startOffset = 0; + myLexer.start(text.toString().toCharArray(), startOffset, text.length()); + int i = 0; + mySegments.removeAll(); + while(myLexer.getTokenType() != null) { + long data = packData(myLexer.getTokenType(), myLexer.getState()); + mySegments.setElementAt(i, myLexer.getTokenStart(), myLexer.getTokenEnd(), data); + i++; + myLexer.advance(); + } + + checkUpdateCorrect(text.length()); + + if(myEditor != null) { + ((EditorEx) myEditor).repaint(0, text.length()); + } + } + + private TextAttributes getAttributes(IElementType tokenType) { + TextAttributes attrs = myAttributesMap.get(tokenType); + if (attrs == null) { + attrs = convertAttributes(myHighlighter.getTokenHighlights(tokenType)); + myAttributesMap.put(tokenType, attrs); + } + return attrs; + } + + private TextAttributes convertAttributes(TextAttributesKey[] keys) { + EditorColorsScheme scheme = myScheme; + TextAttributes attrs = scheme.getAttributes(HighlighterColors.TEXT); + for (int i = 0; i < keys.length; i++) { + TextAttributesKey key = keys[i]; + TextAttributes attrs2 = scheme.getAttributes(key); + if (attrs2 != null) { + attrs = TextAttributes.merge(attrs, attrs2); + } + } + return attrs; + } + + private class HighlighterIteratorImpl implements HighlighterIterator { + private int mySegmentIndex = 0; + private SegmentArrayWithData mySegments; + + HighlighterIteratorImpl(SegmentArrayWithData segments, + int startOffset) { + mySegments = segments; + mySegmentIndex = mySegments.findSegmentIndex(startOffset); + } + + public TextAttributes getTextAttributes() { + IElementType tokenType = getTokenType(); + return getAttributes(tokenType); + } + + public int getStart() { + return mySegments.getSegmentStart(mySegmentIndex); + } + + public int getEnd() { + return mySegments.getSegmentEnd(mySegmentIndex); + } + + public IElementType getTokenType(){ + return unpackToken(mySegments.getSegmentData(mySegmentIndex)); + } + + public void advance() { + mySegmentIndex++; + } + + public void retreat(){ + mySegmentIndex--; + } + + public boolean atEnd() { + return mySegmentIndex >= mySegments.getSegmentCount() || mySegmentIndex < 0; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArray.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArray.java new file mode 100644 index 00000000000..2cb1e4723f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArray.java @@ -0,0 +1,170 @@ +package com.intellij.openapi.editor.ex.util; + +import com.intellij.openapi.diagnostic.Logger; + +public class SegmentArray { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.SegmentArray"); + protected SegmentArray() { + myStarts = new int[INITIAL_SIZE]; + myEnds = new int[INITIAL_SIZE]; + } + + protected void setElementAt(int i, int startOffset, int endOffset) { + if(i >= mySegmentCount) { + mySegmentCount = i+1; + } + myStarts = relocateArray(myStarts, i); + myStarts[i] = startOffset; + + myEnds = relocateArray(myEnds, i); + myEnds[i] = endOffset; + } + + protected static int[] relocateArray(int[] array, int index) { + if(index < array.length) + return array; + + int newArraySize = array.length; + if(newArraySize == 0) { + newArraySize = 16; + } + while(newArraySize <= index) { + newArraySize = (newArraySize * 120) / 100; + } + int[] newArray = new int[newArraySize]; + System.arraycopy(array, 0, newArray, 0, array.length); + return newArray; + } + protected static long[] relocateArray(long[] array, int index) { + if(index < array.length) + return array; + + int newArraySize = array.length; + if(newArraySize == 0) { + newArraySize = 16; + } + while(newArraySize <= index) { + newArraySize = (newArraySize * 120) / 100; + } + long[] newArray = new long[newArraySize]; + System.arraycopy(array, 0, newArray, 0, array.length); + return newArray; + } + + public final int findSegmentIndex(int offset) { + if(mySegmentCount <= 0) { + if (offset == 0) return 0; + throw new IllegalStateException("no segments avaliable"); + } + + if(offset > myEnds[mySegmentCount -1] || offset < 0){ + throw new IndexOutOfBoundsException("Wrong offset: " + offset); + } + + if (offset == myEnds[mySegmentCount - 1]) return mySegmentCount - 1; + + int start = 0; + int end = mySegmentCount - 1; + + while(start < end) { + int i = (start + end)/2; + if(offset < myStarts[i]) { + end = i-1; + } else if(offset >= myEnds[i]) { + start = i+1; + } else { + return i; + } + } + + LOG.assertTrue(offset >= myStarts[start] && offset < myEnds[start]); + + return start; + } + + public final void changeSegmentLength(int startIndex, int change) { + if(startIndex >= 0 && startIndex < mySegmentCount) { + myEnds[startIndex] += change; + } + shiftSegments(startIndex+1, change); + } + + public final void shiftSegments(int startIndex, int shift) { + for(int i=startIndex; i= mySegmentCount) { + throw(new IndexOutOfBoundsException("Wrong line: " + index)); + } + return myStarts[index]; + } + + public int getSegmentEnd(int index) { + if(index < 0 || index >= mySegmentCount) { + throw(new IndexOutOfBoundsException("Wrong line: " + index)); + } + return myEnds[index]; + } + + + public int getSegmentCount() { + return mySegmentCount; + } + + private int[] myStarts; + private int[] myEnds; + + protected int mySegmentCount = 0; + protected final static int INITIAL_SIZE = 64; +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArrayWithData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArrayWithData.java new file mode 100644 index 00000000000..ab2b255647b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/ex/util/SegmentArrayWithData.java @@ -0,0 +1,36 @@ +package com.intellij.openapi.editor.ex.util; + +public class SegmentArrayWithData extends SegmentArray { + private long[] myData; + + public SegmentArrayWithData() { + myData = new long[INITIAL_SIZE]; + } + + public void setElementAt(int i, int startOffset, int endOffset, long data) { + super.setElementAt(i, startOffset, endOffset); + myData = relocateArray(myData, i+1); + myData[i] = data; + } + + public void remove(int startIndex, int endIndex) { + myData = remove(myData, startIndex, endIndex); + super.remove(startIndex, endIndex); + } + + public void insert(SegmentArrayWithData segmentArray, int startIndex) { + myData = insert(myData, segmentArray.myData, startIndex, segmentArray.getSegmentCount()); + super.insert(segmentArray, startIndex); + } + + public long getSegmentData(int index) { + if(index < 0 || index >= mySegmentCount) throw new IndexOutOfBoundsException("Wrong index: " + index); + return myData[index]; + } + + public void setSegmentData(int index, long data) { + if(index < 0 || index >= mySegmentCount) throw new IndexOutOfBoundsException("Wrong index: " + index); + myData[index] = data; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/BorderEffect.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/BorderEffect.java new file mode 100644 index 00000000000..9ce61c3f346 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/BorderEffect.java @@ -0,0 +1,200 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; +import gnu.trove.Equality; + +import java.awt.*; + +public class BorderEffect { + private final Graphics myGraphics; + private final int myStartOffset; + private final int myEndOffset; + private final TextRange myRange; + private final EditorImpl myEditor; + private static final Equality SAME_COLOR_BOXES = new Equality() { + public boolean equals(Object object1, Object object2) { + TextAttributes attributes1 = (TextAttributes)object1; + TextAttributes attributes2 = (TextAttributes)object2; + Color effectColor = attributes1.getEffectColor(); + EffectType effectType = attributes1.getEffectType(); + return effectColor != null && effectColor.equals(attributes2.getEffectColor()) && + EffectType.BOXED == effectType && effectType == attributes2.getEffectType(); + } + }; + private static final Condition BOX_FILTER = new Condition() { + public boolean value(TextAttributes attributes) { + return attributes.getEffectColor() != null && attributes.getEffectType() == EffectType.BOXED; + } + }; + + public BorderEffect(EditorImpl editor, Graphics graphics) { + myEditor = editor; + myGraphics = graphics; + Rectangle clipBounds = myGraphics.getClipBounds(); + myStartOffset = yToLineStartOffset(editor, clipBounds.y); + myEndOffset = yToLineStartOffset(editor, clipBounds.y + clipBounds.height + editor.getLineHeight()); + myRange = new TextRange(myStartOffset, myEndOffset); + } + + private int yToLineStartOffset(EditorImpl editor, int y) { + Point point = new Point(0, y); + LogicalPosition logicalStart = editor.xyToLogicalPosition(point); + int offset = editor.logicalPositionToOffset(logicalStart); + return offset; + } + + public void paintHighlighters(RangeHighlighter[] highlighterList) { + for (int i = 0; i < highlighterList.length; i++) { + RangeHighlighterImpl rangeHighlighter = (RangeHighlighterImpl)highlighterList[i]; + if (rangeHighlighter.isValid()) { + TextAttributes textAttributes = rangeHighlighter.getTextAttributes(); + if (isBorder(textAttributes) && + intersectsRange(rangeHighlighter)) + paintBorder(rangeHighlighter); + } + } + } + + private boolean isBorder(TextAttributes textAttributes) { + return textAttributes != null && + textAttributes.getEffectColor() != null && + EffectType.BOXED == textAttributes.getEffectType(); + } + + private void paintBorder(RangeHighlighterImpl rangeHighlighter) { + paintBorder(rangeHighlighter.getTextAttributes().getEffectColor(), + rangeHighlighter.getAffectedAreaStartOffset(), + rangeHighlighter.getAffectedAreaEndOffset()); + } + + private void paintBorder(Color color, int startOffset, int endOffset) { + paintBorder(myGraphics, myEditor, startOffset, endOffset, color); + } + + private boolean intersectsRange(RangeHighlighterImpl rangeHighlighter) { + return myRange.contains(rangeHighlighter.getAffectedAreaStartOffset()) || + myRange.contains(rangeHighlighter.getAffectedAreaEndOffset()); + } + + public void paintHighlighters(Highlighter highlighter) { + int startOffset = startOfLineByOffset(myStartOffset); + if (0 > startOffset || startOffset >= myEditor.getDocument().getTextLength()) return; + RangeIterator iterator = new RangeIterator(new FoldingOrNewLineGaps(myEditor), SAME_COLOR_BOXES, + highlighter.createIterator(startOffset), + BOX_FILTER); + iterator.init(myRange); + for (; !iterator.atEnd();) { + iterator.advance(); + paintBorder(myGraphics, myEditor, iterator.getStart(), iterator.getEnd(), + iterator.getTextAttributes().getEffectColor()); + } + } + + private int startOfLineByOffset(int offset) { + int line = myEditor.offsetToLogicalPosition(offset).line; + if (line >= myEditor.getDocument().getLineCount()) return -1; + return myEditor.getDocument().getLineStartOffset(line); + } + + private static void paintBorder(Graphics g, EditorImpl editor, int startOffset, int endOffset, Color color) { + Color savedColor = g.getColor(); + g.setColor(color); + paintBorder(g, editor, startOffset, endOffset); + g.setColor(savedColor); + } + + private static void paintBorder(Graphics g, EditorImpl editor, int startOffset, int endOffset) { + Point startPoint = offsetToXY(editor, startOffset); + Point endPoint = offsetToXY(editor, endOffset); + int height = endPoint.y - startPoint.y; + int startX = startPoint.x; + int startY = startPoint.y; + int endX = endPoint.x; + if (height == 0) { + int width = endX == startX ? 1 : endX - startX - 1; + g.drawRect(startX, startY, width, editor.getLineHeight() - 1); + return; + } + BorderGraphics border = new BorderGraphics(g, startX, startY); + border.horizontalTo(editor.getMaxWidthInRange(startOffset, endOffset) - 1); + border.verticalRel(height - 1); + border.horizontalTo(endX); + border.verticalRel(editor.getLineHeight()); + border.horizontalTo(0); + border.verticalRel(-height + 1); + border.horizontalTo(startX); + border.verticalTo(startY); + } + + private static Point offsetToXY(EditorImpl editor, int offset) { + return editor.logicalPositionToXY(editor.offsetToLogicalPosition(offset)); + } + + public static void paintFoldedEffect(Graphics g, int foldingXStart, + int y, int foldingXEnd, int lineHeight, Color effectColor, + EffectType effectType) { + if (effectColor == null || effectType != EffectType.BOXED) return; + g.setColor(effectColor); + g.drawRect(foldingXStart, y, foldingXEnd - foldingXStart, lineHeight - 1); + } + + private static class FoldingOrNewLineGaps implements RangeIterator.Gaps { + private final RangeIterator.FoldingGaps myFoldingGaps; + private final CharSequence myChars; + + public FoldingOrNewLineGaps(CharSequence chars, RangeIterator.FoldingGaps foldingGaps) { + myChars = chars; + myFoldingGaps = foldingGaps; + } + + public FoldingOrNewLineGaps(EditorImpl editor) { + this(editor.getDocument().getCharsSequence(), new RangeIterator.FoldingGaps(editor.getFoldingModel())); + } + + public boolean isGapAt(int offset) { + return myChars.charAt(offset) == '\n' || myFoldingGaps.isGapAt(offset); + } + } + + public static class BorderGraphics { + private final Graphics myGraphics; + + private int myX; + private int myY; + + public BorderGraphics(Graphics graphics, int startX, int stIntY) { + myGraphics = graphics; + + myX = startX; + myY = stIntY; + } + + public void horizontalTo(int x) { + lineTo(x, myY); + } + + public void horizontalRel(int width) { + lineTo(myX + width, myY); + } + + private void lineTo(int x, int y) { + myGraphics.drawLine(myX, myY, x, y); + myX = x; + myY = y; + } + + public void verticalRel(int height) { + lineTo(myX, myY + height); + } + + public void verticalTo(int y) { + lineTo(myX, y); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/CaretModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/CaretModelImpl.java new file mode 100644 index 00000000000..dc13016811d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -0,0 +1,412 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 18, 2002 + * Time: 9:12:05 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; +import com.intellij.openapi.editor.markup.TextAttributes; + +import java.awt.*; +import java.util.ArrayList; + +public class CaretModelImpl implements CaretModel, DocumentListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.CaretModelImpl"); + private EditorImpl myEditor; + private ArrayList myCaretListeners = new ArrayList(); + private LogicalPosition myLogicalCaret; + private VisualPosition myVisibleCaret; + private int myOffset; + private int myVisualLineStart; + private int myVisualLineEnd; + private TextAttributes myTextAttributes; + private boolean myIsInUpdate; + + public CaretModelImpl(EditorImpl editor) { + myEditor = editor; + myLogicalCaret = new LogicalPosition(0, 0); + myVisibleCaret = new VisualPosition(0, 0); + myOffset = 0; + myVisualLineStart = 0; + Document doc = editor.getDocument(); + if (doc.getLineCount() > 1) { + myVisualLineEnd = doc.getLineStartOffset(1); + } + else { + myVisualLineEnd = doc.getLineCount() == 0 ? 0 : doc.getLineEndOffset(0); + } + } + + public void moveToVisualPosition(VisualPosition pos) { + validateCallContext(); + int column = pos.column; + int line = pos.line; + + if (column < 0) column = 0; + + if (line < 0) line = 0; + + int lastLine = myEditor.getVisibleLineCount() - 1; + if (lastLine <= 0) { + lastLine = 0; + } + + if (line > lastLine) { + line = lastLine; + } + + EditorSettings editorSettings = myEditor.getSettings(); + + if (!editorSettings.isVirtualSpace() && line <= lastLine) { + int lineEndColumn = EditorUtil.getLastVisualLineColumnNumber(myEditor, line); + if (column > lineEndColumn) { + column = lineEndColumn; + } + + if (column < 0 && line > 0) { + line--; + column = EditorUtil.getLastVisualLineColumnNumber(myEditor, line); + } + } + + int oldY = myEditor.visibleLineNumberToYPosition(myVisibleCaret.line); + + myVisibleCaret = new VisualPosition(line, column); + + LogicalPosition oldPosition = myLogicalCaret; + + myLogicalCaret = myEditor.visualToLogicalPosition(myVisibleCaret); + myOffset = myEditor.logicalPositionToOffset(myLogicalCaret); + LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength()); + + myVisualLineStart = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0))); + myVisualLineEnd = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0))); + + ((FoldingModelImpl)myEditor.getFoldingModel()).flushCaretPosition(); + + myEditor.setLastColumnNumber(myVisibleCaret.column); + myEditor.updateCaretCursor(); + requestRepaint(oldY); + + if (oldPosition.column != myLogicalCaret.column || oldPosition.line != myLogicalCaret.line) { + CaretEvent event = new CaretEvent(myEditor, oldPosition, myLogicalCaret); + + + CaretListener[] listeners = myCaretListeners.toArray(new CaretListener[myCaretListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].caretPositionChanged(event); + } + } + } + + public void moveToOffset(int offset) { + validateCallContext(); + moveToLogicalPosition(myEditor.offsetToLogicalPosition(offset)); + if (myOffset != offset) { + LOG.error("caret moved to wrong offset. Requested:" + offset + " but actual:" + myOffset); + } + } + + public void moveCaretRelatively(int columnShift, + int lineShift, + boolean withSelection, + boolean blockSelection, + boolean scrollToCaret) { + SelectionModel selectionModel = myEditor.getSelectionModel(); + int selectionStart = selectionModel.getLeadSelectionOffset(); + LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : getLogicalPosition(); + EditorSettings editorSettings = myEditor.getSettings(); + VisualPosition visualCaret = getVisualPosition(); + + int newColumnNumber = visualCaret.column + columnShift; + int newLineNumber = visualCaret.line + lineShift; + + if (!editorSettings.isVirtualSpace() && columnShift == 0) { + newColumnNumber = myEditor.getLastColumnNumber(); + } + else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) { + int lastLine = myEditor.getDocument().getLineCount() - 1; + if (lastLine < 0) lastLine = 0; + if (EditorModificationUtil.calcAfterLineEnd(myEditor) >= 0 && + newLineNumber < myEditor.logicalToVisualPosition(new LogicalPosition(lastLine, 0)).line) { + newColumnNumber = 0; + newLineNumber++; + } + } + else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == -1) { + if (newColumnNumber < 0 && newLineNumber > 0) { + newLineNumber--; + newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber); + } + } + + if (newColumnNumber < 0) newColumnNumber = 0; + if (newLineNumber < 0) newLineNumber = 0; + + int lastColumnNumber = newColumnNumber; + if (!editorSettings.isCaretInsideTabs()) { + LogicalPosition log = myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber)); + int offset = myEditor.logicalPositionToOffset(log); + CharSequence text = myEditor.getDocument().getCharsSequence(); + if (offset >= 0 && offset < myEditor.getDocument().getTextLength()) { + if (text.charAt(offset) == '\t') { + if (columnShift <= 0) { + newColumnNumber = myEditor.offsetToVisualPosition(offset).column; + } + else { + if (myEditor.offsetToVisualPosition(offset).column < newColumnNumber) { + newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column; + } + } + } + } + } + + VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber); + moveToVisualPosition(pos); + + if (!editorSettings.isVirtualSpace() && columnShift == 0) { + myEditor.setLastColumnNumber(lastColumnNumber); + } + + if (withSelection) { + if (blockSelection) { + selectionModel.setBlockSelection(blockSelectionStart, getLogicalPosition()); + } + else { + selectionModel.setSelection(selectionStart, getOffset()); + } + } + else { + selectionModel.removeSelection(); + } + + if (scrollToCaret) { + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + } + + public void moveToLogicalPosition(LogicalPosition pos) { + validateCallContext(); + int column = pos.column; + int line = pos.line; + + Document doc = myEditor.getDocument(); + + if (column < 0) column = 0; + if (line < 0) line = 0; + + int lineCount = doc.getLineCount(); + if (lineCount == 0) { + line = 0; + } + else if (line > lineCount - 1) { + line = lineCount - 1; + } + + EditorSettings editorSettings = myEditor.getSettings(); + + if (!editorSettings.isVirtualSpace() && line < lineCount) { + int lineEndOffset = doc.getLineEndOffset(line); + int lineEndColumnNumber = myEditor.offsetToLogicalPosition(lineEndOffset).column; + if (column > lineEndColumnNumber) { + column = lineEndColumnNumber; + } + } + + ((FoldingModelImpl)myEditor.getFoldingModel()).flushCaretPosition(); + + int oldY = myEditor.visibleLineNumberToYPosition(myVisibleCaret.line); + + LogicalPosition oldCaretPosition = myLogicalCaret; + + myLogicalCaret = new LogicalPosition(line, column); + + final int offset = myEditor.logicalPositionToOffset(myLogicalCaret); + + FoldRegion collapsedAt = ((FoldingModelImpl)myEditor.getFoldingModel()).getCollapsedRegionAtOffset(offset); + + if (collapsedAt != null && offset > collapsedAt.getStartOffset()) { + Runnable runnable = new Runnable() { + public void run() { + FoldRegion[] allCollapsedAt = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchCollapsedAt(offset); + for (int i = 0; i < allCollapsedAt.length; i++) { + FoldRegion foldRange = allCollapsedAt[i]; + foldRange.setExpanded(true); + } + } + }; + + myEditor.getFoldingModel().runBatchFoldingOperation(runnable); + } + + myEditor.setLastColumnNumber(myLogicalCaret.column); + myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret); + + myOffset = myEditor.logicalPositionToOffset(myLogicalCaret); + LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength()); + + myVisualLineStart = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0))); + myVisualLineEnd = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0))); + + myEditor.updateCaretCursor(); + requestRepaint(oldY); + + if (oldCaretPosition.column != myLogicalCaret.column || oldCaretPosition.line != myLogicalCaret.line) { + CaretEvent event = new CaretEvent(myEditor, oldCaretPosition, myLogicalCaret); + + CaretListener[] listeners = myCaretListeners.toArray(new CaretListener[myCaretListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].caretPositionChanged(event); + } + } + } + + private void requestRepaint(int oldY) { + int newY = myEditor.visibleLineNumberToYPosition(myVisibleCaret.line); + int lineHeight = myEditor.getLineHeight(); + Rectangle visibleRect = myEditor.getScrollingModel().getVisibleArea(); + + if (Math.abs(newY - oldY) <= 2 * lineHeight) { + int minY = Math.min(oldY, newY); + int maxY = Math.max(oldY + lineHeight, newY + lineHeight); + ((EditorComponentImpl)myEditor.getContentComponent()).repaintEditorComponent(0, minY, + myEditor.getScrollPane() + .getHorizontalScrollBar() + .getValue() + + visibleRect.width, + maxY - minY); + } + else { + ((EditorComponentImpl)myEditor.getContentComponent()).repaintEditorComponent(0, oldY, + myEditor.getScrollPane() + .getHorizontalScrollBar() + .getValue() + + visibleRect.width, + 2 * lineHeight); + ((EditorComponentImpl)myEditor.getContentComponent()).repaintEditorComponent(0, newY, + myEditor.getScrollPane() + .getHorizontalScrollBar() + .getValue() + + visibleRect.width, + 2 * lineHeight); + } + } + + public LogicalPosition getLogicalPosition() { + validateCallContext(); + return myLogicalCaret; + } + + private void validateCallContext() { + ApplicationManager.getApplication().assertIsDispatchThread(); + LOG.assertTrue(!myIsInUpdate, "Caret model is in its update process. All requests are illegal at this point."); + } + + public VisualPosition getVisualPosition() { + validateCallContext(); + return myVisibleCaret; + } + + public int getOffset() { + validateCallContext(); + return myOffset; + } + + public int getVisualLineStart() { + return myVisualLineStart; + } + + public int getVisualLineEnd() { + return myVisualLineEnd; + } + + public void addCaretListener(CaretListener listener) { + myCaretListeners.add(listener); + } + + public void removeCaretListener(CaretListener listener) { + boolean success = myCaretListeners.remove(listener); + LOG.assertTrue(success); + } + + public TextAttributes getTextAttributes() { + if (myTextAttributes == null) { + myTextAttributes = new TextAttributes(); + myTextAttributes.setBackgroundColor(myEditor.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR)); + } + + return myTextAttributes; + } + + public void reinitSettings() { + myTextAttributes = null; + } + + public void documentChanged(DocumentEvent e) { + myIsInUpdate = false; + + DocumentEventImpl event = (DocumentEventImpl)e; + if (event.isWholeTextReplaced()) { + int newLength = myEditor.getDocument().getTextLength(); + if (myOffset == newLength - e.getNewLength() + e.getOldLength()) { + moveToOffset(newLength); + } + else { + final int line = event.translateLineViaDiff(myLogicalCaret.line); + moveToLogicalPosition(new LogicalPosition(line, myLogicalCaret.column)); + } + } + else { + int startOffset = e.getOffset(); + int oldEndOffset = startOffset + e.getOldLength(); + + int newOffset = myOffset; + VisualPosition oldPosition = getVisualPosition(); + + if (myOffset > oldEndOffset || myOffset >= oldEndOffset && e.getOldLength() > 0) { + newOffset += e.getNewLength() - e.getOldLength(); + } + else if (myOffset >= startOffset && myOffset <= oldEndOffset) { + newOffset = Math.min(newOffset, startOffset + e.getNewLength()); + } + + newOffset = Math.min(newOffset, myEditor.getDocument().getTextLength()); + + if (newOffset != myOffset) { + moveToOffset(newOffset); + } + else { + moveToVisualPosition(oldPosition); + } + } + + myVisualLineStart = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0))); + myVisualLineEnd = + myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0))); + } + + public void beforeDocumentChange(DocumentEvent e) { + myIsInUpdate = true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentImpl.java new file mode 100644 index 00000000000..3e180fbf92f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -0,0 +1,706 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.EditReadOnlyListener; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.ex.LineIterator; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.util.LocalTimeCounter; +import com.intellij.util.containers.CoModifiableList; +import com.intellij.util.containers.WeakList; +import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.CharArrayUtil; +import gnu.trove.THashMap; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.*; + +public class DocumentImpl implements DocumentEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.DocumentImpl"); + + private ArrayList myDocumentListeners = new ArrayList(); + private CoModifiableList myRangeMarkers = new CoModifiableList(new WeakList()); + private List myGuardedBlocks = new ArrayList(); + + private LineSet myLineSet = new LineSet(); + private CharArray myText = new CharArray(); + private boolean myIsReadOnly = false; + private final THashMap myUserDataMap = new THashMap(4); + private boolean isStripTrailingSpacesEnabled = true; + private long myModificationStamp; + private HashMap myProjectToMarkupModelMap = new HashMap(); + private PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this); + + private MarkupModelImpl myMarkupModel; + private DocumentListener[] myCachedDocumentListeners; + private List myReadOnlyListeners = new ArrayList(1); + + private static final Comparator ourListenersComparator = new Comparator() { + public int compare(Object o1, Object o2) { + return getPriority(o1) - getPriority(o2); + } + + private int getPriority(Object o) { + if (o instanceof FoldingModel) return 1; + if (o instanceof Highlighter) return 2; + if (o instanceof CaretModel) return 3; + if (o instanceof SelectionModel) return 4; + if (o instanceof EditorImpl.EditorDocumentAdapter) return 5; + + return 6; + } + }; + private int myCheckGuardedBlocks = 0; + private boolean myGuardsSuppressed = false; + + private DocumentImpl() { + setModificationStamp(LocalTimeCounter.currentTime()); + } + + public DocumentImpl(String text) { + this(); + LOG.assertTrue(text.indexOf("\r") < 0, "Wrong line separators in Document"); + + setChars(text); + setModificationStamp(LocalTimeCounter.currentTime()); + } + + public DocumentImpl(CharSequence chars) { + this(); + setChars(chars); + } + + public char[] getChars() { + return CharArrayUtil.fromSequence(getCharsSequence()); + } + + private void setChars(CharSequence chars) { + myText = new CharArray(chars); + DocumentEvent event = new DocumentEventImpl(this, 0, null, null, -1); + myLineSet.documentCreated(event); + } + + public MarkupModel getMarkupModel() { + if (myMarkupModel == null) myMarkupModel = new MarkupModelImpl(this); + return myMarkupModel; + } + + public void setStripTrailingSpacesEnabled(boolean isEnabled) { + isStripTrailingSpacesEnabled = isEnabled; + } + + public void stripTrailingSpaces(boolean inChangedLinesOnly) { + Editor[] editors = EditorFactory.getInstance().getEditors(this, null); + VisualPosition[] visualCarets = new VisualPosition[editors.length]; + int[] caretLines = new int[editors.length]; + for (int i = 0; i < editors.length; i++) { + visualCarets[i] = editors[i].getCaretModel().getVisualPosition(); + caretLines[i] = editors[i].getCaretModel().getLogicalPosition().line; + } + + if (!isStripTrailingSpacesEnabled) { + return; + } + + boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode(); + + lines: + for (int i = 0; i < myLineSet.getLineCount(); i++) { + if (!isTestMode) { + for (int j = 0; j < caretLines.length; j++) { + if (caretLines[j] == i) continue lines; + } + } + + if (!inChangedLinesOnly || myLineSet.isModified(i)) { + int start = -1; + int lineEnd = myLineSet.getLineEnd(i) - myLineSet.getSeparatorLength(i); + int lineStart = myLineSet.getLineStart(i); + CharSequence text = myText.getCharArray(); + for (int offset = lineEnd - 1; offset >= lineStart; offset--) { + char c = text.charAt(offset); + if (c != ' ' && c != '\t') { + break; + } + start = offset; + } + if (start != -1) { + deleteString(start, lineEnd); + } + } + } + + for (int i = 0; i < editors.length; i++) { + editors[i].getCaretModel().moveToVisualPosition(visualCarets[i]); + } + } + + public void putUserData(Key key, T value) { + synchronized (myUserDataMap) { + if (value != null) { + myUserDataMap.put(key, value); + } + else { + myUserDataMap.remove(key); + } + } + } + + public T getUserData(Key key) { + synchronized (myUserDataMap) { + return (T)myUserDataMap.get(key); + } + } + + public void setReadOnly(boolean isReadOnly) { + if (myIsReadOnly != isReadOnly) { + myIsReadOnly = isReadOnly; + myPropertyChangeSupport.firePropertyChange(PROP_WRITABLE, !isReadOnly, isReadOnly); + } + } + + public boolean isWritable() { + return !myIsReadOnly; + } + + public void addRangeMarker(RangeMarker rangeMarker) { + if (rangeMarker instanceof SelectionModelImpl.MyRangeMarker) return; //Selection range marker is updated by selection model directly. + + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + myRangeMarkers.add((RangeMarkerImpl)rangeMarker); + } + + public RangeMarker createGuardedBlock(int startOffset, int endOffset) { + LOG.assertTrue(startOffset < endOffset, "Should be startOffset < endOffset"); + RangeMarker block = createRangeMarker(startOffset, endOffset, true); + myGuardedBlocks.add(block); + return block; + } + + public void removeGuardedBlock(RangeMarker block) { + myGuardedBlocks.remove(block); + } + + public List getGuardedBlocks() { + return myGuardedBlocks; + } + + public RangeMarker getOffsetGuard(int offset) { + for (int i = 0; i < myGuardedBlocks.size(); i++) { + RangeMarker block = myGuardedBlocks.get(i); + if (offsetInRange(offset, block.getStartOffset(), block.getEndOffset())) return block; + } + + return null; + } + + public RangeMarker getRangeGuard(int start, int end) { + for (int i = 0; i < myGuardedBlocks.size(); i++) { + RangeMarker block = myGuardedBlocks.get(i); + if (rangeIntersect(start, end, block.getStartOffset(), block.getEndOffset())) return block; + } + + return null; + } + + public void startGuardedBlockChecking() { + myCheckGuardedBlocks++; + } + + public void stopGuardedBlockChecking() { + LOG.assertTrue(myCheckGuardedBlocks > 0, "Unpaired start/stopGuardedBlockChecking"); + myCheckGuardedBlocks--; + } + + private static boolean offsetInRange(int offset, int start, int end) { + return start <= offset && offset < end; + } + + private static boolean rangeIntersect(int s1, int e1, int s2, int e2) { + return s2 < s1 && s1 < e2 || s2 < e1 && e1 < e2 + || s1 < s2 && s2 < e1 || s1 < e2 && e2 < e1 + || s1 == s2 && e1 == e2; + } + + public RangeMarker createRangeMarker(int startOffset, int endOffset) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return new RangeMarkerImpl(this, startOffset, endOffset); + } + + public RangeMarker createRangeMarker(int startOffset, int endOffset, boolean surviveOnExternalChange) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + if (!(0 <= startOffset && startOffset <= endOffset && endOffset <= getTextLength())) { + LOG.error("Incorrect offsets startOffset=" + startOffset + ", endOffset=" + endOffset + ", text length=" + + getTextLength()); + } + + if (surviveOnExternalChange) { + return new PersistentRangeMarker(this, startOffset, endOffset); + } + else { + return new RangeMarkerImpl(this, startOffset, endOffset); + } + } + + public PersistentLineMarker createPersistentLineMarker(int offset) { + return new PersistentLineMarker(this, offset); + } + + public long getModificationStamp() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myModificationStamp; + } + + public void setModificationStamp(long modificationStamp) { + myModificationStamp = modificationStamp; + } + + public void replaceText(CharSequence chars, long newModificationStamp) { + replaceString(0, getTextLength(), chars, newModificationStamp); //TODO: optimization!!! + } + + public int getListenersCount() { + return myDocumentListeners.size(); + } + + public void insertString(int offset, CharSequence s) { + if (offset < 0 || offset > getTextLength()) throw new IndexOutOfBoundsException("Wrong offset: " + offset); + ApplicationManager.getApplication().assertWriteAccessAllowed(); + assertValidSeparators(s); + + if (!isWritable()) throw new ReadOnlyModificationException(this); + if (s.length() == 0) return; + + RangeMarker marker = getRangeGuard(offset, offset); + if (marker != null) { + throwGuardedFragment(marker, offset, null, s.toString()); + } + + DocumentEvent event = beforeChangedUpdate(offset, null, s); + myText.insert(s, offset); + changedUpdate(event, LocalTimeCounter.currentTime()); + } + + public void deleteString(int startOffset, int endOffset) { + if (startOffset < 0 || startOffset > getTextLength()) { + throw new IndexOutOfBoundsException("Wrong startOffset: " + startOffset); + } + if (endOffset < 0 || endOffset > getTextLength()) { + throw new IndexOutOfBoundsException("Wrong endOffset: " + endOffset); + } + if (endOffset < startOffset) { + throw new IllegalArgumentException("endOffset < startOffset: " + endOffset + " < " + startOffset); + } + + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (!isWritable()) throw new ReadOnlyModificationException(this); + if (startOffset == endOffset) return; + CharSequence sToDelete = myText.substring(startOffset, endOffset); + + RangeMarker marker = getRangeGuard(startOffset, endOffset); + if (marker != null) { + throwGuardedFragment(marker, startOffset, sToDelete.toString(), null); + } + + DocumentEvent event = beforeChangedUpdate(startOffset, sToDelete, null); + myText.remove(startOffset, endOffset); + changedUpdate(event, LocalTimeCounter.currentTime()); + } + + public void replaceString(int startOffset, int endOffset, CharSequence s) { + replaceString(startOffset, endOffset, s, LocalTimeCounter.currentTime()); + } + + private void replaceString(int startOffset, int endOffset, CharSequence s, long newModificationStamp) { + if (startOffset < 0 || startOffset > getTextLength()) { + throw new IndexOutOfBoundsException("Wrong startOffset: " + startOffset); + } + if (endOffset < 0 || endOffset > getTextLength()) { + throw new IndexOutOfBoundsException("Wrong endOffset: " + endOffset); + } + if (endOffset < startOffset) { + throw new IllegalArgumentException("endOffset < startOffset: " + endOffset + " < " + startOffset); + } + + ApplicationManager.getApplication().assertWriteAccessAllowed(); + assertValidSeparators(s); + + if (!isWritable()) { + throw new ReadOnlyModificationException(this); + } + final int newStringLength = s.length(); + final CharSequence chars = getCharsSequence(); + int newStartInString = 0; + int newEndInString = newStringLength; + { + while(newStartInString < newStringLength && + startOffset < endOffset && + s.charAt(newStartInString) == chars.charAt(startOffset)){ + startOffset++; + newStartInString++; + } + + while(endOffset > startOffset && + newEndInString > newStartInString && + s.charAt(newEndInString - 1) == chars.charAt(endOffset - 1)){ + newEndInString--; + endOffset--; + } + } + if (newEndInString - newStartInString == 0 && startOffset == endOffset) { + setModificationStamp(newModificationStamp); + return; + } + + s = s.subSequence(newStartInString, newEndInString); + CharSequence sToDelete = myText.substring(startOffset, endOffset); + RangeMarker guard = getRangeGuard(startOffset, endOffset); + if (guard != null) { + throwGuardedFragment(guard, startOffset, sToDelete.toString(), s.toString()); + } + + DocumentEvent event = beforeChangedUpdate(startOffset, sToDelete, s); + myText.remove(startOffset, endOffset); + myText.insert(s, startOffset); + changedUpdate(event, newModificationStamp); + } + + private void assertValidSeparators(final CharSequence s) { + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '\r') { + LOG.error("Wrong line separators inserted into Document"); + } + } + } + + private void throwGuardedFragment(RangeMarker guard, int offset, String oldString, String newString) { + if (myCheckGuardedBlocks > 0 && !myGuardsSuppressed) { + DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp); + throw new ReadOnlyFragmentModificationException(event, guard); + } + } + + public void suppressGuardedExceptions() { + myGuardsSuppressed = true; + } + + public void unSuppressGuardedExceptions() { + myGuardsSuppressed = false; + } + + private DocumentEvent beforeChangedUpdate(int offset, CharSequence oldString, CharSequence newString) { + DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp); + + DocumentListener[] listeners = getCachedListeners(); + for (int i = listeners.length - 1; i >= 0; i--) { + try { + listeners[i].beforeDocumentChange(event); + } + catch (Throwable e) { + LOG.error(e); + } + } + + return event; + } + + private void changedUpdate(DocumentEvent event, long newModificationStamp) { + LOG.debug(event.toString()); + myLineSet.changedUpdate(event); + setModificationStamp(newModificationStamp); + + updateRangeMarkers(event); + + DocumentListener[] listeners = getCachedListeners(); + for (int i = 0; i < listeners.length; i++) { + DocumentListener listener = listeners[i]; + try { + listener.documentChanged(event); + } + catch (Throwable e) { + LOG.error(e); + } + } + } + + private void updateRangeMarkers(final DocumentEvent event) { + try { + myRangeMarkers.forEach(new CoModifiableList.InnerIterator() { + public void process(RangeMarkerImpl rangeMarker, Iterator iterator) { + try { + if (rangeMarker.isValid()) { + rangeMarker.documentChanged(event); + if (!rangeMarker.isValid() && myGuardedBlocks.remove(rangeMarker)) { + LOG.error("Guarded blocks should stay valid"); + } + } + else { + iterator.remove(); + } + } + catch (Exception e) { + LOG.error(e); + } + } + }); + } + catch (Exception e) { + LOG.error(e); + } + } + + public String getText() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myText.toString(); + } + + public int getTextLength() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myText.getLength(); + } + +/* + This method should be used very carefully - only to read the array, and to be sure, that nobody changes + text, while this array is processed. + Really it is used only to optimize paint in Editor. + [Valentin] 25.04.2001: More really, it is used in 61 places in 29 files across the project :-))) +*/ + + CharSequence getCharsNoThreadCheck() { + return myText.getCharArray(); + } + + public CharSequence getCharsSequence() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myText.getCharArray(); + } + + + public void addDocumentListener(DocumentListener listener) { + myCachedDocumentListeners = null; + LOG.assertTrue(!myDocumentListeners.contains(listener), listener.toString()); + myDocumentListeners.add(listener); + } + + public void removeDocumentListener(DocumentListener listener) { + myCachedDocumentListeners = null; + boolean success = myDocumentListeners.remove(listener); + LOG.assertTrue(success); + } + + public int getLineNumber(int offset) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myLineSet.findLineIndex(offset); + } + + public LineIterator createLineIterator() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myLineSet.createIterator(); + } + + public final int getLineStartOffset(int line) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + if (line == 0) return 0; // otherwise it crashed for zero-length document + return myLineSet.getLineStart(line); + } + + public final int getLineEndOffset(int line) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myLineSet.getLineEnd(line) - getLineSeparatorLength(line); + } + + public final int getLineSeparatorLength(int line) { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myLineSet.getSeparatorLength(line); + } + + public final int getLineCount() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + return myLineSet.getLineCount(); + } + + private DocumentListener[] getCachedListeners() { + if (myCachedDocumentListeners == null) { + Collections.sort(myDocumentListeners, ourListenersComparator); + myCachedDocumentListeners = myDocumentListeners.toArray(new DocumentListener[myDocumentListeners.size()]); + } + + return myCachedDocumentListeners; + } + + public void fireReadOnlyModificationAttempt() { + ApplicationManagerEx.getApplicationEx().assertReadAccessToDocumentsAllowed(); + EditReadOnlyListener[] listeners = myReadOnlyListeners.toArray( + new EditReadOnlyListener[myReadOnlyListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].readOnlyModificationAttempt(this); + } + } + + public void addEditReadOnlyListener(EditReadOnlyListener listener) { + myReadOnlyListeners.add(listener); + } + + public void removeEditReadOnlyListener(EditReadOnlyListener listener) { + myReadOnlyListeners.remove(listener); + } + + public void removeMarkupModel(Project project) { + MarkupModel model = myProjectToMarkupModelMap.remove(project); + if (model != null) { + ((MarkupModelImpl)model).dispose(); + } + } + + public MarkupModel getMarkupModel(Project project) { + return getMarkupModel(project, true); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.removePropertyChangeListener(listener); + } + + public MarkupModel getMarkupModel(Project project, boolean create) { + if (project == null) { + if (create && myMarkupModel == null) { + myMarkupModel = new MarkupModelImpl(this); + } + return myMarkupModel; + } + + if (DocumentMarkupModelManager.getInstance(project).isDisposed()) return null; + + MarkupModel model = myProjectToMarkupModelMap.get(project); + if (create && model == null) { + model = new MarkupModelImpl(this); + myProjectToMarkupModelMap.put(project, model); + DocumentMarkupModelManager.getInstance(project).registerDocument(this); + } + + return model; + } + + //------------------ Class CharArray --------------------------------------------- + + private static class CharArray { + private int myCount = 0; + private CharSequence myOriginalSequence; + private char[] myArray = null; + private String myString = null; // buffers String value - for not to generate it every time + + public CharArray(CharSequence chars) { + myOriginalSequence = chars; + myCount = chars.length(); + } + + public CharArray() { + this(""); + } + + public void replaceText(CharSequence chars) { + myOriginalSequence = chars; + myArray = null; + myCount = chars.length(); + myString = null; + } + + public void remove(int startIndex, int endIndex) { + prepareForModification(); + + if (endIndex < myCount) { + System.arraycopy(myArray, endIndex, myArray, startIndex, myCount - endIndex); + } + myCount -= (endIndex - startIndex); + } + + public void insert(CharSequence s, int startIndex) { + prepareForModification(); + + int insertLength = s.length(); + myArray = relocateArray(myArray, myCount + insertLength); + if (startIndex < myCount) { + System.arraycopy(myArray, startIndex, myArray, startIndex + insertLength, myCount - startIndex); + } + CharArrayUtil.getChars(s, myArray,startIndex); + myCount += insertLength; + } + + private void prepareForModification() { + if (myOriginalSequence != null) { + myArray = new char[myOriginalSequence.length()]; + CharArrayUtil.getChars(myOriginalSequence, myArray, 0); + myOriginalSequence = null; + } + myString = null; + } + + public int getLength() { + return myCount; + } + + public CharSequence getCharArray() { + if (myOriginalSequence != null) return myOriginalSequence; + return new CharArrayCharSequence(myArray, 0, myCount); + } + + public String toString() { + if (myString == null) { + if (myOriginalSequence != null) { + myString = myOriginalSequence.toString(); + } + else { + myString = new String(myArray, 0, myCount); + } + } + return myString; + } + + public char charAt(int i) { + if (i < 0 || i >= myCount) { + throw new IndexOutOfBoundsException("Wrong offset: " + i); + } + return myArray[i]; + } + + public CharSequence substring(int start, int end) { + if (myOriginalSequence != null) { + return myOriginalSequence.subSequence(start, end); + } + return new String(myArray, start, end - start); + } + + private char[] relocateArray(char[] array, int index) { + if (index < array.length) { + return array; + } + + int newArraySize = array.length; + if (newArraySize == 0) { + newArraySize = 16; + } + while (newArraySize <= index) { + newArraySize = (newArraySize * 120) / 100 + 1; + } + char[] newArray = new char[newArraySize]; + System.arraycopy(array, 0, newArray, 0, array.length); + return newArray; + } + } +//------------------ End of class CharArray --------------------------------------------- + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentMarkupModelManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentMarkupModelManager.java new file mode 100644 index 00000000000..46962604b03 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/DocumentMarkupModelManager.java @@ -0,0 +1,65 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.WeakHashMap; + +import java.util.Iterator; +import java.util.Set; + +/** + * @author max + */ +public class DocumentMarkupModelManager implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.DocumentMarkupModelManager"); + + private WeakHashMap myDocumentSet = new WeakHashMap(); + private Project myProject; + private boolean myIsDisposed = false; + + public static DocumentMarkupModelManager getInstance(Project project) { + return project.getComponent(DocumentMarkupModelManager.class); + } + + public DocumentMarkupModelManager(Project project) { + myProject = project; + } + + public void projectOpened() { + } + + public void projectClosed() { + cleanup(); + } + + public void registerDocument(DocumentImpl doc) { + LOG.assertTrue(!myIsDisposed); + myDocumentSet.put(doc, ""); + } + + public String getComponentName() { + return "DocumentMarkupModelManager"; + } + + public boolean isDisposed() { + return myIsDisposed; + } + + public void initComponent() { } + + public void disposeComponent() { + cleanup(); + } + + private void cleanup() { + if (!myIsDisposed) { + myIsDisposed = true; + Set docs = myDocumentSet.keySet(); + for(Iterator iterator = docs.iterator(); iterator.hasNext(); ) { + DocumentImpl doc = (DocumentImpl)iterator.next(); + doc.removeMarkupModel(myProject); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorActionManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorActionManagerImpl.java new file mode 100644 index 00000000000..5d57d0eb6c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorActionManagerImpl.java @@ -0,0 +1,57 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.editor.ReadOnlyFragmentModificationException; +import com.intellij.openapi.editor.actionSystem.*; +import com.intellij.openapi.ui.Messages; + +public class EditorActionManagerImpl extends EditorActionManager implements ApplicationComponent { + private TypedAction myTypedAction = new TypedAction(); + private ReadonlyFragmentModificationHandler myReadonlyFragmentsHandler = new DefaultReadOnlyFragmentModificationHandler(); + private ActionManager myActionManager; + + public EditorActionManagerImpl(ActionManager actionManager) { + myActionManager = actionManager; + } + + public EditorActionHandler getActionHandler(String actionId) { + return ((EditorAction) myActionManager.getAction(actionId)).getHandler(); + } + + public EditorActionHandler setActionHandler(String actionId, EditorActionHandler handler) { + EditorAction action = ((EditorAction) myActionManager.getAction(actionId)); + return action.setupHandler(handler); + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public TypedAction getTypedAction() { + return myTypedAction; + } + + public ReadonlyFragmentModificationHandler getReadonlyFragmentModificationHandler() { + return myReadonlyFragmentsHandler; + } + + public ReadonlyFragmentModificationHandler setReadonlyFragmentModificationHandler(ReadonlyFragmentModificationHandler handler) { + ReadonlyFragmentModificationHandler oldHandler = myReadonlyFragmentsHandler; + myReadonlyFragmentsHandler = handler; + return oldHandler; + } + + + public String getComponentName() { + return "EditorActionManager"; + } + + private static class DefaultReadOnlyFragmentModificationHandler implements ReadonlyFragmentModificationHandler { + public void handle(ReadOnlyFragmentModificationException e) { + Messages.showErrorDialog("Unable to perform an action since it changes read-only fragments of the current document", "Guarded Block Modification Attempt"); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorComponentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorComponentImpl.java new file mode 100644 index 00000000000..990216fd542 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorComponentImpl.java @@ -0,0 +1,152 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.ApplicationImpl; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.InputMethodEvent; +import java.awt.im.InputMethodRequests; + +/** + * + */ +public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider { + private EditorImpl myEditor; + + public EditorComponentImpl(EditorImpl editor) { + myEditor = editor; + enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK); + enableInputMethods(true); + setFocusCycleRoot(true); + setOpaque(true); + } + + public EditorImpl getEditor() { + return myEditor; + } + + public Object getData(String dataId) { + if (myEditor.isRendererMode()) return null; + + if (DataConstants.EDITOR.equals(dataId)) { + return myEditor; + } + else if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return myEditor.getDeleteProvider(); + } + else if (DataConstantsEx.CUT_PROVIDER.equals(dataId)) { + return myEditor.getCutProvider(); + } + else if (DataConstantsEx.COPY_PROVIDER.equals(dataId)) { + return myEditor.getCopyProvider(); + } + else if (DataConstantsEx.PASTE_PROVIDER.equals(dataId)) { + return myEditor.getPasteProvider(); + } + + return null; + } + + public Dimension getPreferredSize() { + return myEditor.getPreferredSize(); + } + + protected void processInputMethodEvent(InputMethodEvent e) { + super.processInputMethodEvent(e); + if (!e.isConsumed()) { + switch (e.getID()) { + case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: + myEditor.replaceInputMethodText(e); + // No breaks over here. + + case InputMethodEvent.CARET_POSITION_CHANGED: + myEditor.inputMethodCaretPositionChanged(e); + break; + } + e.consume(); + } + } + + public InputMethodRequests getInputMethodRequests() { + return myEditor.getInputMethodRequests(); + } + + public void paintComponent(Graphics g) { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart(); + + try { + Graphics2D g2d = (Graphics2D)g; + UISettings uiSettings = UISettings.getInstance(); + if (uiSettings.ANTIALIASING_IN_EDITOR) { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + else { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + } + myEditor.paint(g); + } + finally { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish(); + } + } + + public void repaintEditorComponent() { + repaint(); + } + + public void repaintEditorComponent(int x, int y, int width, int height) { + repaint(x, y, width, height); + } + + //--implementation of Scrollable interface-------------------------------------- + public Dimension getPreferredScrollableViewportSize() { + return myEditor.getPreferredSize(); + } + + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.VERTICAL) { + return myEditor.getLineHeight(); + } + else { // if orientation == SwingConstants.HORIZONTAL + return myEditor.getSpaceWidth(Font.PLAIN); + } + } + + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.VERTICAL) { + int lineHeight = myEditor.getLineHeight(); + if (direction > 0) { + int lineNumber = (visibleRect.y + visibleRect.height) / lineHeight; + return lineHeight * lineNumber - visibleRect.y; + } + else { + int lineNumber = (visibleRect.y - visibleRect.height) / lineHeight; + return visibleRect.y - lineHeight * lineNumber; + } + } + else { // if orientation == SwingConstants.HORIZONTAL + return visibleRect.width; + } + } + + public boolean getScrollableTracksViewportWidth() { + if (getParent() instanceof JViewport) { + return getParent().getWidth() > getPreferredSize().width; + } + return false; + } + + public boolean getScrollableTracksViewportHeight() { + if (getParent() instanceof JViewport) { + return getParent().getHeight() > getPreferredSize().height; + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorFactoryImpl.java new file mode 100644 index 00000000000..2aa468d0c6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorFactoryImpl.java @@ -0,0 +1,163 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ModalityStateListener; +import com.intellij.openapi.application.impl.LaterInvocatorEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.EditorEventMulticaster; +import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.editor.event.EditorFactoryListener; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.impl.event.EditorEventMulticasterImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.util.EventDispatcher; +import com.intellij.util.text.CharArrayCharSequence; + +import javax.swing.*; +import java.util.ArrayList; + +public class EditorFactoryImpl extends EditorFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorFactoryImpl"); + + private final EditorEventMulticasterImpl myEditorEventMulticaster = new EditorEventMulticasterImpl(); + + private EventDispatcher myEditorFactoryEventDispatcher = EventDispatcher.create(EditorFactoryListener.class); + + private ArrayList myEditors = new ArrayList(); + + public EditorFactoryImpl(ProjectManager projectManager) { + LaterInvocatorEx.addModalityStateListener( + new ModalityStateListener() { + public void beforeModalityStateChanged() { + for (int i = 0; i < myEditors.size(); i++) { + Editor editor = myEditors.get(i); + ((EditorImpl)editor).beforeModalityStateChanged(); + } + } + } + ); + + projectManager.addProjectManagerListener(new ProjectManagerAdapter() { + public void projectClosed(final Project project) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + validateEditorsAreReleased(project); + } + }); + } + }); + } + + public String getComponentName() { + return "EditorFactory"; + } + + public void initComponent() { } + + public void validateEditorsAreReleased(Project project) { + for (int i = 0; i < myEditors.size(); i++) { + Editor editor = myEditors.get(i); + if (editor.getProject() == project) { + LOG.error("Editor for the document with the following text hasn't been released:\n" + editor.getDocument().getText()); + } + } + } + + public void disposeComponent() { + } + + public Document createDocument(char[] text) { + return createDocument(new CharArrayCharSequence(text)); + } + + public Document createDocument(CharSequence text) { + DocumentImpl document = new DocumentImpl(text); + myEditorEventMulticaster.registerDocument(document); + return document; + } + + public void refreshAllEditors() { + Editor[] editors = getAllEditors(); + for (int i = 0; i < editors.length; i++) { + EditorEx editor = (EditorEx)editors[i]; + editor.reinitSettings(); + } + } + + public Editor createEditor(Document document) { + return createEditor(document, false, null); + } + + public Editor createViewer(Document document) { + return createEditor(document, true, null); + } + + public Editor createEditor(Document document, Project project) { + return createEditor(document, false, project); + } + + public Editor createViewer(Document document, Project project) { + return createEditor(document, true, project); + } + + private Editor createEditor(Document document, boolean isViewer, Project project) { + EditorImpl editor = new EditorImpl(document, isViewer, project); + myEditors.add(editor); + myEditorEventMulticaster.registerEditor(editor); + myEditorFactoryEventDispatcher.getMulticaster().editorCreated(new EditorFactoryEvent(this, editor)); + + if (LOG.isDebugEnabled()) { + LOG.debug("number of Editor's:" + myEditors.size()); + //Thread.dumpStack(); + } + + return editor; + } + + public void releaseEditor(Editor editor) { + ((EditorImpl)editor).release(); + myEditors.remove(editor); + myEditorFactoryEventDispatcher.getMulticaster().editorReleased(new EditorFactoryEvent(this, editor)); + + if (LOG.isDebugEnabled()) { + LOG.debug("number of Editor's:" + myEditors.size()); + //Thread.dumpStack(); + } + } + + public Editor[] getEditors(Document document, Project project) { + ArrayList list = new ArrayList(); + for (int i = 0; i < myEditors.size(); i++) { + Editor editor = myEditors.get(i); + Project project1 = editor.getProject(); + if (editor.getDocument().equals(document) && (project == null || project1 == null || project1.equals(project))) { + list.add(editor); + } + } + return list.toArray(new Editor[list.size()]); + } + + public Editor[] getEditors(Document document) { + return getEditors(document, null); + } + + public Editor[] getAllEditors() { + return myEditors.toArray(new Editor[myEditors.size()]); + } + + public void addEditorFactoryListener(EditorFactoryListener listener) { + myEditorFactoryEventDispatcher.addListener(listener); + } + + public void removeEditorFactoryListener(EditorFactoryListener listener) { + myEditorFactoryEventDispatcher.removeListener(listener); + } + + public EditorEventMulticaster getEventMulticaster() { + return myEditorEventMulticaster; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java new file mode 100644 index 00000000000..54d9ffed9c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -0,0 +1,1169 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 6, 2002 + * Time: 8:37:03 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.TooltipController; +import com.intellij.codeInsight.hint.TooltipGroup; +import com.intellij.ide.ui.LafManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.ApplicationImpl; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.TextAnnotationGutterProvider; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.event.EditorMouseEventArea; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorGutterComponentEx; +import com.intellij.openapi.editor.ex.FoldingModelEx; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.diagnostic.Logger; +import gnu.trove.TIntArrayList; +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntProcedure; +import gnu.trove.TObjectProcedure; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; +import java.util.Iterator; + +class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorGutterComponentImpl"); + private static final int START_ICON_AREA_WIDTH = 15; + private static final int FREE_PAINTERS_AREA_WIDTH = 3; + private static final int GAP_BETWEEN_ICONS = 3; + private static final TooltipGroup GUTTER_TOOLTIP_GROUP = new TooltipGroup("GUTTER_TOOLTIP_GROUP", 0); + + private EditorImpl myEditor; + private int myLineMarkerAreaWidth = START_ICON_AREA_WIDTH + FREE_PAINTERS_AREA_WIDTH; + private int myIconsAreaWidth = START_ICON_AREA_WIDTH; + private int myLineNumberAreaWidth = 0; + private FoldRegion myActiveFoldRegion; + private boolean myPopupInvokedOnPressed; + private int myTextAnnotationGuttersSize = 0; + private TIntArrayList myTextAnnotationGutterSizes = new TIntArrayList(); + private ArrayList myTextAnnotationGutters = new ArrayList(); + private static final int GAP_BETWEEN_ANNOTATIONS = 6; + private Color myBackgroundColor = null; + private GutterDraggableObject myGutterDraggableObject; + private DragSource myDragSource = DragSource.getDefaultDragSource(); + + { + new DropTarget(this, new MyDropTargetListener()); + } + + + public EditorGutterComponentImpl(EditorImpl editor) { + myEditor = editor; + myDragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new MyDragGestureListener()); + } + + public Dimension getPreferredSize() { + int w = getLineNumberAreaWidth() + getLineMarkerAreaWidth() + getFoldingAreaWidth() + getAnnotationsAreaWidth(); + return new Dimension(w, myEditor.getPreferredSize().height); + } + + protected void setUI(ComponentUI newUI) { + super.setUI(newUI); + myBackgroundColor = null; + } + + public void updateUI() { + super.updateUI(); + myBackgroundColor = null; + } + + public void paint(Graphics g) { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart(); + + try { + Rectangle clip = g.getClipBounds(); + if (clip.height < 0) return; + + final Graphics2D g2 = (Graphics2D)g; + final AffineTransform old = g2.getTransform(); + + if (isMirrored()) { + final AffineTransform transform = new AffineTransform(old); + transform.scale(-1, 1); + transform.translate(-getWidth(), 0); + g2.setTransform(transform); + } + + paintLineNumbers(g, clip); + + Object antialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + + try { + paintAnnotations(g, clip); + paintFoldingBackground(g); + paintLineMarkers(g, clip); + paintFoldingTree(g, clip); + } + finally { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialiasing); + } + + g2.setTransform(old); + } + finally { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish(); + } + } + + private void paintAnnotations(Graphics g, Rectangle clip) { + g.setColor(getBackground()); + g.fillRect(getAnnotationsAreaOffset(), clip.y, getAnnotationsAreaWidth(), clip.height); + + int x = getAnnotationsAreaOffset(); + + Color color = myEditor.getColorsScheme().getColor(EditorColors.ANNOTATIONS_COLOR); + g.setColor(color != null ? color : Color.blue); + g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN)); + + for (int i = 0; i < myTextAnnotationGutters.size(); i++) { + TextAnnotationGutterProvider gutterProvider = myTextAnnotationGutters.get(i); + int lineHeight = myEditor.getLineHeight(); + int startLineNumber = clip.y / lineHeight; + int endLineNumber = (clip.y + clip.height) / lineHeight + 1; + int lastLine = myEditor.logicalToVisualPosition( + new LogicalPosition(Math.max(0, myEditor.getDocument().getLineCount() - 1), 0)) + .line; + endLineNumber = Math.min(endLineNumber, lastLine + 1); + if (startLineNumber >= endLineNumber) { + return; + } + + for (int j = startLineNumber; j < endLineNumber; j++) { + int logLine = myEditor.visualToLogicalPosition(new VisualPosition(j, 0)).line; + String s = gutterProvider.getLineText(logLine, myEditor); + g.drawString(s, + x, + (j + 1) * lineHeight - myEditor.getDescent()); + } + + x += myTextAnnotationGutterSizes.get(i); + } + } + + private void paintFoldingTree(Graphics g, Rectangle clip) { + if (isFoldingOutlineShown()) { + paintFoldingTree((Graphics2D)g); + } + else { + g.setColor(Color.white); + int x = getWhitespaceSeparatorOffset() - 1; + drawDottedLine((Graphics2D)g, x, clip.y, clip.y + clip.height); + } + } + + private void paintLineMarkers(Graphics g, Rectangle clip) { + if (isLineMarkersShown()) { + g.setColor(getBackground()); + g.fillRect(getLineMarkerAreaOffset(), clip.y, getLineMarkerAreaWidth(), clip.height); + paintGutterRenderers(g); + } + } + + private void paintLineNumbers(Graphics g, Rectangle clip) { + if (isLineNumbersShown()) { + g.setColor(getBackground()); + g.fillRect(getLineNumberAreaOffset(), clip.y, getLineNumberAreaWidth(), clip.height); + g.setColor(Color.white); + int x = getLineNumberAreaOffset() + getLineNumberAreaWidth() - 2; + g.drawLine(x, clip.y, x, clip.y + clip.height); + paintLineNumbers(g); + } + } + + public Color getBackground() { + if (myBackgroundColor == null) { + LafManager lafManager = LafManager.getInstance(); + if (lafManager != null && lafManager.isUnderAquaLookAndFeel()) { + myBackgroundColor = new Color(0xF0F0F0); + } + else { + myBackgroundColor = super.getBackground(); + } + } + return myBackgroundColor; + } + + private void paintLineNumbers(Graphics g) { + if (!isLineNumbersShown()) { + return; + } + Rectangle clip = g.getClipBounds(); + int lineHeight = myEditor.getLineHeight(); + int startLineNumber = clip.y / lineHeight; + int endLineNumber = (clip.y + clip.height) / lineHeight + 1; + int lastLine = myEditor.logicalToVisualPosition( + new LogicalPosition(Math.max(0, myEditor.getDocument().getLineCount() - 1), 0)) + .line; + endLineNumber = Math.min(endLineNumber, lastLine + 1); + if (startLineNumber >= endLineNumber) { + return; + } + Color color = myEditor.getColorsScheme().getColor(EditorColors.LINE_NUMBERS_COLOR); + g.setColor(color != null ? color : Color.blue); + g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN)); + + Graphics2D g2 = (Graphics2D)g; + AffineTransform old = g2.getTransform(); + + if (isMirrored()) { + AffineTransform originalTransform = new AffineTransform(old); + originalTransform.scale(-1, 1); + originalTransform.translate(-getLineNumberAreaWidth() + 2, 0); + g2.setTransform(originalTransform); + } + + for (int i = startLineNumber; i < endLineNumber; i++) { + int logLine = myEditor.visualToLogicalPosition(new VisualPosition(i, 0)).line; + String s = "" + (logLine + 1); + g.drawString(s, + getLineNumberAreaOffset() + getLineNumberAreaWidth() - + myEditor.getFontMetrics(Font.PLAIN).stringWidth(s) - + 4, + (i + 1) * lineHeight - myEditor.getDescent()); + } + + g2.setTransform(old); + } + + private interface RangeHighlighterProcessor { + void process(RangeHighlighter highlighter); + } + + private void processRangeHighlighters(RangeHighlighterProcessor p, int startOffset, int endOffset) { + final MarkupModelImpl docMarkup = (MarkupModelImpl)myEditor.getDocument().getMarkupModel(myEditor.myProject); + Iterator docHighlighters = docMarkup == null ? null : docMarkup.getHighlighterList().getHighlighterIterator(); + Iterator editorHighlighters = ((MarkupModelImpl)myEditor.getMarkupModel()).getHighlighterList() + .getHighlighterIterator(); + + RangeHighlighterImpl lastDocHighlighter = null; + RangeHighlighterImpl lastEditorHighlighter = null; + + while (true) { + if (lastDocHighlighter == null && docHighlighters != null && docHighlighters.hasNext()) { + lastDocHighlighter = (RangeHighlighterImpl)docHighlighters.next(); + if (!lastDocHighlighter.isValid() || lastDocHighlighter.getAffectedAreaStartOffset() > endOffset) { + lastDocHighlighter = null; + continue; + } + if (lastDocHighlighter.getAffectedAreaEndOffset() < startOffset) { + lastDocHighlighter = null; + //docHighlighters = null; + continue; + } + } + + if (lastEditorHighlighter == null && editorHighlighters != null && editorHighlighters.hasNext()) { + lastEditorHighlighter = (RangeHighlighterImpl)editorHighlighters.next(); + if (!lastEditorHighlighter.isValid() || lastEditorHighlighter.getAffectedAreaStartOffset() > endOffset) { + lastEditorHighlighter = null; + continue; + } + if (lastEditorHighlighter.getAffectedAreaEndOffset() < startOffset) { + lastEditorHighlighter = null; + //editorHighlighters = null; + continue; + } + } + + if (lastDocHighlighter == null && lastEditorHighlighter == null) return; + + final RangeHighlighterImpl lowerHighlighter; + + if (less(lastDocHighlighter, lastEditorHighlighter)) { + lowerHighlighter = lastDocHighlighter; + lastDocHighlighter = null; + } + else { + lowerHighlighter = lastEditorHighlighter; + lastEditorHighlighter = null; + } + + if (!lowerHighlighter.isValid()) continue; + + int startLineIndex = lowerHighlighter.getDocument().getLineNumber(startOffset); + if (startLineIndex < 0 || startLineIndex >= myEditor.getDocument().getLineCount()) continue; + + int endLineIndex = lowerHighlighter.getDocument().getLineNumber(endOffset); + if (endLineIndex < 0 || endLineIndex >= myEditor.getDocument().getLineCount()) continue; + + if (lowerHighlighter.getEditorFilter().avaliableIn(myEditor)) { + p.process(lowerHighlighter); + } + } + } + + private boolean less(RangeHighlighter h1, RangeHighlighter h2) { + if (h1 == null) return false; + if (h2 == null) return true; + + return h1.getStartOffset() < h2.getStartOffset(); + } + + public void revalidateMarkup() { + updateSize(); + } + + public void updateSize() { + int oldIconsWidth = myLineMarkerAreaWidth; + int oldAnnotationsWidth = myTextAnnotationGuttersSize; + calcIconAreaWidth(); + calcAnnotationsSize(); + if (oldIconsWidth != myLineMarkerAreaWidth || oldAnnotationsWidth != myTextAnnotationGuttersSize) { + revalidate(); + } + else { + repaint(); + } + } + + private void calcAnnotationsSize() { + myTextAnnotationGuttersSize = 0; + final FontMetrics fontMetrics = myEditor.getFontMetrics(Font.PLAIN); + final int lineCount = myEditor.getDocument().getLineCount(); + for (int j = 0; j < myTextAnnotationGutters.size(); j++) { + TextAnnotationGutterProvider gutterProvider = myTextAnnotationGutters.get(j); + int gutterSize = 0; + for (int i = 0; i < lineCount; i++) { + gutterSize = Math.max(gutterSize, + fontMetrics.stringWidth(gutterProvider.getLineText(i, myEditor))); + } + if (gutterSize > 0) gutterSize += GAP_BETWEEN_ANNOTATIONS; + myTextAnnotationGutterSizes.set(j, gutterSize); + myTextAnnotationGuttersSize += gutterSize; + } + } + + private TIntObjectHashMap> myLineToGutterRenderers; + + private void calcIconAreaWidth() { + myLineToGutterRenderers = new TIntObjectHashMap>(); + + processRangeHighlighters(new RangeHighlighterProcessor() { + public void process(RangeHighlighter highlighter) { + GutterIconRenderer renderer = highlighter.getGutterIconRenderer(); + if (renderer == null || !highlighter.getEditorFilter().avaliableIn(myEditor)) return; + + int startOffset = highlighter.getStartOffset(); + int line = myEditor.getDocument().getLineNumber(startOffset); + + ArrayList renderers = myLineToGutterRenderers.get(line); + if (renderers == null) { + renderers = new ArrayList(); + myLineToGutterRenderers.put(line, renderers); + } + + renderers.add(renderer); + } + }, 0, myEditor.getDocument().getTextLength()); + + myIconsAreaWidth = START_ICON_AREA_WIDTH; + + myLineToGutterRenderers.forEachValue(new TObjectProcedure() { + public boolean execute(Object object) { + ArrayList renderers = (ArrayList)object; + int width = 1; + for (int i = 0; i < renderers.size(); i++) { + GutterIconRenderer renderer = renderers.get(i); + width += renderer.getIcon().getIconWidth(); + if (i > 0) width += GAP_BETWEEN_ICONS; + } + if (myIconsAreaWidth < width) { + myIconsAreaWidth = width; + } + return true; + } + }); + + myLineMarkerAreaWidth = myIconsAreaWidth + FREE_PAINTERS_AREA_WIDTH + + (isFoldingOutlineShown() ? 0 : getFoldingAnchorWidth() / 2); + } + + private void paintGutterRenderers(final Graphics g) { + Rectangle clip = g.getClipBounds(); + + int firstVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y - myEditor.getLineHeight()))); + int lastVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y + clip.height + myEditor.getLineHeight()))); + + Graphics2D g2 = (Graphics2D)g; + + Object antialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + try { + processRangeHighlighters(new RangeHighlighterProcessor() { + public void process(RangeHighlighter highlighter) { + paintLineMarkerRenderer(highlighter, g); + } + }, firstVisibleOffset, lastVisibleOffset); + } + finally { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialiasing); + } + + int firstVisibleLine = myEditor.getDocument().getLineNumber(firstVisibleOffset); + int lastVisibleLine = myEditor.getDocument().getLineNumber(lastVisibleOffset); + paintIcons(firstVisibleLine, lastVisibleLine, g); + } + + private void paintIcons(final int firstVisibleLine, final int lastVisibleLine, final Graphics g) { + myLineToGutterRenderers.forEachKey(new TIntProcedure() { + public boolean execute(int line) { + if (firstVisibleLine > line || lastVisibleLine < line) return true; + int startOffset = myEditor.getDocument().getLineStartOffset(line); + if (myEditor.getFoldingModel().isOffsetCollapsed(startOffset)) return true; + ArrayList renderers = myLineToGutterRenderers.get(line); + paintIconRow(line, renderers, g); + return true; + } + }); + } + + private void paintIconRow(int line, ArrayList row, final Graphics g) { + processIconsRow(line, row, new LineGutterIconRendererProcessor() { + public void process(int x, int y, GutterIconRenderer renderer) { + renderer.getIcon().paintIcon(EditorGutterComponentImpl.this, g, x, y); + } + }); + } + + private void paintLineMarkerRenderer(RangeHighlighter highlighter, Graphics g) { + Rectangle rect = getLineRendererRect(highlighter); + + if (rect != null) { + highlighter.getLineMarkerRenderer().paint(myEditor, g, rect); + } + } + + private Rectangle getLineRendererRect(RangeHighlighter highlighter) { + LineMarkerRenderer renderer = highlighter.getLineMarkerRenderer(); + if (renderer == null) return null; + + int startOffset = highlighter.getStartOffset(); + int endOffset = highlighter.getEndOffset(); + if (myEditor.getFoldingModel().isOffsetCollapsed(startOffset) && + myEditor.getFoldingModel().isOffsetCollapsed(endOffset)) { + return null; + } + + int startY = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset)).y; + int endY = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset)).y; + + int height = endY - startY; + int w = FREE_PAINTERS_AREA_WIDTH; + int x = getLineMarkerAreaOffset() + myIconsAreaWidth; + return new Rectangle(x, startY, w, height); + } + + private interface LineGutterIconRendererProcessor { + void process(int x, int y, GutterIconRenderer renderer); + } + + private void processIconsRow(int line, ArrayList row, LineGutterIconRendererProcessor processor) { + int middleCount = 0; + int middleSize = 0; + + int y = myEditor.logicalPositionToXY(new LogicalPosition(line, 0)).y; + + int x = getLineMarkerAreaOffset() + 1; + for (int i = 0; i < row.size(); i++) { + GutterIconRenderer r = row.get(i); + Icon icon = r.getIcon(); + if (r.getAlignment() == GutterIconRenderer.Alignment.LEFT) { + processor.process(x, y + getTextAlignmentShift(icon), r); + x += icon.getIconWidth() + GAP_BETWEEN_ICONS; + } + else { + if (r.getAlignment() == GutterIconRenderer.Alignment.CENTER) { + middleCount++; + middleSize += icon.getIconWidth() + GAP_BETWEEN_ICONS; + } + } + } + + int leftSize = x - getLineMarkerAreaOffset(); + + x = getLineMarkerAreaOffset() + myIconsAreaWidth; + for (int i = 0; i < row.size(); i++) { + GutterIconRenderer r = row.get(i); + if (r.getAlignment() == GutterIconRenderer.Alignment.RIGHT) { + Icon icon = r.getIcon(); + x -= icon.getIconWidth(); + processor.process(x, y + getTextAlignmentShift(icon), r); + x -= GAP_BETWEEN_ICONS; + } + } + + int rightSize = myIconsAreaWidth + getLineMarkerAreaOffset() - x; + + if (middleCount > 0) { + middleSize -= GAP_BETWEEN_ICONS; + x = getLineMarkerAreaOffset() + leftSize + (myIconsAreaWidth - leftSize - rightSize - middleSize) / 2; + for (int i = 0; i < row.size(); i++) { + GutterIconRenderer r = row.get(i); + if (r.getAlignment() == GutterIconRenderer.Alignment.CENTER) { + Icon icon = r.getIcon(); + processor.process(x, y + getTextAlignmentShift(icon), r); + x += icon.getIconWidth() + GAP_BETWEEN_ICONS; + } + } + } + } + + private int getTextAlignmentShift(Icon icon) { + return myEditor.getLineHeight() - myEditor.getDescent() - icon.getIconHeight(); + } + + public Color getFoldingColor(boolean isActive) { + ColorKey key = isActive ? EditorColors.SELECTED_FOLDING_TREE_COLOR : EditorColors.FOLDING_TREE_COLOR; + Color color = myEditor.getColorsScheme().getColor(key); + return color != null ? color : Color.black; + } + + public void registerTextAnnotation(TextAnnotationGutterProvider provider) { + myTextAnnotationGutters.add(provider); + myTextAnnotationGutterSizes.add(0); + updateSize(); + } + + private VisualPosition offsetToLineStartPosition(int offset) { + int line = myEditor.getDocument().getLineNumber(offset); + return myEditor.logicalToVisualPosition(new LogicalPosition(line, 0)); + } + + private void paintFoldingTree(Graphics2D g) { + Rectangle clip = g.getClipBounds(); + + int anchorX = getFoldingAreaOffset(); + int width = getFoldingAnchorWidth(); + + FoldRegion[] visibleFoldRegions = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchVisible(); + + int firstVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y - myEditor.getLineHeight()))); + int lastVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y + clip.height + myEditor.getLineHeight()))); + + for (int j = 0; j < visibleFoldRegions.length; j++) { + FoldRegion visibleFoldRegion = visibleFoldRegions[j]; + if (visibleFoldRegion.getStartOffset() > lastVisibleOffset) continue; + if (visibleFoldRegion.getEndOffset() < firstVisibleOffset) continue; + drawAnchor(visibleFoldRegion, width, clip, g, anchorX, false, false); + } + + if (myActiveFoldRegion != null) { + drawAnchor(myActiveFoldRegion, width, clip, g, anchorX, true, true); + drawAnchor(myActiveFoldRegion, width, clip, g, anchorX, true, false); + } + } + + private void paintFoldingBackground(Graphics g) { + Rectangle clip = g.getClipBounds(); + int lineX = getWhitespaceSeparatorOffset(); + g.setColor(getBackground()); + g.fillRect(getFoldingAreaOffset(), clip.y, getFoldingAreaWidth(), clip.height); + + g.setColor(myEditor.getBackroundColor()); + g.fillRect(lineX, clip.y, getFoldingAreaWidth(), clip.height); + + paintFoldingBoxBacgrounds((Graphics2D)g); + } + + private void paintFoldingBoxBacgrounds(Graphics2D g) { + if (!isFoldingOutlineShown()) return; + Rectangle clip = g.getClipBounds(); + + drawDottedLine(g, getWhitespaceSeparatorOffset(), clip.y, clip.y + clip.height); + + int anchorX = getFoldingAreaOffset(); + int width = getFoldingAnchorWidth(); + + FoldRegion[] visibleFoldRegions = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchVisible(); + + int firstVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y - myEditor.getLineHeight()))); + int lastVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y + clip.height + myEditor.getLineHeight()))); + + if (myActiveFoldRegion != null) { + drawFoldingLines(myActiveFoldRegion, clip, width, anchorX, g); + } + + for (int j = 0; j < visibleFoldRegions.length; j++) { + FoldRegion visibleFoldRegion = visibleFoldRegions[j]; + if (visibleFoldRegion.getStartOffset() > lastVisibleOffset) continue; + if (visibleFoldRegion.getEndOffset() < firstVisibleOffset) continue; + drawAnchor(visibleFoldRegion, width, clip, g, anchorX, false, true); + } + } + + public int getWhitespaceSeparatorOffset() { + return getFoldingAreaOffset() + getFoldingAnchorWidth() / 2; + } + + public void setActiveFoldRegion(FoldRegion activeFoldRegion) { + if (myActiveFoldRegion != activeFoldRegion) { + myActiveFoldRegion = activeFoldRegion; + repaint(); + } + } + + public int getHeadCenterY(FoldRegion foldRange) { + int width = getFoldingAnchorWidth(); + VisualPosition foldStart = offsetToLineStartPosition(foldRange.getStartOffset()); + int y = myEditor.visibleLineNumberToYPosition(foldStart.line) + myEditor.getLineHeight() - myEditor.getDescent() - + width / 2; + + return y; + } + + private void drawAnchor(FoldRegion foldRange, int width, Rectangle clip, Graphics2D g, + int anchorX, boolean active, boolean paintBackground) { + if (foldRange.isValid()) { + VisualPosition foldStart = offsetToLineStartPosition(foldRange.getStartOffset()); + int y = myEditor.visibleLineNumberToYPosition(foldStart.line) + myEditor.getLineHeight() - myEditor.getDescent() - + width; + int height = width + 2; + + if (!foldRange.isExpanded()) { + if (y <= clip.y + clip.height && y + height >= clip.y) { + drawSquareWithPlus(g, anchorX, y, width, active, paintBackground); + } + } + else { + VisualPosition foldEnd = offsetToLineStartPosition(foldRange.getEndOffset()); + if (foldStart.line == foldEnd.line) { + drawSquareWithMinus(g, anchorX, y, width, active, paintBackground); + } + else { + int endY = myEditor.visibleLineNumberToYPosition(foldEnd.line) + myEditor.getLineHeight() - + myEditor.getDescent(); + + if (y <= clip.y + clip.height && y + height >= clip.y) { + drawDirectedBox(g, anchorX, y, width, height, width - 2, active, paintBackground); + } + + if (endY - height <= clip.y + clip.height && endY >= clip.y) { + drawDirectedBox(g, anchorX, endY, width, -height, -width + 2, active, paintBackground); + } + } + } + } + } + + private void drawDirectedBox(Graphics2D g, + int anchorX, + int y, + int width, + int height, + int baseHeight, + boolean active, boolean paintBackground) { + Object antialiasing = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + if (SystemInfo.isMac && SystemInfo.JAVA_VERSION.startsWith("1.4.1")) { + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + } + + try { + int[] xPoints = new int[]{anchorX, anchorX + width, anchorX + width, anchorX + width / 2, anchorX}; + int[] yPoints = new int[]{y, y, y + baseHeight, y + height, y + baseHeight}; + + if (paintBackground) { + g.setColor(myEditor.getBackroundColor()); + + g.fillPolygon(xPoints, yPoints, 5); + } + else { + g.setColor(getFoldingColor(active)); + g.drawPolygon(xPoints, yPoints, 5); + + //Minus + int minusHeight = y + baseHeight / 2 + (height - baseHeight) / 4; + g.drawLine(anchorX + 2, minusHeight, anchorX + width - 2, minusHeight); + } + } + finally { + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialiasing); + } + } + + private void drawSquareWithPlus(Graphics2D g, + int anchorX, + int y, + int width, + boolean active, + boolean paintBackground) { + drawSquareWithMinus(g, anchorX, y, width, active, paintBackground); + + g.drawLine(anchorX + width / 2, y + 2, anchorX + width / 2, y + width - 2); + } + + private void drawSquareWithMinus(Graphics2D g, + int anchorX, + int y, + int width, + boolean active, + boolean paintBackground) { + if (paintBackground) { + g.setColor(myEditor.getBackroundColor()); + g.fillRect(anchorX, y, width, width); + } + else { + g.setColor(getFoldingColor(active)); + g.drawRect(anchorX, y, width, width); + + // Draw plus + if (!active) g.setColor(getFoldingColor(true)); + g.drawLine(anchorX + 2, y + width / 2, anchorX + width - 2, y + width / 2); + } + } + + private void drawFoldingLines(FoldRegion foldRange, Rectangle clip, int width, int anchorX, Graphics2D g) { + if (foldRange.isExpanded() && foldRange.isValid()) { + VisualPosition foldStart = offsetToLineStartPosition(foldRange.getStartOffset()); + VisualPosition foldEnd = offsetToLineStartPosition(foldRange.getEndOffset()); + int startY = myEditor.visibleLineNumberToYPosition(foldStart.line + 1) - myEditor.getDescent(); + int endY = myEditor.visibleLineNumberToYPosition(foldEnd.line) + myEditor.getLineHeight() - + myEditor.getDescent(); + + if (startY > clip.y + clip.height || endY + 1 + myEditor.getDescent() < clip.y) return; + + int lineX = anchorX + width / 2; + + g.setColor(getFoldingColor(true)); + g.drawLine(lineX, startY, lineX, endY); + } + } + + private void drawDottedLine(Graphics2D g, int lineX, int startY, int endY) { + g.setColor(myEditor.getBackroundColor()); + g.drawLine(lineX, startY, lineX, endY); + + g.setColor(getFoldingColor(false)); + + for (int i = startY / 2 * 2; i < endY; i += 2) { + g.drawRect(lineX, i, 0, 0); + } + } + + private int getFoldingAnchorWidth() { + return Math.min(4, myEditor.getLineHeight() / 2 - 2) * 2; + } + + public int getFoldingAreaOffset() { + return getLineMarkerAreaOffset() + + getLineMarkerAreaWidth(); + } + + public int getFoldingAreaWidth() { + return isFoldingOutlineShown() + ? getFoldingAnchorWidth() + 2 + : isLineNumbersShown() ? getFoldingAnchorWidth() / 2 : 0; + } + + public boolean isLineMarkersShown() { + return myEditor.getSettings().isLineMarkerAreaShown(); + } + + public boolean isLineNumbersShown() { + return myEditor.getSettings().isLineNumbersShown(); + } + + public boolean isFoldingOutlineShown() { + return myEditor.getSettings().isFoldingOutlineShown() && + ((FoldingModelEx)myEditor.getFoldingModel()).isFoldingEnabled(); + } + + public int getLineNumberAreaWidth() { + if (isLineNumbersShown()) { + return myLineNumberAreaWidth; + } + else { + return 0; + } + } + + public int getLineMarkerAreaWidth() { + return isLineMarkersShown() ? myLineMarkerAreaWidth : 0; + } + + public void setLineNumberAreaWidth(int lineNumberAriaWidth) { + myLineNumberAreaWidth = lineNumberAriaWidth; + } + + public int getLineNumberAreaOffset() { + return 0; + } + + public int getAnnotationsAreaOffset() { + return getLineNumberAreaOffset() + getLineNumberAreaWidth(); + } + + public int getAnnotationsAreaWidth() { + return myTextAnnotationGuttersSize; + } + + public int getLineMarkerAreaOffset() { + return getAnnotationsAreaOffset() + getAnnotationsAreaWidth(); + } + + private boolean isMirrored() { + return myEditor.getVerticalScrollbarOrientation() != EditorEx.VERTICAL_SCROLLBAR_RIGHT; + } + + public FoldRegion findFoldingAnchorAt(int x, int y) { + if (!myEditor.getSettings().isFoldingOutlineShown()) return null; + + int anchorX = getFoldingAreaOffset(); + int anchorWidth = getFoldingAnchorWidth(); + + FoldRegion[] visibleRanges = ((FoldingModelImpl)myEditor.getFoldingModel()).fetchVisible(); + for (int i = 0; i < visibleRanges.length; i++) { + FoldRegion foldRange = visibleRanges[i]; + if (rectByFoldOffset(foldRange.getStartOffset(), anchorWidth, anchorX).contains(x, y)) return foldRange; + if (rectByFoldOffset(foldRange.getEndOffset(), anchorWidth, anchorX).contains(x, y)) return foldRange; + } + + return null; + } + + private Rectangle rectByFoldOffset(int offset, int anchorWidth, int anchorX) { + VisualPosition foldStart = offsetToLineStartPosition(offset); + int anchorY = myEditor.visibleLineNumberToYPosition(foldStart.line) + myEditor.getLineHeight() - + myEditor.getDescent() - anchorWidth; + Rectangle rect = new Rectangle(anchorX, anchorY, anchorWidth, anchorWidth); + return rect; + } + + public void mouseDragged(MouseEvent e) { + HintManager.getInstance().getTooltipController().cancelTooltips(); + } + + public void mouseMoved(final MouseEvent e) { + String tooltip = null; + GutterIconRenderer renderer = getGutterRenderer(e); + if (renderer != null) { + tooltip = renderer.getTooltipText(); + if (renderer.isNavigateAction()) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + } + else { + ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e); + if (lineRenderer != null) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + } + + TooltipController controller = HintManager.getInstance().getTooltipController(); + if (tooltip != null && tooltip.length() != 0) { + controller.showTooltipByMouseMove(myEditor, e, tooltip, false, GUTTER_TOOLTIP_GROUP); + } + else { + controller.cancelTooltip(GUTTER_TOOLTIP_GROUP); + } + } + + public void mouseClicked(MouseEvent e) { + if (e.isPopupTrigger()) { + invokePopup(e); + } + } + + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + invokePopup(e); + myPopupInvokedOnPressed = true; + } + } + + public void mouseReleased(final MouseEvent e) { + if (e.isPopupTrigger()) { + invokePopup(e); + return; + } + + if (myPopupInvokedOnPressed) { + myPopupInvokedOnPressed = false; + return; + } + + GutterIconRenderer renderer = getGutterRenderer(e); + AnAction clickAction = null; + if (renderer != null) { + clickAction = (MouseEvent.BUTTON2_MASK & e.getModifiers()) > 0 + ? renderer.getMiddleButtonClickAction() + : renderer.getClickAction(); + } + if (clickAction != null) { + clickAction.actionPerformed(new AnActionEvent(e, myEditor.getDataContext(), "ICON_NAVIGATION", clickAction.getTemplatePresentation(), + ActionManager.getInstance(), + e.getModifiers())); + e.consume(); + repaint(); + } + else { + ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e); + if (lineRenderer != null) { + lineRenderer.doAction(myEditor, e); + } + } + } + + private ActiveGutterRenderer getActiveRendererByMouseEvent(final MouseEvent e) { + final ActiveGutterRenderer[] gutterRenderer = new ActiveGutterRenderer[]{null}; + if (findFoldingAnchorAt(e.getX(), e.getY()) == null) { + if (!e.isConsumed() && + e.getX() > getLineMarkerAreaOffset() + myIconsAreaWidth && + e.getX() <= getWhitespaceSeparatorOffset()) { + Rectangle clip = myEditor.getScrollingModel().getVisibleArea(); + int firstVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y - myEditor.getLineHeight()))); + int lastVisibleOffset = myEditor.logicalPositionToOffset( + myEditor.xyToLogicalPosition(new Point(0, clip.y + clip.height + myEditor.getLineHeight()))); + + processRangeHighlighters(new RangeHighlighterProcessor() { + public void process(RangeHighlighter highlighter) { + if (gutterRenderer[0] != null) return; + Rectangle rect = getLineRendererRect(highlighter); + if (rect == null) return; + + int startY = rect.y; + int endY = startY + rect.height; + if (startY == endY) { + startY -= 4; + endY += 4; + } + + if (startY < e.getY() && e.getY() <= endY) { + if (highlighter.getLineMarkerRenderer() instanceof ActiveGutterRenderer) { + gutterRenderer[0] = (ActiveGutterRenderer)highlighter.getLineMarkerRenderer(); + } + } + } + }, firstVisibleOffset, lastVisibleOffset); + } + } + return gutterRenderer[0]; + } + + public void closeAllAnnotations() { + for (int i = 0; i < myTextAnnotationGutters.size(); i++) { + TextAnnotationGutterProvider provider = myTextAnnotationGutters.get(i); + provider.gutterClosed(); + } + + myTextAnnotationGutters = new ArrayList(); + myTextAnnotationGutterSizes = new TIntArrayList(); + updateSize(); + } + + private class CloseAnnotationsAction extends AnAction { + public CloseAnnotationsAction() { + super("Close Annotations"); + } + + public void actionPerformed(AnActionEvent e) { + closeAllAnnotations(); + } + } + + public void invokePopup(MouseEvent e) { + if (myEditor.getMouseEventArea(e) == EditorMouseEventArea.ANNOTATIONS_AREA) { + DefaultActionGroup actionGroup = new DefaultActionGroup("Annotations", true); + actionGroup.add(new CloseAnnotationsAction()); + JPopupMenu menu = ActionManager.getInstance().createActionPopupMenu("", actionGroup).getComponent(); + menu.show(this, e.getX(), e.getY()); + } + else { + GutterIconRenderer renderer = getGutterRenderer(e); + if (renderer != null) { + ActionGroup actionGroup = renderer.getPopupMenuActions(); + if (actionGroup != null) { + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, + actionGroup); + popupMenu.getComponent().show(this, e.getX(), e.getY()); + e.consume(); + } + } + } + } + + public void mouseEntered(MouseEvent e) { + } + + public void mouseExited(MouseEvent e) { + HintManager.getInstance().getTooltipController().cancelTooltip(GUTTER_TOOLTIP_GROUP); + } + + private GutterIconRenderer getGutterRenderer(final Point p) { + final int ex = convertX((int)p.getX()); + int line = myEditor.xyToLogicalPosition(new Point(0, (int)p.getY())).line; + ArrayList renderers = myLineToGutterRenderers.get(line); + if (renderers == null) return null; + + if (line >= myEditor.getDocument().getLineCount()) return null; + + int startOffset = myEditor.getDocument().getLineStartOffset(line); + if (myEditor.getFoldingModel().isOffsetCollapsed(startOffset)) return null; + + final GutterIconRenderer[] result = new GutterIconRenderer[]{null}; + processIconsRow(line, renderers, new LineGutterIconRendererProcessor() { + public void process(int x, int y, GutterIconRenderer renderer) { + Icon icon = renderer.getIcon(); + if (x <= ex && ex <= x + icon.getIconWidth() && + y <= p.getY() && p.getY() <= y + icon.getIconHeight()) { + result[0] = renderer; + } + } + }); + + return result[0]; + } + + private GutterIconRenderer getGutterRenderer(final MouseEvent e) { + return getGutterRenderer(e.getPoint()); + } + + public int convertX(int x) { + if (!isMirrored()) return x; + return getWidth() - x; + } + + public void dispose() { + for (int j = 0; j < myTextAnnotationGutters.size(); j++) { + TextAnnotationGutterProvider gutterProvider = myTextAnnotationGutters.get(j); + gutterProvider.gutterClosed(); + } + } + + private static final DataFlavor[] FLAVORS; + static { + DataFlavor[] flavors; + try { + final Class aClass = EditorGutterComponentImpl.class; + flavors = new DataFlavor[]{new DataFlavor( + DataFlavor.javaJVMLocalObjectMimeType + ";class=" + aClass.getName(), "GutterTransferable", aClass.getClassLoader() + )}; + } + catch (ClassNotFoundException e) { + LOG.error(e); // should not happen + flavors = new DataFlavor[0]; + } + FLAVORS = flavors; + } + + private class MyDragGestureListener implements DragGestureListener { + public void dragGestureRecognized(DragGestureEvent dge) { + if ((dge.getDragAction() & DnDConstants.ACTION_MOVE) == 0) return; + final GutterIconRenderer renderer = getGutterRenderer(dge.getDragOrigin()); + if (renderer != null) { + final GutterDraggableObject draggableObject = renderer.getDraggableObject(); + if (draggableObject != null) { + try { + myGutterDraggableObject = draggableObject; + final MyDragSourceListener dragSourceListener = new MyDragSourceListener(); + dge.startDrag(DragSource.DefaultMoveNoDrop, new Transferable () { + public DataFlavor[] getTransferDataFlavors() { + return FLAVORS; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + DataFlavor[] flavors = getTransferDataFlavors(); + for (int i = 0; i < flavors.length; i++) { + if (flavor.equals(flavors[i])) { + return true; + } + } + return false; + } + + public Object getTransferData(DataFlavor flavor) { + return null; + } + }, dragSourceListener); + } + catch (InvalidDnDOperationException idoe) {} + } + + } + } + } + + private class MyDragSourceListener implements DragSourceListener{ + public void dragEnter(DragSourceDragEvent dsde) { + setCursor (dsde.getDragSourceContext()); + } + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) { + setCursor (dsde.getDragSourceContext()); + } + + private void setCursor (DragSourceContext context) { + final Cursor cursor = myGutterDraggableObject.getCursor (); + context.setCursor(cursor); + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + if(dsde.getDropSuccess() == false) return; + + if(dsde.getDropAction() == DnDConstants.ACTION_MOVE) { + myGutterDraggableObject.removeSelf(); + } + } + + public void dragExit(DragSourceEvent dse) {} + } + + private class MyDropTargetListener implements DropTargetListener { + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + if (myGutterDraggableObject != null) { + int dropAction = dtde.getDropAction(); + if ((dropAction & DnDConstants.ACTION_MOVE) != 0) { + int line = myEditor.xyToLogicalPosition(new Point(0, (int)dtde.getLocation().getY())).line; + dtde.dropComplete(myGutterDraggableObject.copy(line)); + return; + } + } + + dtde.rejectDrop(); + } + + public void dragExit(DropTargetEvent dte) {} + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorImpl.java new file mode 100644 index 00000000000..37338fae7e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorImpl.java @@ -0,0 +1,3877 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.Patches; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.TooltipController; +import com.intellij.codeInsight.hint.TooltipGroup; +import com.intellij.ide.*; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.colors.*; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.ex.*; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.ex.util.EmptyHighlighter; +import com.intellij.openapi.editor.impl.event.MarkupModelEvent; +import com.intellij.openapi.editor.impl.event.MarkupModelListener; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.JScrollPane2; +import com.intellij.util.Alarm; +import com.intellij.util.IJSwingUtilities; +import com.intellij.util.containers.HashMap; +import gnu.trove.THashMap; +import gnu.trove.TIntArrayList; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.plaf.ScrollBarUI; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.*; +import java.awt.font.TextHitInfo; +import java.awt.im.InputMethodRequests; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.TooManyListenersException; + +public class EditorImpl implements EditorEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorImpl"); + private static final Key DND_COMMAND_KEY = Key.create("DndCommand"); + private final DocumentImpl myDocument; + + private JPanel myPanel; + private JScrollPane myScrollPane; + private EditorComponentImpl myEditorComponent; + private EditorGutterComponentImpl myGutterComponent; + + + private CommandProcessor myCommandProcessor; + private MyScrollBar myVerticalScrollBar; + private MyScrollBar myHorizontalScrollBar; + + private ArrayList myMouseListeners = new ArrayList(); + private ArrayList myMouseMotionListeners = new ArrayList(); + + private int myCharHeight = -1; + private int myLineHeight = -1; + private int myDescent = -1; + + private boolean myIsInsertMode = true; + + private final CaretCursor myCaretCursor; + private final ScrollingTimer myScrollingTimer = new ScrollingTimer(); + + private final Object MOUSE_DRAGGED_GROUP = Key.create("MouseDraggedGroup"); + private final THashMap myUserDataMap = new THashMap(); + + private final DocumentListener myEditorDocumentAdapter; + + private SettingsImpl mySettings; + + private boolean isReleased = false; + + private MouseEvent myMousePressedEvent = null; + + private int mySavedSelectionStart = -1; + private int mySavedSelectionEnd = -1; + private int myLastColumnNumber = 0; + + private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this); + private MyEditable myEditable; + + private EditorColorsScheme myScheme; + private final boolean myIsViewer; + private final SelectionModelImpl mySelectionModel; + private final EditorMarkupModelImpl myMarkupModel; + private final FoldingModelImpl myFoldingModel; + private final ScrollingModelImpl myScrollingModel; + private final CaretModelImpl myCaretModel; + + private static final RepaintCursorThread ourCaretThread; + +// private final BorderEffect myBorderEffect = new BorderEffect(); + + private int myMouseSelectionState = MOUSE_SELECTION_STATE_NONE; + private FoldRegion myMouseSelectedRegion = null; + + private static final int MOUSE_SELECTION_STATE_NONE = 0; + private static final int MOUSE_SELECTION_STATE_WORD_SELECTED = 1; + private static final int MOUSE_SELECTION_STATE_LINE_SELECTED = 2; + + private final MarkupModelListener myMarkupModelListener; + + private Highlighter myHighlighter; + + private int myScrollbarOrientation; + private boolean myMousePressedInsideSelection; + private FontMetrics myPlainFontMetrics; + private FontMetrics myBoldFontMetrics; + private FontMetrics myItalicFontMetrics; + private FontMetrics myBoldItalicFontMetrics; + + private static final int CACHED_CHARS_BUFFER_SIZE = 300; + + private CachedFontContent myPlainCache = new CachedFontContent(Font.PLAIN); + private CachedFontContent myBoldCache = new CachedFontContent(Font.BOLD); + private CachedFontContent myBoldItalicCache = new CachedFontContent(Font.BOLD + Font.ITALIC); + private CachedFontContent myItalicCache = new CachedFontContent(Font.ITALIC); + + private int myCurrentFontType = Font.PLAIN; + + private boolean myIsBlockSelectionMode; + private EditorSizeContainer mySizeContainer = new EditorSizeContainer(); + + private Runnable myCursorUpdater; + private int myCaretUpdateVShift; + Project myProject; + private long myMouseSelectionChangeTimestamp; + private int mySavedCaretOffsetForDNDUndoHack; + private ArrayList myFocusListeners = new ArrayList(); + + private MyInputMethodHandler myInputMethodRequestsHandler; + private InputMethodRequests myInputMethodRequestsSwingWrapper; + private boolean myIsOneLineMode; + private boolean myIsRendererMode; + private VirtualFile myVirtualFile; + private boolean myIsColumnMode = false; + private Color myForcedBackground = null; + private Dimension myPreferredSize; + private Runnable myGutterSizeUpdater = null; + private Alarm myAppleRepaintAlarm; + + static { + ourCaretThread = new RepaintCursorThread(); + ourCaretThread.start(); + } + + + public EditorImpl(Document document, boolean viewer, Project project) { + myProject = project; + myDocument = (DocumentImpl)document; + myScheme = new MyColorSchemeDelegate(); + myIsViewer = viewer; + mySettings = new SettingsImpl(this); + + mySelectionModel = new SelectionModelImpl(this); + myMarkupModel = new EditorMarkupModelImpl(this); + myFoldingModel = new FoldingModelImpl(this); + myCaretModel = new CaretModelImpl(this); + myIsBlockSelectionMode = false; + mySizeContainer.reset(); + + myCommandProcessor = CommandProcessor.getInstance(); + + myEditorDocumentAdapter = new EditorDocumentAdapter(); + + myMarkupModelListener = new MarkupModelListener() { + public void rangeHighlighterChanged(MarkupModelEvent event) { + RangeHighlighterImpl rangeHighlighter = (RangeHighlighterImpl)event.getHighlighter(); + if (rangeHighlighter.isValid()) { + int start = rangeHighlighter.getAffectedAreaStartOffset(); + int end = rangeHighlighter.getAffectedAreaEndOffset(); + int startLine = myDocument.getLineNumber(start); + int endLine = myDocument.getLineNumber(end); + repaintLines(Math.max(0, startLine - 1), Math.min(endLine + 1, getDocument().getLineCount())); + } + else { + repaint(0, getDocument().getTextLength()); + } + ((EditorMarkupModelImpl)getMarkupModel()).repaint(); + ((EditorMarkupModelImpl)getMarkupModel()).markDirtied(); + GutterIconRenderer renderer = rangeHighlighter.getGutterIconRenderer(); + if (renderer != null) { + updateGutterSize(); + } + updateCaretCursor(); + } + }; + + ((MarkupModelImpl)myDocument.getMarkupModel(myProject)).addMarkupModelListener(myMarkupModelListener); + ((MarkupModelImpl)getMarkupModel()).addMarkupModelListener(myMarkupModelListener); + + myDocument.addDocumentListener(myFoldingModel); + myDocument.addDocumentListener(myCaretModel); + myDocument.addDocumentListener(mySelectionModel); + myDocument.addDocumentListener(myEditorDocumentAdapter); + + myCaretCursor = new CaretCursor(); + + myFoldingModel.flushCaretShift(); + myScrollbarOrientation = EditorEx.VERTICAL_SCROLLBAR_RIGHT; + + Highlighter highlighter = new EmptyHighlighter(myScheme.getAttributes(HighlighterColors.TEXT)); + setHighlighter(highlighter); + + initComponent(); + + myScrollingModel = new ScrollingModelImpl(this); + + myGutterComponent.updateSize(); + myEditorComponent.setSize(getContentSize()); + + Dimension preferredSize = getPreferredSize(); + myScrollPane.getViewport().setViewSize(preferredSize); + + if (Patches.APPLE_BUG_ID_3716835) { + myScrollingModel.addVisibleAreaListener(new VisibleAreaListener() { + public void visibleAreaChanged(VisibleAreaEvent e) { + if (myAppleRepaintAlarm == null) { + myAppleRepaintAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + } + myAppleRepaintAlarm.cancelAllRequests(); + myAppleRepaintAlarm.addRequest(new Runnable() { + public void run() { + repaint(0, myDocument.getTextLength()); + } + }, 50, ModalityState.stateForComponent(myEditorComponent)); + } + }); + } + + updateCaretCursor(); + } + + public boolean isViewer() { + return myIsViewer || myIsRendererMode; + } + + public boolean isRendererMode() { + return myIsRendererMode; + } + + public void setRendererMode(boolean isRendererMode) { + myIsRendererMode = isRendererMode; + } + + public void setFile(VirtualFile vFile) { + myVirtualFile = vFile; + reinitSettings(); + } + + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + public SelectionModel getSelectionModel() { + return mySelectionModel; + } + + public MarkupModel getMarkupModel() { + return myMarkupModel; + } + + public FoldingModel getFoldingModel() { + return myFoldingModel; + } + + public CaretModel getCaretModel() { + return myCaretModel; + } + + public ScrollingModel getScrollingModel() { + return myScrollingModel; + } + + public EditorSettings getSettings() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return mySettings; + } + + public void reinitSettings() { + ApplicationManager.getApplication().assertIsDispatchThread(); + myCharHeight = -1; + myLineHeight = -1; + myDescent = -1; + myPlainFontMetrics = null; + + myPlainCache.reinitSettings(); + myBoldCache.reinitSettings(); + myItalicCache.reinitSettings(); + myBoldItalicCache.reinitSettings(); + + myCaretModel.reinitSettings(); + mySelectionModel.reinitSettings(); + mySettings.reinitSettings(); + ourCaretThread.setBlinkCaret(mySettings.isBlinkCaret()); + ourCaretThread.setBlinkPeriod(mySettings.getCaretBlinkPeriod()); + mySizeContainer.reset(); + myFoldingModel.refreshSettings(); + myFoldingModel.rebuild(); + + myHighlighter.setColorScheme(myScheme); + + myGutterComponent.revalidate(); + myEditorComponent.repaint(); + + updateCaretCursor(); + } + + public void release() { + isReleased = true; + myDocument.removeDocumentListener(myHighlighter); + myDocument.removeDocumentListener(myEditorDocumentAdapter); + myDocument.removeDocumentListener(myFoldingModel); + myDocument.removeDocumentListener(myCaretModel); + myDocument.removeDocumentListener(mySelectionModel); + MarkupModelImpl markupModel = (MarkupModelImpl)myDocument.getMarkupModel(myProject, false); + if (markupModel != null) markupModel.removeMarkupModelListener(myMarkupModelListener); + myMarkupModel.dispose(); + myLineHeight = -1; + myCharHeight = -1; + myDescent = -1; + myPlainFontMetrics = null; + myScrollingModel.dispose(); + myGutterComponent.dispose(); + } + + public void putUserData(Key key, T value) { + if (value != null) { + myUserDataMap.put(key, value); + } + else { + myUserDataMap.remove(key); + } + } + + public T getUserData(Key key) { + return (T)myUserDataMap.get(key); + } + + private void initComponent() { + myEditorComponent = new EditorComponentImpl(this); +// myStatusBar = new EditorStatusBarImpl(); + + myScrollPane = new JScrollPane2() { + protected void processMouseWheelEvent(MouseWheelEvent e) { + if (mySettings.isWheelFontChangeEnabled()) { + boolean changeFontSize = SystemInfo.isMac + ? !e.isControlDown() && e.isMetaDown() && !e.isAltDown() && !e.isShiftDown() + : e.isControlDown() && !e.isMetaDown() && !e.isAltDown() && !e.isShiftDown(); + if (changeFontSize) { + setFontSize(myScheme.getEditorFontSize() + e.getWheelRotation()); + return; + } + } + + super.processMouseWheelEvent(e); + } + }; + myPanel = new JPanel() { + public void addNotify() { + super.addNotify(); + if (((JComponent)getParent()).getBorder() != null) myScrollPane.setBorder(null); + } + }; + + //myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.Y_AXIS)); + myPanel.setLayout(new BorderLayout()); + + myVerticalScrollBar = new MyScrollBar(JScrollBar.VERTICAL); + myHorizontalScrollBar = new MyScrollBar(JScrollBar.HORIZONTAL); + + myGutterComponent = new EditorGutterComponentImpl(this); + myGutterComponent.setOpaque(true); + + myScrollPane.setVerticalScrollBar(myVerticalScrollBar); + myScrollPane.setHorizontalScrollBar(myHorizontalScrollBar); + myScrollPane.setViewportView(myEditorComponent); + //myScrollPane.setBorder(null); + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + + myScrollPane.setRowHeaderView(myGutterComponent); + stopOptimizedScrolling(); + + myEditorComponent.setTransferHandler(new MyTransferHandler()); + myEditorComponent.setAutoscrolls(true); + +/* Default mode till 1.4.0 + * myScrollPane.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE); + */ + myPanel.add(myScrollPane); + + myEditorComponent.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent event) { + if (Patches.APPLE_BUG_ID_3337563) return; // Everything is going through InputMethods under MacOS X in JDK releases earlier than 1.4.2_03-117.1 + if (event.isConsumed()) { + return; + } + if (processKeyTyped(event)) { + event.consume(); + } + } + }); + + MyMouseAdapter mouseAdapter = new MyMouseAdapter(); + myEditorComponent.addMouseListener(mouseAdapter); + myGutterComponent.addMouseListener(mouseAdapter); + + MyMouseMotionListener mouseMotionListener = new MyMouseMotionListener(); + myEditorComponent.addMouseMotionListener(mouseMotionListener); + myGutterComponent.addMouseMotionListener(mouseMotionListener); + + myEditorComponent.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + myCaretCursor.activate(); + int caretLine = getCaretModel().getLogicalPosition().line; + repaintLines(caretLine, caretLine); + fireFocusGained(); + } + + public void focusLost(FocusEvent e) { + synchronized (ourCaretThread) { + if (ourCaretThread.myEditor == EditorImpl.this) { + ourCaretThread.myEditor = null; + } + } + int caretLine = getCaretModel().getLogicalPosition().line; + repaintLines(caretLine, caretLine); + fireFocusLost(); + } + }); + +// myBorderEffect.reset(); + + try { + myEditorComponent.getDropTarget().addDropTargetListener(new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + } + + public void dragOver(DropTargetDragEvent dtde) { + Point location = dtde.getLocation(); + + moveCaretToScreenPos(location.x, location.y); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + }); + } + catch (TooManyListenersException e) { + } + } + + public void setFontSize(final int fontSize) { + int oldFontSize = myScheme.getEditorFontSize(); + myScheme.setEditorFontSize(fontSize); + myPropertyChangeSupport.firePropertyChange(EditorEx.PROP_FONT_SIZE, oldFontSize, fontSize); + } + + private void processKeyTyped(char c) { + // [vova] This is patch for Mac OS X. Under Mac "input methods" + // is handled before our EventQueue consume upcoming KeyEvents. + IdeEventQueue queue = IdeEventQueue.getInstance(); + if (queue.isWaitingForSecondKeyStroke() || ProgressManager.getInstance().hasModalProgressIndicator()) { + return; + } + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + DataContext dataContext = getDataContext(); + actionManager.fireBeforeEditorTyping(c, dataContext); + EditorActionManager.getInstance().getTypedAction().actionPerformed(this, c, dataContext); + } + + private void fireFocusLost() { + FocusChangeListener[] listeners = getFocusListeners(); + for (int i = 0; i < listeners.length; i++) { + FocusChangeListener listener = listeners[i]; + listener.focusLost(this); + } + } + + private FocusChangeListener[] getFocusListeners() { + return myFocusListeners.toArray(new FocusChangeListener[myFocusListeners.size()]); + } + + private void fireFocusGained() { + FocusChangeListener[] listeners = getFocusListeners(); + for (int i = 0; i < listeners.length; i++) { + FocusChangeListener listener = listeners[i]; + listener.focusGained(this); + } + } + + public void setHighlighter(Highlighter highlighter) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myHighlighter != null) { + getDocument().removeDocumentListener(myHighlighter); + } + + getDocument().addDocumentListener(highlighter); + highlighter.setText(getDocument().getCharsSequence()); + myHighlighter = highlighter; + myHighlighter.setEditor(this); + if (myPanel != null) { + reinitSettings(); + } + } + + public Highlighter getHighlighter() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myHighlighter; + } + + public JComponent getContentComponent() { + return myEditorComponent; + } + + public EditorGutterComponentEx getGutterComponentEx() { + return myGutterComponent; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.removePropertyChangeListener(listener); + } + + public void setInsertMode(boolean mode) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean oldValue = myIsInsertMode; + myIsInsertMode = mode; + myPropertyChangeSupport.firePropertyChange(EditorEx.PROP_INSERT_MODE, oldValue, mode); + //Repaint the caret line by moving caret to the same place + LogicalPosition caretPosition = getCaretModel().getLogicalPosition(); + getCaretModel().moveToLogicalPosition(caretPosition); + } + + public boolean isInsertMode() { + return myIsInsertMode; + } + + public void setColumnMode(boolean mode) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean oldValue = myIsColumnMode; + myIsColumnMode = mode; + myPropertyChangeSupport.firePropertyChange(PROP_COLUMN_MODE, oldValue, mode); + } + + public boolean isColumnMode() { + return myIsColumnMode; + } + + public void setBlockSelectionMode(boolean isBlockSelectionMode) { + myIsBlockSelectionMode = isBlockSelectionMode; + } + + public boolean isBlockSelectionMode() { + return myIsBlockSelectionMode; + } + + private int yPositionToVisibleLineNumber(int y) { + return y / getLineHeight(); + } + + public int getSpaceWidth(int fontType) { + int width = charWidth(fontType, ' '); + return width > 0 ? width : 1; + } + + public VisualPosition xyToVisualPosition(Point p) { + int line = yPositionToVisibleLineNumber(p.y); + + int x = 0; + int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0))); + int textLength = myDocument.getTextLength(); + + if (offset >= textLength) return new VisualPosition(line, 0); + + int column = 0; + int prevX = 0; + CharSequence text = myDocument.getCharsNoThreadCheck(); + char c = ' '; + IterationState state = new IterationState(this, offset, false); + + int fontType = state.getMergedAttributes().getFontType(); + int spaceSize = getSpaceWidth(fontType); + + outer: + while (true) { + if (offset >= textLength) break; + + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion region = state.getCurrentFold(); + if (region != null) { + char[] placeholder = region.getPlaceholderText().toCharArray(); + for (int j = 0; j < placeholder.length; j++) { + c = placeholder[j]; + x += charWidth(fontType, c); + if (x >= p.x) break outer; + column++; + } + offset = region.getEndOffset(); + } + else { + prevX = x; + c = text.charAt(offset); + if (c == '\n') { + break; + } + if (c == '\t') { + x = nextTabStop(x); + } + else { + x += charWidth(fontType, c); + } + + if (x >= p.x) break; + + if (c == '\t') { + column += (x - prevX) / spaceSize; + } + else { + column++; + } + + offset++; + } + } + + int charWidth = charWidth(fontType, c); + + if (x >= p.x && c == '\t') { + if (mySettings.isCaretInsideTabs()) { + column += (p.x - prevX) / spaceSize; + if ((p.x - prevX) % spaceSize > spaceSize / 2) column++; + } + else { + if ((x - p.x) * 2 < x - prevX) { + column += (x - prevX) / spaceSize; + } + } + } + else { + if (x >= p.x) { + if ((x - p.x) * 2 < charWidth) column++; + } + else { + column += (p.x - x) / getSpaceWidth(fontType); + } + } + + return new VisualPosition(line, column); + } + + public VisualPosition offsetToVisualPosition(int offset) { + return logicalToVisualPosition(offsetToLogicalPosition(offset)); + } + + public LogicalPosition offsetToLogicalPosition(int offset) { + int line = calcLogicalLineNumber(offset); + int column = calcColumnNumber(offset, line); + return new LogicalPosition(line, column); + } + + public LogicalPosition xyToLogicalPosition(Point p) { + final Point pp; + if (p.x >= 0 && p.y >= 0) { + pp = p; + } + else { + pp = new Point(Math.max(p.x, 0), Math.max(p.y, 0)); + } + + return visualToLogicalPosition(xyToVisualPosition(pp)); + } + + public Point logicalPositionToXY(LogicalPosition pos) { + VisualPosition visible = logicalToVisualPosition(pos); + int y = visibleLineNumberToYPosition(visible.line); + + int lineStartOffset; + + if (pos.line == 0) { + lineStartOffset = 0; + } + else { + if (pos.line >= myDocument.getLineCount()) { + lineStartOffset = myDocument.getTextLength(); + } + else { + lineStartOffset = myDocument.getLineStartOffset(pos.line); + } + } + + int x = getTabbedTextWidth(lineStartOffset, visible); + return new Point(x, y); + } + + public Point visualPositionToXY(VisualPosition visible) { + int y = visibleLineNumberToYPosition(visible.line); + int logLine = visualToLogicalPosition(new VisualPosition(visible.line, 0)).line; + + int lineStartOffset; + + if (logLine == 0) { + lineStartOffset = 0; + } + else { + if (logLine >= myDocument.getLineCount()) { + lineStartOffset = myDocument.getTextLength(); + } + else { + lineStartOffset = myDocument.getLineStartOffset(logLine); + } + } + + int x = getTabbedTextWidth(lineStartOffset, visible); + return new Point(x, y); + } + + private int getTabbedTextWidth(int lineStartOffset, VisualPosition pos) { + if (pos.column == 0) return 0; + + int x = 0; + int offset = lineStartOffset; + CharSequence text = myDocument.getCharsNoThreadCheck(); + int textLength = myDocument.getTextLength(); + IterationState state = new IterationState(this, offset, false); + int fontType = state.getMergedAttributes().getFontType(); + int spaceSize = getSpaceWidth(fontType); + + int column = 0; + outer: + while (column < pos.column) { + if (offset >= textLength) break; + + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion region = state.getCurrentFold(); + + if (region != null) { + char[] placeholder = region.getPlaceholderText().toCharArray(); + for (int j = 0; j < placeholder.length; j++) { + x += charWidth(fontType, placeholder[j]); + column++; + if (column >= pos.column) break outer; + } + offset = region.getEndOffset(); + } + else { + char c = text.charAt(offset); + if (c == '\n') { + break; + } + if (c == '\t') { + int prevX = x; + x = nextTabStop(x); + column += (x - prevX) / spaceSize; + } + else { + x += charWidth(fontType, c); + column++; + } + offset++; + } + } + + if (column != pos.column) { + x += getSpaceWidth(fontType) * (pos.column - column); + } + + return x; + } + + public int nextTabStop(int x) { + int tabSize = mySettings.getTabSize(myProject); + if (tabSize <= 0) { + tabSize = 1; + } + + tabSize *= getSpaceWidth(Font.PLAIN); + + int nTabs = x / tabSize; + return (nTabs + 1) * tabSize; + } + + public int visibleLineNumberToYPosition(int lineNum) { + if (lineNum < 0) throw new IndexOutOfBoundsException("Wrong line: " + lineNum); + return lineNum * getLineHeight(); + } + + public void repaint(int startOffset, int endOffset) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myScrollPane == null) { + return; + } + if (endOffset > myDocument.getTextLength()) { + endOffset = myDocument.getTextLength(); + } + if (startOffset < endOffset) { + int startLine = myDocument.getLineNumber(startOffset); + int endLine = myDocument.getLineNumber(endOffset); + repaintLines(startLine, endLine); + } + } + + public void repaintLines(int startLine, int endLine) { + Rectangle visibleRect = getScrollingModel().getVisibleArea(); + int yStartLine = logicalPositionToXY(new LogicalPosition(startLine, 0)).y; + int yEndLine = logicalPositionToXY(new LogicalPosition(endLine, 0)).y + getLineHeight() + WAVE_HEIGHT; + + myEditorComponent.repaintEditorComponent(visibleRect.x, + yStartLine, + visibleRect.x + visibleRect.width, + yEndLine - yStartLine); + myGutterComponent.repaint(0, yStartLine, myGutterComponent.getWidth(), yEndLine - yStartLine); + } + + private void beforeChangedUpdate(DocumentEvent e) { + Rectangle viewRect = getScrollingModel().getVisibleArea(); + Point pos = visualPositionToXY(getCaretModel().getVisualPosition()); + myCaretUpdateVShift = pos.y - viewRect.y; + mySizeContainer.beforeChange(e); + } + + private void changedUpdate(DocumentEvent e) { + if (myScrollPane == null) return; + + stopOptimizedScrolling(); + mySelectionModel.removeBlockSelection(); + + mySizeContainer.changedUpdate(e); + int startVisualLine = offsetToVisualPosition(e.getOffset()).line; + int endVisualLine = offsetToVisualPosition(e.getOffset() + e.getNewLength()).line; + + if (myDocument.getTextLength() > 0) { + int startDocLine = myDocument.getLineNumber(e.getOffset()); + int endDocLine = myDocument.getLineNumber(e.getOffset() + e.getNewLength()); + if (e.getOldLength() > e.getNewLength() || startDocLine != endDocLine) { + updateGutterSize(); + } + } + + updateCaretCursor(); + repaintLines(startVisualLine, endVisualLine); + + Point caretLocation = visualPositionToXY(getCaretModel().getVisualPosition()); + int scrollOffset = caretLocation.y - myCaretUpdateVShift; + getScrollingModel().scrollVertically(scrollOffset); + } + + private void updateGutterSize() { + if (myGutterSizeUpdater != null) return; + myGutterSizeUpdater = new Runnable() { + public void run() { + myGutterComponent.updateSize(); + myGutterSizeUpdater = null; + } + }; + } + + void validateSize() { + if (myGutterSizeUpdater != null) { + SwingUtilities.invokeLater(myGutterSizeUpdater); + } + + Dimension dim = getPreferredSize(); + + if (!dim.equals(myPreferredSize)) { + myPreferredSize = dim; + + stopOptimizedScrolling(); + myScrollPane.getViewport().setViewSize(myPreferredSize); + int lineNum = Math.max(1, getDocument().getLineCount()); + + myGutterComponent.setLineNumberAreaWidth(getFontMetrics(Font.PLAIN).stringWidth(Integer.toString((lineNum + 2))) + 6); + final JViewport rowHeader = myScrollPane.getRowHeader(); + if (rowHeader != null) { + rowHeader.setViewSize(myGutterComponent.getPreferredSize()); + } + + getScrollPane().revalidate(); + + myEditorComponent.repaint(); + myScrollPane.repaint(); + myMarkupModel.repaint(); + } + } + + void recalcSizeAndRepaint() { + mySizeContainer.reset(); + + validateSize(); + + Dimension size = getPreferredSize(); + + myScrollPane.getVerticalScrollBar().setMaximum(size.height); + myScrollPane.getHorizontalScrollBar().setMaximum(size.width); + + getScrollPane().revalidate(); + myMarkupModel.repaint(); + + stopOptimizedScrolling(); + myEditorComponent.repaintEditorComponent(); + + myGutterComponent.repaint(); + } + + public Document getDocument() { + return myDocument; + } + + public JComponent getComponent() { + return myPanel; + } + + public void addEditorMouseListener(EditorMouseListener listener) { + myMouseListeners.add(listener); + } + + public void removeEditorMouseListener(EditorMouseListener listener) { + boolean success = myMouseListeners.remove(listener); + LOG.assertTrue(success); + } + + public void addEditorMouseMotionListener(EditorMouseMotionListener listener) { + myMouseMotionListeners.add(listener); + } + + public void removeEditorMouseMotionListener(EditorMouseMotionListener listener) { + boolean success = myMouseMotionListeners.remove(listener); + LOG.assertTrue(success); + } + + public boolean isDisposed() { + return isReleased; + } + + public void paint(Graphics g) { + validateSize(); + startOptimizedScrolling(); + + if (myCursorUpdater != null) { + myCursorUpdater.run(); + myCursorUpdater = null; + } + + Rectangle clip = getClipBounds(g); + + if (clip == null) { + return; + } + + Rectangle viewRect = getScrollingModel().getVisibleArea(); + if (viewRect == null) { + return; + } + + if (isReleased) { + g.setColor(new Color(128, 255, 128)); + g.fillRect(clip.x, clip.y, clip.width, clip.height); + + return; + } + + Color background = getBackroundColor(); + g.setColor(background); + g.fillRect(clip.x, clip.y, clip.width, clip.height); + + paintBackgrounds(g, clip); + paintRectangularSelection(g); + paintRightMargin(g, clip); + final MarkupModel docMarkup = myDocument.getMarkupModel(myProject); + if (docMarkup != null) { + paintLineMarkersSeparators(g, clip, docMarkup); + } + paintLineMarkersSeparators(g, clip, myMarkupModel); + paintText(g, clip); + paintSegmentHighlightersBorderAndAfterEndOfLine(g, clip); + BorderEffect borderEffect = new BorderEffect(this, g); + borderEffect.paintHighlighters(getHighlighter()); + if (docMarkup != null) { + borderEffect.paintHighlighters(docMarkup.getAllHighlighters()); + } + borderEffect.paintHighlighters((getMarkupModel()).getAllHighlighters()); + paintCaretCursor(g); + + paintComposedTextDecoration((Graphics2D)g); + } + + public void setBackgroundColor(Color color) { + myForcedBackground = color; + } + + public void resetBackgourndColor() { + myForcedBackground = null; + } + + public Color getBackroundColor() { + if (myForcedBackground != null) return myForcedBackground; + + Color color = myScheme.getColor(EditorColors.BACKGROUND_COLOR); + if (color == null) color = Color.white; + if (myDocument.isWritable()) { + return color; + } + Color readOnlyColor = myScheme.getColor(EditorColors.READONLY_BACKGROUND_COLOR); + return readOnlyColor != null ? readOnlyColor : color; + } + + private void paintComposedTextDecoration(Graphics2D g) { + if (myInputMethodRequestsHandler != null && myInputMethodRequestsHandler.composedText != null) { + VisualPosition visStart = offsetToVisualPosition( + Math.min(myInputMethodRequestsHandler.composedTextStart, myDocument.getTextLength())); + int y = visibleLineNumberToYPosition(visStart.line) + getLineHeight() - getDescent() + 1; + Point p1 = visualPositionToXY(visStart); + Point p2 = logicalPositionToXY( + offsetToLogicalPosition(Math.min(myInputMethodRequestsHandler.composedTextEnd, myDocument.getTextLength()))); + + Stroke saved = g.getStroke(); + BasicStroke dotted = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[]{0, 2, 0, 2}, + 0); + g.setStroke(dotted); + g.drawLine(p1.x, y, p2.x, y); + g.setStroke(saved); + } + } + + private static Rectangle getClipBounds(Graphics g) { + return g.getClipBounds(); + } + + private void paintRightMargin(Graphics g, Rectangle clip) { + Color rightMargin = myScheme.getColor(EditorColors.RIGHT_MARGIN_COLOR); + if (!mySettings.isRightMarginShown() || rightMargin == null) { + return; + } + int x = mySettings.getRightMargin(myProject) * getSpaceWidth(Font.PLAIN); + if (x >= clip.x && x < clip.x + clip.width) { + g.setColor(rightMargin); + g.drawLine(x, clip.y, x, clip.y + clip.height); + } + } + + private void paintSegmentHighlightersBorderAndAfterEndOfLine(Graphics g, Rectangle clip) { + if (myDocument.getLineCount() == 0) return; + int startLineNumber = yPositionToVisibleLineNumber(clip.y); + int endLineNumber = yPositionToVisibleLineNumber(clip.y + clip.height) + 1; + + RangeHighlighter[] segmentHighlighters; + final MarkupModel docMarkup = myDocument.getMarkupModel(myProject); + if (docMarkup != null) { + segmentHighlighters = docMarkup.getAllHighlighters(); + for (int i = 0; i < segmentHighlighters.length; i++) { + paintSegmentHighlighterAfterEndOfLine(g, (RangeHighlighterEx)segmentHighlighters[i], startLineNumber, + endLineNumber); + } + } + + segmentHighlighters = getMarkupModel().getAllHighlighters(); + for (int i = 0; i < segmentHighlighters.length; i++) { + RangeHighlighter segmentHighlighter = segmentHighlighters[i]; + paintSegmentHighlighterAfterEndOfLine(g, (RangeHighlighterEx)segmentHighlighter, startLineNumber, endLineNumber); + } + } + + private void paintSegmentHighlighterAfterEndOfLine(Graphics g, RangeHighlighterEx segmentHighlighter, + int startLineNumber, int endLineNumber) { + if (!segmentHighlighter.isValid()) { + return; + } + if (segmentHighlighter.isAfterEndOfLine()) { + int startOffset = segmentHighlighter.getStartOffset(); + int visibleStartLine = offsetToVisualPosition(startOffset).line; + + if (!getFoldingModel().isOffsetCollapsed(startOffset)) { + if (visibleStartLine >= startLineNumber && visibleStartLine <= endLineNumber) { + int logStartLine = offsetToLogicalPosition(startOffset).line; + LogicalPosition logPosition = offsetToLogicalPosition(myDocument.getLineEndOffset(logStartLine)); + Point end = logicalPositionToXY(logPosition); + int charWidth = getSpaceWidth(Font.PLAIN); + int lineHeight = getLineHeight(); + TextAttributes attributes = segmentHighlighter.getTextAttributes(); + if (attributes != null && attributes.getBackgroundColor() != null) { + g.setColor(attributes.getBackgroundColor()); + g.fillRect(end.x, end.y, charWidth, lineHeight); + } + if (attributes != null && attributes.getEffectColor() != null) { + int y = visibleLineNumberToYPosition(visibleStartLine) + getLineHeight() - getDescent() + 1; + g.setColor(attributes.getEffectColor()); + if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) { + drawWave(g, end.x, end.x + charWidth - 1, y); + } + else if (attributes.getEffectType() != EffectType.BOXED) { + g.drawLine(end.x, y, end.x + charWidth - 1, y); + } + } + } + } + } + } + + public int getMaxWidthInRange(int startOffset, int endOffset) { + int width = 0; + VisualPosition start = offsetToVisualPosition(startOffset); + VisualPosition end = offsetToVisualPosition(endOffset); + + for (int i = start.line; i <= end.line; i++) { + int lastColumn = EditorUtil.getLastVisualLineColumnNumber(this, i) + 1; + int lineWidth = visualPositionToXY(new VisualPosition(i, lastColumn)).x; + + if (lineWidth > width) { + width = lineWidth; + } + } + + return width; + } + + private void paintBackgrounds(Graphics g, Rectangle clip) { + int lineHeight = getLineHeight(); + + int visibleLineNumber = clip.y / lineHeight; + + int startLineNumber = xyToLogicalPosition(new Point(0, clip.y)).line; + + if (startLineNumber >= myDocument.getLineCount() || startLineNumber < 0) { + return; + } + + int start = myDocument.getLineStartOffset(startLineNumber); + + IterationState iterationState = new IterationState(this, start, true); + + LineIterator lIterator = createLineIterator(); + lIterator.start(start); + if (lIterator.atEnd()) { + return; + } + + TextAttributes attributes = iterationState.getMergedAttributes(); + Color backColor = attributes.getBackgroundColor(); + Point position = new Point(0, visibleLineNumber * lineHeight); + int fontType = attributes.getFontType(); + CharSequence text = myDocument.getCharsNoThreadCheck(); + int lastLineIndex = Math.max(0, myDocument.getLineCount() - 1); + while (!iterationState.atEnd() && !lIterator.atEnd()) { + int hEnd = iterationState.getEndOffset(); + int lEnd = lIterator.getEnd(); + + if (hEnd >= lEnd) { + FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); + if (collapsedFolderAt == null) { + position.x = drawBackground(g, backColor, text.subSequence(start, lEnd - lIterator.getSeparatorLength()), + position, fontType); + + if (lIterator.getLineNumber() < lastLineIndex) { + if (backColor != null) { + Color saved = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, clip.x + clip.width - position.x, lineHeight); + g.setColor(saved); + } + } + else { + paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight); + break; + } + + position.x = 0; + if (position.y > clip.y + clip.height) break; + position.y += lineHeight; + start = lEnd; + } + + lIterator.advance(); + } + else { + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + position.x = drawBackground(g, backColor, collapsedFolderAt.getPlaceholderText(), + position, fontType); + } + else { + if (hEnd > lEnd - lIterator.getSeparatorLength()) { + position.x = drawBackground(g, backColor, text.subSequence(start, lEnd - lIterator.getSeparatorLength()), + position, fontType); + } + else { + position.x = drawBackground(g, backColor, text.subSequence(start, hEnd), position, fontType); + } + } + + iterationState.advance(); + attributes = iterationState.getMergedAttributes(); + backColor = attributes.getBackgroundColor(); + fontType = attributes.getFontType(); + start = iterationState.getStartOffset(); + } + } + + if (lIterator.getLineNumber() >= lastLineIndex && position.y <= clip.y + clip.height) { + paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight); + } + } + + private void paintRectangularSelection(Graphics g) { + final SelectionModel model = getSelectionModel(); + if (!model.hasBlockSelection()) return; + final Point start = logicalPositionToXY(model.getBlockStart()); + final Point end = logicalPositionToXY(model.getBlockEnd()); + g.setColor(myScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)); + final int y; + final int height; + if (start.y <= end.y) { + y = start.y; + height = end.y - y + getLineHeight(); + } + else { + y = end.y; + height = start.y - end.y + getLineHeight(); + } + final int x = Math.min(start.x, end.x); + final int width = Math.max(2, Math.abs(end.x - start.x)); + g.fillRect(x, y, width, height); + } + + private static void paintAfterFileEndBackground(IterationState iterationState, Graphics g, Point position, + Rectangle clip, int lineHeight) { + Color backColor = iterationState.getPastFileEndBackground(); + if (backColor != null) { + Color saved = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, clip.x + clip.width - position.x, lineHeight); + g.setColor(saved); + } + } + + private int drawBackground(Graphics g, + Color backColor, + CharSequence text, + Point position, + int fontType) { + int w = getTextSegmentWidth(text, position.x, fontType); + + if (backColor != null) { + Color savedColor = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, w, getLineHeight()); + g.setColor(savedColor); + } + + return position.x + w; + } + + private LineIterator createLineIterator() { + return myDocument.createLineIterator(); + } + + private void paintText(Graphics g, Rectangle clip) { + int lineHeight = getLineHeight(); + + int visibleLineNumber = clip.y / lineHeight; + + int startLineNumber = xyToLogicalPosition(new Point(0, clip.y)).line; + + if (startLineNumber >= myDocument.getLineCount() || startLineNumber < 0) { + return; + } + + int start = myDocument.getLineStartOffset(startLineNumber); + + IterationState iterationState = new IterationState(this, start, true); + + LineIterator lIterator = createLineIterator(); + lIterator.start(start); + if (lIterator.atEnd()) { + return; + } + + TextAttributes attributes = iterationState.getMergedAttributes(); + Color currentColor = attributes.getForegroundColor(); + if (currentColor == null) { + currentColor = Color.black; + } + Color effectColor = attributes.getEffectColor(); + EffectType effectType = attributes.getEffectType(); + int fontType = attributes.getFontType(); + myCurrentFontType = fontType; + Font currentFont = getFont(fontType); + g.setColor(currentColor); + g.setFont(currentFont); + Point position = new Point(0, visibleLineNumber * lineHeight); + while (!iterationState.atEnd() && !lIterator.atEnd()) { + int hEnd = iterationState.getEndOffset(); + int lEnd = lIterator.getEnd(); + if (hEnd >= lEnd) { + FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); + if (collapsedFolderAt == null) { + drawString(g, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor, effectType, + fontType, currentColor); + position.x = 0; + if (position.y > clip.y + clip.height) break; + position.y += lineHeight; + start = lEnd; + } + +// myBorderEffect.eolReached(g, this); + lIterator.advance(); + } + else { + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + int foldingXStart = position.x; + position.x = drawString(g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, + fontType, currentColor); + BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, position.x, getLineHeight(), effectColor, + effectType); + + } + else { + if (hEnd > lEnd - lIterator.getSeparatorLength()) { + position.x = drawString(g, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor, + effectType, fontType, currentColor); + } + else { + position.x = drawString(g, start, hEnd, position, clip, effectColor, effectType, fontType, currentColor); + } + } + + iterationState.advance(); + attributes = iterationState.getMergedAttributes(); + Color color = attributes.getForegroundColor(); + if (color == null) { + color = Color.black; + } + if (color != currentColor) { + g.setColor(color); + currentColor = color; + } + effectColor = attributes.getEffectColor(); + effectType = attributes.getEffectType(); + fontType = attributes.getFontType(); + + start = iterationState.getStartOffset(); + } + } + + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + int foldingXStart = position.x; + int foldingXEnd = drawString(g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, + currentColor); + BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, foldingXEnd, getLineHeight(), effectColor, + effectType); +// myBorderEffect.collapsedFolderReached(g, this); + } + + flushCachedChars(g); + } + + private class CachedFontContent { + int[] charWidths = null; + final CharSequence[] data = new CharSequence[CACHED_CHARS_BUFFER_SIZE]; + final int[] x = new int[CACHED_CHARS_BUFFER_SIZE]; + final int[] y = new int[CACHED_CHARS_BUFFER_SIZE]; + final Color[] color = new Color[CACHED_CHARS_BUFFER_SIZE]; + + int myCount = 0; + final int myFontType; + private FontMetrics myFontMetrics; + + public CachedFontContent(int fontType) { + myFontType = fontType; + } + + public void reinitSettings() { + myFontMetrics = null; + charWidths = null; + } + + public int charWidth(char c) { + if (c >= 256) return fontMetrics().charWidth(c); + if (charWidths == null) { + charWidths = new int[256]; + FontMetrics fontMetrics = fontMetrics(); + for (int i = 0; i < 256; i++) { + charWidths[i] = fontMetrics.charWidth(i); + } + } + return charWidths[c]; + } + + private FontMetrics fontMetrics() { + if (myFontMetrics == null) { + myFontMetrics = getFontMetrics(myFontType); + } + return myFontMetrics; + } + + public void flushContent(Graphics g) { + if (myCount != 0) { + if (myCurrentFontType != myFontType) { + myCurrentFontType = myFontType; + g.setFont(getFont(myFontType)); + } + + Color currentColor = null; + for (int i = 0; i < myCount; i++) { + if (!color[i].equals(currentColor)) { + currentColor = color[i]; + g.setColor(currentColor); + } + + drawChars(g, data[i], x[i], y[i]); + color[i] = null; + data[i] = null; + } + + myCount = 0; + } + } + + public void addContent(Graphics g, CharSequence data, int x, int y, Color color) { + this.data[myCount] = data; + this.x[myCount] = x; + this.y[myCount] = y; + this.color[myCount] = color; + + myCount++; + if (myCount >= CACHED_CHARS_BUFFER_SIZE) { + flushContent(g); + } + } + } + + private void flushCachedChars(Graphics g) { + myPlainCache.flushContent(g); + myBoldCache.flushContent(g); + myBoldItalicCache.flushContent(g); + myItalicCache.flushContent(g); + } + + private void paintCaretCursor(Graphics g) { + myCaretCursor.paint(g); + } + + private void paintLineMarkersSeparators(Graphics g, Rectangle clip, MarkupModel markupModel) { + if (markupModel == null) return; + RangeHighlighter[] lineMarkers = markupModel.getAllHighlighters(); + for (int i = 0; i < lineMarkers.length; i++) { + RangeHighlighter lineMarker = lineMarkers[i]; + paintLineMarkerSeparator(lineMarker, clip, g); + } + } + + private void paintLineMarkerSeparator(RangeHighlighter marker, Rectangle clip, Graphics g) { + if (!marker.isValid()) { + return; + } + Color separatorColor = marker.getLineSeparatorColor(); + if (separatorColor != null) { + int lineNumber = marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? marker.getDocument() + .getLineNumber(marker.getStartOffset()) : marker.getDocument().getLineNumber(marker.getEndOffset()); + if (lineNumber < 0 || lineNumber >= myDocument.getLineCount()) { + return; + } + + int endShift = clip.x + clip.width; + g.setColor(separatorColor); + + if (mySettings.isRightMarginShown() + && myScheme.getColor(EditorColors.RIGHT_MARGIN_COLOR) != null) { + endShift = + Math.min(endShift, mySettings.getRightMargin(myProject) * getSpaceWidth(Font.PLAIN)); + } + + int y = visibleLineNumberToYPosition(logicalToVisualPosition(new LogicalPosition(lineNumber, 0)).line); + + if (marker.getLineSeparatorPlacement() != SeparatorPlacement.TOP) { + y += getLineHeight(); + } + + g.drawLine(0, y - 1, endShift, y - 1); + } + } + + private Font getFont(int type) { + if (type == Font.BOLD) { + return myScheme.getFont(EditorFontType.BOLD); + } + else { + if (type == Font.ITALIC) { + return myScheme.getFont(EditorFontType.ITALIC); + } + else { + if (type == Font.ITALIC + Font.BOLD) { + return myScheme.getFont(EditorFontType.BOLD_ITALIC); + } + else { + return myScheme.getFont(EditorFontType.PLAIN); + } + } + } + } + + private int drawString(Graphics g, int start, int end, Point position, Rectangle clip, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + if (start >= end) return position.x; + + CharSequence text = myDocument.getCharsNoThreadCheck(); + boolean isInClip = (getLineHeight() + position.y >= clip.y) && (position.y <= clip.y + clip.height); + + if (!isInClip) return position.x; + + int y = getLineHeight() - getDescent() + position.y; + int x = position.x; + return drawTabbedString(g, text.subSequence(start, end), x, y, effectColor, effectType, fontType, fontColor); + } + + private int drawString(Graphics g, String text, Point position, Rectangle clip, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + boolean isInClip = (getLineHeight() + position.y >= clip.y) && (position.y <= clip.y + clip.height); + + if (!isInClip) return position.x; + + int y = getLineHeight() - getDescent() + position.y; + int x = position.x; + return drawTabbedString(g, text, x, y, effectColor, effectType, fontType, + fontColor); + } + + private int drawTabbedString(Graphics g, CharSequence text, int x, int y, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + int xStart = x; + + int start = 0; + + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) != '\t') continue; + + if (i > start) { + drawCharsCached(g, text.subSequence(start, i), x, y, fontType, fontColor); + for (int j = start; j < i; j++) { + char c = text.charAt(j); + x += charWidth(fontType, c); + } + } + + int x1 = nextTabStop(x); + drawTabPlacer(g, y, x, x1); + x = x1; + start = i + 1; + } + + if (start < text.length()) { + drawCharsCached(g, text.subSequence(start, text.length()), x, y, fontType, fontColor); + for (int j = start; j < text.length(); j++) x += charWidth(fontType, text.charAt(j)); + } + + if (effectColor != null) { + Color savedColor = g.getColor(); + + int w = getTextSegmentWidth(text, xStart, fontType); +// myBorderEffect.flushIfCantProlong(g, this, effectType, effectColor); + if (effectType == EffectType.LINE_UNDERSCORE) { + g.setColor(effectColor); + g.drawLine(xStart, y + 1, xStart + w, y + 1); + g.setColor(savedColor); + } + else { + if (effectType == EffectType.STRIKEOUT) { + g.setColor(effectColor); + int y1 = y - getCharHeight() / 2; + g.drawLine(xStart, y1, xStart + w, y1); + g.setColor(savedColor); + } + else { + if (effectType == EffectType.WAVE_UNDERSCORE) { + g.setColor(effectColor); + drawWave(g, xStart, xStart + w, y + 1); + g.setColor(savedColor); + } /*else { + if (effectType == EffectType.BOXED) { + int yStart = y - getLineHeight() + getDescent(); + if (!myBorderEffect.isDetached()) myBorderEffect.start(effectColor, start); + myBorderEffect.setEndOffset(offset + length); + } + }*/ + } + } + } /*else myBorderEffect.flushBorder(g, this);*/ + + return x; + } + + public int charWidth(int fontType, char c) { + switch(fontType) { + case Font.PLAIN: return myPlainCache.charWidth(c); + case Font.BOLD: return myBoldCache.charWidth(c); + case Font.ITALIC: return myItalicCache.charWidth(c); + case Font.BOLD | Font.ITALIC: return myBoldItalicCache.charWidth(c); + } + + return 0; + } + + private void drawTabPlacer(Graphics g, int y, int start, int stop) { + if (mySettings.isWhitespacesShown()) { + stop -= g.getFontMetrics().charWidth(' ') / 2; + Color oldColor = g.getColor(); + g.setColor(myScheme.getColor(EditorColors.WHITESPACES_COLOR)); + final int charHeight = getCharHeight(); + final int halfCharHeight = charHeight / 2; + int mid = y - halfCharHeight; + int top = y - charHeight; + g.drawLine(start, mid, stop, mid); + g.drawLine(stop, y, stop, top); + g.fillPolygon(new int[]{stop - halfCharHeight, stop - halfCharHeight, stop}, + new int[]{y, y - charHeight, y - halfCharHeight}, 3); + g.setColor(oldColor); + } + } + + private void drawCharsCached(Graphics g, + CharSequence data, + int x, + int y, + int fontType, + Color color) { + if (!SystemInfo.isMac) { + if (fontType == myCurrentFontType) { + drawChars(g, data, x, y); + } + else if (fontType == Font.PLAIN) { + myPlainCache.addContent(g, data, x, y, color); + } + else if (fontType == Font.BOLD) { + myBoldCache.addContent(g, data, x, y, color); + } + else if (fontType == Font.ITALIC) { + myItalicCache.addContent(g, data, x, y, color); + } + else { + myBoldItalicCache.addContent(g, data, x, y, color); + } + } + else { + if (fontType != myCurrentFontType) { + myCurrentFontType = fontType; + g.setFont(getFont(fontType)); + } + + drawChars(g, data, x, y); + } + } + + private void drawChars(Graphics g, CharSequence data, int x, int y) { + g.drawString(data.toString(), x, y); + + if (mySettings.isWhitespacesShown()) { + Color oldColor = g.getColor(); + g.setColor(myScheme.getColor(EditorColors.WHITESPACES_COLOR)); + final FontMetrics metrics = g.getFontMetrics(); + int halfSpaceWidth = metrics.charWidth(' ') / 2; + for (int i = 0; i < data.length(); i++) { + if (data.charAt(i) == ' ') { + g.fillRect(x + halfSpaceWidth, y, 1, 1); + } + x += metrics.charWidth(data.charAt(i)); + } + g.setColor(oldColor); + } + } + + private static final int WAVE_HEIGHT = 2; + private static final int WAVE_SEGMENT_LENGTH = 4; + + private static void drawWave(Graphics g, int xStart, int xEnd, int y) { + int startSegment = xStart / WAVE_SEGMENT_LENGTH; + int endSegment = xEnd / WAVE_SEGMENT_LENGTH; + for (int i = startSegment; i < endSegment; i++) { + drawWaveSegment(g, WAVE_SEGMENT_LENGTH * i, y); + } + + int x = WAVE_SEGMENT_LENGTH * endSegment; + g.drawLine(x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y); + } + + private static void drawWaveSegment(Graphics g, int x, int y) { + g.drawLine(x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y); + g.drawLine(x + WAVE_SEGMENT_LENGTH / 2, y, x + WAVE_SEGMENT_LENGTH, y + WAVE_HEIGHT); + } + + private int getTextSegmentWidth(CharSequence text, int xStart, int fontType) { + int start = 0; + int x = xStart; + + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) != '\t') continue; + + if (i > start) { + for (int j = start; j < i; j++) x += charWidth(fontType, text.charAt(j)); + } + x = nextTabStop(x); + start = i + 1; + } + + if (start < text.length()) { + for (int j = start; j < text.length(); j++) x += charWidth(fontType, text.charAt(j)); + } + + return x - xStart; + } + + public int getLineHeight() { + if (myLineHeight != -1) return myLineHeight; + + ApplicationManager.getApplication().assertIsDispatchThread(); + + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myLineHeight = (int)(fontMetrics.getHeight() * (isOneLineMode() ? 1 : myScheme.getLineSpacing())); + if (myLineHeight == 0) { + myLineHeight = fontMetrics.getHeight(); + if (myLineHeight == 0) { + myLineHeight = 12; + } + } + + return myLineHeight; + } + + int getDescent() { + if (myDescent != -1) { + return myDescent; + } + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myDescent = fontMetrics.getDescent(); + return myDescent; + } + + public FontMetrics getFontMetrics(int fontType) { + if (myPlainFontMetrics == null) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myPlainFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myBoldFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.BOLD)); + myItalicFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.ITALIC)); + myBoldItalicFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.BOLD_ITALIC)); + } + + if (fontType == Font.PLAIN) return myPlainFontMetrics; + if (fontType == Font.BOLD) return myBoldFontMetrics; + if (fontType == Font.ITALIC) return myItalicFontMetrics; + if (fontType == Font.BOLD + Font.ITALIC) return myBoldItalicFontMetrics; + + LOG.assertTrue(false, "Unknown font type: " + fontType); + + return myPlainFontMetrics; + } + + private int getCharHeight() { + if (myCharHeight == -1) { + ApplicationManager.getApplication().assertIsDispatchThread(); + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myCharHeight = fontMetrics.charWidth('a'); + } + return myCharHeight; + } + + public Dimension getPreferredSize() { + Dimension draft = getSizeWithoutCaret(); + int caretX = visualPositionToXY(getCaretModel().getVisualPosition()).x; + draft.width = Math.max(caretX, draft.width) + mySettings.getAdditionalColumnsCount() * getSpaceWidth(Font.PLAIN); + return draft; + } + + private Dimension getSizeWithoutCaret() { + Dimension size = mySizeContainer.getContentSize(); + if (isOneLineMode()) return new Dimension(size.width, getLineHeight()); + if (mySettings.isAdditionalPageAtBottom()) { + int lineHeight = getLineHeight(); + return new Dimension(size.width, + size.height + + Math.max(getScrollingModel().getVisibleArea().height - 2 * lineHeight, lineHeight)); + } + + return getContentSize(); + } + + public Dimension getContentSize() { + Dimension size = mySizeContainer.getContentSize(); + return new Dimension(size.width, size.height + mySettings.getAdditionalLinesCount() * getLineHeight()); + } + + public JScrollPane getScrollPane() { + return myScrollPane; + } + + public int logicalPositionToOffset(LogicalPosition pos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myDocument.getLineCount() == 0) return 0; + + if (pos.line < 0) throw new IndexOutOfBoundsException("Wrong line: " + pos.line); + if (pos.column < 0) throw new IndexOutOfBoundsException("Wrong column:" + pos.column); + + if (pos.line >= myDocument.getLineCount()) { + return myDocument.getTextLength(); + } + + int start = myDocument.getLineStartOffset(pos.line); + int end = myDocument.getLineEndOffset(pos.line); + + CharSequence text = myDocument.getCharsNoThreadCheck(); + + if (pos.column == 0) return start; + return EditorUtil.calcOffset(this, text, start, end, pos.column, mySettings.getTabSize(myProject)); + } + + public void setLastColumnNumber(int val) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myLastColumnNumber = val; + } + + public int getLastColumnNumber() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myLastColumnNumber; + } + + int getVisibleLineCount() { + int line = getDocument().getLineCount(); + line -= myFoldingModel.getFoldedLinesCountBefore(getDocument().getTextLength() + 1); + return line; + } + + public VisualPosition logicalToVisualPosition(LogicalPosition logicalPos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myFoldingModel.isFoldingEnabled()) return new VisualPosition(logicalPos.line, logicalPos.column); + + int offset = logicalPositionToOffset(logicalPos); + + FoldRegion outermostCollapsed = myFoldingModel.getCollapsedRegionAtOffset(offset); + if (outermostCollapsed != null && offset > outermostCollapsed.getStartOffset()) { + if (offset < getDocument().getTextLength() - 1) { + offset = outermostCollapsed.getStartOffset(); + LogicalPosition foldStart = offsetToLogicalPosition(offset); + return logicalToVisualPosition(foldStart); + } + else { + offset = outermostCollapsed.getEndOffset() + 3; + } + } + + int line = logicalPos.line; + int column = logicalPos.column; + + line -= myFoldingModel.getFoldedLinesCountBefore(offset); + + FoldRegion[] toplevel = myFoldingModel.fetchTopLevel(); + for (int idx = myFoldingModel.getLastTopLevelIndexBefore(offset); idx >= 0; idx--) { + FoldRegion region = toplevel[idx]; + if (region.isValid()) { + if (region.getDocument().getLineNumber(region.getEndOffset()) == logicalPos.line && + region.getEndOffset() <= offset) { + LogicalPosition foldStart = offsetToLogicalPosition(region.getStartOffset()); + LogicalPosition foldEnd = offsetToLogicalPosition(region.getEndOffset()); + column += foldStart.column + region.getPlaceholderText().length() - foldEnd.column; + offset = region.getStartOffset(); + logicalPos = foldStart; + } + else { + break; + } + } + } + + LOG.assertTrue(line >= 0); + + return new VisualPosition(line, Math.max(0, column)); + } + + private FoldRegion getLastCollapsedBeforePosition(VisualPosition visual) { + FoldRegion[] topLevelCollapsed = myFoldingModel.fetchTopLevel(); + + if (topLevelCollapsed == null) return null; + + int start = 0; + int end = topLevelCollapsed.length - 1; + int i = 0; + + while (start <= end) { + i = (start + end) / 2; + FoldRegion region = topLevelCollapsed[i]; + LogicalPosition logFoldEnd = offsetToLogicalPosition(region.getEndOffset() - 1); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + if (visFoldEnd.line < visual.line) { + start = i + 1; + } + else { + if (visFoldEnd.line > visual.line) { + end = i - 1; + } + else { + if (visFoldEnd.column < visual.column) { + start = i + 1; + } + else { + if (visFoldEnd.column > visual.column) { + end = i - 1; + } + else { + i--; + break; + } + } + } + } + } + + while (i >= 0 && i < topLevelCollapsed.length) { + if (topLevelCollapsed[i].isValid()) break; + i--; + } + + if (i >= 0 && i < topLevelCollapsed.length) { + FoldRegion region = topLevelCollapsed[i]; + LogicalPosition logFoldEnd = offsetToLogicalPosition(region.getEndOffset() - 1); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + if (visFoldEnd.line > visual.line || visFoldEnd.line == visual.line && visFoldEnd.column > visual.column) { + i--; + if (i >= 0) { + return topLevelCollapsed[i]; + } + else { + return null; + } + } + return region; + } + + return null; + } + + public LogicalPosition visualToLogicalPosition(VisualPosition visiblePos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myFoldingModel.isFoldingEnabled()) return new LogicalPosition(visiblePos.line, visiblePos.column); + + int line = visiblePos.line; + int column = visiblePos.column; + + FoldRegion lastCollapsedBefore = getLastCollapsedBeforePosition(visiblePos); + + if (lastCollapsedBefore != null) { + LogicalPosition logFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset()); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + + line = logFoldEnd.line + (visiblePos.line - visFoldEnd.line); + if (visFoldEnd.line == visiblePos.line) { + if (visiblePos.column >= visFoldEnd.column) { + column = logFoldEnd.column + (visiblePos.column - visFoldEnd.column); + } + else { + return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset()); + } + } + } + + if (column < 0) column = 0; + + return new LogicalPosition(line, column); + } + + private int calcLogicalLineNumber(int offset) { + int textLength = myDocument.getTextLength(); + if (textLength == 0) return 0; + + if (offset > textLength || offset < 0) { + throw new IndexOutOfBoundsException("Wrong offset: " + offset + " textLength: " + textLength); + } + + int lineIndex = myDocument.getLineNumber(offset); + + LOG.assertTrue(lineIndex >= 0 && lineIndex < myDocument.getLineCount()); + + return lineIndex; + } + + private int calcColumnNumber(int offset, int lineIndex) { + if (myDocument.getTextLength() == 0) return 0; + + CharSequence text = myDocument.getCharsSequence(); + int start = myDocument.getLineStartOffset(lineIndex); + if (start == offset) return 0; + return EditorUtil.calcColumnNumber(this, text, start, offset, mySettings.getTabSize(myProject)); + } + + private void moveCaretToScreenPos(int x, int y) { + if (x < 0) { + x = 0; + } + + LogicalPosition pos = xyToLogicalPosition(new Point(x, y)); + + int columnNumber = pos.column; + int lineNumber = pos.line; + + if (lineNumber >= myDocument.getLineCount()) { + lineNumber = myDocument.getLineCount() - 1; + } + if (!mySettings.isVirtualSpace()) { + if (lineNumber >= 0) { + int lineEndOffset = myDocument.getLineEndOffset(lineNumber); + int lineEndColumnNumber = calcColumnNumber(lineEndOffset, lineNumber); + if (columnNumber > lineEndColumnNumber) { + columnNumber = lineEndColumnNumber; + } + } + } + if (lineNumber < 0) { + lineNumber = 0; + columnNumber = 0; + } + if (!mySettings.isCaretInsideTabs()) { + int offset = logicalPositionToOffset(new LogicalPosition(lineNumber, columnNumber)); + CharSequence text = myDocument.getCharsSequence(); + if (offset >= 0 && offset < myDocument.getTextLength()) { + if (text.charAt(offset) == '\t') { + columnNumber = calcColumnNumber(offset, lineNumber); + } + } + } + LogicalPosition pos1 = new LogicalPosition(lineNumber, columnNumber); + getCaretModel().moveToLogicalPosition(pos1); + } + + private void runMousePressedCommand(final MouseEvent e) { + myMousePressedEvent = e; + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + + EditorMouseListener[] mouseListeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < mouseListeners.length; i++) { + mouseListeners[i].mousePressed(event); + } + + // On some systems (for example on Linux) popup trigger is MOUSE_PRESSED event. + // But this trigger is always consumed by popup handler. In that case we have to + // also move caret. + if (event.isConsumed() && + !(event.getMouseEvent().isPopupTrigger() || event.getArea() == EditorMouseEventArea.EDITING_AREA)) { + return; + } + + if (myCommandProcessor != null) { + Runnable runnable = new Runnable() { + public void run() { + processMousePressed(e); + } + }; + myCommandProcessor.executeCommand(myProject, runnable, "", null); + } + else { + processMousePressed(e); + } + } + + private void runMouseClickedCommand(final MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseClicked(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void runMouseReleasedCommand(final MouseEvent e) { + myScrollingTimer.stop(); + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseReleased(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + + if (myCommandProcessor != null) { + Runnable runnable = new Runnable() { + public void run() { + processMouseReleased(e); + } + }; + myCommandProcessor.executeCommand(myProject, runnable, "", null); + } + else { + processMouseReleased(e); + } + } + + private void runMouseEnteredCommand(MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseEntered(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void runMouseExitedCommand(MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseExited(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void processMousePressed(MouseEvent e) { + if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && + System.currentTimeMillis() - myMouseSelectionChangeTimestamp > 1000) { + setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + } + + int x = e.getX(); + int y = e.getY(); + + if (x < 0) x = 0; + if (y < 0) y = 0; + + final EditorMouseEventArea eventArea = getMouseEventArea(e); + if (eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA) { + final FoldRegion range = myGutterComponent.findFoldingAnchorAt(x, y); + if (range != null) { + final boolean expansion = !range.isExpanded(); + + int scrollShift = y - getScrollingModel().getVerticalScrollOffset(); + Runnable processor = new Runnable() { + public void run() { + myFoldingModel.flushCaretShift(); + range.setExpanded(expansion); + } + }; + getFoldingModel().runBatchFoldingOperation(processor); + y = myGutterComponent.getHeadCenterY(range); + getScrollingModel().scrollVertically(y - scrollShift); + return; + } + } + + if (e.getSource() == myGutterComponent) { + if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA || + eventArea == EditorMouseEventArea.ANNOTATIONS_AREA) { + myGutterComponent.mousePressed(e); + if (e.isConsumed()) return; + } + x = 0; + } + + int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); + moveCaretToScreenPos(x, y); + + if (e.isPopupTrigger()) return; + + requestFocus(); + + int caretOffset = getCaretModel().getOffset(); + + myMouseSelectedRegion = myFoldingModel.getFoldingPlaceholderAt(new Point(x, y)); + myMousePressedInsideSelection = mySelectionModel.hasSelection() && + caretOffset >= mySelectionModel.getSelectionStart() && + caretOffset <= mySelectionModel.getSelectionEnd(); + + if (!myMousePressedInsideSelection && mySelectionModel.hasBlockSelection()) { + int[] starts = mySelectionModel.getBlockSelectionStarts(); + int[] ends = mySelectionModel.getBlockSelectionEnds(); + for (int i = 0; i < starts.length; i++) { + if (caretOffset >= starts[i] && caretOffset < ends[i]) { + myMousePressedInsideSelection = true; + break; + } + } + } + + if (getMouseEventArea(e) == EditorMouseEventArea.LINE_NUMBERS_AREA && e.getClickCount() == 1) { + mySelectionModel.selectLineAtCaret(); + setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + return; + } + + if (e.isShiftDown() && !e.isControlDown() && !e.isAltDown()) { + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretOffset < mySavedSelectionStart) { + mySelectionModel.setSelection(mySavedSelectionEnd, caretOffset); + } + else { + mySelectionModel.setSelection(mySavedSelectionStart, caretOffset); + } + } + else { + mySelectionModel.setSelection(oldSelectionStart, caretOffset); + } + } + else { + if (!myMousePressedInsideSelection && getSelectionModel().hasSelection()) { + setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + mySelectionModel.setSelection(caretOffset, caretOffset); + } + else { + if (!e.isPopupTrigger()) { + switch (e.getClickCount()) { + case 2: + mySelectionModel.selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords()); + setMouseSelectionState(MOUSE_SELECTION_STATE_WORD_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + getCaretModel().moveToOffset(mySavedSelectionEnd); + break; + + case 3: + mySelectionModel.selectLineAtCaret(); + setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + break; + } + } + } + } + } + + private static boolean isControlKeyDown(MouseEvent mouseEvent) { + return SystemInfo.isMac ? mouseEvent.isMetaDown() : mouseEvent.isControlDown(); + } + + private void processMouseReleased(MouseEvent e) { + if (e.getSource() == myGutterComponent) { + myGutterComponent.mouseReleased(e); + } + + if (getMouseEventArea(e) != EditorMouseEventArea.EDITING_AREA || e.getY() < 0 || e.getX() < 0) { + return; + } + +// if (myMousePressedInsideSelection) getSelectionModel().removeSelection(); + final FoldRegion region = ((FoldingModelEx)getFoldingModel()).getFoldingPlaceholderAt(e.getPoint()); + if (e.getX() >= 0 && e.getY() >= 0 && region != null && region == myMouseSelectedRegion) { + getFoldingModel().runBatchFoldingOperation(new Runnable() { + public void run() { + myFoldingModel.flushCaretShift(); + region.setExpanded(true); + } + }); + } + + if (myMousePressedEvent != null && myMousePressedEvent.getClickCount() == 1 && myMousePressedInsideSelection) { + getSelectionModel().removeSelection(); + } + } + + public DataContext getDataContext() { + return getProjectAwareDataContext(DataManager.getInstance().getDataContext(getContentComponent())); + } + + public DataContext getProjectAwareDataContext(final DataContext original) { + if (original.getData(DataConstants.PROJECT) == myProject) return original; + + return new DataContext() { + public Object getData(String dataId) { + if (DataConstants.PROJECT.equals(dataId)) { + return myProject; + } + return original.getData(dataId); + } + }; + } + + + public EditorMouseEventArea getMouseEventArea(MouseEvent e) { + if (myGutterComponent != e.getSource()) return EditorMouseEventArea.EDITING_AREA; + + int x = myGutterComponent.convertX(e.getX()); + + if (x >= myGutterComponent.getLineNumberAreaOffset() && + x < myGutterComponent.getLineNumberAreaOffset() + myGutterComponent.getLineNumberAreaWidth()) { + return EditorMouseEventArea.LINE_NUMBERS_AREA; + } + + if (x >= myGutterComponent.getAnnotationsAreaOffset() && + x <= myGutterComponent.getAnnotationsAreaOffset() + myGutterComponent.getAnnotationsAreaWidth()) { + return EditorMouseEventArea.ANNOTATIONS_AREA; + } + + if (x >= myGutterComponent.getLineMarkerAreaOffset() && + x < myGutterComponent.getLineMarkerAreaOffset() + myGutterComponent.getLineMarkerAreaWidth()) { + return EditorMouseEventArea.LINE_MARKERS_AREA; + } + + if (x >= myGutterComponent.getFoldingAreaOffset() && + x < myGutterComponent.getFoldingAreaOffset() + myGutterComponent.getFoldingAreaWidth()) { + return EditorMouseEventArea.FOLDING_OUTLINE_AREA; + } + + return null; + } + + private void requestFocus() { + myEditorComponent.requestFocus(); + } + + private void validateMousePointer(MouseEvent e) { + if (e.getSource() == myGutterComponent) { + FoldRegion foldingAtCursor = myGutterComponent.findFoldingAnchorAt(e.getX(), e.getY()); + myGutterComponent.setActiveFoldRegion(foldingAtCursor); + if (foldingAtCursor != null) { + myGutterComponent.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else { + myGutterComponent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + else { + myGutterComponent.setActiveFoldRegion(null); + if (getSelectionModel().hasSelection() && + (e.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK)) == 0) { + int offset = logicalPositionToOffset(xyToLogicalPosition(e.getPoint())); + if (getSelectionModel().getSelectionStart() <= offset && offset < getSelectionModel().getSelectionEnd()) { + myEditorComponent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return; + } + } + myEditorComponent.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } + } + + private void runMouseDraggedCommand(final MouseEvent e) { + if (myCommandProcessor == null || myMousePressedEvent != null && myMousePressedEvent.isConsumed()) { + return; + } + myCommandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + processMouseDragged(e); + } + }, "", MOUSE_DRAGGED_GROUP); + } + + private void processMouseDragged(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + return; + } + Rectangle rect = getScrollingModel().getVisibleArea(); + + int dx = 0; + int x = e.getX(); + + if (e.getSource() == myGutterComponent) { + x = 0; + } + + if (x < rect.x) { + dx = x - rect.x; + } + else { + if (x > rect.x + rect.width) { + dx = x - rect.x - rect.width; + } + } + + int dy = 0; + int y = e.getY(); + if (y < rect.y) { + dy = y - rect.y; + } + else { + if (y > rect.y + rect.height) { + dy = y - rect.y - rect.height; + } + } + if (dx == 0 && dy == 0) { + myScrollingTimer.stop(); + + SelectionModel selectionModel = getSelectionModel(); + int oldSelectionStart = selectionModel.getLeadSelectionOffset(); + int oldCaretOffset = getCaretModel().getOffset(); + LogicalPosition oldLogicalCaret = getCaretModel().getLogicalPosition(); + moveCaretToScreenPos(x, y); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + int newCaretOffset = getCaretModel().getOffset(); + int caretShift = newCaretOffset - mySavedSelectionStart; + + if (myMousePressedEvent != null && + getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.EDITING_AREA && + getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.LINE_NUMBERS_AREA) { + selectionModel.setSelection(oldSelectionStart, newCaretOffset); + } + else { + if (isColumnMode()) { + final LogicalPosition blockStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : oldLogicalCaret; + selectionModel.setBlockSelection(blockStart, getCaretModel().getLogicalPosition()); + } + else { + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretShift < 0) { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretStart(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset( + visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + selectionModel.setSelection(mySavedSelectionEnd, newSelection); + getCaretModel().moveToOffset(newSelection); + } + else { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretEnd(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset( + visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + selectionModel.setSelection(mySavedSelectionStart, newSelection); + getCaretModel().moveToOffset(newSelection); + } + return; + } + + if (!myMousePressedInsideSelection) { + selectionModel.setSelection(oldSelectionStart, newCaretOffset); + } + else { + if (caretShift != 0) { + if (myMousePressedEvent != null) { + if (mySettings.isDndEnabled()) { + boolean isCopy = isControlKeyDown(e) || isViewer() || !getDocument().isWritable(); + mySavedCaretOffsetForDNDUndoHack = oldCaretOffset; + getContentComponent().getTransferHandler().exportAsDrag(getContentComponent(), e, + isCopy + ? TransferHandler.COPY + : TransferHandler.MOVE); + } + else { + selectionModel.removeSelection(); + } + myMousePressedEvent = null; + } + } + } + } + } + } + else { + myScrollingTimer.start(dx, dy); + } + } + + private static class RepaintCursorThread extends Thread { + private long mySleepTime = 500; + private boolean myIsBlinkCaret = true; + private EditorImpl myEditor = null; + private boolean isStopped = false; + private MyRepaintRunnable myRepaintRunnable; + + public RepaintCursorThread() { + super("EditorCaretThread"); + myRepaintRunnable = new MyRepaintRunnable(); + } + + private class MyRepaintRunnable implements Runnable { + public void run() { + if (myEditor != null) { + myEditor.myCaretCursor.repaint(); + } + } + } + + public void setBlinkPeriod(int blinkPeriod) { + mySleepTime = blinkPeriod > 10 ? blinkPeriod : 10; + } + + public void setBlinkCaret(boolean value) { + myIsBlinkCaret = value; + } + + public synchronized void stopThread() { + isStopped = true; + } + + public void run() { + while (true) { + try { + Thread.sleep(myIsBlinkCaret ? mySleepTime : 1000); + } + catch (InterruptedException e) { + } + + synchronized (this) { + if (isStopped) { + break; + } + } + + if (myEditor == null) { + continue; + } + CaretCursor activeCursor = myEditor.myCaretCursor; + + long time = System.currentTimeMillis(); + time -= activeCursor.myStartTime; + + if (time > mySleepTime) { + boolean toRepaint = true; + if (myIsBlinkCaret) { + activeCursor.isVisible = !activeCursor.isVisible; + } + else { + + toRepaint = !activeCursor.isVisible; + activeCursor.isVisible = true; + } + + if (toRepaint) { + SwingUtilities.invokeLater(myRepaintRunnable); + } + } + } + } + } + + void updateCaretCursor() { + if (!IJSwingUtilities.hasFocus(getContentComponent())) { + stopOptimizedScrolling(); + } + + if (myCursorUpdater == null) { + myCursorUpdater = new Runnable() { + public void run() { + if (myCursorUpdater == null) return; + myCursorUpdater = null; + + if (getDocument().getMarkupModel(myProject) == null) return; + + VisualPosition caretPosition = getCaretModel().getVisualPosition(); + Point pos1 = visualPositionToXY(caretPosition); + Point pos2 = visualPositionToXY(new VisualPosition(caretPosition.line, caretPosition.column + 1)); + myCaretCursor.setPosition(pos1, pos2.x - pos1.x); + } + }; + } + } + + public void setCaretVisible(boolean b) { + if (b) { + myCaretCursor.activate(); + } + else { + myCaretCursor.passivate(); + } + } + + public void addFocusListener(FocusChangeListener listener) { + myFocusListeners.add(listener); + } + + public Project getProject() { + return myProject; + } + + public boolean isOneLineMode() { + return myIsOneLineMode; + } + + public void setOneLineMode(boolean isOneLineMode) { + myIsOneLineMode = isOneLineMode; + getScrollPane().setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + reinitSettings(); + } + + public void stopOptimizedScrolling() { + if (SystemInfo.isMac) return; + myEditorComponent.setOpaque(false); + } + + private void startOptimizedScrolling() { + if (SystemInfo.isMac) return; + myEditorComponent.setOpaque(true); + } + + private class CaretCursor { + private Point myLocation; + private int myWidth; + private boolean isVisible = true; + private long myStartTime = 0; + + public CaretCursor() { + myLocation = new Point(0, 0); + } + + public void activate() { + synchronized (ourCaretThread) { + ourCaretThread.myEditor = EditorImpl.this; + ourCaretThread.setBlinkCaret(mySettings.isBlinkCaret()); + ourCaretThread.setBlinkPeriod(mySettings.getCaretBlinkPeriod()); + isVisible = true; + } + } + + public void passivate() { + synchronized (ourCaretThread) { + isVisible = false; + } + } + + public void setPosition(Point location, int width) { + myStartTime = System.currentTimeMillis(); + myLocation = location; + isVisible = true; + myWidth = Math.max(width, 2); + repaint(); + } + + private void repaint() { + myEditorComponent.repaintEditorComponent(myLocation.x, + myLocation.y, + myWidth, + getLineHeight()); + } + + public void paint(Graphics g) { + if (!isVisible || !IJSwingUtilities.hasFocus(getContentComponent()) || isRendererMode()) return; + + int x = myLocation.x; + int lineHeight = getLineHeight(); + int y = myLocation.y; + + Rectangle viewRect = getScrollingModel().getVisibleArea(); + if (x - viewRect.x < 0) { + return; + } + + + g.setColor(myScheme.getColor(EditorColors.CARET_COLOR)); + if (!SystemInfo.isMac) { + Color background = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + if (background == null) background = getBackroundColor(); + g.setXORMode(background != null ? background : Color.white); + } + + if (EditorImpl.this.myIsInsertMode != mySettings.isBlockCursor()) { + for (int i = 0; i < mySettings.getLineCursorWidth(); i++) { + g.drawLine(x + i, y, x + i, y + lineHeight - 1); + } + } + else { + g.fillRect(x, y, myWidth, lineHeight - 1); + } + + g.setPaintMode(); + } + } + + private class ScrollingTimer { + Timer myTimer; + private static final int TIMER_PERIOD = 100; + private static final int CYCLE_SIZE = 20; + private int myXCycles; + private int myYCycles; + private int myDx; + private int myDy; + private int xPassedCycles = 0; + private int yPassedCycles = 0; + + public void start(int dx, int dy) { + myDx = 0; + myDy = 0; + if (dx > 0) { + myXCycles = CYCLE_SIZE / dx + 1; + myDx = 1 + dx / CYCLE_SIZE; + } + else { + if (dx < 0) { + myXCycles = -CYCLE_SIZE / dx + 1; + myDx = -1 + dx / CYCLE_SIZE; + } + } + + if (dy > 0) { + myYCycles = CYCLE_SIZE / dy + 1; + myDy = 1 + dy / CYCLE_SIZE; + } + else { + if (dy < 0) { + myYCycles = -CYCLE_SIZE / dy + 1; + myDy = -1 + dy / CYCLE_SIZE; + } + } + + if (myTimer != null) { + return; + } + myTimer = new Timer(TIMER_PERIOD, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myCommandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); + LogicalPosition caretPosition = getCaretModel().getLogicalPosition(); + int columnNumber = caretPosition.column; + xPassedCycles++; + if (xPassedCycles >= myXCycles) { + xPassedCycles = 0; + columnNumber += myDx; + } + + int lineNumber = caretPosition.line; + yPassedCycles++; + if (yPassedCycles >= myYCycles) { + yPassedCycles = 0; + lineNumber += myDy; + } + + LogicalPosition pos = new LogicalPosition(lineNumber, columnNumber); + getCaretModel().moveToLogicalPosition(pos); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + int newCaretOffset = getCaretModel().getOffset(); + int caretShift = newCaretOffset - mySavedSelectionStart; + + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretShift < 0) { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretStart(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset(visualToLogicalPosition( + new VisualPosition(getCaretModel().getVisualPosition().line, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + mySelectionModel.setSelection(mySavedSelectionEnd, newSelection); + getCaretModel().moveToOffset(newSelection); + } + else { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretEnd(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset(visualToLogicalPosition( + new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + mySelectionModel.setSelection(mySavedSelectionStart, newSelection); + getCaretModel().moveToOffset(newSelection); + } + return; + } + + if (mySelectionModel.hasBlockSelection()) { + mySelectionModel.setBlockSelection(mySelectionModel.getBlockStart(), + getCaretModel().getLogicalPosition()); + } + else { + mySelectionModel.setSelection(oldSelectionStart, getCaretModel().getOffset()); + } + } + }, + "Move Cursor", null); + } + }); + myTimer.start(); + } + + public void stop() { + if (myTimer != null) { + myTimer.stop(); + myTimer = null; + } + } + + } + + class MyScrollBar extends JScrollBar { + + public MyScrollBar(int orientation) { + super(orientation); + } + + /** + * This is helper method. It returns height of the top (descrease) scrollbar + * button. Please note, that it's possible to return real height only if scrollbar + * is instance of BasicScrollBarUI. Otherwise it returns fake (but good enough :) ) + * value. + */ + int getDecScrollButtonHeight() { + ScrollBarUI ui = getUI(); + Insets insets = getInsets(); + if (ui instanceof BasicScrollBarUI) { + try { + Field decrButtonField = BasicScrollBarUI.class.getDeclaredField("decrButton"); + decrButtonField.setAccessible(true); + JButton decrButtonValue = (JButton)decrButtonField.get(ui); + LOG.assertTrue(decrButtonValue != null); + return insets.top + decrButtonValue.getHeight(); + } + catch (Exception exc) { + exc.printStackTrace(); + throw new IllegalStateException(exc.getMessage()); + } + } + else { + return insets.top + 15; + } + } + + /** + * This is helper method. It returns height of the bottom (increase) scrollbar + * button. Please note, that it's possible to return real height only if scrollbar + * is instance of BasicScrollBarUI. Otherwise it returns fake (but good enough :) ) + * value. + */ + int getIncScrollButtonHeight() { + ScrollBarUI ui = getUI(); + Insets insets = getInsets(); + if (ui instanceof BasicScrollBarUI) { + try { + Field incrButtonField = BasicScrollBarUI.class.getDeclaredField("incrButton"); + incrButtonField.setAccessible(true); + JButton incrButtonValue = (JButton)incrButtonField.get(ui); + LOG.assertTrue(incrButtonValue != null); + return insets.bottom + incrButtonValue.getHeight(); + } + catch (Exception exc) { + exc.printStackTrace(); + throw new IllegalStateException(exc.getMessage()); + } + } + else if ("apple.laf.AquaScrollBarUI".equals(ui.getClass().getName())) { + return insets.bottom + 30; + } + else { + return insets.bottom + 15; + } + } + + public int getUnitIncrement(int direction) { + JViewport vp = myScrollPane.getViewport(); + Rectangle vr = vp.getViewRect(); + return myEditorComponent.getScrollableUnitIncrement(vr, SwingConstants.VERTICAL, direction); + } + + public int getBlockIncrement(int direction) { + JViewport vp = myScrollPane.getViewport(); + Rectangle vr = vp.getViewRect(); + return myEditorComponent.getScrollableBlockIncrement(vr, SwingConstants.VERTICAL, direction); + } + } + + private MyEditable getViewer() { + if (myEditable == null) { + myEditable = new MyEditable(); + } + return myEditable; + } + + public CopyProvider getCopyProvider() { + return getViewer(); + } + + public CutProvider getCutProvider() { + return getViewer(); + } + + public PasteProvider getPasteProvider() { + + return getViewer(); + } + + public DeleteProvider getDeleteProvider() { + return getViewer(); + } + + private class MyEditable implements CutProvider, CopyProvider, PasteProvider, DeleteProvider { + public void performCopy(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_COPY, dataContext); + } + + public boolean isCopyEnabled(DataContext dataContext) { + return true; + } + + public void performCut(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_CUT, dataContext); + } + + public boolean isCutEnabled(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + public void performPaste(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_PASTE, dataContext); + } + + public boolean isPastePossible(DataContext dataContext) { + // Copy of isPasteEnabled. See interface method javadoc. + return !isViewer() && getDocument().isWritable(); + } + + public boolean isPasteEnabled(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + public void deleteElement(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_DELETE, dataContext); + } + + public boolean canDeleteElement(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + private void executeAction(String actionId, DataContext dataContext) { + EditorAction action = (EditorAction)ActionManager.getInstance().getAction(actionId); + if (action != null) { + action.actionPerformed(EditorImpl.this, dataContext); + } + } + } + + public void setColorsScheme(EditorColorsScheme scheme) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myScheme = scheme; + reinitSettings(); + } + + public EditorColorsScheme getColorsScheme() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myScheme; + } + + public void setVerticalScrollbarOrientation(int type) { + ApplicationManager.getApplication().assertIsDispatchThread(); + int currentHorOffset = myScrollingModel.getHorizontalScrollOffset(); + myScrollbarOrientation = type; + if (type == EditorEx.VERTICAL_SCROLLBAR_LEFT) { + myScrollPane.setLayout(new LeftHandScrollbarLayout()); + } + else { + myScrollPane.setLayout(new ScrollPaneLayout()); + } + myScrollingModel.scrollHorizontally(currentHorOffset); + } + + public void setVerticalScrollbarVisible(boolean b) { + if (b) { + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + } + else { + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + } + } + + public void setHorizontalScrollbarVisible(boolean b) { + if (b) { + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + } + else { + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + } + } + + public int getVerticalScrollbarOrientation() { + return myScrollbarOrientation; + } + + public MyScrollBar getVerticalScrollBar() { + return myVerticalScrollBar; + } + + public JPanel getPanel() { + return myPanel; + } + + private int getMouseSelectionState() { + return myMouseSelectionState; + } + + private void setMouseSelectionState(int mouseSelectionState) { + myMouseSelectionState = mouseSelectionState; + myMouseSelectionChangeTimestamp = System.currentTimeMillis(); + } + + + public void replaceInputMethodText(InputMethodEvent e) { + getInputMethodRequests(); + myInputMethodRequestsHandler.replaceInputMethodText(e); + } + + public void inputMethodCaretPositionChanged(InputMethodEvent e) { + getInputMethodRequests(); + myInputMethodRequestsHandler.setInputMethodCaretPosition(e); + } + + public InputMethodRequests getInputMethodRequests() { + if (myInputMethodRequestsHandler == null) { + myInputMethodRequestsHandler = new MyInputMethodHandler(); + myInputMethodRequestsSwingWrapper = new MyInputMethodHandleSwingThreadWrapper(myInputMethodRequestsHandler); + } + return myInputMethodRequestsSwingWrapper; + } + + public boolean processKeyTyped(KeyEvent e) { + if (e.getID() != KeyEvent.KEY_TYPED) return false; + char c = e.getKeyChar(); + if (isReallyTypedEvent(e) && c >= 0x20 && c != 0x7F) { // Hack just like in javax.swing.text.DefaultEditorKit.DefaultKeyTypedAction + processKeyTyped(c); + return true; + } + else { + return false; + } + } + + private static boolean isReallyTypedEvent(KeyEvent e) { + int modifiers = e.getModifiers(); + if (SystemInfo.isMac) { + return !e.isMetaDown() && !e.isControlDown(); + } + + return (modifiers & ActionEvent.ALT_MASK) == (modifiers & ActionEvent.CTRL_MASK); + } + + public void beforeModalityStateChanged() { + myScrollingModel.beforeModalityStateChanged(); + } + + private static class MyInputMethodHandleSwingThreadWrapper implements InputMethodRequests { + private InputMethodRequests myDelegate; + + public MyInputMethodHandleSwingThreadWrapper(InputMethodRequests delegate) { + myDelegate = delegate; + } + + public Rectangle getTextLocation(final TextHitInfo offset) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getTextLocation(offset); + + final Rectangle[] r = new Rectangle[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getTextLocation(offset); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public TextHitInfo getLocationOffset(final int x, final int y) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getLocationOffset(x, y); + + final TextHitInfo[] r = new TextHitInfo[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getLocationOffset(x, y); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public int getInsertPositionOffset() { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getInsertPositionOffset(); + + final int[] r = new int[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getInsertPositionOffset(); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public AttributedCharacterIterator getCommittedText(final int beginIndex, final int endIndex, + final AttributedCharacterIterator.Attribute[] attributes) { + if (ApplicationManager.getApplication().isDispatchThread()) { + return myDelegate.getCommittedText(beginIndex, + endIndex, + attributes); + } + final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getCommittedText(beginIndex, endIndex, attributes); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public int getCommittedTextLength() { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getCommittedTextLength(); + final int[] r = new int[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getCommittedTextLength(); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes) { + return null; + } + + public AttributedCharacterIterator getSelectedText(final AttributedCharacterIterator.Attribute[] attributes) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getSelectedText(attributes); + + final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getSelectedText(attributes); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + } + + private class MyInputMethodHandler implements InputMethodRequests { + private String composedText; + private int composedTextStart; + private int composedTextEnd; + + public Rectangle getTextLocation(TextHitInfo offset) { + Point caret = logicalPositionToXY(getCaretModel().getLogicalPosition()); + Rectangle r = new Rectangle(caret, new Dimension(1, getLineHeight())); + Point p = getContentComponent().getLocationOnScreen(); + r.translate(p.x, p.y); + + return r; + } + + public TextHitInfo getLocationOffset(int x, int y) { + if (composedText != null) { + Point p = getContentComponent().getLocationOnScreen(); + p.x = x - p.x; + p.y = y - p.y; + int pos = logicalPositionToOffset(xyToLogicalPosition(p)); + if (pos >= composedTextStart && pos <= composedTextEnd) { + return TextHitInfo.leading(pos - composedTextStart); + } + } + return null; + } + + public int getInsertPositionOffset() { + int composedStartIndex = 0; + int composedEndIndex = 0; + if (composedText != null) { + composedStartIndex = composedTextStart; + composedEndIndex = composedTextEnd; + } + + int caretIndex = getCaretModel().getOffset(); + + if (caretIndex < composedStartIndex) { + return caretIndex; + } + else { + if (caretIndex < composedEndIndex) { + return composedStartIndex; + } + else { + return caretIndex - (composedEndIndex - composedStartIndex); + } + } + } + + private String getText(int startIdx, int endIdx) { + CharSequence chars = getDocument().getCharsSequence(); + return chars.subSequence(startIdx, endIdx).toString(); + } + + public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, + AttributedCharacterIterator.Attribute[] attributes) { + int composedStartIndex = 0; + int composedEndIndex = 0; + if (composedText != null) { + composedStartIndex = composedTextStart; + composedEndIndex = composedTextEnd; + } + + String committed; + if (beginIndex < composedStartIndex) { + if (endIndex <= composedStartIndex) { + committed = getText(beginIndex, endIndex - beginIndex); + } + else { + int firstPartLength = composedStartIndex - beginIndex; + committed = getText(beginIndex, firstPartLength) + + getText(composedEndIndex, endIndex - beginIndex - firstPartLength); + } + } + else { + committed = getText(beginIndex + (composedEndIndex - composedStartIndex), + endIndex - beginIndex); + } + + return new AttributedString(committed).getIterator(); + } + + public int getCommittedTextLength() { + int length = getDocument().getTextLength(); + if (composedText != null) { + length -= composedText.length(); + } + return length; + } + + public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes) { + return null; + } + + public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes) { + String text = getSelectionModel().getSelectedText(); + return text == null ? null : new AttributedString(text).getIterator(); + } + + private void createComposedString(int composedIndex, AttributedCharacterIterator text) { + StringBuffer strBuf = new StringBuffer(); + + // create attributed string with no attributes + for (char c = text.setIndex(composedIndex); + c != CharacterIterator.DONE; c = text.next()) { + strBuf.append(c); + } + + composedText = new String(strBuf); + } + + private void setInputMethodCaretPosition(InputMethodEvent e) { + if (composedText != null) { + int dot; + dot = composedTextStart; + + TextHitInfo caretPos = e.getCaret(); + if (caretPos != null) { + int index = caretPos.getInsertionIndex(); + dot += index; + } + + getCaretModel().moveToOffset(dot); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + } + + private void runUndoTransparent(final Runnable runnable) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, "", null); + } + }); + } + + private void replaceInputMethodText(InputMethodEvent e) { + int commitCount = e.getCommittedCharacterCount(); + AttributedCharacterIterator text = e.getText(); + int composedTextIndex; + + // old composed text deletion + final Document doc = getDocument(); + + if (composedText != null) { + if (!isViewer() && doc.isWritable()) { + runUndoTransparent(new Runnable() { + public void run() { + doc.deleteString(Math.max(0, composedTextStart), Math.min(composedTextEnd, doc.getTextLength())); + } + }); + } + composedText = null; + } + + if (text != null) { + text.first(); + + // committed text insertion + if (commitCount > 0) { + for (char c = text.current(); commitCount > 0; c = text.next(), commitCount--) { + if (c >= 0x20 && c != 0x7F) { // Hack just like in javax.swing.text.DefaultEditorKit.DefaultKeyTypedAction + processKeyTyped(c); + } + } + } + + // new composed text insertion + if (!isViewer() && doc.isWritable()) { + composedTextIndex = text.getIndex(); + if (composedTextIndex < text.getEndIndex()) { + createComposedString(composedTextIndex, text); + + runUndoTransparent(new Runnable() { + public void run() { + EditorModificationUtil.insertStringAtCaret(EditorImpl.this, composedText, false, false); + } + }); + + composedTextStart = getCaretModel().getOffset(); + composedTextEnd = getCaretModel().getOffset() + composedText.length(); + } + } + } + } + } + + private class MyMouseAdapter extends MouseAdapter { + public void mousePressed(MouseEvent e) { + runMousePressedCommand(e); + } + + public void mouseReleased(MouseEvent e) { + runMouseReleasedCommand(e); + if (!e.isConsumed() && myMousePressedEvent != null && !myMousePressedEvent.isConsumed() && + Math.abs(e.getX() - myMousePressedEvent.getX()) < getSpaceWidth(Font.PLAIN) && + Math.abs(e.getY() - myMousePressedEvent.getY()) < getLineHeight()) { + runMouseClickedCommand(e); + } + myMousePressedEvent = null; + } + + public void mouseEntered(MouseEvent e) { + runMouseEnteredCommand(e); + } + + public void mouseExited(MouseEvent e) { + runMouseExitedCommand(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { + myGutterComponent.mouseExited(e); + } + + HintManager.getInstance().getTooltipController().cancelTooltip(FOLDING_TOOLTIP_GROUP); + } + } + + private static final TooltipGroup FOLDING_TOOLTIP_GROUP = new TooltipGroup("FOLDING_TOOLTIP_GROUP", 10); + + private class MyMouseMotionListener implements MouseMotionListener { + public void mouseDragged(MouseEvent e) { + validateMousePointer(e); + runMouseDraggedCommand(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { + myGutterComponent.mouseDragged(e); + } + + EditorMouseMotionListener[] listeners = myMouseMotionListeners.toArray( + new EditorMouseMotionListener[myMouseMotionListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseDragged(event); + } + } + + public void mouseMoved(MouseEvent e) { + validateMousePointer(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (e.getSource() == myGutterComponent) { + myGutterComponent.mouseMoved(e); + } + + if (event.getArea() == EditorMouseEventArea.EDITING_AREA) { + FoldRegion fold = myFoldingModel.getFoldingPlaceholderAt(e.getPoint()); + TooltipController controller = HintManager.getInstance().getTooltipController(); + if (fold != null) { + DocumentFragment range = new DocumentFragment(myDocument, fold.getStartOffset(), fold.getEndOffset()); + final Point p = SwingUtilities.convertPoint((Component)e.getSource(), + e.getPoint(), + getComponent().getRootPane().getLayeredPane()); + controller.showTooltip(EditorImpl.this, p, range, false, FOLDING_TOOLTIP_GROUP); + } + else { + controller.cancelTooltip(FOLDING_TOOLTIP_GROUP); + } + } + + EditorMouseMotionListener[] listeners = myMouseMotionListeners.toArray( + new EditorMouseMotionListener[myMouseMotionListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseMoved(event); + } + } + } + + private class MyColorSchemeDelegate implements EditorColorsScheme { + private HashMap myOwnAttributes = new HashMap(); + private HashMap myOwnColors = new HashMap(); + private HashMap myFontsMap = null; + private Integer myFontSize = null; + private String myFaceName = null; + + + private EditorColorsScheme getGlobal() { + return EditorColorsManager.getInstance().getGlobalScheme(); + } + + public String getName() { + return getGlobal().getName(); + } + + protected void initFonts() { + String editorFontName = getEditorFontName(); + int editorFontSize = getEditorFontSize(); + + myFontsMap = new HashMap(); + + Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize); + Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize); + Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize); + Font boldItalicFont = new Font(editorFontName, Font.BOLD + Font.ITALIC, editorFontSize); + + myFontsMap.put(EditorFontType.PLAIN, plainFont); + myFontsMap.put(EditorFontType.BOLD, boldFont); + myFontsMap.put(EditorFontType.ITALIC, italicFont); + myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont); + + reinitSettings(); + } + + public void setName(String name) { + getGlobal().setName(name); + } + + public TextAttributes getAttributes(TextAttributesKey key) { + if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key); + return getGlobal().getAttributes(key); + } + + public void setAttributes(TextAttributesKey key, TextAttributes attributes) { + myOwnAttributes.put(key, attributes); + } + + public Color getColor(ColorKey key) { + if (myOwnColors.containsKey(key)) return myOwnColors.get(key); + return getGlobal().getColor(key); + } + + public void setColor(ColorKey key, Color color) { + myOwnColors.put(key, color); + + // These two are here because those attributes are cached and I do not whant the clients to call editor's reinit + // settings in this case. + myCaretModel.reinitSettings(); + mySelectionModel.reinitSettings(); + } + + public int getEditorFontSize() { + if (myFontSize != null) return myFontSize.intValue(); + return getGlobal().getEditorFontSize(); + } + + public void setEditorFontSize(int fontSize) { + if (fontSize < 8) fontSize = 8; + if (fontSize > 20) fontSize = 20; + myFontSize = new Integer(fontSize); + initFonts(); + } + + public String getEditorFontName() { + if (myFaceName != null) return myFaceName; + return getGlobal().getEditorFontName(); + } + + public void setEditorFontName(String fontName) { + myFaceName = fontName; + initFonts(); + } + + public Font getFont(EditorFontType key) { + if (myFontsMap != null) { + Font font = myFontsMap.get(key); + if (font != null) return font; + } + return getGlobal().getFont(key); + } + + public void setFont(EditorFontType key, Font font) { + if (myFontsMap == null) { + initFonts(); + } + myFontsMap.put(key, font); + reinitSettings(); + } + + public float getLineSpacing() { + return getGlobal().getLineSpacing(); + } + + public void setLineSpacing(float lineSpacing) { + getGlobal().setLineSpacing(lineSpacing); + } + + public Object clone() { + return null; + } + + public void readExternal(Element element) throws InvalidDataException { + } + + public void writeExternal(Element element) throws WriteExternalException { + } + } + + private static class MyTransferHandler extends TransferHandler { + private RangeMarker myDraggedRange = null; + + private static Editor getEditor(JComponent comp) { + EditorComponentImpl editorComponent = (EditorComponentImpl)comp; + return editorComponent.getEditor(); + } + + public boolean importData(final JComponent comp, final Transferable t) { + final EditorImpl editor = (EditorImpl)getEditor(comp); + + final int caretOffset = editor.getCaretModel().getOffset(); + if (myDraggedRange != null && + myDraggedRange.getStartOffset() <= caretOffset && + caretOffset < myDraggedRange.getEndOffset()) { + return false; + } + + if (myDraggedRange != null) { + editor.getCaretModel().moveToOffset(editor.mySavedCaretOffsetForDNDUndoHack); + } + + CommandProcessor.getInstance().executeCommand(editor.myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + final int offset; + editor.getSelectionModel().removeSelection(); + if (myDraggedRange != null) { + editor.getCaretModel().moveToOffset(caretOffset); + offset = caretOffset; + } + else { + offset = editor.getCaretModel().getOffset(); + } + if (editor.getDocument().getRangeGuard(offset, offset) != null) return; + + EditorActionHandler pasteHandler = EditorActionManager.getInstance().getActionHandler( + IdeActions.ACTION_EDITOR_PASTE); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + Transferable backup = clipboard.getContents(this); + ClipboardOwner clipboardOwner = new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, Transferable contents) { + } + }; + clipboard.setContents(t, clipboardOwner); + + editor.putUserData(LAST_PASTED_REGION, null); + pasteHandler.execute(editor, editor.getDataContext()); + clipboard.setContents(backup, clipboardOwner); + + TextRange range = editor.getUserData(LAST_PASTED_REGION); + if (range != null) { + editor.getCaretModel().moveToOffset(range.getStartOffset()); + editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + } + } + catch (Exception exception) { + LOG.error(exception); + } + } + }); + } + }, "Paste", DND_COMMAND_KEY); + + return true; + } + + public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { + Editor editor = getEditor(comp); + if (editor.isViewer()) return false; + if (!editor.getDocument().isWritable()) return false; + + int offset = editor.getCaretModel().getOffset(); + if (editor.getDocument().getRangeGuard(offset, offset) != null) return false; + + for (int i = 0; i < transferFlavors.length; i++) { + DataFlavor transferFlavor = transferFlavors[i]; + if (transferFlavor.equals(DataFlavor.stringFlavor)) return true; + } + + return false; + } + + protected Transferable createTransferable(JComponent c) { + Editor editor = getEditor(c); + String s = editor.getSelectionModel().getSelectedText(); + if (s == null) return null; + int selectionStart = editor.getSelectionModel().getSelectionStart(); + int selectionEnd = editor.getSelectionModel().getSelectionEnd(); + myDraggedRange = editor.getDocument().createRangeMarker(selectionStart, selectionEnd); + + return new StringSelection(s); + } + + public int getSourceActions(JComponent c) { + return COPY_OR_MOVE; + } + + protected void exportDone(final JComponent source, Transferable data, int action) { + if (data == null) return; + + if (action == MOVE && !getEditor(source).isViewer() && getEditor(source).getDocument().isWritable()) { + CommandProcessor.getInstance().executeCommand(((EditorImpl)getEditor(source)).myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + Document doc = getEditor(source).getDocument(); + doc.startGuardedBlockChecking(); + try { + doc.deleteString(myDraggedRange.getStartOffset(), myDraggedRange.getEndOffset()); + } + catch (ReadOnlyFragmentModificationException e) { + EditorActionManager.getInstance().getReadonlyFragmentModificationHandler().handle(e); + } + finally { + doc.stopGuardedBlockChecking(); + } + } + }); + } + }, "Move selection", DND_COMMAND_KEY); + } + + myDraggedRange = null; + } + } + + class EditorDocumentAdapter extends DocumentAdapter { + public void beforeDocumentChange(DocumentEvent e) { + beforeChangedUpdate(e); + } + + public void documentChanged(DocumentEvent e) { + changedUpdate(e); + } + } + + private class EditorSizeContainer { + private TIntArrayList myLineWidths; + private boolean myIsDirty; + private int myOldEndLine; + private Dimension mySize; + + public void reset() { + int visLinesCount = getVisibleLineCount(); + myLineWidths = new TIntArrayList(visLinesCount + 300); + int[] values = new int[visLinesCount]; + Arrays.fill(values, -1); + myLineWidths.add(values); + myIsDirty = true; + } + + public void beforeChange(DocumentEvent e) { + myOldEndLine = offsetToVisualPosition(e.getOffset() + e.getOldLength()).line; + } + + public void changedUpdate(DocumentEvent e) { + int startLine = offsetToVisualPosition(e.getOffset()).line; + int newEndLine = offsetToVisualPosition(e.getOffset() + e.getNewLength()).line; + int oldEndLine = myOldEndLine; + + if (myLineWidths.size() == 0) { + reset(); + } + else { + int min = Math.min(oldEndLine, newEndLine); + for (int i = startLine; i <= min; i++) myLineWidths.set(i, -1); + if (newEndLine > oldEndLine) { + int[] delta = new int[newEndLine - oldEndLine]; + Arrays.fill(delta, -1); + myLineWidths.insert(oldEndLine + 1, delta); + } + else if (oldEndLine > newEndLine) { + myLineWidths.remove(newEndLine + 1, oldEndLine - newEndLine); + } + myIsDirty = true; + } + } + + private void validateSizes() { + if (!myIsDirty) return; + + CharSequence text = myDocument.getCharsNoThreadCheck(); + int lineCount = myLineWidths.size(); + int end = myDocument.getTextLength(); + int x = 0; + for (int line = 0; line < lineCount; line++) { + if (myLineWidths.getQuick(line) != -1) continue; + x = 0; + int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0))); + + if (offset >= myDocument.getTextLength()) { + myLineWidths.set(line, 0); + break; + } + + IterationState state = new IterationState(EditorImpl.this, offset, false); + int fontType = state.getMergedAttributes().getFontType(); + + while (offset < end) { + char c = text.charAt(offset); + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion collapsed = state.getCurrentFold(); + if (collapsed != null) { + String placeholder = collapsed.getPlaceholderText(); + for (int i = 0; i < placeholder.length(); i++) { + x += charWidth(fontType, placeholder.charAt(i)); + } + offset = collapsed.getEndOffset(); + } + else { + if (c == '\t') { + x = nextTabStop(x); + offset++; + } + else { + if (c == '\n') { + myLineWidths.set(line, x); + if (line + 1 >= lineCount || myLineWidths.getQuick(line + 1) != -1) break; + offset++; + x = 0; + line++; + } + else { + x += charWidth(fontType, c); + offset++; + } + } + } + } + } + + if (lineCount > 0) { + myLineWidths.set(lineCount - 1, x); // Last line can be non-zero length and won't be caught by in-loop procedure since latter only react on \n's + } + + int maxWidth = 0; + for (int i = 0; i < lineCount; i++) { + maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i)); + } + + mySize = new Dimension(maxWidth, getLineHeight() * lineCount); + + myIsDirty = false; + } + + public Dimension getContentSize() { + validateSizes(); + return mySize; + } + } + + public EditorGutter getGutter() { + return getGutterComponentEx(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java new file mode 100644 index 00000000000..2c462b5a266 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java @@ -0,0 +1,412 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Apr 19, 2002 + * Time: 2:56:43 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.HighlightInfoComposite; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.TooltipGroup; +import com.intellij.codeInsight.hint.TooltipController; +import com.intellij.ide.ui.LafManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.ApplicationImpl; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ScrollingModel; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.editor.ex.ErrorStripeEvent; +import com.intellij.openapi.editor.ex.ErrorStripeListener; +import com.intellij.openapi.editor.markup.ErrorStripeRenderer; +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.RangeHighlighter; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMarkupModel { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorMarkupModelImpl"); + + private static final TooltipGroup ERROR_STRIPE_TOOLTIP_GROUP = new TooltipGroup("ERROR_STRIPE_TOOLTIP_GROUP", 0); + + private EditorImpl myEditor; + private MyErrorPanel myErrorPanel; + private ErrorStripeRenderer myErrorStripeRenderer = null; + private ArrayList myErrorMarkerListeners = new ArrayList(); + private ErrorStripeListener[] myCachedErrorMarkerListeners = null; + private ArrayList myCachedSortedHighlighters = null; + + EditorMarkupModelImpl(EditorImpl editor) { + super((DocumentImpl)editor.getDocument()); + myEditor = editor; + } + + public void setErrorStripeVisible(boolean val) { + if (val) { + myErrorPanel = new MyErrorPanel(); + myEditor.getPanel().add(myErrorPanel, + myEditor.getVerticalScrollbarOrientation() == EditorEx.VERTICAL_SCROLLBAR_LEFT + ? BorderLayout.WEST + : BorderLayout.EAST); + } + else if (myErrorPanel != null) { + myEditor.getPanel().remove(myErrorPanel); + myErrorPanel = null; + } + } + + public Editor getEditor() { + return myEditor; + } + + public void setErrorStripeRenderer(ErrorStripeRenderer renderer) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myErrorStripeRenderer = renderer; + HintManager.getInstance().getTooltipController().cancelTooltips(); + if (myErrorPanel != null) { + myErrorPanel.repaint(); + } + } + + public ErrorStripeRenderer getErrorStripeRenderer() { + return myErrorStripeRenderer; + } + + public void repaint() { + if (myErrorPanel != null) { + myErrorPanel.repaint(); + } + } + + private ArrayList getSortedHighlighters() { + if (myCachedSortedHighlighters == null) { + myCachedSortedHighlighters = new ArrayList(); + RangeHighlighter[] highlighters = getAllHighlighters(); + for (int i = 0; i < highlighters.length; i++) { + if (highlighters[i].getErrorStripeMarkColor() != null) { + myCachedSortedHighlighters.add(highlighters[i]); + } + } + final MarkupModel docMarkup = getDocument().getMarkupModel(myEditor.myProject); + if (docMarkup != null) { + highlighters = docMarkup.getAllHighlighters(); + for (int i = 0; i < highlighters.length; i++) { + if (highlighters[i].getErrorStripeMarkColor() != null) { + myCachedSortedHighlighters.add(highlighters[i]); + } + } + } + + Collections.sort( + myCachedSortedHighlighters, new Comparator() { + public int compare(Object o1, Object o2) { + RangeHighlighter h1 = (RangeHighlighter)o1; + RangeHighlighter h2 = (RangeHighlighter)o2; + return h1.getLayer() - h2.getLayer(); + } + } + ); + } + + return myCachedSortedHighlighters; + } + + private class MyErrorPanel extends JPanel implements MouseMotionListener, MouseListener { + private MyErrorPanel() { + addMouseListener(this); + addMouseMotionListener(this); + } + + public Dimension getPreferredSize() { + return new Dimension(12, 0); + } + + protected void paintComponent(Graphics g) { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart(); + + try { + LafManager lafManager = LafManager.getInstance(); + if (lafManager == null || lafManager.isUnderAquaLookAndFeel()) { + g.setColor(new Color(0xF0F0F0)); + Rectangle clipBounds = g.getClipBounds(); + g.fillRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height); + } else { + super.paintComponent(g); + } + + EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar(); + if (myErrorStripeRenderer != null) { + int top = scrollBar.getDecScrollButtonHeight(); + myErrorStripeRenderer.paint(this, g, new Rectangle(0, 0, top, getWidth())); + } + + int scrollBarHeight = scrollBar.getSize().height; + + ArrayList sortedHighlighters = getSortedHighlighters(); + for (int i = 0; i < sortedHighlighters.size(); i++) { + RangeHighlighter highlighter = sortedHighlighters.get(i); + if (!highlighter.isValid()) continue; + + int visStartLine = myEditor.logicalToVisualPosition( + new LogicalPosition(highlighter.getDocument().getLineNumber(highlighter.getStartOffset()), 0) + ).line; + + int visEndLine = myEditor.logicalToVisualPosition( + new LogicalPosition(highlighter.getDocument().getLineNumber(highlighter.getEndOffset()), 0) + ).line; + + int yStartPosition = visibleLineToYPosition(visStartLine, scrollBarHeight); + int yEndPosition = visibleLineToYPosition(visEndLine, scrollBarHeight); + + final int height = Math.max(yEndPosition - yStartPosition, 2); + + g.setColor(highlighter.getErrorStripeMarkColor()); + int width = getWidth(); + int x = 1; + if (highlighter.isThinErrorStripeMark()) { + width /= 2; + x += width / 2; + } + + g.fill3DRect(x, yStartPosition, width - 1, height, true); + } + } + finally { + ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish(); + } + } + + private boolean checkLineMarker(RangeHighlighter marker, int scrollBarHeight, int m_x, int m_y) { + if (!marker.isValid()) { + return false; + } + + Color color = marker.getErrorStripeMarkColor(); + if (color == null) { + return false; + } + + + int visLine = myEditor.logicalToVisualPosition( + new LogicalPosition(marker.getDocument().getLineNumber(marker.getStartOffset()), 0) + ).line; + + int visEndLine = myEditor.logicalToVisualPosition( + new LogicalPosition(marker.getDocument().getLineNumber(marker.getEndOffset()), 0) + ).line; + + int y = visibleLineToYPosition(visLine, scrollBarHeight); + int endY = visibleLineToYPosition(visEndLine, scrollBarHeight); + if (m_x >= 0 && m_x <= getWidth() && m_y >= y && m_y <= y + Math.max(endY - y, 2)) { + return true; + } + return false; + } + + private int visibleLineToYPosition(int lineNumber, int scrollBarHeight) { + EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar(); + int top = scrollBar.getDecScrollButtonHeight() + 1; + int bottom = scrollBar.getIncScrollButtonHeight(); + final int targetHeight = scrollBarHeight - top - bottom; + final int sourceHeight = myEditor.getPreferredSize().height; + + if (sourceHeight < targetHeight) { + return top + lineNumber * myEditor.getLineHeight(); + } + else { + final int lineCount = sourceHeight / myEditor.getLineHeight(); + return top + (int)(((float)lineNumber / lineCount) * targetHeight); + } + } + + // mouse events + + public void mouseClicked(final MouseEvent e) { + CommandProcessor.getInstance().executeCommand( + myEditor.myProject, new Runnable() { + public void run() { + doMouseClicked(e); + } + }, + "Move caret", null + ); + } + + private void doMouseClicked(MouseEvent e) { + myEditor.getContentComponent().requestFocus(); + EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar(); + int scrollBarHeight = scrollBar.getSize().height; + int lineCount = getDocument().getLineCount() + myEditor.getSettings().getAdditionalLinesCount(); + + if (lineCount == 0) { + return; + } + + ArrayList sortedHighlighters = getSortedHighlighters(); + for (int i = sortedHighlighters.size() - 1; i >= 0; i--) { + RangeHighlighter marker = sortedHighlighters.get(i); + if (checkLineMarker(marker, scrollBarHeight, e.getX(), e.getY())) { + myEditor.getCaretModel().moveToOffset(marker.getStartOffset()); + myEditor.getSelectionModel().removeSelection(); + ScrollingModel scrollingModel = myEditor.getScrollingModel(); + scrollingModel.disableAnimation(); + scrollingModel.scrollToCaret(ScrollType.CENTER); + scrollingModel.enableAnimation(); + fireErrorMarkerClicked(marker, e); + return; + } + } + } + + public void mouseMoved(MouseEvent e) { + EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar(); + int scrollBarHeight = scrollBar.getSize().height; + int buttonHeight = scrollBar.getDecScrollButtonHeight(); + int lineCount = getDocument().getLineCount() + myEditor.getSettings().getAdditionalLinesCount(); + + if (lineCount == 0) { + return; + } + + if (e.getY() < buttonHeight && myErrorStripeRenderer != null) { + String tooltipMessage = myErrorStripeRenderer.getTooltipMessage(); + if (tooltipMessage != null) { + TooltipController tooltipController = HintManager.getInstance().getTooltipController(); + tooltipController.showTooltipByMouseMove(myEditor, e, + tooltipMessage, + myEditor.getVerticalScrollbarOrientation() == + EditorEx.VERTICAL_SCROLLBAR_RIGHT, + ERROR_STRIPE_TOOLTIP_GROUP); + } + return; + } + + ArrayList sortedHighlighters = getSortedHighlighters(); + RangeHighlighter highlighterForTooltip = null; + ArrayList highlightersForTooltip = null; + for (int i = sortedHighlighters.size() - 1; i >= 0; i--) { + RangeHighlighter marker = sortedHighlighters.get(i); + if (checkLineMarker(marker, scrollBarHeight, e.getX(), e.getY())) { + if (highlighterForTooltip == null) { + highlighterForTooltip = marker; + } + else { + if (highlightersForTooltip == null) { + highlightersForTooltip = new ArrayList(); + highlightersForTooltip.add(highlighterForTooltip); + } + highlightersForTooltip.add(marker); + } + } + } + if (highlightersForTooltip != null) { + highlighterForTooltip = highlightersForTooltip.get(0); + final ArrayList infos = new ArrayList(); + for (int i = 0; i < highlightersForTooltip.size(); i++) { + RangeHighlighter marker = highlightersForTooltip.get(i); + if (marker.getErrorStripeTooltip() instanceof HighlightInfo) { + infos.add((HighlightInfo)marker.getErrorStripeTooltip()); + } + } + if (highlightersForTooltip.size() == infos.size()) { + // need to show tooltips for multiple highlightinfos + final HighlightInfoComposite composite = new HighlightInfoComposite(infos); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + showTooltip(e, composite); + return; + } + } + if (highlighterForTooltip != null) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + showTooltip(e, highlighterForTooltip.getErrorStripeTooltip()); + return; + } + + cancelMyToolTips(); + + if (getCursor().equals(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR))) { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + + private void cancelMyToolTips() { + HintManager.getInstance().getTooltipController().cancelTooltip(ERROR_STRIPE_TOOLTIP_GROUP); + } + + private void showTooltip(MouseEvent e, final Object tooltipObject) { + if (tooltipObject != null) { + HintManager.getInstance().getTooltipController().showTooltipByMouseMove(myEditor, e, tooltipObject, + myEditor.getVerticalScrollbarOrientation() == + EditorEx.VERTICAL_SCROLLBAR_RIGHT, + ERROR_STRIPE_TOOLTIP_GROUP); + } + } + + public void mouseEntered(MouseEvent e) { + // this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void mouseExited(MouseEvent e) { + cancelMyToolTips(); + } + + public void mouseDragged(MouseEvent e) { + cancelMyToolTips(); + } + + public void mousePressed(MouseEvent e) { + } + + public void mouseReleased(MouseEvent e) { + } + } + + private ErrorStripeListener[] getCachedErrorMarkerListeners() { + if (myCachedErrorMarkerListeners == null) { + myCachedErrorMarkerListeners = myErrorMarkerListeners.toArray( + new ErrorStripeListener[myErrorMarkerListeners.size()] + ); + } + + return myCachedErrorMarkerListeners; + } + + private void fireErrorMarkerClicked(RangeHighlighter marker, MouseEvent e) { + ErrorStripeEvent event = new ErrorStripeEvent(getEditor(), e, marker); + ErrorStripeListener[] listeners = getCachedErrorMarkerListeners(); + for (int i = 0; i < listeners.length; i++) { + ErrorStripeListener listener = listeners[i]; + listener.errorMarkerClicked(event); + } + } + + public void addErrorMarkerListener(ErrorStripeListener listener) { + myCachedErrorMarkerListeners = null; + myErrorMarkerListeners.add(listener); + } + + public void removeErrorMarkerListener(ErrorStripeListener listener) { + myCachedErrorMarkerListeners = null; + boolean success = myErrorMarkerListeners.remove(listener); + LOG.assertTrue(success); + } + + public void markDirtied() { + myCachedSortedHighlighters = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldRegionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldRegionImpl.java new file mode 100644 index 00000000000..50fb8a54905 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldRegionImpl.java @@ -0,0 +1,54 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Apr 22, 2002 + * Time: 5:51:22 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.FoldRegion; + +public class FoldRegionImpl extends PersistentRangeMarker implements FoldRegion { + private boolean myIsExpanded; + private EditorImpl myEditor; + private String myPlaceholderText; + + public FoldRegionImpl(EditorImpl editor, int startOffset, int endOffset, String placeholder) { + super(editor.getDocument(), startOffset, endOffset); + myIsExpanded = true; + myEditor = editor; + myPlaceholderText = placeholder; + } + + public boolean isExpanded() { + return myIsExpanded; + } + + public void setExpanded(boolean expanded) { + FoldingModelImpl foldingModel = (FoldingModelImpl)myEditor.getFoldingModel(); + if (expanded){ + foldingModel.expandFoldRegion(this); + } + else{ + foldingModel.collapseFoldRegion(this); + } + } + + public boolean isValid() { + return super.isValid() && getStartOffset() + 1 < getEndOffset(); + } + + public void setExpandedInternal(boolean toExpand) { + myIsExpanded = toExpand; + } + + public String getPlaceholderText() { + return myPlaceholderText; + } + + public String toString() { + return "FoldRegion (" + getStartOffset() + ":" + getEndOffset() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldingModelImpl.java new file mode 100644 index 00000000000..36279cbb734 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -0,0 +1,555 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 4, 2002 + * Time: 8:27:13 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.FoldingModelEx; +import com.intellij.openapi.editor.markup.TextAttributes; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedList; + +public class FoldingModelImpl implements FoldingModelEx, DocumentListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorFoldingModelImpl"); + private boolean myIsFoldingEnabled; + private EditorImpl myEditor; + private FoldRegionsTree myFoldTree; + private TextAttributes myFoldTextAttributes; + private boolean myIsBatchFoldingProcessing; + private boolean myFoldRegionsProcessed; + + private int mySavedCaretX; + private int mySavedCaretY; + private int mySavedCaretShift; + private boolean myCaretPositionSaved; + + public FoldingModelImpl(EditorImpl editor) { + myEditor = editor; + myIsFoldingEnabled = true; + myIsBatchFoldingProcessing = false; + myFoldTree = new FoldRegionsTree(); + myFoldRegionsProcessed = false; + refreshSettings(); + } + + public void refreshSettings() { + myFoldTextAttributes = myEditor.getColorsScheme().getAttributes(EditorColors.FOLDED_TEXT_ATTRIBUTES); + } + + public boolean isFoldingEnabled() { + return myIsFoldingEnabled; + } + + public boolean isOffsetCollapsed(int offset) { + ApplicationManager.getApplication().assertIsDispatchThread(); + return getCollapsedRegionAtOffset(offset) != null; + } + + public void setFoldingEnabled(boolean isEnabled) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myIsFoldingEnabled = isEnabled; + } + + public FoldRegion addFoldRegion(int startOffset, int endOffset, String placeholderText) { + ApplicationManager.getApplication().assertIsDispatchThread(); + LOG.assertTrue(placeholderText != null); + FoldRegion range = new FoldRegionImpl(myEditor, startOffset, endOffset, placeholderText); + if (isFoldingEnabled()) { + if (!myIsBatchFoldingProcessing) { + LOG.error("Fold regions must be added or removed inside batchFoldProcessing() only."); + return null; + } + + myFoldRegionsProcessed = true; + return myFoldTree.addRegion(range) ? range : null; + } + + return null; + } + + public void runBatchFoldingOperation(Runnable operation) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean oldBatchFlag = myIsBatchFoldingProcessing; + if (!oldBatchFlag) { + mySavedCaretShift = myEditor.visibleLineNumberToYPosition(myEditor.getCaretModel().getVisualPosition().line) - myEditor.getScrollingModel().getVerticalScrollOffset(); + } + + myIsBatchFoldingProcessing = true; + operation.run(); + if (!oldBatchFlag) { + if (myFoldRegionsProcessed) { + notifyBatchFoldingProcessingDone(); + myFoldRegionsProcessed = false; + } + myIsBatchFoldingProcessing = false; + } + } + + public void flushCaretShift() { + mySavedCaretShift = -1; + } + + public FoldRegion[] getAllFoldRegions() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myFoldTree.fetchAllRegions(); + } + + public FoldRegion getCollapsedRegionAtOffset(int offset) { + return myFoldTree.fetchOutermost(offset); + } + + int getLastTopLevelIndexBefore (int offset) { + return myFoldTree.getLastTopLevelIndexBefore(offset); + } + + public FoldRegion getFoldingPlaceholderAt(Point p) { + ApplicationManager.getApplication().assertIsDispatchThread(); + LogicalPosition pos = myEditor.xyToLogicalPosition(p); + int line = pos.line; + + if (line >= myEditor.getDocument().getLineCount()) return null; + int offset = myEditor.logicalPositionToOffset(pos); + + return myFoldTree.fetchOutermost(offset); + } + + public FoldRegion[] getAllFoldRegionsIncludingInvalid() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myFoldTree.fetchAllRegionsIncludingInvalid(); + } + + public void removeFoldRegion(final FoldRegion region) { + ApplicationManager.getApplication().assertIsDispatchThread(); + + if (!myIsBatchFoldingProcessing) { + LOG.error("Fold regions must be added or removed inside batchFoldProcessing() only."); + } + + expandFoldRegion(region); + myFoldTree.removeRegion(region); + myFoldRegionsProcessed = true; + } + + public void expandFoldRegion(FoldRegion region) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (region.isExpanded()) return; + + if (!myIsBatchFoldingProcessing) { + LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); + } + + if (myCaretPositionSaved) { + int savedOffset = myEditor.logicalPositionToOffset(new LogicalPosition(mySavedCaretY, mySavedCaretX)); + + FoldRegion[] allCollapsed = myFoldTree.fetchCollapsedAt(savedOffset); + if (allCollapsed.length == 1 && allCollapsed[0] == region) { + LogicalPosition pos = new LogicalPosition(mySavedCaretY, mySavedCaretX); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + } + + myFoldRegionsProcessed = true; + ((FoldRegionImpl) region).setExpandedInternal(true); + } + + public void collapseFoldRegion(FoldRegion region) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!region.isExpanded()) return; + + if (!myIsBatchFoldingProcessing) { + LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); + } + + LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition(); + + int caretOffset = myEditor.logicalPositionToOffset(caretPosition); + + if (myFoldTree.contains(region, caretOffset)) { + if (!myCaretPositionSaved) { + mySavedCaretX = caretPosition.column; + mySavedCaretY = caretPosition.line; + myCaretPositionSaved = true; + } + } + + int selectionStart = myEditor.getSelectionModel().getSelectionStart(); + int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); + + if (myFoldTree.contains(region, selectionStart-1) || myFoldTree.contains(region, selectionEnd)) myEditor.getSelectionModel().removeSelection(); + + myFoldRegionsProcessed = true; + ((FoldRegionImpl) region).setExpandedInternal(false); + } + + private void notifyBatchFoldingProcessingDone() { + myFoldTree.rebuild(); + + myEditor.updateCaretCursor(); + myEditor.recalcSizeAndRepaint(); + if (myEditor.getGutterComponentEx().isFoldingOutlineShown()) { + myEditor.getGutterComponentEx().repaint(); + } + + LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition(); + int caretOffset = myEditor.logicalPositionToOffset(caretPosition); + int selectionStart = myEditor.getSelectionModel().getSelectionStart(); + int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); + + int column = -1; + int line = -1; + + FoldRegion collapsed = myFoldTree.fetchOutermost(caretOffset); + if (myCaretPositionSaved) { + int savedOffset = myEditor.logicalPositionToOffset(new LogicalPosition(mySavedCaretY, mySavedCaretX)); + FoldRegion collapsedAtSaved = myFoldTree.fetchOutermost(savedOffset); + column = mySavedCaretX; + line = collapsedAtSaved != null ? collapsedAtSaved.getDocument().getLineNumber(collapsedAtSaved.getStartOffset()) : mySavedCaretY; + } + + if (collapsed != null && column == -1) { + line = collapsed.getDocument().getLineNumber(collapsed.getStartOffset()); + column = myEditor.getCaretModel().getVisualPosition().column; + } + + boolean oldCaretPositionSaved = myCaretPositionSaved; + + if (column != -1) { + LogicalPosition log = new LogicalPosition(line, 0); + VisualPosition vis = myEditor.logicalToVisualPosition(log); + VisualPosition pos = new VisualPosition(vis.line, column); + myEditor.getCaretModel().moveToVisualPosition(pos); + } else { + myEditor.getCaretModel().moveToLogicalPosition(caretPosition); + } + + myCaretPositionSaved = oldCaretPositionSaved; + + myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd); + + if (mySavedCaretShift > 0) { + myEditor.getScrollingModel().disableAnimation(); + int scrollTo = myEditor.visibleLineNumberToYPosition(myEditor.getCaretModel().getVisualPosition().line) - mySavedCaretShift; + myEditor.getScrollingModel().scrollVertically(scrollTo); + myEditor.getScrollingModel().enableAnimation(); + } + } + + public void rebuild() { + myFoldTree.rebuild(); + } + + private void updateCachedOffsets() { + myFoldTree.updateCachedOffsets(); + } + + public int getFoldedLinesCountBefore(int offset) { + return myFoldTree.getFoldedLinesCountBefore(offset); + } + + FoldRegion[] fetchTopLevel() { + return myFoldTree.fetchTopLevel(); + } + + FoldRegion fetchOutermost(int offset) { + return myFoldTree.fetchOutermost(offset); + } + + public FoldRegion[] fetchCollapsedAt(int offset) { + return myFoldTree.fetchCollapsedAt(offset); + } + + public boolean intersectsRegion (int startOffset, int endOffset) { + return myFoldTree.intersectsRegion(startOffset, endOffset); + } + + public FoldRegion[] fetchVisible() { + return myFoldTree.fetchVisible(); + } + + public int getLastCollapsedRegionBefore(int offset) { + return myFoldTree.getLastTopLevelIndexBefore(offset); + } + + public TextAttributes getPlaceholderAttributes() { + return myFoldTextAttributes; + } + + public void flushCaretPosition() { + myCaretPositionSaved = false; + } + + class FoldRegionsTree { + private FoldRegion[] myCachedVisible; + private FoldRegion[] myCachedTopLevelRegions; + private int[] myCachedEndOffsets; + private int[] myCachedStartOffsets; + private int[] myCachedFoldedLines; + private LinkedList myRegions; //sorted in tree left-to-right topdown traversal order + + public FoldRegionsTree() { + myCachedVisible = null; + myRegions = new LinkedList(); + } + + public boolean isFoldingEnabled() { + return FoldingModelImpl.this.isFoldingEnabled() && myCachedVisible != null; + } + + public void rebuild() { + ArrayList topLevels = new ArrayList(myRegions.size() / 2); + ArrayList visible = new ArrayList(myRegions.size()); + FoldRegion[] regions = myRegions.toArray(new FoldRegion[myRegions.size()]); + FoldRegion currentToplevel = null; + for (int i = 0; i < regions.length; i++) { + FoldRegion region = regions[i]; + if (region.isValid()) { + visible.add(region); + if (!region.isExpanded()) { + if (currentToplevel == null || currentToplevel.getEndOffset() < region.getStartOffset()) { + currentToplevel = region; + topLevels.add(region); + } + } + } + } + + myCachedTopLevelRegions = topLevels.toArray(new FoldRegion[topLevels.size()]); + + Arrays.sort(myCachedTopLevelRegions, new Comparator() { + public int compare(Object o1, Object o2) { + FoldRegion r1 = (FoldRegion) o1; + FoldRegion r2 = (FoldRegion) o2; + int end1 = r1.getEndOffset(); + int end2 = r2.getEndOffset(); + if (end1 < end2) return -1; + if (end1 > end2) return 1; + return 0; + } + }); + + FoldRegion[] visibleArrayed = visible.toArray(new FoldRegion[visible.size()]); + for (int i = 0; i < visibleArrayed.length; i++) { + FoldRegion visibleRegion = visibleArrayed[i]; + for (int j = 0; j < myCachedTopLevelRegions.length; j++) { + FoldRegion topLevelRegion = myCachedTopLevelRegions[j]; + if (contains(topLevelRegion, visibleRegion)) { + visible.remove(visibleRegion); + break; + } + } + } + + myCachedVisible = visible.toArray(new FoldRegion[visible.size()]); + + Arrays.sort(myCachedVisible, new Comparator() { + public int compare(Object o1, Object o2) { + FoldRegion r1 = (FoldRegion) o1; + FoldRegion r2 = (FoldRegion) o2; + int end1 = r1.getEndOffset(); + int end2 = r2.getEndOffset(); + if (end1 < end2) return 1; + if (end1 > end2) return -1; + return 0; + } + }); + + updateCachedOffsets(); + } + + public void updateCachedOffsets() { + if (isFoldingEnabled()) { + for (int i = 0; i < myCachedVisible.length; i++) { + FoldRegion foldRegion = myCachedVisible[i]; + if (!foldRegion.isValid()) { + rebuild(); + return; + } + } + + int sum = 0; + + if (myCachedEndOffsets == null || myCachedEndOffsets.length != myCachedTopLevelRegions.length) { + myCachedEndOffsets = new int[myCachedTopLevelRegions.length]; + myCachedStartOffsets = new int[myCachedTopLevelRegions.length]; + myCachedFoldedLines = new int[myCachedTopLevelRegions.length]; + } + + for (int i = 0; i < myCachedTopLevelRegions.length; i++) { + FoldRegion region = myCachedTopLevelRegions[i]; + myCachedStartOffsets[i] = region.getStartOffset(); + myCachedEndOffsets[i] = region.getEndOffset() - 1; + sum += region.getDocument().getLineNumber(region.getEndOffset()) - region.getDocument().getLineNumber(region.getStartOffset()); + myCachedFoldedLines[i] = sum; + } + } + } + + public boolean addRegion(FoldRegion range) { + for (int i = 0; i < myRegions.size(); i++) { + FoldRegion region = myRegions.get(i); + if (region.isValid() && intersects(region, range)) { + return false; + } + + if (range.getStartOffset() < region.getStartOffset() || + (range.getStartOffset() == region.getStartOffset() && range.getEndOffset() > region.getEndOffset())) { + for (int j = i + 1; j < myRegions.size(); j++) { + FoldRegion next = myRegions.get(j); + if (next.getEndOffset() >= range.getEndOffset() && next.isValid()) { + if (next.getStartOffset() < range.getStartOffset()) { + return false; + } else break; + } + } + + myRegions.add(i, range); + return true; + } + } + myRegions.addLast(range); + return true; + } + + public FoldRegion fetchOutermost(int offset) { + if (!isFoldingEnabled()) return null; + int start = 0; + int end = myCachedEndOffsets.length - 1; + + while (start <= end) { + int i = (start + end) / 2; + if (offset < myCachedStartOffsets[i]) { + end = i - 1; + } else if (offset > myCachedEndOffsets[i]) { + start = i + 1; + } else return myCachedTopLevelRegions[i]; + } + + return null; + } + + public FoldRegion[] fetchVisible() { + if (!isFoldingEnabled()) return new FoldRegion[0]; + return myCachedVisible; + } + + public FoldRegion[] fetchTopLevel() { + if (!isFoldingEnabled()) return null; + return myCachedTopLevelRegions; + } + + private boolean contains(FoldRegion outer, FoldRegion inner) { + return outer.getStartOffset() < inner.getStartOffset() && outer.getEndOffset() > inner.getStartOffset(); + } + + private boolean intersects(FoldRegion r1, FoldRegion r2) { + final int s1 = r1.getStartOffset(); + final int s2 = r2.getStartOffset(); + final int e1 = r1.getEndOffset(); + final int e2 = r2.getEndOffset(); + return s1 == s2 && e1 == e2 || + s1 < s2 && s2 < e1 && e1 < e2 || + s2 < s1 && s1 < e2 && e2 < e1; + } + + private boolean contains(FoldRegion region, int offset) { + return region.getStartOffset() <= offset && region.getEndOffset() > offset; + } + + public FoldRegion[] fetchCollapsedAt(int offset) { + if (!isFoldingEnabled()) return new FoldRegion[0]; + ArrayList allCollapsed = new ArrayList(); + for (int i = 0; i < myRegions.size(); i++) { + FoldRegion region = myRegions.get(i); + if (!region.isExpanded() && contains(region, offset)) { + allCollapsed.add(region); + } + } + + return allCollapsed.toArray(new FoldRegion[allCollapsed.size()]); + } + + public boolean intersectsRegion(int startOffset, int endOffset) { + if (!FoldingModelImpl.this.isFoldingEnabled()) return true; + for (int i = 0; i < myRegions.size(); i++) { + FoldRegion region = myRegions.get(i); + boolean contains1 = contains(region, startOffset), contains2 = contains(region, endOffset); + if ((contains1 && !contains2) || (!contains1 && contains2)) { + return true; + } + } + return false; + } + + public FoldRegion[] fetchAllRegions() { + if (!isFoldingEnabled()) return new FoldRegion[0]; + + return myRegions.toArray(new FoldRegion[myRegions.size()]); + } + + public void removeRegion(FoldRegion range) { + myRegions.remove(range); + } + + public int getFoldedLinesCountBefore(int offset) { + int idx = getLastTopLevelIndexBefore(offset); + if (idx == -1) return 0; + return myCachedFoldedLines[idx]; + } + + public int getLastTopLevelIndexBefore(int offset) { + if (!isFoldingEnabled()) return -1; + + int start = 0; + int end = myCachedEndOffsets.length - 1; + + while (start <= end) { + int i = (start + end) / 2; + if (offset < myCachedEndOffsets[i]) { + end = i - 1; + } else if (offset > myCachedEndOffsets[i]) { + start = i + 1; + } else return i; + } + + return end; + +// for (int i = 0; i < myCachedEndOffsets.length; i++) { +// if (!myCachedTopLevelRegions[i].isValid()) continue; +// int endOffset = myCachedEndOffsets[i]; +// if (endOffset > offset) break; +// lastIndex = i; +// } +// +// return lastIndex; + } + + public FoldRegion[] fetchAllRegionsIncludingInvalid() { + if (!FoldingModelImpl.this.isFoldingEnabled()) return new FoldRegion[0]; + + return myRegions.toArray(new FoldRegion[myRegions.size()]); + } + } + + public void beforeDocumentChange(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + updateCachedOffsets(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/HighlighterList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/HighlighterList.java new file mode 100644 index 00000000000..526382e8f20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/HighlighterList.java @@ -0,0 +1,87 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.markup.RangeHighlighter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +public class HighlighterList { + private ArrayList mySegmentHighlighters = new ArrayList(); + private boolean myIsDirtied = false; + private DocumentAdapter myDocumentListener; + private Document myDoc; + private int myLongestHighlighterLength = 0; + + public HighlighterList(Document doc) { + myDocumentListener = new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + myIsDirtied = true; + } + }; + myDoc = doc; + myDoc.addDocumentListener(myDocumentListener); + } + + public void dispose() { + myDoc.removeDocumentListener(myDocumentListener); + } + + public int getLongestHighlighterLength() { + return myLongestHighlighterLength; + } + + private void sortMarkers() { + myLongestHighlighterLength = 0; + RangeHighlighterImpl[] segmentHighlighters = mySegmentHighlighters.toArray(new RangeHighlighterImpl[mySegmentHighlighters.size()]); + for (int i = 0; i < segmentHighlighters.length; i++) { + RangeHighlighterImpl segmentHighlighter = segmentHighlighters[i]; + if (!segmentHighlighter.isValid()) mySegmentHighlighters.remove(segmentHighlighter); + myLongestHighlighterLength = + Math.max(myLongestHighlighterLength, segmentHighlighter.getEndOffset() - segmentHighlighter.getStartOffset()); + } + + Collections.sort(mySegmentHighlighters, new Comparator() { + public int compare(RangeHighlighterImpl r1, RangeHighlighterImpl r2) { +// RangeHighlighterImpl r1 = (RangeHighlighterImpl) o1; +// RangeHighlighterImpl r2 = (RangeHighlighterImpl) o2; + + if (r1.getAffectedAreaStartOffset() != r2.getAffectedAreaStartOffset()) { + return r1.getAffectedAreaStartOffset() - r2.getAffectedAreaStartOffset(); + } + + if (r1.getLayer() != r2.getLayer()) { + return r2.getLayer() - r1.getLayer(); + } + + return (int) (r2.getId() - r1.getId()); + } + }); + + myIsDirtied = false; + } + + public Iterator getHighlighterIterator() { + if (myIsDirtied) sortMarkers(); + return mySegmentHighlighters.iterator(); + } + + ArrayList getSortedHighlighters() { + if (myIsDirtied) sortMarkers(); + return mySegmentHighlighters; + } + + public void addSegmentHighlighter(RangeHighlighter segmentHighlighter) { + myIsDirtied = true; + mySegmentHighlighters.add((RangeHighlighterImpl)segmentHighlighter); + } + + public void removeSegmentHighlighter(RangeHighlighter segmentHighlighter) { + myIsDirtied = true; + mySegmentHighlighters.remove(segmentHighlighter); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/IterationState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/IterationState.java new file mode 100644 index 00000000000..58c77274ab1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/IterationState.java @@ -0,0 +1,508 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.*; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +public class IterationState { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.IterationState"); + private TextAttributes myMergedAttributes = new TextAttributes(); + + private HighlighterIterator myHighlighterIterator; + private ArrayList myViewHighlighters; + private int myCurrentViewHighlighterIdx; + + private ArrayList myDocumentHighlighters; + private int myCurrentDocHighlighterIdx; + + private int myStartOffset; + private int myEndOffset; + private int myEnd; + + private int mySelectionStart; + private int mySelectionEnd; + + private ArrayList myCurrentHighlighters; + + private RangeHighlighterImpl myNextViewHighlighter = null; + private RangeHighlighterImpl myNextDocumentHighlighter = null; + + private FoldingModelImpl myFoldingModel = null; + + private boolean hasSelection = false; + private FoldRegion myCurrentFold = null; + private TextAttributes myFoldTextAttributes = null; + private TextAttributes mySelectionAttributes = null; + private TextAttributes myCaretRowAttributes = null; + private int myCaretRowStart; + private int myCaretRowEnd; + private ArrayList myCachedAttributesList; + private DocumentImpl myDocument; + private EditorImpl myEditor; + private Color myReadOnlyColor; + + public IterationState(EditorImpl editor, int start, boolean useCaretAndSelection) { + myDocument = (DocumentImpl)editor.getDocument(); + myStartOffset = start; + myEnd = editor.getDocument().getTextLength(); + myEditor = editor; + + LOG.assertTrue(myStartOffset <= myEnd); + myHighlighterIterator = editor.getHighlighter().createIterator(start); + + HighlighterList viewHighlighterList = ((MarkupModelImpl)editor.getMarkupModel()).getHighlighterList(); + int longestViewHighlighterLength = viewHighlighterList.getLongestHighlighterLength(); + myViewHighlighters = viewHighlighterList.getSortedHighlighters(); + + final MarkupModelImpl docMarkup = ((MarkupModelImpl)editor.getDocument().getMarkupModel(editor.myProject)); + // docMarkup can be null if editor is released or project is disposed. + myDocumentHighlighters = docMarkup != null + ? docMarkup.getHighlighterList().getSortedHighlighters() + : new ArrayList(); + + int longestDocHighlighterLength = docMarkup != null + ? docMarkup.getHighlighterList().getLongestHighlighterLength() + : 0; + + hasSelection = useCaretAndSelection && editor.getSelectionModel().hasSelection(); + mySelectionStart = hasSelection ? editor.getSelectionModel().getSelectionStart() : -1; + mySelectionEnd = hasSelection ? editor.getSelectionModel().getSelectionEnd() : -1; + + myFoldingModel = (FoldingModelImpl)editor.getFoldingModel(); + myFoldTextAttributes = myFoldingModel.getPlaceholderAttributes(); + mySelectionAttributes = ((SelectionModelImpl)editor.getSelectionModel()).getTextAttributes(); + + myReadOnlyColor = myEditor.getColorsScheme().getColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR); + + CaretModelImpl caretModel = (CaretModelImpl)editor.getCaretModel(); + myCaretRowAttributes = editor.isRendererMode() ? null : caretModel.getTextAttributes(); + + myCurrentHighlighters = new ArrayList(); + + myCurrentViewHighlighterIdx = initHighlighterIterator(start, myViewHighlighters, longestViewHighlighterLength); + while (myCurrentViewHighlighterIdx < myViewHighlighters.size()) { + myNextViewHighlighter = myViewHighlighters.get(myCurrentViewHighlighterIdx); + if (!skipHighlighter(myNextViewHighlighter)) break; + myCurrentViewHighlighterIdx++; + } + if (myCurrentViewHighlighterIdx == myViewHighlighters.size()) myNextViewHighlighter = null; + + myCurrentDocHighlighterIdx = initHighlighterIterator(start, myDocumentHighlighters, longestDocHighlighterLength); + myNextDocumentHighlighter = null; + while (myCurrentDocHighlighterIdx < myDocumentHighlighters.size()) { + myNextDocumentHighlighter = myDocumentHighlighters.get(myCurrentDocHighlighterIdx); + if (!skipHighlighter(myNextDocumentHighlighter)) break; + myCurrentDocHighlighterIdx++; + } + if (myCurrentDocHighlighterIdx == myDocumentHighlighters.size()) myNextDocumentHighlighter = null; + + advanceSegmentHighlighters(); + + myCaretRowStart = caretModel.getVisualLineStart(); + myCaretRowEnd = caretModel.getVisualLineEnd(); + + myEndOffset = Math.min(getHighlighterEnd(myStartOffset), getSelectionEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getSegmentHighlightersEnd()); + myEndOffset = Math.min(myEndOffset, getFoldRangesEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getCaretEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getGuardedBlockEnd(myStartOffset)); + + myCurrentFold = myFoldingModel.getCollapsedRegionAtOffset(myStartOffset); + if (myCurrentFold != null) { + myEndOffset = myCurrentFold.getEndOffset(); + } + + myCachedAttributesList = new ArrayList(5); + + reinit(); + } + + private int initHighlighterIterator(int start, ArrayList sortedHighlighters, int longestHighlighterLength) { + int low = 0; + int high = sortedHighlighters.size(); + int search = myDocument.getLineStartOffset(myDocument.getLineNumber(start)) - + longestHighlighterLength - 1; + + if (search > 0) { + while (low < high) { + int mid = (low + high) / 2; + while (mid > 0 && !(sortedHighlighters.get(mid)).isValid()) mid--; + if (mid < low + 1) break; + RangeHighlighterImpl midHighlighter = sortedHighlighters.get(mid); + if (midHighlighter.getStartOffset() < search) { + low = mid + 1; + } + else { + high = mid - 1; + } + } + } + + for (int i = low == high ? low : 0; i < sortedHighlighters.size(); i++) { + RangeHighlighterImpl rangeHighlighter = sortedHighlighters.get(i); + if (!skipHighlighter(rangeHighlighter) && + rangeHighlighter.getAffectedAreaEndOffset() >= start) { + return i; + } + } + return sortedHighlighters.size(); + } + + private boolean skipHighlighter(RangeHighlighterImpl highlighter) { + return !highlighter.isValid() || + highlighter.isAfterEndOfLine() || + highlighter.getTextAttributes() == null || + myFoldingModel.isOffsetCollapsed(highlighter.getAffectedAreaStartOffset()) || + myFoldingModel.isOffsetCollapsed(highlighter.getAffectedAreaEndOffset()) || + !highlighter.getEditorFilter().avaliableIn(myEditor); + } + + public void advance() { + myCurrentFold = null; + myStartOffset = myEndOffset; + FoldRegion range = myFoldingModel.fetchOutermost(myStartOffset); + + if (range != null) { + myEndOffset = range.getEndOffset(); + myCurrentFold = range; + } + else { + advanceSegmentHighlighters(); + myEndOffset = Math.min(getHighlighterEnd(myStartOffset), getSelectionEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getSegmentHighlightersEnd()); + myEndOffset = Math.min(myEndOffset, getFoldRangesEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getCaretEnd(myStartOffset)); + myEndOffset = Math.min(myEndOffset, getGuardedBlockEnd(myStartOffset)); + } + + reinit(); + } + + private int getHighlighterEnd(int start) { + while (!myHighlighterIterator.atEnd()) { + int end = myHighlighterIterator.getEnd(); + if (end > start) { + return end; + } + myHighlighterIterator.advance(); + } + return myEnd; + } + + private int getCaretEnd(int start) { + if (myCaretRowStart > start) { + return myCaretRowStart; + } + + if (myCaretRowEnd > start) { + return myCaretRowEnd; + } + + return myEnd; + } + + private int getGuardedBlockEnd(int start) { + java.util.List blocks = myDocument.getGuardedBlocks(); + int min = myEnd; + for (int i = 0; i < blocks.size(); i++) { + RangeMarker block = blocks.get(i); + if (block.getStartOffset() > start) { + min = Math.min(min, block.getStartOffset()); + } + else if (block.getEndOffset() > start) { + min = Math.min(min, block.getEndOffset()); + } + } + return min; + } + + private int getSelectionEnd(int start) { + if (!hasSelection) { + return myEnd; + } + if (mySelectionStart > start) { + return mySelectionStart; + } + if (mySelectionEnd > start) { + return mySelectionEnd; + } + return myEnd; + } + + private void advanceSegmentHighlighters() { + if (myNextDocumentHighlighter != null) { + if (myNextDocumentHighlighter.getAffectedAreaStartOffset() <= myStartOffset) { + myCurrentHighlighters.add(myNextDocumentHighlighter); + myNextDocumentHighlighter = null; + } + } + + if (myNextViewHighlighter != null) { + if (myNextViewHighlighter.getAffectedAreaStartOffset() <= myStartOffset) { + myCurrentHighlighters.add(myNextViewHighlighter); + myNextViewHighlighter = null; + } + } + + + RangeHighlighterImpl highlighter; + + while (myNextDocumentHighlighter == null && myCurrentDocHighlighterIdx < myDocumentHighlighters.size()) { + highlighter = myDocumentHighlighters.get(myCurrentDocHighlighterIdx++); + if (!skipHighlighter(highlighter)) { + if (highlighter.getAffectedAreaStartOffset() > myStartOffset) { + myNextDocumentHighlighter = highlighter; + break; + } + else { + myCurrentHighlighters.add(highlighter); + } + } + } + + while (myNextViewHighlighter == null && myCurrentViewHighlighterIdx < myViewHighlighters.size()) { + highlighter = myViewHighlighters.get(myCurrentViewHighlighterIdx++); + if (!skipHighlighter(highlighter)) { + if (highlighter.getAffectedAreaStartOffset() > myStartOffset) { + myNextViewHighlighter = highlighter; + break; + } + else { + myCurrentHighlighters.add(highlighter); + } + } + } + + if (myCurrentHighlighters.size() == 1) { + //Optimization + if ((myCurrentHighlighters.get(0)).getAffectedAreaEndOffset() <= myStartOffset) { + myCurrentHighlighters = new ArrayList(); + } + } + else if (myCurrentHighlighters.size() > 0) { + ArrayList copy = new ArrayList(myCurrentHighlighters.size()); + for (int i = 0; i < myCurrentHighlighters.size(); i++) { + highlighter = myCurrentHighlighters.get(i); + if (highlighter.getAffectedAreaEndOffset() > myStartOffset) { + copy.add(highlighter); + } + } + myCurrentHighlighters = copy; + } + } + + private int getFoldRangesEnd(int startOffset) { + int end = myEnd; + FoldRegion[] topLevelCollapsed = myFoldingModel.fetchTopLevel(); + if (topLevelCollapsed != null) { + for (int i = myFoldingModel.getLastCollapsedRegionBefore(startOffset) + 1; + i >= 0 && i < topLevelCollapsed.length; + i++) { + FoldRegion range = topLevelCollapsed[i]; + if (!range.isValid()) continue; + + int rangeEnd = range.getStartOffset(); + if (rangeEnd > startOffset) { + if (rangeEnd < end) { + end = rangeEnd; + } + else { + break; + } + } + } + } + + return end; + } + + private int getSegmentHighlightersEnd() { + int end = myEnd; + + for (int i = 0; i < myCurrentHighlighters.size(); i++) { + RangeHighlighterImpl highlighter = myCurrentHighlighters.get(i); + if (highlighter.getAffectedAreaEndOffset() < end) { + end = highlighter.getAffectedAreaEndOffset(); + } + } + + if (myNextDocumentHighlighter != null && myNextDocumentHighlighter.getAffectedAreaStartOffset() < end) { + end = myNextDocumentHighlighter.getAffectedAreaStartOffset(); + } + + if (myNextViewHighlighter != null && myNextViewHighlighter.getAffectedAreaStartOffset() < end) { + end = myNextViewHighlighter.getAffectedAreaStartOffset(); + } + + return end; + } + + private void reinit() { + if (myHighlighterIterator.atEnd()) { + return; + } + + boolean isInSelection = (hasSelection && myStartOffset >= mySelectionStart && myStartOffset < mySelectionEnd); + boolean isInCaretRow = (myStartOffset >= myCaretRowStart && myStartOffset < myCaretRowEnd); + boolean isInGuardedBlock = myDocument.getOffsetGuard(myStartOffset) != null; + + TextAttributes syntax = myHighlighterIterator.getTextAttributes(); + + TextAttributes selection = isInSelection ? mySelectionAttributes : null; + TextAttributes caret = isInCaretRow ? myCaretRowAttributes : null; + TextAttributes fold = myCurrentFold != null ? myFoldTextAttributes : null; + TextAttributes guard = isInGuardedBlock + ? new TextAttributes(null, myReadOnlyColor, null, EffectType.BOXED, Font.PLAIN) + : null; + + if (myCurrentHighlighters.size() > 1) { + Collections.sort(myCurrentHighlighters, new Comparator() { + public int compare(Object o1, Object o2) { + RangeHighlighter h1 = (RangeHighlighter)o1; + RangeHighlighter h2 = (RangeHighlighter)o2; + + return h2.getLayer() - h1.getLayer(); + } + }); + } + + myCachedAttributesList.clear(); + + for (int i = 0; i < myCurrentHighlighters.size(); i++) { + RangeHighlighterImpl highlighter = myCurrentHighlighters.get(i); + if (selection != null && highlighter.getLayer() < HighlighterLayer.SELECTION) { + myCachedAttributesList.add(selection); + selection = null; + } + + if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) { + if (fold != null) { + myCachedAttributesList.add(fold); + fold = null; + } + + myCachedAttributesList.add(syntax); + syntax = null; + } + + if (guard != null && highlighter.getLayer() < HighlighterLayer.GUARDED_BLOCKS) { + myCachedAttributesList.add(guard); + guard = null; + } + + if (caret != null && highlighter.getLayer() < HighlighterLayer.CARET_ROW) { + myCachedAttributesList.add(caret); + caret = null; + } + + TextAttributes textAttributes = highlighter.getTextAttributes(); + if (textAttributes != null) { + myCachedAttributesList.add(textAttributes); + } + } + + if (selection != null) myCachedAttributesList.add(selection); + if (fold != null) myCachedAttributesList.add(fold); + if (guard != null) myCachedAttributesList.add(guard); + if (syntax != null) myCachedAttributesList.add(syntax); + if (caret != null) myCachedAttributesList.add(caret); + + Color fore = null; + Color back = isInGuardedBlock ? myReadOnlyColor : null; + Color effect = null; + EffectType effectType = EffectType.BOXED; + int fontType = 0; + + for (int i = 0; i < myCachedAttributesList.size(); i++) { + TextAttributes textAttributes = myCachedAttributesList.get(i); + + if (fore == null) { + fore = textAttributes.getForegroundColor(); + } + + if (back == null) { + back = textAttributes.getBackgroundColor(); + } + + if (fontType == 0) { + fontType = textAttributes.getFontType(); + } + + if (effect == null) { + effect = textAttributes.getEffectColor(); + effectType = textAttributes.getEffectType(); + } + } + + myMergedAttributes.setForegroundColor(fore); + myMergedAttributes.setBackgroundColor(back); + myMergedAttributes.setFontType(fontType); + myMergedAttributes.setEffectColor(effect); + myMergedAttributes.setEffectType(effectType); + } + + + public boolean atEnd() { + return myStartOffset >= myEnd; + } + + + public int getStartOffset() { + return myStartOffset; + } + + public int getEndOffset() { + return myEndOffset; + } + + public TextAttributes getMergedAttributes() { + return myMergedAttributes; + } + + public FoldRegion getCurrentFold() { + return myCurrentFold; + } + + public Color getPastFileEndBackground() { + boolean isInCaretRow = myEditor.getCaretModel().getLogicalPosition().line >= myDocument.getLineCount() - 1; + + Color caret = isInCaretRow && myCaretRowAttributes != null ? myCaretRowAttributes.getBackgroundColor() : null; + + if (myCurrentHighlighters.size() > 1) { + Collections.sort(myCurrentHighlighters, new Comparator() { + public int compare(Object o1, Object o2) { + RangeHighlighter h1 = (RangeHighlighter)o1; + RangeHighlighter h2 = (RangeHighlighter)o2; + + return h2.getLayer() - h1.getLayer(); + } + }); + } + + for (int i = 0; i < myCurrentHighlighters.size(); i++) { + RangeHighlighterImpl highlighter = myCurrentHighlighters.get(i); + + if (caret != null && highlighter.getLayer() < HighlighterLayer.CARET_ROW) { + return caret; + } + + if (highlighter.getTargetArea() != HighlighterTargetArea.LINES_IN_RANGE) continue; + + TextAttributes textAttributes = highlighter.getTextAttributes(); + if (textAttributes != null) { + Color backgroundColor = textAttributes.getBackgroundColor(); + if (backgroundColor != null) return backgroundColor; + } + } + + return caret; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LeftHandScrollbarLayout.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LeftHandScrollbarLayout.java new file mode 100644 index 00000000000..fadc7b90346 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LeftHandScrollbarLayout.java @@ -0,0 +1,1040 @@ +package com.intellij.openapi.editor.impl; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; + +/** + * This class is exact copy of javax.swing.ScrollPaneLayout except is does not ask component for orientation + * and always assumes right-to-left. + * + * @author max + */ +public class LeftHandScrollbarLayout extends ScrollPaneLayout { + /** + * The scrollpane's viewport child. + * Default is an empty JViewport. + * + * @see JScrollPane#setViewport + */ + protected JViewport viewport; + + + /** + * The scrollpane's vertical scrollbar child. + * Default is a JScrollBar. + * + * @see JScrollPane#setVerticalScrollBar + */ + protected JScrollBar vsb; + + + /** + * The scrollpane's horizontal scrollbar child. + * Default is a JScrollBar. + * + * @see JScrollPane#setHorizontalScrollBar + */ + protected JScrollBar hsb; + + + /** + * The row header child. Default is null. + * + * @see JScrollPane#setRowHeader + */ + protected JViewport rowHead; + + + /** + * The column header child. Default is null. + * + * @see JScrollPane#setColumnHeader + */ + protected JViewport colHead; + + + /** + * The component to display in the lower left corner. + * Default is null. + * + * @see JScrollPane#setCorner + */ + protected Component lowerLeft; + + + /** + * The component to display in the lower right corner. + * Default is null. + * + * @see JScrollPane#setCorner + */ + protected Component lowerRight; + + + /** + * The component to display in the upper left corner. + * Default is null. + * + * @see JScrollPane#setCorner + */ + protected Component upperLeft; + + + /** + * The component to display in the upper right corner. + * Default is null. + * + * @see JScrollPane#setCorner + */ + protected Component upperRight; + + + /** + * The display policy for the vertical scrollbar. + * The default is JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED. + *

    + * This field is obsolete, please use the JScrollPane field instead. + * + * @see JScrollPane#setVerticalScrollBarPolicy + */ + protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED; + + + /** + * The display policy for the horizontal scrollbar. + * The default is JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED. + *

    + * This field is obsolete, please use the JScrollPane field instead. + * + * @see JScrollPane#setHorizontalScrollBarPolicy + */ + protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED; + + + /** + * This method is invoked after the ScrollPaneLayout is set as the + * LayoutManager of a JScrollPane. + * It initializes all of the internal fields that + * are ordinarily set by addLayoutComponent. For example: + *

    +   * ScrollPaneLayout mySPLayout = new ScrollPanelLayout() {
    +   *     public void layoutContainer(Container p) {
    +   *         super.layoutContainer(p);
    +   *         // do some extra work here ...
    +   *     }
    +   * };
    +   * scrollpane.setLayout(mySPLayout):
    +   * 
    + */ + public void syncWithScrollPane(JScrollPane sp) { + viewport = sp.getViewport(); + vsb = sp.getVerticalScrollBar(); + hsb = sp.getHorizontalScrollBar(); + rowHead = sp.getRowHeader(); + colHead = sp.getColumnHeader(); + lowerLeft = sp.getCorner(LOWER_LEFT_CORNER); + lowerRight = sp.getCorner(LOWER_RIGHT_CORNER); + upperLeft = sp.getCorner(UPPER_LEFT_CORNER); + upperRight = sp.getCorner(UPPER_RIGHT_CORNER); + vsbPolicy = sp.getVerticalScrollBarPolicy(); + hsbPolicy = sp.getHorizontalScrollBarPolicy(); + } + + + /** + * Removes an existing component. When a new component, such as + * the left corner, or vertical scrollbar, is added, the old one, + * if it exists, must be removed. + *

    + * This method returns newC. If oldC is + * not equal to newC and is non-null, + * it will be removed from its parent. + * + * @param oldC the Component to replace + * @param newC the Component to add + * @return the newC + */ + protected Component addSingletonComponent(Component oldC, Component newC) { + if ((oldC != null) && (oldC != newC)) { + oldC.getParent().remove(oldC); + } + return newC; + } + + + /** + * Adds the specified component to the layout. The layout is + * identified using one of: + *

      + *
    • JScrollPane.VIEWPORT + *
    • JScrollPane.VERTICAL_SCROLLBAR + *
    • JScrollPane.HORIZONTAL_SCROLLBAR + *
    • JScrollPane.ROW_HEADER + *
    • JScrollPane.COLUMN_HEADER + *
    • JScrollPane.LOWER_LEFT_CORNER + *
    • JScrollPane.LOWER_RIGHT_CORNER + *
    • JScrollPane.UPPER_LEFT_CORNER + *
    • JScrollPane.UPPER_RIGHT_CORNER + *
    + * + * @param s the component identifier + * @param c the component to be added + * @throws IllegalArgumentException if s is an invalid key + */ + public void addLayoutComponent(String s, Component c) { + if (s.equals(VIEWPORT)) { + viewport = (JViewport)addSingletonComponent(viewport, c); + } + else if (s.equals(VERTICAL_SCROLLBAR)) { + vsb = (JScrollBar)addSingletonComponent(vsb, c); + } + else if (s.equals(HORIZONTAL_SCROLLBAR)) { + hsb = (JScrollBar)addSingletonComponent(hsb, c); + } + else if (s.equals(ROW_HEADER)) { + rowHead = (JViewport)addSingletonComponent(rowHead, c); + } + else if (s.equals(COLUMN_HEADER)) { + colHead = (JViewport)addSingletonComponent(colHead, c); + } + else if (s.equals(LOWER_LEFT_CORNER)) { + lowerLeft = addSingletonComponent(lowerLeft, c); + } + else if (s.equals(LOWER_RIGHT_CORNER)) { + lowerRight = addSingletonComponent(lowerRight, c); + } + else if (s.equals(UPPER_LEFT_CORNER)) { + upperLeft = addSingletonComponent(upperLeft, c); + } + else if (s.equals(UPPER_RIGHT_CORNER)) { + upperRight = addSingletonComponent(upperRight, c); + } + else { + throw new IllegalArgumentException("invalid layout key " + s); + } + } + + + /** + * Removes the specified component from the layout. + * + * @param c the component to remove + */ + public void removeLayoutComponent(Component c) { + if (c == viewport) { + viewport = null; + } + else if (c == vsb) { + vsb = null; + } + else if (c == hsb) { + hsb = null; + } + else if (c == rowHead) { + rowHead = null; + } + else if (c == colHead) { + colHead = null; + } + else if (c == lowerLeft) { + lowerLeft = null; + } + else if (c == lowerRight) { + lowerRight = null; + } + else if (c == upperLeft) { + upperLeft = null; + } + else if (c == upperRight) { + upperRight = null; + } + } + + + /** + * Returns the vertical scrollbar-display policy. + * + * @return an integer giving the display policy + * @see #setVerticalScrollBarPolicy + */ + public int getVerticalScrollBarPolicy() { + return vsbPolicy; + } + + + /** + * Sets the vertical scrollbar-display policy. The options + * are: + *
      + *
    • JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED + *
    • JScrollPane.VERTICAL_SCROLLBAR_NEVER + *
    • JScrollPane.VERTICAL_SCROLLBAR_ALWAYS + *
    + * Note: Applications should use the JScrollPane version + * of this method. It only exists for backwards compatibility + * with the Swing 1.0.2 (and earlier) versions of this class. + * + * @param x an integer giving the display policy + * @throws IllegalArgumentException if x is an invalid + * vertical scroll bar policy, as listed above + */ + public void setVerticalScrollBarPolicy(int x) { + switch (x) { + case VERTICAL_SCROLLBAR_AS_NEEDED: + case VERTICAL_SCROLLBAR_NEVER: + case VERTICAL_SCROLLBAR_ALWAYS: + vsbPolicy = x; + break; + default: + throw new IllegalArgumentException("invalid verticalScrollBarPolicy"); + } + } + + + /** + * Returns the horizontal scrollbar-display policy. + * + * @return an integer giving the display policy + * @see #setHorizontalScrollBarPolicy + */ + public int getHorizontalScrollBarPolicy() { + return hsbPolicy; + } + + /** + * Sets the horizontal scrollbar-display policy. + * The options are:
      + *
    • JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED + *
    • JScrollPane.HOTRIZONTAL_SCROLLBAR_NEVER + *
    • JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS + *
    + * Note: Applications should use the JScrollPane version + * of this method. It only exists for backwards compatibility + * with the Swing 1.0.2 (and earlier) versions of this class. + * + * @param x an int giving the display policy + * @throws IllegalArgumentException if x is not a valid + * horizontal scrollbar policy, as listed above + */ + public void setHorizontalScrollBarPolicy(int x) { + switch (x) { + case HORIZONTAL_SCROLLBAR_AS_NEEDED: + case HORIZONTAL_SCROLLBAR_NEVER: + case HORIZONTAL_SCROLLBAR_ALWAYS: + hsbPolicy = x; + break; + default: + throw new IllegalArgumentException("invalid horizontalScrollBarPolicy"); + } + } + + + /** + * Returns the JViewport object that displays the + * scrollable contents. + * + * @return the JViewport object that displays the scrollable contents + * @see JScrollPane#getViewport + */ + public JViewport getViewport() { + return viewport; + } + + + /** + * Returns the JScrollBar object that handles horizontal scrolling. + * + * @return the JScrollBar object that handles horizontal scrolling + * @see JScrollPane#getHorizontalScrollBar + */ + public JScrollBar getHorizontalScrollBar() { + return hsb; + } + + /** + * Returns the JScrollBar object that handles vertical scrolling. + * + * @return the JScrollBar object that handles vertical scrolling + * @see JScrollPane#getVerticalScrollBar + */ + public JScrollBar getVerticalScrollBar() { + return vsb; + } + + + /** + * Returns the JViewport object that is the row header. + * + * @return the JViewport object that is the row header + * @see JScrollPane#getRowHeader + */ + public JViewport getRowHeader() { + return rowHead; + } + + + /** + * Returns the JViewport object that is the column header. + * + * @return the JViewport object that is the column header + * @see JScrollPane#getColumnHeader + */ + public JViewport getColumnHeader() { + return colHead; + } + + + /** + * Returns the Component at the specified corner. + * + * @param key the String specifying the corner + * @return the Component at the specified corner, as defined in + * {@link ScrollPaneConstants}; if key is not one of the + * four corners, null is returned + * @see JScrollPane#getCorner + */ + public Component getCorner(String key) { + if (key.equals(LOWER_LEFT_CORNER)) { + return lowerLeft; + } + else if (key.equals(LOWER_RIGHT_CORNER)) { + return lowerRight; + } + else if (key.equals(UPPER_LEFT_CORNER)) { + return upperLeft; + } + else if (key.equals(UPPER_RIGHT_CORNER)) { + return upperRight; + } + else { + return null; + } + } + + + /** + * The preferred size of a ScrollPane is the size of the insets, + * plus the preferred size of the viewport, plus the preferred size of + * the visible headers, plus the preferred size of the scrollbars + * that will appear given the current view and the current + * scrollbar displayPolicies. + *

    Note that the rowHeader is calculated as part of the preferred width + * and the colHeader is calculated as part of the preferred size. + * + * @param parent the Container that will be laid out + * @return a Dimension object specifying the preferred size of the + * viewport and any scrollbars + * @see ViewportLayout + * @see LayoutManager + */ + public Dimension preferredLayoutSize(Container parent) { + /* Sync the (now obsolete) policy fields with the + * JScrollPane. + */ + JScrollPane scrollPane = (JScrollPane)parent; + vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); + hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); + + Insets insets = parent.getInsets(); + int prefWidth = insets.left + insets.right; + int prefHeight = insets.top + insets.bottom; + + /* Note that viewport.getViewSize() is equivalent to + * viewport.getView().getPreferredSize() modulo a null + * view or a view whose size was explicitly set. + */ + + Dimension extentSize = null; + Dimension viewSize = null; + Component view = null; + + if (viewport != null) { + extentSize = viewport.getPreferredSize(); + viewSize = viewport.getViewSize(); + view = viewport.getView(); + } + + /* If there's a viewport add its preferredSize. + */ + + if (extentSize != null) { + prefWidth += extentSize.width; + prefHeight += extentSize.height; + } + + /* If there's a JScrollPane.viewportBorder, add its insets. + */ + + Border viewportBorder = scrollPane.getViewportBorder(); + if (viewportBorder != null) { + Insets vpbInsets = viewportBorder.getBorderInsets(parent); + prefWidth += vpbInsets.left + vpbInsets.right; + prefHeight += vpbInsets.top + vpbInsets.bottom; + } + + /* If a header exists and it's visible, factor its + * preferred size in. + */ + + if ((rowHead != null) && rowHead.isVisible()) { + prefWidth += rowHead.getPreferredSize().width; + } + + if ((colHead != null) && colHead.isVisible()) { + prefHeight += colHead.getPreferredSize().height; + } + + /* If a scrollbar is going to appear, factor its preferred size in. + * If the scrollbars policy is AS_NEEDED, this can be a little + * tricky: + * + * - If the view is a Scrollable then scrollableTracksViewportWidth + * and scrollableTracksViewportHeight can be used to effectively + * disable scrolling (if they're true) in their respective dimensions. + * + * - Assuming that a scrollbar hasn't been disabled by the + * previous constraint, we need to decide if the scrollbar is going + * to appear to correctly compute the JScrollPanes preferred size. + * To do this we compare the preferredSize of the viewport (the + * extentSize) to the preferredSize of the view. Although we're + * not responsible for laying out the view we'll assume that the + * JViewport will always give it its preferredSize. + */ + + if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { + if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { + prefWidth += vsb.getPreferredSize().width; + } + else if ((viewSize != null) && (extentSize != null)) { + boolean canScroll = true; + if (view instanceof Scrollable) { + canScroll = !((Scrollable)view).getScrollableTracksViewportHeight(); + } + if (canScroll && (viewSize.height > extentSize.height)) { + prefWidth += vsb.getPreferredSize().width; + } + } + } + + if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) { + if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { + prefHeight += hsb.getPreferredSize().height; + } + else if ((viewSize != null) && (extentSize != null)) { + boolean canScroll = true; + if (view instanceof Scrollable) { + canScroll = !((Scrollable)view).getScrollableTracksViewportWidth(); + } + if (canScroll && (viewSize.width > extentSize.width)) { + prefHeight += hsb.getPreferredSize().height; + } + } + } + + return new Dimension(prefWidth, prefHeight); + } + + + /** + * The minimum size of a ScrollPane is the size of the insets + * plus minimum size of the viewport, plus the scrollpane's + * viewportBorder insets, plus the minimum size + * of the visible headers, plus the minimum size of the + * scrollbars whose displayPolicy isn't NEVER. + * + * @param parent the Container that will be laid out + * @return a Dimension object specifying the minimum size + */ + public Dimension minimumLayoutSize(Container parent) { + /* Sync the (now obsolete) policy fields with the + * JScrollPane. + */ + JScrollPane scrollPane = (JScrollPane)parent; + vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); + hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); + + Insets insets = parent.getInsets(); + int minWidth = insets.left + insets.right; + int minHeight = insets.top + insets.bottom; + + /* If there's a viewport add its minimumSize. + */ + + if (viewport != null) { + Dimension size = viewport.getMinimumSize(); + minWidth += size.width; + minHeight += size.height; + } + + /* If there's a JScrollPane.viewportBorder, add its insets. + */ + + Border viewportBorder = scrollPane.getViewportBorder(); + if (viewportBorder != null) { + Insets vpbInsets = viewportBorder.getBorderInsets(parent); + minWidth += vpbInsets.left + vpbInsets.right; + minHeight += vpbInsets.top + vpbInsets.bottom; + } + + /* If a header exists and it's visible, factor its + * minimum size in. + */ + + if ((rowHead != null) && rowHead.isVisible()) { + Dimension size = rowHead.getMinimumSize(); + minWidth += size.width; + minHeight = Math.max(minHeight, size.height); + } + + if ((colHead != null) && colHead.isVisible()) { + Dimension size = colHead.getMinimumSize(); + minWidth = Math.max(minWidth, size.width); + minHeight += size.height; + } + + /* If a scrollbar might appear, factor its minimum + * size in. + */ + + if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { + Dimension size = vsb.getMinimumSize(); + minWidth += size.width; + minHeight = Math.max(minHeight, size.height); + } + + if ((hsb != null) && (hsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { + Dimension size = hsb.getMinimumSize(); + minWidth = Math.max(minWidth, size.width); + minHeight += size.height; + } + + return new Dimension(minWidth, minHeight); + } + + + /** + * Lays out the scrollpane. The positioning of components depends on + * the following constraints: + *

      + *
    • The row header, if present and visible, gets its preferred + * width and the viewport's height. + *

      + *

    • The column header, if present and visible, gets its preferred + * height and the viewport's width. + *

      + *

    • If a vertical scrollbar is needed, i.e. if the viewport's extent + * height is smaller than its view height or if the displayPolicy + * is ALWAYS, it's treated like the row header with respect to its + * dimensions and is made visible. + *

      + *

    • If a horizontal scrollbar is needed, it is treated like the + * column header (see the paragraph above regarding the vertical scrollbar). + *

      + *

    • If the scrollpane has a non-null + * viewportBorder, then space is allocated for that. + *

      + *

    • The viewport gets the space available after accounting for + * the previous constraints. + *

      + *

    • The corner components, if provided, are aligned with the + * ends of the scrollbars and headers. If there is a vertical + * scrollbar, the right corners appear; if there is a horizontal + * scrollbar, the lower corners appear; a row header gets left + * corners, and a column header gets upper corners. + *
    + * + * @param parent the Container to lay out + */ + public void layoutContainer(Container parent) { + /* Sync the (now obsolete) policy fields with the + * JScrollPane. + */ + JScrollPane scrollPane = (JScrollPane)parent; + vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); + hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); + + Rectangle availR = scrollPane.getBounds(); + availR.x = availR.y = 0; + + Insets insets = parent.getInsets(); + availR.x = insets.left; + availR.y = insets.top; + availR.width -= insets.left + insets.right; + availR.height -= insets.top + insets.bottom; + + /* Get the scrollPane's orientation. + */ + boolean leftToRight = false; + + /* If there's a visible column header remove the space it + * needs from the top of availR. The column header is treated + * as if it were fixed height, arbitrary width. + */ + + Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0); + + if ((colHead != null) && (colHead.isVisible())) { + int colHeadHeight = Math.min(availR.height, + colHead.getPreferredSize().height); + colHeadR.height = colHeadHeight; + availR.y += colHeadHeight; + availR.height -= colHeadHeight; + } + + /* If there's a visible row header remove the space it needs + * from the left or right of availR. The row header is treated + * as if it were fixed width, arbitrary height. + */ + + Rectangle rowHeadR = new Rectangle(0, 0, 0, 0); + + if ((rowHead != null) && (rowHead.isVisible())) { + int rowHeadWidth = Math.min(availR.width, + rowHead.getPreferredSize().width); + rowHeadR.width = rowHeadWidth; + availR.width -= rowHeadWidth; + if (leftToRight) { + rowHeadR.x = availR.x; + availR.x += rowHeadWidth; + } + else { + rowHeadR.x = availR.x + availR.width; + } + } + + /* If there's a JScrollPane.viewportBorder, remove the + * space it occupies for availR. + */ + + Border viewportBorder = scrollPane.getViewportBorder(); + Insets vpbInsets; + if (viewportBorder != null) { + vpbInsets = viewportBorder.getBorderInsets(parent); + availR.x += vpbInsets.left; + availR.y += vpbInsets.top; + availR.width -= vpbInsets.left + vpbInsets.right; + availR.height -= vpbInsets.top + vpbInsets.bottom; + } + else { + vpbInsets = new Insets(0, 0, 0, 0); + } + + + /* At this point availR is the space available for the viewport + * and scrollbars. rowHeadR is correct except for its height and y + * and colHeadR is correct except for its width and x. Once we're + * through computing the dimensions of these three parts we can + * go back and set the dimensions of rowHeadR.height, rowHeadR.y, + * colHeadR.width, colHeadR.x and the bounds for the corners. + * + * We'll decide about putting up scrollbars by comparing the + * viewport views preferred size with the viewports extent + * size (generally just its size). Using the preferredSize is + * reasonable because layout proceeds top down - so we expect + * the viewport to be laid out next. And we assume that the + * viewports layout manager will give the view it's preferred + * size. One exception to this is when the view implements + * Scrollable and Scrollable.getViewTracksViewport{Width,Height} + * methods return true. If the view is tracking the viewports + * width we don't bother with a horizontal scrollbar, similarly + * if view.getViewTracksViewport(Height) is true we don't bother + * with a vertical scrollbar. + */ + + Component view = (viewport != null) ? viewport.getView() : null; + Dimension viewPrefSize = + (view != null) ? view.getPreferredSize() + : new Dimension(0, 0); + + Dimension extentSize = + (viewport != null) ? viewport.toViewCoordinates(availR.getSize()) + : new Dimension(0, 0); + + boolean viewTracksViewportWidth = false; + boolean viewTracksViewportHeight = false; + boolean isEmpty = (availR.width < 0 || availR.height < 0); + Scrollable sv; + // Don't bother checking the Scrollable methods if there is no room + // for the viewport, we aren't going to show any scrollbars in this + // case anyway. + if (!isEmpty && view instanceof Scrollable) { + sv = (Scrollable)view; + viewTracksViewportWidth = sv.getScrollableTracksViewportWidth(); + viewTracksViewportHeight = sv.getScrollableTracksViewportHeight(); + } + else { + sv = null; + } + + /* If there's a vertical scrollbar and we need one, allocate + * space for it (we'll make it visible later). A vertical + * scrollbar is considered to be fixed width, arbitrary height. + */ + + Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0, 0); + + boolean vsbNeeded; + if (isEmpty) { + vsbNeeded = false; + } + else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { + vsbNeeded = true; + } + else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) { + vsbNeeded = false; + } + else { // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED + vsbNeeded = !viewTracksViewportHeight && (viewPrefSize.height > extentSize.height); + } + + + if ((vsb != null) && vsbNeeded) { + adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); + extentSize = viewport.toViewCoordinates(availR.getSize()); + } + + /* If there's a horizontal scrollbar and we need one, allocate + * space for it (we'll make it visible later). A horizontal + * scrollbar is considered to be fixed height, arbitrary width. + */ + + Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0, 0); + boolean hsbNeeded; + if (isEmpty) { + hsbNeeded = false; + } + else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { + hsbNeeded = true; + } + else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) { + hsbNeeded = false; + } + else { // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED + hsbNeeded = !viewTracksViewportWidth && (viewPrefSize.width > extentSize.width); + } + + if ((hsb != null) && hsbNeeded) { + adjustForHSB(true, availR, hsbR, vpbInsets); + + /* If we added the horizontal scrollbar then we've implicitly + * reduced the vertical space available to the viewport. + * As a consequence we may have to add the vertical scrollbar, + * if that hasn't been done so already. Of course we + * don't bother with any of this if the vsbPolicy is NEVER. + */ + if ((vsb != null) && !vsbNeeded && + (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { + + extentSize = viewport.toViewCoordinates(availR.getSize()); + vsbNeeded = viewPrefSize.height > extentSize.height; + + if (vsbNeeded) { + adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); + } + } + } + + /* Set the size of the viewport first, and then recheck the Scrollable + * methods. Some components base their return values for the Scrollable + * methods on the size of the Viewport, so that if we don't + * ask after resetting the bounds we may have gotten the wrong + * answer. + */ + + if (viewport != null) { + viewport.setBounds(availR); + + if (sv != null) { + extentSize = viewport.toViewCoordinates(availR.getSize()); + + boolean oldHSBNeeded = hsbNeeded; + boolean oldVSBNeeded = vsbNeeded; + viewTracksViewportWidth = sv. + getScrollableTracksViewportWidth(); + viewTracksViewportHeight = sv. + getScrollableTracksViewportHeight(); + if (vsb != null && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) { + boolean newVSBNeeded = !viewTracksViewportHeight && + (viewPrefSize.height > extentSize.height); + if (newVSBNeeded != vsbNeeded) { + vsbNeeded = newVSBNeeded; + adjustForVSB(vsbNeeded, availR, vsbR, vpbInsets, + leftToRight); + extentSize = viewport.toViewCoordinates + (availR.getSize()); + } + } + if (hsb != null && hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) { + boolean newHSBbNeeded = !viewTracksViewportWidth && + (viewPrefSize.width > extentSize.width); + if (newHSBbNeeded != hsbNeeded) { + hsbNeeded = newHSBbNeeded; + adjustForHSB(hsbNeeded, availR, hsbR, vpbInsets); + if ((vsb != null) && !vsbNeeded && + (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { + + extentSize = viewport.toViewCoordinates + (availR.getSize()); + vsbNeeded = viewPrefSize.height > + extentSize.height; + + if (vsbNeeded) { + adjustForVSB(true, availR, vsbR, vpbInsets, + leftToRight); + } + } + } + } + if (oldHSBNeeded != hsbNeeded || + oldVSBNeeded != vsbNeeded) { + viewport.setBounds(availR); + // You could argue that we should recheck the + // Scrollable methods again until they stop changing, + // but they might never stop changing, so we stop here + // and don't do any additional checks. + } + } + } + + /* We now have the final size of the viewport: availR. + * Now fixup the header and scrollbar widths/heights. + */ + vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom; + hsbR.width = availR.width + vpbInsets.left + vpbInsets.right; + rowHeadR.height = availR.height + vpbInsets.top + vpbInsets.bottom; + rowHeadR.y = availR.y - vpbInsets.top; + colHeadR.width = availR.width + vpbInsets.left + vpbInsets.right; + colHeadR.x = availR.x - vpbInsets.left; + + /* Set the bounds of the remaining components. The scrollbars + * are made invisible if they're not needed. + */ + + if (rowHead != null) { + rowHead.setBounds(rowHeadR); + } + + if (colHead != null) { + colHead.setBounds(colHeadR); + } + + if (vsb != null) { + if (vsbNeeded) { + vsb.setVisible(true); + vsb.setBounds(vsbR); + } + else { + vsb.setVisible(false); + } + } + + if (hsb != null) { + if (hsbNeeded) { + hsb.setVisible(true); + hsb.setBounds(hsbR); + } + else { + hsb.setVisible(false); + } + } + + if (lowerLeft != null) { + lowerLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, + hsbR.y, + leftToRight ? rowHeadR.width : vsbR.width, + hsbR.height); + } + + if (lowerRight != null) { + lowerRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, + hsbR.y, + leftToRight ? vsbR.width : rowHeadR.width, + hsbR.height); + } + + if (upperLeft != null) { + upperLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, + colHeadR.y, + leftToRight ? rowHeadR.width : vsbR.width, + colHeadR.height); + } + + if (upperRight != null) { + upperRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, + colHeadR.y, + leftToRight ? vsbR.width : rowHeadR.width, + colHeadR.height); + } + } + + /** + * Adjusts the Rectangle available based on if + * the vertical scrollbar is needed (wantsVSB). + * The location of the vsb is updated in vsbR, and + * the viewport border insets (vpbInsets) are used to offset + * the vsb. This is only called when wantsVSB has + * changed, eg you shouldn't invoke adjustForVSB(true) twice. + */ + private void adjustForVSB(boolean wantsVSB, Rectangle available, + Rectangle vsbR, Insets vpbInsets, + boolean leftToRight) { + int oldWidth = vsbR.width; + if (wantsVSB) { + int vsbWidth = Math.max(0, Math.min(vsb.getPreferredSize().width, + available.width)); + + available.width -= vsbWidth; + vsbR.width = vsbWidth; + + if (leftToRight) { + vsbR.x = available.x + available.width + vpbInsets.right; + } + else { + vsbR.x = available.x - vpbInsets.left; + available.x += vsbWidth; + } + } + else { + available.width += oldWidth; + } + } + + /** + * Adjusts the Rectangle available based on if + * the horizontal scrollbar is needed (wantsHSB). + * The location of the hsb is updated in hsbR, and + * the viewport border insets (vpbInsets) are used to offset + * the hsb. This is only called when wantsHSB has + * changed, eg you shouldn't invoked adjustForHSB(true) twice. + */ + private void adjustForHSB(boolean wantsHSB, Rectangle available, + Rectangle hsbR, Insets vpbInsets) { + int oldHeight = hsbR.height; + if (wantsHSB) { + int hsbHeight = Math.max(0, Math.min(available.height, + hsb.getPreferredSize().height)); + + available.height -= hsbHeight; + hsbR.y = available.y + available.height + vpbInsets.bottom; + hsbR.height = hsbHeight; + } + else { + available.height += oldHeight; + } + } + + + /** + * Returns the bounds of the border around the specified scroll pane's + * viewport. + * + * @return the size and position of the viewport border + * @deprecated As of JDK version Swing1.1 + * replaced by JScrollPane.getViewportBorderBounds(). + */ + public Rectangle getViewportBorderBounds(JScrollPane scrollpane) { + return scrollpane.getViewportBorderBounds(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineIteratorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineIteratorImpl.java new file mode 100644 index 00000000000..874890121e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineIteratorImpl.java @@ -0,0 +1,45 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.ex.LineIterator; + +/** + * + */ +public class LineIteratorImpl implements LineIterator { + private int myLineIndex = 0; + private LineSet myLineSet; + + LineIteratorImpl(LineSet lineSet) { + myLineSet = lineSet; + } + + public void start(int startOffset) { + myLineIndex = myLineSet.findLineIndex(startOffset); + } + + public int getStart() { + return myLineSet.getLineStart(myLineIndex); + } + + public int getEnd() { + return myLineSet.getLineEnd(myLineIndex); + } + + public int getSeparatorLength() { + return myLineSet.getSeparatorLength(myLineIndex); + } + + public int getLineNumber() { + return myLineIndex; + } + + public void advance() { + myLineIndex++; + } + + public boolean atEnd() { + return myLineIndex >= myLineSet.getLineCount() || myLineIndex < 0; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineSet.java new file mode 100644 index 00000000000..25326812341 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/LineSet.java @@ -0,0 +1,181 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.LineIterator; +import com.intellij.openapi.editor.ex.util.SegmentArrayWithData; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.util.text.MergingCharSequence; + +/** + * + */ +public class LineSet{ + private SegmentArrayWithData mySegments = new SegmentArrayWithData(); + private static final int MODIFIED_MASK = 0x4; + private static final int SEPARATOR_MASK = 0x3; + + public int findLineIndex(int offset) { + return mySegments.findSegmentIndex(offset); + } + + public LineIterator createIterator() { + return new LineIteratorImpl(this); + } + + final int getLineStart(int index) { + return mySegments.getSegmentStart(index); + } + + final int getLineEnd(int index) { + return mySegments.getSegmentEnd(index); + } + + final boolean isModified(int index) { + return (mySegments.getSegmentData(index) & MODIFIED_MASK) != 0; + } + + final int getSeparatorLength(int index) { + return (int) (mySegments.getSegmentData(index) & SEPARATOR_MASK); + } + + final int getLineCount() { + return mySegments.getSegmentCount(); + } + + public void documentCreated(DocumentEvent e) { + initSegments(e.getDocument().getCharsSequence(), false); + } + + public void changedUpdate(DocumentEvent e1) { + DocumentEventImpl e = (DocumentEventImpl) e1; + if (e.isOnlyOneLineChanged() && mySegments.getSegmentCount() > 0) { + processOneLineChange(e); + } else { + if (mySegments.getSegmentCount() == 0 || e.getStartOldIndex() >= mySegments.getSegmentCount() || + e.getStartOldIndex() < 0) { + initSegments(e.getDocument().getCharsSequence(), true); + return; + } + + processMultilineChange(e); + } + + if (e.isWholeTextReplaced()) { + clearModificationFlags(); + } + } + + private void processMultilineChange(DocumentEventImpl e) { + int offset = e.getOffset(); + CharSequence newString = e.getNewFragment(); + CharSequence chars = e.getDocument().getCharsSequence(); + + int oldStartLine = e.getStartOldIndex(); + int offset1 = getLineStart(oldStartLine); + if (offset1 != offset) { + CharSequence prefix = chars.subSequence(offset1, offset); + newString = new MergingCharSequence(prefix, newString); + } + + int oldEndLine = findLineIndex(e.getOffset() + e.getOldLength()); + if (oldEndLine < 0) { + oldEndLine = getLineCount() - 1; + } + int offset2 = getLineEnd(oldEndLine); + if (offset2 != offset + e.getOldLength()) { + final int start = offset + e.getNewLength(); + final int length = offset2 - offset - e.getOldLength(); + CharSequence postfix = chars.subSequence(start, start + length); + newString = new MergingCharSequence(newString, postfix); + } + + updateSegments(newString, oldStartLine, oldEndLine, offset1, e); + // We add empty line at the end, if the last line ends by line separator. + addEmptyLineAtEnd(); + } + + private void updateSegments(CharSequence newText, int oldStartLine, int oldEndLine, int offset1, + DocumentEventImpl e) { + int count = 0; + LineTokenizer lineTokenizer = new LineTokenizer(newText); + for (int index = oldStartLine; index <= oldEndLine; index++) { + if (!lineTokenizer.atEnd()) { + setSegmentAt(mySegments, index, lineTokenizer, offset1, true); + lineTokenizer.advance(); + } else { + mySegments.remove(index, oldEndLine + 1); + break; + } + count++; + } + if (!lineTokenizer.atEnd()) { + SegmentArrayWithData insertSegments = new SegmentArrayWithData(); + int i = 0; + while (!lineTokenizer.atEnd()) { + setSegmentAt(insertSegments, i, lineTokenizer, offset1, true); + lineTokenizer.advance(); + count++; + i++; + } + mySegments.insert(insertSegments, oldEndLine + 1); + } + int shift = e.getNewLength() - e.getOldLength(); + mySegments.shiftSegments(oldStartLine + count, shift); + } + + private void processOneLineChange(DocumentEventImpl e) { + // Check, if the change on the end of text + if (e.getOffset() >= mySegments.getSegmentEnd(mySegments.getSegmentCount() - 1)) { + mySegments.changeSegmentLength(mySegments.getSegmentCount() - 1, e.getNewLength() - e.getOldLength()); + setSegmentModified(mySegments, mySegments.getSegmentCount() - 1); + } else { + mySegments.changeSegmentLength(e.getStartOldIndex(), e.getNewLength() - e.getOldLength()); + setSegmentModified(mySegments, e.getStartOldIndex()); + } + } + + private void clearModificationFlags() { + for (int i = 0; i < mySegments.getSegmentCount(); i++) { + mySegments.setSegmentData(i, mySegments.getSegmentData(i) & ~MODIFIED_MASK); + } + } + + private static void setSegmentAt(SegmentArrayWithData segmentArrayWithData, int index, LineTokenizer lineTokenizer, int offsetShift, boolean isModified) { + int offset = lineTokenizer.getOffset() + offsetShift; + int length = lineTokenizer.getLength(); + int separatorLength = lineTokenizer.getLineSeparatorLength(); + int separatorAndModifiedFlag = separatorLength; + if(isModified) { + separatorAndModifiedFlag |= MODIFIED_MASK; + } + segmentArrayWithData.setElementAt(index, offset, offset + length + separatorLength, separatorAndModifiedFlag); + } + + private static void setSegmentModified(SegmentArrayWithData segments, int i) { + segments.setSegmentData(i, segments.getSegmentData(i)|MODIFIED_MASK); + } + + private void initSegments(CharSequence text, boolean toSetModified) { + mySegments.removeAll(); + LineTokenizer lineTokenizer = new LineTokenizer(text); + int i = 0; + while(!lineTokenizer.atEnd()) { + setSegmentAt(mySegments, i, lineTokenizer, 0, toSetModified); + i++; + lineTokenizer.advance(); + } + // We add empty line at the end, if the last line ends by line separator. + addEmptyLineAtEnd(); + } + + // Add empty line at the end, if the last line ends by line separator. + private void addEmptyLineAtEnd() { + int segmentCount = mySegments.getSegmentCount(); + if(segmentCount > 0 && getSeparatorLength(segmentCount-1) > 0) { + mySegments.setElementAt(segmentCount, mySegments.getSegmentEnd(segmentCount-1), mySegments.getSegmentEnd(segmentCount-1), 0); + setSegmentModified(mySegments, segmentCount); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/MarkupModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/MarkupModelImpl.java new file mode 100644 index 00000000000..62e216f0cc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/MarkupModelImpl.java @@ -0,0 +1,183 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Apr 19, 2002 + * Time: 2:26:19 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.MarkupModelEx; +import com.intellij.openapi.editor.impl.event.MarkupModelEvent; +import com.intellij.openapi.editor.impl.event.MarkupModelListener; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.UserDataHolderBase; + +import java.util.ArrayList; + +public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.MarkupModelImpl"); + private DocumentImpl myDocument; + + private final HighlighterList myHighlighterList; + private ArrayList myHighlighters = new ArrayList(); + private RangeHighlighter[] myCachedHighlighters; + private ArrayList myListeners = new ArrayList(); + private MarkupModelListener[] myCachedListeners; + + MarkupModelImpl(DocumentImpl document) { + myDocument = document; + myHighlighterList = new HighlighterList(document); + } + + public void dispose() { + myHighlighterList.dispose(); + } + + public RangeHighlighter addLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (lineNumber >= getDocument().getLineCount() || lineNumber < 0) return null; + + int offset = getFirstNonspaceCharOffset(getDocument(), lineNumber); + + return addRangeHighlighter(offset, offset, layer, textAttributes, HighlighterTargetArea.LINES_IN_RANGE); + } + + public RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (lineNumber >= getDocument().getLineCount() || lineNumber < 0) return null; + + int offset = getFirstNonspaceCharOffset(getDocument(), lineNumber); + + return addRangeHighlighter(offset, offset, layer, textAttributes, HighlighterTargetArea.LINES_IN_RANGE, true); + } + + static int getFirstNonspaceCharOffset(Document doc, int lineNumber) { + int lineStart = doc.getLineStartOffset(lineNumber); + int lineEnd = doc.getLineEndOffset(lineNumber); + CharSequence text = doc.getCharsSequence(); + int offset = lineStart; + for (int i = lineStart; i < lineEnd; i++) { + char c = text.charAt(i); + if (c != ' ' && c != '\t') { + offset = i; + break; + } + } + return offset; + } + + public RangeHighlighter addLineHighliterAtOffset(int startOffset, + int endOffset, + int layer, + TextAttributes textAttributes) { + ApplicationManager.getApplication().assertIsDispatchThread(); + + RangeHighlighterImpl highlighter = new RangeHighlighterImpl(this, startOffset, endOffset, layer, + HighlighterTargetArea.LINES_IN_RANGE, textAttributes, + false); + + myHighlighters.add(highlighter); + myCachedHighlighters = null; + myHighlighterList.addSegmentHighlighter(highlighter); + fireSegmentHighlighterChanged(highlighter); + return highlighter; + } + + public RangeHighlighter[] getAllHighlighters() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myCachedHighlighters == null) { + myCachedHighlighters = myHighlighters.toArray(new RangeHighlighter[myHighlighters.size()]); + } + return myCachedHighlighters; + } + + private RangeHighlighter addRangeHighlighter(int startOffset, + int endOffset, + int layer, + TextAttributes textProperties, + HighlighterTargetArea targetArea, + boolean isPersistent) { + ApplicationManager.getApplication().assertIsDispatchThread(); + + RangeHighlighterImpl segmentHighlighter = new RangeHighlighterImpl(this, startOffset, endOffset, layer, targetArea, + textProperties, isPersistent); + myHighlighters.add(segmentHighlighter); + myCachedHighlighters = null; + myHighlighterList.addSegmentHighlighter(segmentHighlighter); + fireSegmentHighlighterChanged(segmentHighlighter); + return segmentHighlighter; + + } + + public RangeHighlighter addRangeHighlighter(int startOffset, + int endOffset, + int layer, + TextAttributes textProperties, + HighlighterTargetArea targetArea) { + return addRangeHighlighter(startOffset, endOffset, layer, textProperties, targetArea, false); + } + + public void removeHighlighter(RangeHighlighter segmentHighlighter) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean removed = myHighlighters.remove(segmentHighlighter); + myCachedHighlighters = null; + LOG.assertTrue(removed); + myHighlighterList.removeSegmentHighlighter(segmentHighlighter); + fireSegmentHighlighterChanged(segmentHighlighter); + } + + public void removeAllHighlighters() { + ApplicationManager.getApplication().assertIsDispatchThread(); + for (int i = 0; i < myHighlighters.size(); i++) { + RangeHighlighter highlighter = myHighlighters.get(i); + fireSegmentHighlighterChanged(highlighter); + myHighlighterList.removeSegmentHighlighter(highlighter); + } + myHighlighters.clear(); + myCachedHighlighters = null; + } + + public Document getDocument() { + return myDocument; + } + + public void addMarkupModelListener(MarkupModelListener listener) { + myListeners.add(listener); + myCachedListeners = null; + } + + public void removeMarkupModelListener(MarkupModelListener listener) { + boolean success = myListeners.remove(listener); + LOG.assertTrue(success); + myCachedListeners = null; + } + + private MarkupModelListener[] getCachedListeners() { + if (myCachedListeners == null) { + myCachedListeners = myListeners.toArray(new MarkupModelListener[myListeners.size()]); + } + + return myCachedListeners; + } + + protected void fireSegmentHighlighterChanged(RangeHighlighter segmentHighlighter) { + MarkupModelEvent event = new MarkupModelEvent(this, segmentHighlighter); + MarkupModelListener[] listeners = getCachedListeners(); + for (int i = 0; i < listeners.length; i++) { + MarkupModelListener listener = listeners[i]; + listener.rangeHighlighterChanged(event); + } + } + + public HighlighterList getHighlighterList() { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + return myHighlighterList; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentLineMarker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentLineMarker.java new file mode 100644 index 00000000000..55b1e8eb809 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentLineMarker.java @@ -0,0 +1,36 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; + +/** + * @author max + */ +public class PersistentLineMarker extends RangeMarkerImpl { + private int myLine; + public PersistentLineMarker(Document document, int offset) { + super(document, offset, offset); + myLine = document.getLineNumber(offset); + } + + public void documentChanged(DocumentEvent e) { + if (!isValid()) return; + + DocumentEventImpl event = (DocumentEventImpl) e; + if (event.isWholeTextReplaced()) { + myLine = event.translateLineViaDiff(myLine); + if (myLine < 0 || myLine >= getDocument().getLineCount()) { + invalidate(); + } else { + myStart = MarkupModelImpl.getFirstNonspaceCharOffset(getDocument(), myLine); + myEnd = myStart; + } + } else { + super.documentChanged(e); + if (isValid()) { + myLine = getDocument().getLineNumber(myStart); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentRangeMarker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentRangeMarker.java new file mode 100644 index 00000000000..702715c0866 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/PersistentRangeMarker.java @@ -0,0 +1,56 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; + +/** + * @author max + */ +public class PersistentRangeMarker extends RangeMarkerImpl { + private int myStartLine; + private int myStartColumn; + private int myEndLine; + private int myEndColumn; + + public PersistentRangeMarker(Document document, int startOffset, int endOffset) { + super(document, startOffset, endOffset); + storeLinesAndCols(); + } + + private void storeLinesAndCols() { + myStartLine = myDocument.getLineNumber(getStartOffset()); + myStartColumn = getStartOffset() - myDocument.getLineStartOffset(myStartLine); + myEndLine = myDocument.getLineNumber(getEndOffset()); + myEndColumn = getEndOffset() - myDocument.getLineStartOffset(myEndLine); + } + + public void documentChanged(DocumentEvent e) { + if (!isValid()) return; + + DocumentEventImpl event = (DocumentEventImpl)e; + if (event.isWholeTextReplaced()){ + myStartLine = event.translateLineViaDiffStrict(myStartLine); + if (myStartLine < 0 || myStartLine >= getDocument().getLineCount()){ + invalidate(); + } + else{ + myStart = getDocument().getLineStartOffset(myStartLine) + myStartColumn; + } + + myEndLine = event.translateLineViaDiffStrict(myEndLine); + if (myEndLine < 0 || myEndLine >= getDocument().getLineCount()){ + invalidate(); + } + else{ + myEnd = getDocument().getLineStartOffset(myEndLine) + myEndColumn; + } + } + else{ + super.documentChanged(e); + if (isValid()){ + storeLinesAndCols(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java new file mode 100644 index 00000000000..54761bf165b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java @@ -0,0 +1,192 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.RangeHighlighterEx; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.util.Key; + +import java.awt.*; + +/** + * @author max + */ +public class RangeHighlighterImpl implements RangeHighlighterEx { + private MarkupModelImpl myModel; + private int myLayer; + private HighlighterTargetArea myTargetArea; + private TextAttributes myTextAttributes; + private LineMarkerRenderer myLineMarkerRenderer; + private Color myErrorStripeColor; + private Color myLineSeparatorColor; + private SeparatorPlacement mySeparatorPlacement; + private boolean isAfterEndOfLine; + private final RangeMarkerImpl myRangeMarker; + private GutterIconRenderer myGutterIconRenderer; + private boolean myErrorStripeMarkIsThin; + private Object myErrorStripeTooltip; + private MarkupEditorFilter myFilter = MarkupEditorFilter.EMPTY; + + RangeHighlighterImpl(MarkupModel model, + int start, + int end, + int layer, + HighlighterTargetArea target, + TextAttributes textAttributes, + boolean persistent) { + myRangeMarker = persistent + ? new PersistentLineMarker(model.getDocument(), start) + : new RangeMarkerImpl(model.getDocument(), start, end); + myTextAttributes = textAttributes; + myTargetArea = target; + myLayer = layer; + myModel = (MarkupModelImpl)model; + } + + public TextAttributes getTextAttributes() { + return myTextAttributes; + } + + public int getLayer() { + return myLayer; + } + + public HighlighterTargetArea getTargetArea() { + return myTargetArea; + } + + public int getAffectedAreaStartOffset() { + int startOffset = getStartOffset(); + if (myTargetArea == HighlighterTargetArea.EXACT_RANGE) return startOffset; + if (startOffset == getDocument().getTextLength()) return startOffset; + return getDocument().getLineStartOffset(getDocument().getLineNumber(startOffset)); + } + + public int getAffectedAreaEndOffset() { + int endOffset = getEndOffset(); + if (myTargetArea == HighlighterTargetArea.EXACT_RANGE) return endOffset; + int textLength = getDocument().getTextLength(); + if (endOffset == textLength) return endOffset; + return Math.min(textLength, getDocument().getLineEndOffset(getDocument().getLineNumber(endOffset)) + 1); + } + + public LineMarkerRenderer getLineMarkerRenderer() { + return myLineMarkerRenderer; + } + + public void setLineMarkerRenderer(LineMarkerRenderer renderer) { + myLineMarkerRenderer = renderer; + fireChanged(); + } + + public GutterIconRenderer getGutterIconRenderer() { + return myGutterIconRenderer; + } + + public void setGutterIconRenderer(GutterIconRenderer renderer) { + myGutterIconRenderer = renderer; + fireChanged(); + } + + public Color getErrorStripeMarkColor() { + return myErrorStripeColor; + } + + public void setErrorStripeMarkColor(Color color) { + myErrorStripeColor = color; + fireChanged(); + } + + public Object getErrorStripeTooltip() { + return myErrorStripeTooltip; + } + + public void setErrorStripeTooltip(Object tooltipObject) { + myErrorStripeTooltip = tooltipObject; + } + + public boolean isThinErrorStripeMark() { + return myErrorStripeMarkIsThin; + } + + public void setThinErrorStripeMark(boolean value) { + myErrorStripeMarkIsThin = value; + } + + public Color getLineSeparatorColor() { + return myLineSeparatorColor; + } + + public void setLineSeparatorColor(Color color) { + myLineSeparatorColor = color; + fireChanged(); + } + + public SeparatorPlacement getLineSeparatorPlacement() { + return mySeparatorPlacement; + } + + public void setLineSeparatorPlacement(SeparatorPlacement placement) { + mySeparatorPlacement = placement; + fireChanged(); + } + + public void setEditorFilter(MarkupEditorFilter filter) { + myFilter = filter; + } + + public MarkupEditorFilter getEditorFilter() { + return myFilter; + } + + public boolean isAfterEndOfLine() { + return isAfterEndOfLine; + } + + public void setAfterEndOfLine(boolean afterEndOfLine) { + isAfterEndOfLine = afterEndOfLine; + } + + private void fireChanged() { + myModel.fireSegmentHighlighterChanged(this); + } + + public int getStartOffset() { + return myRangeMarker.getStartOffset(); + } + + public long getId() { + return myRangeMarker.getId(); + } + + public int getEndOffset() { + return myRangeMarker.getEndOffset(); + } + + public boolean isValid() { + return myRangeMarker.isValid(); + } + + public Document getDocument() { + return myRangeMarker.getDocument(); + } + + public void setGreedyToLeft(boolean greedy) { + myRangeMarker.setGreedyToLeft(greedy); + } + + public void setGreedyToRight(boolean greedy) { + myRangeMarker.setGreedyToRight(greedy); + } + + public T getUserData(Key key) { + return myRangeMarker.getUserData(key); + } + + public void putUserData(Key key, T value) { + myRangeMarker.putUserData(key, value); + } + + public String toString() { + return myRangeMarker.toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeIterator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeIterator.java new file mode 100644 index 00000000000..48105b3e2fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeIterator.java @@ -0,0 +1,146 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.FoldingModel; +import com.intellij.openapi.editor.ex.HighlighterIterator; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.TextRange; +import gnu.trove.Equality; + +class RangeIterator { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeIterator"); + private static final int NO_NEXT = -1; + private int myRangeEnd; + + public interface Gaps { + boolean isGapAt(int offset); + } + + private final HighlighterIterator mySource; + private final Equality myEquality; + private final Gaps myGaps; + private final Condition myFilter; + private boolean mySourceOutOfRange = false; + + private int myStart; + private int myEnd; + private TextAttributes myTextAttributes; + private int myNextExpanded; + + public RangeIterator(Gaps foldingModel, Equality equality, + HighlighterIterator source, Condition filter) { + mySource = source; + myGaps = foldingModel; + myEquality = equality; + myFilter = filter; + } + + public void init(TextRange range) { + int rangeStart = range.getStartOffset(); + myRangeEnd = range.getEndOffset(); + while(!mySource.atEnd()) { + boolean sourceBeforeRange = rangeStart > mySource.getEnd(); + if (!sourceBeforeRange) break; + mySource.advance(); + } + while (!mySource.atEnd() && !checkOutOfRange()) { + if (myFilter.value(mySource.getTextAttributes())) break; + mySource.advance(); + } + + if (mySource.atEnd() || mySourceOutOfRange) myNextExpanded = NO_NEXT; + else { + myNextExpanded = findExpanded(mySource.getStart()); + if (myNextExpanded == NO_NEXT) myStart = NO_NEXT; + } + } + + private boolean checkOutOfRange() { + if (mySourceOutOfRange) return true; + mySourceOutOfRange = mySource.getStart() > myRangeEnd; + boolean sourceOutOfRange = mySourceOutOfRange; + return sourceOutOfRange; + } + + private void doAdvanceFrom(int start) { + myStart = start; + myEnd = myStart; + doAdvance(); + if (mySource.atEnd()) myNextExpanded = NO_NEXT; + else myNextExpanded = findExpanded(Math.max(myEnd, mySource.getStart())); + } + + private void doAdvance() { + myStart = findExpanded(myStart); + myEnd = findFolding(myStart, mySource.getEnd(), true); + myTextAttributes = mySource.getTextAttributes(); + while (myEnd == mySource.getEnd()) { + if (!advanceSource()) return; + if (mySource.getStart() != myEnd) return; + if (!myEquality.equals(myTextAttributes, mySource.getTextAttributes())) return; + myEnd = findFolding(myEnd, mySource.getEnd(), true); + } + } + + private boolean advanceSource() { + if (mySource.atEnd()) return false; + do { + mySource.advance(); + } while (!(mySource.atEnd() || checkOutOfRange() || myFilter.value(mySource.getTextAttributes()))); + return !mySource.atEnd(); + } + + private int findExpanded(int start) { + start = findFolding(start, mySource.getEnd(), false); + while (start == mySource.getEnd()) { + if (!advanceSource()) return NO_NEXT; + start = findFolding(mySource.getStart(), mySource.getEnd(), false); + } + return start; + } + + private int findFolding(int start, int end, boolean collapsed) { + int position = start; + while (position < end) { + if (myGaps.isGapAt(position) == collapsed) break; + else position++; + } + return position; + } + + public int getStart() { + return myStart; + } + + public int getEnd() { + return myEnd; + } + + public TextAttributes getTextAttributes() { + LOG.assertTrue(myFilter.value(myTextAttributes)); + return myTextAttributes; + } + + public void advance() { + doAdvanceFrom(myNextExpanded); + } + + public boolean atEnd() { + return myStart == NO_NEXT || mySourceOutOfRange || + (mySource.atEnd() && (myNextExpanded == NO_NEXT || + myNextExpanded == mySource.getEnd())); + } + + public static class FoldingGaps implements Gaps { + private final FoldingModel myFoldingModel; + + public FoldingGaps(FoldingModel foldingModel) { + myFoldingModel = foldingModel; + } + + public boolean isGapAt(int offset) { + return myFoldingModel.isOffsetCollapsed(offset); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeMarkerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeMarkerImpl.java new file mode 100644 index 00000000000..01d033df5bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/RangeMarkerImpl.java @@ -0,0 +1,173 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.util.Key; +import gnu.trove.THashMap; + +public class RangeMarkerImpl extends DocumentAdapter implements RangeMarker { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeMarkerImpl"); + + protected Document myDocument; + protected int myStart; + protected int myEnd; + private boolean isValid = true; + private boolean isExpandToLeft = false; + private boolean isExpandToRight = false; + + private static long counter = 0; + private long myId; + + private THashMap myUserMap = null; + + public RangeMarkerImpl(Document document, int start, int end) { + if (!(start <= end && start >= 0 && end <= document.getTextLength())) { + LOG.assertTrue(start <= end); + LOG.assertTrue(start >= 0, "Wrong start: " + start); + LOG.assertTrue(end <= document.getTextLength(), "Wrong end: " + end); + } + + myDocument = document; + myStart = start; + myEnd = end; + myId = counter; + counter++; + ((DocumentImpl)myDocument).addRangeMarker(this); + } + + public long getId() { + return myId; + } + + public int getStartOffset() { + return myStart; + } + + public int getEndOffset() { + return myEnd; + } + + public boolean isValid() { + return isValid; + } + + public void invalidate() { + isValid = false; + } + + public Document getDocument() { + return myDocument; + } + + public void setGreedyToLeft(boolean greedy) { + isExpandToLeft = greedy; + } + + public void setGreedyToRight(boolean greedy) { + isExpandToRight = greedy; + } + + public void documentChanged(DocumentEvent e) { + int oldStart = myStart; + int oldEnd = myEnd; + changedUpdateImpl(e); + if (isValid && (myStart > myEnd || myStart < 0 || myEnd > myDocument.getTextLength())) { + LOG.error("RangeMarker[" + oldStart + ", " + oldEnd + "] update failed. Event = " + e + ". Result[" + myStart + ", " + myEnd + "], doc length=" + myDocument.getTextLength()); + isValid = false; + } + } + + private void changedUpdateImpl(DocumentEvent e) { + if (!isValid) return; + + // Process if one point. + if (myStart == myEnd && !isExpandToRight && !isExpandToLeft) { + processIfOnePoint(e); + return; + } + + final int offset = e.getOffset(); + final int oldLength = e.getOldLength(); + final int newLength = e.getNewLength(); + + // changes after the end. + if (myEnd < offset || (!isExpandToRight && myEnd == offset)) { + return; + } + + // changes before start + if (myStart > offset + oldLength || (!isExpandToLeft && myStart == offset + oldLength)) { + myStart += newLength - oldLength; + myEnd += newLength - oldLength; + return; + } + + // Changes inside marker's area. Expand/collapse. + if (myStart <= offset && myEnd >= offset + oldLength) { + myEnd += newLength - oldLength; + return; + } + + // At this point we either have (myStart xor myEnd inside changed area) or whole area changed. + + // Replacing prefix or suffix... + if (myStart >= offset && myStart <= offset + oldLength && myEnd > offset + oldLength) { + myEnd += newLength - oldLength; + myStart = offset + newLength; + return; + } + + if (myEnd >= offset && myEnd <= offset + oldLength && myStart < offset) { + myEnd = offset; + return; + } + + invalidate(); + } + + private void processIfOnePoint(DocumentEvent e) { + int offset = e.getOffset(); + int oldLength = e.getOldLength(); + int oldEnd = offset + oldLength; + if (myStart > offset && myStart < oldEnd) { + invalidate(); + return; + } + if (myStart > oldEnd || myStart == oldEnd && oldLength > 0) { + myStart += e.getNewLength() - oldLength; + myEnd += e.getNewLength() - oldLength; + } + } + + public T getUserData(Key key){ + synchronized(this){ + if (myUserMap == null) return null; + return (T)myUserMap.get(key); + } + } + + public void putUserData(Key key, T value){ + synchronized(this){ + if (myUserMap == null){ + if (value == null) return; + myUserMap = new THashMap(); + } + if (value != null){ + myUserMap.put(key, value); + } + else{ + myUserMap.remove(key); + if (myUserMap.size() == 0){ + myUserMap = null; + } + } + } + } + + public String toString() { + return "RangeMarker[" + (isValid ? "valid" : "invalid") + "," + myStart + "," + myEnd + "]"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/ScrollingModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/ScrollingModelImpl.java new file mode 100644 index 00000000000..225b50d7e44 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/ScrollingModelImpl.java @@ -0,0 +1,485 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 10, 2002 + * Time: 10:14:59 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ScrollingModel; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.VisibleAreaEvent; +import com.intellij.openapi.editor.event.VisibleAreaListener; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.ArrayList; + +public class ScrollingModelImpl implements ScrollingModel { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.ScrollingModelImpl"); + + private EditorImpl myEditor; + private ArrayList myVisibleAreaListeners = new ArrayList(); + + private AnimatedScrollingRunnable myCurrentAnimatedRunnable = null; + private final Object myAnimatedLock = new Object(); + private boolean myAnimationDisabled = false; + private DocumentAdapter myDocumentListener; + + public ScrollingModelImpl(EditorImpl editor) { + myEditor = editor; + + myEditor.getScrollPane().getViewport().addChangeListener(new ChangeListener() { + private Rectangle myLastViewRect; + + public void stateChanged(ChangeEvent event) { + Rectangle viewRect = getVisibleArea(); + VisibleAreaEvent visibleAreaEvent = new VisibleAreaEvent(myEditor, myLastViewRect, viewRect); + myLastViewRect = viewRect; + VisibleAreaListener[] listeners = myVisibleAreaListeners.toArray( + new VisibleAreaListener[myVisibleAreaListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].visibleAreaChanged(visibleAreaEvent); + } + } + }); + + myDocumentListener = new DocumentAdapter() { + public void beforeDocumentChange(DocumentEvent e) { + cancelAnimatedScrolling(true); + } + }; + myEditor.getDocument().addDocumentListener(myDocumentListener); + } + + public Rectangle getVisibleArea() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) { + return new Rectangle(0, 0, 0, 0); + } + return myEditor.getScrollPane().getViewport().getViewRect(); + } + + public Rectangle getVisibleAreaOnScrollingFinished() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myCurrentAnimatedRunnable != null) { + return myCurrentAnimatedRunnable.getTargetVisibleArea(); + } + else { + return getVisibleArea(); + } + } + + public void scrollToCaret(ScrollType scrollType) { + ApplicationManager.getApplication().assertIsDispatchThread(); + LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition(); + scrollTo(caretPosition, scrollType); + } + + public void scrollTo(LogicalPosition pos, ScrollType scrollType) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) return; + + AnimatedScrollingRunnable canceledThread = cancelAnimatedScrolling(false); + Rectangle viewRect = canceledThread != null ? canceledThread.getTargetVisibleArea() : getVisibleArea(); + + Point p = calcOffsetsToScroll(pos, scrollType, viewRect); + scrollToOffsets(p.x, p.y); + } + + public void runActionOnScrollingFinished(Runnable action) { + ApplicationManager.getApplication().assertIsDispatchThread(); + + synchronized (myAnimatedLock) { + if (myCurrentAnimatedRunnable != null) { + myCurrentAnimatedRunnable.addPostRunnable(action); + return; + } + } + + action.run(); + } + + public void disableAnimation() { + myAnimationDisabled = true; + } + + public void enableAnimation() { + myAnimationDisabled = false; + } + + private Point calcOffsetsToScroll(LogicalPosition pos, ScrollType scrollType, Rectangle viewRect) { + Point targetLocation = myEditor.logicalPositionToXY(pos); + + int spaceWidth = myEditor.getSpaceWidth(Font.PLAIN); + int xInsets = myEditor.getSettings().getAdditionalColumnsCount() * spaceWidth; + + int hOffset = scrollType == ScrollType.CENTER || + scrollType == ScrollType.CENTER_DOWN || + scrollType == ScrollType.CENTER_UP ? 0 : viewRect.x; + if (targetLocation.x < hOffset) { + hOffset = targetLocation.x - 4 * spaceWidth; + hOffset = hOffset > 0 ? hOffset : 0; + } + else if (targetLocation.x > viewRect.x + viewRect.width - xInsets) { + hOffset = targetLocation.x - viewRect.width + xInsets; + } + + int scrollUpBy = viewRect.y + myEditor.getLineHeight() - targetLocation.y; + int scrollDownBy = targetLocation.y - (viewRect.y + viewRect.height - 2 * myEditor.getLineHeight()); + int centerPosition = targetLocation.y - viewRect.height / 3; + + int vOffset = viewRect.y; + if (scrollType == ScrollType.CENTER) { + vOffset = centerPosition; + } + else if (scrollType == ScrollType.CENTER_UP) { + if (scrollUpBy > 0 || scrollDownBy > 0 || vOffset > centerPosition) { + vOffset = centerPosition; + } + } + else if (scrollType == ScrollType.CENTER_DOWN) { + if (scrollUpBy > 0 || scrollDownBy > 0 || vOffset < centerPosition) { + vOffset = centerPosition; + } + } + else if (scrollType == ScrollType.RELATIVE) { + if (scrollUpBy > 0) { + vOffset = viewRect.y - scrollUpBy; + } + else if (scrollDownBy > 0) { + vOffset = viewRect.y + scrollDownBy; + } + } + else if (scrollType == ScrollType.MAKE_VISIBLE) { + if (scrollUpBy > 0 || scrollDownBy > 0) { + vOffset = centerPosition; + } + } + + JScrollPane scrollPane = myEditor.getScrollPane(); + hOffset = Math.max(0, hOffset); + vOffset = Math.max(0, vOffset); + hOffset = Math.min(scrollPane.getHorizontalScrollBar().getMaximum(), hOffset); + vOffset = Math.min(scrollPane.getVerticalScrollBar().getMaximum(), vOffset); + + return new Point(hOffset, vOffset); + } + + public int getVerticalScrollOffset() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) return 0; + + JScrollBar scrollbar = myEditor.getScrollPane().getVerticalScrollBar(); + return scrollbar.getValue(); + } + + public int getHorizontalScrollOffset() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) return 0; + + JScrollBar scrollbar = myEditor.getScrollPane().getHorizontalScrollBar(); + return scrollbar.getValue(); + } + + public void scrollVertically(int scrollOffset) { + scrollToOffsets(getHorizontalScrollOffset(), scrollOffset); + } + + private void _scrollVertically(int scrollOffset) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) return; + + myEditor.validateSize(); + JScrollBar scrollbar = myEditor.getScrollPane().getVerticalScrollBar(); + scrollbar.setValue(scrollOffset); + + //System.out.println("scrolled vertically to: " + scrollOffset); + } + + public void scrollHorizontally(int scrollOffset) { + scrollToOffsets(scrollOffset, getVerticalScrollOffset()); + } + + private void _scrollHorizontally(int scrollOffset) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myEditor.getScrollPane() == null) return; + + myEditor.validateSize(); + JScrollBar scrollbar = myEditor.getScrollPane().getHorizontalScrollBar(); + scrollbar.setValue(scrollOffset); + } + + private void scrollToOffsets(int hOffset, int vOffset) { + cancelAnimatedScrolling(false); + + VisibleEditorsTracker editorsTracker = VisibleEditorsTracker.getInstance(); + boolean useAnimation; + //System.out.println("myCurrentCommandStart - myLastCommandFinish = " + (myCurrentCommandStart - myLastCommandFinish)); + if (!myEditor.getSettings().isAnimatedScrolling() || myAnimationDisabled) { + useAnimation = false; + } + else if (CommandProcessor.getInstance().getCurrentCommand() == null) { + useAnimation = myEditor.getComponent().isShowing(); + } + else if (editorsTracker.getCurrentCommandStart() - editorsTracker.getLastCommandFinish() < + AnimatedScrollingRunnable.SCROLL_DURATION) { + useAnimation = false; + } + else { + useAnimation = editorsTracker.wasEditorVisibleOnCommandStart(myEditor); + } + + if (useAnimation) { + //System.out.println("scrollToAnimated: " + endVOffset); + + int startHOffset = getHorizontalScrollOffset(); + int startVOffset = getVerticalScrollOffset(); + + if (startHOffset == hOffset && startVOffset == vOffset) { + return; + } + + //System.out.println("startVOffset = " + startVOffset); + + try { + myCurrentAnimatedRunnable = new AnimatedScrollingRunnable(startHOffset, startVOffset, hOffset, vOffset); + new Thread(myCurrentAnimatedRunnable, "AnimatedScrollingThread").start(); + } + catch (NoAnimationRequiredException e) { + _scrollHorizontally(hOffset); + _scrollVertically(vOffset); + } + } + else { + _scrollHorizontally(hOffset); + _scrollVertically(vOffset); + } + } + + public void addVisibleAreaListener(VisibleAreaListener listener) { + myVisibleAreaListeners.add(listener); + } + + public void removeVisibleAreaListener(VisibleAreaListener listener) { + boolean success = myVisibleAreaListeners.remove(listener); + LOG.assertTrue(success); + } + + public void commandStarted() { + cancelAnimatedScrolling(true); + } + + private AnimatedScrollingRunnable cancelAnimatedScrolling(boolean scrollToTarget) { + synchronized (myAnimatedLock) { + AnimatedScrollingRunnable thread = myCurrentAnimatedRunnable; + myCurrentAnimatedRunnable = null; + if (thread != null) { + thread.cancel(scrollToTarget); + } + return thread; + } + } + + public void dispose() { + myEditor.getDocument().removeDocumentListener(myDocumentListener); + } + + public void beforeModalityStateChanged() { + cancelAnimatedScrolling(true); + } + + private class AnimatedScrollingRunnable implements Runnable { + private static final int SCROLL_DURATION = 150; + private static final int SCROLL_INTERVAL = 10; + + private final int myStartHOffset; + private final int myStartVOffset; + private final int myEndHOffset; + private final int myEndVOffset; + private final int myAnimationDuration; + + private ArrayList myPostRunnables = new ArrayList(); + + private final Runnable myStartCommand; + private final int myHDist; + private final int myVDist; + private final int myMaxDistToScroll; + private final double myTotalDist; + private final double myScrollDist; + + private boolean myCanceled = false; + private final int myStepCount; + private final double myPow; + private final ModalityState myModalityState; + + public AnimatedScrollingRunnable(int startHOffset, + int startVOffset, + int endHOffset, + int endVOffset) throws NoAnimationRequiredException { + myStartHOffset = startHOffset; + myStartVOffset = startVOffset; + myEndHOffset = endHOffset; + myEndVOffset = endVOffset; + + myHDist = Math.abs(myEndHOffset - myStartHOffset); + myVDist = Math.abs(myEndVOffset - myStartVOffset); + + myMaxDistToScroll = myEditor.getLineHeight() * 50; + myTotalDist = Math.sqrt((double)myHDist * myHDist + (double)myVDist * myVDist); + myScrollDist = Math.min(myTotalDist, myMaxDistToScroll); + myAnimationDuration = calcAnimationDuration(); + if (myAnimationDuration < SCROLL_INTERVAL * 2) { + throw new NoAnimationRequiredException(); + } + myStepCount = myAnimationDuration / SCROLL_INTERVAL - 1; + double firstStepTime = 1.0 / myStepCount; + double firstScrollDist = 5.0; + if (myTotalDist > myScrollDist) { + firstScrollDist *= myTotalDist / myScrollDist; + firstScrollDist = Math.min(firstScrollDist, myEditor.getLineHeight() * 5); + } + myPow = myScrollDist > 0 ? setupPow(firstStepTime, firstScrollDist / myScrollDist) : 1; + + myStartCommand = CommandProcessor.getInstance().getCurrentCommand(); + myModalityState = ModalityState.current(); + } + + public Rectangle getTargetVisibleArea() { + Rectangle viewRect = getVisibleArea(); + return new Rectangle(myEndHOffset, myEndVOffset, viewRect.width, viewRect.height); + } + + public Runnable getStartCommand() { + return myStartCommand; + } + + public void run() { + long startTime = System.currentTimeMillis(); + ScrollLoop: + for (int i = 0; i < myStepCount; i++) { + synchronized (myAnimatedLock) { + if (myCanceled) return; + + double time = (i + 1) / (double)myStepCount; + double fraction = timeToFraction(time); + final int hOffset = (int)(myStartHOffset + (myEndHOffset - myStartHOffset) * fraction + 0.5); + final int vOffset = (int)(myStartVOffset + (myEndVOffset - myStartVOffset) * fraction + 0.5); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myCanceled) return; + _scrollHorizontally(hOffset); + _scrollVertically(vOffset); + } + }, myModalityState); + } + + long delay; + while (true) { + long nextStopTime = startTime + i * SCROLL_INTERVAL; + long currentTime = System.currentTimeMillis(); + delay = nextStopTime - currentTime; + //System.out.println("delay = " + delay); + if (delay >= 0) break; + if (++i == myStepCount) break ScrollLoop; + } + + try { + Thread.sleep(delay); + } + catch (InterruptedException e) { + } + } + + synchronized (myAnimatedLock) { + if (myCanceled) return; + finish(true, true); + } + } + + public void cancel(boolean scrollToTarget) { + ApplicationManager.getApplication().assertIsDispatchThread(); + synchronized (myAnimatedLock) { + myCanceled = true; + finish(false, scrollToTarget); + } + } + + public void addPostRunnable(Runnable runnable) { + myPostRunnables.add(runnable); + } + + private void finish(boolean needInvokeLater, boolean scrollToTarget) { + if (scrollToTarget || myPostRunnables.size() > 0) { + Runnable runnable = new Runnable() { + public void run() { + _scrollHorizontally(myEndHOffset); + _scrollVertically(myEndVOffset); + + for (int i = 0; i < myPostRunnables.size(); i++) { + Runnable runnable = myPostRunnables.get(i); + runnable.run(); + } + } + }; + + if (needInvokeLater) { + ApplicationManager.getApplication().invokeLater(runnable, myModalityState); + } + else { + runnable.run(); + } + } + + + if (myCurrentAnimatedRunnable == this) { + myCurrentAnimatedRunnable = null; + } + } + + private double timeToFraction(double time) { + if (time > 0.5) { + return 1 - timeToFraction(1 - time); + } + + double fraction = Math.pow(time * 2, myPow) / 2; + + if (myTotalDist > myMaxDistToScroll) { + fraction *= (double)myMaxDistToScroll / myTotalDist; + } + + return fraction; + } + + private double setupPow(double inTime, double moveBy) { + double pow = Math.log(2 * moveBy) / Math.log(2 * inTime); + if (pow < 1) pow = 1; + return pow; + } + + private int calcAnimationDuration() { + int lineHeight = myEditor.getLineHeight(); + double lineDist = myTotalDist / lineHeight; + double part = (lineDist - 1) / 10; + if (part > 1) part = 1; + int duration = (int)(part * SCROLL_DURATION); + //System.out.println("duration = " + duration); + return duration; + } + } + + private static class NoAnimationRequiredException extends Exception { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SelectionModelImpl.java new file mode 100644 index 00000000000..353722713e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -0,0 +1,524 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Apr 19, 2002 + * Time: 1:51:41 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actions.EditorActionUtil; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.event.SelectionEvent; +import com.intellij.openapi.editor.event.SelectionListener; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.util.ArrayList; + +public class SelectionModelImpl implements SelectionModel, DocumentListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.SelectionModelImpl"); + private static final int[] EMPTY_INTS_ARRAY = new int[0]; + + private ArrayList mySelectionListeners = new ArrayList(); + private MyRangeMarker mySelectionMarker = null; + private EditorImpl myEditor; + private int myLastSelectionStart; + private LogicalPosition myBlockStart; + private LogicalPosition myBlockEnd; + private TextAttributes myTextAttributes; + private boolean myIsInUpdate; + + class MyRangeMarker extends RangeMarkerImpl { + private boolean myIsReleased; + + public MyRangeMarker(Document document, int start, int end) { + super(document, start, end); + myIsReleased = false; + } + + public void release() { + myIsReleased = true; + } + + public void documentChanged(DocumentEvent e) { + if (!myIsReleased) { + int startBefore = getStartOffset(); + int endBefore = getEndOffset(); + super.documentChanged(e); + + if (!isValid()) { + myLastSelectionStart = myEditor.getCaretModel().getOffset(); + release(); + mySelectionMarker = null; + fireSelectionChanged(startBefore, endBefore, myLastSelectionStart, myLastSelectionStart); + return; + } + + if (startBefore != getStartOffset() || endBefore != getStartOffset()) { + fireSelectionChanged(startBefore, endBefore, getStartOffset(), getEndOffset()); + } + } + } + } + + public void beforeDocumentChange(DocumentEvent event) { + myIsInUpdate = true; + } + + public void documentChanged(DocumentEvent event) { + myIsInUpdate = false; + if (mySelectionMarker != null && mySelectionMarker.isValid()) { + mySelectionMarker.documentChanged(event); + } + } + + public SelectionModelImpl(EditorImpl editor) { + myEditor = editor; + } + + public int getSelectionStart() { + validateContext(); + if (!hasSelection()) return myEditor.getCaretModel().getOffset(); + return mySelectionMarker.getStartOffset(); + } + + private void validateContext() { + ApplicationManager.getApplication().assertIsDispatchThread(); + LOG.assertTrue(!myIsInUpdate, "Selection model is in its update stage. All requests are illegal at this point."); + } + + public int getSelectionEnd() { + validateContext(); + if (!hasSelection()) return myEditor.getCaretModel().getOffset(); + return mySelectionMarker.getEndOffset(); + } + + public boolean hasSelection() { + validateContext(); + if (mySelectionMarker != null && !mySelectionMarker.isValid()) { + removeSelection(); + } + + return mySelectionMarker != null; + } + + public void setSelection(int startOffset, int endOffset) { + validateContext(); + + removeBlockSelection(); + Document doc = myEditor.getDocument(); + + if (!(startOffset >= 0 && startOffset <= doc.getTextLength() && endOffset >= 0 && endOffset <= doc.getTextLength())) { + LOG.assertTrue(startOffset >= 0 && startOffset <= doc.getTextLength(), "Wrong startOffset: " + startOffset); + LOG.assertTrue(endOffset >= 0 && endOffset <= doc.getTextLength(), "Wrong endOffset: " + endOffset); + } + + myLastSelectionStart = startOffset; + if (startOffset == endOffset) { + removeSelection(); + return; + } + + /* Normalize selection */ + if (startOffset > endOffset) { + int tmp = startOffset; + startOffset = endOffset; + endOffset = tmp; + } + + { + Clipboard clip = myEditor.getComponent ().getToolkit ().getSystemSelection(); + if (clip != null) { + clip.setContents(new StringSelection(getSelectedText()), defaultClipboardOwner); + } + } + + int oldSelectionStart; + int oldSelectionEnd; + + if (hasSelection()) { + oldSelectionStart = mySelectionMarker.getStartOffset(); + oldSelectionEnd = mySelectionMarker.getEndOffset(); + if (oldSelectionStart == startOffset && oldSelectionEnd == endOffset) return; + } + else { + oldSelectionStart = oldSelectionEnd = myEditor.getCaretModel().getOffset(); + } + + if (mySelectionMarker != null) { + mySelectionMarker.release(); + } + + mySelectionMarker = new MyRangeMarker(doc, startOffset, endOffset); + + fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset); + } + + private void fireSelectionChanged(int oldSelectionStart, int oldSelectionEnd, int startOffset, int endOffset) { + repaintBySelectionChange(oldSelectionStart, startOffset, oldSelectionEnd, endOffset); + + SelectionEvent event = new SelectionEvent(myEditor, + oldSelectionStart, oldSelectionEnd, + startOffset, endOffset); + + SelectionListener[] listeners = mySelectionListeners.toArray(new SelectionListener[mySelectionListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + try { + listeners[i].selectionChanged(event); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + private void repaintBySelectionChange(int oldSelectionStart, int startOffset, int oldSelectionEnd, int endOffset) { + myEditor.repaint(Math.min(oldSelectionStart, startOffset), Math.max(oldSelectionStart, startOffset)); + myEditor.repaint(Math.min(oldSelectionEnd, endOffset), Math.max(oldSelectionEnd, endOffset)); + } + + public void setBlockSelection(LogicalPosition blockStart, LogicalPosition blockEnd) { + removeSelection(); + + int oldStartLine = 0; + int oldEndLine = 0; + + if (hasBlockSelection()) { + oldStartLine = myBlockStart.line; + oldEndLine = myBlockEnd.line; + if (oldStartLine > oldEndLine) { + int t = oldStartLine; + oldStartLine = oldEndLine; + oldEndLine = t; + } + } + + int newStartLine = blockStart.line; + int newEndLine = blockEnd.line; + + if (newStartLine > newEndLine) { + int t = newStartLine; + newStartLine = newEndLine; + newEndLine = t; + } + + myEditor.repaintLines(Math.min(oldStartLine, newStartLine), Math.max(newEndLine, oldEndLine)); + myBlockStart = blockStart; + myBlockEnd = blockEnd; + } + + public void removeSelection() { + validateContext(); + removeBlockSelection(); + myLastSelectionStart = myEditor.getCaretModel().getOffset(); + if (mySelectionMarker != null) { + int startOffset = mySelectionMarker.getStartOffset(); + int endOffset = mySelectionMarker.getEndOffset(); + mySelectionMarker.release(); + mySelectionMarker = null; + fireSelectionChanged(startOffset, endOffset, myLastSelectionStart, myLastSelectionStart); + } + } + + public void removeBlockSelection() { + if (hasBlockSelection()) { + myEditor.repaint(0, myEditor.getDocument().getTextLength()); + myBlockStart = null; + myBlockEnd = null; + } + } + + public boolean hasBlockSelection() { + return myBlockStart != null; + } + + public LogicalPosition getBlockStart() { + return myBlockStart; + } + + public LogicalPosition getBlockEnd() { + return myBlockEnd; + } + + public boolean isBlockSelectionGuarded() { + if (!hasBlockSelection()) return false; + int[] starts = getBlockSelectionStarts(); + int[] ends = getBlockSelectionEnds(); + Document doc = myEditor.getDocument(); + for (int i = 0; i < starts.length; i++) { + int start = starts[i]; + int end = ends[i]; + if (start == end && doc.getOffsetGuard(start) != null || start != end && doc.getRangeGuard(start, end) != null) { + return true; + } + } + return false; + } + + public RangeMarker getBlockSelectionGuard() { + if (!hasBlockSelection()) return null; + + int[] starts = getBlockSelectionStarts(); + int[] ends = getBlockSelectionEnds(); + Document doc = myEditor.getDocument(); + for (int i = 0; i < starts.length; i++) { + int start = starts[i]; + int end = ends[i]; + if (start == end) { + RangeMarker guard = doc.getOffsetGuard(start); + if (guard != null) return guard; + } + if (start != end) { + RangeMarker guard = doc.getRangeGuard(start, end); + if (guard != null) return guard; + } + } + + return null; + } + + public int[] getBlockSelectionStarts() { + if (hasSelection()) { + return new int[]{getSelectionStart()}; + } + if (!hasBlockSelection()) { + return EMPTY_INTS_ARRAY; + } + + int lineCount = Math.abs(myBlockEnd.line - myBlockStart.line) + 1; + int startLine = Math.min(myBlockStart.line, myBlockEnd.line); + + int startColumn = Math.min(myBlockStart.column, myBlockEnd.column); + + int[] res = new int[lineCount]; + for (int i = startLine; i < startLine + lineCount; i++) { + res[i - startLine] = myEditor.logicalPositionToOffset(new LogicalPosition(i, startColumn)); + } + + return res; + } + + public int[] getBlockSelectionEnds() { + if (hasSelection()) { + return new int[]{getSelectionEnd()}; + } + + if (!hasBlockSelection()) { + return EMPTY_INTS_ARRAY; + } + + int lineCount = Math.abs(myBlockEnd.line - myBlockStart.line) + 1; + int startLine = Math.min(myBlockStart.line, myBlockEnd.line); + + int startColumn = Math.min(myBlockStart.column, myBlockEnd.column); + int columnCount = Math.abs(myBlockEnd.column - myBlockStart.column); + + int[] res = new int[lineCount]; + for (int i = startLine; i < startLine + lineCount; i++) { + res[i - startLine] = myEditor.logicalPositionToOffset(new LogicalPosition(i, startColumn + columnCount)); + } + + return res; + } + + public void addSelectionListener(SelectionListener listener) { + mySelectionListeners.add(listener); + } + + public void removeSelectionListener(SelectionListener listener) { + boolean success = mySelectionListeners.remove(listener); + LOG.assertTrue(success); + } + + public String getSelectedText() { + validateContext(); + if (!hasSelection() && !hasBlockSelection()) return null; + + CharSequence text = myEditor.getDocument().getCharsSequence(); + if (hasBlockSelection()) { + int[] starts = getBlockSelectionStarts(); + int[] ends = getBlockSelectionEnds(); + int width = Math.abs(myBlockEnd.column - myBlockStart.column); + final StringBuffer buf = new StringBuffer(); + for (int i = 0; i < starts.length; i++) { + if (i > 0) buf.append('\n'); + final int len = ends[i] - starts[i]; + appendCharSequence(buf, text, starts[i], len); + for (int j = len; j < width; j++) buf.append(' '); + } + return buf.toString(); + } + + int selectionStart = getSelectionStart(); + int selectionEnd = getSelectionEnd(); + return text.subSequence(selectionStart, selectionEnd).toString(); + } + + private void appendCharSequence(StringBuffer buf, CharSequence s, int srcOffset, int len) { + if (s == null){ + s = "null"; + } + if ((srcOffset < 0) || (len < 0) || (srcOffset > s.length() - len)) { + throw new IndexOutOfBoundsException("srcOffset " + srcOffset + ", len " + len + ", s.length() " + s.length()); + } + if (len == 0) { + return; + } + final int limit = srcOffset + len; + for (int i = srcOffset; i < limit; i++){ + buf.append(s.charAt(i)); + } + } + + + public int getLeadSelectionOffset() { + validateContext(); + int caretOffset = myEditor.getCaretModel().getOffset(); + if (!hasSelection()) return caretOffset; + int startOffset = mySelectionMarker.getStartOffset(); + int endOffset = mySelectionMarker.getEndOffset(); + if (caretOffset == endOffset) return startOffset; + return endOffset; + } + + public void selectLineAtCaret() { + validateContext(); + int lineNumber = myEditor.getCaretModel().getLogicalPosition().line; + Document document = myEditor.getDocument(); + if (lineNumber >= document.getLineCount()) { + return; + } + + VisualPosition caret = myEditor.getCaretModel().getVisualPosition(); + LogicalPosition lineStart = myEditor.visualToLogicalPosition(new VisualPosition(caret.line, 0)); + LogicalPosition nextLineStart = myEditor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0)); + + int start = myEditor.logicalPositionToOffset(lineStart); + int end = myEditor.logicalPositionToOffset(nextLineStart); + + myEditor.getCaretModel().moveToOffset(start); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + myEditor.getSelectionModel().removeSelection(); + myEditor.getSelectionModel().setSelection(start, end); + } + + public void selectWordAtCaret(boolean honorCamelWordsSettings) { + validateContext(); + removeSelection(); + final EditorSettings settings = myEditor.getSettings(); + boolean camelTemp = settings.isCamelWords(); + + final boolean needOverrideSetting = camelTemp && !honorCamelWordsSettings; + if (needOverrideSetting) { + settings.setCamelWords(false); + } + + EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler( + IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET); + handler.execute(myEditor, myEditor.getDataContext()); + + if (needOverrideSetting) { + settings.setCamelWords(camelTemp); + } + } + + int getWordAtCaretStart() { + Document document = myEditor.getDocument(); + int offset = myEditor.getCaretModel().getOffset(); + if (offset == 0) return offset; + int lineNumber = myEditor.getCaretModel().getLogicalPosition().line; + CharSequence text = document.getCharsSequence(); + int newOffset = offset - 1; + int minOffset = lineNumber > 0 ? document.getLineEndOffset(lineNumber - 1) : 0; + boolean camel = myEditor.getSettings().isCamelWords(); + for (; newOffset > minOffset; newOffset--) { + if (EditorActionUtil.isWordStart(text.charAt(newOffset - 1), text.charAt(newOffset), camel)) break; + } + + return newOffset; + } + + int getWordAtCaretEnd() { + Document document = myEditor.getDocument(); + int offset = myEditor.getCaretModel().getOffset(); + + CharSequence text = document.getCharsSequence(); + if (offset >= document.getTextLength() - 1 || document.getLineCount() == 0) return offset; + + int newOffset = offset + 1; + + int lineNumber = myEditor.getCaretModel().getLogicalPosition().line; + int maxOffset = document.getLineEndOffset(lineNumber); + if (newOffset > maxOffset) { + if (lineNumber + 1 >= document.getLineCount()) return offset; + maxOffset = document.getLineEndOffset(lineNumber + 1); + } + boolean camel = myEditor.getSettings().isCamelWords(); + for (; newOffset < maxOffset; newOffset++) { + if (EditorActionUtil.isWordEnd(text.charAt(newOffset - 1), text.charAt(newOffset), camel)) break; + } + + return newOffset; + } + + private static class ClipboardObserver implements ClipboardOwner { + public void lostOwnership(Clipboard clipboard, Transferable contents) { + } + } + + private static ClipboardOwner defaultClipboardOwner = new ClipboardObserver(); + + public void copySelectionToClipboard() { + validateContext(); + String s = myEditor.getSelectionModel().getSelectedText(); + if (s == null) return; + + s = StringUtil.convertLineSeparators(s, "\n"); + StringSelection contents = new StringSelection(s); + + Project project = (Project)DataManager.getInstance().getDataContext(myEditor.getContentComponent()).getData( + DataConstants.PROJECT + ); + if (project == null) { + Clipboard clipboard = myEditor.getComponent().getToolkit().getSystemClipboard(); + clipboard.setContents(contents, defaultClipboardOwner); + } + else { + CopyPasteManager.getInstance().setContents(contents); + } + } + + public TextAttributes getTextAttributes() { + if (myTextAttributes == null) { + myTextAttributes = new TextAttributes(); + EditorColorsScheme scheme = myEditor.getColorsScheme(); + myTextAttributes.setForegroundColor(scheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)); + myTextAttributes.setBackgroundColor(scheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)); + } + + return myTextAttributes; + } + + public void reinitSettings() { + myTextAttributes = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SettingsImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SettingsImpl.java new file mode 100644 index 00000000000..209a8692094 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/SettingsImpl.java @@ -0,0 +1,306 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jun 19, 2002 + * Time: 3:19:05 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; + +public class SettingsImpl implements EditorSettings { + private EditorImpl myEditor; + private Boolean myIsCamelWords; + + public SettingsImpl(EditorImpl editor) { + myEditor = editor; + } + + // This group of settings does not have UI + private int myAdditionalLinesCount = 5; + private int myAdditionalColumnsCount = 3; + private int myLineCursorWidth = 2; + private boolean myLineMarkerAreaShown = true; + + // These comes from CodeStyleSettings + private Integer myTabSize = null; + private Integer myCachedTabSize; + private Boolean myUseTabCharacter = null; + + // These comes from EditorSettingsExternalizable defaults. + private Boolean myIsVirtualSpace = null; + private Boolean myIsCaretInsideTabs = null; + private Boolean myIsCaretBlinking = null; + private Integer myCaretBlinkingPeriod = null; + private Boolean myIsRightMarginShown = null; + private Integer myRightMargin = null; + private Boolean myAreLineNumbersShown = null; + private Boolean myIsFoldingOutlineShown = null; + private Boolean myIsSmartHome = null; + private Boolean myIsBlockCursor = null; + private Boolean myIsWhitespacesShown = null; + private Boolean myIsAnimatedScrolling = null; + private Boolean myIsAdditionalPageAtBottom = null; + private Boolean myIsDndEnabled = null; + private Boolean myIsWheelFontChangeEnabled = null; + private Boolean myIsMouseClickSelectionHonorsCamelWords = null; + + public boolean isRightMarginShown() { + return myIsRightMarginShown != null + ? myIsRightMarginShown.booleanValue() + : EditorSettingsExternalizable.getInstance().isRightMarginShown(); + } + + public void setRightMarginShown(boolean val) { + myIsRightMarginShown = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public boolean isWhitespacesShown() { + return myIsWhitespacesShown != null + ? myIsWhitespacesShown.booleanValue() + : EditorSettingsExternalizable.getInstance().isWhitespacesShown(); + } + + public void setWhitespacesShown(boolean val) { + myIsWhitespacesShown = Boolean.valueOf(val); + } + + public boolean isLineNumbersShown() { + return myAreLineNumbersShown != null + ? myAreLineNumbersShown.booleanValue() + : EditorSettingsExternalizable.getInstance().isLineNumbersShown(); + } + + public void setLineNumbersShown(boolean val) { + myAreLineNumbersShown = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public int getRightMargin(Project project) { + return myRightMargin != null ? myRightMargin.intValue() : + CodeStyleSettingsManager.getSettings(project).RIGHT_MARGIN; + } + + public void setRightMargin(int rightMargin) { + myRightMargin = new Integer(rightMargin); + fireEditorRefresh(); + } + + public int getAdditionalLinesCount() { + return myAdditionalLinesCount; + } + + public void setAdditionalLinesCount(int additionalLinesCount) { + myAdditionalLinesCount = additionalLinesCount; + fireEditorRefresh(); + } + + public int getAdditionalColumnsCount() { + return myAdditionalColumnsCount; + } + + public void setAdditionalColumnsCount(int additinalColumnsCount) { + myAdditionalColumnsCount = additinalColumnsCount; + fireEditorRefresh(); + } + + public boolean isLineMarkerAreaShown() { + return myLineMarkerAreaShown; + } + + public void setLineMarkerAreaShown(boolean lineMarkerAreaShown) { + myLineMarkerAreaShown = lineMarkerAreaShown; + fireEditorRefresh(); + } + + public boolean isFoldingOutlineShown() { + return myIsFoldingOutlineShown != null + ? myIsFoldingOutlineShown.booleanValue() + : EditorSettingsExternalizable.getInstance().isFoldingOutlineShown(); + } + + public void setFoldingOutlineShown(boolean val) { + myIsFoldingOutlineShown = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public boolean isUseTabCharacter(Project project) { + VirtualFile file = myEditor.getVirtualFile(); + FileType fileType = file == null ? null : FileTypeManager.getInstance().getFileTypeByFile(file); + return myUseTabCharacter != null ? myUseTabCharacter.booleanValue() : CodeStyleSettingsManager.getSettings(project) + .useTabCharacter(fileType); + } + + public void setUseTabCharacter(boolean val) { + myUseTabCharacter = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public void reinitSettings() { + myCachedTabSize = null; + } + + public int getTabSize(Project project) { + if (myTabSize != null) return myTabSize.intValue(); + if (myCachedTabSize != null) return myCachedTabSize.intValue(); + + VirtualFile file = myEditor.getVirtualFile(); + FileType fileType = file == null ? null : FileTypeManager.getInstance().getFileTypeByFile(file); + int tabSize = CodeStyleSettingsManager.getSettings(project).getTabSize(fileType); + myCachedTabSize = new Integer(tabSize); + return tabSize; + } + + public void setTabSize(int tabSize) { + myTabSize = new Integer(tabSize); + fireEditorRefresh(); + } + + public boolean isSmartHome() { + return myIsSmartHome != null + ? myIsSmartHome.booleanValue() + : EditorSettingsExternalizable.getInstance().isSmartHome(); + } + + public void setSmartHome(boolean val) { + myIsSmartHome = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public boolean isVirtualSpace() { + if (myEditor.isColumnMode()) return true; + return myIsVirtualSpace != null + ? myIsVirtualSpace.booleanValue() + : EditorSettingsExternalizable.getInstance().isVirtualSpace(); + } + + public void setVirtualSpace(boolean val) { + myIsVirtualSpace = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public boolean isAdditionalPageAtBottom() { + return myIsAdditionalPageAtBottom != null + ? myIsAdditionalPageAtBottom.booleanValue() + : EditorSettingsExternalizable.getInstance().isAdditionalPageAtBottom(); + } + + public void setAdditionalPageAtBottom(boolean val) { + myIsAdditionalPageAtBottom = new Boolean(val); + } + + public boolean isCaretInsideTabs() { + if (myEditor.isColumnMode()) return true; + return myIsCaretInsideTabs != null + ? myIsCaretInsideTabs.booleanValue() + : EditorSettingsExternalizable.getInstance().isCaretInsideTabs(); + } + + public void setCaretInsideTabs(boolean val) { + myIsCaretInsideTabs = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public boolean isBlockCursor() { + return myIsBlockCursor != null + ? myIsBlockCursor.booleanValue() + : EditorSettingsExternalizable.getInstance().isBlockCursor(); + } + + public void setBlockCursor(boolean val) { + myIsBlockCursor = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public int getLineCursorWidth() { + return myLineCursorWidth; + } + + public void setLineCursorWidth(int width) { + myLineCursorWidth = width; + } + + public boolean isAnimatedScrolling() { + return myIsAnimatedScrolling != null + ? myIsAnimatedScrolling.booleanValue() + : EditorSettingsExternalizable.getInstance().isSmoothScrolling(); + } + + public void setAnimatedScrolling(boolean val) { + myIsAnimatedScrolling = val ? Boolean.TRUE : Boolean.FALSE; + } + + public boolean isCamelWords() { + return myIsCamelWords != null + ? myIsCamelWords.booleanValue() + : EditorSettingsExternalizable.getInstance().isCamelWords(); + } + + public void setCamelWords(boolean val) { + myIsCamelWords = val ? Boolean.TRUE : Boolean.FALSE; + } + + public boolean isBlinkCaret() { + return myIsCaretBlinking != null + ? myIsCaretBlinking.booleanValue() + : EditorSettingsExternalizable.getInstance().isBlinkCaret(); + } + + public void setBlinkCaret(boolean val) { + myIsCaretBlinking = val ? Boolean.TRUE : Boolean.FALSE; + fireEditorRefresh(); + } + + public int getCaretBlinkPeriod() { + return myCaretBlinkingPeriod != null + ? myCaretBlinkingPeriod.intValue() + : EditorSettingsExternalizable.getInstance().getBlinkPeriod(); + } + + public void setCaretBlinkPeriod(int blinkPeriod) { + myCaretBlinkingPeriod = new Integer(blinkPeriod); + fireEditorRefresh(); + } + + public boolean isDndEnabled() { + return myIsDndEnabled != null ? myIsDndEnabled.booleanValue() : EditorSettingsExternalizable.getInstance().isDndEnabled(); + } + + public void setDndEnabled(boolean val) { + myIsDndEnabled = val ? Boolean.TRUE : Boolean.FALSE; + } + + public boolean isWheelFontChangeEnabled() { + return myIsWheelFontChangeEnabled != null + ? myIsWheelFontChangeEnabled.booleanValue() + : EditorSettingsExternalizable.getInstance().isWheelFontChangeEnabled(); + } + + public void setWheelFontChangeEnabled(boolean val) { + myIsWheelFontChangeEnabled = val ? Boolean.TRUE : Boolean.FALSE; + } + + public boolean isMouseClickSelectionHonorsCamelWords() { + return myIsMouseClickSelectionHonorsCamelWords != null + ? myIsMouseClickSelectionHonorsCamelWords.booleanValue() + : EditorSettingsExternalizable.getInstance().isMouseClickSelectionHonorsCamelWords(); + } + + public void setMouseClickSelectionHonorsCamelWords(boolean val) { + myIsMouseClickSelectionHonorsCamelWords = val ? Boolean.TRUE : Boolean.FALSE; + } + + private void fireEditorRefresh() { + myEditor.reinitSettings(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/VisibleEditorsTracker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/VisibleEditorsTracker.java new file mode 100644 index 00000000000..e3b53bcbbf8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/VisibleEditorsTracker.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; + +import java.util.HashSet; +import java.util.Set; + +public class VisibleEditorsTracker extends CommandAdapter implements ApplicationComponent{ + private Set myEditorsVisibleOnCommandStart = new HashSet(); + private long myCurrentCommandStart; + private long myLastCommandFinish; + + public static VisibleEditorsTracker getInstance() { + return ApplicationManager.getApplication().getComponent(VisibleEditorsTracker.class); + } + + + public VisibleEditorsTracker(CommandProcessor commandProcessor) { + commandProcessor.addCommandListener(this); + } + + public String getComponentName() { + return "VisibleEditorsTracker"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public boolean wasEditorVisibleOnCommandStart(Editor editor){ + return myEditorsVisibleOnCommandStart.contains(editor); + } + + public long getCurrentCommandStart() { return myCurrentCommandStart; } + + public long getLastCommandFinish() { return myLastCommandFinish; } + + public void commandStarted(CommandEvent event) { + Editor[] editors = EditorFactory.getInstance().getAllEditors(); + for (int i = 0; i < editors.length; i++) { + Editor editor = editors[i]; + + if (editor.getComponent().isShowing()){ + myEditorsVisibleOnCommandStart.add(editor); + } + + ((ScrollingModelImpl)editor.getScrollingModel()).commandStarted(); + myCurrentCommandStart = System.currentTimeMillis(); + } + } + + public void commandFinished(CommandEvent event) { + myEditorsVisibleOnCommandStart.clear(); + myLastCommandFinish = System.currentTimeMillis(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java new file mode 100644 index 00000000000..6843b8c3a22 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/DocumentEventImpl.java @@ -0,0 +1,173 @@ +package com.intellij.openapi.editor.impl.event; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.util.diff.Diff; + +public class DocumentEventImpl extends DocumentEvent { + private final int myOffset; + private CharSequence myOldString; + private final int myOldLength; + private CharSequence myNewString; + private final int myNewLength; + + private boolean isOnlyOneLineChangedCalculated = false; + private boolean isOnlyOneLineChanged; + + private boolean isStartOldIndexCalculated = false; + private int myStartOldIndex; + + private final long myOldTimeStamp; + private boolean myIsWholeDocReplaced = false; + private Diff.Change myChange; + + public DocumentEventImpl(Document document, + int offset, + CharSequence oldString, + CharSequence newString, + long oldTimeStamp) { + super(document); + myOffset = offset; + + myOldString = oldString; + if(myOldString == null) myOldString = ""; + myOldLength = myOldString.length(); + + myNewString = newString; + if(myNewString == null) myNewString = ""; + myNewLength = myNewString.length(); + + myOldTimeStamp = oldTimeStamp; + + if(getDocument().getTextLength() == 0) { + isOnlyOneLineChangedCalculated = true; + isOnlyOneLineChanged = false; + } else { + myIsWholeDocReplaced = offset == 0 && document.getTextLength() == myOldLength; + } + } + + public int getOffset() { + return myOffset; + } + + public int getOldLength() { + return myOldLength; + } + + public int getNewLength() { + return myNewLength; + } + + public CharSequence getOldFragment() { + return myOldString; + } + + public CharSequence getNewFragment() { + return myNewString; + } + + public Document getDocument() { + return (Document) getSource(); + } + + public int getStartOldIndex() { + if(isStartOldIndexCalculated) return myStartOldIndex; + + isStartOldIndexCalculated = true; + myStartOldIndex = getDocument().getLineNumber(myOffset); + return myStartOldIndex; + } + + public boolean isOnlyOneLineChanged() { + if(isOnlyOneLineChangedCalculated) return isOnlyOneLineChanged; + + isOnlyOneLineChangedCalculated = true; + isOnlyOneLineChanged = true; + + for(int i=0; i= change.line0 + change.deleted) { + newLine += change.inserted - change.deleted; + } else { + int delta = Math.min(change.inserted, line - change.line0); + newLine = change.line1 + delta; + break; + } + + change = change.link; + } + + return newLine; + } + + public int translateLineViaDiffStrict(int line) { + if (myChange == null) buildDiff(); + if (myChange == null) return line; + + Diff.Change change = myChange; + + int newLine = line; + + while (change != null) { + if (line < change.line0) break; + if (line >= change.line0 + change.deleted) { + newLine += change.inserted - change.deleted; + } else { + return -1; + } + + change = change.link; + } + + return newLine; + } + + public void buildDiff() { + final String[] strings1 = LineTokenizer.tokenize(myOldString, false); + final String[] strings2 = LineTokenizer.tokenize(myNewString, false); + + //Diff diff = new Diff(strings1, strings2); + //myChange = diff.diff_2(false); + myChange = Diff.buildChanges(strings1, strings2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/EditorEventMulticasterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/EditorEventMulticasterImpl.java new file mode 100644 index 00000000000..1101a5415d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/EditorEventMulticasterImpl.java @@ -0,0 +1,117 @@ +package com.intellij.openapi.editor.impl.event; + +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.ex.*; +import com.intellij.util.EventDispatcher; + +import java.beans.PropertyChangeListener; + +public class EditorEventMulticasterImpl implements EditorEventMulticasterEx { + private EventDispatcher myDocumentMulticaster = EventDispatcher.create(DocumentListener.class); + private EventDispatcher myEditReadOnlyMulticaster = EventDispatcher.create(EditReadOnlyListener.class); + + private EventDispatcher myEditorMouseMulticaster = EventDispatcher.create(EditorMouseListener.class); + private EventDispatcher myEditorMouseMotionMulticaster = EventDispatcher.create(EditorMouseMotionListener.class); + private EventDispatcher myErrorStripeMulticaster = EventDispatcher.create(ErrorStripeListener.class); + private EventDispatcher myCaretMulticaster = EventDispatcher.create(CaretListener.class); + private EventDispatcher mySelectionMulticaster = EventDispatcher.create(SelectionListener.class); + private EventDispatcher myVisibleAreaMulticaster = EventDispatcher.create(VisibleAreaListener.class); + private EventDispatcher myPropertyChangeMulticaster = EventDispatcher.create(PropertyChangeListener.class); + private EventDispatcher myFocusChangeListenerMulticaster = EventDispatcher.create(FocusChangeListener.class); + + public void registerDocument(DocumentEx document) { + document.addDocumentListener(myDocumentMulticaster.getMulticaster()); + document.addEditReadOnlyListener(myEditReadOnlyMulticaster.getMulticaster()); + } + + public void registerEditor(EditorEx editor) { + editor.addEditorMouseListener(myEditorMouseMulticaster.getMulticaster()); + editor.addEditorMouseMotionListener(myEditorMouseMotionMulticaster.getMulticaster()); + ((EditorMarkupModel) editor.getMarkupModel()).addErrorMarkerListener(myErrorStripeMulticaster.getMulticaster()); + editor.getCaretModel().addCaretListener(myCaretMulticaster.getMulticaster()); + editor.getSelectionModel().addSelectionListener(mySelectionMulticaster.getMulticaster()); + editor.getScrollingModel().addVisibleAreaListener(myVisibleAreaMulticaster.getMulticaster()); + editor.addPropertyChangeListener(myPropertyChangeMulticaster.getMulticaster()); + editor.addFocusListener(myFocusChangeListenerMulticaster.getMulticaster()); + } + + public void addDocumentListener(DocumentListener listener) { + myDocumentMulticaster.addListener(listener); + } + + public void removeDocumentListener(DocumentListener listener) { + myDocumentMulticaster.removeListener(listener); + } + + public void addEditorMouseListener(EditorMouseListener listener) { + myEditorMouseMulticaster.addListener(listener); + } + + public void removeEditorMouseListener(EditorMouseListener listener) { + myEditorMouseMulticaster.removeListener(listener); + } + + public void addEditorMouseMotionListener(EditorMouseMotionListener listener) { + myEditorMouseMotionMulticaster.addListener(listener); + } + + public void removeEditorMouseMotionListener(EditorMouseMotionListener listener) { + myEditorMouseMotionMulticaster.removeListener(listener); + } + + public void addCaretListener(CaretListener listener) { + myCaretMulticaster.addListener(listener); + } + + public void removeCaretListener(CaretListener listener) { + myCaretMulticaster.removeListener(listener); + } + + public void addSelectionListener(SelectionListener listener) { + mySelectionMulticaster.addListener(listener); + } + + public void removeSelectionListener(SelectionListener listener) { + mySelectionMulticaster.removeListener(listener); + } + + public void addErrorStripeListener(ErrorStripeListener listener) { + myErrorStripeMulticaster.addListener(listener); + } + + public void removeErrorStripeListener(ErrorStripeListener listener) { + myErrorStripeMulticaster.removeListener(listener); + } + + public void addVisibleAreaListener(VisibleAreaListener listener) { + myVisibleAreaMulticaster.addListener(listener); + } + + public void removeVisibleAreaListener(VisibleAreaListener listener) { + myVisibleAreaMulticaster.removeListener(listener); + } + + public void addEditReadOnlyListener(EditReadOnlyListener listener) { + myEditReadOnlyMulticaster.addListener(listener); + } + + public void removeEditReadOnlyListener(EditReadOnlyListener listener) { + myEditReadOnlyMulticaster.removeListener(listener); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeMulticaster.addListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeMulticaster.removeListener(listener); + } + + public void addFocusChangeListner(FocusChangeListener listener) { + myFocusChangeListenerMulticaster.addListener(listener); + } + + public void removeFocusChangeListner(FocusChangeListener listener) { + myFocusChangeListenerMulticaster.removeListener(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelEvent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelEvent.java new file mode 100644 index 00000000000..3544aa360cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelEvent.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.editor.impl.event; + +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.RangeHighlighter; + +import java.util.EventObject; + +public class MarkupModelEvent extends EventObject { + private final RangeHighlighter myHighlighter; + + public MarkupModelEvent(MarkupModel source, RangeHighlighter segmentHighlighter) { + super(source); + myHighlighter = segmentHighlighter; + } + + public MarkupModel getMarkupModel() { + return (MarkupModel) getSource(); + } + + public RangeHighlighter getHighlighter() { + return myHighlighter; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelListener.java new file mode 100644 index 00000000000..cfe44f2776f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/impl/event/MarkupModelListener.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.editor.impl.event; + +import java.util.EventListener; + +public interface MarkupModelListener extends EventListener { + void rangeHighlighterChanged(MarkupModelEvent event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/markup/MarkupEditorFilterFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/markup/MarkupEditorFilterFactory.java new file mode 100644 index 00000000000..c7f158f78c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/editor/markup/MarkupEditorFilterFactory.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.editor.markup; + +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.editor.Editor; + +/** + * @author max + */ +public class MarkupEditorFilterFactory { + private static final MarkupEditorFilter IS_DIFF_FILTER = DiffManager.getInstance().getDiffEditorFilter(); + private static final MarkupEditorFilter NOT_DIFF_FILTER = createNotFilter(IS_DIFF_FILTER); + + public static MarkupEditorFilter createNotFilter(final MarkupEditorFilter filter) { + return new MarkupEditorFilter() { + public boolean avaliableIn(Editor editor) { + return !filter.avaliableIn(editor); + } + }; + } + + public static MarkupEditorFilter createIsDiffFilter() { + return IS_DIFF_FILTER; + } + + public static MarkupEditorFilter createIsNotDiffFilter() { + return NOT_DIFF_FILTER; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/FileDeleteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/FileDeleteAction.java new file mode 100644 index 00000000000..e39ea553cc7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/FileDeleteAction.java @@ -0,0 +1,101 @@ +package com.intellij.openapi.fileChooser.actions; + +import com.intellij.ide.DeleteProvider; +import com.intellij.ide.actions.DeleteAction; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; + +public class FileDeleteAction extends DeleteAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.chooser.FileDeleteAction"); + private final DeleteProvider myDeleteProvider; + + private FileDeleteAction(DeleteProvider fileChooser) { + super("Delete...", "Delete", IconLoader.getIcon("/actions/delete.png")); + myDeleteProvider = fileChooser; + } + + public FileDeleteAction(FileSystemTree tree) { + this(new FileSystemDeleteProvider(tree)); + setEnabledInModalContext(true); + registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_DELETE).getShortcutSet(), + tree.getTree() + ); + } + + protected DeleteProvider getDeleteProvider(DataContext dataContext) { + return myDeleteProvider; + } + + private static final class FileSystemDeleteProvider implements DeleteProvider { + private final FileSystemTree myTree; + + public FileSystemDeleteProvider(FileSystemTree tree) { + myTree = tree; + } + + public boolean canDeleteElement(DataContext dataContext) {return myTree.selectionExists(); } + + public void deleteElement(DataContext dataContext) { deleteSelectedFiles(); } + + void deleteSelectedFiles() { + final VirtualFile[] files = myTree.getSelectedFiles(); + if (files.length == 0) return; + + String message = createConfirmationMessage(files); + int returnValue = Messages.showYesNoDialog(message, "Delete", Messages.getQuestionIcon()); + if (returnValue != 0) return; + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + try { + file.delete(this); + } + catch (IOException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Could not erase file or folder: " + file.getName(), "Error", Messages.getErrorIcon()); + } + }); + } + } + } + } + ); + } + + private String createConfirmationMessage(VirtualFile[] filesToDelete) { + String deleteWhat; + if (filesToDelete.length == 1){ + deleteWhat = filesToDelete[0].isDirectory() ? "folder" : "file"; + } + else { + boolean hasFiles = false; + boolean hasFolders = false; + for (int i = 0; i < filesToDelete.length; i++) { + VirtualFile file = filesToDelete[i]; + boolean isDirectory = file.isDirectory(); + hasFiles |= !isDirectory; + hasFolders |= isDirectory; + } + LOG.assertTrue(hasFiles || hasFolders); + if (hasFiles && hasFolders) deleteWhat = "files and directories"; + else if (hasFolders) deleteWhat = "folders"; + else deleteWhat = "files"; + } + return "Are you sure you want to delete selected " + deleteWhat + "?"; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoHomeAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoHomeAction.java new file mode 100644 index 00000000000..745f710d44e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoHomeAction.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.fileChooser.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Vladimir Kondratyev + */ +public final class GotoHomeAction extends FileChooserDialogImpl.FileChooserAction{ + public GotoHomeAction(FileSystemTree fileSystemTree) { + super("Home", "Go to home directory", IconLoader.getIcon("/nodes/homeFolder.png"), fileSystemTree); + } + + protected void actionPerformed(FileSystemTree fileSystemTree, AnActionEvent e) { + VirtualFile homeDirectory = getHomeDirectory(); + fileSystemTree.select(homeDirectory); + fileSystemTree.expand(homeDirectory); + } + + private static VirtualFile getHomeDirectory(){ + return LocalFileSystem.getInstance().findFileByPath(System.getProperty("user.home").replace('\\','/')); + } + + protected void update(FileSystemTree fileSystemTree, AnActionEvent e) { + Presentation presentation = e.getPresentation(); + if(!presentation.isEnabled()){ + return; + } + final VirtualFile homeDirectory = getHomeDirectory(); + presentation.setEnabled(homeDirectory != null && (fileSystemTree).isUnderRoots(homeDirectory)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoProjectDirectory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoProjectDirectory.java new file mode 100644 index 00000000000..4cf6806933a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/GotoProjectDirectory.java @@ -0,0 +1,42 @@ +package com.intellij.openapi.fileChooser.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; + +public final class GotoProjectDirectory extends FileChooserDialogImpl.FileChooserAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileChooser.actions.GotoProjectDirectory"); + public GotoProjectDirectory(FileSystemTree fileSystemTree) { + super("Project", "Go to project directory", IconLoader.getIcon("/nodes/ideaProject.png"), fileSystemTree); + } + + protected void actionPerformed(FileSystemTree fileSystemTree, AnActionEvent e) { + final VirtualFile projectPath = getProjectPath(e); + LOG.assertTrue(projectPath != null); + fileSystemTree.select(projectPath); + fileSystemTree.expand(projectPath); + } + + protected void update(FileSystemTree fileSystemTree, AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final VirtualFile projectPath = getProjectPath(e); + presentation.setEnabled(projectPath != null && fileSystemTree.isUnderRoots(projectPath)); + } + + private static VirtualFile getProjectPath(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final VirtualFile projectFileDir = (VirtualFile)dataContext.getData(DataConstantsEx.PROJECT_FILE_DIRECTORY); + if (projectFileDir == null || !projectFileDir.isValid()) { + return null; + } + return projectFileDir; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/NewFolderAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/NewFolderAction.java new file mode 100644 index 00000000000..173a8cd7509 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/actions/NewFolderAction.java @@ -0,0 +1,54 @@ +package com.intellij.openapi.fileChooser.actions; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; + +public class NewFolderAction extends FileChooserDialogImpl.FileChooserAction { + public NewFolderAction(FileSystemTree fileSystemTree) { + super("New Folder...", "Create new folder", IconLoader.getIcon("/actions/newFolder.png"), fileSystemTree); + registerCustomShortcutSet( + ActionManager.getInstance().getAction("NewElement").getShortcutSet(), + fileSystemTree.getTree() + ); + } + + protected void update(FileSystemTree fileSystemTree, AnActionEvent e) { + Presentation presentation = e.getPresentation(); + VirtualFile selectedFile = fileSystemTree.getSelectedFile(); + presentation.setEnabled(selectedFile != null && selectedFile.isDirectory()); + } + + protected void actionPerformed(FileSystemTree fileSystemTree, AnActionEvent e) { + createNewFolder(fileSystemTree); + } + + private static void createNewFolder(FileSystemTree fileSystemTree) { + final VirtualFile file = fileSystemTree.getSelectedFile(); + if (file == null || !file.isDirectory()) return; + + String newFolderName; + while (true) { + newFolderName = Messages.showInputDialog("Enter a new folder name:", "New Folder", Messages.getQuestionIcon()); + if (newFolderName == null) { + return; + } + if ("".equals(newFolderName.trim())) { + Messages.showMessageDialog("Folder name cannot be empty", "Error", Messages.getErrorIcon()); + continue; + } + Exception failReason = ((FileSystemTreeImpl)fileSystemTree).createNewFolder(file, newFolderName); + if (failReason != null) { + Messages.showMessageDialog("Could not create folder '" + newFolderName + "'", "Error", Messages.getErrorIcon()); + continue; + } + return; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java new file mode 100644 index 00000000000..88fa6451cbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java @@ -0,0 +1,297 @@ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.ide.actions.SynchronizeAction; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDialog; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.actions.FileDeleteAction; +import com.intellij.openapi.fileChooser.actions.GotoHomeAction; +import com.intellij.openapi.fileChooser.actions.GotoProjectDirectory; +import com.intellij.openapi.fileChooser.actions.NewFolderAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; + +public class FileChooserDialogImpl extends DialogWrapper implements FileChooserDialog{ + private final FileChooserDescriptor myChooserDescriptor; + /** @fabrique **/ + protected FileSystemTreeImpl myFileSystemTree; + + private static VirtualFile ourLastFile; + /** @fabrique **/ + protected Project myProject; + /** @fabrique **/ + private VirtualFile[] myChosenFiles; + + public FileChooserDialogImpl(FileChooserDescriptor chooserDescriptor, Project project) { + super(project, true); + myProject = project; + myChooserDescriptor = chooserDescriptor; + setTitle("Select Path"); + } + + public FileChooserDialogImpl(FileChooserDescriptor chooserDescriptor, Component parent) { + super(parent, true); + myChooserDescriptor = chooserDescriptor; + setTitle("Select Path"); + } + + public VirtualFile[] choose(VirtualFile toSelect, Project project) { + init(); + + VirtualFile selectFile = null; + + if (toSelect == null && ourLastFile == null) { + if (project != null && project.getProjectFile() != null) { + selectFile = project.getProjectFile().getParent(); + } + } else { + selectFile = (toSelect == null) ? ourLastFile : toSelect; + } + + final VirtualFile file = selectFile; + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (file == null || !file.isValid()) return; + if (select(file)) return; + VirtualFile parent = file.getParent(); + if (parent != null) { + select(parent); + } + } + }, ModalityState.stateForComponent(getContentPane())); + show(); + + return myChosenFiles; + } + + protected DefaultActionGroup createActionGroup() { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new GotoHomeAction(myFileSystemTree)); + group.add(new GotoProjectDirectory(myFileSystemTree)); + group.addSeparator(); + group.add(new NewFolderAction(myFileSystemTree)); + group.add(new FileDeleteAction(myFileSystemTree)); + group.addSeparator(); + SynchronizeAction action1 = new SynchronizeAction(false); + AnAction original = ActionManager.getInstance().getAction(IdeActions.ACTION_SYNCHRONIZE); + action1.copyFrom(original); + action1.registerCustomShortcutSet(original.getShortcutSet(), myFileSystemTree.getTree()); + group.add(action1); + group.addSeparator(); + group.add(new MyShowHiddensAction()); + return group; + } + + protected final JComponent createTitlePane() { + return new TitlePanel(myChooserDescriptor.getTitle(), myChooserDescriptor.getDescription()); + } + + protected JComponent createCenterPanel() { + JPanel panel = new MyPanel(); + + panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + + createTree(); + + final DefaultActionGroup group = createActionGroup(); + ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); + panel.add(toolBar.getComponent(), BorderLayout.NORTH); + + + registerMouseListener(group); + + JScrollPane scrollPane = new JScrollPane(myFileSystemTree.getTree()); + scrollPane.setBorder(BorderFactory.createLineBorder(new Color(148, 154, 156))); + panel.add(scrollPane, BorderLayout.CENTER); + panel.setPreferredSize(new Dimension(400, 400)); + + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myFileSystemTree.getTree(); + } + + protected final void dispose() { + myFileSystemTree.dispose(); + super.dispose(); + } + + protected void doOKAction() { + if (!isOKActionEnabled()) { + return; + } + + final VirtualFile[] selectedFiles = getSelectedFiles(); + try { + myChooserDescriptor.validateSelectedFiles(selectedFiles); + } + catch (Exception e) { + Messages.showErrorDialog(getContentPane(), e.getMessage(), myChooserDescriptor.getTitle()); + return; + } + + myChosenFiles = selectedFiles; + if (selectedFiles.length == 0) { + close(CANCEL_EXIT_CODE); + return; + } + ourLastFile = selectedFiles[selectedFiles.length - 1]; + + super.doOKAction(); + } + + public final void doCancelAction() { + myChosenFiles = VirtualFile.EMPTY_ARRAY; + super.doCancelAction(); + } + + public final boolean select(final VirtualFile file) { + return myFileSystemTree.select(file); + } + + protected JTree createTree() { + myFileSystemTree = new FileSystemTreeImpl(myProject, myChooserDescriptor); + myFileSystemTree.addOkAction(new Runnable() { + public void run() {doOKAction(); } + }); + JTree tree = myFileSystemTree.getTree(); + tree.setCellRenderer(new NodeRenderer()); + tree.addTreeSelectionListener(new FileTreeSelectionListener()); + setOKActionEnabled(false); + return tree; + } + + protected final void registerMouseListener(final ActionGroup group) { + myFileSystemTree.registerMouseListener(group); + } + + protected VirtualFile[] getSelectedFiles() { + return myFileSystemTree.getChoosenFiles(); + } + + private final class FileTreeSelectionListener implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent e) { + TreePath[] paths = e.getPaths(); + + boolean enabled = true; + for (int i = 0; i < paths.length; i++) { + TreePath treePath = paths[i]; + if (!e.isAddedPath(treePath)) continue; + DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent(); + Object userObject = node.getUserObject(); + if (!(userObject instanceof FileNodeDescriptor)) { + enabled = false; + break; + } + FileElement descriptor = (FileElement) ((FileNodeDescriptor) userObject).getElement(); + VirtualFile file = descriptor.getFile(); + enabled = myChooserDescriptor.isFileSelectable(file); + } + setOKActionEnabled(enabled); + } + } + + private static final class TitlePanel extends JPanel { + public TitlePanel(String title, String description) { + super(new BorderLayout()); + JLabel label = new JLabel(title); + add(label, BorderLayout.NORTH); + label.setOpaque(false); + Font font = label.getFont(); + label.setFont(font.deriveFont(Font.BOLD, font.getSize() + 2)); + if (description != null) { + label.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10)); + JLabel descriptionLabel = new JLabel(description); + descriptionLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + add(descriptionLabel, BorderLayout.CENTER); + } + else { + label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + } + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + int width = getSize().width; + int height = getSize().height; + Object oldAntialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setPaint(new Color(247, 247, 247)); + RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, width - 1, height - 1, 0, 0); + g2.fill(rect); + g2.setPaint(Color.GRAY); + g2.drawLine(0, height - 1, width - 1, height - 1); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialiasing); + } + } + + public static abstract class FileChooserAction extends AnAction { + private final FileSystemTree myFileSystemTree; + public FileChooserAction(String text, String description, Icon icon, FileSystemTree fileSystemTree) { + super(text, description, icon); + myFileSystemTree = fileSystemTree; + } + + final public void actionPerformed(AnActionEvent e) { + actionPerformed(myFileSystemTree, e); + } + + final public void update(AnActionEvent e) { + update(myFileSystemTree, e); + } + + protected abstract void update(FileSystemTree fileChooser, AnActionEvent e); + + protected abstract void actionPerformed(FileSystemTree fileChooser, AnActionEvent e); + } + + /** + * @author Vladimir Kondratyev + */ + private final class MyShowHiddensAction extends ToggleAction{ + public MyShowHiddensAction() { + super("Show Hidden Files and Directories", "Show hidden files and directories", IconLoader.getIcon("/actions/showHiddens.png")); + } + + public boolean isSelected(AnActionEvent e) { + return myFileSystemTree.areHiddensShown(); + } + + public void setSelected(AnActionEvent e, boolean state) { + myFileSystemTree.showHiddens(state); + } + } + + private final class MyPanel extends JPanel implements DataContext{ + public MyPanel() { + super(new BorderLayout()); + } + + public Object getData(String dataId) { + if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + return getSelectedFiles(); + } + return null; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileNodeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileNodeDescriptor.java new file mode 100644 index 00000000000..84d16cbe2a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileNodeDescriptor.java @@ -0,0 +1,56 @@ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; + +public class FileNodeDescriptor extends NodeDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.chooser.FileNodeDescriptor"); + + private FileElement myDescriptor; + private Icon myOriginalOpenIcon; + private Icon myOriginalClosedIcon; + + public FileNodeDescriptor(Project project, FileElement element, NodeDescriptor parentDescriptor, Icon openIcon, Icon closedIcon) { + super(project, parentDescriptor); + myOriginalOpenIcon = openIcon; + myOriginalClosedIcon = closedIcon; + LOG.assertTrue(element != null); + myDescriptor = element; + } + + public boolean update() { + boolean changed = false; + + if (!myDescriptor.toString().equals(myName)) changed = true; + + myName = myDescriptor.toString(); + + VirtualFile file = myDescriptor.getFile(); + + if (file == null) return true; + + myOpenIcon = myOriginalOpenIcon; + myClosedIcon = myOriginalClosedIcon; + if (myDescriptor.isHidden()) { + myOpenIcon = IconLoader.getTransparentIcon(myOpenIcon); + myClosedIcon = IconLoader.getTransparentIcon(myClosedIcon); + } + myColor = myDescriptor.isHidden() ? SimpleTextAttributes.DARK_TEXT.getFgColor() : null; + return changed; + } + + public final Object getElement() { + return myDescriptor; + } + + protected final void setElement(FileElement descriptor) { + myDescriptor = descriptor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeFactoryImpl.java new file mode 100644 index 00000000000..eea6792dc96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeFactoryImpl.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.openapi.fileChooser.FileSystemTreeFactory; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.actions.GotoHomeAction; +import com.intellij.openapi.fileChooser.actions.GotoProjectDirectory; +import com.intellij.openapi.fileChooser.actions.NewFolderAction; +import com.intellij.openapi.fileChooser.actions.FileDeleteAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.actionSystem.*; +import com.intellij.ide.actions.SynchronizeAction; + +public class FileSystemTreeFactoryImpl implements FileSystemTreeFactory{ + public FileSystemTree createFileSystemTree(Project project, FileChooserDescriptor fileChooserDescriptor) { + return new FileSystemTreeImpl(project, fileChooserDescriptor); + } + + public DefaultActionGroup createDefaultFileSystemActions(FileSystemTree fileSystemTree) { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new GotoHomeAction(fileSystemTree)); + group.add(new GotoProjectDirectory(fileSystemTree)); + group.addSeparator(); + group.add(new NewFolderAction(fileSystemTree)); + group.add(new FileDeleteAction(fileSystemTree)); + group.addSeparator(); + SynchronizeAction action1 = new SynchronizeAction(false); + AnAction original = ActionManager.getInstance().getAction(IdeActions.ACTION_SYNCHRONIZE); + action1.copyFrom(original); + action1.registerCustomShortcutSet(original.getShortcutSet(), fileSystemTree.getTree()); + group.add(action1); + group.addSeparator(); + + return group; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java new file mode 100644 index 00000000000..b51a5196f12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java @@ -0,0 +1,306 @@ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.fileChooser.FileSystemTree; +import com.intellij.openapi.fileChooser.impl.FileComparator; +import com.intellij.openapi.fileChooser.impl.FileTreeBuilder; +import com.intellij.openapi.fileChooser.impl.FileTreeStructure; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.containers.ConvertingIterator; +import com.intellij.util.containers.Convertor; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.event.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; + +public class FileSystemTreeImpl implements FileSystemTree { + private static final Logger LOG = Logger.getInstance("#com.intellij.chooser.FileSystemTreeImpl"); + + private final Tree myTree; + private final FileTreeStructure myTreeStructure; + private final AbstractTreeBuilder myTreeBuilder; + private final Project myProject; + private final ArrayList myOkActions = new ArrayList(2); + private final FileChooserDescriptor myDescriptor; + + public FileSystemTreeImpl(Project project, FileChooserDescriptor descriptor) { + this(project, descriptor, new Tree()); + myTree.setRootVisible(descriptor.isTreeRootVisible()); + myTree.setShowsRootHandles(true); + } + + public FileSystemTreeImpl(Project project, FileChooserDescriptor descriptor, Tree tree) { + myProject = project; + myTreeStructure = new FileTreeStructure(project, descriptor); + myDescriptor = descriptor; + myTree = tree; + DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode()); + myTree.setModel(treeModel); + myTreeBuilder = createTreeBuilder(myTree, treeModel, myTreeStructure, FileComparator.getInstance(), descriptor); + + new TreeSpeedSearch(myTree); + myTree.putClientProperty("JTree.lineStyle", "Angled"); + myTree.expandPath(new TreePath(treeModel.getRoot())); + TreeToolTipHandler.install(myTree); + TreeUtil.installActions(myTree); + + myTree.getSelectionModel().setSelectionMode( + myTreeStructure.getChooserDescriptor().getChooseMultiple() ? + TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION : + TreeSelectionModel.SINGLE_TREE_SELECTION + ); + addTreeExpansionListener(); + registerTreeActions(); + } + + protected AbstractTreeBuilder createTreeBuilder(final JTree tree, DefaultTreeModel treeModel, final AbstractTreeStructure treeStructure, final Comparator comparator, FileChooserDescriptor descriptor) { + return new FileTreeBuilder(tree, treeModel, treeStructure, comparator, descriptor); + } + + private void registerTreeActions() { + myTree.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + performEnterAction(true); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED + ); + myTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) performEnterAction(false); + } + }); + } + + private void performEnterAction(boolean toggleNodeState) { + TreePath path = myTree.getSelectionPath(); + if (path != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (node != null && node.isLeaf()) { + fireOkAction(); + } + else if (toggleNodeState) { + if (myTree.isExpanded(path)) { + myTree.collapsePath(path); + } + else { + myTree.expandPath(path); + } + } + } + } + + public void addOkAction(Runnable action) { myOkActions.add(action); } + + private void fireOkAction() { + for (Iterator iterator = myOkActions.iterator(); iterator.hasNext();) { + Runnable action = iterator.next(); + action.run(); + } + } + + public void registerMouseListener(final ActionGroup group) { + PopupHandler.installUnknownPopupHandler(myTree, group, ActionManager.getInstance()); + } + + private void addTreeExpansionListener() { + myTree.addTreeExpansionListener(new TreeExpansionListener() { + public void treeExpanded(final TreeExpansionEvent event) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + TreePath path = event.getPath(); + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (node.getUserObject() instanceof FileNodeDescriptor) { + FileNodeDescriptor nodeDescriptor = (FileNodeDescriptor)node.getUserObject(); + FileElement fileDescriptor = (FileElement)nodeDescriptor.getElement(); + VirtualFile virtualFile = fileDescriptor.getFile(); + if (virtualFile != null) { + virtualFile.refresh(false, false); + } + } + } + }); + } + + public void treeCollapsed(TreeExpansionEvent event) { + } + }); + } + + public boolean areHiddensShown() { + return myTreeStructure.areHiddensShown(); + } + + public void showHiddens(boolean showHiddens) { + myTreeStructure.showHiddens(showHiddens); + updateTree(); + } + + public void updateTree() { + myTreeBuilder.updateFromRoot(); + } + + public void dispose() { + if (myTreeBuilder != null) { + myTreeStructure.dispose(); + myTreeBuilder.dispose(); + } + } + + public boolean select(final VirtualFile file) { + DefaultMutableTreeNode node = getNodeForFile(file); + if (node == null) return false; + else { + TreeUtil.selectPath(myTree, new TreePath(node.getPath())); + return true; + } + } + + public boolean expand(VirtualFile directory) { + if (!directory.isDirectory()) return false; + DefaultMutableTreeNode node = getNodeForFile(directory); + if (node == null) return false; + myTree.expandPath(new TreePath(node.getPath())); + return true; + } + + private DefaultMutableTreeNode getNodeForFile(VirtualFile file) { + VirtualFile selectFile; + + if ((file.getFileSystem() instanceof JarFileSystem) && file.getParent() == null) { + selectFile = JarFileSystem.getInstance().getVirtualFileForJar(file); + if (selectFile == null) { + LOG.assertTrue(false, "nothing found for " + file.getPath()); + return null; + } + } + else { + selectFile = file; + } + + FileElement descriptor = new FileElement(selectFile, selectFile.getName()); + + myTreeBuilder.buildNodeForElement(descriptor); + return myTreeBuilder.getNodeForElement(descriptor); + } + + public Exception createNewFolder(final VirtualFile parentDirectory, final String newFolderName) { + final Exception[] failReason = new Exception[] { null }; + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + VirtualFile folder = parentDirectory.createChildDirectory(this, newFolderName); + updateTree(); + FileElement folderDesc = new FileElement(folder, folder.getName()); + myTreeBuilder.buildNodeForElement(folderDesc); + DefaultMutableTreeNode folderNode = + myTreeBuilder.getNodeForElement(folderDesc); + if (folderNode != null) { + TreePath treePath = new TreePath(folderNode.getPath()); + myTree.setSelectionPath(treePath); + myTree.scrollPathToVisible(treePath); + myTree.expandPath(treePath); + } + } + catch (IOException e) { + failReason[0] = e; + } + } + }); + } + }, + "Create New Folder", + null + ); + return failReason[0]; + } + + public JTree getTree() { return myTree; } + + public VirtualFile getSelectedFile() { + final TreePath path = myTree.getSelectionPath(); + if (path == null) return null; + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (!(node.getUserObject() instanceof FileNodeDescriptor)) return null; + FileNodeDescriptor descriptor = (FileNodeDescriptor)node.getUserObject(); + final VirtualFile file = ((FileElement)descriptor.getElement()).getFile(); + return file; + } + + public VirtualFile[] getSelectedFiles() { + return collectSelectedFiles(new ConvertingIterator.IdConvertor()); + } + + public VirtualFile[] getChoosenFiles() { + return collectSelectedFiles(new Convertor() { + public VirtualFile convert(VirtualFile file) { + if (file == null || !file.isValid()) return null; + return myTreeStructure.getChooserDescriptor().getFileToSelect(file); + } + }); + } + + private VirtualFile[] collectSelectedFiles(Convertor fileConvertor) { + TreePath[] paths = myTree.getSelectionPaths(); + if (paths == null) return VirtualFile.EMPTY_ARRAY; + ArrayList files = new ArrayList(paths.length); + + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + if (!(node.getUserObject() instanceof FileNodeDescriptor)) return VirtualFile.EMPTY_ARRAY; + FileNodeDescriptor descriptor = (FileNodeDescriptor)node.getUserObject(); + VirtualFile file = fileConvertor.convert(((FileElement)descriptor.getElement()).getFile()); + if (file != null && file.isValid()) files.add(file); + } + return files.toArray(new VirtualFile[files.size()]); + } + + public boolean selectionExists() { + TreePath[] selectedPaths = myTree.getSelectionPaths(); + return selectedPaths != null && selectedPaths.length != 0; + } + + public boolean isUnderRoots(VirtualFile file) { + final java.util.List roots = myDescriptor.getRoots(); + if (roots.size() == 0) { + return true; + } + for (int i = 0; i < roots.size(); i++) { + VirtualFile root = roots.get(i); + if (VfsUtil.isAncestor(root, file, false)) { + return true; + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/RootFileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/RootFileElement.java new file mode 100644 index 00000000000..b6c8f5c7f63 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/ex/RootFileElement.java @@ -0,0 +1,57 @@ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class RootFileElement extends FileElement { + private final VirtualFile[] myFiles; + private final boolean myShowFileSystemRoots; + private Object[] myChildren; + + public RootFileElement(VirtualFile[] files, String name, boolean showFileSystemRoots) { + super(files.length == 1 ? files[0] : null, name); + myFiles = files; + myShowFileSystemRoots = showFileSystemRoots; + } + + public Object[] getChildren() { + if (myFiles.length <= 1) { + return myShowFileSystemRoots ? getFileSystemRoots() : ArrayUtil.EMPTY_OBJECT_ARRAY; + } + if (myChildren == null) { + myChildren = createFileElementArray(); + } + return myChildren; + } + + private Object[] createFileElementArray() { + final List roots = new ArrayList(); + for (int i = 0; i < myFiles.length; i++) { + final VirtualFile file = myFiles[i]; + roots.add(new FileElement(file, file.getPresentableUrl())); + } + return roots.toArray(new Object[roots.size()]); + } + + private static Object[] getFileSystemRoots() { + File[] roots = File.listRoots(); + LocalFileSystem localFileSystem = LocalFileSystem.getInstance(); + HashSet rootChildren = new HashSet(); + for (int i = 0; i < roots.length; i++) { + if (roots[i].getPath().toLowerCase().startsWith("a:")) continue; + String path = roots[i].getAbsolutePath(); + path = path.replace(File.separatorChar, '/'); + VirtualFile file = localFileSystem.findFileByPath(path); + if (file == null) continue; + rootChildren.add(new FileElement(file, file.getPresentableUrl())); + } + return rootChildren.toArray(new Object[rootChildren.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileChooserFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileChooserFactoryImpl.java new file mode 100644 index 00000000000..0aa66a9a1e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileChooserFactoryImpl.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.fileChooser.impl; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDialog; +import com.intellij.openapi.fileChooser.FileChooserFactory; +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.project.Project; + +import java.awt.*; + +public class FileChooserFactoryImpl extends FileChooserFactory implements ApplicationComponent { + public FileChooserDialog createFileChooser(FileChooserDescriptor descriptor, Project project) { + return new FileChooserDialogImpl(descriptor, project); + } + + public FileChooserDialog createFileChooser(FileChooserDescriptor descriptor, Component parent) { + return new FileChooserDialogImpl(descriptor, parent); + } + + public String getComponentName() { + return "FileChooserFactory"; + } + + public void initComponent() { } + + public void disposeComponent() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileComparator.java new file mode 100644 index 00000000000..745318836b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileComparator.java @@ -0,0 +1,41 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.fileChooser.impl; + +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Comparator; + +public final class FileComparator implements Comparator { + private static final FileComparator INSTANCE = new FileComparator(); + + private FileComparator() { + // empty + } + + public static FileComparator getInstance() { + return INSTANCE; + } + + public int compare(Object o1, Object o2) { + FileNodeDescriptor nodeDescriptor1 = (FileNodeDescriptor)o1; + FileNodeDescriptor nodeDescriptor2 = (FileNodeDescriptor)o2; + + int weight1 = getWeight(nodeDescriptor1); + int weight2 = getWeight(nodeDescriptor2); + + if (weight1 != weight2) { + return weight1 - weight2; + } + + return o1.toString().compareToIgnoreCase(o2.toString()); + } + + private static int getWeight(FileNodeDescriptor descriptor) { + VirtualFile file = ((FileElement)descriptor.getElement()).getFile(); + return file == null || file.isDirectory() ? 0 : 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeBuilder.java new file mode 100644 index 00000000000..6772ed415f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeBuilder.java @@ -0,0 +1,101 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.fileChooser.impl; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.vfs.*; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.util.Comparator; + +public class FileTreeBuilder extends AbstractTreeBuilder { + private final FileChooserDescriptor myChooserDescriptor; + + private VirtualFileAdapter myVirtualFileListener; + + + public FileTreeBuilder(JTree tree, DefaultTreeModel treeModel, + AbstractTreeStructure treeStructure, + Comparator comparator, + FileChooserDescriptor chooserDescriptor) { + super(tree, treeModel, treeStructure, comparator); + myChooserDescriptor = chooserDescriptor; + initRootNode(); + + installVirtualFileListener(); + } + + private void installVirtualFileListener() { + myVirtualFileListener = new VirtualFileAdapter() { + public void propertyChanged(VirtualFilePropertyEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public void fileCreated(VirtualFileEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public void fileDeleted(VirtualFileEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + + public void fileMoved(VirtualFileMoveEvent event) { + myUpdater.addSubtreeToUpdate(myRootNode); + } + }; + + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + } + + public final void dispose() { + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + super.dispose(); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + final Object element = nodeDescriptor.getElement(); + if (element != null){ + FileElement descriptor = (FileElement)element; + VirtualFile file = descriptor.getFile(); + if (file != null){ + if (myChooserDescriptor.isChooseJarContents() && FileElement.isArchive(file)) { + return true; + } + if (file.isDirectory()) { + return true; + } + return false; + } + } + return true; + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + return false; + } + + protected final void expandNodeChildren(DefaultMutableTreeNode node) { + Object element = ((NodeDescriptor)node.getUserObject()).getElement(); + if (element instanceof FileElement){ + final VirtualFile file = ((FileElement)element).getFile(); + if (file != null && file.isValid()){ + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + file.refresh(false, false); + } + } + ); + } + } + super.expandNodeChildren(node); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeStructure.java new file mode 100644 index 00000000000..653064036de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileChooser/impl/FileTreeStructure.java @@ -0,0 +1,141 @@ +/** + * @author Yura Cangea + */ +package com.intellij.openapi.fileChooser.impl; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor; +import com.intellij.openapi.fileChooser.ex.RootFileElement; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import java.util.HashSet; +import java.util.List; + +public class FileTreeStructure extends AbstractTreeStructure { + private static final Logger LOG = Logger.getInstance("#com.intellij.chooser.FileTreeStructure"); + private final RootFileElement myRootElement; + private final FileChooserDescriptor myChooserDescriptor; + private boolean myShownHiddens; + private final Project myProject; + + public FileTreeStructure(Project project, FileChooserDescriptor chooserDescriptor) { + myProject = project; + List roots = chooserDescriptor.getRoots(); + final VirtualFile[] rootFiles = roots.toArray(new VirtualFile[roots.size()]); + VirtualFile rootFile = rootFiles.length == 1 ? rootFiles[0] : null; + myRootElement = new RootFileElement(rootFiles, rootFile != null? rootFile.getPresentableUrl() : chooserDescriptor.getTitle(), chooserDescriptor.isShowFileSystemRoots()); + myChooserDescriptor = chooserDescriptor; + + String value = PropertiesComponent.getInstance().getValue("FileChooser.showHiddens"); + myShownHiddens = Boolean.valueOf(value).booleanValue(); + } + + public final boolean areHiddensShown() { + return myShownHiddens; + } + + public final void showHiddens(final boolean showHiddens) { + myShownHiddens = showHiddens; + } + + public final Object getRootElement() { + return myRootElement; + } + + public Object[] getChildElements(Object element) { + if (element instanceof FileElement) { + return getFileChildren((FileElement) element); + } + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public final FileChooserDescriptor getChooserDescriptor() { + return myChooserDescriptor; + } + + private Object[] getFileChildren(FileElement element) { + if (element.getFile() == null) { + if (element == myRootElement) { + return myRootElement.getChildren(); + } + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + VirtualFile[] children = null; + + if (element.isArchive() && myChooserDescriptor.isChooseJarContents()) { + VirtualFile file = element.getFile(); + String path = file.getPath(); + if (!(file.getFileSystem() instanceof JarFileSystem)) { + file = JarFileSystem.getInstance().findFileByPath(path + JarFileSystem.JAR_SEPARATOR); + } + if (file != null) children = file.getChildren(); + } + else { + children = element.getFile().getChildren(); + } + + if (children == null) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + HashSet childrenSet = new HashSet(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (myChooserDescriptor.isFileVisible(child, myShownHiddens)) { + childrenSet.add(new FileElement(child, child.getName())); + } + } + return childrenSet.toArray(new Object[childrenSet.size()]); + } + + + public Object getParentElement(Object element) { + if (element instanceof FileElement) { + VirtualFile file = ((FileElement) element).getFile(); + if (file == null) return null; + VirtualFile parent = file.getParent(); + if (parent != null && parent.getFileSystem() instanceof JarFileSystem && parent.getParent() == null) { + // parent of jar contents should be local jar file + String localPath = parent.getPath().substring(0, + parent.getPath().length() - JarFileSystem.JAR_SEPARATOR.length()); + parent = LocalFileSystem.getInstance().findFileByPath(localPath); + } + if (parent == null) { + return null; + } + return new FileElement(parent, parent.getName()); + } + return null; + } + + public final void commit() { + } + + public final boolean hasSomethingToCommit() { + return false; + } + + public final void dispose() { + PropertiesComponent.getInstance().setValue("FileChooser.showHiddens", Boolean.toString(myShownHiddens)); + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + LOG.assertTrue(element instanceof FileElement, element.getClass().getName()); + VirtualFile file = ((FileElement)element).getFile(); + Icon openIcon = file == null ? null : myChooserDescriptor.getOpenIcon(file); + Icon closedIcon = file == null ? null : myChooserDescriptor.getClosedIcon(file); + FileNodeDescriptor nodeDescriptor = new FileNodeDescriptor(myProject, (FileElement)element, parentDescriptor, openIcon, closedIcon); + return nodeDescriptor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java new file mode 100644 index 00000000000..e7a82870262 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java @@ -0,0 +1,103 @@ +package com.intellij.openapi.fileEditor.ex; + +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.impl.EditorComposite; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +public abstract class FileEditorManagerEx extends FileEditorManager { + public static FileEditorManagerEx getInstanceEx(Project project) { + return (FileEditorManagerEx)getInstance(project); + } + + /** + * @return JComponent which represent the place where all editors are located + */ + public abstract JComponent getComponent(); + + /** + * @return preferred focused component inside myEditor tabbed container. + * This method does similar things like {@link FileEditor#getPreferredFocusedComponent()} + * but it also tracks (and remember) focus movement inside tabbed container. + * + * @see EditorComposite#getPreferredFocusedComponent() + */ + public abstract JComponent getPreferredFocusedComponent(); + + public abstract Pair getEditorsWithProviders(VirtualFile file); + + /** + * @param editor never null + * + * @return can be null + */ + public abstract VirtualFile getFile(FileEditor editor); + + /** + * + * @return current window in splitters + */ + public abstract EditorWindow getCurrentWindow(); + + public abstract void setCurrentWindow(EditorWindow window); + + /** + * @return true if there are two tab groups, othrwise the + * method returns false + */ + public abstract boolean hasSplitters(); + + public abstract void unsplitWindow(); + + public abstract void unsplitAllWindow(); + + public abstract EditorWindow [] getWindows (); + + /** + * @return arrays of all files (including file itself) that belong + * to the same tabbed container. The method returns empty array if file + * is not open. The returned files have the same order as they have in the + * tabbed container. + */ + public abstract VirtualFile[] getSiblings(VirtualFile file); + + /** + * Moves focus cyclically to the next myEditor + */ + public abstract void moveFocusToNextEditor(); + + public abstract void createSplitter(int orientation); + + public abstract void changeSplitterOrientation(); + + public abstract void flipTabs(); + public abstract boolean tabsMode(); + + public abstract boolean isInSplitter(); + + public abstract boolean hasOpenedFile (); + + public abstract VirtualFile getCurrentFile(); + + public abstract Pair getSelectedEditorWithProvider(VirtualFile file); + + public abstract void closeAllFiles(); + + public FileEditor[] openFile(final VirtualFile file, final boolean focusEditor) { + return openFileWithProviders(file, focusEditor).getFirst (); + } + + public abstract Pair openFileWithProviders(VirtualFile file, boolean focusEditor); + + public abstract boolean isChanged(EditorComposite editor); + + public abstract EditorWindow getNextWindow(final EditorWindow window); + + public abstract EditorWindow getPrevWindow(final EditorWindow window); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorProviderManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorProviderManager.java new file mode 100644 index 00000000000..1f138f4bace --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/FileEditorProviderManager.java @@ -0,0 +1,31 @@ +package com.intellij.openapi.fileEditor.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class FileEditorProviderManager{ + public static FileEditorProviderManager getInstance(){ + return ApplicationManager.getApplication().getComponent(FileEditorProviderManager.class); + } + + /** + * @param file cannot be null + * + * @return array of all editors providers that can create editor + * for the specified file. The method returns + * an empty array if there are no such providers. Please note that returned array + * is constructed with respect to editor policies. + */ + public abstract FileEditorProvider[] getProviders(Project project, VirtualFile file); + + /** + * @return may be null + */ + public abstract FileEditorProvider getProvider(String editorTypeId); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/IdeDocumentHistory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/IdeDocumentHistory.java new file mode 100644 index 00000000000..631b88164c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/ex/IdeDocumentHistory.java @@ -0,0 +1,23 @@ + +package com.intellij.openapi.fileEditor.ex; + +import com.intellij.openapi.project.Project; + +public abstract class IdeDocumentHistory { + public static IdeDocumentHistory getInstance(Project project) { + return project.getComponent(IdeDocumentHistory.class); + } + + public abstract void includeCurrentCommandAsNavigation(); + public abstract void includeCurrentPlaceAsChangePlace(); + public abstract void clearHistory(); + + public abstract void back(); + public abstract void forward(); + + public abstract boolean isBackAvailable(); + public abstract boolean isForwardAvailable(); + + public abstract void navigatePreviousChange(); + public abstract boolean isNavigatePreviousChangeAvailable(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorComposite.java new file mode 100644 index 00000000000..e492d3da679 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorComposite.java @@ -0,0 +1,306 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.FocusWatcher; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.editor.Document; +import com.intellij.ui.TabbedPaneWrapper; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; +import java.awt.*; + +/** + * This class hides internal structure of UI component which represent + * set of opened editors. For example, one myEditor is represented by its + * component, more then one myEditor is wrapped into tabbed pane. + * + * @author Vladimir Kondratyev + */ +public abstract class EditorComposite{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorComposite"); + + private final EventListenerList myListenerList; + /** + * File for which composite is created + */ + private final VirtualFile myFile; + /** + * Whether the composite is pinned or not + */ + private boolean myPinned; + /** + * Editors which are opened in the composite + */ + protected final FileEditor[] myEditors; + /** + * This is initial timestamp of the file. It uses to implement + * "close non modified editors first" feature. + */ + private final long myInitialFileTimeStamp; + protected final TabbedPaneWrapper myTabbedPaneWrapper; + private final MyComponent myComponent; + private final FocusWatcher myFocusWatcher; + /** + * Currently selected myEditor + */ + private FileEditor mySelectedEditor; + private final FileEditorManager myFileEditorManager; + private final long myInitialFileModificationStamp; + + /** + * @param file file for which composite is being constructed + * + * @param editors edittors that should be placed into the composite + * + * @exception java.lang.IllegalArgumentException if editors + * is null + * + * @exception java.lang.IllegalArgumentException if providers + * is null + * + * @exception java.lang.IllegalArgumentException if myEditor + * arrays is empty + */ + EditorComposite( + final VirtualFile file, + final FileEditor[] editors, + final FileEditorManager fileEditorManager + ){ + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + if(editors==null){ + throw new IllegalArgumentException("editors cannot be null"); + } + if (fileEditorManager == null) { + throw new IllegalArgumentException("fileEditorManager cannot be null"); + } + + myFile = file; + myEditors = editors; + myFileEditorManager = fileEditorManager; + myListenerList = new EventListenerList(); + myInitialFileTimeStamp = myFile.getTimeStamp(); + myInitialFileModificationStamp = myFile.getModificationStamp(); + + if(editors.length > 1){ + final TabbedPaneWrapper wrapper = new TabbedPaneWrapper(SwingConstants.BOTTOM); + myTabbedPaneWrapper=wrapper; + myComponent=new MyComponent(wrapper.getComponent()){ + public void requestFocus() { + wrapper.getComponent().requestFocus(); + } + + public boolean requestDefaultFocus() { + return wrapper.getComponent().requestDefaultFocus(); + } + }; + for(int i=0;inull valus. + */ + public VirtualFile getFile() { + return myFile; + } + + /** + * @return initial time stamp of the file (on moment of creation of + * the composite) + */ + public long getInitialFileTimeStamp() { + return myInitialFileTimeStamp; + } + + /** + * @return initial modifcation stamp of the file (on moment of creation of + * the composite) + */ + public long getInitialFileModificationStamp() { + return myInitialFileModificationStamp; + } + + /** + * @return editors which are opened in the composite. Do not modify + * this array. + */ + public FileEditor[] getEditors() { + return myEditors; + } + + /** + * @return currently selected myEditor. The method never returns null. + */ + FileEditor getSelectedEditor(){ + return getSelectedEditorWithProvider ().getFirst (); + } + + /** + * @return currently selected myEditor with its provider. The method never returns null. + */ + public abstract Pair getSelectedEditorWithProvider(); + + void setSelectedEditor(final int index){ + if(myEditors.length == 1){ + // nothing to do + LOG.assertTrue(myTabbedPaneWrapper == null); + } + else{ + LOG.assertTrue(myTabbedPaneWrapper != null); + myTabbedPaneWrapper.setSelectedIndex(index); + } + } + + /** + * @return component which represents set of file editors in the UI + */ + public JComponent getComponent() { + return myComponent; + } + + /** + * @return true if the composite contains at least one + * modified myEditor + */ + public boolean isModified(){ + for(int i=myEditors.length-1;i>=0;i--){ + if(myEditors[i].isModified()){ + return true; + } + } + return false; + } + + /** + * Handles changes of selected myEditor + */ + private final class MyChangeListener implements ChangeListener{ + public void stateChanged(ChangeEvent e) { + FileEditor oldSelectedEditor = mySelectedEditor; + LOG.assertTrue(oldSelectedEditor != null); + int selectedIndex = myTabbedPaneWrapper.getSelectedIndex(); + LOG.assertTrue(selectedIndex != -1); + mySelectedEditor = myEditors[selectedIndex]; + fireSelectedEditorChanged(oldSelectedEditor, mySelectedEditor); + } + } + + private abstract class MyComponent extends JPanel implements DataProvider{ + public MyComponent(JComponent realComponent){ + super(new BorderLayout()); + add(realComponent, BorderLayout.CENTER); + } + + public final Object getData(String dataId){ + if (DataConstants.FILE_EDITOR.equals(dataId)) { + return getSelectedEditor(); + } + else if(DataConstants.VIRTUAL_FILE.equals(dataId)){ + return myFile; + } + else if(DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)){ + return new VirtualFile[] {myFile}; + } + else{ + JComponent component = getPreferredFocusedComponent(); + if(component instanceof DataProvider){ + return ((DataProvider)component).getData(dataId); + } + else{ + return null; + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java new file mode 100644 index 00000000000..c2a155d9a27 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java @@ -0,0 +1,303 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public final class EditorHistoryManager implements ProjectComponent, JDOMExternalizable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorHistoryManager"); + private Element myElement; + + public static EditorHistoryManager getInstance(final Project project){ + return project.getComponent(EditorHistoryManager.class); + } + + private final Project myProject; + /** + * State corresponding to the most recent file is the last + */ + private final ArrayList myEntriesList; + /** + * Listen opening of myEditor to update history + */ + private final MyEditorManagerListener myEditorManagerListener; + /** + * Updates history length + */ + private final MyUISettingsListener myUISettingsListener; + + /** Invoked by reflection */ + EditorHistoryManager(final Project project, FileEditorManager fileEditorManager, UISettings uiSettings){ + myProject = project; + myEntriesList = new ArrayList(); + myEditorManagerListener = new MyEditorManagerListener(); + myUISettingsListener = new MyUISettingsListener(); + + fileEditorManager.addFileEditorManagerListener(myEditorManagerListener); + uiSettings.addUISettingsListener(myUISettingsListener); + } + + public void projectOpened(){ + StartupManager.getInstance(myProject).registerPostStartupActivity( + new Runnable(){ + public void run(){ + // myElement may be null if node that correspondes to this manager does not exist + if (myElement != null){ + final List children = myElement.getChildren(HistoryEntry.TAG); + myElement = null; + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + final Element e = (Element)iterator.next(); + try { + myEntriesList.add(new HistoryEntry(myProject, e)); + } + catch (InvalidDataException e1) { + } + } + trimToSize(); + } + } + } + ); + } + + public void projectClosed(){} + + public String getComponentName(){ + return "editorHistoryManager"; + } + + public void initComponent() { } + + public void disposeComponent(){ + FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myEditorManagerListener); + UISettings.getInstance().removeUISettingsListener(myUISettingsListener); + } + + /** + * Makes file most recent one + */ + private void fileOpenedImpl(final VirtualFile file){ + if (file == null){ + throw new IllegalArgumentException("file cannot be null"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + + final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(myProject); + + final Pair editorsWithProviders = editorManager.getEditorsWithProviders(file); + final FileEditor [] editors = editorsWithProviders.getFirst(); + final FileEditorProvider [] oldProviders = editorsWithProviders.getSecond(); + LOG.assertTrue(editors.length > 0); + final FileEditor selectedEditor = editorManager.getSelectedEditor(file); + LOG.assertTrue(selectedEditor != null); + final int selectedProviderIndex = ArrayUtil.find(editors, selectedEditor); + LOG.assertTrue(selectedProviderIndex != -1); + + final HistoryEntry entry = getEntry(file); + if(entry != null){ + myEntriesList.remove(entry); + myEntriesList.add(entry); + }else{ + final FileEditorState[] states=new FileEditorState[editors.length]; + final FileEditorProvider[] providers=new FileEditorProvider[editors.length]; + for (int i = states.length - 1; i >= 0; i--) { + //final FileEditorProvider provider = FileEditorManagerEx.getInstanceEx(myProject).getProvider(editors[i]); + final FileEditorProvider provider = oldProviders [i]; + LOG.assertTrue(provider != null); + providers[i] = provider; + final FileEditorState state = editors[i].getState(FileEditorStateLevel.FULL); + states[i] = state; + LOG.assertTrue(state != null); + } + myEntriesList.add(new HistoryEntry(file, providers, states, providers[selectedProviderIndex])); + trimToSize(); + } + } + + private void updateHistoryEntry(final VirtualFile file, final boolean changeOrder){ + if (file == null){ + return; + } + final HistoryEntry entry = getEntry(file); + if(entry == null){ + // Size of entry list can be less than number of opened editors (some entries can be removed) + fileOpenedImpl(file); + return; + } + + boolean changed=false; + final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(myProject); + final Pair editorsWithProviders = editorManager.getEditorsWithProviders(file); + final FileEditor [] editors = editorsWithProviders.getFirst(); + final FileEditorProvider [] providers = editorsWithProviders.getSecond(); + //LOG.assertTrue(editors.length > 0); + for (int i = editors.length - 1; i >= 0; i--) { + final FileEditor editor = editors [i]; + final FileEditorProvider provider = providers [i]; + if (!editor.isValid()) { + // this can happen for example if file extension was changed + // and this method was called during correponding myEditor close up + continue; + } + + final FileEditorState oldState = entry.getState(provider); + final FileEditorState newState = editor.getState(FileEditorStateLevel.FULL); + LOG.assertTrue(newState != null); + if (!newState.equals(oldState)) { + changed = true; + entry.putState(provider, newState); + } + } + final Pair selectedEditorWithProvider = editorManager.getSelectedEditorWithProvider(file); + if (selectedEditorWithProvider != null) { + //LOG.assertTrue(selectedEditorWithProvider != null); + entry.mySelectedProvider = selectedEditorWithProvider.getSecond (); + LOG.assertTrue(entry.mySelectedProvider != null); + + if(changed && changeOrder){ + myEntriesList.remove(entry); + myEntriesList.add(entry); + } + } + } + + /** + * Removes all entries that correspond to invalid files + */ + private void validateEntries(){ + for(int i=myEntriesList.size()-1; i>=0; i--){ + final HistoryEntry entry = myEntriesList.get(i); + if(!entry.myFile.isValid()){ + myEntriesList.remove(i); + } + } + } + + /** + * @return array of valid files that are in the history. Files with top + * indices are most recent. + */ + public VirtualFile[] getFiles(){ + validateEntries(); + final VirtualFile[] result = new VirtualFile[myEntriesList.size()]; + for(int i=myEntriesList.size()-1; i>=0 ;i--){ + result[i] = myEntriesList.get(i).myFile; + } + return result; + } + + /** + * Removes specified file from history. The method does + * nothing if file is not in the history. + * + * @exception java.lang.IllegalArgumentException if file + * is null + */ + public void removeFile(final VirtualFile file){ + if (file == null){ + throw new IllegalArgumentException("file cannot be null"); + } + final HistoryEntry entry = getEntry(file); + if(entry != null){ + myEntriesList.remove(entry); + } + } + + public FileEditorState getState(final VirtualFile file, final FileEditorProvider provider) { + validateEntries(); + final HistoryEntry entry = getEntry(file); + return entry != null ? entry.getState(provider) : null; + } + + /** + * @return may be null + */ + public FileEditorProvider getSelectedProvider(final VirtualFile file) { + validateEntries(); + final HistoryEntry entry = getEntry(file); + return entry != null ? entry.mySelectedProvider : null; + } + + private HistoryEntry getEntry(final VirtualFile file){ + validateEntries(); + for (int i = myEntriesList.size() - 1; i >= 0; i--) { + final HistoryEntry entry = myEntriesList.get(i); + if(file.equals(entry.myFile)){ + return entry; + } + } + return null; + } + + /** + * If total number of files in history more then UISettings.RECENT_FILES_LIMIT + * then removes the oldest ones to fit the history to new size. + */ + private void trimToSize(){ + final int limit = UISettings.getInstance().RECENT_FILES_LIMIT; + while(myEntriesList.size()>limit){ + myEntriesList.remove(0); + } + } + + public void readExternal(final Element element) { + // we have to delay xml processing because history entries require EditorStates to be created + // which is done via corresponding EditorProviders, those are not accessible before their + // is initComponent() called + myElement = (Element)element.clone(); + } + + public void writeExternal(final Element element){ + // update history before saving + final VirtualFile[] openFiles = FileEditorManager.getInstance(myProject).getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + if(getEntry(file) != null){ // we have to update only files that are in history + updateHistoryEntry(file, false); + } + } + + for (int i=0; i < myEntriesList.size(); i++){ + final HistoryEntry entry = myEntriesList.get(i); + entry.writeExternal(element, myProject); + } + } + + /** + * Updates history + */ + private final class MyEditorManagerListener extends FileEditorManagerAdapter{ + public void fileOpened(final FileEditorManager source, final VirtualFile file){ + fileOpenedImpl(file); + } + + public void selectionChanged(final FileEditorManagerEvent event){ + updateHistoryEntry(event.getOldFile(), true); + } + } + + /** + * Cuts/extends history length + */ + private final class MyUISettingsListener implements UISettingsListener{ + public void uiSettingsChanged(final UISettings source) { + trimToSize(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java new file mode 100644 index 00000000000..92f644d30e3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java @@ -0,0 +1,465 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.Patches; +import com.intellij.ide.actions.NextTabAction; +import com.intellij.ide.actions.PreviousTabAction; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.ui.plaf.beg.BegTabbedPaneUI; + +import javax.swing.*; +import javax.swing.plaf.TabbedPaneUI; +import javax.swing.plaf.basic.BasicTabbedPaneUI; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class EditorTabbedContainer extends TabbedPaneWrapper { + private final EditorWindow myWindow; + private final Project myProject; + private final FileEditorManagerImpl myEditorManager; + + EditorTabbedContainer(final EditorWindow window, Project project, int tabPlacement, FileEditorManagerImpl editorManager) { + super(tabPlacement); + myWindow = window; + myProject = project; + myEditorManager = editorManager; + } + + protected TabbedPane createTabbedPane(int tabPlacement) { + return new MyTabbedPane(tabPlacement); + + } + + protected JComponent createTabbedPaneHolder() { + return new MyTabbedPaneHolder(); + } + + private final class MyTabbedPane extends TabbedPaneWrapper.TabbedPane { + private final MyTabbedPanePopupHandler myTabbedPanePopupHandler; + + public MyTabbedPane(int tabPlacement) { + super(tabPlacement); + enableEvents(MouseEvent.MOUSE_EVENT_MASK); + setOpaque(true); + myTabbedPanePopupHandler = new MyTabbedPanePopupHandler(); + putClientProperty("TabbedPane.paintContentBorder", Boolean.FALSE); + updateUI(); + } + + /** + * Actually all this stuff should be placed into updateUI method. + * But due to this method replaces the current UI of the tabbed pane + * this code exists here. One I [vova] placed it into updateUI and + * middle mouse button stop working in SCROLL_TAB_LAYOUT. + */ + public void setTabLayoutPolicy(int tabLayoutPolicy) { + super.setTabLayoutPolicy(tabLayoutPolicy); + if (Patches.SUN_BUG_ID_4620537) { + TabbedPaneUI tabbedPaneUI = getUI(); + if (!(tabbedPaneUI instanceof BasicTabbedPaneUI)) { + return; + } + for (int i = 0; i < getComponentCount(); i++) { + Component c = getComponent(i); + if (!(c instanceof JViewport)) { + continue; + } + JPanel panel = (JPanel)((JViewport)c).getView(); + panel.setBackground(UIManager.getColor("TabbedPane.background")); + + MouseListener[] listeners = (MouseListener[])panel.getListeners(MouseListener.class); + for (int j = 0; j < listeners.length; j++) { + panel.removeMouseListener(listeners[j]); + } + } + } + } + + private VirtualFile getFileAt(final int x, final int y) { + final int index = getTabIndexAt(x, y); + if (index < 0) { + return null; + } + return myWindow.getEditors()[index].getFile(); + } + + protected void processMouseEvent(MouseEvent e) { + // First of all we have to hide showing popup menu (if any) + if (MouseEvent.MOUSE_PRESSED == e.getID()) { + final MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); + menuSelectionManager.clearSelectedPath(); + myWindow.setAsCurrentWindow(true); + } + + // activate current tabbed pane: + //if (MouseEvent.MOUSE_RELEASED == e.getID ()) { + //} + + if (e.isPopupTrigger()) { // Popup doesn't activate clicked tab + myTabbedPanePopupHandler.invokePopup(e.getComponent(), e.getX(), e.getY()); + return; + } + + if (!e.isShiftDown() && (MouseEvent.BUTTON1_MASK & e.getModifiers()) > 0) { + // RightClick without Shift modifiers just select tab + // To reach this behaviour we have to block all MOUSE_PRESSED events + // and react only on MOUSE_RELEASE. But clicks outside tab bounds + // have a special sense under Mac OS X. There is a special scroll button + // in Aqua LAF which shows drop down list with opened tab. To make it + // work we also have to specially hande clicks outsode the tab bounds. + final int index = getTabIndexAt(e.getX(), e.getY()); + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + if (index != -1) { + setSelectedIndex(index); + } + else { // push forward events outside thw tab bounds + super.processMouseEvent(e); + } + } + else { + if (index == -1) { // push forward events outside thw tab bounds + super.processMouseEvent(e); + } + } + } + else if (e.isShiftDown() && (MouseEvent.BUTTON1_MASK & e.getModifiers()) > 0) { // Shift+LeftClick closes the tab + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + final VirtualFile file = getFileAt(e.getX(), e.getY()); + if (file != null) { + myWindow.closeFile(file); + } + } + } + else if ((MouseEvent.BUTTON2_MASK & e.getModifiers()) > 0) { // MouseWheelClick closes the tab + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + final VirtualFile file = getFileAt(e.getX(), e.getY()); + if (file != null) { + myWindow.closeFile(file); + } + } + } + else if ((MouseEvent.BUTTON3_MASK & e.getModifiers()) > 0 && SystemInfo.isWindows) { // Right mouse button doesn't activate tab + } + else { + super.processMouseEvent(e); + } + } + + public void paint(Graphics g) { + if (getTabCount() != 0) { + super.paint(g); + } + else { + g.setColor(Color.gray); + g.fillRect(0, 0, getWidth(), getHeight()); + } + } + + public void updateUI() { + super.updateUI(); + if (getUI() instanceof BegTabbedPaneUI) { + ((BegTabbedPaneUI)getUI()).setNoIconSpace(UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK); + } + } + + + private final class MyCloseAction extends AnAction { + private final VirtualFile myFile; + + public MyCloseAction(final VirtualFile file) { + super("Close"); + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_EDITOR).getShortcutSet(), null); + myFile = file; + } + + public void actionPerformed(final AnActionEvent e) { + myWindow.closeFile(myFile); + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + presentation.setEnabled(myFile != null); + } + } + + private final class MyCloseAllButThisAction extends AnAction { + private final VirtualFile myFile; + + public MyCloseAllButThisAction(VirtualFile file) { + super("Close All But This"); + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_ALL_EDITORS_BUT_THIS).getShortcutSet(), null); + myFile = file; + } + + public void actionPerformed(AnActionEvent e) { + final VirtualFile[] siblings = myWindow.getFiles(); + for (int i = 0; i < siblings.length; i++) { + VirtualFile file = siblings[i]; + if (file != myFile) { + myWindow.closeFile(siblings[i]); + } + } + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myFile != null && getTabCount() > 1); + } + } + + /** + * Closes all editor in the tabbed container + */ + private final class MyCloseAllAction extends AnAction { + public MyCloseAllAction() { + super("Close All", "Close all editors in the tab group", null); + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_ALL_EDITORS).getShortcutSet(), null); + } + + public void actionPerformed(AnActionEvent e) { + // Collect files to be closed + final VirtualFile[] files = myWindow.getFiles(); + for (int i = 0; i < files.length; i++) { + myWindow.closeFile(files[i]); + } + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(getTabCount() > 0); + } + } + + /** + * Closes all editor in the tabbed container + */ + private final class MyCloseAllUnmodifiedAction extends AnAction { + public MyCloseAllUnmodifiedAction() { + super("Close All Unmodified", "Close all editors in the tab group", null); + registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_ALL_UNMODIFIED_EDITORS).getShortcutSet(), null); + } + + public void actionPerformed(AnActionEvent e) { + // Collect files to be closed + final EditorWithProviderComposite[] editors = myWindow.getEditors(); + for (int i = 0; i < editors.length; i++) { + final EditorWithProviderComposite editor = editors[i]; + if (!myEditorManager.isChanged(editor)) { + myWindow.closeFile(editor.getFile ()); + } + } + } + + public void update(AnActionEvent e) { + final EditorWithProviderComposite[] editors = myWindow.getEditors(); + for (int i = 0; i < editors.length; i++) { + if (!myEditorManager.isChanged(editors[i])) { + e.getPresentation().setEnabled(true); + return; + } + } + e.getPresentation().setEnabled(false); + } + } + + /** + * Toggles "pin" state of the file + */ + private final class MyPinEditorAction extends AnAction { + private final VirtualFile myFile; + + public MyPinEditorAction(VirtualFile file) { + getTemplatePresentation().setDescription("Pin/unpin editor tab"); + myFile = file; + } + + public void actionPerformed(AnActionEvent e) { + myWindow.setFilePinned(myFile, !myWindow.isFilePinned(myFile)); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setText("Pin Tab"); + if (myFile == null) { + presentation.setEnabled(false); + } + else { + presentation.setEnabled(true); + if (myWindow.isFilePinned(myFile)) { + presentation.setText("Unpin Tab"); + } + } + } + } + + /** + * Selects next tab + */ + private final class MyNextTabAction extends AnAction { + public MyNextTabAction() { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_TAB)); + } + + public void actionPerformed(AnActionEvent e) { + final EditorComposite selectedComposite = myWindow.getSelectedEditor(); + NextTabAction.navigateImpl(myProject, selectedComposite.getFile(), +1); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myTabbedPane.getTabCount() > 1); + } + } + + private final class MyPreviousTabAction extends AnAction { + public MyPreviousTabAction() { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_TAB)); + } + + public void actionPerformed(AnActionEvent e) { + final EditorComposite selectedComposite = myWindow.getSelectedEditor(); + PreviousTabAction.navigateImpl(myProject, selectedComposite.getFile(), -1); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myTabbedPane.getTabCount() > 1); + } + } + + private abstract class MyNewTabGroupAction extends AnAction { + private final int myOrientation; + private final VirtualFile myFile; + + protected MyNewTabGroupAction(int orientation, VirtualFile file) { + myOrientation = orientation; + myFile = file; + } + + public void actionPerformed(AnActionEvent e) { + myEditorManager.createSplitter(myOrientation); + } + + public void update(AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + presentation.setEnabled(myEditorManager.hasOpenedFile()); + } + } + + private final class MyNewHorizontalTabGroupAction extends MyNewTabGroupAction { + public MyNewHorizontalTabGroupAction(VirtualFile file) { + super(SwingConstants.HORIZONTAL, file); + final AnAction action = ActionManager.getInstance().getAction("SplitHorisontal"); + copyFrom(action); + } + } + + private final class MyNewVerticalTabGroupAction extends MyNewTabGroupAction { + public MyNewVerticalTabGroupAction(VirtualFile file) { + super(SwingConstants.VERTICAL, file); + final AnAction action = ActionManager.getInstance().getAction("SplitVertical"); + copyFrom(action); + } + } + + private final class MyMoveEditorToOppositeTabGroupAction extends AnAction{ + private final VirtualFile myFile; + + public MyMoveEditorToOppositeTabGroupAction(final VirtualFile file) { + super ("Move To Opposite Tab Group"); + myFile = file; + } + + public void actionPerformed(final AnActionEvent event) { + if(myFile != null && myWindow != null){ + final EditorWindow[] siblings = myWindow.findSiblings (); + if (siblings != null && siblings.length == 1) { + FileEditorManagerImpl.openFileImpl3 (siblings [0], myFile, true, null); + myWindow.closeFile(myFile); + } + } + } + + public void update(AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + if(myFile != null && myWindow != null){ + final EditorWindow[] siblings = myWindow.findSiblings (); + if (siblings != null && siblings.length == 1) + presentation.setEnabled(true); + else + presentation.setEnabled(false); + return; + } + presentation.setEnabled(false); + } + } + + private final class MyChangeTabGroupsOrientation extends AnAction { + public MyChangeTabGroupsOrientation() { + AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_CHANGE_SPLIT_ORIENTATION); + copyFrom(action); + } + + public void actionPerformed(AnActionEvent e) { + myEditorManager.changeSplitterOrientation(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myEditorManager.isInSplitter()); + } + } + + private final class MyTabbedPanePopupHandler extends PopupHandler { + public void invokePopup(final Component comp, final int x, final int y) { + final DefaultActionGroup _group = new DefaultActionGroup(); + final ActionManager actionManager = ActionManager.getInstance(); + final VirtualFile fileAt = getFileAt(x, y); + _group.add(new MyCloseAction(fileAt)); + _group.add(new MyCloseAllButThisAction(fileAt)); + _group.add(new MyCloseAllAction()); + _group.add(new MyCloseAllUnmodifiedAction()); + _group.addSeparator(); + _group.add(new MyNewHorizontalTabGroupAction(fileAt)); + _group.add(new MyNewVerticalTabGroupAction(fileAt)); + _group.add(new MyMoveEditorToOppositeTabGroupAction(fileAt)); + _group.add(new MyChangeTabGroupsOrientation()); + //_group.addSeparator(); + _group.add(new MyPinEditorAction(fileAt)); + _group.addSeparator(); + _group.add(new MyNextTabAction()); + _group.add(new MyPreviousTabAction()); + _group.addSeparator(); + final ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_EDITOR_TAB_POPUP); + final AnAction[] children = group.getChildren(null); + for (int i = 0; i < children.length; i++) { + final AnAction child = children[i]; + _group.add(child); + } + final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_TAB_POPUP, _group); + menu.getComponent().show(comp, x, y); + } + } + } + + private final class MyTabbedPaneHolder extends TabbedPaneWrapper.TabbedPaneHolder implements DataProvider { + public Object getData(String dataId) { + if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + return myWindow.getSelectedFile(); + } + else { + return null; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWindow.java new file mode 100644 index 00000000000..fb5b875e6c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -0,0 +1,758 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.ui.LayeredIcon; +import com.intellij.util.IconUtil; +import com.intellij.util.containers.ArrayListSet; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * Author: msk + */ +public class EditorWindow { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorWindow"); + + protected JPanel myPanel; + private EditorTabbedContainer myTabbedPane; + public int myInsideTabChange; + private MyTabbedContainerChangeListener myChangeListener; + protected final EditorsSplitters myOwner; + + protected EditorWindow(final EditorsSplitters owner) { + myOwner = owner; + myPanel = new JPanel(new BorderLayout()); + myTabbedPane = null; + + final int tabPlacement = UISettings.getInstance().EDITOR_TAB_PLACEMENT; + //if (tabPlacement == UISettings.TABS_NONE) { + // tabPlacement = SwingConstants.TOP; + //} + //else { + //} + if (tabPlacement != UISettings.TABS_NONE) + createTabs(tabPlacement); + + // Tab layout policy + if (UISettings.getInstance().SCROLL_TAB_LAYOUT_IN_EDITOR) { + setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + } else { + setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); + } + + getWindows().add(this); + if (myOwner.myCurrentWindow == null) { + myOwner.setCurrentWindow(this, false); + } + } + + private void createTabs(int tabPlacement) { + LOG.assertTrue (myTabbedPane == null); + myTabbedPane = new EditorTabbedContainer(this, getManager().myProject, tabPlacement, getManager()); + myTabbedPane.addChangeListener(myChangeListener = new MyTabbedContainerChangeListener()); + myPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + } + + private ArrayListSet getWindows() { + return myOwner.myWindows; + } + + + + private void dispose() { + disposeTabs(); + myChangeListener = null; + getWindows ().remove(this); + } + + private void disposeTabs() { + if (myTabbedPane != null) { + myTabbedPane.removeChangeListener(myChangeListener); + myTabbedPane = null; + } + myPanel.removeAll(); + myPanel.revalidate(); + } + + + public void closeFile(final VirtualFile file) { + closeFile (file, true); + } + + public void closeFile(final VirtualFile file, final boolean unsplit) { + final EditorWithProviderComposite[] editors = getManager().getEditorComposites(file); + LOG.assertTrue(editors != null); + final EditorWithProviderComposite editor = findFileComposite(file); + getManager().disposeComposite(editor); + + if (myTabbedPane != null) { + final int componentIndex = findComponentIndex(editor.getComponent()); + if (componentIndex >= 0) { // editor could close itself on decomposition + if (componentIndex > 0) { + myTabbedPane.setSelectedIndex(componentIndex - 1); + } + myTabbedPane.removeTabAt(componentIndex); + } + if (unsplit && getTabCount() == 0) { + unsplit (); + } + } + else { + myPanel.removeAll (); + } + myPanel.revalidate (); + if (editors.length == 1) { + getManager().closeFile(file); + } + } + + public void removeEditor(final EditorWithProviderComposite editor) { + getManager().disposeComposite(editor); + if (myTabbedPane != null) { + int componentIndex = findComponentIndex(editor.getComponent()); + if (componentIndex >= 0) { // editor could close itself while disposing. + myTabbedPane.removeTabAt(componentIndex); + } + } + } + + public FileEditorManagerImpl getManager() { return myOwner.getManager(); } + + public int getTabCount() { + if (myTabbedPane != null) + return myTabbedPane.getTabCount (); + return myPanel.getComponentCount(); + } + + public void setForegroundAt(final int index, final Color color) { + if (myTabbedPane != null) { + myTabbedPane.setForegroundAt(index, color); + } + } + + public void setIconAt(final int index, final Icon icon) { + if (myTabbedPane != null) { + myTabbedPane.setIconAt(index, icon); + } + } + + public void setTitleAt(final int index, final String text) { + if (myTabbedPane != null) { + myTabbedPane.setTitleAt(index, text); + } + } + + public void setToolTipTextAt(final int index, final String text) { + if (myTabbedPane != null) { + myTabbedPane.setToolTipTextAt(index, text); + } + } + + + public void setTabLayoutPolicy(final int policy) { + try { + ++ myInsideTabChange; + if (myTabbedPane != null) { + myTabbedPane.setTabLayoutPolicy(policy); + } + } + finally { + -- myInsideTabChange; + } + } + + public void setTabsPlacement(final int tabPlacement) { + try { + ++ myInsideTabChange; + if (tabPlacement != UISettings.TABS_NONE) { + if (myTabbedPane == null) { + final EditorWithProviderComposite editor = getSelectedEditor(); + myPanel.removeAll(); + createTabs(tabPlacement); + setEditor (editor); + } + else { + myTabbedPane.setTabPlacement(tabPlacement); + } + } + else if (myTabbedPane != null) { + final boolean focusEditor = ToolWindowManager.getInstance(getManager().myProject).isEditorComponentActive(); + final VirtualFile currentFile = getSelectedFile(); + final VirtualFile[] files = getFiles(); + for (int i = 0; i < files.length; i++) { + closeFile(files[i], false); + } + disposeTabs(); + getManager().openFileImpl2(this, currentFile, focusEditor && (myOwner.getCurrentWindow() == this), null); + } + } + finally { + -- myInsideTabChange; + } + } + + public void setAsCurrentWindow(final boolean requestFocus) { + myOwner.setCurrentWindow(this, requestFocus); + } + + protected class TComp extends JPanel { + final EditorWithProviderComposite myEditor; + + TComp(final EditorWithProviderComposite editor) { + super(new BorderLayout()); + myEditor = editor; + add(editor.getComponent(), BorderLayout.CENTER); + } + } + + private final class MyTabbedContainerChangeListener implements ChangeListener { + public void stateChanged(ChangeEvent e) { + //assertThread(); + if (myInsideTabChange > 0) { // do not react on own events + return; + } + final EditorComposite composite = getSelectedEditor(); + if (composite != null) { + final Project project = getManager().myProject; + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + getManager().openFileImpl2(EditorWindow.this, composite.getFile(), true, null); + } + }, + "", + null); + } + } + } + + private void check() { + for (Iterator iterator = getWindows ().iterator(); iterator.hasNext();) { + final EditorWindow window = iterator.next(); + if (window == this) { + return; + } + } + LOG.error("EditorWindow not in collection"); + } + + public EditorWithProviderComposite getSelectedEditor() { + final TComp comp; + if (myTabbedPane != null) { + comp = (TComp)myTabbedPane.getSelectedComponent(); + } + else if (myPanel.getComponentCount () != 0) { + comp = (TComp)myPanel.getComponent(0); + } + else + return null; + + if (comp != null) { + return comp.myEditor; + } + return null; + } + + public EditorWithProviderComposite[] getEditors() { + final int tabCount = getTabCount(); + final EditorWithProviderComposite[] res = new EditorWithProviderComposite[tabCount]; + for (int i = 0; i != tabCount; ++i) { + res[i] = getEditorAt(i); + } + return res; + } + + public VirtualFile[] getFiles() { + final int tabCount = getTabCount(); + final VirtualFile[] res = new VirtualFile[tabCount]; + for (int i = 0; i != tabCount; ++i) { + res[i] = getEditorAt(i).getFile(); + } + return res; + } + + public void setSelectedEditor(final EditorComposite editor) { + if (myTabbedPane == null) return; + try { + ++myInsideTabChange; + if (editor != null) { + final int index = findFileIndex(editor.getFile()); + if (index != -1) { + myTabbedPane.setSelectedIndex(index); + } + } + } + finally { + --myInsideTabChange; + } + } + + public void setEditor(final EditorWithProviderComposite editor) { + if (editor != null) { + if (myTabbedPane == null) { + myPanel.removeAll (); + myPanel.add (new TComp(editor), BorderLayout.CENTER); + myPanel.revalidate (); + return; + } + + final int index = findEditorIndex(editor); + try { + ++myInsideTabChange; + if (index != -1) { + setSelectedEditor(editor); + } + else { + final int indexToInsert = myTabbedPane.getSelectedIndex() + 1; + final VirtualFile file = editor.getFile(); + myTabbedPane.insertTab(file.getPresentableName(), null, new TComp(editor), null, indexToInsert); + trimToSize(UISettings.getInstance().EDITOR_TAB_LIMIT, file); + setSelectedEditor(editor); + myOwner.updateFileIcon(file, true); + myOwner.updateFileColor(file); + } + myOwner.setCurrentWindow(this, false); + } + finally { + --myInsideTabChange; + } + } + myPanel.revalidate(); + } + + public boolean splitAvailable() { + return getTabCount() >= (getManager().isSingleFileMode() ? 2 : 1); + } + + public EditorWindow split(final int orientation) { + check(); + if (splitAvailable()) { + final JPanel panel = myPanel; + final int tabCount = getTabCount(); + if (tabCount != 0) { + final boolean singleFileMode = getManager().isSingleFileMode(); + final EditorWithProviderComposite firstEC = getEditorAt(0); + myPanel = new JPanel(new BorderLayout()); + final Splitter splitter = new Splitter(orientation == JSplitPane.VERTICAL_SPLIT, 0.5f, 0.1f, 0.9f); + final EditorWindow res = new EditorWindow(myOwner); + if (myTabbedPane != null) { + final EditorWithProviderComposite selectedEditor = getSelectedEditor(); + panel.remove(myTabbedPane.getComponent()); + panel.add(splitter, BorderLayout.CENTER); + splitter.setFirstComponent(myPanel); + myPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + splitter.setSecondComponent(res.myPanel); + if (singleFileMode) { + final TComp component = (TComp)myTabbedPane.getComponent(); + myOwner.remove(component); + res.setEditor(component.myEditor); + } + else { + for (int i = 0; i != tabCount; ++i) { + final EditorWithProviderComposite eC = getEditorAt(i); + final VirtualFile file = eC.getFile(); + FileEditorManagerImpl.openFileImpl3(res, file, false, null); + res.setFilePinned (file, isFilePinned (file)); + } + res.setSelectedEditor(selectedEditor); + selectedEditor.getComponent().requestFocus(); + } + + panel.revalidate(); + } + else { + panel.removeAll(); + panel.add(splitter, BorderLayout.CENTER); + splitter.setFirstComponent(myPanel); + splitter.setSecondComponent(res.myPanel); + panel.revalidate(); + final VirtualFile file = firstEC.getFile(); + FileEditorManagerImpl.openFileImpl3(this, file, true, null); + FileEditorManagerImpl.openFileImpl3(res, file, false, null); + } + return res; + } + } + return this; + } + + + public EditorWindow[] findSiblings() { + check(); + final ArrayList res = new ArrayList(); + if (myPanel.getParent() instanceof Splitter) { + final Splitter splitter = (Splitter)myPanel.getParent(); + for (Iterator elem = getWindows().iterator(); elem.hasNext();) { + final EditorWindow win = elem.next(); + if (win != this && SwingUtilities.isDescendingFrom(win.myPanel, splitter)) { + res.add(win); + } + } + } + return res.toArray(new EditorWindow[res.size()]); + } + + public Container getParent() { + check(); + return myPanel.getParent(); + } + + public void changeOrientation() { + check(); + final Container parent = myPanel.getParent(); + if (parent instanceof Splitter) { + final Splitter splitter = (Splitter)parent; + splitter.setOrientation(!splitter.getOrientation()); + } + } + + protected void updateFileIcon(VirtualFile file) { + final int index = findEditorIndex(findFileComposite(file)); + LOG.assertTrue(index != -1); + setIconAt(index, getFileIcon(file)); + } + + private String getFileTooltipText(final VirtualFile file) { + final StringBuffer tooltipText = new StringBuffer(); + final Module module = VfsUtil.getModuleForFile(getManager().myProject, file); + if (module != null) { + tooltipText.append("["); + tooltipText.append(module.getName()); + tooltipText.append("] "); + } + tooltipText.append(file.getPresentableUrl()); + final String text = tooltipText.toString(); + return text; + } + + protected void updateFileName(VirtualFile file) { + final int index = findEditorIndex(findFileComposite(file)); + if (index != -1) { + setTitleAt(index, file.getPresentableName()); + setToolTipTextAt(index, getFileTooltipText(file)); + } + } + + /** + * @return icon which represents file's type and modification status + */ + protected Icon getFileIcon(final VirtualFile file) { + LOG.assertTrue(file != null); + + final ArrayList icons = new ArrayList(6); + icons.add(IconUtil.getIcon(file, 0, getManager ().myProject)); + + // Read-only + if (!file.isWritable()) { + icons.add(FileEditorManagerImpl.LOCKED_ICON); + } + + // Pinned + final EditorComposite composite = findFileComposite(file); + if (composite != null && composite.isPinned()) { + icons.add(IconLoader.getIcon("/nodes/tabPin.png")); + } + + // Modified + if (UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK) { + if (composite != null && composite.isModified()) { + icons.add(FileEditorManagerImpl.MODIFIED_ICON); + } + else { + icons.add(FileEditorManagerImpl.GAP_ICON); + } + } + + final LayeredIcon result = new LayeredIcon(icons.size()); + for (int i = icons.size() - 1; i >= 0; i--) { + result.setIcon(icons.get(i), i); + } + + return result; + } + public void unsplit() { + check(); + final Container parent = myPanel.getParent(); + if (parent instanceof Splitter) { + final EditorWindow[] siblings = findSiblings(); + final JPanel parent2 = (JPanel)parent.getParent(); + for (int i = 0; i < siblings.length; i++) { + final EditorWindow sibling = siblings[i]; + final EditorWithProviderComposite[] editors = sibling.getEditors(); + for (int j = 0; j < editors.length; j++) { + final EditorWithProviderComposite editor = editors[j]; + if (myTabbedPane != null && getTabCount() < UISettings.getInstance().EDITOR_TAB_LIMIT && findFileComposite(editor.getFile()) == null) { + setEditor(editor); + } + else { + getManager().disposeComposite(editor); + } + } + LOG.assertTrue(sibling != this); + sibling.dispose(); + } + parent2.remove(parent); + if (myTabbedPane != null) { + parent2.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + } + else { + parent2.add(myPanel.getComponent(0), BorderLayout.CENTER); + } + parent2.revalidate(); + myPanel = parent2; + myOwner.setCurrentWindow(this, false); + } + } + + public void unsplitAll() { + check(); + while (inSplitter()) { + unsplit(); + } + } + + public boolean inSplitter() { + check(); + return (myPanel.getParent() instanceof Splitter); + } + + public VirtualFile getSelectedFile() { + check(); + final EditorWithProviderComposite editor = getSelectedEditor(); + return (editor == null ? null : editor.getFile()); + } + + public EditorWithProviderComposite findFileComposite(final VirtualFile file) { + for (int i = 0; i != getTabCount(); ++i) { + final EditorWithProviderComposite editor = getEditorAt(i); + if (editor.getFile ().equals (file)) { + return editor; + } + } + return null; + } + + + public int findComponentIndex(final Component component) { + for (int i = 0; i != getTabCount(); ++i) { + final EditorWithProviderComposite editor = getEditorAt(i); + if (editor.getComponent ().equals (component)) { + return i; + } + } + return -1; + } + + public int findEditorIndex(final EditorComposite editorToFind) { + for (int i = 0; i != getTabCount(); ++i) { + final EditorWithProviderComposite editor = getEditorAt(i); + if (editor.equals (editorToFind)) { + return i; + } + } + return -1; + } + + public int findFileIndex(final VirtualFile fileToFind) { + for (int i = 0; i != getTabCount(); ++i) { + final VirtualFile file = getFileAt(i); + if (file.equals (fileToFind)) { + return i; + } + } + return -1; + } + + private EditorWithProviderComposite getEditorAt(final int i) { + final TComp comp; + if (myTabbedPane != null) + comp = (TComp)myTabbedPane.getComponentAt(i); + else { + LOG.assertTrue (i <= 1); + comp = (TComp)myPanel.getComponent(i); + } + return comp.myEditor; + } + + public boolean isFileOpen(final VirtualFile file) { + return findFileComposite(file) != null; + } + + public boolean isFilePinned(final VirtualFile file) { + if(!isFileOpen(file)){ + throw new IllegalArgumentException("file is not open: " + file.getPath()); + } + getManager().assertThread(); + final EditorComposite editorComposite = findFileComposite(file); + return editorComposite.isPinned(); + } + + public void setFilePinned(final VirtualFile file, final boolean pinned) { + if(!isFileOpen(file)){ + throw new IllegalArgumentException("file is not open: " + file.getPath()); + } + getManager().assertThread(); + final EditorComposite editorComposite = findFileComposite(file); + editorComposite.setPinned(pinned); + updateFileIcon(file); + } + + void trimToSize(final int limit, final VirtualFile fileToIgnore) { + if (myTabbedPane == null) + return; + final boolean closeNonModifiedFilesFirst = UISettings.getInstance().CLOSE_NON_MODIFIED_FILES_FIRST; + final EditorComposite selectedComposite = getSelectedEditor(); + try { + myInsideTabChange++; + while_label: + while (myTabbedPane.getTabCount() > limit && myTabbedPane.getTabCount() > 0) { + // If all tabs are pinned then do nothings. Othrwise we will get infinitive loop + boolean allTabsArePinned = true; + for (int i = myTabbedPane.getTabCount() - 1; i >= 0; i--) { + final VirtualFile file = getFileAt(i); + if (fileCanBeClosed(file, fileToIgnore)) { + allTabsArePinned = false; + break; + } + } + if (allTabsArePinned) { + return; + } + + // Try to close non-modified files first (is specified in oprion) + if (closeNonModifiedFilesFirst) { + // Search in history + final VirtualFile[] allFiles = getFiles(); + final VirtualFile[] histFiles = EditorHistoryManager.getInstance(getManager ().myProject).getFiles(); + + // first, we search for files not in history + for (int i = 0; i != allFiles.length; ++ i) { + final VirtualFile file = allFiles[i]; + if (fileCanBeClosed(file, fileToIgnore)) { + boolean found = false; + for (int j = 0; j != histFiles.length; j++) + if (histFiles[j] == file) { + found = true; + break; + } + if (!found) { + closeFile(file); + continue while_label; + } + } + } + + for (int i = 0; i < histFiles.length; i++) { + final VirtualFile file = histFiles[i]; + if (!fileCanBeClosed(file, fileToIgnore)) { + continue; + } + + final EditorComposite composite = findFileComposite(file); + //LOG.assertTrue(composite != null); + if (composite != null && composite.getInitialFileTimeStamp() == file.getTimeStamp()) { + // we found non modified file + closeFile(file); + continue while_label; + } + } + + // Search in tabbed pane + final VirtualFile selectedFile = getSelectedFile(); + for (int i = 0; i < myTabbedPane.getTabCount(); i++) { + final VirtualFile file = getFileAt(i); + final EditorComposite composite = getEditorAt(i); + if (!fileCanBeClosed(file, fileToIgnore)) { + continue; + } + if (!selectedFile.equals(file)) { + if (composite.getInitialFileTimeStamp() == file.getTimeStamp()) { + // we found non modified file + closeFile(file); + continue while_label; + } + } + } + } + + // It's non enough to close non-modified files only. Try all other files. + // Search in history from less frequently used. + { + final VirtualFile[] allFiles = getFiles(); + final VirtualFile[] histFiles = EditorHistoryManager.getInstance(getManager ().myProject).getFiles(); + + // first, we search for files not in history + for (int i = 0; i != allFiles.length; ++ i) { + final VirtualFile file = allFiles[i]; + if (fileCanBeClosed(file, fileToIgnore)) { + boolean found = false; + for (int j = 0; j != histFiles.length; j++) + if (histFiles[j] == file) { + found = true; + break; + } + if (!found) { + closeFile(file); + continue while_label; + } + } + } + + + for (int i = 0; i < histFiles.length; i++) { + final VirtualFile file = histFiles[i]; + if (fileCanBeClosed(file, fileToIgnore)) { + closeFile(file); + continue while_label; + } + } + } + + // Close first opened file in tabbed pane that isn't a selected one + { + final VirtualFile selectedFile = getSelectedFile(); + for (int i = 0; i < myTabbedPane.getTabCount(); i++) { + final VirtualFile file = getFileAt(i); + if (!fileCanBeClosed(file, fileToIgnore)) { + continue; + } + if (!selectedFile.equals(file)) { + closeFile(file); + continue while_label; + } + else if (i == myTabbedPane.getTabCount() - 1) { + // if file is selected one and it's last file that we have no choice as close it + closeFile(file); + continue while_label; + } + } + } + } + } + finally { + setSelectedEditor(selectedComposite); + --myInsideTabChange; + } + } + + private boolean fileCanBeClosed(final VirtualFile file, final VirtualFile fileToIgnore) { + return isFileOpen (file) && !file.equals(fileToIgnore) && !isFilePinned(file); + } + + protected VirtualFile getFileAt(int i) { + return getEditorAt(i).getFile(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java new file mode 100644 index 00000000000..41c7e80866e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java @@ -0,0 +1,56 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; + +/** + * Author: msk + */ +public class EditorWithProviderComposite extends EditorComposite { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite"); + private final FileEditorProvider[] myProviders; + + EditorWithProviderComposite ( + final VirtualFile file, + final FileEditor[] editors, + final FileEditorProvider[] providers, + final FileEditorManager fileEditorManager + ) { + super(file, editors, fileEditorManager); + myProviders = providers; + } + + public FileEditorProvider[] getProviders() { + return myProviders; + } + + public boolean isModified() { + final FileEditor [] editors = getEditors (); + for (int i = 0; i < editors.length; i++) { + if (editors[i].isModified ()) { + return true; + } + } + return false; + } + + public Pair getSelectedEditorWithProvider() { + if(myEditors.length==1){ + LOG.assertTrue(myTabbedPaneWrapper==null); + return Pair.create (myEditors[0], myProviders [0]); + } + else{ // we have to get myEditor from tabbed pane + LOG.assertTrue(myTabbedPaneWrapper!=null); + final int index=myTabbedPaneWrapper.getSelectedIndex(); + LOG.assertTrue(index>=0); + LOG.assertTrue(index children = leaf.getChildren("file"); + VirtualFile currentFile = null; + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + final Element file = iterator.next(); + final HistoryEntry entry; + entry = new HistoryEntry(getManager().myProject, file.getChild(HistoryEntry.TAG)); + FileEditorManagerImpl.openFileImpl3(window, entry.myFile, false, entry); + if (getManager().isFileOpen(entry.myFile)) { + window.setFilePinned(entry.myFile, Boolean.valueOf(file.getAttributeValue("pinned")).booleanValue()); + if (Boolean.valueOf(file.getAttributeValue("current-in-tab")).booleanValue()) { + currentFile = entry.myFile; + } + if (Boolean.valueOf(file.getAttributeValue("current")).booleanValue()) { + setCurrentWindow (window, false); + } + } + } + if (currentFile != null) { + final EditorComposite editor = window.findFileComposite(currentFile); + if (editor != null) { + window.setSelectedEditor(editor); + } + } + } + catch (InvalidDataException e) { + } + finally { + window.myInsideTabChange--; + } + return window.myPanel; + } + } + return null; + } + + public VirtualFile[] getOpenFiles() { + final ArrayListSet files = new ArrayListSet(); + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWithProviderComposite[] editors = iter.next().getEditors(); + for (int i = 0; i < editors.length; i++) { + final EditorWithProviderComposite editor = editors[i]; + files.add(editor.getFile()); + } + } + return files.toArray(new VirtualFile[files.size()]); + } + + public VirtualFile[] getSelectedFiles() { + final ArrayListSet files = new ArrayListSet(); + for (Iterator iterator = myWindows.iterator(); iterator.hasNext();) { + final EditorWindow window = iterator.next(); + final VirtualFile file = window.getSelectedFile(); + if (file != null) { + files.add(file); + } + } + final VirtualFile[] virtualFiles = files.toArray(new VirtualFile[files.size()]); + final VirtualFile currentFile = getCurrentFile(); + if (currentFile != null) { + for (int i = 0; i != virtualFiles.length; ++i) { + if (virtualFiles[i] == currentFile) { + virtualFiles[i] = virtualFiles[0]; + virtualFiles[0] = currentFile; + break; + } + } + } + return virtualFiles; + } + + public FileEditor[] getSelectedEditors() { + final List editors = new ArrayList(); + final EditorWindow currentWindow = getCurrentWindow(); + if (currentWindow != null) { + final EditorWithProviderComposite composite = currentWindow.getSelectedEditor(); + if (composite != null) { + editors.add (composite.getSelectedEditor()); + } + } + + for (Iterator iterator = myWindows.iterator(); iterator.hasNext();) { + final EditorWindow window = iterator.next(); + if (!window.equals (currentWindow)) { + final EditorWithProviderComposite composite = window.getSelectedEditor(); + if (composite != null) { + editors.add(composite.getSelectedEditor()); + } + } + } + return editors.toArray(new FileEditor[editors.size()]); + } + + protected void updateFileIcon(final VirtualFile file, final boolean b) { + LOG.assertTrue(file != null); + final EditorWindow[] windows = findWindows(file); + if (windows != null) { + for (int i = 0; i < windows.length; i++) { + windows[i].updateFileIcon(file); + } + } + } + + public void updateFileColor(final VirtualFile file) { + LOG.assertTrue(file != null); + final EditorWindow[] windows = findWindows(file); + if (windows != null) { + for (int i = 0; i < windows.length; i++) { + final EditorWindow window = windows[i]; + final int index = window.findEditorIndex(window.findFileComposite(file)); + LOG.assertTrue(index != -1); + window.setForegroundAt(index, getManager().getFileColor(file)); + } + } + } + + public void trimToSize(final int editor_tab_limit, final VirtualFile fileToIgnore) { + for (Iterator iterator = myWindows.iterator(); iterator.hasNext();) { + final EditorWindow window = iterator.next(); + window.trimToSize(editor_tab_limit, fileToIgnore); + } + } + + public void setTabsPlacement(final int tabPlacement) { + final EditorWindow[] windows = getWindows(); + for (int i = 0; i != windows.length; ++ i) { + windows[i].setTabsPlacement(tabPlacement); + } + } + + public void setTabLayoutPolicy(int scrollTabLayout) { + final EditorWindow[] windows = getWindows(); + for (int i = 0; i != windows.length; ++ i) { + windows[i].setTabLayoutPolicy(scrollTabLayout); + } + } + + public void updateFileName(final VirtualFile file) { + final EditorWindow[] windows = getWindows(); + for (int i = 0; i != windows.length; ++ i) { + windows [i].updateFileName(file); + } + } + + private final class MyFocusTraversalPolicy extends IdeFocusTraversalPolicy { + public final Component getDefaultComponentImpl(final Container focusCycleRoot) { + if (myCurrentWindow != null) { + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCurrentWindow.getSelectedEditor().getComponent(), this); + } + else { + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(EditorsSplitters.this, this); + } + } + } + + public EditorWindow getCurrentWindow() { + return myCurrentWindow; + } + + public EditorWindow getOrCreateCurrentWindow() { + if (getCurrentWindow() == null) { + final Iterator iterator = myWindows.iterator(); + if (iterator.hasNext()) { + setCurrentWindow(iterator.next(), false); + } + else { + createCurrentWindow(); + } + } + return getCurrentWindow(); + } + + public EditorWindow createCurrentWindow() { + LOG.assertTrue(myCurrentWindow == null); + myCurrentWindow = new EditorWindow(this); + add(myCurrentWindow.myPanel, BorderLayout.CENTER); + return myCurrentWindow; + } + + public void setCurrentWindow(final EditorWindow window, final boolean requestFocus) { + myCurrentWindow = window; + if (window != null) { + final EditorWithProviderComposite selectedEditor = myCurrentWindow.getSelectedEditor(); + if (selectedEditor != null) { + final boolean focusEditor = ToolWindowManager.getInstance(myManager.myProject).isEditorComponentActive(); + if (focusEditor || requestFocus) + selectedEditor.getComponent().requestFocus (); + } + } + } + + //--------------------------------------------------------- + + public EditorWindow findWindow(final EditorComposite editor) { + for (Iterator elem = myWindows.iterator(); elem.hasNext();) { + final EditorWindow window = elem.next(); + if (window.findEditorIndex(editor) != -1) { + return window; + } + } + return null; + } + + public EditorWindow findWindow(final Component editorComponent) { + for (Iterator elem = myWindows.iterator(); elem.hasNext();) { + final EditorWindow window = elem.next(); + for (Component component = editorComponent; component != null; component = component.getParent()) { + if (window.findComponentIndex(component) != -1) { + return window; + } + } + } + return null; + } + + public EditorWithProviderComposite[] getEditorsComposites() { + final ArrayList res = new ArrayList(); + + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWithProviderComposite[] editors = iter.next().getEditors(); + for (int i = 0; i < editors.length; i++) { + final EditorWithProviderComposite editor = editors[i]; + res.add(editor); + } + } + return res.toArray(new EditorWithProviderComposite[res.size()]); + } + + //--------------------------------------------------------- + + protected final ArrayListSet myWindows = new ArrayListSet(); + + public EditorWithProviderComposite[] findEditorComposites(final VirtualFile file) { + final ArrayList res = new ArrayList(); + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWindow window = iter.next(); + final EditorWithProviderComposite fileComposite = window.findFileComposite(file); + if (fileComposite != null) { + res.add(fileComposite); + } + } + return (res.size() == 0 ? null : res.toArray(new EditorWithProviderComposite[res.size()])); + } + + public EditorWindow[] findWindows(final VirtualFile file) { + final ArrayList res = new ArrayList(); + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWindow window = iter.next(); + if (window.findFileComposite(file) != null) { + res.add(window); + } + } + return (res.size() == 0 ? null : res.toArray(new EditorWindow[res.size()])); + } + + public EditorWindow[] findWindowsWithCurrent(final VirtualFile file) { + final ArrayList res = new ArrayList(); + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWindow window = iter.next(); + if (window.getSelectedFile() == file) { + res.add(window); + } + } + return (res.size() == 0 ? null : res.toArray(new EditorWindow[res.size()])); + } + + public EditorWindow [] getWindows() { + return myWindows.toArray(new EditorWindow [myWindows.size()]); + } + + public EditorWindow[] getOrderedWindows() { + final ArrayList res = new ArrayList(); + + // Collector for windows in tree ordering: + class Inner{ + final void collect(final JPanel panel){ + final Component comp = panel.getComponent(0); + if (comp instanceof Splitter) { + final Splitter splitter = (Splitter)comp; + collect((JPanel)splitter.getFirstComponent()); + collect((JPanel)splitter.getSecondComponent()); + } + else if (comp instanceof JPanel) { + final EditorWindow window = findWindowWith(comp); + if (window != null) { + res.add(window); + } + } + } + }; + + // get root component and traverse splitters tree: + { + if (getComponentCount() != 0) { + final Component comp = getComponent(0); + LOG.assertTrue(comp instanceof JPanel); + final JPanel panel = (JPanel)comp; + if (panel.getComponentCount() != 0) { + new Inner().collect (panel); + } + } + } + + LOG.assertTrue(res.size() == myWindows.size()); + return res.toArray(new EditorWindow [res.size()]); + } + + public EditorWindow findWindowWith(final Component component) { + if (component != null) { + for (final Iterator iter = myWindows.iterator(); iter.hasNext();) { + final EditorWindow window = iter.next(); + if (SwingUtilities.isDescendingFrom(component, window.myPanel)) { + return window; + } + } + } + return null; + } + + private final class MyFocusWatcher extends FocusWatcher { + protected void focusedComponentChanged(final Component component) { + if (myInsideChange > 0 || component == null) { + return; + } + final EditorWindow oldActiveWindow = getCurrentWindow(); + final EditorWindow newActiveWindow = findWindowWith(component); + if (oldActiveWindow != newActiveWindow) { + setCurrentWindow(newActiveWindow, false); + getManager().updateFileName(newActiveWindow.getSelectedFile()); + getManager().fireSelectionChanged((oldActiveWindow == null ? null : oldActiveWindow.getSelectedEditor()), newActiveWindow.getSelectedEditor()); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java new file mode 100644 index 00000000000..ac6c88cdf9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -0,0 +1,572 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.DocumentContent; +import com.intellij.openapi.diff.SimpleContent; +import com.intellij.openapi.diff.SimpleDiffRequest; +import com.intellij.openapi.diff.ex.DiffPanelOptions; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.EditReadOnlyListener; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileDocumentManagerListener; +import com.intellij.openapi.fileEditor.VetoDocumentReloadException; +import com.intellij.openapi.fileEditor.VetoDocumentSavingException; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.PsiExternalChangeAction; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.PsiManagerConfiguration; +import com.intellij.psi.impl.compiled.ClsFileImpl; +import com.intellij.util.EventDispatcher; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.text.CharArrayCharSequence; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.io.Writer; +import java.lang.ref.WeakReference; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class FileDocumentManagerImpl extends FileDocumentManager implements ApplicationComponent, VirtualFileListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl"); + + private static final Key DETECTED_LINE_SEPARATOR_KEY = Key.create("DETECTED_LINE_SEPARATOR_KEY"); + private static final Key LINE_SEPARATOR_KEY = Key.create("LINE_SEPARATOR_KEY"); + private static final Key> DOCUMENT_KEY = Key.create("DOCUMENT_KEY"); + private static final Key FILE_KEY = Key.create("FILE_KEY"); + + private Set myUnsavedDocuments = new HashSet(); + private EditReadOnlyListener myReadOnlyListener = new MyEditReadOnlyListener(); + + private ProjectEx myDummyProject = null; + private boolean myDummyProjectInitialized = false; + private Object myDummyProjectInitializationLock = new Object(); + + private EventDispatcher myEventDispatcher = EventDispatcher.create(FileDocumentManagerListener.class); + private final PsiManagerConfiguration myPsiManagerConfiguration; + private final ProjectManagerEx myProjectManagerEx; + private VirtualFileManager myVirtualFileManager; + + + public FileDocumentManagerImpl(VirtualFileManager virtualFileManager, + PsiManagerConfiguration psiManagerConfiguration, + ProjectManagerEx projectManagerEx) { + myPsiManagerConfiguration = psiManagerConfiguration; + myProjectManagerEx = projectManagerEx; + myVirtualFileManager = virtualFileManager; + + myVirtualFileManager.addVirtualFileListener(this); + this.addFileDocumentManagerListener(new TrailingSpacesStripper()); + } + + public String getComponentName() { + return "FileDocumentManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + if (myDummyProject != null) { + myDummyProject.dispose(); + } + } + + public Document getDocument(VirtualFile file) { + DocumentEx document = (DocumentEx)getCachedDocument(file); + if (document == null){ + final CharSequence text = loadText(file); + if (text == null) return null; + document = (DocumentEx)createDocument(text); + document.setModificationStamp(file.getModificationStamp()); + final FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + document.setReadOnly(!file.isWritable() || fileType.isBinary()); + file.putUserData(DOCUMENT_KEY, new WeakReference(document)); + document.putUserData(FILE_KEY, file); + document.addDocumentListener( + new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + final Document document = e.getDocument(); + myUnsavedDocuments.add(document); + final Runnable currentCommand = CommandProcessor.getInstance().getCurrentCommand(); + Project project = currentCommand != null ? CommandProcessor.getInstance().getCurrentCommandProject() : null; + String lineSeparator = CodeStyleSettingsManager.getSettings(project).getLineSeparator(); + document.putUserData(LINE_SEPARATOR_KEY, lineSeparator); + } + } + ); + document.addEditReadOnlyListener(myReadOnlyListener); + + try { + fireFileContentLoaded(file, document); + } + catch (Exception e) { + LOG.error(e); + } + } + + return document; + } + + private static Document createDocument(final CharSequence text) { + return EditorFactory.getInstance().createDocument(text); + } + + private CharSequence loadText(VirtualFile file) { + if (file.isDirectory()) return null; + final FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + + if (fileType.equals(StdFileTypes.CLASS)){ + return new CharArrayCharSequence(decompile(file)); + } + + if (fileType.isBinary()) return null; + + final String[] detectedLineSeparator = new String[1]; + final CharSequence result = LoadTextUtil.loadText(file, detectedLineSeparator); + file.putUserData(DETECTED_LINE_SEPARATOR_KEY, detectedLineSeparator[0]); + return result; + } + + private char[] decompile(VirtualFile file) { + try{ + final ProjectEx dummyProject = getDummyProject(); + PsiManager manager = PsiManager.getInstance(dummyProject); + final String text = ClsFileImpl.decompile(manager, file); + + PsiFile mirror = manager.getElementFactory().createFileFromText("test.java", text); + + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(dummyProject); // do not use project's code style! + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(dummyProject); + boolean saved = settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE; + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; + codeStyleManager.shortenClassReferences(mirror); + codeStyleManager.reformat(mirror); + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = saved; + + return mirror.textToCharArray(); + } + catch(IncorrectOperationException e){ + LOG.error(e); + return null; + } + } + + public Document getCachedDocument(VirtualFile file) { + WeakReference reference = file.getUserData(DOCUMENT_KEY); + Document document = reference != null ? (Document)reference.get() : null; + + if (document != null && isFileBecameBinary(file)){ + file.putUserData(DOCUMENT_KEY, null); + document.putUserData(FILE_KEY, null); + return null; + } + + return document; + } + + private boolean isFileBecameBinary(VirtualFile file) { + final FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + return fileType.isBinary() && !fileType.equals(StdFileTypes.CLASS); + } + + public VirtualFile getFile(Document document) { + return document.getUserData(FILE_KEY); + } + + public void dropAllUnsavedDocuments() { + if (!ApplicationManager.getApplication().isUnitTestMode()){ + throw new RuntimeException("This method is only for test mode!"); + } + ApplicationManager.getApplication().assertWriteAccessAllowed(); + myUnsavedDocuments.clear(); + } + + public void saveAllDocuments() { + if (myUnsavedDocuments.isEmpty()) return; + + HashSet failedToSave = new HashSet(); + while(true){ + final Document[] unsavedDocuments = getUnsavedDocuments(); + + int count = 0; + for(int i = 0; i < unsavedDocuments.length; i++){ + Document document = unsavedDocuments[i]; + if (failedToSave.contains(document)) continue; + saveDocument(document); + count++; + if (myUnsavedDocuments.contains(document)){ + failedToSave.add(document); + } + } + + if (count == 0) break; + } + } + + public void saveDocument(final Document document) { + if (!myUnsavedDocuments.contains(document)) return; + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + _saveDocument(document); + } + } + ); + } + + private void _saveDocument(final Document document) { + boolean commited = false; + try{ + Writer writer = null; + VirtualFile file = getFile(document); + + if (file == null || !file.isValid()){ + myUnsavedDocuments.remove(document); + LOG.assertTrue(!myUnsavedDocuments.contains(document)); + return; + } + + if (file.getModificationStamp() == document.getModificationStamp()){ + myUnsavedDocuments.remove(document); + LOG.assertTrue(!myUnsavedDocuments.contains(document)); + return; + } + + if (file.getTimeStamp() != file.getActualTimeStamp()){ + file.refresh(false, false); + if (!myUnsavedDocuments.contains(document)) return; + if (!file.isValid()) return; + } + + try { + myEventDispatcher.getMulticaster().beforeDocumentSaving(document); + } + catch (VetoDocumentSavingException e) { + return; + } + + LOG.assertTrue(file.isValid()); + + try{ + String text = document.getText(); + String lineSeparator = getLineSeparator(document, file); + if (!lineSeparator.equals("\n")){ + text = StringUtil.convertLineSeparators(text, lineSeparator); + } + writer = file.getWriter(this, document.getModificationStamp(), -1); + writer.write(text); + commited = true; + } + finally{ + if (writer != null){ + writer.close(); + } + } + } + catch(IOException e){ + reportErrorOnSave(e); + commited = false; + } + finally{ + if (commited){ + myUnsavedDocuments.remove(document); + LOG.assertTrue(!myUnsavedDocuments.contains(document)); + } + + } + } + + public static String getLineSeparator(Document document, VirtualFile file) { + String lineSeparator = file.getUserData(DETECTED_LINE_SEPARATOR_KEY); + if (lineSeparator == null){ + lineSeparator = document.getUserData(LINE_SEPARATOR_KEY); + } + return lineSeparator; + } + + public String getLineSeparator(VirtualFile file, Project project) { + String lineSeparator = file.getUserData(DETECTED_LINE_SEPARATOR_KEY); + if (lineSeparator == null) { + CodeStyleSettingsManager settingsManager = project == null + ? CodeStyleSettingsManager.getInstance() + : CodeStyleSettingsManager.getInstance(project); + return settingsManager.getCurrentSettings().getLineSeparator(); + } + else { + return lineSeparator; + } + } + + + public Document[] getUnsavedDocuments() { + return myUnsavedDocuments.toArray(new Document[myUnsavedDocuments.size()]); + } + + public boolean isDocumentUnsaved(Document document) { + return myUnsavedDocuments.contains(document); + } + + public void addFileDocumentManagerListener(FileDocumentManagerListener listener) { + myEventDispatcher.addListener(listener); + } + + public void removeFileDocumentManagerListener(FileDocumentManagerListener listener) { + myEventDispatcher.removeListener(listener); + } + + public void dispatchPendingEvents(FileDocumentManagerListener listener) { + if (!myEventDispatcher.isDispatching()) { + myVirtualFileManager.dispatchPendingEvent(this); + } + myEventDispatcher.dispatchPendingEvent(listener); + } + + public void propertyChanged(final VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_WRITABLE.equals(event.getPropertyName())){ + final VirtualFile file = event.getFile(); + final Document document = getCachedDocument(file); + if (document == null) return; + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + document.setReadOnly(!event.getFile().isWritable()); + } + } + ); + //myUnsavedDocuments.remove(document); //? + } + } + + public void contentsChanged(VirtualFileEvent event) { + if (event.getRequestor() == this) return; + final VirtualFile file = event.getFile(); + final Document document = getCachedDocument(file); + if (document == null) { + myEventDispatcher.getMulticaster().fileWithNoDocumentChanged(file); + return; + } + + long documentStamp = document.getModificationStamp(); + long oldFileStamp = event.getOldModificationStamp(); + if (documentStamp != oldFileStamp){ + LOG.info("reaload from disk?"); + LOG.info(" documentStamp:" + documentStamp); + LOG.info(" oldFileStamp:" + oldFileStamp); + + Runnable askReloadRunnable = new Runnable() { + public void run() { + if (!file.isValid()) return; + if (askReloadFromDisk(file, document)){ + reloadFromDisk(document); + } + } + }; + // now can show dialogs in write actions... + //if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()){ + // LaterInvocatorEx.invokeLater(askReloadRunnable); + //} + //else{ + askReloadRunnable.run(); + //} + } + else{ + reloadFromDisk(document); + } + } + + public void reloadFromDisk(final Document document) { + final VirtualFile file = getFile(document); + try { + fireBeforeFileContentReload(file, document); + } + catch (VetoDocumentReloadException e) { + return; + } + catch (Exception e) { + LOG.error(e); + } + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + boolean wasWritable = document.isWritable(); + DocumentEx documentEx = (DocumentEx)document; + documentEx.setReadOnly(false); + documentEx.replaceText(loadText(file), file.getModificationStamp()); + documentEx.setReadOnly(!wasWritable); + } + } + ); + myUnsavedDocuments.remove(document); + + try { + fireFileContentReloaded(file, document); + } + catch (Exception e) { + LOG.error(e); + } + } + +// Made protected for Fabrique + protected boolean askReloadFromDisk(final VirtualFile file, final Document document) { + String message = "Changes have been made to \"" + file.getPresentableUrl() + "\"\nin memory and on disk."; + if (ApplicationManager.getApplication().isUnitTestMode()) throw new RuntimeException(message); + final DialogBuilder builder = new DialogBuilder((Project)null); + builder.setCenterPanel(new JLabel(message, Messages.getQuestionIcon(), SwingUtilities.TRAILING)); + builder.addOkAction().setText("&Load FS Changes"); + builder.addCancelAction().setText("&Keep Memory Changes"); + builder.addAction(new AbstractAction("&Show difference"){ + public void actionPerformed(ActionEvent e) { + String windowtitle = "File Cache Conflict " + file.getPresentableUrl(); + SimpleDiffRequest request = new SimpleDiffRequest(getDummyProject(), windowtitle); + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + String fsContent = loadText(file).toString(); + request.setContents(new SimpleContent(fsContent, fileType), + new DocumentContent(myDummyProject, document, fileType)); + request.setContentTitles("File system content", "Memory content"); + DialogBuilder diffBuidler = new DialogBuilder(getDummyProject()); + DiffPanelImpl diffPanel = (DiffPanelImpl)DiffManager.getInstance().createDiffPanel(diffBuidler.getWindow(), getDummyProject()); + diffPanel.getOptions().setShowSourcePolicy(DiffPanelOptions.ShowSourcePolicy.DONT_SHOW); + diffBuidler.setCenterPanel(diffPanel.getComponent()); + diffPanel.setDiffRequest(request); + diffBuidler.addOkAction().setText("Save changes"); + diffBuidler.addCancelAction(); + diffBuidler.setTitle(windowtitle); + if (diffBuidler.show() == DialogWrapper.OK_EXIT_CODE) + builder.getDialogWrapper().close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + //int option = Messages.showYesNoDialog(message, "File Cache Conflict", Messages.getQuestionIcon()); + builder.setTitle("File Cache Conflict"); + builder.setButtonsAlignment(SwingUtilities.CENTER); + return builder.show() == 0; + //return option == 0; + } + + protected void reportErrorOnSave(final IOException e) { + // invokeLater here prevents attempt to show dialog in write action + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog( + "Cannot save file:\n" + e.getMessage(), + "Cannot Save File", + Messages.getErrorIcon() + ); + } + }); + } + + public void fileCreated(VirtualFileEvent event) { + } + + public void fileDeleted(VirtualFileEvent event) { + //todo clear document/file correspondence? + } + + public void fileMoved(VirtualFileMoveEvent event) { + } + + public void beforePropertyChange(VirtualFilePropertyEvent event) { + } + + public void beforeContentsChange(VirtualFileEvent event) { + } + + public void beforeFileDeletion(VirtualFileEvent event) { + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + } + + public ProjectEx getDummyProject() { + synchronized (myDummyProjectInitializationLock) { + if (!myDummyProjectInitialized) { + myDummyProjectInitialized = true; + + if (myPsiManagerConfiguration.CREATE_DUMMY_PROJECT_FOR_OBFUSCATION) { + myDummyProject = (ProjectEx)myProjectManagerEx.newProject("", false, true); + ((StartupManagerImpl)StartupManager.getInstance(myDummyProject)).runStartupActivities(); + } + } + } + return myDummyProject; + } + + private final class MyEditReadOnlyListener implements EditReadOnlyListener { + public void readOnlyModificationAttempt(Document document) { + VirtualFile file = getFile(document); + if (file == null) return; + myVirtualFileManager.fireReadOnlyModificationAttempt(new VirtualFile[]{file}); + } + } + + private void fireFileContentReloaded(final VirtualFile file, final Document document) { + List listeners = myEventDispatcher.getListeners(); + for (int i = 0; i < listeners.size(); i++) { + FileDocumentManagerListener listener = listeners.get(i); + try { + listener.fileContentReloaded(file, document); + } + catch (AbstractMethodError e) { + // Do nothing. Some listener just does not implement this method yet. + } + } + } + + private void fireBeforeFileContentReload(final VirtualFile file, final Document document) throws VetoDocumentReloadException { + List listeners = myEventDispatcher.getListeners(); + for (int i = 0; i < listeners.size(); i++) { + FileDocumentManagerListener listener = listeners.get(i); + try { + listener.beforeFileContentReload(file, document); + } + catch (AbstractMethodError e) { + // Do nothing. Some listener just does not implement this method yet. + } + } + } + + private void fireFileContentLoaded(VirtualFile file, DocumentEx document) { + List listeners = myEventDispatcher.getListeners(); + for (int i = 0; i < listeners.size(); i++) { + FileDocumentManagerListener listener = listeners.get(i); + try { + listener.fileContentLoaded(file, document); + } + catch (AbstractMethodError e) { + // Do nothing. Some listener just does not implement this method yet. + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java new file mode 100644 index 00000000000..99831037548 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -0,0 +1,1208 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiTreeChangeAdapter; +import com.intellij.psi.PsiTreeChangeEvent; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public final class FileEditorManagerImpl extends FileEditorManagerEx implements ProjectComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl"); + + private static final FileEditor[] EMPTY_EDITOR_ARRAY = new FileEditor[]{}; + private static final FileEditorProvider[] EMPTY_PROVIDER_ARRAY = new FileEditorProvider[]{}; + + static final Icon LOCKED_ICON = IconLoader.getIcon("/nodes/locked.png"); + static final Icon MODIFIED_ICON = IconLoader.getIcon("/general/modified.png"); + + static final Icon GAP_ICON = EmptyIcon.create(MODIFIED_ICON.getIconWidth(), + MODIFIED_ICON.getIconHeight()); + private final JPanel myPanels; + public Project myProject; + + private final EventListenerList myListenerList; + + /** + * Updates tabs colors + */ + private final MyFileStatusListener myFileStatusListener; + /** + * Updates tabs icons + */ + private final MyFileTypeListener myFileTypeListener; + /** + * Removes invalid myEditor and updates "modified" status. + */ + protected final MyEditorPropertyChangeListener myEditorPropertyChangeListener; + /** + * Updates tabs names + */ + private final MyVirtualFileListener myVirtualFileListener; + /** + * Extends/cuts number of opened tabs. Also updates location of tabs. + */ + private final MyUISettingsListener myUISettingsListener; + + /** + * Push forward events from composite + */ + protected final MyEditorManagerListener myEditorManagerListener; + /** + * Updates icons for open files when project roots change + */ + private final MyPsiTreeChangeListener myPsiTreeChangeListener; + final private EditorsSplitters mySplitters; + + + FileEditorManagerImpl(final Project project) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myListenerList = new EventListenerList(); + myProject = project; + myPanels = new JPanel(new BorderLayout()); + mySplitters = new EditorsSplitters(this); + myPanels.add(mySplitters, BorderLayout.CENTER); + + myFileStatusListener = new MyFileStatusListener(); + myFileTypeListener = new MyFileTypeListener(); + myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); + myVirtualFileListener = new MyVirtualFileListener(); + myUISettingsListener = new MyUISettingsListener(); + myEditorManagerListener = new MyEditorManagerListener(); + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + } + + //------------------------------------------------------------------------------- + + public JComponent getComponent() { + return myPanels; + } + + public JComponent getPreferredFocusedComponent() { + assertThread(); + final EditorWindow window = getSplitters().getCurrentWindow(); + if (window != null) { + final EditorWithProviderComposite editor = window.getSelectedEditor(); + if (editor != null) { + return editor.getPreferredFocusedComponent(); + } + } + return null; + } + + //------------------------------------------------------- + + /** + * @return color of the file which corresponds to the + * file's status + */ + protected Color getFileColor(final VirtualFile file) { + LOG.assertTrue(file != null); + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + return fileStatusManager.getStatus(file).getColor(); + } + return Color.BLACK; + } + + + /** + * Updates tab color for the specified file. The file + * should be opened in the myEditor, otherwise the method throws an assertion. + */ + protected void updateFileColor(final VirtualFile file) { + getSplitters ().updateFileColor(file); + } + + + /** + * Updates tab icon for the specified file. The file + * should be opened in the myEditor, otherwise the method throws an assertion. + */ + private void updateFileIcon(final VirtualFile file, boolean useAlarm) { + getSplitters ().updateFileIcon(file, useAlarm); + } + + /** + * Updates tab title and tab tool tip for the specified file + */ + protected void updateFileName(final VirtualFile file) { + final WindowManagerEx windowManagerEx = WindowManagerEx.getInstanceEx(); + final IdeFrame frame = windowManagerEx.getFrame(myProject); + LOG.assertTrue(frame != null); + mySplitters.updateFileName (file); + frame.setFileTitle(file); + } + + //------------------------------------------------------- + + + public VirtualFile getFile(final FileEditor editor) { + final EditorComposite editorComposite = getEditorComposite(editor); + if (editorComposite != null) { + return editorComposite.getFile(); + } + return null; + } + + public boolean hasSplitters() { + return true; //false; //To change body of implemented methods use File | Settings | File Templates. + } + + public void unsplitWindow() { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.unsplit(); + } + } + + public void unsplitAllWindow() { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.unsplitAll(); + } + } + + public EditorWindow [] getWindows() { + return mySplitters.getWindows(); + } + + public EditorWindow getNextWindow(final EditorWindow window) { + final EditorWindow[] windows = getSplitters().getOrderedWindows(); + for (int i = 0; i != windows.length; ++ i) + if (windows[i].equals (window)) + return windows [(i+1)%windows.length]; + LOG.error("Not window found"); + return null; + } + + public EditorWindow getPrevWindow(final EditorWindow window) { + final EditorWindow[] windows = getSplitters().getOrderedWindows(); + for (int i = 0; i != windows.length; ++ i) + if (windows[i].equals (window)) + return windows [(i+windows.length-1)%windows.length]; + LOG.error("Not window found"); + return null; + } + + public void moveFocusToNextEditor() { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void createSplitter(final int orientation) { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.split(orientation); + } + } + + public void changeSplitterOrientation() { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.changeOrientation(); + } + } + + + public void revalidate() { + myPanels.repaint(); + } + + public void flipTabs() { + /* + if (myTabs == null) { + myTabs = new EditorTabs (this, UISettings.getInstance().EDITOR_TAB_PLACEMENT); + remove (mySplitters); + add (myTabs, BorderLayout.CENTER); + initTabs (); + } else { + remove (myTabs); + add (mySplitters, BorderLayout.CENTER); + myTabs.dispose (); + myTabs = null; + } + */ + myPanels.revalidate(); + } + + public boolean tabsMode() { + return false; + } + + public void setTabsMode(final boolean mode) { + if (tabsMode() != mode) { + flipTabs(); + } + //LOG.assertTrue (tabsMode () == mode); + } + + + public boolean isInSplitter() { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + if (currentWindow != null) { + return currentWindow.inSplitter(); + } + return false; + } + + public boolean hasOpenedFile() { + final EditorWindow currentWindow = getSplitters ().getCurrentWindow(); + return currentWindow != null && currentWindow.getSelectedEditor() != null; + } + + public VirtualFile getCurrentFile() { + return getSplitters().getCurrentFile(); + } + + public EditorWindow getCurrentWindow() { + return getSplitters().getCurrentWindow(); + } + + public void setCurrentWindow(final EditorWindow window) { + getSplitters().setCurrentWindow(window, true); + } + + //============================= EditorManager methods ================================ + public void closeFile(final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + assertThread(); + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + closeFileImpl(file); + } + }, + "", + null); + } + + + private VirtualFile findNextFile(final VirtualFile file) { + final EditorWindow [] windows = getWindows(); // TODO: use current file as base + for (int i = 0; i != windows.length; ++ i) { + final VirtualFile[] files = windows [i].getFiles(); + for (int j = 0; j < files.length; j++) { + final VirtualFile fileAt = files[j]; + if (fileAt != file) { + return fileAt; + } + } + } + return null; + } + + public void closeFileImpl(final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + FileEditorManagerImpl.assertThread(); + ++getSplitters().myInsideChange; + try { + final EditorWindow[] windows = getSplitters().findWindows(file); + if (windows != null) { + final VirtualFile nextFile = findNextFile(file); + //if (nextFile == null) { + // getSplitters().clear(); + //} + for (int i = 0; i < windows.length; i++) { + final EditorWindow window = windows[i]; + LOG.assertTrue(window.getSelectedEditor() != null); + final EditorWithProviderComposite oldComposite = window.findFileComposite(file); + if (oldComposite != null) { + window.removeEditor(oldComposite); + } + if (nextFile != null) { + if (window.getTabCount() == 0) { + EditorWithProviderComposite newComposite = window.findFileComposite(nextFile); + if (newComposite == null) { + newComposite = newEditorComposite(nextFile, true, null); + } + window.setEditor(newComposite); // newComposite can be null + } + } + } + } + fireFileClosed(file); + } + finally { + --getSplitters().myInsideChange; + } + } + + private EditorsSplitters getSplitters() { + return mySplitters; + } + +//-------------------------------------- Open File ---------------------------------------- + + public Pair openFileWithProviders(final VirtualFile file, final boolean focusEditor) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + if (!file.isValid()) { + throw new IllegalArgumentException("file is not valid: " + file); + } + assertThread(); + + return openFileImpl(file, focusEditor, null); + } + + public Pair openFileImpl(final VirtualFile file, + final boolean focusEditor, + final HistoryEntry entry) { + return openFileImpl2(getSplitters().getOrCreateCurrentWindow(), file, focusEditor, entry); + } + + public Pair openFileImpl2(final EditorWindow window, + final VirtualFile file, + final boolean focusEditor, + final HistoryEntry entry) { + final Ref> resHolder = new Ref>(); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + resHolder.set(openFileImpl3(window, file, focusEditor, entry)); + } + }, + "", + null); + return resHolder.get(); + } + + /** + * @param file to be opened. Unlike openFile method, file can be + * invalid. For example, all file were invalidate and they are being + * removed one by one. If we have removed one invalid file, then another + * invalid file become selected. That's why we are not require that + * passed file is valid. + * @param entry map between FileEditorProvider and FileEditorState. If this parameter + * is not null then it's used to restore state for the newly created + */ + static protected Pair openFileImpl3(final EditorWindow window, + final VirtualFile file, + final boolean focusEditor, + final HistoryEntry entry) { + LOG.assertTrue(file != null); + + // Open file + window.myInsideTabChange++; + FileEditor[] editors; + FileEditorProvider[] providers; + try { + final EditorWithProviderComposite newSelectedComposite; + boolean newEditorCreated = false; + + final boolean open = window.isFileOpen(file); + if (open) { + LOG.assertTrue(window.findFileComposite(file) != null); + // File is already opened. In this case we have to just select existing EditorComposite + newSelectedComposite = window.findFileComposite(file); + LOG.assertTrue(newSelectedComposite != null); + + editors = newSelectedComposite.getEditors(); + providers = newSelectedComposite.getProviders(); + window.setEditor(newSelectedComposite); + } + else { + // File is not opened yet. In this case we have to create editors + // and select the created EditorComposite. + final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + providers = editorProviderManager.getProviders(window.getManager().myProject, file); + + if (providers.length == 0) { + return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); + } + newEditorCreated = true; + + editors = new FileEditor[providers.length]; + for (int i = 0; i < providers.length; i++) { + final FileEditorProvider provider = providers[i]; + LOG.assertTrue(provider != null); + LOG.assertTrue(provider.accept(window.getManager().myProject, file)); + final FileEditor editor = provider.createEditor(window.getManager().myProject, file); + editors[i] = editor; + LOG.assertTrue(editor != null); + LOG.assertTrue(editor.isValid()); + + // Register PropertyChangeListener into editor + editor.addPropertyChangeListener(window.getManager().myEditorPropertyChangeListener); + } + + // Now we have to create EditorComposite and insert it into the TabbedEditorComponent. + // After that we have to select opened editor. + newSelectedComposite = new EditorWithProviderComposite(file, editors, providers, window.getManager()); + newSelectedComposite.addEditorManagerListener(window.getManager().myEditorManagerListener); + window.setEditor(newSelectedComposite); + } + + final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(window.getManager().myProject); + for (int i = 0; i < editors.length; i++) { + final FileEditor editor = editors[i]; + if (editor instanceof TextEditor) { + // hack!!! + // This code prevents "jumping" on next repaint. + ((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); + } + + final FileEditorProvider provider = providers[i];//getProvider(editor); + + // Restore editor state + FileEditorState state = null; + if (entry != null) { + state = entry.getState(provider); + } + if (state == null && !open) { + // We have to try to get state from the history only in case + // if editor is not opened. Otherwise history enty might have a state + // no in sych with the current editor state. + state = editorHistoryManager.getState(file, provider); + } + if (state != null) { + editor.setState(state); + } + } + + // Restore selected editor + final FileEditorProvider selectedProvider = editorHistoryManager.getSelectedProvider(file); + if (selectedProvider != null) { + final FileEditor[] _editors = newSelectedComposite.getEditors(); + final FileEditorProvider[] _providers = newSelectedComposite.getProviders(); + for (int i = _editors.length - 1; i >= 0; i--) { + final FileEditorProvider provider = _providers[i];//getProvider(_editors[i]); + if (provider.equals(selectedProvider)) { + newSelectedComposite.setSelectedEditor(i); + break; + } + } + } + + // Notify editors about selection changes + + final EditorComposite oldSelectedComposite = window.getManager ().getLastSelected (); + if (oldSelectedComposite != null) { + oldSelectedComposite.getSelectedEditor().deselectNotify(); + } + window.getManager ().mySplitters.setCurrentWindow (window, false); + newSelectedComposite.getSelectedEditor().selectNotify(); + + if (newEditorCreated) { + window.getManager().fireFileOpened(file); + } + + // Notify listeners about selection changes + window.getManager().fireSelectionChanged(oldSelectedComposite, newSelectedComposite); + + // Transfer focus into editor + if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) { + if (focusEditor || ToolWindowManager.getInstance(window.getManager().myProject).isEditorComponentActive()) { + //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer); + window.setAsCurrentWindow(false); + ToolWindowManager.getInstance(window.getManager().myProject).activateEditorComponent(); + } + } + + // Update frame and tab title + window.getManager().updateFileName(file); + + // Make back/forward work + IdeDocumentHistory.getInstance(window.getManager().myProject).includeCurrentCommandAsNavigation(); + } + finally { + window.myInsideTabChange--; + } + + return Pair.create(editors, providers); + } + + private EditorWithProviderComposite newEditorComposite(final VirtualFile file, + final boolean focusEditor, + final HistoryEntry entry) { + if (file == null) return null; + + final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file); + final FileEditor[] editors = new FileEditor[providers.length]; + for (int i = 0; i < providers.length; i++) { + final FileEditorProvider provider = providers[i]; + LOG.assertTrue(provider != null); + LOG.assertTrue(provider.accept(myProject, file)); + final FileEditor editor = provider.createEditor(myProject, file); + editors[i] = editor; + LOG.assertTrue(editor != null); + LOG.assertTrue(editor.isValid()); + editor.addPropertyChangeListener(myEditorPropertyChangeListener); + } + + final EditorWithProviderComposite newComposite = new EditorWithProviderComposite(file, editors, providers, this); + final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject); + for (int i = 0; i < editors.length; i++) { + final FileEditor editor = editors[i]; + if (editor instanceof TextEditor) { + // hack!!! + // This code prevents "jumping" on next repaint. + //((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); + } + + final FileEditorProvider provider = providers[i]; + + // Restore myEditor state + FileEditorState state = null; + if (entry != null) { + state = entry.getState(provider); + } + if (state == null/* && !open*/) { + // We have to try to get state from the history only in case + // if myEditor is not opened. Otherwise history enty might have a state + // no in sych with the current myEditor state. + state = editorHistoryManager.getState(file, provider); + } + if (state != null) { + editor.setState(state); + } + } + return newComposite; + } + + public Editor openTextEditor(final OpenFileDescriptor descriptor, final boolean focusEditor) { + if (descriptor == null) { + throw new IllegalArgumentException("descriptor cannot be null"); + } + assertThread(); + + final Editor[] result = new Editor[1]; + CommandProcessor.getInstance().executeCommand(myProject, + new Runnable() { + public void run() { + final FileEditor[] editors = openFile(descriptor.getFile(), focusEditor); + for (int i = 0; i < editors.length; i++) { + final FileEditor editor = editors[i]; + if (!(editor instanceof TextEditor)) { + continue; + } + + final Editor _editor = ((TextEditor)editor).getEditor(); + result[0] = _editor; + + // Move myEditor caret to the specified location. + if (descriptor.getOffset() >= 0) { + _editor.getCaretModel().moveToOffset( + Math.min(descriptor.getOffset(), _editor.getDocument().getTextLength())); + _editor.getSelectionModel().removeSelection(); + _editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + else if (descriptor.getLine() != -1 && descriptor.getColumn() != -1) { + final LogicalPosition pos = new LogicalPosition(descriptor.getLine(), descriptor.getColumn()); + _editor.getCaretModel().moveToLogicalPosition(pos); + _editor.getSelectionModel().removeSelection(); + _editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + + break; + } + } + }, + "", + null); + + return result[0]; + } + + public Editor getSelectedTextEditor() { + assertThread(); + final VirtualFile[] selectedFiles = getSelectedFiles(); + if (selectedFiles.length == 0) { + return null; + } + + final FileEditor editor = getSelectedEditor(selectedFiles[0]); + if (editor instanceof TextEditor) { + return ((TextEditor)editor).getEditor(); + } + else { + return null; + } + } + + + public boolean isFileOpen(final VirtualFile file) { + return getEditors(file).length != 0; + } + + public VirtualFile[] getOpenFiles() { + return getSplitters ().getOpenFiles(); + } + + public VirtualFile[] getSelectedFiles() { + return getSplitters().getSelectedFiles(); + } + + public FileEditor[] getSelectedEditors() { + return getSplitters().getSelectedEditors(); + } + + public FileEditor getSelectedEditor(final VirtualFile file) { + return getSelectedEditorWithProvider(file).getFirst(); + } + + + public Pair getSelectedEditorWithProvider(final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + + final EditorWithProviderComposite[] composites = getEditorComposites(file); + if (composites != null) { + return composites[0].getSelectedEditorWithProvider(); + } + else { + return null; + } + } + + public Pair getEditorsWithProviders(final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + assertThread(); + + final EditorWithProviderComposite[] composites = getEditorComposites(file); + if (composites != null) { + return Pair.create(composites[0].getEditors(), composites[0].getProviders()); + } + else { + return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); + } + } + + public FileEditor[] getEditors(final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + assertThread(); + + final EditorComposite[] composites = getEditorComposites(file); + if (composites != null) { + return composites[0].getEditors(); + } + else { + return EMPTY_EDITOR_ARRAY; + } + } + + public EditorWithProviderComposite[] getEditorComposites(final VirtualFile file) { + return getSplitters().findEditorComposites(file); + } + + public FileEditor[] getAllEditors() { + assertThread(); + final ArrayList result = new ArrayList(); + final EditorWithProviderComposite[] editorsComposites = getSplitters().getEditorsComposites(); + for (int i = 0; i < editorsComposites.length; i++) { + final FileEditor[] editors = editorsComposites[i].getEditors(); + for (int j = 0; j < editors.length; j++) { + result.add(editors[j]); + } + } + return result.toArray(new FileEditor[result.size()]); + } + + public void addFileEditorManagerListener(final FileEditorManagerListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null"); + } + assertThread(); + myListenerList.add(FileEditorManagerListener.class, listener); + } + + public void removeFileEditorManagerListener(final FileEditorManagerListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null"); + } + assertThread(); + myListenerList.remove(FileEditorManagerListener.class, listener); + } + + // ProjectComponent methods + public void projectOpened() { + //myFocusWatcher.install(myWindows.getComponent ()); + + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + fileStatusManager.addFileStatusListener(myFileStatusListener); + } + FileTypeManager.getInstance().addFileTypeListener(myFileTypeListener); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + UISettings.getInstance().addUISettingsListener(myUISettingsListener); + PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); + + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, + new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + setTabsMode(UISettings.getInstance().EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); + getSplitters().openFiles(); + // group 1 + } + }, + "", + null); + } + }); + } + }); + + } + + public void projectClosed() { + //myFocusWatcher.deinstall(myWindows.getComponent ()); + // Remove application level listeners + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + fileStatusManager.removeFileStatusListener(myFileStatusListener); + } + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + UISettings.getInstance().removeUISettingsListener(myUISettingsListener); + + // Dispose created editors. We do not use use closeEditor method because + // it fires event and changes history. + closeAllFiles(); + } + + + // BaseCompomemnt methods + public String getComponentName() { + return "FileEditorManager"; + } + + public void initComponent() { /* really do nothing */ } + + public void disposeComponent() { /* really do nothing */ } + + //JDOMExternalizable methods + public void writeExternal(final Element element) { + getSplitters().writeExternal(element); + } + + public void readExternal(final Element element) { + getSplitters().readExternal(element); + } + + private EditorComposite getEditorComposite(final FileEditor editor) { + LOG.assertTrue(editor != null); + final EditorWithProviderComposite[] editorsComposites = getSplitters().getEditorsComposites(); + for (int i = editorsComposites.length - 1; i >= 0; i--) { + final EditorComposite composite = editorsComposites[i]; + final FileEditor[] editors = composite.getEditors(); + for (int j = editors.length - 1; j >= 0; j--) { + final FileEditor _editor = editors[j]; + LOG.assertTrue(_editor != null); + if (editor.equals(_editor)) { + return composite; + } + } + } + return null; + } + + + //======================= Misc ===================== + public static void assertThread() { + ApplicationManager.getApplication().assertIsDispatchThread(); + } + + //================== Firing events ===================== + private void fireFileOpened(final VirtualFile file) { + final FileEditorManagerListener[] listeners = (FileEditorManagerListener[])myListenerList.getListeners(FileEditorManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].fileOpened(this, file); + } + } + + public void fireFileClosed(final VirtualFile file) { + final FileEditorManagerListener[] listeners = (FileEditorManagerListener[])myListenerList.getListeners(FileEditorManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].fileClosed(this, file); + } + } + + public void fireSelectionChanged(final EditorComposite oldSelectedComposite, + final EditorComposite newSelectedComposite) { + final VirtualFile oldSelectedFile = oldSelectedComposite != null ? oldSelectedComposite.getFile() : null; + final FileEditor oldSelectedEditor = oldSelectedComposite != null ? oldSelectedComposite.getSelectedEditor() : null; + + final VirtualFile newSelectedFile = newSelectedComposite != null ? newSelectedComposite.getFile() : null; + final FileEditor newSelectedEditor = newSelectedComposite != null ? newSelectedComposite.getSelectedEditor() : null; + + final FileEditorManagerEvent event = new FileEditorManagerEvent(this, oldSelectedFile, oldSelectedEditor, newSelectedFile, newSelectedEditor); + final FileEditorManagerListener[] listeners = (FileEditorManagerListener[])myListenerList.getListeners(FileEditorManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].selectionChanged(event); + } + } + + private void fireSelectionChanged(final VirtualFile selectedFile, + final FileEditor oldSelectedEditor, + final FileEditor newSelectedEditor) { + LOG.assertTrue(selectedFile != null); + if (!Comparing.equal(oldSelectedEditor, newSelectedEditor)) { + final FileEditorManagerEvent event = new FileEditorManagerEvent(this, selectedFile, oldSelectedEditor, selectedFile, newSelectedEditor); + final FileEditorManagerListener[] listeners = (FileEditorManagerListener[])myListenerList.getListeners(FileEditorManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].selectionChanged(event); + } + } + } + + // true if only one editor per file allowed + public boolean isSingleFileMode() { + return false; + } + + public boolean isChanged (final EditorComposite editor) { + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + if (!fileStatusManager.getStatus(editor.getFile()).equals (FileStatus.NOT_CHANGED)) { + return true; + } + } + return false; + } + + public void disposeComposite(EditorWithProviderComposite editor) { + if(editor.equals(getLastSelected ())){ + editor.getSelectedEditor().deselectNotify(); + mySplitters.setCurrentWindow (null, false); + fireSelectionChanged(editor, null); // oldSelectedComposite -> null + } + + editor.removeEditorManagerListener(myEditorManagerListener); + + final FileEditor[] editors = editor.getEditors(); + final FileEditorProvider[] providers = editor.getProviders(); + + final FileEditor selectedEditor = editor.getSelectedEditor(); + for (int i = editors.length - 1; i >= 0; i--) { + final FileEditor editor1 = editors[i]; + final FileEditorProvider provider = providers[i]; + if (!editor.equals(selectedEditor)) { // we already notified the myEditor (when fire event) + if (selectedEditor.equals(editor1)) { + editor1.deselectNotify(); + } + } + editor1.removePropertyChangeListener(myEditorPropertyChangeListener); + provider.disposeEditor(editor1); + } + } + + protected EditorComposite getLastSelected() { + final EditorWindow currentWindow = mySplitters.getCurrentWindow (); + if (currentWindow != null) { + return currentWindow.getSelectedEditor(); + } + return null; + } + + //================== Listeners ===================== + /** + * Closes deleted files. Closes file which are in the deleted directories. + */ + private final class MyVirtualFileListener extends VirtualFileAdapter{ + public void beforeFileDeletion(VirtualFileEvent e){ + assertThread(); + final VirtualFile file = e.getFile(); + final VirtualFile[] openFiles = getOpenFiles(); + for(int i = openFiles.length - 1; i >= 0; i--){ + if(VfsUtil.isAncestor(file, openFiles[i], false)){ + closeFile(openFiles[i]); + } + } + } + + public void propertyChanged(VirtualFilePropertyEvent e){ + if(VirtualFile.PROP_NAME.equals(e.getPropertyName())){ + assertThread(); + final VirtualFile file = e.getFile(); + if(isFileOpen(file)){ + updateFileName(file); + updateFileIcon(file, false); // file type can change after renaming + } + } + else if(VirtualFile.PROP_WRITABLE.equals(e.getPropertyName())){ + assertThread(); + final VirtualFile file = e.getFile(); + if(isFileOpen(file)){ + updateFileIcon(file, false); + if(file.equals(getSelectedFiles()[0])){ // update "write" status + final StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); + LOG.assertTrue(statusBar != null); + statusBar.setWriteStatus(!file.isWritable()); + } + } + } + } + + public void fileMoved(VirtualFileMoveEvent e){ + final VirtualFile file = e.getFile(); + final VirtualFile[] selectedFiles = getSelectedFiles(); + for (int i = 0; i < selectedFiles.length; i++) { + final VirtualFile selectedFile = selectedFiles[i]; + if(VfsUtil.isAncestor(file, selectedFile, false)){ + updateFileName(selectedFile); + } + } + } + } + + /* + private final class MyVirtualFileListener extends VirtualFileAdapter { + public void beforeFileDeletion(final VirtualFileEvent e) { + assertThread(); + final VirtualFile file = e.getFile(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + if (VfsUtil.isAncestor(file, openFiles[i], false)) { + closeFile(openFiles[i]); + } + } + } + + public void propertyChanged(final VirtualFilePropertyEvent e) { + if (VirtualFile.PROP_WRITABLE.equals(e.getPropertyName())) { + assertThread(); + final VirtualFile file = e.getFile(); + if (isFileOpen(file)) { + if (file.equals(getSelectedFiles()[0])) { // update "write" status + final StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); + LOG.assertTrue(statusBar != null); + statusBar.setWriteStatus(!file.isWritable()); + } + } + } + } + + //public void fileMoved(final VirtualFileMoveEvent e){ } + } + */ + + private final class MyEditorManagerListener extends FileEditorManagerAdapter { + public void selectionChanged(final FileEditorManagerEvent event) { + final VirtualFile oldSelectedFile = event.getOldFile(); + final VirtualFile newSelectedFile = event.getNewFile(); + LOG.assertTrue(oldSelectedFile != null); + LOG.assertTrue(oldSelectedFile.equals(newSelectedFile)); + if (getSplitters().myInsideChange > 0) { // do not react on own events + return; + } + fireSelectionChanged(oldSelectedFile, event.getOldEditor(), event.getNewEditor()); + } + } + + private final class MyEditorPropertyChangeListener implements PropertyChangeListener { + public void propertyChange(final PropertyChangeEvent e) { + assertThread(); + + final String propertyName = e.getPropertyName(); + if (FileEditor.PROP_MODIFIED.equals(propertyName)) { + final FileEditor editor = (FileEditor)e.getSource(); + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + updateFileIcon(composite.getFile(), false); + } + } + else if (FileEditor.PROP_VALID.equals(propertyName)) { + final boolean valid = ((Boolean)e.getNewValue()).booleanValue(); + if (!valid) { + final FileEditor editor = (FileEditor)e.getSource(); + LOG.assertTrue(editor != null); + final EditorComposite composite = getEditorComposite(editor); + LOG.assertTrue(composite != null); + closeFile(composite.getFile()); + } + } + + } + } + + /** + * Gets events from VCS and updates color of myEditor tabs + */ + private final class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { // update color of all open files + assertThread(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + ApplicationManager.getApplication().invokeLater(new Runnable () { + public void run() { + updateFileStatus(file); + } + }, ModalityState.NON_MMODAL); + } + } + + public void fileStatusChanged(final VirtualFile file) { // update color of the file (if necessary) + assertThread(); + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + if (isFileOpen(file)) { + updateFileStatus(file); + } + } + + private void updateFileStatus(final VirtualFile file) { + updateFileColor(file); + updateFileIcon(file, false); + } + } + + /** + * Gets events from FileTypeManager and updates icons on tabs + */ + private final class MyFileTypeListener implements FileTypeListener { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(final FileTypeEvent event) { + assertThread(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + updateFileIcon(file, false); + } + } + } + + /** + * Gets notifications from UISetting component to track changes of RECENT_FILES_LIMIT + * and EDITOR_TAB_LIMIT, etc values. + */ + private final class MyUISettingsListener implements UISettingsListener { + public void uiSettingsChanged(final UISettings source) { + assertThread(); + setTabsMode(source.EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); + getSplitters().setTabsPlacement(source.EDITOR_TAB_PLACEMENT); + getSplitters().trimToSize(source.EDITOR_TAB_LIMIT, null); + + // Tab layout policy + if (source.SCROLL_TAB_LAYOUT_IN_EDITOR) { + getSplitters().setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + } else { + getSplitters().setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); + } + + // "Mark modified files with asterisk" + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + updateFileIcon(file, false); + updateFileName(file); + } + } + } + + /** + * Updates attribute of open files when roots change + */ + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void propertyChanged(final PsiTreeChangeEvent e) { + if (PsiTreeChangeEvent.PROP_ROOTS.equals(e.getPropertyName())) { + assertThread(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + updateFileIcon(file, false); + } + } + } + + public void childrenChanged(PsiTreeChangeEvent event) { + // use alarm to avoid constant icon update on typing + final VirtualFile currentFile = getCurrentFile(); + if (currentFile != null) { + ApplicationManager.getApplication().invokeLater(new Runnable () { + public void run() { + updateFileIcon(currentFile, true); + } + }, ModalityState.NON_MMODAL); + } + } + } + + + //=================== + + /** + * @return file at the specified index in the tabbed container. Never null. + */ + VirtualFile getFileAt(final EditorTabbedContainer tabbedContainer, final int tabIndex) { + //final JComponent componentAt = tabbedContainer.getComponentAt(tabIndex); + //OpenFile openFile = findOpenFile(componentAt); + //return openFile.myFile; + return null; + } + + public void closeAllFiles() { + final VirtualFile[] openFiles = getSplitters().getOpenFiles(); + for (int i = 0; i < openFiles.length; i++) { + closeFile(openFiles[i]); + } + //getSplitters().clear(); + } + + public VirtualFile[] getSiblings(VirtualFile file) { + return getOpenFiles(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java new file mode 100644 index 00000000000..95baa03f946 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java @@ -0,0 +1,124 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.fileEditor.FileEditorPolicy; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class FileEditorProviderManagerImpl extends FileEditorProviderManager implements ApplicationComponent{ + private static final FileEditorProvider[] EMPTY_ARRAY=new FileEditorProvider[]{}; + + private final ArrayList myProviders; + private final ArrayList mySharedProviderList; + + public FileEditorProviderManagerImpl(FileEditorProvider[] providers) { + myProviders = new ArrayList(); + mySharedProviderList = new ArrayList(); + + for (int i = 0; i < providers.length; i++) { + FileEditorProvider provider = providers[i]; + registerProvider(provider); + } + } + + public synchronized FileEditorProvider[] getProviders(Project project, VirtualFile file){ + if(file==null){ + throw new IllegalArgumentException("file cannot be null"); + } + + // Collect all possible editors + mySharedProviderList.clear(); + boolean doNotShowTextEditor = false; + for(int i = myProviders.size() -1 ; i >= 0; i--){ + FileEditorProvider provider=myProviders.get(i); + if(provider.accept(project, file)){ + mySharedProviderList.add(provider); + doNotShowTextEditor |= provider.getPolicy() == FileEditorPolicy.HIDE_DEFAULT_EDITOR; + } + } + + // Throw out default editors provider if necessary + if(doNotShowTextEditor){ + for(int i = mySharedProviderList.size() - 1; i >= 0; i--){ + if(mySharedProviderList.get(i) instanceof TextEditorProvider){ + mySharedProviderList.remove(i); + } + } + } + + // Sort editors according policies + Collections.sort(myProviders, MyComparator.ourInstance); + + if(mySharedProviderList.size()>0){ + return mySharedProviderList.toArray(new FileEditorProvider[mySharedProviderList.size()]); + } + else{ + return EMPTY_ARRAY; + } + } + + public synchronized FileEditorProvider getProvider(String editorTypeId){ + if (editorTypeId == null){ + throw new IllegalArgumentException("editorTypeId cannot be null"); + } + for(int i=myProviders.size()-1;i>=0;i--){ + FileEditorProvider provider=myProviders.get(i); + if(provider.getEditorTypeId().equals(editorTypeId)){ + return provider; + } + } + return null; + } + + public String getComponentName(){ + return "resourceProviderManager"; + } + + public void initComponent(){ + } + + private void registerProvider(FileEditorProvider provider) { + String editorTypeId = provider.getEditorTypeId(); + for(int i=myProviders.size()-1;i>=0;i--){ + FileEditorProvider _provider=myProviders.get(i); + if(editorTypeId.equals(_provider.getEditorTypeId())){ + throw new IllegalArgumentException( + "attempt to register provider with non unique editorTypeId: "+_provider.getEditorTypeId() + ); + } + } + myProviders.add(provider); + } + + public void disposeComponent(){} + + private static final class MyComparator implements Comparator{ + public static final MyComparator ourInstance = new MyComparator(); + + private MyComparator() {} + + public int compare(FileEditorProvider provider1, FileEditorProvider provider2) { + if(provider1.getPolicy() == FileEditorPolicy.PLACE_BEFORE_DEFAULT_EDITOR){ + return provider2 instanceof TextEditorProvider ? -1 : 0; + } + else if(provider2.getPolicy() == FileEditorPolicy.PLACE_BEFORE_DEFAULT_EDITOR){ + return provider1 instanceof TextEditorProvider ? 1 : 0; + } + else{ + return 0; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/HistoryEntry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/HistoryEntry.java new file mode 100644 index 00000000000..174e08914ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/HistoryEntry.java @@ -0,0 +1,130 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +final class HistoryEntry{ + public static final String TAG = "entry"; + + public final VirtualFile myFile; + /** + * can be null when read from XML + */ + public FileEditorProvider mySelectedProvider; + private final HashMap myProvider2State; + + public HistoryEntry(VirtualFile file, FileEditorProvider[] providers, FileEditorState[] states, FileEditorProvider selectedProvider){ + if (file == null){ + throw new IllegalArgumentException("file cannot be null"); + } + if (providers == null){ + throw new IllegalArgumentException("providers cannot be null"); + } + if (states == null){ + throw new IllegalArgumentException("states cannot be null"); + } + if (selectedProvider == null){ + throw new IllegalArgumentException("selectedProvider cannot be null"); + } + myFile = file; + myProvider2State = new HashMap(); + mySelectedProvider = selectedProvider; + for (int i = 0; i < providers.length; i++) { + putState(providers[i], states[i]); + } + } + + public HistoryEntry(Project project, Element e) throws InvalidDataException{ + if (!e.getName().equals(TAG)) { + throw new IllegalArgumentException("unexpected tag: " + e); + } + + String url = e.getAttributeValue("file"); + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); + if (file == null){ + throw new InvalidDataException(); + } + + myFile = file; + myProvider2State = new HashMap(); + + List providers = e.getChildren("provider"); + for (Iterator iterator = providers.iterator(); iterator.hasNext();) { + Element _e = (Element)iterator.next(); + + String typeId = _e.getAttributeValue("editor-type-id"); + FileEditorProvider provider = FileEditorProviderManager.getInstance().getProvider(typeId); + if (provider == null){ + continue; + } + if ("true".equals(_e.getAttributeValue("selected"))) { + mySelectedProvider = provider; + } + + Element stateElement = _e.getChild("state"); + if (stateElement == null){ + throw new InvalidDataException(); + } + + FileEditorState state = provider.readState(stateElement, project, file); + putState(provider, state); + } + } + + public FileEditorState getState(FileEditorProvider provider) { + if (provider == null){ + throw new IllegalArgumentException("provider cannot be null"); + } + return (FileEditorState)myProvider2State.get(provider); + } + + public void putState(FileEditorProvider provider, FileEditorState state) { + if (provider == null){ + throw new IllegalArgumentException("provider cannot be null"); + } + if (state == null){ + throw new IllegalArgumentException("state cannot be null"); + } + myProvider2State.put(provider, state); + } + + /** + * @return element that was added to the element. + * Returned element has tag {@link #TAG}. Never null. + */ + public Element writeExternal(Element element, Project project) { + Element e = new Element(TAG); + element.addContent(e); + e.setAttribute("file", myFile.getUrl()); + + Iterator i = myProvider2State.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = (Map.Entry)i.next(); + FileEditorProvider provider = (FileEditorProvider)entry.getKey(); + + Element providerElement = new Element("provider"); + if (provider.equals(mySelectedProvider)) { + providerElement.setAttribute("selected", Boolean.TRUE.toString()); + } + providerElement.setAttribute("editor-type-id", provider.getEditorTypeId()); + Element stateElement = new Element("state"); + providerElement.addContent(stateElement); + provider.writeState((FileEditorState)entry.getValue(), project, stateElement); + + e.addContent(providerElement); + } + + return e; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java new file mode 100644 index 00000000000..552dd842124 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java @@ -0,0 +1,509 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandListener; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.util.Pair; + +import java.util.Iterator; +import java.util.LinkedList; + +public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.IdeDocumentHistoryImpl"); + + private static final int BACK_QUEUE_LIMIT = 25; + private static final int CHANGE_QUEUE_LIMIT = 25; + + private final Project myProject; + + private final EditorFactory myEditorFactory; + private FileDocumentManager myFileDocumentManager; + private FileEditorManagerEx myEditorManager; + private VirtualFileManager myVfManager; + private CommandProcessor myCmdProcessor; + private VirtualFileListener myFileListener; + private ToolWindowManager myToolWindowManager; + + private final LinkedList myBackPlaces = new LinkedList(); // LinkedList of PlaceInfo's + private final LinkedList myForwardPlaces = new LinkedList(); // LinkedList of PlaceInfo's + private boolean myBackInProgress = false; + private boolean myForwardInProgress = false; + private Object myLastGroupId = null; + + // change's navigation + private final LinkedList myChangePlaces = new LinkedList(); // LinkedList of PlaceInfo's + private int myStartIndex = 0; + private int myCurrentIndex = 0; + private PlaceInfo myCurrentChangePlace = null; + + private PlaceInfo myCommandStartPlace = null; + private boolean myCurrentCommandIsNavigation = false; + private boolean myCurrentCommandHasChanges = false; + private boolean myCurrentCommandHasMoves = false; + + private DocumentListener myDocumentListener; + private CaretListener myCaretListener; + private final CommandListener myCommandListener = new CommandAdapter() { + public void commandStarted(CommandEvent event) { + onCommandStarted(); + } + + public void commandFinished(CommandEvent event) { + onCommandFinished(event.getCommandGroupId()); + } + }; + + + public IdeDocumentHistoryImpl(Project project, + EditorFactory editorFactory, + FileEditorManager editorManager, + VirtualFileManager vfManager, + CommandProcessor cmdProcessor, + ToolWindowManager toolWindowManager) { + myProject = project; + myEditorFactory = editorFactory; + myEditorManager = (FileEditorManagerEx)editorManager; + myVfManager = vfManager; + myCmdProcessor = cmdProcessor; + myToolWindowManager = toolWindowManager; + } + public IdeDocumentHistoryImpl(Project project, + EditorFactory editorFactory, + FileEditorManager editorManager, + VirtualFileManager vfManager, + CommandProcessor cmdProcessor + ) { + this(project, editorFactory, editorManager, vfManager, cmdProcessor, null); + } + + public final void projectOpened() { + EditorEventMulticaster eventMulticaster = myEditorFactory.getEventMulticaster(); + + myDocumentListener = new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + onDocumentChanged(e); + } + }; + eventMulticaster.addDocumentListener(myDocumentListener); + + myCaretListener = new CaretListener() { + public void caretPositionChanged(CaretEvent e) { + onCaretPositionChanged(e); + } + }; + eventMulticaster.addCaretListener(myCaretListener); + + FileEditorManager fileEditorManager = myEditorManager; + fileEditorManager.addFileEditorManagerListener(new FileEditorManagerAdapter() { + public void selectionChanged(FileEditorManagerEvent e) { + onSelectionChanged(); + } + }); + + myFileListener = new VirtualFileAdapter() { + public void fileDeleted(VirtualFileEvent event) { + onFileDeleted(); + } + }; + myVfManager.addVirtualFileListener(myFileListener); + myCmdProcessor.addCommandListener(myCommandListener); + } + + public final void onFileDeleted() { + removeInvalidFilesFromStacks(); + } + + public final void onSelectionChanged() { + myCurrentCommandIsNavigation = true; + myCurrentCommandHasMoves = true; + } + + public final void onCaretPositionChanged(CaretEvent e) { + if (e.getOldPosition().line == e.getNewPosition().line) return; + Document document = e.getEditor().getDocument(); + if (getFileDocumentManager().getFile(document) != null) { + myCurrentCommandHasMoves = true; + } + } + + public final void onDocumentChanged(DocumentEvent e) { + Document document = e.getDocument(); + if (getFileDocumentManager().getFile(document) != null) { + myCurrentCommandHasChanges = true; + } + } + + public final void onCommandStarted() { + myCommandStartPlace = getCurrentPlaceInfo(); + myCurrentCommandIsNavigation = false; + myCurrentCommandHasChanges = false; + myCurrentCommandHasMoves = false; + } + + private PlaceInfo getCurrentPlaceInfo() { + final Pair selectedEditorWithProvider = getSelectedEditor(); + if (selectedEditorWithProvider != null) { + return createPlaceInfo(selectedEditorWithProvider.getFirst (), selectedEditorWithProvider.getSecond ()); + } + else { + return null; + } + } + + public final void onCommandFinished(Object commandGroupId) { + if (myCommandStartPlace != null) { + if (myCurrentCommandIsNavigation && myCurrentCommandHasMoves) { + if (!myBackInProgress) { + Object gropupId = commandGroupId; + if (gropupId == null || !gropupId.equals(myLastGroupId)) { + putLastOrMerge(myBackPlaces, myCommandStartPlace, BACK_QUEUE_LIMIT); + } + if (!myForwardInProgress) { + for (Iterator iterator = myForwardPlaces.iterator(); iterator.hasNext();) { + iterator.next(); + } + myForwardPlaces.clear(); + } + } + removeInvalidFilesFromStacks(); + } + } + myLastGroupId = commandGroupId; + + if (myCurrentCommandHasChanges) { + setCurrentChangePlace(); + } + else if (myCurrentCommandHasMoves) { + pushCurrentChangePlace(); + } + } + + + public final void projectClosed() { + EditorEventMulticaster eventMulticaster = myEditorFactory.getEventMulticaster(); + eventMulticaster.removeDocumentListener(myDocumentListener); + eventMulticaster.removeCaretListener(myCaretListener); + + myVfManager.removeVirtualFileListener(myFileListener); + myCmdProcessor.removeCommandListener(myCommandListener); + } + + public final void includeCurrentCommandAsNavigation() { + myCurrentCommandIsNavigation = true; + } + + public final void includeCurrentPlaceAsChangePlace() { + setCurrentChangePlace(); + pushCurrentChangePlace(); + } + + private void setCurrentChangePlace() { + final Pair selectedEditorWithProvider = getSelectedEditor(); + if (selectedEditorWithProvider == null) { + return; + } + final PlaceInfo placeInfo = createPlaceInfo(selectedEditorWithProvider.getFirst(), selectedEditorWithProvider.getSecond ()); + myCurrentChangePlace = placeInfo; + if (myChangePlaces.size() > 0) { + final PlaceInfo lastInfo = myChangePlaces.get(myChangePlaces.size() - 1); + if (isSame(placeInfo, lastInfo)) { + myChangePlaces.removeLast(); + } + } + myCurrentIndex = myStartIndex + myChangePlaces.size(); + } + + private void pushCurrentChangePlace() { + if (myCurrentChangePlace != null) { + myChangePlaces.add(myCurrentChangePlace); + if (myChangePlaces.size() > CHANGE_QUEUE_LIMIT) { + myChangePlaces.removeFirst(); + myStartIndex++; + } + myCurrentChangePlace = null; + } + myCurrentIndex = myStartIndex + myChangePlaces.size(); + } + + public final void clearHistory() { + clearPlaceList(myBackPlaces); + clearPlaceList(myForwardPlaces); + clearPlaceList(myChangePlaces); + + myLastGroupId = null; + + myStartIndex = 0; + myCurrentIndex = 0; + if (myCurrentChangePlace != null) { + myCurrentChangePlace = null; + } + + if (myCommandStartPlace != null) { + myCommandStartPlace = null; + } + } + + public final void back() { + removeInvalidFilesFromStacks(); + if (myBackPlaces.isEmpty()) return; + final PlaceInfo info = myBackPlaces.removeLast(); + + PlaceInfo current = getCurrentPlaceInfo(); + if (current != null) { + if (!isSame(current, info)) { + putLastOrMerge(myForwardPlaces, current, Integer.MAX_VALUE); + } + } + putLastOrMerge(myForwardPlaces, info, Integer.MAX_VALUE); + + myBackInProgress = true; + + executeCommand(new Runnable() { + public void run() { + gotoPlaceInfo(info); + } + }, "", null); + + myBackInProgress = false; + } + + public final void forward() { + removeInvalidFilesFromStacks(); + + final PlaceInfo target = getTargetForwardInfo(); + if (target == null) return; + + myForwardInProgress = true; + executeCommand(new Runnable() { + public void run() { + gotoPlaceInfo(target); + } + }, "", null); + myForwardInProgress = false; + } + + private PlaceInfo getTargetForwardInfo() { + if (myForwardPlaces.isEmpty()) return null; + + PlaceInfo target = myForwardPlaces.removeLast(); + PlaceInfo current = getCurrentPlaceInfo(); + + while (!myForwardPlaces.isEmpty()) { + if (isSame(current, target)) { + target = myForwardPlaces.removeLast(); + } else { + break; + } + } + return target; + } + + public final boolean isBackAvailable() { + return !myBackPlaces.isEmpty(); + } + + public final boolean isForwardAvailable() { + return !myForwardPlaces.isEmpty(); + } + + public final void navigatePreviousChange() { + removeInvalidFilesFromStacks(); + if (myCurrentIndex == myStartIndex) return; + int index = myCurrentIndex - 1; + final PlaceInfo info = myChangePlaces.get(index - myStartIndex); + + executeCommand(new Runnable() { + public void run() { + gotoPlaceInfo(info); + } + }, "", null); + myCurrentIndex = index; + } + + public final boolean isNavigatePreviousChangeAvailable() { + return myCurrentIndex > myStartIndex; + } + + private void removeInvalidFilesFromStacks() { + for (Iterator iterator = myBackPlaces.iterator(); iterator.hasNext();) { + PlaceInfo info = iterator.next(); + if (info.myFile != null) { + if (!info.myFile.isValid()) { + iterator.remove(); + } + } + else { + if (!info.getFile().isValid()) { + iterator.remove(); + } + } + } + + for (Iterator iterator = myForwardPlaces.iterator(); iterator.hasNext();) { + PlaceInfo info = iterator.next(); + if (info.myFile != null) { + if (!info.myFile.isValid()) { + iterator.remove(); + } + } + else { + if (!info.getFile().isValid()) { + iterator.remove(); + } + } + } + + for (Iterator iterator = myChangePlaces.iterator(); iterator.hasNext();) { + PlaceInfo info = iterator.next(); + if (info.myFile != null) { + if (!info.myFile.isValid()) { + iterator.remove(); + } + } + else { + if (!info.getFile().isValid()) { + iterator.remove(); + myCurrentIndex = myStartIndex + myChangePlaces.size(); + } + } + } + } + + private void gotoPlaceInfo(PlaceInfo info) { // TODO: Msk + LOG.assertTrue(info != null); + final boolean wasActive = myToolWindowManager.isEditorComponentActive(); + final Pair editorsWithProviders = myEditorManager.openFileWithProviders(info.getFile(), wasActive); + final FileEditor [] editors = editorsWithProviders.getFirst(); + final FileEditorProvider[] providers = editorsWithProviders.getSecond(); + for (int i = 0; i < editors.length; i++) { + String typeId = providers [i].getEditorTypeId(); + if (typeId.equals(info.getEditorTypeId())) { + editors[i].setState(info.getNavigationState()); + } + } + } + + /** + * @return currently selected FileEditor or null. + */ + protected Pair getSelectedEditor() { + final FileEditorManagerEx fileEditorManager = myEditorManager; + final VirtualFile[] selectedFiles = fileEditorManager.getSelectedFiles(); + if (selectedFiles.length == 0) { + return null; + } + return fileEditorManager.getSelectedEditorWithProvider(selectedFiles[0]); + } + + private PlaceInfo createPlaceInfo(final FileEditor fileEditor, final FileEditorProvider fileProvider) { + LOG.assertTrue(fileEditor != null); + final FileEditorManagerEx fileEditorManager = myEditorManager; + final VirtualFile file = fileEditorManager.getFile(fileEditor); + LOG.assertTrue(file != null); + + final FileEditorState state = fileEditor.getState(FileEditorStateLevel.NAVIGATION); + + return new PlaceInfo(file, state, fileProvider.getEditorTypeId()); + } + + private static void clearPlaceList(LinkedList list) { + list.clear(); + } + + + public final String getComponentName() { + return "IdeDocumentHistory"; + } + + private void putLastOrMerge(LinkedList list, PlaceInfo next, int limitSizeLimit) { + if (list.size() > 0) { + PlaceInfo prev = (PlaceInfo)list.get(list.size() - 1); + if (isSame(prev, next)) { + list.removeLast(); + } + } + + list.add(next); + if (list.size() > limitSizeLimit) { + list.removeFirst(); + } + } + + public FileDocumentManager getFileDocumentManager() { + if (myFileDocumentManager == null) { + myFileDocumentManager = FileDocumentManager.getInstance(); + } + return myFileDocumentManager; + } + + private static final class PlaceInfo { + + private final VirtualFile myFile; + private final FileEditorState myNavigationState; + private final String myEditorTypeId; + + public PlaceInfo(VirtualFile file, FileEditorState navigationState, String editorTypeId) { + myNavigationState = navigationState; + myFile = file; + myEditorTypeId = editorTypeId; + } + + public FileEditorState getNavigationState() { + return myNavigationState; + } + + public VirtualFile getFile() { + return myFile; + } + + public String getEditorTypeId() { + return myEditorTypeId; + } + + public String toString() { + return getFile().getName() + " " + getNavigationState(); + } + + } + + public LinkedList getBackPlaces() { + return myBackPlaces; + } + + public LinkedList getForwardPlaces() { + return myForwardPlaces; + } + + public final void initComponent() { } + + public final void disposeComponent() { + } + + protected void executeCommand(Runnable runnable, String name, Object groupId) { + myCmdProcessor.executeCommand(myProject, runnable, name, groupId); + } + + private boolean isSame(PlaceInfo first, PlaceInfo second) { + if (first.getFile().equals(second.getFile())) { + FileEditorState firstState = first.getNavigationState(); + FileEditorState secondState = second.getNavigationState(); + return firstState.equals(secondState) || firstState.canBeMergedWith(secondState, FileEditorStateLevel.NAVIGATION); + } + + return false; + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java new file mode 100644 index 00000000000..89a4c6689a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java @@ -0,0 +1,113 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.text.CharArrayCharSequence; + +import java.io.IOException; +import java.io.Reader; + +public final class LoadTextUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.LoadTextUtil"); + + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + + private static char[] ourSharedBuffer = new char[50000]; + private static final Object OUR_SHARED_BUFFER_LOCK = new Object(); + + public static CharSequence loadText(VirtualFile file, String[] detectedLineSeparator){ + CharSequence chars = new CharArrayCharSequence(EMPTY_CHAR_ARRAY); + if (!file.isDirectory()) { + synchronized (OUR_SHARED_BUFFER_LOCK) { + Reader reader = null; + try { + reader = file.getReader(); + int fileLength = (int)file.getLength(); + chars = loadText(reader, fileLength, detectedLineSeparator); + } + catch (IOException e) { + } + finally { + if (reader != null) { + try { + reader.close(); + } + catch (IOException e) { + } + } + } + } + } + return chars; + } + + public static CharSequence loadText(byte[] bytes, String[] detectedLineSeparator) { + try { + return loadText(VirtualFile.getReader(bytes), bytes.length, detectedLineSeparator); + } catch (IOException e) { + LOG.error(e); + } + + return null; + } + + private static CharSequence loadText(Reader reader, int fileLength, String[] detectedLineSeparator) throws IOException { + + char[] buffer = ourSharedBuffer.length >= fileLength ? ourSharedBuffer : new char[fileLength]; + + int offset = 0; + int read; + do { + read = reader.read( buffer, offset, buffer.length - offset); + if (read < 0) break; + offset += read; + + if (offset >= buffer.length) { + // Number of characters read might exceed fileLength if the encoding being used is capable to + // produce more than one character from a single byte. Need to reallocate in this case. + char[] newBuffer = new char[buffer.length * 2]; + System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); + buffer = newBuffer; + } + } while(true); + + final int LF = 1; + final int CR = 2; + int line_separator = 0; + + int dst = 0; + char prev = ' '; + for( int src = 0; src < offset; src++ ) { + char c = buffer[src]; + switch( c ) { + case '\r': + buffer[dst++] = '\n'; + line_separator = CR; + break; + case '\n': + if( prev != '\r' ) { + buffer[dst++] = '\n'; + line_separator = LF; + } + else line_separator = CR + LF; + break; + default: + buffer[dst++] = c; + break; + } + prev = c; + } + + if( detectedLineSeparator != null && detectedLineSeparator[0] == null ) { + switch( line_separator ) { + case CR: detectedLineSeparator[0] = "\r"; break; + case LF: detectedLineSeparator[0] = "\n"; break; + case CR + LF: detectedLineSeparator[0] = "\r\n"; break; + } + } + + char chars[] = new char[dst]; + System.arraycopy(buffer, 0, chars, 0, chars.length); + return new CharArrayCharSequence(chars); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java new file mode 100644 index 00000000000..cb7e17254ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java @@ -0,0 +1,24 @@ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; + +public final class TrailingSpacesStripper extends FileDocumentManagerAdapter{ + public void beforeDocumentSaving(final Document document) { + if (!document.isWritable()) return; + EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance(); + if (editorSettings != null && !editorSettings.getStripTrailingSpaces().equals(EditorSettingsExternalizable.STRIP_TRAILING_SPACES_NONE)){ + final boolean inChangedLinesOnly = !editorSettings.getStripTrailingSpaces().equals(EditorSettingsExternalizable.STRIP_TRAILING_SPACES_WHOLE); + CommandProcessor.getInstance().runUndoTransparentAction( + new Runnable() { + public void run() { + ((DocumentEx)document).stripTrailingSpaces(inChangedLinesOnly); + } + } + ); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java new file mode 100644 index 00000000000..ac055485df9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java @@ -0,0 +1,432 @@ +package com.intellij.openapi.fileEditor.impl.text; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.VirtualFilePropertyEvent; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.EditorPopupHandler; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class TextEditorComponent extends JPanel implements DataProvider{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.TextEditorComponent"); + + private final Project myProject; + private final VirtualFile myFile; + private final TextEditorImpl myTextEditor; + /** + * Document to be edited + */ + private final Document myDocument; + + private final MyEditorMouseListener myEditorMouseListener; + private final MyEditorCaretListener myEditorCaretListener; + private final MyDocumentListener myDocumentListener; + private final MyEditorPropertyChangeListener myEditorPropertyChangeListener; + private final MyFileTypeListener myFileTypeListener; + private final MyVirtualFileListener myVirtualFileListener; + private Editor myEditor; + + /** + * Whether the editor's document is modified or not + */ + private boolean myModified; + /** + * Whether the editor is valid or not + */ + private boolean myValid; + + TextEditorComponent(final Project project, final VirtualFile file, final TextEditorImpl textEditor) { + super(new BorderLayout (), true); + + if(project==null){ + throw new IllegalArgumentException("project cannot be null"); + } + if(file==null){ + throw new IllegalArgumentException("file cannot be null"); + } + if (textEditor == null) { + throw new IllegalArgumentException("textEditor cannot be null"); + } + assertThread(); + + myProject = project; + myFile = file; + myTextEditor = textEditor; + + myDocument = FileDocumentManager.getInstance().getDocument(myFile); + LOG.assertTrue(myDocument!=null); + myDocumentListener = new MyDocumentListener(); + myDocument.addDocumentListener(myDocumentListener); + + myEditorMouseListener = new MyEditorMouseListener(); + myEditorCaretListener = new MyEditorCaretListener(); + myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); + + myFileTypeListener = new MyFileTypeListener(); + FileTypeManager.getInstance().addFileTypeListener(myFileTypeListener); + + myVirtualFileListener = new MyVirtualFileListener(); + myFile.getFileSystem().addVirtualFileListener(myVirtualFileListener); + myEditor=createEditor(); + add (myEditor.getComponent (), BorderLayout.CENTER); + myModified = isModifiedImpl(); + myValid = isEditorValidImpl(); + LOG.assertTrue(myValid); + } + + /** + * Disposes all resources allocated be the TextEditorComponent. It disposes all created + * editors, unregisters listeners. The behaviour of the splitter after disposing is + * unpredictable. + */ + protected void dispose(){ + myDocument.removeDocumentListener(myDocumentListener); + + disposeEditor(myEditor); + + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + myFile.getFileSystem().removeVirtualFileListener(myVirtualFileListener); + //myFocusWatcher.deinstall(this); + //removePropertyChangeListener(mySplitterPropertyChangeListener); + + //super.dispose(); + } + + /** + * Should be invoked when the corresponding TextEditorImpl + * is selected. Updates the status bar. + */ + void selectNotify(){ + updateStatusBar(); + } + + /** + * Should be invoked when the corresponding TextEditorImpl + * is deselected. Clears the status bar. + */ + void deselectNotify(){ + StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); + LOG.assertTrue(statusBar != null); + statusBar.clear(); + } + + private static void assertThread(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + } + + /** + * TODO[vova] remove this method as soon as splitting will not be a part of TextEditor + * @return array of all existing editors + */ + Editor[] getAllEditors(){ + return new Editor[]{myEditor}; + } + + /** + * @return most recently used editor. This method never returns null. + */ + Editor getEditor(){ + return myEditor; + } + + /** + * @return created editor. This editor should be released by {@link #disposeEditor(Editor) } + * method. + */ + private Editor createEditor(){ + Editor editor=EditorFactory.getInstance().createEditor(myDocument, myProject); + ((EditorMarkupModel) editor.getMarkupModel()).setErrorStripeVisible(true); + Highlighter highlighter=HighlighterFactory.createHighlighter(myProject, myFile.getName()); + ((EditorEx) editor).setHighlighter(highlighter); + ((EditorEx) editor).setFile(myFile); + + editor.addEditorMouseListener(myEditorMouseListener); + editor.getCaretModel().addCaretListener(myEditorCaretListener); + ((EditorEx)editor).addPropertyChangeListener(myEditorPropertyChangeListener); + + TextEditorProvider.putTextEditor(editor, myTextEditor); + return editor; + } + + /** + * Disposes resources allocated by the specified editor view and registeres all + * it's listeners + */ + private void disposeEditor(final Editor editor){ + EditorFactory.getInstance().releaseEditor(editor); + editor.removeEditorMouseListener(myEditorMouseListener); + editor.getCaretModel().removeCaretListener(myEditorCaretListener); + ((EditorEx)editor).removePropertyChangeListener(myEditorPropertyChangeListener); + } + + /** + * @return whether the editor's document is modified or not + */ + boolean isModified(){ + assertThread(); + return myModified; + } + + /** + * Just calculates "modified" property + */ + private boolean isModifiedImpl(){ + return myDocument.getModificationStamp() != myFile.getModificationStamp(); + } + + /** + * Updates "modified" property and fires event if necessary + */ + private void updateModifiedProperty(){ + Boolean oldModified=Boolean.valueOf(myModified); + myModified = isModifiedImpl(); + myTextEditor.firePropertyChange(FileEditor.PROP_MODIFIED, oldModified, Boolean.valueOf(myModified)); + } + + /** + * Name isValid is in use in java.awt.Component + * so we change the name of method to isEditorValid + * + * @return whether the editor is valid or not + */ + boolean isEditorValid(){ + return myValid; + } + + /** + * Just calculates + */ + private boolean isEditorValidImpl(){ + return FileDocumentManager.getInstance().getDocument(myFile) != null; + } + + private void updateValidProperty(){ + Boolean oldValid = Boolean.valueOf(myValid); + myValid = isEditorValidImpl(); + myTextEditor.firePropertyChange(FileEditor.PROP_VALID, oldValid, Boolean.valueOf(myValid)); + } + + /** + * Updates editors' highlighters. This should be done when the opened file + * changes its file type. + */ + private void updateHighlighters(){ + final Highlighter highlighter = HighlighterFactory.createHighlighter(myProject, myFile.getName()); + ((EditorEx)myEditor).setHighlighter(highlighter); + } + + /** + * Updates frame's status bar: insert/overwrite mode, caret position + */ + private void updateStatusBar(){ + final StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); + final Editor editor = getEditor(); + if (editor.isColumnMode()) { + statusBar.setStatus("Column"); + } else { + statusBar.setStatus(editor.isInsertMode() ? "Insert" : "Overwrite"); + } + boolean isWritable = editor.getDocument().isWritable(); + statusBar.setStatusEnabled(isWritable); + statusBar.setWriteStatus(!isWritable); + statusBar.setPosition( + (editor.getCaretModel().getLogicalPosition().line + 1) + + ":" + (editor.getCaretModel().getLogicalPosition().column + 1) + ); + statusBar.updatePopupHintsStatus(); + } + + public Object getData(final String dataId) { + if (DataConstants.PSI_ELEMENT.equals(dataId)){ + final Editor editor=getEditor(); + final PsiFile psiFile = (PsiFile)getData(DataConstants.PSI_FILE); + if (psiFile == null) { + return null; + } + + PsiElement targetElement = + TargetElementUtil.findTargetElement(editor, + TargetElementUtil.THROW_STATEMENT_ACCEPTED | + TargetElementUtil.THROWS_ACCEPTED | + TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED | + TargetElementUtil.ELEMENT_NAME_ACCEPTED | + TargetElementUtil.NEW_AS_CONSTRUCTOR | + TargetElementUtil.LOOKUP_ITEM_ACCEPTED); + return targetElement == null ? psiFile : targetElement; + } + else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + return myFile.isValid()? myFile : null; // fix for SCR 40329 + } + else if (DataConstants.PSI_FILE.equals(dataId)) { + return myFile.isValid()? PsiManager.getInstance(myProject).findFile(myFile) : null; // fix for SCR 40329 + } + else if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) { + /* + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(myFile); + LOG.assertTrue(psiFile != null); + if (!(psiFile instanceof PsiJavaFile)) { + return null; + } + + PsiJavaFile psiJavaFile = (PsiJavaFile)psiFile; + PsiDirectory directory = psiJavaFile.getContainingDirectory(); + if (directory == null) { + return null; + } + PsiPackage aPackage = directory.getPackage(); + if (aPackage == null) { + return null; + } + return directory; + */ + // [dsl] in Editor we do not have any specific target psi element + // we only guess + return null; + }else{ + return null; + } + } + + + /** + * Shows popup menu + */ + private static final class MyEditorMouseListener extends EditorPopupHandler { + public void invokePopup(final EditorMouseEvent event) { + if (!event.isConsumed() && event.getArea() == EditorMouseEventArea.EDITING_AREA) { + ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_EDITOR_POPUP); + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.EDITOR_POPUP, group); + MouseEvent e = event.getMouseEvent(); + popupMenu.getComponent().show(e.getComponent(), e.getX(), e.getY()); + e.consume(); + } + } + } + + /** + * Getts events about caret movements and modifies status bar + */ + private final class MyEditorCaretListener implements CaretListener { + public void caretPositionChanged(final CaretEvent e) { + assertThread(); + if (e.getEditor() == getEditor()) { + updateStatusBar(); + } + } + } + + /** + * Updates "modified" property + */ + private final class MyDocumentListener extends DocumentAdapter { + /** + * We can reuse this runnable to decrease number of allocated object. + */ + private final Runnable myUpdateRunnable; + + public MyDocumentListener() { + myUpdateRunnable = new Runnable() { + public void run() { + updateModifiedProperty(); + } + }; + } + + public void documentChanged(DocumentEvent e) { + // document's timestamp is changed later on undo or PSI changes + ApplicationManager.getApplication().invokeLater(myUpdateRunnable); + } + } + + /** + * Gets event obout insert/overwrite modes + */ + private final class MyEditorPropertyChangeListener implements PropertyChangeListener { + public void propertyChange(final PropertyChangeEvent e) { + assertThread(); + final String propertyName = e.getPropertyName(); + if(EditorEx.PROP_INSERT_MODE.equals(propertyName) || EditorEx.PROP_COLUMN_MODE.equals(propertyName)){ + updateStatusBar(); + } + } + } + + /** + * Listen changes of file types. When type of the file changes we need + * to also change highlighter. + */ + private final class MyFileTypeListener implements FileTypeListener { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(final FileTypeEvent event) { + assertThread(); + // File can be invalid after file type changing. The editor should be removed + // by the FileEditorManager if it's invalid. + updateValidProperty(); + if(isValid()){ + updateHighlighters(); + } + } + } + + /** + * Updates "valid" property and highlighters (if necessary) + */ + private final class MyVirtualFileListener extends VirtualFileAdapter{ + public void propertyChanged(final VirtualFilePropertyEvent e) { + if(VirtualFile.PROP_NAME.equals(e.getPropertyName())){ + // File can be invalidated after file changes name (extension also + // can changes). The editor should be removed if it's invalid. + updateValidProperty(); + if(isValid()){ + updateHighlighters(); + } + } + } + + public void contentsChanged(VirtualFileEvent event){ + if (event.getRequestor() instanceof FileDocumentManager){ // commit + assertThread(); + VirtualFile file = event.getFile(); + LOG.assertTrue(file.isValid()); + if(myFile.equals(file)){ + updateModifiedProperty(); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java new file mode 100644 index 00000000000..ca0d73fa82e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java @@ -0,0 +1,214 @@ +package com.intellij.openapi.fileEditor.impl.text; + +import com.intellij.codeHighlighting.BackgroundEditorHighlighter; +import com.intellij.codeInsight.daemon.impl.TextEditorBackgroundHighlighter; +import com.intellij.codeInsight.folding.CodeFoldingManager; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; + +import javax.swing.*; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * @author Vladimir Kondratyev + */ +public final class TextEditorImpl extends UserDataHolderBase implements TextEditor{ + private final Project myProject; + private final PropertyChangeSupport myChangeSupport; + private final TextEditorComponent myComponent; + private TextEditorBackgroundHighlighter myBackgroundHighlighter; + + TextEditorImpl(final Project project, final VirtualFile file) { + if(project==null){ + throw new IllegalArgumentException("project cannot be null"); + } + if(file==null){ + throw new IllegalArgumentException("file cannot be null"); + } + myProject = project; + myChangeSupport = new PropertyChangeSupport(this); + myComponent = new TextEditorComponent(project, file, this); + } + + void dispose(){ + myComponent.dispose(); + } + + public JComponent getComponent() { + return myComponent; + } + + public JComponent getPreferredFocusedComponent(){ + return getActiveEditor().getContentComponent(); + } + + /** + * TODO[vova] remove this method as soon as splitting will not be a part of TextEditor + * @return always not empty array + */ + public Editor[] getAllEditors(){ + return myComponent.getAllEditors(); + } + + public Editor getEditor(){ + return getActiveEditor(); + } + + /** + * @see TextEditorComponent#getEditor() + */ + private Editor getActiveEditor() { + return myComponent.getEditor(); + } + + public String getName() { + return "Text"; + } + + public FileEditorState getState(FileEditorStateLevel level) { + if (level == null) { + throw new IllegalArgumentException("level cannot be null"); + } + TextEditorState state = new TextEditorState(); + getStateImpl(myProject, getActiveEditor(), state, level); + return state; + } + + static void getStateImpl(final Project project, final Editor editor, final TextEditorState state, FileEditorStateLevel level){ + if (state == null) { + throw new IllegalArgumentException("state cannot be null"); + } + if (level == null) { + throw new IllegalArgumentException("level cannot be null"); + } + state.LINE = editor.getCaretModel().getLogicalPosition().line; + state.COLUMN = editor.getCaretModel().getLogicalPosition().column; + state.SELECTION_START = editor.getSelectionModel().getSelectionStart(); + state.SELECTION_END = editor.getSelectionModel().getSelectionEnd(); + + // Save folding only on FULL level. It's very expensive to commit document on every + // type (caused by undo). + if(FileEditorStateLevel.FULL == level){ + // Folding + if (project != null) { + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + state.FOLDING_STATE = CodeFoldingManager.getInstance(project).saveFoldingState(editor); + } + else { + state.FOLDING_STATE = null; + } + + state.VERTICAL_SCROLL_PROPORTION = EditorUtil.calcVerticalScrollProportion(editor); + } + else { + state.VERTICAL_SCROLL_PROPORTION = -1; + } + } + + public void setState(final FileEditorState state) { + if (state == null){ + throw new IllegalArgumentException("state cannot be null"); + } + setStateImpl(myProject, getActiveEditor(), (TextEditorState)state); + } + + static void setStateImpl(final Project project, final Editor editor, final TextEditorState state){ + LogicalPosition pos = new LogicalPosition(state.LINE, state.COLUMN); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getSelectionModel().removeSelection(); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + if (state.VERTICAL_SCROLL_PROPORTION != -1) { + EditorUtil.setVerticalScrollProportion(editor, state.VERTICAL_SCROLL_PROPORTION); + } + + final Document document = editor.getDocument(); + + if (state.SELECTION_START == state.SELECTION_END) { + editor.getSelectionModel().removeSelection(); + } + else { + int startOffset = Math.min(state.SELECTION_START, document.getTextLength()); + int endOffset = Math.min(state.SELECTION_END, document.getTextLength()); + editor.getSelectionModel().setSelection(startOffset, endOffset); + } + ((EditorEx) editor).stopOptimizedScrolling(); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + // Folding + if (project != null && state.FOLDING_STATE != null){ + PsiDocumentManager.getInstance(project).commitDocument(document); + editor.getFoldingModel().runBatchFoldingOperation( + new Runnable() { + public void run() { + CodeFoldingManager.getInstance(project).restoreFoldingState(editor, state.FOLDING_STATE); + } + } + ); + } + } + + public boolean isModified() { + return myComponent.isModified(); + } + + public boolean isValid() { + return myComponent.isEditorValid(); + } + + public void selectNotify() { + myComponent.selectNotify(); + } + + public void deselectNotify() { + myComponent.deselectNotify(); + } + + void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) { + myChangeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + public void addPropertyChangeListener(final PropertyChangeListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null"); + } + myChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(final PropertyChangeListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null"); + } + myChangeSupport.removePropertyChangeListener(listener); + } + + public BackgroundEditorHighlighter getBackgroundHighlighter() { + if (myBackgroundHighlighter == null) { + myBackgroundHighlighter = new TextEditorBackgroundHighlighter(myProject, getEditor()); + } + return myBackgroundHighlighter; + } + + public FileEditorLocation getCurrentLocation() { + return new TextEditorLocation(getEditor().getCaretModel().getLogicalPosition(), this); + } + + public StructureViewModel getStructureViewModel() { + Document document = myComponent.getEditor().getDocument(); + VirtualFile file = FileDocumentManager.getInstance().getFile(document); + if (file == null) return null; + return file.getFileType().getStructureViewModel(file, myProject); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java new file mode 100644 index 00000000000..4ca47ac3cbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java @@ -0,0 +1,264 @@ +package com.intellij.openapi.fileEditor.impl.text; + +import com.intellij.codeHighlighting.BackgroundEditorHighlighter; +import com.intellij.codeInsight.daemon.impl.TextEditorBackgroundHighlighter; +import com.intellij.codeInsight.folding.CodeFoldingManager; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; + +import javax.swing.*; +import java.beans.PropertyChangeListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class TextEditorProvider implements FileEditorProvider, ApplicationComponent { + + private static final String TYPE_ID = "text-editor"; + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.TextEditorProvider"); + private static final Key TEXT_EDITOR_KEY = Key.create("textEditor"); + + public static TextEditorProvider getInstance() { + return ApplicationManager.getApplication().getComponent(TextEditorProvider.class); + } + + public boolean accept(Project project, VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + if (file.isDirectory() || !file.isValid()) { + return false; + } + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + return !fileType.isBinary() || fileType == StdFileTypes.CLASS; + } + + public FileEditor createEditor(Project project, final VirtualFile file) { + if (file == null) { + throw new IllegalArgumentException("file cannot be null"); + } + LOG.assertTrue(accept(project, file)); + return new TextEditorImpl(project, file); + } + + public void disposeEditor(FileEditor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + ((TextEditorImpl)editor).dispose(); + } + + public FileEditorState readState(Element element, Project project, VirtualFile file) { + TextEditorState state = new TextEditorState(); + + try { + state.LINE = Integer.parseInt(element.getAttributeValue("line")); + state.COLUMN = Integer.parseInt(element.getAttributeValue("column")); + state.SELECTION_START = Integer.parseInt(element.getAttributeValue("selection-start")); + state.SELECTION_END = Integer.parseInt(element.getAttributeValue("selection-end")); + state.VERTICAL_SCROLL_PROPORTION = Float.parseFloat(element.getAttributeValue("vertical-scroll-proportion")); + } + catch (NumberFormatException ignored) { + } + + // Foldings + if (project != null) { + Element child = element.getChild("folding"); + Document document = FileDocumentManager.getInstance().getDocument(file); + if (child != null && document != null) { + //PsiDocumentManager.getInstance(project).commitDocument(document); + state.FOLDING_STATE = CodeFoldingManager.getInstance(project).readFoldingState(child, document); + } + else { + state.FOLDING_STATE = null; + } + } + + return state; + } + + public void writeState(FileEditorState _state, Project project, Element element) { + TextEditorState state = (TextEditorState)_state; + + element.setAttribute("line", Integer.toString(state.LINE)); + element.setAttribute("column", Integer.toString(state.COLUMN)); + element.setAttribute("selection-start", Integer.toString(state.SELECTION_START)); + element.setAttribute("selection-end", Integer.toString(state.SELECTION_END)); + element.setAttribute("vertical-scroll-proportion", Float.toString(state.VERTICAL_SCROLL_PROPORTION)); + + // Foldings + if (state.FOLDING_STATE != null) { + Element e = new Element("folding"); + try { + CodeFoldingManager.getInstance(project).writeFoldingState(state.FOLDING_STATE, e); + } + catch (WriteExternalException e1) { + } + element.addContent(e); + } + } + + public String getEditorTypeId() { + return TYPE_ID; + } + + public FileEditorPolicy getPolicy() { + return FileEditorPolicy.NONE; + } + + public String getComponentName() { + return "textEditorProvider"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + /** + * @return never null + */ + public TextEditor getTextEditor(Editor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + + TextEditor textEditor = (TextEditor)editor.getUserData(TEXT_EDITOR_KEY); + if (textEditor == null) { + textEditor = new DummyTextEditor(editor); + putTextEditor(editor, textEditor); + } + + return textEditor; + } + + public static Document[] getDocuments(FileEditor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + + if (editor instanceof DocumentsEditor) { + DocumentsEditor documentsEditor = ((DocumentsEditor)editor); + Document[] documents = documentsEditor.getDocuments(); + if (documents.length > 0) { + return documents; + } + else { + return null; + } + } + + Project[] projects = ProjectManager.getInstance().getOpenProjects(); + for (int i = projects.length - 1; i >= 0; i--) { + VirtualFile file = FileEditorManagerEx.getInstanceEx(projects[i]).getFile(editor); + if (file != null) { + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + return new Document[]{document}; + } + else { + return null; + } + } + } + + if (editor instanceof TextEditor) { + Document document = ((TextEditor)editor).getEditor().getDocument(); + if (document != null) { + return new Document[]{document}; + } + else { + return null; + } + } + return null; + } + + static void putTextEditor(Editor editor, TextEditor textEditor) { + editor.putUserData(TEXT_EDITOR_KEY, textEditor); + } + + private final class DummyTextEditor extends UserDataHolderBase implements TextEditor { + private final Editor myEditor; + private TextEditorBackgroundHighlighter myBackgroundHighlighter; + + public DummyTextEditor(Editor editor) { + myEditor = editor; + myBackgroundHighlighter = myEditor.getProject() == null + ? null + : new TextEditorBackgroundHighlighter(myEditor.getProject(), myEditor); + } + + public Editor getEditor() { + return myEditor; + } + + public JComponent getComponent() { + return myEditor.getComponent(); + } + + public JComponent getPreferredFocusedComponent() { + return myEditor.getContentComponent(); + } + + public String getName() { + return "Text"; + } + + public StructureViewModel getStructureViewModel() { + VirtualFile file = FileDocumentManager.getInstance().getFile(myEditor.getDocument()); + return file.getFileType().getStructureViewModel(file, myEditor.getProject()); + } + + + public FileEditorState getState(FileEditorStateLevel level) { + TextEditorState state = new TextEditorState(); + TextEditorImpl.getStateImpl(null, myEditor, state, level); + return state; + } + + public void setState(FileEditorState state) { + TextEditorImpl.setStateImpl(null, myEditor, (TextEditorState)state); + } + + public boolean isModified() { + return false; + } + + public boolean isValid() { + return true; + } + + public void selectNotify() { } + + public void deselectNotify() { } + + public void addPropertyChangeListener(PropertyChangeListener listener) { } + + public void removePropertyChangeListener(PropertyChangeListener listener) { } + + public BackgroundEditorHighlighter getBackgroundHighlighter() { + return myBackgroundHighlighter; + } + + public FileEditorLocation getCurrentLocation() { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java new file mode 100644 index 00000000000..1cfdcbd11e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java @@ -0,0 +1,58 @@ +package com.intellij.openapi.fileEditor.impl.text; + +import com.intellij.codeInsight.folding.CodeFoldingState; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; + +/** + * @author Vladimir Kondratyev + */ +final class TextEditorState implements FileEditorState { + + public int LINE; + public int COLUMN; + public float VERTICAL_SCROLL_PROPORTION; + public int SELECTION_START; + public int SELECTION_END; + /** + * State which describes how editor is folded. + * This field can be null. + */ + public CodeFoldingState FOLDING_STATE; + + private static final int MIN_CHANGE_DISTANCE = 4; + + public TextEditorState() { + } + + public boolean equals(Object o) { + if (!(o instanceof TextEditorState)) { + return false; + } + + final TextEditorState textEditorState = (TextEditorState)o; + + if (COLUMN != textEditorState.COLUMN) return false; + if (LINE != textEditorState.LINE) return false; + if (VERTICAL_SCROLL_PROPORTION != textEditorState.VERTICAL_SCROLL_PROPORTION) return false; + if (SELECTION_START != textEditorState.SELECTION_START) return false; + if (SELECTION_END != textEditorState.SELECTION_END) return false; + + return true; + } + + public int hashCode() { + return LINE + COLUMN; + } + + public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) { + if (!(otherState instanceof TextEditorState)) return false; + TextEditorState other = (TextEditorState)otherState; + return level == FileEditorStateLevel.NAVIGATION && Math.abs(LINE - other.LINE) < MIN_CHANGE_DISTANCE; + } + + public String toString() { + return "[" + LINE + "," + COLUMN + "]"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/PlainTextFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/PlainTextFileType.java new file mode 100644 index 00000000000..2c872be766b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/PlainTextFileType.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.fileTypes; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; + +import javax.swing.*; + +public class PlainTextFileType implements FileType { + private static final Icon ICON = IconLoader.getIcon("/fileTypes/text.png"); + + public String getName() { + return "PLAIN_TEXT"; + } + + public String getDescription() { + return "Text files"; + } + + public String getDefaultExtension() { + return "txt"; + } + + public Icon getIcon() { + return ICON; + } + + public boolean isBinary() { + return false; + } + + public boolean isReadOnly() { + return false; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public FileHighlighter getHighlighter(Project project) { + return new PlainFileHighlighter(); + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return new PsiPlainTextFileImpl((PsiManagerImpl)PsiManager.getInstance(project), name, this, text, startOffset, endOffset); + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/UserBinaryFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/UserBinaryFileType.java new file mode 100644 index 00000000000..b7063e9c152 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/UserBinaryFileType.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.fileTypes; + +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.file.PsiBinaryFileImpl; + +public class UserBinaryFileType extends UserFileType { + public SettingsEditor getEditor() { + return null; + } + + public boolean isBinary() { + return true; + } + + public FileHighlighter getHighlighter(Project project) { + return null; + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return new PsiBinaryFileImpl((PsiManagerImpl)PsiManager.getInstance(project), file); + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FakeFileType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FakeFileType.java new file mode 100644 index 00000000000..e7d026cd0ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FakeFileType.java @@ -0,0 +1,62 @@ +/* + * Created by IntelliJ IDEA. + * User: valentin + * Date: 29.01.2004 + * Time: 21:10:56 + */ +package com.intellij.openapi.fileTypes.ex; + +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.ide.util.treeView.smartTree.TreeModel; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; + +import javax.swing.*; + +public abstract class FakeFileType implements FileType { + public abstract boolean isMyFileType(VirtualFile file); + + public String getDefaultExtension() { + return null; + } + + public Icon getIcon() { + return null; + } + + public boolean isBinary() { + return true; + } + + public boolean isReadOnly() { + return true; + } + + public String getCharset(VirtualFile file) { + return null; + } + + public PsiFile createPsiFile(VirtualFile file, Project project) { + return null; + } + + public PsiFile createPsiFile(Project project, String name, char[] text, int startOffset, int endOffset) { + return null; + } + + public FileTypeSupportCapabilities getSupportCapabilities() { + return null; + } + + public PseudoTextBuilder getPseudoTextBuilder() { + return null; + } + + public StructureViewModel getStructureViewModel(VirtualFile file, Project project) { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java new file mode 100644 index 00000000000..54c126cd8c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java @@ -0,0 +1,131 @@ +package com.intellij.openapi.fileTypes.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.impl.FileTypeRenderer; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.ListScrollingUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class FileTypeChooser extends DialogWrapper{ + private DefaultListModel myModel = new DefaultListModel(); + private JList myList = new JList(myModel); + private String myExtension; + + public FileTypeChooser(String extension) { + super(true); + myExtension=extension; + + FileType[] fileTypes = FileTypeManager.getInstance().getRegisteredFileTypes(); + for(int i = 0; i < fileTypes.length; i++){ + FileType type = fileTypes[i]; + if (!type.isBinary() && !type.isReadOnly()) { + myModel.addElement(type); + } + } + setTitle("Register New Extension"); + init(); + } + + protected JComponent createCenterPanel(){ + JPanel panel=new JPanel(new GridBagLayout()); + JLabel label = new JLabel("The extension '" + myExtension + "' is not associated with a registered file type. Please choose one:"); + label.setUI(new MultiLineLabelUI()); + panel.add( + label, + new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,5,5),0,0) + ); + + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myList.setCellRenderer(new FileTypeRenderer()); + + myList.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2){ + doOKAction(); + } + } + } + ); + + myList.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateButtonsState(); + } + } + ); + + + JScrollPane scrollPane = new JScrollPane(myList); + scrollPane.setPreferredSize(new Dimension(150, 200)); + ListScrollingUtil.selectItem(myList, StdFileTypes.PLAIN_TEXT); + panel.add( + scrollPane, + new GridBagConstraints(0,1,1,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0) + ); + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myList; + } + + private void updateButtonsState() { + setOKActionEnabled(myList.getSelectedIndex() != -1); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.fileTypes.FileTypeChooser"; + } + + public FileType getSelectedType() { + return (FileType)myList.getSelectedValue(); + } + + /** + * If fileName is already associated any known file type returns it. + * Otherwise asks user to select file type and associates it with fileName extension if any selected. + * @return Known file type or null. Never returns {@link com.intellij.openapi.fileTypes.StdFileTypes#UNKNOWN}. + */ + public static FileType getKnownFileTypeOrAssociate(VirtualFile file) { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType type = fileTypeManager.getFileTypeByFile(file); + if (type == StdFileTypes.UNKNOWN) + type = getKnownFileTypeOrAssociate(file.getName()); + return type; + } + public static FileType getKnownFileTypeOrAssociate(String fileName) { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType type = fileTypeManager.getFileTypeByFileName(fileName); + if (type == StdFileTypes.UNKNOWN) + type = associateFileType(fileName); + return type; + } + + public static FileType associateFileType(String fileName) { + final String extension = ((FileTypeManagerEx) FileTypeManager.getInstance()).getExtension(fileName); + FileTypeChooser chooser = new FileTypeChooser(extension); + chooser.show(); + if (!chooser.isOK()) return null; + final FileType type = chooser.getSelectedType(); + if (type == StdFileTypes.UNKNOWN) return null; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + FileTypeManagerEx.getInstanceEx().associateExtension(type, extension); + } + }); + return type; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeManagerEx.java new file mode 100644 index 00000000000..19e217e9e12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/ex/FileTypeManagerEx.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.fileTypes.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; + +/** + * @author max + */ +public abstract class FileTypeManagerEx extends FileTypeManager{ + public static FileTypeManagerEx getInstanceEx(){ + return (FileTypeManagerEx) ApplicationManager.getApplication().getComponent(FileTypeManager.class); + } + + public abstract void registerFileType(FileType fileType); + public abstract void unregisterFileType(FileType fileType); + + public abstract String getIgnoredFilesList(); + public abstract void setIgnoredFilesList(String list); + public abstract boolean isIgnoredFilesListEqualToCurrent(String list); + + public abstract String getExtension(String fileName); + + public abstract void associateExtension(FileType type, String extension); + + public abstract void fireFileTypesChanged(); + + public abstract void fireBeforeFileTypesChanged(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java new file mode 100644 index 00000000000..29e6e84f884 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java @@ -0,0 +1,475 @@ +package com.intellij.openapi.fileTypes.impl; + +import com.intellij.ide.highlighter.custom.SyntaxTable; +import com.intellij.ide.highlighter.custom.impl.CustomFileType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.UserFileType; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ListUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.*; + +/** + * @author Eugene Belyaev + */ +public class FileTypeConfigurable extends BaseConfigurable implements ApplicationComponent { + private RecognizedFileTypes myRecognizedFileType; + private ExtensionsPanel myExtensions; + private FileTypePanel myFileTypePanel; + private HashSet myTempFileTypes; + private FileTypeManagerImpl myManager; + private Map myTempExtension2TypeMap; + private Map myOriginalToEditedMap = new HashMap(); + + public FileTypeConfigurable(FileTypeManager fileTypeManager) { + myManager = (FileTypeManagerImpl)fileTypeManager; + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public String getDisplayName() { + return "File Types"; + } + + public JComponent createComponent() { + myFileTypePanel = new FileTypePanel(); + myRecognizedFileType = myFileTypePanel.myRecognizedFileType; + myExtensions = myFileTypePanel.myExtensions; + myRecognizedFileType.attachActions(this); + myRecognizedFileType.myFileTypesList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateExtensionList(); + } + }); + myExtensions.attachActions(this); + return myFileTypePanel.getComponent(); + } + + private void updateFileTypeList() { + FileType[] types = myTempFileTypes.toArray(new FileType[myTempFileTypes.size()]); + Arrays.sort(types, new Comparator() { + public int compare(Object o1, Object o2) { + FileType fileType1 = (FileType)o1; + FileType fileType2 = (FileType)o2; + return fileType1.getDescription().compareToIgnoreCase(fileType2.getDescription()); + } + }); + myRecognizedFileType.setFileTypes(types); + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableFileTypes.png"); + } + + private FileType[] getModifiableFileTypes() { + FileType[] registeredFileTypes = FileTypeManager.getInstance().getRegisteredFileTypes(); + ArrayList result = new ArrayList(); + for (int i = 0; i < registeredFileTypes.length; i++) { + FileType fileType = registeredFileTypes[i]; + if (!fileType.isReadOnly()) result.add(fileType); + } + return result.toArray(new FileType[result.size()]); + } + + private boolean hasAssociatedExtensions(FileType type) { + return myTempExtension2TypeMap.containsValue(type); + } + + public void apply() throws ConfigurationException { + for (Iterator iterator = myTempFileTypes.iterator(); iterator.hasNext();) { + FileType fileType = (FileType)iterator.next(); + if (StdFileTypes.UNKNOWN != fileType && !hasAssociatedExtensions(fileType)) { + throw new ConfigurationException("No default extension specified for type " + fileType.getName()); + } + } + + Set modifiedUserTypes = myOriginalToEditedMap.keySet(); + for (Iterator iterator = modifiedUserTypes.iterator(); iterator.hasNext();) { + UserFileType oldType = iterator.next(); + UserFileType newType = myOriginalToEditedMap.get(oldType); + oldType.copyFrom(newType); + } + myOriginalToEditedMap.clear(); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myManager.setExtensionMap(myTempFileTypes, myTempExtension2TypeMap); + } + }); + } + + public void reset() { + myTempExtension2TypeMap = new HashMap(myManager.getExtensionMap()); + myTempFileTypes = new HashSet(Arrays.asList(getModifiableFileTypes())); + myOriginalToEditedMap.clear(); + + updateFileTypeList(); + updateExtensionList(); + } + + public boolean isModified() { + return !myTempExtension2TypeMap.equals(myManager.getExtensionMap()) || + !myTempFileTypes.equals(new HashSet(Arrays.asList(myManager.getRegisteredFileTypes()))) || + !myOriginalToEditedMap.isEmpty(); + } + + public void disposeUIResources() { + if (myFileTypePanel != null) myFileTypePanel.dispose(); + myFileTypePanel = null; + myRecognizedFileType = null; + myExtensions = null; + } + + private static class ExtensionRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setText(" " + getText()); + return this; + } + + public Dimension getPreferredSize() { + return new Dimension(0, 20); + } + } + + private void updateExtensionList() { + myExtensions.clearList(); + FileType type = myRecognizedFileType.getSelectedFileType(); + if (type == null) return; + Iterator it = myTempExtension2TypeMap.keySet().iterator(); + while (it.hasNext()) { + String extension = (String)it.next(); + if (type.equals(myTempExtension2TypeMap.get(extension))) { + myExtensions.addExtension(extension); + } + } + myExtensions.ensureSelectionExists(); + } + + private void editFileType() { + FileType fileType = myRecognizedFileType.getSelectedFileType(); + if (!canBeModified(fileType)) return; + UserFileType ftToEdit = myOriginalToEditedMap.get(fileType); + if (ftToEdit == null) ftToEdit = ((UserFileType)fileType).clone(); + TypeEditor editor = new TypeEditor(myRecognizedFileType.myEditButton, ftToEdit); + editor.show(); + if (editor.isOK()) { + UserFileType newFileType = ftToEdit; + myOriginalToEditedMap.put((UserFileType)fileType, newFileType); + } + } + + private void removeFileType() { + FileType fileType = myRecognizedFileType.getSelectedFileType(); + if (fileType == null) return; + myTempFileTypes.remove(fileType); + myOriginalToEditedMap.remove(fileType); + + Iterator iterator = myTempExtension2TypeMap.keySet().iterator(); + while (iterator.hasNext()) { + String extension = (String)iterator.next(); + FileType t = myTempExtension2TypeMap.get(extension); + if (fileType == t) { + iterator.remove(); + } + } + + updateFileTypeList(); + updateExtensionList(); + } + + private boolean canBeModified(FileType fileType) { + return fileType instanceof UserFileType; + } + + private void addFileType() { + //TODO: support adding binary file types... + CustomFileType type = new CustomFileType(new SyntaxTable()); + TypeEditor editor = new TypeEditor(myRecognizedFileType.myAddButton, type); + editor.show(); + if (editor.isOK()) { + myTempFileTypes.add(type); + updateFileTypeList(); + updateExtensionList(); + myRecognizedFileType.selectFileType(type); + type.initSupport(); + } + } + + private void addExtension() { + FileType type = myRecognizedFileType.getSelectedFileType(); + if (type == null) return; + String text = Messages.showInputDialog(myExtensions.myAddButton, "Enter new extension:", "Add Extension", Messages.getQuestionIcon()); + if (text == null || "".equals(text)) return; + + FileType registeredFileType = addNewExtension(type, text); + if (registeredFileType != null) { + Messages.showMessageDialog(myExtensions.myAddButton, + "This extension is already registered by \'" + registeredFileType.getDescription() + "\' filetype", + "Add Extension", + Messages.getErrorIcon()); + } + } + + public FileType addNewExtension(FileType type, String extension) { + extension = extension.toLowerCase(); + if (StringUtil.startsWithChar(extension, '.')) extension = extension.substring(1); + FileType fileTypeByExtension = myTempExtension2TypeMap.get(extension); + + if (fileTypeByExtension != null && fileTypeByExtension != StdFileTypes.UNKNOWN) { + return fileTypeByExtension; + } + FileType registeredFileType = FileTypeManager.getInstance().getFileTypeByExtension(extension); + if (registeredFileType != StdFileTypes.UNKNOWN && registeredFileType.isReadOnly()) { + return registeredFileType; + } + + if (extension != null) { + myTempExtension2TypeMap.put(extension, type); + myExtensions.addExtensionAndSelect(extension); + } + myExtensions.myExtensionsList.requestFocus(); + return null; + } + + private void removeExtension() { + FileType type = myRecognizedFileType.getSelectedFileType(); + if (type == null) return; + String extension = myExtensions.removeSelected(); + if (extension == null) return; + myTempExtension2TypeMap.remove(extension); + myExtensions.myExtensionsList.requestFocus(); + } + + public String getHelpTopic() { + return "preferences.fileTypes"; + } + + public String getComponentName() { + return "FileTypeConfigurable"; + } + + public static class RecognizedFileTypes extends JPanel { + private JList myFileTypesList; + private JButton myAddButton; + private JButton myEditButton; + private JButton myRemoveButton; + private JPanel myWholePanel; + + public RecognizedFileTypes() { + super(new BorderLayout()); + add(myWholePanel, BorderLayout.CENTER); + myFileTypesList.setCellRenderer(new FileTypeRenderer()); + myFileTypesList.setModel(new DefaultListModel()); + } + + public void attachActions(final FileTypeConfigurable controller) { + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.addFileType(); + } + }); + myEditButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.editFileType(); + } + }); + myFileTypesList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + FileType fileType = getSelectedFileType(); + boolean b = controller.canBeModified(fileType); + myEditButton.setEnabled(b); + myRemoveButton.setEnabled(b); + } + }); + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.removeFileType(); + } + }); + myFileTypesList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) controller.editFileType(); + } + }); + } + + public FileType getSelectedFileType() { + return (FileType)myFileTypesList.getSelectedValue(); + } + + public JComponent getComponent() { + return myWholePanel; + } + + public void setFileTypes(FileType[] types) { + DefaultListModel listModel = (DefaultListModel)myFileTypesList.getModel(); + listModel.clear(); + for (int i = 0; i < types.length; i++) { + FileType type = types[i]; + if (type != StdFileTypes.UNKNOWN) { + listModel.addElement(type); + } + } + ListScrollingUtil.ensureSelectionExists(myFileTypesList); + } + + public int getSelectedIndex() { + return myFileTypesList.getSelectedIndex(); + } + + public void setSelectionIndex(int selectedIndex) { + myFileTypesList.setSelectedIndex(selectedIndex); + } + + public void selectFileType(FileType fileType) { + myFileTypesList.setSelectedValue(fileType, true); + myFileTypesList.requestFocus(); + } + } + + public static class ExtensionsPanel extends JPanel { + private JList myExtensionsList; + private JButton myAddButton; + private JButton myRemoveButton; + private JPanel myWholePanel; + + public ExtensionsPanel() { + super(new BorderLayout()); + add(myWholePanel, BorderLayout.CENTER); + myExtensionsList.setCellRenderer(new ExtensionRenderer()); + myExtensionsList.setModel(new DefaultListModel()); + myExtensionsList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + myRemoveButton.setEnabled(myExtensionsList.getSelectedIndex() != -1 && getListModel().size() > 1); + } + }); + } + + public void attachActions(final FileTypeConfigurable controller) { + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.addExtension(); + } + }); + + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.removeExtension(); + } + }); + + } + + public JComponent getComponent() { + return myWholePanel; + } + + public void clearList() { + getListModel().clear(); + myExtensionsList.clearSelection(); + } + + private DefaultListModel getListModel() { + return (DefaultListModel)myExtensionsList.getModel(); + } + + public void addExtension(String extension) { + getListModel().addElement(extension); + } + + public void ensureSelectionExists() { + ListScrollingUtil.ensureSelectionExists(myExtensionsList); + } + + public void addExtensionAndSelect(String extension) { + addExtension(extension); + ListScrollingUtil.selectItem(myExtensionsList, getListModel().getSize() - 1); + } + + public boolean isListEmpty() { + return getListModel().size() == 0; + } + + public String removeSelected() { + Object selectedValue = myExtensionsList.getSelectedValue(); + if (selectedValue == null) return null; + ListUtil.removeSelectedItems(myExtensionsList); + return (String)selectedValue; + } + + public String getDefaultExtension() { + return (String)getListModel().getElementAt(0); + } + } + + private static class FileTypePanel { + private JPanel myWholePanel; + private RecognizedFileTypes myRecognizedFileType; + private ExtensionsPanel myExtensions; + + public JComponent getComponent() { + return myWholePanel; + } + + public void dispose() { + myRecognizedFileType.setFileTypes(FileType.EMPTY_ARRAY); + myExtensions.clearList(); + } + } + + private static class TypeEditor> extends DialogWrapper { + private T myFileType; + private SettingsEditor myEditor; + + public TypeEditor(Component parent, T fileType) { + super(parent, false); + myFileType = fileType; + myEditor = fileType.getEditor(); + init(); + } + + protected void init() { + super.init(); + myEditor.resetFrom(myFileType); + } + + protected JComponent createCenterPanel() { + return myEditor.getComponent(); + } + + protected void doOKAction() { + try { + myEditor.applyTo(myFileType); + } + catch (ConfigurationException e) { + Messages.showErrorDialog(getContentPane(), e.getMessage(), e.getTitle()); + return; + } + super.doOKAction(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java new file mode 100644 index 00000000000..e800588941e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -0,0 +1,811 @@ +package com.intellij.openapi.fileTypes.impl; + +import com.intellij.ide.highlighter.*; +import com.intellij.ide.highlighter.custom.SyntaxTable; +import com.intellij.ide.highlighter.custom.impl.CustomFileType; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.fileTypes.ex.FakeFileType; +import com.intellij.openapi.fileTypes.ex.FileTypeChooser; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.ArrayUtil; +import com.intellij.util.EventDispatcher; +import com.intellij.util.PatternUtil; +import com.intellij.util.UniqueFileNamesProvider; +import com.intellij.util.containers.HashSet; +import gnu.trove.THashMap; +import gnu.trove.THashSet; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import javax.swing.*; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.*; +import java.util.regex.Pattern; + +/** + * @author Yura Cangea + */ +public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOMExternalizable, ExportableApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl"); + + private final Set myDefaultTypes = new THashSet(); + private SetWithArray myFileTypes = new SetWithArray(new THashSet()); + private final ArrayList mySpecialFileTypes = new ArrayList(); + private final ArrayList myIgnorePatterns = new ArrayList(); + + private Map myExtToFileTypeMap = new HashMap(); + private final Set myIgnoredFileMasksSet = new LinkedHashSet(); + private final THashSet myNotIgnoredFiles = new THashSet(); + private final THashSet myIgnoredFiles = new THashSet(); + private final EventDispatcher myDispatcher = EventDispatcher.create(FileTypeListener.class); + private final THashMap myDefaultTables = new THashMap(); + + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- + + public FileTypeManagerImpl() { + registerStandardFileTypes(); + loadAllFileTypes(); + } + + public File[] getExportFiles() { + return new File[]{getFileTypesDir(true), PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "File types"; + } + // ------------------------------------------------------------------------- + // ApplicationComponent interface implementation + // ------------------------------------------------------------------------- + + public void disposeComponent() { + } + + public void initComponent() { + } + + public void save() { + try { + saveAllFileTypes(); + } + catch (IOException e) { + Messages.showErrorDialog("Can't save file types: " + e.getLocalizedMessage(), "Error Saving Settings"); + } + } + + // ------------------------------------------------------------------------- + // Implementation of abstract methods + // ------------------------------------------------------------------------- + + public FileType getFileTypeByFileName(String fileName) { + String ext = getExtension(fileName); + return getFileTypeByExtension(ext); + } + + public FileType getFileTypeByFile(VirtualFile file) { + // first let file recognize its type + for (int i = 0; i < mySpecialFileTypes.size(); i++) { + FakeFileType fileType = mySpecialFileTypes.get(i); + if (fileType.isMyFileType(file)) return fileType; + } + + String extension = file.getExtension(); + if (extension == null) extension = ""; + return getFileTypeByExtension(extension); + } + + public FileType getFileTypeByExtension(String extension) { + FileType type = myExtToFileTypeMap.get(extension); + if (type != null) return type; + type = myExtToFileTypeMap.get(extension.toLowerCase()); + return type == null ? StdFileTypes.UNKNOWN : type; + } + + public void registerFileType(FileType fileType) { + registerFileType(fileType, null); + } + + public void unregisterFileType(FileType fileType) { + fireBeforeFileTypesChanged(); + unregisterFileTypeWithoutNotification(fileType); + fireFileTypesChanged(); + } + + private void unregisterFileTypeWithoutNotification(FileType fileType) { + removeAllAssociations(fileType); + myFileTypes.remove(fileType); + if (fileType instanceof FakeFileType) { + mySpecialFileTypes.remove(fileType); + } + } + + public FileType[] getRegisteredFileTypes() { + return myFileTypes.toArray(); + } + + public String getExtension(String fileName) { + int index = fileName.lastIndexOf('.'); + if (index < 0) return ""; + return fileName.substring(index + 1); + } + + public String getIgnoredFilesList() { + StringBuffer sb = new StringBuffer(); + for (Iterator iterator = myIgnoredFileMasksSet.iterator(); iterator.hasNext();) { + String ignoreMask = iterator.next(); + sb.append(ignoreMask); + sb.append(';'); + } + return sb.toString(); + } + + public void setIgnoredFilesList(String list) { + fireBeforeFileTypesChanged(); + setIgnoredFilesListWithoutNotification(list); + + fireFileTypesChanged(); + } + + private void setIgnoredFilesListWithoutNotification(String list) { + myIgnoredFileMasksSet.clear(); + myIgnorePatterns.clear(); + + StringTokenizer tokenizer = new StringTokenizer(list, ";"); + while (tokenizer.hasMoreTokens()) { + String ignoredFile = tokenizer.nextToken(); + if (ignoredFile != null && !myIgnoredFileMasksSet.contains(ignoredFile)) { + if (!myIgnoredFileMasksSet.contains(ignoredFile)) { + myIgnorePatterns.add(PatternUtil.fromMask(ignoredFile)); + } + myIgnoredFileMasksSet.add(ignoredFile); + } + } + + //[mike] + //To make async delete work. See FileUtil.asyncDelete. + //Quite a hack, but still we need to have some name, which + //won't be catched by VF for sure. + Pattern p = Pattern.compile(".*\\.__del__"); + myIgnorePatterns.add(p); + } + + public boolean isIgnoredFilesListEqualToCurrent(String list) { + HashSet tempSet = new HashSet(); + StringTokenizer tokenizer = new StringTokenizer(list, ";"); + while (tokenizer.hasMoreTokens()) { + tempSet.add(tokenizer.nextToken()); + } + return tempSet.equals(myIgnoredFileMasksSet); + } + + public boolean isFileIgnored(String name) { + if (myNotIgnoredFiles.contains(name)) return false; + if (myIgnoredFiles.contains(name)) return true; + + for (Iterator iterator = myIgnorePatterns.iterator(); iterator.hasNext();) { + Pattern pattern = iterator.next(); + if (pattern.matcher(name).matches()) { + myIgnoredFiles.add(name); + return true; + } + } + + myNotIgnoredFiles.add(name); + return false; + } + + public String[] getAssociatedExtensions(FileType type) { + Map extMap = myExtToFileTypeMap; + return getAssociatedExtensions(extMap, type); + } + + private String[] getAssociatedExtensions(Map extMap, FileType type) { + List exts = new ArrayList(); + for (Iterator iterator = extMap.keySet().iterator(); iterator.hasNext();) { + String ext = iterator.next(); + if (extMap.get(ext) == type) { + exts.add(ext); + } + } + return exts.toArray(new String[exts.size()]); + } + + public void associateExtension(FileType type, String extension) { + associateExtension(type, extension, true); + } + + private void removeAllAssociations(FileType type) { + Set exts = myExtToFileTypeMap.keySet(); + String[] extsStrings = exts.toArray(new String[exts.size()]); + for (int i = 0; i < extsStrings.length; i++) { + String s = extsStrings[i]; + if (myExtToFileTypeMap.get(s) == type) myExtToFileTypeMap.remove(s); + } + } + + public void dispatchPendingEvents(FileTypeListener listener) { + myDispatcher.dispatchPendingEvent(listener); + } + + public void fireBeforeFileTypesChanged() { + FileTypeEvent event = new FileTypeEvent(this); + myDispatcher.getMulticaster().beforeFileTypesChanged(event); + } + + public void fireFileTypesChanged() { + myNotIgnoredFiles.clear(); + myIgnoredFiles.clear(); + + myDispatcher.getMulticaster().fileTypesChanged(new FileTypeEvent(this)); + } + + public void addFileTypeListener(FileTypeListener listener) { + myDispatcher.addListener(listener); + } + + public void removeFileTypeListener(FileTypeListener listener) { + myDispatcher.removeListener(listener); + } + + private void saveAllFileTypes() throws IOException { + File dir = getFileTypesDir(true); + if (dir == null) return; + + File[] files = getFileTypeFiles(); + + ArrayList filePaths = new ArrayList(); + ArrayList documents = new ArrayList(); + + UniqueFileNamesProvider namesProvider = new UniqueFileNamesProvider(); + Iterator iterator = myFileTypes.iterator(); + while (iterator.hasNext()) { + FileType fileType = iterator.next(); + + if (!(fileType instanceof CustomFileType) || shouldNotSave(fileType)) continue; + if (myDefaultTypes.contains(fileType) && !isDefaultModified(fileType)) continue; + + Element root = new Element("filetype"); + + writeHeader(root, fileType); + + writeSyntaxTableData(root, fileType); + + String name = namesProvider.suggestName(fileType.getName()); + String filePath = dir.getAbsolutePath() + File.separator + name + ".xml"; + filePaths.add(filePath); + documents.add(new Document(root)); + } + + JDOMUtil.updateFileSet(files, + filePaths.toArray(new String[filePaths.size()]), + documents.toArray(new Document[documents.size()]), CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + + private boolean isDefaultModified(FileType fileType) { + if (fileType instanceof CustomFileType) { + return !Comparing.equal(myDefaultTables.get(fileType), ((CustomFileType)fileType).getSyntaxTable()); + } + return true; //TODO? + } + + // ------------------------------------------------------------------------- + // Implementation of NamedExternalizable interface + // ------------------------------------------------------------------------- + + public String getExternalFileName() { + return "filetypes"; + } + + public void readExternal(Element parentNode) throws InvalidDataException { + for (Iterator iterator = parentNode.getChildren().iterator(); iterator.hasNext();) { + final Element e = (Element)iterator.next(); + if ("filetypes".equals(e.getName())) { + List children = e.getChildren("filetype"); + for (Iterator i = children.iterator(); i.hasNext();) { + Element element = (Element)i.next(); + loadFileType(element, true); + } + } + else if ("ignoreFiles".equals(e.getName())) { + setIgnoredFilesListWithoutNotification(e.getAttributeValue("list")); + } + else if ("extensionMap".equals(e.getName())) { + List mappings = e.getChildren("mapping"); + for (int i = 0; i < mappings.size(); i++) { + Element mapping = (Element)mappings.get(i); + String ext = mapping.getAttributeValue("ext"); + String name = mapping.getAttributeValue("type"); + FileType type = getFileTypeByName(name); + if (type != null) { + associateExtension(type, ext, false); + } + } + } + } + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + Element element = new Element("ignoreFiles"); + parentNode.addContent(element); + element.setAttribute("list", getIgnoredFilesList()); + Element map = new Element("extensionMap"); + parentNode.addContent(map); + for (Iterator iterator = myExtToFileTypeMap.keySet().iterator(); iterator.hasNext();) { + String ext = iterator.next(); + FileType type = myExtToFileTypeMap.get(ext); + if (type != null && !shouldNotSave(type)) { + Element mapping = new Element("mapping"); + mapping.setAttribute("ext", ext); + mapping.setAttribute("type", type.getName()); + map.addContent(mapping); + } + } + } + + // ------------------------------------------------------------------------- + // Helper methods + // ------------------------------------------------------------------------- + + private FileType getFileTypeByName(String name) { + Iterator itr = myFileTypes.iterator(); + while (itr.hasNext()) { + FileType fileType = itr.next(); + if (fileType.getName().equals(name)) return fileType; + } + return null; + } + + public void registerFileType(FileType type, String[] defaultAssociatedExtensions) { + fireBeforeFileTypesChanged(); + registerFileTypeWithoutNotification(type, defaultAssociatedExtensions); + fireFileTypesChanged(); + } + + private void registerStandardFileTypes() { + if (StdFileTypes.ARCHIVE != null) return; + registerFileTypeWithoutNotification(StdFileTypes.ARCHIVE = new ArchiveFileType(), parse("zip;jar;war;ear")); + registerFileTypeWithoutNotification(StdFileTypes.CLASS = new JavaClassFileType(), new String[] {"class"}); + registerFileTypeWithoutNotification(StdFileTypes.HTML = new HtmlFileType(), parse("html;htm;sht;shtm;shtml")); + registerFileTypeWithoutNotification(StdFileTypes.XHTML = new XHtmlFileType(), parse("xhtml")); + registerFileTypeWithoutNotification(StdFileTypes.JAVA = new JavaFileType(), new String[] {"java"}); + if (ApplicationManagerEx.getApplicationEx().isAspectJSupportEnabled()) { + registerFileTypeWithoutNotification(StdFileTypes.ASPECT = new AspectFileType(), new String[] {"aj"}); + } + registerFileTypeWithoutNotification(StdFileTypes.JSP = new JspFileType(), parse("jsf;jsp;jspf")); + registerFileTypeWithoutNotification(StdFileTypes.JSPX = new JspxFileType(), new String[] {"jspx"}); + registerFileTypeWithoutNotification(StdFileTypes.PLAIN_TEXT = new PlainTextFileType(), parse("txt;sh;bat;properties;cmd;policy;log;cgi;pl;MF;sql")); + registerFileTypeWithoutNotification(StdFileTypes.XML = new XmlFileType(), parse("xml;xsd;tld;xsl;jnlp;wsdl;hs;jhm")); + registerFileTypeWithoutNotification(StdFileTypes.DTD = new DTDFileType(), parse("dtd;ent")); + registerFileTypeWithoutNotification(StdFileTypes.GUI_DESIGNER_FORM = new GuiFormFileType(), new String[] {"form"}); + registerFileTypeWithoutNotification(StdFileTypes.IDEA_WORKSPACE = new WorkspaceFileType(), new String[] {"iws"}); + registerFileTypeWithoutNotification(StdFileTypes.IDEA_PROJECT = new ProjectFileType(), new String[]{"ipr"}); + registerFileTypeWithoutNotification(StdFileTypes.IDEA_MODULE = new ModuleFileType(), new String[]{"iml"}); + registerFileTypeWithoutNotification(StdFileTypes.UNKNOWN = new UnknownFileType(), null); + } + + private static String[] parse(String semicolonDelimited) { + if (semicolonDelimited == null) return ArrayUtil.EMPTY_STRING_ARRAY; + StringTokenizer tokenizer = new StringTokenizer(semicolonDelimited, ";", false); + ArrayList list = new ArrayList(); + while (tokenizer.hasMoreTokens()) { + list.add(tokenizer.nextToken().trim()); + } + return list.toArray(new String[list.size()]); + } + + /** + * Registers a standard file type. Doesn't notifyListeners any change events. + */ + private void registerFileTypeWithoutNotification(FileType fileType, String[] extensions) { + myFileTypes.add(fileType); + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + String extension = extensions[i]; + if (myExtToFileTypeMap.containsKey(extension)) { + LOG.info("Extension '" + extension + "' is already registered to " + myExtToFileTypeMap.get(extension)); + } + else { + myExtToFileTypeMap.put(extension, fileType); + } + } + } + if (fileType instanceof FakeFileType) { + mySpecialFileTypes.add((FakeFileType)fileType); + } + } + + private File[] getFileTypeFiles() { + File fileTypesDir = getFileTypesDir(true); + if (fileTypesDir == null) return new File[0]; + + File[] files = fileTypesDir.listFiles(new FileFilter() { + public boolean accept(File file) { + return !file.isDirectory() && file.getName().toLowerCase().endsWith(".xml"); + } + }); + if (files == null) { + LOG.error("Cannot read directory: " + fileTypesDir.getAbsolutePath()); + return new File[0]; + } +// return files; + ArrayList fileList = new ArrayList(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (!file.isDirectory()) { + fileList.add(file); + } + } + return fileList.toArray(new File[fileList.size()]); + } + + private void loadAllFileTypes() { + File[] files = getFileTypeFiles(); + for (int i = 0; i < files.length; i++) { + try { + loadFileType(files[i]); + } + catch (JDOMException e) { + } + catch (InvalidDataException e) { + } + catch (IOException e) { + } + } + } + + private FileType loadFileType(File file) throws JDOMException, InvalidDataException, IOException { + Document document = JDOMUtil.loadDocument(file); + if (document == null) { + throw new InvalidDataException(); + } + Element root = document.getRootElement(); + if (root == null || !"filetype".equals(root.getName())) { + throw new InvalidDataException(); + } + return loadFileType(root, false); + } + + private FileType loadFileType(Element typeElement, boolean isDefaults) { + String fileTypeName = typeElement.getAttributeValue("name"); + String fileTypeDescr = typeElement.getAttributeValue("description"); + String defaultExtension = typeElement.getAttributeValue("default_extension"); + String iconPath = typeElement.getAttributeValue("icon"); + boolean isBinary = Boolean.valueOf(typeElement.getAttributeValue("binary")).booleanValue(); + String extensionsStr = typeElement.getAttributeValue("extensions"); + + SyntaxTable table = null; + Element element = typeElement.getChild("highlighting"); + if (element != null) { + table = readSyntaxTable(element); + } + + FileType type = getFileTypeByName(fileTypeName); + String[] exts = parse(extensionsStr); + if (type != null) { + if (extensionsStr != null) { + removeAllAssociations(type); + for (int i = 0; i < exts.length; i++) { + associateExtension(type, exts[i], false); + } + } + + if (table != null) { + ((CustomFileType)type).setSyntaxTable(table); + } + } + else { + if (table != null) { + type = new CustomFileType(table); + ((CustomFileType)type).initSupport(); + } + else { + type = new UserBinaryFileType(); + } + registerFileTypeWithoutNotification(type, exts); + } + + if (type instanceof UserFileType) { + UserFileType ft = (UserFileType)type; + if (iconPath != null && !"".equals(iconPath.trim())) { + Icon icon = IconLoader.getIcon(iconPath); + if (icon != null) ft.setIcon(icon); + } + + if (fileTypeDescr != null) ft.setDescription(fileTypeDescr); + if (fileTypeName != null) ft.setName(fileTypeName); + } + + if (isDefaults) { + myDefaultTypes.add(type); + if (table != null) { + myDefaultTables.put(type, table); + } + } + + return type; + } + + private SyntaxTable readSyntaxTable(Element root) { + SyntaxTable table = new SyntaxTable(); + + for (Iterator iterator = root.getChildren().iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + + if ("options".equals(element.getName())) { + for (Iterator i = element.getChildren("option").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + String name = e.getAttributeValue("name"); + String value = e.getAttributeValue("value"); + if ("LINE_COMMENT".equals(name)) { + table.setLineComment(value); + } + else if ("COMMENT_START".equals(name)) { + table.setStartComment(value); + } + else if ("COMMENT_END".equals(name)) { + table.setEndComment(value); + } + else if ("HEX_PREFIX".equals(name)) { + table.setHexPrefix(value); + } + else if ("NUM_POSTFIXES".equals(name)) { + table.setNumPostfixChars(value); + } else if ("HAS_BRACES".equals(name)) { + table.setHasBraces(Boolean.valueOf(value).booleanValue()); + } else if ("HAS_BRACKETS".equals(name)) { + table.setHasBrackets(Boolean.valueOf(value).booleanValue()); + } else if ("HAS_PARENS".equals(name)) { + table.setHasParens(Boolean.valueOf(value).booleanValue()); + } + } + } + else if ("keywords".equals(element.getName())) { + boolean ignoreCase = Boolean.valueOf(element.getAttributeValue("ignore_case")).booleanValue(); + table.setIgnoreCase(ignoreCase); + for (Iterator i = element.getChildren("keyword").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + table.addKeyword1(e.getAttributeValue("name")); + } + } + else if ("keywords2".equals(element.getName())) { + for (Iterator i = element.getChildren("keyword").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + table.addKeyword2(e.getAttributeValue("name")); + } + } + else if ("keywords3".equals(element.getName())) { + for (Iterator i = element.getChildren("keyword").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + table.addKeyword3(e.getAttributeValue("name")); + } + } + else if ("keywords4".equals(element.getName())) { + for (Iterator i = element.getChildren("keyword").iterator(); i.hasNext();) { + Element e = (Element)i.next(); + table.addKeyword4(e.getAttributeValue("name")); + } + } + } + + return table; + } + + private File getFileTypesDir(boolean create) { + String directoryPath = PathManager.getConfigPath() + File.separator + "filetypes"; + File directory = new File(directoryPath); + if (!directory.exists()) { + if (!create) return null; + if (!directory.mkdir()) { + LOG.error("Could not create directory: " + directory.getAbsolutePath()); + return null; + } + } + return directory; + } + + private boolean shouldNotSave(FileType fileType) { + return fileType == StdFileTypes.UNKNOWN || fileType.isReadOnly(); + } + + private void writeHeader(Element root, FileType fileType) { + root.setAttribute("binary", String.valueOf(fileType.isBinary())); + final String defaultExtension = fileType.getDefaultExtension(); + if (defaultExtension != null) { + root.setAttribute("default_extension", defaultExtension); + } + + root.setAttribute("description", fileType.getDescription()); + root.setAttribute("name", fileType.getName()); + } + + private void writeSyntaxTableData(Element root, FileType fileType) { + if (!(fileType instanceof CustomFileType)) return; + + SyntaxTable table = ((CustomFileType)fileType).getSyntaxTable(); + Element highlightingElement = new Element("highlighting"); + + Element optionsElement = new Element("options"); + + Element lineComment = new Element("option"); + lineComment.setAttribute("name", "LINE_COMMENT"); + lineComment.setAttribute("value", table.getLineComment()); + optionsElement.addContent(lineComment); + + Element commentStart = new Element("option"); + commentStart.setAttribute("name", "COMMENT_START"); + commentStart.setAttribute("value", table.getStartComment()); + optionsElement.addContent(commentStart); + + Element commentEnd = new Element("option"); + commentEnd.setAttribute("name", "COMMENT_END"); + commentEnd.setAttribute("value", table.getEndComment()); + optionsElement.addContent(commentEnd); + + Element hexPrefix = new Element("option"); + hexPrefix.setAttribute("name", "HEX_PREFIX"); + hexPrefix.setAttribute("value", table.getHexPrefix()); + optionsElement.addContent(hexPrefix); + + Element numPostfixes = new Element("option"); + numPostfixes.setAttribute("name", "NUM_POSTFIXES"); + numPostfixes.setAttribute("value", table.getNumPostfixChars()); + optionsElement.addContent(numPostfixes); + + Element supportBraces = new Element("option"); + supportBraces.setAttribute("name", "HAS_BRACES"); + supportBraces.setAttribute("value", String.valueOf(table.isHasBraces())); + optionsElement.addContent(supportBraces); + + Element supportBrackets = new Element("option"); + supportBrackets.setAttribute("name", "HAS_BRACKETS"); + supportBrackets.setAttribute("value", String.valueOf(table.isHasBrackets())); + optionsElement.addContent(supportBrackets); + + Element supportParens = new Element("option"); + supportParens.setAttribute("name", "HAS_PARENS"); + supportParens.setAttribute("value", String.valueOf(table.isHasParens())); + optionsElement.addContent(supportParens); + + highlightingElement.addContent(optionsElement); + + Element keywordsElement = new Element("keywords"); + keywordsElement.setAttribute("ignore_case", String.valueOf(table.isIgnoreCase())); + writeKeywords(table.getKeywords1(), keywordsElement); + highlightingElement.addContent(keywordsElement); + + Element keywordsElement2 = new Element("keywords2"); + writeKeywords(table.getKeywords2(), keywordsElement2); + highlightingElement.addContent(keywordsElement2); + + Element keywordsElement3 = new Element("keywords3"); + writeKeywords(table.getKeywords3(), keywordsElement3); + highlightingElement.addContent(keywordsElement3); + + Element keywordsElement4 = new Element("keywords4"); + writeKeywords(table.getKeywords4(), keywordsElement4); + highlightingElement.addContent(keywordsElement4); + + root.addContent(highlightingElement); + } + + private void writeKeywords(Set keywords, Element keywordsElement) { + Iterator iterator = keywords.iterator(); + while (iterator.hasNext()) { + Element e = new Element("keyword"); + e.setAttribute("name", (String)iterator.next()); + keywordsElement.addContent(e); + } + } + + // ------------------------------------------------------------------------- + // Setup + // ------------------------------------------------------------------------- + + public String getComponentName() { + return "FileTypeManager"; + } + + public Map getExtensionMap() { + return myExtToFileTypeMap; + } + + public void setExtensionMap(Set fileTypes, Map extension2TypeMap) { + fireBeforeFileTypesChanged(); + myFileTypes = new SetWithArray(fileTypes); + myExtToFileTypeMap = new HashMap(extension2TypeMap.size()); + for (Iterator it = extension2TypeMap.keySet().iterator(); it.hasNext();) { + final String ext = it.next(); + associateExtension(extension2TypeMap.get(ext), ext, false); + } + fireFileTypesChanged(); + } + + private static class SetWithArray { + private final Set mySet; + private FileType[] myArray; + + public SetWithArray(Set set) { + mySet = set; + } + + public void add(FileType element) { + myArray = null; + mySet.add(element); + } + + public void remove(FileType element) { + myArray = null; + mySet.remove(element); + } + + public Iterator iterator() { + final Iterator iterator = mySet.iterator(); + return new Iterator() { + public boolean hasNext() { + return iterator.hasNext(); + } + + public FileType next() { + return iterator.next(); + } + + public void remove() { + myArray = null; + iterator.remove(); + } + }; + } + + public FileType[] toArray() { + if (myArray == null) myArray = mySet.toArray(new FileType[mySet.size()]); + FileType[] array = new FileType[myArray.length]; + System.arraycopy(myArray, 0, array, 0, array.length); + return array; + } + } + + public void associateExtension(FileType fileType, String extension, boolean fireChange){ + //if ("".equals(extension)) { + // return; // do not allow empty extensions + //} + final String lowercasedExtension = extension.toLowerCase(); + if (myExtToFileTypeMap.get(lowercasedExtension) != fileType){ + if (fireChange) { + fireBeforeFileTypesChanged(); + } + myExtToFileTypeMap.put(lowercasedExtension, fileType); + if (fireChange){ + fireFileTypesChanged(); + } + } + } + + public void removeAssociation(FileType fileType, String extension, boolean fireChange){ + final String lowercasedExtension = extension.toLowerCase(); + if (myExtToFileTypeMap.get(lowercasedExtension) == fileType){ + if (fireChange) { + fireBeforeFileTypesChanged(); + } + myExtToFileTypeMap.remove(lowercasedExtension); + if (fireChange){ + fireFileTypesChanged(); + } + } + } + public FileType getKnownFileTypeOrAssociate(VirtualFile file) { + return FileTypeChooser.getKnownFileTypeOrAssociate(file); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeRenderer.java new file mode 100644 index 00000000000..aeef4fcafa7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/fileTypes/impl/FileTypeRenderer.java @@ -0,0 +1,27 @@ +package com.intellij.openapi.fileTypes.impl; + +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; + +import javax.swing.*; +import java.awt.*; + +public class FileTypeRenderer extends DefaultListCellRenderer { + public FileTypeRenderer() { + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + FileType type = (FileType)value; + setIcon(type.getIcon()); + String description = type.getDescription(); + if (description != null) { + setText(description); + } + return this; + } + + public Dimension getPreferredSize() { + return new Dimension(0, 20); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerEx.java new file mode 100644 index 00000000000..72e8ce1c27e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerEx.java @@ -0,0 +1,22 @@ +package com.intellij.openapi.keymap.ex; + +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; + +public abstract class KeymapManagerEx extends KeymapManager { + public static KeymapManagerEx getInstanceEx(){ + return (KeymapManagerEx)getInstance(); + } + + /** + * @return all available keymaps. The method return an aempty array if no + * keymaps are available. + */ + public abstract Keymap[] getAllKeymaps(); + + public abstract void addKeymapManagerListener(KeymapManagerListener listener); + + public abstract void removeKeymapManagerListener(KeymapManagerListener listener); + + public abstract void setActiveKeymap(Keymap activeKeymap); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerListener.java new file mode 100644 index 00000000000..52033e64a7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/KeymapManagerListener.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.keymap.ex; + +import com.intellij.openapi.keymap.Keymap; + +public interface KeymapManagerListener { + void activeKeymapChanged(Keymap keymap); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/WeakKeymapManagerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/WeakKeymapManagerListener.java new file mode 100644 index 00000000000..1d82a96325f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/ex/WeakKeymapManagerListener.java @@ -0,0 +1,24 @@ +package com.intellij.openapi.keymap.ex; + +import com.intellij.openapi.keymap.Keymap; + +import java.lang.ref.WeakReference; + +public final class WeakKeymapManagerListener implements KeymapManagerListener{ + private KeymapManagerEx myKeymapManager; + private WeakReference myRef; + + public WeakKeymapManagerListener(KeymapManagerEx keymapManager,KeymapManagerListener delegate){ + myKeymapManager=keymapManager; + myRef=new WeakReference(delegate); + } + + public void activeKeymapChanged(Keymap keymap){ + KeymapManagerListener delegate=(KeymapManagerListener)myRef.get(); + if(delegate!=null){ + delegate.activeKeymapChanged(keymap); + }else{ + myKeymapManager.removeKeymapManagerListener(this); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/Converter01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/Converter01.java new file mode 100644 index 00000000000..d39f1aa3e0f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/Converter01.java @@ -0,0 +1,109 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +public class Converter01{ + /** + * Converts keymap from version "0" (no version specified) + * to version "1". + * @param keymapElement XML element that corresponds to "keymap" tag. + */ + public static void convert(Element keymapElement) throws InvalidDataException{ + if(!"keymap".equals(keymapElement.getName())){ + throw new IllegalArgumentException("unknown element: "+keymapElement); + } + String version=keymapElement.getAttributeValue("version"); + if(version!=null){ + throw new InvalidDataException("unknown version: "+version); + } + + // Add version + + keymapElement.setAttribute("version",Integer.toString(1)); + + // disableMnemonics -> disable-mnemonics + + boolean disableMnemonics=Boolean.valueOf("disableMnemonics").booleanValue(); + keymapElement.removeAttribute("disableMnemonics"); + keymapElement.setAttribute("disable-mnemonics",Boolean.toString(disableMnemonics)); + + // Now we have to separate all shortcuts by action's ID and convert binding to keyboard-shortcut + + String name=keymapElement.getAttributeValue("name"); + if(name==null){ + throw new InvalidDataException("Attribute 'name' of must be specified"); + } + HashMap id2elements=new HashMap(); + + for(Iterator i=keymapElement.getChildren().iterator();i.hasNext();){ + Element oldChild=(Element)i.next(); + if("binding".equals(oldChild.getName())){ // binding -> keyboard-shortcut + // Remove attribute "id" + String id=oldChild.getAttributeValue("id"); + if(id==null){ + throw new InvalidDataException("attribute 'id' must be specified"); + } + // keystroke -> first-keystroke + String keystroke=oldChild.getAttributeValue("keystroke"); + // suffix -> second-keystroke + String suffix=oldChild.getAttributeValue("suffix"); + if(keystroke!=null){ + Element newChild=new Element("keyboard-shortcut"); + newChild.setAttribute("first-keystroke",keystroke); + if(suffix!=null){ + newChild.setAttribute("second-keystroke",suffix); + } + // Put new child into the map + ArrayList elements=(ArrayList)id2elements.get(id); + if(elements==null){ + elements=new ArrayList(2); + id2elements.put(id,elements); + } + elements.add(newChild); + }else{ + id2elements.put(id,new ArrayList(0)); + } + // Remove old child + i.remove(); + }else if("mouse-shortcut".equals(oldChild.getName())){ + // Remove attribute "id" + String id=oldChild.getAttributeValue("id"); + if(id==null){ + throw new InvalidDataException("Attribute 'id' of must be specified; keymap name="+name); + } + oldChild.removeAttribute("id"); + // Remove old child + i.remove(); + // Put new child into the map + ArrayList elements=(ArrayList)id2elements.get(id); + if(elements==null){ + elements=new ArrayList(2); + id2elements.put(id,elements); + } + elements.add(oldChild); + }else{ + throw new InvalidDataException("unknown element : "+oldChild.getName()); + } + } + + for(Iterator i=id2elements.keySet().iterator();i.hasNext();){ + String id=(String)i.next(); + Element actionElement=new Element("action"); + actionElement.setAttribute("id",id); + ArrayList elements=(ArrayList)id2elements.get(id); + for(Iterator j=elements.iterator();j.hasNext();){ + Element newChild=(Element)j.next(); + actionElement.addContent(newChild); + } + keymapElement.addContent(actionElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymap.java new file mode 100644 index 00000000000..0905fbfbcef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymap.java @@ -0,0 +1,62 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author Eugene Belyaev + */ +public class DefaultKeymap implements JDOMExternalizable, ApplicationComponent { + + private ArrayList myKeymaps = new ArrayList(); + + public static DefaultKeymap getInstance() { + return ApplicationManager.getApplication().getComponent(DefaultKeymap.class); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void readExternal(Element element) throws InvalidDataException{ + myKeymaps = new ArrayList(); + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + Element child=(Element)i.next(); + if ("keymap".equals(child.getName())) { + String keymapName = child.getAttributeValue("name"); + DefaultKeymapImpl keymap = KeymapManager.MAC_OS_X_KEYMAP.equals(keymapName) + ? new MacOSDefaultKeymap() + : new DefaultKeymapImpl(); + keymap.readExternal(child, myKeymaps.toArray(new Keymap[myKeymaps.size()])); + keymap.setName(keymapName); + myKeymaps.add(keymap); + } + } + } + + /** + * We override this method to disable saving the keymap. + */ + public void writeExternal(Element element) throws WriteExternalException{ + throw new WriteExternalException(); + } + + public Keymap[] getKeymaps() { + return myKeymaps.toArray(new Keymap[myKeymaps.size()]); + } + + public String getComponentName() { + return "DefaultKeymap"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymapImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymapImpl.java new file mode 100644 index 00000000000..1a86a67f873 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/DefaultKeymapImpl.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.openapi.keymap.KeymapManager; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 21, 2003 + * Time: 9:00:35 PM + * To change this template use Options | File Templates. + */ +class DefaultKeymapImpl extends KeymapImpl { + public boolean canModify() { + return false; + } + + public String getPresentableName() { + String name = getName(); + return KeymapManager.DEFAULT_IDEA_KEYMAP.equals(name) ? "Default" : name; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java new file mode 100644 index 00000000000..93a021ba545 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -0,0 +1,398 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.impl.PresentationFactory; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.keymap.impl.ui.KeyboardShortcutDialog; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.impl.FloatingDecorator; +import com.intellij.openapi.wm.impl.IdeFrame; + +import javax.swing.*; +import javax.swing.plaf.basic.ComboPopup; +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * This class is automaton with finite number of state. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IdeKeyEventDispatcher { + private static final int STATE_INIT = 0; + private static final int STATE_WAIT_FOR_SECOND_KEYSTROKE = 1; + private static final int STATE_SECOND_STROKE_IN_PROGRESS = 2; + private static final int STATE_PROCESSED = 3; + + private KeyStroke myFirstKeyStroke; + /** + * When we "dispatch" key event via keymap, i.e. when registered action has been executed + * instead of event dispatching, then we have to consume all following KEY_RELEASED and + * KEY_TYPED event because they are not valid. + */ + private boolean myPressedWasProcessed; + private int myState; + + private final ArrayList myActions; + private final PresentationFactory myPresentationFactory; + private JComponent myFoundComponent; + + public IdeKeyEventDispatcher(){ + myState=STATE_INIT; + myActions=new ArrayList(); + myPresentationFactory=new PresentationFactory(); + } + + public boolean isWaitingForSecondKeyStroke(){ + return myState == STATE_WAIT_FOR_SECOND_KEYSTROKE; + } + + /** + * @return true if and only if the passed event is already dispatched by the + * IdeKeyEventDispatcher and there is no need for any other processing of the event. + */ + public boolean dispatchKeyEvent(final KeyEvent e){ + if(e.isConsumed()){ + return false; + } + + KeyboardFocusManager focusManager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); + Component focusOwner = focusManager.getFocusOwner(); + + // shortcuts should not work in shortcut setup fields + if (focusOwner instanceof KeyboardShortcutDialog.ShortcutTextField) { + return false; + } + + MenuSelectionManager menuSelectionManager=MenuSelectionManager.defaultManager(); + MenuElement[] selectedPath = menuSelectionManager.getSelectedPath(); + if(selectedPath.length>0){ + if (!(selectedPath[0] instanceof ComboPopup)) { + // The following couple of lines of code is a PATCH!!! + // It is needed to ignore ENTER KEY_TYPED events which sometimes can reach editor when an action + // is invoked from main menu via Enter key. + myState=STATE_PROCESSED; + myPressedWasProcessed=true; + return false; + } + } + + // Keymap shortcuts (i.e. not local shortcuts) should work only in: + // - main frame + // - floating focusedWindow + // - when there's an editor in contexts + Window focusedWindow = focusManager.getFocusedWindow(); + boolean isModalContext = focusedWindow != null && isModalContext(focusedWindow); + + DataContext dataContext = DataManager.getInstance().getDataContext(); + + if (myState == STATE_INIT) { + return inInitState(focusOwner, e, isModalContext, dataContext); + } else if (myState == STATE_PROCESSED) { + return inProcessedState(focusOwner, e, isModalContext, dataContext); + } else if (myState == STATE_WAIT_FOR_SECOND_KEYSTROKE) { + return inWaitForSecondStrokeState(e, isModalContext, dataContext); + } else if (myState == STATE_SECOND_STROKE_IN_PROGRESS) { + return inSecondStrokeInProgressState(e, isModalContext, dataContext); + } else { + throw new IllegalStateException("state = " + myState); + } + } + + /** + * @return true if and only if the component represents + * modal context. + * @throws java.lang.IllegalArgumentException if component is null. + */ + public static boolean isModalContext(Component component) { + if(component==null){ + throw new IllegalArgumentException("component cannot be null"); + } + Window window; + if (component instanceof Window) { + window = (Window)component; + } else { + window = SwingUtilities.getWindowAncestor(component); + } + boolean isMainFrame = window instanceof IdeFrame; + boolean isFloatingDecorator = window instanceof FloatingDecorator; + return !isMainFrame && !isFloatingDecorator; + } + + private boolean inWaitForSecondStrokeState(KeyEvent e, boolean isModalContext, DataContext dataContext) { + // a key pressed means that the user starts to enter the second stroke... + if (KeyEvent.KEY_PRESSED==e.getID()) { + myState=STATE_SECOND_STROKE_IN_PROGRESS; + return inSecondStrokeInProgressState(e, isModalContext, dataContext); + } + // looks like RELEASEs (from the first stroke) go here... skip them + return true; + } + + /** + * This is hack. AWT doesn't allow to create KeyStroke with specified key code and key char + * simultaneously. Therefore we are using reflection. + */ + private KeyStroke getKeyStrokeWithoutMouseModifiers(KeyStroke originalKeyStroke){ + int modifier=originalKeyStroke.getModifiers()&~InputEvent.BUTTON1_DOWN_MASK&~InputEvent.BUTTON1_MASK& + ~InputEvent.BUTTON2_DOWN_MASK&~InputEvent.BUTTON2_MASK& + ~InputEvent.BUTTON3_DOWN_MASK&~InputEvent.BUTTON3_MASK; + try { + Method[] methods=AWTKeyStroke.class.getDeclaredMethods(); + Method getCachedStrokeMethod=null; + for(int i=0;i> secondKeyStorkes = new ArrayList>(); + for (int i = 0; i < myActions.size(); i++) { + AnAction action = myActions.get(i); + Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); + for (int j = 0; j < shortcuts.length; j++) { + Shortcut shortcut = shortcuts[j]; + if (shortcut instanceof KeyboardShortcut) { + KeyboardShortcut keyShortcut = (KeyboardShortcut)shortcut; + if (keyShortcut.getFirstKeyStroke().equals(myFirstKeyStroke)) { + secondKeyStorkes.add(new Pair(action, keyShortcut.getSecondKeyStroke())); + } + } + } + } + + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + StringBuffer message = new StringBuffer(); + message.append("Prefix Key Pressed. "); + for (int i = 0; i < secondKeyStorkes.size(); i++) { + Pair pair = secondKeyStorkes.get(i); + if (i > 0) message.append(", "); + message.append(pair.getFirst().getTemplatePresentation().getText()); + message.append(" ("); + message.append(KeymapUtil.getKeystrokeText(pair.getSecond())); + message.append(")"); + } + + WindowManager.getInstance().getStatusBar(project).setInfo(message.toString()); + myState=STATE_WAIT_FOR_SECOND_KEYSTROKE; + return true; + }else{ + if (processAction(e, dataContext)) { + return true; + } else { + return false; + } + } + } + + private boolean processAction(final KeyEvent e, DataContext dataContext) { + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + for (int i=0; i < myActions.size(); i++) { + final AnAction action = myActions.get(i); + final Presentation presentation = myPresentationFactory.getPresentation(action); + + // Mouse modifiers are 0 because they have no any sense when action is invoked via keyboard + final AnActionEvent actionEvent = new AnActionEvent(e, dataContext, ActionPlaces.MAIN_MENU, presentation, + ActionManager.getInstance(), + 0); + + action.update(actionEvent); + if (!presentation.isEnabled()) { + continue; + } + + myState = STATE_PROCESSED; + myPressedWasProcessed = e.getID() == KeyEvent.KEY_PRESSED; + + ((DataManagerImpl.MyDataContext)dataContext).setEventCount(IdeEventQueue.getInstance().getEventCount()); + actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext()); + Component component = ((Component)actionEvent.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT)); + if (component != null && !component.isShowing()) { + return true; + } + action.actionPerformed(actionEvent); + return true; + } + + return false; + } + + /** + * This method fills myActions list. + * @return true if there is a shortcut with second stroke found. + */ + private boolean fillActionsList(Component component, KeyStroke firstKeyStroke, KeyStroke secondKeyStroke, boolean isModalContext){ + myFoundComponent = null; + myActions.clear(); + + boolean hasSecondStroke = false; + + // here we try to find "local" shortcuts + + for (; component != null; component = component.getParent()) { + if (!(component instanceof JComponent)) { + continue; + } + ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); + if (listOfActions == null) { + continue; + } + for (int i=0; i < listOfActions.size(); i++) { + Object o = listOfActions.get(i); + if (!(o instanceof AnAction)) { + continue; + } + AnAction action = (AnAction)o; + hasSecondStroke |= addAction(action, firstKeyStroke, secondKeyStroke); + } + // once we've found a proper local shortcut(s), we continue with non-local shortcuts + if (myActions.size() > 0) { + myFoundComponent = (JComponent)component; + break; + } + } + + // search in main keymap + + String[] actionIds; + Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + if (secondKeyStroke == null) { + actionIds = keymap.getActionIds(firstKeyStroke); + } + else { + actionIds = keymap.getActionIds(firstKeyStroke, secondKeyStroke); + } + + ActionManager actionManager = ActionManager.getInstance(); + for (int i = 0; i < actionIds.length; i++) { + String actionId = actionIds[i]; + AnAction action = actionManager.getAction(actionId); + if (action != null){ + if (isModalContext && !action.isEnabledInModalContext()){ + continue; + } + hasSecondStroke |= addAction(action, firstKeyStroke, secondKeyStroke); + } + } + return hasSecondStroke; + } + + /** + * @return true if action is added and has second stroke + */ + private boolean addAction(AnAction action, KeyStroke firstKeyStroke, KeyStroke secondKeyStroke) { + boolean hasSecondStroke = false; + + Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); + for (int j = 0; j < shortcuts.length; j++) { + Shortcut shortcut = shortcuts[j]; + if (!(shortcut instanceof KeyboardShortcut)) { + continue; + } + KeyboardShortcut keyboardShortcut = (KeyboardShortcut)shortcut; + if ( + firstKeyStroke.equals(keyboardShortcut.getFirstKeyStroke()) && + (secondKeyStroke == null || secondKeyStroke.equals(keyboardShortcut.getSecondKeyStroke())) + ) { + if (!myActions.contains(action)) { + myActions.add(action); + } + + if (keyboardShortcut.getSecondKeyStroke() != null) { + hasSecondStroke = true; + } + } + } + + return hasSecondStroke; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java new file mode 100644 index 00000000000..c402bf39845 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -0,0 +1,126 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.impl.PresentationFactory; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +/** + * TODO[vova] rewrite comments + * Current implementation of the dispatcher is intended to filter mouse event addressed to + * the editor. Also it allows to map middle mouse's button to some action. + * + * @author Vladimir Kondratyev + */ +public final class IdeMouseEventDispatcher{ + private final PresentationFactory myPresentationFactory; + private final ArrayList myActions; + + public IdeMouseEventDispatcher(){ + myPresentationFactory=new PresentationFactory(); + myActions=new ArrayList(1); + } + + private void fillActionsList(Component component,MouseShortcut shortcut,boolean isModalContext){ + myActions.clear(); + + // here we try to find "local" shortcuts + + if(component instanceof JComponent){ + ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); + if (listOfActions != null) { + for (int i=0; i < listOfActions.size(); i++) { + AnAction action = (AnAction)listOfActions.get(i); + Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); + for (int j = 0; j < shortcuts.length; j++) { + if(shortcut.equals(shortcuts[j]) && !myActions.contains(action)){ + myActions.add(action); + } + } + } + // once we've found a proper local shortcut(s), we exit + if (myActions.size() > 0) { + return; + } + } + } + + // search in main keymap + + Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + String[] actionIds=keymap.getActionIds(shortcut); + + ActionManager actionManager = ActionManager.getInstance(); + for (int i = 0; i < actionIds.length; i++) { + String actionId = actionIds[i]; + AnAction action = actionManager.getAction(actionId); + if (action == null){ + continue; + } + if (isModalContext && !action.isEnabledInModalContext()){ + continue; + } + if (!myActions.contains(action)) { + myActions.add(action); + } + } + } + + /** + * @return true if and only if the passed event is already dispatched by the + * IdeMouseEventDispatcher and there is no need for any other processing of the event. + * If the method returns false then it means that the event should be delivered + * to normal event dispatching. + */ + public boolean dispatchMouseEvent(MouseEvent e){ + if( + e.isConsumed()|| + e.isPopupTrigger()|| + MouseEvent.MOUSE_RELEASED!=e.getID()|| + e.getClickCount()<1 ||// TODO[vova,anton] is it possible. it seems that yes! but how??? + e.getButton() == MouseEvent.NOBUTTON // See #16995. It did happen + ){ + return false; + } + + Component component=e.getComponent(); + if(component==null){ + throw new IllegalStateException("component cannot be null"); + } + component=SwingUtilities.getDeepestComponentAt(component,e.getX(),e.getY()); + if(component==null){ // do nothing if component doesn't contains specified point + return false; + } + + MouseShortcut shortcut=new MouseShortcut(e.getButton(),e.getModifiersEx(),e.getClickCount()); + fillActionsList(component,shortcut,IdeKeyEventDispatcher.isModalContext(component)); + ActionManagerEx actionManager=ActionManagerEx.getInstanceEx(); + for(int i=0;igetKeystroke2ListOfIds. + */ + private THashMap myKeystroke2ListOfIds = null; + // TODO[vova,anton] it should be final member + + /** + * Don't use this field directly! Use it only through getMouseShortcut2ListOfIds. + */ + private THashMap myMouseShortcut2ListOfIds = null; + // TODO[vova,anton] it should be final member + + private static HashMap ourNamesForKeycodes = null; + private static final Shortcut[] ourEmptyShortcutsArray = new Shortcut[0]; + private final ArrayList myListeners = new ArrayList(); + + static { + ourNamesForKeycodes = new HashMap(); + try { + Field[] fields = KeyEvent.class.getDeclaredFields(); + for(int i = 0; i < fields.length; i++){ + Field field = fields[i]; + String fieldName = field.getName(); + if(fieldName.startsWith("VK_")) { + int keyCode = field.getInt(KeyEvent.class); + ourNamesForKeycodes.put(new Integer(keyCode), fieldName.substring(3)); + } + } + } + catch (Exception e) { + LOG.error(e); + } + } + + public String getName() { + return myName; + } + + public String getPresentableName() { + return getName(); + } + + public void setName(String name) { + myName = name; + } + + + public KeymapImpl deriveKeymap() { + if (!canModify()) { + KeymapImpl newKeymap = new KeymapImpl(); + + newKeymap.myParent = this; + newKeymap.myName = null; + newKeymap.myDisableMnemonics = myDisableMnemonics; + newKeymap.myCanModify = canModify(); + return newKeymap; + } + else { + return copy(); + } + } + + public KeymapImpl copy() { + KeymapImpl newKeymap = new KeymapImpl(); + newKeymap.myParent = myParent; + newKeymap.myName = myName; + newKeymap.myDisableMnemonics = myDisableMnemonics; + newKeymap.myCanModify = canModify(); + + newKeymap.myKeystroke2ListOfIds = null; + newKeymap.myMouseShortcut2ListOfIds = null; + + THashMap actionsIdsToListOfShortcuts = new THashMap(); + for(Iterator i=myActionId2ListOfShortcuts.keySet().iterator();i.hasNext();){ + Object key = i.next(); + ArrayList list = (ArrayList)myActionId2ListOfShortcuts.get(key); + actionsIdsToListOfShortcuts.put(key, list.clone()); + } + + newKeymap.myActionId2ListOfShortcuts = actionsIdsToListOfShortcuts; + + return newKeymap; + } + + public boolean equals(Object object) { + if (!(object instanceof Keymap)) return false; + KeymapImpl secondKeymap = (KeymapImpl)object; + if (!Comparing.equal(myName, secondKeymap.myName)) return false; + if (myDisableMnemonics != secondKeymap.myDisableMnemonics) return false; + if (myCanModify != secondKeymap.myCanModify) return false; + if (!Comparing.equal(myParent, secondKeymap.myParent)) return false; + if (!Comparing.equal(myActionId2ListOfShortcuts, secondKeymap.myActionId2ListOfShortcuts)) return false; + return true; + } + + public int hashCode(){ + int hashCode=0; + if(myName!=null){ + hashCode+=myName.hashCode(); + } + return hashCode; + } + + public Keymap getParent() { + return myParent; + } + + public boolean canModify() { + return myCanModify; + } + + public void setCanModify(boolean val) { + myCanModify = val; + } + + protected Shortcut[] getParentShortcuts(String actionId) { + return myParent.getShortcuts(actionId); + } + + public void addShortcut(String actionId, Shortcut shortcut) { + addShortcutSilently(actionId, shortcut); + fireShortcutChanged(actionId); + } + + private void addShortcutSilently(String actionId, Shortcut shortcut) { + ArrayList list = (ArrayList)myActionId2ListOfShortcuts.get(actionId); + if (list == null) { + list = new ArrayList(); + myActionId2ListOfShortcuts.put(actionId, list); + if (myParent != null) { + // copy parent shortcuts for this actionId + Shortcut[] shortcuts = getParentShortcuts(actionId); + for (int i = 0; i < shortcuts.length; i++) { + // shortcuts are immutables + list.add(shortcuts[i]); + } + } + } + list.add(shortcut); + + if (myParent != null && areShortcutsEqual(getParentShortcuts(actionId), getShortcuts(actionId))) { + myActionId2ListOfShortcuts.remove(actionId); + } + myKeystroke2ListOfIds = null; + myMouseShortcut2ListOfIds = null; + } + + public void removeAllActionShortcuts(String actionId) { + Shortcut[] allShortcuts = getShortcuts(actionId); + for (int i = 0; i < allShortcuts.length; i++) { + Shortcut shortcut = allShortcuts[i]; + removeShortcut(actionId, shortcut); + } + } + + public void removeShortcut(String actionId, Shortcut shortcut) { + ArrayList list = (ArrayList)myActionId2ListOfShortcuts.get(actionId); + if (list != null) { + for(int i=0; i list = (ArrayList)getKeystroke2ListOfIds().get(firstKeyStroke); + if (myParent != null) { + String[] ids = getParentActionIds(firstKeyStroke); + if (ids.length > 0) { + boolean originalListInstance = true; + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + // add actions from parent keymap only if they are absent in this keymap + if (!myActionId2ListOfShortcuts.containsKey(id)) { + if (list == null) { + list = new ArrayList(); + originalListInstance = false; + } else if (originalListInstance) { + list = (ArrayList)list.clone(); + } + list.add(id); + } + } + } + } + if (list == null) return ArrayUtil.EMPTY_STRING_ARRAY; + return sortInOrderOfRegistration(list.toArray(new String[list.size()])); + } + + public String[] getActionIds(KeyStroke firstKeyStroke, KeyStroke secondKeyStroke) { + String[] ids = getActionIds(firstKeyStroke); + ArrayList actualBindings = new ArrayList(); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + Shortcut[] shortcuts = getShortcuts(id); + for (int j = 0; j < shortcuts.length; j++) { + Shortcut shortcut = shortcuts[j]; + if (!(shortcut instanceof KeyboardShortcut)) { + continue; + } + if ( + Comparing.equal(firstKeyStroke, ((KeyboardShortcut)shortcut).getFirstKeyStroke()) && + Comparing.equal(secondKeyStroke, ((KeyboardShortcut)shortcut).getSecondKeyStroke()) + ) { + actualBindings.add(id); + break; + } + } + } + return actualBindings.toArray(new String[actualBindings.size()]); + } + + protected String[] getParentActionIds(MouseShortcut shortcut) { + return myParent.getActionIds(shortcut); + } + + public String[] getActionIds(MouseShortcut shortcut){ + // first, get shortcuts from own map + ArrayList list = (ArrayList)getMouseShortcut2ListOfIds().get(shortcut); + if (myParent != null) { + String[] ids = getParentActionIds(shortcut); + if (ids.length > 0) { + boolean originalListInstance = true; + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + // add actions from parent keymap only if they are absent in this keymap + if (!myActionId2ListOfShortcuts.containsKey(id)) { + if (list == null) { + list = new ArrayList(); + originalListInstance = false; + }else if (originalListInstance) { + list = (ArrayList)list.clone(); + } + list.add(id); + } + } + } + } + if (list == null){ + return ArrayUtil.EMPTY_STRING_ARRAY; + } + return sortInOrderOfRegistration(list.toArray(new String[list.size()])); + } + + private static String[] sortInOrderOfRegistration(String[] ids) { + Arrays.sort(ids, ActionManagerEx.getInstanceEx().getRegistrationOrderComparator()); + return ids; + } + + public Shortcut[] getShortcuts(String actionId) { + ArrayList shortcuts = (ArrayList)myActionId2ListOfShortcuts.get(actionId); + if (shortcuts == null) { + if (myParent != null) { + return getParentShortcuts(actionId); + }else{ + return ourEmptyShortcutsArray; + } + } + return shortcuts.toArray(new Shortcut[shortcuts.size()]); + } + + /** + * @param keymapElement element which corresponds to "keymap" tag. + */ + public void readExternal(Element keymapElement, Keymap[] existingKeymaps) throws InvalidDataException { + // Check and convert parameters + if(!"keymap".equals(keymapElement.getName())){ + throw new InvalidDataException("unknown element: "+keymapElement); + } + if(keymapElement.getAttributeValue("version")==null){ + Converter01.convert(keymapElement); + } + // + String parentName = keymapElement.getAttributeValue("parent"); + if(parentName != null) { + for(int i = 0; i < existingKeymaps.length; i++) { + Keymap existingKeymap = existingKeymaps[i]; + if(parentName.equals(existingKeymap.getName())) { + myParent = (KeymapImpl)existingKeymap; + myCanModify = true; + break; + } + } + } + myName = keymapElement.getAttributeValue("name"); + + myDisableMnemonics = "true".equals(keymapElement.getAttributeValue("disable-mnemonics")); + HashMap id2shortcuts=new HashMap(); + for (Iterator i = keymapElement.getChildren().iterator(); i.hasNext();) { + Element actionElement=(Element)i.next(); + if("action".equals(actionElement.getName())){ + String id = actionElement.getAttributeValue("id"); + if(id==null){ + throw new InvalidDataException("Attribute 'id' cannot be null; Keymap's name="+myName); + } + id2shortcuts.put(id,new ArrayList(1)); + for(Iterator j=actionElement.getChildren().iterator();j.hasNext();){ + Element shortcutElement=(Element)j.next(); + if ("keyboard-shortcut".equals(shortcutElement.getName())){ + + // Parse first keystroke + + KeyStroke firstKeyStroke; + String firstKeyStrokeStr = shortcutElement.getAttributeValue("first-keystroke"); + if(firstKeyStrokeStr != null) { + firstKeyStroke = ActionManagerEx.getKeyStroke(firstKeyStrokeStr); + if(firstKeyStroke==null){ + throw new InvalidDataException( + "Cannot parse first-keystroke: '" + firstKeyStrokeStr+"'; "+ + "Action's id="+id+"; Keymap's name="+myName + ); + } + }else{ + throw new InvalidDataException( + "Attribute 'first-keystroke' cannot be null; Action's id="+id+"; Keymap's name="+myName + ); + } + + // Parse second keystroke + + KeyStroke secondKeyStroke = null; + String secondKeyStrokeStr=shortcutElement.getAttributeValue("second-keystroke"); + if (secondKeyStrokeStr!=null) { + secondKeyStroke = ActionManagerEx.getKeyStroke(secondKeyStrokeStr); + if (secondKeyStroke == null) { + throw new InvalidDataException( + "Wrong second-keystroke: '" + secondKeyStrokeStr+"'; Action's id="+id+"; Keymap's name="+myName + ); + } + } + Shortcut shortcut = new KeyboardShortcut(firstKeyStroke, secondKeyStroke); + ArrayList shortcuts=(ArrayList)id2shortcuts.get(id); + shortcuts.add(shortcut); + }else if("mouse-shortcut".equals(shortcutElement.getName())){ + String keystrokeString=shortcutElement.getAttributeValue("keystroke"); + if (keystrokeString == null) { + throw new InvalidDataException( + "Attribute 'keystroke' cannot be null; Action's id=" + id + "; Keymap's name="+myName + ); + } + + try{ + MouseShortcut shortcut=KeymapUtil.parseMouseShortcut(keystrokeString); + ArrayList shortcuts=(ArrayList)id2shortcuts.get(id); + shortcuts.add(shortcut); + }catch(InvalidDataException exc){ + throw new InvalidDataException( + "Wrong mouse-shortcut: '"+keystrokeString+"'; Action's id="+id+"; Keymap's name="+myName + ); + } + }else{ + throw new InvalidDataException("unknown element: "+shortcutElement+"; Keymap's name="+myName); + } + } + }else{ + throw new InvalidDataException("unknown element: "+actionElement+"; Keymap's name="+myName); + } + } + // Add read shortcuts + for(Iterator i=id2shortcuts.keySet().iterator();i.hasNext();){ + String id=(String)i.next(); + myActionId2ListOfShortcuts.put(id,new ArrayList(2)); // It's a trick! After that paren's shortcuts are not added to the keymap + ArrayList shortcuts=(ArrayList)id2shortcuts.get(id); + for(Iterator j=shortcuts.iterator();j.hasNext();){ + Shortcut shortcut=(Shortcut)j.next(); + addShortcutSilently(id,shortcut); + } + } + } + + public Element writeExternal() { + Element keymapElement = new Element("keymap"); + keymapElement.setAttribute("version",Integer.toString(1)); + keymapElement.setAttribute("name", myName); + keymapElement.setAttribute("disable-mnemonics", myDisableMnemonics ? "true" : "false"); + if(myParent != null) { + keymapElement.setAttribute("parent", myParent.getName()); + } + String[] ownActionIds = getOwnActionIds(); + Arrays.sort(ownActionIds); + for(int i = 0; i < ownActionIds.length; i++){ + String actionId = ownActionIds[i]; + Element actionElement=new Element("action"); + actionElement.setAttribute("id",actionId); + // Save keyboad shortcuts + Shortcut[] shortcuts = getShortcuts(actionId); + for(int j = 0; j < shortcuts.length; j++){ + Shortcut shortcut = shortcuts[j]; + if (shortcut instanceof KeyboardShortcut) { + KeyboardShortcut keyboardShortcut = (KeyboardShortcut)shortcut; + Element element = new Element("keyboard-shortcut"); + element.setAttribute("first-keystroke", getKeyShortcutString(keyboardShortcut.getFirstKeyStroke())); + if (keyboardShortcut.getSecondKeyStroke() != null){ + element.setAttribute("second-keystroke", getKeyShortcutString(keyboardShortcut.getSecondKeyStroke())); + } + actionElement.addContent(element); + } else if (shortcut instanceof MouseShortcut) { + MouseShortcut mouseShortcut = (MouseShortcut)shortcut; + Element element = new Element("mouse-shortcut"); + element.setAttribute("keystroke", getMouseShortcutString(mouseShortcut)); + actionElement.addContent(element); + }else{ + throw new IllegalStateException("unknown shortcut class: " + shortcut); + } + } + keymapElement.addContent(actionElement); + } + return keymapElement; + } + + private boolean areShortcutsEqual(Shortcut[] shortcuts1, Shortcut[] shortcuts2) { + if(shortcuts1.length != shortcuts2.length) { + return false; + } + for(int j = 0; j < shortcuts1.length; j++){ + Shortcut shortcut = shortcuts1[j]; + Shortcut parentShortcutEqual = null; + for(int i = 0; i < shortcuts2.length; i++) { + Shortcut parentShortcut = shortcuts2[i]; + if(shortcut.equals(parentShortcut)) { + parentShortcutEqual = parentShortcut; + break; + } + } + if(parentShortcutEqual == null) { + return false; + } + } + return true; + } + + /** + * @return string representation of passed keystroke. + */ + private static String getKeyShortcutString(KeyStroke keyStroke) { + StringBuffer buf = new StringBuffer(); + int modifiers = keyStroke.getModifiers(); + if((modifiers & InputEvent.SHIFT_MASK) != 0) { + buf.append("shift "); + } + if((modifiers & InputEvent.CTRL_MASK) != 0) { + buf.append("control "); + } + if((modifiers & InputEvent.META_MASK) != 0) { + buf.append("meta "); + } + if((modifiers & InputEvent.ALT_MASK) != 0) { + buf.append("alt "); + } + + buf.append((String)ourNamesForKeycodes.get(new Integer(keyStroke.getKeyCode()))); + + return buf.toString(); + } + + /** + * @return string representation of passed mouse shortcut. This method should + * be used only for serializing of the MouseShortcut + */ + private static String getMouseShortcutString(MouseShortcut shortcut){ + StringBuffer buffer=new StringBuffer(); + + // modifiers + + int modifiers=shortcut.getModifiers(); + if((MouseEvent.SHIFT_DOWN_MASK&modifiers)>0){ + buffer.append("shift "); + } + if((MouseEvent.CTRL_DOWN_MASK&modifiers)>0){ + buffer.append("control "); + } + if((MouseEvent.META_DOWN_MASK&modifiers)>0){ + buffer.append("meta "); + } + if((MouseEvent.ALT_DOWN_MASK&modifiers)>0){ + buffer.append("alt "); + } + if((MouseEvent.ALT_GRAPH_DOWN_MASK&modifiers)>0){ + buffer.append("altGraph "); + } + + // button + + int button=shortcut.getButton(); + if(MouseEvent.BUTTON1==button){ + buffer.append("button1 "); + }else if(MouseEvent.BUTTON2==button){ + buffer.append("button2 "); + }else if(MouseEvent.BUTTON3==button){ + buffer.append("button3 "); + }else{ + throw new IllegalStateException("unknown button: "+button); + } + + if(shortcut.getClickCount()>1){ + buffer.append("doubleClick"); + } + return buffer.toString().trim(); // trim trailing space (if any) + } + + /** + * @return IDs of the action which are specified in the keymap. It doesn't + * return IDs of action from parent keymap. + */ + private String[] getOwnActionIds() { + return (String[])myActionId2ListOfShortcuts.keySet().toArray(new String[myActionId2ListOfShortcuts.size()]); + } + + public String[] getActionIds() { + ArrayList ids = new ArrayList(); + if (myParent != null) { + String[] parentIds = getParentActionIds(); + for (int i = 0; i < parentIds.length; i++) { + String id = parentIds[i]; + ids.add(id); + } + } + String[] ownActionIds = getOwnActionIds(); + for (int i = 0; i < ownActionIds.length; i++) { + String id = ownActionIds[i]; + if (!ids.contains(id)) { + ids.add(id); + } + } + return ids.toArray(new String[ids.size()]); + } + + protected String[] getParentActionIds() { + return myParent.getActionIds(); + } + + public boolean areMnemonicsEnabled() { + return !myDisableMnemonics; + } + + public void setDisableMnemonics(boolean disableMnemonics) { + myDisableMnemonics = disableMnemonics; + } + + public HashMap> getConflicts(String actionId, KeyboardShortcut keyboardShortcut) { + HashMap> result = new HashMap>(); + + String[] actionIds = getActionIds(keyboardShortcut.getFirstKeyStroke()); + for(int i = 0; i < actionIds.length; i++) { + String id = actionIds[i]; + if (id.equals(actionId)){ + continue; + } + + if (actionId.startsWith("Editor") && id.equals("$" + actionId.substring(6))) { + continue; + } + if (StringUtil.startsWithChar(actionId, '$') && id.equals("Editor" + actionId.substring(1))) { + continue; + } + + Shortcut[] shortcuts = getShortcuts(id); + for (int j = 0; j < shortcuts.length; j++) { + if (!(shortcuts[j] instanceof KeyboardShortcut)){ + continue; + } + + KeyboardShortcut shortcut = (KeyboardShortcut)shortcuts[j]; + + if (!shortcut.getFirstKeyStroke().equals(keyboardShortcut.getFirstKeyStroke())) { + continue; + } + + if ( + keyboardShortcut.getSecondKeyStroke() != null && + shortcut.getSecondKeyStroke() != null && + !keyboardShortcut.getSecondKeyStroke().equals(shortcut.getSecondKeyStroke()) + ){ + continue; + } + + ArrayList list = result.get(id); + if (list == null) { + list = new ArrayList(); + result.put(id, list); + } + + list.add(shortcut); + } + } + + return result; + } + + public void addShortcutChangeListener(Keymap.Listener listener) { + myListeners.add(listener); + } + + public void removeShortcutChangeListener(Keymap.Listener listener) { + myListeners.remove(listener); + } + + private void fireShortcutChanged(String actionId) { + Keymap.Listener[] listeners = myListeners.toArray(new Keymap.Listener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + Listener listener = listeners[i]; + listener.onShortcutChanged(actionId); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java new file mode 100644 index 00000000000..c3565f0e8b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java @@ -0,0 +1,242 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.ex.KeymapManagerListener; +import com.intellij.openapi.util.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.UniqueFileNamesProvider; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public class KeymapManagerImpl extends KeymapManagerEx implements NamedJDOMExternalizable, ExportableApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.keymap.KeymapManager"); + + private ArrayList myKeymaps = new ArrayList(); + private KeymapImpl myActiveKeymap; + private ArrayList myListeners = new ArrayList(); + private String myActiveKeymapName; + + KeymapManagerImpl(DefaultKeymap defaultKeymap) { + Keymap[] keymaps = defaultKeymap.getKeymaps(); + for (int i = 0; i < keymaps.length; i++) { + KeymapImpl keymap = (KeymapImpl)keymaps[i]; + addKeymap(keymap); + String systemDefaultKeymap = SystemInfo.isMac ? MAC_OS_X_KEYMAP : DEFAULT_IDEA_KEYMAP; + if (systemDefaultKeymap.equals(keymap.getName())) { + setActiveKeymap(keymap); + } + } + load(); + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this),getKeymapDirectory(true)}; + } + + public String getPresentableName() { + return "Key maps"; + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public Keymap[] getAllKeymaps() { + return myKeymaps.toArray(new Keymap[myKeymaps.size()]); + } + + public Keymap getKeymap(String name) { + for (Iterator iterator = myKeymaps.iterator(); iterator.hasNext();) { + Keymap keymap = iterator.next(); + if (name.equals(keymap.getName())) { + return keymap; + } + } + return null; + } + + public Keymap getActiveKeymap() { + return myActiveKeymap; + } + + public void setActiveKeymap(Keymap activeKeymap) { + myActiveKeymap = (KeymapImpl) activeKeymap; + fireActiveKeymapChanged(); + } + + public void addKeymap(Keymap keymap) { + myKeymaps.add(keymap); + } + + public void removeAllKeymapsExceptUnmodifiable() { + Iterator it = myKeymaps.iterator(); + while (it.hasNext()) { + Keymap keymap = (Keymap) it.next(); + if (keymap.canModify()) { + it.remove(); + } + } + myActiveKeymap = null; + if (myKeymaps.size() > 0) { + myActiveKeymap = (KeymapImpl) myKeymaps.get(0); + } + } + + public String getExternalFileName() { + return "keymap"; + } + + public void readExternal(Element element) throws InvalidDataException{ + Element child = element.getChild("active_keymap"); + if (child != null) { + myActiveKeymapName = child.getAttributeValue("name"); + } + + if (myActiveKeymapName != null) { + Keymap keymap = getKeymap(myActiveKeymapName); + if (keymap != null) { + setActiveKeymap(keymap); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException{ + if (myActiveKeymap != null) { + Element e = new Element("active_keymap"); + e.setAttribute("name", myActiveKeymap.getName()); + element.addContent(e); + } + } + + private void load(){ + File[] files = getKeymapFiles(); + for (int i = 0; i < files.length; i++) { + try { + readKeymap(files[i], myKeymaps); + } + catch (InvalidDataException e) { + LOG.error("Invalid data in file: " + files[i].getAbsolutePath() +" Reason: "+e.getMessage()); + } + catch (JDOMException e){ + LOG.error("Invalid JDOM: " + files[i].getAbsolutePath()); + } + catch (IOException e) { + LOG.error(e); + } + } + } + + private void readKeymap(File file, ArrayList keymaps) throws JDOMException,InvalidDataException, IOException{ + if (!file.exists()) return; + org.jdom.Document document = JDOMUtil.loadDocument(file); + if (document == null) throw new InvalidDataException(); + Element root = document.getRootElement(); + if (root == null || !"keymap".equals(root.getName())) { + throw new InvalidDataException(); + } + KeymapImpl keymap = new KeymapImpl(); + keymap.readExternal(root, getAllKeymaps()); + keymaps.add(keymap); + } + + private static File getKeymapDirectory(boolean toCreate) { + String directoryPath = PathManager.getConfigPath() + File.separator + "keymaps"; + File directory = new File(directoryPath); + if (!directory.exists()) { + if (!toCreate) return null; + if (!directory.mkdir()) { + LOG.error("Cannot create directory: " + directory.getAbsolutePath()); + return null; + } + } + return directory; + } + + private File[] getKeymapFiles() { + File directory = getKeymapDirectory(false); + if (directory == null) { + return new File[0]; + } + File[] ret = directory.listFiles(new FileFilter() { + public boolean accept(File file){ + return !file.isDirectory() && file.getName().toLowerCase().endsWith(".xml"); + } + }); + if (ret == null) { + LOG.error("Cannot read directory: " + directory.getAbsolutePath()); + return new File[0]; + } + return ret; + } + + public void save() throws IOException{ + File directory = getKeymapDirectory(true); + if (directory == null) { + LOG.error("Keymap directory does not exist and cannot be created"); + return; + } + + File[] files = getKeymapFiles(); + + ArrayList filePaths = new ArrayList(); + ArrayList documents = new ArrayList(); + + UniqueFileNamesProvider namesProvider = new UniqueFileNamesProvider(); + Iterator it = myKeymaps.iterator(); + while (it.hasNext()) { + KeymapImpl keymap = (KeymapImpl) it.next(); + if (!keymap.canModify()) { + continue; + } + + Document document=new Document(keymap.writeExternal()); + String filePath = directory.getAbsolutePath() + File.separator + namesProvider.suggestName(keymap.getName()) + ".xml"; + + filePaths.add(filePath); + documents.add(document); + } + + JDOMUtil.updateFileSet( + files, + filePaths.toArray(new String[filePaths.size()]), + documents.toArray(new Document[documents.size()]), CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + + private void fireActiveKeymapChanged() { + KeymapManagerListener[] listeners = myListeners.toArray(new KeymapManagerListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + KeymapManagerListener listener = listeners[i]; + listener.activeKeymapChanged(myActiveKeymap); + } + } + + public void addKeymapManagerListener(KeymapManagerListener listener) { + myListeners.add(listener); + } + + public void removeKeymapManagerListener(KeymapManagerListener listener) { + myListeners.remove(listener); + } + + public String getComponentName() { + return "KeymapManager"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/MacOSDefaultKeymap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/MacOSDefaultKeymap.java new file mode 100644 index 00000000000..09079245dc1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/MacOSDefaultKeymap.java @@ -0,0 +1,98 @@ +package com.intellij.openapi.keymap.impl; + +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.actionSystem.MouseShortcut; +import com.intellij.openapi.actionSystem.Shortcut; + +import javax.swing.*; +import java.awt.event.InputEvent; + +/** + * @author max + */ +class MacOSDefaultKeymap extends DefaultKeymapImpl { + protected String[] getParentActionIds(KeyStroke firstKeyStroke) { + return super.getParentActionIds(convertKeyStroke(firstKeyStroke)); + } + + protected String[] getParentActionIds(MouseShortcut shortcut) { + return super.getParentActionIds(convertMouseShortcut(shortcut)); + } + + protected Shortcut[] getParentShortcuts(String actionId) { + Shortcut[] parentShortcuts = super.getParentShortcuts(actionId); + Shortcut[] macShortcuts = new Shortcut[parentShortcuts.length]; + for (int i = 0; i < parentShortcuts.length; i++) { + macShortcuts[i] = convertShortcutFromParent(parentShortcuts[i]); + } + return macShortcuts; + } + + private Shortcut convertShortcutFromParent(Shortcut parentShortcut) { + if (parentShortcut instanceof MouseShortcut) { + return convertMouseShortcut((MouseShortcut)parentShortcut); + } + + KeyboardShortcut key = (KeyboardShortcut)parentShortcut; + return new KeyboardShortcut(convertKeyStroke(key.getFirstKeyStroke()), + convertKeyStroke(key.getSecondKeyStroke())); + } + + private KeyStroke convertKeyStroke(KeyStroke parentKeyStroke) { + if (parentKeyStroke == null) return null; + return KeyStroke.getKeyStroke(parentKeyStroke.getKeyCode(), + mapModifiers(parentKeyStroke.getModifiers()), + parentKeyStroke.isOnKeyRelease()); + } + + private MouseShortcut convertMouseShortcut(MouseShortcut macShortcut) { + return new MouseShortcut(macShortcut.getButton(), + mapModifiers(macShortcut.getModifiers()), + macShortcut.getClickCount()); + } + + private int mapModifiers(int modifiers) { + boolean meta = false; + boolean metaDown = false; + boolean control = false; + boolean controlDown = false; + + if ((modifiers & InputEvent.META_MASK) != 0) { + modifiers &= ~InputEvent.META_MASK; + meta = true; + } + + if ((modifiers & InputEvent.META_DOWN_MASK) != 0) { + modifiers &= ~InputEvent.META_DOWN_MASK; + metaDown = true; + } + + if ((modifiers & InputEvent.CTRL_MASK) != 0) { + modifiers &= ~InputEvent.CTRL_MASK; + control = true; + } + + if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) { + modifiers &= ~InputEvent.CTRL_DOWN_MASK; + controlDown = true; + } + + if (meta) { + modifiers |= InputEvent.CTRL_MASK; + } + + if (metaDown) { + modifiers |= InputEvent.CTRL_DOWN_MASK; + } + + if (control) { + modifiers |= InputEvent.META_MASK; + } + + if (controlDown) { + modifiers |= InputEvent.META_DOWN_MASK; + } + + return modifiers; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTree.java new file mode 100644 index 00000000000..26aa9931c60 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTree.java @@ -0,0 +1,456 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.Alarm; +import com.intellij.util.ui.treetable.TreeTable; +import com.intellij.util.ui.treetable.TreeTableCellRenderer; +import com.intellij.util.ui.treetable.TreeTableModel; + +import javax.swing.*; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; + +public class ActionsTree { + private static final Icon EMPTY_ICON = EmptyIcon.create(16, 16); + + private TreeTable myTreeTable; + private DefaultMutableTreeNode myRoot; + private JScrollPane myComponent; + private Keymap myKeymap; + private ActionsTreeUtil.Group myMainGroup = new ActionsTreeUtil.Group("", null, null); + private ShortcutColumnCellRenderer myShortcutColumnCellRenderer; + + public ActionsTree() { + myRoot = new DefaultMutableTreeNode("ROOT"); + myShortcutColumnCellRenderer = new ShortcutColumnCellRenderer(); + + myTreeTable = new TreeTable(new MyModel(myRoot)) { + public TreeTableCellRenderer createTableRenderer(TreeTableModel treeTableModel) { + TreeTableCellRenderer tableRenderer = super.createTableRenderer(treeTableModel); + tableRenderer.putClientProperty("JTree.lineStyle", "Angled"); + return tableRenderer; + } + + public TableCellRenderer getCellRenderer(int row, int column){ + if (convertColumnIndexToModel(column) == 1) { + return myShortcutColumnCellRenderer; + } + return super.getCellRenderer(row, column); + } + }; + + myTreeTable.getTree().setCellRenderer(new DefaultTreeCellRenderer(){ + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + setBorderSelectionColor(null); + if (value instanceof DefaultMutableTreeNode) { + Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); + boolean changed; + if (userObject instanceof ActionsTreeUtil.Group) { + ActionsTreeUtil.Group group = (ActionsTreeUtil.Group)userObject; + setText(group.getName()); + Keymap originalKeymap = myKeymap.getParent(); + changed = originalKeymap != null && isGroupChanged(group, originalKeymap, myKeymap); + Icon icon = expanded ? group.getOpenIcon() : group.getIcon(); + + if (icon == null) { + icon = expanded ? getOpenIcon() : getClosedIcon(); + } + + setIcon(icon); + } + else if (userObject instanceof String) { + String actionId = (String)userObject; + AnAction action = ActionManager.getInstance().getAction(actionId); + setText(action != null ? action.getTemplatePresentation().getText() : actionId); + Icon icon = EMPTY_ICON; + if (action != null) { + Icon actionIcon = action.getTemplatePresentation().getIcon(); + if (actionIcon != null) { + icon = actionIcon; + } + } + setIcon(icon); + Keymap originalKeymap = myKeymap.getParent(); + changed = originalKeymap != null && isActionChanged(actionId, originalKeymap, myKeymap); + } + else if (userObject instanceof QuickList) { + QuickList list = (QuickList)userObject; + setIcon(EMPTY_ICON); + setText(list.getDisplayName()); + Keymap originalKeymap = myKeymap.getParent(); + changed = originalKeymap != null && isActionChanged(list.getActionId(), originalKeymap, myKeymap); + } + else if (userObject instanceof Separator) { + // TODO[vova,anton]: beautify + changed = false; + setText("-------------"); + setIcon(EMPTY_ICON); + } + else { + throw new IllegalArgumentException("unknown userObject: " + userObject); + } + + // Set color + + if(sel){ + setForeground(UIManager.getColor("Tree.selectionForeground")); + }else{ + if(changed){ + setForeground(Color.BLUE); + }else{ + setForeground(UIManager.getColor("Tree.foreground")); + } + } + } + return this; + } + }); + + myTreeTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + myTreeTable.getColumnModel().getColumn(0).setPreferredWidth(200); + myTreeTable.getColumnModel().getColumn(1).setPreferredWidth(100); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable); + myComponent = scrollPane; + } + + public JComponent getComponent() { + return myComponent; + } + + public void addListSelectionListener(ListSelectionListener l) { + myTreeTable.getSelectionModel().addListSelectionListener(l); + } + + private Object getSelectedObject() { + int selectedRow = myTreeTable.getSelectedRow(); + if (selectedRow < 0 || selectedRow >= myTreeTable.getRowCount()) return null; + + TreePath selectionPath = myTreeTable.getTree().getPathForRow(selectedRow); + if (selectionPath == null) return null; + Object userObject = ((DefaultMutableTreeNode)selectionPath.getLastPathComponent()).getUserObject(); + return userObject; + } + + public String getSelectedActionId() { + Object userObject = getSelectedObject(); + if (userObject instanceof String) return (String)userObject; + if (userObject instanceof QuickList) return ((QuickList)userObject).getActionId(); + return null; + } + + public QuickList getSelectedQuickList() { + Object userObject = getSelectedObject(); + if (!(userObject instanceof QuickList)) return null; + return (QuickList)userObject; + } + + public void reset(Keymap keymap, final QuickList[] allQuickLists) { + myKeymap = keymap; + + final PathsKeeper pathsKeeper = new PathsKeeper(); + pathsKeeper.storePaths(); + + myRoot.removeAllChildren(); + + Project project = (Project)DataManager.getInstance().getDataContext(getComponent()).getData(DataConstants.PROJECT); + ActionsTreeUtil.Group mainGroup = ActionsTreeUtil.createMainGroup(project, myKeymap, allQuickLists); + + myRoot = ActionsTreeUtil.createNode(mainGroup); + myMainGroup = mainGroup; + MyModel model = (MyModel)myTreeTable.getTree().getModel(); + model.setRoot(myRoot); + model.nodeStructureChanged(myRoot); + + pathsKeeper.restorePaths(); + } + + public ActionsTreeUtil.Group getMainGroup() { + return myMainGroup; + } + + private class MyModel extends DefaultTreeModel implements TreeTableModel { + protected MyModel(DefaultMutableTreeNode root) { + super(root); + } + + public int getColumnCount() { + return 2; + } + + public String getColumnName(int column) { + switch (column) { + case 0: return "Action"; + case 1: return "Shortcuts"; + } + return ""; + } + + public Object getValueAt(Object value, int column) { + if (!(value instanceof DefaultMutableTreeNode)) { + return "???"; + } + + if (column == 0) { + return value; + } + else if (column == 1) { + Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); + if (userObject instanceof QuickList) { + userObject = ((QuickList)userObject).getActionId(); + } + + if (userObject instanceof String) { + Shortcut[] shortcuts = myKeymap.getShortcuts((String)userObject); + return KeymapUtil.getShortcutsText(shortcuts); + } + else { + return ""; + } + } + else { + return "???"; + } + } + + public Object getChild(Object parent, int index) { + return ((TreeNode)parent).getChildAt(index); + } + + public int getChildCount(Object parent) { + return ((TreeNode)parent).getChildCount(); + } + + public Class getColumnClass(int column) { + if (column == 0) { + return TreeTableModel.class; + } + else { + return Object.class; + } + } + + public boolean isCellEditable(Object node, int column) { + return column == 0; + } + + public void setValueAt(Object aValue, Object node, int column) { + } + } + + + private boolean isActionChanged(String actionId, Keymap oldKeymap, Keymap newKeymap) { + Shortcut[] oldShortcuts = oldKeymap.getShortcuts(actionId); + Shortcut[] newShortcuts = newKeymap.getShortcuts(actionId); + return !Comparing.equal(oldShortcuts, newShortcuts); + } + + private boolean isGroupChanged(ActionsTreeUtil.Group group, Keymap oldKeymap, Keymap newKeymap) { + ArrayList children = group.getChildren(); + for (int i = 0; i < children.size(); i++) { + Object child = children.get(i); + if (child instanceof ActionsTreeUtil.Group) { + if (isGroupChanged((ActionsTreeUtil.Group)child, oldKeymap, newKeymap)) { + return true; + } + } + else if (child instanceof String) { + String actionId = (String)child; + if (isActionChanged(actionId, oldKeymap, newKeymap)) { + return true; + } + } + } + return false; + } + + public void selectAction(String actionId) { + final JTree tree = myTreeTable.getTree(); + + String path = myMainGroup.getActionQualifiedPath(actionId); + if (path == null) { + return; + } + final DefaultMutableTreeNode node = getNodeForPath(path); + if (node == null) { + return; + } + tree.expandPath(new TreePath(((DefaultMutableTreeNode)node.getParent()).getPath())); + + Alarm alarm = new Alarm(); + alarm.addRequest(new Runnable() { + public void run() { + JTree tree = myTreeTable.getTree(); + final DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel(); + int rowForPath = tree.getRowForPath(new TreePath(treeModel.getPathToRoot(node))); + myTreeTable.getSelectionModel().setSelectionInterval(rowForPath, rowForPath); + + Rectangle pathBounds = tree.getPathBounds(new TreePath(node.getPath())); + myTreeTable.scrollRectToVisible(pathBounds); + } + }, 100); + } + + private DefaultMutableTreeNode getNodeForPath(String path) { + Enumeration enumeration = ((DefaultMutableTreeNode)myTreeTable.getTree().getModel().getRoot()).preorderEnumeration(); + while (enumeration.hasMoreElements()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)enumeration.nextElement(); + if (Comparing.equal(getPath(node), path)) { + return node; + } + } + return null; + } + + private String getPath(DefaultMutableTreeNode node) { + Object userObject = node.getUserObject(); + if (userObject instanceof String) { + String actionId = (String)userObject; + return myMainGroup.getActionQualifiedPath(actionId); + } + if (userObject instanceof ActionsTreeUtil.Group) { + return ((ActionsTreeUtil.Group)userObject).getQualifiedPath(); + } + return null; + } + + private class PathsKeeper { + private JTree myTree; + private ArrayList myPathsToExpand; + private ArrayList mySelectionPaths; + + public PathsKeeper() { + myTree = myTreeTable.getTree(); + } + + public void storePaths() { + myPathsToExpand = new ArrayList(); + mySelectionPaths = new ArrayList(); + + DefaultMutableTreeNode root = (DefaultMutableTreeNode)myTree.getModel().getRoot(); + + TreePath path = new TreePath(root.getPath()); + if (myTree.isPathSelected(path)){ + mySelectionPaths.add(getPath(root)); + } + if (myTree.isExpanded(path) || root.getChildCount() == 0){ + myPathsToExpand.add(getPath(root)); + _storePaths(root); + } + } + + private void _storePaths(DefaultMutableTreeNode root) { + ArrayList childNodes = childrenToArray(root); + for(Iterator iterator = childNodes.iterator(); iterator.hasNext();){ + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)iterator.next(); + TreePath path = new TreePath(childNode.getPath()); + if (myTree.isPathSelected(path)){ + mySelectionPaths.add(getPath(childNode)); + } + if (myTree.isExpanded(path) || childNode.getChildCount() == 0){ + myPathsToExpand.add(getPath(childNode)); + _storePaths(childNode); + } + } + } + + public void restorePaths() { + for(int i = 0; i < myPathsToExpand.size(); i++){ + String path = myPathsToExpand.get(i); + DefaultMutableTreeNode node = getNodeForPath(path); + if (node != null){ + myTree.expandPath(new TreePath(node.getPath())); + } + } + + Alarm alarm = new Alarm(); + alarm.addRequest(new Runnable() { + public void run() { + final DefaultTreeModel treeModel = (DefaultTreeModel)myTree.getModel(); + for(int i = 0; i < mySelectionPaths.size(); i++){ + String path = mySelectionPaths.get(i); + final DefaultMutableTreeNode node = getNodeForPath(path); + if (node != null){ + int rowForPath = myTree.getRowForPath(new TreePath(treeModel.getPathToRoot(node))); + myTreeTable.getSelectionModel().setSelectionInterval(rowForPath, rowForPath); + // TODO[anton] make selection visible + + } + } + } + }, 100); + } + + + private ArrayList childrenToArray(DefaultMutableTreeNode node) { + ArrayList arrayList = new ArrayList(); + for(int i = 0; i < node.getChildCount(); i++){ + arrayList.add(node.getChildAt(i)); + } + return arrayList; + } + } + + private class ShortcutColumnCellRenderer implements TableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){ + String actionId = null; + + TreePath treePath = myTreeTable.getTree().getPathForRow(row); + if (treePath != null) { + Object userObject = ((DefaultMutableTreeNode)treePath.getLastPathComponent()).getUserObject(); + if (userObject instanceof QuickList) { + userObject = ((QuickList)userObject).getActionId(); + } + if (userObject instanceof String) { + actionId = (String)userObject; + } + } + + JPanel panel = new JPanel(new GridBagLayout()); + + if (actionId != null) { + Color foreground = isSelected ? table.getSelectionForeground() : table.getForeground(); + + Shortcut[] shortcuts = myKeymap.getShortcuts(actionId); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + + String text = KeymapUtil.getShortcutText(shortcut); + Icon icon = KeymapUtil.getShortcutIcon(shortcut); + + JLabel label = new JLabel(); + label.setForeground(foreground); + label.setText(text); + label.setIcon(icon); + + panel.add(label, new GridBagConstraints(i,0,1,1,(i < shortcuts.length - 1 ? 0 : 1),0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0,5,0,5), 0,0)); + } + } + + if (isSelected){ + panel.setBackground(table.getSelectionBackground()); + } + else{ + panel.setBackground(table.getBackground()); + } + panel.setBorder(hasFocus ? UIManager.getBorder("Table.focusCellHighlightBorder") : BorderFactory.createEmptyBorder(1,1,1,1)); + + return panel; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java new file mode 100644 index 00000000000..df8ab5a1504 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java @@ -0,0 +1,538 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.ant.AntConfiguration; +import com.intellij.ant.BuildFile; +import com.intellij.ant.actions.TargetAction; +import com.intellij.ide.actionMacro.ActionMacro; +import com.intellij.ide.actions.ToolWindowsGroup; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.tools.Tool; +import com.intellij.tools.ToolManager; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.*; + +public class ActionsTreeUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.keymap.impl.ui.ActionsTreeUtil"); + + private static final Icon MAIN_MENU_ICON = IconLoader.getIcon("/nodes/keymapMainMenu.png"); + private static final Icon EDITOR_ICON = IconLoader.getIcon("/nodes/keymapEditor.png"); + private static final Icon EDITOR_OPEN_ICON = IconLoader.getIcon("/nodes/keymapEditorOpen.png"); + private static final Icon ANT_ICON = IconLoader.getIcon("/nodes/keymapAnt.png"); + private static final Icon ANT_OPEN_ICON = IconLoader.getIcon("/nodes/keymapAntOpen.png"); + private static final Icon TOOLS_ICON = IconLoader.getIcon("/nodes/keymapTools.png"); + private static final Icon TOOLS_OPEN_ICON = IconLoader.getIcon("/nodes/keymapToolsOpen.png"); + private static final Icon OTHER_ICON = IconLoader.getIcon("/nodes/keymapOther.png"); + + private ActionsTreeUtil() {} + + public static Group createMainGroup(final Project project, final Keymap keymap, final QuickList[] quickLists) { + Group mainGroup = new Group("All Actions", null, null); + mainGroup.addGroup(createEditorActionsGroup()); + mainGroup.addGroup(createMainMenuGroup()); + mainGroup.addGroup(createVcsGroup()); + mainGroup.addGroup(createAntGroup(project)); + mainGroup.addGroup(createDebuggerActionsGroup()); + mainGroup.addGroup(createGuiDesignerActionsGroup(mainGroup)); + mainGroup.addGroup(createBookmarksActionsGroup()); + mainGroup.addGroup(createExternalToolsGroup()); + mainGroup.addGroup(createMacrosGroup()); + mainGroup.addGroup(createQuickListsGroup(quickLists)); + + Group otherGroup = createOtherGroup(mainGroup, keymap); + mainGroup.addGroup(otherGroup); + return mainGroup; + } + + private static Group createBookmarksActionsGroup() { + return createGroup((ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_BOOKMARKS)); + } + + private static Group createGuiDesignerActionsGroup(Group mainGroup) { + Group group = new Group("GUI Designer", null, null); + ActionManager actionManager = ActionManager.getInstance(); + ActionGroup uiGroup = (ActionGroup)actionManager.getAction(IdeActions.GROUP_GUI_DESIGNER_EDITOR_POPUP); + AnAction[] actions = uiGroup.getChildren(null); + for (int i = 0; i < actions.length; i++) { + AnAction action = actions[i]; + String actionId = actionManager.getId(action); + if (actionId == null || mainGroup.containsId(actionId)) continue; + group.addActionId(actionId); + } + return group; + } + + private static Group createVcsGroup() { + Group group = new Group("Version Control Systems", null, null); + ActionGroup versionControls = (ActionGroup)ActionManager.getInstance().getAction("VcsGroup"); + fillGroupIgnorePopupFlag(versionControls, group); + return group; + } + + private static Group createMainMenuGroup() { + Group group = new Group("Main menu", MAIN_MENU_ICON, MAIN_MENU_ICON); + ActionGroup mainMenuGroup = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_MAIN_MENU); + fillGroupIgnorePopupFlag(mainMenuGroup, group); + return group; + } + + private static void fillGroupIgnorePopupFlag(ActionGroup actionGroup, Group group) { + AnAction[] mainMenuTopGroups = actionGroup.getChildren(null); + for (int i = 0; i < mainMenuTopGroups.length; i++) { + AnAction action = mainMenuTopGroups[i]; + if (action instanceof DefaultActionGroup) { + Group subGroup = createGroup((ActionGroup)action); + if (subGroup.getSize() > 0) { + group.addGroup(subGroup); + } + } + } + } + + private static Group createGroup(ActionGroup actionGroup) { + ActionManager actionManager = ActionManager.getInstance(); + Group group = new Group(actionGroup.getTemplatePresentation().getText(), null, null); + AnAction[] children = actionGroup.getChildren(null); + for (int i = 0; i < children.length; i++) { + AnAction action = children[i]; + + if (action instanceof ActionGroup) { + if (action instanceof DefaultActionGroup || action instanceof ToolWindowsGroup) { + Group subGroup = createGroup((ActionGroup)action); + if (subGroup.getSize() > 0) { + if (!((ActionGroup)action).isPopup()) { + group.addAll(subGroup); + } + else { + group.addGroup(subGroup); + } + } + } + } + else if (action instanceof Separator){ + if (group.getSize() > 0 && i < children.length - 1 && !(group.getChildren().get(group.getSize() - 1) instanceof Separator)) { + group.addSeparator(); + } + } + else { + String id = actionManager.getId(action); + if (id != null) { + if (id.startsWith(TargetAction.ACTION_ID_PREFIX)) continue; + if (id.startsWith(Tool.ACTION_ID_PREFIX)) continue; + group.addActionId(id); + } + } + } + group.normalizeSeparators(); + return group; + } + + private static Group createDebuggerActionsGroup() { + ActionManager actionManager = ActionManager.getInstance(); + ActionGroup debuggerGroup = (ActionGroup) actionManager.getAction(IdeActions.GROUP_DEBUGGER); + AnAction[] debuggerActions = debuggerGroup.getChildren(null); + + ArrayList ids = new ArrayList(); + for (int i = 0; i < debuggerActions.length; i++) { + AnAction editorAction = debuggerActions[i]; + String actionId = actionManager.getId(editorAction); + ids.add(actionId); + } + + Collections.sort(ids); + Group group = new Group("Debugger Actions", null, null); + for (Iterator iterator = ids.iterator(); iterator.hasNext();) { + String id = iterator.next(); + group.addActionId(id); + } + + return group; + } + + private static Group createEditorActionsGroup() { + ActionManager actionManager = ActionManager.getInstance(); + ActionGroup editorGroup = (ActionGroup) actionManager.getAction(IdeActions.GROUP_EDITOR); + AnAction[] editorActions = editorGroup.getChildren(null); + + ArrayList ids = new ArrayList(); + for (int i = 0; i < editorActions.length; i++) { + AnAction editorAction = editorActions[i]; + String actionId = actionManager.getId(editorAction); + if (actionId == null) continue; + if (actionId.startsWith("Editor")) { + AnAction action = actionManager.getAction("$" + actionId.substring(6)); + if (action != null) continue; + } + ids.add(actionId); + } + + Collections.sort(ids); + Group group = new Group("Editor Actions", EDITOR_ICON, EDITOR_OPEN_ICON); + for (Iterator iterator = ids.iterator(); iterator.hasNext();) { + String id = iterator.next(); + group.addActionId(id); + } + + return group; + } + + private static Group createAntGroup(final Project project) { + String[] ids = ActionManagerEx.getInstanceEx().getActionIds(TargetAction.ACTION_ID_PREFIX); + Arrays.sort(ids); + Group group = new Group("Ant Targets", ANT_ICON, ANT_OPEN_ICON); + + if (project != null) { + AntConfiguration antConfiguration = AntConfiguration.getInstance(project); + + com.intellij.util.containers.HashMap buildFileToGroup = new com.intellij.util.containers.HashMap(); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + + BuildFile buildFile = antConfiguration.findBuildFileByActionId(id); + if (buildFile == null) { + LOG.info("no buildfile found for actionId=" + id); + continue; + } + + Group subGroup = (Group)buildFileToGroup.get(buildFile); + if (subGroup == null) { + subGroup = new Group(buildFile.getPresentableName(), null, null); + buildFileToGroup.put(buildFile, subGroup); + group.addGroup(subGroup); + } + + subGroup.addActionId(id); + } + } + return group; + } + + private static Group createMacrosGroup() { + String[] ids = ActionManagerEx.getInstanceEx().getActionIds(ActionMacro.MACRO_ACTION_PREFIX); + Arrays.sort(ids); + Group group = new Group("Macros", null, null); + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + group.addActionId(id); + } + return group; + } + + private static Group createQuickListsGroup(final QuickList[] quickLists) { + Arrays.sort(quickLists, new Comparator() { + public int compare(QuickList l1, QuickList l2) { + return l1.getActionId().compareTo(l2.getActionId()); + } + }); + + Group group = new Group("Quick Lists", null, null); + for (int i = 0; i < quickLists.length; i++) { + group.addQuickList(quickLists[i]); + } + return group; + } + + + private static Group createExternalToolsGroup() { + String[] ids = ActionManagerEx.getInstanceEx().getActionIds(Tool.ACTION_ID_PREFIX); + Arrays.sort(ids); + Group group = new Group("External Tools", TOOLS_ICON, TOOLS_OPEN_ICON); + + ToolManager toolManager = ToolManager.getInstance(); + + com.intellij.util.containers.HashMap toolGroupNameToGroup = new com.intellij.util.containers.HashMap(); + + for (int i = 0; i < ids.length; i++) { + String id = ids[i]; + + String groupName = toolManager.getGroupByActionId(id); + + if (groupName != null && groupName.trim().length() == 0) { + groupName = null; + } + + Group subGroup = (Group)toolGroupNameToGroup.get(groupName); + if (subGroup == null) { + subGroup = new Group(groupName, null, null); + toolGroupNameToGroup.put(groupName, subGroup); + if (groupName != null) { + group.addGroup(subGroup); + } + } + + subGroup.addActionId(id); + } + + Group subGroup = (Group)toolGroupNameToGroup.get(null); + if (subGroup != null) { + group.addAll(subGroup); + } + + return group; + } + + private static Group createOtherGroup(Group addedActions, final Keymap keymap) { + ArrayList result = new ArrayList(); + + if (keymap != null) { + String[] actionIds = keymap.getActionIds(); + for(int i = 0; i < actionIds.length; i++){ + String id = actionIds[i]; + + if (id.startsWith("Editor")) { + AnAction action = ActionManager.getInstance().getAction("$" + id.substring(6)); + if (action != null) continue; + } + + if (!id.startsWith(QuickList.QUICK_LIST_PREFIX) && !addedActions.containsId(id)) { + result.add(id); + } + } + } + + // add all registered actions + final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + String[] registeredActionIds = actionManager.getActionIds(""); + for (int i = 0; i < registeredActionIds.length; i++) { + String id = registeredActionIds[i]; + if (actionManager.getAction(id) instanceof ActionGroup){ + continue; + } + if (!id.startsWith(QuickList.QUICK_LIST_PREFIX) && !addedActions.containsId(id) && !result.contains(id)) { + result.add(id); + } + } + + filterOtherActionsGroup(result); + + Collections.sort( + result, new Comparator() { + public int compare(String id1, String id2) { + return getTextToCompare(id1).compareToIgnoreCase(getTextToCompare(id2)); + } + + private String getTextToCompare(String id) { + AnAction action = actionManager.getAction(id); + if (action == null){ + return id; + } + String text = action.getTemplatePresentation().getText(); + return text != null ? text: id; + } + }); + + Group group = new Group("Other", OTHER_ICON, OTHER_ICON); + for (int i = 0; i < result.size(); i++) { + group.addActionId(result.get(i)); + } + return group; + } + + private static void filterOtherActionsGroup(ArrayList actions) { + filterOutGroup(actions, IdeActions.GROUP_GENERATE); + filterOutGroup(actions, IdeActions.GROUP_NEW); + filterOutGroup(actions, IdeActions.GROUP_CHANGE_SCHEME); + } + + private static void filterOutGroup(ArrayList actions, String groupId) { + if (groupId == null) { + throw new IllegalArgumentException(); + } + ActionManager actionManager = ActionManager.getInstance(); + AnAction action = actionManager.getAction(groupId); + if (action instanceof DefaultActionGroup) { + DefaultActionGroup group = (DefaultActionGroup)action; + AnAction[] children = group.getChildren(null); + for (int i = 0; i < children.length; i++) { + AnAction child = children[i]; + String childId = actionManager.getId(child); + if (childId == null) { + // SCR 35149 + continue; + } + if (child instanceof DefaultActionGroup) { + filterOutGroup(actions, childId); + } + else { + actions.remove(childId); + } + } + } + } + + public static DefaultMutableTreeNode createNode(Group group) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(group); + for (Iterator iterator = group.getChildren().iterator(); iterator.hasNext();) { + Object child = iterator.next(); + if (child instanceof Group) { + DefaultMutableTreeNode childNode = createNode((Group)child); + node.add(childNode); + } + else { + node.add(new DefaultMutableTreeNode(child)); + } + } + return node; + } + + public static class Group { + private Group myParent; + private String myName; + private Icon myIcon; + private Icon myOpenIcon; + /** + * Group or action id (String) or Separator or QuickList + */ + private ArrayList myChildren; + + public Group(String name, Icon icon, Icon openIcon) { + myName = name; + myIcon = icon; + myOpenIcon = openIcon; + myChildren = new ArrayList(); + } + + public String getName() { + return myName; + } + + public Icon getIcon() { + return myIcon; + } + + public Icon getOpenIcon() { + return myOpenIcon; + } + + public void addActionId(String id) { + myChildren.add(id); + } + + public void addQuickList(QuickList list) { + myChildren.add(list); + } + + public void addGroup(Group group) { + myChildren.add(group); + group.myParent = this; + } + + public void addSeparator() { + myChildren.add(Separator.getInstance()); + } + + public boolean containsId(String id) { + for (int i=0; i < myChildren.size(); i++) { + Object child = myChildren.get(i); + if (child instanceof String) { + if (id.equals(child)) { + return true; + } + } + else if (child instanceof QuickList) { + if (((QuickList)child).getActionId().equals(id)) return true; + } + else if (child instanceof Group) { + if (((Group)child).containsId(id)) { + return true; + } + } + } + return false; + } + + public ArrayList getChildren() { + return myChildren; + } + + public int getSize() { + return myChildren.size(); + } + + public void normalizeSeparators() { + while (myChildren.size() > 0 && myChildren.get(0) instanceof Separator) { + myChildren.remove(0); + } + + while (myChildren.size() > 0 && myChildren.get(myChildren.size() - 1) instanceof Separator) { + myChildren.remove(myChildren.size() - 1); + } + + for (int i=1; i < myChildren.size() - 1; i++) { + if (myChildren.get(i) instanceof Separator && myChildren.get(i + 1) instanceof Separator) { + myChildren.remove(i); + i--; + } + } + } + + public String getActionQualifiedPath(String id) { + for (int i=0; i < myChildren.size(); i++) { + Object child = myChildren.get(i); + if (child instanceof QuickList) { + child = ((QuickList)child).getActionId(); + } + if (child instanceof String) { + if (id.equals(child)) { + AnAction action = ActionManager.getInstance().getAction(id); + String path; + if (action != null) { + path = action.getTemplatePresentation().getText(); + } + else { + path = id; + } + return !isRoot() ? getName() + " | " + path : path; + } + } + else if (child instanceof Group) { + String path = ((Group)child).getActionQualifiedPath(id); + if (path != null) { + return !isRoot() ? getName() + " | " + path : path; + } + } + } + return null; + } + + public boolean isRoot() { + return myParent == null; + } + + public String getQualifiedPath() { + StringBuffer path = new StringBuffer(64); + Group group = this; + while (group != null && !group.isRoot()) { + path.insert(0, group.getName() + " | "); + group = group.myParent; + } + return path.toString(); + } + + public void addAll(Group group) { + Iterator iterator = group.getChildren().iterator(); + while (iterator.hasNext()) { + Object o = iterator.next(); + if (o instanceof String) { + addActionId((String)o); + } + else if (o instanceof QuickList) { + addQuickList((QuickList)o); + } + else if (o instanceof Group) { + addGroup((Group)o); + } + else if (o instanceof Separator) { + addSeparator(); + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditKeymapsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditKeymapsDialog.java new file mode 100644 index 00000000000..c13a21eb64f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditKeymapsDialog.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; + +import javax.swing.*; + +public class EditKeymapsDialog extends SingleConfigurableEditor { + private String myActionToSelect; + + public EditKeymapsDialog(Project project, String actionToSelect) { + super(project, new KeymapConfigurable()); + myActionToSelect = actionToSelect; + } + + public void show() { + if (myActionToSelect != null) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ((KeymapConfigurable)myConfigurable).selectAction(myActionToSelect); + } + }); + } + super.show(); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.openapi.keymap.impl.ui.EditKeymapsDialog"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditQuickListDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditQuickListDialog.java new file mode 100644 index 00000000000..a7f785a9e7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/EditQuickListDialog.java @@ -0,0 +1,50 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; + +public class EditQuickListDialog extends DialogWrapper { + private QuickList myList; + private QuickList[] myAllQuickLists; + private QuickListPanel myPanel; + private Project myProject; + + public EditQuickListDialog(Project project, QuickList list, QuickList[] allQuickLists) { + super(project, true); + myProject = project; + myList = list; + myAllQuickLists = allQuickLists; + setTitle("Edit Quick List"); + init(); + } + + protected JComponent createCenterPanel() { + myPanel = new QuickListPanel(myList, myAllQuickLists, myProject); + return myPanel.getPanel(); + } + + public QuickList getList() { + return myList; + } + + protected void doOKAction() { + ListModel model = myPanel.getActionsList().getModel(); + int size = model.getSize(); + String[] ids = new String[size]; + for (int i = 0; i < size; i++) { + String actionId = (String)model.getElementAt(i); + ids[i] = actionId; + } + + myList = new QuickList(myPanel.getDisplayName(), myPanel.getDescription(), ids, myList.isReadonly()); + + super.doOKAction(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.openapi.keymap.impl.ui.EditQuickListDialog"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeyboardShortcutDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeyboardShortcutDialog.java new file mode 100644 index 00000000000..733e40179f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeyboardShortcutDialog.java @@ -0,0 +1,284 @@ +package com.intellij.openapi.keymap.impl.ui; + + +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; + +public class KeyboardShortcutDialog extends DialogWrapper { + private StrokePanel myFirstStrokePanel; + private StrokePanel mySecondStrokePanel; + private JCheckBox myEnableSecondKeystroke; + private JLabel myKeystrokePreview; + private JTextArea myConflictInfoArea; + private JScrollPane myConflictInfoScroll; + private Keymap myKeymap; + private String myActionId; + private ActionsTreeUtil.Group myMainGroup; + + public KeyboardShortcutDialog(Component component, String actionId, ActionsTreeUtil.Group mainGroup) { + super(component, true); + setTitle("Enter Keyboard Shortcut"); + myActionId = actionId; + myMainGroup = mainGroup; + myEnableSecondKeystroke = new JCheckBox("Enable:"); + myEnableSecondKeystroke.setFocusable(false); + myKeystrokePreview = new JLabel(" "); + myConflictInfoArea = new JTextArea(""); + myConflictInfoArea.setFocusable(false); + init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + // First stroke + + myFirstStrokePanel = new StrokePanel("First Stroke"); + panel.add( + myFirstStrokePanel, + new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,5,0),0,0) + ); + + // Second stroke panel + + panel.add( + myEnableSecondKeystroke, + new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0,0,5,0),0,0) + ); + + mySecondStrokePanel = new StrokePanel("Second Stroke"); + panel.add( + mySecondStrokePanel, + new GridBagConstraints(0,2,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,5,0),0,0) + ); + + // Shortcut preview + + JPanel previewPanel = new JPanel(new BorderLayout()); + previewPanel.setBorder( + BorderFactory.createCompoundBorder( + IdeBorderFactory.createTitledBorder("Shortcut Preview"), + BorderFactory.createEmptyBorder(5,5,5,5) + ) + ); + previewPanel.add(myKeystrokePreview); + panel.add( + previewPanel, + new GridBagConstraints(0,3,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,5,0),0,0) + ); + + // Conflicts + + JPanel conflictsPanel = new JPanel(new BorderLayout()); + conflictsPanel.setBorder(IdeBorderFactory.createTitledBorder("Conflicts")); + myConflictInfoArea.setEditable(false); + myConflictInfoArea.setBackground(panel.getBackground()); + myConflictInfoArea.setLineWrap(true); + myConflictInfoArea.setWrapStyleWord(true); + myConflictInfoScroll = new JScrollPane(myConflictInfoArea); + myConflictInfoScroll.setPreferredSize(new Dimension(260, 60)); + myConflictInfoScroll.setBorder(null); + conflictsPanel.add(myConflictInfoScroll); + panel.add( + conflictsPanel, + new GridBagConstraints(0,4,1,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0) + ); + + myEnableSecondKeystroke.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleSecondKey(); + updateCurrentKeyStrokeInfo(); + + /** TODO[anton]???? */ + if (myEnableSecondKeystroke.isSelected()) { + mySecondStrokePanel.getShortcutTextField().requestFocus(); + } + else { + myFirstStrokePanel.getShortcutTextField().requestFocus(); + } + } + }); + return panel; + } + + public JComponent getPreferredFocusedComponent(){ + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myFirstStrokePanel); + } + + public void setData(Keymap keymap, KeyboardShortcut shortcut) { + myKeymap = keymap; + myEnableSecondKeystroke.setSelected(false); + if (shortcut != null) { + myFirstStrokePanel.getShortcutTextField().setKeyStroke(shortcut.getFirstKeyStroke()); + if (shortcut.getSecondKeyStroke() != null) { + myEnableSecondKeystroke.setSelected(true); + mySecondStrokePanel.getShortcutTextField().setKeyStroke(shortcut.getSecondKeyStroke()); + } + } + handleSecondKey(); + updateCurrentKeyStrokeInfo(); + } + + private void updateCurrentKeyStrokeInfo() { + if (myConflictInfoArea == null || myKeystrokePreview == null){ + return; + } + + myConflictInfoArea.setText(null); + myKeystrokePreview.setText(" "); + + if (myKeymap == null){ + return; + } + + KeyboardShortcut keyboardShortcut = getKeyboardShortcut(); + if (keyboardShortcut == null){ + return; + } + + String strokeText = getTextByKeyStroke(keyboardShortcut.getFirstKeyStroke()); + String suffixText = getTextByKeyStroke(keyboardShortcut.getSecondKeyStroke()); + if(suffixText != null && suffixText.length() > 0) { + strokeText += ',' + suffixText; + } + myKeystrokePreview.setText(strokeText); + + StringBuffer buffer = new StringBuffer(); + + Map> conflicts = myKeymap.getConflicts(myActionId, keyboardShortcut); + + Set keys = conflicts.keySet(); + String[] actionIds = keys.toArray(new String[keys.size()]); + for(int i = 0; i < actionIds.length; i++) { + String actionId = actionIds[i]; + String actionPath = myMainGroup.getActionQualifiedPath(actionId); + // actionPath == null for editor actions having corresponding $-actions + if (actionPath == null){ + continue; + } + if(buffer.length() > 1) { + buffer.append('\n'); + } + buffer.append('['); + buffer.append(actionPath); + buffer.append(']'); + } + + if (buffer.length() == 0) { + myConflictInfoArea.setForeground(UIManager.getColor("TextArea.foreground")); + myConflictInfoArea.setText("No conflicts"); + } + else { + myConflictInfoArea.setForeground(Color.red); + myConflictInfoArea.setText("Assigned to " + buffer.toString()); + } + } + + private void handleSecondKey() { + mySecondStrokePanel.setEnabled(myEnableSecondKeystroke.isSelected()); + } + + public KeyboardShortcut getKeyboardShortcut() { + KeyStroke firstStroke = myFirstStrokePanel.getKeyStroke(); + if (firstStroke == null) { + return null; + } + KeyStroke secondStroke = myEnableSecondKeystroke.isSelected() ? mySecondStrokePanel.getKeyStroke() : null; + return new KeyboardShortcut(firstStroke, secondStroke); + } + + private String getTextByKeyStroke(KeyStroke keyStroke) { + if(keyStroke == null) { + return ""; + } + return KeymapUtil.getKeystrokeText(keyStroke); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("preferences.keymap.shortcut"); + } + + private class StrokePanel extends JPanel { + private final ShortcutTextField myShortcutTextField; + + public StrokePanel(String borderText) { + setLayout(new BorderLayout()); + setBorder( + BorderFactory.createCompoundBorder( + IdeBorderFactory.createTitledBorder(borderText), + BorderFactory.createEmptyBorder(5,5,5,5) + ) + ); + + myShortcutTextField = new ShortcutTextField(); + add(myShortcutTextField); + } + + public ShortcutTextField getShortcutTextField() { + return myShortcutTextField; + } + + public void setEnabled(boolean state) { + myShortcutTextField.setEnabled(state); + repaint(); + } + + public KeyStroke getKeyStroke() { + return myShortcutTextField.getKeyStroke(); + } + } + + public class ShortcutTextField extends JTextField { + private KeyStroke myKeyStroke; + + public ShortcutTextField() { + enableEvents(KeyEvent.KEY_EVENT_MASK); + setFocusTraversalKeysEnabled(false); + } + + protected void processKeyEvent(KeyEvent e) { + if (e.getID() == KeyEvent.KEY_PRESSED) { + int keyCode = e.getKeyCode(); + if ( + keyCode == KeyEvent.VK_SHIFT || + keyCode == KeyEvent.VK_ALT || + keyCode == KeyEvent.VK_CONTROL || + keyCode == KeyEvent.VK_ALT_GRAPH || + keyCode == KeyEvent.VK_META + ){ + return; + } + + setKeyStroke(KeyStroke.getKeyStroke(keyCode, e.getModifiers())); + } + } + + public void setKeyStroke(KeyStroke keyStroke) { + myKeyStroke = keyStroke; + setText(getTextByKeyStroke(keyStroke)); + updateCurrentKeyStrokeInfo(); + } + + public KeyStroke getKeyStroke() { + return myKeyStroke; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapConfigurable.java new file mode 100644 index 00000000000..878b9142f10 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapConfigurable.java @@ -0,0 +1,59 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class KeymapConfigurable extends BaseConfigurable implements ApplicationComponent { + private static final Icon icon = IconLoader.getIcon("/general/keymap.png"); + private KeymapPanel myPanel; + + public String getComponentName() { + return "KeymapConfigurable"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "Keymap"; + } + + public JComponent createComponent() { + myPanel = new KeymapPanel(); + return myPanel; + } + + public boolean isModified() { + return myPanel.isModified(); + } + + public Icon getIcon() { + return icon; + } + + public void apply() throws ConfigurationException { + myPanel.apply(); + } + + public void reset() { + myPanel.reset(); + } + + public void disposeUIResources() { + myPanel = null; + } + + public String getHelpTopic() { + return "preferences.keymap"; + } + + public void selectAction(String actionId) { + myPanel.selectAction(actionId); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java new file mode 100644 index 00000000000..38eb0bdcbf8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java @@ -0,0 +1,930 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.actionSystem.ex.QuickListsManager; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.impl.KeymapImpl; +import com.intellij.openapi.keymap.impl.KeymapManagerImpl; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ListUtil; +import com.intellij.ui.DocumentAdapter; +import com.intellij.util.containers.HashMap; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.event.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.*; +import java.util.List; + +public class KeymapPanel extends JPanel { + + private JList myKeymapList; + private JList myQuickListsList; + private JList myShortcutsList; + + private DefaultListModel myKeymapListModel = new DefaultListModel(); + private DefaultListModel myQuickListsModel = new DefaultListModel(); + + private KeymapImpl mySelectedKeymap; + private KeymapImpl myActiveKeymap; + + private JButton mySetActiveButton; + private JButton myCopyButton; + private JButton myDeleteButton; + private JButton myAddKeyboardShortcutButton; + private JButton myAddMouseShortcutButton; + private JButton myRemoveShortcutButton; + private JTextField myKeymapNameField; + private JLabel myBaseKeymapLabel; + private JLabel myDescriptionLabel; + + private JCheckBox myDisableMnemonicsCheckbox; + private ActionsTree myActionsTree; + private final DocumentListener myKeymapNameListener = new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + mySelectedKeymap.setName(myKeymapNameField.getText()); + myKeymapList.repaint(); + } + }; + + public KeymapPanel() { + setLayout(new BorderLayout()); + JPanel headerPanel = new JPanel(new GridLayout(1, 2)); + headerPanel.add(createKeymapListPanel()); + headerPanel.add(createQuickListsPanel()); + add(headerPanel, BorderLayout.NORTH); + add(createKeymapSettingsPanel(), BorderLayout.CENTER); + } + + private JPanel createQuickListsPanel() { + JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createTitledBorder("Quick lists")); + panel.setLayout(new BorderLayout()); + myQuickListsList = new JList(myQuickListsModel); + myQuickListsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myQuickListsList.setCellRenderer(new MyQuickListCellRenderer()); + + if (myQuickListsModel.size() > 0) { + myQuickListsList.setSelectedIndex(0); + } + + JScrollPane scrollPane = new JScrollPane(myQuickListsList); + scrollPane.setPreferredSize(new Dimension(180, 100)); + panel.add(scrollPane, BorderLayout.CENTER); + panel.add(createQuickListButtonsPanel(), BorderLayout.EAST); + + return panel; + } + + private JPanel createKeymapListPanel() { + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Keymaps")); + JPanel panel = panel1; + panel.setLayout(new BorderLayout()); + myKeymapList = new JList(myKeymapListModel); + myKeymapList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myKeymapList.setCellRenderer(new MyKeymapRenderer()); + JScrollPane scrollPane = new JScrollPane(myKeymapList); + scrollPane.setPreferredSize(new Dimension(180, 100)); + panel.add(scrollPane, BorderLayout.WEST); + + JPanel rightPanel = new JPanel(); + rightPanel.setLayout(new BorderLayout()); + + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BorderLayout()); + buttonsPanel.add(createKeymapButtonsPanel(), BorderLayout.NORTH); + + rightPanel.add(buttonsPanel, BorderLayout.WEST); + panel.add(rightPanel, BorderLayout.CENTER); + + myKeymapList.addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + processCurrentKeymapChanged(); + } + } + ); + + return panel; + } + + private void processCurrentKeymapChanged() { + myCopyButton.setEnabled(false); + myDeleteButton.setEnabled(false); + mySetActiveButton.setEnabled(false); + myKeymapNameField.getDocument().removeDocumentListener(myKeymapNameListener); + myKeymapNameField.setText(""); + myKeymapNameField.setEnabled(false); + myBaseKeymapLabel.setText(""); + myAddKeyboardShortcutButton.setEnabled(false); + myAddMouseShortcutButton.setEnabled(false); + myRemoveShortcutButton.setEnabled(false); + + KeymapImpl selectedKeymap = getSelectedKeymap(); + mySelectedKeymap = selectedKeymap; + if(selectedKeymap == null) { + myActionsTree.reset(new KeymapImpl(), getCurrentQuickListIds()); + return; + } + + myCopyButton.setEnabled(true); + myKeymapNameField.setText(mySelectedKeymap.getPresentableName()); + myKeymapNameField.getDocument().addDocumentListener(myKeymapNameListener); + + Keymap parent = mySelectedKeymap.getParent(); + if (parent != null) { + myBaseKeymapLabel.setText("Based on keymap: " + parent.getPresentableName()); + } + myDisableMnemonicsCheckbox.setSelected(!mySelectedKeymap.areMnemonicsEnabled()); + myDisableMnemonicsCheckbox.setEnabled(mySelectedKeymap.canModify()); + if(mySelectedKeymap.canModify()) { + myDeleteButton.setEnabled(true); + myKeymapNameField.setEnabled(true); + myAddKeyboardShortcutButton.setEnabled(true); + myAddMouseShortcutButton.setEnabled(true); + myRemoveShortcutButton.setEnabled(true); + } + mySetActiveButton.setEnabled(mySelectedKeymap != myActiveKeymap); + + myActionsTree.reset(mySelectedKeymap, getCurrentQuickListIds()); + + updateShortcutsList(); + } + + private QuickList[] getCurrentQuickListIds() { + int size = myQuickListsModel.size(); + QuickList[] lists = new QuickList[size]; + for (int i = 0; i < lists.length; i++) { + lists[i] = (QuickList)myQuickListsModel.getElementAt(i); + } + return lists; + } + + private KeymapImpl getSelectedKeymap() { + return (KeymapImpl)myKeymapList.getSelectedValue(); + } + + private List getAllKeymaps() { + ListModel model = myKeymapList.getModel(); + List result = new ArrayList(); + for (int i = 0; i < model.getSize(); i++) { + result.add((Keymap)model.getElementAt(i)); + } + return result; + } + + private JPanel createShortcutsPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + JLabel currentKeysLabel = new JLabel("Shortcuts:"); + currentKeysLabel.setDisplayedMnemonic('u'); + panel.add(currentKeysLabel, new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.NONE, new Insets(0, 0, 0, 8), 0, 0)); + + myShortcutsList = new JList(new DefaultListModel()); + myShortcutsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myShortcutsList.setCellRenderer(new ShortcutListRenderer()); + currentKeysLabel.setLabelFor(myShortcutsList); + JScrollPane scrollPane = new JScrollPane(myShortcutsList); + scrollPane.setPreferredSize(new Dimension(160, 200)); + panel.add(scrollPane, new GridBagConstraints(1,1,1,1,1,1,GridBagConstraints.WEST,GridBagConstraints.BOTH, new Insets(0, 0, 0, 8), 0, 0)); + + panel.add( + createShortcutsButtonsPanel(), + new GridBagConstraints(2,1,1,1,0,0,GridBagConstraints.NORTH,GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0) + ); + + myActionsTree.addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateShortcutsList(); + } + } + ); + + return panel; + } + + private JPanel createQuickListButtonsPanel() { + JPanel panel = new JPanel(new VerticalFlowLayout()); + final JButton newList = new JButton("Add"); + final JButton editList = new JButton("Edit"); + final JButton removeList = new JButton("Remove"); + + newList.setMnemonic('d'); + editList.setMnemonic('E'); + removeList.setMnemonic('v'); + + newList.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + QuickList newGroup = new QuickList("unnamed", "", ArrayUtil.EMPTY_STRING_ARRAY, false); + QuickList edited = editList(newGroup); + if (edited != null) { + myQuickListsModel.addElement(edited); + myQuickListsList.setSelectedIndex(myQuickListsModel.getSize() - 1); + processCurrentKeymapChanged(); + } + } + }); + + editList.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editSelectedQuickList(); + } + }); + + removeList.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + deleteSelectedQuickList(); + } + }); + + myQuickListsList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + boolean enabled = myQuickListsList.getSelectedIndex() >= 0; + removeList.setEnabled(enabled); + editList.setEnabled(enabled); + } + }); + + panel.add(newList); + panel.add(editList); + panel.add(removeList); + + editList.setEnabled(false); + removeList.setEnabled(false); + + return panel; + } + + private void deleteSelectedQuickList() { + int idx = myQuickListsList.getSelectedIndex(); + if (idx < 0) return; + + QuickList list = (QuickList)myQuickListsModel.remove(idx); + list.unregisterAllShortcuts(getAllKeymaps()); + + int size = myQuickListsModel.getSize(); + if (size > 0) { + myQuickListsList.setSelectedIndex(Math.min(idx, size - 1)); + } + + processCurrentKeymapChanged(); + } + + private QuickList editList(QuickList list) { + List allKeymaps = getAllKeymaps(); + Map> listShortcuts = list.getShortcutMap(allKeymaps); + list.unregisterAllShortcuts(allKeymaps); + + Project project = (Project)DataManager.getInstance().getDataContext(this).getData(DataConstants.PROJECT); + EditQuickListDialog dlg = new EditQuickListDialog(project, list, getCurrentQuickListIds()); + dlg.show(); + + QuickList editedList = dlg.getList(); + editedList.registerShortcuts(listShortcuts, allKeymaps); + + return dlg.isOK() ? editedList : null; + } + + private void editSelectedQuickList() { + QuickList list = (QuickList)myQuickListsList.getSelectedValue(); + if (list == null) return; + + QuickList newList = editList(list); + if (newList != null) { + myQuickListsModel.set(myQuickListsList.getSelectedIndex(), newList); + processCurrentKeymapChanged(); + } + } + + private JPanel createKeymapButtonsPanel() { + JPanel panel = new JPanel(); + panel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + panel.setLayout(new GridLayout(3, 1, 8, 4)); + mySetActiveButton = new JButton("Set Active"); + mySetActiveButton.setMnemonic('A'); + mySetActiveButton.setMargin(new Insets(2,2,2,2)); + panel.add(mySetActiveButton); + myCopyButton = new JButton("Copy"); + myCopyButton.setMnemonic('C'); + myCopyButton.setMargin(new Insets(2,2,2,2)); + panel.add(myCopyButton); + myDeleteButton = new JButton("Delete"); + myDeleteButton.setMnemonic('l'); + myDeleteButton.setMargin(new Insets(2,2,2,2)); + panel.add(myDeleteButton); + + mySetActiveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + setKeymapActive(); + } + } + ); + + myCopyButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + copyKeymap(); + } + } + ); + + myDeleteButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + deleteKeymap(); + } + } + ); + + return panel; + } + + private JPanel createKeymapSettingsPanel() { + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Keymap Settings")); + JPanel panel = panel1; + panel.setLayout(new GridBagLayout()); + + panel.add(createKeymapNamePanel(), new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(5,0,0,0),0,0)); + +/* + JLabel actionsLabel = new JLabel("Actions:"); + actionsLabel.setDisplayedMnemonic('t'); + actionsLabel.setHorizontalAlignment(JLabel.LEFT); + actionsLabel.setHorizontalTextPosition(JLabel.LEFT); + panel.add(actionsLabel, new GridBagConstraints(0,2,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(5,0,0,0),0,0)); +*/ + + myActionsTree = new ActionsTree(); + JComponent component = myActionsTree.getComponent(); +// actionsLabel.setLabelFor(component); + component.setPreferredSize(new Dimension(100, 300)); + + panel.add(component, new GridBagConstraints(0,3,1,1,1,1,GridBagConstraints.WEST,GridBagConstraints.BOTH,new Insets(5,0,0,0),0,0)); + + panel.add(createShortcutsPanel(), new GridBagConstraints(0,4,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(5,0,0,0),0,0)); + + panel.add(createDescriptionPanel(), new GridBagConstraints(0,5,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(5,0,0,0),0,0)); + + return panel; + } + + private JPanel createDescriptionPanel() { + JPanel panel1 = new JPanel(); + panel1.setBorder(IdeBorderFactory.createTitledBorder("Action Description")); + JPanel panel = panel1; + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + myDescriptionLabel = new JLabel(" "); + panel.add(myDescriptionLabel, gbConstraints); + return panel; + } + + private JPanel createKeymapNamePanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + panel.add(new JLabel("Keymap name:"), new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0, 0, 0, 8),0,0)); + + myKeymapNameField = new JTextField(); + Dimension dimension = new Dimension(150, myKeymapNameField.getPreferredSize().height); + myKeymapNameField.setPreferredSize(dimension); + myKeymapNameField.setMinimumSize(dimension); + panel.add(myKeymapNameField, new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0, 8, 0, 0),0,0)); + + myBaseKeymapLabel = new JLabel("Parent keymap:"); + Dimension preferredSize = myBaseKeymapLabel.getPreferredSize(); + myBaseKeymapLabel.setPreferredSize(new Dimension(preferredSize.width*2,preferredSize.height)); + panel.add(myBaseKeymapLabel, new GridBagConstraints(2,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0, 16, 0, 8),0,0)); + + myDisableMnemonicsCheckbox = new JCheckBox("Disable mnemonics in menu"); + myDisableMnemonicsCheckbox.setMnemonic('M'); + myDisableMnemonicsCheckbox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + mySelectedKeymap.setDisableMnemonics(myDisableMnemonicsCheckbox.isSelected()); + } + }); + panel.add(myDisableMnemonicsCheckbox, new GridBagConstraints(3,0,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0, 0, 0, 0),0,0)); + + return panel; + } + + private JPanel createShortcutsButtonsPanel() { + JPanel panel = new JPanel(new GridLayout(3, 1, 0, 4)); + panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + myAddKeyboardShortcutButton = new JButton("Add Keyboard Shortcut..."); + myAddKeyboardShortcutButton.setMnemonic('K'); + panel.add(myAddKeyboardShortcutButton); + + myAddMouseShortcutButton=new JButton("Add Mouse Shortcut..."); + myAddMouseShortcutButton.setMnemonic('M'); + panel.add(myAddMouseShortcutButton); + + myRemoveShortcutButton = new JButton("Remove"); + myRemoveShortcutButton.setMnemonic('R'); + panel.add(myRemoveShortcutButton); + + myAddKeyboardShortcutButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + addKeyboardShortcut(); + } + } + ); + + myAddMouseShortcutButton.addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent e){ + addMouseShortcut(); + } + } + ); + + myRemoveShortcutButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + removeShortcut(); + } + } + ); + + return panel; + } + + private void addKeyboardShortcut() { + String actionId = myActionsTree.getSelectedActionId(); + if (actionId == null) { + return; + } + + ActionsTreeUtil.Group group = myActionsTree.getMainGroup(); + KeyboardShortcutDialog dialog = new KeyboardShortcutDialog(this, actionId, group); + + Shortcut selected = (Shortcut)myShortcutsList.getSelectedValue(); + KeyboardShortcut selectedKeyboardShortcut = selected instanceof KeyboardShortcut ? (KeyboardShortcut)selected : null; + + dialog.setData(mySelectedKeymap, selectedKeyboardShortcut); + dialog.show(); + if (!dialog.isOK()){ + return; + } + + KeyboardShortcut keyboardShortcut = dialog.getKeyboardShortcut(); + + if (keyboardShortcut == null) return; + + HashMap> conflicts = mySelectedKeymap.getConflicts(actionId, keyboardShortcut); + if(conflicts.size() > 0) { + int result = Messages.showDialog( + this, + "The shortcut is already assigned to other actions.\nDo you want to remove other assignments?", + "Warning", + new String[]{"Remove", "Leave", "Cancel"}, + 0, + Messages.getWarningIcon()); + + if(result == 0) { + for(Iterator actionIds = conflicts.keySet().iterator(); actionIds.hasNext(); ) { + String id = actionIds.next(); + ArrayList list = conflicts.get(id); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + KeyboardShortcut shortcut = iterator.next(); + mySelectedKeymap.removeShortcut(id, shortcut); + } + } + } + else if (result != 1) { + return; + } + } + + // if shortcut is aleady registered to this action, just select it in the list + + Shortcut[] shortcuts = mySelectedKeymap.getShortcuts(actionId); + for (int i = 0; i < shortcuts.length; i++) { + Shortcut shortcut = shortcuts[i]; + if (shortcut.equals(keyboardShortcut)) { + myShortcutsList.setSelectedIndex(i); + return; + } + } + + mySelectedKeymap.addShortcut(actionId, keyboardShortcut); + if (StringUtil.startsWithChar(actionId, '$')) { + mySelectedKeymap.addShortcut("Editor" + actionId.substring(1), keyboardShortcut); + } + updateShortcutsList(); + myShortcutsList.setSelectedIndex(myShortcutsList.getModel().getSize()-1); + + repaintLists(); + } + + private void addMouseShortcut(){ + String actionId = myActionsTree.getSelectedActionId(); + if (actionId == null) { + return; + } + + Shortcut shortcut = (Shortcut)myShortcutsList.getSelectedValue(); + MouseShortcut mouseShortcut = shortcut instanceof MouseShortcut ? (MouseShortcut)shortcut : null; + + MouseShortcutDialog dialog = new MouseShortcutDialog( + this, + mouseShortcut, + mySelectedKeymap, + actionId, + myActionsTree.getMainGroup() + ); + dialog.show(); + if (!dialog.isOK()){ + return; + } + + mouseShortcut = dialog.getMouseShortcut(); + + if (mouseShortcut == null){ + return; + } + + String[] actionIds = mySelectedKeymap.getActionIds(mouseShortcut); + if(actionIds.length > 1 || (actionIds.length == 1 && !actionId.equals(actionIds[0]))) { + int result = Messages.showDialog( + this, + "The shortcut is already assigned to other actions.\nDo you want to remove other assignments?", + "Warning", + new String[]{"Remove", "Leave", "Cancel"}, + 0, + Messages.getWarningIcon()); + + if(result == 0) { + for(int i = 0; i < actionIds.length; i++) { + String id = actionIds[i]; + mySelectedKeymap.removeShortcut(id, mouseShortcut); + } + } + else if (result != 1) { + return; + } + } + + // if shortcut is aleady registered to this action, just select it in the list + + Shortcut[] shortcuts = mySelectedKeymap.getShortcuts(actionId); + for (int i = 0; i < shortcuts.length; i++) { + if (shortcuts[i].equals(mouseShortcut)) { + myShortcutsList.setSelectedIndex(i); + return; + } + } + + mySelectedKeymap.addShortcut(actionId, mouseShortcut); + if (StringUtil.startsWithChar(actionId, '$')) { + mySelectedKeymap.addShortcut("Editor" + actionId.substring(1), mouseShortcut); + } + updateShortcutsList(); + myShortcutsList.setSelectedIndex(myShortcutsList.getModel().getSize()-1); + + repaintLists(); + } + + private void repaintLists() { + myActionsTree.getComponent().repaint(); + myKeymapList.repaint(); + } + + private void removeShortcut() { + String actionId = myActionsTree.getSelectedActionId(); + if (actionId == null) { + return; + } + Shortcut shortcut = (Shortcut)myShortcutsList.getSelectedValue(); + if(shortcut == null) { + return; + } + int selectedIndex = myShortcutsList.getSelectedIndex(); + mySelectedKeymap.removeShortcut(actionId, shortcut); + if (StringUtil.startsWithChar(actionId, '$')) { + mySelectedKeymap.removeShortcut("Editor" + actionId.substring(1), shortcut); + } + + updateShortcutsList(); + + int count = myShortcutsList.getModel().getSize(); + if(count > 0) { + myShortcutsList.setSelectedIndex(Math.max(selectedIndex-1, 0)); + } + else { + myShortcutsList.clearSelection(); + } + + repaintLists(); + } + + private void setKeymapActive() { + KeymapImpl keymap = getSelectedKeymap(); + if(keymap != null) { + myActiveKeymap = keymap; + } + myKeymapList.repaint(); + processCurrentKeymapChanged(); + } + + private void copyKeymap() { + KeymapImpl keymap = getSelectedKeymap(); + if(keymap == null) { + return; + } + KeymapImpl newKeymap = keymap.deriveKeymap(); + + String newKeymapName = "unnamed"; + if(!tryNewKeymapName(newKeymapName)) { + for(int i=0; ; i++) { + newKeymapName = "unnamed"+i; + if(tryNewKeymapName(newKeymapName)) { + break; + } + } + } + newKeymap.setName(newKeymapName); + newKeymap.setCanModify(true); + myKeymapListModel.addElement(newKeymap); + myKeymapList.setSelectedValue(newKeymap, true); + processCurrentKeymapChanged(); + + int result = Messages.showYesNoDialog(this, "Make the new keymap active?", "New Keymap", Messages.getQuestionIcon()); + if(result == 0) { + myActiveKeymap = newKeymap; + myKeymapList.repaint(); + } + + if (myKeymapNameField.isEnabled()) { + myKeymapNameField.setSelectionStart(0); + myKeymapNameField.setSelectionEnd(myKeymapNameField.getText().length()); + myKeymapNameField.requestFocus(); + + } + } + + private boolean tryNewKeymapName(String name) { + for(int i=0; i= 0) { + if (myActiveKeymap == keymap) { + myActiveKeymap = (KeymapImpl)myKeymapListModel.getElementAt(0); + } + } + else { + myActiveKeymap = null; + } + processCurrentKeymapChanged(); + myKeymapList.repaint(); + } + + + private void updateShortcutsList() { + DefaultListModel shortcutsModel = (DefaultListModel)myShortcutsList.getModel(); + shortcutsModel.clear(); + String actionId = myActionsTree.getSelectedActionId(); + myDescriptionLabel.setText(" "); + if (actionId != null && mySelectedKeymap != null) { + AnAction action = ActionManager.getInstance().getAction(actionId); + if (action != null) { + String description = action.getTemplatePresentation().getDescription(); + if (description != null && description.trim().length() > 0) { + myDescriptionLabel.setText(description); + } + } + else { + QuickList list = myActionsTree.getSelectedQuickList(); + if (list != null) { + String description = list.getDescription().trim(); + if (description.length() > 0) { + myDescriptionLabel.setText(description); + } + } + } + + Shortcut[] shortcuts = mySelectedKeymap.getShortcuts(actionId); + for(int i = 0; i < shortcuts.length; i++){ + shortcutsModel.addElement(shortcuts[i]); + } + if(shortcutsModel.size() > 0) { + myShortcutsList.setSelectedIndex(0); + } + + myAddKeyboardShortcutButton.setEnabled(mySelectedKeymap.canModify()); + myAddMouseShortcutButton.setEnabled(mySelectedKeymap.canModify()); + myRemoveShortcutButton.setEnabled(mySelectedKeymap.canModify() && shortcutsModel.size() > 0); + } + else { + myAddKeyboardShortcutButton.setEnabled(false); + myAddMouseShortcutButton.setEnabled(false); + myRemoveShortcutButton.setEnabled(false); + } + } + + private final class MyKeymapRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, selected, cellHasFocus); + Keymap keymap = (Keymap)value; + + // Set color and font. + + Font font = getFont(); + if(keymap == myActiveKeymap) { + font = font.deriveFont(Font.BOLD); + } + setFont(font); + if(selected){ + setForeground(UIManager.getColor("List.selectionForeground")); + }else{ + if(keymap.canModify()){ + setForeground(UIManager.getColor("List.foreground")); + }else{ + setForeground(Color.GRAY); + } + } + + // Set text. + + String name = keymap.getPresentableName(); + if(name == null) { + name = ""; + } + if(keymap == myActiveKeymap) { + name += " (active)"; + } + setText(name); + return this; + } + } + + private static final class ShortcutListRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + Shortcut shortcut = (Shortcut)value; + setText(KeymapUtil.getShortcutText(shortcut)); + setIcon(KeymapUtil.getShortcutIcon(shortcut)); + return this; + } + } + + public void reset() { + myKeymapListModel.removeAllElements(); + KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx(); + Keymap[] keymaps = keymapManager.getAllKeymaps(); + for(int i = 0; i < keymaps.length; i++){ + KeymapImpl keymap = (KeymapImpl)keymaps[i]; + if(keymap.canModify()) { + keymap = keymap.copy(); + } + myKeymapListModel.addElement(keymap); + if(keymapManager.getActiveKeymap() == keymaps[i]) { + myActiveKeymap = keymap; + } + } + + if(myKeymapListModel.getSize() == 0) { + KeymapImpl keymap = new KeymapImpl(); + keymap.setName(""); + myKeymapListModel.addElement(keymap); + } + + myActionsTree.reset(myActiveKeymap, QuickListsManager.getInstance().getAllQuickLists()); + + myQuickListsModel.removeAllElements(); + QuickList[] allQuickLists = QuickListsManager.getInstance().getAllQuickLists(); + for (int i = 0; i < allQuickLists.length; i++) { + QuickList list = allQuickLists[i]; + myQuickListsModel.addElement(list); + } + + mySelectedKeymap = (KeymapImpl)myKeymapListModel.elementAt(0); + myKeymapList.setSelectedValue(myActiveKeymap, true); + processCurrentKeymapChanged(); + } + + public void apply() throws ConfigurationException{ + HashSet keymapNames = new HashSet(); + for(int i = 0; i < myKeymapListModel.getSize(); i++){ + Keymap keymap = (Keymap)myKeymapListModel.elementAt(i); + String name = keymap.getName(); + if (keymapNames.contains(name)) { + throw new ConfigurationException("All keymaps should have unique names"); + } + keymapNames.add(name); + } + + KeymapManagerImpl keymapManager = (KeymapManagerImpl)KeymapManager.getInstance(); + keymapManager.removeAllKeymapsExceptUnmodifiable(); + for(int i = 0; i < myKeymapListModel.getSize(); i++){ + Keymap keymap = (Keymap)myKeymapListModel.elementAt(i); + if(keymap.canModify()) { + keymapManager.addKeymap(keymap); + } + } + keymapManager.setActiveKeymap(myActiveKeymap); + try { + keymapManager.save(); + } + catch (IOException e) { + throw new ConfigurationException(e.getMessage()); + } + + QuickListsManager.getInstance().removeAllQuickLists(); + int size = myQuickListsModel.getSize(); + for (int i = 0; i < size; i++) { + QuickList list = (QuickList)myQuickListsModel.getElementAt(i); + QuickListsManager.getInstance().registerQuickList(list, false); + } + + QuickListsManager.getInstance().registerActions(); + } + + boolean isModified() { + KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx(); + if (!Comparing.equal(myActiveKeymap, keymapManager.getActiveKeymap())) { + return true; + } + Keymap[] managerKeymaps = keymapManager.getAllKeymaps(); + Keymap[] panelKeymaps = new Keymap[myKeymapListModel.getSize()]; + for(int i = 0; i < myKeymapListModel.getSize(); i++){ + panelKeymaps[i] = (Keymap)myKeymapListModel.elementAt(i); + } + + if (!Comparing.equal(managerKeymaps, panelKeymaps)) return true; + QuickList[] storedLists = QuickListsManager.getInstance().getAllQuickLists(); + + QuickList[] modelLists = new QuickList[myQuickListsModel.getSize()]; + for (int i = 0; i < modelLists.length; i++) { + modelLists[i] = (QuickList)myQuickListsModel.getElementAt(i); + } + + return !Comparing.equal(storedLists, modelLists); + } + + public Dimension getPreferredSize() { + //TODO[anton]: it's a hack!!! + Dimension preferredSize = super.getPreferredSize(); + if (preferredSize.height > 600) { + preferredSize.height = 600; + } + return preferredSize; + } + + public void selectAction(String actionId) { + myActionsTree.selectAction(actionId); + } + + private static class MyQuickListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + QuickList quickList = (QuickList)value; + setText(quickList.getDisplayName()); + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/MouseShortcutDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/MouseShortcutDialog.java new file mode 100644 index 00000000000..770501e607c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/MouseShortcutDialog.java @@ -0,0 +1,281 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.openapi.actionSystem.MouseShortcut; +import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Vladimir Kondratyev + */ +class MouseShortcutDialog extends DialogWrapper{ + private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.keymap.impl.ui.MouseShortcutDialog"); + + private final Keymap myKeymap; + private final String myActionId; + private final ActionsTreeUtil.Group myMainGroup; + + private final JRadioButton myRbSingleClick; + private final JRadioButton myRbDoubleClick; + private final JLabel myLblPreview; + private final MyClickPad myClickPad; + private final JTextArea myTarConflicts; + + private int myButton; + private int myModifiers; + + /** + * @param shortcut dialog will be initialized with this shortcut. It can be null + * if dialog is used to create new mouse shortcut. + */ + public MouseShortcutDialog( + JComponent parentComponent, + MouseShortcut shortcut, + Keymap keymap, + String actiondId, + ActionsTreeUtil.Group mainGroup + ){ + super(parentComponent,true); + setTitle("Enter Mouse Shortcut"); + + LOG.assertTrue(keymap!=null); + myKeymap=keymap; + LOG.assertTrue(actiondId!=null); + myActionId=actiondId; + LOG.assertTrue(mainGroup!=null); + myMainGroup=mainGroup; + + myRbSingleClick=new JRadioButton("Single Click"); + myRbDoubleClick=new JRadioButton("Double-Click"); + ButtonGroup buttonGroup=new ButtonGroup(); + buttonGroup.add(myRbSingleClick); + buttonGroup.add(myRbDoubleClick); + + myLblPreview=new JLabel(" "); + + myClickPad=new MyClickPad(); + + myTarConflicts=new JTextArea(); + myTarConflicts.setFocusable(false); + myTarConflicts.setEditable(false); + myTarConflicts.setBackground(UIManager.getColor("Panel.background")); + myTarConflicts.setLineWrap(true); + myTarConflicts.setWrapStyleWord(true); + + if(shortcut!=null){ + if(shortcut.getClickCount()==1){ + myRbSingleClick.setSelected(true); + }else{ + myRbDoubleClick.setSelected(true); + } + myButton=shortcut.getButton(); + myModifiers=shortcut.getModifiers(); + }else{ + myRbSingleClick.setSelected(true); + myButton=-1; + myModifiers=-1; + } + + updatePreviewAndConflicts(); + + init(); + } + + /** + * @return created/edited shortcut. Returns null if shortcut is invalid. + */ + public MouseShortcut getMouseShortcut(){ + if(myButton!=-1 && myModifiers!=-1){ + return new MouseShortcut(myButton,myModifiers,myRbSingleClick.isSelected()?1:2); + }else{ + return null; + } + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected JComponent createCenterPanel(){ + JPanel panel=new JPanel(new GridBagLayout()); + + // Single/Double click + + JPanel clickCountPanel=new JPanel(new GridBagLayout()); + clickCountPanel.setBorder(IdeBorderFactory.createTitledBorder("Click Count")); + panel.add( + clickCountPanel, + new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,4,0),0,0) + ); + clickCountPanel.add( + myRbSingleClick, + new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0,0,0,10),0,0) + ); + clickCountPanel.add( + myRbDoubleClick, + new GridBagConstraints(1,0,1,1,1,0,GridBagConstraints.EAST,GridBagConstraints.NONE,new Insets(0,0,0,0),0,0) + ); + + ActionListener listener=new ActionListener(){ + public void actionPerformed(ActionEvent e){ + updatePreviewAndConflicts(); + } + }; + myRbSingleClick.addActionListener(listener); + myRbDoubleClick.addActionListener(listener); + + // Click pad + + JPanel clickPadPanel=new JPanel(new BorderLayout()); + panel.add( + clickPadPanel, + new GridBagConstraints(0,1,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,4,0),0,0) + ); + clickPadPanel.setBorder(IdeBorderFactory.createTitledBorder("Click Pad")); + myClickPad.setPreferredSize(new Dimension(260,60)); + clickPadPanel.add(myClickPad,BorderLayout.CENTER); + + // Shortcut preview + + JPanel previewPanel=new JPanel(new GridBagLayout()); + previewPanel.setBorder(IdeBorderFactory.createTitledBorder("Shortcut Preview")); + panel.add( + previewPanel, + new GridBagConstraints(0,2,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,4,0),0,0) + ); + previewPanel.add( + myLblPreview, + new GridBagConstraints(0,0,1,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(2,2,2,2),0,0) + ); + + // Conflicts panel + + JPanel conflictsPanel=new JPanel(new GridBagLayout()); + conflictsPanel.setBorder(IdeBorderFactory.createTitledBorder("Conflicts")); + panel.add( + conflictsPanel, + new GridBagConstraints(0,3,1,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0) + ); + myTarConflicts.setPreferredSize(new Dimension(260,60)); + JScrollPane scrollPane=new JScrollPane(myTarConflicts); + scrollPane.setBorder(null); + conflictsPanel.add( + scrollPane, + new GridBagConstraints(0,0,1,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0) + ); + + return panel; + } + + /** + * Updates all UI controls + */ + private void updatePreviewAndConflicts(){ + if(myButton==-1||myModifiers==-1){ + return; + } + + myTarConflicts.setText(null); + + // Set text into preview area + + // empty string should have same height + myLblPreview.setText(KeymapUtil.getMouseShortcutText(myButton,myModifiers,myRbSingleClick.isSelected()?1:2) + " "); + + // Detect conflicts + + final MouseShortcut mouseShortcut; + if(myRbSingleClick.isSelected()){ + mouseShortcut=new MouseShortcut(myButton,myModifiers,1); + }else{ + mouseShortcut=new MouseShortcut(myButton,myModifiers,2); + } + + StringBuffer buffer = new StringBuffer(); + String[] actionIds = myKeymap.getActionIds(mouseShortcut); + for(int i = 0; i < actionIds.length; i++) { + String actionId = actionIds[i]; + if (actionId.equals(myActionId)){ + continue; + } + + String actionPath = myMainGroup.getActionQualifiedPath(actionId); + // actionPath == null for editor actions having corresponding $-actions + if (actionPath == null){ + continue; + } + + Shortcut[] shortcuts = myKeymap.getShortcuts(actionId); + for (int j = 0; j < shortcuts.length; j++) { + if (!(shortcuts[j] instanceof MouseShortcut)){ + continue; + } + + MouseShortcut shortcut = (MouseShortcut)shortcuts[j]; + + if ( + shortcut.getButton() != mouseShortcut.getButton() || + shortcut.getModifiers() != mouseShortcut.getModifiers() + ){ + continue; + } + + if(buffer.length() > 1) { + buffer.append('\n'); + } + buffer.append('['); + buffer.append(actionPath); + buffer.append(']'); + break; + } + } + + if (buffer.length() == 0) { + myTarConflicts.setForeground(UIManager.getColor("TextArea.foreground")); + myTarConflicts.setText("No conflicts"); + } + else { + myTarConflicts.setForeground(Color.red); + myTarConflicts.setText("Assigned to " + buffer.toString()); + } + } + + private class MyClickPad extends JLabel{ + public MyClickPad(){ + super( + "Click here to enter mouse shortcut", + IconLoader.getIcon("/general/mouse.png"), + JLabel.CENTER + ); + // It's very imporatant that MouseListener is added to the Dialog. If you add + // the same listener, for example, into the MyClickPad component you get fake + // Alt and Meta modifiers. I means that pressing of middle button causes + // Alt+Button2 event. + // See bug ID 4109826 on Sun's bug parade. + MouseShortcutDialog.this.addMouseListener( + new MouseAdapter(){ + public void mouseReleased(MouseEvent e){ + Component component=SwingUtilities.getDeepestComponentAt(e.getComponent(),e.getX(),e.getY()); + if(component==MyClickPad.this){ + e.consume(); + myButton=e.getButton(); + myModifiers=e.getModifiersEx(); + updatePreviewAndConflicts(); + } + } + } + ); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java new file mode 100644 index 00000000000..4c4ccd3d37c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java @@ -0,0 +1,320 @@ +package com.intellij.openapi.keymap.impl.ui; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.Separator; +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.project.Project; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; + +public class QuickListPanel { + private static final Icon EMPTY_ICON = EmptyIcon.create(16, 16); + + private JButton myRemoveActionButton; + private JButton myIncludeActionButton; + private JButton myMoveActionDownButton; + private JButton myMoveActionUpButton; + private JPanel myPanel; + private JTree myActionsTree; + private JList myActionsList; + private JTextField myDisplayName; + private JTextField myDescription; + private JButton myAddSeparatorButton; + + public QuickListPanel(QuickList origin, final QuickList[] allQuickLists, Project project) { + ActionsTreeUtil.Group rootGroup = ActionsTreeUtil.createMainGroup(project, null, allQuickLists); + DefaultMutableTreeNode root = ActionsTreeUtil.createNode(rootGroup); + DefaultTreeModel model = new DefaultTreeModel(root); + myActionsTree.setModel(model); + myActionsTree.setCellRenderer(new MyTreeCellRenderer()); + + myActionsList.setModel(new DefaultListModel()); + myActionsList.setCellRenderer(new MyListCellRenderer()); + + myActionsTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + update(); + } + }); + + myActionsTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2 && !e.isPopupTrigger()) { + includeSelectedAction(); + } + } + }); + + myActionsList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2 && !e.isPopupTrigger()) { + excludeSelectionAction(); + } + } + }); + + myActionsList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + update(); + } + }); + + myActionsTree.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + includeSelectedAction(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + myIncludeActionButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + includeSelectedAction(); + } + }); + + myAddSeparatorButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addSeparator(); + } + }); + + myActionsList.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + excludeSelectionAction(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + myRemoveActionButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + excludeSelectionAction(); + } + }); + + myMoveActionUpButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int idx = myActionsList.getSelectedIndex(); + if (idx > 0) { + DefaultListModel listModel = (DefaultListModel)myActionsList.getModel(); + Object oldValue = listModel.get(idx); + listModel.removeElementAt(idx); + listModel.add(--idx, oldValue); + myActionsList.getSelectionModel().setSelectionInterval(idx, idx); + } + } + }); + + myMoveActionDownButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int idx = myActionsList.getSelectedIndex(); + DefaultListModel listModel = (DefaultListModel)myActionsList.getModel(); + if (idx < listModel.getSize() - 1) { + Object oldValue = listModel.get(idx); + listModel.removeElementAt(idx); + listModel.add(++idx, oldValue); + myActionsList.getSelectionModel().setSelectionInterval(idx, idx); + } + } + }); + + myDisplayName.setText(origin.getDisplayName()); + myDescription.setText(origin.getDescription()); + + String[] ids = origin.getActionIds(); + for (int i = 0; i < ids.length; i++) { + includeActionId(ids[i]); + } + + update(); + } + + private void excludeSelectionAction() { + Object[] ids = myActionsList.getSelectedValues(); + for (int i = 0; i < ids.length; i++) { + ((DefaultListModel)myActionsList.getModel()).removeElement(ids[i]); + } + update(); + } + + private void includeSelectedAction() { + String[] ids = getTreeSelectedActionIds(); + for (int i = 0; i < ids.length; i++) { + includeActionId(ids[i]); + } + DefaultListModel listModel = (DefaultListModel)myActionsList.getModel(); + int size = listModel.getSize(); + ListSelectionModel selectionModel = myActionsList.getSelectionModel(); + if (size > 0) { + selectionModel.removeIndexInterval(0, size - 1); + } + for (int i = 0; i < ids.length; i++) { + int idx = listModel.lastIndexOf(ids[i]); + if (idx >= 0) { + selectionModel.addSelectionInterval(idx, idx); + } + } + update(); + } + + private void addSeparator() { + DefaultListModel model = (DefaultListModel)myActionsList.getModel(); + model.addElement(QuickList.SEPARATOR_ID); + update(); + } + + public JList getActionsList() { + return myActionsList; + } + + public String getDescription() { + return myDescription.getText(); + } + + public String getDisplayName() { + return myDisplayName.getText(); + } + + private void update() { + myIncludeActionButton.setEnabled(getTreeSelectedActionIds().length > 0); + myRemoveActionButton.setEnabled(myActionsList.getSelectedValues().length > 0); + boolean enableMove = myActionsList.getSelectedValues().length == 1; + myMoveActionUpButton.setEnabled(enableMove && myActionsList.getSelectedIndex() > 0); + myMoveActionDownButton.setEnabled(enableMove && myActionsList.getSelectedIndex() < myActionsList.getModel().getSize() - 1); + } + + private void includeActionId(String id) { + DefaultListModel model = (DefaultListModel)myActionsList.getModel(); + if (!QuickList.SEPARATOR_ID.equals(id) && model.contains(id)) return; + model.addElement(id); + } + + private String[] getTreeSelectedActionIds() { + TreePath[] paths = myActionsTree.getSelectionPaths(); + if (paths == null) return ArrayUtil.EMPTY_STRING_ARRAY; + + ArrayList actions = new ArrayList(); + for (int i = 0; i < paths.length; i++) { + Object node = paths[i].getLastPathComponent(); + if (node instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode defNode = (DefaultMutableTreeNode)node; + Object userObject = defNode.getUserObject(); + if (userObject instanceof String) { + actions.add((String)userObject); + } + else if (userObject instanceof QuickList) { + actions.add(((QuickList)userObject).getActionId()); + } + } + } + return actions.toArray(new String[actions.size()]); + } + + public JPanel getPanel() { + return myPanel; + } + + private class MyTreeCellRenderer extends DefaultTreeCellRenderer { + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) { + boolean used = false; + Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); + if (userObject instanceof ActionsTreeUtil.Group) { + ActionsTreeUtil.Group group = (ActionsTreeUtil.Group)userObject; + setText(group.getName()); + Icon icon = expanded ? group.getOpenIcon() : group.getIcon(); + + if (icon == null) { + icon = expanded ? getOpenIcon() : getClosedIcon(); + } + + setIcon(icon); + } + else if (userObject instanceof String) { + String actionId = (String)userObject; + used = ((DefaultListModel)myActionsList.getModel()).lastIndexOf(actionId) >= 0; + AnAction action = ActionManager.getInstance().getAction(actionId); + setText(action != null ? action.getTemplatePresentation().getText() : actionId); + Icon icon = EMPTY_ICON; + if (action != null) { + Icon actionIcon = action.getTemplatePresentation().getIcon(); + if (actionIcon != null) { + icon = actionIcon; + } + } + setIcon(icon); + } + else if (userObject instanceof QuickList) { + QuickList list = (QuickList)userObject; + setIcon(EMPTY_ICON); + setText(list.getDisplayName()); + used = ((DefaultListModel)myActionsList.getModel()).lastIndexOf(list.getActionId()) >= 0; + } + else if (userObject instanceof Separator) { + // TODO[vova,anton]: beautify + setText("-------------"); + setIcon(EMPTY_ICON); + } + else { + throw new IllegalArgumentException("unknown userObject: " + userObject); + } + + if (sel) { + setForeground(UIManager.getColor("Tree.selectionForeground")); + } + else { + Color foreground = used ? UIManager.getColor("textInactiveText") : UIManager.getColor("Tree.foreground"); + setForeground(foreground); + } + } + return this; + } + } + + private static class MyListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + String actionId = (String)value; + if (QuickList.SEPARATOR_ID.equals(actionId)) { + // TODO[vova,anton]: beautify + setText("-------------"); + setIcon(EMPTY_ICON); + } + else { + AnAction action = ActionManager.getInstance().getAction(actionId); + setText(action != null ? action.getTemplatePresentation().getText() : actionId); + Icon icon = EMPTY_ICON; + if (action != null) { + Icon actionIcon = action.getTemplatePresentation().getIcon(); + if (actionIcon != null) { + icon = actionIcon; + } + } + setIcon(icon); + } + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/LvcsConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/LvcsConfigurable.java new file mode 100644 index 00000000000..5ef03df637e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/LvcsConfigurable.java @@ -0,0 +1,254 @@ +package com.intellij.openapi.localVcs.impl; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.localVcs.LvcsConfiguration; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.*; + +/** + * author: lesya + */ +public class LvcsConfigurable extends BaseConfigurable implements ApplicationComponent { + + private JCheckBox myCbEnabled; + private JTextField myFieldHistoryLength; + private JCheckBox myCbProjectOpen; + private JCheckBox myCbProjectCompile; + private JCheckBox myCbFileCompile; + private JCheckBox myCbProjectMake; + private JCheckBox myCbRunning; + private JCheckBox myCbUnitTestsPassed; + private JCheckBox myCbUnitTestsFailed; + private JLabel myHistoryLengthLabel; + private JPanel myPanel; + + private static final int MILLIS_IN_DAY = 1000 * 60 * 60 * 24; + + + public LvcsConfigurable() { + } + + public String getDisplayName() { + return "Local History"; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/configurableLocalVCS.png"); + } + + public String getHelpTopic() { + return "project.propLocalVCS"; + } + + public JComponent createComponent() { + myPanel = new JPanel(); + + myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.Y_AXIS)); + + myCbEnabled = createCheckBox(); + myCbEnabled.setText("Enable Local History"); + myCbEnabled.setMnemonic('L'); + myCbEnabled.setAlignmentX(0); + myCbEnabled.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + updateEnabled(); + } + }); + myPanel.add(myCbEnabled); + myPanel.add(Box.createVerticalStrut(10)); + + JPanel historyPanel = new JPanel(); + historyPanel.setLayout(new BoxLayout(historyPanel, BoxLayout.X_AXIS)); + historyPanel.setBorder(BorderFactory.createCompoundBorder( + IdeBorderFactory.createTitledBorder("History"), + BorderFactory.createEmptyBorder(2, 2, 2, 2) + )); + historyPanel.setAlignmentX(0); + + myFieldHistoryLength = new JTextField(); + + myHistoryLengthLabel = new JLabel("Keep local history for (days) "); + myHistoryLengthLabel.setDisplayedMnemonic('H'); + myHistoryLengthLabel.setLabelFor(myFieldHistoryLength); + historyPanel.add(myHistoryLengthLabel); + + final Dimension size = new Dimension(30, myFieldHistoryLength.getPreferredSize().height); + myFieldHistoryLength.setPreferredSize(size); + myFieldHistoryLength.setMaximumSize(size); + myFieldHistoryLength.setDocument(new MyDocument()); + historyPanel.add(Box.createHorizontalStrut(5)); + historyPanel.add(myFieldHistoryLength); + + historyPanel.setMaximumSize(new Dimension(300, 0)); + myPanel.add(historyPanel); + myPanel.add(Box.createVerticalStrut(4)); + + createLabelsPanel(); + + myPanel.add(Box.createVerticalGlue()); + + return myPanel; + } + + private void createLabelsPanel() { + JPanel labelsPanel = createPanel("Automatic Labeling on"); + + myCbProjectOpen = createCheckBox(); + myCbProjectOpen.setText("Project opening"); + labelsPanel.add(myCbProjectOpen); + + myCbProjectCompile = createCheckBox(); + myCbProjectCompile.setText("Project compilation"); + labelsPanel.add(myCbProjectCompile); + + myCbFileCompile = createCheckBox(); + myCbFileCompile.setText("File/package compilation"); + labelsPanel.add(myCbFileCompile); + + myCbProjectMake = createCheckBox(); + myCbProjectMake.setText("Project make"); + labelsPanel.add(myCbProjectMake); + + myCbRunning = createCheckBox(); + myCbRunning.setText("Running/Debugging"); + labelsPanel.add(myCbRunning); + + myCbUnitTestsPassed = createCheckBox(); + myCbUnitTestsPassed.setText("Unit tests passed"); + labelsPanel.add(myCbUnitTestsPassed); + + myCbUnitTestsFailed = createCheckBox(); + myCbUnitTestsFailed.setText("Unit tests failed"); + labelsPanel.add(myCbUnitTestsFailed); + + addPanel(labelsPanel); + } + + private void addPanel(JPanel labelsPanel) { + labelsPanel.setMaximumSize(new Dimension(300, labelsPanel.getMaximumSize().height)); + myPanel.add(labelsPanel); + } + + private JPanel createPanel(String panelTitle) { + JPanel labelsPanel = new JPanel(); + labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS)); + labelsPanel.setBorder( + BorderFactory.createCompoundBorder( + IdeBorderFactory.createTitledBorder(panelTitle), + BorderFactory.createEmptyBorder(2, 2, 2, 2) + )); + labelsPanel.setAlignmentX(0); + return labelsPanel; + } + + public void apply() throws ConfigurationException { + LvcsConfiguration c = LvcsConfiguration.getInstance(); + + c.LOCAL_VCS_ENABLED = myCbEnabled.isSelected(); + + c.ADD_LABEL_ON_FILE_PACKAGE_COMPILATION = myCbFileCompile.isSelected(); + c.ADD_LABEL_ON_PROJECT_COMPILATION = myCbProjectCompile.isSelected(); + c.ADD_LABEL_ON_PROJECT_MAKE = myCbProjectMake.isSelected(); + c.ADD_LABEL_ON_PROJECT_OPEN = myCbProjectOpen.isSelected(); + c.ADD_LABEL_ON_RUNNING = myCbRunning.isSelected(); + c.ADD_LABEL_ON_UNIT_TEST_PASSED = myCbUnitTestsPassed.isSelected(); + c.ADD_LABEL_ON_UNIT_TEST_FAILED = myCbUnitTestsFailed.isSelected(); + + c.LOCAL_VCS_PURGING_PERIOD = Long.parseLong(myFieldHistoryLength.getText()) * MILLIS_IN_DAY; + + setModified(false); + + } + + public void reset() { + LvcsConfiguration c = LvcsConfiguration.getInstance(); + myCbEnabled.setSelected(c.LOCAL_VCS_ENABLED); + + myCbFileCompile.setSelected(c.ADD_LABEL_ON_FILE_PACKAGE_COMPILATION); + myCbProjectCompile.setSelected(c.ADD_LABEL_ON_PROJECT_COMPILATION); + myCbProjectMake.setSelected(c.ADD_LABEL_ON_PROJECT_MAKE); + myCbProjectOpen.setSelected(c.ADD_LABEL_ON_PROJECT_OPEN); + myCbRunning.setSelected(c.ADD_LABEL_ON_RUNNING); + myCbUnitTestsPassed.setSelected(c.ADD_LABEL_ON_UNIT_TEST_PASSED); + myCbUnitTestsFailed.setSelected(c.ADD_LABEL_ON_UNIT_TEST_FAILED); + + myFieldHistoryLength.setText(String.valueOf(c.LOCAL_VCS_PURGING_PERIOD / MILLIS_IN_DAY)); + + updateEnabled(); + + setModified(false); + + } + + public void disposeUIResources() { + myPanel = null; + } + + public String getComponentName() { + return "LvcsConfigurable"; + } + + public void initComponent() { } + public void disposeComponent() { + } + + private void updateEnabled() { + boolean value = myCbEnabled.isSelected(); + + myCbFileCompile.setEnabled(value); + myCbProjectCompile.setEnabled(value); + myCbProjectMake.setEnabled(value); + myCbProjectOpen.setEnabled(value); + myCbRunning.setEnabled(value); + myCbUnitTestsPassed.setEnabled(value); + myCbUnitTestsFailed.setEnabled(value); + myFieldHistoryLength.setEditable(value); + } + + private JCheckBox createCheckBox() { + final JCheckBox box = new JCheckBox(); + box.addChangeListener(new ChangeListener() { + private boolean myOldValue = box.isSelected(); + + public void stateChanged(ChangeEvent e) { + if (myOldValue != box.isSelected()) { + setModified(true); + myOldValue = box.isSelected(); + updateEnabled(); + } + } + }); + + return box; + } + + private class MyDocument extends PlainDocument { + public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { + char[] source = str.toCharArray(); + char[] result = new char[source.length]; + int j = 0; + + for (int i = 0; i < result.length; i++) { + if (Character.isDigit(source[i])) { + result[j++] = source[i]; + } + else { + Toolkit.getDefaultToolkit().beep(); + } + } + super.insertString(offs, new String(result, 0, j), a); + setModified(true); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/UpToDateLineNumberProviderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/UpToDateLineNumberProviderImpl.java new file mode 100644 index 00000000000..4e2f5396d06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/localVcs/impl/UpToDateLineNumberProviderImpl.java @@ -0,0 +1,61 @@ +package com.intellij.openapi.localVcs.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ex.LineStatusTracker; +import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.ex.Range; +import com.intellij.openapi.localVcs.UpToDateLineNumberProvider; + +import java.util.Iterator; +import java.util.List; + +/** + * author: lesya + */ +public class UpToDateLineNumberProviderImpl implements UpToDateLineNumberProvider { + private final Document myDocument; + private final Project myProject; + private final String myUpToDateContent; + + public UpToDateLineNumberProviderImpl(Document document, Project project, String upToDateContent) { + myDocument = document; + myProject = project; + myUpToDateContent = upToDateContent; + } + + public int getLineNumber(int currentNumber) { + LineStatusTracker tracker = ProjectLevelVcsManagerEx.getInstanceEx(myProject).getLineStatusTracker(myDocument); + if (tracker == null) { + tracker = ProjectLevelVcsManagerEx.getInstanceEx(myProject).setUpToDateContent(myDocument, myUpToDateContent); + } + return calcLineNumber(tracker, currentNumber); + } + + + private static int calcLineNumber(LineStatusTracker tracker, int currentNumber){ + List ranges = tracker.getRanges(); + int result = currentNumber; + + for (Iterator each = ranges.iterator(); each.hasNext();) { + Range range = (Range) each.next(); + int startOffset = range.getOffset1(); + int endOffset = range.getOffset2(); + + if ((startOffset <= currentNumber) && (endOffset > currentNumber)) { + return ABSENT_LINE_NUMBER; + } + + if (endOffset > currentNumber) return result; + + int currentRangeLength = endOffset - startOffset; + + result += range.getUpToDateRangeLength() - currentRangeLength; + } + return result; + + } + +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/JavaModuleType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/JavaModuleType.java new file mode 100644 index 00000000000..34f46b17297 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/JavaModuleType.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.module; + +import com.intellij.ide.util.projectWizard.*; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class JavaModuleType extends ModuleType { + private static final Icon JAVA_MODULE_ICON = IconLoader.getIcon("/modules/javaModule.png"); + private static final Icon JAVA_MODULE_NODE_ICON_OPEN = IconLoader.getIcon("/nodes/ModuleOpen.png"); + private static final Icon JAVA_MODULE_NODE_ICON_CLOSED = IconLoader.getIcon("/nodes/ModuleClosed.png"); + //private static final Icon JAVA_MODULE_ICON_NORMAL = IconLoader.getIcon("/nodes/javaModule.png"); + private static final Icon WIZARD_ICON = IconLoader.getIcon("/add_java_modulewizard.png"); + + public JavaModuleType() { + this("JAVA_MODULE"); + } + + protected JavaModuleType(String id) { + super(id); + } + + public JavaModuleBuilder createModuleBuilder() { + return new JavaModuleBuilder(); + } + + public String getName() { + return "Java Module"; + } + + public String getDescription() { + return "Java module is a part of a project describing a set of java sources, paths, libraries, etc."; + } + + public Icon getBigIcon() { + return JAVA_MODULE_ICON; + } + + public Icon getNodeIcon(boolean isOpened) { + return isOpened ? JAVA_MODULE_NODE_ICON_OPEN : JAVA_MODULE_NODE_ICON_CLOSED; + } + + public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, JavaModuleBuilder moduleBuilder, + ModulesProvider modulesProvider) { + final NameLocationStep nameLocationStep = new NameLocationStep(wizardContext, moduleBuilder, modulesProvider, WIZARD_ICON, + "project.creatingModules.page2"); + return new ModuleWizardStep[]{ + nameLocationStep, + new SourcePathsStep(nameLocationStep, moduleBuilder, WIZARD_ICON, "project.creatingModules.page3"), + new OutputPathsStep(nameLocationStep, moduleBuilder, WIZARD_ICON, "project.creatingModules.page4") + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/UnknownModuleType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/UnknownModuleType.java new file mode 100644 index 00000000000..66826a8d940 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/UnknownModuleType.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.module; + + +public class UnknownModuleType extends JavaModuleType { + + public UnknownModuleType(String id) { + super(id); + } + + public String getName() { + return "Unknown module type. Used \"" + super.getName() + "\" as a substitute"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java new file mode 100644 index 00000000000..5f063aaaaaf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.module.impl; + +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.ModuleConfigurationState; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.util.UserDataHolderBase; + +public class ModuleConfigurationStateImpl extends UserDataHolderBase implements ModuleConfigurationState { + private Module myModule; + private ModulesProvider myProvider; + private ModifiableRootModel myRootModel; + private Project myProject; + + public ModuleConfigurationStateImpl(Project project, Module module, ModulesProvider provider, ModifiableRootModel rootModel) { + myModule = module; + myProvider = provider; + myRootModel = rootModel; + myProject = project; + } + + public Module getModule() { + return myModule; + } + + public ModulesProvider getModulesProvider() { + return myProvider; + } + + public ModifiableRootModel getRootModel() { + return myRootModel; + } + + public Project getProject() { + return myProject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleImpl.java new file mode 100644 index 00000000000..73d1251f688 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleImpl.java @@ -0,0 +1,404 @@ +package com.intellij.openapi.module.impl; + +import com.intellij.application.options.PathMacros; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.PathMacroMap; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.ide.plugins.PluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.application.ex.DecodeDefaultsUtil; +import com.intellij.openapi.components.BaseComponent; +import com.intellij.openapi.components.impl.ComponentManagerImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.impl.BaseFileConfigurable; +import com.intellij.openapi.project.impl.ProjectImpl; +import com.intellij.openapi.util.*; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.pom.PomModel; +import com.intellij.pom.PomModule; +import com.intellij.pom.core.impl.PomModuleImpl; +import org.jdom.Attribute; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +/** + * @author max + */ +public class ModuleImpl extends BaseFileConfigurable implements Module { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.ModuleImpl"); + + private final Project myProject; + private VirtualFilePointer myFilePointer; + private ModuleType myModuleType = null; + private boolean myIsDisposed = false; + private MyVirtualFileListener myVirtualFileListener; + private boolean isModuleAdded; + private Map myOptions = new HashMap(); + + private static final String MODULE_LAYER = "module-components"; + private PomModule myPomModule; + private PomModel myPomModel; + + public ModuleImpl(String filePath, Project project, PomModel pomModel, PathMacros pathMacros) { + super(false, pathMacros); + myProject = project; + myPomModel = pomModel; + init(filePath); + } + + private void init(String filePath) { + getPicoContainer().registerComponentInstance(Module.class, this); + myPomModule = new PomModuleImpl(myPomModel, this); + + LOG.assertTrue(filePath != null); + String path = filePath.replace(File.separatorChar, '/'); + String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, path); + myFilePointer = VirtualFilePointerManager.getInstance().create(url, null); + myVirtualFileListener = new MyVirtualFileListener(); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + } + + protected void initJdomExternalizable(Class componentClass, BaseComponent component) { + if (((ProjectImpl)myProject).isOptimiseTestLoadSpeed()) return; //test load speed optimization + doInitJdomExternalizable(componentClass, component); + } + + public void loadModuleComponents() { + loadComponentsConfiguration(MODULE_LAYER); + + ApplicationEx app = ApplicationManagerEx.getApplicationEx(); + if (app.shouldLoadPlugins()) { + final PluginDescriptor[] plugins = PluginManager.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + PluginDescriptor plugin = plugins[i]; + if (!app.shouldLoadPlugin(plugin)) continue; + final Element moduleComponents = plugin.getModuleComponents(); + if (moduleComponents != null) { + loadComponentsConfiguration(moduleComponents, plugin); + } + } + } + } + + protected boolean isComponentSuitable(Map options) { + if (!super.isComponentSuitable(options)) return false; + if (options == null) return true; + + Set optionNames = options.keySet(); + for (Iterator iterator = optionNames.iterator(); iterator.hasNext();) { + String optionName = iterator.next(); + if (Comparing.equal("workspace", optionName)) continue; + if (!parseOptionValue(options.get(optionName)).contains(getOptionValue(optionName))) return false; + } + + return true; + } + + private List parseOptionValue(String optionValue) { + if (optionValue == null) return new ArrayList(0); + return Arrays.asList(optionValue.split(";")); + } + + protected Element getDefaults(BaseComponent component) throws IOException, JDOMException, InvalidDataException { + //[mike] speed optimization. If you need default initialization in tests + //use field initializers instead. + if (((ProjectImpl)myProject).isOptimiseTestLoadSpeed()) return null; + + InputStream stream = DecodeDefaultsUtil.getDefaultsInputStream(component); + if (stream != null) { + Document document = JDOMUtil.loadDocument(stream); + stream.close(); + + if (document == null) { + throw new InvalidDataException(); + } + Element root = document.getRootElement(); + if (root == null || !"component".equals(root.getName())) { + throw new InvalidDataException(); + } + + //TODO: + //JDOMUtil.replaceText(root, getExpandMacroReplacements(), SystemInfo.isFileSystemCaseSensitive); + + return root; + } + return null; + } + + protected ComponentManagerImpl getParentComponentManager() { + return (ComponentManagerImpl)myProject; + } + + public VirtualFile getModuleFile() { + return myFilePointer.getFile(); + } + + void rename(String newName) { + final VirtualFile file = myFilePointer.getFile(); + try { + if (file != null) { + file.rename(ModuleUtil.MODULE_RENAMING_REQUESTOR, newName + ".iml"); + return; + } + } + catch (IOException e) { + } + // [dsl] we get here if either old file didn't exist or renaming failed + final File oldFile = new File(getModuleFilePath()); + final File parentFile = oldFile.getParentFile(); + final File newFile = new File(parentFile, newName + ".iml"); + final String newUrl = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, newFile.getPath().replace(File.separatorChar, '/')); + myFilePointer = VirtualFilePointerManager.getInstance().create(newUrl, null); + } + + public String getModuleFilePath() { + String url = myFilePointer.getUrl(); + String protocol = VirtualFileManager.extractProtocol(url); + LOG.assertTrue(LocalFileSystem.PROTOCOL.equals(protocol)); + String path = VirtualFileManager.extractPath(url); + return path.replace('/', File.separatorChar); + } + + public void dispose() { + isModuleAdded = false; + disposeComponents(); + myIsDisposed = true; + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + } + + public VirtualFile[] getConfigurationFiles() { + final VirtualFile moduleFile = getModuleFile(); + return moduleFile == null? VirtualFile.EMPTY_ARRAY : new VirtualFile[]{moduleFile}; + } + + public String[] getConfigurationFilePaths() { + return new String[]{getModuleFilePath()}; + } + + protected String getRootNodeName() { + return "module"; + } + + protected VirtualFile getComponentConfigurationFile(Class componentInterface) { + return getModuleFile(); + } + + public ReplacePathToMacroMap getMacroReplacements() { + ReplacePathToMacroMap result = new ReplacePathToMacroMap(); + getModuleHomeReplacements(result, false); + result.putAll(super.getMacroReplacements()); + getModuleHomeReplacements(result, mySavePathsRelative); + return result; + } + + public ExpandMacroToPathMap getExpandMacroReplacements() { + ExpandMacroToPathMap result = new ExpandMacroToPathMap(); + getExpandModuleHomeReplacements(result); + result.putAll(super.getExpandMacroReplacements()); + return result; + } + + private void getExpandModuleHomeReplacements(ExpandMacroToPathMap result) { + String moduleDir = getModuleDir(getModuleFilePath()); + if (moduleDir == null) return; + + File f = new File(moduleDir.replace('/', File.separatorChar)); + LOG.assertTrue(f.exists()); + + getExpandModuleHomeReplacements(result, f, "$" + PathMacros.MODULE_DIR_MACRO_NAME + "$"); + } + + private void getExpandModuleHomeReplacements(ExpandMacroToPathMap result, File f, String macro) { + if (f == null) return; + + getExpandModuleHomeReplacements(result, f.getParentFile(), macro + "/.."); + String path = PathMacroMap.quotePath(f.getAbsolutePath()); + String s = macro; + + if (StringUtil.endsWithChar(path, '/')) s += "/"; + + result.put(s, path); + } + + private void getModuleHomeReplacements(ReplacePathToMacroMap result, final boolean addRelativePathMacros) { + String moduleDir = getModuleDir(getModuleFilePath()); + if (moduleDir == null) return; + + File f = new File(moduleDir.replace('/', File.separatorChar)); + // [dsl]: Q? + //if(!f.exists()) return; + + String macro = "$" + PathMacros.MODULE_DIR_MACRO_NAME + "$"; + + while (f != null) { + String path = PathMacroMap.quotePath(f.getAbsolutePath()); + String s = macro; + + if (StringUtil.endsWithChar(path, '/')) s += "/"; + if (path.equals("/")) break; + + result.put("file://" + path, "file://" + s); + result.put("file:/" + path, "file:/" + s); + result.put("file:" + path, "file:" + s); + result.put("jar://" + path, "jar://" + s); + result.put("jar:/" + path, "jar:/" + s); + result.put("jar:" + path, "jar:" + s); + if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/")) { + result.put(path, s); + } + + if (!addRelativePathMacros) break; + macro += "/.."; + f = f.getParentFile(); + } + } + + private String getModuleDir(String moduleFilePath) { + String moduleDir = new File(moduleFilePath).getParent(); + if (moduleDir == null) return null; + moduleDir = moduleDir.replace(File.separatorChar, '/'); + if (moduleDir.endsWith(":/")) { + moduleDir = moduleDir.substring(0, moduleDir.length() - 1); + } + return moduleDir; + } + + public void loadFromXml(Element root, String filePath) throws InvalidDataException { + List attributes = root.getAttributes(); + for (int i = 0; i < attributes.size(); i++) { + Attribute attr = (Attribute)attributes.get(i); + setOption(attr.getName(), attr.getValue()); + } + + final String moduleTypeId = getOptionValue("type"); + setModuleType((moduleTypeId != null)? ModuleTypeManager.getInstance().findByID(moduleTypeId) : ModuleType.JAVA); + super.loadFromXml(root, filePath); + } + + public Element saveToXml(Element targetRoot, VirtualFile configFile) { + final Element root = super.saveToXml(targetRoot, configFile); + Set options = myOptions.keySet(); + for (Iterator iterator = options.iterator(); iterator.hasNext();) { + String option = iterator.next(); + root.setAttribute(option, myOptions.get(option)); + } + return root; + } + + public void projectOpened() { + final BaseComponent[] components = getComponents(false); + for (int i = 0; i < components.length; i++) { + ModuleComponent component = (ModuleComponent)components[i]; + try { + component.projectOpened(); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + public void projectClosed() { + final BaseComponent[] components = getComponents(false); + for (int i = 0; i < components.length; i++) { + ModuleComponent component = (ModuleComponent)components[i]; + try { + component.projectClosed(); + } + catch (Exception e) { + LOG.error(e); + } + } + } + + public ModuleType getModuleType() { + LOG.assertTrue(myModuleType != null, "Module type not initialized yet"); + return myModuleType; + } + + public Project getProject() { + return myProject; + } + + private final Map myFileToModuleName = new HashMap(); + + public String getName() { + final String fileName = myFilePointer.getFileName(); + String moduleName = myFileToModuleName.get(fileName); + if (moduleName == null) { + moduleName = ModuleUtil.moduleNameByFileName(fileName); + myFileToModuleName.put(fileName, moduleName); + } + return moduleName; + } + + public boolean isDisposed() { + return myIsDisposed; + } + + public void moduleAdded() { + isModuleAdded = true; + final BaseComponent[] components = getComponents(false); + for (int i = 0; i < components.length; i++) { + ModuleComponent component = (ModuleComponent) components[i]; + component.moduleAdded(); + } + } + + public void setModuleType(ModuleType type) { + myModuleType = type; + setOption("type", type.getId()); + } + + protected String getConfigurableType() { + return "module"; + } + + public void setOption(String optionName, String optionValue) { + myOptions.put(optionName, optionValue); + } + + public String getOptionValue(String optionName) { + return myOptions.get(optionName); + } + + public PomModule getPom() { + return myPomModule; + } + + public String toString() { + return "Module:" + getName(); + } + + private class MyVirtualFileListener extends VirtualFileAdapter { + + public MyVirtualFileListener() { + } + + public void propertyChanged(VirtualFilePropertyEvent event) { + if (!isModuleAdded) return; + final Object requestor = event.getRequestor(); + if (ModuleUtil.MODULE_RENAMING_REQUESTOR.equals(requestor)) return; + if (!VirtualFile.PROP_NAME.equals(event.getPropertyName())) return; + final VirtualFile moduleFile = getModuleFile(); + if (moduleFile == null) return; + if (moduleFile.equals(event.getFile())) { + ModuleManagerImpl.getInstanceImpl(getProject()).fireModuleRenamedByVfsEvent(ModuleImpl.this); + } + } + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleManagerImpl.java new file mode 100644 index 00000000000..f9e464388e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleManagerImpl.java @@ -0,0 +1,772 @@ +package com.intellij.openapi.module.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.components.LoadCancelledException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.*; +import com.intellij.openapi.project.ModuleListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphGenerator; +import com.intellij.application.options.PathMacros; +import com.intellij.pom.PomModel; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author max + */ +public class ModuleManagerImpl extends ModuleManager implements ProjectComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.ModuleManagerImpl"); + private final EventDispatcher myModuleEventDispatcher = EventDispatcher.create(ModuleListener.class); + private final Project myProject; + private ModuleModelImpl myModuleModel = new ModuleModelImpl(); + private Map myModuleGroup; + private PomModel myPomModel; + + private final ModuleRootListener myModuleRootListener = new ModuleRootListener() { + public void beforeRootsChange(ModuleRootEvent event) { + cleanCachedStuff(); + } + + public void rootsChanged(ModuleRootEvent event) { + cleanCachedStuff(); + } + }; + public static final String COMPONENT_NAME = "ProjectModuleManager"; + + public static ModuleManagerImpl getInstanceImpl(Project project) { + return (ModuleManagerImpl)getInstance(project); + } + + private void cleanCachedStuff() { + myCachedModuleComparator = null; + myCachedSortedModules = null; + } + + public ModuleManagerImpl(Project project, ProjectRootManager projectRootManager, PomModel pomModel) { + myProject = project; + projectRootManager.addModuleRootListener(myModuleRootListener); + myPomModel = pomModel; + } + + + public String getComponentName() { + return COMPONENT_NAME; + } + + public void initComponent() { + } + + public void disposeComponent() { + myModuleModel.disposeModel(); + ProjectRootManager.getInstance(myProject).removeModuleRootListener(myModuleRootListener); + } + + public static final class ModulePath { + private final String myPath; + private final String myModuleGroup; + + public ModulePath(String path, String moduleGroup) { + myPath = path; + myModuleGroup = moduleGroup; + } + + public String getPath() { + return myPath; + } + + public String getModuleGroup() { + return myModuleGroup; + } + } + + public static ModulePath[] getPathsToModuleFiles(Element element) { + final List paths = new ArrayList(); + final Element modules = element.getChild("modules"); + if (modules != null) { + for (Iterator iterator = modules.getChildren("module").iterator(); iterator.hasNext();) { + Element moduleElement = (Element)iterator.next(); + final String fileUrlValue = moduleElement.getAttributeValue("fileurl"); + final String filepath; + if (fileUrlValue != null) { + filepath = VirtualFileManager.extractPath(fileUrlValue).replace('/', File.separatorChar); + } + else { + // [dsl] support for older formats + filepath = moduleElement.getAttributeValue("filepath").replace('/', File.separatorChar); + } + final String group = moduleElement.getAttributeValue("group"); + paths.add(new ModulePath(filepath, group)); + } + } + return paths.toArray(new ModulePath[paths.size()]); + } + + public void readExternal(final Element element) throws InvalidDataException { + final ModulePath[] paths = getPathsToModuleFiles(element); + if (paths.length > 0) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (int idx = 0; idx < paths.length; idx++) { + final ModulePath modulePath = paths[idx]; + try { + final Module module = myModuleModel.loadModuleInternal(modulePath.getPath()); + final String group = modulePath.getModuleGroup(); + if (group != null) { + setModuleGroup(module, group); + } + } + catch (final IOException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Cannot load module: " + e.getMessage(), "Cannot Load Module", + Messages.getErrorIcon()); + } + }); + } + catch (JDOMException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Corruped module file: " + modulePath, "Cannot Load Module", + Messages.getErrorIcon()); + } + }); + } + catch (InvalidDataException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog("Corruped module data at: " + modulePath, "Cannot Load Module", + Messages.getErrorIcon()); + } + }); + } + catch (final ModuleWithNameAlreadyExists moduleWithNameAlreadyExists) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(moduleWithNameAlreadyExists.getMessage(), "Cannot Load Module", + Messages.getErrorIcon()); + } + }); + } + catch (final LoadCancelledException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + int response = Messages.showDialog("Cancelled loading of module from:" + modulePath.getPath() + "\n" + + "Cancelled by component: " + e.getIssuer().getComponentName() + "\n" + + "Reason is: " + e.getMessage(), + "Module Loading Cancelled", new String[]{"Try to load &later", "&Remove from project"}, 0, + Messages.getErrorIcon()); + if (response == 1) { + myModuleModel.myPath2CancelledModelMap.remove(modulePath.getPath()); + } + } + }); + } + } + } + }); + } + } + + public ModifiableModuleModel getModifiableModel() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return new ModuleModelImpl(myModuleModel); + } + + + public void writeExternal(Element element) throws WriteExternalException { + Element modules = new Element("modules"); + final Collection collection = getModulesToWrite(); + ArrayList sorted = new ArrayList(collection); + Collections.sort(sorted, new Comparator() { + public int compare(Module module, Module module1) { + return module.getName().compareTo(module1.getName()); + } + }); + for (Iterator iterator = sorted.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + if (module.isDefault()) continue; + Element moduleElement = new Element("module"); + final String moduleFilePath = module.getModuleFilePath().replace(File.separatorChar, '/'); + final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, moduleFilePath); + moduleElement.setAttribute("fileurl", url); + // [dsl] support for older builds + moduleElement.setAttribute("filepath", moduleFilePath); + + String group = getModuleGroup(module); + if (group != null) { + moduleElement.setAttribute("group", group); + } + + modules.addContent(moduleElement); + } + + element.addContent(modules); + } + + private Collection getModulesToWrite() { + Collection actual = new ArrayList(); + actual.addAll(myModuleModel.myPath2ModelMap.values()); + + Iterator cancelled = myModuleModel.myPath2CancelledModelMap.keySet().iterator(); + while (cancelled.hasNext()) { + String cancelledPath = cancelled.next(); + if (!myModuleModel.myPath2ModelMap.containsKey(cancelledPath)) { + actual.add(myModuleModel.myPath2CancelledModelMap.get(cancelledPath)); + } + } + return actual; + } + + private void fireModuleAdded(Module module) { + myModuleEventDispatcher.getMulticaster().moduleAdded(myProject, module); + } + + private void fireModuleRemoved(Module module) { + myModuleEventDispatcher.getMulticaster().moduleRemoved(myProject, module); + } + + private void fireBeforeModuleRemoved(Module module) { + myModuleEventDispatcher.getMulticaster().beforeModuleRemoved(myProject, module); + } + + + public void addModuleListener(ModuleListener listener) { + myModuleEventDispatcher.addListener(listener); + } + + public void removeModuleListener(ModuleListener listener) { + myModuleEventDispatcher.removeListener(listener); + } + + public void dispatchPendingEvent(ModuleListener listener) { + myModuleEventDispatcher.dispatchPendingEvent(listener); + } + + public Module newModule(String filePath) { + final ModifiableModuleModel modifiableModel = getModifiableModel(); + final Module module = modifiableModel.newModule(filePath); + modifiableModel.commitAssertingNoCircularDependency(); + return module; + } + + public Module newModule(String filePath, ModuleType moduleType) { + final ModifiableModuleModel modifiableModel = getModifiableModel(); + final Module module = modifiableModel.newModule(filePath, moduleType); + modifiableModel.commitAssertingNoCircularDependency(); + return module; + + } + + public Module loadModule(String filePath) throws InvalidDataException, + IOException, + JDOMException, + ModuleWithNameAlreadyExists, + ModuleCircularDependencyException { + final ModifiableModuleModel modifiableModel = getModifiableModel(); + final Module module = modifiableModel.loadModule(filePath); + modifiableModel.commit(); + return module; + } + + public void disposeModule(final Module module) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final ModifiableModuleModel modifiableModel = getModifiableModel(); + modifiableModel.disposeModule(module); + modifiableModel.commitAssertingNoCircularDependency(); + } + }); + } + + public Module[] getModules() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return myModuleModel.getModules(); + } + + private Module[] myCachedSortedModules = null; + + public Module[] getSortedModules() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + ProjectRootManager.getInstance(myProject).dispatchPendingEvent(myModuleRootListener); + if (myCachedSortedModules == null) { + myCachedSortedModules = myModuleModel.getSortedModules(); + } + return myCachedSortedModules; + } + + public Module findModuleByName(String name) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return myModuleModel.findModuleByName(name); + } + + private Comparator myCachedModuleComparator = null; + + public Comparator moduleDependencyComparator() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + ProjectRootManager.getInstance(myProject).dispatchPendingEvent(myModuleRootListener); + if (myCachedModuleComparator == null) { + myCachedModuleComparator = myModuleModel.moduleDependencyComparator(); + } + return myCachedModuleComparator; + } + + public Graph moduleGraph() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return myModuleModel.moduleGraph(); + } + + public Module[] getModuleDependentModules(Module module) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return myModuleModel.getModuleDependentModules(module); + } + + public boolean isModuleDependent(Module module, Module onModule) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return myModuleModel.isModuleDependent(module, onModule); + } + + public void projectOpened() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final Module[] modules = myModuleModel.getModules(); + for (int i = 0; i < modules.length; i++) { + ModuleImpl module = (ModuleImpl)modules[i]; + module.moduleAdded(); + fireModuleAdded(module); + } + } + }); + myModuleModel.projectOpened(); + } + + public void projectClosed() { + myModuleModel.projectClosed(); + } + + public void commitModelWithRunnable(ModifiableModuleModel model, Runnable runnable) { + ((ModuleModelImpl)model).commitWithRunnable(runnable); + } + + class ModuleModelImpl implements ModifiableModuleModel { + private Map myPath2ModelMap = new HashMap(); + private Map myPath2CancelledModelMap = new HashMap(); + + private List myModulesToDispose = new ArrayList(); + private Map myModulesToNewNamesMap = new HashMap(); + private Map myNewNamesToModulesMap = new HashMap(); + private boolean myIsWritable; + + ModuleModelImpl() { + myIsWritable = false; + } + + ModuleModelImpl(ModuleModelImpl that) { + myPath2ModelMap.putAll(that.myPath2ModelMap); + myIsWritable = true; + myPomModel = myProject.getModel(); + } + + private void assertWritable() { + LOG.assertTrue(myIsWritable, "Attempt to modify commited ModifiableModuleModel"); + } + + public Module[] getModules() { + Collection modules = myPath2ModelMap.values(); + return modules.toArray(new Module[modules.size()]); + } + + private Module[] getSortedModules() { + Module[] allModules = getModules(); + Arrays.sort(allModules, moduleDependencyComparator()); + return allModules; + } + + public Module newModule(String filePath) { + assertWritable(); + return newModule(filePath, ModuleType.JAVA); + } + + public void renameModule(Module module, String newName) throws ModuleWithNameAlreadyExists { + final Module oldModule = getModuleByNewName(newName); + if (oldModule != null) { + throw new ModuleWithNameAlreadyExists(newName); + } + final String oldName = myModulesToNewNamesMap.get(module); + myModulesToNewNamesMap.put(module, newName); + myNewNamesToModulesMap.remove(oldName); + myNewNamesToModulesMap.put(newName, module); + } + + public Module getModuleToBeRenamed(String newName) { + return myNewNamesToModulesMap.get(newName); + } + + public Module getModuleByNewName(String newName) { + final Module moduleToBeRenamed = getModuleToBeRenamed(newName); + if (moduleToBeRenamed != null) return moduleToBeRenamed; + final Module moduleWithOldName = findModuleByName(newName); + if (myModulesToNewNamesMap.get(moduleWithOldName) == null) { + return moduleWithOldName; + } + else { + return null; + } + } + + public String getNewName(Module module) { + return myModulesToNewNamesMap.get(module); + } + + public Module newModule(String filePath, ModuleType moduleType) { + assertWritable(); + try { + String canonicalPath = new File(filePath.replace('/', File.separatorChar)).getCanonicalPath(); + if (canonicalPath != null) { + filePath = canonicalPath; + } + } + catch (IOException e) { + } + + ModuleImpl module = getModuleByFilePath(filePath); + if (module == null) { + module = new ModuleImpl(filePath, myProject, myPomModel, PathMacros.getInstance()); + module.setModuleType(moduleType); + module.loadModuleComponents(); + initModule(module, false); + } + return module; + } + + private ModuleImpl getModuleByFilePath(String filePath) { + final Collection modules = myPath2ModelMap.values(); + for (Iterator iterator = modules.iterator(); iterator.hasNext();) { + Module module = iterator.next(); + if (filePath.equals(module.getModuleFilePath())) { + return (ModuleImpl)module; + } + } + return null; + } + + public Module loadModule(String filePath) throws InvalidDataException, + IOException, + JDOMException, + ModuleWithNameAlreadyExists { + assertWritable(); + return loadModuleInternal(filePath); + + } + + private Module loadModuleInternal(String filePath) throws ModuleWithNameAlreadyExists, + JDOMException, + IOException, + InvalidDataException, + LoadCancelledException { + final File moduleFile = new File(filePath); + try { + String canonicalPath = moduleFile.getCanonicalPath(); + if (canonicalPath != null) { + filePath = canonicalPath; + } + } + catch (IOException e) { + } + + final String name = moduleFile.getName(); + if (name.endsWith(".iml")) { + final String moduleName = name.substring(0, name.length() - 4); + final Module[] modules = getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + if (module.getName().equals(moduleName)) { + throw new ModuleWithNameAlreadyExists(moduleName); + } + } + } + if (!moduleFile.exists()) { + throw new IOException("File " + moduleFile.getPath() + " does not exist"); + } + ModuleImpl module = getModuleByFilePath(filePath); + if (module == null) { + module = new ModuleImpl(filePath, myProject, myPomModel, PathMacros.getInstance()); + module.loadSavedConfiguration(); + module.loadModuleComponents(); + initModule(module, true); + } + return module; + } + + private void initModule(ModuleImpl module, boolean saveToCancelled) throws LoadCancelledException { + String path = module.getModuleFilePath(); + try { + myPath2ModelMap.put(path, module); + module.init(); + } + catch (LoadCancelledException e) { + myPath2ModelMap.remove(path); + if (saveToCancelled) { + myPath2CancelledModelMap.put(path, module); + } + throw e; + } + } + + public void disposeModule(Module module) { + assertWritable(); + if (myPath2ModelMap.values().contains(module)) { + myPath2ModelMap.values().remove(module); + myModulesToDispose.add(module); + } + } + + public Module findModuleByName(String name) { + final Module[] allModules = getModules(); + for (int i = 0; i < allModules.length; i++) { + Module module = allModules[i]; + if (module.getName().equals(name)) { + return module; + } + } + return null; + } + + private Comparator moduleDependencyComparator() { + DFSTBuilder builder = new DFSTBuilder(moduleGraph()); + return builder.comparator(); + } + + private Graph moduleGraph() { + final Graph graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return Arrays.asList(getModules()); + } + + public Iterator getIn(Module m) { + Module[] dependentModules = ModuleRootManager.getInstance(m).getDependencies(); + return Arrays.asList(dependentModules).iterator(); + } + })); + return graph; + } + + private Module[] getModuleDependentModules(Module module) { + List result = new ArrayList(); + Module[] modules = getModules(); + for (int i = 0; i < modules.length; i++) { + Module aModule = modules[i]; + if (isModuleDependent(aModule, module)) { + result.add(aModule); + } + } + return result.toArray(new Module[result.size()]); + } + + private boolean isModuleDependent(Module module, Module onModule) { + final OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); + for (int j = 0; j < orderEntries.length; j++) { + OrderEntry entry = orderEntries[j]; + if (entry instanceof ModuleOrderEntry) { + if (((ModuleOrderEntry)entry).getModule() == onModule) { + return true; + } + } + } + return false; + } + + public void commitAssertingNoCircularDependency() { + try { + commit(); + } + catch (ModuleCircularDependencyException e) { + LOG.error(e); + } + } + + public void commit() throws ModuleCircularDependencyException { + ProjectRootManagerEx.getInstanceEx(myProject).multiCommit(this, new ModifiableRootModel[0]); + } + + public void commitWithRunnable(Runnable runnable) { + ModuleManagerImpl.this.commitModel(this, runnable); + myIsWritable = false; + clearRenamingStuff(); + } + + private void clearRenamingStuff() { + myModulesToNewNamesMap.clear(); + myNewNamesToModulesMap.clear(); + myNewNamesToModulesMap.clear(); + } + + public void dispose() { + assertWritable(); + ApplicationManager.getApplication().assertWriteAccessAllowed(); + final List list = Arrays.asList(ModuleManagerImpl.this.myModuleModel.getModules()); + final Module[] thisModules = getModules(); + for (int i = 0; i < thisModules.length; i++) { + ModuleImpl thisModule = (ModuleImpl)thisModules[i]; + if (!list.contains(thisModule)) { + thisModule.dispose(); + } + } + for (int i = 0; i < myModulesToDispose.size(); i++) { + ModuleImpl module = (ModuleImpl)myModulesToDispose.get(i); + if (!list.contains(module)) { + module.dispose(); + } + } + clearRenamingStuff(); + } + + public boolean isChanged() { + if (!myIsWritable) return false; + Set thisModules = new HashSet(myPath2ModelMap.values()); + Set thatModules = new HashSet(ModuleManagerImpl.this.myModuleModel.myPath2ModelMap.values()); + return !thisModules.equals(thatModules); + } + + private void disposeModel() { + final Collection collection = myPath2ModelMap.values(); + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + module.dispose(); + } + myPath2ModelMap.clear(); + } + + public void projectOpened() { + final Collection collection = myPath2ModelMap.values(); + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + module.projectOpened(); + } + } + + public void projectClosed() { + final Collection collection = myPath2ModelMap.values(); + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + module.projectClosed(); + } + } + + } + + private void commitModel(ModuleModelImpl moduleModel, Runnable runnable) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + final Collection oldModules = myModuleModel.myPath2ModelMap.values(); + final Collection newModules = moduleModel.myPath2ModelMap.values(); + List removedModules = new ArrayList(oldModules); + removedModules.removeAll(newModules); + List addedModules = new ArrayList(newModules); + addedModules.removeAll(oldModules); + + ProjectRootManagerEx.getInstanceEx(myProject).beforeRootsChange(false); + + try { + for (int i = 0; i < removedModules.size(); i++) { + ModuleImpl module = (ModuleImpl)removedModules.get(i); + fireBeforeModuleRemoved(module); + cleanCachedStuff(); + } + + List neverAddedModules = new ArrayList(moduleModel.myModulesToDispose); + neverAddedModules.removeAll(myModuleModel.myPath2ModelMap.values()); + for (Iterator iterator = neverAddedModules.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + module.dispose(); + } + + myModuleModel = moduleModel; + + if (runnable != null) { + runnable.run(); + } + + for (int i = 0; i < removedModules.size(); i++) { + ModuleImpl module = (ModuleImpl)removedModules.get(i); + fireModuleRemoved(module); + cleanCachedStuff(); + module.dispose(); + cleanCachedStuff(); + } + + for (int i = 0; i < addedModules.size(); i++) { + ModuleImpl module = (ModuleImpl)addedModules.get(i); + module.moduleAdded(); + cleanCachedStuff(); + fireModuleAdded(module); + cleanCachedStuff(); + } + final Map modulesToNewNamesMap = moduleModel.myModulesToNewNamesMap; + final Set modulesToBeRenamed = modulesToNewNamesMap.keySet(); + final List modules = new ArrayList(); + for (Iterator iterator = modulesToBeRenamed.iterator(); iterator.hasNext();) { + ModuleImpl module = (ModuleImpl)iterator.next(); + modules.add(module); + module.rename(modulesToNewNamesMap.get(module)); + cleanCachedStuff(); + } + fireModulesRenamed(modules); + cleanCachedStuff(); + } + finally { + ProjectRootManagerEx.getInstanceEx(myProject).rootsChanged(false); + } + } + + private void fireModulesRenamed(List modules) { + if (modules.size() > 0) { + myModuleEventDispatcher.getMulticaster().modulesRenamed(myProject, modules); + } + } + + void fireModuleRenamedByVfsEvent(Module module) { + ProjectRootManagerEx.getInstanceEx(myProject).beforeRootsChange(false); + try { + fireModulesRenamed(Collections.singletonList(module)); + } + finally { + ProjectRootManagerEx.getInstanceEx(myProject).rootsChanged(false); + } + } + + public String getModuleGroup(Module module) { + return myModuleGroup == null ? null : myModuleGroup.get(module); + } + + public void setModuleGroup(Module module, String group) { + if (myModuleGroup == null) { + myModuleGroup = new HashMap(); + } + if (group == null) { + myModuleGroup.remove(module); + } + else { + myModuleGroup.put(module, group); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModulePointerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModulePointerImpl.java new file mode 100644 index 00000000000..2b53d97d00c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModulePointerImpl.java @@ -0,0 +1,51 @@ +package com.intellij.openapi.module.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModulePointer; + +/** + * @author dsl + */ +public class ModulePointerImpl implements ModulePointer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.ModulePointerImpl"); + private Module myModule; + private String myModuleName; + + ModulePointerImpl(Module module) { + myModule = module; + myModuleName = null; + } + + ModulePointerImpl(String name) { + myModule = null; + myModuleName = name; + } + + public Module getModule() { + return myModule; + } + + public String getModuleName() { + if (myModule != null) { + return myModule.getName(); + } + else { + return myModuleName; + } + } + + void moduleAdded(Module module) { + LOG.assertTrue(myModule == null); + LOG.assertTrue(myModuleName.equals(module.getName())); + myModuleName = null; + myModule = module; + } + + void moduleRemoved(Module module) { + LOG.assertTrue(myModule == module); + myModuleName = myModule.getName(); + myModule = null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleTypeManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleTypeManagerImpl.java new file mode 100644 index 00000000000..6b8de9f6d49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleTypeManagerImpl.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.module.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.*; + +import java.util.ArrayList; +import java.util.List; + +public class ModuleTypeManagerImpl extends ModuleTypeManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.ModuleTypeManagerImpl"); + + private List myModuleTypes = new ArrayList(); + + public ModuleTypeManagerImpl() { + registerDefaultTypes(); + } + + public void registerModuleType(ModuleType type) { + for (int i = 0; i < myModuleTypes.size(); i++) { + ModuleType oldType = myModuleTypes.get(i); + if (oldType.getId().equals(type.getId())) { + LOG.error("Trying to register a module type that claunches with existing one. Old=" + oldType + ", new = " + type); + return; + } + } + myModuleTypes.add(type); + } + + public ModuleType[] getRegisteredTypes() { + return myModuleTypes.toArray(new ModuleType[myModuleTypes.size()]); + } + + public ModuleType findByID(String moduleTypeID) { + for (int i = 0; i < myModuleTypes.size(); i++) { + ModuleType type = myModuleTypes.get(i); + if (type.getId().equals(moduleTypeID)) return type; + } + + return new UnknownModuleType(moduleTypeID); + } + + public String getComponentName() { + return "ModuleTypeManager"; + } + + public void initComponent() { + } + + private void registerDefaultTypes() { + ModuleType.JAVA = new JavaModuleType(); + ModuleType.WEB = new WebModuleType(); + ModuleType.EJB = new EjbModuleType(); + ModuleType.J2EE_APPLICATION = new J2EEApplicationModuleType(); + + registerModuleType(ModuleType.JAVA); + registerModuleType(ModuleType.WEB); + registerModuleType(ModuleType.EJB); + registerModuleType(ModuleType.J2EE_APPLICATION); + } + + public void disposeComponent() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleUtil.java new file mode 100644 index 00000000000..32ec5d5f555 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/module/impl/ModuleUtil.java @@ -0,0 +1,148 @@ +/** + * @author cdr + */ +package com.intellij.openapi.module.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.ui.configuration.ContentEntriesEditor; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiDirectory; + +import java.util.*; + +public class ModuleUtil { + public static final Object MODULE_RENAMING_REQUESTOR = new Object(); + + public static boolean checkSourceRootsConfigured(final Module module) { + VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(); + if (sourceRoots.length == 0) { + Messages.showErrorDialog( + module.getProject(), + "No Source Roots configured for module "+module.getName()+"\nPlease use Settings | Paths to configure roots.", + "No Source Roots Configured" + ); + + ModulesConfigurator.showDialog(module.getProject(), module.getName(), ContentEntriesEditor.NAME, false); + + sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(); + if (sourceRoots.length == 0) { + return false; + } + } + return true; + } + + static String moduleNameByFileName(String fileName) { + if (fileName.endsWith(".iml")) { + return fileName.substring(0, fileName.length() - ".iml".length()); + } + else { + return fileName; + } + } + + public static String getModuleNameInReadAction(final Module module) { + final String moduleName = ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + final String name = module.getName(); + return name; + } + }); + return moduleName; + } + + public static boolean isModuleDisposed(PsiElement element) { + if (!element.isValid()) return true; + final Project project = element.getProject(); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final PsiFile file = element.getContainingFile(); + if (file == null) return true; + VirtualFile vFile = file.getVirtualFile(); + final Module module = vFile == null ? null : projectFileIndex.getModuleForFile(vFile); + // element may be in library + return module == null ? !projectFileIndex.isInLibraryClasses(vFile) : module.isDisposed(); + } + + public static Module getParentModuleOfType(ModuleType expectedModuleType, Module module) { + if (expectedModuleType.equals(module.getModuleType())) return module; + final List parents = getParentModulesOfType(expectedModuleType, module); + return parents.size() == 0 ? null : parents.get(0); + } + + public static List getParentModulesOfType(ModuleType expectedModuleType, Module module) { + final Module[] parents = ModuleManager.getInstance(module.getProject()).getModuleDependentModules(module); + ArrayList modules = new ArrayList(); + for (int i = 0; i < parents.length; i++) { + Module parent = parents[i]; + if (expectedModuleType.equals(parent.getModuleType())) { + modules.add(parent); + } + } + return modules; + } + + public static Module findModuleForPsiElement(PsiElement element) { + if (!element.isValid()) return null; + Project project = element.getProject(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (element instanceof PsiPackage) { + final PsiDirectory[] directories = ((PsiPackage)element).getDirectories(); + for (int idx = 0; idx < directories.length; idx++) { + final Module module = fileIndex.getModuleForFile(directories[idx].getVirtualFile()); + if (module != null) { + return module; + } + } + return null; + } + if (element instanceof PsiFile) { + VirtualFile vFile = ((PsiFile)element).getVirtualFile(); + return vFile != null ? fileIndex.getModuleForFile(vFile) : null; + } + + if (element instanceof PsiDirectory) { + final VirtualFile vFile = ((PsiDirectory)element).getVirtualFile(); + if (fileIndex.isInLibrarySource(vFile) || fileIndex.isInLibraryClasses(vFile)) { + final OrderEntry[] orderEntries = fileIndex.getOrderEntriesForFile(vFile); + if (orderEntries.length == 0) { + return null; + } + Set modules = new HashSet(); + for (int j = 0; j < orderEntries.length; j++) { + modules.add(orderEntries[j].getOwnerModule()); + } + final Module[] candidates = modules.toArray(new Module[modules.size()]); + Arrays.sort(candidates, ModuleManager.getInstance(project).moduleDependencyComparator()); + return candidates[0]; + } + return fileIndex.getModuleForFile(vFile); + } + final PsiFile containingFile = element.getContainingFile(); + if (containingFile != null) { + final VirtualFile virtualFile = containingFile.getVirtualFile(); + if (virtualFile != null) { + return fileIndex.getModuleForFile(virtualFile); + } + } + return null; + } + + public static Module getModuleForFile(final Project project, final VirtualFile file) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + return fileIndex.getModuleForFile(file); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/ColorSettingsPagesImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/ColorSettingsPagesImpl.java new file mode 100644 index 00000000000..8c10d6f5406 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/ColorSettingsPagesImpl.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import com.intellij.openapi.options.colors.ColorSettingsPages; + +import java.util.ArrayList; +import java.util.List; + +public class ColorSettingsPagesImpl extends ColorSettingsPages implements ApplicationComponent { + private List myPages = new ArrayList(); + + public ColorSettingsPagesImpl() { + registerStandardPages(); + } + + public String getComponentName() { + return "ColorSettingsPages"; + } + + public void initComponent() { } + + private void registerStandardPages() { + registerPage(new GeneralColorsPage()); + registerPage(new JavaColorSettingsPage()); + registerPage(new HTMLColorsPage()); + registerPage(new XMLColorsPage()); + registerPage(new JSPColorsPage()); + registerPage(new CustomColorsPage()); + } + + public void disposeComponent() { + } + + public void registerPage(ColorSettingsPage page) { + myPages.add(page); + } + + public ColorSettingsPage[] getRegisteredPages() { + return myPages.toArray(new ColorSettingsPage[myPages.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/CustomColorsPage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/CustomColorsPage.java new file mode 100644 index 00000000000..a424a1d682a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/CustomColorsPage.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.ide.highlighter.custom.CustomFileHighlighter; +import com.intellij.ide.highlighter.custom.CustomHighlighterColors; +import com.intellij.ide.highlighter.custom.SyntaxTable; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import com.intellij.util.Icons; + +import javax.swing.*; +import java.util.Map; + +public class CustomColorsPage implements ColorSettingsPage { + private static final ColorDescriptor[] COLORS = new ColorDescriptor[0]; + private static final AttributesDescriptor[] ATTRS = new AttributesDescriptor[] { + new AttributesDescriptor("Keyword1", CustomHighlighterColors.CUSTOM_KEYWORD1_ATTRIBUTES), + new AttributesDescriptor("Keyword2", CustomHighlighterColors.CUSTOM_KEYWORD2_ATTRIBUTES), + new AttributesDescriptor("Keyword3", CustomHighlighterColors.CUSTOM_KEYWORD3_ATTRIBUTES), + new AttributesDescriptor("Keyword4", CustomHighlighterColors.CUSTOM_KEYWORD4_ATTRIBUTES), + new AttributesDescriptor("Number", CustomHighlighterColors.CUSTOM_NUMBER_ATTRIBUTES), + new AttributesDescriptor("String", CustomHighlighterColors.CUSTOM_STRING_ATTRIBUTES), + new AttributesDescriptor("Line comment", CustomHighlighterColors.CUSTOM_LINE_COMMENT_ATTRIBUTES), + new AttributesDescriptor("Block comment", CustomHighlighterColors.CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES), + }; + + private final static SyntaxTable SYNTAX_TABLE = new SyntaxTable(); + static { + SYNTAX_TABLE.setLineComment("#"); + SYNTAX_TABLE.setStartComment("/*"); + SYNTAX_TABLE.setEndComment("*/"); + SYNTAX_TABLE.setHexPrefix("0x"); + SYNTAX_TABLE.setNumPostfixChars("dDlL"); + SYNTAX_TABLE.setNumPostfixChars("dDlL"); + SYNTAX_TABLE.addKeyword1("aKeyword1"); + SYNTAX_TABLE.addKeyword1("anotherKeyword1"); + SYNTAX_TABLE.addKeyword2("aKeyword2"); + SYNTAX_TABLE.addKeyword2("anotherKeyword2"); + SYNTAX_TABLE.addKeyword3("aKeyword3"); + SYNTAX_TABLE.addKeyword3("anotherKeyword3"); + SYNTAX_TABLE.addKeyword4("aKeyword4"); + SYNTAX_TABLE.addKeyword4("anotherKeyword4"); + } + + public String getDisplayName() { + return "Custom"; + } + + public Icon getIcon() { + return Icons.CUSTOM_FILE_ICON; + } + + public AttributesDescriptor[] getAttributeDescriptors() { + return ATTRS; + } + + public ColorDescriptor[] getColorDescriptors() { + return COLORS; + } + + public FileHighlighter getHighlighter() { + return new CustomFileHighlighter(SYNTAX_TABLE); + } + + public String getDemoText() { + return "# Line comment\n" + + "aKeyword1 variable = 123;\n" + + "anotherKeyword1 someString = \"SomeString\";\n" + + "aKeyword2 variable = 123;\n" + + "anotherKeyword2 someString = \"SomeString\";\n" + + "aKeyword3 variable = 123;\n" + + "anotherKeyword3 someString = \"SomeString\";\n" + + "aKeyword4 variable = 123;\n" + + "anotherKeyword4 someString = \"SomeString\";\n" + + "/* \n" + + " * Block comment\n" + + " */\n" + + "\n"; + } + + public Map getAdditionalHighlightingTagToDescriptorMap() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java new file mode 100644 index 00000000000..fa295658a9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.codeInsight.template.impl.TemplateColors; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.PlainFileHighlighter; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; + +import javax.swing.*; +import java.util.Map; + +public class GeneralColorsPage implements ColorSettingsPage { + private static final AttributesDescriptor[] ATT_DESCRIPTORS = new AttributesDescriptor[] { + new AttributesDescriptor("Default text", HighlighterColors.TEXT), + + new AttributesDescriptor("Folded text", EditorColors.FOLDED_TEXT_ATTRIBUTES), + new AttributesDescriptor("Search result", EditorColors.SEARCH_RESULT_ATTRIBUTES), + new AttributesDescriptor("Search result (write access)", EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES), + new AttributesDescriptor("Text search result", EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES), + + new AttributesDescriptor("Template variable", TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES) + }; + + private static final ColorDescriptor[] COLOR_DESCRIPTORS = new ColorDescriptor[] { + new ColorDescriptor("Background", EditorColors.BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Background in readonly files", EditorColors.READONLY_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Readonly fragment background", EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND), + + + new ColorDescriptor("Selection Background", EditorColors.SELECTION_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Selection Foreground", EditorColors.SELECTION_FOREGROUND_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Caret", EditorColors.CARET_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Caret row", EditorColors.CARET_ROW_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Right margin", EditorColors.RIGHT_MARGIN_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Whitespaces", EditorColors.WHITESPACES_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Line number", EditorColors.LINE_NUMBERS_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("CVS annotations", EditorColors.ANNOTATIONS_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Folding outline", EditorColors.FOLDING_TREE_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Selected folding outline", EditorColors.SELECTED_FOLDING_TREE_COLOR, ColorDescriptor.Kind.FOREGROUND), + new ColorDescriptor("Added lines", EditorColors.ADDED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor("Modified lines", EditorColors.MODIFIED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), + }; + + public String getDisplayName() { + return "General"; + } + + public Icon getIcon() { + return StdFileTypes.PLAIN_TEXT.getIcon(); + } + + public AttributesDescriptor[] getAttributeDescriptors() { + return new AttributesDescriptor[0]; + } + + public ColorDescriptor[] getColorDescriptors() { + return COLOR_DESCRIPTORS; + } + + public FileHighlighter getHighlighter() { + return new PlainFileHighlighter(); + } + + public String getDemoText() { + String text = + "IntelliJ IDEA is a full-featured Java IDE\n" + + "with a high level of usability and outstanding\n" + + "advanced code editing and refactoring support.\n"; + + return text; + } + + public Map getAdditionalHighlightingTagToDescriptorMap() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/HTMLColorsPage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/HTMLColorsPage.java new file mode 100644 index 00000000000..8cf8b305f06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/HTMLColorsPage.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.ide.highlighter.HtmlFileHighlighter; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; + +import javax.swing.*; +import java.util.Map; + +public class HTMLColorsPage implements ColorSettingsPage { + private static final AttributesDescriptor[] ATTRS = new AttributesDescriptor[] { + new AttributesDescriptor("Comment", HighlighterColors.HTML_COMMENT), + new AttributesDescriptor("Tag", HighlighterColors.HTML_TAG), + new AttributesDescriptor("Tag name", HighlighterColors.HTML_TAG_NAME), + new AttributesDescriptor("Attribute name", HighlighterColors.HTML_ATTRIBUTE_NAME), + new AttributesDescriptor("Attribute value", HighlighterColors.HTML_ATTRIBUTE_VALUE) + }; + + private static final ColorDescriptor[] COLORS = new ColorDescriptor[0]; + + public String getDisplayName() { + return "HTML"; + } + + public Icon getIcon() { + return StdFileTypes.HTML.getIcon(); + } + + public AttributesDescriptor[] getAttributeDescriptors() { + return ATTRS; + } + + public ColorDescriptor[] getColorDescriptors() { + return COLORS; + } + + public FileHighlighter getHighlighter() { + return new HtmlFileHighlighter(); + } + + public String getDemoText() { + return "\n" + + "\n" + + "\n" + + "\n" + + "IntelliJ IDEA\n" + + "\n" + + "\n" + + "

    IntelliJ IDEA

    \n" + + "


    \n" + + "What is IntelliJ IDEA?

    \n" + + "\n" + + ""; + } + + public Map getAdditionalHighlightingTagToDescriptorMap() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java new file mode 100644 index 00000000000..f7a102b5581 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.codeInsight.CodeInsightColors; +import com.intellij.debugger.settings.DebuggerColors; +import com.intellij.ide.highlighter.JavaFileHighlighter; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import com.intellij.pom.java.LanguageLevel; + +import javax.swing.*; +import java.util.HashMap; +import java.util.Map; + +public class JavaColorSettingsPage implements ColorSettingsPage { + private final static AttributesDescriptor[] ourDescriptors = new AttributesDescriptor[] { + new AttributesDescriptor("Keyword", HighlighterColors.JAVA_KEYWORD), + new AttributesDescriptor("Number", HighlighterColors.JAVA_NUMBER), + + new AttributesDescriptor("String", HighlighterColors.JAVA_STRING), + new AttributesDescriptor("Valid escape in string", HighlighterColors.JAVA_VALID_STRING_ESCAPE), + new AttributesDescriptor("Invalid escape in string", HighlighterColors.JAVA_INVALID_STRING_ESCAPE), + + new AttributesDescriptor("Operator sign", HighlighterColors.JAVA_OPERATION_SIGN), + new AttributesDescriptor("Parentheses", HighlighterColors.JAVA_PARENTHS), + new AttributesDescriptor("Braces", HighlighterColors.JAVA_BRACES), + new AttributesDescriptor("Brackets", HighlighterColors.JAVA_BRACKETS), + new AttributesDescriptor("Comma", HighlighterColors.JAVA_COMMA), + new AttributesDescriptor("Semicolon", HighlighterColors.JAVA_SEMICOLON), + new AttributesDescriptor("Dot", HighlighterColors.JAVA_DOT), + + new AttributesDescriptor("Line comment", HighlighterColors.JAVA_LINE_COMMENT), + new AttributesDescriptor("Block comment", HighlighterColors.JAVA_BLOCK_COMMENT), + new AttributesDescriptor("JavaDoc comment", HighlighterColors.JAVA_DOC_COMMENT), + new AttributesDescriptor("JavaDoc tag", HighlighterColors.JAVA_DOC_TAG), + new AttributesDescriptor("JavaDoc markup", HighlighterColors.JAVA_DOC_MARKUP), + + new AttributesDescriptor("Unknown symbol", CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES), + new AttributesDescriptor("Error", CodeInsightColors.ERRORS_ATTRIBUTES), + new AttributesDescriptor("Warning", CodeInsightColors.WARNINGS_ATTRIBUTES), + new AttributesDescriptor("Deprecated symbol", CodeInsightColors.DEPRECATED_ATTRIBUTES), + new AttributesDescriptor("Unused symbol", CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES), + + new AttributesDescriptor("Class", CodeInsightColors.CLASS_NAME_ATTRIBUTES), + new AttributesDescriptor("Interface", CodeInsightColors.INTERFACE_NAME_ATTRIBUTES), + new AttributesDescriptor("Local variable", CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES), + new AttributesDescriptor("Instance field", CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES), + new AttributesDescriptor("Static field", CodeInsightColors.STATIC_FIELD_ATTRIBUTES), + new AttributesDescriptor("Parameter", CodeInsightColors.PARAMETER_ATTRIBUTES), + new AttributesDescriptor("Method call", CodeInsightColors.METHOD_CALL_ATTRIBUTES), + new AttributesDescriptor("Method declaration", CodeInsightColors.METHOD_DECLARATION_ATTRIBUTES), + new AttributesDescriptor("Constructor call", CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES), + new AttributesDescriptor("Constructor declaration", CodeInsightColors.CONSTRUCTOR_DECLARATION_ATTRIBUTES), + new AttributesDescriptor("Static method", CodeInsightColors.STATIC_METHOD_ATTRIBUTES), + + new AttributesDescriptor("Matched brace", CodeInsightColors.MATCHED_BRACE_ATTRIBUTES), + new AttributesDescriptor("Unmatched brace", CodeInsightColors.UNMATCHED_BRACE_ATTRIBUTES), + new AttributesDescriptor("Bad character", HighlighterColors.BAD_CHARACTER), + + new AttributesDescriptor("Breakpoint line", DebuggerColors.BREAKPOINT_ATTRIBUTES), + new AttributesDescriptor("Execution point", DebuggerColors.EXECUTIONPOINT_ATTRIBUTES), + + new AttributesDescriptor("Annotation name", CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES), + new AttributesDescriptor("Annotation attribute name", CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES) + }; + + private final static ColorDescriptor[] ourColorDescriptors = new ColorDescriptor[]{ + new ColorDescriptor("Method separator color", CodeInsightColors.METHOD_SEPARATORS_COLOR, ColorDescriptor.Kind.FOREGROUND) + }; + + private final static Map ourTags = new HashMap(); + { + ourTags.put("field", CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES); + ourTags.put("unusedField", CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES); + ourTags.put("error", CodeInsightColors.ERRORS_ATTRIBUTES); + ourTags.put("warning", CodeInsightColors.WARNINGS_ATTRIBUTES); + ourTags.put("unknownType", CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES); + ourTags.put("localVar", CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES); + ourTags.put("static", CodeInsightColors.STATIC_FIELD_ATTRIBUTES); + ourTags.put("deprecated", CodeInsightColors.DEPRECATED_ATTRIBUTES); + ourTags.put("constructorCall", CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES); + ourTags.put("constructorDeclaration", CodeInsightColors.CONSTRUCTOR_DECLARATION_ATTRIBUTES); + ourTags.put("methodCall", CodeInsightColors.METHOD_CALL_ATTRIBUTES); + ourTags.put("methodDeclaration", CodeInsightColors.METHOD_DECLARATION_ATTRIBUTES); + ourTags.put("static_method", CodeInsightColors.STATIC_METHOD_ATTRIBUTES); + ourTags.put("param", CodeInsightColors.PARAMETER_ATTRIBUTES); + ourTags.put("class", CodeInsightColors.CLASS_NAME_ATTRIBUTES); + ourTags.put("interface", CodeInsightColors.INTERFACE_NAME_ATTRIBUTES); + ourTags.put("annotationName", CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES); + ourTags.put("annotationAttributeName", CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES); + } + + public String getDisplayName() { + return "Java"; + } + + public Icon getIcon() { + return StdFileTypes.JAVA.getIcon(); + } + + public AttributesDescriptor[] getAttributeDescriptors() { + return ourDescriptors; + } + + public ColorDescriptor[] getColorDescriptors() { + return ourColorDescriptors; + } + + public FileHighlighter getHighlighter() { + return new JavaFileHighlighter(LanguageLevel.HIGHEST); + } + + public String getDemoText() { + String text = + "/* Block comment */\n" + + "import java.util.Date;\n" + + " Bad characters: \\n #\n" + + "/**\n" + + " * Doc comment here for SomeClass\n" + + " * @version 1.0\n" + + " * @see Math#sin(double)\n" + + " */\n" + + "@Annotation (name=value)\n" + + "public class SomeClass { // some comment\n" + + " private String field = \"Hello World\";\n" + + " private double unusedField = 12345.67890;\n" + + " private UnknownType anotherString = \"Another\\nStrin\\g\";\n" + + " private int[] array = new int[] {1, 2, 3};\n" + + " public static int staticField = 0;\n" + + "\n" + + " public SomeClass(AnInterface param) {\n" + + " //TODO: something\n" + + " int localVar = \"IntelliJ\"; // Error, incompatible types\n" + + " System.out.println(anotherString + field + localVar);\n" + + " long time = Date.parse(\"1.2.3\"); // Method is deprecated\n" + + " int value = this.staticField; \n" + + " }\n" + + " void method() {/* block\n" + + " comment */\n" + + " new SomeClass();\n" + + " }\n" + + "}\n" + + "\n" + + "interface AnInterface {\n" + + " int CONSTANT = 2;\n" + + "}"; + + return text; + } + + public Map getAdditionalHighlightingTagToDescriptorMap() { + return ourTags; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/XMLColorsPage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/XMLColorsPage.java new file mode 100644 index 00000000000..1ff2b0c090a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/colors/pages/XMLColorsPage.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.options.colors.pages; + +import com.intellij.ide.highlighter.XmlFileHighlighter; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.FileHighlighter; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; + +import javax.swing.*; +import java.util.Map; + +public class XMLColorsPage implements ColorSettingsPage { + private static final ColorDescriptor[] COLORS = new ColorDescriptor[0]; + private static final AttributesDescriptor[] ATTRS = new AttributesDescriptor[] { + new AttributesDescriptor("Prologue", HighlighterColors.XML_PROLOGUE), + new AttributesDescriptor("Comment", HighlighterColors.XML_COMMENT), + new AttributesDescriptor("Tag", HighlighterColors.XML_TAG), + new AttributesDescriptor("Tag name", HighlighterColors.XML_TAG_NAME), + new AttributesDescriptor("Attribute name", HighlighterColors.XML_ATTRIBUTE_NAME), + new AttributesDescriptor("Attribute value", HighlighterColors.XML_ATTRIBUTE_VALUE), + new AttributesDescriptor("Tag data", HighlighterColors.XML_TAG_DATA), + }; + + public String getDisplayName() { + return "XML"; + } + + public Icon getIcon() { + return StdFileTypes.XML.getIcon(); + } + + public AttributesDescriptor[] getAttributeDescriptors() { + return ATTRS; + } + + public ColorDescriptor[] getColorDescriptors() { + return COLORS; + } + + public FileHighlighter getHighlighter() { + return new XmlFileHighlighter(); + } + + public String getDemoText() { + return "\n" + + "\n" + + "\n" + + "\n" + + " Main Index\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } + + public Map getAdditionalHighlightingTagToDescriptorMap() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelMnemonicsUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelMnemonicsUtil.java new file mode 100644 index 00000000000..21922f58980 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelMnemonicsUtil.java @@ -0,0 +1,44 @@ +/** + * @author cdr + */ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; + +import java.awt.event.KeyEvent; + +public class ControlPanelMnemonicsUtil { + public static Configurable getConfigurableFromMnemonic(KeyEvent e, ConfigurableGroup[] groups) { + ConfigurableGroup group = getGroupFromKeycode(e.getKeyCode(), groups); + if (group == null) return null; + + int idx = getIndexFromKeycode(e.getKeyCode(), group == groups[0]); + if (idx < 0 || idx >= group.getConfigurables().length) return null; + + return group.getConfigurables()[idx]; + } + + public static int getIndexFromKeycode(int keyCode, boolean isNumeric) { + if (isNumeric) { + if (keyCode >= KeyEvent.VK_1 && keyCode <= KeyEvent.VK_9) return keyCode - KeyEvent.VK_1; + if (keyCode >= KeyEvent.VK_NUMPAD1 && keyCode <= KeyEvent.VK_NUMPAD9) return keyCode - KeyEvent.VK_NUMPAD1; + if (keyCode == KeyEvent.VK_NUMPAD0 || keyCode == KeyEvent.VK_0) return 9; + } + else { + if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) return keyCode - KeyEvent.VK_A; + } + return -1; + } + + public static ConfigurableGroup getGroupFromKeycode(int keyCode, ConfigurableGroup[] groups) { + if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9 || + keyCode >= KeyEvent.VK_NUMPAD0 && keyCode <= KeyEvent.VK_NUMPAD9) { + return groups[0]; + } + + if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z && groups.length > 1) return groups[1]; + + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelSettingsEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelSettingsEditor.java new file mode 100644 index 00000000000..35d46a95b9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ControlPanelSettingsEditor.java @@ -0,0 +1,394 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.ide.actions.ShowSettingsUtilImpl; +import com.intellij.openapi.actionSystem.ActionButtonComponent; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.LabeledIcon; +import com.intellij.ui.ScrollPaneFactory; + +import javax.swing.*; +import javax.swing.plaf.LabelUI; +import java.awt.*; +import java.awt.event.*; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 8, 2003 + * Time: 9:40:01 PM + * To change this template use Options | File Templates. + */ +public class ControlPanelSettingsEditor extends DialogWrapper { + private static final int ICONS_PER_ROW = 7; + private static final Insets ICON_INSETS = new Insets(2, 2, 2, 2); + + protected final Project myProject; + private final ConfigurableGroup[] myGroups; + private JPanel myPanel; + + private Configurable myKeypressedConfigurable = null; + private int mySelectedRow = 0; + private int mySelectedColumn = 0; + private int mySelectedGroup = 0; + + public ControlPanelSettingsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) { + super(project, true); + myProject = project; + myGroups = groups; + setTitle("Settings"); + setCancelButtonText("Close"); + init(); + if (preselectedConfigurable != null) { + selectConfigurable(preselectedConfigurable); + editConfigurable(preselectedConfigurable); + } + } + + protected String getDimensionServiceKey() { + return "#com.intellij.openapi.options.ex.ControlPanelSettingsEditor"; + } + + protected Action[] createActions() { + return new Action[]{getCancelAction()}; + } + + protected Action[] createLeftSideActions() { + return new Action[]{new SwitchToClassicViewAction()}; + } + + protected JComponent createCenterPanel() { + myPanel = new JPanel(new VerticalFlowLayout()); + for (int i = 0; i < myGroups.length; i++) { + ConfigurableGroup group = myGroups[i]; + myPanel.add(createGroupComponent(group, i)); + } + + myPanel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + try { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + myKeypressedConfigurable = getSelectedConfigurable(); + return; + } + + int code = e.getKeyCode(); + if (code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_RIGHT || + code == KeyEvent.VK_LEFT) { + if (getSelectedConfigurable() == null) { + mySelectedColumn = 0; + mySelectedRow = 0; + mySelectedGroup = 0; + return; + } + + int xShift = 0; + int yShift = 0; + + if (code == KeyEvent.VK_UP) { + yShift = -1; + } + else if (code == KeyEvent.VK_DOWN) { + yShift = 1; + } + else if (code == KeyEvent.VK_LEFT) { + xShift = -1; + } + else /*if (code == KeyEvent.VK_RIGHT)*/ { + xShift = 1; + } + + int newColumn = mySelectedColumn + xShift; + int newRow = mySelectedRow + yShift; + int newGroup = mySelectedGroup; + + if (newColumn < 0) newColumn = 0; + if (newColumn >= ICONS_PER_ROW) newColumn = ICONS_PER_ROW - 1; + + int idx = newColumn + newRow * ICONS_PER_ROW; + if (idx >= myGroups[newGroup].getConfigurables().length) { + if (yShift > 0) { + newRow = 0; + newGroup++; + if (newGroup >= myGroups.length) return; + + idx = newColumn + newRow * ICONS_PER_ROW; + if (idx >= myGroups[newGroup].getConfigurables().length) return; + } + else if (xShift > 0) { + return; + } + } + + if (yShift < 0 && idx < 0) { + newGroup--; + if (newGroup < 0) return; + int rowCount = getRowCount(myGroups[newGroup].getConfigurables().length); + newRow = rowCount - 1; + idx = newColumn + newRow * ICONS_PER_ROW; + if (idx >= myGroups[newGroup].getConfigurables().length) { + if (newRow <= 0) return; + newRow--; + } + } + + mySelectedColumn = newColumn; + mySelectedRow = newRow; + mySelectedGroup = newGroup; + return; + } + + myKeypressedConfigurable = ControlPanelMnemonicsUtil.getConfigurableFromMnemonic(e, myGroups); + } + finally { + myPanel.repaint(); + } + } + + public void keyReleased(KeyEvent e) { + if (myKeypressedConfigurable != null) { + e.consume(); + selectConfigurable(myKeypressedConfigurable); + editConfigurable(myKeypressedConfigurable); + myKeypressedConfigurable = null; + myPanel.repaint(); + } + } + }); + + JPanel panel = new JPanel(new GridBagLayout()); + panel.add(myPanel, + new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(panel); + scrollPane.setBorder(null); + return scrollPane; + } + + private void selectConfigurable(Configurable configurable) { + for (int g = 0; g < myGroups.length; g++) { + ConfigurableGroup group = myGroups[g]; + Configurable[] allConfigurables = group.getConfigurables(); + int count = allConfigurables.length; + int rowCount = getRowCount(count); + + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < ICONS_PER_ROW; j++) { + int n = i * ICONS_PER_ROW + j; + if (n < count && configurable == allConfigurables[n]) { + mySelectedGroup = g; + mySelectedRow = i; + mySelectedColumn = j; + return; + } + } + } + } + } + + public JComponent getPreferredFocusedComponent() { + return myPanel; + } + + private JComponent createGroupComponent(ConfigurableGroup group, int groupIdx) { + JPanel panel = new JPanel(new VerticalFlowLayout()); + JLabel label = new JLabel(group.getDisplayName()) { + public void setUI(LabelUI ui) { + super.setUI(ui); + setFont(new JLabel().getFont().deriveFont(20.0f)); + } + }; + + label.setFont(label.getFont().deriveFont(20.0f)); + panel.add(label); + + panel.add(new JSeparator(JSeparator.HORIZONTAL)); + + Configurable[] allConfigurables = group.getConfigurables(); + int count = allConfigurables.length; + int rowCount = getRowCount(count); + JPanel toolBar = new JPanel(new GridLayout(0, ICONS_PER_ROW)); + + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < ICONS_PER_ROW; j++) { + int n = i * ICONS_PER_ROW + j; + if (n < count) { + toolBar.add(createActionButton(allConfigurables[n], getShortcut(n, groupIdx), groupIdx, j, i)); + } + } + } + + panel.add(toolBar); + + panel.add(new JPanel()); + return panel; + } + + private static int getRowCount(int count) { + return count / ICONS_PER_ROW + (count % ICONS_PER_ROW == 0 ? 0 : 1); + } + + private static KeyStroke getShortcut(int actionIdx, int groupIdx) { + int mnemonic = getMnemonicByIndex(actionIdx, groupIdx); + if (mnemonic == 0) return null; + return KeyStroke.getKeyStroke(mnemonic, 0); + } + + private static int getMnemonicByIndex(int idx, int groupIdx) { + if (groupIdx == 0) { + if (idx >= 0 && idx < 9) return KeyEvent.VK_1 + idx; + if (idx == 9) return KeyEvent.VK_0; + return 0; + } + + if (groupIdx == 1) { + if (idx >= 0 && idx < KeyEvent.VK_Z - KeyEvent.VK_A) return KeyEvent.VK_A + idx; + } + + return 0; + } + + private Configurable getSelectedConfigurable() { + if (mySelectedColumn == -1 || mySelectedRow == -1 || mySelectedGroup == -1) return null; + return myGroups[mySelectedGroup].getConfigurables()[mySelectedColumn + mySelectedRow * ICONS_PER_ROW]; + } + + private JComponent createActionButton(final Configurable configurable, + KeyStroke shortcut, + final int groupIdx, + final int column, + final int row) { + return new MyActionButton(configurable, shortcut, groupIdx, row, column); + } + + private void editConfigurable(Configurable configurable) { + Configurable actualConfigurable = configurable; + if (configurable instanceof ProjectComponent) { + actualConfigurable = new ProjectConfigurableWrapper(myProject, configurable); + } + + new SingleConfigurableEditor(myProject, actualConfigurable, createDimensionKey(configurable)).show(); + } + + private static String createDimensionKey(Configurable configurable) { + String displayName = configurable.getDisplayName(); + displayName = displayName.replaceAll("\n", "_").replaceAll(" ", "_"); + return "#" + displayName; + } + + private class MyActionButton extends JComponent implements ActionButtonComponent { + private Configurable myConfigurable; + private int myGroupIdx; + private int myRowIdx; + private int myColumnIdx; + private Icon myIcon; + private KeyStroke myShortcut; + + public MyActionButton(Configurable configurable, KeyStroke shortcut, int groupIdx, int rowIdx, int columnIdx) { + myConfigurable = configurable; + myGroupIdx = groupIdx; + myRowIdx = rowIdx; + myColumnIdx = columnIdx; + myShortcut = shortcut; + myIcon = createIcon(); + setToolTipText(null); + setupListeners(); + } + + private Icon createIcon() { + Icon icon = myConfigurable.getIcon(); + if (icon == null) { + icon = IconLoader.getIcon("/general/configurableDefault.png"); + } + + String displayName = myConfigurable.getDisplayName(); + + LabeledIcon labeledIcon = new LabeledIcon(icon, displayName, + myShortcut == null + ? null + : " (" + KeyEvent.getKeyText(myShortcut.getKeyCode()) + ")"); + return labeledIcon; + } + + public Dimension getPreferredSize() { + return new Dimension(myIcon.getIconWidth() + ICON_INSETS.left + ICON_INSETS.right, + myIcon.getIconHeight() + ICON_INSETS.top + ICON_INSETS.bottom); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + ActionButtonLook look = ActionButtonLook.IDEA_LOOK; + look.paintBackground(g, this); + look.paintIcon(g, this, myIcon); + look.paintBorder(g, this); + } + + public int getPopState() { + if (myKeypressedConfigurable == myConfigurable) return ActionButtonComponent.PUSHED; + if (myKeypressedConfigurable != null) return ActionButtonComponent.NORMAL; + Configurable selectedConfigurable = getSelectedConfigurable(); + if (selectedConfigurable == myConfigurable) return ActionButtonComponent.POPPED; + return ActionButtonComponent.NORMAL; + } + + private void setupListeners() { + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + myKeypressedConfigurable = myConfigurable; + myPanel.repaint(); + } + + public void mouseReleased(MouseEvent e) { + if (myKeypressedConfigurable == myConfigurable) { + myKeypressedConfigurable = null; + editConfigurable(myConfigurable); + } + else { + myKeypressedConfigurable = null; + } + + myPanel.repaint(); + } + }); + + addMouseMotionListener(new MouseMotionListener() { + public void mouseDragged(MouseEvent e) { + } + + public void mouseMoved(MouseEvent e) { + mySelectedColumn = myColumnIdx; + mySelectedRow = myRowIdx; + mySelectedGroup = myGroupIdx; + myPanel.repaint(); + } + }); + } + } + + private class SwitchToClassicViewAction extends AbstractAction { + public SwitchToClassicViewAction() { + putValue(Action.NAME, "Classic &View"); + } + + public void actionPerformed(ActionEvent e) { + ControlPanelSettingsEditor.this.close(OK_EXIT_CODE); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ((ShowSettingsUtilImpl)ShowSettingsUtil.getInstance()).showExplorerOptions(myProject, myGroups); + } + }, ModalityState.NON_MMODAL); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ExplorerSettingsEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ExplorerSettingsEditor.java new file mode 100644 index 00000000000..f7a5c80821a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ExplorerSettingsEditor.java @@ -0,0 +1,532 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.ide.actions.ShowSettingsUtilImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionButtonLook; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.ui.HorizontalLabeledIcon; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.Alarm; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashMap; +import gnu.trove.TObjectIntHashMap; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.Iterator; +import java.util.Map; + +public class ExplorerSettingsEditor extends DialogWrapper { + /** When you visit the same editor next time you see the same selected configurable. */ + private static final TObjectIntHashMap ourGroup2LastConfigurableIndex = new TObjectIntHashMap(); + private static String ourLastGroup; + + private final Project myProject; + private Configurable myKeySelectedConfigurable; + private int myKeySelectedConfigurableIndex; + + private final ConfigurableGroup[] myGroups; + + /** Configurable which is currently selected. */ + private Configurable mySelectedConfigurable; + private ConfigurableGroup mySelectedGroup; + private JPanel myOptionsPanel; + + private final Map myInitializedConfigurables2Component; + private final Dimension myPreferredSize; + private final Map myConfigurable2PrefSize; + private TabbedPaneWrapper myGroupTabs; + private JButton myHelpButton; + private JPanel myComponentPanel; + + public ExplorerSettingsEditor(Project project, ConfigurableGroup[] group) { + super(project, true); + myProject = project; + myPreferredSize = new Dimension(800, 600); + myGroups = group; + + if (myGroups.length == 0) { + throw new IllegalStateException("number of configurables must be more then zero"); + } + + myInitializedConfigurables2Component = new HashMap(); + myConfigurable2PrefSize = new HashMap(); + + init(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.openapi.options.ex.ExplorerSettingsEditor"; + } + + protected final void init() { + super.init(); + + int lastGroup = 0; + for (int i = 0; i < myGroups.length; i++) { + ConfigurableGroup group = myGroups[i]; + if (Comparing.equal(group.getShortName(), ourLastGroup)) { + lastGroup = i; + break; + } + } + + selectGroup(lastGroup); + } + + private void selectGroup(int groupIdx) { + int lastIndex = ourGroup2LastConfigurableIndex.get(myGroups[groupIdx].getShortName()); + selectGroup(groupIdx,lastIndex); + } + private void selectGroup(int groupIdx, int indexToSelect) { + rememberLastUsedPage(); + + ConfigurableGroup group = myGroups[groupIdx]; + mySelectedGroup = group; + String shortName = mySelectedGroup.getShortName(); + ourLastGroup = shortName; + Configurable[] configurables = mySelectedGroup.getConfigurables(); + Configurable toSelect = configurables[indexToSelect]; + myGroupTabs.setSelectedIndex(groupIdx); + + selectConfigurable(toSelect, indexToSelect); + + requestFocusForMainPanel(); + } + + private void rememberLastUsedPage() { + if (mySelectedGroup != null) { + Configurable[] configurables = mySelectedGroup.getConfigurables(); + int index = -1; + for (int i = 0; i < configurables.length; i++) { + Configurable configurable = configurables[i]; + if (configurable == mySelectedConfigurable) { + index = i; + break; + } + } + ourGroup2LastConfigurableIndex.put(mySelectedGroup.getShortName(), index); + } + } + + private void updateTitle() { + if (mySelectedConfigurable == null) { + setTitle("Settings"); + } + else { + String displayName = mySelectedConfigurable.getDisplayName(); + setTitle(mySelectedGroup.getDisplayName() + " - " + (displayName != null ? displayName.replace('\n', ' ') : "")); + myHelpButton.setEnabled(mySelectedConfigurable.getHelpTopic() != null); + } + } + + /** + * @return false if failed + */ + protected boolean apply() { + if (mySelectedConfigurable == null || !mySelectedConfigurable.isModified()) { + return true; + } + + try { + mySelectedConfigurable.apply(); + return true; + } + catch (ConfigurationException e) { + Messages.showMessageDialog(e.getMessage(), e.getTitle(), Messages.getErrorIcon()); + return false; + } + } + + protected final void dispose() { + rememberLastUsedPage(); + + for (int i = 0; i < myGroups.length; i++) { + Configurable[] configurables = myGroups[i].getConfigurables(); + for (int j = 0; j < configurables.length; j++) { + Configurable configurable = configurables[j]; + configurable.disposeUIResources(); + } + } + myInitializedConfigurables2Component.clear(); + super.dispose(); + } + + public JComponent getPreferredFocusedComponent() { + return myComponentPanel; + } + + protected final JComponent createCenterPanel() { + myComponentPanel = new JPanel(new BorderLayout()); + + // myOptionPanel contains all configurables. When it updates its UI we also need to update + // UIs of all created but not currently visible configurables. + + myOptionsPanel = new JPanel(new BorderLayout()) { + public void updateUI() { + super.updateUI(); + for (Iterator i = myInitializedConfigurables2Component.keySet().iterator(); i.hasNext();) { + Configurable configurable = i.next(); + if (configurable.equals(mySelectedConfigurable)) { // don't update visible component (optimization) + continue; + } + JComponent component = myInitializedConfigurables2Component.get(configurable); + SwingUtilities.updateComponentTreeUI(component); + } + } + }; + + JPanel compoundToolbarPanel = new JPanel(new BorderLayout()); + + myGroupTabs = new TabbedPaneWrapper(); + myGroupTabs.installKeyboardNavigation(); + + for (int i = 0; i < myGroups.length; i++) { + final ConfigurableGroup group = myGroups[i]; + JComponent toolbar = createGroupToolbar(group, i == 0 ? '1' : 'A'); + myGroupTabs.addTab(group.getShortName(), toolbar); + } + myGroupTabs.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + int selectedIndex = myGroupTabs.getSelectedIndex(); + if (selectedIndex >= 0) { + selectGroup(selectedIndex); + } + } + }); + + compoundToolbarPanel.add(myGroupTabs.getComponent(), BorderLayout.CENTER); + + myComponentPanel.setBorder(BorderFactory.createRaisedBevelBorder()); + myComponentPanel.add(compoundToolbarPanel, BorderLayout.WEST); + + myOptionsPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 2, 5)); + myComponentPanel.add(myOptionsPanel, BorderLayout.CENTER); + + myOptionsPanel.setPreferredSize(myPreferredSize); + + myComponentPanel.setFocusable(true); + myComponentPanel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + Configurable[] configurables = mySelectedGroup.getConfigurables(); + int index = myKeySelectedConfigurableIndex; + if (index == -1) return; + int keyCode = e.getKeyCode(); + if (keyCode == KeyEvent.VK_UP) { + index--; + } + else if (keyCode == KeyEvent.VK_DOWN) { + index++; + } + else { + Configurable configurableFromMnemonic = ControlPanelMnemonicsUtil.getConfigurableFromMnemonic(e, myGroups); + if (configurableFromMnemonic == null) return; + int keyGroupIndex = -1; + ConfigurableGroup keyGroup = null; + int keyIndexInGroup = 0; + for (int i = 0; i < myGroups.length; i++) { + ConfigurableGroup group = myGroups[i]; + int ingroupIdx = ArrayUtil.find(group.getConfigurables(), configurableFromMnemonic); + if (ingroupIdx != -1) { + keyGroupIndex = i; + keyGroup = group; + keyIndexInGroup = ingroupIdx; + break; + } + } + if (mySelectedGroup != keyGroup) { + selectGroup(keyGroupIndex, keyIndexInGroup); + return; + } + index = ControlPanelMnemonicsUtil.getIndexFromKeycode(keyCode, mySelectedGroup == myGroups[0]); + } + if (index == -1 || index == configurables.length) return; + selectConfigurableLater(configurables[index], index); + } + }); + return myComponentPanel; + } + + + private void requestFocusForMainPanel() { + myComponentPanel.requestFocus(); + } + + private JComponent createGroupToolbar(ConfigurableGroup group, char mnemonicStartChar) { + final Configurable[] configurables = group.getConfigurables(); + DefaultActionGroup actionGroup = new DefaultActionGroup(); + for (int i = 0; i < configurables.length; i++) { + Configurable configurable = configurables[i]; + actionGroup.add(new MySelectConfigurableAction(configurable, i, (char)(mnemonicStartChar + i))); + } + + final ActionToolbarEx toolbar = (ActionToolbarEx)ActionManager.getInstance().createActionToolbar( + ActionPlaces.UNKNOWN, + actionGroup, + false); + + toolbar.adjustTheSameSize(true); + + toolbar.setButtonLook(new LeftAlignedIconButtonLook()); + + JPanel toolbarPanel = new JPanel(new BorderLayout(2, 0)); + toolbarPanel.add(toolbar.getComponent(), BorderLayout.CENTER); + + JScrollPane scrollPane = new JScrollPane(toolbarPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) { + public Dimension getPreferredSize() { + return new Dimension( + toolbar.getComponent().getPreferredSize().width + getVerticalScrollBar().getPreferredSize().width + 5, 5); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + }; + scrollPane.getVerticalScrollBar().setUnitIncrement(toolbar.getMaxButtonHeight()); + return scrollPane; + } + + private final Alarm myAlarm = new Alarm(); + private void selectConfigurableLater(final Configurable configurable, final int index) { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + public void run() { + selectConfigurable(configurable, index); + } + }, 400); + myKeySelectedConfigurable = configurable; + myKeySelectedConfigurableIndex = index; + + myComponentPanel.repaint(); + } + + /** + * Selects configurable with specified class. If there is no configurable of class + * then the method does nothing. + */ + private void selectConfigurable(Configurable configurable, int index) { + // If nothing to be selected then clear panel with configurable's options. + if (configurable == null) { + mySelectedConfigurable = null; + myKeySelectedConfigurableIndex = 0; + myKeySelectedConfigurable = null; + updateTitle(); + myOptionsPanel.removeAll(); + validate(); + repaint(); + return; + } + + // Save changes if any + Dimension currentOptionsSize = myOptionsPanel.getSize(); + + if (mySelectedConfigurable != null && mySelectedConfigurable.isModified()) { + int exitCode = Messages.showYesNoDialog("The page has been modified. Save changes made on this page?", + "Save Changes", + Messages.getQuestionIcon()); + if (exitCode == 0) { + try { + mySelectedConfigurable.apply(); + } + catch (ConfigurationException exc) { + Messages.showMessageDialog(exc.getMessage(), exc.getTitle(), Messages.getErrorIcon()); + return; + } + } + } + + if (mySelectedConfigurable != null) { + Dimension savedPrefferedSize = myConfigurable2PrefSize.get(mySelectedConfigurable); + if (savedPrefferedSize != null) { + myConfigurable2PrefSize.put(mySelectedConfigurable, new Dimension(currentOptionsSize)); + } + } + + // Show new configurable + myComponentPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + myOptionsPanel.removeAll(); + + mySelectedConfigurable = configurable; + myKeySelectedConfigurable = configurable; + myKeySelectedConfigurableIndex = index; + JComponent component = myInitializedConfigurables2Component.get(configurable); + if (component == null) { + component = configurable.createComponent(); + myInitializedConfigurables2Component.put(configurable, component); + } + + Dimension compPrefSize; + if (myConfigurable2PrefSize.containsKey(configurable)) { + compPrefSize = myConfigurable2PrefSize.get(configurable); + } + else { + compPrefSize = component.getPreferredSize(); + myConfigurable2PrefSize.put(configurable, compPrefSize); + } + int widthDelta = Math.max(compPrefSize.width - currentOptionsSize.width, 0); + int heightDelta = Math.max(compPrefSize.height - currentOptionsSize.height, 0); + myOptionsPanel.add(component, BorderLayout.CENTER); + if (widthDelta > 0 || heightDelta > 0) { + setSize(getSize().width + widthDelta, getSize().height + heightDelta); + centerRelativeToParent(); + } + + configurable.reset(); + + updateTitle(); + validate(); + repaint(); + + requestFocusForMainPanel(); + myComponentPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + protected final Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), new ApplyAction(), getHelpAction()}; + } + + protected JButton createJButtonForAction(Action action) { + JButton button = super.createJButtonForAction(action); + if (action == getHelpAction()) { + myHelpButton = button; + } + return button; + } + + protected Action[] createLeftSideActions() { + return new Action[]{new SwitchToDefaultViewAction()}; + } + + protected final void doOKAction() { + boolean ok = apply(); + if (ok) { + super.doOKAction(); + } + } + + protected final void doHelpAction() { + if (mySelectedConfigurable != null) { + String helpTopic = mySelectedConfigurable.getHelpTopic(); + if (helpTopic != null) { + HelpManager.getInstance().invokeHelp(helpTopic); + } + } + } + + private final class ApplyAction extends AbstractAction { + private Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + public ApplyAction() { + super("A&pply"); + final Runnable updateRequest = new Runnable() { + public void run() { + if (!ExplorerSettingsEditor.this.isShowing()) return; + ApplyAction.this.setEnabled(mySelectedConfigurable != null && mySelectedConfigurable.isModified()); + addUpdateRequest(this); + } + }; + + addUpdateRequest(updateRequest); + } + + private void addUpdateRequest(final Runnable updateRequest) { + myUpdateAlarm.addRequest(updateRequest, 500, ModalityState.stateForComponent(getWindow())); + } + + public void actionPerformed(ActionEvent e) { + if (apply()) { + setCancelButtonText("Close"); + } + } + } + + private final class MySelectConfigurableAction extends ToggleAction { + private final Configurable myConfigurable; + private final int myIndex; + + private MySelectConfigurableAction(Configurable configurable, int index, char mnemonic) { + myConfigurable = configurable; + myIndex = index; + Presentation presentation = getTemplatePresentation(); + String displayName = myConfigurable.getDisplayName(); + Icon icon = myConfigurable.getIcon(); + if (icon == null) { + icon = IconLoader.getIcon("/general/configurableDefault.png"); + } + Icon labeledIcon = new HorizontalLabeledIcon(icon, displayName, " ("+mnemonic+")"); + presentation.setIcon(labeledIcon); + presentation.setText(null); + } + + public boolean isSelected(AnActionEvent e) { + return myConfigurable.equals(myKeySelectedConfigurable); + } + + public void setSelected(AnActionEvent e, boolean state) { + if (state) { + selectConfigurableLater(myConfigurable, myIndex); + } + } + } + + private class SwitchToDefaultViewAction extends AbstractAction { + public SwitchToDefaultViewAction() { + putValue(Action.NAME, "Default &View"); + } + + public void actionPerformed(ActionEvent e) { + switchToDefaultView(null); + } + } + private void switchToDefaultView(final Configurable preselectedConfigurable) { + close(OK_EXIT_CODE); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ((ShowSettingsUtilImpl)ShowSettingsUtil.getInstance()).showControlPanelOptions(myProject, myGroups, preselectedConfigurable); + } + }, ModalityState.NON_MMODAL); + } + + private static class LeftAlignedIconButtonLook extends ActionButtonLook { + private ActionButtonLook myDelegate = ActionButtonLook.IDEA_LOOK; + + public void paintIconAt(Graphics g, ActionButtonComponent button, Icon icon, int x, int y) { + myDelegate.paintIconAt(g, button, icon, x, y); + } + + public void paintBorder(Graphics g, JComponent component, int state) { + myDelegate.paintBorder(g, component, state); + } + + public void paintIcon(Graphics g, ActionButtonComponent actionButton, Icon icon) { + int height = icon.getIconHeight(); + int x = 2; + int y = (int)Math.ceil((actionButton.getHeight() - height) / 2); + paintIconAt(g, actionButton, icon, x, y); + } + + public void paintBackground(Graphics g, JComponent component, int state) { + myDelegate.paintBackground(g, component, state); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java new file mode 100644 index 00000000000..9e5ae883e70 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java @@ -0,0 +1,34 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Dec 9, 2003 + * Time: 3:35:56 PM + * To change this template use Options | File Templates. + */ +public class IdeConfigurablesGroup implements ConfigurableGroup { + public String getDisplayName() { + return "IDE Settings"; + } + + public String getShortName() { + return "IDE"; + } + + public Configurable[] getConfigurables() { + return ApplicationManager.getApplication().getComponents(Configurable.class); + } + + public boolean equals(Object object) { + return object instanceof IdeConfigurablesGroup; + } + + public int hashCode() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurableWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurableWrapper.java new file mode 100644 index 00000000000..00f825dc422 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurableWrapper.java @@ -0,0 +1,74 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.io.File; + +/** + * @author max + */ +public class ProjectConfigurableWrapper implements Configurable { + private Project myProject; + private Configurable myDelegate; + + public ProjectConfigurableWrapper(Project project, Configurable delegate) { + myProject = project; + myDelegate = delegate; + } + + public String getDisplayName() { + return myDelegate.getDisplayName(); + } + + public void reset() { + myDelegate.reset(); + } + + public void apply() throws ConfigurationException { + checkProjectFileWritable(); + myDelegate.apply(); + } + + private void checkProjectFileWritable() { + final VirtualFile projectFile = myProject.getProjectFile(); + if (projectFile != null) { + String path = projectFile.getPresentableUrl(); + if (path != null) { + File file = new File(path); + if (file.exists() && !file.canWrite()) { + Messages.showMessageDialog( + myProject, + "The project file is read-only.\nThe settings will not be saved until you make the file writable.", + "Cannot Save Settings", + Messages.getErrorIcon() + ); + } + } + } + } + + public String getHelpTopic() { + return myDelegate.getHelpTopic(); + } + + public void disposeUIResources() { + myDelegate.disposeUIResources(); + } + + public boolean isModified() { + return myDelegate.isModified(); + } + + public JComponent createComponent() { + return myDelegate.createComponent(); + } + + public Icon getIcon() { + return myDelegate.getIcon(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java new file mode 100644 index 00000000000..d8f086c8b9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java @@ -0,0 +1,51 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurable; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author max + */ +public class ProjectConfigurablesGroup implements ConfigurableGroup { + private Project myProject; + + public ProjectConfigurablesGroup(Project project) { + myProject = project; + } + + public String getDisplayName() { + if (isDefault()) return "Template Project Settings"; + VirtualFile projectFile = myProject.getProjectFile(); + return "Project Settings [" + (projectFile != null ? projectFile.getNameWithoutExtension() : "unknown") + "]"; + } + + public String getShortName() { + return isDefault() ? "Template Project" : "Project"; + } + + private boolean isDefault() { + return myProject.isDefault(); + } + + public Configurable[] getConfigurables() { + Configurable[] components = myProject.getComponents(Configurable.class); + Configurable[] configurables = new Configurable[components.length - (isDefault() ? 1 : 0)]; + int j = 0; + for (int i = 0; i < components.length; i++) { + if (components[i] instanceof ModulesConfigurable && isDefault()) continue; + configurables[j++] = components[i]; + } + return configurables; + } + + public int hashCode() { + return 0; + } + + public boolean equals(Object object) { + return object instanceof ProjectConfigurablesGroup && ((ProjectConfigurablesGroup)object).myProject == myProject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/SingleConfigurableEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/SingleConfigurableEditor.java new file mode 100644 index 00000000000..af58b75f2d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/options/ex/SingleConfigurableEditor.java @@ -0,0 +1,165 @@ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +public class SingleConfigurableEditor extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.ex.SingleConfigurableEditor"); + private Project myProject; + private Component myParentComponent; + protected Configurable myConfigurable; + private JComponent myCenterPanel; + private String myDimensionKey; + + public SingleConfigurableEditor(Project project, Configurable configurable, String dimensionKey) { + super(project, true); + myDimensionKey = dimensionKey; + setTitle(createTitleString(configurable)); + + myProject = project; + myConfigurable = configurable; + init(); + myConfigurable.reset(); + } + + public Configurable getConfigurable() { + return myConfigurable; + } + + public Project getProject() { + return myProject; + } + + public SingleConfigurableEditor(Project project, Configurable configurable) { + this(project, configurable, null); + } + + public SingleConfigurableEditor(Component parent, Configurable configurable) { + this(parent, configurable, null); + } + + private String createTitleString(Configurable configurable) { + String displayName = configurable.getDisplayName(); + LOG.assertTrue(displayName != null, configurable.getClass().getName()); + return displayName.replaceAll("\n", " "); + } + + public SingleConfigurableEditor(Component parent, Configurable configurable, String dimensionServiceKey) { + super(parent, true); + myDimensionKey = dimensionServiceKey; + setTitle(createTitleString(configurable)); + + myParentComponent = parent; + myConfigurable = configurable; + init(); + myConfigurable.reset(); + } + + protected String getDimensionServiceKey() { + if (myDimensionKey == null) { + return super.getDimensionServiceKey(); + } + else { + return myDimensionKey; + } + } + + protected Action[] createActions() { + if (myConfigurable.getHelpTopic() != null) { + return new Action[]{getOKAction(), getCancelAction(), new ApplyAction(), getHelpAction()}; + } + else { + return new Action[]{getOKAction(), getCancelAction(), new ApplyAction()}; + } + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myConfigurable.getHelpTopic()); + } + + protected void doOKAction() { + try { + if (myConfigurable.isModified()) myConfigurable.apply(); + } + catch (ConfigurationException e) { + if (myProject != null) { + Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon()); + } + else { + Messages.showMessageDialog(myParentComponent, e.getMessage(), e.getTitle(), Messages.getErrorIcon()); + } + return; + } + super.doOKAction(); + } + + protected class ApplyAction extends AbstractAction { + private Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + public ApplyAction() { + super("&Apply"); + final Runnable updateRequest = new Runnable() { + public void run() { + if (!SingleConfigurableEditor.this.isShowing()) return; + ApplyAction.this.setEnabled(myConfigurable != null && myConfigurable.isModified()); + addUpdateRequest(this); + } + }; + + addUpdateRequest(updateRequest); + } + + private void addUpdateRequest(final Runnable updateRequest) { + myUpdateAlarm.addRequest(updateRequest, 500, ModalityState.stateForComponent(getWindow())); + } + + public void actionPerformed(ActionEvent event) { + try { + if (myConfigurable.isModified()) { + myConfigurable.apply(); + setCancelButtonText("Close"); + } + } + catch (ConfigurationException e) { + if (myProject != null) { + Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon()); + } + else { + Messages.showMessageDialog(myParentComponent, e.getMessage(), e.getTitle(), + Messages.getErrorIcon()); + } + } + } + } + + protected JComponent createCenterPanel() { + myCenterPanel = myConfigurable.createComponent(); + return myCenterPanel; + } + + public JComponent getPreferredFocusedComponent() { + if (myConfigurable instanceof BaseConfigurable) { + JComponent preferred = ((BaseConfigurable)myConfigurable).getPreferredFocusedComponent(); + if (preferred != null) return preferred; + } + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCenterPanel); + } + + protected void dispose() { + super.dispose(); + myConfigurable.disposeUIResources(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/impl/ProgressManagerImpl.java new file mode 100644 index 00000000000..fac5d73d478 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -0,0 +1,166 @@ +package com.intellij.openapi.progress.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressFunComponentProvider; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.progress.util.SmoothProgressAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiLock; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ProgressManagerImpl extends ProgressManager implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.ProgressManager"); + + private HashMap myThreadToIndicatorMap = new HashMap(); + + private static volatile boolean ourNeedToCheckCancel = false; + private List myFunComponentProviders = new ArrayList(); + + public ProgressManagerImpl(Application application) { + if (!application.isUnitTestMode()) { + new Thread() { + public void run() { + while (true) { + try { + sleep(10); + } + catch (InterruptedException e) { + } + ourNeedToCheckCancel = true; + } + } + }.start(); + } + } + + public void checkCanceled() { + // Q: how about 2 cancelable progresses in time?? + if (ourNeedToCheckCancel) { // smart optimization! + ourNeedToCheckCancel = false; + final ProgressIndicator progress = getInstance().getProgressIndicator(); + if (progress != null) { + try { + progress.checkCanceled(); + } + catch (ProcessCanceledException e) { + if (!Thread.holdsLock(PsiLock.LOCK)) { + progress.checkCanceled(); + } + } + } + } + } + + public JComponent getProvidedFunComponent(Project project, String processId) { + for (int i = 0; i < myFunComponentProviders.size(); i++) { + ProgressFunComponentProvider provider = myFunComponentProviders.get(i); + JComponent cmp = provider.getProgressFunComponent(project, processId); + if (cmp != null) return cmp; + } + return null; + } + + public void setCancelButtonText(String cancelButtonText) { + ProgressIndicator progressIndicator = getProgressIndicator(); + if (progressIndicator != null) { + if ((progressIndicator instanceof SmoothProgressAdapter) && (cancelButtonText != null)) { + ProgressIndicator original = ((SmoothProgressAdapter)progressIndicator).getOriginal(); + if (original instanceof ProgressWindow) { + ((ProgressWindow)original).setCancelButtonText(cancelButtonText); + } + } + } + + } + + public void registerFunComponentProvider(ProgressFunComponentProvider provider) { + myFunComponentProviders.add(provider); + } + + public void removeFunComponentProvider(ProgressFunComponentProvider provider) { + myFunComponentProviders.remove(provider); + } + + public String getComponentName() { + return "ProgressManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public boolean hasProgressIndicator() { + synchronized (this) { + return myThreadToIndicatorMap.size() != 0; + } + } + + public boolean hasModalProgressIndicator() { + synchronized (this) { + for (Iterator i = myThreadToIndicatorMap.values().iterator(); i.hasNext();) { + ProgressIndicator indicator = i.next(); + if (indicator.isModal()) { + return true; + } + } + return false; + } + } + + public void runProcess(Runnable process, ProgressIndicator progress) throws ProcessCanceledException { + LOG.assertTrue(process != null); + + Thread currentThread = Thread.currentThread(); + + ProgressIndicator oldIndicator; + synchronized (this) { + oldIndicator = myThreadToIndicatorMap.get(currentThread); + if (progress != null) { + myThreadToIndicatorMap.put(currentThread, progress); + } + else{ + myThreadToIndicatorMap.remove(currentThread); + } + } + synchronized (process) { + process.notify(); + } + try { + if (progress != null && !progress.isRunning()) { + progress.start(); + } + process.run(); + } + finally { + if (progress != null && progress.isRunning()) { + progress.stop(); + } + synchronized (this) { + if (oldIndicator != null) { + myThreadToIndicatorMap.put(currentThread, oldIndicator); + } + else { + myThreadToIndicatorMap.remove(currentThread); + } + } + } + } + + public ProgressIndicator getProgressIndicator() { + synchronized (this) { + return myThreadToIndicatorMap.get(Thread.currentThread()); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/BlockingProgressIndicator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/BlockingProgressIndicator.java new file mode 100644 index 00000000000..d4957696b3c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/BlockingProgressIndicator.java @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.progress.util; + +public abstract class BlockingProgressIndicator extends ProgressIndicatorBase { + public abstract void startBlocking(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ColorProgressBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ColorProgressBar.java new file mode 100644 index 00000000000..0d448ba3c42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ColorProgressBar.java @@ -0,0 +1,220 @@ +package com.intellij.openapi.progress.util; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.Rectangle2D; + +/** + * @author Eugene Belyaev + */ +public class ColorProgressBar extends JComponent { + private static final Dimension PREFERRED_SIZE = new Dimension(146, 17); + + public static final Color GREEN = new Color(47, 212, 50); + public static final Color RED = new Color(210, 69, 30); + public static final Color BLUE = new Color(1, 68, 208); + public static final Color YELLOW = new Color(212, 183, 33); + + private static final Color SHADOW1 = new Color(190, 190, 188); + private static final Color SHADOW2 = new Color(105, 103, 106); + + private static final int BRICK_WIDTH = 6; + private static final int BRICK_SPACE = 1; + + private static final int INDETERMINATE_BRICKS_DRAW = 5; + private static final double INDETERMINATE_INC_OFFSET = 0.02; + + private double myFraction = 0.0; + private Color myColor = BLUE; + + private double myIndeterminateInc = INDETERMINATE_INC_OFFSET; + private boolean myIndeterminate = false; + + public boolean isIndeterminate() { + return myIndeterminate; + } + + public void setIndeterminate(boolean indeterminate) { + this.myIndeterminate = indeterminate; + } + + public ColorProgressBar() { + updateUI(); + } + + public void setColor(Color color) { + myColor = color; + if (isDisplayable()) repaint(); + } + + public double getFraction() { + return myFraction; + } + + public void setFraction(double fraction) { + if (myIndeterminate) { + if (myFraction >= 1.0) + myIndeterminateInc = -INDETERMINATE_INC_OFFSET; + else if (myFraction <= 0) + myIndeterminateInc = INDETERMINATE_INC_OFFSET; + + boolean changed = myFraction == 0 || + getBricksToDraw(myFraction) != getBricksToDraw(myFraction + myIndeterminateInc); + myFraction += myIndeterminateInc; + + if (changed) + repaint(); + } else { + boolean changed = myFraction == 0 || getBricksToDraw(myFraction) != getBricksToDraw(fraction); + myFraction = fraction; + if (changed) { + repaint(); + } + } + } + + private int getBricksToDraw(double fraction) { + int bricksTotal = (getWidth() - 8) / (BRICK_WIDTH + BRICK_SPACE); + return (int)(bricksTotal * fraction) + 1; + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (myFraction == 0) return; + + Graphics2D g2 = (Graphics2D)g; + Object oldAntialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + if (myFraction > 1) { + myFraction = 1; + } + + Dimension size = getSize(); + + g2.setPaint(Color.WHITE); + Rectangle2D rect = new Rectangle2D.Double(2, 2, size.width - 4, size.height - 4); + g2.fill(rect); + + g2.setPaint(SHADOW1); + rect.setRect(1, 1, size.width - 3, size.height - 3); + g2.draw(rect); + g2.drawLine(2, 2, 2, 2); + g2.drawLine(2, size.height - 2, 2, size.height - 2); + g2.drawLine(size.width - 2, 2, size.width - 2, 2); + g2.drawLine(0, 2, 0, 2); + g2.drawLine(2, 0, 2, 0); + + g2.setPaint(SHADOW2); + g2.drawLine(0, 2, 0, size.height - 4); + g2.drawLine(1, 1, 1, 1); + g2.drawLine(2, 0, size.width - 3, 0); + g2.drawLine(1, size.height - 3, 1, size.height - 3); + g2.drawLine(2, size.height - 2, size.width - 3, size.height - 2); + g2.drawLine(size.width - 2, 1, size.width - 2, 1); + g2.drawLine(size.width - 1, 2, size.width - 1, size.height - 4); + g2.drawLine(size.width - 2, size.height - 3, size.width - 2, size.height - 3); + + int y_center = size.height / 2; + int y_steps = size.height / 2 - 3; + int alpha_step = y_steps > 0 ? (255 - 70) / y_steps : 255 - 70; + int x_offset = 4; + + g.setClip(4, 3, size.width - 8, size.height - 6); + + int bricksToDraw = getBricksToDraw(myFraction); + + if (myIndeterminate) { + + int startFrom = bricksToDraw < INDETERMINATE_BRICKS_DRAW ? 0 : bricksToDraw - INDETERMINATE_BRICKS_DRAW; + int endTo = bricksToDraw + INDETERMINATE_BRICKS_DRAW < getBricksToDraw(1) ? bricksToDraw + INDETERMINATE_BRICKS_DRAW : getBricksToDraw(1); + + for (int i = startFrom; i <= endTo; i++) { + g2.setPaint(myColor); + + int startXOffset = x_offset + (BRICK_WIDTH + BRICK_SPACE) * i; + g2.drawLine(startXOffset, y_center, startXOffset + BRICK_WIDTH - 1, y_center); + + for (int j = 0; j < y_steps; j++) { + Color color = new Color(myColor.getRed(), myColor.getGreen(), myColor.getBlue(), 255 - alpha_step * (j + 1)); + g2.setPaint(color); + g2.drawLine(startXOffset, y_center - 1 - j, startXOffset + BRICK_WIDTH - 1, y_center - 1 - j); + + if (!(y_center % 2 != 0 && j == y_steps - 1)) { + g2.drawLine(startXOffset, y_center + 1 + j, startXOffset + BRICK_WIDTH - 1, y_center + 1 + j); + } + } + g2.setColor( + new Color(myColor.getRed(), myColor.getGreen(), myColor.getBlue(), 255 - alpha_step * (y_steps / 2 + 1))); + g2.drawRect(startXOffset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7); + } + + } else { + for (int i = 0; i < bricksToDraw; i++) { + g2.setPaint(myColor); + g2.drawLine(x_offset, y_center, x_offset + BRICK_WIDTH - 1, y_center); + for (int j = 0; j < y_steps; j++) { + Color color = new Color(myColor.getRed(), myColor.getGreen(), myColor.getBlue(), 255 - alpha_step * (j + 1)); + g2.setPaint(color); + g2.drawLine(x_offset, y_center - 1 - j, x_offset + BRICK_WIDTH - 1, y_center - 1 - j); + if (!(y_center % 2 != 0 && j == y_steps - 1)) { + g2.drawLine(x_offset, y_center + 1 + j, x_offset + BRICK_WIDTH - 1, y_center + 1 + j); + } + } + g2.setColor( + new Color(myColor.getRed(), myColor.getGreen(), myColor.getBlue(), 255 - alpha_step * (y_steps / 2 + 1))); + g2.drawRect(x_offset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7); + x_offset += BRICK_WIDTH + BRICK_SPACE; + } + } + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialiasing); + } + + public Dimension getPreferredSize() { + return PREFERRED_SIZE; + } + + public Dimension getMaximumSize() { + Dimension dimension = getPreferredSize(); + dimension.width = Short.MAX_VALUE; + return dimension; + } + + public Dimension getMinimumSize() { + Dimension dimension = getPreferredSize(); + dimension.width = 13; + return dimension; + } + + public static void main(String[] args) { + JFrame frame = new JFrame("ColorProgressBar Test"); + frame.addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + } + ); + frame.setSize(800, 600); + frame.setLocation(0, 0); + Container contentPane = frame.getContentPane(); + contentPane.setLayout(new BorderLayout()); + final ColorProgressBar colorProgressBar = new ColorProgressBar(); + colorProgressBar.setFraction(0.5); + colorProgressBar.setIndeterminate(true); + contentPane.add(colorProgressBar, BorderLayout.NORTH); + frame.setVisible(true); + JButton b = new JButton ("X"); + b.addActionListener(new ActionListener () { + public void actionPerformed(ActionEvent e) { + colorProgressBar.setFraction(1); + } + }); + contentPane.add(b, BorderLayout.SOUTH); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/CommandLineProgress.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/CommandLineProgress.java new file mode 100644 index 00000000000..603333dcb71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/CommandLineProgress.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.progress.util; + + +public class CommandLineProgress extends ProgressIndicatorBase{ + public void setText(String text) { + if (getText().equals(text)) return; + super.setText(text); + System.out.println(getTextToPrint()); + } + + public void setFraction(double fraction) { + String oldText = getTextToPrint(); + super.setFraction(fraction); + String newText = getTextToPrint(); + if (!newText.equals(oldText)){ + System.out.println(newText); + } + } + + private String getTextToPrint(){ + if (getFraction() > 0){ + return getText() + " " + (int)(getFraction() * 100 + 0.5) + "%"; + } + else{ + return getText(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/DispatchThreadProgressWindow.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/DispatchThreadProgressWindow.java new file mode 100644 index 00000000000..ce4e0c9b9c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/DispatchThreadProgressWindow.java @@ -0,0 +1,53 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.ide.IdeEventQueue; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; + +import java.awt.*; + +public class DispatchThreadProgressWindow extends ProgressWindow{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.DispatchThreadProgressWindow"); + + private long myLastPumpEventsTime = 0; + private static final int PUMP_INTERVAL = SystemInfo.isWindows ? 100 : 500; + + public DispatchThreadProgressWindow(boolean shouldShowCancel, Project project) { + super(shouldShowCancel, project); + } + + public void setText(String text) { + super.setText(text); + pumpEvents(); + } + + public void setFraction(double fraction) { + super.setFraction(fraction); + pumpEvents(); + } + + public void setText2(String text) { + super.setText2(text); + pumpEvents(); + } + + private void pumpEvents() { + long time = System.currentTimeMillis(); + if (time - myLastPumpEventsTime < PUMP_INTERVAL) return; + myLastPumpEventsTime = time; + + IdeEventQueue eventQueue = IdeEventQueue.getInstance(); + while(true){ + AWTEvent event = eventQueue.peekEvent(); + if (event == null) return; + try{ + AWTEvent event1 = eventQueue.getNextEvent(); + eventQueue.dispatchEvent(event1); + } + catch(Exception e){ + LOG.error(e); //? + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/MaxIntervalCalculator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/MaxIntervalCalculator.java new file mode 100644 index 00000000000..4d2190dfe26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/MaxIntervalCalculator.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.progress.util; + +public class MaxIntervalCalculator { + private static long myLastTimeChecked; + private static long myMaxInterval; + private static int myTouchCount; + private static long myStartTime; + + public static void touch(){ + /* + long time = System.currentTimeMillis(); + long interval = time - myLastTimeChecked; + if (interval > myMaxInterval){ + myMaxInterval = interval; + } + myLastTimeChecked = time; + myTouchCount++; + */ + } + + public static void startCalc(){ + /* + myLastTimeChecked = myStartTime = System.currentTimeMillis(); + myMaxInterval = -1; + myTouchCount = 0; + */ + } + + public static void endCalc(){ + /* + long time = System.currentTimeMillis(); + long totalTime = time - myStartTime; + double avgInterval = totalTime / (double)myTouchCount; + System.out.println("max interval = " + myMaxInterval); + System.out.println("total time = " + totalTime); + System.out.println("average interval = " + avgInterval); + */ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressBar.java new file mode 100644 index 00000000000..dfc9c3d5e24 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressBar.java @@ -0,0 +1,59 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; + +public class ProgressBar extends JComponent { + private double myFraction = 0.0; + + private Icon myProgressIcon = IconLoader.getIcon("/general/progress.png"); + + public ProgressBar() { + updateUI(); + } + + public void setProgressIcon(Icon progressIcon){ + if (progressIcon == null) { + throw new IllegalArgumentException("progressIcon cannot be null"); + } + myProgressIcon = progressIcon; + repaint(); + } + + public double getFraction() { + return myFraction; + } + + public void setFraction(double fraction) { + myFraction = fraction; + repaint(); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (myFraction == 0 || myProgressIcon == null){ + return; + } + if (myFraction > 1){ + myFraction = 1; + } + int bricksTotal = (getWidth() - 4) / (myProgressIcon.getIconWidth() + 2); + int bricksToDraw = (int)(bricksTotal * myFraction + 0.5); + + int rWidth = (myProgressIcon.getIconWidth() + 2) * bricksTotal + 1; + int rHeight = myProgressIcon.getIconHeight() + 3; + + g.drawRoundRect(0, (getHeight() - rHeight)/2 , rWidth, rHeight, 2, 2 ); + int offset = 2; + for (int i=0; i myTextStack = new ArrayList(); + private DoubleArrayList myFractionStack = new DoubleArrayList(); + private ArrayList myText2Stack = new ArrayList(); + private volatile int myNonCancelableCount = 0; + + private ProgressIndicator myModalityProgress = null; + private ModalityState myModalityState = ModalityState.NON_MMODAL; + + public void start(){ + LOG.assertTrue(!isRunning()); + synchronized(this){ + myText = ""; + myFraction = 0; + myText2 = ""; + myCanceled = false; + myRunning = true; + } + + if (myModalityProgress == this){ + if (!EventQueue.isDispatchThread()){ + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + LaterInvocatorEx.enterModal(ProgressIndicatorBase.this); + } + } + ); + } + else{ + LaterInvocatorEx.enterModal(this); + } + } + } + + public void stop(){ + LOG.assertTrue(myRunning, "stop() should be called only if start() called before"); + myRunning = false; + + if (myModalityProgress == this){ + if (!EventQueue.isDispatchThread()){ + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + LaterInvocatorEx.leaveModal(ProgressIndicatorBase.this); + } + } + ); + } + else{ + LaterInvocatorEx.leaveModal(this); + } + } + } + + public boolean isRunning() { + return myRunning; + } + + public void cancel(){ + myCanceled = true; + } + + public boolean isCanceled(){ + return myCanceled; + } + + public final void checkCanceled(){ + if (isCanceled() && myNonCancelableCount == 0) { + throw new ProcessCanceledException(); + } + } + + public void setText(String text){ + myText = text; + } + + public String getText(){ + return myText; + } + + public void setText2(String text){ + myText2 = text; + } + + public String getText2(){ + return myText2; + } + + public double getFraction() { + return myFraction; + } + + public void setFraction(double fraction) { + myFraction = fraction; + } + + public void pushState(){ + synchronized(this){ + myTextStack.add(myText); + myFractionStack.add(myFraction); + myText2Stack.add(myText2); + setText(""); + setFraction(0); + setText2(""); + } + } + + public void popState(){ + synchronized(this){ + LOG.assertTrue(myTextStack.size() > 0); + setText(myTextStack.remove(myTextStack.size() - 1)); + setFraction(myFractionStack.remove(myFractionStack.size() - 1)); + setText2(myText2Stack.remove(myText2Stack.size() - 1)); + } + } + + public void startNonCancelableSection(){ + myNonCancelableCount++; + } + + public void finishNonCancelableSection(){ + myNonCancelableCount--; + } + + public final boolean isModal(){ + return myModalityProgress != null; + } + + public final ModalityState getModalityState() { + return myModalityState; + } + + public void setModalityProgress(ProgressIndicator modalityProgress) { + LOG.assertTrue(!isRunning()); + myModalityProgress = modalityProgress; + ModalityState currentModality = ApplicationManager.getApplication().getCurrentModalityState(); + myModalityState = myModalityProgress != null ? ((ModalityStateEx)currentModality).appendProgress(myModalityProgress) : currentModality; + } + + public boolean isIndeterminate() { + return myIndeterminate; + } + + public void setIndeterminate(boolean indeterminate) { + myIndeterminate = indeterminate; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListener.java new file mode 100644 index 00000000000..2a284c4d9ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListener.java @@ -0,0 +1,14 @@ +package com.intellij.openapi.progress.util; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 19, 2004 + * Time: 5:15:09 PM + * To change this template use File | Settings | File Templates. + */ +public interface ProgressIndicatorListener { + public void cancelled(); + + public void stopped(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListenerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListenerAdapter.java new file mode 100644 index 00000000000..e143867704e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressIndicatorListenerAdapter.java @@ -0,0 +1,18 @@ +package com.intellij.openapi.progress.util; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 19, 2004 + * Time: 5:23:48 PM + * To change this template use File | Settings | File Templates. + */ +public class ProgressIndicatorListenerAdapter implements ProgressIndicatorListener{ + //should return whether to stop processing + public void cancelled() { + } + + //should return whether to stop processing + public void stopped() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressStream.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressStream.java new file mode 100644 index 00000000000..0b15c632ed4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressStream.java @@ -0,0 +1,46 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.progress.ProgressIndicator; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Oct 9, 2003 + * Time: 2:20:15 AM + * To change this template use Options | File Templates. + */ +public class ProgressStream extends InputStream { + private InputStream myInputStream; + private ProgressIndicator myProgressIndicator; + private long available; + private long count; + + public ProgressStream(InputStream inputStream, ProgressIndicator progressIndicator) { + this (0, 0, inputStream, progressIndicator); + } + + public ProgressStream(long start, long available, InputStream inputStream, ProgressIndicator progressIndicator) { + count = start; + this.available = available; + myInputStream = inputStream; + myProgressIndicator = progressIndicator; + } + + public int read() throws IOException { + if (myProgressIndicator != null) { + if (myProgressIndicator.isCanceled()) { + throw new RuntimeException (new InterruptedException()); + } + + if (available > 0) { + myProgressIndicator.setFraction((double) count++ / (double) available); + } else { + myProgressIndicator.setFraction((double) 1 - (double) 1 / (double) count++); + } + } + return myInputStream.read(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindow.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindow.java new file mode 100644 index 00000000000..a10af943ed1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindow.java @@ -0,0 +1,375 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.util.Alarm; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ProgressWindow extends BlockingProgressIndicator { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressWindow"); + + private static final int UPDATE_INTERVAL = 50; //msec. 20 frames per second. + + private MyDialog myDialog; + private Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private Alarm myInstallFunAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + private final Project myProject; + private final boolean myShouldShowBackground; + private final boolean myShouldShowCancel; + private String myCancelText; + private JComponent myParentComponent; + + private String myDeferredTitle = null; + + private boolean myStoppedAlready = false; + + public ProgressWindow(boolean shouldShowCancel, Project project) { + this(shouldShowCancel, false, project); + } + + public ProgressWindow(boolean shouldShowCancel, boolean shouldShowBackground, Project project) { + this(shouldShowCancel, shouldShowBackground, project, null); + } + + public ProgressWindow(boolean shouldShowCancel, boolean shouldShowBackground, Project project, String cancelText) { + myShouldShowBackground = shouldShowBackground; + myProject = project; + myShouldShowCancel = shouldShowCancel; + myCancelText = cancelText; + setModalityProgress(myShouldShowBackground ? null : this); + } + + public ProgressWindow(boolean shouldShowCancel, boolean shouldShowBackground, Project project, JComponent parentComponent, String cancelText) { + myShouldShowBackground = shouldShowBackground; + myProject = project; + myShouldShowCancel = shouldShowCancel; + myCancelText = cancelText; + myParentComponent = parentComponent; + setModalityProgress(myShouldShowBackground ? null : this); + } + + public synchronized void start() { + LOG.assertTrue(!isRunning()); + LOG.assertTrue(!myStoppedAlready); + + super.start(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myDialog == null && isRunning()) { + showDialog(); + } + } + }, getModalityState()); + } + + public void startBlocking() { + ApplicationManager.getApplication().assertIsDispatchThread(); + LOG.assertTrue(!isRunning()); + LOG.assertTrue(!myStoppedAlready); + + synchronized(this){ + super.start(); + } + + showDialog(); + } + + private void showDialog() { + //System.out.println("ProgressWindow.showDialog"); + LOG.assertTrue(myDialog == null); + if(myParentComponent != null) { + myDialog = new MyDialog(myShouldShowCancel, myShouldShowBackground, myParentComponent, myCancelText); + } else { + myDialog = new MyDialog(myShouldShowCancel, myShouldShowBackground, myProject, myCancelText); + } + if (myDeferredTitle != null) { + setTitle(myDeferredTitle); + } + + final JComponent cmp = ProgressManager.getInstance().getProvidedFunComponent(myProject, ""); + if (cmp != null) { + Runnable installer = new Runnable() { + public void run() { + if (isRunning() && !isCanceled() && getFraction() < 0.15 && myDialog!=null) { + setFunComponent(cmp); + } + } + }; + myInstallFunAlarm.addRequest(installer, 3000, getModalityState()); + } + + myDialog.setIndeterminate(isIndeterminate()); + myDialog.show(); + } + + public synchronized void stop() { + LOG.assertTrue(!myStoppedAlready); + myInstallFunAlarm.cancelAllRequests(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myDialog != null) { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + }, getModalityState()); + + super.stop(); + myStoppedAlready = true; + } + + public void cancel() { + super.cancel(); + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + if (myDialog != null) { + myDialog.cancel(); + } + } + } + ); + } + + public void background() { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + if (myDialog != null) { + myDialog.background(); + myDialog = null; + } + } + } + ); + } + + public void setText(String text) { + if (!text.equals(getText())) { + super.setText(text); + update(); + } + } + + public void setFraction(double fraction) { + if (fraction != getFraction()) { + super.setFraction(fraction); + update(); + } + } + + public void setText2(String text) { + if (!text.equals(getText2())) { + super.setText2(text); + update(); + } + } + + private void update() { + if (myDialog != null) { + myDialog.update(); + } + } + + public void setTitle(String title) { + if (myDialog == null) { + myDeferredTitle = title; + } + else { + myDialog.setTitle(title); + } + } + + protected static final int getPercentage(double fraction) { + return (int)(fraction * 99 + 0.5); + } + + private class MyDialog extends DialogWrapper { + private long myLastTimeDrawn = -1; + private boolean myShouldShowCancel; + private boolean myShouldShowBackground; + + private Runnable myRepaintRunnable = new Runnable() { + public void run() { + String text = getText(); + double fraction = getFraction(); + String text2 = getText2(); + + myTextLabel.setText(text != null && text.length() > 0 ? text : " "); + if (!isIndeterminate() && fraction > 0) { + myPercentLabel.setText(getPercentage(fraction) + "%"); + } + else { + myPercentLabel.setText(" "); + } + myProgressBar.setFraction(fraction); + myText2Label.setText(text2 != null && text2.length() > 0 ? text2 : " "); + + myLastTimeDrawn = System.currentTimeMillis(); + myRepaintedFlag = true; + } + }; + private final Runnable myUpdateRequest = new Runnable() { + public void run() { + update(); + } + }; + + private JPanel myPanel; + + private JLabel myTextLabel; + private JLabel myPercentLabel; + private JLabel myText2Label; + + private JButton myCancelButton; + private JButton myBackgroundButton; + + private ColorProgressBar myProgressBar; + private boolean myRepaintedFlag = false; + private JPanel myFunPanel; + + public void setIndeterminate (boolean indeterminate) { + myProgressBar.setIndeterminate(indeterminate); + } + + public MyDialog(boolean shouldShowCancel, boolean shouldShowBackground, Project project, String cancelText) { + super(project, false); + + initDialog(shouldShowCancel, shouldShowBackground, cancelText); + + } + + public MyDialog(boolean shouldShowCancel, boolean shouldShowBackground, Component parent, String cancelText) { + super(parent, false); + initDialog(shouldShowCancel, shouldShowBackground, cancelText); + } + + private void initDialog(boolean shouldShowCancel, boolean shouldShowBackground, String cancelText) { + myFunPanel.setLayout(new BorderLayout()); + myCancelButton.setAction(getCancelAction()); + + myShouldShowCancel = shouldShowCancel; + myShouldShowBackground = shouldShowBackground; + if (cancelText != null) { + setCancelButtonText(cancelText); + } + init(); + } + + public void changeCancelButtonText(String text){ + setCancelButtonText(text); + } + + protected boolean isProgressDialog() { + return true; + } + + protected void init() { + setCrossClosesWindow(myShouldShowCancel); + + super.init(); + + myRepaintRunnable.run(); + } + + public void doCancelAction() { + if (myShouldShowCancel) { + ProgressWindow.this.cancel(); + } + } + + public void cancel() { + if (myShouldShowCancel) { + myCancelButton.setEnabled(false); + } + } + + protected Border createContentPaneBorder() { + return null;//new LineBorder(Color.BLACK); + } + + protected JComponent createSouthPanel() { + return null; + } + + protected JComponent createCenterPanel() { + // Cancel button (if any) + + myCancelButton.setVisible(myShouldShowCancel); + + myBackgroundButton.setVisible(myShouldShowBackground); + if (myShouldShowBackground) { + myBackgroundButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + ProgressWindow.this.background(); + } + } + ); + } + + // Panel with progress indicator and percents + + int width = myPercentLabel.getFontMetrics(myPercentLabel.getFont()).stringWidth("1000%"); + myPercentLabel.setPreferredSize(new Dimension(width, myPercentLabel.getPreferredSize().height)); + myPercentLabel.setHorizontalAlignment(SwingConstants.RIGHT); + + return myPanel; + } + + private void update() { + synchronized (this) { + if (myRepaintedFlag) { + if (System.currentTimeMillis() > myLastTimeDrawn + UPDATE_INTERVAL) { + myRepaintedFlag = false; + SwingUtilities.invokeLater(myRepaintRunnable); + } + else { + if (myUpdateAlarm.getActiveRequestCount() == 0){ + myUpdateAlarm.addRequest(myUpdateRequest, 500, getModalityState()); + } + } + } + } + } + + public void background() { + synchronized (this) { + if (myShouldShowBackground) { + myBackgroundButton.setEnabled(false); + } + + close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + } + + public void setCancelButtonText(String text){ + if (myDialog != null) + myDialog.changeCancelButtonText(text); + else + myCancelText = text; + } + + private void setFunComponent(JComponent c) { + myDialog.myFunPanel.removeAll(); + if (c != null) { + myDialog.myFunPanel.add(new JSeparator(), BorderLayout.NORTH); + myDialog.myFunPanel.add(c, BorderLayout.CENTER); + } + myDialog.pack(); + myDialog.centerRelativeToParent(); + } + + public Project getProject() { + return myProject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java new file mode 100644 index 00000000000..4ba966b2fe1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java @@ -0,0 +1,60 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Created by IntelliJ IDEA. + * User: lex + * Date: Apr 19, 2004 + * Time: 5:10:44 PM + * To change this template use File | Settings | File Templates. + */ +public class ProgressWindowWithNotification extends ProgressWindow { + private final LinkedList myListeners = new LinkedList(); + + public ProgressWindowWithNotification(boolean shouldShowCancel, Project project) { + super(shouldShowCancel, project); + } + + public ProgressWindowWithNotification(boolean shouldShowCancel, boolean shouldShowBackground, Project project) { + super(shouldShowCancel, shouldShowBackground, project); + } + + public ProgressWindowWithNotification(boolean shouldShowCancel, boolean shouldShowBackground, Project project, String cancelText) { + super(shouldShowCancel, shouldShowBackground, project, cancelText); + } + + public ProgressWindowWithNotification(boolean shouldShowCancel, boolean shouldShowBackground, Project project, JComponent parentComponent, String cancelText) { + super(shouldShowCancel, shouldShowBackground, project, parentComponent, cancelText); + } + + public void cancel() { + super.cancel(); + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + ProgressIndicatorListener progressIndicatorListener = iterator.next(); + progressIndicatorListener.cancelled(); + } + } + + public synchronized void stop() { + for (Iterator iterator = myListeners.iterator(); iterator.hasNext();) { + ProgressIndicatorListener progressIndicatorListener = iterator.next(); + progressIndicatorListener.stopped(); + } + super.stop(); + } + + public void addListener(ProgressIndicatorListener listener) { + myListeners.addFirst(listener); + } + + public void removeListener(ProgressIndicatorListener listener) { + myListeners.remove(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/SmoothProgressAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/SmoothProgressAdapter.java new file mode 100644 index 00000000000..9ccecbbdeca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/SmoothProgressAdapter.java @@ -0,0 +1,165 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.util.Alarm; +import com.intellij.util.concurrency.Semaphore; + +import javax.swing.*; + +public class SmoothProgressAdapter extends BlockingProgressIndicator { + private static final int SHOW_DELAY = 500; + + private Alarm myStartupAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + + protected ProgressIndicator myOriginal; + private Project myProject; + + private boolean myOriginalStarted; + + private DialogWrapper myDialog; + + private final Runnable myShowRequest = new Runnable() { + public void run() { + synchronized(SmoothProgressAdapter.this){ + if (!isRunning()) { + return; + } + + myOriginal.start(); + myOriginalStarted = true; + + myOriginal.setText(getText()); + myOriginal.setFraction(getFraction()); + myOriginal.setText2(getText2()); + } + } + }; + + public SmoothProgressAdapter(ProgressIndicator original, Project project){ + myOriginal = original; + myProject = project; + if (myOriginal.isModal()) { + myOriginal.setModalityProgress(this); + this.setModalityProgress(this); + } + } + + public void setIndeterminate(boolean indeterminate) { + super.setIndeterminate(indeterminate); + myOriginal.setIndeterminate(indeterminate); + } + + public boolean isIndeterminate() { + return myOriginal.isIndeterminate(); + } + + public synchronized void start() { + if (isRunning()) return; + + super.start(); + myOriginalStarted = false; + myStartupAlarm.addRequest(myShowRequest, SHOW_DELAY); + } + + public void startBlocking() { + ApplicationManager.getApplication().assertIsDispatchThread(); + start(); + if (isModal()) { + showDialog(); + } + } + + private void showDialog(){ + if (myDialog == null){ + //System.out.println("showDialog()"); + myDialog = new DialogWrapper(myProject, false) { + { + getWindow().setBounds(0, 0, 1, 1); + setResizable(false); + } + + protected boolean isProgressDialog() { + return true; + } + + protected JComponent createCenterPanel() { + return null; + } + }; + myDialog.setModal(true); + myDialog.setUndecorated(true); + myDialog.show(); + } + } + + public synchronized void stop() { + if (myOriginal.isRunning()) { + myOriginal.stop(); + } + else { + myStartupAlarm.cancelAllRequests(); + } + + // needed only for correct assertion of !progress.isRunning() in ApplicationImpl.runProcessWithProgressSynchroniously + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + semaphore.waitFor(); + if (myDialog != null){ + //System.out.println("myDialog.destroyProcess()"); + myDialog.close(DialogWrapper.OK_EXIT_CODE); + myDialog = null; + } + } + } + ); + + super.stop(); // should be last to not leaveModal before closing the dialog + semaphore.up(); + } + + public synchronized void setText(String text) { + super.setText(text); + if (myOriginal.isRunning()) { + myOriginal.setText(text); + } + } + + public synchronized void setFraction(double fraction) { + super.setFraction(fraction); + if (myOriginal.isRunning()) { + myOriginal.setFraction(fraction); + } + } + + public synchronized void setText2(String text) { + super.setText2(text); + if (myOriginal.isRunning()) { + myOriginal.setText2(text); + } + } + + public void cancel() { + super.cancel(); + myOriginal.cancel(); + } + + + + public boolean isCanceled() { + if (super.isCanceled()) return true; + if (!myOriginalStarted) return false; + return myOriginal.isCanceled(); + } + + public ProgressIndicator getOriginal() { + return myOriginal; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/StatusBarProgress.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/StatusBarProgress.java new file mode 100644 index 00000000000..0181c4ca217 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/progress/util/StatusBarProgress.java @@ -0,0 +1,114 @@ +package com.intellij.openapi.progress.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.util.Iterator; + +public class StatusBarProgress extends ProgressIndicatorBase { + // statusBar -> [textToRestore, MyPreviousText] + private HashMap> myStatusBar2SavedText = new HashMap>(); + + public void start() { + super.start(); + SwingUtilities.invokeLater ( + new Runnable() { + public void run() { + Project[] projects=ProjectManager.getInstance().getOpenProjects(); + if(projects.length==0){ + projects=new Project[]{null}; + } + for(int i=0;i(info, info)); // initial value + } + } + } + } + } + ); + } + + public void stop() { + super.stop(); + SwingUtilities.invokeLater ( + new Runnable() { + public void run() { + for(Iterator i = myStatusBar2SavedText.keySet().iterator();i.hasNext();){ + final StatusBarEx statusBar = i.next(); + final String textToRestore = updateRestoreText(statusBar); + statusBar.setInfo(textToRestore); + } + myStatusBar2SavedText.clear(); + } + } + ); + } + + public void setText(String text) { + super.setText(text); + update(); + } + + public void setFraction(double fraction) { + super.setFraction(fraction); + update(); + } + + private void update(){ + String text; + if (!isRunning()){ + text = ""; + } + else{ + text = getText(); + double fraction = getFraction(); + if (fraction > 0) { + text += " " + (int)(fraction * 100 + 0.5) + "%"; + } + } + final String text1 = text; + SwingUtilities.invokeLater ( + new Runnable() { + public void run() { + for(Iterator i = myStatusBar2SavedText.keySet().iterator();i.hasNext();){ + setStatusBarText(i.next(), text1); + } + } + } + ); + } + + private void setStatusBarText(StatusBarEx statusBar, String text) { + updateRestoreText(statusBar); + final Pair textsPair = myStatusBar2SavedText.get(statusBar); + myStatusBar2SavedText.put(statusBar, Pair.create(textsPair.first, text)); + statusBar.setInfo(text); + } + + private String updateRestoreText(StatusBarEx statusBar) { + final Pair textsPair = myStatusBar2SavedText.get(statusBar); + // if current status bar info doesn't match the value, that we set, use this value as a restore value + String info = statusBar.getInfo(); + if (info == null) { + info = ""; + } + if (!textsPair.getSecond().equals(info)) { + myStatusBar2SavedText.put(statusBar, Pair.create(info, textsPair.second)); + } + return textsPair.getFirst(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectEx.java new file mode 100644 index 00000000000..645770f0378 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectEx.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.project.ex; + +import com.intellij.openapi.project.Project; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.ReplacePathToMacroMap; + +import java.util.Map; + +public interface ProjectEx extends Project { + void dispose(); + + boolean isSavePathsRelative(); + + void setSavePathsRelative(boolean b); + + ReplacePathToMacroMap getMacroReplacements(); + + ExpandMacroToPathMap getExpandMacroReplacements(); + + boolean isDummy(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectManagerEx.java new file mode 100644 index 00000000000..bb17b14b290 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/ex/ProjectManagerEx.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.project.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.InvalidDataException; +import org.jdom.JDOMException; + +import java.io.IOException; + +/** + * + */ +public abstract class ProjectManagerEx extends ProjectManager { + public static ProjectManagerEx getInstanceEx() { + return (ProjectManagerEx)ApplicationManager.getApplication().getComponent(ProjectManager.class); + } + + public abstract Project newProject(String filePath, boolean useDefaultProjectSettings, boolean isDummy); + + public abstract Project loadProject(String filePath) throws IOException, JDOMException, InvalidDataException; + + public abstract void openProject(Project project); + + public abstract boolean closeProject(Project project); + + public abstract boolean isProjectOpened(Project project); + + public abstract boolean canClose(Project project); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/DefineMacrosDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/DefineMacrosDialog.java new file mode 100644 index 00000000000..ccbf085b75b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/DefineMacrosDialog.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.project.impl; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.util.ui.Table; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import java.awt.*; +import java.io.File; + +import gnu.trove.TObjectIntHashMap; + +/** + * @author Eugene Zhuravlev + * Date: Dec 3, 2004 + */ +public class DefineMacrosDialog extends DialogWrapper{ + public static final int MACRO_NAME = 0; + public static final int MACRO_VALUE = 1; + private final String[][] myMacroTable; + private final TObjectIntHashMap myIndex = new TObjectIntHashMap(); + + public DefineMacrosDialog(String[] macroNames) { + super(true); + myMacroTable = new String[macroNames.length][2]; + + for (int idx = 0; idx < macroNames.length; idx++) { + final String macroName = macroNames[idx]; + myMacroTable[idx] = new String[]{macroName, ""}; + myIndex.put(macroName, idx); + } + setCancelButtonText("Cancel Project Load"); + init(); + } + + protected void doOKAction() { + for (int idx = 0; idx < myMacroTable.length; idx++) { + String[] row = myMacroTable[idx]; + String path = row[MACRO_VALUE]; + + if (path == null || path.length() == 0) { + Messages.showErrorDialog(getContentPane(), "Value for the path variable \"" + row[MACRO_NAME] + "\" is not defined", "Undefined Path Variable"); + return; + } + if (!new File(path).exists()) { + Messages.showErrorDialog(getContentPane(), "Value for the path variable \"" + row[MACRO_NAME] + "\" is not defined", "Undefined Path Variable"); + return; + } + } + super.doOKAction(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction()}; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + Table table = new Table(new MyTableModel()); + JLabel label = new JLabel("TODO: message"); + label.setBorder(IdeBorderFactory.createEmptyBorder(6, 6, 6, 6)); + panel.add(label, BorderLayout.NORTH); + panel.add(new JScrollPane(table), BorderLayout.CENTER); + return panel; + } + + public String getMacroValue(String macro) { + final int index = myIndex.get(macro); + return (index >= 0 && index < myMacroTable.length)? myMacroTable[index][MACRO_VALUE] : null; + } + + private class MyTableModel extends AbstractTableModel { + public String getColumnName(int column) { + switch(column) { + case MACRO_NAME : return "Macro Name"; + case MACRO_VALUE : return "Path"; + } + return ""; + } + + public int getColumnCount() { + return myMacroTable[0].length; + } + + public int getRowCount() { + return myMacroTable.length; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + return myMacroTable[rowIndex][columnIndex]; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (columnIndex == MACRO_VALUE && aValue instanceof String) { + myMacroTable[rowIndex][MACRO_VALUE] = (String)aValue; + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == MACRO_VALUE; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectImpl.java new file mode 100644 index 00000000000..7567482baad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectImpl.java @@ -0,0 +1,564 @@ +package com.intellij.openapi.project.impl; + +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.PathMacroMap; +import com.intellij.application.options.PathMacros; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.ide.plugins.PluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.startup.StartupManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.application.ex.DecodeDefaultsUtil; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.BaseComponent; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.components.impl.ComponentManagerImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.ex.MessagesEx; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.ShutDownTracker; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.ReadonlyStatusHandler; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.pom.PomModel; +import com.intellij.util.ArrayUtil; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + + +/** + * + */ +public class ProjectImpl extends BaseFileConfigurable implements ProjectEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.project.impl.ProjectImpl"); + + private ProjectManagerImpl myManager; + private VirtualFilePointer myFilePointer; + + private MyProjectManagerListener myProjectManagerListener; + private boolean myDummy; + + private ArrayList myConversionProblemsStorage = new ArrayList(); + + private static boolean ourSaveSettingsInProgress = false; + + private static final String WORKSPACE_EXTENSION = ".iws"; + private static final String PROJECT_LAYER = "project-components"; + private boolean myDisposed = false; + private PomModel myModel = null; + + private final boolean myOptimiseTestLoadSpeed; + private static final String USED_MACROS_ELEMENT_NAME = "UsedPathMacros"; + private static final Comparator ourStringComparator = new Comparator() { + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }; + + protected ProjectImpl(ProjectManagerImpl manager, + String filePath, + boolean isDefault, + boolean isOptimiseTestLoadSpeed, + PathMacros pathMacros, VirtualFilePointerManager filePointerManager) { + super(isDefault, pathMacros); + + myOptimiseTestLoadSpeed = isOptimiseTestLoadSpeed; + + getPicoContainer().registerComponentInstance(Project.class, this); + + myManager = manager; + if (filePath != null) { + String path = filePath.replace(File.separatorChar, '/'); + String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, path); + myFilePointer = filePointerManager.create(url, null); + } + else { + myFilePointer = null; + } + } + + public synchronized Element getConfiguration(String name) { + return super.getConfiguration(name); + } + + public boolean isDummy() { + return myDummy; + } + + public boolean isDisposed() { + return myDisposed; + } + + public boolean isOpen() { + return ProjectManagerEx.getInstanceEx().isProjectOpened(this); + } + + public boolean isInitialized() { + if (!isOpen() || isDisposed()) return false; + return StartupManagerEx.getInstanceEx(this).startupActivityPassed(); + } + + public PomModel getModel() { + return myModel != null ? myModel : (myModel = getComponent(PomModel.class)); + } + + public void setDummy(boolean isDummy) { + myDummy = isDummy; + } + + protected ArrayList getConversionProblemsStorage() { + return myConversionProblemsStorage; + } + + protected void initJdomExternalizable(Class componentClass, BaseComponent component) { + if (myOptimiseTestLoadSpeed) return; //test load speed optimization + doInitJdomExternalizable(componentClass, component); + } + + public void loadProjectComponents() { + loadComponentsConfiguration(PROJECT_LAYER); + + ApplicationEx app = ApplicationManagerEx.getApplicationEx(); + if (app.shouldLoadPlugins()) { + final PluginDescriptor[] plugins = PluginManager.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + PluginDescriptor plugin = plugins[i]; + if (!app.shouldLoadPlugin(plugin)) continue; + final Element projectComponents = plugin.getProjectComponents(); + if (projectComponents != null) { + loadComponentsConfiguration(projectComponents, plugin); + } + } + } + } + + public VirtualFile[] getConfigurationFiles() { + final List files = new ArrayList(2); + + final VirtualFile projectFile = getProjectFile(); + if (projectFile != null) { + files.add(projectFile); + } + + final VirtualFile workspaceFile = getWorkspaceFile(); + if (workspaceFile != null) { + files.add(workspaceFile); + } + return files.toArray(new VirtualFile[files.size()]); + } + + public String[] getConfigurationFilePaths() { + if (myFilePointer == null) return null; + String iprPath = getProjectFilePath(); + + int dotIdx = iprPath.lastIndexOf('.'); + if (dotIdx < 0) dotIdx = iprPath.length(); + String iwsPath = iprPath.substring(0, dotIdx) + WORKSPACE_EXTENSION; + + return new String[]{iprPath, iwsPath}; + } + + public String getProjectFilePath() { + if (myFilePointer == null) return null; + String iprUrl = myFilePointer.getUrl(); + String iprProtocol = VirtualFileManager.extractProtocol(iprUrl); + LOG.assertTrue(LocalFileSystem.PROTOCOL.equals(iprProtocol)); + String iprPath = VirtualFileManager.extractPath(iprUrl).replace('/', File.separatorChar); + return iprPath; + } + + public VirtualFile getProjectFile() { + if (myFilePointer == null) return null; + VirtualFile file = myFilePointer.getFile(); + /* commented out to fix # 25591 + if (file == null){ + //??? + return ApplicationManager.getApplication().runWriteAction(new Computable() { + public VirtualFile compute() { + return VirtualFileManager.getInstance().refreshAndFindFileByUrl(myFilePointer.getUrl()); + } + }); + } + */ + return file; + } + + public String getName() { + final VirtualFile projectFile = getProjectFile(); + if (projectFile != null) return projectFile.getNameWithoutExtension(); + String temp = getProjectFilePath(); + if (temp.endsWith(".ipr")) { + temp = temp.substring(temp.length() - 4); + } + final int i = temp.lastIndexOf(File.separatorChar); + if (i >= 0) { + temp = temp.substring(i + 1, temp.length() - i + 1); + } + return temp; + } + + public VirtualFile getWorkspaceFile() { + final VirtualFile projectFile = getProjectFile(); + if (projectFile == null) return null; + + final VirtualFile parent = projectFile.getParent(); + if (parent == null) return null; + final String name = projectFile.getNameWithoutExtension() + WORKSPACE_EXTENSION; + + VirtualFile workspaceFile = parent.findChild(name); + return workspaceFile; + } + + protected Element getDefaults(BaseComponent component) throws IOException, JDOMException, InvalidDataException { + //[max | mike] speed optimization. If you need default initialization in tests + //use field initializers instead. + + if (myOptimiseTestLoadSpeed) return null; + + InputStream stream = DecodeDefaultsUtil.getDefaultsInputStream(component); + if (stream != null) { + Document document = JDOMUtil.loadDocument(stream); + stream.close(); + + if (document == null) { + throw new InvalidDataException(); + } + Element root = document.getRootElement(); + if (root == null || !"component".equals(root.getName())) { + throw new InvalidDataException(); + } + + getExpandMacroReplacements().substitute(root, SystemInfo.isFileSystemCaseSensitive); + return root; + } + return null; + } + + protected ComponentManagerImpl getParentComponentManager() { + return (ComponentManagerImpl)ApplicationManager.getApplication(); + } + + protected String getRootNodeName() { + return "project"; + } + + protected VirtualFile getComponentConfigurationFile(Class componentInterface) { + return isWorkspace(componentInterface) ? getWorkspaceFile() : getProjectFile(); + } + + public boolean isOptimiseTestLoadSpeed() { + return myOptimiseTestLoadSpeed; + } + + private boolean isWorkspace(Class componentInterface) { + final Map options = getComponentOptions(componentInterface); + if (options == null) return false; + if ("true".equals(options.get("workspace"))) return true; + return false; + } + + private void getExpandProjectHomeReplacements(ExpandMacroToPathMap result) { + String projectDir = getProjectDir(); + if (projectDir == null) return; + + File f = new File(projectDir.replace('/', File.separatorChar)); + + getExpandProjectHomeReplacements(result, f, "$" + PathMacros.PROJECT_DIR_MACRO_NAME + "$"); + } + + private void getExpandProjectHomeReplacements(ExpandMacroToPathMap result, File f, String macro) { + if (f == null) return; + + getExpandProjectHomeReplacements(result, f.getParentFile(), macro + "/.."); + String path = PathMacroMap.quotePath(f.getAbsolutePath()); + String s = macro; + + if (StringUtil.endsWithChar(path, '/')) s += "/"; + + result.put(s, path); + } + + private void getProjectHomeReplacements(ReplacePathToMacroMap result, final boolean savePathsRelative) { + String projectDir = getProjectDir(); + if (projectDir == null) return; + + File f = new File(projectDir.replace('/', File.separatorChar)); + //LOG.assertTrue(f.exists()); + + String macro = "$" + PathMacros.PROJECT_DIR_MACRO_NAME + "$"; + + while (f != null) { + String path = PathMacroMap.quotePath(f.getAbsolutePath()); + String s = macro; + + if (StringUtil.endsWithChar(path, '/')) s += "/"; + if (path.equals("/")) break; + + result.put("file://" + path, "file://" + s); + result.put("file:/" + path, "file:/" + s); + result.put("file:" + path, "file:" + s); + result.put("jar://" + path, "jar://" + s); + result.put("jar:/" + path, "jar:/" + s); + result.put("jar:" + path, "jar:" + s); + if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/")) { + result.put(path, s); + } + + if (!savePathsRelative) break; + macro += "/.."; + f = f.getParentFile(); + } + } + + private String getProjectDir() { + if (myFilePointer == null) return null; + String url = myFilePointer.getUrl(); + String path = VirtualFileManager.extractPath(url).replace('/', File.separatorChar); + String projectDir = new File(path).getParent(); + if (projectDir == null) return null; + projectDir = projectDir.replace(File.separatorChar, '/'); + if (projectDir.endsWith(":/")) { + projectDir = projectDir.substring(0, projectDir.length() - 1); + } + return projectDir; + } + + public ExpandMacroToPathMap getExpandMacroReplacements() { + ExpandMacroToPathMap result = super.getExpandMacroReplacements(); + getExpandProjectHomeReplacements(result); + return result; + } + + public ReplacePathToMacroMap getMacroReplacements() { + ReplacePathToMacroMap result = new ReplacePathToMacroMap(); + getProjectHomeReplacements(result, false); + result.putAll(super.getMacroReplacements()); + getProjectHomeReplacements(result, mySavePathsRelative); + return result; + } + + public void init() { + super.init(); + + myProjectManagerListener = new ProjectImpl.MyProjectManagerListener(); + myManager.addProjectManagerListener(this, myProjectManagerListener); + } + + public void save() { + ShutDownTracker.getInstance().registerStopperThread(Thread.currentThread()); + + try { + if (!ourSaveSettingsInProgress) { + try { + ourSaveSettingsInProgress = true; + startLoggingUsedMacros(); + + saveSettingsSavingComponents(); + + final Module[] modules = ModuleManager.getInstance(ProjectImpl.this).getModules(); + final ReadonlyStatusHandler.OperationStatus operationStatus = ensureConfigFilesWritable(modules); + if (operationStatus.hasReadonlyFiles()) { + MessagesEx.error(this, "Could not save project:\n" + operationStatus.getReadonlyFilesMessage()).showLater(); + return; + } + + final Exception[] exception = new Exception[]{null}; + CommandProcessor.getInstance().executeCommand(this, new Runnable() { + public void run() { + for (int i = 0; i < modules.length; i++) { + ModuleImpl module = (ModuleImpl)modules[i]; + try { + module._save(); + } + catch (Exception e) { + exception[0] = e; + return; + } + } + try { + // important! must save project after modules are saved, otherwise not all used macros will be saved to the ipr file + _save(); + } + catch (Exception e) { + exception[0] = e; + return; + } + } + }, "Save settings", null); + + if (exception[0] != null) { + MessagesEx.error(this, "Could not save project:\n" + exception[0].getMessage()).showLater(); + } + } + finally { + endLoggingUsedMacros(); + ourSaveSettingsInProgress = false; + } + } + } + finally { + ShutDownTracker.getInstance().unregisterStopperThread(Thread.currentThread()); + } + } + + private ReadonlyStatusHandler.OperationStatus ensureConfigFilesWritable(Module[] modules) { + final List readonlyFiles = new ArrayList(modules.length + 2); + + collectReadonlyFiles(getConfigurationFiles(), readonlyFiles); + + for (int idx = 0; idx < modules.length; idx++) { + final ModuleImpl module = (ModuleImpl)modules[idx]; + collectReadonlyFiles(module.getConfigurationFiles(), readonlyFiles); + } + + return ReadonlyStatusHandler.getInstance(this).ensureFilesWriteable(readonlyFiles.toArray(new VirtualFile[readonlyFiles.size()])); + } + + private static void collectReadonlyFiles(final VirtualFile[] files, final List readonlyFiles) { + if (files != null) { + for (int idx = 0; idx < files.length; idx++) { + VirtualFile file = files[idx]; + if (!file.isWritable()) { + readonlyFiles.add(file); + } + } + } + } + + public Element saveToXml(Element targetRoot, VirtualFile configFile) { + final Element root = super.saveToXml(targetRoot, configFile); + if (!isMacroLoggingEnabled()) { + return root; + } + VirtualFile projectFile = getProjectFile(); + if (projectFile != null && projectFile.equals(configFile)) { + final String[] usedMacros = getUsedMacroNames(); + // need this in order to keep file looking the same for vcs if macro set is not changed + Arrays.sort(usedMacros, ourStringComparator); + final Element allMacrosElement = new Element(USED_MACROS_ELEMENT_NAME); + root.addContent(allMacrosElement); + for (int idx = 0; idx < usedMacros.length; idx++) { + final String usedMacro = usedMacros[idx]; + final Element macroElem = new Element("macro"); + allMacrosElement.addContent(macroElem); + macroElem.setAttribute("name", usedMacro); + } + } + return root; + } + + public static String[] readUsedMacros(Element root) { + Element child = root.getChild(USED_MACROS_ELEMENT_NAME); + if (child == null) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + final List children = child.getChildren("macro"); + final List macroNames = new ArrayList(children.size()); + for (Iterator it = children.iterator(); it.hasNext();) { + final Element macro = (Element)it.next(); + String macroName = macro.getAttributeValue("name"); + if (macroName != null) { + macroNames.add(macroName); + } + } + return macroNames.toArray(new String[macroNames.size()]); + } + + public void dispose() { + LOG.assertTrue(!myDisposed); + if (myProjectManagerListener != null) { + myManager.removeProjectManagerListener(this, myProjectManagerListener); + } + + disposeComponents(); + myDisposed = true; + } + + private void projectOpened() { + final BaseComponent[] components = getComponents(false); + for (int i = 0; i < components.length; i++) { + try { + ProjectComponent component = (ProjectComponent)components[i]; + component.projectOpened(); + } + catch (Throwable e) { + LOG.error(e); + } + } + } + + private void projectClosed() { + final BaseComponent[] components = getComponents(false); + for (int i = components.length - 1; i >= 0; i--) { + try { + ProjectComponent component = (ProjectComponent)components[i]; + component.projectClosed(); + } + catch (Throwable e) { + LOG.error(e); + } + } + } + + protected String getConfigurableType() { + return "project"; + } + + private class MyProjectManagerListener implements ProjectManagerListener { + public void projectOpened(Project project) { + LOG.assertTrue(project == ProjectImpl.this); + ProjectImpl.this.projectOpened(); + } + + public void projectClosed(Project project) { + LOG.assertTrue(project == ProjectImpl.this); + ProjectImpl.this.projectClosed(); + } + + public boolean canCloseProject(Project project) { + return true; + } + + public void projectClosing(Project project) { + } + } + + public static class ReadOnlyProjectException extends Exception { + private String myConfigurableType; + private File myFile; + + public ReadOnlyProjectException(String configurableType, File file) { + myFile = file; + myConfigurableType = configurableType; + } + + public MessagesEx.MessageInfo getMessageInfo(Project project) { + return MessagesEx.fileIsReadOnly(project, myFile.getAbsolutePath()).setTitle("Cannot save " + myConfigurableType); + } + + public File getFile() { + return myFile; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectManagerImpl.java new file mode 100644 index 00000000000..db5d3a04276 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -0,0 +1,696 @@ +package com.intellij.openapi.project.impl; + +import com.intellij.application.options.PathMacros; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.project.ProjectReloadState; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.openapi.vfs.ex.VirtualFileManagerListener; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.containers.HashMap; +import gnu.trove.TObjectLongHashMap; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.util.*; + +public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExternalizable, ExportableApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.project.impl.ProjectManagerImpl"); + static final int CURRENT_FORMAT_VERSION = 4; + + private static final Key> LISTENERS_IN_PROJECT_KEY = Key.create("LISTENERS_IN_PROJECT_KEY"); + + private ProjectImpl myDefaultProject; + private Element myDefaultProjectRootElement; + + private final ArrayList myOpenProjects = new ArrayList(); + private final ArrayList myListeners = new ArrayList(); + + /** + * More then 0 while openProject is being executed: [openProject..runStartupActivities...runPostStartupActivitites]. + * This flag is required by SaveAndSynchHandler. We do not save + * anything while project is being opened. + */ + private int myCountOfProjectsBeingOpen; + private boolean myIsInRefresh; + private Map mySavedCopies = new HashMap(); + private TObjectLongHashMap mySavedTimestamps = new TObjectLongHashMap(); + private HashMap> myChangedProjectFiles = new HashMap>(); + private PathMacros myPathMacros; + private VirtualFilePointerManager myFilePointerManager; + + private static ProjectManagerListener[] getListeners(Project project) { + ArrayList array = project.getUserData(LISTENERS_IN_PROJECT_KEY); + if (array == null) return ProjectManagerListener.EMPTY_ARRAY; + ProjectManagerListener[] listeners = array.toArray(new ProjectManagerListener[array.size()]); + return listeners; + } + + /* @fabrique used by fabrique! */ + public ProjectManagerImpl(VirtualFileManagerEx virtualFileManagerEx, + PathMacros pathMacros, + VirtualFilePointerManager filePointerManager) { + addProjectManagerListener( + new ProjectManagerListener() { + + public void projectOpened(Project project) { + ProjectManagerListener[] listeners = getListeners(project); + for (int i = 0; i < listeners.length; i++) { + ProjectManagerListener listener = listeners[i]; + listener.projectOpened(project); + } + } + + public void projectClosed(Project project) { + ProjectManagerListener[] listeners = getListeners(project); + for (int i = 0; i < listeners.length; i++) { + ProjectManagerListener listener = listeners[i]; + listener.projectClosed(project); + } + } + + public boolean canCloseProject(Project project) { + ProjectManagerListener[] listeners = getListeners(project); + for (int i = 0; i < listeners.length; i++) { + ProjectManagerListener listener = listeners[i]; + if (!listener.canCloseProject(project)) { + return false; + } + } + return true; + } + + public void projectClosing(Project project) { + ProjectManagerListener[] listeners = getListeners(project); + for (int i = 0; i < listeners.length; i++) { + ProjectManagerListener listener = listeners[i]; + listener.projectClosing(project); + } + } + } + ); + + registerExternalProjectFileListener(virtualFileManagerEx); + myPathMacros = pathMacros; + myFilePointerManager = filePointerManager; + } + + public void disposeComponent() { + if (myDefaultProject != null) { + myDefaultProject.dispose(); + myDefaultProject = null; + } + } + + public void initComponent() { + } + + public Project newProject(String filePath, boolean useDefaultProjectSettings, boolean isDummy) { + if (filePath != null) { + try { + String canonicalPath = new File(filePath).getCanonicalPath(); + if (canonicalPath != null) { + filePath = canonicalPath; + } + } + catch (IOException e) { + } + } + ProjectImpl project = createProject(filePath, false, isDummy, ApplicationManager.getApplication().isUnitTestMode()); + + if (useDefaultProjectSettings) { + ProjectImpl defaultProject = (ProjectImpl)getDefaultProject(); + Element element = defaultProject.saveToXml(null, defaultProject.getProjectFile()); + try { + project.loadFromXml(element, filePath); + } + catch (Exception e) { + LOG.error(e); + } + } + project.init(); + return project; + } + + private ProjectImpl createProject(String filePath, boolean isDefault, boolean isDummy, boolean isOptimiseTestLoadSpeed) { + final ProjectImpl project = new ProjectImpl(this, filePath, isDefault, isOptimiseTestLoadSpeed, myPathMacros, myFilePointerManager); + project.setDummy(isDummy); + project.loadProjectComponents(); + return project; + } + + public Project loadProject(String filePath) throws IOException, JDOMException, InvalidDataException { + try { + String canonicalPath = new File(filePath).getCanonicalPath(); + if (canonicalPath != null) { + filePath = canonicalPath; + } + } + catch (IOException e) { + } + ProjectImpl project = createProject(filePath, false, false, false); + + final boolean macrosOk = checkMacros(project, getDefinedMacros()); + if (!macrosOk) { + throw new IOException("There are undefined path variables in project file"); + } + + project.loadSavedConfiguration(); + + project.init(); + return project; + } + + private Set getDefinedMacros() { + Set definedMacros = new HashSet(myPathMacros.getUserMacroNames()); + definedMacros.addAll(myPathMacros.getSystemMacroNames()); + definedMacros = Collections.unmodifiableSet(definedMacros); + return definedMacros; + } + + private static boolean checkMacros(Project project, Set definedMacros) throws IOException, JDOMException { + String projectFilePath = project.getProjectFilePath(); + if (projectFilePath == null) { + return true; + } + Document document = JDOMUtil.loadDocument(new File(projectFilePath)); + Element root = document.getRootElement(); + final Set usedMacros = new HashSet(Arrays.asList(ProjectImpl.readUsedMacros(root))); + + usedMacros.removeAll(definedMacros); + if (usedMacros.isEmpty()) { + return true; // all macros in configuration files are defined + } + // there are undefined macros, need to define them before loading components + final String text = "There are undefined path variables in project configuration files.\n" + + "In order for the project to load all path variables must be defined."; + return showMacrosConfigurationDialog(project, text, usedMacros); + } + + private static boolean showMacrosConfigurationDialog(Project project, final String text, final Set usedMacros) { + final UndefinedMacrosConfigurable configurable = new UndefinedMacrosConfigurable(text, usedMacros.toArray(new String[usedMacros.size()])); + final SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable) { + protected void doOKAction() { + if (!myConfigurable.isModified()) { + Messages.showErrorDialog(getContentPane(), "All path variables should be defined", "Path Variables Not Defined"); + return; + } + super.doOKAction(); + } + }; + editor.show(); + return editor.isOK(); + } + + public synchronized Project getDefaultProject() { + if (myDefaultProject == null) { + myDefaultProject = createProject(null, true, false, ApplicationManager.getApplication().isUnitTestMode()); + if (myDefaultProjectRootElement != null) { + try { + myDefaultProject.loadFromXml(myDefaultProjectRootElement, null); + } + catch (InvalidDataException e) { + LOG.info(e); + Messages.showErrorDialog(e.getMessage(), "Error Loading Default Project"); + } + finally { + myDefaultProjectRootElement = null; + } + } + myDefaultProject.init(); + } + return myDefaultProject; + } + + public Project[] getOpenProjects() { + return myOpenProjects.toArray(new Project[myOpenProjects.size()]); + } + + public boolean isProjectOpened(Project project) { + return myOpenProjects.contains(project); + } + + public void openProject(final Project project) { + if (myOpenProjects.contains(project)) return; + if (!ApplicationManager.getApplication().isUnitTestMode() && !checkVersion(project)) return; + + myCountOfProjectsBeingOpen++; + myOpenProjects.add(project); + fireProjectOpened(project); + + ApplicationManager.getApplication().runProcessWithProgressSynchronously( + new Runnable() { + public void run() { + ((StartupManagerImpl)StartupManager.getInstance(project)).runStartupActivities(); + } + }, + "Loading Project", + false, + project + ); + ((StartupManagerImpl)StartupManager.getInstance(project)).runPostStartupActivities(); + + // Hack. We need to initialize FileDocumentManagerImpl's dummy project since it is lazy initialized and initialization can happen in + // non-swing thread which could lead to some dummy components fail to initialize. + FileDocumentManager fdManager = FileDocumentManager.getInstance(); + if (fdManager instanceof FileDocumentManagerImpl) { + ((FileDocumentManagerImpl)fdManager).getDummyProject(); + } + myCountOfProjectsBeingOpen--; + } + + private void registerExternalProjectFileListener(VirtualFileManagerEx virtualFileManager) { + virtualFileManager.addVirtualFileManagerListener(new VirtualFileManagerListener() { + public void beforeRefreshStart(boolean asynchonous) { + myIsInRefresh = true; + } + + public void afterRefreshFinish(boolean asynchonous) { + myIsInRefresh = false; + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myChangedProjectFiles.size() > 0) { + Set projects = myChangedProjectFiles.keySet(); + List projectsToReload = new ArrayList(); + + for (Iterator iterator = projects.iterator(); iterator.hasNext();) { + Project project = iterator.next(); + List causes = myChangedProjectFiles.get(project); + Set liveCauses = new HashSet(causes); + for (int i = 0; i < causes.size(); i++) { + VirtualFile cause = causes.get(i); + if (!cause.isValid()) liveCauses.remove(cause); + } + + if (!liveCauses.isEmpty()) { + StringBuffer message = new StringBuffer(); + message.append("Project file"); + if (liveCauses.size() > 1) { + message.append("s:\n"); + } + else { + message.append(" "); + } + + boolean first = true; + for (Iterator it = liveCauses.iterator(); it.hasNext();) { + VirtualFile cause = it.next(); + if (!first) message.append("\n"); + first = false; + message.append(cause.getPresentableUrl()); + } + + message.append(liveCauses.size() > 1 ? "\nhave" : " has"); + message.append(" been changed externally.\n\nReload project?"); + + if (Messages.showYesNoDialog(project, + message.toString(), + "Project Files Changed", + Messages.getQuestionIcon()) == 0) { + projectsToReload.add(project); + } + } + + for (Iterator reloadIterator = projectsToReload.iterator(); reloadIterator.hasNext();) { + reloadProject(reloadIterator.next()); + } + } + + myChangedProjectFiles.clear(); + } + } + }, ModalityState.NON_MMODAL); + } + }); + + virtualFileManager.addVirtualFileListener(new VirtualFileAdapter() { + public void contentsChanged(VirtualFileEvent event) { + if (event.getRequestor() == null && myIsInRefresh) { // external change + final VirtualFile file = event.getFile(); + final Project[] projects = getOpenProjects(); + for (int i = 0; i < projects.length; i++) { + Project project = projects[i]; + if (file == project.getProjectFile() || file == project.getWorkspaceFile()) { + copyToTemp(file); + registerProjectToReload(project, file); + } + + ModuleManager moduleManager = ModuleManager.getInstance(project); + final Module[] modules = moduleManager.getModules(); + for (int j = 0; j < modules.length; j++) { + if (modules[j].getModuleFile() == file) { + copyToTemp(file); + registerProjectToReload(project, file); + } + } + } + } + } + }); + } + + private void registerProjectToReload(final Project project, final VirtualFile cause) { + List changedProjectFiles = myChangedProjectFiles.get(project); + + if (changedProjectFiles == null) { + changedProjectFiles = new ArrayList(); + myChangedProjectFiles.put(project, changedProjectFiles); + } + + changedProjectFiles.add(cause); + } + + private void copyToTemp(VirtualFile file) { + try { + final byte[] bytes = file.contentsToByteArray(); + mySavedCopies.put(file, bytes); + mySavedTimestamps.put(file, file.getActualTimeStamp()); + } + catch (IOException e) { + LOG.error(e); + } + } + + private void restoreCopy(VirtualFile file) { + try { + if (file == null) return; // Externally deleted actually. + if (!file.isWritable()) return; // IDEA was unable to save it as well. So no need to restore. + + final byte[] bytes = mySavedCopies.get(file); + if (bytes != null) { + try { + final OutputStream stream = file.getOutputStream(this, -1, mySavedTimestamps.get(file)); + stream.write(bytes); + stream.close(); + } + catch (IOException e) { + Messages.showWarningDialog("Error writing to file '" + file.getPresentableUrl() + "'. Project may reload incorrectly.", "Write error"); + } + } + } + finally { + mySavedCopies.remove(file); + mySavedTimestamps.remove(file); + } + } + + private void reloadProject(final Project project) { + ProjectReloadState.getInstance(project).onBeforeAutomaticProjectReload(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + LOG.info("Reloading project after external change."); + final String path = project.getProjectFilePath(); + final List original = getAllProjectFiles(project); + + if (project.isDisposed() || ProjectUtil.closeProject(project)){ + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (Iterator iterator = original.iterator(); iterator.hasNext();) { + restoreCopy(iterator.next()); + } + } + }); + + ProjectUtil.openProject(path, null, true); + } + } + }, ModalityState.NON_MMODAL); + } + + private static List getAllProjectFiles(Project project) { + List files = new ArrayList(); + files.add(project.getProjectFile()); + files.add(project.getWorkspaceFile()); + + ModuleManager moduleManager = ModuleManager.getInstance(project); + final Module[] modules = moduleManager.getModules(); + for (int j = 0; j < modules.length; j++) { + Module module = modules[j]; + files.add(module.getModuleFile()); + } + return files; + } + + private static boolean checkVersion(final Project project) { + int version = ((ProjectImpl)project).getOriginalVersion(); + if (version >= 0 && version < CURRENT_FORMAT_VERSION) { + final VirtualFile projectFile = project.getProjectFile(); + LOG.assertTrue(projectFile != null); + String name = projectFile.getNameWithoutExtension(); + + String message = + "The project " + projectFile.getName() + " you are about to open has an older format.\n" + + "IDEA will automatically convert it to the new format.\n" + + "You will not be able to open it by earlier versions.\n" + + "The old project file will be saved to " + name + "_old.ipr.\n" + + "Proceed with conversion?"; + if (Messages.showYesNoDialog(message, "Warning", Messages.getWarningIcon()) != 0) return false; + + final ArrayList conversionProblems = ((ProjectImpl) project).getConversionProblemsStorage(); + if (conversionProblems.size() > 0) { + StringBuffer buffer = new StringBuffer(); + buffer.append("During your project conversion, the following problem(s) were detected:"); + for (Iterator iterator = conversionProblems.iterator(); iterator.hasNext();) { + String s = iterator.next(); + buffer.append('\n'); + buffer.append(s); + } + buffer.append("\n\nPress 'Show Help' for more information."); + final int result = Messages.showDialog(project, buffer.toString(), "Project Conversion Problems", + new String[]{"Show Help", "Close"}, 0, + Messages.getWarningIcon() + ); + if (result == 0) { + HelpManager.getInstance().invokeHelp("project.migrationProblems"); + } + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + VirtualFile projectDir = projectFile.getParent(); + + final String oldProjectName = projectFile.getNameWithoutExtension() + "_old." + projectFile.getExtension(); + VirtualFile oldProject = projectDir.findChild(oldProjectName); + if (oldProject == null) { + oldProject = projectDir.createChildData(this, oldProjectName); + } + Writer writer = oldProject.getWriter(this); + writer.write(projectFile.contentsToCharArray()); + writer.close(); + + VirtualFile workspaceFile = project.getWorkspaceFile(); + if (workspaceFile != null) { + final String oldWorkspaceName = workspaceFile.getNameWithoutExtension() + "_old." + + project.getWorkspaceFile().getExtension(); + VirtualFile oldWorkspace = projectDir.findChild(oldWorkspaceName); + if (oldWorkspace == null) { + oldWorkspace = projectDir.createChildData(this, oldWorkspaceName); + } + writer = oldWorkspace.getWriter(this); + writer.write(workspaceFile.contentsToCharArray()); + writer.close(); + } + } + catch (IOException e) { + LOG.error(e); + } + } + }); + } + + if (version > CURRENT_FORMAT_VERSION) { + String message = + "The project " + project.getName() + " you are about to open " + + "has been created by a newer version of IDEA. If you open it, your project" + + " is likely to be corrupted. Continue?"; + + if (Messages.showYesNoDialog(message, "Warning", Messages.getWarningIcon()) != 0) return false; + } + + return true; + } + + + /* + public boolean isOpeningProject() { + return myCountOfProjectsBeingOpen > 0; + } + */ + + public boolean closeProject(final Project project) { + if (!isProjectOpened(project)) return true; + if (!canClose(project)) return false; + + fireProjectClosing(project); + + ShutDownTracker.getInstance().registerStopperThread(Thread.currentThread()); + try { + FileDocumentManager.getInstance().saveAllDocuments(); + project.save(); + + myOpenProjects.remove(project); + fireProjectClosed(project); + + ApplicationManagerEx.getApplicationEx().saveSettings(); + } + finally { + ShutDownTracker.getInstance().unregisterStopperThread(Thread.currentThread()); + } + + return true; + } + + protected void fireProjectClosing(Project project) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: fireProjectClosing()"); + } + synchronized (myListeners) { + if (myListeners.size() > 0) { + ProjectManagerListener[] listeners = myListeners.toArray(new ProjectManagerListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].projectClosing(project); + } + } + } + } + + public void addProjectManagerListener(ProjectManagerListener listener) { + synchronized (myListeners) { + myListeners.add(listener); + } + } + + public void removeProjectManagerListener(ProjectManagerListener listener) { + synchronized (myListeners) { + boolean removed = myListeners.remove(listener); + LOG.assertTrue(removed); + } + } + + public void addProjectManagerListener(Project project, ProjectManagerListener listener) { + ArrayList listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY); + if (listeners == null) { + listeners = new ArrayList(); + project.putUserData(LISTENERS_IN_PROJECT_KEY, listeners); + } + listeners.add(listener); + } + + public void removeProjectManagerListener(Project project, ProjectManagerListener listener) { + ArrayList listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY); + if (listeners != null) { + boolean removed = listeners.remove(listener); + LOG.assertTrue(removed); + } + else { + LOG.assertTrue(false); + } + } + + private void fireProjectOpened(Project project) { + if (LOG.isDebugEnabled()) { + LOG.debug("projectOpened"); + } + synchronized (myListeners) { + if (myListeners.size() > 0) { + ProjectManagerListener[] listeners = myListeners.toArray(new ProjectManagerListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].projectOpened(project); + } + } + } + } + + private void fireProjectClosed(Project project) { + if (LOG.isDebugEnabled()) { + LOG.debug("projectClosed"); + } + synchronized (myListeners) { + if (myListeners.size() > 0) { + ProjectManagerListener[] listeners = myListeners.toArray(new ProjectManagerListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].projectClosed(project); + } + } + } + } + + public boolean canClose(Project project) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: canClose()"); + } + synchronized (myListeners) { + if (myListeners.size() > 0) { + ProjectManagerListener[] listeners = myListeners.toArray(new ProjectManagerListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + if (!listeners[i].canCloseProject(project)) return false; + } + } + } + + return true; + } + + public void writeExternal(Element parentNode) throws WriteExternalException { + if (myDefaultProject != null) { + Element element = new Element("defaultProject"); + parentNode.addContent(element); + myDefaultProject.saveToXml(element, myDefaultProject.getProjectFile()); + } + else if (myDefaultProjectRootElement != null){ + parentNode.addContent((Element)myDefaultProjectRootElement.clone()); + } + + } + + public void readExternal(Element parentNode) throws InvalidDataException { + Element element = parentNode.getChild("defaultProject"); + if (element != null) { + myDefaultProjectRootElement = element; + } + } + + public String getExternalFileName() { + return "project.default"; + } + + public String getComponentName() { + return "ProjectManager"; + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Default project settings"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectReloadStateImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectReloadStateImpl.java new file mode 100644 index 00000000000..f8f98142f19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/ProjectReloadStateImpl.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.project.impl; + +import com.intellij.openapi.project.ProjectReloadState; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import org.jdom.Element; + +public class ProjectReloadStateImpl extends ProjectReloadState implements ProjectComponent, JDOMExternalizable { + + public static final int UNKNOWN = 0; + public static final int BEFORE_RELOAD = 1; + public static final int AFTER_RELOAD = 2; + + public int STATE = UNKNOWN; + + public void projectOpened() { + + } + + public void projectClosed() { + + } + + public String getComponentName() { + return "ProjectReloadState"; + } + + public void initComponent() { } + + public void disposeComponent() { + + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + private void transformState() { + if (STATE == BEFORE_RELOAD) { + STATE = AFTER_RELOAD; + } + else if (STATE == AFTER_RELOAD) { + STATE = UNKNOWN; + } + } + + public void setBeforeReload() { + STATE = BEFORE_RELOAD; + } + + public boolean isAfterAutomaticReload() { + return STATE == AFTER_RELOAD; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + transformState(); + } + + public void onBeforeAutomaticProjectReload() { + setBeforeReload(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/UndefinedMacrosConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/UndefinedMacrosConfigurable.java new file mode 100644 index 00000000000..904a9c640f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/UndefinedMacrosConfigurable.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.project.impl; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.application.options.pathMacros.PathMacroConfigurable; +import com.intellij.application.options.pathMacros.PathMacroListEditor; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Zhuravlev + * Date: Dec 4, 2004 + */ +public class UndefinedMacrosConfigurable implements Configurable{ + private PathMacroListEditor myEditor; + private final String myText; + private final String[] myUndefinedMacroNames; + + public UndefinedMacrosConfigurable(String text, String[] undefinedMacroNames) { + myText = text; + myUndefinedMacroNames = undefinedMacroNames; + } + + public String getHelpTopic() { + return PathMacroConfigurable.HELP_ID; + } + + public Icon getIcon() { + return PathMacroConfigurable.ICON; + } + + public String getDisplayName() { + return "Configure Path Variables"; + } + + public JComponent createComponent() { + final JPanel mainPanel = new JPanel(new BorderLayout()); + // important: do not allow to remove or change macro name for already defined macros befor project is loaded + myEditor = new PathMacroListEditor(myUndefinedMacroNames, true); + final JComponent editorPanel = myEditor.getPanel(); + + mainPanel.add(editorPanel, BorderLayout.CENTER); + + final JLabel textLabel = new JLabel(myText); + textLabel.setUI(new MultiLineLabelUI()); + textLabel.setBorder(IdeBorderFactory.createEmptyBorder(6, 6, 6, 6)); + mainPanel.add(textLabel, BorderLayout.NORTH); + + return mainPanel; + } + + public boolean isModified() { + return myEditor.isModified(); + } + + public void apply() throws ConfigurationException { + myEditor.commit(); + } + + public void reset() { + myEditor.reset(); + } + + public void disposeUIResources() { + myEditor = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor01.java new file mode 100644 index 00000000000..6a73d567455 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor01.java @@ -0,0 +1,122 @@ +package com.intellij.openapi.project.impl.convertors; + +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Element; + +import java.util.List; +import java.util.Iterator; + +public class Convertor01 { + private static final String VIRTUAL_FILE_MANAGER_CLASS = "com.intellij.vfs.VirtualFileManager"; + private static final String JAR_FILE_SYSTEM_CLASS = "com.intellij.vfs.jar.JarFileSystem"; + private static final String PROJECT_ROOT_CONTAINER_CLASS = "com.intellij.project.ProjectRootContainer"; + + private static final String SOURCE_PATH_ENTRY_ATTRIBUTE = "sourcePathEntry"; + private static final String CLASS_PATH_ENTRY_ATTRIBUTE = "classPathEntry"; + private static final String OUTPUT_PATH_ENTRY_ATTRIBUTE = "outputPathEntry"; + private static final String JAVADOC_PATH_ENTRY_ATTRIBUTE = "javadocPathEntry"; + + public static void execute(Element root) { + Element rootContComponent = Util.findComponent(root, PROJECT_ROOT_CONTAINER_CLASS); + if (rootContComponent != null) { + for (Iterator iterator = rootContComponent.getChildren("root").iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + + String url = element.getAttributeValue("file"); + if (url != null) { + boolean isJar = url.indexOf("!/") >= 0; + if (isJar) { + url = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, url); + } + else { + url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, url); + } + element.setAttribute("file", url); + } + Element propertyElement = new Element("property"); + element.addContent(propertyElement); + propertyElement.setAttribute("name", "type"); + propertyElement.setAttribute("value", "projectFiles"); + } + + } + else { + rootContComponent = new Element("component"); + root.addContent(rootContComponent); + rootContComponent.setAttribute("class", PROJECT_ROOT_CONTAINER_CLASS); + } + + Element vfManComponent = Util.findComponent(root, VIRTUAL_FILE_MANAGER_CLASS); + if (vfManComponent != null) { + for (Iterator iterator = vfManComponent.getChildren("fileSystem").iterator(); iterator.hasNext();) { + Element node = (Element)iterator.next(); + + String fileSystemClass = node.getAttributeValue("class"); + boolean isJar = JAR_FILE_SYSTEM_CLASS.equals(fileSystemClass); + String path = null; + String rootType = null; + + List children = node.getChildren(); + for (Iterator i = children.iterator(); i.hasNext();) { + Element node1 = (Element)i.next(); + + if ("root".equals(node1.getName())) { + path = node1.getAttributeValue("path"); + } + else if ("attribute".equals(node1.getName())) { + String name = node1.getAttributeValue("name"); + if (SOURCE_PATH_ENTRY_ATTRIBUTE.equals(name)) { + rootType = "sourcePathEntry"; + } + else if (CLASS_PATH_ENTRY_ATTRIBUTE.equals(name)) { + rootType = "classPathEntry"; + } + else if (OUTPUT_PATH_ENTRY_ATTRIBUTE.equals(name)) { + rootType = "outputPath"; + } + else if (JAVADOC_PATH_ENTRY_ATTRIBUTE.equals(name)) { + rootType = "javadocPathEntry"; + } + /* + else if (EXTERNAL_ATTRIBUTE.equals(name)){ + isExternal = true; + } + */ + } + } + + String url; + if (isJar) { + path += JarFileSystem.JAR_SEPARATOR; + url = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, path); + } + else { + url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, path); + } + + Element element = new Element("root"); + rootContComponent.addContent(element); + element.setAttribute("file", url); + + Element propertyElement = new Element("property"); + element.addContent(propertyElement); + propertyElement.setAttribute("name", "type"); + if (rootType != null) { + propertyElement.setAttribute("value", rootType); + } + + /* + if (isExternal){ + propertyElement = document.createElement("property"); + element.appendChild(propertyElement); + propertyElement.setAttribute("name", ProjectRoot.PROP_EXTERNAL); + } + */ + } + + root.removeContent(vfManComponent); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor12.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor12.java new file mode 100644 index 00000000000..05453938f84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor12.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.project.impl.convertors; + +import org.jdom.Element; + +public class Convertor12 { + private static final String OLD_PROJECT_ROOT_CONTAINER_CLASS = "com.intellij.project.ProjectRootContainer"; + private static final String NEW_PROJECT_ROOT_CONTAINER_CLASS = "com.intellij.projectRoots.ProjectRootContainer"; + + public static void execute(Element root) { + Element rootContComponent = Util.findComponent(root, OLD_PROJECT_ROOT_CONTAINER_CLASS); + if (rootContComponent != null) { + rootContComponent.setAttribute("class", NEW_PROJECT_ROOT_CONTAINER_CLASS); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor23.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor23.java new file mode 100644 index 00000000000..17b3b2601ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor23.java @@ -0,0 +1,95 @@ +package com.intellij.openapi.project.impl.convertors; + +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Element; + +import java.util.Iterator; + +/** + * @author mike + */ +public class Convertor23 { + private static final String PROJECT_ROOT_CONTAINER_CLASS = "com.intellij.projectRoots.ProjectRootContainer"; + + public static void execute(Element root) { + Element rootContComponent = Util.findComponent(root, PROJECT_ROOT_CONTAINER_CLASS); + if (rootContComponent != null) { + rootContComponent.setAttribute("class", ProjectRootManager.class.getName()); + } + convertCompilerConfiguration(root); + } + + private static final String COMPILER_CONFIGURATION_CLASS = "com.intellij.openapi.compiler.Compiler"; + private static final String COMPILER_CONFIGURATION_COMPONENT = "CompilerConfiguration"; + private static final String COMPILER_WORKSPACE_CONFIGURATION_COMPONENT = "CompilerWorkspaceConfiguration"; + + private static final String ATTR_CLASS = "class"; + private static final String ATTR_OPTION = "option"; + private static final String ATTR_NAME = "name"; + private static final String ATTR_VALUE = "value"; + private static final String ATTR_PATH = "path"; + private static final String ATTR_URL = "url"; + private static final String ATTR_EXCLUDE_FROM_COMPILE = "excludeFromCompile"; + + public static void convertCompilerConfiguration(Element root){ + String compileInBackgroundValue = null; + Element component = Util.findComponent(root, COMPILER_CONFIGURATION_CLASS); + if(component != null){ + component.setAttribute(ATTR_NAME, COMPILER_CONFIGURATION_COMPONENT); + component.removeAttribute(ATTR_CLASS); + for(Iterator children = component.getChildren().iterator(); children.hasNext();){ + Element element = (Element)children.next(); + String elementName = element.getName(); + if(ATTR_OPTION.equals(elementName)){ + String name = element.getAttributeValue(ATTR_NAME); + if(name != null){ + if(name.equals("COMPILE_IN_BACKGROUND")){ + compileInBackgroundValue = element.getAttributeValue(ATTR_VALUE); + } + } + } + else if (ATTR_EXCLUDE_FROM_COMPILE.equals(elementName)){ + for(Iterator excludeIterator = element.getChildren().iterator(); excludeIterator.hasNext();){ + Element excludeElement = (Element)excludeIterator.next(); + String path = excludeElement.getAttributeValue(ATTR_PATH); + if(path != null){ + String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, path); + excludeElement.removeAttribute(ATTR_PATH); + excludeElement.setAttribute(ATTR_URL, url); + } + } + } + } + } + if(compileInBackgroundValue != null){ + component = Util.findComponent(root, COMPILER_WORKSPACE_CONFIGURATION_COMPONENT); + if(component == null){ + component = new Element("component"); + component.setAttribute(ATTR_NAME, COMPILER_WORKSPACE_CONFIGURATION_COMPONENT); + root.addContent(component); + } + boolean added = false; + for(Iterator children = component.getChildren().iterator(); children.hasNext();){ + Element element = (Element)children.next(); + String elementName = element.getName(); + if(ATTR_OPTION.equals(elementName)){ + String name = element.getAttributeValue(ATTR_NAME); + if(name != null){ + if(name.equals("COMPILE_IN_BACKGROUND")){ + element.setAttribute(ATTR_VALUE, compileInBackgroundValue); + added = true; + } + } + } + } + if(!added){ + Element compileInBackgroundElement = new Element(ATTR_OPTION); + compileInBackgroundElement.setAttribute(ATTR_NAME, "COMPILE_IN_BACKGROUND"); + compileInBackgroundElement.setAttribute(ATTR_VALUE, compileInBackgroundValue); + component.addContent(compileInBackgroundElement); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor34.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor34.java new file mode 100644 index 00000000000..bb79ecdd01b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Convertor34.java @@ -0,0 +1,739 @@ +package com.intellij.openapi.project.impl.convertors; + +import com.intellij.j2ee.DeploymentDescriptorsConstants; +import com.intellij.j2ee.j2eeDom.web.WebRoot; +import com.intellij.j2ee.module.J2EEDeploymentDescriptorBase; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.impl.ProjectRootUtil; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Attribute; +import org.jdom.Document; +import org.jdom.Element; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author max, dsl + */ +public class Convertor34 { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.impl.convertors.Convertor34"); + + public static final String PROJECT_ROOT_MANAGER = "ProjectRootManager"; + public static final String PROJECT_ROOT_MANAGER_CLASS = "com.intellij.openapi.projectRoots.ProjectRootManager"; + + private static final String SOURCE_ROOTS_NOT_UNDER_PROJECT_ROOTS = "There are source roots that are not under project roots."; + private static final String JAVA_DOC_ROOTS_CANNOT_BE_CONVERTED = "JavaDoc paths cannot be converted."; + private static final String MULTIPLE_OUTPUT_PATHS = "The project uses multiple output paths."; + + public static void execute(Element root, String filePath, ArrayList conversionProblems) { + if (filePath == null) return; + + if (conversionProblems == null) { + conversionProblems = new ArrayList(); + } + convertProjectFile(root, filePath, conversionProblems); + } + + public static String convertLibraryTable34(Element root, String filePath) { + if (filePath == null) return null; + final Element libraryTable = findNamedChild(root, "component", "ProjectLibraryTable"); + if (libraryTable == null) return null; + + final Element applicationLibraryTable = new Element("component"); + applicationLibraryTable.setAttribute("name", "libraryTable"); + + final List oldLibraries = libraryTable.getChildren("library"); + for (int i = 0; i < oldLibraries.size(); i++) { + Element oldLibrary = (Element)oldLibraries.get(i); + Element newLibrary = convertLibrary(oldLibrary); + applicationLibraryTable.addContent(newLibrary); + } + + final String ioFilePath = filePath.replace('/', File.separatorChar); + String parentPath = new File(ioFilePath).getParent(); + if (parentPath == null) parentPath = "."; + parentPath += "/applicationLibraries.xml"; + final Element newRoot = new Element("application"); + newRoot.addContent(applicationLibraryTable); + final Document libraryTableDocument = new Document(newRoot); + try { + JDOMUtil.writeDocument(libraryTableDocument, parentPath, "\n"); + } + catch (IOException e) { + LOG.error(e); + return null; + } + return parentPath; + } + + private static Element convertLibrary(Element oldLibrary) { + final Element library = new Element("library"); + final Element nameChild = oldLibrary.getChild("name"); + LOG.assertTrue(nameChild != null); + library.setAttribute("name", nameChild.getAttributeValue("value")); + + processLibraryRootContainer(oldLibrary, library, "CLASSES", "classPath"); + processLibraryRootContainer(oldLibrary, library, "JAVADOC", "javadocPath"); + processLibraryRootContainer(oldLibrary, library, "SOURCES", "sourcePath"); + return library; + } + + private static void processLibraryRootContainer(Element oldLibrary, + final Element library, + String newElementType, + String oldElementType) { + final Element elementCLASSES = new Element(newElementType); + final Element rootsElement = oldLibrary.getChild("roots"); + final Element classPath = rootsElement.getChild(oldElementType); + if (classPath != null) { + processRootTypeElement(classPath, new SimpleRootProcessor(elementCLASSES)); + } + library.addContent(elementCLASSES); + } + + private static void convertProjectFile(Element root, String filePath, ArrayList conversionProblems) { + Element rootComponent = null; + List components = root.getChildren("component"); + for (Iterator iterator = components.iterator(); iterator.hasNext();) { + Element component = (Element)iterator.next(); + if (isProjectRootManager(component)) rootComponent = component; + } + + if (rootComponent == null) return; + + Element module = createModule(root); + + final String moduleFilePath = filePath.substring(0, filePath.lastIndexOf('.')) + ".iml"; + + Element moduleRootComponent = convertProjectRootManager(rootComponent, conversionProblems); + module.addContent(moduleRootComponent); + + Document moduleDoc = new Document(module); + + try { + JDOMUtil.writeDocument(moduleDoc, moduleFilePath, "\n"); + } + catch (IOException e) { + LOG.error(e); + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(moduleFilePath)); + } + }); + + rootComponent.setAttribute("name", "ProjectRootManager"); + rootComponent.setAttribute("version", "4"); + + Element moduleManager = new Element("component"); + moduleManager.setAttribute("name", "ProjectModuleManager"); + addModule(moduleFilePath, moduleManager); + + String moduleFile = new File(moduleFilePath).getName(); + convertWebApps(moduleManager, root, rootComponent, moduleFile.substring(0, moduleFile.lastIndexOf('.'))); + root.addContent(moduleManager); + } + + private static Element createModule(Element root) { + Element module = new Element("module"); + module.setAttribute("version", "4"); + String relativePaths = root.getAttributeValue("relativePaths"); + if (relativePaths != null) { + module.setAttribute("relativePaths", relativePaths); + } + return module; + } + + private static void convertWebApps(Element moduleManager, Element projectElement, Element projectRootManager, String mainModule) { + Element webRootContainer = findNamedChild(projectElement, "component", "WebRootContainer"); + if(webRootContainer == null) return; + List roots = webRootContainer.getChildren("root"); + + for (Iterator iterator = roots.iterator(); iterator.hasNext();) { + Element root = (Element)iterator.next(); + String name = root.getAttributeValue("name"); + String url = root.getAttributeValue("url"); + + if(name == null || url == null) continue; + + String filepath = VirtualFileManager.extractPath(url); + + VirtualFile moduleDirectory = LocalFileSystem.getInstance().findFileByPath(filepath); + if(moduleDirectory != null) { + Element module = createModule(projectElement); + module.setAttribute("type", "J2EE_WEB_MODULE"); + + Element rootManager = createWebModuleRootManager(module, moduleDirectory, projectRootManager, mainModule); + module.addContent(rootManager); + + Element buildComponent = createWebModuleBuildComponent(); + module.addContent(buildComponent); + + Element moduleProperties = createWebModuleProperties(moduleDirectory); + module.addContent(moduleProperties); + + Document moduleDocument = new Document(module); + String moduleName = (!"".equals(name) ? name : moduleDirectory.getName()); + if(moduleName.equals(mainModule)) moduleName = "web" + moduleName; + try { + final String modulePath = moduleDirectory.getPath() + "/" + moduleName + ".iml"; + JDOMUtil.writeDocument(moduleDocument, modulePath, "\n"); + addModule(modulePath, moduleManager); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(modulePath)); + } + }); + + } + catch (IOException e) { + LOG.error(e); + } + } + } + } + + private static void addSetting(Element parent, String name, String value){ + Element option = new Element("setting"); + option.setAttribute("name", name); + option.setAttribute("value", value); + parent.addContent(option); + } + + private static Element createWebModuleProperties(VirtualFile moduleDirectory) { + Element component = new Element("component"); + component.setAttribute("name", "WebModuleProperties"); + + J2EEDeploymentDescriptorBase webXml = new J2EEDeploymentDescriptorBase(null, DeploymentDescriptorsConstants.WEB_XML_DEPLOYMENT_DESCRIPTOR); + webXml.setUrl("file://$MODULE_DIR$/WEB-INF/web.xml"); + try { + webXml.writeExternal(component); + webXml.dispose(); + } + catch (WriteExternalException e) { + LOG.error(e); + } + + Element webRoots = new Element("webroots"); + component.addContent(webRoots); + Element root = new Element("root"); + webRoots.addContent(root); + try { + new WebRoot(moduleDirectory, "/").writeExternal(root); + } + catch (WriteExternalException e) { + LOG.error(e); + } + return component; + } + + private static Element createWebModuleBuildComponent() { + Element component = new Element("component"); + component.setAttribute("name", "WebModuleBuildComponent"); + + addSetting(component, "EXPLODED_URL", "file://$MODULE_DIR$"); + addSetting(component, "EXPLODED_ENABLED", "true"); + + return component; + } + + private static Element createWebModuleRootManager(Element module, VirtualFile moduleDirectory, Element projectRootManager, String mainModule) { + Element newModuleRootManager = new Element("component"); + newModuleRootManager.setAttribute("name", "NewModuleRootManager"); + + Element jdk = projectRootManager.getChild("jdk"); + if(jdk != null) { + String jdkName = jdk.getAttributeValue("name"); + if (jdkName != null) { + Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "jdk"); + orderEntry.setAttribute("jdkName", jdkName); + newModuleRootManager.addContent(orderEntry); + } + } + + Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "module"); + orderEntry.setAttribute("module-name", mainModule); + newModuleRootManager.addContent(orderEntry); + + Element output = new Element("output"); + output.setAttribute("url", "file://" + getModulePath("classes", module, moduleDirectory.getPath())); + newModuleRootManager.addContent(output); + + Element content = new Element("content"); + content.setAttribute("url", "file://" + getModulePath("", module, moduleDirectory.getPath())); + newModuleRootManager.addContent(content); + + VirtualFile classesDir = moduleDirectory.findFileByRelativePath("WEB-INF/classes"); + if(classesDir != null) { + Element classes = createLibraryEntry(classesDir, module, moduleDirectory); + newModuleRootManager.addContent(classes); + } + + VirtualFile lib = moduleDirectory.findFileByRelativePath("WEB-INF/lib"); + if(lib != null) { + String modulePath = moduleDirectory.getPath(); + VirtualFile[] libs = lib.getChildren(); + for (int i = 0; i < libs.length; i++) { + VirtualFile virtualFile = libs[i]; + Element libEntry = createLibraryEntry(virtualFile, module, moduleDirectory); + newModuleRootManager.addContent(libEntry); + } + } + + return newModuleRootManager; + } + + private static Element createLibraryEntry(VirtualFile file, Element module, VirtualFile moduleDirectory) { + String path = file.getPath().substring(moduleDirectory.getPath().length() + 1); + if(file.getFileSystem() instanceof JarFileSystem) { + path = path + "!/"; + } + + Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "module-library"); + Element library = new Element("library"); + orderEntry.addContent(library); + Element classes = new Element("CLASSES"); + library.addContent(classes); + Element root = new Element("root"); + root.setAttribute("url", "file://" + getModulePath(path, module, moduleDirectory.getPath())); + classes.addContent(root); + return orderEntry; + } + + private static String getModulePath(String path, Element module, String moduleDirectory) { + return "".equals(path) ? moduleDirectory : moduleDirectory + "/" + path; + } + + private static void addModule(final String moduleFilePath, Element moduleManager) { + Element moduleEntry = new Element("module"); + final String moduleVfsPath = moduleFilePath.replace(File.separatorChar, '/'); + moduleEntry.setAttribute("filepath", moduleVfsPath); + moduleEntry.setAttribute("fileurl", "file://" +moduleVfsPath); + Element modulesEntry = moduleManager.getChild("modules"); + if(modulesEntry == null) { + modulesEntry = new Element("modules"); + moduleManager.addContent(modulesEntry); + } + modulesEntry.addContent(moduleEntry); + } + + private static Element convertProjectRootManager(Element projectRootManager, ArrayList conversionProblems) { + return new ProjectToModuleConverter(projectRootManager, conversionProblems).getModuleRootManager(); + } + + private static interface RootElementProcessor { + void processSimpleRoot(Element root); + + void processJdkRoot(Element root); + + void processOutputRoot(Element root); + + void processExcludedOutputRoot(Element root); + + void processLibraryRoot(Element root); + + void processEjbRoot(Element root); + } + + private static abstract class EmptyRootProcessor implements RootElementProcessor { + public void processSimpleRoot(Element root) { + cannotProcess(root); + } + + public void processJdkRoot(Element root) { + cannotProcess(root); + } + + public void processOutputRoot(Element root) { + cannotProcess(root); + } + + public void processExcludedOutputRoot(Element root) { + cannotProcess(root); + } + + public void processLibraryRoot(Element root) { + cannotProcess(root); + } + + public void processEjbRoot(Element root) { + cannotProcess(root); + } + + protected void cannotProcess(Element root) { + LOG.error("Cannot process roots of type " + root.getAttributeValue("type") + " in " + classId()); + } + + abstract protected String classId(); + + } + + private static void processRoot(Element root, RootElementProcessor processor) { + LOG.assertTrue("root".equals(root.getName())); + final String type = root.getAttributeValue("type"); + LOG.assertTrue(type != null); + if (ProjectRootUtil.SIMPLE_ROOT.equals(type)) { + processor.processSimpleRoot(root); + } + else if (ProjectRootUtil.OUTPUT_ROOT.equals(type)) { + processor.processOutputRoot(root); + } + else if (ProjectRootUtil.JDK_ROOT.equals(type)) { + processor.processJdkRoot(root); + } + else if (ProjectRootUtil.EXCLUDED_OUTPUT.equals(type)) { + processor.processExcludedOutputRoot(root); + } + else if (ProjectRootUtil.LIBRARY_ROOT.equals(type)) { + processor.processLibraryRoot(root); + } + else if (ProjectRootUtil.EJB_ROOT.equals(type)) { + processor.processEjbRoot(root); + } + else if (ProjectRootUtil.COMPOSITE_ROOT.equals(type)) { + final List children = root.getChildren("root"); + for (int i = 0; i < children.size(); i++) { + Element element = (Element)children.get(i); + processRoot(element, processor); + } + } + else { + LOG.error("Unknown root type: " + type); + } + } + + private static void processRootTypeElement(Element rootTypeElement, RootElementProcessor rootProcessor) { + if (rootTypeElement == null) return; + final List children = rootTypeElement.getChildren("root"); + for (int i = 0; i < children.size(); i++) { + Element element = (Element)children.get(i); + processRoot(element, rootProcessor); + } + } + + + private static class ProjectToModuleConverter { + private final Element myProjectRootManager; + private final Element myModuleRootManager; + private final ArrayList myProjectRoots; + private final List mySourceFolders; + private final ArrayList myExcludeFolders; + private final ArrayList myDetectedProblems; + + private ProjectToModuleConverter(Element projectRootManager, ArrayList problems) { + myProjectRootManager = projectRootManager; + myModuleRootManager = new Element("component"); + myModuleRootManager.setAttribute("name", "NewModuleRootManager"); + myProjectRoots = new ArrayList(); + myDetectedProblems = problems; + + final Element projectPath = projectRootManager.getChild("projectPath"); + if(projectPath != null) { + processRootTypeElement(projectPath, new ProjectRootProcessor()); + } + Collections.sort(myProjectRoots); + for (int i = 0; i < myProjectRoots.size(); i++) { + String path = myProjectRoots.get(i); + final int next = i + 1; + while (next < myProjectRoots.size() && myProjectRoots.get(next).startsWith(path)) { + myProjectRoots.remove(next); + } + } + + final Element sourcePath = projectRootManager.getChild("sourcePath"); + mySourceFolders = new ArrayList(); + processRootTypeElement(sourcePath, new SourceRootProcessor()); + + final Element excludePath = projectRootManager.getChild("excludePath"); + myExcludeFolders = new ArrayList(); + processRootTypeElement(excludePath, new ExcludeRootsProcessor()); + + Element javadocPath = projectRootManager.getChild("javadocPath"); + processRootTypeElement(javadocPath, new JavaDocRootProcessor()); + + final Element patternExcludeFolder = new Element("excludeFolder"); + final Element patternSourceFolder = new Element("sourceFolder"); + patternSourceFolder.setAttribute("isTestSource", "false"); + Map> contentToSource = dispatchFolders(myProjectRoots, mySourceFolders); + final Map> contentToExclude = dispatchFolders(myProjectRoots, myExcludeFolders); + + for (Iterator iterator = myProjectRoots.iterator(); iterator.hasNext();) { + String root = iterator.next(); + final Element contentElement = new Element("content"); + contentElement.setAttribute("url", root); + createFolders(contentElement, patternSourceFolder, contentToSource.get(root)); + createFolders(contentElement, patternExcludeFolder, contentToExclude.get(root)); + myModuleRootManager.addContent(contentElement); + } + + final Element classPath = projectRootManager.getChild("classPath"); + processRootTypeElement(classPath, new ClassPathRootProcessor()); + + final Element projectElement = myProjectRootManager.getParent(); + final Element compilerConfigurationElement = findNamedChild(projectElement, "component", "CompilerConfiguration"); + if (compilerConfigurationElement != null) { + final Element option = findNamedChild(compilerConfigurationElement, "option", "DEFAULT_OUTPUT_PATH"); + final String path = option == null ? null : option.getAttributeValue("value"); + + if (path != null) { + final String url = "file://" + path; + final Element outputElement = new Element("output"); + outputElement.setAttribute("url", url); + myModuleRootManager.addContent(outputElement); + final Element outputTestElement = new Element("output-test"); + outputTestElement.setAttribute("url", url); + myModuleRootManager.addContent(outputTestElement); + } + // check for multiple outputs + { + final Element outputMode = findNamedChild(compilerConfigurationElement, "option", "OUTPUT_MODE"); + final String attributeValue = outputMode != null ? outputMode.getAttributeValue("value") : ""; + if ("multiple".equals(attributeValue)) { + addProblem(MULTIPLE_OUTPUT_PATHS); + } + } + } + + final Element excludeOutput = myProjectRootManager.getChild("exclude_output"); + if (excludeOutput != null) { + final String enabled = excludeOutput.getAttributeValue("enabled"); + if ("yes".equals(enabled) || "true".equals(enabled)) { + myModuleRootManager.addContent(new Element("exclude-output")); + } + } + } + + private void createFolders(final Element contentElement, + final Element patternFolderElement, + final List folders) { + for (Iterator iterator1 = folders.iterator(); iterator1.hasNext();) { + String folder = iterator1.next(); + + Element folderElement = (Element)patternFolderElement.clone(); + folderElement.setAttribute("url", folder); + contentElement.addContent(folderElement); + } + } + + private Map> dispatchFolders(ArrayList projectRoots, List folders) { + final Map> result = new HashMap>(); + for (Iterator iterator = projectRoots.iterator(); iterator.hasNext();) { + String root = iterator.next(); + final ArrayList foldersForRoot = new ArrayList(); + result.put(root, foldersForRoot); + for (Iterator iterator1 = folders.iterator(); iterator1.hasNext();) { + String folder = iterator1.next(); + if (folder.startsWith(root)) { + foldersForRoot.add(folder); + } + } + Collections.sort(foldersForRoot); + } + return result; + } + + public Element getModuleRootManager() { return myModuleRootManager; } + + private class JavaDocRootProcessor extends EmptyRootProcessor { + + protected void cannotProcess(Element root) { + addProblem(JAVA_DOC_ROOTS_CANNOT_BE_CONVERTED); + } + + protected String classId() { + return "JavaDocRootProcessor"; + } + } + + private class ProjectRootProcessor extends EmptyRootProcessor { + public void processSimpleRoot(Element root) { + final String value = root.getAttributeValue("url"); + myProjectRoots.add(value); + } + + public void processEjbRoot(Element root) { + // todo[cdr,dsl] implement conversion of EJB roots + } + + protected String classId() { + return "ProjectRootProcessor"; + } + } + + private void addProblem(final String description) { + if (!myDetectedProblems.contains(description)) { + myDetectedProblems.add(description); + } + } + + private class SourceRootProcessor extends EmptyRootProcessor { + + public void processSimpleRoot(Element root) { + final String url = root.getAttributeValue("url"); + boolean found = false; + for (int i = 0; i < myProjectRoots.size(); i++) { + String projectPath = myProjectRoots.get(i); + if (url.startsWith(projectPath)) { + mySourceFolders.add(url); + found = true; + break; + } + else if (projectPath.startsWith(url)) { + myProjectRoots.remove(i); + myProjectRoots.add(i, url); + mySourceFolders.add(url); + found = true; + break; + } + } + if (!found) { + addProblem(SOURCE_ROOTS_NOT_UNDER_PROJECT_ROOTS); + } + } + + public void processJdkRoot(Element root) { + } + + public void processLibraryRoot(Element root) { + } + + public void processEjbRoot(Element root) { + // todo[cdr,dsl] implement conversion of EJB roots + } + + protected String classId() { + return "SourceRootProcessor"; + } + } + + private class ExcludeRootsProcessor extends EmptyRootProcessor { + public void processSimpleRoot(Element root) { + final String url = root.getAttributeValue("url"); + for (int i = 0; i < myProjectRoots.size(); i++) { + String projectRoot = myProjectRoots.get(i); + if (url.startsWith(projectRoot)) { + myExcludeFolders.add(url); + } + } + } + + public void processEjbRoot(Element root) { + // todo[cdr,dsl] implement conversion of EJB roots + } + + protected String classId() { + return "ExcludeRootsProcessor"; + } + + public void processJdkRoot(Element root) { + // [dsl]: fix for SCR24517 + // [dsl]: I have no idea how such project can be configured in Ariadna, + // [dsl]: and what does it mean, but such projects do exist.... + } + + public void processExcludedOutputRoot(Element root) { + } + } + + private class ClassPathRootProcessor extends EmptyRootProcessor { + public void processSimpleRoot(Element root) { + final Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "module-library"); + final Element libraryElement = new Element("library"); + final Element classesElement = new Element("CLASSES"); + final Element rootElement = new Element("root"); + rootElement.setAttribute((Attribute)root.getAttribute("url").clone()); + classesElement.addContent(rootElement); + libraryElement.addContent(classesElement); + orderEntry.addContent(libraryElement); + myModuleRootManager.addContent(orderEntry); + } + + public void processJdkRoot(Element root) { + final Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "jdk"); + orderEntry.setAttribute("jdkName", root.getAttributeValue("name")); + myModuleRootManager.addContent(orderEntry); + } + + public void processLibraryRoot(Element root) { + final String libraryName = root.getAttributeValue("name"); + final Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "library"); + orderEntry.setAttribute("name", libraryName); + orderEntry.setAttribute("level", LibraryTablesRegistrar.APPLICATION_LEVEL); + myModuleRootManager.addContent(orderEntry); + } + + public void processEjbRoot(Element root) { + // todo[cdr,dsl] implement conversion of EJB roots + } + + protected String classId() { + return "ClassPathProcessor"; + } + + public void processOutputRoot(Element root) { + final Element orderEntry = new Element("orderEntry"); + orderEntry.setAttribute("type", "sourceFolder"); + myModuleRootManager.addContent(orderEntry); + } + } + } + + private static boolean isProjectRootManager(Element component) { + String compName = component.getAttributeValue("name"); + String compClass = component.getAttributeValue("class"); + return compName != null && compName.equals(PROJECT_ROOT_MANAGER) || + compClass != null && compClass.equals(PROJECT_ROOT_MANAGER_CLASS); + } + + private static Element findNamedChild(Element root, String name, String nameAttributeValue) { + final List children = root.getChildren(name); + for (int i = 0; i < children.size(); i++) { + Element e = (Element)children.get(i); + if (nameAttributeValue.equals(e.getAttributeValue("name"))) { + return e; + } + } + return null; + } + + private static class SimpleRootProcessor extends EmptyRootProcessor { + private final Element myTargetElement; + + public SimpleRootProcessor(Element targetElement) { + myTargetElement = targetElement; + } + + public void processSimpleRoot(Element root) { + final String url = root.getAttributeValue("url"); + final Element newRoot = new Element("root"); + newRoot.setAttribute("url", url); + myTargetElement.addContent(newRoot); + } + + public void processEjbRoot(Element root) { + // todo[cdr,dsl] implement conversion of EJB roots + } + + protected String classId() { + return "SimpleRootProcessor"; + } + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Util.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Util.java new file mode 100644 index 00000000000..941ecdad361 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/project/impl/convertors/Util.java @@ -0,0 +1,18 @@ +package com.intellij.openapi.project.impl.convertors; + +import org.jdom.Element; + +import java.util.Iterator; + +class Util { + static Element findComponent(Element root, String className) { + for (Iterator iterator = root.getChildren("component").iterator(); iterator.hasNext();) { + Element element = (Element)iterator.next(); + String className1 = element.getAttributeValue("class"); + if (className1 != null && className1.equals(className)) { + return element; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/PathUtilEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/PathUtilEx.java new file mode 100644 index 00000000000..968b7cf6f79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/PathUtilEx.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.projectRoots.ex; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.rt.compiler.JavacRunner; +import com.intellij.util.PathUtil; +import com.intellij.util.PathsList; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.ComparatorUtil; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.FilteringIterator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * @author Eugene Zhuravlev + * Date: Apr 14, 2004 + */ +public class PathUtilEx { + private static final Convertor MODULE_JDK = new Convertor() { + public ProjectJdk convert(Module module) { + return ModuleRootManager.getInstance(module).getJdk(); + } + }; + private static final Convertor JDK_VERSION = new Convertor() { + public String convert(ProjectJdk jdk) { + return jdk.getVersionString(); + } + }; + + public static void addRtJar(PathsList pathsList) { + final String ideaRtJarPath = getIdeaRtJarPath(); + if (Boolean.getBoolean("idea.prepend.rtjar")) { + pathsList.addFirst(ideaRtJarPath); + } + else { + pathsList.addTail(ideaRtJarPath); + } + } + + public static String getIdeaRtJarPath() { + final Class aClass = JavacRunner.class; + return PathUtil.getJarPathForClass(aClass); + } + + public static ProjectJdk getAnyJdk(Project project) { + return chooseJdk(project, Arrays.asList(ModuleManager.getInstance(project).getModules())); + } + + public static ProjectJdk chooseJdk(Project project, Collection modules) { + ProjectJdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk(); + if (projectJdk != null) { + return projectJdk; + } + return chooseJdk(modules); + } + + public static ProjectJdk chooseJdk(Collection modules) { + ArrayList jdks = CollectUtil.SKIP_NULLS.toList(FilteringIterator.skipNulls(modules.iterator()), MODULE_JDK); + if (jdks.size() == 0) { + return null; + } + Collections.sort(jdks, ComparatorUtil.compareBy(JDK_VERSION, String.CASE_INSENSITIVE_ORDER)); + return jdks.get(jdks.size() - 1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRoot.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRoot.java new file mode 100644 index 00000000000..b8701691be3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRoot.java @@ -0,0 +1,13 @@ +package com.intellij.openapi.projectRoots.ex; + +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author mike + */ +public interface ProjectRoot { + boolean isValid(); + VirtualFile[] getVirtualFiles(); + String getPresentableString(); + void update(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRootContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRootContainer.java new file mode 100644 index 00000000000..801e4fb3161 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ex/ProjectRootContainer.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jul 16, 2002 + * Time: 7:14:37 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.openapi.projectRoots.ex; + +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.vfs.VirtualFile; + +public interface ProjectRootContainer { + VirtualFile[] getRootFiles(ProjectRootType type); + ProjectRoot[] getRoots(ProjectRootType type); + + void startChange(); + void finishChange(); + + ProjectRoot addRoot(VirtualFile virtualFile, ProjectRootType type); + void addRoot(ProjectRoot root, ProjectRootType type); + void removeRoot(ProjectRoot root, ProjectRootType type); + void removeAllRoots(ProjectRootType type); + + void removeAllRoots(); + + void removeRoot(VirtualFile root, ProjectRootType type); + + void update(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/CompositeProjectRoot.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/CompositeProjectRoot.java new file mode 100644 index 00000000000..f5976665e21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/CompositeProjectRoot.java @@ -0,0 +1,97 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.projectRoots.ex.ProjectRoot; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * @author mike + */ +class CompositeProjectRoot implements ProjectRoot { + private List myRoots = new ArrayList(); + + ProjectRoot[] getProjectRoots() { + return (ProjectRoot[])myRoots.toArray(new ProjectRoot[myRoots.size()]); + } + + public String getPresentableString() { + throw new UnsupportedOperationException(); + } + + public VirtualFile[] getVirtualFiles() { + List result = new ArrayList(); + for (Iterator iterator = myRoots.iterator(); iterator.hasNext();) { + ProjectRoot root = (ProjectRoot)iterator.next(); + result.addAll(Arrays.asList(root.getVirtualFiles())); + } + + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + public boolean isValid() { + return true; + } + + void remove(ProjectRoot root) { + myRoots.remove(root); + } + + ProjectRoot add(VirtualFile virtualFile) { + final SimpleProjectRoot root = new SimpleProjectRoot(virtualFile); + myRoots.add(root); + return root; + } + + void add(ProjectRoot root) { + myRoots.add(root); + } + + void remove(VirtualFile root) { + for (Iterator iterator = myRoots.iterator(); iterator.hasNext();) { + ProjectRoot projectRoot = (ProjectRoot)iterator.next(); + if (projectRoot instanceof SimpleProjectRoot) { + SimpleProjectRoot r = (SimpleProjectRoot)projectRoot; + if (r.getFile() != null && r.getFile().equals(root)) { + iterator.remove(); + } + } + } + } + + void clear() { + myRoots.clear(); + } + + public void readExternal(Element element) throws InvalidDataException { + final List children = element.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element e = (Element)iterator.next(); + myRoots.add(ProjectRootUtil.read(e)); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (Iterator iterator = myRoots.iterator(); iterator.hasNext();) { + ProjectRoot root = (ProjectRoot)iterator.next(); + final Element e = ProjectRootUtil.write(root); + if (e != null) { + element.addContent(e); + } + } + } + + public void update() { + for (Iterator iterator = myRoots.iterator(); iterator.hasNext();) { + ProjectRoot root = (ProjectRoot)iterator.next(); + root.update(); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java new file mode 100644 index 00000000000..5ace15aeced --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.projectRoots.*; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.jar.JarFileSystemEx; +import org.jdom.Element; + +import javax.swing.*; +import java.io.*; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Eugene Zhuravlev + * Date: Sep 17, 2004 + */ +public class JavaSdkImpl extends JavaSdk { + // do not use javaw.exe for Windows because of issues with encoding + private static final String VM_EXE_NAME = "java"; + private final Pattern myVersionStringPattern = Pattern.compile("^(.*)java version \"([1234567890_.]*)\"(.*)$"); + public static final Icon ICON = IconLoader.getIcon("/nodes/ppJdkClosed.png"); + private static final Icon JDK_ICON_EXPANDED = IconLoader.getIcon("/nodes/ppJdkOpen.png"); + private static final Icon ADD_ICON = IconLoader.getIcon("/general/addJdk.png"); + private final JarFileSystem myJarFileSystem; + + public JavaSdkImpl(JarFileSystem jarFileSystem) { + super("JavaSDK"); + myJarFileSystem = jarFileSystem; + } + + public String getPresentableName() { + return "JSDK"; + } + + public Icon getIcon() { + return ICON; + } + + public Icon getIconForExpandedTreeNode() { + return JDK_ICON_EXPANDED; + } + + public Icon getIconForAddAction() { + return ADD_ICON; + } + + public AdditionalDataConfigurable createAdditionalDataConfigurable(SdkModel sdkModel, SdkModificator sdkModificator) { + return null; + } + + public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) { + } + + public SdkAdditionalData loadAdditionalData(Element additional) { + return null; + } + + public String getBinPath(Sdk sdk) { + return getConvertedHomePath(sdk) + "bin"; + } + + public String getToolsPath(Sdk sdk) { + final String versionString = sdk.getVersionString(); + final boolean isJdk1_x = versionString.indexOf("1.0") > -1 || versionString.indexOf("1.1") > -1; + return getConvertedHomePath(sdk) + "lib" + File.separator + (isJdk1_x? "classes.zip" : "tools.jar"); + } + + public String getVMExecutablePath(Sdk sdk) { + /* + if ("64".equals(System.getProperty("sun.arch.data.model"))) { + return getBinPath(sdk) + File.separator + System.getProperty("os.arch") + File.separator + VM_EXE_NAME; + } + */ + return getBinPath(sdk) + File.separator + VM_EXE_NAME; + } + + public String getRtLibraryPath(Sdk sdk) { + return getConvertedHomePath(sdk) + "jre" + File.separator + "lib" + File.separator + "rt.jar"; + } + + private String getConvertedHomePath(Sdk sdk) { + String path = sdk.getHomePath().replace('/', File.separatorChar); + if (!path.endsWith(File.separator)) { + path = path + File.separator; + } + return path; + } + + public boolean isValidSdkHome(String path) { + return checkForJdk(new File(path)); + } + + public String suggestSdkName(String currentSdkName, String sdkHome) { + final String suggestedName; + if (currentSdkName != null && currentSdkName.length() > 0) { + final Matcher matcher = myVersionStringPattern.matcher(currentSdkName); + final boolean replaceNameWithVersion = matcher.matches(); + if (replaceNameWithVersion){ + // user did not change name -> set it automatically + final String versionString = getVersionString(sdkHome); + suggestedName = (versionString == null)? currentSdkName : matcher.replaceFirst("$1" + versionString + "$3"); + } + else { + suggestedName = currentSdkName; + } + } + else { + final String versionString = getVersionString(sdkHome); + suggestedName = (versionString == null)? "Unknown" : versionString; + } + return suggestedName; + } + + public void setupSdkPaths(Sdk sdk) { + final File jdkHome = new File(sdk.getHomePath()); + VirtualFile[] classes = findClasses(jdkHome, false, JarFileSystem.getInstance()); + VirtualFile sources = findSources(jdkHome); + VirtualFile docs = findDocs(jdkHome); + + final SdkModificator sdkModificator = sdk.getSdkModificator(); + for (int i = 0; i < classes.length; i++){ + sdkModificator.addRoot(classes[i], ProjectRootType.CLASS); + } + if(sources != null){ + sdkModificator.addRoot(sources, ProjectRootType.SOURCE); + } + if(docs != null){ + sdkModificator.addRoot(docs, ProjectRootType.JAVADOC); + } + sdkModificator.commitChanges(); + } + + public final String getVersionString(final String sdkHome) { + String versionString = getVersionStringImpl(sdkHome); + if (versionString != null && versionString.length() == 0) { + versionString = null; + } + if (versionString == null){ + Messages.showMessageDialog("Probably JDK installed in '" + sdkHome + "' is corrupt", "Cannot Detect JDK Version", Messages.getErrorIcon()); + } + return versionString; + } + + + public String getComponentName() { + return getName(); + } + + public void initComponent() { } + + public void disposeComponent() { + } + + private static String getVersionStringImpl(String homePath){ + if (homePath == null || !new File(homePath).exists()) { + return null; + } + final String[] versionString = new String[1]; + try { + Process process = Runtime.getRuntime().exec(new String[] {homePath + File.separator + "bin" + File.separator + "java", "-version"}); + VersionParsingThread parsingThread = new VersionParsingThread(process.getErrorStream(), versionString); + parsingThread.start(); + ReadStreamThread readThread = new ReadStreamThread(process.getInputStream()); + readThread.start(); + try { + try { + process.waitFor(); + } + catch (InterruptedException e) { + e.printStackTrace(); + process.destroy(); + } + } + finally { + try { + parsingThread.join(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + catch (IOException ex) { + ex.printStackTrace(); + } + return versionString[0]; + } + + public ProjectJdk createJdk(final String jdkName, String jdkHome) { + ProjectJdkImpl jdk = new ProjectJdkImpl(jdkName, this); + SdkModificator sdkModificator = jdk.getSdkModificator(); + + String path = jdkHome.replace(File.separatorChar, '/'); + sdkModificator.setHomePath(path); + jdk.setVersionString(jdkName); // must be set after home path, otherwise setting home path clears the version string + + File jdkHomeFile = new File(jdkHome); + addClasses(jdkHomeFile, sdkModificator, true, myJarFileSystem); + addSources(jdkHomeFile, sdkModificator); + addDocs(jdkHomeFile, sdkModificator); + sdkModificator.commitChanges(); + return jdk; + } + + public static ProjectJdk getMockJdk(String versionName) { + final String forcedPath = System.getProperty("idea.testingFramework.mockJDK"); + String jdkHome = forcedPath != null ? forcedPath : PathManager.getHomePath() + File.separator + "mockJDK"; + return createMockJdk(jdkHome, versionName, getInstance()); + } + + public static ProjectJdk getMockJdk15(String versionName) { + String jdkHome = PathManager.getHomePath() + File.separator + "mockJDK-1.5"; + return createMockJdk(jdkHome, versionName, getInstance()); + } + + private static ProjectJdk createMockJdk(String jdkHome, final String versionName, JavaSdk javaSdk) { + File jdkHomeFile = new File(jdkHome); + if (!jdkHomeFile.exists()) return null; + + final ProjectJdk jdk = new ProjectJdkImpl(versionName, javaSdk); + final SdkModificator sdkModificator = jdk.getSdkModificator(); + + String path = jdkHome.replace(File.separatorChar, '/'); + sdkModificator.setHomePath(path); + sdkModificator.setVersionString(versionName); // must be set after home path, otherwise setting home path clears the version string + + addSources(jdkHomeFile, sdkModificator); + addClasses(jdkHomeFile, sdkModificator, false, JarFileSystem.getInstance()); + addClasses(jdkHomeFile, sdkModificator, true, JarFileSystem.getInstance()); + sdkModificator.commitChanges(); + + return jdk; + } + + private static void addClasses(File file, SdkModificator sdkModificator, final boolean isJre, JarFileSystem jarFileSystem) { + VirtualFile[] classes = findClasses(file, isJre, jarFileSystem); + for (int i = 0; i < classes.length; i++) { + VirtualFile virtualFile = classes[i]; + sdkModificator.addRoot(virtualFile, ProjectRootType.CLASS); + } + } + + public static VirtualFile[] findClasses(File file, boolean isJre, JarFileSystem jarFileSystem) { + FileFilter jarFileFilter = new FileFilter(){ + public boolean accept(File f){ + if (f.isDirectory()) return false; + if (f.getName().endsWith(".jar")) return true; + return false; + } + }; + + File[] jarDirs; + if(SystemInfo.isMac && !ApplicationManager.getApplication().isUnitTestMode()){ + File libFile = new File(file, "lib"); + File classesFile = new File(file, "../Classes"); + File libExtFile = new File(libFile, "ext"); + jarDirs = new File[]{libFile, classesFile, libExtFile}; + } + else{ + File jreLibFile = isJre ? new File(file, "lib") : new File(new File(file, "jre"), "lib"); + File jreLibExtFile = new File(jreLibFile, "ext"); + jarDirs = new File[]{jreLibFile, jreLibExtFile}; + } + + ArrayList childrenList = new ArrayList(); + for (int i = 0; i < jarDirs.length; i++){ + File jarDir = jarDirs[i]; + if ((jarDir != null) && jarDir.isDirectory()){ + File[] files = jarDir.listFiles(jarFileFilter); + for (int j = 0; j < files.length; j++){ + childrenList.add(files[j]); + } + } + } + + ArrayList result = new ArrayList(); + for (int i = 0; i < childrenList.size(); i++){ + File child = (File)childrenList.get(i); + String path = child.getAbsolutePath().replace(File.separatorChar, '/') + JarFileSystem.JAR_SEPARATOR; + ((JarFileSystemEx)jarFileSystem).setNoCopyJarForPath(path); + VirtualFile vFile = jarFileSystem.findFileByPath(path); + if (vFile != null){ + result.add(vFile); + } + } + + File classesZipFile = new File(new File(file, "lib"), "classes.zip"); + if((!classesZipFile.isDirectory()) && classesZipFile.exists()){ + String path = classesZipFile.getAbsolutePath().replace(File.separatorChar, '/') + JarFileSystem.JAR_SEPARATOR; + ((JarFileSystemEx)jarFileSystem).setNoCopyJarForPath(path); + VirtualFile vFile = jarFileSystem.findFileByPath(path); + if (vFile != null){ + result.add(vFile); + } + } + + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + private static void addSources(File file, SdkModificator sdkModificator) { + VirtualFile vFile = findSources(file); + if (vFile != null) { + sdkModificator.addRoot(vFile, ProjectRootType.SOURCE); + } + } + + public static VirtualFile findSources(File file) { + File srcfile = new File(file, "src"); + File jarfile = new File(file, "src.jar"); + if (!jarfile.exists()) { + jarfile = new File(file, "src.zip"); + } + + if (jarfile.exists()) { + JarFileSystemEx jarFileSystem = (JarFileSystemEx)JarFileSystem.getInstance(); + String path = jarfile.getAbsolutePath().replace(File.separatorChar, '/') + JarFileSystem.JAR_SEPARATOR + "src"; + jarFileSystem.setNoCopyJarForPath(path); + VirtualFile vFile = jarFileSystem.findFileByPath(path); + if (vFile != null) return vFile; + // try 1.4 format + path = jarfile.getAbsolutePath().replace(File.separatorChar, '/') + JarFileSystem.JAR_SEPARATOR; + jarFileSystem.setNoCopyJarForPath(path); + vFile = jarFileSystem.findFileByPath(path); + return vFile; + } + else { + if (!srcfile.exists() || !srcfile.isDirectory()) return null; + String path = srcfile.getAbsolutePath().replace(File.separatorChar, '/'); + VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(path); + return vFile; + } + } + + private static void addDocs(File file, SdkModificator rootContainer) { + VirtualFile vFile = findDocs(file); + if (vFile != null) { + rootContainer.addRoot(vFile, ProjectRootType.JAVADOC); + } + } + + public static VirtualFile findDocs(File file) { + file = new File(file.getAbsolutePath() + File.separator + "docs" + File.separator + "api"); + if (!file.exists() || !file.isDirectory()) return null; + String path = file.getAbsolutePath().replace(File.separatorChar, '/'); + VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(path); + return vFile; + } + + public static boolean checkForJdk(File file) { + file = new File(file.getAbsolutePath() + File.separator + "bin"); + if (!file.exists()) return false; + FileFilter fileFilter = new FileFilter() { + public boolean accept(File f) { + if (f.isDirectory()) return false; + if (f.getName().startsWith("javac")) return true; + if (f.getName().startsWith("javah")) return true; + return false; + } + }; + File[] children = file.listFiles(fileFilter); + return (children != null && children.length >= 2); + } + + private static class ReadStreamThread extends Thread { + private InputStream myStream; + + protected ReadStreamThread(InputStream stream) { + myStream = stream; + } + + public void run() { + try { + while (true) { + int b = myStream.read(); + if (b == -1) break; + } + } + catch (IOException e) { + } + } + } + + private static class VersionParsingThread extends Thread { + private Reader myReader; + private boolean mySkipLF = false; + private String[] myVersionString; + + protected VersionParsingThread(InputStream input, String[] versionString) { + myReader = new InputStreamReader(input); + myVersionString = versionString; + } + + public void run() { + try { + while (true) { + String line = readLine(); + if (line == null) return; + if (line.indexOf("version") >= 0) { + myVersionString[0] = line; + } + } + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private String readLine() throws IOException { + boolean first = true; + StringBuffer buffer = new StringBuffer(); + while (true) { + int c = myReader.read(); + if (c == -1) break; + first = false; + if (c == '\n') { + if (mySkipLF) { + mySkipLF = false; + continue; + } + break; + } + else if (c == '\r') { + mySkipLF = true; + break; + } + else { + mySkipLF = false; + buffer.append((char)c); + } + } + if (first) return null; + String s = buffer.toString(); + //if (Diagnostic.TRACE_ENABLED){ + // Diagnostic.trace(s); + //} + return s; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java new file mode 100644 index 00000000000..2667e3d86d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java @@ -0,0 +1,82 @@ +/** + * @author cdr + */ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.SdkType; +import com.intellij.openapi.projectRoots.SdkAdditionalData; +import com.intellij.openapi.projectRoots.SdkModificator; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.roots.RootProvider; + +import java.io.File; + +/** + * used to override JdkHome location in order to provide correct paths + */ +public final class MockJdkWrapper implements ProjectJdk { + private final String myHomePath; + private final ProjectJdk myDelegate; + + public MockJdkWrapper(String homePath, ProjectJdk delegate) { + myHomePath = homePath; + myDelegate = delegate; + } + + public VirtualFile getHomeDirectory() { + return LocalFileSystem.getInstance().findFileByIoFile(new File(getHomePath())); + } + + public String getHomePath() { + final String homePath = FileUtil.toSystemDependentName(myHomePath == null ? myDelegate.getHomePath() : myHomePath); + return StringUtil.trimEnd(homePath, File.separator); + } + + public SdkType getSdkType() { + return myDelegate.getSdkType(); + } + + public String getName() { + return myDelegate.getName(); + } + + public String getVersionString() { + return myDelegate.getVersionString(); + } + + public String getBinPath() { + return getSdkType().getBinPath(this); + } + + public String getToolsPath() { + return getSdkType().getToolsPath(this); + } + + public String getVMExecutablePath() { + return getSdkType().getVMExecutablePath(this); + } + + public String getRtLibraryPath() { + return getSdkType().getRtLibraryPath(this); + } + + public RootProvider getRootProvider() { + return myDelegate.getRootProvider(); + } + + public Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + public SdkAdditionalData getSdkAdditionalData() { + return null; + } + + public SdkModificator getSdkModificator() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java new file mode 100644 index 00000000000..af0069898a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java @@ -0,0 +1,331 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.*; +import com.intellij.openapi.projectRoots.ex.ProjectRoot; +import com.intellij.openapi.projectRoots.ex.ProjectRootContainer; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.impl.RootProviderBaseImpl; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.util.*; + +public class ProjectJdkImpl implements JDOMExternalizable, ProjectJdk, SdkModificator { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.impl.ProjectJdkImpl"); + private final ProjectRootContainerImpl myRootContainer; + private String myName; + private String myVersionString; + private String myHomePath = ""; + private final MyRootProvider myRootProvider = new MyRootProvider(); + private ProjectJdkImpl myOrigin = null; + private SdkAdditionalData myAdditionalData = null; + private SdkType mySdkType; + + public ProjectJdkImpl(String name, SdkType sdkType) { + mySdkType = sdkType; + myRootContainer = new ProjectRootContainerImpl(true); + myName = name; + myRootContainer.addProjectRootContainerListener(myRootProvider); + } + + public SdkType getSdkType() { + return mySdkType; + } + + public String getName() { + return myName; + } + + public void setName(String name) { + LOG.assertTrue(name != null); + myName = name; + } + + public final void setVersionString(String versionString) { + myVersionString = (versionString == null || "".equals(versionString)) ? null : versionString; + } + + public String getVersionString() { + if (myVersionString == null) { + String homePath = getHomePath(); + if (homePath != null && homePath.length() > 0) { + this.setVersionString(mySdkType.getVersionString(homePath)); + } + } + return myVersionString; + } + + public String getHomePath() { + return myHomePath; + } + + public VirtualFile getHomeDirectory() { + if (myHomePath == null) { + return null; + } + return LocalFileSystem.getInstance().findFileByPath(myHomePath); + } + + public void readExternal(Element element) throws InvalidDataException { + myName = element.getChild("name").getAttributeValue("value"); + final Element typeChild = element.getChild("type"); + final String sdkTypeName = typeChild != null? typeChild.getAttributeValue("value") : null; + if (sdkTypeName != null) { + mySdkType = getSdkTypeByName(sdkTypeName); + } + else { + // assume java sdk by default + mySdkType = JavaSdk.getInstance(); + } + final Element version = element.getChild("version"); + this.setVersionString((version != null) ? version.getAttributeValue("value") : null); + + if (element.getAttribute("version") == null || !"2".equals(element.getAttributeValue("version"))) { + myRootContainer.startChange(); + myRootContainer.readOldVersion(element.getChild("roots")); + final List children = element.getChild("roots").getChildren("root"); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element root = (Element)iterator.next(); + for (Iterator j = root.getChildren("property").iterator(); j.hasNext();) { + Element prop = (Element)j.next(); + if ("type".equals(prop.getAttributeValue("name")) && "jdkHome".equals(prop.getAttributeValue("value"))) { + myHomePath = VirtualFileManager.extractPath(root.getAttributeValue("file")); + } + } + } + myRootContainer.finishChange(); + } + else { + myHomePath = element.getChild("homePath").getAttributeValue("value"); + myRootContainer.readExternal(element.getChild("roots")); + } + + final Element additional = element.getChild("additional"); + myAdditionalData = (additional != null)? mySdkType.loadAdditionalData(additional) : null; + } + + private static SdkType getSdkTypeByName(String sdkTypeName) { + final SdkType[] allSdkTypes = ApplicationManager.getApplication().getComponents(SdkType.class); + for (int idx = 0; idx < allSdkTypes.length; idx++) { + final SdkType type = allSdkTypes[idx]; + if (type.getName().equals(sdkTypeName)) { + return type; + } + } + return UnknownSdkType.getInstance(sdkTypeName); + } + + public void writeExternal(Element element) throws WriteExternalException { + element.setAttribute("version", "2"); + + final Element name = new Element("name"); + name.setAttribute("value", myName); + element.addContent(name); + + if (mySdkType != null) { + final Element sdkType = new Element("type"); + sdkType.setAttribute("value", mySdkType.getName()); + element.addContent(sdkType); + } + + if (myVersionString != null) { + final Element version = new Element("version"); + version.setAttribute("value", myVersionString); + element.addContent(version); + } + + final Element home = new Element("homePath"); + home.setAttribute("value", myHomePath); + element.addContent(home); + + Element roots = new Element("roots"); + myRootContainer.writeExternal(roots); + element.addContent(roots); + + Element additional = new Element("additional"); + if (myAdditionalData != null) { + mySdkType.saveAdditionalData(myAdditionalData, additional); + } + element.addContent(additional); + } + + public void setHomePath(String path) { + final boolean changes = myHomePath == null? path != null : !myHomePath.equals(path); + myHomePath = path; + if (changes) { + myVersionString = null; // clear cached value if home path changed + } + } + + public final String getBinPath() { + return mySdkType.getBinPath(this); + } + + public final String getToolsPath() { + return mySdkType.getToolsPath(this); + } + + public final String getVMExecutablePath() { + return mySdkType.getVMExecutablePath(this); + } + + public final String getRtLibraryPath() { + return mySdkType.getRtLibraryPath(this); + } + + public Object clone() throws CloneNotSupportedException { + ProjectJdkImpl newJdk = new ProjectJdkImpl("", mySdkType); + copyTo(newJdk); + return newJdk; + } + + public RootProvider getRootProvider() { + return myRootProvider; + } + + public void copyTo(ProjectJdkImpl dest){ + final String previousName = dest.getName(); + final String name = getName(); + dest.setName(name); + dest.setHomePath(getHomePath()); + dest.setVersionString(getVersionString()); + dest.setSdkAdditionalData(getSdkAdditionalData()); + dest.myRootContainer.startChange(); + dest.myRootContainer.removeAllRoots(); + copyRoots(myRootContainer, dest.myRootContainer, ProjectRootType.CLASS); + copyRoots(myRootContainer, dest.myRootContainer, ProjectRootType.SOURCE); + copyRoots(myRootContainer, dest.myRootContainer, ProjectRootType.JAVADOC); + dest.myRootContainer.finishChange(); + } + + private static void copyRoots(ProjectRootContainer srcContainer, ProjectRootContainer destContainer, ProjectRootType type){ + final ProjectRoot[] newRoots = srcContainer.getRoots(type); + for (int i = 0; i < newRoots.length; i++){ + destContainer.addRoot(newRoots[i], type); + } + } + + private class MyRootProvider extends RootProviderBaseImpl implements ProjectRootListener { + public String[] getUrls(OrderRootType rootType) { + final VirtualFile[] rootFiles = myRootContainer.getRootFiles((ProjectRootType)ourOrderRootsToProjectRoots.get(rootType)); + final ArrayList result = new ArrayList(); + for (int i = 0; i < rootFiles.length; i++) { + result.add(rootFiles[i].getUrl()); + } + return result.toArray(new String[result.size()]); + } + + private Set myListeners = new HashSet(); + + public void addRootSetChangedListener(RootSetChangedListener listener) { + synchronized (this) { + myListeners.add(listener); + } + super.addRootSetChangedListener(listener); + } + + public void removeRootSetChangedListener(RootSetChangedListener listener) { + super.removeRootSetChangedListener(listener); + synchronized (this) { + myListeners.remove(listener); + } + } + + public void rootsChanged() { + synchronized (this) { + if (myListeners.size() == 0) { + return; + } + } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + fireRootSetChanged(); + } + }); + } + } + + private final static HashMap ourOrderRootsToProjectRoots = new HashMap(); + + static { + ourOrderRootsToProjectRoots.put(OrderRootType.CLASSES, ProjectRootType.CLASS); + ourOrderRootsToProjectRoots.put(OrderRootType.CLASSES_AND_OUTPUT, ProjectRootType.CLASS); + ourOrderRootsToProjectRoots.put(OrderRootType.COMPILATION_CLASSES, ProjectRootType.CLASS); + ourOrderRootsToProjectRoots.put(OrderRootType.SOURCES, ProjectRootType.SOURCE); + ourOrderRootsToProjectRoots.put(OrderRootType.JAVADOC, ProjectRootType.JAVADOC); + } + + // SdkModificator implementation + + public SdkModificator getSdkModificator() { + try { + ProjectJdkImpl sdk = (ProjectJdkImpl)clone(); + sdk.myOrigin = this; + sdk.myRootContainer.startChange(); + sdk.update(); + return sdk; + } + catch (CloneNotSupportedException e) { + LOG.error(e); // should not happen + return null; + } + } + + public void commitChanges() { + LOG.assertTrue(isWritable()); + myRootContainer.finishChange(); + copyTo(myOrigin); + myOrigin = null; + } + + public SdkAdditionalData getSdkAdditionalData() { + return myAdditionalData; + } + + public void setSdkAdditionalData(SdkAdditionalData data) { + myAdditionalData = data; + } + + public VirtualFile[] getRoots(ProjectRootType rootType) { + final ProjectRoot[] roots = myRootContainer.getRoots(rootType); // use getRoots() cause the data is most up-to-date there + final List files = new ArrayList(roots.length); + for (int idx = 0; idx < roots.length; idx++) { + ProjectRoot root = roots[idx]; + files.addAll(Arrays.asList(root.getVirtualFiles())); + } + return files.toArray(new VirtualFile[files.size()]); + } + + public void addRoot(VirtualFile root, ProjectRootType rootType) { + myRootContainer.addRoot(root, rootType); + } + + public void removeRoot(VirtualFile root, ProjectRootType rootType) { + myRootContainer.removeRoot(root, rootType); + } + + public void removeRoots(ProjectRootType rootType) { + myRootContainer.removeAllRoots(rootType); + } + + public void removeAllRoots() { + myRootContainer.removeAllRoots(); + } + + public boolean isWritable() { + return myOrigin != null; + } + + public void update() { + myRootContainer.update(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java new file mode 100644 index 00000000000..349ad4c2357 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java @@ -0,0 +1,151 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.projectRoots.JavaSdk; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.util.EventDispatcher; +import org.jdom.Element; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ProjectJdkTableImpl extends ProjectJdkTable implements NamedJDOMExternalizable, ExportableApplicationComponent { + private ArrayList myJdks = new ArrayList(); + private ProjectJdk myInternalJdk; + private EventDispatcher myEventDispatcher = EventDispatcher.create(Listener.class); + private JavaSdk myJavaSdk; + private JarFileSystem myJarFileSystem; + + public ProjectJdkTableImpl(JavaSdk javaSdk, JarFileSystem jarFileSystem) { + myJavaSdk = javaSdk; + myJarFileSystem = jarFileSystem; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "JDK Table"; + } + + public ProjectJdk findJdk(String name) { + for (int i = 0; i < myJdks.size(); i++) { + ProjectJdk jdk = myJdks.get(i); + if (name.equals(jdk.getName())) { + return jdk; + } + } + return null; + } + + public ProjectJdk getInternalJdk() { + if (myInternalJdk == null) { + final String jdkHome = System.getProperty("java.home"); + final String versionName = "java version \"" + System.getProperty("java.version") + "\""; + myInternalJdk = myJavaSdk.createJdk(versionName, jdkHome); + } + return myInternalJdk; + } + + public int getJdkCount() { + return myJdks.size(); + } + + public ProjectJdk[] getAllJdks() { + return myJdks.toArray(new ProjectJdk[myJdks.size()]); + } + + public void addJdk(ProjectJdk jdk) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + myJdks.add(jdk); + myEventDispatcher.getMulticaster().jdkAdded(jdk); + } + + public void removeJdk(ProjectJdk jdk) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + myEventDispatcher.getMulticaster().jdkRemoved(jdk); + myJdks.remove(jdk); + if (jdk.equals(myInternalJdk)) { + myInternalJdk = null; + } + } + + public void updateJdk(ProjectJdk originalJdk, ProjectJdk modifiedJdk) { + final String previousName = originalJdk.getName(); + final String newName = modifiedJdk.getName(); + + ((ProjectJdkImpl)modifiedJdk).copyTo((ProjectJdkImpl)originalJdk); + + if (previousName != null ? !previousName.equals(newName) : newName != null) { + // fire changes because after renaming JDK its name may match the associated jdk name of modules/project + myEventDispatcher.getMulticaster().jdkNameChanged(originalJdk, previousName); + } + } + + public void addListener(ProjectJdkTable.Listener listener) { + myEventDispatcher.addListener(listener); + } + + public void removeListener(ProjectJdkTable.Listener listener) { + myEventDispatcher.removeListener(listener); + } + + public void readExternal(Element element) throws InvalidDataException { + myInternalJdk = null; + myJdks.clear(); + + final List children = element.getChildren("jdk"); + final List jdks = new ArrayList(children.size()); + try { + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + final Element e = (Element)iterator.next(); + final ProjectJdkImpl jdk = new ProjectJdkImpl(null, null); + jdk.readExternal(e); + jdks.add(jdk); + } + } + finally { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (Iterator it = jdks.iterator(); it.hasNext();) { + addJdk(it.next()); + } + } + }); + getInternalJdk(); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myJdks.size(); i++) { + final ProjectJdkImpl jdk = (ProjectJdkImpl)myJdks.get(i); + final Element e = new Element("jdk"); + element.addContent(e); + jdk.writeExternal(e); + } + } + + public String getExternalFileName() { + return "jdk.table"; + } + + public String getComponentName() { + return "ProjectJdkTable"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java new file mode 100644 index 00000000000..31ac578f423 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java @@ -0,0 +1,251 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.ProjectRootListener; +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.projectRoots.ex.ProjectRoot; +import com.intellij.openapi.projectRoots.ex.ProjectRootContainer; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.ex.jar.JarFileSystemEx; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author mike + */ +public class ProjectRootContainerImpl implements JDOMExternalizable, ProjectRootContainer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.impl.ProjectRootContainerImpl"); + private CompositeProjectRoot[] myRoots = new CompositeProjectRoot[ProjectRootType.ALL_TYPES.length]; + + private VirtualFile[][] myFiles = new VirtualFile[ProjectRootType.ALL_TYPES.length][]; + + private boolean myInsideChange = false; + private List myListeners = new ArrayList(); + + private boolean myNoCopyJars = false; + + public ProjectRootContainerImpl(boolean noCopyJars) { + myNoCopyJars = noCopyJars; + + for (int i = 0; i < myRoots.length; i++) { + myRoots[i] = new CompositeProjectRoot(); + } + for (int i = 0; i < myFiles.length; i++) { + myFiles[i] = VirtualFile.EMPTY_ARRAY; + } + } + + public VirtualFile[] getRootFiles(ProjectRootType type) { + return myFiles[type.getIndex()]; + } + + public ProjectRoot[] getRoots(ProjectRootType type) { + return myRoots[type.getIndex()].getProjectRoots(); + } + + public void startChange() { + LOG.assertTrue(!myInsideChange); + + myInsideChange = true; + } + + public void finishChange() { + LOG.assertTrue(myInsideChange); + VirtualFile[][] oldRoots = new VirtualFile[ProjectRootType.ALL_TYPES.length][]; + for (int i = 0; i < oldRoots.length; i++) { + oldRoots[i] = myFiles[i]; + } + + for (int i = 0; i < ProjectRootType.ALL_TYPES.length; i++) { + final VirtualFile[] roots = myRoots[i].getVirtualFiles(); + final boolean same = Comparing.equal(roots, oldRoots[i]); + + myFiles[i] = myRoots[i].getVirtualFiles(); + + if (!same) { + fireRootsChanged(oldRoots[i], myFiles[i], ProjectRootType.ALL_TYPES[i]); + } + } + + myInsideChange = false; + } + + public void addProjectRootContainerListener(ProjectRootListener listener) { + List listeners = new ArrayList(myListeners); + listeners.add(listener); + myListeners = listeners; + } + + public void removeProjectRootContainerListener(ProjectRootListener listener) { + List listeners = new ArrayList(myListeners); + listeners.remove(listener); + myListeners = listeners; + } + + private void fireRootsChanged(final VirtualFile[] oldRoots, final VirtualFile[] newRoots, final ProjectRootType type) { + /* + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + LOG.info("roots changed: type='" + type + "'\n oldRoots='" + Arrays.asList(oldRoots) + "'\n newRoots='" + Arrays.asList(newRoots) + "' "); + } + }); + */ + for (Iterator listenersIterator = myListeners.iterator(); listenersIterator.hasNext();) { + final ProjectRootListener listener = (ProjectRootListener)listenersIterator.next(); + listener.rootsChanged(); + } + } + + + public void removeRoot(ProjectRoot root, ProjectRootType type) { + LOG.assertTrue(myInsideChange); + myRoots[type.getIndex()].remove(root); + } + + public ProjectRoot addRoot(VirtualFile virtualFile, ProjectRootType type) { + LOG.assertTrue(myInsideChange); + return myRoots[type.getIndex()].add(virtualFile); + } + + public void addRoot(ProjectRoot root, ProjectRootType type) { + LOG.assertTrue(myInsideChange); + myRoots[type.getIndex()].add(root); + } + + public void removeAllRoots(ProjectRootType type ) { + LOG.assertTrue(myInsideChange); + myRoots[type.getIndex()].clear(); + } + + public void removeRoot(VirtualFile root, ProjectRootType type) { + LOG.assertTrue(myInsideChange); + myRoots[type.getIndex()].remove(root); + } + + public void removeAllRoots() { + LOG.assertTrue(myInsideChange); + for (int i = 0; i < myRoots.length; i++) { + myRoots[i].clear(); + } + } + + public void update() { + LOG.assertTrue(myInsideChange); + for (int i = 0; i < myRoots.length; i++) { + myRoots[i].update(); + } + } + + public void readExternal(Element element) throws InvalidDataException { + for (int i = 0; i < ProjectRootType.ALL_TYPES.length; i++) { + read(element, ProjectRootType.ALL_TYPES[i]); + } + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + myFiles = new VirtualFile[ProjectRootType.ALL_TYPES.length][]; + for (int i = 0; i < myFiles.length; i++) { + CompositeProjectRoot root = myRoots[i]; + if (myNoCopyJars){ + setNoCopyJars(root); + } + myFiles[i] = root.getVirtualFiles(); + } + } + }); + + for (int i = 0; i < ProjectRootType.ALL_TYPES.length; i++) { + final VirtualFile[] newRoots = getRootFiles(ProjectRootType.ALL_TYPES[i]); + final VirtualFile[] oldRoots = VirtualFile.EMPTY_ARRAY; + if (!Comparing.equal(oldRoots, newRoots)) { + fireRootsChanged(oldRoots, newRoots, ProjectRootType.ALL_TYPES[i]); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < ProjectRootType.ALL_TYPES.length; i++) { + write(element, ProjectRootType.ALL_TYPES[i]); + } + } + + private void setNoCopyJars(ProjectRoot root){ + if (root instanceof SimpleProjectRoot){ + String url = ((SimpleProjectRoot)root).getUrl(); + if (JarFileSystem.PROTOCOL.equals(VirtualFileManager.extractProtocol(url))){ + String path = VirtualFileManager.extractPath(url); + ((JarFileSystemEx)JarFileSystem.getInstance()).setNoCopyJarForPath(path); + } + } + else if (root instanceof CompositeProjectRoot){ + ProjectRoot[] roots = ((CompositeProjectRoot)root).getProjectRoots(); + for(int i = 0; i < roots.length; i++){ + setNoCopyJars(roots[i]); + } + } + } + + private void read(Element element, ProjectRootType type) throws InvalidDataException { + Element child = element.getChild(ProjectRootUtil.typeToString(type)); + if (child == null){ + myRoots[type.getIndex()] = new CompositeProjectRoot(); + return; + } + + List children = child.getChildren(); + LOG.assertTrue(children.size() == 1); + myRoots[type.getIndex()] = (CompositeProjectRoot)ProjectRootUtil.read((Element)children.get(0)); + } + + private void write(Element roots, ProjectRootType type) throws WriteExternalException { + Element e = new Element(ProjectRootUtil.typeToString(type)); + roots.addContent(e); + final Element root = ProjectRootUtil.write(myRoots[type.getIndex()]); + if (root != null) { + e.addContent(root); + } + } + + + void readOldVersion(Element child) { + for (Iterator iterator = child.getChildren("root").iterator(); iterator.hasNext();) { + Element root = (Element)iterator.next(); + String url = root.getAttributeValue("file"); + SimpleProjectRoot projectRoot = new SimpleProjectRoot(url); + String type = root.getChild("property").getAttributeValue("value"); + + if (type.equals("sourcePathEntry")) { + addRoot(projectRoot, ProjectRootType.SOURCE); + } + else if (type.equals("javadocPathEntry")) { + addRoot(projectRoot, ProjectRootType.JAVADOC); + } + else if (type.equals("classPathEntry")) { + addRoot(projectRoot, ProjectRootType.CLASS); + } + } + + myFiles = new VirtualFile[ProjectRootType.ALL_TYPES.length][]; + for (int i = 0; i < myFiles.length; i++) { + myFiles[i] = myRoots[i].getVirtualFiles(); + } + for (int i = 0; i < ProjectRootType.ALL_TYPES.length; i++) { + final VirtualFile[] oldRoots = VirtualFile.EMPTY_ARRAY; + final VirtualFile[] newRoots = getRootFiles(ProjectRootType.ALL_TYPES[i]); + if (!Comparing.equal(oldRoots, newRoots)) { + fireRootsChanged(oldRoots, newRoots, ProjectRootType.ALL_TYPES[i]); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java new file mode 100644 index 00000000000..97a66b3cde8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java @@ -0,0 +1,109 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.projectRoots.ex.ProjectRoot; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +/** + * @author mike + */ +public class ProjectRootUtil { + public static final String SIMPLE_ROOT = "simple"; + public static final String COMPOSITE_ROOT = "composite"; + /** + * @deprecated + */ + public static final String JDK_ROOT = "jdk"; + /** + * @deprecated + */ + public static final String OUTPUT_ROOT = "output"; + /** + * @deprecated + */ + public static final String EXCLUDED_OUTPUT = "excludedOutput"; + /** + * @deprecated + */ + public static final String LIBRARY_ROOT = "library"; + /** + * @deprecated + */ + public static final String EJB_ROOT = "ejb"; + + static ProjectRoot read(Element element) throws InvalidDataException { + final String type = element.getAttributeValue("type"); + + if (type.equals(SIMPLE_ROOT)) { + final SimpleProjectRoot root = new SimpleProjectRoot(); + root.readExternal(element); + return root; + } + else if (type.equals(COMPOSITE_ROOT)) { + final CompositeProjectRoot root = new CompositeProjectRoot(); + root.readExternal(element); + return root; + } + throw new IllegalArgumentException("Wrong type: " + type); + } + + static Element write(ProjectRoot projectRoot) throws WriteExternalException { + Element element = new Element("root"); + if (projectRoot instanceof SimpleProjectRoot) { + element.setAttribute("type", SIMPLE_ROOT); + ((JDOMExternalizable)projectRoot).writeExternal(element); + } + else if (projectRoot instanceof CompositeProjectRoot) { + element.setAttribute("type", COMPOSITE_ROOT); + ((CompositeProjectRoot)projectRoot).writeExternal(element); + } + else { + throw new IllegalArgumentException("Wrong root: " + projectRoot); + } + + return element; + } + + public static String typeToString(ProjectRootType type) { + if (type == ProjectRootType.SOURCE) { + return "sourcePath"; + } + if (type == ProjectRootType.CLASS) { + return "classPath"; + } + if (type == ProjectRootType.JAVADOC) { + return "javadocPath"; + } + if (type == ProjectRootType.PROJECT) { + return "projectPath"; + } + if (type == ProjectRootType.EXCLUDE) { + return "excludePath"; + } + + throw new IllegalArgumentException("Wrong type: " + type); + } + + public static ProjectRootType stringToType(String s) { + if (s.equals("sourcePath")) { + return ProjectRootType.SOURCE; + } + if (s.equals("classPath")) { + return ProjectRootType.CLASS; + } + if (s.equals("javadocPath")) { + return ProjectRootType.JAVADOC; + } + if (s.equals("projectPath")) { + return ProjectRootType.PROJECT; + } + if (s.equals("excludePath")) { + return ProjectRootType.EXCLUDE; + } + + throw new IllegalArgumentException("Wrong type: " + s); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java new file mode 100644 index 00000000000..b792639e1b0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java @@ -0,0 +1,104 @@ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.projectRoots.ex.ProjectRoot; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import org.jdom.Element; + +import java.io.File; + +/** + * @author mike + */ +public class SimpleProjectRoot implements ProjectRoot, JDOMExternalizable { + private String myUrl; + private VirtualFile myFile; + private VirtualFile[] myFileArrray = new VirtualFile[1]; + private boolean myInitialized = false; + + SimpleProjectRoot(VirtualFile file) { + myFile = file; + myUrl = myFile.getUrl(); + } + + public SimpleProjectRoot(String url) { + myUrl = url; + } + + SimpleProjectRoot() { + } + + public VirtualFile getFile() { + return myFile; + } + + public String getPresentableString() { + String path = VirtualFileManager.extractPath(myUrl); + if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { + path = path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()); + } + return path.replace('/', File.separatorChar); + } + + public VirtualFile[] getVirtualFiles() { + if (!myInitialized) initialize(); + + if (myFile == null) { + return VirtualFile.EMPTY_ARRAY; + } + + myFileArrray[0] = myFile; + return myFileArrray; + } + + public boolean isValid() { + if (!myInitialized) { + initialize(); + } + + return myFile != null && myFile.isValid(); + } + + public void update() { + if (!myInitialized) { + initialize(); + } + + if (myFile == null || !myFile.isValid()) { + myFile = VirtualFileManager.getInstance().findFileByUrl(myUrl); + if (myFile != null && !myFile.isDirectory()) myFile = null; + } + } + + private void initialize() { + myInitialized = true; + + if (myFile == null || !myFile.isValid()) { + myFile = VirtualFileManager.getInstance().findFileByUrl(myUrl); + if (myFile != null && !myFile.isDirectory()) { + myFile = null; + } + } + } + + public String getUrl() { + return myUrl; + } + + public void readExternal(Element element) throws InvalidDataException { + myUrl = element.getAttributeValue("url"); + } + + public void writeExternal(Element element) throws WriteExternalException { + if (!myInitialized) { + initialize(); + } + + element.setAttribute("url", myUrl); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java new file mode 100644 index 00000000000..7c4135b789c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.projectRoots.impl; + +import com.intellij.openapi.projectRoots.*; +import com.intellij.openapi.application.impl.ApplicationImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.IconLoader; +import org.jdom.Element; + +import javax.swing.*; +import java.util.Map; +import java.util.HashMap; + +/** + * Used as a plug for all SDKs which type cannot be determined (for example, plugin that registered a custom type has been deinstalled) + * @author Eugene Zhuravlev + * Date: Dec 11, 2004 + */ +public class UnknownSdkType extends SdkType{ + public static final Icon ICON = IconLoader.getIcon("/nodes/unknownJdkClosed.png"); + private static final Icon JDK_ICON_EXPANDED = IconLoader.getIcon("/nodes/unknownJdkOpen.png"); + private static Map ourTypeNameToInstanceMap = new HashMap(); + + /** + * @param typeName the name of the SDK type that this SDK serves as a plug for + */ + private UnknownSdkType(String typeName) { + super(typeName); + } + + public static UnknownSdkType getInstance(String typeName) { + UnknownSdkType instance = ourTypeNameToInstanceMap.get(typeName); + if (instance == null) { + instance = new UnknownSdkType(typeName); + ourTypeNameToInstanceMap.put(typeName, instance); + } + return instance; + } + + public boolean isValidSdkHome(String path) { + return false; + } + + public String getVersionString(String sdkHome) { + return ""; + } + + public String suggestSdkName(String currentSdkName, String sdkHome) { + return currentSdkName; + } + + public void setupSdkPaths(Sdk sdk) { + } + + public AdditionalDataConfigurable createAdditionalDataConfigurable(SdkModel sdkModel, SdkModificator sdkModificator) { + return null; + } + + public String getBinPath(Sdk sdk) { + return null; + } + + public String getToolsPath(Sdk sdk) { + return null; + } + + public String getVMExecutablePath(Sdk sdk) { + return null; + } + + public String getRtLibraryPath(Sdk sdk) { + return null; + } + + public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) { + } + + public SdkAdditionalData loadAdditionalData(Element additional) { + return null; + } + + public String getPresentableName() { + return "Unknown SDK"; + } + + public Icon getIcon() { + return ICON; + } + + public Icon getIconForExpandedTreeNode() { + return JDK_ICON_EXPANDED; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/NotifiableSdkModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/NotifiableSdkModel.java new file mode 100644 index 00000000000..1a3e54f8da8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/NotifiableSdkModel.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.projectRoots.ui; + +import com.intellij.openapi.projectRoots.SdkModel; + +/** + * @author Eugene Zhuravlev + * Date: Oct 4, 2004 + */ +public interface NotifiableSdkModel extends SdkModel{ + Listener getMulticaster(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/PathEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/PathEditor.java new file mode 100644 index 00000000000..3c4749803b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/PathEditor.java @@ -0,0 +1,381 @@ +package com.intellij.openapi.projectRoots.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.projectRoots.SdkModificator; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.http.HttpFileSystem; +import com.intellij.ui.ListUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.Icons; +import com.intellij.util.containers.HashSet; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; + +import gnu.trove.TIntArrayList; + +/** + * @author MYakovlev + */ +public abstract class PathEditor { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.ui.PathEditor"); + public static final Color INVALID_COLOR = new Color(210, 0, 0); + + private JPanel myPanel; + private JButton myRemoveButton; + private JButton myAddButton; + private JButton mySpecifyUrlButton; + private JList myList; + private DefaultListModel myModel; + private Set myAllFiles = new HashSet(); + private boolean myModified = false; + private boolean myEnabled = false; + private static final Icon ICON_INVALID = IconLoader.getIcon("/nodes/ppInvalid.png"); + private static final Icon ICON_EMPTY = IconLoader.getIcon("/nodes/emptyNode.png"); + + protected abstract boolean isShowUrlButton(); + + protected abstract ProjectRootType getRootType(); + + protected abstract FileChooserDescriptor createFileChooserDescriptor(); + + public abstract String getDisplayName(); + + public Icon getIcon(){ + return null; + } + + protected void setModified(boolean modified){ + this.myModified = modified; + } + + public boolean isModified(){ + return myModified; + } + + public void apply(SdkModificator sdkModificator) { + final ProjectRootType rootType = getRootType(); + sdkModificator.removeRoots(rootType); + // add all items + for (int i = 0; i < getRowCount(); i++){ + sdkModificator.addRoot(getValueAt(i), rootType); + } + setModified(false); + updateButtons(); + } + + public VirtualFile[] getRoots() { + final int count = getRowCount(); + if (count == 0) { + return VirtualFile.EMPTY_ARRAY; + } + final VirtualFile[] roots = new VirtualFile[count]; + for (int i = 0; i < count; i++){ + roots[i] = getValueAt(i); + } + return roots; + } + + public void reset(VirtualFile[] files) { + keepSelectionState(); + clearList(); + myEnabled = files != null; + if(myEnabled){ + for (int i = 0; i < files.length; i++){ + addElement(files[i]); + } + } + setModified(false); + updateButtons(); + } + + public JComponent createComponent(){ + myPanel = new JPanel(new GridBagLayout()); + Insets anInsets = new Insets(2, 2, 2, 2); + + myModel = new DefaultListModel(); + myList = new JList(myModel); + myList.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ + public void valueChanged(ListSelectionEvent e){ + updateButtons(); + } + }); + myList.setCellRenderer(new MyCellRenderer()); + + myRemoveButton = new JButton("Remove"); + myAddButton = new JButton("Add..."); + mySpecifyUrlButton = new JButton("Specify URL..."); + + myAddButton.setMnemonic('A'); + myRemoveButton.setMnemonic('R'); + mySpecifyUrlButton.setMnemonic('S'); + + mySpecifyUrlButton.setVisible(isShowUrlButton()); + + myAddButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + final VirtualFile[] added = doAdd(); + if (added.length > 0){ + setModified(true); + } + updateButtons(); + requestDefaultFocus(); + setSelectedRoots(added); + } + }); + myRemoveButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + java.util.List removedItems = ListUtil.removeSelectedItems(myList); + itemsRemoved(removedItems); + } + }); + mySpecifyUrlButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + VirtualFile virtualFile = Util.showSpecifyJavadocUrlDialog(myPanel); + if(virtualFile != null){ + addElement(virtualFile); + setModified(true); + updateButtons(); + requestDefaultFocus(); + setSelectedRoots(new Object[]{virtualFile}); + } + } + }); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myList); + scrollPane.setPreferredSize(new Dimension(500, 500)); + myPanel.add(scrollPane, new GridBagConstraints(0, 0, 1, 8, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, anInsets, 0, 0)); + myPanel.add(myAddButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, anInsets, 0, 0)); + myPanel.add(myRemoveButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, anInsets, 0, 0)); + myPanel.add(mySpecifyUrlButton, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, anInsets, 0, 0)); + myPanel.add(Box.createRigidArea(new Dimension(mySpecifyUrlButton.getPreferredSize().width, 4)), new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, anInsets, 0, 0)); + return myPanel; + } + + private void itemsRemoved(java.util.List removedItems) { + myAllFiles.removeAll(removedItems); + if (removedItems.size() > 0){ + setModified(true); + } + updateButtons(); + requestDefaultFocus(); + } + + private VirtualFile[] doAdd(){ + FileChooserDescriptor descriptor = createFileChooserDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myPanel, descriptor); + java.util.List added = new ArrayList(files.length); + for (int i = 0; i < files.length; i++){ + VirtualFile vFile = files[i]; + if(addElement(vFile)){ + added.add(vFile); + } + } + return added.toArray(new VirtualFile[added.size()]); + } + + private void updateButtons(){ + Object[] values = getSelectedRoots(); + myRemoveButton.setEnabled((values.length > 0) && myEnabled); + myAddButton.setEnabled(myEnabled); + mySpecifyUrlButton.setEnabled(myEnabled && !isUrlInserted()); + mySpecifyUrlButton.setVisible(isShowUrlButton()); + } + + private boolean isUrlInserted(){ + if(getRowCount() > 0){ + return ((VirtualFile)myModel.lastElement()).getFileSystem() instanceof HttpFileSystem; + } + return false; + } + + private void requestDefaultFocus(){ + if (myList != null){ + myList.requestFocus(); + } + } + + public void addPaths(VirtualFile[] paths){ + boolean added = false; + keepSelectionState(); + for (int i = 0; i < paths.length; i++){ + final VirtualFile path = paths[i]; + if(addElement(path)){ + added = true; + } + } + if (added){ + setModified(true); + updateButtons(); + } + } + + public void removePaths(VirtualFile[] paths) { + final Set pathsSet = new java.util.HashSet(Arrays.asList(paths)); + int size = getRowCount(); + final TIntArrayList indicesToRemove = new TIntArrayList(paths.length); + for (int idx = 0; idx < size; idx++) { + VirtualFile path = getValueAt(idx); + if (pathsSet.contains(path)) { + indicesToRemove.add(idx); + } + } + final java.util.List list = ListUtil.removeIndices(myList, indicesToRemove.toNativeArray()); + itemsRemoved(list); + } + + /** Method adds element only if it is not added yet. */ + protected boolean addElement(VirtualFile item){ + if(item == null){ + return false; + } + if (myAllFiles.contains(item)){ + return false; + } + if(isUrlInserted()){ + myModel.insertElementAt(item, myModel.size() - 1); + } + else{ + myModel.addElement(item); + } + myAllFiles.add(item); + return true; + } + + private void setSelectedRoots(Object[] roots){ + ArrayList rootsList = new ArrayList(roots.length); + for (int i = 0; i < roots.length; i++){ + Object root = roots[i]; + if(root != null){ + rootsList.add(root); + } + } + myList.getSelectionModel().clearSelection(); + int rowCount = myModel.getSize(); + for (int i = 0; i < rowCount; i++){ + Object currObject = myModel.get(i); + LOG.assertTrue(currObject != null); + if (rootsList.contains(currObject)){ + myList.getSelectionModel().addSelectionInterval(i, i); + } + } + } + + private void keepSelectionState(){ + final Object[] selectedItems = getSelectedRoots(); + + SwingUtilities.invokeLater(new Runnable(){ + public void run(){ + if (selectedItems != null){ + setSelectedRoots(selectedItems); + } + } + }); + } + + protected Object[] getSelectedRoots(){ + return myList.getSelectedValues(); + } + + private int getRowCount(){ + return myModel.getSize(); + } + + private VirtualFile getValueAt(int row){ + return (VirtualFile)myModel.get(row); + } + + public void clearList(){ + myModel.clear(); + myAllFiles.clear(); + setModified(true); + } + + private static boolean isJarFile(final VirtualFile file){ + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + VirtualFile tempFile = file; + if ((file.getFileSystem() instanceof JarFileSystem) && file.getParent() == null){ + //[myakovlev] It was bug - directories with *.jar extensions was saved as files of JarFileSystem. + // so we can not just return true, we should filter such directories. + String path = file.getPath().substring(0, file.getPath().length() - JarFileSystem.JAR_SEPARATOR.length()); + tempFile = LocalFileSystem.getInstance().findFileByPath(path); + } + if (tempFile != null && !tempFile.isDirectory()){ + return Boolean.valueOf(FileTypeManager.getInstance().getFileTypeByFile(tempFile).equals(StdFileTypes.ARCHIVE)); + } + return Boolean.FALSE; + + } + } ).booleanValue(); + } + + /** + * @return icon for displaying parameter (ProjectRoot or VirtualFile) + * If parameter is not ProjectRoot or VirtualFile, returns empty icon "/nodes/emptyNode.png" + */ + private static Icon getIconForRoot(Object projectRoot){ + if (projectRoot instanceof VirtualFile){ + final VirtualFile file = (VirtualFile)projectRoot; + if (!file.isValid()){ + return ICON_INVALID; + } + else if (isHttpRoot(file)){ + return Icons.WEB_ICON; + } + else{ + return isJarFile(file) ? Icons.JAR_ICON : Icons.FILE_ICON; + } + } + return ICON_EMPTY; + } + + private static boolean isHttpRoot(VirtualFile virtualFileOrProjectRoot){ + if(virtualFileOrProjectRoot != null){ + return (virtualFileOrProjectRoot.getFileSystem() instanceof HttpFileSystem); + } + return false; + } + + private final class MyCellRenderer extends DefaultListCellRenderer{ + private String getPresentableString(final Object value){ + return ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + return (value instanceof VirtualFile)? ((VirtualFile)value).getPresentableUrl() : "UNKNOWN OBJECT"; + } + }); + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus){ + super.getListCellRendererComponent(list, getPresentableString(value), index, isSelected, cellHasFocus); + if (isSelected){ + setForeground(UIManager.getColor("List.selectionForeground")); + } + else{ + if (value instanceof VirtualFile){ + VirtualFile file = (VirtualFile)value; + if (!file.isValid()){ + setForeground(INVALID_COLOR); + } + } + } + setIcon(getIconForRoot(value)); + return this; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java new file mode 100644 index 00000000000..24176be35d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java @@ -0,0 +1,52 @@ +package com.intellij.openapi.projectRoots.ui; + +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; + +import javax.swing.*; +import java.awt.*; + +/** + * @author MYakovlev + */ +public class ProjectJdksEditor extends DialogWrapper{ + private JdkTableConfigurable myJdkTableConfigurable; + + public ProjectJdksEditor(ProjectJdk jdk, Component parent){ + super(parent, true); + myJdkTableConfigurable = new JdkTableConfigurable(); + myJdkTableConfigurable.setSelectedJdk(jdk); + setTitle("Configure JDK"); + init(); + } + + protected JComponent createCenterPanel(){ + JComponent component = myJdkTableConfigurable.createComponent(); + component.setPreferredSize(new Dimension(600, 300)); + return component; + } + + protected void doOKAction(){ + if(!myJdkTableConfigurable.canApply(true, new String[1])){ + return; + } + try{ + myJdkTableConfigurable.apply(); + super.doOKAction(); + } + catch (ConfigurationException e){ + Messages.showMessageDialog(getContentPane(), e.getMessage(), "Cannot Save Settings", Messages.getErrorIcon()); + } + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.openapi.projectRoots.ui.ProjectJdksEditor"; + } + + public ProjectJdk getSelectedJdk(){ + return myJdkTableConfigurable.getSelectedJdk(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/SdkEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/SdkEditor.java new file mode 100644 index 00000000000..345f5ff4656 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/SdkEditor.java @@ -0,0 +1,513 @@ +package com.intellij.openapi.projectRoots.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.projectRoots.*; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.EventDispatcher; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.*; + +/* + * @author: MYakovlev + * Date: Aug 15, 2002 + * Time: 1:27:59 PM + */ + +public class SdkEditor implements Configurable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.ui.SdkEditor"); + private ProjectJdk mySdk; + private PathEditor myClassPathEditor; + private PathEditor mySourcePathEditor; + private PathEditor myJavadocPathEditor; + + private TextFieldWithBrowseButton myHomeComponent; + private Map myAdditionalDataConfigurables = new HashMap(); + private Map myAdditionalDataComponents = new HashMap(); + private EventDispatcher myEventDispatcher = EventDispatcher.create(ChangeListener.class); + private JPanel myAdditionalDataPanel; + private SdkModificator myEditedSdkModificator = new EditedSdkModificator(); + + // GUI components + private JPanel myMainPanel; + private JTextField myNameField; + private TabbedPaneWrapper myTabbedPane; + private static final String EMPTY_AREA = "component0"; + private static final String LAYOUT_ID_PROPERTY_NAME = "layout_id"; + private final NotifiableSdkModel mySdkModel; + private JLabel myHomeFieldLabel; + private String myVersionString; + + public SdkEditor(NotifiableSdkModel sdkModel) { + mySdkModel = sdkModel; + } + + protected String getElementTypeName() { + return "JDK"; + } + + public ProjectJdk getEditedSdk(){ + return mySdk; + } + + public void setSdk(ProjectJdk sdk){ + mySdk = sdk; + final AdditionalDataConfigurable additionalDataConfigurable = getAdditionalDataConfigurable(); + if (additionalDataConfigurable != null) { + additionalDataConfigurable.setSdk(sdk); + } + if (myMainPanel != null){ + reset(); + } + } + + public String getDisplayName(){ + return "JDK Editor"; + } + + public Icon getIcon(){ + return null; + } + + public String getHelpTopic(){ + return null; + } + + public JComponent createComponent(){ + createMainPanel(); + reset(); + return myMainPanel; + } + + private void createMainPanel(){ + myClassPathEditor = new MyPathsEditor("Classpath", ProjectRootType.CLASS, new FileChooserDescriptor(true, true, true, false, true, true), false); + mySourcePathEditor = new MyPathsEditor("Sourcepath", ProjectRootType.SOURCE, new FileChooserDescriptor(true, true, true, false, true, true), false); + myJavadocPathEditor = new MyPathsEditor("JavaDoc API Paths", ProjectRootType.JAVADOC, new FileChooserDescriptor(false, true, true, false, true, true), true); + + myMainPanel = new JPanel(new GridBagLayout()); + myNameField = new JTextField(); + + JLabel nameLabel = new JLabel("Name:"); + nameLabel.setDisplayedMnemonic('N'); + nameLabel.setLabelFor(myNameField); + myMainPanel.add(nameLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 2, 2), 0, 0)); + myMainPanel.add(myNameField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 2, 0), 0, 0)); + + myTabbedPane = new TabbedPaneWrapper(); + myTabbedPane.addTab(myClassPathEditor.getDisplayName(), myClassPathEditor.createComponent()); + myTabbedPane.addTab(mySourcePathEditor.getDisplayName(), mySourcePathEditor.createComponent()); + myTabbedPane.addTab(myJavadocPathEditor.getDisplayName(), myJavadocPathEditor.createComponent()); + myTabbedPane.installKeyboardNavigation(); + + myHomeComponent = new TextFieldWithBrowseButton(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + doSelectHomePath(); + } + }); + 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)); + + myAdditionalDataPanel = new JPanel(new CardLayout()); + myAdditionalDataPanel.add(new JPanel(), EMPTY_AREA); + myMainPanel.add(myAdditionalDataPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 0, 0), 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)); + + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(SdkEditor.this)); + } + }); + } + + private String getHomeFieldLabelValue() { + if (mySdk != null) { + return mySdk.getSdkType().getPresentableName() + " home path:"; + } + return "SDK home path:"; + } + + public boolean isModified(){ + boolean isModified = false; + final String initialName = (mySdk == null) ? "" : mySdk.getName(); + final String initialHome = (mySdk == null) ? "" : mySdk.getHomePath(); + isModified = isModified || !Comparing.equal(getNameValue(), initialName); + isModified = isModified || !Comparing.equal(getHomeValue().replace(File.separatorChar, '/'), initialHome); + isModified = isModified || myClassPathEditor.isModified(); + isModified = isModified || mySourcePathEditor.isModified(); + isModified = isModified || myJavadocPathEditor.isModified(); + final AdditionalDataConfigurable configurable = getAdditionalDataConfigurable(); + if (configurable != null) { + isModified = isModified || configurable.isModified(); + } + return isModified; + } + + public void apply() throws ConfigurationException{ + final String currName = getNameValue(); + if(!Comparing.equal(currName, (mySdk == null) ? "" : mySdk.getName())){ + if(currName.length() == 0){ + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run(){ + focusToNameField(); + } + }); + throw new ConfigurationException("Please specify SDK name"); + } + } + if (mySdk != null){ + final SdkModificator sdkModificator = mySdk.getSdkModificator(); + sdkModificator.setName(getNameValue()); + sdkModificator.setHomePath(getHomeValue().replace(File.separatorChar, '/')); + myClassPathEditor.apply(sdkModificator); + mySourcePathEditor.apply(sdkModificator); + myJavadocPathEditor.apply(sdkModificator); + ApplicationManager.getApplication().runWriteAction(new Runnable() { // fix SCR #29193 + public void run() { + sdkModificator.commitChanges(); + } + }); + final AdditionalDataConfigurable configurable = getAdditionalDataConfigurable(); + if (configurable != null) { + configurable.apply(); + } + } + } + + public void reset(){ + if (mySdk == null){ + setNameValue(""); + setHomePathValue(""); + myClassPathEditor.reset(null); + mySourcePathEditor.reset(null); + myJavadocPathEditor.reset(null); + } + else{ + final SdkModificator sdkModificator = mySdk.getSdkModificator(); + myClassPathEditor.reset(sdkModificator.getRoots(myClassPathEditor.getRootType())); + mySourcePathEditor.reset(sdkModificator.getRoots(mySourcePathEditor.getRootType())); + myJavadocPathEditor.reset(sdkModificator.getRoots(myJavadocPathEditor.getRootType())); + sdkModificator.commitChanges(); + setNameValue(mySdk.getName()); + setHomePathValue(mySdk.getHomePath().replace('/', File.separatorChar)); + } + myVersionString = null; + myHomeFieldLabel.setText(getHomeFieldLabelValue()); + updateAdditionalDataComponent(); + final AdditionalDataConfigurable configurable = getAdditionalDataConfigurable(); + if (configurable != null) { + configurable.reset(); + } + + myNameField.setEnabled(mySdk != null); + myHomeComponent.setEnabled(mySdk != null); + + for(int i = 0; i < myTabbedPane.getTabCount(); i++){ + myTabbedPane.setEnabledAt(i, mySdk != null); + } + } + + public void disposeUIResources(){ + myMainPanel = null; + for (Iterator it = myAdditionalDataConfigurables.keySet().iterator(); it.hasNext();) { + final SdkType sdkType = (SdkType)it.next(); + final AdditionalDataConfigurable configurable = myAdditionalDataConfigurables.get(sdkType); + configurable.disposeUIResources(); + } + myAdditionalDataConfigurables.clear(); + myAdditionalDataComponents.clear(); + } + + public void focusToNameField(){ + myNameField.requestFocus(); + } + + public String getNameValue(){ + return myNameField.getText().trim(); + } + + private String getHomeValue() { + return myHomeComponent.getText().trim(); + } + + public void setNameValue(String value){ + myNameField.setText(value); + } + + public void addChangeListener(ChangeListener listener){ + myEventDispatcher.addListener(listener); + } + + public void removeChangeListener(ChangeListener listener){ + myEventDispatcher.removeListener(listener); + } + + public void clearAllPaths(){ + myClassPathEditor.clearList(); + mySourcePathEditor.clearList(); + myJavadocPathEditor.clearList(); + } + + private void setHomePathValue(String absolutePath) { + myHomeComponent.setText(absolutePath); + final Color fg; + if (absolutePath != null && absolutePath.length() > 0) { + final File homeDir = new File(absolutePath); + fg = homeDir.isDirectory() && homeDir.exists()? UIManager.getColor("field.foreground") : PathEditor.INVALID_COLOR; + } + else { + fg = UIManager.getColor("field.foreground"); + } + myHomeComponent.getTextField().setForeground(fg); + } + + public static String selectSdkHome(final Component parentComponent, final SdkType sdkType){ + final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) { + public void validateSelectedFiles(VirtualFile[] files) throws Exception { + if (files.length != 0){ + if (!sdkType.isValidSdkHome(files[0].getPath())){ + throw new Exception("The directory selected is not a valid home for " + sdkType.getPresentableName()); + } + } + } + }; + descriptor.setTitle("Select Home Directory for " + sdkType.getPresentableName()); + VirtualFile[] files = FileChooser.chooseFiles(parentComponent, descriptor); + if (files.length != 0){ + return files[0].getPath(); + } + return null; + } + + private class MyPathsEditor extends PathEditor { + private final String myDisplayName; + private final ProjectRootType myRootType; + private final FileChooserDescriptor myDescriptor; + private final boolean myCanAddUrl; + + public MyPathsEditor(String displayName, ProjectRootType rootType, FileChooserDescriptor descriptor, boolean canAddUrl) { + myDisplayName = displayName; + myRootType = rootType; + myDescriptor = descriptor; + myCanAddUrl = canAddUrl; + } + + protected ProjectRootType getRootType() { + return myRootType; + } + + protected FileChooserDescriptor createFileChooserDescriptor() { + return myDescriptor; + } + + public String getDisplayName() { + return myDisplayName; + } + + protected boolean isShowUrlButton() { + return myCanAddUrl; + } + } + + private void doSelectHomePath(){ + final SdkType sdkType = mySdk.getSdkType(); + final String homePath = selectSdkHome(myHomeComponent, sdkType); + doSetHomePath(homePath, sdkType); + } + + private void doSetHomePath(final String homePath, final SdkType sdkType) { + if (homePath == null){ + return; + } + setHomePathValue(homePath.replace('/', File.separatorChar)); + + final String newSdkName = suggestSdkName(homePath); + setNameValue(newSdkName); + + try { + final ProjectJdk dummySdk = (ProjectJdk)mySdk.clone(); + SdkModificator sdkModificator = dummySdk.getSdkModificator(); + sdkModificator.setHomePath(homePath); + sdkModificator.removeAllRoots(); + sdkModificator.commitChanges(); + + sdkType.setupSdkPaths(dummySdk); + + clearAllPaths(); + myVersionString = dummySdk.getVersionString(); + sdkModificator = dummySdk.getSdkModificator(); + myClassPathEditor.addPaths(sdkModificator.getRoots(myClassPathEditor.getRootType())); + mySourcePathEditor.addPaths(sdkModificator.getRoots(mySourcePathEditor.getRootType())); + myJavadocPathEditor.addPaths(sdkModificator.getRoots(myJavadocPathEditor.getRootType())); + + mySdkModel.getMulticaster().sdkHomeSelected(mySdk, homePath); + } + catch (CloneNotSupportedException e) { + LOG.error(e); // should not happen in normal program + } + } + + private String suggestSdkName(final String homePath) { + final String suggestedName = mySdk.getSdkType().suggestSdkName(getNameValue(), homePath); + String newSdkName = suggestedName; + final Set allNames = new HashSet(); + Sdk[] sdks = mySdkModel.getSdks(); + for (int idx = 0; idx < sdks.length; idx++) { + allNames.add(sdks[idx].getName()); + } + int i = 0; + while(allNames.contains(newSdkName)){ + newSdkName = suggestedName + " (" + (++i) + ")"; + } + return newSdkName; + } + + private void updateAdditionalDataComponent() { + final AdditionalDataConfigurable configurable = getAdditionalDataConfigurable(); + String layoutId = EMPTY_AREA; + if (configurable != null) { + JComponent component = myAdditionalDataComponents.get(configurable); + if (component == null) { + component = configurable.createComponent(); + myAdditionalDataComponents.put(configurable, component); + layoutId = "component" + Integer.toString(myAdditionalDataComponents.size()); + component.putClientProperty(LAYOUT_ID_PROPERTY_NAME, layoutId); + myAdditionalDataPanel.add(component, layoutId); + } + else { + layoutId = (String)component.getClientProperty(LAYOUT_ID_PROPERTY_NAME); + } + } + ((CardLayout)myAdditionalDataPanel.getLayout()).show(myAdditionalDataPanel, layoutId); + } + + private AdditionalDataConfigurable getAdditionalDataConfigurable() { + if (mySdk == null) { + return null; + } + final SdkType sdkType = mySdk.getSdkType(); + AdditionalDataConfigurable configurable = myAdditionalDataConfigurables.get(sdkType); + if (configurable == null) { + configurable = sdkType.createAdditionalDataConfigurable(mySdkModel, myEditedSdkModificator); + if (configurable != null) { + myAdditionalDataConfigurables.put(sdkType, configurable); + } + } + return configurable; + } + + private class EditedSdkModificator implements SdkModificator { + public String getName() { + return getNameValue(); + } + + public void setName(String name) { + setNameValue(name); + } + + public String getHomePath() { + return getHomeValue(); + } + + public void setHomePath(String path) { + doSetHomePath(path, mySdk.getSdkType()); + } + + public String getVersionString() { + return myVersionString != null? myVersionString : mySdk.getVersionString(); + } + + public void setVersionString(String versionString) { + throw new UnsupportedOperationException(); // not supported for this editor + } + + public SdkAdditionalData getSdkAdditionalData() { + return mySdk.getSdkAdditionalData(); + } + + public void setSdkAdditionalData(SdkAdditionalData data) { + throw new UnsupportedOperationException(); // not supported for this editor + } + + public VirtualFile[] getRoots(ProjectRootType rootType) { + if (ProjectRootType.CLASS.equals(rootType)) { + return myClassPathEditor.getRoots(); + } + if (ProjectRootType.JAVADOC.equals(rootType)) { + return myJavadocPathEditor.getRoots(); + } + if (ProjectRootType.SOURCE.equals(rootType)) { + return mySourcePathEditor.getRoots(); + } + return VirtualFile.EMPTY_ARRAY; + } + + public void addRoot(VirtualFile root, ProjectRootType rootType) { + if (ProjectRootType.CLASS.equals(rootType)) { + myClassPathEditor.addPaths(new VirtualFile[] {root}); + } + else if (ProjectRootType.JAVADOC.equals(rootType)) { + myJavadocPathEditor.addPaths(new VirtualFile[] {root}); + } + else if (ProjectRootType.SOURCE.equals(rootType)) { + mySourcePathEditor.addPaths(new VirtualFile[] {root}); + } + } + + public void removeRoot(VirtualFile root, ProjectRootType rootType) { + if (ProjectRootType.CLASS.equals(rootType)) { + myClassPathEditor.removePaths(new VirtualFile[] {root}); + } + else if (ProjectRootType.JAVADOC.equals(rootType)) { + myJavadocPathEditor.removePaths(new VirtualFile[] {root}); + } + else if (ProjectRootType.SOURCE.equals(rootType)) { + mySourcePathEditor.removePaths(new VirtualFile[] {root}); + } + } + + public void removeRoots(ProjectRootType rootType) { + if (ProjectRootType.CLASS.equals(rootType)) { + myClassPathEditor.clearList(); + } + else if (ProjectRootType.JAVADOC.equals(rootType)) { + myJavadocPathEditor.clearList(); + } + else if (ProjectRootType.SOURCE.equals(rootType)) { + mySourcePathEditor.clearList(); + } + } + + public void removeAllRoots() { + myClassPathEditor.clearList(); + myJavadocPathEditor.clearList(); + mySourcePathEditor.clearList(); + } + + public void commitChanges() { + } + + public boolean isWritable() { + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/Util.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/Util.java new file mode 100644 index 00000000000..9ca2b880f5e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/projectRoots/ui/Util.java @@ -0,0 +1,43 @@ +package com.intellij.openapi.projectRoots.ui; + +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +import javax.swing.*; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * @author MYakovlev + * Date: Oct 29, 2002 + * Time: 8:47:43 PM + */ +public class Util{ + + public static VirtualFile showSpecifyJavadocUrlDialog(JComponent parent){ + final String url = Messages.showInputDialog(parent, "Enter javadoc URL:", "Specify Javadoc URL", Messages.getQuestionIcon(), "", new InputValidator() { + public boolean checkInput(String inputString) { + return true; + } + public boolean canClose(String inputString) { + try { + new URL(StringUtil.endsWithChar(inputString, '/') ? inputString : (inputString + "/")); + return true; + } + catch (MalformedURLException e1) { + Messages.showErrorDialog(e1.getMessage(), "Specify Javadoc URL"); + } + return false; + } + }); + if (url == null) { + return null; + } + return VirtualFileManager.getInstance().findFileByUrl(StringUtil.endsWithChar(url, '/') ? url : (url + "/")); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java new file mode 100644 index 00000000000..7cf8d876fc5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java @@ -0,0 +1,35 @@ +package com.intellij.openapi.roots.ex; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.pom.java.LanguageLevel; + +import java.util.EventListener; + +public abstract class ProjectRootManagerEx extends ProjectRootManager { + public static ProjectRootManagerEx getInstanceEx(Project project) { + return (ProjectRootManagerEx)getInstance(project); + } + + public abstract void setLanguageLevel(LanguageLevel level); + + public abstract LanguageLevel getLanguageLevel(); + + public abstract void registerChangeUpdater(CacheUpdater updater); + + public abstract void unregisterChangeUpdater(CacheUpdater updater); + + public abstract void addProjectJdkListener(ProjectJdkListener listener); + + public abstract void removeProjectJdkListener(ProjectJdkListener listener); + + public abstract void beforeRootsChange(boolean filetypes); + + public abstract void rootsChanged(boolean filetypes); + + + public interface ProjectJdkListener extends EventListener { + void projectJdkChanged(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentEntry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentEntry.java new file mode 100644 index 00000000000..6207c89ea0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentEntry.java @@ -0,0 +1,10 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.ContentEntry; + +/** + * @author dsl + */ +public interface ClonableContentEntry { + ContentEntry cloneEntry(RootModelImpl rootModel); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentFolder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentFolder.java new file mode 100644 index 00000000000..25fc3c47a67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableContentFolder.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; + +/** + * @author dsl + */ +public interface ClonableContentFolder { + ContentFolder cloneFolder(ContentEntry contentEntry); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableOrderEntry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableOrderEntry.java new file mode 100644 index 00000000000..567c63e102f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ClonableOrderEntry.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; + +/** + * @author dsl + */ +public interface ClonableOrderEntry { + OrderEntry cloneEntry(RootModelImpl rootModel, ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentEntryImpl.java new file mode 100644 index 00000000000..19ab6816ec5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentEntryImpl.java @@ -0,0 +1,250 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +import java.util.*; + +/** + * @author dsl + */ +public class ContentEntryImpl extends RootModelComponentBase implements ContentEntry, ClonableContentEntry { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleContentEntryImpl"); + private final VirtualFilePointer myRoot; + private RootModelImpl myRootModel; + final static String ELEMENT_NAME = "content"; + private final TreeSet mySourceFolders = new TreeSet(ContentFolderComparator.INSTANCE); + private final TreeSet myExcludeFolders = new TreeSet(ContentFolderComparator.INSTANCE); + private static final String URL_ATTR = "url"; + + + private ContentEntryImpl(VirtualFilePointer root, RootModelImpl rootModel) { + super(rootModel); + myRootModel = rootModel; + myRoot = rootModel.pointerFactory().duplicate(root); + } + + ContentEntryImpl(Element element, RootModelImpl rootModel) throws InvalidDataException { + super(rootModel); + myRootModel = rootModel; + LOG.assertTrue(ELEMENT_NAME.equals(element.getName())); + final String urlAttrValue = element.getAttributeValue(URL_ATTR); + if (urlAttrValue == null) throw new InvalidDataException(); + myRoot = myRootModel.pointerFactory().create(urlAttrValue); + + mySourceFolders.clear(); + final List sourceChildren = element.getChildren(SourceFolderImpl.ELEMENT_NAME); + for (int i = 0; i < sourceChildren.size(); i++) { + Element sourceEntryElement = (Element)sourceChildren.get(i); + mySourceFolders.add(new SourceFolderImpl(sourceEntryElement, this)); + } + + myExcludeFolders.clear(); + final List excludeChildren = element.getChildren(ExcludeFolderImpl.ELEMENT_NAME); + for (int i = 0; i < excludeChildren.size(); i++) { + Element excludeFolderElement = (Element)excludeChildren.get(i); + myExcludeFolders.add(new ExcludeFolderImpl(excludeFolderElement, this)); + } + } + + ContentEntryImpl(VirtualFile file, RootModelImpl rootModel) { + super(rootModel); + myRootModel = rootModel; + myRoot = myRootModel.pointerFactory().create(file); + } + + public VirtualFile getFile() { + final VirtualFile file = myRoot.getFile(); + if (file == null || file.isDirectory()) { + return file; + } else { + return null; + } + } + + public String getUrl() { + return myRoot.getUrl(); + } + + public SourceFolder[] getSourceFolders() { + return (SourceFolder[])mySourceFolders.toArray(new SourceFolder[mySourceFolders.size()]); + } + + public VirtualFile[] getSourceFolderFiles() { + final SourceFolder[] sourceFolders = getSourceFolders(); + ArrayList result = new ArrayList(); + for (int i = 0; i < sourceFolders.length; i++) { + SourceFolder sourceFolder = sourceFolders[i]; + final VirtualFile file = sourceFolder.getFile(); + if (file != null) { + result.add(file); + } + } + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + public ExcludeFolder[] getExcludeFolders() { + return calculateExcludeFolders(); + } + + private ExcludeFolder[] calculateExcludeFolders() { + if (!myRootModel.isExcludeOutput() && !myRootModel.isExcludeExplodedDirectory()) { // optimization + return (ExcludeFolder[])myExcludeFolders.toArray(new ExcludeFolder[myExcludeFolders.size()]); + } + final ArrayList result = new ArrayList(myExcludeFolders); + if (myRootModel.isExcludeOutput()) { + addExcludeForOutputPath(myRootModel.myCompilerOutputPath, result); + addExcludeForOutputPath(myRootModel.myCompilerOutputPathForTests, result); + } + if (myRootModel.isExcludeExplodedDirectory()) { + addExcludeForOutputPath(myRootModel.myExplodedDirectory, result); + } + return (ExcludeFolder[])result.toArray(new ExcludeFolder[result.size()]); + } + + private void addExcludeForOutputPath(final VirtualFilePointer outputPath, ArrayList result) { + if (outputPath == null) return; + final VirtualFile outputPathFile = outputPath.getFile(); + final VirtualFile file = myRoot.getFile(); + if (outputPathFile != null && file != null && VfsUtil.isAncestor(file, outputPathFile, false)) { + result.add(new ExcludedOutputFolderImpl(this, outputPath)); + } + } + + public VirtualFile[] getExcludeFolderFiles() { + final ExcludeFolder[] excludeFolders = getExcludeFolders(); + ArrayList result = new ArrayList(); + for (int i = 0; i < excludeFolders.length; i++) { + ExcludeFolder excludeFolder = excludeFolders[i]; + final VirtualFile file = excludeFolder.getFile(); + if (file != null) { + result.add(file); + } + } + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + public SourceFolder addSourceFolder(VirtualFile file, boolean isTestSource) { + return addSourceFolder(file, isTestSource, SourceFolderImpl.DEFAULT_PACKAGE_PREFIX); + } + + public SourceFolder addSourceFolder(VirtualFile file, boolean isTestSource, String packagePrefix) { + myRootModel.assertWritable(); + assertFolderUnderMe(file); + final SourceFolderImpl simpleSourceFolder = new SourceFolderImpl(file, isTestSource, packagePrefix, this); + mySourceFolders.add(simpleSourceFolder); + return simpleSourceFolder; + } + + private void assertFolderUnderMe(VirtualFile file) { + final VirtualFile rootFile = getFile(); + if (rootFile == null) { + LOG.assertTrue(false, "Content entry file is null"); + return; + } + if (!VfsUtil.isAncestor(rootFile, file, false)) { + LOG.assertTrue(false, "The file " + file.getPresentableUrl() + " is not under content entry root " + rootFile.getPresentableUrl()); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + LOG.assertTrue(ELEMENT_NAME.equals(element.getName())); + element.setAttribute(URL_ATTR, myRoot.getUrl()); + for (Iterator iterator = mySourceFolders.iterator(); iterator.hasNext();) { + SourceFolder simpleSourceFolder = (SourceFolder)iterator.next(); + + if (simpleSourceFolder instanceof SourceFolderImpl) { + final Element subElement = new Element(SourceFolderImpl.ELEMENT_NAME); + ((SourceFolderImpl)simpleSourceFolder).writeExternal(subElement); + element.addContent(subElement); + } + } + + for (Iterator iterator = myExcludeFolders.iterator(); iterator.hasNext();) { + ExcludeFolder excludeFolder = (ExcludeFolder)iterator.next(); + if (excludeFolder instanceof ExcludeFolderImpl) { + final Element subElement = new Element(ExcludeFolderImpl.ELEMENT_NAME); + ((ExcludeFolderImpl)excludeFolder).writeExternal(subElement); + element.addContent(subElement); + } + } + } + + public boolean isSynthetic() { + return false; + } + + private final static class ContentFolderComparator implements Comparator { + public static final ContentFolderComparator INSTANCE = new ContentFolderComparator(); + + public int compare(ContentFolder o1, ContentFolder o2) { + return ((ContentFolder)o1).getUrl().compareTo(((ContentFolder)o2).getUrl()); + } + } + + public void removeSourceFolder(SourceFolder sourceFolder) { + myRootModel.assertWritable(); + LOG.assertTrue(mySourceFolders.contains(sourceFolder)); + mySourceFolders.remove(sourceFolder); + } + + public ExcludeFolder addExcludeFolder(VirtualFile file) { + myRootModel.assertWritable(); + assertFolderUnderMe(file); + final ExcludeFolderImpl excludeFolder = new ExcludeFolderImpl(file, this); + myExcludeFolders.add(excludeFolder); + return excludeFolder; + } + + public void removeExcludeFolder(ExcludeFolder excludeFolder) { + myRootModel.assertWritable(); + LOG.assertTrue(myExcludeFolders.contains(excludeFolder)); + myExcludeFolders.remove(excludeFolder); + } + + public ContentEntry cloneEntry(RootModelImpl rootModel) { + final ContentEntryImpl cloned = new ContentEntryImpl(myRoot, rootModel); + for (Iterator iterator = mySourceFolders.iterator(); iterator.hasNext();) { + SourceFolder sourceFolder = (SourceFolder)iterator.next(); + if (sourceFolder instanceof ClonableContentFolder) { + cloned.mySourceFolders.add(((ClonableContentFolder)sourceFolder).cloneFolder(cloned)); + } + } + + for (Iterator iterator = myExcludeFolders.iterator(); iterator.hasNext();) { + ExcludeFolder excludeFolder = (ExcludeFolder)iterator.next(); + if (excludeFolder instanceof ClonableContentFolder) { + cloned.myExcludeFolders.add(((ClonableContentFolder)excludeFolder).cloneFolder(cloned)); + } + } + return cloned; + } + + RootModelImpl getRootModel() { + return myRootModel; + } + + protected void dispose() { + super.dispose(); + VirtualFilePointerManager.getInstance().kill(myRoot); + for (Iterator iterator = mySourceFolders.iterator(); iterator.hasNext();) { + ContentFolder contentFolder = (ContentFolder)iterator.next(); + ((RootModelComponentBase)contentFolder).dispose(); + } + for (Iterator iterator = myExcludeFolders.iterator(); iterator.hasNext();) { + ContentFolder contentFolder = (ContentFolder)iterator.next(); + ((RootModelComponentBase)contentFolder).dispose(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java new file mode 100644 index 00000000000..8be9c84befc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +/** + * @author dsl + */ +public abstract class ContentFolderBaseImpl extends RootModelComponentBase implements ContentFolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleContentFolderBaseImpl"); + private VirtualFilePointer myFilePointer; + protected final ContentEntryImpl myContentEntry; + protected static final String URL_ATTR = "url"; + + ContentFolderBaseImpl(VirtualFile file, ContentEntryImpl contentEntry) { + super(contentEntry.getRootModel()); + myContentEntry = contentEntry; + myFilePointer = contentEntry.getRootModel().pointerFactory().create(file); + } + + protected ContentFolderBaseImpl(ContentFolderBaseImpl that, ContentEntryImpl contentEntry) { + super(contentEntry.getRootModel()); + myContentEntry = contentEntry; + myFilePointer = + contentEntry.getRootModel().pointerFactory().duplicate(that.myFilePointer); + } + + ContentFolderBaseImpl(Element element, ContentEntryImpl contentEntry) throws InvalidDataException { + super(contentEntry.getRootModel()); + final String path = element.getAttributeValue(URL_ATTR); + if (path == null) throw new InvalidDataException(); + myContentEntry = contentEntry; + myFilePointer = myContentEntry.getRootModel().pointerFactory().create(path); + } + + public VirtualFile getFile() { + final VirtualFile file = myFilePointer.getFile(); + if (file == null || file.isDirectory()) { + return file; + } + else { + return null; + } + } + + public ContentEntry getContentEntry() { + return myContentEntry; + } + + protected void writeFolder(Element element, String elementName) { + LOG.assertTrue(element.getName().equals(elementName)); + element.setAttribute(URL_ATTR, myFilePointer.getUrl()); + } + + public String getUrl() { + return myFilePointer.getUrl(); + } + + public boolean isSynthetic() { + return false; + } + + protected void dispose() { + super.dispose(); + VirtualFilePointerManager.getInstance().kill(myFilePointer); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndex.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndex.java new file mode 100644 index 00000000000..c16cf3f3dfd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndex.java @@ -0,0 +1,17 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +public abstract class DirectoryIndex { + public static DirectoryIndex getInstance(Project project) { + return project.getComponent(DirectoryIndex.class); + } + + // for tests + public abstract void checkConsistency(); + + public abstract DirectoryInfo getInfoForDirectory(VirtualFile dir); + + public abstract VirtualFile[] getDirectoriesByPackageName(String packageName, boolean includeLibrarySources); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java new file mode 100644 index 00000000000..bc2f0e6fd97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -0,0 +1,900 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.ide.startup.StartupManagerEx; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiNameHelper; +import com.intellij.psi.impl.PsiManagerConfiguration; +import com.intellij.util.EventDispatcher; +import junit.framework.Assert; + +import java.util.*; + +public class DirectoryIndexImpl extends DirectoryIndex implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexImpl"); + + private boolean LAZY_MODE; + + private final Project myProject; + + private boolean myInitialized = false; + private boolean myDisposed = false; + + private com.intellij.util.containers.HashMap myDirToInfoMap = new com.intellij.util.containers.HashMap(); + private com.intellij.util.containers.HashMap myPackageNameToDirsMap = new com.intellij.util.containers.HashMap(); + + private VirtualFileListener myVirtualFileListener; + private FileTypeListener myFileTypeListener; + private ModuleRootListener myRootListener; + + private PsiNameHelper myNameHelper; + + public DirectoryIndexImpl(Project project, PsiManagerConfiguration psiManagerConfiguration, StartupManagerEx startupManagerEx) { + myProject = project; + + PsiManagerConfiguration configuration = psiManagerConfiguration; + LAZY_MODE = !configuration.REPOSITORY_ENABLED; + startupManagerEx.registerPreStartupActivity( + new Runnable() { + public void run() { + initialize(); + } + } + ); + } + + public String getComponentName() { + return "DirectoryIndex"; + } + + public void initComponent() { + } + + public void disposeComponent() { + if (myInitialized) { + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + ProjectRootManager.getInstance(myProject).removeModuleRootListener(myRootListener); + } + myDisposed = true; + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + // for tests + public void checkConsistency() { + checkConsistency(false); + checkConsistency(true); + } + + private void checkConsistency(boolean reverseAllSets) { + Assert.assertTrue(myInitialized); + Assert.assertTrue(!myDisposed); + + com.intellij.util.containers.HashMap oldDirToInfoMap = myDirToInfoMap; + myDirToInfoMap = new com.intellij.util.containers.HashMap(); + + com.intellij.util.containers.HashMap oldPackageNameToDirsMap = myPackageNameToDirsMap; + myPackageNameToDirsMap = new com.intellij.util.containers.HashMap(); + + _initialize(reverseAllSets, null); + + if (LAZY_MODE) { + com.intellij.util.containers.HashMap newDirToInfoMap = myDirToInfoMap; + com.intellij.util.containers.HashMap newPackageNameToDirsMap = myPackageNameToDirsMap; + myDirToInfoMap = oldDirToInfoMap; + myPackageNameToDirsMap = oldPackageNameToDirsMap; + + Set allDirsSet = newDirToInfoMap.keySet(); + for (Iterator iterator = allDirsSet.iterator(); iterator.hasNext();) { + VirtualFile dir = iterator.next(); + getInfoForDirectory(dir); + } + + myDirToInfoMap = newDirToInfoMap; + myPackageNameToDirsMap = newPackageNameToDirsMap; + } + + Set keySet = myDirToInfoMap.keySet(); + Assert.assertEquals(keySet, oldDirToInfoMap.keySet()); + for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { + VirtualFile file = iterator.next(); + DirectoryInfo info1 = myDirToInfoMap.get(file); + DirectoryInfo info2 = oldDirToInfoMap.get(file); + Assert.assertEquals(info1, info2); + } + + Assert.assertEquals(myPackageNameToDirsMap.keySet(), oldPackageNameToDirsMap.keySet()); + for (Iterator> iterator = myPackageNameToDirsMap.entrySet().iterator(); + iterator.hasNext(); + ) { + Map.Entry entry = iterator.next(); + String packageName = entry.getKey(); + VirtualFile[] dirs = entry.getValue(); + VirtualFile[] dirs1 = oldPackageNameToDirsMap.get(packageName); + + HashSet set1 = new HashSet(); + set1.addAll(Arrays.asList(dirs)); + HashSet set2 = new HashSet(); + set2.addAll(Arrays.asList(dirs1)); + Assert.assertEquals(set1, set2); + } + } + + /** + * @fabrique Used in fabrique + */ + public void initialize() { + myNameHelper = PsiManager.getInstance(myProject).getNameHelper(); + + LOG.assertTrue(!myInitialized); + LOG.assertTrue(!myDisposed); + myInitialized = true; + + myVirtualFileListener = new MyVirtualFileListener(); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + + myFileTypeListener = new FileTypeListener() { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(FileTypeEvent event) { + _initialize(); + } + }; + FileTypeManager.getInstance().addFileTypeListener(myFileTypeListener); + + myRootListener = new ModuleRootListener() { + public void beforeRootsChange(ModuleRootEvent event) { + } + + public void rootsChanged(ModuleRootEvent event) { + _initialize(); + } + }; + ProjectRootManager.getInstance(myProject).addModuleRootListener(myRootListener); + + _initialize(); + } + + private void _initialize() { + if (LAZY_MODE) { + myDirToInfoMap.clear(); + myPackageNameToDirsMap.clear(); + } + else { + _initialize(false, null); + } + } + + private void _initialize( + boolean reverseAllSets/* for testing order independence*/, + VirtualFile forDir/* in LAZY_MODE only*/ + ) { + + final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null) { + progress.pushState(); + progress.setText("Scanning files..."); + } + + if (forDir == null) { + myDirToInfoMap.clear(); + myPackageNameToDirsMap.clear(); + } + + if (forDir != null) { + // clear map for all ancestors to not interfer with previous results + VirtualFile dir = forDir; + do { + myDirToInfoMap.remove(dir); + dir = dir.getParent(); + } + while (dir != null); + } + + ModuleManager moduleManager = ModuleManager.getInstance(myProject); + Module[] modules = moduleManager.getModules(); + if (reverseAllSets) { + modules = (Module[])reverseArray(modules); + } + + // exclude roots should be merged to prevent including excluded dirs of an inner module into the outer + // exclude root should exclude from its content root and all outer content roots + + if (progress != null) { + progress.setText2("Building exclude roots..."); + } + Map> excludeRootsMap = new HashMap>(); + for (int i = 0; i < modules.length; i++) { + ModuleRootManager rootManager = ModuleRootManager.getInstance(modules[i]); + ContentEntry[] contentEntries = rootManager.getContentEntries(); + for (int j = 0; j < contentEntries.length; j++) { + ContentEntry contentEntry = contentEntries[j]; + VirtualFile contentRoot = contentEntry.getFile(); + if (contentRoot == null) continue; + + VirtualFile[] excludeRoots = contentEntry.getExcludeFolderFiles(); + for (int k = 0; k < excludeRoots.length; k++) { + putForFileAndAllAncestors(excludeRootsMap, contentRoot, excludeRoots[k]); + } + } + } + + // fill module content's + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + if (progress != null) { + progress.setText2("Processing module \"" + module.getName() + "\" content..."); + } + VirtualFile[] contentRoots = rootManager.getContentRoots(); + if (reverseAllSets) { + contentRoots = (VirtualFile[])reverseArray(contentRoots); + } + + for (int j = 0; j < contentRoots.length; j++) { + final VirtualFile contentRoot = contentRoots[j]; + Set excludeRootsSet = excludeRootsMap.get(contentRoot); + fillMapWithModuleContent(contentRoot, module, contentRoot, excludeRootsSet, forDir); + } + } + + // fill module sources + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + if (progress != null) { + progress.setText2("Processing module \"" + module.getName() + "\" sources..."); + } + + ContentEntry[] contentEntries = rootManager.getContentEntries(); + if (reverseAllSets) { + contentEntries = (ContentEntry[])reverseArray(contentEntries); + } + for (int j = 0; j < contentEntries.length; j++) { + ContentEntry contentEntry = contentEntries[j]; + SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + if (reverseAllSets) { + sourceFolders = (SourceFolder[])reverseArray(sourceFolders); + } + for (int k = 0; k < sourceFolders.length; k++) { + SourceFolder sourceFolder = sourceFolders[k]; + VirtualFile dir = sourceFolder.getFile(); + if (dir != null) { + fillMapWithModuleSource(dir, module, sourceFolder.getPackagePrefix(), dir, sourceFolder.isTestSource(), forDir); + } + } + } + } + + // fill library sources + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + if (progress != null) { + progress.setText2("Processing module \"" + module.getName() + "\" library sources..."); + } + OrderEntry[] orderEntries = rootManager.getOrderEntries(); + for (int j = 0; j < orderEntries.length; j++) { + OrderEntry orderEntry = orderEntries[j]; + + boolean isLibrary = orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry; + if (isLibrary) { + VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); + for (int k = 0; k < sourceRoots.length; k++) { + final VirtualFile sourceRoot = sourceRoots[k]; + fillMapWithLibrarySources(sourceRoot, "", sourceRoot, forDir); + } + } + } + } + + // fill library classes + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + if (progress != null) { + progress.setText2("Processing module \"" + module.getName() + "\" library classes..."); + } + OrderEntry[] orderEntries = rootManager.getOrderEntries(); + for (int j = 0; j < orderEntries.length; j++) { + OrderEntry orderEntry = orderEntries[j]; + + boolean isLibrary = orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry; + if (isLibrary) { + VirtualFile[] classRoots = orderEntry.getFiles(OrderRootType.CLASSES); + for (int k = 0; k < classRoots.length; k++) { + final VirtualFile classRoot = classRoots[k]; + fillMapWithLibraryClasses(classRoot, "", classRoot, forDir); + } + } + } + } + + if (progress != null) { + progress.setText2(""); + } + // fill order entries + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + OrderEntry[] orderEntries = rootManager.getOrderEntries(); + for (int j = 0; j < orderEntries.length; j++) { + OrderEntry orderEntry = orderEntries[j]; + List oneEntryList = Arrays.asList(new OrderEntry[]{orderEntry}); + + + if (orderEntry instanceof ModuleOrderEntry) { + // [dsl] this is probably incorrect. However I do not see any other way (yet) + // to make exporting work. + Module entryModule = null; + + VirtualFile[] importedClassRoots = orderEntry.getFiles(OrderRootType.COMPILATION_CLASSES); + for (int k = 0; k < importedClassRoots.length; k++) { + fillMapWithOrderEntries(importedClassRoots[k], oneEntryList, entryModule, null, null, forDir); + } + + VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); + for (int k = 0; k < sourceRoots.length; k++) { + fillMapWithOrderEntries(sourceRoots[k], oneEntryList, entryModule, null, null, forDir); + } + } + else if (orderEntry instanceof ModuleSourceOrderEntry) { + Module entryModule = orderEntry.getOwnerModule(); + + VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); + for (int k = 0; k < sourceRoots.length; k++) { + fillMapWithOrderEntries(sourceRoots[k], oneEntryList, entryModule, null, null, forDir); + } + } + else if (orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry){ + VirtualFile[] classRoots = orderEntry.getFiles(OrderRootType.CLASSES); + for (int k = 0; k < classRoots.length; k++) { + VirtualFile classRoot = classRoots[k]; + fillMapWithOrderEntries(classRoot, oneEntryList, null, classRoot, null, forDir); + } + + VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); + for (int k = 0; k < sourceRoots.length; k++) { + VirtualFile sourceRoot = sourceRoots[k]; + fillMapWithOrderEntries(sourceRoot, oneEntryList, null, null, sourceRoot, forDir); + } + } + } + } + + if (progress != null) { + progress.popState(); + } + } + + private void putForFileAndAllAncestors(Map> map, VirtualFile file, VirtualFile value) { + while (true) { + Set set = map.get(file); + if (set == null) { + set = new HashSet(); + map.put(file, set); + } + set.add(value); + + file = file.getParent(); + if (file == null) break; + } + } + + // could not make it generic because of bug in compiler :-( + private static Object[] reverseArray(Object[] array) { + Object[] newArray = (Object[])array.clone(); + for (int i = 0; i < array.length; i++) { + Object e = array[i]; + newArray[array.length - i - 1] = e; + } + return newArray; + } + + public DirectoryInfo getInfoForDirectory(VirtualFile dir) { + LOG.assertTrue(myInitialized); + LOG.assertTrue(!myDisposed); + + dispatchPendingEvents(); + + if (LAZY_MODE) { + DirectoryInfo info = myDirToInfoMap.get(dir); + if (info != null) return info; + _initialize(false, dir); + } + + return myDirToInfoMap.get(dir); + } + + public VirtualFile[] getDirectoriesByPackageName(String packageName, boolean includeLibrarySources) { + LOG.assertTrue(myInitialized); + LOG.assertTrue(!myDisposed); + + VirtualFile[] allDirs = getDirectoriesByPackageName(packageName); + if (includeLibrarySources) { + return allDirs; + } + else { + List result = new ArrayList(); + for (int i = 0; i < allDirs.length; i++) { + VirtualFile dir = allDirs[i]; + DirectoryInfo info = getInfoForDirectory(dir); + LOG.assertTrue(info != null); + if (!info.isInLibrarySource || info.libraryClassRoot != null) { + result.add(dir); + } + } + return result.toArray(new VirtualFile[result.size()]); + } + } + + private VirtualFile[] getDirectoriesByPackageName(String packageName) { + dispatchPendingEvents(); + + if (!LAZY_MODE) { + VirtualFile[] dirs = myPackageNameToDirsMap.get(packageName); + return dirs != null ? dirs : VirtualFile.EMPTY_ARRAY; + } + else { + VirtualFile[] dirs = myPackageNameToDirsMap.get(packageName); + if (dirs != null) return dirs; + dirs = _getDirectoriesByPackageNameInLazyMode(packageName); + myPackageNameToDirsMap.put(packageName, dirs); + return dirs; + } + } + + private VirtualFile[] _getDirectoriesByPackageNameInLazyMode(String packageName) { + ArrayList list = new ArrayList(); + + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + + ContentEntry[] contentEntries = rootManager.getContentEntries(); + for (int j = 0; j < contentEntries.length; j++) { + ContentEntry contentEntry = contentEntries[j]; + SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int k = 0; k < sourceFolders.length; k++) { + SourceFolder sourceFolder = sourceFolders[k]; + VirtualFile sourceRoot = sourceFolder.getFile(); + if (sourceRoot != null) { + findAndAddDirByPackageName(list, sourceRoot, packageName); + } + } + } + + OrderEntry[] orderEntries = rootManager.getOrderEntries(); + for (int j = 0; j < orderEntries.length; j++) { + OrderEntry orderEntry = orderEntries[j]; + if (orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry) { + VirtualFile[] libRoots = orderEntry.getFiles(OrderRootType.CLASSES); + for (int k = 0; k < libRoots.length; k++) { + findAndAddDirByPackageName(list, libRoots[k], packageName); + } + + VirtualFile[] libSourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); + for (int k = 0; k < libSourceRoots.length; k++) { + findAndAddDirByPackageName(list, libSourceRoots[k], packageName); + } + } + } + } + + VirtualFile[] result = list.toArray(new VirtualFile[list.size()]); + return result; + } + + private void dispatchPendingEvents() { + if (EventDispatcher.isDispatchingAnyEvent()){ // optimization + VirtualFileManager.getInstance().dispatchPendingEvent(myVirtualFileListener); + ProjectRootManager.getInstance(myProject).dispatchPendingEvent(myRootListener); + //TODO: other listners!!! + } + } + + private void findAndAddDirByPackageName(ArrayList list, VirtualFile root, String packageName) { + VirtualFile dir = findDirByPackageName(root, packageName); + if (dir == null) return; + DirectoryInfo info = getInfoForDirectory(dir); + if (info == null) return; + if (!packageName.equals(info.packageName)) return; + if (!list.contains(dir)) { + list.add(dir); + } + } + + private static VirtualFile findDirByPackageName(VirtualFile root, String packageName) { + if (packageName.length() == 0) { + return root; + } + else { + int index = packageName.indexOf('.'); + if (index < 0) { + VirtualFile child = root.findChild(packageName); + if (child == null || !child.isDirectory()) return null; + return child; + } + else { + String name = packageName.substring(0, index); + String restName = packageName.substring(index + 1); + VirtualFile child = root.findChild(name); + if (child == null || !child.isDirectory()) return null; + return findDirByPackageName(child, restName); + } + } + } + + private void fillMapWithModuleContent(VirtualFile dir, + Module module, + VirtualFile contentRoot, + Set excludeRoots, + VirtualFile forDir) { + if (excludeRoots != null && excludeRoots.contains(dir)) return; + if (FileTypeManager.getInstance().isFileIgnored(dir.getName())) return; + + if (forDir != null) { + if (!VfsUtil.isAncestor(dir, forDir, false)) return; + } + + DirectoryInfo info = getOrCreateDirInfo(dir); + + if (info.module != null) { // module contents overlap + DirectoryInfo parentInfo = myDirToInfoMap.get(dir.getParent()); + if (parentInfo == null || !info.module.equals(parentInfo.module)) return; // content of another module is below this module's content + } + + VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + fillMapWithModuleContent(child, module, contentRoot, excludeRoots, forDir); + } + } + + // important to change module AFTER processing children - to handle overlapping modules + info.module = module; + info.contentRoot = contentRoot; + } + + private void fillMapWithModuleSource(VirtualFile dir, + Module module, + String packageName, + VirtualFile sourceRoot, + boolean isTestSource, + VirtualFile forDir) { + DirectoryInfo info = myDirToInfoMap.get(dir); + if (info == null) return; + if (!module.equals(info.module)) return; + + if (forDir != null) { + if (!VfsUtil.isAncestor(dir, forDir, false)) return; + } + + if (info.isInModuleSource) { // module sources overlap + if (info.packageName != null && info.packageName.length() == 0) return; // another source root starts here + } + + info.isInModuleSource = true; + info.isTestSource = isTestSource; + info.sourceRoot = sourceRoot; + setPackageName(dir, info, packageName); + + VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + String childPackageName = getPackageNameForSubdir(packageName, child.getName()); + fillMapWithModuleSource(child, module, childPackageName, sourceRoot, isTestSource, forDir); + } + } + } + + private void fillMapWithLibraryClasses(VirtualFile dir, + String packageName, + VirtualFile classRoot, + VirtualFile forDir) { + if (FileTypeManager.getInstance().isFileIgnored(dir.getName())) return; + + if (forDir != null) { + if (!VfsUtil.isAncestor(dir, forDir, false)) return; + } + + DirectoryInfo info = getOrCreateDirInfo(dir); + + if (info.libraryClassRoot != null) { // library classes overlap + if (info.packageName != null && info.packageName.length() == 0) return; // another library root starts here + } + + info.libraryClassRoot = classRoot; + + if (!info.isInModuleSource && !info.isInLibrarySource) { + setPackageName(dir, info, packageName); + } + + VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + String childPackageName = getPackageNameForSubdir(packageName, child.getName()); + fillMapWithLibraryClasses(child, childPackageName, classRoot, forDir); + } + } + } + + private void fillMapWithLibrarySources(VirtualFile dir, + String packageName, + VirtualFile sourceRoot, + VirtualFile forDir) { + if (FileTypeManager.getInstance().isFileIgnored(dir.getName())) return; + + if (forDir != null) { + if (!VfsUtil.isAncestor(dir, forDir, false)) return; + } + + DirectoryInfo info = getOrCreateDirInfo(dir); + + if (info.isInLibrarySource) { // library sources overlap + if (info.packageName != null && info.packageName.length() == 0) return; // another library source root starts here + } + + info.isInModuleSource = false; + info.isInLibrarySource = true; + info.sourceRoot = sourceRoot; + setPackageName(dir, info, packageName); + + VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + String childPackageName = getPackageNameForSubdir(packageName, child.getName()); + fillMapWithLibrarySources(child, childPackageName, sourceRoot, forDir); + } + } + } + + private void fillMapWithOrderEntries(VirtualFile dir, + Collection orderEntries, + Module module, + VirtualFile libraryClassRoot, + VirtualFile librarySourceRoot, + VirtualFile forDir) { + if (FileTypeManager.getInstance().isFileIgnored(dir.getName())) return; + + if (forDir != null) { + if (!VfsUtil.isAncestor(dir, forDir, false)) return; + } + + DirectoryInfo info = myDirToInfoMap.get(dir); // do not create it here! + if (info == null) return; + + if (module != null) { + if (info.module != module) return; + if (!info.isInModuleSource) return; + } + else if (libraryClassRoot != null){ + if (info.libraryClassRoot != libraryClassRoot) return; + if (info.isInModuleSource) return; + } + else if (librarySourceRoot != null){ + if (!info.isInLibrarySource) return; + if (info.sourceRoot != librarySourceRoot) return; + if (info.libraryClassRoot != null) return; + } + + info.orderEntries.addAll(orderEntries); + + final VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + fillMapWithOrderEntries(child, orderEntries, module, libraryClassRoot, librarySourceRoot, forDir); + } + } + } + + private DirectoryInfo getOrCreateDirInfo(VirtualFile dir) { + DirectoryInfo info = myDirToInfoMap.get(dir); + if (info == null) { + info = new DirectoryInfo(); + myDirToInfoMap.put(dir, info); + } + return info; + } + + private void setPackageName(VirtualFile dir, DirectoryInfo info, String newPackageName) { + LOG.assertTrue(dir != null); + if (!LAZY_MODE) { + String oldPackageName = info.packageName; + if (oldPackageName != null) { + VirtualFile[] oldPackageDirs = myPackageNameToDirsMap.get(oldPackageName); + LOG.assertTrue(oldPackageDirs != null); + LOG.assertTrue(oldPackageDirs.length > 0); + VirtualFile[] dirs; + if (oldPackageDirs.length != 1) { + dirs = new VirtualFile[oldPackageDirs.length - 1]; + + boolean found = false; + for (int i = 0; i < oldPackageDirs.length; i++) { + VirtualFile oldDir = oldPackageDirs[i]; + if (oldDir.equals(dir)) { + found = true; + continue; + } + dirs[found ? i - 1 : i] = oldDir; + } + LOG.assertTrue(found); + + myPackageNameToDirsMap.put(oldPackageName, dirs); + } + else { + LOG.assertTrue(dir.equals(oldPackageDirs[0])); + myPackageNameToDirsMap.remove(oldPackageName); + } + + } + + if (newPackageName != null) { + VirtualFile[] newPackageDirs = myPackageNameToDirsMap.get(newPackageName); + VirtualFile[] dirs; + if (newPackageDirs == null) { + dirs = new VirtualFile[]{dir}; + } + else { + dirs = new VirtualFile[newPackageDirs.length + 1]; + System.arraycopy(newPackageDirs, 0, dirs, 0, newPackageDirs.length); + dirs[newPackageDirs.length] = dir; + } + myPackageNameToDirsMap.put(newPackageName, dirs); + } + } + else { + if (info.packageName != null) { + myPackageNameToDirsMap.remove(info.packageName); + } + if (newPackageName != null) { + myPackageNameToDirsMap.remove(newPackageName); + } + } + + info.packageName = newPackageName; + } + + private String getPackageNameForSubdir(String parentPackageName, String subdirName) { + if (parentPackageName == null) return null; + if (!myNameHelper.isIdentifier(subdirName)) return null; + return parentPackageName.length() > 0 ? parentPackageName + "." + subdirName : subdirName; + } + + private class MyVirtualFileListener implements VirtualFileListener { + private final Key FILES_TO_RELEASE_KEY = Key.create("DirectoryIndexImpl.MyVirtualFileListener.FILES_TO_RELEASE_KEY"); + + public void fileCreated(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + if (!file.isDirectory()) return; + VirtualFile parent = file.getParent(); + if (parent == null) return; + if (FileTypeManager.getInstance().isFileIgnored(file.getName())) return; + + DirectoryInfo parentInfo = myDirToInfoMap.get(parent); + if (parentInfo == null) return; + + if (!LAZY_MODE) { + if (parentInfo.module != null) { + fillMapWithModuleContent(file, parentInfo.module, parentInfo.contentRoot, null, null); + + if (parentInfo.isInModuleSource) { + String newDirPackageName = getPackageNameForSubdir(parentInfo.packageName, file.getName()); + fillMapWithModuleSource(file, parentInfo.module, newDirPackageName, parentInfo.sourceRoot, + parentInfo.isTestSource, null); + } + } + + if (parentInfo.libraryClassRoot != null) { + String newDirPackageName = getPackageNameForSubdir(parentInfo.packageName, file.getName()); + fillMapWithLibraryClasses(file, newDirPackageName, parentInfo.libraryClassRoot, null); + } + + if (parentInfo.isInLibrarySource) { + String newDirPackageName = getPackageNameForSubdir(parentInfo.packageName, file.getName()); + fillMapWithLibrarySources(file, newDirPackageName, parentInfo.sourceRoot, null); + } + + if (parentInfo.orderEntries.size() > 0) { + fillMapWithOrderEntries(file, parentInfo.orderEntries, null, null, null, null); + } + } + } + + public void beforeFileDeletion(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + if (!file.isDirectory()) return; + if (!myDirToInfoMap.containsKey(file)) return; + + ArrayList list = new ArrayList(); + addDirsRecursively(list, file); + file.putUserData(FILES_TO_RELEASE_KEY, list); + } + + private void addDirsRecursively(ArrayList list, VirtualFile dir) { + if (!myDirToInfoMap.containsKey(dir)) return; + + list.add(dir); + + VirtualFile[] children = dir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + addDirsRecursively(list, child); + } + } + } + + public void fileDeleted(VirtualFileEvent event) { + VirtualFile file = event.getFile(); + ArrayList list = (ArrayList)file.getUserData(FILES_TO_RELEASE_KEY); + if (list == null) return; + + for (int i = 0; i < list.size(); i++) { + VirtualFile dir = list.get(i); + DirectoryInfo info = myDirToInfoMap.remove(dir); + if (info != null) { + setPackageName(dir, info, null); + } + } + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + } + + public void fileMoved(VirtualFileMoveEvent event) { + VirtualFile file = event.getFile(); + if (file.isDirectory()) { + _initialize(); + } + } + + public void beforePropertyChange(VirtualFilePropertyEvent event) { + } + + public void propertyChanged(VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { + VirtualFile file = event.getFile(); + if (file.isDirectory()) { + _initialize(); + } + } + } + + public void contentsChanged(VirtualFileEvent event) { + } + + public void beforeContentsChange(VirtualFileEvent event) { + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryInfo.java new file mode 100644 index 00000000000..21d8c5083bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -0,0 +1,61 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ArrayListSet; + +import java.util.Set; + +public class DirectoryInfo { + public Module module; // module to which content it belongs or null + public boolean isInModuleSource; // true if files in this directory belongs to sources of the module (if field 'module' is not null) + public boolean isTestSource; // (makes sense only if isInModuleSource is true) + public boolean isInLibrarySource; // true if it's a directory with sources of some library + public String packageName; // package name; makes sense only when at least one of isInModuleSource, isInLibrary or isInLibrarySource is true + public VirtualFile libraryClassRoot; // class root in library + public VirtualFile contentRoot; + public VirtualFile sourceRoot; + + /** + * orderEntry to (classes of) which a directory belongs + */ + public Set orderEntries = new ArrayListSet(); + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DirectoryInfo)) return false; + + final DirectoryInfo info = (DirectoryInfo)o; + + if (isInLibrarySource != info.isInLibrarySource) return false; + if (isInModuleSource != info.isInModuleSource) return false; + if (isTestSource != info.isTestSource) return false; + if (module != null ? !module.equals(info.module) : info.module != null) return false; + if (packageName != null ? !packageName.equals(info.packageName) : info.packageName != null) return false; + if (orderEntries != null ? !orderEntries.equals(info.orderEntries) : info.orderEntries != null) return false; + if (!Comparing.equal(libraryClassRoot, info.libraryClassRoot)) return false; + if (!Comparing.equal(contentRoot, info.contentRoot)) return false; + if (!Comparing.equal(sourceRoot, info.sourceRoot)) return false; + + return true; + } + + public int hashCode() { + return (packageName != null ? packageName.hashCode() : 0); + } + + public String toString() { + return "DirectoryInfo{" + + "module=" + module + + ", isInModuleSource=" + isInModuleSource + + ", isTestSource=" + isTestSource + + ", isInLibrarySource=" + isInLibrarySource + + ", packageName=" + packageName + + ", libraryClassRoot=" + libraryClassRoot + + ", contentRoot=" + contentRoot + + ", sourceRoot=" + sourceRoot + + "}"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java new file mode 100644 index 00000000000..604ac0574ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.roots.UserDefinedExcludeFolder; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; + +/** + * @author dsl + */ +public class ExcludeFolderImpl extends ContentFolderBaseImpl implements ClonableContentFolder, + UserDefinedExcludeFolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleExcludeFolderImpl"); + static final String ELEMENT_NAME = "excludeFolder"; + + ExcludeFolderImpl(VirtualFile file, ContentEntryImpl contentEntry) { + super(file, contentEntry); + } + + ExcludeFolderImpl(Element element, ContentEntryImpl contentEntry) throws InvalidDataException { + super(element, contentEntry); + LOG.assertTrue(ELEMENT_NAME.equals(element.getName())); + } + + public ExcludeFolderImpl(ExcludeFolderImpl that, ContentEntryImpl contentEntry) { + super(that, contentEntry); + } + + public void writeExternal(Element element) { + writeFolder(element, ELEMENT_NAME); + } + + public ContentFolder cloneFolder(ContentEntry contentEntry) { + return new ExcludeFolderImpl(this, (ContentEntryImpl)contentEntry); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludedOutputFolderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludedOutputFolderImpl.java new file mode 100644 index 00000000000..236df9e4869 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ExcludedOutputFolderImpl.java @@ -0,0 +1,41 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ExcludedOutputFolder; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; + +/** + * @author dsl + */ +public class ExcludedOutputFolderImpl implements ExcludedOutputFolder { + private final ContentEntryImpl myContentEntry; + private final VirtualFilePointer myOutputPath; + + ExcludedOutputFolderImpl(ContentEntryImpl contentEntry, VirtualFilePointer outputPath) { + myContentEntry = contentEntry; + myOutputPath = outputPath; + } + + public VirtualFile getFile() { + final VirtualFile file = myOutputPath.getFile(); + if (file == null || file.isDirectory()) { + return file; + } + else { + return null; + } + } + + public ContentEntry getContentEntry() { + return myContentEntry; + } + + public String getUrl() { + return myOutputPath.getUrl(); + } + + public boolean isSynthetic() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/FileIndexImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/FileIndexImplUtil.java new file mode 100644 index 00000000000..22990eb47e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/FileIndexImplUtil.java @@ -0,0 +1,22 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; + +class FileIndexImplUtil { + public static boolean iterateRecursively(VirtualFile root, VirtualFileFilter filter, ContentIterator iterator){ + if (!filter.accept(root)) return true; + + if (!iterator.processFile(root)) return false; + + if (root.isDirectory()){ + VirtualFile[] children = root.getChildren(); + for(int i = 0; i < children.length; i++){ + if (!iterateRecursively(children[i], filter, iterator)) return false; + } + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java new file mode 100644 index 00000000000..1413e0d9f01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java @@ -0,0 +1,143 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.roots.InheritedJdkOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +/** + * @author dsl + */ +public class InheritedJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implements InheritedJdkOrderEntry, ClonableOrderEntry, + WritableOrderEntry { + private final ProjectRootManagerEx myProjectRootManager; + static final String ENTRY_TYPE = "inheritedJdk"; + private final MyJdkTableListener myJdkTableListener = new MyJdkTableListener(); + private final MyProjectJdkListener myListener = new MyProjectJdkListener(); + + InheritedJdkOrderEntryImpl(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + myProjectRootManager = projectRootManager; + myProjectRootManager.addProjectJdkListener(myListener); + init(getRootProvider()); + myProjectRootManagerImpl.addJdkTableListener(myJdkTableListener); + } + + + /** + * @param element + * @param rootModel + * @param projectRootManager + * @param filePointerManager + * @throws InvalidDataException + */ + InheritedJdkOrderEntryImpl(Element element, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + super(rootModel, projectRootManager, filePointerManager); + if (!element.getName().equals(OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME)) { + throw new InvalidDataException(); + } + myProjectRootManager = projectRootManager; + myProjectRootManager.addProjectJdkListener(myListener); + init(getRootProvider()); + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + return new InheritedJdkOrderEntryImpl(rootModel, projectRootManager, filePointerManager); + } + + public boolean isSynthetic() { + return false; + } + + public boolean isValid() { + return true; + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitInheritedJdkOrderEntry(this, initialValue); + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + final Element orderEntryElement = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + rootElement.addContent(orderEntryElement); + } + + public ProjectJdk getJdk() { + return myProjectRootManager.getProjectJdk(); + } + + public String getJdkName() { + return myProjectRootManager.getProjectJdkName(); + } + + private RootProvider getRootProvider() { + final ProjectJdk projectJdk = myProjectRootManager.getProjectJdk(); + if (projectJdk != null) { + return projectJdk.getRootProvider(); + } + else { + return null; + } + } + + + public String getPresentableName() { + return "< " + getJdkName() + " >"; + } + + protected void dispose() { + super.dispose(); + myProjectRootManagerImpl.removeJdkTableListener(myJdkTableListener); + } + + + private class MyJdkTableListener implements ProjectJdkTable.Listener { + public void jdkRemoved(ProjectJdk jdk) { + if (isAffectedByJdkAddition(jdk)) { + updateFromRootProviderAndSubscribe(null); + } + } + + private boolean isAffectedByJdkAddition(ProjectJdk jdk) { + return jdk.equals(getJdk()); + } + + public void jdkAdded(ProjectJdk jdk) { + if (isAffectedByJdkRemoval(jdk)) { + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + public void jdkNameChanged(ProjectJdk jdk, String previousName) { + String currentName = getJdkName(); + if (jdk.getName().equals(currentName)) { + // if current name matches my name + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + private boolean isAffectedByJdkRemoval(ProjectJdk jdk) { + return jdk.getName().equals(getJdkName()); + } + } + + private class MyProjectJdkListener implements ProjectRootManagerEx.ProjectJdkListener { + public void projectJdkChanged() { + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryBaseImpl.java new file mode 100644 index 00000000000..239ff760c81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryBaseImpl.java @@ -0,0 +1,166 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.containers.HashMap; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +abstract class LibraryOrderEntryBaseImpl extends OrderEntryBaseImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LibraryOrderEntryBaseImpl"); + protected final RootModelImpl myRootModel; + private final HashMap myRootContainers; + private final MyRootSetChangedListener myRootSetChangedListener = new MyRootSetChangedListener(); + private RootProvider myCurrentlySubscribedRootProvider = null; + protected final ProjectRootManagerImpl myProjectRootManagerImpl; + + LibraryOrderEntryBaseImpl(RootModelImpl rootModel, ProjectRootManagerImpl instanceImpl, VirtualFilePointerManager filePointerManager) { + super(rootModel); + myRootModel = rootModel; + myRootContainers = new HashMap(); + for (int i = 0; i < OrderRootType.ALL_TYPES.length; i++) { + OrderRootType type = OrderRootType.ALL_TYPES[i]; + myRootContainers.put(type, filePointerManager.createContainer(myRootModel.pointerFactory())); + } + myProjectRootManagerImpl = instanceImpl; + } + + protected final void init(RootProvider rootProvider) { + if (rootProvider == null) return; + updatePathsFromProviderAndSubscribe(rootProvider); + } + + protected void updatePathsFromProviderAndSubscribe(final RootProvider rootProvider) { + updatePathsFromProvider(rootProvider); + resubscribe(rootProvider); + } + + private void updatePathsFromProvider(final RootProvider rootProvider) { + final OrderRootType[] allTypes = OrderRootType.ALL_TYPES; + for (int i = 0; i < allTypes.length; i++) { + OrderRootType type = allTypes[i]; + final VirtualFilePointerContainer container = myRootContainers.get(type); + container.clear(); + if (rootProvider != null) { + final String[] urls = rootProvider.getUrls(type); + for (int j = 0; j < urls.length; j++) { + String url = urls[j]; + container.add(url); + } + } + } + } + + private boolean needUpdateFromProvider(final RootProvider rootProvider) { + final OrderRootType[] allTypes = OrderRootType.ALL_TYPES; + for (int i = 0; i < allTypes.length; i++) { + OrderRootType type = allTypes[i]; + final VirtualFilePointerContainer container = myRootContainers.get(type); + final String[] urls = container.getUrls(); + final String[] providerUrls = rootProvider.getUrls(type); + if (!Arrays.equals(urls, providerUrls)) return true; + } + return false; + } + + public VirtualFile[] getFiles(OrderRootType type) { + return myRootContainers.get(type).getDirectories(); + } + + public VirtualFilePointer[] getFilePointers(OrderRootType type) { + final List list = myRootContainers.get(type).getList(); + return (VirtualFilePointer[])list.toArray(new VirtualFilePointer[list.size()]); + } + + public abstract boolean isValid(); + + public String[] getUrls(OrderRootType type) { + LOG.assertTrue(!myRootModel.getModule().isDisposed()); + return myRootContainers.get(type).getUrls(); + } + + public final Module getOwnerModule() { + return myRootModel.getModule(); + } + + protected void updateFromRootProviderAndSubscribe(RootProvider wrapper) { + myRootModel.fireBeforeExternalChange(); + updatePathsFromProviderAndSubscribe(wrapper); + myRootModel.fireAfterExternalChange(); + } + + private void updateFromRootProvider(RootProvider wrapper) { + myRootModel.fireBeforeExternalChange(); + updatePathsFromProvider(wrapper); + myRootModel.fireAfterExternalChange(); + } + + private void resubscribe(RootProvider wrapper) { + unsubscribe(); + subscribe(wrapper); + } + + private void subscribe(RootProvider wrapper) { + if (wrapper != null) { + addListenerToWrapper(wrapper, myRootSetChangedListener); + } + myCurrentlySubscribedRootProvider = wrapper; + } + + protected void addListenerToWrapper(final RootProvider wrapper, + final RootProvider.RootSetChangedListener rootSetChangedListener) { + myProjectRootManagerImpl.addRootSetChangedListener(rootSetChangedListener, wrapper); + } + + + private void unsubscribe() { + if (myCurrentlySubscribedRootProvider != null) { + final RootProvider wrapper = myCurrentlySubscribedRootProvider; + removeListenerFromWrapper(wrapper, myRootSetChangedListener); + } + myCurrentlySubscribedRootProvider = null; + } + + protected void removeListenerFromWrapper(final RootProvider wrapper, + final RootProvider.RootSetChangedListener rootSetChangedListener) { + myProjectRootManagerImpl.removeRootSetChangedListener(rootSetChangedListener, wrapper); + } + + + protected void dispose() { + super.dispose(); + final Collection virtualFilePointerContainers = myRootContainers.values(); + for (Iterator iterator = virtualFilePointerContainers.iterator(); iterator.hasNext();) { + VirtualFilePointerContainer virtualFilePointerContainer = iterator.next(); + virtualFilePointerContainer.killAll(); + } + unsubscribe(); + } + + private class MyRootSetChangedListener implements RootProvider.RootSetChangedListener { + + public MyRootSetChangedListener() { + } + + public void rootSetChanged(RootProvider wrapper) { + if (LibraryOrderEntryBaseImpl.this.needUpdateFromProvider(wrapper)) { + LibraryOrderEntryBaseImpl.this.updateFromRootProvider(wrapper); + } + } + + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java new file mode 100644 index 00000000000..946d24d7dc8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java @@ -0,0 +1,237 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +/** + * @author dsl + */ +class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements + LibraryOrderEntry, ClonableOrderEntry, WritableOrderEntry { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LibraryOrderEntryImpl"); + private Library myLibrary; + private String myLibraryName; // is non-null if myLibrary == null + private String myLibraryLevel; // is non-null if myLibraryLevel == null + private boolean myExported; + static final String ENTRY_TYPE = "library"; + private static final String NAME_ATTR = "name"; + private static final String LEVEL_ATTR = "level"; + private final MyOrderEntryLibraryTableListener myLibraryListener = new MyOrderEntryLibraryTableListener(); + private static final String EXPORTED_ATTR = "exported"; + + LibraryOrderEntryImpl (Library library, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager virtualFilePointerManager) { + super(rootModel, projectRootManager, virtualFilePointerManager); + LOG.assertTrue(library.getTable() != null); + myLibrary = library; + init(getRootProvider()); + addListeners(); + } + + LibraryOrderEntryImpl (Element element, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + super(rootModel, projectRootManager, filePointerManager); + LOG.assertTrue(ENTRY_TYPE.equals(element.getAttributeValue(OrderEntryFactory.ORDER_ENTRY_TYPE_ATTR))); + myExported = element.getAttributeValue(EXPORTED_ATTR) != null; + String level = element.getAttributeValue(LEVEL_ATTR); + String name = element.getAttributeValue(NAME_ATTR); + if (name == null) throw new InvalidDataException(); + if (level == null) throw new InvalidDataException(); + searchForLibrary(level, name); + init(getRootProvider()); + addListeners(); + } + + private LibraryOrderEntryImpl(LibraryOrderEntryImpl that, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super (rootModel, projectRootManager, filePointerManager); + if (that.myLibrary == null) { + myLibraryName = that.myLibraryName; + myLibraryLevel = that.myLibraryLevel; + } else { + myLibrary = that.myLibrary; + } + myExported = that.myExported; + init (getRootProvider()); + addListeners(); + } + + public LibraryOrderEntryImpl(String name, + String level, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + LOG.assertTrue(name != null); + LOG.assertTrue(level != null); + searchForLibrary(level, name); + init(getRootProvider()); + addListeners(); + } + + private void searchForLibrary(String level, String name) { + if (myLibrary != null) return; + final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, myRootModel.getModule().getProject()); + final Library library = (libraryTable != null)? libraryTable.getLibraryByName(name) : null; + if (library == null) { + myLibraryName = name; + myLibraryLevel = level; + myLibrary = null; + } else { + myLibraryName = null; + myLibraryLevel = null; + myLibrary = library; + } + } + + public boolean isExported() { + return myExported; + } + + public void setExported(boolean exported) { + myExported = exported; + } + + public Library getLibrary() { + return myLibrary; + } + + public boolean isModuleLevel() { + return false; + } + + public String getPresentableName() { + return getLibraryName(); + } + + private RootProvider getRootProvider() { + if (myLibrary != null) { + return myLibrary.getRootProvider(); + } else { + return null; + } + } + + public boolean isValid() { + return myLibrary != null; + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitLibraryOrderEntry(this, initialValue); + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + return new LibraryOrderEntryImpl(this, rootModel, ProjectRootManagerImpl.getInstanceImpl(myRootModel.getModule().getProject()), VirtualFilePointerManager.getInstance()); + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + final Element element = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + final String libraryLevel = getLibraryLevel(); + if (myExported) { + element.setAttribute(EXPORTED_ATTR, ""); + } + element.setAttribute(NAME_ATTR, getLibraryName()); + element.setAttribute(LEVEL_ATTR, libraryLevel); + rootElement.addContent(element); + } + + public String getLibraryLevel() { + if (myLibrary != null) { + final LibraryTable table = myLibrary.getTable(); + return table.getTableLevel(); + } else { + return myLibraryLevel; + } + } + + public String getLibraryName() { + if (myLibrary != null) { + return myLibrary.getName(); + } else { + return myLibraryName; + } + } + + private void addListeners () { + final String libraryLevel = getLibraryLevel(); + final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(libraryLevel, myRootModel.getModule().getProject()); + if (libraryTable != null) { + myProjectRootManagerImpl.addListenerForTable(myLibraryListener, libraryTable); + } + } + + + public boolean isSynthetic() { + return false; + } + + protected void dispose() { + super.dispose(); + final LibraryTable libraryTable = (LibraryTable)LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(getLibraryLevel(), myRootModel.getModule().getProject()); + if (libraryTable != null) { + myProjectRootManagerImpl.removeListenerForTable(myLibraryListener, libraryTable); + } + } + + + public void afterLibraryAdded(Library newLibrary) { + if (myLibrary == null) { + if (Comparing.equal(myLibraryName, newLibrary.getName())) { + myLibrary = newLibrary; + myLibraryName = null; + myLibraryLevel = null; + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + } + + + public void beforeLibraryRemoved(Library library) { + if (library == myLibrary) { + myLibraryName = myLibrary.getName(); + myLibraryLevel = myLibrary.getTable().getTableLevel(); + myLibrary = null; + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + private class MyOrderEntryLibraryTableListener implements LibraryTable.Listener { + public MyOrderEntryLibraryTableListener() { + } + + public void afterLibraryAdded(Library newLibrary) { + LibraryOrderEntryImpl.this.afterLibraryAdded(newLibrary); + } + + public void afterLibraryRenamed(Library library) { + afterLibraryAdded(library); + } + + public void beforeLibraryRemoved(Library library) { + LibraryOrderEntryImpl.this.beforeLibraryRemoved(library); + } + + public void afterLibraryRemoved(Library library) { + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java new file mode 100644 index 00000000000..7a88b207174 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java @@ -0,0 +1,135 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.ModuleFileIndex; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; + +public class ModuleFileIndexImpl implements ModuleFileIndex { + private final Module myModule; + private final FileTypeManager myFileTypeManager; + private final DirectoryIndex myDirectoryIndex; + private final ContentFilter myContentFilter; + + public ModuleFileIndexImpl(Module module, DirectoryIndex directoryIndex) { + myModule = module; + myDirectoryIndex = directoryIndex; + myFileTypeManager = FileTypeManager.getInstance(); + + myContentFilter = new ContentFilter(); + } + + public boolean iterateContent(ContentIterator iterator) { + VirtualFile[] contentRoots = ModuleRootManager.getInstance(myModule).getContentRoots(); + for (int j = 0; j < contentRoots.length; j++) { + VirtualFile contentRoot = contentRoots[j]; + + VirtualFile parent = contentRoot.getParent(); + if (parent != null) { + DirectoryInfo parentInfo = myDirectoryIndex.getInfoForDirectory(parent); + if (parentInfo != null && myModule.equals(parentInfo.module)) continue; // inner content - skip it + } + + boolean finished = FileIndexImplUtil.iterateRecursively(contentRoot, myContentFilter, iterator); + if (!finished) return false; + } + + return true; + } + + public boolean iterateContentUnderDirectory(VirtualFile dir, ContentIterator iterator) { + return FileIndexImplUtil.iterateRecursively(dir, myContentFilter, iterator); + } + + public boolean isContentJavaSourceFile(VirtualFile file) { + if (file.isDirectory()) return false; + if (myFileTypeManager.getFileTypeByFile(file) != StdFileTypes.JAVA) return false; + if (myFileTypeManager.isFileIgnored(file.getName())) return false; + return isInSourceContent(file); + } + + public boolean isInContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && myModule.equals(info.module); + } + else { + VirtualFile parent = fileOrDir.getParent(); + if (parent == null) return false; + return isInContent(parent); + } + } + + public boolean isInSourceContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && info.isInModuleSource && myModule.equals(info.module); + } + else { + VirtualFile parent = fileOrDir.getParent(); + if (parent == null) return false; + return isInSourceContent(parent); + } + } + + public OrderEntry getOrderEntryForFile(VirtualFile fileOrDir) { + VirtualFile dir = fileOrDir.isDirectory() ? fileOrDir : fileOrDir.getParent(); + if (dir == null) return null; + final DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + final Set orderEntries = info.orderEntries; + for (Iterator iterator = orderEntries.iterator(); iterator.hasNext();) { + OrderEntry orderEntry = iterator.next(); + if (orderEntry.getOwnerModule() == myModule) return orderEntry; + } + return null; + } + + public boolean isInTestSourceContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && info.isInModuleSource && info.isTestSource && myModule.equals(info.module); + } + else { + VirtualFile parent = fileOrDir.getParent(); + if (parent == null) return false; + return isInTestSourceContent(parent); + } + } + + public VirtualFile[] getDirectoriesByPackageName(String packageName, boolean includeLibrarySources) { + VirtualFile[] allDirs = myDirectoryIndex.getDirectoriesByPackageName(packageName, includeLibrarySources); + if (allDirs.length == 0) return allDirs; + + ArrayList list = new ArrayList(); + for (int i = 0; i < allDirs.length; i++) { + VirtualFile dir = allDirs[i]; + if (getOrderEntryForFile(dir) != null) { + list.add(dir); + } + } + return list.toArray(new VirtualFile[list.size()]); + } + + private class ContentFilter implements VirtualFileFilter { + public boolean accept(VirtualFile file) { + if (file.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(file); + if (info == null) return false; + return myModule.equals(info.module); + } + else { + return !myFileTypeManager.isFileIgnored(file.getName()); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java new file mode 100644 index 00000000000..ab28e2ab5a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java @@ -0,0 +1,175 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.roots.ModuleJdkOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Attribute; +import org.jdom.Element; + +/** + * @author dsl + */ +public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implements WritableOrderEntry, + ClonableOrderEntry, + ModuleJdkOrderEntry, + ProjectJdkTable.Listener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.JdkLibraryEntryImpl"); + static final String ENTRY_TYPE = "jdk"; + private static final String JDK_NAME_ATTR = "jdkName"; + + private ProjectJdk myJdk; + private String myJdkName; + + ModuleJdkOrderEntryImpl(ProjectJdk projectJdk, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + LOG.assertTrue(projectJdk != null); + myJdk = projectJdk; + setJdkName(null); + init(getRootProvider()); + addListener(); + } + + ModuleJdkOrderEntryImpl(Element element, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + super(rootModel, projectRootManager, filePointerManager); + if (!element.getName().equals(OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME)) { + throw new InvalidDataException(); + } + final Attribute jdkNameAttribute = element.getAttribute(JDK_NAME_ATTR); + if (jdkNameAttribute == null) { + throw new InvalidDataException(); + } + + final String jdkName = jdkNameAttribute.getValue(); + final ProjectJdkTable projectJdkTable = ProjectJdkTable.getInstance(); + final ProjectJdk jdkByName = projectJdkTable.findJdk(jdkName); + if (jdkByName == null) { + myJdk = null; + setJdkName(jdkName); + } + else { + myJdk = jdkByName; + setJdkName(null); + } + init(getRootProvider()); + addListener(); + } + + private ModuleJdkOrderEntryImpl(ModuleJdkOrderEntryImpl that, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + myJdk = that.myJdk; + setJdkName(that.getJdkName()); + init(getRootProvider()); + addListener(); + } + + private void addListener() { + myProjectRootManagerImpl.addJdkTableListener(this); + } + + private RootProvider getRootProvider() { + if (myJdk != null) { + return myJdk.getRootProvider(); + } + else { + return null; + } + } + + public ProjectJdk getJdk() { + return myJdk; + } + + public String getJdkName() { + if (myJdk != null) { + return myJdk.getName(); + } + else { + return myJdkName; + } + } + + public boolean isSynthetic() { + return true; + } + + + public String getPresentableName() { + if (myJdk != null) { + return "< " + myJdk.getName() + " >"; + } + else { + return "< " + getJdkName() + " >"; + } + } + + public boolean isValid() { + return myJdk != null; + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitModuleJdkOrderEntry(this, initialValue); + } + + public void jdkAdded(ProjectJdk jdk) { + if (myJdk == null && getJdkName().equals(jdk.getName())) { + myJdk = jdk; + myJdkName = null; + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + public void jdkNameChanged(ProjectJdk jdk, String previousName) { + if (myJdk == null && getJdkName().equals(jdk.getName())) { + myJdk = jdk; + myJdkName = null; + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + public void jdkRemoved(ProjectJdk jdk) { + if (jdk == myJdk) { + setJdkName(myJdk.getName()); + myJdk = null; + updateFromRootProviderAndSubscribe(getRootProvider()); + } + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + final Element element = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + element.setAttribute(JDK_NAME_ATTR, myJdk != null ? myJdk.getName() : getJdkName()); + rootElement.addContent(element); + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + return new ModuleJdkOrderEntryImpl(this, rootModel, ProjectRootManagerImpl.getInstanceImpl(myRootModel.getModule().getProject()), + VirtualFilePointerManager.getInstance()); + } + + protected void dispose() { + super.dispose(); + myProjectRootManagerImpl.removeJdkTableListener(this); + } + + private void setJdkName(String jdkName) { + myJdkName = jdkName; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java new file mode 100644 index 00000000000..bb1772d5f10 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java @@ -0,0 +1,146 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.libraries.LibraryEx; +import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +/** + * Library entry for moduler ("in-place") libraries + * @author dsl + */ +class ModuleLibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements + LibraryOrderEntry, ClonableOrderEntry, WritableOrderEntry { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LibraryOrderEntryImpl"); + private final Library myLibrary; + static final String ENTRY_TYPE = "module-library"; + private boolean myExported; + private static final String EXPORTED_ATTR = "exported"; + + private ModuleLibraryOrderEntryImpl (Library library, + RootModelImpl rootModel, + boolean isExported, + ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + myLibrary = library; + ((LibraryEx) myLibrary).setRootModel(myRootModel); + init(myLibrary.getRootProvider()); + myExported = isExported; + } + + ModuleLibraryOrderEntryImpl (RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + this ((String) null, rootModel, projectRootManager, filePointerManager); + } + + ModuleLibraryOrderEntryImpl (String name, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + super(rootModel, projectRootManager, filePointerManager); + if (name != null) { + myLibrary = LibraryTableImplUtil.createModuleLevelLibrary(name); + } else { + myLibrary = LibraryTableImplUtil.createModuleLevelLibrary(); + } + ((LibraryEx)myLibrary).setRootModel(myRootModel); + init(myLibrary.getRootProvider()); + } + + ModuleLibraryOrderEntryImpl (Element element, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + super(rootModel, projectRootManager, filePointerManager); + LOG.assertTrue(ENTRY_TYPE.equals(element.getAttributeValue(OrderEntryFactory.ORDER_ENTRY_TYPE_ATTR))); + myExported = element.getAttributeValue(EXPORTED_ATTR) != null; + myLibrary = LibraryTableImplUtil.loadLibrary(element, null); + ((LibraryEx)myLibrary).setRootModel(myRootModel); + init(myLibrary.getRootProvider()); + } + + public Library getLibrary() { + return myLibrary; + } + + public boolean isModuleLevel() { + return true; + } + + protected void addListenerToWrapper(RootProvider wrapper, + RootProvider.RootSetChangedListener rootSetChangedListener) { + wrapper.addRootSetChangedListener(rootSetChangedListener); + } + + protected void removeListenerFromWrapper(RootProvider wrapper, + RootProvider.RootSetChangedListener rootSetChangedListener) { + wrapper.removeRootSetChangedListener(rootSetChangedListener); + } + + public String getLibraryName() { + return myLibrary.getName(); + } + + public String getLibraryLevel() { + return LibraryTableImplUtil.MODULE_LEVEL; + } + + public String getPresentableName() { + final String name = myLibrary.getName(); + if (name != null) { + return name; + } else { + final String[] urls = myLibrary.getUrls(OrderRootType.CLASSES); + if (urls.length > 0) { + return urls[0]; + } else { + return null; + } + } + } + + public boolean isValid() { + return true; + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitLibraryOrderEntry(this, initialValue); + } + + public boolean isSynthetic() { + return true; + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + final Library thatLibrary; + thatLibrary = ((LibraryEx) myLibrary).cloneLibrary(); + + return new ModuleLibraryOrderEntryImpl(thatLibrary, rootModel, myExported, ProjectRootManagerImpl.getInstanceImpl(myRootModel.getModule().getProject()), VirtualFilePointerManager.getInstance()); + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + final Element element = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + if (myExported) { + element.setAttribute(EXPORTED_ATTR, ""); + } + myLibrary.writeExternal(element); + rootElement.addContent(element); + } + + + public boolean isExported() { + return myExported; + } + + public void setExported(boolean value) { + myExported = value; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryTable.java new file mode 100644 index 00000000000..b5c81dc6303 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleLibraryTable.java @@ -0,0 +1,120 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.ConvertingIterator; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.FilteringIterator; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author dsl + */ +public class ModuleLibraryTable implements LibraryTable, LibraryTable.ModifiableModel { + private RootModelImpl myRootModel; + private static final ModuleLibraryOrderEntryCondition MODULE_LIBRARY_ORDER_ENTRY_FILTER = new ModuleLibraryOrderEntryCondition(); + private static final OrderEntryToLibraryConvertor ORDER_ENTRY_TO_LIBRARY_CONVERTOR = new OrderEntryToLibraryConvertor(); + private ProjectRootManagerImpl myProjectRootManager; + private VirtualFilePointerManager myFilePointerManager; + + ModuleLibraryTable(RootModelImpl rootModel, ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager) { + myRootModel = rootModel; + myProjectRootManager = projectRootManager; + myFilePointerManager = filePointerManager; + } + + public Library[] getLibraries() { + final ArrayList result = new ArrayList(); + final Iterator libraryIterator = getLibraryIterator(); + ContainerUtil.addAll(result, libraryIterator); + return (Library[]) result.toArray(new Library[result.size()]); + } + + public Library createLibrary() { + final ModuleLibraryOrderEntryImpl orderEntry = new ModuleLibraryOrderEntryImpl(myRootModel, myProjectRootManager, myFilePointerManager); + myRootModel.addOrderEntry(orderEntry); + return orderEntry.getLibrary(); + } + + public Library createLibrary(String name) { + final ModuleLibraryOrderEntryImpl orderEntry = new ModuleLibraryOrderEntryImpl(name, myRootModel, myProjectRootManager, VirtualFilePointerManager.getInstance()); + myRootModel.addOrderEntry(orderEntry); + return orderEntry.getLibrary(); + } + + public void removeLibrary(Library library) { + final Iterator orderIterator = myRootModel.getOrderIterator(); + while (orderIterator.hasNext()) { + OrderEntry orderEntry = (OrderEntry) orderIterator.next(); + if (orderEntry instanceof LibraryOrderEntry) { + final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry; + if (libraryOrderEntry.isModuleLevel()) { + if (library.equals(libraryOrderEntry.getLibrary())) { + myRootModel.removeOrderEntry(orderEntry); + return; + } + } + } + } + } + + public Iterator getLibraryIterator() { + return new ConvertingIterator( + new FilteringIterator(myRootModel.getOrderIterator(), MODULE_LIBRARY_ORDER_ENTRY_FILTER), + ORDER_ENTRY_TO_LIBRARY_CONVERTOR); + } + + public String getTableLevel() { + return LibraryTableImplUtil.MODULE_LEVEL; + } + + public Library getLibraryByName(String name) { + final Iterator libraryIterator = getLibraryIterator(); + while (libraryIterator.hasNext()) { + Library library = (Library) libraryIterator.next(); + if (name.equals(library.getName())) return library; + } + return null; + } + + public void addListener(Listener listener) { + throw new UnsupportedOperationException(); + } + + public void removeListener(Listener listener) { + throw new UnsupportedOperationException(); + } + + + + private static class ModuleLibraryOrderEntryCondition implements Condition { + public boolean value(OrderEntry entry) { + return (entry instanceof LibraryOrderEntry) && ((LibraryOrderEntry)entry).isModuleLevel() && ((LibraryOrderEntry)entry).getLibrary() != null; + } + } + + private static class OrderEntryToLibraryConvertor implements Convertor { + public Object convert(Object o) { + return ((LibraryOrderEntry) o).getLibrary(); + } + } + + public void commit() { + } + + public boolean isChanged() { + return myRootModel.isChanged(); + } + + public LibraryTable.ModifiableModel getModifiableModel() { + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java new file mode 100644 index 00000000000..01c4cabdc5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java @@ -0,0 +1,260 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.ModuleListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.containers.HashSet; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author dsl + */ +public class ModuleOrderEntryImpl extends OrderEntryBaseImpl implements ModuleOrderEntry, WritableOrderEntry, ClonableOrderEntry { + static final String ENTRY_TYPE = "module"; + private Module myModule; + private String myModuleName; // non-null if myProject is null + private static final String MODULE_NAME_ATTR = "module-name"; + private final MyModuleListener myListener = new MyModuleListener(); + protected boolean myExported = false; + protected static final String EXPORTED_ATTR = "exported"; + + ModuleOrderEntryImpl(Module module, RootModelImpl rootModel) { + super(rootModel); + myModule = module; + } + + ModuleOrderEntryImpl(String moduleName, RootModelImpl rootModel) { + super(rootModel); + myModuleName = moduleName; + myModule = null; + } + + ModuleOrderEntryImpl(Element element, RootModelImpl rootModel) throws InvalidDataException { + super(rootModel); + myExported = element.getAttributeValue(EXPORTED_ATTR) != null; + final String moduleName = element.getAttributeValue(MODULE_NAME_ATTR); + if (moduleName == null) { + throw new InvalidDataException(); + } + + myModule = null; + myModuleName = moduleName; + //addListeners(); // Q???? + } + + private ModuleOrderEntryImpl(ModuleOrderEntryImpl that, RootModelImpl rootModel) { + super(rootModel); + final Module thatModule = that.myModule; + if (thatModule != null) { + if (!thatModule.isDisposed()) { + myModule = thatModule; + } else { + myModule = null; + myModuleName = thatModule.getName(); + } + } + else { + myModuleName = that.myModuleName; + } + myExported = that.myExported; + addListeners(); + } + + private boolean myListenersAdded = false; + + private void addListeners() { + myListenersAdded = true; + ModuleManager.getInstance(myRootModel.getModule().getProject()).addModuleListener(myListener); + } + + public Module getOwnerModule() { + return myRootModel.getModule(); + } + + public VirtualFile[] getFiles(OrderRootType type) { + return getFiles(type, new HashSet()); + } + + VirtualFile[] getFiles(OrderRootType type, Set processed) { + if (myModule != null && !processed.contains(myModule)) { + processed.add(myModule); + return ((ModuleRootManagerImpl)ModuleRootManager.getInstance(myModule)).getFilesForOtherModules(type, processed); + } + else { + return VirtualFile.EMPTY_ARRAY; + } + } + + public String[] getUrls(OrderRootType rootType) { + return getUrls(rootType, new HashSet()); + } + + public String[] getUrls (OrderRootType rootType, Set processed) { + if (myModule != null && !processed.contains(myModule)) { + processed.add(myModule); + return ((ModuleRootManagerImpl)ModuleRootManager.getInstance(myModule)).getUrlsForOtherModules(rootType, processed); + } + else { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + } + + + public boolean isValid() { + return myModule != null; + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitModuleOrderEntry(this, initialValue); + } + + public String getPresentableName() { + if (myModule != null) { + return myModule.getName(); + } + else { + return myModuleName; + } + } + + public boolean isSynthetic() { + return false; + } + + public Module getModule() { + return myModule; + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + final Element element = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + element.setAttribute(MODULE_NAME_ATTR, getModuleName()); + if (myExported) { + element.setAttribute(EXPORTED_ATTR, ""); + } + rootElement.addContent(element); + } + + public String getModuleName() { + if (myModule != null) { + return myModule.getName(); + } + else { + return myModuleName; + } + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + return new ModuleOrderEntryImpl(this, rootModel); + } + + protected void dispose() { + super.dispose(); + if (myListenersAdded) { + ModuleManager.getInstance(myRootModel.getModule().getProject()).removeModuleListener(myListener); + } + } + + private void moduleAdded(Module module) { + if (Comparing.equal(myModuleName, module.getName())) { + setModule(module); + } + } + + private void setModule(Module module) { + myModule = module; + myModuleName = null; + } + + private void moduleRemoved(Module module) { + if (myModule == module) { + unsetModule(module); + } + } + + private void unsetModule(Module module) { + myModuleName = module.getName(); + myModule = null; + } + + public boolean isExported() { + return myExported; + } + + public void setExported(boolean value) { + myRootModel.assertWritable(); + myExported = value; + } + + private class MyModuleListener implements ModuleListener { + + public MyModuleListener() { + } + + public void moduleAdded(Project project, Module module) { + final ModuleOrderEntryImpl moduleOrderEntry = ModuleOrderEntryImpl.this; + moduleOrderEntry.moduleAdded(module); + } + + public void beforeModuleRemoved(Project project, Module module) { + } + + public void moduleRemoved(Project project, Module module) { + final ModuleOrderEntryImpl moduleOrderEntry = ModuleOrderEntryImpl.this; + moduleOrderEntry.moduleRemoved(module); + } + + public void modulesRenamed(Project project, List modules) { + if (myModule != null) return; + for (Iterator iterator = modules.iterator(); iterator.hasNext();) { + Module module = iterator.next(); + if (module.getName().equals(myModuleName)) { + setModule(module); + break; + } + } + } + } + + protected void projectOpened() { + addListeners(); + } + + protected void moduleAdded() { + super.moduleAdded(); + if (myModule == null) { + final Module module = ModuleManager.getInstance(myRootModel.getModule().getProject()).findModuleByName(myModuleName); + if (module != null) { + setModule(module); + } + } + } + + /* + private static boolean circularDependency(Module module, + final String thisModuleName, final ModuleManager moduleManager) { + if (module == null) return false; + final String[] dependencyNames = ModuleRootManager.getInstance(module).getDependencyModuleNames(); + for (int i = 0; i < dependencyNames.length; i++) { + String dependencyName = dependencyNames[i]; + if (dependencyName.equals(thisModuleName)) return true; + final Module depModule = moduleManager.findModuleByName(dependencyName); + if (circularDependency(depModule, thisModuleName, moduleManager)) return true; + } + return false; + } + */ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootEventImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootEventImpl.java new file mode 100644 index 00000000000..7b5ec5f48ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootEventImpl.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootEvent; + +/** + * @author dsl + */ +public class ModuleRootEventImpl extends ModuleRootEvent { + private final boolean myFiletypes; + + public ModuleRootEventImpl (final Project project, boolean filetypes) { + super(project); + myFiletypes = filetypes; + } + + public boolean isCausedByFileTypesChange() { + return myFiletypes; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java new file mode 100644 index 00000000000..0671d500869 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -0,0 +1,502 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleComponent; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.containers.HashMap; +import com.intellij.util.graph.CachingSemiGraph; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.GraphGenerator; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.util.*; + +/** + * @author dsl + */ +public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.ModuleRootManagerImpl"); + + private final Module myModule; + private final ProjectRootManagerImpl myProjectRootManager; + private final VirtualFilePointerManager myFilePointerManager; + private RootModelImpl myRootModel; + private final ModuleFileIndexImpl myFileIndex; + private boolean myIsDisposed = false; + private boolean isModuleAdded = false; + + private Map myCachedFiles; + + public ModuleRootManagerImpl(Module module, + DirectoryIndex directoryIndex, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + myModule = module; + myProjectRootManager = projectRootManager; + myFilePointerManager = filePointerManager; + + myFileIndex = new ModuleFileIndexImpl(myModule, directoryIndex); + myCachedFiles = new HashMap(); + myRootModel = new RootModelImpl(this, myProjectRootManager, myFilePointerManager); + } + + public Module getModule() { + return myModule; + } + + public ModuleFileIndex getFileIndex() { + return myFileIndex; + } + + public String getComponentName() { + return "NewModuleRootManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + myRootModel.disposeModel(); + myIsDisposed = true; + } + + public VirtualFile getCompilerOutputPath() { + return myRootModel.getCompilerOutputPath(); + } + + public String getCompilerOutputPathUrl() { + return myRootModel.getCompilerOutputUrl(); + } + + public VirtualFile getCompilerOutputPathForTests() { + return myRootModel.getCompilerOutputPathForTests(); + } + + public String getCompilerOutputPathForTestsUrl() { + return myRootModel.getCompilerOutputUrlForTests(); + } + + public boolean isJdkInherited() { + return myRootModel.isJdkInherited(); + } + + public ProjectJdk getJdk() { + return myRootModel.getJdk(); + } + + public VirtualFile getExplodedDirectory() { + return myRootModel.getExplodedDirectory(); + } + + public String getExplodedDirectoryUrl() { + return myRootModel.getExplodedDirectoryUrl(); + } + + public void readExternal(Element element) throws InvalidDataException { + setModel(new RootModelImpl(element, this, myProjectRootManager, myFilePointerManager)); + } + + public void writeExternal(Element element) throws WriteExternalException { + myRootModel.writeExternal(element); + } + + public ModifiableRootModel getModifiableModel() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return new RootModelImpl(myRootModel, this, true, null, myFilePointerManager, myProjectRootManager); + } + + void fireBeforeRootsChange() { + if (!isModuleAdded) return; + + // IMPORTANT: should be the first listener! + ((ProjectRootManagerImpl)ProjectRootManager.getInstance(myModule.getProject())).beforeRootsChange(false); + } + + void fireRootsChanged() { + if (!isModuleAdded) return; + + ((ProjectRootManagerImpl)ProjectRootManager.getInstance(myModule.getProject())).rootsChanged(false); + } + + + RootModelImpl getRootModel() { + return myRootModel; + } + + public ContentEntry[] getContentEntries() { + return myRootModel.getContentEntries(); + } + + public OrderEntry[] getOrderEntries() { + return myRootModel.getOrderEntries(); + } + + public VirtualFile[] getFiles(OrderRootType type) { + return getFiles(type, new HashSet()); + } + + private VirtualFile[] getFiles(OrderRootType type, Set processed) { + VirtualFile[] cachedFiles = myCachedFiles.get(type); + if (cachedFiles == null) { + final LinkedHashSet result = new LinkedHashSet(); + final Iterator orderIterator = myRootModel.getOrderIterator(); + while (orderIterator.hasNext()) { + OrderEntry entry = (OrderEntry)orderIterator.next(); + final VirtualFile[] files; + if (entry instanceof ModuleOrderEntry) { + files = ((ModuleOrderEntryImpl)entry).getFiles(type, processed); + } + else { + files = entry.getFiles(type); + } + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + if (file != null) { + result.add(file); + } + } + } + cachedFiles = result.toArray(new VirtualFile[result.size()]); + myCachedFiles.put(type, cachedFiles); + } + return cachedFiles; + } + + public String[] getUrls(OrderRootType type) { + return getUrls(type, new HashSet()); + } + + private String[] getUrls(OrderRootType type, Set processed) { + final ArrayList result = new ArrayList(); + final Iterator orderIterator = myRootModel.getOrderIterator(); + while (orderIterator.hasNext()) { + final OrderEntry entry = (OrderEntry)orderIterator.next(); + final String[] urls; + if (entry instanceof ModuleOrderEntry) { + urls = ((ModuleOrderEntryImpl)entry).getUrls(type, processed); + } + else { + urls = entry.getUrls(type); + } + result.addAll(Arrays.asList(urls)); + } + return result.toArray(new String[result.size()]); + } + + void commitModel(RootModelImpl rootModel) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + LOG.assertTrue(rootModel.myModuleRootManager == this); + + final Project project = myModule.getProject(); + final ModifiableModuleModel moduleModel = ModuleManager.getInstance(project).getModifiableModel(); + multiCommit(project, new ModifiableRootModel[]{rootModel}, moduleModel); + } + + private void commitModelWithoutEvents(RootModelImpl rootModel) { + setModel(rootModel); + } + + private void setModel(RootModelImpl rootModel) { + if (myRootModel != rootModel) { + myRootModel.disposeModel(); + } + if (!isModuleAdded) { + myRootModel = rootModel; + } + else { + final VirtualFilePointerListener listener = ((ProjectRootManagerImpl)ProjectRootManager.getInstance( + myModule.getProject())).getVirtualFilePointerListener(); + myRootModel = new RootModelImpl(rootModel, this, false, listener, myFilePointerManager, myProjectRootManager); + rootModel.disposeModel(); + } + } + + + static void multiCommit(Project project, + ModifiableRootModel[] _rootModels, + ModifiableModuleModel moduleModel) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + + final List modelsToCommit = getSortedChangedModels(_rootModels, moduleModel); + + final List modelsToDispose = new ArrayList(Arrays.asList(_rootModels)); + modelsToDispose.removeAll(modelsToCommit); + + Runnable runnable = new Runnable() { + public void run() { + for (int i = 0; i < modelsToCommit.size(); i++) { + RootModelImpl rootModel = modelsToCommit.get(i); + rootModel.myModuleRootManager.commitModelWithoutEvents(rootModel); + } + + for (int i = 0; i < modelsToDispose.size(); i++) { + ModifiableRootModel model = modelsToDispose.get(i); + model.dispose(); + } + } + }; + ((ModuleManagerImpl)ModuleManager.getInstance(project)).commitModelWithRunnable(moduleModel, runnable); + + } + + static List getSortedChangedModels(ModifiableRootModel[] _rootModels, + final ModifiableModuleModel moduleModel) { + List rootModels = new ArrayList(); + for (int i = 0; i < _rootModels.length; i++) { + RootModelImpl rootModel = (RootModelImpl)_rootModels[i]; + if (rootModel.isChanged()) { + rootModels.add((RootModelImpl)rootModel); + } + } + + sortRootModels(rootModels, moduleModel); + return rootModels; + } + + public Module[] getDependencies() { + return myRootModel.getModuleDependencies(); + } + + public String[] getDependencyModuleNames() { + return myRootModel.getDependencyModuleNames(); + } + + public R processOrder(RootPolicy policy, R initialValue) { + LOG.assertTrue(!myIsDisposed); + return myRootModel.processOrder(policy, initialValue); + } + + String[] getUrlsForOtherModules(OrderRootType rootType, Set processed) { + List result = new ArrayList(); + if (OrderRootType.SOURCES.equals(rootType) || OrderRootType.COMPILATION_CLASSES.equals(rootType)) { + myRootModel.addExportedUrs(rootType, result, processed); + return result.toArray(new String[result.size()]); + } + else if (OrderRootType.JAVADOC.equals(rootType)) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + else if (OrderRootType.CLASSES.equals(rootType)) { + myRootModel.addExportedUrs(rootType, result, processed); + return result.toArray(new String[result.size()]); + } + else if (OrderRootType.CLASSES_AND_OUTPUT.equals(rootType)) { + return ModuleRootManagerImpl.this.getUrls(OrderRootType.CLASSES_AND_OUTPUT, processed); + } + LOG.error("Unknown root type: " + rootType); + return null; + + /* + if (OrderRootType.SOURCES.equals(rootType)) { + return ModuleRootManagerImpl.this.getSourceRootUrls(); + } + else if (OrderRootType.JAVADOC.equals(rootType)) { + return new String[0]; + } + else if (OrderRootType.CLASSES.equals(rootType)) { + return ModuleRootManagerImpl.this.getUrls(OrderRootType.CLASSES); + } + else if (OrderRootType.CLASSES_AND_OUTPUT.equals(rootType)) { + return ModuleRootManagerImpl.this.getUrls(OrderRootType.CLASSES_AND_OUTPUT); + } + else if (OrderRootType.COMPILATION_CLASSES.equals(rootType)) { + final ArrayList result = new ArrayList(); + if (getCompilerOutputPathUrl() != null) { + result.add(getCompilerOutputPathUrl()); + } + if (getCompilerOutputPathForTestsUrl() != null) { + result.add(getCompilerOutputPathForTestsUrl()); + } + return (String[])result.toArray(new String[result.size()]); + } + LOG.error("Unknown root type: " + rootType); + return null; + */ + } + + + VirtualFile[] getFilesForOtherModules(OrderRootType rootType, Set processed) { + List result = new ArrayList(); + if (OrderRootType.SOURCES.equals(rootType) || OrderRootType.COMPILATION_CLASSES.equals(rootType)) { + myRootModel.addExportedFiles(rootType, result, processed); + return result.toArray(new VirtualFile[result.size()]); + } + else if (OrderRootType.JAVADOC.equals(rootType)) { + return VirtualFile.EMPTY_ARRAY; + } + else if (OrderRootType.CLASSES.equals(rootType)) { + myRootModel.addExportedFiles(rootType, result, processed); + return result.toArray(new VirtualFile[result.size()]); + } + else if (OrderRootType.CLASSES_AND_OUTPUT.equals(rootType)) { + return ModuleRootManagerImpl.this.getFiles(OrderRootType.CLASSES_AND_OUTPUT, processed); + } + LOG.error("Unknown root type: " + rootType); + return null; + } + + public VirtualFile[] getContentRoots() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getContentRoots(); + } + + public String[] getContentRootUrls() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getContentRootUrls(); + } + + public String[] getExcludeRootUrls() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getExcludeRootUrls(); + } + + public VirtualFile[] getExcludeRoots() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getExcludeRoots(); + } + + public String[] getSourceRootUrls() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getSourceRootUrls(); + } + + public VirtualFile[] getSourceRoots() { + LOG.assertTrue(!myIsDisposed); + return myRootModel.getSourceRoots(); + } + + public void projectOpened() { + final ArrayList components = myRootModel.myComponents; + for (int i = 0; i < components.size(); i++) { + RootModelComponentBase rootModelComponentBase = components.get(i); + rootModelComponentBase.projectOpened(); + } + } + + public void projectClosed() { + final ArrayList components = myRootModel.myComponents; + for (int i = 0; i < components.size(); i++) { + RootModelComponentBase rootModelComponentBase = components.get(i); + rootModelComponentBase.projectClosed(); + } + } + + public void moduleAdded() { + RootModelImpl oldModel = myRootModel; + final VirtualFilePointerListener listener = ((ProjectRootManagerImpl)ProjectRootManager.getInstance( + myModule.getProject())).getVirtualFilePointerListener(); + myRootModel = new RootModelImpl(myRootModel, this, false, listener, myFilePointerManager, myProjectRootManager); + oldModel.disposeModel(); + final ArrayList components = myRootModel.myComponents; + for (int i = 0; i < components.size(); i++) { + RootModelComponentBase rootModelComponentBase = components.get(i); + rootModelComponentBase.moduleAdded(); + } + isModuleAdded = true; + } + + + private static void sortRootModels(List rootModels, final ModifiableModuleModel moduleModel) { + DFSTBuilder builder = createDFSTBuilder(rootModels, moduleModel); + + final Comparator comparator = builder.comparator(); + Collections.sort(rootModels, comparator); + } + + private static DFSTBuilder createDFSTBuilder(List rootModels, final ModifiableModuleModel moduleModel) { + final Map nameToModel = new HashMap(); + for (int i = 0; i < rootModels.size(); i++) { + final RootModelImpl rootModel = rootModels.get(i); + final String name = rootModel.getModule().getName(); + LOG.assertTrue(!nameToModel.containsKey(name)); + nameToModel.put(name, rootModel); + } + final Module[] modules = moduleModel.getModules(); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + final String name = module.getName(); + if (!nameToModel.containsKey(name)) { + final RootModelImpl rootModel = ((ModuleRootManagerImpl)ModuleRootManager.getInstance(module)).myRootModel; + nameToModel.put(name, rootModel); + } + } + final Collection allRootModels = nameToModel.values(); + DFSTBuilder builder = new DFSTBuilder(new GraphGenerator(new CachingSemiGraph(new GraphGenerator.SemiGraph() { + public Collection getNodes() { + return allRootModels; + } + + public Iterator getIn(RootModelImpl rootModel) { + final ArrayList names1 = rootModel.processOrder(new RootPolicy>() { + public ArrayList visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, ArrayList strings) { + final Module module = moduleOrderEntry.getModule(); + if (module != null) { + strings.add(module.getName()); + } else { + final Module moduleToBeRenamed = moduleModel.getModuleToBeRenamed(moduleOrderEntry.getModuleName()); + if (moduleToBeRenamed != null) { + strings.add(moduleToBeRenamed.getName()); + } + } + return strings; + } + }, new ArrayList()); + + final String[] names = names1.toArray(new String[names1.size()]); + List result = new ArrayList(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + final RootModelImpl depRootModel = nameToModel.get(name); + if (depRootModel != null) { // it is ok not to find one + result.add(depRootModel); + } + } + return result.iterator(); + } + }))); + return builder; + } + + + public VirtualFile[] getJavadocPaths() { + return myRootModel.getJavadocPaths(); + } + + public String[] getJavadocUrls() { + return myRootModel.getJavadocUrls(); + } + + public void dropCaches() { + myCachedFiles.clear(); + } + + static void checkCircularDependencies(ModifiableRootModel[] _rootModels, ModifiableModuleModel moduleModel) + throws ModuleCircularDependencyException { + List rootModels = new ArrayList(); + for (int i = 0; i < _rootModels.length; i++) { + RootModelImpl rootModel = (RootModelImpl)_rootModels[i]; + if (rootModel.isChanged()) { + rootModels.add((RootModelImpl)rootModel); + } + } + DFSTBuilder dfstBuilder = createDFSTBuilder(rootModels, moduleModel); + Pair circularDependency = dfstBuilder.getCircularDependency(); + if (circularDependency != null) { + throw new ModuleCircularDependencyException(circularDependency.first.getModule().getName(), + circularDependency.second.getModule().getName()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java new file mode 100644 index 00000000000..b0cfe8a4f33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java @@ -0,0 +1,125 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author dsl + */ +public class ModuleSourceOrderEntryImpl extends OrderEntryBaseImpl implements ModuleSourceOrderEntry, + WritableOrderEntry, + ClonableOrderEntry { + private final RootModelImpl myRootModel; + + static final String ENTRY_TYPE = "sourceFolder"; + + ModuleSourceOrderEntryImpl(RootModelImpl rootModel) { + super(rootModel); + myRootModel = rootModel; + } + + ModuleSourceOrderEntryImpl(Element element, RootModelImpl rootModel) throws InvalidDataException { + super(rootModel); + if (!element.getName().equals(OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME)) { + throw new InvalidDataException(); + } + myRootModel = rootModel; + } + + public void writeExternal(Element rootElement) throws WriteExternalException { + Element element = OrderEntryFactory.createOrderEntryElement(ENTRY_TYPE); + element.setAttribute(OrderEntryFactory.ORDER_ENTRY_TYPE_ATTR, ENTRY_TYPE); + element.setAttribute("forTests", "false"); // compatibility with prev builds + rootElement.addContent(element); + } + + public boolean isValid() { + return true; + } + + public Module getOwnerModule() { + return myRootModel.getModule(); + } + + public R accept(RootPolicy policy, R initialValue) { + return policy.visitModuleSourceOrderEntry(this, initialValue); + } + + public String getPresentableName() { + return ""; + } + + void addExportedFiles(OrderRootType type, List result) { + result.addAll(Arrays.asList(getFiles(type))); + } + + void addExportedUrls(OrderRootType type, List result) { + result.addAll(Arrays.asList(getUrls(type))); + } + + + public VirtualFile[] getFiles(OrderRootType type) { + final ArrayList result = new ArrayList(); + if (OrderRootType.SOURCES.equals(type)) { + result.addAll(Arrays.asList(myRootModel.getSourceRoots())); + } + else if (OrderRootType.CLASSES_AND_OUTPUT.equals(type) || OrderRootType.COMPILATION_CLASSES.equals(type)) { + VirtualFile outputRoot = myRootModel.getCompilerOutputPath(); + if (outputRoot != null) result.add(outputRoot); + final VirtualFile outputPathForTests = myRootModel.getCompilerOutputPathForTests(); + if (outputPathForTests != null && !outputPathForTests.equals(outputRoot)) { + result.add(outputPathForTests); + } + } + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + public VirtualFilePointer[] getFilePointers(OrderRootType type) { + return new VirtualFilePointer[0]; + } + + public String[] getUrls(OrderRootType type) { + final ArrayList result = new ArrayList(); + if (OrderRootType.SOURCES.equals(type)) { + final ContentEntry[] content = myRootModel.getContentEntries(); + for (int i = 0; i < content.length; i++) { + ContentEntry contentEntry = content[i]; + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int j = 0; j < sourceFolders.length; j++) { + final String url = sourceFolders[j].getUrl(); + if (url != null) result.add(url); + } + } + } + else if (OrderRootType.CLASSES_AND_OUTPUT.equals(type) || OrderRootType.COMPILATION_CLASSES.equals(type)) { + String outputRoot = myRootModel.getCompilerOutputPathUrl(); + if (outputRoot != null) result.add(outputRoot); + final String outputPathForTests = myRootModel.getCompilerOutputUrlForTests(); + if (outputPathForTests != null && !outputPathForTests.equals(outputRoot)) { + result.add(outputPathForTests); + } + } + return (String[])result.toArray(new String[result.size()]); + + } + + public OrderEntry cloneEntry(RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + return new ModuleSourceOrderEntryImpl(rootModel); + } + + public boolean isSynthetic() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OldModuleRootsKeeper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OldModuleRootsKeeper.java new file mode 100644 index 00000000000..e99f16a06dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OldModuleRootsKeeper.java @@ -0,0 +1,60 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleComponent; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class OldModuleRootsKeeper implements ModuleComponent, JDOMExternalizable { + private Element myElement; + + public static OldModuleRootsKeeper getInstance(Module module) { + return module.getComponent(OldModuleRootsKeeper.class); + } + + public OldModuleRootsKeeper(Module module) { + + } + + public String getComponentName() { + return "ModuleRootManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void readExternal(Element element) throws InvalidDataException { + myElement = (Element)element.clone(); + } + + + public void writeExternal(Element element) throws WriteExternalException { + if (myElement != null) { + final List children = myElement.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element child = (Element)iterator.next(); + element.addContent((Element)child.clone()); + } + } + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void moduleAdded() { + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryBaseImpl.java new file mode 100644 index 00000000000..e87a77943d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryBaseImpl.java @@ -0,0 +1,25 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.OrderEntry; + +public abstract class OrderEntryBaseImpl extends RootModelComponentBase implements OrderEntry { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.OrderEntryVeryBaseImpl"); + + private int myIndex; + + protected OrderEntryBaseImpl(RootModelImpl rootModel) { + super(rootModel); + } + + public void setIndex(int index) { myIndex = index; } + + public int compareTo(OrderEntry orderEntry) { + LOG.assertTrue(orderEntry.getOwnerModule() == getOwnerModule()); + return myIndex - ((OrderEntryBaseImpl)orderEntry).myIndex; + } + + boolean sameType(OrderEntry that) { + return getClass().equals(that.getClass()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryFactory.java new file mode 100644 index 00000000000..bff5a0fb9b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryFactory.java @@ -0,0 +1,53 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +/** + * @author dsl + */ +class OrderEntryFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.OrderEntryFactory"); + static final String ORDER_ENTRY_ELEMENT_NAME = "orderEntry"; + static final String ORDER_ENTRY_TYPE_ATTR = "type"; + + static OrderEntry createOrderEntryByElement(Element element, + RootModelImpl rootModel, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + LOG.assertTrue(ORDER_ENTRY_ELEMENT_NAME.equals(element.getName())); + final String type = element.getAttributeValue(ORDER_ENTRY_TYPE_ATTR); + if (type == null) { + throw new InvalidDataException(); + } + if (ModuleSourceOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new ModuleSourceOrderEntryImpl(element, rootModel); + } + else if (ModuleJdkOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new ModuleJdkOrderEntryImpl(element, rootModel, projectRootManager, filePointerManager); + } + else if (InheritedJdkOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new InheritedJdkOrderEntryImpl(element, rootModel, projectRootManager, filePointerManager); + } + else if (LibraryOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new LibraryOrderEntryImpl(element, rootModel, projectRootManager, filePointerManager); + } + else if (ModuleLibraryOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new ModuleLibraryOrderEntryImpl(element, rootModel, projectRootManager, filePointerManager); + } + else if (ModuleOrderEntryImpl.ENTRY_TYPE.equals(type)) { + return new ModuleOrderEntryImpl(element, rootModel); + } + else throw new InvalidDataException("Unknown order entry type:" + type); + } + + static Element createOrderEntryElement(String type) { + final Element element = new Element(ORDER_ENTRY_ELEMENT_NAME); + element.setAttribute(ORDER_ENTRY_TYPE_ATTR, type); + return element; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryUtil.java new file mode 100644 index 00000000000..6fbc49f9959 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/OrderEntryUtil.java @@ -0,0 +1,72 @@ +/** + * @author cdr + */ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class OrderEntryUtil { + public static OrderEntry[] getDependentOrderEntries(ModifiableRootModel modifiableModel) { + HashSet processedModules = new HashSet(); + processedModules.add(modifiableModel.getModule()); + return getDependentOrderEntries(modifiableModel,processedModules); + } + public static OrderEntry[] getDependentOrderEntries(ModifiableRootModel modifiableModel, Set processedModules) { + final Set orderEntries = modifiableModel.processOrder(new CollectDependentOrderEntries(processedModules), new HashSet()); + return orderEntries.toArray(new OrderEntry[orderEntries.size()]); + } + + private static class CollectDependentOrderEntries extends RootPolicy> { + private final Set myProcessedModules; + + public CollectDependentOrderEntries(Set processedModules) { + myProcessedModules = processedModules; + } + + public Set visitOrderEntry(OrderEntry orderEntry, Set orderEntries) { + orderEntries.add(orderEntry); + return orderEntries; + } + + public Set visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Set orderEntries) { + final Module module = moduleOrderEntry.getModule(); + if (module != null && myProcessedModules.add(module)) { + orderEntries.add(moduleOrderEntry); + final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); + final OrderEntry[] dependentOrderEntries = getDependentOrderEntries(modifiableModel,myProcessedModules); + orderEntries.addAll(Arrays.asList(dependentOrderEntries)); + } + return orderEntries; + } + } + + public static boolean equals(OrderEntry orderEntry1, OrderEntry orderEntry2) { + if (orderEntry1 instanceof JdkOrderEntry && orderEntry2 instanceof JdkOrderEntry) { + final JdkOrderEntry jdkOrderEntry1 = (JdkOrderEntry)orderEntry1; + final JdkOrderEntry jdkOrderEntry2 = (JdkOrderEntry)orderEntry2; + return Comparing.equal(jdkOrderEntry1.getJdk(), jdkOrderEntry2.getJdk()) && Comparing.strEqual(jdkOrderEntry1.getJdkName(), jdkOrderEntry2.getJdkName()); + } + if (orderEntry1 instanceof LibraryOrderEntry && orderEntry2 instanceof LibraryOrderEntry) { + final LibraryOrderEntry jdkOrderEntry1 = (LibraryOrderEntry)orderEntry1; + final LibraryOrderEntry jdkOrderEntry2 = (LibraryOrderEntry)orderEntry2; + return Comparing.equal(jdkOrderEntry1.getLibrary(), jdkOrderEntry2.getLibrary()); + } + if (orderEntry1 instanceof ModuleSourceOrderEntry && orderEntry2 instanceof ModuleSourceOrderEntry) { + final ModuleSourceOrderEntry jdkOrderEntry1 = (ModuleSourceOrderEntry)orderEntry1; + final ModuleSourceOrderEntry jdkOrderEntry2 = (ModuleSourceOrderEntry)orderEntry2; + return Comparing.equal(jdkOrderEntry1.getOwnerModule(), jdkOrderEntry2.getOwnerModule()); + } + if (orderEntry1 instanceof ModuleOrderEntry && orderEntry2 instanceof ModuleOrderEntry) { + final ModuleOrderEntry jdkOrderEntry1 = (ModuleOrderEntry)orderEntry1; + final ModuleOrderEntry jdkOrderEntry2 = (ModuleOrderEntry)orderEntry2; + return Comparing.equal(jdkOrderEntry1.getModule(), jdkOrderEntry2.getModule()); + } + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java new file mode 100644 index 00000000000..b4f1f24a59c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java @@ -0,0 +1,240 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; + +import java.util.Set; + +public class ProjectFileIndexImpl implements ProjectFileIndex { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.ProjectFileIndexImpl"); + + private final Project myProject; + private final FileTypeManager myFileTypeManager; + private final DirectoryIndex myDirectoryIndex; + private final ContentFilter myContentFilter; + + public ProjectFileIndexImpl(Project project, DirectoryIndex directoryIndex, FileTypeManager fileTypeManager) { + myProject = project; + + myDirectoryIndex = directoryIndex; + myFileTypeManager = fileTypeManager; + myContentFilter = new ContentFilter(); + } + + public boolean iterateContent(ContentIterator iterator) { + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + for (int j = 0; j < contentRoots.length; j++) { + VirtualFile contentRoot = contentRoots[j]; + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(contentRoot); + if (info == null) continue; // is exluded or ignored + if (!module.equals(info.module)) continue; // maybe 2 modules have the same content root? + + VirtualFile parent = contentRoot.getParent(); + if (parent != null) { + DirectoryInfo parentInfo = myDirectoryIndex.getInfoForDirectory(parent); + if (parentInfo != null && parentInfo.module != null) continue; // inner content - skip it + } + + boolean finished = FileIndexImplUtil.iterateRecursively(contentRoot, myContentFilter, iterator); + if (!finished) return false; + } + } + + return true; + } + + public boolean iterateContentUnderDirectory(VirtualFile dir, ContentIterator iterator) { + return FileIndexImplUtil.iterateRecursively(dir, myContentFilter, iterator); + } + + public boolean isIgnored(VirtualFile file) { + if (myFileTypeManager.isFileIgnored(file.getName())) return true; + VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return false; + + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info != null) return false; + + VirtualFile parent = dir.getParent(); + while (true) { + if (parent == null) return false; + DirectoryInfo parentInfo = myDirectoryIndex.getInfoForDirectory(parent); + if (parentInfo != null) return true; + parent = parent.getParent(); + } + } + + public Module getModuleForFile(VirtualFile file) { + VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return null; + DirectoryIndex directoryIndex = myDirectoryIndex; + DirectoryInfo info = directoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + return info.module; + } + + public VirtualFile[] getDirectoriesByPackageName(String packageName, boolean includeLibrarySources) { + return myDirectoryIndex.getDirectoriesByPackageName(packageName, includeLibrarySources); + } + + public OrderEntry[] getOrderEntriesForFile(VirtualFile file) { + VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return OrderEntry.EMPTY_ARRAY; + DirectoryIndex directoryIndex = myDirectoryIndex; + final DirectoryInfo info = directoryIndex.getInfoForDirectory(dir); + if (info == null) return OrderEntry.EMPTY_ARRAY; + final Set orderEntries = info.orderEntries; + return orderEntries.toArray(new OrderEntry[orderEntries.size()]); + } + + public VirtualFile getClassRootForFile(VirtualFile file) { + VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return null; + final DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + return info.libraryClassRoot; + } + + public VirtualFile getSourceRootForFile(VirtualFile file) { + final VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return null; + final DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + return info.sourceRoot; + } + + public VirtualFile getContentRootForFile(VirtualFile file) { + VirtualFile dir = file.isDirectory() ? file : file.getParent(); + if (dir == null) return null; + final DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + return info.contentRoot; + } + + public String getPackageNameByDirectory(VirtualFile dir) { + LOG.assertTrue(dir.isDirectory()); + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); + if (info == null) return null; + return info.packageName; + } + + public boolean isJavaSourceFile(VirtualFile file) { + if (file.isDirectory()) return false; + if (myFileTypeManager.getFileTypeByFile(file) != StdFileTypes.JAVA) return false; + if (myFileTypeManager.isFileIgnored(file.getName())) return false; + return isInSource(file); + } + + public boolean isContentJavaSourceFile(VirtualFile file) { + if (file.isDirectory()) return false; + if (myFileTypeManager.getFileTypeByFile(file) != StdFileTypes.JAVA) return false; + if (myFileTypeManager.isFileIgnored(file.getName())) return false; + return isInSourceContent(file); + } + + public boolean isLibraryClassFile(VirtualFile file) { + if (file.isDirectory()) return false; + if (myFileTypeManager.getFileTypeByFile(file) != StdFileTypes.CLASS) return false; + if (myFileTypeManager.isFileIgnored(file.getName())) return false; + VirtualFile parent = file.getParent(); + DirectoryInfo parentInfo = myDirectoryIndex.getInfoForDirectory(parent); + if (parentInfo == null) return false; + return parentInfo.libraryClassRoot != null; + } + + public boolean isInSource(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + if (info == null) return false; + return info.isInModuleSource || info.isInLibrarySource; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInSource(parent); + } + } + + public boolean isInLibraryClasses(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + if (info == null) return false; + return info.libraryClassRoot != null; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInLibraryClasses(parent); + } + } + + public boolean isInLibrarySource(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + if (info == null) return false; + return info.isInLibrarySource; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInLibrarySource(parent); + } + } + + public boolean isInContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && info.module != null; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInContent(parent); + } + } + + public boolean isInSourceContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && info.isInModuleSource; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInSourceContent(parent); + } + } + + public boolean isInTestSourceContent(VirtualFile fileOrDir) { + if (fileOrDir.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(fileOrDir); + return info != null && info.isInModuleSource && info.isTestSource; + } + else { + VirtualFile parent = fileOrDir.getParent(); + return parent != null && isInTestSourceContent(parent); + } + } + + private class ContentFilter implements VirtualFileFilter { + public boolean accept(VirtualFile file) { + if (file.isDirectory()) { + DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(file); + if (info == null) return false; + return info.module != null; + } + else { + return !myFileTypeManager.isFileIgnored(file.getName()); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java new file mode 100644 index 00000000000..37aaf8bec6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java @@ -0,0 +1,627 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.ide.startup.FileSystemSynchronizer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.ProjectRootType; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; + +import java.util.*; + +/** + * @author max + */ +public class ProjectRootManagerImpl extends ProjectRootManagerEx implements ProjectComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.impl.ProjectRootManagerImpl"); + + private static final String ASSERT_KEYWORD_ATTR = "assert-keyword"; + private static final String JDK_15_ATTR = "jdk-15"; + private static final String PROJECT_JDK_NAME_ATTR = "project-jdk-name"; + + private final ProjectEx myProject; + private ProjectFileIndex myProjectFileIndex; + + private final EventDispatcher myModuleRootEventDispatcher = EventDispatcher.create(ModuleRootListener.class); + private final EventDispatcher myProjectJdkEventDispatcher = EventDispatcher.create(ProjectJdkListener.class); + + private final MyVirtualFilePointerListener myVirtualFilePointerListener = new MyVirtualFilePointerListener(); + + private String myProjectJdkName; + + private ArrayList myChangeUpdaters = new ArrayList(); + + private boolean myProjectOpened = false; + private LanguageLevel myLanguageLevel = LanguageLevel.JDK_1_3; + private FileTypeListener myFileTypeListener; + private long myModificationCount = 0; + + static ProjectRootManagerImpl getInstanceImpl(Project project) { + return (ProjectRootManagerImpl)getInstance(project); + } + + public ProjectRootManagerImpl(Project project, FileTypeManager fileTypeManager, DirectoryIndex directoryIndex) { + myProject = (ProjectEx)project; + myFileTypeListener = new FileTypeListener() { + public void beforeFileTypesChanged(FileTypeEvent event) { + beforeRootsChange(true); + } + + public void fileTypesChanged(FileTypeEvent event) { + rootsChanged(true); + } + }; + + fileTypeManager.addFileTypeListener(myFileTypeListener); + myProjectFileIndex = new ProjectFileIndexImpl(myProject, directoryIndex, fileTypeManager); + } + + public void registerChangeUpdater(CacheUpdater updater) { + myChangeUpdaters.add(updater); + } + + public void unregisterChangeUpdater(CacheUpdater updater) { + boolean success = myChangeUpdaters.remove(updater); + LOG.assertTrue(success); + } + + + public void multiCommit(ModifiableRootModel[] rootModels) { + ModuleRootManagerImpl.multiCommit(myProject, rootModels, ModuleManager.getInstance(myProject).getModifiableModel()); + } + + public void multiCommit(ModifiableModuleModel moduleModel, ModifiableRootModel[] rootModels) { + ModuleRootManagerImpl.multiCommit(myProject, rootModels, moduleModel); + } + + public void checkCircularDependency(ModifiableRootModel[] rootModels, ModifiableModuleModel moduleModel) + throws ModuleCircularDependencyException { + ModuleRootManagerImpl.checkCircularDependencies(rootModels, moduleModel); + } + + public VirtualFilePointerListener getVirtualFilePointerListener() { + return myVirtualFilePointerListener; + } + + public ProjectFileIndex getFileIndex() { + return myProjectFileIndex; + } + + public void addModuleRootListener(final ModuleRootListener listener) { + myModuleRootEventDispatcher.addListener(listener); + } + + public void removeModuleRootListener(ModuleRootListener listener) { + myModuleRootEventDispatcher.removeListener(listener); + } + + public void dispatchPendingEvent(ModuleRootListener listener) { + myModuleRootEventDispatcher.dispatchPendingEvent(listener); + } + + public LanguageLevel getLanguageLevel() { + return myLanguageLevel; + } + + public void setLanguageLevel(LanguageLevel languageLevel) { + myLanguageLevel = languageLevel; + } + + private final static HashMap ourProjectRootTypeToOrderRootType = new HashMap(); + + static { + ourProjectRootTypeToOrderRootType.put(ProjectRootType.CLASS, OrderRootType.CLASSES); + ourProjectRootTypeToOrderRootType.put(ProjectRootType.SOURCE, OrderRootType.SOURCES); + ourProjectRootTypeToOrderRootType.put(ProjectRootType.JAVADOC, OrderRootType.JAVADOC); + } + + public VirtualFile[] getRootFiles(ProjectRootType type) { + if (ourProjectRootTypeToOrderRootType.get(type) != null) { + return getFilesFromAllModules(ourProjectRootTypeToOrderRootType.get(type)); + } + else if (type == ProjectRootType.EXCLUDE) { + return getExcludeRootsFromAllModules(); + } + else if (type == ProjectRootType.PROJECT) { + return getContentRootsFromAllModules(); + } + LOG.assertTrue(false); + return null; + } + + public VirtualFile[] getContentRoots() { + ArrayList result = new ArrayList(); + final Module[] modules = getModuleManager().getModules(); + for (int i = 0; i < modules.length; i++) { + final VirtualFile[] contentRoots = ModuleRootManager.getInstance(modules[i]).getContentRoots(); + result.addAll(Arrays.asList(contentRoots)); + } + return result.toArray(new VirtualFile[result.size()]); + } + + public VirtualFile[] getContentSourceRoots() { + ArrayList result = new ArrayList(); + final Module[] modules = getModuleManager().getModules(); + for (int i = 0; i < modules.length; i++) { + final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(modules[i]).getSourceRoots(); + result.addAll(Arrays.asList(sourceRoots)); + } + return result.toArray(new VirtualFile[result.size()]); + } + + private VirtualFile[] getFilesFromAllModules(OrderRootType type) { + List result = new ArrayList(); + final Module[] modules = getModuleManager().getSortedModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + final VirtualFile[] files = ModuleRootManager.getInstance(module).getFiles(type); + result.addAll(Arrays.asList(files)); + } + return result.toArray(new VirtualFile[result.size()]); + } + + private VirtualFile[] getExcludeRootsFromAllModules() { + List result = new ArrayList(); + final Module[] modules = getModuleManager().getSortedModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + final VirtualFile[] files = ModuleRootManager.getInstance(module).getExcludeRoots(); + result.addAll(Arrays.asList(files)); + } + return result.toArray(new VirtualFile[result.size()]); + } + + private VirtualFile[] getContentRootsFromAllModules() { + List result = new ArrayList(); + final Module[] modules = getModuleManager().getSortedModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots(); + result.addAll(Arrays.asList(files)); + } + return result.toArray(new VirtualFile[result.size()]); + } + + public VirtualFile[] getFullClassPath() { + return getFilesFromAllModules(OrderRootType.CLASSES_AND_OUTPUT); + } + + public ProjectJdk getJdk() { + final Module[] modules = ModuleManager.getInstance(myProject).getModules(); + if (modules.length > 0) { + return ModuleRootManager.getInstance(modules[0]).getJdk(); + } + else { + return null; + } + } + + public ProjectJdk getProjectJdk() { + if (myProjectJdkName != null) { + return ProjectJdkTable.getInstance().findJdk(myProjectJdkName); + } + else { + return null; + } + } + + public String getProjectJdkName() { + return myProjectJdkName; + } + + public void setProjectJdk(ProjectJdk projectJdk) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (projectJdk != null) { + myProjectJdkName = projectJdk.getName(); + } + else { + myProjectJdkName = null; + } + doRootsChangedOnDemand(new Runnable() { + public void run() { + myProjectJdkEventDispatcher.getMulticaster().projectJdkChanged(); + } + }); + } + + public void setProjectJdkName(String name) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + myProjectJdkName = name; + + doRootsChangedOnDemand(new Runnable() { + public void run() { + myProjectJdkEventDispatcher.getMulticaster().projectJdkChanged(); + } + }); + } + + public void addProjectJdkListener(ProjectJdkListener listener) { + myProjectJdkEventDispatcher.addListener(listener); + } + + public void removeProjectJdkListener(ProjectJdkListener listener) { + myProjectJdkEventDispatcher.removeListener(listener); + } + + + public void projectOpened() { + myProjectOpened = true; + } + + public void projectClosed() { + myProjectOpened = false; + } + + public String getComponentName() { + return "ProjectRootManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + if (myJdkTableMultilistener != null) { + myJdkTableMultilistener.uninstallListner(false); + myJdkTableMultilistener = null; + } + FileTypeManager.getInstance().removeFileTypeListener(myFileTypeListener); + } + + public void readExternal(Element element) throws InvalidDataException { + final boolean assertKeyword = Boolean.valueOf(element.getAttributeValue(ASSERT_KEYWORD_ATTR)).booleanValue(); + final boolean jdk15 = Boolean.valueOf(element.getAttributeValue(JDK_15_ATTR)).booleanValue(); + if (jdk15) { + myLanguageLevel = LanguageLevel.JDK_1_5; + } + else if (assertKeyword) { + myLanguageLevel = LanguageLevel.JDK_1_4; + } + else { + myLanguageLevel = LanguageLevel.JDK_1_3; + } + myProjectJdkName = element.getAttributeValue(PROJECT_JDK_NAME_ATTR); + } + + public void writeExternal(Element element) throws WriteExternalException { + element.setAttribute("version", "2"); + final boolean is14 = LanguageLevel.JDK_1_4.equals(myLanguageLevel); + final boolean is15 = LanguageLevel.JDK_1_5.equals(myLanguageLevel); + element.setAttribute(ASSERT_KEYWORD_ATTR, Boolean.toString(is14 || is15)); + element.setAttribute(JDK_15_ATTR, Boolean.toString(is15)); + if (myProjectJdkName != null) { + element.setAttribute(PROJECT_JDK_NAME_ATTR, myProjectJdkName); + } + } + + + private boolean myIsRootsChangedOnDemandStartedButNotDemanded = false; + + private int myRootsChangeCounter = 0; + + private void doRootsChangedOnDemand(Runnable r) { + LOG.assertTrue(!myIsRootsChangedOnDemandStartedButNotDemanded, "Nested on-demand rootsChanged not supported"); + LOG.assertTrue(myRootsChangeCounter == 0, "On-demand rootsChanged not allowed inside rootsChanged"); + myIsRootsChangedOnDemandStartedButNotDemanded = true; + try { + r.run(); + } + finally { + if (myIsRootsChangedOnDemandStartedButNotDemanded) { + myIsRootsChangedOnDemandStartedButNotDemanded = false; + } + else { + LOG.assertTrue(myRootsChangeCounter == 1, "myRootsChangedCounter = " + myRootsChangeCounter); + myIsRootsChangedOnDemandStartedButNotDemanded = false; + rootsChanged(false); + } + } + } + + public void beforeRootsChange(boolean filetypes) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (myRootsChangeCounter == 0) { + if (myIsRootsChangedOnDemandStartedButNotDemanded) { + myIsRootsChangedOnDemandStartedButNotDemanded = false; + myRootsChangeCounter++; // blocks all firing until finishRootsChangedOnDemand + } + myModuleRootEventDispatcher.getMulticaster().beforeRootsChange(new ModuleRootEventImpl(myProject, filetypes)); + } + myRootsChangeCounter++; + } + + public void rootsChanged(boolean filetypes) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + myRootsChangeCounter--; + if (myRootsChangeCounter > 0) return; + + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + ((ModuleRootManagerImpl)ModuleRootManager.getInstance(module)).dropCaches(); + } + + myModuleRootEventDispatcher.getMulticaster().rootsChanged(new ModuleRootEventImpl(myProject, filetypes)); + + final FileSystemSynchronizer synchronizer = new FileSystemSynchronizer(); + for (int i = 0; i < myChangeUpdaters.size(); i++) { + CacheUpdater updater = myChangeUpdaters.get(i); + synchronizer.registerCacheUpdater(updater); + } + + if (!ApplicationManager.getApplication().isUnitTestMode() && myProjectOpened) { + Runnable process = new Runnable() { + public void run() { + synchronizer.execute(); + } + }; + ApplicationManager.getApplication().runProcessWithProgressSynchronously(process, "Loading Files...", false, myProject); + } + else { + synchronizer.execute(); + } + + myModificationCount++; + } + + private ModuleManager getModuleManager() { + return ModuleManager.getInstance(myProject); + } + + void addRootSetChangedListener(RootProvider.RootSetChangedListener rootSetChangedListener, + final RootProvider provider) { + RootSetChangedMulticaster multicaster = myRegisteredRootProviderListeners.get(provider); + if (multicaster == null) { + multicaster = new RootSetChangedMulticaster(provider); + } + multicaster.addListener(rootSetChangedListener); + } + + void removeRootSetChangedListener(RootProvider.RootSetChangedListener rootSetChangedListener, + final RootProvider provider) { + RootSetChangedMulticaster multicaster = myRegisteredRootProviderListeners.get(provider); + if (multicaster != null) { + multicaster.removeListener(rootSetChangedListener); + } + } + + + private class MyVirtualFilePointerListener implements VirtualFilePointerListener { + private void assertPointersCorrect(VirtualFilePointer[] pointers) { + for (int i = 0; i < pointers.length; i++) { + VirtualFilePointer pointer = pointers[i]; + final RootModelImpl rootModel = pointer.getUserData(RootModelImpl.ORIGINATING_ROOT_MODEL); + LOG.assertTrue(rootModel != null); + LOG.assertTrue(!rootModel.isDisposed()); + LOG.assertTrue(!rootModel.isWritable()); + } + } + + public void beforeValidityChanged(VirtualFilePointer[] pointers) { + assertPointersCorrect(pointers); + beforeRootsChange(false); + } + + public void validityChanged(VirtualFilePointer[] pointers) { + assertPointersCorrect(pointers); + rootsChanged(false); + } + } + + + void addListenerForTable(LibraryTable.Listener libraryListener, + final LibraryTable libraryTable) { + LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable); + if (multilistener == null) { + multilistener = new LibraryTableMultilistener(libraryTable); + } + multilistener.addListener(libraryListener); + } + + void removeListenerForTable(LibraryTable.Listener libraryListener, + final LibraryTable libraryTable) { + LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable); + if (multilistener == null) { + multilistener = new LibraryTableMultilistener(libraryTable); + } + multilistener.removeListener(libraryListener); + } + + Map myLibraryTableMultilisteners = new HashMap(); + + private class LibraryTableMultilistener implements LibraryTable.Listener { + EventDispatcher myDispatcher = EventDispatcher.create(LibraryTable.Listener.class); + Set myListeners = new HashSet(); + private final LibraryTable myLibraryTable; + + private LibraryTableMultilistener(LibraryTable libraryTable) { + myLibraryTable = libraryTable; + myLibraryTable.addListener(this); + myLibraryTableMultilisteners.put(myLibraryTable, this); + } + + private void addListener(LibraryTable.Listener listener) { + myListeners.add(listener); + myDispatcher.addListener(listener); + } + + private void removeListener(LibraryTable.Listener listener) { + myDispatcher.removeListener(listener); + myListeners.remove(listener); + if (!myDispatcher.hasListeners()) { + myLibraryTable.removeListener(this); + myLibraryTableMultilisteners.remove(myLibraryTable); + } + } + + public void afterLibraryAdded(final Library newLibrary) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().afterLibraryAdded(newLibrary); + } + }); + } + + public void afterLibraryRenamed(final Library library) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().afterLibraryRenamed(library); + } + }); + } + + public void beforeLibraryRemoved(final Library library) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().beforeLibraryRemoved(library); + } + }); + } + + public void afterLibraryRemoved(final Library library) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().afterLibraryRemoved(library); + } + }); + } + } + + private JdkTableMultilistener myJdkTableMultilistener = null; + + private class JdkTableMultilistener implements ProjectJdkTable.Listener { + EventDispatcher myDispatcher = EventDispatcher.create(ProjectJdkTable.Listener.class); + Set myListeners = new HashSet(); + + private JdkTableMultilistener() { + ProjectJdkTable.getInstance().addListener(this); + } + + private void addListener(ProjectJdkTable.Listener listener) { + myDispatcher.addListener(listener); + myListeners.add(listener); + } + + private void removeListener(ProjectJdkTable.Listener listener) { + myDispatcher.removeListener(listener); + myListeners.remove(listener); + uninstallListner(true); + } + + public void jdkAdded(final ProjectJdk jdk) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().jdkAdded(jdk); + } + }); + } + + public void jdkRemoved(final ProjectJdk jdk) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().jdkRemoved(jdk); + } + }); + } + + public void jdkNameChanged(final ProjectJdk jdk, final String previousName) { + doRootsChangedOnDemand(new Runnable() { + public void run() { + myDispatcher.getMulticaster().jdkNameChanged(jdk, previousName); + } + }); + String currentName = getProjectJdkName(); + if (previousName != null && previousName.equals(currentName)) { + // if already had jdk name and that name was the name of the jdk just changed + myProjectJdkName = jdk.getName(); + } + } + + public void uninstallListner(boolean soft) { + if (!soft || !myDispatcher.hasListeners()) { + ProjectJdkTable.getInstance().removeListener(this); + } + } + } + + private final Map myRegisteredRootProviderListeners = new HashMap(); + + void addJdkTableListener(ProjectJdkTable.Listener jdkTableListener) { + getJdkTableMultiListener().addListener(jdkTableListener); + } + + private JdkTableMultilistener getJdkTableMultiListener() { + if (myJdkTableMultilistener == null) { + myJdkTableMultilistener = new JdkTableMultilistener(); + } + return myJdkTableMultilistener; + } + + + void removeJdkTableListener(ProjectJdkTable.Listener jdkTableListener) { + if (myJdkTableMultilistener == null) return; + myJdkTableMultilistener.removeListener(jdkTableListener); + } + + private class RootSetChangedMulticaster implements RootProvider.RootSetChangedListener { + EventDispatcher myDispatcher = EventDispatcher.create(RootProvider.RootSetChangedListener.class); + private final RootProvider myProvider; + + private RootSetChangedMulticaster(RootProvider provider) { + myProvider = provider; + provider.addRootSetChangedListener(this); + myRegisteredRootProviderListeners.put(myProvider, this); + } + + private void addListener(RootProvider.RootSetChangedListener listener) { + myDispatcher.addListener(listener); + } + + private void removeListener(RootProvider.RootSetChangedListener listener) { + myDispatcher.removeListener(listener); + if (!myDispatcher.hasListeners()) { + myProvider.removeRootSetChangedListener(this); + myRegisteredRootProviderListeners.remove(myProvider); + } + } + + public void rootSetChanged(final RootProvider wrapper) { + LOG.assertTrue(myProvider.equals(wrapper)); + Runnable runnable = new Runnable() { + public void run() { + myDispatcher.getMulticaster().rootSetChanged(wrapper); + } + }; + doRootsChangedOnDemand(runnable); + } + + } + + public long getModificationCount() { + return myModificationCount; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelComponentBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelComponentBase.java new file mode 100644 index 00000000000..7e422d54cf0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelComponentBase.java @@ -0,0 +1,35 @@ +package com.intellij.openapi.roots.impl; + + + +/** + * @author dsl + */ +public abstract class RootModelComponentBase { + RootModelImpl myRootModel; + + RootModelComponentBase(RootModelImpl rootModel) { + rootModel.myComponents.add(this); + myRootModel = rootModel; + } + + protected void projectOpened() { + + } + + protected void projectClosed() { + + } + + protected void moduleAdded() { + + } + + RootModelImpl getRootModel() { + return myRootModel; + } + + protected void dispose() { + myRootModel.myComponents.remove(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelImpl.java new file mode 100644 index 00000000000..82f5bc4fa63 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -0,0 +1,1053 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.watcher.OrderEntryProperties; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.*; +import org.jdom.Element; + +import java.util.*; + +/** + * @author dsl + */ +class RootModelImpl implements ModifiableRootModel { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootModelImpl"); + static final Key ORIGINATING_ROOT_MODEL = Key.create("ORIGINATING_ROOT_MODEL"); + + private TreeSet myContent = new TreeSet(ContentComparator.INSTANCE); + + private List myOrder = new Order(); + + private final ModuleLibraryTable myModuleLibraryTable; + final ModuleRootManagerImpl myModuleRootManager; + private boolean myWritable; + private final VirtualFilePointerListener myVirtualFilePointerListener; + private VirtualFilePointerManager myFilePointerManager; + VirtualFilePointer myCompilerOutputPath; + VirtualFilePointer myCompilerOutputPathForTests; + VirtualFilePointer myExplodedDirectory; + ArrayList myComponents = new ArrayList(); + private List myPointersToDispose = new ArrayList(); + + private boolean myExcludeOutput; + private boolean myExcludeExploded; + + private static final String OUTPUT_TAG = "output"; + private static final String TEST_OUTPUT_TAG = "output-test"; + private static final String EXPLODED_TAG = "exploded"; + private static final String URL_ATTR = "url"; + private static final String EXCLUDE_OUTPUT_TAG = "exclude-output"; + private static final String EXCLUDE_EXPLODED_TAG = "exclude-exploded"; + private boolean myDisposed = false; + private final OrderEntryProperties myOrderEntryProperties; + private final VirtualFilePointerContainer myJavadocPointerContainer; + + private VirtualFilePointerFactory myVirtualFilePointerFactory = new VirtualFilePointerFactory() { + public VirtualFilePointer create(VirtualFile file) { + final VirtualFilePointer pointer = myFilePointerManager.create(file, getFileListener()); + annotatePointer(pointer); + return pointer; + } + + public VirtualFilePointer create(String url) { + final VirtualFilePointer pointer = myFilePointerManager.create(url, getFileListener()); + annotatePointer(pointer); + return pointer; + } + + public VirtualFilePointer duplicate(VirtualFilePointer virtualFilePointer) { + final VirtualFilePointer pointer = myFilePointerManager.duplicate(virtualFilePointer, getFileListener()); + annotatePointer(pointer); + return pointer; + } + }; + private static final String PROPERTIES_CHILD_NAME = "orderEntryProperties"; + private static final String JAVADOC_PATHS_NAME = "javadoc-paths"; + private static final String JAVADOC_ROOT_ELEMENT = "root"; + private ProjectRootManagerImpl myProjectRootManager; + + + public String getCompilerOutputPathUrl() { + return getCompilerOutputUrl(); + } + + public String getCompilerOutputPathForTestsUrl() { + return getCompilerOutputUrlForTests(); + } + + RootModelImpl(ModuleRootManagerImpl moduleRootManager, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { + myModuleRootManager = moduleRootManager; + myProjectRootManager = projectRootManager; + myFilePointerManager = filePointerManager; + + myWritable = false; + myVirtualFilePointerListener = null; + addSourceOrderEntries(); + myOrderEntryProperties = new OrderEntryProperties(); + myJavadocPointerContainer = myFilePointerManager.createContainer(myVirtualFilePointerFactory); + myModuleLibraryTable = new ModuleLibraryTable(this, myProjectRootManager, myFilePointerManager); + } + + private void addSourceOrderEntries() { + myOrder.add(new ModuleSourceOrderEntryImpl(this)); + } + + RootModelImpl(Element element, + ModuleRootManagerImpl moduleRootManager, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) throws InvalidDataException { + myProjectRootManager = projectRootManager; + myFilePointerManager = filePointerManager; + myModuleRootManager = moduleRootManager; + + myModuleLibraryTable = new ModuleLibraryTable(this, myProjectRootManager, myFilePointerManager); + + myVirtualFilePointerListener = null; + final List contentChildren = element.getChildren(ContentEntryImpl.ELEMENT_NAME); + for (int i = 0; i < contentChildren.size(); i++) { + Element child = (Element)contentChildren.get(i); + ContentEntryImpl contentEntry = new ContentEntryImpl(child, this); + myContent.add(contentEntry); + } + + final List orderElements = element.getChildren(OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME); + boolean moduleSourceAdded = false; + for (int i = 0; i < orderElements.size(); i++) { + Element child = (Element)orderElements.get(i); + final OrderEntry orderEntry = OrderEntryFactory.createOrderEntryByElement(child, this, myProjectRootManager, myFilePointerManager); + if (orderEntry instanceof ModuleSourceOrderEntry) { + if (moduleSourceAdded) continue; + moduleSourceAdded = true; + } + myOrder.add(orderEntry); + } + + if (!moduleSourceAdded) { + myOrder.add(new ModuleSourceOrderEntryImpl(this)); + } + + myExcludeOutput = element.getChild(EXCLUDE_OUTPUT_TAG) != null; + myExcludeExploded = element.getChild(EXCLUDE_EXPLODED_TAG) != null; + + myCompilerOutputPath = getOutputPathValue(element, OUTPUT_TAG); + myCompilerOutputPathForTests = getOutputPathValue(element, TEST_OUTPUT_TAG); + myExplodedDirectory = getOutputPathValue(element, EXPLODED_TAG); + + + myWritable = false; + myOrderEntryProperties = new OrderEntryProperties(); + final Element propertiesChild = element.getChild(PROPERTIES_CHILD_NAME); + if (propertiesChild != null) { + myOrderEntryProperties.readExternal(propertiesChild); + } + + myJavadocPointerContainer = myFilePointerManager.createContainer(myVirtualFilePointerFactory); + final Element javaDocPaths = element.getChild(JAVADOC_PATHS_NAME); + if (javaDocPaths != null) { + myJavadocPointerContainer.readExternal(javaDocPaths, JAVADOC_ROOT_ELEMENT); + } + } + + public boolean isWritable() { + return myWritable; + } + + RootModelImpl(RootModelImpl rootModel, + ModuleRootManagerImpl moduleRootManager, + final boolean writable, + final VirtualFilePointerListener virtualFilePointerListener, + VirtualFilePointerManager filePointerManager, + ProjectRootManagerImpl projectRootManager) { + myFilePointerManager = filePointerManager; + myModuleRootManager = moduleRootManager; + myProjectRootManager = projectRootManager; + + myModuleLibraryTable = new ModuleLibraryTable(this, myProjectRootManager, myFilePointerManager); + + myWritable = writable; + LOG.assertTrue(!writable || virtualFilePointerListener == null); + myVirtualFilePointerListener = virtualFilePointerListener; + + if (rootModel.myCompilerOutputPath != null) { + myCompilerOutputPath = pointerFactory().duplicate(rootModel.myCompilerOutputPath); + } + + if (rootModel.myCompilerOutputPathForTests != null) { + myCompilerOutputPathForTests = pointerFactory().duplicate(rootModel.myCompilerOutputPathForTests); + } + + if (rootModel.myExplodedDirectory != null) { + myExplodedDirectory = pointerFactory().duplicate(rootModel.myExplodedDirectory); + } + + myExcludeOutput = rootModel.myExcludeOutput; + myExcludeExploded = rootModel.myExcludeExploded; + + final TreeSet thatContent = rootModel.myContent; + for (Iterator iterator = thatContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + if (contentEntry instanceof ClonableContentEntry) { + myContent.add(((ClonableContentEntry)contentEntry).cloneEntry(this)); + } + } + + final List order = rootModel.myOrder; + for (int i = 0; i < order.size(); i++) { + OrderEntry orderEntry = order.get(i); + if (orderEntry instanceof ClonableOrderEntry) { + myOrder.add(((ClonableOrderEntry)orderEntry).cloneEntry(this, myProjectRootManager, myFilePointerManager)); + } + } + myOrderEntryProperties = rootModel.myOrderEntryProperties.copy(this); + myJavadocPointerContainer = myFilePointerManager.createContainer(myVirtualFilePointerFactory); + myJavadocPointerContainer.addAll(rootModel.myJavadocPointerContainer); + } + + public VirtualFile[] getOrderedRoots(OrderRootType type) { + final ArrayList result = new ArrayList(); + + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + OrderEntry orderEntry = iterator.next(); + result.addAll(Arrays.asList(orderEntry.getFiles(type))); + } + return result.toArray(new VirtualFile[result.size()]); + } + + public String[] getOrderedRootUrls(OrderRootType type) { + final ArrayList result = new ArrayList(); + + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + OrderEntry orderEntry = iterator.next(); + result.addAll(Arrays.asList(orderEntry.getUrls(type))); + } + return result.toArray(new String[result.size()]); + } + + public VirtualFile[] getContentRoots() { + final ArrayList result = new ArrayList(); + + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final VirtualFile file = contentEntry.getFile(); + if (file != null) { + result.add(file); + } + } + return result.toArray(new VirtualFile[result.size()]); + } + + public String[] getContentRootUrls() { + final ArrayList result = new ArrayList(); + + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + result.add(contentEntry.getUrl()); + } + return result.toArray(new String[result.size()]); + } + + public String[] getExcludeRootUrls() { + final ArrayList result = new ArrayList(); + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); + for (int i = 0; i < excludeFolders.length; i++) { + ExcludeFolder excludeFolder = excludeFolders[i]; + result.add(excludeFolder.getUrl()); + } + } + return result.toArray(new String[result.size()]); + } + + public VirtualFile[] getExcludeRoots() { + final ArrayList result = new ArrayList(); + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); + for (int i = 0; i < excludeFolders.length; i++) { + ExcludeFolder excludeFolder = excludeFolders[i]; + final VirtualFile file = excludeFolder.getFile(); + if (file != null) { + result.add(file); + } + } + } + return result.toArray(new VirtualFile[result.size()]); + } + + + public String[] getSourceRootUrls() { + final ArrayList result = new ArrayList(); + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int i = 0; i < sourceFolders.length; i++) { + SourceFolder sourceFolder = sourceFolders[i]; + result.add(sourceFolder.getUrl()); + } + } + return result.toArray(new String[result.size()]); + } + + public String[] getSourceRootUrls(boolean testFlagValue) { + final ArrayList result = new ArrayList(); + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int i = 0; i < sourceFolders.length; i++) { + SourceFolder sourceFolder = sourceFolders[i]; + if (sourceFolder.isTestSource() == testFlagValue) { + result.add(sourceFolder.getUrl()); + } + } + } + return result.toArray(new String[result.size()]); + } + + public VirtualFile[] getSourceRoots() { + final ArrayList result = new ArrayList(); + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int i = 0; i < sourceFolders.length; i++) { + SourceFolder sourceFolder = sourceFolders[i]; + final VirtualFile file = sourceFolder.getFile(); + if (file != null) { + result.add(file); + } + } + } + return result.toArray(new VirtualFile[result.size()]); + } + + public ContentEntry[] getContentEntries() { + return myContent.toArray(new ContentEntry[myContent.size()]); + } + + public OrderEntry[] getOrderEntries() { + return myOrder.toArray(new OrderEntry[myOrder.size()]); + } + + Iterator getOrderIterator() { + return Collections.unmodifiableList(myOrder).iterator(); + } + + public void removeContentEntry(ContentEntry entry) { + assertWritable(); + LOG.assertTrue(myContent.contains(entry)); + myContent.remove(entry); + if (myComponents.contains(entry)) { + ((RootModelComponentBase)entry).dispose(); + } + } + + public void addOrderEntry(OrderEntry entry) { + assertWritable(); + LOG.assertTrue(!myOrder.contains(entry)); + myOrder.add(entry); + } + + public LibraryOrderEntry addLibraryEntry(Library library) { + assertWritable(); + final LibraryOrderEntry libraryOrderEntry = new LibraryOrderEntryImpl(library, this, myProjectRootManager, myFilePointerManager); + myOrder.add(libraryOrderEntry); + return libraryOrderEntry; + } + + public LibraryOrderEntry addInvalidLibrary(String name, String level) { + assertWritable(); + final LibraryOrderEntry libraryOrderEntry = new LibraryOrderEntryImpl(name, level, this, myProjectRootManager, myFilePointerManager); + myOrder.add(libraryOrderEntry); + return libraryOrderEntry; + } + + public ModuleOrderEntry addModuleOrderEntry(Module module) { + assertWritable(); + LOG.assertTrue(!module.equals(getModule())); + LOG.assertTrue(Comparing.equal(myModuleRootManager.getModule().getProject(), module.getProject())); + final ModuleOrderEntryImpl moduleOrderEntry = new ModuleOrderEntryImpl(module, this); + myOrder.add(moduleOrderEntry); + return moduleOrderEntry; + } + + public ModuleOrderEntry addInvalidModuleEntry(String name) { + assertWritable(); + LOG.assertTrue(!name.equals(getModule().getName())); + final ModuleOrderEntryImpl moduleOrderEntry = new ModuleOrderEntryImpl(name, this); + myOrder.add(moduleOrderEntry); + return moduleOrderEntry; + } + + public LibraryOrderEntry findLibraryOrderEntry(Library library) { + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + OrderEntry orderEntry = iterator.next(); + if (orderEntry instanceof LibraryOrderEntry && library.equals(((LibraryOrderEntry)orderEntry).getLibrary())) { + return (LibraryOrderEntry)orderEntry; + } + } + return null; + } + + public void removeOrderEntry(OrderEntry entry) { + assertWritable(); + removeOrderEntryInternal(entry); + } + + void removeOrderEntryInternal(OrderEntry entry) { + LOG.assertTrue(myOrder.contains(entry)); + myOrder.remove(entry); + } + + public void rearrangeOrderEntries(OrderEntry[] newEntries) { + assertWritable(); + assertValidRearrangement(newEntries); + myOrder.clear(); + for (int i = 0; i < newEntries.length; i++) { + OrderEntry newEntry = newEntries[i]; + myOrder.add(newEntry); + } + } + + private void assertValidRearrangement(OrderEntry[] newEntries) { + LOG.assertTrue(newEntries.length == myOrder.size(), "Invalid rearranged order"); + Set set = new com.intellij.util.containers.HashSet(); + for (int i = 0; i < newEntries.length; i++) { + OrderEntry newEntry = newEntries[i]; + LOG.assertTrue(myOrder.contains(newEntry), "Invalid rearranged order"); + LOG.assertTrue(!set.contains(newEntry), "Invalid rearranged order"); + set.add(newEntry); + } + } + + public void clear() { + final ProjectJdk jdk = getJdk(); + myContent.clear(); + myOrder.clear(); + setJdk(jdk); + addSourceOrderEntries(); + } + + public void commit() { + myModuleRootManager.commitModel(this); + myWritable = false; + } + + public LibraryTable getModuleLibraryTable() { + return myModuleLibraryTable; + } + + public R processOrder(RootPolicy policy, R initialValue) { + R result = initialValue; + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + OrderEntry orderEntry = iterator.next(); + result = orderEntry.accept(policy, result); + } + return result; + } + + public ContentEntry addContentEntry(VirtualFile file) { + ContentEntry entry = new ContentEntryImpl(file, this); + myContent.add(entry); + return entry; + } + + private VirtualFilePointer getOutputPathValue(Element element, String tag) { + final Element outputPathChild = element.getChild(tag); + VirtualFilePointer vptr = null; + if (outputPathChild != null) { + String outputPath = outputPathChild.getAttributeValue("url"); + vptr = pointerFactory().create(outputPath); + } + return vptr; + } + + public void writeExternal(Element element) throws WriteExternalException { + if (myCompilerOutputPath != null) { + final Element pathElement = new Element(OUTPUT_TAG); + pathElement.setAttribute(URL_ATTR, myCompilerOutputPath.getUrl()); + element.addContent(pathElement); + } + + if (myExcludeOutput) { + element.addContent(new Element(EXCLUDE_OUTPUT_TAG)); + } + + if (myExplodedDirectory != null) { + final Element pathElement = new Element(EXPLODED_TAG); + pathElement.setAttribute(URL_ATTR, myExplodedDirectory.getUrl()); + element.addContent(pathElement); + } + + if (myExcludeExploded) { + element.addContent(new Element(EXCLUDE_EXPLODED_TAG)); + } + + if (myCompilerOutputPathForTests != null) { + final Element pathElement = new Element(TEST_OUTPUT_TAG); + pathElement.setAttribute("url", myCompilerOutputPathForTests.getUrl()); + element.addContent(pathElement); + } + + for (Iterator iterator = myContent.iterator(); iterator.hasNext();) { + ContentEntry contentEntry = iterator.next(); + if (contentEntry instanceof ContentEntryImpl) { + final Element subElement = new Element(ContentEntryImpl.ELEMENT_NAME); + ((ContentEntryImpl)contentEntry).writeExternal(subElement); + element.addContent(subElement); + } + } + + for (int i = 0; i < myOrder.size(); i++) { + OrderEntry orderEntry = myOrder.get(i); + if (orderEntry instanceof WritableOrderEntry) { + ((WritableOrderEntry)orderEntry).writeExternal(element); + } + } + + final Element propertiesChild = new Element(PROPERTIES_CHILD_NAME); + myOrderEntryProperties.writeExternal(propertiesChild, this); + element.addContent(propertiesChild); + + if (myJavadocPointerContainer.size() > 0) { + final Element javaDocPaths = new Element(JAVADOC_PATHS_NAME); + myJavadocPointerContainer.writeExternal(javaDocPaths, JAVADOC_ROOT_ELEMENT); + element.addContent(javaDocPaths); + } + } + + public void setJdk(ProjectJdk jdk) { + assertWritable(); + final JdkOrderEntry jdkLibraryEntry; + if (jdk != null) { + jdkLibraryEntry = new ModuleJdkOrderEntryImpl(jdk, this, myProjectRootManager, myFilePointerManager); + } + else { + jdkLibraryEntry = null; + } + replaceJdkEntry(jdkLibraryEntry); + + } + + private void replaceJdkEntry(final JdkOrderEntry jdkLibraryEntry) { + for (int i = 0; i < myOrder.size(); i++) { + OrderEntry orderEntry = myOrder.get(i); + if (orderEntry instanceof JdkOrderEntry) { + myOrder.remove(i); + if (jdkLibraryEntry != null) { + myOrder.add(i, jdkLibraryEntry); + } + return; + } + } + + if (jdkLibraryEntry != null) { + myOrder.add(0, jdkLibraryEntry); + } + } + + public void inheritJdk() { + assertWritable(); + replaceJdkEntry(new InheritedJdkOrderEntryImpl(this, myProjectRootManager, myFilePointerManager)); + } + + public ProjectJdk getJdk() { + for (int i = 0; i < myOrder.size(); i++) { + OrderEntry orderEntry = myOrder.get(i); + if (orderEntry instanceof JdkOrderEntry) { + return ((JdkOrderEntry)orderEntry).getJdk(); + } + } + return null; + } + + public boolean isJdkInherited() { + for (int i = 0; i < myOrder.size(); i++) { + OrderEntry orderEntry = myOrder.get(i); + if (orderEntry instanceof InheritedJdkOrderEntry) { + return true; + } + } + return false; + } + + public void assertWritable() { + LOG.assertTrue(myWritable); + } + + private static class ContentComparator implements Comparator { + public static final ContentComparator INSTANCE = new ContentComparator(); + + public int compare(final ContentEntry o1, final ContentEntry o2) { + return o1.getUrl().compareTo(o2.getUrl()); + } + } + + public VirtualFile getCompilerOutputPath() { + if (myCompilerOutputPath == null) { + return null; + } + else { + return myCompilerOutputPath.getFile(); + } + } + + public VirtualFile getCompilerOutputPathForTests() { + if (myCompilerOutputPathForTests == null) { + return null; + } + else { + return myCompilerOutputPathForTests.getFile(); + } + } + + public VirtualFile getExplodedDirectory() { + if (myExplodedDirectory == null) { + return null; + } + else { + return myExplodedDirectory.getFile(); + } + } + + public void setCompilerOutputPath(VirtualFile file) { + assertWritable(); + if (file != null) { + myCompilerOutputPath = pointerFactory().create(file); + } + else { + myCompilerOutputPath = null; + } + } + + public void setCompilerOutputPath(String url) { + assertWritable(); + if (url != null) { + myCompilerOutputPath = pointerFactory().create(url); + } + else { + myCompilerOutputPath = null; + } + } + + public void setCompilerOutputPathForTests(VirtualFile file) { + assertWritable(); + if (file != null) { + myCompilerOutputPathForTests = pointerFactory().create(file); + } + else { + myCompilerOutputPathForTests = null; + } + } + + public void setCompilerOutputPathForTests(String url) { + assertWritable(); + if (url != null) { + myCompilerOutputPathForTests = pointerFactory().create(url); + } + else { + myCompilerOutputPathForTests = null; + } + } + + public void setExplodedDirectory(VirtualFile file) { + assertWritable(); + if (file != null) { + myExplodedDirectory = pointerFactory().create(file); + } + else { + myExplodedDirectory = null; + } + } + + public void setExplodedDirectory(String url) { + assertWritable(); + if (url != null) { + myExplodedDirectory = pointerFactory().create(url); + } + else { + myExplodedDirectory = null; + } + } + + public Module getModule() { + return myModuleRootManager.getModule(); + } + + VirtualFilePointerListener getFileListener() { + return myVirtualFilePointerListener; + } + + public String getCompilerOutputUrl() { + if (myCompilerOutputPath == null) { + return null; + } + else { + return myCompilerOutputPath.getUrl(); + } + } + + public String getCompilerOutputUrlForTests() { + if (myCompilerOutputPathForTests == null) { + return null; + } + else { + return myCompilerOutputPathForTests.getUrl(); + } + } + + public String getExplodedDirectoryUrl() { + if (myExplodedDirectory == null) { + return null; + } + else { + return myExplodedDirectory.getUrl(); + } + } + + private static boolean vptrEqual(VirtualFilePointer p1, VirtualFilePointer p2) { + if (p1 == null && p2 == null) return true; + if (p1 == null || p2 == null) return false; + return Comparing.equal(p1.getUrl(), p2.getUrl()); + } + + + public boolean isChanged() { + if (!myWritable) return false; +// if (myJdkChanged) return true; + + if (!vptrEqual(myCompilerOutputPath, getSourceModel().myCompilerOutputPath)) { + return true; + } + if (!vptrEqual(myCompilerOutputPathForTests, getSourceModel().myCompilerOutputPathForTests)) { + return true; + } + if (!vptrEqual(myExplodedDirectory, getSourceModel().myExplodedDirectory)) { + return true; + } + + if (myExcludeOutput != getSourceModel().myExcludeOutput) return true; + if (myExcludeExploded != getSourceModel().myExcludeExploded) return true; + + OrderEntry[] orderEntries = getOrderEntries(); + OrderEntry[] sourceOrderEntries = getSourceModel().getOrderEntries(); + if (orderEntries.length != sourceOrderEntries.length) return true; + for (int i = 0; i < orderEntries.length; i++) { + OrderEntry orderEntry = orderEntries[i]; + OrderEntry sourceOrderEntry = sourceOrderEntries[i]; + if (!orderEntriesEquals(orderEntry, sourceOrderEntry)) { + return true; + } + } + + final String[] contentRootUrls = getContentRootUrls(); + final String[] thatContentRootUrls = getSourceModel().getContentRootUrls(); + if (!Arrays.equals(contentRootUrls, thatContentRootUrls)) return true; + + final String[] excludeRootUrls = getExcludeRootUrls(); + final String[] thatExcludeRootUrls = getSourceModel().getExcludeRootUrls(); + if (!Arrays.equals(excludeRootUrls, thatExcludeRootUrls)) return true; + + final String[] sourceRootForMainUrls = getSourceRootUrls(false); + final String[] thatSourceRootForMainUrls = getSourceModel().getSourceRootUrls(false); + if (!Arrays.equals(sourceRootForMainUrls, thatSourceRootForMainUrls)) return true; + + final String[] sourceRootForTestUrls = getSourceRootUrls(true); + final String[] thatSourceRootForTestUrls = getSourceModel().getSourceRootUrls(true); + if (!Arrays.equals(sourceRootForTestUrls, thatSourceRootForTestUrls)) return true; + + final ContentEntry[] contentEntries = getContentEntries(); + final ContentEntry[] thatContentEntries = getSourceModel().getContentEntries(); + if (contentEntries.length != thatContentEntries.length) return true; + for (int i = 0; i < contentEntries.length; i++) { + final ContentEntry contentEntry = contentEntries[i]; + final ContentEntry thatContentEntry = thatContentEntries[i]; + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + final SourceFolder[] thatSourceFolders = thatContentEntry.getSourceFolders(); + if (sourceFolders.length != thatSourceFolders.length) return true; + for (int j = 0; j < sourceFolders.length; j++) { + final SourceFolder sourceFolder = sourceFolders[j]; + final SourceFolder thatSourceFolder = thatSourceFolders[j]; + if (!sourceFolder.getUrl().equals(thatSourceFolder.getUrl()) + || !sourceFolder.getPackagePrefix().equals(thatSourceFolder.getPackagePrefix())) { + return true; + } + } + } + final String[] urls = myJavadocPointerContainer.getUrls(); + final String[] thatUrls = getSourceModel().myJavadocPointerContainer.getUrls(); + if (!Arrays.equals(urls, thatUrls)) return true; + return false; + } + + void addExportedFiles(OrderRootType type, List result, Set processed) { + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + final OrderEntry orderEntry = iterator.next(); + if (orderEntry instanceof ModuleSourceOrderEntryImpl) { + ((ModuleSourceOrderEntryImpl)orderEntry).addExportedFiles(type, result); + } + else if (orderEntry instanceof ExportableOrderEntry && ((ExportableOrderEntry)orderEntry).isExported()) { + if (orderEntry instanceof ModuleOrderEntryImpl) { + result.addAll(Arrays.asList(((ModuleOrderEntryImpl)orderEntry).getFiles(type, processed))); + } + else { + result.addAll(Arrays.asList(orderEntry.getFiles(type))); + } + } + } + } + + void addExportedUrs(OrderRootType type, List result, Set processed) { + for (Iterator iterator = myOrder.iterator(); iterator.hasNext();) { + final OrderEntry orderEntry = iterator.next(); + if (orderEntry instanceof ModuleSourceOrderEntry) { + ((ModuleSourceOrderEntryImpl)orderEntry).addExportedUrls(type, result); + } + else if (orderEntry instanceof ExportableOrderEntry && ((ExportableOrderEntry)orderEntry).isExported()) { + if (orderEntry instanceof ModuleOrderEntryImpl) { + result.addAll(Arrays.asList(((ModuleOrderEntryImpl)orderEntry).getUrls(type, processed))); + } + else { + result.addAll(Arrays.asList(orderEntry.getUrls(type))); + } + } + } + } + + private static boolean orderEntriesEquals(OrderEntry orderEntry1, OrderEntry orderEntry2) { + if (!((OrderEntryBaseImpl)orderEntry1).sameType(orderEntry2)) return false; + if (orderEntry1 instanceof JdkOrderEntry) { + if (!(orderEntry2 instanceof JdkOrderEntry)) return false; + if (orderEntry1 instanceof InheritedJdkOrderEntry && orderEntry2 instanceof ModuleJdkOrderEntry) { + return false; + } + if (orderEntry2 instanceof InheritedJdkOrderEntry && orderEntry1 instanceof ModuleJdkOrderEntry) { + return false; + } + if (orderEntry1 instanceof ModuleJdkOrderEntry && orderEntry2 instanceof ModuleJdkOrderEntry) { + String name1 = ((ModuleJdkOrderEntry)orderEntry1).getJdkName(); + String name2 = ((ModuleJdkOrderEntry)orderEntry2).getJdkName(); + if (!name1.equals(name2)) { + return false; + } + } + } + if (orderEntry1 instanceof ExportableOrderEntry) { + if (!(((ExportableOrderEntry)orderEntry1).isExported() == ((ExportableOrderEntry)orderEntry2).isExported())) { + return false; + } + } + if (orderEntry1 instanceof ModuleOrderEntry) { + LOG.assertTrue(orderEntry2 instanceof ModuleOrderEntryImpl); + final String name1 = ((ModuleOrderEntryImpl)orderEntry1).getModuleName(); + final String name2 = ((ModuleOrderEntryImpl)orderEntry2).getModuleName(); + return Comparing.equal(name1, name2); + } + + if (orderEntry1 instanceof LibraryOrderEntry) { + LOG.assertTrue(orderEntry2 instanceof LibraryOrderEntry); + LibraryOrderEntry libraryOrderEntry1 = (LibraryOrderEntry)orderEntry1; + LibraryOrderEntry libraryOrderEntry2 = (LibraryOrderEntry)orderEntry2; + boolean equal = Comparing.equal(libraryOrderEntry1.getLibraryName(), libraryOrderEntry2.getLibraryName()) + && Comparing.equal(libraryOrderEntry1.getLibraryLevel(), libraryOrderEntry2.getLibraryLevel()); + if (!equal) return false; + } + + final OrderRootType[] allTypes = OrderRootType.ALL_TYPES; + for (int i = 0; i < allTypes.length; i++) { + OrderRootType type = allTypes[i]; + final String[] orderedRootUrls1 = orderEntry1.getUrls(type); + final String[] orderedRootUrls2 = orderEntry2.getUrls(type); + if (!Arrays.equals(orderedRootUrls1, orderedRootUrls2)) { + return false; + } + } + return true; + } + + void fireBeforeExternalChange() { + if (myWritable || myDisposed) return; + myModuleRootManager.fireBeforeRootsChange(); + } + + void fireAfterExternalChange() { + if (myWritable || myDisposed) return; + myModuleRootManager.fireRootsChanged(); + } + + public void dispose() { + assertWritable(); + disposeModel(); + myWritable = false; + } + + boolean isDisposed() { + return myDisposed; + } + + void disposeModel() { + final RootModelComponentBase[] rootModelComponentBases = myComponents.toArray( + new RootModelComponentBase[myComponents.size()]); + for (int i = 0; i < rootModelComponentBases.length; i++) { + RootModelComponentBase rootModelComponentBase = rootModelComponentBases[i]; + rootModelComponentBase.dispose(); + } + + for (Iterator iterator = myPointersToDispose.iterator(); iterator.hasNext();) { + VirtualFilePointer pointer = iterator.next(); + myFilePointerManager.kill(pointer); + } + myDisposed = true; + } + + public boolean isExcludeOutput() { return myExcludeOutput; } + + public boolean isExcludeExplodedDirectory() { return myExcludeExploded; } + + public void setExcludeOutput(boolean excludeOutput) { myExcludeOutput = excludeOutput; } + + public void setExcludeExplodedDirectory(boolean excludeExplodedDir) { myExcludeExploded = excludeExplodedDir; } + + private void annotatePointer(VirtualFilePointer pointer) { + pointer.putUserData(ORIGINATING_ROOT_MODEL, this); + myPointersToDispose.add(pointer); + } + + private class Order extends ArrayList { + public OrderEntry set(int i, OrderEntry orderEntry) { + super.set(i, orderEntry); + ((OrderEntryBaseImpl)orderEntry).setIndex(i); + return orderEntry; + } + + public boolean add(OrderEntry orderEntry) { + super.add(orderEntry); + ((OrderEntryBaseImpl)orderEntry).setIndex(size() - 1); + return true; + } + + public void add(int i, OrderEntry orderEntry) { + super.add(i, orderEntry); + setIndicies(i); + } + + public OrderEntry remove(int i) { + OrderEntry entry = super.remove(i); + setIndicies(i); + if (myComponents.contains(entry)) { + ((RootModelComponentBase)entry).dispose(); + } + return entry; + } + + public boolean remove(Object o) { + int index = indexOf(o); + if (index < 0) return false; + remove(index); + return true; + } + + public boolean addAll(Collection collection) { + int startSize = size(); + boolean result = super.addAll(collection); + setIndicies(startSize); + return result; + } + + public boolean addAll(int i, Collection collection) { + boolean result = super.addAll(i, collection); + setIndicies(i); + return result; + } + + public void removeRange(int i, int i1) { + super.removeRange(i, i1); + setIndicies(i); + } + + public boolean removeAll(Collection collection) { + boolean result = super.removeAll(collection); + setIndicies(0); + return result; + } + + public boolean retainAll(Collection collection) { + boolean result = super.retainAll(collection); + setIndicies(0); + return result; + } + + private void setIndicies(int startIndex) { + for (int j = startIndex; j < size(); j++) { + ((OrderEntryBaseImpl)get(j)).setIndex(j); + } + } + } + + public String[] getDependencyModuleNames() { + List result = processOrder(new CollectDependentModules(), new ArrayList()); + return result.toArray(new String[result.size()]); + } + + public Module[] getModuleDependencies() { + final List result = new ArrayList(); + + for (int i = 0; i < myOrder.size(); i++) { + OrderEntry entry = myOrder.get(i); + if (entry instanceof ModuleOrderEntry) { + final Module module1 = ((ModuleOrderEntry)entry).getModule(); + if (module1 != null) { + result.add(module1); + } + } + } + + return result.toArray(new Module[result.size()]); + } + + VirtualFilePointerFactory pointerFactory() { + return myVirtualFilePointerFactory; + } + + private RootModelImpl getSourceModel() { + assertWritable(); + return myModuleRootManager.getRootModel(); + } + + + private static class CollectDependentModules extends RootPolicy> { + public List visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, List arrayList) { + arrayList.add(moduleOrderEntry.getModuleName()); + return arrayList; + } + } + + + public VirtualFile[] getJavadocPaths() { + return myJavadocPointerContainer.getDirectories(); + } + + public String[] getJavadocUrls() { + return myJavadocPointerContainer.getUrls(); + } + + public void setJavadocUrls(String[] urls) { + assertWritable(); + myJavadocPointerContainer.clear(); + for (int i = 0; i < urls.length; i++) { + final String url = urls[i]; + myJavadocPointerContainer.add(url); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootProviderBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootProviderBaseImpl.java new file mode 100644 index 00000000000..12b25096976 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/RootProviderBaseImpl.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.roots.RootProvider; +import com.intellij.util.EventDispatcher; + +/** + * @author dsl + */ +public abstract class RootProviderBaseImpl implements RootProvider { + private EventDispatcher myDispatcher = EventDispatcher.create(RootSetChangedListener.class); + public void addRootSetChangedListener(RootSetChangedListener listener) { + myDispatcher.addListener(listener); + } + + public void removeRootSetChangedListener(RootSetChangedListener listener) { + myDispatcher.removeListener(listener); + } + + protected void fireRootSetChanged() { + myDispatcher.getMulticaster().rootSetChanged(this); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/SourceFolderImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/SourceFolderImpl.java new file mode 100644 index 00000000000..df4b9365465 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/SourceFolderImpl.java @@ -0,0 +1,81 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; + +/** + * @author dsl + */ +public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFolder, ClonableContentFolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleSourceFolderImpl"); + private boolean myIsTestSource; + static final String ELEMENT_NAME = "sourceFolder"; + private static final String TEST_SOURCE_ATTR = "isTestSource"; + private String myPackagePrefix; + static final String DEFAULT_PACKAGE_PREFIX = ""; + private static final String PACKAGE_PREFIX_ATTR = "packagePrefix"; + + SourceFolderImpl(VirtualFile file, boolean isTestSource, ContentEntryImpl contentEntry) { + this(file, isTestSource, DEFAULT_PACKAGE_PREFIX, contentEntry); + } + + SourceFolderImpl(VirtualFile file, boolean isTestSource, String packagePrefix, ContentEntryImpl contentEntry) { + super(file, contentEntry); + myIsTestSource = isTestSource; + myPackagePrefix = packagePrefix; + } + + SourceFolderImpl(Element element, ContentEntryImpl contentEntry) throws InvalidDataException { + super(element, contentEntry); + LOG.assertTrue(element.getName().equals(ELEMENT_NAME)); + final String testSource = element.getAttributeValue("isTestSource"); + if (testSource == null) throw new InvalidDataException(); + myIsTestSource = Boolean.valueOf(testSource).booleanValue(); + final String packagePrefix = element.getAttributeValue(PACKAGE_PREFIX_ATTR); + if (packagePrefix != null) { + myPackagePrefix = packagePrefix; + } + else { + myPackagePrefix = DEFAULT_PACKAGE_PREFIX; + } + } + + private SourceFolderImpl(SourceFolderImpl that, ContentEntryImpl contentEntry) { + super(that, contentEntry); + myIsTestSource = that.myIsTestSource; + myPackagePrefix = that.myPackagePrefix; + } + + public boolean isTestSource() { + return myIsTestSource; + } + + public String getPackagePrefix() { + return myPackagePrefix; + } + + public void setPackagePrefix(String packagePrefix) { + myPackagePrefix = packagePrefix; + } + + void writeExternal(Element element) { + writeFolder(element, ELEMENT_NAME); + element.setAttribute(TEST_SOURCE_ATTR, Boolean.toString(myIsTestSource)); + if (!DEFAULT_PACKAGE_PREFIX.equals(myPackagePrefix)) { + element.setAttribute(PACKAGE_PREFIX_ATTR, myPackagePrefix); + } + } + + public ContentFolder cloneFolder(ContentEntry contentEntry) { + return new SourceFolderImpl(this, (ContentEntryImpl)contentEntry); + } + + public boolean isSynthetic() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/WritableOrderEntry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/WritableOrderEntry.java new file mode 100644 index 00000000000..a74d826c9b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/WritableOrderEntry.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +/** + * @author dsl + */ +interface WritableOrderEntry { + void writeExternal(Element rootElement) throws WriteExternalException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ApplicationLibraryTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ApplicationLibraryTable.java new file mode 100644 index 00000000000..ac6b574c346 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ApplicationLibraryTable.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.application.options.PathMacros; +import com.intellij.application.options.ExpandMacroToPathMap; +import com.intellij.application.options.ReplacePathToMacroMap; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.util.*; +import org.jdom.Element; + +import java.io.File; + +/** + * @author dsl + */ +public class ApplicationLibraryTable extends LibraryTableBase implements NamedJDOMExternalizable, ExportableApplicationComponent { + private PathMacros myPathMacros; + + public ApplicationLibraryTable(PathMacros pathMacros) { + myPathMacros = pathMacros; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getTableLevel() { + return LibraryTablesRegistrar.APPLICATION_LEVEL; + } + + public String getExternalFileName() { + return "applicationLibraries"; + } + + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile(this)}; + } + + public String getPresentableName() { + return "Global libraries"; + } + + public static LibraryTable getInstance() { + return ApplicationManager.getApplication().getComponent(LibraryTable.class); + } + + public void readExternal(Element element) throws InvalidDataException { + final ExpandMacroToPathMap macroExpands = new ExpandMacroToPathMap(); + myPathMacros.addMacroExpands(macroExpands); + macroExpands.substitute(element, SystemInfo.isFileSystemCaseSensitive); + super.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + final ReplacePathToMacroMap macroReplacements = new ReplacePathToMacroMap(); + PathMacros.getInstance().addMacroReplacements(macroReplacements); + macroReplacements.substitute(element, SystemInfo.isFileSystemCaseSensitive); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryEx.java new file mode 100644 index 00000000000..7183d90cdda --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryEx.java @@ -0,0 +1,12 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.libraries.Library; + +/** + * @author dsl + */ +public interface LibraryEx extends Library { + Library cloneLibrary(); + void setRootModel(ModifiableRootModel rootModel); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java new file mode 100644 index 00000000000..8ede63b4b61 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -0,0 +1,258 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.impl.RootProviderBaseImpl; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jdom.Element; + +import java.util.Arrays; +import java.util.List; + +/** + * @author dsl + */ +public class LibraryImpl implements Library.ModifiableModel, LibraryEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.impl.LibraryImpl"); + private static final String LIBRARY_NAME_ATTR = "name"; + private static final String ROOT_PATH_ELEMENT = "root"; + private String myName; + private final LibraryTable myLibraryTable; + private com.intellij.util.containers.HashMap myRoots; + private LibraryImpl mySource; + + private final MyRootProviderImpl myRootProvider = new MyRootProviderImpl(); + public static final String ELEMENT = "library"; + private ModifiableRootModel myRootModel; + + LibraryImpl(String name, LibraryTable table) { + myName = name; + myLibraryTable = table; + myRoots = initRoots(); + mySource = null; + } + + LibraryImpl(LibraryTable table) { + myLibraryTable = table; + myRoots = initRoots(); + mySource = null; + } + + + LibraryImpl() { + myLibraryTable = null; + myRoots = initRoots(); + mySource = null; + } + + LibraryImpl(LibraryImpl that) { + myName = that.myName; + myRoots = initRoots(); + mySource = that; + myLibraryTable = that.myLibraryTable; + for (int i = 0; i < SERIALIZABLE_ROOT_TYPES.length; i++) { + OrderRootType rootType = SERIALIZABLE_ROOT_TYPES[i]; + final VirtualFilePointerContainer thisContainer = myRoots.get(rootType); + final VirtualFilePointerContainer thatContainer = that.myRoots.get(rootType); + thisContainer.addAll(thatContainer); + } + } + + public String getName() { + return myName; + } + + public String[] getUrls(OrderRootType rootType) { + final VirtualFilePointerContainer result = myRoots.get(rootType); + return result.getUrls(); + } + + public VirtualFile[] getFiles(OrderRootType rootType) { + final VirtualFilePointerContainer result = myRoots.get(rootType); + return result.getFiles(); + } + + public VirtualFilePointer[] getFilePointers(OrderRootType rootType) { + final List list = myRoots.get(rootType).getList(); + return (VirtualFilePointer[])list.toArray(new VirtualFilePointer[list.size()]); + } + + public void setName(String name) { + LOG.assertTrue(isWritable()); + myName = name; + } + + public Library.ModifiableModel getModifiableModel() { + return new LibraryImpl(this); + } + + public Library cloneLibrary() { + LOG.assertTrue(myLibraryTable == null); + final LibraryImpl that = new LibraryImpl(this); + that.mySource = null; + return that; + } + + public void setRootModel(ModifiableRootModel rootModel) { + LOG.assertTrue(myLibraryTable == null); + myRootModel = rootModel; + } + + public RootProvider getRootProvider() { + return myRootProvider; + } + + private com.intellij.util.containers.HashMap initRoots() { + final com.intellij.util.containers.HashMap result = + new com.intellij.util.containers.HashMap(5); + + final VirtualFilePointerContainer classesRoots = VirtualFilePointerManager.getInstance().createContainer(); + result.put(OrderRootType.CLASSES, classesRoots); + result.put(OrderRootType.COMPILATION_CLASSES, classesRoots); + result.put(OrderRootType.CLASSES_AND_OUTPUT, classesRoots); + result.put(OrderRootType.JAVADOC, VirtualFilePointerManager.getInstance().createContainer()); + result.put(OrderRootType.SOURCES, VirtualFilePointerManager.getInstance().createContainer()); + return result; + } + + private static final OrderRootType[] SERIALIZABLE_ROOT_TYPES = { + OrderRootType.CLASSES, OrderRootType.JAVADOC, OrderRootType.SOURCES + }; + + public void readExternal(Element element) throws InvalidDataException { + final String nameAttribute = element.getAttributeValue(LIBRARY_NAME_ATTR); + myName = nameAttribute; + for (int rootIndex = 0; rootIndex < SERIALIZABLE_ROOT_TYPES.length; rootIndex++) { + OrderRootType rootType = SERIALIZABLE_ROOT_TYPES[rootIndex]; + VirtualFilePointerContainer roots = myRoots.get(rootType); + final Element rootChild = element.getChild(rootType.getName()); + if (rootChild == null) continue; + roots.readExternal(rootChild, ROOT_PATH_ELEMENT); + } + } + + + public void writeExternal(Element rootElement) throws WriteExternalException { + Element element = new Element(ELEMENT); + if (myName != null) { + element.setAttribute(LIBRARY_NAME_ATTR, myName); + } + + for (int rootIndex = 0; rootIndex < SERIALIZABLE_ROOT_TYPES.length; rootIndex++) { + OrderRootType rootType = SERIALIZABLE_ROOT_TYPES[rootIndex]; + final Element rootTypeElement = new Element(rootType.getName()); + final VirtualFilePointerContainer roots = myRoots.get(rootType); + roots.writeExternal(rootTypeElement, ROOT_PATH_ELEMENT); + element.addContent(rootTypeElement); + } + rootElement.addContent(element); + } + + private boolean isWritable() { + return mySource != null; + } + + public void addRoot(String url, OrderRootType rootType) { + LOG.assertTrue(isWritable()); + + final VirtualFilePointerContainer container = myRoots.get(rootType); + container.add(url); + } + + public void addRoot(VirtualFile file, OrderRootType rootType) { + LOG.assertTrue(isWritable()); + + final VirtualFilePointerContainer container = myRoots.get(rootType); + container.add(file); + } + + public boolean removeRoot(String url, OrderRootType rootType) { + LOG.assertTrue(isWritable()); + final VirtualFilePointerContainer container = myRoots.get(rootType); + final VirtualFilePointer byUrl = container.findByUrl(url); + if (byUrl != null) { + container.remove(byUrl); + return true; + } else { + return false; + } + } + + public void moveRootUp(String url, OrderRootType rootType) { + LOG.assertTrue(isWritable()); + final VirtualFilePointerContainer container = myRoots.get(rootType); + container.moveUp(url); + } + + public void moveRootDown(String url, OrderRootType rootType) { + LOG.assertTrue(isWritable()); + final VirtualFilePointerContainer container = myRoots.get(rootType); + container.moveDown(url); + } + + public boolean isChanged() { + final boolean sameName = Comparing.equal(mySource.myName, myName); + final boolean sameRoots = myRoots.equals(mySource.myRoots); + return !sameName || !sameRoots; + } + + public void commit() { + LOG.assertTrue(mySource != null); + mySource.commit(this); + mySource = null; + } + + private void commit(LibraryImpl model) { + if (myLibraryTable != null) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + } else if (myRootModel != null) { + LOG.assertTrue(myRootModel.isWritable()); + } + final boolean sameName = Comparing.equal(model.myName, myName); + boolean sameRoots = true; + for (int i = 0; i < SERIALIZABLE_ROOT_TYPES.length; i++) { + final OrderRootType rootType = SERIALIZABLE_ROOT_TYPES[i]; + final VirtualFilePointerContainer container = myRoots.get(rootType); + final VirtualFilePointerContainer thatContainer = model.myRoots.get(rootType); + sameRoots = Arrays.equals(container.getUrls(), thatContainer.getUrls()); + if (!sameRoots) break; + } + final boolean isChanged = sameName && sameRoots; + if (isChanged) return; + if (!sameName) { + myName = model.myName; + if (myLibraryTable instanceof LibraryTableBase) { + ((LibraryTableBase)myLibraryTable).fireLibraryRenamed(this); + } + } + if (!sameRoots) { + myRoots = model.myRoots; + myRootProvider.fireRootSetChanged(); + } + } + + private class MyRootProviderImpl extends RootProviderBaseImpl { + public String[] getUrls(OrderRootType rootType) { + return LibraryImpl.this.getUrls(rootType); + } + + public void fireRootSetChanged() { + super.fireRootSetChanged(); + } + } + + public LibraryTable getTable() { + return myLibraryTable; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java new file mode 100644 index 00000000000..3bf3734d0fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java @@ -0,0 +1,211 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.CollectUtil; +import com.intellij.util.containers.Convertor; +import org.jdom.Element; + +import java.util.*; + +/** + * @author dsl + */ +public abstract class LibraryTableBase implements JDOMExternalizable, LibraryTable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.libraries.LibraryTableBase"); + private final EventDispatcher myDispatcher = EventDispatcher.create(Listener.class); + private LibraryModel myModel = new LibraryModel(); + + + public LibraryTable.ModifiableModel getModifiableModel() { + return new LibraryModel(myModel); + } + + public void readExternal(Element element) throws InvalidDataException { + myModel.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException { + myModel.writeExternal(element); + } + + public Library[] getLibraries() { + return myModel.getLibraries(); + } + + public Iterator getLibraryIterator() { + return myModel.getLibraryIterator(); + } + + public Library getLibraryByName(String name) { + return myModel.getLibraryByName(name); + } + + public void addListener(Listener listener) { + myDispatcher.addListener(listener); + } + + public void removeListener(Listener listener) { + myDispatcher.removeListener(listener); + } + + private void fireLibraryAdded (Library library) { + myDispatcher.getMulticaster().afterLibraryAdded(library); + } + + private void fireBeforeLibraryRemoved (Library library) { + myDispatcher.getMulticaster().beforeLibraryRemoved(library); + } + + + public Library createLibrary() { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + return createLibrary(null); + } + + + public String getComponentName() { + return "libraryTable"; + } + + public void fireLibraryRenamed(LibraryImpl library) { + myDispatcher.getMulticaster().afterLibraryRenamed(library); + } + + public Library createLibrary(String name) { + final LibraryTable.ModifiableModel modifiableModel = getModifiableModel(); + final Library library = modifiableModel.createLibrary(name); + modifiableModel.commit(); + return library; + } + + public void removeLibrary(Library library) { + final LibraryTable.ModifiableModel modifiableModel = getModifiableModel(); + modifiableModel.removeLibrary(library); + modifiableModel.commit(); + } + + public void commit(LibraryModel model) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + List addedLibraries = new ArrayList(model.myLibraries); + addedLibraries.removeAll(myModel.myLibraries); + List removedLibraries = new ArrayList(myModel.myLibraries); + removedLibraries.removeAll(model.myLibraries); + + for (Iterator iterator = removedLibraries.iterator(); iterator.hasNext();) { + LibraryImpl library = iterator.next(); + fireBeforeLibraryRemoved(library); + } + myModel = model; + for (Iterator iterator = removedLibraries.iterator(); iterator.hasNext();) { + LibraryImpl library = iterator.next(); + fireAfterLibraryRemoved(library); + } + for (Iterator iterator = addedLibraries.iterator(); iterator.hasNext();) { + LibraryImpl library = iterator.next(); + fireLibraryAdded(library); + } + } + + private void fireAfterLibraryRemoved(LibraryImpl library) { + myDispatcher.getMulticaster().afterLibraryRemoved(library); + } + + private class LibraryModel implements LibraryTable.ModifiableModel { + private final ArrayList myLibraries = new ArrayList(); + private boolean myWritable; + + private LibraryModel() { + myWritable = false; + } + + private LibraryModel(LibraryModel that) { + myWritable = true; + myLibraries.addAll(that.myLibraries); + } + + public void commit() { + myWritable = false; + LibraryTableBase.this.commit(this); + } + + public Iterator getLibraryIterator() { + return Collections.unmodifiableList(myLibraries).iterator(); + } + + public Library getLibraryByName(String name) { + for (int i = 0; i < myLibraries.size(); i++) { + LibraryImpl library = (LibraryImpl) myLibraries.get(i); + if (Comparing.equal(name, library.getName())) return library; + } + return null; + } + + + public Library[] getLibraries() { + return (Library[]) myLibraries.toArray(new Library[myLibraries.size()]); + } + + private void assertWritable() { + LOG.assertTrue(myWritable); + } + + public Library createLibrary(String name) { + assertWritable(); + final LibraryImpl library = new LibraryImpl(name, LibraryTableBase.this); + myLibraries.add(library); + return library; + } + + public void removeLibrary(Library library) { + assertWritable(); + myLibraries.remove(library); + } + + public boolean isChanged() { + if (!myWritable) return false; + Set thisLibraries = new com.intellij.util.containers.HashSet(myLibraries); + Set thatLibraries = new com.intellij.util.containers.HashSet(myModel.myLibraries); + return !thisLibraries.equals(thatLibraries); + } + + public void readExternal(Element element) throws InvalidDataException { + HashMap libraries = new HashMap(); + for (Iterator iterator = myLibraries.iterator(); iterator.hasNext();) { + LibraryImpl library = iterator.next(); + libraries.put(library.getName(), library); + } + + final List libraryElements = element.getChildren(LibraryImpl.ELEMENT); + for (int i = 0; i < libraryElements.size(); i++) { + Element libraryElement = (Element) libraryElements.get(i); + final LibraryImpl library = new LibraryImpl(LibraryTableBase.this); + library.readExternal(libraryElement); + if (library.getName() != null) { + LibraryImpl oldLibrary = libraries.get(library.getName()); + if(oldLibrary != null) { + myLibraries.remove(oldLibrary); + } + myLibraries.add(library); + fireLibraryAdded(library); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + for (int i = 0; i < myLibraries.size(); i++) { + LibraryImpl library = (LibraryImpl) myLibraries.get(i); + if (library.getName() != null) { + library.writeExternal(element); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableImplUtil.java new file mode 100644 index 00000000000..c7de76b8fbe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTableImplUtil.java @@ -0,0 +1,33 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTableUtil; +import com.intellij.openapi.util.InvalidDataException; +import org.jdom.Element; + +import java.util.List; + +/** + * @author dsl + */ +public class LibraryTableImplUtil extends LibraryTableUtil { + public static final String MODULE_LEVEL = "module"; + + + public static Library loadLibrary(Element rootElement, final LibraryTable libraryTable) throws InvalidDataException { + final LibraryImpl library = new LibraryImpl(libraryTable); + final List children = rootElement.getChildren(LibraryImpl.ELEMENT); + if (children.size() != 1) throw new InvalidDataException(); + library.readExternal((Element) children.get(0)); + return library; + } + + public static Library createModuleLevelLibrary() { + return new LibraryImpl(); + } + + public static Library createModuleLevelLibrary(String name) { + return new LibraryImpl(name, null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java new file mode 100644 index 00000000000..27e225e3ac4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/LibraryTablesRegistrarImpl.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.util.containers.HashMap; + +import java.util.Map; + +public class LibraryTablesRegistrarImpl extends LibraryTablesRegistrar implements ApplicationComponent { + static final Map myLibraryTables = new HashMap(); + + public LibraryTable getLibraryTable() { + return ApplicationManager.getApplication().getComponent(LibraryTable.class); + } + + public LibraryTable getLibraryTable(Project project) { + return project.getComponent(LibraryTable.class); + } + + public LibraryTable getLibraryTableByLevel(String level, Project project) { + if (LibraryTablesRegistrar.PROJECT_LEVEL.equals(level)) return getLibraryTable(project); + if (LibraryTablesRegistrar.APPLICATION_LEVEL.equals(level)) return getLibraryTable(); + return myLibraryTables.get(level); + } + + public void registerLibraryTable(LibraryTable libraryTable) { + String tableLevel = libraryTable.getTableLevel(); + final LibraryTable oldTable = myLibraryTables.put(tableLevel, libraryTable); + if (oldTable != null) { + throw new IllegalArgumentException("Library table '" + tableLevel + "' already registered."); + } + } + + public LibraryTable registerLibraryTable(final String customLevel) { + LibraryTable table = new LibraryTableBase() { + public String getTableLevel() { + return customLevel; + } + }; + + registerLibraryTable(table); + return table; + } + + public String getComponentName() { + return "LibraryTablesRegistrar"; + } + + public void initComponent() { } + + public void disposeComponent() { + myLibraryTables.clear(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ProjectLibraryTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ProjectLibraryTable.java new file mode 100644 index 00000000000..7171ddf2073 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/impl/libraries/ProjectLibraryTable.java @@ -0,0 +1,33 @@ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; + +/** + * @author dsl + */ +public class ProjectLibraryTable extends LibraryTableBase implements ProjectComponent { + ProjectLibraryTable (Project project) { + + } + public static LibraryTable getInstance(Project project) { + return project.getComponent(LibraryTable.class); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public String getTableLevel() { + return LibraryTablesRegistrar.PROJECT_LEVEL; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/LightFilePointer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/LightFilePointer.java new file mode 100644 index 00000000000..5f2f7b84bbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/LightFilePointer.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.roots.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import org.jdom.Element; + +import java.io.File; + +public class LightFilePointer extends UserDataHolderBase implements VirtualFilePointer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.LightFilePointer"); + private String myUrl; + private VirtualFile myFile; + + public LightFilePointer(String url) { + myUrl = url; + } + + public VirtualFile getFile() { + refreshFile(); + return myFile; + } + + public String getUrl() { + return myUrl; + } + + public String getFileName() { + if (myFile != null) { + return myFile.getName(); + } else { + int index = myUrl.lastIndexOf('/'); + return (index >= 0) ? myUrl.substring(index + 1) : myUrl; + } + } + + public String getPresentableUrl() { + VirtualFile file = getFile(); + if (file != null) return file.getPresentableUrl(); + return toPresentableUrl(myUrl); + } + + public static String toPresentableUrl(String url) { + String path = VirtualFileManager.extractPath(url); + if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { + path = path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()); + } + return path.replace('/', File.separatorChar); + } + + public boolean isValid() { + return getFile() != null; + } + + public void readExternal(Element element) throws InvalidDataException { + LOG.assertTrue(false); + } + + public void writeExternal(Element element) throws WriteExternalException { + LOG.assertTrue(false); + } + + private void refreshFile() { + if (myFile != null && myFile.isValid()) return; + VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(myUrl); + myFile = (virtualFile != null && virtualFile.isValid()) ? virtualFile : null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/components/ScrollablePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/components/ScrollablePanel.java new file mode 100644 index 00000000000..6ae2f59afcb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/components/ScrollablePanel.java @@ -0,0 +1,49 @@ +package com.intellij.openapi.roots.ui.componentsList.components; + +import javax.swing.*; +import java.awt.*; + +public class ScrollablePanel extends JPanel implements Scrollable { + private int myUnitHeight = -1; + private int myUnitWidth = 10; + + public ScrollablePanel(LayoutManager layout) { + super(layout); + } + + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + public void addNotify() { + super.addNotify(); + final FontMetrics fontMetrics = getFontMetrics(getFont()); + if (myUnitHeight < 0) { + myUnitHeight = fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent(); + } + } + + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.HORIZONTAL) { + return myUnitWidth; + } + else { + return myUnitHeight; + } + } + + public boolean getScrollableTracksViewportWidth() { + return true; + } + + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.HORIZONTAL) { + return visibleRect.width; + } + return visibleRect.height; + } + + public boolean getScrollableTracksViewportHeight() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/ComponentOperation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/ComponentOperation.java new file mode 100644 index 00000000000..ecc277d6a39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/ComponentOperation.java @@ -0,0 +1,78 @@ +package com.intellij.openapi.roots.ui.componentsList.layout; + + +import java.awt.*; + +public abstract class ComponentOperation { + public abstract void applyTo(Component component); + + public static class SizeCalculator extends ComponentOperation { + private final int myDefaultExtent; + private final SizeProperty mySizeProperty; + private OrientedDimensionSum myDimensionSum; + + public SizeCalculator(int defaultExtent, SizeProperty sizeProperty, Orientation orientation) { + myDefaultExtent = defaultExtent; + mySizeProperty = sizeProperty; + myDimensionSum = new OrientedDimensionSum(orientation); + } + + protected SizeCalculator(SizeProperty sizeProperty) { + this(0, sizeProperty, Orientation.VERTICAL); + } + + public void applyTo(Component component) { + Dimension size = mySizeProperty.getSize(component); + if (size != null) { + myDimensionSum.add(size); + } else + myDimensionSum.grow(myDefaultExtent); + } + + public OrientedDimensionSum getSum() { + return myDimensionSum; + } + } + + public static class InlineLayout extends ComponentOperation { + private final Point myPosition; + private final int myParentExtent; + private final int myDefaultExtent; + private final SizeProperty mySizeProperty; + private final Orientation myOrientation; + + public InlineLayout(Container parent, int defaultExtent, SizeProperty sizeProperty, Orientation orientation) { + final Insets insets = parent.getInsets(); + + myOrientation = orientation; + mySizeProperty = sizeProperty; + myDefaultExtent = defaultExtent; + myParentExtent = myOrientation.getContrary().getInnerExtent(parent); + myPosition = new Point(insets.left, insets.top); + } + + public void applyTo(Component component) { + component.setSize(myParentExtent, myDefaultExtent); + Dimension preferredSize = mySizeProperty.getSize(component); + int height = getHeight(preferredSize); + int width = getWidth(preferredSize); + component.setBounds(myPosition.x, myPosition.y, width, height); + myOrientation.advance(myPosition, width, height); + } + + private int getHeight(Dimension preferredSize) { + if (myOrientation.isVertical()) + return preferredSize != null ? preferredSize.height : myDefaultExtent; + else + return myParentExtent; + } + + private int getWidth(Dimension preferredSize) { + if (!myOrientation.isVertical()) + return preferredSize != null ? preferredSize.width : myDefaultExtent; + else + return myParentExtent; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/Orientation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/Orientation.java new file mode 100644 index 00000000000..0848cc71544 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/Orientation.java @@ -0,0 +1,86 @@ +package com.intellij.openapi.roots.ui.componentsList.layout; + + +import java.awt.*; + +public abstract class Orientation { + public static Orientation VERTICAL = new Orientation() { + public int getExtent(Insets insets) { + return insets.top + insets.bottom; + } + + public Orientation getContrary() { + return HORIZONTAL; + } + + public int getExtent(Container container) { + return container.getHeight(); + } + + public void advance(Point point, int width, int height) { + point.y += height; + } + + public boolean isVertical() { + return true; + } + + public void extend(Dimension dimension, int extend) { + dimension.height += extend; + } + + public void expandInline(Dimension dimension, Dimension extend) { + dimension.height += extend.height; + dimension.width = Math.max(dimension.width, extend.width); + } + }; + + public static Orientation HORIZONTAL = new Orientation() { + public int getExtent(Insets insets) { + return insets.left + insets.right; + } + + public Orientation getContrary() { + return VERTICAL; + } + + public int getExtent(Container container) { + return container.getWidth(); + } + + public void advance(Point point, int width, int height) { + point.x += width; + } + + public boolean isVertical() { + return false; + } + + public void extend(Dimension dimension, int extend) { + dimension.width += extend; + } + + public void expandInline(Dimension dimension, Dimension extend) { + dimension.width += extend.width; + dimension.height = Math.max(dimension.height, extend.height); + } + }; + + public int getInnerExtent(Container container) { + return getExtent(container) - getExtent(container.getInsets()); + } + + public abstract int getExtent(Insets insets); + + public abstract Orientation getContrary(); + + public abstract int getExtent(Container container); + + public abstract void advance(Point point, int width, int height); + + public abstract boolean isVertical(); + + public abstract void extend(Dimension dimension, int extend); + + public abstract void expandInline(Dimension dimension, Dimension extend); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/OrientedDimensionSum.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/OrientedDimensionSum.java new file mode 100644 index 00000000000..cfca707f309 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/OrientedDimensionSum.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.roots.ui.componentsList.layout; + +import java.awt.*; + +public class OrientedDimensionSum { + private final Orientation myOrientation; + private final Dimension mySum = new Dimension(); + + public OrientedDimensionSum(Orientation orientation) { + myOrientation = orientation; + } + + public void add(Dimension size) { + myOrientation.expandInline(mySum, size); + } + + public void addInsets(Insets insets) { + mySum.width += insets.left + insets.right; + mySum.height += insets.top + insets.bottom; + } + + public Dimension getSum() { return mySum; } + + public void grow(int length) { + myOrientation.extend(mySum, length); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/SizeProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/SizeProperty.java new file mode 100644 index 00000000000..78c392f1e05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/SizeProperty.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.roots.ui.componentsList.layout; + + +import java.awt.*; + +public interface SizeProperty { + Dimension getSize(Component component); + + SizeProperty PREFERED_SIZE = new SizeProperty() { + public Dimension getSize(Component component) { + return component.getPreferredSize(); + } + }; + + SizeProperty MINIMUM_SIZE = new SizeProperty() { + public Dimension getSize(Component component) { + return component.getMinimumSize(); + } + }; + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/VerticalStackLayout.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/VerticalStackLayout.java new file mode 100644 index 00000000000..3fb1ef4f5e6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/componentsList/layout/VerticalStackLayout.java @@ -0,0 +1,65 @@ +package com.intellij.openapi.roots.ui.componentsList.layout; + + +import java.awt.*; + +public class VerticalStackLayout implements LayoutManager2 { + private int myDefaultHeight = 200; + + /** + * Calculates the minimum size dimensions for the specified + * container, given the components it contains. + * @param parent the component to be laid out + * @see #preferredLayoutSize + */ + public Dimension minimumLayoutSize(Container parent) { + ComponentOperation.SizeCalculator calculator = new ComponentOperation.SizeCalculator(SizeProperty.MINIMUM_SIZE); + withAllVisibleDo(parent, calculator); + OrientedDimensionSum result = calculator.getSum(); + result.addInsets(parent.getInsets()); + return result.getSum(); + } + + public static void withAllVisibleDo(Container container, ComponentOperation operation) { + Component[] components = container.getComponents(); + for (int i = 0; i < components.length; i++) { + Component component = components[i]; + if (!component.isVisible()) continue; + operation.applyTo(component); + } + } + + /** + * Lays out the specified container. + * @param parent the container to be laid out + */ + public void layoutContainer(final Container parent) { + withAllVisibleDo(parent, + new ComponentOperation.InlineLayout(parent, myDefaultHeight, SizeProperty.PREFERED_SIZE, + Orientation.VERTICAL)); + } + + /** + * Calculates the preferred size dimensions for the specified + * container, given the components it contains. + * @param parent the container to be laid out + * + * @see #minimumLayoutSize + */ + public Dimension preferredLayoutSize(Container parent) { + ComponentOperation.SizeCalculator calculator = + new ComponentOperation.SizeCalculator(myDefaultHeight, SizeProperty.PREFERED_SIZE, Orientation.VERTICAL); + withAllVisibleDo(parent, calculator); + OrientedDimensionSum result = calculator.getSum(); + result.addInsets(parent.getInsets()); + return result.getSum(); + } + + public void removeLayoutComponent(Component comp) {} + public Dimension maximumLayoutSize(Container target) { return null; } + public float getLayoutAlignmentY(Container target) { return 0; } + public void addLayoutComponent(Component comp, Object constraints) {} + public void invalidateLayout(Container target) {} + public void addLayoutComponent(String name, Component comp) {} + public float getLayoutAlignmentX(Container target) { return 0; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ActionsHeaderComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ActionsHeaderComponent.java new file mode 100644 index 00000000000..30e4ae6d14d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ActionsHeaderComponent.java @@ -0,0 +1,55 @@ +package com.intellij.openapi.roots.ui.configuration; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 31 + * @author 2003 + */ +public class ActionsHeaderComponent extends JPanel/*ScalableIconComponent*/ { + private static final int HEADER_Y_OFFSET = 4; + private JLabel myHeaderLabel; + + public void addNotify() { + super.addNotify(); + final Dimension preferredSize = new Dimension(0, 0); + calcPreferredSize(this, preferredSize); + preferredSize.height += HEADER_Y_OFFSET; + this.setPreferredSize(preferredSize); + } + + public void setHeaderTextColor(Color color) { + myHeaderLabel.setForeground(color); + } + + private void calcPreferredSize(Container container, Dimension dimension) { + final Component[] components = container.getComponents(); + int maxWidth = 0; + int maxHeight = 0; + for (int idx = 0; idx < components.length; idx++) { + Component component = components[idx]; + if (component instanceof Container) { + calcPreferredSize((Container)component, dimension); + maxWidth = Math.max(maxWidth, dimension.width); + maxHeight = Math.max(maxHeight, dimension.height); + } + else { + final Dimension preferredSize = component.getPreferredSize(); + maxWidth = Math.max(maxWidth, preferredSize.width); + maxHeight = Math.max(maxHeight, preferredSize.height); + } + } + final Dimension preferredSize = container.getPreferredSize(); + dimension.width = Math.max(maxWidth, preferredSize.width); + dimension.height = Math.max(maxHeight, preferredSize.height); + } + + public final void setSelected(boolean isSelected) { + setBackground(isSelected? UIManager.getColor("Table.selectionBackground") : UIManager.getColor("Table.textBackground")); + myHeaderLabel.setForeground(isSelected? UIManager.getColor("Table.selectionForeground") : UIManager.getColor("Table.textForeground")); + this.revalidate(); + this.repaint(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java new file mode 100644 index 00000000000..39e59985666 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java @@ -0,0 +1,616 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.Patches; +import com.intellij.ide.util.BrowseFilesListener; +import com.intellij.ide.util.JavaUtil; +import com.intellij.ide.util.projectWizard.ToolbarPanel; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.progress.util.SmoothProgressAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel; +import com.intellij.openapi.roots.ui.componentsList.layout.VerticalStackLayout; +import com.intellij.openapi.roots.ui.configuration.actions.ModulesConfigurationAction; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.ui.FieldPanel; +import com.intellij.ui.InsertPathAction; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.concurrency.SwingWorker; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.awt.event.*; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author Eugene Zhuravlev + * Date: Oct 4, 2003 + * Time: 6:54:57 PM + */ +public class ContentEntriesEditor extends ModuleElementsEditor { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.ContentEntriesEditor"); + public static final String NAME = "Paths"; + public static final Icon ICON = IconLoader.getIcon("/modules/paths.png"); + private static final Color BACKGROUND_COLOR = UIManager.getColor("List.background"); + private static final Icon ADD_CONTENT_ENTRY_ICON = IconLoader.getIcon("/modules/addContentEntry.png"); + + private ContentEntryTreeEditor myRootTreeEditor; + private MyContentEntryEditorListener myContentEntryEditorListener; + private JPanel myEditorsPanel; + private final Map myEntryToEditorMap = new HashMap(); + private ContentEntry mySelectedEntry; + private FieldPanel myOutputPathPanel; + private FieldPanel myTestsOutputPathPanel; + private VirtualFile myLastSelectedDir = null; + private JRadioButton myRbRelativePaths; + private JCheckBox myCbExcludeOutput; + private VirtualFileManagerAdapter myVFMListener; + private final String myModuleName; + private final ModulesProvider myModulesProvider; + + public ContentEntriesEditor(Project project, String moduleName, ModifiableRootModel model, ModulesProvider modulesProvider) { + super(project, model); + myModuleName = moduleName; + myModulesProvider = modulesProvider; + myVFMListener = new VirtualFileManagerAdapter() { + public void afterRefreshFinish(boolean asynchonous) { + for (Iterator it = myEntryToEditorMap.keySet().iterator(); it.hasNext();) { + final ContentEntryEditor editor = myEntryToEditorMap.get(it.next()); + if (editor != null) { + editor.update(); + } + } + } + }; + ((VirtualFileManagerEx)VirtualFileManager.getInstance()).addVirtualFileManagerListener(myVFMListener); + } + + public String getHelpTopic() { + return "project.paths.paths"; + } + + public String getDisplayName() { + return NAME; + } + + public Icon getIcon() { + return ICON; + } + + public void disposeUIResources() { + ((VirtualFileManagerEx)VirtualFileManager.getInstance()).removeVirtualFileManagerListener(myVFMListener); + if (myRootTreeEditor != null) { + myRootTreeEditor.setContentEntryEditor(null); + } + super.disposeUIResources(); + } + + public boolean isModified() { + if (super.isModified()) { + return true; + } + final Module selfModule = getMyModule(); + return selfModule == null || myRbRelativePaths == null ? false : selfModule.isSavePathsRelative() != myRbRelativePaths.isSelected(); + } + + public JPanel createComponentImpl() { + final Project project = getMyModule().getProject(); + + myContentEntryEditorListener = new MyContentEntryEditorListener(); + + final JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); + + JComponent outputPathsBlock = createOutputPathsBlock(); + outputPathsBlock.setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0)); + mainPanel.add(outputPathsBlock, BorderLayout.NORTH); + + final JPanel entriesPanel = new JPanel(new BorderLayout()); + + final DefaultActionGroup group = new DefaultActionGroup(); + group.add(new AddContentEntryAction()); + + myEditorsPanel = new ScrollablePanel(new VerticalStackLayout()); + myEditorsPanel.setBackground(BACKGROUND_COLOR); + JScrollPane myScrollPane = ScrollPaneFactory.createScrollPane(myEditorsPanel); + entriesPanel.add(new ToolbarPanel(myScrollPane, group), BorderLayout.CENTER); + + final Splitter splitter = new Splitter(false); + splitter.setHonorComponentsMinimumSize(true); + mainPanel.add(splitter, BorderLayout.CENTER); + + final JPanel editorsPanel = new JPanel(new GridBagLayout()); + splitter.setFirstComponent(editorsPanel); + editorsPanel.add(entriesPanel, + new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + myRootTreeEditor = new ContentEntryTreeEditor(project); + final JComponent treeEditorComponent = myRootTreeEditor.createComponent(); + splitter.setSecondComponent(treeEditorComponent); + + final JPanel rbPanel = new JPanel(new GridBagLayout()); + rbPanel.setBorder(BorderFactory.createEmptyBorder(6, 0, 0, 6)); + myRbRelativePaths = new JRadioButton("Use relative path"); + final JRadioButton rbAbsolutePaths = new JRadioButton("Use absolute path"); + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbRelativePaths); + buttonGroup.add(rbAbsolutePaths); + rbPanel.add(new JLabel("For files outside module file directory:"), + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), + 0, 0)); + rbPanel.add(rbAbsolutePaths, + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), + 0, 0)); + rbPanel.add(myRbRelativePaths, + new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), + 0, 0)); + if (getMyModule().isSavePathsRelative()) { + myRbRelativePaths.setSelected(true); + } + else { + rbAbsolutePaths.setSelected(true); + } + mainPanel.add(rbPanel, BorderLayout.SOUTH); + + final ContentEntry[] contentEntries = myModel.getContentEntries(); + if (contentEntries.length > 0) { + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + addContentEntryPanel(contentEntry); + } + selectContentEntry(contentEntries[0]); + } + + return mainPanel; + } + + private Module getMyModule() { + return myModulesProvider.getModule(myModuleName); + } + + private JComponent createOutputPathsBlock() { + myOutputPathPanel = createOutputPathPanel("Select Output Path", new CommitPathRunnable() { + public void saveUrl(String url) { + myModel.setCompilerOutputPath(url); + } + }); + myTestsOutputPathPanel = createOutputPathPanel("Select Test Output Path", new CommitPathRunnable() { + public void saveUrl(String url) { + myModel.setCompilerOutputPathForTests(url); + } + }); + + myCbExcludeOutput = new JCheckBox("Exclude output paths", myModel.isExcludeOutput()); + myCbExcludeOutput.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + myModel.setExcludeOutput(e.getStateChange() == ItemEvent.SELECTED); + if (myRootTreeEditor != null) { + myRootTreeEditor.update(); + } + } + }); + + final JPanel outputPathsPanel = new JPanel(new GridBagLayout()); + + outputPathsPanel.add(new JLabel("Output path:"), + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, + new Insets(6, 0, 0, 6), 0, 0)); + outputPathsPanel.add(myOutputPathPanel, + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(6, 0, 0, 0), 0, 0)); + + outputPathsPanel.add(new JLabel("Test output path:"), + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, + new Insets(6, 0, 0, 6), 0, 0)); + outputPathsPanel.add(myTestsOutputPathPanel, + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(6, 0, 0, 0), 0, 0)); + + outputPathsPanel.add(myCbExcludeOutput, + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, + new Insets(6, 0, 0, 6), 0, 0)); + + // fill with data + final VirtualFile compilerOutputPath = myModel.getCompilerOutputPath(); + if (compilerOutputPath != null) { + myOutputPathPanel.setText(compilerOutputPath.getPath().replace('/', File.separatorChar)); + } + else { + final String compilerOutputUrl = myModel.getCompilerOutputPathUrl(); + if (compilerOutputUrl != null) { + myOutputPathPanel.setText(VirtualFileManager.extractPath(compilerOutputUrl).replace('/', File.separatorChar)); + } + } + + final VirtualFile testsOutputPath = myModel.getCompilerOutputPathForTests(); + if (testsOutputPath != null) { + myTestsOutputPathPanel.setText(testsOutputPath.getPath().replace('/', File.separatorChar)); + } + else { + final String testsOutputUrl = myModel.getCompilerOutputPathForTestsUrl(); + if (testsOutputUrl != null) { + myTestsOutputPathPanel.setText(VirtualFileManager.extractPath(testsOutputUrl).replace('/', File.separatorChar)); + } + } + + return outputPathsPanel; + } + + private static interface CommitPathRunnable { + void saveUrl(String url); + } + + private FieldPanel createOutputPathPanel(final String title, final CommitPathRunnable commitPathRunnable) { + final JTextField textField = new JTextField(); + final FileChooserDescriptor outputPathsChooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); + outputPathsChooserDescriptor.setHideIgnored(false); + InsertPathAction.addTo(textField, outputPathsChooserDescriptor); + + final Runnable commitRunnable = new Runnable() { + public void run() { + if (!myModel.isWritable()) { + return; + } + final String path = textField.getText().trim(); + if (path.length() == 0) { + commitPathRunnable.saveUrl(null); + } + else { + // should set only absolute paths + String canonicalPath; + try { + canonicalPath = new File(path).getCanonicalPath(); + } + catch (IOException e) { + canonicalPath = path; + } + commitPathRunnable.saveUrl(VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, canonicalPath.replace(File.separatorChar, '/'))); + } + if (myRootTreeEditor != null) { + myRootTreeEditor.update(); // need this in order to update appearance of excluded output paths if they are under content root + } + } + }; + + textField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + commitRunnable.run(); + } + }); + + final FieldPanel fieldPanel = new FieldPanel(textField, null, null, new BrowseFilesListener(textField, title, "", outputPathsChooserDescriptor) { + public void actionPerformed(ActionEvent e) { + super.actionPerformed(e); + commitRunnable.run(); + } + }, null); + + return fieldPanel; + } + + private void addContentEntryPanel(final ContentEntry contentEntry) { + final ContentEntryEditor contentEntryEditor = new ContentEntryEditor(contentEntry, myModel); + contentEntryEditor.addContentEntryEditorListener(myContentEntryEditorListener); + myEntryToEditorMap.put(contentEntry, contentEntryEditor); + Border border = BorderFactory.createEmptyBorder(2, 2, 0, 2); + final JComponent component = contentEntryEditor.getComponent(); + final Border componentBorder = component.getBorder(); + if (componentBorder != null) { + border = BorderFactory.createCompoundBorder(border, componentBorder); + } + component.setBorder(border); + myEditorsPanel.add(component); + } + + private void selectContentEntry(ContentEntry contentEntry) { + if (mySelectedEntry != null && mySelectedEntry.equals(contentEntry)) { + return; + } + try { + if (mySelectedEntry != null) { + ContentEntryEditor editor = myEntryToEditorMap.get(mySelectedEntry); + if (editor != null) { + editor.setSelected(false); + } + } + + if (contentEntry != null) { + ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); + if (editor != null) { + editor.setSelected(true); + final JComponent component = editor.getComponent(); + final JComponent scroller = (JComponent)component.getParent(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + scroller.scrollRectToVisible(component.getBounds()); + } + }); + myRootTreeEditor.setContentEntryEditor(editor); + myRootTreeEditor.requestFocus(); + } + } + } + finally { + mySelectedEntry = contentEntry; + } + } + + private ContentEntry getNextContentEntry(ContentEntry contentEntry) { + return getAdjacentContentEntry(contentEntry, 1); + } + + /* + private ContentEntry getPreviousContentEntry(ContentEntry contentEntry) { + return getAdjacentContentEntry(contentEntry, -1); + } + */ + + private ContentEntry getAdjacentContentEntry(ContentEntry contentEntry, int delta) { + final ContentEntry[] contentEntries = myModel.getContentEntries(); + for (int idx = 0; idx < contentEntries.length; idx++) { + ContentEntry entry = contentEntries[idx]; + if (contentEntry.equals(entry)) { + int nextEntryIndex = (idx + delta) % contentEntries.length; + if (nextEntryIndex < 0) { + nextEntryIndex += contentEntries.length; + } + return nextEntryIndex == idx ? null : contentEntries[nextEntryIndex]; + } + } + return null; + } + + private void addContentEntries(final VirtualFile[] files) { + java.util.List contentEntries = new ArrayList(); + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = files[idx]; + if (isAlreadyAdded(file)) { + continue; + } + final ContentEntry contentEntry = myModel.addContentEntry(file); + contentEntries.add(contentEntry); + } + + if (contentEntries.size() > 0) { + final ContentEntry[] contentEntriesArray = contentEntries.toArray(new ContentEntry[contentEntries.size()]); + addSourceRoots(myProject, contentEntriesArray, new Runnable() { + public void run() { + for (int idx = 0; idx < contentEntriesArray.length; idx++) { + addContentEntryPanel(contentEntriesArray[idx]); + } + myEditorsPanel.revalidate(); + myEditorsPanel.repaint(); + selectContentEntry(contentEntriesArray[contentEntriesArray.length - 1]); + } + }); + } + } + + private boolean isAlreadyAdded(VirtualFile file) { + final VirtualFile[] contentRoots = myModel.getContentRoots(); + for (int idx = 0; idx < contentRoots.length; idx++) { + VirtualFile contentRoot = contentRoots[idx]; + if (contentRoot.equals(file)) { + return true; + } + } + return false; + } + + public void saveData() { + getMyModule().setSavePathsRelative(myRbRelativePaths.isSelected()); + } + + private static void addSourceRoots(final Project project, final ContentEntry[] contentEntries, final Runnable finishRunnable) { + final HashMap>> entryToRootMap = new HashMap>>(); + final Map fileToEntryMap = new HashMap(); + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + entryToRootMap.put(contentEntry, null); + fileToEntryMap.put(VfsUtil.virtualToIoFile(contentEntry.getFile()), contentEntry); + } + + final ProgressWindow progressWindow = new ProgressWindow(true, project); + final ProgressIndicator progressIndicator = Patches.MAC_HIDE_QUIT_HACK + ? progressWindow + : (ProgressIndicator)new SmoothProgressAdapter(progressWindow, project); + + final Runnable searchRunnable = new Runnable() { + public void run() { + final Runnable process = new Runnable() { + public void run() { + for (Iterator it = fileToEntryMap.keySet().iterator(); it.hasNext();) { + final File entryFile = (File)it.next(); + progressIndicator.setText("Searching for source roots in " + entryFile.getPath()); + final java.util.List> roots = JavaUtil.suggestRoots(entryFile); + entryToRootMap.put(fileToEntryMap.get(entryFile), roots); + } + } + }; + progressWindow.setTitle("Adding Source Roots"); + ProgressManager.getInstance().runProcess(process, progressIndicator); + } + }; + + final Runnable addSourcesRunnable = new Runnable() { + public void run() { + for (int idx = 0; idx < contentEntries.length; idx++) { + final ContentEntry contentEntry = contentEntries[idx]; + final java.util.List> suggestedRoots = entryToRootMap.get(contentEntry); + if (suggestedRoots != null) { + for (int j = 0; j < suggestedRoots.size(); j++) { + final Pair suggestedRoot = suggestedRoots.get(j); + final VirtualFile sourceRoot = LocalFileSystem.getInstance().findFileByIoFile(suggestedRoot.first); + if (sourceRoot != null && VfsUtil.isAncestor(contentEntry.getFile(), sourceRoot, false)) { + contentEntry.addSourceFolder(sourceRoot, false, suggestedRoot.getSecond()); + } + } + } + } + if (finishRunnable != null) { + finishRunnable.run(); + } + } + }; + + new SwingWorker() { + public Object construct() { + searchRunnable.run(); + return null; + } + + public void finished() { + addSourcesRunnable.run(); + } + }.start(); + } + + private final class MyContentEntryEditorListener extends ContentEntryEditorListenerAdapter { + public void editingStarted(ContentEntryEditor editor) { + selectContentEntry(editor.getContentEntry()); + } + + public void beforeEntryDeleted(ContentEntryEditor editor) { + final ContentEntry entry = editor.getContentEntry(); + if (mySelectedEntry != null && mySelectedEntry.equals(entry)) { + myRootTreeEditor.setContentEntryEditor(null); + } + final ContentEntry nextContentEntry = getNextContentEntry(entry); + removeContentEntryPanel(entry); + selectContentEntry(nextContentEntry); + editor.removeContentEntryEditorListener(this); + } + + public void folderIncluded(ContentEntryEditor editor, VirtualFile file) { + if (editor.isCompilerOutput(file)) { + myCbExcludeOutput.setSelected(false); + } + } + + public void folderExcluded(ContentEntryEditor editor, VirtualFile file) { + if (editor.isCompilerOutput(file)) { + myCbExcludeOutput.setSelected(true); + } + } + + public void navigationRequested(ContentEntryEditor editor, VirtualFile file) { + if (mySelectedEntry != null && mySelectedEntry.equals(editor.getContentEntry())) { + myRootTreeEditor.requestFocus(); + myRootTreeEditor.select(file); + } + else { + selectContentEntry(editor.getContentEntry()); + myRootTreeEditor.requestFocus(); + myRootTreeEditor.select(file); + } + } + + private void removeContentEntryPanel(final ContentEntry contentEntry) { + ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); + if (editor != null) { + myEditorsPanel.remove(editor.getComponent()); + myEntryToEditorMap.remove(contentEntry); + myEditorsPanel.revalidate(); + myEditorsPanel.repaint(); + } + } + } + + private class AddContentEntryAction extends ModulesConfigurationAction { + private final FileChooserDescriptor myDescriptor; + + public AddContentEntryAction() { + super("Add Content Root", "Add content root to the module", ADD_CONTENT_ENTRY_ICON); + myDescriptor = new FileChooserDescriptor(false, true, true, false, true, true) { + public void validateSelectedFiles(VirtualFile[] files) throws Exception { + validateContentEntriesCandidates(files); + } + }; + myDescriptor.setTitle("Select content root directory"); + myDescriptor.setDescription("Content root is a directory containing all files related to this module"); + } + + public void actionPerformed(AnActionEvent e) { + VirtualFile[] files = FileChooser.chooseFiles(myProject, myDescriptor, myLastSelectedDir); + if (files.length > 0) { + myLastSelectedDir = files[0]; + addContentEntries(files); + } + } + + private void validateContentEntriesCandidates(VirtualFile[] files) throws Exception { + for (int i = 0; i < files.length; i++) { + final VirtualFile file = files[i]; + // check for collisions with already existing entries + for (Iterator it = myEntryToEditorMap.keySet().iterator(); it.hasNext();) { + final ContentEntry contentEntry = it.next(); + final VirtualFile contentEntryFile = contentEntry.getFile(); + if (contentEntryFile == null) { + continue; // skip invalid entry + } + if (contentEntryFile.equals(file)) { + throw new Exception("Content root \"" + file.getPresentableUrl() + "\" already exists"); + } + if (VfsUtil.isAncestor(contentEntryFile, file, true)) { + // intersection not allowed + throw new Exception( + "Content root being added \"" + file.getPresentableUrl() + "\"\nis located below existing content root \"" + + contentEntryFile.getPresentableUrl() + + "\".\nContent entries should not intersect."); + } + if (VfsUtil.isAncestor(file, contentEntryFile, true)) { + // intersection not allowed + throw new Exception( + "Content root being added \"" + file.getPresentableUrl() + "\"\ndominates existing content root \"" + contentEntryFile.getPresentableUrl() + + "\".\nContent entries should not intersect."); + } + } + // check if the same root is configured for another module + final Module[] modules = myModulesProvider.getModules(); + for (int j = 0; j < modules.length; j++) { + final Module module = modules[j]; + if (myModuleName.equals(module.getName())) { + continue; + } + ModuleRootModel rootModel = myModulesProvider.getRootModel(module); + LOG.assertTrue(rootModel != null); + final VirtualFile[] moduleContentRoots = rootModel.getContentRoots(); + for (int k = 0; k < moduleContentRoots.length; k++) { + VirtualFile moduleContentRoot = moduleContentRoots[k]; + if (file.equals(moduleContentRoot)) { + throw new Exception( + "Content root \"" + file.getPresentableUrl() + "\" already defined for module \"" + module.getName() + + "\".\nTwo modules in a project cannot share the same content root."); + } + } + } + } + } + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java new file mode 100644 index 00000000000..7a1ece16406 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java @@ -0,0 +1,302 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.*; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.EventDispatcher; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.EventListener; + +/** + * @author Eugene Zhuravlev + * Date: Oct 8, 2003 + * Time: 3:48:13 PM + */ +public final class ContentEntryEditor implements ContentRootPanel.ActionCallback { + + private final ContentEntry myContentEntry; + private final ModifiableRootModel myRootModel; + private boolean myIsSelected; + private ContentRootPanel myContentRootPanel; + private JPanel myMainPanel; + private EventDispatcher myEventDispatcher; + + public static interface ContentEntryEditorListener extends EventListener{ + void editingStarted(ContentEntryEditor editor); + void beforeEntryDeleted(ContentEntryEditor editor); + void sourceFolderAdded(ContentEntryEditor editor, SourceFolder folder); + void sourceFolderRemoved(ContentEntryEditor editor, VirtualFile file, boolean isTestSource); + void folderExcluded(ContentEntryEditor editor, VirtualFile file); + void folderIncluded(ContentEntryEditor editor, VirtualFile file); + void navigationRequested(ContentEntryEditor editor, VirtualFile file); + void packagePrefixSet(ContentEntryEditor editor, SourceFolder folder); + } + + public ContentEntryEditor(ContentEntry contentEntry, ModifiableRootModel rootModel) { + myContentEntry = contentEntry; + myRootModel = rootModel; + myMainPanel = new JPanel(new BorderLayout()); + myMainPanel.setOpaque(false); + myMainPanel.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + myEventDispatcher.getMulticaster().editingStarted(ContentEntryEditor.this); + } + public void mouseEntered(MouseEvent e) { + if (!myIsSelected) { + highlight(true); + } + } + public void mouseExited(MouseEvent e) { + if (!myIsSelected) { + highlight(false); + } + } + }); + myEventDispatcher = EventDispatcher.create(ContentEntryEditorListener.class); + setSelected(false); + update(); + } + + + public void deleteContentEntry() { + final int answer = Messages.showYesNoDialog("Remove content root \"" + VirtualFileManager.extractPath(myContentEntry.getUrl()).replace('/', File.separatorChar) +"\"?", "Remove Content Root", Messages.getQuestionIcon()); + if (answer != 0) { // no + return; + } + myEventDispatcher.getMulticaster().beforeEntryDeleted(this); + myRootModel.removeContentEntry(myContentEntry); + } + + public void deleteContentFolder(ContentEntry contentEntry, ContentFolder folder) { + if (folder instanceof SourceFolder) { + removeSourceFolder((SourceFolder)folder); + update(); + } + else if (folder instanceof ExcludeFolder) { + removeExcludeFolder((ExcludeFolder)folder); + update(); + } + + } + + public void navigateFolder(ContentEntry contentEntry, ContentFolder contentFolder) { + final VirtualFile file = contentFolder.getFile(); + if (file != null) { // file can be deleted externally + myEventDispatcher.getMulticaster().navigationRequested(this, file); + } + } + + public void setPackagePrefix(SourceFolder folder, String prefix) { + folder.setPackagePrefix(prefix); + update(); + myEventDispatcher.getMulticaster().packagePrefixSet(this, folder); + } + + void addContentEntryEditorListener(ContentEntryEditorListener listener) { + myEventDispatcher.addListener(listener); + } + + void removeContentEntryEditorListener(ContentEntryEditorListener listener) { + myEventDispatcher.removeListener(listener); + } + + public void setSelected(boolean isSelected) { + if (myIsSelected != isSelected) { + highlight(isSelected); + myIsSelected = isSelected; + } + } + + private void highlight(boolean selected) { + if (myContentRootPanel != null) { + myContentRootPanel.setSelected(selected); + } + } + + public JComponent getComponent() { + return myMainPanel; + } + + public ContentEntry getContentEntry() { + return myContentEntry; + } + + public void update() { + if (myContentRootPanel != null) { + myMainPanel.remove(myContentRootPanel); + } + myContentRootPanel = new ContentRootPanel(myContentEntry, this); + myContentRootPanel.setSelected(myIsSelected); + myMainPanel.add(myContentRootPanel, BorderLayout.CENTER); + myMainPanel.revalidate(); + } + + + public SourceFolder addSourceFolder(VirtualFile file, boolean isTestSource) { + final SourceFolder sourceFolder = myContentEntry.addSourceFolder(file, isTestSource); + try { + return sourceFolder; + } + finally { + myEventDispatcher.getMulticaster().sourceFolderAdded(this, sourceFolder); + update(); + } + } + + public void removeSourceFolder(SourceFolder sourceFolder) { + final VirtualFile file = sourceFolder.getFile(); + final boolean isTestSource = sourceFolder.isTestSource(); + try { + myContentEntry.removeSourceFolder(sourceFolder); + } + finally { + myEventDispatcher.getMulticaster().sourceFolderRemoved(this, file, isTestSource); + update(); + } + } + + public ExcludeFolder addExcludeFolder(VirtualFile file) { + try { + final boolean isCompilerOutput = isCompilerOutput(file); + boolean isExplodedDirectory = isExplodedDirectory(file); + if (isCompilerOutput || isExplodedDirectory) { + if (isCompilerOutput) { + myRootModel.setExcludeOutput(true); + } + if (isExplodedDirectory) { + myRootModel.setExcludeExplodedDirectory(true); + } + return null; + } + else { + final ExcludeFolder excludeFolder = myContentEntry.addExcludeFolder(file); + return excludeFolder; + } + } + finally { + myEventDispatcher.getMulticaster().folderExcluded(this, file); + update(); + } + } + + public void removeExcludeFolder(ExcludeFolder excludeFolder) { + final VirtualFile file = excludeFolder.getFile(); + try { + if (isCompilerOutput(file)) { + myRootModel.setExcludeOutput(false); + } + if (isExplodedDirectory(file)) { + myRootModel.setExcludeExplodedDirectory(false); + } + if (!excludeFolder.isSynthetic()) { + myContentEntry.removeExcludeFolder(excludeFolder); + } + } + finally { + myEventDispatcher.getMulticaster().folderIncluded(this, file); + update(); + } + } + + public boolean isCompilerOutput(VirtualFile file) { + final VirtualFile compilerOutputPath = myRootModel.getCompilerOutputPath(); + if (compilerOutputPath != null) { + if (compilerOutputPath.equals(file)) { + return true; + } + } + + final VirtualFile compilerOutputPathForTests = myRootModel.getCompilerOutputPathForTests(); + if (compilerOutputPathForTests != null) { + if (compilerOutputPathForTests.equals(file)) { + return true; + } + } + + return false; + } + + public boolean isExplodedDirectory(VirtualFile file) { + final VirtualFile explodedDir = myRootModel.getExplodedDirectory(); + if (explodedDir != null) { + if (explodedDir.equals(file)) { + return true; + } + } + return false; + } + + public boolean isSource(VirtualFile file) { + final SourceFolder sourceFolder = getSourceFolder(file); + return sourceFolder != null && !sourceFolder.isTestSource(); + } + + public boolean isTestSource(VirtualFile file) { + final SourceFolder sourceFolder = getSourceFolder(file); + return sourceFolder != null && sourceFolder.isTestSource(); + } + + public boolean isExcluded(VirtualFile file) { + return getExcludeFolder(file) != null; + } + + public boolean isUnderExcludedDirectory(final VirtualFile file) { + if (myContentEntry == null) { + return false; + } + final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + final VirtualFile excludedDir = excludeFolders[idx].getFile(); + if (excludedDir == null) { + continue; + } + if (VfsUtil.isAncestor(excludedDir, file, true)) { + return true; + } + } + return false; + } + + public ExcludeFolder getExcludeFolder(VirtualFile file) { + if (myContentEntry == null) { + return null; + } + final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + final ExcludeFolder excludeFolder = excludeFolders[idx]; + final VirtualFile f = excludeFolder.getFile(); + if (f == null) { + continue; + } + if (f.equals(file)) { + return excludeFolder; + } + } + return null; + } + + public SourceFolder getSourceFolder(VirtualFile file) { + if (myContentEntry == null) { + return null; + } + final SourceFolder[] sourceFolders = myContentEntry.getSourceFolders(); + for (int idx = 0; idx < sourceFolders.length; idx++) { + SourceFolder sourceFolder = sourceFolders[idx]; + final VirtualFile f = sourceFolder.getFile(); + if (f == null) { + continue; + } + if (f.equals(file)) { + return sourceFolder; + } + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java new file mode 100644 index 00000000000..361c413c3e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java @@ -0,0 +1,35 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Eugene Zhuravlev + * Date: Oct 14 + * @author 2003 + */ +public class ContentEntryEditorListenerAdapter implements ContentEntryEditor.ContentEntryEditorListener{ + public void editingStarted(ContentEntryEditor editor) { + } + + public void beforeEntryDeleted(ContentEntryEditor editor) { + } + + public void sourceFolderAdded(ContentEntryEditor editor, SourceFolder folder) { + } + + public void sourceFolderRemoved(ContentEntryEditor editor, VirtualFile file, boolean isTestSource) { + } + + public void folderExcluded(ContentEntryEditor editor, VirtualFile file) { + } + + public void folderIncluded(ContentEntryEditor editor, VirtualFile file) { + } + + public void navigationRequested(ContentEntryEditor editor, VirtualFile file) { + } + + public void packagePrefixSet(ContentEntryEditor editor, SourceFolder folder) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java new file mode 100644 index 00000000000..c0be4dfd02d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java @@ -0,0 +1,107 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; + +public class ContentEntryTreeCellRenderer extends NodeRenderer { + private final ContentEntryTreeEditor myTreeEditor; + + public ContentEntryTreeCellRenderer(ContentEntryTreeEditor treeEditor) { + myTreeEditor = treeEditor; + } + + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus); + final ContentEntryEditor contentEntryEditor = myTreeEditor.getContentEntryEditor(); + if (contentEntryEditor == null) { + return; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + if (!(node.getUserObject() instanceof NodeDescriptor)) { + return; + } + NodeDescriptor descriptor = (NodeDescriptor)node.getUserObject(); + final Object element = descriptor.getElement(); + if (element instanceof FileElement) { + final VirtualFile file = ((FileElement)element).getFile(); + if (file != null && file.isDirectory()) { + final ContentEntry contentEntry = contentEntryEditor.getContentEntry(); + final String prefix = getPrefix(contentEntry, file); + if (prefix.length() > 0) { + append(" (" + prefix + ")", new SimpleTextAttributes(Font.PLAIN, Color.GRAY)); + } + final Icon updatedIcon = updateIcon(contentEntry, file, getIcon(), expanded); + setIcon(updatedIcon); + } + } + } + + private String getPrefix(final ContentEntry entry, final VirtualFile file) { + final SourceFolder[] sourceFolders = entry.getSourceFolders(); + final String url = file.getUrl(); + for (int idx = 0; idx < sourceFolders.length; idx++) { + final SourceFolder sourceFolder = sourceFolders[idx]; + if (url.equals(sourceFolder.getUrl())) { + return sourceFolder.getPackagePrefix(); + } + } + return ""; + } + + private Icon updateIcon(final ContentEntry entry, final VirtualFile file, Icon originalIcon, final boolean expanded) { + final ExcludeFolder[] excludeFolders = entry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + ExcludeFolder excludeFolder = excludeFolders[idx]; + final VirtualFile f = excludeFolder.getFile(); + if (f == null) { + continue; + } + + if (VfsUtil.isAncestor(f, file, false)) { + return IconSet.getExcludeIcon(expanded); + } + } + + final SourceFolder[] sourceFolders = entry.getSourceFolders(); + for (int idx = 0; idx < sourceFolders.length; idx++) { + SourceFolder sourceFolder = sourceFolders[idx]; + final VirtualFile f = sourceFolder.getFile(); + if (f == null) { + continue; + } + if (f.equals(file)) { + return IconSet.getSourceRootIcon(sourceFolder.isTestSource(), expanded); + } + } + + VirtualFile currentRoot = null; + for (int idx = 0; idx < sourceFolders.length; idx++) { + SourceFolder sourceFolder = sourceFolders[idx]; + final VirtualFile f = sourceFolder.getFile(); + if (f == null) { + continue; + } + if (VfsUtil.isAncestor(f, file, true)) { + if (currentRoot != null && VfsUtil.isAncestor(f, currentRoot, false)) { + continue; + } + originalIcon = IconSet.getSourceFolderIcon(sourceFolder.isTestSource(), expanded); + currentRoot = f; + } + } + + return originalIcon; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java new file mode 100644 index 00000000000..1d62c0528c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java @@ -0,0 +1,222 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.util.projectWizard.ToolbarPanel; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl; +import com.intellij.openapi.fileChooser.impl.FileTreeBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.roots.ui.configuration.actions.ModulesConfigurationAction; +import com.intellij.openapi.roots.ui.configuration.actions.ToggleExcludedStateAction; +import com.intellij.openapi.roots.ui.configuration.actions.ToggleSourcesStateAction; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.io.File; +import java.util.Comparator; + +/** + * @author Eugene Zhuravlev + * Date: Oct 9, 2003 + * Time: 1:19:47 PM + */ +public class ContentEntryTreeEditor { + private final Project myProject; + protected Tree myTree; + private FileSystemTreeImpl myFileSystemTree; + private JPanel myTreePanel; + private final DefaultMutableTreeNode EMPTY_TREE_ROOT = new DefaultMutableTreeNode(""); + protected DefaultActionGroup myEditingActionsGroup; + private ContentEntryEditor myContentEntryEditor; + private final MyContentEntryEditorListener myContentEntryEditorListener = new MyContentEntryEditorListener(); + private final FileChooserDescriptor myDescriptor; + private final ToggleExcludedStateAction myToggleExcludedAction; + private final ToggleSourcesStateAction myMarkSourcesAction; + private final ToggleSourcesStateAction myMarkTestsAction; + + public ContentEntryTreeEditor(Project project) { + myProject = project; + myTree = new Tree(); + myTree.setRootVisible(true); + myTree.setShowsRootHandles(true); + + myEditingActionsGroup = new DefaultActionGroup(); + + myMarkSourcesAction = new ToggleSourcesStateAction(myTree, this, false); + myMarkSourcesAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.ALT_MASK)), myTree); + + myToggleExcludedAction = new ToggleExcludedStateAction(myTree, this); + myToggleExcludedAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.ALT_MASK)), myTree); + + myMarkTestsAction = new ToggleSourcesStateAction(myTree, this, true); + myMarkTestsAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.ALT_MASK)), myTree); + + TreeToolTipHandler.install(myTree); + TreeUtil.installActions(myTree); + new TreeSpeedSearch(myTree); + + myTreePanel = new JPanel(new BorderLayout()); + final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree); + scrollPane.setPreferredSize(new Dimension(300, 300)); + myTreePanel.add(new ToolbarPanel(scrollPane, myEditingActionsGroup), BorderLayout.CENTER); + + myTreePanel.setVisible(false); + myDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); + myDescriptor.setShowFileSystemRoots(false); + } + + protected void createEditingActions() { + myEditingActionsGroup.add(myToggleExcludedAction); + myEditingActionsGroup.add(myMarkSourcesAction); + myEditingActionsGroup.add(myMarkTestsAction); + } + + protected TreeCellRenderer getContentEntryCellRenderer() { + return new ContentEntryTreeCellRenderer(this); + } + + /** + * @param contentEntryEditor : null means to clear the editor + */ + public void setContentEntryEditor(ContentEntryEditor contentEntryEditor) { + if (myContentEntryEditor != null && myContentEntryEditor.equals(contentEntryEditor)) { + return; + } + if (myFileSystemTree != null) { + myFileSystemTree.dispose(); + myFileSystemTree = null; + } + if (myContentEntryEditor != null) { + myContentEntryEditor.removeContentEntryEditorListener(myContentEntryEditorListener); + myContentEntryEditor = null; + } + if (contentEntryEditor == null) { + ((DefaultTreeModel)myTree.getModel()).setRoot(EMPTY_TREE_ROOT); + myTreePanel.setVisible(false); + return; + } + myTreePanel.setVisible(true); + myContentEntryEditor = contentEntryEditor; + myContentEntryEditor.addContentEntryEditorListener(myContentEntryEditorListener); + final VirtualFile file = contentEntryEditor.getContentEntry().getFile(); + myDescriptor.setRoot(file); + if (file != null) { + myDescriptor.setTitle(file.getPresentableUrl()); + } + else { + final String url = contentEntryEditor.getContentEntry().getUrl(); + myDescriptor.setTitle(VirtualFileManager.extractPath(url).replace('/', File.separatorChar)); + } + myFileSystemTree = new FileSystemTreeImpl(myProject, myDescriptor, myTree) { + protected AbstractTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, AbstractTreeStructure treeStructure, Comparator comparator, FileChooserDescriptor descriptor) { + return new MyFileTreeBuilder(tree, treeModel, treeStructure, comparator, descriptor); + } + }; + final com.intellij.openapi.fileChooser.actions.NewFolderAction newFolderAction = new NewFolderAction(myFileSystemTree); + DefaultActionGroup mousePopupGroup = new DefaultActionGroup(); + mousePopupGroup.add(myEditingActionsGroup); + mousePopupGroup.addSeparator(); + mousePopupGroup.add(newFolderAction); + myFileSystemTree.registerMouseListener(mousePopupGroup); + + myFileSystemTree.updateTree(); + if (file != null) { + select(file); + } + } + + public ContentEntryEditor getContentEntryEditor() { + return myContentEntryEditor; + } + + public JComponent createComponent() { + myTree.setCellRenderer(getContentEntryCellRenderer()); + createEditingActions(); + return myTreePanel; + } + + public void select(VirtualFile file) { + if (myFileSystemTree != null) { + myFileSystemTree.select(file); + } + } + + public void requestFocus() { + myTree.requestFocus(); + } + + public void update() { + if (myFileSystemTree != null) { + myFileSystemTree.updateTree(); + final DefaultTreeModel model = (DefaultTreeModel)myTree.getModel(); + final int visibleRowCount = myTree.getVisibleRowCount(); + for (int row = 0; row < visibleRowCount; row++) { + final TreePath pathForRow = myTree.getPathForRow(row); + if (pathForRow != null) { + final TreeNode node = (TreeNode)pathForRow.getLastPathComponent(); + if (node != null) { + model.nodeChanged(node); + } + } + } + } + } + + private class MyContentEntryEditorListener extends ContentEntryEditorListenerAdapter { + public void sourceFolderAdded(ContentEntryEditor editor, SourceFolder folder) { + update(); + } + + public void sourceFolderRemoved(ContentEntryEditor editor, VirtualFile file, boolean isTestSource) { + update(); + } + + public void folderExcluded(ContentEntryEditor editor, VirtualFile file) { + update(); + } + + public void folderIncluded(ContentEntryEditor editor, VirtualFile file) { + update(); + } + + public void packagePrefixSet(ContentEntryEditor editor, SourceFolder folder) { + update(); + } + } + + private static class NewFolderAction extends com.intellij.openapi.fileChooser.actions.NewFolderAction implements CustomComponentAction { + public NewFolderAction(FileSystemTreeImpl fileSystemTree) { + super(fileSystemTree); + } + + public JComponent createCustomComponent(Presentation presentation) { + return ModulesConfigurationAction.createCustomComponentImpl(this, presentation); + } + } + + private static class MyFileTreeBuilder extends FileTreeBuilder { + public MyFileTreeBuilder(JTree tree, DefaultTreeModel treeModel, AbstractTreeStructure treeStructure, Comparator comparator, FileChooserDescriptor descriptor) { + super(tree, treeModel, treeStructure, comparator, descriptor); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return false; // need this in order to not show plus for empty directories + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java new file mode 100644 index 00000000000..7b224c81bb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java @@ -0,0 +1,370 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.ui.HoverHyperlinkLabel; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import java.awt.*; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author Eugene Zhuravlev + * Date: Jan 19, 2004 + */ +public class ContentRootPanel extends JPanel { + private static final Color SOURCES_COLOR = new Color(0x0A50A1); + private static final Color TESTS_COLOR = new Color(0x008C2E); + private static final Color EXCLUDED_COLOR = new Color(0x992E00); + private static final Color SELECTED_HEADER_COLOR = new Color(0xDEF2FF); + private static final Color HEADER_COLOR = new Color(0xF5F5F5); + private static final Color SELECTED_CONTENT_COLOR = new Color(0xF0F9FF); + private static final Color CONTENT_COLOR = Color.WHITE; + private static final Color UNSELECTED_TEXT_COLOR = new Color(0x333333); + + private static final Icon DELETE_ROOT_ICON = IconLoader.getIcon("/modules/deleteContentRoot.png"); + private static final Icon DELETE_ROOT_ROLLOVER_ICON = IconLoader.getIcon("/modules/deleteContentRootRollover.png"); + private static final Icon DELETE_FOLDER_ICON = IconLoader.getIcon("/modules/deleteContentFolder.png"); + private static final Icon DELETE_FOLDER_ROLLOVER_ICON = IconLoader.getIcon("/modules/deleteContentFolderRollover.png"); + private static final Icon ADD_PREFIX_ICON = IconLoader.getIcon("/modules/setPackagePrefix.png"); + private static final Icon ADD_PREFIX_ROLLOVER_ICON = IconLoader.getIcon("/modules/setPackagePrefixRollover.png"); + + private final ContentEntry myContentEntry; + private final ActionCallback myCallback; + private JComponent myHeader; + private JComponent myBottom; + private Map myComponentToForegroundMap = new HashMap(); + + public static interface ActionCallback { + void deleteContentEntry(); + void deleteContentFolder(ContentEntry contentEntry, ContentFolder contentFolder); + void navigateFolder(ContentEntry contentEntry, ContentFolder contentFolder); + void setPackagePrefix(SourceFolder folder, String prefix); + } + + public ContentRootPanel(ContentEntry contentEntry, ActionCallback callback) { + super(new GridBagLayout()); + myContentEntry = contentEntry; + myCallback = callback; + + myHeader = createHeader(); + this.add(myHeader, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 8, 0), 0, 0)); + + final java.util.List sources = new ArrayList(); + final java.util.List testSources = new ArrayList(); + final java.util.List excluded = new ArrayList(); + final SourceFolder[] sourceFolders = myContentEntry.getSourceFolders(); + for (int idx = 0; idx < sourceFolders.length; idx++) { + SourceFolder folder = sourceFolders[idx]; + if (folder.isSynthetic()) { + continue; + } + final VirtualFile folderFile = folder.getFile(); + if (folderFile != null && (isExcluded(folderFile) || isUnderExcludedDirectory(folderFile))) { + continue; + } + if (folder.isTestSource()) { + testSources.add(folder); + } + else { + sources.add(folder); + } + } + + final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + final ExcludeFolder excludeFolder = excludeFolders[idx]; + if (!excludeFolder.isSynthetic()) { + excluded.add(excludeFolder); + } + } + + if (sources.size() > 0) { + final JComponent sourcesComponent = createFolderGroupComponent("Source Folders", sources.toArray(new ContentFolder[sources.size()]), SOURCES_COLOR); + this.add(sourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0)); + } + if (testSources.size() > 0) { + final JComponent testSourcesComponent = createFolderGroupComponent("Test Source Folders", testSources.toArray(new ContentFolder[testSources.size()]), TESTS_COLOR); + this.add(testSourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0)); + } + if (excluded.size() > 0) { + final JComponent excludedComponent = createFolderGroupComponent("Excluded Folders", excluded.toArray(new ContentFolder[excluded.size()]), EXCLUDED_COLOR); + this.add(excludedComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0)); + } + + myBottom = new JPanel(new BorderLayout()); + myBottom.add(Box.createVerticalStrut(3), BorderLayout.NORTH); + this.add(myBottom, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + + setSelected(false); + } + + private JComponent createHeader() { + final JPanel panel = new JPanel(new GridBagLayout()); + final JLabel headerLabel = new JLabel(toDisplayPath(myContentEntry.getUrl())); + headerLabel.setFont(headerLabel.getFont().deriveFont(Font.BOLD)); + headerLabel.setOpaque(false); + if (myContentEntry.getFile() == null) { + headerLabel.setForeground(Color.RED); + } + final IconActionComponent deleteIconComponent = new IconActionComponent(DELETE_ROOT_ICON, DELETE_ROOT_ROLLOVER_ICON, "Remove Content Entry", new Runnable() { + public void run() { + myCallback.deleteContentEntry(); + } + }); + final ResizingWrapper wrapper = new ResizingWrapper(headerLabel); + panel.add(wrapper, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); + panel.add(deleteIconComponent, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 1.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 2), 0, 0)); + FilePathClipper.install(headerLabel, wrapper); + return panel; + } + + private JComponent createFolderGroupComponent(String title, ContentFolder[] folders, Color foregroundColor) { + final JPanel panel = new JPanel(new GridLayoutManager(folders.length, 3, new Insets(1, 17, 0, 2), 0, 1)); + panel.setOpaque(false); + + for (int idx = 0; idx < folders.length; idx++) { + final ContentFolder folder = folders[idx]; + final int verticalPolicy = idx == folders.length - 1? GridConstraints.SIZEPOLICY_CAN_GROW : GridConstraints.SIZEPOLICY_FIXED; + panel.add(createFolderComponent(folder, foregroundColor), new GridConstraints(idx, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, verticalPolicy, null, null, null)); + int column = 1; + int colspan = 2; + if (folder instanceof SourceFolder) { + panel.add(createAddPrefixComponent((SourceFolder)folder), new GridConstraints(idx, column++, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null)); + colspan = 1; + } + panel.add(createFolderDeleteComponent(folder), new GridConstraints(idx, column, 1, colspan, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null)); + } + + final JLabel titleLabel = new JLabel(title); + final Font labelFont = UIManager.getFont("Label.font"); + titleLabel.setFont(labelFont.deriveFont(Font.BOLD).deriveFont((float)labelFont.getSize() - 0.5f )); + titleLabel.setOpaque(false); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0)); + registerTextComponent(titleLabel, foregroundColor); + + final JPanel groupPanel = new JPanel(new BorderLayout()); + groupPanel.setOpaque(false); + groupPanel.add(titleLabel, BorderLayout.NORTH); + groupPanel.add(panel, BorderLayout.CENTER); + + return groupPanel; + } + + private void registerTextComponent(final JComponent component, final Color foreground) { + component.setForeground(foreground); + myComponentToForegroundMap.put(component, foreground); + } + + private JComponent createFolderComponent(final ContentFolder folder, Color foreground) { + final VirtualFile folderFile = folder.getFile(); + final VirtualFile contentEntryFile = myContentEntry.getFile(); + final String packagePrefix = folder instanceof SourceFolder? ((SourceFolder)folder).getPackagePrefix() : ""; + if (folderFile != null && contentEntryFile != null) { + String path = folderFile.equals(contentEntryFile)? "." :VfsUtil.getRelativePath(folderFile, contentEntryFile, File.separatorChar); + if (packagePrefix.length() > 0) { + path = path + " (" + packagePrefix + ")"; + } + HoverHyperlinkLabel hyperlinkLabel = new HoverHyperlinkLabel(path, foreground); + hyperlinkLabel.setMinimumSize(new Dimension(0, 0)); + hyperlinkLabel.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + myCallback.navigateFolder(myContentEntry, folder); + } + }); + registerTextComponent(hyperlinkLabel, foreground); + return new UnderlinedPathLabel(hyperlinkLabel); + } + else { + String path = toRelativeDisplayPath(folder.getUrl(), myContentEntry.getUrl()); + if (packagePrefix.length() > 0) { + path = path + " (" + packagePrefix + ")"; + } + final JLabel pathLabel = new JLabel(path); + pathLabel.setOpaque(false); + pathLabel.setForeground(Color.RED); + + return new UnderlinedPathLabel(pathLabel); + } + } + + private JComponent createFolderDeleteComponent(final ContentFolder folder) { + final String tooltipText; + if (folder.getFile() != null && myContentEntry.getFile() != null) { + if (folder instanceof SourceFolder) { + tooltipText = ((SourceFolder)folder).isTestSource()? "Unmark Tests" : "Unmark Source"; + } + else if (folder instanceof ExcludeFolder) { + tooltipText = "Include"; + } + else { + tooltipText = null; + } + } + else { + tooltipText = "Remove"; + } + return new IconActionComponent(DELETE_FOLDER_ICON, DELETE_FOLDER_ROLLOVER_ICON, tooltipText, new Runnable() { + public void run() { + myCallback.deleteContentFolder(myContentEntry, folder); + } + }); + } + + private JComponent createAddPrefixComponent(final SourceFolder folder) { + final IconActionComponent iconComponent = new IconActionComponent(ADD_PREFIX_ICON, ADD_PREFIX_ROLLOVER_ICON, "Set package prefix", new Runnable() { + public void run() { + final String message = "Enter package prefix for " + toRelativeDisplayPath(folder.getUrl(), myContentEntry.getUrl() + ":"); + final String prefix = Messages.showInputDialog(ContentRootPanel.this, message, "Set Package Prefix", Messages.getQuestionIcon(), folder.getPackagePrefix(), null); + if (prefix != null) { + myCallback.setPackagePrefix(folder, prefix); + } + } + }); + final JPanel panel = new JPanel(new BorderLayout()); + panel.setOpaque(false); + panel.add(iconComponent, BorderLayout.CENTER); + panel.add(Box.createHorizontalStrut(3), BorderLayout.EAST); + return panel; + } + + public boolean isExcluded(VirtualFile file) { + return getExcludeFolder(file) != null; + } + + public boolean isUnderExcludedDirectory(final VirtualFile file) { + if (myContentEntry == null) { + return false; + } + final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + final VirtualFile excludedDir = excludeFolders[idx].getFile(); + if (excludedDir == null) { + continue; + } + if (VfsUtil.isAncestor(excludedDir, file, true)) { + return true; + } + } + return false; + } + + public ExcludeFolder getExcludeFolder(VirtualFile file) { + if (myContentEntry == null) { + return null; + } + final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + for (int idx = 0; idx < excludeFolders.length; idx++) { + final ExcludeFolder excludeFolder = excludeFolders[idx]; + final VirtualFile f = excludeFolder.getFile(); + if (f == null) { + continue; + } + if (f.equals(file)) { + return excludeFolder; + } + } + return null; + } + + private static String toRelativeDisplayPath(String url, String ancestorUrl) { + if (!StringUtil.endsWithChar(ancestorUrl, '/')) { + ancestorUrl = ancestorUrl + "/"; + } + if (url.startsWith(ancestorUrl)) { + return url.substring(ancestorUrl.length()).replace('/', File.separatorChar); + } + return toDisplayPath(url); + } + + private static String toDisplayPath(final String url) { + return VirtualFileManager.extractPath(url).replace('/', File.separatorChar); + } + + + public void setSelected(boolean selected) { + if (selected) { + myHeader.setBackground(SELECTED_HEADER_COLOR); + setBackground(SELECTED_CONTENT_COLOR); + myBottom.setBackground(SELECTED_HEADER_COLOR); + for (Iterator it = myComponentToForegroundMap.keySet().iterator(); it.hasNext();) { + final JComponent component = it.next(); + component.setForeground(myComponentToForegroundMap.get(component)); + } + } + else { + myHeader.setBackground(HEADER_COLOR); + setBackground(CONTENT_COLOR); + myBottom.setBackground(HEADER_COLOR); + for (Iterator it = myComponentToForegroundMap.keySet().iterator(); it.hasNext();) { + final JComponent component = it.next(); + component.setForeground(UNSELECTED_TEXT_COLOR); + } + } + } + + private static class UnderlinedPathLabel extends ResizingWrapper { + private static final float[] DASH = new float[]{0, 2, 0, 2}; + private static final Color DASH_LINE_COLOR = new Color(0xC9C9C9); + + public UnderlinedPathLabel(JLabel wrappedComponent) { + super(wrappedComponent); + FilePathClipper.install(wrappedComponent, this); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + final int startX = myWrappedComponent.getWidth(); + final int endX = getWidth(); + if (endX > startX) { + final FontMetrics fontMetrics = myWrappedComponent.getFontMetrics(myWrappedComponent.getFont()); + final int y = fontMetrics.getMaxAscent(); + final Color savedColor = g.getColor(); + g.setColor(DASH_LINE_COLOR); + drawDottedLine((Graphics2D)g, startX, y, endX, y); + g.setColor(savedColor); + } + } + + private void drawDottedLine(Graphics2D g, int x1, int y1, int x2, int y2) { + /* + // TODO!!! + final Color color = g.getColor(); + g.setColor(getBackground()); + g.setColor(color); + for (int i = x1 / 2 * 2; i < x2; i += 2) { + g.drawRect(i, y1, 0, 0); + } + */ + if (SystemInfo.isMac) { + g.drawLine(x1, y1, x2, y2); + } + else { + final Stroke saved = g.getStroke(); + g.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, DASH, y1 % 2)); + + g.drawLine(x1, y1, x2, y2); + + g.setStroke(saved); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java new file mode 100644 index 00000000000..a16dc8079a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleConfigurationEditor; +import com.intellij.openapi.roots.ModifiableRootModel; + +/** + * @author Eugene Zhuravlev + * Date: Oct 28, 2004 + */ +public class DefaultModuleConfigurationEditorFactoryImpl extends DefaultModuleConfigurationEditorFactory { + public ModuleConfigurationEditor createModuleContentRootsEditor(ModuleConfigurationState state) { + final ModifiableRootModel rootModel = state.getRootModel(); + final Module module = rootModel.getModule(); + final String moduleName = module.getName(); + return new ContentEntriesEditor(state.getProject(), moduleName, rootModel, state.getModulesProvider()); + } + + public ModuleConfigurationEditor createLibrariesEditor(ModuleConfigurationState state) { + return new LibrariesEditor(state.getProject(), state.getRootModel()); + } + + public ModuleConfigurationEditor createDependenciesEditor(ModuleConfigurationState state) { + return new DependenciesEditor(state.getProject(), state.getRootModel(), state.getModulesProvider()); + } + + public ModuleConfigurationEditor createOrderEntriesEditor(ModuleConfigurationState state) { + return new OrderEntryEditor(state.getProject(), state.getRootModel()); + } + + public ModuleConfigurationEditor createJavadocEditor(ModuleConfigurationState state) { + return new JavadocEditor(state.getProject(), state.getRootModel()); + } + + public String getComponentName() { + return "DefaultModuleConfigurationEditorFactory"; + } + + public void initComponent() { } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java new file mode 100644 index 00000000000..a430560b343 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleComponent; +import com.intellij.openapi.module.ModuleConfigurationEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; + +import java.util.ArrayList; +import java.util.List; + +public class DefaultModuleEditorsProvider implements ModuleComponent, ModuleConfigurationEditorProvider { + public String getComponentName() { + return "DefaultModuleEditorsProvider"; + } + + public void initComponent() {} + public void disposeComponent() {} + public void projectOpened() {} + public void projectClosed() {} + public void moduleAdded() {} + + public ModuleConfigurationEditor[] createEditors(ModuleConfigurationState state) { + ModifiableRootModel rootModel = state.getRootModel(); + Module module = rootModel.getModule(); + String moduleName = module.getName(); + ModulesProvider provider = state.getModulesProvider(); + Project project = state.getProject(); + List editors = new ArrayList(); + editors.add(new ContentEntriesEditor(project, moduleName, rootModel, provider)); + editors.add(new LibrariesEditor(project, rootModel)); + if (provider.getModules().length > 1) { + editors.add(new DependenciesEditor(project, rootModel, provider)); + } + editors.add(new OrderEntryEditor(project, rootModel)); + editors.add(new JavadocEditor(project, rootModel)); + return editors.toArray(new ModuleConfigurationEditor[editors.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/FilePathClipper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/FilePathClipper.java new file mode 100644 index 00000000000..9cf91268f89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/FilePathClipper.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.util.ui.FilePathSplittingPolicy; +import com.intellij.util.ui.FilePathSplittingPolicy; + +import javax.swing.*; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: Jan 20, 2004 + */ +public class FilePathClipper implements ComponentListener { + private final File myFile; + private final JLabel myLabelToClip; + private final JComponent myComponentToWatch; + + private FilePathClipper(JLabel labelToClip, JComponent componentToWatch) { + myLabelToClip = labelToClip; + myComponentToWatch = componentToWatch; + final String text = labelToClip.getText(); // newly created JLabel can return null here + myFile = new File(text != null? text : ""); + } + + public static void install(JLabel labelToClip, JComponent componentToWatch) { + componentToWatch.addComponentListener(new FilePathClipper(labelToClip, componentToWatch)); + } + + public void componentResized(ComponentEvent e) { + final String optimalTextForComponent = FilePathSplittingPolicy.SPLIT_BY_SEPARATOR.getOptimalTextForComponent(myFile, myLabelToClip, myComponentToWatch.getWidth()); + myLabelToClip.setText(optimalTextForComponent); + } + + public void componentHidden(ComponentEvent e) {} + public void componentMoved(ComponentEvent e) {} + public void componentShown(ComponentEvent e) {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconActionComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconActionComponent.java new file mode 100644 index 00000000000..5f495bafdac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconActionComponent.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.roots.ui.configuration; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Eugene Zhuravlev + * Date: Nov 3 + * @author 2003 + */ +public class IconActionComponent extends ScalableIconComponent { + public IconActionComponent(Icon icon, Icon rolloverIcon, String tooltipText, final Runnable action) { + super(icon, rolloverIcon); + this.addMouseListener(new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + setSelected(true); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void mouseClicked(MouseEvent e) { + if (action != null) { + action.run(); + } + } + + public void mouseExited(MouseEvent e) { + setSelected(false); + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + }); + if (tooltipText != null) { + this.setToolTipText(tooltipText); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconSet.java new file mode 100644 index 00000000000..7a688caa41e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/IconSet.java @@ -0,0 +1,44 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 20 + * @author 2003 + */ +public class IconSet { + public static final Icon SOURCE_ROOT_FOLDER = IconLoader.getIcon("/modules/sourceRootClosed.png"); + public static final Icon SOURCE_ROOT_FOLDER_EXPANDED = IconLoader.getIcon("/modules/sourceRootOpened.png"); + public static final Icon SOURCE_FOLDER = IconLoader.getIcon("/modules/sourceClosed.png"); + public static final Icon SOURCE_FOLDER_EXPANDED = IconLoader.getIcon("/modules/sourceOpened.png"); + + public static final Icon TEST_ROOT_FOLDER = IconLoader.getIcon("/modules/testRootClosed.png"); + public static final Icon TEST_ROOT_FOLDER_EXPANDED = IconLoader.getIcon("/modules/testRootOpened.png"); + public static final Icon TEST_SOURCE_FOLDER = IconLoader.getIcon("/modules/testSourceClosed.png"); + public static final Icon TEST_SOURCE_FOLDER_EXPANDED = IconLoader.getIcon("/modules/testSourceOpened.png"); + + public static final Icon EXCLUDE_FOLDER = IconLoader.getIcon("/modules/excludeRootClosed.png"); + public static final Icon EXCLUDE_FOLDER_EXPANDED = IconLoader.getIcon("/modules/excludeRootOpened.png"); + + public static Icon getSourceRootIcon(boolean isTestSource, final boolean isExpanded) { + if (isExpanded) { + return isTestSource ? TEST_ROOT_FOLDER_EXPANDED : SOURCE_ROOT_FOLDER_EXPANDED; + } + return isTestSource ? TEST_ROOT_FOLDER : SOURCE_ROOT_FOLDER; + } + + public static Icon getSourceFolderIcon(boolean isTestSource, final boolean isExpanded) { + if (isExpanded) { + return isTestSource ? TEST_SOURCE_FOLDER_EXPANDED : SOURCE_FOLDER_EXPANDED; + } + return isTestSource ? TEST_SOURCE_FOLDER : SOURCE_FOLDER; + } + + public static Icon getExcludeIcon(boolean isExpanded) { + return isExpanded? EXCLUDE_FOLDER_EXPANDED : EXCLUDE_FOLDER; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java new file mode 100644 index 00000000000..a1a91fd7015 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java @@ -0,0 +1,257 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ui.Util; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ui.util.CellAppearance; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.roots.ui.util.SimpleTextCellAppearance; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.ItemRemovable; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +/** + * @author Eugene Zhuravlev + * Date: Oct 4, 2003 + * Time: 6:54:57 PM + */ +public class JavadocEditor extends ModuleElementsEditor { + private JTable myTable; + private JButton myAddPathButton; + private JButton myAddUrlButton; + private JButton myRemoveButton; + + public static final String NAME = "Javadoc"; + public static final Icon ICON = IconLoader.getIcon("/nodes/javaDocFolder.png"); + + public JavadocEditor(Project project, ModifiableRootModel model) { + super(project, model); + } + + public String getHelpTopic() { + return "project.paths.javadoc"; + } + + public String getDisplayName() { + return NAME; + } + + public Icon getIcon() { + return ICON; + } + + public void saveData() { + TableUtil.stopEditing(myTable); + final int count = myTable.getRowCount(); + String[] urls = new String[count]; + for (int row = 0; row < count; row++) { + final TableItem item = ((MyTableModel)myTable.getModel()).getTableItemAt(row); + urls[row] = item.getUrl(); + } + myModel.setJavadocUrls(urls); + } + + public JComponent createComponentImpl() { + final JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); + final DefaultTableModel tableModel = createModel(); + myTable = new Table(tableModel); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.setDefaultRenderer(TableItem.class, new MyRenderer()); + myTable.setShowGrid(false); + myTable.setDragEnabled(false); + myTable.setShowHorizontalLines(false); + myTable.setShowVerticalLines(false); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + myAddPathButton = new JButton("Add Path..."); + myAddPathButton.setMnemonic('A'); + myAddPathButton.addActionListener(new AddPathActionListener()); + + myAddUrlButton = new JButton("Add Javadoc URL..."); + myAddUrlButton.setMnemonic('U'); + myAddUrlButton.addActionListener(new AddUrlActionListener()); + + myRemoveButton = new JButton("Remove"); + myRemoveButton.setMnemonic('R'); + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + final ArrayList removedItems = TableUtil.removeSelectedItems(myTable); + if (removedItems.size() > 0) { + saveData(); + } + } + }); + + final JPanel panel = new JPanel(new GridBagLayout()); + panel.add(myAddPathButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 6, 0, 0), 0, 0)); + panel.add(myAddUrlButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(6, 6, 0, 0), 0, 0)); + panel.add(myRemoveButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(6, 6, 0, 0), 0, 0)); + + mainPanel.add(ScrollPaneFactory.createScrollPane(myTable), BorderLayout.CENTER); + mainPanel.add(panel, BorderLayout.EAST); + + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) { + return; + } + final int selectedIndex = myTable.getSelectedRow(); + myRemoveButton.setEnabled(selectedIndex >= 0); + } + }); + if (tableModel.getRowCount() > 0) { + TableUtil.selectRows(myTable, new int[] {0}); + } + else { + myRemoveButton.setEnabled(false); + } + return mainPanel; + } + + protected DefaultTableModel createModel() { + final MyTableModel tableModel = new MyTableModel(); + final String[] javadocUrls = myModel.getJavadocUrls(); + for (int idx = 0; idx < javadocUrls.length; idx++) { + String javadocUrl = javadocUrls[idx]; + tableModel.addTableItem(new TableItem(javadocUrl)); + } + return tableModel; + } + + public void moduleStateChanged() { + if (myTable != null) { + final DefaultTableModel tableModel = createModel(); + myTable.setModel(tableModel); + myRemoveButton.setEnabled(tableModel.getRowCount() > 0); + } + } + + private static class MyRenderer extends ColoredTableCellRenderer { + private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); + + protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { + setPaintFocusBorder(false); + setFocusBorderAroundIcon(true); + this.setBorder(NO_FOCUS_BORDER); + + final TableItem tableItem = ((TableItem)value); + tableItem.getCellAppearance().customize(this); + } + } + + private static class TableItem { + private final String myUrl; + private CellAppearance myCellAppearance; + public TableItem(VirtualFile file) { + myUrl = file.getUrl(); + myCellAppearance = CellAppearanceUtils.forVirtualFile(file); + } + + public TableItem(String url) { + myUrl = url; + final VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); + if (file != null) { + myCellAppearance = CellAppearanceUtils.forVirtualFile(file); + } + else { + myCellAppearance = SimpleTextCellAppearance.invalid(url, CellAppearanceUtils.INVALID_ICON); + } + } + + public String getUrl() { + return myUrl; + } + + public CellAppearance getCellAppearance() { + return myCellAppearance; + } + } + + private static class MyTableModel extends DefaultTableModel implements ItemRemovable{ + public String getColumnName(int column) { + return null; + } + + public Class getColumnClass(int columnIndex) { + return TableItem.class; + } + + public int getColumnCount() { + return 1; + } + + public boolean isCellEditable(int row, int column) { + return false; + } + + public TableItem getTableItemAt(int row) { + return (TableItem)getValueAt(row, 0); + } + + public void addTableItem(TableItem item) { + addRow(new Object[] {item}); + } + } + + private abstract class MyAddAction implements ActionListener { + protected abstract VirtualFile[] getFiles(); + + public void actionPerformed(ActionEvent e) { + VirtualFile[] files = getFiles(); + final MyTableModel tableModel = (MyTableModel)myTable.getModel(); + boolean changes = false; + for (int idx = 0; idx < files.length; idx++) { + final VirtualFile file = files[idx]; + if (file != null) { + tableModel.addTableItem(new TableItem(file)); + changes = true; + } + } + if (changes) { + saveData(); + TableUtil.selectRows(myTable, new int[] {tableModel.getRowCount() - 1}); + } + } + } + + private class AddUrlActionListener extends MyAddAction{ + protected VirtualFile[] getFiles() { + return new VirtualFile[] {Util.showSpecifyJavadocUrlDialog(myTable)}; + } + } + + private class AddPathActionListener extends MyAddAction{ + private final FileChooserDescriptor myDescriptor; + + public AddPathActionListener() { + myDescriptor = new FileChooserDescriptor(false, true, true, false, true, true); + myDescriptor.setTitle("Add Path To Javadoc"); + myDescriptor.setDescription("Select jar/zip files or directories in which module javadoc documentation is located"); + } + + protected VirtualFile[] getFiles() { + final VirtualFile[] files = FileChooser.chooseFiles(myTable, myDescriptor); + return (files != null)? files : VirtualFile.EMPTY_ARRAY; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibrariesAlphaComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibrariesAlphaComparator.java new file mode 100644 index 00000000000..85e6f240704 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibrariesAlphaComparator.java @@ -0,0 +1,48 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Comparator; + +/** + * @author Eugene Zhuravlev + * Date: Jan 14, 2004 + */ +public class LibrariesAlphaComparator implements Comparator { + public static LibrariesAlphaComparator INSTANCE = new LibrariesAlphaComparator(); + + public int compare(Library library1, Library library2) { + String name1 = library1.getName(); + if (name1 != null && name1.length() == 0) { + name1 = null; + } + String name2 = library2.getName(); + if (name2 != null && name2.length() == 0) { + name2 = null; + } + if (name1 == null && name2 == null) { + final VirtualFile[] files1 = library1.getFiles(OrderRootType.CLASSES); + final VirtualFile[] files2 = library2.getFiles(OrderRootType.CLASSES); + name1 = files1.length > 0? files1[0].getName() : null; + name2 = files2.length > 0? files2[0].getName() : null; + } + return compareNames(name1, name2); + } + + public int compareNames(String name1, String name2) { + if (name1 == null && name2 == null) { + return 0; + } + else if (name1 == null) { + return -1; + } + else if (name2 == null) { + return +1; + } + else { + return name1.compareToIgnoreCase(name2); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java new file mode 100644 index 00000000000..d9c46abcf6c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java @@ -0,0 +1,79 @@ +/** + * @author cdr + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.IconUtilEx; +import com.intellij.util.Icons; +import com.intellij.ide.util.ElementsChooser; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.util.Icons; + +import javax.swing.*; +import java.awt.*; + +public class LibraryChooserElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.LibraryChooserElement"); + + private final String myName; + private final Library myLibrary; + private LibraryOrderEntry myOrderEntry; + public static final ElementsChooser.ElementProperties VALID_LIBRARY_ELEMENT_PROPERTIES = new ElementsChooser.ElementProperties() { + public Icon getIcon() { + return Icons.LIBRARY_ICON; + } + public Color getColor() { + return null; + } + }; + public static final ElementsChooser.ElementProperties INVALID_LIBRARY_ELEMENT_PROPERTIES = new ElementsChooser.ElementProperties() { + public Icon getIcon() { + return Icons.LIBRARY_ICON; + } + public Color getColor() { + return Color.RED; + } + }; + + public LibraryChooserElement(Library library, final LibraryOrderEntry orderEntry) { + myLibrary = library; + myOrderEntry = orderEntry; + if (myLibrary == null && myOrderEntry == null) { + LOG.assertTrue(false, "Both library and order entry are null"); + myName = "Unknown"; + } + else { + myName = myLibrary != null? myLibrary.getName() : myOrderEntry.getLibraryName(); + } + } + + public String toString() { + return myName; + } + + public String getName() { + return myName; + } + + public Library getLibrary() { + return myLibrary; + } + + public LibraryOrderEntry getOrderEntry() { + return myOrderEntry; + } + + public void setOrderEntry(LibraryOrderEntry orderEntry) { + myOrderEntry = orderEntry; + } + + public boolean isAttachedToProject() { + return myOrderEntry != null; + } + + public boolean isValid() { + return myLibrary != null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryTableModifiableModelProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryTableModifiableModelProvider.java new file mode 100644 index 00000000000..1552bf3b2ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/LibraryTableModifiableModelProvider.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.libraries.LibraryTable; + +public interface LibraryTableModifiableModelProvider { + + LibraryTable.ModifiableModel getModifiableModel(); + + String getTableLevel(); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleCreationInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleCreationInfo.java new file mode 100644 index 00000000000..b85f0c8a353 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleCreationInfo.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.ui.configuration; + +/** + * @author Eugene Zhuravlev + * Date: Dec 15, 2003 + */ +public class ModuleCreationInfo { + public String name; + public String path; + public String moduleType; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java new file mode 100644 index 00000000000..a948d0ab035 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -0,0 +1,409 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.j2ee.ex.J2EEModulePropertiesEx; +import com.intellij.j2ee.j2eeDom.J2EEModuleProperties; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleConfigurationEditor; +import com.intellij.openapi.module.impl.ModuleConfigurationStateImpl; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.EventDispatcher; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.*; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Oct 4, 2003 + * Time: 6:29:56 PM + */ +public class ModuleEditor { + private final Project myProject; + private JPanel myPanel; + private ModifiableRootModel myModifiableRootModel; // important: in order to correctly update OrderEntries UI use corresponding proxy for the model + private String mySelectedTabName; + private TabbedPaneWrapper myTabbedPane; + private final ModulesProvider myModulesProvider; + private final String myName; + private List myEditors = new ArrayList(); + private DependenciesEditor myDependenciesEditor; + private ModifiableRootModel myModifiableRootModelProxy; + private EventDispatcher myEventDispatcher = EventDispatcher.create(ChangeListener.class); + + public static interface ChangeListener extends EventListener { + void moduleStateChanged(ModifiableRootModel moduleRootModel); + } + + public ModuleEditor(Project project, ModulesProvider modulesProvider, String moduleName) { + myProject = project; + myModulesProvider = modulesProvider; + myName = moduleName; + } + + public void addChangeListener(ChangeListener listener) { + myEventDispatcher.addListener(listener); + } + + public void removeChangeListener(ChangeListener listener) { + myEventDispatcher.removeListener(listener); + } + + public Module getModule() { + return myModulesProvider.getModule(myName); + } + + public ModifiableRootModel getModifiableRootModel() { + return myModifiableRootModel; + } + + public ModifiableRootModel getModifiableRootModelProxy() { + if (myModifiableRootModelProxy == null) { + createPanel(); // this will initialize the proxy + } + return myModifiableRootModelProxy; + } + + public boolean isModified() { + for (int i = 0; i < myEditors.size(); i++) { + ModuleConfigurationEditor moduleElementsEditor = myEditors.get(i); + if (moduleElementsEditor.isModified()) { + return true; + } + } + return false; + } + + private void createEditors(Module module) { + Object[] providers = module.getComponents(ModuleConfigurationEditorProvider.class); + ModuleConfigurationState state = new ModuleConfigurationStateImpl(myProject, module, myModulesProvider, myModifiableRootModelProxy); + for (int i = 0; i < providers.length; i++) { + ModuleConfigurationEditorProvider provider = (ModuleConfigurationEditorProvider)providers[i]; + final ModuleConfigurationEditor[] editors = provider.createEditors(state); + myEditors.addAll(Arrays.asList(editors)); + if (myDependenciesEditor == null) { + for (int idx = 0; idx < editors.length; idx++) { + ModuleConfigurationEditor editor = editors[idx]; + if (editor instanceof DependenciesEditor) { + myDependenciesEditor = (DependenciesEditor)editor; + break; + } + } + } + } + } + + private JPanel createPanel() { + myModifiableRootModel = ModuleRootManager.getInstance(getModule()).getModifiableModel(); + myModifiableRootModelProxy = (ModifiableRootModel)Proxy.newProxyInstance( + getClass().getClassLoader(), new Class[]{ModifiableRootModel.class}, new ModifiableRootModelInvocationHandler(myModifiableRootModel) + ); + + myPanel = new JPanel(new BorderLayout()); + + createEditors(getModule()); + + myTabbedPane = new TabbedPaneWrapper(); + for (Iterator it = myEditors.iterator(); it.hasNext();) { + ModuleConfigurationEditor editor = it.next(); + if (editor == myDependenciesEditor && myModulesProvider.getModules().length <= 1) { + continue; + } + myTabbedPane.addTab(editor.getDisplayName(), editor.getIcon(), editor.createComponent(), null); + editor.reset(); + } + myTabbedPane.installKeyboardNavigation(); + setSelectedTabName(mySelectedTabName); + + myPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); + + return myPanel; + } + + private int getEditorTabIndex(final String editorName) { + if (myTabbedPane != null && editorName != null) { + final int tabCount = myTabbedPane.getTabCount(); + for (int idx = 0; idx < tabCount; idx++) { + if (editorName.equals(myTabbedPane.getTitleAt(idx))) { + return idx; + } + } + } + return -1; + } + + public JPanel getPanel() { + if (myPanel == null) { + myPanel = createPanel(); + } + return myPanel; + } + + public void moduleCountChanged(int oldCount, int newCount) { + if (myTabbedPane != null && myDependenciesEditor != null) { + if (newCount > 1) { + if (getEditorTabIndex(myDependenciesEditor.getDisplayName()) == -1) { // if not added yet + final int indexToInsert = myEditors.indexOf(myDependenciesEditor); + myTabbedPane.insertTab(myDependenciesEditor.getDisplayName(), myDependenciesEditor.getIcon(), + myDependenciesEditor.getComponent(), null, indexToInsert); + } + } + else { + final int editorTabIndex = getEditorTabIndex(myDependenciesEditor.getDisplayName()); + if (editorTabIndex >= 0) { // already added + myTabbedPane.removeTabAt(editorTabIndex); + } + } + } + updateOrderEntriesInEditors(); + } + + private void updateOrderEntriesInEditors() { + for (Iterator it = myEditors.iterator(); it.hasNext();) { + it.next().moduleStateChanged(); + } + myEventDispatcher.getMulticaster().moduleStateChanged(getModifiableRootModelProxy()); + } + + public ModifiableRootModel dispose() { + try { + for (Iterator it = myEditors.iterator(); it.hasNext();) { + it.next().disposeUIResources(); + } + + myEditors.clear(); + + if (myTabbedPane != null) { + mySelectedTabName = getSelectedTabName(); + myTabbedPane = null; + } + myPanel = null; + return myModifiableRootModel; + } + finally { + myModifiableRootModel = null; + myModifiableRootModelProxy = null; + } + } + + public ModifiableRootModel applyAndDispose() throws ConfigurationException { + for (Iterator it = myEditors.iterator(); it.hasNext();) { + ModuleConfigurationEditor editor = it.next(); + editor.saveData(); + editor.apply(); + } + + if (getModule().getModuleType().isJ2EE() && myModifiableRootModel != null) { + final J2EEModulePropertiesEx j2EEModulePropertiesEx = (J2EEModulePropertiesEx)J2EEModuleProperties.getInstance(getModule()); + if (j2EEModulePropertiesEx != null) { + j2EEModulePropertiesEx.commit(myModifiableRootModel); + } + } + + return dispose(); + } + + public String getName() { + return myName; + } + + public String getSelectedTabName() { + return myTabbedPane == null ? null : myTabbedPane.getTitleAt(myTabbedPane.getSelectedIndex()); + } + + public void setSelectedTabName(String name) { + if (name != null) { + final int editorTabIndex = getEditorTabIndex(name); + if (editorTabIndex >= 0 && editorTabIndex < myTabbedPane.getTabCount()) { + myTabbedPane.setSelectedIndex(editorTabIndex); + mySelectedTabName = name; + } + } + } + + private class ModifiableRootModelInvocationHandler implements InvocationHandler { + private final ModifiableRootModel myDelegateModel; + private final Set myCheckedNames = new HashSet( + Arrays.asList( + new String[]{"addOrderEntry", "addLibraryEntry", "addInvalidLibrary", "addModuleOrderEntry", "addInvalidModuleEntry", + "removeOrderEntry", "setJdk", "inheritJdk"} + )); + + ModifiableRootModelInvocationHandler(ModifiableRootModel model) { + myDelegateModel = model; + } + + public Object invoke(Object object, Method method, Object[] params) throws Throwable { + final boolean needUpdate = myCheckedNames.contains(method.getName()); + try { + final Object result = method.invoke(myDelegateModel, unwrapParams(params)); + if (result instanceof LibraryTable) { + return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{LibraryTable.class}, + new LibraryTableInvocationHandler((LibraryTable)result)); + } + return result; + } + finally { + if (needUpdate) { + updateOrderEntriesInEditors(); + } + } + } + } + + private class LibraryTableInvocationHandler implements InvocationHandler { + private final LibraryTable myDelegateTable; + private final Set myCheckedNames = new HashSet(Arrays.asList(new String[]{"removeLibrary", /*"createLibrary"*/})); + + LibraryTableInvocationHandler(LibraryTable table) { + myDelegateTable = table; + } + + public Object invoke(Object object, Method method, Object[] params) throws Throwable { + final boolean needUpdate = myCheckedNames.contains(method.getName()); + try { + final Object result = method.invoke(myDelegateTable, unwrapParams(params)); + if (result instanceof Library) { + return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Library.class}, + new LibraryInvocationHandler((Library)result)); + } + else if (result instanceof LibraryTable.ModifiableModel) { + return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{LibraryTable.ModifiableModel.class}, + new LibraryTableModelInvocationHandler((LibraryTable.ModifiableModel)result)); + } + if (result instanceof Library[]) { + Library[] libraries = (Library[])result; + for (int idx = 0; idx < libraries.length; idx++) { + Library library = libraries[idx]; + libraries[idx] = + (Library)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Library.class}, + new LibraryInvocationHandler(library)); + } + } + return result; + } + finally { + if (needUpdate) { + updateOrderEntriesInEditors(); + } + } + } + + } + + private class LibraryInvocationHandler implements InvocationHandler, ProxyDelegateAccessor { + private final Library myDelegateLibrary; + + LibraryInvocationHandler(Library delegateLibrary) { + myDelegateLibrary = delegateLibrary; + } + + public Object invoke(Object object, Method method, Object[] params) throws Throwable { + final Object result = method.invoke(myDelegateLibrary, unwrapParams(params)); + if (result instanceof Library.ModifiableModel) { + return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Library.ModifiableModel.class}, + new LibraryModifiableModelInvocationHandler((Library.ModifiableModel)result)); + } + return result; + } + + public Object getDelegate() { + return myDelegateLibrary; + } + } + + private class LibraryModifiableModelInvocationHandler implements InvocationHandler { + private final Library.ModifiableModel myDelegateModel; + + LibraryModifiableModelInvocationHandler(Library.ModifiableModel delegateModel) { + myDelegateModel = delegateModel; + } + + public Object invoke(Object object, Method method, Object[] params) throws Throwable { + final boolean needUpdate = "commit".equals(method.getName()); + try { + return method.invoke(myDelegateModel, unwrapParams(params)); + } + finally { + if (needUpdate) { + updateOrderEntriesInEditors(); + } + } + } + } + + private class LibraryTableModelInvocationHandler implements InvocationHandler { + private final LibraryTable.ModifiableModel myDelegateModel; + + LibraryTableModelInvocationHandler(LibraryTable.ModifiableModel delegateModel) { + myDelegateModel = delegateModel; + } + + public Object invoke(Object object, Method method, Object[] params) throws Throwable { + final boolean needUpdate = "commit".equals(method.getName()); + try { + Object result = method.invoke(myDelegateModel, unwrapParams(params)); + if (result instanceof Library[]) { + Library[] libraries = (Library[])result; + for (int idx = 0; idx < libraries.length; idx++) { + Library library = libraries[idx]; + libraries[idx] = + (Library)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Library.class}, + new LibraryInvocationHandler(library)); + } + } + if (result instanceof Library) { + result = + Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Library.class}, + new LibraryInvocationHandler((Library)result)); + } + return result; + } + finally { + if (needUpdate) { + updateOrderEntriesInEditors(); + } + } + } + } + + public static interface ProxyDelegateAccessor { + Object getDelegate(); + } + + private Object[] unwrapParams(Object[] params) { + if (params == null || params.length == 0) { + return params; + } + final Object[] unwrappedParams = new Object[params.length]; + for (int idx = 0; idx < params.length; idx++) { + Object param = params[idx]; + if (param != null && Proxy.isProxyClass(param.getClass())) { + final InvocationHandler invocationHandler = Proxy.getInvocationHandler(param); + if (invocationHandler instanceof ProxyDelegateAccessor) { + param = ((ProxyDelegateAccessor)invocationHandler).getDelegate(); + } + } + unwrappedParams[idx] = param; + } + return unwrappedParams; + } + + public String getHelpTopic() { + if (myTabbedPane == null || myEditors.isEmpty()) { + return null; + } + final ModuleConfigurationEditor moduleElementsEditor = myEditors.get(myTabbedPane.getSelectedIndex()); + return moduleElementsEditor.getHelpTopic(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditorState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditorState.java new file mode 100644 index 00000000000..244293c42d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleEditorState.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.util.*; +import com.intellij.openapi.project.Project; +import org.jdom.Element; + +/** + * @author Eugene Zhuravlev + * Date: Jul 22, 2004 + */ +public class ModuleEditorState implements ProjectComponent, JDOMExternalizable{ + + public String LAST_EDITED_MODULE_NAME; + public String LAST_EDITED_TAB_NAME; + + public static ModuleEditorState getInstance(Project project) { + return (ModuleEditorState)project.getComponent(ModuleEditorState.class); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "ModuleEditorState"; + } + + public void initComponent() { } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java new file mode 100644 index 00000000000..289ee1aec2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java @@ -0,0 +1,49 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.module.ModuleConfigurationEditor; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 4, 2003 + * Time: 7:24:37 PM + */ +public abstract class ModuleElementsEditor implements ModuleConfigurationEditor { + protected final Project myProject; + protected final ModifiableRootModel myModel; + protected JComponent myComponent; + + protected ModuleElementsEditor(Project project, ModifiableRootModel model) { + myProject = project; + myModel = model; + } + + public boolean isModified() { + boolean modelChanged = myModel == null? false : myModel.isChanged(); + return modelChanged; + } + + public void apply() throws ConfigurationException {} + public void reset() {} + public void moduleStateChanged() {} + public void disposeUIResources() {} + + // caching + public final JComponent createComponent() { + if (myComponent == null) { + myComponent = createComponentImpl(); + } + return myComponent; + } + + + public JComponent getComponent() { + return createComponent(); + } + + protected abstract JComponent createComponentImpl(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleLevelConfigurablesEditorProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleLevelConfigurablesEditorProvider.java new file mode 100644 index 00000000000..01a7a91ba04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModuleLevelConfigurablesEditorProvider.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.module.ModuleComponent; +import com.intellij.openapi.module.ModuleConfigurationEditor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.roots.ModifiableRootModel; + +import javax.swing.*; +import java.util.ArrayList; + +public class ModuleLevelConfigurablesEditorProvider implements ModuleConfigurationEditorProvider, ModuleComponent { + private final Module myModule; + + public ModuleLevelConfigurablesEditorProvider(Module module) { + myModule = module; + } + + public ModuleConfigurationEditor[] createEditors(ModuleConfigurationState state) { + ArrayList result = new ArrayList(); + Configurable[] moduleConfigurables = myModule.getComponents(Configurable.class); + for (int i = 0; i < moduleConfigurables.length; i++) { + final Configurable moduleConfigurable = moduleConfigurables[i]; + result.add(new ConfigurableWrapper(moduleConfigurable)); + } + return result.toArray(new ModuleConfigurationEditor[result.size()]); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void moduleAdded() { + } + + public String getComponentName() { + return "ModuleLevelConfigurablesEditorProvider"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + private static class ConfigurableWrapper implements ModuleConfigurationEditor { + private final Configurable myModuleConfigurable; + + public ConfigurableWrapper(Configurable moduleConfigurable) { + myModuleConfigurable = moduleConfigurable; + } + + public void saveData() { + + } + + public void moduleStateChanged() { + } + + public String getDisplayName() { + return myModuleConfigurable.getDisplayName(); + } + + public Icon getIcon() { + return myModuleConfigurable.getIcon(); + } + + public String getHelpTopic() { + return myModuleConfigurable.getHelpTopic(); + } + + public JComponent createComponent() { + return myModuleConfigurable.createComponent(); + } + + public boolean isModified() { + return myModuleConfigurable.isModified(); + } + + public void apply() throws ConfigurationException { + myModuleConfigurable.apply(); + } + + public void reset() { + myModuleConfigurable.reset(); + } + + public void disposeUIResources() { + myModuleConfigurable.disposeUIResources(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java new file mode 100644 index 00000000000..bc42b4a8145 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesAlphaComparator.java @@ -0,0 +1,18 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.module.Module; + +import java.util.Comparator; + +/** + * @author Eugene Zhuravlev + * Date: Dec 1 + * @author 2003 + */ +public class ModulesAlphaComparator implements Comparator{ + public int compare(Module module1, Module module2) { + final String name1 = module1.getName(); + final String name2 = module2.getName(); + return name1.compareToIgnoreCase(name2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurable.java new file mode 100644 index 00000000000..7dfbcc07a9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurable.java @@ -0,0 +1,106 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Dec 15, 2003 + */ +public class ModulesConfigurable implements Configurable { + private final Project myProject; + private final String myModuleNameToSelect; + private final String myTabNameToSelect; + private final boolean myStartModuleWizardOnShow; + private ModulesConfigurator myConfigurator; + private static final Icon ICON = IconLoader.getIcon("/modules/modules.png"); + + public ModulesConfigurable(Project project) { + this(project, null, null, false); + } + + public ModulesConfigurable(Project project, String moduleNameToSelect, String tabNameToSelect, boolean startModuleWizard) { + myProject = project; + myModuleNameToSelect = moduleNameToSelect; + myTabNameToSelect = tabNameToSelect; + myStartModuleWizardOnShow = startModuleWizard; + } + + public String getDisplayName() { + return "Paths"; + } + + public void reset() { + if (myConfigurator != null) { + if (isModified()) { + myConfigurator.reset(); + } + final String moduleNameToSelect = getModuleNameToSelect(); + if (moduleNameToSelect == null || !myConfigurator.selectModule(moduleNameToSelect, getTabNameToSelect())) { + myConfigurator.selectFirstModule(); + } + } + } + + public void apply() throws ConfigurationException { + myConfigurator.apply(); + } + + public String getHelpTopic() { + if (myConfigurator != null) { + final String helpTopic = myConfigurator.getHelpTopic(); + if (helpTopic != null) { + return helpTopic; + } + } + return "project.paths"; + } + + public void disposeUIResources() { + if (myConfigurator != null) { + final ModuleEditorState state = ModuleEditorState.getInstance(myProject); + state.LAST_EDITED_MODULE_NAME = myConfigurator.getSelectedModuleName(); + state.LAST_EDITED_TAB_NAME = myConfigurator.getSelectedTabName(); + myConfigurator.dispose(); + myConfigurator = null; // important: becomes invalid after destroyProcess + } + } + + public boolean isModified() { + return myConfigurator.isModified(); + } + + public JComponent createComponent() { + if (myConfigurator == null) { + myConfigurator = new ModulesConfigurator(myProject, myStartModuleWizardOnShow); + } + return myConfigurator.createComponent(); + } + + public Icon getIcon() { + return ICON; + } + + public ModulesConfigurator getConfigurator() { + return myConfigurator; + } + + private String getModuleNameToSelect() { + if (myModuleNameToSelect == null) { + return ModuleEditorState.getInstance(myProject).LAST_EDITED_MODULE_NAME; + } + return myModuleNameToSelect; + } + + private String getTabNameToSelect() { + if (myTabNameToSelect == null) { + return ModuleEditorState.getInstance(myProject).LAST_EDITED_TAB_NAME; + } + return myTabNameToSelect; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java new file mode 100644 index 00000000000..aa4473ce99e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java @@ -0,0 +1,676 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.IconUtilEx; +import com.intellij.ide.util.projectWizard.AddModuleWizard; +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.util.projectWizard.ToolbarPanel; +import com.intellij.j2ee.module.J2EEModuleUtilEx; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleCircularDependencyException; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider; +import com.intellij.openapi.roots.ui.configuration.actions.ModulesConfigurationAction; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.ui.ScrollPaneFactory; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.*; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Dec 15, 2003 + */ +public class ModulesConfigurator implements ModulesProvider, ModuleEditor.ChangeListener { + + private final Project myProject; + private final boolean myStartModuleWizardOnShow; + + private List myModuleEditors = new ArrayList(); + private JList myModuleEditorsList; + private JPanel myModuleContentsPanel; + private static final String EMPTY_PANEL_ID = "EmptyPanel"; + private ComboBox myLanguageLevelCombo; + private JRadioButton myRbRelativePaths; + private JRadioButton myRbAbsolutePaths; + + private final Comparator myModuleEditorComparator = new Comparator() { + final ModulesAlphaComparator myModulesComparator = new ModulesAlphaComparator(); + + public int compare(ModuleEditor editor1, ModuleEditor editor2) { + return myModulesComparator.compare(editor1.getModule(), editor2.getModule()); + } + + public boolean equals(Object o) { + return false; + } + }; + private ModifiableModuleModel myModuleModel; + private JPanel myModuleListPanel; + private static final String DIMENSION_KEY = "#com.intellij.openapi.roots.ui.configuration.ModulesConfigurator"; + private JLabel myWarningLabel; + + public ModulesConfigurator(Project project) { + this(project, false); + } + + public ModulesConfigurator(Project project, boolean startModuleWizardOnShow) { + myProject = project; + myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); + myStartModuleWizardOnShow = startModuleWizardOnShow; + } + + public JComponent createComponent() { + final JPanel mainPanel = new MyJPanel(); + mainPanel.setPreferredSize(new Dimension(700, 500)); + + myModuleListPanel = new JPanel(new BorderLayout()); + + myLanguageLevelCombo = new ComboBox(); + myLanguageLevelCombo.addItem(LanguageLevel.JDK_1_3); + myLanguageLevelCombo.addItem(LanguageLevel.JDK_1_4); + myLanguageLevelCombo.addItem(LanguageLevel.JDK_1_5); + myLanguageLevelCombo.setRenderer(new MyDefaultListCellRenderer()); + myLanguageLevelCombo.setSelectedItem(ProjectRootManagerEx.getInstanceEx(myProject).getLanguageLevel()); + myRbRelativePaths = new JRadioButton("Use relative path"); + myRbAbsolutePaths = new JRadioButton("Use absolute path"); + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbRelativePaths); + buttonGroup.add(myRbAbsolutePaths); + if (((ProjectEx)myProject).isSavePathsRelative()) { + myRbRelativePaths.setSelected(true); + } + else { + myRbAbsolutePaths.setSelected(true); + } + + + myModuleEditorsList = new JList(new DefaultListModel()); + myModuleEditorsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myModuleEditorsList.setCellRenderer(new ModulesListCellRenderer()); + + final JScrollPane modulesListScrollPane = ScrollPaneFactory.createScrollPane(myModuleEditorsList); + final Dimension preferredSize = new Dimension(130, 100); + modulesListScrollPane.setPreferredSize(preferredSize); + modulesListScrollPane.setMinimumSize(preferredSize); + + myModuleContentsPanel = new JPanel(new CardLayout()); + myModuleContentsPanel.add(new JPanel(), EMPTY_PANEL_ID); + + final DefaultActionGroup moduleActionsGroup = new DefaultActionGroup(); + + final AddModuleAction addModuleAction = new AddModuleAction(mainPanel); + addModuleAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myModuleEditorsList); + moduleActionsGroup.add(addModuleAction); + + final RemoveModuleAction removeModuleAction = new RemoveModuleAction(); + removeModuleAction.registerCustomShortcutSet(CommonShortcuts.DELETE, myModuleEditorsList); + moduleActionsGroup.add(removeModuleAction); + + myModuleListPanel.add(new JLabel("Modules:"), BorderLayout.NORTH); + myModuleListPanel.add(new ToolbarPanel(modulesListScrollPane, moduleActionsGroup), BorderLayout.CENTER); + + final Splitter modulesContentSplitter = new Splitter(false); + modulesContentSplitter.setHonorComponentsMinimumSize(true); + modulesContentSplitter.setShowDividerControls(true); + modulesContentSplitter.setProportion(0.20f); + modulesContentSplitter.setFirstComponent(myModuleListPanel); + modulesContentSplitter.setSecondComponent(myModuleContentsPanel); + mainPanel.add( + modulesContentSplitter, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 0, 0, 0), 0, 0) + ); + + mainPanel.add(new JLabel("For files outside project file directory:"), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0)); + mainPanel.add(myRbAbsolutePaths, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0)); + mainPanel.add(myRbRelativePaths, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0)); + + final Box horizontalBox = Box.createHorizontalBox(); + horizontalBox.add(new JLabel("Language level for project (effective on restart): ")); + horizontalBox.add(Box.createHorizontalStrut(5)); + horizontalBox.add(myLanguageLevelCombo); + mainPanel.add(horizontalBox, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0)); + + myWarningLabel = new JLabel(""); + myWarningLabel.setUI(new MultiLineLabelUI()); + mainPanel.add(myWarningLabel, new GridBagConstraints(3, GridBagConstraints.RELATIVE, 1, 2, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 6, 0, 0), 0, 0) ); + + myModuleEditorsList.addListSelectionListener(new ListSelectionListener() { + int mySelectedIndex = -1; + + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) { + return; + } + final ModuleEditor previousEditor = getEditorAt(mySelectedIndex); + final ModuleEditor selectedEditor = getSelectedEditor(); + if (selectedEditor != null) { + showModuleEditor(selectedEditor, previousEditor != null ? previousEditor.getSelectedTabName() : null); + } + mySelectedIndex = myModuleEditorsList.getSelectedIndex(); + } + + }); + + resetModuleEditors(); + + return mainPanel; + } + + public void dispose() { + disposeModuleEditors(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myModuleModel.dispose(); + } + }); + } + + public Module[] getModules() { + return myModuleModel.getModules(); + } + + public Module getModule(String name) { + return myModuleModel.findModuleByName(name); + } + + public String getSelectedModuleName() { + final ModuleEditor selectedEditor = getSelectedEditor(); + if (selectedEditor == null) { + return null; + } + return selectedEditor.getModule().getName(); + } + + public String getSelectedTabName() { + final ModuleEditor selectedEditor = getSelectedEditor(); + if (selectedEditor == null) { + return null; + } + return selectedEditor.getSelectedTabName(); + } + + private ModuleEditor getModuleEditor(Module module) { + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = (ModuleEditor)it.next(); + if (module.equals(moduleEditor.getModule())) { + return moduleEditor; + } + } + return null; + } + + public ModuleRootModel getRootModel(Module module) { + final ModuleEditor editor = getModuleEditor(module); + ModuleRootModel rootModel = null; + if (editor != null) { + rootModel = editor.getModifiableRootModel(); + } + if (rootModel == null) { + rootModel = ModuleRootManager.getInstance(module); + } + + return rootModel; + } + + public void reset() { + try { + disposeModuleEditors(); + } + finally { + myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); + } + + resetModuleEditors(); + + refreshUI(); + } + + private void disposeModuleEditors() { + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = it.next(); + removeModuleEditorUIComponent(moduleEditor); + final ModifiableRootModel model = moduleEditor.dispose(); + if (model != null) { + model.dispose(); + } + } + } + + private void resetModuleEditors() { + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = (ModuleEditor)it.next(); + moduleEditor.removeChangeListener(this); + } + myModuleEditors.clear(); + final DefaultListModel listModel = (DefaultListModel)myModuleEditorsList.getModel(); + listModel.clear(); + final Module[] modules = myModuleModel.getModules(); + if (modules.length > 0) { + for (int idx = 0; idx < modules.length; idx++) { + createModuleEditor(modules[idx]); + } + Collections.sort(myModuleEditors, myModuleEditorComparator); + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + listModel.addElement(new ModuleEditorWrapper(it.next())); + } + } + updateCircularDependencyWarning(); + } + + private ModuleEditor createModuleEditor(final Module module) { + final ModuleEditor moduleEditor = new ModuleEditor(myProject, this, module.getName()); + myModuleEditors.add(moduleEditor); + moduleEditor.addChangeListener(this); + return moduleEditor; + } + + public void moduleStateChanged(final ModifiableRootModel moduleRootModel) { + updateCircularDependencyWarning(); + } + + private void updateCircularDependencyWarning() { + final ProjectRootManagerEx projectRootManagerEx = ProjectRootManagerEx.getInstanceEx(myProject); + String warningMessage = ""; + try { + List modelsToCheck = new ArrayList(myModuleEditors.size()); + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = it.next(); + final ModifiableRootModel model = moduleEditor.getModifiableRootModel(); + if (model != null) { + modelsToCheck.add(model); + } + } + projectRootManagerEx.checkCircularDependency(modelsToCheck.toArray(new ModifiableRootModel[modelsToCheck.size()]), myModuleModel); + } + catch (ModuleCircularDependencyException e) { + warningMessage = "There is a circular dependency between modules \"" + e.getModuleName1() + "\" and \"" + e.getModuleName2() + "\""; + } + myWarningLabel.setIcon(warningMessage.length() > 0? Messages.getWarningIcon() : null); + myWarningLabel.setText(warningMessage); + } + + public void apply() throws ConfigurationException { + final ProjectRootManagerEx projectRootManagerEx = ProjectRootManagerEx.getInstanceEx(myProject); + + try { + final List models = new ArrayList(myModuleEditors.size()); + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = it.next(); + removeModuleEditorUIComponent(moduleEditor); + final ModifiableRootModel model = moduleEditor.applyAndDispose(); + if (model != null) { + models.add(model); + } + } + + J2EEModuleUtilEx.checkJ2EEModulesAcyclic(models); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + projectRootManagerEx.setLanguageLevel((LanguageLevel)myLanguageLevelCombo.getSelectedItem()); + ((ProjectEx)myProject).setSavePathsRelative(myRbRelativePaths.isSelected()); + final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]); + projectRootManagerEx.multiCommit(myModuleModel, rootModels); + } + finally { + myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); + } + } + }); + ApplicationManager.getApplication().saveAll(); + + } + finally { + refreshUI(); + } + } + + private void refreshUI() { + if (myModuleEditorsList == null) { + return; + } + int selectedModuleIndex = myModuleEditorsList.getSelectedIndex(); + if (selectedModuleIndex < 0 && myModuleEditors.size() > 0) { + selectedModuleIndex = 0; + } + if (selectedModuleIndex >= 0) { + final ModuleEditor selectedEditor = myModuleEditors.get(selectedModuleIndex); + showModuleEditor(selectedEditor, null); // this will create new ModifiableRootModel for selected editor as well + } + else { + showModuleEditor(null, null); + } + } + + private void removeModuleEditorUIComponent(final ModuleEditor moduleEditor) { + final String id = moduleEditor.getName(); + if (myShownModuleEditors.contains(id)) { + myModuleContentsPanel.remove(moduleEditor.getPanel()); + myShownModuleEditors.remove(id); + } + } + + private Set myShownModuleEditors = new HashSet(); + + private void showModuleEditor(ModuleEditor moduleEditor, final String tabNameToSelect) { + final String id; + if (moduleEditor != null) { + id = moduleEditor.getName(); + if (!myShownModuleEditors.contains(id)) { + myModuleContentsPanel.add(moduleEditor.getPanel(), id); + myShownModuleEditors.add(id); + } + myModuleEditorsList.setSelectedIndex(myModuleEditors.indexOf(moduleEditor)); + moduleEditor.setSelectedTabName(tabNameToSelect); + } + else { + id = EMPTY_PANEL_ID; + } + ((CardLayout)myModuleContentsPanel.getLayout()).show(myModuleContentsPanel, id); + } + + private ModuleEditor getSelectedEditor() { + if (myModuleEditors.size() == 0) { + return null; + } + if (myModuleEditors.size() == 1) { + return myModuleEditors.get(0); + } + return getEditorAt(myModuleEditorsList.getSelectedIndex()); + } + + private ModuleEditor getEditorAt(final int selectedIndex) { + return selectedIndex >= 0 && selectedIndex < myModuleEditors.size() ? myModuleEditors.get(selectedIndex) : null; + } + + private static class ModuleEditorWrapper { + private final ModuleEditor myModuleEditor; + private final String myDisplayName; + + public ModuleEditorWrapper(ModuleEditor moduleEditor) { + myModuleEditor = moduleEditor; + myDisplayName = myModuleEditor.getModule().getName(); + } + + public String toString() { + return myDisplayName; + } + + public ModuleEditor getModuleEditor() { + return myModuleEditor; + } + } + + private ModuleEditor findModuleEditor(String name) { + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + ModuleEditor moduleEditor = (ModuleEditor)it.next(); + if (name.equals(moduleEditor.getModule().getName())) { + return moduleEditor; + } + } + return null; + } + + private void addModule(final Module module) { + final ModuleEditor moduleEditor = createModuleEditor(module); + final ModuleEditor selectedEditor = getSelectedEditor(); + + Collections.sort(myModuleEditors, myModuleEditorComparator); + final int insertIndex = myModuleEditors.indexOf(moduleEditor); + final String selectedTab = selectedEditor != null ? selectedEditor.getSelectedTabName() : null; + final DefaultListModel listModel = (DefaultListModel)myModuleEditorsList.getModel(); + listModel.add(insertIndex, new ModuleEditorWrapper(moduleEditor)); + showModuleEditor(moduleEditor, selectedTab); + myModuleEditorsList.revalidate(); + processModuleCountChanged(myModuleEditors.size() - 1, myModuleEditors.size()); + } + + public void addModule(final ModuleBuilder moduleBuilder) { + final Exception[] ex = new Exception[] {null}; + final Module module = ApplicationManager.getApplication().runWriteAction(new Computable() { + public Module compute() { + try { + return moduleBuilder.createModule(myModuleModel); + } + catch (Exception e) { + ex[0] = e; + return null; + } + } + }); + if (ex[0] != null) { + Messages.showErrorDialog("Error adding module to project: " + ex[0].getMessage(), "Add Module"); + } + if (module != null) { + addModule(module); + } + } + + private ModuleBuilder runModuleWizard(Component dialogParent) { + AddModuleWizard wizard = new AddModuleWizard(dialogParent, myProject, this); + wizard.show(); + if (wizard.isOK()) { + return wizard.getModuleBuilder(); + } + return null; + } + + + private class AddModuleAction extends ModulesConfigurationAction { + private final Component myDialogParent; + + public AddModuleAction(Component dialogParent) { + super("Add", "Add module to the project", IconLoader.getIcon("/actions/include.png")); + myDialogParent = dialogParent; + } + + public void actionPerformed(AnActionEvent e) { + final ModuleBuilder moduleBuilder = runModuleWizard(myDialogParent); + if (moduleBuilder != null) { + addModule(moduleBuilder); + myModuleEditorsList.requestFocus(); + } + } + } + + + private class RemoveModuleAction extends ModulesConfigurationAction { + public RemoveModuleAction() { + super("Remove", "Remove module from the project", IconLoader.getIcon("/actions/exclude.png")); + } + + public void actionPerformed(AnActionEvent e) { + try { + final ModuleEditor selectedEditor = getSelectedEditor(); + String question; + if (myModuleEditors.size() == 1) { + question = "Are you sure you want to remove the only module from this project?\nNo files will be deleted on disk."; + } + else { + question = "Remove module \"" + selectedEditor.getModule().getName() + "\" from the project?\nNo files will be deleted on disk."; + } + int result = Messages.showYesNoDialog(myModuleEditorsList, question, "Remove Module", Messages.getQuestionIcon()); + if (result != 0) { + return; + } + // do remove + myModuleEditors.remove(selectedEditor); + removeModuleEditorUIComponent(selectedEditor); + final DefaultListModel listModel = (DefaultListModel)myModuleEditorsList.getModel(); + final int selectedIndex = myModuleEditorsList.getSelectedIndex(); + listModel.removeElementAt(selectedIndex); + // select another + if (selectedIndex < listModel.getSize()) { + myModuleEditorsList.setSelectedIndex(selectedIndex); + } + else if (listModel.getSize() > 0) { + myModuleEditorsList.setSelectedIndex(0); + } + final ModuleEditor newSelectedEditor = getSelectedEditor(); + final String selectedTabName = selectedEditor.getSelectedTabName(); + showModuleEditor(newSelectedEditor, selectedTabName); + // destroyProcess removed module + final Module moduleToRemove = selectedEditor.getModule(); + // remove all dependencies on the module that is about to be removed + List modifiableRootModels = new ArrayList(); + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + final ModuleEditor moduleEditor = (ModuleEditor)it.next(); + if (moduleToRemove.equals(moduleEditor.getModule())) { + continue; // skip self + } + final ModifiableRootModel modifiableRootModel = moduleEditor.getModifiableRootModelProxy(); + modifiableRootModels.add(modifiableRootModel); + } + // destroyProcess editor + final ModifiableRootModel model = selectedEditor.dispose(); + ModuleDeleteProvider.removeModule(moduleToRemove, model, modifiableRootModels, myModuleModel); + myModuleEditorsList.revalidate(); + processModuleCountChanged(myModuleEditors.size() + 1, myModuleEditors.size()); + } + finally { + myModuleEditorsList.requestFocus(); + } + } + + public void update(AnActionEvent e) { + final ModuleEditor selectedEditor = getSelectedEditor(); + e.getPresentation().setEnabled(selectedEditor != null); + } + } + + private void processModuleCountChanged(int oldCount, int newCount) { + //updateTitle(); + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + ModuleEditor moduleEditor = it.next(); + moduleEditor.moduleCountChanged(oldCount, newCount); + } + } + + public boolean selectModule(String moduleNameToSelect, String tabToSelect) { + final ModuleEditor editor = findModuleEditor(moduleNameToSelect); + if (editor != null) { + showModuleEditor(editor, tabToSelect); + return true; + } + return false; + } + + public void selectFirstModule() { + if (myModuleEditors.size() > 0) { + myModuleEditorsList.setSelectedIndex(0); + } + } + + public boolean isModified() { + if (myModuleModel.isChanged()) { + return true; + } + for (Iterator it = myModuleEditors.iterator(); it.hasNext();) { + ModuleEditor moduleEditor = it.next(); + if (moduleEditor.isModified()) { + return true; + } + } + if (myLanguageLevelCombo != null) { + if (!ProjectRootManagerEx.getInstanceEx(myProject).getLanguageLevel().equals(myLanguageLevelCombo.getSelectedItem())) { + return true; + } + } + if (myRbRelativePaths != null) { + if (((ProjectEx)myProject).isSavePathsRelative() != myRbRelativePaths.isSelected()) { + return true; + } + } + return false; + } + + + public static boolean showDialog(Project project, String moduleToSelect, String tabNameToSelect, boolean startAddModuleWizard) { + return ShowSettingsUtil.getInstance().editConfigurable( + project, DIMENSION_KEY, new ModulesConfigurable(project, moduleToSelect, tabNameToSelect, startAddModuleWizard) + ); + } + + public String getHelpTopic() { + final ModuleEditor selectedEditor = getSelectedEditor(); + if (selectedEditor == null) { + return null; + } + return selectedEditor.getHelpTopic(); + } + + private static class ModulesListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + final JLabel rendererComponent = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + ModuleEditorWrapper moduleEditorWrapper = (ModuleEditorWrapper)value; + final ModuleType moduleType = moduleEditorWrapper.getModuleEditor().getModule().getModuleType(); + rendererComponent.setIcon(IconUtilEx.getModuleTypeIcon(moduleType, 0)); + return rendererComponent; + } + } + + private class MyJPanel extends JPanel { + public MyJPanel() { + super(new GridBagLayout()); + } + + public void addNotify() { + super.addNotify(); + if (myStartModuleWizardOnShow) { + final Window parentWindow = (Window)SwingUtilities.getAncestorOfClass(Window.class, this); + parentWindow.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + parentWindow.removeWindowListener(this); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + final ModuleBuilder moduleBuilder = runModuleWizard(parentWindow); + if (moduleBuilder != null) { + addModule(moduleBuilder); + } + } + }); + } + }); + } + } + } + + private static class MyDefaultListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setText(((LanguageLevel)value).getPresentableText()); + return this; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/MoveTableRowButtonListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/MoveTableRowButtonListener.java new file mode 100644 index 00000000000..c9792104c90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/MoveTableRowButtonListener.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ui.TableUtil; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Eugene Zhuravlev + * Date: May 21, 2004 + */ +class MoveTableRowButtonListener implements ActionListener { + private final int myDelta; + private final JTable myTable; + private final Runnable myOnRowMoveAction; + + public MoveTableRowButtonListener(int delta, JTable table, Runnable onRowMoveAction) { + myDelta = delta; + myTable = table; + myOnRowMoveAction = onRowMoveAction; + } + + public void actionPerformed(ActionEvent e) { + final int moveCount = Math.abs(myDelta); + for (int idx = 0; idx < moveCount; idx++) { + if (myDelta < 0) { + TableUtil.moveSelectedItemsUp(myTable); + } + else { + TableUtil.moveSelectedItemsDown(myTable); + } + } + /* + final int selectedIndex = myTable.getSelectedRow(); + if (selectedIndex < 0) { + return; + } + final DefaultTableModel tableModel = (DefaultTableModel)myTable.getModel(); + final int nextIndex = calcNextIndex(selectedIndex, tableModel.getRowCount(), myDelta); + if (selectedIndex == nextIndex) { + return; + } + tableModel.moveRow(selectedIndex, selectedIndex, nextIndex); + myTable.getSelectionModel().setSelectionInterval(nextIndex, nextIndex); + */ + if (myOnRowMoveAction != null) { + myOnRowMoveAction.run(); + } + myTable.requestFocus(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/NamedLibrariesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/NamedLibrariesPanel.java new file mode 100644 index 00000000000..e4a4bfc2189 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/NamedLibrariesPanel.java @@ -0,0 +1,235 @@ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.ide.util.ElementsChooser; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Oct 28 + * @author 2003 + */ +public class NamedLibrariesPanel extends JPanel { + private final ModifiableRootModel myRootModel; + private final LibraryTable myLibraryTable; + private final ElementsChooser myLibrariesChooser; + private ElementsChooser.ElementsMarkListener myMarkListener; + private final JButton myIncludeAllButton; + private final JButton myExcludeAllButton; + private LibraryTable.Listener myLibrariesUpdateListener; + + public NamedLibrariesPanel(ModifiableRootModel rootModel, LibraryTable libraryTable) { + super(new BorderLayout()); + + myRootModel = rootModel; + myLibraryTable = libraryTable; + myLibrariesUpdateListener = new LibraryTable.Listener() { + public void afterLibraryAdded(Library newLibrary) { + updateChooser(null, true, null); + } + + public void afterLibraryRenamed(Library library) { + updateChooser(null, true, null); + } + + public void beforeLibraryRemoved(Library library) { + } + + public void afterLibraryRemoved(Library library) { + updateChooser(null, true, null); + } + }; + myLibrariesChooser = new ElementsChooser(); + myLibrariesChooser.setColorUnmarkedElements(false); + + myMarkListener = new ElementsChooser.ElementsMarkListener() { + public void elementMarkChanged(LibraryChooserElement libraryElement, boolean isMarked) { + setChooserElementMarked(libraryElement, isMarked); + } + }; + myLibrariesChooser.addElementsMarkListener(myMarkListener); + + final JButton editButton = new JButton("Edit..."); + myIncludeAllButton = new JButton("Include All"); + myExcludeAllButton = new JButton("Exclude All"); + editButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + removeLibraryTableListener(); + try { + final HashSet librariesBeforeEdit = new HashSet(Arrays.asList(myLibraryTable.getLibraries())); + final List selection = new ArrayList(Arrays.asList(convertToLibraries(myLibrariesChooser.getSelectedElements()))); + final boolean isOk = LibraryTableEditor.showEditDialog(editButton, myLibraryTable, selection); + final Set librariesAfterEdit = new HashSet(Arrays.asList(myLibraryTable.getLibraries())); + librariesAfterEdit.removeAll(librariesBeforeEdit); + if (isOk) { + updateChooser(librariesAfterEdit, !isOk, selection); + } + else { + updateChooser(librariesAfterEdit, !isOk, null); + } + } + finally { + attachLibraryTableListener(); + } + } + }); + myIncludeAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myLibrariesChooser.setAllElementsMarked(true); + } + }); + myExcludeAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myLibrariesChooser.setAllElementsMarked(false); + } + }); + + final JPanel buttonsPanel = new JPanel(new GridBagLayout()); + buttonsPanel.add(editButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 5, 0), 0, 0)); + buttonsPanel.add(myIncludeAllButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 5, 0), 0, 0)); + buttonsPanel.add(myExcludeAllButton, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); + + add(myLibrariesChooser, BorderLayout.CENTER); + add(buttonsPanel, BorderLayout.EAST); + + updateChooser(null, false, null); + attachLibraryTableListener(); + } + + private Library[] convertToLibraries(final List selectedElements) { + List libs = new ArrayList(); + for (Iterator it = selectedElements.iterator(); it.hasNext();) { + final LibraryChooserElement chooserElement = (LibraryChooserElement)it.next(); + final Library library = chooserElement.getLibrary(); + if (library != null) { + libs.add(library); + } + } + return libs.toArray(new Library[libs.size()]); + } + + private boolean myListenerAdded = false; + private void attachLibraryTableListener() { + if (!myListenerAdded) { + myLibraryTable.addListener(myLibrariesUpdateListener); + myListenerAdded = true; + } + } + + private void removeLibraryTableListener() { + if (myListenerAdded) { + myLibraryTable.removeListener(myLibrariesUpdateListener); + myListenerAdded = false; + } + } + + private void updateChooser(Set librariesToMark, boolean keepUnmarkedInvalidEntries, Collection librariesToSelect) { + myLibrariesChooser.saveSelection(); + try { + myLibrariesChooser.removeElementsMarkListener(myMarkListener); + final List unmarkedInvalidElems = new ArrayList(); + if (keepUnmarkedInvalidEntries) { + final int count = myLibrariesChooser.getElementCount(); + for (int idx = 0; idx < count; idx++) { + final LibraryChooserElement chooserElement = myLibrariesChooser.getElementAt(idx); + if (!chooserElement.isValid() && !chooserElement.isAttachedToProject()) { + unmarkedInvalidElems.add(chooserElement); + } + } + } + myLibrariesChooser.clear(); + + final List elements = new ArrayList(); + final Library[] libraries = myLibraryTable.getLibraries(); + for (int idx = 0; idx < libraries.length; idx++) { + final Library library = libraries[idx]; + elements.add(new LibraryChooserElement(library, myRootModel.findLibraryOrderEntry(library))); + } + final LibraryOrderEntry[] invalidLibraryOrderEntries = getInvalidLibraryOrderEntries(); + for (int idx = 0; idx < invalidLibraryOrderEntries.length; idx++) { + LibraryOrderEntry entry = invalidLibraryOrderEntries[idx]; + elements.add(new LibraryChooserElement(null, entry)); + } + elements.addAll(unmarkedInvalidElems); + Collections.sort(elements, new Comparator() { + public int compare(LibraryChooserElement elem1, LibraryChooserElement elem2) { + return elem1.getName().compareToIgnoreCase(elem2.getName()); + } + }); + List elementsToSelect = new ArrayList(); + for (Iterator it = elements.iterator(); it.hasNext();) { + LibraryChooserElement chooserElement = (LibraryChooserElement)it.next(); + if (librariesToMark != null && chooserElement.isValid()) { + if (librariesToMark.contains(chooserElement.getLibrary())) { + setChooserElementMarked(chooserElement, true); + } + } + myLibrariesChooser.addElement(chooserElement, chooserElement.isAttachedToProject(), chooserElement.isValid()? LibraryChooserElement.VALID_LIBRARY_ELEMENT_PROPERTIES : LibraryChooserElement.INVALID_LIBRARY_ELEMENT_PROPERTIES); + if (librariesToSelect != null && librariesToSelect.contains(chooserElement.getLibrary())) { + elementsToSelect.add(chooserElement); + } + } + if (elementsToSelect.size() > 0) { + myLibrariesChooser.selectElements(elementsToSelect); + } + + final int elementCount = myLibrariesChooser.getElementCount(); + myIncludeAllButton.setEnabled(elementCount > 0); + myExcludeAllButton.setEnabled(elementCount > 0); + + myLibrariesChooser.addElementsMarkListener(myMarkListener); + } + finally { + if (librariesToSelect == null) { // do not restore previous selection if there is already stuff to select + myLibrariesChooser.restoreSelection(); + } + } + } + + protected void setChooserElementMarked(LibraryChooserElement chooserElement, boolean isMarked) { + if (isMarked) { + if (!chooserElement.isAttachedToProject()) { + final LibraryOrderEntry orderEntry = chooserElement.isValid()? myRootModel.addLibraryEntry(chooserElement.getLibrary()) : myRootModel.addInvalidLibrary(chooserElement.getName(), myLibraryTable.getTableLevel()); + chooserElement.setOrderEntry(orderEntry); + } + } + else { + if (chooserElement.isAttachedToProject()) { + myRootModel.removeOrderEntry(chooserElement.getOrderEntry()); + chooserElement.setOrderEntry(null); + } + } + } + + private LibraryOrderEntry[] getInvalidLibraryOrderEntries() { + final OrderEntry[] orderEntries = myRootModel.getOrderEntries(); + ArrayList entries = new ArrayList(); + for (int idx = 0; idx < orderEntries.length; idx++) { + OrderEntry orderEntry = orderEntries[idx]; + if (orderEntry instanceof LibraryOrderEntry) { + final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry; + if (!libraryOrderEntry.isValid() && libraryOrderEntry.getLibraryLevel().equals(myLibraryTable.getTableLevel())) { + entries.add(libraryOrderEntry); + } + } + } + return entries.toArray(new LibraryOrderEntry[entries.size()]); + } + + public void disposeUIResources() { + removeLibraryTableListener(); + } +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ResizingWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ResizingWrapper.java new file mode 100644 index 00000000000..7dcd71dc026 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ResizingWrapper.java @@ -0,0 +1,18 @@ +/** + * @author cdr + */ +package com.intellij.openapi.roots.ui.configuration; + +import javax.swing.*; +import java.awt.*; + +public class ResizingWrapper extends JComponent { + protected final JComponent myWrappedComponent; + public ResizingWrapper(JComponent wrappedComponent) { + myWrappedComponent = wrappedComponent; + setLayout(new GridBagLayout()); + setOpaque(false); + this.add(wrappedComponent, new GridBagConstraints(0, 0, 1, 1, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + this.add(Box.createHorizontalGlue(), new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ScalableIconComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ScalableIconComponent.java new file mode 100644 index 00000000000..83cfe1a3949 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/ScalableIconComponent.java @@ -0,0 +1,54 @@ +package com.intellij.openapi.roots.ui.configuration; + +import javax.swing.*; +import java.awt.*; +import java.awt.geom.AffineTransform; + +/** + * @author Eugene Zhuravlev + * Date: Oct 29 + * @author 2003 + */ +public class ScalableIconComponent extends JComponent { + private final Icon myIcon; + private final Icon mySelectedIcon; + private boolean myIsSelected = false; + + public ScalableIconComponent(Icon icon) { + this(icon, icon); + } + + public ScalableIconComponent(Icon icon, Icon selectedIcon) { + myIcon = icon; + mySelectedIcon = selectedIcon != null? selectedIcon : icon; + if (icon != null) { + final Dimension size = new Dimension(icon.getIconWidth(), icon.getIconHeight()); + this.setPreferredSize(size); + this.setMinimumSize(size); + } + } + + protected void paintComponent(Graphics g) { + final Icon icon = myIsSelected? mySelectedIcon : myIcon; + if (icon != null) { + final Graphics2D g2 = (Graphics2D)g; + + g2.setBackground(getBackground()); + final AffineTransform savedTransform = g2.getTransform(); + + g2.scale(((double)getWidth()) / icon.getIconWidth(), ((double)getHeight()) / icon.getIconHeight()); + icon.paintIcon(this, g2, 0, 0); + + g2.setTransform(savedTransform); + } + + super.paintComponent(g); + } + + + public final void setSelected(boolean isSelected) { + myIsSelected = isSelected; + this.revalidate(); + this.repaint(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ContentEntryEditingAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ContentEntryEditingAction.java new file mode 100644 index 00000000000..d1fc86b3486 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ContentEntryEditingAction.java @@ -0,0 +1,67 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.actionSystem.impl.ActionButtonWithText; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.fileChooser.FileElement; +import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.ActionToolbarEx; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; + +/** + * @author Eugene Zhuravlev + * Date: Oct 14 + * @author 2003 + * Time: 3:07:14 PM + */ +public abstract class ContentEntryEditingAction extends ToggleAction implements CustomComponentAction{ + protected final JTree myTree; + + protected ContentEntryEditingAction(JTree tree) { + myTree = tree; + getTemplatePresentation().setEnabled(true); + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + presentation.setEnabled(true); + final VirtualFile file = getSelectedFile(); + if (file == null) { + presentation.setEnabled(false); + return; + } + if (!file.isDirectory()) { + presentation.setEnabled(false); + } + } + + protected final VirtualFile getSelectedFile() { + final TreePath selectionPath = myTree.getSelectionPath(); + if (selectionPath == null) { + return null; + } + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPath.getLastPathComponent(); + final Object nodeDescriptor = node.getUserObject(); + if (!(nodeDescriptor instanceof FileNodeDescriptor)) { + return null; + } + final Object element = ((FileNodeDescriptor)nodeDescriptor).getElement(); + if (!(element instanceof FileElement)) { + return null; + } + return ((FileElement)element).getFile(); + } + + public JComponent createCustomComponent(Presentation presentation) { + return new ActionButtonWithText(this, presentation, ActionPlaces.UNKNOWN, ActionToolbarEx.DEFAULT_MINIMUM_BUTTON_SIZE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java new file mode 100644 index 00000000000..1f44fc7c048 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java @@ -0,0 +1,84 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.ide.DeleteProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.ArrayList; +import java.util.List; + +public class ModuleDeleteProvider implements DeleteProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider"); + + public boolean canDeleteElement(DataContext dataContext) { + return dataContext.getData(DataConstantsEx.MODULE_CONTEXT) != null; + } + + public void deleteElement(DataContext dataContext) { + final Module module = ((Module)dataContext.getData(DataConstantsEx.MODULE_CONTEXT)); + + int ret = Messages.showOkCancelDialog("Remove Module '" + module.getName() + "' from the project?" + + "\nNo files will be deleted.", "Remove Module", Messages.getQuestionIcon()); + if (ret != 0) return; + CommandProcessor.getInstance().executeCommand(module.getProject(), new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + removeModule(module); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, "Detach module from project", null); + } + + public static void removeModule(final Module module) { + ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); + ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); + Module[] modules = moduleManager.getModules(); + List otherModuleRootModels = new ArrayList(); + for (int i = 0; i < modules.length; i++) { + final Module otherModule = modules[i]; + if (otherModule == module) continue; + otherModuleRootModels.add(ModuleRootManager.getInstance(otherModule).getModifiableModel()); + } + ModifiableModuleModel modifiableModuleModel = moduleManager.getModifiableModel(); + removeModule(module, modifiableModel, otherModuleRootModels, modifiableModuleModel); + final ModifiableRootModel[] modifiableRootModels = otherModuleRootModels.toArray(new ModifiableRootModel[otherModuleRootModels.size()]); + ProjectRootManager.getInstance(module.getProject()).multiCommit(modifiableModuleModel, modifiableRootModels); + } + + public static void removeModule(final Module moduleToRemove, + ModifiableRootModel modifiableRootModelToRemove, + List otherModuleRootModels, + final ModifiableModuleModel moduleModel) { + // remove all dependencies on the module that is about to be removed + for (int i = 0; i < otherModuleRootModels.size(); i++) { + final ModifiableRootModel modifiableRootModel = otherModuleRootModels.get(i); + final OrderEntry[] orderEntries = modifiableRootModel.getOrderEntries(); + for (int idx = 0; idx < orderEntries.length; idx++) { + final OrderEntry orderEntry = orderEntries[idx]; + if (orderEntry.isValid() && orderEntry instanceof ModuleOrderEntry) { + final Module orderEntryModule = ((ModuleOrderEntry)orderEntry).getModule(); + if (orderEntryModule != null && orderEntryModule.equals(moduleToRemove)) { + modifiableRootModel.removeOrderEntry(orderEntry); + } + } + } + } + // destroyProcess editor + if (modifiableRootModelToRemove != null) { + modifiableRootModelToRemove.dispose(); + } + // destroyProcess module + moduleModel.disposeModule(moduleToRemove); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModulesConfigurationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModulesConfigurationAction.java new file mode 100644 index 00000000000..8f4185d9339 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ModulesConfigurationAction.java @@ -0,0 +1,37 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.actionSystem.impl.ActionButtonWithText; +import com.intellij.openapi.actionSystem.ex.CustomComponentAction; +import com.intellij.openapi.wm.ex.ActionToolbarEx; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Nov 25 + * @author 2003 + */ +public abstract class ModulesConfigurationAction extends AnAction implements CustomComponentAction { + protected ModulesConfigurationAction() { + } + + protected ModulesConfigurationAction(String text) { + super(text); + } + + protected ModulesConfigurationAction(String text, String description, Icon icon) { + super(text, description, icon); + } + + public JComponent createCustomComponent(final Presentation presentation) { + return createCustomComponentImpl(this, presentation); + } + + public static JComponent createCustomComponentImpl(final AnAction action, final Presentation presentation) { + return new ActionButtonWithText(action, presentation, ActionPlaces.UNKNOWN, ActionToolbarEx.DEFAULT_MINIMUM_BUTTON_SIZE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java new file mode 100644 index 00000000000..682c789ab39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java @@ -0,0 +1,92 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.ide.util.projectWizard.AddModuleWizard; +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.components.LoadCancelledException; + +/** + * @author Eugene Zhuravlev + * Date: Jan 5, 2004 + */ +public class NewModuleAction extends AnAction { + public NewModuleAction() { + super("New Module", "Add new module to the project", null); + } + + public void actionPerformed(AnActionEvent e) { + final Project project = getProject(e); + if (project == null) { + return; + } + final AddModuleWizard wizard = new AddModuleWizard(project, new ModulesProvider() { + public Module[] getModules() { + return ModuleManager.getInstance(project).getModules(); + } + + public Module getModule(String name) { + return ModuleManager.getInstance(project).findModuleByName(name); + } + + public ModuleRootModel getRootModel(Module module) { + return ModuleRootManager.getInstance(module); + } + }); + + wizard.show(); + + if (wizard.isOK()) { + final ModuleBuilder moduleBuilder = wizard.getModuleBuilder(); + Exception ex = ApplicationManager.getApplication().runWriteAction(new Computable() { + public Exception compute() { + try { + final ModifiableModuleModel moduleModel = ModuleManager.getInstance(project).getModifiableModel(); + final Module module = moduleBuilder.createModule(moduleModel); + if (module != null) { + moduleModel.commitAssertingNoCircularDependency(); + } + return null; + } + catch (Exception e) { + return e; + } + } + }); + if (ex != null) { + if (ex instanceof LoadCancelledException) { + LoadCancelledException cancelled = (LoadCancelledException)ex; + Messages.showInfoMessage("Creation of module was cancelled by component: " + cancelled.getIssuer().getComponentName() + "\n" + + "Reason is: " + cancelled.getMessage(), + "Module Was Not Created"); + } else { + Messages.showErrorDialog("Error adding module to project: " + ex.getMessage(), "New Module"); + } + } + } + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(getProject(e) != null); + } + + private Project getProject(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + return project; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleExcludedStateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleExcludedStateAction.java new file mode 100644 index 00000000000..851a6616b81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleExcludedStateAction.java @@ -0,0 +1,59 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.ui.configuration.ContentEntryEditor; +import com.intellij.openapi.roots.ui.configuration.ContentEntryTreeEditor; +import com.intellij.openapi.roots.ui.configuration.IconSet; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 14 2003 + */ +public class ToggleExcludedStateAction extends ContentEntryEditingAction { + private final ContentEntryTreeEditor myEntryTreeEditor; + + public ToggleExcludedStateAction(JTree tree, ContentEntryTreeEditor entryEditor) { + super(tree); + myEntryTreeEditor = entryEditor; + final Presentation templatePresentation = getTemplatePresentation(); + templatePresentation.setText("Excluded"); + templatePresentation.setDescription("Include/Exclude directory from module"); + templatePresentation.setIcon(IconSet.EXCLUDE_FOLDER); + } + + public boolean isSelected(AnActionEvent e) { + final VirtualFile selectedFile = getSelectedFile(); + if (selectedFile == null) { + return false; + } + final ContentEntryEditor contentEntryEditor = myEntryTreeEditor.getContentEntryEditor(); + return contentEntryEditor.isExcluded(selectedFile) || contentEntryEditor.isUnderExcludedDirectory(selectedFile); + } + + public void setSelected(AnActionEvent e, boolean isSelected) { + final VirtualFile selectedFile = getSelectedFile(); + final ExcludeFolder excludeFolder = myEntryTreeEditor.getContentEntryEditor().getExcludeFolder(selectedFile); + if (isSelected) { + if (excludeFolder == null) { // not excluded yet + myEntryTreeEditor.getContentEntryEditor().addExcludeFolder(selectedFile); + } + } + else { + if (excludeFolder != null) { + myEntryTreeEditor.getContentEntryEditor().removeExcludeFolder(excludeFolder); + } + } + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + presentation.setText("Excluded"); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java new file mode 100644 index 00000000000..8b0d700273e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java @@ -0,0 +1,77 @@ +package com.intellij.openapi.roots.ui.configuration.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.roots.ui.configuration.ContentEntryEditor; +import com.intellij.openapi.roots.ui.configuration.ContentEntryTreeEditor; +import com.intellij.openapi.roots.ui.configuration.IconSet; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: Oct 14 2003 + */ +public class ToggleSourcesStateAction extends ContentEntryEditingAction { + private final ContentEntryTreeEditor myEntryTreeEditor; + private final boolean myEditTestSources; + + public ToggleSourcesStateAction(JTree tree, ContentEntryTreeEditor entryEditor, boolean editTestSources) { + super(tree); + myEntryTreeEditor = entryEditor; + myEditTestSources = editTestSources; + final Presentation templatePresentation = getTemplatePresentation(); + if (editTestSources) { + templatePresentation.setText("Test Sources"); + templatePresentation.setDescription("Mark directory as a Test Sources root"); + templatePresentation.setIcon(IconSet.TEST_ROOT_FOLDER); + } + else { + templatePresentation.setText("Sources"); + templatePresentation.setDescription("Mark directory as a Sources root"); + templatePresentation.setIcon(IconSet.SOURCE_ROOT_FOLDER); + } + } + + public boolean isSelected(AnActionEvent e) { + final VirtualFile selectedFile = getSelectedFile(); + if (selectedFile == null) { + return false; + } + final ContentEntryEditor contentEntryEditor = myEntryTreeEditor.getContentEntryEditor(); + return myEditTestSources? contentEntryEditor.isTestSource(selectedFile) : contentEntryEditor.isSource(selectedFile); + } + + public void setSelected(AnActionEvent e, boolean isSelected) { + final VirtualFile selectedFile = getSelectedFile(); + if (selectedFile == null) { + return; + } + final ContentEntryEditor contentEntryEditor = myEntryTreeEditor.getContentEntryEditor(); + final SourceFolder sourceFolder = contentEntryEditor.getSourceFolder(selectedFile); + if (isSelected) { + if (sourceFolder == null) { // not marked yet + contentEntryEditor.addSourceFolder(selectedFile, myEditTestSources); + } + else { + if (myEditTestSources? !sourceFolder.isTestSource() : sourceFolder.isTestSource()) { + contentEntryEditor.removeSourceFolder(sourceFolder); + contentEntryEditor.addSourceFolder(selectedFile, myEditTestSources); + } + } + } + else { + if (sourceFolder != null) { // already marked + contentEntryEditor.removeSourceFolder(sourceFolder); + } + } + } + + public void update(AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + presentation.setText(myEditTestSources? "Test Sources" : "Sources"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElement.java new file mode 100644 index 00000000000..1b660a185c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElement.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +class ClassesElement extends LibraryTableTreeContentElement { + private final LibraryElement myParent; + + public ClassesElement(LibraryElement parent) { + myParent = parent; + } + + public LibraryElement getParent() { + return myParent; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClassesElement)) return false; + + final ClassesElement classesElement = (ClassesElement)o; + + if (!myParent.equals(classesElement.myParent)) return false; + + return true; + } + + public int hashCode() { + return myParent.hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElementDescriptor.java new file mode 100644 index 00000000000..e68ea095b56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesElementDescriptor.java @@ -0,0 +1,26 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +class ClassesElementDescriptor extends NodeDescriptor { + private final ClassesElement myElement; + public static final Icon ICON = IconLoader.getIcon("/nodes/compiledClassesFolder.png"); + + public ClassesElementDescriptor(NodeDescriptor parentDescriptor, ClassesElement element) { + super(null, parentDescriptor); + myElement = element; + myOpenIcon = myClosedIcon = ICON; + } + + public boolean update() { + myName = "Classes"; + return false; + } + + public ClassesElement getElement() { + return myElement; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElement.java new file mode 100644 index 00000000000..2c109b3c1fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElement.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.OrderRootType; + + +class ItemElement extends LibraryTableTreeContentElement { + private final Object myParent; + private final Library myLibrary; + private final String myUrl; + private final OrderRootType myRootType; + private boolean myValid; + + public ItemElement(Object parent, Library library, String url, OrderRootType rootType, boolean isValid) { + myParent = parent; + myLibrary = library; + myUrl = url; + myRootType = rootType; + myValid = isValid; + } + + public Object getParent() { + return myParent; + } + + public String getUrl() { + return myUrl; + } + + public boolean isValid() { + return myValid; + } + + public OrderRootType getRootType() { + return myRootType; + } + + public Library getLibrary() { + return myLibrary; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ItemElement)) return false; + + final ItemElement itemElement = (ItemElement)o; + + if (!myLibrary.equals(itemElement.myLibrary)) return false; + if (!myParent.equals(itemElement.myParent)) return false; + if (!myRootType.equals(itemElement.myRootType)) return false; + if (!myUrl.equals(itemElement.myUrl)) return false; + + return true; + } + + public int hashCode() { + int result; + result = myParent.hashCode(); + result = 29 * result + myLibrary.hashCode(); + result = 29 * result + myUrl.hashCode(); + result = 29 * result + myRootType.hashCode(); + return result; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElementDescriptor.java new file mode 100644 index 00000000000..ff19040ea75 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/ItemElementDescriptor.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; + +import java.io.File; +import java.awt.*; + +class ItemElementDescriptor extends NodeDescriptor { + private final ItemElement myElement; + + public ItemElementDescriptor(NodeDescriptor parentDescriptor, ItemElement element) { + super(null, parentDescriptor); + myElement = element; + final String url = myElement.getUrl(); + myName = LibraryTableEditor.getPresentablePath(url).replace('/', File.separatorChar); + myOpenIcon = myClosedIcon = LibraryTableEditor.getIconForUrl(url, element.isValid()); + } + + public boolean update() { + Color color = myElement.isValid()? Color.BLACK : Color.RED; + final boolean changes = !color.equals(myColor); + myColor = color; + return changes; + } + + public ItemElement getElement() { + return myElement; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElement.java new file mode 100644 index 00000000000..2b4c02b86c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElement.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +class JavadocElement extends LibraryTableTreeContentElement { + private final LibraryElement myParent; + + public JavadocElement(LibraryElement parent) { + myParent = parent; + } + + public LibraryElement getParent() { + return myParent; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof JavadocElement)) return false; + + final JavadocElement javadocElement = (JavadocElement)o; + + if (!myParent.equals(javadocElement.myParent)) return false; + + return true; + } + + public int hashCode() { + return myParent.hashCode(); + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElementDescriptor.java new file mode 100644 index 00000000000..4143d0dc909 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavadocElementDescriptor.java @@ -0,0 +1,26 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +class JavadocElementDescriptor extends NodeDescriptor { + private final JavadocElement myElement; + public static final Icon ICON = IconLoader.getIcon("/nodes/javaDocFolder.png"); + + public JavadocElementDescriptor(NodeDescriptor parentDescriptor, JavadocElement element) { + super(null, parentDescriptor); + myElement = element; + myOpenIcon = myClosedIcon = ICON; + } + + public boolean update() { + myName = "JavaDocs"; + return false; + } + + public JavadocElement getElement() { + return myElement; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java new file mode 100644 index 00000000000..35b4bdcfd6d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java @@ -0,0 +1,75 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.vfs.VirtualFile; + +public class LibraryEditor { + private final Library myLibrary; + private String myLibraryName = null; + private Library.ModifiableModel myModel = null; + + public LibraryEditor(Library library) { + myLibrary = library; + } + + public String getName() { + if (myLibraryName != null) { + return myLibraryName; + } + return myLibrary.getName(); + } + + public String[] getUrls(OrderRootType rootType) { + if (myModel != null) { + return myModel.getUrls(rootType); + } + return myLibrary.getUrls(rootType); + } + + public VirtualFile[] getFiles(OrderRootType rootType) { + if (myModel != null) { + return myModel.getFiles(rootType); + } + return myLibrary.getFiles(rootType); + } + + public void setName(String name) { + myLibraryName = name; + getModel().setName(name); + } + + public void addRoot(String url, OrderRootType rootType) { + getModel().addRoot(url, rootType); + } + + public void addRoot(VirtualFile file, OrderRootType rootType) { + getModel().addRoot(file, rootType); + } + + public void removeRoot(String url, OrderRootType rootType) { + while (getModel().removeRoot(url, rootType)) ; + } + + public void commit() { + if (myModel != null) { + myModel.commit(); + myModel = null; + myLibraryName = null; + } + } + + private Library.ModifiableModel getModel() { + if (myModel == null) { + myModel = myLibrary.getModifiableModel(); + } + return myModel; + } + + public boolean hasChanges() { + if (myModel != null) { + return myModel.isChanged(); + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElement.java new file mode 100644 index 00000000000..8d5d87790ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElement.java @@ -0,0 +1,42 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.openapi.roots.libraries.Library; + +class LibraryElement extends LibraryTableTreeContentElement { + private final Library myLibrary; + private final LibraryTableEditor myParentEditor; + + public LibraryElement(Library library, LibraryTableEditor parentEditor) { + myLibrary = library; + myParentEditor = parentEditor; + } + + public Library getLibrary() { + return myLibrary; + } + + public boolean isAnonymous() { + final String name = myParentEditor.getLibraryEditor(myLibrary).getName(); + return name == null; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LibraryElement)) { + return false; + } + + final LibraryElement libraryElement = (LibraryElement)o; + + + if (!myLibrary.equals(libraryElement.myLibrary)) { + return false; + } + + return true; + } + + public int hashCode() { + return myLibrary.hashCode(); + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElementDescriptor.java new file mode 100644 index 00000000000..61721d38bfa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryElementDescriptor.java @@ -0,0 +1,62 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Icons; + +import javax.swing.*; +import java.io.File; + + +class LibraryElementDescriptor extends NodeDescriptor { + private final LibraryElement myElement; + private final LibraryTableEditor myParentEditor; + + public LibraryElementDescriptor(NodeDescriptor parentDescriptor, LibraryElement element, LibraryTableEditor parentEditor) { + super(null, parentDescriptor); + myElement = element; + myParentEditor = parentEditor; + } + + public boolean update() { + final Library library = myElement.getLibrary(); + final String name; + final Icon icon; + if (myElement.isAnonymous()) { + final VirtualFile[] files = myParentEditor.getLibraryEditor(library).getFiles(OrderRootType.CLASSES); + if (files.length > 0) { + name = files[0].getPresentableUrl(); + icon = LibraryTableEditor.getIconForUrl(files[0].getUrl(), true); + } + else { + final String[] urls = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.CLASSES); + if (urls.length > 0) { + final String url = urls[0]; + name = LibraryTableEditor.getPresentablePath(url).replace('/', File.separatorChar); + icon = LibraryTableEditor.getIconForUrl(url, false); + } + else { + name = ""; // the library is anonymous, library.getName() == null + icon = Icons.LIBRARY_ICON; + } + } + } + else { + name = myParentEditor.getLibraryEditor(library).getName(); + icon = Icons.LIBRARY_ICON; + } + final boolean changed = !name.equals(myName) || !icon.equals(myClosedIcon); + if (changed) { + myName = name; + myClosedIcon = myOpenIcon = icon; + } + return changed; + } + + public LibraryElement getElement() { + return myElement; + } + } + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryFileChooser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryFileChooser.java new file mode 100644 index 00000000000..16f046674e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryFileChooser.java @@ -0,0 +1,145 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; +import com.intellij.ui.FieldPanel; + +import javax.swing.*; +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.event.TreeSelectionEvent; +import java.awt.*; + +class LibraryFileChooser extends FileChooserDialogImpl { + private JTextField myNameField; + private final boolean myInputName; + private final LibraryTableEditor myParentEditor; + private boolean myNameChangedByUser = false; + + public LibraryFileChooser(FileChooserDescriptor chooserDescriptor, + Component parent, + boolean inputName, + LibraryTableEditor parentEditor) { + super(chooserDescriptor, parent); + myInputName = inputName; + myParentEditor = parentEditor; + } + + public String getName() { + if (myNameField != null) { + final String name = myNameField.getText().trim(); + return name.length() > 0 ? name : null; + } + return null; + } + + private void setName(String name) { + if (myNameField != null) { + final boolean savedValue = myNameChangedByUser; + try { + myNameField.setText(name); + } + finally { + myNameChangedByUser = savedValue; + } + } + } + + public JComponent getPreferredFocusedComponent() { + return myInputName ? myNameField : super.getPreferredFocusedComponent(); + } + + protected JComponent createCenterPanel() { + final JComponent centerPanel = super.createCenterPanel(); + if (!myInputName) { + return centerPanel; + } + + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(centerPanel, BorderLayout.CENTER); + + final FieldPanel fieldPanel = FieldPanel.create("Library name:", null); + fieldPanel.getFieldLabel().setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + myNameField = fieldPanel.getTextField(); + myNameField.getDocument().addDocumentListener(new DocumentListener() { + public void changedUpdate(DocumentEvent e) { + myNameChangedByUser = true; + } + + public void insertUpdate(DocumentEvent e) { + myNameChangedByUser = true; + } + + public void removeUpdate(DocumentEvent e) { + myNameChangedByUser = true; + } + }); + panel.add(fieldPanel, BorderLayout.NORTH); + + myFileSystemTree.getTree().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + if (myNameField == null || myNameChangedByUser) { + return; + } + final VirtualFile[] selectedFiles = getSelectedFiles(); + setName(selectedFiles.length == 1 ? selectedFiles[0].getNameWithoutExtension() : ""); + } + }); + return panel; + } + + protected void doOKAction() { + if (!validateData()) { + return; + } + + super.doOKAction(); + } + + private boolean validateData() { + JComponent componentToFocus = null; + try { + final VirtualFile[] chosenFiles = getSelectedFiles(); + if (chosenFiles != null && chosenFiles.length > 0) { + if (myInputName) { + final String name = getName(); + if (name == null) { + Messages.showErrorDialog(myNameField, "Please enter library name", "Library Name Not Specified"); + componentToFocus = myNameField; + return false; + } + if (myParentEditor.libraryAlreadyExists(name)) { + Messages.showErrorDialog(myNameField, "Library \"" + name + "\" already exists", "Library Already Exists"); + componentToFocus = myNameField; + return false; + } + } + } + else { + Messages.showErrorDialog("Please select files or directories to be added to the library", "Library Files Not Selected"); + componentToFocus = myFileSystemTree.getTree(); + return false; + } + return true; + } + finally { + if (componentToFocus != null) { + final JComponent _componentToFocus = componentToFocus; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + _componentToFocus.requestFocus(); + } + }); + } + } + } + + public Pair chooseNameAndFiles() { + VirtualFile[] chosenFiles = choose(null, null); + return new Pair(getName(), chosenFiles); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java new file mode 100644 index 00000000000..29ac09b0193 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java @@ -0,0 +1,781 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.IconUtilEx; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.projectRoots.ui.Util; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.ex.http.HttpFileSystem; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Icons; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.*; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: Jan 11, 2004 + */ +public class LibraryTableEditor { + static final UrlComparator ourUrlComparator = new UrlComparator(); + + private JPanel myPanel; + private JButton myAddLibraryButton; + private JButton myRemoveButton; + private JButton myRenameLibraryButton; + private JButton myAttachClassesButton; + private JButton myAttachSourcesButton; + private JButton myAttachJavadocsButton; + private JButton myAttachUrlJavadocsButton; + private JPanel myTreePanel; + private Tree myTree; + private Map myLibraryToEditorMap = new HashMap(); + + private final LibraryTableModifiableModelProvider myLibraryTable; + private final boolean myEditingModuleLibraries; + private LibraryTableTreeBuilder myTreeBuilder; + private LibraryTable.ModifiableModel myTableModifiableModel; + private static final Icon INVALID_ITEM_ICON = IconLoader.getIcon("/nodes/ppInvalid.png"); + + private LibraryTableEditor(final LibraryTable libraryTable) { + this(new LibraryTableModifiableModelProvider() { + public LibraryTable.ModifiableModel getModifiableModel() { + return libraryTable.getModifiableModel(); + } + + public String getTableLevel() { + return libraryTable.getTableLevel(); + } + }); + } + + public static LibraryTableEditor editLibraryTable(LibraryTableModifiableModelProvider provider){ + LibraryTableEditor result = new LibraryTableEditor(provider); + result.init(new LibraryTableTreeStructure(result)); + return result; + } + + public static LibraryTableEditor editLibraryTable(LibraryTable libraryTable){ + LibraryTableEditor result = new LibraryTableEditor(libraryTable); + result.init(new LibraryTableTreeStructure(result)); + return result; + } + + public static LibraryTableEditor editLibrary(LibraryTableModifiableModelProvider provider, Library library){ + LibraryTableEditor result = new LibraryTableEditor(provider); + result.init(new LibraryTreeStructure(result, library)); + result.myAddLibraryButton.setVisible(false); + result.myRenameLibraryButton.setVisible(false); + return result; + } + + public static LibraryTableEditor create(final LibraryTable libraryTable){ + LibraryTableEditor result = new LibraryTableEditor(libraryTable); + result.init(new LibraryTableTreeStructure(result)); + return result; + } + + private LibraryTableEditor(LibraryTableModifiableModelProvider provider){ + myLibraryTable = provider; + myTableModifiableModel = myLibraryTable.getModifiableModel(); + final String tableLevel = provider.getTableLevel(); + myEditingModuleLibraries = LibraryTableImplUtil.MODULE_LEVEL.equals(tableLevel); + } + + private void init(AbstractTreeStructure treeStructure) { + myTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode())); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + new MyTreeSpeedSearch(myTree); + myTree.setCellRenderer(new LibraryTreeRenderer()); + final MyTreeSelectionListener treeSelectionListener = new MyTreeSelectionListener(); + myTree.getSelectionModel().addTreeSelectionListener(treeSelectionListener); + myTreeBuilder = new LibraryTableTreeBuilder(myTree, (DefaultTreeModel)myTree.getModel(), treeStructure); + myTreePanel.setLayout(new BorderLayout()); + myTreePanel.add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER); + + myAddLibraryButton.setText(myEditingModuleLibraries? "Add Jar/Directory..." : "Create Library..."); + myAddLibraryButton.setMnemonic(myEditingModuleLibraries? 'J' : 'L'); + myAddLibraryButton.addActionListener(new AddLibraryAction()); + myRemoveButton.addActionListener(new RemoveAction()); + myRemoveButton.setMnemonic('R'); + myRenameLibraryButton.setMnemonic('e'); + if (myEditingModuleLibraries) { + myAttachClassesButton.setVisible(false); + myRenameLibraryButton.setVisible(false); + } + else { + myRenameLibraryButton.setVisible(true); + myRenameLibraryButton.addActionListener(new RenameLibraryAction()); + myAttachClassesButton.setVisible(true); + myAttachClassesButton.setMnemonic('C'); + myAttachClassesButton.addActionListener(new AttachClassesAction()); + } + myAttachSourcesButton.addActionListener(new AttachSourcesAction()); + myAttachSourcesButton.setMnemonic('S'); + myAttachJavadocsButton.addActionListener(new AttachJavadocAction()); + myAttachJavadocsButton.setMnemonic('J'); + myAttachUrlJavadocsButton.addActionListener(new AttachUrlJavadocAction()); + myAttachUrlJavadocsButton.setMnemonic('U'); + + treeSelectionListener.updateButtons(); + } + + public JComponent getComponent() { + return myPanel; + } + + public static boolean showEditDialog(final Component parent, LibraryTable libraryTable, final Collection selection) { + final LibraryTableEditor libraryTableEditor = LibraryTableEditor.editLibraryTable(libraryTable); + final MyDialogWrapper dialogWrapper = libraryTableEditor.new MyDialogWrapper(parent); + if (selection != null) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + for (Iterator iterator = selection.iterator(); iterator.hasNext();) { + final Library library = iterator.next(); + libraryTableEditor.selectLibrary(library, true); + } + } + }, ModalityState.stateForComponent(dialogWrapper.getContentPane())); + } + dialogWrapper.show(); + final boolean ok = dialogWrapper.isOK(); + if (selection != null && ok) { + selection.clear(); + selection.addAll(Arrays.asList(libraryTableEditor.getSelectedLibraries())); + } + return ok; + } + + public void selectLibrary(Library library, boolean expand) { + LibraryTableTreeContentElement element = new LibraryElement(library, this); + myTreeBuilder.buildNodeForElement(element); + DefaultMutableTreeNode node = myTreeBuilder.getNodeForElement(element); + if (node == null) { + return; + } + myTree.requestFocus(); + final TreePath treePath = new TreePath(node.getPath()); + TreeUtil.selectPath(myTree, treePath); + if (expand) { + myTree.expandPath(treePath); + } + } + + public void disableAttachButtons() { + myAttachJavadocsButton.setVisible(false); + myAttachSourcesButton.setVisible(false); + myAttachUrlJavadocsButton.setVisible(false); + } + + + public LibraryEditor getLibraryEditor(Library library) { + LibraryEditor libraryEditor = myLibraryToEditorMap.get(library); + if (libraryEditor == null) { + libraryEditor = new LibraryEditor(library); + myLibraryToEditorMap.put(library, libraryEditor); + } + return libraryEditor; + } + + private void removeLibrary(Library library) { + myLibraryToEditorMap.remove(library); + myTableModifiableModel.removeLibrary(library); + } + + /** + * Should call this method in order to commit all the changes that were done by the editor + */ + public void commitChanges() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (Iterator it = myLibraryToEditorMap.keySet().iterator(); it.hasNext();) { + Library library = it.next(); + final LibraryEditor libraryEditor = myLibraryToEditorMap.get(library); + libraryEditor.commit(); + } + myTableModifiableModel.commit(); + } + }); + myTableModifiableModel = myLibraryTable.getModifiableModel(); + myLibraryToEditorMap.clear(); + } + + public void cancelChanges() { + + myLibraryToEditorMap.clear(); + } + + public boolean hasChanges() { + if (myTableModifiableModel.isChanged()) { + return true; + } + for (Iterator it = myLibraryToEditorMap.keySet().iterator(); it.hasNext();) { + final LibraryEditor libraryEditor = myLibraryToEditorMap.get(it.next()); + if (libraryEditor.hasChanges()) { + return true; + } + } + return false; + } + + public Library[] getLibraries() { + return myTableModifiableModel.getLibraries(); + } + + private Object getSelectedElement() { + final TreePath selectionPath = myTreeBuilder.getTree().getSelectionPath(); + return getPathElement(selectionPath); + } + + private Object[] getSelectedElements() { + final TreePath[] selectionPaths = myTreeBuilder.getTree().getSelectionPaths(); + if (selectionPaths == null) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + List elements = new ArrayList(); + for (int idx = 0; idx < selectionPaths.length; idx++) { + TreePath selectionPath = selectionPaths[idx]; + final Object pathElement = getPathElement(selectionPath); + if (pathElement != null) { + elements.add(pathElement); + } + } + return elements.toArray(new Object[elements.size()]); + } + + private Object getPathElement(final TreePath selectionPath) { + if (selectionPath == null) { + return null; + } + final DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode)selectionPath.getLastPathComponent(); + if (lastPathComponent == null) { + return null; + } + final Object userObject = lastPathComponent.getUserObject(); + if (!(userObject instanceof NodeDescriptor)) { + return null; + } + final Object element = ((NodeDescriptor)userObject).getElement(); + if (!(element instanceof LibraryTableTreeContentElement)) { + return null; + } + return element; + } + + private Library getSelectedLibrary() { + return convertElementToLibrary(getSelectedElement()); + } + + private Library[] getSelectedLibraries() { + final List libs = new ArrayList(); + final Object[] selectedElements = getSelectedElements(); + for (int idx = 0; idx < selectedElements.length; idx++) { + final Library library = convertElementToLibrary(selectedElements[idx]); + if (library != null) { + libs.add(library); + } + } + return libs.toArray(new Library[libs.size()]); + } + + private Library convertElementToLibrary(Object selectedElement) { + LibraryElement libraryElement = null; + if (selectedElement instanceof LibraryElement) { + libraryElement = (LibraryElement)selectedElement; + } + else if (selectedElement instanceof ItemElement) { + selectedElement = ((ItemElement)selectedElement).getParent(); + } + if (selectedElement instanceof ClassesElement) { + libraryElement = ((ClassesElement)selectedElement).getParent(); + } + else if (selectedElement instanceof SourcesElement) { + libraryElement = ((SourcesElement)selectedElement).getParent(); + } + else if (selectedElement instanceof JavadocElement) { + libraryElement = ((JavadocElement)selectedElement).getParent(); + } + return libraryElement != null? libraryElement.getLibrary() : null; + } + + public void renameLibrary(Library library, String newName) { + if (library == null) { + return; + } + final LibraryEditor libraryEditor = getLibraryEditor(library); + if (newName != null) { + libraryEditor.setName(newName); + } + librariesChanged(); + + } + + private class AddLibraryAction implements ActionListener { + private final FileChooserDescriptor myFileChooserDescriptor = new FileChooserDescriptor(false, true, true, false, false, true); + + public AddLibraryAction() { + myFileChooserDescriptor.setTitle("Choose Library Classes"); + myFileChooserDescriptor.setDescription("Select jars or directories in which library classes can be found"); + } + + public void actionPerformed(ActionEvent e) { + final VirtualFile[] files; + final String name; + if (myEditingModuleLibraries) { + final Pair pair = new LibraryFileChooser(myFileChooserDescriptor, myPanel, false, LibraryTableEditor.this).chooseNameAndFiles(); + files = filterAlreadyAdded(null, pair.getSecond(), OrderRootType.CLASSES); + name = null; + } + else { + final Pair pair = new LibraryFileChooser(myFileChooserDescriptor, myPanel, true, LibraryTableEditor.this).chooseNameAndFiles(); + files = pair.getSecond(); + name = pair.getFirst(); + } + if (files == null || files.length == 0) { + return; + } + final Library[] libraryToSelect = new Library[] {null}; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + if (myEditingModuleLibraries) { + for (int idx = 0; idx < files.length; idx++) { + VirtualFile file = files[idx]; + final Library library = myTableModifiableModel.createLibrary(null); + getLibraryEditor(library).addRoot(file, OrderRootType.CLASSES); + libraryToSelect[0] = library; + } + commitChanges(); + } + else { + final Library library = myTableModifiableModel.createLibrary(name); + final LibraryEditor libraryEditor = getLibraryEditor(library); + for (int i = 0; i < files.length; i++) { + libraryEditor.addRoot(files[i], OrderRootType.CLASSES); + } + libraryToSelect[0] = library; + } + } + }); + librariesChanged(); + if (libraryToSelect[0] != null) { + selectLibrary(libraryToSelect[0], false); + } + } + } + + private abstract class AttachItemAction implements ActionListener { + private final FileChooserDescriptor myDescriptor; + + protected abstract String getTitle(); + protected abstract String getDescription(); + protected abstract OrderRootType getRootType(); + + protected AttachItemAction() { + myDescriptor = createDescriptor(); + } + + protected FileChooserDescriptor createDescriptor() { + return new FileChooserDescriptor(false, true, true, false, true, true); + } + + public final void actionPerformed(ActionEvent e) { + final Library library = getSelectedLibrary(); + if (library != null) { + myDescriptor.setTitle(getTitle()); + myDescriptor.setTitle(getDescription()); + attachFiles(library, FileChooser.chooseFiles(myPanel, myDescriptor), getRootType()); + } + myTree.requestFocus(); + } + } + + private void attachFiles(final Library library, final VirtualFile[] files, final OrderRootType rootType) { + final VirtualFile[] filesToAttach = filterAlreadyAdded(library, files, rootType); + if (filesToAttach.length > 0) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final LibraryEditor libraryEditor = getLibraryEditor(library); + for (int i = 0; i < filesToAttach.length; i++) { + libraryEditor.addRoot(filesToAttach[i], rootType); + } + if (myEditingModuleLibraries) { + commitChanges(); + } + } + }); + myTreeBuilder.updateFromRoot(); + } + } + + private VirtualFile[] filterAlreadyAdded(Library lib, VirtualFile[] files, final OrderRootType rootType) { + if (files == null || files.length == 0) { + return VirtualFile.EMPTY_ARRAY; + } + final Set chosenFilesSet = new HashSet(Arrays.asList(files)); + final Set alreadyAdded = new HashSet(); + if (lib == null) { + final Library[] libraries = myTableModifiableModel.getLibraries(); + for (int idx = 0; idx < libraries.length; idx++) { + final VirtualFile[] libraryFiles = getLibraryEditor(libraries[idx]).getFiles(rootType); + for (int i = 0; i < libraryFiles.length; i++) { + alreadyAdded.add(libraryFiles[i]); + } + } + } + else { + final VirtualFile[] libraryFiles = getLibraryEditor(lib).getFiles(rootType); + for (int i = 0; i < libraryFiles.length; i++) { + alreadyAdded.add(libraryFiles[i]); + } + } + chosenFilesSet.removeAll(alreadyAdded); + return chosenFilesSet.toArray(new VirtualFile[chosenFilesSet.size()]); + } + + private class AttachClassesAction extends AttachItemAction { + protected FileChooserDescriptor createDescriptor() { + return new FileChooserDescriptor(false, true, true, false, false, true); + } + + protected String getTitle() { + final Library selectedLibrary = getSelectedLibrary(); + String title = "Attach Classes"; + if (selectedLibrary != null) { + title += "to Library \"" + getLibraryEditor(selectedLibrary).getName() + "\""; + } + return title; + } + + protected String getDescription() { + return "Select jar/zip files or directories in which library classes are located"; + } + + protected OrderRootType getRootType() { + return OrderRootType.CLASSES; + } + } + + private class AttachSourcesAction extends AttachItemAction { + protected String getTitle() { + return "Attach Sources"; + } + + protected String getDescription() { + return "Select jar/zip files or directories in which library sources are located"; + } + + protected OrderRootType getRootType() { + return OrderRootType.SOURCES; + } + } + + private class AttachJavadocAction extends AttachItemAction { + protected String getTitle() { + return "Attach Javadoc"; + } + + protected String getDescription() { + return "Select jar/zip files or directories in which library javadoc documentation is located"; + } + + protected OrderRootType getRootType() { + return OrderRootType.JAVADOC; + } + } + + private class AttachUrlJavadocAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + final Library library = getSelectedLibrary(); + if (library != null) { + final VirtualFile vFile = Util.showSpecifyJavadocUrlDialog(myPanel); + if (vFile != null) { + attachFiles(library, new VirtualFile[] {vFile}, OrderRootType.JAVADOC); + } + } + myTree.requestFocus(); + } + } + + private class RemoveAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + final Object[] selectedElements = getSelectedElements(); + if (selectedElements.length == 0) { + return; + } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (int idx = 0; idx < selectedElements.length; idx++) { + Object selectedElement = selectedElements[idx]; + if (selectedElement instanceof LibraryElement) { + // todo: any confirmation on library remove? + removeLibrary(((LibraryElement)selectedElement).getLibrary()); + } + else if (selectedElement instanceof ItemElement) { + final ItemElement itemElement = ((ItemElement)selectedElement); + final Library library = itemElement.getLibrary(); + getLibraryEditor(library).removeRoot(itemElement.getUrl(), itemElement.getRootType()); + } + } + if (myEditingModuleLibraries) { + commitChanges(); + } + } + }); + librariesChanged(); + } + + } + + protected void librariesChanged() { + myTreeBuilder.updateFromRoot(); + myTree.requestFocus(); + } + + private class RenameLibraryAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + final Library selectedLibrary = getSelectedLibrary(); + if (selectedLibrary == null) { + return; + } + final LibraryEditor libraryEditor = getLibraryEditor(selectedLibrary); + final String currentName = selectedLibrary.getName(); + final String newName = Messages.showInputDialog(myTree, "Enter new library name", "Rename library \"" + libraryEditor.getName() + "\"", Messages.getQuestionIcon(), libraryEditor.getName(), new InputValidator() { + public boolean checkInput(String inputString) { + return true; + } + public boolean canClose(String libraryName) { + if (!currentName.equals(libraryName)) { + if (libraryAlreadyExists(libraryName)) { + Messages.showErrorDialog("Library \"" + libraryName + "\" already exists", "Library Already Exists"); + return false; + } + } + return true; + } + }); + if (newName != null) { + libraryEditor.setName(newName); + } + librariesChanged(); + } + + } + + boolean libraryAlreadyExists(String libraryName) { + for (Iterator it = myTableModifiableModel.getLibraryIterator(); it.hasNext(); ) { + final Library lib = (Library)it.next(); + final LibraryEditor editor = myLibraryToEditorMap.get(lib); + final String libName = (editor != null)? editor.getName() : lib.getName(); + if (libraryName.equals(libName)) { + return true; + } + } + return false; + } + + private class MyDialogWrapper extends DialogWrapper { + + public MyDialogWrapper(final Component parent) { + super(parent, true); + String levelName = ""; + final String tableLevel = LibraryTableEditor.this.myLibraryTable.getTableLevel(); + if (tableLevel == LibraryTablesRegistrar.PROJECT_LEVEL) { + levelName = "Project "; + } + else if (tableLevel == LibraryTablesRegistrar.APPLICATION_LEVEL) { + levelName = "Global "; + } + setTitle("Configure " + levelName + "Libraries"); + init(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor.MyDialogWrapper"; + } + + public JComponent getPreferredFocusedComponent() { + return myTree; + } + + protected void doOKAction() { + commitChanges(); + super.doOKAction(); + } + + public void doCancelAction() { + cancelChanges(); + super.doCancelAction(); + } + + protected JComponent createCenterPanel() { + return LibraryTableEditor.this.getComponent(); + } + } + + + + private class MyTreeSelectionListener implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent e) { + updateButtons(); + } + + public void updateButtons() { + final Object[] selectedElements = getSelectedElements(); + final Class elementsClass = getElementsClass(selectedElements); + myRemoveButton.setEnabled( + elementsClass != null && + !(elementsClass.isAssignableFrom(ClassesElement.class) || elementsClass.equals(SourcesElement.class) || elementsClass.isAssignableFrom(JavadocElement.class)) + ); + myRenameLibraryButton.setEnabled(selectedElements.length == 1 && elementsClass != null && elementsClass.equals(LibraryElement.class)); + if (elementsClass != null && elementsClass.isAssignableFrom(ItemElement.class)) { + myRemoveButton.setText("Detach"); + myRemoveButton.setMnemonic('D'); + } + else { + myRemoveButton.setText("Remove"); + myRemoveButton.setMnemonic('R'); + } + boolean attachActionsEnabled = selectedElements.length == 1; + myAttachClassesButton.setEnabled(attachActionsEnabled); + myAttachJavadocsButton.setEnabled(attachActionsEnabled); + myAttachUrlJavadocsButton.setEnabled(attachActionsEnabled); + myAttachSourcesButton.setEnabled(attachActionsEnabled); + } + + private Class getElementsClass(Object[] elements) { + if (elements.length == 0) { + return null; + } + Class cls = null; + for (int idx = 0; idx < elements.length; idx++) { + Object element = elements[idx]; + if (cls == null) { + cls = element.getClass(); + } + else { + if (!cls.equals(element.getClass())) { + return null; + } + } + } + return cls; + } + } + + + + static Icon getIconForUrl(final String url, final boolean isValid) { + final Icon icon; + if (isValid) { + VirtualFile presentableFile; + if (isJarFileRoot(url)) { + presentableFile = LocalFileSystem.getInstance().findFileByPath(getPresentablePath(url)); + } + else { + presentableFile = VirtualFileManager.getInstance().findFileByUrl(url); + } + if (presentableFile != null && presentableFile.isValid()) { + if (presentableFile.getFileSystem() instanceof HttpFileSystem) { + icon = Icons.WEB_ICON; + } + else { + icon = presentableFile.isDirectory()? Icons.DIRECTORY_CLOSED_ICON : IconUtilEx.getIcon(presentableFile, 0, null); + } + } + else { + icon = INVALID_ITEM_ICON; + } + } + else { + icon = INVALID_ITEM_ICON; + } + return icon; + } + + static String getPresentablePath(final String url) { + String presentablePath = VirtualFileManager.extractPath(url); + if (isJarFileRoot(url)) { + presentablePath = presentablePath.substring(0, presentablePath.length() - JarFileSystem.JAR_SEPARATOR.length()); + } + return presentablePath; + } + + private static boolean isJarFileRoot(final String url) { + return VirtualFileManager.extractPath(url).endsWith(JarFileSystem.JAR_SEPARATOR); + } + + private static class MyTreeSpeedSearch extends TreeSpeedSearch { + public MyTreeSpeedSearch(final Tree tree) { + super(tree); + } + + public boolean isMatchingElement(Object element, String pattern) { + Object userObject = ((DefaultMutableTreeNode)((TreePath)element).getLastPathComponent()).getUserObject(); + if (userObject instanceof ItemElementDescriptor || userObject instanceof LibraryElementDescriptor) { + String str = getElementText(element); + if (str == null) { + return false; + } + if (!hasCapitals(pattern)) { // be case-sensitive only if user types capitals + str = str.toLowerCase(); + } + if (pattern.indexOf(File.separator) >= 0) { + return compare(str,pattern); + } + final StringTokenizer tokenizer = new StringTokenizer(str, File.separator); + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken(); + if (compare(token,pattern)) { + return true; + } + } + return false; + } + else { + return super.isMatchingElement(element, pattern); + } + } + + private boolean hasCapitals(String str) { + for (int idx = 0; idx < str.length(); idx++) { + if (Character.isUpperCase(str.charAt(idx))) { + return true; + } + } + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeBuilder.java new file mode 100644 index 00000000000..57f46992bc5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeBuilder.java @@ -0,0 +1,27 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.IndexComparator; +import com.intellij.ide.util.treeView.NodeDescriptor; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; + +class LibraryTableTreeBuilder extends AbstractTreeBuilder { + public LibraryTableTreeBuilder(JTree tree, DefaultTreeModel treeModel, AbstractTreeStructure treeStructure) { + super(tree, treeModel, treeStructure, IndexComparator.INSTANCE); + initRootNode(); + } + + protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) { + return false; + } + + protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { + final Object element = nodeDescriptor.getElement(); + final Object rootElement = getTreeStructure().getRootElement(); + return rootElement.equals(element) || (element instanceof ClassesElement) || (element instanceof SourcesElement) || + (element instanceof JavadocElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeContentElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeContentElement.java new file mode 100644 index 00000000000..bd0e398367c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeContentElement.java @@ -0,0 +1,5 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +abstract class LibraryTableTreeContentElement { + // empty, just to serve as a base for all tree structure elements +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeStructure.java new file mode 100644 index 00000000000..920cc560673 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableTreeStructure.java @@ -0,0 +1,154 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.LibrariesAlphaComparator; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; + +import java.util.*; + +class LibraryTableTreeStructure extends AbstractTreeStructure { + private final Object myRootElement = new Object(); + private NodeDescriptor myRootElementDescriptor; + private final LibraryTableEditor myParentEditor; + + public LibraryTableTreeStructure(LibraryTableEditor result) { + myParentEditor = result; + myRootElementDescriptor = new NodeDescriptor(null, null) { + public boolean update() { + myName = "Root"; + return false; + } + public Object getElement() { + return myRootElement; + } + }; + } + + public Object getRootElement() { + return myRootElement; + } + + public Object[] getChildElements(Object element) { + if (element == myRootElement) { + final Library[] libraries = myParentEditor.getLibraries(); + Arrays.sort(libraries, LibrariesAlphaComparator.INSTANCE); + LibraryElement[] elements = new LibraryElement[libraries.length]; + for (int idx = 0; idx < libraries.length; idx++) { + elements[idx] = new LibraryElement(libraries[idx], myParentEditor); + } + return elements; + } + + if (element instanceof LibraryElement) { + final LibraryElement libraryItemElement = (LibraryElement)element; + ArrayList elements = new ArrayList(3); + final Library library = libraryItemElement.getLibrary(); + + if (!libraryItemElement.isAnonymous()) { + elements.add(new ClassesElement(libraryItemElement)); + } + + final String[] sources = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.SOURCES); + if (sources.length > 0) { + elements.add(new SourcesElement(libraryItemElement)); + } + + final String[] javadocs = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.JAVADOC); + if (javadocs.length > 0) { + elements.add(new JavadocElement(libraryItemElement)); + } + return elements.toArray(); + } + + if (element instanceof ClassesElement) { + return buildItems(element, ((ClassesElement)element).getParent().getLibrary(), OrderRootType.CLASSES); + } + + if (element instanceof SourcesElement) { + return buildItems(element, ((SourcesElement)element).getParent().getLibrary(), OrderRootType.SOURCES); + } + + if (element instanceof JavadocElement) { + return buildItems(element, ((JavadocElement)element).getParent().getLibrary(), OrderRootType.JAVADOC); + } + + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + private Object[] buildItems(Object parent, Library library, OrderRootType orderRootType) { + final VirtualFile[] files = myParentEditor.getLibraryEditor(library).getFiles(orderRootType); + final Set validUrls; + if (files.length > 0) { + validUrls = new HashSet(); + for (int idx = 0; idx < files.length; idx++) { + validUrls.add(files[idx].getUrl()); + } + } + else { + validUrls = Collections.EMPTY_SET; + } + ArrayList items = new ArrayList(); + + + final String[] urls = myParentEditor.getLibraryEditor(library).getUrls(orderRootType); + Arrays.sort(urls, myParentEditor.ourUrlComparator); + for (int idx = 0; idx < urls.length; idx++) { + String url = urls[idx]; + items.add(new ItemElement(parent, library, url, orderRootType, validUrls.contains(url))); + } + + return items.toArray(); + } + + public Object getParentElement(Object element) { + if (element == myRootElement) { + return null; + } + if (element instanceof ClassesElement) { + return ((ClassesElement)element).getParent(); + } + if (element instanceof SourcesElement) { + return ((SourcesElement)element).getParent(); + } + if (element instanceof JavadocElement) { + return ((JavadocElement)element).getParent(); + } + if (element instanceof ItemElement) { + return ((ItemElement)element).getParent(); + } + return myRootElement; + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + if (element == myRootElement) { + return myRootElementDescriptor; + } + if (element instanceof LibraryElement) { + return new LibraryElementDescriptor(parentDescriptor, (LibraryElement)element, myParentEditor); + } + if (element instanceof ClassesElement) { + return new ClassesElementDescriptor(parentDescriptor, (ClassesElement)element); + } + if (element instanceof SourcesElement) { + return new SourcesElementDescriptor(parentDescriptor, (SourcesElement)element); + } + if (element instanceof JavadocElement) { + return new JavadocElementDescriptor(parentDescriptor, (JavadocElement)element); + } + if (element instanceof ItemElement) { + return new ItemElementDescriptor(parentDescriptor, (ItemElement)element); + } + return null; + } + + public void commit() { + } + + public boolean hasSomethingToCommit() { + return false; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeRenderer.java new file mode 100644 index 00000000000..5b145b76b8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeRenderer.java @@ -0,0 +1,34 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; + +public class LibraryTreeRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + final NodeDescriptor descriptor = (NodeDescriptor)userObject; + final Icon closedIcon = descriptor.getClosedIcon(); + Icon openIcon = descriptor.getOpenIcon(); + if (openIcon == null) { + openIcon = closedIcon; + } + setIcon(expanded? openIcon : closedIcon); + append(descriptor.toString(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, descriptor.getColor())); + } + } + + public Font getFont() { + Font font = super.getFont(); + if (font == null) { + font = UIManager.getFont("Label.font"); + } + return font; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java new file mode 100644 index 00000000000..45f8be39d00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java @@ -0,0 +1,146 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; + +import java.util.*; + +public class LibraryTreeStructure extends AbstractTreeStructure{ + private final LibraryElement myRootElement; + private NodeDescriptor myRootElementDescriptor; + private final LibraryTableEditor myParentEditor; + + public LibraryTreeStructure(LibraryTableEditor parentElement, Library library) { + myParentEditor = parentElement; + myRootElement = new LibraryElement(library, myParentEditor); + myRootElementDescriptor = new NodeDescriptor(null, null) { + public boolean update() { + myName = "Root"; + return false; + } + public Object getElement() { + return myRootElement; + } + }; + } + + public Object getRootElement() { + return myRootElement; + } + + public Object[] getChildElements(Object element) { + if (element == myRootElement) { + ArrayList elements = new ArrayList(3); + + Library library = myRootElement.getLibrary(); + final String[] sources = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.SOURCES); + if (sources.length > 0) { + elements.add(new SourcesElement(myRootElement)); + } + + final String[] javadocs = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.JAVADOC); + if (javadocs.length > 0) { + elements.add(new JavadocElement(myRootElement)); + } + + final String[] classes = myParentEditor.getLibraryEditor(library).getUrls(OrderRootType.CLASSES); + if (classes.length > 0) { + elements.add(new ClassesElement(myRootElement)); + } + + return elements.toArray(); + } + + if (element instanceof ClassesElement) { + return buildItems(element, ((ClassesElement)element).getParent().getLibrary(), OrderRootType.CLASSES); + } + + if (element instanceof SourcesElement) { + return buildItems(element, ((SourcesElement)element).getParent().getLibrary(), OrderRootType.SOURCES); + } + + if (element instanceof JavadocElement) { + return buildItems(element, ((JavadocElement)element).getParent().getLibrary(), OrderRootType.JAVADOC); + } + + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + private Object[] buildItems(Object parent, Library library, OrderRootType orderRootType) { + final VirtualFile[] files = myParentEditor.getLibraryEditor(library).getFiles(orderRootType); + final Set validUrls; + if (files.length > 0) { + validUrls = new HashSet(); + for (int idx = 0; idx < files.length; idx++) { + validUrls.add(files[idx].getUrl()); + } + } + else { + validUrls = Collections.EMPTY_SET; + } + ArrayList items = new ArrayList(); + + + final String[] urls = myParentEditor.getLibraryEditor(library).getUrls(orderRootType); + Arrays.sort(urls, myParentEditor.ourUrlComparator); + for (int idx = 0; idx < urls.length; idx++) { + String url = urls[idx]; + items.add(new ItemElement(parent, library, url, orderRootType, validUrls.contains(url))); + } + + return items.toArray(); + } + + public Object getParentElement(Object element) { + if (element == myRootElement) { + return null; + } + if (element instanceof ClassesElement) { + return ((ClassesElement)element).getParent(); + } + if (element instanceof SourcesElement) { + return ((SourcesElement)element).getParent(); + } + if (element instanceof JavadocElement) { + return ((JavadocElement)element).getParent(); + } + if (element instanceof ItemElement) { + return ((ItemElement)element).getParent(); + } + return myRootElement; + } + + public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) { + if (element == myRootElement) { + return myRootElementDescriptor; + } + if (element instanceof LibraryElement) { + return new LibraryElementDescriptor(parentDescriptor, (LibraryElement)element, myParentEditor); + } + if (element instanceof ClassesElement) { + return new ClassesElementDescriptor(parentDescriptor, (ClassesElement)element); + } + if (element instanceof SourcesElement) { + return new SourcesElementDescriptor(parentDescriptor, (SourcesElement)element); + } + if (element instanceof JavadocElement) { + return new JavadocElementDescriptor(parentDescriptor, (JavadocElement)element); + } + if (element instanceof ItemElement) { + return new ItemElementDescriptor(parentDescriptor, (ItemElement)element); + } + return null; + } + + public void commit() { + } + + public boolean hasSomethingToCommit() { + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElement.java new file mode 100644 index 00000000000..9f1bcc37286 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElement.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +class SourcesElement extends LibraryTableTreeContentElement { + private final LibraryElement myParent; + + public SourcesElement(LibraryElement parent) { + myParent = parent; + } + + public LibraryElement getParent() { + return myParent; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SourcesElement)) return false; + + final SourcesElement sourcesElement = (SourcesElement)o; + + if (!myParent.equals(sourcesElement.myParent)) return false; + + return true; + } + + public int hashCode() { + return myParent.hashCode(); + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElementDescriptor.java new file mode 100644 index 00000000000..42fabcd4f69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesElementDescriptor.java @@ -0,0 +1,26 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +class SourcesElementDescriptor extends NodeDescriptor { + private final SourcesElement myElement; + private static final Icon ICON = IconLoader.getIcon("/nodes/sourceFolder.png"); + + public SourcesElementDescriptor(NodeDescriptor parentDescriptor, SourcesElement element) { + super(null, parentDescriptor); + myElement = element; + myOpenIcon = myClosedIcon = ICON; + } + + public boolean update() { + myName = "Sources"; + return false; + } + + public SourcesElement getElement() { + return myElement; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/UrlComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/UrlComparator.java new file mode 100644 index 00000000000..b1a955a6587 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/configuration/libraryEditor/UrlComparator.java @@ -0,0 +1,11 @@ +package com.intellij.openapi.roots.ui.configuration.libraryEditor; + +import java.util.Comparator; + +class UrlComparator implements Comparator { + public int compare(String url1, String url2) { + String name1 = url1.substring(url1.lastIndexOf('/') + 1); + String name2 = url2.substring(url2.lastIndexOf('/') + 1); + return name1.compareToIgnoreCase(name2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/BaseTextCommentCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/BaseTextCommentCellAppearance.java new file mode 100644 index 00000000000..d97f54992a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/BaseTextCommentCellAppearance.java @@ -0,0 +1,40 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.Icon; + +public abstract class BaseTextCommentCellAppearance implements CellAppearance { + private SimpleTextAttributes myCommentAttributes = SimpleTextAttributes.GRAY_ATTRIBUTES; + private SimpleTextAttributes myTextAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; + + protected abstract Icon getIcon(); + + protected abstract String getSecondaryText(); + + protected abstract String getPrimaryText(); + + public void customize(SimpleColoredComponent component) { + component.setIcon(getIcon()); + component.append(getPrimaryText(), myTextAttributes); + String secondaryText = getSecondaryText(); + if (secondaryText != null && secondaryText.length() > 0) + component.append(" (" + secondaryText + ")", myCommentAttributes); + } + + public String getText() { + String secondaryText = getSecondaryText(); + if (secondaryText != null && secondaryText.length() >0) + return getPrimaryText() + " (" + secondaryText + ")"; + return getPrimaryText(); + } + + public void setCommentAttributes(SimpleTextAttributes commentAttributes) { + myCommentAttributes = commentAttributes; + } + + public void setTextAttributes(SimpleTextAttributes textAttributes) { + myTextAttributes = textAttributes; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearance.java new file mode 100644 index 00000000000..dc9f1cf8702 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearance.java @@ -0,0 +1,8 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.ui.SimpleColoredComponent; + +public interface CellAppearance { + void customize(SimpleColoredComponent component); + String getText(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearanceUtils.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearanceUtils.java new file mode 100644 index 00000000000..b76ac3c6c37 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CellAppearanceUtils.java @@ -0,0 +1,230 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.LightFilePointer; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.openapi.vfs.ex.http.HttpFileSystem; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.Icons; + +import javax.swing.*; +import java.io.File; + +// Author: dyoma + +public class CellAppearanceUtils { + public static final Icon FOLDER_ICON = IconLoader.getIcon("/nodes/folder.png"); + public static final Icon INVALID_ICON = IconLoader.getIcon("/nodes/ppInvalid.png"); + public static final Icon SOURCE_FOLDERS_ICON = IconLoader.getIcon("/nodes/sourceFolder.png"); + public static final Icon JAVA_DOC_FOLDER = IconLoader.getIcon("/nodes/javaDocFolder.png"); + public static final Icon TEST_SOURCE_FOLDER = IconLoader.getIcon("/nodes/testSourceFolder.png"); + public static final Icon CLASSES_FOLDER = IconLoader.getIcon("/nodes/compiledClassesFolder.png"); + public static final Icon EXCLUDE_FOLDERS_ICON = excludeIcon(SOURCE_FOLDERS_ICON); + public static final Icon EXCLUDE_FOLDER_ICON = excludeIcon(FOLDER_ICON); + public static final CellAppearance EMPTY = new EmptyAppearance(); + public static final Icon GENERIC_JDK_ICON = IconLoader.getIcon("/general/jdk.png"); + public static final String NO_JDK = ""; + + public static final SimpleTextAttributes createSimpleCellAttributes(boolean isSelected){ + return isSelected ? SimpleTextAttributes.SELECTED_SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES; + } + + + public static CellAppearance forVirtualFilePointer(VirtualFilePointer filePointer) { + return filePointer.isValid() ? + forValidVirtualFile(filePointer.getFile()) : + forInvalidVirtualFilePointer(filePointer); + } + + public static CellAppearance forVirtualFile(VirtualFile virtualFile) { + return virtualFile.isValid() ? + forValidVirtualFile(virtualFile) : + forInvalidVirtualFilePointer(new LightFilePointer(virtualFile.getUrl())); + } + + private static SimpleTextCellAppearance forInvalidVirtualFilePointer(VirtualFilePointer filePointer) { + return SimpleTextCellAppearance.invalid(filePointer.getPresentableUrl(), INVALID_ICON); + } + + private static CellAppearance forValidVirtualFile(VirtualFile virtualFile) { + final VirtualFileSystem fileSystem = virtualFile.getFileSystem(); + if (fileSystem.getProtocol().equals(JarFileSystem.PROTOCOL)) { + return new JarSubfileCellAppearance(virtualFile); + } + if (fileSystem instanceof HttpFileSystem) { + return new HttpUrlCellAppearance(virtualFile); + } + if (virtualFile.isDirectory()) { + return SimpleTextCellAppearance.normal(virtualFile.getPresentableUrl(), FOLDER_ICON); + } + return new ValidFileCellAppearance(virtualFile); + } + + public static Icon iconForFile(VirtualFile file) { + if (file.getFileSystem().getProtocol().equals(JarFileSystem.PROTOCOL) && file.getParent() == null) { + return file.getIcon(); + } + if (file.isDirectory()) return FOLDER_ICON; + return file.getIcon(); + } + + public static CellAppearance forOrderEntry(OrderEntry orderEntry) { + if (orderEntry instanceof JdkOrderEntry) { + JdkOrderEntry jdkLibraryEntry = (JdkOrderEntry)orderEntry; + ProjectJdk jdk = jdkLibraryEntry.getJdk(); + if (!orderEntry.isValid()) { + return SimpleTextCellAppearance.invalid(jdkLibraryEntry.getJdkName(), INVALID_ICON); + } + return forJdk(jdk, false); + } + else if (!orderEntry.isValid()) { + return SimpleTextCellAppearance.invalid(orderEntry.getPresentableName(), INVALID_ICON); + } + else if (orderEntry instanceof LibraryOrderEntry) { + LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry; + return forLibrary(libraryOrderEntry.getLibrary()); + } + else if (orderEntry.isSynthetic()) { + String presentableName = orderEntry.getPresentableName(); + Icon icon = orderEntry instanceof ModuleSourceOrderEntry ? sourceFolderIcon(false) : null; + return new SimpleTextCellAppearance(presentableName, icon, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES); + } + else if (orderEntry instanceof ModuleOrderEntry) { + final Icon icon = IconUtilEx.getIcon(((ModuleOrderEntry)orderEntry).getModule(), 0); + return SimpleTextCellAppearance.normal(orderEntry.getPresentableName(), icon); + } + else return CompositeAppearance.single(orderEntry.getPresentableName()); + } + + public static CellAppearance forLibrary(Library library) { + String name = library.getName(); + if (name != null) { + return SimpleTextCellAppearance.normal(name, Icons.LIBRARY_ICON); + } + String[] files = library.getUrls(OrderRootType.CLASSES); + if (files.length == 0) { + return SimpleTextCellAppearance.invalid("Empty Library", Icons.LIBRARY_ICON); + } + if (files.length == 1) { + return forVirtualFilePointer(new LightFilePointer(files[0])); + } + throw new RuntimeException(library.toString()); + } + + public static SimpleTextCellAppearance forSourceFolder(SourceFolder folder) { + return formatRelativePath(folder, FOLDER_ICON); + } + + public static Icon sourceFolderIcon(boolean testSource) { + return testSource ? TEST_SOURCE_FOLDER : SOURCE_FOLDERS_ICON; + } + + public static CellAppearance forExcludeFolder(ExcludeFolder folder) { + return formatRelativePath(folder, EXCLUDE_FOLDER_ICON); + } + + public static CellAppearance forContentFolder(ContentFolder folder) { + if (folder instanceof SourceFolder) { + return forSourceFolder((SourceFolder)folder); + } + else if (folder instanceof ExcludeFolder) { + return forExcludeFolder((ExcludeFolder)folder); + } + else { + throw new RuntimeException(folder.getClass().getName()); + } + } + + public static CellAppearance forModule(Module module) { + return SimpleTextCellAppearance.normal(module.getName(), IconUtilEx.getIcon(module, 0)); + } + + public static CellAppearance forContentEntry(ContentEntry contentEntry) { + return forVirtualFilePointer(new LightFilePointer(contentEntry.getUrl())); + } + + public static SimpleTextCellAppearance formatRelativePath(ContentFolder folder, Icon icon) { + VirtualFilePointer contentFile = new LightFilePointer(folder.getContentEntry().getUrl()); + VirtualFilePointer folderFile = new LightFilePointer(folder.getUrl()); + if (!contentFile.isValid()) return forInvalidVirtualFilePointer(folderFile); + String contentPath = contentFile.getFile().getPath(); + char separator = File.separatorChar; + String relativePath; + SimpleTextAttributes textAttributes; + if (!folderFile.isValid()) { + textAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES; + String absolutePath = folderFile.getPresentableUrl(); + relativePath = + absolutePath.startsWith(contentPath) ? absolutePath.substring(contentPath.length()) : absolutePath; + } + else { + relativePath = VfsUtil.getRelativePath(folderFile.getFile(), contentFile.getFile(), separator); + textAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; + } + if (relativePath == null) relativePath = ""; + relativePath = relativePath.length() == 0 ? "." + File.separatorChar : relativePath; + return new SimpleTextCellAppearance(relativePath, icon, textAttributes); + } + + public static CellAppearance forJdk(ProjectJdk jdk, boolean isInComboBox) { + if (jdk == null) { + return SimpleTextCellAppearance.invalid(NO_JDK, INVALID_ICON); + } + String name = jdk.getName(); + CompositeAppearance appearance = new CompositeAppearance(); + appearance.setIcon(jdk.getSdkType().getIcon()); + VirtualFile homeDirectory = jdk.getHomeDirectory(); + SimpleTextAttributes attributes = (homeDirectory != null && homeDirectory.isValid()) + ? SimpleTextAttributes.REGULAR_ATTRIBUTES + : SimpleTextAttributes.ERROR_ATTRIBUTES; + CompositeAppearance.DequeEnd ending = appearance.getEnding(); + ending.addText(name, attributes); + String versionString = jdk.getVersionString(); + if (versionString != null && !versionString.equals(name)) { + SimpleTextAttributes textAttributes = isInComboBox ? SimpleTextAttributes.SYNTHETIC_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES; + ending.addComment(versionString, textAttributes); + } + return ending.getAppearance(); + } + + public static Icon excludeIcon(Icon icon) { + return IconLoader.getDisabledIcon(icon); + } + + public static CompositeAppearance forFile(File file) { + String absolutePath = file.getAbsolutePath(); + if (!file.exists()) return CompositeAppearance.invalid(absolutePath); + if (file.isDirectory()) { + CompositeAppearance appearance = CompositeAppearance.single(absolutePath); + appearance.setIcon(FOLDER_ICON); + return appearance; + } + String name = file.getName(); + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name); + File parent = file.getParentFile(); + CompositeAppearance appearance = CompositeAppearance.textComment(name, parent.getAbsolutePath()); + appearance.setIcon(fileType.getIcon()); + return appearance; + } + + private static class EmptyAppearance implements CellAppearance { + public void customize(SimpleColoredComponent component) { + } + + public String getText() { + return ""; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CompositeAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CompositeAppearance.java new file mode 100644 index 00000000000..40025d32f66 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/CompositeAppearance.java @@ -0,0 +1,182 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +public class CompositeAppearance implements ModifiableCellAppearance { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.util.CompositeAppearance"); + private Icon myIcon; + private final ArrayList mySections = new ArrayList(); + private int myInsertionIndex = 0; + + public synchronized void customize(SimpleColoredComponent component) { + for (Iterator iterator = getSectionsIterator(); iterator.hasNext();) { + TextSection section = (TextSection) iterator.next(); + TextAttributes attributes = section.ATTRIBUTES; + component.append(section.TEXT, SimpleTextAttributes.fromTextAttributes(attributes)); + } + component.setIcon(myIcon); + } + + public void setIcon(Icon icon) { myIcon = icon; } + + public synchronized String getText() { + StringBuffer buffer = new StringBuffer(); + for (Iterator iterator = getSectionsIterator(); iterator.hasNext();) { + TextSection section = iterator.next(); + buffer.append(section.TEXT); + } + return buffer.toString(); + } + + public synchronized boolean equals(Object obj) { + if (!(obj instanceof CompositeAppearance)) return false; + CompositeAppearance appearance = (CompositeAppearance) obj; + if (SwingUtilities.isEventDispatchThread()) + return appearance.mySections.equals(mySections); + else + return new ArrayList(appearance.mySections).equals(new ArrayList(mySections)); + } + + public int hashCode() {return getText().hashCode();} + + protected void addSectionAt(int index, TextSection section) { + synchronized(this) { + LOG.assertTrue(section != null); + mySections.add(index, section); + for (Iterator iterator = getSectionsIterator(); iterator.hasNext();) { + TextSection textSection = iterator.next(); + if (textSection == null) { + LOG.assertTrue(false, "index: " + index + " size: " + mySections.size()); + iterator.remove(); + } + } + } + } + + public DequeEnd getBeginning() { + return new DequeBeginning(); + } + + public DequeEnd getEnding() { + return new DequeEnding(); + } + + public DequeEnd getSuffix() { + return new DequeSuffix(); + } + + protected Iterator getSectionsIterator() { + return mySections.iterator(); + } + + public static CompositeAppearance textComment(String text, String comment) { + DequeEnd ending = new CompositeAppearance().getEnding(); + ending.addText(text); + ending.addComment(comment); + return ending.getAppearance(); + } + + public static CompositeAppearance single(String text, SimpleTextAttributes textAttributes) { + CompositeAppearance result = new CompositeAppearance(); + result.getEnding().addText(text, textAttributes); + return result; + } + + public static CompositeAppearance single(String text) { + return single(text, SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + + public static CompositeAppearance invalid(String absolutePath) { + CompositeAppearance appearance = new CompositeAppearance(); + appearance.setIcon(CellAppearanceUtils.INVALID_ICON); + appearance.getEnding().addText(absolutePath, SimpleTextAttributes.ERROR_ATTRIBUTES); + return appearance; + } + + protected static class TextSection { + private static final TextAttributes DEFAULT_TEXT_ATTRIBUTES = new TextAttributes(null, null, null, null, Font.PLAIN); + private static final String DEFAULT_TEXT = ""; + public String TEXT; + public TextAttributes ATTRIBUTES; + + public TextSection(String text, TextAttributes attributes) { + ATTRIBUTES = attributes == null ? DEFAULT_TEXT_ATTRIBUTES : attributes; + TEXT = text == null ? DEFAULT_TEXT : text; + } + + public boolean equals(Object obj) { + if (!(obj instanceof TextSection)) return false; + TextSection section = (TextSection) obj; + return section.ATTRIBUTES.equals(ATTRIBUTES) && section.TEXT.equals(TEXT); + } + + public int hashCode() {return TEXT.hashCode();} + } + + public abstract class DequeEnd { + public void addText(String text, SimpleTextAttributes textAttributes) { + addText(text, textAttributes.toTextAttributes()); + } + + public void addText(String text) { + addText(text, SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + + public abstract void addSection(TextSection section); + + public void addText(String text, TextAttributes attributes) { + addSection(new TextSection(text, attributes)); + } + + public void addSurrounded(String text, String prefix, String suffix, SimpleTextAttributes textAttributes) { + if (text != null && text.trim().length() > 0) + addText(prefix + text + suffix, textAttributes); + } + + public CompositeAppearance getAppearance() { + return CompositeAppearance.this; + } + + public void addComment(String comment, SimpleTextAttributes commentAttributes) { + addSurrounded(comment, " (", ")", commentAttributes); + } + + public void addComment(String comment) { + addComment(comment, SimpleTextAttributes.GRAY_ATTRIBUTES); + } + } + + private class DequeBeginning extends DequeEnd { + public void addSection(TextSection section) { + synchronized(CompositeAppearance.this) { + addSectionAt(0, section); + myInsertionIndex++; + } + } + } + + private class DequeEnding extends DequeEnd { + public void addSection(TextSection section) { + synchronized(CompositeAppearance.this) { + addSectionAt(myInsertionIndex, section); + myInsertionIndex++; + } + } + } + + private class DequeSuffix extends DequeEnd { + public void addSection(TextSection section) { + synchronized(CompositeAppearance.this) { + addSectionAt(mySections.size(), section); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/HttpUrlCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/HttpUrlCellAppearance.java new file mode 100644 index 00000000000..80ba31086d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/HttpUrlCellAppearance.java @@ -0,0 +1,17 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.ide.IconUtilEx; +import com.intellij.util.Icons; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +public class HttpUrlCellAppearance extends ValidFileCellAppearance { + public HttpUrlCellAppearance(VirtualFile file) { + super(file); + } + + protected Icon getIcon() { + return Icons.WEB_ICON; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/JarSubfileCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/JarSubfileCellAppearance.java new file mode 100644 index 00000000000..6c9c805e4f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/JarSubfileCellAppearance.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; + +public class JarSubfileCellAppearance extends ValidFileCellAppearance { + public JarSubfileCellAppearance(VirtualFile file) { + super(file); + } + + protected Icon getIcon() { + return StdFileTypes.ARCHIVE.getIcon(); + } + + protected int getSplitUrlIndex(String url) { + int jarNameEnd = url.lastIndexOf(JarFileSystem.JAR_SEPARATOR.charAt(0)); + String jarUrl = jarNameEnd >= 0 ? url.substring(0, jarNameEnd) : url; + return super.getSplitUrlIndex(jarUrl); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ModifiableCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ModifiableCellAppearance.java new file mode 100644 index 00000000000..62bdd3f5d5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ModifiableCellAppearance.java @@ -0,0 +1,9 @@ +package com.intellij.openapi.roots.ui.util; + +import javax.swing.Icon; + +// Author: dyoma + +public interface ModifiableCellAppearance extends CellAppearance { + void setIcon(Icon icon); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/SimpleTextCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/SimpleTextCellAppearance.java new file mode 100644 index 00000000000..03710213b15 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/SimpleTextCellAppearance.java @@ -0,0 +1,47 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.Icon; + +public class SimpleTextCellAppearance implements ModifiableCellAppearance { + private Icon myIcon; + private SimpleTextAttributes myTextAttributes; + private String myText; + + public static SimpleTextCellAppearance invalid(String text, Icon icon) { + return new SimpleTextCellAppearance(text, icon, SimpleTextAttributes.ERROR_ATTRIBUTES); + } + + public static CellAppearance normal(String text, Icon icon) { + CompositeAppearance result = CompositeAppearance.single(text); + result.setIcon(icon); + return result; + } + + public SimpleTextCellAppearance(String text, Icon icon, SimpleTextAttributes textAttributes) { + myIcon = icon; + myTextAttributes = textAttributes; + myText = text; + } + + public void customize(SimpleColoredComponent component) { + component.setIcon(myIcon); + component.append(myText, myTextAttributes); + } + + public String getText() { + return myText; + } + + public SimpleTextAttributes getTextAttributes() { + return myTextAttributes; + } + + public static SimpleTextCellAppearance syntetic(String text, Icon icon) { + return new SimpleTextCellAppearance(text, icon, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES); + } + + public void setIcon(Icon icon) { myIcon = icon; } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ValidFileCellAppearance.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ValidFileCellAppearance.java new file mode 100644 index 00000000000..d795c5f7929 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/ui/util/ValidFileCellAppearance.java @@ -0,0 +1,44 @@ +package com.intellij.openapi.roots.ui.util; + +import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import java.io.File; + +public class ValidFileCellAppearance extends BaseTextCommentCellAppearance { + private final VirtualFile myFile; + + public ValidFileCellAppearance(VirtualFile file) { + myFile = file; + } + + protected Icon getIcon() { + return FileTypeManagerImpl.getInstance().getFileTypeByFile(myFile).getIcon(); + } + + protected String getSecondaryText() { + return getSubname(true); + } + + protected String getPrimaryText() { + return getSubname(false); + } + + private String getSubname(boolean headOrTail) { + String presentableUrl = myFile.getPresentableUrl(); + int separatorIndex = getSplitUrlIndex(presentableUrl); + if (headOrTail) + return separatorIndex >= 0 ? presentableUrl.substring(0, separatorIndex) : ""; + else + return presentableUrl.substring(separatorIndex + 1); + } + + protected int getSplitUrlIndex(String presentableUrl) { + return presentableUrl.lastIndexOf(File.separatorChar); + } + + public VirtualFile getFile() { + return myFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/watcher/impl/OrderEntryPredicate.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/watcher/impl/OrderEntryPredicate.java new file mode 100644 index 00000000000..f92f6c9f5d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/roots/watcher/impl/OrderEntryPredicate.java @@ -0,0 +1,13 @@ +package com.intellij.openapi.roots.watcher.impl; + +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.Condition; +import org.jdom.Element; + +/** + * @author dsl + */ +public interface OrderEntryPredicate extends Condition, Cloneable { + void writeToElement(Element element); + Object clone() throws CloneNotSupportedException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MessagesEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MessagesEx.java new file mode 100644 index 00000000000..bd10c6ef5a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MessagesEx.java @@ -0,0 +1,231 @@ +package com.intellij.openapi.ui.ex; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; + +public class MessagesEx extends Messages { + + public static MessageInfo fileIsReadOnly(Project project, String filePath) { + return error(project, "File '" + filePath + " is read-only."); + } + + public static MessageInfo filesAreReadOnly(Project project, String[] files) { + if (files.length == 1){ + return fileIsReadOnly(project, files[0]); + } else { + return error(project, "Files " + filePaths(files) + " are read-only"); + } + } + + private static String filePaths(String[] files) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < files.length; i++) { + String file = files[i]; + if (i > 0){ + result.append(","); + result.append("\n"); + } + result.append(file); + } + return result.toString(); + } + + public static MessageInfo fileIsReadOnly(Project project, VirtualFile file) { + return fileIsReadOnly(project, file.getPresentableUrl()); + } + + public static MessageInfo error(Project project, String message) { + return error(project, message, "Error"); + } + + public static MessageInfo error(Project project, String message, String title) { + return new MessageInfo(project, message, title); + } + + public static abstract class BaseDialogInfo { + private Project myProject; + private String myMessage; + private String myTitle; + private Icon myIcon; + private String[] myOptions = new String[]{"OK"}; + private int myDefaultOption = 0; + + protected BaseDialogInfo(Project project) { + myProject = project; + } + + public BaseDialogInfo(Project project, String message, String title, Icon icon) { + this(project); + myMessage = message; + myTitle = title; + myIcon = icon; + } + + public ThisClass setTitle(String title) { myTitle = title; return getThis(); } + + public String getMessage() { return myMessage; } + + public ThisClass appendMessage(String message) { + myMessage += message; + return getThis(); + } + + public void setOptions(String[] options, int defaultOption) { + myOptions = options; + myDefaultOption = defaultOption; + } + + protected abstract ThisClass getThis(); + + public ThisClass setIcon(Icon icon) { myIcon = icon; return getThis(); } + + public void setMessage(String message) { + myMessage = message; + } + + public Project getProject() { + return myProject; + } + + public String getTitle() { + return myTitle; + } + + public String[] getOptions() { + return myOptions; + } + + public int getDefaultOption() { + return myDefaultOption; + } + + public Icon getIcon() { + return myIcon; + } + } + + public static class MessageInfo extends BaseDialogInfo { + public MessageInfo(Project project, String message, String title) { + super(project, message, title, getErrorIcon()); + } + + public int showNow() { + return showDialog(getProject(), getMessage(), getTitle(), getOptions(), getDefaultOption(), getIcon()); + } + + public void showLater() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + showNow(); + } + }); + } + + public int askOkCancel() { + setIcon(getQuestionIcon()); + return showOkCancelDialog(getProject(), getMessage(), getTitle(), getIcon()); + } + + public int ask(String[] options, int defaultOptionIndex) { + setOptions(options, defaultOptionIndex); + return showNow(); + } + + protected MessageInfo getThis() { + return this; + } + } + + public static class ChoiceInfo extends BaseInputInfo { + private String[] myChoises = ArrayUtil.EMPTY_STRING_ARRAY; + private String myDefaultChoice = null; + private boolean myEditable = false; + + public ChoiceInfo(Project project) { + super(project); + setIcon(getQuestionIcon()); + setOptions(new String[]{"OK"}, 0); + } + + public ChoiceInfo getThis() { + return this; + } + + public ChoiceInfo setChoices(String[] choices, int defaultChoiceIndex) { + setChoices(choices, defaultChoiceIndex >= 0 ? choices[defaultChoiceIndex] : null); + return getThis(); + } + + public ChoiceInfo setChoices(String[] choices, String defaultChoice) { + myChoises = choices; + myDefaultChoice = defaultChoice; + return getThis(); + } + + public UserInput askUser() { + ChooseDialog dialog = new ChooseDialog(getProject(), getMessage(), getTitle(), getIcon(), myChoises, myDefaultChoice, getOptions(), getDefaultOption()); + dialog.setValidator(null); + JComboBox comboBox = dialog.getComboBox(); + comboBox.setEditable(myEditable); + if (myEditable) + comboBox.getEditor().setItem(myDefaultChoice); + comboBox.setSelectedItem(myDefaultChoice); + dialog.show(); + Object selectedItem = comboBox.getSelectedItem(); + return new UserInput(selectedItem != null ? selectedItem.toString() : null, dialog.getExitCode()); + } + } + + public static class UserInput { + private final int mySelectedOption; + private final String myInput; + + public UserInput(String choice, int option) { + mySelectedOption = option; + myInput = choice; + } + + public String getInput() { + return myInput; + } + + public int getSelectedOption() { + return mySelectedOption; + } + } + + public static class InputInfo extends BaseInputInfo { + public InputInfo(Project project) { + super(project); + setOptions(new String[]{"OK", "Cancel"}, 0); + } + + public UserInput askUser() { + InputDialog dialog = new InputDialog(getProject(), getMessage(), getTitle(), getIcon(), null, null, getOptions(), getDefaultOption()); + dialog.show(); + return new UserInput(dialog.getTextField().getText(), dialog.getExitCode()); + } + + public InputInfo getThis() { + return this; + } + } + + public static abstract class BaseInputInfo extends BaseDialogInfo { + public BaseInputInfo(Project project) { + super(project); + } + + public String forceUserInput() { + setOptions(new String[]{"OK"}, 0); + return askUser().getInput(); + } + + public abstract UserInput askUser(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MultiLineLabel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MultiLineLabel.java new file mode 100644 index 00000000000..7c030a801ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/ex/MultiLineLabel.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.ui.ex; + +import com.intellij.openapi.ui.MultiLineLabelUI; + +import javax.swing.*; +import java.awt.*; + +public class MultiLineLabel extends JLabel{ + public MultiLineLabel(){ + } + + public MultiLineLabel(String text){ + super(text); + } + + public void updateUI(){ + setUI(new MultiLineLabelUI()); + } + + public Dimension getMinimumSize(){ + return getPreferredSize(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java new file mode 100644 index 00000000000..a7bedbeb00b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java @@ -0,0 +1,22 @@ +package com.intellij.openapi.ui.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.DialogWrapperPeer; +import com.intellij.openapi.ui.DialogWrapperPeerFactory; + +import java.awt.*; + +public class DialogWrapperPeerFactoryImpl extends DialogWrapperPeerFactory { + public DialogWrapperPeer createPeer(DialogWrapper wrapper, Project project, boolean canBeParent) { + return new DialogWrapperPeerImpl(wrapper, project, canBeParent); + } + + public DialogWrapperPeer createPeer(DialogWrapper wrapper, boolean canBeParent) { + return new DialogWrapperPeerImpl(wrapper, canBeParent); + } + + public DialogWrapperPeer createPeer(DialogWrapper wrapper, Component parent, boolean canBeParent) { + return new DialogWrapperPeerImpl(wrapper, parent, canBeParent); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java new file mode 100644 index 00000000000..b299fef966c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -0,0 +1,532 @@ +package com.intellij.openapi.ui.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.LaterInvocatorEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.CommandProcessorEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.DialogWrapperDialog; +import com.intellij.openapi.ui.DialogWrapperPeer; +import com.intellij.openapi.util.DimensionService; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.IdeFrame; +import com.intellij.ui.SpeedSearchBase; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.ref.WeakReference; + +public class DialogWrapperPeerImpl extends DialogWrapperPeer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.ui.DialogWrapper"); + + private DialogWrapper myWrapper; + private MyDialog myDialog; + private boolean myCanBeParent = true; + /* + * Default dialog's actions. + */ + private WindowManagerEx myWindowManager; + private Project myProject; + + /** + * Creates modal DialogWrapper. The currently active window will be the dialog's parent. + * + * @param project parent window for the dialog will be calculated based on focused window for the + * specified project. This parameter can be null. In this case parent window + * will be suggested based on current focused window. + * @param canBeParent specifies whether the dialog can be parent for other windows. This parameter is used + * by WindowManager. + */ + protected DialogWrapperPeerImpl(DialogWrapper wrapper, Project project, boolean canBeParent) { + myWrapper = wrapper; + myWindowManager = null; + Application application = ApplicationManager.getApplication(); + if (application != null && application.hasComponent(WindowManager.class)) { + myWindowManager = (WindowManagerEx)WindowManager.getInstance(); + } + + Window window = null; + if (myWindowManager != null) { + + if (project == null) { + project = (Project)DataManager.getInstance().getDataContext().getData(DataConstants.PROJECT); + } + + myProject = project; + window = myWindowManager.suggestParentWindow(myProject); + if (window == null) { + Window focusedWindow = myWindowManager.getMostRecentFocusedWindow(); + if (focusedWindow instanceof IdeFrame) { + window = focusedWindow; + } + } + } + + Window owner; + if (window != null) { + owner = window; + } + else { + owner = JOptionPane.getRootFrame(); + } + + createDialog(owner, canBeParent); + } + + protected DialogWrapperPeerImpl(DialogWrapper wrapper, boolean canBeParent) { + this(wrapper, (Project)null, canBeParent); + } + + /** + * @param parent parent component whicg is used to canculate heavy weight window ancestor. + * parent cannot be null and must be showing. + */ + protected DialogWrapperPeerImpl(DialogWrapper wrapper, Component parent, boolean canBeParent) { + myWrapper = wrapper; + if (parent == null) { + throw new IllegalArgumentException("parent cannot be null"); + } + if (!parent.isShowing()) { + throw new IllegalArgumentException("parent must be showing: " + parent); + } + myWindowManager = null; + Application application = ApplicationManager.getApplication(); + if (application != null && application.hasComponent(WindowManager.class)) { + myWindowManager = (WindowManagerEx)WindowManager.getInstance(); + } + + Window owner = parent instanceof Window + ? (Window)parent + : (Window)SwingUtilities.getAncestorOfClass(Window.class, parent); + if (!(owner instanceof Dialog) && !(owner instanceof Frame)) { + owner = JOptionPane.getRootFrame(); + } + createDialog(owner, canBeParent); + } + + public void setUndecorated(boolean undecorated) { + myDialog.setUndecorated(undecorated); + } + + public void addMouseListener(MouseListener listener) { + myDialog.addMouseListener(listener); + } + + public void addMouseListener(MouseMotionListener listener) { + myDialog.addMouseMotionListener(listener); + } + + public void addKeyListener(KeyListener listener) { + myDialog.addKeyListener(listener); + } + + private void createDialog(Window owner, boolean canBeParent) { + if (owner instanceof Frame) { + myDialog = new MyDialog((Frame)owner, myWrapper); + } + else { + myDialog = new MyDialog((Dialog)owner, myWrapper); + } + myDialog.setModal(true); + myCanBeParent = canBeParent; + + } + + + public void toFront() { + myDialog.toFront(); + } + + public void toBack() { + myDialog.toBack(); + } + + protected void dispose() { + LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only"); + myDialog.remove(myDialog.getRootPane()); + + Runnable disposer = new Runnable() { + public void run() { + myDialog.dispose(); + /* + if (myWindowManager == null) { + myDialog.dispose(); + } + else { + myWindowManager.hideDialog(myDialog, myProject); + } + */ + } + }; + + if (EventQueue.isDispatchThread()) { + disposer.run(); + } + else { + SwingUtilities.invokeLater(disposer); + } + } + + private boolean isProgressDialog() { + return myWrapper.isModalProgress(); + } + + public Container getContentPane() { + return myDialog.getContentPane(); + } + + /** + * @see javax.swing.JDialog#validate + */ + public void validate() { + myDialog.validate(); + } + + /** + * @see javax.swing.JDialog#repaint + */ + public void repaint() { + myDialog.repaint(); + } + + public Window getOwner() { + return myDialog.getOwner(); + } + + public Window getWindow() { + return myDialog; + } + + public JRootPane getRootPane() { + return myDialog.getRootPane(); + } + + public Dimension getSize() { + return myDialog.getSize(); + } + + public String getTitle() { + return myDialog.getTitle(); + } + + /** + * @see java.awt.Window#pack + */ + public void pack() { + myDialog.pack(); + } + + public Dimension getPreferredSize() { + return myDialog.getPreferredSize(); + } + + public void setModal(boolean modal) { + myDialog.setModal(modal); + } + + public boolean isVisible() { + return myDialog.isVisible(); + } + + public boolean isShowing() { + return myDialog.isShowing(); + } + + public void setSize(int width, int height) { + myDialog.setSize(width, height); + } + + public void setTitle(String title) { + myDialog.setTitle(title); + } + + public void isResizable() { + myDialog.isResizable(); + } + + public void setResizable(boolean resizable) { + myDialog.setResizable(resizable); + } + + public Point getLocation() { + return myDialog.getLocation(); + } + + public void setLocation(Point p) { + myDialog.setLocation(p); + } + + public void setLocation(int x, int y) { + myDialog.setLocation(x, y); + } + + public void show() { + LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only"); + + new AnCancelAction().registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), getRootPane()); + + if (!myCanBeParent && myWindowManager != null) { + myWindowManager.doNotSuggestAsParent(myDialog); + } + + if (myDialog.isModal() && !isProgressDialog()) { + /* TODO: Temporarily disable due to J2EE dialogs. Lots of code to rewrite there. + if (ApplicationManager.getApplication() != null) { // [dsl] for license dialog + if (ApplicationManager.getApplication().getCurrentWriteAction(null) != null) { + LOG.error( + "Showing of modal dialog is prohibited inside write-action, modalityState=" + ModalityState.current()); + } + } + */ + ((CommandProcessorEx)CommandProcessor.getInstance()).enterModal(); + LaterInvocatorEx.enterModal(myDialog); + } + + try { + myDialog.show(); + } + finally { + if (myDialog.isModal() && !isProgressDialog()) { + ((CommandProcessorEx)CommandProcessor.getInstance()).leaveModal(); + LaterInvocatorEx.leaveModal(myDialog); + } + } + } + + private class AnCancelAction extends AnAction { + public void update(AnActionEvent e) { + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + e.getPresentation().setEnabled(false); + if (focusOwner instanceof JComponent && SpeedSearchBase.hasActiveSpeedSearch((JComponent)focusOwner)) { + return; + } + + if (focusOwner instanceof JTree) { + JTree tree = (JTree)focusOwner; + if (!tree.isEditing()) { + e.getPresentation().setEnabled(true); + } + } + else if (focusOwner instanceof JTable) { + JTable table = (JTable)focusOwner; + if (!table.isEditing()) { + e.getPresentation().setEnabled(true); + } + } + } + + public void actionPerformed(AnActionEvent e) { + myWrapper.doCancelAction(); + } + } + + + private static class MyDialog extends JDialog implements DialogWrapperDialog, DataProvider { + private final WeakReference myDialogWrapper; + /** + * Initial size of the dialog. When the dialog is being closed and + * current size of the dialog is not equals to the initial sizethen the + * current (changed) size is stored in the DimensionService. + */ + private Dimension myInitialSize; + private String myDimensionServiceKey; + + public MyDialog(Dialog owner, DialogWrapper dialogWrapper) { + super(owner); + myDialogWrapper = new WeakReference(dialogWrapper); + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new MyWindowListener()); + } + + public MyDialog(Frame owner, DialogWrapper dialogWrapper) { + super(owner); + myDialogWrapper = new WeakReference(dialogWrapper); + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new MyWindowListener()); + } + + public DialogWrapper getDialogWrapper() { + return myDialogWrapper.get(); + } + + public void centerInParent() { + setLocationRelativeTo(getOwner()); + } + + public Object getData(String dataId) { + final DialogWrapper wrapper = myDialogWrapper.get(); + if (wrapper instanceof DataProvider) { + return ((DataProvider)wrapper).getData(dataId); + } + return null; + } + + protected JRootPane createRootPane() { + return new JRootPane() { + public void reshape(int x, int y, int width, int height) { + Dimension minSize = getMinimumSize(); + if (width < minSize.width || height < minSize.height) { + Window window = MyDialog.this; + + Dimension size = window.getSize(); + if (width < minSize.width) { + size.width = size.width - width + minSize.width; + width = minSize.width; + } + + if (height < minSize.height) { + size.height = size.height - height + minSize.height; + height = minSize.height; + } + + window.setSize(size); + } + + super.reshape(x, y, width, height); + } + }; + } + + public void show() { + final DialogWrapper dialogWrapper = getDialogWrapper(); + + pack(); + setSize((int)(getWidth() * dialogWrapper.getHorizontalStretch()), + (int)(getHeight() * dialogWrapper.getVerticalStretch())); + + // Restore dialog's size and location + + myDimensionServiceKey = dialogWrapper.getDimensionKey(); + Point location = null; + + if (myDimensionServiceKey != null) { + location = DimensionService.getInstance().getLocation(myDimensionServiceKey); + Dimension size = DimensionService.getInstance().getSize(myDimensionServiceKey); + if (size != null) { + myInitialSize = (Dimension)size.clone(); + setSize(myInitialSize); + } + } + + if (myInitialSize == null) { + myInitialSize = getSize(); + } + + if (location == null) { + location = dialogWrapper.getInitialLocation(); + } + + if (location != null) { + setLocation(location); + } + else { + setLocationRelativeTo(getOwner()); + } + + // Request focus into preferred component, move mouse of default button (if configured), etc + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + // Do nothing if dialog was already disposed + DialogWrapper dialogWrapper = getDialogWrapper(); + if (dialogWrapper == null || !dialogWrapper.isShowing()) { + return; + } + + JButton defaultButton = getRootPane().getDefaultButton(); + JComponent component = dialogWrapper.getPreferredFocusedComponent(); + if (component == null) { + component = defaultButton; + } + if (component != null) { + component.requestFocus(); + } + // + Application application = ApplicationManager.getApplication(); + if (application != null && application.hasComponent(UISettings.class)) { + if (defaultButton != null && UISettings.getInstance().MOVE_MOUSE_ON_DEFAULT_BUTTON) { + Point p = defaultButton.getLocationOnScreen(); + Rectangle r = defaultButton.getBounds(); + try { + Robot robot = new Robot(); + robot.mouseMove(p.x + r.width / 2, p.y + r.height / 2); + } + catch (AWTException exc) { + exc.printStackTrace(); + } + } + } + } + }); + + super.show(); + } + + private class MyWindowListener extends WindowAdapter { + public void windowClosing(WindowEvent e) { + DialogWrapper dialogWrapper = getDialogWrapper(); + if (dialogWrapper.shouldCloseOnCross()) { + dialogWrapper.doCancelAction(); + } + } + + public void windowClosed(WindowEvent e) { + if (myDimensionServiceKey != null && myInitialSize != null) { // myInitialSize can be null only if dialog is disposed before first showing + Point location = getLocation(); + // Save location + DimensionService.getInstance().setLocation(myDimensionServiceKey, location); + // Save size + Dimension size = getSize(); + if (!myInitialSize.equals(size)) { + DimensionService.getInstance().setSize(myDimensionServiceKey, size); + } + } + } + + public void windowOpened(WindowEvent e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + // Do nothing if dialog was already disposed + DialogWrapper dialogWrapper = getDialogWrapper(); + if (dialogWrapper == null || !dialogWrapper.isShowing()) { + return; + } + + selectPreferredFocusedComponent(dialogWrapper.getPreferredFocusedComponent()); + } + }); + } + } + } + + private static void selectPreferredFocusedComponent(final JComponent component) { + if (component instanceof JTextField) { + JTextField field = (JTextField)component; + String text = field.getText(); + if (text != null) { + field.setSelectionStart(0); + field.setSelectionEnd(text.length()); + } + } + else if (component instanceof JComboBox) { + JComboBox combobox = (JComboBox)component; + combobox.getEditor().selectAll(); + } + } + + public void setContentPane(JComponent content) { + myDialog.setContentPane(content); + } + + public void centerInParent() { + myDialog.centerInParent(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/FilePathImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/FilePathImpl.java new file mode 100644 index 00000000000..77e8f878a14 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/FilePathImpl.java @@ -0,0 +1,162 @@ +package com.intellij.openapi.vcs; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; + +import java.io.File; +import java.nio.charset.Charset; + +public class FilePathImpl implements FilePath { + private VirtualFile myVirtualFile; + private final VirtualFile myVirtualParent; + private final String myName; + private final File myFile; + + public FilePathImpl(VirtualFile virtualParent, String name) { + myVirtualParent = virtualParent; + myName = name; + if (myVirtualParent == null) { + myFile = new File(myName); + } + else { + myFile = new File(new File(myVirtualParent.getPath()), myName); + } + + refresh(); + } + + public int hashCode() { + return myFile.hashCode(); + } + + public boolean equals(Object o) { + if (!(o instanceof FilePath)) { + return false; + } + else { + return myFile.equals(((FilePath)o).getIOFile()); + } + } + + public FilePathImpl(VirtualFile virtualFile) { + this(virtualFile.getParent(), virtualFile.getName()); + } + + public void refresh() { + if (myVirtualParent == null) { + myVirtualFile = LocalFileSystem.getInstance().findFileByPath(myName); + } + else { + myVirtualFile = myVirtualParent.findChild(myName); + } + + } + + public String getPath() { + if (myVirtualFile != null) { + return myVirtualFile.getPath(); + } + else { + return myVirtualParent.getPath() + "/" + myName; + } + } + + public boolean isDirectory() { + if (myVirtualFile == null) { + return false; + } + else { + return myVirtualFile.isDirectory(); + } + } + + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + public VirtualFile getVirtualFileParent() { + return myVirtualParent; + } + + public File getIOFile() { + return myFile; + } + + public String getName() { + return myName; + } + + public String getPresentableUrl() { + if (myVirtualFile == null) { + return myFile.getAbsolutePath(); + } + else { + return myVirtualFile.getPresentableUrl(); + } + } + + public Document getDocument() { + return myVirtualFile != null ? FileDocumentManager.getInstance().getDocument(myVirtualFile) : null; + } + + public Charset getCharset() { + return myVirtualFile != null ? + myVirtualFile.getCharset() + : CharsetToolkit.getIDEOptionsCharset(); + } + + public FileType getFileType() { + return myVirtualFile != null + ? myVirtualFile.getFileType() + : FileTypeManager.getInstance().getFileTypeByFileName(myFile.getName()); + } + + public static FilePathImpl create(File selectedFile) { + if (selectedFile == null) { + return null; + } + + LocalFileSystem lfs = LocalFileSystem.getInstance(); + + VirtualFile virtualFile = lfs.findFileByIoFile(selectedFile); + if (virtualFile != null) { + return new FilePathImpl(virtualFile); + } + + File parentFile = selectedFile.getParentFile(); + if (parentFile == null) { + return null; + } + + VirtualFile virtualFileParent = lfs.findFileByIoFile(parentFile); + if (virtualFileParent != null) { + return new FilePathImpl(virtualFileParent, selectedFile.getName()); + } + else { + return null; + } + } + + public static FilePath createOn(String s) { + File ioFile = new File(s); + final LocalFileSystem localFileSystem = LocalFileSystem.getInstance(); + VirtualFile virtualFile = localFileSystem.findFileByIoFile(ioFile); + if (virtualFile != null) { + return new FilePathImpl(virtualFile); + } + else { + VirtualFile virtualFileParent = localFileSystem.findFileByIoFile(ioFile.getParentFile()); + if (virtualFileParent != null) { + return new FilePathImpl(virtualFileParent, ioFile.getName()); + } + else { + return null; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractCommonCheckinAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractCommonCheckinAction.java new file mode 100644 index 00000000000..f1fd1c9ffc9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractCommonCheckinAction.java @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; +import com.intellij.openapi.vcs.checkin.VcsOperation; +import com.intellij.openapi.vcs.fileView.impl.FileViewPanel; +import com.intellij.openapi.vcs.ui.CheckinDialog; +import com.intellij.openapi.vcs.ui.CheckinFileDialog; +import com.intellij.openapi.vcs.ui.OptionsDialog; +import com.intellij.openapi.vcs.ui.Refreshable; +import com.intellij.openapi.vcs.ui.impl.CheckinProjectPanelImpl; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.vcsUtil.VcsUtil; + +import java.util.*; + + +public abstract class AbstractCommonCheckinAction extends AbstractVcsAction { + private static final int MIXED = 0; + protected static final int DIRECTORIES = 1; + private static final int FILES = 2; + + public void actionPerformed(final VcsContext context) { + final Project project = context.getProject(); + + if (project == null) return; + + FilePath[] roots = filterDescindingFiles(getRoots(context), project); + + + int ciType = getCheckinType(roots); + + if (ciType == MIXED) { + return; + } + if (ciType == DIRECTORIES) { + if (ApplicationManager.getApplication().isDispatchThread()) { + ApplicationManager.getApplication().saveAll(); + } + checkinDirectories(project, context, roots); + } + else { + CheckinEnvironment env = getCommonEnvironmentFor(roots, project); + if (env == null) return; + if (ApplicationManager.getApplication().isDispatchThread()) { + ApplicationManager.getApplication().saveAll(); + } + checkinFiles(project, context, roots, env); + } + + } + + protected CheckinEnvironment getCommonEnvironmentFor(FilePath[] roots, Project project) { + if (roots.length == 0) return null; + AbstractVcs firstVcs = VcsUtil.getVcsFor (project, roots[0]); + if (firstVcs == null) return null; + CheckinEnvironment firstEnv = firstVcs.getCheckinEnvironment(); + if (firstEnv == null) return null; + + for (int i = 0; i < roots.length; i++) { + FilePath file = roots[i]; + AbstractVcs vcs = VcsUtil.getVcsFor(project, file); + if (vcs == null) return null; + CheckinEnvironment env = vcs.getCheckinEnvironment(); + if (firstEnv != env) { + return null; + } + } + return firstEnv; + } + + private void checkinFiles(final Project project, final VcsContext context, FilePath[] roots, CheckinEnvironment checkinEnvironment) { + VcsConfiguration configuration = VcsConfiguration.getInstance(project); + if (configuration.SHOW_CHECKIN_OPTIONS || OptionsDialog.shiftIsPressed(context.getModifiers())) { + + + CheckinFileDialog dialog = new CheckinFileDialog(project, getActionName(context), + checkinEnvironment, + roots); + dialog.show(); + if (!dialog.isOK()) return; + List vcsExceptions = checkinEnvironment.commit(roots, project, dialog.getPreparedComment(checkinEnvironment)); + if (!vcsExceptions.isEmpty()) { + AbstractVcsHelper.getInstance(project).showErrors(vcsExceptions, getActionName(context)); + } + } + else { + List vcsExceptions = checkinEnvironment.commit(roots, project, + checkinEnvironment.prepareCheckinMessage( + CheckinDialog.getInitialMessage(roots, project))); + if (!vcsExceptions.isEmpty()) { + AbstractVcsHelper.getInstance(project).showErrors(vcsExceptions, getActionName(context)); + } + } + + final LvcsAction lvcsAction = LocalVcs.getInstance(project).startAction(getActionName(context), "", true); + VirtualFileManager.getInstance().refresh(true, new Runnable() { + public void run() { + lvcsAction.finish(); + FileStatusManager.getInstance(project).fileStatusesChanged(); + final Refreshable refreshablePanel = context.getRefreshableDialog(); + if (refreshablePanel != null) { + refreshablePanel.refresh(); + } + refreshFileView(project); + } + }); + } + + private void checkinDirectories(final Project project, final VcsContext context, FilePath[] roots) { + final CheckinProjectDialogImplementer dialog = + AbstractVcsHelper.getInstance(project).createCheckinProjectDialog(getActionName(context), true, asPathList(roots)); + + final Refreshable refreshablePanel = context.getRefreshableDialog(); + + final List vcsExceptions = new ArrayList(); + + Runnable actionAfterDialogWasShown = new Runnable() { + public void run() { + try { + if (!shouldCheckin(dialog, project)) { + return; + } + + final Runnable checkinAction = new Runnable() { + public void run() { + CheckinProjectPanelImpl checkinProjectPanel = (CheckinProjectPanelImpl)dialog.getCheckinProjectPanel(); + final Map> checkinOperations = checkinProjectPanel.getCheckinOperations(); + Runnable checkinAction = new Runnable() { + public void run() { + + for (Iterator iterator = checkinOperations.keySet().iterator(); iterator.hasNext();) { + CheckinEnvironment checkinEnvironment = iterator.next(); + vcsExceptions.addAll(checkinEnvironment.commit(dialog, project)); + } + + final LvcsAction lvcsAction = LocalVcs.getInstance(project).startAction(getActionName(context), "", true); + VirtualFileManager.getInstance().refresh(true, new Runnable() { + public void run() { + lvcsAction.finish(); + FileStatusManager.getInstance(project).fileStatusesChanged(); + if (refreshablePanel != null) { + refreshablePanel.refresh(); + } + refreshFileView(project); + } + }); + + AbstractVcsHelper.getInstance(project).showErrors(vcsExceptions, getActionName(context)); + } + }; + ApplicationManager.getApplication().runProcessWithProgressSynchronously(checkinAction, getActionName(context), true, project); + } + }; + + AbstractVcsHelper.getInstance(project).optimizeImportsAndReformatCode(dialog.getCheckinProjectPanel().getVirtualFiles(), + VcsConfiguration.getInstance(project), checkinAction, true); + + + } + finally { + dialog.dispose(); + } + + } + }; + + try { + dialog.analyzeChanges(true, actionAfterDialogWasShown); + } + catch (VcsException e) { + Messages.showErrorDialog("Cannot analize changes: " + e.getLocalizedMessage(), "Analizing Changes"); + } + } + + protected int getCheckinType(FilePath[] roots) { + if (roots.length == 0) return MIXED; + FilePath file = roots[0]; + int firstType = getCheckinType(file); + + for (int i = 0; i < roots.length; i++) { + FilePath root = roots[i]; + int checkinType = getCheckinType(root); + if (checkinType != firstType) return MIXED; + } + + return firstType; + } + + private int getCheckinType(FilePath file) { + return file.isDirectory() ? DIRECTORIES : FILES; + } + + private Collection asPathList(FilePath[] roots) { + ArrayList result = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + result.add(roots[i].getPath()); + } + return result; + } + + protected abstract String getActionName(VcsContext dataContext); + + protected abstract FilePath[] getRoots(VcsContext project); + + protected void refreshFileView(Project project) { + if (project == null) return; + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + + ToolWindowEx fileViewToolWindow = (ToolWindowEx)toolWindowManager + .getToolWindow(ProjectLevelVcsManager.FILE_VIEW_TOOL_WINDOW_ID); + if (fileViewToolWindow == null) return; + if (!fileViewToolWindow.isAvailable()) return; + ((FileViewPanel)fileViewToolWindow.getComponent()).refresh(); + } + + private boolean shouldCheckin(CheckinProjectDialogImplementer d, Project project) { + if (!d.hasDiffs()) { + Messages.showMessageDialog(project, "Nothing was found to commit", "Nothing Found", + Messages.getInformationIcon()); + return false; + } + d.show(); + return d.isOK(); + } + + protected void update(VcsContext vcsContext, Presentation presentation) { + Project project = vcsContext.getProject(); + if (project == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + FilePath[] roots = getRoots(vcsContext); + if (roots == null || roots.length == 0) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + + int checkinType = getCheckinType(roots); + if (checkinType == DIRECTORIES) { + for (int i = 0; i < roots.length; i++) { + FilePath root = roots[i]; + AbstractVcs vcs = VcsUtil.getVcsFor(project, root); + if (vcs == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + CheckinEnvironment checkinEnvironment = vcs.getCheckinEnvironment(); + if (checkinEnvironment == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + } + } + else { + CheckinEnvironment commonEnvironmentFor = getCommonEnvironmentFor(roots, project); + if (commonEnvironmentFor == null) { + presentation.setEnabled(false); + presentation.setVisible(false); + return; + } + } + + String actionName = getActionName(vcsContext); + if (shouldShowDialog(vcsContext) || OptionsDialog.shiftIsPressed(vcsContext.getModifiers())){ + actionName += "..."; + } + + presentation.setText(actionName); + + presentation.setEnabled(true); + presentation.setVisible(true); + } + + protected abstract boolean shouldShowDialog(VcsContext context); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractVcsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractVcsAction.java new file mode 100644 index 00000000000..a48597a5d36 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/AbstractVcsAction.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ModuleLevelVcsManager; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.util.containers.HashSet; + +import java.util.Collection; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +public abstract class AbstractVcsAction extends AnAction { + public static Collection getActiveVcses(VcsContext dataContext) { + Collection result = new HashSet(); + Project project = dataContext.getProject(); + if (project != null) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + AbstractVcs activeVcs = ModuleLevelVcsManager.getInstance(module).getActiveVcs(); + if (activeVcs != null) { + result.add(activeVcs); + } + } + } + return result; + } + + protected FilePath[] filterDescindingFiles(FilePath[] roots, Project project) { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + List result = new ArrayList(Arrays.asList(roots)); + for (int i = 0; i < roots.length; i++) { + FilePath first = roots[i]; + for (int j = 0; j < roots.length; j++) { + FilePath second = roots[j]; + Module firstModule = getModuleForPath(fileIndex, first); + Module secondModule = getModuleForPath(fileIndex, second); + + if ((first != second) && (firstModule == secondModule) && VfsUtil.isAncestor(first.getIOFile(), second.getIOFile(), false)) { + result.remove(second); + } + } + } + + return result.toArray(new FilePath[result.size()]); + } + + private Module getModuleForPath(ProjectFileIndex fileIndex, FilePath path) { + VirtualFile virtualFile = path.getVirtualFile(); + if (virtualFile != null) { + return fileIndex.getModuleForFile(virtualFile); + } + VirtualFile virtualFileParent = path.getVirtualFileParent(); + if (virtualFileParent != null) { + return fileIndex.getModuleForFile(virtualFileParent); + } + return null; + } + + public final void update(AnActionEvent e) { + super.update(e); + update(VcsContextWrapper.on(e), e.getPresentation()); + } + + public final void actionPerformed(AnActionEvent e) { + actionPerformed(VcsContextWrapper.on(e)); + } + + protected abstract void actionPerformed(VcsContext e); + + protected abstract void update(VcsContext vcsContext, Presentation presentation); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CashedVcsContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CashedVcsContext.java new file mode 100644 index 00000000000..5a43b670eed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CashedVcsContext.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.vcs.ui.Refreshable; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.psi.PsiElement; + +import java.util.Collection; +import java.io.File; + +public class CashedVcsContext implements VcsContext { + private final Project myProject; + private final VirtualFile mySelectedFile; + private final VirtualFile[] mySelectedFiles; + private final Collection mySelectedFilesCollection; + private final Editor myEditor; + private final File[] mySelectedIOFiles; + private final int myModifiers; + private final Refreshable myRefreshablePanel; + private final String myPlace; + private final PsiElement myPsiElement; + private final File mySelectedIOFile; + private final FilePath[] mySelectedFilePaths; + private final FilePath mySelectedFilePath; + + public CashedVcsContext(VcsContext baseContext) { + myProject = baseContext.getProject(); + mySelectedFile = baseContext.getSelectedFile(); + mySelectedFiles = baseContext.getSelectedFiles(); + mySelectedFilesCollection = baseContext.getSelectedFilesCollection(); + myEditor = baseContext.getEditor(); + mySelectedIOFiles = baseContext.getSelectedIOFiles(); + myModifiers = baseContext.getModifiers(); + myRefreshablePanel = baseContext.getRefreshableDialog(); + myPlace = baseContext.getPlace(); + myPsiElement = baseContext.getPsiElement(); + mySelectedIOFile = baseContext.getSelectedIOFile(); + mySelectedFilePaths = baseContext.getSelectedFilePaths(); + mySelectedFilePath = baseContext.getSelectedFilePath(); + } + + public String getPlace() { + return myPlace; + } + + public PsiElement getPsiElement() { + return myPsiElement; + } + + public Project getProject() { + return myProject; + } + + public VirtualFile getSelectedFile() { + return mySelectedFile; + } + + public VirtualFile[] getSelectedFiles() { + return mySelectedFiles; + } + + public Editor getEditor() { + return myEditor; + } + + public Collection getSelectedFilesCollection() { + return mySelectedFilesCollection; + } + + public File[] getSelectedIOFiles() { + return mySelectedIOFiles; + } + + public int getModifiers() { + return myModifiers; + } + + public Refreshable getRefreshableDialog() { + return myRefreshablePanel; + } + + public File getSelectedIOFile() { + return mySelectedIOFile; + } + + public FilePath[] getSelectedFilePaths() { + return mySelectedFilePaths; + } + + public FilePath getSelectedFilePath() { + return mySelectedFilePath; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java new file mode 100644 index 00000000000..5eefe2cafa1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsConfiguration; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; + +public class CommonCheckinFilesAction extends AbstractCommonCheckinAction { + protected String getActionName(VcsContext dataContext) { + FilePath[] roots = getRoots(dataContext); + if (roots == null || roots.length == 0) return getCheckinActionName(dataContext); + FilePath first = roots[0]; + if (roots.length == 1) { + if (first.isDirectory()) { + return getCheckinActionName(dataContext) + " Directory"; + } + else { + return getCheckinActionName(dataContext) + " File"; + } + } + else { + if (first.isDirectory()) { + return getCheckinActionName(dataContext) + " Directories"; + } + else { + return getCheckinActionName(dataContext) + " Files"; + } + } + } + + private String getCheckinActionName(VcsContext dataContext) { + Project project = dataContext.getProject(); + if (project == null) return "Checkin"; + CheckinEnvironment env = getCommonEnvironmentFor(getRoots(dataContext), project); + if (env == null) { + return "Checkin"; + } + else { + return env.getCheckinOperationName(); + } + } + + protected FilePath[] getRoots(VcsContext context) { + return context.getSelectedFilePaths(); + } + + protected boolean shouldShowDialog(VcsContext context) { + Project project = context.getProject(); + FilePath[] roots = filterDescindingFiles(getRoots(context), project); + int ciType = getCheckinType(roots); + if (ciType == DIRECTORIES) { + return true; + } + else { + return VcsConfiguration.getInstance(project).SHOW_CHECKIN_OPTIONS; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java new file mode 100644 index 00000000000..4a79d09d67a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.ArrayList; + + +public class CommonCheckinProjectAction extends AbstractCommonCheckinAction { + + protected FilePath[] getRoots(final VcsContext context) { + Project project = context.getProject(); + ArrayList virtualFiles = new ArrayList(); + VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots(); + for (int i = 0; i < roots.length; i++) { + VirtualFile root = roots[i]; + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(root); + if (vcs == null) continue; + CheckinEnvironment checkinEnvironment = vcs.getCheckinEnvironment(); + if (checkinEnvironment == null) continue; + virtualFiles.add(new FilePathImpl(root)); + } + return virtualFiles.toArray(new FilePath[virtualFiles.size()]); + } + + protected String getActionName(VcsContext dataContext) { + return "Commit Project"; + } + + protected boolean shouldShowDialog(VcsContext context) { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/SelectedBlockHistoryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/SelectedBlockHistoryAction.java new file mode 100644 index 00000000000..f564fdd6753 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/SelectedBlockHistoryAction.java @@ -0,0 +1,69 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.history.VcsHistoryProvider; +import com.intellij.openapi.vcs.history.VcsHistorySession; +import com.intellij.openapi.vcs.history.impl.VcsBlockHistoryDialog; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.vcsUtil.VcsSelection; +import com.intellij.vcsUtil.VcsUtil; + +public class SelectedBlockHistoryAction extends FileHistoryAction { + + protected boolean isEnabled(VcsContext context) { + + if (!super.isEnabled(context)) return false; + + VcsSelection selection = VcsUtil.getSelection(context); + if (selection == null) { + return false; + } + + VirtualFile file = FileDocumentManager.getInstance().getFile(selection.getDocument()); + AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(context.getProject()).getVcsFor(file); + if (activeVcs == null) return false; + + VcsHistoryProvider provider = getProvider(activeVcs); + if (provider == null) return false; + + return activeVcs.fileExistsInVcs(new FilePathImpl(file)); + } + + public void actionPerformed(VcsContext context) { + try { + VcsSelection selection = VcsUtil.getSelection(context); + VirtualFile file = FileDocumentManager.getInstance().getFile(selection.getDocument()); + Project project = context.getProject(); + AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(file); + if (activeVcs == null) return; + + VcsHistoryProvider provider = getProvider(activeVcs); + + int selectionStart = selection.getSelectionStartLineNumber(); + int selectionEnd = selection.getSelectionEndLineNumber(); + VcsHistorySession session = provider.createSessionFor(new FilePathImpl(file)); + VcsBlockHistoryDialog vcsHistoryDialog = + new VcsBlockHistoryDialog(project, + context.getSelectedFiles()[0], + activeVcs, + provider, + session, + Math.min(selectionStart, selectionEnd), + Math.max(selectionStart, selectionEnd)); + + vcsHistoryDialog.show(); + } + catch (Exception exception) { + reportError(exception); + } + + } + + protected VcsHistoryProvider getProvider(AbstractVcs activeVcs) { + return activeVcs.getVcsBlockHistoryProvider(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowChangeMarkerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowChangeMarkerAction.java new file mode 100644 index 00000000000..a1a86625e01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowChangeMarkerAction.java @@ -0,0 +1,85 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ex.LineStatusTracker; +import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.ex.Range; + +/** + * author: lesya + */ +public abstract class ShowChangeMarkerAction extends AbstractVcsAction { + protected final ChangeMarkerContext myChangeMarkerContext; + + + protected abstract Range extractRange(LineStatusTracker lineStatusTracker, int line, Editor editor); + + public ShowChangeMarkerAction(final Range range, final LineStatusTracker lineStatusTracker, final Editor editor) { + myChangeMarkerContext = new ChangeMarkerContext() { + public Range getRange(VcsContext dataContext) { + return range; + } + + public LineStatusTracker getLineStatusTracker(VcsContext dataContext) { + return lineStatusTracker; + } + + public Editor getEditor(VcsContext dataContext) { + return editor; + } + }; + } + + public ShowChangeMarkerAction() { + myChangeMarkerContext = new ChangeMarkerContext() { + public Range getRange(VcsContext context) { + Editor editor = getEditor(context); + if (editor == null) return null; + + LineStatusTracker lineStatusTracker = getLineStatusTracker(context); + if (lineStatusTracker == null) return null; + + return extractRange(lineStatusTracker, editor.getCaretModel().getLogicalPosition().line, editor); + } + + public LineStatusTracker getLineStatusTracker(VcsContext dataContext) { + Editor editor = getEditor(dataContext); + if (editor == null) return null; + Project project = dataContext.getProject(); + if (project == null) return null; + return ProjectLevelVcsManagerEx.getInstanceEx(project).getLineStatusTracker(editor.getDocument()); + } + + public Editor getEditor(VcsContext dataContext) { + return dataContext.getEditor(); + } + }; + } + + private boolean isActive(VcsContext context) { + return myChangeMarkerContext.getRange(context) != null; + } + + protected void update(VcsContext context, Presentation presentation) { + presentation.setEnabled(isActive(context)); + } + + + protected void actionPerformed(VcsContext context) { + Editor editor = myChangeMarkerContext.getEditor(context); + LineStatusTracker lineStatusTracker = myChangeMarkerContext.getLineStatusTracker(context); + Range range = myChangeMarkerContext.getRange(context); + + lineStatusTracker.moveToRange(range, editor); + } + + protected interface ChangeMarkerContext { + Range getRange(VcsContext dataContext); + + LineStatusTracker getLineStatusTracker(VcsContext dataContext); + + Editor getEditor(VcsContext dataContext); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowNextChangeMarkerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowNextChangeMarkerAction.java new file mode 100644 index 00000000000..b46b2b5e250 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowNextChangeMarkerAction.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.vcs.ex.LineStatusTracker; +import com.intellij.openapi.vcs.ex.Range; + +/** + * author: lesya + */ +public class ShowNextChangeMarkerAction extends ShowChangeMarkerAction { + + public ShowNextChangeMarkerAction(final Range range, final LineStatusTracker lineStatusTracker, final Editor editor) { + super(range, lineStatusTracker, editor); + } + + public ShowNextChangeMarkerAction() { + } + + protected Range extractRange(LineStatusTracker lineStatusTracker, int line, Editor editor) { + return lineStatusTracker.getNextRange(line); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowPrevChangeMarkerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowPrevChangeMarkerAction.java new file mode 100644 index 00000000000..4720076edc8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/ShowPrevChangeMarkerAction.java @@ -0,0 +1,21 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.vcs.ex.LineStatusTracker; +import com.intellij.openapi.vcs.ex.Range; + +/** + * author: lesya + */ +public class ShowPrevChangeMarkerAction extends ShowChangeMarkerAction { + public ShowPrevChangeMarkerAction(final Range range, final LineStatusTracker lineStatusTracker, final Editor editor) { + super(range, lineStatusTracker, editor); + } + + public ShowPrevChangeMarkerAction() { + } + + protected Range extractRange(LineStatusTracker lineStatusTracker, int line, Editor editor) { + return lineStatusTracker.getPrevRange(line); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java new file mode 100644 index 00000000000..80568c65dfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java @@ -0,0 +1,116 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.history.FileHistoryPanel; +import com.intellij.openapi.vcs.history.VcsFileRevision; +import com.intellij.openapi.vcs.history.VcsHistoryProvider; +import com.intellij.openapi.vcs.history.VcsHistorySession; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +public class TabbedShowHistoryAction extends AbstractVcsAction { + + protected void update(VcsContext context, Presentation presentation) { + presentation.setVisible(isVisible(context)); + presentation.setEnabled(isEnabled(context)); + } + + protected boolean isVisible(VcsContext context) { + return true; + } + + protected VcsHistoryProvider getProvider(AbstractVcs activeVcs) { + return activeVcs.getVcsHistoryProvider(); + } + + protected boolean isEnabled(VcsContext context) { + FilePath[] selectedFiles = getSelectedFiles(context); + if (selectedFiles == null) return false; + if (selectedFiles.length != 1) return false; + if (selectedFiles[0].isDirectory()) return false; + FilePath path = selectedFiles[0]; + Project project = context.getProject(); + if (project == null) return false; + VirtualFile someVFile = path.getVirtualFile() != null ? path.getVirtualFile() : path.getVirtualFileParent(); + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(someVFile); + if (vcs == null) return false; + VcsHistoryProvider vcsHistoryProvider = getProvider(vcs); + if (vcsHistoryProvider == null) return false; + return vcs.fileExistsInVcs(path) && isVisible(context); + } + + protected FilePath[] getSelectedFiles(VcsContext context) { + ArrayList result = new ArrayList(); + VirtualFile[] virtualFileArray = context.getSelectedFiles(); + if (virtualFileArray != null) { + for (int i = 0; i < virtualFileArray.length; i++) { + VirtualFile virtualFile = virtualFileArray[i]; + result.add(new FilePathImpl(virtualFile)); + } + } + + File[] fileArray = context.getSelectedIOFiles(); + if (fileArray != null) { + for (int i = 0; i < fileArray.length; i++) { + File file = fileArray[i]; + VirtualFile parent = LocalFileSystem.getInstance().findFileByIoFile(file.getParentFile()); + if (parent != null) { + result.add(new FilePathImpl(parent, file.getName())); + } + } + } + return result.toArray(new FilePath[result.size()]); + } + + protected void actionPerformed(VcsContext context) { + FilePath path = getSelectedFiles(context)[0]; + Project project = context.getProject(); + VirtualFile someVFile = path.getVirtualFile() != null ? path.getVirtualFile() : path.getVirtualFileParent(); + AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(someVFile); + VcsHistoryProvider vcsHistoryProvider = getProvider(activeVcs); + try { + VcsHistorySession session = vcsHistoryProvider.createSessionFor(path); + List revisionsList = session.getRevisionList(); + if (revisionsList.isEmpty()) return; + + String actionName = "File " + path.getName() + " History"; + + ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(project).getContentManager(); + + FileHistoryPanel fileHistoryPanel = new FileHistoryPanel(project, + path, session, activeVcs, contentManager); + Content content = PeerFactory.getInstance().getContentFactory().createContent(fileHistoryPanel, actionName, true); + contentManager.addContent(content); + + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS); + toolWindow.activate(null); + contentManager.setSelectedContent(content); + } + catch (Exception exception) { + reportError(exception); + } + } + + protected void reportError(Exception exception) { + exception.printStackTrace(); + Messages.showMessageDialog(exception.getLocalizedMessage(), "Could Not Load File History", Messages.getErrorIcon()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsActionGroup.java new file mode 100644 index 00000000000..15ef1231660 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsActionGroup.java @@ -0,0 +1,31 @@ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; + +/** + * @author mike + */ +public class VcsActionGroup extends DefaultActionGroup { + public VcsActionGroup() { + super(); + } + + public void update(AnActionEvent event) { + super.update(event); + + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null){ + presentation.setVisible(false); + presentation.setEnabled(false); + } else if (ProjectLevelVcsManager.getInstance(project).getAllActiveVcss().length == 0){ + presentation.setVisible(false); + presentation.setEnabled(false); + } else { + presentation.setVisible(true); + presentation.setEnabled(true); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsContextWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsContextWrapper.java new file mode 100644 index 00000000000..27f5a403637 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsContextWrapper.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.VcsDataConstants; +import com.intellij.openapi.vcs.ui.Refreshable; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public class VcsContextWrapper implements VcsContext { + protected final DataContext myContext; + protected final int myModifiers; + private final String myPlace; + + public VcsContextWrapper(DataContext context, int modifiers, String place) { + myContext = context; + myModifiers = modifiers; + myPlace = place; + } + + public String getPlace() { + return myPlace; + } + + public PsiElement getPsiElement() { + return (PsiElement)myContext.getData(DataConstants.PSI_ELEMENT); + } + + public static VcsContext on(AnActionEvent event) { + VcsContextWrapper wrapper = new VcsContextWrapper(event.getDataContext(), event.getModifiers(), event.getPlace()); + return new CashedVcsContext(wrapper); + } + + public Project getProject() { + return (Project)myContext.getData(DataConstants.PROJECT); + } + + public VirtualFile getSelectedFile() { + VirtualFile[] files = getSelectedFiles(); + if (files == null || files.length == 0) return null; + return files[0]; + } + + public VirtualFile[] getSelectedFiles() { + VirtualFile[] fileArray = (VirtualFile[])myContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + if (fileArray != null) { + return filterLocalFiles(fileArray); + } + + VirtualFile virtualFile = (VirtualFile)myContext.getData(DataConstants.VIRTUAL_FILE); + if (virtualFile != null && isLocal(virtualFile)) { + return new VirtualFile[]{virtualFile}; + } + + return VirtualFile.EMPTY_ARRAY; + } + + private boolean isLocal(VirtualFile virtualFile) { + return virtualFile.getFileSystem() == LocalFileSystem.getInstance(); + } + + private VirtualFile[] filterLocalFiles(VirtualFile[] fileArray) { + ArrayList result = new ArrayList(); + for (int i = 0; i < fileArray.length; i++) { + VirtualFile virtualFile = fileArray[i]; + if (isLocal(virtualFile)) { + result.add(virtualFile); + } + } + return result.toArray(new VirtualFile[result.size()]); + } + + public Editor getEditor() { + return (Editor)myContext.getData(DataConstants.EDITOR); + } + + public Collection getSelectedFilesCollection() { + return Arrays.asList(getSelectedFiles()); + } + + public File getSelectedIOFile() { + File file = (File)myContext.getData(VcsDataConstants.IO_FILE); + if (file != null) return file; + File[] files = (File[])myContext.getData(VcsDataConstants.IO_FILE_ARRAY); + if (files == null) return null; + if (files.length == 0) return null; + return files[0]; + } + + public File[] getSelectedIOFiles() { + File[] files = (File[])myContext.getData(VcsDataConstants.IO_FILE_ARRAY); + if (files != null && files.length > 0) return files; + File file = getSelectedIOFile(); + if (file != null) return new File[]{file}; + return null; + } + + public int getModifiers() { + return myModifiers; + } + + public Refreshable getRefreshableDialog() { + return ((Refreshable)myContext.getData(Refreshable.PANEL)); + } + + public FilePath[] getSelectedFilePaths() { + ArrayList result = new ArrayList(); + FilePath path = (FilePath)myContext.getData(VcsDataConstants.FILE_PATH); + if (path != null) { + result.add(path); + } + + FilePath paths[] = (FilePath[])myContext.getData(VcsDataConstants.FILE_PATH_ARRAY); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + FilePath filePath = paths[i]; + if (!result.contains(filePath)) { + result.add(filePath); + } + } + } + + VirtualFile[] selectedFiles = getSelectedFiles(); + if (selectedFiles != null) { + for (int i = 0; i < selectedFiles.length; i++) { + VirtualFile selectedFile = selectedFiles[i]; + FilePathImpl filePath = new FilePathImpl(selectedFile); + if (!result.contains(filePath)) { + result.add(filePath); + } + } + } + + File[] selectedIOFiles = getSelectedIOFiles(); + if (selectedIOFiles != null){ + for (int i = 0; i < selectedIOFiles.length; i++) { + File selectedFile = selectedIOFiles[i]; + FilePathImpl filePath = FilePathImpl.create(selectedFile); + if ((filePath != null) && !result.contains(filePath)) { + result.add(filePath); + } + } + + } + + return result.toArray(new FilePath[result.size()]); + + } + + public FilePath getSelectedFilePath() { + FilePath[] selectedFilePaths = getSelectedFilePaths(); + if (selectedFilePaths.length == 0) { + return null; + } + else { + return selectedFilePaths[0]; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsGroupsWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsGroupsWrapper.java new file mode 100644 index 00000000000..e1e173b3cf5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/actions/VcsGroupsWrapper.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.impl.PresentationFactory; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.*; + +public class VcsGroupsWrapper extends DefaultActionGroup { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.actions.DefaultActionGroup"); + + private final PresentationFactory myPresentationFactory = new PresentationFactory(); + private AnAction[] myChildren; + + public VcsGroupsWrapper() { + super(); + } + + public void update(AnActionEvent e) { + super.update(e); + VcsContext dataContext = VcsContextWrapper.on(e); + if (myChildren == null) { + DefaultActionGroup vcsGroupsGroup = (DefaultActionGroup)ActionManager.getInstance().getAction("VcsGroup"); + ArrayList validChildren = new ArrayList(); + AnAction[] children = vcsGroupsGroup.getChildren(new AnActionEvent(null, e.getDataContext(), e.getPlace(), myPresentationFactory.getPresentation( + vcsGroupsGroup), + ActionManager.getInstance(), + 0)); + for (int i = 0; i < children.length; i++) { + AnAction child = children[i]; + LOG.assertTrue(child instanceof StandardVcsGroup, + "Any version control group should extends com.intellij.openapi.vcs.actions.StandardVcsGroup class. Groupd class: " + + child.getClass().getName() + + ", group ID: " + + ActionManager.getInstance().getId(child)); + if (child instanceof StandardVcsGroup) { + validChildren.add(child); + } + } + + myChildren = validChildren.toArray(new AnAction[validChildren.size()]); + + } + + Project project = dataContext.getProject(); + Presentation presentation = e.getPresentation(); + if (project == null) { + presentation.setVisible(false); + return; + } + + Collection currentVcses = new HashSet(); + + VirtualFile[] selectedFiles = dataContext.getSelectedFiles(); + + ProjectLevelVcsManager projectLevelVcsManager = ProjectLevelVcsManager.getInstance(project); + + Map vcsToActionMap = new HashMap(); + + for (int i = 0; i < myChildren.length; i++) { + StandardVcsGroup child = (StandardVcsGroup)myChildren[i]; + AbstractVcs vcs = child.getVcs(project); + vcsToActionMap.put(vcs, child); + } + + if (selectedFiles != null) { + for (int i = 0; i < selectedFiles.length; i++) { + VirtualFile selectedFile = selectedFiles[i]; + AbstractVcs vcs = projectLevelVcsManager.getVcsFor(selectedFile); + if (vcs != null) { + currentVcses.add(vcs); + } + } + } + + + if (currentVcses.size() == 1 && vcsToActionMap.containsKey(currentVcses.iterator().next())) { + updateFromAction(vcsToActionMap.get(currentVcses.iterator().next()), presentation); + } + else { + DefaultActionGroup composite = new DefaultActionGroup(); + for (int i = 0; i < myChildren.length; i++) { + StandardVcsGroup child = (StandardVcsGroup)myChildren[i]; + AbstractVcs vcs = child.getVcs(project); + if (currentVcses.contains(vcs)) { + composite.add(child); + } + } + updateFromAction(composite, presentation); + } + } + + private void updateFromAction(AnAction action, Presentation presentation) { + Presentation wrappedActionPresentation = myPresentationFactory.getPresentation(action); + presentation.setDescription(wrappedActionPresentation.getDescription()); + presentation.setText(wrappedActionPresentation.getText()); + presentation.setVisible(wrappedActionPresentation.isVisible()); + presentation.setEnabled(wrappedActionPresentation.isEnabled()); + removeAll(); + DefaultActionGroup wrappedGroup = (DefaultActionGroup)action; + AnAction[] children = wrappedGroup.getChildren(null); + for (int i = 0; i < children.length; i++) { + add(children[i]); + } + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/DocumentWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/DocumentWrapper.java new file mode 100644 index 00000000000..d611a87a14d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/DocumentWrapper.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.vcs.ex; + +import com.intellij.openapi.editor.Document; + +import java.util.ArrayList; + +/** + * author: lesya + */ +public class DocumentWrapper{ + private final Document myDocument; + public DocumentWrapper(Document document) { + myDocument = document; + } + + public int getLineNum(int offset){ + return myDocument.getLineNumber(offset); + } + + public String[] getLines(){ + return getLines(0, myDocument.getLineCount() - 1); + } + + public String[] getLines(int from, int to){ + ArrayList result = new ArrayList(); + for (int i = from; i <= to; i++){ + if (i >= myDocument.getLineCount()) break; + result.add(getLine(i)); + } + return result.toArray(new String[result.size()]); + } + + private String getLine(int i) { + int lineStartOffset = myDocument.getLineStartOffset(i); + String line = myDocument.getCharsSequence().subSequence(lineStartOffset, myDocument.getLineEndOffset(i)).toString(); + return line; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/LineStatusTracker.java new file mode 100644 index 00000000000..9e178ffbffb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -0,0 +1,740 @@ +package com.intellij.openapi.vcs.ex; + +import com.intellij.codeInsight.hint.EditorFragmentComponent; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.colors.*; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorGutterComponentEx; +import com.intellij.openapi.editor.ex.Highlighter; +import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.actions.ShowNextChangeMarkerAction; +import com.intellij.openapi.vcs.actions.ShowPrevChangeMarkerAction; +import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.ui.HintListener; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.SideBorder2; +import com.intellij.util.EventUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.*; +import java.util.List; + +/** + * author: lesya + */ +public class LineStatusTracker implements EditorColorsListener { + private final Document myDocument; + private final Document myUpToDateDocument; + private List myRanges = new ArrayList(); + private final Project myProject; + private int myHighlighterCount = 0; + + private EditorColorsListener myListener; + private final MyDocumentListener myDocumentListener = new MyDocumentListener(); + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.LineStatusTracker"); + + + private boolean myIsReleased = false; + + public LineStatusTracker(Document document, Document upToDateDocument, Project project) { + myDocument = document; + myUpToDateDocument = upToDateDocument; + myProject = project; + reinstallRanges(); + + myListener = EventUtil.createWeakListener(EditorColorsListener.class, this); + EditorColorsManager.getInstance().addEditorColorsListener(myListener); + myDocument.addDocumentListener(myDocumentListener); + + } + + private synchronized void reinstallRanges() { + reinstallRanges(new RangesBuilder(myDocument, myUpToDateDocument).getRanges()); + } + + private void reinstallRanges(List ranges) { + removeHighlighters(ranges); + myRanges = ranges; + addHighlighters(); + } + + private void addHighlighters() { + for (Iterator each = myRanges.iterator(); each.hasNext();) { + Range range = each.next(); + if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range)); + } + } + + synchronized private RangeHighlighter createHighlighter(Range range) { + int first = range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() + : myDocument.getLineStartOffset(range.getOffset1()); + + int second = range.getOffset2() >= myDocument.getLineCount() ? myDocument.getTextLength() + : myDocument.getLineStartOffset(range.getOffset2()); + + + RangeHighlighter highlighter = myDocument.getMarkupModel(myProject).addRangeHighlighter(first, + second, + HighlighterLayer.FIRST - 1, + null, + HighlighterTargetArea.LINES_IN_RANGE); + myHighlighterCount++; + TextAttributes attr = getAttributesFor(range); + highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor()); + highlighter.setThinErrorStripeMark(true); + highlighter.setGreedyToLeft(true); + highlighter.setGreedyToRight(true); + highlighter.setLineMarkerRenderer(createRenderer(range)); + highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter()); + return highlighter; + } + + + private void removeHighlighters(Collection newRanges) { + for (Iterator each = myRanges.iterator(); each.hasNext();) { + Range oldRange = each.next(); + if (!newRanges.contains(oldRange)) { + removeHighlighter(oldRange.getHighlighter()); + oldRange.setHighlighter(null); + } + } + } + + synchronized void removeHighlighter(RangeHighlighter highlighter) { + if (highlighter == null) return; + MarkupModel markupModel = myDocument.getMarkupModel(myProject); + if (markupModel == null) return; + markupModel.removeHighlighter(highlighter); + myHighlighterCount--; + } + + private static TextAttributesKey getDiffColor(Range range) { + switch (range.getType()) { + case Range.INSERTED: + return DiffColors.DIFF_INSERTED; + case Range.DELETED: + return DiffColors.DIFF_DELETED; + case Range.MODIFIED: + return DiffColors.DIFF_MODIFIED; + default: + return null; + } + } + + private static ColorKey getEditorColorNameFor(Range range) { + switch (range.getType()) { + case Range.MODIFIED: + return EditorColors.MODIFIED_LINES_COLOR; + default: + return EditorColors.ADDED_LINES_COLOR; + } + } + + private static TextAttributes getAttributesFor(Range range) { + EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); + Color color = globalScheme.getColor(getEditorColorNameFor(range)); + TextAttributes textAttributes = new TextAttributes(null, color, null, EffectType.BOXED, Font.PLAIN); + textAttributes.setErrorStripeColor(color); + return textAttributes; + } + + private static void paintGutterFragment(Editor editor, Graphics g, Rectangle r, TextAttributesKey diffAttributeKey) { + EditorGutterComponentEx gutter = ((EditorEx)editor).getGutterComponentEx(); + g.setColor(editor.getColorsScheme().getAttributes(diffAttributeKey).getBackgroundColor()); + int endX = gutter.getWhitespaceSeparatorOffset(); + int x = r.x + r.width - 2; + int width = endX - x; + if (r.height > 0) { + g.fillRect(x, r.y + 2, width, r.height - 4); + g.setColor(gutter.getFoldingColor(false)); + g.drawLine(x, r.y + 2, x + width, r.y + 2); + g.drawLine(x, r.y + 2, x, r.y + r.height - 3); + g.drawLine(x, r.y + r.height - 3, x + width, r.y + r.height - 3); + } + else { + int[] xPoints = new int[]{x, x, x + width - 1}; + int[] yPoints = new int[]{r.y - 4, r.y + 4, r.y}; + g.fillPolygon(xPoints, yPoints, 3); + + g.setColor(gutter.getFoldingColor(false)); + g.drawPolygon(xPoints, yPoints, 3); + } + } + + + private LineMarkerRenderer createRenderer(final Range range) { + return new ActiveGutterRenderer() { + public void paint(Editor editor, Graphics g, Rectangle r) { + paintGutterFragment(editor, g, r, getDiffColor(range)); + } + + public void doAction(Editor editor, MouseEvent e) { + e.consume(); + JComponent editorComponent = editor.getContentComponent(); + JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); + Point point = SwingUtilities.convertPoint(editorComponent, 0, e.getY(), layeredPane); + showActiveHint(range, editor, point); + } + }; + } + + public void globalSchemeChange(EditorColorsScheme scheme) { + EditorColorsManager.getInstance().removeEditorColorsListener(myListener); + ((ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(getProject())).resetTracker(this); + + } + + public synchronized void release() { + LOG.assertTrue(!myIsReleased); + myIsReleased = true; + removeHighlighters(new ArrayList()); + myDocument.removeDocumentListener(myDocumentListener); + EditorColorsManager.getInstance().removeEditorColorsListener(myListener); + } + + public Document getDocument() { + return myDocument; + } + + public VirtualFile getVirtualFile() { + return FileDocumentManager.getInstance().getFile(getDocument()); + } + + public List getRanges() { + return myRanges; + } + + public Document getUpToDateDocument() { + return myUpToDateDocument; + } + + private class MyDocumentListener extends DocumentAdapter { + private int myFirstChangedLine; + private int myUpToDateFirstLine; + private int myUpToDateLastLine; + Range myRange; + private int myLastChangedLine; + private int myLinesBeforeChange; + + public void beforeDocumentChange(DocumentEvent e) { + myFirstChangedLine = myDocument.getLineNumber(e.getOffset()); + myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength()); + if (StringUtil.endsWithChar(e.getOldFragment(), '\n')) myLastChangedLine++; + + myLinesBeforeChange = myDocument.getLineNumber(e.getOffset() + e.getOldLength()) + - myDocument.getLineNumber(e.getOffset()); + + Range firstChangedRange = getLastRangeBeforeLine(myFirstChangedLine); + + if (firstChangedRange == null) { + myUpToDateFirstLine = myFirstChangedLine; + } + else if (firstChangedRange.containsLine(myFirstChangedLine)) { + myFirstChangedLine = firstChangedRange.getOffset1(); + myUpToDateFirstLine = firstChangedRange.getUOffset1(); + } + else { + myUpToDateFirstLine = firstChangedRange.getUOffset2() + + (myFirstChangedLine - firstChangedRange.getOffset2()); + } + + Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine); + + if (myLastChangedRange == null) { + myUpToDateLastLine = myLastChangedLine; + } + else if (myLastChangedRange.containsLine(myLastChangedLine)) { + myUpToDateLastLine = myLastChangedRange.getUOffset2(); + myLastChangedLine = myLastChangedRange.getOffset2(); + } + else { + myUpToDateLastLine = myLastChangedRange.getUOffset2() + + (myLastChangedLine - myLastChangedRange.getOffset2()); + } + + } + + private Range getLastRangeBeforeLine(int line) { + Range result = null; + for (Iterator iterator = myRanges.iterator(); iterator.hasNext();) { + Range range = iterator.next(); + if (range.isMoreThen(line)) return result; + result = range; + } + return result; + } + + public void documentChanged(DocumentEvent e) { + int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength()); + int linesAfterChange = line + - myDocument.getLineNumber(e.getOffset()); + int linesShift = linesAfterChange - myLinesBeforeChange; + + List rangesAfterChange = getRangesAfter(myLastChangedLine); + List rangesBeforeChange = getRangesBefore(myFirstChangedLine); + + List changedRanges = getChangedRanges(myFirstChangedLine, myLastChangedLine); + + int newSize = rangesBeforeChange.size() + changedRanges.size() + rangesAfterChange.size(); + if (myRanges.size() != newSize) { + LOG.info("Ranges: " + myRanges + "; first changed line: " + myFirstChangedLine + + "; last changed line: " + myLastChangedLine); + LOG.assertTrue(false); + } + + + myLastChangedLine += linesShift; + + + List newChangedRanges = getNewChangedRanges(); + + shiftRanges(rangesAfterChange, linesShift); + + replaceRanges(changedRanges, newChangedRanges); + + myRanges = new ArrayList(); + + myRanges.addAll(rangesBeforeChange); + myRanges.addAll(newChangedRanges); + myRanges.addAll(rangesAfterChange); + + LOG.assertTrue(myHighlighterCount == myRanges.size(), + "Highlighters: " + myHighlighterCount + ", ranges: " + myRanges.size()); + + myRanges = mergeRanges(myRanges); + + for (Iterator each = myRanges.iterator(); each.hasNext();) { + Range range = each.next(); + if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range)); + + } + + LOG.assertTrue(myHighlighterCount == myRanges.size(), + "Highlighters: " + myHighlighterCount + ", ranges: " + myRanges.size()); + + } + + private List getNewChangedRanges() { + String[] lines = new DocumentWrapper(myDocument).getLines(myFirstChangedLine, myLastChangedLine); + String[] uLines = new DocumentWrapper(myUpToDateDocument) + .getLines(myUpToDateFirstLine, myUpToDateLastLine); + return new RangesBuilder(lines, uLines, myFirstChangedLine, myUpToDateFirstLine).getRanges(); + } + + private List mergeRanges(List ranges) { + ArrayList result = new ArrayList(); + Iterator iterator = ranges.iterator(); + if (!iterator.hasNext()) return result; + Range prev = iterator.next(); + while (iterator.hasNext()) { + Range range = iterator.next(); + if (prev.canBeMergedWith(range)) { + prev = prev.mergeWith(range, LineStatusTracker.this); + } + else { + result.add(prev); + prev = range; + } + } + result.add(prev); + return result; + } + + private void replaceRanges(List rangesInChange, List newRangesInChange) { + for (Iterator each = rangesInChange.iterator(); each.hasNext();) { + Range range = each.next(); + removeHighlighter(range.getHighlighter()); + range.setHighlighter(null); + } + for (Iterator each = newRangesInChange.iterator(); each.hasNext();) { + Range range = each.next(); + range.setHighlighter(createHighlighter(range)); + } + } + + private void shiftRanges(List rangesAfterChange, int shift) { + for (Iterator each = rangesAfterChange.iterator(); each.hasNext();) { + (each.next()).shift(shift); + } + } + + } + + private List getChangedRanges(int from, int to) { + return getChangedRanges(myRanges, from, to); + } + + public static List getChangedRanges(List ranges, int from, int to) { + ArrayList result = new ArrayList(); + for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { + Range range = iterator.next(); + if (range.getOffset1() <= to && range.getOffset2() >= from) result.add(range); +// if (range.getOffset1() > to) break; + } + return result; + } + + private List getRangesBefore(int line) { + return getRangesBefore(myRanges, line); + + } + + public static List getRangesBefore(List ranges, int line) { + ArrayList result = new ArrayList(); + + for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { + Range range = iterator.next(); + if (range.getOffset2() < line) result.add(range); + //if (range.getOffset2() > line) break; + } + return result; + } + + private List getRangesAfter(int line) { + return getRangesAfter(myRanges, line); + } + + public static List getRangesAfter(List ranges, int line) { + ArrayList result = new ArrayList(); + for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { + Range range = iterator.next(); + if (range.getOffset1() > line) result.add(range); + } + return result; + } + + public void moveToRange(final Range range, final Editor editor) { + final int firstOffset = myDocument.getLineStartOffset(Math.min(range.getOffset1(), myDocument.getLineCount() - 1) ); + editor.getCaretModel().moveToOffset(firstOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + + editor.getScrollingModel().runActionOnScrollingFinished(new Runnable() { + public void run() { + Point p = editor.visualPositionToXY(editor.offsetToVisualPosition(firstOffset)); + JComponent editorComponent = editor.getContentComponent(); + JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); + p = SwingUtilities.convertPoint(editorComponent, 0, p.y, layeredPane); + showActiveHint(range, editor, p); + } + }); + } + + private Range getNextRange(Range range) { + int index = myRanges.indexOf(range); + if (index == myRanges.size() - 1) return null; + return myRanges.get(index + 1); + } + + private Range getPrevRange(Range range) { + int index = myRanges.indexOf(range); + if (index == 0) return null; + return myRanges.get(index - 1); + } + + public Range getNextRange(int line) { + for (Iterator iterator = myRanges.iterator(); iterator.hasNext();) { + Range range = iterator.next(); + if (range.getOffset2() < line) continue; + return range; + } + return null; + } + + public Range getPrevRange(int line) { + for (ListIterator iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious();) { + Range range = iterator.previous(); + if (range.getOffset1() > line) continue; + return range; + } + return null; + } + + public static abstract class MyAction extends AnAction { + protected final LineStatusTracker myLineStatusTracker; + protected final Range myRange; + protected final Editor myEditor; + + protected MyAction(String text, Icon icon, LineStatusTracker lineStatusTracker, Range range, Editor editor) { + super(text, null, icon); + myLineStatusTracker = lineStatusTracker; + myRange = range; + myEditor = editor; + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(isEnabled()); + } + + public abstract boolean isEnabled(); + + protected int getMyRangeIndex() { + List ranges = myLineStatusTracker.getRanges(); + for (int i = 0; i < ranges.size(); i++) { + Range range = ranges.get(i); + if (range.getOffset1() == myRange.getOffset1() && range.getOffset2() == myRange.getOffset2()) { + return i; + } + } + return -1; + } + } + + public static class RollbackAction extends LineStatusTracker.MyAction { + public RollbackAction(LineStatusTracker lineStatusTracker, Range range, Editor editor) { + super("Rollback", IconLoader.getIcon("/actions/reset.png"), lineStatusTracker, range, editor); + } + + public boolean isEnabled() { + return true; + } + + public void actionPerformed(AnActionEvent e) { + CommandProcessor.getInstance().executeCommand(myLineStatusTracker.getProject(), new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + if (!myLineStatusTracker.getDocument().isWritable()) { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt(new VirtualFile[]{myLineStatusTracker.getVirtualFile()}); + } + else { + myLineStatusTracker.rollbackChanges(myRange); + } + } + }); + } + }, "Rollback Change", + null); + + } + } + + public void rollbackChanges(Range range) { + TextRange currentTextRange = getCurrentTextRange(range); + + if (range.getType() == Range.INSERTED) { + myDocument.replaceString(currentTextRange.getStartOffset(), + Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()), + ""); + } + else if (range.getType() == Range.DELETED) { + String upToDateContent = getUpToDateContent(range); + myDocument.insertString(currentTextRange.getStartOffset(), upToDateContent); + } + else { + + String upToDateContent = getUpToDateContent(range); + myDocument.replaceString(currentTextRange.getStartOffset(), + Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()), upToDateContent); + } + } + + public String getUpToDateContent(Range range) { + TextRange textRange = getUpToDateRange(range); + final int startOffset = textRange.getStartOffset(); + final int endOffset = Math.min(textRange.getEndOffset() + 1, + myUpToDateDocument.getTextLength()); + return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString(); + } + + private Project getProject() { + return myProject; + } + + public class ShowDiffAction extends LineStatusTracker.MyAction { + public ShowDiffAction(LineStatusTracker lineStatusTracker, Range range, Editor editor) { + super("Show Difference", IconLoader.getIcon("/actions/diff.png") + , lineStatusTracker, range, editor); + } + + public boolean isEnabled() { + return isModifiedRange() || isDeletedRange(); + } + + private boolean isDeletedRange() { + return myRange.getType() == Range.DELETED; + } + + private boolean isModifiedRange() { + return myRange.getType() == Range.MODIFIED; + } + + public void actionPerformed(AnActionEvent e) { + DiffManager.getInstance().getDiffTool().show(createDiffData()); + } + + private DiffRequest createDiffData() { + return new DiffRequest(myLineStatusTracker.getProject()) { + public DiffContent[] getContents() { + return new DiffContent[]{ + createDiffContent(myLineStatusTracker.getUpToDateDocument(), + myLineStatusTracker.getUpToDateRange(myRange), null), + createDiffContent(myLineStatusTracker.getDocument(), + myLineStatusTracker.getCurrentTextRange(myRange), myLineStatusTracker.getVirtualFile()) + }; + } + + public String[] getContentTitles() { + return new String[]{"Up To Date", "Current"}; + } + + public String getWindowTitle() { + return "Diff for Range"; + } + }; + } + + private DiffContent createDiffContent(final Document uDocument, TextRange textRange, VirtualFile file) { + DiffContent diffContent = new DocumentContent(myProject, uDocument); + return new FragmentContent(diffContent, textRange, myLineStatusTracker.getProject(), file); + } + } + + private TextRange getCurrentTextRange(Range range) { + return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument); + } + + private TextRange getUpToDateRange(Range range) { + return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument); + } + + private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) { + if (rangeType == emptyRangeCondition) { + int lineStartOffset; + if (offset1 == 0) { + lineStartOffset = 0; + } + else { + lineStartOffset = document.getLineEndOffset(offset1 - 1); + } + //if (lineStartOffset > 0) lineStartOffset--; + return new TextRange(lineStartOffset, lineStartOffset); + + } + else { + int startOffset = document.getLineStartOffset(offset1); + int endOffset = document.getLineEndOffset(offset2 - 1); + if (startOffset > 0) { + startOffset--; + endOffset--; + } + return new TextRange(startOffset, endOffset); + } + } + + + public void showActiveHint(Range range, final Editor editor, Point point) { + + DefaultActionGroup group = new DefaultActionGroup(); + + final AnAction globalShowNextAction = ActionManager.getInstance().getAction("VcsShowNextChangeMarker"); + final AnAction globalShowPrevAction = ActionManager.getInstance().getAction("VcsShowPrevChangeMarker"); + + final ShowPrevChangeMarkerAction localShowPrevAction = new ShowPrevChangeMarkerAction(getPrevRange(range), this, editor); + final ShowNextChangeMarkerAction localShowNextAction = new ShowNextChangeMarkerAction(getNextRange(range), this, editor); + + JComponent editorComponent = editor.getComponent(); + + localShowNextAction.registerCustomShortcutSet(localShowNextAction.getShortcutSet(), editorComponent); + localShowPrevAction.registerCustomShortcutSet(localShowPrevAction.getShortcutSet(), editorComponent); + + group.add(localShowPrevAction); + group.add(localShowNextAction); + + localShowNextAction.copyFrom(globalShowNextAction); + localShowPrevAction.copyFrom(globalShowPrevAction); + + group.add(new LineStatusTracker.RollbackAction(this, range, editor)); + group.add(new LineStatusTracker.ShowDiffAction(this, range, editor)); + + final List actionList = (List)editorComponent.getClientProperty(AnAction.ourClientProperty); + + actionList.remove(globalShowPrevAction); + actionList.remove(globalShowNextAction); + + JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, + group, true).getComponent(); + + final Color background = ((EditorEx)editor).getBackroundColor(); + final Color foreground = editor.getColorsScheme().getColor(EditorColors.CARET_COLOR); + toolbar.setBackground(background); + + toolbar.setBorder(new SideBorder2(foreground, foreground, + range.getType() != Range.INSERTED ? null : foreground, foreground, 1)); + + JPanel component = new JPanel(new BorderLayout()); + component.setOpaque(false); + + JPanel toolbarPanel = new JPanel(new BorderLayout()); + toolbarPanel.setOpaque(false); + toolbarPanel.add(toolbar, BorderLayout.WEST); + component.add(toolbarPanel, BorderLayout.NORTH); + + if (range.getType() != Range.INSERTED) { + DocumentEx doc = (DocumentEx)myUpToDateDocument; + EditorImpl uEditor = new EditorImpl(doc, true, myProject); + Highlighter highlighter = HighlighterFactory.createHighlighter(myProject, getFileName()); + uEditor.setHighlighter(highlighter); + + EditorFragmentComponent editorFragmentComponent = EditorFragmentComponent.createEditorFragmentComponent(uEditor, + range.getUOffset1(), + range.getUOffset2(), + false, + false); + + component.add(editorFragmentComponent, BorderLayout.CENTER); + } + + LightweightHint lightweightHint = new LightweightHint(component); + lightweightHint.addHintListener(new HintListener() { + public void hintHidden(EventObject event) { + actionList.remove(localShowPrevAction); + actionList.remove(localShowNextAction); + actionList.add(globalShowPrevAction); + actionList.add(globalShowNextAction); + } + }); + + HintManager.getInstance().showEditorHint(lightweightHint, editor, + point, HintManager.HIDE_BY_ANY_KEY | + HintManager.HIDE_BY_TEXT_CHANGE | + HintManager.HIDE_BY_OTHER_HINT | + HintManager.HIDE_BY_SCROLLING, -1, false); + } + + private String getFileName() { + VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument); + if (file == null) return ""; + return file.getName(); + } + + public static LineStatusTracker createOn(Document doc, String upToDateContent, Project project) { + Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(upToDateContent, "\n")); + document.setReadOnly(true); + return new LineStatusTracker(doc, document, project); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/ProjectLevelVcsManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/ProjectLevelVcsManagerEx.java new file mode 100644 index 00000000000..c71e5170939 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/ProjectLevelVcsManagerEx.java @@ -0,0 +1,19 @@ +package com.intellij.openapi.vcs.ex; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.ui.content.ContentManager; + +public abstract class ProjectLevelVcsManagerEx extends ProjectLevelVcsManager { + public static ProjectLevelVcsManagerEx getInstanceEx(Project project) { + return (ProjectLevelVcsManagerEx)project.getComponent(ProjectLevelVcsManager.class); + } + + public abstract LineStatusTracker getLineStatusTracker(Document document); + + public abstract LineStatusTracker setUpToDateContent(Document document, + String lastUpToDateContent); + + public abstract ContentManager getContentManager(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/Range.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/Range.java new file mode 100644 index 00000000000..eacb00e431a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/Range.java @@ -0,0 +1,182 @@ +package com.intellij.openapi.vcs.ex; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.util.diff.Diff; + +/** + * author: lesya + */ +public class Range { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.Range"); + public static final byte MODIFIED = 1; + public static final byte INSERTED = 2; + public static final byte DELETED = 3; + + private int myOffset1; + private int myOffset2; + private int myUpToDateOffset1; + private int myUpToDateOffset2; + private final byte myType; + private RangeHighlighter myRangeHighlighter; + + public static Range createOn(Diff.Change change, int shift, int upToDateShift) { + + byte type = getChangeTypeFrom(change); + + int offset1 = shift + change.line1; + int offset2 = offset1 + change.inserted; + + int uOffset1 = upToDateShift + change.line0; + int uOffset2 = uOffset1 + change.deleted; + + return new Range(offset1, offset2, uOffset1, uOffset2, type); + } + + private static byte getChangeTypeFrom(Diff.Change change) { + if ((change.deleted > 0) && (change.inserted > 0)) return MODIFIED; + if ((change.deleted > 0)) return DELETED; + if ((change.inserted > 0)) return INSERTED; + LOG.assertTrue(false, "Unknown change type"); + return 0; + } + + public Range(int offset1, int offset2, int uOffset1, int uOffset2, byte type) { + myOffset1 = offset1; + myOffset2 = offset2; + myUpToDateOffset1 = uOffset1; + myUpToDateOffset2 = uOffset2; + myType = type; + } + + public int hashCode() { + return myUpToDateOffset1 ^ myUpToDateOffset2 ^ myType ^ myOffset1 ^ myOffset2; + } + + public boolean equals(Object object) { + if (!(object instanceof Range)) return false; + Range other = (Range)object; + return + (myOffset1 == other.myOffset1) + && (myUpToDateOffset1 == other.myUpToDateOffset1) + && (myUpToDateOffset2 == other.myUpToDateOffset2) + && (myOffset1 == other.myOffset1) + && (myOffset2 == other.myOffset2) + && (myType == other.myType); + } + + public String toString() { + StringBuffer result = new StringBuffer(); + result.append(String.valueOf(myOffset1)); + result.append(", "); + result.append(String.valueOf(myOffset2)); + result.append(", "); + result.append(String.valueOf(myUpToDateOffset1)); + result.append(", "); + result.append(String.valueOf(myUpToDateOffset2)); + result.append(", "); + result.append(getTypeName()); + return result.toString(); + } + + private String getTypeName() { + switch (myType) { + case MODIFIED: + return "MODIFIED"; + case INSERTED: + return "INSERTED"; + case DELETED: + return "DELETED"; + } + return "UNKNOWN"; + } + + public byte getType() { + return myType; + } + + public int getUpToDateRangeLength() { + return myUpToDateOffset2 - myUpToDateOffset1; + } + + public boolean isInRange(int from, int to) { + return (myOffset2 >= from && myOffset1 <= from) || + ((myOffset1 <= to) && (myOffset2 >= to)); + } + + public void shift(int shift) { + myOffset1 += shift; + myOffset2 += shift; + } + + public boolean isAfter(int to) { + return myOffset1 > to; + } + + public int getCurrentLength() { + return myOffset2 - myOffset1; + } + + public int getOffset1() { + return myOffset1; + } + + public int getOffset2() { + return myOffset2; + } + + public int getUOffset1() { + return myUpToDateOffset1; + } + + public int getUOffset2() { + return myUpToDateOffset2; + } + + public boolean canBeMergedWith(Range range) { + return myOffset2 == range.myOffset1; + } + + public Range mergeWith(Range range, LineStatusTracker tracker) { + tracker.removeHighlighter(getHighlighter()); + tracker.removeHighlighter(range.getHighlighter()); + Range result = new Range(myOffset1, range.myOffset2, myUpToDateOffset1, range.myUpToDateOffset2, mergedStatusWith(range)); + return result; + } + + private byte mergedStatusWith(Range range) { + byte type = myType; + if (myType != range.myType) type = Range.MODIFIED; + return type; + } + + public boolean hasHighlighter() { + return myRangeHighlighter != null; + } + + public void setHighlighter(RangeHighlighter highlighter) { + myRangeHighlighter = highlighter; + } + + public RangeHighlighter getHighlighter() { + return myRangeHighlighter; + } + + public boolean contains(int offset1, int offset2) { + return getOffset1() <= offset1 && getOffset2() >= offset2; + } + + public boolean containsLine(int line) { + if (myType == DELETED) return (myOffset1 - 1) <= line + && (myOffset2) >= line; + return myOffset1 <= line && myOffset2 >= line; + } + + public boolean isMoreThen(int line) { + if (myType == DELETED) + return (getOffset1() - 1) > line; + else + return getOffset1() > line; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/RangesBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/RangesBuilder.java new file mode 100644 index 00000000000..3c13d298e09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ex/RangesBuilder.java @@ -0,0 +1,48 @@ +package com.intellij.openapi.vcs.ex; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.util.diff.Diff; + +import java.util.ArrayList; +import java.util.List; + +/** + * author: lesya + */ + +public class RangesBuilder { + private List myRanges; + + public RangesBuilder(String current, String upToDate) { + this(EditorFactory.getInstance().createDocument(current), EditorFactory.getInstance().createDocument(upToDate)); + } + + public RangesBuilder(Document current, Document upToDate) { + this(new DocumentWrapper(current).getLines(), + new DocumentWrapper(upToDate).getLines(), + 0, 0); + } + + public RangesBuilder(String[] current, String[] upToDate, int shift, int uShift) { + myRanges = new ArrayList(); + + //Diff diff = new Diff(upToDate, current); + //Diff.change ch = diff.diff_2(false); + Diff.Change ch = Diff.buildChanges(upToDate, current); + + + + while (ch != null) { + Range range = Range.createOn(ch, shift, uShift); + myRanges.add(range); + ch = ch.link; + } + + } + + public List getRanges() { + return myRanges; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/FileHistoryPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/FileHistoryPanel.java new file mode 100644 index 00000000000..c9e6132019a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/FileHistoryPanel.java @@ -0,0 +1,1025 @@ +package com.intellij.openapi.vcs.history; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.PanelWithActionsAndCloseButton; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.fileView.DualViewColumnInfo; +import com.intellij.openapi.vcs.ui.ReplaceFileConfirmationDialog; +import com.intellij.openapi.vcs.vfs.VcsFileSystem; +import com.intellij.openapi.vcs.vfs.VcsVirtualFile; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.dualView.CellWrapper; +import com.intellij.ui.dualView.DualTreeElement; +import com.intellij.ui.dualView.DualView; +import com.intellij.util.TreeItem; +import com.intellij.util.text.LineReader; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.IdeaUIManager; +import com.intellij.util.ui.LabelWithTooltip; +import com.intellij.util.ui.TableViewModel; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.List; + +/** + * author: lesya + */ + +public class FileHistoryPanel extends PanelWithActionsAndCloseButton { + private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.ui.FileHistoryDialog"); + + private JTextArea myComments; + private final DefaultActionGroup myPopupActions; + + private final Project myProject; + private final AbstractVcs myVcs; + private VcsHistorySession myHistorySession; + private final FilePath myFilePath; + private final DualView myDualView; + + + private static final String COMMIT_MESSAGE_TITLE = "Commit Message"; + + public static final DualViewColumnInfo REVISION = new VcsColumnInfo("Version", true) { + protected Comparable getDataOf(Object object) { + return ((VcsFileRevision)object).getRevisionNumber(); + } + + public Object valueOf(Object object) { + return ((VcsFileRevision)object).getRevisionNumber().asString(); + } + }; + + public static final DualViewColumnInfo DATE = new VcsColumnInfo("Date") { + protected Comparable getDataOf(Object object) { + Date date = ((VcsFileRevision)object).getRevisionDate(); + if (date == null) return ""; + return DATE_FORMAT.format(date); + } + + public int compare(Object o1, Object o2) { + return ((VcsFileRevision)o1).getRevisionDate() + .compareTo(((VcsFileRevision)o2).getRevisionDate()); + } + }; + + public static final DualViewColumnInfo AUTHOR = new VcsColumnInfo("Author") { + protected Comparable getDataOf(Object object) { + return ((VcsFileRevision)object).getAuthor(); + } + }; + + public static final DualViewColumnInfo MESSAGE = new VcsColumnInfo(COMMIT_MESSAGE_TITLE) { + protected Comparable getDataOf(Object object) { + String commitMessage = ((VcsFileRevision)object).getCommitMessage(); + try { + List lines = new LineReader().readLines(new ByteArrayInputStream(commitMessage.getBytes())); + if (!lines.isEmpty()) { + int lastIndex = lines.size() - 1; + if (lines.get(lastIndex).length == 0) lines.remove(lastIndex); + } + if (lines.isEmpty()) return ""; + if (lines.size() == 1) { + return new String(lines.get(0)); + } + else { + return new String(lines.get(0)) + "..."; + } + } + catch (IOException e) { + LOG.error(e); + return commitMessage; + } + + + } + + public TableCellRenderer getRenderer(Object p0) { + return new LabelWithTooltip(); + } + }; + + private final DualViewColumnInfo[] COLUMNS; + + public static final DateFormat DATE_FORMAT = + SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT); + private Map myRevisionToVirtualFile = new HashMap(); + + + public FileHistoryPanel(Project project, + FilePath filePath, + VcsHistorySession session, + AbstractVcs vcs, + ContentManager contentManager) { + super(contentManager, vcs.getVcsHistoryProvider().getHelpId()); + myVcs = vcs; + myProject = project; + myHistorySession = session; + myFilePath = filePath; + + VcsHistoryProvider provider = vcs.getVcsHistoryProvider(); + COLUMNS = createColumnList(provider); + + myComments = new JTextArea(); + myComments.setRows(5); + myComments.setEditable(false); + + HistoryAsTreeProvider treeHistoryProvider = provider.getTreeHistoryProvider(); + + if (treeHistoryProvider != null) { + + myDualView = new DualView(new TreeNodeOnVcsRevision(null, + treeHistoryProvider.createTreeOn(myHistorySession.getRevisionList())), + COLUMNS, "cvs_file_history", project); + } + else { + myDualView = new DualView(new TreeNodeOnVcsRevision(null, wrapWithTreeElements(myHistorySession.getRevisionList())), + COLUMNS, "cvs_file_history", project); + myDualView.switchToTheFlatMode(); + } + + createDualView(); + + myPopupActions = createPopupActions(); + + init(); + + chooseView(); + } + + private DualViewColumnInfo[] createColumnList(VcsHistoryProvider provider) { + ColumnInfo[] additionalColunms = provider.getRevisionColumns(); + ArrayList columns = new ArrayList(); + columns.addAll(Arrays.asList(new DualViewColumnInfo[]{REVISION, DATE, AUTHOR})); + columns.addAll(wrapAdditionalColumns(additionalColunms)); + columns.add(MESSAGE); + return columns.toArray(new DualViewColumnInfo[columns.size()]); + } + + private Collection wrapAdditionalColumns(ColumnInfo[] additionalColunms) { + ArrayList result = new ArrayList(); + if (additionalColunms != null) { + for (int i = 0; i < additionalColunms.length; i++) { + ColumnInfo additionalColunm = additionalColunms[i]; + result.add(new MyColumnWrapper(additionalColunm)); + } + } + return result; + } + + private List> wrapWithTreeElements(List revisions) { + ArrayList> result = new ArrayList>(); + for (Iterator iterator = revisions.iterator(); iterator.hasNext();) { + result.add(new TreeItem(iterator.next())); + } + return result; + } + + public void refresh(VcsHistorySession session) { + myHistorySession = session; + HistoryAsTreeProvider treeHistoryProvider = getHistoryProvider().getTreeHistoryProvider(); + + if (treeHistoryProvider != null) { + myDualView.setRoot(new TreeNodeOnVcsRevision(null, + treeHistoryProvider.createTreeOn(myHistorySession.getRevisionList()))); + } + else { + myDualView.setRoot(new TreeNodeOnVcsRevision(null, + wrapWithTreeElements(myHistorySession.getRevisionList()))); + } + + myDualView.rebuild(); + myDualView.repaint(); + } + + protected void addActionsTo(DefaultActionGroup group) { + addToGroup(false, group); + } + + private void createDualView() { + myDualView.setShowGrid(true); + myDualView.getTreeView().addMouseListener(new PopupHandler() { + public void invokePopup(Component comp, int x, int y) { + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UPDATE_POPUP, + myPopupActions); + popupMenu.getComponent().show(comp, x, y); + } + }); + + myDualView.getFlatView().addMouseListener(new PopupHandler() { + public void invokePopup(Component comp, int x, int y) { + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UPDATE_POPUP, + myPopupActions); + popupMenu.getComponent().show(comp, x, y); + } + }); + + myDualView.requestFocus(); + myDualView.setSelectionInterval(0, 0); + + + myDualView.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateMessage(); + } + }); + + myDualView.setRootVisible(false); + + myDualView.expandAll(); + + final TreeCellRenderer defaultCellRenderer = myDualView.getTree().getCellRenderer(); + + myDualView.setTreeCellRenderer(new TreeCellRenderer() { + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + Component result = defaultCellRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, + hasFocus); + + TreePath path = tree.getPathForRow(row); + if (path == null) return result; + VcsFileRevision revision = row >= 0 ? (VcsFileRevision)path.getLastPathComponent() : null; + + if (revision != null) { + + if (Comparing.equal(revision.getRevisionNumber(), myHistorySession.getCurrentRevisionNumber())) { + makeBold(result); + } + if (!selected && Comparing.equal(revision.getRevisionNumber(), myHistorySession.getCurrentRevisionNumber())) { + result.setBackground(new Color(188, 227, 231)); + ((JComponent)result).setOpaque(false); + } + } + else if (selected) { + result.setBackground(IdeaUIManager.getTableSelectionBackgroung()); + } + else { + result.setBackground(IdeaUIManager.getTableBackgroung()); + } + + return result; + } + }); + + myDualView.setCellWrapper(new CellWrapper() { + public void wrap(Component component, + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column, Object treeNode) { + VcsFileRevision revision = (VcsFileRevision)treeNode; + if (revision == null) return; + if (myHistorySession.getCurrentRevisionNumber() == null) return; + if (revision.getRevisionNumber().compareTo(myHistorySession.getCurrentRevisionNumber()) == 0) { + makeBold(component); + } + } + }); + + TableViewModel sortableModel = myDualView.getFlatView().getTableViewModel(); + sortableModel.setSortable(true); + sortableModel.sortByColumn(0); + + } + + private void makeBold(Component component) { + if (component instanceof JComponent) { + JComponent jComponent = (JComponent)component; + Font font = jComponent.getFont(); + if (font != null) { + jComponent.setFont(font.deriveFont(Font.BOLD)); + } + return; + } + else if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + makeBold(container.getComponent(i)); + } + } + + } + + private void updateMessage() { + List selection = getSelection(); + if (selection.size() != 1) { + myComments.setText(""); + } + else { + myComments.setText(getFirstSelectedRevision().getCommitMessage()); + myComments.setCaretPosition(0); + } + } + + + private void showDifferences(Project project, VcsFileRevision revision1, VcsFileRevision revision2) { + + try { + revision1.loadContent(); + revision2.loadContent(); + + VcsFileRevision left = revision1; + VcsFileRevision right = revision2; + if (VcsHistoryUtil.compare(revision1, revision2) > 0) { + left = revision2; + right = revision1; + } + byte[] content1 = left.getContent(); + byte[] content2 = right.getContent(); + + + SimpleDiffRequest diffData = new SimpleDiffRequest(myProject, myFilePath.getPresentableUrl()); + + diffData.addHint(DiffTool.HINT_SHOW_FRAME); + + LOG.assertTrue(content1 != null); + LOG.assertTrue(content2 != null); + + Document doc = myFilePath.getDocument(); + + String charset = myFilePath.getCharset().name(); + FileType fileType = myFilePath.getFileType(); + diffData.setContentTitles(left.getRevisionNumber().asString(), right.getRevisionNumber().asString()); + diffData.setContents(createContent(project, content1, left, doc, charset, fileType), + createContent(project, content2, right, doc, charset, fileType)); + DiffManager.getInstance().getDiffTool().show(diffData); + } + catch (final VcsException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog("Cannot show differences: " + e.getLocalizedMessage(), "Show Differences"); + } + }); + } + catch (IOException e) { + LOG.error(e); + } + catch (ProcessCanceledException ex) { + return; + } + } + + private static DiffContent createContent(Project project, byte[] content1, VcsFileRevision revision, Document doc, + String charset, FileType fileType) { + if (isCurrent(revision) && (doc != null)) return new DocumentContent(project, doc); + return new BinaryContent(content1, charset, fileType); + } + + private static boolean isCurrent(VcsFileRevision revision) { + return revision instanceof CurrentRevision; + } + + + protected JComponent createCenterPanel() { + Splitter splitter = new Splitter(true, getSplitterProportion()); + + splitter.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { + setSplitterProportionTo((Float)evt.getNewValue()); + } + } + }); + + JPanel commentGroup = new JPanel(new BorderLayout(4, 4)); + commentGroup.add(new JLabel(COMMIT_MESSAGE_TITLE + ":"), BorderLayout.NORTH); + commentGroup.add(ScrollPaneFactory.createScrollPane(myComments), BorderLayout.CENTER); + myComments.setWrapStyleWord(true); + myComments.setLineWrap(true); + + splitter.setFirstComponent(myDualView); + splitter.setSecondComponent(commentGroup); + return splitter; + } + + private void chooseView() { + if (showTree()) { + myDualView.switchToTheTreeMode(); + } + else { + myDualView.switchToTheFlatMode(); + } + } + + private boolean showTree() { + return getConfiguration().SHOW_FILE_HISTORY_AS_TREE; + } + + private void setSplitterProportionTo(Float newProportion) { + getConfiguration().FILE_HISTORY_SPLITTER_PROPORTION = newProportion.floatValue(); + } + + private float getSplitterProportion() { + return getConfiguration().FILE_HISTORY_SPLITTER_PROPORTION; + } + + private VcsConfiguration getConfiguration() { + return VcsConfiguration.getInstance(myProject); + } + + private DefaultActionGroup createPopupActions() { + return addToGroup(true, new DefaultActionGroup(null, false)); + + } + + private DefaultActionGroup addToGroup(boolean popup, DefaultActionGroup result) { + if (popup) { + result.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); + } + + result.add(new MyDiffAction()); + MyDiffWithCurrentAction diffWithCurrent = new MyDiffWithCurrentAction(); + if (!popup) { + myDualView.installDoubleClickHandler(diffWithCurrent); + } + result.add(diffWithCurrent); + result.add(new MyGetVersionAction()); + AnAction[] additionalActions = getHistoryProvider().getAdditionalActions(); + if (additionalActions != null) { + for (int i = 0; i < additionalActions.length; i++) { + result.add(additionalActions[i]); + } + } + result.add(new AnAction("Refresh", "Refresh file history", IconLoader.getIcon("/actions/sync.png")) { + public void actionPerformed(AnActionEvent e) { + try { + refresh(getHistoryProvider().createSessionFor(myFilePath)); + } + catch (VcsException e1) { + Messages.showErrorDialog("Cannot refresh: " + e1.getLocalizedMessage(), "Refresh"); + } + + } + }); + + if (!popup && supportsTree()) { + result.add(new MyShowAsTreeAction()); + } + + return result; + } + + private boolean supportsTree() { + return getHistoryProvider().getTreeHistoryProvider() != null; + } + + private VcsHistoryProvider getHistoryProvider() { + return myVcs.getVcsHistoryProvider(); + } + + private class MyShowAsTreeAction extends ToggleAction { + public MyShowAsTreeAction() { + super("Show as Tree", null, IconLoader.getIcon("/_cvs/showAsTree.png")); + } + + public boolean isSelected(AnActionEvent e) { + return getConfiguration().SHOW_FILE_HISTORY_AS_TREE; + } + + public void setSelected(AnActionEvent e, boolean state) { + getConfiguration().SHOW_FILE_HISTORY_AS_TREE = state; + chooseView(); + } + } + + private class MyDiffAction extends AbstractActionForSomeSelection { + public MyDiffAction() { + super("Compare", "Compare versions", "diff", 2, FileHistoryPanel.this); + } + + protected void actionPerformed() { + try { + showDifferences(myProject, (VcsFileRevision)getSelection().get(0), + (VcsFileRevision)getSelection().get(1)); + } + catch (Exception e) { + LOG.error(e); + } + } + + public boolean isEnabled() { + if (!super.isEnabled()) return false; + return true; + } + } + + private class MyDiffWithCurrentAction extends AbstractActionForSomeSelection { + public MyDiffWithCurrentAction() { + super("Compare with Local", "Compare with local version", "diffWithCurrent", 1, FileHistoryPanel.this); + } + + protected void actionPerformed() { + showDifferences(myProject, getFirstSelectedRevision(), new CurrentRevision(myFilePath.getVirtualFile(), + myHistorySession.getCurrentRevisionNumber())); + } + + public boolean isEnabled() { + if (myFilePath.getVirtualFile() == null) return false; + if (!super.isEnabled()) return false; + //if (CvsEntriesManager.getInstance().getEntryFor(myVirtualFile) == null) return false; + return true; + } + } + + private class MyGetVersionAction extends AbstractActionForSomeSelection { + public MyGetVersionAction() { + super("Get", "Get version from cvs", "get", 1, FileHistoryPanel.this); + } + + public void update(AnActionEvent e) { + if (getVirtualParent() == null) { + Presentation presentation = e.getPresentation(); + presentation.setVisible(false); + presentation.setEnabled(false); + } + else { + super.update(e); + } + } + + protected void actionPerformed() { + final VcsFileRevision revision = getFirstSelectedRevision(); + if (getVirtualFile() != null) { + if (!new ReplaceFileConfirmationDialog(myProject, "Get Revision").confirmFor(new VirtualFile[]{getVirtualFile()})) return; + } + + try { + revision.loadContent(); + } + catch (VcsException e) { + Messages.showErrorDialog("Get Version", "Cannot load versopn: " + e.getLocalizedMessage()); + } + catch (ProcessCanceledException ex) { + return; + } + getVersion(revision); + refreshFile(revision); + } + + private void refreshFile(VcsFileRevision revision) { + if (getVirtualFile() == null) { + final LvcsAction action = startLvcsAction(revision); + if (getVirtualParent() != null) { + getVirtualParent().refresh(true, true, new Runnable() { + public void run() { + myFilePath.refresh(); + action.finish(); + } + }); + } + } + } + + private void getVersion(final VcsFileRevision revision) { + if ((getVirtualFile() != null) && !getVirtualFile().isWritable()) { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt(new VirtualFile[]{getVirtualFile()}); + return; + } + + LvcsAction action = getVirtualFile() != null ? startLvcsAction(revision) : LvcsAction.EMPTY; + + byte[] revisionContent = null; + try { + revision.loadContent(); + revisionContent = revision.getContent(); + } + catch (IOException e) { + LOG.error(e); + return; + } + catch (VcsException e) { + Messages.showMessageDialog("Cannot load revision test: " + e.getLocalizedMessage(), "Get Revision Content", + Messages.getInformationIcon()); + return; + } catch (ProcessCanceledException ex){ + return; + } + final byte[] finalRevisionContent = revisionContent; + try { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, + getVersionRunnable(finalRevisionContent), createGetActionTitle(revision), + null); + } + }); + if (getVirtualFile() != null) { + FileStatusManager.getInstance(myProject).fileStatusChanged(getVirtualFile()); + } + } + finally { + action.finish(); + } + } + + private LvcsAction startLvcsAction(final VcsFileRevision revision) { + return LocalVcs.getInstance(myProject).startAction(createGetActionTitle(revision), getFilePath(), false); + } + + private String createGetActionTitle(final VcsFileRevision revision) { + return getIOFile().getAbsolutePath() + ": Get Version " + revision.getRevisionNumber(); + } + + private File getIOFile() { + return myFilePath.getIOFile(); + } + + private String getFilePath() { + return myFilePath.getPath(); + } + + private Runnable getVersionRunnable(final byte[] revision) { + return new Runnable() { + public void run() { + try { + write(revision); + } + catch (Exception e) { + LOG.error(e); + } + } + }; + } + + private void write(byte[] revision) throws Exception { + if (getVirtualFile() == null) { + writeContentToIOFile(revision); + } + else { + Document document = myFilePath.getDocument(); + if (document == null) { + writeContentToFile(revision); + } + else { + writeContentToDocument(document, revision); + } + } + } + + private void writeContentToIOFile(byte[] revisionContent) throws Exception { + FileOutputStream outputStream = new FileOutputStream(getIOFile()); + try { + outputStream.write(revisionContent); + } + finally { + outputStream.close(); + } + } + + private void writeContentToFile(final byte[] revision) { + + try { + OutputStream output = getVirtualFile().getOutputStream(this); + try { + output.write(revision); + } + finally { + output.close(); + } + } + catch (Exception e) { + LOG.error(e); + } + } + + private void writeContentToDocument(final Document document, byte[] revisionContent) throws Exception { + final String content = StringUtil.convertLineSeparators(new String(revisionContent, myFilePath.getCharset().name())); + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + document.replaceString(0, document.getTextLength(), content); + } + }, "Get CVS Version", null); + } + + } + + public Object getData(String dataId) { + VcsFileRevision firstSelectedRevision = getFirstSelectedRevision(); + if (DataConstants.NAVIGATABLE.equals(dataId)) { + List selectedItems = getSelection(); + if (selectedItems.size() != 1) return null; + VcsFileRevision revision = firstSelectedRevision; + VirtualFile virtualFileForRevision = createVirtualFileForRevision(revision); + if (virtualFileForRevision != null) { + return new OpenFileDescriptor(myProject, virtualFileForRevision); + } + else { + return null; + } + } + else if (DataConstants.PROJECT.equals(dataId)) { + return myProject; + } + else if (VcsDataConstants.VCS_FILE_REVISION.equals(dataId)) { + return firstSelectedRevision; + } + else if (VcsDataConstants.VCS_VIRTUAL_FILE.equals(dataId)) { + if (firstSelectedRevision == null) return null; + return createVirtualFileForRevision(firstSelectedRevision); + } + else if (VcsDataConstants.FILE_PATH.equals(dataId)) { + return myFilePath; + } + else if (VcsDataConstants.IO_FILE.equals(dataId)) { + return myFilePath.getIOFile(); + } + else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + if (getVirtualFile() == null) return null; + if (getVirtualFile().isValid()) { + return getVirtualFile(); + } + else { + return null; + } + } + else { + return null; + } + } + + private VirtualFile createVirtualFileForRevision(VcsFileRevision revision) { + if (!myRevisionToVirtualFile.containsKey(revision)) { + myRevisionToVirtualFile.put(revision, + new VcsVirtualFile(myFilePath.getPath(), revision, + VcsFileSystem.getInstance())); + } + return myRevisionToVirtualFile.get(revision); + } + + public List getSelection() { + return myDualView.getSelection(); + } + + private VcsFileRevision getFirstSelectedRevision() { + List selection = getSelection(); + if (selection.isEmpty()) return null; + return ((TreeNodeOnVcsRevision)selection.get(0)).myRevision; + } + + class TreeNodeOnVcsRevision extends DefaultMutableTreeNode + implements VcsFileRevision, DualTreeElement { + private final VcsFileRevision myRevision; + + public TreeNodeOnVcsRevision(VcsFileRevision revision, + List> roots) { + myRevision = revision == null ? VcsFileRevision.NULL : revision; + for (Iterator iterator = roots.iterator(); iterator.hasNext();) { + TreeItem root = (TreeItem)iterator.next(); + add(new TreeNodeOnVcsRevision(root.getData(), root.getChildren())); + } + } + + public String getAuthor() { + return myRevision.getAuthor(); + } + + public String getCommitMessage() { + return myRevision.getCommitMessage(); + } + + public void loadContent() throws VcsException { + myRevision.loadContent(); + } + + public VcsRevisionNumber getRevisionNumber() { + return myRevision.getRevisionNumber(); + } + + public Date getRevisionDate() { + return myRevision.getRevisionDate(); + } + + public byte[] getContent() throws IOException { + return myRevision.getContent(); + } + + public String toString() { + return getRevisionNumber().asString(); + } + + public boolean shouldBeInTheFlatView() { + return myRevision != VcsFileRevision.NULL; + } + + } + + protected void dispose() { + super.dispose(); + myDualView.dispose(); + } + + abstract class AbstractActionForSomeSelection extends AnAction { + private final int mySuitableSelectedElements; + private final FileHistoryPanel mySelectionProvider; + + public AbstractActionForSomeSelection(String name, + String description, + String iconName, + int suitableSelectionSize, + FileHistoryPanel tableProvider) { + super(name, description, IconLoader.getIcon("/actions/" + iconName + ".png")); + mySuitableSelectedElements = suitableSelectionSize; + mySelectionProvider = tableProvider; + } + + protected abstract void actionPerformed(); + + public boolean isEnabled() { + return mySelectionProvider.getSelection().size() == mySuitableSelectedElements; + } + + public void actionPerformed(AnActionEvent e) { + if (!isEnabled()) return; + actionPerformed(); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setVisible(true); + presentation.setEnabled(isEnabled()); + } + } + + abstract static class VcsColumnInfo extends DualViewColumnInfo implements Comparator { + private boolean myIsReverse = false; + + public VcsColumnInfo(String name) { + super(name); + } + + public VcsColumnInfo(String name, boolean isReverse) { + super(name); + myIsReverse = isReverse; + } + + protected abstract Comparable getDataOf(Object o); + + public Comparator getComparator() { + return new Comparator() { + public int compare(Object o, Object o1) { + return getDataOf(o).compareTo(getDataOf(o1)); + } + }; + } + + public Object valueOf(Object object) { + Comparable result = getDataOf(object); + return result == null ? "" : result.toString(); + } + + public int compare(Object o1, Object o2) { + int result = compareObjects(getDataOf(o1), getDataOf(o2)); + if (myIsReverse) { + return result * -1; + } + else { + return result; + } + } + + private int compareObjects(Comparable data1, Comparable data2) { + if (data1 == data2) return 0; + if (data1 == null) return -1; + if (data2 == null) return 1; + return data1.compareTo(data2); + } + + public boolean shouldBeShownIsTheTree() { + return true; + } + + public boolean shouldBeShownIsTheTable() { + return true; + } + + } + + private static class MyColumnWrapper extends DualViewColumnInfo { + private final ColumnInfo myBaseColumn; + + public Comparator getComparator() { + final Comparator comparator = myBaseColumn.getComparator(); + if (comparator == null) return null; + return new Comparator() { + public int compare(TreeNodeOnVcsRevision o1, TreeNodeOnVcsRevision o2) { + if (o1 == null) return -1; + if (o2 == null) return 1; + VcsFileRevision revision1 = o1.myRevision; + VcsFileRevision revision2 = o2.myRevision; + if (revision1 == null) return -1; + if (revision2 == null) return 1; + return comparator.compare(revision1, revision2); + } + }; + } + + public String getName() { + return myBaseColumn.getName(); + } + + public Class getColumnClass() { + return myBaseColumn.getColumnClass(); + } + + public boolean isCellEditable(TreeNodeOnVcsRevision o) { + return myBaseColumn.isCellEditable(o.myRevision); + } + + public void setValue(TreeNodeOnVcsRevision o, Object aValue) { + myBaseColumn.setValue(o.myRevision, aValue); + } + + public TableCellRenderer getRenderer(TreeNodeOnVcsRevision p0) { + return myBaseColumn.getRenderer(p0.myRevision); + } + + public TableCellEditor getEditor(TreeNodeOnVcsRevision item) { + return myBaseColumn.getEditor(item.myRevision); + } + + public String getMaxStringValue() { + return myBaseColumn.getMaxStringValue(); + } + + public int getAdditionalWidth() { + return myBaseColumn.getAdditionalWidth(); + } + + public int getWidth(JTable table) { + return myBaseColumn.getWidth(table); + } + + public void setName(String s) { + myBaseColumn.setName(s); + } + + public MyColumnWrapper(ColumnInfo additionalColunm) { + super(additionalColunm.getName()); + myBaseColumn = additionalColunm; + } + + public boolean shouldBeShownIsTheTree() { + return true; + } + + public boolean shouldBeShownIsTheTable() { + return true; + } + + public Object valueOf(TreeNodeOnVcsRevision o) { + return myBaseColumn.valueOf(o.myRevision); + } + } + + private VirtualFile getVirtualFile() { + return myFilePath.getVirtualFile(); + } + + private VirtualFile getVirtualParent() { + return myFilePath.getVirtualFileParent(); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsBlockHistoryDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsBlockHistoryDialog.java new file mode 100644 index 00000000000..db20672d015 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsBlockHistoryDialog.java @@ -0,0 +1,72 @@ +package com.intellij.openapi.vcs.history.impl; + +import com.intellij.diff.Block; +import com.intellij.diff.FindBlock; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.history.VcsFileRevision; +import com.intellij.openapi.vcs.history.VcsHistoryProvider; +import com.intellij.openapi.vcs.history.VcsHistoryUtil; +import com.intellij.openapi.vcs.history.VcsHistorySession; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.*; + +/** + * author: lesya + */ +public class VcsBlockHistoryDialog extends VcsHistoryDialog{ + + private final int mySelectionStart; + private final int mySelectionEnd; + + private final Map myRevisionToContentMap = new com.intellij.util.containers.HashMap(); + + public VcsBlockHistoryDialog(Project project, final VirtualFile file, + AbstractVcs vcs, + VcsHistoryProvider provider, + VcsHistorySession session, int selectionStart, int selectionEnd){ + super(project, file, provider, session,vcs); + mySelectionStart = selectionStart; + mySelectionEnd = selectionEnd; + } + + protected String getContentToShow(VcsFileRevision revision) { + return getBlock(revision).getBlockContent(); + } + + private Block getBlock(VcsFileRevision revision){ + if (myRevisionToContentMap.containsKey(revision)) + return myRevisionToContentMap.get(revision); + + int index = myRevisions.indexOf(revision); + + if (index == 0) + myRevisionToContentMap.put(revision, new Block(getContentOf(revision), mySelectionStart, mySelectionEnd)); + else { + Block prevBlock = getBlock(myRevisions.get(index - 1)); + myRevisionToContentMap.put(revision, new FindBlock(getContentOf(revision), prevBlock).getBlockInThePrevVersion()); + } + return myRevisionToContentMap.get(revision); + } + + protected VcsFileRevision[] revisionsNeededToBeLoaded(VcsFileRevision[] revisions) { + Collection result = new HashSet(); + for (int i = 0; i < revisions.length; i++) { + VcsFileRevision revision = revisions[i]; + result.addAll(collectRevisionsFromFirstTo(revision)); + } + + return result.toArray(new VcsFileRevision[result.size()]); + } + + private Collection collectRevisionsFromFirstTo(VcsFileRevision revision) { + ArrayList result = new ArrayList(); + for (Iterator iterator = myRevisions.iterator(); iterator.hasNext();) { + VcsFileRevision vcsFileRevision = (VcsFileRevision) iterator.next(); + if (VcsHistoryUtil.compare(revision, vcsFileRevision) > 0) continue; + result.add(vcsFileRevision); + } + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java new file mode 100644 index 00000000000..6a3a34cb485 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java @@ -0,0 +1,391 @@ +package com.intellij.openapi.vcs.history.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.DiffManager; +import com.intellij.openapi.diff.DiffPanel; +import com.intellij.openapi.diff.SimpleContent; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.VcsConfiguration; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.history.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.table.TableView; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; +import com.intellij.util.ui.SortableColumnModel; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.List; + +public class VcsHistoryDialog extends DialogWrapper { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.history.impl.VcsHistoryDialog"); + private final AbstractVcs myActiveVcs; + + private final static DateFormat DATE_FORMAT = SimpleDateFormat + .getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT, Locale.getDefault()); + + private final DiffPanel myDiffPanel; + private final Project myProject; + + private final static ColumnInfo REVISION = new ColumnInfo("Revision") { + public Object valueOf(Object object) { + return ((VcsFileRevision)object).getRevisionNumber(); + } + + }; + + private final static ColumnInfo DATE = new ColumnInfo("Date") { + public Object valueOf(Object object) { + Date date = ((VcsFileRevision)object).getRevisionDate(); + if (date == null) return ""; + return DATE_FORMAT.format(date); + } + + }; + + private final static ColumnInfo MESSAGE = new ColumnInfo("Message") { + public Object valueOf(Object object) { + return ((VcsFileRevision)object).getCommitMessage(); + } + + }; + + private final static ColumnInfo AUTHOR = new ColumnInfo("Author") { + public Object valueOf(Object object) { + return ((VcsFileRevision)object).getAuthor(); + } + + }; + + private final static ColumnInfo[] COLUMNS = new ColumnInfo[]{REVISION, DATE, AUTHOR, MESSAGE}; + + private final TableView myList; + protected final List myRevisions; + private Splitter mySplitter; + private final VirtualFile myFile; + private final JCheckBox myChangesOnlyCheckBox = new JCheckBox("Changes only"); + private final Map myCachedContents = new com.intellij.util.containers.HashMap(); + private final JTextArea myComments = new JTextArea(); + private static final int CURRENT = 0; + private boolean myIsInLoading = false; + private final String myHelpId; + private boolean myIsDisposed = false; + private final FileType myContentFileType; + + + public VcsHistoryDialog(Project project, + final VirtualFile file, + final VcsHistoryProvider vcsHistoryProvider, + VcsHistorySession session, + AbstractVcs vcs){ + super(project, true); + myProject = project; + myActiveVcs = vcs; + myRevisions = new ArrayList(); + myFile = file; + myHelpId = vcsHistoryProvider.getHelpId(); + myList = new TableView(new ListTableModel(createColumns(vcsHistoryProvider.getRevisionColumns()))); + ((SortableColumnModel)myList.getModel()).setSortable(false); + + myDiffPanel = DiffManager.getInstance().createDiffPanel(getWindow(), myProject); + + myRevisions.addAll(session.getRevisionList()); + myRevisions.add(new CurrentRevision(file, session.getCurrentRevisionNumber())); + Collections.sort((List)myRevisions, new Comparator() { + public int compare(VcsFileRevision rev1, VcsFileRevision rev2){ + return VcsHistoryUtil.compare(rev1, rev2); + } + }); + Collections.reverse(myRevisions); + + myContentFileType = FileTypeManager.getInstance().getFileTypeByFile(file); + + updateRevisionsList(); + + mySplitter = new Splitter(true, getVcsConfiguration().FILE_HISTORY_DIALOG_SPLITTER_PROPORTION); + + mySplitter.setFirstComponent(myDiffPanel.getComponent()); + mySplitter.setSecondComponent(createBottomPanel()); + + mySplitter.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { + getVcsConfiguration().FILE_HISTORY_DIALOG_SPLITTER_PROPORTION + = ((Float)evt.getNewValue()).floatValue(); + } + } + }); + + myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (myList.getSelectedRowCount() == 1) { + myComments.setText(myRevisions.get(myList.getSelectedRow()).getCommitMessage()); + myComments.setCaretPosition(0); + } + else { + myComments.setText(""); + } + updateDiff(); + } + }); + + myChangesOnlyCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateRevisionsList(); + } + }); + + init(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myList.getSelectionModel().addSelectionInterval(0, 0); + } + }); + + setTitle("History for File " + file.getName()); + } + + public void show() { + myList.getSelectionModel().setSelectionInterval(0, 0); + super.show(); + } + + private ColumnInfo[] createColumns(ColumnInfo[] additionalColumns) { + if (additionalColumns == null) { + return COLUMNS; + } + + ColumnInfo[] result = new ColumnInfo[additionalColumns.length + COLUMNS.length]; + + System.arraycopy(COLUMNS, 0, result, 0, COLUMNS.length); + + for (int i = 0; i < additionalColumns.length; i++) { + ColumnInfo additionalColumn = additionalColumns[i]; + result[i + COLUMNS.length] = additionalColumn; + } + + return result; + } + + protected synchronized String getContentOf(VcsFileRevision revision) { + LOG.assertTrue(myCachedContents.containsKey(revision), revision.getRevisionNumber().asString()); + return myCachedContents.get(revision); + } + + private synchronized void loadContentsFor(final VcsFileRevision[] revisions) { + if (myIsInLoading) return; + myIsInLoading = true; + synchronized (myCachedContents) { + + final VcsFileRevision[] revisionsToLoad = revisionsNeededToBeLoaded(revisions); + ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() { + public void run() { + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + progressIndicator.pushState(); + try { + for (int i = 0; i < revisionsToLoad.length; i++) { + final VcsFileRevision vcsFileRevision = revisionsToLoad[i]; + progressIndicator.setText2("Loading revision " + vcsFileRevision.getRevisionNumber()); + progressIndicator.setFraction((double)i / (double)revisionsToLoad.length); + if (!myCachedContents.containsKey(vcsFileRevision)) { + try { + vcsFileRevision.loadContent(); + } + catch (final VcsException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog("Load Version", "Cannot load version " + vcsFileRevision.getRevisionNumber() + + ":" + e.getLocalizedMessage()); + } + }); + } catch (ProcessCanceledException ex){ + return; + } + String content = null; + try { + content = new String(vcsFileRevision.getContent(), + myFile.getCharset().name()); + } + catch (IOException e) { + LOG.error(e); + } + myCachedContents.put(vcsFileRevision, content); + + } + } + } + finally { + myIsInLoading = false; + progressIndicator.popState(); + } + + } + }, "Loading Contents", false, myProject); + } + + } + + protected VcsFileRevision[] revisionsNeededToBeLoaded(VcsFileRevision[] revisions) { + return revisions; + } + + private void updateRevisionsList() { + if (myIsInLoading) return; + if (myChangesOnlyCheckBox.isSelected()) { + loadContentsFor(myRevisions.toArray(new VcsFileRevision[myRevisions.size()])); + ((ListTableModel)myList.getModel()).setItems(filteredRevisions()); + ((ListTableModel)myList.getModel()).fireTableDataChanged(); + updateDiff(0, 0); + + } + else { + ((ListTableModel)myList.getModel()).setItems(myRevisions); + ((ListTableModel)myList.getModel()).fireTableDataChanged(); + } + + } + + private List filteredRevisions() { + ArrayList result = new ArrayList(); + VcsFileRevision nextRevision = myRevisions.get(myRevisions.size() - 1); + result.add(nextRevision); + for (int i = myRevisions.size() - 2; i >= 0; i--) { + VcsFileRevision vcsFileRevision = myRevisions.get(i); + if (getContentToShow(nextRevision).equals(getContentToShow(vcsFileRevision))) continue; + result.add(vcsFileRevision); + nextRevision = vcsFileRevision; + } + Collections.reverse(result); + return result; + } + + private synchronized void updateDiff() { + int[] selectedIndices = myList.getSelectedRows(); + if (selectedIndices.length == 0) { + updateDiff(CURRENT, CURRENT); + } + else if (selectedIndices.length == 1) { + updateDiff(selectedIndices[0], CURRENT); + } + else { + updateDiff(selectedIndices[selectedIndices.length - 1], selectedIndices[0]); + } + } + + private synchronized void updateDiff(int first, int second) { + if (myIsDisposed) return; + List items = ((ListTableModel)myList.getModel()).getItems(); + VcsFileRevision firstRev = (VcsFileRevision)items.get(first); + VcsFileRevision secondRev = (VcsFileRevision)items.get(second); + + if (VcsHistoryUtil.compare(firstRev, secondRev) > 0) { + VcsFileRevision tmp = firstRev; + firstRev = secondRev; + secondRev = tmp; + } + + loadContentsFor(new VcsFileRevision[]{firstRev, secondRev}); + myDiffPanel.setContents(new SimpleContent(getContentToShow(firstRev), myContentFileType), + new SimpleContent(getContentToShow(secondRev), myContentFileType)); + myDiffPanel.setTitle1("Revision " + firstRev.getRevisionNumber()); + myDiffPanel.setTitle2("Revision " + secondRev.getRevisionNumber()); + + } + + protected synchronized void dispose() { + myIsDisposed = true; + myDiffPanel.dispose(); + super.dispose(); + } + + protected String getContentToShow(final VcsFileRevision firstRev) { + return getContentOf(firstRev); + } + + private JComponent createBottomPanel() { + Splitter splitter = new Splitter(true, getVcsConfiguration() + .FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION); + + splitter.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { + getVcsConfiguration().FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION + = ((Float)evt.getNewValue()).floatValue(); + } + } + }); + + JPanel tablePanel = new JPanel(new BorderLayout()); + tablePanel.add(createTablePanel(), BorderLayout.CENTER); + tablePanel.add(myChangesOnlyCheckBox, BorderLayout.NORTH); + + splitter.setFirstComponent(tablePanel); + splitter.setSecondComponent(createComments()); + + return splitter; + } + + private VcsConfiguration getVcsConfiguration() { + return myActiveVcs.getConfiguration(); + } + + private JComponent createComments() { + myComments.setRows(5); + myComments.setEditable(false); + myComments.setLineWrap(true); + return new JScrollPane(myComments); + } + + private JComponent createTablePanel() { + return ScrollPaneFactory.createScrollPane(myList); + } + + protected JComponent createCenterPanel() { + return mySplitter; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpId); + } + + protected Action[] createActions() { + Action okAction = getOKAction(); + okAction.putValue(Action.NAME, "Close"); + if (myHelpId != null) { + return new Action[]{okAction, getHelpAction()}; + } + else { + return new Action[]{okAction}; + } + } + + protected String getDimensionServiceKey() { + return "VCS.FileHistoryDialog"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java new file mode 100644 index 00000000000..9b510dd96bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java @@ -0,0 +1,441 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.codeInsight.actions.OptimizeImportsProcessor; +import com.intellij.codeInsight.actions.ReformatCodeProcessor; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.localVcs.*; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressWindow; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; +import com.intellij.openapi.vcs.checkin.VcsOperation; +import com.intellij.openapi.vcs.impl.checkin.CheckinHandler; +import com.intellij.openapi.vcs.ui.Refreshable; +import com.intellij.openapi.vcs.ui.impl.CheckinProjectPanelImpl; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiImportList; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.MessageView; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; + +import javax.swing.*; +import java.io.File; +import java.util.*; + +public class AbstractVcsHelperImpl extends AbstractVcsHelper implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.impl.AbstractVcsHelperImpl"); + + private Project myProject; + + public AbstractVcsHelperImpl(Project project) { + myProject = project; + } + + private static final Key KEY = Key.create("ErrorTreeViewPanel.KEY"); + + public void showErrors(final List abstractVcsExceptions, final String tabDisplayName) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + if (abstractVcsExceptions.isEmpty()) { + removeContents(null, tabDisplayName); + return; + } + + final NewErrorTreeViewPanel errorTreeView = new NewErrorTreeViewPanel(myProject, null); + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + MessageView messageView = myProject.getComponent(MessageView.class); + Content content = PeerFactory.getInstance().getContentFactory().createContent(errorTreeView.getComponent(), tabDisplayName, true); + content.putUserData(KEY, errorTreeView); + messageView.addContent(content); + messageView.setSelectedContent(content); + removeContents(content, tabDisplayName); + } + }, + "Open message view", + null); + + for (Iterator i = abstractVcsExceptions.iterator(); i.hasNext();) { + VcsException exception = (VcsException)i.next(); + String[] messages = exception.getMessages(); + if (messages.length == 0) messages = new String[]{"Unknown error"}; + errorTreeView.addMessage(getErrorCategory(exception), messages, exception.getVirtualFile(), -1, -1, null); + } + + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW).activate(null); + } + }); + } + + private int getErrorCategory(VcsException exception) { + if (exception.isWarning()) { + return MessageCategory.WARNING; + } else { + return MessageCategory.ERROR; + } + } + + protected void removeContents(Content notToRemove, final String tabDisplayName) { + MessageView messageView = myProject.getComponent(MessageView.class); + Content[] contents = messageView.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (content.isPinned()) continue; + if (tabDisplayName.equals(content.getDisplayName()) && content != notToRemove) { + ErrorTreeView listErrorView = (ErrorTreeView)content.getComponent(); + if (listErrorView != null) { + if (messageView.removeContent(content)) { + content.release(); + } + } + } + } + } + + public void markFileAsUpToDate(final VirtualFile file) { + LvcsObject object; + if (file.isDirectory()) { + object = LocalVcs.getInstance(myProject).findDirectory(file.getPath()); + } + else { + object = LocalVcs.getInstance(myProject).findFile(file.getPath()); + } + + if (object != null) { + object.getRevision().setUpToDate(true); + } + } + + public LvcsAction startVcsAction(String actionName) { + return LocalVcs.getInstance(myProject).startAction(actionName, "", false); + } + + public void finishVcsAction(LvcsAction action) { + action.finish(); + } + + public List runTransactionRunnable(AbstractVcs vcs, TransactionRunnable runnable, Object vcsParameters) { + List exceptions = new ArrayList(); + + TransactionProvider transactionProvider = vcs.getTransactionProvider(); + boolean transactionSupported = transactionProvider != null; + + if (transactionSupported) { + try { + transactionProvider.startTransaction(vcsParameters); + } + catch (VcsException e) { + return Collections.singletonList(e); + } + } + + runnable.run(exceptions); + + if (transactionSupported) { + if (exceptions.isEmpty()) { + try { + transactionProvider.commitTransaction(vcsParameters); + } + catch (VcsException e) { + exceptions.add(e); + transactionProvider.rollbackTransaction(vcsParameters); + } + } + else { + transactionProvider.rollbackTransaction(vcsParameters); + } + } + + return exceptions; + } + + public String getUpToDateFilePath(VirtualFile file) { + LvcsFile lvcsFile = LocalVcs.getInstance(myProject).findFile(file.getPath()); + if (lvcsFile == null) return null; + LvcsRevision lastUpToDateRevision = StatusUtil.findLastUpToDateRevision(lvcsFile); + return lastUpToDateRevision.getAbsolutePath().replace('/', File.separatorChar); + } + + public Refreshable createCheckinProjectPanel(Project project) { + return new CheckinProjectPanelImpl(project, + Arrays.asList(LocalVcs.getInstance(myProject).getRootPaths()), new JPanel()); + } + + public void prepareFileForCheckin(final VirtualFile file) { + if (ApplicationManagerEx.getApplicationEx().isInternal()) { + final PsiImportList[] resultList = new PsiImportList[1]; + final PsiManager psiManager = PsiManager.getInstance(myProject); + final boolean[] writable = new boolean[1]; + writable[0] = true; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (!file.isWritable()) { + writable[0] = false; + return; + } + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile instanceof PsiJavaFile) { + resultList[0] = CodeStyleManager.getInstance(myProject).prepareOptimizeImportsResult(psiFile); + } + } + }); + + if (!writable[0]) return; + + if (resultList[0] != null) { + Runnable runnable = new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + final PsiFile psiFile = psiManager.findFile(file); + ((PsiJavaFile)psiFile).getImportList().replace(resultList[0]); + final Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + FileDocumentManager.getInstance().saveDocument(document); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }); + } + }, + "Optimize Imports", + null); + } + }; + + if (ApplicationManager.getApplication().isDispatchThread()) { + runnable.run(); + } + else { + ApplicationManager.getApplication().invokeAndWait(runnable, ModalityState.NON_MMODAL); + } + } + } + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "AbstractVcsHelper"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public List doCheckinProject(final CheckinProjectPanel checkinProjectPanel, + final Object checkinParameters, final AbstractVcs abstractVcs) { + + final ArrayList exceptions = new ArrayList(); + + final ProgressWindow progressWindow = new ProgressWindow(true, myProject); + progressWindow.setTitle("Checking In Files"); + + final ProgressManager progressManager = ApplicationManager.getApplication().getComponent(ProgressManager.class); + + Collection roots = ((CheckinProjectPanelImpl)checkinProjectPanel).getRoots(); + Collection correspondingRoots = new ArrayList(); + for (Iterator iterator = roots.iterator(); iterator.hasNext();) { + VirtualFile virtualFile = iterator.next(); + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(myProject).getVcsFor(virtualFile); + CheckinEnvironment env = vcs.getCheckinEnvironment(); + if (env == abstractVcs.getCheckinEnvironment()) correspondingRoots.add(virtualFile); + } + + final Map> checkinOperations = ((CheckinProjectPanelImpl)checkinProjectPanel).getCheckinOperations(); + + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + + new Thread("Check In") { + public void run() { + Runnable checkinAction = new Runnable() { + public void run() { + try { + progressManager.runProcess(new Runnable() { + public void run() { + final CheckinHandler checkinHandler = new CheckinHandler(myProject, + abstractVcs); + Collection vcsOperations = checkinOperations.get(abstractVcs.getCheckinEnvironment()); + if (vcsOperations == null) vcsOperations = new ArrayList(); + final List abstractVcsExceptions = + checkinHandler.checkin(vcsOperations.toArray(new VcsOperation[vcsOperations.size()]), + checkinParameters); + exceptions.addAll(abstractVcsExceptions); + semaphore.up(); + } + }, progressWindow); + } + catch (ProcessCanceledException e) { + return; + } + } + }; + ApplicationManager.getApplication().runReadAction(checkinAction); + + } + }.start(); + + semaphore.waitFor(); + + return exceptions; + } + + public void doCheckinFiles(VirtualFile[] files, Object checkinParameters) { + + Map> vcsToFileMap = new HashMap>(); + + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(myProject).getVcsFor(file); + if (activeVcs == null) continue; + if (!vcsToFileMap.containsKey(activeVcs)) vcsToFileMap.put(activeVcs, new ArrayList()); + vcsToFileMap.get(activeVcs).add(file); + } + + for (Iterator iterator = vcsToFileMap.keySet().iterator(); iterator.hasNext();) { + AbstractVcs abstractVcs = iterator.next(); + doCheckinFiles(abstractVcs, vcsToFileMap.get(abstractVcs), checkinParameters); + } + } + + private void doCheckinFiles(AbstractVcs abstractVcs, List virtualFiles, Object checkinParameters) { + final LocalVcs lvcs = LocalVcs.getInstance(myProject); + + List objects = new ArrayList(); + for (Iterator iterator = virtualFiles.iterator(); iterator.hasNext();) { + VirtualFile file = iterator.next(); + LvcsFile lvcsFile = lvcs.findFile(file.getPath()); + if (lvcsFile != null) { + objects.add(lvcsFile); + } + } + + if (objects.isEmpty()) return; + + final CheckinHandler checkinHandler = new CheckinHandler(myProject, abstractVcs); + List exceptions = checkinHandler.checkin((LvcsObject[])objects.toArray(new LvcsObject[objects.size()]), + checkinParameters); + showErrors(exceptions, "Check In"); + + + } + + public void optimizeImportsAndReformatCode(final Collection files, + final VcsConfiguration configuration, + final Runnable finishAction, + final boolean checkinProject) { + + final Runnable performCheckoutAction = new Runnable() { + public void run() { + FileDocumentManager.getInstance().saveAllDocuments(); + finishAction.run(); + } + }; + + final Runnable reformatCodeAndPerformCheckout = new Runnable() { + public void run() { + if (reformat(configuration, checkinProject)) { + new ReformatCodeProcessor(myProject, getPsiFiles(files), performCheckoutAction).run(); + } + else { + performCheckoutAction.run(); + } + } + }; + + if (optimizeImports(configuration, checkinProject)) { + new OptimizeImportsProcessor(myProject, getPsiFiles(files), reformatCodeAndPerformCheckout).run(); + } + else { + reformatCodeAndPerformCheckout.run(); + } + + } + + public CheckinProjectDialogImplementer createCheckinProjectDialog(String title, + boolean requestComments, + Collection roots) { + return new CheckinProjectDialogImplementerImpl(myProject, title, requestComments, roots); + } + + private boolean reformat(final VcsConfiguration configuration, boolean checkinProject) { + return checkinProject ? configuration.REFORMAT_BEFORE_PROJECT_COMMIT : + configuration.REFORMAT_BEFORE_FILE_COMMIT; + } + + private boolean optimizeImports(final VcsConfiguration configuration, boolean checkinProject) { + return checkinProject ? configuration.OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT : + configuration.OPTIMIZE_IMPORTS_BEFORE_FILE_COMMIT; + } + + private PsiFile[] getPsiFiles(Collection selectedFiles) { + ArrayList result = new ArrayList(); + PsiManager psiManager = PsiManager.getInstance(myProject); + + for (Iterator each = selectedFiles.iterator(); each.hasNext();) { + VirtualFile file = each.next(); + if (file.isValid()) { + PsiFile psiFile = psiManager.findFile(file); + if (psiFile != null) result.add(psiFile); + } + } + return result.toArray(new PsiFile[result.size()]); + } + + public List doCheckinFiles(AbstractVcs vcs, FilePath[] roots, String preparedComment) { + final LocalVcs lvcs = LocalVcs.getInstance(myProject); + + List objects = new ArrayList(); + + for (int i = 0; i < roots.length; i++) { + FilePath file = roots[i]; + LvcsFile lvcsFile = lvcs.findFile(file.getPath()); + if (lvcsFile != null) { + objects.add(lvcsFile); + } + + } + + if (objects.isEmpty()) return new ArrayList(); + + final CheckinHandler checkinHandler = new CheckinHandler(myProject, vcs); + return checkinHandler.checkin((LvcsObject[])objects.toArray(new LvcsObject[objects.size()]), + preparedComment); + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusFactoryImpl.java new file mode 100644 index 00000000000..ab2ff4eca84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusFactoryImpl.java @@ -0,0 +1,97 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.diff.DiffColors; +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusFactory; +import com.intellij.openapi.vcs.checkin.DifferenceType; +import com.intellij.openapi.vcs.checkin.impl.DifferenceTypeImpl; + +import java.util.List; +import java.util.ArrayList; +import java.awt.Color; + + +public class FileStatusFactoryImpl implements FileStatusFactory { + private final List myStatuses = new ArrayList(); + + public FileStatus createFileStatus(String id, String description, Color color) { + FileStatusImpl result = new FileStatusImpl(id, ColorKey.createColorKey("FILESTATUS_" + id, color), description); + myStatuses.add(result); + return result; + } + + public DifferenceType createDifferenceType(String id, + FileStatus fileStatus, + final TextAttributesKey textColorKey, + final Color backgroundColor, Color activeBgColor) { + return new DifferenceTypeImpl(id, fileStatus, activeBgColor, backgroundColor) { + public TextAttributesKey getDiffColor(int index) { + return textColorKey; + } + + public TextAttributesKey getColor() { + return textColorKey; + } + }; + } + + public DifferenceType createDifferenceTypeInserted() { + return createDifferenceType("Added", + FileStatus.ADDED, + DiffColors.DIFF_INSERTED, + DiffColors.DIFF_ABSENT, + DiffColors.DIFF_INSERTED, + null, new Color(125, 223, 125)); + } + + public DifferenceType createDifferenceTypeNotChanged() { + return createDifferenceType("Not changed", + FileStatus.NOT_CHANGED, + null, + null, Color.white); + } + + public DifferenceType createDifferenceTypeDeleted() { + return createDifferenceType("Deleted", + FileStatus.DELETED, + DiffColors.DIFF_DELETED, + DiffColors.DIFF_DELETED, + DiffColors.DIFF_ABSENT, + null, new Color(157, 157, 157)); + } + + public DifferenceType createDifferenceTypeModified() { + return createDifferenceType("Modified", + FileStatus.MODIFIED, + DiffColors.DIFF_MODIFIED, + null, new Color(129, 164, 244)); + } + + public DifferenceType createDifferenceType(String id, + FileStatus fileStatus, + final TextAttributesKey mainTextColorKey, + final TextAttributesKey leftTextColorKey, + final TextAttributesKey rightTextColorKey, + Color activeBgColor, Color background) { + return new DifferenceTypeImpl(id, fileStatus, background, activeBgColor) { + public TextAttributesKey getDiffColor(int index) { + if (index == 0) { + return leftTextColorKey; + } + else { + return rightTextColorKey; + } + } + + public TextAttributesKey getColor() { + return mainTextColorKey; + } + }; + } + + public FileStatus[] getAllFileStatuses() { + return myStatuses.toArray(new FileStatus[myStatuses.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusImpl.java new file mode 100644 index 00000000000..dafc3b920cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusImpl.java @@ -0,0 +1,38 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.vcs.FileStatus; + +import java.awt.*; + +/** + * author: lesya + */ +public class FileStatusImpl implements FileStatus { + private final String myStatus; + private final ColorKey myColorKey; + private final String myText; + + public FileStatusImpl(String status, ColorKey key, String text) { + myStatus = status; + myColorKey = key; + myText = text; + } + + public String toString() { + return myStatus; + } + + public String getText() { + return myText; + } + + public Color getColor() { + return EditorColorsManager.getInstance().getGlobalScheme().getColor(getColorKey()); + } + + public ColorKey getColorKey() { + return myColorKey; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java new file mode 100644 index 00000000000..dbf848803fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java @@ -0,0 +1,276 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vfs.*; + +import java.util.*; + +/** + * @author mike + */ +public class FileStatusManagerImpl extends FileStatusManager implements ProjectComponent { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.impl.FileStatusManagerImpl"); + + private final com.intellij.util.containers.HashMap myCachedStatuses = new com.intellij.util.containers.HashMap(); + + private Project myProject; + private List myListeners = new ArrayList(); + private MyVirtualFileListener myVirtualFileListener; + private MyCommandListener myCommandListener; + private boolean myInsideCommand; + private Set myChangedFiles = new HashSet(); + private MyDocumentAdapter myDocumentListener; + private ModuleRootListener myModuleRootListener; + + public FileStatusManagerImpl(Project project, StartupManager startupManager) { + myProject = project; + + startupManager.registerPostStartupActivity(new Runnable() { + public void run() { + fileStatusesChanged(); + } + }); + } + + private boolean fileIsInContent(VirtualFile file) { + return ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(file); + } + + public FileStatus calcStatus(VirtualFile virtualFile) { + LOG.assertTrue(virtualFile != null); + + if (!(virtualFile.getFileSystem() instanceof LocalFileSystem)) return FileStatus.NOT_CHANGED; + + if (!fileIsInContent(virtualFile)) return FileStatus.NOT_CHANGED; + + final AbstractVcs vcs = ProjectLevelVcsManager.getInstance(myProject).getVcsFor(virtualFile); + if (vcs == null) return FileStatus.NOT_CHANGED; + + + FileStatusProvider vcsStatusProvider = vcs.getFileStatusProvider(); + if (vcsStatusProvider != null) { + FileStatus status = vcsStatusProvider.getStatus(virtualFile); + if (status.equals(FileStatus.NOT_CHANGED) && isDocumentModified(virtualFile)) { + return FileStatus.MODIFIED; + } + return status; + } + else { + return FileStatus.NOT_CHANGED; + } + } + + private boolean isDocumentModified(VirtualFile virtualFile) { + if (virtualFile.isDirectory()) return false; + final Document editorDocument = FileDocumentManager.getInstance().getCachedDocument(virtualFile); + + if (editorDocument != null && editorDocument.getModificationStamp() != virtualFile.getModificationStamp()) { + return true; + } + + return false; + } + + public void projectClosed() { + CommandProcessor.getInstance().removeCommandListener(myCommandListener); + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(myDocumentListener); + ProjectRootManager.getInstance(myProject).removeModuleRootListener(myModuleRootListener); + } + + public void projectOpened() { + myCommandListener = new MyCommandListener(); + CommandProcessor.getInstance().addCommandListener(myCommandListener); + + myVirtualFileListener = new MyVirtualFileListener(); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + + myDocumentListener = new MyDocumentAdapter(); + EditorFactory.getInstance().getEventMulticaster().addDocumentListener(myDocumentListener); + + myModuleRootListener = new ModuleRootListener() { + public void rootsChanged(ModuleRootEvent event) { + fileStatusesChanged(); + } + + public void beforeRootsChange(ModuleRootEvent event) { + } + }; + ProjectRootManager.getInstance(myProject).addModuleRootListener(myModuleRootListener); + } + + public void disposeComponent() { + myCachedStatuses.clear(); + } + + public String getComponentName() { + return "FileStatusManager"; + } + + public void initComponent() { } + + public void addFileStatusListener(FileStatusListener listener) { + myListeners.add(listener); + } + + public void fileStatusesChanged() { + if (!ApplicationManager.getApplication().isDispatchThread()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + fileStatusesChanged(); + } + }, ModalityState.NON_MMODAL); + return; + } + + myCachedStatuses.clear(); + + final FileStatusListener[] listeners = myListeners.toArray(new FileStatusListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + FileStatusListener listener = listeners[i]; + listener.fileStatusesChanged(); + } + } + + public void fileStatusChanged(final VirtualFile file) { + if (!ApplicationManager.getApplication().isDispatchThread()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + fileStatusChanged(file); + } + }); + return; + } + + if (!file.isValid()) return; + FileStatus cachedStatus = getCachedStatus(file); + if (cachedStatus == null) return; + FileStatus newStatus = calcStatus(file); + if (cachedStatus == newStatus) return; + myCachedStatuses.put(file, newStatus); + + final FileStatusListener[] listeners = myListeners.toArray(new FileStatusListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + FileStatusListener listener = listeners[i]; + listener.fileStatusChanged(file); + } + } + + public FileStatus getStatus(final VirtualFile file) { + FileStatus status = getCachedStatus(file); + if (status == null) { + status = calcStatus(file); + myCachedStatuses.put(file, status); + } + + return status; + } + + private FileStatus getCachedStatus(final VirtualFile file) { + return myCachedStatuses.get(file); + } + + public void removeFileStatusListener(FileStatusListener listener) { + myListeners.remove(listener); + } + + private class MyCommandListener extends CommandAdapter { + public void commandStarted(CommandEvent event) { + myInsideCommand = true; + } + + public void commandFinished(CommandEvent event) { + myInsideCommand = false; + + if (!myChangedFiles.isEmpty()) { + for (Iterator i = myChangedFiles.iterator(); i.hasNext();) { + final VirtualFile file = i.next(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + fileStatusChanged(file); + } + }); + } + } + + myChangedFiles.clear(); + } + } + + private class MyVirtualFileListener implements VirtualFileListener { + public void propertyChanged(VirtualFilePropertyEvent event) { + onFileChanged(event.getFile()); + } + + public void contentsChanged(VirtualFileEvent event) { + onFileChanged(event.getFile()); + } + + public void fileCreated(VirtualFileEvent event) { + onFileChanged(event.getFile()); + } + + public void fileDeleted(VirtualFileEvent event) { + onFileChanged(event.getFile()); + } + + public void fileMoved(VirtualFileMoveEvent event) { + onFileChanged(event.getFile()); + } + + public void beforePropertyChange(VirtualFilePropertyEvent event) { + onFileChanged(event.getFile()); + } + + public void beforeContentsChange(VirtualFileEvent event) { + onFileChanged(event.getFile()); + } + + public void beforeFileDeletion(VirtualFileEvent event) { + onFileChanged(event.getFile()); + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + onFileChanged(event.getFile()); + } + + private void onFileChanged(VirtualFile file) { + if (myInsideCommand) { + myChangedFiles.add(file); + } + else { + fileStatusChanged(file); + } + } + } + + private class MyDocumentAdapter extends DocumentAdapter { + public void documentChanged(DocumentEvent event) { + VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument()); + if (file != null) { + FileStatus cachedStatus = getCachedStatus(file); + if (cachedStatus == FileStatus.NOT_CHANGED) { + fileStatusChanged(file); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java new file mode 100644 index 00000000000..66d283dcb52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.EditorFactoryAdapter; +import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.editor.event.EditorFactoryListener; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.localVcs.LocalVcs; +import com.intellij.openapi.localVcs.LvcsFile; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.ex.LineStatusTracker; +import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.fileView.impl.VirtualAndPsiFileDataProvider; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.ContentManager; + +import java.io.File; +import java.util.*; + +public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx implements ProjectComponent { + + private List myVcss = new ArrayList(); + private final Project myProject; + private final Map myVcsToStatus = new HashMap(); + private com.intellij.util.containers.HashMap myLineStatusTrackers = + new com.intellij.util.containers.HashMap(); + private boolean myIsDisposed = false; + + private EditorFactoryListener myEditorFactoryListener = new MyEditorFactoryListener(); + private final MyFileStatusListener myFileStatusListener = new MyFileStatusListener(); + private final MyVirtualFileListener myVirtualFileListener = new MyVirtualFileListener(); + private ContentManager myContentManager; + + + public ProjectLevelVcsManagerImpl(Project project) { + myProject = project; + } + + public void initComponent() { } + + public void registerVcs(AbstractVcs vcs) { + try { + vcs.start(); + myVcsToStatus.put(vcs, Boolean.TRUE); + } + catch (VcsException e) { + myVcsToStatus.put(vcs, Boolean.FALSE); + } + myVcss.add(vcs); + } + + public AbstractVcs findVcsByName(String name) { + if (name == null) return null; + + for (Iterator iterator = myVcss.iterator(); iterator.hasNext();) { + AbstractVcs vcs = iterator.next(); + if (vcs.getName().equals(name)) { + return vcs; + } + } + + return null; + } + + public AbstractVcs[] getAllVcss() { + return myVcss.toArray(new AbstractVcs[myVcss.size()]); + } + + + public void disposeComponent() { + } + + public void projectOpened() { + myIsDisposed = false; + myContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(true, myProject); + myLineStatusTrackers = new com.intellij.util.containers.HashMap(); + + Object[] components = myProject.getComponents(AbstractVcs.class); + for (int i = 0; i < components.length; i++) { + AbstractVcs vcs = (AbstractVcs)components[i]; + registerVcs(vcs); + } + + EditorFactory.getInstance().addEditorFactoryListener(myEditorFactoryListener); + FileStatusManager.getInstance(getProject()).addFileStatusListener(myFileStatusListener); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener); + + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + if (toolWindowManager != null) { // Can be null in tests + ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.VCS, myContentManager.getComponent(), + ToolWindowAnchor.BOTTOM); + toolWindow.setIcon(IconLoader.getIcon("/_cvs/cvs.png")); + toolWindow.installWatcher(myContentManager); + } + } + }); + } + + public void projectClosed() { + dispose(); + } + + public String getComponentName() { + return "ProjectLevelVcsManager"; + } + + public boolean checkAllFielsAreUnder(AbstractVcs abstractVcs, VirtualFile[] files) { + if (files == null) return false; + for (int i = 0; i < files.length; i++) { + if (ProjectLevelVcsManager.getInstance(myProject).getVcsFor(files[i]) != abstractVcs) { + return false; + } + } + return true; + } + + public AbstractVcs getVcsFor(VirtualFile file) { + if (file == null) return null; + if (myProject.isDisposed()) return null; + Module module = VfsUtil.getModuleForFile(myProject, file); + if (module == null) return null; + return ModuleLevelVcsManager.getInstance(module).getActiveVcs(); + } + + private void dispose() { + if (myIsDisposed) return; + AbstractVcs[] allVcss = getAllVcss(); + for (int i = 0; i < allVcss.length; i++) { + unregisterVcs(allVcss[i]); + } + try { + final Collection trackers = myLineStatusTrackers.values(); + final LineStatusTracker[] lineStatusTrackers = trackers.toArray(new LineStatusTracker[trackers.size()]); + for (int i = 0; i < lineStatusTrackers.length; i++) { + LineStatusTracker tracker = lineStatusTrackers[i]; + releaseTracker(tracker.getDocument()); + } + + myLineStatusTrackers = null; + myContentManager = null; + + EditorFactory.getInstance().removeEditorFactoryListener(myEditorFactoryListener); + FileStatusManager.getInstance(getProject()).removeFileStatusListener(myFileStatusListener); + VirtualFileManager.getInstance().removeVirtualFileListener(myVirtualFileListener); + + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + if (toolWindowManager != null && toolWindowManager.getToolWindow(ToolWindowId.VCS) != null) { + toolWindowManager.unregisterToolWindow(ToolWindowId.VCS); + } + } + finally { + myIsDisposed = true; + } + + } + + public void unregisterVcs(AbstractVcs vcs) { + try { + vcs.shutdown(); + } + catch (VcsException e) { + e.printStackTrace(); + } + myVcss.remove(vcs); + } + + private Project getProject() { + return myProject; + } + + public synchronized void setLineStatusTracker(Document document, LineStatusTracker tracker) { + myLineStatusTrackers.put(document, tracker); + } + + public LineStatusTracker getLineStatusTracker(Document document) { + if (myLineStatusTrackers == null) return null; + return myLineStatusTrackers.get(document); + } + + + public LineStatusTracker setUpToDateContent(Document document, String lastUpToDateContent) { + LineStatusTracker result = myLineStatusTrackers.get(document); + if (result == null) { + result = LineStatusTracker.createOn(document, lastUpToDateContent, getProject()); + myLineStatusTrackers.put(document, result); + } + return result; + } + + public ContentManager getContentManager() { + return myContentManager; + } + + private synchronized void resetTracker(final VirtualFile virtualFile) { + final LvcsFile lvcsFile = LocalVcs.getInstance(getProject()).findFile(virtualFile.getPath()); + if (lvcsFile == null) return; + + final Document document = FileDocumentManager.getInstance().getCachedDocument(virtualFile); + if (document == null) return; + + final LineStatusTracker tracker = myLineStatusTrackers.get(document); + if (tracker != null) { + resetTracker(tracker); + } + else { + if (Arrays.asList(FileEditorManager.getInstance(getProject()).getOpenFiles()).contains(virtualFile)) { + installTracker(virtualFile, document); + } + } + } + + private synchronized boolean releaseTracker(Document document) { + if (myLineStatusTrackers == null) return false; + if (!myLineStatusTrackers.containsKey(document)) return false; + LineStatusTracker tracker = myLineStatusTrackers.remove(document); + tracker.release(); + return true; + } + + public synchronized void resetTracker(final LineStatusTracker tracker) { + if (tracker != null) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myIsDisposed) return; + if (releaseTracker(tracker.getDocument())) { + installTracker(tracker.getVirtualFile(), tracker.getDocument()); + } + } + }); + } + } + + private class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { + if (myIsDisposed) return; + synchronized (this) { + List trackers = new ArrayList(myLineStatusTrackers.values()); + for (Iterator i = trackers.iterator(); i.hasNext();) { + LineStatusTracker tracker = i.next(); + resetTracker(tracker); + } + } + } + + public void fileStatusChanged(VirtualFile virtualFile) { + resetTracker(virtualFile); + } + } + + private class MyEditorFactoryListener extends EditorFactoryAdapter { + public void editorCreated(EditorFactoryEvent event) { + Editor editor = event.getEditor(); + Document document = editor.getDocument(); + VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + installTracker(virtualFile, document); + } + + public void editorReleased(EditorFactoryEvent event) { + final Editor editor = event.getEditor(); + final Document doc = editor.getDocument(); + final Editor[] editors = event.getFactory().getEditors(doc, getProject()); + if (editors.length == 0) { + releaseTracker(doc); + } + } + } + + + private class MyVirtualFileListener extends VirtualFileAdapter { + public void beforeContentsChange(VirtualFileEvent event) { + if (event.getRequestor() == null) { + resetTracker(event.getFile()); + } + } + } + + private synchronized void installTracker(VirtualFile virtualFile, Document document) { + ApplicationManager.getApplication().assertIsDispatchThread(); + AbstractVcs activeVcs = getVcsFor(virtualFile); + + if (activeVcs == null) return; + if (virtualFile == null) return; + + if (!(virtualFile.getFileSystem() instanceof LocalFileSystem)) return; + + UpToDateRevisionProvider upToDateRevisionProvider = activeVcs.getUpToDateRevisionProvider(); + if (upToDateRevisionProvider == null) return; + + String lastUpToDateContent = upToDateRevisionProvider.getLastUpToDateContentFor(virtualFile); + if (lastUpToDateContent == null) return; + + setUpToDateContent(document, lastUpToDateContent); + } + + public boolean checkVcsIsActive(AbstractVcs vcs) { + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + if (ModuleLevelVcsManager.getInstance(module).getActiveVcs() == vcs) return true; + } + return false; + } + + public String getPresentableRelativePathFor(final VirtualFile file) { + if (file == null) return ""; + return ApplicationManager.getApplication().runReadAction(new Computable() { + public String compute() { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + Module module = fileIndex.getModuleForFile(file); + VirtualFile contentRoot = fileIndex.getContentRootForFile(file); + if (module == null) return file.getPresentableUrl(); + StringBuffer result = new StringBuffer(); + result.append("<"); + result.append(module.getName()); + result.append(">"); + result.append(File.separatorChar); + result.append(contentRoot.getName()); + String relativePath = VfsUtil.getRelativePath(file, contentRoot, File.separatorChar); + if (relativePath.length() > 0) { + result.append(File.separatorChar); + result.append(relativePath); + } + return result.toString(); + } + }); + } + + public DataProvider createVirtualAndPsiFileDataProvider(VirtualFile[] virtualFileArray, VirtualFile selectedFile) { + return new VirtualAndPsiFileDataProvider(myProject, virtualFileArray, selectedFile); + } + + public Module[] getAllModulesUnder(AbstractVcs vcs) { + ArrayList result = new ArrayList(); + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + if (ModuleLevelVcsManager.getInstance(module).getActiveVcs() == vcs) { + result.add(module); + } + } + return result.toArray(new Module[result.size()]); + } + + public AbstractVcs[] getAllActiveVcss() { + ArrayList result = new ArrayList(); + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + AbstractVcs activeVcs = ModuleLevelVcsManager.getInstance(module).getActiveVcs(); + if (activeVcs != null && !result.contains(activeVcs)) { + result.add(activeVcs); + } + } + return result.toArray(new AbstractVcs[result.size()]); + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerConfigurable.java new file mode 100644 index 00000000000..5ab31669dd5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerConfigurable.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class VcsManagerConfigurable implements ProjectComponent, Configurable { + + private VcsManagerConfigurablePanel myPanel; + public static final Icon ICON = IconLoader.getIcon("/general/configurableVcs.png"); + private final Project myProject; + + public VcsManagerConfigurable(Project project) { + myProject = project; + } + + public void moduleAdded() { + + } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void disposeComponent() { + } + + public void initComponent() { } + + + public String getDisplayName() { + return "Version Control"; + } + + public String getHelpTopic() { + return "project.propVCSSupport"; + } + + public Icon getIcon() { + return ICON; + } + + public String getComponentName() { + return "VcsManagerConfigurable"; + } + + public JComponent createComponent() { + myPanel = new VcsManagerConfigurablePanel(myProject); + return myPanel.getPanel(); + } + + public void apply() throws ConfigurationException { + myPanel.apply(); + } + + public void reset() { + myPanel.reset(); + } + + public void disposeUIResources() { + myPanel = null; + } + + public boolean isModified() { + return myPanel.isModified(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerPerModuleConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerPerModuleConfiguration.java new file mode 100644 index 00000000000..a2da6d5d42f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/impl/VcsManagerPerModuleConfiguration.java @@ -0,0 +1,52 @@ +package com.intellij.openapi.vcs.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleComponent; +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 org.jdom.Element; + +/** + * @author mike + */ +public class VcsManagerPerModuleConfiguration implements JDOMExternalizable, ModuleComponent { + public String ACTIVE_VCS_NAME = ""; + public boolean USE_PROJECT_VCS = true; + + public static VcsManagerPerModuleConfiguration getInstance(Module module) { + return module.getComponent(VcsManagerPerModuleConfiguration.class); + } + + public void moduleAdded() { + + } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public String getComponentName() { + //return "VcsManagerPerModuleConfiguration"; + return "VcsManagerConfiguration"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + if ("".equals(ACTIVE_VCS_NAME) && USE_PROJECT_VCS) { + throw new WriteExternalException(); + } + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/FileInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/FileInfo.java new file mode 100644 index 00000000000..f0d610faf5c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/FileInfo.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.readOnlyHandler; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.EditFileProvider; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.util.ListWithSelection; +import com.intellij.util.io.ReadOnlyAttributeUtil; + +import java.io.IOException; + +class FileInfo { + private final VirtualFile myFile; + private final EditFileProvider myEditFileProvider; + private final ListWithSelection myHandleType = new ListWithSelection(); + + public FileInfo(VirtualFile file, Project project) { + myFile = file; + myHandleType.add(HandleType.USE_FILE_SYSTEM); + myHandleType.selectFirst(); + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(file); + if (vcs == null) { + myEditFileProvider = null; + } + else { + boolean fileExistsInVcs = vcs.fileExistsInVcs(new FilePathImpl(file)); + if (fileExistsInVcs) { + myEditFileProvider = vcs.getEditFileProvider(); + if (myEditFileProvider != null) { + HandleType handleType = HandleType.createForVcs(vcs); + myHandleType.add(handleType); + myHandleType.select(handleType); + } + } + else { + myEditFileProvider = null; + } + } + + + } + + public VirtualFile getFile() { + return myFile; + } + + public boolean getUseVersionControl() { + return ( (HandleType)myHandleType.getSelection()).getUseVcs(); + } + + public boolean hasVersionControl() { + return myEditFileProvider != null; + } + + public ListWithSelection getHandleType(){ + return myHandleType; + } + + public void handle(){ + if (getUseVersionControl()){ + myEditFileProvider.editFiles(new VirtualFile[]{getFile()}); + getFile().refresh(false, false); + } else { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + ReadOnlyAttributeUtil.setReadOnlyAttribute(getFile(), false); + } + catch (IOException e) { + //ignore + } + } + }); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/HandleType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/HandleType.java new file mode 100644 index 00000000000..f32481b530d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/HandleType.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.readOnlyHandler; + +import com.intellij.openapi.vcs.AbstractVcs; + +public class HandleType { + private final String myName; + private final boolean myUseVcs; + + public static final HandleType USE_FILE_SYSTEM = new HandleType("using file system", false); + + public static final HandleType createForVcs(AbstractVcs vcs) { + return new HandleType("using " + vcs.getDisplayName(), true); + } + + private HandleType(String name, boolean useVcs) { + myName = name; + myUseVcs = useVcs; + } + + public String toString() { + return myName; + } + + public boolean getUseVcs() { + return myUseVcs; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java new file mode 100644 index 00000000000..37594796819 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.readOnlyHandler; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.ReadonlyStatusHandler; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.ArrayList; +import java.util.List; + +public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements ProjectComponent{ + private final Project myProject; + + public ReadonlyStatusHandlerImpl(Project project) { + myProject = project; + } + + public OperationStatus ensureFilesWriteable(VirtualFile[] files) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (files.length == 0) return new OperationStatus(VirtualFile.EMPTY_ARRAY, VirtualFile.EMPTY_ARRAY); + + long[] modificationStamps = new long[files.length]; + for (int i = 0; i < files.length; i++) { + modificationStamps[i] = files[i].getModificationStamp(); + } + + HandleReadOnlyStatusDialog dialog = new HandleReadOnlyStatusDialog(myProject, createFileInfos(files)); + dialog.show(); + List readOnlyFiles = new ArrayList(); + List updatedFiles = new ArrayList(); + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + if (!file.isWritable()) { + readOnlyFiles.add(file); + } + if (modificationStamps[i] != file.getModificationStamp()) { + updatedFiles.add(file); + } + } + + return new OperationStatus(readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()]), + updatedFiles.toArray(new VirtualFile[updatedFiles.size()])); + } + + private FileInfo[] createFileInfos(VirtualFile[] files) { + FileInfo[] result = new FileInfo[files.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new FileInfo(files[i], myProject); + } + return result; + } + + public void projectOpened() { + + } + + public void projectClosed() { + + } + + public String getComponentName() { + return "ReadonlyStatusHandler"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ui/exclude/SortedComboBoxModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ui/exclude/SortedComboBoxModel.java new file mode 100644 index 00000000000..7120cd9b031 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/ui/exclude/SortedComboBoxModel.java @@ -0,0 +1,29 @@ +package com.intellij.openapi.vcs.ui.exclude; + +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.SortedListModel; + +import javax.swing.*; +import java.util.Comparator; + +public class SortedComboBoxModel extends SortedListModel implements ComboBoxModel { + private T mySelection; + + public SortedComboBoxModel(Comparator comparator) { + super(comparator); + } + + public T getSelectedItem() { + return mySelection; + } + + public void setSelectedItem(Object anItem) { + if (Comparing.equal(mySelection, anItem)) return; + mySelection = (T)anItem; + fireSelectionChanged(); + } + + private void fireSelectionChanged() { + fireContentsChanged(this, -1, -1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java new file mode 100644 index 00000000000..c749f99cb6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.AbstractVcsHelper; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.actions.AbstractVcsAction; +import com.intellij.openapi.vcs.actions.VcsContext; +import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.ui.OptionsDialog; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.vcsUtil.VcsUtil; + +import java.util.*; + +public class AbstractCommonUpdateAction extends AbstractVcsAction { + + private final ActionInfo myActionInfo; + private final ScopeInfo myScopeInfo; + + protected AbstractCommonUpdateAction(ActionInfo actionInfo, ScopeInfo scopeInfo) { + myActionInfo = actionInfo; + myScopeInfo = scopeInfo; + } + + protected final String getCompleteActionName(VcsContext dataContext) { + return myActionInfo.getActionName() + " " + myScopeInfo.getScopeName(dataContext); + } + + + protected void actionPerformed(final VcsContext context) { + final Project project = context.getProject(); + + boolean showUpdateOptions = myActionInfo.showOptions(project); + + final UpdatedFiles updatedFiles = UpdatedFiles.create(); + if (project != null) { + try { + + if (ApplicationManager.getApplication().isDispatchThread()) { + ApplicationManager.getApplication().saveAll(); + } + + final FilePath[] roots = filterDescindingFiles(myScopeInfo.getRoots(context), project); + + final Map> updateEnvToVirtualFiles = createEnvToFilesMap(roots, project); + + + if (showUpdateOptions || OptionsDialog.shiftIsPressed(context.getModifiers())) { + showOptionsDialog(updateEnvToVirtualFiles, project); + } + final ArrayList vcsExceptions = new ArrayList(); + final List updateSessions = new ArrayList(); + ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() { + public void run() { + + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + for (Iterator iterator = updateEnvToVirtualFiles.keySet().iterator(); iterator.hasNext();) { + UpdateEnvironment updateEnvironment = iterator.next(); + updateEnvironment.fillGroups(updatedFiles); + Collection files = updateEnvToVirtualFiles.get(updateEnvironment); + UpdateSession updateSession = updateEnvironment.updateDirectories(files.toArray(new FilePath[files.size()]), + updatedFiles, + progressIndicator); + vcsExceptions.addAll(updateSession.getExceptions()); + updateSessions.add(updateSession); + } + + if (progressIndicator != null) { + progressIndicator.setText("Synchronizing files..."); + progressIndicator.setText2(""); + } + + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + VirtualFileManager.getInstance().refresh(true, new Runnable() { + public void run() { + semaphore.up(); + } + }); + } + }); + semaphore.waitFor(); + if (!someSessionWasCanceled(updateSessions)) { + for (Iterator iterator = updateSessions.iterator(); iterator.hasNext();) { + iterator.next().onRefreshFilesCompleted(); + } + } + } + + }, getCompleteActionName(context), true, project); + + if (!someSessionWasCanceled(updateSessions)) { + + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (!vcsExceptions.isEmpty()) { + AbstractVcsHelper.getInstance(project).showErrors(vcsExceptions, getCompleteActionName(context) + " Errors"); + } + if (updatedFiles.isEmpty() && vcsExceptions.isEmpty()) { + Messages.showMessageDialog(getAllFilesAreUpToDateMessage(roots), + getCompleteActionName(context), + Messages.getInformationIcon()); + + return; + } + else if (!updatedFiles.isEmpty()) { + RestoreUpdateTree restoreUpdateTree = RestoreUpdateTree.getInstance(project); + restoreUpdateTree.registerUpdateInformation(updatedFiles, myActionInfo); + showUpdateProjectInfo(project, updatedFiles, getCompleteActionName(context), myActionInfo); + + } + } + }); + } + } + catch (ProcessCanceledException e1) { + + } + } + } + + private boolean someSessionWasCanceled(List updateSessions) { + for (Iterator iterator = updateSessions.iterator(); iterator.hasNext();) { + UpdateSession updateSession = iterator.next(); + if (updateSession.isCanceled()) { + return true; + } + } + return false; + } + + private String getAllFilesAreUpToDateMessage(FilePath[] roots) { + if (roots.length == 1 && !roots[0].isDirectory()) { + return "File is up-to-date"; + } + else { + return "All files are up-to-date"; + } + } + + public static void showUpdateProjectInfo(final Project project, + final UpdatedFiles updatedFiles, + String actionName, + ActionInfo actionInfo) { + ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(project).getContentManager(); + final UpdateInfoTree updateInfoTree = new UpdateInfoTree(contentManager, null, project, updatedFiles, actionName, actionInfo); + Content content = PeerFactory.getInstance().getContentFactory().createContent(updateInfoTree, actionInfo.getActionName() + " Info", + true); + contentManager.addContent(content); + ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS).activate(null); + contentManager.setSelectedContent(content); + updateInfoTree.expandRootChildren(); + } + + private void showOptionsDialog(final Map> updateEnvToVirtualFiles, final Project project) { + LinkedHashMap envToConfMap = createConfigurableToEnvMap(updateEnvToVirtualFiles); + if (!envToConfMap.isEmpty()) { + UpdateOrStatusOptionsDialog dialogOrStatus = myActionInfo.createOptionsDialog(project, envToConfMap); + dialogOrStatus.show(); + if (!dialogOrStatus.isOK()) { + throw new ProcessCanceledException(); + } + } + } + + private LinkedHashMap createConfigurableToEnvMap( + Map> updateEnvToVirtualFiles) { + LinkedHashMap envToConfMap = new LinkedHashMap(); + for (Iterator iterator = updateEnvToVirtualFiles.keySet().iterator(); iterator.hasNext();) { + UpdateEnvironment updateEnvironment = iterator.next(); + Configurable configurable = updateEnvironment.createConfigurable(updateEnvToVirtualFiles.get(updateEnvironment)); + if (configurable != null) { + envToConfMap.put(configurable, updateEnvironment); + } + } + return envToConfMap; + } + + private Map> createEnvToFilesMap(FilePath[] roots, Project project) { + HashMap> result = new HashMap>(); + + for (int i = 0; i < roots.length; i++) { + FilePath file = roots[i]; + AbstractVcs vcs = VcsUtil.getVcsFor(project, file); + if (vcs != null) { + UpdateEnvironment updateEnvironment = myActionInfo.getEnvironment(vcs); + if (updateEnvironment != null) { + if (!result.containsKey(updateEnvironment)) result.put(updateEnvironment, new HashSet()); + if (vcs.fileIsUnderVcs(file)) { + result.get(updateEnvironment).add(file); + } + } + } + } + + for (Iterator> iterator = result.values().iterator(); iterator.hasNext();) { + filterSubDirectories(iterator.next()); + } + + return result; + } + + private void filterSubDirectories(Collection virtualFiles) { + FilePath[] array = virtualFiles.toArray(new FilePath[virtualFiles.size()]); + for (int i = 0; i < array.length; i++) { + FilePath file = array[i]; + if (containsParent(array, file)) { + virtualFiles.remove(file); + } + } + } + + private boolean containsParent(FilePath[] array, FilePath file) { + for (int i = 0; i < array.length; i++) { + FilePath virtualFile = array[i]; + if (virtualFile == file) continue; + if (VfsUtil.isAncestor(virtualFile.getIOFile(), file.getIOFile(), false)) return true; + } + return false; + } + + protected void update(VcsContext vcsContext, Presentation presentation) { + Project project = vcsContext.getProject(); + + + if (project != null) { + + String actionName = getCompleteActionName(vcsContext); + if (myActionInfo.showOptions(project) || OptionsDialog.shiftIsPressed(vcsContext.getModifiers())) { + actionName += "..."; + } + + presentation.setText(actionName); + + presentation.setVisible(true); + presentation.setEnabled(true); + + FilePath[] roots = myScopeInfo.getRoots(vcsContext); + if (roots == null || roots.length == 0) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + if (roots != null && roots.length > 0) { + for (int i = 0; i < roots.length; i++) { + FilePath file = roots[i]; + AbstractVcs vcs = VcsUtil.getVcsFor(project, file); + if (vcs == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + UpdateEnvironment updateEnvironment = myActionInfo.getEnvironment(vcs); + if (updateEnvironment == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + + } + } + } else { + presentation.setVisible(false); + presentation.setEnabled(false); + } + + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractTreeNode.java new file mode 100644 index 00000000000..c322a77de02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/AbstractTreeNode.java @@ -0,0 +1,80 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.io.File; + +/** + * author: lesya + */ +public abstract class AbstractTreeNode extends DefaultMutableTreeNode{ + protected static final ArrayList EMPTY_FILE_ARRAY = new ArrayList(); + DefaultTreeModel myTreeModel; + private JTree myTree; + + public void setTree(JTree tree) { + myTree = tree; + if (children == null) return; + for (Iterator each = children.iterator(); each.hasNext();) { + AbstractTreeNode node = (AbstractTreeNode) each.next(); + node.setTree(tree); + } + + } + + public void setTreeModel(DefaultTreeModel treeModel) { + myTreeModel = treeModel; + if (children == null) return; + for (Iterator each = children.iterator(); each.hasNext();) { + AbstractTreeNode node = (AbstractTreeNode) each.next(); + node.setTreeModel(treeModel); + } + } + + protected DefaultTreeModel getTreeModel() { + return myTreeModel; + } + + public JTree getTree() { + return myTree; + } + + public AbstractTreeNode() { + } + + public String getText(){ + StringBuffer result = new StringBuffer(); + result.append(getName()); + if(showStatistics()){ + result.append(" ("); + result.append(getStatistics(getItemsCount())); + result.append(")"); + } + return result.toString(); + } + + private String getStatistics(int itemsCount){ + if(itemsCount == 0) return "no items"; + if(itemsCount == 1) return "1 item"; + return "" + itemsCount + " items"; + } + + protected abstract String getName(); + protected abstract int getItemsCount(); + protected abstract boolean showStatistics(); + + public abstract Icon getIcon(boolean expanded); + public abstract Collection getVirtualFiles(); + public abstract Collection getFiles(); + + public abstract SimpleTextAttributes getAttributes(); + + public abstract boolean getSupportsDeletion(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ActionInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ActionInfo.java new file mode 100644 index 00000000000..b8c6aed3b6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ActionInfo.java @@ -0,0 +1,94 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.vcs.VcsConfiguration; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.options.Configurable; + +import java.util.LinkedHashMap; + +public interface ActionInfo { + ActionInfo UPDATE = new ActionInfo() { + public boolean showOptions(Project project) { + return VcsConfiguration.getInstance(project).SHOW_UPDATE_OPTIONS; + } + + public UpdateEnvironment getEnvironment(AbstractVcs vcs) { + return vcs.getUpdateEnvironment(); + } + + public UpdateOrStatusOptionsDialog createOptionsDialog(final Project project, + LinkedHashMap envToConfMap) { + return new UpdateOrStatusOptionsDialog(project, envToConfMap) { + protected String getRealTitle() { + return getActionName(); + } + + protected boolean isToBeShown() { + return VcsConfiguration.getInstance(project).SHOW_UPDATE_OPTIONS; + } + + protected void setToBeShown(boolean value, boolean onOk) { + if (onOk) { + VcsConfiguration.getInstance(project).SHOW_UPDATE_OPTIONS = value; + } + } + }; + } + + public String getActionName() { + return "Update"; + } + + public String getGroupName(FileGroup fileGroup) { + return fileGroup.getUpdateName(); + } + }; + + ActionInfo STATUS = new ActionInfo() { + public boolean showOptions(Project project) { + return VcsConfiguration.getInstance(project).SHOW_STATUS_OPTIONS; + } + + public UpdateEnvironment getEnvironment(AbstractVcs vcs) { + return vcs.getStatusEnvironment(); + } + + public UpdateOrStatusOptionsDialog createOptionsDialog(final Project project, + LinkedHashMap envToConfMap) { + return new UpdateOrStatusOptionsDialog(project, envToConfMap) { + protected String getRealTitle() { + return getActionName(); + } + + protected boolean isToBeShown() { + return VcsConfiguration.getInstance(project).SHOW_STATUS_OPTIONS; + } + + protected void setToBeShown(boolean value, boolean onOk) { + if (onOk) { + VcsConfiguration.getInstance(project).SHOW_STATUS_OPTIONS = value; + } + } + }; + } + + public String getActionName() { + return "Check Status for"; + } + + public String getGroupName(FileGroup fileGroup) { + return fileGroup.getStatusName(); + } + }; + + boolean showOptions(Project project); + + UpdateEnvironment getEnvironment(AbstractVcs vcs); + + UpdateOrStatusOptionsDialog createOptionsDialog(Project project, LinkedHashMap envToConfMap); + + String getActionName(); + + String getGroupName(FileGroup fileGroup); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusFileOrDirectoryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusFileOrDirectoryAction.java new file mode 100644 index 00000000000..6c2c4b1e38d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusFileOrDirectoryAction.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.vcs.update; + +public class CommonStatusFileOrDirectoryAction extends AbstractCommonUpdateAction{ + public CommonStatusFileOrDirectoryAction() { + super(ActionInfo.STATUS, ScopeInfo.FILES); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusProjectAction.java new file mode 100644 index 00000000000..43494c3771a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonStatusProjectAction.java @@ -0,0 +1,7 @@ +package com.intellij.openapi.vcs.update; + +public class CommonStatusProjectAction extends AbstractCommonUpdateAction { + public CommonStatusProjectAction() { + super(ActionInfo.STATUS, ScopeInfo.PROJECT); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateFileOrDirectoryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateFileOrDirectoryAction.java new file mode 100644 index 00000000000..2c8d7ffdc08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateFileOrDirectoryAction.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + + + +public class CommonUpdateFileOrDirectoryAction extends AbstractCommonUpdateAction { + public CommonUpdateFileOrDirectoryAction() { + super(ActionInfo.UPDATE, ScopeInfo.FILES); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateProjectAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateProjectAction.java new file mode 100644 index 00000000000..8a3fd7ca961 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/CommonUpdateProjectAction.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + + + +public class CommonUpdateProjectAction extends AbstractCommonUpdateAction { + public CommonUpdateProjectAction() { + super(ActionInfo.UPDATE, ScopeInfo.PROJECT); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/DirectoryTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/DirectoryTreeNode.java new file mode 100644 index 00000000000..f53df42e9e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/DirectoryTreeNode.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; +import java.io.File; + +/** + * author: lesya + */ +public class DirectoryTreeNode extends FileOrDirectoryTreeNode{ + private static final Icon OPEN_ICON = IconLoader.getIcon("/nodes/folderOpen.png"); + private static final Icon COLLAPSED_ICON = IconLoader.getIcon("/nodes/folder.png"); + + public DirectoryTreeNode(String path, Project project, String parentPath) { + super(path, SimpleTextAttributes.ERROR_ATTRIBUTES, project, parentPath); + } + + protected int getItemsCount() { + int result = 0; + for (int i = 0; i < getChildCount(); i++){ + result += ((FileOrDirectoryTreeNode)getChildAt(i)).getItemsCount(); + } + return result; + } + + protected boolean showStatistics() { + return true; + } + + public Icon getIcon(boolean expanded) { + return expanded ? OPEN_ICON : COLLAPSED_ICON; + } + + public Collection getVirtualFiles() { + Collection result = new ArrayList(); + for (int i = 0; i < getChildCount(); i++){ + FileOrDirectoryTreeNode child = (FileOrDirectoryTreeNode)getChildAt(i); + result.addAll(child.getVirtualFiles()); + } + return result; + } + + public Collection getFiles() { + Collection result = new ArrayList(); + for (int i = 0; i < getChildCount(); i++){ + FileOrDirectoryTreeNode child = (FileOrDirectoryTreeNode)getChildAt(i); + result.addAll(child.getFiles()); + } + return result; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileOrDirectoryTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileOrDirectoryTreeNode.java new file mode 100644 index 00000000000..a85a798f5f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileOrDirectoryTreeNode.java @@ -0,0 +1,96 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vcs.update.AbstractTreeNode; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.ui.SimpleTextAttributes; + +import java.awt.*; +import java.io.File; +import java.util.Map; + +/** + * author: lesya + */ +public abstract class FileOrDirectoryTreeNode extends AbstractTreeNode implements VirtualFilePointerListener { + private final static Map myFileStatusToAttributeMap = new com.intellij.util.containers.HashMap(); + protected final SimpleTextAttributes myInvalidAttributes; + protected final Project myProject; + protected final File myFile; + private final String myParentPath; + private final String myName; + + public FileOrDirectoryTreeNode(String path, SimpleTextAttributes invalidAttributes, + Project project, String parentPath) { + String preparedPath = path.replace(File.separatorChar, '/'); + String url = VirtualFileManager.constructUrl(LocalFileSystem.getInstance().getProtocol(), + preparedPath); + setUserObject(VirtualFilePointerManager.getInstance().create(url, this)); + myFile = new File(getFilePath()); + myInvalidAttributes = invalidAttributes; + myProject = project; + myParentPath = parentPath; + myName = myParentPath == null ? myFile.getAbsolutePath() : myFile.getName(); + } + + public String getName() { + return myName; + } + + protected String getFilePath() { + return getFilePointer().getPresentableUrl(); + } + + public void beforeValidityChanged(VirtualFilePointer[] pointers) { + } + + public void validityChanged(VirtualFilePointer[] pointers) { + if (!getFilePointer().isValid()) { + AbstractTreeNode parent = (AbstractTreeNode) getParent(); + if ((parent != null) && parent.getSupportsDeletion()) { + getTreeModel().removeNodeFromParent(this); + } + else { + if (getTree() != null) + getTree().repaint(); + } + } + } + + public VirtualFilePointer getFilePointer() { + return ((VirtualFilePointer)getUserObject()); + } + + public SimpleTextAttributes getAttributes() { + if (!getFilePointer().isValid()) { + return myInvalidAttributes; + } + VirtualFile file = getFilePointer().getFile(); + FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + FileStatus status = fileStatusManager.getStatus(file); + return getAttributesFor(status); + } + + private SimpleTextAttributes getAttributesFor(FileStatus status) { + Color color = status.getColor(); + if (color == null) color = Color.black; + + if (!myFileStatusToAttributeMap.containsKey(status)) { + myFileStatusToAttributeMap.put(status, new SimpleTextAttributes(Font.PLAIN, color)); + } + return (SimpleTextAttributes)myFileStatusToAttributeMap.get(status); + } + + public boolean getSupportsDeletion() { + AbstractTreeNode parent = ((AbstractTreeNode)getParent()); + if (parent == null) return false; + return parent.getSupportsDeletion(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileTreeNode.java new file mode 100644 index 00000000000..06a7d68a59f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/FileTreeNode.java @@ -0,0 +1,53 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.ArrayList; + +/** + * author: lesya + */ +public class FileTreeNode extends FileOrDirectoryTreeNode { + private static final Collection EMPTY_VIRTUAL_FILE_ARRAY = new ArrayList(); + + + public FileTreeNode(String path, SimpleTextAttributes invalidAttributes, + Project project, String parentPath) { + super(path, invalidAttributes, project, parentPath); + } + + public Icon getIcon(boolean expanded) { + return FileTypeManager.getInstance().getFileTypeByFileName(myFile.getName()).getIcon(); + } + + public Collection getVirtualFiles() { + VirtualFile virtualFile = getFilePointer().getFile(); + if (virtualFile == null) return EMPTY_VIRTUAL_FILE_ARRAY; + return Collections.singleton(virtualFile); + } + + public Collection getFiles() { + if (getFilePointer().getFile() == null) { + return Collections.singleton(myFile); + } + else { + return EMPTY_FILE_ARRAY; + } + } + + protected int getItemsCount() { + return 1; + } + + protected boolean showStatistics() { + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupByPackages.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupByPackages.java new file mode 100644 index 00000000000..c019ebc725d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupByPackages.java @@ -0,0 +1,71 @@ +package com.intellij.openapi.vcs.update; + +import java.io.File; +import java.util.*; + +/** + * author: lesya + */ +public class GroupByPackages { + + private final Map> myParentToChildrenMap + = new HashMap>(); + private Collection myRoots = new HashSet(); + + public GroupByPackages(Collection fiels) { + for (Iterator each = fiels.iterator(); each.hasNext();) { + process((File)each.next()); + } + + splitRoots(); + } + + private void splitRoots() { + for (Iterator each = new ArrayList(myRoots).iterator(); each.hasNext();) { + File oldRoot = (File)each.next(); + File newRoot = splitRoot(oldRoot); + if (!oldRoot.equals(newRoot)) replaceRoot(oldRoot, newRoot); + } + } + + private void replaceRoot(File oldRoot, File newRoot) { + myRoots.remove(oldRoot); + myRoots.add(newRoot); + } + + private File splitRoot(File oldRoot) { + Collection children = getChildren(oldRoot); + if (children == null) return oldRoot; + if (children.size() == 1) + return splitRoot(children.iterator().next()); + else { + return oldRoot; + } + + } + + private void process(File file) { + File parent = file.getParentFile(); + if (parent == null) { + myRoots.add(file); + return; + } + + if (!myParentToChildrenMap.containsKey(parent)) myParentToChildrenMap.put(parent, new HashSet()); + myParentToChildrenMap.get(parent).add(file); + + process(parent); + } + + public List getRoots() { + return new ArrayList(myRoots); + } + + public List getChildren(File file) { + Collection collection = myParentToChildrenMap.get(file); + if (collection == null) + return new ArrayList(); + else + return new ArrayList(collection); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupTreeNode.java new file mode 100644 index 00000000000..6d60a148597 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/GroupTreeNode.java @@ -0,0 +1,164 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.io.File; +import java.util.*; + +/** + * author: lesya + */ +public class GroupTreeNode extends AbstractTreeNode { + private final String myName; + private final boolean mySupportsDeletion; + private final List myFilePaths = new ArrayList(); + private final SimpleTextAttributes myInvalidAttributes; + private final Project myProject; + + public GroupTreeNode(String name, boolean supportsDeletion, SimpleTextAttributes invalidAttributes, + Project project) { + myName = name; + mySupportsDeletion = supportsDeletion; + myInvalidAttributes = invalidAttributes; + myProject = project; + } + + public String getName() { + return myName; + } + + public Icon getIcon(boolean expanded) { + String iconName = expanded ? "folderOpen" : "folder"; + return IconLoader.getIcon("/nodes/" + iconName + ".png"); + } + + public Collection getVirtualFiles() { + ArrayList result = new ArrayList(); + for (int i = 0; i < getChildCount(); i++) { + result.addAll(((AbstractTreeNode)getChildAt(i)).getVirtualFiles()); + } + return result; + } + + public Collection getFiles() { + ArrayList result = new ArrayList(); + for (int i = 0; i < getChildCount(); i++) { + result.addAll(((AbstractTreeNode)getChildAt(i)).getFiles()); + } + return result; + } + + protected int getItemsCount() { + int result = 0; + Enumeration children = children(); + while (children.hasMoreElements()) { + AbstractTreeNode treeNode = (AbstractTreeNode)children.nextElement(); + result += treeNode.getItemsCount(); + } + return result; + } + + protected boolean showStatistics() { + return true; + } + + public SimpleTextAttributes getAttributes() { + return SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES; + } + + public boolean getSupportsDeletion() { + return mySupportsDeletion; + } + + public void addFilePath(String filePath) { + myFilePaths.add(filePath); + } + + public void rebuild(boolean groupByPackages) { + if (containsGroups()) { + rebuildGroups(groupByPackages); + } + else + rebuildFiles(groupByPackages); + + } + + private void rebuildGroups(boolean groupByPackages) { + for (int i = 0; i < getChildCount(); i++) + ((GroupTreeNode)getChildAt(i)).rebuild(groupByPackages); + } + + private void rebuildFiles(boolean groupByPackages) { + removeAllChildren(); + + if (groupByPackages) { + buildPackages(); + } + else { + buildFiles(); + } + + setTreeModel(myTreeModel); + + if (myTreeModel != null) + myTreeModel.nodeStructureChanged(this); + } + + private void buildPackages() { + ArrayList files = new ArrayList(); + for (Iterator each = myFilePaths.iterator(); each.hasNext();) { + files.add(new File((String)each.next())); + } + GroupByPackages groupByPackages = new GroupByPackages(files); + + List roots = groupByPackages.getRoots(); + addFiles(this, roots, files, groupByPackages, null); + + } + + private void addFiles(AbstractTreeNode parentNode, List roots, + final ArrayList files, GroupByPackages groupByPackages, String parentPath) { + if (roots == null) return; + + Collections.sort(roots, new Comparator(){ + public int compare(File file, File file1) { + if (files.contains(file) == files.contains(file1)) + return file.getAbsolutePath().compareToIgnoreCase(file1.getAbsolutePath()); + else if (files.contains(file)) + return 1; + else + return -1; + } + }); + + for (Iterator iterator = roots.iterator(); iterator.hasNext();) { + File file = (File)iterator.next(); + FileOrDirectoryTreeNode child = files.contains(file) ? + new FileTreeNode(file.getAbsolutePath(), myInvalidAttributes, myProject, parentPath) + : (FileOrDirectoryTreeNode)new DirectoryTreeNode(file.getAbsolutePath(), myProject, parentPath); + parentNode.add(child); + addFiles(child, groupByPackages.getChildren(file), files, groupByPackages, child.getFilePath()); + } + } + + private void buildFiles() { + Collections.sort(myFilePaths, new Comparator(){ + public int compare(String path1, String path2) { + return path1.compareToIgnoreCase(path2); + } + }); + + for (Iterator each = myFilePaths.iterator(); each.hasNext();) { + String filePath = (String)each.next(); + add(new FileTreeNode(filePath, myInvalidAttributes, myProject, null)); + } + } + + private boolean containsGroups(){ + return myFilePaths.isEmpty(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/RestoreUpdateTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/RestoreUpdateTree.java new file mode 100644 index 00000000000..6783f0f306d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/RestoreUpdateTree.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectReloadState; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.startup.StartupManager; +import org.jdom.Element; + +public class RestoreUpdateTree implements ProjectComponent, JDOMExternalizable { + private final Project myProject; + + private UpdateInfo myUpdateInfo; + private static final String UPDATE_INFO = "UpdateInfo"; + + public RestoreUpdateTree(Project project) { + myProject = project; + } + + public void projectOpened() { + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + if (myUpdateInfo != null && !myUpdateInfo.isEmpty() && ProjectReloadState.getInstance(myProject).isAfterAutomaticReload()) { + ActionInfo actionInfo = myUpdateInfo.getActionInfo(); + if (actionInfo != null) { + CommonUpdateProjectAction.showUpdateProjectInfo(myProject, myUpdateInfo.getFileInformation(), "Update", actionInfo); + } + myUpdateInfo = null; + } + else { + myUpdateInfo = null; + } + } + }); + } + + public void projectClosed() { + + } + + public String getComponentName() { + return "RestoreUpdateTree"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void readExternal(Element element) throws InvalidDataException { + Element child = element.getChild(UPDATE_INFO); + if (child != null) { + UpdateInfo updateInfo = new UpdateInfo(myProject); + updateInfo.readExternal(child); + myUpdateInfo = updateInfo; + } + } + + public void writeExternal(Element element) throws WriteExternalException { + if (myUpdateInfo != null) { + Element child = new Element(UPDATE_INFO); + element.addContent(child); + myUpdateInfo.writeExternal(child); + } + } + + + public static RestoreUpdateTree getInstance(Project project) { + return project.getComponent(RestoreUpdateTree.class); + } + + public void registerUpdateInformation(UpdatedFiles updatedFiles, ActionInfo actionInfo) { + myUpdateInfo = new UpdateInfo(myProject, updatedFiles, actionInfo); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ScopeInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ScopeInfo.java new file mode 100644 index 00000000000..d0cba647300 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/ScopeInfo.java @@ -0,0 +1,73 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.actions.VcsContext; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.ArrayList; + +public interface ScopeInfo { + FilePath[] getRoots(VcsContext context); + + String getScopeName(VcsContext dataContext); + + ScopeInfo PROJECT = new ScopeInfo() { + public String getScopeName(VcsContext dataContext) { + return "Project"; + } + + public FilePath[] getRoots(VcsContext context) { + ArrayList result = new ArrayList(); + Project project = context.getProject(); + VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots(); + for (int i = 0; i < contentRoots.length; i++) { + VirtualFile contentRoot = contentRoots[i]; + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(contentRoot); + if (vcs != null) { + UpdateEnvironment updateEnvironment = vcs.getUpdateEnvironment(); + if (updateEnvironment != null) { + result.add(new FilePathImpl(contentRoot)); + } + } + } + return result.toArray(new FilePath[result.size()]); + } + }; + + ScopeInfo FILES = new ScopeInfo() { + public String getScopeName(VcsContext dataContext) { + FilePath[] roots = getRoots(dataContext); + if (roots == null || roots.length == 0) { + return "Files"; + } + boolean directory = roots[0].isDirectory(); + if (roots.length == 1) { + if (directory) { + return "Directory"; + } + else { + return "File"; + } + } + else { + if (directory) { + return "Directories"; + } + else { + return "Files"; + } + } + + } + + public FilePath[] getRoots(VcsContext context) { + return context.getSelectedFilePaths(); + } + + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfo.java new file mode 100644 index 00000000000..90e03ad0c6f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfo.java @@ -0,0 +1,94 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class UpdateInfo implements JDOMExternalizable { + private final Project myProject; + private UpdatedFiles myUpdatedFiles; + private String myDate; + private ActionInfo myActionInfo; + private static final DateFormat DATE_FORMAT = + SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT, Locale.getDefault()); + private static final String DATE_ATTR = "date"; + private static final String FILE_INFO_ELEMENTS = "UpdatedFiles"; + private static final String ACTION_INFO_ATTRIBUTE_NAME = "ActionInfo"; + + public UpdateInfo(Project project, UpdatedFiles updatedFiles, ActionInfo actionInfo) { + myProject = project; + myActionInfo = actionInfo; + myUpdatedFiles = updatedFiles; + myDate = DATE_FORMAT.format(new Date()); + } + + public UpdateInfo(Project project) { + myProject = project; + } + + public void writeExternal(Element element) throws WriteExternalException { + if (myUpdatedFiles == null) return; + element.setAttribute(DATE_ATTR, myDate); + element.setAttribute(ACTION_INFO_ATTRIBUTE_NAME, myActionInfo.getActionName()); + Element filesElement = new Element(FILE_INFO_ELEMENTS); + myUpdatedFiles.writeExternal(filesElement); + element.addContent(filesElement); + } + + public void readExternal(Element element) throws InvalidDataException { + myDate = element.getAttributeValue(DATE_ATTR); + Element fileInfoElement = element.getChild(FILE_INFO_ELEMENTS); + if (fileInfoElement == null) return; + + String actionInfoName = element.getAttributeValue(ACTION_INFO_ATTRIBUTE_NAME); + + myActionInfo = getActionInfoByName(actionInfoName); + if (myActionInfo == null) return; + + UpdatedFiles updatedFiles = UpdatedFiles.create(); + updatedFiles.readExternal(fileInfoElement); + myUpdatedFiles = updatedFiles; + + } + + private ActionInfo getActionInfoByName(String actionInfoName) { + if (ActionInfo.UPDATE.getActionName().equals(actionInfoName)) return ActionInfo.UPDATE; + if (ActionInfo.STATUS.getActionName().equals(actionInfoName)) return ActionInfo.STATUS; + return null; + } + + public String getHelpId() { + return null; + } + + public Project getPoject() { + return myProject; + } + + public UpdatedFiles getFileInformation() { + return myUpdatedFiles; + } + + public String getCaption() { + return "Update Project" + " (" + myDate + ")"; + } + + public boolean isEmpty() { + if (myUpdatedFiles != null) { + return myUpdatedFiles.isEmpty(); + } else { + return true; + } + } + + public ActionInfo getActionInfo() { + return myActionInfo; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfoTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfoTree.java new file mode 100644 index 00000000000..deaa45a2d42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateInfoTree.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.PanelWithActionsAndCloseButton; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.UIHelper; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.io.File; +import java.util.ArrayList; + +public class UpdateInfoTree extends PanelWithActionsAndCloseButton { + private VirtualFile mySelectedFile; + protected JTree myTree = new Tree(); + protected final Project myProject; + protected final UpdatedFiles myUpdatedFiles; + private UpdateRootNode myRoot; + private DefaultTreeModel myTreeModel; + private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.updateinfo.CvsUpdateInfoTree"); + protected FileStatusListener myFileStatusListener; + protected final FileStatusManager myFileStatusManager; + private final String myRootName; + private final ActionInfo myActionInfo; + + public UpdateInfoTree(ContentManager contentManager, + String helpId, + Project project, + UpdatedFiles updatedFiles, + String rootName, + ActionInfo actionInfo) { + super(contentManager, helpId); + myActionInfo = actionInfo; + + myFileStatusListener = new FileStatusListener() { + public void fileStatusesChanged() { + myTree.repaint(); + } + + public void fileStatusChanged(VirtualFile virtualFile) { + myTree.repaint(); + } + }; + + myProject = project; + myUpdatedFiles = updatedFiles; + myRootName = rootName; + + myFileStatusManager = FileStatusManager.getInstance(myProject); + myFileStatusManager.addFileStatusListener(myFileStatusListener); + createTree(); + init(); + } + + protected void dispose() { + super.dispose(); + myFileStatusManager.removeFileStatusListener(myFileStatusListener); + } + + protected void addActionsTo(DefaultActionGroup group) { + group.add(new MyGroupByPackagesAction()); + } + + protected JComponent createCenterPanel() { + return ScrollPaneFactory.createScrollPane(myTree); + } + + protected void createTree() { + UIHelper uiHelper = PeerFactory.getInstance().getUIHelper(); + uiHelper.installSmartExpander(myTree); + uiHelper.installSelectionSaver(myTree); + refreshTree(); + + myTree.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + AbstractTreeNode treeNode = (AbstractTreeNode)e.getPath().getLastPathComponent(); + if (treeNode instanceof FileTreeNode) { + mySelectedFile = ((FileTreeNode)treeNode).getFilePointer().getFile(); + } + else { + mySelectedFile = null; + } + } + }); + myTree.setCellRenderer(new UpdateTreeCellRenderer()); + uiHelper.installToolTipHandler(myTree); + TreeUtil.installActions(myTree); + + myTree.addMouseListener(new PopupHandler() { + public void invokePopup(Component comp, int x, int y) { + ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UPDATE_POPUP, + getActionGroup()); + popupMenu.getComponent().show(comp, x, y); + } + }); + uiHelper.installEditSourceOnDoubleClick(myTree); + uiHelper.installEditSourceOnEnterKeyHandler(myTree); + + myTree.setSelectionRow(0); + } + + private void refreshTree() { + LOG.assertTrue(myProject != null); + myRoot = new UpdateRootNode(myUpdatedFiles, myProject, myRootName, myActionInfo); + myRoot.rebuild(VcsConfiguration.getInstance(myProject).UPDATE_GROUP_BY_PACKAGES); + myTreeModel = new DefaultTreeModel(myRoot); + myRoot.setTreeModel(myTreeModel); + myTree.setModel(myTreeModel); + myRoot.setTree(myTree); + } + + private DefaultActionGroup getActionGroup() { + return (DefaultActionGroup)ActionManager.getInstance().getAction("UpdateActionGroup"); + } + + public Object getData(String dataId) { + if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (mySelectedFile == null) return null; + return new OpenFileDescriptor(myProject, mySelectedFile); + } + else if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + return getVirtualFileArray(); + } + else if (VcsDataConstants.IO_FILE_ARRAY.equals(dataId)) { + return getFileArray(); + } + return ProjectLevelVcsManager.getInstance(myProject).createVirtualAndPsiFileDataProvider(getVirtualFileArray(), mySelectedFile) + .getData(dataId); + } + + private VirtualFile[] getVirtualFileArray() { + ArrayList result = new ArrayList(); + TreePath[] selectionPaths = myTree.getSelectionPaths(); + if (selectionPaths != null) { + for (int i = 0; i < selectionPaths.length; i++) { + TreePath selectionPath = selectionPaths[i]; + AbstractTreeNode treeNode = (AbstractTreeNode)selectionPath.getLastPathComponent(); + result.addAll(treeNode.getVirtualFiles()); + } + } + if (result.isEmpty()) return VirtualFile.EMPTY_ARRAY; + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + protected File[] getFileArray() { + ArrayList result = new ArrayList(); + TreePath[] selectionPaths = myTree.getSelectionPaths(); + if (selectionPaths != null) { + for (int i = 0; i < selectionPaths.length; i++) { + TreePath selectionPath = selectionPaths[i]; + AbstractTreeNode treeNode = (AbstractTreeNode)selectionPath.getLastPathComponent(); + result.addAll(treeNode.getFiles()); + } + } + if (result.isEmpty()) return null; + return (File[])result.toArray(new File[result.size()]); + } + + public void expandRootChildren() { + TreeNode root = (TreeNode)myTreeModel.getRoot(); + + if (root.getChildCount() == 1) { + myTree.expandPath(new TreePath(new Object[]{root, root.getChildAt(0)})); + } + } + + private class MyGroupByPackagesAction extends ToggleAction { + public MyGroupByPackagesAction() { + super("Group by Packages", null, IconLoader.getIcon("/_cvs/showAsTree.png")); + } + + public boolean isSelected(AnActionEvent e) { + return VcsConfiguration.getInstance(myProject).UPDATE_GROUP_BY_PACKAGES; + } + + public void setSelected(AnActionEvent e, boolean state) { + VcsConfiguration.getInstance(myProject).UPDATE_GROUP_BY_PACKAGES = state; + myRoot.rebuild(VcsConfiguration.getInstance(myProject).UPDATE_GROUP_BY_PACKAGES); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateOrStatusOptionsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateOrStatusOptionsDialog.java new file mode 100644 index 00000000000..6a1d5073d84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateOrStatusOptionsDialog.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vcs.ui.OptionsDialog; + +import javax.swing.*; +import java.awt.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public abstract class UpdateOrStatusOptionsDialog extends OptionsDialog { + private final JComponent myMainPanel; + private final Map myEnvToConfMap = new HashMap(); + protected final Project myProject; + + + public UpdateOrStatusOptionsDialog(Project project, Map confs) { + super(project); + setTitle(getRealTitle()); + myProject = project; + if (confs.size() == 1) { + myMainPanel = new JPanel(new BorderLayout()); + addComponent(confs.get(confs.keySet().iterator().next()), confs.keySet().iterator().next(), BorderLayout.CENTER); + myMainPanel.add(new JSeparator(), BorderLayout.SOUTH); + } + else { + myMainPanel = new JTabbedPane(); + for (Iterator iterator = confs.keySet().iterator(); iterator.hasNext();) { + addComponent(confs.get(iterator.next()), iterator.next(), iterator.next().getDisplayName()); + } + } + init(); + } + + protected abstract String getRealTitle(); + + private void addComponent(UpdateEnvironment updateEnvironment, Configurable configurable, String constraint) { + myEnvToConfMap.put(updateEnvironment, configurable); + myMainPanel.add(configurable.createComponent(), constraint); + configurable.reset(); + } + + protected void doOKAction() { + for (Iterator iterator = myEnvToConfMap.values().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next(); + try { + configurable.apply(); + } + catch (ConfigurationException e) { + Messages.showErrorDialog(myProject, "Cannot save sattings: " + e.getLocalizedMessage(), getRealTitle()); + return; + } + } + super.doOKAction(); + } + + protected boolean shouldSaveOptionsOnCancel() { + return false; + } + + protected JComponent createCenterPanel() { + + return myMainPanel; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateRootNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateRootNode.java new file mode 100644 index 00000000000..080855361e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateRootNode.java @@ -0,0 +1,46 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.openapi.project.Project; +import com.intellij.ui.SimpleTextAttributes; + +import java.util.Iterator; +import java.util.List; + +public class UpdateRootNode extends GroupTreeNode { + + private final Project myProject; + + public UpdateRootNode(UpdatedFiles updatedFiles, Project project, String rootName, ActionInfo actionInfo) { + super(rootName, false, SimpleTextAttributes.ERROR_ATTRIBUTES, project); + myProject = project; + + addGroupsToNode(updatedFiles.getTopLevelGroups(), this, actionInfo); + } + + private void addGroupsToNode(List groups, AbstractTreeNode owner, ActionInfo actionInfo) { + for (Iterator iterator = groups.iterator(); iterator.hasNext();) { + FileGroup fileGroup = iterator.next(); + GroupTreeNode node = addFileGroup(fileGroup, owner, actionInfo); + if (node != null) { + addGroupsToNode(fileGroup.getChildren(), node, actionInfo); + } + } + } + + private GroupTreeNode addFileGroup(FileGroup fileGroup, AbstractTreeNode parent, ActionInfo actionInfo) { + if (fileGroup.isEmpty()) { + return null; + } + GroupTreeNode group = new GroupTreeNode(actionInfo.getGroupName(fileGroup), fileGroup.getSupportsDeletion(), + fileGroup.getInvalidAttributes(), myProject); + parent.add(group); + for (Iterator each = fileGroup.getFiles().iterator(); each.hasNext();) { + group.addFilePath((String)each.next()); + } + return group; + } + + public boolean getSupportsDeletion() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateTreeCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateTreeCellRenderer.java new file mode 100644 index 00000000000..49679c94e8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vcs/update/UpdateTreeCellRenderer.java @@ -0,0 +1,19 @@ +package com.intellij.openapi.vcs.update; + +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.openapi.vcs.update.AbstractTreeNode; + +import javax.swing.*; + +/** + * author: lesya + */ +public class UpdateTreeCellRenderer extends ColoredTreeCellRenderer{ + + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + + AbstractTreeNode treeNode = (AbstractTreeNode)value; + append(treeNode.getText(), treeNode.getAttributes()); + setIcon(treeNode.getIcon(expanded)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerAdapter.java new file mode 100644 index 00000000000..627477e397d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerAdapter.java @@ -0,0 +1,10 @@ + +package com.intellij.openapi.vfs.ex; + +public abstract class VirtualFileManagerAdapter implements VirtualFileManagerListener { + public void beforeRefreshStart(boolean asynchonous) { + } + + public void afterRefreshFinish(boolean asynchonous) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerEx.java new file mode 100644 index 00000000000..57eafb1a5b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/VirtualFileManagerEx.java @@ -0,0 +1,29 @@ + +package com.intellij.openapi.vfs.ex; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; + +public abstract class VirtualFileManagerEx extends VirtualFileManager { + public abstract ProgressIndicator getRefreshIndicator(); + // Used by Fabrique: + public abstract void setRefreshIndicator(ProgressIndicator refreshIndicator); + + public abstract void addVirtualFileManagerListener(VirtualFileManagerListener listener); + public abstract void removeVirtualFileManagerListener(VirtualFileManagerListener listener); + + public abstract void beforeRefreshStart(boolean asynchronous, ModalityState modalityState, Runnable postAction); + public abstract void afterRefreshFinish(boolean asynchronous, ModalityState modalityState); + public abstract void addEventToFireByRefresh(Runnable action, boolean asynchronous, ModalityState modalityState); + + public abstract void registerFileContentProvider(FileContentProvider provider); + public abstract void unregisterFileContentProvider(FileContentProvider provider); + + public abstract void registerRefreshUpdater(CacheUpdater updater); + public abstract void unregisterRefreshUpdater(CacheUpdater updater); + + public abstract ProvidedContent getProvidedContent(VirtualFile file); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java new file mode 100644 index 00000000000..224f6654e45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java @@ -0,0 +1,72 @@ + +package com.intellij.openapi.vfs.ex.dummy; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; + +/** + * + */ +public class DummyFileSystem extends VirtualFileSystem implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.ex.dummy.DummyFileSystem"); + + public static final String PROTOCOL = "dummy"; + + public static DummyFileSystem getInstance() { + return ApplicationManager.getApplication().getComponent(DummyFileSystem.class); + } + + public DummyFileSystem() { + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public VirtualFile createRoot(String name) { + final VirtualFileDirectoryImpl root = new VirtualFileDirectoryImpl(this, null, name); + fireFileCreated(null, root); + return root; + } + + protected void fireFileCreated(Object requestor, VirtualFile file) { + super.fireFileCreated(requestor, file); + } + + protected void fireFileDeleted(Object requestor, VirtualFile file, String fileName, boolean isDirectory, VirtualFile parent) { + super.fireFileDeleted(requestor, file, fileName, isDirectory, parent); + } + + protected void fireBeforeFileDeletion(Object requestor, VirtualFile file) { + super.fireBeforeFileDeletion(requestor, file); + } + + public String getProtocol() { + return PROTOCOL; + } + + public VirtualFile findFileByPath(String path) { +// LOG.error("method not implemented"); + return null; + } + + public String extractPresentableUrl(String path) { + return path; + } + + public void refresh(boolean asynchronous) { + } + + public VirtualFile refreshAndFindFileByPath(String path) { + return findFileByPath(path); + } + + public String getComponentName() { + return "DummyFileSystem"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDataImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDataImpl.java new file mode 100644 index 00000000000..13a2de5578a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDataImpl.java @@ -0,0 +1,97 @@ + +package com.intellij.openapi.vfs.ex.dummy; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.LocalTimeCounter; + +import java.io.*; + +/** + * + */ +class VirtualFileDataImpl extends VirtualFileImpl { + private byte[] myContents = new byte[0]; + private long myModificationStamp = LocalTimeCounter.currentTime(); + + public VirtualFileDataImpl(DummyFileSystem fileSystem, VirtualFileDirectoryImpl parent, String name) { + super(fileSystem, parent, name); + } + + public boolean isDirectory() { + return false; + } + + public long getLength() { + return myContents.length; + } + + public VirtualFile[] getChildren() { + return null; + } + + public VirtualFile createChildDirectory(Object requestor, String name) throws IOException { + throw new IOException(); + } + + public VirtualFile createChildData(Object requestor, String name) throws IOException { + throw new IOException(); + } + + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(myContents); + } + + public OutputStream getOutputStream(Object requestor, final long newModificationStamp, long newTimeStamp) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + return new OutputStream() { + public void write(int b) throws IOException { + out.write(b); + } + + public void write(byte[] b) throws IOException { + out.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + public void flush() throws IOException { + out.flush(); + } + + public void close() throws IOException { + out.close(); + myContents = out.toByteArray(); + myModificationStamp = newModificationStamp >= 0 ? newModificationStamp : LocalTimeCounter.currentTime(); + } + }; + } + + public byte[] contentsToByteArray() throws IOException { + return myContents; + } + + public char[] contentsToCharArray() throws IOException { + Reader reader = getReader(); + char[] chars = new char[myContents.length]; + int count = reader.read(chars, 0, chars.length); + reader.close(); + if (count == chars.length){ + return chars; + } + else{ + char[] newChars = new char[count]; + System.arraycopy(chars, 0, newChars, 0, count); + return newChars; + } + } + + public long getModificationStamp() { + return myModificationStamp; + } + + public void setModificationStamp(long modificationStamp, Object requestor) { + myModificationStamp = modificationStamp; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDirectoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDirectoryImpl.java new file mode 100644 index 00000000000..f30c7192dec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileDirectoryImpl.java @@ -0,0 +1,81 @@ + +package com.intellij.openapi.vfs.ex.dummy; + +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.*; +import java.util.ArrayList; + +/** + * + */ +class VirtualFileDirectoryImpl extends VirtualFileImpl { + private ArrayList myChildren = new ArrayList(); + + public VirtualFileDirectoryImpl(DummyFileSystem fileSystem, VirtualFileDirectoryImpl parent, String name) { + super(fileSystem, parent, name); + } + + public boolean isDirectory() { + return true; + } + + public long getLength() { + return 0; + } + + public VirtualFile[] getChildren() { + return (VirtualFile[])myChildren.toArray(new VirtualFile[myChildren.size()]); + } + + public VirtualFile createChildDirectory(Object requestor, String name) throws IOException { + VirtualFile file = findChild(name); + if (file != null){ + throw new IOException("Cannot create file " + getUrl() + "/" + name + ". File already exists."); + } + VirtualFileImpl child = new VirtualFileDirectoryImpl(myFileSystem, this, name); + addChild(child); + return child; + } + + public VirtualFile createChildData(Object requestor, String name) throws IOException { + VirtualFile file = findChild(name); + if (file != null){ + throw new IOException("Cannot create file " + getUrl() + "/" + name + ". File already exists."); + } + VirtualFileImpl child = new VirtualFileDataImpl(myFileSystem, this, name); + addChild(child); + return child; + } + + public InputStream getInputStream() throws IOException { + throw new IOException("Cannot read from file " + getUrl() + "."); + } + + public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException { + throw new IOException("Cannot write to file " + getUrl() + "."); + } + + public byte[] contentsToByteArray() throws IOException { + throw new IOException("Cannot read from file " + getUrl() + "."); + } + + public char[] contentsToCharArray() throws IOException { + throw new IOException("Cannot read from file " + getUrl() + "."); + } + + public long getModificationStamp() { + return -1; + } + + void addChild(VirtualFileImpl child) { + myChildren.add(child); + myFileSystem.fireFileCreated(null, child); + } + + void removeChild(VirtualFileImpl child) { + myFileSystem.fireBeforeFileDeletion(null, child); + myChildren.remove(child); + myFileSystem.fireFileDeleted(null, child, child.getName(), child.isDirectory(), this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java new file mode 100644 index 00000000000..d06a44d186c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java @@ -0,0 +1,91 @@ + +package com.intellij.openapi.vfs.ex.dummy; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; + +import java.io.IOException; + +/** + * + */ +abstract class VirtualFileImpl extends VirtualFile { + protected final DummyFileSystem myFileSystem; + protected VirtualFileDirectoryImpl myParent; + private boolean myRootFlag; + private String myName; + private boolean myIsValid = true; + + protected VirtualFileImpl(DummyFileSystem fileSystem, VirtualFileDirectoryImpl parent, String name) { + myFileSystem = fileSystem; + myParent = parent; + myRootFlag = parent != null; + myName = name; + } + + public VirtualFileSystem getFileSystem() { + return myFileSystem; + } + + public String getPath() { + if (myParent == null) { + return myName; + } else { + return myParent.getPath() + "/" + myName; + } + } + + public String getName() { + return myName; + } + + public void rename(Object requestor, String newName) throws IOException { + if (myName.equals(newName)){ + return; + } + myName = newName; + } + + public boolean isWritable() { + return true; + } + + public boolean isValid() { + return myIsValid; +/* + if (myParent != null){ + return myParent.isValid(); + } + else{ + return myRootFlag; + } +*/ + } + + public VirtualFile getParent() { + return myParent; + } + + public void delete(Object requestor) throws IOException { + if (myParent == null){ + throw new IOException("Cannot delete root file " + getPresentableUrl() + "."); + } + myParent.removeChild(this); + myIsValid = false; + } + + public void move(Object requestor, VirtualFile newParent) throws IOException { + throw new UnsupportedOperationException(); + } + + public long getTimeStamp() { + return -1; + } + + public long getActualTimeStamp() { + return -1; + } + + public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/HttpFileSystem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/HttpFileSystem.java new file mode 100644 index 00000000000..23280f4521e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/HttpFileSystem.java @@ -0,0 +1,46 @@ + +package com.intellij.openapi.vfs.ex.http; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.VirtualFileSystem; + +public class HttpFileSystem extends VirtualFileSystem implements ApplicationComponent { + + public static final String PROTOCOL = "http"; + + public static HttpFileSystem getInstance() { + return ApplicationManager.getApplication().getComponent(HttpFileSystem.class); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public String getProtocol() { + return PROTOCOL; + } + + public VirtualFile findFileByPath(String path) { + return new VirtualFileImpl(this, path); + } + + public String extractPresentableUrl(String path) { + return VirtualFileManager.constructUrl(PROTOCOL, path); + } + + public VirtualFile refreshAndFindFileByPath(String path) { + return findFileByPath(path); + } + + public void refresh(boolean asynchronous) { + } + + public String getComponentName() { + return "HttpFileSystem"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/VirtualFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/VirtualFileImpl.java new file mode 100644 index 00000000000..f37c9b59981 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/ex/http/VirtualFileImpl.java @@ -0,0 +1,135 @@ + +package com.intellij.openapi.vfs.ex.http; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; + +import java.io.*; + +class VirtualFileImpl extends VirtualFile { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.ex.http.VirtualFileImpl"); + + private final HttpFileSystem myFileSystem; + + private String myPath; + private String myParentPath; + private String myName; + + private static final VirtualFileImpl[] EMPTY_VIRTUAL_FILE_ARRAY = new VirtualFileImpl[0]; + + VirtualFileImpl(HttpFileSystem fileSystem, String path) { + myFileSystem = fileSystem; + myPath = path; + int lastSlash = path.lastIndexOf('/'); + if (lastSlash == path.length() - 1){ + myParentPath = null; + myName = path; + } + else{ + int prevSlash = path.lastIndexOf('/', lastSlash - 1); + if (prevSlash < 0){ + myParentPath = path.substring(0, lastSlash + 1); + myName = path.substring(lastSlash + 1); + } + else{ + myParentPath = path.substring(0, lastSlash); + myName = path.substring(lastSlash + 1); + } + } + } + + public VirtualFileSystem getFileSystem() { + return myFileSystem; + } + + public String getPath() { + return myPath; + } + + public String getName() { + return myName; + } + + public VirtualFile getParent() { + if (myParentPath == null) return null; + return myFileSystem.findFileByPath(myParentPath); + } + + public void rename(Object requestor, String newName) throws IOException { + throw new UnsupportedOperationException(); + } + + public boolean isWritable() { + return false; + } + + public boolean isValid() { + return true; + } + + public boolean isDirectory() { + return true; + } + + public VirtualFile[] getChildren() { + throw new UnsupportedOperationException(); + } + + public VirtualFile createChildDirectory(Object requestor, String name) throws IOException { + throw new UnsupportedOperationException(); + } + + public VirtualFile createChildData(Object requestor, String name) throws IOException { + throw new UnsupportedOperationException(); + } + + public void delete(Object requestor) throws IOException { + throw new UnsupportedOperationException(); + } + + public void move(Object requestor, VirtualFile newParent) throws IOException { + throw new UnsupportedOperationException(); + } + + public InputStream getInputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException { + throw new UnsupportedOperationException(); + } + + public byte[] contentsToByteArray() throws IOException { + throw new UnsupportedOperationException(); + } + + public char[] contentsToCharArray() throws IOException { + throw new UnsupportedOperationException(); + } + + public long getModificationStamp() { + throw new UnsupportedOperationException(); + } + + public long getTimeStamp() { + throw new UnsupportedOperationException(); + } + + public long getActualTimeStamp() { + throw new UnsupportedOperationException(); + } + + public long getLength() { + return -1; + } + + public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) { + throw new UnsupportedOperationException(); + }; + + public String toString() { + return getPath(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java new file mode 100644 index 00000000000..36c887533f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java @@ -0,0 +1,412 @@ +package com.intellij.openapi.vfs.impl; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.ide.startup.FileSystemSynchronizer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.StatusBarProgress; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.ex.FileContentProvider; +import com.intellij.openapi.vfs.ex.ProvidedContent; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.openapi.vfs.ex.VirtualFileManagerListener; +import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.HashMap; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Stack; + +public class VirtualFileManagerImpl extends VirtualFileManagerEx implements ApplicationComponent { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.VirtualFileManagerImpl"); + + private ArrayList myFileSystems = null; + private HashMap myProtocolToSystemMap = null; + + private EventDispatcher myVirtualFileListenerMulticaster = EventDispatcher.create(VirtualFileListener.class); + private EventDispatcher myVirtualFileManagerListenerMulticaster = EventDispatcher.create(VirtualFileManagerListener.class); + private EventDispatcher myModificationAttemptListenerMulticaster = EventDispatcher.create(ModificationAttemptListener.class); + + private ProgressIndicator myRefreshIndicator = new StatusBarProgress(); + + private ArrayList myContentProviders = new ArrayList(); + private EventDispatcher myContentProvidersDispatcher = EventDispatcher.create(VirtualFileListener.class); + private ArrayList myRefreshParticipants = new ArrayList(); + + private int myRefreshCount = 0; + private ArrayList myRefreshEventsToFire = null; + private Stack myPostRefreshRunnables = new Stack(); + + + public VirtualFileManagerImpl(VirtualFileSystem[] fileSystems) { + myFileSystems = new ArrayList(); + myProtocolToSystemMap = new HashMap(); + for (int i = 0; i < fileSystems.length; i++) { + registerFileSystem(fileSystems[i]); + } + + if (LOG.isDebugEnabled()) { + addVirtualFileListener(new LoggingListener()); + } + addVirtualFileListener(myContentProvidersDispatcher.getMulticaster()); + + } + + public String getComponentName() { + return "VirtualFileManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public ProgressIndicator getRefreshIndicator() { + return myRefreshIndicator; + } + + // Used by Fabrique: + public void setRefreshIndicator(ProgressIndicator refreshIndicator) { + myRefreshIndicator = refreshIndicator; + } + + private void registerFileSystem(VirtualFileSystem fileSystem) { + myFileSystems.add(fileSystem); + fileSystem.addVirtualFileListener(myVirtualFileListenerMulticaster.getMulticaster()); + myProtocolToSystemMap.put(fileSystem.getProtocol(), fileSystem); + } + + public VirtualFileSystem[] getFileSystems() { + return myFileSystems.toArray(new VirtualFileSystem[myFileSystems.size()]); + } + + public VirtualFileSystem getFileSystem(String protocol) { + return myProtocolToSystemMap.get(protocol); + } + + public void refresh(boolean asynchronous) { + refresh(asynchronous, null); + } + + public void refresh(boolean asynchronous, final Runnable postAction) { + ModalityState modalityState = EventQueue.isDispatchThread() ? ModalityState.current() : ModalityState.NON_MMODAL; + + beforeRefreshStart(asynchronous, modalityState, postAction); + + try { + if (!asynchronous) { + LOG.assertTrue( + ApplicationManager.getApplication().isDispatchThread(), + "Synchronous refresh can be performed in AWT-thread only!" + ); + } + + LOG.info("refresh(), modalityState=" + modalityState); + + for (int i = 0; i < myFileSystems.size(); i++) { + VirtualFileSystem fileSystem = myFileSystems.get(i); + fileSystem.refresh(asynchronous); + } + } + finally { + afterRefreshFinish(asynchronous, modalityState); + } + } + + public VirtualFile findFileByUrl(String url) { + String protocol = extractProtocol(url); + if (protocol == null) return null; + VirtualFileSystem fileSystem = myProtocolToSystemMap.get(protocol); + if (fileSystem == null) return null; + return fileSystem.findFileByPath(extractPath(url)); + } + + public VirtualFile refreshAndFindFileByUrl(String url) { + String protocol = extractProtocol(url); + if (protocol == null) return null; + VirtualFileSystem fileSystem = myProtocolToSystemMap.get(protocol); + if (fileSystem == null) return null; + String path = extractPath(url); + return fileSystem.refreshAndFindFileByPath(path); + } + + public void addVirtualFileListener(VirtualFileListener listener) { + myVirtualFileListenerMulticaster.addListener(listener); + } + + public void removeVirtualFileListener(VirtualFileListener listener) { + myVirtualFileListenerMulticaster.removeListener(listener); + } + + public void dispatchPendingEvent(VirtualFileListener listener) { + myVirtualFileListenerMulticaster.dispatchPendingEvent(listener); + } + + public void addModificationAttemptListener(ModificationAttemptListener listener) { + myModificationAttemptListenerMulticaster.addListener(listener); + } + + public void removeModificationAttemptListener(ModificationAttemptListener listener) { + myModificationAttemptListenerMulticaster.removeListener(listener); + } + + public void fireReadOnlyModificationAttempt(VirtualFile[] files) { + ApplicationManager.getApplication().assertIsDispatchThread(); + + final ModificationAttemptEvent event = new ModificationAttemptEvent(this, files); + myModificationAttemptListenerMulticaster.getMulticaster().readOnlyModificationAttempt(event); + } + + public void addVirtualFileManagerListener(VirtualFileManagerListener listener) { + myVirtualFileManagerListenerMulticaster.addListener(listener); + } + + public void removeVirtualFileManagerListener(VirtualFileManagerListener listener) { + myVirtualFileManagerListenerMulticaster.removeListener(listener); + } + + public void beforeRefreshStart(final boolean asynchronous, ModalityState modalityState, final Runnable postAction) { + Runnable action = new Runnable() { + public void run() { + myRefreshCount++; + myPostRefreshRunnables.push(postAction); + if (myRefreshCount == 1) { + myRefreshEventsToFire = new ArrayList(); + myRefreshEventsToFire.add(new FireBeforeRefresh(asynchronous)); + } + } + }; + if (asynchronous) { + ApplicationManager.getApplication().invokeLater(action, modalityState); + } + else { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + action.run(); + } + } + + private class FireBeforeRefresh implements Runnable { + private final boolean myAsynchonous; + + public FireBeforeRefresh(boolean asynchonous) { + myAsynchonous = asynchonous; + } + + public void run() { + LOG.info("beforeRefreshStart()"); + myVirtualFileManagerListenerMulticaster.getMulticaster().beforeRefreshStart(myAsynchonous); + } + } + + public void afterRefreshFinish(final boolean asynchronous, ModalityState modalityState) { + Runnable action = new Runnable() { + public void run() { + myRefreshCount--; + + Runnable postRunnable = myPostRefreshRunnables.pop(); + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + for (int i = 0; i < myRefreshEventsToFire.size(); i++) { + Runnable runnable = myRefreshEventsToFire.get(i); + try { + runnable.run(); + } + catch (Exception e) { + LOG.error(e); + } + } + + if (myRefreshCount > 0) { + myRefreshEventsToFire.clear(); + } + else { + myRefreshEventsToFire = null; + + final FileSystemSynchronizer synchronizer; + if (asynchronous) { + synchronizer = new FileSystemSynchronizer(); + for (int i = 0; i < myRefreshParticipants.size(); i++) { + CacheUpdater participant = myRefreshParticipants.get(i); + synchronizer.registerCacheUpdater(participant); + } + } + else { + synchronizer = null; + } + + LOG.info("afterRefreshFinish()"); + myVirtualFileManagerListenerMulticaster.getMulticaster().afterRefreshFinish(asynchronous); + + if (asynchronous) { + int filesCount = synchronizer.collectFilesToUpdate(); + if (filesCount > 0) { + boolean runWithProgress = !ApplicationManager.getApplication().isUnitTestMode() && filesCount > 5; + if (runWithProgress) { + Runnable process = new Runnable() { + public void run() { + synchronizer.execute(); + } + }; + ApplicationManager.getApplication().runProcessWithProgressSynchronously(process, + "Updating Modified Files...", + false, null); + } + else { + synchronizer.execute(); + } + } + } + } + } + } + ); + + if (postRunnable != null){ + postRunnable.run(); + } + } + }; + + if (asynchronous) { + ApplicationManager.getApplication().invokeLater(action, modalityState); + } + else { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + action.run(); + } + } + + public void addEventToFireByRefresh(final Runnable action, boolean asynchronous, ModalityState modalityState) { + if (asynchronous) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myRefreshEventsToFire.add(action); + } + }, modalityState); + } + else { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + myRefreshEventsToFire.add(action); + } + } + + public void registerFileContentProvider(FileContentProvider provider) { + myContentProviders.add(provider); + myContentProvidersDispatcher.addListener(provider.getVirtualFileListener()); + } + + public void unregisterFileContentProvider(FileContentProvider provider) { + myContentProviders.remove(provider); + myContentProvidersDispatcher.removeListener(provider.getVirtualFileListener()); + } + + public void registerRefreshUpdater(CacheUpdater updater) { + myRefreshParticipants.add(updater); + } + + public void unregisterRefreshUpdater(CacheUpdater updater) { + boolean success = myRefreshParticipants.remove(updater); + LOG.assertTrue(success); + } + + public ProvidedContent getProvidedContent(VirtualFile file) { + for (int i = 0; i < myContentProviders.size(); i++) { + FileContentProvider provider = myContentProviders.get(i); + // not needed because of special order! + //dispatchPendingEvent(provider.getVirtualFileListener()); + VirtualFile[] coveredDirectories = provider.getCoveredDirectories(); + for (int j = 0; j < coveredDirectories.length; j++) { + VirtualFile coveredDirectory = coveredDirectories[j]; + if (VfsUtil.isAncestor(coveredDirectory, file, true)) { + return provider.getProvidedContent(file); + } + } + } + + return null; + } + + private static class LoggingListener implements VirtualFileListener { + public void propertyChanged(VirtualFilePropertyEvent event) { + LOG.debug( + "propertyChanged: file = " + event.getFile().getUrl() + + ", propertyName = " + event.getPropertyName() + + ", oldValue = " + event.getOldValue() + + ", newValue = " + event.getNewValue() + + ", requestor = " + event.getRequestor() + ); + } + + public void contentsChanged(VirtualFileEvent event) { + LOG.debug( + "contentsChanged: file = " + event.getFile().getUrl() + + ", requestor = " + event.getRequestor() + ); + } + + public void fileCreated(VirtualFileEvent event) { + LOG.debug( + "fileCreated: file = " + event.getFile().getUrl() + + ", requestor = " + event.getRequestor() + ); + } + + public void fileDeleted(VirtualFileEvent event) { + LOG.debug( + "fileDeleted: file = " + event.getFile().getName() + + ", parent = " + (event.getParent() != null ? event.getParent().getUrl() : null) + + ", requestor = " + event.getRequestor() + ); + } + + public void fileMoved(VirtualFileMoveEvent event) { + LOG.debug( + "fileMoved: file = " + event.getFile().getUrl() + + ", oldParent = " + event.getOldParent() + + ", newParent = " + event.getNewParent() + + ", requestor = " + event.getRequestor() + ); + } + + public void beforeContentsChange(VirtualFileEvent event) { + LOG.debug( + "beforeContentsChange: file = " + event.getFile().getUrl() + + ", requestor = " + event.getRequestor() + ); + } + + public void beforePropertyChange(VirtualFilePropertyEvent event) { + LOG.debug( + "beforePropertyChange: file = " + event.getFile().getUrl() + + ", propertyName = " + event.getPropertyName() + + ", oldValue = " + event.getOldValue() + + ", newValue = " + event.getNewValue() + + ", requestor = " + event.getRequestor() + ); + } + + public void beforeFileDeletion(VirtualFileEvent event) { + LOG.debug( + "beforeFileDeletion: file = " + event.getFile().getUrl() + + ", requestor = " + event.getRequestor() + ); + + LOG.assertTrue(event.getFile().isValid()); + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + LOG.debug( + "beforeFileMovement: file = " + event.getFile().getUrl() + + ", oldParent = " + event.getOldParent() + + ", newParent = " + event.getNewParent() + + ", requestor = " + event.getRequestor() + ); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java new file mode 100644 index 00000000000..be5bfdd8a99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java @@ -0,0 +1,247 @@ +package com.intellij.openapi.vfs.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.*; +import com.intellij.util.containers.ContainerUtil; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class VirtualFilePointerContainerImpl implements VirtualFilePointerContainer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer"); + private final ArrayList myList = new ArrayList(); + private final List myReadOnlyList = Collections.unmodifiableList(myList); + private final VirtualFilePointerFactory myVirtualFilePointerFactory; + private VirtualFile[] myCachedDirectories; + private static final String URL_ATTR = "url"; + + public void readExternal(final Element rootChild, final String childElements) throws InvalidDataException { + final List urls = rootChild.getChildren(childElements); + for (int i = 0; i < urls.size(); i++) { + Element pathElement = (Element)urls.get(i); + final String urlAttribute = pathElement.getAttributeValue(URL_ATTR); + if (urlAttribute == null) throw new InvalidDataException("path element without url"); + add(urlAttribute); + } + } + + public void writeExternal(final Element element, final String childElementName) { + for (int i = 0; i < getList().size(); i++) { + String url = ((VirtualFilePointer)getList().get(i)).getUrl(); + final Element rootPathElement = new Element(childElementName); + rootPathElement.setAttribute(URL_ATTR, url); + element.addContent(rootPathElement); + } + } + + public void moveUp(String url) { + int index = -1; + for (int i = 0; i < myList.size(); i++) { + final VirtualFilePointer pointer = myList.get(i); + if (url.equals(pointer.getUrl())) { + index = i; + break; + } + } + if (index <= 0) return; + dropCaches(); + ContainerUtil.swapElements(myList, index - 1, index); + } + + public void moveDown(String url) { + int index = -1; + for (int i = 0; i < myList.size(); i++) { + final VirtualFilePointer pointer = myList.get(i); + if (url.equals(pointer.getUrl())) { + index = i; + break; + } + } + if (index < 0 || index + 1 >= myList.size()) return; + dropCaches(); + ContainerUtil.swapElements(myList, index, index + 1); + } + + private class DefaultFactory implements VirtualFilePointerFactory { + private final VirtualFilePointerListener myListener; + private final VirtualFilePointerManager myVirtualFilePointerManager = VirtualFilePointerManager.getInstance(); + + public DefaultFactory(VirtualFilePointerListener listener) { + myListener = listener; + } + + public VirtualFilePointer create(VirtualFile file) { + return myVirtualFilePointerManager.create(file, myListener); + } + + public VirtualFilePointer create(String url) { + return myVirtualFilePointerManager.create(url, myListener); + } + + public VirtualFilePointer duplicate(VirtualFilePointer virtualFilePointer) { + return myVirtualFilePointerManager.duplicate(virtualFilePointer, myListener); + } + } + + public VirtualFilePointerContainerImpl() { + myVirtualFilePointerFactory = new DefaultFactory(null); + } + + public VirtualFilePointerContainerImpl(VirtualFilePointerListener listener) { + myVirtualFilePointerFactory = new DefaultFactory(listener); + } + + public VirtualFilePointerContainerImpl(VirtualFilePointerFactory factory) { + myVirtualFilePointerFactory = factory; + } + + public void killAll() { + final VirtualFilePointerManager virtualFilePointerManager = VirtualFilePointerManager.getInstance(); + for (Iterator iterator = myList.iterator(); iterator.hasNext();) { + final VirtualFilePointer virtualFilePointer = iterator.next(); + virtualFilePointerManager.kill(virtualFilePointer); + } + } + + + public void add(VirtualFile file) { + dropCaches(); + final VirtualFilePointer pointer = myVirtualFilePointerFactory.create(file); + myList.add(pointer); + } + + public void add(String url) { + dropCaches(); + final VirtualFilePointer pointer = myVirtualFilePointerFactory.create(url); + myList.add(pointer); + } + + public void remove(VirtualFilePointer pointer) { + dropCaches(); + final boolean result = myList.remove(pointer); + LOG.assertTrue(result); + } + + public List getList() { + return myReadOnlyList; + } + + public void addAll(VirtualFilePointerContainer that) { + dropCaches(); + + final ArrayList thatList = ((VirtualFilePointerContainerImpl)that).myList; + for (Iterator iterator = thatList.iterator(); iterator.hasNext();) { + final VirtualFilePointer virtualFilePointer = (VirtualFilePointer)iterator.next(); + myList.add(myVirtualFilePointerFactory.duplicate(virtualFilePointer)); + } + } + + + void dropCaches() { + myCachedDirectories = null; + myCachedFiles = null; + myCachedUrls = null; + } + + private String[] myCachedUrls; + public String[] getUrls() { + if (myCachedUrls == null) { + myCachedUrls = calcUrls(); + } + return myCachedUrls; + } + + private String[] calcUrls() { + final ArrayList result = new ArrayList(); + for (int i = 0; i < myList.size(); i++) { + VirtualFilePointer smartVirtualFilePointer = myList.get(i); + result.add(smartVirtualFilePointer.getUrl()); + } + return (String[]) result.toArray(new String[result.size()]); + } + + private VirtualFile[] myCachedFiles; + public VirtualFile[] getFiles() { + if (myCachedFiles == null) { + myCachedFiles = calcFiles(); + } + return myCachedFiles; + } + + private VirtualFile[] calcFiles() { + final ArrayList result = new ArrayList(); + for (int i = 0; i < myList.size(); i++) { + VirtualFilePointer smartVirtualFilePointer = myList.get(i); + final VirtualFile file = smartVirtualFilePointer.getFile(); + if (file != null) { + result.add(file); + } + } + return (VirtualFile[]) result.toArray(new VirtualFile[result.size()]); + } + + public VirtualFile[] getDirectories() { + if (myCachedDirectories == null) { + myCachedDirectories = calcDirectories(); + } + return myCachedDirectories; + } + + private VirtualFile[] calcDirectories() { + final ArrayList result = new ArrayList(); + for (int i = 0; i < myList.size(); i++) { + VirtualFilePointer smartVirtualFilePointer = myList.get(i); + final VirtualFile file = smartVirtualFilePointer.getFile(); + if (file != null && file.isDirectory()) { + LOG.assertTrue(file.isValid()); + result.add(file); + } + } + return (VirtualFile[]) result.toArray(new VirtualFile[result.size()]); + } + + public VirtualFilePointer findByUrl(String url) { + for (int i = 0; i < myList.size(); i++) { + VirtualFilePointer pointer = myList.get(i); + if (pointer.getUrl().equals(url)) return pointer; + } + return null; + } + + public void clear() { + dropCaches(); + myList.clear(); + } + + + public int size() { + return myList.size(); + } + + public Object get(int index) { + return myList.get(index); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof VirtualFilePointerContainerImpl)) return false; + + final VirtualFilePointerContainerImpl virtualFilePointerContainer = (VirtualFilePointerContainerImpl)o; + + if (myList != null ? !myList.equals(virtualFilePointerContainer.myList) : virtualFilePointerContainer.myList != null) return false; + + return true; + } + + public int hashCode() { + return (myList != null ? myList.hashCode() : 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java new file mode 100644 index 00000000000..8770aad2293 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java @@ -0,0 +1,156 @@ +package com.intellij.openapi.vfs.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; +import com.intellij.util.PathUtil; +import org.jdom.Element; + +public class VirtualFilePointerImpl extends UserDataHolderBase implements VirtualFilePointer { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.SmartVirtualFilePointerImpl"); + private String myUrl; // is null when myFile is not null + private VirtualFile myFile; + private VirtualFilePointerListener myListener; + private boolean myInitialized = false; + private boolean myWasRecentlyValid = false; + private boolean myIsDead = false; + private VirtualFileManager myVirtualFileManager; + + VirtualFilePointerImpl(VirtualFile file, VirtualFilePointerListener listener, VirtualFileManager virtualFileManager) { + LOG.assertTrue(file != null); + myFile = file; + myUrl = null; + myListener = listener; + myVirtualFileManager = virtualFileManager; + } + + VirtualFilePointerImpl(String url, VirtualFilePointerListener listener, VirtualFileManager virtualFileManager) { + LOG.assertTrue(url != null); + myFile = null; + myUrl = url; + myListener = listener; + myVirtualFileManager = virtualFileManager; + } + + VirtualFilePointerImpl(VirtualFilePointerImpl that, VirtualFilePointerListener listener, VirtualFileManager virtualFileManager) { + if (that.myFile != null) { + myFile = that.myFile; + myUrl = that.myUrl; + } else { + myFile = null; + myUrl = that.myUrl; + } + myListener = listener; + myVirtualFileManager = virtualFileManager; + } + + public String getFileName() { + LOG.assertTrue(!myIsDead); + if (!myInitialized) update(); + + if (myFile != null) { + return myFile.getName(); + } else { + int index = myUrl.lastIndexOf('/'); + return (index >= 0) ? myUrl.substring(index + 1) : myUrl; + } + } + + public VirtualFile getFile() { + LOG.assertTrue(!myIsDead); + if (!myInitialized) update(); + return myFile; + } + + public String getUrl() { + LOG.assertTrue(!myIsDead); + if (!myInitialized) update(); + if (myUrl != null) { + return myUrl; + } else { + return myFile.getUrl(); + } + } + + public String getPresentableUrl() { + LOG.assertTrue(!myIsDead); + if (!myInitialized) update(); + + return PathUtil.toPresentableUrl(getUrl()); + } + + public boolean isValid() { + LOG.assertTrue(!myIsDead); + if (!myInitialized) update(); + + return myFile != null; // && myFile.isValid(); + } + + public void update() { + myInitialized = true; + + if (!isValid()) { + LOG.assertTrue(myUrl != null); + myFile = myVirtualFileManager.findFileByUrl(myUrl); + if (myFile != null) { + myUrl = null; + } + } + + myWasRecentlyValid = isValid(); + } + + public void invalidateByDeletion() { + myInitialized = true; + LOG.assertTrue(myFile != null); + myUrl = myFile.getUrl(); + myFile = null; + myWasRecentlyValid = false; + } + + public boolean wasRecentlyValid() { + return myWasRecentlyValid; + } + + public VirtualFilePointerListener getListener() { + return myListener; + } + + void die() { + myIsDead = true; + } + + boolean isDead() { + return myIsDead; + } + + public void readExternal(Element element) throws InvalidDataException { + myUrl = element.getAttributeValue("url"); + myFile = null; + } + + public void writeExternal(Element element) throws WriteExternalException { + if (!myInitialized) update(); + + element.setAttribute("url", getUrl()); + } + + boolean willValidityChange() { + if (!myInitialized) update(); + + if (myWasRecentlyValid) { + LOG.assertTrue(myFile != null); + return !myFile.isValid(); + } + else { + LOG.assertTrue(myUrl != null); + final VirtualFile fileByUrl = myVirtualFileManager.findFileByUrl(myUrl); + return fileByUrl != null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java new file mode 100644 index 00000000000..d4c5b3636c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -0,0 +1,278 @@ +package com.intellij.openapi.vfs.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.openapi.vfs.ex.VirtualFileManagerListener; +import com.intellij.openapi.vfs.pointers.*; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.WeakHashMap; +import com.intellij.util.containers.WeakList; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements ApplicationComponent{ + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl"); + private WeakHashMap myPointers; + private WeakList myContainers; + private MyVirtualFileListener myVirtualFileListener; + private MyVirtualFileManagerListener myVirtualFileManagerListener; + private MyCommandListener myCommandListener; + + private boolean myInsideRefresh = false; + private boolean myInsideCommand = false; + private boolean myChangesDetected = false; + private VirtualFileManagerEx myVirtualFileManager; + + + VirtualFilePointerManagerImpl(VirtualFileManagerEx virtualFileManagerEx, + CommandProcessor commandProcessor) { + myPointers = new WeakHashMap(); + myContainers = new WeakList(); + myVirtualFileListener = new MyVirtualFileListener(); + myVirtualFileManagerListener = new MyVirtualFileManagerListener(); + myCommandListener = new MyCommandListener(); + + virtualFileManagerEx.addVirtualFileListener(myVirtualFileListener); + virtualFileManagerEx.addVirtualFileManagerListener(myVirtualFileManagerListener); + commandProcessor.addCommandListener(myCommandListener); + myVirtualFileManager = virtualFileManagerEx; + } + + public void cleanupForNextTest() { + myPointers = new WeakHashMap(); + myContainers = new WeakList(); + } + + public VirtualFilePointer create(String url, VirtualFilePointerListener listener) { + VirtualFilePointerImpl pointer = new VirtualFilePointerImpl(url, listener, myVirtualFileManager); + myPointers.put(pointer, null); + return pointer; + } + + public VirtualFilePointer create(VirtualFile file, VirtualFilePointerListener listener) { + VirtualFilePointerImpl pointer = new VirtualFilePointerImpl(file, listener, myVirtualFileManager); + myPointers.put(pointer, null); + return pointer; + } + + public VirtualFilePointer duplicate(VirtualFilePointer pointer, VirtualFilePointerListener listener) { + VirtualFilePointerImpl newPointer = new VirtualFilePointerImpl((VirtualFilePointerImpl)pointer, listener, myVirtualFileManager); + myPointers.put(newPointer, null); + return newPointer; + } + + public void kill(VirtualFilePointer pointer) { + if (pointer == null) return; + if (((VirtualFilePointerImpl)pointer).isDead()) return; + myPointers.remove(pointer); + ((VirtualFilePointerImpl)pointer).die(); + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public String getComponentName() { + return "SmartVirtualPointerManager"; + } + + private interface PointerProcessor { + void notifyListeners(VirtualFilePointerListener listener, VirtualFilePointer[] pointers); + /** + * @return true if event should be fired for this pointer. + */ + boolean processPointer(VirtualFilePointerImpl pointer); + } + + private HashMap> iteratePointers(PointerProcessor listenerNotifier) { + HashMap> listenerToArrayOfPointers = buildIterationMap(listenerNotifier); + iterateMap(listenerToArrayOfPointers, listenerNotifier); + return listenerToArrayOfPointers; + } + + private void iterateMap(HashMap> listenerToArrayOfPointers, PointerProcessor listenerCollector) { + Iterator keys = listenerToArrayOfPointers.keySet().iterator(); + while (keys.hasNext()) { + VirtualFilePointerListener listener = keys.next(); + ArrayList list = listenerToArrayOfPointers.get(listener); + final VirtualFilePointer[] pointers = (VirtualFilePointer[])list.toArray(new VirtualFilePointer[list.size()]); + listenerCollector.notifyListeners(listener, pointers); + } + } + + private HashMap> buildIterationMap(PointerProcessor listenerNotifier) { + Iterator iterator = myPointers.keySet().iterator(); + HashMap> listenerToArrayOfPointers = + new HashMap>(); + while (iterator.hasNext()) { + VirtualFilePointerImpl pointer = iterator.next(); + if (pointer != null) { + if (listenerNotifier.processPointer(pointer)) { + VirtualFilePointerListener listener = pointer.getListener(); + if (listener != null) { + ArrayList list = listenerToArrayOfPointers.get(listener); + if (list == null) { + list = new ArrayList(); + listenerToArrayOfPointers.put(listener, list); + } + list.add(pointer); + } + } + } + } + + return listenerToArrayOfPointers; + } + + private void validate() { + cleanContainerCaches(); + iteratePointers(PointerValidityChangeDetector.INSTANCE); + iteratePointers(PointerValidator.INSTANCE); + } + + private void cleanContainerCaches() { + for (Iterator iterator = myContainers.iterator(); iterator.hasNext();) { + VirtualFilePointerContainerImpl container = iterator.next(); + container.dropCaches(); + } + } + + private static class PointerValidator implements PointerProcessor { + private final static PointerValidator INSTANCE = new PointerValidator(); + public void notifyListeners(VirtualFilePointerListener listener, final VirtualFilePointer[] pointers) { + listener.validityChanged(pointers); + } + + public boolean processPointer(VirtualFilePointerImpl pointer) { + boolean wasValid = pointer.wasRecentlyValid(); + pointer.update(); + return pointer.wasRecentlyValid() != wasValid; + } + } + + private static class PointerValidityChangeDetector implements PointerProcessor { + private static final PointerValidityChangeDetector INSTANCE = new PointerValidityChangeDetector(); + public boolean processPointer(VirtualFilePointerImpl pointer) { + return pointer.willValidityChange(); + } + + public void notifyListeners(VirtualFilePointerListener listener, VirtualFilePointer[] pointers) { + listener.beforeValidityChanged(pointers); + } + } + + private class MyVirtualFileListener extends VirtualFileAdapter { + + public void propertyChanged(VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { + handleEvent(); + } + } + + public void fileCreated(VirtualFileEvent event) { + handleEvent(); + } + + public void fileMoved(VirtualFileMoveEvent event) { + handleEvent(); + } + + public void beforeFileDeletion(final VirtualFileEvent event) { + cleanContainerCaches(); + final List invalidatedPointers = new ArrayList(); + PointerProcessor listenerNotifier = new PointerProcessor() { + public boolean processPointer(VirtualFilePointerImpl pointer) { + final boolean invalidated = isInvalidatedByDeletion(pointer, event); + if (invalidated) { + invalidatedPointers.add(pointer); + } + return invalidated; + } + + public void notifyListeners(VirtualFilePointerListener listener, VirtualFilePointer[] pointers) { + listener.beforeValidityChanged(pointers); + } + }; + HashMap> fileDeletedNotificationMap = iteratePointers(listenerNotifier); + for (Iterator iterator = invalidatedPointers.iterator(); iterator.hasNext();) { + VirtualFilePointerImpl pointer = iterator.next(); + pointer.invalidateByDeletion(); + } + iterateMap(fileDeletedNotificationMap, PointerValidator.INSTANCE); + } + + private void handleEvent() { + if (!myInsideRefresh && !myInsideCommand) { + validate(); + } + else { + myChangesDetected = true; + } + } + } + + private static boolean isInvalidatedByDeletion(VirtualFilePointerImpl pointer, final VirtualFileEvent event) { + return pointer.isValid() && VfsUtil.isAncestor(event.getFile(), pointer.getFile(), false); + } + + public VirtualFilePointerContainer createContainer() { + final VirtualFilePointerContainerImpl virtualFilePointerContainer = new VirtualFilePointerContainerImpl(); + myContainers.add(virtualFilePointerContainer); + return virtualFilePointerContainer; + } + + public VirtualFilePointerContainer createContainer(VirtualFilePointerListener listener) { + final VirtualFilePointerContainerImpl virtualFilePointerContainer = new VirtualFilePointerContainerImpl(listener); + myContainers.add(virtualFilePointerContainer); + return virtualFilePointerContainer; + } + + public VirtualFilePointerContainer createContainer(VirtualFilePointerFactory factory) { + final VirtualFilePointerContainerImpl virtualFilePointerContainer = new VirtualFilePointerContainerImpl(factory); + myContainers.add(virtualFilePointerContainer); + return virtualFilePointerContainer; + } + + + private class MyVirtualFileManagerListener implements VirtualFileManagerListener { + public void beforeRefreshStart(boolean asynchonous) { + myInsideRefresh = true; + } + + public void afterRefreshFinish(boolean asynchonous) { + myInsideRefresh = false; + if (myChangesDetected && !myInsideCommand) { + myChangesDetected = false; + validate(); + } + } + } + + private class MyCommandListener extends CommandAdapter { + public void commandStarted(CommandEvent event){ + myInsideCommand = true; + } + + public void commandFinished(CommandEvent event){ + myInsideCommand = false; + if (myChangesDetected && !myInsideRefresh) { + myChangesDetected = false; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + validate(); + } + }); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java new file mode 100644 index 00000000000..54709b63cdf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -0,0 +1,285 @@ +package com.intellij.openapi.vfs.impl.jar; + +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.openapi.vfs.ex.jar.JarFileSystemEx; +import com.intellij.util.containers.HashMap; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.zip.ZipFile; + +public class JarFileSystemImpl extends JarFileSystemEx implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.jar.JarFileSystemImpl"); + + final Object LOCK = new Object(); + + private HashMap myPathToFileInfoMap = new HashMap(); + private HashSet myNoCopyJarPaths = new HashSet(); + private HashSet myContentChangingJars = new HashSet(); + + private VirtualFileManagerEx myManager; + + public JarFileSystemImpl(LocalFileSystem localFileSystem) { + + localFileSystem.addVirtualFileListener( + new VirtualFileAdapter() { + public void contentsChanged(VirtualFileEvent event) { + JarFileInfo info = myPathToFileInfoMap.get(event.getFile().getPath()); + if (info != null) { + refreshInfo(info, true); + } + } + + public void fileDeleted(VirtualFileEvent event) { + VirtualFile parent = event.getParent(); + if (parent != null) { + String oldPath = parent.getPath() + '/' + event.getFileName(); + JarFileInfo info = myPathToFileInfoMap.get(oldPath); + if (info != null) { + refreshInfo(info, true); + } + } + } + + public void fileMoved(VirtualFileMoveEvent event) { + //TODO: real move + String oldPath = event.getOldParent().getPath() + '/' + event.getFileName(); + JarFileInfo info = myPathToFileInfoMap.get(oldPath); + if (info != null) { + refreshInfo(info, true); + } + } + + public void propertyChanged(VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { + //TODO: real rename + VirtualFile parent = event.getParent(); + String oldPath = (parent == null ? "" : parent.getPath() + '/') + event.getOldValue(); + JarFileInfo info = myPathToFileInfoMap.get(oldPath); + if (info != null) { + refreshInfo(info, true); + } + } + } + } + ); + } + + public String getComponentName() { + return "JarFileSystem"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public void setNoCopyJarForPath(String pathInJar) { + int index = pathInJar.indexOf(JAR_SEPARATOR); + if (index < 0) return; + String path = pathInJar.substring(0, index); + path = path.replace('/', File.separatorChar); + if (!SystemInfo.isFileSystemCaseSensitive) { + path = path.toLowerCase(); + } + myNoCopyJarPaths.add(path); + } + + boolean isValid(JarFileInfo info) { + synchronized (LOCK) { + String path = info.getFile().getPath(); + JarFileInfo info1 = myPathToFileInfoMap.get(path); + return info1 == info; + } + } + + public VirtualFile getVirtualFileForJar(VirtualFile entryVFile) { + String rootPath = ((VirtualFileImpl)entryVFile).getFileInfo().getRootPath(); + LOG.assertTrue(rootPath.endsWith(JAR_SEPARATOR)); + return LocalFileSystem.getInstance().findFileByPath(rootPath.substring(0, rootPath.length() - JAR_SEPARATOR.length())); + } + + public ZipFile getJarFile(VirtualFile entryVFile) throws IOException { + synchronized (LOCK) { + return ((VirtualFileImpl)entryVFile).getFileInfo().getZipFile(); + } + } + + public String getProtocol() { + return PROTOCOL; + } + + public VirtualFile findFileByPath(String path) { + int index = path.lastIndexOf(JAR_SEPARATOR); + if (index < 0) return null; + String jarPath = path.substring(0, index); + String relPath = path.substring(index + JAR_SEPARATOR.length()); + + synchronized (LOCK) { + JarFileInfo info = myPathToFileInfoMap.get(jarPath); + if (info == null) { + if (myContentChangingJars.contains(jarPath)) return null; + File file = new File(jarPath); + try { + jarPath = file.getCanonicalPath(); + } + catch (IOException e) { + LOG.info("Could not fetch canonical path for " + jarPath); + return null; + } + + if (jarPath == null) { + LOG.info("Canonical path is null for " + file.getPath()); + return null; + } + + file = new File(jarPath); + info = myPathToFileInfoMap.get(jarPath); + if (info != null) { + return info.findFile(relPath); + } + + if (myContentChangingJars.contains(jarPath)) return null; + + if (!file.exists()) { + LOG.info("Jar file " + file.getPath() + " not found"); + return null; + } + + File mirrorFile = getMirrorFile(file); + info = new JarFileInfo(this, file, mirrorFile); + + myPathToFileInfoMap.put(jarPath, info); + } + + return info.findFile(relPath); + } + } + + public String extractPresentableUrl(String path) { + if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { + path = path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()); + } + path = super.extractPresentableUrl(path); + return path; + } + + public void refresh(boolean asynchronous) { + JarFileInfo[] infos; + synchronized (LOCK) { + infos = myPathToFileInfoMap.values().toArray(new JarFileInfo[myPathToFileInfoMap.size()]); + } + + for (int i = 0; i < infos.length; i++) { + refreshInfo(infos[i], asynchronous); + } + } + + private void refreshInfo(final JarFileInfo info, boolean asynchronous) { + ModalityState modalityState = EventQueue.isDispatchThread() ? ModalityState.current() : ModalityState.NON_MMODAL; + + getManager().beforeRefreshStart(asynchronous, modalityState, null); + + if (!info.getFile().exists()) { + LOG.info("file deleted"); + + final VirtualFile rootFile = info.getRootFile(); + getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + fireBeforeFileDeletion(null, rootFile); + synchronized (LOCK) { + myPathToFileInfoMap.remove(info.getFile().getPath()); + } + info.close(); + fireFileDeleted(null, rootFile, rootFile.getName(), true, null); + } + }, + asynchronous, + modalityState + ); + } + else if (info.getTimeStamp() != info.getFile().lastModified()) { + LOG.info("timestamp changed"); + + final VirtualFile rootFile = info.getRootFile(); + getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (!rootFile.isValid()) return; + fireBeforeFileDeletion(null, rootFile); + final String path = info.getFile().getPath(); + synchronized (LOCK) { + myPathToFileInfoMap.remove(path); + myContentChangingJars.add(path); + } + info.close(); + fireFileDeleted(null, rootFile, rootFile.getName(), true, null); + synchronized (LOCK) { + myContentChangingJars.remove(path); + } + fireFileCreated(null, findFileByPath(path + JAR_SEPARATOR)); + } + }, + asynchronous, + modalityState + ); + } + + getManager().afterRefreshFinish(asynchronous, modalityState); + } + + public VirtualFile refreshAndFindFileByPath(String path) { + return findFileByPath(path); + } + + public File getMirrorFile(File originalFile) { + if (!isMakeCopyOfJar(originalFile)) return originalFile; + + String folderPath = PathManager.getSystemPath() + File.separatorChar + "jars"; + if (!new File(folderPath).exists()) { + if (!new File(folderPath).mkdirs()) { + return originalFile; + } + } + + String fileName = originalFile.getName() + "." + Integer.toHexString(originalFile.getPath().hashCode()); + return new File(folderPath, fileName); + } + + private boolean isMakeCopyOfJar(File originalJar) { + String property = System.getProperty("idea.jars.nocopy"); + if ("true".equalsIgnoreCase(property)) return false; + + String path = originalJar.getPath(); + if (!SystemInfo.isFileSystemCaseSensitive) { + path = path.toLowerCase(); + } + if (myNoCopyJarPaths.contains(path)) return false; + + String name = originalJar.getName(); + if (name.equalsIgnoreCase("idea.jar")) { + if (originalJar.getParent().equalsIgnoreCase(PathManager.getLibPath())) { + return false; + } + } + + return true; + } + + public VirtualFileManagerEx getManager() { + if (myManager == null) { + myManager = (VirtualFileManagerEx)VirtualFileManagerEx.getInstance(); + } + return myManager; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java new file mode 100644 index 00000000000..1ea1066a11f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -0,0 +1,682 @@ +package com.intellij.openapi.vfs.impl.local; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; +import com.intellij.util.Alarm; +import com.intellij.util.concurrency.WorkerThread; +import com.intellij.util.containers.WeakHashMap; +import com.intellij.vfs.local.win32.FileWatcher; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class LocalFileSystemImpl extends LocalFileSystem implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl"); + private VirtualFileManagerEx myManager = null; + + final Object LOCK = new Object(); + + private final ArrayList myRoots = new ArrayList(); + + private ArrayList myFilesToWatchManual = new ArrayList(); + private final HashSet myDirtyFiles = new HashSet(); // dirty files when FileWatcher is available + private final HashSet myDeletedFiles = new HashSet(); + + private Alarm mySynchronizeQueueAlarm; + + private File[] myCachedRoots; + + private final Map myRefreshStatusMap = new WeakHashMap(); // VirtualFile --> 'status' + private static final Object DIRTY_STATUS = Key.create("DIRTY_STATUS"); + private static final Object DELETED_STATUS = Key.create("DELETED_STATUS"); + + private WatchForChangesThread myWatchForChangesThread; + + public LocalFileSystemImpl() { + myCachedRoots = File.listRoots(); + + mySynchronizeQueueAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD){ + public void addRequest(Runnable request, int delay) { + LOG.info("adding request to synchronize queue:" + request); + super.addRequest(request, delay); + } + }; + + if (FileWatcher.isAvailable()) { + FileWatcher.initialize(); + myWatchForChangesThread = new WatchForChangesThread(); + myWatchForChangesThread.start(); + new StoreRefreshStatusThread().start(); + } + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public void cleanupForNextTest() { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + refresh(false); + } + } + ); + + myRoots.clear(); + myDirtyFiles.clear(); + myDeletedFiles.clear(); + } + + final VirtualFileManagerEx getManager() { + if (myManager == null) { + myManager = (VirtualFileManagerEx)VirtualFileManagerEx.getInstance(); + } + + return myManager; + } + + private void updateFileWatcher() { + if (FileWatcher.isAvailable()) { + FileWatcher.interrupt(); + } + } + + boolean isRoot(VirtualFileImpl file) { + synchronized (LOCK) { + return myRoots.contains(file); + } + } + + private boolean isPhysicalRoot(String path) { + path = path.replace('/', File.separatorChar); + for (int i = 0; i < myCachedRoots.length; i++) { + File root = myCachedRoots[i]; + String rootPath = root.getPath(); + if (equal(path, rootPath)) { + return true; + } + } + return false; + } + + public String getProtocol() { + return PROTOCOL; + } + + public VirtualFile findFileByPath(String path) { + if (File.separatorChar == '\\') { + if (path.indexOf('\\') >= 0) return null; + } + + VirtualFile file = _findFileByPath(path); + if (file == null){ + String canonicalPath = getCanonicalPath(new File(path.replace('/', File.separatorChar))); + if (canonicalPath == null) return null; + String path1 = canonicalPath.replace(File.separatorChar, '/'); + if (!path.equals(path1)){ + return _findFileByPath(path1); + } + } + return file; + } + + public VirtualFile _findFileByPath(String path) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + return findFileByPath(path, true); + } + + private VirtualFile findFileByPath(String path, boolean createIfNoCache) { + if (SystemInfo.isWindows || SystemInfo.isOS2) { + if (path.endsWith(":/")) { // instead of getting canonical path - see below + path = Character.toUpperCase(path.charAt(0)) + path.substring(1); + } + } + + synchronized (LOCK) { + for (int i = 0; i < myRoots.size(); i++) { + VirtualFile root = myRoots.get(i); + String rootPath = root.getPath(); + if (!startsWith(path, rootPath)) continue; + if (path.length() == rootPath.length()) return root; + String tail; + if (path.charAt(rootPath.length()) == '/') { + tail = path.substring(rootPath.length() + 1); + } + else if (StringUtil.endsWithChar(rootPath, '/')) { + tail = path.substring(rootPath.length()); + } + else { + continue; + } + StringTokenizer tokenizer = new StringTokenizer(tail, "/"); + while (tokenizer.hasMoreTokens()) { + final String name = tokenizer.nextToken(); + if (".".equals(name)) continue; + if ("..".equals(name)) { + root = root.getParent(); + } + else { + if (!createIfNoCache && !((VirtualFileImpl)root).areChildrenCached()) return null; + if (!root.isDirectory()) return null; + root = root.findChild(name); + } + if (root == null) return null; + } + return root; + } + + boolean isPhysicalRoot = isPhysicalRoot(path); + File file = new File(path.replace('/', File.separatorChar)); + boolean exists; + if (!isPhysicalRoot) { + exists = file.exists(); + } + else { + exists = true; // not used + } + if (!isPhysicalRoot && exists) { // getting canonicalPath is very slow for some network drives + String newPath = getCanonicalPath(file); + if (newPath == null) return null; + newPath = newPath.replace(File.separatorChar, '/'); + if (!path.equals(newPath)) return findFileByPath(newPath, createIfNoCache); + } + + if (!createIfNoCache) return null; + if (!isPhysicalRoot && !exists) return null; + + VirtualFileImpl newRoot = new VirtualFileImpl(this, path); + for (int i = 0; i < myRoots.size(); i++) { + VirtualFile root = myRoots.get(i); + String rootPath = root.getPath(); + if (!startsWith(rootPath, path)) continue; + if (rootPath.length() == path.length()) return root; + String tail; + if (rootPath.charAt(path.length()) == '/') { + tail = rootPath.substring(path.length() + 1); + } + else if (StringUtil.endsWithChar(path, '/')) { + tail = rootPath.substring(path.length()); + } + else { + continue; + } + StringTokenizer tokenizer = new StringTokenizer(tail, "/"); + VirtualFileImpl vFile = newRoot; + while (tokenizer.hasMoreTokens()) { + String name = tokenizer.nextToken(); + VirtualFile child = vFile.findChild(name); + if (child == null) break; + if (!tokenizer.hasMoreTokens()) { + vFile.replaceChild((VirtualFileImpl)child, (VirtualFileImpl)root); + ((VirtualFileImpl)root).setParent(vFile); + myRoots.remove(i); + i--; + } + vFile = (VirtualFileImpl)child; + } + } + myRoots.add(newRoot); + updateFileWatcher(); + return newRoot; + } + } + + public VirtualFile refreshAndFindFileByPath(String path) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + + VirtualFile file = findFileByPath(path); + if (file != null) return file; + + if (!new File(path.replace('/', File.separatorChar)).exists()) return null; + + String parentPath = getParentPath(path); + if (parentPath == null) return null; + VirtualFile parent = refreshAndFindFileByPath(parentPath); + if (parent == null) return null; + + if (FileWatcher.isAvailable()) { + synchronized (myRefreshStatusMap) { // changes might not be processed yet + if (myRefreshStatusMap.get(parent) == null) { + myRefreshStatusMap.put(parent, DIRTY_STATUS); + } + } + } + parent.refresh(false, false); + + file = findFileByPath(path); + return file; + } + + private static String getParentPath(String path) { + int index = path.lastIndexOf('/'); + if (index < 0) return null; + if (index == path.length() - 1) return null; // "c:/" or "/" + path = path.substring(0, index); + if (path.indexOf('/') < 0) { + path += "/"; // "c:/" or "/" + } + return path; + } + + public VirtualFile findFileByIoFile(File file) { + String path = getCanonicalPath(file); + if (path == null) return null; + path = path.replace(File.separatorChar, '/'); + return findFileByPath(path); + } + + public VirtualFile refreshAndFindFileByIoFile(File file) { + String path = getCanonicalPath(file); + if (path == null) return null; + path = path.replace(File.separatorChar, '/'); + return refreshAndFindFileByPath(path); + } + + public String extractPresentableUrl(String path) { + String url = super.extractPresentableUrl(path); + /* + if (SystemInfo.isWindows || SystemInfo.isOS2){ + if (url.endsWith(":")){ + url += File.separatorChar; + } + } + */ + return url; + } + + public void refresh(final boolean asynchronous) { + if (asynchronous) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + else { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + } + + final ModalityState modalityState = EventQueue.isDispatchThread() ? ModalityState.current() : ModalityState.NON_MMODAL; + + final WorkerThread worker; + if (asynchronous) { + worker = new WorkerThread("Synchronize worker"); + } + else { + worker = null; + } + + final Runnable endTask = new Runnable() { + public void run() { + ProgressIndicator indicator = getManager().getRefreshIndicator(); + if (indicator != null) { + indicator.stop(); + } + + getManager().afterRefreshFinish(asynchronous, modalityState); + } + }; + + final Runnable runnable = new Runnable() { + public void run() { + getManager().beforeRefreshStart(asynchronous, modalityState, null); + + final ProgressIndicator indicator = getManager().getRefreshIndicator(); + if (indicator != null) { + indicator.start(); + indicator.setText("Synchronizing files..."); + } + + storeRefreshStatusToFiles(); + + myCachedRoots = File.listRoots(); + + VirtualFileImpl[] roots; + synchronized (LOCK) { + roots = myRoots.toArray(new VirtualFileImpl[myRoots.size()]); + } + + for (int i = 0; i < roots.length; i++) { + final VirtualFileImpl rootFile = roots[i]; + PhysicalFile file = rootFile.getPhysicalFile(); + if (!file.exists()) { + final Runnable action = new Runnable() { + public void run() { + if (!rootFile.isValid()) return; + boolean isDirectory = rootFile.isDirectory(); + fireBeforeFileDeletion(null, rootFile); + synchronized (LOCK) { + myRoots.remove(rootFile); + updateFileWatcher(); + } + fireFileDeleted(null, rootFile, rootFile.getName(), isDirectory, null); + } + }; + getManager().addEventToFireByRefresh(action, asynchronous, modalityState); + } + else { + refresh(rootFile, true, false, worker, modalityState); + } + } + } + }; + + if (asynchronous) { + Runnable runnable1 = new Runnable() { + public void run() { + LOG.info("Executing request:" + this); + + worker.start(); + ApplicationManager.getApplication().runReadAction(runnable); + worker.dispose(false); + try { + worker.join(); + } + catch (InterruptedException e) { + } + endTask.run(); + } + }; + getSynchronizeQueueAlarm().addRequest(runnable1, 0); + } + else { + runnable.run(); + endTask.run(); + } + } + + Alarm getSynchronizeQueueAlarm() { + return mySynchronizeQueueAlarm; + } + + void refresh(VirtualFile file, boolean recursive, boolean storeStatus, WorkerThread worker, ModalityState modalityState) { + if (!FileWatcher.isAvailable()) { + ((VirtualFileImpl)file).refreshInternal(recursive, worker, modalityState); + } + else { + synchronized (LOCK) { + for (int i = 0; i < myFilesToWatchManual.size(); i++) { + VirtualFile fileToWatch = myFilesToWatchManual.get(i); + if (VfsUtil.isAncestor(fileToWatch, file, false)) { + ((VirtualFileImpl)file).refreshInternal(recursive, worker, modalityState); + return; + } + } + } + + if (storeStatus) { + storeRefreshStatusToFiles(); + } + + Object status; + synchronized (myRefreshStatusMap) { + status = myRefreshStatusMap.remove(file); + } + if (status == DELETED_STATUS) { + if (((VirtualFileImpl)file).getPhysicalFile().exists()) { // file was deleted but later restored - need to rescan the whole subtree + ((VirtualFileImpl)file).refreshInternal(true, worker, modalityState); + } + } + else { + if (status == DIRTY_STATUS) { + ((VirtualFileImpl)file).refreshInternal(false, worker, modalityState); + } + if (recursive && ((VirtualFileImpl)file).areChildrenCached()) { + VirtualFile[] children = file.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (status == DIRTY_STATUS && !((VirtualFileImpl)child).getPhysicalFile().exists()) continue; // should be already handled above (see SCR6145) + refresh(child, recursive, false, worker, modalityState); + } + } + } + } + } + + private void storeRefreshStatusToFiles() { + if (FileWatcher.isAvailable()) { + final String[] dirtyFiles; + synchronized (myDirtyFiles) { + dirtyFiles = myDirtyFiles.toArray(new String[myDirtyFiles.size()]); + myDirtyFiles.clear(); + } + Runnable action = new Runnable() { + public void run() { + for (int i = 0; i < dirtyFiles.length; i++) { + String path = dirtyFiles[i]; + path = path.replace(File.separatorChar, '/'); + VirtualFile file = findFileByPath(path, false); + if (file != null) { + synchronized (myRefreshStatusMap) { + if (myRefreshStatusMap.get(file) == null) { + myRefreshStatusMap.put(file, DIRTY_STATUS); + } + } + } + } + } + }; + ApplicationManager.getApplication().runReadAction(action); + + final String[] deletedFiles; + synchronized (myDeletedFiles) { + deletedFiles = myDeletedFiles.toArray(new String[myDeletedFiles.size()]); + myDeletedFiles.clear(); + } + Runnable action1 = new Runnable() { + public void run() { + for (int i = 0; i < deletedFiles.length; i++) { + String path = deletedFiles[i]; + path = path.replace(File.separatorChar, '/'); + VirtualFile file = findFileByPath(path, false); + if (file != null) { + synchronized (myRefreshStatusMap) { + myRefreshStatusMap.put(file, DELETED_STATUS); + } + // when moving file in Explorer FILE_MODIFIED is not fired for the parent... + VirtualFile parent = file.getParent(); + if (parent != null) { + synchronized (myRefreshStatusMap) { + if (myRefreshStatusMap.get(parent) == null) { + myRefreshStatusMap.put(parent, DIRTY_STATUS); + } + } + } + } + } + } + }; + ApplicationManager.getApplication().runReadAction(action1); + } + } + + protected void fireContentsChanged(Object requestor, VirtualFile file, long oldModificationStamp) { + super.fireContentsChanged(requestor, file, oldModificationStamp); + } + + protected void fireFileCreated(Object requestor, VirtualFile file) { + super.fireFileCreated(requestor, file); + } + + protected void fireFileDeleted(Object requestor, + VirtualFile file, + String fileName, + boolean isDirectory, + VirtualFile parent) { + super.fireFileDeleted(requestor, file, fileName, isDirectory, parent); + } + + protected void fireFileMoved(Object requestor, VirtualFile file, VirtualFile oldParent) { + super.fireFileMoved(requestor, file, oldParent); + } + + protected void fireBeforePropertyChange(Object requestor, + VirtualFile file, + String propertyName, + Object oldValue, + Object newValue) { + super.fireBeforePropertyChange(requestor, file, propertyName, oldValue, newValue); + } + + protected void firePropertyChanged(Object requestor, + VirtualFile file, + String propertyName, + Object oldValue, + Object newValue) { + super.firePropertyChanged(requestor, file, propertyName, oldValue, newValue); + } + + protected void fireBeforeContentsChange(Object requestor, VirtualFile file) { + super.fireBeforeContentsChange(requestor, file); + } + + protected void fireBeforeFileDeletion(Object requestor, VirtualFile file) { + super.fireBeforeFileDeletion(requestor, file); + } + + protected void fireBeforeFileMovement(Object requestor, VirtualFile file, VirtualFile newParent) { + super.fireBeforeFileMovement(requestor, file, newParent); + } + + private static boolean equal(String path1, String path2) { + if (SystemInfo.isFileSystemCaseSensitive) { + return path1.equals(path2); + } + else { + return path1.equalsIgnoreCase(path2); + } + } + + private static boolean startsWith(String path1, String path2) { + if (!SystemInfo.isFileSystemCaseSensitive) { + path1 = path1.toLowerCase(); + path2 = path2.toLowerCase(); + } + return path1.startsWith(path2); + } + + private String getCanonicalPath(File file) { + if (SystemInfo.isFileSystemCaseSensitive) { + return file.getAbsolutePath(); // fixes problem with symlinks under Unix (however does not under Windows!) + } + else { + try { + return file.getCanonicalPath(); + } + catch (IOException e) { + return null; + } + } + } + + private class WatchForChangesThread extends Thread { + public WatchForChangesThread() { + super("WatchForChangesThread"); + } + + public void run() { + updateFileWatcher(); + while (true) { + FileWatcher.ChangeInfo[] infos = FileWatcher.waitForChange(); + + if (infos == null) { + ApplicationManager.getApplication().runReadAction( + new Runnable() { + public void run() { + synchronized (LOCK) { + String[] dirPaths = new String[myRoots.size()]; + for (int i = 0; i < myRoots.size(); i++) { + VirtualFile root = myRoots.get(i); + dirPaths[i] = root.getPath(); + } + + final Vector watchManual = new Vector(); + + int numDir = FileWatcher.setup(dirPaths, true, watchManual); + if (numDir == 0) { + try { + FileWatcher.setup(new String[]{FileUtil.getTempDirectory()}, true, new Vector()); + } + catch (IOException e) { + LOG.error(e); + } + } + + myFilesToWatchManual.clear(); + for (int i = 0; i < watchManual.size(); i++) { + String path = watchManual.elementAt(i); + path = path.replace(File.separatorChar, '/'); + VirtualFile file = findFileByPath(path); + if (file != null) { + myFilesToWatchManual.add(file); + } + } + } + } + } + ); + } else { + for (int i = 0; i < infos.length; i++) { + FileWatcher.ChangeInfo info = infos[i]; + String path = info.getFilePath(); + int changeType = info.getChangeType(); + if (changeType == FileWatcher.FILE_MODIFIED) { + synchronized (myDirtyFiles) { + myDirtyFiles.add(path); + } + } + else if (changeType == FileWatcher.FILE_ADDED) { + synchronized (myDirtyFiles) { + String parent = new File(path).getParent(); + if (parent != null) { + myDirtyFiles.add(parent); + } + } + } + else if (changeType == FileWatcher.FILE_REMOVED || changeType == FileWatcher.FILE_RENAMED_OLD_NAME) { + synchronized (myDeletedFiles) { + myDeletedFiles.add(path); + } + } + } + } + } + } + } + + private class StoreRefreshStatusThread extends Thread { + private static final long PERIOD = 1000; + + public StoreRefreshStatusThread() { + super("StoreRefreshStatusThread"); + setPriority(MIN_PRIORITY); + } + + public void run() { + while (true) { + storeRefreshStatusToFiles(); + try { + sleep(PERIOD); + } + catch (InterruptedException e) { + } + } + } + } + + public String getComponentName() { + return "LocalFileSystem"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileImpl.java new file mode 100644 index 00000000000..386b3d8852a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileImpl.java @@ -0,0 +1,838 @@ +package com.intellij.openapi.vfs.impl.local; + +import com.intellij.Patches; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.openapi.vfs.ex.ProvidedContent; +import com.intellij.util.LocalTimeCounter; +import com.intellij.util.concurrency.WorkerThread; + +import java.awt.*; +import java.io.*; +import java.util.ArrayList; + +public class VirtualFileImpl extends VirtualFile { + + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.local.VirtualFileImpl"); + + private final LocalFileSystemImpl myFileSystem; + + private VirtualFileImpl myParent; + private String myParentPath; // filled when myParent == null + private String myName; +// private String myExtension; // cached +// private String myNameWithoutExtension; // cached + private VirtualFileImpl[] myChildren = null; + private boolean myDirectoryFlag; // null, if not defined yet + private Boolean myWritableFlag = null; // null, if not defined yet + private long myModificationStamp = LocalTimeCounter.currentTime(); + private long myTimeStamp = -1; // -1, if file content has not been requested yet + + private static final VirtualFileImpl[] EMPTY_VIRTUAL_FILE_ARRAY = new VirtualFileImpl[0]; + + // used by tests + public void setTimeStamp(long timeStamp) { + myTimeStamp = timeStamp; + } + + private VirtualFileImpl( + LocalFileSystemImpl fileSystem, + VirtualFileImpl parent, + PhysicalFile file, + boolean isDirectory + ) { + myFileSystem = fileSystem; + myParent = parent; + setName(file.getName()); + if (myName.length() == 0){ + LOG.error("file:" + file.getPath()); + } + myDirectoryFlag = isDirectory; + if (!myDirectoryFlag) { + myTimeStamp = file.lastModified(); + } + } + + VirtualFileImpl(LocalFileSystemImpl fileSystem, String path) { + myFileSystem = fileSystem; + + int lastSlash = path.lastIndexOf('/'); + LOG.assertTrue(lastSlash >= 0); + if (lastSlash == path.length() - 1) { // 'c:/' or '/' + myParentPath = null; + setName(path); + myDirectoryFlag = true; + } + else { + int prevSlash = path.lastIndexOf('/', lastSlash - 1); + if (prevSlash < 0) { + myParentPath = path.substring(0, lastSlash + 1); // 'c:/' or '/' + setName(path.substring(lastSlash + 1)); + } + else { + myParentPath = path.substring(0, lastSlash); + setName(path.substring(lastSlash + 1)); + } + myDirectoryFlag = getPhysicalFile().isDirectory(); + } + LOG.assertTrue(myName.length() > 0); + } + + boolean areChildrenCached() { + synchronized (myFileSystem.LOCK) { + return myChildren != null; + } + } + + void setParent(VirtualFileImpl parent) { + synchronized (myFileSystem.LOCK) { + myParent = parent; + myParentPath = null; + } + } + + PhysicalFile getPhysicalFile() { + String path = getPath(File.separatorChar); + return new IoFile(path); + } + + public VirtualFileSystem getFileSystem() { + return myFileSystem; + } + + public String getPath() { + return getPath('/'); + } + + private String getPath(char separatorChar) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + int length = calcPathLength(false); + StringBuffer buffer = new StringBuffer(length); + appendPath(buffer, separatorChar); + if (buffer.length() != length){ + LOG.error("buffer.length() != length", + new String [] { + "length=" + length, + "buffer=" + buffer.toString() + }); + } + return buffer.toString(); + } + + private int calcPathLength(boolean addSepAfter) { + int length = 0; + synchronized (myFileSystem.LOCK) { + if (myParent != null) { + length += myParent.calcPathLength(true); + } + else { + if (myParentPath != null) { + length += myParentPath.length(); + if (!StringUtil.endsWithChar(myParentPath, '/')) { + length++; + } + } + } + } + length += myName.length(); + if (addSepAfter && !StringUtil.endsWithChar(myName, '/')) { + length++; + } + return length; + } + + private void appendPath(StringBuffer buffer, char separatorChar) { + synchronized (myFileSystem.LOCK) { + if (myParent == null) { + if (myParentPath != null) { + buffer.append(myParentPath.replace('/', separatorChar)); + } + } + else { + myParent.appendPath(buffer, separatorChar); + } + } + + if (buffer.length() != 0 && buffer.charAt(buffer.length() - 1) != separatorChar) { + buffer.append(separatorChar); + } + + buffer.append(myName.replace('/', separatorChar)); + } + + public String getName() { + return myName; + } + + public String getPresentableName() { + if (UISettings.getInstance().HIDE_KNOWN_EXTENSION_IN_TABS) { + final String nameWithoutExtension = getNameWithoutExtension(); + return (nameWithoutExtension.length () == 0 ? getName() : nameWithoutExtension); + } + return getName(); + } + + public void rename(Object requestor, String newName) throws IOException { + if (getParent() == null) { + return; + } + if (myName.equals(newName)) { + return; + } + + if (isInvalidName(newName)){ + throw new IOException("Invalid file name: \"" + newName + "\""); + } + + myFileSystem.fireBeforePropertyChange(requestor, this, PROP_NAME, myName, newName); + PhysicalFile file = getPhysicalFile(); + String oldName = myName; + setName(newName); + PhysicalFile newFile = getPhysicalFile(); + if (!file.renameTo(newFile)) { + setName(file.getName()); + throw new IOException("Cannot rename file " + file.getPath() + " to " + newFile.getPath() + "."); + } + else { + myFileSystem.firePropertyChanged(requestor, this, PROP_NAME, oldName, myName); + } + } + + public boolean isWritable() { + synchronized (myFileSystem.LOCK) { + if (myWritableFlag == null) { + myWritableFlag = isWritable(getPhysicalFile(), isDirectory()) ? Boolean.TRUE : Boolean.FALSE; + } + } + return myWritableFlag.booleanValue(); + } + + private static boolean isWritable(PhysicalFile physicalFile, boolean isDirectory) { + if (Patches.ALL_FOLDERS_ARE_WRITABLE && isDirectory) { + return true; + } + else { + return physicalFile.canWrite(); + } + } + + public boolean isDirectory() { + return myDirectoryFlag; + } + + public boolean isValid() { + synchronized (myFileSystem.LOCK) { + if (myParent != null) { + return myParent.isValid(); + } + else { + return myFileSystem.isRoot(this); + } + } + } + + public VirtualFile getParent() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + synchronized (myFileSystem.LOCK) { + if (myParent != null) { + return myParent; + } + else { + if (myParentPath == null) return null; + return myFileSystem.findFileByPath(myParentPath); + } + } + } + + public VirtualFile[] getChildren() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + if (!isDirectory()) return null; + synchronized (myFileSystem.LOCK) { + if (myChildren == null) { + ArrayList array = new ArrayList(); + PhysicalFile file = getPhysicalFile(); + PhysicalFile[] files = file.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + PhysicalFile f = files[i]; + array.add(new VirtualFileImpl(myFileSystem, this, f, f.isDirectory())); + } + } + myChildren = array.toArray(EMPTY_VIRTUAL_FILE_ARRAY); + } + } + return myChildren; + } + + void replaceChild(VirtualFileImpl oldChild, VirtualFileImpl newChild) { + for (int i = 0; i < myChildren.length; i++) { + VirtualFileImpl child = myChildren[i]; + if (child == oldChild) { + myChildren[i] = newChild; + return; + } + } + } + + public VirtualFile createChildDirectory(Object requestor, String name) throws IOException { + if (!isDirectory()) { + throw new IOException(); + } + + if (isInvalidName(name)){ + throw new IOException("Invalid file name: \"" + name + "\""); + } + + PhysicalFile physicalFile = getPhysicalFile().createChild(name); + VirtualFile file = findChild(name); + if (file != null || physicalFile.exists()) { + throw new IOException("Cannot create file " + physicalFile.getPath() + ". File already exists."); + } + if (!physicalFile.mkdir()) { + throw new IOException("Cannot create file " + physicalFile.getPath() + "."); + } + VirtualFileImpl child = new VirtualFileImpl(myFileSystem, this, physicalFile, true); + addChild(child); + myFileSystem.fireFileCreated(requestor, child); + return child; + } + + public VirtualFile createChildData(Object requestor, String name) throws IOException { + if (!isDirectory()) { + throw new IOException(); + } + + if (isInvalidName(name)){ + throw new IOException("Invalid file name: \"" + name + "\""); + } + + PhysicalFile physicalFile = getPhysicalFile().createChild(name); + VirtualFile file = findChild(name); + if (file != null || physicalFile.exists()) { + throw new IOException("Cannot create file " + physicalFile.getPath() + ". File already exists."); + } + physicalFile.createOutputStream().close(); + VirtualFileImpl child = new VirtualFileImpl(myFileSystem, this, physicalFile, false); + addChild(child); + myFileSystem.fireFileCreated(requestor, child); + return child; + } + + public void delete(Object requestor) throws IOException { + LOG.assertTrue(isValid()); + + PhysicalFile physicalFile = getPhysicalFile(); + VirtualFileImpl parent = (VirtualFileImpl)getParent(); + if (parent == null) { + throw new IOException("Cannot delete root file " + physicalFile.getPath() + "."); + } + + myFileSystem.fireBeforeFileDeletion(requestor, this); + + boolean isDirectory = isDirectory(); + delete(physicalFile); + + parent.removeChild(this); + myFileSystem.fireFileDeleted(requestor, this, myName, isDirectory, parent); + } + + private static void delete(PhysicalFile physicalFile) throws IOException { + PhysicalFile[] list = physicalFile.listFiles(); + if (list != null) { + for (int i = 0; i < list.length; i++) { + delete(list[i]); + } + } + if (!physicalFile.delete()) { + throw new IOException("Cannot delete file " + physicalFile.getPath() + "."); + } + } + + public void move(Object requestor, VirtualFile newParent) throws IOException { + if (!(newParent instanceof VirtualFileImpl)) { + throw new IOException("Can not move file to " + newParent.getPresentableUrl()); + } + + String name = getName(); + VirtualFileImpl oldParent = myParent; + myFileSystem.fireBeforeFileMovement(requestor, this, newParent); + + PhysicalFile physicalFile = getPhysicalFile(); + PhysicalFile newPhysicalParent = ((VirtualFileImpl)newParent).getPhysicalFile(); + PhysicalFile newPhysicalFile = newPhysicalParent.createChild(name); + if (!physicalFile.renameTo(newPhysicalFile)) { + throw new IOException("Cannot move file " + physicalFile.getPath() + " to " + newPhysicalParent.getPath() + "."); + } + + oldParent.removeChild(this); + + myParent = (VirtualFileImpl)newParent; + ((VirtualFileImpl)newParent).addChild(this); + //myModificationStamp = LocalTimeCounter.currentTime(); + //myTimeStamp = -1; + myFileSystem.fireFileMoved(requestor, this, oldParent); + } + + public InputStream getInputStream() throws IOException { + return getProvidedContent().getInputStream(); + } + + public long getLength() { + LOG.assertTrue(!isDirectory()); + ProvidedContent content; + try { + content = getProvidedContent(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + return content.getLength(); + } + + + private ProvidedContent getProvidedContent() throws IOException { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + if (isDirectory()) { + throw new IOException("Cannot read from file " + getPhysicalFile().getPath() + "."); + } + + if (myTimeStamp < 0) return physicalContent(); + + ProvidedContent content = myFileSystem.getManager().getProvidedContent(this); + return content == null ? physicalContent() : content; + + } + + private ProvidedContent physicalContent() { + return new ProvidedContent() { + public InputStream getInputStream() throws IOException { + return new BufferedInputStream(getPhysicalFileInputStream()); + } + + public int getLength() { + return getPhysicalFileLength(); + } + }; + } + + private InputStream getPhysicalFileInputStream() throws IOException { + getTimeStamp(); + return getPhysicalFile().createInputStream(); + } + + public OutputStream getOutputStream(final Object requestor, + final long newModificationStamp, + final long newTimeStamp) throws IOException { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + + PhysicalFile physicalFile = getPhysicalFile(); + if (isDirectory()) { + throw new IOException("Cannot write to file " + physicalFile.getPath() + "."); + } + myFileSystem.fireBeforeContentsChange(requestor, this); + final OutputStream out = new BufferedOutputStream(physicalFile.createOutputStream()); + return new OutputStream() { + public void write(int b) throws IOException { + out.write(b); + } + + public void write(byte[] b) throws IOException { + out.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + public void flush() throws IOException { + out.flush(); + } + + public void close() throws IOException { + out.close(); + long oldModificationStamp = getModificationStamp(); + myModificationStamp = newModificationStamp >= 0 ? newModificationStamp : LocalTimeCounter.currentTime(); + if (newTimeStamp >= 0) { + getPhysicalFile().setLastModified(newTimeStamp); + } + myTimeStamp = getPhysicalFile().lastModified(); + myFileSystem.fireContentsChanged(requestor, VirtualFileImpl.this, oldModificationStamp); + } + }; + } + + public byte[] contentsToByteArray() throws IOException { + InputStream in = getInputStream(); + byte[] bytes = new byte[(int)getLength()]; + try { + int count = 0; + for (; ;) { + int n = in.read(bytes, count, bytes.length - count); + if (n <= 0) break; + count += n; + } + } + finally { + in.close(); + } + return bytes; + } + + public char[] contentsToCharArray() throws IOException { + Reader reader = getReader(); + char[] chars; + try { + chars = FileUtil.loadText(reader, (int)getLength()); + } + finally { + reader.close(); + } + return chars; + } + + public long getModificationStamp() { + return myModificationStamp; + } + + public long getTimeStamp() { + if (myTimeStamp < 0) { + myTimeStamp = getPhysicalFile().lastModified(); + } + return myTimeStamp; + } + + public long getActualTimeStamp() { + return getPhysicalFile().lastModified(); + } + + public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) { + if (asynchronous) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + else { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + } + + final ModalityState modalityState = EventQueue.isDispatchThread() ? ModalityState.current() : ModalityState.NON_MMODAL; + + if (LOG.isDebugEnabled()) { + LOG.debug("VirtualFile.refresh():" + getPresentableUrl() + ", recursive = " + recursive + ", modalityState = " + modalityState); + } + + final WorkerThread worker; + if (asynchronous) { + worker = new WorkerThread("Synchronize worker"); + } + else { + worker = null; + } + + final Runnable runnable = new Runnable() { + public void run() { + myFileSystem.getManager().beforeRefreshStart(asynchronous, modalityState, postRunnable); + + PhysicalFile physicalFile = getPhysicalFile(); + if (!physicalFile.exists()) { + Runnable runnable = new Runnable() { + public void run() { + if (!isValid()) return; + VirtualFileImpl parent = (VirtualFileImpl)getParent(); + if (parent != null) { + myFileSystem.fireBeforeFileDeletion(null, VirtualFileImpl.this); + parent.removeChild(VirtualFileImpl.this); + myFileSystem.fireFileDeleted(null, VirtualFileImpl.this, myName, myDirectoryFlag, parent); + } + } + }; + myFileSystem.getManager().addEventToFireByRefresh(runnable, asynchronous, modalityState); + } + else { + myFileSystem.refresh(VirtualFileImpl.this, recursive, true, worker, modalityState); + } + } + }; + + final Runnable endTask = new Runnable() { + public void run() { + myFileSystem.getManager().afterRefreshFinish(asynchronous, modalityState); + } + }; + + if (asynchronous) { + Runnable runnable1 = new Runnable() { + public void run() { + LOG.info("Executing request:" + this); + + final ProgressIndicator indicator = myFileSystem.getManager().getRefreshIndicator(); + if (indicator != null) { + indicator.start(); + indicator.setText("Synchronizing files..."); + } + + worker.start(); + ApplicationManager.getApplication().runReadAction(runnable); + worker.dispose(false); + try { + worker.join(); + } + catch (InterruptedException e) { + } + + if (indicator != null) { + indicator.stop(); + } + + endTask.run(); + } + }; + myFileSystem.getSynchronizeQueueAlarm().addRequest(runnable1, 0); + } + else { + runnable.run(); + endTask.run(); + } + } + + public boolean nameEquals(String name) { + return SystemInfo.isFileSystemCaseSensitive ? getName().equals(name) : getName().equalsIgnoreCase(name); + } + + public byte[] physicalContentsToByteArray() throws IOException { + InputStream inputStream = getPhysicalFileInputStream(); + try { + int physicalFileLength = getPhysicalFileLength(); + LOG.assertTrue(physicalFileLength >= 0); + return FileUtil.loadBytes(inputStream, physicalFileLength); + } + finally { + inputStream.close(); + } + } + + public int getPhysicalFileLength() { + return (int)getPhysicalFile().length(); + } + + // should not check if file exists - already checked + void refreshInternal(final boolean recursive, final WorkerThread worker, final ModalityState modalityState) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + if (LOG.isDebugEnabled()) { + LOG.debug("refreshInternal recursive = " + recursive + " worker = " + worker + " " + myName); + } + + PhysicalFile physicalFile = getPhysicalFile(); + + final boolean isDirectory = physicalFile.isDirectory(); + if (isDirectory != myDirectoryFlag) { + final PhysicalFile _physicalFile = physicalFile; + myFileSystem.getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (!isValid()) return; + VirtualFileImpl parent = (VirtualFileImpl)getParent(); + if (parent == null) return; + + myFileSystem.fireBeforeFileDeletion(null, VirtualFileImpl.this); + parent.removeChild(VirtualFileImpl.this); + myFileSystem.fireFileDeleted(null, VirtualFileImpl.this, myName, myDirectoryFlag, parent); + VirtualFileImpl newChild = new VirtualFileImpl(myFileSystem, parent, _physicalFile, isDirectory); + parent.addChild(newChild); + myFileSystem.fireFileCreated(null, newChild); + } + }, + worker != null, + modalityState + ); + return; + } + + if (isDirectory) { + if (myChildren == null) return; + PhysicalFile[] files = physicalFile.listFiles(); + if (files == null) { + files = new PhysicalFile[0]; //? + } + boolean[] found = new boolean[myChildren.length]; + VirtualFileImpl[] children = myChildren; + for (int i = 0; i < files.length; i++) { + final PhysicalFile file = files[i]; + final String name = file.getName(); + int index = -1; + // optimization: first check at expected index + if (i < children.length && children[i].myName.equals(name)) { + index = i; + } + else { + for (int j = 0; j < children.length; j++) { + if (children[j].myName.equals(name)) { + index = j; + break; + } + } + } + if (index < 0) { + myFileSystem.getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (VirtualFileImpl.this.isValid()) { + if (findChild(file.getName()) != null) return; // was already created + VirtualFileImpl newChild = new VirtualFileImpl( + myFileSystem, + VirtualFileImpl.this, + file, + file.isDirectory() + ); + addChild(newChild); + myFileSystem.fireFileCreated(null, newChild); + } + } + }, + worker != null, + modalityState + ); + } + else { + found[index] = true; + } + } + for (int i = 0; i < children.length; i++) { + final VirtualFileImpl child = children[i]; + if (found[i]) { + if (recursive) { + if (worker != null) { + worker.addTask( + new Runnable() { + public void run() { + Runnable action = new Runnable() { + public void run() { + child.refreshInternal(recursive, worker, modalityState); + } + }; + ApplicationManager.getApplication().runReadAction(action); + } + } + ); + } + else { + child.refreshInternal(recursive, null, modalityState); + } + } + } + else { + myFileSystem.getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (child.isValid()) { + myFileSystem.fireBeforeFileDeletion(null, child); + removeChild(child); + myFileSystem.fireFileDeleted(null, child, child.myName, child.myDirectoryFlag, VirtualFileImpl.this); + } + } + }, + worker != null, + modalityState + ); + } + } + } + else { + if (myTimeStamp > 0) { + final long timeStamp = physicalFile.lastModified(); + if (timeStamp != myTimeStamp) { + myFileSystem.getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (!isValid()) return; + + myFileSystem.fireBeforeContentsChange(null, VirtualFileImpl.this); + long oldModificationStamp = getModificationStamp(); + myTimeStamp = timeStamp; + myModificationStamp = LocalTimeCounter.currentTime(); + myFileSystem.fireContentsChanged(null, VirtualFileImpl.this, oldModificationStamp); + } + }, + worker != null, + modalityState + ); + } + } + } + + if (myWritableFlag != null) { + final boolean isWritable = isWritable(physicalFile, isDirectory()); + if (isWritable != myWritableFlag.booleanValue()) { + myFileSystem.getManager().addEventToFireByRefresh( + new Runnable() { + public void run() { + if (!isValid()) return; + + myFileSystem.fireBeforePropertyChange( + null, VirtualFileImpl.this, PROP_WRITABLE, + myWritableFlag, isWritable ? Boolean.TRUE : Boolean.FALSE + ); + myWritableFlag = isWritable ? Boolean.TRUE : Boolean.FALSE; + myFileSystem.firePropertyChanged( + null, VirtualFileImpl.this, PROP_WRITABLE, + isWritable ? Boolean.FALSE : Boolean.TRUE, myWritableFlag + ); + } + }, + worker != null, + modalityState + ); + } + } + } + + + private void addChild(VirtualFileImpl child) { + getChildren(); // to initialize myChildren + + VirtualFileImpl[] newChildren = new VirtualFileImpl[myChildren.length + 1]; + System.arraycopy(myChildren, 0, newChildren, 0, myChildren.length); + newChildren[myChildren.length] = child; + myChildren = newChildren; + } + + private void removeChild(VirtualFileImpl child) { + getChildren(); // to initialize myChildren + + for (int i = 0; i < myChildren.length; i++) { + if (myChildren[i] == child) { + VirtualFileImpl[] newChildren = new VirtualFileImpl[myChildren.length - 1]; + System.arraycopy(myChildren, 0, newChildren, 0, i); + System.arraycopy(myChildren, i + 1, newChildren, i, newChildren.length - i); + myChildren = newChildren; + child.myParent = null; + return; + } + } + } + + private boolean isInvalidName(String name){ + if (name.indexOf('\\') >= 0) return true; + if (name.indexOf('/') >= 0) return true; + return false; + } + + public String toString() { + return "VirtualFile: " + getPresentableUrl(); + } + + private void setName(String name) { + myName = new String(name); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileInfoAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileInfoAction.java new file mode 100644 index 00000000000..7ffe41554c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/vfs/impl/local/VirtualFileInfoAction.java @@ -0,0 +1,64 @@ +package com.intellij.openapi.vfs.impl.local; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * author: lesya + */ +public class VirtualFileInfoAction extends AnAction{ + + public static final DateFormat DATE_FORMAT = + SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG); + + + public void actionPerformed(AnActionEvent e) { + String pathToFile = Messages.showInputDialog("Path to file: ", + "Virtual File Info", + Messages.getQuestionIcon()); + if (pathToFile == null) return; + VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(pathToFile)); + if (virtualFile == null){ + Messages.showErrorDialog("Cannot find virtual file", "Virtual File Info"); + return; + } else { + StringBuffer info = new StringBuffer(); + info.append("Path: "); + info.append(virtualFile.getPath()); + info.append("\n"); + info.append("Time stamp: "); + info.append(DATE_FORMAT.format(new Date(virtualFile.getTimeStamp()))); + info.append("\n"); + info.append("Actual time stamp: "); + info.append(DATE_FORMAT.format(new Date(virtualFile.getActualTimeStamp()))); + info.append("\n"); + info.append("isValid: "); + info.append(String.valueOf(virtualFile.isValid())); + info.append("\n"); + info.append("isWritable: "); + info.append(String.valueOf(virtualFile.isWritable())); + info.append("\n"); + info.append("Content: "); + try { + info.append(new String(virtualFile.contentsToCharArray())); + } + catch (IOException e1) { + e1.printStackTrace(); + } + info.append("\n"); + + Messages.showMessageDialog(info.toString(), "Virtual File Info", Messages.getInformationIcon()); + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java new file mode 100644 index 00000000000..32026bdbb6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java @@ -0,0 +1,120 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.impl.EditorComponentImpl; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.*; +import java.lang.reflect.Field; + +public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicyExt { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy"); + + protected Component getDefaultComponentImpl(Container focusCycleRoot) { + if (!(focusCycleRoot instanceof JComponent)) { + return super.getDefaultComponent(focusCycleRoot); + } + return getPreferredFocusedComponent((JComponent)focusCycleRoot, this); + } + + public static JComponent getPreferredFocusedComponent(final JComponent component) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + return getPreferredFocusedComponent(component, null); + } + + /** + * @return preferred focused component inside the specified component. + * Method can return component itself if the component is legal + * (JTextFiel)focusable + * + */ + public static JComponent getPreferredFocusedComponent(final JComponent component, final FocusTraversalPolicy policyToIgnore) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + + if (!component.isVisible()) { + return null; + } + + final FocusTraversalPolicy focusTraversalPolicy = getFocusTraversalPolicyAwtImpl(component); + if (focusTraversalPolicy != null && focusTraversalPolicy != policyToIgnore) { + final Component defaultComponent = focusTraversalPolicy.getDefaultComponent(component); + if (defaultComponent instanceof JComponent) { + return (JComponent)defaultComponent; + }else{ + return null; + } + } + + if (component instanceof JTabbedPane) { + final JTabbedPane tabbedPane = (JTabbedPane)component; + final Component selectedComponent = tabbedPane.getSelectedComponent(); + if (selectedComponent instanceof JComponent) { + return getPreferredFocusedComponent((JComponent)selectedComponent); + } + return null; + } + + if(_accept(component)) { + return component; + } + + final Component[] ca = component.getComponents(); + for(int i=0 ; i < ca.length ; i++) { + if(!(ca[i] instanceof JComponent)){ + continue; + } + final JComponent c = getPreferredFocusedComponent((JComponent)ca[i]); + if (c != null) { + return c; + } + } + return null; + } + + private static FocusTraversalPolicy getFocusTraversalPolicyAwtImpl(final JComponent component) { + try { + final Field field = Container.class.getDeclaredField("focusTraversalPolicy"); + field.setAccessible(true); + final FocusTraversalPolicy focusTraversalPolicy = (FocusTraversalPolicy)field.get(component); + return focusTraversalPolicy; + } + catch (Exception e) { + LOG.error(e); + return null; + } + } + + protected final boolean accept(final Component aComponent) { + if (aComponent instanceof JComponent) { + return _accept((JComponent)aComponent); + } + return super.accept(aComponent); + } + + private static boolean _accept(final JComponent component) { + if (!component.isEnabled() || !component.isVisible() || !component.isFocusable()) { + return false; + } + + /** TODO[anton,vova] implement Policy in Editor component instead */ + if (component instanceof EditorComponentImpl) { + return true; + } + + if(component instanceof JTextComponent){ + return ((JTextComponent)component).isEditable(); + } + + return + component instanceof AbstractButton || + component instanceof JList || + component instanceof JTree || + component instanceof JTable || + component instanceof JComboBox; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java new file mode 100644 index 00000000000..4b82191adb5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/LayoutFocusTraversalPolicyExt.java @@ -0,0 +1,91 @@ +package com.intellij.openapi.wm.ex; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +public class LayoutFocusTraversalPolicyExt extends LayoutFocusTraversalPolicy{ + /** + * Overriden default component + */ + private static JComponent myOverridenDefaultComponent; + + /** + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * + * THIS IS AN "ABSOLUTELY-GURU METHOD". + * NOBODY SHOULD ADD OTHER USAGES OF IT :) + * ONLY ANTON AND VOVA ARE PERMITTED TO USE THIS METHOD!!! + * + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * + * This is absolutely guru method. Please do not use it without deep understanding + * of Swing concepts, especially Swing focus management. do not forget to clear + * this "overiden" component! + */ + public static void setOverridenDefaultComponent(final JComponent overridenDefaultComponent) { + myOverridenDefaultComponent = overridenDefaultComponent; + } + +// Made non-final for Fabrique + public Component getDefaultComponent(final Container focusCycleRoot) { + if (myOverridenDefaultComponent != null) { + return myOverridenDefaultComponent; + } + return getDefaultComponentImpl(focusCycleRoot); + } + + protected Component getDefaultComponentImpl(final Container focusCycleRoot) { + return super.getDefaultComponent(focusCycleRoot); + } + + public Component getFirstComponent(final Container focusCycleRoot) { + if (myOverridenDefaultComponent != null) { + return myOverridenDefaultComponent; + } + return getFirstComponentImpl(focusCycleRoot); + } + + protected Component getFirstComponentImpl(final Container focusCycleRoot) { + return super.getFirstComponent(focusCycleRoot); + } + + public Component getLastComponent(final Container focusCycleRoot) { + if (myOverridenDefaultComponent != null) { + return myOverridenDefaultComponent; + } + return getLastComponentImpl(focusCycleRoot); + } + + protected Component getLastComponentImpl(final Container focusCycleRoot) { + return super.getLastComponent(focusCycleRoot); + } + + public Component getComponentAfter(final Container focusCycleRoot, final Component aComponent) { + if (myOverridenDefaultComponent != null) { + return myOverridenDefaultComponent; + } + return getComponentAfterImpl(focusCycleRoot, aComponent); + } + + protected Component getComponentAfterImpl(final Container focusCycleRoot, final Component aComponent) { + return super.getComponentAfter(focusCycleRoot, aComponent); + } + + public Component getComponentBefore(final Container focusCycleRoot, final Component aComponent) { + if (myOverridenDefaultComponent != null) { + return myOverridenDefaultComponent; + } + return getComponentBeforeImpl(focusCycleRoot, aComponent); + } + + protected Component getComponentBeforeImpl(final Container focusCycleRoot, final Component aComponent) { + return super.getComponentBefore(focusCycleRoot, aComponent); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/StatusBarEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/StatusBarEx.java new file mode 100644 index 00000000000..2b0fde102b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/StatusBarEx.java @@ -0,0 +1,32 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.wm.StatusBar; + +import javax.swing.*; +import java.awt.event.ActionListener; + +public interface StatusBarEx extends StatusBar{ + String getInfo(); + + void setPosition(String s); + + void setStatus(String s); + + void setStatusEnabled(boolean enabled); + + void showCancelButton(Icon icon, ActionListener listener, String tooltopText); + + void hideCancelButton(); + + void addProgress(); + + void setProgressValue(int progress); + + void hideProgress(); + + void setWriteStatus(boolean locked); + + void clear(); + + void updatePopupHintsStatus(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowEx.java new file mode 100644 index 00000000000..69d8bccfa67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowEx.java @@ -0,0 +1,30 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowType; + +import java.beans.PropertyChangeListener; + +public interface ToolWindowEx extends ToolWindow{ + /** + */ + String PROP_AVAILABLE="available"; + /** + */ + String PROP_ICON="icon"; + /** + */ + String PROP_TITLE="title"; + + /** + * Removes specified property change listener. + * @param l listener to be removed. + */ + void removePropertyChangeListener(PropertyChangeListener l); + + /** + * @return type of internal decoration of tool window. + * @exception java.lang.IllegalStateException if tool window isn't installed. + */ + ToolWindowType getInternalType(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerAdapter.java new file mode 100644 index 00000000000..cf7177fd939 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerAdapter.java @@ -0,0 +1,12 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.openapi.wm.ex; + + + +public class ToolWindowManagerAdapter implements ToolWindowManagerListener{ + public void toolWindowRegistered(final String id){} + + public void stateChanged(){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java new file mode 100644 index 00000000000..e6c5fff3dc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java @@ -0,0 +1,33 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.impl.DesktopLayout; +import com.intellij.openapi.project.Project; + +public abstract class ToolWindowManagerEx extends ToolWindowManager{ + public static ToolWindowManagerEx getInstanceEx(final Project project){ + return (ToolWindowManagerEx)getInstance(project); + } + + public abstract void addToolWindowManagerListener(ToolWindowManagerListener l); + + public abstract void removeToolWindowManagerListener(ToolWindowManagerListener l); + + /** + * @return ID of tool window that was activated last time. + */ + public abstract String getLastActiveToolWindowId(); + + /** + * @return layout of tool windows. + */ + public abstract DesktopLayout getLayout(); + + /** + * Copied layout into internal layout and rearranges tool windows. + */ + public abstract void setLayout(DesktopLayout layout); + + public abstract void clearSideStack(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerListener.java new file mode 100644 index 00000000000..45505ac99d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/ToolWindowManagerListener.java @@ -0,0 +1,15 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.wm.ToolWindowManager; + +import java.util.EventListener; + +public interface ToolWindowManagerListener extends EventListener{ + /** + * Invoked when tool window with specified id is registered in ToolWindowMnagare. + * @param id id of registered tool window. + */ + void toolWindowRegistered(String id); + + void stateChanged(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/WindowManagerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/WindowManagerEx.java new file mode 100644 index 00000000000..5dd25a4bfd5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/ex/WindowManagerEx.java @@ -0,0 +1,110 @@ +package com.intellij.openapi.wm.ex; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.impl.CommandProcessor; +import com.intellij.openapi.wm.impl.DesktopLayout; +import com.intellij.openapi.wm.impl.IdeFrame; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class WindowManagerEx extends WindowManager { + public static WindowManagerEx getInstanceEx(){ + return (WindowManagerEx)WindowManager.getInstance(); + } + + + public abstract IdeFrame getFrame(Project project); + + public abstract IdeFrame allocateFrame(Project project); + + public abstract void releaseFrame(IdeFrame frame); + + /** + * @return focus owner of the specified window. + * @exception IllegalArgumentException if window is null. + */ + public abstract Component getFocusedComponent(Window window); + + /** + * @param project may be null when no project is opened. + * @return focused component for the project. If project isn't specified then + * the method returns focused compoent in window which has no project. + * If there is no focused component at all then the method returns null. + */ + public abstract Component getFocusedComponent(Project project); + + public abstract Window getMostRecentFocusedWindow(); + + public abstract CommandProcessor getCommandProcessor(); + + /** + * @return default layout for tool windows. + */ + public abstract DesktopLayout getLayout(); + + /** + * Copies layout into internal default layout. + */ + public abstract void setLayout(DesktopLayout layout); + + /** + * This method is invoked by IdeEventQueue to notify window manager that + * some window activity happens. Do not invoke it in other places!!! + */ + public abstract void dispatchComponentEvent(ComponentEvent e); + + /** + * @return union of bounds of all default screen devices. Note that x and/or y + * coordinates can be negative. It depends on phisical configuration of graphics devices. + * For example, the left monitor has negative coordinates on Win32 platform with dual monitor support + * (right monitor is the primer one) . + */ + public abstract Rectangle getScreenBounds(); + + /** + * @return true is and only if current OS supports alpha mode for windows and + * all native libraries were successfully loaded. + */ + public abstract boolean isAlphaModeSupported(); + + /** + * Sets alpha (transparency) ratio for the specified window. + * If alpha mode isn't supported by underlying windowing system then the method does nothing. + * The method also does nothing if alpha mode isn't enabled for the specified window. + * @param window window which transparency should be changed. + * @param ratio ratio of transparency. 0 means absolutely non transparent window. + * 1 means absolutely transparent window. + * @exception java.lang.IllegalArgumentException if window is not + * desplayable or not showing. + * @exception java.lang.IllegalArgumentException if ration isn't + * in [0..1] range. + */ + public abstract void setAlphaModeRatio(Window window,float ratio); + + /** + * @return true if specified window is currently is alpha mode. + */ + public abstract boolean isAlphaModeEnabled(Window window); + + /** + * Sets whether the alpha (transparent) mode is enabled for specified window. + * If alpha mode isn't supported by underlying windowing system then the method does nothing. + * @param window window which mode to be set. + * @param state determines the new alpha mode. + */ + public abstract void setAlphaModeEnabled(Window window,boolean state); + + /** + * Either dispose the dialog immediately if project's frame has focus or just hide and dispose when frame gets focus or closes. + * @param dialog to hide and dispose later + * @param project the dialog has been shown for + */ + public abstract void hideDialog(JDialog dialog, Project project); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ActiveStack.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ActiveStack.java new file mode 100644 index 00000000000..b74adf053eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ActiveStack.java @@ -0,0 +1,91 @@ +package com.intellij.openapi.wm.impl; + +import java.util.Iterator; +import java.util.Stack; + +/** + * Actually this class represent two stacks. + * 1. Stack of ids of active tool windows. This stack is used for reactivation of tool window + * after the another tool window was closed. This stack is cleared every time you active the editor. + * 2. Permanent stack. It is the same as the first one, but it's not cleared when editor is being + * activated. It used to provide id of last active tool window. + * + * @author Vladimir Kondratyev + */ +final class ActiveStack { + /** + * Contains ids of tool window that were activated. This stack + * is cleared each time when editor is being activated. + */ + private final Stack myStack; + /** + * This stack is not cleared when editor is being activated. It means its "long" + * persistence. + */ + private final Stack myPersistentStack; + + /** + * Creates enabled window stack. + */ + ActiveStack() { + myStack = new Stack(); + myPersistentStack = new Stack(); + } + + /** + * Clears stack but doesn't affect long persistence stack. + */ + void clear() { + myStack.clear(); + } + + /** + * Return whether the stack of active (not persistent) ids is empty or not. + */ + boolean isEmpty() { + return myStack.isEmpty(); + } + + String pop() { + return myStack.pop(); + } + + void push(final String id) { + remove(id, true); + myStack.push(id); + myPersistentStack.push(id); + } + + int getPersistentSize() { + return myPersistentStack.size(); + } + + /** + * Peeks element at the persistent stack. 0 means the top of the stack. + */ + String peekPersistent(final int index) { + return myPersistentStack.get(myPersistentStack.size() - index - 1); + } + + /** + * Removes specified ID from stack. + * + * @param id ID to be removed. + * @param removePersistentAlso if true then clears last active ID + * if it's the last active ID. + */ + void remove(final String id, final boolean removePersistentAlso) { + for (Iterator i = myStack.iterator(); i.hasNext();) { + if (id.equals(i.next())) { + i.remove(); + } + } + if (removePersistentAlso) { + for (Iterator i = myPersistentStack.iterator(); i.hasNext();) { + if (id.equals(i.next())) { + i.remove(); + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/CommandProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/CommandProcessor.java new file mode 100644 index 00000000000..71a22e62c08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/CommandProcessor.java @@ -0,0 +1,51 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.wm.impl.commands.FinalizableCommand; + +import java.util.ArrayList; + +public final class CommandProcessor implements Runnable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.CommandProcessor"); + private final Object myLock; + private final ArrayList myCommandList; + + public CommandProcessor() { + myLock = new Object(); + myCommandList = new ArrayList(); + } + + public final int getCommandCount() { + synchronized (myLock) { + return myCommandList.size(); + } + } + + /** + * Executes passed batch of commands. Note, that the processor surround the + * commands with BlockFocusEventsCmd - UnbockFocusEventsCmd. It's required to + * prevent focus handling of events which is caused by the commands to be executed. + */ + public final void execute(final java.util.List commandList) { + synchronized (myLock) { + final boolean isBusy = myCommandList.size() > 0; + myCommandList.addAll(commandList); + if (!isBusy) { + run(); + } + } + } + + public final void run() { + synchronized (myLock) { + if (myCommandList.size() > 0) { + final FinalizableCommand command = (FinalizableCommand)myCommandList.remove(0); + if (LOG.isDebugEnabled()) { + LOG.debug("CommandProcessor.run " + command); + } + ApplicationManager.getApplication().invokeLater(command); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/DesktopLayout.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/DesktopLayout.java new file mode 100644 index 00000000000..18ab9c2fee5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/DesktopLayout.java @@ -0,0 +1,318 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; + +/** + * @author Vladimir Kondratyev + */ +public final class DesktopLayout implements JDOMExternalizable { + static final String TAG = "layout"; + /** + * Map between ids and registered WindowInfos. + */ + private final com.intellij.util.containers.HashMap myRegisteredId2Info; + /** + * Map between ids and unregistered WindowInfos. + */ + private final com.intellij.util.containers.HashMap myUnregisteredId2Info; + /** + * + */ + private static final MyWindowInfoComparator ourWindowInfoComparator = new MyWindowInfoComparator(); + /** + * Don't use this member directly. Get it only by getInfos method. + * It exists here only for optimization purposes. This member can be null + * if the cached data is invalid. + */ + private WindowInfo[] myRegisteredInfos; + /** + * Don't use this member directly. Get it only by getUnregisteredInfos method. + * It exists here only for optimization purposes. This member can be null + * if the cached data is invalid. + */ + private WindowInfo[] myUnregisteredInfos; + /** + * Don't use this member directly. Get it only by getAllInfos method. + * It exists here only for optimization purposes. This member can be null + * if the cached data is invalid. + */ + private WindowInfo[] myAllInfos; + + DesktopLayout() { + myRegisteredId2Info = new com.intellij.util.containers.HashMap(); + myUnregisteredId2Info = new com.intellij.util.containers.HashMap(); + } + + /** + * Copies itself into the passed + * + * @param layout to be copied. + */ + final void copyFrom(final DesktopLayout layout) { + final WindowInfo[] infos = layout.getAllInfos(); + for (int i = 0; i < infos.length; i++) { + WindowInfo info = myRegisteredId2Info.get(infos[i].getId()); + if (info != null) { + info.copyFrom(infos[i]); + continue; + } + info = myUnregisteredId2Info.get(infos[i].getId()); + if (info != null) { + info.copyFrom(infos[i]); + } + else { + myUnregisteredId2Info.put(infos[i].getId(), infos[i].copy()); + } + } + // invalidate caches + myRegisteredInfos = null; + myUnregisteredInfos = null; + myAllInfos = null; + // normalize orders + normalizeOrder(getAllInfos(ToolWindowAnchor.TOP)); + normalizeOrder(getAllInfos(ToolWindowAnchor.LEFT)); + normalizeOrder(getAllInfos(ToolWindowAnchor.BOTTOM)); + normalizeOrder(getAllInfos(ToolWindowAnchor.RIGHT)); + } + + /** + * Creates or gets WindowInfo for the specified id. If tool + * window is being registered first time the method uses anchor. + * + * @param id id of tool window to be registered. + * @param anchor the default tool window anchor. + * @return + */ + final WindowInfo register(final String id, final ToolWindowAnchor anchor) { + WindowInfo info = myUnregisteredId2Info.get(id); + if (info != null) { // tool window has been already registered some time + myUnregisteredId2Info.remove(id); + } + else { // tool window is being registered first time + info = new WindowInfo(id); + info.setAnchor(anchor); + } + myRegisteredId2Info.put(id, info); + // invalidate caches + myRegisteredInfos = null; + myUnregisteredInfos = null; + myAllInfos = null; + // + return info; + } + + final void unregister(final String id) { + final WindowInfo info = myRegisteredId2Info.remove(id).copy(); + myUnregisteredId2Info.put(id, info); + // invalidate caches + myRegisteredInfos = null; + myUnregisteredInfos = null; + myAllInfos = null; + } + + /** + * @return WindowInfo for the window with specified id. + * If onlyRegistered is true then returns not null + * value if and only if window with id is registered one. + */ + final WindowInfo getInfo(final String id, final boolean onlyRegistered) { + final WindowInfo info = myRegisteredId2Info.get(id); + if (onlyRegistered || info != null) { + return info; + } + else { + return myUnregisteredId2Info.get(id); + } + } + + final String getActiveId() { + final WindowInfo[] infos = getInfos(); + for (int i = 0; i < infos.length; i++) { + if (infos[i].isActive()) { + return infos[i].getId(); + } + } + return null; + } + + /** + * @return WindowInfos for all registered tool windows. + */ + final WindowInfo[] getInfos() { + if (myRegisteredInfos == null) { + myRegisteredInfos = myRegisteredId2Info.values().toArray(new WindowInfo[myRegisteredId2Info.size()]); + } + return myRegisteredInfos; + } + + /** + * @return WindowInfoss for all windows that are currently unregistered. + */ + private WindowInfo[] getUnregisteredInfos() { + if (myUnregisteredInfos == null) { + myUnregisteredInfos = myUnregisteredId2Info.values().toArray(new WindowInfo[myUnregisteredId2Info.size()]); + } + return myUnregisteredInfos; + } + + /** + * @return WindowInfos of all (registered and unregistered) tool windows. + */ + private WindowInfo[] getAllInfos() { + final WindowInfo[] registeredInfos = getInfos(); + final WindowInfo[] unregisteredInfos = getUnregisteredInfos(); + myAllInfos = ArrayUtil.mergeArrays(registeredInfos, unregisteredInfos, WindowInfo.class); + return myAllInfos; + } + + /** + * @return all (registered and not unregistered) WindowInfos for the specified anchor. + * Returned infos are sorted by order. + */ + private WindowInfo[] getAllInfos(final ToolWindowAnchor anchor) { + WindowInfo[] infos = getAllInfos(); + final ArrayList list = new ArrayList(infos.length); + for (int i = 0; i < infos.length; i++) { + if (anchor == infos[i].getAnchor()) { + list.add(infos[i]); + } + } + infos = list.toArray(new WindowInfo[list.size()]); + Arrays.sort(infos, ourWindowInfoComparator); + return infos; + } + + /** + * Normalizes order of windows in the passed array. Note, that array should be + * sorted by order (by ascending). Order of first window will be 0. + */ + private static void normalizeOrder(final WindowInfo[] infos) { + for (int i = 0; i < infos.length; i++) { + infos[i].setOrder(i); + } + } + + final boolean isToolWindowRegistered(final String id) { + return myRegisteredId2Info.containsKey(id); + } + + /** + * @return comparator which compares StripeButtons in the stripe with + * specified anchor. + */ + final Comparator comparator(final ToolWindowAnchor anchor) { + return new MyStripeButtonComparator(anchor); + } + + /** + * @param anchor anchor of the stripe. + * @return maximum ordinal number in the specified stripe. Returns -1 + * if there is no any tool window with the specified anchor. + */ + private int getMaxOrder(final ToolWindowAnchor anchor) { + int res = -1; + final WindowInfo[] infos = getAllInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + if (anchor == info.getAnchor() && res < info.getOrder()) { + res = info.getOrder(); + } + } + return res; + } + + /** + * Sets new anchor and id for the specified tool window. + * Also the method properly updates order of all other tool windows. + * + * @param newAnchor new anchor + * @param newOrder new order + */ + final void setAnchor(final String id, final ToolWindowAnchor newAnchor, int newOrder) { + if (newOrder == -1) { // if order isn't defined then the window will the last in the stripe + newOrder = getMaxOrder(newAnchor) + 1; + } + final WindowInfo info = getInfo(id, true); + final ToolWindowAnchor oldAnchor = info.getAnchor(); + // Shift order to the right in the target stripe. + final WindowInfo[] infos = getAllInfos(newAnchor); + for (int i = infos.length - 1; i > -1; i--) { + final WindowInfo info2 = infos[i]; + if (newOrder <= info2.getOrder()) { + info2.setOrder(info2.getOrder() + 1); + } + } + // "move" window into the target position + info.setAnchor(newAnchor); + info.setOrder(newOrder); + // Normalize orders in the source and target stripes + normalizeOrder(getAllInfos(oldAnchor)); + if (oldAnchor != newAnchor) { + normalizeOrder(getAllInfos(newAnchor)); + } + } + + public final void readExternal(final org.jdom.Element layoutElement) { + for (Iterator i = layoutElement.getChildren().iterator(); i.hasNext();) { + final Element e = (Element)i.next(); + if (WindowInfo.TAG.equals(e.getName())) { + final WindowInfo info = new WindowInfo(e.getAttributeValue("id")); + info.readExternal(e); + if (info.getOrder() == -1) { // if order isn't defined then window's button will be the last one in the stripe + info.setOrder(getMaxOrder(info.getAnchor()) + 1); + } + myUnregisteredId2Info.put(info.getId(), info); + } + } + } + + public final void writeExternal(final Element layoutElement) { + final WindowInfo[] infos = getAllInfos(); + for (int i = 0; i < infos.length; i++) { + final Element element = new Element(WindowInfo.TAG); + infos[i].writeExternal(element); + layoutElement.addContent(element); + } + } + + private static final class MyWindowInfoComparator implements Comparator { + public int compare(final Object obj1, final Object obj2) { + final WindowInfo info1 = (WindowInfo)obj1; + final WindowInfo info2 = (WindowInfo)obj2; + return info1.getOrder() - info2.getOrder(); + } + } + + private final class MyStripeButtonComparator implements Comparator { + private final com.intellij.util.containers.HashMap myId2Info; + + public MyStripeButtonComparator(final ToolWindowAnchor anchor) { + myId2Info = new com.intellij.util.containers.HashMap(); + final WindowInfo[] infos = getInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + if (anchor == info.getAnchor()) { + myId2Info.put(info.getId(), info.copy()); + } + } + } + + public final int compare(final Object obj1, final Object obj2) { + final WindowInfo info1 = myId2Info.get(((StripeButton)obj1).getWindowInfo().getId()); + final int order1 = info1 != null ? info1.getOrder() : 0; + + final WindowInfo info2 = myId2Info.get(((StripeButton)obj2).getWindowInfo().getId()); + final int order2 = info2 != null ? info2.getOrder() : 0; + + return order1 - order2; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/FloatingDecorator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/FloatingDecorator.java new file mode 100644 index 00000000000..0c772649be1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/FloatingDecorator.java @@ -0,0 +1,353 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class FloatingDecorator extends JDialog{ + private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.wm.impl.FloatingDecorator"); + + private static final int ANCHOR_TOP=1; + private static final int ANCHOR_LEFT=2; + private static final int ANCHOR_BOTTOM=4; + private static final int ANCHOR_RIGHT=8; + + private static final int DELAY=15; // Delay between frames + private static final int TOTAL_FRAME_COUNT=7; // Total number of frames in animation sequence + + private final InternalDecorator myInternalDecorator; + private final MyUISettingsListener myUISettingsListener; + private WindowInfo myInfo; + + private final Alarm myDelayAlarm; // Determines moment when tool window should become transparent + private final Alarm myFrameTicker; // Determines moments of rendering of next frame + private final MyAnimator myAnimator; // Renders alpha ratio + private int myCurrentFrame; // current frame in transparency animation + private float myStartRatio, myEndRatio; // start and end alpha ratio for transparency animation + + + FloatingDecorator(final IdeFrame owner,final WindowInfo info,final InternalDecorator internalDecorator){ + super(owner,internalDecorator.getToolWindow().getId()); + + myInternalDecorator=internalDecorator; + + setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + final JComponent cp=(JComponent)getContentPane(); + cp.setLayout(new BorderLayout()); + + if(SystemInfo.isWindows){ + setUndecorated(true); + cp.add(new BorderItem(ANCHOR_TOP),BorderLayout.NORTH); + cp.add(new BorderItem(ANCHOR_LEFT),BorderLayout.WEST); + cp.add(new BorderItem(ANCHOR_BOTTOM),BorderLayout.SOUTH); + cp.add(new BorderItem(ANCHOR_RIGHT),BorderLayout.EAST); + cp.add(myInternalDecorator,BorderLayout.CENTER); + }else{ + // Due to JDK's bug #4234645 we cannot support custom decoration on Linux platform. + // The prblem is that Window.setLocation() doesn't work properly wjen the dialod is displayable. + // Therefore we use native WM decoration. + // TODO[vova] investigate the problem under Mac OSX. + cp.add(myInternalDecorator,BorderLayout.CENTER); + } + + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new MyWindowListener()); + + // + + myDelayAlarm=new Alarm(); + myFrameTicker=new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + myAnimator=new MyAnimator(); + myCurrentFrame=0; + myStartRatio=0.0f; + myEndRatio=0.0f; + + myUISettingsListener=new MyUISettingsListener(); + + // + + apply(info); + } + + public final void show(){ + super.show(); + final UISettings uiSettings=UISettings.getInstance(); + if(uiSettings.ENABLE_ALPHA_MODE){ + final WindowManagerEx windowManager=WindowManagerEx.getInstanceEx(); + windowManager.setAlphaModeEnabled(this,true); + if(myInfo.isActive()){ + windowManager.setAlphaModeRatio(this,0.0f); + }else{ + windowManager.setAlphaModeRatio(this,uiSettings.ALPHA_MODE_RATIO); + } + } + paint(getGraphics()); // This prevents annoying flick + + // + + uiSettings.addUISettingsListener(myUISettingsListener); + } + + public final void dispose(){ + UISettings.getInstance().removeUISettingsListener(myUISettingsListener); + super.dispose(); + } + + final void apply(final WindowInfo info){ + LOG.assertTrue(info.isFloating()); + myInfo=info; + // Set alpha mode + final UISettings uiSettings=UISettings.getInstance(); + if(uiSettings.ENABLE_ALPHA_MODE&&isShowing()&&isDisplayable()){ + myDelayAlarm.cancelAllRequests(); + if(myInfo.isActive()){ // make window non transparent + myFrameTicker.cancelAllRequests(); + myStartRatio=getCurrentAlphaRatio(); + if(myCurrentFrame>0){ + myCurrentFrame=TOTAL_FRAME_COUNT-myCurrentFrame; + } + myEndRatio=.0f; + myFrameTicker.addRequest(myAnimator,DELAY); + }else{ // make window transparent + myDelayAlarm.addRequest( + new Runnable(){ + public void run(){ + myFrameTicker.cancelAllRequests(); + myStartRatio=getCurrentAlphaRatio(); + if(myCurrentFrame>0){ + myCurrentFrame=TOTAL_FRAME_COUNT-myCurrentFrame; + } + myEndRatio=uiSettings.ALPHA_MODE_RATIO; + myFrameTicker.addRequest(myAnimator,DELAY); + } + }, + uiSettings.ALPHA_MODE_DELAY + ); + } + } + } + + private float getCurrentAlphaRatio(){ + float delta=(myEndRatio-myStartRatio)/(float)TOTAL_FRAME_COUNT; + if(myStartRatio>myEndRatio){ // dialog is becoming non transparent quicker + delta*=2; + } + final float ratio=myStartRatio+(float)myCurrentFrame*delta; + return Math.min(1.0f,Math.max(.0f,ratio)); + } + + private final class BorderItem extends JPanel{ + private static final int DIVIDER_WIDTH=3; + private static final int RESIZER_WIDTH=10; + + private final int myAnchor; + private int myMotionMask; + private Point myLastPoint; + private boolean myDragging; + + public BorderItem(final int anchor){ + myAnchor=anchor; + enableEvents(MouseEvent.MOUSE_EVENT_MASK|MouseEvent.MOUSE_MOTION_EVENT_MASK); + } + + protected final void processMouseMotionEvent(final MouseEvent e){ + super.processMouseMotionEvent(e); + if(MouseEvent.MOUSE_DRAGGED==e.getID()){ + final Point newPoint=e.getPoint(); + SwingUtilities.convertPointToScreen(newPoint,this); + final Rectangle screenBounds=WindowManagerEx.getInstanceEx().getScreenBounds(); + + newPoint.x=Math.min(Math.max(newPoint.x,screenBounds.x),screenBounds.width); + newPoint.y=Math.min(Math.max(newPoint.y,screenBounds.y),screenBounds.height); + + final Rectangle oldBounds=FloatingDecorator.this.getBounds(); + final Rectangle newBounds=new Rectangle(oldBounds); + + if((myMotionMask&ANCHOR_TOP)>0){ + newPoint.y=Math.min(newPoint.y,oldBounds.y+oldBounds.height-2*DIVIDER_WIDTH); + if(newPoint.y0){ + newPoint.x=Math.min(newPoint.x,oldBounds.x+oldBounds.width-2*DIVIDER_WIDTH); + if(newPoint.x0){ + newPoint.y=Math.max(newPoint.y,oldBounds.y+2*DIVIDER_WIDTH); + if(newPoint.y>screenBounds.height-DIVIDER_WIDTH){ + newPoint.y=screenBounds.height; + } + final Point offset=new Point(newPoint.x-myLastPoint.x,newPoint.y-myLastPoint.y); + newBounds.height=oldBounds.height+offset.y; + } + if((myMotionMask&ANCHOR_RIGHT)>0){ + newPoint.x=Math.max(newPoint.x,oldBounds.x+2*DIVIDER_WIDTH); + if(newPoint.x>screenBounds.width-DIVIDER_WIDTH){ + newPoint.x=screenBounds.width; + } + final Point offset=new Point(newPoint.x-myLastPoint.x,newPoint.y-myLastPoint.y); + newBounds.width=oldBounds.width+offset.x; + } + // It's much better to resize frame this way then via Component.setBounds() method. + // Component.setBounds() method cause annoying repainting and blinking. + FloatingDecorator.this.getPeer().setBounds(newBounds.x,newBounds.y,newBounds.width,newBounds.height); + + myLastPoint=newPoint; + } else if(e.getID()==MouseEvent.MOUSE_MOVED){ + if(!myDragging){ + setMotionMask(e.getPoint()); + } + } + } + + protected final void processMouseEvent(final MouseEvent e){ + super.processMouseEvent(e); + switch(e.getID()){ + case MouseEvent.MOUSE_PRESSED:{ + myLastPoint=e.getPoint(); + SwingUtilities.convertPointToScreen(myLastPoint,this); + setMotionMask(e.getPoint()); + myDragging=true; + break; + }case MouseEvent.MOUSE_RELEASED:{ + FloatingDecorator.this.validate(); + FloatingDecorator.this.repaint(); + myDragging=false; + break; + }case MouseEvent.MOUSE_ENTERED:{ + if(!myDragging){ + setMotionMask(e.getPoint()); + } + } + } + } + + private void setMotionMask(final Point p){ + myMotionMask=myAnchor; + if(ANCHOR_TOP==myAnchor||ANCHOR_BOTTOM==myAnchor){ + if(p.getX()getWidth()-RESIZER_WIDTH){ + myMotionMask|=ANCHOR_RIGHT; + } + } else{ + if(p.getY()getHeight()-RESIZER_WIDTH){ + myMotionMask|=ANCHOR_BOTTOM; + } + } + if(myMotionMask==ANCHOR_TOP){ + setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); + } else if(myMotionMask==(ANCHOR_TOP|ANCHOR_LEFT)){ + setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)); + } else if(myMotionMask==ANCHOR_LEFT){ + setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); + } else if(myMotionMask==(ANCHOR_LEFT|ANCHOR_BOTTOM)){ + setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR)); + } else if(myMotionMask==ANCHOR_BOTTOM){ + setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); + } else if(myMotionMask==(ANCHOR_BOTTOM|ANCHOR_RIGHT)){ + setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)); + } else if(myMotionMask==ANCHOR_RIGHT){ + setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); + } else if(myMotionMask==(ANCHOR_RIGHT|ANCHOR_TOP)){ + setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)); + } + } + + public final Dimension getPreferredSize(){ + final Dimension d=super.getPreferredSize(); + if(ANCHOR_TOP==myAnchor||ANCHOR_BOTTOM==myAnchor){ + d.height=DIVIDER_WIDTH; + } else{ + d.width=DIVIDER_WIDTH; + } + return d; + } + + public final void paint(final Graphics g){ + super.paint(g); + if(ANCHOR_TOP==myAnchor){ + g.setColor(Color.lightGray); + g.drawLine(0,0,getWidth()-1,0); + g.drawLine(0,0,0,getHeight()-1); + g.setColor(Color.gray); + g.drawLine(getWidth()-1,0,getWidth()-1,getHeight()-1); + } else if(ANCHOR_LEFT==myAnchor){ + g.setColor(Color.lightGray); + g.drawLine(0,0,0,getHeight()-1); + } else if(ANCHOR_BOTTOM==myAnchor){ + g.setColor(Color.lightGray); + g.drawLine(0,0,0,getHeight()-1); + g.setColor(Color.gray); + g.drawLine(0,getHeight()-1,getWidth()-1,getHeight()-1); + g.drawLine(getWidth()-1,0,getWidth()-1,getHeight()-1); + } else{ // RIGHT + g.setColor(Color.gray); + g.drawLine(getWidth()-1,0,getWidth()-1,getHeight()-1); + } + } + } + + private final class MyWindowListener extends WindowAdapter{ + public void windowClosing(final WindowEvent e){ + myInternalDecorator.fireResized(); + myInternalDecorator.fireHidden(); + } + } + + private final class MyAnimator implements Runnable{ + public final void run(){ + final WindowManagerEx windowManager=WindowManagerEx.getInstanceEx(); + if(isDisplayable()&&isShowing()){ + windowManager.setAlphaModeRatio(FloatingDecorator.this,getCurrentAlphaRatio()); + } + if(myCurrentFrameHierarchyWatcher invokes this method each time one of the populated container changes. + * @param e event which describes the changes. + */ + protected abstract void hierarchyChanged(ContainerEvent e); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeFrame.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeFrame.java new file mode 100644 index 00000000000..2500266cec5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeFrame.java @@ -0,0 +1,166 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.util.ImageLoader; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ + +// Made non-final for Fabrique +public class IdeFrame extends JFrame implements DataProvider { + private String myTitle; + private String myFileTitle; + private Project myProject; + private final LayoutFocusTraversalPolicyExt myLayoutFocusTraversalPolicy; + private ActionManager myActionManager; + + public IdeFrame(ApplicationInfoEx applicationInfoEx, + ActionManager actionManager, + UISettings uiSettings, + DataManager dataManager, + KeymapManager keymapManager) { + super(applicationInfoEx.getFullApplicationName()); + + setRootPane(new IdeRootPane(actionManager, uiSettings, dataManager, keymapManager)); + + final Image image = ImageLoader.loadFromResource("/icon.png"); + setIconImage(image); + final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + setBounds(10, 10, screenSize.width - 20, screenSize.height - 40); + + myLayoutFocusTraversalPolicy = new LayoutFocusTraversalPolicyExt(); + setFocusTraversalPolicy(myLayoutFocusTraversalPolicy); + + setupCloseAction(); + myActionManager = actionManager; + } + + /** + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * + * THIS IS AN "ABSOLUTELY-GURU METHOD". + * NOBODY SHOULD ADD OTHER USAGES OF IT :) + * ONLY ANTON AND VOVA ARE PERMITTED TO USE THIS METHOD!!! + * + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + * !!!!! CAUTION !!!!! + */ + public final void setDefaultFocusableComponent(final JComponent component) { + myLayoutFocusTraversalPolicy.setOverridenDefaultComponent(component); + } + +// Made protected for Fabrique + protected void setupCloseAction() { + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener( + new WindowAdapter() { + public void windowClosing(final WindowEvent e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length > 1) { + ProjectUtil.closeProject(myProject); + RecentProjectsManager.getInstance().updateLastProjectPath(); + } + else { + ApplicationManagerEx.getApplicationEx().exit(); + } + } + }, ModalityState.NON_MMODAL); + } + } + ); + } + + public StatusBarEx getStatusBar() { + return ((IdeRootPane)getRootPane()).getStatusBar(); + } + + public void updateToolbar() { + ((IdeRootPane)getRootPane()).updateToolbar(); + } + + public void setTitle(final String title) { + myTitle = title; + updateTitle(); + } + + protected void setFrameTitle(final String text) { + super.setTitle(text); + } + + public void setFileTitle(final VirtualFile file) { + myFileTitle = file != null ? calcFileTitle(file) : null; + updateTitle(); + } + + private String calcFileTitle(final VirtualFile file) { + final String url = file.getPresentableUrl(); + if (myProject == null) { + return url; + } + else { + final Module module = VfsUtil.getModuleForFile(myProject, file); + if (module == null) return url; + return new StringBuffer().append("[").append(module.getName()).append("] - ").append(url).toString(); + } + } + + private void updateTitle() { + final StringBuffer sb = new StringBuffer(); + if (myTitle != null && myTitle.length() > 0) { + sb.append(myTitle); + sb.append(" - "); + } + if (myFileTitle != null && myFileTitle.length() > 0) { + sb.append(myFileTitle); + sb.append(" - "); + } + sb.append(((ApplicationInfoEx)ApplicationInfo.getInstance()).getFullApplicationName()); + setFrameTitle(sb.toString()); + } + + public Object getData(final String dataId) { + if (DataConstants.PROJECT.equals(dataId)) { + return myProject; + } + return null; + } + + public void setProject(final Project project) { + myProject = project; + } + + public Project getProject() { + return myProject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeMenuBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeMenuBar.java new file mode 100644 index 00000000000..ec296287731 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeMenuBar.java @@ -0,0 +1,167 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.TimerListener; +import com.intellij.openapi.actionSystem.impl.ActionMenu; +import com.intellij.openapi.actionSystem.impl.PresentationFactory; +import com.intellij.openapi.actionSystem.impl.WeakTimerListener; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.ex.KeymapManagerListener; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ + +// Made non-final public for Fabrique +public class IdeMenuBar extends JMenuBar{ + private final MyTimerListener myTimerListener; + private final MyKeymapManagerListener myKeymapManagerListener; + private final DefaultActionGroup myActionGroup; + private ArrayList myVisibleActions; + private ArrayList myNewVisibleActions; + private final PresentationFactory myPresentationFactory; + private DataManager myDataManager; + private ActionManager myActionManager; + private KeymapManager myKeymapManager; + + public IdeMenuBar(ActionManager actionManager, DataManager dataManager, KeymapManager keymapManager){ + myActionManager = actionManager; + myTimerListener=new MyTimerListener(); + myKeymapManagerListener=new MyKeymapManagerListener(); + myActionGroup = (DefaultActionGroup)actionManager.getAction(IdeActions.GROUP_MAIN_MENU); + myVisibleActions = new ArrayList(); + myNewVisibleActions = new ArrayList(); + myPresentationFactory = new PresentationFactory(); + myDataManager = dataManager; + myKeymapManager = keymapManager; + } + + /** + * Invoked when enclosed frame is being shown. + */ + public void addNotify(){ + super.addNotify(); + updateActions(); + // Add updater for menus + final ActionManagerEx actionManager=(ActionManagerEx)myActionManager; + actionManager.addTimerListener(1000,new WeakTimerListener(actionManager,myTimerListener)); + ((KeymapManagerEx)myKeymapManager).addKeymapManagerListener(myKeymapManagerListener); + } + + /** + * Invoked when enclosed frame is being disposed. + */ + public void removeNotify(){ + KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(myKeymapManagerListener); + super.removeNotify(); + } + + private void updateActions() { + myNewVisibleActions.clear(); + final DataContext dataContext = ((DataManagerImpl)myDataManager).getDataContextTest(this); + + expandActionGroup(dataContext, myNewVisibleActions, myActionManager); + + if (!myNewVisibleActions.equals(myVisibleActions)) { + // should rebuild UI + + final boolean changeBarVisibility = myNewVisibleActions.size() == 0 || myVisibleActions.size() == 0; + + final ArrayList temp = myVisibleActions; + myVisibleActions = myNewVisibleActions; + myNewVisibleActions = temp; + + removeAll(); + for(int i=0;i0){ + return; + } + + // don't update toolbar if there is currently active modal dialog + + final Window window=KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + if(window instanceof Dialog){ + if (((Dialog)window).isModal()){ + return; + } + } + + updateActions(); + } + } + + private final class MyKeymapManagerListener implements KeymapManagerListener{ + public final void activeKeymapChanged(final Keymap keymap){ + updateMnemonicsVisibility(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeRootPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeRootPane.java new file mode 100644 index 00000000000..77d8c8cde8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/IdeRootPane.java @@ -0,0 +1,137 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.wm.ex.ActionToolbarEx; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.impl.status.StatusBarImpl; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.KeymapManager; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ + +// Made public and non-final for Fabrique +public class IdeRootPane extends JRootPane{ + /** + * Toolbar and status bar. + */ + private JComponent myToolbar; + private StatusBarImpl myStatusBar; + /** + * Current ToolWindowsPane. If there is no such pane then this field is null. + */ + private ToolWindowsPane myToolWindowsPane; + + private final MyUISettingsListenerImpl myUISettingsListener; + private JPanel myContentPane; + private ActionManager myActionManager; + private UISettings myUISettings; + + IdeRootPane(ActionManager actionManager, UISettings uiSettings, DataManager dataManager, KeymapManager keymapManager){ + myActionManager = actionManager; + myUISettings = uiSettings; + + updateToolbar(); + + createStatusBar(); + updateStatusBarVisibility(); + myContentPane.add(myStatusBar,BorderLayout.SOUTH); + + myUISettingsListener=new MyUISettingsListenerImpl(); + setJMenuBar(new IdeMenuBar(myActionManager, dataManager, keymapManager)); + } + + /** + * Invoked when enclosed frame is being shown. + */ + public final void addNotify(){ + super.addNotify(); + myUISettings.addUISettingsListener(myUISettingsListener); + } + + /** + * Invoked when enclosed frame is being disposed. + */ + public final void removeNotify(){ + myUISettings.removeUISettingsListener(myUISettingsListener); + super.removeNotify(); + } + + /** + * Sets current tool windows pane (panel where all tool windows are located). + * If toolWindowsPane is null then the method just removes + * the current tool windows pane. + */ + final void setToolWindowsPane(final ToolWindowsPane toolWindowsPane){ + final Container contentPane=getContentPane(); + if(myToolWindowsPane!=null){ + contentPane.remove(myToolWindowsPane); + } + myToolWindowsPane=toolWindowsPane; + if(myToolWindowsPane!=null){ + contentPane.add(myToolWindowsPane,BorderLayout.CENTER); + } + } + + protected final Container createContentPane(){ + myContentPane = new JPanel(new BorderLayout()); + myContentPane.setBackground(Color.GRAY); + + return myContentPane; + } + + void updateToolbar() { + if (myToolbar != null) { + myContentPane.remove(myToolbar); + } + myToolbar = createToolbar(); + myContentPane.add(myToolbar,BorderLayout.NORTH); + updateToolbarVisibility(); + myContentPane.revalidate(); + } + + private JComponent createToolbar() { + ActionGroup group = (ActionGroup)myActionManager.getAction(IdeActions.GROUP_MAIN_TOOLBAR); + final ActionToolbarEx toolBar=(ActionToolbarEx)myActionManager.createActionToolbar( + ActionPlaces.MAIN_TOOLBAR, + group, + true + ); + toolBar.setLayoutPolicy(ActionToolbarEx.WRAP_LAYOUT_POLICY); + return toolBar.getComponent(); + } + + private void createStatusBar() { + myStatusBar = new StatusBarImpl(myActionManager, myUISettings); + } + + final StatusBarEx getStatusBar() { + return myStatusBar; + } + + private void updateToolbarVisibility(){ + myToolbar.setVisible(myUISettings.SHOW_MAIN_TOOLBAR); + } + + private void updateStatusBarVisibility(){ + myStatusBar.setVisible(myUISettings.SHOW_STATUS_BAR); + } + + private final class MyUISettingsListenerImpl implements UISettingsListener{ + public final void uiSettingsChanged(final UISettings source){ + updateToolbarVisibility(); + updateStatusBarVisibility(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecorator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecorator.java new file mode 100644 index 00000000000..076c473f30f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -0,0 +1,793 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.ex.KeymapManagerListener; +import com.intellij.openapi.keymap.ex.WeakKeymapManagerListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ToolWindowType; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.ActivatableLineBorder; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.EventListenerList; +import javax.swing.plaf.metal.MetalButtonUI; +import java.awt.*; +import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public final class InternalDecorator extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.InternalDecorator"); + + private static final int DIVIDER_WIDTH = 5; + + /* + * Icons for buttons in the title bar. + */ + private static final Icon ourSlidingIcon = IconLoader.getIcon("/general/sliding.png"); + private static final Icon ourSlidingInactiveIcon = IconLoader.getIcon("/general/slidingInactive.png"); + private static final Icon ourDockedIcon = IconLoader.getIcon("/general/docked.png"); + private static final Icon ourDockedInactiveIcon = IconLoader.getIcon("/general/dockedInactive.png"); + + private static final Icon ourAuthoHideOnIcon = IconLoader.getIcon("/general/autohideOn.png"); + private static final Icon ourAuthoHideOnInactiveIcon = IconLoader.getIcon("/general/autohideOnInactive.png"); + private static final Icon ourAuthoHideOffIcon = IconLoader.getIcon("/general/autohideOff.png"); + private static final Icon ourAuthoHideOffInactiveIcon = IconLoader.getIcon("/general/autohideOffInactive.png"); + + private static final Icon ourHideIcon = IconLoader.getIcon("/general/hideToolWindow.png"); + private static final Icon ourHideInactiveIcon = IconLoader.getIcon("/general/hideToolWindowInactive.png"); + + private static final Icon ourFloatingIcon = IconLoader.getIcon("/general/floating.png"); + private static final Icon ourFloatingInactiveIcon = IconLoader.getIcon("/general/floatingInactive.png"); + private static final Icon ourFixIcon = IconLoader.getIcon("/general/fix.png"); + private static final Icon ourFixInactiveIcon = IconLoader.getIcon("/general/fixInactive.png"); + + private Project myProject; + private WindowInfo myInfo; + private final ToolWindowImpl myToolWindow; + private final MyDivider myDivider; + private final TitlePanel myTitlePanel; + private final ActivatableLineBorder myToolWindowBorder; + private final MyTitleLabel myTitleLabel; + private final MyTitleButton myToggleFloatingModeButton; + private final Separator myFloatingDockSeparator; + private final MyTitleButton myToggleDockModeButton; + private final Separator myDockAutoHideSeparator; + private final MyTitleButton myToggleAutoHideModeButton; + private final Separator myAutoHideHideSeparator; + private final MyTitleButton myHideButton; + private final EventListenerList myListenerList; + /* + * Actions + */ + private final TogglePinnedModeAction myToggleAutoHideModeAction; + private final HideAction myHideAction; + private final ToggleDockModeAction myToggleDockModeAction; + private final ToggleFloatingModeAction myToggleFloatingModeAction; + /** + * Catches all event from tool window and modifies decorator's appearance. + */ + private final ToolWindowHandler myToolWindowHandler; + private final MyKeymapManagerListener myKeymapManagerListener; + private final WeakKeymapManagerListener myWeakKeymapManagerListener; + + InternalDecorator(final Project project, final WindowInfo info, final ToolWindowImpl toolWindow) { + super(new BorderLayout()); + myProject = project; + myToolWindow = toolWindow; + myDivider = new MyDivider(); + myTitlePanel = new TitlePanel(); + myTitleLabel = new MyTitleLabel(); + myToolWindowBorder = new ActivatableLineBorder(); + myToggleFloatingModeButton = new MyTitleButton(); + myToggleDockModeButton = new MyTitleButton(); + myToggleAutoHideModeButton = new MyTitleButton(); + myHideButton = new MyTitleButton(); + myListenerList = new EventListenerList(); + + myToggleFloatingModeAction = new ToggleFloatingModeAction(); + myFloatingDockSeparator = new Separator(); + myFloatingDockSeparator.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); + myToggleDockModeAction = new ToggleDockModeAction(); + myDockAutoHideSeparator = new Separator(); + myToggleAutoHideModeAction = new TogglePinnedModeAction(); + myAutoHideHideSeparator = new Separator(); + myHideAction = new HideAction(); + + myKeymapManagerListener = new MyKeymapManagerListener(); + final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx(); + myWeakKeymapManagerListener = new WeakKeymapManagerListener(keymapManager, myKeymapManagerListener); + keymapManager.addKeymapManagerListener(myWeakKeymapManagerListener); + + init(); + + myToolWindowHandler = new ToolWindowHandler(); + myToolWindow.addPropertyChangeListener(myToolWindowHandler); + + // + + apply(info); + } + + /** + * Applies specified decoration. + */ + public final void apply(final WindowInfo info) { + if (Comparing.equal(myInfo, info)) { + return; + } + myInfo = info; + // Active + final boolean active = info.isActive(); + myTitlePanel.setActive(active, !info.isSliding()); + //todo myToolWindowBorder.setActive(active); + myFloatingDockSeparator.setActive(active); + myDockAutoHideSeparator.setActive(active); + myAutoHideHideSeparator.setActive(active); + // Icon + if (myInfo.isFloating()) { + myTitleLabel.setIcon(myToolWindow.getIcon()); + } + else { + myTitleLabel.setIcon(null); + } + // Anchor + final ToolWindowAnchor anchor = myInfo.getAnchor(); + if (info.isSliding()) { + myDivider.invalidate(); + if (ToolWindowAnchor.TOP == anchor) { + add(myDivider, BorderLayout.SOUTH); + } + else if (ToolWindowAnchor.LEFT == anchor) { + add(myDivider, BorderLayout.EAST); + } + else if (ToolWindowAnchor.BOTTOM == anchor) { + add(myDivider, BorderLayout.NORTH); + } + else if (ToolWindowAnchor.RIGHT == anchor) { + add(myDivider, BorderLayout.WEST); + } + myDivider.setPreferredSize(new Dimension(DIVIDER_WIDTH, DIVIDER_WIDTH)); + } + else { // docked and floating windows don't have divider + remove(myDivider); + } + validate(); + repaint(); + // Type + if (myInfo.isDocked()) { + myToggleFloatingModeButton.setIcon(active ? ourFloatingIcon : ourFloatingInactiveIcon); + myToggleDockModeButton.setVisible(true); + myDockAutoHideSeparator.setVisible(true); + myToggleDockModeButton.setIcon(active ? ourSlidingIcon : ourSlidingInactiveIcon); + myToggleAutoHideModeButton.setVisible(true); + myAutoHideHideSeparator.setVisible(true); + myToggleAutoHideModeButton.setIcon(active ? + (myInfo.isAutoHide() ? ourAuthoHideOnIcon : ourAuthoHideOffIcon) : + (myInfo.isAutoHide() ? ourAuthoHideOnInactiveIcon : ourAuthoHideOffInactiveIcon)); + myHideButton.setVisible(true); + } + else if (myInfo.isFloating()) { + myToggleFloatingModeButton.setIcon(active ? ourFixIcon : ourFixInactiveIcon); + myToggleDockModeButton.setVisible(false); + myDockAutoHideSeparator.setVisible(false); + myToggleAutoHideModeButton.setVisible(true); + myAutoHideHideSeparator.setVisible(true); + myToggleAutoHideModeButton.setIcon(active ? + myInfo.isAutoHide() ? ourAuthoHideOnIcon : ourAuthoHideOffIcon : + myInfo.isAutoHide() ? ourAuthoHideOnInactiveIcon : ourAuthoHideOffInactiveIcon); + myHideButton.setVisible(true); + } + else if (myInfo.isSliding()) { + myToggleFloatingModeButton.setIcon(active ? ourFloatingIcon : ourFloatingInactiveIcon); + myToggleDockModeButton.setVisible(true); + myDockAutoHideSeparator.setVisible(true); + myToggleDockModeButton.setIcon(active ? ourDockedIcon : ourDockedInactiveIcon); + myToggleAutoHideModeButton.setVisible(false); + myAutoHideHideSeparator.setVisible(false); + myHideButton.setVisible(true); + } + myHideButton.setIcon(active ? ourHideIcon : ourHideInactiveIcon); + // + updateTitle(); + updateTooltips(); + + // Push "apply" request forward + + if (myInfo.isFloating() && myInfo.isVisible()) { + final FloatingDecorator floatingDecorator = (FloatingDecorator) SwingUtilities.getAncestorOfClass(FloatingDecorator.class, this); + LOG.assertTrue(floatingDecorator != null); + floatingDecorator.apply(myInfo); + } + } + + final void addInternalDecoratorListener(final InternalDecoratorListener l) { + myListenerList.add(InternalDecoratorListener.class, l); + } + + final void removeInternalDecoratorListener(final InternalDecoratorListener l) { + myListenerList.remove(InternalDecoratorListener.class, l); + } + + final void dispose() { + removeAll(); + myToolWindow.removePropertyChangeListener(myToolWindowHandler); + KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(myWeakKeymapManagerListener); + myProject = null; + } + + private static String getToolTipTextByAction(final String actionId, final String description) { + String text = description; + final String shortcutForAction = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(actionId)); + if (shortcutForAction.length() > 0) { + text += " " + shortcutForAction; + } + return text; + } + + private void fireAnchorChanged(final ToolWindowAnchor anchor) { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].anchorChanged(this, anchor); + } + } + + private void fireAutoHideChanged(final boolean autoHide) { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].autoHideChanged(this, autoHide); + } + } + + /** + * Fires event that "hide" button has been pressed. + */ + final void fireHidden() { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].hidden(this); + } + } + + /** + * Fires event that user performed click into the title bar area. + */ + final void fireActivated() { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].activated(this); + } + } + + private void fireTypeChanged(final ToolWindowType type) { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].typeChanged(this, type); + } + } + + final void fireResized() { + final InternalDecoratorListener[] listeners = (InternalDecoratorListener[]) myListenerList.getListeners(InternalDecoratorListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].resized(this); + } + } + + private void init() { + enableEvents(ComponentEvent.COMPONENT_EVENT_MASK); + // Compose title bar + final Component strut = Box.createHorizontalStrut(3); + myTitlePanel.add(strut, BorderLayout.WEST); + myTitleLabel.setForeground(Color.white); + myTitlePanel.add(myTitleLabel, BorderLayout.CENTER); + + final JPanel buttonPanel = new JPanel(new GridBagLayout()); + buttonPanel.setOpaque(false); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); + buttonPanel.add(myToggleFloatingModeButton, + new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myFloatingDockSeparator, + new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myToggleDockModeButton, + new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myDockAutoHideSeparator, + new GridBagConstraints(3, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myToggleAutoHideModeButton, + new GridBagConstraints(4, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myAutoHideHideSeparator, + new GridBagConstraints(5, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + buttonPanel.add(myHideButton, + new GridBagConstraints(6, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + + myTitlePanel.add(buttonPanel, BorderLayout.EAST); + final JPanel contentPane = new JPanel(new BorderLayout()); + contentPane.setBorder(myToolWindowBorder); + contentPane.add(myTitlePanel, BorderLayout.NORTH); + JPanel innerPanel = new JPanel(new BorderLayout()); + innerPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + JComponent toolWindowComponent = myToolWindow.getComponent(); + innerPanel.add(toolWindowComponent, BorderLayout.CENTER); + contentPane.add(innerPanel, BorderLayout.CENTER); + add(contentPane, BorderLayout.CENTER); + + // Add listeners + + myToggleFloatingModeButton.addActionListener(myToggleFloatingModeAction); + myToggleDockModeButton.addActionListener(myToggleDockModeAction); + myToggleAutoHideModeButton.addActionListener(myToggleAutoHideModeAction); + myHideButton.addActionListener(myHideAction); + myTitleLabel.addMouseListener(new PopupHandler() { + public void invokePopup(final Component comp, final int x, final int y) { + final ActionGroup group = createPopupGroup(); + final ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); + popupMenu.getComponent().show(comp, x, y); + } + }); + myTitleLabel.addMouseListener(new MouseAdapter() { + public void mousePressed(final MouseEvent e) { + if (!e.isPopupTrigger()) { + fireActivated(); + } + } + }); + + registerKeyboardAction(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + ToolWindowManager.getInstance(myProject).activateEditorComponent(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + final ActionGroup createPopupGroup() { + final DefaultActionGroup group = new DefaultActionGroup(); + + if (myInfo.isDocked()) { + group.add(myToggleAutoHideModeAction); + group.add(myToggleDockModeAction); + group.add(myToggleFloatingModeAction); + } + else if (myInfo.isFloating()) { + group.add(myToggleAutoHideModeAction); + group.add(myToggleFloatingModeAction); + } + else if (myInfo.isSliding()) { + group.add(myToggleDockModeAction); + group.add(myToggleFloatingModeAction); + } + + final DefaultActionGroup moveGroup = new DefaultActionGroup("Move to", true); + final ToolWindowAnchor anchor = myInfo.getAnchor(); + if (anchor != ToolWindowAnchor.TOP) { + final AnAction topAction = new ChangeAnchorAction("Top", ToolWindowAnchor.TOP); + moveGroup.add(topAction); + } + if (anchor != ToolWindowAnchor.LEFT) { + final AnAction leftAction = new ChangeAnchorAction("Left", ToolWindowAnchor.LEFT); + moveGroup.add(leftAction); + } + if (anchor != ToolWindowAnchor.BOTTOM) { + final AnAction bottomAction = new ChangeAnchorAction("Bottom", ToolWindowAnchor.BOTTOM); + moveGroup.add(bottomAction); + } + if (anchor != ToolWindowAnchor.RIGHT) { + final AnAction rightAction = new ChangeAnchorAction("Right", ToolWindowAnchor.RIGHT); + moveGroup.add(rightAction); + } + group.add(moveGroup); + + group.addSeparator(); + group.add(myHideAction); + return group; + } + + /** + * @return tool window associated with the decorator. + */ + final ToolWindowImpl getToolWindow() { + return myToolWindow; + } + + /** + * @return last window info applied to the decorator. + */ + final WindowInfo getWindowInfo() { + return myInfo; + } + + protected final void processComponentEvent(final ComponentEvent e) { + super.processComponentEvent(e); + if (ComponentEvent.COMPONENT_RESIZED == e.getID()) { + fireResized(); + } + } + + private void updateTitle() { + final StringBuffer fullTitle = new StringBuffer(); + // Due to JDK's bug #4234645 we cannot support custom decoration on Linux platform. + // The prblem is that Window.setLocation() doesn't work properly wjen the dialod is displayable. + // Therefore we use native WM decoration. When the dialog has native decoration we show window ID + // in the dialog's title and window title at the custom title panel. If the custom decoration + // is used we show composite string at the custom title panel. + // TODO[vova] investigate the problem under Mac OSX. + if (SystemInfo.isWindows || !myInfo.isFloating()) { + fullTitle.append(myInfo.getId()); + final String title = myToolWindow.getTitle(); + if (title != null && title.length() > 0) { + fullTitle.append(" - ").append(title); + } + } + else { // Unixes ans MacOSX go here when tool window is in floating mode + final String title = myToolWindow.getTitle(); + if (title != null && title.length() > 0) { + fullTitle.append(title); + } + } + myTitleLabel.setText(fullTitle.toString()); + } + + private void updateTooltips() { + if (myInfo.isDocked()) { + myToggleDockModeButton.setToolTipText(getToolTipTextByAction("ToggleDockMode", "Undock")); + } + else if (myInfo.isSliding()) { + myToggleDockModeButton.setToolTipText(getToolTipTextByAction("ToggleDockMode", "Dock")); + } + myToggleFloatingModeButton.setToolTipText(getToolTipTextByAction("ToggleFloatingMode", myInfo.isFloating() ? "Fix" : "Float")); + myToggleAutoHideModeButton.setToolTipText(getToolTipTextByAction("TogglePinnedMode", myInfo.isAutoHide() ? "Pin" : "Unpin")); + myHideButton.setToolTipText(getToolTipTextByAction("HideActiveWindow", "Hide")); + } + + private final class ChangeAnchorAction extends AnAction { + private final ToolWindowAnchor myAnchor; + + public ChangeAnchorAction(final String title, final ToolWindowAnchor anchor) { + super(title); + myAnchor = anchor; + } + + public final void actionPerformed(final AnActionEvent e) { + fireAnchorChanged(myAnchor); + } + } + + private final class HideAction extends AnAction { + public HideAction() { + copyFrom(ActionManager.getInstance().getAction("HideActiveWindow")); + getTemplatePresentation().setText("Hide"); + } + + public final void actionPerformed(final AnActionEvent e) { + fireHidden(); + } + + public final void update(final AnActionEvent event) { + final Presentation presentation = event.getPresentation(); + presentation.setEnabled(myInfo.isVisible()); + } + } + + private final class TogglePinnedModeAction extends ToggleAction { + public TogglePinnedModeAction() { + copyFrom(ActionManager.getInstance().getAction("TogglePinnedMode")); + } + + public final boolean isSelected(final AnActionEvent event) { + return !myInfo.isAutoHide(); + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + fireAutoHideChanged(!myInfo.isAutoHide()); + } + } + + private final class ToggleDockModeAction extends ToggleAction { + public ToggleDockModeAction() { + copyFrom(ActionManager.getInstance().getAction("ToggleDockMode")); + } + + public final boolean isSelected(final AnActionEvent event) { + return myInfo.isDocked(); + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + if (myInfo.isDocked()) { + fireTypeChanged(ToolWindowType.SLIDING); + } + else if (myInfo.isSliding()) { + fireTypeChanged(ToolWindowType.DOCKED); + } + } + } + + private final class ToggleFloatingModeAction extends ToggleAction { + public ToggleFloatingModeAction() { + copyFrom(ActionManager.getInstance().getAction("ToggleFloatingMode")); + } + + public final boolean isSelected(final AnActionEvent event) { + return myInfo.isFloating(); + } + + public final void setSelected(final AnActionEvent event, final boolean flag) { + if (myInfo.isFloating()) { + fireTypeChanged(myInfo.getInternalType()); + } + else { + fireTypeChanged(ToolWindowType.FLOATING); + } + } + } + + private final class MyDivider extends JPanel { + private boolean myDragging; + private Point myLastPoint; + + public MyDivider() { + myDragging = false; + enableEvents(MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK); + setBorder(new DividerBorder()); + } + + protected final void processMouseMotionEvent(final MouseEvent e) { + super.processMouseMotionEvent(e); + if (MouseEvent.MOUSE_DRAGGED == e.getID()) { + myDragging = true; + final ToolWindowAnchor anchor = myInfo.getAnchor(); + final boolean isVertical = anchor == ToolWindowAnchor.TOP || anchor == ToolWindowAnchor.BOTTOM; + setCursor(isVertical ? Cursor.getPredefinedCursor(9) : Cursor.getPredefinedCursor(11)); + final Point point = e.getPoint(); + + final Container windowPane = InternalDecorator.this.getParent(); + myLastPoint = SwingUtilities.convertPoint(this, point, windowPane); + myLastPoint.x = Math.min(Math.max(myLastPoint.x, 0), windowPane.getWidth()); + myLastPoint.y = Math.min(Math.max(myLastPoint.y, 0), windowPane.getHeight()); + + final Rectangle bounds = InternalDecorator.this.getBounds(); + if (anchor == ToolWindowAnchor.TOP) { + if (myLastPoint.y < DIVIDER_WIDTH) { + myLastPoint.y = DIVIDER_WIDTH; + } + InternalDecorator.this.setBounds(0, 0, bounds.width, myLastPoint.y); + } + else if (anchor == ToolWindowAnchor.LEFT) { + if (myLastPoint.x < DIVIDER_WIDTH) { + myLastPoint.x = DIVIDER_WIDTH; + } + InternalDecorator.this.setBounds(0, 0, myLastPoint.x, bounds.height); + } + else if (anchor == ToolWindowAnchor.BOTTOM) { + if (myLastPoint.y > windowPane.getHeight() - DIVIDER_WIDTH) { + myLastPoint.y = windowPane.getHeight() - DIVIDER_WIDTH; + } + InternalDecorator.this.setBounds(0, myLastPoint.y, bounds.width, windowPane.getHeight() - myLastPoint.y); + } + else if (anchor == ToolWindowAnchor.RIGHT) { + if (myLastPoint.x > windowPane.getWidth() - DIVIDER_WIDTH) { + myLastPoint.x = windowPane.getWidth() - DIVIDER_WIDTH; + } + InternalDecorator.this.setBounds(myLastPoint.x, 0, windowPane.getWidth() - myLastPoint.x, bounds.height); + } + InternalDecorator.this.validate(); + } + } + + protected final void processMouseEvent(final MouseEvent e) { + super.processMouseEvent(e); + final ToolWindowAnchor anchor = myInfo.getAnchor(); + final boolean isVerticalCursor = anchor == ToolWindowAnchor.TOP || anchor == ToolWindowAnchor.BOTTOM; + switch (e.getID()) { + case MouseEvent.MOUSE_MOVED: + default: + break; + case MouseEvent.MOUSE_ENTERED: + setCursor(isVerticalCursor + ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) + : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); + break; + case MouseEvent.MOUSE_EXITED: + if (!myDragging) { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + break; + case MouseEvent.MOUSE_PRESSED: + setCursor(isVerticalCursor + ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) + : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); + break; + case MouseEvent.MOUSE_RELEASED: + myDragging = false; + myLastPoint = null; + break; + case MouseEvent.MOUSE_CLICKED: + break; + } + } + + private final class DividerBorder implements Border { + public final void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { + final ToolWindowAnchor anchor = myInfo.getAnchor(); + final boolean isVertical = anchor == ToolWindowAnchor.TOP || anchor == ToolWindowAnchor.BOTTOM; + if (isVertical) { + if (anchor == ToolWindowAnchor.TOP) { + g.setColor(Color.white); + g.drawLine(x, y, x + width - 1, y); + g.setColor(Color.darkGray); + g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); + } + else { + g.setColor(Color.darkGray); + g.drawLine(x, y, x + width - 1, y); + g.setColor(Color.white); + g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); + } + } + else { + if (anchor == ToolWindowAnchor.LEFT) { + g.setColor(Color.white); + g.drawLine(x, y, x, y + height - 1); + g.setColor(Color.darkGray); + g.drawLine(x + width - 1, y, x + width - 1, y + height - 1); + } + else { + g.setColor(Color.darkGray); + g.drawLine(x, y, x, y + height - 1); + g.setColor(Color.white); + g.drawLine(x + width - 1, y, x + width - 1, y + height - 1); + } + } + } + + public final Insets getBorderInsets(final Component c) { + if (c instanceof MyDivider) { + return new Insets(1, 1, 1, 1); + } + return new Insets(0, 0, 0, 0); + } + + public final boolean isBorderOpaque() { + return true; + } + } + } + + + private final class MyTitleLabel extends JLabel { + private Point myLastPoint; + + public MyTitleLabel() { + enableEvents(MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK); + } + + public void updateUI() { + super.updateUI(); + setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD)); + } + + protected final void processMouseEvent(final MouseEvent e) { + super.processMouseEvent(e); + switch (e.getID()) { + case MouseEvent.MOUSE_PRESSED: + { + myLastPoint = e.getPoint(); + SwingUtilities.convertPointToScreen(myLastPoint, this); + break; + } + } + } + + protected final void processMouseMotionEvent(final MouseEvent e) { + super.processMouseMotionEvent(e); + switch (e.getID()) { + case MouseEvent.MOUSE_DRAGGED: + { + // 1. myLast point can be null due to bugs in Swing. + // 2. do not allow drag enclosed window if ToolWindow isn't floating + if (myLastPoint == null || !myInfo.isFloating()) { + return; + } + final Window window = SwingUtilities.windowForComponent(this); + final Rectangle oldBounds = window.getBounds(); + final Point newPoint = e.getPoint(); + SwingUtilities.convertPointToScreen(newPoint, this); + final Point offset = new Point(newPoint.x - myLastPoint.x, newPoint.y - myLastPoint.y); + window.setLocation(oldBounds.x + offset.x, oldBounds.y + offset.y); + myLastPoint = newPoint; + break; + } + } + } + } + + /** + * Updates tooltips. + */ + private final class MyKeymapManagerListener implements KeymapManagerListener { + public final void activeKeymapChanged(final Keymap keymap) { + updateTooltips(); + } + } + + private static final class MyTitleButton extends FixedSizeButton { + public MyTitleButton() { + super(16); + setBorder(BorderFactory.createEmptyBorder()); + } + + public final void addActionListener(final AnAction action) { + final DataContext dataContext = DataManager.getInstance().getDataContext(this); + + final ActionListener actionListener = new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + actionManager.fireBeforeActionPerformed(action, dataContext); + final Component component = ((Component) dataContext.getData(DataConstantsEx.CONTEXT_COMPONENT)); + if (component != null && !component.isShowing()) { + return; + } + action.actionPerformed(new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation(), + ActionManager.getInstance(), + 0)); + } + }; + + addActionListener(actionListener); + } + + /** + * Some UIs paint only opague buttons. It causes that button has gray background color. + * To prevent this I don't allow to change UI. + */ + public final void updateUI() { + setUI(MetalButtonUI.createUI(this)); + setOpaque(false); + setRolloverEnabled(true); + } + } + + private static final class Separator extends JLabel { + private static final Icon ourActiveSeparator = IconLoader.getIcon("/general/separator.png"); + private static final Icon ourInactiveSeparator = IconLoader.getIcon("/general/inactiveSeparator.png"); + + public final void setActive(final boolean active) { + setIcon(active ? ourActiveSeparator : ourInactiveSeparator); + } + + public final void updateUI() { + super.updateUI(); + setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3)); + } + } + + /** + * Synchronizes decorator with IdeToolWindow changes. + */ + private final class ToolWindowHandler implements PropertyChangeListener { + public final void propertyChange(final PropertyChangeEvent e) { + final String name = e.getPropertyName(); + if (ToolWindowEx.PROP_TITLE.equals(name)) { + updateTitle(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecoratorListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecoratorListener.java new file mode 100644 index 00000000000..1815618ee4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/InternalDecoratorListener.java @@ -0,0 +1,25 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowType; + +import java.util.EventListener; + +/** + * @author Vladimir Kondratyev + */ +interface InternalDecoratorListener extends EventListener{ + + public void anchorChanged(InternalDecorator source,ToolWindowAnchor anchor); + + public void autoHideChanged(InternalDecorator source,boolean autoHide); + + public void hidden(InternalDecorator source); + + public void resized(InternalDecorator source); + + public void activated(InternalDecorator source); + + public void typeChanged(InternalDecorator source,ToolWindowType type); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/SideStack.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/SideStack.java new file mode 100644 index 00000000000..863f67166da --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/SideStack.java @@ -0,0 +1,70 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.wm.ToolWindowAnchor; + +import java.util.Iterator; +import java.util.Stack; + +/** + * This is stack of tool window that were replaced by another tool windows. + * + * @author Vladimir Kondratyev + */ +final class SideStack { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.SideStack"); + private final Stack myStack; + + SideStack() { + myStack = new Stack(); + } + + /** + * Pushes info into the stack. The method stores cloned copy of original info. + */ + void push(final WindowInfo info) { + LOG.assertTrue(info.isDocked()); + LOG.assertTrue(!info.isAutoHide()); + myStack.push(info.copy()); + } + + WindowInfo pop(final ToolWindowAnchor anchor) { + for (int i = myStack.size() - 1; true; i--) { + final WindowInfo info = (WindowInfo)myStack.get(i); + if (anchor == info.getAnchor()) { + myStack.remove(i); + return info; + } + } + } + + /** + * @return true if and only if there is window in the state with the same + * anchor as the specified info. + */ + boolean isEmpty(final ToolWindowAnchor anchor) { + for (int i = myStack.size() - 1; i > -1; i--) { + final WindowInfo info = (WindowInfo)myStack.get(i); + if (anchor == info.getAnchor()) { + return false; + } + } + return true; + } + + /** + * Removes all WindowInfos with the specified id. + */ + void remove(final String id) { + for (Iterator i = myStack.iterator(); i.hasNext();) { + final WindowInfo info = (WindowInfo)i.next(); + if (id.equals(info.getId())) { + i.remove(); + } + } + } + + void clear() { + myStack.clear(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Stripe.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Stripe.java new file mode 100644 index 00000000000..eb7554386cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Stripe.java @@ -0,0 +1,126 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.keymap.ex.KeymapManagerListener; +import com.intellij.openapi.keymap.ex.WeakKeymapManagerListener; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +/** + * @author Eugene Belyaev + */ +final class Stripe extends JPanel{ + private final int myAnchor; + private final ArrayList myButtons = new ArrayList(); + private final MyKeymapManagerListener myKeymapManagerListener; + private final WeakKeymapManagerListener myWeakKeymapManagerListener; + private final MyUISettingsListener myUISettingsListener; + + Stripe(final int anchor){ + super(new GridBagLayout()); + setBackground(new Color(247, 243, 239)); + myAnchor = anchor; + myKeymapManagerListener=new MyKeymapManagerListener(); + myWeakKeymapManagerListener=new WeakKeymapManagerListener(KeymapManagerEx.getInstanceEx(),myKeymapManagerListener); + myUISettingsListener=new MyUISettingsListener(); + } + + /** + * Invoked when enclosed frame is being shown. + */ + public void addNotify(){ + super.addNotify(); + updateText(); + updateState(); + KeymapManagerEx.getInstanceEx().addKeymapManagerListener(myWeakKeymapManagerListener); + UISettings.getInstance().addUISettingsListener(myUISettingsListener); + } + + /** + * Invoked when enclosed frame is being disposed. + */ + public void removeNotify(){ + KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(myWeakKeymapManagerListener); + UISettings.getInstance().removeUISettingsListener(myUISettingsListener); + super.removeNotify(); + } + + void addButton(final StripeButton button,final Comparator comparator){ + myButtons.add(button); + Collections.sort(myButtons,comparator); + rebuild(); + } + + void removeButton(final StripeButton button) { + myButtons.remove(button); + rebuild(); + } + + private void rebuild() { + removeAll(); + if (myAnchor == SwingConstants.TOP || myAnchor == SwingConstants.BOTTOM) { + add(Box.createHorizontalStrut(19)); + int idx=1; + for (Iterator i=myButtons.iterator();i.hasNext();) { + final StripeButton button=(StripeButton)i.next(); + add( + button, + new GridBagConstraints(idx,0,1,1,0,1,GridBagConstraints.WEST,GridBagConstraints.VERTICAL,new Insets(0,0,0,0),0,0) + ); + idx++; + } + add( + Box.createGlue(), + new GridBagConstraints(idx,0,1,1,1,1,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0,0,0,0),0,0) + ); + }else if(myAnchor == SwingConstants.LEFT || myAnchor == SwingConstants.RIGHT) { + for (int i = 0; i < myButtons.size(); i++) { + final StripeButton button=(StripeButton)myButtons.get(i); + add( + button, + new GridBagConstraints(0,i,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0) + ); + } + final GridBagConstraints gc = new GridBagConstraints(); + gc.gridy = myButtons.size(); + gc.weighty = 1; + gc.anchor = GridBagConstraints.NORTH; + add(Box.createGlue(), gc); + } + } + + private void updateText(){ + final int size=myButtons.size(); + for(int i=0;iid + * and short cut registered in the key map. + */ + void updateText(){ + final String toolWindowId = getWindowInfo().getId(); + String text=toolWindowId; + if (UISettings.getInstance().SHOW_WINDOW_SHORTCUTS) { + final int mnemonic=ActivateToolWindowAction.getMnemonicForToolWindow(toolWindowId); + if(mnemonic!=-1){ + text = ((char)mnemonic) + ": " + text; + setMnemonic2(mnemonic); + }else{ + setMnemonic2(0); + } + } + setText(text); + } + + void updateState(){ + final boolean available=myDecorator.getToolWindow().isAvailable(); + if(UISettings.getInstance().ALWAYS_SHOW_WINDOW_BUTTONS){ + setVisible(true); + }else{ + setVisible(available); + } + setEnabled(available); + } + + private final class MyPopupHandler extends PopupHandler{ + public void invokePopup(final Component component,final int x,final int y) { + showPopup(component,x,y); + } + } + + private final class MyPropertyChangeListener implements PropertyChangeListener{ + public void propertyChange(final PropertyChangeEvent e){ + final String name=e.getPropertyName(); + if(ToolWindowEx.PROP_AVAILABLE.equals(name)){ + updateState(); + }else if(ToolWindowEx.PROP_TITLE.equals(name)){ + updateText(); + }else if(ToolWindowEx.PROP_ICON.equals(name)){ + final Icon icon=(Icon)e.getNewValue(); + final Icon disabledIcon=IconLoader.getDisabledIcon(icon); + setIcon(icon); + setDisabledIcon(disabledIcon); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/StripeButtonUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/StripeButtonUI.java new file mode 100644 index 00000000000..99250976f4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/StripeButtonUI.java @@ -0,0 +1,158 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.wm.ToolWindowAnchor; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicGraphicsUtils; +import javax.swing.plaf.metal.MetalToggleButtonUI; +import java.awt.*; +import java.awt.geom.AffineTransform; + +/** + * @author Vladimir Kondratyev + */ +final class StripeButtonUI extends MetalToggleButtonUI{ + private static final StripeButtonUI ourInstance=new StripeButtonUI(); + + private static final Rectangle ourIconRect=new Rectangle(); + private static final Rectangle ourTextRect=new Rectangle(); + private static final Rectangle ourViewRect=new Rectangle(); + private static Insets ourViewInsets=new Insets(0,0,0,0); + + private StripeButtonUI(){} + + /** Invoked by reflection */ + public static ComponentUI createUI(final JComponent c){ + return ourInstance; + } + + public Dimension getPreferredSize(final JComponent c){ + final StripeButton button=(StripeButton)c; + final Dimension dim=super.getPreferredSize(button); + + dim.width=(int)(4+dim.width*1.1f); + dim.height+=4; + + final ToolWindowAnchor anchor=button.getWindowInfo().getAnchor(); + if(ToolWindowAnchor.LEFT==anchor||ToolWindowAnchor.RIGHT==anchor){ + return new Dimension(dim.height,dim.width); + } else{ + return dim; + } + } + + public void paint(final Graphics g,final JComponent c){ + final StripeButton button=(StripeButton)c; + + final String text=button.getText(); + final Icon icon=(button.isEnabled()) ? button.getIcon() : button.getDisabledIcon(); + + if((icon==null)&&(text==null)){ + return; + } + + final FontMetrics fm=button.getFontMetrics(button.getFont()); + ourViewInsets=c.getInsets(ourViewInsets); + + ourViewRect.x=ourViewInsets.left; + ourViewRect.y=ourViewInsets.top; + + final ToolWindowAnchor anchor=button.getWindowInfo().getAnchor(); + + // Use inverted height & width + if(ToolWindowAnchor.RIGHT==anchor||ToolWindowAnchor.LEFT==anchor){ + ourViewRect.height=c.getWidth()-(ourViewInsets.left+ourViewInsets.right); + ourViewRect.width=c.getHeight()-(ourViewInsets.top+ourViewInsets.bottom); + } else{ + ourViewRect.height=c.getHeight()-(ourViewInsets.left+ourViewInsets.right); + ourViewRect.width=c.getWidth()-(ourViewInsets.top+ourViewInsets.bottom); + } + + ourIconRect.x=ourIconRect.y=ourIconRect.width=ourIconRect.height=0; + ourTextRect.x=ourTextRect.y=ourTextRect.width=ourTextRect.height=0; + + final String clippedText=SwingUtilities.layoutCompoundLabel( + c,fm,text,icon, + button.getVerticalAlignment(),button.getHorizontalAlignment(), + button.getVerticalTextPosition(),button.getHorizontalTextPosition(), + ourViewRect,ourIconRect,ourTextRect, + button.getText()==null ? 0 : defaultTextIconGap + ); + + // Paint button's background + + final Graphics2D g2=(Graphics2D)g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY); + + final ButtonModel model=button.getModel(); + if (model.isArmed() && model.isPressed() || model.isSelected()) { +// g.setColor(button.getBackground().darker()); +// g.fillRect(0, 0, button.getWidth(), button.getHeight()); + g.setColor(button.getBackground()); + g.fillRect(0, 0, button.getWidth(), button.getHeight()); + g.setColor(button.getBackground().darker()); + g.fillRoundRect(3, 3, button.getWidth() - 6, button.getHeight() - 6, 5, 5); + } else /*if (button.isOpaque())*/ { + g.setColor(button.getBackground()); + g.fillRect(0, 0, button.getWidth(), button.getHeight()); + g.setColor(Color.GRAY); + g.drawRoundRect(3, 3, button.getWidth() - 6, button.getHeight() - 6, 5, 5); + } + + AffineTransform tr=null; + if(ToolWindowAnchor.RIGHT==anchor||ToolWindowAnchor.LEFT==anchor){ + tr=g2.getTransform(); + if(ToolWindowAnchor.RIGHT==anchor){ + if(icon != null){ // do not rotate icon + icon.paintIcon(c, g2, ourIconRect.y, ourIconRect.x); + } + g2.rotate(Math.PI/2); + g2.translate(0,-c.getWidth()); + } else { + if(icon != null){ // do not rotate icon + icon.paintIcon(c, g2, ourIconRect.y, c.getHeight() - ourIconRect.x - icon.getIconHeight()); + } + g2.rotate(-Math.PI/2); + g2.translate(-c.getHeight(),0); + } + } + else{ + if(icon!=null){ + icon.paintIcon(c,g2,ourIconRect.x,ourIconRect.y); + } + } + + // paint text + + if(text!=null){ + if(model.isEnabled()){ + if(model.isArmed()&&model.isPressed()||model.isSelected()){ + g.setColor(button.getBackground()); + } else{ + g.setColor(button.getForeground()); + } + } else{ + g.setColor(button.getBackground().darker()); + } + /* Draw the Text */ + if(model.isEnabled()){ + /*** paint the text normally */ + g.setColor(button.getForeground()); + BasicGraphicsUtils.drawString(g,clippedText,button.getMnemonic2(),ourTextRect.x,ourTextRect.y+fm.getAscent()); + } else{ + /*** paint the text disabled ***/ + if(model.isSelected()){ + g.setColor(c.getBackground()); + } else{ + g.setColor(getDisabledTextColor()); + } + BasicGraphicsUtils.drawString(g,clippedText,button.getMnemonic2(),ourTextRect.x,ourTextRect.y+fm.getAscent()); + } + } + if(ToolWindowAnchor.RIGHT==anchor||ToolWindowAnchor.LEFT==anchor){ + g2.setTransform(tr); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Surface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Surface.java new file mode 100644 index 00000000000..1452e9eb62e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/Surface.java @@ -0,0 +1,134 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.wm.ToolWindowAnchor; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Belyaev + */ +final class Surface extends JComponent { + private final Image myTopImage; + private final Image myBottomImage; + private final double myPixelsPerSec; + private final int myDirection; + private final ToolWindowAnchor myAnchor; + private int myOffset = 0; + + public Surface(final Image topImage, final Image bottomImage, final int direction, final ToolWindowAnchor anchor, final double pixelsPerSec) { + myTopImage = topImage; + myBottomImage = bottomImage; + myAnchor = anchor; + myDirection = direction; + myPixelsPerSec = pixelsPerSec; + setOpaque(true); + } + + public final void runMovement() { + if(!isShowing()){ + return; + } + final int distance; + final Rectangle bounds = getBounds(); + if (myAnchor == ToolWindowAnchor.LEFT || myAnchor == ToolWindowAnchor.RIGHT) { + distance = bounds.width; + } + else { + distance = bounds.height; + } + final double desiredTime = distance / myPixelsPerSec * 1000; + final long startTime = System.currentTimeMillis(); + int count = 0; + myOffset = 0; + + + while(true){ + paintImmediately(0,0,getWidth(),getHeight()); + final long timeSpent = System.currentTimeMillis() - startTime; + count++; + if (timeSpent >= desiredTime) break; + final double onePaintTime = (double)timeSpent / count; + int iterations = (int)((desiredTime - timeSpent) / onePaintTime); + iterations = Math.max(1, iterations); + myOffset += (distance - myOffset) / iterations; + } + } + + public final void paint(final Graphics g) { + final Rectangle bounds = getBounds(); + if (myAnchor == ToolWindowAnchor.LEFT) { + if (myDirection == 1) { + g.setClip(null); + g.clipRect(myOffset, 0, bounds.width - myOffset, bounds.height); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, 0, myOffset, bounds.height); + g.drawImage(myTopImage, myOffset - bounds.width, 0, null); + } + else { + g.setClip(null); + g.clipRect(bounds.width - myOffset, 0, myOffset, bounds.height); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, 0, bounds.width - myOffset, bounds.height); + g.drawImage(myTopImage, -myOffset, 0, null); + } + myTopImage.flush(); + } + else if (myAnchor == ToolWindowAnchor.RIGHT) { + if (myDirection == 1) { + g.setClip(null); + g.clipRect(0, 0, bounds.width - myOffset, bounds.height); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(bounds.width - myOffset, 0, myOffset, bounds.height); + g.drawImage(myTopImage, bounds.width - myOffset, 0, null); + } + else { + g.setClip(null); + g.clipRect(0, 0, myOffset, bounds.height); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(myOffset, 0, bounds.width - myOffset, bounds.height); + g.drawImage(myTopImage, myOffset, 0, null); + } + } + else if (myAnchor == ToolWindowAnchor.TOP) { + if (myDirection == 1) { + g.setClip(null); + g.clipRect(0, myOffset, bounds.width, bounds.height - myOffset); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, 0, bounds.width, myOffset); + g.drawImage(myTopImage, 0, -bounds.height + myOffset, null); + } + else { + g.setClip(null); + g.clipRect(0, bounds.height - myOffset, bounds.width, myOffset); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, 0, bounds.width, bounds.height - myOffset); + g.drawImage(myTopImage, 0, -myOffset, null); + } + } + else if (myAnchor == ToolWindowAnchor.BOTTOM) { + if (myDirection == 1) { + g.setClip(null); + g.clipRect(0, 0, bounds.width, bounds.height - myOffset); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, bounds.height - myOffset, bounds.width, myOffset); + g.drawImage(myTopImage, 0, bounds.height - myOffset, null); + } + else { + g.setClip(null); + g.clipRect(0, 0, bounds.width, myOffset); + g.drawImage(myBottomImage, 0, 0, null); + g.setClip(null); + g.clipRect(0, myOffset, bounds.width, bounds.height - myOffset); + g.drawImage(myTopImage, 0, myOffset, null); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TestWindowManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TestWindowManager.java new file mode 100644 index 00000000000..3b1fbc06956 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TestWindowManager.java @@ -0,0 +1,142 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class TestWindowManager extends WindowManagerEx implements ApplicationComponent{ + private static final StatusBar ourStatusBar = new DummyStatusBar(); + + public final void doNotSuggestAsParent(final Window window) { + } + + public final Window suggestParentWindow(final Project project) { + return null; + } + + public final StatusBar getStatusBar(final Project project) { + return ourStatusBar; + } + + private static final class DummyStatusBar implements StatusBarEx { + public final void setInfo(final String s) {} + + public final String getInfo() { + return null; + } + + public final void setPosition(final String s) {} + + public final void setStatus(final String s) {} + + public final void setStatusEnabled(final boolean enabled) {} + + public final void showCancelButton(final Icon icon, final ActionListener listener, final String tooltopText) {} + + public final void hideCancelButton() {} + + public final void addProgress() {} + + public final void setProgressValue(final int progress) {} + + public final void hideProgress() {} + + public final void setWriteStatus(final boolean locked) {} + + public final void clear() {} + + public final void updatePopupHintsStatus() {} + } + + public final IdeFrame getFrame(final Project project) { + throw new UnsupportedOperationException(); + } + + public final IdeFrame allocateFrame(final Project project) { + throw new UnsupportedOperationException(); + } + + public final void releaseFrame(final IdeFrame frame) { + throw new UnsupportedOperationException(); + } + + public final Component getFocusedComponent(final Window window) { + throw new UnsupportedOperationException(); + } + + public final Component getFocusedComponent(final Project project) { + throw new UnsupportedOperationException(); + } + + public final Window getMostRecentFocusedWindow() { + return null; + } + + public final CommandProcessor getCommandProcessor() { + throw new UnsupportedOperationException(); + } + + public final DesktopLayout getLayout() { + throw new UnsupportedOperationException(); + } + + public final void setLayout(final DesktopLayout layout) { + throw new UnsupportedOperationException(); + } + + public final void dispatchComponentEvent(final ComponentEvent e) { + throw new UnsupportedOperationException(); + } + + public final Rectangle getScreenBounds() { + throw new UnsupportedOperationException(); + } + + public final boolean isInsideScreenBounds(final int x, final int y, final int width) { + throw new UnsupportedOperationException(); + } + + public final boolean isInsideScreenBounds(final int x, final int y) { + throw new UnsupportedOperationException(); + } + + public final boolean isAlphaModeSupported() { + throw new UnsupportedOperationException(); + } + + public final void setAlphaModeRatio(final Window window, final float ratio) { + throw new UnsupportedOperationException(); + } + + public final boolean isAlphaModeEnabled(final Window window) { + throw new UnsupportedOperationException(); + } + + public final void setAlphaModeEnabled(final Window window, final boolean state) { + throw new UnsupportedOperationException(); + } + + public void hideDialog(JDialog dialog, Project project) { + dialog.dispose(); + } + + public final String getComponentName() { + return "TestWindowManager"; + } + + public final void initComponent() { } + + public final void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TitlePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TitlePanel.java new file mode 100644 index 00000000000..d504066d5d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/TitlePanel.java @@ -0,0 +1,167 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class TitlePanel extends JPanel { + private final Color BND_ENABLE_COLOR = new Color(105, 128, 180); + private final Color BND_DISABLE_COLOR = new Color(160, 160, 160); + + private final Color CNT_ENABLE_COLOR = new Color(120, 144, 192); + private final Color CNT_DISABLE_COLOR = new Color(184, 184, 184); + + private static final int DELAY = 5; // Delay between frames + private static final int TOTAL_FRAME_COUNT = 7; // Total number of frames in animation sequence + + private int myCurrentFrame; + + private float myBndStartRed, myBndStartGreen, myBndStartBlue; // start boundary color for animation + private float myBndEndRed, myBndEndGreen, myBndEndBlue; // end boundary color for animation + private Color myBndColor; // current boundary color + + private float myCntStartRed, myCntStartGreen, myCntStartBlue; // start center color for animation + private float myCntEndRed, myCntEndGreen, myCntEndBlue; // end center color for animation + private Color myCntColor; // current center color + + private final Alarm myFrameTicker; // Determines moments of rendering of next frame + private final MyAnimator myAnimator; // Renders panel's color + private boolean myActive = true; + + TitlePanel() { + super(new BorderLayout()); + myFrameTicker = new Alarm(); + myAnimator = new MyAnimator(); + setLayout(new BorderLayout()); + + // Initial boundary color + + myBndStartRed = BND_DISABLE_COLOR.getRed(); + myBndStartGreen = BND_DISABLE_COLOR.getGreen(); + myBndStartBlue = BND_DISABLE_COLOR.getBlue(); + + myBndEndRed = BND_ENABLE_COLOR.getRed(); + myBndEndGreen = BND_ENABLE_COLOR.getGreen(); + myBndEndBlue = BND_ENABLE_COLOR.getBlue(); + + // Initial center color + + myCntStartRed = CNT_DISABLE_COLOR.getRed(); + myCntStartGreen = CNT_DISABLE_COLOR.getGreen(); + myCntStartBlue = CNT_DISABLE_COLOR.getBlue(); + + myCntEndRed = CNT_ENABLE_COLOR.getRed(); + myCntEndGreen = CNT_ENABLE_COLOR.getGreen(); + myCntEndBlue = CNT_ENABLE_COLOR.getBlue(); + + myCurrentFrame = TOTAL_FRAME_COUNT; + updateColor(); + } + + public final void setActive(final boolean active, boolean animate) { + if (active == myActive) { + return; + } + myActive = active; + myFrameTicker.cancelAllRequests(); + if (myCurrentFrame > 0) { // reverse rendering + myCurrentFrame = TOTAL_FRAME_COUNT - myCurrentFrame; + } + if (active) { + + // Boundary color + + myBndStartRed = BND_DISABLE_COLOR.getRed(); + myBndStartGreen = BND_DISABLE_COLOR.getGreen(); + myBndStartBlue = BND_DISABLE_COLOR.getBlue(); + + myBndEndRed = BND_ENABLE_COLOR.getRed(); + myBndEndGreen = BND_ENABLE_COLOR.getGreen(); + myBndEndBlue = BND_ENABLE_COLOR.getBlue(); + + // Center color + + myCntStartRed = CNT_DISABLE_COLOR.getRed(); + myCntStartGreen = CNT_DISABLE_COLOR.getGreen(); + myCntStartBlue = CNT_DISABLE_COLOR.getBlue(); + + myCntEndRed = CNT_ENABLE_COLOR.getRed(); + myCntEndGreen = CNT_ENABLE_COLOR.getGreen(); + myCntEndBlue = CNT_ENABLE_COLOR.getBlue(); + } + else { + + // Boundary color + + myBndStartRed = BND_ENABLE_COLOR.getRed(); + myBndStartGreen = BND_ENABLE_COLOR.getGreen(); + myBndStartBlue = BND_ENABLE_COLOR.getBlue(); + + myBndEndRed = BND_DISABLE_COLOR.getRed(); + myBndEndGreen = BND_DISABLE_COLOR.getGreen(); + myBndEndBlue = BND_DISABLE_COLOR.getBlue(); + + // Center color + + myCntStartRed = CNT_ENABLE_COLOR.getRed(); + myCntStartGreen = CNT_ENABLE_COLOR.getGreen(); + myCntStartBlue = CNT_ENABLE_COLOR.getBlue(); + + myCntEndRed = CNT_DISABLE_COLOR.getRed(); + myCntEndGreen = CNT_DISABLE_COLOR.getGreen(); + myCntEndBlue = CNT_DISABLE_COLOR.getBlue(); + } + if (animate) { + myFrameTicker.addRequest(myAnimator, DELAY); + } + } + + private void updateColor() { + + // Update boundary color + + final int bndRed = (int) (myBndStartRed + (float) myCurrentFrame * (myBndEndRed - myBndStartRed) / TOTAL_FRAME_COUNT); + final int bndGreen = (int) (myBndStartGreen + (float) myCurrentFrame * (myBndEndGreen - myBndStartGreen) / TOTAL_FRAME_COUNT); + final int bndBlue = (int) (myBndStartBlue + (float) myCurrentFrame * (myBndEndBlue - myBndStartBlue) / TOTAL_FRAME_COUNT); + myBndColor = new Color(Math.max(0, Math.min(bndRed, 255)), + Math.max(0, Math.min(bndGreen, 255)), + Math.max(0, Math.min(bndBlue, 255))); + + // Update center color + + final int cntRed = (int) (myCntStartRed + (float) myCurrentFrame * (myCntEndRed - myCntStartRed) / TOTAL_FRAME_COUNT); + final int cntGreen = (int) (myCntStartGreen + (float) myCurrentFrame * (myCntEndGreen - myCntStartGreen) / TOTAL_FRAME_COUNT); + final int cntBlue = (int) (myCntStartBlue + (float) myCurrentFrame * (myCntEndBlue - myCntStartBlue) / TOTAL_FRAME_COUNT); + myCntColor = new Color(Math.max(0, Math.min(cntRed, 255)), + Math.max(0, Math.min(cntGreen, 255)), + Math.max(0, Math.min(cntBlue, 255))); + } + + protected final void paintComponent(final Graphics g) { + super.paintComponent(g); + final Graphics2D g2d = (Graphics2D) g; + g2d.setPaint(new GradientPaint(0, 0, myBndColor, 0, getHeight() / 2, myCntColor)); + g2d.fillRect(0, 0, getWidth(), getHeight() / 2); + g2d.setPaint(new GradientPaint(0, getHeight() / 2, myCntColor, 0, getHeight() - 1, myBndColor)); + g2d.fillRect(0, getHeight() / 2, getWidth(), getHeight() - 1); + } + + private final class MyAnimator implements Runnable { + public void run() { + updateColor(); + paintImmediately(0, 0, getWidth(), getHeight()); + if (myCurrentFrame <= TOTAL_FRAME_COUNT) { + myCurrentFrame++; + myFrameTicker.addRequest(this, DELAY); + } + else { + myFrameTicker.cancelAllRequests(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowImpl.java new file mode 100644 index 00000000000..5291764873c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -0,0 +1,178 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowType; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.ui.content.ContentManager; +import com.intellij.ide.impl.ContentManagerWatcher; + +import javax.swing.*; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ToolWindowImpl implements ToolWindowEx{ + private final PropertyChangeSupport myChangeSupport; + private final ToolWindowManagerImpl myToolWindowManager; + private final String myId; + private Icon myIcon; + private final JComponent myComponent; + private boolean myAvailable; + private String myTitle; + + ToolWindowImpl( + final ToolWindowManagerImpl toolWindowManager, + final String id, + final JComponent component + ){ + myToolWindowManager=toolWindowManager; + myChangeSupport=new PropertyChangeSupport(this); + myId=id; + myComponent=component; + myAvailable = true; + } + + public final void addPropertyChangeListener(final PropertyChangeListener l) { + myChangeSupport.addPropertyChangeListener(l); + } + + public final void removePropertyChangeListener(final PropertyChangeListener l){ + myChangeSupport.removePropertyChangeListener(l); + } + + public final void activate(final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.activateToolWindow(myId); + if (runnable != null) { + myToolWindowManager.invokeLater(runnable); + } + } + + public final boolean isActive(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.isToolWindowActive(myId); + } + + public final void show(final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.showToolWindow(myId); + if (runnable != null) { + myToolWindowManager.invokeLater(runnable); + } + } + + public final void hide(final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.hideToolWindow(myId); + if (runnable != null) { + myToolWindowManager.invokeLater(runnable); + } + } + + public final boolean isVisible(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.isToolWindowVisible(myId); + } + + public final ToolWindowAnchor getAnchor(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.getToolWindowAnchor(myId); + } + + public final void setAnchor(final ToolWindowAnchor anchor, final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.setToolWindowAnchor(myId,anchor); + if (runnable != null) { + myToolWindowManager.invokeLater(runnable); + } + } + + public final void setAutoHide(final boolean state){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.setToolWindowAutoHide(myId,state); + } + + public final boolean isAutoHide(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.isToolWindowAutoHide(myId); + } + + public final ToolWindowType getType(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.getToolWindowType(myId); + } + + public final void setType(final ToolWindowType type, final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + myToolWindowManager.setToolWindowType(myId,type); + if (runnable != null) { + myToolWindowManager.invokeLater(runnable); + } + } + + public final ToolWindowType getInternalType(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myToolWindowManager.getToolWindowInternalType(myId); + } + + public final void setAvailable(final boolean available,final Runnable runnable){ + ApplicationManager.getApplication().assertIsDispatchThread(); + final Boolean oldAvailable=myAvailable?Boolean.TRUE:Boolean.FALSE; + myAvailable=available; + myChangeSupport.firePropertyChange(PROP_AVAILABLE,oldAvailable,myAvailable?Boolean.TRUE:Boolean.FALSE); + if(runnable!=null){ + myToolWindowManager.invokeLater(runnable); + } + } + + public void installWatcher(ContentManager contentManager) { + new ContentManagerWatcher(this, contentManager); + } + + /** + * @return true if the component passed into constructor is not instance of + * ContentManager class. Otherwise it delegates the functionality to the + * passed content manager. + */ + public final boolean isAvailable(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myAvailable; + } + + public final JComponent getComponent(){ + return myComponent; + } + + public final Icon getIcon(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myIcon; + } + + final String getId(){ + return myId; + } + + public final String getTitle(){ + ApplicationManager.getApplication().assertIsDispatchThread(); + return myTitle; + } + + public final void setIcon(final Icon icon){ + ApplicationManager.getApplication().assertIsDispatchThread(); + final Icon oldIcon=myIcon; + myIcon=icon; + myChangeSupport.firePropertyChange(PROP_ICON,oldIcon,myIcon); + } + + public final void setTitle(final String title){ + ApplicationManager.getApplication().assertIsDispatchThread(); + final String oldTitle=myTitle; + myTitle=title; + myChangeSupport.firePropertyChange(PROP_TITLE,oldTitle,myTitle); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java new file mode 100644 index 00000000000..4bdf70074b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -0,0 +1,1207 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.Patches; +import com.intellij.ide.ui.LafManager; +import com.intellij.ide.ui.LafManagerListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.*; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.ex.ToolWindowManagerListener; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.commands.*; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements ProjectComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.ToolWindowManagerImpl"); + + private final Project myProject; + private final EventListenerList myListenerList; + private final DesktopLayout myLayout; + private final HashMap myId2InternalDecorator; + private final HashMap myId2FloatingDecorator; + private final HashMap myId2StripeButton; + private final HashMap myId2FocusWatcher; + + private final EditorComponentFocusWatcher myEditorComponentFocusWatcher; + private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener; + private final InternalDecoratorListener myInternalDecoratorListener; + private final MyUIManagerPropertyChangeListener myUIManagerPropertyChangeListener; + private final MyLafManagerListener myLafManagerListener; + + private boolean myEditorComponentActive; + private final ActiveStack myActiveStack; + private final SideStack mySideStack; + + private ToolWindowsPane myToolWindowsPane; + private IdeFrame myFrame; + + /** + * invoked by reflection + */ + public ToolWindowManagerImpl(final Project project, WindowManagerEx windowManagerEx) { + myProject = project; + myListenerList = new EventListenerList(); + + myLayout = new DesktopLayout(); + myLayout.copyFrom(windowManagerEx.getLayout()); + + myId2InternalDecorator = new HashMap(); + myId2FloatingDecorator = new HashMap(); + myId2StripeButton = new HashMap(); + myId2FocusWatcher = new HashMap(); + + myEditorComponentFocusWatcher = new EditorComponentFocusWatcher(); + myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener(); + myInternalDecoratorListener = new MyInternalDecoratorListener(); + myUIManagerPropertyChangeListener = new MyUIManagerPropertyChangeListener(); + myLafManagerListener = new MyLafManagerListener(); + myEditorComponentActive = false; + myActiveStack = new ActiveStack(); + mySideStack = new SideStack(); + } + + public void initComponent() {} + + public void disposeComponent() {} + + public void projectOpened() { + UIManager.addPropertyChangeListener(myUIManagerPropertyChangeListener); + LafManager.getInstance().addLafManagerListener(myLafManagerListener); + + myFrame = getWindowManager().allocateFrame(myProject); + LOG.assertTrue(myFrame != null); + + final ArrayList commandsList = new ArrayList(); + + myToolWindowsPane = new ToolWindowsPane(myFrame); + ((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(myToolWindowsPane); + appendUpdateToolWindowsPaneCmd(commandsList); + + final VirtualFile projectFile = myProject.getProjectFile(); + if (projectFile != null) { + final VirtualFile parentDir = projectFile.getParent(); + LOG.assertTrue(parentDir != null); + myFrame.setTitle(projectFile.getName() + " - [" + parentDir.getPresentableUrl() + "]"); + } + else { + myFrame.setTitle(myProject.getName()); + } + + final JComponent editorComponent = FileEditorManagerEx.getInstanceEx(myProject).getComponent(); + myEditorComponentFocusWatcher.install(editorComponent); + + appendSetEditorComponentCmd(editorComponent, commandsList); + if (myEditorComponentActive) { + activateEditorComponentImpl(commandsList); + } + execute(commandsList); + } + + public void projectClosed() { + UIManager.removePropertyChangeListener(myUIManagerPropertyChangeListener); + LafManager.getInstance().removeLafManagerListener(myLafManagerListener); + final ArrayList commandsList = new ArrayList(); + final String[] ids = getToolWindowIds(); + + // Remove ToolWindowsPane + + ((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(null); + getWindowManager().releaseFrame(myFrame); + appendUpdateToolWindowsPaneCmd(commandsList); + + + // Hide all tool windows + + for (int i = 0; i < ids.length; i++) { + final String id = ids[i]; + deactivateToolWindowImpl(id, true, commandsList); + } + + // Remove editor component + + final JComponent editorComponent = FileEditorManagerEx.getInstanceEx(myProject).getComponent(); + myEditorComponentFocusWatcher.deinstall(editorComponent); + appendSetEditorComponentCmd(null, commandsList); + execute(commandsList); + } + + public void addToolWindowManagerListener(final ToolWindowManagerListener l) { + myListenerList.add(ToolWindowManagerListener.class, l); + } + + public void removeToolWindowManagerListener(final ToolWindowManagerListener l) { + myListenerList.remove(ToolWindowManagerListener.class, l); + } + + /** + * This is helper method. It delegated its fuctionality to the WindowManager. + * Before delegating it fires state changed. + */ + private void execute(final ArrayList commandList) { + fireStateChanged(); + getWindowManager().getCommandProcessor().execute(commandList); + } + + public void activateEditorComponent() { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: activateEditorComponent()"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + activateEditorComponentImpl(commandList); + execute(commandList); + } + + private void activateEditorComponentImpl(final ArrayList commandList) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: activateEditorComponentImpl()"); + } + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + deactivateToolWindowImpl(info.getId(), + (info.isAutoHide() || info.isSliding()) && !(info.isFloating() && hasModalChild(info)), + commandList); + } + myEditorComponentActive = true; + + // Now we have to request focus into most recent focused editor + appendRequestFocusInEditorComponentCmd(commandList); + myActiveStack.clear(); + } + + /** + * Helper method. It makes window visible, activates it and request focus into the tool window. + * But it doesn't deactivate other tool windows. Use prepareForActivation method to + * deactivates other tool windows. + * + * @param dirtyMode if true then all UI operations are performed in "dirty" mode. + * It means that UI isn't validated and repainted just after each add/remove operation. + * @see ToolWindowManagerImpl#prepareForActivation + */ + private void showAndActivate(final String id, final boolean dirtyMode, final ArrayList commandsList) { + if (!getToolWindow(id).isAvailable()) { + return; + } + // show + showToolWindowImpl(id, dirtyMode, commandsList); + // activate + final WindowInfo info = getInfo(id); + if (!info.isActive()) { + info.setActive(true); + appendApplyWindowInfoCmd(info, commandsList); + myActiveStack.push(id); + myEditorComponentActive = false; + } + appendRequestFocusInToolWindowCmd(id, commandsList); + } + + void activateToolWindow(final String id) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: activateToolWindow(" + id + ")"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + final ArrayList commandList = new ArrayList(); + activateToolWindowImpl(id, commandList); + execute(commandList); + } + + private void activateToolWindowImpl(final String id, final ArrayList commandList) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: activateToolWindowImpl(" + id + ")"); + } + if (!getToolWindow(id).isAvailable()) { + // Tool window can be "logically" active but not focused. For example, + // when the user switched to another application. So we just need to bring + // tool window's window to front. + final InternalDecorator decorator = getInternalDecorator(id); + if (!decorator.hasFocus()) { + appendRequestFocusInToolWindowCmd(id, commandList); + } + return; + } + prepareForActivation(id, commandList); + showAndActivate(id, false, commandList); + } + + /** + * Checkes whether the specified id defines installed tool + * window. If it's not then throws IllegalStateException. + * + * @throws IllegalStateException if tool window isn't installed. + */ + private void checkId(final String id) { + if (!myLayout.isToolWindowRegistered(id)) { + throw new IllegalStateException("window with id=\"" + id + "\" isn't registered"); + } + } + + /** + * Helper method. It deactivates (and hides) window with specified id. + * + * @param id id of the tool window to be deactivated. + * @param shouldHide if true then also hides specified tool window. + */ + private void deactivateToolWindowImpl(final String id, final boolean shouldHide, final java.util.List commandsList) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: deactivateToolWindowImpl(" + id + "," + shouldHide + ")"); + } + final WindowInfo info = getInfo(id); + if (shouldHide && info.isVisible()) { + info.setVisible(false); + if (info.isFloating()) { + appendRemoveFloatingDecoratorCmd(info, commandsList); + } + else { // docked and sliding windows + appendRemoveDecoratorCmd(id, false, commandsList); + } + } + info.setActive(false); + appendApplyWindowInfoCmd(info, commandsList); + } + + public String[] getToolWindowIds() { + ApplicationManager.getApplication().assertIsDispatchThread(); + final WindowInfo[] infos = myLayout.getInfos(); + final String[] ids = new String[infos.length]; + for (int i = 0; i < infos.length; i++) { + ids[i] = infos[i].getId(); + } + return ids; + } + + public String getActiveToolWindowId() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myLayout.getActiveId(); + } + + public String getLastActiveToolWindowId() { + ApplicationManager.getApplication().assertIsDispatchThread(); + String lastActiveToolWindowId = null; + for (int i = 0; i < myActiveStack.getPersistentSize(); i++) { + final String id = myActiveStack.peekPersistent(i); + final ToolWindow toolWindow = getToolWindow(id); + LOG.assertTrue(toolWindow != null); + if (toolWindow.isAvailable()) { + lastActiveToolWindowId = id; + break; + } + } + return lastActiveToolWindowId; + } + + /** + * @return floating decorator for the tool window with specified ID. + */ + private FloatingDecorator getFloatingDecorator(final String id) { + return myId2FloatingDecorator.get(id); + } + + /** + * @return internal decorator for the tool window with specified ID. + */ + private InternalDecorator getInternalDecorator(final String id) { + return myId2InternalDecorator.get(id); + } + + /** + * @return tool button for the window with specified ID. + */ + private StripeButton getStripeButton(final String id) { + return myId2StripeButton.get(id); + } + + /** + * @return info for the tool window with specified ID. + */ + private WindowInfo getInfo(final String id) { + return myLayout.getInfo(id, true); + } + + public ToolWindow getToolWindow(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myLayout.isToolWindowRegistered(id)) { + return null; + } + return getInternalDecorator(id).getToolWindow(); + } + + void showToolWindow(final String id) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: showToolWindow(" + id + ")"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + showToolWindowImpl(id, false, commandList); + execute(commandList); + } + + /** + * @param dirtyMode if true then all UI operations are performed in dirty mode. + */ + private void showToolWindowImpl(final String id, + final boolean dirtyMode, + final java.util.List commandsList) { + final WindowInfo toBeShownInfo = getInfo(id); + if (toBeShownInfo.isVisible() || !getToolWindow(id).isAvailable()) { + return; + } + + toBeShownInfo.setVisible(true); + final InternalDecorator decorator = getInternalDecorator(id); + + if (toBeShownInfo.isFloating()) { + commandsList.add(new AddFloatingDecoratorCmd(decorator, toBeShownInfo)); + } + else { // docked and sliding windows + + // If there is tool window on the same side then we have to hide it, i.e. + // clear place for tool window to be shown. + // + // We store WindowInfo of hidden tool window in the SideStack (if the tool window + // is docked and not auto-hide one). Therefore it's possible to restore the + // hidden tool window when showing tool window will be closed. + + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + if (id.equals(info.getId())) { + continue; + } + if ( + info.isVisible() && + info.getType() == toBeShownInfo.getType() && + info.getAnchor() == toBeShownInfo.getAnchor() + ) { + // hide and deactivate tool window + info.setVisible(false); + appendRemoveDecoratorCmd(info.getId(), false, commandsList); + if (info.isActive()) { + info.setActive(false); + } + appendApplyWindowInfoCmd(info, commandsList); + // store WindowInfo into the SideStack + if (info.isDocked() && !info.isAutoHide()) { + mySideStack.push(info); + } + } + } + appendAddDecoratorCmd(decorator, toBeShownInfo, dirtyMode, commandsList); + + // Remove tool window from the SideStack. + + mySideStack.remove(id); + } + + appendApplyWindowInfoCmd(toBeShownInfo, commandsList); + } + + void hideToolWindow(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + final WindowInfo info = getInfo(id); + final ArrayList commandList = new ArrayList(); + final boolean wasActive = info.isActive(); + + // hide and deactivate + + deactivateToolWindowImpl(id, true, commandList); + + // first of all we have to find tool window that was located at the same side and + // was hidden. + + WindowInfo info2 = null; + while (!mySideStack.isEmpty(info.getAnchor())) { + final WindowInfo storedInfo = mySideStack.pop(info.getAnchor()); + final WindowInfo currentInfo = getInfo(storedInfo.getId()); + LOG.assertTrue(currentInfo != null); + // SideStack contains copies of real WindowInfos. It means that + // these stored infos can be invalid. The following loop removes invalid WindowInfos. + if ( + storedInfo.getAnchor() == currentInfo.getAnchor() && + storedInfo.getType() == currentInfo.getType() && + storedInfo.isAutoHide() == currentInfo.isAutoHide() + ) { + info2 = storedInfo; + break; + } + } + if (info2 != null) { + showToolWindowImpl(info2.getId(), false, commandList); + } + + // If we hide currently active tool window then we should activate the previous + // one which is located in the tool window stack. + // Activate another tool window if no active tool window exists and + // window stack is enabled. + + if (wasActive) { + myActiveStack.remove(id, false); // hidden window should be at the top of stack + if (myActiveStack.isEmpty()) { + activateEditorComponentImpl(commandList); + } + else { + final String toBeActivatedId = myActiveStack.pop(); + if (toBeActivatedId != null) { + activateToolWindowImpl(toBeActivatedId, commandList); + } + } + } + + execute(commandList); + } + + public ToolWindow registerToolWindow(final String id, final JComponent component, final ToolWindowAnchor anchor) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: installToolWindow(" + id + "," + component + "," + anchor + "\")"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + if (id == null) { + throw new IllegalArgumentException("window id cannot be null"); + } + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (anchor == null) { + throw new IllegalArgumentException("anchor cannot be null"); + } + if (myLayout.isToolWindowRegistered(id)) { + throw new IllegalArgumentException("window with id=\"" + id + "\" is already registered"); + } + + final WindowInfo info = myLayout.register(id, anchor); + final boolean wasActive = info.isActive(); + final boolean wasVisible = info.isVisible(); + info.setActive(false); + info.setVisible(false); + + // Create decorator + + final ToolWindowImpl toolWindow = new ToolWindowImpl(this, id, component); + final InternalDecorator decorator = new InternalDecorator(myProject, info.copy(), toolWindow); + myId2InternalDecorator.put(id, decorator); + decorator.addInternalDecoratorListener(myInternalDecoratorListener); + toolWindow.addPropertyChangeListener(myToolWindowPropertyChangeListener); + myId2FocusWatcher.put(id, new ToolWindowFocusWatcher(toolWindow)); + + // Create and show tool button + + final StripeButton button = new StripeButton(decorator); + myId2StripeButton.put(id, button); + final ArrayList commandsList = new ArrayList(); + appendAddButtonCmd(button, info, commandsList); + + // If preloaded info is visible or active then we have to show/activate the installed + // tool window. This step has sense only for windows which are not in the autohide + // mode. But if tool window was active but its mode doen't allow to activate it again + // (for example, tool window is in autohide mode) then we just activate editor component. + + if (!info.isAutoHide() && (info.isDocked() || info.isFloating())) { + if (wasActive) { + activateToolWindowImpl(info.getId(), commandsList); + } + else if (wasVisible) { + showToolWindowImpl(info.getId(), false, commandsList); + } + } + else if (wasActive) { // tool window was active but it cannot be activate again + activateEditorComponentImpl(commandsList); + } + + execute(commandsList); + fireToolWindowRegistered(id); + return toolWindow; + } + + public void unregisterToolWindow(final String id) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: unregisterToolWindow(" + id + ")"); + } + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myLayout.isToolWindowRegistered(id)) { + throw new IllegalArgumentException("window with id=\"" + id + "\" isn't registered"); + } + final WindowInfo info = getInfo(id); + final ToolWindowEx toolWindow = (ToolWindowEx)getToolWindow(id); + // Save recent appearance of tool window + myLayout.unregister(id); + // Remove decorator and tool button from the screen + final ArrayList commandsList = new ArrayList(); + if (info.isVisible()) { + info.setVisible(false); + if (info.isFloating()) { + appendRemoveFloatingDecoratorCmd(info, commandsList); + } + else { // floating and sliding windows + appendRemoveDecoratorCmd(id, false, commandsList); + } + } + appendRemoveButtonCmd(id, commandsList); + appendApplyWindowInfoCmd(info, commandsList); + execute(commandsList); + // Remove all references on tool window and save its last properties + toolWindow.removePropertyChangeListener(myToolWindowPropertyChangeListener); + myActiveStack.remove(id, true); + mySideStack.remove(id); + // Destroy stripe button + final StripeButton button = getStripeButton(id); + button.dispose(); + myId2StripeButton.remove(id); + // + myId2FocusWatcher.remove(id); + // Destroy decorator + final InternalDecorator decorator = getInternalDecorator(id); + decorator.dispose(); + decorator.removeInternalDecoratorListener(myInternalDecoratorListener); + myId2InternalDecorator.remove(id); + } + + public DesktopLayout getLayout() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myLayout; + } + + public void setLayout(final DesktopLayout layout) { + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + // hide tool window that are invisible in new layout + final WindowInfo[] currentInfos = myLayout.getInfos(); + for (int i = 0; i < currentInfos.length; i++) { + final WindowInfo currentInfo = currentInfos[i]; + final WindowInfo info = layout.getInfo(currentInfo.getId(), false); + if (info == null) { + continue; + } + if (currentInfo.isVisible() && !info.isVisible()) { + deactivateToolWindowImpl(currentInfo.getId(), true, commandList); + } + } + // change anchor of tool windows + for (int i = 0; i < currentInfos.length; i++) { + final WindowInfo currentInfo = currentInfos[i]; + final WindowInfo info = layout.getInfo(currentInfo.getId(), false); + if (info == null) { + continue; + } + if (currentInfo.getAnchor() != info.getAnchor() || currentInfo.getOrder() != info.getOrder()) { + setToolWindowAnchorImpl(currentInfo.getId(), info.getAnchor(), info.getOrder(), commandList); + } + } + // change types of tool windows + for (int i = 0; i < currentInfos.length; i++) { + final WindowInfo currentInfo = currentInfos[i]; + final WindowInfo info = layout.getInfo(currentInfo.getId(), false); + if (info == null) { + continue; + } + if (currentInfo.getType() != info.getType()) { + setToolWindowTypeImpl(currentInfo.getId(), info.getType(), commandList); + } + } + // change auto-hide state + for (int i = 0; i < currentInfos.length; i++) { + final WindowInfo currentInfo = currentInfos[i]; + final WindowInfo info = layout.getInfo(currentInfo.getId(), false); + if (info == null) { + continue; + } + if (currentInfo.isAutoHide() != info.isAutoHide()) { + setToolWindowAutoHideImpl(currentInfo.getId(), info.isAutoHide(), commandList); + } + } + // restore visibility + for (int i = 0; i < currentInfos.length; i++) { + final WindowInfo currentInfo = currentInfos[i]; + final WindowInfo info = layout.getInfo(currentInfo.getId(), false); + if (info == null) { + continue; + } + if (info.isVisible()) { + showToolWindowImpl(currentInfo.getId(), false, commandList); + } + } + // if there is no any active tool window and editor is also inactive + // then activate editor + if (!myEditorComponentActive && getActiveToolWindowId() == null) { + activateEditorComponentImpl(commandList); + } + execute(commandList); + } + + public void invokeLater(final Runnable runnable) { + final ArrayList commandList = new ArrayList(); + commandList.add(new InvokeLaterCmd(runnable, getWindowManager().getCommandProcessor())); + execute(commandList); + } + + public boolean isEditorComponentActive() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myEditorComponentActive; + } + + ToolWindowAnchor getToolWindowAnchor(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).getAnchor(); + } + + void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor) { + ApplicationManager.getApplication().assertIsDispatchThread(); + setToolWindowAnchor(id, anchor, -1); + } + + private void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor, final int order) { + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + setToolWindowAnchorImpl(id, anchor, order, commandList); + execute(commandList); + } + + private void setToolWindowAnchorImpl(final String id, final ToolWindowAnchor anchor, final int order, final ArrayList commandsList) { + checkId(id); + final WindowInfo info = getInfo(id); + if (anchor == info.getAnchor() && order == info.getOrder()) { + return; + } + // if tool window isn't visible or only order number is changed then just remove/add stripe button + if (!info.isVisible() || anchor == info.getAnchor() || info.isFloating()) { + appendRemoveButtonCmd(id, commandsList); + myLayout.setAnchor(id, anchor, order); + // update infos for all window. Actually we have to update only infos affected by + // setAnchor method + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + appendApplyWindowInfoCmd(infos[i], commandsList); + } + appendAddButtonCmd(getStripeButton(id), info, commandsList); + } + else { // for docked and sliding windows we have to move buttons and window's decorators + info.setVisible(false); + appendRemoveDecoratorCmd(id, false, commandsList); + appendRemoveButtonCmd(id, commandsList); + myLayout.setAnchor(id, anchor, order); + // update infos for all window. Actually we have to update only infos affected by + // setAnchor method + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + appendApplyWindowInfoCmd(infos[i], commandsList); + } + appendAddButtonCmd(getStripeButton(id), info, commandsList); + showToolWindowImpl(id, false, commandsList); + if (info.isActive()) { + appendRequestFocusInToolWindowCmd(id, commandsList); + } + } + } + + ToolWindowType getToolWindowInternalType(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).getInternalType(); + } + + ToolWindowType getToolWindowType(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).getType(); + } + + private void fireToolWindowRegistered(final String id) { + final ToolWindowManagerListener[] listeners = (ToolWindowManagerListener[])myListenerList.getListeners(ToolWindowManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].toolWindowRegistered(id); + } + } + + private void fireStateChanged() { + final ToolWindowManagerListener[] listeners = (ToolWindowManagerListener[])myListenerList.getListeners(ToolWindowManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].stateChanged(); + } + } + + boolean isToolWindowActive(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).isActive(); + } + + boolean isToolWindowAutoHide(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).isAutoHide(); + } + + boolean isToolWindowVisible(final String id) { + ApplicationManager.getApplication().assertIsDispatchThread(); + checkId(id); + return getInfo(id).isVisible(); + } + + void setToolWindowAutoHide(final String id, final boolean autoHide) { + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + setToolWindowAutoHideImpl(id, autoHide, commandList); + execute(commandList); + } + + private void setToolWindowAutoHideImpl(final String id, final boolean autoHide, final ArrayList commandsList) { + checkId(id); + final WindowInfo info = getInfo(id); + if (info.isAutoHide() == autoHide) { + return; + } + info.setAutoHide(autoHide); + appendApplyWindowInfoCmd(info, commandsList); + if (info.isVisible()) { + prepareForActivation(id, commandsList); + showAndActivate(id, false, commandsList); + } + } + + void setToolWindowType(final String id, final ToolWindowType type) { + ApplicationManager.getApplication().assertIsDispatchThread(); + final ArrayList commandList = new ArrayList(); + setToolWindowTypeImpl(id, type, commandList); + execute(commandList); + } + + private void setToolWindowTypeImpl(final String id, final ToolWindowType type, final ArrayList commandsList) { + checkId(id); + final WindowInfo info = getInfo(id); + if (info.getType() == type) { + return; + } + if (info.isVisible()) { + final boolean dirtyMode = info.isDocked() || info.isSliding(); + info.setVisible(false); + if (info.isFloating()) { + appendRemoveFloatingDecoratorCmd(info, commandsList); + } + else { // docked and sliding windows + appendRemoveDecoratorCmd(id, dirtyMode, commandsList); + } + info.setType(type); + appendApplyWindowInfoCmd(info, commandsList); + prepareForActivation(id, commandsList); + showAndActivate(id, dirtyMode, commandsList); + appendUpdateToolWindowsPaneCmd(commandsList); + } + else { + info.setType(type); + appendApplyWindowInfoCmd(info, commandsList); + } + } + + private void appendApplyWindowInfoCmd(final WindowInfo info, final java.util.List commandsList) { + final StripeButton button = getStripeButton(info.getId()); + final InternalDecorator decorator = getInternalDecorator(info.getId()); + commandsList.add(new ApplyWindowInfoCmd(info, button, decorator, getWindowManager().getCommandProcessor())); + } + + /** + * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddDecoratorCmd + */ + private void appendAddDecoratorCmd(final InternalDecorator decorator, + final WindowInfo info, + final boolean dirtyMode, + final java.util.List commandsList) { + final CommandProcessor commandProcessor = getWindowManager().getCommandProcessor(); + final FinalizableCommand command = myToolWindowsPane.createAddDecoratorCmd(decorator, info, dirtyMode, commandProcessor); + commandsList.add(command); + } + + /** + * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createRemoveDecoratorCmd + */ + private void appendRemoveDecoratorCmd(final String id, final boolean dirtyMode, final java.util.List commandsList) { + final FinalizableCommand command = myToolWindowsPane.createRemoveDecoratorCmd(id, dirtyMode, getWindowManager().getCommandProcessor()); + commandsList.add(command); + } + + private void appendRemoveFloatingDecoratorCmd(final WindowInfo info, final java.util.List commandsList) { + final RemoveFloatingDecoratorCmd command = new RemoveFloatingDecoratorCmd(info); + commandsList.add(command); + } + + /** + * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddButtonCmd + */ + private void appendAddButtonCmd(final StripeButton button, final WindowInfo info, final java.util.List commandsList) { + final Comparator comparator = myLayout.comparator(info.getAnchor()); + final CommandProcessor commandProcessor = getWindowManager().getCommandProcessor(); + final FinalizableCommand command = myToolWindowsPane.createAddButtonCmd(button, info, comparator, commandProcessor); + commandsList.add(command); + } + + /** + * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddButtonCmd + */ + private void appendRemoveButtonCmd(final String id, final java.util.List commandsList) { + final FinalizableCommand command = myToolWindowsPane.createRemoveButtonCmd(id, getWindowManager().getCommandProcessor()); + commandsList.add(command); + } + + private void appendRequestFocusInEditorComponentCmd(final ArrayList commandList) { + final CommandProcessor commandProcessor = getWindowManager().getCommandProcessor(); + final RequestFocusInEditorComponentCmd command = new RequestFocusInEditorComponentCmd(FileEditorManagerEx.getInstanceEx(myProject), + commandProcessor); + commandList.add(command); + } + + private void appendRequestFocusInToolWindowCmd(final String id, final ArrayList commandList) { + final ToolWindowImpl toolWindow = (ToolWindowImpl)getToolWindow(id); + final FocusWatcher focusWatcher = myId2FocusWatcher.get(id); + commandList.add(new RequestFocusInToolWindowCmd(toolWindow, focusWatcher, getWindowManager().getCommandProcessor())); + } + + /** + * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createSetEditorComponentCmd + */ + private void appendSetEditorComponentCmd(final JComponent component, final java.util.List commandsList) { + final CommandProcessor commandProcessor = getWindowManager().getCommandProcessor(); + final FinalizableCommand command = myToolWindowsPane.createSetEditorComponentCmd(component, commandProcessor); + commandsList.add(command); + } + + private void appendUpdateToolWindowsPaneCmd(final java.util.List commandsList) { + final JRootPane rootPane = myFrame.getRootPane(); + final FinalizableCommand command = new UpdateRootPaneCmd(rootPane, getWindowManager().getCommandProcessor()); + commandsList.add(command); + } + + private static WindowManagerEx getWindowManager() { + return WindowManagerEx.getInstanceEx(); + } + + /** + * @return true if tool window with the specified id + * is floating and has modal showing child dialog. Such windows should not be closed + * when auto-hide windows are gone. + */ + private boolean hasModalChild(final WindowInfo info) { + if (!info.isVisible() || !info.isFloating()) { + return false; + } + final FloatingDecorator decorator = getFloatingDecorator(info.getId()); + LOG.assertTrue(decorator != null); + return isModalOrHasModalChild(decorator); + } + + private static boolean isModalOrHasModalChild(final Window window) { + if (window instanceof Dialog) { + final Dialog dialog = (Dialog)window; + if (dialog.isModal() && dialog.isShowing()) { + return true; + } + final Window[] ownedWindows = dialog.getOwnedWindows(); + for (int i = ownedWindows.length - 1; i >= 0; i--) { + if (isModalOrHasModalChild(ownedWindows[i])) { + return true; + } + } + } + return false; + } + + /** + * Helper method. It deactivates all tool windows excepting the tool window + * which should be activated. + */ + private void prepareForActivation(final String id, final java.util.List commandList) { + final WindowInfo toBeActivatedInfo = getInfo(id); + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + if (id.equals(info.getId())) { + continue; + } + if (toBeActivatedInfo.isDocked() || toBeActivatedInfo.isSliding()) { + deactivateToolWindowImpl(info.getId(), info.isAutoHide() || info.isSliding(), commandList); + } + else { // floating window is being activated + deactivateToolWindowImpl(info.getId(), + info.isAutoHide() && info.isFloating() && !hasModalChild(info), + commandList) + ; + } + } + } + + public void clearSideStack() { + mySideStack.clear(); + } + + public void readExternal(final org.jdom.Element element) { + for (Iterator i = element.getChildren().iterator(); i.hasNext();) { + final Element e = (Element)i.next(); + if ("editor".equals(e.getName())) { + myEditorComponentActive = Boolean.valueOf(e.getAttributeValue("active")).booleanValue(); + } + else if (DesktopLayout.TAG.equals(e.getName())) { // read layout of tool windows + myLayout.readExternal(e); + } + } + } + + public void writeExternal(final Element element) { + if (myFrame == null) { + // do nothing if the project was not opened + return; + } + final String[] ids = getToolWindowIds(); + + // Update size of all open floating windows. See SCR #18439 + for (int i = 0; i < ids.length; i++) { + final String id = ids[i]; + final WindowInfo info = getInfo(id); + if (info.isVisible()) { + final InternalDecorator decorator = getInternalDecorator(id); + LOG.assertTrue(decorator != null); + decorator.fireResized(); + } + } + + // Save frame's bounds + final Rectangle frameBounds = myFrame.getBounds(); + final Element frameElement = new Element("frame"); + element.addContent(frameElement); + frameElement.setAttribute("x", Integer.toString(frameBounds.x)); + frameElement.setAttribute("y", Integer.toString(frameBounds.y)); + frameElement.setAttribute("width", Integer.toString(frameBounds.width)); + frameElement.setAttribute("height", Integer.toString(frameBounds.height)); + frameElement.setAttribute("extended-state", Integer.toString(myFrame.getExtendedState())); + // Save whether editor is active or not + final Element editorElement = new Element("editor"); + editorElement.setAttribute("active", myEditorComponentActive ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); + element.addContent(editorElement); + // Save layout of tool windows + final Element layoutElement = new Element(DesktopLayout.TAG); + element.addContent(layoutElement); + myLayout.writeExternal(layoutElement); + } + + /** + * This command creates and shows FloatingDecorator. + */ + private final class AddFloatingDecoratorCmd extends FinalizableCommand { + private final FloatingDecorator myFloatingDecorator; + + /** + * Creates floating decorator for specified floating decorator. + */ + public AddFloatingDecoratorCmd(final InternalDecorator decorator, final WindowInfo info) { + super(getWindowManager().getCommandProcessor()); + myFloatingDecorator = new FloatingDecorator(myFrame, info.copy(), decorator); + myId2FloatingDecorator.put(info.getId(), myFloatingDecorator); + final Rectangle bounds = info.getFloatingBounds(); + if ( + bounds != null && + bounds.width > 0 && + bounds.height > 0 && + getWindowManager().isInsideScreenBounds(bounds.x, bounds.y, bounds.width) + ) { + myFloatingDecorator.setBounds(bounds); + } + else { // place new frame at the center of main frame if there are no floating bounds + Dimension size = decorator.getSize(); + if (size.width == 0 || size.height == 0) { + size = decorator.getPreferredSize(); + } + myFloatingDecorator.setSize(size); + myFloatingDecorator.setLocationRelativeTo(myFrame); + } + } + + public void run() { + try { + myFloatingDecorator.show(); + } + finally { + finish(); + } + } + } + + /** + * This command hides and destroys floating decorator for tool window + * with specified ID. + */ + private final class RemoveFloatingDecoratorCmd extends FinalizableCommand { + private final FloatingDecorator myFloatingDecorator; + + public RemoveFloatingDecoratorCmd(final WindowInfo info) { + super(getWindowManager().getCommandProcessor()); + myFloatingDecorator = getFloatingDecorator(info.getId()); + myId2FloatingDecorator.remove(info.getId()); + info.setFloatingBounds(myFloatingDecorator.getBounds()); + } + + public void run() { + try { + if (Patches.SPECIAL_WINPUT_METHOD_PROCESSING) { + myFloatingDecorator.remove(myFloatingDecorator.getRootPane()); + } + myFloatingDecorator.dispose(); + } + finally { + finish(); + } + } + } + + private final class EditorComponentFocusWatcher extends FocusWatcher { + protected void focusedComponentChanged(final Component component) { + if (getWindowManager().getCommandProcessor().getCommandCount() > 0 || component == null) { + return; + } + // Sometimes focus gained comes when editor is active. For example it can happen when + // user switches between menus or closes some dialog. In that case we just ignore this event, + // i.e. don't initiate deactivation of tool windows and requesting focus in editor. + if (myEditorComponentActive) { + return; + } + invokeLater(// we have to be last listener + new Runnable() { + public void run() { + activateEditorComponent(); + } + }); + } + } + + /** + * Notifies window manager about focus traversal in tool window + */ + private final class ToolWindowFocusWatcher extends FocusWatcher { + private final String myId; + + public ToolWindowFocusWatcher(final ToolWindowImpl toolWindow) { + myId = toolWindow.getId(); + install(toolWindow.getComponent()); + } + + protected void focusedComponentChanged(final Component component) { + if (getWindowManager().getCommandProcessor().getCommandCount() > 0 || component == null) { + return; + } + final WindowInfo info = getInfo(myId); + if (!info.isActive()) { + activateToolWindow(myId); + } + } + } + + /** + * Spies on IdeToolWindow properties and applies them to the window + * state. + */ + private final class MyToolWindowPropertyChangeListener implements PropertyChangeListener { + public void propertyChange(final PropertyChangeEvent e) { + final ToolWindowImpl toolWindow = (ToolWindowImpl)e.getSource(); + if (ToolWindowEx.PROP_AVAILABLE.equals(e.getPropertyName())) { + final WindowInfo info = getInfo(toolWindow.getId()); + if (!toolWindow.isAvailable() && info.isVisible()) { + hideToolWindow(toolWindow.getId()); + } + } + } + } + + /** + * Translates events from InternalDecorator into ToolWindowManager method invocations. + */ + private final class MyInternalDecoratorListener implements InternalDecoratorListener { + public void anchorChanged(final InternalDecorator source, final ToolWindowAnchor anchor) { + setToolWindowAnchor(source.getToolWindow().getId(), anchor); + } + + public void autoHideChanged(final InternalDecorator source, final boolean autoHide) { + setToolWindowAutoHide(source.getToolWindow().getId(), autoHide); + } + + public void hidden(final InternalDecorator source) { + hideToolWindow(source.getToolWindow().getId()); + } + + /** + * Handles event from decorator and modify weight/floating bounds of the + * tool window depending on decoration type. + */ + public void resized(final InternalDecorator source) { + final WindowInfo info = getInfo(source.getToolWindow().getId()); + if (info.isFloating()) { + final Window owner = SwingUtilities.getWindowAncestor(source); + if (owner != null) { + info.setFloatingBounds(owner.getBounds()); + } + } + else { // docked and sliding windows + if (ToolWindowAnchor.TOP == info.getAnchor() || ToolWindowAnchor.BOTTOM == info.getAnchor()) { + info.setWeight((float)source.getHeight() / (float)myToolWindowsPane.getMyLayeredPane().getHeight()); + } + else { + info.setWeight((float)source.getWidth() / (float)myToolWindowsPane.getMyLayeredPane().getWidth()); + } + } + } + + public void activated(final InternalDecorator source) { + activateToolWindow(source.getToolWindow().getId()); + } + + public void typeChanged(final InternalDecorator source, final ToolWindowType type) { + setToolWindowType(source.getToolWindow().getId(), type); + } + } + + private void updateComponentTreeUI() { + ApplicationManager.getApplication().assertIsDispatchThread(); + final WindowInfo[] infos = myLayout.getInfos(); + for (int i = 0; i < infos.length; i++) { + final WindowInfo info = infos[i]; + if (info.isVisible()) { // skip visible tool windows (optimization) + continue; + } + SwingUtilities.updateComponentTreeUI(getInternalDecorator(info.getId())); + } + } + + private final class MyUIManagerPropertyChangeListener implements PropertyChangeListener { + public void propertyChange(final PropertyChangeEvent e) { + updateComponentTreeUI(); + } + } + + private final class MyLafManagerListener implements LafManagerListener { + public void lookAndFeelChanged(final LafManager source) { + updateComponentTreeUI(); + } + } + + public String getComponentName() { + return "ToolWindowManager"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowsPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowsPane.java new file mode 100644 index 00000000000..a85df0679f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/ToolWindowsPane.java @@ -0,0 +1,716 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.impl.commands.FinalizableCommand; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentEvent; +import java.awt.image.BufferedImage; +import java.lang.ref.SoftReference; +import java.util.Comparator; + +/** + * This panel contains all tool stripes and JLayeredPanle at the center area. All tool windows are + * located inside this layered pane. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ToolWindowsPane extends JPanel{ + private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.wm.impl.ToolWindowsPane"); + + private final IdeFrame myFrame; + + private final HashMap myId2Button; + private final HashMap myId2Decorator; + private final HashMap myButton2Info; + private final HashMap myDecorator2Info; + /** + * This panel is the layered pane where all sliding tool windows are located. The DEFAULT + * layer contains splitters. The PALETTE layer contains all sliding tool windows. + */ + private final MyLayeredPane myLayeredPane; + /* + * Splitters. + */ + private final Splitter myLeftSplitter; + private final Splitter myRightSplitter; + private final Splitter myTopSplitter; + private final Splitter myBottomSplitter; + /* + * Tool stripes. + */ + private final Stripe myLeftStripe; + private final Stripe myRightStripe; + private final Stripe myBottomStripe; + private final Stripe myTopStripe; + + private final MyUISettingsListenerImpl myUISettingsListener; + + ToolWindowsPane(final IdeFrame frame){ + super(new BorderLayout()); + + setOpaque(false); + myFrame=frame; + myId2Button=new HashMap(); + myId2Decorator=new HashMap(); + myButton2Info=new HashMap(); + myDecorator2Info=new HashMap(); + myUISettingsListener=new MyUISettingsListenerImpl(); + + // Splitters + + myLeftSplitter = new Splitter(); + myLeftSplitter.setBackground(Color.gray); + myLeftSplitter.setProportion(0.33f); + + myRightSplitter = new Splitter(); + myRightSplitter.setBackground(Color.gray); + myRightSplitter.setProportion(0.66f); + myRightSplitter.setFirstComponent(myLeftSplitter); + + myTopSplitter=new Splitter(true); + myTopSplitter.setBackground(Color.gray); + myTopSplitter.setProportion(0.66f); + myTopSplitter.setSecondComponent(myRightSplitter); + + myBottomSplitter = new Splitter(true); + myBottomSplitter.setBackground(Color.gray); + myBottomSplitter.setFirstComponent(myTopSplitter); + myBottomSplitter.setProportion(0.66f); + + // Tool stripes + + myTopStripe=new Stripe(SwingConstants.TOP); + myLeftStripe=new Stripe(SwingConstants.LEFT); + myBottomStripe=new Stripe(SwingConstants.BOTTOM); + myRightStripe=new Stripe(SwingConstants.RIGHT); + updateToolStripesVisibility(); + + // Layered pane + + myLayeredPane=new MyLayeredPane(myBottomSplitter); + + // Compose layout + + add(myTopStripe,BorderLayout.NORTH); + add(myLeftStripe,BorderLayout.WEST); + add(myBottomStripe,BorderLayout.SOUTH); + add(myRightStripe,BorderLayout.EAST); + add(myLayeredPane,BorderLayout.CENTER); + } + + /** + * Invoked when enclosed frame is being shown. + */ + public final void addNotify(){ + super.addNotify(); + UISettings.getInstance().addUISettingsListener(myUISettingsListener); + } + + /** + * Invoked when enclosed frame is being disposed. + */ + public final void removeNotify(){ + UISettings.getInstance().removeUISettingsListener(myUISettingsListener); + super.removeNotify(); + } + + /** + * Creates command which adds button into the specified tool stripe. + * Command uses copy of passed info object. + * @param button button which should be added. + * @param info window info for the corresponded tool window. + * @param comparator which is used to sort buttons within the stripe. + * @param finishCallBack invoked when the command is completed. + */ + final FinalizableCommand createAddButtonCmd(final StripeButton button,final WindowInfo info,final Comparator comparator,final Runnable finishCallBack){ + final WindowInfo copiedInfo=info.copy(); + myId2Button.put(copiedInfo.getId(),button); + myButton2Info.put(button,copiedInfo); + return new AddToolStripeButtonCmd(button,copiedInfo,comparator,finishCallBack); + } + + /** + * Creates command which shows tool window with specified set of parameters. + * Command uses cloned copy of passed info object. + * @param dirtyMode if true then JRootPane will not be validated and repainted after adding + * the decorator. Moreover in this (dirty) mode animation doesn't work. + */ + final FinalizableCommand createAddDecoratorCmd( + final InternalDecorator decorator, + final WindowInfo info, + final boolean dirtyMode, + final Runnable finishCallBack + ){ + final WindowInfo copiedInfo=info.copy(); + final String id=copiedInfo.getId(); + // + myDecorator2Info.put(decorator,copiedInfo); + myId2Decorator.put(id,decorator); + // + if(info.isDocked()){ + return new AddDockedComponentCmd(decorator,info,dirtyMode,finishCallBack); + }else if(info.isSliding()){ + return new AddSlidingComponentCmd(decorator,info,dirtyMode,finishCallBack); + }else{ + throw new IllegalArgumentException("Unknown window type: "+info.getType()); + } + } + + /** + * Creates command which removes tool button from tool stripe. + * @param id ID of the button to be removed. + */ + final FinalizableCommand createRemoveButtonCmd(final String id,final Runnable finishCallBack){ + final StripeButton button=getButtonById(id); + final WindowInfo info=getButtonInfoById(id); + // + myButton2Info.remove(button); + myId2Button.remove(id); + return new RemoveToolStripeButtonCmd(button,info,finishCallBack); + } + + /** + * Creates command which hides tool window with specified set of parameters. + * @param dirtyMode if true then JRootPane will not be validated and repainted after removing + * the decorator. Moreover in this (dirty) mode animation doesn't work. + */ + final FinalizableCommand createRemoveDecoratorCmd(final String id, final boolean dirtyMode, final Runnable finishCallBack){ + final Component decorator=getDecoratorById(id); + final WindowInfo info=getDecoratorInfoById(id); + // + myDecorator2Info.remove(decorator); + myId2Decorator.remove(id); + // + if(info.isDocked()){ + return new RemoveDockedComponentCmd(info,dirtyMode,finishCallBack); + }else if(info.isSliding()){ + return new RemoveSlidingComponentCmd(decorator,info,dirtyMode,finishCallBack); + }else{ + throw new IllegalArgumentException("Unknown window type"); + } + } + + /** + * Creates command which sets specified document component. + * @param component component to be set. + */ + final FinalizableCommand createSetEditorComponentCmd(final JComponent component,final Runnable finishCallBack){ + return new SetEditorComponentCmd(component,finishCallBack); + } + + final JComponent getMyLayeredPane(){ + return myLayeredPane; + } + + private StripeButton getButtonById(final String id){ + return myId2Button.get(id); + } + + private Component getDecoratorById(final String id){ + return myId2Decorator.get(id); + } + + /** + * @return WindowInfo associated with specified tool stripe button. + * @param id ID of tool stripe butoon. + */ + private WindowInfo getButtonInfoById(final String id){ + return myButton2Info.get(myId2Button.get(id)); + } + + /** + * @return WindowInfo associated with specified window decorator. + * @param id ID of decorator. + */ + private WindowInfo getDecoratorInfoById(final String id){ + return myDecorator2Info.get(myId2Decorator.get(id)); + } + + /** + * Sets (docks) specified component to the specified anchor. + */ + private void setComponent(final JComponent component,final ToolWindowAnchor anchor){ + if(ToolWindowAnchor.TOP==anchor){ + myTopSplitter.setFirstComponent(component); + }else if(ToolWindowAnchor.LEFT==anchor){ + myLeftSplitter.setFirstComponent(component); + }else if(ToolWindowAnchor.BOTTOM==anchor){ + myBottomSplitter.setSecondComponent(component); + }else if(ToolWindowAnchor.RIGHT==anchor){ + myRightSplitter.setSecondComponent(component); + }else{ + LOG.error("unknown anchor: "+anchor); + } + } + + private void setDocumentComponent(final JComponent component){ + myLeftSplitter.setSecondComponent(component); + } + + private void updateToolStripesVisibility(){ + final boolean visible = !UISettings.getInstance().HIDE_TOOL_STRIPES; + myLeftStripe.setVisible(visible); + myRightStripe.setVisible(visible); + myTopStripe.setVisible(visible); + myBottomStripe.setVisible(visible); + } + + private final class AddDockedComponentCmd extends FinalizableCommand{ + private final JComponent myComponent; + private final WindowInfo myInfo; + private final boolean myDirtyMode; + + public AddDockedComponentCmd(final JComponent component, final WindowInfo info, final boolean dirtyMode, final Runnable finishCallBack){ + super(finishCallBack); + myComponent=component; + myInfo=info; + myDirtyMode=dirtyMode; + } + + public final void run(){ + try{ + final float weight=myInfo.getWeight()<=.0f?WindowInfo.DEFAULT_WEIGHT:myInfo.getWeight(); + float newWeight=weight; + final ToolWindowAnchor anchor=myInfo.getAnchor(); + if(ToolWindowAnchor.TOP==anchor){ + if(myTopSplitter.getHeight()>0){ + newWeight=(myLayeredPane.getHeight()*weight+myTopSplitter.getDividerWidth()/2)/(float)myTopSplitter.getHeight(); + } + if(newWeight>=1.0f){ + newWeight=1-WindowInfo.DEFAULT_WEIGHT; + } + myTopSplitter.setProportion(newWeight); + setComponent(myComponent,ToolWindowAnchor.TOP); + }else if(ToolWindowAnchor.LEFT==anchor){ + if(myLeftSplitter.getWidth()>0){ + newWeight=(myLayeredPane.getWidth()*weight+myLeftSplitter.getDividerWidth()/2)/(float)myLeftSplitter.getWidth(); + } + if(newWeight>=1.0f){ + newWeight=1-WindowInfo.DEFAULT_WEIGHT; + } + myLeftSplitter.setProportion(newWeight); + setComponent(myComponent,ToolWindowAnchor.LEFT); + }else if(ToolWindowAnchor.BOTTOM==anchor){ + if(myBottomSplitter.getHeight()>0){ + newWeight=(myLayeredPane.getHeight()*weight+myBottomSplitter.getDividerWidth()/2+.5f)/(float)myBottomSplitter.getHeight(); + } + if(newWeight>=1.0f){ + newWeight=1-WindowInfo.DEFAULT_WEIGHT; + } + myBottomSplitter.setProportion(1-newWeight); + setComponent(myComponent,ToolWindowAnchor.BOTTOM); + }else if(ToolWindowAnchor.RIGHT==anchor){ + if(myRightSplitter.getWidth()>0){ + newWeight=(myLayeredPane.getWidth()*weight+myRightSplitter.getDividerWidth()/2+.5f)/(float)myRightSplitter.getWidth(); + } + if(newWeight>=1.0f){ + newWeight=1-WindowInfo.DEFAULT_WEIGHT; + } + myRightSplitter.setProportion(1-newWeight); + setComponent(myComponent,ToolWindowAnchor.RIGHT); + }else{ + LOG.error("unknown anchor: "+anchor); + } + if(!myDirtyMode){ + myLayeredPane.validate(); + myLayeredPane.repaint(); + } + }finally{ + finish(); + } + } + } + + private final class AddSlidingComponentCmd extends FinalizableCommand{ + private final Component myComponent; + private final WindowInfo myInfo; + private final boolean myDirtyMode; + + public AddSlidingComponentCmd(final Component component, final WindowInfo info, final boolean dirtyMode, final Runnable finishCallBack){ + super(finishCallBack); + myComponent=component; + myInfo=info; + myDirtyMode=dirtyMode; + } + + public final void run(){ + try{ + // Show component. + final UISettings uiSettings=UISettings.getInstance(); + if(!myDirtyMode && uiSettings.ANIMATE_WINDOWS){ + // Prepare top image. This image is scrolling over bottom image. + final Image topImage=myLayeredPane.getTopImage(); + final Graphics topGraphics=topImage.getGraphics(); + + Rectangle bounds; + + try{ + myLayeredPane.add(myComponent,JLayeredPane.PALETTE_LAYER); + myLayeredPane.moveToFront(myComponent); + myLayeredPane.setBoundsInPaletteLayer(myComponent,myInfo.getAnchor(),myInfo.getWeight()); + bounds=myComponent.getBounds(); + myComponent.paint(topGraphics); + myLayeredPane.remove(myComponent); + }finally{ + topGraphics.dispose(); + } + // Prepare bottom image. + final Image bottomImage=myLayeredPane.getBottomImage(); + final Graphics bottomGraphics=bottomImage.getGraphics(); + try{ + bottomGraphics.setClip(0,0,bounds.width,bounds.height); + bottomGraphics.translate(-bounds.x,-bounds.y); + myLayeredPane.paint(bottomGraphics); + }finally{ + bottomGraphics.dispose(); + } + // Start animation. + final Surface surface=new Surface(topImage,bottomImage,1,myInfo.getAnchor(),uiSettings.ANIMATION_SPEED); + myLayeredPane.add(surface,JLayeredPane.PALETTE_LAYER); + surface.setBounds(bounds); + myLayeredPane.validate(); + myLayeredPane.repaint(); + + surface.runMovement(); + myLayeredPane.remove(surface); + myLayeredPane.add(myComponent,JLayeredPane.PALETTE_LAYER); + }else{ // not animated + myLayeredPane.add(myComponent,JLayeredPane.PALETTE_LAYER); + myLayeredPane.setBoundsInPaletteLayer(myComponent,myInfo.getAnchor(),myInfo.getWeight()); + } + if(!myDirtyMode){ + myLayeredPane.validate(); + myLayeredPane.repaint(); + } + }finally{ + finish(); + } + } + } + + private final class AddToolStripeButtonCmd extends FinalizableCommand{ + private final StripeButton myButton; + private final WindowInfo myInfo; + private final Comparator myComparator; + + public AddToolStripeButtonCmd(final StripeButton button,final WindowInfo info,final Comparator comparator,final Runnable finishCallBack){ + super(finishCallBack); + myButton=button; + myInfo=info; + myComparator=comparator; + } + + public final void run(){ + try{ + final ToolWindowAnchor anchor=myInfo.getAnchor(); + if(ToolWindowAnchor.TOP==anchor){ + myTopStripe.addButton(myButton,myComparator); + }else if(ToolWindowAnchor.LEFT==anchor){ + myLeftStripe.addButton(myButton,myComparator); + }else if(ToolWindowAnchor.BOTTOM==anchor){ + myBottomStripe.addButton(myButton,myComparator); + }else if(ToolWindowAnchor.RIGHT==anchor){ + myRightStripe.addButton(myButton,myComparator); + }else{ + LOG.error("unknown anchor: "+anchor); + } + validate(); + repaint(); + }finally{ + finish(); + } + } + } + + private final class RemoveToolStripeButtonCmd extends FinalizableCommand{ + private final StripeButton myButton; + private final WindowInfo myInfo; + + public RemoveToolStripeButtonCmd(final StripeButton button,final WindowInfo info,final Runnable finishCallBack){ + super(finishCallBack); + myButton=button; + myInfo=info; + } + + public final void run(){ + try{ + final ToolWindowAnchor anchor=myInfo.getAnchor(); + if(ToolWindowAnchor.TOP==anchor){ + myTopStripe.removeButton(myButton); + }else if(ToolWindowAnchor.LEFT==anchor){ + myLeftStripe.removeButton(myButton); + }else if(ToolWindowAnchor.BOTTOM==anchor){ + myBottomStripe.removeButton(myButton); + }else if(ToolWindowAnchor.RIGHT==anchor){ + myRightStripe.removeButton(myButton); + }else{ + LOG.error("unknown anchor: "+anchor); + } + validate(); + repaint(); + }finally{ + finish(); + } + } + } + + private final class RemoveDockedComponentCmd extends FinalizableCommand{ + private final WindowInfo myInfo; + private final boolean myDirtyMode; + + public RemoveDockedComponentCmd(final WindowInfo info, final boolean dirtyMode, final Runnable finishCallBack){ + super(finishCallBack); + myInfo=info; + myDirtyMode=dirtyMode; + } + + public final void run(){ + try{ + setComponent(null,myInfo.getAnchor()); + if(!myDirtyMode){ + myLayeredPane.validate(); + myLayeredPane.repaint(); + } + }finally{ + finish(); + } + } + } + + private final class RemoveSlidingComponentCmd extends FinalizableCommand{ + private final Component myComponent; + private final WindowInfo myInfo; + private final boolean myDirtyMode; + + public RemoveSlidingComponentCmd( + final Component component, + final WindowInfo info, + final boolean dirtyMode, + final Runnable finishCallBack + ){ + super(finishCallBack); + myComponent=component; + myInfo=info; + myDirtyMode=dirtyMode; + } + + public final void run(){ + try{ + final UISettings uiSettings=UISettings.getInstance(); + if(!myDirtyMode && uiSettings.ANIMATE_WINDOWS){ + final Rectangle bounds=myComponent.getBounds(); + // Prepare top image. This image is scrolling over bottom image. It contains + // picture of component is being removed. + final Image topImage=myLayeredPane.getTopImage(); + final Graphics topGraphics=topImage.getGraphics(); + try{ + myComponent.paint(topGraphics); + }finally{ + topGraphics.dispose(); + } + // Prepare bottom image. This image contains picture of component that is located + // under the component to is being removed. + final Image bottomImage=myLayeredPane.getBottomImage(); + final Graphics bottomGraphics = bottomImage.getGraphics(); + try{ + myLayeredPane.remove(myComponent); + bottomGraphics.clipRect(0,0,bounds.width,bounds.height); + bottomGraphics.translate(-bounds.x,-bounds.y); + myLayeredPane.paint(bottomGraphics); + }finally{ + bottomGraphics.dispose(); + } + // Remove component from the layered pane and start animation. + final Surface surface=new Surface(topImage,bottomImage,-1,myInfo.getAnchor(),uiSettings.ANIMATION_SPEED * 2); + myLayeredPane.add(surface,JLayeredPane.PALETTE_LAYER); + surface.setBounds(bounds); + myLayeredPane.validate(); + myLayeredPane.repaint(); + + surface.runMovement(); + myLayeredPane.remove(surface); + }else{ // not animated + myLayeredPane.remove(myComponent); + } + if(!myDirtyMode){ + myLayeredPane.validate(); + myLayeredPane.repaint(); + } + }finally{ + finish(); + } + } + } + + private final class SetEditorComponentCmd extends FinalizableCommand{ + private final JComponent myComponent; + + public SetEditorComponentCmd(final JComponent component,final Runnable finishCallBack){ + super(finishCallBack); + myComponent=component; + } + + public void run(){ + try{ + setDocumentComponent(myComponent); + myLayeredPane.validate(); + myLayeredPane.repaint(); + }finally{ + finish(); + } + } + } + + private final class MyUISettingsListenerImpl implements UISettingsListener{ + public final void uiSettingsChanged(final UISettings source){ + updateToolStripesVisibility(); + } + } + + private final class MyLayeredPane extends JLayeredPane{ + /* + * These images are used to perform animated showing and hiding of components. + * They are the member for performance reason. + */ + private SoftReference myBottomImageRef; + private SoftReference myTopImageRef; + + public MyLayeredPane(final Splitter splitter) { + myBottomImageRef=new SoftReference(null); + myTopImageRef=new SoftReference(null); + setOpaque(true); + setBackground(Color.gray); + add(splitter,JLayeredPane.DEFAULT_LAYER); + splitter.setBounds(0,0,getWidth(),getHeight()); + enableEvents(ComponentEvent.COMPONENT_EVENT_MASK); + } + + /** + * TODO[vova] extract method + * Lazily creates and returns bottom image for animation. + */ + public final Image getBottomImage(){ + LOG.assertTrue(UISettings.getInstance().ANIMATE_WINDOWS); + BufferedImage image=(BufferedImage)myBottomImageRef.get(); + if( + image==null || + image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight() + ){ + final int width=Math.max(Math.max(1,getWidth()),myFrame.getWidth()); + final int height=Math.max(Math.max(1,getHeight()),myFrame.getHeight()); + if(SystemInfo.isWindows || SystemInfo.isMac){ + image=myFrame.getGraphicsConfiguration().createCompatibleImage(width,height); + }else{ + // Under Linux we have found that images created by createCompatibleImage(), + // createVolatileImage(), etc extremely slow for rendering. TrueColor buffered image + // is MUCH faster. + image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); + } + myBottomImageRef=new SoftReference(image); + } + return image; + } + + /** + * TODO[vova] extract method + * Lazily creates and returns top image for animation. + */ + public final Image getTopImage(){ + LOG.assertTrue(UISettings.getInstance().ANIMATE_WINDOWS); + BufferedImage image=(BufferedImage)myTopImageRef.get(); + if( + image==null || + image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight() + ){ + final int width=Math.max(Math.max(1,getWidth()),myFrame.getWidth()); + final int height=Math.max(Math.max(1,getHeight()),myFrame.getHeight()); + if(SystemInfo.isWindows || SystemInfo.isMac){ + image=myFrame.getGraphicsConfiguration().createCompatibleImage(width,height); + }else{ + // Under Linux we have found that images created by createCompatibleImage(), + // createVolatileImage(), etc extremely slow for rendering. TrueColor buffered image + // is MUCH faster. + image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); + } + myTopImageRef=new SoftReference(image); + } + return image; + } + + /** + * When component size becomes larger then bottom and top images should be enlarged. + */ + protected final void processComponentEvent(final ComponentEvent e) { + if(ComponentEvent.COMPONENT_RESIZED==e.getID()){ + final int width=getWidth(); + final int height=getHeight(); + if(width<0||height<0){ + return; + } + // Resize component at the DEFAULT layer. It should be only on component in that layer + Component[] components=getComponentsInLayer(JLayeredPane.DEFAULT_LAYER.intValue()); + LOG.assertTrue(components.length<=1); + for(int i=0;i1.0f){ + weight=1.0f; + } + if(ToolWindowAnchor.TOP==anchor){ + component.setBounds(0,0,getWidth(),(int)(getHeight()*weight+.5f)); + }else if(ToolWindowAnchor.LEFT==anchor){ + component.setBounds(0,0,(int)(getWidth()*weight+.5f),getHeight()); + }else if(ToolWindowAnchor.BOTTOM==anchor){ + final int height=(int)(getHeight()*weight+.5f); + component.setBounds(0,getHeight()-height,getWidth(),height); + }else if(ToolWindowAnchor.RIGHT==anchor){ + final int width=(int)(getWidth()*weight+.5f); + component.setBounds(getWidth()-width,0,width,getHeight()); + }else{ + LOG.error("unknown anchor "+anchor); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/VisibilityWatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/VisibilityWatcher.java new file mode 100644 index 00000000000..09a1b4ceaf7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/VisibilityWatcher.java @@ -0,0 +1,58 @@ +package com.intellij.openapi.wm.impl; + +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class VisibilityWatcher extends ComponentAdapter implements PropertyChangeListener{ + public final void componentHidden(final ComponentEvent e){ + visibilityChanged(); + } + + public final void componentShown(final ComponentEvent e){ + visibilityChanged(); + } + + public final void propertyChange(final PropertyChangeEvent e){ + if("ancestor".equals(e.getPropertyName())){ + final Component oldAncestor=(Component)e.getOldValue(); + deinstall(oldAncestor); + final Component newAncestor=(Component)e.getNewValue(); + install(newAncestor); + visibilityChanged(); + }else{ + throw new IllegalArgumentException("unknown propertyName: "+e.getPropertyName()); + } + } + + public final void install(Component component){ + while(component!=null){ + component.removePropertyChangeListener("ancestor",this); // it prevent double registering + component.addPropertyChangeListener("ancestor",this); + + component.removeComponentListener(this); // it prevent double registering + component.addComponentListener(this); + component=component.getParent(); + } + } + + public void deinstall(Component component){ + while(component!=null){ + component.removePropertyChangeListener("ancestor",this); + component.removeComponentListener(this); + component=component.getParent(); + } + } + + /** + * Invokes every time component changes its visibility. It means one of parent component + * change visibility or hierarchy is connected/disconnected to/from peer. + */ + public abstract void visibilityChanged(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowInfo.java new file mode 100644 index 00000000000..57cbeab49cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowInfo.java @@ -0,0 +1,341 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowType; +import org.jdom.Element; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class WindowInfo implements Cloneable,JDOMExternalizable{ + /** + * XML tag. + */ + static final String TAG="window_info"; + /** + * Default window weight. + */ + static final float DEFAULT_WEIGHT=.33f; + + private boolean myActive; + private ToolWindowAnchor myAnchor; + private boolean myAutoHide; + /** + * Bounds of window in "floating" mode. It equals to null if + * floating bounds are undefined. + */ + private Rectangle myFloatingBounds; + private String myId; + private ToolWindowType myInternalType; + private ToolWindowType myType; + private boolean myVisible; + private float myWeight; + /** + * Defines order of tool window button inside the stripe. + * The default value is -1. + */ + private int myOrder; + + /** + * Creates WindowInfo for tool window with wpecified ID. + */ + WindowInfo(final String id){ + myActive=false; + myAnchor=ToolWindowAnchor.LEFT; + myAutoHide=false; + myFloatingBounds=null; + myId=id; + setType(ToolWindowType.DOCKED); + myVisible=false; + myWeight=DEFAULT_WEIGHT; + myOrder=-1; + } + + /** + * Creates copy of WindowInfo object. + */ + public WindowInfo copy(){ + WindowInfo info=null; + try{ + info=(WindowInfo)clone(); + if(myFloatingBounds!=null){ + info.myFloatingBounds=(Rectangle)myFloatingBounds.clone(); + } + }catch(CloneNotSupportedException ignored){} + return info; + } + + /** + * Copies all data from the passed WindowInfo into itself. + */ + void copyFrom(final WindowInfo info){ + myActive=info.myActive; + myAnchor=info.myAnchor; + myAutoHide=info.myAutoHide; + if(info.myFloatingBounds!=null){ + myFloatingBounds=(Rectangle)info.myFloatingBounds.clone(); + }else{ + myFloatingBounds=null; + } + myId=info.myId; + myType=info.myType; + myInternalType=info.myInternalType; + myVisible=info.myVisible; + myWeight=info.myWeight; + myOrder=info.myOrder; + } + + /** + * @return tool window's anchor in internal mode. + */ + ToolWindowAnchor getAnchor(){ + return myAnchor; + } + + /** + * @return bound of tool window in floating mode. + */ + Rectangle getFloatingBounds(){ + return myFloatingBounds; + } + + /** + * @return ID of the tool window. + */ + String getId(){ + return myId; + } + + /** + * @return type of the tool window in internal (docked or sliding) mode. Actually the tool + * window can be in floating mode, but this method has sense if you want to know what type + * tool window had when it was internal one. The method never returns null. + */ + ToolWindowType getInternalType(){ + return myInternalType; + } + + /** + * @return current type of tool window. + * @see com.intellij.openapi.wm.ToolWindowType#DOCKED + * @see com.intellij.openapi.wm.ToolWindowType#FLOATING + * @see com.intellij.openapi.wm.ToolWindowType#SLIDING + */ + ToolWindowType getType(){ + return myType; + } + + /** + * @return internal weight of tool window. "weigth" means how much of internal desktop + * area the tool window is occupied. The weight has sense if the tool window is docked or + * sliding. + */ + float getWeight(){ + return myWeight; + } + + public int getOrder(){ + return myOrder; + } + + public void setOrder(final int order){ + myOrder=order; + } + + boolean isActive(){ + return myActive; + } + + boolean isAutoHide(){ + return myAutoHide; + } + + boolean isDocked(){ + return ToolWindowType.DOCKED==myType; + } + + boolean isFloating(){ + return ToolWindowType.FLOATING==myType; + } + + boolean isSliding(){ + return ToolWindowType.SLIDING==myType; + } + + boolean isVisible(){ + return myVisible; + } + + private static ToolWindowType parseToolWindowType(final String text){ + if(ToolWindowType.DOCKED.toString().equals(text)){ + return ToolWindowType.DOCKED; + }else if(ToolWindowType.FLOATING.toString().equals(text)){ + return ToolWindowType.FLOATING; + }else if(ToolWindowType.SLIDING.toString().equals(text)){ + return ToolWindowType.SLIDING; + }else{ + throw new IllegalArgumentException(); + } + } + + private static ToolWindowAnchor parseToolWindowAnchor(final String text){ + if(ToolWindowAnchor.TOP.toString().equals(text)){ + return ToolWindowAnchor.TOP; + }else if(ToolWindowAnchor.LEFT.toString().equals(text)){ + return ToolWindowAnchor.LEFT; + }else if(ToolWindowAnchor.BOTTOM.toString().equals(text)){ + return ToolWindowAnchor.BOTTOM; + }else if(ToolWindowAnchor.RIGHT.toString().equals(text)){ + return ToolWindowAnchor.RIGHT; + }else{ + throw new IllegalArgumentException(); + } + } + + public void readExternal(final Element element){ + myId=element.getAttributeValue("id"); + try{ + myActive=Boolean.valueOf(element.getAttributeValue("active")).booleanValue(); + }catch(NumberFormatException ignored){} + try{ + myAnchor=WindowInfo.parseToolWindowAnchor(element.getAttributeValue("anchor")); + }catch(IllegalArgumentException ignored){} + myAutoHide=Boolean.valueOf(element.getAttributeValue("auto_hide")).booleanValue(); + try{ + myInternalType=WindowInfo.parseToolWindowType(element.getAttributeValue("internal_type")); + }catch(IllegalArgumentException ignored){} + try{ + myType=parseToolWindowType(element.getAttributeValue("type")); + }catch(IllegalArgumentException ignored){} + myVisible=Boolean.valueOf(element.getAttributeValue("visible")).booleanValue(); + try{ + myWeight=Float.parseFloat(element.getAttributeValue("weight")); + }catch(NumberFormatException ignored){} + try{ + myOrder=Integer.valueOf(element.getAttributeValue("order")).intValue(); + }catch(NumberFormatException ignored){} + try{ + myFloatingBounds=new Rectangle( + Integer.parseInt(element.getAttributeValue("x")), + Integer.parseInt(element.getAttributeValue("y")), + Integer.parseInt(element.getAttributeValue("width")), + Integer.parseInt(element.getAttributeValue("height")) + ); + }catch(NumberFormatException ignored){} + } + + /** + * Sets new anchor. + */ + void setAnchor(final ToolWindowAnchor anchor){ + if(anchor==null){ + throw new IllegalArgumentException("anchor cannot be null"); + } + myAnchor=anchor; + } + + void setActive(final boolean active){ + myActive=active; + } + + void setAutoHide(final boolean autoHide){ + myAutoHide=autoHide; + } + + void setFloatingBounds(final Rectangle floatingBounds){ + myFloatingBounds=floatingBounds; + } + + void setType(final ToolWindowType type){ + if(type==null){ + throw new IllegalArgumentException("type cannot be null"); + } + if(ToolWindowType.DOCKED==type||ToolWindowType.SLIDING==type){ + myInternalType=type; + } + myType=type; + } + + void setVisible(final boolean visible){ + myVisible=visible; + } + + /** + * Sets window weight and adjust it to [0..1] range if necessary. + */ + void setWeight(float weigth){ + if(weigth<.0f){ + weigth=.0f; + }else if(weigth>1.0f){ + weigth=1.0f; + } + myWeight=weigth; + } + + public void writeExternal(final Element element){ + element.setAttribute("id",myId); + element.setAttribute("active",myActive?Boolean.TRUE.toString():Boolean.FALSE.toString()); + element.setAttribute("anchor",myAnchor.toString()); + element.setAttribute("auto_hide",myAutoHide?Boolean.TRUE.toString():Boolean.FALSE.toString()); + element.setAttribute("internal_type",myInternalType.toString()); + element.setAttribute("type",myType.toString()); + element.setAttribute("visible",myVisible?Boolean.TRUE.toString():Boolean.FALSE.toString()); + element.setAttribute("weight",Float.toString(myWeight)); + element.setAttribute("order",Integer.toString(myOrder)); + if(myFloatingBounds!=null){ + element.setAttribute("x",Integer.toString(myFloatingBounds.x)); + element.setAttribute("y",Integer.toString(myFloatingBounds.y)); + element.setAttribute("width",Integer.toString(myFloatingBounds.width)); + element.setAttribute("height",Integer.toString(myFloatingBounds.height)); + } + } + + public boolean equals(final Object obj){ + if(!(obj instanceof WindowInfo)){ + return false; + } + final WindowInfo info=(WindowInfo)obj; + if( + myActive!=info.myActive|| + myAnchor!=info.myAnchor|| + !myId.equals(info.myId)|| + myAutoHide!=info.myAutoHide|| + !Comparing.equal(myFloatingBounds,info.myFloatingBounds)|| + myInternalType!=info.myInternalType|| + myType!=info.myType|| + myVisible!=info.myVisible|| + myWeight!=info.myWeight|| + myOrder!=info.myOrder + ){ + return false; + }else{ + return true; + } + } + + public int hashCode(){ + return myAnchor.hashCode()+myId.hashCode()+myType.hashCode()+myOrder; + } + + public String toString(){ + final StringBuffer buffer=new StringBuffer(); + buffer.append(getClass().getName()).append('['); + buffer.append("myId=").append(myId).append("; "); + buffer.append("myVisible=").append(myVisible).append("; "); + buffer.append("myActive=").append(myActive).append("; "); + buffer.append("myAnchor=").append(myAnchor).append("; "); + buffer.append("myOrder=").append(myOrder).append("; "); + buffer.append("myAutoHide=").append(myAutoHide).append("; "); + buffer.append("myWeight=").append(myWeight).append("; "); + buffer.append("myType=").append(myType).append("; "); + buffer.append("myInternalType=").append(myInternalType).append("; "); + buffer.append("myFloatingBounds=").append(myFloatingBounds); + buffer.append(']'); + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowManagerImpl.java new file mode 100644 index 00000000000..9baeecfd8f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowManagerImpl.java @@ -0,0 +1,501 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.Patches; +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.DataManagerImpl; +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.ex.KeymapManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.NamedJDOMExternalizable; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.util.Alarm; +import org.jdom.Element; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ + +// Made non-final for Fabrique +public class WindowManagerImpl extends WindowManagerEx implements ApplicationComponent, NamedJDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.WindowManagerImpl"); + private static boolean ourAlphaModeLibraryLoaded; + + static { + try { + System.loadLibrary("jawt"); + System.loadLibrary("transparency"); + ourAlphaModeLibraryLoaded = true; + } + catch (Throwable exc) { + ourAlphaModeLibraryLoaded = false; + } + } + + /** + * Union of bounds of all available default screen devices. + */ + protected Rectangle myScreenBounds; + + private final CommandProcessor myCommandProcessor; + private final WindowWatcher myWindowWatcher; + /** + * That is the default layout. + */ + protected DesktopLayout myLayout; + +// Made protected for Fabrique + protected final HashMap myProject2Frame; + + private final HashMap> myDialogsToDispose; + + /** + * This members is needed to read frame's bounds from XML. + * myFrameBounds can be null. + */ + protected Rectangle myFrameBounds; + protected int myFrameExtendedState; + private WindowAdapter myActivationListener; + private final ApplicationInfoEx myApplicationInfoEx; + private final DataManager myDataManager; + private final ActionManager myActionManager; + private final UISettings myUiSettings; + private final KeymapManager myKeymapManager; + + /** + * invoked by reflection + * @param dataManager + * @param applicationInfoEx + * @param actionManager + * @param uiSettings + * @param keymapManager + */ + protected WindowManagerImpl(DataManager dataManager, + ApplicationInfoEx applicationInfoEx, + ActionManager actionManager, + UISettings uiSettings, + KeymapManager keymapManager) { + myApplicationInfoEx = applicationInfoEx; + myDataManager = dataManager; + myActionManager = actionManager; + myUiSettings = uiSettings; + myKeymapManager = keymapManager; + if (myDataManager instanceof DataManagerImpl) { + ((DataManagerImpl)myDataManager).setWindowManager(this); + } + + myCommandProcessor = new CommandProcessor(); + myWindowWatcher = new WindowWatcher(); + final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + keyboardFocusManager.addPropertyChangeListener("focusedWindow", myWindowWatcher); + if (Patches.SUN_BUG_ID_4218084) { + keyboardFocusManager.addPropertyChangeListener("focusedWindow", new SUN_BUG_ID_4218084_Patch()); + } + myLayout = new DesktopLayout(); + myProject2Frame = new HashMap(); + myDialogsToDispose = new HashMap>(); + myFrameExtendedState = Frame.NORMAL; + + // Calculate screen bounds. + + myScreenBounds = new Rectangle(); + final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + final GraphicsDevice[] devices = env.getScreenDevices(); + for (int i = 0; i < devices.length; i++) { + final GraphicsDevice device = devices[i]; + myScreenBounds = myScreenBounds.union(device.getDefaultConfiguration().getBounds()); + } + + myActivationListener = new WindowAdapter() { + public void windowActivated(WindowEvent e) { + Window activeWindow = e.getWindow(); + if (activeWindow instanceof IdeFrame) { // must be + proceedDialogDisposalQueue(((IdeFrame)activeWindow).getProject()); + } + } + }; + } + + private void showFrame() { + final IdeFrame frame = new IdeFrame(myApplicationInfoEx, myActionManager, myUiSettings, myDataManager, myKeymapManager); + myProject2Frame.put(null, frame); + if (myFrameBounds != null) { + frame.setBounds(myFrameBounds); + } + frame.show(); + frame.setExtendedState(myFrameExtendedState); + } + + public final Rectangle getScreenBounds() { + return myScreenBounds; + } + + public final boolean isInsideScreenBounds(final int x, final int y, final int width) { + return + x >= myScreenBounds.x + 50 - width && + y >= myScreenBounds.y - 50 && + x <= myScreenBounds.x + myScreenBounds.width - 50 && + y <= myScreenBounds.y + myScreenBounds.height - 50; + } + + public final boolean isInsideScreenBounds(final int x, final int y) { + return myScreenBounds.contains(x, y); + } + + public final boolean isAlphaModeSupported() { + return ourAlphaModeLibraryLoaded && (SystemInfo.isWindows2000 || SystemInfo.isWindowsXP); + } + + public final void setAlphaModeRatio(final Window window, final float ratio) { + if (!window.isDisplayable() || !window.isShowing()) { + throw new IllegalArgumentException("window must be displayable and showing. window=" + window); + } + if (ratio < 0.0f || ratio > 1.0f) { + throw new IllegalArgumentException("ratio must be in [0..1] range. ratio=" + ratio); + } + if (!isAlphaModeSupported() || !isAlphaModeEnabled(window)) { + return; + } + setAlphaModeRatioWin32Impl(window, 255 - (int)(255f * ratio)); + } + + private static native void setAlphaModeRatioWin32Impl(Window window, int ratio); + + public final boolean isAlphaModeEnabled(final Window window) { + if (!window.isDisplayable() || !window.isShowing()) { + throw new IllegalArgumentException("window must be displayable and showing. window=" + window); + } + if (!isAlphaModeSupported()) { + return false; + } + else { + return isAlphaModeEnabledWin32Impl(window); + } + } + + private static native boolean isAlphaModeEnabledWin32Impl(Window window); + + public final void setAlphaModeEnabled(final Window window, final boolean state) { + if (!window.isDisplayable() || !window.isShowing()) { + throw new IllegalArgumentException("window must be displayable and showing. window=" + window); + } + if (!isAlphaModeSupported()) { + return; + } + else { + setAlphaModeEnabledWin32Impl(window, state); + } + } + + public void hideDialog(JDialog dialog, Project project) { + if (project == null) { + dialog.dispose(); + } + else { + IdeFrame frame = getFrame(project); + if (frame.isActive()) { + dialog.dispose(); + } + else { + queueForDisposal(dialog, project); + dialog.hide(); + } + } + } + + private static native void setAlphaModeEnabledWin32Impl(Window window, boolean state); + + public final void disposeComponent() {} + + public final void initComponent() { + showFrame(); + } + + public final void doNotSuggestAsParent(final Window window) { + myWindowWatcher.doNotSuggestAsParent(window); + } + + public final void dispatchComponentEvent(final ComponentEvent e) { + myWindowWatcher.dispatchComponentEvent(e); + } + + public final Window suggestParentWindow(final Project project) { + return myWindowWatcher.suggestParentWindow(project); + } + +// made non-final for Fabrique + public StatusBar getStatusBar(final Project project) { + if (!myProject2Frame.containsKey(project)) { + return null; + } + final IdeFrame frame = getFrame(project); + LOG.assertTrue(frame != null); + return frame.getStatusBar(); + } + + // made non-final for Fabrique + public IdeFrame getFrame(final Project project) { + // no assert! otherwise WindowWatcher.suggestParentWindow fails for default project + //LOG.assertTrue(myProject2Frame.containsKey(project)); + final IdeFrame frame = myProject2Frame.get(project); + return frame; + } + + public final IdeFrame allocateFrame(final Project project) { + LOG.assertTrue(!myProject2Frame.containsKey(project)); + + final IdeFrame frame; + if (myProject2Frame.containsKey(null)) { + frame = myProject2Frame.get(null); + myProject2Frame.remove(null); + myProject2Frame.put(project, frame); + frame.setProject(project); + } + else { + frame = new IdeFrame((ApplicationInfoEx)ApplicationInfo.getInstance(), ActionManager.getInstance(), UISettings.getInstance(), DataManager.getInstance(), KeymapManagerEx.getInstance()); + if (myFrameBounds != null) { + frame.setBounds(myFrameBounds); + } + frame.setProject(project); + myProject2Frame.put(project, frame); + frame.show(); + } + + frame.addWindowListener(myActivationListener); + + return frame; + } + + private void proceedDialogDisposalQueue(Project project) { + Set dialogs = myDialogsToDispose.get(project); + if (dialogs == null) return; + for (Iterator iterator = dialogs.iterator(); iterator.hasNext();) { + iterator.next().dispose(); + } + myDialogsToDispose.put(project, null); + } + + private void queueForDisposal(JDialog dialog, Project project) { + Set dialogs = myDialogsToDispose.get(project); + if (dialogs == null) { + dialogs = new HashSet(); + myDialogsToDispose.put(project, dialogs); + } + dialogs.add(dialog); + } + + public final void releaseFrame(final IdeFrame frame) { + final Project project = frame.getProject(); + LOG.assertTrue(project != null); + + frame.removeWindowListener(myActivationListener); + proceedDialogDisposalQueue(project); + + frame.setProject(null); + frame.setTitle(null); + frame.setFileTitle(null); + + final StatusBarEx statusBar = frame.getStatusBar(); + statusBar.setStatus(null); + statusBar.setWriteStatus(false); + statusBar.setPosition(null); + statusBar.updatePopupHintsStatus(); + + myProject2Frame.remove(project); + if (myProject2Frame.size() == 0) { + myProject2Frame.put(null, frame); + } + else { + frame.dispose(); + } + } + + public final Window getMostRecentFocusedWindow() { + return myWindowWatcher.getFocusedWindow(); + } + +// made non-final for Fabrique + public Component getFocusedComponent(final Window window) { + return myWindowWatcher.getFocusedComponent(window); + } + + public final Component getFocusedComponent(final Project project) { + return myWindowWatcher.getFocusedComponent(project); + } + + /** + * Private part + */ + public final CommandProcessor getCommandProcessor() { + return myCommandProcessor; + } + + public final String getExternalFileName() { + return "window.manager"; + } + +// Non final for Fabrique + public void readExternal(final Element element) throws InvalidDataException { + final Element frameElement = element.getChild("frame"); + if (frameElement != null) { +// load frame bounds + myFrameBounds = new Rectangle(); + try { + myFrameBounds.x = Integer.parseInt(frameElement.getAttributeValue("x")); + } + catch (NumberFormatException ignored) { + } + try { + myFrameBounds.y = Integer.parseInt(frameElement.getAttributeValue("y")); + } + catch (NumberFormatException ignored) { + } + try { + myFrameBounds.width = Integer.parseInt(frameElement.getAttributeValue("width")); + } + catch (NumberFormatException ignored) { + } + try { + myFrameBounds.height = Integer.parseInt(frameElement.getAttributeValue("height")); + } + catch (NumberFormatException ignored) { + } + try { + myFrameExtendedState = Integer.parseInt(frameElement.getAttributeValue("extended-state")); + if ((myFrameExtendedState & Frame.ICONIFIED) > 0) { + myFrameExtendedState = Frame.NORMAL; + } + } + catch (NumberFormatException ignored) { + } + } + + final Element desktopElement = element.getChild(DesktopLayout.TAG); + if (desktopElement != null) { + myLayout.readExternal(desktopElement); + } + } + +// Non final for Fabrique + public void writeExternal(final org.jdom.Element element) throws WriteExternalException { + // Save frame bounds + final Element frameElement = new Element("frame"); + element.addContent(frameElement); + final Project[] projects = ProjectManager.getInstance().getOpenProjects(); + final Project project; + if (projects.length > 0) { + project = projects[projects.length - 1]; + } + else { + project = null; + } + final IdeFrame frame = getFrame(project); + LOG.assertTrue(frame != null); + final Rectangle rectangle = frame.getBounds(); + frameElement.setAttribute("x", Integer.toString(rectangle.x)); + frameElement.setAttribute("y", Integer.toString(rectangle.y)); + frameElement.setAttribute("width", Integer.toString(rectangle.width)); + frameElement.setAttribute("height", Integer.toString(rectangle.height)); + frameElement.setAttribute("extended-state", Integer.toString(frame.getExtendedState())); + // Save default layout + final Element layoutElement = new Element(DesktopLayout.TAG); + element.addContent(layoutElement); + myLayout.writeExternal(layoutElement); + } + + public final DesktopLayout getLayout() { + return myLayout; + } + + public final void setLayout(final DesktopLayout layout) { + myLayout.copyFrom(layout); + } + + public final String getComponentName() { + return "WindowManager"; + } + + /** + * We cannot clear selected menu path just by changing of focused window. Under Windows LAF + * focused window changes sporadically when user clickes on menu item or submenu. The problem + * is that all popups under Windows LAF always has native window ancestor. This window isn't + * focusable but by mouse click focused window changes in this manner: + * InitialFocusedWindow->null + * null->InitialFocusedWindow + * To fix this problem we use alarm to accumulate such focus events. + */ + private static final class SUN_BUG_ID_4218084_Patch implements PropertyChangeListener { + private final Alarm myAlarm; + private Window myInitialFocusedWindow; + private Window myLastFocusedWindow; + private final Runnable myClearSelectedPathRunnable; + + public SUN_BUG_ID_4218084_Patch() { + myAlarm = new Alarm(); + myClearSelectedPathRunnable = new Runnable() { + public void run() { + if (myInitialFocusedWindow != myLastFocusedWindow) { + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + } + }; + } + + public void propertyChange(final PropertyChangeEvent e) { + if (myAlarm.getActiveRequestCount() == 0) { + myInitialFocusedWindow = (Window)e.getOldValue(); + final MenuElement[] selectedPath = MenuSelectionManager.defaultManager().getSelectedPath(); + if (selectedPath.length == 0) { // there is no visible popup + return; + } + Component firstComponent = null; + for (int i = 0; i < selectedPath.length; i++) { + final MenuElement menuElement = selectedPath[i]; + final Component component = menuElement.getComponent(); + if (component instanceof JMenuBar) { + firstComponent = component; + break; + } + else if (component instanceof JPopupMenu) { + firstComponent = ((JPopupMenu)component).getInvoker(); + break; + } + } + if (firstComponent == null) { + return; + } + final Window window = SwingUtilities.getWindowAncestor(firstComponent); + if (window != myInitialFocusedWindow) { // focused window doesn't have popup + return; + } + } + myLastFocusedWindow = (Window)e.getNewValue(); + myAlarm.cancelAllRequests(); + myAlarm.addRequest(myClearSelectedPathRunnable, 150); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowWatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowWatcher.java new file mode 100644 index 00000000000..6acb72e7fec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/WindowWatcher.java @@ -0,0 +1,289 @@ +package com.intellij.openapi.wm.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.FocusWatcher; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class WindowWatcher implements PropertyChangeListener{ + private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.wm.impl.WindowWatcher"); + private final Object myLock; + private final HashMap myWindow2Info; + /** + * Currenly focused window (window which has focused component). Can be null if there is no focused + * window at all. + */ + private Window myFocusedWindow; + /** + * Contains last focused window for each project. + */ + private final HashSet myFocusedWindows; + + WindowWatcher(){ + myLock=new Object(); + myWindow2Info=new HashMap(); + myFocusedWindows=new HashSet(); + } + + /** + * This method should get notifications abount changes of focused window. + * Only focusedWindow property is acceptable. + * @throws IllegalArgumentException if property name isn't focusedWindow. + */ + public final void propertyChange(final PropertyChangeEvent e){ + if(LOG.isDebugEnabled()){ + LOG.debug("enter: propertyChange("+e+")"); + } + if(!"focusedWindow".equals(e.getPropertyName())){ + throw new IllegalArgumentException("unknown property name: "+e.getPropertyName()); + } + synchronized(myLock){ + final Window window=(Window)e.getNewValue(); + if(window==null){ + return; + } + if(!myWindow2Info.containsKey(window)){ + myWindow2Info.put(window,new WindowInfo(window, true)); + } + myFocusedWindow=window; + final Project project = (Project)DataManager.getInstance().getDataContext(myFocusedWindow).getData(DataConstants.PROJECT); + for (Iterator i = myFocusedWindows.iterator(); i.hasNext();) { + final Window w = (Window)i.next(); + if (project==DataManager.getInstance().getDataContext(w).getData(DataConstants.PROJECT)) { + i.remove(); + } + } + myFocusedWindows.add(myFocusedWindow); + // Set new root frame + final IdeFrame frame; + if(window instanceof IdeFrame){ + frame=(IdeFrame)window; + }else{ + frame=(IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class,window); + } + if(frame!=null){ + JOptionPane.setRootFrame(frame); + } + } + if(LOG.isDebugEnabled()){ + LOG.debug("exit: propertyChange()"); + } + } + + final void dispatchComponentEvent(final ComponentEvent e){ + final int id=e.getID(); + if(WindowEvent.WINDOW_CLOSED==id||(ComponentEvent.COMPONENT_HIDDEN==id&&e.getSource() instanceof Window)){ + dispatchHiddenOrClosed((Window)e.getSource()); + } + // Clear obsolete reference on root frame + if(WindowEvent.WINDOW_CLOSED==id){ + final Window window=(Window)e.getSource(); + if(JOptionPane.getRootFrame()==window){ + JOptionPane.setRootFrame(null); + } + } + } + + private void dispatchHiddenOrClosed(final Window window){ + if(LOG.isDebugEnabled()){ + LOG.debug("enter: dispatchClosed("+window+")"); + } + synchronized(myLock){ + final WindowInfo info=myWindow2Info.get(window); + if(info!=null){ + final FocusWatcher focusWatcher=info.myFocusWatcherRef.get(); + if(focusWatcher!=null){ + focusWatcher.deinstall(window); + } + myWindow2Info.remove(window); + } + } + // Now, we have to recalculate focused window if currently focused + // window is being closed. + if(myFocusedWindow==window){ + if(LOG.isDebugEnabled()){ + LOG.debug("currently active window should be closed"); + } + myFocusedWindow=myFocusedWindow.getOwner(); + if (LOG.isDebugEnabled()) { + LOG.debug("new active window is "+myFocusedWindow); + } + } + for(Iterator i=myFocusedWindows.iterator();i.hasNext();){ + final Window activeWindow = (Window)i.next(); + if (activeWindow == window) { + final Window newActiveWindow = activeWindow.getOwner(); + i.remove(); + if (newActiveWindow != null) { + myFocusedWindows.add(newActiveWindow); + } + break; + } + } + // Remove invalid infos for garbage collected windows + for(Iterator i=myWindow2Info.values().iterator();i.hasNext();){ + final WindowInfo info=(WindowInfo)i.next(); + if(info.myFocusWatcherRef.get()==null){ + if (LOG.isDebugEnabled()) { + LOG.debug("remove collected info"); + } + i.remove(); + } + } + } + + public final Window getFocusedWindow(){ + synchronized(myLock){ + return myFocusedWindow; + } + } + + public final Component getFocusedComponent(final Project project){ + synchronized(myLock){ + final Window window=getFocusedWindowForProject(project); + if(window==null){ + return null; + } + return getFocusedComponent(window); + } + } + + + public final Component getFocusedComponent(final Window window){ + synchronized(myLock){ + if(window==null){ + throw new IllegalArgumentException("window is null"); + } + final WindowInfo info=myWindow2Info.get(window); + if(info==null){ // it means that we don't manage this window, so just return standard focus owner + // return window.getFocusOwner(); + // TODO[vova,anton] usage of getMostRecentFocusOwner is experimental. But it seems suitable here. + return window.getMostRecentFocusOwner(); + } + final FocusWatcher focusWatcher=info.myFocusWatcherRef.get(); + if(focusWatcher!=null){ + final Component focusedComponent = focusWatcher.getFocusedComponent(); + if(focusedComponent != null && focusedComponent.isShowing()){ + return focusedComponent; + } + else{ + return null; + } + }else{ + // info isn't valid, i.e. window was garbage collected, so we need the remove invalid info + // and return null + myWindow2Info.remove(window); + return null; + } + } + } + + /** + * @param project may be null (for example, if no projects are opened) + */ + public final Window suggestParentWindow(final Project project){ + synchronized(myLock){ + Window window=getFocusedWindowForProject(project); + if(window==null){ + if (project != null) { + return WindowManagerEx.getInstanceEx().getFrame(project); + } + else{ + return null; + } + } + + LOG.assertTrue(window.isDisplayable()); + LOG.assertTrue(window.isShowing()); + + while(window!=null){ + // skip all windows until found forst dialog or frame + if(!(window instanceof Dialog)&&!(window instanceof Frame)){ + window=window.getOwner(); + continue; + } + // skip not visible and disposed/not shown windows + if(!window.isDisplayable()||!window.isShowing()){ + window = window.getOwner(); + continue; + } + // skip windows that have not associated WindowInfo + final WindowInfo info=myWindow2Info.get(window); + if(info==null){ + window=window.getOwner(); + continue; + } + if(info.mySuggestAsParent){ + return window; + }else{ + window=window.getOwner(); + } + } + return null; + } + } + + public final void doNotSuggestAsParent(final Window window){ + if(LOG.isDebugEnabled()){ + LOG.debug("enter: doNotSuggestAsParent("+window+")"); + } + synchronized(myLock){ + final WindowInfo info=myWindow2Info.get(window); + if(info==null){ + myWindow2Info.put(window,new WindowInfo(window, false)); + }else{ + info.mySuggestAsParent=false; + } + } + } + + /** + * @return active window for specified project. There is only one window + * for project can be at any point of time. + */ + private Window getFocusedWindowForProject(final Project project){ + //todo[anton,vova]: it is possible that returned wnd is not contained in myFocusedWindows; investigate + outer: for(Iterator i=myFocusedWindows.iterator();i.hasNext();){ + Window window=(Window)i.next(); + while(!window.isDisplayable()||!window.isShowing()){ // if window isn't visible then gets its first visible ancestor + window=window.getOwner(); + if(window==null){ + continue outer; + } + } + if (project==DataManager.getInstance().getDataContext(window).getData(DataConstants.PROJECT)) { + return window; + } + } + return null; + } + + private static final class WindowInfo { + public final WeakReference myFocusWatcherRef; + public boolean mySuggestAsParent; + + public WindowInfo(final Window window,final boolean suggestAsParent){ + final FocusWatcher focusWatcher=new FocusWatcher(); + focusWatcher.install(window); + myFocusWatcherRef=new WeakReference(focusWatcher); + mySuggestAsParent=suggestAsParent; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/ApplyWindowInfoCmd.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/ApplyWindowInfoCmd.java new file mode 100644 index 00000000000..015fe56735c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/ApplyWindowInfoCmd.java @@ -0,0 +1,38 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.openapi.wm.impl.commands; + +import com.intellij.openapi.wm.impl.commands.FinalizableCommand; +import com.intellij.openapi.wm.impl.*; + +/** + * Apply info to the corresponded tool button and decarator. + * Command uses freezed copy of passed info object. + */ +public final class ApplyWindowInfoCmd extends FinalizableCommand{ + private final WindowInfo myInfo; + private final StripeButton myButton; + private final InternalDecorator myDecorator; + + public ApplyWindowInfoCmd( + final WindowInfo info, + final StripeButton button, + final InternalDecorator decorator, + final Runnable finishCallBack + ){ + super(finishCallBack); + myInfo=info.copy(); + myButton=button; + myDecorator=decorator; + } + + public final void run(){ + try{ + myButton.apply(myInfo); + myDecorator.apply(myInfo); + }finally{ + finish(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java new file mode 100644 index 00000000000..bdf0e96cb7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java @@ -0,0 +1,16 @@ +package com.intellij.openapi.wm.impl.commands; + +/** + * @author Vladimir Kondratyev + */ +public abstract class FinalizableCommand implements Runnable{ + private final Runnable myFinishCallBack; + + public FinalizableCommand(final Runnable finishCallBack){ + myFinishCallBack=finishCallBack; + } + + public final void finish(){ + myFinishCallBack.run(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/InvokeLaterCmd.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/InvokeLaterCmd.java new file mode 100644 index 00000000000..05aeee726d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/InvokeLaterCmd.java @@ -0,0 +1,23 @@ +package com.intellij.openapi.wm.impl.commands; + + + +/** + * @author Vladimir Kondratyev + */ +public final class InvokeLaterCmd extends FinalizableCommand{ + private final Runnable myRunnable; + + public InvokeLaterCmd(final Runnable runnable,final Runnable finishCallBack){ + super(finishCallBack); + myRunnable=runnable; + } + + public void run(){ + try{ + myRunnable.run(); + }finally{ + finish(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java new file mode 100644 index 00000000000..361a2347007 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java @@ -0,0 +1,78 @@ +/** + * @author Vladimir Kondratyev + */ +package com.intellij.openapi.wm.impl.commands; + +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.wm.impl.FloatingDecorator; + +import javax.swing.*; +import java.awt.*; + +/** + * Requests focus for the editor component. + */ +public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{ + private final FileEditorManagerEx myEditorManager; + private final JComponent myComponent; + + public RequestFocusInEditorComponentCmd(final FileEditorManagerEx editorManager, final Runnable finishCallBack){ + super(finishCallBack); + if(editorManager == null){ + throw new IllegalArgumentException("component cannot be null"); + } + myEditorManager = editorManager; + myComponent = myEditorManager.getPreferredFocusedComponent(); + } + + public final void run(){ + try{ + final Window owner=SwingUtilities.getWindowAncestor(myEditorManager.getComponent()); + if(owner==null){ + return; + } + // if owner is active window or it has active child window which isn't floating decorator then + // don't bring owner window to font. If we will make toFront every time then it's possible + // the following situation: + // 1. user prform refactoring + // 2. "Do not show preview" dialog is popping up. + // 3. At that time "preview" tool window is being activated and modal "don't show..." dialog + // isn't active. + if(!owner.isActive()){ + final Window activeWindow=getActiveWindow(owner.getOwnedWindows()); + if(activeWindow == null || (activeWindow instanceof FloatingDecorator)){ + //Thread.dumpStack(); + //System.out.println("------------------------------------------------------"); + owner.toFront(); + } + } + + if(myComponent != null){ + if(!myComponent.requestFocusInWindow()){ + myComponent.requestFocus(); + } + } + + }finally{ + finish(); + } + } + + /** + * @return first active window from hierarchy with specified roots. Returns null + * if there is no active window in the hierarchy. + */ + private Window getActiveWindow(final Window[] windows){ + for(int i=0;inull + * if there is no active window in the hierarchy. + */ + private Window getActiveWindow(final Window[] windows){ + for(int i=0;i 0) { + result.append('\n'); + } + result.append(line); + } + return result.toString(); + } + + + public final void updateUI() { + super.updateUI(); + final Font font = UIManager.getFont("Label.font"); + if (font!=null){ + STATUS_FONT = font;//.deriveFont(Font.BOLD, font.getSize()); + setFont(STATUS_FONT); + } + } + + public final void setText(final String text) { + myText = text; + repaint(); + } + + public final void setEnabled(final boolean enabled) { + myEnabled = enabled; + } + + public final void paintComponent(final Graphics g) { + super.paintComponent(g); + g.setColor( + myEnabled ? UIManager.getColor("Label.foreground") : getBackground().darker()/*UIManager.getColor("Label.disabledForeground")*/ + ); + g.setFont(STATUS_FONT); + g.drawString(myText, 10, getLineHeight()+(getSize().height-getLineHeight())/2); + } + + public final Dimension getPreferredSize(){ + int max = 0; + for (int i = 0; i < myPossibleStrings.length; i++) { + max = Math.max(max, getLineWidth(myPossibleStrings[i])); + } + return new Dimension(20 + max, getLineHeight() + 6); + } + + private int getLineHeight() { + return getFontMetrics(STATUS_FONT).getAscent(); + } + + private int getLineWidth(final String longestString) { + return getFontMetrics(STATUS_FONT).stringWidth(longestString); + } + + private final class MyMouseListener extends MouseAdapter { + private LightweightHint myHint; + + public void mouseEntered(final MouseEvent e){ + if (myHint != null) { + myHint.hide(); + myHint = null; + } + + final int widthLimit = getSize().width - 20; + + if (getFontMetrics(STATUS_FONT).stringWidth(myText) < widthLimit) return; + + final JLabel label = new JLabel(); + label.setBorder( + BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(Color.black), + BorderFactory.createEmptyBorder(0,5,0,5) + ) + ); + label.setForeground(Color.black); + label.setBackground(HintUtil.INFORMATION_COLOR); + label.setOpaque(true); + label.setUI(new MultiLineLabelUI()); + + final JLayeredPane layeredPane = getRootPane().getLayeredPane(); + + + label.setText(splitText(label, myText, layeredPane.getWidth() - 10)); + + final Point p = SwingUtilities.convertPoint(TextPanel.this, 1, getHeight() - 1, layeredPane); + p.y -= label.getPreferredSize().height; + + myHint = new LightweightHint(label); + myHint.show(layeredPane, p.x, p.y, null); + } + + public void mouseExited(final MouseEvent e){ + if (myHint != null) { + myHint.hide(); + myHint = null; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java new file mode 100644 index 00000000000..fe3000b45c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java @@ -0,0 +1,130 @@ +package com.intellij.openapi.wm.impl.status; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.ui.PopupHandler; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +//Made public for Fabrique +public class TogglePopupHintsPanel extends TextPanel { + private static final String STATE_ON_MSG = "Import Popup: ON"; + private static final String STATE_OFF_MSG = "Import Popup: OFF"; + + public TogglePopupHintsPanel(ActionManager actionManager) { + super(new String[]{STATE_ON_MSG, STATE_OFF_MSG}, false); + final DefaultActionGroup group = new DefaultActionGroup(); + group.add(new TurnOnAction()); + group.add(new TurnOffAction()); + PopupHandler.installUnknownPopupHandler(this, group, actionManager); + + addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2 && isStateChangeable()) { + setHintsState(!getCurrentState()); + } + } + }); + } + + void update() { + if (isStateChangeable()) { + setText(getCurrentState() ? STATE_ON_MSG : STATE_OFF_MSG); + setToolTipText("Double-click to toggle popup hints for this file"); + } + else { + setText(""); + setToolTipText(null); + } + } + + private boolean isStateChangeable() { + final PsiFile file = getCurrentFile(); + if (file == null) { + return false; + } + return DaemonCodeAnalyzer.getInstance(getCurrentProject()).isAutohintsAvailable(file); + } + + private boolean getCurrentState() { + if (!isStateChangeable()) { + return false; + } + final PsiFile file = getCurrentFile(); + final Project project = getCurrentProject(); + return DaemonCodeAnalyzer.getInstance(project).isImportHintsEnabled(file); + } + + private PsiFile getCurrentFile() { + final Project project = getCurrentProject(); + if (project == null) { + return null; + } + + final VirtualFile[] files = FileEditorManager.getInstance(project).getSelectedFiles(); + if (files.length == 0 || !files[0].isValid()) { + return null; + } + + final PsiFile file = PsiManager.getInstance(project).findFile(files[0]); + return file; + } + + private Project getCurrentProject() { + return (Project)DataManager.getInstance().getDataContext(this).getData(DataConstants.PROJECT); + } + + private void setHintsState(final boolean isOn) { + final PsiFile file = getCurrentFile(); + if (file == null) { + return; + } + DaemonCodeAnalyzer.getInstance(getCurrentProject()).setImportHintsEnabled(file, isOn); + update(); + } + + private final class TurnOnAction extends ToggleAction { + public TurnOnAction() { + super("Import Popup ON"); + } + + public boolean isSelected(final AnActionEvent event) { + return getCurrentState(); + } + + public void setSelected(final AnActionEvent event,final boolean flag) { + setHintsState(true); + } + + public void update(final AnActionEvent e){ + super.update(e); + e.getPresentation().setEnabled(isStateChangeable()); + } + } + + private final class TurnOffAction extends ToggleAction { + public TurnOffAction() { + super("Import Popup OFF"); + } + + public boolean isSelected(final AnActionEvent event) { + return !getCurrentState(); + } + + public void setSelected(final AnActionEvent event,final boolean flag) { + setHintsState(false); + } + + public void update(final AnActionEvent e){ + super.update(e); + e.getPresentation().setEnabled(isStateChangeable()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java new file mode 100644 index 00000000000..ffe7dd5b9f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/openapi/wm/impl/status/ToggleReadOnlyAttributePanel.java @@ -0,0 +1,56 @@ +package com.intellij.openapi.wm.impl.status; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.io.ReadOnlyAttributeUtil; + +import javax.swing.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; + +//Made public for Fabrique +public class ToggleReadOnlyAttributePanel extends JLabel { + public ToggleReadOnlyAttributePanel() { + setToolTipText("Double-click to toggle the read-only attribute"); + addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { + processDoubleClick(); + } + } + }); + setIconTextGap(0); + } + + private void processDoubleClick() { + final Project project = (Project)DataManager.getInstance().getDataContext(this).getData(DataConstants.PROJECT); + if (project == null) { + return; + } + final FileEditorManager editorManager = FileEditorManager.getInstance(project); + final VirtualFile[] files = editorManager.getSelectedFiles(); + if (files.length == 0 || !(files[0].getFileSystem() instanceof LocalFileSystem)) { + return; + } + FileDocumentManager.getInstance().saveAllDocuments(); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + ReadOnlyAttributeUtil.setReadOnlyAttribute(files[0], files[0].isWritable()); + } + catch (IOException e) { + Messages.showMessageDialog(project, e.getMessage(), "Error", Messages.getErrorIcon()); + } + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependenciesBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependenciesBuilder.java new file mode 100644 index 00000000000..d757def7304 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependenciesBuilder.java @@ -0,0 +1,144 @@ +package com.intellij.packageDependencies; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; + +import java.util.*; + +public class DependenciesBuilder { + private Project myProject; + private final AnalysisScope myScope; + private final Map> myDependencies = new HashMap>(); + private final int myTotalFileCount; + private int myFileCount = 0; + + public DependenciesBuilder(Project project, AnalysisScope scope) { + myProject = project; + myScope = scope; + myTotalFileCount = scope.getFileCount(); + } + + public AnalysisScope getScope() { + return myScope; + } + + public void analyze() { + final PsiManager psiManager = PsiManager.getInstance(myProject); + psiManager.startBatchFilesProcessingMode(); + try { + myScope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitFile(final PsiFile file) { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + if (indicator.isCanceled()) { + throw new ProcessCanceledException(); + } + indicator.setText("Analyzing package dependencies"); + indicator.setText2(file.getVirtualFile().getPresentableUrl()); + indicator.setFraction(((double)++myFileCount) / myTotalFileCount); + } + + final Set fileDeps = new HashSet(); + myDependencies.put(file, fileDeps); + analyzeFileDependencies(file, new DependencyProcessor() { + public void process(PsiElement place, PsiElement dependency) { + PsiFile dependencyFile = dependency.getContainingFile(); + if (dependencyFile != null && dependencyFile.isPhysical()) { + fileDeps.add(dependencyFile); + } + } + }); + psiManager.dropResolveCaches(); + } + }); + } + finally { + psiManager.finishBatchFilesProcessingMode(); + } + } + + public Map> getDependencies() { + return myDependencies; + } + + public Map>> getIllegalDependencies() { + Map>> result = new HashMap>>(); + DependencyValidationManager validator = DependencyValidationManager.getInstance(myProject); + for (Iterator iterator = myDependencies.keySet().iterator(); iterator.hasNext();) { + PsiFile file = iterator.next(); + Set deps = myDependencies.get(file); + Map> illegal = null; + for (Iterator depsIterator = deps.iterator(); depsIterator.hasNext();) { + PsiFile dependency = depsIterator.next(); + final DependencyRule rule = validator.getViolatorDependencyRule(file, dependency); + if (rule != null) { + if (illegal == null) { + illegal = new HashMap>(); + result.put(file, illegal); + } + Set illegalFilesByRule = illegal.get(rule); + if (illegalFilesByRule == null) { + illegalFilesByRule = new HashSet(); + } + illegalFilesByRule.add(dependency); + illegal.put(rule, illegalFilesByRule); + } + } + } + return result; + } + + public void analyzeFileDependencies(PsiFile file, DependencyProcessor processor) { + file.accept(new DependenciesWalker(processor)); + } + + public interface DependencyProcessor { + void process(PsiElement place, PsiElement dependency); + } + + private static class DependenciesWalker extends PsiRecursiveElementVisitor { + private final DependencyProcessor myProcessor; + + public DependenciesWalker(DependencyProcessor processor) { + myProcessor = processor; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitElement(PsiElement element) { + super.visitElement(element); + PsiReference[] refs = element.getReferences(); + for (int i = 0; i < refs.length; i++) { + PsiReference ref = refs[i]; + PsiElement resolved = ref.resolve(); + if (resolved != null) { + myProcessor.process(ref.getElement(), resolved); + } + } + } + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + PsiMethod psiMethod = expression.resolveMethod(); + if (psiMethod != null) { + PsiType returnType = psiMethod.getReturnType(); + if (returnType != null) { + PsiClass psiClass = PsiUtil.resolveClassInType(returnType); + if (psiClass != null) { + myProcessor.process(expression, psiClass); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyRule.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyRule.java new file mode 100644 index 00000000000..5433537b313 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyRule.java @@ -0,0 +1,77 @@ +package com.intellij.packageDependencies; + +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.scope.packageSet.ComplementPackageSet; +import com.intellij.psi.search.scope.packageSet.NamedScope; + +public class DependencyRule { + private NamedScope myFromScope; + private NamedScope myToScope; + private boolean myDenyRule = true; + + public DependencyRule(NamedScope fromPackageSet, NamedScope toPackageSet, boolean isDenyRule) { + myFromScope = fromPackageSet; + myToScope = toPackageSet; + myDenyRule = isDenyRule; + } + + public boolean isForbiddenToUse(PsiFile from, PsiFile to) { + if (myFromScope == null || myToScope == null) return false; + DependencyValidationManager holder = DependencyValidationManager.getInstance(from.getProject()); + return (myDenyRule + ? myFromScope.getValue().contains(from, holder) + : new ComplementPackageSet(myFromScope.getValue()).contains(from, holder)) && + myToScope.getValue().contains(to, holder); + } + + public String getDisplayText() { + StringBuffer buf = new StringBuffer(); + buf.append(myDenyRule ? "Deny " : "Allow "); + buf.append("usages of '"); + if (myToScope != null) { + buf.append(myToScope.getName()); + } + buf.append("' " + (myDenyRule ? " " : "only ") + "in '"); + if (myFromScope != null) { + buf.append(myFromScope.getName()); + } + buf.append('\''); + return buf.toString(); + } + + public boolean equals(Object o) { + if (!(o instanceof DependencyRule)) return false; + DependencyRule rule = (DependencyRule)o; + return getDisplayText().equals(rule.getDisplayText()); + } + + public int hashCode() { + return getDisplayText().hashCode(); + } + + public DependencyRule createCopy() { + return new DependencyRule(myFromScope == null ? null : myFromScope.createCopy(), + myToScope == null ? null : myToScope.createCopy(), + myDenyRule); + } + + public boolean isDenyRule() { + return myDenyRule; + } + + public NamedScope getFromScope() { + return myFromScope; + } + + public void setFromScope(NamedScope fromScope) { + myFromScope = fromScope; + } + + public NamedScope getToScope() { + return myToScope; + } + + public void setToScope(NamedScope toScope) { + myToScope = toScope; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyUISettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyUISettings.java new file mode 100644 index 00000000000..118f01cce4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyUISettings.java @@ -0,0 +1,36 @@ +package com.intellij.packageDependencies; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +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 org.jdom.Element; + +public class DependencyUISettings implements JDOMExternalizable, ApplicationComponent { + public boolean UI_FLATTEN_PACKAGES = true; + public boolean UI_SHOW_FILES = false; + public boolean UI_SHOW_MODULES = true; + public boolean UI_FILTER_LEGALS = false; + public boolean UI_GROUP_BY_SCOPE_TYPE = true; + + public static DependencyUISettings getInstance() { + return ApplicationManager.getApplication().getComponent(DependencyUISettings.class); + } + + public String getComponentName() { + return "DependencyUISettings"; + } + + public void initComponent() {} + public void disposeComponent() {} + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyValidationManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyValidationManager.java new file mode 100644 index 00000000000..2e41342e5e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/DependencyValidationManager.java @@ -0,0 +1,144 @@ +package com.intellij.packageDependencies; + +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.*; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.packageDependencies.ui.DependenciesPanel; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; + +public class DependencyValidationManager extends NamedScopesHolder implements ProjectComponent, JDOMExternalizable { + private List myRules = new ArrayList(); + private Project myProject; + private ContentManager myContentManager; + + public DependencyValidationManager(Project project) { + myProject = project; + } + + public static DependencyValidationManager getInstance(Project project) { + return project.getComponent(DependencyValidationManager.class); + } + + public DependencyRule getViolatorDependencyRule(PsiFile from, PsiFile to) { + for (int i = 0; i < myRules.size(); i++) { + DependencyRule dependencyRule = myRules.get(i); + if (dependencyRule.isForbiddenToUse(from, to)) return dependencyRule; + } + + return null; + } + + public DependencyRule[] getAllRules() { + return myRules.toArray(new DependencyRule[myRules.size()]); + } + + public void removeAllRules() { + myRules.clear(); + } + + public void addRule(DependencyRule rule) { + myRules.add(rule); + } + + public void projectOpened() { + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + myContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(true, myProject); + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.DEPENDENCIES, + myContentManager.getComponent(), + ToolWindowAnchor.BOTTOM); + + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowInspection.png")); + new ContentManagerWatcher(toolWindow, myContentManager); + } + }); + } + + public void addContent(DependenciesBuilder builder) { + DependenciesPanel panel = new DependenciesPanel(myProject, builder); + Content content = PeerFactory.getInstance().getContentFactory().createContent(panel, + "Dependencies of " + builder.getScope().getDisplayName(), + false); + panel.setContent(content); + myContentManager.addContent(content); + myContentManager.setSelectedContent(content); + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.DEPENDENCIES).activate(null); + } + + public void closeContent(Content content) { + myContentManager.removeContent(content); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.DEPENDENCIES); + } + + public void initComponent() {} + + public void disposeComponent() {} + + public String getComponentName() { + return "DependencyValidationManager"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + super.readExternal(element); + + List rules = element.getChildren("deny_rule"); + for (int i = 0; i < rules.size(); i++) { + DependencyRule rule = readRule((Element)rules.get(i)); + if (rule != null) { + addRule(rule); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + super.writeExternal(element); + + for (int i = 0; i < myRules.size(); i++) { + DependencyRule rule = myRules.get(i); + Element ruleElement = writeRule(rule); + if (ruleElement != null) { + element.addContent(ruleElement); + } + } + } + + private Element writeRule(DependencyRule rule) { + NamedScope fromScope = rule.getFromScope(); + NamedScope toScope = rule.getToScope(); + if (fromScope == null || toScope == null) return null; + Element ruleElement = new Element("deny_rule"); + ruleElement.setAttribute("from_scope", fromScope.getName()); + ruleElement.setAttribute("to_scope", toScope.getName()); + ruleElement.setAttribute("is_deny", rule.isDenyRule() ? "true" : "false"); + return ruleElement; + } + + private DependencyRule readRule(Element ruleElement) { + String fromScope = ruleElement.getAttributeValue("from_scope"); + String toScope = ruleElement.getAttributeValue("to_scope"); + String denyRule = ruleElement.getAttributeValue("is_deny"); + if (fromScope == null || toScope == null || denyRule == null) return null; + return new DependencyRule(getScope(fromScope), getScope(toScope), denyRule.equals("true")); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/FindDependencyUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/FindDependencyUtil.java new file mode 100644 index 00000000000..b49d2108fe8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/FindDependencyUtil.java @@ -0,0 +1,45 @@ +package com.intellij.packageDependencies; + +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.usageView.UsageInfo; + +import java.util.*; + +public class FindDependencyUtil { + private FindDependencyUtil() {} + + public static UsageInfo[] findDependencies(final DependenciesBuilder builder, Set searchIn, Set searchFor) { + final List usages = new ArrayList(); + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + int totalCount = searchIn.size(); + int count = 0; + + for (Iterator inIterator = searchIn.iterator(); inIterator.hasNext();) { + final PsiFile psiFile = inIterator.next(); + if (indicator != null) { + if (indicator.isCanceled()) throw new ProcessCanceledException(); + indicator.setFraction(((double)++count)/totalCount); + indicator.setText("Searching for usages: " + psiFile.getVirtualFile().getPresentableUrl()); + } + + final Set deps = new HashSet(builder.getDependencies().get(psiFile)); + deps.retainAll(searchFor); + if (deps.isEmpty()) continue; + + builder.analyzeFileDependencies(psiFile, new DependenciesBuilder.DependencyProcessor() { + public void process(PsiElement place, PsiElement dependency) { + PsiFile dependencyFile = dependency.getContainingFile(); + if (deps.contains(dependencyFile)) { + usages.add(new UsageInfo(place)); + } + } + }); + } + + return usages.toArray(new UsageInfo[usages.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesAction.java new file mode 100644 index 00000000000..95d7466d4ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesAction.java @@ -0,0 +1,15 @@ +package com.intellij.packageDependencies.actions; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.analysis.BaseAnalysisAction; +import com.intellij.openapi.project.Project; + +public class AnalyzeDependenciesAction extends BaseAnalysisAction { + public AnalyzeDependenciesAction() { + super(AnalysisScope.SOURCE_JAVA_FILES, "Dependency Analysis", "Analyze", "Analysis"); + } + + protected void analyze(final Project project, AnalysisScope scope) { + new AnalyzeDependenciesHandler(project, scope).analyze(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java new file mode 100644 index 00000000000..0da5d0c8be6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java @@ -0,0 +1,28 @@ +package com.intellij.packageDependencies.actions; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.packageDependencies.DependenciesBuilder; +import com.intellij.packageDependencies.DependencyValidationManager; + +public class AnalyzeDependenciesHandler { + private Project myProject; + private AnalysisScope myScope; + + public AnalyzeDependenciesHandler(Project project, AnalysisScope scope) { + myProject = project; + myScope = scope; + } + + public void analyze() { + final DependenciesBuilder builder = new DependenciesBuilder(myProject, myScope); + if (ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() { + public void run() { + builder.analyze(); + } + }, "Analyzing Dependencies", true, myProject)) { + DependencyValidationManager.getInstance(myProject).addContent(builder); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/packageSet/PackageSetFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/packageSet/PackageSetFactoryImpl.java new file mode 100644 index 00000000000..3b243d2bc06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/packageSet/PackageSetFactoryImpl.java @@ -0,0 +1,187 @@ +package com.intellij.packageDependencies.packageSet; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.TokenType; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.search.scope.packageSet.*; + +public class PackageSetFactoryImpl extends PackageSetFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.packageDependencies.packageSet.PackageSetFactoryImpl"); + + public PackageSetFactoryImpl() {} + + public PackageSet compile(String text) throws ParsingException { + Lexer lexer = new FilterLexer(new JavaLexer(LanguageLevel.JDK_1_3), + new FilterLexer.SetFilter(ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(text.toCharArray()); + return new Parser(lexer).parse(); + } + + private static class Parser { + private Lexer myLexer; + + public Parser(Lexer lexer) { + myLexer = lexer; + } + + public PackageSet parse() throws ParsingException { + PackageSet set = parseUnion(); + if (myLexer.getTokenType() != null) error("Unexpected '" + getTokenText() + "'"); + return set; + } + + private PackageSet parseUnion() throws ParsingException { + PackageSet result = parseIntersection(); + while (true) { + if (myLexer.getTokenType() != TokenType.OROR) break; + myLexer.advance(); + result = new UnionPackageSet(result, parseIntersection()); + } + return result; + } + + private PackageSet parseIntersection() throws ParsingException { + PackageSet result = parseTerm(); + while (true) { + if (myLexer.getTokenType() != TokenType.ANDAND) break; + myLexer.advance(); + result = new IntersectionPackageSet(result, parseTerm()); + } + return result; + } + + private PackageSet parseTerm() throws ParsingException { + if (myLexer.getTokenType() == TokenType.EXCL) { + myLexer.advance(); + return new ComplementPackageSet(parseTerm()); + } + + if (myLexer.getTokenType() == TokenType.LPARENTH) return parseParenthesized(); + if (myLexer.getTokenType() == TokenType.IDENTIFIER && myLexer.getBuffer()[myLexer.getTokenStart()] == '$') { + NamedPackageSetReference namedPackageSetReference = new NamedPackageSetReference(getTokenText()); + myLexer.advance(); + return namedPackageSetReference; + } + return parsePattern(); + } + + private PackageSet parsePattern() throws ParsingException { + String scope = parseScope(); + String modulePattern = parseModulePattern(); + + if (myLexer.getTokenType() == TokenType.COLON) { + if (scope == PatternPackageSet.SCOPE_ANY && modulePattern == null) { + error("(test|lib|src)[modulename] expected before :"); + } + myLexer.advance(); + } + + String pattern = parseAspectJPattern(); + + return new PatternPackageSet(pattern, scope, modulePattern); + } + + private String parseScope() { + if (myLexer.getTokenType() != TokenType.IDENTIFIER) return PatternPackageSet.SCOPE_ANY; + String id = getTokenText(); + String scope = PatternPackageSet.SCOPE_ANY; + if (PatternPackageSet.SCOPE_SOURCE.equals(id)) { + scope = PatternPackageSet.SCOPE_SOURCE; + } + if (PatternPackageSet.SCOPE_TEST.equals(id)) { + scope = PatternPackageSet.SCOPE_TEST; + } + if (PatternPackageSet.SCOPE_LIBRARY.equals(id)) { + scope = PatternPackageSet.SCOPE_LIBRARY; + } + + char[] buf = myLexer.getBuffer(); + int end = myLexer.getTokenEnd(); + int bufferEnd = myLexer.getBufferEnd(); + + if (scope == PatternPackageSet.SCOPE_ANY || end >= bufferEnd || buf[end] != ':' && buf[end] != '[') { + return PatternPackageSet.SCOPE_ANY; + } + + myLexer.advance(); + + return scope; + } + + private String parseAspectJPattern() throws ParsingException { + StringBuffer pattern = new StringBuffer(); + boolean wasIdentifier = false; + while (true) { + if (myLexer.getTokenType() == TokenType.DOT) { + pattern.append('.'); + wasIdentifier = false; + } + else if (myLexer.getTokenType() == TokenType.ASTERISK) { + pattern.append('*'); + wasIdentifier = false; + } + else if (myLexer.getTokenType() == TokenType.IDENTIFIER) { + if (wasIdentifier) error("Unexpected " + getTokenText()); + wasIdentifier = true; + pattern.append(getTokenText()); + } + else { + break; + } + myLexer.advance(); + } + + if (pattern.length() == 0) { + error("Package pattern expected"); + } + + return pattern.toString(); + } + + private String getTokenText() { + int start = myLexer.getTokenStart(); + int end = myLexer.getTokenEnd(); + return new String(myLexer.getBuffer(), start, end - start); + } + + private String parseModulePattern() throws ParsingException { + if (myLexer.getTokenType() != TokenType.LBRACKET) return null; + myLexer.advance(); + StringBuffer pattern = new StringBuffer(); + while (true) { + if (myLexer.getTokenType() == TokenType.RBRACKET) { + myLexer.advance(); + break; + } + + if (myLexer.getTokenType() == TokenType.IDENTIFIER || myLexer.getTokenType() == TokenType.ASTERISK) { + pattern.append(getTokenText()); + myLexer.advance(); + } + else { + error("identifier or whildcard expected as module name pattern"); + } + } + return pattern.toString(); + } + + private PackageSet parseParenthesized() throws ParsingException { + LOG.assertTrue(myLexer.getTokenType() == TokenType.LPARENTH); + myLexer.advance(); + + PackageSet result = parseUnion(); + if (myLexer.getTokenType() != TokenType.RPARENTH) error("')' expected"); + myLexer.advance(); + + return result; + } + + private void error(String message) throws ParsingException { + throw new ParsingException(message + " at position " + (myLexer.getTokenStart() + 1)); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependecyNodeComparator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependecyNodeComparator.java new file mode 100644 index 00000000000..b5a32e007cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependecyNodeComparator.java @@ -0,0 +1,10 @@ +package com.intellij.packageDependencies.ui; + +import java.util.Comparator; + +public class DependecyNodeComparator implements Comparator{ + public int compare(PackageDependenciesNode p1, PackageDependenciesNode p2) { + if (p1.getWeight() != p2.getWeight()) return p1.getWeight() - p2.getWeight(); + return p1.toString().compareTo(p2.toString()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependenciesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependenciesPanel.java new file mode 100644 index 00000000000..04a07e14379 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependenciesPanel.java @@ -0,0 +1,584 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.packageDependencies.DependenciesBuilder; +import com.intellij.packageDependencies.DependencyRule; +import com.intellij.packageDependencies.DependencyUISettings; +import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.packageDependencies.actions.AnalyzeDependenciesHandler; +import com.intellij.pom.Navigatable; +import com.intellij.psi.*; +import com.intellij.ui.*; +import com.intellij.ui.content.Content; +import com.intellij.util.Icons; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.io.StringReader; +import java.util.*; + +public class DependenciesPanel extends JPanel { + private Map> myDependencies; + private Map>> myIllegalDependencies; + private MyTree myLeftTree = new MyTree(); + private JEditorPane myBrowser = new JEditorPane("text/html", ""); + private MyTree myRightTree = new MyTree(); + private UsagesPanel myUsagesPanel; + + private static final HashSet EMPTY_FILE_SET = new HashSet(0); + private TreeExpantionMonitor myRightTreeExpantionMonitor; + private TreeExpantionMonitor myLeftTreeExpantionMonitor; + + private TreeModelBuilder.Marker myRightTreeMarker; + private TreeModelBuilder.Marker myLeftTreeMarker; + private Set myIllegalsInRightTree = new HashSet(); + + private Project myProject; + private DependenciesBuilder myBuilder; + private Content myContent; + + private JComponent myLeftTreePanel; + + public DependenciesPanel(Project project, final DependenciesBuilder builder) { + super(new BorderLayout()); + myDependencies = builder.getDependencies(); + myBuilder = builder; + myIllegalDependencies = myBuilder.getIllegalDependencies(); + myProject = project; + myUsagesPanel = new UsagesPanel(myProject); + + hideHintsWhenNothingToShow(); + + + Splitter treeSplitter = new Splitter(); + treeSplitter.setFirstComponent(myLeftTreePanel); + treeSplitter.setSecondComponent(ScrollPaneFactory.createScrollPane(myRightTree)); + + Splitter splitter = new Splitter(true); + splitter.setFirstComponent(treeSplitter); + splitter.setSecondComponent(myUsagesPanel); + add(splitter, BorderLayout.CENTER); + add(createToolbar(), BorderLayout.NORTH); + + myRightTreeExpantionMonitor = TreeExpantionMonitor.install(myRightTree); + myLeftTreeExpantionMonitor = TreeExpantionMonitor.install(myLeftTree); + + myRightTreeMarker = new TreeModelBuilder.Marker() { + public boolean isMarked(PsiFile file) { + return myIllegalsInRightTree.contains(file); + } + }; + + myLeftTreeMarker = new TreeModelBuilder.Marker() { + public boolean isMarked(PsiFile file) { + return myIllegalDependencies.containsKey(file); + } + }; + + updateLeftTreeModel(); + updateRightTreeModel(); + + myLeftTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + updateRightTreeModel(); + final StringBuffer denyRules = new StringBuffer(); + final StringBuffer allowRules = new StringBuffer(); + PackageDependenciesNode selectedNode = (PackageDependenciesNode)myLeftTree.getSelectionPath().getLastPathComponent(); + traverseToLeaves(selectedNode, denyRules, allowRules); + try { + if (denyRules.length() + allowRules.length() > 0) { + myBrowser.read(new StringReader("The following rule" + + ((denyRules.length() == 0 || allowRules.length() == 0) ? " is " : "s are ") + + "violated: " + + (denyRules.length() > 0 ? denyRules.toString() : " ") + "
    " + + (allowRules.length() > 0 ? allowRules.toString() : " ") + + ""), null); + + } + else { + myBrowser.read(new StringReader("No rules are violated."), null); + } + } + catch (IOException e1) { + //can't be + } + } + }); + + myRightTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Set searchIn = getSelectedScope(myLeftTree); + Set searchFor = getSelectedScope(myRightTree); + if (searchIn.isEmpty() || searchFor.isEmpty()) { + myUsagesPanel.setToInitialPosition(); + } + else { + myUsagesPanel.findUsages(builder, searchIn, searchFor); + } + } + }); + } + }); + + initTree(myLeftTree, false); + initTree(myRightTree, true); + + AnalysisScope scope = builder.getScope(); + if (scope.getScopeType() == AnalysisScope.FILE) { + Set oneFileSet = myDependencies.keySet(); + if (oneFileSet.size() == 1) { + selectElementInLeftTree(oneFileSet.iterator().next()); + } + } + } + + private void traverseToLeaves(final PackageDependenciesNode treeNode, final StringBuffer denyRules, final StringBuffer allowRules) { + for (int i = 0; i < treeNode.getChildCount(); i++) { + traverseToLeaves((PackageDependenciesNode)treeNode.getChildAt(i), denyRules, allowRules); + } + if (myIllegalDependencies.containsKey(treeNode.getPsiElement())) { + final Map> illegalDeps = myIllegalDependencies.get(treeNode.getPsiElement()); + for (Iterator iterator = illegalDeps.keySet().iterator(); iterator.hasNext();) { + final DependencyRule rule = iterator.next(); + if (rule.isDenyRule()) { + if (denyRules.indexOf(rule.getDisplayText()) == -1) { + denyRules.append(rule.getDisplayText()); + denyRules.append("\n"); + } + } + else { + if (allowRules.indexOf(rule.getDisplayText()) == -1) { + allowRules.append(rule.getDisplayText()); + allowRules.append("\n"); + } + } + } + } + } + + private JComponent createToolbar() { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new CloseAction()); + group.add(new RerunAction(this)); + group.add(new FlattenPackagesAction()); + group.add(new ShowFilesAction()); + group.add(new ShowModulesAction()); + group.add(new GroupByScopeTypeAction()); + group.add(new FilterLegalsAction()); + group.add(new EditDependencyRulesAction()); + group.add(new HelpAction()); + + if (((ApplicationEx)ApplicationManager.getApplication()).isInternal()) { + group.add(new ExportZkmAction()); + } + + ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); + return toolbar.getComponent(); + } + + private void rebuild() { + myIllegalDependencies = myBuilder.getIllegalDependencies(); + hideHintsWhenNothingToShow(); + updateLeftTreeModel(); + updateRightTreeModel(); + } + + private void hideHintsWhenNothingToShow() { + if (myIllegalDependencies.isEmpty()) { + myLeftTreePanel = ScrollPaneFactory.createScrollPane(myLeftTree); + } + else { + Splitter leftTreeSplitter = new Splitter(); + leftTreeSplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myLeftTree)); + leftTreeSplitter.setSecondComponent(ScrollPaneFactory.createScrollPane(myBrowser)); + myLeftTreePanel = leftTreeSplitter; + } + } + + private void initTree(final MyTree tree, boolean isRightTree) { + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.setCellRenderer(new MyTreeCellRenderer()); + tree.setRootVisible(false); + tree.setShowsRootHandles(true); + tree.putClientProperty("JTree.lineStyle", "Angled"); + + TreeToolTipHandler.install(tree); + TreeUtil.installActions(tree); + SmartExpander.installOn(tree); + new TreeSpeedSearch(tree); + + PopupHandler.installUnknownPopupHandler(tree, createTreePopupActions(isRightTree), ActionManager.getInstance()); + + tree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.isPopupTrigger() && e.getClickCount() == 2) { + Navigatable navigatable = (Navigatable)tree.getData(DataConstants.NAVIGATABLE); + if (navigatable != null) { + navigatable.navigate(true); + } + } + } + }); + } + + private void updateRightTreeModel() { + Set deps = new HashSet(); + Set scope = getSelectedScope(myLeftTree); + myIllegalsInRightTree = new HashSet(); + for (Iterator iterator = scope.iterator(); iterator.hasNext();) { + PsiFile psiFile = iterator.next(); + Map> illegalDeps = myIllegalDependencies.get(psiFile); + if (illegalDeps != null) { + for (Iterator iterator1 = illegalDeps.keySet().iterator(); iterator1.hasNext();) { + final DependencyRule rule = iterator1.next(); + myIllegalsInRightTree.addAll(illegalDeps.get(rule)); + } + } + deps.addAll(myDependencies.get(psiFile)); + } + deps.removeAll(scope); + myRightTreeExpantionMonitor.freeze(); + myRightTree.setModel(buildTreeModel(deps, myRightTreeMarker)); + myRightTreeExpantionMonitor.restore(); + expandFirstLevel(myRightTree); + } + + private ActionGroup createTreePopupActions(boolean isRightTree) { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); + group.add(ActionManager.getInstance().getAction(IdeActions.GROUP_VERSION_CONTROLS)); + + if (isRightTree) { + group.add(new SelectInLeftTreeAction()); + } + + return group; + } + + private TreeModelBuilder.TreeModel buildTreeModel(Set deps, TreeModelBuilder.Marker marker) { + return TreeModelBuilder.createTreeModel(myProject, false, deps, marker); + } + + private void updateLeftTreeModel() { + Set psiFiles = myDependencies.keySet(); + myLeftTreeExpantionMonitor.freeze(); + myLeftTree.setModel(buildTreeModel(psiFiles, myLeftTreeMarker)); + myLeftTreeExpantionMonitor.restore(); + expandFirstLevel(myLeftTree); + } + + private static void expandFirstLevel(Tree tree) { + PackageDependenciesNode root = (PackageDependenciesNode)tree.getModel().getRoot(); + int count = root.getChildCount(); + if (count < 10) { + for (int i = 0; i < count; i++) { + PackageDependenciesNode child = (PackageDependenciesNode)root.getChildAt(i); + expandNodeIfNotTooWide(tree, child); + } + } + } + + private static void expandNodeIfNotTooWide(Tree tree, PackageDependenciesNode node) { + int count = node.getChildCount(); + if (count > 5) return; + tree.expandPath(new TreePath(node.getPath())); + } + + private Set getSelectedScope(final Tree tree) { + int[] rows = tree.getSelectionRows(); + if (rows == null || rows.length != 1) return EMPTY_FILE_SET; + PackageDependenciesNode node = (PackageDependenciesNode)tree.getPathForRow(rows[0]).getLastPathComponent(); + if (node.isRoot()) return EMPTY_FILE_SET; + Set result = new HashSet(); + node.fillFiles(result, !DependencyUISettings.getInstance().UI_FLATTEN_PACKAGES); + return result; + } + + public void setContent(Content content) { + myContent = content; + } + + public JTree getLeftTree() { + return myLeftTree; + } + + public JTree getRightTree() { + return myRightTree; + } + + private static class MyTreeCellRenderer extends DefaultTreeCellRenderer { + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + PackageDependenciesNode node = (PackageDependenciesNode)value; + if (expanded) { + setIcon(node.getOpenIcon()); + } + else { + setIcon(node.getClosedIcon()); + } + + if (node.hasMarked() && !sel) { + setForeground(Color.red); + } + + return this; + } + } + + private final class CloseAction extends AnAction { + public CloseAction() { + super("Close", "Close Dependency Viewer", IconLoader.getIcon("/actions/cancel.png")); + } + + public void actionPerformed(AnActionEvent e) { + DependencyValidationManager.getInstance(myProject).closeContent(myContent); + } + } + + private final class FlattenPackagesAction extends ToggleAction { + FlattenPackagesAction() { + super("Flatten Packages", "Flatten Packages", IconLoader.getIcon("/objectBrowser/flattenPackages.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_FLATTEN_PACKAGES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_FLATTEN_PACKAGES = flag; + rebuild(); + } + } + + private final class ShowFilesAction extends ToggleAction { + ShowFilesAction() { + super("Show Files", "Show/Hide Files", IconLoader.getIcon("/fileTypes/java.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_SHOW_FILES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_SHOW_FILES = flag; + rebuild(); + } + } + + private final class ShowModulesAction extends ToggleAction { + ShowModulesAction() { + super("Show Modules", "Show/Hide Modules", IconLoader.getIcon("/objectBrowser/showModules.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_SHOW_MODULES; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_SHOW_MODULES = flag; + rebuild(); + } + } + + private final class GroupByScopeTypeAction extends ToggleAction { + GroupByScopeTypeAction() { + super("Group by Scope Type", "Group by Scope Type (production, test, libraries)", IconLoader.getIcon("/nodes/testSourceFolder.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_GROUP_BY_SCOPE_TYPE; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_GROUP_BY_SCOPE_TYPE = flag; + rebuild(); + } + } + + + private final class FilterLegalsAction extends ToggleAction { + FilterLegalsAction() { + super("Show Illegals Only", "Show only files that have illegal dependencies", IconLoader.getIcon("/ant/filter.png")); + } + + public boolean isSelected(AnActionEvent event) { + return DependencyUISettings.getInstance().UI_FILTER_LEGALS; + } + + public void setSelected(AnActionEvent event, boolean flag) { + DependencyUISettings.getInstance().UI_FILTER_LEGALS = flag; + rebuild(); + } + } + + private final class EditDependencyRulesAction extends AnAction { + public EditDependencyRulesAction() { + super("Edit Rules", "Edit Dependency Rules", IconLoader.getIcon("/general/ideOptions.png")); + } + + public void actionPerformed(AnActionEvent e) { + boolean applied = ShowSettingsUtil.getInstance().editConfigurable(DependenciesPanel.this, new DependencyConfigurable(myProject)); + if (applied) { + rebuild(); + } + } + } + + private class RerunAction extends AnAction { + public RerunAction(JComponent comp) { + super("Rerun", "Rerun Dependency Analysis", IconLoader.getIcon("/actions/refreshUsages.png")); + registerCustomShortcutSet(CommonShortcuts.getRerun(), comp); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myBuilder.getScope().isValid()); + } + + public void actionPerformed(AnActionEvent e) { + DependencyValidationManager.getInstance(myProject).closeContent(myContent); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new AnalyzeDependenciesHandler(myProject, myBuilder.getScope()).analyze(); + } + }); + } + } + + private static class HelpAction extends AnAction { + private HelpAction() { + super("Help", null, IconLoader.getIcon("/actions/help.png")); + } + + public void actionPerformed(AnActionEvent event) { + HelpManager.getInstance().invokeHelp("editing.analyzeDependencies"); + } + } + + private class ExportZkmAction extends AnAction { + private ExportZkmAction() { + super("Export ZKM", null, Icons.CUSTOM_FILE_ICON); + } + + public void actionPerformed(AnActionEvent event) { + System.out.println("// -----------------------------------------------------------------------------"); + + Set files = getSelectedScope(myRightTree); + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + PsiFile psiFile = iterator.next(); + if (psiFile instanceof PsiJavaFile) { + PsiClass[] classes = ((PsiJavaFile)psiFile).getClasses(); + for (int i = 0; i < classes.length; i++) { + String qName = classes[i].getQualifiedName(); + String instr = qName.substring(0, qName.lastIndexOf(".") + 1) + "^" + classes[i].getName() + "^"; + + System.out.println(instr + " !private *(*) and"); + System.out.println(instr + " !private * and"); + } + } + } + + System.out.println("// -----------------------------------------------------------------------------"); + } + } + + private static class MyTree extends Tree implements DataProvider { + public Object getData(String dataId) { + PackageDependenciesNode node = getSelectedNode(); + if (node != null && DataConstants.PSI_ELEMENT.equals(dataId)) { + return node.getPsiElement(); + } + return null; + } + + public PackageDependenciesNode getSelectedNode() { + TreePath[] paths = getSelectionPaths(); + if (paths == null || paths.length != 1) return null; + return (PackageDependenciesNode)paths[0].getLastPathComponent(); + } + } + + private class SelectInLeftTreeAction extends AnAction { + public SelectInLeftTreeAction() { + super("Select in Left Tree", "Select in left tree (to browse dependencies from)", null); + } + + public void update(AnActionEvent e) { + boolean enabled = false; + PackageDependenciesNode node = myRightTree.getSelectedNode(); + if (node != null) { + PsiElement elt = node.getPsiElement(); + if (elt != null) { + if (elt instanceof PsiFile) { + enabled = myDependencies.containsKey(elt); + } + else if (elt instanceof PsiPackage) { + Set files = myDependencies.keySet(); + String packageName = ((PsiPackage)elt).getQualifiedName(); + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + PsiFile file = iterator.next(); + if (file instanceof PsiJavaFile && Comparing.equal(packageName, ((PsiJavaFile)file).getPackageName())) { + enabled = true; + break; + } + } + } + } + } + e.getPresentation().setEnabled(enabled); + } + + public void actionPerformed(AnActionEvent e) { + PackageDependenciesNode node = myRightTree.getSelectedNode(); + if (node != null) { + PsiElement elt = node.getPsiElement(); + if (elt != null) { + DependencyUISettings.getInstance().UI_FILTER_LEGALS = false; + selectElementInLeftTree(elt); + + } + } + } + } + + private void selectElementInLeftTree(PsiElement elt) { + PsiManager manager = PsiManager.getInstance(myProject); + + PackageDependenciesNode root = (PackageDependenciesNode)myLeftTree.getModel().getRoot(); + Enumeration enumeration = root.breadthFirstEnumeration(); + while (enumeration.hasMoreElements()) { + PackageDependenciesNode child = (PackageDependenciesNode)enumeration.nextElement(); + if (manager.areElementsEquivalent(child.getPsiElement(), elt)) { + myLeftTree.setSelectionPath(new TreePath(((DefaultTreeModel)myLeftTree.getModel()).getPathToRoot(child))); + break; + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependencyConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependencyConfigurable.java new file mode 100644 index 00000000000..866c8227b8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/DependencyConfigurable.java @@ -0,0 +1,245 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.ide.util.scopeChooser.PackageSetChooserCombo; +import com.intellij.openapi.options.BaseConfigurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.packageDependencies.DependencyRule; +import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.refactoring.ui.EditableRowTableManager; +import com.intellij.refactoring.ui.RowEditableTableModel; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.table.TableView; +import com.intellij.util.ui.AbstractTableCellEditor; +import com.intellij.util.ui.CellEditorComponentWithBrowseButton; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.ListTableModel; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DependencyConfigurable extends BaseConfigurable { + private Project myProject; + private MyTableModel myDenyRulesModel; + private MyTableModel myAllowRulesModel; + private TableView myDenyTable; + private TableView myAllowTable; + + private final ColumnInfo DENY_USAGES_OF = new LeftColumn("Deny usages of"); + private final ColumnInfo DENY_USAGES_IN = new RightColumn("in"); + private final ColumnInfo ALLOW_USAGES_OF = new LeftColumn("Allow usages of"); + private final ColumnInfo ALLOW_USAGES_ONLY_IN = new RightColumn("only in"); + + public DependencyConfigurable(Project project) { + myProject = project; + } + + public String getDisplayName() { + return "Dependency Validation"; + } + + public Icon getIcon() { + return null; + } + + public String getHelpTopic() { + return "editing.analyzeDependencies.validation"; + } + + public JComponent createComponent() { + myDenyRulesModel = new MyTableModel(new ColumnInfo[]{DENY_USAGES_OF, DENY_USAGES_IN}, true); + myDenyRulesModel.setSortable(false); + + myAllowRulesModel = new MyTableModel(new ColumnInfo[]{ALLOW_USAGES_OF, ALLOW_USAGES_ONLY_IN}, false); + myAllowRulesModel.setSortable(false); + + JPanel wholePanel = new JPanel(new GridLayout(2, 1, 10, 10)); + myDenyTable = new TableView(myDenyRulesModel); + wholePanel.add(createRulesPanel(myDenyRulesModel, myDenyTable)); + myAllowTable = new TableView(myAllowRulesModel); + wholePanel.add(createRulesPanel(myAllowRulesModel, myAllowTable)); + return wholePanel; + } + + private JPanel createRulesPanel(MyTableModel model, TableView table) { + JPanel panel = new JPanel(new BorderLayout()); + table.setSurrendersFocusOnKeystroke(true); + + JPanel buttonsPanel = new EditableRowTableManager(table, model, true).getButtonsPanel(); + panel.add(buttonsPanel, BorderLayout.EAST); + + table.setShowGrid(true); + table.setRowHeight(new PackageSetChooserCombo(myProject, null).getPreferredSize().height); + + panel.add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER); + table.setPreferredScrollableViewportSize(new Dimension(300, 150)); + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myDenyTable; + } + + public void apply() throws ConfigurationException { + stopTableEditing(); + DependencyValidationManager validationManager = DependencyValidationManager.getInstance(myProject); + validationManager.removeAllRules(); + List modelItems = new ArrayList(); + modelItems.addAll(myDenyRulesModel.getItems()); + modelItems.addAll(myAllowRulesModel.getItems()); + for (int i = 0; i < modelItems.size(); i++) { + DependencyRule rule = modelItems.get(i); + if (isRuleValid(rule)) { + validationManager.addRule(rule); + } + } + + DaemonCodeAnalyzer.getInstance(myProject).settingsChanged(); + } + + private void stopTableEditing() { + myDenyTable.stopEditing(); + myAllowTable.stopEditing(); + } + + private boolean isRuleValid(DependencyRule rule) { + return scopeExists(rule.getFromScope()) && scopeExists(rule.getToScope()); + } + + private boolean scopeExists(NamedScope scope) { + return scope != null && DependencyValidationManager.getInstance(myProject).getScope(scope.getName()) != null; + } + + public void reset() { + DependencyRule[] rules = DependencyValidationManager.getInstance(myProject).getAllRules(); + final ArrayList denyList = new ArrayList(); + final ArrayList allowList = new ArrayList(); + for (int i = 0; i < rules.length; i++) { + DependencyRule rule = rules[i]; + if (rule.isDenyRule()) { + denyList.add(rule.createCopy()); + } + else { + allowList.add(rule.createCopy()); + } + } + myDenyRulesModel.setItems(denyList); + myAllowRulesModel.setItems(allowList); + } + + public boolean isModified() { + final List rules = new ArrayList(); + rules.addAll(myDenyRulesModel.getItems()); + rules.addAll(myAllowRulesModel.getItems()); + return !Arrays.asList(DependencyValidationManager.getInstance(myProject).getAllRules()).equals(rules); + } + + public void disposeUIResources() { + } + + private static final DefaultTableCellRenderer + CELL_RENDERER = new DefaultTableCellRenderer() { + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setText(value == null ? "" : ((NamedScope)value).getName()); + return this; + } + }; + + public abstract class MyColumnInfo extends ColumnInfo { + protected MyColumnInfo(String name) { + super(name); + } + + public boolean isCellEditable(DependencyRule rule) { + return true; + } + + public TableCellRenderer getRenderer(DependencyRule rule) { + return CELL_RENDERER; + } + + public TableCellEditor getEditor(DependencyRule packageSetDependencyRule) { + return new AbstractTableCellEditor() { + private PackageSetChooserCombo myCombo; + + public Object getCellEditorValue() { + return myCombo.getSelectedScope(); + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + myCombo = new PackageSetChooserCombo(myProject, value == null ? null : ((NamedScope)value).getName()); + return new CellEditorComponentWithBrowseButton(myCombo, this); + } + }; + } + + public abstract void setValue(DependencyRule rule, NamedScope packageSet); + } + + + private class RightColumn extends MyColumnInfo { + public RightColumn(final String name) { + super(name); + } + + public NamedScope valueOf(DependencyRule rule) { + return rule.getFromScope(); + } + + public void setValue(DependencyRule rule, NamedScope set) { + rule.setFromScope(set); + } + } + + private class LeftColumn extends MyColumnInfo { + public LeftColumn(final String name) { + super(name); + } + + public NamedScope valueOf(DependencyRule rule) { + return rule.getToScope(); + } + + public void setValue(DependencyRule rule, NamedScope set) { + rule.setToScope(set); + } + } + + private class MyTableModel extends ListTableModel implements RowEditableTableModel { + private boolean myDenyRule; + + public MyTableModel(final ColumnInfo[] columnInfos, final boolean isDenyRule) { + super(columnInfos); + myDenyRule = isDenyRule; + } + + public void addRow() { + ArrayList newList = new ArrayList(getItems()); + newList.add(new DependencyRule(null, null, myDenyRule)); + setItems(newList); + } + + public void exchangeRows(int index1, int index2) { + ArrayList newList = new ArrayList(getItems()); + DependencyRule r1 = newList.get(index1); + DependencyRule r2 = newList.get(index2); + newList.set(index1, r2); + newList.set(index2, r1); + setItems(newList); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/FileNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/FileNode.java new file mode 100644 index 00000000000..eecc31adb28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/FileNode.java @@ -0,0 +1,89 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; + +import javax.swing.*; +import java.util.Set; + +public class FileNode extends PackageDependenciesNode { + private PsiFile myFile; + private boolean myMarked; + + public FileNode(PsiFile file, boolean marked) { + myFile = file; + myMarked = marked; + } + + public void fillFiles(Set set, boolean recursively) { + super.fillFiles(set, recursively); + set.add(myFile); + } + + public boolean hasUnmarked() { + return !myMarked; + } + + public boolean hasMarked() { + return myMarked; + } + + public String toString() { + return myFile.getVirtualFile().getName(); + } + + public Icon getOpenIcon() { + return getIcon(); + } + + public Icon getClosedIcon() { + return getIcon(); + } + + private Icon getIcon() { + VirtualFile vFile = myFile.getVirtualFile(); + return vFile.getIcon(); + } + + public int getWeight() { + return 4; + } + + public PsiElement getPsiElement() { + return myFile; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FileNode)) return false; + + final FileNode fileNode = (FileNode)o; + + if (!myFile.equals(fileNode.myFile)) return false; + + return true; + } + + public int hashCode() { + return myFile.hashCode(); + } + + public String getFQName() { + if (myFile instanceof PsiJavaFile) { + StringBuffer buf = new StringBuffer(20); + String packageName = ((PsiJavaFile)myFile).getPackageName(); + if (packageName != null) { + buf.append(packageName); + } + if (buf.length() > 0) { + buf.append('.'); + } + buf.append(myFile.getVirtualFile().getNameWithoutExtension()); + return buf.toString(); + } + + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/GeneralGroupNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/GeneralGroupNode.java new file mode 100644 index 00000000000..968dc229d85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/GeneralGroupNode.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.packageDependencies.ui; + +import com.intellij.psi.PsiFile; + +import javax.swing.*; +import java.util.Set; + +public class GeneralGroupNode extends PackageDependenciesNode { + private String myName; + private Icon myOpenIcon; + private Icon myClosedIcon; + + public GeneralGroupNode(String name, Icon openIcon, Icon closedIcon) { + myName = name; + myOpenIcon = openIcon; + myClosedIcon = closedIcon; + } + + public void fillFiles(Set set, boolean recursively) { + super.fillFiles(set, recursively); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + PackageDependenciesNode child = (PackageDependenciesNode)getChildAt(i); + child.fillFiles(set, true); + } + } + + public String toString() { + return myName; + } + + public int getWeight() { + return 2; + } + + public boolean equals(Object o) { + if (!(o instanceof GeneralGroupNode)) return false; + return myName.equals(((GeneralGroupNode)o).myName); + } + + public int hashCode() { + return myName.hashCode(); + } + + public Icon getOpenIcon() { + return myOpenIcon; + } + + public Icon getClosedIcon() { + return myClosedIcon; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/LibraryNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/LibraryNode.java new file mode 100644 index 00000000000..e4571cb85ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/LibraryNode.java @@ -0,0 +1,62 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.openapi.roots.JdkOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiFile; + +import javax.swing.*; +import java.util.Set; + +public class LibraryNode extends PackageDependenciesNode { + private static final Icon LIB_ICON_OPEN = IconLoader.getIcon("/nodes/ppLibOpen.png"); + private static final Icon LIB_ICON_CLOSED = IconLoader.getIcon("/nodes/ppLibClosed.png"); + private static final Icon JDK_ICON_OPEN = IconLoader.getIcon("/nodes/ppJdkOpen.png"); + private static final Icon JDK_ICON_CLOSED = IconLoader.getIcon("/nodes/ppJdkClosed.png"); + + private OrderEntry myLibraryOrJdk; + + public LibraryNode(OrderEntry libraryOrJdk) { + myLibraryOrJdk = libraryOrJdk; + } + + public void fillFiles(Set set, boolean recursively) { + super.fillFiles(set, recursively); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + PackageDependenciesNode child = (PackageDependenciesNode)getChildAt(i); + child.fillFiles(set, true); + } + } + + public String toString() { + return myLibraryOrJdk.getPresentableName(); + } + + public int getWeight() { + return 2; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LibraryNode)) return false; + + final LibraryNode libraryNode = (LibraryNode)o; + + if (!myLibraryOrJdk.equals(libraryNode.myLibraryOrJdk)) return false; + + return true; + } + + public int hashCode() { + return myLibraryOrJdk.hashCode(); + } + + public Icon getOpenIcon() { + return myLibraryOrJdk instanceof JdkOrderEntry ? JDK_ICON_OPEN : LIB_ICON_OPEN; + } + + public Icon getClosedIcon() { + return myLibraryOrJdk instanceof JdkOrderEntry ? JDK_ICON_CLOSED : LIB_ICON_CLOSED; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/ModuleNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/ModuleNode.java new file mode 100644 index 00000000000..81f0e68edd9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/ModuleNode.java @@ -0,0 +1,60 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiFile; + +import javax.swing.*; +import java.util.Set; + +public class ModuleNode extends PackageDependenciesNode { + private Module myModule; + + public ModuleNode(Module module) { + myModule = module; + } + + public void fillFiles(Set set, boolean recursively) { + super.fillFiles(set, recursively); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + PackageDependenciesNode child = (PackageDependenciesNode)getChildAt(i); + child.fillFiles(set, true); + } + } + + public Icon getOpenIcon() { + return myModule == null ? null : IconUtilEx.getIcon(myModule, Iconable.ICON_FLAG_OPEN); + } + + public Icon getClosedIcon() { + return myModule == null ? null : IconUtilEx.getIcon(myModule, 0); + } + + public String toString() { + return myModule == null ? "" : myModule.getName(); + } + + public String getModuleName() { + return myModule.getName(); + } + + public int getWeight() { + return 1; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ModuleNode)) return false; + + final ModuleNode moduleNode = (ModuleNode)o; + + return Comparing.equal(myModule, moduleNode.myModule); + } + + public int hashCode() { + return myModule == null ? 0 : myModule.hashCode(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageDependenciesNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageDependenciesNode.java new file mode 100644 index 00000000000..a979e9b62a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageDependenciesNode.java @@ -0,0 +1,70 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.MutableTreeNode; +import java.util.HashSet; +import java.util.Set; + +public class PackageDependenciesNode extends DefaultMutableTreeNode { + private static final EmptyIcon EMPTY_ICON = EmptyIcon.create(0, IconUtilEx.getEmptyIcon(false).getIconHeight()); + private Set myRegisteredFiles = new HashSet(); + private boolean myHasUnmarked = false; + private boolean myHasMarked = false; + + public void fillFiles(Set set, boolean recursively) { + set.addAll(myRegisteredFiles); + } + + public void addFile(PsiFile file, boolean isMarked) { + myRegisteredFiles.add(file); + updateMarked(!isMarked, isMarked); + } + + public Icon getOpenIcon() { + return EMPTY_ICON; + } + + public Icon getClosedIcon() { + return EMPTY_ICON; + } + + public int getWeight() { + return 0; + } + + public boolean hasUnmarked() { + return myHasUnmarked; + } + + public boolean hasMarked() { + return myHasMarked; + } + + public PsiElement getPsiElement() { + return null; + } + + public void add(MutableTreeNode newChild) { + super.add(newChild); + boolean hasUnmarked = ((PackageDependenciesNode)newChild).hasUnmarked(); + boolean hasMarked = ((PackageDependenciesNode)newChild).hasMarked(); + updateMarked(hasUnmarked, hasMarked); + } + + private void updateMarked(boolean hasUnmarked, boolean hasMarked) { + if (hasUnmarked && !myHasUnmarked || hasMarked && !myHasMarked) { + myHasUnmarked |= hasUnmarked; + myHasMarked |= hasMarked; + PackageDependenciesNode parent = ((PackageDependenciesNode)getParent()); + if (parent != null) { + parent.updateMarked(myHasUnmarked, myHasMarked); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageNode.java new file mode 100644 index 00000000000..8b9b5483845 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/PackageNode.java @@ -0,0 +1,84 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; + +import javax.swing.*; +import java.util.Set; + +public class PackageNode extends PackageDependenciesNode { + private static final Icon PACKAGE_OPEN_ICON = IconLoader.getIcon("/nodes/packageOpen.png"); + private static final Icon PACKAGE_CLOSED_ICON = IconLoader.getIcon("/nodes/packageClosed.png"); + + private String myPackageName; + private String myPackageQName; + private final PsiPackage myPackage; + + public PackageNode(PsiPackage aPackage, boolean showFQName) { + myPackage = aPackage; + myPackageName = showFQName ? aPackage.getQualifiedName() : aPackage.getName(); + if (myPackageName == null || myPackageName.length() == 0) { + myPackageName = ""; + } + myPackageQName = aPackage.getQualifiedName(); + if (myPackageQName != null && myPackageQName.length() == 0) { + myPackageQName = null; + } + } + + public void fillFiles(Set set, boolean recursively) { + super.fillFiles(set, recursively); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + PackageDependenciesNode child = (PackageDependenciesNode)getChildAt(i); + if (child instanceof FileNode || recursively) { + child.fillFiles(set, true); + } + } + } + + public String toString() { + return myPackageName; + } + + public String getPackageQName() { + return myPackageQName; + } + + public PsiElement getPsiElement() { + return myPackage; + } + + public int getWeight() { + return 3; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PackageNode)) return false; + + final PackageNode packageNode = (PackageNode)o; + + if (!myPackageName.equals(packageNode.myPackageName)) return false; + if (myPackageQName != null ? !myPackageQName.equals(packageNode.myPackageQName) : packageNode.myPackageQName != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = myPackageName.hashCode(); + result = 29 * result + (myPackageQName != null ? myPackageQName.hashCode() : 0); + return result; + } + + public Icon getOpenIcon() { + return PACKAGE_OPEN_ICON; + } + + public Icon getClosedIcon() { + return PACKAGE_CLOSED_ICON; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/RootNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/RootNode.java new file mode 100644 index 00000000000..daef1fe61fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/RootNode.java @@ -0,0 +1,15 @@ +package com.intellij.packageDependencies.ui; + +public class RootNode extends PackageDependenciesNode { + public boolean equals(Object obj) { + return obj instanceof RootNode; + } + + public int hashCode() { + return 0; + } + + public String toString() { + return "Root"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java new file mode 100644 index 00000000000..1ee95cf925b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java @@ -0,0 +1,77 @@ +package com.intellij.packageDependencies.ui; + +import javax.swing.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; +import java.util.*; + +public class TreeExpantionMonitor { + public static TreeExpantionMonitor install(JTree tree) { + return new TreeExpantionMonitor(tree); + } + + private Set myExpandedPaths = new HashSet(); + private List mySelectionPath = new ArrayList(); + private JTree myTree; + private boolean myFrozen = false; + + + private TreeExpantionMonitor(JTree tree) { + myTree = tree; + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + if (myFrozen) return; + mySelectionPath = new ArrayList(); + TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + mySelectionPath.add(paths[i]); + } + } + } + }); + + myTree.addTreeExpansionListener(new TreeExpansionListener() { + public void treeExpanded(TreeExpansionEvent event) { + if (myFrozen) return; + TreePath path = event.getPath(); + if (path != null) { + myExpandedPaths.add(path); + } + } + + public void treeCollapsed(TreeExpansionEvent event) { + if (myFrozen) return; + TreePath path = event.getPath(); + if (path != null) { + TreePath[] allPaths = myExpandedPaths.toArray(new TreePath[myExpandedPaths.size()]); + for (int i = 0; i < allPaths.length; i++) { + TreePath treePath = allPaths[i]; + if (treePath.equals(path) || path.isDescendant(treePath)) { + myExpandedPaths.remove(treePath); + } + } + } + } + }); + } + + public void freeze() { + myFrozen = true; + } + + public void restore() { + freeze(); + for (int i = 0; i < mySelectionPath.size(); i++) { + TreePath treePath = mySelectionPath.get(i); + myTree.getSelectionModel().addSelectionPath(treePath); + } + for (Iterator iterator = myExpandedPaths.iterator(); iterator.hasNext();) { + myTree.expandPath(iterator.next()); + } + myFrozen = false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeModelBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeModelBuilder.java new file mode 100644 index 00000000000..a28ee3421d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/TreeModelBuilder.java @@ -0,0 +1,415 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packageDependencies.DependencyUISettings; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import java.util.*; + +public class TreeModelBuilder { + private ProjectFileIndex myFileIndex; + private PsiManager myPsiManager; + private Project myProject; + + private static final class ScopeType { + private ScopeType() {} + + public static ScopeType TEST = new ScopeType(); + public static ScopeType SOURCE = new ScopeType(); + public static ScopeType LIB = new ScopeType(); + } + + private boolean myShowModules; + private boolean myGroupByScopeType; + private boolean myFlattenPackages; + private boolean myShowFiles; + private boolean myShowIndividualLibs; + private Marker myMarker; + private boolean myAddUnmarkedFiles; + private PackageDependenciesNode myRoot; + private Map, PackageNode>> myModulePackageNodes = new HashMap, PackageNode>>(); + private Map, PackageNode>> myLibraryPackageNodes = new HashMap, PackageNode>>(); + private Map> myModuleNodes = new HashMap>(); + private Map> myLibraryNodes = new HashMap>(); + private int myScannedFileCount = 0; + private int myTotalFileCount = 0; + private int myMarkedFileCount = 0; + private GeneralGroupNode myAllLibsNode = null; + + private GeneralGroupNode mySourceRoot = null; + private GeneralGroupNode myTestRoot = null; + private GeneralGroupNode myLibsRoot = null; + + + private static final Icon LIB_ICON_OPEN = IconLoader.getIcon("/nodes/ppLibOpen.png"); + private static final Icon LIB_ICON_CLOSED = IconLoader.getIcon("/nodes/ppLibClosed.png"); + private static final Icon PACKAGE_CLOSED = IconLoader.getIcon("/nodes/packageClosed.png"); + private static final Icon PACKAGE_OPEN = IconLoader.getIcon("/nodes/packageOpen.png"); + private static final Icon TEST_ICON = IconLoader.getIcon("/nodes/testSourceFolder.png"); + public static final String PRODUCTION_NAME = "Production Classes"; + public static final String TEST_NAME = "Test Classes"; + public static final String LIBRARY_NAME = "Library Classes"; + + private TreeModelBuilder(Project project, boolean showIndividualLibs, Marker marker) { + myProject = project; + DependencyUISettings settings = DependencyUISettings.getInstance(); + myShowModules = settings.UI_SHOW_MODULES; + myGroupByScopeType = settings.UI_GROUP_BY_SCOPE_TYPE; + myFlattenPackages = settings.UI_FLATTEN_PACKAGES; + myShowFiles = settings.UI_SHOW_FILES; + myShowIndividualLibs = showIndividualLibs; + myMarker = marker; + myAddUnmarkedFiles = !settings.UI_FILTER_LEGALS; + myRoot = new RootNode(); + myFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + myPsiManager = PsiManager.getInstance(project); + + createMaps(ScopeType.LIB); + createMaps(ScopeType.SOURCE); + createMaps(ScopeType.TEST); + + if (myGroupByScopeType) { + mySourceRoot = new GeneralGroupNode(PRODUCTION_NAME, PACKAGE_OPEN, PACKAGE_CLOSED); + myTestRoot = new GeneralGroupNode(TEST_NAME, TEST_ICON, TEST_ICON); + myLibsRoot = new GeneralGroupNode(LIBRARY_NAME, LIB_ICON_OPEN, LIB_ICON_CLOSED); + myRoot.add(mySourceRoot); + myRoot.add(myTestRoot); + myRoot.add(myLibsRoot); + } + } + + private void createMaps(ScopeType scopeType) { + myModulePackageNodes.put(scopeType, new HashMap, PackageNode>()); + myLibraryPackageNodes.put(scopeType, new HashMap, PackageNode>()); + myModuleNodes.put(scopeType, new HashMap()); + myLibraryNodes.put(scopeType, new HashMap()); + } + + public static class TreeModel extends DefaultTreeModel { + private int myMarkedFileCount = 0; + private int myTotalFileCount = 0; + + public TreeModel(TreeNode root, int total, int marked) { + super(root); + myMarkedFileCount = marked; + myTotalFileCount = total; + } + + public int getMarkedFileCount() { + return myMarkedFileCount; + } + + public int getTotalFileCount() { + return myTotalFileCount; + } + } + + public interface Marker { + boolean isMarked(PsiFile file); + } + + public static TreeModel createTreeModel(Project project, boolean showProgress, Set files, Marker marker) { + return new TreeModelBuilder(project, true, marker).build(files, showProgress); + } + + public static TreeModel createTreeModel(Project project, boolean showProgress, + boolean showIndividualLibs, + Marker marker) { + return new TreeModelBuilder(project, showIndividualLibs, marker).build(project, showProgress); + } + + private VirtualFile[] getLibraryRoots(Project project) { + Set roots = new HashSet(); + final Module[] modules = ModuleManager.getInstance(project).getModules(); + for (int i = 0; i < modules.length; i++) { + Module module = modules[i]; + roots.addAll(Arrays.asList(ModuleRootManager.getInstance(module).getFiles(OrderRootType.SOURCES))); + } + return roots.toArray(new VirtualFile[roots.size()]); + } + + private void countFiles(Project project) { + myFileIndex.iterateContent(new ContentIterator() { + public boolean processFile(VirtualFile fileOrDir) { + if (!fileOrDir.isDirectory()) { + if (myFileIndex.isContentJavaSourceFile(fileOrDir)) { + myTotalFileCount++; + } + } + return true; + } + }); + + VirtualFile[] roots = getLibraryRoots(project); + for (int i = 0; i < roots.length; i++) { + countFilesRecursively(roots[i]); + } + } + + private TreeModel build(final Project project, boolean showProgress) { + countFiles(project); + + Runnable buildingRunnable = new Runnable() { + public void run() { + final PsiManager psiManager = PsiManager.getInstance(project); + myFileIndex.iterateContent(new ContentIterator() { + public boolean processFile(VirtualFile fileOrDir) { + if (!fileOrDir.isDirectory()) { + if (myFileIndex.isContentJavaSourceFile(fileOrDir)) { + buildFileNode(psiManager.findFile(fileOrDir)); + } + } + return true; + } + }); + + VirtualFile[] roots = getLibraryRoots(project); + for (int i = 0; i < roots.length; i++) { + processFilesRecursively(roots[i], psiManager); + } + } + }; + + if (showProgress) { + ApplicationManager.getApplication().runProcessWithProgressSynchronously(buildingRunnable, "Scanning Packages", false, project); + } + else { + buildingRunnable.run(); + } + + TreeUtil.sort(myRoot, new DependecyNodeComparator()); + return new TreeModel(myRoot, myTotalFileCount, myMarkedFileCount); + } + + private void processFilesRecursively(VirtualFile file, PsiManager psiManager) { + if (file.isDirectory()) { + VirtualFile[] children = file.getChildren(); + for (int i = 0; i < children.length; i++) { + processFilesRecursively(children[i], psiManager); + } + } + else if (myFileIndex.isInLibrarySource(file) && myFileIndex.isJavaSourceFile(file)) { + buildFileNode(psiManager.findFile(file)); + } + } + + private void countFilesRecursively(VirtualFile file) { + if (file.isDirectory()) { + VirtualFile[] children = file.getChildren(); + for (int i = 0; i < children.length; i++) { + countFilesRecursively(children[i]); + } + } + else if (myFileIndex.isInLibrarySource(file) && myFileIndex.isJavaSourceFile(file)) { + myTotalFileCount++; + } + } + + private TreeModel build(final Set files, boolean showProgress) { + if (files.size() == 1) { + myShowFiles = true; + } + + Runnable buildingRunnable = new Runnable() { + public void run() { + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + buildFileNode(iterator.next()); + } + } + }; + + if (showProgress) { + ApplicationManager.getApplication().runProcessWithProgressSynchronously(buildingRunnable, "Scanning Packages", false, myProject); + } + else { + buildingRunnable.run(); + } + + TreeUtil.sort(myRoot, new DependecyNodeComparator()); + return new TreeModel(myRoot, myTotalFileCount, myMarkedFileCount); + } + + private void buildFileNode(PsiFile file) { + if (!(file instanceof PsiJavaFile)) return; + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.setText("Scanning packages"); + indicator.setText2(file.getVirtualFile().getPresentableUrl()); + indicator.setFraction(((double)myScannedFileCount++) / myTotalFileCount); + } + + boolean isMarked = myMarker == null ? false : myMarker.isMarked(file); + if (isMarked) myMarkedFileCount++; + if (isMarked || myAddUnmarkedFiles) { + PackageDependenciesNode dirNode = getFileParentNode((PsiJavaFile)file); + + if (myShowFiles) { + FileNode fileNode = new FileNode(file, isMarked); + dirNode.add(fileNode); + } + else { + dirNode.addFile(file, isMarked); + } + } + } + + private PackageDependenciesNode getFileParentNode(PsiJavaFile file) { + VirtualFile vFile = file.getVirtualFile(); + PsiPackage aPackage = getFilePackage(file); + if (myFileIndex.isInLibrarySource(vFile) || myFileIndex.isInLibraryClasses(vFile)) { + return getLibraryDirNode(aPackage, getLibraryForFile(file)); + } + else { + return getModuleDirNode(aPackage, myFileIndex.getModuleForFile(vFile), getFileScopeType(vFile)); + } + } + + private PsiPackage getFilePackage(PsiJavaFile file) { + VirtualFile vFile = file.getVirtualFile(); + if (myFileIndex.isInLibrarySource(vFile)) { + return myPsiManager.findPackage(myFileIndex.getPackageNameByDirectory(vFile.getParent())); + } + return myPsiManager.findPackage(file.getPackageName()); + } + + private ScopeType getFileScopeType(VirtualFile file) { + if (myFileIndex.isLibraryClassFile(file) || myFileIndex.isInLibrarySource(file)) return ScopeType.LIB; + if (myFileIndex.isInTestSourceContent(file)) return ScopeType.TEST; + return ScopeType.SOURCE; + } + + private OrderEntry getLibraryForFile(PsiFile file) { + OrderEntry[] orders = myFileIndex.getOrderEntriesForFile(file.getVirtualFile()); + for (int i = 0; i < orders.length; i++) { + OrderEntry order = orders[i]; + if (order instanceof LibraryOrderEntry || order instanceof JdkOrderEntry) return order; + } + return null; + } + + private T getMap(Map map, ScopeType scopeType) { + return map.get(myGroupByScopeType ? scopeType : ScopeType.SOURCE); + } + + private PackageDependenciesNode getLibraryDirNode(PsiPackage aPackage, OrderEntry libraryOrJdk) { + if (aPackage == null) { + return getLibraryOrJDKNode(libraryOrJdk); + } + + if (!myShowModules && !myGroupByScopeType) { + return getModuleDirNode(aPackage, null, ScopeType.LIB); + } + + Pair descriptor = new Pair(myShowModules ? libraryOrJdk : null, aPackage); + PackageNode node = getMap(myLibraryPackageNodes, ScopeType.LIB).get(descriptor); + if (node != null) return node; + + node = new PackageNode(aPackage, myFlattenPackages); + getMap(myLibraryPackageNodes, ScopeType.LIB).put(descriptor, node); + + if (myFlattenPackages) { + getLibraryOrJDKNode(libraryOrJdk).add(node); + } + else { + getLibraryDirNode(aPackage.getParentPackage(), libraryOrJdk).add(node); + } + + return node; + } + + private PackageDependenciesNode getModuleDirNode(PsiPackage aPackage, Module module, ScopeType scopeType) { + if (aPackage == null) { + return getModuleNode(module, scopeType); + } + + Pair descriptor = new Pair(myShowModules ? module : null, aPackage); + PackageNode node = getMap(myModulePackageNodes, scopeType).get(descriptor); + + if (node != null) return node; + + node = new PackageNode(aPackage, myFlattenPackages); + getMap(myModulePackageNodes, scopeType).put(descriptor, node); + + if (myFlattenPackages) { + getModuleNode(module, scopeType).add(node); + } + else { + getModuleDirNode(aPackage.getParentPackage(), module, scopeType).add(node); + } + + return node; + } + + private PackageDependenciesNode getModuleNode(Module module, ScopeType scopeType) { + if (module == null || !myShowModules) { + return getScopeNode(scopeType); + } + + ModuleNode node = getMap(myModuleNodes, scopeType).get(module); + if (node != null) return node; + node = new ModuleNode(module); + getMap(myModuleNodes, scopeType).put(module, node); + getScopeNode(scopeType).add(node); + + return node; + } + + private PackageDependenciesNode getLibraryOrJDKNode(OrderEntry libraryOrJdk) { + if (libraryOrJdk == null || !myShowModules) { + return getScopeNode(ScopeType.LIB); + } + + if (!myShowIndividualLibs) { + if (myGroupByScopeType) return getScopeNode(ScopeType.LIB); + if (myAllLibsNode == null) { + myAllLibsNode = new GeneralGroupNode("Libraries", LIB_ICON_OPEN, LIB_ICON_CLOSED); + getScopeNode(ScopeType.LIB).add(myAllLibsNode); + } + return myAllLibsNode; + } + + LibraryNode node = getMap(myLibraryNodes, ScopeType.LIB).get(libraryOrJdk); + if (node != null) return node; + node = new LibraryNode(libraryOrJdk); + getMap(myLibraryNodes, ScopeType.LIB).put(libraryOrJdk, node); + + getScopeNode(ScopeType.LIB).add(node); + return node; + } + + + private PackageDependenciesNode getScopeNode(ScopeType scopeType) { + if (!myGroupByScopeType) { + return myRoot; + } + else { + if (scopeType == ScopeType.TEST) { + return myTestRoot; + } + else if (scopeType == ScopeType.SOURCE) { + return mySourceRoot; + } + else if (scopeType == ScopeType.LIB) { + return myLibsRoot; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/UsagesPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/UsagesPanel.java new file mode 100644 index 00000000000..9731634eef7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/packageDependencies/ui/UsagesPanel.java @@ -0,0 +1,184 @@ +package com.intellij.packageDependencies.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ColorProgressBar; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.project.Project; +import com.intellij.packageDependencies.DependenciesBuilder; +import com.intellij.packageDependencies.FindDependencyUtil; +import com.intellij.psi.PsiFile; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.*; +import com.intellij.util.Alarm; + +import javax.swing.*; +import java.awt.*; +import java.util.Set; + +public class UsagesPanel extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.packageDependencies.ui.UsagesPanel"); + + private Project myProject; + + private ProgressIndicator myCurrentProgress; + private JComponent myCurrentComponent; + private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + public UsagesPanel(Project project) { + super(new BorderLayout()); + myProject = project; + setToInitialPosition(); + } + + public void setToInitialPosition() { + cancelCurrentFindRequest(); + setToComponent(createLabel("Select where to search in left tree and what to search in right tree.")); + } + + public void findUsages(final DependenciesBuilder builder, final Set searchIn, final Set searchFor) { + cancelCurrentFindRequest(); + + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + public void run() { + new Thread(new Runnable() { + public void run() { + final ProgressIndicator progress = new MyProgressIndicator(); + myCurrentProgress = progress; + ProgressManager.getInstance().runProcess(new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + UsageInfo[] usages = new UsageInfo[0]; + try { + usages = FindDependencyUtil.findDependencies(builder, searchIn, searchFor); + } + catch (ProcessCanceledException e) { + } + catch (Exception e) { + LOG.error(e); + } + + if (!progress.isCanceled()) { + final UsageInfo[] finalUsages = usages; + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + showUsages(finalUsages); + } + }, ModalityState.stateForComponent(UsagesPanel.this)); + } + } + }); + myCurrentProgress = null; + } + }, progress); + } + }).start(); + } + }, 300); + } + + private void cancelCurrentFindRequest() { + if (myCurrentProgress != null) { + myCurrentProgress.cancel(); + } + } + + private void showUsages(final UsageInfo[] usageInfos) { + try { + Usage[] usages = UsageInfo2UsageAdapter.convert(usageInfos); + UsageViewPresentation presentation = new UsageViewPresentation(); + presentation.setCodeUsagesString("Usages of the right tree scope selection in the left tree scope selection"); + UsageView usageView = myProject.getComponent(UsageViewManager.class).createUsageView(new UsageTarget[0], + usages, presentation); + setToComponent(usageView.getComponent()); + } + catch (ProcessCanceledException e) { + setToCanceled(); + } + } + + private void setToCanceled() { + setToComponent(createLabel("Canceled")); + } + + private void setToComponent(final JComponent cmp) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (myCurrentComponent != null) { + remove(myCurrentComponent); + } + myCurrentComponent = cmp; + add(cmp, BorderLayout.CENTER); + revalidate(); + } + }); + } + + private JComponent createLabel(String text) { + JLabel label = new JLabel(text); + label.setHorizontalAlignment(SwingConstants.CENTER); + return label; + } + + private class MyProgressIndicator extends ProgressIndicatorBase { + private MyProgressPanel myProgressPanel; + private boolean myPaintInQueue; + + public MyProgressIndicator() { + myProgressPanel = new MyProgressPanel(); + } + + public void start() { + super.start(); + setToComponent(myProgressPanel.myPanel); + } + + public void stop() { + super.stop(); + if (isCanceled()) { + setToCanceled(); + } + } + + public void setText(String text) { + if (!text.equals(getText())) { + super.setText(text); + update(); + } + } + + public void setFraction(double fraction) { + if (fraction != getFraction()) { + super.setFraction(fraction); + update(); + } + } + + private void update() { + if (myPaintInQueue) return; + myPaintInQueue = true; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + myPaintInQueue = false; + myProgressPanel.myTextLabel.setText(getText()); + double fraction = getFraction(); + myProgressPanel.myFractionLabel.setText((int)(fraction * 99 + 0.5) + "%"); + myProgressPanel.myFractionProgress.setFraction(fraction); + } + }); + } + } + + private static class MyProgressPanel { + public JLabel myFractionLabel; + public ColorProgressBar myFractionProgress; + public JLabel myTextLabel; + public JPanel myPanel; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/peer/impl/PeerFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/peer/impl/PeerFactoryImpl.java new file mode 100644 index 00000000000..59d91a32b11 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/peer/impl/PeerFactoryImpl.java @@ -0,0 +1,196 @@ +package com.intellij.peer.impl; + +import com.intellij.execution.runners.ProcessProxyFactory; +import com.intellij.execution.runners.ProcessProxyFactoryImpl; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diff.DiffRequestFactory; +import com.intellij.openapi.diff.impl.mergeTool.DiffRequestFactoryImpl; +import com.intellij.openapi.fileChooser.FileSystemTreeFactory; +import com.intellij.openapi.fileChooser.ex.FileSystemTreeFactoryImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapperPeerFactory; +import com.intellij.openapi.ui.impl.DialogWrapperPeerFactoryImpl; +import com.intellij.openapi.vcs.FileStatusFactory; +import com.intellij.openapi.vcs.actions.VcsContextFactory; +import com.intellij.openapi.vcs.actions.VcsContext; +import com.intellij.openapi.vcs.actions.VcsContextWrapper; +import com.intellij.openapi.vcs.impl.FileStatusFactoryImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.packageDependencies.packageSet.PackageSetFactoryImpl; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.*; +import com.intellij.psi.search.scope.packageSet.PackageSetFactory; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.ui.*; +import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.content.ContentFactoryImpl; +import com.intellij.ui.errorView.ErrorViewFactory; +import com.intellij.ui.errorView.impl.ErrorViewFactoryImpl; +import com.intellij.ui.plaf.beg.BegTreeHandleUtil; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.EditSourceOnEnterKeyHandler; +import com.intellij.util.ui.Table; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.treetable.TreeTable; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.TreeCellRenderer; +import java.awt.*; + +public class PeerFactoryImpl extends PeerFactory implements ApplicationComponent { + private ProcessProxyFactory myProxyFactory = null; + private PackageSetFactory myPackageSetFactory; + private final UIHelper myUIHelper = new MyUIHelper(); + private final ErrorViewFactory myErrorViewFactory = new ErrorViewFactoryImpl(); + private final ContentFactoryImpl myContentFactory = new ContentFactoryImpl(); + private final FileSystemTreeFactoryImpl myFileSystemTreeFactory = new FileSystemTreeFactoryImpl(); + private final DiffRequestFactoryImpl myDiffRequestFactory = new DiffRequestFactoryImpl(); + private final FileStatusFactoryImpl myFileStatusFactory; + + public PeerFactoryImpl() { + myFileStatusFactory = new FileStatusFactoryImpl(); + } + + public String getComponentName() { + return "PeerFactory"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public FileStatusFactory getFileStatusFactory() { + return myFileStatusFactory; + } + + public DialogWrapperPeerFactory getDialogWrapperPeerFactory() { + return new DialogWrapperPeerFactoryImpl(); + } + + public ProcessProxyFactory getProcessProxyFactory() { + if (myProxyFactory == null) { + myProxyFactory = new ProcessProxyFactoryImpl(); + } + return myProxyFactory; + } + + public PackageSetFactory getPackageSetFactory() { + if (myPackageSetFactory == null) { + myPackageSetFactory = new PackageSetFactoryImpl(); + } + return myPackageSetFactory; + } + + public UIHelper getUIHelper() { + return myUIHelper; + } + + public ErrorViewFactory getErrorViewFactory() { + return myErrorViewFactory; + } + + public ContentFactory getContentFactory() { + return myContentFactory; + } + + public FileSystemTreeFactory getFileSystemTreeFactory() { + return myFileSystemTreeFactory; + } + + public DiffRequestFactory getDiffRequestFactory() { + return myDiffRequestFactory; + } + + private static class MyUIHelper implements UIHelper { + public void installToolTipHandler(JTree tree) { + TreeToolTipHandler.install(tree); + } + + public void installToolTipHandler(JTable table) { + TableToolTipHandler.install(table); + } + + public void installEditSourceOnDoubleClick(JTree tree) { + EditSourceOnDoubleClickHandler.install(tree); + } + + public void installEditSourceOnDoubleClick(TreeTable tree) { + EditSourceOnDoubleClickHandler.install(tree); + } + + public void installEditSourceOnDoubleClick(Table table) { + EditSourceOnDoubleClickHandler.install(table); + } + + public void installTreeSpeedSearch(Tree tree) { + new TreeSpeedSearch(tree); + } + + public void installEditSourceOnEnterKeyHandler(JTree tree) { + EditSourceOnEnterKeyHandler.install(tree); + } + + public TableCellRenderer createPsiElementRenderer(final PsiElement psiElement, final Project project) { + return new ColoredTableCellRenderer() { + protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { + append(getPsiElementText(psiElement), SimpleTextAttributes.REGULAR_ATTRIBUTES); + setIcon(psiElement.getIcon(0)); + } + }; + + } + + public TreeCellRenderer createHighlightableTreeCellRenderer() { + return new HighlightableCellRenderer(); + } + + public void drawDottedRectangle(Graphics g, int x, int y, int i, int i1) { + BegTreeHandleUtil.drawDottedRectangle(g,x,y,i,i1); + } + + public void showListPopup(String title, JList list, Runnable finishAction, Project project, int x, int y) { + new ListPopup(title, list, finishAction, project).show(x, y); + + } + + public void installSmartExpander(JTree tree) { + SmartExpander.installOn(tree); + } + + public void installSelectionSaver(JTree tree) { + SelectionSaver.installOn(tree); + } + + private static String getPsiElementText(PsiElement psiElement) { + if (psiElement instanceof PsiClass) { + return PsiFormatUtil.formatClass((PsiClass)psiElement, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_FQ_NAME); + } + else if (psiElement instanceof PsiMethod) { + return PsiFormatUtil.formatMethod((PsiMethod)psiElement, + PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_CONTAINING_CLASS, + 0); + } + else if (psiElement instanceof PsiField) { + return PsiFormatUtil.formatVariable((PsiField)psiElement, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_CONTAINING_CLASS, + PsiSubstitutor.EMPTY); + } + else { + return psiElement.toString(); + } + + } + + } + + public VcsContextFactory getVcsContextFactory() { + return new VcsContextFactory() { + public VcsContext createOn(AnActionEvent event) { + return VcsContextWrapper.on(event); + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/core/impl/PomModelImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/core/impl/PomModelImpl.java new file mode 100644 index 00000000000..7360699570d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/core/impl/PomModelImpl.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.pom.core.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.pom.*; +import com.intellij.pom.event.PomModelEvent; +import com.intellij.pom.event.PomModelListener; +import com.intellij.util.IncorrectOperationException; +import com.intellij.psi.PsiLock; + +import java.util.*; + +public class PomModelImpl extends UserDataHolderBase implements PomModel { + private final PomProject myPomProject; + private Map, PomModelAspect> myAspects = new HashMap, PomModelAspect>(); + private Map> myAspectDependencies = new HashMap>(); + private Map> myIncidence = new HashMap>(); + private Map> myInvertedIncidence = new HashMap>(); + private List myListeners = new ArrayList(); + + public PomModelImpl(Project project) { + myPomProject = new PomProjectImpl(this, project); + } + + public PomProject getRoot() { + return myPomProject; + } + + public T getModelAspect(Class aClass) { + return (T)myAspects.get(aClass); + } + + public void registerAspect(PomModelAspect aspect, Set dependencies) { + myAspectDependencies.put(aspect, dependencies); + myAspects.put(aspect.getClass(), aspect); + final Iterator iterator = dependencies.iterator(); + final List deps = new ArrayList(); + // todo: reorder dependencies + while (iterator.hasNext()) { + final PomModelAspect depend = iterator.next(); + deps.add(depend); + deps.addAll(getAllDependencies(depend)); + } + + final Iterator depsIterator = deps.iterator(); + while (depsIterator.hasNext()) { + final PomModelAspect pomModelAspect = depsIterator.next(); + final List pomModelAspects = myInvertedIncidence.get(pomModelAspect); + if(pomModelAspects != null) pomModelAspects.add(aspect); + else myInvertedIncidence.put(pomModelAspect, new ArrayList(Collections.singletonList(aspect))); + } + myIncidence.put(aspect, deps); + } + + //private final Pair myHolderPair = new Pair(null, null); + public List getAllDependencies(PomModelAspect aspect){ + List pomModelAspects = myIncidence.get(aspect); + return pomModelAspects != null ? pomModelAspects : Collections.EMPTY_LIST; + } + + public List getAllDependants(PomModelAspect aspect){ + List pomModelAspects = myInvertedIncidence.get(aspect); + return pomModelAspects != null ? pomModelAspects : Collections.EMPTY_LIST; + } + + public void addModelListener(PomModelListener listener) { + synchronized(myListeners){ + myListeners.add(listener); + } + } + + public void removeModelListener(PomModelListener listener) { + synchronized(myListeners){ + myListeners.remove(listener); + } + } + + private final Stack myBlockedAspects = new Stack(); + + public synchronized void runTransaction(PomTransaction transaction, PomModelAspect aspect) throws IncorrectOperationException{ + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if(progressIndicator != null) progressIndicator.startNonCancelableSection(); + try{ + synchronized(PsiLock.LOCK){ + myBlockedAspects.push(aspect); + final PomModelEvent event; + try{ + event = transaction.run(); + if(event == null) return; + } + catch(IncorrectOperationException ioe){ + return; + } + finally{ + myBlockedAspects.pop(); + } + + final List dependants = getAllDependants(aspect); + { // update + final Iterator depsIter = dependants.iterator(); + while (depsIter.hasNext()) { + final PomModelAspect modelAspect = depsIter.next(); + if(myBlockedAspects.contains(modelAspect)) continue; + modelAspect.update(event); + } + } + { + final Iterator listenersIterator = myListeners.iterator(); + while (listenersIterator.hasNext()) listenersIterator.next().modelChanged(event); + } + } + } + finally{ + if(progressIndicator != null) progressIndicator.finishNonCancelableSection(); + } + } + // Project component + + public void projectOpened() {} + public void projectClosed() {} + public String getComponentName() { + return "PomModel"; + } + public void initComponent() {} + public void disposeComponent() {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/java/impl/PomJavaAspectImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/java/impl/PomJavaAspectImpl.java new file mode 100644 index 00000000000..321d3e83cb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/pom/java/impl/PomJavaAspectImpl.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.pom.java.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.pom.PomElement; +import com.intellij.pom.PomModel; +import com.intellij.pom.PomScope; +import com.intellij.pom.PomTransaction; +import com.intellij.pom.event.PomModelEvent; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.PomJavaAspect; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.pom.java.PomPackage; +import com.intellij.pom.java.events.PomJavaAspectChangeSet; +import com.intellij.pom.java.events.JavaTreeChanged; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class PomJavaAspectImpl extends PomJavaAspect implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.pom.java.impl.PomJavaAspectImpl"); + private final Project myProject; + private final PsiManager myPsiManager; + private PomPackage myRootPackage; + private Map myPackageMap = new HashMap(); + + public PomJavaAspectImpl(Project project, PsiManager psiManager) { + myProject = project; + myPsiManager = psiManager; + myRootPackage = new PomPackageImpl("", null, this); + + myPsiManager.addPsiTreeChangeListener(new PsiTreeChangeAdapter() { + public void childAdded(PsiTreeChangeEvent event) { + firePomEvent(event.getChild()); + } + + public void childRemoved(PsiTreeChangeEvent event) { + firePomEvent(event.getParent()); + } + + public void childReplaced(PsiTreeChangeEvent event) { + firePomEvent(event.getParent()); + } + + public void childrenChanged(PsiTreeChangeEvent event) { + firePomEvent(event.getParent()); + } + + public void childMoved(PsiTreeChangeEvent event) { + final PsiFile file1 = event.getOldParent().getContainingFile(); + final PsiFile file2 = event.getNewParent().getContainingFile(); + firePomEvent(file1); + if (!file1.equals(file2)) { + firePomEvent(file2); + } + } + + public void propertyChanged(PsiTreeChangeEvent event) { + firePomEvent(event.getElement()); + } + }); + } + + public PomPackage getRootPackage() { + return myRootPackage; + } + + public PsiManager getPsiManager() { + return myPsiManager; + } + + public PomMemberOwner findClass(String fqn, PomScope scope) { + //TODO scope conversion + return myPsiManager.findClass(fqn, null).getPom(); + } + + public PomMemberOwner[] findClasses(String fqn, PomScope scope) { + //TODO scope conversion + PsiClass[] psis = myPsiManager.findClasses(fqn, null); + PomMemberOwner[] poms = new PomMemberOwner[psis.length]; + for (int i = 0; i < poms.length; i++) { + poms[i] = psis[i].getPom(); + } + return poms; + } + + public PomPackage findPackage(String fqn) { + if (fqn == null || fqn.length() == 0) return myRootPackage; + PomPackageImpl pomPackage = myPackageMap.get(fqn); + if (pomPackage == null) { + final String name; + final String prefix; + int idx = fqn.lastIndexOf('.'); + if (idx < 0) { + name = fqn; + prefix = null; + } + else { + prefix = fqn.substring(0, idx); + name = fqn.substring(idx + 1); + } + + pomPackage = new PomPackageImpl(name, (PomPackageImpl)findPackage(prefix), this); + myPackageMap.put(fqn, pomPackage); + } + return pomPackage; + } + + public LanguageLevel getLanguageLevel() { + return myPsiManager.getEffectiveLanguageLevel(); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "PomJavaModel"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public PomPackage[] getSubPackages(PomPackageImpl pomPackage) { + List subs = new ArrayList(); + for (Iterator iterator = myPackageMap.values().iterator(); iterator.hasNext();) { + PomPackageImpl aPackage = iterator.next(); + if (aPackage.getParentPackage() == pomPackage) subs.add(aPackage); + } + return subs.toArray(new PomPackage[subs.size()]); + } + + public void update(PomModelEvent event) { + //TODO + } + + public PomModelEvent getEvent() { + return null; + } + + public PomElement getMorph(PomElement element) { + //TODO + return null; + } + + private void firePomEvent(final PsiElement element) { + if (element != null) { + firePomEvent(element.getContainingFile()); + } + } + + private void firePomEvent(final PsiFile file) { + if (isJavaFile(file)) { + final PomModel model = myProject.getModel(); + try { + myProject.getModel().runTransaction(new PomTransaction() { + public PomModelEvent run() { + final PomModelEvent event = new PomModelEvent(model); + final PomJavaAspectChangeSet set = new PomJavaAspectChangeSet(model, file); + set.addChange(new JavaTreeChanged(file)); + event.registerChangeSet(PomJavaAspectImpl.this, set); + return event; + } + }, this); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + private boolean isJavaFile(final PsiFile file) { + return file instanceof PsiJavaFile || file instanceof PsiCodeFragment; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/projectView/LibrariesElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/projectView/LibrariesElement.java new file mode 100644 index 00000000000..6f650abadf5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/projectView/LibrariesElement.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.projectView; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; + +public class LibrariesElement { + private final Module myModule; + private final Project myProject; + + public LibrariesElement(final Module module, final Project project) { + myModule = module; + myProject = project; + } + + public Module getModule() { + return myModule; + } + + public Project getProject() { + return myProject; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LibrariesElement)) return false; + + final LibrariesElement librariesElement = (LibrariesElement)o; + + if (myModule != null ? !myModule.equals(librariesElement.myModule) : librariesElement.myModule != null) return false; + if (!myProject.equals(librariesElement.myProject)) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myModule != null ? myModule.hashCode() : 0); + result = 29 * result + myProject.hashCode(); + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/PsiLock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/PsiLock.java new file mode 100644 index 00000000000..f3a0b416ccc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/PsiLock.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.psi; + + + +public class PsiLock { + public static final Object LOCK = new Object(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/AllVariablesControlFlowPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/AllVariablesControlFlowPolicy.java new file mode 100644 index 00000000000..df9e08be6b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/AllVariablesControlFlowPolicy.java @@ -0,0 +1,33 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Aug 6, 2002 + * Time: 6:16:17 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.*; + +public class AllVariablesControlFlowPolicy implements ControlFlowPolicy { + private final static AllVariablesControlFlowPolicy INSTANCE = new AllVariablesControlFlowPolicy(); + + public PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + PsiElement resolved = refExpr.resolve(); + return (resolved instanceof PsiVariable) ? (PsiVariable) resolved : null; + } + + public boolean isParameterAccepted(PsiParameter psiParameter) { + return true; + } + + public boolean isLocalVariableAccepted(PsiLocalVariable psiVariable) { + return true; + } + + public AllVariablesControlFlowPolicy getInstance() { + return INSTANCE; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/BranchingInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/BranchingInstruction.java new file mode 100644 index 00000000000..3dae36370d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/BranchingInstruction.java @@ -0,0 +1,18 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Sep 20, 2002 + */ +package com.intellij.psi.controlFlow; + +public abstract class BranchingInstruction extends InstructionBase { + public int offset; + + public BranchingInstruction(int offset) { + this.offset = offset; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitBranchingInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CallInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CallInstruction.java new file mode 100644 index 00000000000..d83a8a72e0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CallInstruction.java @@ -0,0 +1,28 @@ +package com.intellij.psi.controlFlow; + + + +public class CallInstruction extends GoToInstruction { + public final ControlFlowStack stack; + public int procBegin; + public int procEnd; + + public CallInstruction(int procBegin, int procEnd, ControlFlowStack stack) { + super(procBegin); + this.stack = stack; + this.procBegin = procBegin; + this.procEnd = procEnd; + } + + public String toString() { + return "CALL " + offset ; + } + + public void execute(int returnOffset) { + stack.push(returnOffset, this); + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitCallInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CommentInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CommentInstruction.java new file mode 100644 index 00000000000..e4b85f9d365 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CommentInstruction.java @@ -0,0 +1,17 @@ +package com.intellij.psi.controlFlow; + +public class CommentInstruction extends SimpleInstruction { + private final String myText; + + public CommentInstruction(String text) { + myText = text; + } + + public String toString() { + return "; " + myText; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitCommentInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CompositeInstructionClientVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CompositeInstructionClientVisitor.java new file mode 100644 index 00000000000..a215846c951 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/CompositeInstructionClientVisitor.java @@ -0,0 +1,119 @@ +/** + * @author Alexey + */ +package com.intellij.psi.controlFlow; + +class CompositeInstructionClientVisitor extends InstructionClientVisitor { + private final InstructionClientVisitor[] myVisitors; + + public CompositeInstructionClientVisitor(InstructionClientVisitor[] visitors) { + myVisitors = visitors; + } + + public Object[] getResult() { + Object[] result = new Object[myVisitors.length]; + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + result[i] = visitor.getResult(); + } + return result; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitInstruction(instruction, offset, nextOffset); + } + } + + public void visitEmptyInstruction(EmptyInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitEmptyInstruction(instruction, offset, nextOffset); + } + } + + public void visitCommentInstruction(CommentInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitCommentInstruction(instruction, offset, nextOffset); + } + } + + public void visitReadVariableInstruction(ReadVariableInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitReadVariableInstruction(instruction, offset, nextOffset); + } + } + + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitWriteVariableInstruction(instruction, offset, nextOffset); + } + } + + public void visitSimpleInstruction(SimpleInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitSimpleInstruction(instruction, offset, nextOffset); + } + } + + public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitBranchingInstruction(instruction, offset, nextOffset); + } + } + + public void visitConditionalBranchingInstruction(ConditionalBranchingInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitConditionalBranchingInstruction(instruction, offset, nextOffset); + } + } + + public void visitConditionalGoToInstruction(ConditionalGoToInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitConditionalGoToInstruction(instruction, offset, nextOffset); + } + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitConditionalThrowToInstruction(instruction, offset, nextOffset); + } + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitThrowToInstruction(instruction, offset, nextOffset); + } + } + + public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitGoToInstruction(instruction, offset, nextOffset); + } + } + + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitCallInstruction(instruction, offset, nextOffset); + } + } + + public void visitReturnInstruction(ReturnInstruction instruction, int offset, int nextOffset) { + for (int i = 0; i < myVisitors.length; i++) { + final InstructionClientVisitor visitor = myVisitors[i]; + visitor.visitReturnInstruction(instruction, offset, nextOffset); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalBranchingInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalBranchingInstruction.java new file mode 100644 index 00000000000..cccc59ad44b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalBranchingInstruction.java @@ -0,0 +1,30 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; + +/** + * Author: msk + */ +public class ConditionalBranchingInstruction extends BranchingInstruction { + protected static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ConditionalGoToInstruction"); + + public ConditionalBranchingInstruction(int offset) { + super(offset); + } + + public int nNext() { return 2; } + + public int getNext(int index, int no) { + switch (no) { + case 0: return offset; + case 1: return index + 1; + default: + LOG.assertTrue (false); + return -1; + } + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitConditionalBranchingInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalGoToInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalGoToInstruction.java new file mode 100644 index 00000000000..ab75c0479ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalGoToInstruction.java @@ -0,0 +1,37 @@ +package com.intellij.psi.controlFlow; + + +public class ConditionalGoToInstruction extends ConditionalBranchingInstruction { + + public final int role; + public final boolean isReturn; //true if goto has been generated as a result of return statement + + public ConditionalGoToInstruction(int offset) { + this(offset,ControlFlow.JUMP_ROLE_GOTO_END); + } + public ConditionalGoToInstruction(int offset, int role) { + this(offset,role, false); + } + public ConditionalGoToInstruction(int offset, int role, boolean isReturn) { + super(offset); + this.role = role; + this.isReturn = isReturn; + } + + public String toString() { + final String sRole; + if (role == ControlFlow.JUMP_ROLE_GOTO_ELSE) sRole = "[ELSE]"; + else if (role == ControlFlow.JUMP_ROLE_GOTO_THEN) sRole = "[THEN]"; + else if (role == ControlFlow.JUMP_ROLE_GOTO_END) sRole = "[END]"; + else { + LOG.assertTrue(false,"Unknown Role: "+role); + sRole = "???"; + } + + return "COND_GOTO " + sRole + " " + offset + (isReturn ? " RETURN" : ""); + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitConditionalGoToInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalThrowToInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalThrowToInstruction.java new file mode 100644 index 00000000000..2d88397973f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ConditionalThrowToInstruction.java @@ -0,0 +1,16 @@ +package com.intellij.psi.controlFlow; + +public class ConditionalThrowToInstruction extends ConditionalBranchingInstruction { + + public ConditionalThrowToInstruction(int offset) { + super(offset); + } + + public String toString() { + return "COND_THROW_TO " + offset; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitConditionalThrowToInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlow.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlow.java new file mode 100644 index 00000000000..e6d082559dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlow.java @@ -0,0 +1,32 @@ +/** + * @author cdr + */ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.PsiElement; + +import java.util.List; + +public interface ControlFlow { + ControlFlow EMPTY = new ControlFlowImpl(); + + int JUMP_ROLE_GOTO_END = 0; + int JUMP_ROLE_GOTO_THEN = 1; + int JUMP_ROLE_GOTO_ELSE = 2; + + Instruction[] getInstructions(); + + List getInstructionsList(); + + int getSize(); + + int getStartOffset(PsiElement element); + + int getEndOffset(PsiElement element); + + PsiElement getElement(int offset); + + // true means there is at least one place where controlflow has been shortcircuited due to constant condition + // false means no constant conditions were detected affecting control flow + boolean isConstantConditionOccurred(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java new file mode 100644 index 00000000000..414712aaa3c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java @@ -0,0 +1,1544 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.IntArrayList; +import gnu.trove.THashMap; +import gnu.trove.TIntArrayList; + +import java.util.*; + +public class ControlFlowAnalyzer extends PsiElementVisitor { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ControlFlowAnalyzer"); + + private final PsiElement myCodeFragment; + private final ControlFlowPolicy myPolicy; + + private ControlFlowImpl myCurrentFlow; + private List myCatchParameters = new ArrayList(); // stack of PsiParameter for catch + private List myCatchBlocks = new ArrayList(); + + private List myFinallyBlocks = new ArrayList(); + private List myUnhandledExceptionCatchBlocks = new ArrayList(); + private List myCheckedExceptions = new ArrayList(); + + private class StatementStack { + private List myStatements = new ArrayList(); + private TIntArrayList myAtStart = new TIntArrayList(); + + void popStatement() { + myAtStart.remove(myAtStart.size() - 1); + myStatements.remove(myStatements.size() - 1); + } + + PsiElement peekElement() { + return myStatements.get(myStatements.size() - 1); + } + + boolean peekAtStart() { + return myAtStart.get(myAtStart.size() - 1) == 1; + } + + void pushStatement(PsiElement statement, boolean atStart) { + myStatements.add(statement); + myAtStart.add(atStart ? 1 : 0); + } + } + + // element to jump to from inner (sub)expression in "jump to begin" situation. + // E.g. we should to jump to "then" branch if condition expression evaluated to true inside if statement + StatementStack myStartStatementStack = new StatementStack(); + // element to jump to from inner (sub)expression in "jump to end" situation. + // E.g. we should to jump to "else" branch if condition expression evaluated to false inside if statement + StatementStack myEndStatementStack = new StatementStack(); + + private IntArrayList myStartJumpRoles = new IntArrayList(); + private IntArrayList myEndJumpRoles = new IntArrayList(); + + // true if generate direct jumps for short-circuited operations, + // e.g. jump to else branch of if statement after each calculation of '&&' operand in condition + private final boolean myEnabledShortCircuit; + // true if evaluate constant expression inside 'if' statement condition and alter control flow accordingly + // in case of unreachable statement analysis must be false + private final boolean myEvaluateConstantIfConfition; + private final boolean myAssignmentTargetsAreElements; + + private List intArrayPool = new ArrayList(); + // map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getStartoffset(element) + private Map offsetsAddElementStart = new THashMap(); + // map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getEndOffset(element) + private Map offsetsAddElementEnd = new THashMap(); + + TIntArrayList getEmptyIntArray() { + final int size = intArrayPool.size(); + if (size == 0) { + return new TIntArrayList(1); + } + TIntArrayList list = intArrayPool.get(size - 1); + intArrayPool.remove(size - 1); + list.clear(); + return list; + } + + void poolIntArray(TIntArrayList list) { + intArrayPool.add(list); + } + + // patch instruction currently added to control flow so that its jump offset corrected on getStartOffset(element) or getEndOffset(element) + // when corresponding element offset become available + void addElementOffsetLater(PsiElement element, boolean atStart) { + Map offsetsAddElement = atStart ? offsetsAddElementStart : offsetsAddElementEnd; + TIntArrayList offsets = offsetsAddElement.get(element); + if (offsets == null) { + offsets = getEmptyIntArray(); + offsetsAddElement.put(element, offsets); + } + int offset = myCurrentFlow.getSize() - 1; + offsets.add(offset); + if (myCurrentFlow.getEndOffset(element) != -1) { + patchInstructionOffsets(element); + } + } + + + private void patchInstructionOffsets(PsiElement element) { + patchInstructionOffsets(offsetsAddElementStart.get(element), myCurrentFlow.getStartOffset(element)); + offsetsAddElementStart.put(element, null); + patchInstructionOffsets(offsetsAddElementEnd.get(element), myCurrentFlow.getEndOffset(element)); + offsetsAddElementEnd.put(element, null); + } + + private void patchInstructionOffsets(TIntArrayList offsets, int add) { + if (offsets == null) return; + for (int i = 0; i < offsets.size(); i++) { + int offset = offsets.get(i); + BranchingInstruction instruction = (BranchingInstruction)myCurrentFlow.getInstructionsList().get(offset); + instruction.offset += add; + LOG.assertTrue(instruction.offset >= 0); +// if (instruction instanceof ReturnInstruction) { +// final ReturnInstruction returnInstruction = ((ReturnInstruction) instruction); +// returnInstruction.procBegin += add; +// returnInstruction.procEnd += add; +// LOG.assertTrue(returnInstruction.procBegin > 0); +// LOG.assertTrue(returnInstruction.procEnd > returnInstruction.procBegin); +// } + } + poolIntArray(offsets); + } + + private void cleanupNonPatchedInstructionOffsets() { + // make all non patched goto instructions jump to the end of control flow + Iterator nonPatchedOffsets = offsetsAddElementStart.values().iterator(); + while (nonPatchedOffsets.hasNext()) { + TIntArrayList offsets = nonPatchedOffsets.next(); + patchInstructionOffsets(offsets, myCurrentFlow.getEndOffset(myCodeFragment)); + } + nonPatchedOffsets = offsetsAddElementEnd.values().iterator(); + while (nonPatchedOffsets.hasNext()) { + TIntArrayList offsets = nonPatchedOffsets.next(); + patchInstructionOffsets(offsets, myCurrentFlow.getEndOffset(myCodeFragment)); + } + } + + + public ControlFlowAnalyzer(PsiElement codeFragment, ControlFlowPolicy policy) { + this(codeFragment, policy, true); + } + + public ControlFlowAnalyzer(PsiElement codeFragment, ControlFlowPolicy policy, boolean enabledShortCircuit) { + // by default, do not evaluate constant conditions inside if + this(codeFragment, policy, enabledShortCircuit, false); + } + + public ControlFlowAnalyzer(PsiElement codeFragment, + ControlFlowPolicy policy, + boolean enabledShortCircuit, + boolean evaluateConstantIfConfition) { + this (codeFragment, policy, enabledShortCircuit, evaluateConstantIfConfition, false); + } + + public ControlFlowAnalyzer(PsiElement codeFragment, + ControlFlowPolicy policy, + boolean enabledShortCircuit, + boolean evaluateConstantIfConfition, + boolean assignmentTargetsAreElements) { + myCodeFragment = codeFragment; + myPolicy = policy; + myEnabledShortCircuit = enabledShortCircuit; + myEvaluateConstantIfConfition = evaluateConstantIfConfition; + myAssignmentTargetsAreElements = assignmentTargetsAreElements; + } + + + public ControlFlow buildControlFlow() throws AnalysisCanceledException { + + // push guard outer statement offsets in case when nested expression is incorrect + myStartJumpRoles.add(ControlFlow.JUMP_ROLE_GOTO_END); + myEndJumpRoles.add(ControlFlow.JUMP_ROLE_GOTO_END); + + myCurrentFlow = new ControlFlowImpl(); + + // guard elements + myStartStatementStack.pushStatement(myCodeFragment, false); + myEndStatementStack.pushStatement(myCodeFragment, false); + + try { + myCodeFragment.accept(this); + cleanupNonPatchedInstructionOffsets(); + } + catch (AnalysisCanceledSoftException e) { + throw new AnalysisCanceledException(e.getErrorElement()); + } + + return myCurrentFlow; + } + + public static class AnalysisCanceledException extends Exception { + private final PsiElement myErrorElement; + + public AnalysisCanceledException(PsiElement errorElement) { + myErrorElement = errorElement; + } + + public PsiElement getErrorElement() { + return myErrorElement; + } + } + + private static class AnalysisCanceledSoftException extends RuntimeException { + private final PsiElement myErrorElement; + + public AnalysisCanceledSoftException(PsiElement errorElement) { + myErrorElement = errorElement; + } + + public PsiElement getErrorElement() { + return myErrorElement; + } + + } + + private void startElement(PsiElement element) { + if (PsiUtil.hasErrorElementChild(element)) { + // do not perform control flow analysis for incomplete code + throw new AnalysisCanceledSoftException(element); + } + ProgressManager.getInstance().checkCanceled(); + myCurrentFlow.startElement(element); + + generateUncheckedExceptionJumpsIfNeeded(element, true); + } + + private void generateUncheckedExceptionJumpsIfNeeded(PsiElement element, boolean atStart) { + // optimization: reduce number of instructions + boolean isGeneratingStatement = element instanceof PsiStatement && !(element instanceof PsiSwitchLabelStatement); + boolean isGeneratingCodeBlock = element instanceof PsiCodeBlock && !(element.getParent() instanceof PsiSwitchStatement); + if (isGeneratingStatement || isGeneratingCodeBlock) { + generateUncheckedExceptionJumps(element, atStart); + } + } + + private void finishElement(PsiElement element) { + generateUncheckedExceptionJumpsIfNeeded(element, false); + + myCurrentFlow.finishElement(element); + patchInstructionOffsets(element); + } + + + private void generateUncheckedExceptionJumps(PsiElement element, boolean atStart) { + // optimization: if we just generated all necessary jumps, do not generate it once again + if (atStart + && element instanceof PsiStatement + && element.getParent() instanceof PsiCodeBlock && element.getPrevSibling() != null) { + return; + } + + for (int i = myUnhandledExceptionCatchBlocks.size() - 1; i >= 0; i--) { + PsiElement block = myUnhandledExceptionCatchBlocks.get(i); + // cannot jump to outer catch blocks (belonging to outer try stmt) if current try{} has finally block + if (block == null) { + if (myFinallyBlocks.size() != 0) { + break; + } + else { + continue; + } + } + ConditionalThrowToInstruction throwToInstruction = new ConditionalThrowToInstruction(-1); // -1 for init parameter + myCurrentFlow.addInstruction(throwToInstruction); + if (!patchUncheckedThrowInstructionIfInsideFinally(throwToInstruction, element, block)) { + addElementOffsetLater(block, true); + } + } + + + // generate jump to the top finally block + if (myFinallyBlocks.size() != 0) { + final PsiElement finallyBlock = myFinallyBlocks.get(myFinallyBlocks.size() - 1); + ConditionalThrowToInstruction throwToInstruction = new ConditionalThrowToInstruction(-2); + myCurrentFlow.addInstruction(throwToInstruction); + if (!patchUncheckedThrowInstructionIfInsideFinally(throwToInstruction, element, finallyBlock)) { + addElementOffsetLater(finallyBlock, true); + } + } + + } + + private void generateCheckedExceptionJumps(PsiElement element) { + //generate jumps to all handled exception handlers + if (myCatchBlocks.size() != 0) { + final PsiClassType[] unhandledExceptions = ExceptionUtil.collectUnhandledExceptions(element, element.getParent()); + if (unhandledExceptions != null) { + for (int i = 0; i < unhandledExceptions.length; i++) { + PsiClassType unhandledException = unhandledExceptions[i]; + myCheckedExceptions.add(unhandledException); + generateThrow(unhandledException, element); + } + } + } + } + + private void generateThrow(PsiClassType unhandledException, PsiElement throwingElement) { + final List catchBlocks = findThrowToBlocks(unhandledException); + for (int j = 0; j < catchBlocks.size(); j++) { + PsiElement block = catchBlocks.get(j); + ConditionalThrowToInstruction instruction = new ConditionalThrowToInstruction(0); + myCurrentFlow.addInstruction(instruction); + if (!patchCheckedThrowInstructionIfInsideFinally(instruction, throwingElement, block)) { + if (block == null) { + addElementOffsetLater(myCodeFragment, false); + } + else { + instruction.offset--; // -1 for catch block param init + addElementOffsetLater(block, true); + } + } + } + } + + Map> finallyBlockToUnhandledExceptions = new HashMap>(); + + private boolean patchCheckedThrowInstructionIfInsideFinally(ConditionalThrowToInstruction instruction, + PsiElement throwingElement, + PsiElement elementToJumpTo) { + LOG.assertTrue(instruction != null); + + final PsiElement finallyBlock = findEnclosingFinallyBlockElement(throwingElement, elementToJumpTo); + if (finallyBlock == null) return false; + + List unhandledExceptionCatchBlocks = finallyBlockToUnhandledExceptions.get(finallyBlock); + if (unhandledExceptionCatchBlocks == null) { + unhandledExceptionCatchBlocks = new ArrayList(); + finallyBlockToUnhandledExceptions.put(finallyBlock, unhandledExceptionCatchBlocks); + } + int index = unhandledExceptionCatchBlocks.indexOf(elementToJumpTo); + if (index == -1) { + index = unhandledExceptionCatchBlocks.size(); + unhandledExceptionCatchBlocks.add(elementToJumpTo); + } + // first three return instructions are for normal completion, return statement call completion and unchecked exception throwing completion resp. + instruction.offset = 3 + index; + addElementOffsetLater(finallyBlock, false); + + return true; + } + + private boolean patchUncheckedThrowInstructionIfInsideFinally(ConditionalThrowToInstruction instruction, + PsiElement throwingElement, + PsiElement elementToJumpTo) { + LOG.assertTrue(instruction != null); + + final PsiElement finallyBlock = findEnclosingFinallyBlockElement(throwingElement, elementToJumpTo); + if (finallyBlock == null) return false; + + // first three return instructions are for normal completion, return statement call completion and unchecked exception throwing completion resp. + instruction.offset = 2; + addElementOffsetLater(finallyBlock, false); + + return true; + } + + public void visitCodeFragment(PsiCodeFragment codeFragment) { + startElement(codeFragment); + int prevOffset = myCurrentFlow.getSize(); + PsiElement[] children = codeFragment.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].accept(this); + } + + finishElement(codeFragment); + // cache child code block in hope it will be needed + ControlFlowFactory.registerControlFlow(codeFragment, new ControlFlowSubRange(myCurrentFlow, prevOffset, myCurrentFlow.getSize()), + myEvaluateConstantIfConfition, myPolicy); + } + + public void visitCodeBlock(PsiCodeBlock block) { + startElement(block); + int prevOffset = myCurrentFlow.getSize(); + PsiStatement[] statements = block.getStatements(); + for (int i = 0; i < statements.length; i++) { + statements[i].accept(this); + } + + //each statement should contain at least one instruction in order to getElement(offset) work + int nextOffset = myCurrentFlow.getSize(); + if (!(block.getParent() instanceof PsiSwitchStatement) && prevOffset == nextOffset) { + emitEmptyInstruction(); + } + + finishElement(block); + // cache child code block in hope it will be needed + ControlFlowFactory.registerControlFlow(block, new ControlFlowSubRange(myCurrentFlow, prevOffset, myCurrentFlow.getSize()), + myEvaluateConstantIfConfition, myPolicy); + } + + private void emitEmptyInstruction() { + myCurrentFlow.addInstruction(new EmptyInstruction()); + } + + + public void visitJspFile(JspFile file) { + visitChildren(file); + } + + public void visitBlockStatement(PsiBlockStatement statement) { + startElement(statement); + final PsiCodeBlock codeBlock = statement.getCodeBlock(); + if (codeBlock != null) codeBlock.accept(this); + finishElement(statement); + } + + public void visitBreakStatement(PsiBreakStatement statement) { + startElement(statement); + PsiStatement exitedStatement = statement.findExitedStatement(); + if (exitedStatement != null) { + final Instruction instruction; + final PsiElement finallyBlock = findEnclosingFinallyBlockElement(statement, exitedStatement); + final int finallyStartOffset = finallyBlock == null ? -1 : myCurrentFlow.getStartOffset(finallyBlock); + if (finallyBlock != null && finallyStartOffset != -1) { + // go out of finally, use return + CallInstruction callInstruction = (CallInstruction)myCurrentFlow.getInstructionsList().get(finallyStartOffset - 2); + instruction = new ReturnInstruction(0, myCurrentFlow.myStack, callInstruction); + } + else { + instruction = new GoToInstruction(0); + } + myCurrentFlow.addInstruction(instruction); + // exited statement might be out of control flow analyzed + addElementOffsetLater(exitedStatement, false); + } + finishElement(statement); + } + + private PsiElement findEnclosingFinallyBlockElement(PsiElement sourceElement, PsiElement jumpElement) { + PsiElement element = sourceElement; + while (element != null && !(element instanceof PsiFile)) { + if (element instanceof PsiCodeBlock + && element.getParent() instanceof PsiTryStatement + && ((PsiTryStatement)element.getParent()).getFinallyBlock() == element) { + // element maybe out of scope to be analyzed + if (myCurrentFlow.getStartOffset(element.getParent()) == -1) return null; + if (jumpElement == null || !PsiTreeUtil.isAncestor(element, jumpElement, false)) return element; + } + element = element.getParent(); + } + return null; + } + + public void visitContinueStatement(PsiContinueStatement statement) { + startElement(statement); + PsiStatement continuedStatement = statement.findContinuedStatement(); + if (continuedStatement != null) { + PsiElement body = null; + if (continuedStatement instanceof PsiForStatement) { + body = ((PsiForStatement)continuedStatement).getBody(); + } + else if (continuedStatement instanceof PsiWhileStatement) { + body = ((PsiWhileStatement)continuedStatement).getBody(); + } + else if (continuedStatement instanceof PsiDoWhileStatement) { + body = ((PsiDoWhileStatement)continuedStatement).getBody(); + } + else if (continuedStatement instanceof PsiForeachStatement) { + body = ((PsiForeachStatement)continuedStatement).getBody(); + } + if (body == null) { + body = myCodeFragment; + } + final Instruction instruction; + final PsiElement finallyBlock = findEnclosingFinallyBlockElement(statement, continuedStatement); + final int finallyStartOffset = finallyBlock == null ? -1 : myCurrentFlow.getStartOffset(finallyBlock); + if (finallyBlock != null && finallyStartOffset != -1) { + // go out of finally, use return + CallInstruction callInstruction = (CallInstruction)myCurrentFlow.getInstructionsList().get(finallyStartOffset - 2); + instruction = new ReturnInstruction(0, myCurrentFlow.myStack, callInstruction); + } + else { + instruction = new GoToInstruction(0); + } + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(body, false); + } + finishElement(statement); + } + + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + startElement(statement); + int pc = myCurrentFlow.getSize(); + PsiElement[] elements = statement.getDeclaredElements(); + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (element instanceof PsiClass) { + element.accept(this); + } + else if (element instanceof PsiVariable) { + PsiExpression initializer = ((PsiVariable)element).getInitializer(); + if (initializer != null) { + myStartStatementStack.pushStatement(initializer, false); + myEndStatementStack.pushStatement(initializer, false); + initializer.accept(this); + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + } + if ((element instanceof PsiLocalVariable && initializer != null) + || element instanceof PsiField) { + if (element instanceof PsiLocalVariable && !myPolicy.isLocalVariableAccepted((PsiLocalVariable)element)) continue; + + if (myAssignmentTargetsAreElements) + startElement(element); + + generateWriteInstruction((PsiVariable)element); + + if (myAssignmentTargetsAreElements) + finishElement(element); + } + } + } + if (pc == myCurrentFlow.getSize()) { + // generate at least one instruction for declaration + emitEmptyInstruction(); + } + finishElement(statement); + } + + public void visitDoWhileStatement(PsiDoWhileStatement statement) { + startElement(statement); + myStartStatementStack.pushStatement(statement.getBody() == null ? statement : statement.getBody(), true); + myEndStatementStack.pushStatement(statement, false); + + PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + PsiExpression condition = statement.getCondition(); + if (condition != null) { + condition.accept(this); + } + + int offset = myCurrentFlow.getStartOffset(statement); + + Object loopCondition = statement.getManager().getConstantEvaluationHelper().computeConstantExpression(statement.getCondition()); + if (loopCondition instanceof Boolean) { + if (((Boolean)loopCondition).booleanValue()) { + myCurrentFlow.addInstruction(new GoToInstruction(offset)); + } + else { + emitEmptyInstruction(); + } + + } + else { + Instruction instruction = new ConditionalGoToInstruction(offset); + myCurrentFlow.addInstruction(instruction); + } + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + finishElement(statement); + } + + public void visitEmptyStatement(PsiEmptyStatement statement) { + startElement(statement); + emitEmptyInstruction(); + + finishElement(statement); + } + + public void visitExpressionStatement(PsiExpressionStatement statement) { + startElement(statement); + final PsiExpression expression = statement.getExpression(); + if (expression != null) expression.accept(this); + + for (int i = myCheckedExceptions.size() - 1; i >= 0; i--) { + PsiClassType exception = myCheckedExceptions.get(i); + generateThrow(exception, statement); + } + myCheckedExceptions.clear(); + + finishElement(statement); + } + + public void visitExpressionListStatement(PsiExpressionListStatement statement) { + startElement(statement); + PsiExpression[] expressions = statement.getExpressionList().getExpressions(); + for (int i = 0; i < expressions.length; i++) { + PsiExpression expr = expressions[i]; + expr.accept(this); + } + finishElement(statement); + } + + public void visitField(PsiField field) { + final PsiExpression initializer = field.getInitializer(); + if (initializer != null) { + startElement(field); + initializer.accept(this); + finishElement(field); + } + } + + public void visitForStatement(PsiForStatement statement) { + startElement(statement); + myStartStatementStack.pushStatement(statement.getBody() == null ? statement : statement.getBody(), false); + myEndStatementStack.pushStatement(statement, false); + + PsiStatement initialization = statement.getInitialization(); + if (initialization != null) { + initialization.accept(this); + } + + PsiExpression condition = statement.getCondition(); + if (condition != null) { + condition.accept(this); + } + + + Object loopCondition = statement.getManager().getConstantEvaluationHelper().computeConstantExpression(condition); + if (loopCondition instanceof Boolean || condition == null) { + boolean value = condition == null ? true : ((Boolean)loopCondition).booleanValue(); + if (value) { + emitEmptyInstruction(); + } + else { + myCurrentFlow.addInstruction(new GoToInstruction(0)); + addElementOffsetLater(statement, false); + } + } + else { + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(statement, false); + } + + PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + PsiStatement update = statement.getUpdate(); + if (update != null) { + update.accept(this); + } + + int offset = initialization != null + ? myCurrentFlow.getEndOffset(initialization) + : myCurrentFlow.getStartOffset(statement); + Instruction instruction = new GoToInstruction(offset); + myCurrentFlow.addInstruction(instruction); + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + finishElement(statement); + } + + public void visitForeachStatement(PsiForeachStatement statement) { + startElement(statement); + final PsiStatement body = statement.getBody(); + myStartStatementStack.pushStatement(body == null ? statement : body, false); + myEndStatementStack.pushStatement(statement, false); + final PsiExpression iteratedValue = statement.getIteratedValue(); + if (iteratedValue != null) { + iteratedValue.accept(this); + } + + final int gotoTarget = myCurrentFlow.getSize(); + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(statement, false); + + final PsiParameter iterationParameter = statement.getIterationParameter(); + if (iterationParameter != null) { + if (myPolicy.isParameterAccepted(iterationParameter)) { + generateWriteInstruction(iterationParameter); + } + } + if (body != null) { + body.accept(this); + } + + final GoToInstruction gotoInstruction = new GoToInstruction(gotoTarget); + myCurrentFlow.addInstruction(gotoInstruction); + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + finishElement(statement); + } + + public void visitIfStatement(PsiIfStatement statement) { + startElement(statement); + + final PsiStatement elseBranch = statement.getElseBranch(); + final PsiStatement thenBranch = statement.getThenBranch(); + PsiExpression conditionExpression = statement.getCondition(); + + generateConditionalStatementInstructions(statement, conditionExpression, thenBranch, elseBranch); + + finishElement(statement); + } + + private void generateConditionalStatementInstructions(PsiElement statement, + PsiExpression conditionExpression, + final PsiElement thenBranch, + final PsiElement elseBranch) { + if (thenBranch == null) { + myStartStatementStack.pushStatement(statement, false); + } + else { + myStartStatementStack.pushStatement(thenBranch, + true); + } + if (elseBranch == null) myEndStatementStack.pushStatement(statement, false); else myEndStatementStack.pushStatement(elseBranch, true); + + myEndJumpRoles.add(elseBranch == null ? ControlFlow.JUMP_ROLE_GOTO_END : ControlFlow.JUMP_ROLE_GOTO_ELSE); + myStartJumpRoles.add(thenBranch == null ? ControlFlow.JUMP_ROLE_GOTO_END : ControlFlow.JUMP_ROLE_GOTO_THEN); + + if (conditionExpression != null) { + conditionExpression.accept(this); + } + + boolean generateElseFlow = true; + boolean generateThenFlow = true; + boolean generateConditionalJump = true; + /** + * if() statement generated instructions outline: + * 'if (C) { A } [ else { B } ]' : + * generate (C) + * cond_goto else + * generate (A) + * [ goto end ] + * :else + * [ generate (B) ] + * :end + */ + if (myEvaluateConstantIfConfition) { + final Object value = statement.getManager().getConstantEvaluationHelper().computeConstantExpression(conditionExpression); + if (value instanceof Boolean) { + boolean condition = ((Boolean)value).booleanValue(); + generateThenFlow = condition; + generateElseFlow = !condition; + generateConditionalJump = false; + myCurrentFlow.setConstantConditionOccurred(true); + } + } + if (generateConditionalJump) { + Instruction instruction = new ConditionalGoToInstruction(0, + elseBranch == null + ? ControlFlow.JUMP_ROLE_GOTO_END + : ControlFlow.JUMP_ROLE_GOTO_ELSE); + myCurrentFlow.addInstruction(instruction); + if (elseBranch != null) { + addElementOffsetLater(elseBranch, true); + } + else { + addElementOffsetLater(statement, false); + } + } + if (thenBranch != null && generateThenFlow) { + thenBranch.accept(this); + } + if (elseBranch != null && generateElseFlow) { + if (generateThenFlow) { + // make jump to end after then branch (only if it has been generated) + Instruction instruction = new GoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(statement, false); + } + elseBranch.accept(this); + } + + myStartJumpRoles.remove(myStartJumpRoles.size() - 1); + myEndJumpRoles.remove(myEndJumpRoles.size() - 1); + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + } + + public void visitLabeledStatement(PsiLabeledStatement statement) { + startElement(statement); + final PsiStatement innerStatement = statement.getStatement(); + if (innerStatement != null) { + innerStatement.accept(this); + } + finishElement(statement); + } + + public void visitReturnStatement(PsiReturnStatement statement) { + startElement(statement); + PsiExpression returnValue = statement.getReturnValue(); + + myStartStatementStack.pushStatement(returnValue, false); + myEndStatementStack.pushStatement(returnValue, false); + + if (returnValue != null) { + returnValue.accept(this); + } + addReturnInstruction(statement); + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + + finishElement(statement); + } + + private void addReturnInstruction(PsiElement statement) { + BranchingInstruction instruction; + final PsiElement finallyBlock = findEnclosingFinallyBlockElement(statement, null); + final int finallyStartOffset = finallyBlock == null ? -1 : myCurrentFlow.getStartOffset(finallyBlock); + if (finallyBlock != null && finallyStartOffset != -1) { + // go out of finally, go to 2nd return after finally block + // second return is for return statement called completion + instruction = new GoToInstruction(2, ControlFlow.JUMP_ROLE_GOTO_END, true); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(finallyBlock, false); + } + else { + instruction = new GoToInstruction(0, ControlFlow.JUMP_ROLE_GOTO_END, true); + myCurrentFlow.addInstruction(instruction); + if (myFinallyBlocks.size() == 0) { + addElementOffsetLater(myCodeFragment, false); + } + else { + instruction.offset = -4; // -4 for return + addElementOffsetLater(myFinallyBlocks.get(myFinallyBlocks.size() - 1), true); + } + } + } + + public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) { + startElement(statement); + finishElement(statement); + } + + public void visitSwitchStatement(PsiSwitchStatement statement) { + startElement(statement); + + PsiExpression expr = statement.getExpression(); + if (expr != null) { + expr.accept(this); + } + + PsiCodeBlock body = statement.getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + PsiSwitchLabelStatement defaultLabel = null; + for (int i = 0; i < statements.length; i++) { + PsiStatement aStatement = statements[i]; + if (aStatement instanceof PsiSwitchLabelStatement) { + if (((PsiSwitchLabelStatement)aStatement).isDefaultCase()) { + defaultLabel = (PsiSwitchLabelStatement)aStatement; + } + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(aStatement, true); + } + } + if (defaultLabel == null) { + Instruction instruction = new GoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(body, false); + } + + body.accept(this); + } + + finishElement(statement); + } + + public void visitSynchronizedStatement(PsiSynchronizedStatement statement) { + startElement(statement); + + PsiExpression lock = statement.getLockExpression(); + if (lock != null) { + lock.accept(this); + } + + PsiCodeBlock body = statement.getBody(); + if (body != null) { + body.accept(this); + } + + finishElement(statement); + } + + public void visitThrowStatement(PsiThrowStatement statement) { + startElement(statement); + + PsiExpression exception = statement.getException(); + if (exception != null) { + exception.accept(this); + } + final List blocks = findThrowToBlocks(statement); + PsiElement element; + if (blocks.size() == 0 || blocks.get(0) == null) { + ThrowToInstruction instruction = new ThrowToInstruction(0); + myCurrentFlow.addInstruction(instruction); + if (myFinallyBlocks.size() == 0) { + element = myCodeFragment; + addElementOffsetLater(element, false); + } + else { + instruction.offset = -2; // -2 to rethrow exception + element = myFinallyBlocks.get(myFinallyBlocks.size() - 1); + addElementOffsetLater(element, true); + } + } + else { + for (int i = 0; i < blocks.size(); i++) { + element = blocks.get(i); + BranchingInstruction instruction = i == blocks.size() - 1 + ? new ThrowToInstruction(0) + : (BranchingInstruction)new ConditionalThrowToInstruction(0); + myCurrentFlow.addInstruction(instruction); + instruction.offset = -1; // -1 to init catch param + addElementOffsetLater(element, true); + } + } + + + finishElement(statement); + } + + /** + * find offsets of catch(es) corresponding to this throw statement + * mycatchParameters and mycatchpoints arrays should be sorted in ascending scope order (from outermost to innermost) + * + * @return offset or -1 if not found + */ + private List findThrowToBlocks(PsiThrowStatement statement) { + final PsiExpression exceptionExpr = statement.getException(); + if (exceptionExpr == null) return Collections.EMPTY_LIST; + final PsiType throwType = exceptionExpr.getType(); + if (!(throwType instanceof PsiClassType)) return Collections.EMPTY_LIST; + return findThrowToBlocks((PsiClassType)throwType); + } + + private List findThrowToBlocks(PsiClassType throwType) { + List blocks = new ArrayList(); + for (int i = myCatchParameters.size() - 1; i >= 0; i--) { + PsiParameter parameter = myCatchParameters.get(i); + final PsiType type = parameter.getType(); + if (type == null) continue; + PsiClass catchedClass = PsiUtil.resolveClassInType(type); + if (catchedClass == null) continue; + if (type.isAssignableFrom(throwType)) { + blocks.add(myCatchBlocks.get(i)); + } + else if (throwType.isAssignableFrom(type)) { + blocks.add(myCatchBlocks.get(i)); + } + } + if (blocks.size() == 0) { + // consider it as throw at the end of the control flow + blocks.add(null); + } + return blocks; + } + + public void visitAssertStatement(PsiAssertStatement statement) { + startElement(statement); + + final Instruction instruction; + + // should not try to compute constant expression within assert + // since assertions can be disabled/enabled at any moment via JVM flags + + instruction = new ConditionalThrowToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(myCodeFragment, false); + + final PsiExpression condition = statement.getAssertCondition(); + if (condition != null) { + myStartStatementStack.pushStatement(statement, false); + myEndStatementStack.pushStatement(statement, false); + + myEndJumpRoles.add(ControlFlow.JUMP_ROLE_GOTO_END); + myStartJumpRoles.add(ControlFlow.JUMP_ROLE_GOTO_END); + + condition.accept(this); + + myStartJumpRoles.remove(myStartJumpRoles.size() - 1); + myEndJumpRoles.remove(myEndJumpRoles.size() - 1); + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + } + PsiExpression description = statement.getAssertDescription(); + if (description != null) { + description.accept(this); + } + finishElement(statement); + } + + public void visitTryStatement(PsiTryStatement statement) { + startElement(statement); + + PsiCodeBlock[] catchBlocks = statement.getCatchBlocks(); + PsiParameter[] catchBlockParameters = statement.getCatchBlockParameters(); + int catchNum = Math.min(catchBlocks.length, catchBlockParameters.length); + myUnhandledExceptionCatchBlocks.add(null); + for (int i = catchNum - 1; i >= 0; i--) { + myCatchParameters.add(catchBlockParameters[i]); + myCatchBlocks.add(catchBlocks[i]); + + final PsiType type = catchBlockParameters[i].getType(); + // todo cast param + if (type instanceof PsiClassType && + ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)type)) { + myUnhandledExceptionCatchBlocks.add(catchBlocks[i]); + } + } + + PsiCodeBlock finallyBlock = statement.getFinallyBlock(); + + if (finallyBlock != null) { + myFinallyBlocks.add(finallyBlock); + } + + PsiCodeBlock tryBlock = statement.getTryBlock(); + if (tryBlock != null) { + // javac works as if all checked exceptions can occur at the top of the block + generateCheckedExceptionJumps(tryBlock); + tryBlock.accept(this); + } + + while (myUnhandledExceptionCatchBlocks.remove(myUnhandledExceptionCatchBlocks.size() - 1) != null) ; + + myCurrentFlow.addInstruction(new GoToInstruction(finallyBlock == null ? 0 : -6)); + if (finallyBlock == null) { + addElementOffsetLater(statement, false); + } + else { + addElementOffsetLater(finallyBlock, true); + } + + for (int i = 0; i < catchNum; i++) { + myCatchParameters.remove(myCatchParameters.size() - 1); + myCatchBlocks.remove(myCatchBlocks.size() - 1); + } + + for (int i = catchNum - 1; i >= 0; i--) { + if (myPolicy.isParameterAccepted(catchBlockParameters[i])) { + generateWriteInstruction(catchBlockParameters[i]); + } + catchBlocks[i].accept(this); + + myCurrentFlow.addInstruction(new GoToInstruction(finallyBlock == null ? 0 : -6)); + if (finallyBlock == null) { + addElementOffsetLater(statement, false); + } + else { + addElementOffsetLater(finallyBlock, true); + } + } + + if (finallyBlock != null) { + myFinallyBlocks.remove(myFinallyBlocks.size() - 1); + } + + if (finallyBlock != null) { + // normal completion, call finally block and proceed + myCurrentFlow.addInstruction(new CallInstruction(0, 0, myCurrentFlow.myStack)); + addElementOffsetLater(finallyBlock, true); + myCurrentFlow.addInstruction(new GoToInstruction(0)); + addElementOffsetLater(statement, false); + // return completion, call finally block and return + myCurrentFlow.addInstruction(new CallInstruction(0, 0, myCurrentFlow.myStack)); + addElementOffsetLater(finallyBlock, true); + addReturnInstruction(statement); + // throw exception completion, call finally block and rethrow + myCurrentFlow.addInstruction(new CallInstruction(0, 0, myCurrentFlow.myStack)); + addElementOffsetLater(finallyBlock, true); + final GoToInstruction gotoUncheckedRethrow = new GoToInstruction(0); + myCurrentFlow.addInstruction(gotoUncheckedRethrow); + addElementOffsetLater(finallyBlock, false); + + finallyBlock.accept(this); + final int procStart = myCurrentFlow.getStartOffset(finallyBlock); + final int procEnd = myCurrentFlow.getEndOffset(finallyBlock); + int offset = procStart - 6; + final Instruction[] instructions = myCurrentFlow.getInstructions(); + CallInstruction callInstruction = (CallInstruction)instructions[offset]; + callInstruction.procBegin = procStart; + callInstruction.procEnd = procEnd; + offset += 2; + callInstruction = (CallInstruction)instructions[offset]; + callInstruction.procBegin = procStart; + callInstruction.procEnd = procEnd; + offset += 2; + callInstruction = (CallInstruction)instructions[offset]; + callInstruction.procBegin = procStart; + callInstruction.procEnd = procEnd; + + // generate return instructions + // first three return instructions are for normal completion, return statement call completion and unchecked exception throwing completion resp. + + // normal completion + myCurrentFlow.addInstruction(new ReturnInstruction(0, myCurrentFlow.myStack, callInstruction)); + + // return statement call completion + myCurrentFlow.addInstruction(new ReturnInstruction(procStart - 3, myCurrentFlow.myStack, callInstruction)); + + // unchecked exception throwing completion + myCurrentFlow.addInstruction(new ReturnInstruction(procStart - 1, myCurrentFlow.myStack, callInstruction)); + + // checked exception throwing completion. need to dispatch to the correct catch clause + final List unhandledExceptionCatchBlocks = finallyBlockToUnhandledExceptions.remove(finallyBlock); + for (int i = 0; unhandledExceptionCatchBlocks != null && i < unhandledExceptionCatchBlocks.size(); i++) { + PsiElement catchBlock = unhandledExceptionCatchBlocks.get(i); + + final ReturnInstruction returnInstruction = new ReturnInstruction(0, myCurrentFlow.myStack, callInstruction); + myCurrentFlow.addInstruction(returnInstruction); + if (catchBlock == null) { + // dispatch to rethrowing exception code + returnInstruction.offset = procStart - 1; + } + else { + // dispatch to catch clause + addElementOffsetLater(catchBlock, true); + } + } + + // here generated rethrowing code for unchecked exceptions + gotoUncheckedRethrow.offset = myCurrentFlow.getSize(); + generateUncheckedExceptionJumps(statement, false); + // just in case + myCurrentFlow.addInstruction(new ThrowToInstruction(0)); + addElementOffsetLater(myCodeFragment, false); + + } + + finishElement(statement); + } + + + public void visitWhileStatement(PsiWhileStatement statement) { + startElement(statement); + if (statement.getBody() == null) { + myStartStatementStack.pushStatement(statement, false); + } + else { + myStartStatementStack.pushStatement(statement.getBody(), true); + } + myEndStatementStack.pushStatement(statement, false); + + PsiExpression condition = statement.getCondition(); + if (condition != null) { + condition.accept(this); + } + + + Object loopCondition = statement.getManager().getConstantEvaluationHelper().computeConstantExpression(statement.getCondition()); + if (loopCondition instanceof Boolean) { + boolean value = ((Boolean)loopCondition).booleanValue(); + if (value) { + emitEmptyInstruction(); + } + else { + myCurrentFlow.addInstruction(new GoToInstruction(0)); + addElementOffsetLater(statement, false); + } + } + else { + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(statement, false); + } + + PsiStatement body = statement.getBody(); + if (body != null) { + body.accept(this); + } + int offset = myCurrentFlow.getStartOffset(statement); + Instruction instruction = new GoToInstruction(offset); + myCurrentFlow.addInstruction(instruction); + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + finishElement(statement); + } + + public void visitExpressionList(PsiExpressionList list) { + PsiExpression[] expressions = list.getExpressions(); + for (int i = 0; i < expressions.length; i++) { + final PsiExpression expression = expressions[i]; + myStartStatementStack.pushStatement(expression, false); + myEndStatementStack.pushStatement(expression, false); + + expression.accept(this); + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + } + } + + public void visitArrayAccessExpression(PsiArrayAccessExpression expression) { + startElement(expression); + + if (expression.getArrayExpression() != null) expression.getArrayExpression().accept(this); + if (expression.getIndexExpression() != null) expression.getIndexExpression().accept(this); + + finishElement(expression); + } + + public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { + startElement(expression); + + PsiExpression[] initializers = expression.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + initializers[i].accept(this); + } + + finishElement(expression); + } + + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + startElement(expression); + + myStartStatementStack.pushStatement(expression.getRExpression() == null ? expression : expression.getRExpression(), false); + myEndStatementStack.pushStatement(expression.getRExpression() == null ? expression : expression.getRExpression(), false); + + PsiExpression rExpr = expression.getRExpression(); + if (rExpr != null) { + rExpr.accept(this); + } + + PsiExpression lExpr = expression.getLExpression(); + if (lExpr instanceof PsiReferenceExpression) { + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lExpr; + if (!referenceExpression.isQualified() + || referenceExpression.getQualifierExpression() instanceof PsiThisExpression) { + + PsiVariable variable = getUsedVariable(referenceExpression); + if (variable != null) { + if (myAssignmentTargetsAreElements) + startElement(lExpr); + + if (expression.getOperationSign().getTokenType() != JavaTokenType.EQ) { + generateReadInstruction(variable); + } + generateWriteInstruction(variable); + + if (myAssignmentTargetsAreElements) + finishElement(lExpr); + } + + } + else { + lExpr.accept(this); //? + } + } + else { + if (lExpr != null) lExpr.accept(this); + } + + myStartStatementStack.popStatement(); + myEndStatementStack.popStatement(); + + finishElement(expression); + } + + public void visitBinaryExpression(PsiBinaryExpression expression) { + startElement(expression); + + final PsiExpression lOperand = expression.getLOperand(); + if (lOperand != null) lOperand.accept(this); + + PsiConstantEvaluationHelper evalHelper = expression.getManager().getConstantEvaluationHelper(); + if (expression.getOperationSign() != null) { + IElementType signTokenType = expression.getOperationSign().getTokenType(); + if (signTokenType == JavaTokenType.ANDAND) { + if (myEnabledShortCircuit) { + final Object exprValue = evalHelper.computeConstantExpression(lOperand); + if (exprValue instanceof Boolean) { + myCurrentFlow.setConstantConditionOccurred(true); + } + if (calculateConstantExpression(expression) && exprValue instanceof Boolean) { + if (!((Boolean)exprValue).booleanValue()) { + myCurrentFlow.addInstruction(new GoToInstruction(0, myEndJumpRoles.get(myEndJumpRoles.size() - 1))); + addElementOffsetLater(myEndStatementStack.peekElement(), myEndStatementStack.peekAtStart()); + } + } + else { + myCurrentFlow.addInstruction(new ConditionalGoToInstruction(0, myEndJumpRoles.get(myEndJumpRoles.size() - 1))); + addElementOffsetLater(myEndStatementStack.peekElement(), myEndStatementStack.peekAtStart()); + } + } + else { + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(expression, false); + } + } + else if (signTokenType == JavaTokenType.OROR) { + if (myEnabledShortCircuit) { + final Object exprValue = evalHelper.computeConstantExpression(lOperand); + if (exprValue instanceof Boolean) { + myCurrentFlow.setConstantConditionOccurred(true); + } + if (calculateConstantExpression(expression) && exprValue instanceof Boolean) { + if (((Boolean)exprValue).booleanValue()) { + myCurrentFlow.addInstruction(new GoToInstruction(0, myStartJumpRoles.get(myStartJumpRoles.size() - 1))); + addElementOffsetLater(myStartStatementStack.peekElement(), myStartStatementStack.peekAtStart()); + } + } + else { + myCurrentFlow.addInstruction(new ConditionalGoToInstruction(0, myStartJumpRoles.get(myStartJumpRoles.size() - 1))); + addElementOffsetLater(myStartStatementStack.peekElement(), myStartStatementStack.peekAtStart()); + } + } + else { + Instruction instruction = new ConditionalGoToInstruction(0); + myCurrentFlow.addInstruction(instruction); + addElementOffsetLater(expression, false); + } + } + } + + if (expression.getROperand() != null) { + expression.getROperand().accept(this); + } + + finishElement(expression); + } + + private static boolean isInsideIfCondition(PsiExpression expression) { + PsiElement element = expression; + while (element instanceof PsiExpression) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiIfStatement && element == ((PsiIfStatement)parent).getCondition()) return true; + element = parent; + } + return false; + } + + private boolean calculateConstantExpression(PsiExpression expression) { + return myEvaluateConstantIfConfition || !isInsideIfCondition(expression); + } + + + public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { + visitChildren(expression); + + } + + private void visitChildren(PsiElement element) { + startElement(element); + + PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].accept(this); + } + + finishElement(element); + } + + public void visitConditionalExpression(PsiConditionalExpression expression) { + startElement(expression); + + final PsiExpression condition = expression.getCondition(); + final PsiExpression thenExpression = expression.getThenExpression(); + final PsiExpression elseExpression = expression.getElseExpression(); + generateConditionalStatementInstructions(expression, condition, thenExpression, elseExpression); + + finishElement(expression); + } + + public void visitInstanceOfExpression(PsiInstanceOfExpression expression) { + startElement(expression); + + final PsiExpression operand = expression.getOperand(); + if (operand != null) operand.accept(this); + + finishElement(expression); + } + + public void visitLiteralExpression(PsiLiteralExpression expression) { + startElement(expression); + finishElement(expression); + } + + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + startElement(expression); + + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + if (methodExpression != null) methodExpression.accept(this); + final PsiExpressionList argumentList = expression.getArgumentList(); + if (argumentList != null) argumentList.accept(this); + // just to increase counter - there is some executable code here + emitEmptyInstruction(); + + generateCheckedExceptionJumps(expression); + + finishElement(expression); + } + + public void visitNewExpression(PsiNewExpression expression) { + startElement(expression); + + int pc = myCurrentFlow.getSize(); + PsiElement[] children = expression.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].accept(this); + } + generateCheckedExceptionJumps(expression); + + if (pc == myCurrentFlow.getSize()) { + // generate at least one instruction for constructor call + emitEmptyInstruction(); + } + + finishElement(expression); + } + + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { + visitChildren(expression); + } + + public void visitPostfixExpression(PsiPostfixExpression expression) { + startElement(expression); + + String op = expression.getOperationSign().getText(); + PsiExpression operand = expression.getOperand(); + if (operand != null) operand.accept(this); + if (op.equals("++") || op.equals("--")) { + if (operand instanceof PsiReferenceExpression) { + PsiVariable variable = getUsedVariable((PsiReferenceExpression)operand); + if (variable != null) { + generateWriteInstruction(variable); + } + } + } + + finishElement(expression); + } + + public void visitPrefixExpression(PsiPrefixExpression expression) { + startElement(expression); + + String op = expression.getOperationSign().getText(); + PsiExpression operand = expression.getOperand(); + if (operand != null) { + operand.accept(this); + if (op.equals("++") || op.equals("--")) { + if (operand instanceof PsiReferenceExpression) { + PsiVariable variable = getUsedVariable((PsiReferenceExpression)operand); + if (variable != null) { + generateWriteInstruction(variable); + } + } + } + + } + + finishElement(expression); + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + startElement(expression); + + PsiExpression qualifier = expression.getQualifierExpression(); + if (qualifier != null) { + qualifier.accept(this); + } + + PsiVariable variable = getUsedVariable(expression); + if (variable != null) { + generateReadInstruction(variable); + } + + finishElement(expression); + } + + + public void visitSuperExpression(PsiSuperExpression expression) { + startElement(expression); + finishElement(expression); + } + + public void visitThisExpression(PsiThisExpression expression) { + startElement(expression); + finishElement(expression); + } + + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + startElement(expression); + PsiExpression operand = expression.getOperand(); + if (operand != null) { + operand.accept(this); + + } + finishElement(expression); + } + + public void visitClass(PsiClass aClass) { + startElement(aClass); + // anonymous or local class + if (aClass instanceof PsiAnonymousClass) { + final PsiElement arguments = PsiTreeUtil.getChildOfType(aClass, PsiExpressionList.class); + if (arguments != null) arguments.accept(this); + } + List array = new ArrayList(); + addUsedVariables(array, aClass); + for (int i = 0; i < array.size(); i++) { + PsiVariable var = array.get(i); + generateReadInstruction(var); + } + finishElement(aClass); + } + + private void addUsedVariables(List array, PsiElement scope) { + if (scope instanceof PsiReferenceExpression) { + PsiVariable variable = getUsedVariable((PsiReferenceExpression)scope); + if (variable != null) { + if (!array.contains(variable)) { + array.add(variable); + } + } + } + + PsiElement[] children = scope.getChildren(); + for (int i = 0; i < children.length; i++) { + addUsedVariables(array, children[i]); + } + } + + private void generateReadInstruction(PsiVariable variable) { + Instruction instruction = new ReadVariableInstruction(variable); + myCurrentFlow.addInstruction(instruction); + } + + private void generateWriteInstruction(PsiVariable variable) { + Instruction instruction = new WriteVariableInstruction(variable); + myCurrentFlow.addInstruction(instruction); + } + + private PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + if (refExpr.getParent() instanceof PsiMethodCallExpression) return null; + return myPolicy.getUsedVariable(refExpr); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowFactory.java new file mode 100644 index 00000000000..c3e677fd955 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowFactory.java @@ -0,0 +1,84 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Aug 13, 2002 + * Time: 12:07:14 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiElement; + +import java.lang.ref.SoftReference; + +public class ControlFlowFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ControlFlowFactory"); + + private static final Key> CONTROL_FLOW_KEY = Key.create("CONTROL_FLOW_KEY"); + + private static class ControlFlowContext { + private final ControlFlowPolicy policy; + private final boolean evaluateConstantIfCondition; + private final ControlFlow flow; + private ControlFlowContext next; + private final long myModificationCount; + + public ControlFlowContext(boolean evaluateConstantIfCondition, ControlFlowPolicy policy, ControlFlow flow, ControlFlowContext next, long modificationCount) { + this.evaluateConstantIfCondition = evaluateConstantIfCondition; + this.policy = policy; + this.flow = flow; + this.next = next; + myModificationCount = modificationCount; + } + } + + public static ControlFlow getControlFlow(PsiElement element, ControlFlowPolicy policy) throws ControlFlowAnalyzer.AnalysisCanceledException { + return getControlFlow(element, policy, true); + } + + public static ControlFlow getControlFlow(PsiElement element, ControlFlowPolicy policy, boolean evaluateConstantIfCondition) throws ControlFlowAnalyzer.AnalysisCanceledException { + SoftReference ref = element.getUserData(CONTROL_FLOW_KEY); + ControlFlowContext flows = ref == null ? null : ref.get(); + ControlFlowContext currentFlow = flows; + final long modificationCount = element.getManager().getModificationTracker().getModificationCount(); + ControlFlow flow = null; + while (currentFlow != null) { + if (currentFlow.policy == policy && isValid(currentFlow, modificationCount)) { + // optimization: when no constant condition were computed, both control flows are the same + if (currentFlow.evaluateConstantIfCondition == evaluateConstantIfCondition || !currentFlow.flow.isConstantConditionOccurred()) { + if (currentFlow.evaluateConstantIfCondition != evaluateConstantIfCondition) { + LOG.debug("CF constant cond optimization works for "+element+"("+(element.getText().length() > 40 ? element.getText().substring(0,40) : element.getText())+")"); + } + flow = currentFlow.flow; + break; + } + } + currentFlow = currentFlow.next; + } + if (flow == null) { + flow = new ControlFlowAnalyzer(element, policy, true, evaluateConstantIfCondition).buildControlFlow(); + registerControlFlow(element, flow, evaluateConstantIfCondition, policy); + } + if (flow instanceof ControlFlowSubRange) { + LOG.debug("CF optimization subrange works for "+element+"("+(element.getText().length() > 40 ? element.getText().substring(0,40) : element.getText())+")"); + } + return flow; + } + + static void registerControlFlow(PsiElement element, ControlFlow flow, boolean evaluateConstantIfCondition, ControlFlowPolicy policy) { + SoftReference ref = element.getUserData(CONTROL_FLOW_KEY); + ControlFlowContext flows = ref == null ? null : (ControlFlowContext) ref.get(); + final long modificationCount = element.getManager().getModificationTracker().getModificationCount(); + final ControlFlowContext controlFlowContext = new ControlFlowContext(evaluateConstantIfCondition, policy, flow, flows, modificationCount); + element.putUserData(CONTROL_FLOW_KEY, new SoftReference(controlFlowContext)); + } + + private static boolean isValid(ControlFlowContext currentFlow, long modificationCount) { + return modificationCount == currentFlow.myModificationCount; + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowImpl.java new file mode 100644 index 00000000000..42734e086ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowImpl.java @@ -0,0 +1,99 @@ + +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiStatement; +import gnu.trove.TObjectIntHashMap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +class ControlFlowImpl implements ControlFlow { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ControlFlowImpl"); + + private List myInstructions = new ArrayList(); + private TObjectIntHashMap myElementToStartOffsetMap = new TObjectIntHashMap(); + private TObjectIntHashMap myElementToEndOffsetMap = new TObjectIntHashMap(); + private List myElementsForInstructions = new ArrayList(); + ControlFlowStack myStack = new ControlFlowStack(); + private boolean myConstantConditionOccurred; + + private Stack myElementStack = new Stack(); + + public void addInstruction(Instruction instruction) { + myInstructions.add(instruction); + myElementsForInstructions.add(myElementStack.peek()); + } + + public void startElement(PsiElement element) { + myElementStack.push(element); + myElementToStartOffsetMap.put(element, myInstructions.size()); + + if (LOG.isDebugEnabled()){ + if (element instanceof PsiStatement){ + String text = element.getText(); + int index = Math.min(text.indexOf('\n'), text.indexOf('\r')); + if (index >= 0){ + text = text.substring(0, index); + } + addInstruction(new CommentInstruction(text)); + } + } + } + + public void finishElement(PsiElement element) { + LOG.assertTrue(myElementStack.pop().equals(element)); + myElementToEndOffsetMap.put(element, myInstructions.size()); + } + + public Instruction[] getInstructions() { + return myInstructions.toArray(new Instruction[myInstructions.size()]); + } + public List getInstructionsList() { + return myInstructions; + } + public int getSize() { + return myInstructions.size(); + } + + public int getStartOffset(PsiElement element) { + int value = myElementToStartOffsetMap.get(element); + if (value == 0){ + if (!myElementToStartOffsetMap.containsKey(element)) return -1; + } + return value; + } + + public int getEndOffset(PsiElement element) { + int value = myElementToEndOffsetMap.get(element); + if (value == 0){ + if (!myElementToEndOffsetMap.containsKey(element)) return -1; + } + return value; + } + + public PsiElement getElement(int offset) { + return myElementsForInstructions.get(offset); + } + + public boolean isConstantConditionOccurred() { + return myConstantConditionOccurred; + } + public void setConstantConditionOccurred(boolean constantConditionOccurred) { + myConstantConditionOccurred = constantConditionOccurred; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < myInstructions.size(); i++){ + Instruction instruction = myInstructions.get(i); + buffer.append(Integer.toString(i)); + buffer.append(": "); + buffer.append(instruction.toString()); + buffer.append("\n"); + } + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowInstructionVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowInstructionVisitor.java new file mode 100644 index 00000000000..ef4c29b5c34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowInstructionVisitor.java @@ -0,0 +1,49 @@ +/** + * @author cdr + */ +package com.intellij.psi.controlFlow; + +public class ControlFlowInstructionVisitor { + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + + } + public void visitEmptyInstruction(EmptyInstruction instruction, int offset, int nextOffset) { + visitSimpleInstruction(instruction, offset, nextOffset); + } + public void visitCommentInstruction(CommentInstruction instruction, int offset, int nextOffset) { + visitSimpleInstruction(instruction, offset, nextOffset); + } + public void visitReadVariableInstruction(ReadVariableInstruction instruction, int offset, int nextOffset) { + visitSimpleInstruction(instruction, offset, nextOffset); + } + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + visitSimpleInstruction(instruction, offset, nextOffset); + } + public void visitSimpleInstruction(SimpleInstruction instruction, int offset, int nextOffset) { + visitInstruction(instruction, offset, nextOffset); + } + public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { + visitInstruction(instruction, offset, nextOffset); + } + public void visitConditionalBranchingInstruction(ConditionalBranchingInstruction instruction, int offset, int nextOffset) { + visitBranchingInstruction(instruction, offset, nextOffset); + } + public void visitConditionalGoToInstruction(ConditionalGoToInstruction instruction, int offset, int nextOffset) { + visitConditionalBranchingInstruction(instruction, offset, nextOffset); + } + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + visitConditionalBranchingInstruction(instruction, offset, nextOffset); + } + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + visitBranchingInstruction(instruction, offset, nextOffset); + } + public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { + visitBranchingInstruction(instruction, offset, nextOffset); + } + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + visitGoToInstruction(instruction, offset, nextOffset); + } + public void visitReturnInstruction(ReturnInstruction instruction, int offset, int nextOffset) { + visitGoToInstruction(instruction, offset, nextOffset); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowPolicy.java new file mode 100644 index 00000000000..0b3e446cd0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowPolicy.java @@ -0,0 +1,12 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiVariable; + +public interface ControlFlowPolicy { + PsiVariable getUsedVariable(PsiReferenceExpression refExpr); + boolean isParameterAccepted(PsiParameter psiParameter); + boolean isLocalVariableAccepted(PsiLocalVariable psiVariable); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowStack.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowStack.java new file mode 100644 index 00000000000..dce08e8fbaf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowStack.java @@ -0,0 +1,37 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Sep 20, 2002 + */ +package com.intellij.psi.controlFlow; + +import com.intellij.util.containers.IntArrayList; + +import java.util.ArrayList; + +public class ControlFlowStack { + IntArrayList myIpStack = new IntArrayList(); + ArrayList myCallInstructionStack = new ArrayList(); + + public void push(int ip, CallInstruction callInstruction) { + myIpStack.add(ip); + myCallInstructionStack.add(callInstruction); + } + + public int pop(boolean pushBack) { + final int i = myIpStack.get(myIpStack.size() - 1); + if (!pushBack) { + myIpStack.remove(myIpStack.size()-1); + myCallInstructionStack.remove(myCallInstructionStack.size()-1); + } + return i; + } + public int peekReturnOffset() { + final int i = myIpStack.get(myIpStack.size() - 1); + return i; + } + public int size() { + return myIpStack.size(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowSubRange.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowSubRange.java new file mode 100644 index 00000000000..1db79f9b68d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowSubRange.java @@ -0,0 +1,96 @@ +/** + * @author cdr + */ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.PsiElement; + +import java.util.ArrayList; +import java.util.List; + +public class ControlFlowSubRange implements ControlFlow { + private final ControlFlow myControlFlow; + private final int myStart; + private final int myEnd; + private List myInstructions; + + public ControlFlowSubRange(ControlFlow controlFlow, int start, int end) { + myControlFlow = controlFlow; + myStart = start; + myEnd = end; + } + + public Instruction[] getInstructions() { + return getInstructionsList().toArray(new Instruction[myEnd-myStart]); + } + + public List getInstructionsList() { + if (myInstructions == null) { + final List list = new ArrayList(myEnd - myStart); + final List oldList = myControlFlow.getInstructionsList(); + for (int i = myStart; i < myEnd; i++) { + Instruction instruction = oldList.get(i).clone(); + if (instruction instanceof BranchingInstruction) { + BranchingInstruction branchingInstruction = (BranchingInstruction)instruction; + branchingInstruction.offset = patchOffset(branchingInstruction.offset); + } + if (instruction instanceof CallInstruction) { + final CallInstruction callInstruction = (CallInstruction)instruction; + callInstruction.procBegin = patchOffset(callInstruction.procBegin); + callInstruction.procEnd = patchOffset(callInstruction.procEnd); + } + if (instruction instanceof ReturnInstruction) { + final ReturnInstruction returnInstruction = (ReturnInstruction)instruction; + CallInstruction callInstruction = new CallInstruction(patchOffset(returnInstruction.getProcBegin()), patchOffset(returnInstruction.getProcEnd()), null); + returnInstruction.setCallInstruction(callInstruction); + } + list.add(instruction); + } + myInstructions = list; + } + return myInstructions; + } + + private int patchOffset(int offset) { + if (offset < myStart) offset = myStart; + else if (offset > myEnd) offset = myEnd; + offset -= myStart; + return offset; + } + + public int getSize() { + return myEnd - myStart; + } + + public int getStartOffset(PsiElement element) { + return patchOffset(myControlFlow.getStartOffset(element)); + //return (myControlFlow.getStartOffset(element)); + } + + public int getEndOffset(PsiElement element) { + return patchOffset(myControlFlow.getEndOffset(element)); + //return myControlFlow.getEndOffset(element); + } + + public PsiElement getElement(int offset) { + return myControlFlow.getElement(myStart + offset); + } + + public boolean isConstantConditionOccurred() { + return myControlFlow.isConstantConditionOccurred(); + } + + public String toString() { + StringBuffer buffer = new StringBuffer("CF range:["+myStart+"-"+myEnd+"]\n"); + final List instructions = getInstructionsList(); + for(int i = 0; i < instructions.size(); i++){ + Instruction instruction = instructions.get(i); + buffer.append(Integer.toString(i)); + buffer.append(": "); + buffer.append(instruction.toString()); + buffer.append("\n"); + } + return buffer.toString(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowUtil.java new file mode 100644 index 00000000000..585ac43f576 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -0,0 +1,1403 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.aspects.psi.PsiAdvice; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.IntArrayList; +import gnu.trove.*; + +import java.util.*; + +public class ControlFlowUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ControlFlowUtil"); + + private static class SSAInstructionState implements Cloneable { + private int myWriteCount; + private int myInstructionIdx; + + public SSAInstructionState(int writeCount, int instructionIdx) { + myWriteCount = writeCount; + myInstructionIdx = instructionIdx; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SSAInstructionState)) return false; + + final SSAInstructionState ssaInstructionState = (SSAInstructionState)o; + + if (myInstructionIdx != ssaInstructionState.myInstructionIdx) return false; + if (Math.min(2, myWriteCount) != Math.min(2, ssaInstructionState.myWriteCount)) return false; + + return true; + } + + public int hashCode() { + int result; + result = Math.min(2, myWriteCount); + result = 29 * result + myInstructionIdx; + return result; + } + + public int getWriteCount() { + return myWriteCount; + } + + public int getInstructionIdx() { + return myInstructionIdx; + } + } + + public static PsiVariable[] getSSAVariables(ControlFlow flow, boolean reportVarsIfNonInitializingPathExists) { + Instruction[] instructions = flow.getInstructions(); + return getSSAVariables(flow, 0, instructions.length, reportVarsIfNonInitializingPathExists); + } + + public static PsiVariable[] getSSAVariables(ControlFlow flow, int from, int to, + boolean reportVarsIfNonInitializingPathExists) { + Instruction[] instructions = flow.getInstructions(); + PsiVariable[] writtenVariables = getWrittenVariables(flow, from, to); + ArrayList result = new ArrayList(1); + + variables: + for (int k = 0; k < writtenVariables.length; k++) { + PsiVariable psiVariable = writtenVariables[k]; + + Set processedStates = new THashSet(); + + final List queue = new ArrayList(); + queue.add(new SSAInstructionState(0, from)); + + while (queue.size() > 0) { + final SSAInstructionState state = queue.remove(0); + if (state.getWriteCount() > 1) continue variables; + if (!processedStates.contains(state)) { + processedStates.add(state); + int i = state.getInstructionIdx(); + if (i < to) { + Instruction instruction = instructions[i]; + + if (instruction instanceof ReturnInstruction) { + int[] offsets = ((ReturnInstruction)instruction).getPossibleReturnOffsets(); + for (int j = 0; j < offsets.length; j++) { + queue.add(new SSAInstructionState(state.getWriteCount(), Math.min(offsets[j], to))); + } + } + else if (instruction instanceof GoToInstruction) { + int nextOffset = ((GoToInstruction)instruction).offset; + nextOffset = Math.min(nextOffset, to); + queue.add(new SSAInstructionState(state.getWriteCount(), nextOffset)); + } + else if (instruction instanceof ThrowToInstruction) { + int nextOffset = ((ThrowToInstruction)instruction).offset; + nextOffset = Math.min(nextOffset, to); + queue.add(new SSAInstructionState(state.getWriteCount(), nextOffset)); + } + else if (instruction instanceof ConditionalGoToInstruction) { + int nextOffset = ((ConditionalGoToInstruction)instruction).offset; + nextOffset = Math.min(nextOffset, to); + queue.add(new SSAInstructionState(state.getWriteCount(), nextOffset)); + queue.add(new SSAInstructionState(state.getWriteCount(), i + 1)); + } + else if (instruction instanceof ConditionalThrowToInstruction) { + int nextOffset = ((ConditionalThrowToInstruction)instruction).offset; + nextOffset = Math.min(nextOffset, to); + queue.add(new SSAInstructionState(state.getWriteCount(), nextOffset)); + queue.add(new SSAInstructionState(state.getWriteCount(), i + 1)); + } + else if (instruction instanceof WriteVariableInstruction) { + WriteVariableInstruction write = (WriteVariableInstruction)instruction; + queue.add( + new SSAInstructionState(state.getWriteCount() + (write.variable == psiVariable ? 1 : 0), i + 1) + ); + } + else if (instruction instanceof ReadVariableInstruction) { + ReadVariableInstruction read = (ReadVariableInstruction)instruction; + if (read.variable == psiVariable && state.getWriteCount() == 0) continue variables; + queue.add(new SSAInstructionState(state.getWriteCount(), i + 1)); + } + else { + queue.add(new SSAInstructionState(state.getWriteCount(), i + 1)); + } + } + else if (!reportVarsIfNonInitializingPathExists && state.getWriteCount() == 0) continue variables; + } + } + + result.add(psiVariable); + } + + return result.toArray(new PsiVariable[result.size()]); + } + + public static boolean needVariableValueAt(final PsiVariable variable, final ControlFlow flow, final int offset) { + InstructionClientVisitor visitor = new InstructionClientVisitor() { + boolean[] neededBelow = new boolean[flow.getSize()+1]; + + public void visitReadVariableInstruction(ReadVariableInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean needed = neededBelow[nextOffset]; + if (instruction.variable.equals(variable)) { + needed = true; + } + neededBelow[offset] |= needed; + } + + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean needed = neededBelow[nextOffset]; + if (instruction.variable.equals(variable)) { + needed = false; + } + neededBelow[offset] = needed; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean needed = neededBelow[nextOffset]; + neededBelow[offset] |= needed; + } + + public Boolean getResult() { + return Boolean.valueOf(neededBelow[offset]); + } + }; + depthFirstSearch(flow, visitor, offset, flow.getSize()); + return visitor.getResult().booleanValue(); + } + + public static PsiVariable[] getReadVariables(ControlFlow flow, int start, int end) { + ArrayList array = new ArrayList(); + Instruction[] instructions = flow.getInstructions(); + for (int i = start; i < end; i++) { + Instruction instruction = instructions[i]; + if (instruction instanceof ReadVariableInstruction) { + PsiVariable variable = ((ReadVariableInstruction)instruction).variable; + if (!array.contains(variable)) { + array.add(variable); + } + } + } + return array.toArray(new PsiVariable[array.size()]); + } + + public static PsiVariable[] getWrittenVariables(ControlFlow flow, int start, int end) { + ArrayList array = new ArrayList(); + Instruction[] instructions = flow.getInstructions(); + for (int i = start; i < end; i++) { + Instruction instruction = instructions[i]; + if (instruction instanceof WriteVariableInstruction) { + PsiVariable variable = ((WriteVariableInstruction)instruction).variable; + if (!array.contains(variable)) { + array.add(variable); + } + } + } + return array.toArray(new PsiVariable[array.size()]); + } + + public static PsiVariable[] getUsedVariables(ControlFlow flow, int start, int end) { + ArrayList array = new ArrayList(); + Instruction[] instructions = flow.getInstructions(); + for (int i = start; i < end; i++) { + Instruction instruction = instructions[i]; + if (instruction instanceof ReadVariableInstruction) { + PsiVariable variable = ((ReadVariableInstruction)instruction).variable; + if (!array.contains(variable)) { + array.add(variable); + } + } + else if (instruction instanceof WriteVariableInstruction) { + PsiVariable variable = ((WriteVariableInstruction)instruction).variable; + if (!array.contains(variable)) { + array.add(variable); + } + } + } + return array.toArray(new PsiVariable[array.size()]); + } + + public static PsiVariable[] getInputVariables(ControlFlow flow, int start, int end) { + PsiVariable[] usedVariables = ControlFlowUtil.getUsedVariables(flow, start, end); + ArrayList array = new ArrayList(); + for (int i = 0; i < usedVariables.length; i++) { + PsiVariable variable = usedVariables[i]; + if (ControlFlowUtil.needVariableValueAt(variable, flow, start)) { + array.add(variable); + } + } + PsiVariable[] inputVariables = array.toArray(new PsiVariable[array.size()]); + if (LOG.isDebugEnabled()) { + LOG.debug("input variables:"); + for (int i = 0; i < inputVariables.length; i++) { + PsiVariable variable = inputVariables[i]; + LOG.debug(" " + variable.toString()); + } + } + return inputVariables; + } + + public static PsiVariable[] getOutputVariables(ControlFlow flow, int start, int end, int exitPoint) { + PsiVariable[] writtenVariables = ControlFlowUtil.getWrittenVariables(flow, start, end); + ArrayList array = new ArrayList(); + for (int i = 0; i < writtenVariables.length; i++) { + PsiVariable variable = writtenVariables[i]; + if (ControlFlowUtil.needVariableValueAt(variable, flow, exitPoint)) { + array.add(variable); + } + } + PsiVariable[] outputVariables = array.toArray(new PsiVariable[array.size()]); + if (LOG.isDebugEnabled()) { + LOG.debug("output variables:"); + for (int i = 0; i < outputVariables.length; i++) { + PsiVariable variable = outputVariables[i]; + LOG.debug(" " + variable.toString()); + } + } + return outputVariables; + } + + public static void findExitPointsAndStatements(final ControlFlow flow, final int start, final int end, + final IntArrayList exitPoints, final List exitStatements, final Class[] classesFilter) { + if (end == start) { + exitPoints.add(end); + return; + } + InstructionClientVisitor visitor = new InstructionClientVisitor() { + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + //[ven]This is a hack since Extract Method doesn't want to see throw's exit points + processGotoStatement(flow, offset, classesFilter, exitStatements); + } + + public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { + processGoto(flow, start, end, exitPoints, exitStatements, offset, instruction.offset, null, classesFilter); + } + + // call/return do not incur exit points + public void visitReturnInstruction(ReturnInstruction instruction, int offset, int nextOffset) { + } + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + // ??? + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (offset >= end - 1) { + int exitOffset = end; + exitOffset = promoteThroughGotoChain(flow, exitOffset); + if (!exitPoints.contains(exitOffset)) { + exitPoints.add(exitOffset); + } + } + } + + public Object getResult() { + return null; + } + }; + depthFirstSearch(flow, visitor, start, end); + } + + private static void processGoto(ControlFlow flow, int start, int end, + IntArrayList exitPoints, + List exitStatements, + int offset, + int gotoOffset, + IntArrayList stack, + Class[] classesFilter) { + if (start <= gotoOffset && gotoOffset < end) { + if (stack != null) { + stack.add(gotoOffset); + } + } + else { + // process chain of goto's + gotoOffset = promoteThroughGotoChain(flow, gotoOffset); + + if (!exitPoints.contains(gotoOffset) && (gotoOffset >= end || gotoOffset < start)) { + exitPoints.add(gotoOffset); + } + processGotoStatement(flow, offset, classesFilter, exitStatements); + } + } + + private static void processGotoStatement(ControlFlow flow, int offset, Class[] classesFilter, List exitStatements) { + PsiStatement statement = findStatement(flow, offset); + if (statement != null) { + if (classesFilter == null) { + exitStatements.add(statement); + } else { + for (int i = 0; i < classesFilter.length; i++) { + if (classesFilter[i].isAssignableFrom(statement.getClass())) { + exitStatements.add(statement); + break; + } + } + } + } + } + + private static int promoteThroughGotoChain(ControlFlow flow, int offset) { + Instruction[] instructions = flow.getInstructions(); + while (true) { + if (offset >= instructions.length) break; + Instruction instruction = instructions[offset]; + if (!(instruction instanceof GoToInstruction) || ((GoToInstruction)instruction).isReturn) break; + offset = ((GoToInstruction)instruction).offset; + } + return offset; + } + + public static final Class[] DEFAULT_EXIT_STATEMENTS_CLASSES = new Class[] {PsiReturnStatement.class, PsiBreakStatement.class, PsiContinueStatement.class}; + + private static PsiStatement findStatement(ControlFlow flow, int offset) { + PsiElement element = flow.getElement(offset); + while (!(element instanceof PsiStatement) && element != null) { + element = element.getParent(); + } + return (PsiStatement)element; + } + + public static PsiElement findCodeFragment(PsiElement element) { + PsiElement codeFragment = element; + PsiElement parent = codeFragment.getParent(); + while (parent != null) { + if (parent instanceof PsiDirectory + || parent instanceof PsiMethod || parent instanceof PsiAdvice + || parent instanceof PsiField || parent instanceof PsiClassInitializer) { + break; + } + codeFragment = parent; + parent = parent.getParent(); + } + return codeFragment; + } + + private static boolean checkReferenceExpressionScope (final PsiReferenceExpression ref, final PsiElement targetClassMember) { + final ResolveResult resolveResult = ref.advancedResolve(false); + final PsiElement def = resolveResult.getElement(); + if (def != null) { + PsiElement parent = def.getParent (); + PsiElement commonParent = PsiTreeUtil.findCommonParent(parent, targetClassMember); + if (commonParent == null) { + parent = resolveResult.getCurrentFileResolveScope(); + } + if (parent instanceof PsiClass) { + final PsiClass clss = (PsiClass) parent; + if (PsiTreeUtil.isAncestor(targetClassMember, clss, false)) + return false; + } + } + + return true; + } + + /** + * Checks possibility of extracting code fragment outside containing anonymous (local) class. + * Also collects variables to be passed as additional parameters. + * @return true if code fragement can be extracted outside + * @param array Vector to collect variables to be passed as additional parameters + * @param scope scope to be scanned (part of code fragement to be extracted) + * @param member member containing the code to be extracted + * @param targetClassMember member in target class containing code fragement + */ + public static boolean collectOuterLocals(List array, PsiElement scope, PsiElement member, + PsiElement targetClassMember) { + if (scope instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression call = (PsiMethodCallExpression)scope; + if (!checkReferenceExpressionScope (call.getMethodExpression(), targetClassMember)) { + return false; + } + } + else if (scope instanceof PsiReferenceExpression) { + if (!checkReferenceExpressionScope ((PsiReferenceExpression)scope, targetClassMember)) { + return false; + } + } + + if (scope instanceof PsiJavaCodeReferenceElement) { + + final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)scope; + final ResolveResult result = ref.advancedResolve(false); + final PsiElement refElement = result.getElement(); + + if (refElement != null) { + + PsiElement parent = PsiTreeUtil.findCommonParent(refElement.getParent(), member); + if (parent == null) { + parent = result.getCurrentFileResolveScope(); + } + + if (parent != null && !member.equals(parent)) { // not local in member + parent = PsiTreeUtil.findCommonParent(parent, targetClassMember); + if (targetClassMember.equals(parent)) { //something in anonymous class + if (refElement instanceof PsiVariable) { + if (scope instanceof PsiReferenceExpression && + PsiUtil.isAccessedForWriting((PsiReferenceExpression)scope)) { + return false; + } + if (!array.contains(refElement)) { + array.add((PsiVariable)refElement); + } + } + else { + return false; + } + } + } + /* + if (scope instanceof PsiExpression) { + ResolveResult result = PsiUtil.getAccessObjectClass ((PsiExpression)scope); + if (result != null) { + return false; + } + } + */ + } + } + else if (scope instanceof PsiThisExpression) { + PsiJavaCodeReferenceElement qualifier = ((PsiThisExpression)scope).getQualifier(); + if (qualifier == null) { + return false; + } + } + else if (scope instanceof PsiSuperExpression) { + if (((PsiSuperExpression)scope).getQualifier() == null) { + return false; + } + } + + for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) { + if (!collectOuterLocals(array, child, member, targetClassMember)) return false; + } + return true; + } + + + /** + * @return true if each control flow path results in return statement or exception thrown + */ + public static boolean returnPresent(final ControlFlow flow) { + InstructionClientVisitor visitor = new ReturnPresentClientVisitor(flow); + + depthFirstSearch(flow, visitor); + return visitor.getResult().booleanValue(); + } + private static class ReturnPresentClientVisitor extends InstructionClientVisitor { + // false if control flow at this offset terminates either by return called or exception thrown + private final boolean[] isNormalCompletion; + private final ControlFlow myFlow; + + public ReturnPresentClientVisitor(ControlFlow flow) { + myFlow = flow; + isNormalCompletion = new boolean[myFlow.getSize() + 1]; + isNormalCompletion[myFlow.getSize()] = true; + } + + public void visitConditionalGoToInstruction(ConditionalGoToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + isNormalCompletion[offset] |= !instruction.isReturn && isNormalCompletion[nextOffset]; + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + boolean isNormal = instruction.offset == nextOffset && nextOffset != offset + 1 ? + !isLeaf(nextOffset) && isNormalCompletion[nextOffset] : + isLeaf(nextOffset) || isNormalCompletion[nextOffset]; + + isNormalCompletion[offset] |= isNormal; + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + isNormalCompletion[offset] |= !isLeaf(nextOffset) && isNormalCompletion[nextOffset]; + } + + public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + isNormalCompletion[offset] |= !instruction.isReturn && isNormalCompletion[nextOffset]; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + + boolean isNormal = isLeaf(nextOffset) || isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + + public Boolean getResult() { + return Boolean.valueOf(!isNormalCompletion[0]); + } + } + + public static boolean returnPresentBetween(final ControlFlow flow, final int startOffset, final int endOffset) { + class MyVisitor extends InstructionClientVisitor { + // false if control flow at this offset terminates either by return called or exception thrown + boolean[] isNormalCompletion = new boolean[flow.getSize() + 1]; + + public MyVisitor() { + int i; + final int length = flow.getSize(); + for (i = 0; i < startOffset; i++) { + isNormalCompletion[i] = true; + } + for (i = endOffset; i <= length; i++) { + isNormalCompletion[i] = true; + } + } + + public void visitConditionalGoToInstruction(ConditionalGoToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + boolean isNormal = !instruction.isReturn && isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + int throwToOffset = instruction.offset; + boolean isNormal; + if (throwToOffset == nextOffset) { + if (throwToOffset <= endOffset) { + isNormal = !isLeaf(nextOffset) && isNormalCompletion[nextOffset]; + } + else { + return; + } + } + else { + isNormal = isLeaf(nextOffset) || isNormalCompletion[nextOffset]; + } + isNormalCompletion[offset] |= isNormal; + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + if (nextOffset <= endOffset) { + boolean isNormal = !isLeaf(nextOffset) && isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + } + + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + if (nextOffset > endOffset && nextOffset != offset + 1) { + return; + } + boolean isNormal = isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + + public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + boolean isNormal = !instruction.isReturn && isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + final boolean isNormal = isLeaf(nextOffset) || isNormalCompletion[nextOffset]; + isNormalCompletion[offset] |= isNormal; + } + + public Boolean getResult() { + return Boolean.valueOf(!isNormalCompletion[startOffset]); + } + } + final MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor, startOffset, endOffset); + return visitor.getResult().booleanValue(); + } + + public static Object[] getAllWorldProblemsAtOnce(final ControlFlow flow) { + InstructionClientVisitor[] visitors = new InstructionClientVisitor[]{ + new ReturnPresentClientVisitor(flow), + new UnreachableStatementClientVisitor(flow), + new ReadBeforeWriteClientVisitor(flow), + new InitializedTwiceClientVisitor(flow), + }; + CompositeInstructionClientVisitor visitor = new CompositeInstructionClientVisitor(visitors); + depthFirstSearch(flow, visitor); + return visitor.getResult(); + } + + /** + * returns true iff exists controlflow path completing normally, i.e. not resulting in return,break,continue or exception thrown. + * In other words, if we add instruction after controlflow specified, it should be reachable + */ + public static boolean canCompleteNormally(final ControlFlow flow, final int startOffset, final int endOffset) { + class MyVisitor extends InstructionClientVisitor { + // false if control flow at this offset terminates abruptly + boolean[] canCompleteNormally = new boolean[flow.getSize() + 1]; + + public MyVisitor() { + //canCompleteNormally[endOffset] = true; + } + + public void visitConditionalGoToInstruction(ConditionalGoToInstruction instruction, int offset, int nextOffset) { + checkInstruction(offset, nextOffset, instruction.isReturn); + } + public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { + checkInstruction(offset, nextOffset, instruction.isReturn); + } + + private void checkInstruction(int offset, int nextOffset, boolean isReturn) { + if (offset > endOffset) return; + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean isNormal = nextOffset <= endOffset && !isReturn && (nextOffset == endOffset || canCompleteNormally[nextOffset]); + if (isNormal && nextOffset == endOffset) { + PsiElement element = flow.getElement(offset); + if (element instanceof PsiBreakStatement || element instanceof PsiContinueStatement) { + isNormal = false; + } + } + canCompleteNormally[offset] |= isNormal; + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + int throwToOffset = instruction.offset; + boolean isNormal; + if (throwToOffset == nextOffset) { + if (throwToOffset <= endOffset) { + isNormal = !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; + } + else { + isNormal = false; + } + } + else { + isNormal = canCompleteNormally[nextOffset]; + } + canCompleteNormally[offset] |= isNormal; + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + if (nextOffset <= endOffset) { + boolean isNormal = !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; + canCompleteNormally[offset] |= isNormal; + } + } + + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + if (offset > endOffset) return; + if (nextOffset > endOffset && nextOffset != offset + 1) { + return; + } + boolean isNormal = canCompleteNormally[nextOffset]; + canCompleteNormally[offset] |= isNormal; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + checkInstruction(offset, nextOffset, false); + } + + public Boolean getResult() { + return Boolean.valueOf(canCompleteNormally[startOffset]); + } + } + final MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor, startOffset, endOffset); + return visitor.getResult().booleanValue(); + } + + /** + * @return any unreachable statement or null + */ + public static PsiElement getUnreachableStatement(final ControlFlow flow) { + final InstructionClientVisitor visitor = new UnreachableStatementClientVisitor(flow); + depthFirstSearch(flow, visitor); + return visitor.getResult(); + } + private static class UnreachableStatementClientVisitor extends InstructionClientVisitor { + private final ControlFlow myFlow; + + public UnreachableStatementClientVisitor(ControlFlow flow) { + myFlow = flow; + } + + public PsiElement getResult() { + for (int i = 0; i < processedInstructions.length; i++) { + if (!processedInstructions[i]) { + PsiElement element = myFlow.getElement(i); + if (element == null || !PsiUtil.isStatement(element)) continue; + if (element.getParent() instanceof PsiExpression) continue; + + // ignore for(;;) statement unreachable update + while (element instanceof PsiExpression) { + element = element.getParent(); + } + if (element instanceof PsiStatement + && element.getParent() instanceof PsiForStatement + && element == ((PsiForStatement) element.getParent()).getUpdate()) { + continue; + } + //filter out generated stmts + final int endOffset = myFlow.getEndOffset(element); + if (endOffset != i + 1) continue; + final int startOffset = myFlow.getStartOffset(element); + // this offset actually is a part of reachable statement + if (0 <= startOffset && startOffset < processedInstructions.length && processedInstructions[startOffset]) continue; + return element; + } + } + return null; + } + } + + private static PsiReferenceExpression getEnclosingReferenceExpression(PsiElement element, PsiVariable variable) { + final PsiReferenceExpression reference = findReferenceTo(element, variable); + if (reference != null) return reference; + while (element != null) { + if (element instanceof PsiReferenceExpression) { + return (PsiReferenceExpression)element; + } + else if (element instanceof PsiMethod || element instanceof PsiClass) { + return null; + } + element = element.getParent(); + } + return null; + } + + private static PsiReferenceExpression findReferenceTo(PsiElement element, PsiVariable variable) { + if (element instanceof PsiReferenceExpression + && ((PsiReferenceExpression)element).resolve() == variable) { + return (PsiReferenceExpression)element; + } + final PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + final PsiReferenceExpression reference = findReferenceTo(child, variable); + if (reference != null) return reference; + } + return null; + } + + + public static boolean isVariableDefinitelyAssigned(final PsiVariable variable, final ControlFlow flow) { + class MyVisitor extends InstructionClientVisitor { + // true if from this point below there may be branch with no variable assignment + boolean[] maybeUnassigned = new boolean[flow.getSize() + 1]; + + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + if (instruction.variable == variable) { + maybeUnassigned[offset] = false; + } + else { + visitInstruction(instruction, offset, nextOffset); + } + } + + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + for (int i = instruction.procBegin; i flow.getSize()) nextOffset = flow.getSize(); + if (instruction.offset == nextOffset) { + boolean unassigned = !isLeaf(nextOffset) && maybeUnassigned[nextOffset]; + maybeUnassigned[offset] |= unassigned; + } + else { + visitInstruction(instruction, offset, nextOffset); + } + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean unassigned = !isLeaf(nextOffset) && maybeUnassigned[nextOffset]; + maybeUnassigned[offset] |= unassigned; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + + boolean unassigned = isLeaf(nextOffset) || maybeUnassigned[nextOffset]; + maybeUnassigned[offset] |= unassigned; + } + + public Boolean getResult() { + return Boolean.valueOf(!maybeUnassigned[0]); + } + } + if (flow.getSize() == 0) return false; + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor); + return visitor.getResult().booleanValue(); + } + + public static boolean isVariableDefinitelyNotAssigned(final PsiVariable variable, final ControlFlow flow) { + class MyVisitor extends InstructionClientVisitor { + // true if from this point below there may be branch with variable assignment + boolean[] maybeAssigned = new boolean[flow.getSize() + 1]; + + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean assigned; + if (instruction.variable == variable) { + assigned = true; + } + else { + assigned = maybeAssigned[nextOffset]; + } + maybeAssigned[offset] |= assigned; + } + + public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + boolean assigned = !isLeaf(nextOffset) && maybeAssigned[nextOffset]; + maybeAssigned[offset] |= assigned; + } + + public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + int throwToOffset = instruction.offset; + boolean assigned = throwToOffset == nextOffset ? !isLeaf(nextOffset) && maybeAssigned[nextOffset] : + maybeAssigned[nextOffset]; + maybeAssigned[offset] |= assigned; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + + boolean assigned = maybeAssigned[nextOffset]; + + maybeAssigned[offset] |= assigned; + } + + public Boolean getResult() { + return Boolean.valueOf(!maybeAssigned[0]); + } + } + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor); + return visitor.getResult().booleanValue(); + } + + /** + * @return min offset after sourceOffset which is definitely reachable from all references + */ + public static int getMinDefinitelyReachedOffset(final ControlFlow flow, final int sourceOffset, + final List references) { + class MyVisitor extends InstructionClientVisitor { + // set of exit posint reached from this offset + TIntHashSet[] exitPoints = new TIntHashSet[flow.getSize()]; + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + + if (exitPoints[offset] == null) { + exitPoints[offset] = new TIntHashSet(); + } + if (isLeaf(nextOffset)) { + exitPoints[offset].add(offset); + } + else { + exitPoints[offset].addAll(exitPoints[nextOffset].toArray()); + } + } + + public Integer getResult() { + int minOffset = flow.getSize(); + int maxExitPoints = 0; + nextOffset: + for (int i = sourceOffset; i < exitPoints.length; i++) { + TIntHashSet exitPointSet = exitPoints[i]; + final int size = exitPointSet == null ? 0 : exitPointSet.size(); + if (size > maxExitPoints) { + // this offset should be reachable from all other references + for (int j = 0; j < references.size(); j++) { + PsiElement element = (PsiElement)references.get(j); + final PsiElement statement = PsiUtil.getEnclosingStatement(element); + if (statement == null) continue; + final int endOffset = flow.getEndOffset(statement); + if (endOffset == -1) continue; + if (i != endOffset && !isInstructionReachable(flow, i, endOffset)) continue nextOffset; + } + minOffset = i; + maxExitPoints = size; + } + } + return new Integer(minOffset); + } + } + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor); + return visitor.getResult().intValue(); + } + + private static void depthFirstSearch(ControlFlow flow, InstructionClientVisitor visitor) { + visitor.processedInstructions = new boolean[flow.getSize()]; + internalDepthFirstSearch(flow.getInstructions(), visitor, 0, visitor.processedInstructions.length); + } + + private static void depthFirstSearch(ControlFlow flow, InstructionClientVisitor visitor, int startOffset, int endOffset) { + visitor.processedInstructions = new boolean[endOffset]; + internalDepthFirstSearch(flow.getInstructions(), visitor, startOffset, endOffset); + } + + private static void internalDepthFirstSearch(final Instruction[] instructions, final InstructionClientVisitor clientVisitor, int offset, int endOffset) { + final IntArrayList oldOffsets = new IntArrayList(instructions.length / 2); + final IntArrayList newOffsets = new IntArrayList(instructions.length / 2); + final IntArrayList currentProcedureReturnOffsets = new IntArrayList(); + + ControlFlowInstructionVisitor getNextOffsetVisitor = new ControlFlowInstructionVisitor() { + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + instruction.execute(offset + 1); + int newOffset = instruction.offset; + // 'procedure' pointed by call instruction should be processed regardless of whether it was already visited or not + // clear procedure text and return instructions aftewards + for (int i = instruction.procBegin; i < instruction.procEnd || instructions[i] instanceof ReturnInstruction; i++) { + clientVisitor.processedInstructions[i] = false; + } + oldOffsets.add(offset); + newOffsets.add(newOffset); + + oldOffsets.add(newOffset); + newOffsets.add(-1); + + currentProcedureReturnOffsets.add(offset + 1); + } + + public void visitReturnInstruction(ReturnInstruction instruction, int offset, int nextOffset) { + int newOffset = instruction.execute(false); + if (newOffset != -1) { + oldOffsets.add(offset); + newOffsets.add(newOffset); + + oldOffsets.add(newOffset); + newOffsets.add(-1); + } + } + + public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { + int newOffset = instruction.offset; + oldOffsets.add(offset); + newOffsets.add(newOffset); + + oldOffsets.add(newOffset); + newOffsets.add(-1); + } + + public void visitConditionalBranchingInstruction(ConditionalBranchingInstruction instruction, int offset, int nextOffset) { + int newOffset = instruction.offset; + + oldOffsets.add(offset); + newOffsets.add(newOffset); + + oldOffsets.add(offset); + newOffsets.add(offset + 1); + + oldOffsets.add(newOffset); + newOffsets.add(-1); + + oldOffsets.add(offset + 1); + newOffsets.add(-1); + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + int newOffset = offset + 1; + oldOffsets.add(offset); + newOffsets.add(newOffset); + + oldOffsets.add(newOffset); + newOffsets.add(-1); + } + }; + + oldOffsets.add(offset); + newOffsets.add(-1); + + while (oldOffsets.size() != 0) { + offset = oldOffsets.remove(oldOffsets.size() - 1); + int newOffset = newOffsets.remove(newOffsets.size() - 1); + + if (offset >= endOffset) { + continue; + } + Instruction instruction = instructions[offset]; + + if (clientVisitor.processedInstructions[offset]) { + if (newOffset != -1) { + instruction.accept(clientVisitor, offset, newOffset); + } + // when traversing call instruction, we have traversed all procedure control flows, so pop return address + if (currentProcedureReturnOffsets.size() != 0 && currentProcedureReturnOffsets.get(currentProcedureReturnOffsets.size() - 1) - 1 == offset) { + currentProcedureReturnOffsets.remove(currentProcedureReturnOffsets.size() - 1); + } + continue; + } + if (currentProcedureReturnOffsets.size() != 0) { + int returnOffset = currentProcedureReturnOffsets.get(currentProcedureReturnOffsets.size() - 1); + CallInstruction callInstruction = (CallInstruction) instructions[returnOffset - 1]; + // check if we inside procedure but 'return offset' stack is empty, so + // we should push back to 'return offset' stack + if (callInstruction.procBegin <= offset && offset < callInstruction.procEnd + 2 + && (callInstruction.stack.size() == 0 || callInstruction.stack.peekReturnOffset() != returnOffset)) { + callInstruction.stack.push(returnOffset, callInstruction); + } + } + + clientVisitor.processedInstructions[offset] = true; + instruction.accept(getNextOffsetVisitor, offset, newOffset); + } + } + + private static boolean isInsideReturnStatement(PsiElement element) { + while (element instanceof PsiExpression) element = element.getParent(); + return element instanceof PsiReturnStatement; + } + + private static class CopyOnWriteList { + List original; + List list; + + public CopyOnWriteList add(VariableInfo value) { + CopyOnWriteList newList = new CopyOnWriteList(); + List list = getList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + if (!value.equals(variableInfo)) { + newList.list.add(variableInfo); + } + } + newList.list.add(value); + return newList; + } + public CopyOnWriteList remove(VariableInfo value) { + CopyOnWriteList newList = new CopyOnWriteList(); + List list = getList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + if (!value.equals(variableInfo)) { + newList.list.add(variableInfo); + } + } + return newList; + } + + public List getList() { + return original == null ? list : original; + } + + public CopyOnWriteList(List original) { + this.original = original; + } + public CopyOnWriteList() { + list = new LinkedList(); + } + public CopyOnWriteList addAll(CopyOnWriteList addList) { + CopyOnWriteList newList = new CopyOnWriteList(); + List list = getList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + newList.list.add(variableInfo); + } + List toAdd = addList.getList(); + for (Iterator iterator = toAdd.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + if (!newList.list.contains(variableInfo)) { + // no copy + newList.list.add(variableInfo); + } + } + return newList; + } + } + private static class VariableInfo { + private final PsiVariable variable; + private final PsiElement expression; + + private VariableInfo(PsiVariable variable, PsiElement expression) { + this.variable = variable; + this.expression = expression; + } + + public VariableInfo(VariableInfo variableInfo) { + this(variableInfo.variable, variableInfo.expression); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof VariableInfo)) return false; + return variable.equals(((VariableInfo)o).variable); + } + + public int hashCode() { + return variable.hashCode(); + } + } + private static void merge(int offset, CopyOnWriteList readVars, CopyOnWriteList[] readVariables) { + if (readVars != null) { + CopyOnWriteList existing = readVariables[offset]; + readVariables[offset] = existing == null ? readVars : existing.addAll(readVars); + } + } + /** + * @return list of PsiReferenceExpression of usages of non-initialized variables + */ + public static List getReadBeforeWrite(final ControlFlow flow) { + InstructionClientVisitor> visitor = new ReadBeforeWriteClientVisitor(flow); + depthFirstSearch(flow, visitor); + return visitor.getResult(); + } + private static class ReadBeforeWriteClientVisitor extends InstructionClientVisitor> { + // map of variable->PsiReferenceExpressions for all read before written variables for this point and below in control flow + private final CopyOnWriteList[] readVariables; + private final ControlFlow myFlow; + + public ReadBeforeWriteClientVisitor(ControlFlow flow) { + myFlow = flow; + readVariables = new CopyOnWriteList[myFlow.getSize()+1]; + } + + public void visitReadVariableInstruction(ReadVariableInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + CopyOnWriteList readVars = readVariables[nextOffset]; + PsiElement element = myFlow.getElement(offset); + final PsiVariable variable = instruction.variable; + if (!(variable instanceof PsiParameter)) { + PsiReferenceExpression expression = getEnclosingReferenceExpression(element, variable); + if (expression != null) { + VariableInfo variableInfo = new VariableInfo(variable, expression); + if (readVars == null) { + readVars = new CopyOnWriteList(); + readVars.list.add(variableInfo); + } + else { + readVars = readVars.add(variableInfo); + } + } + } + merge(offset, readVars, readVariables); + } + + public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + CopyOnWriteList readVars = readVariables[nextOffset]; + final PsiVariable variable = instruction.variable; + if (!(variable instanceof PsiParameter) && readVars != null) { + readVars = readVars.remove(new VariableInfo(variable, null)); + } + merge(offset, readVars, readVariables); + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + CopyOnWriteList readVars = readVariables[nextOffset]; + merge(offset, readVars, readVariables); + } + + public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { + visitInstruction(instruction, offset, nextOffset); + for (int i = instruction.procBegin; i <= instruction.procEnd; i++) { + readVariables[i] = null; + } + } + + public List getResult() { + List problemsFound = new ArrayList(); + CopyOnWriteList topReadVariables = readVariables[0]; + if (topReadVariables != null) { + List list = topReadVariables.getList(); + for (int i = 0; i < list.size(); i++) { + final VariableInfo variableInfo = list.get(i); + problemsFound.add((PsiReferenceExpression)variableInfo.expression); + } + } + return problemsFound; + } + } + + public static final int NORMAL_COMPLETION_REASON = 1; + public static final int RETURN_COMPLETION_REASON = 2; + /** + * return reasons.normalCompletion when block can complete normally + * reasons.returnCalled when block can complete abruptly because of return statement executed + */ + public static int getCompletionReasons(final ControlFlow flow, final int offset, final int endOffset) { + class MyVisitor extends InstructionClientVisitor { + boolean[] normalCompletion = new boolean[endOffset]; + boolean[] returnCalled = new boolean[endOffset]; + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + boolean ret = nextOffset < endOffset ? returnCalled[nextOffset] : false; + boolean normal = nextOffset < endOffset ? normalCompletion[nextOffset] : false; + final PsiElement element = flow.getElement(offset); + boolean goToReturn = instruction instanceof GoToInstruction && ((GoToInstruction)instruction).isReturn; + boolean condGoToReturn = instruction instanceof ConditionalGoToInstruction && ((ConditionalGoToInstruction)instruction).isReturn; + if (goToReturn || condGoToReturn || isInsideReturnStatement(element)) { + ret = true; + } + else if (instruction instanceof ConditionalThrowToInstruction) { + final int throwOffset = ((ConditionalThrowToInstruction)instruction).offset; + boolean normalWhenThrow = throwOffset < endOffset && normalCompletion[throwOffset]; + boolean normalWhenNotThrow = offset == endOffset - 1 || normalCompletion[offset + 1]; + normal = normalWhenThrow || normalWhenNotThrow; + } + else if (!(instruction instanceof ThrowToInstruction) && nextOffset >= endOffset) { + normal = true; + } + returnCalled[offset] |= ret; + normalCompletion[offset] |= normal; + } + + public Integer getResult() { + return new Integer((returnCalled[offset] ? RETURN_COMPLETION_REASON : 0) | (normalCompletion[offset] ? NORMAL_COMPLETION_REASON : 0)); + } + } + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor, offset, endOffset); + + return visitor.getResult().intValue(); + } + + public static List getInitializedTwice(final ControlFlow flow) { + InstructionClientVisitor> visitor = new InitializedTwiceClientVisitor(flow); + depthFirstSearch(flow, visitor); + return visitor.getResult(); + } + private static class InitializedTwiceClientVisitor extends InstructionClientVisitor> { + // map of variable->PsiReferenceExpressions for all read and not written variables for this point and below in control flow + private final CopyOnWriteList[] writtenVariables; + private final CopyOnWriteList[] writtenTwiceVariables; + private final ControlFlow myFlow; + + public InitializedTwiceClientVisitor(ControlFlow flow) { + myFlow = flow; + writtenVariables = new CopyOnWriteList[myFlow.getSize() + 1]; + writtenTwiceVariables = new CopyOnWriteList[myFlow.getSize() + 1]; + } + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset > myFlow.getSize()) nextOffset = myFlow.getSize(); + + CopyOnWriteList writeVars = writtenVariables[nextOffset]; + CopyOnWriteList writeTwiceVars = writtenTwiceVariables[nextOffset]; + if (instruction instanceof WriteVariableInstruction) { + final WriteVariableInstruction writeVariableInstruction = (WriteVariableInstruction)instruction; + final PsiVariable variable = writeVariableInstruction.variable; + final PsiElement element = myFlow.getElement(offset); + + PsiElement latestWriteVarExpression = null; + if (writeVars != null) { + List list = writeVars.getList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + if (variableInfo.variable == variable) { + latestWriteVarExpression = variableInfo.expression; + break; + } + } + } + if (latestWriteVarExpression == null) { + PsiElement expression = null; + if (element instanceof PsiAssignmentExpression + && ((PsiAssignmentExpression)element).getLExpression() instanceof PsiReferenceExpression) { + expression = ((PsiAssignmentExpression)element).getLExpression(); + } + else if (element instanceof PsiPostfixExpression) { + expression = ((PsiPostfixExpression)element).getOperand(); + } + else if (element instanceof PsiPrefixExpression) { + expression = ((PsiPrefixExpression)element).getOperand(); + } + else if (element instanceof PsiDeclarationStatement) { + //should not happen + expression = element; + } + if (writeVars == null) { + writeVars = new CopyOnWriteList(); + } + writeVars = writeVars.add(new VariableInfo(variable, expression)); + } + else { + if (writeTwiceVars == null) { + writeTwiceVars = new CopyOnWriteList(); + } + writeTwiceVars = writeTwiceVars.add(new VariableInfo(variable, latestWriteVarExpression)); + } + } + merge(offset, writeVars, writtenVariables); + merge(offset, writeTwiceVars, writtenTwiceVariables); + } + + public List getResult() { + List problemsFound = new ArrayList(); + CopyOnWriteList writtenTwiceVariable = writtenTwiceVariables[0]; + if (writtenTwiceVariable == null) return problemsFound; + List list = writtenTwiceVariable.getList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + final VariableInfo variableInfo = iterator.next(); + final PsiElement problem = variableInfo.expression; + if (!problemsFound.contains(problem)) problemsFound.add(problem); + } + return problemsFound; + } + } + + /** + * @return true if instruction at 'instructionOffset' is reachable from offset 'startOffset' + */ + public static boolean isInstructionReachable(final ControlFlow flow, final int instructionOffset, + final int startOffset) { + class MyVisitor extends InstructionClientVisitor { + boolean reachable; + + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (nextOffset == instructionOffset) reachable = true; + } + + public Boolean getResult() { + return Boolean.valueOf(reachable); + } + } + + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor, startOffset, flow.getSize()); + + return visitor.getResult().booleanValue(); + } + + public static boolean isVariableAssignedInLoop(PsiReferenceExpression expression, PsiElement resolved) { + if (!(expression.getParent() instanceof PsiAssignmentExpression) + || ((PsiAssignmentExpression)expression.getParent()).getLExpression() != expression) { + return false; + } + PsiExpression qualifier = expression.getQualifierExpression(); + if (qualifier != null && !(qualifier instanceof PsiThisExpression)) return false; + + if (!(resolved instanceof PsiVariable)) return false; + PsiVariable variable = (PsiVariable)resolved; + + final PsiElement codeBlock = PsiUtil.getVariableCodeBlock(variable, expression); + if (codeBlock == null) return false; + final ControlFlow flow; + try { + flow = ControlFlowFactory.getControlFlow(codeBlock, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return false; + } + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression.getParent(); + int startOffset = flow.getStartOffset(assignmentExpression); + if (startOffset == -1) return false; + return isInstructionReachable(flow, startOffset, startOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/EmptyInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/EmptyInstruction.java new file mode 100644 index 00000000000..9443d9bb434 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/EmptyInstruction.java @@ -0,0 +1,11 @@ +package com.intellij.psi.controlFlow; + +public class EmptyInstruction extends SimpleInstruction { + public String toString() { + return "EMPTY"; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitEmptyInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/GoToInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/GoToInstruction.java new file mode 100644 index 00000000000..021b133136e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/GoToInstruction.java @@ -0,0 +1,46 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; + +public class GoToInstruction extends BranchingInstruction { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.GoToInstruction"); + + public final int role; + public final boolean isReturn; //true if goto has been generated as a result of return statement + + public GoToInstruction(int offset) { + this(offset,ControlFlow.JUMP_ROLE_GOTO_END); + } + public GoToInstruction(int offset, int role) { + this (offset,role,false); + } + public GoToInstruction(int offset, int role, boolean isReturn) { + super(offset); + this.role = role; + this.isReturn = isReturn; + } + + public String toString() { + final String sRole; + if (role == ControlFlow.JUMP_ROLE_GOTO_ELSE) sRole = "[ELSE]"; + else if (role == ControlFlow.JUMP_ROLE_GOTO_THEN) sRole = "[THEN]"; + else if (role == ControlFlow.JUMP_ROLE_GOTO_END) sRole = "[END]"; + else { + LOG.assertTrue(false,"Unknown Role: "+role); + sRole = "???"; + } + + return "GOTO " + sRole + " " + offset + (isReturn ? " RETURN" : ""); + } + + public int nNext() { return 1; } + + public int getNext(int index, int no) { + LOG.assertTrue(no == 0); + return offset; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitGoToInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/Instruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/Instruction.java new file mode 100644 index 00000000000..55594714643 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/Instruction.java @@ -0,0 +1,9 @@ +package com.intellij.psi.controlFlow; + +public interface Instruction extends Cloneable { + Instruction clone(); + int nNext (); + int getNext (int index, int no); + + void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionBase.java new file mode 100644 index 00000000000..d5545c7409e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionBase.java @@ -0,0 +1,16 @@ +/** + * @author cdr + */ +package com.intellij.psi.controlFlow; + +public abstract class InstructionBase implements Instruction, Cloneable{ + public Instruction clone() { + try { + return (Instruction)super.clone(); + } + catch (CloneNotSupportedException e) { + return null; + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionClientVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionClientVisitor.java new file mode 100644 index 00000000000..8ca2a65b8f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/InstructionClientVisitor.java @@ -0,0 +1,11 @@ +package com.intellij.psi.controlFlow; + +abstract class InstructionClientVisitor extends ControlFlowInstructionVisitor { + public abstract T getResult(); + + protected final boolean isLeaf(int offset) { + return offset == processedInstructions.length; + } + + protected boolean[] processedInstructions; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java new file mode 100644 index 00000000000..23989355fb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java @@ -0,0 +1,44 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.*; + +public class LocalsControlFlowPolicy implements ControlFlowPolicy { + private final PsiElement myCodeFragment; + + public LocalsControlFlowPolicy(PsiElement codeFragment) { + myCodeFragment = codeFragment; + } + + public PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + if (refExpr.isQualified()) return null; + + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter){ + return checkCodeFragment(refElement); + } + else{ + return null; + } + } + + private PsiVariable checkCodeFragment(PsiElement refElement) { + PsiElement codeFragement; + if (refElement instanceof PsiParameter + && ((PsiParameter)refElement).getDeclarationScope() instanceof PsiMethod){ + codeFragement = ((PsiMethod)((PsiParameter)refElement).getDeclarationScope()).getBody(); + } + else{ + codeFragement = ControlFlowUtil.findCodeFragment(refElement); + } + if (!myCodeFragment.equals(codeFragement)) return null; + return (PsiVariable)refElement; + } + + public boolean isParameterAccepted(PsiParameter psiParameter) { + return checkCodeFragment(psiParameter) != null; + } + + public boolean isLocalVariableAccepted(PsiLocalVariable psiVariable) { + return checkCodeFragment(psiVariable) != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java new file mode 100644 index 00000000000..daac8516dc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java @@ -0,0 +1,41 @@ +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Aug 6, 2002 + * Time: 6:16:17 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.*; + +public class LocalsOrMyInstanceFieldsControlFlowPolicy implements ControlFlowPolicy { + private static final LocalsOrMyInstanceFieldsControlFlowPolicy INSTANCE = new LocalsOrMyInstanceFieldsControlFlowPolicy(); + + private LocalsOrMyInstanceFieldsControlFlowPolicy() { + } + + public PsiVariable getUsedVariable(PsiReferenceExpression refExpr) { + PsiExpression qualifier = refExpr.getQualifierExpression(); + if (qualifier == null || qualifier instanceof PsiThisExpression) { + PsiElement resolved = refExpr.resolve(); + if (!(resolved instanceof PsiVariable)) return null; + return (PsiVariable)resolved; + } + + return null; + } + + public boolean isParameterAccepted(PsiParameter psiParameter) { + return true; + } + + public boolean isLocalVariableAccepted(PsiLocalVariable psiVariable) { + return true; + } + + public static LocalsOrMyInstanceFieldsControlFlowPolicy getInstance() { + return INSTANCE; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReadVariableInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReadVariableInstruction.java new file mode 100644 index 00000000000..d76e6088175 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReadVariableInstruction.java @@ -0,0 +1,19 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.PsiVariable; + +public class ReadVariableInstruction extends SimpleInstruction { + public final PsiVariable variable; + + public ReadVariableInstruction(PsiVariable variable) { + this.variable = variable; + } + + public String toString() { + return "READ " + variable.getName(); + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitReadVariableInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReturnInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReturnInstruction.java new file mode 100644 index 00000000000..d1374f9feac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ReturnInstruction.java @@ -0,0 +1,84 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; + + +public class ReturnInstruction extends GoToInstruction { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ReturnInstruction"); + + public final ControlFlowStack stack; + private CallInstruction myCallInstruction; + + public ReturnInstruction(int offset, ControlFlowStack stack, CallInstruction callInstruction) { + super(offset, ControlFlow.JUMP_ROLE_GOTO_END, false); + this.stack = stack; + myCallInstruction = callInstruction; + } + + public String toString() { + return "RETURN FROM " + getProcBegin() + (offset == 0 ? "" : " TO "+offset); + } + + public int execute(boolean pushBack) { + int jumpTo = -1; + if (stack.size() != 0) { + jumpTo = stack.pop(pushBack); + } + if (offset != 0) { + jumpTo = offset; + } + return jumpTo; + } + + public int[] getPossibleReturnOffsets() { + return offset == 0 ? + new int[]{ + getProcBegin() - 5, // call normal + getProcBegin() - 3, // call return + getProcBegin() - 1, // call throw + } + : + new int[]{ + offset, // exit from middle of the finally + }; + + } + + public int getProcBegin() { + return myCallInstruction.procBegin; + } + + public int getProcEnd() { + return myCallInstruction.procEnd; + } + + public void setCallInstruction(CallInstruction callInstruction) { + myCallInstruction = callInstruction; + } + + + public int nNext() { return offset == 0 ? 3 : 1; } + + public int getNext(int index, int no) { + if (offset == 0) + switch (no) { + case 0: return getProcBegin() - 5; // call normal + case 1: return getProcBegin() - 3; // call return + case 2: return getProcBegin() - 1; // call throw + default: + LOG.assertTrue (false); + return -1; + } + else + switch (no) { + case 0: return offset; // call normal + default: + LOG.assertTrue (false); + return -1; + } + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitReturnInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/SimpleInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/SimpleInstruction.java new file mode 100644 index 00000000000..dc3d9673255 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/SimpleInstruction.java @@ -0,0 +1,21 @@ +/** + * @author cdr + */ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; + +public abstract class SimpleInstruction extends InstructionBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.SimpleInstruction"); + + public int nNext() { return 1; } + + public int getNext(int index, int no) { + LOG.assertTrue(no == 0); + return index + 1; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitSimpleInstruction(this, offset, nextOffset); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ThrowToInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ThrowToInstruction.java new file mode 100644 index 00000000000..a2ef0b0ae63 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/ThrowToInstruction.java @@ -0,0 +1,28 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.openapi.diagnostic.Logger; + + +public class ThrowToInstruction extends BranchingInstruction { + + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.controlFlow.ThrowToInstruction"); + + public ThrowToInstruction(int offset) { + super(offset); + } + + public String toString() { + return "THROW_TO " + offset; + } + + public int nNext() { return 1; } + + public int getNext(int index, int no) { + LOG.assertTrue(no == 0); + return offset; + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitThrowToInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/WriteVariableInstruction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/WriteVariableInstruction.java new file mode 100644 index 00000000000..3e1362aa898 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/controlFlow/WriteVariableInstruction.java @@ -0,0 +1,19 @@ +package com.intellij.psi.controlFlow; + +import com.intellij.psi.PsiVariable; + +public class WriteVariableInstruction extends SimpleInstruction { + public final PsiVariable variable; + + public WriteVariableInstruction(PsiVariable variable) { + this.variable = variable; + } + + public String toString() { + return "WRITE " + variable.getName(); + } + + public void accept(ControlFlowInstructionVisitor visitor, int offset, int nextOffset) { + visitor.visitWriteVariableInstruction(this, offset, nextOffset); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/AndFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/AndFilter.java new file mode 100644 index 00000000000..79b1e939595 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/AndFilter.java @@ -0,0 +1,82 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 19:11:46 + * To change this template use Options | File Templates. + */ +public class AndFilter implements ElementFilter{ + private List myFilters = new ArrayList(); + + public AndFilter(ElementFilter filter1, ElementFilter filter2){ + this(new ElementFilter[]{filter1, filter2}); + } + + public AndFilter(ElementFilter[] filters){ + for(int i = 0; i < filters.length; i++){ + addFilter(filters[i]); + } + } + + public void addFilter(ElementFilter filter){ + myFilters.add(filter); + } + + public List getFilters(){ + return myFilters; + } + + public boolean isAcceptable(Object element, PsiElement context){ + for(int i = 0; i < myFilters.size(); i++){ + final ElementFilter elementFilter = (ElementFilter) myFilters.get(i); + if(!elementFilter.isAcceptable(element, context)){ + return false; + } + } + return true; + } + + public boolean isClassAcceptable(Class elementClass){ + for(int i = 0; i < myFilters.size(); i++){ + final ElementFilter elementFilter = (ElementFilter) myFilters.get(i); + if(!elementFilter.isClassAcceptable(elementClass)){ + return false; + } + } + return true; + } + + public void readExternal(Element element) + throws InvalidDataException{ + myFilters = FilterUtil.readFilterGroup(element); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + String ret = "("; + Iterator iter = myFilters.iterator(); + while(iter.hasNext()){ + ret += iter.next(); + if(iter.hasNext()){ + ret += " & "; + } + } + ret += ")"; + return ret; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ClassFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ClassFilter.java new file mode 100644 index 00000000000..380572061eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ClassFilter.java @@ -0,0 +1,68 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 19:30:55 + * To change this template use Options | File Templates. + */ +public class ClassFilter implements ElementFilter{ + private Class myFilter; + private boolean myAcceptableFlag = true; + + public ClassFilter(Class filter){ + myFilter = filter; + } + + public ClassFilter(Class filter, boolean acceptableFlag){ + myFilter = filter; + myAcceptableFlag = acceptableFlag; + } + + + public void setClassFilter(Class filter){ + myFilter = filter; + } + + public Class getClassFilter(){ + return myFilter; + } + + public boolean isClassAcceptable(Class hintClass){ + return myAcceptableFlag ? myFilter.isAssignableFrom(hintClass) : !myFilter.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element == null){ + return false; + } + return myAcceptableFlag ? myFilter.isAssignableFrom(element.getClass()) : !myFilter.isAssignableFrom(element.getClass()); + } + + public void readExternal(Element element) + throws InvalidDataException{ + final String className = element.getTextTrim(); + try{ + myFilter = Class.forName(className); + } + catch(Exception e){ + throw new InvalidDataException("Invalid class name in class filter"); + } + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "class(" + myFilter.getName() + ")"; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ConstructorFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ConstructorFilter.java new file mode 100644 index 00000000000..6bafb70d823 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ConstructorFilter.java @@ -0,0 +1,39 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 21:22:31 + * To change this template use Options | File Templates. + */ +public class ConstructorFilter extends ClassFilter { + public ConstructorFilter(){ + super(PsiMethod.class); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiMethod){ + return ((PsiMethod)element).isConstructor(); + } + return false; + } + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "constructor"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContentFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContentFilter.java new file mode 100644 index 00000000000..f1e078caa2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContentFilter.java @@ -0,0 +1,33 @@ +package com.intellij.psi.filters; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.position.PositionElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 13.02.2003 + * Time: 12:17:49 + * To change this template use Options | File Templates. + */ +public class ContentFilter extends PositionElementFilter{ + public ContentFilter(ElementFilter filter){ + setFilter(filter); + } + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + PsiElement currentChild = ((PsiElement) element).getFirstChild(); + while(currentChild != null){ + if(getFilter().isAcceptable(currentChild, ((PsiElement) element))){ + return true; + } + currentChild = currentChild.getNextSibling(); + } + return false; + } + + public String toString(){ + return "content(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContextGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContextGetter.java new file mode 100644 index 00000000000..f8813a975d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ContextGetter.java @@ -0,0 +1,15 @@ +package com.intellij.psi.filters; + +import com.intellij.psi.PsiElement; +import com.intellij.codeInsight.completion.CompletionContext; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.03.2003 + * Time: 21:14:27 + * To change this template use Options | File Templates. + */ +public interface ContextGetter{ + Object[] get(final PsiElement context, CompletionContext completionContext); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementExtractorFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementExtractorFilter.java new file mode 100644 index 00000000000..7b8ea37ed32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementExtractorFilter.java @@ -0,0 +1,60 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.infos.CandidateInfo; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 17.07.2003 + * Time: 13:43:17 + * To change this template use Options | File Templates. + */ +public class ElementExtractorFilter implements ElementFilter{ + ElementFilter myFilter; + + public ElementExtractorFilter(){} + + public ElementExtractorFilter(ElementFilter filter){ + myFilter = filter; + } + + public void setFilter(ElementFilter filter){ + myFilter = filter; + } + + public ElementFilter getFilter(){ + return myFilter; + } + + public boolean isClassAcceptable(Class hintClass){ + return myFilter.isClassAcceptable(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof CandidateInfo) + return myFilter.isAcceptable(((CandidateInfo)element).getElement(), context); + else if(myFilter instanceof PsiElement) + return myFilter.isAcceptable(element, context); + return false; + } + + + public void readExternal(Element element) + throws InvalidDataException{ + myFilter = (ElementFilter)FilterUtil.readFilterGroup(element).get(0); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + + public String toString(){ + return getFilter().toString(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementFilter.java new file mode 100644 index 00000000000..53062579962 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ElementFilter.java @@ -0,0 +1,16 @@ +package com.intellij.psi.filters; + +import com.intellij.psi.PsiElement; +import com.intellij.openapi.util.JDOMExternalizable; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 19:10:27 + * To change this template use Options | File Templates. + */ +public interface ElementFilter{ + boolean isAcceptable(Object element, PsiElement context); + boolean isClassAcceptable(Class hintClass); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FalseFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FalseFilter.java new file mode 100644 index 00000000000..c676c62fcf2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FalseFilter.java @@ -0,0 +1,38 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 17:31:05 + * To change this template use Options | File Templates. + */ +public class FalseFilter + implements ElementFilter{ + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + public boolean isAcceptable(Object element, PsiElement context){ + return false; + } + + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "false"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FilterUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FilterUtil.java new file mode 100644 index 00000000000..71672cdd85d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/FilterUtil.java @@ -0,0 +1,200 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspToken; +import com.intellij.psi.filters.classes.AnyInnerFilter; +import com.intellij.psi.filters.classes.InheritorFilter; +import com.intellij.psi.filters.classes.InterfaceFilter; +import com.intellij.psi.filters.classes.ThisOrAnyInnerFilter; +import com.intellij.psi.filters.element.IsAccessibleFilter; +import com.intellij.psi.filters.element.ModifierFilter; +import com.intellij.psi.filters.element.PackageEqualsFilter; +import com.intellij.psi.filters.position.PreviousElementFilter; +import com.intellij.psi.filters.position.StartElementFilter; +import com.intellij.psi.util.PsiTreeUtil; +import org.jdom.Element; +import org.jdom.Namespace; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 17:45:45 + * To change this template use Options | File Templates. + */ +public class FilterUtil{ + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CompletionData"); + public static final Namespace FILTER_NS = Namespace.getNamespace("http://www.intellij.net/data/filter"); + + private static final Map ourRegisteredFilters = new HashMap(); + static{ + registerFilter("and", AndFilter.class); + registerFilter("or", OrFilter.class); + registerFilter("any-inner", AnyInnerFilter.class); + registerFilter("assignable", InheritorFilter.class); + registerFilter("class", ClassFilter.class); + registerFilter("constructor", AndFilter.class); + registerFilter("interface", InterfaceFilter.class); + registerFilter("accessible-class", IsAccessibleFilter.class); + registerFilter("modifiers", ModifierFilter.class); + registerFilter("not", NotFilter.class); + registerFilter("same-package", PackageEqualsFilter.class); + registerFilter("previous", PreviousElementFilter.class); + registerFilter("parent", ScopeFilter.class); + registerFilter("text", TextFilter.class); + registerFilter("first-classes", StartElementFilter.class); + registerFilter("this-or-any-inner", ThisOrAnyInnerFilter.class); + } + + static void registerFilter(String name, Class filterClass){ + ourRegisteredFilters.put(name, filterClass); + } + + public static ElementFilter readFilter(Element element) + throws UnknownFilterException{ + final String filterName = element.getName(); + + if(ourRegisteredFilters.containsKey(filterName)){ + + final ElementFilter filter; + try{ + filter = (ElementFilter)(ourRegisteredFilters.get(filterName)).newInstance(); + //filter.readExternal(element); + } + catch(InstantiationException e){ + throw new UnknownFilterException(filterName, e); + } + catch(IllegalAccessException e){ + throw new UnknownFilterException(filterName, e); + } + + return filter; + } + else{ + throw new UnknownFilterException(filterName); + } + } + + public static List readFilterGroup(Element element){ + final List list = new ArrayList(); + final Iterator filtersIterator = element.getChildren().iterator(); + while(filtersIterator.hasNext()){ + final Element current = (Element)filtersIterator.next(); + if(current.getNamespace().equals(FILTER_NS)){ + try{ + list.add(FilterUtil.readFilter(current)); + } + catch(UnknownFilterException ufe){ + LOG.error(ufe); + } + } + } + return list; + } + + public static final Class getClassByName(String shortName){ + final String[] packs = { + "", + "com.intellij.psi.", + "com.intellij.psi.jsp.", + "com.intellij.psi.xml.", + "com.intellij.aspects.psi." + }; + + for(int i = 0; i < packs.length; i++){ + final Class aClass = tryClass(packs[i] + shortName); + if(aClass != null){ + return aClass; + } + } + return null; + } + + private static Class tryClass(String name){ + try{ + return Class.forName(name); + } + catch(Exception e){ + return null; + } + } + + public static PsiType getTypeByElement(PsiElement element, PsiElement context){ + //if(!element.isValid()) return null; + if(element instanceof PsiType){ + return (PsiType)element; + } + if(element instanceof PsiClass){ + return element.getManager().getElementFactory().createType((PsiClass)element); + } + else if(element instanceof PsiMethod){ + return ((PsiMethod)element).getReturnType(); + } + else if(element instanceof PsiVariable){ + return ((PsiVariable)element).getType(); + } + else if(element instanceof PsiKeyword){ + if("class".equals(element.getText())){ + return PsiType.getJavaLangClass(element.getManager(), element.getResolveScope()); + } + else if("true".equals(element.getText()) || "false".equals(element.getText())){ + return PsiType.BOOLEAN; + } + else if("this".equals(element.getText())){ + PsiElement previousElement = getPreviousElement(context, false); + if(".".equals(previousElement.getText())){ + previousElement = getPreviousElement(previousElement, false); + final String className = previousElement.getText(); + PsiElement walker = context; + while(walker != null){ + if(walker instanceof PsiClass && !(walker instanceof PsiAnonymousClass)){ + if(className.equals(((PsiClass)walker).getName())) + return getTypeByElement(walker, context); + } + walker = walker.getContext(); + } + } + else{ + final PsiClass owner = PsiTreeUtil.getContextOfType(context, PsiClass.class, true); + return getTypeByElement(owner, context); + } + } + } + else if(element instanceof PsiExpression){ + return ((PsiExpression)element).getType(); + } + + return null; + } + + public static PsiElement searchNonSpaceNonCommentBack(PsiElement element) { + if(element == null) return null; + while (true) { + int offset = element.getTextRange().getStartOffset() - 1; + if (offset < 0) return null; + element = element.getContainingFile().findElementAt(offset); + if (element == null) return null; + if(element instanceof JspToken && ((JspToken)element).getTokenType() == JspToken.JSP_DIRECTIVE_WHITE_SPACE) continue; + if (!(element instanceof PsiWhiteSpace) && !(element instanceof PsiComment)) return element; + } + } + + public static final PsiElement getPreviousElement(final PsiElement element, boolean skipReference){ + PsiElement prev = element; + if(element != null){ + if(skipReference){ + prev = searchNonSpaceNonCommentBack(element); + while(prev != null && prev.getParent() instanceof PsiJavaCodeReferenceElement){ + prev = searchNonSpaceNonCommentBack(prev.getParent()); + } + } + else{ + prev = searchNonSpaceNonCommentBack(prev); + } + } + return prev; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/GeneratorFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/GeneratorFilter.java new file mode 100644 index 00000000000..1fb3e7b7ebd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/GeneratorFilter.java @@ -0,0 +1,93 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +import java.lang.ref.SoftReference; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.03.2003 + * Time: 19:55:15 + * To change this template use Options | File Templates. + */ +public class GeneratorFilter implements ElementFilter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.filters.GeneratorFilter"); + private ContextGetter myGetter; + private Class myFilterClass; + + public GeneratorFilter(Class filterClass, ContextGetter getter){ + myFilterClass = filterClass; + myGetter = getter; + } + + public boolean isClassAcceptable(Class hintClass){ + final ElementFilter filter = getFilter(); + if(filter != null){ + return filter.isClassAcceptable(hintClass); + } + return true; + } + + + private SoftReference myCachedElement = new SoftReference(null); + private SoftReference myCachedFilter = new SoftReference(null); + + private ElementFilter getFilter(){ + return (ElementFilter) myCachedFilter.get(); + } + + protected ElementFilter getFilter(PsiElement context){ + ElementFilter filter = (ElementFilter)myCachedFilter.get(); + if(myCachedElement.get() != context || filter == null){ + filter = generateFilter(context); + myCachedFilter = new SoftReference(filter); + myCachedElement = new SoftReference(context); + } + return filter; + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element == null) return false; + final ElementFilter filter = getFilter(context); + if(filter != null){ + return filter.isAcceptable(element, context); + } + return false; + } + + protected ElementFilter generateFilter(PsiElement context){ + try{ + final ElementFilter elementFilter = (ElementFilter) myFilterClass.newInstance(); + final Object[] initArgument = myGetter.get(context, null); + if(InitializableFilter.class.isAssignableFrom(myFilterClass) && initArgument != null){ + ((InitializableFilter)elementFilter).init(initArgument); + return elementFilter; + } + else{ + LOG.error("Filter initialization failed!"); + } + } + catch(InstantiationException e){ + LOG.error(e); + } + catch(IllegalAccessException e){ + LOG.error(e); + } + return null; + } + + public void readExternal(Element element) + throws InvalidDataException{ + throw new InvalidDataException("Not implemented yet!"); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/InitializableFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/InitializableFilter.java new file mode 100644 index 00000000000..6133b311aa0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/InitializableFilter.java @@ -0,0 +1,12 @@ +package com.intellij.psi.filters; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 22.04.2003 + * Time: 16:15:21 + * To change this template use Options | File Templates. + */ +public interface InitializableFilter extends ElementFilter{ + void init(Object[] fromGetter); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/NotFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/NotFilter.java new file mode 100644 index 00000000000..a8387a97b31 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/NotFilter.java @@ -0,0 +1,57 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 19:24:33 + * To change this template use Options | File Templates. + */ +public class NotFilter + implements ElementFilter{ + ElementFilter myFilter; + + public NotFilter(){} + + public NotFilter(ElementFilter filter){ + myFilter = filter; + } + + public void setFilter(ElementFilter filter){ + myFilter = filter; + } + + public ElementFilter getFilter(){ + return myFilter; + } + + public boolean isClassAcceptable(Class hintClass){ + return myFilter.isClassAcceptable(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + return !myFilter.isAcceptable(element, context); + } + + + public void readExternal(Element element) + throws InvalidDataException{ + myFilter = (ElementFilter)FilterUtil.readFilterGroup(element).get(0); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + + public String toString(){ + return "!" + getFilter(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/OrFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/OrFilter.java new file mode 100644 index 00000000000..6115a170b0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/OrFilter.java @@ -0,0 +1,91 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 19:23:44 + * To change this template use Options | File Templates. + */ + +public class OrFilter + implements ElementFilter{ + private List myFilters = new ArrayList(); + + public OrFilter(){} + + public OrFilter(ElementFilter[] filters){ + for(int i = 0; i < filters.length; i++){ + addFilter(filters[i]); + } + } + + public OrFilter(ElementFilter filter1, ElementFilter filter2){ + this(new ElementFilter[]{filter1, filter2}); + } + + public void addFilter(ElementFilter filter){ + myFilters.add(filter); + } + + public List getFilters(){ + return myFilters; + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(myFilters.isEmpty()) + return true; + for(int i = 0; i < myFilters.size(); i++){ + final ElementFilter elementFilter = (ElementFilter) myFilters.get(i); + if(elementFilter.isAcceptable(element, context)){ + return true; + } + } + return false; + } + + public boolean isClassAcceptable(Class elementClass){ + if(myFilters.isEmpty()) + return true; + for(int i = 0; i < myFilters.size(); i++){ + final ElementFilter elementFilter = (ElementFilter) myFilters.get(i); + if(elementFilter.isClassAcceptable(elementClass)){ + return true; + } + } + return false; + } + + public void readExternal(Element element) + throws InvalidDataException{ + myFilters = FilterUtil.readFilterGroup(element); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + + public String toString(){ + String ret = "("; + Iterator iter = myFilters.iterator(); + while(iter.hasNext()){ + ret += iter.next(); + if(iter.hasNext()){ + ret += " | "; + } + } + ret += ")"; + return ret; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ScopeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ScopeFilter.java new file mode 100644 index 00000000000..309184cedf5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/ScopeFilter.java @@ -0,0 +1,30 @@ +package com.intellij.psi.filters; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.position.PositionElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 13:38:10 + * To change this template use Options | File Templates. + */ +public class ScopeFilter extends PositionElementFilter{ + public ScopeFilter(){} + + public ScopeFilter(ElementFilter filter){ + setFilter(filter); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(context != null){ + return getFilter().isAcceptable(context, context); + } + return false; + } + + public String toString(){ + return "scope(" +getFilter()+")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TextFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TextFilter.java new file mode 100644 index 00000000000..6908167f5a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TextFilter.java @@ -0,0 +1,123 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.PsiType; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +import java.util.StringTokenizer; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 13:57:35 + * To change this template use Options | File Templates. + */ +public class TextFilter + implements ElementFilter, InitializableFilter{ + protected String[] myValue; + private boolean myCaseInsensitiveFlag = false; + + public TextFilter(){ + myValue = ArrayUtil.EMPTY_STRING_ARRAY; + } + public TextFilter(String value, boolean incensetiveFlag){ + myCaseInsensitiveFlag = incensetiveFlag; + myValue = new String[1]; + myValue[0] = value; + } + + public TextFilter(String value){ + myValue = new String[1]; + myValue[0] = value; + } + + public TextFilter(String[] values){ + myValue = values; + } + + public TextFilter(String value1, String value2){ + myValue = new String[2]; + myValue[0] = value1; + myValue[1] = value2; + } + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element != null) { + for(int i = 0; i < myValue.length; i++){ + final String value = myValue[i]; + if(value == null) + return true; + final String elementText = getTextByElement(element); + if(myCaseInsensitiveFlag){ + if(value.equalsIgnoreCase(elementText)) return true; + } + else{ + if(value.equals(elementText)) return true; + } + } + } + + return false; + } + + public void readExternal(Element element) + throws InvalidDataException{ + final StringTokenizer tok = new StringTokenizer(element.getTextTrim(), "|"); + int i = 0; + + myValue = new String[tok.countTokens()]; + while(tok.hasMoreTokens()){ + myValue[i++] = tok.nextToken().trim(); + } + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + String ret = "("; + for(int i = 0; i < myValue.length; i++){ + ret += myValue[i]; + if(i < myValue.length - 1){ + ret += " | "; + } + } + ret += ")"; + return ret; + } + + public void init(Object[] fromGetter){ + try{ + myValue = new String[fromGetter.length]; + System.arraycopy(fromGetter, 0, myValue, 0, fromGetter.length); + } + catch(ClassCastException cce){ + myValue = ArrayUtil.EMPTY_STRING_ARRAY; + } + } + + protected String getTextByElement(Object element){ + String elementValue = null; + if(element instanceof PsiNamedElement){ + elementValue = ((PsiNamedElement)element).getName(); + } + else if (element instanceof PsiType) { + elementValue = ((PsiType) element).getPresentableText(); + } + else if (element instanceof PsiElement) { + elementValue = ((PsiElement) element).getText(); + } + return elementValue; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TrueFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TrueFilter.java new file mode 100644 index 00000000000..ee10d944c15 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/TrueFilter.java @@ -0,0 +1,42 @@ +package com.intellij.psi.filters; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 17:31:05 + * To change this template use Options | File Templates. + */ +public class TrueFilter + implements ElementFilter{ + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + public boolean isAcceptable(Object element, PsiElement context){ + return true; + } + + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "true"; + } + + public static final ElementFilter INSTANCE = new TrueFilter(); + + private TrueFilter() {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnnotationTypeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnnotationTypeFilter.java new file mode 100644 index 00000000000..8840c247738 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnnotationTypeFilter.java @@ -0,0 +1,46 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 21:00:45 + * To change this template use Options | File Templates. + */ +public class AnnotationTypeFilter + implements ElementFilter{ + + protected boolean isClassAcceptable(PsiClass aClass){ + return aClass.isAnnotationType(); + } + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiClass){ + return ((PsiClass)element).isAnnotationType(); + } + return false; + } + + public String toString(){ + return "annotationType"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnyInnerFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnyInnerFilter.java new file mode 100644 index 00000000000..389cffd9094 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AnyInnerFilter.java @@ -0,0 +1,66 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.filters.*; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:37:26 + * To change this template use Options | File Templates. + */ +public class AnyInnerFilter extends ClassFilter{ + ElementFilter myFilter; + public AnyInnerFilter(){ + super(PsiClass.class); + } + + public AnyInnerFilter(ElementFilter filter){ + this(); + myFilter = filter; + } + + public ElementFilter getFilter(){ + return myFilter; + } + + public void setFilter(ElementFilter myFilter){ + this.myFilter = myFilter; + } + + public boolean isAcceptable(Object classElement, PsiElement place){ + if(classElement instanceof PsiClass){ + final PsiClass[] inners = ((PsiClass)classElement).getInnerClasses(); + for(int j = 0; j < inners.length; j++){ + final PsiClass inner = inners[j]; + if(inner.hasModifierProperty(PsiModifier.STATIC) + && PsiUtil.isAccessible(inner, place, null) + && myFilter.isAcceptable(inner, place)){ + return true; + } + } + } + return false; + } + + public void readExternal(Element element) + throws InvalidDataException{ + myFilter = (ElementFilter)FilterUtil.readFilterGroup(element).get(0); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "any-inner(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AssignableFromContextFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AssignableFromContextFilter.java new file mode 100644 index 00000000000..91a2852044c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/AssignableFromContextFilter.java @@ -0,0 +1,63 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.util.InheritanceUtil; +import org.jdom.Element; + +import java.lang.ref.SoftReference; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 04.02.2003 + * Time: 12:40:51 + * To change this template use Options | File Templates. + */ +public class AssignableFromContextFilter + implements ElementFilter{ + public AssignableFromContextFilter(){} + + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass); + } + + SoftReference myCurrentContext = new SoftReference(null); + SoftReference myCachedClass = new SoftReference(null); + public boolean isAcceptable(Object element, PsiElement context){ + if(myCurrentContext.get() != context){ + myCurrentContext = new SoftReference(context); + PsiElement cachedClass = context; + while(cachedClass != null && !(cachedClass instanceof PsiClass)) + cachedClass = cachedClass.getContext(); + myCachedClass = new SoftReference(cachedClass); + } + + + if(myCachedClass.get() instanceof PsiClass && element instanceof PsiClass){ + final String qualifiedName = ((PsiClass)myCachedClass.get()).getQualifiedName(); + return qualifiedName != null && (qualifiedName.equals(((PsiClass)element).getQualifiedName()) + || ((PsiClass)element).isInheritor((PsiClass)myCachedClass.get(), true)); + + } + return false; + } + + public String toString(){ + return "assignable-from-context"; + } +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableFilter.java new file mode 100644 index 00000000000..0667255aa4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableFilter.java @@ -0,0 +1,54 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +import java.lang.ref.SoftReference; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 26.03.2003 + * Time: 21:01:47 + * To change this template use Options | File Templates. + */ +public abstract class ClassAssignableFilter implements ElementFilter{ + protected String myClassName = null; + protected PsiClass myClass = null; + private SoftReference myCachedClass = new SoftReference(null); + + public abstract boolean isAcceptable(Object aClass, PsiElement context); + public abstract String toString(); + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass); + } + + + protected PsiClass getPsiClass(PsiManager manager, GlobalSearchScope scope){ + if(myClass != null){ + return myClass; + } + + if(myCachedClass.get() == null && manager != null){ + myCachedClass = new SoftReference(manager.findClass(myClassName, scope)); + } + return (PsiClass) myCachedClass.get(); + } + + public void readExternal(Element element) + throws InvalidDataException{ + myClassName = element.getTextTrim(); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableToFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableToFilter.java new file mode 100644 index 00000000000..2128fbdab95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ClassAssignableToFilter.java @@ -0,0 +1,39 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.InheritanceUtil; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 26.03.2003 + * Time: 21:02:40 + * To change this template use Options | File Templates. + */ +public class ClassAssignableToFilter extends ClassAssignableFilter{ + public ClassAssignableToFilter(String className){ + myClassName = className; + } + + public ClassAssignableToFilter(PsiClass psiClass){ + myClass = psiClass; + } + + public ClassAssignableToFilter(){} + + public boolean isAcceptable(Object aClass, PsiElement context){ + if(aClass instanceof PsiClass){ + PsiManager manager = ((PsiElement) aClass).getManager(); + final PsiClass psiClass = getPsiClass(manager, context.getResolveScope()); + return psiClass == aClass || ((PsiClass) aClass).isInheritor(psiClass, true); + } + return false; + } + + public String toString(){ + return "class-assignable-to(" + getPsiClass(null, null) + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/EnumFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/EnumFilter.java new file mode 100644 index 00000000000..af4edd0652d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/EnumFilter.java @@ -0,0 +1,39 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +public class EnumFilter + implements ElementFilter{ + + protected boolean isClassAcceptable(PsiClass aClass){ + return aClass.isEnum(); + } + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiClass){ + return ((PsiClass)element).isEnum(); + } + return false; + } + + public String toString(){ + return "enum"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/InterfaceFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/InterfaceFilter.java new file mode 100644 index 00000000000..bdb16226a88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/InterfaceFilter.java @@ -0,0 +1,46 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 21:00:45 + * To change this template use Options | File Templates. + */ +public class InterfaceFilter + implements ElementFilter{ + + protected boolean isClassAcceptable(PsiClass aClass){ + return aClass.isInterface(); + } + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiClass){ + return ((PsiClass)element).isInterface(); + } + return false; + } + + public String toString(){ + return "interface"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ThisOrAnyInnerFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ThisOrAnyInnerFilter.java new file mode 100644 index 00000000000..a680370be05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/classes/ThisOrAnyInnerFilter.java @@ -0,0 +1,26 @@ +package com.intellij.psi.filters.classes; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:49:29 + * To change this template use Options | File Templates. + */ +public class ThisOrAnyInnerFilter extends OrFilter{ + public ThisOrAnyInnerFilter(ElementFilter filter){ + super(filter, new AnyInnerFilter(filter)); + } + + public boolean isClassAcceptable(Class aClass){ + return PsiClass.class.isAssignableFrom(aClass); + } + + public String toString(){ + return "this-or-any-inner(" + getFilters().get(0).toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeDeclaredFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeDeclaredFilter.java new file mode 100644 index 00000000000..9544ed4d741 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeDeclaredFilter.java @@ -0,0 +1,70 @@ +package com.intellij.psi.filters.element; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiClass; +import com.intellij.psi.util.*; +import com.intellij.psi.filters.position.PositionElementFilter; +import com.intellij.psi.filters.ElementFilter; + +import java.lang.ref.SoftReference; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 26.02.2003 + * Time: 12:31:24 + * To change this template use Options | File Templates. + */ +public class ExcludeDeclaredFilter extends PositionElementFilter{ + public ExcludeDeclaredFilter(ElementFilter filter){ + setFilter(filter); + } + + public ExcludeDeclaredFilter(){ + } + + public boolean isClassAcceptable(Class hintClass){ + return true; + //return PsiVariable.class.isAssignableFrom(hintClass); + } + + SoftReference myCachedVar = new SoftReference(null); + SoftReference myCurrentContext = new SoftReference(null); + + public boolean isAcceptable(Object element, PsiElement context){ + PsiElement cachedVar = context; + + if(myCurrentContext.get() != context){ + myCurrentContext = new SoftReference(context); + while(cachedVar != null && !(getFilter().isAcceptable(cachedVar, cachedVar.getContext()))) + cachedVar = cachedVar.getContext(); + myCachedVar = new SoftReference(cachedVar); + } + + if (element instanceof PsiMethod && myCachedVar.get() instanceof PsiMethod) { + final PsiMethod currentMethod = (PsiMethod) element; + final PsiMethod candidate = (PsiMethod) myCachedVar.get(); + return !candidate.getManager().areElementsEquivalent(candidate, currentMethod) && !isOverridingMethod(currentMethod, candidate); + } + else if(element instanceof PsiClassType){ + final PsiClass psiClass = ((PsiClassType)element).resolve(); + return isAcceptable(psiClass, context); + } + else if(context != null){ + if(element instanceof PsiElement) + return !context.getManager().areElementsEquivalent(myCachedVar.get(), (PsiElement)element); + return true; + } + return true; + } + + //TODO check exotic conditions like overriding method in package local class from class in other package + private static boolean isOverridingMethod(final PsiMethod method, final PsiMethod candidate) { + if (method.getManager().areElementsEquivalent(method, candidate)) return false; + if (!MethodSignatureUtil.areSignaturesEqual(method,candidate)) return false; + final PsiClass candidateContainingClass = candidate.getContainingClass(); + return candidateContainingClass.isInheritor(method.getContainingClass(), true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeSillyAssignment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeSillyAssignment.java new file mode 100644 index 00000000000..7585068303e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ExcludeSillyAssignment.java @@ -0,0 +1,32 @@ +package com.intellij.psi.filters.element; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.PsiReference; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 06.01.2004 + * Time: 17:59:58 + * To change this template use Options | File Templates. + */ +public class ExcludeSillyAssignment implements ElementFilter { + public boolean isAcceptable(Object element, PsiElement context) { + if(!(element instanceof PsiElement)) return true; + final PsiElement previousElement = FilterUtil.getPreviousElement(context, false); + if(previousElement==null || !"=".equals(previousElement.getText())) return true; + final PsiElement id = FilterUtil.getPreviousElement(previousElement, false); + if(id instanceof PsiIdentifier && id.getParent() instanceof PsiReference){ + final PsiElement resolve = ((PsiReference)id.getParent()).resolve(); + if(resolve != null && context.getManager().areElementsEquivalent((PsiElement)element, resolve)) return false; + } + return true; + } + + public boolean isClassAcceptable(Class hintClass) { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ModifierFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ModifierFilter.java new file mode 100644 index 00000000000..ab6165f9204 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ModifierFilter.java @@ -0,0 +1,104 @@ +package com.intellij.psi.filters.element; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifierList; +import com.intellij.psi.PsiModifierListOwner; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.filters.FilterUtil; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:29:25 + * To change this template use Options | File Templates. + */ +public class ModifierFilter extends ClassFilter{ + public List myModifierRestrictions = new ArrayList(); + + public ModifierFilter(){ + super(PsiModifierListOwner.class); + } + + public ModifierFilter(String modifier, boolean hasToBe){ + this(); + addModiferRestriction(modifier, hasToBe); + } + + public ModifierFilter(String[] modifiers){ + this(); + for(int i = 0; i < modifiers.length; i++){ + final String modifier = modifiers[i]; + addModiferRestriction(modifier, true); + } + } + + public void addModiferRestriction(String mod, boolean hasToBe){ + myModifierRestrictions.add(new ModifierRestriction(mod, hasToBe)); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiModifierListOwner){ + final PsiModifierList list = ((PsiModifierListOwner)element).getModifierList(); + if(list == null) return true; + final Iterator iter = myModifierRestrictions.iterator(); + while(iter.hasNext()){ + final ModifierRestriction psiModifer = (ModifierRestriction)iter.next(); + boolean shouldHave = psiModifer.myIsSet; + if(shouldHave != list.hasModifierProperty(psiModifer.myModifierName)) + return false; + } + return true; + } + return false; + } + + protected static final class ModifierRestriction{ + public String myModifierName; + public boolean myIsSet; + + ModifierRestriction(String modifierName, boolean isSet){ + myModifierName = modifierName; + myIsSet = isSet; + } + } + + public void readExternal(Element element) + throws InvalidDataException{ + final Iterator iter = element.getChildren("modifier", FilterUtil.FILTER_NS).iterator(); + + while(iter.hasNext()){ + final Element modifierElement = (Element) iter.next(); + final String attribute = modifierElement.getAttribute("is-set").getValue(); + myModifierRestrictions.add( + new ModifierRestriction(modifierElement.getTextTrim(), + attribute.equalsIgnoreCase("true"))); + } + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + String ret = "modifiers("; + Iterator iter = myModifierRestrictions.iterator(); + while(iter.hasNext()){ + final ModifierRestriction rest = (ModifierRestriction) iter.next(); + ret += rest.myModifierName + "=" + rest.myIsSet; + if(iter.hasNext()){ + ret += ", "; + } + } + ret += ")"; + return ret; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/PackageEqualsFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/PackageEqualsFilter.java new file mode 100644 index 00000000000..ae550a6eeb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/PackageEqualsFilter.java @@ -0,0 +1,61 @@ +package com.intellij.psi.filters.element; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 14:37:06 + * To change this template use Options | File Templates. + */ +public class PackageEqualsFilter + implements ElementFilter{ + + public boolean isClassAcceptable(Class hintClass){ + return PsiClass.class.isAssignableFrom(hintClass) + || PsiPackage.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if (!(element instanceof PsiElement)) return false; + final String elementPackName = getPackageName((PsiElement) element); + final String contextPackName = getPackageName(context); + if(elementPackName != null && contextPackName != null){ + return elementPackName.equals(contextPackName); + } + return false; + } + + protected String getPackageName(PsiElement element){ + if(element instanceof PsiPackage){ + return ((PsiPackage)element).getQualifiedName(); + } + if(element.getContainingFile() instanceof PsiJavaFile){ + return ((PsiJavaFile)element.getContainingFile()).getPackageName(); + } + return null; + } + + + public void readExternal(Element element) + throws InvalidDataException{ + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + + public String toString(){ + return "same-package"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ReferenceOnFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ReferenceOnFilter.java new file mode 100644 index 00000000000..0de87f62a80 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/element/ReferenceOnFilter.java @@ -0,0 +1,33 @@ +package com.intellij.psi.filters.element; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiJavaReference; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.position.PositionElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 07.02.2003 + * Time: 17:25:04 + * To change this template use Options | File Templates. + */ +public class ReferenceOnFilter extends PositionElementFilter{ + public ReferenceOnFilter(ElementFilter filter){ + setFilter(filter); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiJavaCodeReferenceElement.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if (!(element instanceof PsiElement)) return false; + PsiElement parent = ((PsiElement) element).getParent(); + if(parent instanceof PsiJavaCodeReferenceElement){ + return getFilter().isAcceptable((((PsiJavaReference)parent).advancedResolve(true)).getElement(), context); + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/AllClassesGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/AllClassesGetter.java new file mode 100644 index 00000000000..2b551bb38f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/AllClassesGetter.java @@ -0,0 +1,62 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ArrayUtil; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 02.12.2003 + * Time: 16:49:25 + * To change this template use Options | File Templates. + */ +public class AllClassesGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext) { + if(context == null || !context.isValid()) return ArrayUtil.EMPTY_OBJECT_ARRAY; + + final List classesList = new ArrayList(); + final PsiManager manager = context.getManager(); + final PsiShortNamesCache cache = manager.getShortNamesCache(); + // Optimization: + final String prefix = context.getUserData(CompletionUtil.COMPLETION_PREFIX); + final GlobalSearchScope scope = context.getContainingFile().getResolveScope(); + + final String[] names = cache.getAllClassNames(true); + for (int i = 0; i < names.length; i++) { + final String name = names[i]; + if(prefix != null && !CompletionUtil.checkName(name, prefix)) continue; + classesList.addAll(Arrays.asList(cache.getClassesByName(name, scope))); + } + + Collections.sort(classesList, new Comparator() { + public int compare(PsiClass psiClass, PsiClass psiClass1) { + if(manager.areElementsEquivalent(psiClass, psiClass1)) return 0; + + return getClassIndex(psiClass) - getClassIndex(psiClass1); + } + + private int getClassIndex(PsiClass psiClass){ + if(psiClass.getManager().isInProject(psiClass)) return 2; + final String qualifiedName = psiClass.getQualifiedName(); + if(qualifiedName.startsWith("java.") || qualifiedName.startsWith("javax.")) return 1; + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + }); + + return classesList.toArray(PsiClass.EMPTY_ARRAY); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/CastTypeGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/CastTypeGetter.java new file mode 100644 index 00000000000..9b440678f41 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/CastTypeGetter.java @@ -0,0 +1,29 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiTypeCastExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.codeInsight.completion.CompletionContext; + +import java.util.Set; +import java.util.HashSet; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.03.2003 + * Time: 21:29:59 + * To change this template use Options | File Templates. + */ +public class CastTypeGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext){ + final PsiTypeCastExpression cast = PsiTreeUtil.getContextOfType(context, PsiTypeCastExpression.class, true); + return new Object[]{cast.getCastType().getType()}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ExpectedTypesGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ExpectedTypesGetter.java new file mode 100644 index 00000000000..be2d27ce1cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ExpectedTypesGetter.java @@ -0,0 +1,68 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.codeInsight.*; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiNewExpression; +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 09.04.2003 + * Time: 12:37:26 + * To change this template use Options | File Templates. + */ +public class ExpectedTypesGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext){ + final List result = new ArrayList(); + final PsiExpression expression = PsiTreeUtil.getContextOfType(context, PsiExpression.class, true); + if(expression == null) return ArrayUtil.EMPTY_OBJECT_ARRAY; + + ExpectedTypesProvider typesProvider = ExpectedTypesProvider.getInstance(expression.getProject()); + ExpectedTypeInfo[] infos = typesProvider.getExpectedTypes(expression, true); + + infos = extractUnique(infos, typesProvider); + if (expression instanceof PsiNewExpression) { + for(int i = 0; i < infos.length; i++) { + result.add(CompletionUtil.eliminateWildcards(infos[i].getType())); + } + + } else { + for(int i = 0; i < infos.length; i++) { + result.add(infos[i].getType()); + } + } + return (PsiType[]) result.toArray(new PsiType[result.size()]); + } + + private ExpectedTypeInfo[] extractUnique(ExpectedTypeInfo[] infos, ExpectedTypesProvider typesProvider){ + ArrayList infoV = new ArrayList(); + AddInfosLoop: + for(int i = 0; i < infos.length; i++) { + ExpectedTypeInfo info = infos[i]; + PsiType type = info.getType(); + for(int j = 0; j < infoV.size(); j++) { + ExpectedTypeInfo info1 = (ExpectedTypeInfo)infoV.get(j); + PsiType type1 = info1.getType(); + if (type.equals(type1)){ //? + if (info.getTailType() != info1.getTailType()){ + infoV.set(j, typesProvider.createInfo(type1, info1.getKind(), info1.getDefaultType(), TailType.NONE)); + } + continue AddInfosLoop; + } + } + infoV.add(info); + } + infos = (ExpectedTypeInfo[])infoV.toArray(new ExpectedTypeInfo[infoV.size()]); + return infos; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/FilterGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/FilterGetter.java new file mode 100644 index 00000000000..e9daea20134 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/FilterGetter.java @@ -0,0 +1,38 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.PsiElement; +import com.intellij.codeInsight.completion.CompletionContext; + +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 15.04.2003 + * Time: 17:18:58 + * To change this template use Options | File Templates. + */ +public class FilterGetter implements ContextGetter{ + private ContextGetter myBaseGetter; + private ElementFilter myFilter; + + public FilterGetter(ContextGetter baseGetter, ElementFilter filter){ + myBaseGetter = baseGetter; + myFilter = filter; + } + + public Object[] get(PsiElement context, CompletionContext completionContext){ + final List results = new ArrayList(); + final Object[] elements = myBaseGetter.get(context, null); + for(int i = 0; i < elements.length; i++){ + final Object element = elements[i]; + if(myFilter.isClassAcceptable(element.getClass()) && myFilter.isAcceptable(element, context)){ + results.add(element); + } + } + return results.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/InstanceOfLeftPartTypeGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/InstanceOfLeftPartTypeGetter.java new file mode 100644 index 00000000000..02d8c5b9b1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/InstanceOfLeftPartTypeGetter.java @@ -0,0 +1,27 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.filters.FilterUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.codeInsight.completion.CompletionContext; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 15.12.2003 + * Time: 17:39:34 + * To change this template use Options | File Templates. + */ +public class InstanceOfLeftPartTypeGetter implements ContextGetter { + public Object[] get(PsiElement context, CompletionContext completionContext) { + if((context = FilterUtil.getPreviousElement((PsiElement) context, true)) == null) return ArrayUtil.EMPTY_OBJECT_ARRAY; + if(!PsiKeyword.INSTANCEOF.equals(context.getText())) return ArrayUtil.EMPTY_OBJECT_ARRAY; + if((context = FilterUtil.getPreviousElement((PsiElement) context, false)) == null) return ArrayUtil.EMPTY_OBJECT_ARRAY; + final PsiExpression contextOfType = PsiTreeUtil.getContextOfType(context, PsiExpression.class, false); + return new Object[]{contextOfType.getType()}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/MembersGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/MembersGetter.java new file mode 100644 index 00000000000..c70c05a68bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/MembersGetter.java @@ -0,0 +1,56 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.filters.TrueFilter; +import com.intellij.psi.*; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.codeInsight.completion.CompletionContext; + +import java.util.Set; +import java.util.HashSet; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 15.04.2003 + * Time: 17:07:09 + * To change this template use Options | File Templates. + */ +public class MembersGetter implements ContextGetter{ + private ContextGetter myBaseGetter; + + public MembersGetter(ContextGetter baseGetter){ + myBaseGetter = baseGetter; + } + + public Object[] get(PsiElement context, CompletionContext completionContext){ + final FilterScopeProcessor processor = new FilterScopeProcessor(TrueFilter.INSTANCE, context); + final Object[] elements = myBaseGetter.get(context, completionContext); + + for(int i = 0; i < elements.length; i++){ + final Object element = elements[i]; + final PsiClass psiClass; + + if(element instanceof PsiClass){ + psiClass = (PsiClass) context; + PsiScopesUtil.processScope(psiClass, processor, PsiSubstitutor.EMPTY, null, context); + } + else if(element instanceof PsiType){ + psiClass = PsiUtil.resolveClassInType((PsiType) element); + if(psiClass != null){ + PsiScopesUtil.processScope(psiClass, processor, PsiSubstitutor.EMPTY, null, context); + } + } + else{ + PsiScopesUtil.processScope((PsiElement)element, processor, PsiSubstitutor.EMPTY, null, context); + } + } + + final List results = processor.getResults(); + return (PsiElement[]) results.toArray(new PsiElement[results.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/TemplatesGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/TemplatesGetter.java new file mode 100644 index 00000000000..181b426b7dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/TemplatesGetter.java @@ -0,0 +1,44 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.CompletionContext; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.codeInsight.template.impl.TemplateContext; +import com.intellij.codeInsight.template.impl.TemplateSettings; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.04.2003 + * Time: 19:37:23 + * To change this template use Options | File Templates. + */ +public class TemplatesGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext){ + final List result = new ArrayList(); + final TemplateSettings templateSettings = TemplateSettings.getInstance(); + final TemplateImpl[] templates = templateSettings.getTemplates(); + + for (int i = 0; i < templates.length; i++) { + final TemplateImpl template = templates[i]; + if (template.isDeactivated()) continue; + + final TemplateContext templateContext = template.getTemplateContext(); + + if (!templateContext.isInContext(TemplateContext.COMPLETION_CONTEXT)) { + continue; + } + result.add(template); + } + + return result.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThisGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThisGetter.java new file mode 100644 index 00000000000..2e8295f62d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThisGetter.java @@ -0,0 +1,44 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.codeInsight.completion.CompletionContext; + +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 05.12.2003 + * Time: 14:02:59 + * To change this template use Options | File Templates. + */ +public class ThisGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext) { + boolean first = true; + final List expressions = new ArrayList(); + final PsiElementFactory factory = context.getManager().getElementFactory(); + + while(context != null){ + if(context instanceof PsiClass){ + final String expressionText; + if(first){ + first = false; + expressionText = "this"; + } + else expressionText = ((PsiClass)context).getName() + ".this"; + try{ + expressions.add(factory.createExpressionFromText(expressionText, context)); + } + catch(IncorrectOperationException ioe){} + } + if(context instanceof PsiModifierListOwner){ + if(((PsiModifierListOwner)context).hasModifierProperty(PsiModifier.STATIC)) break; + } + context = context.getContext(); + } + return expressions.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThrowsListGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThrowsListGetter.java new file mode 100644 index 00000000000..3cbf169fe54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/ThrowsListGetter.java @@ -0,0 +1,33 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.codeInsight.completion.CompletionContext; + +import java.util.Set; +import java.util.HashSet; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.03.2003 + * Time: 21:29:59 + * To change this template use Options | File Templates. + */ +public class ThrowsListGetter implements ContextGetter{ + public Object[] get(PsiElement context, CompletionContext completionContext){ + final Set throwsSet = new HashSet(); + final PsiMethod method = PsiTreeUtil.getContextOfType(context, PsiMethod.class, true); + if(method != null){ + final PsiClassType[] refs = method.getThrowsList().getReferencedTypes(); + for(int i = 0; i < refs.length; i++){ + final PsiClass exception = refs[i].resolve(); + if(exception != null) + throwsSet.add(exception); + } + } + return throwsSet.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/XmlAttributeValueGetter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/XmlAttributeValueGetter.java new file mode 100644 index 00000000000..cd1f74c4662 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/getters/XmlAttributeValueGetter.java @@ -0,0 +1,36 @@ +package com.intellij.psi.filters.getters; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ContextGetter; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.util.ArrayUtil; +import com.intellij.codeInsight.completion.CompletionContext; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 24.11.2003 + * Time: 14:17:59 + * To change this template use Options | File Templates. + */ +public class XmlAttributeValueGetter implements ContextGetter { + public XmlAttributeValueGetter() {} + + public Object[] get(PsiElement context, CompletionContext completionContext) { + if(context != null) + context = PsiTreeUtil.getParentOfType(context, XmlAttribute.class); + + if(context instanceof XmlAttribute){ + XmlAttributeDescriptor jspTagAttribute = ((XmlAttribute)context).getDescriptor(); + if(jspTagAttribute != null){ + final String[] values = jspTagAttribute.getEnumeratedValues(); + if(values == null) + return ArrayUtil.EMPTY_OBJECT_ARRAY; + return values; + } + } + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/AfterElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/AfterElementFilter.java new file mode 100644 index 00000000000..b07bd07a2bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/AfterElementFilter.java @@ -0,0 +1,39 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.position.PositionElementFilter; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 18:33:46 + * To change this template use Options | File Templates. + */ +public class AfterElementFilter extends PositionElementFilter{ + public AfterElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public AfterElementFilter(){} + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + PsiElement currentChild = getOwnerChild(scope, (PsiElement) element); + PsiElement currentElement = scope.getFirstChild(); + while(currentElement != null){ + if(currentElement == currentChild) + break; + if(getFilter().isAcceptable(currentElement, scope)){ + return true; + } + currentElement = currentElement.getNextSibling(); + } + return false; + } + + public String toString(){ + return "after(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/BeforeElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/BeforeElementFilter.java new file mode 100644 index 00000000000..cab94b74fb7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/BeforeElementFilter.java @@ -0,0 +1,36 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 18:29:13 + * To change this template use Options | File Templates. + */ +public class BeforeElementFilter extends PositionElementFilter{ + public BeforeElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public BeforeElementFilter(){} + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + final PsiElement ownerChild = getOwnerChild(scope, (PsiElement) element); + if(ownerChild == null) return false; + PsiElement currentChild = ownerChild.getNextSibling(); + while(currentChild != null){ + if(getFilter().isAcceptable(currentChild, scope)){ + return true; + } + currentChild = currentChild.getNextSibling(); + } + return false; + } + + public String toString(){ + return "before(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/InsideElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/InsideElementFilter.java new file mode 100644 index 00000000000..b0ce6e4e9eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/InsideElementFilter.java @@ -0,0 +1,30 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.position.PositionElementFilter; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 25.03.2003 + * Time: 12:11:40 + * To change this template use Options | File Templates. + */ +public class InsideElementFilter extends PositionElementFilter{ + public InsideElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public InsideElementFilter(){} + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + PsiElement currentChild = getOwnerChild(scope, (PsiElement) element); + return getFilter().isAcceptable(currentChild, scope); + } + + public String toString(){ + return "in(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/LeftNeighbour.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/LeftNeighbour.java new file mode 100644 index 00000000000..19c6ecda333 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/LeftNeighbour.java @@ -0,0 +1,34 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 06.02.2003 + * Time: 19:03:05 + * To change this template use Options | File Templates. + */ +public class LeftNeighbour extends PositionElementFilter{ + public LeftNeighbour(){} + + public LeftNeighbour(ElementFilter filter){ + setFilter(filter); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if (!(element instanceof PsiElement)) return false; + final PsiElement previous = FilterUtil.getPreviousElement((PsiElement) element, false); + if(previous != null){ + return getFilter().isAcceptable(previous, context); + } + return false; + } + + public String toString(){ + return "left(" +getFilter()+")"; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentElementFilter.java new file mode 100644 index 00000000000..a9994c9167f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentElementFilter.java @@ -0,0 +1,52 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 18:54:57 + * To change this template use Options | File Templates. + */ +public class ParentElementFilter extends PositionElementFilter{ + private PsiElement myParent = null; + private int myLevel = 1; + public ParentElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public ParentElementFilter(ElementFilter filter, int level) { + setFilter(filter); + myLevel = level; + } + + public ParentElementFilter(PsiElement parent){ + myParent = parent; + } + + + public ParentElementFilter(){} + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + PsiElement context = (PsiElement)element; + for(int i = 0; i < myLevel && context != null; i++){ + context = context.getContext(); + } + if(context != null){ + if(myParent == null){ + return getFilter().isAcceptable(context, scope); + } + return myParent == context; + } + return false; + } + + + public String toString(){ + return "parent(" +getFilter()+")"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentSkipReferenceElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentSkipReferenceElementFilter.java new file mode 100644 index 00000000000..9ac42e2d1a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/ParentSkipReferenceElementFilter.java @@ -0,0 +1,37 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 18:54:57 + * To change this template use Options | File Templates. + */ +public class ParentSkipReferenceElementFilter extends PositionElementFilter{ + public ParentSkipReferenceElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public ParentSkipReferenceElementFilter(){} + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + final PsiElement context = ((PsiElement)element).getContext(); + if(context != null){ + if(context instanceof PsiReference) + return isAcceptable(context, scope); + return getFilter().isAcceptable(context, scope); + } + return false; + } + + + public String toString(){ + return "parent(" +getFilter()+")"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PositionElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PositionElementFilter.java new file mode 100644 index 00000000000..4ebf7c3bca8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PositionElementFilter.java @@ -0,0 +1,49 @@ +package com.intellij.psi.filters.position; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 13:51:02 + * To change this template use Options | File Templates. + */ +public abstract class PositionElementFilter + implements ElementFilter{ + private ElementFilter myFilter; + + public void setFilter(ElementFilter filter){ + myFilter = filter; + } + + public ElementFilter getFilter(){ + return myFilter; + } + + public void readExternal(Element element) + throws InvalidDataException{ + myFilter = (ElementFilter)FilterUtil.readFilterGroup(element).get(0); + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + protected static final PsiElement getOwnerChild(final PsiElement scope, PsiElement element){ + while(element != null && element.getParent() != scope){ + element = element.getParent(); + } + return element; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PreviousElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PreviousElementFilter.java new file mode 100644 index 00000000000..d51ac22b66a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/PreviousElementFilter.java @@ -0,0 +1,32 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 13:48:00 + * To change this template use Options | File Templates. + */ +public class PreviousElementFilter extends PositionElementFilter{ + public PreviousElementFilter(){} + + public PreviousElementFilter(ElementFilter filter){ + setFilter(filter); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if (!(element instanceof PsiElement)) return false; + if((element = FilterUtil.getPreviousElement((PsiElement) element, true)) != null){ + return getFilter().isAcceptable(element, context); + } + return false; + } + + public String toString(){ + return "previous(" +getFilter()+")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/RootTagFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/RootTagFilter.java new file mode 100644 index 00000000000..48e411fb8b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/RootTagFilter.java @@ -0,0 +1,32 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.02.2003 + * Time: 18:29:13 + * To change this template use Options | File Templates. + */ +public class RootTagFilter extends PositionElementFilter{ + public RootTagFilter(ElementFilter filter){ + setFilter(filter); + } + + public RootTagFilter(){} + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof XmlDocument)) return false; + final XmlTag rootTag = ((XmlDocument)element).getRootTag(); + if(rootTag == null) return false; + + return getFilter().isAcceptable(rootTag, (PsiElement)element); + } + + public String toString(){ + return "roottag(" + getFilter().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/StartElementFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/StartElementFilter.java new file mode 100644 index 00000000000..b6b4a18275f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/StartElementFilter.java @@ -0,0 +1,28 @@ +package com.intellij.psi.filters.position; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.FilterUtil; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 30.01.2003 + * Time: 13:09:39 + * To change this template use Options | File Templates. + */ +public class StartElementFilter extends PositionElementFilter{ + public boolean isAcceptable(Object element, PsiElement context){ + if (!(element instanceof PsiElement)) return false; + return FilterUtil.getPreviousElement((PsiElement) element, false) == null; + } + + public void readExternal(Element element) + throws InvalidDataException{ + } + + public String toString(){ + return "start"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/SuperParentFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/SuperParentFilter.java new file mode 100644 index 00000000000..8a8c766cac7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/SuperParentFilter.java @@ -0,0 +1,33 @@ +package com.intellij.psi.filters.position; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 11.02.2003 + * Time: 13:54:33 + * To change this template use Options | File Templates. + */ +public class SuperParentFilter extends PositionElementFilter{ + public SuperParentFilter(ElementFilter filter){ + setFilter(filter); + } + + public SuperParentFilter(){} + + public boolean isAcceptable(Object element, PsiElement scope){ + if (!(element instanceof PsiElement)) return false; + while((element = ((PsiElement) element).getParent()) != null){ + if(getFilter().isAcceptable(element, scope)) + return true; + } + return false; + } + + + public String toString(){ + return "super-parent(" +getFilter()+")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/TokenTypeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/TokenTypeFilter.java new file mode 100644 index 00000000000..e1e4c33b5fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/position/TokenTypeFilter.java @@ -0,0 +1,72 @@ +package com.intellij.psi.filters.position; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.jsp.JspToken; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.javadoc.PsiDocToken; +import com.intellij.psi.filters.ElementFilter; +import org.jdom.Element; + +import java.lang.reflect.Field; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 10.03.2003 + * Time: 12:10:08 + * To change this template use Options | File Templates. + */ +public class TokenTypeFilter implements ElementFilter{ + private IElementType myType = null; + + public TokenTypeFilter(){} + + public TokenTypeFilter(IElementType type){ + myType = type; + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiDocToken.class.isAssignableFrom(hintClass) || XmlToken.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiDocToken) + return ((PsiDocToken)element).getTokenType() == myType; + else if(element instanceof XmlToken) + return ((XmlToken)element).getTokenType() == myType; + else if(element instanceof JspToken) + return ((JspToken)element).getTokenType() == myType; + + return false; + } + + public void readExternal(Element element) throws InvalidDataException{ + final String typeName = element.getText().trim(); + final Class tokenClass = PsiDocToken.class; + + try{ + final Field field = tokenClass.getField(typeName); + if(IElementType.class.isAssignableFrom(field.getType())){ + myType = (IElementType)field.get(null); + } + } + catch(NoSuchFieldException e){ + } + catch(SecurityException e){ + } + catch(IllegalAccessException e){ + } + } + + public void writeExternal(Element element) + throws WriteExternalException{ + throw new WriteExternalException("Filter data could _not_ be written"); + } + + public String toString(){ + return "token-type(" + myType + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ArrayTypeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ArrayTypeFilter.java new file mode 100644 index 00000000000..77ff5e1902e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ArrayTypeFilter.java @@ -0,0 +1,25 @@ +package com.intellij.psi.filters.types; + +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiArrayType; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 05.06.2003 + * Time: 16:31:39 + * To change this template use Options | File Templates. + */ +public class ArrayTypeFilter implements ElementFilter{ + public boolean isAcceptable(Object element, PsiElement context){ + return element instanceof PsiArrayType; + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiArrayType.class.isAssignableFrom(hintClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableFromFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableFromFilter.java new file mode 100644 index 00000000000..08e6c582e89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableFromFilter.java @@ -0,0 +1,74 @@ +package com.intellij.psi.filters.types; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.*; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; +import com.intellij.psi.infos.CandidateInfo; +import org.jdom.Element; + + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:53:38 + * To change this template use Options | File Templates. + */ +public class AssignableFromFilter implements ElementFilter{ + private PsiType myType; + + public AssignableFromFilter(PsiType type){ + myType = type; + } + + public AssignableFromFilter(){} + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element == null) return false; + if (element instanceof PsiType) return myType.isAssignableFrom((PsiType) element); + PsiSubstitutor substitutor = null; + if(element instanceof CandidateInfo){ + final CandidateInfo info = (CandidateInfo)element; + substitutor = info.getSubstitutor(); + element = info.getElement(); + } + + if(element instanceof PsiMethod){ + final PsiMethod method = (PsiMethod)element; + final PsiTypeParameterList list = method.getTypeParameterList(); + if(list != null && list.getTypeParameters().length > 0){ + final PsiTypeParameter[] parameters = list.getTypeParameters(); + for (int i = 0; i < parameters.length; i++) { + final PsiTypeParameter parameter = parameters[i]; + PsiType returnType = method.getReturnType(); + if(substitutor != null) returnType = substitutor.substitute(returnType); + final PsiType substitutionForParameter = method.getManager().getResolveHelper().getSubstitutionForTypeParameter(parameter, returnType, myType, false); + if(substitutionForParameter != PsiType.NULL){ + return true; + } + } + } + } + final PsiType typeByElement = FilterUtil.getTypeByElement((PsiElement)element, context); + if(substitutor != null) return myType.isAssignableFrom(substitutor.substitute(typeByElement)); + if(typeByElement == null) + return false; + return myType.isAssignableFrom(typeByElement); + } + + public void readExternal(Element element) throws InvalidDataException{ + } + + public void writeExternal(Element element) throws WriteExternalException{ + } + + public String toString(){ + return "assignable-from(" + myType + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableGroupFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableGroupFilter.java new file mode 100644 index 00000000000..32463cd9bb5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableGroupFilter.java @@ -0,0 +1,36 @@ +package com.intellij.psi.filters.types; + +import com.intellij.psi.filters.FalseFilter; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.filters.InitializableFilter; +import com.intellij.psi.filters.classes.InheritorFilter; +import com.intellij.psi.filters.element.AssignableFilter; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiType; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 20.03.2003 + * Time: 21:27:25 + * To change this template use Options | File Templates. + */ +public class AssignableGroupFilter extends OrFilter implements InitializableFilter{ + public AssignableGroupFilter(){} + + public AssignableGroupFilter(PsiClass[] classes){ + init(classes); + } + + public void init(Object[] classes){ + for(int i = 0; i < classes.length; i++){ + if (classes[i] instanceof PsiClass) { + addFilter(new InheritorFilter((PsiClass)classes[i])); + } + if (classes[i] instanceof PsiType) { + addFilter(new AssignableFromFilter((PsiType)classes[i])); + } + } + addFilter(new FalseFilter()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableToFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableToFilter.java new file mode 100644 index 00000000000..c3bb71e538f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/AssignableToFilter.java @@ -0,0 +1,93 @@ +package com.intellij.psi.filters.types; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.PsiType; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterUtil; +import com.intellij.psi.filters.InitializableFilter; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.infos.CandidateInfo; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:53:38 + * To change this template use Options | File Templates. + */ +public class AssignableToFilter implements InitializableFilter{ + private PsiType myType = null; + private ElementFilter myFilter = null; + + public AssignableToFilter(PsiType type){ + myType = type; + } + + public AssignableToFilter(){} + + public void init(Object[] type){ + myFilter = new OrFilter(); + final List filters = new ArrayList(); + for (int i = 0; i < type.length; i++) { + final Object o = type[i]; + PsiType currentType = null; + if(o instanceof PsiType) + currentType = (PsiType) o; + else if(o instanceof PsiClass){ + final PsiClass psiClass = (PsiClass)o; + currentType = psiClass.getManager().getElementFactory().createType(psiClass); + } + if(currentType != null){ + filters.add(new AssignableToFilter(currentType)); + } + } + myFilter = new OrFilter(filters.toArray(new ElementFilter[filters.size()])); + } + + public boolean isClassAcceptable(Class hintClass){ + return true; + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(myType != null){ + if(element == null) return false; + if (element instanceof PsiType) return myType.isAssignableFrom((PsiType) element); + PsiSubstitutor substitutor = null; + if(element instanceof CandidateInfo){ + final CandidateInfo info = (CandidateInfo)element; + substitutor = info.getSubstitutor(); + element = info.getElement(); + } + + PsiType typeByElement = FilterUtil.getTypeByElement((PsiElement)element, context); + if(substitutor != null) typeByElement = substitutor.substitute(typeByElement); + return typeByElement != null && typeByElement.isAssignableFrom(myType) && !typeByElement.equals(myType); + } + else if(myFilter != null){ + if(element == null) return false; + return myFilter.isAcceptable(element, context); + } + else return false; + } + + public void readExternal(Element element) throws InvalidDataException{ + } + + public void writeExternal(Element element) throws WriteExternalException{ + } + + public String toString(){ + if(myType != null) + return "assignable-to(" + myType + ")"; + else if(myFilter != null) return myFilter.toString(); + return "uninitialized-equals-filter"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ReturnTypeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ReturnTypeFilter.java new file mode 100644 index 00000000000..5b187d71cb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/ReturnTypeFilter.java @@ -0,0 +1,78 @@ +package com.intellij.psi.filters.types; + +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.*; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.util.IncorrectOperationException; +import org.jdom.Element; + + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 28.01.2003 + * Time: 20:05:52 + * To change this template use Options | File Templates. + */ +public class ReturnTypeFilter implements ElementFilter{ + private ElementFilter myFilter; + + public ReturnTypeFilter(ElementFilter filter){ + myFilter = filter; + } + public boolean isClassAcceptable(Class hintClass){ + return PsiVariable.class.isAssignableFrom(hintClass) + || PsiMethod.class.isAssignableFrom(hintClass) + || PsiExpression.class.isAssignableFrom(hintClass) + || Template.class.isAssignableFrom(hintClass) + || CandidateInfo.class.isAssignableFrom(hintClass); + + } + + public boolean isAcceptable(Object element, PsiElement context){ + PsiType type = null; + if(element instanceof TemplateImpl){ + final TemplateImpl template = (TemplateImpl) element; + String text = template.getTemplateText(); + StringBuffer resultingText = new StringBuffer(text); + + int segmentsCount = template.getSegmentsCount(); + + for (int j = segmentsCount - 1; j >= 0; j--) { + if (template.getSegmentName(j).equals("END")) { + continue; + } + + int segmentOffset = template.getSegmentOffset(j); + + resultingText.insert(segmentOffset, "xxx"); + } + + try { + final PsiExpression templateExpression = + context.getManager().getElementFactory().createExpressionFromText(resultingText.toString(), context); + type = templateExpression.getType(); + } + catch (IncorrectOperationException e) { // can happen when text of the template does not form an expression + } + if(type == null) return false; + } + + if(type != null){ + return myFilter.isAcceptable(type, context); + } + return myFilter.isAcceptable(element, context); + } + + public void readExternal(Element element) throws InvalidDataException{ + //myFilter.readExternal(element); + } + + public void writeExternal(Element element) throws WriteExternalException{ + //myFilter.writeExternal(element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeClassFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeClassFilter.java new file mode 100644 index 00000000000..3d161622db4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeClassFilter.java @@ -0,0 +1,48 @@ +package com.intellij.psi.filters.types; + +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.util.PsiUtil; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 17.04.2003 + * Time: 21:49:00 + * To change this template use Options | File Templates. + */ +public class TypeClassFilter implements ElementFilter{ + private final ElementFilter myFilter; + + public TypeClassFilter(ElementFilter _filter){ + myFilter = _filter; + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiType.class.isAssignableFrom(hintClass); + } + + public boolean isAcceptable(Object element, PsiElement context){ + if(element instanceof PsiType){ + final PsiType type = (PsiType) element; + if(type instanceof PsiClassType && PsiUtil.resolveClassInType(type) != null){ + final PsiClass psiClass = PsiUtil.resolveClassInType(type); + if(psiClass != null) + return myFilter.isAcceptable(psiClass, context); + } + } + return false; + } + + public void readExternal(Element element) throws InvalidDataException{ + } + + public void writeExternal(Element element) throws WriteExternalException{ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeCodeFragmentIsVoidEnabledFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeCodeFragmentIsVoidEnabledFilter.java new file mode 100644 index 00000000000..9b74bc98452 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeCodeFragmentIsVoidEnabledFilter.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.psi.filters.types; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiTypeCodeFragment; +import com.intellij.psi.filters.ElementFilter; + +/** + * @author dsl + */ +public class TypeCodeFragmentIsVoidEnabledFilter implements ElementFilter { + public boolean isAcceptable(Object element, PsiElement context) { + return context instanceof PsiTypeCodeFragment && + ((PsiTypeCodeFragment)context).isVoidValid(); + } + + + public boolean isClassAcceptable(Class hintClass) { + return hintClass.isAssignableFrom(PsiTypeCodeFragment.class); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeFilter.java new file mode 100644 index 00000000000..e2ac9ee038d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/filters/types/TypeFilter.java @@ -0,0 +1,28 @@ +package com.intellij.psi.filters.types; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.filters.ElementFilter; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.08.2003 + * Time: 17:54:00 + * To change this template use Options | File Templates. + */ +public class TypeFilter implements ElementFilter{ + private Object myType; + + public TypeFilter(Object type){ + myType = type; + } + + public boolean isAcceptable(Object element, PsiElement context){ + return ((PsiType)element).equals(myType); + } + + public boolean isClassAcceptable(Class hintClass){ + return PsiType.class.isAssignableFrom(hintClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValueImpl.java new file mode 100644 index 00000000000..ede9928c389 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValueImpl.java @@ -0,0 +1,173 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jun 6, 2002 + * Time: 5:41:42 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.impl; + +import com.intellij.j2ee.j2eeDom.J2EEModuleProperties; +import com.intellij.j2ee.j2eeDom.VerificationException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.ModificationTracker; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.PsiModificationTracker; +import gnu.trove.TLongArrayList; + +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.ArrayList; +import java.util.List; + +public class CachedValueImpl implements CachedValue { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.CachedValueImpl"); + + private final PsiManager myManager; + private final CachedValueProvider myProvider; + private boolean myComputed = false; + private boolean myTrackValue = true; + private SoftReference myValue = null; + private Object[] myDependencies = null; + private long[] myTimeStamps; + private long myLastPsiTimeStamp = -1; + + public CachedValueImpl(PsiManager manager, CachedValueProvider provider, boolean trackValue) { + myManager = manager; + myProvider = provider; + myTrackValue = trackValue; + } + + public void releaseValueIfOutdated() { + if (!myComputed || isUpToDate()) return; + myValue = null; + myComputed = false; + } + + public T getValue() { + T value = getUpToDateOrNull(); + if (value != null) { + return value; + } + + CachedValueProvider.Result result = myProvider.compute(); + value = result.getValue(); + myValue = new SoftReference(value); + computeTimeStamps(result.getDependencyItems()); + + myComputed = true; + return value; + } + + private T getUpToDateOrNull() { + T value = myValue == null ? null : myValue.get(); + return myComputed && isUpToDate() ? value : null; + } + + public boolean hasUpToDateValue() { + return getUpToDateOrNull() != null; + } + + private boolean isUpToDate() { + if (myTimeStamps == null) return true; + if (myManager.isDisposed()) return false; + + for (int i = 0; i < myDependencies.length; i++) { + Object dependency = myDependencies[i]; + if (dependency == null) continue; + if (isDependencyOutOfDate(dependency, i)) return false; + } + + return true; + } + + private boolean isDependencyOutOfDate(Object dependency, int i) { + if (dependency instanceof PsiElement && + myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount()) { + return false; + } + final long timeStamp = getTimeStamp(dependency); + return timeStamp < 0 || timeStamp != myTimeStamps[i]; + } + + private void computeTimeStamps(Object[] dependencies) { + if (dependencies == null) { + myTimeStamps = null; + myDependencies = null; + return; + } + + TLongArrayList timeStamps = new TLongArrayList(); + List deps = new ArrayList(); + collectDependencies(timeStamps, deps, dependencies); + if (myTrackValue) { + collectDependencies(timeStamps, deps, new Object[]{myValue}); + } + + myLastPsiTimeStamp = myManager.getModificationTracker().getModificationCount(); + myTimeStamps = timeStamps.toNativeArray(); + myDependencies = deps.toArray(new Object[deps.size()]); + } + + private void collectDependencies(TLongArrayList timeStamps, List resultingDeps, Object[] dependencies) { + for (int i = 0; i < dependencies.length; i++) { + Object dependency = dependencies[i]; + if (dependency == null) continue; + if (dependency.getClass().isArray()) { + Object[] objects = (Object[])dependency; + collectDependencies(timeStamps, resultingDeps, objects); + } + else { + resultingDeps.add(dependency); + timeStamps.add(getTimeStamp(dependency)); + } + } + } + + private long getTimeStamp(Object dependency) { + if (dependency instanceof Reference){ + final Object original = ((Reference)dependency).get(); + if(original == null) return -1; + return getTimeStamp(original); + } + + if (dependency instanceof ModificationTracker) { + return ((ModificationTracker)dependency).getModificationCount(); + } + + if (dependency instanceof PsiElement) { + PsiElement element = (PsiElement)dependency; + if (!element.isValid()) return -1; + PsiFile containingFile = element.getContainingFile(); + if (containingFile == null) return -1; + return containingFile.getModificationStamp(); + } + else if (dependency instanceof J2EEModuleProperties) { + try { + ((J2EEModuleProperties)dependency).getMainDeploymentDescriptor().checkIsValid(); + } + catch (VerificationException e) { + return -1; + } + } + + if (dependency == PsiModificationTracker.MODIFICATION_COUNT) { + return myManager.getModificationTracker().getModificationCount(); + } + else if (dependency == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) { + return myManager.getModificationTracker().getOutOfCodeBlockModificationCount(); + } else { + LOG.error("Wrong dependency type: " + dependency.getClass()); + return -1; + } + } + + public CachedValueProvider getValueProvider() { + return myProvider; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValuesManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValuesManagerImpl.java new file mode 100644 index 00000000000..2accdee8910 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CachedValuesManagerImpl.java @@ -0,0 +1,67 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.PsiLock; +import com.intellij.psi.PsiManager; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +/** + * @author ven + */ +public class CachedValuesManagerImpl extends CachedValuesManager { + private final PsiManager myManager; + + public CachedValuesManagerImpl(PsiManager manager) { + myManager = manager; + } + + private List> myValues = new ArrayList>(); + private int myValuesMaxSize = 0; + private boolean myReleaseOutdatedInProgress = false; + + public CachedValue createCachedValue(CachedValueProvider provider, boolean trackValue) { + synchronized (PsiLock.LOCK) { + final CachedValue value = new CachedValueImpl(myManager, provider, trackValue); + myValues.add(new WeakReference(value)); + myValuesMaxSize = Math.max(myValuesMaxSize, myValues.size()); + return value; + } + } + + public void releaseOutdatedValues() { + synchronized (PsiLock.LOCK) { + if (myReleaseOutdatedInProgress) { + return; + } + myReleaseOutdatedInProgress = true; + int removed = 0; + for (int i = 0; i < myValues.size(); i++) { + WeakReference ref = myValues.get(i); + final CachedValue value = ref.get(); + if (value == null) { + removed++; + continue; + } + + value.releaseValueIfOutdated(); + + if (removed > 0) { + myValues.set(i - removed, ref); + } + } + for (int i = 0; i < removed; i++) { + myValues.remove(myValues.size() - 1); + } + if (myValues.size() < myValuesMaxSize / 2) { // makes sense to reallocate + myValues = new ArrayList>(myValues); + myValuesMaxSize = myValues.size(); + } + ; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CheckUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CheckUtil.java new file mode 100644 index 00000000000..164d7346584 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CheckUtil.java @@ -0,0 +1,62 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.*; + +import com.intellij.openapi.vfs.VirtualFile; + +import com.intellij.util.IncorrectOperationException; + +/** + * + */ +public class CheckUtil { + public static void checkIsIdentifier(PsiManager manager, String text) throws IncorrectOperationException{ + if (!manager.getNameHelper().isIdentifier(text)){ + throw new IncorrectOperationException("\"" + text + "\" is not an identifier." ); + } + } + + public static void checkWritable(PsiElement element) throws IncorrectOperationException{ + if (!element.isWritable()){ + if (element instanceof PsiDirectory){ + throw new IncorrectOperationException("Cannot modify a read-only directory " + ((PsiDirectory)element).getVirtualFile().getPresentableUrl() + "."); + } + else{ + PsiFile file = element.getContainingFile(); + if (file == null){ + throw new IncorrectOperationException(); + } + throw new IncorrectOperationException("Cannot modify a read-only file " + file.getVirtualFile().getPresentableUrl() + "."); + } + } + } + + public static void checkNotCompiled(PsiElement element) throws IncorrectOperationException{ + if (element instanceof PsiCompiledElement){ + PsiClass aClass; + if (element instanceof PsiFile){ + aClass = ((PsiJavaFile)element).getClasses()[0]; + } + else{ + PsiElement parent = element; + while(!(parent instanceof PsiClass)){ + parent = parent.getParent(); + } + aClass = (PsiClass)parent; + } + throw new IncorrectOperationException("Cannot modify a compiled class " + aClass.getQualifiedName() + "."); + } + } + + public static void checkDelete(VirtualFile file) throws IncorrectOperationException{ + if (!file.isWritable()){ + throw new IncorrectOperationException("Cannot delete a read-only file " + file.getPresentableUrl() + "."); + } + if (file.isDirectory()){ + VirtualFile[] children = file.getChildren(); + for(int i = 0; i < children.length; i++) { + checkDelete(children[i]); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CommitToPsiFileAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CommitToPsiFileAction.java new file mode 100644 index 00000000000..d37041d237c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CommitToPsiFileAction.java @@ -0,0 +1,10 @@ +package com.intellij.psi.impl; + + + +public interface CommitToPsiFileAction extends Runnable { +} + + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CompositeShortNamesCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CompositeShortNamesCache.java new file mode 100644 index 00000000000..6bf3ee02998 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/CompositeShortNamesCache.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.psi.impl; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.util.containers.HashSet; +import gnu.trove.THashSet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class CompositeShortNamesCache implements PsiShortNamesCache { + private List myCaches = new ArrayList(); + private static final String[] EMPTY_STRINGS = new String[0]; + + public void addCache(PsiShortNamesCache cache) { + myCaches.add(cache); + } + + public void runStartupActivity() { + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + cache.runStartupActivity(); + } + } + + public PsiFile[] getFilesByName(String name) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getFilesByName(name)); + } + PsiFile[] result = merger.getResult(); + return result != null ? result : PsiFile.EMPTY_ARRAY; + } + + public String[] getAllFileNames() { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getAllFileNames()); + } + String[] result = merger.getResult(); + return result != null ? result : EMPTY_STRINGS; + } + + public PsiClass[] getClassesByName(String name, GlobalSearchScope scope) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getClassesByName(name, scope)); + } + PsiClass[] result = merger.getResult(); + return result != null ? result : PsiClass.EMPTY_ARRAY; + } + + public String[] getAllClassNames(boolean searchInLibraries) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getAllClassNames(searchInLibraries)); + } + String[] result = merger.getResult(); + return result != null ? result : EMPTY_STRINGS; + } + + public void getAllClassNames(boolean searchInLibraries, HashSet dest) { + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + cache.getAllClassNames(searchInLibraries, dest); + } + } + + public PsiMethod[] getMethodsByName(String name, GlobalSearchScope scope) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getMethodsByName(name, scope)); + } + PsiMethod[] result = merger.getResult(); + return result != null ? result : PsiMethod.EMPTY_ARRAY; + } + + public String[] getAllMethodNames(boolean searchInLibraries) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getAllMethodNames(searchInLibraries)); + } + String[] result = merger.getResult(); + return result != null ? result : EMPTY_STRINGS; + } + + public void getAllMethodNames(boolean searchInLibraries, HashSet set) { + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + cache.getAllMethodNames(searchInLibraries, set); + } + } + + public PsiField[] getFieldsByName(String name, GlobalSearchScope scope) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getFieldsByName(name, scope)); + } + PsiField[] result = merger.getResult(); + return result != null ? result : PsiField.EMPTY_ARRAY; + } + + public String[] getAllFieldNames(boolean searchInLibraries) { + Merger merger = new Merger(); + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + merger.add(cache.getAllFieldNames(searchInLibraries)); + } + String[] result = merger.getResult(); + return result != null ? result : EMPTY_STRINGS; + } + + public void getAllFieldNames(boolean checkBoxState, HashSet set) { + for (int i = 0; i < myCaches.size(); i++) { + PsiShortNamesCache cache = myCaches.get(i); + cache.getAllFieldNames(checkBoxState, set); + } + } + + private static class Merger { + private T[] mySingleItem = null; + private Set myAllItems = null; + + public void add(T[] items) { + if (items == null || items.length == 0) return; + if (mySingleItem == null) { + mySingleItem = items; + return; + } + if (myAllItems == null) { + myAllItems = new THashSet(Arrays.asList(mySingleItem)); + } + myAllItems.addAll(Arrays.asList(items)); + } + + public T[] getResult() { + if (myAllItems == null) return mySingleItem; + return myAllItems.toArray(mySingleItem); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ConstantExpressionEvaluator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ConstantExpressionEvaluator.java new file mode 100644 index 00000000000..9b37f317037 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ConstantExpressionEvaluator.java @@ -0,0 +1,558 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.ConstantEvaluationOverflowException; +import com.intellij.psi.util.ConstantExpressionUtil; +import gnu.trove.THashSet; + +import java.util.Set; + +public class ConstantExpressionEvaluator extends PsiElementVisitor { + protected Set myVisitedVars; + protected boolean myThrowExceptionOnOverflow; + protected Object myValue; + + protected ConstantExpressionEvaluator(Set visitedVars, boolean throwExceptionOnOverflow) { + myVisitedVars = visitedVars; + myThrowExceptionOnOverflow = throwExceptionOnOverflow; + } + + protected Object getValue() { + return myValue; + } + + public void visitLiteralExpression(PsiLiteralExpression expression) { + myValue = expression.getValue(); + } + + public void visitBinaryExpression(PsiBinaryExpression expression) { + Object lOperandValue = accept(expression.getLOperand()); + Object rOperandValue = accept(expression.getROperand()); + + final PsiJavaToken operationSign = expression.getOperationSign(); + if (operationSign == null) { + myValue = null; + return; + } + + final IElementType tokenType = operationSign.getTokenType(); + + Object value = null; + if (tokenType == JavaTokenType.LT) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() < ((Number)rOperandValue).doubleValue()); + } + } + else if (tokenType == JavaTokenType.LE) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() <= ((Number)rOperandValue).doubleValue()); + } + } + else if (tokenType == JavaTokenType.GT) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() > ((Number)rOperandValue).doubleValue()); + } + } + else if (tokenType == JavaTokenType.GE) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() >= ((Number)rOperandValue).doubleValue()); + } + } + else if (tokenType == JavaTokenType.EQEQ) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() == ((Number)rOperandValue).doubleValue()); + } + else if (lOperandValue instanceof String && rOperandValue instanceof String) { + value = Boolean.valueOf(lOperandValue == rOperandValue); + } + else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() != ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.NE) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + value = Boolean.valueOf(((Number)lOperandValue).doubleValue() != ((Number)rOperandValue).doubleValue()); + } + else if (lOperandValue instanceof String && rOperandValue instanceof String) { + value = Boolean.valueOf(lOperandValue != rOperandValue); + } + else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() != ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.PLUS) { + if (lOperandValue == null || rOperandValue == null) { + myValue = null; + return; + } + if (lOperandValue instanceof String || rOperandValue instanceof String) { + value = (lOperandValue.toString() + rOperandValue.toString()).intern(); + } + else { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + if (lOperandValue instanceof Double || rOperandValue instanceof Double) { + value = new Double(((Number)lOperandValue).doubleValue() + ((Number)rOperandValue).doubleValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue,expression); + } + else if (lOperandValue instanceof Float || rOperandValue instanceof Float) { + value = new Float(((Number)lOperandValue).floatValue() + ((Number)rOperandValue).floatValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + final long l = ((Number)lOperandValue).longValue(); + final long r = ((Number)rOperandValue).longValue(); + value = new Long(l + r); + checkAdditionOverflow(((Long)value).longValue() >= 0, l >= 0, r >= 0, expression); + } + else { + final int l = ((Number)lOperandValue).intValue(); + final int r = ((Number)rOperandValue).intValue(); + value = new Integer(l + r); + checkAdditionOverflow(((Integer)value).intValue() >= 0, l >= 0, r >= 0, expression); + } + } + } + } + else if (tokenType == JavaTokenType.MINUS) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + if (lOperandValue instanceof Double || rOperandValue instanceof Double) { + value = new Double(((Number)lOperandValue).doubleValue() - ((Number)rOperandValue).doubleValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Float || rOperandValue instanceof Float) { + value = new Float(((Number)lOperandValue).floatValue() - ((Number)rOperandValue).floatValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + final long l = ((Number)lOperandValue).longValue(); + final long r = ((Number)rOperandValue).longValue(); + value = new Long(l - r); + checkAdditionOverflow(((Long)value).longValue() >= 0, l >= 0, r < 0, expression); + } + else { + final int l = ((Number)lOperandValue).intValue(); + final int r = ((Number)rOperandValue).intValue(); + value = new Integer(l - r); + checkAdditionOverflow(((Integer)value).intValue() >= 0, l >= 0, r < 0, expression); + } + } + } + else if (tokenType == JavaTokenType.ASTERISK) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + if (lOperandValue instanceof Double || rOperandValue instanceof Double) { + value = new Double(((Number)lOperandValue).doubleValue() * ((Number)rOperandValue).doubleValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Float || rOperandValue instanceof Float) { + value = new Float(((Number)lOperandValue).floatValue() * ((Number)rOperandValue).floatValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + final long l = ((Number)lOperandValue).longValue(); + final long r = ((Number)rOperandValue).longValue(); + value = new Long(l * r); + checkMultiplicationOverflow(((Long)value).longValue(), l, r, expression); + } + else { + final int l = ((Number)lOperandValue).intValue(); + final int r = ((Number)rOperandValue).intValue(); + value = new Integer(l * r); + checkMultiplicationOverflow(((Integer)value).intValue(), l, r, expression); + } + } + } + else if (tokenType == JavaTokenType.DIV) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + if (lOperandValue instanceof Double || rOperandValue instanceof Double) { + value = new Double(((Number)lOperandValue).doubleValue() / ((Number)rOperandValue).doubleValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Float || rOperandValue instanceof Float) { + value = new Float(((Number)lOperandValue).floatValue() / ((Number)rOperandValue).floatValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + final long r = ((Number)rOperandValue).longValue(); + final long l = ((Number)lOperandValue).longValue(); + checkDivisionOverflow(l, r, Long.MIN_VALUE, expression); + value = r == 0 ? null : new Long(l / r); + } + else { + final int r = ((Number)rOperandValue).intValue(); + final int l = ((Number)lOperandValue).intValue(); + checkDivisionOverflow(l, r, Integer.MIN_VALUE, expression); + value = r == 0 ? null : new Integer(l / r); + } + } + } + else if (tokenType == JavaTokenType.PERC) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (lOperandValue instanceof Number && rOperandValue instanceof Number) { + double rVal = ((Number)rOperandValue).doubleValue(); + if (myThrowExceptionOnOverflow && rVal == 0) throw new ConstantEvaluationOverflowException(expression); + if (lOperandValue instanceof Double || rOperandValue instanceof Double) { + value = new Double(((Number)lOperandValue).doubleValue() % ((Number)rOperandValue).doubleValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Float || rOperandValue instanceof Float) { + value = new Float(((Number)lOperandValue).floatValue() % ((Number)rOperandValue).floatValue()); + checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression); + } + else if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() % ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() % ((Number)rOperandValue).intValue()); + } + } + } + else if (tokenType == JavaTokenType.LTLT) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() << ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() << ((Number)rOperandValue).intValue()); + } + } + } + else if (tokenType == JavaTokenType.GTGT) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() >> ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() >> ((Number)rOperandValue).intValue()); + } + } + } + else if (tokenType == JavaTokenType.GTGTGT) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() >>> ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() >>> ((Number)rOperandValue).intValue()); + } + } + } + else if (tokenType == JavaTokenType.AND) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() & ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() & ((Number)rOperandValue).intValue()); + } + } + else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() & ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.OR) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() | ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() | ((Number)rOperandValue).intValue()); + } + } + else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() | ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.XOR) { + if (lOperandValue instanceof Character) lOperandValue = new Integer(((Character)lOperandValue).charValue()); + if (rOperandValue instanceof Character) rOperandValue = new Integer(((Character)rOperandValue).charValue()); + if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) { + if (lOperandValue instanceof Long || rOperandValue instanceof Long) { + value = new Long(((Number)lOperandValue).longValue() ^ ((Number)rOperandValue).longValue()); + } + else { + value = new Integer(((Number)lOperandValue).intValue() ^ ((Number)rOperandValue).intValue()); + } + } + else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() ^ ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.ANDAND) { + if (lOperandValue == null || rOperandValue == null) { + myValue = null; + return; + } + if (lOperandValue instanceof Boolean && !((Boolean)lOperandValue).booleanValue()) { + myValue = Boolean.FALSE; + return; + } + if (rOperandValue instanceof Boolean && !((Boolean)rOperandValue).booleanValue()) { + myValue = Boolean.FALSE; + return; + } + if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() && ((Boolean)rOperandValue).booleanValue()); + } + } + else if (tokenType == JavaTokenType.OROR) { + if (lOperandValue == null || rOperandValue == null) { + myValue = null; + return; + } + if (lOperandValue instanceof Boolean && ((Boolean)lOperandValue).booleanValue()) { + myValue = Boolean.TRUE; + return; + } + if (rOperandValue instanceof Boolean && ((Boolean)rOperandValue).booleanValue()) { + myValue = Boolean.TRUE; + return; + } + if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) { + value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() || ((Boolean)rOperandValue).booleanValue()); + } + } + + myValue = value; + } + + protected Object accept(PsiElement element) { + myValue = null; + if (element != null) { + element.accept(this); + } + + return myValue; + } + + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + Object operand; + PsiType castType = expression.getCastType().getType(); + if(expression.getOperand() == null) { + myValue = null; + return; + } + + operand = accept(expression.getOperand()); + + myValue = ConstantExpressionUtil.computeCastTo(operand, castType); + } + + public void visitConditionalExpression(PsiConditionalExpression expression) { + if (expression.getCondition() == null || expression.getThenExpression() == null || expression.getElseExpression() == null) { + myValue = null; + return; + } + + Object condition = accept(expression.getCondition()); + Object thenExpr = accept(expression.getThenExpression()); + Object elseExpr = accept(expression.getElseExpression()); + + Object value = null; + if (condition instanceof Boolean && thenExpr != null && elseExpr != null) { + value = ((Boolean) condition).booleanValue() ? thenExpr : elseExpr; + } + + myValue = value; + } + + public void visitPrefixExpression(PsiPrefixExpression expression) { + Object operand; + if (expression.getOperand() == null) { + myValue = null; + return; + } + operand = accept(expression.getOperand()); + if (operand == null || expression.getOperationSign() == null) { + myValue = null; + return; + } + IElementType tokenType = expression.getOperationSign().getTokenType(); + Object value = null; + if (tokenType == JavaTokenType.MINUS) { + if (operand instanceof Character) operand = new Integer(((Character)operand).charValue()); + if (operand instanceof Number) { + if (operand instanceof Double) { + value = new Double(-((Number)operand).doubleValue()); + checkRealNumberOverflow(value, null, null, expression); + } + else if (operand instanceof Float) { + value = new Float(-((Number)operand).floatValue()); + checkRealNumberOverflow(value, null, null, expression); + } + else if (operand instanceof Long) { + value = new Long(-((Number)operand).longValue()); + if (myThrowExceptionOnOverflow + && !(expression.getOperand() instanceof PsiLiteralExpression) + && ((Number)operand).longValue() == Long.MIN_VALUE) { + throw new ConstantEvaluationOverflowException(expression); + } + } + else { + value = new Integer(-((Number)operand).intValue()); + if (myThrowExceptionOnOverflow + && !(expression.getOperand() instanceof PsiLiteralExpression) + && ((Number)operand).intValue() == Integer.MIN_VALUE) { + throw new ConstantEvaluationOverflowException(expression); + } + } + } + } + else if (tokenType == JavaTokenType.PLUS) { + if (operand instanceof Character) operand = new Integer(((Character)operand).charValue()); + if (operand instanceof Number) { + value = operand; + } + } + else if (tokenType == JavaTokenType.TILDE) { + if (operand instanceof Character) operand = new Integer(((Character)operand).charValue()); + if (isIntegral(operand)) { + if (operand instanceof Long) { + value = new Long(~((Number)operand).longValue()); + } + else { + value = new Integer(~((Number)operand).intValue()); + } + } + } + else if (tokenType == JavaTokenType.EXCL) { + if (operand instanceof Boolean) { + value = Boolean.valueOf(!((Boolean)operand).booleanValue()); + } + } + + myValue = value; + } + + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { + myValue = accept(expression.getExpression()); + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + PsiExpression qualifierExpression = expression.getQualifierExpression(); + while (qualifierExpression != null) { + if (!(qualifierExpression instanceof PsiReferenceExpression)) { + myValue = null; + return; + } + + PsiReferenceExpression qualifier = (PsiReferenceExpression) qualifierExpression; + final PsiElement resolved = qualifier.resolve(); + if (resolved instanceof PsiPackage) break; + if (!(resolved instanceof PsiClass)) { + myValue = null; + return; + } + qualifierExpression = ((PsiReferenceExpression) qualifierExpression).getQualifierExpression(); + } + PsiElement resolvedExpression = expression.resolve(); + if (resolvedExpression instanceof PsiVariable) { + PsiVariable variable = (PsiVariable) resolvedExpression; + // avoid cycles + if (myVisitedVars != null && myVisitedVars.contains(variable)) { + myValue = null; + return; + } + + Set oldVisitedVars = myVisitedVars; + if (myVisitedVars == null) { myVisitedVars = new THashSet(); } + + myVisitedVars.add(variable); + try { + if (!(variable instanceof PsiVariableEx)) { + myValue = null; //? + return; + } + + myValue = ((PsiVariableEx) variable).computeConstantValue(myVisitedVars); + return; + } + finally { + myVisitedVars.remove(variable); + myVisitedVars = oldVisitedVars; + } + } + + myValue = null; + } + + protected static boolean isIntegral(Object o) { + return o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte || o instanceof Character; + } + + protected void checkDivisionOverflow(long l, final long r, long minValue, PsiBinaryExpression expression) { + if (!myThrowExceptionOnOverflow) return; + if (r == 0) throw new ConstantEvaluationOverflowException(expression); + if (r == -1 && l == minValue) throw new ConstantEvaluationOverflowException(expression); + } + + protected void checkMultiplicationOverflow(long result, long l, long r, PsiExpression expression) { + if (!myThrowExceptionOnOverflow) return; + if (r == 0 || l == 0) return; + if (result / r != l || ((l < 0) ^ (r < 0) != (result < 0))) throw new ConstantEvaluationOverflowException(expression); + } + + protected void checkAdditionOverflow(boolean resultPositive, + boolean lPositive, + boolean rPositive, PsiBinaryExpression expression) { + if (!myThrowExceptionOnOverflow) return; + boolean overflow = lPositive == rPositive && lPositive != resultPositive; + if (overflow) throw new ConstantEvaluationOverflowException(expression); + } + + protected void checkRealNumberOverflow(Object result, + Object lOperandValue, + Object rOperandValue, PsiExpression expression) { + if (!myThrowExceptionOnOverflow) return; + if (lOperandValue instanceof Float && ((Float) lOperandValue).isInfinite()) return; + if (lOperandValue instanceof Double && ((Double) lOperandValue).isInfinite()) return; + if (rOperandValue instanceof Float && ((Float) rOperandValue).isInfinite()) return; + if (rOperandValue instanceof Double && ((Double) rOperandValue).isInfinite()) return; + + if (result instanceof Float && ((Float) result).isInfinite()) throw new ConstantEvaluationOverflowException(expression); + if (result instanceof Double && ((Double) result).isInfinite()) throw new ConstantEvaluationOverflowException(expression); + } + + public static Object computeConstantExpression(PsiExpression expression, Set visitedVars, boolean throwExceptionOnOverflow) { + ConstantExpressionEvaluator evaluator = new ConstantExpressionEvaluator(visitedVars, throwExceptionOnOverflow); + return _compute(evaluator, expression); + } + + protected static Object _compute(ConstantExpressionEvaluator evaluator, PsiExpression expression) { + evaluator.accept(expression); + return evaluator.getValue(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/DebugUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/DebugUtil.java new file mode 100644 index 00000000000..de570e6d417 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/DebugUtil.java @@ -0,0 +1,226 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLock; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.ArrayUtil; +import com.intellij.util.CharTable; + +/** + * + */ +public class DebugUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DebugUtil"); + + public static /*final*/ boolean CHECK = false; + public static final boolean CHECK_INSIDE_ATOMIC_ACTION_ENABLED = true; + + public static String psiTreeToString(PsiElement element, boolean skipWhitespaces) { + return treeToString(SourceTreeToPsiMap.psiElementToTree(element), skipWhitespaces); + } + + public static String treeToString(TreeElement root, boolean skipWhitespaces) { + StringBuffer buffer = new StringBuffer(); + treeToBuffer(buffer, root, 0, skipWhitespaces); + return buffer.toString(); + } + + public static String treeToStringWithUserData(TreeElement root, boolean skipWhitespaces) { + StringBuffer buffer = new StringBuffer(); + treeToBufferWithUserData(buffer, root, 0, skipWhitespaces); + return buffer.toString(); + } + + public static String treeToStringWithUserData(PsiElement root, boolean skipWhitespaces) { + StringBuffer buffer = new StringBuffer(); + treeToBufferWithUserData(buffer, root, 0, skipWhitespaces); + return buffer.toString(); + } + + private static void treeToBuffer(StringBuffer buffer, TreeElement root, int indent, boolean skipWhiteSpaces) { + if (skipWhiteSpaces && root.getElementType() == ElementType.WHITE_SPACE) return; + + for(int i = 0; i < indent; i++){ + buffer.append(' '); + } + if (root instanceof CompositeElement){ + buffer.append(SourceTreeToPsiMap.treeElementToPsi(root).toString()); + } + else{ + String text = root.getText(); + text = StringUtil.replace(text, "\n", "\\n"); + text = StringUtil.replace(text, "\r", "\\r"); + text = StringUtil.replace(text, "\t", "\\t"); + buffer.append(root.toString() + "('" + text + "')"); + } + buffer.append("\n"); + if (root instanceof CompositeElement){ + ChameleonTransforming.transformChildren((CompositeElement)root); + TreeElement child = ((CompositeElement)root).firstChild; + + if (child == null){ + for(int i = 0; i < indent + 2; i++){ + buffer.append(' '); + } + buffer.append("\n"); + } + else while(child != null){ + treeToBuffer(buffer, child, indent + 2, skipWhiteSpaces); + child = child.getTreeNext(); + } + } + } + + private static void treeToBufferWithUserData(StringBuffer buffer, TreeElement root, int indent, boolean skipWhiteSpaces) { + if (skipWhiteSpaces && root.getElementType() == ElementType.WHITE_SPACE) return; + + for(int i = 0; i < indent; i++){ + buffer.append(' '); + } + if (root instanceof CompositeElement){ + buffer.append(SourceTreeToPsiMap.treeElementToPsi(root).toString()); + } + else{ + String text = root.getText(); + text = StringUtil.replace(text, "\n", "\\n"); + text = StringUtil.replace(text, "\r", "\\r"); + text = StringUtil.replace(text, "\t", "\\t"); + buffer.append(root.toString() + "('" + text + "')"); + } + buffer.append(root.getUserDataString()); + buffer.append("\n"); + if (root instanceof CompositeElement || root instanceof ChameleonElement){ + PsiElement[] children = SourceTreeToPsiMap.treeElementToPsi(root).getChildren(); + + for(int i = 0; i < children.length; i++){ + PsiElement child = children[i]; + treeToBufferWithUserData(buffer, SourceTreeToPsiMap.psiElementToTree(child), indent + 2, skipWhiteSpaces); + } + + if (children.length == 0){ + for(int i = 0; i < indent + 2; i++){ + buffer.append(' '); + } + buffer.append("\n"); + } + } + } + + private static void treeToBufferWithUserData(StringBuffer buffer, PsiElement root, int indent, boolean skipWhiteSpaces) { + if (skipWhiteSpaces && root instanceof PsiWhiteSpace) return; + + for(int i = 0; i < indent; i++){ + buffer.append(' '); + } + if (root instanceof CompositeElement){ + buffer.append(root); + } + else{ + String text = root.getText(); + text = StringUtil.replace(text, "\n", "\\n"); + text = StringUtil.replace(text, "\r", "\\r"); + text = StringUtil.replace(text, "\t", "\\t"); + buffer.append(root.toString() + "('" + text + "')"); + } + buffer.append(((UserDataHolderBase)root).getUserDataString()); + buffer.append("\n"); + + PsiElement[] children = root.getChildren(); + + for(int i = 0; i < children.length; i++){ + PsiElement child = children[i]; + treeToBufferWithUserData(buffer, child, indent + 2, skipWhiteSpaces); + } + + if (children.length == 0){ + for(int i = 0; i < indent + 2; i++){ + buffer.append(' '); + } + buffer.append("\n"); + } + + } + + public static void checkTreeStructure(TreeElement anyElement) { + TreeElement root = anyElement; + while(root.getTreeParent() != null){ + root = root.getTreeParent(); + } + if (root instanceof CompositeElement) { + synchronized (PsiLock.LOCK) { + checkSubtree((CompositeElement)root); + } + } + } + + private static void checkSubtree(CompositeElement root) { + if (root.firstChild == null){ + if (root.lastChild != null){ + throw new IncorrectTreeStructureException(root, "firstChild == null, but lastChild != null"); + } + } + else{ + for(TreeElement child = root.firstChild; child != null; child = child.getTreeNext()){ + if (child instanceof CompositeElement){ + checkSubtree((CompositeElement)child); + } + if (child.getTreeParent() != root){ + throw new IncorrectTreeStructureException(child, "child has wrong parent value"); + } + if (child == root.firstChild){ + if (child.getTreePrev() != null){ + throw new IncorrectTreeStructureException(root, "firstChild.prev != null"); + } + } + else{ + if (child.getTreePrev() == null){ + throw new IncorrectTreeStructureException(child, "not first child has prev == null"); + } + if (child.getTreePrev().getTreeNext() != child){ + throw new IncorrectTreeStructureException(child, "element.prev.next != element"); + } + } + if (child.getTreeNext() == null){ + if (root.lastChild != child){ + throw new IncorrectTreeStructureException(child, "not last child has next == null"); + } + } + } + } + } + + public static void checkParentChildConsistent(TreeElement element) { + CompositeElement treeParent = element.getTreeParent(); + if (treeParent == null) return; + TreeElement[] elements = treeParent.getChildren(null); + if (ArrayUtil.find(elements, element) == -1) { + throw new IncorrectTreeStructureException(element, "child cannot be found among parents children"); + } + //LOG.debug("checked consistence: "+System.identityHashCode(element)); + } + + public static void checkSameCharTabs(TreeElement element1, TreeElement element2) { + final CharTable fromCharTab = SharedImplUtil.findCharTableByTree(element1); + final CharTable toCharTab = SharedImplUtil.findCharTableByTree(element2); + LOG.assertTrue(fromCharTab == toCharTab); + } + + public static class IncorrectTreeStructureException extends RuntimeException { + private final TreeElement myElement; + + public IncorrectTreeStructureException(TreeElement element, String message) { + super(message); + myElement = element; + } + + public TreeElement getElement() { + return myElement; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ElementBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ElementBase.java new file mode 100644 index 00000000000..0a034222b7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/ElementBase.java @@ -0,0 +1,183 @@ +package com.intellij.psi.impl; + +import com.intellij.ant.PsiAntElement; +import com.intellij.aspects.psi.PsiAdvice; +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.aspects.psi.gen.PsiErrorIntroduction; +import com.intellij.aspects.psi.gen.PsiParentsIntroduction; +import com.intellij.aspects.psi.gen.PsiSofteningIntroduction; +import com.intellij.aspects.psi.gen.PsiWarningIntroduction; +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.ide.IconUtilEx; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.jsp.jspJava.JspClass; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.XmlTag; +import com.intellij.ui.LayeredIcon; +import com.intellij.ui.RowIcon; +import com.intellij.util.Icons; + +import javax.swing.*; + +public abstract class ElementBase extends UserDataHolderBase implements Iconable { + public Icon getIcon(int flags) { + if (!(this instanceof PsiElement)) return null; + return getIcon((PsiElement) this, flags, ((PsiElement) this).isWritable()); + } + + private static Icon getIcon(PsiElement element, int flags, boolean elementWritable) { + RowIcon baseIcon; + boolean showReadStatus = (flags & ICON_FLAG_READ_STATUS) != 0; + PsiModifierList modifierList = PsiUtil.getModifierList(element); + + if (element instanceof PsiDirectory) { + Icon symbolIcon; + final PsiDirectory psiDirectory = (PsiDirectory)element; + if (psiDirectory.getPackage() != null) { + symbolIcon = Icons.PACKAGE_ICON; + } + else { + symbolIcon = Icons.DIRECTORY_CLOSED_ICON; + } + boolean isExcluded = false; + final VirtualFile vFile = psiDirectory.getVirtualFile(); + if (vFile != null) { + final Project project = psiDirectory.getProject(); + if (ProjectRootManager.getInstance(project).getFileIndex().isInSource(vFile) && CompilerConfiguration.getInstance(project).isExcludedFromCompilation(vFile)) { + isExcluded = true; + } + } + baseIcon = createLockableExcludableIcon(symbolIcon, showReadStatus && !elementWritable, isExcluded); + } + else if (element instanceof PsiPackage) { + baseIcon = createLockableIcon(Icons.PACKAGE_ICON, showReadStatus && !elementWritable); + } + else if (element instanceof PsiFile) { + PsiFile file = (PsiFile)element; + Icon symbolIcon = IconUtilEx.getIcon(file.getVirtualFile(), flags & ~ICON_FLAG_READ_STATUS, file.getProject()); + baseIcon = createLockableIcon(symbolIcon, showReadStatus && !elementWritable); + } + else if (element instanceof PsiClass) { + Icon symbolIcon; + final PsiClass aClass = (PsiClass)element; + final EjbClassRole role = J2EERolesUtil.getEjbRole(aClass); + if (role != null) { + symbolIcon = role.getIcon(); + } + else { + if (aClass instanceof PsiAspect) { + symbolIcon = Icons.ASPECT_ICON; + } else if (aClass.isAnnotationType()) { + symbolIcon = Icons.ANNOTATION_TYPE_ICON; + } else if (aClass.isEnum()) { + symbolIcon = Icons.ENUM_ICON; + } + else if (aClass.isInterface()) { + symbolIcon = + modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC) + ? Icons.STATIC_INTERFACE_ICON + : Icons.INTERFACE_ICON; + } + else if (aClass instanceof JspClass) { + symbolIcon = Icons.JSP_ICON; + } + else { + symbolIcon = + modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC) + ? Icons.STATIC_CLASS_ICON + : Icons.CLASS_ICON; + } + } + boolean isExcluded = false; + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile != null) { + final VirtualFile vFile = containingFile.getVirtualFile(); + if (vFile != null) { + final Project project = aClass.getProject(); + if (ProjectRootManager.getInstance(project).getFileIndex().isInSource(vFile) && CompilerConfiguration.getInstance(project).isExcludedFromCompilation(vFile)) { + isExcluded = true; + } + } + } + baseIcon = createLockableExcludableIcon(symbolIcon, showReadStatus && !elementWritable, isExcluded); + } + else if (element instanceof PsiMethod) { + final EjbMethodRole role = J2EERolesUtil.getEjbRole((PsiMethod)element); + Icon methodIcon = role == null + ? modifierList.hasModifierProperty(PsiModifier.STATIC) ? Icons.STATIC_METHOD_ICON : Icons.METHOD_ICON + : role.getIcon(); + baseIcon = createLockableIcon(methodIcon, showReadStatus && !elementWritable); + } + else if (element instanceof PsiField) { + Icon fieldIcon = ((PsiField)element).hasModifierProperty(PsiModifier.STATIC) ? Icons.STATIC_FIELD_ICON : Icons.FIELD_ICON; + baseIcon = createLockableIcon(fieldIcon, showReadStatus && !elementWritable); + } + else if (element instanceof PsiParameter) { + baseIcon = createLockableIcon(Icons.PARAMETER_ICON, showReadStatus && !elementWritable); + } + else if (element instanceof PsiVariable) { + baseIcon = createLockableIcon(Icons.VARIABLE_ICON, showReadStatus && !elementWritable); + } + else if (element instanceof PsiPointcutDef) { + baseIcon = createLockableIcon(Icons.POINTCUT_ICON, showReadStatus && !elementWritable); + } + else if (element instanceof PsiParentsIntroduction) { + baseIcon = createLockableIcon(Icons.PARENTS_INTRODUCTION_ICON, false); + } + else if (element instanceof PsiErrorIntroduction) { + baseIcon = createLockableIcon(Icons.ERROR_INTRODUCTION_ICON, false); + } + else if (element instanceof PsiWarningIntroduction) { + baseIcon = createLockableIcon(Icons.WARNING_INTRODUCTION_ICON, false); + } + else if (element instanceof PsiSofteningIntroduction) { + baseIcon = createLockableIcon(Icons.SOFTENING_INTRODUCTION_ICON, false); + } + else if (element instanceof PsiAdvice) { + baseIcon = createLockableIcon(Icons.ADVICE_ICON, false); + } + else if (element instanceof XmlTag) { + return Icons.XML_TAG_ICON; + } + else if (element instanceof PsiAntElement) { + return ((PsiAntElement)element).getRole().getIcon(); + } + else { + return null; + } + if ((flags & ICON_FLAG_VISIBILITY) != 0) { + IconUtilEx.setVisibilityIcon(modifierList, baseIcon); + } + return baseIcon; + } + + private static RowIcon createLockableIcon(Icon icon, boolean isLocked) { + return createLockableExcludableIcon(icon, isLocked, false); + } + private static RowIcon createLockableExcludableIcon(Icon icon, boolean isLocked, boolean isExcluded) { + if (isExcluded || isLocked) { + LayeredIcon layeredIcon = new LayeredIcon(1 + (isLocked? 1 : 0) + (isExcluded? 1 : 0)); + int layer = 0; + layeredIcon.setIcon(icon, layer++); + if (isLocked) { + layeredIcon.setIcon(Icons.LOCKED_ICON, layer++); + } + if (isExcluded) { + layeredIcon.setIcon(Icons.EXCLUDED_FROM_COMPILE_ICON, layer); + } + icon = layeredIcon; + } + RowIcon baseIcon = new RowIcon(2); + baseIcon.setIcon(icon, 0); + return baseIcon; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/EmptySubstitutorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/EmptySubstitutorImpl.java new file mode 100644 index 00000000000..90d0511d579 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/EmptySubstitutorImpl.java @@ -0,0 +1,75 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.psi.*; + +import java.util.Collections; +import java.util.Map; + +/** + * @author dsl + */ +public final class EmptySubstitutorImpl extends EmptySubstitutor implements PsiSubstitutorEx, ApplicationComponent { + public PsiType substitute(PsiTypeParameter typeParameter){ + return typeParameter.getManager().getElementFactory().createType(typeParameter); + } + + public PsiType substitute(PsiType type){ + return type; + } + + public PsiType substituteAndCapture(PsiType type) { + return type; + } + + public PsiType substituteInternal(PsiType type) { + return substitute(type); + } + + public PsiSubstitutor put(PsiTypeParameter classParameter, PsiType mapping){ + final PsiSubstitutor substitutor = new PsiSubstitutorImpl(); + return substitutor.put(classParameter, mapping); + } + public PsiSubstitutor putAll(PsiClass parentClass, PsiType[] mappings){ + if(!parentClass.hasTypeParameters()) return this; + final PsiSubstitutor substitutor = new PsiSubstitutorImpl(); + return substitutor.putAll(parentClass, mappings); + } + + public PsiSubstitutor putAll(PsiSubstitutor another) { + return another; + } + + public PsiSubstitutor merge(PsiSubstitutor other){ + return other; + } + + public String toString() { + return "EMPTY"; + } + + public Map getSubstitutionMap() { + return Collections.EMPTY_MAP; + } + + public boolean isValid() { + return true; + } + + public String getComponentName() { + return "EmptySubstitutorComponent"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public PsiSubstitutor inplacePut(PsiTypeParameter classParameter, PsiType mapping) { + return put(classParameter, mapping); + } + + public PsiSubstitutor inplacePutAll(PsiClass parentClass, PsiType[] mappings) { + return putAll(parentClass, mappings); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/InheritanceImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/InheritanceImplUtil.java new file mode 100644 index 00000000000..593c9bd27ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/InheritanceImplUtil.java @@ -0,0 +1,145 @@ +package com.intellij.psi.impl; + +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.j2ee.j2eeDom.J2EEElementsVisitor; +import com.intellij.j2ee.j2eeDom.ejb.Ejb; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.cache.impl.ClassHashProvider; +import com.intellij.psi.util.InheritanceUtil; + +import java.util.ArrayList; +import java.util.List; + +public class InheritanceImplUtil { + private static final Key HASH_PROVIDER_KEY = Key.create("Hash provider for isInheritor"); + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.InheritanceUtil"); + + private static ClassHashProvider getHashProvider(final PsiManagerImpl manager) { + final ClassHashProvider data = (ClassHashProvider) manager.getUserData(HASH_PROVIDER_KEY); + if (data != null) return data; + final ClassHashProvider newProvider = new ClassHashProvider(manager); + manager.putUserData(HASH_PROVIDER_KEY, newProvider); + return newProvider; + } + + public static boolean isInheritor(PsiClass candidateClass, final PsiClass baseClass, final boolean checkDeep) { + if (baseClass instanceof PsiAnonymousClass) { + return false; + } + if (isInheritor(candidateClass, baseClass, checkDeep, null)) return true; + + final EjbClassRole classRole = J2EERolesUtil.getEjbRole(candidateClass); + if (classRole != null && candidateClass.getManager().areElementsEquivalent(candidateClass, classRole.getEjb().getEjbClass().getPsiClass())) { + final Ejb ejb = classRole.getEjb(); + return !EjbUtil.visitEjbInterfaces(ejb, new J2EEElementsVisitor(){ + public boolean visitInterface(PsiClass anInterface) { + return !InheritanceUtil.isInheritorOrSelf(anInterface, baseClass, checkDeep); + } + }); + } + return false; + } + + private static boolean isInheritor(PsiClass candidateClass, PsiClass baseClass, boolean checkDeep, List checkedClasses) { + if (candidateClass instanceof PsiAnonymousClass) { + final PsiClass baseCandidateClass = ((PsiAnonymousClass)candidateClass).getBaseClassType().resolve(); + if (baseCandidateClass == null) return false; + return 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) { + try { + return provider.isInheritor(baseClass, candidateClass); + } + catch (ClassHashProvider.OutOfRangeException e) { + } + } + */ + if(checkDeep && LOG.isDebugEnabled()){ + LOG.debug("Using uncached version for " + candidateClass.getQualifiedName() + " and " + baseClass); + } + PsiClass objectClass = manager.findClass("java.lang.Object", candidateClass.getResolveScope()); + if (manager.areElementsEquivalent(baseClass, objectClass)) { + if (manager.areElementsEquivalent(candidateClass, objectClass)) return false; + if (checkDeep) return true; + if (candidateClass.isInterface()) return true; + return candidateClass.getExtendsListTypes().length == 0; + } + + return isInheritorWithoutCaching(candidateClass, baseClass, checkDeep, checkedClasses); + } + + private static boolean isInheritorWithoutCaching(PsiClass aClass, PsiClass baseClass, boolean checkDeep, List checkedClasses) { + PsiManager manager = aClass.getManager(); + 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 ArrayList(); + } + checkedClasses.add(aClass); + } + + if (!aClass.isInterface() && baseClass.isInterface()) { + if (checkDeep) { + if (checkInheritor(aClass.getSuperClass(), baseClass, checkDeep, checkedClasses)) { + return true; + } + } + if (checkInheritor(aClass.getInterfaces(), baseClass, checkDeep, checkedClasses)) { + return true; + } + + return false; + } + else { + if (checkInheritor(aClass.getSupers(), baseClass, checkDeep, checkedClasses)) { + return true; + } + return false; + } + } + + private static boolean checkInheritor(PsiClass[] supers, PsiClass baseClass, boolean checkDeep, List checkedClasses) { + for (int i = 0; i < supers.length; i++) { + if (checkInheritor(supers[i], baseClass, checkDeep, checkedClasses)) { + return true; + } + } + return false; + } + + private static boolean checkInheritor(PsiClass aClass, PsiClass baseClass, boolean checkDeep, List checkedClasses) { + 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; + } + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiClassImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiClassImplUtil.java new file mode 100644 index 00000000000..6e7769b8735 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiClassImplUtil.java @@ -0,0 +1,883 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.impl.source.PsiImmediateClassType; +import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.processor.MethodResolverProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 24.10.2003 + * Time: 16:50:37 + * To change this template use Options | File Templates. + */ +public class PsiClassImplUtil{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiClassImplUtil"); + private static final Key MAP_IN_CLASS_KEY = Key.create("MAP_IN_CLASS_KEY"); + private static final Key ALL_MAPS_BUILT_FLAG = Key.create("ALL_MAPS_BUILT_FLAG"); + + public static PsiField[] getAllFields(final PsiClass aClass) { + return getAllByMap(aClass, PsiField.class); + } + + public static PsiMethod[] getAllMethods(final PsiClass aClass) { + return getAllByMap(aClass, PsiMethod.class); + } + + public static PsiClass[] getAllInnerClasses(PsiClass aClass) { + return getAllByMap(aClass, PsiClass.class); + } + + public static PsiField findFieldByName(PsiClass aClass, String name, boolean checkBases) { + final PsiField[] byMap = findByMap(aClass, name, checkBases, PsiField.class); + return byMap.length >= 1 ? byMap[0] : null; + } + + public static PsiMethod[] findMethodsByName(PsiClass aClass, String name, boolean checkBases) { + return findByMap(aClass, name, checkBases, PsiMethod.class); + } + + public static PsiMethod findMethodBySignature(final PsiClass aClass, final PsiMethod patternMethod, final boolean checkBases) { + final PsiMethod[] result = findMethodsBySignature(aClass, patternMethod, checkBases, true); + return (result.length != 0 ? result [0] : null); + } + + // ----------------------------- findMethodsBySignature ----------------------------------- + + public static PsiMethod[] findMethodsBySignature(final PsiClass aClass, final PsiMethod patternMethod, final boolean checkBases) { + return findMethodsBySignature(aClass, patternMethod, checkBases, false); + } + + private static PsiMethod[] findMethodsBySignature(final PsiClass aClass, final PsiMethod patternMethod, final boolean checkBases, final boolean stopOnFirst) { + final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases); + final ArrayList methods = new ArrayList(); + final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY); + for (int i = 0; i < methodsByName.length; i++) { + final PsiMethod method = methodsByName[i]; + final PsiClass superClass = method.getContainingClass(); + final PsiSubstitutor substitutor; + if (checkBases && !aClass.equals(superClass)) { + substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); + LOG.assertTrue(substitutor != null); + } + else { + substitutor = PsiSubstitutor.EMPTY; + } + final MethodSignature signature = method.getSignature(substitutor); + if (signature.equals(patternSignature)) { + methods.add(method); + if (stopOnFirst) + break; + } + } + return methods.toArray(new PsiMethod[methods.size()]); + } + + // ---------------------------------------------------------------------------------------- + + public static PsiClass findInnerByName(PsiClass aClass, String name, boolean checkBases) { + final PsiClass[] byMap = findByMap(aClass, name, checkBases, PsiClass.class); + return byMap.length >= 1 ? byMap[0] : null; + } + + private static final T[] emptyArrayByType(Class type){ + if(type.isAssignableFrom(PsiMethod.class)) return (T[])PsiMethod.EMPTY_ARRAY; + if(type.isAssignableFrom(PsiField.class)) return (T[])PsiField.EMPTY_ARRAY; + if(type.isAssignableFrom(PsiClass.class)) return (T[])PsiClass.EMPTY_ARRAY; + + return (T[])ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + private static T[] findByMap(PsiClass aClass, String name, boolean checkBases, Class type) { + if(name == null) return emptyArrayByType(type); + + if (!checkBases) { + Object[] members = null; + if(type.isAssignableFrom(PsiMethod.class)){ + members = aClass.getMethods(); + } + else if(type.isAssignableFrom(PsiClass.class)){ + members = aClass.getInnerClasses(); + } + else if(type.isAssignableFrom(PsiField.class)){ + members = aClass.getFields(); + } + if(members == null) return emptyArrayByType(type); + + List list = new ArrayList(); + for (int i = 0; i < members.length; i++) { + final T method = (T)members[i]; + if(name.equals(method.getName())) list.add(method); + } + return list.toArray(emptyArrayByType(type)); + } + else { + final Map>> allMethodsMap = getMap(aClass, type); + final List> list = allMethodsMap.get(name); + if(list == null) return emptyArrayByType(type); + final List ret = new ArrayList(); + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair info = iterator.next(); + ret.add(info.getFirst()); + } + + return ret.toArray(emptyArrayByType(type)); + } + } + + public static List> getAllWithSubstitutorsByMap(PsiClass aClass, Class type) { + final Map>> allMap = getMap(aClass, type); + final List> pairs = allMap.get(ALL); + return pairs; + } + + private static T[] getAllByMap(PsiClass aClass, Class type) { + final Map>> allMap = getMap(aClass, type); + final List> pairs = allMap.get(ALL); + + if (pairs == null) { + LOG.error("pairs should be already computed. Wrong allMap: " + allMap); + } + + final List ret = new ArrayList(pairs.size()); + final Iterator> iterator = pairs.iterator(); + while (iterator.hasNext()) { + final Pair pair = iterator.next(); + ret.add(pair.getFirst()); + } + return ret.toArray(emptyArrayByType(type)); + } + + private static final String NULL = "Intellij-IDEA-NULL"; + private static final String ALL = "Intellij-IDEA-ALL"; + + private static void buildMap(PsiClass psiClass, + Map>> map, + final Class type) { + final Object data; + synchronized (PsiLock.LOCK) { + data = psiClass.getUserData(ALL_MAPS_BUILT_FLAG); + } + if (data != null) return; + if (map.containsKey(NULL)) return; + + final List> list = new ArrayList>(); + processDeclarationsInClassNotCached(psiClass, new FilterScopeProcessor(new ClassFilter(type), null, list) { + protected void add(PsiElement element, PsiSubstitutor substitutor) { + list.add(new Pair((T)element, substitutor)); + } + }, PsiSubstitutor.EMPTY, new HashSet(), null, psiClass); + + + synchronized (map) { + map.put(ALL, list); + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair info = iterator.next(); + final T element = info.getFirst(); + final String currentName = element.getName(); + List> elementsList = map.get(currentName); + if (elementsList == null) { + elementsList = new ArrayList>(1); + map.put(currentName, elementsList); + } + elementsList.add(info); + } + map.put(NULL, null); + } + } + + private static Map>> buildAllMaps(final PsiClass psiClass, Class type) { + if (!psiClass.isPhysical()) return getMapInner(psiClass, type); + final Object data; + synchronized (PsiLock.LOCK) { + data = psiClass.getUserData(ALL_MAPS_BUILT_FLAG); + } + + if (data != null) { + final Map>> mapInner = getMapInner(psiClass, type); + if (mapInner.isEmpty()) { + LOG.assertTrue(false); + } + return mapInner; + } + + final List> classes = new ArrayList>(); + final List> fields = new ArrayList>(); + final List> methods = new ArrayList>(); + + + final List list = new ArrayList(); + processDeclarationsInClassNotCached(psiClass, new FilterScopeProcessor(new OrFilter(new ElementFilter[]{ + new ClassFilter(PsiMethod.class), + new ClassFilter(PsiField.class), + new ClassFilter(PsiClass.class) + }), null, list) { + protected void add(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiMethod) { + methods.add(new Pair((PsiMethod)element, substitutor)); + } + else if (element instanceof PsiField) { + fields.add(new Pair((PsiField)element, substitutor)); + } + else if (element instanceof PsiClass) { + classes.add(new Pair((PsiClass)element, substitutor)); + } + } + }, PsiSubstitutor.EMPTY, new HashSet(), null, psiClass); + + synchronized (PsiLock.LOCK) { + //This is quite a critical doubled check. Actually, the first check might be removed +//But at least one check should be performed inside the non-cancelable action +//In order not to put uncomplete data to map + if (psiClass.getUserData(ALL_MAPS_BUILT_FLAG) != null) { + final Map>> mapInner = getMapInner(psiClass, type); + if (mapInner.isEmpty()) { + LOG.assertTrue(false); + } + return mapInner; + } + final Map>> classesMap = getMapInner(psiClass, PsiClass.class); + final Map>> fieldsMap = getMapInner(psiClass, PsiField.class); + final Map>> methodsMap = getMapInner(psiClass, PsiMethod.class); + if (classesMap.isEmpty()) { + generateMapByList(classesMap, classes); + } + ; + if (fieldsMap.isEmpty()) { + generateMapByList(fieldsMap, fields); + } + ; + if (methodsMap.isEmpty()) { + generateMapByList(methodsMap, methods); + } + ; + psiClass.putUserData(ALL_MAPS_BUILT_FLAG, ""); + return getMapInner(psiClass, type); + } + } + + private static void generateMapByList(final Map>> map, + final List> list) { + LOG.assertTrue(list != null); + synchronized(map){ + map.put(ALL, list); + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair info = iterator.next(); + final T element = info.getFirst(); + final String currentName = element.getName(); + List> listByName = map.get(currentName); + if(listByName == null){ + listByName = new ArrayList>(1); + map.put(currentName, listByName); + } + listByName.add(info); + } + } + } + + private static Map>> getMap(final PsiClass psiClass, final Class type){ + return buildAllMaps(psiClass, type); + } + + private static Map>> getMapInner(final PsiClass psiClass, final Class type) { + if (!psiClass.isPhysical()) { + final Map>> hashMap = new HashMap>>(); + buildMap(psiClass, hashMap, type); + return hashMap; + } + final Map>> map; + synchronized (PsiLock.LOCK) { + Map>>, Runnable>> mapInClass = (Map>>, Runnable>>)psiClass.getUserData(MAP_IN_CLASS_KEY); + if (mapInClass == null) { + mapInClass = new HashMap>>, Runnable>>(); + psiClass.putUserData(MAP_IN_CLASS_KEY, mapInClass); + } + final String typeName = type.getName(); + final Pair>>, Runnable> value = mapInClass.get(typeName); + if (value == null) { + map = Collections.synchronizedMap(new HashMap>>()); + final Map>>, Runnable>> mapInClass1 = mapInClass; + final Runnable cleaner = new Runnable() { + public void run() { + synchronized (PsiLock.LOCK) { + psiClass.putUserData(ALL_MAPS_BUILT_FLAG, null); + mapInClass1.remove(typeName); + } + } + }; + mapInClass.put(typeName, new Pair>>, Runnable>(map, cleaner)); + PsiManagerImpl manager = (PsiManagerImpl)psiClass.getManager(); + manager.registerWeakRunnableToRunOnChange(cleaner); + } + else { + map = value.first; + } + ; + } + return map; + } + + public static boolean processDeclarationsInClass(PsiClass aClass, PsiScopeProcessor processor, + PsiSubstitutor substitutor, Set visited, PsiElement last, + PsiElement place) { + if (visited.contains(aClass)) return true; + if (last instanceof PsiTypeParameterList) return true; //TypeParameterList doesn't see our declarations + final Object data; + synchronized (PsiLock.LOCK) { + data = aClass.getUserData(ALL_MAPS_BUILT_FLAG); + } + if (last instanceof PsiReferenceList && data == null || aClass instanceof PsiTypeParameter) { + return processDeclarationsInClassNotCached(aClass, processor, substitutor, visited, last, place); + } + + final NameHint nameHint = processor.getHint(NameHint.class); + final ElementClassHint classHint = processor.getHint(ElementClassHint.class); + + if (nameHint != null) { + if (classHint == null || classHint.shouldProcess(PsiField.class)) { + final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(), false); + if (fieldByName != null) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass); + if (!processor.execute(fieldByName, substitutor)) return false; + } + else { + final Map>> allFieldsMap = getMap(aClass, PsiField.class); + + final List> list = allFieldsMap.get(nameHint.getName()); + if (list != null) { + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair candidate = iterator.next(); + PsiField candidateField = candidate.getFirst(); + PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass, + substitutor); + + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass()); + if (!processor.execute(candidateField, finalSubstitutor)) return false; + } + } + } + } + if (classHint == null || classHint.shouldProcess(PsiClass.class)) { + if (last != null && last.getParent() == aClass) { + // Parameters + final PsiTypeParameterList list = aClass.getTypeParameterList(); + if (list != null && !PsiScopesUtil.processScope(list, processor, substitutor, last, place)) return false; + } + if (!(last instanceof PsiReferenceList) && !(last instanceof PsiModifierList)) { + final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(), false); + if (classByName != null) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass); + if (!processor.execute(classByName, substitutor)) return false; + } + else { + final Map>> allClassesMap = getMap(aClass, PsiClass.class); + + final List> list = allClassesMap.get(nameHint.getName()); + if (list != null) { + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair candidate = iterator.next(); + final PsiElement psiClass = candidate.getFirst().getParent(); + if (psiClass instanceof PsiClass) { + PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(((PsiClass)psiClass), candidate.getSecond(), aClass, + substitutor); + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, psiClass); + if (!processor.execute(candidate.getFirst(), finalSubstitutor)) return false; + } + } + } + } + } + } + if (classHint == null || classHint.shouldProcess(PsiMethod.class)) { + if (processor instanceof MethodResolverProcessor) { + final MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor; + if (methodResolverProcessor.isConstructor()) { + final PsiMethod[] constructors = aClass.getConstructors(); + methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass); + for (int i = 0; i < constructors.length; i++) { + if (!methodResolverProcessor.execute(constructors[i], substitutor)) return false; + } + return true; + } + } + final Map>> allMethodsMap = getMap(aClass, PsiMethod.class); + final List> list = allMethodsMap.get(nameHint.getName()); + if (list != null) { + final Iterator> iterator = list.iterator(); + while (iterator.hasNext()) { + final Pair candidate = iterator.next(); + PsiMethod candidateMethod = candidate.getFirst(); + PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateMethod.getContainingClass(), candidate.getSecond(), aClass, + substitutor); + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidate.getFirst().getContainingClass()); + if (!processor.execute(candidate.getFirst(), finalSubstitutor)) return false; + } + } + } + return true; + } + + return processDeclarationsInClassNotCached(aClass, processor, substitutor, visited, last, place); + } + + private static PsiSubstitutor obtainFinalSubstitutor(PsiClass candidateClass, PsiSubstitutor candidateSubstitutor, PsiClass aClass, + PsiSubstitutor substitutor) { + PsiElementFactory elementFactory = candidateClass.getManager().getElementFactory(); + if (PsiUtil.isRawSubstitutorForClass(aClass, substitutor)) { + return candidateSubstitutor.merge(elementFactory.createRawSubstitutor(candidateClass)); + } + + final PsiType containingType = elementFactory.createType(candidateClass, candidateSubstitutor); + PsiType type = substitutor.substitute(containingType); + if (!(type instanceof PsiClassType)) return candidateSubstitutor; + PsiSubstitutor finalSubstitutor = ((PsiClassType)type).resolveGenerics().getSubstitutor(); + return finalSubstitutor; + } + + public static boolean processDeclarationsInClassNotCached(PsiClass aClass, PsiScopeProcessor processor, + PsiSubstitutor substitutor, Set visited, PsiElement last, + PsiElement place) { + if (visited.contains(aClass)) return true; + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass); + final ElementClassHint classHint = processor.getHint(ElementClassHint.class); + final NameHint nameHint = processor.getHint(NameHint.class); + + + PsiManager manager = aClass.getManager(); + if (classHint == null || classHint.shouldProcess(PsiField.class)) { + if (nameHint != null) { + final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(), false); + if(fieldByName != null) + if(!processor.execute(fieldByName, substitutor)) return false; + } + else { + final PsiField[] fields = aClass.getFields(); + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + if (!processor.execute(field, substitutor)) return false; + } + } + + final PsiField[] introducedFields = manager.getAspectManager().getIntroducedFields(aClass); + for (int i = 0; i < introducedFields.length; i++) { + if (!processor.execute(introducedFields[i], substitutor)) return false; + } + } + + if (classHint == null || classHint.shouldProcess(PsiMethod.class)) { + if (nameHint != null) { + final PsiMethod[] methods = aClass.findMethodsByName(nameHint.getName(), false); + for (int i = 0; methods != null && i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (!processor.execute(method, substitutor)) return false; + } + } + else { + final PsiMethod[] methods = aClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (!processor.execute(method, substitutor)) return false; + } + } + + PsiMethod[] introducedMethods = manager.getAspectManager().getIntroducedMethods(aClass); + for (int i = 0; i < introducedMethods.length; i++) { + if (!processor.execute(introducedMethods[i], substitutor)) return false; + } + } + + if (classHint == null || classHint.shouldProcess(PsiClass.class)) { + if (last != null && last.getParent() == aClass) { + // Parameters + final PsiTypeParameterList list = aClass.getTypeParameterList(); + if (list != null && !PsiScopesUtil.processScope(list, processor, PsiSubstitutor.EMPTY, last, place)) return false; + } + + if (!(last instanceof PsiReferenceList) && !(last instanceof PsiModifierList)) { + // Inners + if(nameHint != null){ + final PsiClass inner = aClass.findInnerClassByName(nameHint.getName(), false); + if(inner != null) + if(!processor.execute(inner, substitutor)) return false; + } + else{ + final PsiClass[] inners = aClass.getInnerClasses(); + for (int i = 0; i < inners.length; i++) { + final PsiClass inner = inners[i]; + if (!processor.execute(inner, substitutor)) return false; + } + } + } + } + + visited.add(aClass); + if (!(last instanceof PsiReferenceList)) { + if (!processSuperTypes( + aClass.getSuperTypes(), + processor, visited, last, place, aClass, substitutor)) { + return false; + } + } + return true; + } + + private static boolean processSuperTypes(final PsiClassType[] superTypes, PsiScopeProcessor processor, + Set visited, PsiElement last, PsiElement place, PsiClass aClass, PsiSubstitutor substitutor) { + if (superTypes == null) return true; + for (int i = 0; i < superTypes.length; i++) { + final PsiClassType superType = superTypes[i]; + if(superType == null) continue; + final PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics(); + PsiClass superClass = superTypeResolveResult.getElement(); + if (superClass == null) continue; + PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass, substitutor); + if (!processDeclarationsInClass(superClass, processor, finalSubstitutor, visited, last, place)) { + return false; + } + } + return true; + } + + public static PsiClass getSuperClass(PsiClass psiClass) { + PsiManager manager = psiClass.getManager(); + GlobalSearchScope resolveScope = psiClass.getResolveScope(); + + if (psiClass.isInterface()) { + return manager.findClass("java.lang.Object", resolveScope); + } + if (psiClass.isEnum()) { + return manager.findClass("java.lang.Enum", resolveScope); + } + + if (psiClass instanceof PsiAnonymousClass) { + PsiClassType baseClassReference = ((PsiAnonymousClass)psiClass).getBaseClassType(); + PsiClass baseClass = baseClassReference.resolve(); + if (baseClass == null || baseClass.isInterface()) return manager.findClass("java.lang.Object", resolveScope); + return baseClass; + } + + if ("java.lang.Object".equals(psiClass.getQualifiedName())) return null; + + PsiReferenceList[] introducedExtendsList = new PsiReferenceList[1]; + PsiReferenceList[] introducedImplementsList = new PsiReferenceList[1]; + + manager.getAspectManager().getIntroducedParents(psiClass, introducedExtendsList, + introducedImplementsList); + final PsiClassType[] referenceElements; + if (introducedExtendsList[0] != null) { + referenceElements = introducedExtendsList[0].getReferencedTypes(); + } + else { + referenceElements = psiClass.getExtendsListTypes(); + } + + if (referenceElements.length == 0) return manager.findClass("java.lang.Object", resolveScope); + + PsiClass psiResoved = referenceElements[0].resolve(); + return psiResoved == null ? manager.findClass("java.lang.Object", resolveScope) : psiResoved; + } + + public static PsiClass[] getSupers(PsiClass psiClass) { + final PsiClass[] supers = getSupersInner(psiClass); + for (int i = 0; i < supers.length; i++) { + final PsiClass aSuper = supers[i]; + LOG.assertTrue(aSuper != null);/// + } + return supers; + } + + private static PsiClass[] getSupersInner(PsiClass psiClass) { + PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes(); + PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes(); + + PsiReferenceList[] introducedExtendsList = new PsiReferenceList[1]; + PsiReferenceList[] introducedImplementsList = new PsiReferenceList[1]; + + psiClass.getManager().getAspectManager().getIntroducedParents(psiClass, introducedExtendsList, + introducedImplementsList); + if (introducedExtendsList[0] != null) { + extendsListTypes = introducedExtendsList[0].getReferencedTypes(); + } + if (introducedImplementsList[0] != null) { + implementsListTypes = introducedImplementsList[0].getReferencedTypes(); + } + + if (psiClass.isInterface()) { + return resolveClassReferenceList(extendsListTypes, + psiClass.getManager(), psiClass.getResolveScope(), true); + } + + if (psiClass instanceof PsiAnonymousClass) { + PsiAnonymousClass psiAnonymousClass = (PsiAnonymousClass)psiClass; + PsiClassType baseClassReference = psiAnonymousClass.getBaseClassType(); + PsiClass baseClass = baseClassReference.resolve(); + if (baseClass != null) { + if (baseClass.isInterface()) { + PsiClass objectClass = psiClass.getManager().findClass("java.lang.Object", psiClass.getResolveScope()); + return objectClass != null ? new PsiClass[]{objectClass, baseClass} : new PsiClass[]{baseClass}; + } + return new PsiClass[]{baseClass}; + } + + PsiClass objectClass = psiClass.getManager().findClass("java.lang.Object", psiClass.getResolveScope()); + return objectClass != null ? new PsiClass[]{objectClass} : PsiClass.EMPTY_ARRAY; + } + else if (psiClass instanceof PsiTypeParameter) { + PsiClassType[] referencedTypes = extendsListTypes; + if (referencedTypes.length == 0) { + final PsiClass objectClass = psiClass.getManager().findClass("java.lang.Object", psiClass.getResolveScope()); + return objectClass != null ? new PsiClass[]{objectClass} : PsiClass.EMPTY_ARRAY; + } + return resolveClassReferenceList(referencedTypes, psiClass.getManager(), + psiClass.getResolveScope(), false); + } + + PsiClass[] interfaces = resolveClassReferenceList(implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); + + PsiClass superClass = getSuperClass(psiClass); + if (superClass == null) return interfaces; + PsiClass[] types = new PsiClass[interfaces.length + 1]; + types[0] = superClass; + System.arraycopy(interfaces, 0, types, 1, interfaces.length); + + return types; + } + + public static PsiClassType[] getSuperTypes(PsiClass psiClass) { + if (psiClass instanceof PsiAnonymousClass) { + PsiClassType baseClassType = ((PsiAnonymousClass)psiClass).getBaseClassType(); + PsiClass baseClass = baseClassType.resolve(); + if (baseClass == null || !baseClass.isInterface()) { + return new PsiClassType[]{baseClassType}; + } + else { + PsiClass objectClass = psiClass.getManager().findClass("java.lang.Object", psiClass.getResolveScope()); + if (objectClass != null) { + return new PsiClassType[]{new PsiImmediateClassType(objectClass, PsiSubstitutor.EMPTY), baseClassType}; + } + else { + return new PsiClassType[]{baseClassType}; + } + } + } + + List result = new ArrayList(); + + PsiClassType[] extendsTypes = psiClass.getExtendsListTypes(); + result.addAll(Arrays.asList(extendsTypes)); + boolean noExtends = extendsTypes.length == 0; + + result.addAll(Arrays.asList(psiClass.getImplementsListTypes())); + + final PsiReferenceList[] extendsListOut = new PsiReferenceList[1]; + final PsiReferenceList[] implementsListOut = new PsiReferenceList[1]; + psiClass.getManager().getAspectManager().getIntroducedParents(psiClass, extendsListOut, + implementsListOut); + noExtends = noExtends && extendsListOut[0] == null; + addReferenceTypes(extendsListOut[0], result); + addReferenceTypes(implementsListOut[0], result); + + + if (noExtends) { + PsiManager manager = psiClass.getManager(); + PsiClass objectClass = manager.findClass("java.lang.Object", psiClass.getResolveScope()); + if (objectClass != null && !manager.areElementsEquivalent(psiClass, objectClass)) { + result.add(0, manager.getElementFactory().createType(objectClass)); + } + } + + return result.toArray(new PsiClassType[result.size()]); + } + + private static PsiClassType getAnnotationSuperType(PsiClass psiClass) { + return psiClass.getManager().getElementFactory().createTypeByFQClassName("java.lang.annotation.Annotation", psiClass.getResolveScope()); + } + + private static PsiClassType getEnumSuperType(PsiClass psiClass) { + PsiClassType superType; + final PsiManager manager = psiClass.getManager(); + final PsiClass enumClass = manager.findClass("java.lang.Enum", psiClass.getResolveScope()); + if (enumClass == null) { + try { + superType = (PsiClassType)manager.getElementFactory().createTypeFromText("java.lang.Enum", null); + } + catch (IncorrectOperationException e) { + superType = null; + } + } + else { + final PsiTypeParameter[] typeParameters = enumClass.getTypeParameters(); + if (typeParameters.length != 1) { + superType = new PsiImmediateClassType(enumClass, PsiSubstitutor.EMPTY); + } + else { + superType = new PsiImmediateClassType(enumClass, PsiSubstitutor.EMPTY.put( + typeParameters[0], manager.getElementFactory().createType(psiClass) + )); + } + } + return superType; + } + + private static void addReferenceTypes(final PsiReferenceList referenceList, List result) { + if (referenceList != null) { + final PsiClassType[] referenceElements = referenceList.getReferencedTypes(); + for (int i = 0; i < referenceElements.length; i++) { + final PsiClassType referenceElement = referenceElements[i]; + LOG.assertTrue(referenceElement != null); + result.add(referenceElement); + } + } + } + + public static PsiClass[] getInterfaces(PsiTypeParameter typeParameter) { + final ArrayList result = new ArrayList(); + final PsiClassType[] referencedTypes = typeParameter.getExtendsListTypes(); + for (int i = 0; i < referencedTypes.length; i++) { + PsiClassType referencedType = referencedTypes[i]; + final PsiClass psiClass = referencedType.resolve(); + if (psiClass != null && psiClass.isInterface()) { + result.add(psiClass); + } + } + return result.toArray(new PsiClass[result.size()]); + } + + public static PsiClass[] getInterfaces(PsiClass psiClass) { + PsiReferenceList[] introducedExtendsList = new PsiReferenceList[1]; + PsiReferenceList[] introducedImplementsList = new PsiReferenceList[1]; + + psiClass.getManager().getAspectManager().getIntroducedParents(psiClass, introducedExtendsList, + introducedImplementsList); + final PsiClassType[] extendsListTypes; + if (introducedExtendsList[0] == null) { + extendsListTypes = psiClass.getExtendsListTypes(); + } + else { + extendsListTypes = introducedExtendsList[0].getReferencedTypes(); + } + final PsiClassType[] implementsListTypes; + if (introducedImplementsList[0] == null) { + implementsListTypes = psiClass.getImplementsListTypes(); + } + else { + implementsListTypes = introducedImplementsList[0].getReferencedTypes(); + } + + + if (psiClass.isInterface()) { + return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); + } + + if (psiClass instanceof PsiAnonymousClass) { + PsiClassType baseClassReference = ((PsiAnonymousClass)psiClass).getBaseClassType(); + PsiClass baseClass = baseClassReference.resolve(); + if (baseClass != null && baseClass.isInterface()) return new PsiClass[]{baseClass}; + return PsiClass.EMPTY_ARRAY; + } + + return resolveClassReferenceList(implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); + } + + private static PsiClass[] resolveClassReferenceList(final PsiClassType[] listOfTypes, + final PsiManager manager, final GlobalSearchScope resolveScope, boolean includeObject) { + PsiClass objectClass = manager.findClass("java.lang.Object", resolveScope); + if (objectClass == null) includeObject = false; + if (listOfTypes == null || listOfTypes.length == 0) { + if (includeObject) return new PsiClass[]{objectClass}; + return PsiClass.EMPTY_ARRAY; + } + + int referenceCount = listOfTypes.length; + if (includeObject) referenceCount++; + + PsiClass[] resolved = new PsiClass[referenceCount]; + int resolvedCount = 0; + + if (includeObject) resolved[resolvedCount++] = objectClass; + for (int i = 0; i < listOfTypes.length; i++) { + PsiClassType reference = listOfTypes[i]; + PsiClass refResolved = reference.resolve(); + if (refResolved != null) resolved[resolvedCount++] = refResolved; + } + + if (resolvedCount < referenceCount) { + PsiClass[] shorter = new PsiClass[resolvedCount]; + System.arraycopy(resolved, 0, shorter, 0, resolvedCount); + resolved = shorter; + } + + return resolved; + } + + public static List> findMethodsAndTheirSubstitutorsByName(PsiClass psiClass, String name, boolean checkBases) { + if(!checkBases){ + final PsiMethod[] methodsByName = psiClass.findMethodsByName(name, false); + final List> ret = new ArrayList>(methodsByName.length); + for (int i = 0; i < methodsByName.length; i++) { + final PsiMethod method = methodsByName[i]; + ret.add(new Pair(method, PsiSubstitutor.EMPTY)); + } + return ret; + } + final Map>> map = getMap(psiClass, PsiMethod.class); + final List> list = map.get(name); + return list == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(list); + } + + public static PsiTypeParameter[] getTypeParameters(PsiClass psiClass) { + final PsiTypeParameterList typeParameterList = psiClass.getTypeParameterList(); + if (typeParameterList != null) { + return typeParameterList.getTypeParameters(); + } + else { + return PsiTypeParameter.EMPTY_ARRAY; + } + } + + public static PsiClassType[] getExtendsListTypes(PsiClass psiClass) { + if (psiClass.isEnum()) { + return new PsiClassType[]{getEnumSuperType(psiClass)}; + } else if (psiClass.isAnnotationType()) { + return new PsiClassType[]{getAnnotationSuperType(psiClass)}; + } + final PsiReferenceList extendsList = psiClass.getExtendsList(); + if (extendsList != null) { + return extendsList.getReferencedTypes(); + } + return PsiClassType.EMPTY_ARRAY; + } + + public static PsiClassType[] getImplementsListTypes(PsiClass psiClass) { + final PsiReferenceList extendsList = psiClass.getImplementsList(); + if (extendsList != null) { + return extendsList.getReferencedTypes(); + } + return PsiClassType.EMPTY_ARRAY; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiConstantEvaluationHelperImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiConstantEvaluationHelperImpl.java new file mode 100644 index 00000000000..217ff58f8b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiConstantEvaluationHelperImpl.java @@ -0,0 +1,27 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.PsiConstantEvaluationHelper; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.ConstantExpressionUtil; + +import java.util.Set; + +/** + * @author ven + */ +public class PsiConstantEvaluationHelperImpl extends PsiConstantEvaluationHelper { + public Object computeConstantExpression(PsiExpression expression) { + return computeConstantExpression(expression, false); + } + + public Object computeConstantExpression(PsiExpression expression, boolean throwExceptionOnOverflow) { + return ConstantExpressionEvaluator.computeConstantExpression(expression, null, throwExceptionOnOverflow); + } + + public static Object computeCastTo(PsiExpression expression, PsiType castTo, Set visitedVars) { + Object value = ConstantExpressionEvaluator.computeConstantExpression(expression, visitedVars, false); + if(value == null) return null; + return ConstantExpressionUtil.computeCastTo(value, castTo); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiDocumentManagerImpl.java new file mode 100644 index 00000000000..6a275e35e42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -0,0 +1,469 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.psi.*; +import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.text.BlockSupportImpl; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.text.BlockSupport; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.text.CharArrayUtil; + +import javax.swing.*; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +//todo listen & notifyListeners readonly events? + +public class PsiDocumentManagerImpl extends PsiDocumentManager implements ProjectComponent, DocumentListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiDocumentManagerImpl"); + + private final Project myProject; + private PsiManager myPsiManager; + private final Key KEY_PSI_FILE = Key.create("KEY_PSI_FILE"); + private final Key> KEY_DOCUMENT = Key.create("KEY_DOCUMENT"); + private final Key KEY_TEXT_BLOCK = Key.create("KEY_TEXT_BLOCK"); + private Set myUncommittedDocuments = new HashSet(); + private boolean myProcessDocumentEvents = true; + private SmartPointerManagerImpl mySmartPointerManager; + private BlockSupportImpl myBlockSupport; + private boolean myIsCommitInProgress; + + private List myListeners = new ArrayList(); + private Listener[] myCachedListeners = null; + + public PsiDocumentManagerImpl(Project project, + PsiManager psiManager, + SmartPointerManager smartPointerManager, + BlockSupport blockSupport, EditorFactory editorFactory) { + myProject = project; + + myPsiManager = psiManager; + mySmartPointerManager = (SmartPointerManagerImpl)smartPointerManager; + myBlockSupport = (BlockSupportImpl)blockSupport; + myPsiManager.addPsiTreeChangeListener(new PsiToDocumentSynchronizer(this, mySmartPointerManager)); + editorFactory.getEventMulticaster().addDocumentListener(this); + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "PsiDocumentManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(this); + } + + public PsiFile getPsiFile(Document document) { + PsiFile psiFile = getCachedPsiFile(document); + + if (psiFile == null){ + final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + if (virtualFile == null || !virtualFile.isValid()) return null; + psiFile = getPsiFile(virtualFile); + if (psiFile == null) return null; + + psiFile.setModificationStamp(document.getModificationStamp()); + fireFileCreated(document, psiFile); + } + + return psiFile; + } + + + public PsiFile getCachedPsiFile(Document document) { + PsiFile file = document.getUserData(KEY_PSI_FILE); + if (file != null) { + /* TODO[max, lex]: This is right code. Disabled for now since Lex wants to get event invalid files through this hole. + if (!file.isValid()) { + document.putUserData(KEY_PSI_FILE, null); + return null; + } + */ + return file; + } + + final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + if (virtualFile == null || !virtualFile.isValid()) return null; + PsiFile psiFile = getCachedPsiFile(virtualFile); + return psiFile; + } + + protected PsiFile getCachedPsiFile(VirtualFile virtualFile) { + return ((PsiManagerImpl)myPsiManager).getFileManager().getCachedPsiFile(virtualFile); + } + + protected PsiFile getPsiFile(VirtualFile virtualFile) { + return ((PsiManagerImpl)myPsiManager).getFileManager().findFile(virtualFile); + } + + public Document getDocument(PsiFile file) { + if (file instanceof PsiBinaryFile) return null; + + Document document = getCachedDocument(file); + if (document != null) return document; + + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null){ + document = FileDocumentManager.getInstance().getDocument(virtualFile); + } + else{ + if (!file.isPhysical()) return null; + document = createDocument(file.getText()); + ((DocumentEx)document).setModificationStamp(file.getModificationStamp()); + + file.putUserData(KEY_DOCUMENT, new WeakReference(document)); + document.putUserData(KEY_PSI_FILE, file); + } + + fireDocumentCreated(document, file); + + return document; + } + + private static Document createDocument(String text) { + return EditorFactory.getInstance().createDocument(text); + } + + public Document getCachedDocument(PsiFile file) { + VirtualFile vFile = file.getVirtualFile(); + if (vFile != null){ + return FileDocumentManager.getInstance().getCachedDocument(vFile); + } + else{ + WeakReference reference = file.getUserData(KEY_DOCUMENT); + if (reference == null) return null; + return reference.get(); + } + } + + public void commitAllDocuments() { + if (myUncommittedDocuments.isEmpty()) return; + + //long time1 = System.currentTimeMillis(); + + final Document[] documents = getUncommittedDocuments(); + for(int i = 0; i < documents.length; i++){ + Document document = documents[i]; + commitDocument(document); + } + + //long time2 = System.currentTimeMillis(); + //Statistics.commitTime += (time2 - time1); + } + + public void commitDocument(final Document document) { + ApplicationManager.getApplication().runWriteAction( + new CommitToPsiFileAction() { + public void run() { + if (!isUncommited(document)) return; + myUncommittedDocuments.remove(document); + + final PsiFile file = getCachedPsiFile(document); + if (file == null || !file.isValid()) return; + /* This is right code. Commented out due TODO in getCachedPsiFile() + if (file == null) return; + LOG.assertTrue(file.isValid()); + */ + + commit(document, file); + } + } + ); + } + + public T commitAndRunReadAction(final Computable computation) { + final Ref ref = Ref.create(null); + commitAndRunReadAction(new Runnable() { + public void run() { + ref.set(computation.compute()); + } + }); + return ref.get(); + } + + public void commitAndRunReadAction(final Runnable runnable) { + final Application application = ApplicationManager.getApplication(); + if (SwingUtilities.isEventDispatchThread()){ + commitAllDocuments(); + runnable.run(); + } + else{ + LOG.assertTrue(!ApplicationManager.getApplication().isReadAccessAllowed(), "Don't call commitAndRunReadAction inside ReadAction it may cause a deadlock."); + + final Semaphore s1 = new Semaphore(); + final Semaphore s2 = new Semaphore(); + final boolean[] commited = {false}; + + application.runReadAction( + new Runnable() { + public void run() { + if (myUncommittedDocuments.isEmpty()){ + runnable.run(); + commited[0] = true; + } + else{ + s1.down(); + s2.down(); + final Runnable commitRunnable = new Runnable() { + public void run() { + commitAllDocuments(); + s1.up(); + s2.waitFor(); + } + }; + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator == null) { + ApplicationManager.getApplication().invokeLater(commitRunnable); + } + else { + ApplicationManager.getApplication().invokeLater(commitRunnable, progressIndicator.getModalityState()); + } + } + } + } + ); + + if (!commited[0]){ + s1.waitFor(); + application.runReadAction( + new Runnable() { + public void run() { + s2.up(); + runnable.run(); + } + } + ); + } + } + } + + private Listener[] getCachedListeners() { + synchronized (myListeners) { + if (myCachedListeners == null) { + myCachedListeners = myListeners.toArray(new Listener[myListeners.size()]); + } + return myCachedListeners; + } + } + + public void addListener(Listener listener) { + synchronized (myListeners) { + myListeners.add(listener); + myCachedListeners = null; + } + } + + public void removeListener(Listener listener) { + synchronized (myListeners) { + myListeners.remove(listener); + myCachedListeners = null; + } + } + + protected void fireDocumentCreated(Document document, PsiFile file) { + Listener[] listeners = getCachedListeners(); + for (int i = 0; i < listeners.length; i++) { + Listener listener = listeners[i]; + listener.documentCreated(document, file); + } + } + + protected void fireFileCreated(Document document, PsiFile file) { + Listener[] listeners = getCachedListeners(); + for (int i = 0; i < listeners.length; i++) { + Listener listener = listeners[i]; + listener.fileCreated(file, document); + } + } + + protected void commit(final Document document, final PsiFile file) { + document.putUserData(TEMP_TREE_IN_DOCUMENT_KEY, null); + + TextBlock textBlock = getTextBlock(document); + if (textBlock.isEmpty()) return; + + myIsCommitInProgress = true; + try{ + if (file.getModificationStamp() != document.getModificationStamp()){ + if (mySmartPointerManager != null) { // can be true in "mock" tests + mySmartPointerManager.synchronizePointers(file); + } + + CompositeElement treeElement = ((PsiFileImpl)file).calcTreeElement(); // Lock up in local variable so gc wont collect it. + textBlock = getTextBlock(document); + if (textBlock.isEmpty()) return; // if tree was just loaded above textBlock will be cleared by contentsLoaded + + char[] chars = CharArrayUtil.fromSequence(document.getCharsSequence()); + int startOffset = textBlock.getStartOffset(); + int endOffset = textBlock.getTextEndOffset(); + final int psiEndOffset = textBlock.getPsiEndOffset(); + //String s = new String(chars, startOffset, endOffset - startOffset); + //myBlockSupport.reparseRangeInternal(file, startOffset, psiEndOffset, s); + myBlockSupport.reparseRange(file, startOffset, psiEndOffset, endOffset - psiEndOffset, chars); + //checkConsistency(file, document); + file.setModificationStamp(document.getModificationStamp()); + } + + textBlock.clear(); + } + finally{ + myIsCommitInProgress = false; + } + + //mySmartPointerManager.synchronizePointers(file); + } + + public Document[] getUncommittedDocuments() { + return myUncommittedDocuments.toArray(new Document[myUncommittedDocuments.size()]); + } + + public boolean isUncommited(Document document) { + return myUncommittedDocuments.contains(document); + } + + public boolean hasUncommitedDocuments() { + if (myIsCommitInProgress) return false; + return !myUncommittedDocuments.isEmpty(); + } + + public void setProcessDocumentEvents(boolean processDocumentEvents) { + myProcessDocumentEvents = processDocumentEvents; + } + + private final Key TEMP_TREE_IN_DOCUMENT_KEY = Key.create("TEMP_TREE_IN_DOCUMENT_KEY"); + + public void beforeDocumentChange(DocumentEvent event) { + if (!myProcessDocumentEvents) return; + + final Document document = event.getDocument(); + final PsiFile file = getCachedPsiFile(document); + if (file == null) return; + + if (file instanceof PsiFileImpl){ + myIsCommitInProgress = true; + try{ + PsiFileImpl psiFile = (PsiFileImpl)file; + // tree should be initialized and be kept until commit + document.putUserData(TEMP_TREE_IN_DOCUMENT_KEY, psiFile.calcTreeElement()); + } + finally{ + myIsCommitInProgress = false; + } + } + if (mySmartPointerManager != null) { // can be false in "mock" tests + mySmartPointerManager.fastenBelts(file); + } + } + + public void documentChanged(DocumentEvent event) { + if (!myProcessDocumentEvents) return; + + final Document document = event.getDocument(); + final PsiFile file = getCachedPsiFile(document); + if (file == null) return; + + if (mySmartPointerManager != null) { // can be false in "mock" tests + mySmartPointerManager.unfastenBelts(file); + } + + getTextBlock(document).documentChanged(event); + myUncommittedDocuments.add(document); + + if (ApplicationManager.getApplication().getCurrentWriteAction(PsiExternalChangeAction.class) != null){ + commitDocument(document); + } + } + + public TextBlock getTextBlock(Document document) { + TextBlock textBlock = document.getUserData(KEY_TEXT_BLOCK); + if (textBlock == null){ + textBlock = new TextBlock(); + document.putUserData(KEY_TEXT_BLOCK, textBlock); + } + + return textBlock; + } + + public static void checkConsistency(PsiFile psiFile, Document document) { + //todo hack + if (psiFile.getVirtualFile() == null) return; + + CharSequence editorText = document.getCharsSequence(); + int documentLength = document.getTextLength(); + if (psiFile.textMatches(editorText)) { + LOG.assertTrue(psiFile.getTextLength() == documentLength); + LOG.debug("Consistent OK: length=" + documentLength + "; file=" + psiFile.getName() + ":" + psiFile.getClass()); + return; + } + + char[] fileText = psiFile.textToCharArray(); + LOG.error("File text mismatch after reparse. File length="+fileText.length+"; Doc length="+documentLength); + int i = 0; + for(; i < documentLength; i++){ + if (i >= fileText.length){ + LOG.info("editorText.length > psiText.length i=" + i); + break; + } + if (editorText.charAt(i) != fileText[i]){ + LOG.info("first unequal char i=" + i); + break; + } + } + LOG.info("*********************************************"); + if (i <= 500){ + LOG.info("Equal part:" + editorText.subSequence(0, i)); + } + else{ + LOG.info("Equal part start:\n" + editorText.subSequence(0, 200)); + LOG.info("................................................"); + LOG.info("................................................"); + LOG.info("................................................"); + LOG.info("Equal part end:\n" + editorText.subSequence(i - 200, i)); + } + LOG.info("*********************************************"); + LOG.info("Editor Text tail:\n" + editorText.subSequence(i, Math.min(i + 300, documentLength))); + LOG.info("*********************************************"); + LOG.info("Psi Text tail:\n" + new String(fileText, i, Math.min(i + 300, fileText.length) - i)); + LOG.info("*********************************************"); + document.replaceString(0, documentLength, psiFile.getText()); + } + + public void contentsLoaded(PsiFileImpl file) { + final Document document = getCachedDocument(file); + LOG.assertTrue(document != null); + getTextBlock(document).clear(); + } + + public boolean isDocumentCommited(Document doc) { + if (myIsCommitInProgress) return true; + return !myUncommittedDocuments.contains(doc); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementBase.java new file mode 100644 index 00000000000..d50e81669a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementBase.java @@ -0,0 +1,140 @@ + +package com.intellij.psi.impl; + +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +public abstract class PsiElementBase extends ElementBase implements PsiElement { + public PsiElement getFirstChild() { + PsiElement[] children = getChildren(); + if (children.length == 0) return null; + return children[0]; + } + + public PsiElement getLastChild() { + PsiElement[] children = getChildren(); + if (children.length == 0) return null; + return children[children.length - 1]; + } + + public PsiElement getNextSibling() { + return SharedPsiElementImplUtil.getNextSibling(this); + } + + public PsiElement getPrevSibling() { + return SharedPsiElementImplUtil.getPrevSibling(this); + } + + public void acceptChildren(PsiElementVisitor visitor) { + PsiElement[] children = getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + child.accept(visitor); + } + } + + public PsiReference getReference() { + return null; + } + + public PsiReference[] getReferences() { + return SharedPsiElementImplUtil.getReferences(this); + } + + public PsiReference findReferenceAt(int offset) { + return SharedPsiElementImplUtil.findReferenceAt(this, offset); + } + + public PsiElement addRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void deleteChildRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public boolean textContains(char c) { + return getText().indexOf(c) >= 0; + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + return true; + } + + public PsiElement getContext() { + return ResolveUtil.getContext(this); + } + + public PsiElement getNavigationElement() { + return this; + } + + public PsiElement getOriginalElement() { + return this; + } + + public final GlobalSearchScope getResolveScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getResolveScope(this); + } + + public GlobalSearchScope getUseScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getUseScope(this); + } + + public ItemPresentation getPresentation() { + return null; + } + + public void navigate(boolean requestFocus) { + EditSourceUtil.getDescriptor(getNavigationElement()).navigate(requestFocus); + } + + public boolean canNavigate() { + return true; + } + + public FileStatus getFileStatus() { + return FileStatus.NOT_CHANGED; + } + + public Project getProject() { + return getManager().getProject(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementFactoryImpl.java new file mode 100644 index 00000000000..283c35d92fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiElementFactoryImpl.java @@ -0,0 +1,805 @@ +package com.intellij.psi.impl; + +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.aspects.psi.PsiTypePattern; +import com.intellij.aspects.psi.PsiWithinPointcut; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.light.*; +import com.intellij.psi.impl.source.*; +import com.intellij.psi.impl.source.parsing.DeclarationParsing; +import com.intellij.psi.impl.source.parsing.ExpressionParsing; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.parsing.StatementParsing; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; +import com.intellij.xml.util.XmlTagTextUtil; +import com.intellij.xml.util.XmlUtil; + +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +public class PsiElementFactoryImpl implements PsiElementFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiElementFactoryImpl"); + + private PsiClass ARRAY_CLASS; + + private final PsiManagerImpl myManager; + private static final Map ourPrimitiveTypesMap = new HashMap(); + + static { + ourPrimitiveTypesMap.put("byte", (PsiPrimitiveType)PsiType.BYTE); + ourPrimitiveTypesMap.put("char", (PsiPrimitiveType)PsiType.CHAR); + ourPrimitiveTypesMap.put("double", (PsiPrimitiveType)PsiType.DOUBLE); + ourPrimitiveTypesMap.put("float", (PsiPrimitiveType)PsiType.FLOAT); + ourPrimitiveTypesMap.put("int", (PsiPrimitiveType)PsiType.INT); + ourPrimitiveTypesMap.put("long", (PsiPrimitiveType)PsiType.LONG); + ourPrimitiveTypesMap.put("short", (PsiPrimitiveType)PsiType.SHORT); + ourPrimitiveTypesMap.put("boolean", (PsiPrimitiveType)PsiType.BOOLEAN); + ourPrimitiveTypesMap.put("void", (PsiPrimitiveType)PsiType.VOID); + ourPrimitiveTypesMap.put("null", (PsiPrimitiveType)PsiType.NULL); + } + + private PsiJavaFile myDummyJavaFile; + + public PsiElementFactoryImpl(PsiManagerImpl manager) { + myManager = manager; + } + + public PsiJavaFile getDummyJavaFile() { + if (myDummyJavaFile == null) { + try { + myDummyJavaFile = createDummyJavaFile(""); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + return myDummyJavaFile; + } + + public PsiClass getArrayClass() { + if (ARRAY_CLASS == null) { + try { + if (myManager.getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) { + ARRAY_CLASS = createClassFromText( + "public class __Array__{\n public final int length; \n public Object clone(){}\n}", null); + } else { + ARRAY_CLASS = createClassFromText( + "public class __Array__{\n public final int length; \n public T[] clone(){}\n}", null); + } + CodeStyleManager.getInstance(myManager.getProject()).reformat(ARRAY_CLASS); + ARRAY_CLASS = ARRAY_CLASS.getInnerClasses()[0]; + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + return ARRAY_CLASS; + } + + public PsiClassType getArrayClassType(PsiType componentType) { + PsiClass arrayClass = getArrayClass(); + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + PsiTypeParameter[] typeParameters = arrayClass.getTypeParameters(); + if (typeParameters.length == 1) { + substitutor = substitutor.put(typeParameters[0], componentType); + } + + return createType(arrayClass, substitutor); + } + + public PsiClassType createType(PsiClass resolve, PsiSubstitutor substitutor) { + return new PsiImmediateClassType(resolve, substitutor); + } + + public PsiClass createClass(String name) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + String text = "public class " + name + "{ }"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiClass[] classes = aFile.getClasses(); + if (classes.length != 1) { + throw new IncorrectOperationException(); + } + return classes[0]; + } + + public PsiClass createInterface(String name) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + String text = "public interface " + name + "{ }"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiClass[] classes = aFile.getClasses(); + if (classes.length != 1) { + throw new IncorrectOperationException(); + } + return classes[0]; + } + + public PsiTypeElement createTypeElement(PsiType psiType) { + return new LightTypeElement(myManager, psiType); + } + + public PsiJavaCodeReferenceElement createReferenceElementByType(PsiClassType type) { + if (type instanceof PsiClassReferenceType) { + return ((PsiClassReferenceType)type).getReference(); + } + final CompositeElement treeElement = (CompositeElement)ChangeUtil.copyToElement(createTypeElement(type)); + new DummyHolder(myManager, treeElement, null); + final TreeElement referenceChild = treeElement.firstChild; + LOG.assertTrue(referenceChild.getElementType() == ElementType.JAVA_CODE_REFERENCE); + return (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(referenceChild); + } + + public PsiField createField(String name, PsiType type) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + if (type == PsiType.NULL) { + throw new IncorrectOperationException("Cannot create field with type \"\"."); + } + TreeElement typeCopy = ChangeUtil.copyToElement(createTypeElement(type)); + String text = "class _Dummy_ {private int " + name + ";}"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiClass aClass = aFile.getClasses()[0]; + PsiField field = aClass.getFields()[0]; + ChangeUtil.replaceChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(field), + SourceTreeToPsiMap.psiElementToTree(field.getTypeElement()), + typeCopy); + ChangeUtil.decodeInformation(SourceTreeToPsiMap.psiElementToTree(field)); + return (PsiField)CodeStyleManager.getInstance(myManager.getProject()).reformat(field); + } + + public PsiMethod createMethod(String name, PsiType returnType) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + if (returnType == PsiType.NULL) { + throw new IncorrectOperationException("Cannot create field with type \"\"."); + } + String text = "class _Dummy_ {\n public void " + name + "(){}\n}"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiClass aClass = aFile.getClasses()[0]; + PsiMethod method = aClass.getMethods()[0]; + method.getReturnTypeElement().replace(createTypeElement(returnType)); + return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method); + } + + public PsiMethod createConstructor() { + String text = "class _Dummy_ {\n public _Dummy_(){}\n}"; + try { + PsiJavaFile aFile = createDummyJavaFile(text); + PsiClass aClass = aFile.getClasses()[0]; + PsiMethod method = aClass.getMethods()[0]; + return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method); + } + catch (IncorrectOperationException e) { + LOG.assertTrue(false); + return null; + } + } + + public PsiClassInitializer createClassInitializer() throws IncorrectOperationException { + String text = "class _Dummy_ { {} }"; + final PsiJavaFile aFile = createDummyJavaFile(text); + final PsiClass aClass = aFile.getClasses()[0]; + final PsiClassInitializer psiClassInitializer = aClass.getInitializers()[0]; + return (PsiClassInitializer)CodeStyleManager.getInstance(myManager.getProject()).reformat(psiClassInitializer); + } + + public PsiParameter createParameter(String name, PsiType type) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + if (type == PsiType.NULL) { + throw new IncorrectOperationException("Cannot create field with type \"\"."); + } + final FileElement treeHolder = new DummyHolder(myManager, null).getTreeElement(); + final CompositeElement treeElement = DeclarationParsing.parseParameterText(myManager, ("int " + name).toCharArray(), treeHolder.getCharTable()); + TreeUtil.addChildren(treeHolder, treeElement); + + TreeElement typeElement = ChangeUtil.copyToElement(createTypeElement(type)); + ChangeUtil.replaceChild(treeElement, treeElement.findChildByRole(ChildRole.TYPE), typeElement); + ChangeUtil.decodeInformation(typeElement); + + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myManager.getProject()); + PsiParameter parameter = (PsiParameter)SourceTreeToPsiMap.treeElementToPsi(treeElement); + parameter.getModifierList().setModifierProperty(PsiModifier.FINAL, CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_PARAMETERS); + return (PsiParameter)codeStyleManager.reformat(parameter); + } + + public PsiCodeBlock createCodeBlock() { + try { + PsiCodeBlock block = createCodeBlockFromText("{}", null); + return (PsiCodeBlock)CodeStyleManager.getInstance(myManager.getProject()).reformat(block); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + public PsiClassType createType(PsiClass aClass) { + return new PsiImmediateClassType(aClass, aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : createRawSubstitutor(aClass)); + } + + public PsiClassType createType(PsiJavaCodeReferenceElement classReference) { + LOG.assertTrue(classReference != null); + return new PsiClassReferenceType(classReference); + } + + private static class TypeDetacher extends PsiTypeVisitor { + public static final TypeDetacher INSTANCE = new TypeDetacher(); + + public PsiType visitType(PsiType type) { + return type; + } + + public PsiType visitWildcardType(PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); + if (bound == null) return wildcardType; + else { + return PsiWildcardType.changeBound(wildcardType, bound.accept(this)); + } + } + + public PsiType visitArrayType(PsiArrayType arrayType) { + final PsiType componentType = arrayType.getComponentType(); + final PsiType detachedComponentType = componentType.accept(this); + if (detachedComponentType == componentType) return arrayType; // optimization + return detachedComponentType.createArrayType(); + } + + public PsiType visitClassType(PsiClassType classType) { + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass aClass = resolveResult.getElement(); + if (aClass == null) return classType; + final Iterator iterator = PsiUtil.typeParametersIterator(aClass); + final HashMap map = new HashMap(); + while (iterator.hasNext()) { + PsiTypeParameter parameter = iterator.next(); + PsiType type = resolveResult.getSubstitutor().substitute(parameter); + if (type != null) { + type = type.accept(this); + } + map.put(parameter, type); + } + return new PsiImmediateClassType(aClass, PsiSubstitutorImpl.createSubstitutor(map)); + } + } + + + public PsiType detachType(PsiType type) { + return type.accept(TypeDetacher.INSTANCE); + } + + public PsiSubstitutor createRawSubstitutor(PsiClass aClass) { + final Iterator iterator = PsiUtil.typeParametersIterator(aClass); + if (!iterator.hasNext()) return PsiSubstitutor.EMPTY; + Map substMap = new HashMap(); + while (iterator.hasNext()) { + substMap.put(iterator.next(), null); + } + return PsiSubstitutorImpl.createSubstitutor(substMap); + } + + public PsiSubstitutor createSubstitutor(Map map) { + return PsiSubstitutorImpl.createSubstitutor(map); + } + + public PsiPrimitiveType createPrimitiveType(String text) { + return ourPrimitiveTypesMap.get(text); + } + + public PsiClassType createTypeByFQClassName(String qName) { + return createTypeByFQClassName(qName, GlobalSearchScope.allScope(myManager.getProject())); + } + + public PsiClassType createTypeByFQClassName(String qName, GlobalSearchScope resolveScope) { + return new PsiClassReferenceType(createReferenceElementByFQClassName(qName, resolveScope)); + } + + public PsiJavaCodeReferenceElement createClassReferenceElement(PsiClass aClass) { + final String text; + if (aClass instanceof PsiAnonymousClass) { + text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText(); + } + else { + text = aClass.getName(); + } + return new LightClassReference(myManager, text, aClass); + } + + public PsiJavaCodeReferenceElement createReferenceElementByFQClassName(String qName, GlobalSearchScope resolveScope) { + String shortName = PsiNameHelper.getShortClassName(qName); + return new LightClassReference(myManager, shortName, qName, resolveScope); + } + + public PsiJavaCodeReferenceElement createFQClassNameReferenceElement(String qName, GlobalSearchScope resolveScope) { + return new LightClassReference(myManager, qName, qName, resolveScope); + } + + public PsiJavaCodeReferenceElement createPackageReferenceElement(PsiPackage aPackage) + throws IncorrectOperationException { + if (aPackage.getQualifiedName().length() == 0) { + throw new IncorrectOperationException("Cannot create reference to default package."); + } + return new LightPackageReference(myManager, aPackage); + } + + public PsiPackageStatement createPackageStatement(String name) throws IncorrectOperationException { + final PsiJavaFile javaFile = (PsiJavaFile)createFileFromText("dummy.java", "package " + name + ";"); + final PsiPackageStatement packageStatement = javaFile.getPackageStatement(); + return packageStatement; + } + + public XmlTag getAntImplicitDeclarationTag() throws IncorrectOperationException { + return createTagFromText( + ""); + } + + public PsiAnnotation createAnnotationFromText(String annotationText, PsiElement context) throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement annotationElement = DeclarationParsing.parseAnnotationFromText(myManager, annotationText, holderElement.getCharTable()); + if (annotationElement == null || annotationElement.getElementType() != ElementType.ANNOTATION) { + throw new IncorrectOperationException("Incorrect annotation \"" + annotationText + "\"."); + } + TreeUtil.addChildren(holderElement, annotationElement); + return (PsiAnnotation)SourceTreeToPsiMap.treeElementToPsi(annotationElement); + } + + public PsiImportStaticStatement createImportStaticStatement(PsiClass aClass, String memberName) throws IncorrectOperationException { + if (aClass instanceof PsiAnonymousClass) { + throw new IncorrectOperationException("Cannot create import statement for anonymous class."); + } + else if (aClass.getParent() instanceof PsiDeclarationStatement) { + throw new IncorrectOperationException("Cannot create import statement for local class."); + } + String text = "import static " + aClass.getQualifiedName() + "." + memberName + ";"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiImportStaticStatement statement = aFile.getImportList().getImportStaticStatements()[0]; + return (PsiImportStaticStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement); + } + + public PsiParameterList createParameterList(String[] names, PsiType[] types) throws IncorrectOperationException { + String text = "void method("; + String sep = ""; + for (int i = 0; i < names.length; i++) { + final String name = names[i]; + PsiType type = types[i]; + text += sep + type.getCanonicalText() + " " + name; + sep = ","; + } + text += "){}"; + PsiMethod method = createMethodFromText(text,null); + return method.getParameterList(); + } + + public PsiReferenceList createReferenceList(PsiJavaCodeReferenceElement[] references) throws IncorrectOperationException { + String text = "void method() "; + if (references.length > 0) text += "throws "; + String sep = ""; + for (int i = 0; i < references.length; i++) { + final PsiJavaCodeReferenceElement reference = references[i]; + text += sep + reference.getCanonicalText(); + sep = ","; + } + text += "{}"; + PsiMethod method = createMethodFromText(text, null); + return method.getThrowsList(); + } + + public PsiCatchSection createCatchSection(PsiClassType exceptionType, String exceptionName, PsiElement context) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + buffer.append("catch ("); + buffer.append(exceptionType.getCanonicalText()); + buffer.append(" " + exceptionName + "){}"); + String catchSectionText = buffer.toString(); + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + TreeElement catchSection = StatementParsing.parseCatchSectionText(myManager, catchSectionText.toCharArray(), + holderElement.getCharTable()); + LOG.assertTrue(catchSection != null && catchSection.getElementType() == ElementType.CATCH_SECTION); + TreeUtil.addChildren(holderElement, catchSection); + PsiCatchSection psiCatchSection = (PsiCatchSection)SourceTreeToPsiMap.treeElementToPsi(catchSection); + + setupCatchBlock(exceptionName, context, psiCatchSection); + return (PsiCatchSection)myManager.getCodeStyleManager().reformat(psiCatchSection); + } + + private void setupCatchBlock(String exceptionName, PsiElement context, PsiCatchSection psiCatchSection) + throws IncorrectOperationException { + FileTemplate catchBodyTemplate = FileTemplateManager.getInstance().getCodeTemplate(FileTemplateManager.TEMPLATE_CATCH_BODY); + LOG.assertTrue(catchBodyTemplate != null); + + Properties props = new Properties(); + props.setProperty(FileTemplate.ATTRIBUTE_EXCEPTION, exceptionName); + if (context != null && context.isPhysical()) { + FileTemplateUtil.setPackageNameAttribute(props, context.getContainingFile().getContainingDirectory()); + } + PsiCodeBlock codeBlockFromText; + try { + String catchBody = catchBodyTemplate.getText(props); + codeBlockFromText = createCodeBlockFromText("{\n" + catchBody + "\n}", null); + } + catch (Exception e) { + throw new IncorrectOperationException("Incorrect file template"); + } + psiCatchSection.getCatchBlock().replace(codeBlockFromText); + } + + public XmlText createDisplayText(String s) throws IncorrectOperationException{ + final XmlTag tagFromText = createTagFromText("" + XmlTagTextUtil.getCDATAQuote(s) + ""); + final XmlText[] textElements = tagFromText.getValue().getTextElements(); + if(textElements.length == 0) return (XmlText)Factory.createCompositeElement(XmlElementType.XML_TEXT); + return textElements[0]; + } + + public XmlTag createXHTMLTagFromText(String text) throws IncorrectOperationException{ + return ((XmlFile)createFileFromText("dummy.xhtml", text)).getDocument().getRootTag(); + } + + public PsiJavaCodeReferenceElement createPackageReferenceElement(String packageName) + throws IncorrectOperationException { + if (packageName.length() == 0) { + throw new IncorrectOperationException("Cannot create reference to default package."); + } + return new LightPackageReference(myManager, packageName); + } + + public PsiReferenceExpression createReferenceExpression(PsiClass aClass) throws IncorrectOperationException { + String text; + if (aClass instanceof PsiAnonymousClass) { + text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText(); + } + else { + text = aClass.getName(); + } + return new LightClassReferenceExpression(myManager, text, aClass); + } + + public PsiReferenceExpression createReferenceExpression(PsiPackage aPackage) throws IncorrectOperationException { + if (aPackage.getQualifiedName().length() == 0) { + throw new IncorrectOperationException("Cannot create reference to default package."); + } + return new LightPackageReferenceExpression(myManager, aPackage); + } + + public PsiIdentifier createIdentifier(String text) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, text); + return new LightIdentifier(myManager, text); + } + + public PsiKeyword createKeyword(String text) throws IncorrectOperationException { + if (!myManager.getNameHelper().isKeyword(text)) { + throw new IncorrectOperationException("\"" + text + "\" is not a keyword."); + } + return new LightKeyword(myManager, text); + } + + public PsiImportStatement createImportStatement(PsiClass aClass) throws IncorrectOperationException { + if (aClass instanceof PsiAnonymousClass) { + throw new IncorrectOperationException("Cannot create import statement for anonymous class."); + } + else if (aClass.getParent() instanceof PsiDeclarationStatement) { + throw new IncorrectOperationException("Cannot create import statement for local class."); + } + String text = "import " + aClass.getQualifiedName() + ";"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiImportStatement statement = aFile.getImportList().getImportStatements()[0]; + return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement); + } + + public PsiImportStatement createImportStatementOnDemand(String packageName) throws IncorrectOperationException { + if (packageName.length() == 0) { + throw new IncorrectOperationException("Cannot create import statement for default package."); + } + if (!myManager.getNameHelper().isQualifiedName(packageName)) { + throw new IncorrectOperationException("Incorrect package name: \"" + packageName + "\"."); + } + + String text = "import " + packageName + ".*;"; + PsiJavaFile aFile = createDummyJavaFile(text); + PsiImportStatement statement = aFile.getImportList().getImportStatements()[0]; + return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement); + } + + public PsiDeclarationStatement createVariableDeclarationStatement(String name, + PsiType type, + PsiExpression initializer) + throws IncorrectOperationException { + + if (!myManager.getNameHelper().isIdentifier(name)) { + throw new IncorrectOperationException("\"" + name + "\" is not an identifier."); + } + if (type == PsiType.NULL) { + throw new IncorrectOperationException("Cannot create field with type \"\"."); + } + StringBuffer buffer = new StringBuffer(); + buffer.append("X "); + buffer.append(name); + if (initializer != null) { + buffer.append("=x"); + } + buffer.append(";"); + PsiDeclarationStatement statement = (PsiDeclarationStatement)createStatementFromText(buffer.toString(), null); + PsiVariable variable = (PsiVariable)statement.getDeclaredElements()[0]; + variable.getTypeElement().replace(createTypeElement(type)); + variable.getModifierList().setModifierProperty(PsiModifier.FINAL, CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_LOCALS); + if (initializer != null) { + variable.getInitializer().replace(initializer); + } + + statement = (PsiDeclarationStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement); + return statement; + } + + public PsiDocTag createParamTag(String parameterName, String description) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + buffer.append(" * @param "); + buffer.append(parameterName); + buffer.append(" "); + final String[] strings = description.split("\\n"); + for (int i = 0; i < strings.length; i++) { + String string = strings[i]; + if (i > 0) buffer.append("\n * "); + buffer.append(string); + } + return createDocTagFromText(buffer.toString(), null); + } + + public PsiDocTag createDocTagFromText(String docTagText, PsiElement context) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + buffer.append("/**\n"); + buffer.append(docTagText); + buffer.append("\n */"); + PsiDocComment comment = createDocCommentFromText(buffer.toString(), context); + return comment.getTags()[0]; + } + + public PsiDocComment createDocCommentFromText(String docCommentText, PsiElement context) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + buffer.append(docCommentText); + buffer.append("void m();"); + final PsiMethod method = createMethodFromText(buffer.toString(), null); + return method.getDocComment(); + } + + public PsiFile createFileFromText(String name, String text) throws IncorrectOperationException { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType type = fileTypeManager.getFileTypeByFileName(name); + + char[] chars = text.toCharArray(); + int startOffset = 0; + int endOffset = text.length(); + + if (type.isBinary()) { + throw new IncorrectOperationException("Cannot create binary files from text"); + } + + return createFileFromText(myManager, type, name, chars, startOffset, endOffset); + } + + public PsiFile createDummyFileFromText(FileType fileType, char[] chars, int startOffset, int endOffset) { + LOG.assertTrue(!fileType.isBinary()); + return createFileFromText(myManager, fileType, "", chars, startOffset, endOffset); + } + + public static PsiFile createFileFromText(PsiManagerImpl manager, + FileType fileType, + String name, + char[] chars, + int startOffset, + int endOffset) { + LOG.assertTrue(!fileType.isBinary()); + PsiFile psiFile = fileType.createPsiFile(manager.getProject(), name, chars, startOffset, endOffset); + return psiFile != null ? psiFile : new PsiPlainTextFileImpl(manager, name, fileType, chars, startOffset, endOffset); + } + + public PsiClass createClassFromText(String text, PsiElement context) throws IncorrectOperationException { + String fileText = "class _Dummy_ { " + text + " }"; + PsiJavaFile aFile = createDummyJavaFile(fileText); + PsiClass[] classes = aFile.getClasses(); + if (classes.length != 1) { + throw new IncorrectOperationException("Incorrect class \"" + text + "\"."); + } + return classes[0]; + } + + public PsiField createFieldFromText(String text, PsiElement context) throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + TreeElement decl = DeclarationParsing.parseDeclarationText(myManager, myManager.getEffectiveLanguageLevel(), text.toCharArray(), + DeclarationParsing.CLASS_CONTEXT, holderElement.getCharTable()); + if (decl == null || decl.getElementType() != ElementType.FIELD) { + throw new IncorrectOperationException("Incorrect field \"" + text + "\"."); + } + TreeUtil.addChildren(holderElement, decl); + return (PsiField)SourceTreeToPsiMap.treeElementToPsi(decl); + } + + public PsiMethod createMethodFromText(String text, PsiElement context, LanguageLevel languageLevel) throws IncorrectOperationException { + return createMethodFromTextInner(text, context, languageLevel); + } + + public PsiMethod createMethodFromText(String text, PsiElement context) throws IncorrectOperationException { + return createMethodFromTextInner(text, context, myManager.getEffectiveLanguageLevel()); + } + + private PsiMethod createMethodFromTextInner (String text, PsiElement context, LanguageLevel level) throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + TreeElement decl = DeclarationParsing.parseDeclarationText(myManager, level, text.toCharArray(), + DeclarationParsing.CLASS_CONTEXT, holderElement.getCharTable()); + if (decl == null || decl.getElementType() != ElementType.METHOD) { + throw new IncorrectOperationException("Incorrect method \"" + text + "\"."); + } + TreeUtil.addChildren(holderElement, decl); + return (PsiMethod)SourceTreeToPsiMap.treeElementToPsi(decl); + } + + public PsiParameter createParameterFromText(String text, PsiElement context) throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement param = DeclarationParsing.parseParameterText(myManager, text.toCharArray(), holderElement.getCharTable()); + if (param == null) { + throw new IncorrectOperationException("Incorrect parameter \"" + text + "\"."); + } + TreeUtil.addChildren(holderElement, param); + return (PsiParameter)SourceTreeToPsiMap.treeElementToPsi(param); + } + + public PsiType createTypeFromText(String text, PsiElement context) throws IncorrectOperationException { + PsiPrimitiveType primitiveType = ourPrimitiveTypesMap.get(text); + if (primitiveType != null) return primitiveType; + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement typeElement = Parsing.parseTypeText(myManager, text.toCharArray(), 0, text.length(), holderElement.getCharTable()); + if (typeElement == null) { + throw new IncorrectOperationException("Incorrect type \"" + text + "\""); + } + TreeUtil.addChildren(holderElement, typeElement); + PsiTypeElement psiTypeElement = (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(typeElement); + return psiTypeElement.getType(); + } + + public PsiCodeBlock createCodeBlockFromText(String text, PsiElement context) throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement treeElement = StatementParsing.parseCodeBlockText(myManager, text.toCharArray(), holderElement.getCharTable()); + if (treeElement == null) { + throw new IncorrectOperationException("Incorrect code block \"" + text + "\"."); + } + TreeUtil.addChildren(holderElement, treeElement); + return (PsiCodeBlock)SourceTreeToPsiMap.treeElementToPsi(treeElement); + } + + public PsiStatement createStatementFromText(String text, PsiElement context) throws IncorrectOperationException { + final FileElement treeHolder = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement treeElement = StatementParsing.parseStatementText(myManager, text.toCharArray(), treeHolder.getCharTable()); + if (treeElement == null) { + throw new IncorrectOperationException("Incorrect statement \"" + text + "\"."); + } + TreeUtil.addChildren(treeHolder, treeElement); + return (PsiStatement)SourceTreeToPsiMap.treeElementToPsi(treeElement); + } + + public PsiExpression createExpressionFromText(String text, PsiElement context) throws IncorrectOperationException { + final FileElement treeHolder = new DummyHolder(myManager, context).getTreeElement(); + final CompositeElement treeElement = ExpressionParsing.parseExpressionText(myManager, text.toCharArray(), 0, + text.length(), treeHolder.getCharTable()); + if (treeElement == null) { + throw new IncorrectOperationException("Incorrect expression \"" + text + "\"."); + } + TreeUtil.addChildren(treeHolder, treeElement); + return (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(treeElement); + } + + public PsiComment createCommentFromText(String text, PsiElement context) throws IncorrectOperationException { + PsiJavaFile aFile = createDummyJavaFile(text); + PsiElement[] children = aFile.getChildren(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof PsiComment) { + if (!children[i].getText().equals(text)) { + throw new IncorrectOperationException("Incorrect comment \"" + text + "\"."); + } + PsiComment comment = (PsiComment)children[i]; + new DummyHolder(myManager, SourceTreeToPsiMap.psiElementToTree(comment), context); + return comment; + } + } + throw new IncorrectOperationException("Incorrect comment \"" + text + "\"."); + } + + private PsiJavaFile createDummyJavaFile(String text) throws IncorrectOperationException { + String ext = StdFileTypes.JAVA.getDefaultExtension(); + return (PsiJavaFile)createFileFromText("_Dummy_." + ext, text); + } + + private PsiAspectFile createDummyAspectFile(String text) throws IncorrectOperationException { + String ext = StdFileTypes.ASPECT.getDefaultExtension(); + return (PsiAspectFile)createFileFromText("_Dummy_." + ext, text); + } + + public XmlTag createTagFromText(String text) throws IncorrectOperationException { + return ((XmlFile)createFileFromText("dummy.xml", text)).getDocument().getRootTag(); + } + + public XmlAttribute createXmlAttribute(String name, String value) throws IncorrectOperationException { + XmlTag tag = ((XmlFile)createFileFromText("dummy.xml", "")).getDocument() + .getRootTag(); + return tag.getAttributes()[0]; + } + + public PsiTypePattern createTypePattern(String pattern) throws IncorrectOperationException { + PsiAspectFile psiFile = createDummyAspectFile("aspect foo { pointcut foo():within(" + pattern + ");}"); + PsiWithinPointcut pointcut = (PsiWithinPointcut)psiFile.getAspects()[0].getPointcutDefs()[0].getPointcut(); + return pointcut.getTypePattern(); + } + + public PsiExpressionCodeFragment createExpressionCodeFragment(String text, PsiElement context, boolean isPhysical) { + final PsiExpressionCodeFragmentImpl result = new PsiExpressionCodeFragmentImpl( + myManager, isPhysical, "fragment.java", text.toCharArray(), 0, text.length()); + result.setContext(context); + return result; + } + + public PsiCodeFragment createCodeBlockCodeFragment(String text, PsiElement context, boolean isPhysical) { + final PsiCodeFragmentImpl result = new PsiCodeFragmentImpl(myManager, + ElementType.STATEMENTS, + isPhysical, + "fragment.java", + text.toCharArray(), + 0, + text.length()); + result.setContext(context); + return result; + } + + public PsiTypeCodeFragment createTypeCodeFragment(String text, PsiElement context, boolean isPhysical) { + + return createTypeCodeFragment(text, context, false, isPhysical, false); + } + + + public PsiTypeCodeFragment createTypeCodeFragment(String text, + PsiElement context, + boolean isVoidValid, + boolean isPhysical) { + return createTypeCodeFragment(text, context, true, isPhysical, false); + } + + public PsiTypeCodeFragment createTypeCodeFragment(String text, + PsiElement context, + boolean isVoidValid, + boolean isPhysical, boolean allowEllipsis) { + final PsiTypeCodeFragmentImpl result = new PsiTypeCodeFragmentImpl(myManager, + isPhysical, + allowEllipsis, + "fragment.java", + text.toCharArray(), + 0, + text.length()); + result.setContext(context); + if (isVoidValid) { + result.putUserData(PsiUtil.VALID_VOID_TYPE_IN_CODE_FRAGMENT, Boolean.TRUE); + } + return result; + } + + + public PsiTypeParameter createTypeParameterFromText(String text, PsiElement context) + throws IncorrectOperationException { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + TreeElement treeElement = DeclarationParsing.parseTypeParameterText(myManager, text.toCharArray(), holderElement.getCharTable()); + if (treeElement == null) { + throw new IncorrectOperationException("Incorrect type parameter \"" + text + "\""); + } + TreeUtil.addChildren(holderElement, treeElement); + return (PsiTypeParameter)SourceTreeToPsiMap.treeElementToPsi(treeElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiFileEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiFileEx.java new file mode 100644 index 00000000000..ed4258dd0fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiFileEx.java @@ -0,0 +1,7 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.*; + +public interface PsiFileEx extends PsiFile{ + boolean isContentsLoaded(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiImplUtil.java new file mode 100644 index 00000000000..d497367bee4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiImplUtil.java @@ -0,0 +1,371 @@ +package com.intellij.psi.impl; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.impl.light.LightClassReference; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.PsiImmediateClassType; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class PsiImplUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiImplUtil"); + + private static final Key>,Runnable>> METHODS_MAP_IN_CLASS_KEY = Key.create("METHODS_MAP_IN_CLASS_KEY"); + private static final Key>,Runnable>> FIELDS_MAP_IN_CLASS_KEY = Key.create("FIELDS_MAP_IN_CLASS_KEY"); + + public static PsiMethod[] getConstructors(PsiClass aClass) { + final List constructorsList = new ArrayList(); + final PsiMethod[] methods = aClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (method.isConstructor()) constructorsList.add(method); + } + return constructorsList.toArray(PsiMethod.EMPTY_ARRAY); + } + + public static Map> getAllMethodsMap(final PsiClass psiClass){ + if (!psiClass.isPhysical()) { + return _getAllMethodsMap(psiClass); + } + + final Pair>, Runnable> value = psiClass.getUserData(METHODS_MAP_IN_CLASS_KEY); + + if (value == null) { + final Map> allMethods = _getAllMethodsMap(psiClass); + final Runnable cleaner = new Runnable() { + public void run() { + psiClass.putUserData(METHODS_MAP_IN_CLASS_KEY, null); + } + }; + psiClass.putUserData(METHODS_MAP_IN_CLASS_KEY, new Pair>, Runnable>(allMethods, cleaner)); + PsiManagerImpl manager = (PsiManagerImpl)psiClass.getManager(); + manager.registerWeakRunnableToRunOnChange(cleaner); + return allMethods; + } + + return value.first; + } + + private static Map> _getAllMethodsMap(PsiClass psiClass) { + final List list = new ArrayList(); + PsiScopesUtil.processScope(psiClass, new FilterScopeProcessor(new ClassFilter(PsiMethod.class), null, list){ + protected void add(PsiElement element, PsiSubstitutor substitutor) { + list.add(new MethodCandidateInfo(element, substitutor)); + } + }, PsiSubstitutor.EMPTY, null, psiClass); + + final Map> methods = new HashMap>(); + final Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + final MethodCandidateInfo info = iterator.next(); + final PsiMethod method = info.getElement(); + final String name = method.getName(); + List methodsList = methods.get(name); + if(methodsList == null){ + methodsList = new ArrayList(1); + methods.put(name, methodsList); + } + methodsList.add(info); + } + return methods; + } + + public static Map> getAllFieldsMap(final PsiClass psiClass){ + if (!psiClass.isPhysical()) { + return _getAllFieldsMap(psiClass); + } + + final Pair>, Runnable> value = psiClass.getUserData(FIELDS_MAP_IN_CLASS_KEY); + + if (value == null) { + final Map> allFields = _getAllFieldsMap(psiClass); + final Runnable cleaner = new Runnable() { + public void run() { + psiClass.putUserData(FIELDS_MAP_IN_CLASS_KEY, null); + } + }; + psiClass.putUserData(FIELDS_MAP_IN_CLASS_KEY, new Pair>, Runnable>(allFields, cleaner)); + PsiManagerImpl manager = (PsiManagerImpl)psiClass.getManager(); + manager.registerWeakRunnableToRunOnChange(cleaner); + return allFields; + } + + return value.first; + } + + private static Map> _getAllFieldsMap(PsiClass psiClass) { + final List list = new ArrayList(); + PsiScopesUtil.processScope(psiClass, new FilterScopeProcessor(new ClassFilter(PsiField.class), null, list){ + protected void add(PsiElement element, PsiSubstitutor substitutor) { + list.add(new CandidateInfo(element, substitutor)); + } + }, PsiSubstitutor.EMPTY, null, psiClass); + + final Map> fields = new HashMap>(); + final Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + final CandidateInfo info = iterator.next(); + final PsiField field = (PsiField)info.getElement(); + final String name = field.getName(); + List fieldsList = fields.get(name); + if(fieldsList == null){ + fieldsList = new ArrayList(1); + fields.put(name, fieldsList); + } + fieldsList.add(info); + } + return fields; + } + + + public static PsiPointcutDef findPointcutDefBySignature(PsiAspect psiAspect, PsiPointcutDef patternPointcut, + boolean checkBases) { + if (!checkBases) { + PsiPointcutDef[] pointcuts = psiAspect.getPointcutDefs(); + for (int i = 0; i < pointcuts.length; i++) { + if (MethodSignatureUtil.areSignaturesEqual(pointcuts[i], patternPointcut)) { + return pointcuts[i]; + } + } + return null; + } + else { + FindPointcutBySignatureProcessor processor = new FindPointcutBySignatureProcessor(patternPointcut); + PsiScopesUtil.processScope(psiAspect, processor, PsiSubstitutor.UNKNOWN, null, patternPointcut); + + return processor.getResult(); + } + } + + public static PsiAnnotationMemberValue findAttributeValue(PsiAnnotation annotation, String attributeName) { + PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); + for (int i = 0; i < attributes.length; i++) { + PsiNameValuePair attribute = attributes[i]; + if (attributeName.equals(attribute.getName())) return attribute.getValue(); + } + + PsiElement resolved = annotation.getNameReferenceElement().resolve(); + if (resolved != null) { + PsiMethod[] methods = ((PsiClass)resolved).getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method instanceof PsiAnnotationMethod && attributeName.equals(method.getName())) { + return ((PsiAnnotationMethod)method).getDefaultValue(); + } + } + } + return null; + } + + private static class FindPointcutBySignatureProcessor extends BaseScopeProcessor implements NameHint, + ElementClassHint { + private final String myName; + private final PsiPointcutDef myPatternPointcut; + private PsiPointcutDef myResult = null; + + public FindPointcutBySignatureProcessor(PsiPointcutDef patternPointcut) { + myName = patternPointcut.getName(); + myPatternPointcut = patternPointcut; + } + + public PsiPointcutDef getResult() { + return myResult; + } + + public String getName() { + return myName; + } + + public boolean shouldProcess(Class elementClass) { + return PsiMethod.class.isAssignableFrom(elementClass); + } + + public void handleEvent(Event event, Object associated) { + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiPointcutDef) { + PsiPointcutDef method = (PsiPointcutDef)element; + if (MethodSignatureUtil.areSignaturesEqual(method, myPatternPointcut)) { + myResult = method; + return false; + } + } + return true; + } + } + + public static PsiJavaCodeReferenceElement[] namesToPackageReferences(PsiManager manager, String[] names) { + PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[names.length]; + for (int i = 0; i < names.length; i++) { + String name = names[i]; + try { + refs[i] = manager.getElementFactory().createPackageReferenceElement(name); + } + catch (IncorrectOperationException e) { + e.printStackTrace(); + } + } + return refs; + } + + public static int getParameterIndex(PsiParameter parameter, PsiParameterList parameterList) { + PsiParameter[] parameters = parameterList.getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (parameter.equals(parameters[i])) return i; + } + LOG.assertTrue(false); + return -1; + } + + public static int getTypeParameterIndex(PsiTypeParameter typeParameter, PsiTypeParameterList typeParameterList) { + PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + for (int i = 0; i < typeParameters.length; i++) { + if (typeParameter.equals(typeParameters[i])) return i; + } + LOG.assertTrue(false); + return -1; + } + + public static final Object[] getReferenceVariantsByFilter(PsiJavaCodeReferenceElement reference, + ElementFilter filter) { + FilterScopeProcessor processor = new FilterScopeProcessor(filter, reference); + PsiScopesUtil.resolveAndWalk(processor, reference, null, true); + return processor.getResults().toArray(); + } + + public static final MethodSignature getMethodSignature(PsiMethod method, PsiSubstitutor substitutor) { + return new MethodSignatureBackedByPsiMethod(method, substitutor); + } + + public static boolean processDeclarationsInMethod(PsiMethod method, PsiScopeProcessor processor, PsiSubstitutor substitutor, + PsiElement lastParent, PsiElement place) { + final ElementClassHint hint = processor.getHint(ElementClassHint.class); + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, method); + if (hint == null || hint.shouldProcess(PsiClass.class)) { + final PsiTypeParameterList list = method.getTypeParameterList(); + if (list != null && !list.processDeclarations(processor, substitutor, null, place)) return false; + } + if (lastParent instanceof PsiCodeBlock) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (!processor.execute(parameters[i], substitutor)) return false; + } + } + + return true; + } + + public static boolean hasTypeParameters(PsiTypeParameterListOwner psiMethod) { + final PsiTypeParameterList typeParameterList = psiMethod.getTypeParameterList(); + return typeParameterList != null && typeParameterList.getTypeParameters().length != 0; + } + + public static PsiType[] typesByReferenceParameterList(final PsiReferenceParameterList parameterList) { + PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); + + return typesByTypeElements(typeElements); + } + + public static PsiType[] typesByTypeElements(PsiTypeElement[] typeElements) { + PsiType[] types = new PsiType[typeElements.length]; + for(int i = 0; i < types.length; i++){ + types[i] = typeElements[i].getType(); + } + return types; + } + + public static PsiType getType (PsiClassObjectAccessExpression classAccessExpression) { + GlobalSearchScope resolveScope = classAccessExpression.getResolveScope(); + PsiManager manager = classAccessExpression.getManager(); + final PsiClass classClass = manager.findClass("java.lang.Class", resolveScope); + if (classClass == null){ + return new PsiClassReferenceType(new LightClassReference(manager, "Class", "java.lang.Class", resolveScope)); + } + else { + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + PsiType operandType = classAccessExpression.getOperand().getType(); + if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) { + if (PsiType.VOID.equals(operandType)) { + operandType = manager.getElementFactory().createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope()); + } else { + operandType = ((PsiPrimitiveType)operandType).getBoxedType(manager, classAccessExpression.getResolveScope()); + } + } + final PsiTypeParameterList typeParameterList = classClass.getTypeParameterList(); + if (typeParameterList != null) { + final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + if (typeParameters.length == 1) { + substitutor = substitutor.put(typeParameters[0], operandType); + } + } + + return new PsiImmediateClassType(classClass, substitutor); + } + } + + public static PsiAnnotation findAnnotation(PsiModifierList modifierList, String qualifiedName) { + PsiAnnotation[] annotations = modifierList.getAnnotations(); + for (int i = 0; i < annotations.length; i++) { + PsiAnnotation annotation = annotations[i]; + final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); + if (nameRef != null && qualifiedName.equals(nameRef.getCanonicalText())) return annotation; + } + + return null; + } + +public static PsiType normalizeWildcardTypeByPosition(final PsiType type, final PsiExpression expression) { + if (type instanceof PsiCapturedWildcardType) { + return normalizeWildcardTypeByPosition(((PsiCapturedWildcardType)type).getWildcard(), expression); + } + if (type instanceof PsiWildcardType) { + final PsiWildcardType wildcardType = (PsiWildcardType)type; + if (PsiUtil.isInCovariantPosition(expression)) { + return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType); + } + else { + if (wildcardType.isExtends()) { + return wildcardType.getBound(); + } + else { + return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); + } + } + } + else if (type instanceof PsiArrayType) { + final PsiType componentType = ((PsiArrayType)type).getComponentType(); + final PsiType normalizedComponentType = normalizeWildcardTypeByPosition(componentType, expression); + if (normalizedComponentType != componentType) { + return normalizedComponentType.createArrayType(); + } + else { + return type; + } + } + else { + return type; + } +} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerConfiguration.java new file mode 100644 index 00000000000..07619255c0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerConfiguration.java @@ -0,0 +1,34 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +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.openapi.application.ApplicationManager; +import org.jdom.Element; + +public class PsiManagerConfiguration implements ApplicationComponent, JDOMExternalizable { + public boolean REPOSITORY_ENABLED = true; + public boolean CREATE_DUMMY_PROJECT_FOR_OBFUSCATION = true; + + public static PsiManagerConfiguration getInstance() { + return ApplicationManager.getApplication().getComponent(PsiManagerConfiguration.class); + } + + public String getComponentName() {return "PsiManagerConfiguration"; } + + public void initComponent() { } + + public void disposeComponent() { } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + throw new WriteExternalException(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerImpl.java new file mode 100644 index 00000000000..55d038d4a9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiManagerImpl.java @@ -0,0 +1,1072 @@ +package com.intellij.psi.impl; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.ide.startup.FileContent; +import com.intellij.ide.startup.FileSystemSynchronizer; +import com.intellij.ide.startup.StartupManagerEx; +import com.intellij.j2ee.extResources.ExternalResourceListener; +import com.intellij.j2ee.openapi.ex.ExternalResourceManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.cache.CacheManager; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.cache.impl.CacheManagerImpl; +import com.intellij.psi.impl.cache.impl.CacheUtil; +import com.intellij.psi.impl.cache.impl.CompositeCacheManager; +import com.intellij.psi.impl.cache.impl.RepositoryManagerImpl; +import com.intellij.psi.impl.file.PsiPackageImpl; +import com.intellij.psi.impl.file.impl.FileManager; +import com.intellij.psi.impl.file.impl.FileManagerImpl; +import com.intellij.psi.impl.migration.PsiMigrationImpl; +import com.intellij.psi.impl.search.PsiSearchHelperImpl; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.javadoc.JavadocManagerImpl; +import com.intellij.psi.impl.source.jsp.JspElementFactoryImpl; +import com.intellij.psi.impl.source.jsp.JspManager; +import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.javadoc.JavadocManager; +import com.intellij.psi.jsp.JspElementFactory; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.*; + +public class PsiManagerImpl extends PsiManager implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiManagerImpl"); + + private final Project myProject; + + private FileManager myFileManager; + private PsiElementFactory myElementFactory; + private JspElementFactory myJspElementFactory; + private PsiSearchHelper mySearchHelper; + private PsiShortNamesCache myShortNamesCache; + private PsiResolveHelper myResolveHelper; + //private MemoryManager myMemoryManager; + private CacheManager myCacheManager; + private RepositoryManager myRepositoryManager; + private RepositoryElementsManager myRepositoryElementsManager; + private JspManager myJspManager; + private JavadocManager myJavadocManager; + private PsiNameHelper myNameHelper; + private PsiModificationTrackerImpl myModificationTracker; + private PsiAspectManager myAspectManager; + private ResolveCache myResolveCache; + private CachedValuesManager myCachedValuesManager; + private PsiConstantEvaluationHelper myConstantEvaluationHelper; + + private final ArrayList myTreeChangeListeners = new ArrayList(); + private PsiTreeChangeListener[] myCachedTreeChangeListeners = null; + private boolean myTreeChangeEventIsFiring = false; + + private final HashMap myUserMap = new HashMap(); + + private final ArrayList myRunnablesOnChange = new ArrayList(); + private final ArrayList> myWeakRunnablesOnChange = new ArrayList>(); + private final ArrayList myRunnablesOnAnyChange = new ArrayList(); + private final ArrayList myRunnablesAfterAnyChange = new ArrayList(); + + private ExternalResourceListener myExternalResourceListener; + private boolean myIsDisposed; + + private VirtualFileFilter myAssertOnFileLoadingFilter = VirtualFileFilter.NONE; + + private int myBatchFilesProcessingModeCount = 0; + + private static final Key CACHED_PSI_FILE_COPY_IN_FILECONTENT = Key.create("CACHED_PSI_FILE_COPY_IN_FILECONTENT"); + public static final int BEFORE_CHILD_ADDITION = 0; + public static final int BEFORE_CHILD_REMOVAL = 1; + public static final int BEFORE_CHILD_REPLACEMENT = 2; + public static final int BEFORE_CHILD_MOVEMENT = 3; + public static final int BEFORE_CHILDREN_CHANGE = 4; + public static final int BEFORE_PROPERTY_CHANGE = 5; + public static final int CHILD_ADDED = 6; + public static final int CHILD_REMOVED = 7; + public static final int CHILD_REPLACED = 8; + public static final int CHILD_MOVED = 9; + public static final int CHILDREN_CHANGED = 10; + public static final int PROPERTY_CHANGED = 11; + private PsiMigrationImpl myCurrentMigration; + private LanguageLevel myLanguageLevel; + private PsiElementFinder[] myElementFinders; + private FileTypeManager myFileTypeManager; + + public PsiManagerImpl(Project project, + PsiManagerConfiguration psiManagerConfiguration, + ProjectRootManagerEx projectRootManagerEx, + ExternalResourceManagerEx externalResourceManagerEx, + StartupManagerEx startupManagerEx, + FileTypeManager fileTypeManager, + VirtualFileManager virtualFileManager, + FileDocumentManager fileDocumentManager) { + myProject = project; + + if (psiManagerConfiguration.REPOSITORY_ENABLED) { + myRepositoryManager = new RepositoryManagerImpl(this); + } else { + myRepositoryManager = new EmptyRepository.MyRepositoryManagerImpl(); + } + + myLanguageLevel = projectRootManagerEx.getLanguageLevel(); + + myFileManager = new FileManagerImpl(this, fileTypeManager, virtualFileManager, fileDocumentManager, projectRootManagerEx); + myElementFactory = new PsiElementFactoryImpl(this); + myJspElementFactory = new JspElementFactoryImpl(this); + mySearchHelper = new PsiSearchHelperImpl(this); + myResolveHelper = new PsiResolveHelperImpl(this); + //myMemoryManager = new MemoryManager(); + CompositeCacheManager cacheManager = new CompositeCacheManager(); + if (psiManagerConfiguration.REPOSITORY_ENABLED) { + myShortNamesCache = new PsiShortNamesCacheImpl(this, projectRootManagerEx); + cacheManager.addCacheManager(new CacheManagerImpl(this)); + myRepositoryElementsManager = new RepositoryElementsManager(this); + } + else { + myShortNamesCache = new EmptyRepository.PsiShortNamesCacheImpl(); + cacheManager.addCacheManager(new EmptyRepository.CacheManagerImpl()); + myRepositoryElementsManager = new EmptyRepository.MyRepositoryElementsManager(this); + } + + myCacheManager = cacheManager; + + myJavadocManager = new JavadocManagerImpl(); + myNameHelper = new PsiNameHelperImpl(this); + myExternalResourceListener = new MyExternalResourceListener(); + myModificationTracker = new PsiModificationTrackerImpl(this); + myAspectManager = new PsiAspectManagerImpl(this); + myResolveCache = new ResolveCache(this); + myCachedValuesManager = new CachedValuesManagerImpl(this); + myConstantEvaluationHelper = new PsiConstantEvaluationHelperImpl(); + + List elementFinders = new ArrayList(); + elementFinders.addAll(Arrays.asList(myProject.getComponents(PsiElementFinder.class))); + elementFinders.add(new PsiElementFinderImpl()); //this finder should be added at end for Fabrique's needs + myElementFinders = elementFinders.toArray(new PsiElementFinder[elementFinders.size()]); + + ExternalResourceManagerEx externalResourceManager = externalResourceManagerEx; + if (externalResourceManager != null) { + externalResourceManager.addExteralResourceListener(myExternalResourceListener); + } + + StartupManagerEx startupManager = startupManagerEx; + if (startupManager != null) { + startupManager.registerPreStartupActivity( + new Runnable() { + public void run() { + runStartupActivity(); + } + } + ); + } + myFileTypeManager = fileTypeManager; + } + + public PsiConstantEvaluationHelper getConstantEvaluationHelper() { + return myConstantEvaluationHelper; + } + + public void initComponent() { + } + + public void disposeComponent() { + myFileManager.dispose(); + myCacheManager.dispose(); + myRepositoryManager.dispose(); + + ExternalResourceManagerEx externalResourceManager = ExternalResourceManagerEx.getInstanceEx(); + if (externalResourceManager != null) { + externalResourceManager.removeExternalResourceListener(myExternalResourceListener); + } + myIsDisposed = true; + } + + public boolean isDisposed() { + return myIsDisposed; + } + + public LanguageLevel getEffectiveLanguageLevel() { + return myLanguageLevel; + } + + public boolean isPartOfPackagePrefix(String packageName) { + final Collection packagePrefixes = myFileManager.getNonTrivialPackagePrefixes(); + for (Iterator iterator = packagePrefixes.iterator(); iterator.hasNext();) { + final String subpackageName = iterator.next(); + if (isSubpackageOf(subpackageName, packageName)) return true; + } + return false; + } + + private static boolean isSubpackageOf(final String subpackageName, String packageName) { + if (subpackageName.equals(packageName)) return true; + if (!subpackageName.startsWith(packageName)) return false; + return subpackageName.charAt(packageName.length()) == '.'; + } + + public void dropResolveCaches() { + onChange(true); + } + + public boolean isInPackage(PsiElement element, PsiPackage aPackage) { + final PsiFile file = ResolveUtil.getContextFile(element); + if (file instanceof DummyHolder) { + return ((DummyHolder) file).isInPackage(aPackage); + } + if (file instanceof PsiJavaFile) { + final String packageName = ((PsiJavaFile) file).getPackageName(); + return packageName.equals(aPackage != null ? aPackage.getQualifiedName() : ""); + } + return false; + } + + public boolean isInProject(PsiElement element) { + PsiFile file = element.getContainingFile(); + if (file instanceof PsiFileImpl && ((PsiFileImpl) file).isExplicitlySetAsPhysical()) return true; + + if (element instanceof PsiPackage) { + PsiDirectory[] dirs = ((PsiPackage) element).getDirectories(); + for (int i = 0; i < dirs.length; i++) { + PsiDirectory dir = dirs[i]; + if (!isInProject(dir)) return false; + } + return true; + } + + Module module = ModuleUtil.findModuleForPsiElement(element); + return module != null; + } + + public boolean arePackagesTheSame(PsiElement element1, PsiElement element2) { + PsiFile file1 = ResolveUtil.getContextFile(element1); + PsiFile file2 = ResolveUtil.getContextFile(element2); + if (Comparing.equal(file1, file2)) return true; + if (file1 instanceof DummyHolder && file2 instanceof DummyHolder) return true; + if (file1 instanceof DummyHolder || file2 instanceof DummyHolder) { + DummyHolder dummyHolder = (DummyHolder) (file1 instanceof DummyHolder ? file1 : file2); + PsiElement other = file1 instanceof DummyHolder ? file2 : file1; + return dummyHolder.isSamePackage(other); + } + if (!(file1 instanceof PsiJavaFile)) return false; + if (!(file2 instanceof PsiJavaFile)) return false; + String package1 = ((PsiJavaFile) file1).getPackageName(); + String package2 = ((PsiJavaFile) file2).getPackageName(); + return Comparing.equal(package1, package2); + } + + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void runStartupActivity() { + if (LOG.isDebugEnabled()) { + LOG.debug("PsiManager.runStartupActivity()"); + } + myFileManager.runStartupActivity(); + + myCacheManager.initialize(); + myShortNamesCache.runStartupActivity(); + + StartupManagerEx startupManager = StartupManagerEx.getInstanceEx(myProject); + if (startupManager != null) { + FileSystemSynchronizer synchronizer = startupManager.getFileSystemSynchronizer(); + + if (PsiManagerConfiguration.getInstance().REPOSITORY_ENABLED) { + synchronizer.registerCacheUpdater(myRepositoryManager.getCacheUpdater()); + + CacheUpdater[] updaters = myCacheManager.getCacheUpdaters(); + for (int i = 0; i < updaters.length; i++) { + synchronizer.registerCacheUpdater(updaters[i]); + } + } + } + } + + public void setAssertOnFileLoadingFilter(VirtualFileFilter filter) { + myAssertOnFileLoadingFilter = filter; + } + + public boolean isAssertOnFileLoading(VirtualFile file) { + return myAssertOnFileLoadingFilter.accept(file); + } + + public Project getProject() { + return myProject; + } + + public FileManager getFileManager() { + return myFileManager; + } + + public RepositoryManager getRepositoryManager() { + LOG.assertTrue(!myIsDisposed); + return myRepositoryManager; + } + + public RepositoryElementsManager getRepositoryElementsManager() { + return myRepositoryElementsManager; + } + + public CacheManager getCacheManager() { + LOG.assertTrue(!myIsDisposed); + return myCacheManager; + } + + public CodeStyleManager getCodeStyleManager() { + return CodeStyleManager.getInstance(myProject); + } + + public ResolveCache getResolveCache() { + return myResolveCache; + } + + public PsiDirectory[] getRootDirectories(int rootType) { + return myFileManager.getRootDirectories(rootType); + } + + /** + * @deprecated + */ + public PsiClass findClass(String qualifiedName) { + return findClass(qualifiedName, GlobalSearchScope.allScope(myProject)); + } + + public PsiClass findClass(String qualifiedName, GlobalSearchScope scope) { + for (int i = 0; i < myElementFinders.length; i++) { + PsiElementFinder finder = myElementFinders[i]; + PsiClass aClass = finder.findClass(qualifiedName, scope); + if (aClass != null) return aClass; + } + + return null; + } + + public PsiClass[] findClasses(String qualifiedName, GlobalSearchScope scope) { + List classes = new ArrayList(); + for (int i = 0; i < myElementFinders.length; i++) { + PsiElementFinder finder = myElementFinders[i]; + PsiClass[] finderClasses = finder.findClasses(qualifiedName, scope); + for (int j = 0; j < finderClasses.length; j++) { + PsiClass finderClass = finderClasses[j]; + classes.add(finderClass); + } + } + + return classes.toArray(new PsiClass[classes.size()]); + } + + public boolean areElementsEquivalent(PsiElement element1, PsiElement element2) { + if (element1 == element2) return true; + if (element1 == null || element2 == null) { + return false; + } + if (element1 instanceof PsiPackage || element2 instanceof PsiPackage) { + return element1.equals(element2); + } + if (element1 instanceof PsiDirectory || element2 instanceof PsiDirectory) { + return false; + } + if (element1 instanceof PsiClass) { + if (!(element2 instanceof PsiClass)) return false; + String name1 = ((PsiClass)element1).getName(); + if (name1 == null) return false; + String name2 = ((PsiClass)element2).getName(); + if (name2 == null) return false; + if (name1.hashCode() != name2.hashCode()) return false; + if (!name1.equals(name2)) return false; + String qName1 = ((PsiClass)element1).getQualifiedName(); + String qName2 = ((PsiClass)element2).getQualifiedName(); + if (qName1 == null || qName2 == null) { + if (qName1 != qName2) return false; + + if (element1 instanceof PsiTypeParameter && element2 instanceof PsiTypeParameter) { + PsiTypeParameter p1 = ((PsiTypeParameter)element1); + PsiTypeParameter p2 = ((PsiTypeParameter)element2); + + if (p1.getIndex() != p2.getIndex()) { + return false; + } + + return areElementsEquivalent(p1.getOwner(), p2.getOwner()); + } + else { + return false; + } + } + if (qName1.hashCode() != qName2.hashCode()) return false; + return qName1.equals(qName2); + } + if (element1 instanceof PsiField) { + if (!(element2 instanceof PsiField)) return false; + String name1 = ((PsiField)element1).getName(); + if (name1 == null) return false; + String name2 = ((PsiField)element2).getName(); + if (!name1.equals(name2)) return false; + PsiClass aClass1 = ((PsiField)element1).getContainingClass(); + PsiClass aClass2 = ((PsiField)element2).getContainingClass(); + return aClass1 != null && aClass2 != null && areElementsEquivalent(aClass1, aClass2); + } + if (element1 instanceof PsiMethod) { + if (!(element2 instanceof PsiMethod)) return false; + String name1 = ((PsiMethod)element1).getName(); + if (name1 == null) return false; + String name2 = ((PsiMethod)element2).getName(); + if (!name1.equals(name2)) return false; + PsiClass aClass1 = ((PsiMethod)element1).getContainingClass(); + PsiClass aClass2 = ((PsiMethod)element2).getContainingClass(); + if (aClass1 == null || aClass2 == null || !areElementsEquivalent(aClass1, aClass2)) return false; + return MethodSignatureUtil.areSignaturesEqual(((PsiMethod)element1).getSignature(PsiSubstitutor.EMPTY), + ((PsiMethod)element2).getSignature(PsiSubstitutor.EMPTY)); + } + return false; + } + + public PsiFile findFile(VirtualFile file) { + return myFileManager.findFile(file); + } + + public void cleanupForNextTest() { + //myFileManager.cleanupForNextTest(); + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode()); + myJspElementFactory = new JspElementFactoryImpl(this); + } + + public PsiFile getFile(FileContent content) { + PsiFile psiFile = content.getUserData(CACHED_PSI_FILE_COPY_IN_FILECONTENT); + if (psiFile == null) { + final VirtualFile vFile = content.getVirtualFile(); + psiFile = myFileManager.getCachedPsiFile(vFile); + if (psiFile == null) { + psiFile = findFile(vFile); + if (psiFile == null) return null; + psiFile = CacheUtil.createFileCopy(content, psiFile); + } + content.putUserData(CACHED_PSI_FILE_COPY_IN_FILECONTENT, psiFile); + } + + LOG.assertTrue(psiFile instanceof PsiCompiledElement || psiFile.isValid()); + return psiFile; + } + + public PsiDirectory findDirectory(VirtualFile file) { + return myFileManager.findDirectory(file); + } + + public PsiPackage findPackage(String qualifiedName) { + for (int i = 0; i < myElementFinders.length; i++) { + PsiElementFinder finder = myElementFinders[i]; + PsiPackage aPackage = finder.findPackage(qualifiedName); + + if (aPackage != null) return aPackage; + } + + return null; + } + + public PsiMigrationImpl getCurrentMigration() { + return myCurrentMigration; + } + + public void invalidateFile(PsiFile file) { + if (myIsDisposed) { + LOG.error("Disposed PsiManager calls invalidateFile!"); + } + + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null && myCacheManager != null) { + myCacheManager.addOrInvalidateFile(virtualFile); + } + } + + public void reloadFromDisk(PsiFile file) { + myFileManager.reloadFromDisk(file); + } + + public void addPsiTreeChangeListener(PsiTreeChangeListener listener) { + myTreeChangeListeners.add(listener); + myCachedTreeChangeListeners = null; + } + + public void removePsiTreeChangeListener(PsiTreeChangeListener listener) { + myTreeChangeListeners.remove(listener); + myCachedTreeChangeListeners = null; + } + + public void beforeChildAddition(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_CHILD_ADDITION); + if (LOG.isDebugEnabled()) { + LOG.debug( + "beforeChildAddition: parent = " + event.getParent() + ); + } + fireEvent(event); + } + + public void beforeChildRemoval(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_CHILD_REMOVAL); + if (LOG.isDebugEnabled()) { + LOG.debug( + "beforeChildRemoval: child = " + event.getChild() + + ", parent = " + event.getParent() + ); + } + fireEvent(event); + } + + public void beforeChildReplacement(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_CHILD_REPLACEMENT); + if (LOG.isDebugEnabled()) { + LOG.debug( + "beforeChildReplacement: oldChild = " + event.getOldChild() + + ", parent = " + event.getParent() + ); + } + fireEvent(event); + } + + public void beforeChildrenChange(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_CHILDREN_CHANGE); + if (LOG.isDebugEnabled()) { + LOG.debug("beforeChildrenChange: parent = " + event.getParent()); + } + fireEvent(event); + } + + public void beforeChildMovement(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_CHILD_MOVEMENT); + if (LOG.isDebugEnabled()) { + LOG.debug( + "beforeChildMovement: child = " + event.getChild() + + ", oldParent = " + event.getOldParent() + + ", newParent = " + event.getNewParent() + ); + } + fireEvent(event); + } + + public void beforePropertyChange(PsiTreeChangeEventImpl event) { + event.setCode(BEFORE_PROPERTY_CHANGE); + if (LOG.isDebugEnabled()) { + LOG.debug( + "beforePropertyChange: element = " + event.getElement() + + ", propertyName = " + event.getPropertyName() + + ", oldValue = " + event.getOldValue() + ); + } + fireEvent(event); + } + + public void childAdded(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(CHILD_ADDED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "childAdded: child = " + event.getChild() + + ", parent = " + event.getParent() + ); + } + fireEvent(event); + afterAnyChange(); + } + + public void childRemoved(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(CHILD_REMOVED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "childRemoved: child = " + event.getChild() + ", parent = " + event.getParent() + ); + } + fireEvent(event); + afterAnyChange(); + } + + public void childReplaced(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(CHILD_REPLACED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "childReplaced: oldChild = " + event.getOldChild() + + ", newChild = " + event.getNewChild() + + ", parent = " + event.getParent() + ); + } + fireEvent(event); + afterAnyChange(); + } + + public void childMoved(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(CHILD_MOVED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "childMoved: child = " + event.getChild() + + ", oldParent = " + event.getOldParent() + + ", newParent = " + event.getNewParent() + ); + } + fireEvent(event); + afterAnyChange(); + } + + public void childrenChanged(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(CHILDREN_CHANGED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "childrenChanged: parent = " + event.getParent() + ); + } + fireEvent(event); + afterAnyChange(); + } + + public void propertyChanged(PsiTreeChangeEventImpl event) { + onChange(true); + event.setCode(PROPERTY_CHANGED); + if (LOG.isDebugEnabled()) { + LOG.debug( + "propertyChanged: element = " + event.getElement() + + ", propertyName = " + event.getPropertyName() + + ", oldValue = " + event.getOldValue() + + ", newValue = " + event.getNewValue() + ); + } + fireEvent(event); + afterAnyChange(); + } + + private void fireEvent(PsiTreeChangeEventImpl event) { + boolean isRealTreeChange = event.getCode() != PROPERTY_CHANGED && event.getCode() != BEFORE_PROPERTY_CHANGE; + + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (isRealTreeChange) { + LOG.assertTrue(!myTreeChangeEventIsFiring, "Changes to PSI are not allowed inside event processing"); + } + + if (isRealTreeChange) { + myTreeChangeEventIsFiring = true; + } + try { + myModificationTracker.treeChanged(event); + + if (myCachedTreeChangeListeners == null) { + myCachedTreeChangeListeners = myTreeChangeListeners.toArray( + new PsiTreeChangeListener[myTreeChangeListeners.size()] + ); + } + PsiTreeChangeListener[] listeners = myCachedTreeChangeListeners; + for (int i = 0; i < listeners.length; i++) { + PsiTreeChangeListener listener = listeners[i]; + try { + switch (event.getCode()) { + case BEFORE_CHILD_ADDITION: + listener.beforeChildAddition(event); + break; + + case BEFORE_CHILD_REMOVAL: + listener.beforeChildRemoval(event); + break; + + case BEFORE_CHILD_REPLACEMENT: + listener.beforeChildReplacement(event); + break; + + case BEFORE_CHILD_MOVEMENT: + listener.beforeChildMovement(event); + break; + + case BEFORE_CHILDREN_CHANGE: + listener.beforeChildrenChange(event); + break; + + case BEFORE_PROPERTY_CHANGE: + listener.beforePropertyChange(event); + break; + + case CHILD_ADDED: + listener.childAdded(event); + break; + + case CHILD_REMOVED: + listener.childRemoved(event); + break; + + case CHILD_REPLACED: + listener.childReplaced(event); + break; + + case CHILD_MOVED: + listener.childMoved(event); + break; + + case CHILDREN_CHANGED: + listener.childrenChanged(event); + break; + + case PROPERTY_CHANGED: + listener.propertyChanged(event); + break; + } + } + catch (Exception e) { + LOG.error(e); + } + } + } + finally { + if (isRealTreeChange) { + myTreeChangeEventIsFiring = false; + } + } + } + + public void registerRunnableToRunOnChange(Runnable runnable) { + myRunnablesOnChange.add(runnable); + } + + public void registerWeakRunnableToRunOnChange(Runnable runnable) { + myWeakRunnablesOnChange.add(new WeakReference(runnable)); + } + + public void registerRunnableToRunOnAnyChange(Runnable runnable) { // includes non-physical changes + myRunnablesOnAnyChange.add(runnable); + } + + public void registerRunnableToRunAfterAnyChange(Runnable runnable) { // includes non-physical changes + myRunnablesAfterAnyChange.add(runnable); + } + + public void nonPhysicalChange() { + onChange(false); + } + + private void onChange(boolean isPhysical) { + if (isPhysical) { + runRunnables(myRunnablesOnChange); + + WeakReference[] refs = myWeakRunnablesOnChange.toArray( + new WeakReference[myWeakRunnablesOnChange.size()]); + myWeakRunnablesOnChange.clear(); + for (int i = 0; i < refs.length; i++) { + WeakReference ref = refs[i]; + Runnable runnable = (Runnable)ref.get(); + if (runnable != null) { + runnable.run(); + } + } + } + + runRunnables(myRunnablesOnAnyChange); + } + + private void afterAnyChange() { + runRunnables(myRunnablesAfterAnyChange); + } + + private static void runRunnables(ArrayList runnables) { + Runnable[] array = runnables.toArray(new Runnable[runnables.size()]); + for (int i = 0; i < array.length; i++) { + array[i].run(); + } + } + + public PsiElementFactory getElementFactory() { + return myElementFactory; + } + + public JspElementFactory getJspElementFactory() { + return myJspElementFactory; + } + + public PsiSearchHelper getSearchHelper() { + return mySearchHelper; + } + + public PsiResolveHelper getResolveHelper() { + return myResolveHelper; + } + + public PsiShortNamesCache getShortNamesCache() { + return myShortNamesCache; + } + + public void registerShortNamesCache(PsiShortNamesCache cache) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (myShortNamesCache instanceof CompositeShortNamesCache) { + ((CompositeShortNamesCache)myShortNamesCache).addCache(cache); + } + else { + CompositeShortNamesCache composite = new CompositeShortNamesCache(); + composite.addCache(myShortNamesCache); + composite.addCache(cache); + myShortNamesCache = composite; + } + } + + public PsiMigration startMigration() { + LOG.assertTrue(myCurrentMigration == null); + myCurrentMigration = new PsiMigrationImpl(this); + return myCurrentMigration; + } + + public JavadocManager getJavadocManager() { + return myJavadocManager; + } + + public PsiModificationTracker getModificationTracker() { + return myModificationTracker; + } + + public PsiAspectManager getAspectManager() { + return myAspectManager; + } + + public CachedValuesManager getCachedValuesManager() { + return myCachedValuesManager; + } + + public PsiNameHelper getNameHelper() { + return myNameHelper; + } + + public void moveDirectory(final PsiDirectory dir, PsiDirectory newParent) throws IncorrectOperationException { + checkMove(dir, newParent); + + try { + dir.getVirtualFile().move(this, newParent.getVirtualFile()); + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + } + + public void moveFile(final PsiFile file, PsiDirectory newParent) throws IncorrectOperationException { + checkMove(file, newParent); + + try { + file.getVirtualFile().move(this, newParent.getVirtualFile()); + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + } + + public void checkMove(PsiElement element, PsiElement newContainer) throws IncorrectOperationException { + if (element instanceof PsiPackage) { + PsiDirectory[] dirs = ((PsiPackage)element).getDirectories(); + if (dirs.length == 0) { + throw new IncorrectOperationException(); + } + else if (dirs.length > 1) { + throw new IncorrectOperationException( + "Moving of packages represented by more than one physical directory is not supported."); + } + checkMove(dirs[0], newContainer); + return; + } + + element.checkDelete(); + newContainer.checkAdd(element); + checkIfMoveIntoSelf(element, newContainer); + } + + private void checkIfMoveIntoSelf(PsiElement element, PsiElement newContainer) throws IncorrectOperationException { + PsiElement container = newContainer; + while (container != null) { + if (container == element) { + if (element instanceof PsiDirectory) { + if (element == newContainer) { + throw new IncorrectOperationException("Cannot move directory into itself."); + } + else { + throw new IncorrectOperationException("Cannot move directory into its subdirectory."); + } + } + else { + throw new IncorrectOperationException(); + } + } + container = container.getParent(); + } + } + + public void startBatchFilesProcessingMode() { + myBatchFilesProcessingModeCount++; + } + + public void finishBatchFilesProcessingMode() { + myBatchFilesProcessingModeCount--; + LOG.assertTrue(myBatchFilesProcessingModeCount >= 0); + } + + public boolean isBatchFilesProcessingMode() { + return myBatchFilesProcessingModeCount > 0; + } + + public T getUserData(Key key) { + synchronized (myUserMap) { + return (T)myUserMap.get(key); + } + } + + public void putUserData(Key key, T value) { + synchronized (myUserMap) { + if (value != null) { + myUserMap.put(key, value); + } + else { + myUserMap.remove(key); + } + } + } + + public String getComponentName() { + return "PsiManager"; + } + + public void physicalChange() { + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode(), + "DO NOT use this function in live code!!!"); + onChange(true); + } + + public void migrationModified(boolean terminated) { + if (terminated) { + myCurrentMigration = null; + } + onChange(true); + } + + public PsiClass[] getClasses(PsiPackageImpl psiPackage, GlobalSearchScope scope) { + List result = new ArrayList(); + for (int i = 0; i < myElementFinders.length; i++) { + PsiElementFinder finder = myElementFinders[i]; + PsiClass[] classes = finder.getClasses(psiPackage, scope); + for (int j = 0; j < classes.length; j++) { + PsiClass aClass = classes[j]; + result.add(aClass); + } + } + + return result.toArray(new PsiClass[result.size()]); + } + + public PsiPackage[] getSubPackages(PsiPackageImpl psiPackage, GlobalSearchScope scope) { + List result = new ArrayList(); + for (int i = 0; i < myElementFinders.length; i++) { + PsiElementFinder finder = myElementFinders[i]; + PsiPackage[] packages = finder.getSubPackages(psiPackage, scope); + for (int j = 0; j < packages.length; j++) { + PsiPackage aPackage = packages[j]; + result.add(aPackage); + } + } + + return result.toArray(new PsiPackage[result.size()]); + } + + private class MyExternalResourceListener implements ExternalResourceListener { + public void externalResourceChanged() { + onChange(true); + } + } + + public void setEffectiveLanguageLevel(LanguageLevel languageLevel) { + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode(), "Use PsiManager.setEffectiveLanguageLevel only from unit tests"); + myLanguageLevel = languageLevel; + } + + private class PsiElementFinderImpl implements PsiElementFinder { + public PsiClass findClass(String qualifiedName, GlobalSearchScope scope) { + PsiClass psiClass = myFileManager.findClass(qualifiedName, scope); + + //TODO: remove + if (psiClass == null) { + psiClass = ((PsiAspectManagerImpl)myAspectManager).findAspectByQualifiedName(qualifiedName); + } + + if (psiClass == null && myCurrentMigration != null) { + psiClass = myCurrentMigration.getMigrationClass(qualifiedName); + } + + return psiClass; + } + + public PsiClass[] findClasses(String qualifiedName, GlobalSearchScope scope) { + final PsiClass[] classes = myFileManager.findClasses(qualifiedName, scope); + if (classes.length == 0 && myCurrentMigration != null) { + final PsiClass migrationClass = myCurrentMigration.getMigrationClass(qualifiedName); + if (migrationClass != null) { + return new PsiClass[]{migrationClass}; + } + } + return classes; + } + + public PsiPackage findPackage(String qualifiedName) { + final PsiPackage aPackage = myFileManager.findPackage(qualifiedName); + if (aPackage == null && myCurrentMigration != null) { + final PsiPackage migrationPackage = myCurrentMigration.getMigrationPackage(qualifiedName); + if (migrationPackage != null) return migrationPackage; + } + + return aPackage; + } + + public PsiPackage[] getSubPackages(PsiPackage psiPackage, GlobalSearchScope scope) { + final Map packagesMap = new HashMap(); + final PsiDirectory[] dirs = psiPackage.getDirectories(scope); + for (int i = 0; i < dirs.length; i++) { + PsiDirectory[] subdirs = dirs[i].getSubdirectories(); + for (int j = 0; j < subdirs.length; j++) { + final PsiPackage aPackage = subdirs[j].getPackage(); + if (aPackage != null && !packagesMap.containsKey(aPackage.getQualifiedName())) { + packagesMap.put(aPackage.getQualifiedName(), aPackage); + } + } + } + return packagesMap.values().toArray(new PsiPackage[packagesMap.size()]); + } + + public PsiClass[] getClasses(PsiPackage psiPackage, GlobalSearchScope scope) { + ArrayList list = new ArrayList(); + final PsiDirectory[] dirs = psiPackage.getDirectories(scope); + for (int i = 0; i < dirs.length; i++) { + PsiClass[] classes = dirs[i].getClasses(); + for (int j = 0; j < classes.length; j++) { + list.add(classes[j]); + } + } + return list.toArray(new PsiClass[list.size()]); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiModificationTrackerImpl.java new file mode 100644 index 00000000000..d8227816115 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiModificationTrackerImpl.java @@ -0,0 +1,94 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jul 18, 2002 + * Time: 5:57:57 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiModificationTracker; + +public class PsiModificationTrackerImpl implements PsiModificationTracker { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiModificationTrackerImpl"); + + private PsiManager myManager; + private long myModificationCount = 0; + private long myOutOfCodeBlockModificationCount = 0; + + public PsiModificationTrackerImpl(PsiManager manager) { + myManager = manager; + } + + public void incCounter(){ + myModificationCount++; + myOutOfCodeBlockModificationCount++; + } + + public void treeChanged(PsiTreeChangeEventImpl event) { + myModificationCount++; + + boolean changedInsideCodeBlock = false; + + switch (event.getCode()) { + case PsiManagerImpl.BEFORE_CHILD_ADDITION: + case PsiManagerImpl.BEFORE_CHILD_REMOVAL: + case PsiManagerImpl.BEFORE_CHILDREN_CHANGE: + case PsiManagerImpl.CHILD_ADDED : + case PsiManagerImpl.CHILD_REMOVED : + case PsiManagerImpl.CHILDREN_CHANGED : + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); + break; + + case PsiManagerImpl.BEFORE_PROPERTY_CHANGE: + case PsiManagerImpl.PROPERTY_CHANGED : + changedInsideCodeBlock = false; + break; + + case PsiManagerImpl.BEFORE_CHILD_REPLACEMENT: + case PsiManagerImpl.CHILD_REPLACED : + changedInsideCodeBlock = isInsideCodeBlock(event.getOldChild()); + break; + + case PsiManagerImpl.BEFORE_CHILD_MOVEMENT: + case PsiManagerImpl.CHILD_MOVED : + changedInsideCodeBlock = isInsideCodeBlock(event.getOldParent()) && isInsideCodeBlock(event.getNewParent()); + break; + + default: + LOG.error("Unknown code:" + event.getCode()); + } + + if (!changedInsideCodeBlock) myOutOfCodeBlockModificationCount++; + + myManager.getCachedValuesManager().releaseOutdatedValues(); + } + + public boolean isInsideCodeBlock(PsiElement element) { + if (element.getParent() == null) return true; + while(true){ + if (element instanceof PsiFile || element instanceof PsiDirectory || element == null){ + return false; + } + PsiElement pparent = element.getParent(); + if (element instanceof PsiClass) return false; // anonymous or local class + if (element instanceof PsiCodeBlock){ + if (pparent instanceof PsiMethod || pparent instanceof PsiClassInitializer){ + return true; + } + } + element = pparent; + } + } + + public long getModificationCount() { + return myModificationCount; + } + + public long getOutOfCodeBlockModificationCount() { + return myOutOfCodeBlockModificationCount; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiNameHelperImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiNameHelperImpl.java new file mode 100644 index 00000000000..a9300ab035a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiNameHelperImpl.java @@ -0,0 +1,77 @@ + +package com.intellij.psi.impl; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiLock; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiNameHelper; + +public class PsiNameHelperImpl extends PsiNameHelper{ + private final PsiManager myManager; + private Lexer myLexer; + private LanguageLevel myLastLanguageLevel = LanguageLevel.JDK_1_3; + + public PsiNameHelperImpl(PsiManager manager) { + myManager = manager; + myLastLanguageLevel = LanguageLevel.JDK_1_3; // to be updated by updateLexer() + myLexer = new JavaLexer(myLastLanguageLevel); + } + + private void updateLexer(LanguageLevel languageLevel){ + if (!myLastLanguageLevel.equals(languageLevel)){ + myLastLanguageLevel = languageLevel; + myLexer = new JavaLexer(myLastLanguageLevel); + } + } + + public boolean isIdentifier(String text) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + synchronized (PsiLock.LOCK) { + updateLexer(myManager.getEffectiveLanguageLevel()); + myLexer.start(text.toCharArray()); + if (myLexer.getTokenType() != JavaTokenType.IDENTIFIER) return false; + myLexer.advance(); + return myLexer.getTokenType() == null; + } + } + + public boolean isIdentifier(String text, LanguageLevel languageLevel) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + synchronized (PsiLock.LOCK) { + updateLexer(languageLevel); + myLexer.start(text.toCharArray()); + if (myLexer.getTokenType() != JavaTokenType.IDENTIFIER) return false; + myLexer.advance(); + return myLexer.getTokenType() == null; + } + } + + public boolean isKeyword(String text) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + synchronized (PsiLock.LOCK) { + updateLexer(myManager.getEffectiveLanguageLevel()); + myLexer.start(text.toCharArray()); + if (myLexer.getTokenType() == null || !JavaTokenType.KEYWORD_BIT_SET.isInSet(myLexer.getTokenType())) return false; + myLexer.advance(); + return myLexer.getTokenType() == null; + } + } + + public boolean isQualifiedName(String text){ + int index = 0; + while(true){ + int index1 = text.indexOf('.', index); + if (index1 < 0) index1 = text.length(); + if (!isIdentifier(text.substring(index, index1))) return false; + if (index1 == text.length()) return true; + index = index1 + 1; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiShortNamesCacheImpl.java new file mode 100644 index 00000000000..58d35ab67fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiShortNamesCacheImpl.java @@ -0,0 +1,385 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.psi.*; +import com.intellij.psi.impl.cache.RepositoryIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.util.containers.GenericHashSet; +import com.intellij.util.containers.HashSet; +import gnu.trove.THashMap; +import gnu.trove.TObjectHashingStrategy; + +import java.util.ArrayList; +import java.util.Arrays; + +class PsiShortNamesCacheImpl implements PsiShortNamesCache { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiShortNamesCacheImpl"); + + private final PsiManagerImpl myManager; + private final ProjectFileIndex myProjectFileIndex; + + private THashMap myFileNameToFilesMap = new THashMap(); // short name --> VirtualFile or Pair of VirtualFile or ArrayList of VirtualFile + + private boolean myInitialized = false; + private RepositoryIndex myRepositoryIndex = null; + + public PsiShortNamesCacheImpl(PsiManagerImpl manager, ProjectRootManager projectRootManager) { + myManager = manager; + myProjectFileIndex = projectRootManager.getFileIndex(); + } + + public void runStartupActivity() { + fillCache(); + + myManager.addPsiTreeChangeListener(new MyPsiTreeChangeListener()); + } + + public PsiFile[] getFilesByName(String name) { + synchronized (PsiLock.LOCK) { + fillCache(); + VirtualFile[] vFiles = getFiles(myFileNameToFilesMap, name); + int originalSize = vFiles.length; + ArrayList files = new ArrayList(vFiles.length); + for (int i = 0; i < vFiles.length; i++) { + VirtualFile vFile = vFiles[i]; + if (!vFile.isValid() || myManager.findFile(vFile) == null) { + VirtualFile[] newFiles = new VirtualFile[vFiles.length - 1]; + System.arraycopy(vFiles, 0, newFiles, 0, i); + System.arraycopy(vFiles, i + 1, newFiles, i, newFiles.length - i); + vFiles = newFiles; + i--; + continue; + } + PsiFile file = myManager.findFile(vFile); + files.add(file); + } + if (vFiles.length < originalSize) { + putFiles(myFileNameToFilesMap, name, vFiles); + if (vFiles.length == 0) { + return PsiFile.EMPTY_ARRAY; + } + } + return files.toArray(new PsiFile[files.size()]); + } + } + + public String[] getAllFileNames() { + fillCache(); + return (String[])myFileNameToFilesMap.keySet().toArray(new String[myFileNameToFilesMap.size()]); + } + + public PsiClass[] getClassesByName(String name, final GlobalSearchScope scope) { + VirtualFileFilter filter = getRepositoryIndex().rootFilterBySearchScope(scope); + long[] classIds = getRepositoryIndex().getClassesByShortName(name, filter); + + if (classIds.length == 0) return PsiClass.EMPTY_ARRAY; + RepositoryElementsManager repositoryElementsManager = myManager.getRepositoryElementsManager(); + ArrayList list = new ArrayList(); + IdLoop: + for (int i = 0; i < classIds.length; i++) { + long id = classIds[i]; + PsiClass aClass = (PsiClass)repositoryElementsManager.findOrCreatePsiElementById(id); + VirtualFile vFile = aClass.getContainingFile().getVirtualFile(); + if (!scope.contains(vFile)) continue; + + for (int j = 0; j < list.size(); j++) { + PsiClass aClass1 = list.get(j); + + String qName = aClass.getQualifiedName(); + String qName1 = aClass1.getQualifiedName(); + if (qName != null && qName1 != null && qName.equals(qName1)) { + VirtualFile vFile1 = aClass1.getContainingFile().getVirtualFile(); + int res = scope.compare(vFile1, vFile); + if (res > 0) { + continue IdLoop; // aClass1 hides aClass + } + else if (res < 0) { + list.remove(j); + j--; + continue; // aClass hides aClass1 + } + } + } + + list.add(aClass); + } + return list.toArray(new PsiClass[list.size()]); + } + + public String[] getAllClassNames(boolean searchInLibraries) { + VirtualFileFilter filter = createFilter(searchInLibraries); + return getRepositoryIndex().getAllClassNames(filter); + } + + public void getAllClassNames(boolean searchInLibraries, HashSet set) { + VirtualFileFilter filter = createFilter(searchInLibraries); + getRepositoryIndex().getAllClassNames(filter, set); + } + + public PsiMethod[] getMethodsByName(String name, final GlobalSearchScope scope) { + VirtualFileFilter filter = getRepositoryIndex().rootFilterBySearchScope(scope); + long[] methodIds = getRepositoryIndex().getMethodsByName(name, filter); + + if (methodIds.length == 0) return PsiMethod.EMPTY_ARRAY; + ArrayList list = new ArrayList(); + addElementsByIds(list, methodIds, scope); + return list.toArray(new PsiMethod[list.size()]); + } + + public String[] getAllMethodNames(boolean searchInLibraries) { + VirtualFileFilter filter = createFilter(searchInLibraries); + return getRepositoryIndex().getAllMethodNames(filter); + } + + public void getAllMethodNames(boolean searchInLibraries, HashSet set) { + VirtualFileFilter filter = createFilter(searchInLibraries); + getRepositoryIndex().getAllMethodNames(filter, set); + } + + public PsiField[] getFieldsByName(String name, final GlobalSearchScope scope) { + VirtualFileFilter filter = getRepositoryIndex().rootFilterBySearchScope(scope); + long[] fieldIds = getRepositoryIndex().getFieldsByName(name, filter); + + if (fieldIds.length == 0) return PsiField.EMPTY_ARRAY; + ArrayList list = new ArrayList(); + addElementsByIds(list, fieldIds, scope); + return list.toArray(new PsiField[list.size()]); + } + + public String[] getAllFieldNames(boolean searchInLibraries) { + VirtualFileFilter filter = createFilter(searchInLibraries); + return getRepositoryIndex().getAllFieldNames(filter); + } + + public void getAllFieldNames(boolean searchInLibraries, HashSet set) { + VirtualFileFilter filter = createFilter(searchInLibraries); + getRepositoryIndex().getAllFieldNames(filter, set); + } + + private void addElementsByIds(ArrayList list, long[] ids, final GlobalSearchScope scope) { + RepositoryElementsManager repositoryElementsManager = myManager.getRepositoryElementsManager(); + GenericHashSet set = new GenericHashSet(new TObjectHashingStrategy() { + public int computeHashCode(PsiElement psiElement) { + if (psiElement instanceof PsiMember) { + PsiMember member = (PsiMember)psiElement; + int code = 0; + if (member instanceof PsiMethod) { + code += ((PsiMethod)member).getParameterList().getParameters().length; + } + PsiClass aClass = member.getContainingClass(); + if (aClass != null) { + code += computeHashCode(aClass); + } + return code; + } + else { + LOG.error(psiElement.toString()); + return 0; + } + } + + public boolean equals(PsiElement object, PsiElement object1) { + return myManager.areElementsEquivalent((PsiElement)object, (PsiElement)object1); + } + }); + for (int i = 0; i < ids.length; i++) { + long id = ids[i]; + PsiElement element = repositoryElementsManager.findOrCreatePsiElementById(id); + if (!scope.contains(element.getContainingFile().getVirtualFile())) continue; + if (!set.add(element)) continue; + list.add(element); + } + } + + private VirtualFileFilter createFilter(boolean searchInLibraries) { + if (!searchInLibraries) { + return getRepositoryIndex().rootFilterBySearchScope(GlobalSearchScope.projectScope(myManager.getProject())); + } + else { + return null; + } + } + + private void fillCache() { + if (myInitialized) return; + + _fillCache(); + + myInitialized = true; + } + + private void _fillCache() { + myFileNameToFilesMap.clear(); + + PsiDirectory[] projectRoots = myManager.getRootDirectories(PsiRootPackageType.PROJECT); + for (int i = 0; i < projectRoots.length; i++) { + cacheFilesInDirectory(projectRoots[i]); + } + } + + private void cacheFilesInDirectory(PsiDirectory dir) { + ProgressManager progressManager = ProgressManager.getInstance(); + ProgressIndicator progress = progressManager.getProgressIndicator(); + + if (progress != null) { + progress.pushState(); + progress.setText("Scanning files..."); + } + + _cacheFilesInDirectory(dir); + + if (progress != null) { + progress.popState(); + } + } + + private void _cacheFilesInDirectory(PsiDirectory dir) { + if (LOG.isDebugEnabled()) { + LOG.debug("Scanning files in " + dir.getVirtualFile().getPresentableUrl()); + } + + ProgressManager progressManager = ProgressManager.getInstance(); + ProgressIndicator progress = progressManager.getProgressIndicator(); + if (progress != null) { + progress.setText2(dir.getVirtualFile().getPresentableUrl()); + } + + PsiFile[] files = dir.getFiles(); + for (int i = 0; i < files.length; i++) { + cacheFile(files[i]); + } + + PsiDirectory[] subdirs = dir.getSubdirectories(); + for (int i = 0; i < subdirs.length; i++) { + _cacheFilesInDirectory(subdirs[i]); + } + } + + private void cacheFile(PsiFile file) { + VirtualFile vFile = file.getVirtualFile(); + String fileName = vFile.getName(); + VirtualFile[] files = getFiles(myFileNameToFilesMap, fileName); + if (!Arrays.asList(files).contains(vFile)) { + VirtualFile[] newFiles = new VirtualFile[files.length + 1]; + System.arraycopy(files, 0, newFiles, 0, files.length); + newFiles[files.length] = vFile; + putFiles(myFileNameToFilesMap, fileName, newFiles); + } + } + + private void releaseFile(PsiFile file, String oldName) { + VirtualFile[] files = getFiles(myFileNameToFilesMap, oldName); + ArrayList list = new ArrayList(); + list.addAll(Arrays.asList(files)); + list.remove(file.getVirtualFile()); + putFiles(myFileNameToFilesMap, oldName, list.toArray(new VirtualFile[list.size()])); + } + + private static VirtualFile[] getFiles(THashMap map, String key) { + Object o = map.get(key); + if (o == null) return VirtualFile.EMPTY_ARRAY; + if (o instanceof VirtualFile) { + return new VirtualFile[]{(VirtualFile)o}; + } + else if (o instanceof Pair) { + Pair pair = (Pair)o; + return new VirtualFile[]{(VirtualFile)pair.first, (VirtualFile)pair.second}; + } + else { + return (VirtualFile[])o; + } + } + + private static void putFiles(THashMap map, String key, VirtualFile[] files) { + if (files.length == 0) { + map.remove(key); + } + else if (files.length == 1) { + map.put(key, files[0]); + } + else if (files.length == 2) { + map.put(key, new Pair(files[0], files[1])); + } + else { + map.put(key, files); + } + } + + private RepositoryIndex getRepositoryIndex() { + if (myRepositoryIndex == null) { + myRepositoryIndex = myManager.getRepositoryManager().getIndex(); + } + return myRepositoryIndex; + } + + private class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void childAdded(PsiTreeChangeEvent event) { + if (!myInitialized) return; + PsiElement child = event.getChild(); + if (child instanceof PsiDirectory) { + VirtualFile vFile = ((PsiDirectory)child).getVirtualFile(); + if (myProjectFileIndex.isInContent(vFile)) { + cacheFilesInDirectory((PsiDirectory)child); + } + } + else if (child instanceof PsiFile) { + VirtualFile vFile = ((PsiFile)child).getVirtualFile(); + if (myProjectFileIndex.isInContent(vFile)) { + cacheFile((PsiFile)child); + } + } + } + + public void childMoved(PsiTreeChangeEvent event) { + if (!myInitialized) return; + PsiElement child = event.getChild(); + if (child instanceof PsiDirectory) { + VirtualFile vFile = ((PsiDirectory)child).getVirtualFile(); + if (myProjectFileIndex.isInContent(vFile)) { + cacheFilesInDirectory((PsiDirectory)child); + } + } + else if (child instanceof PsiFile) { + VirtualFile vFile = ((PsiFile)child).getVirtualFile(); + if (myProjectFileIndex.isInContent(vFile)) { + cacheFile((PsiFile)child); + } + } + } + + public void propertyChanged(PsiTreeChangeEvent event) { + if (!myInitialized) return; + + String propertyName = event.getPropertyName(); + if (PsiTreeChangeEvent.PROP_FILE_NAME.equals(propertyName)) { + PsiFile file = (PsiFile)event.getElement(); + String oldName = (String)event.getOldValue(); + releaseFile(file, oldName); + VirtualFile vFile = file.getVirtualFile(); + if (myProjectFileIndex.isInContent(vFile)) { + cacheFile(file); + } + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_ROOTS)) { + myInitialized = false; + /* + _fillCache(); + */ + } + else if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_TYPES)) { + /* + _fillCache(); + */ + myInitialized = false; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSubstitutorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSubstitutorImpl.java new file mode 100644 index 00000000000..a59212df68b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -0,0 +1,325 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author ik, dsl + */ +public class PsiSubstitutorImpl implements PsiSubstitutorEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiSubstitutorImpl"); + private final Map mySubstitutionMap; + + protected PsiSubstitutorImpl(Map map){ + mySubstitutionMap = map; + } + + public PsiSubstitutorImpl(){ + mySubstitutionMap = new HashMap(); + } + + public PsiType substitute(PsiTypeParameter typeParameter){ + if(!mySubstitutionMap.containsKey(typeParameter)){ + return typeParameter.getManager().getElementFactory().createType(typeParameter); + } + return mySubstitutionMap.get(typeParameter); + } + + public PsiType substitute(PsiType type){ + if (type == null) return null; + PsiType substituted = type.accept(myInternalSubstitutionVisitor); + return correctExternalSubstitution(substituted, type, myInternalSubstitutionVisitor); + } + + public PsiType substituteAndCapture(PsiType type){ + if (type == null) return null; + PsiType substituted = type.accept(myInternalCapturingSubstitutionVisitor); + return correctExternalSubstitution(substituted, type, myInternalCapturingSubstitutionVisitor); + } + + private PsiType rawTypeForTypeParameter(final PsiTypeParameter typeParameter) { + final PsiType substType = substitute(typeParameter); + if(substType == null){ + final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); + if(extendsTypes.length > 0){ + // First bound + return substitute(extendsTypes[0]); + } + else { + // Object + return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()); + } + } else { + return substType; + } + } + + private abstract class SubstitutionVisitor extends PsiTypeVisitor { + public PsiType visitType(PsiType type) { + LOG.assertTrue(false); + return null; + } + + public PsiType visitWildcardType(PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); + if (bound == null) return wildcardType; + else + { + final PsiType newBound = bound.accept(this); + if (newBound == null) { + return null; + } else if (newBound instanceof PsiWildcardType) { + final PsiType newBoundBound = ((PsiWildcardType)newBound).getBound(); + if (newBoundBound != null) { + return PsiWildcardType.changeBound(wildcardType, newBoundBound); + } + else { + return PsiWildcardType.createUnbounded(wildcardType.getManager()); + } + } + else { + return PsiWildcardType.changeBound(wildcardType, newBound); + } + } + } + + public PsiType visitPrimitiveType(PsiPrimitiveType primitiveType) { + return primitiveType; + } + + public PsiType visitArrayType(PsiArrayType arrayType) { + final PsiType componentType = arrayType.getComponentType(); + final PsiType substitutedComponentType = componentType.accept(this); + if (substitutedComponentType == null) return null; + if (substitutedComponentType == componentType) return arrayType; // optimization + return new PsiArrayType(substitutedComponentType); + } + + public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) { + final PsiType componentType = ellipsisType.getComponentType(); + final PsiType substitutedComponentType = componentType.accept(this); + if (substitutedComponentType == null) return null; + if (substitutedComponentType == componentType) return ellipsisType; // optimization + return new PsiEllipsisType(substitutedComponentType); + } + + public abstract PsiType visitClassType(PsiClassType classType); + } + + private final InternalSubstitutionVisitor myInternalSubstitutionVisitor = new InternalSubstitutionVisitor(); + private final InternalCapturingSubstitutionVisitor myInternalCapturingSubstitutionVisitor = new InternalCapturingSubstitutionVisitor(); + + private class InternalSubstitutionVisitor extends SubstitutionVisitor { + public PsiType visitClassType(PsiClassType classType) { + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass aClass = resolveResult.getElement(); + if (aClass == null) return classType; + if (aClass instanceof PsiTypeParameter) { + final PsiTypeParameter typeParameter = ((PsiTypeParameter)aClass); + if (!mySubstitutionMap.containsKey(typeParameter)) { + return classType; + } + else { + return substituteTypeParameter(typeParameter); + } + } + final Map hashMap = new HashMap(); + processClass(aClass, resolveResult.getSubstitutor(), hashMap); + return aClass.getManager().getElementFactory().createType(aClass, createSubstitutor(hashMap)); + } + + protected PsiType substituteTypeParameter(final PsiTypeParameter typeParameter) { + return mySubstitutionMap.get(typeParameter); + } + + private PsiType substituteInternal(PsiType type) { + if (type == null) return null; + return type.accept(this); + } + + private void processClass(PsiClass resolve, PsiSubstitutor originalSubstitutor, final Map substMap) { + final PsiTypeParameterList list = resolve.getTypeParameterList(); + final PsiTypeParameter[] params = list != null ? list.getTypeParameters() : null; + for (int i = 0; params != null && i < params.length; i++) { + final PsiTypeParameter param = params[i]; + substMap.put(param, substituteInternal(originalSubstitutor.substitute(param))); + } + if (resolve.hasModifierProperty(PsiModifier.STATIC)) return; + + final PsiClass containingClass = resolve.getContainingClass(); + if (containingClass != null) { + processClass(containingClass, originalSubstitutor, substMap); + } + } + } + + private PsiType correctExternalSubstitution(PsiType substituted, final PsiType original, final InternalSubstitutionVisitor visitor) { + if (original == null) return null; + boolean captured = false; + PsiType copy = substituted; + if (copy instanceof PsiCapturedWildcardType) { + captured = true; + copy = ((PsiCapturedWildcardType)substituted).getWildcard(); + } + if (copy instanceof PsiWildcardType && !((PsiWildcardType)copy).isSuper()) { + PsiWildcardType wildcardType = (PsiWildcardType)copy; + if (original instanceof PsiClassType) { + PsiClass aClass = ((PsiClassType)original).resolve(); + if (aClass instanceof PsiTypeParameter) { + final PsiType boundType = visitor.substituteInternal(aClass.getSuperTypes()[0]); + if (boundType != null && !boundType.equalsToText("java.lang.Object")) { + final PsiManager manager = aClass.getManager(); + if (wildcardType.isExtends()) { + final PsiType glb = GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), boundType); + if (glb != null) { + PsiWildcardType corrected = PsiWildcardType.createExtends(manager, glb); + return captured ? PsiCapturedWildcardType.create(corrected) : ((PsiType)corrected); + } + } + else { + //unbounded + PsiWildcardType corrected = PsiWildcardType.createExtends(manager, boundType); + return captured ? PsiCapturedWildcardType.create(corrected) : ((PsiType)corrected); + } + } + } + } + } + + if (substituted == null) { + return original.accept(new PsiTypeVisitor() { + public PsiType visitArrayType(PsiArrayType arrayType) { + return new PsiArrayType(arrayType.getComponentType().accept(this)); + } + + public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) { + return new PsiEllipsisType(ellipsisType.getComponentType().accept(this)); + } + + public PsiType visitClassType(PsiClassType classType) { + PsiClass aClass = classType.resolve(); + return rawTypeForTypeParameter((PsiTypeParameter)aClass); + } + + public PsiType visitType(PsiType type) { + LOG.assertTrue(false); + return null; + } + }); + } + return substituted; + } + + private class InternalCapturingSubstitutionVisitor extends InternalSubstitutionVisitor { + protected PsiType substituteTypeParameter(PsiTypeParameter typeParameter) { + PsiType type = super.substituteTypeParameter(typeParameter); + if (type instanceof PsiWildcardType && typeParameter.getOwner() instanceof PsiClass) { + return PsiCapturedWildcardType.create((PsiWildcardType)type); + } + return type; + } + } + + public synchronized PsiSubstitutor put(PsiTypeParameter typeParameter, PsiType mapping) { + final PsiSubstitutorImpl ret = new PsiSubstitutorImpl(new HashMap(mySubstitutionMap)); + ret.mySubstitutionMap.put(typeParameter, mapping); + return ret; + } + + public synchronized PsiSubstitutor putAll(PsiClass parentClass, PsiType[] mappings){ + final PsiTypeParameterList list = parentClass.getTypeParameterList(); + if(list == null) return this; + final PsiTypeParameter[] params = list.getTypeParameters(); + PsiSubstitutorImpl substitutor = new PsiSubstitutorImpl(new HashMap(mySubstitutionMap)); + for(int i = 0; i < params.length; i++){ + if(mappings != null && mappings.length > i) + substitutor.mySubstitutionMap.put(params[i], mappings[i]); + else substitutor.mySubstitutionMap.put(params[i], null); + } + + return substitutor; + } + + public PsiSubstitutor putAll(PsiSubstitutor another){ + if(another instanceof EmptySubstitutorImpl) return this; + final PsiSubstitutorImpl anotherImpl = (PsiSubstitutorImpl) another; + final PsiTypeParameter[] params = anotherImpl.mySubstitutionMap.keySet().toArray(PsiTypeParameter.EMPTY_ARRAY); + PsiSubstitutorImpl substitutor = new PsiSubstitutorImpl(new HashMap(mySubstitutionMap)); + for(int i = 0; i < params.length; i++){ + final PsiTypeParameter param = params[i]; + substitutor.mySubstitutionMap.put(param, another.substitute(param)); + } + + return substitutor; + } + + + public PsiSubstitutor merge(PsiSubstitutor other){ + if(other == PsiSubstitutor.EMPTY) return this; + + PsiSubstitutorImpl substitutor = new PsiSubstitutorImpl(new HashMap(mySubstitutionMap)); + substitutor.mySubstitutionMap.putAll(((PsiSubstitutorImpl)other).mySubstitutionMap); + return substitutor; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + final Set> set = mySubstitutionMap.entrySet(); + for (Iterator> iterator = set.iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + final PsiTypeParameter typeParameter = entry.getKey(); + buffer.append(typeParameter.getName()); + final PsiElement owner = typeParameter.getOwner(); + if(owner instanceof PsiClass) + buffer.append(" of " + ((PsiClass) owner).getQualifiedName()); + else if(owner instanceof PsiMethod) + buffer.append(" of " + ((PsiMethod) owner).getName() + " in " + ((PsiMethod) owner).getContainingClass().getQualifiedName()); + buffer.append(" -> "); + if(entry.getValue() != null) + buffer.append(entry.getValue().getCanonicalText()); + else + buffer.append("null"); + buffer.append('\n'); + } + return buffer.toString(); + } + + public static PsiSubstitutor createSubstitutor(Map map){ + if(map == null || map.keySet().isEmpty()) return EMPTY; + return new PsiSubstitutorImpl(map); + } + + public boolean isValid() { + Collection substitutorValues = mySubstitutionMap.values(); + for (Iterator it = substitutorValues.iterator(); it.hasNext ();) { + PsiType type = it.next(); + if (type != null && !type.isValid()) return false; + } + return true; + } + + public Map getSubstitutionMap() { + return Collections.unmodifiableMap(mySubstitutionMap); + } + + public PsiSubstitutor inplacePut(PsiTypeParameter typeParameter, PsiType mapping) { + mySubstitutionMap.put(typeParameter, mapping); + return this; + } + + public PsiSubstitutor inplacePutAll(PsiClass parentClass, PsiType[] mappings) { + final PsiTypeParameterList list = parentClass.getTypeParameterList(); + if(list == null) return this; + final PsiTypeParameter[] params = list.getTypeParameters(); + + for(int i = 0; i < params.length; i++){ + if(mappings != null && mappings.length > i) mySubstitutionMap.put(params[i], mappings[i]); + else mySubstitutionMap.put(params[i], null); + } + + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSuperMethodImplUtil.java new file mode 100644 index 00000000000..ebbc0bf9090 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -0,0 +1,315 @@ +package com.intellij.psi.impl; + +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.j2ee.ejb.role.EjbImplMethodRole; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Collections; + +public class PsiSuperMethodImplUtil { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.util.PsiSuperMethodImplUtil"); + + public static PsiPointcutDef findSuperPointcut(PsiPointcutDef pointcut) { + return findSuperPointcut(pointcut, pointcut.getContainingAspect()); + } + + private static PsiPointcutDef findSuperPointcut(PsiPointcutDef pointcut, PsiAspect psiAspect) { + PsiClass superClass = psiAspect.getSuperClass(); + + while (!(superClass instanceof PsiAspect) && superClass != null) superClass = superClass.getSuperClass(); + if (superClass == null) return null; + + PsiAspect superAspect = (PsiAspect)superClass; + return superAspect.findPointcutDefBySignature(pointcut, true); + } + + public static PsiPointcutDef findDeepestSuperPointcut(PsiPointcutDef pointcut) { + PsiPointcutDef superPointcut = findSuperPointcut(pointcut); + PsiPointcutDef prevSuperPointcut = null; + + while (superPointcut != null) { + prevSuperPointcut = superPointcut; + superPointcut = findSuperPointcut(prevSuperPointcut); + } + + return prevSuperPointcut; + } + + public static PsiMethod[] findSuperMethods(PsiMethod method) { + return findSuperMethods(method, method.getContainingClass()); + } + + public static PsiMethod[] findSuperMethods(PsiMethod method, boolean checkAccess) { + if (!canHaveSuperMethod(method, checkAccess, false)) return PsiMethod.EMPTY_ARRAY; + final PsiClass aClass = method.getContainingClass(); + return findSuperMethodsInternal(method, aClass); + } + + public static PsiMethod[] findSuperMethods(PsiMethod method, PsiClass parentClass) { + if (!canHaveSuperMethod(method, true, false)) return PsiMethod.EMPTY_ARRAY; + return findSuperMethodsInternal(method, parentClass); + } + + + private static PsiMethod[] findSuperMethodsInternal(PsiMethod method, PsiClass parentClass) { + List outputMethods = findSuperMethodSignatures(method, parentClass, false); + + return MethodSignatureUtil.convertMethodSignaturesToMethods(outputMethods); + } + + public static List findSuperMethodSignaturesIncludingStatic(PsiMethod method, + boolean checkAccess) { + if (!canHaveSuperMethod(method, checkAccess, true)) return Collections.EMPTY_LIST; + return findSuperMethodSignatures(method, method.getContainingClass(), true); + } + + private static List findSuperMethodSignatures(PsiMethod method, + PsiClass parentClass, boolean allowStaticMethod) { + final boolean isStatic = method.hasModifierProperty(PsiModifier.STATIC); + final MethodSignatureUtil.MethodSignatureToMethods allMethodsCollection = MethodSignatureUtil.getSameSignatureMethods(parentClass); + final MethodSignature originalMethodSignature = method.getSignature(PsiSubstitutor.EMPTY); + final List methods = allMethodsCollection.get(originalMethodSignature); + List sameSignatureMethods = new ArrayList(); + if (methods != null) { + sameSignatureMethods.addAll(methods); + } + final EjbMethodRole role = J2EERolesUtil.getEjbRole(method); + if (role instanceof EjbImplMethodRole) { + final PsiMethod[] ejbDeclarations = EjbUtil.findEjbDeclarations(method); + for (int i = 0; i < ejbDeclarations.length; i++) { + PsiMethod ejbDeclaration = ejbDeclarations[i]; + sameSignatureMethods.add(new MethodSignatureBackedByPsiMethod(ejbDeclaration, PsiSubstitutor.EMPTY)); + } + } + PsiManager manager = method.getManager(); + + List outputMethods = new ArrayList(); + AllMethodsLoop: + for (int i = 0; i < sameSignatureMethods.size(); i++) { + final MethodSignatureBackedByPsiMethod methodSignature = sameSignatureMethods.get(i); + PsiMethod superMethod = methodSignature.getMethod(); + PsiClass superClass = superMethod.getContainingClass(); + if (superClass == null || manager.areElementsEquivalent(superClass, parentClass)) continue; + final boolean isSuperStatic = superMethod.hasModifierProperty(PsiModifier.STATIC); + if (isStatic != isSuperStatic) continue; + if (!allowStaticMethod && isSuperStatic) continue; + if (superMethod.hasModifierProperty(PsiModifier.PRIVATE)) continue; + // cannot override package local method from other package + if (superMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) + && !manager.arePackagesTheSame(parentClass, superClass)) { + continue; + } + + for (int j = 0; j < outputMethods.size(); j++) { + final MethodSignatureBackedByPsiMethod methodSignature1 = outputMethods.get(j); + PsiMethod superMethod1 = methodSignature1.getMethod(); + PsiClass superClass1 = superMethod1.getContainingClass(); + if (superClass1.isInheritor(superClass, true)) { + continue AllMethodsLoop; + } + if (superClass.isInheritor(superClass1, true)) { + outputMethods.set(j, methodSignature); + continue AllMethodsLoop; + } + } + outputMethods.add(methodSignature); + } + return outputMethods; + } + + public static PsiMethod findConstructorInSuper(PsiMethod constructor) { + if (constructor.getBody() != null) { + PsiStatement[] statements = constructor.getBody().getStatements(); + if (statements.length > 0) { + PsiElement firstChild = statements[0].getFirstChild(); + if (firstChild instanceof PsiMethodCallExpression) { + PsiReferenceExpression superExpr = ((PsiMethodCallExpression)firstChild).getMethodExpression(); + if (superExpr.getText().equals("super")) { + PsiElement superConstructor = superExpr.resolve(); + if (superConstructor instanceof PsiMethod) { + return (PsiMethod)superConstructor; + } + } + } + } + } + + PsiClass containingClass = constructor.getContainingClass(); + if (containingClass != null) { + PsiClass superClass = containingClass.getSuperClass(); + if (superClass != null) { + PsiMethod defConstructor = constructor.getManager().getElementFactory().createConstructor(); + try { + defConstructor.getNameIdentifier().replace(superClass.getNameIdentifier().copy()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + return superClass.findMethodBySignature(defConstructor, false); + } + } + return null; + } + + private static boolean canHaveSuperMethod(PsiMethod method, boolean checkAccess, boolean allowStaticMethod) { + if (method.isConstructor()) return false; + if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) return false; + if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) return false; + PsiClass parentClass = method.getContainingClass(); + if (parentClass == null) return false; + if ("java.lang.Object".equals(parentClass.getQualifiedName())) return false; + return true; + } + + public static PsiMethod findDeepestSuperMethod(PsiMethod method) { + if (method.isConstructor()) return null; + if (method.hasModifierProperty(PsiModifier.STATIC)) return null; + if (method.hasModifierProperty(PsiModifier.PRIVATE)) return null; + + PsiClass aClass = method.getContainingClass(); + if (aClass == null) { + return null; + } + + final PsiMethod[] allMethods; + + PsiMethod[] ejbDeclarations = EjbUtil.findEjbDeclarations(method); + boolean isEjbInherited = J2EERolesUtil.getEjbRole(method) instanceof EjbImplMethodRole && ejbDeclarations.length != 0; + if (isEjbInherited) { + allMethods = ejbDeclarations; + } + else { + allMethods = aClass.getAllMethods(); + } + PsiMethod topSuper = null; + for (int i = 0; i < allMethods.length; i++) { + PsiMethod superMethod = allMethods[i]; + PsiClass superClass = superMethod.getContainingClass(); + if (superClass.equals(aClass)) continue; + PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); + if (superClassSubstitutor == null) superClassSubstitutor = PsiSubstitutor.EMPTY; + boolean looksLikeSuperMethod = method.getName().equals(superMethod.getName()) && + !superMethod.hasModifierProperty(PsiModifier.STATIC) && + PsiUtil.isAccessible(superMethod, aClass, aClass) && + method.getSignature(PsiSubstitutor.EMPTY).equals(superMethod.getSignature(superClassSubstitutor)); + if (isEjbInherited || looksLikeSuperMethod) { + if (topSuper != null && superClass.isInheritor(topSuper.getContainingClass(), true)) { + continue; + } + topSuper = superMethod; + } + } + return topSuper; + } + + /** + * @return all overridden methods sorted by hierarchy, + * i.e Map: PsiMethod method -> List of overridden methods (access control rules are respected) + */ + public static Map getMethodHierarchy(PsiMethod method) { + final PsiClass aClass = method.getContainingClass(); + if (aClass == null) return null; + return getMethodHierarchy(method, aClass); + } + + public static Map getMethodHierarchy(PsiMethod method, PsiClass aClass) { + Map map = new HashMap(); + List allMethods = new ArrayList(); + getMethodHierarchy(method, aClass, map, allMethods); + return map; + } + + public static Map getMethodHierarchy(MethodSignature method, PsiClass containingClass) { + final Map map = new HashMap(); + final List allMethods = new ArrayList(); + getMethodHierarchy(method, containingClass, map, allMethods); + return map; + } + + private static void getMethodHierarchy(Object method, PsiClass aClass, Map map, List allMethods) { + final PsiClass[] superTypes = aClass.getSupers(); + final int startMethodIndex = allMethods.size(); + for (int i = 0; i < superTypes.length; i++) { + PsiClass superType = superTypes[i]; + final PsiMethod superMethod; + if (method instanceof PsiMethod) { + superMethod = MethodSignatureUtil.findMethodBySignature(superType, (PsiMethod)method, false); + } + else { + superMethod = MethodSignatureUtil.findMethodBySignature(superType, (MethodSignature)method, false); + } + if (superMethod == null) { + getMethodHierarchy(method, superType, map, allMethods); + } + else { + if (PsiUtil.isAccessible(superMethod, aClass, aClass)) { + allMethods.add(superMethod); + } + } + } + final int endMethodIndex = allMethods.size(); + map.put(method, new ArrayList(allMethods.subList(startMethodIndex, endMethodIndex))); + for (int i = startMethodIndex; i < endMethodIndex; i++) { + final PsiMethod superMethod = (PsiMethod)allMethods.get(i); + if (map.get(superMethod) == null) { + getMethodHierarchy(superMethod, superMethod.getContainingClass(), map, allMethods); + } + } + } + + // remove from list all methods overridden by contextClass or its super classes + // if (checkForSiblingOverride) then abstract method inherited from superClass1 and implemented in superClass2 considered to be overridden by contextClass + public static void removeOverriddenMethods(List sameSignatureMethods, + PsiClass contextClass, + boolean checkForSiblingOverride) { + for (int i = sameSignatureMethods.size() - 1; i >= 0; i--) { + final MethodSignatureBackedByPsiMethod methodBackedMethodSignature1 = sameSignatureMethods.get(i); + PsiMethod method1 = methodBackedMethodSignature1.getMethod(); + final PsiClass class1 = method1.getContainingClass(); + if (method1.hasModifierProperty(PsiModifier.STATIC) + || method1.hasModifierProperty(PsiModifier.PRIVATE)) { + continue; + } + // check if method1 is overridden + boolean overridden = false; + for (int j = 0; j < sameSignatureMethods.size(); j++) { + if (i == j) continue; + final MethodSignatureBackedByPsiMethod methodBackedMethodSignature2 = sameSignatureMethods.get(j); + PsiMethod method2 = methodBackedMethodSignature2.getMethod(); + final PsiClass class2 = method2.getContainingClass(); + if (InheritanceUtil.isInheritorOrSelf(class2, class1, true) + // method from interface cannot override method from Object + && !("java.lang.Object".equals(class1.getQualifiedName()) && class2.isInterface()) + && !(method1.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !method1.getManager().arePackagesTheSame(class1, class2))) { + overridden = true; + break; + } + // check for sibling override: class Context extends Implementations implements Declarations {} + // see JLS 8.4.6.4 + if (checkForSiblingOverride + && !method2.hasModifierProperty(PsiModifier.ABSTRACT) + && PsiUtil.isAccessible(method1, contextClass, contextClass) + && PsiUtil.isAccessible(method2, contextClass, contextClass)) { + overridden = true; + break; + } + } + if (overridden) { + sameSignatureMethods.remove(i); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiToDocumentSynchronizer.java new file mode 100644 index 00000000000..b4bb671d944 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -0,0 +1,179 @@ + +package com.intellij.psi.impl; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.psi.*; +import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.jsp.JspxFileImpl; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiToDocumentSynchronizer"); + + private final SmartPointerManagerImpl mySmartPointerManager; + private PsiDocumentManagerImpl myPsiDocumentManager; + + public PsiToDocumentSynchronizer(PsiDocumentManagerImpl psiDocumentManager, SmartPointerManagerImpl smartPointerManager) { + mySmartPointerManager = smartPointerManager; + myPsiDocumentManager = psiDocumentManager; + } + + private static interface DocSyncAction { + void syncDocument(Document document, PsiTreeChangeEventImpl event); + } + private void doSync(PsiTreeChangeEvent event, DocSyncAction syncAction) { + if (!toProcessPsiEvent()) { + return; + } + PsiFile psiFile = event.getFile(); + if (psiFile == null) return; + DocumentEx document = getCachedDocument(psiFile); + if (document == null) return; + + TextBlock textBlock = getTextBlock(document); + if (!textBlock.isEmpty()) { + LOG.error("Attempt to modify PSI for non-commited Document!"); + textBlock.clear(); + } + + TreeElement element = SourceTreeToPsiMap.psiElementToTree(event.getParent()); + while(element != null && !(element instanceof FileElement)) { + element = element.getTreeParent(); + } + PsiFile fileForDoc = PsiDocumentManager.getInstance(psiFile.getProject()).getPsiFile(document); + boolean isOriginal = element != null ? fileForDoc == SourceTreeToPsiMap.treeElementToPsi(element) : false; + LOG.debug("DOCSync: " + isOriginal + "; document=" + document+"; file="+psiFile.getName() + ":" + + psiFile.getClass() +"; file for doc="+fileForDoc.getName()+"; virtualfile="+psiFile.getVirtualFile()); + + if (isOriginal) { + myPsiDocumentManager.setProcessDocumentEvents(false); + syncAction.syncDocument(document, (PsiTreeChangeEventImpl)event); + document.setModificationStamp(psiFile.getModificationStamp()); + myPsiDocumentManager.setProcessDocumentEvents(true); + mySmartPointerManager.synchronizePointers(psiFile); + if (LOG.isDebugEnabled()) { + PsiDocumentManagerImpl.checkConsistency(psiFile, document); + if (psiFile instanceof JspxFileImpl) { + ( (JspxFileImpl)psiFile).checkAllConsistent(); + } + } + } + } + + public void childAdded(final PsiTreeChangeEvent event) { + doSync(event, new DocSyncAction() { + public void syncDocument(Document document, PsiTreeChangeEventImpl event) { + insertString(document, event.getOffset(), event.getChild().getText()); + } + }); + } + + public void childRemoved(final PsiTreeChangeEvent event) { + doSync(event, new DocSyncAction() { + public void syncDocument(Document document, PsiTreeChangeEventImpl event) { + deleteString(document, event.getOffset(), event.getOffset() + event.getOldLength()); + } + }); + } + + public void childReplaced(final PsiTreeChangeEvent event) { + doSync(event, new DocSyncAction() { + public void syncDocument(Document document, PsiTreeChangeEventImpl event) { + replaceString(document, event.getOffset(), event.getOffset() + event.getOldLength(), event.getNewChild().getText()); + } + }); + } + + public void childrenChanged(final PsiTreeChangeEvent event) { + doSync(event, new DocSyncAction() { + public void syncDocument(Document document, PsiTreeChangeEventImpl event) { + replaceString(document, event.getOffset(), event.getOffset() + event.getOldLength(), event.getParent().getText()); + } + }); + } + + public void beforeChildReplacement(PsiTreeChangeEvent event) { + processBeforeEvent(event); + } + + public void beforeChildAddition(PsiTreeChangeEvent event) { + processBeforeEvent(event); + } + + public void beforeChildRemoval(PsiTreeChangeEvent event) { + processBeforeEvent(event); + } + + private void processBeforeEvent(PsiTreeChangeEvent event) { + if (toProcessPsiEvent()) { + PsiFile psiFile = event.getParent().getContainingFile(); + if (psiFile == null) return; + + //TODO: get red of this? + mySmartPointerManager.fastenBelts(psiFile); + mySmartPointerManager.unfastenBelts(psiFile); + } + } + + private static boolean toProcessPsiEvent() { + Application application = ApplicationManager.getApplication(); + return application.getCurrentWriteAction(CommitToPsiFileAction.class) == null + && application.getCurrentWriteAction(PsiExternalChangeAction.class) == null; + } + + private static void replaceString(Document document, int startOffset, int endOffset, String s) { + DocumentEx ex = (DocumentEx) document; + ex.suppressGuardedExceptions(); + try { + boolean isReadOnly = !document.isWritable(); + ex.setReadOnly(false); + ex.replaceString(startOffset, endOffset, s); + ex.setReadOnly(isReadOnly); + } + finally { + ex.unSuppressGuardedExceptions(); + } + } + + private static void insertString(Document document, int offset, String s) { + DocumentEx ex = (DocumentEx) document; + ex.suppressGuardedExceptions(); + try { + boolean isReadOnly = !ex.isWritable(); + ex.setReadOnly(false); + ex.insertString(offset, s); + ex.setReadOnly(isReadOnly); + } + finally { + ex.unSuppressGuardedExceptions(); + } + } + + private static void deleteString(Document document, int startOffset, int endOffset){ + DocumentEx ex = (DocumentEx) document; + ex.suppressGuardedExceptions(); + try { + boolean isReadOnly = !ex.isWritable(); + ex.setReadOnly(false); + ex.deleteString(startOffset, endOffset); + ex.setReadOnly(isReadOnly); + } + finally { + ex.unSuppressGuardedExceptions(); + } + } + + private DocumentEx getCachedDocument(PsiFile file) { + return (DocumentEx)myPsiDocumentManager.getCachedDocument(file); + } + + private TextBlock getTextBlock(Document document) { + return myPsiDocumentManager.getTextBlock(document); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiTreeChangeEventImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiTreeChangeEventImpl.java new file mode 100644 index 00000000000..596bfa54269 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiTreeChangeEventImpl.java @@ -0,0 +1,79 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.*; + +public class PsiTreeChangeEventImpl extends PsiTreeChangeEvent{ + private int myCode; + + public PsiTreeChangeEventImpl(PsiManager manager) { + super(manager); + } + + public int getCode() { + return myCode; + } + + public void setCode(int code) { + myCode = code; + } + + public void setParent(PsiElement parent) { + myParent = parent; + } + + public void setOldParent(PsiElement oldParent) { + myOldParent = oldParent; + } + + public void setNewParent(PsiElement newParent) { + myNewParent = newParent; + } + + public void setChild(PsiElement child) { + myChild = child; + } + + public void setOldChild(PsiElement oldChild) { + myOldChild = oldChild; + } + + public void setNewChild(PsiElement newChild) { + myNewChild = newChild; + } + + public void setElement(PsiElement element) { + myElement = element; + } + + public void setPropertyName(String propertyName) { + myPropertyName = propertyName; + } + + public void setOldValue(Object oldValue) { + myOldValue = oldValue; + } + + public void setNewValue(Object newValue) { + myNewValue = newValue; + } + + public void setFile(PsiFile file) { + myFile = file; + } + + public void setOffset(int offset) { + myOffset = offset; + } + + public int getOffset() { + return myOffset; + } + + public void setOldLength(int oldLength) { + myOldLength = oldLength; + } + + public int getOldLength() { + return myOldLength; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiVariableEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiVariableEx.java new file mode 100644 index 00000000000..847090a126e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/PsiVariableEx.java @@ -0,0 +1,9 @@ +package com.intellij.psi.impl; + +import com.intellij.psi.*; + +import java.util.Set; + +public interface PsiVariableEx extends PsiVariable{ + Object computeConstantValue(Set visitedVars); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/SharedPsiElementImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/SharedPsiElementImplUtil.java new file mode 100644 index 00000000000..caf99000b18 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/SharedPsiElementImplUtil.java @@ -0,0 +1,95 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +public class SharedPsiElementImplUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.SharedPsiElementImplUtil"); + + public static PsiReference findReferenceAt(PsiElement thisElement, int offset) { + if(thisElement == null) + return null; + PsiElement element = thisElement.findElementAt(offset); + if (element == null) return null; + offset = thisElement.getTextRange().getStartOffset() + offset - element.getTextRange().getStartOffset(); + + while(element != null) { + final PsiReference[] ref = extractReference(offset, element); + if (ref.length == 1) return ref[0]; + else if(ref.length > 1) return new PsiMultiReference(ref, element); + + offset = element.getStartOffsetInParent() + offset; + element = element.getParent(); + } + + return null; + } + + private static PsiReference[] extractReference(int offset, PsiElement element) { + final List referencesList = new ArrayList(); + int offsetInElement = offset; + + + final PsiReference[] references = element.getReferences(); + LOG.assertTrue(references != null, element.toString()); + for (int i = 0; i < references.length; i++) { + final PsiReference reference = references[i]; + if (reference == null) { + LOG.error(element.toString()); + } + final TextRange range = reference.getRangeInElement(); + if (range.getStartOffset() <= offsetInElement && (offsetInElement < range.getEndOffset() || (offsetInElement == range.getEndOffset() && range.getLength() == 0))) { + referencesList.add(reference); + } + } + + return referencesList.toArray(new PsiReference[referencesList.size()]); + } + + public static PsiReference[] getReferences(PsiElement thisElement) { + PsiReference ref = thisElement.getReference(); + if (ref == null) return PsiReference.EMPTY_ARRAY; + return new PsiReference[] {ref}; + } + + public static PsiElement getNextSibling(PsiElement element) { + PsiElement parent = element.getParent(); + if (parent == null) return null; + PsiElement[] children = parent.getChildren(); + for(int i = 0; i < children.length; i++){ + PsiElement child = children[i]; + if (child.equals(element)) { + return i < children.length - 1 ? children[i + 1] : null; + } + } + LOG.assertTrue(false); + return null; + } + + public static PsiElement getPrevSibling(PsiElement element) { + PsiElement parent = element.getParent(); + if (parent == null) return null; + PsiElement[] children = parent.getChildren(); + for(int i = 0; i < children.length; i++){ + PsiElement child = children[i]; + if (child.equals(element)) { + return i > 0 ? children[i - 1] : null; + } + } + LOG.assertTrue(false); + return null; + } + + public static PsiElement setName(PsiElement element, String name) throws IncorrectOperationException{ + PsiManager manager = element.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + PsiIdentifier newNameIdentifier = factory.createIdentifier(name); + return element.replace(newNameIdentifier); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/TextBlock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/TextBlock.java new file mode 100644 index 00000000000..e7df119c969 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/TextBlock.java @@ -0,0 +1,52 @@ +package com.intellij.psi.impl; + +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; + +public class TextBlock extends DocumentAdapter { + private int myStartOffset = -1; + private int myTextEndOffset = -1; + private int myPsiEndOffset = -1; + + public boolean isEmpty() { + return myStartOffset == -1; + } + + public void clear() { + myStartOffset = -1; + } + + public int getStartOffset() { + return myStartOffset; + } + + public int getTextEndOffset() { + return myTextEndOffset; + } + + public int getPsiEndOffset() { + return myPsiEndOffset; + } + + public void documentChanged(DocumentEvent e) { + final int offset = e.getOffset(); + if (isEmpty()) { + myStartOffset = offset; + myTextEndOffset = offset + e.getNewLength(); + myPsiEndOffset = offset + e.getOldLength(); + } + else { + int shift = offset + e.getOldLength() - myTextEndOffset; + if (shift > 0) { + myPsiEndOffset += shift; + myTextEndOffset = offset + e.getNewLength(); + } + else { + int sizeDelta = e.getNewLength() - e.getOldLength(); + myTextEndOffset += sizeDelta; + } + + myStartOffset = Math.min(myStartOffset, offset); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/CacheManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/CacheManager.java new file mode 100644 index 00000000000..9862acd289b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/CacheManager.java @@ -0,0 +1,36 @@ +package com.intellij.psi.impl.cache; + +import com.intellij.ide.startup.CacheUpdater; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.TodoPattern; +import com.intellij.psi.PsiFile; + +public interface CacheManager { + void initialize(); + void dispose(); + CacheUpdater[] getCacheUpdaters(); + + PsiFile[] getFilesWithWord(String word, short occurenceMask, GlobalSearchScope scope); + + /** + * @return all VirtualFile's that contain todo-items under project roots + */ + PsiFile[] getFilesWithTodoItems(); + + /** + * @return -1 if it's not known + */ + int getTodoCount(VirtualFile file); + + /** + * @return -1 if it's not known + */ + int getTodoCount(VirtualFile file, TodoPattern pattern); + + /** + * @deprecated + */ + void addOrInvalidateFile(VirtualFile file); +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassInitializerView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassInitializerView.java new file mode 100644 index 00000000000..8b904ebbce8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassInitializerView.java @@ -0,0 +1,7 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface ClassInitializerView extends DeclarationView { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassView.java new file mode 100644 index 00000000000..3f1a8c57896 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ClassView.java @@ -0,0 +1,30 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface ClassView extends DeclarationView { + String getQualifiedName(long classId); + boolean isInterface(long classId); + boolean isAnonymous(long classId); + boolean isAnnotationType (long classId); + + int getParametersListSize(long classId); + String getParameterText(long classId, int parameterIdx); + + long[] getMethods(long classId); + long[] findMethodsByName(long classId, String name); + long[] getFields(long classId); + long findFieldByName(long classId, String name); + long[] getInitializers(long classId); + + String getBaseClassReferenceText(long classId); + boolean isInQualifiedNew(long classId); + + String[] getExtendsList(long classId); + String[] getImplementsList(long classId); + + boolean isEnum(long classId); + + boolean isEnumConstantInitializer(long classId); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DeclarationView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DeclarationView.java new file mode 100644 index 00000000000..1714c827ec3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DeclarationView.java @@ -0,0 +1,14 @@ +package com.intellij.psi.impl.cache; + + + +/** + * @author max + */ +public interface DeclarationView extends RepositoryItemView { + int getModifiers(long id); + boolean isDeprecated(long id); + boolean mayBeDeprecatedByAnnotation(long id); //for source elements only, for cls the value of the attribute is written + long[] getInnerClasses(long id); + String[] getAnnotations (long id); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DirectoryView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DirectoryView.java new file mode 100644 index 00000000000..e879f28c39a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/DirectoryView.java @@ -0,0 +1,9 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface DirectoryView extends RepositoryItemView { + long[] getDirs(long id); + long[] getFiles(long id); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FieldView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FieldView.java new file mode 100644 index 00000000000..6d07202b484 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FieldView.java @@ -0,0 +1,18 @@ +package com.intellij.psi.impl.cache; + + + +/** + * @author max + */ +public interface FieldView extends DeclarationView { + long getFirstFieldInDeclaration(long fieldId); + + String getTypeText(long fieldId); + + String getInitializerText(long fieldId) throws InitializerTooLongException; + + boolean isEnumConstant (long fieldId); + + long getEnumConstantInitializer(long fieldId); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FileView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FileView.java new file mode 100644 index 00000000000..e4f0fc66ba6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/FileView.java @@ -0,0 +1,26 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface FileView extends RepositoryItemView { + long getTimestamp(long fileId); + + String getPackageName(long fileId); + + int getImportStatementsCount(long fileId); + + boolean isImportOnDemand(long fileId, int importStatementIdx); + + boolean isImportStatic(long fileId, int importStatementIdx); + + String getImportQualifiedName(long fileId, int importStatementIdx); + + long[] getClasses(long fileId); + + long[] getAllClasses(long fileId); + + String getSourceFileName(long classId); + + int getLength(long fileId); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/InitializerTooLongException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/InitializerTooLongException.java new file mode 100644 index 00000000000..1cbb4865a02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/InitializerTooLongException.java @@ -0,0 +1,4 @@ +package com.intellij.psi.impl.cache; + +public class InitializerTooLongException extends Exception{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/MethodView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/MethodView.java new file mode 100644 index 00000000000..dfede95a358 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/MethodView.java @@ -0,0 +1,24 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface MethodView extends DeclarationView { + boolean isConstructor(long methodId); + boolean isVarArgs(long methodId); + + String getReturnTypeText(long methodId); + + int getParameterCount(long methodId); + String getParameterName(long methodId, int paramIdx); + String getParameterTypeText(long methodId, int paramIdx); + + int getTypeParametersCount(long methodId); + String getTypeParameterText(long methodId, int paramIdx); + + String[] getThrowsList(long methodId); + + boolean isAnnotationMethod(long methodId); + String getDefaultValueText(long methodId); + String[][] getParameterAnnotations (long methodId); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ModifierFlags.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ModifierFlags.java new file mode 100644 index 00000000000..f87d890a608 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/ModifierFlags.java @@ -0,0 +1,27 @@ +package com.intellij.psi.impl.cache; + +/** + * @author max + */ +public interface ModifierFlags { +// ---- Group equals to correspoding in ClsUtil's ACC_* + int PUBLIC_MASK = 0x0001; + int PRIVATE_MASK = 0x0002; + int PROTECTED_MASK = 0x0004; + int STATIC_MASK = 0x0008; + int FINAL_MASK = 0x0010; + int SYNCHRONIZED_MASK = 0x0020; + int VOLATILE_MASK = 0x0040; + int TRANSIENT_MASK = 0x0080; + int NATIVE_MASK = 0x0100; + int INTERFACE_MASK = 0x0200; + int ABSTRACT_MASK = 0x0400; +// ---- End of the group equals to correspoding in ClsUtil's ACC_* + + int STRICTFP_MASK = 0x0800; + int PACKAGE_LOCAL_MASK = 0x1000; + int DEPRECATED_MASK = 0x2000; + int ENUM_MASK = 0x4000; + int ANNOTATION_TYPE_MASK = 0x8000; + int ANNOTATION_DEPRECATED_MASK = 0x10000; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryElementType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryElementType.java new file mode 100644 index 00000000000..5f1184b1f67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryElementType.java @@ -0,0 +1,34 @@ +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Nov 13, 2002 + * Time: 10:36:49 PM + * To change this template use Options | File Templates. + */ +package com.intellij.psi.impl.cache; + +public class RepositoryElementType { + public static final RepositoryElementType DIR = new RepositoryElementType("DIR", 0); + public static final RepositoryElementType FILE = new RepositoryElementType("FILE", 1); + public static final RepositoryElementType CLASS = new RepositoryElementType("CLASS", 2); + public static final RepositoryElementType METHOD = new RepositoryElementType("METHOD", 3); + public static final RepositoryElementType FIELD = new RepositoryElementType("FIELD", 4); + public static final RepositoryElementType CLASS_INITIALIZER = new RepositoryElementType("CLASS_INITIALIZER", 5); + + private final String myName; // for debug only + private final int myType; + + + private RepositoryElementType(String name, int type) { + myName = name; + myType = type; + } + + public String toString() { + return myName; + } + + public int getType() { + return myType; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryItemView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryItemView.java new file mode 100644 index 00000000000..bba6ba36b06 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/RepositoryItemView.java @@ -0,0 +1,17 @@ +package com.intellij.psi.impl.cache; + + +/** + * @author max + */ +public interface RepositoryItemView { + String getName(long id); + + long getParent(long id); + + long[] getChildren(long id, RepositoryElementType type); + + long getContainingFile(long id); + + boolean isCompiled(long id); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CacheUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CacheUtil.java new file mode 100644 index 00000000000..22b4102c3e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CacheUtil.java @@ -0,0 +1,77 @@ +package com.intellij.psi.impl.cache.impl; + +import com.intellij.ide.startup.FileContent; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.LoadTextUtil; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPlainTextFile; +import com.intellij.psi.impl.PsiElementFactoryImpl; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.compiled.ClsFileImpl; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.CharArrayUtil; + +import java.io.IOException; + +public class CacheUtil { + public static PsiFile createFileCopy(PsiFile psiFile) { + return createFileCopy(null, psiFile); + } + + public static PsiFile createFileCopy(FileContent content, PsiFile psiFile) { + PsiFile fileCopy; + + VirtualFile vFile = psiFile.getVirtualFile(); + if (psiFile instanceof ClsFileImpl) { + ClsFileImpl implFile = (ClsFileImpl)psiFile; + if (implFile.isContentsLoaded()) { + fileCopy = implFile; + } + else { + fileCopy = new ClsFileImpl((PsiManagerImpl)psiFile.getManager(), vFile); + ((ClsFileImpl)fileCopy).setRepositoryId(-1); + } + } + else if (psiFile instanceof PsiFileImpl) { + PsiFileImpl implFile = (PsiFileImpl)psiFile; + if (implFile.isContentsLoaded()) { + fileCopy = implFile; + } + else { + CharSequence text; + if (content == null) { + Document document = FileDocumentManager.getInstance().getDocument(vFile); + text = ((DocumentEx)document).getCharsSequence(); + } + else { + try { + text = LoadTextUtil.loadText(content.getBytes(), new String[1]); + } + catch (IOException e) { + text = new CharArrayCharSequence(new char[0]); + } + } + + FileType fileType = psiFile.getFileType(); + if (psiFile instanceof PsiPlainTextFile && (fileType == StdFileTypes.JAVA || fileType == StdFileTypes.ASPECT)) { // fixes problem with java&aspect files outside sourcepath + fileType = StdFileTypes.PLAIN_TEXT; + } + PsiElementFactoryImpl factory = (PsiElementFactoryImpl)psiFile.getManager().getElementFactory(); + char[] chars = CharArrayUtil.fromSequence(text); + fileCopy = factory.createDummyFileFromText(fileType, chars, 0, text.length()); + } + fileCopy.setModificationStamp(psiFile.getModificationStamp()); + } + else { + fileCopy = psiFile; + } + + return fileCopy; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CompositeCacheManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CompositeCacheManager.java new file mode 100644 index 00000000000..6db4e6dcc98 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/CompositeCacheManager.java @@ -0,0 +1,97 @@ +package com.intellij.psi.impl.cache.impl; + +import com.intellij.psi.impl.cache.CacheManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.TodoPattern; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.project.Project; +import com.intellij.ide.startup.CacheUpdater; + +import java.util.List; +import java.util.Arrays; +import java.util.Iterator; +import java.util.ArrayList; + +/** + * @author peter + */ +public class CompositeCacheManager implements CacheManager{ + private List myManagers = new ArrayList(); + + public void addCacheManager(CacheManager manager) { + myManagers.add(manager); + } + + public void addProjectComponent(CacheManager cacheManager) { + if (cacheManager != null) { + addCacheManager(cacheManager); + } + } + + public void initialize() { + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + cacheManager.initialize(); + } + } + + public void dispose() { + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + cacheManager.dispose(); + } + } + + public CacheUpdater[] getCacheUpdaters() { + List updaters = new ArrayList(); + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + updaters.addAll(Arrays.asList(cacheManager.getCacheUpdaters())); + } + return updaters.toArray(new CacheUpdater[updaters.size()]); + } + + public PsiFile[] getFilesWithWord(String word, short occurenceMask, GlobalSearchScope scope) { + List files = new ArrayList(); + for (Iterator iterator = myManagers.iterator(); iterator.hasNext();) { + CacheManager cacheManager = iterator.next(); + files.addAll(Arrays.asList(cacheManager.getFilesWithWord(word, occurenceMask, scope))); + } + return files.toArray(new PsiFile[files.size()]); + } + + public PsiFile[] getFilesWithTodoItems() { + List files = new ArrayList(); + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + files.addAll(Arrays.asList(cacheManager.getFilesWithTodoItems())); + } + return files.toArray(new PsiFile[files.size()]); + } + + public int getTodoCount(VirtualFile file) { + int count = 0; + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + count += cacheManager.getTodoCount(file); + } + return count; + } + + public int getTodoCount(VirtualFile file, TodoPattern pattern) { + int count = 0; + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + count += cacheManager.getTodoCount(file, pattern); + } + return count; + } + + public void addOrInvalidateFile(VirtualFile file) { + for (int i = 0; i < myManagers.size(); i++) { + CacheManager cacheManager = myManagers.get(i); + cacheManager.addOrInvalidateFile(file); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/BaseFilterLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/BaseFilterLexer.java new file mode 100644 index 00000000000..223e9deea42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/BaseFilterLexer.java @@ -0,0 +1,95 @@ +package com.intellij.psi.impl.cache.impl.idCache; + +import com.intellij.ide.todo.TodoConfiguration; +import com.intellij.lexer.Lexer; +import com.intellij.psi.search.TodoPattern; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.text.CharArrayCharSequence; +import gnu.trove.TIntIntHashMap; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class BaseFilterLexer implements Lexer { + protected final Lexer myOriginalLexer; + protected final TIntIntHashMap myTable; + protected final int[] myTodoCounts; + + private int myTodoScannedBound = 0; + + protected BaseFilterLexer(Lexer originalLexer, TIntIntHashMap table, int[] todoCounts) { + myOriginalLexer = originalLexer; + myTable = table; + myTodoCounts = todoCounts; + } + + public void start(char[] buffer) { + myOriginalLexer.start(buffer); + } + + public void start(char[] buffer, int startOffset, int endOffset) { + myOriginalLexer.start(buffer, startOffset, endOffset); + } + + public void start(char[] buffer, int startOffset, int endOffset, int initialState) { + myOriginalLexer.start(buffer, startOffset, endOffset, initialState); + } + + public int getState() { + return myOriginalLexer.getState(); + } + + public int getLastState() { + return myOriginalLexer.getLastState(); + } + + public IElementType getTokenType() { + return myOriginalLexer.getTokenType(); + } + + public int getTokenStart() { + return myOriginalLexer.getTokenStart(); + } + + public int getTokenEnd() { + return myOriginalLexer.getTokenEnd(); + } + + public char[] getBuffer() { + return myOriginalLexer.getBuffer(); + } + + public int getBufferEnd() { + return myOriginalLexer.getBufferEnd(); + } + + public int getSmartUpdateShift() { + return myOriginalLexer.getSmartUpdateShift(); + } + + protected final void advanceTodoItemCounts(char[] chars, int start, int end) { + if (myTodoCounts != null){ + start = Math.max(start, myTodoScannedBound); + if (start >= end) return; // this prevents scanning of the same comment twice + + TodoPattern[] patterns = TodoConfiguration.getInstance().getTodoPatterns(); + for(int index = 0; index < patterns.length; index++){ + Pattern pattern = patterns[index].getPattern(); + if (pattern != null){ + CharSequence input = new CharArrayCharSequence(chars, start, end); + Matcher matcher = pattern.matcher(input); + while(matcher.find()){ + if (matcher.start() != matcher.end()){ + myTodoCounts[index]++; + } + } + } + } + + myTodoScannedBound = end; + } + } + + public abstract Object clone(); + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/IdTableBuilding.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/IdTableBuilding.java new file mode 100644 index 00000000000..30f05524370 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/IdTableBuilding.java @@ -0,0 +1,315 @@ +package com.intellij.psi.impl.cache.impl.idCache; + +import com.intellij.aspects.lexer._AspectjLexer; +import com.intellij.aspects.psi.PsiAspectFile; +import com.intellij.ide.startup.FileContent; +import com.intellij.ide.todo.TodoConfiguration; +import com.intellij.lexer.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.cache.impl.CacheManagerImpl; +import com.intellij.psi.impl.source.parsing.jsp.JspStep1Lexer; +import com.intellij.psi.impl.source.parsing.xml.XmlPsiLexer; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.search.TodoPattern; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaElementType; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.IComponent; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.util.text.CharArrayCharSequence; +import gnu.trove.TIntIntHashMap; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.HashMap; + +public class IdTableBuilding { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.impl.idCache.IdTableBuilding"); + + private static final int FILE_SIZE_LIMIT = 1000000; // ignore files of size > 1Mb + + public static class Result { + final Runnable runnable; + final TIntIntHashMap wordsMap; + final int[] todoCounts; + + private Result(Runnable runnable, TIntIntHashMap wordsMap, int[] todoCounts) { + this.runnable = runnable; + this.wordsMap = wordsMap; + this.todoCounts = todoCounts; + } + } + + public interface IdCacheBuilder { + void build(char[] chars, int length, TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts); + } + + public interface ScanWordProcessor { + void run (char[] chars, int start, int end); + } + + static class TextIdCacheBuilder implements IdCacheBuilder { + public void build(char[] chars, int length, TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts) { + scanWords(wordsTable, chars, 0, length, WordInfo.PLAIN_TEXT); + + if (todoCounts != null) { + for (int index = 0; index < todoPatterns.length; index++) { + Pattern pattern = todoPatterns[index].getPattern(); + if (pattern != null) { + CharSequence input = new CharArrayCharSequence(chars, 0, length); + Matcher matcher = pattern.matcher(input); + while (matcher.find()) { + if (matcher.start() != matcher.end()) { + todoCounts[index]++; + } + } + } + } + } + } + } + + static class JavaIdCacheBuilder implements IdCacheBuilder { + protected Lexer createLexer() { + return new JavaLexer(LanguageLevel.JDK_1_3); + } + + public void build(char[] chars, int length, TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts) { + Lexer lexer = createLexer(); + JavaJspFilterLexer filterLexer = new JavaJspFilterLexer(lexer, wordsTable, todoCounts); + lexer = new FilterLexer(filterLexer, new FilterLexer.SetFilter(ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(chars); + while (lexer.getTokenType() != null) lexer.advance(); + } + } + + static class AspectJIdCacheBuilder extends JavaIdCacheBuilder { + protected Lexer createLexer() { + return new _AspectjLexer(false, false); + } + } + + static class JspIdCacheBuilder implements IdCacheBuilder { + public void build(char[] chars, int length, TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts) { + Lexer lexer = new JspStep1Lexer(LanguageLevel.JDK_1_3); + JavaJspFilterLexer filterLexer = new JavaJspFilterLexer(lexer, wordsTable, todoCounts); + lexer = new FilterLexer(filterLexer, TOKEN_FILTER); + lexer.start(chars); + while (lexer.getTokenType() != null) lexer.advance(); + } + } + + static class XmlIdCacheBuilder implements IdCacheBuilder { + public void build(char[] chars, int length, TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts) { + XmlFilterLexer filterLexer = createLexer(wordsTable, todoCounts); + filterLexer.start(chars); + while (filterLexer.getTokenType() != null) { + filterLexer.advance(); + } + } + + protected XmlFilterLexer createLexer(TIntIntHashMap wordsTable, int[] todoCounts) { + Lexer lexer = new XmlPsiLexer(); + return new XmlFilterLexer(lexer, wordsTable, todoCounts); + } + } + + static class HtmlIdCacheBuilder extends XmlIdCacheBuilder { + protected XmlFilterLexer createLexer(TIntIntHashMap wordsTable, int[] todoCounts) { + return new XmlFilterLexer(new HtmlLexer(), wordsTable, todoCounts, true); + } + } + + static class XHtmlIdCacheBuilder extends XmlIdCacheBuilder { + protected XmlFilterLexer createLexer(TIntIntHashMap wordsTable, int[] todoCounts) { + return new XmlFilterLexer(new XHtmlLexer(), wordsTable, todoCounts, false); + } + } + + static class FormFileIdCacheBuilder extends TextIdCacheBuilder { + public void build(char[] chars, int length, final TIntIntHashMap wordsTable, TodoPattern[] todoPatterns, int[] todoCounts) { + super.build(chars, length, wordsTable, todoPatterns, todoCounts); + + try { + LwRootContainer container = Utils.getRootContainer(new String(chars), + null/*no need component classes*/); + String className = container.getClassToBind(); + if (className != null) { + addClassAndPackagesNames(className, wordsTable); + } + + FormEditingUtil.iterate(container, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(IComponent iComponent) { + String componentClassName = iComponent.getComponentClassName(); + addClassAndPackagesNames(componentClassName, wordsTable); + return true; + } + }); + } + catch (Exception e) { + } + } + } + + private static final HashMap cacheBuilders = new HashMap(); + + public static void registerCacheBuilder(FileType fileType,IdCacheBuilder idCacheBuilder) { + cacheBuilders.put(fileType, idCacheBuilder); + } + + static { + registerCacheBuilder(StdFileTypes.JAVA,new JavaIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.ASPECT,new AspectJIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.XML,new XmlIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.XHTML,new XmlIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.DTD,new XmlIdCacheBuilder()); + + registerCacheBuilder(StdFileTypes.HTML,new HtmlIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.XHTML,new XHtmlIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.JSP,new JspIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.PLAIN_TEXT,new TextIdCacheBuilder()); + registerCacheBuilder(StdFileTypes.GUI_DESIGNER_FORM,new FormFileIdCacheBuilder()); + } + + public static IdCacheBuilder getCacheBuilder(PsiFile psiFile) { + final FileType fileType = psiFile.getFileType(); + final IdCacheBuilder idCacheBuilder = cacheBuilders.get(fileType); + + if (idCacheBuilder != null) return idCacheBuilder; + + if (psiFile instanceof JspFile) { + return cacheBuilders.get(StdFileTypes.JSP); + } + + if(psiFile instanceof PsiPlainTextFile) { + return cacheBuilders.get(StdFileTypes.PLAIN_TEXT); + } + + if (psiFile instanceof PsiAspectFile) { + return cacheBuilders.get(StdFileTypes.ASPECT); + } + + if (psiFile instanceof PsiJavaFile) { + return cacheBuilders.get(StdFileTypes.JAVA); + } + + if (psiFile instanceof XmlFile) { + return cacheBuilders.get(StdFileTypes.XML); + } + + return null; + } + + public static Result getBuildingRunnable(PsiManagerImpl manager, FileContent fileContent, final boolean buildTodos) { + if (LOG.isDebugEnabled()){ + LOG.debug( + "enter: getBuildingRunnable(file='" + fileContent.getVirtualFile() + "' buildTodos='" + buildTodos + "' )" + ); + //LOG.debug(new Throwable()); + } + + if (fileContent.getVirtualFile().getLength() > FILE_SIZE_LIMIT) return null; + final PsiFile psiFile = manager.getFile(fileContent); + if (psiFile == null) return null; + if (psiFile instanceof PsiBinaryFile) return null; + if (psiFile instanceof PsiCompiledElement) return null; + + final TIntIntHashMap wordsTable = new TIntIntHashMap(); + + final int[] todoCounts; + final TodoPattern[] todoPatterns = TodoConfiguration.getInstance().getTodoPatterns(); + if (buildTodos && CacheManagerImpl.canContainTodoItems(fileContent.getVirtualFile())){ + int patternCount = todoPatterns.length; + todoCounts = patternCount > 0 ? new int[patternCount] : null; + } + else{ + todoCounts = null; + } + + final char[] chars = psiFile.textToCharArray(); + final int textLength = psiFile.getTextLength(); + final IdCacheBuilder cacheBuilder = getCacheBuilder(psiFile); + + if (cacheBuilder==null) return null; + + Runnable runnable = new Runnable() { + public void run() { + synchronized (PsiLock.LOCK) { + cacheBuilder.build(chars, textLength, wordsTable, todoPatterns, todoCounts); + } + } + }; + + return new Result(runnable, wordsTable, todoCounts); + } + + private static void addClassAndPackagesNames(String qName, final TIntIntHashMap wordsTable) { + IdCacheUtil.addOccurrence(wordsTable, qName.hashCode(), WordInfo.GUI_FORM_CLASS_NAME); + int idx = qName.lastIndexOf('.'); + while (idx > 0) { + qName = qName.substring(0, idx); + IdCacheUtil.addOccurrence(wordsTable, qName.hashCode(), WordInfo.GUI_FORM_CLASS_NAME); + idx = qName.lastIndexOf('.'); + } + } + + private static final FilterLexer.Filter TOKEN_FILTER = new FilterLexer.Filter() { + public boolean reject(IElementType type) { + return !(type instanceof IJavaElementType) || ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(type); + } + }; + + public static void scanWords(final ScanWordProcessor processor, final char[] chars, final int startOffset, final int endOffset) { + int index = startOffset; + ScanWordsLoop: + while(true){ + while(true){ + if (index == endOffset) break ScanWordsLoop; + char c = chars[index]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (Character.isJavaIdentifierStart(c) && c != '$')) break; + index++; + } + int index1 = index; + while(true){ + index++; + if (index == endOffset) break; + char c = chars[index]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) continue; + if (!Character.isJavaIdentifierPart(c) || c == '$') break; + } + if (index - index1 > 100) continue; // Strange limit but we should have some! + + processor.run(chars, index1, index); + } + } + + public static void scanWords(final TIntIntHashMap table, final char[] chars, final int start, final int end, final int occurrenceMask) { + scanWords(new ScanWordProcessor(){ + public void run(final char[] chars, final int start, final int end) { + registerOccurence(chars, start, end, table, occurrenceMask,false); + } + }, chars, start, end); + } + + public static void registerOccurence(final char[] chars, + final int start, + final int end, + final TIntIntHashMap table, + final int occurrenceMask, + final boolean caseInsensitive) { + final int hashCode = (caseInsensitive)? + StringUtil.stringHashCodeInsensitive(chars, start, end-start): + StringUtil.stringHashCode(chars, start, end-start); + IdCacheUtil.addOccurrence(table, hashCode, occurrenceMask); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/VfsIndexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/VfsIndexer.java new file mode 100644 index 00000000000..946fc614041 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/VfsIndexer.java @@ -0,0 +1,106 @@ +package com.intellij.psi.impl.cache.impl.idCache; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class VfsIndexer { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.impl.idCache.VfsIndexer"); + + public static VirtualFile[] writeFileIndex( + OutputStream stream, + VirtualFile root, + VirtualFileFilter filter) throws IOException { + + List result = new ArrayList(); + + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null){ + progress.setText2("Scanning files in " + root.getPresentableUrl() + "..."); + } + + DataOutputStream out = stream != null ? new DataOutputStream(stream) : null; + + _writeFileIndex(out, root, filter, result); + + if (out != null){ + out.flush(); + } + + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + private static void _writeFileIndex(DataOutputStream out, VirtualFile file, VirtualFileFilter filter, List result) throws IOException { + ProgressManager.getInstance().checkCanceled(); + + result.add(file); + if (out != null){ + out.writeUTF(file.getName()); + } + + VirtualFile[] children = file.getChildren(); + if (children == null) { + if (out != null){ + out.writeInt(0); + } + return; + } + + int childrenCount = 0; + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (filter.accept(child)) childrenCount++; + } + + if (out != null){ + out.writeInt(childrenCount); + } + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (filter.accept(child)){ + _writeFileIndex(out, child, filter, result); + } + } + } + + public static VirtualFile[] readFileIndex( + InputStream stream, + VirtualFile root, + VirtualFileFilter filter + ) throws IOException { + List result = new ArrayList(); + + DataInputStream in = new DataInputStream(stream); + + String rootName = in.readUTF(); + LOG.assertTrue(root.getName().equals(rootName)); + _readFileIndex(in, root, filter, result); + + return (VirtualFile[])result.toArray(new VirtualFile[result.size()]); + } + + private static void _readFileIndex(DataInputStream in, VirtualFile file, VirtualFileFilter filter, List result) throws IOException { + ProgressManager.getInstance().checkCanceled(); + + result.add(file); + int childrenCount = in.readInt(); + if (childrenCount == 0) return; + + for (int i = 0; i < childrenCount; i++) { + String name = in.readUTF(); + VirtualFile child = file != null ? file.findChild(name) : null; + + if (child != null && !filter.accept(child)){ + child = null; + } + + _readFileIndex(in, child, filter, result); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/XmlFilterLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/XmlFilterLexer.java new file mode 100644 index 00000000000..25202a5d60b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/idCache/XmlFilterLexer.java @@ -0,0 +1,37 @@ +package com.intellij.psi.impl.cache.impl.idCache; + +import com.intellij.lexer.Lexer; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.tree.IElementType; +import gnu.trove.TIntIntHashMap; + +public class XmlFilterLexer extends BaseFilterLexer implements IdTableBuilding.ScanWordProcessor { + private boolean caseInsensitive; + + public void run(char[] chars, int start, int end) { + IdTableBuilding.registerOccurence(chars, start, end, myTable, WordInfo.PLAIN_TEXT, caseInsensitive); + } + + public XmlFilterLexer(Lexer originalLexer, TIntIntHashMap table, int[] todoCounts) { + this(originalLexer, table, todoCounts,false); + } + + public XmlFilterLexer(Lexer originalLexer, TIntIntHashMap table, int[] todoCounts, boolean _caseInsensitive) { + super(originalLexer, table, todoCounts); + caseInsensitive = _caseInsensitive; + } + + public Object clone() { + return new XmlFilterLexer((Lexer)myOriginalLexer.clone(), myTable, myTodoCounts, caseInsensitive); + } + + public void advance() { + IElementType tokenType = myOriginalLexer.getTokenType(); + if (tokenType == ElementType.XML_COMMENT_CHARACTERS) { + advanceTodoItemCounts(getBuffer(), getTokenStart(), getTokenEnd()); + } + + IdTableBuilding.scanWords(this, getBuffer(), getTokenStart(), getTokenEnd()); + myOriginalLexer.advance(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/RecordUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/RecordUtil.java new file mode 100644 index 00000000000..09633a20063 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/RecordUtil.java @@ -0,0 +1,651 @@ +package com.intellij.psi.impl.cache.impl.repositoryCache; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.impl.cache.ModifierFlags; +import com.intellij.psi.impl.compiled.ClsTypeElementImpl; +import com.intellij.psi.impl.source.PsiJavaFileImpl; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashMap; +import com.intellij.util.io.Internalize; +import com.intellij.util.io.NameStore; +import com.intellij.util.io.RecordDataOutput; +import gnu.trove.TIntObjectHashMap; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author max + */ +public class RecordUtil { + private RecordUtil() {} + + private static final Ref> ourList = new Ref>(); + private static final int[] ourEmptyIntArray = new int[0]; + private static final String[][] ourEmptyStringStringArray = new String[0][]; + private static final TypeInfo[] ourEmptyTypeArray = new TypeInfo[0]; + private static boolean[] ourEmptyBooleanArray = new boolean[0]; + + public static List getInnerClasses(PsiElement psiElement) { + ourList.set(null); + + if (psiElement != null && mayContainClassesInside(psiElement)) { + psiElement.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitClass(PsiClass aClass) { + if (ourList.isNull()) ourList.set(new ArrayList()); + ourList.get().add(aClass); + } + + public void visitTypeParameter(PsiTypeParameter classParameter) { + // just skip (because type parameter is class - bad!) + } + }); + } + + return ourList.get(); + } + + private static boolean mayContainClassesInside(PsiElement psiElement) { + PsiFile psiFile = psiElement.getContainingFile(); + boolean mayHaveClassesInside = false; + if (psiFile instanceof PsiJavaFileImpl) { + PsiJavaFileImpl impl = (PsiJavaFileImpl)psiFile; + Lexer originalLexer = impl.createLexer(); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET)); + final char[] buffer = psiElement.textToCharArray(); + lexer.start(buffer, 0, buffer.length); + boolean isInNewExpression = false; + boolean isRightAfterNewExpression = false; + int angleLevel = 0; + int parenLevel = 0; + do { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + + if (tokenType == JavaTokenType.NEW_KEYWORD) { + isInNewExpression = true; + } + else if (tokenType == JavaTokenType.LPARENTH) { + if (isInNewExpression) parenLevel++; + } + else if (tokenType == JavaTokenType.LT) { + if (isInNewExpression) angleLevel++; + } + else if (tokenType == JavaTokenType.GT) { + if (isInNewExpression) angleLevel--; + } + else if (tokenType == JavaTokenType.RPARENTH) { + if (isInNewExpression) { + parenLevel--; + if (parenLevel == 0) { + isRightAfterNewExpression = true; + } + } + } + else if (tokenType == JavaTokenType.LBRACE) { + if (isInNewExpression || isRightAfterNewExpression) { + mayHaveClassesInside = true; + } + } + else if (tokenType == JavaTokenType.LBRACKET) { + if (parenLevel == 0 && angleLevel == 0) isInNewExpression = false; + } + else if (tokenType == JavaTokenType.INTERFACE_KEYWORD || tokenType == JavaTokenType.CLASS_KEYWORD || + tokenType == JavaTokenType.ENUM_KEYWORD) { + mayHaveClassesInside = true; + } + + if (isInNewExpression && isRightAfterNewExpression) { + isInNewExpression = false; + } + else { + isRightAfterNewExpression = false; + } + + lexer.advance(); + } + while (!mayHaveClassesInside); + } + return mayHaveClassesInside; + } + + static int[] createIntArray(int size) { + if (size == 0) return ourEmptyIntArray; + return new int[size]; + } + + static String[] createStringArray(int size) { + if (size == 0) return ArrayUtil.EMPTY_STRING_ARRAY; + return new String[size]; + } + + static String[][] createStringStringArray(int size) { + if (size == 0) return ourEmptyStringStringArray; + return new String[size][]; + } + + static boolean[] createBooleanArray(int size) { + if (size == 0) return ourEmptyBooleanArray; + return new boolean[size]; + } + + static TypeInfo[] createTypeInfoArray(int size) { + if (size == 0) return ourEmptyTypeArray; + TypeInfo[] res = new TypeInfo[size]; + for (int i = 0; i < res.length; i++) { + res[i] = new TypeInfo(); + } + return res; + } + + public static int packFlags(PsiElement psiElement) { + int packed = packModifiers(psiElement); + if (isDeprecatedByDocComment(psiElement)) { + packed |= ModifierFlags.DEPRECATED_MASK; + } else { //No need for yet another deprecated flag if the first is true + if (isDeprecatedByAnnotation(psiElement)) { + packed |= ModifierFlags.ANNOTATION_DEPRECATED_MASK; + } + } + + if (isInterface(psiElement)) { + packed |= ModifierFlags.INTERFACE_MASK; + } + + if (isEnum(psiElement)) { + packed |= ModifierFlags.ENUM_MASK; + } + + if (isAnnotationType(psiElement)) { + packed |= ModifierFlags.ANNOTATION_TYPE_MASK; + } + + return packed; + } + + private static boolean isDeprecatedByAnnotation(PsiElement element) { + if (element instanceof PsiModifierListOwner) { + PsiModifierList modifierList = ((PsiModifierListOwner)element).getModifierList(); + if (modifierList != null) { + PsiAnnotation[] annotations = modifierList.getAnnotations(); + for (int i = 0; i < annotations.length; i++) { + PsiAnnotation annotation = annotations[i]; + PsiJavaCodeReferenceElement nameElement = annotation.getNameReferenceElement(); + if (nameElement != null && "Deprecated".equals(nameElement.getReferenceName())) return true; + } + } + } + + return false; + } + + + private static int packModifiers(PsiElement psiElement) { + int packed = 0; + PsiModifierList psiModifierList = null; + + if (psiElement instanceof PsiModifierListOwner) { + psiModifierList = ((PsiModifierListOwner)psiElement).getModifierList(); + } + + if (psiModifierList != null) { + if (psiModifierList.hasModifierProperty(PsiModifier.ABSTRACT)) { + packed |= ModifierFlags.ABSTRACT_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.FINAL)) { + packed |= ModifierFlags.FINAL_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.NATIVE)) { + packed |= ModifierFlags.NATIVE_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.STATIC)) { + packed |= ModifierFlags.STATIC_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { + packed |= ModifierFlags.SYNCHRONIZED_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.TRANSIENT)) { + packed |= ModifierFlags.TRANSIENT_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.VOLATILE)) { + packed |= ModifierFlags.VOLATILE_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.PRIVATE)) { + packed |= ModifierFlags.PRIVATE_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.PROTECTED)) { + packed |= ModifierFlags.PROTECTED_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.PUBLIC)) { + packed |= ModifierFlags.PUBLIC_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { + packed |= ModifierFlags.PACKAGE_LOCAL_MASK; + } + if (psiModifierList.hasModifierProperty(PsiModifier.STRICTFP)) { + packed |= ModifierFlags.STRICTFP_MASK; + } + } + + return packed; + } + + private static boolean isDeprecatedByDocComment(PsiElement psiElement) { + if (!(psiElement instanceof PsiDocCommentOwner)) return false; + PsiDocComment docComment = ((PsiDocCommentOwner)psiElement).getDocComment(); + return docComment != null && docComment.findTagByName("deprecated") != null; + } + + private static boolean isInterface(PsiElement psiElement) { + if (!(psiElement instanceof PsiClass)) return false; + return ((PsiClass)psiElement).isInterface(); + } + + private static boolean isEnum(PsiElement psiElement) { + if (!(psiElement instanceof PsiClass)) return false; + return ((PsiClass)psiElement).isEnum(); + } + + private static boolean isAnnotationType(PsiElement psiElement) { + if (!(psiElement instanceof PsiClass)) return false; + return ((PsiClass)psiElement).isAnnotationType(); + } + + + private static final HashMap ourModifierNameToFlagMap; + private static final HashMap ourFrequentTypeIndex; + private static final TIntObjectHashMap ourIndexFrequentType; + + static { + ourModifierNameToFlagMap = new HashMap(); + ourModifierNameToFlagMap.put(PsiModifier.PUBLIC, new Integer(ModifierFlags.PUBLIC_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.PROTECTED, new Integer(ModifierFlags.PROTECTED_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.PRIVATE, new Integer(ModifierFlags.PRIVATE_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.PACKAGE_LOCAL, new Integer(ModifierFlags.PACKAGE_LOCAL_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.STATIC, new Integer(ModifierFlags.STATIC_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.ABSTRACT, new Integer(ModifierFlags.ABSTRACT_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.FINAL, new Integer(ModifierFlags.FINAL_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.NATIVE, new Integer(ModifierFlags.NATIVE_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.SYNCHRONIZED, new Integer(ModifierFlags.SYNCHRONIZED_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.TRANSIENT, new Integer(ModifierFlags.TRANSIENT_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.VOLATILE, new Integer(ModifierFlags.VOLATILE_MASK)); + ourModifierNameToFlagMap.put(PsiModifier.STRICTFP, new Integer(ModifierFlags.STRICTFP_MASK)); + ourModifierNameToFlagMap.put("interface", new Integer(ModifierFlags.INTERFACE_MASK)); + ourModifierNameToFlagMap.put("deprecated", new Integer(ModifierFlags.DEPRECATED_MASK)); + ourModifierNameToFlagMap.put("@Deprecated", new Integer(ModifierFlags.ANNOTATION_DEPRECATED_MASK)); + ourModifierNameToFlagMap.put("enum", new Integer(ModifierFlags.ENUM_MASK)); + ourModifierNameToFlagMap.put("@", new Integer(ModifierFlags.ANNOTATION_TYPE_MASK)); + + ourFrequentTypeIndex = new HashMap(); + ourIndexFrequentType = new TIntObjectHashMap(); + + ourFrequentTypeIndex.put("boolean", new Integer(1)); + ourIndexFrequentType.put(1, "boolean"); + + ourFrequentTypeIndex.put("byte", new Integer(2)); + ourIndexFrequentType.put(2, "byte"); + + ourFrequentTypeIndex.put("char", new Integer(3)); + ourIndexFrequentType.put(3, "char"); + + ourFrequentTypeIndex.put("double", new Integer(4)); + ourIndexFrequentType.put(4, "double"); + + ourFrequentTypeIndex.put("float", new Integer(5)); + ourIndexFrequentType.put(5, "float"); + + ourFrequentTypeIndex.put("int", new Integer(6)); + ourIndexFrequentType.put(6, "int"); + + ourFrequentTypeIndex.put("long", new Integer(7)); + ourIndexFrequentType.put(7, "long"); + + ourFrequentTypeIndex.put("null", new Integer(8)); + ourIndexFrequentType.put(8, "null"); + + ourFrequentTypeIndex.put("short", new Integer(9)); + ourIndexFrequentType.put(9, "short"); + + ourFrequentTypeIndex.put("void", new Integer(10)); + ourIndexFrequentType.put(10, "void"); + + ourFrequentTypeIndex.put("Object", new Integer(11)); + ourIndexFrequentType.put(11, "Object"); + + ourFrequentTypeIndex.put("java.lang.Object", new Integer(12)); + ourIndexFrequentType.put(12, "java.lang.Object"); + + ourFrequentTypeIndex.put("String", new Integer(13)); + ourIndexFrequentType.put(13, "String"); + + ourFrequentTypeIndex.put("java.lang.String", new Integer(14)); + ourIndexFrequentType.put(14, "java.lang.String"); + } + + + public static boolean hasModifierProperty(String psiModifier, int packed) { + return (ourModifierNameToFlagMap.get(psiModifier).intValue() & packed) != 0; + } + + public static void readType(DataInput record, TypeInfo view) throws IOException { + int flags = record.readByte(); + + if (flags == 0x02) { + view.arrayCount = 0; + view.isEllipsis = false; + view.text = null; + return; + } + + view.arrayCount = record.readByte(); + view.isEllipsis = record.readBoolean(); + if (flags == 0x00) { + view.text = record.readUTF(); + } + else { + view.text = ourIndexFrequentType.get(flags >> 2); + } + } + + public static void skipType(DataInput record) throws IOException { + byte flags = record.readByte(); + if (flags == 0x02) return; + record.readByte(); + record.readBoolean(); + if (flags == 0x00) { + skipUTF(record); + } + } + + public static void skipUTF(DataInput record) throws IOException { + record.skipBytes(record.readUnsignedShort()); + } + + public static String createTypeText(TypeInfo typeInfo) { + if (typeInfo.arrayCount == 0) return typeInfo.text; + if (typeInfo.text == null) return null; + + StringBuffer buf = new StringBuffer(typeInfo.text); + final int arrayCount = !typeInfo.isEllipsis ? typeInfo.arrayCount : typeInfo.arrayCount - 1; + for (int i = 0; i < arrayCount; i++) buf.append("[]"); + if (typeInfo.isEllipsis) { + buf.append("..."); + } + + return buf.toString(); + } + + public static int getLocalId(long id) { + return (int)(id & 0x0FFFFFFFL); + } + + + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.impl.repositoryCache"); + + public static String readNAME(DataInput record, NameStore nameStore) throws IOException { + final int low = record.readUnsignedByte(); + final int nameId = (readINT(record) << 8) | low; + return nameStore.stringOfId(nameId); + } + + public static void writeNAME(RecordDataOutput record, final String name, NameStore nameStore) throws IOException { + final int nameId = nameStore.idOfString(name); + record.writeByte(nameId & 0xFF); + writeINT(record, (nameId >> 8)); + } + + public static void skipNAME(DataInput record, NameStore nameStore) throws IOException { + record.readUnsignedByte(); + readINT(record); + } + + public static void readTYPE(DataInput record, TypeInfo view, NameStore nameStore) throws IOException { + final int b = 0xFF & record.readByte(); + final int tag = b & 0x3; + final int index = 0xF & (b >> 2); + final int flags = 0x3 & (b >> 6); + + if (tag == 0x02) { + view.arrayCount = 0; + view.isEllipsis = false; + view.text = null; + return; + } + + view.arrayCount = ((flags & 1) != 0 ? record.readByte() : 0); + view.isEllipsis = (flags & 2) != 0; + if (tag == 0x00) { + view.text = readNAME(record, nameStore); + //view.text = readSTR(record); + } + else { + view.text = ourIndexFrequentType.get(index); + } + } + + public static void writeTYPE(RecordDataOutput record, + PsiType type, + PsiTypeElement typeElement, + /*, NameStore nameStore*/NameStore nameStore) + throws IOException { + if (typeElement == null) { + record.writeByte(0x02); + return; + } + + final boolean isEllipsis = type instanceof PsiEllipsisType; + int arrayCount = type.getArrayDimensions(); + type = type.getDeepComponentType(); + + while (typeElement.getFirstChild() instanceof PsiTypeElement) { + typeElement = (PsiTypeElement)typeElement.getFirstChild(); + } + + String text = typeElement instanceof PsiCompiledElement + ? ((ClsTypeElementImpl)typeElement).getCanonicalText() + : typeElement.getText(); + Integer frequentIndex = ourFrequentTypeIndex.get(text); + LOG.assertTrue(frequentIndex == null || frequentIndex.intValue() < 16); + int flags = (arrayCount == 0 ? 0 : 1); + if (isEllipsis) flags |= 2; + if (frequentIndex != null) { + record.writeByte((flags << 6) | 0x01 | (frequentIndex.byteValue() << 2)); + if (arrayCount != 0) { + record.writeByte(arrayCount); + } + } + else { + record.writeByte((flags << 6) | 0x00); + if (arrayCount != 0) { + record.writeByte(arrayCount); + } + writeNAME(record, text, nameStore); + //writeSTR(record, text); + } + } + + public static void skipTYPE(DataInput record, NameStore nameStore) throws IOException { + final byte b = record.readByte(); + final int tag = b & 0x3; + final int flags = 0x3 & (b >> 6); + if (tag == 0x02) return; + if ((flags & 1) != 0) { + record.readByte(); + } + if (tag == 0x00) { + skipNAME(record, nameStore); + //skipSTR(record); + } + } + + public static void skipSTR(DataInput record) throws IOException { + final int len = record.readUnsignedByte(); + if (len < 255) { + record.skipBytes(len); + } + else { + final int len2 = record.readInt(); + record.skipBytes(len2 * 2); + } + } + + public static String readSTR(DataInput record) throws IOException { + final int len = record.readUnsignedByte(); + if (len < 255) { + byte[] b = new byte[len]; + record.readFully(b); + return Internalize.put(new String(b)); + } + else { + final int len2 = record.readInt(); + final char[] res = new char[len2]; + for (int i = 0; i < res.length; i++) { + res[i] = record.readChar(); + } + return Internalize.put(new String(res)); + } + } + + public static void writeSTR(DataOutput record, String str) throws IOException { + final int len = str.length(); + if (len < 255 && NameStore.isAscii(str)) { + record.writeByte(len); + record.writeBytes(str); + } + else { + record.writeByte(255); + record.writeInt(str.length()); + record.writeChars(str); + } + } + + public static int lengthSTR(String str) { + final int len = str.length(); + if (len < 255) { + return 1 + len; + } + else { + return 1 + 4 + len * 2; + } + } + + public static void skipINT(DataInput record) throws IOException { + readINT(record); + } + + public static int readINT(DataInput record) throws IOException { + final int val = record.readUnsignedByte(); + if (val < 192) { + return val; + } + + for (int res = (val - 192), sh = 6; ; sh += 7) { + int next = record.readUnsignedByte(); + res |= (next & 0x7F) << sh; + if ((next & 0x80) == 0) { + return res; + } + } + } + + public static void writeINT(RecordDataOutput record, int val) throws IOException { + /* + if (0 <= val && val < 255) + record.writeByte(val); + else { + record.writeByte(255); + record.writeInt(val); + } + */ + if (0 <= val && val < 192) { + record.writeByte(val); + } + else { + record.writeByte(192 + (val & 0x3F)); + val >>>= 6; + while (val >= 128) { + record.writeByte((val & 0x7F) | 0x80); + val >>>= 7; + } + record.writeByte(val); + } + } + + public static void skipSINT(DataInput record) throws IOException { + readSINT(record); + } + + public static int readSINT(DataInput record) throws IOException { + return readINT(record) - 64; + } + + public static void writeSINT(RecordDataOutput record, int val) throws IOException { + writeINT(record, val + 64); + } + + + public static int readID(DataInput record, int prevId) throws IOException { + return prevId + readSINT(record); + } + + public static int readID(DataInput record) throws IOException { + int low = record.readUnsignedByte(); + return low + (readINT(record) << 8); + } + + public static void writeID(RecordDataOutput record, int prevId, int id) throws IOException { + writeSINT(record, id - prevId); + } + + public static void writeID(RecordDataOutput record, int id) throws IOException { + record.writeByte(id & 0xFF); + writeINT(record, id >>> 8); + } + + private final static long timeBase = 33l * 365l * 24l * 3600l * 1000l; + + public static void writeTIME(RecordDataOutput record, long timestamp) throws IOException { + long relStamp = timestamp - timeBase; + if (relStamp < 0 || relStamp >= 0xFF00000000l) { + record.writeByte(255); + record.writeLong(timestamp); + } + else { + record.writeByte((int)(relStamp >> 32)); + record.writeByte((int)(relStamp >> 24)); + record.writeByte((int)(relStamp >> 16)); + record.writeByte((int)(relStamp >> 8)); + record.writeByte((int)(relStamp >> 0)); + } + } + + public static long readTIME(DataInput record) throws IOException { + final int first = record.readUnsignedByte(); + if (first == 255) { + return record.readLong(); + } + else { + final int second = record.readUnsignedByte(); + + final int third = record.readUnsignedByte() << 16; + final int fourth = record.readUnsignedByte() << 8; + final int fifth = record.readUnsignedByte(); + return ((((long)((first << 8) | second)) << 24) | (third | fourth | fifth)) + timeBase; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/TypeInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/TypeInfo.java new file mode 100644 index 00000000000..cc721155b67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/cache/impl/repositoryCache/TypeInfo.java @@ -0,0 +1,10 @@ +package com.intellij.psi.impl.cache.impl.repositoryCache; + +/** + * @author max + */ +public class TypeInfo { + public String text; + public byte arrayCount; + public boolean isEllipsis; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java new file mode 100644 index 00000000000..4f9362e6a7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java @@ -0,0 +1,86 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.PsiImplUtil; + +/** + * @author ven + */ +public class ClsAnnotationImpl extends ClsElementImpl implements PsiAnnotation { + public static final ClsAnnotationImpl[] EMPTY_ARRAY = new ClsAnnotationImpl[0]; + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsAnnotationImpl"); + private ClsJavaCodeReferenceElementImpl myReferenceElement; + private ClsAnnotationParameterListImpl myParameterList; + private ClsElementImpl myParent; + + public ClsAnnotationImpl(ClsJavaCodeReferenceElementImpl referenceElement, ClsElementImpl parent) { + myReferenceElement = referenceElement; + myParent = parent; + } + + public void setParameterList(ClsAnnotationParameterListImpl parameterList) { + myParameterList = parameterList; + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer("@"); + buffer.append(myReferenceElement.getCanonicalText()); + ClsNameValuePairImpl[] attributes = (ClsNameValuePairImpl[])getParameterList().getAttributes(); + if (attributes.length > 0) { + buffer.append("("); + for (int i = 0; i < attributes.length; i++) { + ClsNameValuePairImpl attribute = attributes[i]; + buffer.append(attribute.getName()); + ClsElementImpl value = ((ClsElementImpl)attribute.getValue()); + if (value != null) { + buffer.append("=" + value.getMirrorText()); + } + if (i < attributes.length - 1) buffer.append(","); + } + buffer.append(")"); + } + + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiAnnotation mirror = (PsiAnnotation)SourceTreeToPsiMap.treeElementToPsi(element); + ((ClsElementImpl)getParameterList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getParameterList())); + ((ClsElementImpl)getNameReferenceElement()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameReferenceElement())); + } + + public PsiElement[] getChildren() { + return new PsiElement[] {myReferenceElement, myParameterList}; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAnnotation(this); + } + + public PsiAnnotationParameterList getParameterList() { + return myParameterList; + } + + public PsiJavaCodeReferenceElement getNameReferenceElement() { + return myReferenceElement; + } + + public PsiAnnotationMemberValue findAttributeValue(String attributeName) { + return PsiImplUtil.findAttributeValue(this, attributeName); + } + + public String getText() { + return getMirrorText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java new file mode 100644 index 00000000000..9d969c4149d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java @@ -0,0 +1,71 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiAnnotationParameterList; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiNameValuePair; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author ven + */ +public class ClsAnnotationParameterListImpl extends ClsElementImpl implements PsiAnnotationParameterList { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsAnnotationParameterListImpl"); + + private ClsNameValuePairImpl[] myAttributes; + private ClsAnnotationImpl myParent; + + public ClsAnnotationParameterListImpl(ClsAnnotationImpl parent) { + myParent = parent; + } + + void setAttributes(ClsNameValuePairImpl[] attributes) { + myAttributes = attributes; + } + + public String getMirrorText() { + if (myAttributes.length == 0) return ""; + + StringBuffer buffer = new StringBuffer("("); + for (int i = 0; i < myAttributes.length; i++) { + buffer.append(myAttributes[i].getMirrorText()); + if (i < myAttributes.length - 1) { + buffer.append(", "); + } + } + + buffer.append(")"); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiAnnotationParameterList mirror = (PsiAnnotationParameterList)SourceTreeToPsiMap.treeElementToPsi(element); + PsiNameValuePair[] attrs = mirror.getAttributes(); + LOG.assertTrue(myAttributes.length == attrs.length); + for (int i = 0; i < myAttributes.length; i++) { + myAttributes[i].setMirror(SourceTreeToPsiMap.psiElementToTree(attrs[i])); + } + } + + public PsiElement[] getChildren() { + return myAttributes; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAnnotationParameterList(this); + } + + public PsiNameValuePair[] getAttributes() { + return myAttributes; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationsUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationsUtil.java new file mode 100644 index 00000000000..aa5d4371f39 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsAnnotationsUtil.java @@ -0,0 +1,169 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiElementFactoryImpl; +import com.intellij.psi.impl.cache.DeclarationView; +import com.intellij.psi.impl.cache.impl.repositoryCache.RecordUtil; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.DeclarationParsing; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.cls.BytePointer; +import com.intellij.util.io.RecordDataOutput; + +import java.io.IOException; + +/** + * @author ven + */ +public class ClsAnnotationsUtil { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsAnnotationsUtil"); + + private ClsAnnotationsUtil() {} + + private static PsiAnnotationMemberValue getMemberValue(PsiElement element, ClsElementImpl parent) { + if (element instanceof PsiLiteralExpression) { + PsiLiteralExpression expr = (PsiLiteralExpression)element; + return new ClsLiteralExpressionImpl(parent, element.getText(), expr.getType(), expr.getValue()); + + } + else if (element instanceof PsiClassObjectAccessExpression) { + PsiClassObjectAccessExpression expr = (PsiClassObjectAccessExpression)element; + return new ClsClassObjectAccessExpressionImpl(expr.getOperand().getType().getCanonicalText(), parent); + + } + else if (element instanceof PsiArrayInitializerMemberValue) { + PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)element).getInitializers(); + PsiAnnotationMemberValue[] clsInitializers = new PsiAnnotationMemberValue[initializers.length]; + ClsArrayInitializerMemberValueImpl arrayValue = new ClsArrayInitializerMemberValueImpl(parent); + for (int i = 0; i < initializers.length; i++) { + PsiAnnotationMemberValue innerValue = getMemberValue(initializers[i], arrayValue); + clsInitializers[i] = innerValue; + } + arrayValue.setInitializers(clsInitializers); + return arrayValue; + + } + else if (element instanceof PsiAnnotation) { + PsiAnnotation psiAnnotation = (PsiAnnotation)element; + ClsJavaCodeReferenceElementImpl ref = new ClsJavaCodeReferenceElementImpl(null, + psiAnnotation.getNameReferenceElement().getCanonicalText()); + ClsAnnotationImpl result = new ClsAnnotationImpl(ref, parent); + ref.setParent(result); + ClsAnnotationParameterListImpl list = new ClsAnnotationParameterListImpl(result); + PsiNameValuePair[] psiAttributes = psiAnnotation.getParameterList().getAttributes(); + ClsNameValuePairImpl[] attributes = new ClsNameValuePairImpl[psiAttributes.length]; + list.setAttributes(attributes); + for (int i = 0; i < attributes.length; i++) { + attributes[i] = new ClsNameValuePairImpl(list); + attributes[i].setNameIdentifier(new ClsIdentifierImpl(attributes[i], psiAttributes[i].getName())); + attributes[i].setMemberValue(getMemberValue(psiAttributes[i].getValue(), attributes[i])); + } + + result.setParameterList(list); + return result; + } + else if (element instanceof PsiReferenceExpression) { + return new ClsReferenceExpressionImpl(parent, (PsiReferenceExpression)element); + } + else { + LOG.error("Unexpected source element for annotation member value: " + element); + return null; + } + } + + public static PsiAnnotationMemberValue createMemberValueFromText(String text, PsiManager manager, ClsElementImpl parent) { + PsiJavaFile dummyJavaFile = ((PsiElementFactoryImpl)manager.getElementFactory()).getDummyJavaFile(); // kind of hack - we need to resolve classes from java.lang + final FileElement holderElement = new DummyHolder(manager, dummyJavaFile).getTreeElement(); + TreeElement element = DeclarationParsing.parseMemberValueText(manager, text.toCharArray(), holderElement.getCharTable()); + if (element == null) { + LOG.error("Could not parse initializer:'" + text + "'"); + return null; + } + TreeUtil.addChildren(holderElement, element); + PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element); + return getMemberValue(psiElement, parent); + } + + public interface AttributeReader { + BytePointer readAttribute(String attributeName); + + ClassFileData getClassFileData(); + } + + public static ClsAnnotationImpl[] getAnnotationsImpl(ClsRepositoryPsiElement element, AttributeReader reader, + ClsModifierListImpl modifierList) { + long id = element.getRepositoryId(); + if (id < 0) { + ClassFileData data = reader.getClassFileData(); + BytePointer pointer1 = reader.readAttribute("RuntimeVisibleAnnotations"); + if (pointer1 != null) { + pointer1.offset += 4; + ClsAnnotationImpl[] ann1 = data.readAnnotations(modifierList, pointer1); + BytePointer pointer2 = reader.readAttribute("RuntimeInvisibleAnnotations"); + if (pointer2 != null) { + pointer2.offset += 4; + ClsAnnotationImpl[] ann2 = data.readAnnotations(modifierList, pointer2); + ClsAnnotationImpl[] result = ArrayUtil.mergeArrays(ann1, ann2, ClsAnnotationImpl.class); + return result; + } + else { + return ann1; + } + } + else { + BytePointer pointer2 = reader.readAttribute("RuntimeInvisibleAnnotations"); + if (pointer2 != null) { + pointer2.offset += 4; + return data.readAnnotations(modifierList, pointer2); + } + else { + return ClsAnnotationImpl.EMPTY_ARRAY; + } + } + } + else { + DeclarationView view = (DeclarationView)element.getRepositoryManager().getItemView(id); + String[] annotationTexts = view.getAnnotations(id); + ClsAnnotationImpl[] result = new ClsAnnotationImpl[annotationTexts.length]; + for (int i = 0; i < annotationTexts.length; i++) { + result[i] = + (ClsAnnotationImpl)ClsAnnotationsUtil.createMemberValueFromText(annotationTexts[i], element.getManager(), modifierList); + } + + return result; + } + } + + public static void writeAnnotations(PsiModifierListOwner owner, RecordDataOutput record) throws IOException { + PsiModifierList modifierList = owner.getModifierList(); + if (modifierList != null) { + PsiAnnotation[] annotations = modifierList.getAnnotations(); + record.writeInt(annotations.length); + for (int i = 0; i < annotations.length; i++) { + record.writeUTF(annotations[i].getText()); + } + } + else { + record.writeInt(0); + } + } + + public static void writeAnnotationsINT(PsiModifierListOwner owner, RecordDataOutput record) throws IOException { + PsiModifierList modifierList = owner.getModifierList(); + if (modifierList != null) { + PsiAnnotation[] annotations = modifierList.getAnnotations(); + RecordUtil.writeINT(record, annotations.length); + for (int i = 0; i < annotations.length; i++) { + RecordUtil.writeSTR(record, annotations[i].getText()); + } + } + else { + RecordUtil.writeINT(record, 0); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsArrayInitializerMemberValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsArrayInitializerMemberValueImpl.java new file mode 100644 index 00000000000..db47c3fc0fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsArrayInitializerMemberValueImpl.java @@ -0,0 +1,69 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author ven + */ +public class ClsArrayInitializerMemberValueImpl extends ClsElementImpl implements PsiArrayInitializerMemberValue { + private final ClsElementImpl myParent; + private PsiAnnotationMemberValue[] myInitializers; + private final static Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsArrayInitializerMemberValueImpl"); + + public ClsArrayInitializerMemberValueImpl(ClsElementImpl parent) { + myParent = parent; + } + + public void setInitializers(PsiAnnotationMemberValue[] initializers) { + myInitializers = initializers; + } + + public String getText() { + return getMirrorText(); + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer("{"); + for (int i = 0; i < myInitializers.length; i++) { + buffer.append(((ClsElementImpl)myInitializers[i]).getMirrorText()); + if (i < myInitializers.length - 1) { + buffer.append(", "); + } + } + buffer.append('}'); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiArrayInitializerMemberValue mirror = (PsiArrayInitializerMemberValue)SourceTreeToPsiMap.treeElementToPsi(element); + PsiAnnotationMemberValue[] initializers = mirror.getInitializers(); + LOG.assertTrue(myInitializers.length == initializers.length); + for (int i = 0; i < myInitializers.length; i++) { + ClsElementImpl value = (ClsElementImpl)myInitializers[i]; + value.setMirror(SourceTreeToPsiMap.psiElementToTree(initializers[i])); + } + } + + public PsiElement[] getChildren() { + return myInitializers; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAnnotationArrayInitializer(this); + } + + public PsiAnnotationMemberValue[] getInitializers() { + return myInitializers; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassImpl.java new file mode 100644 index 00000000000..4d1abc1be9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassImpl.java @@ -0,0 +1,1140 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.psi.*; +import com.intellij.psi.impl.*; +import com.intellij.psi.impl.cache.ClassView; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.BytePointer; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.cls.ClsUtil; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.*; + +public class ClsClassImpl extends ClsRepositoryPsiElement implements PsiClass, ClsModifierListOwner { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsClassImpl"); + + private ClassFileData myClassFileData; // it's null when repository id exists + + // these fields are not used when has repository id + private PsiElement myParent; + private PsiField[] myFields = null; + private PsiMethod[] myMethods = null; + private PsiMethod[] myConstructors = null; + private PsiClass[] myInnerClasses = null; + + private Map myCachedFieldsMap = null; + private Map myCachedMethodsMap = null; + private Map myCachedInnersMap = null; + + + private String myQualifiedName = null; + private String myName = null; + private PsiIdentifier myNameIdentifier = null; + private ClsModifierListImpl myModifierList = null; + private PsiReferenceList myExtendsList = null; + private PsiReferenceList myImplementsList = null; + private PsiTypeParameterList myTypeParameters = null; + private Boolean myIsDeprecated = null; + private PsiDocComment myDocComment = null; + private ClsAnnotationImpl[] myAnnotations = null; + + public ClsClassImpl(PsiManagerImpl manager, ClsElementImpl parent, VirtualFile file) { + super(manager, -1); + myParent = parent; + myClassFileData = new ClassFileData(file); + } + + public ClsClassImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + myClassFileData = null; + myParent = null; + } + + void invalidate() { + myParent = null; + } + + boolean isContentsLoaded() { + return myClassFileData != null; + } + + ClassFileData getClassFileData() { + VirtualFile vFile = getContainingFile().getVirtualFile(); + if (vFile != null) { + LOG.assertTrue(!myManager.isAssertOnFileLoading(vFile)); + } + return myClassFileData; + } + + public void setRepositoryId(long repositoryId) { + synchronized (PsiLock.LOCK) { + super.setRepositoryId(repositoryId); + if (repositoryId >= 0) { + myClassFileData = null; + } + ; + } + } + + public PsiDirectory getContainingPackage() { + return getContainingFile().getContainingDirectory(); + } + + public PsiElement getParent() { + if (myParent == null) { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0) { + long parentId = getRepositoryManager().getClassView().getParent(repositoryId); + myParent = getRepositoryElementsManager().findOrCreatePsiElementById(parentId); + } + } + return myParent; + } + + public PsiFile getContainingFile() { + PsiElement parent = getParent(); + if (parent == null) return null; + return parent.getContainingFile(); + } + + public PsiElement[] getChildren() { + PsiIdentifier name = getNameIdentifier(); + PsiDocComment docComment = getDocComment(); + PsiModifierList modifierList = getModifierList(); + PsiReferenceList extendsList = getExtendsList(); + PsiReferenceList implementsList = getImplementsList(); + PsiField[] fields = getFields(); + PsiMethod[] methods = getMethods(); + PsiClass[] classes = getInnerClasses(); + + int count = + (docComment != null ? 1 : 0) + + (modifierList != null ? 1 : 0) + + (name != null ? 1 : 0) + + (extendsList != null ? 1 : 0) + + (implementsList != null ? 1 : 0) + + fields.length + + methods.length + + classes.length; + PsiElement[] children = new PsiElement[count]; + + int offset = 0; + if (docComment != null) { + children[offset++] = docComment; + } + if (modifierList != null) { + children[offset++] = modifierList; + } + if (name != null) { + children[offset++] = name; + } + if (extendsList != null) { + children[offset++] = extendsList; + } + if (implementsList != null) { + children[offset++] = implementsList; + } + System.arraycopy(fields, 0, children, offset, fields.length); + offset += fields.length; + System.arraycopy(methods, 0, children, offset, methods.length); + offset += methods.length; + System.arraycopy(classes, 0, children, offset, classes.length); + /*offset += classes.length;*/ + + return children; + } + + public PsiIdentifier getNameIdentifier() { + synchronized (PsiLock.LOCK) { + if (myNameIdentifier == null) { + String qName = getQualifiedName(); + String name = PsiNameHelper.getShortClassName(qName); + if (name.length() == 0) { + name = "_"; + } + myNameIdentifier = new ClsIdentifierImpl(this, name); + } + ; + } + return myNameIdentifier; + } + + public String getName() { + if (myName == null) { + String qName = getQualifiedName(); + myName = PsiNameHelper.getShortClassName(qName); + } + return myName; + } + + public PsiTypeParameterList getTypeParameterList() { + synchronized (PsiLock.LOCK) { + if (myTypeParameters == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + if (!parseViaGenericSignature()) { + myTypeParameters = new ClsTypeParametersListImpl(this, new ClsTypeParameterImpl[0]); + } + } + else { + ClassView classView = getRepositoryManager().getClassView(); + int count = classView.getParametersListSize(repositoryId); + if (count == 0) { + myTypeParameters = new ClsTypeParametersListImpl(this, new ClsTypeParameterImpl[0]); + } + else { + StringBuffer compiledParams = new StringBuffer(); + compiledParams.append('<'); + for (int i = 0; i < count; i++) { + compiledParams.append(classView.getParameterText(repositoryId, i)); + } + compiledParams.append('>'); + try { + final String signature = compiledParams.toString(); + myTypeParameters = + GenericSignatureParsing.parseTypeParametersDeclaration(new StringCharacterIterator(signature, 0), this, signature); + } + catch (ClsFormatException e) { + LOG.error(e); // dsl: this should not happen + } + } + } + } + return myTypeParameters; + } + } + + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public String getQualifiedName() { + synchronized (PsiLock.LOCK) { + if (myQualifiedName == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = getClassFileData(); + BytePointer ptr = new BytePointer(classFileData.getData(), classFileData.getConstantPoolEnd() + 2); + ptr.offset = classFileData.getOffsetInConstantPool(ClsUtil.readU2(ptr)); + int tag = ClsUtil.readU1(ptr); + if (tag != ClsUtil.CONSTANT_Class) { + throw new ClsFormatException(); + } + ptr.offset = classFileData.getOffsetInConstantPool(ClsUtil.readU2(ptr)); + String className = ClsUtil.readUtf8Info(ptr, '/', '.'); + myQualifiedName = ClsUtil.convertClassName(className, false); + } + catch (ClsFormatException e) { + myQualifiedName = ""; + } + } + else { + myQualifiedName = getRepositoryManager().getClassView().getQualifiedName(repositoryId); + if (myQualifiedName == null) { + myQualifiedName = ""; + } + } + } + ; + } + return myQualifiedName; + } + + public PsiModifierList getModifierList() { + synchronized (PsiLock.LOCK) { + if (myModifierList == null) { + int flags = getAccessFlags(); + myModifierList = new ClsModifierListImpl(this, flags); + } + return myModifierList; + } + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiReferenceList getExtendsList() { + synchronized (PsiLock.LOCK) { + if (myExtendsList == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + if (parseViaGenericSignature()) return myExtendsList; + if (!isInterface()) { + myExtendsList = buildSuperList(PsiKeyword.EXTENDS); + } + else { + myExtendsList = buildInterfaceList(PsiKeyword.EXTENDS); + } + } + catch (ClsFormatException e) { + myExtendsList = new ClsReferenceListImpl(this, PsiJavaCodeReferenceElement.EMPTY_ARRAY, PsiKeyword.EXTENDS); + } + } + else { + ClassView classView = getRepositoryManager().getClassView(); + String[] refTexts = classView.getExtendsList(repositoryId); + ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[refTexts.length]; + for (int i = 0; i < refTexts.length; i++) { + refs[i] = new ClsJavaCodeReferenceElementImpl(null, refTexts[i]); + } + myExtendsList = new ClsReferenceListImpl(this, refs, PsiKeyword.EXTENDS); + for (int i = 0; i < refs.length; i++) { + ClsJavaCodeReferenceElementImpl ref = refs[i]; + ref.setParent(myExtendsList); + } + } + } + ; + } + return myExtendsList; + } + + private boolean parseViaGenericSignature() { + try { + String signature = getSignatureAttribute(); + if (signature == null) return false; + + CharacterIterator iterator = new StringCharacterIterator(signature, 0); + myTypeParameters = GenericSignatureParsing.parseTypeParametersDeclaration(iterator, this, signature); + + PsiJavaCodeReferenceElement[] supers = GenericSignatureParsing.parseToplevelClassRefSignatures(iterator, this); + + if (!isInterface()) { + if (supers.length > 0 && !supers[0].getCanonicalText().equals("java.lang.Object")) { + myExtendsList = new ClsReferenceListImpl(this, new PsiJavaCodeReferenceElement[]{supers[0]}, PsiKeyword.EXTENDS); + } + else { + myExtendsList = new ClsReferenceListImpl(this, PsiJavaCodeReferenceElement.EMPTY_ARRAY, PsiKeyword.EXTENDS); + } + + PsiJavaCodeReferenceElement[] interfaces = buildInterfaces(supers); + myImplementsList = new ClsReferenceListImpl(this, interfaces, PsiKeyword.IMPLEMENTS); + } + else { + myImplementsList = new ClsReferenceListImpl(this, PsiJavaCodeReferenceElement.EMPTY_ARRAY, PsiKeyword.IMPLEMENTS); + if (supers.length == 0 || supers[0].getCanonicalText().equals("java.lang.Object")) { + supers = buildInterfaces(supers); + } + myExtendsList = new ClsReferenceListImpl(this, supers, PsiKeyword.EXTENDS); + } + } + catch (ClsFormatException e) { + return false; + } + + return true; + } + + private static PsiJavaCodeReferenceElement[] buildInterfaces(PsiJavaCodeReferenceElement[] supers) { + PsiJavaCodeReferenceElement[] interfaces; + if (supers.length > 0) { + interfaces = new PsiJavaCodeReferenceElement[supers.length - 1]; + for (int i = 1; i < supers.length; i++) { + interfaces[i - 1] = supers[i]; + } + } + else { + interfaces = PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + return interfaces; + } + + public PsiReferenceList getImplementsList() { + synchronized (PsiLock.LOCK) { + if (myImplementsList == null) { + if (!isInterface()) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + if (parseViaGenericSignature()) return myImplementsList; + myImplementsList = buildInterfaceList(PsiKeyword.IMPLEMENTS); + } + catch (ClsFormatException e) { + myImplementsList = new ClsReferenceListImpl(this, PsiJavaCodeReferenceElement.EMPTY_ARRAY, PsiKeyword.IMPLEMENTS); + } + } + else { + ClassView classView = getRepositoryManager().getClassView(); + String[] refTexts = classView.getImplementsList(repositoryId); + ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[refTexts.length]; + for (int i = 0; i < refTexts.length; i++) { + refs[i] = new ClsJavaCodeReferenceElementImpl(null, refTexts[i]); + } + myImplementsList = new ClsReferenceListImpl(this, refs, PsiKeyword.IMPLEMENTS); + for (int i = 0; i < refs.length; i++) { + ClsJavaCodeReferenceElementImpl ref = refs[i]; + ref.setParent(myImplementsList); + } + } + } + else { + myImplementsList = new ClsReferenceListImpl(this, PsiJavaCodeReferenceElement.EMPTY_ARRAY, PsiKeyword.IMPLEMENTS); + } + } + ; + } + return myImplementsList; + } + + public PsiClassType[] getExtendsListTypes() { + return PsiClassImplUtil.getExtendsListTypes(this); + } + + public PsiClassType[] getImplementsListTypes() { + return PsiClassImplUtil.getImplementsListTypes(this); + } + + public PsiClass getSuperClass() { + return PsiClassImplUtil.getSuperClass(this); + } + + public PsiClass[] getInterfaces() { + return PsiClassImplUtil.getInterfaces(this); + } + + public PsiClass[] getSupers() { + return PsiClassImplUtil.getSupers(this); + } + + public PsiClassType[] getSuperTypes() { + return PsiClassImplUtil.getSuperTypes(this); + } + + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? ((PsiClass)parent) : null; + } + + private PsiReferenceList buildSuperList(String type) throws ClsFormatException { + ClassFileData classFileData = getClassFileData(); + int offset = classFileData.getConstantPoolEnd() + 4; + if (offset + 2 > myClassFileData.data.length) { + throw new ClsFormatException(); + } + int b1 = myClassFileData.data[offset++] & 0xFF; + int b2 = myClassFileData.data[offset/*++*/] & 0xFF; + int index = (b1 << 8) + b2; + ClsJavaCodeReferenceElementImpl ref = index != 0 ? classFileData.buildReference(index) : null; + if (ref != null && "java.lang.Object".equals(ref.getCanonicalText())) { + ref = null; + } + PsiReferenceList list = new ClsReferenceListImpl(this, + ref != null + ? new PsiJavaCodeReferenceElement[]{ref} + : PsiJavaCodeReferenceElement.EMPTY_ARRAY, + type); + if (ref != null) { + ref.setParent(list); + } + return list; + } + + private PsiReferenceList buildInterfaceList(String type) throws ClsFormatException { + ClassFileData classFileData = getClassFileData(); + int offset = classFileData.getConstantPoolEnd() + 6; + byte[] data = classFileData.getData(); + if (offset + 2 > data.length) { + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int count = (b1 << 8) + b2; + if (offset + count * 2 > data.length) { + throw new ClsFormatException(); + } + ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[count]; + for (int i = 0; i < count; i++) { + b1 = data[offset++] & 0xFF; + b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + refs[i] = classFileData.buildReference(index); + } + PsiReferenceList list = new ClsReferenceListImpl(this, refs, type); + for (int i = 0; i < count; i++) { + refs[i].setParent(list); + } + return list; + } + + public PsiField[] getFields() { + synchronized (PsiLock.LOCK) { + if (myFields == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = getClassFileData(); + BytePointer ptr = new BytePointer(classFileData.getData(), classFileData.getConstantPoolEnd() + 6); + int count = ClsUtil.readU2(ptr); + ptr.offset += count * 2; // skip interfaces + count = ClsUtil.readU2(ptr); + ArrayList array = new ArrayList(); + for (int i = 0; i < count; i++) { + PsiField field; + if (isEnumField(ptr.offset)) { + field = new ClsEnumConstantImpl(this, ptr.offset); + } + else { + field = new ClsFieldImpl(this, ptr.offset); + } + String name = field.getName(); + //if (name.indexOf('$') < 0 && name.indexOf('<') < 0){ // skip synthetic fields + if (myManager.getNameHelper().isIdentifier(name) && name.indexOf('$') < 0) { // skip synthetic&obfuscated fields + array.add(field); + } + ptr.offset += 6; + ClsUtil.skipAttributes(ptr); + } + myFields = array.toArray(new PsiField[array.size()]); + } + catch (ClsFormatException e) { + myFields = PsiField.EMPTY_ARRAY; + } + } + else { + long[] fieldIds = getRepositoryManager().getClassView().getFields(repositoryId); + PsiField[] fields = new PsiField[fieldIds.length]; + RepositoryElementsManager repositoryElementsManager = getRepositoryElementsManager(); + for (int i = 0; i < fieldIds.length; i++) { + long id = fieldIds[i]; + fields[i] = (PsiField)repositoryElementsManager.findOrCreatePsiElementById(id); + } + myFields = fields; + } + } + ; + } + return myFields; + } + + private boolean isEnumField(int ptrOffset) { + int flags = 0; + try { + int offset = ptrOffset; + byte[] data = getClassFileData().getData(); + if (offset + 2 > data.length) { + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset] & 0xFF; + flags = (b1 << 8) + b2; + } + catch (ClsFormatException e) {} + + return (flags & ClsUtil.ACC_ENUM) != 0; + } + + public PsiMethod[] getMethods() { + synchronized (PsiLock.LOCK) { + if (myMethods == null) { + long repositoryId = getRepositoryId(); + + if (repositoryId < 0) { + try { + ClassFileData classFileData = getClassFileData(); + BytePointer ptr = new BytePointer(classFileData.getData(), classFileData.getConstantPoolEnd() + 6); + int count = ClsUtil.readU2(ptr); + ptr.offset += count * 2; // skip interfaces + count = ClsUtil.readU2(ptr); + for (int i = 0; i < count; i++) { // skip fields + ptr.offset += 6; + ClsUtil.skipAttributes(ptr); + } + count = ClsUtil.readU2(ptr); + ArrayList array = new ArrayList(); + for (int i = 0; i < count; i++) { + ClsMethodImpl method = new ClsMethodImpl(this, ptr.offset); + String name = method.getName(); + //if (name.indexOf('$') < 0 && name.indexOf('<') < 0){ // skip synthetic methods + if (!method.isBridge()) { //skip bridge methods + if (myManager.getNameHelper().isIdentifier(name) && name.indexOf('$') < 0) { // skip synthetic&obfuscated methods + array.add(method); + } + } + ptr.offset += 6; + ClsUtil.skipAttributes(ptr); + } + myMethods = array.toArray(new PsiMethod[array.size()]); + } + catch (ClsFormatException e) { + myMethods = PsiMethod.EMPTY_ARRAY; + } + } + else { + long[] methodIds = getRepositoryManager().getClassView().getMethods(repositoryId); + PsiMethod[] methods = new PsiMethod[methodIds.length]; + RepositoryElementsManager repositoryElementsManager = getRepositoryElementsManager(); + for (int i = 0; i < methodIds.length; i++) { + long id = methodIds[i]; + methods[i] = (PsiMethod)repositoryElementsManager.findOrCreatePsiElementById(id); + } + myMethods = methods; + } + } + ; + } + return myMethods; + } + + public PsiMethod[] getConstructors() { + if (myConstructors == null){ + myConstructors = PsiImplUtil.getConstructors(this); + } + return myConstructors; + } + + public PsiClass[] getInnerClasses() { + synchronized (PsiLock.LOCK) { + if (myInnerClasses == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + VirtualFile vFile = myClassFileData.vFile; + VirtualFile parentFile = vFile.getParent(); + if (parentFile == null) return null; + String name = vFile.getNameWithoutExtension(); + String prefix = name + "$"; + ArrayList array = new ArrayList(); + VirtualFile[] children = parentFile.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + String childName = child.getNameWithoutExtension(); + if (childName.startsWith(prefix)) { + String innerName = childName.substring(prefix.length()); + if (innerName.indexOf('$') >= 0) continue; + if (!myManager.getNameHelper().isIdentifier(innerName)) continue; + PsiClass aClass = new ClsClassImpl(myManager, this, child); + array.add(aClass); + } + } + myInnerClasses = array.toArray(new PsiClass[array.size()]); + } + else { + long[] classIds = getRepositoryManager().getClassView().getInnerClasses(repositoryId); + PsiClass[] classes = new PsiClass[classIds.length]; + RepositoryElementsManager repositoryElementsManager = getRepositoryElementsManager(); + for (int i = 0; i < classIds.length; i++) { + long id = classIds[i]; + classes[i] = (PsiClass)repositoryElementsManager.findOrCreatePsiElementById(id); + } + myInnerClasses = classes; + } + } + ; + } + return myInnerClasses; + } + + public PsiClassInitializer[] getInitializers() { + //Diagnostic.methodNotImplemented(); + return PsiClassInitializer.EMPTY_ARRAY; + } + + public PsiTypeParameter[] getTypeParameters() { + return PsiClassImplUtil.getTypeParameters(this); + } + + public PsiField[] getAllFields() { + return PsiClassImplUtil.getAllFields(this); + } + + public PsiMethod[] getAllMethods() { + return PsiClassImplUtil.getAllMethods(this); + } + + public PsiClass[] getAllInnerClasses() { + return PsiClassImplUtil.getAllInnerClasses(this); + } + + public PsiField findFieldByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedFieldsMap == null){ + myCachedFieldsMap = new HashMap(); + final PsiField[] fields = getFields(); + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + myCachedFieldsMap.put(field.getName(), field); + } + } + return myCachedFieldsMap.get(name); + } + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedMethodsMap == null){ + myCachedMethodsMap = new HashMap(); + Map> cachedMethodsMap = new HashMap>(); + final PsiMethod[] methods = getMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + List list = cachedMethodsMap.get(method.getName()); + if(list == null){ + list = new ArrayList(1); + cachedMethodsMap.put(method.getName(), list); + } + list.add(method); + } + final Iterator iterator = cachedMethodsMap.keySet().iterator(); + while (iterator.hasNext()) { + final String methodName = iterator.next(); + myCachedMethodsMap.put(methodName, cachedMethodsMap.get(methodName).toArray(PsiMethod.EMPTY_ARRAY)); + } + } + final PsiMethod[] psiMethods = myCachedMethodsMap.get(name); + return psiMethods != null ? psiMethods : PsiMethod.EMPTY_ARRAY; + } + + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + public List> findMethodsAndTheirSubstitutorsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + public PsiClass findInnerClassByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedInnersMap == null){ + myCachedInnersMap = new HashMap(); + final PsiClass[] classes = getInnerClasses(); + for (int i = 0; i < classes.length; i++) { + final PsiClass psiClass = classes[i]; + myCachedInnersMap.put(psiClass.getName(), psiClass); + } + } + return myCachedInnersMap.get(name); + } + return PsiClassImplUtil.findInnerByName(this, name, checkBases); + } + + public boolean isDeprecated() { + synchronized (PsiLock.LOCK) { + if (myIsDeprecated == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + boolean isDeprecated = readClassAttribute("Deprecated") != null; + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + catch (ClsFormatException e) { + myIsDeprecated = Boolean.FALSE; + } + } + else { + boolean isDeprecated = getRepositoryManager().getClassView().isDeprecated(repositoryId); + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + } + ; + } + return myIsDeprecated.booleanValue(); + } + + public String getSourceFileName() { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + String sourceFileName = getClassFileData().readUtf8Attribute(readClassAttribute("SourceFile")); + if (sourceFileName == null) { + sourceFileName = obtainSourceFileNameFromClassFileName(); + return sourceFileName; + } + int slashIndex = sourceFileName.lastIndexOf('/'); // We need short name while some compilers do generate fulls + if (slashIndex >= 0) { + sourceFileName = sourceFileName.substring(slashIndex + 1, sourceFileName.length()); + } + return sourceFileName; + } + catch (ClsFormatException e) { + return null; + } + } + else { + ClsFileImpl file = (ClsFileImpl)getContainingFile(); + String sourceFileName = getRepositoryManager().getFileView().getSourceFileName(file.getRepositoryId()); + if (sourceFileName == null || sourceFileName.length() == 0) { + sourceFileName = obtainSourceFileNameFromClassFileName(); + } + return sourceFileName; + } + } + } + + private String obtainSourceFileNameFromClassFileName() { + final String name = getContainingFile().getName(); + int i = name.indexOf('$'); + if (i < 0) { + i = name.indexOf('.'); + if (i < 0) { + i = name.length(); + } + } + return name.substring(0, i) + ".java"; + } + + public String getSignatureAttribute() throws ClsFormatException { + return getClassFileData().readUtf8Attribute(readClassAttribute("Signature")); + } + + private BytePointer readClassAttribute(String attributeName) throws ClsFormatException { + ClassFileData classFileData = getClassFileData(); + BytePointer ptr = new BytePointer(classFileData.getData(), classFileData.getConstantPoolEnd() + 6); + int count = ClsUtil.readU2(ptr); + ptr.offset += count * 2; // skip interfaces + count = ClsUtil.readU2(ptr); + for (int i = 0; i < count; i++) { // skip fields + ptr.offset += 6; + ClsUtil.skipAttributes(ptr); + } + count = ClsUtil.readU2(ptr); + for (int i = 0; i < count; i++) { // skip methods + ptr.offset += 6; + ClsUtil.skipAttributes(ptr); + } + + BytePointer attribute = getClassFileData().findAttribute(ptr.offset, attributeName); + return attribute; + } + + public PsiDocComment getDocComment() { + if (!isDeprecated()) return null; + + synchronized (PsiLock.LOCK) { + if (myDocComment == null) { + myDocComment = new ClsDocCommentImpl(this); + } + ; + } + return myDocComment; + } + + public PsiJavaToken getLBrace() { + return null; + } + + public PsiJavaToken getRBrace() { + return null; + } + + public boolean isInterface() { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + return (getAccessFlags() & ClsUtil.ACC_INTERFACE) != 0; + } + else { + return getRepositoryManager().getClassView().isInterface(repositoryId); + } + } + + public boolean isAnnotationType() { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + return (getAccessFlags() & ClsUtil.ACC_ANNOTATION) != 0; + } + else { + return getRepositoryManager().getClassView().isAnnotationType(repositoryId); + } + } + + public boolean isEnum() { + PsiField[] fields = getFields(); + if (fields.length == 0) return false; + return fields[0] instanceof ClsEnumConstantImpl; + } + + private int getAccessFlags() { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = getClassFileData(); + int offset = classFileData.getConstantPoolEnd(); + byte[] data = classFileData.getData(); + if (offset + 2 > data.length) { + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset/*++*/] & 0xFF; + int flags = ((b1 << 8) + b2) & ClsUtil.ACC_CLASS_MASK; + + PsiElement parent = getParent(); + if (parent instanceof PsiClass) { + PsiClass aClass = (PsiClass)parent; + if (aClass.isInterface()) { + flags |= ClsUtil.ACC_STATIC; + } + else { + flags &= ~ClsUtil.ACC_STATIC; + + BytePointer ptr = readClassAttribute("InnerClasses"); + if (ptr != null) { + //Skip attribute_length + ptr.offset += 4; + int numClasses = ClsUtil.readU2(ptr); + int startOffset = ptr.offset + 4; + for (int i = 0; i < numClasses; i++) { + BytePointer ptr1 = new BytePointer(classFileData.getData(), startOffset + i * 8); + int innerNameIdx = ClsUtil.readU2(ptr1); + if (innerNameIdx == 0) { + continue; + } + int innerNameOffset = classFileData.getOffsetInConstantPool(innerNameIdx); + String innerName = ClsUtil.convertClassName(ClsUtil.readUtf8Info(classFileData.getData(), innerNameOffset), true); + if (getName().equals(innerName)) { + int accessFlags = ClsUtil.readU2(ptr1); + flags = accessFlags; + break; + } + } + } + } + } + return flags; + } + catch (ClsFormatException e) { + return 0; + } + } + else { + ClassView classView = getRepositoryManager().getClassView(); + return classView.getModifiers(repositoryId); + } + } + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); + if (docComment != null) { + buffer.append(docComment.getMirrorText()); + } + buffer.append(((ClsElementImpl)getModifierList()).getMirrorText()); + buffer.append(' '); + buffer.append(isEnum() ? "enum " : isAnnotationType() ? "@interface " : isInterface() ? "interface " : "class "); + buffer.append(((ClsElementImpl)getNameIdentifier()).getMirrorText()); + buffer.append(((ClsTypeParametersListImpl)getTypeParameterList()).getMirrorText()); + buffer.append(' '); + if (!isEnum() & !isAnnotationType()) { + buffer.append(((ClsElementImpl)getExtendsList()).getMirrorText()); + buffer.append(' '); + } + if (!isInterface()) { + buffer.append(((ClsElementImpl)getImplementsList()).getMirrorText()); + } + buffer.append('{'); + PsiField[] fields = getFields(); + for (int i = 0; i < fields.length; i++) { + PsiField field = fields[i]; + buffer.append(((ClsElementImpl)field).getMirrorText()); + if (field instanceof ClsEnumConstantImpl) { + if (i < fields.length - 1 && fields[i + 1] instanceof ClsEnumConstantImpl) { + buffer.append(", "); + } else { + buffer.append(";"); + } + } + } + PsiMethod[] methods = getMethods(); + for (int i = 0; i < methods.length; i++) { + buffer.append(((ClsElementImpl)methods[i]).getMirrorText()); + } + PsiClass[] classes = getInnerClasses(); + for (int i = 0; i < classes.length; i++) { + buffer.append(((ClsElementImpl)classes[i]).getMirrorText()); + } + buffer.append('}'); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + PsiClass mirror = (PsiClass)SourceTreeToPsiMap.treeElementToPsi(element); + + if (getDocComment() != null) { + ((ClsElementImpl)getDocComment()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getDocComment())); + } + ((ClsElementImpl)getModifierList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getModifierList())); + ((ClsElementImpl)getNameIdentifier()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameIdentifier())); + if (!isAnnotationType() &&!isEnum()) { + ((ClsElementImpl)getExtendsList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getExtendsList())); + } + ((ClsElementImpl)getImplementsList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getImplementsList())); + ((ClsElementImpl)getTypeParameterList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getTypeParameterList())); + + PsiField[] fields = getFields(); + PsiField[] mirrorFields = mirror.getFields(); + if (LOG.assertTrue(fields.length == mirrorFields.length)) { + for (int i = 0; i < fields.length; i++) { + ((ClsElementImpl)fields[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(mirrorFields[i])); + } + } + + PsiMethod[] methods = getMethods(); + PsiMethod[] mirrorMethods = mirror.getMethods(); + if (LOG.assertTrue(methods.length == mirrorMethods.length)) { + for (int i = 0; i < methods.length; i++) { + ((ClsElementImpl)methods[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(mirrorMethods[i])); + } + } + + PsiClass[] classes = getInnerClasses(); + PsiClass[] mirrorClasses = mirror.getInnerClasses(); + if (LOG.assertTrue(classes.length == mirrorClasses.length)) { + for (int i = 0; i < classes.length; i++) { + ((ClsElementImpl)classes[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(mirrorClasses[i])); + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitClass(this); + } + + public String toString() { + return "PsiClass:" + getName(); + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + return PsiClassImplUtil.processDeclarationsInClass(this, processor, substitutor, new HashSet(), lastParent, place); + } + + public PsiElement getScope() { + return getParent(); + } + + public boolean isInheritor(PsiClass baseClass, boolean checkDeep) { + return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep); + } + + public PomMemberOwner getPom() { + //TODO: + return null; + } + + public PsiClass getSourceMirrorClass() { + PsiElement parent = getParent(); + if (parent instanceof PsiFile) { + String packageName = ((ClsFileImpl)parent).getPackageName(); + String sourceFileName = getSourceFileName(); + String relativeFilePath = packageName.replace('.', '/') + '/' + sourceFileName; + + final VirtualFile vFile = getContainingFile().getVirtualFile(); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); + final OrderEntry[] orderEntries = projectFileIndex.getOrderEntriesForFile(vFile); + for (int i = 0; i < orderEntries.length; i++) { + VirtualFile[] files = orderEntries[i].getFiles(OrderRootType.SOURCES); + for (int j = 0; j < files.length; j++) { + VirtualFile source = files[j].findFileByRelativePath(relativeFilePath); + if (source != null) { + PsiFile psiSource = getManager().findFile(source); + if (psiSource == null) continue; + if (!(psiSource instanceof PsiJavaFile)) { + LOG.error("Not PsiJavaFile:" + psiSource); + continue; + } + PsiJavaFile psiJavaFile = (PsiJavaFile)psiSource; + PsiClass[] classes = psiJavaFile.getClasses(); + for (int k = 0; k < classes.length; k++) { + PsiClass aClass = classes[k]; + if (aClass.getName().equals(getName())) return aClass; + } + } + } + } + } + else { + ClsClassImpl parentClass = (ClsClassImpl)parent; + PsiClass parentSourceMirror = parentClass.getSourceMirrorClass(); + if (parentSourceMirror == null) return null; + PsiClass[] innerClasses = parentSourceMirror.getInnerClasses(); + for (int i = 0; i < innerClasses.length; i++) { + PsiClass innerClass = innerClasses[i]; + if (innerClass.getName().equals(getName())) return innerClass; + } + } + + return null; + } + + public PsiElement getNavigationElement() { + PsiClass aClass = getSourceMirrorClass(); + return aClass != null ? aClass : this; + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return false; + } + + public ClsAnnotationImpl[] getAnnotations() { + if (myAnnotations == null) { + ClsAnnotationsUtil.AttributeReader reader = new ClsAnnotationsUtil.AttributeReader() { + public BytePointer readAttribute(String attributeName) { + try { + return readClassAttribute(attributeName); + } + catch (ClsFormatException e) { + return null; + } + } + + public ClassFileData getClassFileData() { + return ClsClassImpl.this.getClassFileData(); + } + }; + myAnnotations = ClsAnnotationsUtil.getAnnotationsImpl(this, reader, myModifierList); + } + + return myAnnotations; + } + + public ItemPresentation getPresentation() { + return ClassPresentationUtil.getPresentation(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java new file mode 100644 index 00000000000..10aa68b9e60 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java @@ -0,0 +1,58 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author ven + */ +public class ClsClassObjectAccessExpressionImpl extends ClsElementImpl implements PsiClassObjectAccessExpression { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsClassObjectAccessExpressionImpl"); + private ClsTypeElementImpl myTypeElement; + private ClsElementImpl myParent; + + public ClsClassObjectAccessExpressionImpl (String canonicalClassText, ClsElementImpl parent) { + myParent = parent; + myTypeElement = new ClsTypeElementImpl(this, canonicalClassText, ClsTypeElementImpl.VARIANCE_NONE); + } + + public String getMirrorText() { + return myTypeElement.getMirrorText() + ".class"; + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiClassObjectAccessExpression mirror = (PsiClassObjectAccessExpression)SourceTreeToPsiMap.treeElementToPsi(element); + ((ClsElementImpl)getOperand()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getOperand())); + } + + public PsiElement[] getChildren() { + return new PsiElement[] {myTypeElement}; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitClassObjectAccessExpression(this); + } + + public PsiTypeElement getOperand() { + return myTypeElement; + } + + public PsiType getType() { + return PsiImplUtil.getType(this); + } + + public String getText() { + return getMirrorText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java new file mode 100644 index 00000000000..245026d5dc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java @@ -0,0 +1,82 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; + +class ClsDocCommentImpl extends ClsElementImpl implements PsiDocComment, JavaTokenType{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsDocCommentImpl"); + + private final ClsElementImpl myParent; + + private PsiDocTag[] myTags = null; + + public ClsDocCommentImpl(ClsElementImpl parent) { + myParent = parent; + } + + public String getMirrorText() { + getTags(); + StringBuffer buffer = new StringBuffer(); + buffer.append("/**\n"); + for(int i = 0; i < myTags.length; i++){ + PsiDocTag tag = myTags[i]; + buffer.append("* "); + buffer.append(tag.getText()); + buffer.append("\n"); + } + buffer.append("*/"); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.DOC_COMMENT); + myMirror = element; + } + + public PsiElement[] getChildren() { + return getTags(); + } + + public PsiElement getParent() { + return myParent; + } + + public PsiElement[] getDescriptionElements() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiDocTag[] getTags() { + if (myTags == null){ + myTags = new PsiDocTag[1]; + myTags[0] = new ClsDocTagImpl(this, "@deprecated"); + } + return myTags; + } + + public PsiDocTag findTagByName(String name) { + if (!name.equals("deprecated")) return null; + return getTags()[0]; + } + + public PsiDocTag[] findTagsByName(String name) { + if (!name.equals("deprecated")) return PsiDocTag.EMPTY_ARRAY; + return getTags(); + } + + public IElementType getTokenType() { + return JavaTokenType.DOC_COMMENT; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocComment(this); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocTagImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocTagImpl.java new file mode 100644 index 00000000000..45237a5f0f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsDocTagImpl.java @@ -0,0 +1,127 @@ + +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.util.IncorrectOperationException; + +class ClsDocTagImpl extends ClsElementImpl implements PsiDocTag { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsDocTagImpl"); + + private final ClsDocCommentImpl myDocComment; + private final PsiElement myNameElement; + + public ClsDocTagImpl(ClsDocCommentImpl docComment, String name) { + myDocComment = docComment; + myNameElement = new NameElement(name); + } + + public String getMirrorText() { + return myNameElement.getText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.DOC_TAG); + myMirror = element; + } + + public String getText() { + return myNameElement.getText(); + } + + public char[] textToCharArray(){ + return myNameElement.textToCharArray(); + } + + public String getName() { + return getNameElement().getText().substring(1); + } + + public boolean textMatches(CharSequence text) { + return myNameElement.textMatches(text); + } + + public boolean textMatches(PsiElement element) { + return myNameElement.textMatches(element); + } + + public int getTextLength(){ + return myNameElement.getTextLength(); + } + + public PsiElement[] getChildren() { + return new PsiElement[]{myNameElement}; + } + + public PsiElement getParent() { + return getContainingComment(); + } + + public PsiDocComment getContainingComment() { + return myDocComment; + } + + public PsiElement getNameElement() { + return myNameElement; + } + + public PsiElement[] getDataElements() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiDocTagValue getValueElement() { + return null; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocTag(this); + } + + private class NameElement extends ClsElementImpl { + private String myText; + + public NameElement(String text) { + myText = text; + } + + public String getText() { + return myText; + } + + public char[] textToCharArray(){ + return myText.toCharArray(); + } + + public PsiElement[] getChildren(){ + return PsiElement.EMPTY_ARRAY; + } + + public String getMirrorText() { + return null; + } + + public void setMirror(TreeElement element) { + myMirror = element; + } + + public PsiElement getParent() { + return ClsDocTagImpl.this; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitElement(this); + } + } + public PsiElement setName(String name) throws IncorrectOperationException{ + SharedPsiElementImplUtil.setName(getNameElement(), name); + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsElementImpl.java new file mode 100644 index 00000000000..0aa436ded4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsElementImpl.java @@ -0,0 +1,193 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiElementBase; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.util.IncorrectOperationException; + +abstract class ClsElementImpl extends PsiElementBase implements PsiCompiledElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsElementImpl"); + + protected TreeElement myMirror = null; + + public PsiManager getManager() { + return getParent().getManager(); + } + + public PsiFile getContainingFile() { + return getParent().getContainingFile(); + } + + public final boolean isWritable() { + return false; + } + + public boolean isPhysical() { + return true; + } + + public boolean isValid() { + PsiElement parent = getParent(); + return parent != null && parent.isValid(); + } + + public PsiElement copy() { + return this; + } + + public void checkAdd(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void delete() throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkDelete() throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + protected static final String CAN_NOT_MODIFY_MESSAGE = "Cannot modify compiled element"; + + public abstract String getMirrorText(); + + public abstract void setMirror(TreeElement element); + + public final PsiElement getMirror() { + synchronized (PsiLock.LOCK) { + if (myMirror == null) { + getContainingFile().getText(); // to initialize mirror + } + ; + } + return SourceTreeToPsiMap.treeElementToPsi(myMirror); + } + + public final TextRange getTextRange() { + getMirror(); + return myMirror != null ? myMirror.getTextRange() : new TextRange(0, 0); + } + + public final int getStartOffsetInParent() { + getMirror(); + return myMirror != null ? myMirror.getStartOffsetInParent() : -1; + } + + public int getTextLength() { + String text = getText(); + if (text == null){ + LOG.error("getText() == null, element = " + this + ", parent = " + getParent()); + return 0; + } + return text.length(); + } + + public PsiElement findElementAt(int offset) { + PsiElement mirrorAt = getMirror().findElementAt(offset); + while(true){ + if (mirrorAt == null) return null; + PsiElement elementAt = mirrorToElement(mirrorAt); + if (elementAt != null) return elementAt; + mirrorAt = mirrorAt.getParent(); + } + + /* + PsiElement[] children = getChildren(); + if (children.length == 0) return this; + for(int i = 0; i < children.length; i++){ + int start = children[i].getStartOffsetInParent(); + if (offset < start) return null; + int end = start + children[i].getTextLength(); + if (offset < end){ + return children[i].findElementAt(offset - start); + } + } + return null; + */ + } + + public PsiReference findReferenceAt(int offset) { + PsiReference mirrorRef = getMirror().findReferenceAt(offset); + if (mirrorRef == null) return null; + PsiElement mirrorElement = mirrorRef.getElement(); + PsiElement element = mirrorToElement(mirrorElement); + if (element == null) return null; + return element.getReference(); + } + + private PsiElement mirrorToElement(PsiElement mirror) { + getMirror(); + if (myMirror == mirror) return this; + + PsiElement[] children = getChildren(); + if (children.length == 0) return null; + + for(int i = 0; i < children.length; i++){ + PsiElement element = ((ClsElementImpl)children[i]).mirrorToElement(mirror); + if (element != null) return element; + } + + return null; + } + + public final int getTextOffset() { + getMirror(); + return myMirror != null ? myMirror.getTextOffset() : -1; + } + + public String getText() { + getMirror(); + return myMirror != null ? myMirror.getText() : null; + } + + public char[] textToCharArray() { + return getText().toCharArray(); + } + + public boolean textMatches(CharSequence text) { + return getText().equals(text.toString()); + } + + public boolean textMatches(PsiElement element) { + return getText().equals(element.getText()); + } + + public PsiElement getNavigationElement() { + return this; + } + + public PsiElement getOriginalElement() { + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java new file mode 100644 index 00000000000..49a975d9ea3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java @@ -0,0 +1,88 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author ven + */ +public class ClsEnumConstantImpl extends ClsFieldImpl implements PsiEnumConstant { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsEnumConstantImpl"); + public ClsEnumConstantImpl(ClsClassImpl parent, int startOffset) { + super(parent, startOffset); + } + + public ClsEnumConstantImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); + if (docComment != null) { + buffer.append(docComment.getMirrorText()); + } + + buffer.append(((ClsElementImpl)getModifierList()).getMirrorText()); + buffer.append(' '); + buffer.append(((ClsElementImpl)getNameIdentifier()).getMirrorText()); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiField mirror = (PsiField)SourceTreeToPsiMap.treeElementToPsi(element); + if (getDocComment() != null){ + ((ClsElementImpl)getDocComment()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getDocComment())); + } + ((ClsElementImpl)getModifierList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getModifierList())); + ((ClsElementImpl)getNameIdentifier()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameIdentifier())); + } + + public PsiExpressionList getArgumentList() { + return null; + } + + public PsiMethod resolveMethod() { + return null; + } + + public ResolveResult resolveMethodGenerics() { + return ResolveResult.EMPTY; + } + + public PsiEnumConstantInitializer getInitializingClass() { + return null; + } + + public PsiMethod resolveConstructor() { + return null; + } + + + public PsiType getType() { + return getManager().getElementFactory().createType(getContainingClass()); + } + + public PsiTypeElement getTypeElement() { + return null; + } + + public PsiExpression getInitializer() { + return null; + } + + public boolean hasInitializer() { + return true; + } + + public boolean hasModifierProperty(String name) { + return (PsiModifier.PUBLIC.equals(name) || PsiModifier.STATIC.equals(name) || PsiModifier.FINAL.equals(name)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFieldImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFieldImpl.java new file mode 100644 index 00000000000..18971b76fcd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFieldImpl.java @@ -0,0 +1,617 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.PomField; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiConstantEvaluationHelperImpl; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiVariableEx; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.cache.FieldView; +import com.intellij.psi.impl.cache.InitializerTooLongException; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.BytePointer; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.cls.ClsUtil; + +import java.text.StringCharacterIterator; +import java.util.HashSet; +import java.util.Set; + +public class ClsFieldImpl extends ClsRepositoryPsiElement implements PsiField, PsiVariableEx, ClsModifierListOwner { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsFieldImpl"); + + private ClsClassImpl myParent; + private int myStartOffset; + + private String myName = null; + private PsiIdentifier myNameIdentifier = null; + private PsiTypeElement myType = null; + private ClsModifierListImpl myModifierList = null; + private PsiDocComment myDocComment = null; + private Boolean myIsDeprecated = null; + private PsiExpression myInitializer = null; + private boolean myInitializerInitialized = false; + private ClsAnnotationImpl[] myAnnotations = null; + + public ClsFieldImpl(ClsClassImpl parent, int startOffset) { + super(parent.myManager, -1); + myParent = parent; + myStartOffset = startOffset; + } + + public ClsFieldImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + myParent = null; + myStartOffset = -1; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + if (repositoryId >= 0){ + myStartOffset = -1; + } + } + + public PsiElement[] getChildren() { + PsiDocComment docComment = getDocComment(); + PsiModifierList modifierList = getModifierList(); + PsiTypeElement type = getTypeElement(); + PsiIdentifier name = getNameIdentifier(); + + int count = + (docComment != null ? 1 : 0) + + (modifierList != null ? 1 : 0) + + (type != null ? 1 : 0) + + (name != null ? 1 : 0); + PsiElement[] children = new PsiElement[count]; + + int offset = 0; + if (docComment != null){ + children[offset++] = docComment; + } + if (modifierList != null){ + children[offset++] = modifierList; + } + if (type != null){ + children[offset++] = type; + } + if (name != null){ + children[offset++] = name; + } + + return children; + } + + public PsiElement getParent() { + final long parentId = getParentId(); + if(parentId < 0) return myParent; + return getRepositoryElementsManager().findOrCreatePsiElementById(parentId); + } + + public PsiClass getContainingClass() { + return (PsiClass)getParent(); + } + + public PsiIdentifier getNameIdentifier() { + synchronized (PsiLock.LOCK) { + if (myNameIdentifier == null) { + myNameIdentifier = new ClsIdentifierImpl(this, getName()); + } + ; + } + return myNameIdentifier; + } + + public String getName() { + if (myName == null) { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + byte[] data = classFileData.getData(); + int offset = myStartOffset + 2; + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + offset = classFileData.getOffsetInConstantPool(index); + myName = ClsUtil.readUtf8Info(data, offset); + } + catch (ClsFormatException e) { + myName = ""; + } + } + else { + myName = getRepositoryManager().getFieldView().getName(repositoryId); + } + ; + } + } + return myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiType getType() { + return getTypeElement().getType(); + } + + public PsiTypeElement getTypeElement() { + if (myType == null) { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + if (!parseViaGenericSignature()) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + byte[] data = classFileData.getData(); + int offset = myStartOffset + 4; + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + offset = classFileData.getOffsetInConstantPool(index); + offset += 3; // skip tag and length + String typeText = ClsUtil.getTypeText(data, offset); + myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE); + } + catch (ClsFormatException e) { + myType = null; + } + } + } + else { + String typeText = getRepositoryManager().getFieldView().getTypeText(repositoryId); + myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE); + } + ; + } + } + return myType; + } + + public String getSignatureAttribute() { + try { + ClassFileData data = myParent.getClassFileData(); + return data.readUtf8Attribute(data.findAttribute(myStartOffset + 6, "Signature")); + } catch (ClsFormatException e) { + return null; + } + } + + private boolean parseViaGenericSignature() { + if (getRepositoryId() >= 0) return false; + try { + String signature = getSignatureAttribute(); + if (signature == null) return false; + + myType = new ClsTypeElementImpl(this, GenericSignatureParsing.parseTypeString(new StringCharacterIterator(signature, 0)), ClsTypeElementImpl.VARIANCE_NONE); + return true; + } + catch (ClsFormatException e) { + return false; + } + } + + public PsiModifierList getModifierList() { + synchronized (PsiLock.LOCK) { + if (myModifierList == null) { + int flags = getAccessFlags(); + myModifierList = new ClsModifierListImpl(this, flags & ClsUtil.ACC_FIELD_MASK); + } + ; + } + return myModifierList; + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + private int getAccessFlags() { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + int offset = myStartOffset; + byte[] data = myParent.getClassFileData().getData(); + if (offset + 2 > data.length) { + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + return (b1 << 8) + b2; + } + catch (ClsFormatException e) { + return 0; + } + } + else { + FieldView fieldView = getRepositoryManager().getFieldView(); + return fieldView.getModifiers(repositoryId); + } + } + } + + public PsiExpression getInitializer() { + synchronized (PsiLock.LOCK) { + if (!myInitializerInitialized) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + myInitializer = createInitializerFromClassFile(); + } + catch (ClsFormatException e) { + } + } + else { + myInitializer = createInitializerFromRepository(); + } + myInitializerInitialized = true; + } + ; + } + return myInitializer; + } + + private PsiExpression createInitializerFromClassFile() throws ClsFormatException { + ClassFileData classFileData = myParent.getClassFileData(); + BytePointer ptr = classFileData.findAttribute(myStartOffset + 6, "ConstantValue"); + if (ptr == null) return null; + ptr.offset += 4; // skip length + int index = ClsUtil.readU2(ptr); + int offsetInPool = classFileData.getOffsetInConstantPool(index); + + ptr = new BytePointer(classFileData.getData(), offsetInPool); + int kind = ClsUtil.readU1(ptr); + + PsiType type = getType(); + if (PsiType.INT == type){ + if (kind != ClsUtil.CONSTANT_Integer){ + throw new ClsFormatException(); + } + int v = ClsUtil.readU4(ptr); + return createNumberExpr(v); + } + else if (PsiType.LONG == type){ + if (kind != ClsUtil.CONSTANT_Long){ + throw new ClsFormatException(); + } + int valueH = ClsUtil.readU4(ptr); + int valueL = ClsUtil.readU4(ptr); + long v = ((long)valueH << 32) | (valueL & 0xFFFFFFFFL); + return createNumberExpr(v); + } + else if (PsiType.SHORT == type){ + if (kind != ClsUtil.CONSTANT_Integer){ + throw new ClsFormatException(); + } + int v = ClsUtil.readU4(ptr); + return createNumberExpr(v); + } + else if (PsiType.BYTE == type){ + if (kind != ClsUtil.CONSTANT_Integer){ + throw new ClsFormatException(); + } + int v = ClsUtil.readU4(ptr); + return createNumberExpr(v); + } + else if (PsiType.CHAR == type){ + if (kind != ClsUtil.CONSTANT_Integer){ + throw new ClsFormatException(); + } + char v = (char)ClsUtil.readU4(ptr); + Object value = new Character(v); + String text = literalToString(value.toString(), '\''); + return new ClsLiteralExpressionImpl(this, text, type, value); + } + else if (PsiType.BOOLEAN == type){ + if (kind != ClsUtil.CONSTANT_Integer){ + throw new ClsFormatException(); + } + int v = ClsUtil.readU4(ptr); + Object value = v != 0 ? Boolean.TRUE : Boolean.FALSE; + String text = value.toString(); + return new ClsLiteralExpressionImpl(this, text, type, value); + } + else if (PsiType.FLOAT == type){ + if (kind != ClsUtil.CONSTANT_Float){ + throw new ClsFormatException(); + } + float v = ClsUtil.readFloat(ptr); + String text; + if (Float.isInfinite(v)){ + text = v > 0 ? "Float.POSITIVE_INFINITY" : "Float.NEGATIVE_INFINITY"; + } + else if (Float.isNaN(v)){ + text = "Float.NaN"; + } + else{ + text = Float.toString(v) + "f"; + } + return ClsParsingUtil.createExpressionFromText(text, getManager(), this); + } + else if (PsiType.DOUBLE == type){ + if (kind != ClsUtil.CONSTANT_Double){ + throw new ClsFormatException(); + } + double v = ClsUtil.readDouble(ptr); + String text; + if (Double.isInfinite(v)){ + text = v > 0 ? "Double.POSITIVE_INFINITY" : "Double.NEGATIVE_INFINITY"; + } + else if (Double.isNaN(v)){ + text = "Double.NaN"; + } + else{ + text = Double.toString(v); + } + return ClsParsingUtil.createExpressionFromText(text, getManager(), this); + } + else if (getTypeElement() != null && "java.lang.String".equals(((ClsTypeElementImpl) getTypeElement()).getCanonicalText())){ + if (kind != ClsUtil.CONSTANT_String){ + throw new ClsFormatException(); + } + int stringIndex = ClsUtil.readU2(ptr); + ptr.offset = classFileData.getOffsetInConstantPool(stringIndex); + String value = ClsUtil.readUtf8Info(ptr); + String text = literalToString(value, '"'); + return new ClsLiteralExpressionImpl(this, text, type, value); + } + else{ + throw new ClsFormatException(); + } + } + + private PsiExpression createNumberExpr(long v) { + if (v < 0){ + ClsLiteralExpressionImpl literalExpression = (ClsLiteralExpressionImpl)_createNumberExpr(-v, true); + ClsPrefixExpressionImpl prefixExpression = new ClsPrefixExpressionImpl(this, literalExpression); + literalExpression.setParent(prefixExpression); + return prefixExpression; + } + + return _createNumberExpr(v, false); + } + + private PsiExpression _createNumberExpr(long v, boolean negated) { + String text = Long.toString(v); + if (negated && StringUtil.startsWithChar(text, '-')){ + LOG.assertTrue(v == -1L << 63); + text = text.substring(1); + } + + Object value; + PsiType type; + if (0 <= v && v <= Integer.MAX_VALUE || negated && v == (long)Integer.MAX_VALUE + 1){ + type = PsiType.INT; + value = new Integer((int)v); + } + else{ + type = PsiType.LONG; + text += "L"; + value = new Long(v); + } + return new ClsLiteralExpressionImpl(this, text, type, value); + } + + private PsiExpression createInitializerFromRepository() { + String initializerText; + try{ + initializerText = getRepositoryManager().getFieldView().getInitializerText(getRepositoryId()); + } + catch(InitializerTooLongException e){ + return null; //?? + } + + if (initializerText == null) return null; + + return ClsParsingUtil.createExpressionFromText(initializerText, getManager(), this); + } + + private static String literalToString(String value, char quote) { + int length = value.length(); + StringBuffer buffer = new StringBuffer(length + 3); + buffer.append(quote); + + for(int i = 0; i < length; i++){ + char c = value.charAt(i); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) { + buffer.append(c); + continue; + } + + switch (c) { + case '\b': + buffer.append("\\b"); + break; + case '\t': + buffer.append("\\t"); + break; + case '\n': + buffer.append("\\n"); + break; + case '\f': + buffer.append("\\f"); + break; + case '\r': + buffer.append("\\r"); + break; + case '\\': + buffer.append("\\\\"); + break; + default: + if (c == quote) { + buffer.append("\\" + quote); + } + else if (Character.isISOControl(c)) { + String hexCode = Integer.toHexString(c).toUpperCase(); + buffer.append("\\x"); + int paddingCount = 4 - hexCode.length(); + while (paddingCount-- > 0) { + buffer.append(0); + } + buffer.append(hexCode); + } + else { + buffer.append(c); + } + } + } + + buffer.append(quote); + return buffer.toString(); + } + + public boolean hasInitializer() { + return getInitializer() != null; + } + + public Object computeConstantValue() { + return computeConstantValue(new HashSet()); + } + + public Object computeConstantValue(Set visitedVars) { + if (!hasModifierProperty(PsiModifier.FINAL)) return null; + PsiExpression initializer = getInitializer(); + if (initializer == null) return null; + + final String qName = getContainingClass().getQualifiedName(); + if ("java.lang.Float".equals(qName)) { + if ("POSITIVE_INFINITY".equals(getName())) return new Float(Float.POSITIVE_INFINITY); + if ("NEGATIVE_INFINITY".equals(getName())) return new Float(Float.NEGATIVE_INFINITY); + if ("NaN".equals(getName())) return new Float(Float.NaN); + } else if ("java.lang.Double".equals(qName)) { + if ("POSITIVE_INFINITY".equals(getName())) return new Double(Double.POSITIVE_INFINITY); + if ("NEGATIVE_INFINITY".equals(getName())) return new Double(Double.NEGATIVE_INFINITY); + if ("NaN".equals(getName())) return new Double(Double.NaN); + } + + return PsiConstantEvaluationHelperImpl.computeCastTo(initializer, getType(), visitedVars); + } + + public boolean isDeprecated() { + synchronized (PsiLock.LOCK) { + if (myIsDeprecated == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + boolean isDeprecated = myParent.getClassFileData().findAttribute(myStartOffset + 6, "Deprecated") != null; + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + catch (ClsFormatException e) { + myIsDeprecated = Boolean.FALSE; + } + } + else { + boolean isDeprecated = getRepositoryManager().getFieldView().isDeprecated(repositoryId); + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + } + ; + } + return myIsDeprecated.booleanValue(); + } + + public PsiDocComment getDocComment() { + if (!isDeprecated()) return null; + + synchronized (PsiLock.LOCK) { + if (myDocComment == null) { + myDocComment = new ClsDocCommentImpl(this); + } + ; + } + return myDocComment; + } + + public void normalizeDeclaration() throws IncorrectOperationException { + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); + if (docComment != null){ + buffer.append(docComment.getMirrorText()); + } + buffer.append(((ClsElementImpl)getModifierList()).getMirrorText()); + buffer.append(' '); + buffer.append(((ClsElementImpl)getTypeElement()).getMirrorText()); + buffer.append(' '); + buffer.append(((ClsElementImpl)getNameIdentifier()).getMirrorText()); + if (getInitializer() != null){ + buffer.append("="); + buffer.append(getInitializer().getText()); + } + buffer.append(';'); + return buffer.toString(); + + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiField mirror = (PsiField)SourceTreeToPsiMap.treeElementToPsi(element); + if (getDocComment() != null){ + ((ClsElementImpl)getDocComment()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getDocComment())); + } + ((ClsElementImpl)getModifierList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getModifierList())); + ((ClsElementImpl)getTypeElement()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getTypeElement())); + ((ClsElementImpl)getNameIdentifier()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameIdentifier())); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitField(this); + } + + public String toString() { + return "PsiField:" + getName(); + } + + public PsiElement getNavigationElement() { + PsiClass sourceClassMirror = ((ClsClassImpl)getParent()).getSourceMirrorClass(); + PsiElement sourceFieldMirror = sourceClassMirror != null ? sourceClassMirror.findFieldByName(myName, false) : null; + return sourceFieldMirror != null ? sourceFieldMirror : this; + } + + public ClsAnnotationImpl[] getAnnotations() { + if (myAnnotations == null) { + ClsAnnotationsUtil.AttributeReader reader = new ClsAnnotationsUtil.AttributeReader() { + public BytePointer readAttribute(String attributeName) { + try { + return myParent.getClassFileData().findAttribute(myStartOffset + 6, attributeName); + } + catch (ClsFormatException e) { + return null; + } + } + + public ClassFileData getClassFileData() { + return myParent.getClassFileData(); + } + }; + myAnnotations = ClsAnnotationsUtil.getAnnotationsImpl(this, reader, myModifierList); + } + + return myAnnotations; } + + public PomField getPom() { + //TODO: + return null; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getFieldPresentation(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFileImpl.java new file mode 100644 index 00000000000..1d9e6d10a51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -0,0 +1,288 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiFileEx; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; + +public class ClsFileImpl extends ClsRepositoryPsiElement implements PsiJavaFile, PsiFileEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsFileImpl"); + + private final VirtualFile myFile; + private ClsClassImpl myClass = null; + private ClsPackageStatementImpl myPackageStatement = null; + private static final Key DOCUMENT_IN_MIRROR_KEY = Key.create("DOCUMENT_IN_MIRROR_KEY"); + private final boolean myIsForDecompiling; + + private ClsFileImpl(PsiManagerImpl manager, VirtualFile file, boolean forDecompiling) { + super(manager, -2); + myFile = file; + myIsForDecompiling = forDecompiling; + } + + public ClsFileImpl(PsiManagerImpl manager, VirtualFile file) { + this(manager, file, false); + } + + + public boolean isContentsLoaded() { + if (myClass == null) return false; + return myClass.isContentsLoaded(); + } + + public void unloadContent() { + if (myClass != null) { + myClass.invalidate(); + myClass = null; + } + if (myPackageStatement != null) { + myPackageStatement.invalidate(); + myPackageStatement = null; + } + myMirror = null; + } + + public long getRepositoryId() { + long id = super.getRepositoryId(); + if (id == -2) { + RepositoryManager repositoryManager = getRepositoryManager(); + if (repositoryManager != null) { + id = repositoryManager.getFileId(myFile); + } + else { + id = -1; + } + + super.setRepositoryId(id); + } + return id; + } + + public boolean isRepositoryIdInitialized() { + return super.getRepositoryId() != -2; + } + + public VirtualFile getVirtualFile() { + return myFile; + } + + public PsiElement getParent() { + return getContainingDirectory(); + } + + public PsiDirectory getContainingDirectory() { + VirtualFile parentFile = myFile.getParent(); + if (parentFile == null) return null; + return getManager().findDirectory(parentFile); + } + + public PsiFile getContainingFile() { + return this; + } + + public boolean isValid() { + if (myIsForDecompiling) return true; + VirtualFile vFile = getVirtualFile(); + return vFile.isValid() && myManager.findFile(vFile) == this; + } + + public String getName() { + return myFile.getName(); + } + + public PsiElement[] getChildren() { + return getClasses(); // TODO : package statement? + } + + public PsiClass[] getClasses() { + long id = getRepositoryId(); + if (myClass == null) { + if (id >= 0) { + long[] classIds = getRepositoryManager().getFileView().getClasses(id); + LOG.assertTrue(classIds.length == 1); + myClass = (ClsClassImpl)getRepositoryElementsManager().findOrCreatePsiElementById(classIds[0]); + } + else { + myClass = new ClsClassImpl(myManager, this, myFile); + } + } + return new PsiClass[]{myClass}; + } + + public PsiPackageStatement getPackageStatement() { + if (myPackageStatement == null) { + myPackageStatement = new ClsPackageStatementImpl(this); + } + return myPackageStatement.getPackageName() != null ? myPackageStatement : null; + } + + public String getPackageName() { + PsiPackageStatement statement = getPackageStatement(); + if (statement == null) { + return ""; + } + else { + return statement.getPackageName(); + } + } + + public PsiImportList getImportList() { + return null; + } + + public PsiElement[] getOnDemandImports(boolean includeImplicit, boolean checkIncludes) { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + public PsiClass[] getSingleClassImports(boolean checkIncludes) { + return PsiClass.EMPTY_ARRAY; + } + + public String[] getImplicitlyImportedPackages() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + public PsiJavaCodeReferenceElement[] getImplicitlyImportedPackageReferences() { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + public PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass) { + return null; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkSetName(String name) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + buffer.append("// IntelliJ API Decompiler stub source generated from a class file\n"); + buffer.append("// Implementation of methods is not available\n"); + buffer.append("\n"); + if (getPackageStatement() != null) { + buffer.append(((ClsElementImpl)getPackageStatement()).getMirrorText()); + } + PsiClass aClass = getClasses()[0]; + buffer.append(((ClsClassImpl)aClass).getMirrorText()); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiPackageStatement packageStatement = ((PsiJavaFile)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getPackageStatement(); + if (packageStatement != null) { + ((ClsElementImpl)getPackageStatement()).setMirror(SourceTreeToPsiMap.psiElementToTree(packageStatement)); + } + PsiClass[] classes = getClasses(); + PsiClass[] mirrorClasses = ((PsiJavaFile)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getClasses(); + LOG.assertTrue(classes.length == mirrorClasses.length); + if (classes.length == mirrorClasses.length) { + for (int i = 0; i < classes.length; i++) { + ((ClsElementImpl)classes[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(mirrorClasses[i])); + } + } + } + + public String getText() { + initializeMirror(); + return myMirror.getText(); + } + + public char[] textToCharArray() { + initializeMirror(); + return myMirror.textToCharArray(); + } + + private void initializeMirror() { + if (myMirror == null) { + try { + FileDocumentManager documentManager = FileDocumentManager.getInstance(); + Document document = documentManager.getDocument(getVirtualFile()); + String text = document.getText(); + String ext = StdFileTypes.JAVA.getDefaultExtension(); + PsiClass aClass = getClasses()[0]; + String fileName = aClass.getName() + "." + ext; + PsiManager manager = getManager(); + PsiFile mirror = manager.getElementFactory().createFileFromText(fileName, text); + TreeElement mirrorTreeElement = SourceTreeToPsiMap.psiElementToTree(mirror); + + //IMPORTANT: do not take lock too early - FileDocumentManager.getInstance().saveToString() can run write action... + synchronized (PsiLock.LOCK) { + if (myMirror == null) { + setMirror(mirrorTreeElement); + myMirror.putUserData(DOCUMENT_IN_MIRROR_KEY, document); + } + ; + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + public long getModificationStamp() { + return myFile.getModificationStamp(); + } + + public void setModificationStamp(long modificationStamp) { + if (modificationStamp == getModificationStamp()) return; + LOG.assertTrue(false); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitJavaFile(this); + } + + public String getDetectedLineSeparator() { + throw new UnsupportedOperationException(); + } + + public String toString() { + return "PsiFile:" + getName(); + } + + public PsiFile getOriginalFile() { + return null; + } + + public boolean canContainJavaCode() { + return true; + } + + public FileType getFileType() { + return StdFileTypes.CLASS; + } + + public PsiFile[] getPsiRoots() { + return new PsiFile[]{this}; + } + + public PsiFile createPseudoPhysicalCopy() { + LOG.assertTrue(false); + return null; + } + + public static String decompile(PsiManager manager, VirtualFile file) { + final ClsFileImpl psiFile = new ClsFileImpl((PsiManagerImpl)manager, file, true); + final String text = psiFile.getMirrorText(); + return text; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java new file mode 100644 index 00000000000..1a3ccea472d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java @@ -0,0 +1,53 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.tree.IElementType; + +class ClsIdentifierImpl extends ClsElementImpl implements PsiIdentifier, PsiJavaToken { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsIdentifierImpl"); + + private final PsiElement myParent; + private final String myText; + + public ClsIdentifierImpl(PsiElement parent, String text) { + myParent = parent; + myText = text; + } + + public IElementType getTokenType() { + return JavaTokenType.IDENTIFIER; + } + + public String getText() { + return myText; + } + + public PsiElement[] getChildren(){ + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent(){ + return myParent; + } + + public String getMirrorText(){ + return getText(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.IDENTIFIER); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitIdentifier(this); + } + + public String toString() { + return "PsiIdentifier:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java new file mode 100644 index 00000000000..f68120921c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java @@ -0,0 +1,301 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.impl.PsiSubstitutorImpl; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.containers.HashMap; + +import java.text.CharacterIterator; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements PsiJavaCodeReferenceElement { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl"); + + private PsiElement myParent; + private final String myCanonicalText; + private final String myQualifiedName; + private ClsReferenceParametersListImpl myTypeParameterList = null; + private final ClsTypeElementImpl[] myTypeParameters; // in right-to-left order + private PsiType[] myTypeParametersCachedTypes = null; // in left-to-right-order + private static final String EXTENDS_PREFIX = "?extends"; + private static final String SUPER_PREFIX = "?super"; + + public ClsJavaCodeReferenceElementImpl(PsiElement parent, String canonicalText) { + myParent = parent; + + myCanonicalText = canonicalText; + final String[] classParametersText = PsiNameHelper.getClassParametersText(canonicalText); + myTypeParameters = new ClsTypeElementImpl[classParametersText.length]; + for (int i = 0; i < classParametersText.length; i++) { + String s = classParametersText[classParametersText.length - i - 1]; + char variance = ClsTypeElementImpl.VARIANCE_NONE; + if (s.startsWith(EXTENDS_PREFIX)) { + variance = ClsTypeElementImpl.VARIANCE_EXTENDS; + s = s.substring(EXTENDS_PREFIX.length()); + } + else if (s.startsWith(SUPER_PREFIX)) { + variance = ClsTypeElementImpl.VARIANCE_SUPER; + s = s.substring(SUPER_PREFIX.length()); + } + else if (StringUtil.startsWithChar(s, '?')) { + variance = ClsTypeElementImpl.VARIANCE_INVARIANT; + s = s.substring(1); + } + + myTypeParameters[i] = new ClsTypeElementImpl(this, s, variance); + } + + myQualifiedName = PsiNameHelper.getQualifiedClassName(myCanonicalText, false); + } + + public ClsJavaCodeReferenceElementImpl(PsiElement psiParent, CharacterIterator signature) throws ClsFormatException { + myParent = psiParent; + StringBuffer canonicalText = new StringBuffer(); + LOG.assertTrue(signature.current() == 'L'); + signature.next(); + ArrayList typeParameters = new ArrayList(); + while (signature.current() != ';' && signature.current() != CharacterIterator.DONE) { + switch (signature.current()) { + case '$': + case '/': + case '.': + canonicalText.append('.'); + break; + case '<': + canonicalText.append('<'); + signature.next(); + do { + processTypeArgument(signature, typeParameters, canonicalText); + } + while (signature.current() != '>'); + canonicalText.append('>'); + break; + case ' ': + break; + default: + canonicalText.append(signature.current()); + } + signature.next(); + } + + if (signature.current() == CharacterIterator.DONE) { + throw new ClsFormatException(); + } + + for(int index = 0; index < canonicalText.length(); index++) { + final char c = canonicalText.charAt(index); + if ('0' <= c && c <= '1') { + if (index > 0 && canonicalText.charAt(index-1) == '.') { + canonicalText.setCharAt(index-1, '$'); + } + } + } + myCanonicalText = canonicalText.toString(); + final int nParams = typeParameters.size(); + myTypeParameters = new ClsTypeElementImpl[nParams]; + for (int i = nParams - 1; i >= 0; i--) { + myTypeParameters[nParams - i - 1] = typeParameters.get(i); + } + myQualifiedName = PsiNameHelper.getQualifiedClassName(myCanonicalText, false); + + signature.next(); + } + + private void processTypeArgument(CharacterIterator signature, ArrayList typeParameters, StringBuffer canonicalText) + throws ClsFormatException { + ClsTypeElementImpl typeArgument = GenericSignatureParsing.parseClassOrTypeVariableElement(signature, this); + typeParameters.add(typeArgument); + canonicalText.append(typeArgument.getCanonicalText()); + if (signature.current() != '>') { + canonicalText.append(','); + } + } + + + void setParent(PsiElement parent) { + myParent = parent; + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return myParent; + } + + public String getText() { + return PsiNameHelper.getPresentableText(this); + } + + public int getTextLength() { + return getText().length(); + } + + public PsiReference getReference() { + return this; + } + + public String getCanonicalText() { + return myCanonicalText; + } + + public ResolveResult advancedResolve(boolean incompleteCode) { + final PsiElement resolve = resolve(); + if (resolve instanceof PsiClass) { + final Map substitutionMap = new HashMap(); + final Iterator it = PsiUtil.typeParametersIterator((PsiClass)resolve); + int index = 0; + while (it.hasNext()) { + PsiTypeParameter parameter = it.next(); + if (index >= myTypeParameters.length) { + substitutionMap.put(parameter, null); + } + else { + substitutionMap.put(parameter, myTypeParameters[index].getType()); + } + index++; + } + return new CandidateInfo(resolve, PsiSubstitutorImpl.createSubstitutor(substitutionMap)); + } + else { + return new CandidateInfo(resolve, PsiSubstitutor.EMPTY); + } + } + + public ResolveResult[] multiResolve(boolean incompleteCode) { + final ResolveResult result = advancedResolve(incompleteCode); + if (result != ResolveResult.EMPTY) return new ResolveResult[]{result}; + return ResolveResult.EMPTY_ARRAY; + } + + public PsiElement resolve() { + PsiElement element = getParent(); + while(!(element instanceof PsiClass) || element instanceof PsiTypeParameter){ + if(element instanceof PsiMethod){ + final PsiMethod method = (PsiMethod)element; + final PsiTypeParameterList list = method.getTypeParameterList(); + if (list != null) { + final PsiTypeParameter[] parameters = list.getTypeParameters(); + for (int i = 0; parameters != null && i < parameters.length; i++) { + final PsiTypeParameter parameter = parameters[i]; + if (parameter.getName().equals(myQualifiedName)) return parameter; + } + } + } + element = element.getParent(); + } + + Iterator it = PsiUtil.typeParametersIterator((PsiClass)element); + while (it.hasNext()) { + PsiTypeParameter parameter = it.next(); + if (parameter.getName().equals(myQualifiedName)) return parameter; + } + return getManager().findClass(myQualifiedName, GlobalSearchScope.allScope(getProject())); + } + + public void processVariants(PsiScopeProcessor processor) { + throw new RuntimeException("Variants are not available for light references"); + } + + public PsiElement getReferenceNameElement() { + return null; + } + + public PsiReferenceParameterList getParameterList() { + return myTypeParameterList; + } + + public String getQualifiedName() { + return getCanonicalText(); + } + + public String getReferenceName() { + return PsiNameHelper.getShortClassName(myCanonicalText); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof PsiClass)) return false; + PsiClass aClass = (PsiClass)element; + return myCanonicalText.equals(aClass.getQualifiedName()); + } + + public Object[] getVariants() { + throw new RuntimeException("Variants are not available for references to compiled code"); + } + + public boolean isSoft() { + return false; + } + + public String getMirrorText() { + return getCanonicalText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.JAVA_CODE_REFERENCE); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceElement(this); + } + + public String toString() { + return "PsiJavaCodeReferenceElement:" + getText(); + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public PsiElement getElement() { + return this; + } + + ClsTypeElementImpl[] getTypeElements() { + return myTypeParameters; + } + + public PsiType[] getTypeParameters() { + if (myTypeParametersCachedTypes == null) { + myTypeParametersCachedTypes = new PsiType[myTypeParameters.length]; + for (int i = 0; i < myTypeParametersCachedTypes.length; i++) { + myTypeParametersCachedTypes[myTypeParametersCachedTypes.length - i - 1] = myTypeParameters[i].getType(); + } + } + + return myTypeParametersCachedTypes; + } + + public boolean isQualified() { + return false; + } + + public PsiElement getQualifier() { + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java new file mode 100644 index 00000000000..5a5e79a5dc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java @@ -0,0 +1,71 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiLiteralExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ClsLiteralExpressionImpl extends ClsElementImpl implements PsiLiteralExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsLiteralExpressionImpl"); + + private ClsElementImpl myParent; + private final String myText; + private final PsiType myType; + private final Object myValue; + + public ClsLiteralExpressionImpl(ClsElementImpl parent, String text, PsiType type, Object value) { + myParent = parent; + myText = text; + myType = type; + myValue = value; + } + + void setParent(ClsElementImpl parent) { + myParent = parent; + } + + public PsiType getType() { + return myType; + } + + public Object getValue() { + return myValue; + } + + public String getText() { + return myText; + } + + public String getParsingError() { + return null; + } + + public String getMirrorText() { + return getText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.LITERAL_EXPRESSION); + myMirror = element; + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return myParent; + } + + public String toString() { + return "PsiLiteralExpression:" + getText(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitLiteralExpression(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsMethodImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsMethodImpl.java new file mode 100644 index 00000000000..9f2e5079f25 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsMethodImpl.java @@ -0,0 +1,829 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.PomMethod; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiSuperMethodImplUtil; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.cache.MethodView; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.BytePointer; +import com.intellij.util.cls.ClsFormatException; +import com.intellij.util.cls.ClsUtil; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.ArrayList; +import java.util.List; + +public class ClsMethodImpl extends ClsRepositoryPsiElement implements PsiAnnotationMethod, ClsModifierListOwner { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsMethodImpl"); + + private ClsClassImpl myParent; + private int myStartOffset; + + private String myName = null; + private PsiIdentifier myNameIdentifier = null; + private boolean myConstructorFlag; + private Boolean myIsVarArgs = null; + private PsiTypeElement myReturnType = null; + private ClsModifierListImpl myModifierList = null; + private PsiParameterList myParameterList = null; + private PsiReferenceList myThrowsList = null; + private PsiDocComment myDocComment = null; + private Boolean myIsDeprecated = null; + private PsiTypeParameterList myTypeParameters = null; + private PsiAnnotationMemberValue[] myDefaultValue = null; + private ClsAnnotationImpl[] myAnnotations = null; + private ClsAnnotationImpl[][] myParameterAnnotations = null; + + public ClsMethodImpl(ClsClassImpl parent, int startOffset) { + super(parent.myManager, -1); + myParent = parent; + myStartOffset = startOffset; + } + + public ClsMethodImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + myParent = null; + myStartOffset = -1; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + if (repositoryId >= 0) { + myStartOffset = -1; + } + } + + public PsiElement[] getChildren() { + PsiDocComment docComment = getDocComment(); + PsiModifierList modifierList = getModifierList(); + PsiTypeElement returnType = getReturnTypeElement(); + PsiIdentifier name = getNameIdentifier(); + PsiReferenceList throwsList = getThrowsList(); + PsiAnnotationMemberValue defaultValue = getDefaultValue(); + + int count = + (docComment != null ? 1 : 0) + + (modifierList != null ? 1 : 0) + + (returnType != null ? 1 : 0) + + (name != null ? 1 : 0) + + (throwsList != null ? 1 : 0) + + (defaultValue != null ? 1 : 0);; + PsiElement[] children = new PsiElement[count]; + + int offset = 0; + if (docComment != null) { + children[offset++] = docComment; + } + if (modifierList != null) { + children[offset++] = modifierList; + } + if (returnType != null) { + children[offset++] = returnType; + } + if (name != null) { + children[offset++] = name; + } + if (throwsList != null) { + children[offset++] = throwsList; + } + if (defaultValue != null) { + children[offset++] = defaultValue; + } + + return children; + } + + public PsiElement getParent() { + final long parentId = getParentId(); + if(parentId < 0) return myParent; + return getRepositoryElementsManager().findOrCreatePsiElementById(parentId); + } + + public PsiClass getContainingClass() { + return (PsiClass)getParent(); + } + + public PsiIdentifier getNameIdentifier() { + synchronized (PsiLock.LOCK) { + if (myNameIdentifier == null) { + myNameIdentifier = new ClsIdentifierImpl(this, getName()); + } + ; + } + return myNameIdentifier; + } + + public PsiMethod[] findSuperMethods() { + return PsiSuperMethodImplUtil.findSuperMethods(this); + } + + public PsiMethod[] findSuperMethods(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); + } + + public PsiMethod[] findSuperMethods(PsiClass parentClass) { + return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); + } + + public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); + } + + public PsiMethod findConstructorInSuper() { + return PsiSuperMethodImplUtil.findConstructorInSuper(this); + } + + public PsiMethod findDeepestSuperMethod() { + return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); + } + + public PomMethod getPom() { + //TODO: + return null; + } + + public String getName() { + if (myName == null) { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + byte[] data = classFileData.getData(); + int offset = myStartOffset + 2; + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + offset = classFileData.getOffsetInConstantPool(index); + String name = ClsUtil.readUtf8Info(data, offset); + if (name.equals("")) { + name = myParent.getName(); + myConstructorFlag = true; + } + else { + myConstructorFlag = false; + } + myName = name; + } + catch (ClsFormatException e) { + myName = ""; + } + } + else { + MethodView methodView = getRepositoryManager().getMethodView(); + myName = methodView.getName(repositoryId); + myConstructorFlag = methodView.getReturnTypeText(repositoryId) == null; + } + ; + } + } + return myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiTypeElement getReturnTypeElement() { + if (isConstructor()) return null; + + synchronized (PsiLock.LOCK) { + if (myReturnType == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + if (!parseViaGenericSignature()) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + byte[] data = classFileData.getData(); + int offset = myStartOffset + 4; + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + offset = classFileData.getOffsetInConstantPool(index); + offset += 3; // skip tag and length + while (true) { + if (offset >= data.length) { + throw new ClsFormatException(); + } + if (data[offset++] == ')') break; + } + String typeText = ClsUtil.getTypeText(data, offset); + myReturnType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE); + } + catch (ClsFormatException e) { + myReturnType = null; + } + } + } + else { + String typeText = getRepositoryManager().getMethodView().getReturnTypeText(repositoryId); + myReturnType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE); + } + } + ; + } + return myReturnType; + } + + public PsiType getReturnType() { + PsiTypeElement typeElement = getReturnTypeElement(); + return typeElement == null ? null : typeElement.getType(); + } + + public PsiModifierList getModifierList() { + synchronized (PsiLock.LOCK) { + if (myModifierList == null) { + int flags = getAccessFlags(); + myModifierList = new ClsModifierListImpl(this, flags & ClsUtil.ACC_METHOD_MASK); + } + ; + } + return myModifierList; + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + private int getAccessFlags() { + synchronized (PsiLock.LOCK) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + int offset = myStartOffset; + byte[] data = myParent.getClassFileData().getData(); + if (offset + 2 > data.length) { + throw new ClsFormatException(); + } + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + return (b1 << 8) + b2; + } + catch (ClsFormatException e) { + return 0; + } + } + else { + MethodView methodView = getRepositoryManager().getMethodView(); + return methodView.getModifiers(repositoryId); + } + } + } + + boolean isBridge () throws ClsFormatException { + return ClsUtil.isBridge(getAccessFlags()) || + //This is 2.2 spec rudiment; TODO remove it + myParent.getClassFileData().findAttribute(myStartOffset + 6, "Bridge") != null; + } + + public PsiParameterList getParameterList() { + synchronized (PsiLock.LOCK) { + if (myParameterList == null && !parseViaGenericSignature()) { + myParameterList = createParameters(calcParameterTypes()); + } + } + + return myParameterList; + } + + private PsiParameterList createParameters(ArrayList types) { + ClsParameterImpl[] parameters = types != null ? new ClsParameterImpl[types.size()] : ClsParameterImpl.EMPTY_ARRAY; + ClsParameterListImpl parameterList = new ClsParameterListImpl(this, parameters); + for (int i = 0; i < parameters.length; i++) { + String typeText = types.get(i); + ClsTypeElementImpl type = new ClsTypeElementImpl(null, typeText, ClsTypeElementImpl.VARIANCE_NONE); + parameters[i] = new ClsParameterImpl(parameterList, type, i); + type.setParent(parameters[i]); + } + + return parameterList; + } + + private ClsAnnotationImpl[][] calcParameterAnnotations () { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + ClassFileData classFileData = myParent.getClassFileData(); + try { + BytePointer pointer1 = classFileData.findAttribute(myStartOffset + 6, "RuntimeVisibleParameterAnnotations"); + ClsParameterImpl[] parameters = (ClsParameterImpl[])myParameterList.getParameters(); + if (pointer1 != null) { + ClsAnnotationImpl[][] ann1 = readParameterAnnotations(pointer1, parameters); + BytePointer pointer2 = classFileData.findAttribute(myStartOffset + 6, "RuntimeInvisibleParameterAnnotations"); + if (pointer2 != null) { + ClsAnnotationImpl[][] ann2 = readParameterAnnotations(pointer2, parameters); + ClsAnnotationImpl[][] result = ArrayUtil.mergeArrays(ann1, ann2, ClsAnnotationImpl[].class); + return result; + } + else { + return ann1; + } + } + else { + BytePointer pointer2 = classFileData.findAttribute(myStartOffset + 6, "RuntimeInvisibleParameterAnnotations"); + if (pointer2 != null) { + return readParameterAnnotations(pointer2, parameters); + } + else { + return new ClsAnnotationImpl[0][]; + } + } + } + catch (ClsFormatException e) { + return new ClsAnnotationImpl[0][]; + } + } else { + MethodView methodView = getRepositoryManager().getMethodView(); + + String[][] parameterAnnotations = methodView.getParameterAnnotations(repositoryId); + ClsAnnotationImpl[][] result = new ClsAnnotationImpl[parameterAnnotations.length][]; + for (int i = 0; i < parameterAnnotations.length; i++) { + String[] annotations = parameterAnnotations[i]; + ClsParameterImpl parameter = (ClsParameterImpl)myParameterList.getParameters()[i]; + result[i] = new ClsAnnotationImpl[annotations.length]; + for (int j = 0; j < annotations.length; j++) { + result[i][j] = (ClsAnnotationImpl)ClsAnnotationsUtil.createMemberValueFromText(annotations[j], myManager, (ClsElementImpl)parameter.getModifierList()); + } + } + + return result; + } + } + + private ClsAnnotationImpl[][] readParameterAnnotations(BytePointer pointer, ClsParameterImpl[] parameters) throws ClsFormatException { + pointer.offset += 4; + int numParameters = ClsUtil.readU1(pointer); + ClsAnnotationImpl[][] result = new ClsAnnotationImpl[numParameters][]; + for (int i = 0; i < numParameters; i++) { + result[i] = myParent.getClassFileData().readAnnotations(parameters[i], pointer); + } + + return result; + } + + private ArrayList calcParameterTypes() { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + byte[] data = classFileData.getData(); + int offset = myStartOffset + 4; + int b1 = data[offset++] & 0xFF; + int b2 = data[offset++] & 0xFF; + int index = (b1 << 8) + b2; + offset = classFileData.getOffsetInConstantPool(index); + offset += 3; // skip tag and length + if (offset + 1 >= data.length) { + throw new ClsFormatException(); + } + if (data[offset++] != '(') { + throw new ClsFormatException(); + } + + ArrayList types = null; + if (myConstructorFlag && myParent.getParent() instanceof PsiClass && + !myParent.getModifierList().hasModifierProperty(PsiModifier.STATIC)) { + //Then there is presumably a synthetic field in the class, that is instantiated in the constructor + //Skip the first parameter + // there is Sun generic compiler bug here, happens to throw... + if (data[offset] == ')') { + throw new ClsFormatException(); + } + offset = ClsUtil.getTypeEndOffset(data, offset); + if (offset >= data.length) { + throw new ClsFormatException(); + } + } + + while (data[offset] != ')') { + String typeText = ClsUtil.getTypeText(data, offset); + offset = ClsUtil.getTypeEndOffset(data, offset); + if (offset >= data.length) { + throw new ClsFormatException(); + } + if (types == null) { + types = new ArrayList(); + } + types.add(typeText); + } + + if (types != null) { + patchVarargs(types); + } + return types; + } + catch (ClsFormatException e) { + return new ArrayList(); + } + } + else { + MethodView methodView = getRepositoryManager().getMethodView(); + int count = methodView.getParameterCount(repositoryId); + if (count == 0) return null; + ArrayList types = new ArrayList(count); + for (int i = 0; i < count; i++) { + String text = methodView.getParameterTypeText(repositoryId, i); + types.add(text); + } + return types; + } + } + + private void patchVarargs(ArrayList types) { + if (isVarArgs()) { + String lastParamTypeText = types.get(types.size() - 1); + LOG.assertTrue(lastParamTypeText.endsWith("[]")); + lastParamTypeText = lastParamTypeText.substring(0 ,lastParamTypeText.length() - 2) + "..."; + types.set(types.size() - 1, lastParamTypeText); + } + } + + public PsiReferenceList getThrowsList() { + synchronized (PsiLock.LOCK) { + if (myThrowsList == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + parseViaGenericSignature(); + if (myThrowsList == null) { + try { + ClassFileData classFileData = myParent.getClassFileData(); + BytePointer ptr = classFileData.findAttribute(myStartOffset + 6, "Exceptions"); + if (ptr != null) { + ptr.offset += 4; // skip length + int exceptionCount = ClsUtil.readU2(ptr); + ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[exceptionCount]; + int jj = 0; + for (int j = 0; j < exceptionCount; j++) { + int index = ClsUtil.readU2(ptr); + if (index != 0) { + refs[jj++] = classFileData.buildReference(index); + } + } + if (jj < exceptionCount) { + ClsJavaCodeReferenceElementImpl[] refs1 = new ClsJavaCodeReferenceElementImpl[jj]; + System.arraycopy(refs, 0, refs1, 0, jj); + refs = refs1; + } + + myThrowsList = new ClsReferenceListImpl(this, refs, PsiKeyword.THROWS); + for (int j = 0; j < refs.length; j++) { + refs[j].setParent(myThrowsList); + } + } + } + catch (ClsFormatException e) { + } + if (myThrowsList == null) { + myThrowsList = new ClsReferenceListImpl(this, new ClsJavaCodeReferenceElementImpl[0], PsiKeyword.THROWS); + } + } + } + else { + MethodView methodView = getRepositoryManager().getMethodView(); + String[] refTexts = methodView.getThrowsList(repositoryId); + ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[refTexts.length]; + for (int i = 0; i < refTexts.length; i++) { + refs[i] = new ClsJavaCodeReferenceElementImpl(null, refTexts[i]); + } + myThrowsList = new ClsReferenceListImpl(this, refs, PsiKeyword.THROWS); + for (int i = 0; i < refs.length; i++) { + ClsJavaCodeReferenceElementImpl ref = refs[i]; + ref.setParent(myThrowsList); + } + } + } + ; + } + return myThrowsList; + } + + public PsiCodeBlock getBody() { + return null; + } + + public boolean isDeprecated() { + synchronized (PsiLock.LOCK) { + if (myIsDeprecated == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + try { + boolean isDeprecated = myParent.getClassFileData().findAttribute(myStartOffset + 6, "Deprecated") != null; + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + catch (ClsFormatException e) { + myIsDeprecated = Boolean.FALSE; + } + } + else { + boolean isDeprecated = getRepositoryManager().getMethodView().isDeprecated(repositoryId); + myIsDeprecated = isDeprecated ? Boolean.TRUE : Boolean.FALSE; + } + } + ; + } + return myIsDeprecated.booleanValue(); + } + + ClassFileData getClassFileData () { + return myParent.getClassFileData(); + } + + public PsiAnnotationMemberValue getDefaultValue () { + if (myDefaultValue == null) { + myDefaultValue = new PsiAnnotationMemberValue[1]; + + if (getRepositoryId() < 0) { + if (myParent != null && myParent.isAnnotationType()) { + try { + BytePointer ptr = myParent.getClassFileData().findAttribute(myStartOffset + 6, "AnnotationDefault"); + if (ptr != null) { + ptr.offset += 4; + myDefaultValue[0] = myParent.getClassFileData().readMemberValue(ptr, this); + } + } + catch (ClsFormatException e) { + } + } + } + else { + RepositoryManager repositoryManager = getRepositoryManager(); + if (repositoryManager.getClassView().isAnnotationType(getParentId())) { + String defaultValueText = repositoryManager.getMethodView().getDefaultValueText(getRepositoryId()); + if (defaultValueText != null && defaultValueText.length() > 0) { + myDefaultValue[0] = ClsAnnotationsUtil.createMemberValueFromText(defaultValueText, myManager, this); + } + } + } + } + + return myDefaultValue[0]; + } + + private boolean parseViaGenericSignature() { + if (getRepositoryId() >= 0) return false; + try { + String signature = getSignatureAttribute(); + if (signature == null) return false; + + CharacterIterator iterator = new StringCharacterIterator(signature, 0); + myTypeParameters = GenericSignatureParsing.parseTypeParametersDeclaration(iterator, this, signature); + + if (iterator.current() != '(') return false; + iterator.next(); + ArrayList types = new ArrayList(); + while (iterator.current() != ')') { + types.add(GenericSignatureParsing.parseTypeString(iterator)); + } + patchVarargs(types); + myParameterList = createParameters(types); + + iterator.next(); + myReturnType = new ClsTypeElementImpl(this, GenericSignatureParsing.parseTypeString(iterator), ClsTypeElementImpl.VARIANCE_NONE); + + if (iterator.current() == '^') { + iterator.next(); + myThrowsList = new ClsReferenceListImpl(this, "throws"); + PsiJavaCodeReferenceElement[] refs = GenericSignatureParsing.parseToplevelClassRefSignatures(iterator, myThrowsList); + ((ClsReferenceListImpl)myThrowsList).setReferences(refs); + } + + return true; + } + catch (ClsFormatException e) { + return false; + } + } + + public String getSignatureAttribute() { + try { + ClassFileData data = myParent.getClassFileData(); + return data.readUtf8Attribute(data.findAttribute(myStartOffset + 6, "Signature")); + } + catch (ClsFormatException e) { + return null; + } + } + + public PsiDocComment getDocComment() { + if (!isDeprecated()) return null; + + synchronized (PsiLock.LOCK) { + if (myDocComment == null) { + myDocComment = new ClsDocCommentImpl(this); + } + ; + } + return myDocComment; + } + + + public boolean isConstructor() { + getName(); // to initialize myConstructorFlag + return myConstructorFlag; + } + + public boolean isVarArgs() { + if (myIsVarArgs == null) { + boolean isVarArgs; + if (getRepositoryId() < 0) { + isVarArgs = (getAccessFlags() & ClsUtil.ACC_VARARGS) != 0; + } else { + RepositoryManager repositoryManager = getRepositoryManager(); + isVarArgs = repositoryManager.getMethodView().isVarArgs(getRepositoryId()); + } + + myIsVarArgs = isVarArgs ? Boolean.TRUE : Boolean.FALSE; + } + + return myIsVarArgs.booleanValue(); + } + + public MethodSignature getSignature(PsiSubstitutor substitutor) { + return PsiImplUtil.getMethodSignature(this, substitutor); + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + appendMethodHeader(buffer); + + if (hasModifierProperty(PsiModifier.ABSTRACT) || hasModifierProperty(PsiModifier.NATIVE)) { + buffer.append(";"); + } + else { + buffer.append("{ /* compiled code */ }\n"); + } + return buffer.toString(); + } + + private void appendMethodHeader(StringBuffer buffer) { + ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); + if (docComment != null) { + buffer.append(docComment.getMirrorText()); + } + buffer.append(((ClsElementImpl)getModifierList()).getMirrorText()); + buffer.append(' '); + buffer.append(((ClsElementImpl)getTypeParameterList()).getMirrorText()); + if (!isConstructor()) { + buffer.append(' '); + buffer.append(((ClsElementImpl)getReturnTypeElement()).getMirrorText()); + } + buffer.append(' '); + buffer.append(((ClsElementImpl)getNameIdentifier()).getMirrorText()); + buffer.append(((ClsElementImpl)getParameterList()).getMirrorText()); + buffer.append(((ClsElementImpl)getThrowsList()).getMirrorText()); + + PsiAnnotationMemberValue defaultValue = getDefaultValue(); + if (defaultValue != null) { + buffer.append(" default "); + buffer.append(((ClsElementImpl)defaultValue).getMirrorText()); + } + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiMethod mirror = (PsiMethod)SourceTreeToPsiMap.treeElementToPsi(element); + if (getDocComment() != null) { + ((ClsElementImpl)getDocComment()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getDocComment())); + } + ((ClsElementImpl)getModifierList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getModifierList())); + if (!isConstructor() && mirror.getReturnTypeElement() != null) { + ((ClsElementImpl)getReturnTypeElement()).setMirror( + SourceTreeToPsiMap.psiElementToTree(mirror.getReturnTypeElement())); + } + ((ClsElementImpl)getNameIdentifier()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameIdentifier())); + ((ClsElementImpl)getParameterList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getParameterList())); + ((ClsElementImpl)getThrowsList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getThrowsList())); + ((ClsElementImpl)getTypeParameterList()).setMirror( + SourceTreeToPsiMap.psiElementToTree(mirror.getTypeParameterList())); + if (getDefaultValue() != null) { + LOG.assertTrue(mirror instanceof PsiAnnotationMethod); + ((ClsElementImpl)getDefaultValue()).setMirror(SourceTreeToPsiMap.psiElementToTree(((PsiAnnotationMethod)mirror).getDefaultValue())); + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitMethod(this); + } + + public String toString() { + return "PsiMethod:" + getName(); + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null) return true; + + if (!PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place)) return false; + + final PsiParameter[] parameters = getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (!processor.execute(parameters[i], substitutor)) return false; + } + + return true; + } + + public PsiElement getNavigationElement() { + PsiClass sourceClassMirror = ((ClsClassImpl)getParent()).getSourceMirrorClass(); + PsiMethod sourceMethodMirror = sourceClassMirror != null + ? sourceClassMirror.findMethodBySignature(this, false) + : null; + return sourceMethodMirror != null ? sourceMethodMirror : this; + } + + public PsiTypeParameterList getTypeParameterList() { + synchronized (PsiLock.LOCK) { + if (myTypeParameters == null) { + long repositoryId = getRepositoryId(); + if (repositoryId < 0) { + if (!parseViaGenericSignature()) { + myTypeParameters = new ClsTypeParametersListImpl(this, new ClsTypeParameterImpl[0]); + } + } + else { + MethodView methodView = getRepositoryManager().getMethodView(); + int count = methodView.getTypeParametersCount(repositoryId); + if (count == 0) { + myTypeParameters = new ClsTypeParametersListImpl(this, new ClsTypeParameterImpl[0]); + } + else { + StringBuffer compiledParams = new StringBuffer(); + compiledParams.append('<'); + for (int i = 0; i < count; i++) { + compiledParams.append(methodView.getTypeParameterText(repositoryId, i)); + } + compiledParams.append('>'); + try { + final String signature = compiledParams.toString(); + myTypeParameters = + GenericSignatureParsing.parseTypeParametersDeclaration(new StringCharacterIterator(signature, 0), this, signature); + } + catch (ClsFormatException e) { + LOG.error(e); // dsl: should not happen when stuff is parsed from repository + } + } + } + } + return myTypeParameters; + } + } + + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); + } + + public ClsAnnotationImpl[] getAnnotations() { + if (myAnnotations == null) { + ClsAnnotationsUtil.AttributeReader reader = new ClsAnnotationsUtil.AttributeReader() { + public BytePointer readAttribute(String attributeName) { + try { + return myParent.getClassFileData().findAttribute(myStartOffset + 6, attributeName); + } + catch (ClsFormatException e) { + return null; + } + } + + public ClassFileData getClassFileData() { + return myParent.getClassFileData(); + } + }; + myAnnotations = ClsAnnotationsUtil.getAnnotationsImpl(this, reader, myModifierList); + } + + return myAnnotations; + } + + public ClsAnnotationImpl[] getParameterAnntations(int paramIdx) { + if (myParameterAnnotations == null) { + myParameterAnnotations = calcParameterAnnotations(); + } + return paramIdx >= myParameterAnnotations.length ? ClsAnnotationImpl.EMPTY_ARRAY : myParameterAnnotations[paramIdx]; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getMethodPresentation(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListImpl.java new file mode 100644 index 00000000000..2b19dc3f630 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListImpl.java @@ -0,0 +1,161 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.ClsUtil; +import com.intellij.util.containers.HashMap; + +public class ClsModifierListImpl extends ClsElementImpl implements PsiModifierList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsModifierListImpl"); + + private static final HashMap ourModifierNameToFlagMap = new HashMap(); + static{ + ourModifierNameToFlagMap.put(PsiModifier.PUBLIC, new Integer(ClsUtil.ACC_PUBLIC)); + ourModifierNameToFlagMap.put(PsiModifier.PROTECTED, new Integer(ClsUtil.ACC_PROTECTED)); + ourModifierNameToFlagMap.put(PsiModifier.PRIVATE, new Integer(ClsUtil.ACC_PRIVATE)); + ourModifierNameToFlagMap.put(PsiModifier.STATIC, new Integer(ClsUtil.ACC_STATIC)); + ourModifierNameToFlagMap.put(PsiModifier.ABSTRACT, new Integer(ClsUtil.ACC_ABSTRACT)); + ourModifierNameToFlagMap.put(PsiModifier.FINAL, new Integer(ClsUtil.ACC_FINAL)); + ourModifierNameToFlagMap.put(PsiModifier.NATIVE, new Integer(ClsUtil.ACC_NATIVE)); + ourModifierNameToFlagMap.put(PsiModifier.SYNCHRONIZED, new Integer(ClsUtil.ACC_SYNCHRONIZED)); + ourModifierNameToFlagMap.put(PsiModifier.TRANSIENT, new Integer(ClsUtil.ACC_TRANSIENT)); + ourModifierNameToFlagMap.put(PsiModifier.VOLATILE, new Integer(ClsUtil.ACC_VOLATILE)); + } + + private final ClsModifierListOwner myParent; + private ClsAnnotationImpl[] myAnnotations = null; + private final int myFlags; + + public ClsModifierListImpl(ClsModifierListOwner parent, int flags){ + myParent = parent; + myFlags = flags; + } + + public PsiElement[] getChildren(){ + return getAnnotations(); + } + + public PsiElement getParent(){ + return myParent; + } + + public boolean hasModifierProperty(String name){ + Integer flag = ourModifierNameToFlagMap.get(name); + if (flag == null){ + if (PsiModifier.PACKAGE_LOCAL.equals(name)){ + return (myFlags & (ClsUtil.ACC_PUBLIC | ClsUtil.ACC_PROTECTED | ClsUtil.ACC_PRIVATE)) == 0; + } + return false; + } + return (myFlags & flag.intValue()) != 0; + } + + public void setModifierProperty(String name, boolean value) throws IncorrectOperationException{ + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public void checkSetModifierProperty(String name, boolean value) throws IncorrectOperationException{ + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiAnnotation[] getAnnotations() { + if (myAnnotations == null) { + myAnnotations = myParent.getAnnotations(); + } + return myAnnotations; + } + + public PsiAnnotation findAnnotation(String qualifiedName) { + return PsiImplUtil.findAnnotation(this, qualifiedName); + } + + public String getMirrorText(){ + StringBuffer buffer = new StringBuffer(); + PsiAnnotation[] annotations = getAnnotations(); + for (int i = 0; i < annotations.length; i++) { + PsiAnnotation annotation = annotations[i]; + buffer.append(((ClsAnnotationImpl)annotation).getMirrorText()); + buffer.append(" "); + } + + //TODO : filtering & ordering modifiers can go to CodeStyleManager + boolean isInterface = myParent instanceof PsiClass && ((PsiClass)myParent).isInterface(); + boolean isInterfaceMethod = myParent instanceof PsiMethod && ((PsiClass)myParent.getParent()).isInterface(); + boolean isInterfaceField = myParent instanceof PsiField && ((PsiClass)myParent.getParent()).isInterface(); + boolean isInterfaceClass = myParent instanceof PsiClass && myParent.getParent() instanceof PsiClass && ((PsiClass)myParent.getParent()).isInterface(); + if (hasModifierProperty(PsiModifier.PUBLIC)){ + if (!isInterfaceMethod && !isInterfaceField && !isInterfaceClass){ + buffer.append(PsiModifier.PUBLIC); + buffer.append(' '); + } + } + if (hasModifierProperty(PsiModifier.PROTECTED)){ + buffer.append(PsiModifier.PROTECTED); + buffer.append(' '); + } + if (hasModifierProperty(PsiModifier.PRIVATE)){ + buffer.append(PsiModifier.PRIVATE); + buffer.append(' '); + } + if (hasModifierProperty(PsiModifier.STATIC)){ + if (!isInterfaceField){ + buffer.append(PsiModifier.STATIC); + buffer.append(' '); + } + } + if (hasModifierProperty(PsiModifier.ABSTRACT)){ + if (!isInterface && !isInterfaceMethod){ + buffer.append(PsiModifier.ABSTRACT); + buffer.append(' '); + } + } + if (hasModifierProperty(PsiModifier.FINAL)){ + if (!isInterfaceField){ + buffer.append(PsiModifier.FINAL); + buffer.append(' '); + } + } + if (hasModifierProperty(PsiModifier.NATIVE)){ + buffer.append(PsiModifier.NATIVE); + buffer.append(' '); + } + if (hasModifierProperty(PsiModifier.SYNCHRONIZED)){ + buffer.append(PsiModifier.SYNCHRONIZED); + buffer.append(' '); + } + if (hasModifierProperty(PsiModifier.TRANSIENT)){ + buffer.append(PsiModifier.TRANSIENT); + buffer.append(' '); + } + if (hasModifierProperty(PsiModifier.VOLATILE)){ + buffer.append(PsiModifier.VOLATILE); + buffer.append(' '); + } + return buffer.toString(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.MODIFIER_LIST); + myMirror = element; + PsiElement[] mirrorAnnotations = ((PsiModifierList)SourceTreeToPsiMap.treeElementToPsi(element)).getAnnotations(); + PsiAnnotation[] annotations = getAnnotations(); + LOG.assertTrue(annotations.length == mirrorAnnotations.length); + for (int i = 0; i < annotations.length; i++) { + ((ClsElementImpl)annotations[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(mirrorAnnotations[i])); + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitModifierList(this); + } + + public String toString() { + return "PsiModifierList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListOwner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListOwner.java new file mode 100644 index 00000000000..eba918ae1eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsModifierListOwner.java @@ -0,0 +1,10 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.psi.PsiModifierListOwner; + +/** + * @author ven + */ +public interface ClsModifierListOwner extends PsiModifierListOwner { + ClsAnnotationImpl[] getAnnotations(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java new file mode 100644 index 00000000000..7c6ffb6fe79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java @@ -0,0 +1,66 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author ven + */ +public class ClsNameValuePairImpl extends ClsElementImpl implements PsiNameValuePair { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsNameValuePairImpl"); + private ClsElementImpl myParent; + private ClsIdentifierImpl myNameIdentifier; + private PsiAnnotationMemberValue myMemberValue; + + public ClsNameValuePairImpl(ClsElementImpl parent) { + myParent = parent; + } + + void setNameIdentifier(ClsIdentifierImpl nameIdentifier) { + myNameIdentifier = nameIdentifier; + } + + void setMemberValue(PsiAnnotationMemberValue memberValue) { + myMemberValue = memberValue; + } + + public String getMirrorText() { + return myNameIdentifier.getMirrorText() + "=" + ((ClsElementImpl)myMemberValue).getMirrorText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(isValid()); + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiNameValuePair mirror = (PsiNameValuePair)SourceTreeToPsiMap.treeElementToPsi(element); + ((ClsElementImpl)getNameIdentifier()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getNameIdentifier())); + ((ClsElementImpl)getValue()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getValue())); + } + + public PsiElement[] getChildren() { + return new PsiElement[] {myNameIdentifier, myMemberValue}; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitNameValuePair(this); + } + + public PsiIdentifier getNameIdentifier() { + return myNameIdentifier; + } + + public String getName() { + return myNameIdentifier.getText(); + } + + public PsiAnnotationMemberValue getValue() { + return myMemberValue; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java new file mode 100644 index 00000000000..fc287b567bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java @@ -0,0 +1,83 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; + +class ClsPackageStatementImpl extends ClsElementImpl implements PsiPackageStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsPackageStatementImpl"); + + private ClsFileImpl myFile; + private final String myPackageName; + + public ClsPackageStatementImpl(ClsFileImpl file) { + myFile = file; + String className = myFile.getClasses()[0].getQualifiedName(); + int index = className.lastIndexOf('.'); + if (index < 0){ + myPackageName = null; + } + else{ + myPackageName = className.substring(0, index); + } + } + + public PsiElement getParent() { + return myFile; + } + + void invalidate() { + myFile = null; + } + + /** + * @not_implemented + */ + public PsiJavaCodeReferenceElement getPackageReference() { + LOG.error("method not implemented"); + return null; + } + + /** + * @not_implemented + */ + public PsiModifierList getAnnotationList() { + LOG.error("method not implemented"); + return null; + } + + /** + * @not_implemented + */ + public PsiElement[] getChildren() { + LOG.error("method not implemented"); + return null; + } + + public String getPackageName() { + return myPackageName; + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + buffer.append("package "); + buffer.append(getPackageName()); + buffer.append(";"); + return buffer.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.PACKAGE_STATEMENT); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPackageStatement(this); + } + + public String toString() { + return "PsiPackageStatement:" + getPackageName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterImpl.java new file mode 100644 index 00000000000..a2290e461f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -0,0 +1,196 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.util.IncorrectOperationException; + +public class ClsParameterImpl extends ClsElementImpl implements PsiParameter, ClsModifierListOwner { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsParameterImpl"); + + private final PsiParameterList myParent; + private final PsiTypeElement myType; + private final int myIdx; + private PsiModifierList myModifierList = null; + private String myMirrorName = null; + private String myName = null; + public static final ClsParameterImpl[] EMPTY_ARRAY = new ClsParameterImpl[0]; + + public ClsParameterImpl(PsiParameterList parent, PsiTypeElement type, int idx) { + myParent = parent; + myType = type; + myIdx = idx; + } + + public PsiElement[] getChildren() { + return new PsiElement[]{getModifierList(), getTypeElement()}; + } + + public PsiElement getParent() { + return myParent; + } + + public PsiIdentifier getNameIdentifier() { + return null; + } + + public String getName() { + if (myName == null) { + ClsMethodImpl method = (ClsMethodImpl)getDeclarationScope(); + if (method.getRepositoryId() < 0) return null; + PsiMethod sourceMethod = (PsiMethod)method.getNavigationElement(); + if (sourceMethod == method) return null; + myName = sourceMethod.getParameterList().getParameters()[myIdx].getName(); + } + return myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiTypeElement getTypeElement() { + return myType; + } + + public PsiType getType() { + return myType.getType(); + } + + public PsiModifierList getModifierList() { + synchronized (PsiLock.LOCK) { + if (myModifierList == null) { + myModifierList = new ClsModifierListImpl(this, 0); + } + ; + } + return myModifierList; + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiExpression getInitializer() { + return null; + } + + public boolean hasInitializer() { + return false; + } + + public Object computeConstantValue() { + return null; + } + + public void normalizeDeclaration() throws IncorrectOperationException { + } + + public String getMirrorText() { + StringBuffer buffer = new StringBuffer(); + ClsAnnotationImpl[] annotations = getAnnotations(); + for (int i = 0; i < annotations.length; i++) { + buffer.append(annotations[i].getMirrorText()); + buffer.append(" "); + } + buffer.append(((ClsElementImpl)getTypeElement()).getMirrorText()); + buffer.append(" "); + buffer.append(getMirrorName()); + return buffer.toString(); + } + + private String getMirrorName() { + synchronized (PsiLock.LOCK) { + if (myMirrorName == null) { + String name = getName(); + if (name != null) return name; + + String[] nameSuggestions = getManager().getCodeStyleManager().suggestVariableName(VariableKind.PARAMETER, null, + null, getType()) + .names; + name = "p"; + if (nameSuggestions.length > 0) { + name = nameSuggestions[0]; + } + + PsiParameter[] parms = ((PsiParameterList)getParent()).getParameters(); + AttemptsLoop: + while (true) { + for (int i = 0; i < parms.length; i++) { + if (parms[i] == this) break AttemptsLoop; + String name1 = ((ClsParameterImpl)parms[i]).getMirrorName(); + if (name.equals(name1)) { + name = nextName(name); + continue AttemptsLoop; + } + } + } + myMirrorName = name; + } + ; + } + return myMirrorName; + } + + private static String nextName(String name) { + int count = 0; + while (true) { + if (count == name.length()) break; + char c = name.charAt(name.length() - count - 1); + if ('0' <= c && c <= '9') { + count++; + } + else { + break; + } + } + + try { + int n = count > 0 ? Integer.parseInt(name.substring(name.length() - count)) : 0; + n++; + return name.substring(0, name.length() - count) + n; + } + catch (NumberFormatException e) { + LOG.assertTrue(false); + return null; + } + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiParameter mirror = (PsiParameter)SourceTreeToPsiMap.treeElementToPsi(element); + ((ClsElementImpl)getModifierList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getModifierList())); + ((ClsElementImpl)getTypeElement()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getTypeElement())); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitParameter(this); + } + + public String toString() { + return "PsiParameter"; + } + + public PsiElement getDeclarationScope() { + // only method parameters exist in compiled code + return getParent().getParent(); + } + + public boolean isVarArgs() { + if (((PsiMethod)myParent.getParent()).isVarArgs()) { + return myIdx == myParent.getParameters().length - 1; + } + + return false; + } + + public ClsAnnotationImpl[] getAnnotations() { + return ((ClsMethodImpl)myParent.getParent()).getParameterAnntations(myIdx); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterListImpl.java new file mode 100644 index 00000000000..100c94438b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParameterListImpl.java @@ -0,0 +1,73 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiParameterList; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ClsParameterListImpl extends ClsElementImpl implements PsiParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsParameterListImpl"); + + private final PsiElement myParent; + private final ClsParameterImpl[] myParameters; + + public ClsParameterListImpl(PsiElement parent, ClsParameterImpl[] parameters) { + myParent = parent; + myParameters = parameters; + } + + public PsiElement[] getChildren(){ + return myParameters; + } + + public PsiElement getParent(){ + return myParent; + } + + public PsiParameter[] getParameters(){ + return myParameters; + } + + public int getParameterIndex(PsiParameter parameter) { + LOG.assertTrue(parameter.getParent() == this); + return PsiImplUtil.getParameterIndex(parameter, this); + } + + public String getMirrorText(){ + StringBuffer buffer = new StringBuffer(); + buffer.append('('); + for(int i = 0; i < myParameters.length; i++) { + PsiParameter parm = myParameters[i]; + if (i > 0) buffer.append(","); + buffer.append(((ClsElementImpl)parm).getMirrorText()); + } + buffer.append(')'); + return buffer.toString(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiParameter[] parms = getParameters(); + PsiParameter[] parmMirrors = ((PsiParameterList)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getParameters(); + LOG.assertTrue(parms.length == parmMirrors.length); + if (parms.length == parmMirrors.length){ + for(int i = 0; i < parms.length; i++) { + ((ClsElementImpl)parms[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(parmMirrors[i])); + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitParameterList(this); + } + + public String toString() { + return "PsiParameterList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParsingUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParsingUtil.java new file mode 100644 index 00000000000..2661f5a8caa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsParsingUtil.java @@ -0,0 +1,47 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiElementFactoryImpl; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ExpressionParsing; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +/** + * @author ven + */ +public class ClsParsingUtil { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.compiled.ClsParsingUtil"); + public static PsiExpression createExpressionFromText(String exprText, PsiManager manager, ClsElementImpl parent) { + PsiJavaFile dummyJavaFile = ((PsiElementFactoryImpl)manager.getElementFactory()).getDummyJavaFile(); // kind of hack - we need to resolve classes from java.lang + final FileElement holderElement = new DummyHolder(manager, dummyJavaFile).getTreeElement(); + CompositeElement _expr = ExpressionParsing.parseExpressionText(manager, exprText.toCharArray(), 0, exprText.toCharArray().length, holderElement.getCharTable()); + if (_expr == null){ + LOG.error("Could not parse expression:'" + exprText + "'"); + return null; + } + TreeUtil.addChildren(holderElement, _expr); + if (_expr instanceof PsiLiteralExpression){ + PsiLiteralExpression expr = (PsiLiteralExpression)_expr; + return new ClsLiteralExpressionImpl(parent, exprText, expr.getType(), expr.getValue()); + } + else if (_expr instanceof PsiPrefixExpression){ + PsiLiteralExpression operand = (PsiLiteralExpression)((PsiPrefixExpression)_expr).getOperand(); + ClsLiteralExpressionImpl literalExpression = new ClsLiteralExpressionImpl(null, operand.getText(), operand.getType(), operand.getValue()); + ClsPrefixExpressionImpl prefixExpression = new ClsPrefixExpressionImpl(parent, literalExpression); + literalExpression.setParent(prefixExpression); + return prefixExpression; + } + else if (_expr instanceof PsiReferenceExpression){ + PsiReferenceExpression patternExpr = (PsiReferenceExpression)SourceTreeToPsiMap.treeElementToPsi(_expr); + return new ClsReferenceExpressionImpl(parent, patternExpr); + } + else{ + LOG.error(_expr.toString()); + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPrefixExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPrefixExpressionImpl.java new file mode 100644 index 00000000000..de80c217278 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsPrefixExpressionImpl.java @@ -0,0 +1,94 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.tree.IElementType; + +public class ClsPrefixExpressionImpl extends ClsElementImpl implements PsiPrefixExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsPrefixExpressionImpl"); + + private final ClsElementImpl myParent; + private final PsiExpression myOperand; + + private MySign mySign = null; + + public ClsPrefixExpressionImpl(ClsElementImpl parent, PsiExpression operand) { + myParent = parent; + myOperand = operand; + } + + public PsiExpression getOperand() { + return myOperand; + } + + public PsiJavaToken getOperationSign() { + if (mySign == null){ + mySign = new MySign(); + } + return mySign; + } + + public PsiType getType() { + return myOperand.getType(); + } + + public PsiElement getParent() { + return myParent; + } + + public PsiElement[] getChildren() { + return new PsiElement[]{getOperationSign(), getOperand()}; + } + + public String getText() { + return "-" + myOperand.getText(); + } + + public String getMirrorText() { + return getText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.PREFIX_EXPRESSION); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPrefixExpression(this); + } + + public String toString() { + return "PsiPrefixExpression:" + getText(); + } + + private class MySign extends ClsElementImpl implements PsiJavaToken, JavaTokenType{ + public IElementType getTokenType() { + return MINUS; + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return ClsPrefixExpressionImpl.this; + } + + public String getMirrorText() { + return "-"; + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.MINUS); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitJavaToken(this); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java new file mode 100644 index 00000000000..55420958c84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java @@ -0,0 +1,170 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +public class ClsReferenceExpressionImpl extends ClsElementImpl implements PsiReferenceExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsReferenceExpressionImpl"); + + private final ClsElementImpl myParent; + private final PsiReferenceExpression myPatternExpression; + private final PsiReferenceExpression myQualifier; + private final String myName; + private final PsiIdentifier myNameElement; + + public ClsReferenceExpressionImpl(ClsElementImpl parent, PsiReferenceExpression patternExpression) { + myParent = parent; + myPatternExpression = patternExpression; + + PsiReferenceExpression patternQualifier = (PsiReferenceExpression)myPatternExpression.getQualifierExpression(); + if (patternQualifier != null){ + myQualifier = new ClsReferenceExpressionImpl(this, patternQualifier); + } + else{ + myQualifier = null; + } + + myName = myPatternExpression.getReferenceName(); + myNameElement = new ClsIdentifierImpl(this, myName); + } + + public PsiElement getParent() { + return myParent; + } + + public PsiExpression getQualifierExpression() { + return myQualifier; + } + + public PsiElement bindToElementViaStaticImport(PsiClass aClass) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement getReferenceNameElement() { + return myNameElement; + } + + public PsiReferenceParameterList getParameterList() { + return null; + } + + public PsiElement[] getChildren() { + if (myQualifier != null){ + return new PsiElement[]{myQualifier, myNameElement}; + } + else{ + return new PsiElement[]{myNameElement}; + } + } + + public String getText() { + return myQualifier != null ? myQualifier.getText() + "." + myName : myName; + } + + public boolean isQualified() { + return myQualifier != null; + } + + public PsiType getType() { + return myPatternExpression.getType(); + } + + public PsiElement resolve() { + return myPatternExpression.resolve(); + } + + public ResolveResult advancedResolve(boolean incompleteCode){ + return myPatternExpression.advancedResolve(incompleteCode); + } + + public ResolveResult[] multiResolve(boolean incompleteCode){ + final ResolveResult result = advancedResolve(incompleteCode); + if(result != ResolveResult.EMPTY) return new ResolveResult[]{result}; + return ResolveResult.EMPTY_ARRAY; + } + + + public PsiElement getElement() { + return this; + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public String getCanonicalText() { + return myPatternExpression.getCanonicalText(); + } + + public String getQualifiedName() { + return getCanonicalText(); + } + + public String getReferenceName() { + return myPatternExpression.getReferenceName(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public boolean isReferenceTo(PsiElement element) { + return myPatternExpression.isReferenceTo(element); + } + + public Object[] getVariants() { + return myPatternExpression.getVariants(); + } + + public void processVariants(PsiScopeProcessor processor) { + myPatternExpression.processVariants(processor); + } + + public boolean isSoft() { + return false; + } + + // very special method + public void setCachedResolveResult(PsiElement result, Boolean problemWithAccess, Boolean problemWithStatic) { + ResolveCache resolveCache = ((PsiManagerImpl)getManager()).getResolveCache(); + resolveCache.setCachedJavaResolve(this, new ResolveResult[]{new CandidateInfo(result, PsiSubstitutor.EMPTY)}, true, true); + } + + public String getMirrorText() { + return getText(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.REFERENCE_EXPRESSION); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceExpression(this); + } + + public String toString() { + return "PsiReferenceExpression:" + getText(); + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } + + public PsiElement getQualifier() { + return getQualifierExpression(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java new file mode 100644 index 00000000000..033150d7bcd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java @@ -0,0 +1,96 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ClsReferenceListImpl extends ClsElementImpl implements PsiReferenceList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsReferenceListImpl"); + + private final PsiElement myParent; + private PsiJavaCodeReferenceElement[] myReferences; + private PsiClassType[] myTypes; + private final String myType; + + public ClsReferenceListImpl(PsiElement parent, PsiJavaCodeReferenceElement[] references, String type) { + myParent = parent; + myReferences = references; + LOG.assertTrue(type != null); + myType = type; + } + + public ClsReferenceListImpl(PsiElement parent, String type) { + myParent = parent; + LOG.assertTrue(type != null); + myType = type; + } + + public void setReferences(PsiJavaCodeReferenceElement[] references) { + myReferences = references; + } + + public PsiElement[] getChildren(){ + return myReferences; + } + + public PsiElement getParent(){ + return myParent; + } + + public PsiJavaCodeReferenceElement[] getReferenceElements(){ + return myReferences; + } + + public PsiClassType[] getReferencedTypes() { + synchronized (PsiLock.LOCK) { + if (myTypes == null) { + final PsiElementFactory factory = getManager().getElementFactory(); + myTypes = new PsiClassType[myReferences.length]; + for (int i = 0; i < myReferences.length; i++) { + PsiJavaCodeReferenceElement reference = myReferences[i]; + myTypes[i] = factory.createType(reference); + } + } + ; + } + return myTypes; + } + + public String getMirrorText(){ + if (myReferences.length == 0) return ""; + StringBuffer buffer = new StringBuffer(); + buffer.append(myType); + buffer.append(" "); + for(int i = 0; i < myReferences.length; i++) { + PsiJavaCodeReferenceElement ref = myReferences[i]; + if (i > 0) buffer.append(","); + buffer.append(((ClsElementImpl)ref).getMirrorText()); + } + return buffer.toString(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiJavaCodeReferenceElement[] refs = getReferenceElements(); + PsiJavaCodeReferenceElement[] refMirrors = ((PsiReferenceList)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getReferenceElements(); + LOG.assertTrue(refs.length == refMirrors.length); + if (refs.length == refMirrors.length){ + for(int i = 0; i < refs.length; i++) { + ((ClsElementImpl)refs[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(refMirrors[i])); + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitReferenceList(this); + } + + public String toString() { + return "PsiReferenceList"; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceParametersListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceParametersListImpl.java new file mode 100644 index 00000000000..3f1294020bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsReferenceParametersListImpl.java @@ -0,0 +1,69 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author max + */ +public class ClsReferenceParametersListImpl extends ClsElementImpl implements PsiReferenceParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsReferenceParametersListImpl"); + + private final PsiElement myParent; + private final PsiTypeElement[] myTypeElements; + + public ClsReferenceParametersListImpl(PsiElement parent, PsiTypeElement[] typeElements) { + myParent = parent; + myTypeElements = typeElements; + } + + public String getMirrorText() { + if (myTypeElements.length == 0) return ""; + StringBuffer buf = new StringBuffer(); + buf.append('<'); + for (int i = 0; i < myTypeElements.length; i++) { + if (i > 0) buf.append(','); + ClsTypeElementImpl typeElement = (ClsTypeElementImpl) myTypeElements[i]; + buf.append(typeElement.getMirrorText()); + } + buf.append('>'); + return buf.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiTypeElement[] typeElements = getTypeParameterElements(); + PsiTypeElement[] typeMirrors = ((PsiReferenceParameterList)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getTypeParameterElements(); + LOG.assertTrue(typeElements.length == typeMirrors.length); + if (typeElements.length == typeMirrors.length){ + for(int i = 0; i < typeElements.length; i++) { + ((ClsElementImpl)typeElements[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(typeMirrors[i])); + } + } + } + + public PsiElement[] getChildren() { + return myTypeElements; + } + + public PsiTypeElement[] getTypeParameterElements() { + return myTypeElements; + } + + public PsiType[] getTypeArguments() { + return PsiImplUtil.typesByTypeElements(myTypeElements); + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceParameterList(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java new file mode 100644 index 00000000000..ab7e33b18c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java @@ -0,0 +1,61 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.RepositoryElementsManager; +import com.intellij.psi.impl.RepositoryPsiElement; +import com.intellij.psi.impl.cache.RepositoryManager; + +public abstract class ClsRepositoryPsiElement extends ClsElementImpl implements RepositoryPsiElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsRepositoryPsiElement"); + + protected final PsiManagerImpl myManager; + private long myRepositoryId; + + public ClsRepositoryPsiElement(PsiManagerImpl manager, long repositoryId) { + myManager = manager; + myRepositoryId = repositoryId; + } + + public long getRepositoryId() { + return myRepositoryId; + } + + public boolean isRepositoryIdInitialized() { + return true; + } + + public void setRepositoryId(long repositoryId) { + myRepositoryId = repositoryId; + myCachedParentId = -1; + } + + private long myCachedParentId = -1; + + protected long getParentId(){ + if(myCachedParentId > 0) return myCachedParentId; + long repositoryId = getRepositoryId(); + if (repositoryId < 0) return -1; + myCachedParentId = getRepositoryManager().getItemView(repositoryId).getParent(repositoryId); + return myCachedParentId; + } + + + public void prepareToRepositoryIdInvalidation() { + LOG.assertTrue(false); + } + + public final PsiManager getManager() { + return myManager; + } + + protected RepositoryManager getRepositoryManager() { + return myManager.getRepositoryManager(); + } + + protected RepositoryElementsManager getRepositoryElementsManager() { + return myManager.getRepositoryElementsManager(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java new file mode 100644 index 00000000000..e4d65a1ac19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java @@ -0,0 +1,193 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsTypeImpl"); + static final char VARIANCE_NONE = '\0'; + static final char VARIANCE_EXTENDS = '+'; + static final char VARIANCE_SUPER = '-'; + static final char VARIANCE_INVARIANT = '*'; + + + private PsiElement myParent; + private final String myTypeText; + + private ClsElementImpl myChild = null; + private boolean myChildSet = false; + private PsiType myCachedType; + private char myVariance; + + public ClsTypeElementImpl(PsiElement parent, String typeText, char variance) { + myParent = parent; + myTypeText = typeText; + myVariance = variance; + } + + void setParent(PsiElement parent){ + myParent = parent; + } + + public PsiElement[] getChildren(){ + loadChild(); + if (myChild == null) return PsiElement.EMPTY_ARRAY; + return new PsiElement[] {myChild}; + } + + public PsiElement getParent(){ + return myParent; + } + + public String getText(){ + final String shortClassName = PsiNameHelper.getShortClassName(myTypeText); + return decorateTypeText(shortClassName); + } + + private String decorateTypeText(final String shortClassName) { + switch(myVariance) { + case VARIANCE_NONE: + return shortClassName; + case VARIANCE_EXTENDS: + return "? extends " + shortClassName; + case VARIANCE_SUPER: + return "? super " + shortClassName; + case VARIANCE_INVARIANT: + return "?"; + default: + LOG.assertTrue(false); + return null; + } + } + + public String getCanonicalText(){ + return decorateTypeText(myTypeText); + } + + public String getMirrorText(){ + return decorateTypeText(myTypeText); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.TYPE); + myMirror = element; + + loadChild(); + + if (myChild != null) { + myChild.setMirror(((CompositeElement) element).firstChild); + } + } + + private void loadChild() { + if (isPrimitive()) { + myChildSet = true; + return; + } + + if (isArray() || isVarArgs()) { + createComponentTypeChild(); + } + else { + createClassReferenceChild(); + } + } + + private boolean isPrimitive() { + return getManager().getElementFactory().createPrimitiveType(myTypeText) != null; + } + + private boolean isArray() { + return myTypeText.endsWith("[]"); + } + + private boolean isVarArgs() { + return myTypeText.endsWith("..."); + } + + public PsiType getType() { + if (myCachedType == null) { + myCachedType = calculateType(); + } + return myCachedType; + } + + public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() { + return null; + } + + private PsiType calculateType() { + PsiType result = getManager().getElementFactory().createPrimitiveType(myTypeText); + if (result != null) return result; + + if (isArray()) { + createComponentTypeChild(); + return ((PsiTypeElement)myChild).getType().createArrayType(); + } else if (isVarArgs()) { + createComponentTypeChild(); + return new PsiEllipsisType(((PsiTypeElement)myChild).getType()); + } + + createClassReferenceChild(); + final PsiClassReferenceType psiClassReferenceType; + if (myVariance != VARIANCE_INVARIANT) { + psiClassReferenceType = new PsiClassReferenceType((PsiJavaCodeReferenceElement) myChild); + } + else { + psiClassReferenceType = null; + } + + switch(myVariance) { + case VARIANCE_NONE: + return psiClassReferenceType; + case VARIANCE_EXTENDS: + return PsiWildcardType.createExtends(getManager(), psiClassReferenceType); + case VARIANCE_SUPER: + return PsiWildcardType.createSuper(getManager(), psiClassReferenceType); + case VARIANCE_INVARIANT: + return PsiWildcardType.createUnbounded(getManager()); + default: + LOG.assertTrue(false); + return null; + } + } + + private void createClassReferenceChild() { + synchronized (PsiLock.LOCK) { + if (!myChildSet) { + if (myVariance != VARIANCE_INVARIANT) { + myChild = new ClsJavaCodeReferenceElementImpl(this, myTypeText); + } + myChildSet = true; + } + ; + } + } + + private void createComponentTypeChild() { + if (!myChildSet) { + if (isArray()) { + myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 2), myVariance); + } else if (isVarArgs()) { + myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 3), myVariance); + } else { + LOG.assertTrue(false); + } + myChildSet = true; + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitTypeElement(this); + } + + public String toString() { + return "PsiTypeElement:" + getText(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java new file mode 100644 index 00000000000..22e7b8ea506 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java @@ -0,0 +1,326 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.psi.*; +import com.intellij.psi.impl.InheritanceImplUtil; +import com.intellij.psi.impl.PsiClassImplUtil; +import com.intellij.psi.impl.light.LightEmptyImplementsList; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.cls.ClsFormatException; + +import java.text.CharacterIterator; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * @author max + */ +public class ClsTypeParameterImpl extends ClsElementImpl implements PsiTypeParameter { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsTypeParameterImpl"); + + private String myName; + private ClsReferenceListImpl myBoundsList; + private PsiElement myParent; + private int myIndex; + private LightEmptyImplementsList myLightEmptyImplementsList; + private final String mySignature; + + public ClsTypeParameterImpl(PsiElement parent, CharacterIterator signature, int index, String parentSignatureAttribute) throws ClsFormatException { + myParent = parent; + myIndex = index; + StringBuffer name = new StringBuffer(); + final int signatureBeginIndex = signature.getIndex(); + while (signature.current() != ':' && signature.current() != CharacterIterator.DONE) { + name.append(signature.current()); + signature.next(); + } + if (signature.current() == CharacterIterator.DONE) { + throw new ClsFormatException(); + } + myName = name.toString(); + + ArrayList bounds = new ArrayList(); + while (signature.current() == ':') { + signature.next(); + PsiJavaCodeReferenceElement bound = GenericSignatureParsing.parseToplevelClassRefSignature(signature, this); + if (bound != null && !bound.getQualifiedName().equals("java.lang.Object")) { + bounds.add(bound); + } + } + + myBoundsList = new ClsReferenceListImpl(this, bounds.toArray( + new PsiJavaCodeReferenceElement[bounds.size()]), PsiKeyword.EXTENDS); + final int endIndex = signature.getIndex(); + mySignature = parentSignatureAttribute.substring(signatureBeginIndex, endIndex); + } + + public String getQualifiedName() { + return null; + } + + public boolean isInterface() { + return false; + } + + public boolean isAnnotationType() { + return false; + } + + public boolean isEnum() { + return false; + } + + public PsiField[] getFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + public PsiField findFieldByName(String name, boolean checkBases) { + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + public PsiMethod[] findMethodsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + public List> findMethodsAndTheirSubstitutorsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + public PsiClass findInnerClassByName(String name, boolean checkBases) { + return PsiClassImplUtil.findInnerByName(this, name, checkBases); + } + + public PsiTypeParameterList getTypeParameterList() { + return null; + } + + public boolean hasTypeParameters() { + return false; + } + + // very special method! + public PsiElement getScope() { + return getParent().getParent(); + } + + public boolean isInheritor(PsiClass baseClass, boolean checkDeep) { + return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep); + } + + public PomMemberOwner getPom() { + //TODO: + return null; + } + + public PsiIdentifier getNameIdentifier() { + return null; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + return PsiClassImplUtil.processDeclarationsInClass(this, processor, substitutor, new HashSet(), lastParent, place); + } + + public String getName() { + return myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + myName = name; + return this; + } + + public PsiMethod[] getConstructors() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiDocComment getDocComment() { + return null; + } + + public boolean isDeprecated() { + return false; + } + + public PsiReferenceList getExtendsList() { + return myBoundsList; + } + + public PsiReferenceList getImplementsList() { + if (myLightEmptyImplementsList == null) { + myLightEmptyImplementsList = new LightEmptyImplementsList(getManager()); + } + return myLightEmptyImplementsList; + } + + public PsiClassType[] getExtendsListTypes() { + return myBoundsList.getReferencedTypes(); + } + + public PsiClassType[] getImplementsListTypes() { + return PsiClassType.EMPTY_ARRAY; + } + + public PsiClass[] getInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiField[] getAllFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getAllMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiClass[] getAllInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiClassInitializer[] getInitializers() { + return PsiClassInitializer.EMPTY_ARRAY; + } + + public PsiTypeParameter[] getTypeParameters() { + return PsiTypeParameter.EMPTY_ARRAY; + } + + public PsiClass getSuperClass() { + return PsiClassImplUtil.getSuperClass(this); + } + + public PsiClass[] getInterfaces() { + return PsiClassImplUtil.getInterfaces(this); + } + + public PsiClass[] getSupers() { + return PsiClassImplUtil.getSupers(this); + } + + public PsiClassType[] getSuperTypes() { + return PsiClassImplUtil.getSuperTypes(this); + } + + public PsiClass getContainingClass() { + return null; + } + + public PsiModifierList getModifierList() { + return null; + } + + public boolean hasModifierProperty(String name) { + return false; + } + + public PsiJavaToken getLBrace() { + return null; + } + + public PsiJavaToken getRBrace() { + return null; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeParameter(this); + } + + public String toString() { + return "PsiTypeParameter"; + } + + public String getMirrorText() { + StringBuffer buf = new StringBuffer(); + buf.append(myName); + PsiJavaCodeReferenceElement[] bounds = myBoundsList.getReferenceElements(); + if (bounds.length > 0) { + buf.append(" extends "); + for (int i = 0; i < bounds.length; i++) { + PsiJavaCodeReferenceElement bound = bounds[i]; + if (i > 0) buf.append("&"); + buf.append(bound.getCanonicalText()); + } + } + return buf.toString(); + } + + public void setMirror(TreeElement element) { + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiTypeParameter mirror = (PsiTypeParameter) SourceTreeToPsiMap.treeElementToPsi(element); + ((ClsReferenceListImpl) getExtendsList()).setMirror(SourceTreeToPsiMap.psiElementToTree(mirror.getExtendsList())); + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return myParent; + } + + public PsiTypeParameterListOwner getOwner() { + if (myParent instanceof ClsTypeParametersListImpl) { + final PsiElement parent = myParent.getParent(); + if (parent instanceof PsiTypeParameterListOwner) return (PsiTypeParameterListOwner) parent; + } + return null; + } + + + public int getIndex() { + return myIndex; + } + + public String getSignature() { + return mySignature; + /* + StringBuffer buf = new StringBuffer(); + buf.append(myName); + buf.append(":"); + PsiJavaCodeReferenceElement[] bounds = myBoundsList.getReferenceElements(); + if (bounds.length > 0) { + for (int i = 0; i < bounds.length; i++) { + buf.append(((ClsElementWithSignature)bounds[i]).getSignature()); + if (i < bounds.length - 1) { + buf.append(":"); + } + } + } + return buf.toString(); + */ + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java new file mode 100644 index 00000000000..f58167f5d7e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java @@ -0,0 +1,165 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +/** + * @author max + */ +public class ClsTypeParameterReferenceImpl extends ClsElementImpl implements PsiJavaCodeReferenceElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsTypeParameterReferenceImpl"); + private PsiElement myParent; + private String myName; + + public ClsTypeParameterReferenceImpl(PsiElement parent, String name) { + myParent = parent; + myName = name; + } + + public void processVariants(PsiScopeProcessor processor) { + throw new RuntimeException("Variants are not available for light references"); + } + + public PsiElement getReferenceNameElement() { + return null; + } + + public PsiReferenceParameterList getParameterList() { + return null; + } + + public String getQualifiedName() { + return myName; + } + + public String getReferenceName() { + return myName; + } + + public PsiElement resolve() { + LOG.assertTrue(myParent.isValid()); + PsiElement parent = myParent; + while (!(parent instanceof PsiFile)) { + PsiTypeParameterList parameterList = null; + if (parent instanceof PsiClass) { + parameterList = ((PsiClass) parent).getTypeParameterList(); + } + else if (parent instanceof PsiMethod) { + parameterList = ((PsiMethod) parent).getTypeParameterList(); + } + + if (parameterList != null) { + PsiTypeParameter[] parameters = parameterList.getTypeParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiTypeParameter parameter = parameters[i]; + if (parameter.getName().equals(myName)) return parameter; + } + } + parent = parent.getParent(); + } + + return null; + } + + public ResolveResult advancedResolve(boolean incompleteCode){ + return new CandidateInfo(resolve(), PsiSubstitutor.EMPTY); + } + + public ResolveResult[] multiResolve(boolean incompleteCode){ + final ResolveResult result = advancedResolve(incompleteCode); + if(result != ResolveResult.EMPTY) return new ResolveResult[]{result}; + return ResolveResult.EMPTY_ARRAY; + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } + + public PsiElement getQualifier() { + return null; + } + + public boolean isQualified() { + return false; + } + + public String getCanonicalText() { + return myName; + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof ClsTypeParameterImpl)) return false; + + return element == resolve(); + } + + public String getText() { + return myName; + } + + public int getTextLength() { + return getText().length(); + } + + public PsiReference getReference() { + return this; + } + + public PsiElement[] getChildren(){ + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent(){ + return myParent; + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE); + } + + public Object[] getVariants() { + throw new RuntimeException("Variants are not available for references to compiled code"); + } + + public boolean isSoft(){ + return false; + } + + public String getMirrorText(){ + return getCanonicalText(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + LOG.assertTrue(element.getElementType() == ElementType.JAVA_CODE_REFERENCE); + myMirror = element; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitReferenceElement(this); + } + + public String toString() { + return "PsiJavaCodeReferenceElement:" + getText(); + } + + public TextRange getRangeInElement() { + getMirror(); + return myMirror != null ? myMirror.getTextRange() : new TextRange(0, getTextLength()); + } + + public PsiElement getElement() { + return this; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java new file mode 100644 index 00000000000..4e5d63dc4e3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java @@ -0,0 +1,85 @@ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.PsiTypeParameterList; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.PsiImplUtil; + +/** + * @author max + */ +public class ClsTypeParametersListImpl extends ClsElementImpl implements PsiTypeParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsTypeParametersListImpl"); + + private PsiElement myParent; + private ClsTypeParameterImpl[] myParameters; + + public ClsTypeParametersListImpl(PsiElement parent, ClsTypeParameterImpl[] parameters) { + myParent = parent; + myParameters = parameters; + } + + public ClsTypeParametersListImpl(PsiElement parent) { + myParent = parent; + } + + public void setParameters(ClsTypeParameterImpl[] parameters) { + myParameters = parameters; + } + + public String getMirrorText() { + if (myParameters.length == 0) return ""; + StringBuffer buf = new StringBuffer(); + buf.append('<'); + for (int i = 0; i < myParameters.length; i++) { + ClsTypeParameterImpl parameter = myParameters[i]; + if (i > 0) buf.append(','); + buf.append(parameter.getMirrorText()); + } + buf.append('>'); + return buf.toString(); + } + + public void setMirror(TreeElement element){ + LOG.assertTrue(myMirror == null); + myMirror = element; + + PsiTypeParameter[] parms = getTypeParameters(); + PsiTypeParameter[] parmMirrors = ((PsiTypeParameterList)SourceTreeToPsiMap.treeElementToPsi(myMirror)).getTypeParameters(); + LOG.assertTrue(parms.length == parmMirrors.length); + if (parms.length == parmMirrors.length){ + for(int i = 0; i < parms.length; i++) { + ((ClsElementImpl)parms[i]).setMirror(SourceTreeToPsiMap.psiElementToTree(parmMirrors[i])); + } + } + } + + public PsiElement[] getChildren() { + return myParameters; + } + + public PsiElement getParent() { + return myParent; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeParameterList(this); + } + + public PsiTypeParameter[] getTypeParameters() { + return myParameters; + } + + public int getTypeParameterIndex(PsiTypeParameter typeParameter) { + LOG.assertTrue(typeParameter.getParent() == this); + return PsiImplUtil.getTypeParameterIndex(typeParameter, this); + } + + public String toString() { + return "PsiTypeParameterList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiBinaryFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiBinaryFileImpl.java new file mode 100644 index 00000000000..5665713088d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiBinaryFileImpl.java @@ -0,0 +1,262 @@ +package com.intellij.psi.impl.file; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiElementBase; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.IncorrectOperationException; + +import java.io.IOException; +import java.io.OutputStream; + +public class PsiBinaryFileImpl extends PsiElementBase implements PsiBinaryFile, Cloneable { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.PsiBinaryFileImpl"); + + private final PsiManagerImpl myManager; + private VirtualFile myFile; + private String myName; // for myFile == null only + private byte[] myContents; // for myFile == null only + private long myModificationStamp; + private FileType myFileType; + + public PsiBinaryFileImpl(PsiManagerImpl manager, VirtualFile vFile) { + myManager = manager; + myFile = vFile; + myModificationStamp = myFile.getModificationStamp(); + myFileType = FileTypeManager.getInstance().getFileTypeByFile(myFile); + } + + public VirtualFile getVirtualFile() { + return myFile; + } + + public void setVirtualFile(VirtualFile file) throws IOException { + myFile = file; + if (file != null){ + myName = null; + if (myContents != null){ + OutputStream out = myFile.getOutputStream(myManager); + out.write(myContents); + out.close(); + myContents = null; + } + } + } + + public byte[] getStoredContents() { + return myContents; + } + + public String getName() { + return myFile != null ? myFile.getName() : myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + checkSetName(name); + + if (myFile == null){ + myName = name; + return this; // not absolutely correct - might change type + } + + return PsiFileImplUtil.setName(this, name); + } + + public void checkSetName(String name) throws IncorrectOperationException { + if (myFile == null) return; + PsiFileImplUtil.checkSetName(this, name); + } + + public PsiDirectory getContainingDirectory() { + VirtualFile parentFile = myFile.getParent(); + if (parentFile == null) return null; + return getManager().findDirectory(parentFile); + } + + public long getModificationStamp() { + return myModificationStamp; + } + + public void setModificationStamp(long modificationStamp) { + myModificationStamp = modificationStamp; + } + + public PsiElement[] getOnDemandImports(boolean includeImplicit, boolean checkIncludes) { + return null; + } + + public PsiClass[] getSingleClassImports(boolean checkIncludes) { + return null; + } + + public String[] getImplicitlyImportedPackages() { + return null; + } + + public PsiJavaCodeReferenceElement[] getImplicitlyImportedPackageReferences() { + return null; + } + + public PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass) { + return null; + } + + public PsiManager getManager() { + return myManager; + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return getContainingDirectory(); + } + + public PsiFile getContainingFile() { + return this; + } + + public TextRange getTextRange() { + return null; + } + + public int getStartOffsetInParent() { + return -1; + } + + public int getTextLength() { + return -1; + } + + public PsiElement findElementAt(int offset) { + return null; + } + + public int getTextOffset() { + return -1; + } + + public String getText() { + return null; + } + + public char[] textToCharArray() { + return null; + } + + public boolean textMatches(CharSequence text) { + return false; + } + + public boolean textMatches(PsiElement element) { + return false; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitBinaryFile(this); + } + + public PsiElement copy() { + PsiBinaryFileImpl clone = (PsiBinaryFileImpl)clone(); + clone.myFile = null; + clone.myName = getName(); + try{ + clone.myContents = myFile != null ? myFile.contentsToByteArray() : myContents; + } + catch(IOException e){ + } + return clone; + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAdd(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void delete() throws IncorrectOperationException{ + checkDelete(); + PsiFileImplUtil.doDelete(this); + } + + public void checkDelete() throws IncorrectOperationException{ + if (myFile == null){ + throw new IncorrectOperationException(); + } + CheckUtil.checkWritable(this); + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + return null; + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + } + + public boolean isValid() { + if (myFile == null) return true; // "dummy" file + if (!myFile.isValid()) return false; + return myManager.getFileManager().findFile(myFile) == this; + } + + public boolean isWritable() { + return myFile != null ? myFile.isWritable() : true; + } + + public boolean isPhysical() { + return myFile != null; + } + + public String getDetectedLineSeparator() { + throw new UnsupportedOperationException(); + } + + public PsiFile getOriginalFile() { + return null; + } + + public String toString() { + return "PsiBinaryFile:" + getName(); + } + + public boolean canContainJavaCode() { + return false; + } + + public FileType getFileType() { + return myFileType; + } + + public PsiFile[] getPsiRoots() { + return new PsiFile[]{this}; + } + + public PsiFile createPseudoPhysicalCopy() { + LOG.assertTrue(false); + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiDirectoryImpl.java new file mode 100644 index 00000000000..3888228c2c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -0,0 +1,605 @@ +package com.intellij.psi.impl.file; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiElementBase; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChangeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Properties; + +public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.PsiDirectoryImpl"); + + private final PsiManagerImpl myManager; + private VirtualFile myFile; + + public PsiDirectoryImpl(PsiManagerImpl manager, VirtualFile file) { + myManager = manager; + myFile = file; + } + + public VirtualFile getVirtualFile() { + return myFile; + } + + public void setVirtualFile(VirtualFile file) { + myFile = file; + } + + public boolean isValid() { + return myFile.isValid(); + } + + public PsiManager getManager() { + return myManager; + } + + public String getName() { + return myFile.getName(); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + checkSetName(name); + + /* + final String oldName = myFile.getName(); + PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); + event.setElement(this); + event.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME); + event.setOldValue(oldName); + myManager.beforePropertyChange(event); + */ + + try { + myFile.rename(myManager, name); + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + + /* + PsiUndoableAction undoableAction = new PsiUndoableAction(){ + public void undo() throws IncorrectOperationException { + if (!PsiDirectoryImpl.this.isValid()){ + throw new IncorrectOperationException(); + } + setName(oldName); + } + }; + */ + + /* + event = new PsiTreeChangeEventImpl(myManager); + event.setElement(this); + event.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME); + event.setOldValue(oldName); + event.setNewValue(name); + event.setUndoableAction(undoableAction); + myManager.propertyChanged(event); + */ + return this; + } + + public void checkSetName(String name) throws IncorrectOperationException { + //CheckUtil.checkIsIdentifier(name); + CheckUtil.checkWritable(this); + VirtualFile parentFile = myFile.getParent(); + if (parentFile == null) { + throw new IncorrectOperationException("Cannot rename root directory."); + } + VirtualFile child = parentFile.findChild(name); + if (child != null && !child.equals(myFile)) { + throw new IncorrectOperationException("File " + child.getPresentableUrl() + " already exists."); + } + } + + public PsiPackage getPackage() { + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); + String packageName = projectFileIndex.getPackageNameByDirectory(myFile); + if (packageName == null) return null; + return myManager.findPackage(packageName); + } + + public PsiDirectory getParentDirectory() { + VirtualFile parentFile = myFile.getParent(); + if (parentFile == null) return null; + return myManager.findDirectory(parentFile); + } + + public PsiDirectory[] getSubdirectories() { + VirtualFile[] files = myFile.getChildren(); + ArrayList dirs = new ArrayList(); + for (int i = 0; i < files.length; i++) { + PsiDirectory dir = myManager.findDirectory(files[i]); + if (dir != null) { + dirs.add(dir); + } + } + return dirs.toArray(new PsiDirectory[dirs.size()]); + } + + public PsiFile[] getFiles() { + LOG.assertTrue(myFile.isValid()); + VirtualFile[] files = myFile.getChildren(); + ArrayList psiFiles = new ArrayList(); + for (int i = 0; i < files.length; i++) { + PsiFile psiFile = myManager.findFile(files[i]); + if (psiFile != null) { + psiFiles.add(psiFile); + } + } + return psiFiles.toArray(new PsiFile[psiFiles.size()]); + } + + public PsiDirectory findSubdirectory(String name) { + VirtualFile childVFile = myFile.findChild(name); + if (childVFile == null) return null; + return myManager.findDirectory(childVFile); + } + + public PsiFile findFile(String name) { + VirtualFile childVFile = myFile.findChild(name); + if (childVFile == null) return null; + return myManager.findFile(childVFile); + } + + public PsiClass[] getClasses() { + LOG.assertTrue(isValid()); + + VirtualFile[] vFiles = myFile.getChildren(); + ArrayList classes = new ArrayList(); + for (int i = 0; i < vFiles.length; i++) { + PsiFile file = myManager.findFile(vFiles[i]); + if (file instanceof PsiJavaFile) { + PsiClass[] fileClasses = ((PsiJavaFile)file).getClasses(); + for (int j = 0; j < fileClasses.length; j++) { + classes.add(fileClasses[j]); + } + } + } + return classes.toArray(new PsiClass[classes.size()]); + } + + public PsiElement[] getChildren() { + LOG.assertTrue(isValid()); + + VirtualFile[] files = myFile.getChildren(); + ArrayList children = new ArrayList(); + for (int i = 0; i < files.length; i++) { + VirtualFile vFile = files[i]; + if (vFile.isDirectory()) { + PsiDirectory dir = myManager.findDirectory(vFile); + if (dir != null) { + children.add(dir); + } + } + else { + PsiFile file = myManager.findFile(vFile); + if (file != null) { + children.add(file); + } + } + } + return children.toArray(PsiElement.EMPTY_ARRAY); + } + + public PsiElement getParent() { + return getParentDirectory(); + } + + public PsiFile getContainingFile() { + return null; + } + + public TextRange getTextRange() { + return null; + } + + public int getStartOffsetInParent() { + return -1; + } + + public int getTextLength() { + return -1; + } + + public PsiElement findElementAt(int offset) { + return null; + } + + public int getTextOffset() { + return -1; + } + + public String getText() { + return null; + } + + public char[] textToCharArray() { + return null; + } + + public boolean textMatches(CharSequence text) { + return false; + } + + public boolean textMatches(PsiElement element) { + return false; + } + + public final boolean isWritable() { + return myFile.isWritable(); + } + + public boolean isPhysical() { + return !(myFile.getFileSystem() instanceof DummyFileSystem); + } + + /** + * @not_implemented + */ + public PsiElement copy() { + LOG.error("not implemented"); + return null; + } + + public PsiClass createClass(String name) throws IncorrectOperationException { + return createSomeClass(name, FileTemplateManager.INTERNAL_CLASS_TEMPLATE_NAME); + } + + public PsiClass createInterface(String name) throws IncorrectOperationException { + String templateName = FileTemplateManager.INTERNAL_INTERFACE_TEMPLATE_NAME; + PsiClass someClass = createSomeClass(name, templateName); + if (!someClass.isInterface()) { + throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName)); + } + return someClass; + } + + public PsiClass createEnum(String name) throws IncorrectOperationException { + String templateName = FileTemplateManager.INTERNAL_ENUM_TEMPLATE_NAME; + PsiClass someClass = createSomeClass(name, templateName); + if (!someClass.isEnum()) { + throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName)); + } + return someClass; + } + + public PsiClass createAnnotationType(String name) throws IncorrectOperationException { + String templateName = FileTemplateManager.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME; + PsiClass someClass = createSomeClass(name, templateName); + if (!someClass.isAnnotationType()) { + throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName)); + } + return someClass; + } + + private PsiClass createSomeClass(String name, String templateName) throws IncorrectOperationException { + checkCreateClassOrInterface(name); + + CodeStyleManager styleManager = CodeStyleManager.getInstance(myManager.getProject()); + + FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName); + boolean adjustCode = template.isAdjust(); + + Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(); + Properties properties = new Properties(defaultProperties); + FileTemplateUtil.setPackageNameAttribute(properties, this); + properties.setProperty("NAME", name); + String text; + try { + text = template.getText(properties); + } + catch (Exception e) { + throw new RuntimeException("Unable to load template for " + FileTemplateManager.getInstance().internalTemplateToSubject(templateName), e); + } + + PsiElementFactory factory = myManager.getElementFactory(); + String ext = StdFileTypes.JAVA.getDefaultExtension(); + final PsiJavaFile file = (PsiJavaFile)factory.createFileFromText(name + "." + ext, text); + PsiClass[] classes = file.getClasses(); + if (classes.length != 1 || !classes[0].getName().equals(name)) { + throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName)); + } + if (adjustCode) { + styleManager.reformat(file); + } + + PsiJavaFile newFile = (PsiJavaFile)add(file); + return newFile.getClasses()[0]; + } + + private String getIncorrectTemplateMessage(String templateName) { + String incorrectTemplateMessage = "Cannot create " + FileTemplateManager.getInstance().internalTemplateToSubject(templateName) + " - incorrect " + templateName + " template."; + return incorrectTemplateMessage; + } + + public void checkCreateClass(String name) throws IncorrectOperationException { + checkCreateClassOrInterface(name); + } + + public void checkCreateInterface(String name) throws IncorrectOperationException { + checkCreateClassOrInterface(name); + } + + /** + * @not_implemented + */ + public void checkCreateClassOrInterface(String name) throws IncorrectOperationException { + CheckUtil.checkIsIdentifier(myManager, name); + CheckUtil.checkIsIdentifier(myManager, name); + + String fileName = name + "." + StdFileTypes.JAVA.getDefaultExtension(); + checkCreateFile(fileName); + } + + public PsiDirectory createSubdirectory(String name) throws IncorrectOperationException { + checkCreateSubdirectory(name); + + try { + VirtualFile file = getVirtualFile().createChildDirectory(myManager, name); + return myManager.findDirectory(file); + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + } + + public void checkCreateSubdirectory(String name) throws IncorrectOperationException { + // TODO : another check? + //CheckUtil.checkIsIdentifier(name); + VirtualFile existingFile = getVirtualFile().findChild(name); + if (existingFile != null) { + throw new IncorrectOperationException( + "Cannot create package - file \"" + existingFile.getPresentableUrl() + "\" already exists."); + } + CheckUtil.checkWritable(this); + } + + public PsiFile createFile(String name) throws IncorrectOperationException { + checkCreateFile(name); + + try { + VirtualFile vFile = getVirtualFile().createChildData(myManager, name); + final PsiFile psiFile = myManager.findFile(vFile); + return psiFile; + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + } + + public void checkCreateFile(String name) throws IncorrectOperationException { + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + FileType type = fileTypeManager.getFileTypeByFileName(name); +/* [dsl] now it is possible to create a Java file outside source path. + if (type == FileType.JAVA) { + if (getPackage() == null){ + throw new IncorrectOperationException("Cannot create java-files outside sourcepath"); + } + } + else +*/ + if (type == StdFileTypes.CLASS) { + throw new IncorrectOperationException("Cannot create class-file"); + } + + VirtualFile existingFile = getVirtualFile().findChild(name); + if (existingFile != null) { + throw new IncorrectOperationException( + "Cannot create file - file \"" + existingFile.getPresentableUrl() + "\" already exists."); + } + CheckUtil.checkWritable(this); + } + + public boolean isSourceRoot() { + if (myFile == null) return false; + final VirtualFile sourceRoot = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getSourceRootForFile(myFile); + return myFile.equals(sourceRoot); + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + checkAdd(element); + if (element instanceof PsiDirectory) { + LOG.error("not implemented"); + return null; + } + else if (element instanceof PsiFile) { + PsiFile originalFile = (PsiFile)element; + + try { + VirtualFile newVFile; + if (originalFile instanceof com.intellij.psi.impl.source.PsiFileImpl) { + newVFile = myFile.createChildData(myManager, originalFile.getName()); + String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(newVFile, getProject()); + String text = originalFile.getText(); + if (!lineSeparator.equals("\n")) { + text = StringUtil.convertLineSeparators(text, lineSeparator); + } + Writer writer = newVFile.getWriter(myManager); //? + writer.write(text); + writer.close(); + } + else { + byte[] storedContents = ((PsiBinaryFileImpl)originalFile).getStoredContents(); + if (storedContents != null) { + newVFile = myFile.createChildData(myManager, originalFile.getName()); + OutputStream out = newVFile.getOutputStream(myManager); + out.write(storedContents); + out.close(); + } + else { + newVFile = VfsUtil.copyFile(null, originalFile.getVirtualFile(), myFile); + } + } + PsiDocumentManager.getInstance(myManager.getProject()).commitAllDocuments(); + + PsiFile newFile = myManager.findFile(newVFile); + if (newFile instanceof com.intellij.psi.impl.source.PsiFileImpl) { + ChangeUtil.encodeInformation(SourceTreeToPsiMap.psiElementToTree(newFile)); + PsiUtil.updatePackageStatement(newFile); + ChangeUtil.decodeInformation(SourceTreeToPsiMap.psiElementToTree(newFile)); + } + + return newFile; + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + } + else if (element instanceof PsiClass) { + if (element.getParent() instanceof PsiJavaFile) { + PsiJavaFile newFile = (PsiJavaFile)add(element.getParent()); + PsiClass[] classes = ((PsiJavaFile)element.getParent()).getClasses(); + PsiClass[] newClasses = newFile.getClasses(); + LOG.assertTrue(classes.length == newClasses.length); + for (int i = 0; i < classes.length; i++) { + if (classes[i] == element) return newClasses[i]; + } + LOG.assertTrue(false); + return null; + } + else { + LOG.error("not implemented"); + return null; + } + } + else { + LOG.assertTrue(false); + return null; + } + } + + public void checkAdd(PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + if (element instanceof PsiDirectory) { + String name = ((PsiDirectory)element).getName(); + PsiDirectory[] subpackages = getSubdirectories(); + for (int i = 0; i < subpackages.length; i++) { + PsiDirectory dir = subpackages[i]; + if (dir.getName().equals(name)) { + throw new IncorrectOperationException( + "File " + dir.getVirtualFile().getPresentableUrl() + " already exists."); + } + } + } + else if (element instanceof PsiFile) { + String name = ((PsiFile)element).getName(); + PsiFile[] files = getFiles(); + for (int i = 0; i < files.length; i++) { + PsiFile file = files[i]; + if (file.getName().equals(name)) { + throw new IncorrectOperationException( + "File " + file.getVirtualFile().getPresentableUrl() + " already exists."); + } + } + } + else if (element instanceof PsiClass) { + if (element.getParent() instanceof PsiFile) { + checkAdd(element.getParent()); + } + else { + LOG.error("not implemented"); + } + } + else { + throw new IncorrectOperationException(); + } + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void delete() throws IncorrectOperationException { + checkDelete(); + //PsiDirectory parent = getParentDirectory(); + + /* + PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); + event.setParent(parent); + event.setChild(this); + myManager.beforeChildRemoval(event); + */ + + try { + myFile.delete(myManager); + } + catch (IOException e) { + throw new IncorrectOperationException(e.toString()); + } + + /* + //TODO : allow undo + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parent); + treeEvent.setChild(this); + treeEvent.setUndoableAction(null); + myManager.childRemoved(treeEvent); + */ + } + + public void checkDelete() throws IncorrectOperationException { + CheckUtil.checkDelete(myFile); + } + + /** + * @not_implemented + */ + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + LOG.error("not implemented"); + return null; + } + + /** + * @not_implemented + */ + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + LOG.error("not implemented"); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDirectory(this); + } + + public String toString() { + return "PsiDirectory:" + myFile.getPresentableUrl(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiFileImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiFileImplUtil.java new file mode 100644 index 00000000000..12f9c6da2ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiFileImplUtil.java @@ -0,0 +1,63 @@ +package com.intellij.psi.impl.file; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.IncorrectOperationException; + +import java.io.IOException; + +public class PsiFileImplUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.PsiFileImplUtil"); + + public static PsiFile setName(final PsiFile file, String newName) throws IncorrectOperationException { + VirtualFile vFile = file.getVirtualFile(); + PsiManagerImpl manager = (PsiManagerImpl)file.getManager(); + + try{ + vFile.rename(manager, newName); + } + catch(IOException e){ + throw new IncorrectOperationException(e.toString()); + } + return manager.findFile(vFile); + } + + public static void checkSetName(PsiFile file, String name) throws IncorrectOperationException { + VirtualFile vFile = file.getVirtualFile(); + VirtualFile parentFile = vFile.getParent(); + if (parentFile == null) return; + VirtualFile child = parentFile.findChild(name); + if (child != null && !child.equals(vFile)){ + throw new IncorrectOperationException("File " + child.getPresentableUrl() + " already exists."); + } + } + + public static void doDelete(final PsiFile file) throws IncorrectOperationException { + final PsiManagerImpl manager = (PsiManagerImpl)file.getManager(); + + final VirtualFile vFile = file.getVirtualFile(); + try{ + vFile.delete(manager); + } + catch(IOException e){ + throw new IncorrectOperationException(e.toString()); + } + } + + public static PsiFile[] getPsiFilesByVirtualFiles(VirtualFile[] files, PsiManager manager) { + PsiFile[] psiFiles = new PsiFile[files.length]; + for (int i = 0; i < files.length; i++) { + VirtualFile file = files[i]; + PsiFile psiFile = manager.findFile(file); + if (psiFile == null) { + LOG.error("psiFile==null:" + file); + continue; + } + psiFiles[i] = psiFile; + } + return psiFiles; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiPackageImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiPackageImpl.java new file mode 100644 index 00000000000..ce1db1091c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/PsiPackageImpl.java @@ -0,0 +1,432 @@ +package com.intellij.psi.impl.file; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.command.undo.UnexpectedUndoException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.PsiElementBase; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class PsiPackageImpl extends PsiElementBase implements PsiPackage { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.PsiPackageImpl"); + + private final PsiManagerImpl myManager; + private final String myQualifiedName; + + public PsiPackageImpl(PsiManagerImpl manager, String qualifiedName) { + myManager = manager; + myQualifiedName = qualifiedName; + } + + public boolean equals(Object o) { + if (o instanceof PsiPackageImpl) { + return myManager == ((PsiPackageImpl)o).myManager && myQualifiedName.equals(((PsiPackageImpl)o).myQualifiedName); + } + return false; + } + + public int hashCode() { + return myQualifiedName.hashCode(); + } + + public String getQualifiedName() { + return myQualifiedName; + } + + public PsiDirectory[] getDirectories() { + return getDirectories(GlobalSearchScope.allScope(myManager.getProject())); + } + + public PsiDirectory[] getDirectories(GlobalSearchScope scope) { + FileIndex projectFileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); + VirtualFile[] dirs = projectFileIndex.getDirectoriesByPackageName(myQualifiedName, false); + ArrayList list = new ArrayList(); + for (int i = 0; i < dirs.length; i++) { + VirtualFile dir = dirs[i]; + if (!scope.contains(dir)) continue; + PsiDirectory psiDir = myManager.findDirectory(dir); + LOG.assertTrue(psiDir != null); + list.add(psiDir); + } + return list.toArray(new PsiDirectory[list.size()]); + } + + public String getName() { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + if (myQualifiedName.length() == 0) return null; + int index = myQualifiedName.lastIndexOf('.'); + if (index < 0) { + return myQualifiedName; + } + else { + return myQualifiedName.substring(index + 1); + } + } + + public PsiElement setName(String name) throws IncorrectOperationException { + checkSetName(name); + PsiDirectory[] dirs = getDirectories(); + for (int i = 0; i < dirs.length; i++) { + dirs[i].setName(name); + } + return this; + } + + public void checkSetName(String name) throws IncorrectOperationException { + PsiDirectory[] dirs = getDirectories(); + for (int i = 0; i < dirs.length; i++) { + dirs[i].checkSetName(name); + } + } + + public void handleQualifiedNameChange(final String newQualifiedName) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + final String oldQualifedName = myQualifiedName; + final boolean anyChanged = changePackagePrefixes(oldQualifedName, newQualifiedName); + if (anyChanged) { + UndoManager.getInstance(myManager.getProject()).undoableActionPerformed(new UndoableAction() { + public void undo() throws UnexpectedUndoException { + changePackagePrefixes(newQualifiedName, oldQualifedName); + } + + public void redo() throws UnexpectedUndoException { + changePackagePrefixes(oldQualifedName, newQualifiedName); + } + + public DocumentReference[] getAffectedDocuments() { + return new DocumentReference[0]; + } + + public boolean isComplex() { + return true; + } + }); + } + } + + private boolean changePackagePrefixes(final String oldQualifiedName, final String newQualifiedName) { + final Module[] modules = ModuleManager.getInstance(myManager.getProject()).getModules(); + List modelsToCommit = new ArrayList(); + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + boolean anyChange = false; + final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel(); + final ContentEntry[] contentEntries = rootModel.getContentEntries(); + for (int j = 0; j < contentEntries.length; j++) { + final ContentEntry contentEntry = contentEntries[j]; + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int k = 0; k < sourceFolders.length; k++) { + final SourceFolder sourceFolder = sourceFolders[k]; + final String packagePrefix = sourceFolder.getPackagePrefix(); + if (packagePrefix.startsWith(oldQualifiedName)) { + sourceFolder.setPackagePrefix(newQualifiedName + packagePrefix.substring(oldQualifiedName.length())); + anyChange = true; + } + } + } + if (anyChange) { + modelsToCommit.add(rootModel); + } + } + + if (!modelsToCommit.isEmpty()) { + ProjectRootManager.getInstance(myManager.getProject()).multiCommit( + modelsToCommit.toArray(new ModifiableRootModel[modelsToCommit.size()]) + ); + return true; + } else { + return false; + } + } + + public VirtualFile[] occursInPackagePrefixes() { + List result = new ArrayList(); + final Module[] modules = ModuleManager.getInstance(myManager.getProject()).getModules(); + + for (int i = 0; i < modules.length; i++) { + final Module module = modules[i]; + final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries(); + for (int j = 0; j < contentEntries.length; j++) { + final ContentEntry contentEntry = contentEntries[j]; + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (int k = 0; k < sourceFolders.length; k++) { + final SourceFolder sourceFolder = sourceFolders[k]; + final String packagePrefix = sourceFolder.getPackagePrefix(); + if (packagePrefix.startsWith(myQualifiedName)) { + final VirtualFile file = sourceFolder.getFile(); + if (file != null) { + result.add(file); + } + } + } + } + } + + return result.toArray(new VirtualFile[result.size()]); + } + + public PsiPackage getParentPackage() { + if (myQualifiedName.length() == 0) return null; + int lastDot = myQualifiedName.lastIndexOf('.'); + if (lastDot < 0) { + return new PsiPackageImpl(myManager, ""); + } + else { + return new PsiPackageImpl(myManager, myQualifiedName.substring(0, lastDot)); + } + } + + public PsiManager getManager() { + return myManager; + } + + public PsiElement[] getChildren() { + LOG.error("method not implemented"); + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getParent() { + return getParentPackage(); + } + + public PsiFile getContainingFile() { + return null; + } + + public TextRange getTextRange() { + return null; + } + + public int getStartOffsetInParent() { + return -1; + } + + public int getTextLength() { + return -1; + } + + public PsiElement findElementAt(int offset) { + return null; + } + + public int getTextOffset() { + return -1; + } + + public String getText() { + return null; + } + + public char[] textToCharArray() { + return null; + } + + public boolean textMatches(CharSequence text) { + return false; + } + + public boolean textMatches(PsiElement element) { + return false; + } + + public PsiElement copy() { + LOG.error("method not implemented"); + return null; + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAdd(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void delete() throws IncorrectOperationException { + checkDelete(); + PsiDirectory[] dirs = getDirectories(); + for (int i = 0; i < dirs.length; i++) { + dirs[i].delete(); + } + } + + public void checkDelete() throws IncorrectOperationException { + PsiDirectory[] dirs = getDirectories(); + for (int i = 0; i < dirs.length; i++) { + dirs[i].checkDelete(); + } + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public boolean isValid() { + return getDirectories().length > 0; + } + + public boolean isWritable() { + PsiDirectory[] dirs = getDirectories(); + for (int i = 0; i < dirs.length; i++) { + PsiDirectory dir = dirs[i]; + if (!dir.isWritable()) return false; + } + return true; + } + + public T getUserData(Key key) { + return null; + } + + public void putUserData(Key key, T value) { + throw new RuntimeException("PsiPackage is not peresisitent. Cannot store user data in it."); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPackage(this); + } + + public String toString() { + return "PsiPackage:" + getQualifiedName(); + } + + public PsiClass[] getClasses() { + return getClasses(GlobalSearchScope.allScope(myManager.getProject())); + } + + public PsiClass[] getClasses(GlobalSearchScope scope) { + return myManager.getClasses(this, scope); + } + + public PsiPackage[] getSubPackages() { + return getSubPackages(GlobalSearchScope.allScope(myManager.getProject())); + } + + public PsiPackage[] getSubPackages(GlobalSearchScope scope) { + return myManager.getSubPackages(this, scope); + } + + private PsiClass findClassByName(String name, GlobalSearchScope scope) { + final String qName = getQualifiedName(); + final String classQName = qName.length() > 0 ? qName + "." + name : name; + return myManager.findClass(classQName, scope); + } + + private PsiPackage findSubPackageByName(String name, GlobalSearchScope scope) { + final String qName = getQualifiedName(); + final String subpackageQName = qName.length() > 0 ? qName + "." + name : name; + PsiPackage aPackage = myManager.findPackage(subpackageQName); + if (aPackage == null) return null; + if (aPackage.getDirectories(scope).length == 0) return null; + return aPackage; + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + GlobalSearchScope scope = place.getResolveScope(); + + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + ElementClassHint classHint = processor.getHint(ElementClassHint.class); + + if (classHint == null || classHint.shouldProcess(PsiClass.class)) { + NameHint nameHint = processor.getHint(NameHint.class); + if (nameHint != null) { + final PsiClass aClass = findClassByName(nameHint.getName(), scope); + if (aClass != null) { + if (!processor.execute(aClass, substitutor)) return false; + } + } + else { + PsiClass[] classes = getClasses(scope); + for (int i = 0; i < classes.length; i++) { + if (!processor.execute(classes[i], substitutor)) { + return false; + } + } + if (myManager.getCurrentMigration() != null) { + final Iterator migrationClasses = myManager.getCurrentMigration().getMigrationClasses(getQualifiedName()); + while (migrationClasses.hasNext()) { + PsiClass psiClass = migrationClasses.next(); + if (!processor.execute(psiClass, substitutor)) { + return false; + } + } + } + } + } + if (classHint == null || classHint.shouldProcess(PsiPackage.class)) { + NameHint nameHint = processor.getHint(NameHint.class); + if (nameHint != null) { + PsiPackage aPackage = findSubPackageByName(nameHint.getName(), scope); + if (aPackage != null) { + if (!processor.execute(aPackage, substitutor)) return false; + } + } + else { + PsiPackage[] packs = getSubPackages(scope); + for (int i = 0; i < packs.length; i++) { + if (!processor.execute(packs[i], substitutor)) { + return false; + } + } + if (myManager.getCurrentMigration() != null) { + final Iterator migrationClasses = myManager.getCurrentMigration().getMigrationPackages(getQualifiedName()); + while (migrationClasses.hasNext()) { + PsiPackage psiPackage = migrationClasses.next(); + if (!processor.execute(psiPackage, substitutor)) { + return false; + } + } + } + } + } + return true; + } + + public boolean isPhysical() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManager.java new file mode 100644 index 00000000000..a3f54b193fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManager.java @@ -0,0 +1,35 @@ +package com.intellij.psi.impl.file.impl; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; + +import java.util.List; +import java.util.Collection; + +public interface FileManager { + void dispose(); + + void runStartupActivity(); + + PsiFile findFile(VirtualFile vFile); + + PsiDirectory findDirectory(VirtualFile vFile); + + PsiPackage findPackage(String packageName); + + PsiDirectory[] getRootDirectories(int rootType); + + PsiClass findClass(String qName, GlobalSearchScope scope); + PsiClass[] findClasses(String qName, GlobalSearchScope scope); + + void reloadFromDisk(PsiFile file); //Q: move to PsiFile(Impl)? + + PsiFile getCachedPsiFile(VirtualFile vFile); + + GlobalSearchScope getResolveScope(PsiElement element); + GlobalSearchScope getUseScope(PsiElement element); + Collection getNonTrivialPackagePrefixes(); + + void cleanupForNextTest(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManagerImpl.java new file mode 100644 index 00000000000..ce0fc00e184 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -0,0 +1,1216 @@ +package com.intellij.psi.impl.file.impl; + +import com.intellij.ide.highlighter.JavaClassFileType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; +import com.intellij.openapi.fileEditor.FileDocumentManagerListener; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerConfiguration; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiTreeChangeEventImpl; +import com.intellij.psi.impl.RepositoryElementsManager; +import com.intellij.psi.impl.cache.RepositoryIndex; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.compiled.ClsFileImpl; +import com.intellij.psi.impl.file.PsiBinaryFileImpl; +import com.intellij.psi.impl.file.PsiDirectoryImpl; +import com.intellij.psi.impl.file.PsiPackageImpl; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.PsiPlainTextFileImpl; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.containers.WeakValueHashMap; + +import java.io.IOException; +import java.io.Writer; +import java.util.*; + +public class FileManagerImpl implements FileManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.impl.FileManagerImpl"); + + private final PsiManagerImpl myManager; + + private final FileTypeManager myFileTypeManager; + + private final ProjectRootManager myProjectRootManager; + private ProjectFileIndex myProjectFileIndex; + private RootManager myRootManager; + + private com.intellij.util.containers.HashMap myVFileToPsiDirMap = new com.intellij.util.containers.HashMap(); + private WeakValueHashMap myVFileToPsiFileMap = new WeakValueHashMap(); // VirtualFile --> PsiFile + + private VirtualFileListener myVirtualFileListener; + private FileDocumentManagerListener myFileDocumentManagerListener; + private ModuleRootListener myModuleRootListener; + private FileTypeListener myFileTypeListener; + private boolean myInitialized = false; + private boolean myDisposed = false; + private boolean myUseRepository = true; + + private HashMap myCachedObjectClassMap = null; + + private Map myNameToClassMap = new com.intellij.util.containers.HashMap(); // used only in mode without repository + private Map myNameToPacakageMap = new com.intellij.util.containers.HashMap(); // used only in mode without repository + private HashSet myNontrivialPackagePrefixes; + private final VirtualFileManager myVirtualFileManager; + private final FileDocumentManager myFileDocumentManager; + + public FileManagerImpl(PsiManagerImpl manager, + FileTypeManager fileTypeManager, + VirtualFileManager virtualFileManager, + FileDocumentManager fileDocumentManager, + ProjectRootManager projectRootManager) { + myFileTypeManager = fileTypeManager; + myManager = manager; + myVirtualFileManager = virtualFileManager; + myFileDocumentManager = fileDocumentManager; + myProjectRootManager = projectRootManager; + } + + public void dispose() { + if (myInitialized) { + myVirtualFileManager.removeVirtualFileListener(myVirtualFileListener); + myFileDocumentManager.removeFileDocumentManagerListener(myFileDocumentManagerListener); + myProjectRootManager.removeModuleRootListener(myModuleRootListener); + myFileTypeManager.removeFileTypeListener(myFileTypeListener); + synchronized (PsiLock.LOCK) { + myCachedObjectClassMap = null; + } + } + myDisposed = true; + } + + public void cleanupForNextTest() { + myVFileToPsiFileMap.clear(); + myVFileToPsiDirMap.clear(); + } + + public void runStartupActivity() { + LOG.assertTrue(!myInitialized); + myDisposed = false; + myInitialized = true; + + myRootManager = new RootManager(this, myProjectRootManager); + + PsiManagerConfiguration configuration = PsiManagerConfiguration.getInstance(); + myUseRepository = configuration.REPOSITORY_ENABLED; + + myProjectFileIndex = myProjectRootManager.getFileIndex(); + + Runnable runnable = new Runnable() { + public void run() { + synchronized (PsiLock.LOCK) { + myCachedObjectClassMap = null; + } + } + }; + myManager.registerRunnableToRunOnChange(runnable); + + myVirtualFileListener = new MyVirtualFileListener(); + myVirtualFileManager.addVirtualFileListener(myVirtualFileListener); + + myFileDocumentManagerListener = new FileDocumentManagerAdapter() { + public void fileWithNoDocumentChanged(VirtualFile file) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final PsiFile psiFile = myVFileToPsiFileMap.get(file); + if (psiFile != null) { + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + reloadFromDisk(psiFile, true); // important to ignore document which might appear already! + } + } + ); + } + } + }; + myFileDocumentManager.addFileDocumentManagerListener(myFileDocumentManagerListener); + + myModuleRootListener = new MyModuleRootListener(); + myProjectRootManager.addModuleRootListener(myModuleRootListener); + + myFileTypeListener = new FileTypeListener() { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(FileTypeEvent e) { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); + event.setPropertyName(PsiTreeChangeEvent.PROP_FILE_TYPES); + myManager.beforePropertyChange(event); + + removeInvalidFilesAndDirs(true); + + event = new PsiTreeChangeEventImpl(myManager); + event.setPropertyName(PsiTreeChangeEvent.PROP_FILE_TYPES); + myManager.propertyChanged(event); + } + } + ); + } + }; + myFileTypeManager.addFileTypeListener(myFileTypeListener); + } + + private void dispatchPendingEvents() { + LOG.assertTrue(myInitialized); + //LOG.assertTrue(!myDisposed); + + // [dsl]todo[max, dsl] this is a hack. MUST FIX + if (!ApplicationManager.getApplication().isDispatchThread()) return; + + myVirtualFileManager.dispatchPendingEvent(myVirtualFileListener); + myFileDocumentManager.dispatchPendingEvents(myFileDocumentManagerListener); + myProjectRootManager.dispatchPendingEvent(myModuleRootListener); + myFileTypeManager.dispatchPendingEvents(myFileTypeListener); + //TODO: other listeners + } + + // for tests + public void checkConsistency() { + Map fileToPsiFileMap = myVFileToPsiFileMap; + myVFileToPsiFileMap = new WeakValueHashMap(); + for (Iterator iterator = fileToPsiFileMap.keySet().iterator(); iterator.hasNext();) { + VirtualFile vFile = iterator.next(); + PsiFile psiFile = fileToPsiFileMap.get(vFile); + + LOG.assertTrue(vFile.isValid()); + PsiFile psiFile1 = findFile(vFile); + LOG.assertTrue(psiFile1 != null, vFile.toString()); + if (psiFile != null) { // might get collected + LOG.assertTrue(psiFile1.getClass().equals(psiFile.getClass())); + } + + VirtualFile parent = vFile.getParent(); + LOG.assertTrue(myVFileToPsiDirMap.containsKey(parent)); + } + + com.intellij.util.containers.HashMap fileToPsiDirMap = myVFileToPsiDirMap; + myVFileToPsiDirMap = new com.intellij.util.containers.HashMap(); + for (Iterator iterator = fileToPsiDirMap.keySet().iterator(); iterator.hasNext();) { + VirtualFile vFile = iterator.next(); + + LOG.assertTrue(vFile.isValid()); + PsiDirectory psiDir1 = findDirectory(vFile); + LOG.assertTrue(psiDir1 != null); + + VirtualFile parent = vFile.getParent(); + if (parent != null) { + LOG.assertTrue(myVFileToPsiDirMap.containsKey(parent)); + } + } + } + + public PsiFile findFile(VirtualFile vFile) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + if (vFile == null) { + LOG.assertTrue(false); + return null; + } + LOG.assertTrue(vFile.isValid()); + + dispatchPendingEvents(); + + synchronized (PsiLock.LOCK) { + PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + if (psiFile != null) return psiFile; + + psiFile = createPsiFile(vFile, vFile.getName()); + if (psiFile == null) return null; + + myVFileToPsiFileMap.put(vFile, psiFile); + return psiFile; + } + } + + public PsiFile getCachedPsiFile(VirtualFile vFile) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + LOG.assertTrue(vFile.isValid()); + LOG.assertTrue(!myDisposed); + if (!myInitialized) return null; + + dispatchPendingEvents(); + + synchronized (PsiLock.LOCK) { + return myVFileToPsiFileMap.get(vFile); + } + } + + public GlobalSearchScope getResolveScope(PsiElement element) { + VirtualFile vFile; + if (element instanceof PsiDirectory) { + vFile = ((PsiDirectory)element).getVirtualFile(); + } + else { + final PsiFile contextFile = ResolveUtil.getContextFile(element); + if (contextFile == null || contextFile instanceof XmlFile) { + return GlobalSearchScope.allScope(myManager.getProject()); + } + vFile = contextFile.getVirtualFile(); + if (vFile == null) { + PsiFile originalFile = contextFile.getOriginalFile(); + if (originalFile != null) { + vFile = originalFile.getVirtualFile(); + } + } + } + if (vFile == null) { + return GlobalSearchScope.allScope(myManager.getProject()); + } + + ProjectFileIndex projectFileIndex = myProjectRootManager.getFileIndex(); + Module module = projectFileIndex.getModuleForFile(vFile); + if (module != null) { + boolean includeTests = projectFileIndex.isInTestSourceContent(vFile) || + !projectFileIndex.isContentJavaSourceFile(vFile); + return GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, includeTests); + } + else { + // resolve references in libraries in any module which contain it + //TODO: exclude project content + OrderEntry[] orderEntries = projectFileIndex.getOrderEntriesForFile(vFile); + if (orderEntries.length == 0) return GlobalSearchScope.allScope(myManager.getProject()); + Module ownerModule = orderEntries[0].getOwnerModule(); + return GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(ownerModule); + } + } + + public GlobalSearchScope getUseScope(PsiElement element) { + VirtualFile vFile; + if (element instanceof PsiDirectory) { + vFile = ((PsiDirectory)element).getVirtualFile(); + } + else { + final PsiFile containingFile = element.getContainingFile(); + if (containingFile == null) return GlobalSearchScope.allScope(myManager.getProject()); + final VirtualFile virtualFile = containingFile.getVirtualFile(); + if (virtualFile == null) return GlobalSearchScope.allScope(myManager.getProject()); + vFile = virtualFile.getParent(); + } + + if (vFile == null) return null; + ProjectFileIndex projectFileIndex = myProjectRootManager.getFileIndex(); + Module module = projectFileIndex.getModuleForFile(vFile); + if (module != null) { + boolean isTest = projectFileIndex.isInTestSourceContent(vFile); + return isTest + ? GlobalSearchScope.moduleTestsWithDependentsScope(module) + : GlobalSearchScope.moduleWithDependentsScope(module); + } + else { + return GlobalSearchScope.allScope(myManager.getProject()); + } + } + + public Collection getNonTrivialPackagePrefixes() { + if (myNontrivialPackagePrefixes == null) { + myNontrivialPackagePrefixes = new HashSet(); + final ProjectRootManager rootManager = myProjectRootManager; + final VirtualFile[] sourceRoots = rootManager.getContentSourceRoots(); + final ProjectFileIndex fileIndex = rootManager.getFileIndex(); + for (int i = 0; i < sourceRoots.length; i++) { + final VirtualFile sourceRoot = sourceRoots[i]; + final String packageName = fileIndex.getPackageNameByDirectory(sourceRoot); + if (packageName != null && packageName.length() > 0) { + myNontrivialPackagePrefixes.add(packageName); + } + } + } + return myNontrivialPackagePrefixes; + } + + private PsiFile createPsiFile(VirtualFile vFile, String name) { + if (vFile.isDirectory()) return null; + if (myFileTypeManager.isFileIgnored(name)) return null; // cannot use ProjectFileIndex because of "name"! + + VirtualFile parent = vFile.getParent(); + if (parent == null) return null; + PsiDirectory psiDir = findDirectory(parent); // need to cache parent directory - used for firing events + if (psiDir == null) return null; + + FileType fileType = myFileTypeManager.getFileTypeByFileName(name); + PsiFile psiFile = fileType.createPsiFile(vFile, myManager.getProject()); + if (psiFile == null) { + // a bit hacky. + if (fileType instanceof JavaClassFileType) return null; + + if (fileType.isBinary()) { + psiFile = new PsiBinaryFileImpl(myManager, vFile); + } + else { + psiFile = new PsiPlainTextFileImpl(myManager, vFile); + } + } + return psiFile; + } + + public PsiDirectory findDirectory(VirtualFile vFile) { + LOG.assertTrue(myInitialized, "Access to psi files should be performed only after startup activity"); + LOG.assertTrue(!myDisposed); + + ApplicationManager.getApplication().assertReadAccessAllowed(); + LOG.assertTrue(vFile.isValid()); + + if (!vFile.isDirectory()) return null; + + dispatchPendingEvents(); + + synchronized (PsiLock.LOCK) { + PsiDirectory psiDir = myVFileToPsiDirMap.get(vFile); + if (psiDir != null) return psiDir; + + if (myProjectRootManager.getFileIndex().isIgnored(vFile)) return null; + + VirtualFile parent = vFile.getParent(); + if (parent != null) { //? + findDirectory(parent);// need to cache parent directory - used for firing events + } + psiDir = new PsiDirectoryImpl(myManager, vFile); + myVFileToPsiDirMap.put(vFile, psiDir); + return psiDir; + } + } + + public PsiPackage findPackage(String packageName) { + VirtualFile[] dirs = myProjectRootManager.getFileIndex().getDirectoriesByPackageName(packageName, false); + if (dirs.length == 0) return null; + return new PsiPackageImpl(myManager, packageName); + } + + public PsiDirectory[] getRootDirectories(int rootType) { + return myRootManager.getRootDirectories(rootType); + } + + public PsiClass[] findClasses(String qName, GlobalSearchScope scope) { + RepositoryManager repositoryManager = myManager.getRepositoryManager(); + long[] classIds = repositoryManager.getIndex().getClassesByQualifiedName(qName, null); + if (classIds.length == 0) return PsiClass.EMPTY_ARRAY; + + ArrayList result = new ArrayList(); + for (int i = 0; i < classIds.length; i++) { + long classId = classIds[i]; + PsiClass aClass = (PsiClass)myManager.getRepositoryElementsManager().findOrCreatePsiElementById(classId); + VirtualFile vFile = aClass.getContainingFile().getVirtualFile(); + if (scope.contains(vFile)) { + result.add(aClass); + } + } + return result.toArray(new PsiClass[result.size()]); + } + + public PsiClass findClass(String qName, GlobalSearchScope scope) { + if (!myUseRepository) { + return findClassWithoutRepository(qName); + } + + if (!myInitialized) { + LOG.error("Access to psi files should be performed only after startup activity"); + return null; + } + LOG.assertTrue(!myDisposed); + + if ("java.lang.Object".equals(qName)) { // optimization + synchronized (PsiLock.LOCK) { + if (myCachedObjectClassMap == null) { + myCachedObjectClassMap = new HashMap(); + + Module[] modules = ModuleManager.getInstance(myManager.getProject()).getModules(); + for (int i = 0; i < modules.length; i++) { + Module aModule = modules[i]; + GlobalSearchScope moduleScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(aModule); + PsiClass objectClass = _findClass(qName, moduleScope); + myCachedObjectClassMap.put(moduleScope, objectClass); + } + + GlobalSearchScope allScope = GlobalSearchScope.allScope(myManager.getProject()); + PsiClass objectClass = _findClass(qName, allScope); + myCachedObjectClassMap.put(allScope, objectClass); + } + final PsiClass cachedClass = myCachedObjectClassMap.get(scope); + return cachedClass == null ? _findClass(qName, scope) : cachedClass; + } + } + + return _findClass(qName, scope); + } + + private PsiClass findClassWithoutRepository(String qName) { + synchronized (PsiLock.LOCK) { + if (myNameToClassMap.containsKey(qName)) return myNameToClassMap.get(qName); + + PsiClass aClass = _findClassWithoutRepository(qName); + myNameToClassMap.put(qName, aClass); + return aClass; + } + } + + private PsiClass _findClassWithoutRepository(String qName) { + PsiClass aClass = myNameToClassMap.get(qName); + if (aClass != null) return aClass; + + VirtualFile[] sourcePath = myRootManager.getSourceRootsCopy(); + VirtualFile[] classPath = myRootManager.getClassRootsCopy(); + + int index = 0; + while (index < qName.length()) { + int index1 = qName.indexOf('.', index); + if (index1 < 0) { + index1 = qName.length(); + } + String name = qName.substring(index, index1); + + final int sourceType = 0; + //final int compiledType = 1; + + for (int type = 0; type < 2; type++) { + VirtualFile[] vDirs = type == sourceType ? sourcePath : classPath; + for (int i = 0; i < vDirs.length; i++) { + if (vDirs[i] != null) { + VirtualFile vChild = type == sourceType + ? vDirs[i].findChild(name + ".java") + : vDirs[i].findChild(name + ".class"); + if (vChild != null) { + PsiFile file = findFile(vChild); + if (file instanceof PsiJavaFile) { + aClass = findClassByName((PsiJavaFile)file, name); + if (aClass != null) { + index = index1 + 1; + while (index < qName.length()) { + index1 = qName.indexOf('.', index); + if (index1 < 0) { + index1 = qName.length(); + } + name = qName.substring(index, index1); + aClass = findClassByName(aClass, name); + if (aClass == null) return null; + index = index1 + 1; + } + return aClass; + } + } + } + } + } + } + + boolean existsDir = false; + for (int type = 0; type < 2; type++) { + VirtualFile[] vDirs = type == sourceType ? sourcePath : classPath; + for (int i = 0; i < vDirs.length; i++) { + if (vDirs[i] != null) { + VirtualFile vDirChild = vDirs[i].findChild(name); + if (vDirChild != null) { + PsiDirectory dir = findDirectory(vDirChild); + if (dir != null) { + vDirs[i] = vDirChild; + existsDir = true; + continue; + } + } + vDirs[i] = null; + } + } + } + if (!existsDir) return null; + index = index1 + 1; + } + return null; + } + + private static PsiClass findClassByName(PsiJavaFile scope, String name) { + PsiClass[] classes = scope.getClasses(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + if (aClass.getName().equals(name)) { + return aClass; + } + } + return null; + } + + private static PsiClass findClassByName(PsiClass scope, String name) { + PsiClass[] classes = scope.getInnerClasses(); + for (int i = 0; i < classes.length; i++) { + PsiClass aClass = classes[i]; + if (aClass.getName().equals(name)) { + return aClass; + } + } + return null; + } + + private PsiClass _findClass(String qName, GlobalSearchScope scope) { + RepositoryManager repositoryManager = myManager.getRepositoryManager(); + RepositoryIndex index = repositoryManager.getIndex(); + VirtualFileFilter rootFilter = null;//index.rootFilterBySearchScope(scope); + long[] classIds = index.getClassesByQualifiedName(qName, rootFilter); + if (classIds.length == 0) return null; + + RepositoryElementsManager repositoryElementsManager = myManager.getRepositoryElementsManager(); + VirtualFile bestFile = null; + PsiClass bestClass = null; + for (int i = 0; i < classIds.length; i++) { + long classId = classIds[i]; + PsiClass aClass = (PsiClass)repositoryElementsManager.findOrCreatePsiElementById(classId); + LOG.assertTrue(aClass != null); + LOG.assertTrue(aClass.isValid()); + PsiFile file = aClass.getContainingFile(); + if (file == null){ + LOG.error("aClass=" + aClass); + continue; + } + VirtualFile vFile = file.getVirtualFile(); + if (!scope.contains(vFile)) continue; + if (bestFile == null || scope.compare(vFile, bestFile) > 0) { + bestFile = vFile; + bestClass = aClass; + } + } + return bestClass; + } + + private void removeInvalidFilesAndDirs(boolean useFind) { + com.intellij.util.containers.HashMap fileToPsiDirMap = myVFileToPsiDirMap; + if (useFind) { + myVFileToPsiDirMap = new com.intellij.util.containers.HashMap(); + } + for (Iterator iterator = fileToPsiDirMap.keySet().iterator(); iterator.hasNext();) { + VirtualFile vFile = iterator.next(); + if (!vFile.isValid()) { + iterator.remove(); + continue; + } + + PsiDirectory psiDir = findDirectory(vFile); + if (psiDir == null) { + iterator.remove(); + continue; + } + } + myVFileToPsiDirMap = fileToPsiDirMap; + + // note: important to update directories map first - findFile uses findDirectory! + WeakValueHashMap fileToPsiFileMap = myVFileToPsiFileMap; + if (useFind) { + myVFileToPsiFileMap = new WeakValueHashMap(); + } + for (Iterator iterator = fileToPsiFileMap.keySet().iterator(); iterator.hasNext();) { + VirtualFile vFile = iterator.next(); + + if (!vFile.isValid()) { + iterator.remove(); + continue; + } + + if (useFind) { + PsiFile psiFile = fileToPsiFileMap.get(vFile); + if (psiFile == null) { // soft ref. collected + iterator.remove(); + continue; + } + PsiFile psiFile1 = findFile(vFile); + if (psiFile1 == null) { + iterator.remove(); + continue; + } + + if (!psiFile1.getClass().equals(psiFile.getClass())) { + iterator.remove(); + continue; + } + } + } + myVFileToPsiFileMap = fileToPsiFileMap; + } + + public void reloadFromDisk(PsiFile file) { + reloadFromDisk(file, false); + } + + private void reloadFromDisk(PsiFile file, boolean ignoreDocument) { + VirtualFile vFile = file.getVirtualFile(); + + if (file instanceof PsiBinaryFile) { + file.setModificationStamp(vFile.getModificationStamp()); + } + else { + FileDocumentManager fileDocumentManager = myFileDocumentManager; + Document document = fileDocumentManager.getCachedDocument(vFile); + if (document != null && !ignoreDocument){ + fileDocumentManager.reloadFromDisk(document); + } + else{ + PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); + event.setParent(file); + event.setFile(file); + if (file instanceof PsiFileImpl && ((PsiFileImpl)file).isContentsLoaded()) { + event.setOffset(0); + event.setOldLength(file.getTextLength()); + } + myManager.beforeChildrenChange(event); + + if (file instanceof PsiFileImpl) { + PsiFileImpl fileImpl = (PsiFileImpl)file; + fileImpl.subtreeChanged(); // important! otherwise cached information is not released + if (fileImpl.isContentsLoaded()) { + ((PsiFileImpl)file).unloadContent(); + } + } + else if (file instanceof ClsFileImpl) { + if (((ClsFileImpl)file).isContentsLoaded()) { + ((ClsFileImpl)file).unloadContent(); + } + } + file.setModificationStamp(vFile.getModificationStamp()); + + myManager.childrenChanged(event); + } + } + } + + private void clearNonRepositoryMaps() { + myNameToClassMap.clear(); + myNameToPacakageMap.clear(); + } + + private class MyVirtualFileListener extends VirtualFileAdapter { + public void contentsChanged(final VirtualFileEvent event) { + // handled by FileDocumentManagerListener + } + + public void fileCreated(VirtualFileEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final VirtualFile vFile = event.getFile(); + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiDirectory parentDir = myVFileToPsiDirMap.get(vFile.getParent()); + if (parentDir == null) return; // do not notifyListeners event if parent directory was never accessed via PSI + + if (!vFile.isDirectory()) { + PsiFile psiFile = findFile(vFile); + if (psiFile != null) { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + myManager.beforeChildAddition(treeEvent); + treeEvent.setChild(psiFile); + myManager.childAdded(treeEvent); + } + } + else { + PsiDirectory psiDir = findDirectory(vFile); + if (psiDir != null) { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + myManager.beforeChildAddition(treeEvent); + treeEvent.setChild(psiDir); + myManager.childAdded(treeEvent); + } + } + } + } + ); + } + + public void beforeFileDeletion(VirtualFileEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final VirtualFile vFile = event.getFile(); + + final PsiDirectory parentDir = myVFileToPsiDirMap.get(vFile.getParent()); + if (parentDir == null) return; // do not notify listeners if parent directory was never accessed via PSI + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + if (!vFile.isDirectory()) { + PsiFile psiFile = findFile(vFile); + if (psiFile != null) { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + treeEvent.setChild(psiFile); + myManager.beforeChildRemoval(treeEvent); + } + } + else { + PsiDirectory psiDir = findDirectory(vFile); + if (psiDir != null) { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + treeEvent.setChild(psiDir); + myManager.beforeChildRemoval(treeEvent); + } + } + } + } + ); + } + + public void fileDeleted(final VirtualFileEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final VirtualFile vFile = event.getFile(); + + final PsiDirectory parentDir = myVFileToPsiDirMap.get(event.getParent()); + + if (!event.isDirectory()) { + final PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + if (psiFile != null) { + myVFileToPsiFileMap.remove(vFile); + + if (parentDir != null) { + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + treeEvent.setChild(psiFile); + myManager.childRemoved(treeEvent); + } + } + ); + } + } + } + else { + final PsiDirectory psiDir = myVFileToPsiDirMap.get(vFile); + if (psiDir != null) { + removeInvalidFilesAndDirs(false); + + if (parentDir != null) { + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + treeEvent.setChild(psiDir); + myManager.childRemoved(treeEvent); + } + } + ); + } + } + } + } + + public void beforePropertyChange(final VirtualFilePropertyEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final VirtualFile vFile = event.getFile(); + final String propertyName = event.getPropertyName(); + + final PsiDirectory parentDir = myVFileToPsiDirMap.get(vFile.getParent()); + if (parentDir == null) return; // do not notifyListeners event if parent directory was never accessed via PSI + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + + if (VirtualFile.PROP_NAME.equals(propertyName)) { + final String newName = (String)event.getNewValue(); + + if (vFile.isDirectory()) { + PsiDirectory psiDir = findDirectory(vFile); + if (psiDir != null) { + if (!myFileTypeManager.isFileIgnored(newName)) { + treeEvent.setChild(psiDir); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME); + treeEvent.setOldValue(vFile.getName()); + treeEvent.setNewValue(newName); + myManager.beforePropertyChange(treeEvent); + } + else { + treeEvent.setChild(psiDir); + myManager.beforeChildRemoval(treeEvent); + } + } + else { + if (!isExcludeRoot(vFile) && !myFileTypeManager.isFileIgnored(newName)) { + myManager.beforeChildAddition(treeEvent); + } + } + } + else { + PsiFile psiFile = findFile(vFile); + PsiFile psiFile1 = createPsiFile(vFile, newName); + + if (psiFile != null) { + if (psiFile1 == null) { + treeEvent.setChild(psiFile); + myManager.beforeChildRemoval(treeEvent); + } + else if (!psiFile1.getClass().equals(psiFile.getClass())) { + treeEvent.setOldChild(psiFile); + myManager.beforeChildReplacement(treeEvent); + } + else { + treeEvent.setChild(psiFile); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_FILE_NAME); + treeEvent.setOldValue(vFile.getName()); + treeEvent.setNewValue(newName); + myManager.beforePropertyChange(treeEvent); + } + } + else { + if (psiFile1 != null) { + myManager.beforeChildAddition(treeEvent); + } + } + } + } + else if (VirtualFile.PROP_WRITABLE.equals(propertyName)) { + PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + if (psiFile == null) return; + + treeEvent.setElement(psiFile); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_WRITABLE); + treeEvent.setOldValue(event.getOldValue()); + treeEvent.setNewValue(event.getNewValue()); + myManager.beforePropertyChange(treeEvent); + } + } + } + ); + } + + private boolean isExcludeRoot(VirtualFile file) { + VirtualFile parent = file.getParent(); + Module module = myProjectRootManager.getFileIndex().getModuleForFile(parent); + if (module == null) return false; + VirtualFile[] excludeRoots = ModuleRootManager.getInstance(module).getExcludeRoots(); + for (int i = 0; i < excludeRoots.length; i++) { + VirtualFile root = excludeRoots[i]; + if (root.equals(file)) return true; + } + return false; + } + + public void propertyChanged(final VirtualFilePropertyEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final String propertyName = event.getPropertyName(); + final VirtualFile vFile = event.getFile(); + + final PsiDirectory parentDir = myVFileToPsiDirMap.get(vFile.getParent()); + if (parentDir == null) { + boolean fire = VirtualFile.PROP_NAME.equals(propertyName) && + vFile.isDirectory(); + if (fire) { + PsiDirectory psiDir = myVFileToPsiDirMap.get(vFile); + fire = psiDir != null; + } + if (!fire) return; // do not fire event if parent directory was never accessed via PSI + } + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setParent(parentDir); + + if (VirtualFile.PROP_NAME.equals(propertyName)) { + if (vFile.isDirectory()) { + PsiDirectory psiDir = myVFileToPsiDirMap.get(vFile); + if (psiDir != null) { + if (myFileTypeManager.isFileIgnored(vFile.getName())) { + removeFilesAndDirsRecursively(vFile); + + treeEvent.setChild(psiDir); + myManager.childRemoved(treeEvent); + } + else { + treeEvent.setElement(psiDir); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME); + treeEvent.setOldValue(event.getOldValue()); + treeEvent.setNewValue(event.getNewValue()); + myManager.propertyChanged(treeEvent); + } + } + else { + PsiDirectory psiDir1 = findDirectory(vFile); + if (psiDir1 != null) { + treeEvent.setChild(psiDir1); + myManager.childAdded(treeEvent); + } + } + } + else { + PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + + if (psiFile != null) { + PsiFile psiFile1 = createPsiFile(vFile, vFile.getName()); + if (psiFile1 == null) { + myVFileToPsiFileMap.remove(vFile); + + treeEvent.setChild(psiFile); + myManager.childRemoved(treeEvent); + } + else if (!psiFile1.getClass().equals(psiFile.getClass())) { + myVFileToPsiFileMap.remove(vFile); + + treeEvent.setOldChild(psiFile); + treeEvent.setNewChild(psiFile1); + myManager.childReplaced(treeEvent); + } + else { + treeEvent.setElement(psiFile); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_FILE_NAME); + treeEvent.setOldValue(event.getOldValue()); + treeEvent.setNewValue(event.getNewValue()); + myManager.propertyChanged(treeEvent); + } + } + else { + PsiFile psiFile1 = findFile(vFile); + if (psiFile1 != null) { + treeEvent.setChild(psiFile1); + myManager.childAdded(treeEvent); + } + } + } + } + else if (VirtualFile.PROP_WRITABLE.equals(propertyName)) { + PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + if (psiFile == null) return; + + treeEvent.setElement(psiFile); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_WRITABLE); + treeEvent.setOldValue(event.getOldValue()); + treeEvent.setNewValue(event.getNewValue()); + myManager.propertyChanged(treeEvent); + } + } + } + ); + } + + public void beforeFileMovement(VirtualFileMoveEvent event) { + final VirtualFile vFile = event.getFile(); + + final PsiDirectory oldParentDir = findDirectory(event.getOldParent()); + final PsiDirectory newParentDir = findDirectory(event.getNewParent()); + if (oldParentDir == null && newParentDir == null) return; + if (myFileTypeManager.isFileIgnored(vFile.getName())) return; + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + + boolean isExcluded = vFile.isDirectory() && myProjectFileIndex.isIgnored(vFile); + if (oldParentDir != null && !isExcluded) { + if (newParentDir != null) { + treeEvent.setOldParent(oldParentDir); + treeEvent.setNewParent(newParentDir); + if (vFile.isDirectory()) { + PsiDirectory psiDir = findDirectory(vFile); + treeEvent.setChild(psiDir); + } + else { + PsiFile psiFile = findFile(vFile); + treeEvent.setChild(psiFile); + } + myManager.beforeChildMovement(treeEvent); + } + else { + treeEvent.setParent(oldParentDir); + if (vFile.isDirectory()) { + PsiDirectory psiDir = findDirectory(vFile); + treeEvent.setChild(psiDir); + } + else { + PsiFile psiFile = findFile(vFile); + treeEvent.setChild(psiFile); + } + myManager.beforeChildRemoval(treeEvent); + } + } + else { + LOG.assertTrue(newParentDir != null); // checked above + treeEvent.setParent(newParentDir); + myManager.beforeChildAddition(treeEvent); + } + } + } + ); + } + + public void fileMoved(VirtualFileMoveEvent event) { + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + + final VirtualFile vFile = event.getFile(); + + final PsiDirectory oldParentDir = findDirectory(event.getOldParent()); + final PsiDirectory newParentDir = findDirectory(event.getNewParent()); + if (oldParentDir == null && newParentDir == null) return; + + final PsiElement oldElement = vFile.isDirectory() ? (PsiElement)myVFileToPsiDirMap.get(vFile) : myVFileToPsiFileMap.get(vFile); + removeInvalidFilesAndDirs(true); + final PsiElement newElement = vFile.isDirectory() ? (PsiElement)findDirectory(vFile) : findFile(vFile); + if (oldElement == null && newElement == null) return; + + if (oldElement != null && newElement != null) { + if (oldElement != newElement) { + // [dsl] fix for 24136: if one cuts file from non-source-dir, and pastes it into source dir + // the above holds + ApplicationManager.getApplication().runWriteAction(new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeRemoveEvent = new PsiTreeChangeEventImpl(myManager); + treeRemoveEvent.setParent(oldParentDir); + treeRemoveEvent.setChild(oldElement); + myManager.childRemoved(treeRemoveEvent); + PsiTreeChangeEventImpl treeAddEvent = new PsiTreeChangeEventImpl(myManager); + treeAddEvent.setParent(newParentDir); + treeAddEvent.setChild(newElement); + myManager.childAdded(treeAddEvent); + } + }); + return; + } + } + + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + + if (oldElement != null) { + if (newElement != null) { + treeEvent.setOldParent(oldParentDir); + treeEvent.setNewParent(newParentDir); + treeEvent.setChild(newElement); + myManager.childMoved(treeEvent); + } + else { + treeEvent.setParent(oldParentDir); + treeEvent.setChild(oldElement); + myManager.childRemoved(treeEvent); + } + } + else { + LOG.assertTrue(newElement != null); // checked above + treeEvent.setParent(newParentDir); + treeEvent.setChild(newElement); + myManager.childAdded(treeEvent); + } + } + } + ); + } + + private void removeFilesAndDirsRecursively(VirtualFile vFile) { + if (vFile.isDirectory()) { + myVFileToPsiDirMap.remove(vFile); + + VirtualFile[] children = vFile.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + removeFilesAndDirsRecursively(child); + } + } + else { + myVFileToPsiFileMap.remove(vFile); + } + } + } + + private class MyModuleRootListener implements ModuleRootListener { + private VirtualFile[] myOldContentRoots = null; + public void beforeRootsChange(final ModuleRootEvent event) { + if (!myInitialized) return; + if (event.isCausedByFileTypesChange()) return; + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS); + final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots(); + LOG.assertTrue(myOldContentRoots == null); + myOldContentRoots = contentRoots; + treeEvent.setOldValue(contentRoots); + myManager.beforePropertyChange(treeEvent); + } + } + ); + } + + public void rootsChanged(final ModuleRootEvent event) { + dispatchPendingEvents(); + myNontrivialPackagePrefixes = null; + + if (!myInitialized) return; + if (!myUseRepository) { + clearNonRepositoryMaps(); + } + if (event.isCausedByFileTypesChange()) return; + ApplicationManager.getApplication().runWriteAction( + new PsiExternalChangeAction() { + public void run() { + RepositoryManager repositoryManager = myManager.getRepositoryManager(); + + removeInvalidFilesAndDirs(true); + + if (repositoryManager != null) { + repositoryManager.updateByRootsChange(); + } + + PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); + treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS); + final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots(); + treeEvent.setNewValue(contentRoots); + LOG.assertTrue(myOldContentRoots != null); + treeEvent.setOldValue(myOldContentRoots); + myOldContentRoots = null; + myManager.propertyChanged(treeEvent); + } + } + ); + } + } + + public void dumpFilesWithContentLoaded(Writer out) throws IOException { + out.write("Files with content loaded cached in FileManagerImpl:\n"); + Set vFiles = myVFileToPsiFileMap.keySet(); + for (Iterator iterator = vFiles.iterator(); iterator.hasNext();) { + VirtualFile vFile = iterator.next(); + PsiFile psiFile = myVFileToPsiFileMap.get(vFile); + if (psiFile instanceof PsiFileImpl && ((PsiFileImpl)psiFile).isContentsLoaded()) { + out.write(vFile.getPresentableUrl()); + out.write("\n"); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/ImplicitVariableImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/ImplicitVariableImpl.java new file mode 100644 index 00000000000..d127ad5587c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/ImplicitVariableImpl.java @@ -0,0 +1,21 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public abstract class ImplicitVariableImpl extends LightVariableBase implements ImplicitVariable { + + public ImplicitVariableImpl(PsiManager manager, PsiIdentifier nameIdentifier, PsiType type, boolean writable, PsiElement scope) { + super(manager, nameIdentifier, type, writable, scope); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitImplicitVariable(this); + } + + public String toString() { + return "Implicit variable:" + getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReference.java new file mode 100644 index 00000000000..b76c14f4e73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReference.java @@ -0,0 +1,219 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +public class LightClassReference extends LightElement implements PsiJavaCodeReferenceElement { + private final String myText; + private final String myClassName; + private final PsiElement myContext; + private final GlobalSearchScope myResolveScope; + private final PsiClass myRefClass; + + private LightReferenceParameterList myParameterList; + + public LightClassReference(PsiManager manager, String text, String className, GlobalSearchScope resolveScope) { + super(manager); + myText = text; + myClassName = className; + myResolveScope = resolveScope; + + myContext = null; + myRefClass = null; + } + + public LightClassReference(PsiManager manager, String text, String className, PsiElement context) { + super(manager); + myText = text; + myClassName = className; + myContext = context; + + myResolveScope = null; + myRefClass = null; + } + + public LightClassReference(PsiManager manager, String text, PsiClass refClass) { + super(manager); + myText = text; + myRefClass = refClass; + + myResolveScope = null; + myClassName = null; + myContext = null; + } + + public PsiElement resolve() { + if (myClassName != null) { + if (myContext != null) { + return myManager.getResolveHelper().resolveReferencedClass(myClassName, myContext); + } + else { + return myManager.findClass(myClassName, myResolveScope); + } + } + else { + return myRefClass; + } + } + + public ResolveResult advancedResolve(boolean incompleteCode){ + final PsiElement resolved = resolve(); + final PsiSubstitutor rawSubstitutor; + if (resolved instanceof PsiClass) { + rawSubstitutor = myManager.getElementFactory().createRawSubstitutor((PsiClass) resolved); + } else { + rawSubstitutor = PsiSubstitutor.EMPTY; + } + return new CandidateInfo(resolved, rawSubstitutor); + } + + public ResolveResult[] multiResolve(boolean incompleteCode){ + final ResolveResult result = advancedResolve(incompleteCode); + if(result != ResolveResult.EMPTY) return new ResolveResult[]{result}; + return ResolveResult.EMPTY_ARRAY; + } + + public void processVariants(PsiScopeProcessor processor){ + throw new RuntimeException("Variants are not available for light references"); + } + + public PsiElement getReferenceNameElement() { + return null; + } + + public PsiReferenceParameterList getParameterList() { + if (myParameterList == null) { + myParameterList = new LightReferenceParameterList(myManager, PsiTypeElement.EMPTY_ARRAY); + } + return myParameterList; + } + + public String getQualifiedName() { + if (myClassName != null) { + PsiClass psiClass = (PsiClass)resolve(); + + if (psiClass != null) { + return psiClass.getQualifiedName(); + } + else { + return myClassName; + } + } + else { + return myRefClass.getQualifiedName(); + } + } + + public String getReferenceName() { + if (myClassName != null){ + return PsiNameHelper.getShortClassName(myClassName); + } + else{ + if (myRefClass instanceof PsiAnonymousClass){ + return ((PsiAnonymousClass)myRefClass).getBaseClassReference().getReferenceName(); + } + else{ + return myRefClass.getName(); + } + } + } + + public String getText() { + return myText; + } + + public PsiReference getReference() { + return this; + } + + public String getCanonicalText() { + String name = getQualifiedName(); + if (name == null) return null; + PsiType[] types = getTypeParameters(); + if (types.length == 0) return name; + + StringBuffer buf = new StringBuffer(); + buf.append(name); + buf.append('<'); + for (int i = 0; i < types.length; i++) { + if (i > 0) buf.append(','); + buf.append(types[i].getCanonicalText()); + } + buf.append('>'); + + return buf.toString(); + } + + public PsiElement copy() { + if (myClassName != null) { + if (myContext != null) { + return new LightClassReference(myManager, myText, myClassName, myContext); + } + else{ + return new LightClassReference(myManager, myText, myClassName, myResolveScope); + } + } + else { + return new LightClassReference(myManager, myText, myRefClass); + } + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + //TODO? + throw new UnsupportedOperationException(); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + //TODO? + throw new UnsupportedOperationException(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceElement(this); + } + + public String toString() { + return "LightClassReference:" + myText; + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof PsiClass)) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + throw new RuntimeException("Variants are not available for light references"); + } + + public boolean isSoft(){ + return false; + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public PsiElement getElement() { + return this; + } + + public boolean isValid() { + return myRefClass == null || myRefClass.isValid(); + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } + + public PsiElement getQualifier() { + return null; + } + + public boolean isQualified() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReferenceExpression.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReferenceExpression.java new file mode 100644 index 00000000000..c283c6f9f9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightClassReferenceExpression.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +public class LightClassReferenceExpression extends LightClassReference implements PsiReferenceExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.light.LightClassReferenceExpression"); + + public LightClassReferenceExpression(PsiManager manager, String text, PsiClass refClass) { + super(manager, text, refClass); + } + + public PsiExpression getQualifierExpression(){ + return null; + } + + public PsiElement bindToElementViaStaticImport(PsiClass aClass) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + // very special method + public void setCachedResolveResult(PsiElement result, Boolean problemWithAccess, Boolean problemWithStatic) { + LOG.assertTrue(false); + } + + public PsiType getType(){ + return null; + } + + public boolean isReferenceTo(PsiElement element) { + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + throw new RuntimeException("Variants are not available for light references"); + } + + public void processVariants(PsiScopeProcessor processor){ + throw new RuntimeException("Variants are not available for light references"); + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public PsiReferenceParameterList getParameterList() { + return null; + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightElement.java new file mode 100644 index 00000000000..9479585fcf6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightElement.java @@ -0,0 +1,122 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiElementBase; +import com.intellij.util.IncorrectOperationException; + +/** + * + */ +public abstract class LightElement extends PsiElementBase { + protected final PsiManager myManager; + + protected LightElement(PsiManager manager) { + myManager = manager; + } + + public PsiManager getManager(){ + return myManager; + } + + public PsiElement getParent(){ + return null; + } + + public PsiElement[] getChildren(){ + return PsiElement.EMPTY_ARRAY; + } + + public PsiFile getContainingFile(){ + return null; + } + + public TextRange getTextRange(){ + return null; + } + + public int getStartOffsetInParent(){ + return -1; + } + + public final int getTextLength(){ + String text = getText(); + return text != null ? text.length() : 0; + } + + public char[] textToCharArray(){ + return getText().toCharArray(); + } + + public boolean textMatches(CharSequence text) { + return getText().equals(text.toString()); + } + + public boolean textMatches(PsiElement element) { + return getText().equals(element.getText()); + } + + public PsiElement findElementAt(int offset) { + return null; + } + + public int getTextOffset(){ + return -1; + } + + public boolean isValid(){ + return true; + } + + public boolean isWritable(){ + return false; + } + + public boolean isPhysical() { + return false; + } + + public abstract String toString(); + + public void checkAdd(PsiElement element) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void delete() throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void checkDelete() throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightEmptyImplementsList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightEmptyImplementsList.java new file mode 100644 index 00000000000..ad6b64f8ed5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightEmptyImplementsList.java @@ -0,0 +1,36 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; + +/** + * @author max + */ +public class LightEmptyImplementsList extends LightElement implements PsiReferenceList { + public LightEmptyImplementsList(PsiManager manager) { + super(manager); + } + + public String toString() { + return "PsiReferenceList"; + } + + public String getText() { + return ""; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceList(this); + } + + public PsiElement copy() { + return this; + } + + public PsiJavaCodeReferenceElement[] getReferenceElements() { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + public PsiClassType[] getReferencedTypes() { + return PsiClassType.EMPTY_ARRAY; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightIdentifier.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightIdentifier.java new file mode 100644 index 00000000000..e39ffcbf130 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightIdentifier.java @@ -0,0 +1,37 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; + +/** + * + */ +public class LightIdentifier extends LightElement implements PsiIdentifier, PsiJavaToken { + private String myText; + + public LightIdentifier(PsiManager manager, String text) { + super(manager); + myText = text; + } + + public IElementType getTokenType() { + return JavaTokenType.IDENTIFIER; + } + + public String getText(){ + return myText; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitIdentifier(this); + } + + public PsiElement copy(){ + return new LightIdentifier(getManager(), myText); + } + + public String toString(){ + return "PsiIdentifier:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightKeyword.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightKeyword.java new file mode 100644 index 00000000000..cf812485e18 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightKeyword.java @@ -0,0 +1,40 @@ +package com.intellij.psi.impl.light; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; + +/** + * + */ +public class LightKeyword extends LightElement implements PsiKeyword, PsiJavaToken { + private String myText; + + public LightKeyword(PsiManager manager, String text) { + super(manager); + myText = text; + } + + public String getText(){ + return myText; + } + + public IElementType getTokenType(){ + Lexer lexer = new JavaLexer(myManager.getEffectiveLanguageLevel()); + lexer.start(myText.toCharArray()); + return lexer.getTokenType(); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitKeyword(this); + } + + public PsiElement copy(){ + return new LightKeyword(getManager(), myText); + } + + public String toString(){ + return "PsiKeyword:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightMethod.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightMethod.java new file mode 100644 index 00000000000..4226af027a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightMethod.java @@ -0,0 +1,146 @@ +package com.intellij.psi.impl.light; + +import com.intellij.pom.java.PomMethod; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; + +/** + * @author ven + */ +public class LightMethod extends LightElement implements PsiMethod { + private PsiMethod myMethod; + private PsiClass myContainingClass; + + public LightMethod(PsiManager manager, PsiMethod method, PsiClass containingClass) { + super(manager); + myMethod = method; + myContainingClass = containingClass; + } + + + public boolean hasTypeParameters() { + return myMethod.hasTypeParameters(); + } + + public PsiTypeParameterList getTypeParameterList() { + return myMethod.getTypeParameterList(); + } + + public PsiDocComment getDocComment() { + return myMethod.getDocComment(); + } + + public boolean isDeprecated() { + return myMethod.isDeprecated(); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + return myMethod.setName(name); + } + + public String getName() { + return myMethod.getName(); + } + + public boolean hasModifierProperty(String name) { + return myMethod.hasModifierProperty(name); + } + + public PsiModifierList getModifierList() { + return myMethod.getModifierList(); + } + + public PsiType getReturnType() { + return myMethod.getReturnType(); + } + + public PsiTypeElement getReturnTypeElement() { + return myMethod.getReturnTypeElement(); + } + + public PsiParameterList getParameterList() { + return myMethod.getParameterList(); + } + + public PsiReferenceList getThrowsList() { + return myMethod.getThrowsList(); + } + + public PsiCodeBlock getBody() { + return myMethod.getBody(); + } + + public boolean isConstructor() { + return myMethod.isConstructor(); + } + + public boolean isVarArgs() { + return myMethod.isVarArgs(); + } + + public MethodSignature getSignature(PsiSubstitutor substitutor) { + return myMethod.getSignature(substitutor); + } + + public PsiIdentifier getNameIdentifier() { + return myMethod.getNameIdentifier(); + } + + public PsiMethod[] findSuperMethods() { + return myMethod.findSuperMethods(); + } + + public PsiMethod[] findSuperMethods(boolean checkAccess) { + return myMethod.findSuperMethods(checkAccess); + } + + public PsiMethod[] findSuperMethods(PsiClass parentClass) { + return myMethod.findSuperMethods(parentClass); + } + + public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { + return myMethod.findSuperMethodSignaturesIncludingStatic(checkAccess); + } + + public PsiMethod findConstructorInSuper() { + return myMethod.findConstructorInSuper(); + } + + public PsiMethod findDeepestSuperMethod() { + return myMethod.findDeepestSuperMethod(); + } + + public PomMethod getPom() { + //TODO: + return null; + } + + public String getText() { + return myMethod.getText(); + } + + public void accept(PsiElementVisitor visitor) { + myMethod.accept(visitor); + } + + public PsiElement copy() { + return new LightMethod(myManager, (PsiMethod)myMethod.copy(), myContainingClass); + } + + public boolean isValid() { + return myContainingClass.isValid(); + } + + public PsiClass getContainingClass() { + return myContainingClass; + } + + public String toString() { + return "PsiMethod:" + getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightModifierList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightModifierList.java new file mode 100644 index 00000000000..e8880d3d83c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightModifierList.java @@ -0,0 +1,47 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +public class LightModifierList extends LightElement implements PsiModifierList{ + public LightModifierList(PsiManager manager){ + super(manager); + } + + public boolean hasModifierProperty(String name){ + return false; + } + + public void setModifierProperty(String name, boolean value) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public void checkSetModifierProperty(String name, boolean value) throws IncorrectOperationException{ + throw new IncorrectOperationException(); + } + + public PsiAnnotation[] getAnnotations() { + return PsiAnnotation.EMPTY_ARRAY; + } + + public PsiAnnotation findAnnotation(String qualifiedName) { + return null; + } + + public String getText(){ + return null; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitModifierList(this); + } + + public PsiElement copy(){ + return null; + } + + public String toString(){ + return "PsiModifierList"; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReference.java new file mode 100644 index 00000000000..6b529e476f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReference.java @@ -0,0 +1,149 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +public class LightPackageReference extends LightElement implements PsiJavaCodeReferenceElement { + private final String myPackageName; + private final PsiPackage myRefPackage; + + public LightPackageReference(PsiManager manager, PsiPackage refPackage) { + super(manager); + myPackageName = null; + myRefPackage = refPackage; + } + + public LightPackageReference(PsiManager manager, String packageName) { + super(manager); + myPackageName = packageName; + myRefPackage = null; + } + + public PsiElement resolve(){ + if (myPackageName != null){ + return myManager.findPackage(myPackageName); + } + else { + return myRefPackage; + } + } + + public ResolveResult advancedResolve(boolean incompleteCode){ + return new CandidateInfo(resolve(), PsiSubstitutor.EMPTY); + } + + public ResolveResult[] multiResolve(boolean incompleteCode){ + final ResolveResult result = advancedResolve(incompleteCode); + if(result != ResolveResult.EMPTY) return new ResolveResult[]{result}; + return ResolveResult.EMPTY_ARRAY; + } + + public String getText(){ + if (myPackageName != null){ + return myPackageName; + } + else { + return myRefPackage.getQualifiedName(); + } + } + + public PsiReference getReference() { + return this; + } + + public String getCanonicalText(){ + return getText(); + } + + public PsiElement copy(){ + if (myPackageName != null){ + return new LightPackageReference(myManager, myPackageName); + } + else{ + return new LightPackageReference(myManager, myRefPackage); + } + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + //TODO? + throw new UnsupportedOperationException(); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + //TODO? + throw new UnsupportedOperationException(); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitReferenceElement(this); + } + + public String toString(){ + return "PsiJavaCodeReferenceElement:" + getText(); + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof PsiPackage)) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + throw new RuntimeException("Variants are not available for light references"); + } + + public boolean isSoft(){ + return false; + } + + public void processVariants(PsiScopeProcessor processor){ + throw new RuntimeException("Variants are not available for light references"); + } + + public PsiElement getReferenceNameElement() { + return null; + } + + public PsiReferenceParameterList getParameterList() { + return null; + } + + public String getQualifiedName() { + return getText(); + } + + public String getReferenceName() { + if (myPackageName != null){ + return PsiNameHelper.getShortClassName(myPackageName); + } + else { + return myRefPackage.getName(); + } + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public PsiElement getElement() { + return this; + } + + public boolean isValid() { + return myRefPackage == null || myRefPackage.isValid(); + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } + + public PsiElement getQualifier() { + return null; + } + + public boolean isQualified() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReferenceExpression.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReferenceExpression.java new file mode 100644 index 00000000000..997a13cbb16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightPackageReferenceExpression.java @@ -0,0 +1,39 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +public class LightPackageReferenceExpression extends LightPackageReference implements PsiReferenceExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.light.LightPackageReferenceExpression"); + + public LightPackageReferenceExpression(PsiManager manager, PsiPackage refPackage) { + super(manager, refPackage); + } + + public PsiExpression getQualifierExpression(){ + return null; + } + + public PsiElement bindToElementViaStaticImport(PsiClass aClass) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + // very special method + public void setCachedResolveResult(PsiElement result, Boolean problemWithAccess, Boolean problemWithStatic) { + LOG.assertTrue(false); + } + + public PsiType getType(){ + return null; + } + + public boolean isReferenceTo(PsiElement element) { + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightReferenceParameterList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightReferenceParameterList.java new file mode 100644 index 00000000000..51c02a35162 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightReferenceParameterList.java @@ -0,0 +1,63 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; + +/** + * @author dsl + */ +public class LightReferenceParameterList extends LightElement implements PsiReferenceParameterList { + private final PsiTypeElement[] myTypeElements; + private final String myText; + + public LightReferenceParameterList(PsiManager manager, + PsiTypeElement[] referenceElements) { + super(manager); + myTypeElements = referenceElements; + myText = calculateText(); + } + + private String calculateText() { + if (myTypeElements.length == 0) return ""; + final StringBuffer buffer = new StringBuffer(); + buffer.append("<"); + for (int i = 0; i < myTypeElements.length; i++) { + PsiTypeElement type = myTypeElements[i]; + if (i > 0) { + buffer.append(","); + } + buffer.append(type.getText()); + } + buffer.append(">"); + return buffer.toString(); + } + + public String toString() { + return "PsiReferenceParameterList"; + } + + public String getText() { + return myText; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceParameterList(this); + } + + public PsiElement copy() { + final PsiTypeElement[] elements = new PsiTypeElement[myTypeElements.length]; + for (int i = 0; i < myTypeElements.length; i++) { + PsiTypeElement typeElement = myTypeElements[i]; + elements[i] = (PsiTypeElement) typeElement.copy(); + } + return new LightReferenceParameterList(myManager, elements); + } + + public PsiTypeElement[] getTypeParameterElements() { + return myTypeElements; + } + + public PsiType[] getTypeArguments() { + return PsiImplUtil.typesByTypeElements(myTypeElements); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightTypeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightTypeElement.java new file mode 100644 index 00000000000..f9ad03a32e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightTypeElement.java @@ -0,0 +1,48 @@ +package com.intellij.psi.impl.light; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; + +/** + * @author max + */ +public class LightTypeElement extends LightElement implements PsiTypeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.light.LightTypeElement"); + + private final PsiType myType; + + public LightTypeElement(PsiManager manager, PsiType type) { + super(manager); + type = PsiUtil.convertAnonymousToBaseType(type); + myType = type; + } + + public String toString() { + return "PsiTypeElement:" + getText(); + } + + public String getText() { + return myType.getPresentableText(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeElement(this); + } + + public PsiElement copy() { + return new LightTypeElement(myManager, myType); + } + + public PsiType getType() { + return myType; + } + + public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() { + return null; + } + + public boolean isValid() { + return myType.isValid(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightVariableBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightVariableBase.java new file mode 100644 index 00000000000..eee6debe325 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/light/LightVariableBase.java @@ -0,0 +1,81 @@ +package com.intellij.psi.impl.light; + +import com.intellij.psi.*; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.util.IncorrectOperationException; + +/** + * @author ven + */ +public abstract class LightVariableBase extends LightElement implements PsiVariable { + protected PsiElement myScope; + protected PsiIdentifier myNameIdentifier; + protected final PsiType myType; + protected PsiModifierList myModifierList; + protected boolean myWritable; + + public LightVariableBase(PsiManager manager, PsiIdentifier nameIdentifier, PsiType type, boolean writable, PsiElement scope) { + super(manager); + myModifierList = new LightModifierList(myManager); + myNameIdentifier = nameIdentifier; + myWritable = writable; + myType = type; + myScope = scope; + } + + public PsiElement getDeclarationScope() { + return myScope; + } + + public PsiIdentifier getNameIdentifier() { + return myNameIdentifier; + } + + public String getName() { + return getNameIdentifier().getText(); + } + + public PsiElement setName(String name) throws IncorrectOperationException{ + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiType getType() { + return myType; + } + + public PsiTypeElement getTypeElement() { + return getManager().getElementFactory().createTypeElement(myType); + } + + public PsiModifierList getModifierList() { + return myModifierList; + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiExpression getInitializer() { + return null; + } + + public boolean hasInitializer() { + return false; + } + + public String getText() { + return myNameIdentifier.getText(); + } + + public PsiElement copy() { + return null; + } + + public Object computeConstantValue() { + return null; + } + + public void normalizeDeclaration() throws IncorrectOperationException { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/meta/MetaRegistry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/meta/MetaRegistry.java new file mode 100644 index 00000000000..26603f32b11 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/meta/MetaRegistry.java @@ -0,0 +1,350 @@ +package com.intellij.psi.impl.meta; + +import com.intellij.ant.impl.dom.impl.RegisterInPsi; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.*; +import com.intellij.psi.filters.position.NamespaceFilter; +import com.intellij.psi.filters.position.RootTagFilter; +import com.intellij.psi.impl.source.jsp.tagLibrary.JspTagAttributeInfoImpl; +import com.intellij.psi.impl.source.jsp.tagLibrary.JspTagInfoImpl; +import com.intellij.psi.impl.source.jsp.tagLibrary.JspTagLibraryInfoImpl; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.xml.XmlAttributeDecl; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlElementDecl; +import com.intellij.psi.xml.XmlMarkupDecl; +import com.intellij.xml.util.XmlUtil; +import com.intellij.jsp.impl.TldDescriptor; + +import java.lang.ref.SoftReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 07.05.2003 + * Time: 3:31:09 + * To change this template use Options | File Templates. + */ +public class MetaRegistry { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.meta.MetaRegistry"); + private static final List ourBindings = new ArrayList(); + private static final String[] TAGLIB_URIS = new String[]{XmlUtil.TAGLIB_1_1_URI, XmlUtil.TAGLIB_1_2_a_URI, XmlUtil.TAGLIB_1_2_URI, XmlUtil.TAGLIB_2_0_URI, XmlUtil.TAGLIB_1_2_b_URI,}; + private static final String[] SCHEMA_URIS = { XmlUtil.XML_SCHEMA_URI, XmlUtil.XML_SCHEMA_URI2, XmlUtil.XML_SCHEMA_URI3 }; + + static { + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(TAGLIB_URIS), + new TextFilter("taglib") + ), + JspTagLibraryInfoImpl.class); + } + + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(TAGLIB_URIS), + new RootTagFilter(new TextFilter("taglib")) + ), + TldDescriptor.class); + } + + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(TAGLIB_URIS), + new TextFilter("tag") + ), + JspTagInfoImpl.class); + } + + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(TAGLIB_URIS), + new TextFilter("attribute") + ), + JspTagAttributeInfoImpl.class + ); + } + + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(SCHEMA_URIS), + new ClassFilter(XmlDocument.class) + ), + com.intellij.xml.impl.schema.XmlNSDescriptorImpl.class + ); + } + + RegisterInPsi.metaData(); + + { + addMetadataBinding( + new OrFilter( + new AndFilter( + new ContentFilter(new ClassFilter(XmlElementDecl.class)), + new ClassFilter(XmlDocument.class) + ), + new ClassFilter(XmlMarkupDecl.class) + ), + com.intellij.xml.impl.dtd.XmlNSDescriptorImpl.class + ); + } + + { + addMetadataBinding(new AndFilter( + new NamespaceFilter(SCHEMA_URIS), + new TextFilter("element") + ), + com.intellij.xml.impl.schema.XmlElementDescriptorImpl.class); + } + + { + addMetadataBinding( + new AndFilter( + new NamespaceFilter(SCHEMA_URIS), + new TextFilter("attribute") + ), + com.intellij.xml.impl.schema.XmlAttributeDescriptorImpl.class + ); + } + + { + addMetadataBinding( + new ClassFilter(XmlElementDecl.class), + com.intellij.xml.impl.dtd.XmlElementDescriptorImpl.class + ); + } + + { + addMetadataBinding( + new ClassFilter(XmlAttributeDecl.class), + com.intellij.xml.impl.dtd.XmlAttributeDescriptorImpl.class + ); + } + + { + //// Ant related declarations + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("property", true) + // ), + // PropertyPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("loadfile", true) + // ), + // LoadFilePropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("param", true) + // ), + // ParamPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("dirname", true) + // ), + // DirnamePropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("input", true) + // ), + // InputPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("pathconvert", true) + // ), + // PathconvertPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("condition", true) + // ), + // ConditionPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("tempfile", true) + // ), + // TempFilePropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("loadfile", true) + // ), + // LoadFilePropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("buildnumber", true) + // ), + // BuildNumberPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("format", true) + // ), + // FormatPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("loadproperties", true) + // ), + // LoadpropertiesPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("tstamp", true) + // ), + // TstampPropertyDeclaration.class + // ); + //} + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("fail", true) + // ), + // FailPropertyDeclaration.class + // ); + //} + + //{ + // addMetadataBinding( + // new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("target", true) + // ), + // AntTargetDeclaration.class + // ); + //} + } + } + + public static final Key>> META_DATA_KEY = Key.create("META DATA KEY"); + + public static final void bindDataToElement(final PsiElement element, final PsiMetaData data){ + SoftReference> value = new SoftReference>( + element.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + data.init(element); + return new Result(data, data.getDependences()); + } + })); + element.putUserData(META_DATA_KEY, value); + } + + private final static SoftReference> NULL = new SoftReference>(null); + + public static final PsiMetaData getMeta(final PsiElement element) { + ProgressManager.getInstance().checkCanceled(); + PsiMetaData ret = null; + SoftReference> value = element.getUserData(META_DATA_KEY); + if (value == null || (value != NULL && value.get() == null)) { + final Iterator iter = ourBindings.iterator(); + while (iter.hasNext()) { + final MyBinding binding = iter.next(); + try { + if (binding.myFilter.isClassAcceptable(element.getClass()) && binding.myFilter.isAcceptable(element, element.getParent())) { + final PsiMetaData data = binding.myDataClass.newInstance(); + final CachedValue cachedValue = element.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + data.init(element); + return new Result(data, data.getDependences()); + } + },false); + value = new SoftReference>(cachedValue); + ret = cachedValue.getValue(); + break; + } + } + catch (IllegalAccessException iae) { + value = null; + } + catch(InstantiationException ie){ + value = null; + } + } + element.putUserData(META_DATA_KEY, value != null ? value : NULL); + } + else if(value != NULL){ + ret = value.get().getValue(); + } + + return ret; + } + + public static void addMetadataBinding(ElementFilter filter, Class aMetadataClass) { + LOG.assertTrue(filter != null); + LOG.assertTrue(aMetadataClass != null); + ourBindings.add(new MyBinding(filter, aMetadataClass)); + } + + public static void clearMetaForElement(PsiElement element) { + element.putUserData(META_DATA_KEY, null); + } + + private static class MyBinding { + ElementFilter myFilter; + Class myDataClass; + + public MyBinding(ElementFilter filter, Class dataClass) { + myFilter = filter; + myDataClass = (Class)dataClass; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationClassImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationClassImpl.java new file mode 100644 index 00000000000..5e955308eef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationClassImpl.java @@ -0,0 +1,233 @@ +package com.intellij.psi.impl.migration; + +import com.intellij.openapi.util.Pair; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.psi.*; +import com.intellij.psi.impl.InheritanceImplUtil; +import com.intellij.psi.impl.light.LightElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +public class MigrationClassImpl extends LightElement implements PsiClass{ + private final String myQualifiedName; + private final String myName; + private final PsiMigrationImpl myMigration; + + MigrationClassImpl(PsiMigrationImpl migration, String qualifiedName) { + super(migration.getManager()); + myMigration = migration; + myQualifiedName = qualifiedName; + myName = PsiNameHelper.getShortClassName(myQualifiedName); + } + + public String toString() { + return "MigrationClass:" + myQualifiedName; + } + + public String getText() { + return "class " + myName + " {}"; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitClass(this); + } + + public PsiElement copy() { + return new MigrationClassImpl(myMigration, myQualifiedName); + } + + public boolean isValid() { + return myMigration.isValid(); + } + + public String getQualifiedName() { + return myQualifiedName; + } + + public boolean isInterface() { + return false; + } + + public boolean isAnnotationType() { + return false; + } + + public boolean isEnum() { + return false; + } + + public PsiReferenceList getExtendsList() { + return null; + } + + + public PsiReferenceList getImplementsList() { + return null; + } + + public PsiClassType[] getExtendsListTypes() { + return PsiClassType.EMPTY_ARRAY; + } + + public PsiClassType[] getImplementsListTypes() { + return PsiClassType.EMPTY_ARRAY; + } + + public PsiClass getSuperClass() { + return myManager.findClass("java.lang.Object", GlobalSearchScope.allScope(myManager.getProject())); + } + + public PsiClass[] getInterfaces() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiClass[] getSupers() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiClassType[] getSuperTypes() { + return PsiClassType.EMPTY_ARRAY; + } + + public PsiClass getContainingClass() { + return null; + } + + public PsiField[] getFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiMethod[] getConstructors() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiClass[] getInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiClassInitializer[] getInitializers() { + return PsiClassInitializer.EMPTY_ARRAY; + } + + public PsiTypeParameter[] getTypeParameters() { + return PsiTypeParameter.EMPTY_ARRAY; + } + + public PsiField[] getAllFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getAllMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiClass[] getAllInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiField findFieldByName(String name, boolean checkBases) { + return null; + } + + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return null; + } + + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiMethod[] findMethodsByName(String name, boolean checkBases) { + return PsiMethod.EMPTY_ARRAY; + } + + public List> findMethodsAndTheirSubstitutorsByName(String name, boolean checkBases) { + return new ArrayList>(); + } + + public List> getAllMethodsAndTheirSubstitutors() { + return new ArrayList>(); + } + + public PsiClass findInnerClassByName(String name, boolean checkBases) { + return null; + } + + public PsiTypeParameterList getTypeParameterList() { + return null; + } + + public boolean hasTypeParameters() { + return false; + } + + public PsiJavaToken getLBrace() { + return null; + } + + public PsiJavaToken getRBrace() { + return null; + } + + public PsiIdentifier getNameIdentifier() { + return null; + } + + // very special method! + public PsiElement getScope() { + return null; + } + + public boolean isInheritor(PsiClass baseClass, boolean checkDeep) { + return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep); + } + + public PomMemberOwner getPom() { + //TODO: + return null; + } + + public String getName() { + return myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiModifierList getModifierList() { + return null; + } + + public boolean hasModifierProperty(String name) { + return PsiModifier.PUBLIC.equals(name); + } + + public PsiDocComment getDocComment() { + return null; + } + + public boolean isDeprecated() { + return false; + } + + public PsiMetaData getMetaData() { + return null; + } + + public boolean isMetaEnough() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationPackageImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationPackageImpl.java new file mode 100644 index 00000000000..2932b4577c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/MigrationPackageImpl.java @@ -0,0 +1,41 @@ +package com.intellij.psi.impl.migration; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.impl.file.PsiPackageImpl; + +/** + * @author dsl + */ +public class MigrationPackageImpl extends PsiPackageImpl implements PsiPackage { + private final PsiMigrationImpl myMigration; + + public MigrationPackageImpl(PsiMigrationImpl migration, String qualifiedName) { + super(migration.getManager(), qualifiedName); + myMigration = migration; + } + + public String toString() { + return "MigrationPackage: " + getQualifiedName(); + } + + public boolean isWritable() { + return false; + } + + public boolean isValid() { + return myMigration.isValid(); + } + + public String getText() { + return null; + } + + public void handleQualifiedNameChange(String newQualifiedName) { + throw new UnsupportedOperationException(); + } + + public VirtualFile[] occursInPackagePrefixes() { + return VirtualFile.EMPTY_ARRAY; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/PsiMigrationImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/PsiMigrationImpl.java new file mode 100644 index 00000000000..f01bee076e3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/migration/PsiMigrationImpl.java @@ -0,0 +1,135 @@ +package com.intellij.psi.impl.migration; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMigration; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * @author dsl + */ +public class PsiMigrationImpl implements PsiMigration { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.migration.PsiMigrationImpl"); + private final PsiManagerImpl myManager; + private final Map myQNameToClassMap = new HashMap(); + private final Map> myPackageToClassesMap = new HashMap>(); + private final Map myQNameToPackageMap = new HashMap(); + private final Map> myPackageToSubpackagesMap = new HashMap>(); + private boolean myIsValid = true; + + public PsiMigrationImpl(PsiManagerImpl manager) { + myManager = manager; + } + + public PsiClass createClass(String qualifiedName) { + assertValid(); + ApplicationManager.getApplication().assertWriteAccessAllowed(); + final MigrationClassImpl migrationClass = new MigrationClassImpl(this, qualifiedName); + final MigrationClassImpl oldMigrationClass = myQNameToClassMap.put(qualifiedName, migrationClass); + LOG.assertTrue(oldMigrationClass == null, qualifiedName); + String packageName = parentPackageName(qualifiedName); + final PsiPackage aPackage = myManager.findPackage(packageName); + if (aPackage == null) { + createPackage(packageName); + } + List psiClasses = getClassesList(packageName); + psiClasses.add(migrationClass); + myManager.migrationModified(false); + return migrationClass; + } + + private List getClassesList(String packageName) { + assertValid(); + ApplicationManager.getApplication().assertReadAccessAllowed(); + List psiClasses = myPackageToClassesMap.get(packageName); + if (psiClasses == null) { + psiClasses = new ArrayList(); + myPackageToClassesMap.put(packageName, psiClasses); + } + return psiClasses; + } + + public PsiPackage createPackage(String qualifiedName) { + assertValid(); + ApplicationManager.getApplication().assertWriteAccessAllowed(); + final MigrationPackageImpl migrationPackage = new MigrationPackageImpl(this, qualifiedName); + final MigrationPackageImpl oldMigrationPackage = myQNameToPackageMap.put(qualifiedName, migrationPackage); + LOG.assertTrue(oldMigrationPackage == null, qualifiedName); + final String parentName = parentPackageName(qualifiedName); + final PsiPackage aPackage = myManager.findPackage(parentName); + if (aPackage == null) { + createPackage(parentName); + } + List psiPackages = getSubpackagesList(parentName); + psiPackages.add(migrationPackage); + myManager.migrationModified(false); + return migrationPackage; + } + + public void finish() { + assertValid(); + myQNameToClassMap.clear(); + myQNameToPackageMap.clear(); + myPackageToClassesMap.clear(); + myPackageToSubpackagesMap.clear(); + myIsValid = false; + myManager.migrationModified(true); + } + + private void assertValid() { + LOG.assertTrue(myIsValid); + } + + private List getSubpackagesList(final String parentName) { + assertValid(); + List psiPackages = myPackageToSubpackagesMap.get(parentName); + if (psiPackages == null) { + psiPackages = new ArrayList(); + myPackageToSubpackagesMap.put(parentName, psiPackages); + } + return psiPackages; + } + + public Iterator getMigrationClasses(String packageName) { + assertValid(); + return getClassesList(packageName).iterator(); + } + + public Iterator getMigrationPackages(String packageName) { + assertValid(); + return getSubpackagesList(packageName).iterator(); + } + + public PsiClass getMigrationClass(String qualifiedName) { + assertValid(); + return myQNameToClassMap.get(qualifiedName); + } + + public PsiPackage getMigrationPackage(String qualifiedName) { + assertValid(); + return myQNameToPackageMap.get(qualifiedName); + } + + + private String parentPackageName(String qualifiedName) { + final int lastDotIndex = qualifiedName.lastIndexOf('.'); + final String packageName = lastDotIndex >= 0 ? qualifiedName.substring(0, lastDotIndex) : ""; + return packageName; + } + + PsiManagerImpl getManager() { + return myManager; + } + + boolean isValid() { + return myIsValid; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/LowLevelSearchUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/LowLevelSearchUtil.java new file mode 100644 index 00000000000..ff61fbee654 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/LowLevelSearchUtil.java @@ -0,0 +1,184 @@ +package com.intellij.psi.impl.search; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLock; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.ChameleonElement; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.text.StringSearcher; + +import java.util.Set; + +public class LowLevelSearchUtil { + public static boolean processElementsContainingWordInElement(PsiElementProcessorEx processor, + PsiElement scope, + StringSearcher searcher, + TokenSet elementTypes, + ProgressIndicator progress) { + return processElementsContainingWordInElement(processor, SourceTreeToPsiMap.psiElementToTree(scope), searcher, elementTypes, progress); + } + + + private static boolean processElementsContainingWordInElement(PsiElementProcessorEx processor, + TreeElement scope, + StringSearcher searcher, + TokenSet elementTypes, + ProgressIndicator progress) { + ProgressManager.getInstance().checkCanceled(); + + if (elementTypes.isInSet(scope.getElementType())) { + int startOffset; + int endOffset; + if (scope instanceof LeafElement) { + LeafElement leaf = (LeafElement)scope; + startOffset = 0; + endOffset = leaf.getTextLength(); + do { + int i = leaf.searchWord(startOffset, searcher); + if (i >= 0) { + if (!processor.execute(SourceTreeToPsiMap.treeElementToPsi(scope), i)) return false; + startOffset = i + 1; + } + else { + return true; + } + } + while (startOffset < endOffset); + endOffset = startOffset + leaf.getTextLength(); + } + else { + char[] buffer = scope.textToCharArray(); + + // This is hack. Need to be fixed and optimized. current code's extremely slow + // LeafElement leaf = SourceUtil.findLeafToFetchCharArrayRange(scope); + //if (leaf != null) { + // buffer = leaf.buffer; + // startOffset = leaf.offset; + // endOffset = leaf.offset + scope.getTextLength(); + //} + //else { + // buffer = scope.textToCharArray(); + // startOffset = 0; + // endOffset = buffer.length; + //} + startOffset = 0; + endOffset = buffer.length; + + final int originalStartOffset = startOffset; + do { + int i = searchWord(buffer, startOffset, endOffset, searcher); + if (i >= 0) { + if (!processor.execute(SourceTreeToPsiMap.treeElementToPsi(scope), i - originalStartOffset)) return false; + startOffset = i + 1; + } + else { + return true; + } + } + while (startOffset < endOffset); + } + } + + if (scope instanceof CompositeElement) { + return processChildren(scope, searcher, processor, elementTypes, progress); + } + + return true; + } + + private static boolean processChildren(TreeElement scope, + StringSearcher searcher, + PsiElementProcessorEx processor, + TokenSet elementTypes, ProgressIndicator progress) { + synchronized (PsiLock.LOCK) { + TreeElement child = ((CompositeElement)scope).firstChild; + while (child != null) { + if (child instanceof ChameleonElement) { + LeafElement leaf = (LeafElement)child; + if (leaf.searchWord(0, searcher) >= 0) { + TreeElement next = child.getTreeNext(); + child = ChameleonTransforming.transform((ChameleonElement)child); + if (child == null) { + child = next; + } + continue; + } + } + child = child.getTreeNext(); + } + } + + TreeElement child = null; + while (true) { + synchronized (PsiLock.LOCK) { + child = child != null ? child.getTreeNext() : ((CompositeElement)scope).firstChild; + while (child instanceof ChameleonElement) { + child = child.getTreeNext(); + } + if (child == null) break; + } + + if (!processElementsContainingWordInElement(processor, child, searcher, elementTypes, progress)) return false; + } + return true; + } + + public static int searchWord(char[] text, int startOffset, int endOffset, StringSearcher searcher) { + for (int index = startOffset; index < endOffset; index++) { + index = searcher.scan(text, index, endOffset); + if (index < 0) return -1; + + if (index > startOffset) { + char c = text[index - 1]; + if (Character.isJavaIdentifierPart(c) && c != '$') { + continue; + } + } + + String pattern = searcher.getPattern(); + if (index + pattern.length() < endOffset) { + char c = text[index + pattern.length()]; + if (Character.isJavaIdentifierPart(c) && c != '$') { + continue; + } + } + return index; + } + return -1; + } + + public static boolean processIdentifiersBySet( + PsiElementProcessor processor, + TreeElement scope, + TokenSet elementTypes, + Set namesSet, + ProgressIndicator progress + ) { + ProgressManager.getInstance().checkCanceled(); + + if (elementTypes.isInSet(scope.getElementType())) { + String text = scope.getText(); //TODO: optimization to not fetch text? + if (namesSet.contains(text)) { + if (!processor.execute(SourceTreeToPsiMap.treeElementToPsi(scope))) return false; + } + } + + if (scope instanceof CompositeElement) { + CompositeElement _scope = (CompositeElement)scope; + ChameleonTransforming.transformChildren(_scope); + + for (TreeElement child = _scope.firstChild; child != null; child = child.getTreeNext()) { + if (!processIdentifiersBySet(processor, child, elementTypes, namesSet, progress)) return false; + } + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/PsiSearchHelperImpl.java new file mode 100644 index 00000000000..9aa38a63db2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -0,0 +1,1587 @@ +package com.intellij.psi.impl.search; + +import com.intellij.ant.PsiAntElement; +import com.intellij.aspects.psi.PsiAspect; +import com.intellij.aspects.psi.PsiPointcut; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.ide.todo.TodoConfiguration; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.role.EjbClassRole; +import com.intellij.j2ee.ejb.role.EjbDeclMethodRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.RepositoryElementsManager; +import com.intellij.psi.impl.cache.RepositoryIndex; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.cache.impl.idCache.WordInfo; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.jsp.*; +import com.intellij.psi.search.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.StringSearcher; +import gnu.trove.TIntArrayList; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PsiSearchHelperImpl implements PsiSearchHelper { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.PsiSearchHelperImpl"); + + private final PsiManagerImpl myManager; + private final JoinPointSearchHelper myJoinPointSearchHelper; + private static final TokenSet XML_ATTRIBUTE_VALUE_TOKEN_BIT_SET = TokenSet.create(new IElementType[]{ElementType.XML_ATTRIBUTE_VALUE_TOKEN}); + private static final TodoItem[] EMPTY_TODO_ITEMS = new TodoItem[0]; + + public interface CustomSearchHelper { + short getOccurenceMask(); + TokenSet getElementTokenSet(); + boolean caseInsensitive(); + } + + public static class XmlCustomSearchHelper implements CustomSearchHelper { + private TokenSet myTokenSet = TokenSet.create(new IElementType[] { XmlTokenType.XML_NAME}); + private short myOccurenceMask = WordInfo.PLAIN_TEXT; + + public short getOccurenceMask() { + return myOccurenceMask; + } + + public TokenSet getElementTokenSet() { + return myTokenSet; + } + + public boolean caseInsensitive() { + return false; + } + } + + public static class HtmlCustomSearchHelper implements CustomSearchHelper { + private TokenSet myTokenSet = XML_ATTRIBUTE_VALUE_TOKEN_BIT_SET; + private short myOccurenceMask; + + public final void registerStyleCustomSearchHelper(CustomSearchHelper helper) { + myTokenSet = TokenSet.orSet(myTokenSet,helper.getElementTokenSet()); + myOccurenceMask |= helper.getOccurenceMask(); + } + + public short getOccurenceMask() { + return myOccurenceMask; + } + + public TokenSet getElementTokenSet() { + return myTokenSet; + } + + public boolean caseInsensitive() { + return true; + } + } + + static class XHtmlCustomSearchHelper extends HtmlCustomSearchHelper { + public boolean caseInsensitive() { + return false; + } + } + + private static final HashMap CUSTOM_SEARCH_HELPERS = new HashMap(); + + static { + registerCustomSearchHelper(StdFileTypes.HTML,new HtmlCustomSearchHelper()); + registerCustomSearchHelper(StdFileTypes.XHTML,new XHtmlCustomSearchHelper()); + + XmlCustomSearchHelper searchHelper = new XmlCustomSearchHelper(); + registerCustomSearchHelper(StdFileTypes.XML,searchHelper); + registerCustomSearchHelper(StdFileTypes.DTD,searchHelper); + } + + public static void registerCustomSearchHelper(FileType fileType,CustomSearchHelper searchHelper) { + CUSTOM_SEARCH_HELPERS.put(fileType, searchHelper); + } + + public static final CustomSearchHelper getCustomSearchHelper(FileType fileType) { + return CUSTOM_SEARCH_HELPERS.get(fileType); + } + + public PsiSearchHelperImpl(PsiManagerImpl manager) { + myManager = manager; + myJoinPointSearchHelper = new JoinPointSearchHelper(manager, this); + } + + public PsiReference[] findReferences(PsiElement element, SearchScope searchScope, boolean ignoreAccessScope) { + LOG.assertTrue(searchScope != null); + + PsiReferenceProcessor.CollectElements processor = new PsiReferenceProcessor.CollectElements(); + processReferences(processor, element, searchScope, ignoreAccessScope); + return processor.toArray(PsiReference.EMPTY_ARRAY); + } + + public boolean processReferences(final PsiReferenceProcessor processor, + final PsiElement refElement, + SearchScope searchScope, + boolean ignoreAccessScope) { + return processReferences(processor, refElement, searchScope, ignoreAccessScope, true); + } + + private boolean processReferences(final PsiReferenceProcessor processor, + final PsiElement refElement, + SearchScope originalScope, + boolean ignoreAccessScope, + boolean isStrictSignatureSearch) { + LOG.assertTrue(originalScope != null); + + if (refElement instanceof PsiAnnotationMethod) { + PsiMethod method = (PsiMethod)refElement; + if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParameters().length == 0) { + PsiReference[] references = findReferences(method.getContainingClass(), originalScope, ignoreAccessScope); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + if (reference instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference; + if (javaReference.getParent() instanceof PsiAnnotation) { + PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes(); + if (members.length == 1 && members[0].getNameIdentifier() == null) { + processor.execute(members[0].getReference()); + } + } + } + } + } + } + + + String text; +// final boolean[] refTypes = new boolean[ElementType.LAST + 1]; + if (refElement instanceof PsiPackage) { + text = ((PsiPackage)refElement).getName(); + if (text == null) return true; + } + else if (refElement instanceof PsiClass) { + if (refElement instanceof PsiAnonymousClass) return true; + text = ((PsiClass)refElement).getName(); + } + else if (refElement instanceof PsiVariable) { + text = ((PsiVariable)refElement).getName(); + if (text == null) return true; + } + else if (refElement instanceof PsiMethod) { + if (((PsiMethod)refElement).isConstructor()) { + return processConstructorReferences(processor, (PsiMethod)refElement, originalScope, ignoreAccessScope, + isStrictSignatureSearch); + } + + text = ((PsiMethod)refElement).getName(); + } + else if (refElement instanceof PsiAntElement) { + final PsiAntElement antElement = (PsiAntElement)refElement; + final SearchScope searchScope = antElement.getSearchScope().intersectWith(originalScope); + if (searchScope instanceof LocalSearchScope) { + final PsiElement[] scopes = ((LocalSearchScope)searchScope).getScope(); + for (int i = 0; i < scopes.length; i++) { + final PsiElement scope = scopes[i]; + if (!processAntElementScopeRoot(scope, refElement, antElement, processor)) return false; + } + return true; + } + else { + return true; + } + } + else if (refElement instanceof XmlAttributeValue) { + /* + if (((XmlAttributeValue)refElement).isAntPropertyDefinition() || + ((XmlAttributeValue)refElement).isAntTargetDefinition()) { + PsiMetaData metaData = PsiTreeUtil.getParentOfType(refElement, XmlTag.class).getMetaData(); + if (metaData instanceof AntPropertyDeclaration) { + Set properties = ((AntPropertyDeclaration)metaData).getProperties(); + for (Iterator iterator = properties.iterator(); iterator.hasNext();) { + String propertyName = iterator.next(); + PsiReference[] refs = findReferencesInNonJavaFile(refElement.getContainingFile(), refElement, propertyName); + for (int i = 0; i < refs.length; i++) { + if (!processor.execute(refs[i])) return false; + } + } + + return true; + } + } + */ + + text = ((XmlAttributeValue)refElement).getValue(); + } + else if (refElement instanceof PsiPointcutDef) { + text = ((PsiPointcutDef)refElement).getName(); + } + else if (refElement instanceof PsiNamedElement) { + text = ((PsiNamedElement)refElement).getName(); + } + else { + return true; + } + + SearchScope searchScope; + if (!ignoreAccessScope) { + SearchScope accessScope = getAccessScope(refElement); + searchScope = originalScope.intersectWith(accessScope); + if (searchScope == null) return true; + } + else { + searchScope = originalScope; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("visitReferences() search scope: " + searchScope); + } + + final PsiElementProcessorEx processor1 = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + final PsiReference reference = element.findReferenceAt(offsetInElement); + if (reference == null) return true; + if (reference.isReferenceTo(refElement)) { + return processor.execute(reference); + } + else { + return true; + } + } + }; + + final CustomSearchHelper customSearchHelper = getCustomSearchHelper(refElement); + + final short occurrenceMask; + + if (customSearchHelper!=null) { + occurrenceMask = customSearchHelper.getOccurenceMask(); + if (customSearchHelper.caseInsensitive()) text = text.toLowerCase(); + } else if (refElement instanceof XmlAttributeValue) { + occurrenceMask = WordInfo.PLAIN_TEXT; + } + else { + occurrenceMask = WordInfo.IN_CODE | + WordInfo.JSP_ATTRIBUTE_VALUE | + WordInfo.IN_COMMENTS; + } + + final TokenSet elementTypes; + if (customSearchHelper!=null) { + elementTypes = customSearchHelper.getElementTokenSet(); + } else if (refElement instanceof XmlAttributeValue) { + elementTypes = XML_ATTRIBUTE_VALUE_TOKEN_BIT_SET; + } + else { + elementTypes = IDENTIFIER_OR_DOC_VALUE_OR_JSP_ATTRIBUTE_VALUE_BIT_SET; + } + + if (!processElementsWithWord( + processor1, + searchScope, + text, + elementTypes, + occurrenceMask, + customSearchHelper!=null && customSearchHelper.caseInsensitive() + )) { + return false; + } + + if (refElement instanceof PsiMethod) { + PsiMethod method = (PsiMethod)refElement; + if (PropertyUtil.isSimplePropertyAccessor(method)) { + final String propertyName = PropertyUtil.getPropertyName(method); + if (myManager.getNameHelper().isIdentifier(propertyName)) { + if (!processElementsWithWord(processor1, + searchScope, + propertyName, + IDENTIFIER_OR_ATTRIBUTE_VALUE_BIT_SET, + WordInfo.JSP_ATTRIBUTE_VALUE, + false)) { + return false; + } + } + } + } + + if (refElement.getContainingFile() instanceof JspFile) { + boolean canBeAccessedByIncludes; + if (refElement instanceof PsiField || refElement instanceof PsiMethod) { + canBeAccessedByIncludes = refElement.getParent() instanceof JspDeclaration; + } + else if (refElement instanceof JspImplicitVariable) { + canBeAccessedByIncludes = true; + } + else if (refElement instanceof PsiLocalVariable) { + canBeAccessedByIncludes = refElement.getParent().getParent() instanceof JspFile; + } + else { + canBeAccessedByIncludes = false; + } + if (canBeAccessedByIncludes) { + PsiElementProcessor processor2 = new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + return processor1.execute(element, 0); + } + }; + + PsiFile[] files = JspUtil.findIncludingFiles(refElement.getContainingFile(), searchScope); + for (int i = 0; i < files.length; i++) { + if (!processIdentifiers(processor2, text, new LocalSearchScope(files[i]), IdentifierPosition.IN_CODE)) return false; + } + } + } + + if (refElement instanceof PsiPackage && originalScope instanceof GlobalSearchScope) { + if (!UIFormUtil.processReferencesInUIForms(processor, (PsiPackage)refElement, (GlobalSearchScope)originalScope)) return false; + } + else if (refElement instanceof PsiClass && originalScope instanceof GlobalSearchScope) { + if (!UIFormUtil.processReferencesInUIForms(processor, (PsiClass)refElement, (GlobalSearchScope)originalScope)) return false; + } + else if (refElement instanceof PsiField && originalScope instanceof GlobalSearchScope) { + if (!UIFormUtil.processReferencesInUIForms(processor, (PsiField)refElement, (GlobalSearchScope)originalScope)) return false; + } + + return true; + } + + private static CustomSearchHelper getCustomSearchHelper(final PsiElement refElement) { + PsiFile containingFile = refElement.getContainingFile(); + final CustomSearchHelper customSearchHelper = containingFile != null ? CUSTOM_SEARCH_HELPERS.get(containingFile.getFileType()) : null; + return customSearchHelper; + } + + private boolean processAntElementScopeRoot(final PsiElement scope, + final PsiElement refElement, + final PsiAntElement antElement, + final PsiReferenceProcessor processor) { + final PsiReference[] references = findReferencesInNonJavaFile(scope.getContainingFile(), refElement, antElement.getName()); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + if (!processor.execute(reference)) return false; + } + return true; + } + + private boolean processConstructorReferences(final PsiReferenceProcessor processor, + final PsiMethod constructor, + final SearchScope searchScope, + boolean ignoreAccessScope, + final boolean isStrictSignatureSearch) { + LOG.assertTrue(searchScope != null); + + PsiClass aClass = constructor.getContainingClass(); + if (aClass == null) return true; + + if (aClass.isEnum()) { + PsiField[] fields = aClass.getFields(); + for (int i = 0; i < fields.length; i++) { + PsiField field = fields[i]; + if (field instanceof PsiEnumConstant) { + PsiReference reference = field.getReference(); + if (reference != null && reference.isReferenceTo(constructor)) { + if (!processor.execute(reference)) return false; + } + } + } + } + + // search usages like "new XXX(..)" + PsiReferenceProcessor processor1 = new PsiReferenceProcessor() { + public boolean execute(PsiReference reference) { + PsiElement parent = reference.getElement().getParent(); + if (parent instanceof PsiAnonymousClass) { + parent = parent.getParent(); + } + if (parent instanceof PsiNewExpression) { + PsiMethod constructor1 = ((PsiNewExpression)parent).resolveConstructor(); + if (constructor1 != null) { + if (isStrictSignatureSearch) { + if (myManager.areElementsEquivalent(constructor, constructor1)) { + return processor.execute(reference); + } + } + else { + if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) { + return processor.execute(reference); + } + } + } + } + return true; + } + }; + if (!processReferences(processor1, aClass, searchScope, ignoreAccessScope)) return false; + + // search usages like "this(..)" + PsiMethod[] methods = aClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method.isConstructor()) { + PsiCodeBlock body = method.getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement statement = statements[0]; + if (statement instanceof PsiExpressionStatement) { + PsiExpression expr = ((PsiExpressionStatement)statement).getExpression(); + if (expr instanceof PsiMethodCallExpression) { + PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); + if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) { + if (refExpr.getText().equals("this")) { + PsiElement referencedElement = refExpr.resolve(); + if (referencedElement instanceof PsiMethod) { + PsiMethod constructor1 = (PsiMethod)referencedElement; + if (isStrictSignatureSearch) { + if (myManager.areElementsEquivalent(constructor1, constructor)) { + if (!processor.execute(refExpr)) return false; + } + } + else { + if (myManager.areElementsEquivalent(constructor.getContainingClass(), + constructor1.getContainingClass())) { + if (!processor.execute(refExpr)) return false; + } + } + } + } + } + } + } + } + } + } + } + + // search usages like "super(..)" + PsiElementProcessor processor2 = new PsiBaseElementProcessor() { + public boolean execute(PsiClass element) { + PsiClass inheritor = element; + PsiMethod[] methods = inheritor.getMethods(); + for (int j = 0; j < methods.length; j++) { + PsiMethod method = methods[j]; + if (method.isConstructor()) { + PsiCodeBlock body = method.getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement statement = statements[0]; + if (statement instanceof PsiExpressionStatement) { + PsiExpression expr = ((PsiExpressionStatement)statement).getExpression(); + if (expr instanceof PsiMethodCallExpression) { + PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); + if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) { + if (refExpr.getText().equals("super")) { + PsiElement referencedElement = refExpr.resolve(); + if (referencedElement instanceof PsiMethod) { + PsiMethod constructor1 = (PsiMethod)referencedElement; + if (isStrictSignatureSearch) { + if (myManager.areElementsEquivalent(constructor1, constructor)) { + if (!processor.execute(refExpr)) return false; + } + } + else { + if (myManager.areElementsEquivalent(constructor.getContainingClass(), + constructor1.getContainingClass())) { + if (!processor.execute(refExpr)) return false; + } + } + } + } + } + } + } + } + } + } + } + return true; + } + }; + return processInheritors(processor2, aClass, searchScope, false); + } + + public PsiMethod[] findOverridingMethods(PsiMethod method, SearchScope searchScope, boolean checkDeep) { + LOG.assertTrue(searchScope != null); + + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + processOverridingMethods(processor, method, searchScope, checkDeep); + + return processor.toArray(PsiMethod.EMPTY_ARRAY); + } + + public boolean processOverridingMethods(final PsiElementProcessor processor, + final PsiMethod method, + SearchScope searchScope, + final boolean checkDeep) { + LOG.assertTrue(searchScope != null); + + final PsiClass parentClass = method.getContainingClass(); + if (parentClass == null + || method.isConstructor() + || method.hasModifierProperty(PsiModifier.STATIC) + || method.hasModifierProperty(PsiModifier.FINAL) + || method.hasModifierProperty(PsiModifier.PRIVATE) + || parentClass instanceof PsiAnonymousClass + || parentClass.hasModifierProperty(PsiModifier.FINAL)) { + return true; + } + + PsiElementProcessor inheritorsProcessor = new PsiBaseElementProcessor() { + public boolean execute(PsiClass element) { + PsiClass inheritor = element; + PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, + PsiSubstitutor.EMPTY); + MethodSignature signature = method.getSignature(substitutor); + PsiMethod method1 = MethodSignatureUtil.findMethodBySignature(inheritor, signature, false); + if (method1 == null || + method1.hasModifierProperty(PsiModifier.STATIC) || + (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && + !method1.getManager().arePackagesTheSame(parentClass, inheritor))) { + return true; + } + return processor.execute(method1); + } + }; + if (!processInheritors(inheritorsProcessor, parentClass, searchScope, true)) return false; + final EjbMethodRole ejbRole = J2EERolesUtil.getEjbRole(method); + if (ejbRole instanceof EjbDeclMethodRole) { + final PsiMethod[] implementations = ((EjbDeclMethodRole)ejbRole).findImplementations(); + for (int i = 0; i < implementations.length; i++) { + PsiMethod implementation = implementations[i]; + // same signature methods were processed already + if (implementation.getSignature(PsiSubstitutor.EMPTY).equals(method.getSignature(PsiSubstitutor.EMPTY))) continue; + if (!processor.execute(implementation)) return false; + } + } + return true; + } + + public PsiPointcutDef[] findOverridingPointcuts(PsiPointcutDef pointcut, + SearchScope searchScope, + boolean checkDeep) { + LOG.assertTrue(searchScope != null); + + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + processOverridingPointcuts(processor, pointcut, searchScope, checkDeep); + + final Collection foundPointcuts = processor.getCollection(); + return foundPointcuts.toArray(new PsiPointcutDef[foundPointcuts.size()]); + } + + public boolean processOverridingPointcuts(final PsiElementProcessor processor, + final PsiPointcutDef pointcut, + SearchScope searchScope, + boolean checkDeep) { + PsiAspect parentAspect = pointcut.getContainingAspect(); + + if (parentAspect == null || pointcut.hasModifierProperty(PsiModifier.FINAL)) { + return true; + } + + PsiElementProcessor inheritorsProcessor = new PsiBaseElementProcessor() { + public boolean execute(PsiClass element) { + if (!(element instanceof PsiAspect)) return true; + PsiAspect inheritor = (PsiAspect)element; + PsiPointcutDef pointcut1 = inheritor.findPointcutDefBySignature(pointcut, false); + if (pointcut1 == null) return true; + return processor.execute(pointcut1); + } + }; + + return processInheritors(inheritorsProcessor, parentAspect, searchScope, true); + } + + public PsiReference[] findReferencesIncludingOverriding(final PsiMethod method, + SearchScope searchScope, + boolean isStrictSignatureSearch) { + LOG.assertTrue(searchScope != null); + + PsiReferenceProcessor.CollectElements processor = new PsiReferenceProcessor.CollectElements(); + processReferencesIncludingOverriding(processor, method, searchScope, isStrictSignatureSearch); + return processor.toArray(PsiReference.EMPTY_ARRAY); + } + + public boolean processReferencesIncludingOverriding(final PsiReferenceProcessor processor, + final PsiMethod method, + SearchScope searchScope) { + return processReferencesIncludingOverriding(processor, method, searchScope, true); + } + + public boolean processReferencesIncludingOverriding(final PsiReferenceProcessor processor, + final PsiMethod method, + SearchScope searchScope, + final boolean isStrictSignatureSearch) { + LOG.assertTrue(searchScope != null); + + PsiClass parentClass = method.getContainingClass(); + if (method.isConstructor()) { + return processConstructorReferences(processor, method, searchScope, !isStrictSignatureSearch, + isStrictSignatureSearch); + } + + if (isStrictSignatureSearch && (parentClass == null + || parentClass instanceof PsiAnonymousClass + || parentClass.hasModifierProperty(PsiModifier.FINAL) + || method instanceof PsiAnnotationMethod + || method.hasModifierProperty(PsiModifier.STATIC) + || method.hasModifierProperty(PsiModifier.FINAL) + || method.hasModifierProperty(PsiModifier.PRIVATE)) + ) { + return processReferences(processor, method, searchScope, false); + } + + final String text = method.getName(); + final PsiMethod[] methods = isStrictSignatureSearch ? new PsiMethod[]{method} : getOverloadsMayBeOverriden(method); + + SearchScope accessScope = getAccessScope(methods[0]); + for (int i = 0; i < methods.length; i++) { + SearchScope someScope = PsiSearchScopeUtil.scopesUnion(accessScope, getAccessScope(methods[i])); + accessScope = someScope == null ? accessScope : someScope; + } + + final PsiClass aClass = method.getContainingClass(); + + final PsiElementProcessorEx processor1 = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + PsiReference reference = element.findReferenceAt(offsetInElement); + + if (reference != null) { + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (reference.isReferenceTo(method)) { + return processor.execute(reference); + } + PsiElement refElement = reference.resolve(); + + if (refElement instanceof PsiMethod) { + PsiMethod refMethod = (PsiMethod)refElement; + PsiClass refMethodClass = refMethod.getContainingClass(); + if (refMethodClass == null) return true; + + if (!refMethod.hasModifierProperty(PsiModifier.STATIC)) { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(aClass, refMethodClass, PsiSubstitutor.EMPTY); + if (substitutor != null) { + if (method.getSignature(PsiSubstitutor.EMPTY).equals(refMethod.getSignature(substitutor))) { + if (!processor.execute(reference)) return false; + } + } + } + + if (!isStrictSignatureSearch) { + PsiManager manager = method.getManager(); + if (manager.areElementsEquivalent(refMethodClass, aClass)) { + return processor.execute(reference); + } + } + } + else { + return true; + } + } + } + + return true; + } + }; + + searchScope = searchScope.intersectWith(accessScope); + if (searchScope == null) return true; + + short occurrenceMask = WordInfo.IN_CODE | WordInfo.IN_COMMENTS; + boolean toContinue = processElementsWithWord(processor1, + searchScope, + text, + IDENTIFIER_OR_DOC_VALUE_BIT_SET, + occurrenceMask, false); + if (!toContinue) return false; + + if (PropertyUtil.isSimplePropertyAccessor(method)) { + String propertyName = PropertyUtil.getPropertyName(method); + if (myManager.getNameHelper().isIdentifier(propertyName)) { + toContinue = processElementsWithWord(processor1, + searchScope, + propertyName, + IDENTIFIER_OR_ATTRIBUTE_VALUE_BIT_SET, + WordInfo.JSP_ATTRIBUTE_VALUE, false); + if (!toContinue) return false; + } + } + + return true; + } + + public PsiClass[] findInheritors(PsiClass aClass, SearchScope searchScope, boolean checkDeep) { + LOG.assertTrue(searchScope != null); + + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + processInheritors(processor, aClass, searchScope, checkDeep); + return processor.toArray(PsiClass.EMPTY_ARRAY); + } + + public boolean processInheritors(PsiElementProcessor processor, + PsiClass aClass, + SearchScope searchScope, + boolean checkDeep) { + return processInheritors(processor, aClass, searchScope, checkDeep, true); + } + + public boolean processInheritors(PsiElementProcessor processor, + PsiClass aClass, + SearchScope searchScope, + boolean checkDeep, + boolean checkInheritance) { + LOG.assertTrue(searchScope != null); + + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null) { + progress.pushState(); + String className = aClass.getName(); + progress.setText("Searching inheritors" + (className != null ? " of " + className : "") + "..."); + } + + ArrayList processed = new ArrayList(); + processed.add(aClass); + boolean result = processInheritors(processor, aClass, searchScope, checkDeep, processed, + checkInheritance); + + if (progress != null) { + progress.popState(); + } + + return result; + } + + private boolean processInheritors(PsiElementProcessor processor, + PsiClass aClass, + final SearchScope searchScope, + boolean checkDeep, + ArrayList processed, + boolean checkInheritance) { + LOG.assertTrue(searchScope != null); + + if (aClass instanceof PsiAnonymousClass) return true; + + if (aClass.hasModifierProperty(PsiModifier.FINAL)) return true; + + String name = aClass.getName(); + + RepositoryManager repositoryManager = myManager.getRepositoryManager(); + RepositoryElementsManager repositoryElementsManager = myManager.getRepositoryElementsManager(); + + if ("java.lang.Object".equals(aClass.getQualifiedName())) { // special case + // TODO! + } + + if (aClass instanceof PsiAspect) { + PsiAspectManager aspectManager = aClass.getManager().getAspectManager(); + PsiAspect[] aspects = aspectManager.getAspects(); + for (int i = 0; i < aspects.length; i++) { + if (!processInheritorCandidate(processor, aspects[i], aClass, searchScope, checkDeep, processed, + checkInheritance)) { + return false; + } + } + return true; + } + + final SearchScope searchScope1 = searchScope.intersectWith(PsiSearchScopeUtil.getAccessScope(aClass)); + + RepositoryIndex repositoryIndex = repositoryManager.getIndex(); + VirtualFileFilter rootFilter; + if (searchScope1 instanceof GlobalSearchScope) { + rootFilter = repositoryIndex.rootFilterBySearchScope((GlobalSearchScope)searchScope1); + } + else { + rootFilter = null; + } + long[] candidateIds = repositoryIndex.getNameOccurrencesInExtendsLists(name, rootFilter); + for (int i = 0; i < candidateIds.length; i++) { + long id = candidateIds[i]; + PsiClass candidate = (PsiClass)repositoryElementsManager.findOrCreatePsiElementById(id); + LOG.assertTrue(candidate.isValid()); + if (!processInheritorCandidate(processor, candidate, aClass, searchScope, checkDeep, processed, + checkInheritance)) { + return false; + } + } + + final EjbClassRole classRole = J2EERolesUtil.getEjbRole(aClass); + if (classRole != null && classRole.isDeclarationRole()) { + final PsiClass[] implementations = classRole.findImplementations(); + for (int i = 0; i < implementations.length; i++) { + PsiClass candidate = implementations[i]; + if (!processInheritorCandidate(processor, candidate, aClass, searchScope, checkDeep, processed, + checkInheritance)) { + return false; + } + } + } + + return true; + } + + private boolean processInheritorCandidate(PsiElementProcessor processor, + PsiClass candidate, + PsiClass baseClass, + SearchScope searchScope, + boolean checkDeep, + ArrayList processed, + boolean checkInheritance) { + if (checkInheritance || (checkDeep && !(candidate instanceof PsiAnonymousClass))) { + if (!candidate.isInheritor(baseClass, false)) return true; + } + + if (processed.contains(candidate)) return true; + processed.add(candidate); + + if (candidate instanceof PsiAnonymousClass) { + if (!processor.execute(candidate)) return false; + } + else { + if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { + if (searchScope instanceof GlobalSearchScope) { + String qName = candidate.getQualifiedName(); + if (qName != null) { + PsiClass candidate1 = myManager.findClass(qName, (GlobalSearchScope)searchScope); + if (candidate != candidate1) return true; + } + } + if (!processor.execute(candidate)) return false; + } + + if (checkDeep) { + if (!processInheritors(processor, candidate, searchScope, checkDeep, processed, checkInheritance)) return false; + } + } + + return true; + } + + public JspDirective[] findIncludeDirectives(final PsiFile file, SearchScope searchScope) { + LOG.assertTrue(searchScope != null); + + String name = file.getVirtualFile().getName(); + final ArrayList directives = new ArrayList(); + PsiElementProcessorEx processor = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + CompositeElement parent = (SourceTreeToPsiMap.psiElementToTree(element)).getTreeParent(); + if (parent.getElementType() == ElementType.JSP_FILE_REFERENCE) { + CompositeElement pparent = parent.getTreeParent(); + if (SourceTreeToPsiMap.treeElementToPsi(pparent) instanceof JspAttribute && + pparent.getTreeParent().getElementType() == ElementType.JSP_DIRECTIVE) { + JspDirective directive = (JspDirective)SourceTreeToPsiMap.treeElementToPsi(pparent.getTreeParent()); + if (directive.getName().equals("include")) { + JspAttribute attribute = (JspAttribute)SourceTreeToPsiMap.treeElementToPsi(pparent); + if (attribute.getName().equals("file")) { + PsiFile refFile = (PsiFile)((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(parent)).resolve(); + if (file.equals(refFile)) { + directives.add(directive); + } + } + } + } + } + return true; + } + }; + processElementsWithWord(processor, + searchScope, + name, + JSP_DIRECTIVE_ATTRIBUTE_BIT_SET, + WordInfo.JSP_INCLUDE_DIRECTIVE_FILE_NAME, false); + return directives.toArray(new JspDirective[directives.size()]); + } + + private static final TokenSet JSP_DIRECTIVE_ATTRIBUTE_BIT_SET = TokenSet.create(new IElementType[]{ElementType.JSP_DIRECTIVE_ATTRIBUTE_VALUE_TOKEN}); + + public PsiFile[] findFilesWithTodoItems() { + return myManager.getCacheManager().getFilesWithTodoItems(); + } + + private static final TokenSet XML_COMMENT_BIT_SET = TokenSet.create(new IElementType[]{TreeElement.XML_COMMENT_CHARACTERS}); + + public TodoItem[] findTodoItems(PsiFile file) { + return findTodoItems(file, null); + } + + public TodoItem[] findTodoItems(PsiFile file, int startOffset, int endOffset) { + return findTodoItems(file, new TextRange(startOffset, endOffset)); + } + + private TodoItem[] findTodoItems(PsiFile file, TextRange range) { + if (file instanceof PsiBinaryFile || file instanceof PsiCompiledElement || + file.getVirtualFile() == null) { + return EMPTY_TODO_ITEMS; + } + + int count = myManager.getCacheManager().getTodoCount(file.getVirtualFile()); + if (count == 0) { + return EMPTY_TODO_ITEMS; + } + + TIntArrayList commentStarts = new TIntArrayList(); + TIntArrayList commentEnds = new TIntArrayList(); + char[] chars = file.textToCharArray(); + if (file instanceof PsiPlainTextFile) { + commentStarts.add(0); + commentEnds.add(file.getTextLength()); + } + else { + // collect comment offsets to prevent long locks by PsiManagerImpl.LOCK + synchronized (PsiLock.LOCK) { + final Lexer lexer = ((PsiFileImpl)file).createLexer(); + TokenSet COMMENT_TOKEN_BIT_SET; + if (file instanceof PsiJavaFile || file instanceof JspFile) { + COMMENT_TOKEN_BIT_SET = ElementType.COMMENT_BIT_SET; + } + else if (file instanceof XmlFile) { + COMMENT_TOKEN_BIT_SET = XML_COMMENT_BIT_SET; + } + else { + // TODO: ask the lexer about comment types! + //LOG.assertTrue(false); + return EMPTY_TODO_ITEMS; + } + for (lexer.start(chars); ; lexer.advance()) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + + if (range != null) { + if (lexer.getTokenEnd() <= range.getStartOffset()) continue; + if (lexer.getTokenStart() >= range.getEndOffset()) break; + } + + if (COMMENT_TOKEN_BIT_SET.isInSet(tokenType)) { + commentStarts.add(lexer.getTokenStart()); + commentEnds.add(lexer.getTokenEnd()); + } + } + } + } + + ArrayList list = new ArrayList(); + + for (int i = 0; i < commentStarts.size(); i++) { + int commentStart = commentStarts.get(i); + int commentEnd = commentEnds.get(i); + + TodoPattern[] patterns = TodoConfiguration.getInstance().getTodoPatterns(); + for (int j = 0; j < patterns.length; j++) { + TodoPattern toDoPattern = patterns[j]; + Pattern pattern = toDoPattern.getPattern(); + if (pattern != null) { + ProgressManager.getInstance().checkCanceled(); + + CharSequence input = new CharArrayCharSequence(chars, commentStart, commentEnd); + Matcher matcher = pattern.matcher(input); + while (true) { + //long time1 = System.currentTimeMillis(); + boolean found = matcher.find(); + //long time2 = System.currentTimeMillis(); + //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms")); + + if (!found) break; + int start = matcher.start() + commentStart; + int end = matcher.end() + commentStart; + if (start != end) { + if (range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) { + list.add(new TodoItemImpl(file, start, end, toDoPattern)); + } + } + + ProgressManager.getInstance().checkCanceled(); + } + } + } + } + + return list.toArray(new TodoItem[list.size()]); + } + + public int getTodoItemsCount(PsiFile file) { + int count = myManager.getCacheManager().getTodoCount(file.getVirtualFile()); + if (count != -1) return count; + return findTodoItems(file).length; + } + + public int getTodoItemsCount(PsiFile file, TodoPattern pattern) { + int count = myManager.getCacheManager().getTodoCount(file.getVirtualFile(), pattern); + if (count != -1) return count; + TodoItem[] items = findTodoItems(file); + count = 0; + for (int i = 0; i < items.length; i++) { + TodoItem item = items[i]; + if (item.getPattern().equals(pattern)) count++; + } + return count; + } + + public PsiIdentifier[] findIdentifiers(String identifier, SearchScope searchScope, int position) { + LOG.assertTrue(searchScope != null); + + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + processIdentifiers(processor, identifier, searchScope, position); + return processor.toArray(new PsiIdentifier[0]); + } + + public boolean processIdentifiers(final PsiElementProcessor processor, + final String identifier, + SearchScope searchScope, + int position) { + LOG.assertTrue(searchScope != null); + + short occurrenceMask; + switch (position) { + case IdentifierPosition.ANY: + occurrenceMask = WordInfo.ANY; + break; + + case IdentifierPosition.IN_CODE: + occurrenceMask = WordInfo.IN_CODE; + break; + + default: + LOG.assertTrue(false); + return true; + } + + PsiElementProcessorEx processor1 = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + if (element.getText().equals(identifier)) { + return processor.execute(element); + } + return true; + } + }; + return processElementsWithWord(processor1, searchScope, identifier, IDENTIFIER_BIT_SET, occurrenceMask, false); + } + + + public PsiElement[] findThrowUsages(final PsiThrowStatement aThrow, final SearchScope searchScope) { + return new PsiElement[]{aThrow}; + } + + + private static final TokenSet IDENTIFIER_BIT_SET = TokenSet.create(new IElementType[]{ElementType.IDENTIFIER}); + + private static final TokenSet IDENTIFIER_OR_DOC_VALUE_BIT_SET = TokenSet.create(new IElementType[]{ElementType.IDENTIFIER, ElementType.DOC_TAG_VALUE_TOKEN}); + + private static final TokenSet IDENTIFIER_OR_ATTRIBUTE_VALUE_BIT_SET = TokenSet.create(new IElementType[]{ElementType.IDENTIFIER, + ElementType.JSP_ACTION_ATTRIBUTE_VALUE_TOKEN}); + + private static final TokenSet IDENTIFIER_OR_DOC_VALUE_OR_JSP_ATTRIBUTE_VALUE_BIT_SET = TokenSet.create(new IElementType[]{ + ElementType.IDENTIFIER, ElementType.JSP_ACTION_ATTRIBUTE_VALUE_TOKEN, ElementType.DOC_TAG_VALUE_TOKEN}); + + public PsiElement[] findCommentsContainingIdentifier(String identifier, SearchScope searchScope) { + LOG.assertTrue(searchScope != null); + + final ArrayList results = new ArrayList(); + PsiElementProcessorEx processor = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + if (element.findReferenceAt(offsetInElement) == null) { + results.add(element); + } + return true; + } + }; + processElementsWithWord(processor, searchScope, identifier, COMMENT_BIT_SET, WordInfo.IN_COMMENTS, false); + return results.toArray(new PsiElement[results.size()]); + } + + private static final TokenSet COMMENT_BIT_SET = TokenSet.create(new IElementType[]{ + ElementType.DOC_COMMENT_DATA, + ElementType.DOC_TAG_VALUE_TOKEN, + ElementType.C_STYLE_COMMENT, + ElementType.END_OF_LINE_COMMENT}); + + public PsiLiteralExpression[] findStringLiteralsContainingIdentifier(String identifier, SearchScope searchScope) { + LOG.assertTrue(searchScope != null); + + final ArrayList results = new ArrayList(); + PsiElementProcessorEx processor = new PsiElementProcessorEx() { + public boolean execute(PsiElement element, int offsetInElement) { + if (element instanceof PsiLiteralExpression && StringUtil.startsWithChar(element.getText(), '\"')) { + results.add((PsiLiteralExpression)element); + } + return true; + } + }; + processElementsWithWord(processor, + searchScope, + identifier, + LITERAL_EXPRESSION_BIT_SET, + WordInfo.IN_STRING_LITERALS, + false); + return results.toArray(new PsiLiteralExpression[results.size()]); + } + + public boolean processAllClasses(final PsiElementProcessor processor, SearchScope searchScope) { + if (searchScope instanceof GlobalSearchScope) { + return processAllClassesInGlobalScope((GlobalSearchScope)searchScope, processor); + } + + PsiElement[] scopeRoots = ((LocalSearchScope)searchScope).getScope(); + for (int i = 0; i < scopeRoots.length; i++) { + final PsiElement scopeRoot = scopeRoots[i]; + if (!processScopeRootForAllClasses(scopeRoot, processor)) return false; + } + return true; + } + + private static boolean processScopeRootForAllClasses(PsiElement scopeRoot, final PsiElementProcessor processor) { + if (scopeRoot == null) return true; + final boolean[] stopped = new boolean[]{false}; + + scopeRoot.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (!stopped[0]) { + visitElement(expression); + } + } + + public void visitClass(PsiClass aClass) { + stopped[0] = !processor.execute(aClass); + super.visitClass(aClass); + } + }); + + return !stopped[0]; + } + + private boolean processAllClassesInGlobalScope(GlobalSearchScope searchScope, PsiElementProcessor processor) { + myManager.getRepositoryManager().updateAll(); + + LinkedList queue = new LinkedList(); + PsiDirectory[] roots = myManager.getRootDirectories(PsiRootPackageType.SOURCE_PATH); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex(); + for (int i = 0; i < roots.length; i++) { + final PsiDirectory root = roots[i]; + if (fileIndex.isInContent(root.getVirtualFile())) { + queue.addFirst(root); + } + } + + roots = myManager.getRootDirectories(PsiRootPackageType.CLASS_PATH); + for (int i = 0; i < roots.length; i++) { + queue.addFirst(roots[i]); + } + + while (!queue.isEmpty()) { + PsiDirectory dir = queue.removeFirst(); + Module module = ModuleUtil.findModuleForPsiElement(dir); + if (!(module != null ? searchScope.isSearchInModuleContent(module) : searchScope.isSearchInLibraries())) continue; + + PsiDirectory[] subdirectories = dir.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + queue.addFirst(subdirectories[i]); + } + + PsiFile[] files = dir.getFiles(); + for (int i = 0; i < files.length; i++) { + PsiFile file = files[i]; + if (!searchScope.contains(file.getVirtualFile())) continue; + if (!(file instanceof PsiJavaFile)) continue; + + long fileId = myManager.getRepositoryManager().getFileId(file.getVirtualFile()); + if (fileId >= 0) { + long[] allClasses = myManager.getRepositoryManager().getFileView().getAllClasses(fileId); + for (int j = 0; j < allClasses.length; j++) { + PsiClass psiClass = (PsiClass)myManager.getRepositoryElementsManager().findOrCreatePsiElementById(allClasses[j]); + if (!processor.execute(psiClass)) return false; + } + } + else { + if (!processAllClasses(processor, new LocalSearchScope(file))) return false; + } + } + } + + return true; + } + + public PsiClass[] findAllClasses(SearchScope searchScope) { + LOG.assertTrue(searchScope != null); + + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + processAllClasses(processor, searchScope); + return processor.toArray(PsiClass.EMPTY_ARRAY); + } + + static class SearchDescriptor { + private HashSet myNames = new HashSet(); + private HashSet myFiles = new HashSet(); + private HashSet myElements = new HashSet(); + } + + public SearchDescriptor prepareBundleReferenceSearch(PsiElement[] refElements) { + SearchDescriptor descriptor = new SearchDescriptor(); + for (int i = 0; i < refElements.length; i++) { + PsiElement refElement = refElements[i]; + if (refElement instanceof PsiNamedElement) { + String name = ((PsiNamedElement)refElement).getName(); + if (name != null) { + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(name, + WordInfo.IN_CODE, + GlobalSearchScope.allScope(myManager.getProject())); + descriptor.myNames.add(name); + descriptor.myFiles.addAll(Arrays.asList(files)); + descriptor.myElements.add(refElement); + } + } + } + + return descriptor; + } + + public boolean processReferencesToElementsInLocalScope(final PsiReferenceProcessor processor, + final SearchDescriptor bundleSearchDescriptor, + LocalSearchScope scope) { + PsiElement[] scopeElements = scope.getScope(); + for (int i = 0; i < scopeElements.length; i++) { + final PsiElement scopeElement = scopeElements[i]; + if (!processReferencesToElementInScopeElement(scopeElement, bundleSearchDescriptor, processor)) { + return false; + } + } + return true; + + } + + private static boolean processReferencesToElementInScopeElement(PsiElement scopeElement, + final SearchDescriptor bundleSearchDescriptor, + final PsiReferenceProcessor processor) { + if (scopeElement == null) return true; + if (!bundleSearchDescriptor.myFiles.contains(scopeElement.getContainingFile())) return true; + + final PsiElementProcessor processor1 = new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + PsiElement parent = element.getParent(); + if (parent instanceof PsiJavaCodeReferenceElement) { + PsiReference ref = (PsiJavaCodeReferenceElement)parent; + PsiElement target = ref.resolve(); + //TODO: including overriding! + if (bundleSearchDescriptor.myElements.contains(target)) { + return processor.execute(ref); + } + } + + return true; + } + }; + + TreeElement scopeTreeElement = SourceTreeToPsiMap.psiElementToTree(scopeElement); + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + return LowLevelSearchUtil.processIdentifiersBySet(processor1, + scopeTreeElement, + IDENTIFIER_BIT_SET, + bundleSearchDescriptor.myNames, + progress); + } + + public PsiElement[] findJoinPointsByPointcut(PsiPointcut pointcut, SearchScope searchScope) { + return myJoinPointSearchHelper.findJoinPointsByPointcut(pointcut, searchScope); + } + + public boolean processJoinPointsByPointcut(PsiElementProcessor processor, + PsiPointcut pointcut, + SearchScope searchScope) { + return myJoinPointSearchHelper.processJoinPointsByPointcut(processor, pointcut, searchScope); + } + + private static final TokenSet LITERAL_EXPRESSION_BIT_SET = TokenSet.create(new IElementType[]{ElementType.LITERAL_EXPRESSION}); + + private boolean processElementsWithWord(PsiElementProcessorEx processor, + SearchScope searchScope, + String word, + TokenSet elementTypes, + short occurrenceMask, + boolean caseInsensitive) { + LOG.assertTrue(searchScope != null); + + if (searchScope instanceof GlobalSearchScope) { + StringSearcher searcher = new StringSearcher(word); + searcher.setCaseSensitive(!caseInsensitive); + + return processElementsWithWordInGlobalScope(processor, + (GlobalSearchScope)searchScope, + searcher, + elementTypes, + occurrenceMask); + } + else { + LocalSearchScope _scope = (LocalSearchScope)searchScope; + PsiElement[] scopeElements = _scope.getScope(); + + for (int i = 0; i < scopeElements.length; i++) { + final PsiElement scopeElement = scopeElements[i]; + if (!processElementsWithWordInScopeElement(scopeElement, processor, word, elementTypes, caseInsensitive)) return false; + } + return true; + } + } + + private static boolean processElementsWithWordInScopeElement(PsiElement scopeElement, + PsiElementProcessorEx processor, + String word, + TokenSet elementTypes, + boolean caseInsensitive) { + if (SourceTreeToPsiMap.hasTreeElement(scopeElement)) { + StringSearcher searcher = new StringSearcher(word); + searcher.setCaseSensitive(!caseInsensitive); + + return LowLevelSearchUtil.processElementsContainingWordInElement(processor, + scopeElement, + searcher, + elementTypes, + null); + } + else { + return true; + } + } + + private boolean processElementsWithWordInGlobalScope(PsiElementProcessorEx processor, + GlobalSearchScope scope, + StringSearcher searcher, + TokenSet elementTypes, + short occurrenceMask) { + + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + if (progress != null) { + progress.pushState(); + progress.setText("Scanning files..."); + } + myManager.startBatchFilesProcessingMode(); + + try { + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(searcher.getPattern(), occurrenceMask, scope); + + if (progress != null) { + progress.setText("Searching for " + searcher.getPattern() + "..."); + } + + for (int i = 0; i < files.length; i++) { + ProgressManager.getInstance().checkCanceled(); + + PsiFile file = files[i]; + PsiFile[] psiRoots = file.getPsiRoots(); + for (int j = 0; j < psiRoots.length; j++) { + PsiFile psiRoot = psiRoots[j]; + if (!LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, elementTypes, progress)) { + return false; + } + } + + if (progress != null) { + double fraction = (double)i / files.length; + progress.setFraction(fraction); + } + + myManager.dropResolveCaches(); + } + } + finally { + if (progress != null) { + progress.popState(); + } + myManager.finishBatchFilesProcessingMode(); + } + + return true; + } + + public PsiFile[] findFilesWithPlainTextWords(String word) { + return myManager.getCacheManager().getFilesWithWord(word, + WordInfo.PLAIN_TEXT, + GlobalSearchScope.projectScope(myManager.getProject())); + } + + private static PsiReference[] findReferencesInNonJavaFile(PsiFile file, final PsiElement element, String refText) { + class MyRefsProcessor implements PsiNonJavaFileReferenceProcessor { + private List myRefs = new ArrayList(); + + PsiReference[] getResult() { + return myRefs.toArray(new PsiReference[myRefs.size()]); + } + + public boolean process(PsiFile file, int startOffset, int endOffset) { + PsiElement elementAt = file.findElementAt(startOffset); + if (elementAt != null) { + PsiReference ref = elementAt.findReferenceAt(startOffset - elementAt.getTextRange().getStartOffset()); + if (ref != null && ref.isReferenceTo(element)) myRefs.add(ref); + } + + return true; + } + } + + MyRefsProcessor processor = new MyRefsProcessor(); + + char[] text = file.textToCharArray(); + StringSearcher searcher = new StringSearcher(refText); + for (int index = LowLevelSearchUtil.searchWord(text, 0, text.length, searcher); index >= 0;) { + if (!processor.process(file, index, index + searcher.getPattern().length())) break; + index = LowLevelSearchUtil.searchWord(text, index + searcher.getPattern().length(), text.length, searcher); + } + return processor.getResult(); + } + + + public void processUsagesInNonJavaFiles(String qName, + PsiNonJavaFileReferenceProcessor processor, + GlobalSearchScope searchScope) { + ProgressManager progressManager = ProgressManager.getInstance(); + ProgressIndicator progress = progressManager.getProgressIndicator(); + + int dotIndex = qName.lastIndexOf('.'); + int dollarIndex = qName.lastIndexOf('$'); + int maxIndex = Math.max(dotIndex, dollarIndex); + String wordToSearch = maxIndex >= 0 ? qName.substring(maxIndex + 1) : qName; + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(wordToSearch, WordInfo.PLAIN_TEXT, searchScope); + + StringSearcher searcher = new StringSearcher(qName); + searcher.setCaseSensitive(true); + searcher.setForwardDirection(true); + + if (progress != null) { + progress.pushState(); + progress.setText("Analyzing usages in non-java files..."); + } + + AllFilesLoop: + for (int i = 0; i < files.length; i++) { + ProgressManager.getInstance().checkCanceled(); + + PsiFile psiFile = files[i]; + char[] text = psiFile.textToCharArray(); + for (int index = LowLevelSearchUtil.searchWord(text, 0, text.length, searcher); index >= 0;) { + PsiReference referenceAt = psiFile.findReferenceAt(index); + if (referenceAt == null || referenceAt.isSoft()) { //? + if (!processor.process(psiFile, index, index + searcher.getPattern().length())) break AllFilesLoop; + } + + index = LowLevelSearchUtil.searchWord(text, index + searcher.getPattern().length(), text.length, searcher); + } + + if (progress != null) { + progress.setFraction((double)(i + 1) / files.length); + } + } + + if (progress != null) { + progress.popState(); + } + } + + public SearchScope getAccessScope(PsiElement element) { + return PsiSearchScopeUtil.getAccessScope(element); + } + + public PsiFile[] findFormsBoundToClass(String className) { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myManager.getProject()); + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(className, WordInfo.GUI_FORM_CLASS_NAME, + projectScope); + List boundForms = new ArrayList(files.length); + for (int i = 0; i < files.length; i++) { + PsiFile psiFile = files[i]; + LOG.assertTrue(psiFile.getFileType() == StdFileTypes.GUI_DESIGNER_FORM); + String text = psiFile.getText(); + try { + LwRootContainer container = Utils.getRootContainer(text, null); + if (className.equals(container.getClassToBind())) boundForms.add(psiFile); + } + catch (Exception e) { + LOG.debug(e); + } + } + + return boundForms.toArray(new PsiFile[boundForms.size()]); + } + + public boolean isFieldBoundToForm(PsiField field) { + PsiClass aClass = field.getContainingClass(); + if (aClass != null && aClass.getQualifiedName() != null) { + PsiFile[] formFiles = findFormsBoundToClass(aClass.getQualifiedName()); + for (int i = 0; i < formFiles.length; i++) { + PsiFile file = formFiles[i]; + final PsiReference[] references = file.getReferences(); + for (int j = 0; j < references.length; j++) { + final PsiReference reference = references[j]; + if (reference.isReferenceTo(field)) return true; + } + } + } + + return false; + } + + public void processAllFilesWithWord(String word, GlobalSearchScope scope, FileSink sink) { + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(word, WordInfo.IN_CODE, scope); + + for (int i = 0; i < files.length; i++) { + sink.foundFile(files[i]); + } + } + + public void processAllFilesWithWordInComments(String word, GlobalSearchScope scope, FileSink sink) { + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(word, WordInfo.IN_COMMENTS, scope); + + for (int i = 0; i < files.length; i++) { + sink.foundFile(files[i]); + } + } + + public void processAllFilesWithWordInLiterals(String word, GlobalSearchScope scope, FileSink sink) { + PsiFile[] files = myManager.getCacheManager().getFilesWithWord(word, WordInfo.IN_STRING_LITERALS, scope); + + for (int i = 0; i < files.length; i++) { + sink.foundFile(files[i]); + } + } + + private static PsiMethod[] getOverloadsMayBeOverriden(PsiMethod method) { + PsiClass aClass = method.getContainingClass(); + if (aClass == null) return new PsiMethod[]{method}; + PsiMethod[] methods = aClass.findMethodsByName(method.getName(), false); + List result = new ArrayList(); + for (int i = 0; i < methods.length; i++) { + PsiMethod psiMethod = methods[i]; + PsiModifierList modList = psiMethod.getModifierList(); + if (!modList.hasModifierProperty(PsiModifier.STATIC) && + !modList.hasModifierProperty(PsiModifier.FINAL)) { + result.add(psiMethod); + } + } + + //Should not happen + if (result.size() == 0) return new PsiMethod[]{method}; + + return result.toArray(new PsiMethod[result.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/ThrowSearchUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/ThrowSearchUtil.java new file mode 100644 index 00000000000..2dbb3c56224 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/ThrowSearchUtil.java @@ -0,0 +1,167 @@ +package com.intellij.psi.impl.search; + +import com.intellij.find.findUsages.FindUsagesOptions; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.Processor; + +import java.util.HashSet; + +/** + * Author: msk + */ +public class ThrowSearchUtil { + + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.ThrowSearchUtil"); + + private final PsiManager myManager; + private final PsiSearchHelper myHelper; + private final Processor myResults; + private final FindUsagesOptions myOptions; + private final Root myRoot; + + private final HashSet myReadySet; + + public static class Root { + final PsiElement myElement; + final PsiType myType; + final boolean isExact; + + public Root(final PsiElement root, final PsiType type, final boolean exact) { + myElement = root; + myType = type; + isExact = exact; + } + + public String toString() { + return PsiFormatUtil.formatType (myType, PsiFormatUtil.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); + } + } + + public ThrowSearchUtil (final Processor processor, final Root root, final FindUsagesOptions options) { + myRoot = root; + myResults = processor; + myOptions = options; + myManager = myRoot.myElement.getManager (); + myHelper = myManager.getSearchHelper(); + myReadySet = new HashSet(); + } + + /** + * @param aCatch + * @return true, if we should continue processing + */ + + private boolean processExn (final PsiParameter aCatch) { + final PsiType type = aCatch.getType(); + if (type.isAssignableFrom(myRoot.myType)) { + myResults.process (new UsageInfo (aCatch)); + return false; + } + else if (myOptions.isStrictThrowUsages && !myRoot.isExact && myRoot.myType.isAssignableFrom (type)) { + myResults.process (new UsageInfo (aCatch)); + return true; + } + else { + return true; + } + } + + private void scanCatches (PsiElement elem) + { + while (elem != null) { + final PsiElement parent = elem.getParent(); + if (elem instanceof PsiMethod) { + final PsiMethod method = (PsiMethod) elem; + if (!myReadySet.contains(method)) { + myReadySet.add(method); + final PsiReference[] refs = myHelper.findReferencesIncludingOverriding(method, myOptions.searchScope, true); + for (int i = 0; i != refs.length; ++ i) + scanCatches(refs [i].getElement ()); + } + return; + } + else if (elem instanceof PsiTryStatement) { + final PsiTryStatement aTry = (PsiTryStatement) elem; + final PsiParameter[] catches = aTry.getCatchBlockParameters(); + for (int i = 0; i != catches.length; ++ i) { + if (!processExn(catches[i])) { + return; + } + } + } + else if (parent instanceof PsiTryStatement) { + final PsiTryStatement tryStmt = (PsiTryStatement) parent; + if (elem != tryStmt.getTryBlock()) { + elem = parent.getParent(); + continue; + } + } + elem = parent; + } + } + + public void run() { + scanCatches (myRoot.myElement); + } + + /** + * + * @param exn + * @return is type of exn exactly known + */ + + public static boolean isExactExnType(final PsiExpression exn) { + if (exn instanceof PsiNewExpression) + return true; + else + return false; + } + + public static Root [] getSearchRoots (final PsiElement element) { + if (element instanceof PsiThrowStatement) { + final PsiThrowStatement aThrow = (PsiThrowStatement) element; + final PsiExpression exn = aThrow.getException(); + return new Root[]{new Root (aThrow.getParent(), exn.getType(), isExactExnType(exn))}; + } + if (element instanceof PsiKeyword) { + final PsiKeyword kwd = (PsiKeyword) element; + if (PsiKeyword.THROWS.equals (kwd.getText())) { + final PsiElement parent = kwd.getParent(); + if (parent != null && parent.getParent() instanceof PsiMethod) { + final PsiMethod method = (PsiMethod) parent.getParent(); + final PsiReferenceList throwsList = method.getThrowsList(); + final PsiClassType[] exns = throwsList.getReferencedTypes(); + final Root [] roots = new Root [exns.length]; + for (int i = 0; i != roots.length; ++ i) { + final PsiClassType exn = exns [i]; + roots [i] = new Root (method, exn, false); // TODO: test for final + } + return roots; + } + } + } + return null; + } + + public static boolean isSearchable(final PsiElement element) { + return getSearchRoots (element) != null; + } + + public static String getSearchableTypeName(final PsiElement e) { + if (e instanceof PsiThrowStatement) { + final PsiThrowStatement aThrow = (PsiThrowStatement) e; + final PsiType type = aThrow.getException ().getType (); + return PsiFormatUtil.formatType (type, PsiFormatUtil.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); + } + if (e instanceof PsiKeyword && PsiKeyword.THROWS.equals (e.getText())) { + return e.getParent().getText (); + } + LOG.error ("invalid searchable element"); + return e.getText(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/TodoItemImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/TodoItemImpl.java new file mode 100644 index 00000000000..08118cd92c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/search/TodoItemImpl.java @@ -0,0 +1,53 @@ + +package com.intellij.psi.impl.search; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.search.TodoItem; +import com.intellij.psi.search.TodoPattern; + +public class TodoItemImpl implements TodoItem { + private final PsiFile myFile; + private final int myStartOffset; + private final int myEndOffset; + private final TodoPattern myPattern; + + public TodoItemImpl(PsiFile file, int startOffset, int endOffset, TodoPattern pattern) { + myFile = file; + myStartOffset = startOffset; + myEndOffset = endOffset; + myPattern = pattern; + } + + public PsiFile getFile() { + return myFile; + } + + public TextRange getTextRange() { + return new TextRange(myStartOffset, myEndOffset); + } + + public TodoPattern getPattern() { + return myPattern; + } + + public int hashCode(){ + return myFile.hashCode()+myStartOffset+myEndOffset+myPattern.hashCode(); + } + + public boolean equals(Object obj){ + if(!(obj instanceof TodoItemImpl)){ + return false; + } + TodoItemImpl todoItem=(TodoItemImpl)obj; + if( + !myFile.equals(todoItem.myFile)|| + myStartOffset!=todoItem.myStartOffset|| + myEndOffset!=todoItem.myEndOffset|| + !myPattern.equals(todoItem.myPattern) + ){ + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java new file mode 100644 index 00000000000..273708eb200 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.dupLocator.util.PsiAnchor; +import com.intellij.psi.*; + +public class LazyPointerImpl implements SmartPointerEx { + private PsiElement myElement = null; + private PsiAnchor myAnchor = null; + private SmartPsiElementPointer myPointer = null; + + public LazyPointerImpl(PsiElement element) { + if (element instanceof PsiCompiledElement) { + myElement = element; + } + else if (element instanceof PsiMember) { + myPointer = setupPointer(element); + } + else { + myAnchor = new PsiAnchor(element); + } + } + + private SmartPsiElementPointer setupPointer(PsiElement element) { + return SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); + } + + public void fastenBelt() { + if (myAnchor != null) { + myPointer = setupPointer(myAnchor.retrieve()); + ((SmartPointerEx)myPointer).fastenBelt(); + myAnchor = null; + } + } + + public void documentAndPsiInSync() { + } + + public PsiElement getElement() { + if (myElement != null) return myElement.isValid() ? myElement : null; + if (myPointer != null) return myPointer.getElement(); + return myAnchor.retrieve(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerEx.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerEx.java new file mode 100644 index 00000000000..ae2977908ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerEx.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.psi.SmartPsiElementPointer; + +public interface SmartPointerEx extends SmartPsiElementPointer { + void fastenBelt(); + void documentAndPsiInSync(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java new file mode 100644 index 00000000000..250099f5ba3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -0,0 +1,333 @@ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiSubstitutorImpl; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.PsiImmediateClassType; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class SmartPointerManagerImpl extends SmartPointerManager implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl"); + + private static final Key>> SMART_POINTERS_IN_PSI_FILE_KEY = Key.create( + "SMART_POINTERS_IN_DOCUMENT_KEY"); + private static final Key BELTS_ARE_FASTEN_KEY = Key.create("BELTS_ARE_FASTEN_KEY"); + + private final Project myProject; + + public SmartPointerManagerImpl(Project project) { + myProject = project; + } + + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "SmartPointerManager"; + } + + public void initComponent() { } + + public void disposeComponent() { + } + + public void fastenBelts(PsiFile file) { + synchronized (file) { + file.putUserData(BELTS_ARE_FASTEN_KEY, Boolean.TRUE); + + ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + if (pointers == null) return; + + int index = 0; + for (int i = 0; i < pointers.size(); i++) { + WeakReference reference = pointers.get(i); + SmartPointerEx pointer = reference.get(); + if (pointer != null) { + pointer.fastenBelt(); + pointers.set(index++, reference); + } + } + + int size = pointers.size(); + for (int i = size - 1; i >= index; i--) { + pointers.remove(i); + } + } + } + + public void unfastenBelts(PsiFile file) { + synchronized (file) { + file.putUserData(BELTS_ARE_FASTEN_KEY, null); + } + } + + public void synchronizePointers(PsiFile file) { + synchronized (file) { + ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + if (pointers == null) return; + + int index = 0; + for (int i = 0; i < pointers.size(); i++) { + WeakReference reference = pointers.get(i); + SmartPointerEx pointer = reference.get(); + if (pointer != null) { + pointer.documentAndPsiInSync(); + pointers.set(index++, reference); + } + } + + int size = pointers.size(); + for (int i = size - 1; i >= index; i--) { + pointers.remove(i); + } + } + } + + public SmartPsiElementPointer createSmartPsiElementPointer(PsiElement element) { + if (!element.isValid()) { + LOG.assertTrue(false, "Invalid element:" + element); + } + + SmartPointerEx pointer = new SmartPsiElementPointerImpl(myProject, element); + initPointer(element, pointer); + + return pointer; + } + + private void initPointer(PsiElement element, SmartPointerEx pointer) { + PsiFile file = element.getContainingFile(); + if (file != null) { + synchronized (file) { + Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file); + if (document != null) { + //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional + if (!(element instanceof PsiFile)) { + LOG.assertTrue(!PsiDocumentManager.getInstance(myProject).isUncommited(document)); + } + } + + ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + if (pointers == null) { + pointers = new ArrayList>(); + file.putUserData(SMART_POINTERS_IN_PSI_FILE_KEY, pointers); + } + pointers.add(new WeakReference(pointer)); + + Boolean isFasten = file.getUserData(BELTS_ARE_FASTEN_KEY); + if (isFasten == Boolean.TRUE) { + pointer.fastenBelt(); + } + } + } + } + + public SmartTypePointer createSmartTypePointer(PsiType type) { + return type.accept(new SmartTypeCreatingVisitor()); + } + + public SmartPsiElementPointer createLazyPointer(PsiElement element) { + LazyPointerImpl pointer = new LazyPointerImpl(element); + initPointer(element, pointer); + return pointer; + } + + private static class SimpleTypePointer implements SmartTypePointer { + private final PsiType myType; + + private SimpleTypePointer(PsiType type) { + myType = type; + } + + public PsiType getType() { + return myType; + } + } + + private static class ArrayTypePointer implements SmartTypePointer { + private PsiType myType; + private final SmartTypePointer myComponentTypePointer; + + public ArrayTypePointer(PsiType type, SmartTypePointer componentTypePointer) { + myType = type; + myComponentTypePointer = componentTypePointer; + } + + public PsiType getType() { + if (myType.isValid()) return myType; + final PsiType type = myComponentTypePointer.getType(); + if (type == null) { + myType = null; + } + else { + myType = new PsiArrayType(type); + } + return myType; + } + } + + private static class WildcardTypePointer implements SmartTypePointer { + private PsiWildcardType myType; + private PsiManager myManager; + private final SmartTypePointer myBoundPointer; + private boolean myIsExtending; + + public WildcardTypePointer(PsiWildcardType type, SmartTypePointer boundPointer) { + myType = type; + myManager = myType.getManager(); + myBoundPointer = boundPointer; + myIsExtending = myType.isExtends(); + } + + public PsiType getType() { + if (myType.isValid()) return myType; + if (myBoundPointer == null) { + return PsiWildcardType.createUnbounded(myManager); + } + else { + if (myIsExtending) { + return PsiWildcardType.createExtends(myManager, myBoundPointer.getType()); + } + else { + return PsiWildcardType.createSuper(myManager, myBoundPointer.getType()); + } + } + } + } + + + private static class ClassTypePointer implements SmartTypePointer { + private PsiType myType; + private final SmartPsiElementPointer myClass; + private final Map myMap; + + + public ClassTypePointer(PsiType type, + SmartPsiElementPointer aClass, + Map map) { + myType = type; + myClass = aClass; + myMap = map; + } + + public PsiType getType() { + if (myType.isValid()) return myType; + final PsiElement classElement = myClass.getElement(); + if (!(classElement instanceof PsiClass)) return null; + Map resurrected = new HashMap(); + final Set> set = myMap.entrySet(); + for (Iterator> iterator = set.iterator(); + iterator.hasNext();) { + Map.Entry entry = iterator.next(); + PsiElement element = entry.getKey().getElement(); + if (element instanceof PsiTypeParameter) { + resurrected.put(((PsiTypeParameter)element), entry.getValue().getType()); + } + } + Iterator iterator = PsiUtil.typeParametersIterator((PsiClass) classElement); + while (iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + if (!resurrected.containsKey(typeParameter)) { + resurrected.put(typeParameter, null); + } + } + final PsiSubstitutor resurrectedSubstitutor = PsiSubstitutorImpl.createSubstitutor(resurrected); + myType = new PsiImmediateClassType(((PsiClass)classElement), resurrectedSubstitutor); + return myType; + } + } + + private class ClassReferenceTypePointer implements SmartTypePointer { + private PsiType myType; + private final SmartPsiElementPointer mySmartPsiElementPointer; + private final String myReferenceText; + + ClassReferenceTypePointer(PsiClassReferenceType type) { + myType = type; + final PsiJavaCodeReferenceElement reference = type.getReference(); + mySmartPsiElementPointer = createSmartPsiElementPointer(reference); + myReferenceText = reference.getText(); + } + + public PsiType getType() { + if (myType.isValid()) return myType; + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)mySmartPsiElementPointer.getElement(); + final PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + if (referenceElement != null) { + final PsiClassType type = factory.createType(referenceElement); + myType = type; + } + else { + try { + myType = factory.createTypeFromText(myReferenceText, null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + return myType; + } + } + + private class SmartTypeCreatingVisitor extends PsiTypeVisitor { + public SmartTypePointer visitPrimitiveType(PsiPrimitiveType primitiveType) { + return new SimpleTypePointer(primitiveType); + } + + public SmartTypePointer visitArrayType(PsiArrayType arrayType) { + return new ArrayTypePointer(arrayType, arrayType.getComponentType().accept(this)); + } + + public SmartTypePointer visitWildcardType(PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); + final SmartTypePointer boundPointer; + if (bound == null) { + boundPointer = null; + } + else { + boundPointer = bound.accept(this); + } + return new WildcardTypePointer(wildcardType, boundPointer); + } + + public SmartTypePointer visitClassType(PsiClassType classType) { + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass aClass = resolveResult.getElement(); + if (aClass == null) { + LOG.assertTrue(classType instanceof PsiClassReferenceType); + return new ClassReferenceTypePointer((PsiClassReferenceType)classType); + } + if (classType instanceof PsiClassReferenceType) { + classType = ((PsiClassReferenceType)classType).createImmediateCopy(); + } + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + final com.intellij.util.containers.HashMap map = new com.intellij.util.containers.HashMap(); + final Iterator iterator = PsiUtil.typeParametersIterator(aClass); + while (iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + final PsiType substitutionResult = substitutor.substitute(typeParameter); + if (substitutionResult != null) { + final SmartPsiElementPointer pointer = createSmartPsiElementPointer(typeParameter); + map.put(pointer, substitutionResult.accept(this)); + } + } + return new ClassTypePointer(classType, createSmartPsiElementPointer(aClass), map); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java new file mode 100644 index 00000000000..f98d6d2a2ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -0,0 +1,307 @@ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.xml.XmlChildRole; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.xml.XmlTokenType; + +class SmartPsiElementPointerImpl implements SmartPointerEx { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.psi.impl.smartPointers.SmartPsiElementPointerImpl"); + + private PsiElement myElement; + private ElementInfo myElementInfo; + private final Project myProject; + + private static interface ElementInfo { + Document getDocumentToSynchronize(); + + void documentAndPsiInSync(); + + PsiElement restoreElement(); + } + + public SmartPsiElementPointerImpl(Project project, PsiElement element) { + myProject = project; + ApplicationManager.getApplication().assertReadAccessAllowed(); + myElement = element; + myElementInfo = null; + + // Assert document commited. + PsiFile file = element.getContainingFile(); + if (file != null) { + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + Document doc = documentManager.getCachedDocument(file); + if (doc != null) { + //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional + if (!(element instanceof PsiFile)) { + LOG.assertTrue(!documentManager.isUncommited(doc)); + } + } + } + } + + public boolean equals(Object obj) { + if (!(obj instanceof SmartPsiElementPointer)) return false; + SmartPsiElementPointer pointer = (SmartPsiElementPointer)obj; + return Comparing.equal(pointer.getElement(), getElement()); + } + + public int hashCode() { + PsiElement element = getElement(); + return element != null ? element.hashCode() : 0; + } + + public PsiElement getElement() { + if (myElement != null && !myElement.isValid()) { + if (myElementInfo == null) { + myElement = null; + } + else { + PsiElement restored = myElementInfo.restoreElement(); + if (restored != null && (!areElementKindEqual(restored, myElement) || !restored.isValid())) { + restored = null; + } + myElement = restored; + } + } + + if (myElementInfo != null && myElement != null) { + Document document = myElementInfo.getDocumentToSynchronize(); + if (document != null && PsiDocumentManager.getInstance(myProject).isUncommited(document)) return myElement; // keep element info if document is modified + } + myElementInfo = null; + + return myElement; + } + + private ElementInfo createElementInfo() { + if (myElement instanceof PsiCompiledElement) return null; + + if (myElement.getContainingFile() == null) return null; + + if (myElement instanceof PsiImportList) { + return new ImportListInfo((PsiJavaFile)myElement.getContainingFile()); + } + else { + LOG.assertTrue(myElement.isPhysical()); + PsiElement anchor = getAnchor(myElement); + if (anchor != null) { + return new AnchorElementInfo(anchor); + } + else { + return new SelfElementInfo(myElement); + } + } + } + + private static PsiElement getAnchor(PsiElement element) { + LOG.assertTrue(element.isValid()); + PsiElement anchor = null; + if (element instanceof PsiClass) { + if (element instanceof PsiAnonymousClass) { + anchor = ((PsiAnonymousClass)element).getBaseClassReference().getReferenceNameElement(); + } + else { + anchor = ((PsiClass)element).getNameIdentifier(); + } + } + else if (element instanceof PsiMethod) { + anchor = ((PsiMethod)element).getNameIdentifier(); + } + else if (element instanceof PsiVariable) { + anchor = ((PsiVariable)element).getNameIdentifier(); + } + else if (element instanceof XmlTag) { + anchor = SourceTreeToPsiMap.treeElementToPsi(XmlChildRole.START_TAG_NAME_FINDER.findChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(element))); + } + return anchor; + } + + private static boolean areElementKindEqual(PsiElement element1, PsiElement element2) { + if (element1 instanceof PsiType) { + return element2 instanceof PsiType; + } + + return element1.getClass().equals(element2.getClass()); //? + } + + public void documentAndPsiInSync() { + if (myElementInfo != null) { + myElementInfo.documentAndPsiInSync(); + } + } + + public void fastenBelt() { + if (myElementInfo == null && myElement != null && myElement.isValid()) { + myElementInfo = createElementInfo(); + } + } + + private static class SelfElementInfo implements ElementInfo { + protected PsiFile myFile; + private RangeMarker myMarker; + private int mySyncStartOffset; + private int mySyncEndOffset; + private boolean mySyncMarkerIsValid; + private Class myType; + + public SelfElementInfo(PsiElement anchor) { + LOG.assertTrue(anchor.isPhysical()); + myFile = anchor.getContainingFile(); + TextRange range = anchor.getTextRange(); + + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myFile.getProject()); + Document document = documentManager.getDocument(myFile); + LOG.assertTrue(!documentManager.isUncommited(document)); + myMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); + + mySyncStartOffset = range.getStartOffset(); + mySyncEndOffset = range.getEndOffset(); + mySyncMarkerIsValid = true; + myType = anchor.getClass(); + } + + public Document getDocumentToSynchronize() { + return myMarker.getDocument(); + } + + public void documentAndPsiInSync() { + if (!myMarker.isValid()) { + mySyncMarkerIsValid = false; + return; + } + + mySyncStartOffset = myMarker.getStartOffset(); + mySyncEndOffset = myMarker.getEndOffset(); + } + + public PsiElement restoreElement() { + if (!mySyncMarkerIsValid) return null; + if (!myFile.isValid()) return null; + + PsiElement anchor = myFile.findElementAt(mySyncStartOffset); + if (anchor == null) return null; + + TextRange range = anchor.getTextRange(); + + if (range.getStartOffset() != mySyncStartOffset) return null; + while (range.getEndOffset() < mySyncEndOffset) { + anchor = anchor.getParent(); + if (anchor == null || anchor.getTextRange() == null) break; + range = anchor.getTextRange(); + } + + while (range.getEndOffset() == mySyncEndOffset && anchor != null && !myType.equals(anchor.getClass())) { + anchor = anchor.getParent(); + if (anchor == null || anchor.getTextRange() == null) break; + range = anchor.getTextRange(); + } + + if (range.getEndOffset() == mySyncEndOffset) return anchor; + return null; + } + } + + private static class AnchorElementInfo implements ElementInfo { + protected PsiFile myFile; + private RangeMarker myMarker; + private int mySyncStartOffset; + private int mySyncEndOffset; + private boolean mySyncMarkerIsValid; + + public AnchorElementInfo(PsiElement anchor) { + LOG.assertTrue(anchor.isPhysical()); + myFile = anchor.getContainingFile(); + TextRange range = anchor.getTextRange(); + + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myFile.getProject()); + Document document = documentManager.getDocument(myFile); + LOG.assertTrue(!documentManager.isUncommited(document)); + myMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); + + mySyncStartOffset = range.getStartOffset(); + mySyncEndOffset = range.getEndOffset(); + mySyncMarkerIsValid = true; + } + + public Document getDocumentToSynchronize() { + return myMarker.getDocument(); + } + + public void documentAndPsiInSync() { + if (!myMarker.isValid()) { + mySyncMarkerIsValid = false; + return; + } + + mySyncStartOffset = myMarker.getStartOffset(); + mySyncEndOffset = myMarker.getEndOffset(); + } + + public PsiElement restoreElement() { + if (!mySyncMarkerIsValid) return null; + if (!myFile.isValid()) return null; + + PsiElement anchor = myFile.findElementAt(mySyncStartOffset); + if (anchor == null) return null; + + TextRange range = anchor.getTextRange(); + if (range.getStartOffset() != mySyncStartOffset || range.getEndOffset() != mySyncEndOffset) return null; + + if (anchor instanceof PsiIdentifier) { + PsiElement parent = anchor.getParent(); + if (parent instanceof PsiJavaCodeReferenceElement) { // anonymous class, type + parent = parent.getParent(); + } + + if (!anchor.equals(getAnchor(parent))) return null; + + return parent; + } + else if (anchor instanceof XmlToken) { + XmlToken token = (XmlToken)anchor; + + if (token.getTokenType() == XmlTokenType.XML_NAME) { + return token.getParent(); + } + else { + return null; + } + } + else { + return null; + } + } + } + + private static class ImportListInfo implements ElementInfo { + private final PsiJavaFile myFile; + + public ImportListInfo(PsiJavaFile file) { + myFile = file; + } + + public PsiElement restoreElement() { + if (!myFile.isValid()) return null; + return myFile.getImportList(); + } + + public Document getDocumentToSynchronize() { + return null; + } + + public void documentAndPsiInSync() { + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CharTableImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CharTableImpl.java new file mode 100644 index 00000000000..c77d6f10bd9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CharTableImpl.java @@ -0,0 +1,140 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.CharTable; +import gnu.trove.TObjectIntHashMap; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 07.06.2004 + * Time: 15:37:59 + * To change this template use File | Settings | File Templates. + */ +public class CharTableImpl implements CharTable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.CharTableImpl"); + private final TObjectIntHashMap myEntries = new TObjectIntHashMap(); + private char[] myCurrentPage = null; + private CharTableEntry[] myReferences = new CharTableEntry[0]; + private int currentReferencesEnd = 1; + private int bufferEnd = 0; + + public CharTableImpl() { + bufferEnd = PAGE_SIZE; + } + + public int getId(String str) { + return getId(str.toCharArray(), 0, str.length()); + } + + public int checkId(String str) { + return myEntries.get(str); + } + + public int copyTo(int id, char[] buffer, int startOffset) { + final CharTableEntry arrayElement = myReferences[id]; + final int length = arrayElement.length; + System.arraycopy(arrayElement.buffer, arrayElement.offset, buffer, startOffset, length); + return startOffset + length; + } + + public int getId(char[] buffer, int offset, int length) { + final int index = myEntries.get(StringFactory.createStringFromConstantArray(buffer, offset, length)); + if(index <= 0){ + final CharTableEntry entry = createEntry(buffer, offset, length); + final int refsLength = myReferences.length; + if(currentReferencesEnd >= refsLength - 1){ + final CharTableEntry[] oldReferences = myReferences; + myReferences = new CharTableEntry[(int)(refsLength + Math.max(5, refsLength * 0.1))]; + System.arraycopy(oldReferences, 0, myReferences, 0, refsLength); + } + myEntries.put(entry, currentReferencesEnd); + myReferences[currentReferencesEnd++ - 1] = entry; + return currentReferencesEnd - 1; + } + return index; + } + + private CharTableEntry createEntry(char[] buffer, int offset, int length) { + if(length > PAGE_SIZE){ + // creating new page in case of long (>PAGE_SIZE) token + final char[] page = new char[length]; + System.arraycopy(buffer, offset, page, 0, length); + return new CharTableEntry(page, 0, length); + } + + if(myCurrentPage == null || PAGE_SIZE - bufferEnd < length){ + // append to buffer + myCurrentPage = new char[PAGE_SIZE]; + bufferEnd = 0; + } + System.arraycopy(buffer, offset, myCurrentPage, bufferEnd, length); + bufferEnd += length; + return new CharTableEntry(myCurrentPage, bufferEnd - length, length); + } + + public Entry getEntry(int id) { + checkId(id); + return myReferences[id - 1]; + } + + public void checkId(int id) { + if(id < 0 || id >= currentReferencesEnd){ + LOG.assertTrue(false); + } + } + + private static final class CharTableEntry implements Entry{ + char[] buffer; + int offset; + int length; + + public CharTableEntry(char[] buffer, int offset, int length) { + this.buffer = buffer; + this.offset = offset; + this.length = length; + } + + public int hashCode() { + int off = offset; + int h = 0; + for (int i = 0; i < length; i++) { + h = 31*h + buffer[off++]; + } + return h; + } + + public boolean equals(Object o) { + if(o instanceof String){ + String str = (String)o; + if(str.length() != length) return false; + int off = offset; + for (int i = 0; i < length; i++) { + if(buffer[off++] != str.charAt(i)) return false; + } + return true; + } + else if(o instanceof CharTableEntry){ + final CharTableEntry entry = (CharTableEntry)o; + return buffer == entry.buffer && offset == entry.offset && length == entry.length; + } + return false; + } + + public char[] getBuffer() { + return buffer; + } + + public int getOffset() { + return offset; + } + + public int getLength() { + return length; + } + + public String toString() { + return StringFactory.createStringFromConstantArray(buffer, offset, length); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CodeFragmentElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CodeFragmentElement.java new file mode 100644 index 00000000000..75c4b0e3578 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/CodeFragmentElement.java @@ -0,0 +1,9 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.impl.source.tree.FileElement; + +public class CodeFragmentElement extends FileElement { + public CodeFragmentElement() { + super(CODE_FRAGMENT); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/Constants.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/Constants.java new file mode 100644 index 00000000000..029c6ba2885 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/Constants.java @@ -0,0 +1,121 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.impl.source.tree.ElementType; + +public interface Constants extends ElementType { + public static interface PsiElementArrayConstructor { + PsiElement[] newPsiElementArray(int length); + } + + public static final PsiElementArrayConstructor PSI_ELEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiElement[length] : PsiElement.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_CLASS_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiClass[length] : PsiClass.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_FIELD_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiField[length] : PsiField.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_METHOD_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiMethod[length] : PsiMethod.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_CLASS_INITIALIZER_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiClassInitializer[length] : PsiClassInitializer.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_PARAMETER_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiParameter[length] : PsiParameter.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_CATCH_SECTION_ARRAYS_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiCatchSection[length] : PsiCatchSection.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiJavaCodeReferenceElement[length] : PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiStatement[length] : PsiStatement.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_EXPRESSION_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiExpression[length] : PsiExpression.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_IMPORT_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiImportStatement[length] : EMPTY; + } + + private final PsiElement[] EMPTY = new PsiImportStatement[0]; + }; + + public static final PsiElementArrayConstructor PSI_IMPORT_STATIC_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiImportStaticStatement[length] : PsiImportStaticStatement.EMPTY_ARRAY; + } + }; + + + public static final PsiElementArrayConstructor PSI_IMPORT_STATEMENT_BASE_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiImportStatementBase[length] : PsiImportStatementBase.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_ANNOTATION_MEMBER_VALUE_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiAnnotationMemberValue[length] : PsiAnnotationMemberValue.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_NAME_VALUE_PAIR_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiNameValuePair[length] : PsiNameValuePair.EMPTY_ARRAY; + } + }; + + public static final PsiElementArrayConstructor PSI_ANNOTATION_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiAnnotation[length] : PsiAnnotation.EMPTY_ARRAY; + } + }; + + TokenSet CLASS_BIT_SET = TokenSet.create(new IElementType[]{CLASS}); + TokenSet FIELD_BIT_SET = TokenSet.create(new IElementType[]{FIELD, ENUM_CONSTANT}); + TokenSet METHOD_BIT_SET = TokenSet.create(new IElementType[]{METHOD, ANNOTATION_METHOD}); + TokenSet CLASS_INITIALIZER_BIT_SET = TokenSet.create(new IElementType[]{CLASS_INITIALIZER}); + TokenSet PARAMETER_BIT_SET = TokenSet.create(new IElementType[]{PARAMETER}); + TokenSet CATCH_SECTION_BIT_SET = TokenSet.create(new IElementType[]{CATCH_SECTION}); + TokenSet JAVA_CODE_REFERENCE_BIT_SET = TokenSet.create(new IElementType[]{JAVA_CODE_REFERENCE}); + TokenSet NAME_VALUE_PAIR_BIT_SET = TokenSet.create(new IElementType[]{NAME_VALUE_PAIR}); + public static final TokenSet ANNOTATION_BIT_SET = TokenSet.create(new IElementType[]{ANNOTATION}); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolder.java new file mode 100644 index 00000000000..67ff8ace392 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolder.java @@ -0,0 +1,157 @@ +package com.intellij.psi.impl.source; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.SharedImplUtil; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.CharTable; + +import java.util.Iterator; +import java.util.LinkedHashMap; + +public class DummyHolder extends PsiFileImpl implements PsiImportHolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.DummyHolder"); + + private PsiElement myContext; + private CharTable myTable = null; + private final LinkedHashMap myPseudoImports = new LinkedHashMap(); + + public DummyHolder(PsiManager manager, TreeElement contentElement, PsiElement context) { + this(manager, contentElement, context, SharedImplUtil.findCharTableByTree(contentElement)); + } + + public DummyHolder(PsiManager manager, PsiElement context) { + super((PsiManagerImpl)manager, DUMMY_HOLDER); + myContext = context; + getTreeElement(); + } + + public DummyHolder(PsiManager manager, TreeElement contentElement, PsiElement context, CharTable table) { + super((PsiManagerImpl)manager, DUMMY_HOLDER); + myContext = context; + myTable = table; + TreeUtil.addChildren(getTreeElement(), contentElement); + } + + public DummyHolder(PsiManager manager, PsiElement context, CharTable table) { + this(manager, context); + myTable = table; + } + + + public PsiElement getContext() { + return myContext; + } + + public boolean isValid() { + if (!super.isValid()) return false; + if (myContext != null && !myContext.isValid()) return false; + return true; + } + + public boolean importClass(PsiClass aClass){ + LOG.assertTrue(myContext == null); + String className = aClass.getName(); + if (!myPseudoImports.containsKey(className)){ + myPseudoImports.put(className, aClass); + myManager.nonPhysicalChange(); // to clear resolve caches! + return true; + } + else{ + return false; + } + } + + public boolean hasImports(){ + return !myPseudoImports.isEmpty(); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + if (myContext == null){ // process classes in lang&default package + "pseudo-imports" + ElementClassHint classHint = (ElementClassHint)processor.getHint(ElementClassHint.class); + if (classHint == null || classHint.shouldProcess(PsiClass.class)){ + final NameHint nameHint = (NameHint)processor.getHint(NameHint.class); + final String name = nameHint != null ? nameHint.getName() : null; + if (name != null){ + PsiClass imported = myPseudoImports.get(name); + if (imported != null){ + if (!processor.execute(imported, substitutor)) return false; + } + } + else{ + Iterator iter = myPseudoImports.values().iterator(); + while(iter.hasNext()){ + PsiClass aClass = iter.next(); + if (!processor.execute(aClass, substitutor)) return false; + } + } + + PsiPackage langPackage = getManager().findPackage("java.lang"); + if (langPackage != null){ + if (!langPackage.processDeclarations(processor, substitutor, null, place)) return false; + } + + PsiPackage defaultPackage = getManager().findPackage(""); + if (defaultPackage != null){ + if (!defaultPackage.processDeclarations(processor, substitutor, null, place)) return false; + } + } + } + return true; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitFile(this); + } + + public String toString() { + return "DummyHolder"; + } + + public boolean isSamePackage(PsiElement other) { + if (other instanceof DummyHolder) { + final PsiElement otherContext = ((DummyHolder) other).myContext; + return (myContext == null && otherContext == null) || myContext.getManager().arePackagesTheSame(myContext, otherContext); + } + if (other instanceof PsiJavaFile) { + if (myContext != null) return myContext.getManager().arePackagesTheSame(myContext, other); + final String packageName = ((PsiJavaFile) other).getPackageName(); + return "".equals(packageName); + } + return false; + } + + public FileType getFileType() { + if (myContext!=null) { + PsiFile containingFile = myContext.getContainingFile(); + if (containingFile!=null) return containingFile.getFileType(); + } + return StdFileTypes.JAVA; + } + + public boolean isInPackage(PsiPackage aPackage) { + if (myContext != null) return myContext.getManager().isInPackage(myContext, aPackage); + if (aPackage == null) return true; + return "".equals(aPackage.getQualifiedName()); + } + + public Lexer createLexer() { + return new JavaLexer(myManager.getEffectiveLanguageLevel()); + } + + public FileElement getTreeElement() { + final FileElement holderElement = super.getTreeElement(); + if(myTable != null) holderElement.setCharTable(myTable); + return holderElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolderElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolderElement.java new file mode 100644 index 00000000000..a10908202d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/DummyHolderElement.java @@ -0,0 +1,9 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.impl.source.tree.FileElement; + +public class DummyHolderElement extends FileElement { + public DummyHolderElement() { + super(DUMMY_HOLDER); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/ParsingContext.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/ParsingContext.java new file mode 100644 index 00000000000..7fac1e7c66e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/ParsingContext.java @@ -0,0 +1,90 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.impl.source.parsing.*; +import com.intellij.psi.impl.source.parsing.jsp.JspParsing; +import com.intellij.psi.impl.source.parsing.xml.XmlParsing; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.util.CharTable; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 07.06.2004 + * Time: 18:45:17 + * To change this template use File | Settings | File Templates. + */ +public class ParsingContext { + private final CharTable myTable; + private final DeclarationParsing myDeclarationParsing; + private final ExpressionParsing myExpressionParsing; + private final ClassBodyParsing myClassBodyParsing; + private final StatementParsing myStatementParsing; + private final ImportsTextParsing myImportsParsing; + private final FileTextParsing myFileTextParsing; + private final JspParsing myJspParsing; + private final JavadocParsing myJavadocParsing; + private final XmlParsing myXmlParsing; + private TreeElement myCurrentReparseElement = null; + + public StatementParsing getStatementParsing() { + return myStatementParsing; + } + + public ParsingContext(CharTable table) { + myTable = table; + myStatementParsing = new StatementParsing(this); + myDeclarationParsing = new DeclarationParsing(this); + myExpressionParsing = new ExpressionParsing(this); + myClassBodyParsing = new ClassBodyParsing(this); + myImportsParsing = new ImportsTextParsing(this); + myFileTextParsing = new FileTextParsing(this); + myJspParsing = new JspParsing(this); + myJavadocParsing = new JavadocParsing(this); + myXmlParsing = new XmlParsing(this); + } + + public CharTable getCharTable() { + return myTable; + } + + public DeclarationParsing getDeclarationParsing() { + return myDeclarationParsing; + } + + public ExpressionParsing getExpressionParsing() { + return myExpressionParsing; + } + + public ClassBodyParsing getClassBodyParsing() { + return myClassBodyParsing; + } + + public ImportsTextParsing getImportsTextParsing() { + return myImportsParsing; + } + + public FileTextParsing getFileTextParsing() { + return myFileTextParsing; + } + + public JspParsing getJspParsing() { + return myJspParsing; + } + + public JavadocParsing getJavadocParsing() { + return myJavadocParsing; + } + + public XmlParsing getXmlParsing(){ + return myXmlParsing; + } + + public TreeElement getCurrentReparseElement(){ + return myCurrentReparseElement; + } + + public void setCurrentReparseElement(TreeElement element){ + myCurrentReparseElement = element; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnnotationMethodImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnnotationMethodImpl.java new file mode 100644 index 00000000000..c864c4553ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnnotationMethodImpl.java @@ -0,0 +1,34 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.PsiAnnotationMethod; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiAnnotationMemberValue; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.impl.source.tree.ChildRole; + +/** + * @author ven + */ +public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotationMethod { + public PsiAnnotationMethodImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiAnnotationMethodImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiAnnotationMemberValue getDefaultValue() { + return (PsiAnnotationMemberValue)calcTreeElement().findChildByRole(ChildRole.ANNOTATION_DEFAULT_VALUE); + } + + public String toString() { + return "PsiAnnotationMethod:" + getName(); + } + + public final void accept(PsiElementVisitor visitor) { + visitor.visitAnnotationMethod(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java new file mode 100644 index 00000000000..8724a8b66b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java @@ -0,0 +1,154 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.PsiScopeProcessor; + +public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousClass { + private PsiClassType myCachedBaseType = null; + + public PsiAnonymousClassImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiAnonymousClassImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + protected Object clone() { + PsiAnonymousClassImpl clone = (PsiAnonymousClassImpl)super.clone(); + clone.myCachedBaseType = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedBaseType = null; + } + + public PsiExpressionList getArgumentList() { + return (PsiExpressionList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); + } + + public PsiJavaCodeReferenceElement getBaseClassReference() { + return (PsiJavaCodeReferenceElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.BASE_CLASS_REFERENCE); + } + + public PsiClassType getBaseClassType() { + // Only do caching if no tree element is avaliable. Otherwise we're in danger to leak tree element via cached type. + synchronized (PsiLock.LOCK) { + if (getTreeElement() != null) { + myCachedBaseType = null; + return getTypeByTree(); + } + + if (myCachedBaseType == null) { + final PsiJavaCodeReferenceElement ref; + long repositoryId = getRepositoryId(); + String refText = getRepositoryManager().getClassView().getBaseClassReferenceText(repositoryId); + boolean isInQualifiedNew = getRepositoryManager().getClassView().isInQualifiedNew(repositoryId); + if (!isInQualifiedNew) { + final DummyHolder holder = new DummyHolder(myManager, calcBasesResolveContext(PsiNameHelper.getShortClassName(refText))); + final FileElement holderElement = holder.getTreeElement(); + ref = (PsiJavaCodeReferenceElementImpl)Parsing.parseJavaCodeReferenceText(myManager, refText.toCharArray(), + holderElement.getCharTable()); + TreeUtil.addChildren(holderElement, (TreeElement)ref); + ((PsiJavaCodeReferenceElementImpl)ref).setKindWhenDummy(PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND); + } + else { + return getTypeByTree(); + } + + myCachedBaseType = myManager.getElementFactory().createType(ref); + } + return myCachedBaseType; + } + } + + private PsiClassType getTypeByTree() { + return myManager.getElementFactory().createType(getBaseClassReference()); + } + + public PsiIdentifier getNameIdentifier() { + return null; + } + + public String getQualifiedName() { + return null; + } + + public PsiModifierList getModifierList() { + return null; + } + + public boolean hasModifierProperty(String name) { + return false; + } + + public PsiReferenceList getExtendsList() { + return null; + } + + public PsiReferenceList getImplementsList() { + return null; + } + + public PsiClassType[] getSuperTypes() { + return new PsiClassType[]{getBaseClassType()}; + } + + public PsiClass getContainingClass() { + return null; + } + + public boolean isInterface() { + return false; + } + + public boolean isAnnotationType() { + return false; + } + + public boolean isEnum() { + return false; + } + + public PsiTypeParameterList getTypeParameterList() { + return null; + } + + public PsiElement getOriginalElement() { + return this; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAnonymousClass(this); + } + + public String toString() { + return "PsiAnonymousClass"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + if (lastParent instanceof PsiExpressionList) return true; + if (lastParent != null/* IMPORTANT: do not call getBaseClassReference() for lastParent == null - loads tree!*/ + && lastParent == getBaseClassReference()) { + return true; + } + return super.processDeclarations(processor, substitutor, lastParent, place); + } + + public void treeElementSubTreeChanged() { + myCachedBaseType = null; + super.treeElementSubTreeChanged(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassImpl.java new file mode 100644 index 00000000000..7dbb1c34528 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassImpl.java @@ -0,0 +1,755 @@ +package com.intellij.psi.impl.source; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.psi.*; +import com.intellij.psi.impl.*; +import com.intellij.psi.impl.cache.RepositoryElementType; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.cache.ClassView; +import com.intellij.psi.impl.light.LightMethod; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.java.ClassElement; +import com.intellij.psi.impl.source.tree.java.PsiTypeParameterListImpl; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class PsiClassImpl extends NonSlaveRepositoryPsiElement implements PsiClass { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiClassImpl"); + + private PsiModifierListImpl myRepositoryModifierList = null; + private PsiReferenceListImpl myRepositoryExtendsList = null; + private PsiReferenceListImpl myRepositoryImplementsList = null; + private PsiTypeParameterListImpl myRepositoryParameterList = null; + + private String myCachedName = null; + private String myCachedQName = null; + private Map myCachedFieldsMap = null; + private Map myCachedMethodsMap = null; + private Map myCachedInnersMap = null; + + private PsiField[] myCachedFields = null; + private PsiMethod[] myCachedMethods = null; + private PsiMethod[] myCachedConstructors = null; + private PsiClass[] myCachedInners = null; + private Boolean myCachedIsDeprecated = null; + private Boolean myCachedIsInterface = null; + private Boolean myCachedIsAnnotationType = null; + private Boolean myCachedIsEnum = null; + + private PsiMethod myValuesMethod = null; + private PsiMethod myValueOfMethod = null; + private String myCachedForLongName = null; + + public PsiClassImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiClassImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void subtreeChanged() { + myCachedName = null; + myCachedFields = null; + myCachedMethods = null; + myCachedConstructors = null; + myCachedInners = null; + + myCachedFieldsMap = null; + myCachedMethodsMap = null; + myCachedInnersMap = null; + + myCachedIsDeprecated = null; + myCachedIsInterface = null; + myCachedIsAnnotationType = null; + myCachedIsEnum = null; + super.subtreeChanged(); + } + + protected Object clone() { + PsiClassImpl clone = (PsiClassImpl)super.clone(); + clone.myRepositoryModifierList = null; + clone.myRepositoryExtendsList = null; + clone.myRepositoryImplementsList = null; + clone.myRepositoryParameterList = null; + clone.myCachedFields = null; + clone.myCachedMethods = null; + clone.myCachedConstructors = null; + clone.myCachedInners = null; + + clone.myCachedFieldsMap = null; + clone.myCachedMethodsMap = null; + clone.myCachedInnersMap = null; + + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0){ + if (myRepositoryModifierList != null){ + myRepositoryModifierList.setOwner(this); + myRepositoryModifierList = null; + } + if (myRepositoryExtendsList != null){ + myRepositoryExtendsList.setOwner(this); + myRepositoryExtendsList = null; + } + if (myRepositoryImplementsList != null){ + myRepositoryImplementsList.setOwner(this); + myRepositoryImplementsList = null; + } + if (myRepositoryParameterList != null) { + myRepositoryParameterList.setOwner(this); + myRepositoryParameterList = null; + } + } + else{ + myRepositoryModifierList = (PsiModifierListImpl)bindSlave(ChildRole.MODIFIER_LIST); + myRepositoryExtendsList = (PsiReferenceListImpl)bindSlave(ChildRole.EXTENDS_LIST); + myRepositoryImplementsList = (PsiReferenceListImpl)bindSlave(ChildRole.IMPLEMENTS_LIST); + myRepositoryParameterList = (PsiTypeParameterListImpl)bindSlave(ChildRole.TYPE_PARAMETER_LIST); + } + + myCachedQName = null; + } + + public PsiElement getParent() { + PsiElement parent = getDefaultParentByRepository(); + if (parent instanceof PsiMethod || parent instanceof PsiField || parent instanceof PsiClassInitializer){ + return SourceTreeToPsiMap.treeElementToPsi(calcTreeElement().getTreeParent()); // anonymous or local + } + return parent; + } + + public PsiElement getOriginalElement() { + PsiFile psiFile = getContainingFile(); + VirtualFile vFile = psiFile.getVirtualFile(); + final ProjectFileIndex idx = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex(); + + if (!idx.isInLibrarySource(vFile)) return this; + final Set orderEntries = new HashSet(Arrays.asList(idx.getOrderEntriesForFile(vFile))); + PsiClass original = myManager.findClass(getQualifiedName(), new GlobalSearchScope() { + public int compare(VirtualFile file1, VirtualFile file2) { + return 0; + } + + public boolean contains(VirtualFile file) { + // order for file and vFile has non empty intersection. + Set entries = new HashSet(Arrays.asList(idx.getOrderEntriesForFile(file))); + int size = entries.size(); + entries.addAll(orderEntries); + return size + orderEntries.size() > entries.size(); + } + + public boolean isSearchInModuleContent(Module aModule) { + return false; + } + + public boolean isSearchInLibraries() { + return true; + } + }); + + return original != null ? original : this; + } + + public PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public PsiElement getScope() { + CompositeElement treeElement = getTreeElement(); + if (treeElement != null){ + CompositeElement parent = treeElement.getTreeParent(); + while(true){ + if (parent instanceof RepositoryTreeElement){ + return SourceTreeToPsiMap.treeElementToPsi(parent); + } + parent = parent.getTreeParent(); + } + } + else{ + return getRepositoryElementsManager().findOrCreatePsiElementById(getParentId()); + } + } + + public String getName() { + if (myCachedName == null){ + if (getTreeElement() != null){ + PsiIdentifier identifier = getNameIdentifier(); + myCachedName = identifier != null ? identifier.getText() : null; + } + else{ + myCachedName = getRepositoryManager().getClassView().getName(getRepositoryId()); + } + } + return myCachedName; + } + + public String getQualifiedName() { + if (myCachedQName != null) return myCachedQName; + + String qName = null; + if (getTreeElement() != null){ + PsiElement parent = getParent(); + if (parent instanceof PsiJavaFile){ + String packageName = ((PsiJavaFile)parent).getPackageName(); + if (packageName.length() > 0){ + qName = packageName + "." + getName(); + } + else{ + qName = getName(); + } + } + else if (parent instanceof PsiClass) { + String parentQName = ((PsiClass)parent).getQualifiedName(); + if (parentQName == null) return null; + qName = parentQName + "." + getName(); + } + } + else{ + qName = getRepositoryManager().getClassView().getQualifiedName(getRepositoryId()); + } + + if (getRepositoryId() >= 0){ + myCachedQName = qName; + } + + return qName; + } + + public PsiModifierList getModifierList(){ + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryModifierList == null){ + myRepositoryModifierList = new PsiModifierListImpl(myManager, this); + } + return myRepositoryModifierList; + } + else{ + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiReferenceList getExtendsList() { + if (isEnum() || isAnnotationType()) return null; + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryExtendsList == null){ + myRepositoryExtendsList = new PsiReferenceListImpl(myManager, this, ElementType.EXTENDS_LIST); + } + return myRepositoryExtendsList; + } + else{ + return (PsiReferenceList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.EXTENDS_LIST); + } + } + + public PsiReferenceList getImplementsList() { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryImplementsList == null){ + myRepositoryImplementsList = new PsiReferenceListImpl(myManager, this, ElementType.IMPLEMENTS_LIST); + } + return myRepositoryImplementsList; + } + else{ + return (PsiReferenceList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPLEMENTS_LIST); + } + } + + public PsiClassType[] getExtendsListTypes() { + return PsiClassImplUtil.getExtendsListTypes(this); + } + + public PsiClassType[] getImplementsListTypes() { + return PsiClassImplUtil.getImplementsListTypes(this); + } + + public PsiClass getSuperClass() { + return PsiClassImplUtil.getSuperClass(this); + } + + public PsiClass[] getInterfaces() { + return PsiClassImplUtil.getInterfaces(this); + } + + public PsiClass[] getSupers() { + return PsiClassImplUtil.getSupers(this); + } + + public PsiClassType[] getSuperTypes() { + return PsiClassImplUtil.getSuperTypes(this); + } + + public PsiClass getContainingClass() { + PsiElement parent = getDefaultParentByRepository(); + return parent instanceof PsiClass ? ((PsiClass)parent) : null; + } + + public PsiField[] getFields() { + if (myCachedFields == null){ + if (getTreeElement() != null){ + myCachedFields = (PsiField[])calcTreeElement().getChildrenAsPsiElements(FIELD_BIT_SET, PSI_FIELD_ARRAY_CONSTRUCTOR); + } + else{ + long[] fieldIds = getRepositoryManager().getClassView().getFields(getRepositoryId()); + PsiField[] fields = fieldIds.length > 0 ? new PsiField[fieldIds.length] : PsiField.EMPTY_ARRAY; + for(int i = 0; i < fieldIds.length; i++){ + long id = fieldIds[i]; + fields[i] = (PsiField)getRepositoryElementsManager().findOrCreatePsiElementById(id); + } + myCachedFields = fields; + } + } + return myCachedFields; + } + + public PsiMethod[] getMethods() { + if (myCachedMethods == null){ + if (getTreeElement() != null){ + myCachedMethods = (PsiMethod[])calcTreeElement().getChildrenAsPsiElements(METHOD_BIT_SET, PSI_METHOD_ARRAY_CONSTRUCTOR); + } + else{ + long[] methodIds = getRepositoryManager().getClassView().getMethods(getRepositoryId()); + PsiMethod[] methods = methodIds.length > 0 ? new PsiMethod[methodIds.length] : PsiMethod.EMPTY_ARRAY; + for(int i = 0; i < methodIds.length; i++){ + long id = methodIds[i]; + methods[i] = (PsiMethod)getRepositoryElementsManager().findOrCreatePsiElementById(id); + } + myCachedMethods = methods; + } + } + return myCachedMethods; + } + + public PsiMethod[] getConstructors() { + if (myCachedConstructors == null){ + myCachedConstructors = PsiImplUtil.getConstructors(this); + } + return myCachedConstructors; + } + + public PsiClass[] getInnerClasses() { + if (myCachedInners == null){ + if (getTreeElement() != null){ + myCachedInners = (PsiClass[])calcTreeElement().getChildrenAsPsiElements(CLASS_BIT_SET, PSI_CLASS_ARRAY_CONSTRUCTOR); + } + else{ + long[] classIds = getRepositoryManager().getClassView().getInnerClasses(getRepositoryId()); + PsiClass[] classes = classIds.length > 0 ? new PsiClass[classIds.length] : PsiClass.EMPTY_ARRAY; + for(int i = 0; i < classIds.length; i++){ + long id = classIds[i]; + classes[i] = (PsiClass)getRepositoryElementsManager().findOrCreatePsiElementById(id); + } + myCachedInners = classes; + } + } + return myCachedInners; + } + + public PsiClassInitializer[] getInitializers(){ + if (getTreeElement() != null){ + return (PsiClassInitializer[])calcTreeElement().getChildrenAsPsiElements(CLASS_INITIALIZER_BIT_SET, PSI_CLASS_INITIALIZER_ARRAY_CONSTRUCTOR); + } + else{ + long[] initializerIds = getRepositoryManager().getClassView().getInitializers(getRepositoryId()); + PsiClassInitializer[] initializers = initializerIds.length > 0 ? new PsiClassInitializer[initializerIds.length] : PsiClassInitializer.EMPTY_ARRAY; + for(int i = 0; i < initializerIds.length; i++){ + long id = initializerIds[i]; + initializers[i] = (PsiClassInitializer)getRepositoryElementsManager().findOrCreatePsiElementById(id); + } + return initializers; + } + } + + public PsiTypeParameter[] getTypeParameters() { + return PsiClassImplUtil.getTypeParameters(this); + } + + public PsiField[] getAllFields() { + return PsiClassImplUtil.getAllFields(this); + } + + public PsiMethod[] getAllMethods() { + return PsiClassImplUtil.getAllMethods(this); + } + + public PsiClass[] getAllInnerClasses() { + return PsiClassImplUtil.getAllInnerClasses(this); + } + + public PsiField findFieldByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedFieldsMap == null){ + final PsiField[] fields = getFields(); + myCachedFieldsMap = new HashMap(); + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + myCachedFieldsMap.put(field.getName(), field); + } + } + return myCachedFieldsMap.get(name); + } + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedMethodsMap == null){ + final HashMap map = new HashMap(); + + Map> cachedMethodsMap = new HashMap>(); + final PsiMethod[] methods = getMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + List list = cachedMethodsMap.get(method.getName()); + if(list == null){ + list = new ArrayList(1); + cachedMethodsMap.put(method.getName(), list); + } + list.add(method); + } + final Iterator iterator = cachedMethodsMap.keySet().iterator(); + while (iterator.hasNext()) { + final String methodName = iterator.next(); + map.put(methodName, cachedMethodsMap.get(methodName).toArray(PsiMethod.EMPTY_ARRAY)); + } + myCachedMethodsMap = map; + } + + final PsiMethod[] psiMethods = myCachedMethodsMap.get(name); + return psiMethods != null ? psiMethods : PsiMethod.EMPTY_ARRAY; + } + + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + public List> findMethodsAndTheirSubstitutorsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + public PsiClass findInnerClassByName(String name, boolean checkBases) { + if(!checkBases){ + if(myCachedInnersMap == null){ + final PsiClass[] classes = getInnerClasses(); + myCachedInnersMap = new HashMap(); + for (int i = 0; i < classes.length; i++) { + final PsiClass psiClass = classes[i]; + myCachedInnersMap.put(psiClass.getName(), psiClass); + } + } + return myCachedInnersMap.get(name); + } + return PsiClassImplUtil.findInnerByName(this, name, checkBases); + } + + public PsiTypeParameterList getTypeParameterList() { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryParameterList == null){ + myRepositoryParameterList = new PsiTypeParameterListImpl(myManager, this); + } + return myRepositoryParameterList; + } + + return (PsiTypeParameterList) calcTreeElement().findChildByRoleAsPsiElement(ChildRole.TYPE_PARAMETER_LIST); + } + + public boolean hasTypeParameters() { + final PsiTypeParameterList typeParameterList = getTypeParameterList(); + return typeParameterList != null && typeParameterList.getTypeParameters().length != 0; + } + + public boolean isDeprecated() { + if (myCachedIsDeprecated == null){ + boolean deprecated; + if (getTreeElement() != null){ + PsiDocComment docComment = getDocComment(); + deprecated = docComment != null && getDocComment().findTagByName("deprecated") != null; + if (!deprecated) { + PsiModifierList modifierList = getModifierList(); + if (modifierList != null) { + deprecated = modifierList.findAnnotation("java.lang.Deprecated") != null; + } + } + } + else{ + ClassView classView = getRepositoryManager().getClassView(); + deprecated = classView.isDeprecated(getRepositoryId()); + if (!deprecated && classView.mayBeDeprecatedByAnnotation(getRepositoryId())) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + myCachedIsDeprecated = deprecated ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsDeprecated.booleanValue(); + } + + public PsiDocComment getDocComment(){ + return (PsiDocComment)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); + } + + public PsiJavaToken getLBrace() { + return (PsiJavaToken)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.LBRACE); + } + + public PsiJavaToken getRBrace() { + return (PsiJavaToken)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.RBRACE); + } + + public boolean isInterface(){ + if (myCachedIsInterface == null){ + boolean isInterface; + if (getTreeElement() != null){ + TreeElement keyword = calcTreeElement().findChildByRole(ChildRole.CLASS_OR_INTERFACE_KEYWORD); + if (keyword.getElementType() == CLASS_KEYWORD) { + isInterface = false; + } + else if (keyword.getElementType() == INTERFACE_KEYWORD) { + isInterface = true; + } + else if (keyword.getElementType() == ENUM_KEYWORD) { + isInterface = false; + } + else{ + LOG.assertTrue(false); + isInterface = false; + } + } + else{ + isInterface = getRepositoryManager().getClassView().isInterface(getRepositoryId()); + } + myCachedIsInterface = isInterface ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsInterface.booleanValue(); + } + + public boolean isAnnotationType() { + if (myCachedIsAnnotationType == null){ + boolean isAnnotationType = false; + if (isInterface()) { + if (getTreeElement() != null){ + isAnnotationType = calcTreeElement().findChildByRole(ChildRole.AT) != null; + } + else{ + isAnnotationType = getRepositoryManager().getClassView().isAnnotationType(getRepositoryId()); + } + } + myCachedIsAnnotationType = isAnnotationType ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsAnnotationType.booleanValue(); + } + + public boolean isEnum() { + if (myCachedIsEnum == null) { + final boolean isEnum; + if (getTreeElement() != null) { + isEnum = ((ClassElement)getTreeElement()).isEnum(); + } + else { + isEnum = getRepositoryManager().getClassView().isEnum(getRepositoryId()); + } + myCachedIsEnum = Boolean.valueOf(isEnum); + } + return myCachedIsEnum.booleanValue(); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitClass(this); + } + + public String toString(){ + return "PsiClass:" + getName(); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + if (isEnum()) { + if (getName() != null) { + try { + if (myValuesMethod == null || myValueOfMethod == null || !getName().equals(myCachedForLongName)) { + myCachedForLongName = getName(); + final PsiMethod valuesMethod = getManager().getElementFactory().createMethodFromText("public static " + getName() + "[] values() {}", this); + myValuesMethod = new LightMethod(getManager(), valuesMethod, this); + final PsiMethod valueOfMethod = getManager().getElementFactory().createMethodFromText("public static " + getName() + " valueOf(String name) {}", this); + myValueOfMethod = new LightMethod(getManager(), valueOfMethod, this); + } + final NameHint hint = processor.getHint(NameHint.class); + if (hint == null || "values".equals(hint.getName())) { + if (!processor.execute(myValuesMethod, PsiSubstitutor.EMPTY)) return false; + } + if (hint == null || "valueOf".equals(hint.getName())) { + if (!processor.execute(myValueOfMethod, PsiSubstitutor.EMPTY)) return false; + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + return PsiClassImplUtil.processDeclarationsInClass(this, processor, substitutor, new HashSet(), lastParent, place); + } + + public PsiElement setName(String newName) throws IncorrectOperationException{ + String oldName = getName(); + boolean isRenameFile = isRenameFileOnRenaming(); + + SharedPsiElementImplUtil.setName(getNameIdentifier(), newName); + + if (isRenameFile) { + PsiFile file = (PsiFile)getParent(); + String fileName = file.getName(); + int dotIndex = fileName.lastIndexOf('.'); + file.setName(dotIndex >= 0 ? newName + "." + fileName.substring(dotIndex + 1) : newName); + } + + // rename constructors + PsiMethod[] methods = getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method.isConstructor() && method.getName().equals(oldName)) { + method.setName(newName); + } + } + + return this; + } + + private boolean isRenameFileOnRenaming() { + if (getParent() instanceof PsiFile) { + PsiFile file = (PsiFile)getParent(); + String fileName = file.getName(); + int dotIndex = fileName.lastIndexOf('.'); + String name = dotIndex >= 0 ? fileName.substring(0, dotIndex) : fileName; + String oldName = getName(); + return oldName.equals(name); + } + else { + return false; + } + } + + public PsiMetaData getMetaData(){ + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough(){ + return false; + } + + // optimization to not load tree when resolving bases of anonymous and locals + // if there is no local classes with such name in scope it's possible to use outer scope as context + protected PsiElement calcBasesResolveContext(String baseClassName) { + return calcBasesResolveContext(this, baseClassName, true); + } + + private PsiElement calcBasesResolveContext(PsiClass aClass, String className, boolean isInitialClass) { + boolean isAnonOrLocal = false; + if (aClass instanceof PsiAnonymousClass){ + isAnonOrLocal = true; + } + else { + long scopeId = ((PsiClassImpl)aClass).getParentId(); + RepositoryElementType scopeType = myManager.getRepositoryManager().getElementType(scopeId); + boolean isLocalClass = scopeType == RepositoryElementType.METHOD || scopeType == RepositoryElementType.FIELD || scopeType == RepositoryElementType.CLASS_INITIALIZER; + if (isLocalClass){ + isAnonOrLocal = true; + } + } + + if (!isAnonOrLocal) { + return isInitialClass ? (PsiElement)aClass.getExtendsList() : aClass; //?!!! + } + + if (!isInitialClass){ + if (aClass.findInnerClassByName(className, true) != null) return aClass; + } + + long classId = ((RepositoryPsiElement)aClass).getRepositoryId(); + RepositoryManager repositoryManager = myManager.getRepositoryManager(); + long scopeId = repositoryManager.getClassView().getParent(classId); + long[] classesInScope = repositoryManager.getItemView(scopeId).getChildren(scopeId, RepositoryElementType.CLASS); + + boolean needPreciseContext = false; + if (classesInScope.length > 1){ + for(int i = 0; i < classesInScope.length; i++){ + long id = classesInScope[i]; + if (id == classId) continue; + String className1 = repositoryManager.getClassView().getName(id); + if (className.equals(className1)){ + needPreciseContext = true; + break; + } + } + } + else{ + LOG.assertTrue(classesInScope.length == 1); + LOG.assertTrue(classesInScope[0] == classId); + } + + if (needPreciseContext){ + return aClass.getParent(); + } + else{ + PsiElement context = myManager.getRepositoryElementsManager().findOrCreatePsiElementById(scopeId); + if (context instanceof PsiClass){ + return calcBasesResolveContext((PsiClass)context, className, false); + } + else if (context instanceof PsiMember){ + return calcBasesResolveContext(((PsiMember)context).getContainingClass(), className, false); + } + else{ + LOG.assertTrue(false); + return context; + } + } + } + + public boolean isInheritor(PsiClass baseClass, boolean checkDeep) { + return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep); + } + + public PomMemberOwner getPom() { + //TODO: + return null; + } + + public ItemPresentation getPresentation() { + return ClassPresentationUtil.getPresentation(this); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassInitializerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassInitializerImpl.java new file mode 100644 index 00000000000..3cdfd84489f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassInitializerImpl.java @@ -0,0 +1,81 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; + +public class PsiClassInitializerImpl extends NonSlaveRepositoryPsiElement implements PsiClassInitializer { + private PsiModifierListImpl myRepositoryModifierList = null; + + public PsiClassInitializerImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiClassInitializerImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + protected Object clone() { + PsiClassInitializerImpl clone = (PsiClassInitializerImpl)super.clone(); + clone.myRepositoryModifierList = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0){ + if (myRepositoryModifierList != null){ + myRepositoryModifierList.setOwner(this); + myRepositoryModifierList = null; + } + } + else{ + myRepositoryModifierList = (PsiModifierListImpl)bindSlave(ChildRole.MODIFIER_LIST); + } + } + + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? (PsiClass)parent : null; + } + + public PsiModifierList getModifierList(){ + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryModifierList == null){ + myRepositoryModifierList = new PsiModifierListImpl(myManager, this); + } + return myRepositoryModifierList; + } + else{ + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiCodeBlock getBody(){ + return (PsiCodeBlock)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.METHOD_BODY); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitClassInitializer(this); + } + + public String toString(){ + return "PsiClassInitializer"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if(lastParent == null) return true; + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassReferenceType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassReferenceType.java new file mode 100644 index 00000000000..80645cc39c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiClassReferenceType.java @@ -0,0 +1,162 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightClassReference; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +/** + * @author max + */ +public class PsiClassReferenceType extends PsiClassType { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiClassReferenceType"); + private final PsiJavaCodeReferenceElement myReference; + + public PsiClassReferenceType(PsiJavaCodeReferenceElement reference) { + LOG.assertTrue(reference != null); + myReference = reference; + } + + public boolean isValid() { + return myReference.isValid(); + } + + public boolean equalsToText(String text) { + PsiElementFactory factory = myReference.getManager().getElementFactory(); + PsiType patternType; + try { + patternType = factory.createTypeFromText(text, null); + } + catch (IncorrectOperationException e) { + return false; + } + return equals(patternType); + } + + public GlobalSearchScope getResolveScope() { + return myReference.getResolveScope(); + } + + public PsiClass resolve() { + ClassResolveResult result = resolveGenerics(); + if (result != null) { + return result.getElement(); + } + else { + return null; + } + } + + private static class DelegatingClassResolveResult implements ClassResolveResult { + private final ResolveResult myDelegate; + + private DelegatingClassResolveResult(ResolveResult delegate) { + myDelegate = delegate; + } + + public boolean hasCandidates() { + return myDelegate.getElement() != null; + } + + public PsiSubstitutor getSubstitutor() { + return myDelegate.getSubstitutor(); + } + + public boolean isValidResult() { + return myDelegate.isValidResult(); + } + + public boolean isAccessible() { + return myDelegate.isAccessible(); + } + + public boolean isStaticsScopeCorrect() { + return myDelegate.isStaticsScopeCorrect(); + } + + public PsiElement getCurrentFileResolveScope() { + return myDelegate.getCurrentFileResolveScope(); + } + + public boolean isPackagePrefixPackageReference() { + return myDelegate.isPackagePrefixPackageReference(); + } + + public PsiClass getElement() { + final PsiElement element = myDelegate.getElement(); + return element instanceof PsiClass ? (PsiClass)element : null; + } + } + + private static ClassResolveResult createClassResolveResult(ResolveResult result) { + return new DelegatingClassResolveResult(result); + } + + public ClassResolveResult resolveGenerics() { + final ResolveResult result = myReference.advancedResolve(false); + return createClassResolveResult(result); + } + + public PsiClassType rawType() { + PsiElement resolved = myReference.resolve(); + PsiManager manager = myReference.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + if (resolved instanceof PsiClass) { + final PsiSubstitutor rawSubstitutor = factory.createRawSubstitutor((PsiClass) resolved); + return factory.createType((PsiClass) resolved, rawSubstitutor); + } + String qualifiedName = myReference.getQualifiedName(); + return new PsiClassReferenceType(new LightClassReference(manager, myReference.getReferenceName(), qualifiedName, myReference.getResolveScope())); + } + + public String getClassName() { + return myReference.getReferenceName(); + } + + public PsiClassType getQualiferType() { + if (!(myReference instanceof SourceJavaCodeReference)) { + // todo[dsl] fix this for compiled code + return null; + } + final PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(((SourceJavaCodeReference) myReference).getTreeQualifier()); + if (psiElement instanceof PsiJavaCodeReferenceElement) { + final PsiJavaCodeReferenceElement qualifierReference = ((PsiJavaCodeReferenceElement)psiElement); + if (qualifierReference.getTypeParameters().length > 0) { + return new PsiClassReferenceType(qualifierReference); + } + else { + return null; + } + } + else { + return null; + } + } + + public PsiType[] getParameters() { + return myReference.getTypeParameters(); + } + + public PsiClassType createImmediateCopy() { + final PsiClassType.ClassResolveResult resolveResult = resolveGenerics(); + if (resolveResult.getElement() == null) return this; + return new PsiImmediateClassType(resolveResult.getElement(), resolveResult.getSubstitutor()); + } + + public String getPresentableText() { + return PsiNameHelper.getPresentableText(myReference); + } + + public String getCanonicalText() { + return myReference.getCanonicalText(); + } + + public String getInternalCanonicalText() { + return getCanonicalText(); + } + + public PsiJavaCodeReferenceElement getReference() { + return myReference; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiCodeFragmentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiCodeFragmentImpl.java new file mode 100644 index 00000000000..4c50f493568 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiCodeFragmentImpl.java @@ -0,0 +1,241 @@ +package com.intellij.psi.impl.source; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.command.impl.DocumentReferenceByDocument; +import com.intellij.openapi.command.undo.DocumentReference; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.tree.IElementType; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.StringTokenizer; + +public class PsiCodeFragmentImpl extends PsiFileImpl implements PsiCodeFragment, PsiImportHolder { + private PsiElement myContext; + private boolean myPhysical; + private PsiType myThisType; + private LinkedHashMap myPseudoImports = new LinkedHashMap(); + private VisibilityChecker myVisibilityChecker; + + public PsiCodeFragmentImpl(PsiManagerImpl manager, + IElementType contentElementType, + boolean isPhysical, + String name, + char[] text, + int startOffset, + int endOffset) { + super(manager, CODE_FRAGMENT, contentElementType, name, text, startOffset, endOffset); + myPhysical = isPhysical; + } + + protected PsiCodeFragmentImpl clone() { + PsiCodeFragmentImpl clone = (PsiCodeFragmentImpl)super.clone(); + clone.myPhysical = false; + clone.myOriginalFile = this; + clone.myPseudoImports = new LinkedHashMap(myPseudoImports); + return clone; + } + + public boolean isValid() { + if (!super.isValid()) return false; + if (myContext != null && !myContext.isValid()) return false; + return true; + } + + public boolean canContainJavaCode() { + return true; + } + + public FileType getFileType() { + return StdFileTypes.JAVA; + } + + + public PsiElement getContext() { + return myContext; + } + + public void setContext(PsiElement context) { + this.myContext = context; + } + + public void setEverythingAcessible(boolean value) { + myVisibilityChecker = new VisibilityChecker() { + public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) { + return Visibility.VISIBLE; + } + }; + } + + public PsiType getThisType() { + return myThisType; + } + + public void setThisType(PsiType psiType) { + myThisType = psiType; + } + + public String importsToString() { + StringBuffer buffer = new StringBuffer(); + for (Iterator iterator = myPseudoImports.values().iterator(); iterator.hasNext();) { + if (buffer.length() > 0) { + buffer.append(","); + } + String importedQName = iterator.next(); + buffer.append(importedQName); + } + return buffer.toString(); + } + + public void addImportsFromString(String imports) { + StringTokenizer tokenizer = new StringTokenizer(imports, ","); + while(tokenizer.hasMoreTokens()){ + String qName = tokenizer.nextToken(); + String name = PsiNameHelper.getShortClassName(qName); + myPseudoImports.put(name, qName); + } + } + + public void setVisibilityChecker(VisibilityChecker checker) { + myVisibilityChecker = checker; + } + + public VisibilityChecker getVisibilityChecker() { + return myVisibilityChecker; + } + + public boolean isPhysical() { + return myPhysical; + } + + /** + * @fabrique + */ + public void setPhysical(boolean physical) { + myPhysical = physical; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitCodeFragment(this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + final ElementClassHint classHint = processor.getHint(ElementClassHint.class); + + if (classHint == null || classHint.shouldProcess(PsiClass.class)) { + final NameHint nameHint = processor.getHint(NameHint.class); + final String name = nameHint != null ? nameHint.getName() : null; + if (name != null) { + String qNameImported = myPseudoImports.get(name); + if (qNameImported != null) { + PsiClass imported = myManager.findClass(qNameImported, getResolveScope()); + if (imported != null) { + if (!processor.execute(imported, substitutor)) return false; + } + } + } + else { + Iterator iter = myPseudoImports.values().iterator(); + while (iter.hasNext()) { + String qNameImported = iter.next(); + PsiClass aClass = myManager.findClass(qNameImported, getResolveScope()); + if (aClass != null) { + if (!processor.execute(aClass, substitutor)) return false; + } + } + } + + PsiPackage langPackage = getManager().findPackage("java.lang"); + if (langPackage != null) { + if (!langPackage.processDeclarations(processor, substitutor, null, place)) return false; + } + + PsiPackage defaultPackage = getManager().findPackage(""); + if (defaultPackage != null) { + if (!defaultPackage.processDeclarations(processor, substitutor, null, place)) return false; + } + } + + + IElementType i = getContentElementType(); + if (i == ElementType.TYPE_TEXT) { + return true; + } + else if (i == ElementType.EXPRESSION_TEXT) { + return true; + } + else { + { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null) + // Parent element should not see our vars + { + return true; + } + + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } + } + } + + public String toString() { + return "PsiCodeFragment:" + getName(); + } + + public Lexer createLexer() { + final PsiManager manager = getManager(); + return new JavaLexer(manager.getEffectiveLanguageLevel()); + } + + public boolean importClass(PsiClass aClass) { + final String className = aClass.getName(); + final String qName = aClass.getQualifiedName(); + if (qName == null) return false; + //if (!myPseudoImports.containsKey(className)){ + myPseudoImports.put(className, qName); + myManager.nonPhysicalChange(); // to clear resolve caches! + if (isPhysical()) { + final Project project = myManager.getProject(); + UndoManager.getInstance(project).undoableActionPerformed(new UndoableAction() { + public boolean isComplex() { + return false; + } + + public void undo() { + myPseudoImports.remove(className); + } + + public void redo() { + myPseudoImports.put(className, qName); + } + + public DocumentReference[] getAffectedDocuments() { + PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + Document document = psiDocumentManager.getDocument(PsiCodeFragmentImpl.this); + return new DocumentReference[]{DocumentReferenceByDocument.createDocumentReference(document)}; + } + }); + } + return true; + //} + //else{ + // return false; + //} + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantImpl.java new file mode 100644 index 00000000000..9d5e7284812 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantImpl.java @@ -0,0 +1,274 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.TextRange; +import com.intellij.pom.java.PomField; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.cache.FieldView; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class PsiEnumConstantImpl extends NonSlaveRepositoryPsiElement implements PsiEnumConstant { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiEnumConstantImpl"); + private String myCachedName = null; + private Boolean myCachedIsDeprecated; + private MyReference myReference = new MyReference(); + private Ref myCachedInitializingClass = null; + private PsiModifierListImpl myRepositoryModifierList = null; + + public PsiEnumConstantImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public String toString() { + return "PsiEnumConstant:" + getName(); + } + + public PsiEnumConstantImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitEnumConstant(this); + } + + public PsiExpressionList getArgumentList() { + return (PsiExpressionList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); + } + + public PsiEnumConstantInitializer getInitializingClass() { + if (myCachedInitializingClass == null) { + if (getTreeElement() != null) { + myCachedInitializingClass = Ref.create((PsiEnumConstantInitializer)getTreeElement().findChildByRoleAsPsiElement(ChildRole.ANONYMOUS_CLASS)); + } + else { + long initializingClass = getRepositoryManager().getFieldView().getEnumConstantInitializer(getRepositoryId()); + if (initializingClass < 0) { + myCachedInitializingClass = Ref.create((PsiEnumConstantInitializer)null); + } + else { + PsiEnumConstantInitializer repoElement = (PsiEnumConstantInitializer)getRepositoryElementsManager().findOrCreatePsiElementById(initializingClass); + myCachedInitializingClass = Ref.create(repoElement); + } + } + } + + return myCachedInitializingClass.get(); + } + + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? (PsiClass)parent : null; + } + + public PsiModifierList getModifierList() { + if (getRepositoryId() >= 0) { + if (myRepositoryModifierList == null) { + myRepositoryModifierList = new PsiModifierListImpl(myManager, this); + } + return myRepositoryModifierList; + } + else { + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + } + + public boolean hasModifierProperty(String name) { + return (PsiModifier.PUBLIC.equals(name) || PsiModifier.STATIC.equals(name) || PsiModifier.FINAL.equals(name)); + } + + + protected Object clone() { + PsiEnumConstantImpl clone = (PsiEnumConstantImpl)super.clone(); + clone.myRepositoryModifierList = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0) { + if (myRepositoryModifierList != null) { + myRepositoryModifierList.setOwner(this); + myRepositoryModifierList = null; + } + } + else { + myRepositoryModifierList = (PsiModifierListImpl)bindSlave(ChildRole.MODIFIER_LIST); + } + } + + public PsiType getType() { + return getManager().getElementFactory().createType(getContainingClass()); + } + + public PsiTypeElement getTypeElement() { + return null; + } + + public PsiExpression getInitializer() { + return null; + } + + public boolean hasInitializer() { + return true; + } + + public void normalizeDeclaration() throws IncorrectOperationException {} + + public Object computeConstantValue() { + return null; + } + + public PsiMethod resolveMethod() { + PsiClass containingClass = getContainingClass(); + LOG.assertTrue(containingClass != null); + ResolveResult resolveResult = getManager().getResolveHelper().resolveConstructor(getManager().getElementFactory().createType(containingClass), getArgumentList(), this); + return (PsiMethod)resolveResult.getElement(); + } + + public ResolveResult resolveMethodGenerics() { + PsiClass containingClass = getContainingClass(); + LOG.assertTrue(containingClass != null); + return getManager().getResolveHelper().resolveConstructor(getManager().getElementFactory().createType(containingClass), getArgumentList(), this); + } + + public PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public String getName() { + if (myCachedName == null) { + if (getTreeElement() != null) { + myCachedName = getNameIdentifier().getText(); + } + else { + myCachedName = getRepositoryManager().getFieldView().getName(getRepositoryId()); + } + } + return myCachedName; + } + + public void subtreeChanged() { + myCachedName = null; + myCachedIsDeprecated = null; + myCachedInitializingClass = null; + super.subtreeChanged(); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiDocComment getDocComment() { + return (PsiDocComment)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); + } + + public boolean isDeprecated() { + if (myCachedIsDeprecated == null) { + boolean deprecated; + if (getTreeElement() != null) { + PsiDocComment docComment = getDocComment(); + deprecated = docComment != null && getDocComment().findTagByName("deprecated") != null; + if (!deprecated) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + else { + FieldView fieldView = getRepositoryManager().getFieldView(); + deprecated = fieldView.isDeprecated(getRepositoryId()); + if (!deprecated && fieldView.mayBeDeprecatedByAnnotation(getRepositoryId())) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + myCachedIsDeprecated = deprecated ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsDeprecated.booleanValue(); + } + + public PsiReference getReference() { + return myReference; + } + + public PsiMethod resolveConstructor() { + return resolveMethod(); + } + + public PomField getPom() { + //TODO: + return null; + } + + private class MyReference implements PsiJavaReference { + public PsiElement getElement() { + return PsiEnumConstantImpl.this; + } + + public TextRange getRangeInElement() { + PsiIdentifier nameIdentifier = getNameIdentifier(); + LOG.assertTrue(nameIdentifier != null, getText()); + int startOffsetInParent = nameIdentifier.getStartOffsetInParent(); + return new TextRange(startOffsetInParent, startOffsetInParent + nameIdentifier.getTextLength()); + } + + public boolean isSoft() { + return false; + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return getElement(); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException("Invalid operation"); + } + + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public void processVariants(PsiScopeProcessor processor) { + } + + public ResolveResult[] multiResolve(boolean incompleteCode) { + PsiManager manager = getManager(); + PsiClassType type = manager.getElementFactory().createType(getContainingClass()); + return manager.getResolveHelper().multiResolveConstructor(type, getArgumentList(), getElement()); + } + + public ResolveResult advancedResolve(boolean incompleteCode) { + final ResolveResult[] results = multiResolve(incompleteCode); + if (results.length == 1) return results[0]; + return ResolveResult.EMPTY; + } + + public PsiElement resolve() { + return advancedResolve(false).getElement(); + } + + public String getCanonicalText() { + String name = getContainingClass().getName(); + return name; + } + + public boolean isReferenceTo(PsiElement element) { + return element instanceof PsiMethod + && ((PsiMethod)element).isConstructor() + && ((PsiMethod)element).getContainingClass() == getContainingClass() + && getManager().areElementsEquivalent(resolve(), element); + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantInitializerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantInitializerImpl.java new file mode 100644 index 00000000000..9babbf2bdf7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiEnumConstantInitializerImpl.java @@ -0,0 +1,134 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.light.LightClassReference; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.openapi.diagnostic.Logger; + +public class PsiEnumConstantInitializerImpl extends PsiClassImpl implements PsiEnumConstantInitializer { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiEnumConstantInitializerImpl"); + private PsiClassType myCachedBaseType = null; + + public PsiEnumConstantInitializerImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiEnumConstantInitializerImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + protected Object clone() { + PsiEnumConstantInitializerImpl clone = (PsiEnumConstantInitializerImpl)super.clone(); + clone.myCachedBaseType = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedBaseType = null; + } + + public PsiExpressionList getArgumentList() { + PsiElement parent = getParent(); + LOG.assertTrue(parent instanceof PsiEnumConstant); + return ((PsiEnumConstant)parent).getArgumentList(); + } + + public PsiJavaCodeReferenceElement getBaseClassReference() { + PsiClass containingClass = getBaseClass(); + return new LightClassReference(getManager(), containingClass.getName(), containingClass); + } + + private PsiClass getBaseClass() { + PsiElement parent = getParent(); + LOG.assertTrue(parent instanceof PsiEnumConstant); + PsiClass containingClass = ((PsiEnumConstant)parent).getContainingClass(); + LOG.assertTrue(containingClass != null); + return containingClass; + } + + public PsiElement getParent() { + return getDefaultParentByRepository(); + } + + public PsiEnumConstant getEnumConstant() { + return (PsiEnumConstant) getParent(); + } + + public PsiClassType getBaseClassType() { + if (myCachedBaseType == null) { + myCachedBaseType = myManager.getElementFactory().createType(getBaseClass()); + } + return myCachedBaseType; + } + + public PsiIdentifier getNameIdentifier() { + return null; + } + + public String getQualifiedName() { + return null; + } + + public PsiModifierList getModifierList() { + return null; + } + + public boolean hasModifierProperty(String name) { + return false; + } + + public PsiReferenceList getExtendsList() { + return null; + } + + public PsiReferenceList getImplementsList() { + return null; + } + + public PsiClassType[] getSuperTypes() { + return new PsiClassType[]{getBaseClassType()}; + } + + public boolean isInterface() { + return false; + } + + public boolean isAnnotationType() { + return false; + } + + public boolean isEnum() { + return false; + } + + public PsiTypeParameterList getTypeParameterList() { + return null; + } + + public PsiElement getOriginalElement() { + return this; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitEnumConstantInitializer(this); + } + + public String toString() { + return "PsiAnonymousClass (PsiEnumConstantInitializerImpl)):"; + } + + public void treeElementSubTreeChanged() { + myCachedBaseType = null; + super.treeElementSubTreeChanged(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiExpressionCodeFragmentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiExpressionCodeFragmentImpl.java new file mode 100644 index 00000000000..378842d22a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiExpressionCodeFragmentImpl.java @@ -0,0 +1,25 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionCodeFragment; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; + +public class PsiExpressionCodeFragmentImpl extends PsiCodeFragmentImpl implements PsiExpressionCodeFragment { + public PsiExpressionCodeFragmentImpl(PsiManagerImpl manager, + boolean isPhysical, + String name, + char[] text, + int startOffset, + int endOffset) { + super(manager, ElementType.EXPRESSION_TEXT, isPhysical, name, text, startOffset, endOffset); + } + + public PsiExpression getExpression() { + ChameleonTransforming.transformChildren(calcTreeElement()); + TreeElement exprChild = TreeUtil.findChild(calcTreeElement(), EXPRESSION_BIT_SET); + if (exprChild == null) return null; + return (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(exprChild); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFieldImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFieldImpl.java new file mode 100644 index 00000000000..ce7338cf314 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFieldImpl.java @@ -0,0 +1,373 @@ +package com.intellij.psi.impl.source; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.PomField; +import com.intellij.psi.*; +import com.intellij.psi.impl.*; +import com.intellij.psi.impl.cache.InitializerTooLongException; +import com.intellij.psi.impl.cache.FieldView; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.parsing.ExpressionParsing; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +import java.util.HashSet; +import java.util.Set; + +public class PsiFieldImpl extends NonSlaveRepositoryPsiElement implements PsiField, PsiVariableEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiFieldImpl"); + + private PsiModifierListImpl myRepositoryModifierList = null; + + private String myCachedName = null; + private String myCachedTypeText = null; + private long myCachedFirstFieldInDeclId = -1; + private Boolean myCachedIsDeprecated = null; + private String myCachedInitializerText = null; + private Object myCachedInitializerValue = null; // PsiExpression on constant value for literal + + public PsiFieldImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiFieldImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedName = null; + myCachedInitializerText = null; + myCachedIsDeprecated = null; + myCachedInitializerValue = null; + } + + protected Object clone() { + PsiFieldImpl clone = (PsiFieldImpl)super.clone(); + clone.myRepositoryModifierList = null; + clone.myCachedTypeText = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0){ + if (myRepositoryModifierList != null){ + myRepositoryModifierList.setOwner(this); + myRepositoryModifierList = null; + } + } + else{ + myRepositoryModifierList = (PsiModifierListImpl)bindSlave(ChildRole.MODIFIER_LIST); + } + + myCachedTypeText = null; + myCachedFirstFieldInDeclId = -1; + } + + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? (PsiClass)parent : null; + } + + public final PsiIdentifier getNameIdentifier(){ + return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public String getName() { + if (myCachedName == null){ + if (getTreeElement() != null){ + myCachedName = getNameIdentifier().getText(); + } + else{ + myCachedName = getRepositoryManager().getFieldView().getName(getRepositoryId()); + } + } + return myCachedName; + } + + public PsiElement setName(String name) throws IncorrectOperationException{ + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiType getType(){ + if (getTreeElement() != null){ + return SharedImplUtil.getType(this); + } + else{ + myCachedTypeText = getRepositoryManager().getFieldView().getTypeText(getRepositoryId()); + try{ + return myManager.getElementFactory().createTypeFromText(myCachedTypeText, this); + } + catch(IncorrectOperationException e){ + LOG.error(e); + return null; + } + } + } + + public PsiTypeElement getTypeElement(){ + PsiField firstField = findFirstFieldInDeclaration(); + if (firstField != this){ + return firstField.getTypeElement(); + } + + return (PsiTypeElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public PsiModifierList getModifierList(){ + PsiField firstField = findFirstFieldInDeclaration(); + if (firstField != this){ + return firstField.getModifierList(); + } + + if (getRepositoryId() >= 0){ + if (myRepositoryModifierList == null){ + myRepositoryModifierList = new PsiModifierListImpl(myManager, this); + } + return myRepositoryModifierList; + } + else{ + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + private PsiField findFirstFieldInDeclaration(){ + if (myRepositoryModifierList != null) return this; // optmization + + CompositeElement treeElement = getTreeElement(); + if (treeElement != null){ + TreeElement modifierList = treeElement.findChildByRole(ChildRole.MODIFIER_LIST); + if (modifierList != null) { + return this; + } + else{ + TreeElement prevField = treeElement.getTreePrev(); + while(prevField.getElementType() != JavaElementType.FIELD){ + prevField = prevField.getTreePrev(); + } + return ((PsiFieldImpl)SourceTreeToPsiMap.treeElementToPsi(prevField)).findFirstFieldInDeclaration(); + } + } + else{ + long repositoryId = getRepositoryId(); + if (myCachedFirstFieldInDeclId < 0){ + myCachedFirstFieldInDeclId = getRepositoryManager().getFieldView().getFirstFieldInDeclaration(repositoryId); + } + long repositoryId1 = myCachedFirstFieldInDeclId; + if (repositoryId1 == repositoryId){ + return this; + } + else{ + return (PsiField)getRepositoryElementsManager().findOrCreatePsiElementById(repositoryId1); + } + } + } + + public PsiExpression getInitializer() { + return (PsiExpression)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.INITIALIZER); + } + + public boolean hasInitializer() { + if (getTreeElement() != null){ + return getInitializer() != null; + } + else{ + try{ + return getInitializerText() != null; + } + catch(InitializerTooLongException e){ + calcTreeElement(); + return hasInitializer(); + } + } + } + + public PomField getPom() { + //TODO: + return null; + } + + private static class OurConstValueComputer implements ResolveCache.ConstValueComputer{ + private static final OurConstValueComputer INSTANCE = new OurConstValueComputer(); + + public Object execute(PsiVariable variable, Set visitedVars) { + return ((PsiFieldImpl)variable)._computeConstantValue(visitedVars); + } + } + + private Object _computeConstantValue(Set visitedVars) { + if (myCachedInitializerValue != null && !(myCachedInitializerValue instanceof PsiExpression)){ + return myCachedInitializerValue; + } + + PsiType type = getType(); + if (type == null) return null; + // javac rejects all non primitive and non String constants, although JLS states constants "variables whose initializers are constant expressions" + if (!(type instanceof PsiPrimitiveType) && !type.equalsToText("java.lang.String")) return null; + + PsiExpression initializer; + if (myCachedInitializerValue instanceof PsiExpression){ + initializer = (PsiExpression)myCachedInitializerValue; + } + else{ + if (getTreeElement() != null){ + initializer = getInitializer(); + if (initializer == null) return null; + } + else{ + try{ + String initializerText = getInitializerText(); + if (initializerText == null) return null; + final FileElement holderElement = new DummyHolder(myManager, this).getTreeElement(); + CompositeElement exprElement = ExpressionParsing.parseExpressionText(myManager, initializerText.toCharArray(), 0, initializerText.length(), holderElement.getCharTable()); + TreeUtil.addChildren(holderElement, exprElement); + initializer = (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(exprElement); + } + catch(InitializerTooLongException e){ + calcTreeElement(); + return computeConstantValue(visitedVars); + } + } + } + + Object result = PsiConstantEvaluationHelperImpl.computeCastTo(initializer, type, visitedVars); + + if (initializer instanceof PsiLiteralExpression){ + myCachedInitializerValue = result; + } + else{ + myCachedInitializerValue = initializer; + } + + + return result; + } + + public Object computeConstantValue() { + if (myCachedInitializerValue != null && !(myCachedInitializerValue instanceof PsiExpression)){ + return myCachedInitializerValue; + } + + return computeConstantValue(new HashSet(2)); + } + + public Object computeConstantValue(Set visitedVars) { + if (!hasModifierProperty(PsiModifier.FINAL)) return null; + + return myManager.getResolveCache().computeConstantValueWithCaching(this, OurConstValueComputer.INSTANCE, visitedVars); + } + + private String getInitializerText() throws InitializerTooLongException { + if (myCachedInitializerText == null){ + long repositoryId = getRepositoryId(); + myCachedInitializerText = getRepositoryManager().getFieldView().getInitializerText(repositoryId); + if (myCachedInitializerText == null) myCachedInitializerText = ""; + } + return myCachedInitializerText.length() > 0 ? myCachedInitializerText : null; + } + + public boolean isDeprecated() { + if (myCachedIsDeprecated == null){ + boolean deprecated; + if (getTreeElement() != null){ + PsiDocComment docComment = getDocComment(); + deprecated = docComment != null && getDocComment().findTagByName("deprecated") != null; + if (!deprecated) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + else{ + FieldView fieldView = getRepositoryManager().getFieldView(); + deprecated = fieldView.isDeprecated(getRepositoryId()); + if (!deprecated && fieldView.mayBeDeprecatedByAnnotation(getRepositoryId())) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + myCachedIsDeprecated = deprecated ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsDeprecated.booleanValue(); + } + + public PsiDocComment getDocComment(){ + CompositeElement treeElement = calcTreeElement(); + if (getTypeElement() != null) { + return (PsiDocComment)treeElement.findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); + } + else{ + TreeElement prevField = treeElement.getTreePrev(); + while(prevField.getElementType() != JavaElementType.FIELD){ + prevField = prevField.getTreePrev(); + } + return ((PsiField)SourceTreeToPsiMap.treeElementToPsi(prevField)).getDocComment(); + } + } + + public void normalizeDeclaration() throws IncorrectOperationException{ + CheckUtil.checkWritable(this); + + TreeElement type = SourceTreeToPsiMap.psiElementToTree(getTypeElement()); + TreeElement modifierList = SourceTreeToPsiMap.psiElementToTree(getModifierList()); + TreeElement field = type.getTreeParent(); + while(true){ + TreeElement comma = TreeUtil.skipElements(field.getTreeNext(), ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET); + if (comma == null || comma.getElementType() != JavaTokenType.COMMA) break; + TreeElement nextField = TreeUtil.skipElements(comma.getTreeNext(), ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET); + if (nextField == null || nextField.getElementType() != JavaElementType.FIELD) break; + + TreeElement semicolon = Factory.createSingleLeafElement(JavaTokenType.SEMICOLON, new char[]{';'}, 0, 1, null, getManager()); + CodeEditUtil.addChild((CompositeElement)field, semicolon, null); + + CodeEditUtil.removeChild(comma.getTreeParent(), comma); + + TreeElement typeClone = (TreeElement)type.clone(); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(type); + typeClone.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + CodeEditUtil.addChild((CompositeElement)nextField, typeClone, ((CompositeElement)nextField).firstChild); + + TreeElement modifierListClone = (TreeElement)modifierList.clone(); + modifierListClone.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + CodeEditUtil.addChild((CompositeElement)nextField, modifierListClone, ((CompositeElement)nextField).firstChild); + + field = nextField; + } + + SharedImplUtil.normalizeBrackets(this); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitField(this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + return true; + } + + public String toString(){ + return "PsiField:" + getName(); + } + + public PsiElement getOriginalElement() { + PsiClass originalClass = (PsiClass)getContainingClass().getOriginalElement(); + PsiField originalField = originalClass.findFieldByName(getName(), false); + return originalField != null ? originalField : this; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getFieldPresentation(this); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFileImpl.java new file mode 100644 index 00000000000..e2613f7731f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiFileImpl.java @@ -0,0 +1,336 @@ +package com.intellij.psi.impl.source; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem; +import com.intellij.psi.*; +import com.intellij.psi.impl.*; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.file.PsiFileImplUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.LocalTimeCounter; +import com.intellij.util.text.CharArrayUtil; + +public abstract class PsiFileImpl extends NonSlaveRepositoryPsiElement implements PsiFile, PsiFileEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiFileImpl"); + + private VirtualFile myFile; + private String myName; // for myFile == null only + + private final IElementType myElementType; + private final IElementType myContentElementType; + + private long myModificationStamp; + private boolean myModificationStampSticky = false; + + protected PsiFile myOriginalFile; + private boolean myExplicitlySetAsPhysical; + private boolean myExplicitlySetAsValid; + + protected PsiFileImpl(PsiManagerImpl manager, IElementType elementType, IElementType contentElementType, VirtualFile file) { + super(manager, -2); + myFile = file; + myElementType = elementType; + myContentElementType = contentElementType; + myModificationStamp = file.getModificationStamp(); + } + + protected PsiFileImpl(PsiManagerImpl manager, + IElementType elementType, + IElementType contentElementType, + String name, + char[] text, + int startOffset, + int endOffset) { + super(manager, (RepositoryTreeElement)Factory.createCompositeElement(elementType)); + LOG.assertTrue(name != null); + myName = name; + myFile = null; + myElementType = elementType; + myContentElementType = contentElementType; + final FileElement parent = getTreeElement(); + TreeElement contentElement = Factory.createLeafElement(myContentElementType, text, startOffset, endOffset, -1, parent.getCharTable()); + TreeUtil.addChildren(parent, contentElement); + myModificationStamp = LocalTimeCounter.currentTime(); + } + + protected PsiFileImpl(PsiManagerImpl manager, IElementType elementType) { + super(manager, (RepositoryTreeElement)Factory.createCompositeElement(elementType)); + myElementType = elementType; + myName = null; + myFile = null; + myContentElementType = null; + myModificationStamp = LocalTimeCounter.currentTime(); + } + + public long getRepositoryId() { + long id = super.getRepositoryId(); + if (id == -2) { + RepositoryManager repositoryManager = getRepositoryManager(); + if (repositoryManager != null) { + id = repositoryManager.getFileId(myFile); + } + else { + id = -1; + } + super.setRepositoryId(id); // super is important here! + } + return id; + } + + public boolean isRepositoryIdInitialized() { + return super.getRepositoryId() != -2; + } + + public FileElement getTreeElement() { + return (FileElement)_getTreeElement(); + } + + public void prepareToRepositoryIdInvalidation() { + if (isRepositoryIdInitialized()){ + super.prepareToRepositoryIdInvalidation(); + } + } + + protected boolean isKeepTreeElementByHardReference() { + return myFile == null || myExplicitlySetAsPhysical; + } + + private CompositeElement _getTreeElement() { + return super.getTreeElement(); + } + + public VirtualFile getVirtualFile() { + return myFile; + } + + public void setVirtualFile(VirtualFile file) { + myFile = file; + if (file != null) { + myName = null; + } + } + + public boolean isValid() { + if (myFile == null || myExplicitlySetAsValid) return true; // "dummy" file + if (!myFile.isValid()) return false; + return myManager.getFileManager().findFile(myFile) == this; + } + + public boolean isContentsLoaded() { + return _getTreeElement() != null; + } + + public FileElement loadTreeElement() { + // load document outside lock for better performance + if (!isPhysical()) { + return getTreeElement(); + } + final Document document = FileDocumentManager.getInstance().getDocument(myFile); + + synchronized (PsiLock.LOCK) { + FileElement treeElement = getTreeElement(); + if (treeElement != null) return treeElement; + if (myFile != null && myManager.isAssertOnFileLoading(myFile)) { + LOG.error("File text loaded " + myFile.getPresentableUrl()); + } + treeElement = (FileElement)Factory.createCompositeElement(myElementType); + treeElement.setDocument(document); + final CharSequence docText = ((DocumentEx)document).getCharsSequence(); + char[] chars = CharArrayUtil.fromSequence(docText); + + TreeElement contentElement = Factory.createLeafElement(myContentElementType, chars, 0, docText.length(), -1, treeElement.getCharTable()); + TreeUtil.addChildren(treeElement, contentElement); + setTreeElement(treeElement); + treeElement.setPsiElement(this); + ((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myManager.getProject())).contentsLoaded(this); + if (LOG.isDebugEnabled()) { + LOG.debug("Loaded text for file " + myFile.getPresentableUrl()); + } + return treeElement; + } + } + + public PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass) { + return null; + } + + public void setIsPhysicalExplicitly(boolean b) { + //LOG.assertTrue(ApplicationManagerEx.getApplicationEx().isUnitTestMode()); + myExplicitlySetAsPhysical = b; + } + + public boolean isExplicitlySetAsPhysical() { + return myExplicitlySetAsPhysical; + } + + public void setIsValidExplicitly(boolean b) { + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode()); + myExplicitlySetAsValid = b; + } + + public void unloadContent() { + LOG.assertTrue(getTreeElement() != null); + + setTreeElement(null); + } + + public String getText() { + return new String(textToCharArray()); + } + + public PsiElement getNextSibling() { + return SharedPsiElementImplUtil.getNextSibling(this); + } + + public PsiElement getPrevSibling() { + return SharedPsiElementImplUtil.getPrevSibling(this); + } + + public long getModificationStamp() { + return myModificationStamp; + } + + public void setModificationStamp(long modificationStamp) { + myModificationStamp = modificationStamp; + } + + public void setModificationStampSticky(boolean timeStampSticky) { + myModificationStampSticky = timeStampSticky; + } + + public PsiElement[] getOnDemandImports(boolean includeImplicit, boolean checkIncludes) { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + public PsiClass[] getSingleClassImports(boolean checkIncludes) { + return PsiClass.EMPTY_ARRAY; + } + + public String[] getImplicitlyImportedPackages() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + public PsiJavaCodeReferenceElement[] getImplicitlyImportedPackageReferences() { + return PsiJavaCodeReferenceElement.EMPTY_ARRAY; + } + + public void subtreeChanged() { + if (!myModificationStampSticky) { + myModificationStamp = LocalTimeCounter.currentTime(); + } + super.subtreeChanged(); + } + + protected PsiFileImpl clone() { + PsiFileImpl clone = (PsiFileImpl)super.clone(); + + clone.myFile = null; + clone.myName = getName(); + clone.myExplicitlySetAsPhysical = false; + if (getVirtualFile() != null) { + clone.myOriginalFile = this; + } + else if (myOriginalFile != null) { + clone.myOriginalFile = myOriginalFile; + } + + return clone; + } + + public String getName() { + return myFile != null ? myFile.getName() : myName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + checkSetName(name); + + if (myFile == null) { + myName = name; + return this; // not absolutely correct - might change type + } + + return PsiFileImplUtil.setName(this, name); + } + + public void checkSetName(String name) throws IncorrectOperationException { + if (myFile == null) return; + PsiFileImplUtil.checkSetName(this, name); + } + + public boolean isWritable() { + return myFile != null ? myFile.isWritable() : true; + } + + public PsiElement getParent() { + return getContainingDirectory(); + } + + public PsiDirectory getContainingDirectory() { + if (myFile == null) return null; + final VirtualFile parentFile = myFile.getParent(); + if (parentFile == null) return null; + return getManager().findDirectory(parentFile); + } + + public PsiFile getContainingFile() { + return this; + } + + public void delete() throws IncorrectOperationException { + checkDelete(); + PsiFileImplUtil.doDelete(this); + } + + public void checkDelete() throws IncorrectOperationException { + if (myFile == null) { + throw new IncorrectOperationException(); + } + CheckUtil.checkWritable(this); + } + + public PsiFile getOriginalFile() { + return myOriginalFile; + } + + public boolean canContainJavaCode() { + return false; + } + + public PsiFile[] getPsiRoots() { + return new PsiFile[]{this}; + } + + public PsiFile createPseudoPhysicalCopy() { + PsiFileImpl copy = (PsiFileImpl)copy(); + copy.setIsPhysicalExplicitly(true); //? + return copy; + } + + public IElementType getContentElementType() { + return myContentElementType; + } + + public T getCopyableUserData(Key key) { + return getCopyableUserDataImpl(key); + } + + public void putCopyableUserData(Key key, T value) { + putCopyableUserDataImpl(key, value); + } + + public boolean isPhysical() { + return myExplicitlySetAsPhysical || myFile != null && !(myFile.getFileSystem() instanceof DummyFileSystem); + } + + public abstract Lexer createLexer(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImmediateClassType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImmediateClassType.java new file mode 100644 index 00000000000..5b67898097b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImmediateClassType.java @@ -0,0 +1,230 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.EmptySubstitutorImpl; +import com.intellij.psi.impl.PsiSubstitutorImpl; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +public class PsiImmediateClassType extends PsiClassType { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiImmediateClassType"); + private final PsiClass myClass; + private final PsiSubstitutor mySubstitutor; + private final PsiManager myManager; + private String myCanonicalText; + private String myPresentableText; + private String myInternalCanonicalText; + + private final PsiClassType.ClassResolveResult myClassResolveResult = new PsiClassType.ClassResolveResult() { + public PsiClass getElement() { + return myClass; + } + + public PsiSubstitutor getSubstitutor() { + return mySubstitutor; + } + + public boolean isValidResult() { + return true; + } + + public boolean isAccessible() { + return true; + } + + public boolean isStaticsScopeCorrect() { + return true; + } + + public PsiElement getCurrentFileResolveScope() { + return null; + } + + public boolean hasCandidates() { + return true; + } + + public boolean isPackagePrefixPackageReference() { + return false; + } + }; + + public PsiImmediateClassType(PsiClass aClass, PsiSubstitutor substitutor) { + myClass = aClass; + myManager = aClass.getManager(); + mySubstitutor = substitutor; + LOG.assertTrue(mySubstitutor != null); + } + + public PsiClass resolve() { + return myClass; + } + + public String getClassName() { + return myClass.getName(); + } + + private PsiClassType myCachedQualiferType; + private boolean isQualifierTypeCalculated = false; + public PsiClassType getQualiferType() { + if (isQualifierTypeCalculated) { + if (!(myClass.getParent() instanceof PsiClass)) { + myCachedQualiferType = null; + } else { + final PsiClass parentClass = ((PsiClass)myClass.getParent()); + myCachedQualiferType = new PsiImmediateClassType(parentClass, mySubstitutor); + } + isQualifierTypeCalculated = true; + } + return myCachedQualiferType; + } + + public PsiType[] getParameters() { + List lst = new ArrayList(); + final PsiTypeParameterList list = myClass.getTypeParameterList(); + if(list == null) return PsiType.EMPTY_ARRAY; + final PsiTypeParameter[] parameters = list.getTypeParameters(); + for(int i = 0; parameters != null && i < parameters.length; i++){ + lst.add(mySubstitutor.substitute(parameters[i])); + } + return lst.toArray(PsiType.EMPTY_ARRAY); + } + + public PsiClassType.ClassResolveResult resolveGenerics() { + return myClassResolveResult; + } + + public PsiClassType rawType() { + return myClass.getManager().getElementFactory().createType(myClass); + } + + public PsiType createUninvalidateableCopy() { + return this; + } + + public String getPresentableText() { + if (myPresentableText == null) { + final StringBuffer buffer = new StringBuffer(); + buildText(myClass, buffer, false, false); + myPresentableText = buffer.toString(); + } + return myPresentableText; + } + + public String getCanonicalText() { + if (myCanonicalText == null) { + final StringBuffer buffer = new StringBuffer(); + buildText(myClass, buffer, true, false); + myCanonicalText = buffer.toString(); + } + return myCanonicalText; + } + + public String getInternalCanonicalText() { + if (myInternalCanonicalText == null) { + final StringBuffer buffer = new StringBuffer(); + buildText(myClass, buffer, true, true); + myInternalCanonicalText = buffer.toString(); + } + return myInternalCanonicalText; + } + + private void buildText(PsiClass aClass, StringBuffer buffer, boolean canonical, boolean internal) { + if (aClass instanceof PsiAnonymousClass) { + aClass = ((PsiAnonymousClass)aClass).getBaseClassType().resolve(); + if (aClass == null) return; + } + PsiClass parentClass = null; + if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { + final PsiElement parent = aClass.getParent(); + if (parent instanceof PsiClass) { + parentClass = (PsiClass)parent; + } + } + + if (parentClass != null) { + buildText(parentClass, buffer, canonical, false); + buffer.append('.'); + buffer.append(aClass.getName()); + } + else { + final String name; + if (!canonical) { + name = aClass.getName(); + } + else { + final String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName != null) { + name = qualifiedName; + } + else { + name = aClass.getName(); + } + } + buffer.append(name); + } + + final PsiTypeParameterList typeParameterList = aClass.getTypeParameterList(); + if (typeParameterList != null) { + final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + if (typeParameters.length > 0) { + StringBuffer pineBuffer = new StringBuffer(); + pineBuffer.append('<'); + for (int i = 0; i < typeParameters.length; i++) { + PsiTypeParameter typeParameter = typeParameters[i]; + if (i > 0) pineBuffer.append(','); + final PsiType substitutionResult = mySubstitutor.substitute(typeParameter); + if (substitutionResult == null) { + pineBuffer = null; + break; + } + if (!canonical) { + pineBuffer.append(substitutionResult.getPresentableText()); + } + else { + if (internal) { + pineBuffer.append(substitutionResult.getInternalCanonicalText()); + } + else { + pineBuffer.append(substitutionResult.getCanonicalText()); + } + } + } + if (pineBuffer != null) { + buffer.append(pineBuffer); + buffer.append('>'); + } + } + } + } + + public boolean isValid() { + if (!myClass.isValid()) return false; + if (mySubstitutor instanceof EmptySubstitutorImpl) return true; + return mySubstitutor.isValid(); + } + + public boolean equalsToText(String text) { + PsiElementFactory factory = myManager.getElementFactory(); + final PsiType patternType; + try { + patternType = factory.createTypeFromText(text, null); + } + catch (IncorrectOperationException e) { + return false; + } + return equals(patternType); + + } + + public GlobalSearchScope getResolveScope() { + return myClass.getResolveScope(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportListImpl.java new file mode 100644 index 00000000000..aac113ea4ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportListImpl.java @@ -0,0 +1,221 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.cache.FileView; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class PsiImportListImpl extends SlaveRepositoryPsiElement implements PsiImportList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiImportListImpl"); + private PsiImportStatementBaseImpl[] myRepositoryImports = null; + private PsiImportStatementImpl[] myRepositoryClassImports = null; + private PsiImportStaticStatementImpl[] myRepositoryStaticImports = null; + + private HashMap myClassNameToImportMap = null; + private HashMap myPackageNameToImportMap = null; + private HashMap myNameToSingleImportMap = null; + + private static final PsiElementArrayConstructor IMPORT_STATEMENT_BASE_IMPL_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return new PsiImportStatementBaseImpl[length]; + } + }; + + public PsiImportListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiImportListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + protected Object clone() { + PsiImportListImpl clone = (PsiImportListImpl)super.clone(); + clone.myRepositoryImports = null; + clone.myRepositoryClassImports = null; + clone.myRepositoryStaticImports = null; + clone.myClassNameToImportMap = null; + clone.myPackageNameToImportMap = null; + clone.myNameToSingleImportMap = null; + return clone; + } + + public void setOwner(SrcRepositoryPsiElement owner) { + super.setOwner(owner); + + if (myOwner == null){ + if (myRepositoryImports != null){ + for(int i = 0; i < myRepositoryImports.length; i++){ + PsiImportStatementBaseImpl anImport = myRepositoryImports[i]; + anImport.setOwnerAndIndex(this, i); + } + } + myRepositoryImports = null; + myRepositoryClassImports = null; + myRepositoryStaticImports = null; + } + else{ + myRepositoryImports = (PsiImportStatementBaseImpl[])bindIndexedSlaves(IMPORT_STATEMENT_BASE_BIT_SET, IMPORT_STATEMENT_BASE_IMPL_ARRAY_CONSTRUCTOR); + myRepositoryClassImports = null; + myRepositoryStaticImports = null; + } + } + + public void subtreeChanged() { + myClassNameToImportMap = null; + myPackageNameToImportMap = null; + myNameToSingleImportMap = null; + super.subtreeChanged(); + } + + public PsiImportStatement[] getImportStatements(){ + if (myOwner != null){ + if (myRepositoryClassImports == null){ + calcRepositoryImports(); + final ArrayList importStatements = new ArrayList(); + for (int i = 0; i < myRepositoryImports.length; i++) { + PsiImportStatementBaseImpl repositoryImport = myRepositoryImports[i]; + if (repositoryImport instanceof PsiImportStatementImpl) { + importStatements.add((PsiImportStatementImpl) repositoryImport); + } + } + myRepositoryClassImports = (PsiImportStatementImpl[])importStatements.toArray(new PsiImportStatementImpl[importStatements.size()]); + } + return myRepositoryClassImports; + } + else{ + return (PsiImportStatement[])calcTreeElement().getChildrenAsPsiElements(IMPORT_STATEMENT_BIT_SET, PSI_IMPORT_STATEMENT_ARRAY_CONSTRUCTOR); + } + } + + public PsiImportStaticStatement[] getImportStaticStatements() { + if (myOwner != null){ + if (myRepositoryStaticImports == null){ + calcRepositoryImports(); + final ArrayList importStatements = new ArrayList(); + for (int i = 0; i < myRepositoryImports.length; i++) { + PsiImportStatementBaseImpl repositoryImport = myRepositoryImports[i]; + if (repositoryImport instanceof PsiImportStaticStatementImpl) { + importStatements.add((PsiImportStaticStatementImpl) repositoryImport); + } + } + myRepositoryStaticImports = (PsiImportStaticStatementImpl[])importStatements.toArray(new PsiImportStaticStatementImpl[importStatements.size()]); + } + return myRepositoryStaticImports; + } + else{ + return (PsiImportStaticStatement[])calcTreeElement().getChildrenAsPsiElements(IMPORT_STATIC_STATEMENT_BIT_SET, PSI_IMPORT_STATIC_STATEMENT_ARRAY_CONSTRUCTOR); + } + + } + + public PsiImportStatementBase[] getAllImportStatements() { + if (myOwner != null) { + calcRepositoryImports(); + return myRepositoryImports; + } + else { + return (PsiImportStatementBase[])calcTreeElement().getChildrenAsPsiElements(IMPORT_STATEMENT_BASE_BIT_SET, PSI_IMPORT_STATEMENT_BASE_ARRAY_CONSTRUCTOR); + } + } + + private void calcRepositoryImports() { + if (myRepositoryImports == null){ + CompositeElement treeElement = getTreeElement(); + if (treeElement != null){ + final TreeElement[] imports = treeElement.getChildren(IMPORT_STATEMENT_BASE_BIT_SET); + int count = imports.length; + myRepositoryImports = new PsiImportStatementBaseImpl[count]; + for(int i = 0; i < myRepositoryImports.length; i++){ + final IElementType type = imports[i].getElementType(); + if (type == IMPORT_STATEMENT) { + myRepositoryImports[i] = new PsiImportStatementImpl(myManager, this, i); + } + else if (imports[i].getElementType() == IMPORT_STATIC_STATEMENT){ + myRepositoryImports[i] = new PsiImportStaticStatementImpl(myManager, this, i); + } + else { + LOG.assertTrue(false, "Unknown child: " + type.toString() + " " + type); + } + } + } + else{ + final FileView fileView = getRepositoryManager().getFileView(); + final long repositoryId = getRepositoryId(); + int count = fileView.getImportStatementsCount(repositoryId); + myRepositoryImports = new PsiImportStatementBaseImpl[count]; + for(int i = 0; i < myRepositoryImports.length; i++){ + if (fileView.isImportStatic(repositoryId, i)) { + myRepositoryImports[i] = new PsiImportStaticStatementImpl(myManager, this, i); + } + else { + myRepositoryImports[i] = new PsiImportStatementImpl(myManager, this, i); + } + } + } + + } + } + + public PsiImportStatement findSingleClassImportStatement(String qName) { + initializeMaps(); + return (PsiImportStatement)myClassNameToImportMap.get(qName); + } + + public PsiImportStatement findOnDemandImportStatement(String packageName) { + initializeMaps(); + return (PsiImportStatement)myPackageNameToImportMap.get(packageName); + } + + public PsiImportStatementBase findSingleImportStatement(String name) { + initializeMaps(); + return (PsiImportStatementBase)myNameToSingleImportMap.get(name); + } + + private void initializeMaps() { + if (myClassNameToImportMap == null){ + myClassNameToImportMap = new HashMap(); + myPackageNameToImportMap = new HashMap(); + myNameToSingleImportMap = new HashMap(); + PsiImportStatement[] imports = getImportStatements(); + for(int i = 0; i < imports.length; i++){ + PsiImportStatement anImport = imports[i]; + String qName = anImport.getQualifiedName(); + if (qName == null) continue; + if (anImport.isOnDemand()){ + myPackageNameToImportMap.put(qName, anImport); + } + else{ + myClassNameToImportMap.put(qName, anImport); + myNameToSingleImportMap.put(anImport.getImportReference().getReferenceName(), anImport); + } + } + + PsiImportStaticStatement[] importStatics = getImportStaticStatements(); + for (int i = 0; i < importStatics.length; i++) { + PsiImportStaticStatement importStatic = importStatics[i]; + if (!importStatic.isOnDemand()) { + String referenceName = importStatic.getReferenceName(); + if (referenceName != null) { + myNameToSingleImportMap.put(referenceName, importStatic); + } + } + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitImportList(this); + } + + public String toString(){ + return "PsiImportList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java new file mode 100644 index 00000000000..4c0dcb27348 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java @@ -0,0 +1,81 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiImportStatementBase; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.util.PatchedSoftReference; +import com.intellij.util.PatchedWeakReference; + +import java.lang.ref.Reference; + +/** + * @author dsl + */ +public abstract class PsiImportStatementBaseImpl extends IndexedRepositoryPsiElement implements PsiImportStatementBase{ + private Reference myCachedMirrorReference = null; + private Boolean myCachedIsOnDemand = null; + + protected PsiImportStatementBaseImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, int index) { + super(manager, owner, index); + } + + protected PsiImportStatementBaseImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedIsOnDemand = null; + setCachedMirrorReference(null); + } + + public void setOwnerAndIndex(SrcRepositoryPsiElement owner, int index) { + super.setOwnerAndIndex(owner, index); + setCachedMirrorReference(null); + } + + protected Object clone() { + PsiImportStatementBaseImpl clone = (PsiImportStatementBaseImpl)super.clone(); + clone.setCachedMirrorReference(null); + return clone; + } + + public boolean isOnDemand(){ + if (myCachedIsOnDemand == null){ + boolean onDemand; + if (getTreeElement() != null){ + onDemand = calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_ON_DEMAND_DOT) != null; + } + else{ + onDemand = getRepositoryManager().getFileView().isImportOnDemand(getRepositoryId(), getIndex()); + } + myCachedIsOnDemand = onDemand ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsOnDemand.booleanValue(); + } + + public PsiElement resolve() { + final PsiJavaCodeReferenceElement mirrorReference = getMirrorReference(); + return mirrorReference == null ? null : mirrorReference.resolve(); + } + + protected abstract PsiJavaCodeReferenceElement getMirrorReference(); + + protected PsiJavaCodeReferenceElement getCachedMirrorReference() { + return myCachedMirrorReference == null ? null : (PsiJavaCodeReferenceElement)myCachedMirrorReference.get(); + } + + protected void setCachedMirrorReference(PsiJavaCodeReferenceElement refElement) { + if (refElement == null) { + myCachedMirrorReference = null; + } + else { + myCachedMirrorReference = myManager.isBatchFilesProcessingMode() + ? new PatchedWeakReference(refElement) + : (Reference)new PatchedSoftReference(refElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementImpl.java new file mode 100644 index 00000000000..5e8ca376601 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStatementImpl.java @@ -0,0 +1,65 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiImportStatement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.*; + +public class PsiImportStatementImpl extends PsiImportStatementBaseImpl implements PsiImportStatement { + + public PsiImportStatementImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiImportStatementImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, int index) { + super(manager, owner, index); + } + + public String getQualifiedName() { + final PsiJavaCodeReferenceElement mirrorReference = getMirrorReference(); + return mirrorReference == null ? null : mirrorReference.getCanonicalText(); + } + + public PsiJavaCodeReferenceElement getImportReference() { + return (PsiJavaCodeReferenceElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_REFERENCE); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitImportStatement(this); + } + + public String toString(){ + return "PsiImportStatement"; + } + + public PsiJavaCodeReferenceElement getMirrorReference() { + if (myOwner != null){ + if (getCachedMirrorReference() == null){ + CompositeElement treeElement = getTreeElement(); + if (treeElement != null){ + setCachedMirrorReference((PsiJavaCodeReferenceElementImpl) treeElement.findChildByRole(ChildRole.IMPORT_REFERENCE)); + } + else{ + final FileElement holderElement = new DummyHolder(myManager, this).getTreeElement(); + final String refText = getRepositoryManager().getFileView().getImportQualifiedName(getRepositoryId(), getIndex()); + if (refText == null) return null; + PsiJavaCodeReferenceElementImpl mirrorRef = (PsiJavaCodeReferenceElementImpl) Parsing.parseJavaCodeReferenceText(myManager, refText.toCharArray(), holderElement.getCharTable()); + if(mirrorRef == null) return null; + setCachedMirrorReference(mirrorRef); + TreeUtil.addChildren(holderElement, mirrorRef); + mirrorRef.setKindWhenDummy( + isOnDemand() + ? PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND + : PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND); + } + } + return getCachedMirrorReference(); + } + else{ + return (PsiJavaCodeReferenceElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_REFERENCE); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java new file mode 100644 index 00000000000..a1f8c61a614 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java @@ -0,0 +1,357 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +public class PsiImportStaticReferenceElementImpl extends CompositePsiElement implements PsiImportStaticReferenceElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiImportStaticReferenceElementImpl"); + private String myCanonicalText; + + public PsiImportStaticReferenceElementImpl() { + super(IMPORT_STATIC_REFERENCE); + } + + public int getTextOffset() { + TreeElement refName = findChildByRole(ChildRole.REFERENCE_NAME); + if (refName != null){ + return refName.getStartOffset(); + } + else{ + return super.getTextOffset(); + } + } + + public void clearCaches() { + super.clearCaches(); + myCanonicalText = null; + } + + public final TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.REFERENCE_NAME: + if (lastChild.getElementType() == IDENTIFIER){ + return lastChild; + } + else{ + return null; + } + + case ChildRole.QUALIFIER: + if (firstChild.getElementType() == JAVA_CODE_REFERENCE){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + } + } + + public final int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JAVA_CODE_REFERENCE) { + return ChildRole.QUALIFIER; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == IDENTIFIER) { + return ChildRole.REFERENCE_NAME; + } + else { + return ChildRole.NONE; + } + } + + + public PsiElement getReferenceNameElement() { + return findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + } + + public PsiReferenceParameterList getParameterList() { + return null; + } + + public PsiType[] getTypeParameters() { + return PsiType.EMPTY_ARRAY; + } + + public PsiElement getQualifier() { + return findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiJavaCodeReferenceElement getClassReference() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiImportStaticStatement bindToTargetClass(PsiClass aClass) throws IncorrectOperationException { + final String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName == null) throw new IncorrectOperationException(); + final CompositeElement newRef = Parsing.parseJavaCodeReferenceText(getManager(), qualifiedName.toCharArray(), SharedImplUtil.findCharTableByTree(this)); + if (getQualifier() != null) { + replaceChildInternal(findChildByRole(ChildRole.QUALIFIER), newRef); + return (PsiImportStaticStatement)getParent(); + } + else { + final LeafElement dot = Factory.createSingleLeafElement(ElementType.DOT, new char[]{'.'}, 0, 1, SharedImplUtil.findCharTableByTree(newRef), getManager()); + TreeUtil.insertAfter(newRef, dot); + final CompositeElement errorElement = Factory.createErrorElement("Identifier or '*' expected"); + TreeUtil.insertAfter(dot, errorElement); + final CompositeElement parentComposite = ((CompositeElement)SourceTreeToPsiMap.psiElementToTree(getParent())); + parentComposite.addInternal(newRef, errorElement, this, Boolean.TRUE); + parentComposite.deleteChildInternal(this); + return (PsiImportStaticStatement)SourceTreeToPsiMap.treeElementToPsi(parentComposite); + } + } + + public boolean isQualified() { + return findChildByRole(ChildRole.QUALIFIER) != null; + } + + public String getQualifiedName() { + return getCanonicalText(); + } + + public boolean isSoft() { + return false; + } + + public String getReferenceName() { + final TreeElement childByRole = findChildByRole(ChildRole.REFERENCE_NAME); + if (childByRole == null) return ""; + return childByRole.getText(); + } + + public PsiElement getElement() { + return this; + } + + public TextRange getRangeInElement() { + TreeElement nameChild = findChildByRole(ChildRole.REFERENCE_NAME); + if (nameChild == null) return new TextRange(0, getTextLength()); + final int startOffset = nameChild.getStartOffsetInParent(); + return new TextRange(startOffset, startOffset + nameChild.getTextLength()); + } + + public String getCanonicalText() { + if (myCanonicalText == null) { + myCanonicalText = calcCanonicalText(); + } + return myCanonicalText; + } + + private String calcCanonicalText() { + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)getQualifier(); + if (referenceElement == null) { + return getReferenceName(); + } + else { + return referenceElement.getCanonicalText() + "." + getReferenceName(); + } + } + + public String toString() { + return "PsiImportStaticReferenceElement:" + getText(); + } + + public ResolveResult advancedResolve(boolean incompleteCode) { + final ResolveResult[] results = multiResolve(incompleteCode); + if (results.length == 1) return results[0]; + return ResolveResult.EMPTY; + } + + public ResolveResult[] multiResolve(boolean incompleteCode) { + final ResolveCache resolveCache = ((PsiManagerImpl)getManager()).getResolveCache(); + return resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, false, incompleteCode); + } + + private class OurResolveResult implements ResolveResult { + PsiMember myTarget; + Boolean myAccessible = null; + + + public OurResolveResult(PsiMember target) { + myTarget = target; + } + + public PsiMember getElement() { + return myTarget; + } + + public PsiSubstitutor getSubstitutor() { + return PsiSubstitutor.EMPTY; + } + + public boolean isValidResult() { + return isAccessible(); + } + + public boolean isAccessible() { + if (myAccessible == null) { + myAccessible = Boolean.valueOf(getManager().getResolveHelper().isAccessible(myTarget, PsiImportStaticReferenceElementImpl.this, null)); + } + return myAccessible.booleanValue(); + } + + public boolean isStaticsScopeCorrect() { + return true; + } + + public PsiElement getCurrentFileResolveScope() { + return null; + } + + public boolean isPackagePrefixPackageReference() { + return false; + } + + } + + private static final class OurGenericsResolver implements ResolveCache.GenericsResolver { + private static final OurGenericsResolver INSTANCE = new OurGenericsResolver(); + public ResolveResult[] resolve(PsiJavaReference ref, boolean incompleteCode) { + LOG.assertTrue(ref instanceof PsiImportStaticReferenceElementImpl); + final PsiImportStaticReferenceElementImpl referenceElement = ((PsiImportStaticReferenceElementImpl)ref); + final PsiElement qualifier = referenceElement.getQualifier(); + if (!(qualifier instanceof PsiJavaCodeReferenceElement)) return ResolveResult.EMPTY_ARRAY; + final PsiElement target = ((PsiJavaCodeReferenceElement)qualifier).resolve(); + if (!(target instanceof PsiClass)) return ResolveResult.EMPTY_ARRAY; + final ArrayList results = new ArrayList(); + target.processDeclarations(referenceElement.new MyScopeProcessor(results), + PsiSubstitutor.EMPTY, referenceElement, referenceElement); + if (results.size() <= 1) { + return results.toArray(new ResolveResult[results.size()]); + } + for(int i = results.size() - 1; i >= 0; i--) { + final ResolveResult resolveResult = results.get(i); + if (!resolveResult.isValidResult()) { + results.remove(i); + } + } + return results.toArray(new ResolveResult[results.size()]); + } + + } + + private class MyScopeProcessor extends BaseScopeProcessor implements NameHint { + private final List myResults; + + public MyScopeProcessor(List results) { + myResults = results; + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiMember + && ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { + myResults.add(new OurResolveResult((PsiMember)element)); + } + return true; + } + + public void handleEvent(Event event, Object associated) { + } + + public String getName() { + return getReferenceName(); + } + } + + public PsiReference getReference() { + return this; + } + + public PsiElement resolve() { + return advancedResolve(false).getElement(); + } + + public boolean isReferenceTo(PsiElement element) { + final String name = getReferenceName(); + if (name == null) return false; + if (!(element instanceof PsiNamedElement) || !(name.equals(((PsiNamedElement)element).getName()))) { + return false; + } + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + PsiElement oldIdentifier = findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + if (oldIdentifier == null){ + throw new IncorrectOperationException(); + } + PsiIdentifier identifier = getManager().getElementFactory().createIdentifier(newElementName); + oldIdentifier.replace(identifier); + return this; + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + if (!(element instanceof PsiMember) || + !(element instanceof PsiNamedElement) || + !((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC) || + ((PsiNamedElement)element).getName() == null) { + throw new IncorrectOperationException(); + } + + PsiClass containingClass = ((PsiMember)element).getContainingClass(); + if (containingClass == null) throw new IncorrectOperationException(); + PsiElement qualifier = getQualifier(); + if (qualifier == null) { + throw new IncorrectOperationException(); + } else { + ((PsiJavaCodeReferenceElement)qualifier).bindToElement(containingClass); + } + + PsiElement oldIdentifier = findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + if (oldIdentifier == null){ + throw new IncorrectOperationException(); + } + + PsiIdentifier identifier = getManager().getElementFactory().createIdentifier(((PsiNamedElement)element).getName()); + oldIdentifier.replace(identifier); + return this; + } + + public void processVariants(PsiScopeProcessor processor) { + ElementFilter filter = new OrFilter(new ClassFilter[]{new ClassFilter(PsiModifierListOwner.class), + new ClassFilter(PsiPackage.class)}); + FilterScopeProcessor proc = new FilterScopeProcessor(filter, this, processor); + PsiScopesUtil.resolveAndWalk(proc, this, null, true); + } + + public Object[] getVariants() { + // IMPLEMENT[dsl] + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitImportStaticReferenceElement(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticStatementImpl.java new file mode 100644 index 00000000000..5a5ffcb2fe8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiImportStaticStatementImpl.java @@ -0,0 +1,114 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.*; + +public class PsiImportStaticStatementImpl extends PsiImportStatementBaseImpl implements PsiImportStaticStatement { + + public PsiImportStaticStatementImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiImportStaticStatementImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, int index) { + super(manager, owner, index); + } + + public PsiClass resolveTargetClass() { + final PsiJavaCodeReferenceElement classReference = getClassReference(); + if (classReference == null) return null; + final PsiElement result = classReference.resolve(); + if (result instanceof PsiClass) { + return (PsiClass) result; + } + else { + return null; + } + } + + public String getReferenceName() { + if (isOnDemand()) return null; + final PsiImportStaticReferenceElement memberReference = getMemberReference(); + if (memberReference != null) { + return memberReference.getReferenceName(); + } + else { + return null; + } + } + + public PsiJavaCodeReferenceElement getImportReference() { + return (PsiJavaCodeReferenceElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_REFERENCE); + } + + private PsiImportStaticReferenceElement getMemberReference() { + if (isOnDemand()) { + return null; + } + else { + return (PsiImportStaticReferenceElement) getMirrorReference(); + } + } + + private PsiJavaCodeReferenceElement getClassReference() { + if (isOnDemand()) { + return getMirrorReference(); + } + else { + final PsiImportStaticReferenceElement memberReference = getMemberReference(); + if (memberReference != null) { + return memberReference.getClassReference(); + } + else { + return null; + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitImportStaticStatement(this); + } + + public String toString(){ + return "PsiImportStaticStatement"; + } + + public PsiJavaCodeReferenceElement getMirrorReference() { + if (myOwner != null){ + PsiJavaCodeReferenceElement refElement = getCachedMirrorReference(); + if (refElement == null) { + CompositeElement treeElement = getTreeElement(); + if (treeElement != null){ + refElement = (PsiJavaCodeReferenceElement)treeElement.findChildByRole(ChildRole.IMPORT_REFERENCE); + } + else{ + final FileElement holderElement = new DummyHolder(myManager, this).getTreeElement(); + final ParsingContext context = new ParsingContext(holderElement.getCharTable()); + final String refText = getRepositoryManager().getFileView().getImportQualifiedName(getRepositoryId(), getIndex()); + if (refText == null) return null; + CompositeElement parsedRef = Parsing.parseJavaCodeReferenceText(myManager, refText.toCharArray(), context.getCharTable()); + refElement = (PsiJavaCodeReferenceElement)parsedRef; + final boolean onDemand = isOnDemand(); + if (onDemand) { + TreeUtil.addChildren(holderElement, (TreeElement)refElement); + ((PsiJavaCodeReferenceElementImpl)refElement).setKindWhenDummy( + PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND); + } + else { + refElement = (PsiImportStaticReferenceElement)context.getImportsTextParsing().convertToImportStaticReference(parsedRef); + TreeUtil.addChildren(holderElement, (TreeElement)refElement); + } + } + + setCachedMirrorReference(refElement); + } + + return refElement; + } + else{ + return (PsiJavaCodeReferenceElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_REFERENCE); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java new file mode 100644 index 00000000000..9863faffa82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -0,0 +1,893 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.filters.*; +import com.intellij.psi.filters.element.ModifierFilter; +import com.intellij.psi.filters.classes.AnnotationTypeFilter; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiSubstitutorEx; +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerEx; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.resolve.ClassResolverProcessor; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.resolve.VariableResolverProcessor; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; + +public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiJavaCodeReferenceElement, SourceJavaCodeReference { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl"); + + private String myCachedQName = null; + private String myCachedTextSkipWhiteSpaceAndComments; + private int myKindWhenDummy = CLASS_NAME_KIND; + + public static final int CLASS_NAME_KIND = 1; + public static final int PACKAGE_NAME_KIND = 2; + public static final int CLASS_OR_PACKAGE_NAME_KIND = 3; + public static final int CLASS_FQ_NAME_KIND = 4; + public static final int CLASS_FQ_OR_PACKAGE_NAME_KIND = 5; + public static final int CLASS_IN_QUALIFIED_NEW_KIND = 6; + + public PsiJavaCodeReferenceElementImpl() { + super(JAVA_CODE_REFERENCE); + } + + public int getTextOffset() { + final TreeElement refName = findChildByRole(ChildRole.REFERENCE_NAME); + if (refName != null){ + return refName.getStartOffset(); + } + else{ + return super.getTextOffset(); + } + } + + public void setKindWhenDummy(final int kind) { + LOG.assertTrue(getTreeParent().getElementType() == DUMMY_HOLDER); + myKindWhenDummy = kind; + } + + public int getKind() { + IElementType i = getTreeParent().getElementType(); + if (i == DUMMY_HOLDER) { + return myKindWhenDummy; + } + else if (i == TYPE || i == EXTENDS_LIST || i == IMPLEMENTS_LIST || i == EXTENDS_BOUND_LIST || i == THROWS_LIST || i == THIS_EXPRESSION || + i == SUPER_EXPRESSION || + i == DOC_METHOD_OR_FIELD_REF || + i == DOC_TAG_VALUE_TOKEN || + i == REFERENCE_PARAMETER_LIST || + i == ANNOTATION) { + return CLASS_NAME_KIND; + } + else if (i == NEW_EXPRESSION) { + { + final TreeElement qualifier = getTreeParent().findChildByRole(ChildRole.QUALIFIER); + return qualifier != null ? CLASS_IN_QUALIFIED_NEW_KIND : CLASS_NAME_KIND; + } + } + else if (i == ANONYMOUS_CLASS) { + if (getTreeParent().getChildRole(this) == ChildRole.BASE_CLASS_REFERENCE) { + LOG.assertTrue(getTreeParent().getTreeParent().getElementType() == NEW_EXPRESSION); + final TreeElement qualifier = getTreeParent().getTreeParent().findChildByRole(ChildRole.QUALIFIER); + return qualifier != null ? CLASS_IN_QUALIFIED_NEW_KIND : CLASS_NAME_KIND; + } + else { + return CLASS_OR_PACKAGE_NAME_KIND; // uncomplete code + } + } + else if (i == PACKAGE_STATEMENT) { + return PACKAGE_NAME_KIND; + } + else if (i == IMPORT_STATEMENT) { + { + final boolean isOnDemand = ((PsiImportStatement)SourceTreeToPsiMap.treeElementToPsi(getTreeParent())).isOnDemand(); + return isOnDemand ? CLASS_FQ_OR_PACKAGE_NAME_KIND : CLASS_FQ_NAME_KIND; + } + } + else if (i == IMPORT_STATIC_STATEMENT) { + { + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + } + } + else if (i == JSP_IMPORT_VALUE) { + { + final TreeElement nextNonSpace = TreeUtil.skipElements(getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + final boolean isOnDemand = nextNonSpace != null && nextNonSpace.getElementType() == DOT; + return isOnDemand ? CLASS_FQ_OR_PACKAGE_NAME_KIND : CLASS_FQ_NAME_KIND; + } + } + else if (i == JAVA_CODE_REFERENCE) { + { + final int parentKind = ((PsiJavaCodeReferenceElementImpl)getTreeParent()).getKind(); + switch (parentKind) { + case CLASS_NAME_KIND: + return CLASS_OR_PACKAGE_NAME_KIND; + + case PACKAGE_NAME_KIND: + return PACKAGE_NAME_KIND; + + case CLASS_OR_PACKAGE_NAME_KIND: + return CLASS_OR_PACKAGE_NAME_KIND; + + case CLASS_FQ_NAME_KIND: + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + + case CLASS_IN_QUALIFIED_NEW_KIND: + return CLASS_IN_QUALIFIED_NEW_KIND; //?? + + default: + LOG.assertTrue(false); + return -1; + } + } + } + else if (i == CLASS || i == PARAMETER_LIST || i == ERROR_ELEMENT) { + return CLASS_OR_PACKAGE_NAME_KIND; + } + else if (i == IMPORT_STATIC_REFERENCE) { + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + } + else if (i == DOC_TAG || i == DOC_INLINE_TAG) { + return CLASS_OR_PACKAGE_NAME_KIND; + } + else { + LOG.error("Unknown parent for java code reference:" + getTreeParent()); + return CLASS_NAME_KIND; + } + } + + public void deleteChildInternal(final TreeElement child) { + if (getChildRole(child) == ChildRole.QUALIFIER){ + final TreeElement dot = findChildByRole(ChildRole.DOT); + super.deleteChildInternal(child); + deleteChildInternal(dot); + } + else{ + super.deleteChildInternal(child); + } + } + + public final TreeElement findChildByRole(final int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.REFERENCE_NAME: + if (lastChild.getElementType() == IDENTIFIER){ + return lastChild; + } + else{ + if (lastChild.getElementType() == REFERENCE_PARAMETER_LIST){ + TreeElement current = lastChild.getTreePrev(); + while(current != null && WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(current.getElementType())){ + current = current.getTreePrev(); + } + if (current != null && current.getElementType() == IDENTIFIER){ + return current; + } + } + return null; + } + + case ChildRole.REFERENCE_PARAMETER_LIST: + if (lastChild.getElementType() == REFERENCE_PARAMETER_LIST){ + return lastChild; + } + else{ + return null; + } + + case ChildRole.QUALIFIER: + if (firstChild.getElementType() == JAVA_CODE_REFERENCE){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + } + } + + public final int getChildRole(final TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + final IElementType i = child.getElementType(); + if (i == REFERENCE_PARAMETER_LIST) { + return ChildRole.REFERENCE_PARAMETER_LIST; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.QUALIFIER; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == IDENTIFIER) { + return ChildRole.REFERENCE_NAME; + } + else { + return ChildRole.NONE; + } + } + + /** + * [dsl]:Should not be called when tree is not loaded + * @return + */ + public PsiIdentifier getClassName() { + return (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + } + + public String getCanonicalText() { + switch(getKind()){ + case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND: + { + final PsiElement target = resolve(); + if (target instanceof PsiClass){ + final PsiClass aClass = (PsiClass)target; + String name = aClass.getQualifiedName(); + if (name == null){ + name = aClass.getName(); //? + } + final PsiType[] types = getTypeParameters(); + if (types.length == 0) return name; + + final StringBuffer buf = new StringBuffer(); + buf.append(name); + buf.append('<'); + for(int i = 0; i < types.length; i++){ + if (i > 0) buf.append(','); + buf.append(types[i].getCanonicalText()); + } + buf.append('>'); + + return buf.toString(); + } + else if (target instanceof PsiPackage){ + return ((PsiPackage)target).getQualifiedName(); + } + else{ + LOG.assertTrue(target == null); + return getTextSkipWhiteSpaceAndComments(); + } + } + + case PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND: + return getTextSkipWhiteSpaceAndComments(); + + default: + LOG.assertTrue(false); + return null; + } + } + + public PsiReference getReference() { + return this; + } + + public final PsiElement resolve() { + return advancedResolve(false).getElement(); + } + + private static final class OurGenericsResolver implements ResolveCache.GenericsResolver { + public static final OurGenericsResolver INSTANCE = new OurGenericsResolver(); + + public ResolveResult[] _resolve(final PsiJavaReference ref, final boolean incompleteCode) { + final PsiJavaCodeReferenceElementImpl referenceElement = (PsiJavaCodeReferenceElementImpl)ref; + final int kind = referenceElement.getKind(); + ResolveResult[] result = referenceElement.resolve(kind); + if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND){ + final VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement); + PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode); + result = processor.getResult(); + if (result.length > 0) + return result; + if (kind == CLASS_NAME_KIND) + return referenceElement.resolve(PACKAGE_NAME_KIND); + } + return result; + } + + public ResolveResult[] resolve(final PsiJavaReference ref, final boolean incompleteCode) { + final ResolveResult[] result = _resolve(ref, incompleteCode); + if (result.length > 0 && result[0].getElement() instanceof PsiClass){ + final PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters(); + final ResolveResult[] newResult = new ResolveResult[result.length]; + for(int i = 0; i < result.length; i++){ + final CandidateInfo resolveResult = (CandidateInfo)result[i]; + newResult[i] = new CandidateInfo( + resolveResult, + ((PsiSubstitutorEx)resolveResult.getSubstitutor()).inplacePutAll((PsiClass)resolveResult.getElement(), parameters) + ); + } + return newResult; + } + return result; + } + } + + public ResolveResult advancedResolve(final boolean incompleteCode) { + final ResolveResult[] results = multiResolve(incompleteCode); + if (results.length == 1) return results[0]; + return ResolveResult.EMPTY; + } + + public ResolveResult[] multiResolve(final boolean incompleteCode) { + final PsiManager manager = getManager(); + if (manager == null){ + LOG.assertTrue(false, "getManager() == null!"); + return ResolveResult.EMPTY_ARRAY; + } + + final ResolveCache resolveCache = ((PsiManagerImpl)manager).getResolveCache(); + final boolean needToPreventRecursion = getContext() instanceof PsiReferenceList; + return resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, needToPreventRecursion, incompleteCode); + } + + private final PsiSubstitutor updateSubstitutor(PsiSubstitutor subst, final PsiClass psiClass) { + final PsiType[] parameters = getTypeParameters(); + if (psiClass != null){ + subst = ((PsiSubstitutorEx)subst).inplacePutAll(psiClass, parameters); + } + return subst; + } + + private ResolveResult[] resolve(final int kind) { + switch(kind){ + case CLASS_FQ_NAME_KIND: + { + // TODO: support type parameters in FQ names + final String textSkipWhiteSpaceAndComments = getTextSkipWhiteSpaceAndComments(); + if(textSkipWhiteSpaceAndComments == null || textSkipWhiteSpaceAndComments.length() == 0) return ResolveResult.EMPTY_ARRAY; + final PsiClass aClass = getManager().findClass(textSkipWhiteSpaceAndComments, getResolveScope()); + if (aClass == null) return ResolveResult.EMPTY_ARRAY; + return new ResolveResult[]{new CandidateInfo(aClass, updateSubstitutor(PsiSubstitutor.EMPTY, aClass), this, false)}; + } + + case CLASS_IN_QUALIFIED_NEW_KIND: + { + final PsiExpression qualifier; + PsiElement parent = getParent(); + if (parent instanceof DummyHolder){ + parent = parent.getContext(); + } + + if (parent instanceof PsiAnonymousClass){ + parent = parent.getParent(); + } + if (parent instanceof PsiNewExpression){ + qualifier = ((PsiNewExpression)parent).getQualifier(); + LOG.assertTrue(qualifier != null); + } + else if (parent instanceof PsiJavaCodeReferenceElement){ + return ResolveResult.EMPTY_ARRAY; + } + else{ + LOG.assertTrue(false, "Invalid java reference!"); + return ResolveResult.EMPTY_ARRAY; + } + + final PsiType qualifierType = qualifier.getType(); + if (qualifierType == null) return ResolveResult.EMPTY_ARRAY; + if (!(qualifierType instanceof PsiClassType)) return ResolveResult.EMPTY_ARRAY; + final ResolveResult result = PsiUtil.resolveGenericsClassInType(qualifierType); + if (result.getElement() == null) return ResolveResult.EMPTY_ARRAY; + final PsiElement classNameElement; + classNameElement = getReferenceNameElement(); + if (!(classNameElement instanceof PsiIdentifier)) return ResolveResult.EMPTY_ARRAY; + final String className = classNameElement.getText(); + + final ClassResolverProcessor processor = new ClassResolverProcessor(className, this); + PsiScopesUtil.processScope(result.getElement(), processor, result.getSubstitutor(), this, this); + return processor.getResult(); + } + case CLASS_NAME_KIND: + { + final PsiElement classNameElement; + classNameElement = getReferenceNameElement(); + if (!(classNameElement instanceof PsiIdentifier)) return ResolveResult.EMPTY_ARRAY; + final String className = classNameElement.getText(); + + final ClassResolverProcessor processor = new ClassResolverProcessor(className, this); + PsiScopesUtil.resolveAndWalk(processor, this, null); + + return processor.getResult(); + } + + case PACKAGE_NAME_KIND: + { + final String packageName = getTextSkipWhiteSpaceAndComments(); + final PsiManager manager = getManager(); + final PsiPackage aPackage = manager.findPackage(packageName); + if (aPackage == null || !aPackage.isValid()) { + if (!manager.isPartOfPackagePrefix(packageName)) { + return ResolveResult.EMPTY_ARRAY; + } + else { + return CandidateInfo.RESOLVE_RESULT_FOR_PACKAGE_PREFIX_PACKAGE; + } + } + return new ResolveResult[]{new CandidateInfo(aPackage, PsiSubstitutor.EMPTY)}; + } + + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + { + final ResolveResult[] result = resolve(CLASS_FQ_NAME_KIND); + if (result.length == 0){ + return resolve(PACKAGE_NAME_KIND); + } + return result; + } + case CLASS_OR_PACKAGE_NAME_KIND: + { + final ResolveResult[] classResolveResult = resolve(CLASS_NAME_KIND); + // [dsl]todo[ik]: review this change I guess ResolveInfo should be merged if both + // class and package resolve failed. + if (classResolveResult.length == 0){ + final ResolveResult[] packageResolveResult = resolve(PACKAGE_NAME_KIND); + if (packageResolveResult.length > 0) return packageResolveResult; + } + return classResolveResult; + } + default: + LOG.assertTrue(false); + } + return ResolveResult.EMPTY_ARRAY; + } + + public final PsiElement handleElementRename(final String newElementName) throws IncorrectOperationException { + final PsiElement oldIdentifier = findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + if (oldIdentifier == null){ + throw new IncorrectOperationException(); + } + final PsiIdentifier identifier = getManager().getElementFactory().createIdentifier(newElementName); + oldIdentifier.replace(identifier); + return this; + } + + public PsiElement bindToElement(final PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + + if (isReferenceTo(element)) return this; + + switch(getKind()){ + case CLASS_NAME_KIND: + case CLASS_FQ_NAME_KIND: + { + if (!(element instanceof PsiClass)){ + throw new IncorrectOperationException(); + } + return bindToClass((PsiClass)element); + } + + case PACKAGE_NAME_KIND: + { + if (!(element instanceof PsiPackage)){ + throw new IncorrectOperationException(); + } + return bindToPackage((PsiPackage)element); + } + + case CLASS_OR_PACKAGE_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + { + if (element instanceof PsiClass){ + return bindToClass((PsiClass)element); + } + else if (element instanceof PsiPackage){ + return bindToPackage((PsiPackage)element); + } + else{ + throw new IncorrectOperationException(); + } + } + + case CLASS_IN_QUALIFIED_NEW_KIND: + { + if (element instanceof PsiClass){ + final PsiClass aClass = (PsiClass)element; + final String name = aClass.getName(); + if (name == null){ + throw new IncorrectOperationException(); + } + final TreeElement ref = Parsing.parseJavaCodeReferenceText(aClass.getManager(), name.toCharArray(), SharedImplUtil.findCharTableByTree(this)); + getTreeParent().replaceChildInternal(this, ref); + return SourceTreeToPsiMap.treeElementToPsi(ref); + } + else{ + throw new IncorrectOperationException(); + } + } + + default: + LOG.assertTrue(false); + return null; + } + } + + private PsiElement bindToClass(final PsiClass aClass) throws IncorrectOperationException { + String qName = aClass.getQualifiedName(); + if (qName == null){ + qName = aClass.getName(); + final PsiClass psiClass = getManager().getResolveHelper().resolveReferencedClass(qName, this); + if(!getManager().areElementsEquivalent(psiClass, aClass)){ + throw new IncorrectOperationException(); + } + } else { + if (getManager().findClass(qName, getResolveScope()) == null) { + return this; + } + } + + final boolean wasFullyQualified = isFullyQualified(); + final PsiManager manager = aClass.getManager(); + TreeElement ref = Parsing.parseJavaCodeReferenceText(manager, (qName + getParameterList().getText()).toCharArray(), SharedImplUtil.findCharTableByTree(this)); + getTreeParent().replaceChildInternal(this, ref); + if (!wasFullyQualified /*&& (TreeUtil.findParent(ref, ElementType.DOC_COMMENT) == null)*/){ + final CodeStyleManagerEx codeStyleManager = (CodeStyleManagerEx)manager.getCodeStyleManager(); + ref = SourceTreeToPsiMap.psiElementToTree( + codeStyleManager.shortenClassReferences(SourceTreeToPsiMap.treeElementToPsi(ref), CodeStyleManagerEx.UNCOMPLETE_CODE) + ); + } + return SourceTreeToPsiMap.treeElementToPsi(ref); + } + + private boolean isFullyQualified() { + switch(getKind()){ + case CLASS_OR_PACKAGE_NAME_KIND: + if (resolve() instanceof PsiPackage) return true; + case CLASS_NAME_KIND: + break; + + case PACKAGE_NAME_KIND: + case CLASS_FQ_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + return true; + + default: + LOG.assertTrue(false); + return true; + } + + final TreeElement qualifier = findChildByRole(ChildRole.QUALIFIER); + if (qualifier == null) return false; + + LOG.assertTrue(qualifier.getElementType() == JAVA_CODE_REFERENCE); + final PsiElement refElement = ((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(qualifier)).resolve(); + if (refElement instanceof PsiPackage) return true; + + return ((PsiJavaCodeReferenceElementImpl)SourceTreeToPsiMap.treeElementToPsi(qualifier)).isFullyQualified(); + } + + private PsiElement bindToPackage(final PsiPackage aPackage) throws IncorrectOperationException { + final String qName = aPackage.getQualifiedName(); + if (qName.length() == 0){ + throw new IncorrectOperationException(); + } + final TreeElement ref = Parsing.parseJavaCodeReferenceText(getManager(), qName.toCharArray(), SharedImplUtil.findCharTableByTree(this)); + getTreeParent().replaceChildInternal(this, ref); + return SourceTreeToPsiMap.treeElementToPsi(ref); + } + + public boolean isReferenceTo(final PsiElement element) { + switch(getKind()){ + case CLASS_NAME_KIND: + case CLASS_IN_QUALIFIED_NEW_KIND: + if (!(element instanceof PsiClass)) return false; + break; + + case CLASS_FQ_NAME_KIND: + { + if (!(element instanceof PsiClass)) return false; + final String qName = ((PsiClass)element).getQualifiedName(); + if (qName == null) return false; + return qName.equals(getCanonicalText()); + } + + case PACKAGE_NAME_KIND: + { + if (!(element instanceof PsiPackage)) return false; + final String qName = ((PsiPackage)element).getQualifiedName(); + if (qName == null) return false; + return qName.equals(getCanonicalText()); + } + + case CLASS_OR_PACKAGE_NAME_KIND: + { +// if (lastChild.type != IDENTIFIER) return false; + if (element instanceof PsiPackage){ + final String qName = ((PsiPackage)element).getQualifiedName(); + if (qName == null) return false; + return qName.equals(getCanonicalText()); + } + else if (element instanceof PsiClass){ + final PsiIdentifier nameIdentifier = ((PsiClass)element).getNameIdentifier(); + if (nameIdentifier == null) return false; + if (!getReferenceNameElement().textMatches(nameIdentifier)) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + else{ + return false; + } + } + + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + if (element instanceof PsiClass){ + final String qName = ((PsiClass)element).getQualifiedName(); + if (qName == null) return false; + return qName.equals(getCanonicalText()); + } + else if (element instanceof PsiPackage){ + final String qName = ((PsiPackage)element).getQualifiedName(); + if (qName == null) return false; + return qName.equals(getCanonicalText()); + } + else{ + return false; + } + + default: + LOG.assertTrue(false); + return true; + } + + final TreeElement referenceNameElement = findChildByRole(ChildRole.REFERENCE_NAME); + if (referenceNameElement.getElementType() != IDENTIFIER) return false; + final String name = ((PsiClass)element).getName(); + if (name == null) return false; + if (!referenceNameElement.getText().equals(name)) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + + private String getTextSkipWhiteSpaceAndComments() { + if (myCachedTextSkipWhiteSpaceAndComments == null){ + myCachedTextSkipWhiteSpaceAndComments = SourceUtil.getTextSkipWhiteSpaceAndComments(this); + } + return myCachedTextSkipWhiteSpaceAndComments; + } + + public String getClassNameText() { + if (myCachedQName == null){ + myCachedQName = PsiNameHelper.getQualifiedClassName(getTextSkipWhiteSpaceAndComments(), false); + } + return myCachedQName; + } + + public void fullyQualify(final PsiClass targetClass) { + final int kind = getKind(); + if (kind != CLASS_NAME_KIND && kind != CLASS_OR_PACKAGE_NAME_KIND && kind != CLASS_IN_QUALIFIED_NEW_KIND) { + LOG.error("Wrong kind " + kind); + return; + } + SourceUtil.fullyQualifyReference(this, targetClass); + } + + public boolean isQualified() { + return getChildRole(firstChild) != ChildRole.REFERENCE_NAME; + } + + public TreeElement getTreeQualifier() { + return findChildByRole(ChildRole.QUALIFIER); + } + + public PsiElement getQualifier() { + return SourceTreeToPsiMap.treeElementToPsi(getTreeQualifier()); + } + + public void dequalify() { + SourceUtil.dequalifyImpl(this); + } + + public void clearCaches() { + super.clearCaches(); + myCachedQName = null; + myCachedTextSkipWhiteSpaceAndComments = null; + } + + public Object[] getVariants() { + final ElementFilter filter; + switch(getKind()){ + + case CLASS_OR_PACKAGE_NAME_KIND: + filter = new OrFilter(); + ((OrFilter)filter).addFilter(new ClassFilter(PsiClass.class)); + ((OrFilter)filter).addFilter(new ClassFilter(PsiPackage.class)); + break; + case CLASS_NAME_KIND: + filter = new ClassFilter(PsiClass.class); + break; + case PACKAGE_NAME_KIND: + filter = new ClassFilter(PsiPackage.class); + break; + case CLASS_FQ_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + filter = new OrFilter(); + ((OrFilter)filter).addFilter(new ClassFilter(PsiPackage.class)); + if (isQualified()){ + ((OrFilter)filter).addFilter(new ClassFilter(PsiClass.class)); + } + break; + case CLASS_IN_QUALIFIED_NEW_KIND: + filter = new ClassFilter(PsiClass.class); + break; + default: + throw new RuntimeException("Unknown reference type"); + } + + return PsiImplUtil.getReferenceVariantsByFilter(this, filter); + } + + public boolean isSoft() { + return false; + } + + public void processVariants(final PsiScopeProcessor processor) { + final OrFilter filter = new OrFilter(); + PsiElement superParent = getParent(); + boolean smartCompletion = true; + if (isQualified()){ + smartCompletion = false; + } + else{ + while(superParent != null){ + if (superParent instanceof PsiCodeBlock || superParent instanceof PsiVariable){ + smartCompletion = false; + break; + } + superParent = superParent.getParent(); + } + } + if (!smartCompletion){ + filter.addFilter(new ClassFilter(PsiClass.class)); + filter.addFilter(new ClassFilter(PsiPackage.class)); + filter.addFilter(new NotFilter(new ConstructorFilter())); + filter.addFilter(new ClassFilter(PsiVariable.class)); + } + switch(getKind()){ + case CLASS_OR_PACKAGE_NAME_KIND: + filter.addFilter(new ClassFilter(PsiClass.class)); + filter.addFilter(new ClassFilter(PsiPackage.class)); + break; + case CLASS_NAME_KIND: + if (getParent() instanceof PsiAnnotation) { + filter.addFilter(new AnnotationTypeFilter()); + } else { + filter.addFilter(new ClassFilter(PsiClass.class)); + } + break; + case PACKAGE_NAME_KIND: + filter.addFilter(new ClassFilter(PsiPackage.class)); + break; + case CLASS_FQ_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + filter.addFilter(new ClassFilter(PsiPackage.class)); + if (isQualified()){ + filter.addFilter(new ClassFilter(PsiClass.class)); + } + break; + case CLASS_IN_QUALIFIED_NEW_KIND: + final PsiElement parent = getParent(); + if (parent instanceof PsiNewExpression){ + final PsiNewExpression newExpr = (PsiNewExpression)parent; + final PsiType type = newExpr.getQualifier().getType(); + final PsiClass aClass = PsiUtil.resolveClassInType(type); + if (aClass != null){ + PsiScopesUtil.processScope( + aClass, + new FilterScopeProcessor(new AndFilter (new ClassFilter(PsiClass.class), new ModifierFilter(PsiModifier.STATIC, false)), this, processor), + PsiSubstitutor.EMPTY, + null, + this + ); + } +// else{ +// throw new RuntimeException("Qualified new is not allowed for primitives"); +// } + } +// else{ +// throw new RuntimeException("Reference type is qualified new, but parent expression is: " + getParent()); +// } + + return; + default: + throw new RuntimeException("Unknown reference type"); + } + final FilterScopeProcessor proc = new FilterScopeProcessor(filter, this, processor); + PsiScopesUtil.resolveAndWalk(proc, this, null, true); + } + + public PsiElement getReferenceNameElement() { + return findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + } + + public PsiReferenceParameterList getParameterList() { + return (PsiReferenceParameterList)findChildByRoleAsPsiElement(ChildRole.REFERENCE_PARAMETER_LIST); + } + + public String getQualifiedName() { + switch(getKind()){ + case CLASS_NAME_KIND: + case CLASS_OR_PACKAGE_NAME_KIND: + case CLASS_IN_QUALIFIED_NEW_KIND: + { + final PsiElement target = resolve(); + if (target instanceof PsiClass){ + final PsiClass aClass = (PsiClass)target; + String name = aClass.getQualifiedName(); + if (name == null){ + name = aClass.getName(); //? + } + return name; + } + else if (target instanceof PsiPackage){ + return ((PsiPackage)target).getQualifiedName(); + } + else{ + LOG.assertTrue(target == null); + return getClassNameText(); + } + } + + case PACKAGE_NAME_KIND: + case CLASS_FQ_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + return getTextSkipWhiteSpaceAndComments(); // there cannot be any <...> + + default: + LOG.assertTrue(false); + return null; + } + + } + + public String getReferenceName() { + final TreeElement childByRole = findChildByRole(ChildRole.REFERENCE_NAME); + if (childByRole == null) return null; + return childByRole.getText(); + } + + public final TextRange getRangeInElement() { + final TreeElement nameChild = findChildByRole(ChildRole.REFERENCE_NAME); + if (nameChild == null) return new TextRange(0, getTextLength()); + final int startOffset = nameChild.getStartOffsetInParent(); + return new TextRange(startOffset, startOffset + nameChild.getTextLength()); + } + + public PsiType[] getTypeParameters() { + final PsiReferenceParameterList parameterList = getParameterList(); + if (parameterList == null) return PsiType.EMPTY_ARRAY; + return parameterList.getTypeArguments(); + + } + + public final PsiElement getElement() { + return this; + } + + public final void accept(final PsiElementVisitor visitor) { + visitor.visitReferenceElement(this); + } + + public final String toString() { + return "PsiJavaCodeReferenceElement:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java new file mode 100644 index 00000000000..588487082b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java @@ -0,0 +1,438 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.resolve.ClassResolverProcessor; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; + +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJavaFile { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiJavaFileBaseImpl"); + private static final Key CACHED_CLASSES_MAP_KEY = Key.create("PsiJavaFileBaseImpl.CACHED_CLASSES_MAP_KEY"); + + private PsiImportListImpl myRepositoryImportList = null; + private String myCachedPackageName = null; + protected PsiClass[] myCachedClasses = null; + private final Map myGuessCache = ResolveCache.getOrCreateWeakMap(myManager, CACHED_CLASSES_MAP_KEY, false); + + private static final String[] IMPLICIT_IMPORTS = new String[]{ "java.lang" }; + + protected PsiJavaFileBaseImpl(PsiManagerImpl manager, + IElementType elementType, + IElementType contentElementType, + String name, + char[] text, + int startOffset, + int endOffset) { + super(manager, elementType, contentElementType, name, text, startOffset, endOffset); + } + + protected PsiJavaFileBaseImpl(PsiManagerImpl manager, IElementType elementType, IElementType contentElementType, VirtualFile file) { + super(manager, elementType, contentElementType, file); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedPackageName = null; + myCachedClasses = null; + } + + protected PsiJavaFileBaseImpl clone() { + PsiJavaFileBaseImpl clone = (PsiJavaFileBaseImpl)super.clone(); + clone.myRepositoryImportList = null; + clone.myCachedClasses = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0){ + if (myRepositoryImportList != null){ + myRepositoryImportList.setOwner(this); + myRepositoryImportList = null; + } + } + else{ + myRepositoryImportList = (PsiImportListImpl)bindSlave(ChildRole.IMPORT_LIST); + } + } + + public PsiClass[] getClasses() { + if (myCachedClasses == null){ + if (getTreeElement() != null || getRepositoryId() < 0){ + LOG.debug("Loading tree for " + getName()); + myCachedClasses = (PsiClass[])calcTreeElement().getChildrenAsPsiElements(CLASS_BIT_SET, PSI_CLASS_ARRAY_CONSTRUCTOR); + } + else{ + long[] classIds = getRepositoryManager().getFileView().getClasses(getRepositoryId()); + PsiClass[] classes = classIds.length > 0 ? new PsiClass[classIds.length] : PsiClass.EMPTY_ARRAY; + for(int i = 0; i < classIds.length; i++){ + long id = classIds[i]; + classes[i] = (PsiClass)getRepositoryElementsManager().findOrCreatePsiElementById(id); + } + myCachedClasses = classes; + } + } + return myCachedClasses; + } + + public PsiPackageStatement getPackageStatement() { + return (PsiPackageStatement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.PACKAGE_STATEMENT); + } + + public String getPackageName(){ + if (myCachedPackageName == null){ + if (getTreeElement() != null || getRepositoryId() < 0){ + PsiPackageStatement statement = getPackageStatement(); + if (statement == null){ + myCachedPackageName = ""; + } + else{ + myCachedPackageName = statement.getPackageName(); + } + } + else{ + myCachedPackageName = getRepositoryManager().getFileView().getPackageName(getRepositoryId()); + } + } + return myCachedPackageName; + } + + public PsiImportList getImportList() { + if (getRepositoryId() >= 0){ + if (myRepositoryImportList == null){ + myRepositoryImportList = new PsiImportListImpl(myManager, this); + } + return myRepositoryImportList; + } + else{ + return (PsiImportList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.IMPORT_LIST); + } + } + + public PsiElement[] getOnDemandImports(boolean includeImplicit, boolean checkIncludes) { + List array = new ArrayList(); + + PsiImportList importList = getImportList(); + PsiImportStatement[] statements = importList.getImportStatements(); + for(int i = 0; i < statements.length; i++) { + PsiImportStatement statement = statements[i]; + if (statement.isOnDemand()){ + PsiElement resolved = statement.resolve(); + if (resolved != null){ + array.add(resolved); + } + } + } + + if (includeImplicit){ + PsiJavaCodeReferenceElement[] implicitRefs = getImplicitlyImportedPackageReferences(); + for(int i = 0; i < implicitRefs.length; i++){ + final PsiElement resolved = implicitRefs[i].resolve(); + if (resolved != null) { + array.add(resolved); + } + } + } + + return array.toArray(new PsiElement[array.size()]); + } + + public PsiClass[] getSingleClassImports(boolean checkIncludes) { + List array = new ArrayList(); + PsiImportList importList = getImportList(); + PsiImportStatement[] statements = importList.getImportStatements(); + for(int i = 0; i < statements.length; i++) { + PsiImportStatement statement = statements[i]; + if (!statement.isOnDemand()){ + PsiElement ref = statement.resolve(); + if (ref instanceof PsiClass){ + array.add((PsiClass)ref); + } + } + } + return array.toArray(new PsiClass[array.size()]); + } + + public PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass) { + PsiImportList importList = getImportList(); + PsiImportStatement[] statements = importList.getImportStatements(); + for(int i = 0; i < statements.length; i++) { + PsiImportStatement statement = statements[i]; + if (!statement.isOnDemand()){ + PsiElement ref = statement.resolve(); + if (ref != null && getManager().areElementsEquivalent(ref, aClass)){ + return statement.getImportReference(); + } + } + } + return null; + } + + public String[] getImplicitlyImportedPackages() { + return IMPLICIT_IMPORTS; + } + + public PsiJavaCodeReferenceElement[] getImplicitlyImportedPackageReferences() { + return PsiImplUtil.namesToPackageReferences(myManager, IMPLICIT_IMPORTS); + } + + public boolean canContainJavaCode() { + return true; + } + + public static class StaticImportFilteringProcessor implements PsiScopeProcessor { + private final PsiScopeProcessor myDelegate; + private String myNameToFilter; + private boolean myIsProcessingOnDemand; + private HashSet myHiddenNames = new HashSet(); + + public StaticImportFilteringProcessor(PsiScopeProcessor delegate, String nameToFilter) { + myDelegate = delegate; + myNameToFilter = nameToFilter; + } + + public void setNameToFilter(String nameToFilter) { + myNameToFilter = nameToFilter; + } + + public T getHint(Class hintClass) { + return myDelegate.getHint(hintClass); + } + + public void handleEvent(Event event, Object associated) { + if (Event.SET_CURRENT_FILE_CONTEXT.equals(event)) { + if (associated instanceof PsiImportStaticStatement) { + final PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement)associated; + if (importStaticStatement.isOnDemand()) { + myIsProcessingOnDemand = true; + } + else { + myIsProcessingOnDemand = false; + myHiddenNames.add(importStaticStatement.getReferenceName()); + } + } + else { + myIsProcessingOnDemand = false; + } + } + + myDelegate.handleEvent(event, associated); + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiModifierListOwner && ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { + if (myNameToFilter != null && + (!(element instanceof PsiNamedElement) || !myNameToFilter.equals(((PsiNamedElement)element).getName()))) { + return true; + } + if (element instanceof PsiNamedElement && myIsProcessingOnDemand) { + final String name = ((PsiNamedElement)element).getName(); + if (myHiddenNames.contains(name)) return true; + } + return myDelegate.execute(element, substitutor); + } + else { + return true; + } + } + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + if(!processDeclarationsNoGuess(processor, substitutor, lastParent, place)){ + if(processor instanceof ClassResolverProcessor){ + final ClassResolverProcessor hint = (ClassResolverProcessor)processor; + if(isPhysical()){ + setGuess(hint.getName(), hint.getResult()); + } + } + return false; + } + return true; + } + + private boolean processDeclarationsNoGuess(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + final ElementClassHint classHint = processor.getHint(ElementClassHint.class); + final NameHint nameHint = processor.getHint(NameHint.class); + final String name = nameHint != null ? nameHint.getName() : null; + if (classHint == null || classHint.shouldProcess(PsiClass.class)){ + if(processor instanceof ClassResolverProcessor){ + // Some speedup + final ResolveResult[] guessClass = getGuess(name); + if(guessClass != null){ + ((ClassResolverProcessor) processor).forceResult(guessClass); + return false; + } + } + + final PsiClass[] classes = getClasses(); + for(int i = 0; i < classes.length; i++){ + PsiClass aClass = classes[i]; + if (!processor.execute(aClass, substitutor)) return false; + } + + PsiImportList importList = getImportList(); + PsiImportStatement[] importStatements = importList.getImportStatements(); + + //Single-type processing + for(int i1 = 0; i1 < importStatements.length; i1++) { + PsiImportStatement statement = importStatements[i1]; + if (!statement.isOnDemand()){ + if (nameHint != null) { + String refText = statement.getQualifiedName(); + if (refText == null || !refText.endsWith(name)) continue; + } + + PsiElement resolved = statement.resolve(); + if (resolved instanceof PsiClass){ + processor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, statement); + if (!processor.execute(resolved, substitutor)) return false; + } + } + } + processor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, null); + + { + // check in current package + String packageName = getPackageName(); + PsiPackage aPackage = myManager.findPackage(packageName); + if (aPackage != null){ + if(!PsiScopesUtil.processScope(aPackage, processor, substitutor, null, place)) + return false; + } + } + + //On demand processing + for (int i = 0; i < importStatements.length; i++) { + PsiImportStatement statement = importStatements[i]; + if (statement.isOnDemand()) { + PsiElement resolved = statement.resolve(); + if (resolved != null) { + processor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, statement); + processOnDemandTarget(resolved, processor, substitutor, place); + } + } + } + processor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, null); + + PsiJavaCodeReferenceElement[] implicitlyImported = getImplicitlyImportedPackageReferences(); + for (int i = 0; i < implicitlyImported.length; i++) { + PsiElement resolved = implicitlyImported[i].resolve(); + if (resolved != null) { + processOnDemandTarget(resolved, processor, substitutor, place); + } + } + } + + if(classHint == null || classHint.shouldProcess(PsiPackage.class)){ + final PsiPackage rootPackage = getManager().findPackage(""); + if(rootPackage != null) rootPackage.processDeclarations(processor, substitutor, null, place); + } + + + // todo[dsl] class processing + final PsiImportList importList = getImportList(); + if (importList != null) { + final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); + if (importStaticStatements.length > 0) { + final StaticImportFilteringProcessor staticImportProcessor = new StaticImportFilteringProcessor(processor, null); + + // single member processing + for (int i = 0; i < importStaticStatements.length; i++) { + PsiImportStaticStatement importStaticStatement = importStaticStatements[i]; + if (!importStaticStatement.isOnDemand()) { + final String referenceName = importStaticStatement.getReferenceName(); + final PsiClass targetElement = importStaticStatement.resolveTargetClass(); + if (targetElement != null) { + staticImportProcessor.setNameToFilter(referenceName); + staticImportProcessor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, importStaticStatement); + final boolean result = targetElement.processDeclarations(staticImportProcessor, substitutor, lastParent, place); + if (!result) return false; + } + } + } + + // on-demand processing + for (int i = 0; i < importStaticStatements.length; i++) { + PsiImportStaticStatement importStaticStatement = importStaticStatements[i]; + if (importStaticStatement.isOnDemand()) { + final PsiClass targetElement = importStaticStatement.resolveTargetClass(); + if (targetElement != null) { + staticImportProcessor.setNameToFilter(null); + staticImportProcessor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, importStaticStatement); + staticImportProcessor.handleEvent(PsiScopeProcessor.Event.BEGIN_GROUP, null); + final boolean result = targetElement.processDeclarations(staticImportProcessor, substitutor, lastParent, place); + staticImportProcessor.handleEvent(PsiScopeProcessor.Event.END_GROUP, null); + if (!result) return false; + } + } + } + + staticImportProcessor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, null); + } + } + + return true; + } + + private static boolean processOnDemandTarget (PsiElement target, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement place) { + if (target instanceof PsiPackage) { + processor.handleEvent(PsiScopeProcessor.Event.BEGIN_GROUP, null); + if (!PsiScopesUtil.processScope(target, processor, substitutor, null, place)) { + return false; + } + processor.handleEvent(PsiScopeProcessor.Event.END_GROUP, null); + } + else if (target instanceof PsiClass) { + PsiClass[] inners = ((PsiClass)target).getInnerClasses(); + for (int j = 0; j < inners.length; j++) { + PsiClass inner = inners[j]; + if (!processor.execute(inner, substitutor)) return false; + } + } + else { + LOG.assertTrue(false); + } + return true; + } + + private ResolveResult[] getGuess(final String name){ + final Map guessForFile = (Map) myGuessCache.get(this); + final Reference ref = guessForFile != null ? (Reference)guessForFile.get(name) : null; + + return ref != null ? (ResolveResult[])ref.get() : null; + } + + private void setGuess(final String name, final ResolveResult[] cached){ + Map> guessForFile = (Map>) myGuessCache.get(this); + if(guessForFile == null){ + guessForFile = new HashMap>(); + myGuessCache.put(this, guessForFile); + } + guessForFile.put(name, new SoftReference(cached)); + } + + + public void accept(PsiElementVisitor visitor){ + visitor.visitJavaFile(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileImpl.java new file mode 100644 index 00000000000..a90a6c9b404 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiJavaFileImpl.java @@ -0,0 +1,32 @@ +package com.intellij.psi.impl.source; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; + +public class PsiJavaFileImpl extends PsiJavaFileBaseImpl { + public PsiJavaFileImpl(PsiManagerImpl manager, VirtualFile file) { + super(manager, JAVA_FILE, JAVA_FILE_TEXT, file); + } + + public PsiJavaFileImpl(PsiManagerImpl manager, String name, char[] text, int startOffset, int endOffset) { + super(manager, JAVA_FILE, JAVA_FILE_TEXT, name, text, startOffset, endOffset); + } + + public String toString(){ + return "PsiJavaFile:" + getName(); + } + + public Lexer createLexer() { + final PsiManager manager = getManager(); + return new JavaLexer(manager.getEffectiveLanguageLevel()); + } + + public FileType getFileType() { + return StdFileTypes.JAVA; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiLabelReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiLabelReference.java new file mode 100644 index 00000000000..6c8b8fbbd9c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiLabelReference.java @@ -0,0 +1,87 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 06.05.2003 + * Time: 23:32:45 + * To change this template use Options | File Templates. + */ +public class PsiLabelReference implements PsiReference{ + private final PsiStatement myStatement; + private PsiIdentifier myIdentifier; + + public PsiLabelReference(PsiStatement stat, PsiIdentifier identifier){ + myStatement = stat; + myIdentifier = identifier; + } + + public PsiElement getElement(){ + return myStatement; + } + + public TextRange getRangeInElement(){ + final int parent = myIdentifier.getStartOffsetInParent(); + return new TextRange(parent, myIdentifier.getTextLength() + parent); + } + + public PsiElement resolve(){ + final String label = myIdentifier.getText(); + if(label == null) return null; + PsiElement context = myStatement; + while(context != null){ + if(context instanceof PsiLabeledStatement){ + final PsiLabeledStatement statement = (PsiLabeledStatement) context; + if(label.equals(statement.getName())) + return statement; + } + context = context.getContext(); + } + return null; + } + + public String getCanonicalText(){ + return getElement().getText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException{ + myIdentifier = (PsiIdentifier) SharedPsiElementImplUtil.setName(myIdentifier, newElementName); + return myIdentifier; + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException{ + if(element instanceof PsiLabeledStatement){ + myIdentifier = (PsiIdentifier) SharedPsiElementImplUtil.setName(myIdentifier, ((PsiLabeledStatement)element).getName()); + return myIdentifier; + } + throw new IncorrectOperationException("Can't bind not to labeled statement"); + } + + public boolean isReferenceTo(PsiElement element){ + return resolve() == element; + } + + public Object[] getVariants(){ + final List result = new ArrayList(); + PsiElement context = myStatement; + while(context != null){ + if(context instanceof PsiLabeledStatement){ + result.add(context); + } + context = context.getContext(); + } + return result.toArray(); + } + + public boolean isSoft(){ + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiMethodImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiMethodImpl.java new file mode 100644 index 00000000000..3e0f950c4cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiMethodImpl.java @@ -0,0 +1,364 @@ +package com.intellij.psi.impl.source; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.PomMethod; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiSuperMethodImplUtil; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.cache.MethodView; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.java.PsiTypeParameterListImpl; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; + +public class PsiMethodImpl extends NonSlaveRepositoryPsiElement implements PsiMethod { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiMethodImpl"); + + private PsiModifierListImpl myRepositoryModifierList = null; + private PsiParameterListImpl myRepositoryParameterList = null; + private PsiReferenceListImpl myRepositoryThrowsList = null; + private PsiTypeParameterListImpl myRepositoryTypeParameterList; + + private String myCachedName = null; + private Boolean myCachedIsDeprecated = null; + private Boolean myCachedIsConstructor = null; + private Boolean myCachedIsVarargs = null; + private String myCachedTypeText = null; + + public PsiMethodImpl(PsiManagerImpl manager, long repositoryId) { + super(manager, repositoryId); + } + + public PsiMethodImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedTypeText = null; + myCachedName = null; + myCachedIsDeprecated = null; + myCachedIsConstructor = null; + myCachedIsVarargs = null; + } + + protected Object clone() { + PsiMethodImpl clone = (PsiMethodImpl)super.clone(); + clone.myRepositoryModifierList = null; + clone.myRepositoryParameterList = null; + clone.myRepositoryTypeParameterList = null; + clone.myRepositoryThrowsList = null; + return clone; + } + + public void setRepositoryId(long repositoryId) { + super.setRepositoryId(repositoryId); + + if (repositoryId < 0){ + if (myRepositoryModifierList != null){ + myRepositoryModifierList.setOwner(this); + myRepositoryModifierList = null; + } + if (myRepositoryParameterList != null){ + myRepositoryParameterList.setOwner(this); + myRepositoryParameterList = null; + } + if (myRepositoryTypeParameterList != null){ + myRepositoryTypeParameterList.setOwner(this); + myRepositoryTypeParameterList = null; + } + if (myRepositoryThrowsList != null){ + myRepositoryThrowsList.setOwner(this); + myRepositoryThrowsList = null; + } + } + else{ + myRepositoryModifierList = (PsiModifierListImpl)bindSlave(ChildRole.MODIFIER_LIST); + myRepositoryParameterList = (PsiParameterListImpl)bindSlave(ChildRole.PARAMETER_LIST); + myRepositoryTypeParameterList = (PsiTypeParameterListImpl) bindSlave(ChildRole.TYPE_PARAMETER_LIST); + myRepositoryThrowsList = (PsiReferenceListImpl)bindSlave(ChildRole.THROWS_LIST); + } + } + + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? (PsiClass)parent : null; + } + + public PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public PsiMethod[] findSuperMethods() { + return PsiSuperMethodImplUtil.findSuperMethods(this); + } + + public PsiMethod[] findSuperMethods(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); + } + + public PsiMethod[] findSuperMethods(PsiClass parentClass) { + return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); + } + + public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); + } + + public PsiMethod findConstructorInSuper() { + return PsiSuperMethodImplUtil.findConstructorInSuper(this); + } + + public PsiMethod findDeepestSuperMethod() { + return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); + } + + public PomMethod getPom() { + //TODO: + return null; + } + + public String getName() { + if (myCachedName == null){ + if (getTreeElement() != null){ + myCachedName = getNameIdentifier().getText(); + } + else{ + myCachedName = getRepositoryManager().getMethodView().getName(getRepositoryId()); + } + } + return myCachedName; + } + + public PsiElement setName(String name) throws IncorrectOperationException{ + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiTypeElement getReturnTypeElement() { + if (myCachedIsConstructor == Boolean.TRUE) return null; + return (PsiTypeElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public PsiTypeParameterList getTypeParameterList() { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0){ + if (myRepositoryTypeParameterList == null){ + myRepositoryTypeParameterList = new PsiTypeParameterListImpl(myManager, this); + } + return myRepositoryTypeParameterList; + } + + return (PsiTypeParameterList) calcTreeElement().findChildByRoleAsPsiElement(ChildRole.TYPE_PARAMETER_LIST); + } + + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); + } + + public PsiType getReturnType() { + if (myCachedIsConstructor == Boolean.TRUE) return null; + + if (getTreeElement() != null){ + PsiTypeElement typeElement = getReturnTypeElement(); + if (typeElement == null) return null; + + int arrayCount = 0; + TreeElement parameterList = SourceTreeToPsiMap.psiElementToTree(getParameterList()); + Loop: + for(TreeElement child = parameterList.getTreeNext(); child != null; child = child.getTreeNext()){ + IElementType i = child.getElementType(); + if (i == LBRACKET) { + arrayCount++; + } + else if (i == RBRACKET || i == WHITE_SPACE || i == C_STYLE_COMMENT || i == DOC_COMMENT || i == END_OF_LINE_COMMENT) { + } + else { + break Loop; + } + } + + PsiType type; + if (!(typeElement instanceof PsiTypeElementImpl)) { + type = typeElement.getType(); + } + else { + type = ((PsiTypeElementImpl)typeElement).getDetachedType(this); + } + + for (int i = 0; i < arrayCount; i++) { + type = type.createArrayType(); + } + + return type; + } + else{ + myCachedTypeText = getRepositoryManager().getMethodView().getReturnTypeText(getRepositoryId()); + if (myCachedTypeText == null) return null; + try{ + return getManager().getElementFactory().createTypeFromText(myCachedTypeText, this); + } + catch(IncorrectOperationException e){ + LOG.error(e); + return null; + } + } + } + + public PsiModifierList getModifierList() { + if (getRepositoryId() >= 0){ + if (myRepositoryModifierList == null){ + myRepositoryModifierList = new PsiModifierListImpl(myManager, this); + } + return myRepositoryModifierList; + } + else{ + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiParameterList getParameterList() { + if (getRepositoryId() >= 0){ + if (myRepositoryParameterList == null){ + myRepositoryParameterList = new PsiParameterListImpl(myManager, this); + } + return myRepositoryParameterList; + } + else{ + return (PsiParameterList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.PARAMETER_LIST); + } + } + + public PsiReferenceList getThrowsList() { + if (getRepositoryId() >= 0){ + if (myRepositoryThrowsList == null){ + myRepositoryThrowsList = new PsiReferenceListImpl(myManager, this, ElementType.THROWS_LIST); + } + return myRepositoryThrowsList; + } + else{ + final CompositeElement compositeElement = calcTreeElement(); + return (PsiReferenceList)compositeElement.findChildByRoleAsPsiElement(ChildRole.THROWS_LIST); + } + } + + public PsiCodeBlock getBody() { + return (PsiCodeBlock)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.METHOD_BODY); + } + + public boolean isDeprecated() { + if (myCachedIsDeprecated == null){ + boolean deprecated; + if (getTreeElement() != null){ + PsiDocComment docComment = getDocComment(); + deprecated = docComment != null && getDocComment().findTagByName("deprecated") != null; + if (!deprecated) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + else{ + MethodView methodView = getRepositoryManager().getMethodView(); + deprecated = methodView.isDeprecated(getRepositoryId()); + if (!deprecated && methodView.mayBeDeprecatedByAnnotation(getRepositoryId())) { + deprecated = getModifierList().findAnnotation("java.lang.Deprecated") != null; + } + } + myCachedIsDeprecated = deprecated ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsDeprecated.booleanValue(); + } + + public PsiDocComment getDocComment() { + return (PsiDocComment)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); + } + + public boolean isConstructor() { + if (myCachedIsConstructor == null){ + boolean isConstructor; + if (getTreeElement() != null){ + isConstructor = calcTreeElement().findChildByRole(ChildRole.TYPE) == null; + } + else{ + isConstructor = getRepositoryManager().getMethodView().isConstructor(getRepositoryId()); + } + myCachedIsConstructor = isConstructor ? Boolean.TRUE : Boolean.FALSE; + } + return myCachedIsConstructor.booleanValue(); + } + + public boolean isVarArgs() { + if (myCachedIsVarargs == null) { + boolean isVarArgs = false; + if (getTreeElement() != null) { + PsiParameter[] parameters = getParameterList().getParameters(); + for (int i = parameters.length - 1; i >= 0; i--) { + if (parameters[i].isVarArgs()) { + isVarArgs = true; + break; + } + } + } + else { + isVarArgs = getRepositoryManager().getMethodView().isVarArgs(getRepositoryId()); + } + + myCachedIsVarargs = isVarArgs ? Boolean.TRUE : Boolean.FALSE; + } + + return myCachedIsVarargs.booleanValue(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitMethod(this); + } + + public String toString() { + return "PsiMethod:" + getName(); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + return PsiImplUtil.processDeclarationsInMethod(this, processor, substitutor, lastParent, place); + + } + + public MethodSignature getSignature(PsiSubstitutor substitutor){ + return PsiImplUtil.getMethodSignature(this, substitutor); + } + + public void treeElementSubTreeChanged() { + myCachedTypeText = null; + myCachedName = null; + myCachedIsDeprecated = null; + myCachedIsConstructor = null; + myRepositoryThrowsList = null; + myRepositoryModifierList = null; + myRepositoryParameterList = null; + myRepositoryTypeParameterList = null; + super.treeElementSubTreeChanged(); + } + + public PsiElement getOriginalElement() { + PsiClass originalClass = (PsiClass)getContainingClass().getOriginalElement(); + final PsiMethod originalMethod = originalClass.findMethodBySignature(this, false); + return originalMethod != null ? originalMethod : this; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getMethodPresentation(this); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiModifierListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiModifierListImpl.java new file mode 100644 index 00000000000..cbdcb5d17a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiModifierListImpl.java @@ -0,0 +1,270 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.cache.DeclarationView; +import com.intellij.psi.impl.cache.ModifierFlags; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; +import gnu.trove.TObjectIntHashMap; + +import java.util.Map; + +public class PsiModifierListImpl extends SlaveRepositoryPsiElement implements PsiModifierList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiModifierListImpl"); + + private static Map NAME_TO_KEYWORD_TYPE_MAP = new HashMap(); + + static{ + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.PUBLIC, PUBLIC_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.PROTECTED, PROTECTED_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.PRIVATE, PRIVATE_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.STATIC, STATIC_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.ABSTRACT, ABSTRACT_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.FINAL, FINAL_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.NATIVE, NATIVE_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.SYNCHRONIZED, SYNCHRONIZED_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.STRICTFP, STRICTFP_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.TRANSIENT, TRANSIENT_KEYWORD); + NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.VOLATILE, VOLATILE_KEYWORD); + } + + private static TObjectIntHashMap NAME_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap(); + + static{ + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PUBLIC, ModifierFlags.PUBLIC_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PROTECTED, ModifierFlags.PROTECTED_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PRIVATE, ModifierFlags.PRIVATE_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PACKAGE_LOCAL, ModifierFlags.PACKAGE_LOCAL_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.STATIC, ModifierFlags.STATIC_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.ABSTRACT, ModifierFlags.ABSTRACT_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.FINAL, ModifierFlags.FINAL_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.NATIVE, ModifierFlags.NATIVE_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.SYNCHRONIZED, ModifierFlags.SYNCHRONIZED_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.STRICTFP, ModifierFlags.STRICTFP_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.TRANSIENT, ModifierFlags.TRANSIENT_MASK); + NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.VOLATILE, ModifierFlags.VOLATILE_MASK); + } + + private int myCachedModifiers = -1; + private PsiAnnotation[] myCachedAnnotations = null; + + public PsiModifierListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + public PsiModifierListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedModifiers = -1; + myCachedAnnotations = null; + } + + public boolean hasModifierProperty(String name){ + if (getTreeElement() != null){ + IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name); + + PsiElement parent = getParent(); + if (parent instanceof PsiClass){ + PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiClass && ((PsiClass)pparent).isInterface()){ + if (type == PUBLIC_KEYWORD){ + return true; + } + if (type == null){ // package local + return false; + } + if (type == STATIC_KEYWORD){ + return true; + } + } + if (((PsiClass)parent).isInterface()){ + if (type == ABSTRACT_KEYWORD){ + return true; + } + + // nested interface is implicitly static + if (pparent instanceof PsiClass) { + if (type == STATIC_KEYWORD){ + return true; + } + } + } + if (((PsiClass)parent).isEnum()){ + if (type == STATIC_KEYWORD) { + return true; + } + else if (type == FINAL_KEYWORD) { + final PsiField[] fields = ((PsiClass)parent).getFields(); + for (int i = 0; i < fields.length; i++) { + PsiField field = fields[i]; + if (field instanceof PsiEnumConstant && ((PsiEnumConstant)field).getInitializingClass() != null) return false; + } + return true; + } + else if (type == ABSTRACT_KEYWORD) { + final PsiMethod[] methods = ((PsiClass)parent).getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return true; + } + return false; + } + } + } + else if (parent instanceof PsiMethod){ + PsiClass aClass = ((PsiMethod)parent).getContainingClass(); + if (aClass != null && aClass.isInterface()){ + if (type == PUBLIC_KEYWORD){ + return true; + } + if (type == null){ // package local + return false; + } + if (type == ABSTRACT_KEYWORD){ + return true; + } + } + } + else if (parent instanceof PsiField){ + if (parent instanceof PsiEnumConstant) { + return type == PUBLIC_KEYWORD || type == STATIC_KEYWORD || type == FINAL_KEYWORD; + } + else { + PsiClass aClass = ((PsiField)parent).getContainingClass(); + if (aClass != null && aClass.isInterface()){ + if (type == PUBLIC_KEYWORD){ + return true; + } + if (type == null){ // package local + return false; + } + if (type == STATIC_KEYWORD){ + return true; + } + if (type == FINAL_KEYWORD){ + return true; + } + } + } + } + + if (type == null){ // package local + return !hasModifierProperty(PsiModifier.PUBLIC) && !hasModifierProperty(PsiModifier.PRIVATE) && !hasModifierProperty(PsiModifier.PROTECTED); + } + + CompositeElement treeElement = calcTreeElement(); + return TreeUtil.findChild(treeElement, type) != null; + } + else{ + long repositoryId = getRepositoryId(); + if (myCachedModifiers < 0){ + myCachedModifiers = ((DeclarationView)getRepositoryManager().getItemView(repositoryId)).getModifiers(repositoryId); + } + int flag = NAME_TO_MODIFIER_FLAG_MAP.get(name); + LOG.assertTrue(flag != 0); + return (myCachedModifiers & flag) != 0; + } + } + + public void setModifierProperty(String name, boolean value) throws IncorrectOperationException{ + checkSetModifierProperty(name, value); + + IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name); + + CompositeElement treeElement = calcTreeElement(); + CompositeElement parentTreeElement = treeElement.getTreeParent(); + if (value){ + if (parentTreeElement.getElementType() == ElementType.FIELD && parentTreeElement.getTreeParent().getElementType() == ElementType.CLASS && ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()){ + if (type == PUBLIC_KEYWORD || type == STATIC_KEYWORD || type == FINAL_KEYWORD) return; + } + else if (parentTreeElement.getElementType() == ElementType.METHOD && parentTreeElement.getTreeParent().getElementType() == ElementType.CLASS && ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()){ + if (type == PUBLIC_KEYWORD || type == ABSTRACT_KEYWORD) return; + } + else if (parentTreeElement.getElementType() == ElementType.CLASS && parentTreeElement.getTreeParent().getElementType() == ElementType.CLASS && ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()){ + if (type == PUBLIC_KEYWORD) return; + } + + if (type == PUBLIC_KEYWORD + || type == PRIVATE_KEYWORD + || type == PROTECTED_KEYWORD + || type == null /* package local */){ + + if (type != PUBLIC_KEYWORD){ + setModifierProperty(PsiModifier.PUBLIC, false); + } + if (type != PRIVATE_KEYWORD){ + setModifierProperty(PsiModifier.PRIVATE, false); + } + if (type != PROTECTED_KEYWORD){ + setModifierProperty(PsiModifier.PROTECTED, false); + } + if (type == null) return; + } + + if (TreeUtil.findChild(treeElement, type) == null){ + TreeElement keyword = Factory.createSingleLeafElement(type, name.toCharArray(), 0, name.length(), null, getManager()); + treeElement.addInternal(keyword, keyword, null, null); + } + if ((type == ABSTRACT_KEYWORD || type == NATIVE_KEYWORD) && parentTreeElement.getElementType() == METHOD){ + //Q: remove body? + } + } + else{ + if (type == null){ // package local + throw new IncorrectOperationException("Cannot reset package local modifier."); //? + } + TreeElement child = TreeUtil.findChild(treeElement, type); + if (child != null){ + SourceTreeToPsiMap.treeElementToPsi(child).delete(); + } + } + } + + public void checkSetModifierProperty(String name, boolean value) throws IncorrectOperationException{ + CheckUtil.checkWritable(this); + } + + public PsiAnnotation[] getAnnotations() { + if (myCachedAnnotations == null) { + if (getTreeElement() != null) { + myCachedAnnotations = (PsiAnnotation[])calcTreeElement().getChildrenAsPsiElements(ANNOTATION_BIT_SET, PSI_ANNOTATION_ARRAY_CONSTRUCTOR); + } + else { + long parentId = ((SrcRepositoryPsiElement)getParent()).getRepositoryId(); + DeclarationView view = (DeclarationView)getRepositoryManager().getItemView(parentId); + String[] annotationStrings = view.getAnnotations(parentId); + myCachedAnnotations = new PsiAnnotation[annotationStrings.length]; + for (int i = 0; i < annotationStrings.length; i++) { + try { + myCachedAnnotations[i] = getManager().getElementFactory().createAnnotationFromText(annotationStrings[i], this); + } + catch (IncorrectOperationException e) { + LOG.error("Bad annotation text in repository: " + annotationStrings[i]); + } + } + } + } + return myCachedAnnotations; + } + + public PsiAnnotation findAnnotation(String qualifiedName) { + return PsiImplUtil.findAnnotation(this, qualifiedName); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitModifierList(this); + } + + public String toString(){ + return "PsiModifierList:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterImpl.java new file mode 100644 index 00000000000..44ed1ac8bf3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterImpl.java @@ -0,0 +1,147 @@ +package com.intellij.psi.impl.source; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.util.IncorrectOperationException; + +public class PsiParameterImpl extends IndexedRepositoryPsiElement implements PsiParameter { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterImpl"); + + private String myCachedName = null; + private String myCachedTypeText = null; + + public PsiParameterImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiParameterImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, int index) { + super(manager, owner, index); + } + + public void subtreeChanged() { + super.subtreeChanged(); + myCachedName = null; + myCachedTypeText = null; + } + + protected Object clone() { + PsiParameterImpl clone = (PsiParameterImpl)super.clone(); + clone.myCachedTypeText = null; + clone.myCachedName = null; + return clone; + } + + public final String getName() { + if (myCachedName == null){ + if (getTreeElement() != null){ + myCachedName = getNameIdentifier().getText(); + } + else{ + myCachedName = getRepositoryManager().getMethodView().getParameterName(getRepositoryId(), getIndex()); + } + } + return myCachedName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public final PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public PsiType getType() { + if (getTreeElement() != null){ + return SharedImplUtil.getType(this); + } + else{ + myCachedTypeText = getRepositoryManager().getMethodView().getParameterTypeText(getRepositoryId(), getIndex()); + try{ + return getManager().getElementFactory().createTypeFromText(myCachedTypeText, this); + } + catch(IncorrectOperationException e){ + LOG.error(e); + return null; + } + } + } + + public PsiTypeElement getTypeElement() { + return (PsiTypeElement)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public PsiModifierList getModifierList() { + return (PsiModifierList)calcTreeElement().findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiExpression getInitializer() { + return null; + } + + public boolean hasInitializer() { + return false; + } + + public Object computeConstantValue() { + return null; + } + + public void normalizeDeclaration() throws IncorrectOperationException { + CheckUtil.checkWritable(this); + SharedImplUtil.normalizeBrackets(this); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitParameter(this); + } + + public String toString() { + return "PsiParameter:" + getName(); + } + + public PsiElement getDeclarationScope() { + final PsiElement parent = getParent(); + if (parent instanceof PsiParameterList){ + return parent.getParent(); + } + else if (parent instanceof PsiForeachStatement) { + return parent; + } + else if (parent instanceof PsiCatchSection) { + return parent.getParent(); + } + else{ + PsiElement[] children = parent.getChildren(); + for(int i = 0; i < children.length; i++){ + if (children[i].equals(this)){ + while(!(children[i] instanceof PsiCodeBlock)){ + i++; + } + return children[i]; + } + } + LOG.assertTrue(false); + return null; + } + } + + public boolean isVarArgs() { + return TreeUtil.findChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(getTypeElement()), ELLIPSIS) != null; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getVariablePresentation(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterListImpl.java new file mode 100644 index 00000000000..579479f7dff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiParameterListImpl.java @@ -0,0 +1,90 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; + +public class PsiParameterListImpl extends SlaveRepositoryPsiElement implements PsiParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterListImpl"); + + private PsiParameterImpl[] myRepositoryParameters = null; + + private static final PsiElementArrayConstructor PARAMETER_IMPL_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return new PsiParameterImpl[length]; + } + }; + + public PsiParameterListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiParameterListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + public Object clone() { + PsiParameterListImpl clone = (PsiParameterListImpl)super.clone(); + clone.myRepositoryParameters = null; + return clone; + } + + public void setOwner(SrcRepositoryPsiElement owner) { + super.setOwner(owner); + + if (myOwner == null){ + if (myRepositoryParameters != null){ + for(int i = 0; i < myRepositoryParameters.length; i++){ + PsiParameterImpl parm = myRepositoryParameters[i]; + parm.setOwnerAndIndex(this, i); + } + } + myRepositoryParameters = null; + } + else{ + myRepositoryParameters = (PsiParameterImpl[])bindIndexedSlaves(PARAMETER_BIT_SET, PARAMETER_IMPL_ARRAY_CONSTRUCTOR); + } + } + + public PsiParameter[] getParameters(){ + long repositoryId = getRepositoryId(); + if (repositoryId >= 0) { + synchronized (PsiLock.LOCK) { + if (myRepositoryParameters == null) { + int count; + CompositeElement treeElement = getTreeElement(); + if (treeElement != null) { + count = treeElement.countChildren(PARAMETER_BIT_SET); + } + else { + count = getRepositoryManager().getMethodView().getParameterCount(repositoryId); + } + myRepositoryParameters = new PsiParameterImpl[count]; + for (int i = 0; i < myRepositoryParameters.length; i++) { + myRepositoryParameters[i] = new PsiParameterImpl(myManager, this, i); + } + } + return myRepositoryParameters; + } + } + else{ + return (PsiParameter[])calcTreeElement().getChildrenAsPsiElements(PARAMETER_BIT_SET, PSI_PARAMETER_ARRAY_CONSTRUCTOR); + } + } + + public int getParameterIndex(PsiParameter parameter) { + LOG.assertTrue(parameter.getParent() == this); + return PsiImplUtil.getParameterIndex(parameter, this); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitParameterList(this); + } + + public String toString(){ + return "PsiParameterList:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiPlainTextFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiPlainTextFileImpl.java new file mode 100644 index 00000000000..2eb2680d85d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiPlainTextFileImpl.java @@ -0,0 +1,55 @@ +package com.intellij.psi.impl.source; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiPlainTextFile; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.uiDesigner.ReferenceUtil; + +public class PsiPlainTextFileImpl extends PsiFileImpl implements PsiPlainTextFile{ + private final FileType myFileType; + + public PsiPlainTextFileImpl(PsiManagerImpl manager, VirtualFile file) { + super(manager, PLAIN_TEXT_FILE, PLAIN_TEXT, file); + myFileType = FileTypeManager.getInstance().getFileTypeByFile(file); + } + + public PsiPlainTextFileImpl(PsiManagerImpl manager, + String name, + FileType fileType, + char[] text, + int startOffset, + int endOffset) { + super(manager, PLAIN_TEXT_FILE, PLAIN_TEXT, name, text, startOffset, endOffset); + myFileType = fileType; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitPlainTextFile(this); + } + + public String toString(){ + return "PsiFile(plain text):" + getName(); + } + + public FileType getFileType() { + return myFileType; + } + + public Lexer createLexer() { + return null; + } + + public PsiReference[] getReferences() { + if (myFileType.equals(StdFileTypes.GUI_DESIGNER_FORM)) { + return ReferenceUtil.getReferences(this); + } + return ResolveUtil.getReferencesFromProviders(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiReferenceListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiReferenceListImpl.java new file mode 100644 index 00000000000..a177f0ed876 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiReferenceListImpl.java @@ -0,0 +1,126 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.PatchedSoftReference; +import com.intellij.util.PatchedWeakReference; + +import java.lang.ref.Reference; + +public final class PsiReferenceListImpl extends SlaveRepositoryPsiElement implements PsiReferenceList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiReferenceListImpl"); + + private final IElementType myElementType; + + private Reference myRepositoryTypesRef = null; + + public PsiReferenceListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + myElementType = treeElement.getElementType(); + } + + public PsiReferenceListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, IElementType elementType) { + super(manager, owner); + myElementType = elementType; + } + + public IElementType getElementType() { + return myElementType; + } + + protected Object clone() { + PsiReferenceListImpl clone = (PsiReferenceListImpl)super.clone(); + clone.myRepositoryTypesRef = null; + return clone; + } + + public void subtreeChanged() { + super.subtreeChanged(); + myRepositoryTypesRef = null; + } + + public void setOwner(SrcRepositoryPsiElement owner) { + super.setOwner(owner); + myRepositoryTypesRef = null; + } + + private static final TokenSet REFERENCE_BIT_SET = TokenSet.create(new IElementType[]{JAVA_CODE_REFERENCE}); + + public PsiJavaCodeReferenceElement[] getReferenceElements() { + return (PsiJavaCodeReferenceElement[])calcTreeElement().getChildrenAsPsiElements(REFERENCE_BIT_SET, + PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiClassType[] getReferencedTypes() { + PsiClassType[] types; + synchronized (PsiLock.LOCK) { + types = (PsiClassType[])(myRepositoryTypesRef == null ? null : myRepositoryTypesRef.get()); + if (types == null) { + String[] refTexts; + CompositeElement treeElement = getTreeElement(); + final PsiElementFactory factory = getManager().getElementFactory(); + long repositoryId = getRepositoryId(); + if (treeElement == null && repositoryId > 0) { + RepositoryManager repositoryManager = getRepositoryManager(); + if (myElementType == ElementType.EXTENDS_LIST) { + refTexts = repositoryManager.getClassView().getExtendsList(repositoryId); + } + else if (myElementType == ElementType.IMPLEMENTS_LIST) { + refTexts = repositoryManager.getClassView().getImplementsList(repositoryId); + } + else if (myElementType == ElementType.THROWS_LIST) { + refTexts = repositoryManager.getMethodView().getThrowsList(repositoryId); + } + else { + LOG.error("Unknown element type:" + myElementType); + return null; + } + + types = new PsiClassType[refTexts.length]; + for (int i = 0; i < types.length; i++) { + final PsiElement parent = getParent(); + PsiElement context = this; + if (parent instanceof PsiClass) { + context = ((PsiClassImpl)parent).calcBasesResolveContext(PsiNameHelper.getShortClassName(refTexts[i])); + } + + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + final PsiJavaCodeReferenceElementImpl ref = (PsiJavaCodeReferenceElementImpl)Parsing.parseJavaCodeReferenceText(myManager, + refTexts[i].toCharArray(), + holderElement.getCharTable()); + TreeUtil.addChildren(holderElement, ref); + ref.setKindWhenDummy(PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND); + types[i] = factory.createType(ref); + } + } + else { + final PsiJavaCodeReferenceElement[] refs = getReferenceElements(); + types = new PsiClassType[refs.length]; + for (int i = 0; i < types.length; i++) { + types[i] = factory.createType(refs[i]); + } + } + + myRepositoryTypesRef = myManager.isBatchFilesProcessingMode() + ? new PatchedWeakReference(types) + : (Reference)new PatchedSoftReference(types); + } + ; + } + return types; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceList(this); + } + + public String toString() { + return "PsiReferenceList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeCodeFragmentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeCodeFragmentImpl.java new file mode 100644 index 00000000000..e21adfdfd7e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeCodeFragmentImpl.java @@ -0,0 +1,67 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.util.PsiUtil; + +/** + * @author dsl + */ +public class PsiTypeCodeFragmentImpl extends PsiCodeFragmentImpl implements PsiTypeCodeFragment { + private final boolean myAllowEllipsis; + + public PsiTypeCodeFragmentImpl(PsiManagerImpl manager, + boolean isPhysical, + boolean allowEllipsis, String name, + char[] text, + int startOffset, + int endOffset) { + super(manager, TYPE_TEXT, isPhysical, name, text, startOffset, endOffset); + myAllowEllipsis = allowEllipsis; + } + + public PsiType getType() + throws TypeSyntaxException, NoTypeException { + PsiType type; + class SyntaxError extends RuntimeException {} + try { + accept(new PsiRecursiveElementVisitor() { + public void visitErrorElement(PsiErrorElement element) { + throw new SyntaxError(); + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + }); + } + catch(SyntaxError e) { + throw new TypeSyntaxException(); + } + PsiElement child = getFirstChild(); + while (child != null && !(child instanceof PsiTypeElement)) { + child = child.getNextSibling(); + } + final PsiTypeElement typeElement1 = (PsiTypeElement)child; + PsiTypeElement typeElement = typeElement1; + if (typeElement == null) { + throw new NoTypeException(); + } + type = typeElement.getType(); + PsiElement sibling = typeElement.getNextSibling(); + while (sibling instanceof PsiWhiteSpace) { + sibling = sibling.getNextSibling(); + } + if (sibling instanceof PsiJavaToken && "...".equals(sibling.getText())) { + if (myAllowEllipsis) return new PsiEllipsisType(type); + else throw new TypeSyntaxException(); + } else { + return type; + } + } + + public boolean isVoidValid() { + return getUserData(PsiUtil.VALID_VOID_TYPE_IN_CODE_FRAGMENT) != null || + getOriginalFile() != null && getOriginalFile().getUserData(PsiUtil.VALID_VOID_TYPE_IN_CODE_FRAGMENT) != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeElementImpl.java new file mode 100644 index 00000000000..e12c4281bc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/PsiTypeElementImpl.java @@ -0,0 +1,120 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiTypeElementImpl"); + private PsiType myCachedType = null; + private PsiType myCachedDetachedType = null; + + public PsiTypeElementImpl() { + super(TYPE); + } + + public void clearCaches() { + super.clearCaches(); + myCachedType = null; + myCachedDetachedType = null; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitTypeElement(this); + } + + public String toString(){ + return "PsiTypeElement:" + getText(); + } + + public PsiType getType() { + if (myCachedType != null) return myCachedType; + + if (firstChild.getTreeNext() == null && PRIMITIVE_TYPE_BIT_SET.isInSet(firstChild.getElementType())) { + myCachedType = getManager().getElementFactory().createPrimitiveType(firstChild.getText()); + } + else if (firstChild.getElementType() == ElementType.TYPE) { + PsiType componentType = ((PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(firstChild)).getType(); + myCachedType = lastChild.getElementType() == ElementType.ELLIPSIS ? new PsiEllipsisType(componentType) : componentType.createArrayType(); + } + else if (firstChild.getElementType() == ElementType.JAVA_CODE_REFERENCE) { + myCachedType = new PsiClassReferenceType(getReferenceElement()); + } + else if (firstChild.getElementType() == ElementType.QUEST) { + PsiType temp = createWildcardType(); + myCachedType = temp; + } + + return myCachedType; + } + + public PsiType getDetachedType(PsiElement context) { + if (myCachedDetachedType != null) return myCachedDetachedType; + try { + myCachedDetachedType = getManager().getElementFactory().createTypeFromText(getText(), context); + } + catch (IncorrectOperationException e) { + return getType(); + } + return myCachedDetachedType; + } + + private PsiType createWildcardType() { + final PsiType temp; + if (firstChild.getTreeNext() == null) { + temp = PsiWildcardType.createUnbounded(getManager()); + } + else { + if (lastChild.getElementType() == TYPE) { + PsiTypeElement bound = (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(lastChild); + TreeElement keyword = firstChild; + while(keyword != null && (keyword.getElementType() != EXTENDS_KEYWORD && keyword.getElementType() != SUPER_KEYWORD)) { + keyword = keyword.getTreeNext(); + } + if (keyword != null) { + IElementType i = keyword.getElementType(); + if (i == EXTENDS_KEYWORD) { + temp = PsiWildcardType.createExtends(getManager(), bound.getType()); + } + else if (i == SUPER_KEYWORD) { + temp = PsiWildcardType.createSuper(getManager(), bound.getType()); + } + else { + LOG.assertTrue(false); + temp = PsiWildcardType.createUnbounded(getManager()); + } + } + else { + temp = PsiWildcardType.createUnbounded(getManager()); + } + } else { + temp = PsiWildcardType.createUnbounded(getManager()); + } + } + return temp; + } + + public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() { + if (firstChild.getElementType() == ElementType.TYPE) { + return ((PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(firstChild)).getInnermostComponentReferenceElement(); + } else { + return getReferenceElement(); + } + } + + private PsiJavaCodeReferenceElement getReferenceElement() { + if (firstChild.getElementType() != ElementType.JAVA_CODE_REFERENCE) return null; + return (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(firstChild); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + return true; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceJavaCodeReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceJavaCodeReference.java new file mode 100644 index 00000000000..416678e6724 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceJavaCodeReference.java @@ -0,0 +1,35 @@ +package com.intellij.psi.impl.source; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * This interface should be implemented by all PsiJavaCodeReference implementations + * in source. + * + * @author dsl + */ +public interface SourceJavaCodeReference { + /** + * @return text of class name (as much as there is in reference text, that is + * with qualifications if they are present) + */ + String getClassNameText(); + + /** + * Helper method for ReferenceAdjuster. Tries to qualify this reference as if + * it references targetClass. Does not check that it indeed references + * targetClass + * @param targetClass + */ + void fullyQualify(PsiClass targetClass); + + boolean isQualified(); + + TreeElement getTreeQualifier(); + PsiElement getQualifier(); + + void dequalify(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceTreeToPsiMap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceTreeToPsiMap.java new file mode 100644 index 00000000000..528c5e1fac7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/SourceTreeToPsiMap.java @@ -0,0 +1,50 @@ +package com.intellij.psi.impl.source; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.RepositoryElementsManager; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class SourceTreeToPsiMap { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.SourceTreeToPsiMap"); + + public static PsiElement treeElementToPsi(TreeElement element){ + ProgressManager.getInstance().checkCanceled(); + + if (element == null) return null; + + if (element instanceof PsiElement){ + return (PsiElement)element; + } + else if (element instanceof RepositoryTreeElement){ + return RepositoryElementsManager.getOrFindPsiElement((RepositoryTreeElement)element); + } + else{ + LOG.error("Not PsiElement:" + element); + return null; + } + } + + public static TreeElement psiElementToTree(PsiElement psiElement){ + ProgressManager.getInstance().checkCanceled(); + + if (psiElement == null) return null; + + if (psiElement instanceof TreeElement) { + return (TreeElement)psiElement; + } + else if (psiElement instanceof SrcRepositoryPsiElement){ + return RepositoryElementsManager.getOrFindTreeElement((SrcRepositoryPsiElement)psiElement); + } + else{ + LOG.error("Not TreeElement:" + psiElement); + return null; + } + } + + public static boolean hasTreeElement(PsiElement psiElement){ + return psiElement instanceof TreeElement || psiElement instanceof SrcRepositoryPsiElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/BraceEnforcer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/BraceEnforcer.java new file mode 100644 index 00000000000..18a5c1d2d8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/BraceEnforcer.java @@ -0,0 +1,94 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.util.IncorrectOperationException; + +/** + * @author max + */ +public class BraceEnforcer extends PsiRecursiveElementVisitor { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.BraceEnforcer"); + private CodeStyleSettings mySettings; + + public BraceEnforcer(CodeStyleSettings settings) { + mySettings = settings; + } + + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitIfStatement(PsiIfStatement statement) { + super.visitIfStatement(statement); + processStatement(statement, statement.getThenBranch(), mySettings.IF_BRACE_FORCE); + final PsiStatement elseBranch = statement.getElseBranch(); + if (!(elseBranch instanceof PsiIfStatement) || !mySettings.SPECIAL_ELSE_IF_TREATMENT) { + processStatement(statement, elseBranch, mySettings.IF_BRACE_FORCE); + } + } + + public void visitForStatement(PsiForStatement statement) { + super.visitForStatement(statement); + processStatement(statement, statement.getBody(), mySettings.FOR_BRACE_FORCE); + } + + public void visitForeachStatement(PsiForeachStatement statement) { + super.visitForeachStatement(statement); + processStatement(statement, statement.getBody(), mySettings.FOR_BRACE_FORCE); + } + + public void visitWhileStatement(PsiWhileStatement statement) { + super.visitWhileStatement(statement); + processStatement(statement, statement.getBody(), mySettings.WHILE_BRACE_FORCE); + } + + public void visitDoWhileStatement(PsiDoWhileStatement statement) { + super.visitDoWhileStatement(statement); + processStatement(statement, statement.getBody(), mySettings.DOWHILE_BRACE_FORCE); + } + + private void processStatement(PsiStatement statement, PsiStatement blockCandidate, int options) { + if (blockCandidate instanceof PsiBlockStatement || blockCandidate == null) return; + if (options == CodeStyleSettings.FORCE_BRACES_ALWAYS || + options == CodeStyleSettings.FORCE_BRACES_IF_MULTILINE && isMultiline(statement)) { + replaceWithBlock(statement, blockCandidate); + } + } + + private static void replaceWithBlock(PsiStatement statement, PsiStatement blockCandidate) { + final PsiElementFactory factory = statement.getManager().getElementFactory(); + String oldText = blockCandidate.getText(); + StringBuffer buf = new StringBuffer(oldText.length() + 3); + buf.append('{'); + buf.append(oldText); + buf.append("\n}"); + try { + CodeEditUtil.replaceChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(statement), + SourceTreeToPsiMap.psiElementToTree(blockCandidate), + SourceTreeToPsiMap.psiElementToTree(factory.createStatementFromText(buf.toString(), null))); + CodeStyleManager.getInstance(statement.getProject()).reformat(statement); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private static boolean isMultiline(PsiStatement statement) { + return statement.getText().indexOf('\n') > 0; + } + + public PsiElement process(PsiElement formatted) { + formatted.accept(this); + return formatted; + } + + public PsiElement process(PsiElement formatted, int startOffset, int endOffset) { + formatted.accept(this); + return formatted; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java new file mode 100644 index 00000000000..2d7f69d7db8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java @@ -0,0 +1,405 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.CharTable; +import com.intellij.util.containers.HashMap; + +public class CodeEditUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeEditUtil"); + + public static TreeElement addChild(CompositeElement parent, TreeElement child, TreeElement anchorBefore) { + return addChildren(parent, child, child, anchorBefore); + } + + public static TreeElement addChildren(CompositeElement parent, TreeElement first, TreeElement last, TreeElement anchorBefore) { + final Project project = parent.getManager().getProject(); + final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(parent).getContainingFile(); + FileType fileType = file.getFileType(); + + //??? + if (first.getElementType() == ElementType.WHITE_SPACE){ + if (first == last) return null; + first = first.getTreeNext(); + } + if (last.getElementType() == ElementType.WHITE_SPACE){ + if (first == last) return null; + last = last.getTreePrev(); + } + + boolean oneElement = first == last; + boolean adjustSelf = parent.getTreeParent() != null && parent.getTextLength() == 0; + + final Helper helper = new Helper(fileType, project); + final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + final CodeFormatterFacade codeLayouter = new CodeFormatterFacade(settings, helper); + final IndentAdjusterFacade indentAdjuster = new IndentAdjusterFacade(settings, helper); + final int oldIndent = helper.getIndent(first); + + TreeElement afterLast = last.getTreeNext(); + TreeElement next; + for(TreeElement child = first; child != afterLast; child = next){ + next = child.getTreeNext(); + ChangeUtil.addChild(parent, child, anchorBefore); + } + + if(fileType == StdFileTypes.XHTML) return first; + if (adjustSelf){ + TreeElement elementBefore = Helper.shiftBackwardToNonSpace(parent.getTreePrev()); + parent = (CompositeElement)codeLayouter.processSpace(elementBefore, parent); + parent = (CompositeElement)indentAdjuster.adjustFirstLineIndent(parent); + TreeElement elementAfter = Helper.shiftForwardToNonSpace(parent.getTreeNext()); + elementAfter = codeLayouter.processSpace(parent, elementAfter); + if (elementAfter != null){ + elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); + } + } + + TreeElement elementBefore = Helper.shiftBackwardToNonSpace(first.getTreePrev()); + if (needSeparateLines(first) && helper.getLineBreakCount(parent, elementBefore, first) == 0){ + helper.makeVerticalSpace(parent, elementBefore, first, 0); + } + first = codeLayouter.processSpace(elementBefore, first);// special mode? + + // restore old indent of the first line + TreeElement prev = Helper.shiftBackwardToNonSpace(first.getTreePrev()); + String spaceText = Helper.getSpaceText(parent, prev, first); + int index = Math.max(spaceText.lastIndexOf('\n'), spaceText.lastIndexOf('\r')); + if (index >= 0 + || (parent.getTreeParent() == null && prev == null && first.getTextRange().getStartOffset() == spaceText.length())){ + spaceText = spaceText.substring(0, index + 1) + helper.fillIndent(oldIndent); + first = helper.makeSpace(parent, prev, first, spaceText, false); + } + + if (oneElement){ + last = first; + } + + TreeElement elementAfter = Helper.shiftForwardToNonSpace(last.getTreeNext()); + if (elementAfter != null && needSeparateLines(last) && helper.getLineBreakCount(parent, last, elementAfter) == 0){ + helper.makeVerticalSpace(parent, last, elementAfter, 0); + } + elementAfter = codeLayouter.processSpace(last, elementAfter);// special mode? + if (elementAfter != null){ + elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); + } + + afterLast = last.getTreeNext(); + for(TreeElement child = first; child != afterLast; child = child.getTreeNext()){ + child = indentAdjuster.adjustNormalizeIndent(child); + if (child.getElementType() == ElementType.CODE_BLOCK){ + PsiElement[] children = SourceTreeToPsiMap.treeElementToPsi(child).getChildren(); + for(int i = 0; i < children.length; i++){ + PsiElement element = children[i]; + TreeElement child1 = SourceTreeToPsiMap.psiElementToTree(element); + if (Helper.isNonSpace(child1)){ + child1 = indentAdjuster.adjustIndent(child1); + } + } + } + } + + return first; + } + + public static void removeChild(CompositeElement parent, TreeElement child) { + removeChildren(parent, child, child); + } + + public static void removeChildren(CompositeElement parent, TreeElement first, TreeElement last) { + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(parent); + final PsiManager manager = parent.getManager(); + final Project project = manager.getProject(); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + + final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(parent).getContainingFile(); + FileType fileType = file.getFileType(); + Helper helper = new Helper(fileType, project); + CodeFormatterFacade codeLayouter = new CodeFormatterFacade(settings, helper); + IndentAdjusterFacade indentAdjuster = new IndentAdjusterFacade(settings, helper); + + TreeElement prev = first.getTreePrev(); + TreeElement next = last.getTreeNext(); + TreeElement prevNonSpace = Helper.shiftBackwardToNonSpace(prev); + TreeElement nextNonSpace = Helper.shiftForwardToNonSpace(next); + TreeElement spaceBefore = Helper.getSpaceElement(parent, prevNonSpace, first); + TreeElement spaceAfter = Helper.getSpaceElement(parent, last, nextNonSpace); + + TreeElement childNext; + for(TreeElement child = first; child != next; child = childNext){ + childNext = child.getTreeNext(); + ChangeUtil.removeChild(parent, child); + } + if(fileType == StdFileTypes.XHTML) return; + + if (prevNonSpace == null && nextNonSpace == null){ + if (spaceBefore != null){ + ChangeUtil.removeChild(parent, spaceBefore); + } + if (spaceAfter != null){ + ChangeUtil.removeChild(parent, spaceAfter); + } + LOG.assertTrue(parent.getTextLength() == 0); + TreeElement elementBefore = Helper.shiftBackwardToNonSpace(parent.getTreePrev()); + TreeElement elementAfter = Helper.shiftForwardToNonSpace(parent.getTreeNext()); + normalizeSpace(helper, parent.getTreeParent(), elementBefore, elementAfter, charTableByTree); + elementAfter = codeLayouter.processSpace(elementBefore, elementAfter); + if (elementAfter != null){ + elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); + } + return; + } + + int breaksBefore = spaceBefore != null ? StringUtil.getLineBreakCount(spaceBefore.getText()) : 0; + int breaksAfter = spaceAfter != null ? StringUtil.getLineBreakCount(spaceAfter.getText()) : 0; + + normalizeSpace(helper, parent, prevNonSpace, nextNonSpace, charTableByTree); + + int newBreaks = Math.max(breaksBefore, breaksAfter); + if (newBreaks != breaksBefore + breaksAfter){ + helper.makeLineBreaks(parent, prevNonSpace, nextNonSpace, newBreaks); + } + + nextNonSpace = codeLayouter.processSpace(prevNonSpace, nextNonSpace); + if (nextNonSpace != null){ + nextNonSpace = indentAdjuster.adjustFirstLineIndent(nextNonSpace); + } + } + + public static TreeElement replaceChild(CompositeElement parent, TreeElement oldChild, TreeElement newChild) { + final PsiManager manager = parent.getManager(); + final Project project = manager.getProject(); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(parent); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + //CodeFormatterFacade codeLayouter = new CodeFormatterFacade(settings, helper); + final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(parent).getContainingFile(); + FileType fileType = file.getFileType(); + + Helper helper = new Helper(fileType, project); + IndentAdjusterFacade indentAdjuster = new IndentAdjusterFacade(settings, helper); + + int oldIndent = helper.getIndent(newChild); + + ChangeUtil.replaceChild(parent, oldChild, newChild); + if(fileType == StdFileTypes.XHTML) return newChild; + + TreeElement prevNonSpace = Helper.shiftBackwardToNonSpace(newChild.getTreePrev()); + TreeElement nextNonSpace = Helper.shiftForwardToNonSpace(newChild.getTreeNext()); + + if (newChild instanceof CompositeElement && newChild.getTextLength() == 0){ + normalizeSpace(helper, parent, prevNonSpace, nextNonSpace, treeCharTab); + } + else{ + normalizeSpace(helper, parent, prevNonSpace, newChild, treeCharTab); // just to not allow sticking tokens + normalizeSpace(helper, parent, newChild, nextNonSpace, treeCharTab); // just to not allow sticking tokens + } + + // restore old indent of the first line + String newChildText = newChild.getText(); + boolean isMultiline = newChildText.indexOf('\n') >= 0 || newChildText.indexOf('\r') >= 0; + if (isMultiline){ + String spaceText = helper.getSpaceText(parent, prevNonSpace, newChild); + int index = Math.max(spaceText.lastIndexOf('\n'), spaceText.lastIndexOf('\r')); + if (index >= 0 + || (parent.getTreeParent() == null && prevNonSpace == null && newChild.getTextRange().getStartOffset() == spaceText.length()) + ){ + spaceText = spaceText.substring(0, index + 1) + helper.fillIndent(oldIndent); + newChild = helper.makeSpace(parent, prevNonSpace, newChild, spaceText, false); + //indentAdjuster.adjustIndent(newChild); + } + } + indentAdjuster.adjustNormalizeIndent(newChild); + + return newChild; + } + + public static void unindentSubtree(TreeElement clone, TreeElement original, CharTable table) { + PsiManager manager = original.getManager(); + LOG.assertTrue(manager != null, "Manager should present (?)"); + LOG.assertTrue(clone.getTreeParent().getElementType() == ElementType.DUMMY_HOLDER); + + final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(original).getContainingFile(); + FileType fileType = file.getFileType(); + Helper helper = new Helper(fileType, manager.getProject()); +/* + TreeElement prevWS = helper.getPrevWhitespace(original); + if( prevWS == null || prevWS.getText().indexOf('\n') < 0 ) return; +*/ + if( clone instanceof CompositeElement) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(manager.getProject()); + + int origIndent = helper.getIndent(original); + + helper.indentSubtree((CompositeElement) clone, origIndent, 0, table); + } + } + + public static TreeElement getDefaultAnchor(PsiImportList list, PsiImportStatementBase statement) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(list.getProject()); + ImportHelper importHelper = new ImportHelper(settings); + return importHelper.getDefaultAnchor(list, statement); + } + + private static final HashMap ourModifierToOrderMap = new HashMap(); + + static { //TODO : options? + ourModifierToOrderMap.put(PsiModifier.PUBLIC, new Integer(1)); + ourModifierToOrderMap.put(PsiModifier.PRIVATE, new Integer(1)); + ourModifierToOrderMap.put(PsiModifier.PROTECTED, new Integer(1)); + ourModifierToOrderMap.put(PsiModifier.NATIVE, new Integer(2)); + ourModifierToOrderMap.put(PsiModifier.STATIC, new Integer(3)); + ourModifierToOrderMap.put(PsiModifier.ABSTRACT, new Integer(3)); + ourModifierToOrderMap.put(PsiModifier.FINAL, new Integer(4)); + ourModifierToOrderMap.put(PsiModifier.SYNCHRONIZED, new Integer(5)); + ourModifierToOrderMap.put(PsiModifier.TRANSIENT, new Integer(5)); + ourModifierToOrderMap.put(PsiModifier.VOLATILE, new Integer(5)); + ourModifierToOrderMap.put(PsiModifier.STRICTFP, new Integer(6)); + } + + public static TreeElement getDefaultAnchor(PsiModifierList modifierList, PsiKeyword modifier) { + Integer order = (Integer)ourModifierToOrderMap.get(modifier.getText()); + if (order == null) return null; + for(TreeElement child = ((CompositeElement)SourceTreeToPsiMap.psiElementToTree(modifierList)).firstChild; + child != null; + child = child.getTreeNext()){ + if (ElementType.KEYWORD_BIT_SET.isInSet(child.getElementType())){ + Integer order1 = (Integer)ourModifierToOrderMap.get(child.getText()); + if (order1 == null) continue; + if (order1.intValue() > order.intValue()){ + return child; + } + } + } + return null; + } + + public static PsiElement getDefaultAnchor(PsiClass aClass, PsiMember member) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(aClass.getProject()); + + int order = getMemberOrderWeight(member, settings); + if (order < 0) return null; + + PsiElement lastMember = null; + for (PsiElement child = aClass.getFirstChild(); child != null; child = child.getNextSibling()) { + int order1 = getMemberOrderWeight(child, settings); + if (order1 < 0) continue; + if (order1 > order) { + if (lastMember != null) { + PsiElement nextSibling = lastMember.getNextSibling(); + while (nextSibling instanceof PsiJavaToken && + (nextSibling.getText().equals(",") || nextSibling.getText().equals(";"))) { + nextSibling = nextSibling.getNextSibling(); + } + return nextSibling == null ? aClass.getLBrace().getNextSibling() : nextSibling; + } + else { + return aClass.getLBrace().getNextSibling(); + } + } + lastMember = child; + } + return aClass.getRBrace(); + } + + private static int getMemberOrderWeight(PsiElement member, CodeStyleSettings settings) { + if (member instanceof PsiField){ + return member instanceof PsiEnumConstant ? 1 : settings.FIELDS_ORDER_WEIGHT + 1; + } + else if (member instanceof PsiMethod){ + return ((PsiMethod)member).isConstructor() ? settings.CONSTRUCTORS_ORDER_WEIGHT + 1: settings.METHODS_ORDER_WEIGHT + 1; + } + else if (member instanceof PsiClass){ + return settings.INNER_CLASSES_ORDER_WEIGHT + 1; + } + else{ + return -1; + } + } + + private static boolean needSeparateLines(TreeElement element) { + if (ElementType.STATEMENT_BIT_SET.isInSet(element.getElementType())){ + return true; + } + else if (element.getElementType() == ElementType.FIELD){ + return true; + } + else if (element.getElementType() == ElementType.METHOD){ + return true; + } + else if (element.getElementType() == ElementType.CLASS){ + return true; + } + else if (element.getElementType() == ElementType.CLASS_INITIALIZER){ + return true; + } + else{ + return false; + } + } + + /* + private static void normalizeSpaces(CompositeElement parent){ + Element child1 = parent.firstChild; + if (child1 == null) return; + while(true){ + Element child2; + for(child2 = child1.next; child2 != null; child2 = child2.next){ + if (child2.type == JavaTokenType.XML_WHITE_SPACE) continue; + if (child2 instanceof CompositeElement && ((CompositeElement)child2).firstChild == null) continue; + break; + } + if (child2 == null) break; + normalizeSpace(parent, child1, child2); + child1 = child2; + } + } + */ + + public static void normalizeSpace(Helper helper, CompositeElement parent, TreeElement child1, TreeElement child2, CharTable table) { + StringBuffer buffer = null; + int count = 0; + for(TreeElement child = child1 != null ? child1.getTreeNext() : parent.firstChild; child != child2; child = child.getTreeNext()){ + if (child instanceof CompositeElement && ((CompositeElement)child).firstChild == null) continue; + + if (Helper.isNonSpace(child)) { + LOG.error("Whitespace expected"); + } + if (buffer == null){ + buffer = new StringBuffer(); + } + buffer.append(child.getText()); + count++; + } + + if (count > 1){ + LeafElement newSpace = Factory.createSingleLeafElement(JavaTokenType.WHITE_SPACE, buffer.toString().toCharArray(), 0, buffer.length(), table, null); + count = 0; + TreeElement next; + for(TreeElement child = child1 != null ? child1.getTreeNext() : parent.firstChild; child != child2; child = next){ + next = child.getTreeNext(); + if (child instanceof CompositeElement && child.getTextLength() == 0) continue; + if (count == 0){ + ChangeUtil.replaceChild(parent, child, newSpace); + } + else{ + ChangeUtil.removeChild(parent, child); + } + count++; + } + } + + if (child1 != null && child2 != null && Helper.getSpaceText(parent, child1, child2).length() == 0){ + if (!helper.canStickChildrenTogether(child1, child2)){ + helper.makeSpace(parent, child1, child2, " "); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java new file mode 100644 index 00000000000..4e7fe8598d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -0,0 +1,233 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.codeFormatting.PseudoText; +import com.intellij.codeFormatting.PseudoTextBuilder; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.java.JavaCodeFormatter; +import com.intellij.psi.impl.source.codeStyle.javadoc.CommentFormatter; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * + */ +public class CodeFormatterFacade implements Constants { + private CodeStyleSettings mySettings; + private Helper myHelper; + private IndentAdjusterFacade myIndentAdjuster; + private CodeWrapperFacade myWrapper; + private CommentFormatter myCommentFormatter; + + private TreeElement child1; + private TreeElement child2; + private BraceEnforcer myBraceEnforcer; + private CodeFormatter myCodeFormatter = new JavaCodeFormatter(); + + public static int USE_NEW_CODE_FORMATTER = -1; + + public CodeFormatterFacade(CodeStyleSettings settings, Helper helper) { + if (USE_NEW_CODE_FORMATTER < 0) { + ApplicationEx application = ( (ApplicationEx)ApplicationManager.getApplication()); + boolean internal = application.isInternal(); + boolean unitTestMode = application.isUnitTestMode(); + USE_NEW_CODE_FORMATTER = (internal || unitTestMode) ? 1 : 0; + } + + mySettings = settings; + myHelper = helper; + myIndentAdjuster = new IndentAdjusterFacade(settings, helper); + myWrapper = new CodeWrapperFacade(settings, helper, myIndentAdjuster); + myBraceEnforcer = new BraceEnforcer(mySettings); + myCommentFormatter = new CommentFormatter(helper.getProject()); + } + + private void formatComments(TreeElement element, int startOffset, int endOffset) { + TextRange range = element.getTextRange(); + if (range.getStartOffset() >= startOffset && range.getEndOffset() <= endOffset) { + myCommentFormatter.process(element); + } + + if (element instanceof CompositeElement) { + for (TreeElement elem = ((CompositeElement)element).firstChild; elem != null; elem = elem.getTreeNext()) { + formatComments(elem, startOffset, endOffset); + } + } + } + + public TreeElement process(TreeElement element, int parent_indent) { + if (useNewFormatter(myHelper.getFileType())) { + TextRange range = element.getTextRange(); + int startOffset = range.getStartOffset(); + int endOffset = range.getEndOffset(); + + processRange(element, startOffset, endOffset); + return element; + } + + if (element instanceof CompositeElement) { + CompositeElement parent = (CompositeElement)element; + ChameleonTransforming.transformChildren(parent); + + child1 = null; + child2 = Helper.shiftForwardToNonSpace(parent.firstChild); + int indent = -1; + for (; child2 != null; child1 = child2, child2 = Helper.shiftForwardToNonSpace(child2.getTreeNext())) { + if (child1 != null || SourceTreeToPsiMap.treeElementToPsi(parent) instanceof PsiFile) { + child2 = myCodeFormatter.format(SourceTreeToPsiMap.treeElementToPsi(parent), child1, child2, mySettings, myHelper); + } + + if (indent < 0) { + indent = myIndentAdjuster.calculateIndent(child2, -1); + } + + if (child2 != null) { + child2 = myIndentAdjuster.adjustIndent(child2, indent); + } + } + + element = myWrapper.wrap(element); + element = myIndentAdjuster.adjustIndent(element, parent_indent); + myCommentFormatter.process(element); + + indent = -1; + for (TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()) { + if (indent < 0) indent = myIndentAdjuster.calculateIndent(child, -1); + child = process(child, indent); + } + } + return element; + } + + public TreeElement processRange(TreeElement element, int startOffset, int endOffset) { + FileType fileType = myHelper.getFileType(); + if (useNewFormatter(fileType)) { + PseudoTextBuilder pseudoTextBuilder = fileType.getPseudoTextBuilder(); + if (pseudoTextBuilder == null) { + return element; + } + else { + PseudoText pseudoText = pseudoTextBuilder.build(myHelper.getProject(), mySettings, SourceTreeToPsiMap.treeElementToPsi(element), + startOffset, endOffset); + GeneralCodeFormatter.createSimpleInstance(pseudoText, mySettings, fileType).format(); + formatComments(element, startOffset, endOffset); + return element; + } + } + + final TextRange range = element.getTextRange(); + final int elementStartOffset = range.getStartOffset(); + return processRange(element, new int[]{startOffset - elementStartOffset, endOffset - elementStartOffset}); + } + + private boolean useNewFormatter(FileType fileType) { + return (fileType == StdFileTypes.JAVA || fileType == StdFileTypes.XML || fileType == StdFileTypes.JSPX) && + USE_NEW_CODE_FORMATTER == 1; + } + + private TreeElement processRange(TreeElement element, int[] bounds) { + if (element instanceof CompositeElement) { + CompositeElement parent = (CompositeElement)element; + ChameleonTransforming.transformChildren(parent); + + child1 = null; + child2 = Helper.shiftForwardToNonSpace(parent.firstChild); + int child1Offset = 0; + int child2Offset; + for (; + child2 != null; + child1 = child2, child2 = Helper.shiftForwardToNonSpace(child2.getTreeNext()), child1Offset = child2Offset) { + int length1 = child1 != null ? child1.getTextLength() : 0; + int length2 = child2.getTextLength(); + child2Offset = child1Offset + length1; + for (TreeElement child = child1 != null ? child1.getTreeNext() : parent.firstChild; + child != child2; + child = child.getTreeNext()) { + child2Offset += child.getTextLength(); + } + //Diagnostic.assertTrue(child2Offset == child2.getStartOffsetInParent()); + int offset1 = child1 != null ? child1Offset + length1 : child2Offset; + int offset2 = child2Offset; + int offset3 = offset2 + length2; + if (bounds[0] <= offset1 && offset2 <= bounds[1]) { + if (child1 != null && child2 != null) { + child2 = myCodeFormatter.format(SourceTreeToPsiMap.treeElementToPsi(parent), child1, child2, mySettings, myHelper); + child2Offset = child1Offset + length1; + for (TreeElement child = child1 != null ? child1.getTreeNext() : parent.firstChild; + child != child2; + child = child.getTreeNext()) { + child2Offset += child.getTextLength(); + } + //Diagnostic.assertTrue(child2Offset == child2.getStartOffsetInParent()); + bounds[1] += child2Offset - offset2; + offset2 = child2Offset; + offset3 = offset2 + length2; + } + } + if (bounds[0] <= offset2 && offset3 <= bounds[1]) { + if (bounds[0] > offset1) { + String space = Helper.getSpaceText(parent, child1, child2); + int index = bounds[0] - offset1 - 1; + if (space.indexOf('\n', index) < 0 && space.indexOf('\r', index) < 0) continue; + } + child2 = myIndentAdjuster.adjustIndent(child2); + child2 = myWrapper.wrap(child2); + child2 = + SourceTreeToPsiMap.psiElementToTree(myBraceEnforcer.process(SourceTreeToPsiMap.treeElementToPsi(child2))); + child2 = myCommentFormatter.formatComment(child2); + child2Offset = child1Offset + length1; + for (TreeElement child = child1 != null ? child1.getTreeNext() : parent.firstChild; + child != child2; + child = child.getTreeNext()) { + child2Offset += child.getTextLength(); + } + //Diagnostic.assertTrue(child2Offset == child2.getStartOffsetInParent()); + bounds[1] += child2Offset + child2.getTextLength() - offset3; + } + } + + int offset = 0; + for (TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()) { + //Diagnostic.assertTrue(offset == child.getStartOffsetInParent()); + int offset1 = offset; + int offset2 = offset + child.getTextLength(); + if (bounds[0] <= offset2 && offset1 <= bounds[1]) { + bounds[0] -= offset1; + bounds[1] -= offset1; + child = processRange(child, bounds); + bounds[0] += offset1; + bounds[1] += offset1; + offset2 = offset + child.getTextLength(); + } + offset = offset2; + } + } + return element; + } + + public TreeElement processSpace(TreeElement child1, TreeElement child2) { + this.child1 = child1; + this.child2 = child2; + CompositeElement parent = child1 != null ? child1.getTreeParent() : ((child2 != null) ? child2.getTreeParent() : null); + if ((child1 == null || child2 == null) && !(SourceTreeToPsiMap.treeElementToPsi(parent) instanceof PsiFile)) { + if (parent != null) myHelper.makeSpace(parent, child1, child2, ""); + return child2; + } + child2 = myCodeFormatter.format(SourceTreeToPsiMap.treeElementToPsi(parent), child1, child2, mySettings, myHelper); + if (child1 != null && child1.getElementType() == END_OF_LINE_COMMENT) { + if (myHelper.getLineBreakCount(parent, child1, child2) == 0) { + myHelper.makeVerticalSpace(parent, child1, child2, 0); + } + } + return child2; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java new file mode 100644 index 00000000000..40fa871fd2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -0,0 +1,1180 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.text.BlockSupport; +import com.intellij.psi.tree.jsp.IJspElementType; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.text.CharArrayUtil; + +import java.beans.Introspector; +import java.util.*; + +public class CodeStyleManagerImpl extends CodeStyleManagerEx implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl"); + + private Project myProject; + + private StatisticsManagerEx myStatisticsManager; + + public CodeStyleManagerImpl(Project project, StatisticsManagerEx statisticsManagerEx) { + myProject = project; + + myStatisticsManager = + statisticsManagerEx; + } + + public String getComponentName() { + return "CodeStyleManager"; + } + + public void initComponent() { } + + public void disposeComponent() {} + + public void projectOpened() {} + + public void projectClosed() {} + + public Project getProject() { + return myProject; + } + + public PsiElement reformat(PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(element); + if (!SourceTreeToPsiMap.hasTreeElement(element)) return element; + + TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(element); + if (treeElement instanceof CompositeElement) { + ChameleonTransforming.transformChildren((CompositeElement)treeElement, true); // optimization : parse all first + } + PsiFileImpl file = (PsiFileImpl)element.getContainingFile(); + FileType fileType = StdFileTypes.JAVA; + if (file != null) { + fileType = file.getFileType(); + } + Helper helper = new Helper(fileType, myProject); + final PsiElement formatted = SourceTreeToPsiMap.treeElementToPsi( + new CodeFormatterFacade(getSettings(), helper).process(treeElement,-1)); + return new BraceEnforcer(getSettings()).process(formatted); + } + + public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset) + throws IncorrectOperationException { + CheckUtil.checkWritable(element); + if (!SourceTreeToPsiMap.hasTreeElement(element)) return element; + + TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(element); + if (treeElement instanceof CompositeElement) { + ChameleonTransforming.transformChildren((CompositeElement)treeElement, true); // optimization : parse all first + } + FileType fileType = StdFileTypes.JAVA; + PsiFile file = element.getContainingFile(); + if (file != null) { + fileType = file.getFileType(); + } + Helper helper = new Helper(fileType, myProject); + final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings(), helper); + return SourceTreeToPsiMap.treeElementToPsi(codeFormatter.processRange(treeElement, startOffset, endOffset)); + } + + public PsiElement shortenClassReferences(PsiElement element) throws IncorrectOperationException { + return shortenClassReferences(element, 0); + } + + public PsiElement shortenClassReferences(PsiElement element, int flags) throws IncorrectOperationException { + CheckUtil.checkWritable(element); + if (!SourceTreeToPsiMap.hasTreeElement(element)) return element; + + boolean addImports = (flags & DO_NOT_ADD_IMPORTS) == 0; + boolean uncompleteCode = (flags & UNCOMPLETE_CODE) != 0; + return SourceTreeToPsiMap.treeElementToPsi( + new ReferenceAdjuster(getSettings()).process(SourceTreeToPsiMap.psiElementToTree(element), addImports, + uncompleteCode)); + } + + public void shortenClassReferences(PsiElement element, int startOffset, int endOffset) + throws IncorrectOperationException { + CheckUtil.checkWritable(element); + if (!SourceTreeToPsiMap.hasTreeElement(element)) return; + new ReferenceAdjuster(getSettings()).processRange(SourceTreeToPsiMap.psiElementToTree(element), startOffset, + endOffset); + } + + public PsiElement qualifyClassReferences(PsiElement element) { + return SourceTreeToPsiMap.treeElementToPsi( + new ReferenceAdjuster(getSettings(), true, true).process(SourceTreeToPsiMap.psiElementToTree(element), false, + false)); + } + + public void optimizeImports(PsiFile file) throws IncorrectOperationException { + CheckUtil.checkWritable(file); + if (file instanceof PsiJavaFile) { + PsiImportList newList = prepareOptimizeImportsResult(file); + if (newList != null) { + ((PsiJavaFile)file).getImportList().replace(newList); + } + } + } + + public PsiImportList prepareOptimizeImportsResult(PsiFile file) { + if (!(file instanceof PsiJavaFile)) return null; + return new ImportHelper(getSettings()).prepareOptimizeImportsResult(this, (PsiJavaFile)file); + } + + public boolean addImport(PsiFile file, PsiClass refClass) { + return new ImportHelper(getSettings()).addImport(file, refClass); + } + + public int findEntryIndex(PsiImportStatementBase statement){ + return new ImportHelper(getSettings()).findEntryIndex(statement); + } + + public int adjustLineIndent(PsiFile file, int offset) throws IncorrectOperationException { + return adjustLineIndent(file, offset, true); + } + + private int adjustLineIndent(PsiFile file, int offset, boolean canTryXXX) throws IncorrectOperationException { + CheckUtil.checkWritable(file); + if (!SourceTreeToPsiMap.hasTreeElement(file)) return offset; + + final CharTable charTable = ((FileElement)SourceTreeToPsiMap.psiElementToTree(file)).getCharTable(); + TreeElement element = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(offset)); + if (element == null) return offset; + if (element.getElementType() == ElementType.WHITE_SPACE) { + int spaceStart = element.getTextRange().getStartOffset(); + offset = spaceStart + CharArrayUtil.shiftForward(element.textToCharArray(), offset - spaceStart, " \t"); + element = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(offset)); + } + + FileType fileType = file.getFileType(); + Helper helper = new Helper(fileType, myProject); + + CheckUncompleteCode: + if (element != null && canTryXXX) { + TreeElement space; + if (element.getElementType() == ElementType.WHITE_SPACE) { + space = element; + } + else { + space = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(offset - 1)); + } + + int spaceStart; + if (space != null && space.getElementType() == ElementType.WHITE_SPACE) { + spaceStart = space.getStartOffset(); + } + else { + spaceStart = element.getTextRange().getStartOffset(); + } + + if (spaceStart > 0) { + TreeElement leafBeforeSpace = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(spaceStart - 1)); + if (leafBeforeSpace.getTreeNext() != null && leafBeforeSpace.getTreeNext().getElementType() == ElementType.ERROR_ELEMENT) { + PsiErrorElement errorElement = (PsiErrorElement)SourceTreeToPsiMap.treeElementToPsi(leafBeforeSpace.getTreeNext()); + Project project = file.getProject(); + BlockSupport blockSupport = project.getComponent(BlockSupport.class); + String dummyString = "xxx"; + if ("';' expected".equals(errorElement.getErrorDescription())) { //TODO: change!!! + break CheckUncompleteCode; + } + + blockSupport.reparseRange(file, offset, offset, dummyString); + int newOffset = adjustLineIndent(file, offset, false); + blockSupport.reparseRange(file, newOffset, newOffset + dummyString.length(), ""); + return newOffset; + } + } + } + + int start = -1; // start of the line + int end = -1; // end of whitespace at the beginning of the line + if (element != null && element.getElementType() == ElementType.WHITE_SPACE) { // optimization to not fetch file.textToCharArray() + TextRange range = element.getTextRange(); + int localOffset = offset - range.getStartOffset(); + char[] chars = element.textToCharArray(); + start = CharArrayUtil.shiftBackward(chars, localOffset - 1, " \t"); + if (start > 0 && chars[start] != '\n' && chars[start] != '\r') return offset; + start++; + end = CharArrayUtil.shiftForward(chars, localOffset, " \t"); + if (end < chars.length) { + start += range.getStartOffset(); + end += range.getStartOffset(); + } + else { + end = -1; + } + } + + if (end < 0) { + char[] chars = file.textToCharArray(); + + start = CharArrayUtil.shiftBackward(chars, offset - 1, " \t"); + if (start > 0 && chars[start] != '\n' && chars[start] != '\r') return offset; + start++; + end = CharArrayUtil.shiftForward(chars, offset, " \t"); + if (end >= chars.length) return start; + + element = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(end)); + if (element == null) return start; + } + + if (element.getElementType() == ElementType.WHITE_SPACE) { + // trick to reduce number of PsiTreeChangeEvent's (Enter action optimization) + final boolean physical = file.isPhysical(); + CompositeElement parent; + TreeElement newSpace; + try { + ((PsiFileImpl)file).setIsPhysicalExplicitly(false); + + int spaceStart = element.getTextRange().getStartOffset(); + parent = element.getTreeParent(); + TreeElement prev = element.getTreePrev(); + TreeElement next = element.getTreeNext(); + TreeElement space1 = Helper.splitSpaceElement(element, end - spaceStart, charTable); + TreeElement tempElement = Factory.createSingleLeafElement( + ElementType.NEW_LINE_INDENT, "###".toCharArray(), 0, + "###".length(), charTable, null); + ChangeUtil.addChild(parent, tempElement, space1.getTreeNext()); + tempElement = new IndentAdjusterFacade(getSettings(), helper).adjustIndent(tempElement); + offset = tempElement.getTextRange().getStartOffset(); + ChangeUtil.removeChild(parent, tempElement); + CodeEditUtil.normalizeSpace(helper, parent, prev, next, charTable); + + newSpace = prev != null ? prev.getTreeNext() : parent.firstChild; + LOG.assertTrue(newSpace.getElementType() == ElementType.WHITE_SPACE); + ChangeUtil.replaceChild(parent, newSpace, element); + } + finally { + ((PsiFileImpl)file).setIsPhysicalExplicitly(physical); + } + + ChangeUtil.replaceChild(parent, element, newSpace); + + return offset; + } + else { + int elementStart = element.getTextRange().getStartOffset(); + if (elementStart == end) { + while (true) { + TreeElement prev = element.getTreePrev(); + while (prev != null && prev.getTextLength() == 0) { + prev = prev.getTreePrev(); + } + if (prev != null) break; + if (element.getTreeParent() == null) break; + element = element.getTreeParent(); + } + element = new IndentAdjusterFacade(getSettings(), helper).adjustFirstLineIndent(element); + return element.getTextRange().getStartOffset(); + } + else { + char[] chars = file.textToCharArray(); + int offset1 = CharArrayUtil.shiftBackward(chars, start, " \t\n\r"); + int indent; + if (offset1 < 0) { + indent = 0; + } + else { + offset1 = CharArrayUtil.shiftBackwardUntil(chars, offset1, "\n\r"); + offset1++; + int offset2 = CharArrayUtil.shiftForward(chars, offset1, " \t"); + String space = new String(chars, offset1, offset2 - offset1); + indent = helper.getIndent(space, true); + } + String indentSpace = helper.fillIndent(indent); + String elementText = element.getText(); + String newElementText = elementText.substring(0, start - elementStart) + indentSpace + + elementText.substring(end - elementStart); + LeafElement newElement = Factory.createSingleLeafElement(element.getElementType(), newElementText.toCharArray(), 0, + newElementText.length(), null, element.getManager()); + ChangeUtil.replaceChild(element.getTreeParent(), element, newElement); + return start + indentSpace.length(); + } + } + } + + public boolean isLineToBeIndented(PsiFile file, int offset) { + if (!SourceTreeToPsiMap.hasTreeElement(file)) return false; + Helper helper = new Helper(file.getFileType(), myProject); + char[] chars = file.textToCharArray(); + int start = CharArrayUtil.shiftBackward(chars, offset - 1, " \t"); + if (start > 0 && chars[start] != '\n' && chars[start] != '\r') return false; + int end = CharArrayUtil.shiftForward(chars, offset, " \t"); + if (end >= chars.length) return false; + TreeElement element = SourceTreeToPsiMap.psiElementToTree(file.findElementAt(end)); + if (element == null) return false; + if (element.getElementType() == ElementType.WHITE_SPACE) return false; + if (element.getElementType() == ElementType.PLAIN_TEXT) return false; + if (element.getElementType() instanceof IJspElementType) return false; + if (getSettings().KEEP_FIRST_COLUMN_COMMENT + && (element.getElementType() == ElementType.END_OF_LINE_COMMENT || element.getElementType() == ElementType.C_STYLE_COMMENT) + ) { + if (helper.getIndent(element, true) == 0) return false; + } + return true; + } + + public PsiElement insertNewLineIndentMarker(PsiFile file, int offset) throws IncorrectOperationException { + CheckUtil.checkWritable(file); + final CharTable charTable = ((FileElement)SourceTreeToPsiMap.psiElementToTree(file)).getCharTable(); + PsiElement elementAt = file.findElementAt(offset); + if (elementAt == null) return null; + TreeElement element = SourceTreeToPsiMap.psiElementToTree(elementAt); + CompositeElement parent = element.getTreeParent(); + int elementStart = element.getTextRange().getStartOffset(); + if (element.getElementType() != ElementType.WHITE_SPACE) { + /* + if (elementStart < offset) return null; + Element marker = Factory.createLeafElement(ElementType.NEW_LINE_INDENT, "###".toCharArray(), 0, "###".length()); + ChangeUtil.addChild(parent, marker, element); + return marker; + */ + return null; + } + + TreeElement space1 = Helper.splitSpaceElement(element, offset - elementStart, charTable); + TreeElement marker = Factory.createSingleLeafElement(ElementType.NEW_LINE_INDENT, "###".toCharArray(), 0, "###".length(), charTable, null); + ChangeUtil.addChild(parent, marker, space1.getTreeNext()); + return SourceTreeToPsiMap.treeElementToPsi(marker); + } + + public Indent getIndent(String text, FileType fileType) { + int indent = new Helper(fileType, myProject).getIndent(text, true); + int indenLevel = indent / Helper.INDENT_FACTOR; + int spaceCount = indent - indenLevel * Helper.INDENT_FACTOR; + return new IndentImpl(getSettings(), indenLevel, spaceCount, fileType); + } + + public String fillIndent(Indent indent, FileType fileType) { + IndentImpl indent1 = (IndentImpl)indent; + int indentLevel = indent1.getIndentLevel(); + int spaceCount = indent1.getSpaceCount(); + if (indentLevel < 0) { + spaceCount += indentLevel * getSettings().getIndentSize(fileType); + indentLevel = 0; + if (spaceCount < 0) { + spaceCount = 0; + } + } + else { + if (spaceCount < 0) { + int v = (-spaceCount + getSettings().getIndentSize(fileType) - 1) / getSettings().getIndentSize(fileType); + indentLevel -= v; + spaceCount += v * getSettings().getIndentSize(fileType); + if (indentLevel < 0) { + indentLevel = 0; + } + } + } + return new Helper(fileType, myProject).fillIndent(indentLevel * Helper.INDENT_FACTOR + spaceCount); + } + + public Indent zeroIndent() { + return new IndentImpl(getSettings(), 0, 0, null); + } + + public VariableKind getVariableKind(PsiVariable variable) { + if (variable instanceof PsiField) { + if (variable.hasModifierProperty(PsiModifier.STATIC)) { + if (variable.hasModifierProperty(PsiModifier.FINAL)) { + return VariableKind.STATIC_FINAL_FIELD; + } + else { + return VariableKind.STATIC_FIELD; + } + } + else { + return VariableKind.FIELD; + } + } + else { + if (variable instanceof PsiParameter) { + return VariableKind.PARAMETER; + } + else { + if (variable instanceof PsiLocalVariable) { + return VariableKind.LOCAL_VARIABLE; + } + else { + return VariableKind.LOCAL_VARIABLE; + // TODO[ik]: open api for this + //LOG.assertTrue(false); + //return null; + } + } + } + } + + public SuggestedNameInfo suggestVariableName(final VariableKind kind, + final String propertyName, + final PsiExpression expr, + PsiType type) { + LinkedHashSet names = new LinkedHashSet(); + + if (expr != null && type == null) { + type = expr.getType(); + } + + if (propertyName != null) { + String[] namesByName = getSuggestionsByName(propertyName, kind, false); + sortVariableNameSuggestions(namesByName, kind, propertyName, null); + names.addAll(Arrays.asList(namesByName)); + } + + final NamesByExprInfo namesByExpr; + if (expr != null) { + namesByExpr = suggestVariableNameByExpression(expr, kind); + if (namesByExpr.propertyName != null) { + sortVariableNameSuggestions(namesByExpr.names, kind, namesByExpr.propertyName, null); + } + names.addAll(Arrays.asList(namesByExpr.names)); + } + else { + namesByExpr = null; + } + + if (type != null) { + String[] namesByType = suggestVariableNameByType(type, kind); + sortVariableNameSuggestions(namesByType, kind, null, type); + names.addAll(Arrays.asList(namesByType)); + } + + final String _propertyName; + if (propertyName != null) { + _propertyName = propertyName; + } + else { + _propertyName = namesByExpr != null ? namesByExpr.propertyName : null; + } + + addNamesFromStatistics(names, kind, _propertyName, type); + + String[] namesArray = names.toArray(new String[names.size()]); + sortVariableNameSuggestions(namesArray, kind, _propertyName, type); + + final PsiType _type = type; + return new SuggestedNameInfo(namesArray) { + public void nameChoosen(String name) { + if (_propertyName != null || _type != null) { + if (_type != null && !_type.isValid()) return; + myStatisticsManager.incVariableNameUseCount(name, kind, _propertyName, _type); + } + } + }; + } + + private void addNamesFromStatistics(Set names, VariableKind variableKind, String propertyName, PsiType type) { + String[] allNames = myStatisticsManager.getAllVariableNamesUsed(variableKind, propertyName, type); + + int maxFrequency = 0; + for (int i = 0; i < allNames.length; i++) { + String name = allNames[i]; + int count = myStatisticsManager.getVariableNameUseCount(name, variableKind, propertyName, type); + maxFrequency = Math.max(maxFrequency, count); + } + + int frequencyLimit = Math.max(5, maxFrequency / 2); + + for (int i = 0; i < allNames.length; i++) { + String name = allNames[i]; + if (names.contains(name)) continue; + int count = myStatisticsManager.getVariableNameUseCount(name, variableKind, propertyName, type); + if (LOG.isDebugEnabled()) { + LOG.debug("new name:" + name + " count:" + count); + LOG.debug("frequencyLimit:" + frequencyLimit); + } + if (count >= frequencyLimit) { + names.add(name); + } + } + + if (propertyName != null && type != null) { + addNamesFromStatistics(names, variableKind, propertyName, null); + addNamesFromStatistics(names, variableKind, null, type); + } + } + + private String[] suggestVariableNameByType(PsiType type, final VariableKind variableKind) { + String longTypeName = getLongTypeName(type); + CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind); + if (map != null && longTypeName != null) { + if (longTypeName.equals(PsiType.NULL)) { + longTypeName = "java.lang.Object"; + } + String name = map.nameByType(longTypeName); + if (name != null) { + return new String[]{name}; + } + } + + List suggestions = new ArrayList(); + + suggestNamesForCollectionInheritors(type, variableKind, suggestions); + + String typeName = normalizeTypeName(getTypeName(type)); + if (typeName != null) { + suggestions.addAll(Arrays.asList(getSuggestionsByName(typeName, variableKind, type instanceof PsiArrayType))); + } + + return suggestions.toArray(new String[suggestions.size()]); + } + + private void suggestNamesForCollectionInheritors(final PsiType type, + final VariableKind variableKind, + List suggestions) { + if (!(type instanceof PsiClassType)) return; + PsiClassType classType = (PsiClassType)type; + PsiClassType.ClassResolveResult resolved = classType.resolveGenerics(); + if (resolved.getElement() == null) return; + final PsiManager manager = PsiManager.getInstance(myProject); + final PsiClass collectionClass = manager.findClass("java.util.Collection", resolved.getElement().getResolveScope()); + if (collectionClass == null) return; + + if (InheritanceUtil.isInheritorOrSelf(resolved.getElement(), collectionClass, true)) { + final PsiSubstitutor substitutor; + if (!manager.areElementsEquivalent(resolved.getElement(), collectionClass)) { + substitutor = TypeConversionUtil.getClassSubstitutor(collectionClass, resolved.getElement(), + PsiSubstitutor.EMPTY); + } + else { + substitutor = PsiSubstitutor.EMPTY; + } + + PsiTypeParameterList typeParameterList = collectionClass.getTypeParameterList(); + if (typeParameterList == null) return; + PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + if (typeParameters.length == 0) return; + + PsiType componentTypeParameter = substitutor.substitute(typeParameters[0]); + if (componentTypeParameter instanceof PsiClassType) { + PsiClass componentClass = ((PsiClassType)componentTypeParameter).resolve(); + if (componentClass instanceof PsiTypeParameter) { + if (collectionClass.getManager().areElementsEquivalent(((PsiTypeParameter)componentClass).getOwner(), + resolved.getElement())) { + PsiType componentType = resolved.getSubstitutor().substitute((PsiTypeParameter)componentClass); + if (componentType == null) return; + String typeName = normalizeTypeName(getTypeName(componentType)); + if (typeName != null) { + suggestions.addAll(Arrays.asList(getSuggestionsByName(typeName, variableKind, true))); + } + } + } + } + } + } + + private static String normalizeTypeName(String typeName) { + if (typeName == null) return null; + if (typeName.endsWith("Impl") && typeName.length() > "Impl".length()) { + return typeName.substring(0, typeName.length() - "Impl".length()); + } + return typeName; + } + + private static String getTypeName(PsiType type) { + type = type.getDeepComponentType(); + if (type instanceof PsiClassType) { + final PsiClassType classType = (PsiClassType)type; + final String className = classType.getClassName(); + if (className != null) { + return className; + } + else { + final PsiClass aClass = classType.resolve(); + if (aClass instanceof PsiAnonymousClass) { + return ((PsiAnonymousClass)aClass).getBaseClassType().getClassName(); + } + else { + return null; + } + } + } + else { + if (type instanceof PsiPrimitiveType) { + return type.getPresentableText(); + } + else if (type instanceof PsiWildcardType) { + return getTypeName(((PsiWildcardType)type).getExtendsBound()); + } + else if (type instanceof PsiIntersectionType) { + return getTypeName(((PsiIntersectionType)type).getRepresentative()); + } + else if (type instanceof PsiCapturedWildcardType) { + return getTypeName(((PsiCapturedWildcardType)type).getWildcard()); + } + else { + LOG.error("Unknown type:" + type); + return null; + } + } + } + + private String getLongTypeName(PsiType type) { + if (type instanceof PsiClassType) { + PsiClass aClass = ((PsiClassType)type).resolve(); + if (aClass == null) return null; + if (aClass instanceof PsiAnonymousClass) { + PsiClass baseClass = ((PsiAnonymousClass)aClass).getBaseClassType().resolve(); + if (baseClass == null) return null; + return baseClass.getQualifiedName(); + } + return aClass.getQualifiedName(); + } + else { + if (type instanceof PsiArrayType) { + return getLongTypeName(((PsiArrayType)type).getComponentType()) + "[]"; + } + else { + if (type instanceof PsiPrimitiveType) { + return type.getPresentableText(); + } + else if (type instanceof PsiWildcardType) { + final PsiType bound = ((PsiWildcardType)type).getBound(); + if (bound != null) { + return getLongTypeName(bound); + } + else { + return "java.lang.Object"; + } + } + else if (type instanceof PsiCapturedWildcardType) { + final PsiType bound = ((PsiCapturedWildcardType)type).getWildcard().getBound(); + if (bound != null) { + return getLongTypeName(bound); + } + else { + return "java.lang.Object"; + } + } + else if (type instanceof PsiIntersectionType) { + return getLongTypeName(((PsiIntersectionType)type).getRepresentative()); + } + else { + LOG.error("Unknown type:" + type); + return null; + } + } + } + } + + private static class NamesByExprInfo { + final String[] names; + final String propertyName; + + public NamesByExprInfo(String[] names, String propertyName) { + this.names = names; + this.propertyName = propertyName; + } + } + + private NamesByExprInfo suggestVariableNameByExpression(PsiExpression expr, VariableKind variableKind) { + final NamesByExprInfo names1 = suggestVariableNameByExpressionOnly(expr, variableKind); + final NamesByExprInfo names2 = suggestVariableNameByExpressionPlace(expr, variableKind); + + PsiType type = expr.getType(); + final String[] names3; + if (type != null) { + names3 = suggestVariableNameByType(type, variableKind); + } + else { + names3 = null; + } + + LinkedHashSet names = new LinkedHashSet(); + names.addAll(Arrays.asList(names1.names)); + names.addAll(Arrays.asList(names2.names)); + if (names3 != null) { + names.addAll(Arrays.asList(names3)); + } + String[] namesArray = names.toArray(new String[names.size()]); + String propertyName = names1.propertyName != null ? names1.propertyName : names2.propertyName; + return new NamesByExprInfo(namesArray, propertyName); + } + + private NamesByExprInfo suggestVariableNameByExpressionOnly(PsiExpression expr, final VariableKind variableKind) { + if (expr instanceof PsiMethodCallExpression) { + PsiReferenceExpression methodExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); + PsiElement[] children = methodExpr.getChildren(); + String methodName = children[children.length - 1].getText(); + String[] words = NameUtil.nameToWords(methodName); + if (words.length > 1) { + String firstWord = words[0]; + if ("get".equals(firstWord) + || "is".equals(firstWord) + || "find".equals(firstWord) + || "create".equals(firstWord)) { + final String propertyName = methodName.substring(firstWord.length()); + String[] names = getSuggestionsByName(propertyName, variableKind, false); + return new NamesByExprInfo(names, propertyName); + } + } + } + else { + if (expr instanceof PsiReferenceExpression) { + String propertyName = ((PsiReferenceExpression)expr).getReferenceName(); + PsiElement refElement = ((PsiReferenceExpression)expr).resolve(); + if (refElement instanceof PsiVariable) { + VariableKind refVariableKind = getVariableKind((PsiVariable)refElement); + propertyName = variableNameToPropertyName(propertyName, refVariableKind); + } + if (refElement != null && propertyName != null) { + String[] names = getSuggestionsByName(propertyName, variableKind, false); + return new NamesByExprInfo(names, propertyName); + } + } + else { + if (expr instanceof PsiArrayAccessExpression) { + PsiExpression array = ((PsiArrayAccessExpression)expr).getArrayExpression(); + if (array instanceof PsiReferenceExpression) { + PsiElement[] children = array.getChildren(); + String arrayName = children[children.length - 1].getText(); + PsiElement refElement = ((PsiReferenceExpression)array).resolve(); + if (refElement instanceof PsiVariable) { + VariableKind refVariableKind = getVariableKind((PsiVariable)refElement); + arrayName = variableNameToPropertyName(arrayName, refVariableKind); + } + String name = null; + if (arrayName.endsWith("ses") || arrayName.endsWith("xes")) { //? + name = arrayName.substring(0, arrayName.length() - 2); + } + else { + if (arrayName.endsWith("ies")) { + name = arrayName.substring(0, arrayName.length() - 3) + "y"; + } + else { + if (StringUtil.endsWithChar(arrayName, 's')) { + name = arrayName.substring(0, arrayName.length() - 1); + } + else { + if ("children".equals(arrayName)) { + name = "child"; + } + } + } + } + + if (name != null) { + String[] names = getSuggestionsByName(name, variableKind, false); + return new NamesByExprInfo(names, name); + } + } + } + } + } + + return new NamesByExprInfo(ArrayUtil.EMPTY_STRING_ARRAY, null); + } + + private NamesByExprInfo suggestVariableNameByExpressionPlace(PsiExpression expr, final VariableKind variableKind) { + if (expr.getParent() instanceof PsiExpressionList) { + PsiExpressionList list = (PsiExpressionList)expr.getParent(); + PsiElement listParent = list.getParent(); + PsiMethod method = null; + if (listParent instanceof PsiMethodCallExpression) { + method = (PsiMethod)((PsiMethodCallExpression)listParent).getMethodExpression().resolve(); + } + else { + if (listParent instanceof PsiAnonymousClass) { + listParent = listParent.getParent(); + } + if (listParent instanceof PsiNewExpression) { + method = ((PsiNewExpression)listParent).resolveConstructor(); + } + } + + if (method != null) { + method = (PsiMethod)method.getNavigationElement(); + PsiExpression[] expressions = list.getExpressions(); + int index = -1; + for (int i = 0; i < expressions.length; i++) { + if (expressions[i] == expr) { + index = i; + break; + } + } + PsiParameter[] parms = method.getParameterList().getParameters(); + if (index < parms.length) { + PsiIdentifier identifier = parms[index].getNameIdentifier(); + if (identifier != null) { + String name = identifier.getText(); + name = variableNameToPropertyName(name, VariableKind.PARAMETER); + String[] names = getSuggestionsByName(name, variableKind, false); + return new NamesByExprInfo(names, name); + } + } + } + } + + return new NamesByExprInfo(ArrayUtil.EMPTY_STRING_ARRAY, null); + } + + public String variableNameToPropertyName(String name, VariableKind variableKind) { + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + if (c != '_') { + if (Character.isLowerCase(c)) return variableNameToPropertyNameInner(name, variableKind); + + buffer.append(Character.toLowerCase(c)); + continue; + } + i++; + if (i < name.length()) { + c = name.charAt(i); + buffer.append(c); + } + } + return buffer.toString(); + } + + return variableNameToPropertyNameInner(name, variableKind); + } + + private String variableNameToPropertyNameInner(String name, VariableKind variableKind) { + String prefix = getPrefixByVariableKind(variableKind); + String suffix = getSuffixByVariableKind(variableKind); + boolean doDecapitalize = false; + + if (name.startsWith(prefix) && name.length() > prefix.length()) { + name = name.substring(prefix.length()); + doDecapitalize = true; + } + + if (name.endsWith(suffix) && name.length() > suffix.length()) { + name = name.substring(0, name.length() - suffix.length()); + doDecapitalize = true; + } + + if (name.startsWith("is") && name.length() > "is".length() && Character.isUpperCase(name.charAt("is".length()))) { + name = name.substring("is".length()); + doDecapitalize = true; + } + + if (doDecapitalize) { + name = Introspector.decapitalize(name); + } + + return name; + } + + public String propertyNameToVariableName(String propertyName, VariableKind variableKind) { + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + String[] words = NameUtil.nameToWords(propertyName); + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (i > 0) { + buffer.append("_"); + } + buffer.append(word.toUpperCase()); + } + return buffer.toString(); + } + + String prefix = getPrefixByVariableKind(variableKind); + String name = propertyName; + if (name.length() > 0 && prefix.length() > 0 && !StringUtil.endsWithChar(prefix, '_')) { + name = Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + name = prefix + name + getSuffixByVariableKind(variableKind); + name = changeIfNotIdentifier(name); + return name; + } + + private String[] getSuggestionsByName(String name, VariableKind variableKind, boolean isArray) { + String prefix = getPrefixByVariableKind(variableKind); + ArrayList list = new ArrayList(); + String[] words = NameUtil.nameToWords(name); + + for (int step = 0; step < words.length; step++) { + int wordCount = getSettings().PREFER_LONGER_NAMES ? words.length - step : step + 1; + + String startWord = words[words.length - wordCount]; + char c = startWord.charAt(0); + if (c == '_' || !Character.isJavaIdentifierStart(c)) continue; + + StringBuffer buffer = new StringBuffer(); + buffer.append(prefix); + + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + startWord = startWord.toUpperCase(); + } + else { + if (prefix.length() == 0 || StringUtil.endsWithChar(prefix, '_')) { + startWord = startWord.toLowerCase(); + } + else { + startWord = Character.toUpperCase(c) + startWord.substring(1); + } + } + buffer.append(startWord); + + for (int i = words.length - wordCount + 1; i < words.length; i++) { + String word = words[i]; + String prevWord = words[i - 1]; + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + word = word.toUpperCase(); + if (prevWord.charAt(prevWord.length() - 1) != '_') { + word = "_" + word; + } + } + else { + if (prevWord.charAt(prevWord.length() - 1) == '_') { + word = word.toLowerCase(); + } + } + buffer.append(word); + } + + String suggestion = buffer.toString(); + + if (isArray && variableKind != VariableKind.STATIC_FINAL_FIELD) { + suggestion = StringUtil.pluralize(suggestion); + } + + suggestion = changeIfNotIdentifier(suggestion + getSuffixByVariableKind(variableKind)); + + list.add(suggestion); + } + + return list.toArray(new String[list.size()]); + } + + public String suggestUniqueVariableName(String baseName, PsiElement place, boolean lookForward) { + PsiElement scope; + if (lookForward) { + scope = place.getParent(); + while (true) { + if (scope instanceof PsiCodeBlock) break; + if (scope instanceof PsiClass) break; + if (scope instanceof PsiFile) break; + scope = scope.getParent(); + } + place = scope.getLastChild(); + } + else { + scope = null; + } + + int index = 0; + while (true) { + String name = baseName; + if (index > 0) { + name += index; + } + index++; + if (PsiUtil.isVariableNameUnique(name, place)) { + if (scope instanceof PsiCodeBlock) { + final String name1 = name; + class Cancel extends RuntimeException {} + try { + scope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitClass(PsiClass aClass) { + + } + + public void visitVariable(PsiVariable variable) { + if (name1.equals(variable.getName())) { + throw new Cancel(); + } + } + }); + } + catch (Cancel e) { + continue; + } + } + return name; + } + } + } + + public boolean checkIdentifierRole(String identifier, IdentifierRole role) { + if (role == IdentifierRole.CLASS_NAME) { + return identifier.length() > 0 && Character.isUpperCase(identifier.charAt(0)); + } + else { + if (role == IdentifierRole.FIELD_NAME) { + return identifier.startsWith(getSettings().FIELD_NAME_PREFIX) && + identifier.endsWith(getSettings().FIELD_NAME_SUFFIX); + } + else { + if (role == IdentifierRole.LOCAL_VAR_NAME) { + return identifier.startsWith(getSettings().LOCAL_VARIABLE_NAME_PREFIX) && + identifier.endsWith(getSettings().LOCAL_VARIABLE_NAME_SUFFIX); + } + else { + if (role == IdentifierRole.PARAMETER_NAME) { + return identifier.startsWith(getSettings().PARAMETER_NAME_PREFIX) && + identifier.endsWith(getSettings().PARAMETER_NAME_SUFFIX); + } + } + } + } + + return false; + } + + private void sortVariableNameSuggestions(String[] names, + final VariableKind variableKind, + final String propertyName, + final PsiType type) { + if (names.length <= 1) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("sorting names:" + variableKind); + if (propertyName != null) { + LOG.debug("propertyName:" + propertyName); + } + if (type != null) { + LOG.debug("type:" + type); + } + for (int i = 0; i < names.length; i++) { + String name = names[i]; + int count = myStatisticsManager.getVariableNameUseCount(name, variableKind, propertyName, type); + LOG.debug(name + " : " + count); + } + } + + Comparator comparator = new Comparator() { + public int compare(Object o1, Object o2) { + int count1 = myStatisticsManager.getVariableNameUseCount((String)o1, variableKind, propertyName, type); + int count2 = myStatisticsManager.getVariableNameUseCount((String)o2, variableKind, propertyName, type); + return count2 - count1; + } + }; + Arrays.sort(names, comparator); + } + + public String getPrefixByVariableKind(VariableKind variableKind) { + String prefix = ""; + if (variableKind == VariableKind.FIELD) { + prefix = getSettings().FIELD_NAME_PREFIX; + } + else { + if (variableKind == VariableKind.STATIC_FIELD) { + prefix = getSettings().STATIC_FIELD_NAME_PREFIX; + } + else { + if (variableKind == VariableKind.PARAMETER) { + prefix = getSettings().PARAMETER_NAME_PREFIX; + } + else { + if (variableKind == VariableKind.LOCAL_VARIABLE) { + prefix = getSettings().LOCAL_VARIABLE_NAME_PREFIX; + } + else { + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + prefix = ""; + } + else { + LOG.assertTrue(false); + } + } + } + } + } + if (prefix == null) { + prefix = ""; + } + return prefix; + } + + public String getSuffixByVariableKind(VariableKind variableKind) { + String suffix = ""; + if (variableKind == VariableKind.FIELD) { + suffix = getSettings().FIELD_NAME_SUFFIX; + } + else { + if (variableKind == VariableKind.STATIC_FIELD) { + suffix = getSettings().STATIC_FIELD_NAME_SUFFIX; + } + else { + if (variableKind == VariableKind.PARAMETER) { + suffix = getSettings().PARAMETER_NAME_SUFFIX; + } + else { + if (variableKind == VariableKind.LOCAL_VARIABLE) { + suffix = getSettings().LOCAL_VARIABLE_NAME_SUFFIX; + } + else { + if (variableKind == VariableKind.STATIC_FINAL_FIELD) { + suffix = ""; + } + else { + LOG.assertTrue(false); + } + } + } + } + } + if (suffix == null) { + suffix = ""; + } + return suffix; + } + + private CodeStyleSettings.TypeToNameMap getMapByVariableKind(VariableKind variableKind) { + if (variableKind == VariableKind.FIELD) { + return getSettings().FIELD_TYPE_TO_NAME; + } + else { + if (variableKind == VariableKind.STATIC_FIELD) { + return getSettings().STATIC_FIELD_TYPE_TO_NAME; + } + else { + if (variableKind == VariableKind.PARAMETER) { + return getSettings().PARAMETER_TYPE_TO_NAME; + } + else { + if (variableKind == VariableKind.LOCAL_VARIABLE) { + return getSettings().LOCAL_VARIABLE_TYPE_TO_NAME; + } + else { + return null; + } + } + } + } + } + + private String changeIfNotIdentifier(String name) { + PsiManager manager = PsiManager.getInstance(myProject); + + if (!manager.getNameHelper().isIdentifier(name)) { + char c = name.charAt(0); + if (StringUtil.isVowel(c)) { + return "an" + Character.toUpperCase(c) + name.substring(1); + } + return "a" + Character.toUpperCase(c) + name.substring(1); + } + return name; + } + + private CodeStyleSettings getSettings() { + return CodeStyleSettingsManager.getSettings(myProject); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemeImpl.java new file mode 100644 index 00000000000..d7319f7f883 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemeImpl.java @@ -0,0 +1,154 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; + +/** + * @author MYakovlev + * Date: Jul 17, 2002 + */ +public class CodeStyleSchemeImpl implements JDOMExternalizable, CodeStyleScheme{ + private static final String CODE_SCHEME = "code_scheme"; + private static final String NAME = "name"; + private static final String PARENT = "parent"; + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl"); + + private String myName; + private Element myRootElement; + private String myParentSchemeName; + private boolean myIsDefault; + private CodeStyleSettings myCodeStyleSettings; + private CodeStyleScheme myParentScheme; + + public CodeStyleSchemeImpl(String name, String parentSchemeName, Element rootElement) { + myName = name; + myRootElement = rootElement; + myIsDefault = false; + myParentSchemeName = parentSchemeName; + } + + public void init(CodeStyleSchemes schemesManager) { + LOG.assertTrue(myCodeStyleSettings == null, "Already initialized"); + init(schemesManager.findSchemeByName(myParentSchemeName), myRootElement); + myParentSchemeName = null; + myRootElement = null; + } + + public CodeStyleSchemeImpl(String name, boolean isDefault, CodeStyleScheme parentScheme){ + myName = name; + myIsDefault = isDefault; + init(parentScheme, null); + } + + private void init(CodeStyleScheme parentScheme, Element root) { + CodeStyleSettings parentSettings = parentScheme == null ? null : parentScheme.getCodeStyleSettings(); + if (parentSettings == null){ + myCodeStyleSettings = new CodeStyleSettings(); + } + else{ + myCodeStyleSettings = (CodeStyleSettings)parentSettings.clone(); + while(parentSettings.getParentSettings() != null){ + parentSettings = parentSettings.getParentSettings(); + } + myCodeStyleSettings.setParentSettings(parentSettings); + } + + myParentScheme = parentScheme; + + if (root != null) { + try { + readExternal(root); + } catch (InvalidDataException e) { + LOG.error(e); + } + } + } + + public CodeStyleSettings getCodeStyleSettings(){ + return myCodeStyleSettings; + } + + public void setCodeStyleSettings(CodeStyleSettings codeStyleSettings){ + LOG.assertTrue(codeStyleSettings != null); + myCodeStyleSettings = codeStyleSettings; + } + + public CodeStyleScheme getParentScheme(){ + return myParentScheme; + } + + public String getName(){ + return myName; + } + + public boolean isDefault(){ + return myIsDefault; + } + + public String toString(){ + return getName(); + } + + public void writeExternal(Element element) throws WriteExternalException{ + myCodeStyleSettings.writeExternal(element); + } + + public void readExternal(Element element) throws InvalidDataException{ + myCodeStyleSettings.readExternal(element); + } + + public static CodeStyleSchemeImpl readScheme(File file) throws InvalidDataException, JDOMException, IOException{ + Document document = JDOMUtil.loadDocument(file); + + if (document == null) throw new InvalidDataException(); + Element root = document.getRootElement(); + if (root == null){ + throw new InvalidDataException(); + } + + String schemeName = root.getAttributeValue(NAME); + String parentName = root.getAttributeValue(PARENT); + + if (schemeName == null){ + throw new InvalidDataException(); + } + + CodeStyleSchemeImpl newScheme = new CodeStyleSchemeImpl(schemeName, parentName, root); + + return newScheme; + } + + public void save(File dir) throws WriteExternalException{ + Element newElement = new Element(CODE_SCHEME); + newElement.setAttribute(NAME, getName()); + if(getParentScheme() != null){ + CodeStyleSchemeImpl parentScheme = (CodeStyleSchemeImpl)getParentScheme(); + while(parentScheme.getParentScheme() != null){ + parentScheme = (CodeStyleSchemeImpl)parentScheme.getParentScheme(); + } + newElement.setAttribute(PARENT, parentScheme.getName()); + } + (this).writeExternal(newElement); + + String filePath = dir.getAbsolutePath() + File.separator + getName() + ".xml"; + try { + JDOMUtil.writeDocument(new Document(newElement), filePath, getCodeStyleSettings().getLineSeparator()); + } + catch (IOException e) { + Messages.showErrorDialog("Can't save code style scheme " + filePath + ". " + e.getLocalizedMessage(), "Cannot Save File"); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java new file mode 100644 index 00000000000..45182066815 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java @@ -0,0 +1,216 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +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.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import java.io.File; +import java.util.Collection; + +/** + * @author MYakovlev + * Date: Jul 16, 2002 + */ +public class CodeStyleSchemesImpl extends CodeStyleSchemes implements ExportableApplicationComponent,JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleSchemesImpl"); + private HashMap mySchemes = new HashMap(); // name -> scheme + private CodeStyleScheme myCurrentScheme; + + public String CURRENT_SCHEME_NAME = "Default"; + private boolean myIsInitialized = false; + + private CodeStyleSchemesImpl() { + } + + public String getComponentName() { + return "CodeStyleSchemes"; + } + + public void initComponent() { + init(); + addScheme(new CodeStyleSchemeImpl("Default", true, null)); + CodeStyleScheme current = findSchemeByName(CURRENT_SCHEME_NAME); + if (current == null) current = getDefaultScheme(); + setCurrentScheme(current); + } + + public void disposeComponent() { + } + + public CodeStyleScheme[] getSchemes() { + final Collection schemes = mySchemes.values(); + return schemes.toArray(new CodeStyleScheme[schemes.size()]); + } + + public CodeStyleScheme getCurrentScheme() { + return myCurrentScheme; + } + + public void setCurrentScheme(CodeStyleScheme scheme) { + myCurrentScheme = scheme; + CURRENT_SCHEME_NAME = scheme.getName(); + } + + public CodeStyleScheme createNewScheme(String preferredName, CodeStyleScheme parentScheme) { + String name; + if (preferredName == null) { + // Generate using parent name + name = null; + for (int i = 1; name == null; i++) { + String currName = parentScheme.getName() + " (" + i + ")"; + if (null == findSchemeByName(currName)) { + name = currName; + } + } + } + else { + name = null; + for (int i = 0; name == null; i++) { + String currName = i == 0 ? preferredName : preferredName + " (" + i + ")"; + if (null == findSchemeByName(currName)) { + name = currName; + } + } + } + return new CodeStyleSchemeImpl(name, false, parentScheme); + } + + public void deleteScheme(CodeStyleScheme scheme) { + if (scheme.isDefault()) { + throw new IllegalArgumentException("Unable to delete default scheme!"); + } + CodeStyleSchemeImpl currScheme = (CodeStyleSchemeImpl)getCurrentScheme(); + if (currScheme == scheme) { + CodeStyleScheme newCurrentScheme = getDefaultScheme(); + if (newCurrentScheme == null) { + throw new IllegalStateException("Unable to load default scheme!"); + } + setCurrentScheme(newCurrentScheme); + } + mySchemes.remove(scheme.getName()); + } + + public CodeStyleScheme getDefaultScheme() { + return findSchemeByName("Default"); + } + + public CodeStyleScheme findSchemeByName(String name) { + return mySchemes.get(name); + } + + public void addScheme(CodeStyleScheme scheme) { + String name = scheme.getName(); + LOG.assertTrue(!mySchemes.containsKey(name), "Not unique scheme name"); + mySchemes.put(name, scheme); + } + + protected void removeScheme(CodeStyleScheme scheme) { + mySchemes.remove(scheme.getName()); + } + + public void readExternal(Element element) throws InvalidDataException { + init(); + DefaultJDOMExternalizer.readExternal(this, element); + } + + private void init() { + if (myIsInitialized) return; + myIsInitialized = true; + mySchemes.clear(); + + File[] files = getSchemeFiles(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.getName().toLowerCase().endsWith(".xml")) { + try { + addScheme(CodeStyleSchemeImpl.readScheme(file)); + } + catch (Exception e) { + Messages.showErrorDialog("Error reading code style scheme from " + file.getName(), "Corrupted File"); + } + } + } + + final CodeStyleScheme[] schemes = getSchemes(); + for (int i = 0; i < schemes.length; i++) { + ((CodeStyleSchemeImpl)schemes[i]).init(this); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + File[] files = getSchemeFiles(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + String fileName = file.getName().toLowerCase(); + String xmlExtension = ".xml"; + if (fileName.endsWith(xmlExtension)) { + try { + String fileNameWithoutExtension = fileName.substring(0, fileName.length() - xmlExtension.length()); + if (!mySchemes.containsKey(fileNameWithoutExtension)) { + file.delete(); + } + } + catch (Exception e) { + LOG.assertTrue(false, "Unable to save Code Style Settings"); + } + } + } + + final CodeStyleScheme[] schemes = getSchemes(); + for (int i = 0; i < schemes.length; i++) { + CodeStyleScheme scheme = schemes[i]; + if (!scheme.isDefault()) { + File dir = getDir(true); + if (dir == null) break; + ((CodeStyleSchemeImpl)scheme).save(dir); + } + } + + DefaultJDOMExternalizer.writeExternal(this, element); + } + + public File[] getExportFiles() { + return new File[]{getDir(true), PathManager.getDefaultOptionsFile()}; + } + + public String getPresentableName() { + return "Code style schemes"; + } + + private File[] getSchemeFiles() { + File schemesDir = getDir(true); + if (schemesDir == null) { + return new File[0]; + } + + File[] files = schemesDir.listFiles(); + if (files == null) { + LOG.error("Cannot read directory: " + schemesDir.getAbsolutePath()); + return new File[0]; + } + return files; + } + + private static File getDir(boolean create) { + String directoryPath = PathManager.getConfigPath() + File.separator + "codestyles"; + File directory = new File(directoryPath); + if (!directory.exists()) { + if (!create) return null; + if (!directory.mkdir()) { + Messages.showErrorDialog("Cannot save code style schemes. Directory " + directoryPath + " cannot be created.", + "Cannot Save Settings"); + return null; + } + } + return directory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/Helper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/Helper.java new file mode 100644 index 00000000000..5f66ea378ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/Helper.java @@ -0,0 +1,704 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaElementType; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlText; +import com.intellij.util.CharTable; +import java.util.HashMap; +import java.util.Map; + +public class Helper { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.Helper"); + + private final CodeStyleSettings mySettings; + private final FileType myFileType; + private final Project myProject; + + public Helper(FileType fileType, Project project) { + mySettings = CodeStyleSettingsManager.getSettings(project); + myProject = project; + myFileType = fileType; + } + + public static boolean isNonSpace(TreeElement element) { + IElementType elementType = element.getElementType(); + if(elementType == JavaTokenType.WHITE_SPACE) return false; + else if(elementType == XmlElementType.XML_TEXT && element.getText().trim().length() == 0) return false; + return element.getTextLength() > 0; + } + + public static TreeElement shiftForwardToNonSpace(TreeElement element) { + while (element != null && !isNonSpace(element)) { + element = element.getTreeNext(); + } + return element; + } + + public static TreeElement shiftBackwardToNonSpace(TreeElement element) { + while (element != null && !isNonSpace(element)) { + element = element.getTreePrev(); + } + return element; + } + + private int getStartOffset(TreeElement root, TreeElement child) { + if (child == root) return 0; + CompositeElement parent = child.getTreeParent(); + int offset = 0; + for (TreeElement child1 = parent.firstChild; child1 != child; child1 = child1.getTreeNext()) { + offset += child1.getTextLength(); + } + return getStartOffset(root, parent) + offset; + } + + public static TreeElement splitSpaceElement(TreeElement space, int offset, CharTable charTable) { + LOG.assertTrue(space.getElementType() == ElementType.WHITE_SPACE); + char[] chars = space.textToCharArray(); + LeafElement space1 = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, chars, 0, offset, charTable, null); + LeafElement space2 = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, chars, offset, chars.length, charTable, null); + CompositeElement parent = space.getTreeParent(); + ChangeUtil.replaceChild(parent, space, space1); + ChangeUtil.addChild(parent, space2, space1.getTreeNext()); + return space1; + } + +//---------------------------------------------------------------------------------------------------- + + public static final int INDENT_FACTOR = 10000; // "indent" is indent_level * INDENT_FACTOR + spaces + + public int getIndent(TreeElement element) { + return getIndent(element, false); + } + + public TreeElement getPrevWhitespace(final TreeElement element) { + if (element.getTreePrev() != null) { + TreeElement prev = element.getTreePrev(); + CompositeElement lastCompositePrev; + while (prev instanceof CompositeElement) { + lastCompositePrev = (CompositeElement)prev; + prev = ((CompositeElement)prev).lastChild; + if (prev == null) { // element.prev is "empty composite" + return getPrevWhitespace(lastCompositePrev); + } + } + if( prev.getElementType() == ElementType.WHITE_SPACE ) + return prev; + else + return getPrevWhitespace(prev); + } + else { + if (element.getTreeParent() == null) { + return null; + } + return getPrevWhitespace(element.getTreeParent()); + } + } + + public int getIndent(final TreeElement element, boolean includeNonSpace) { + if (element.getTreePrev() != null) { + TreeElement prev = element.getTreePrev(); + CompositeElement lastCompositePrev; + while (prev instanceof CompositeElement && !(prev instanceof XmlText)) { + lastCompositePrev = (CompositeElement)prev; + prev = ((CompositeElement)prev).lastChild; + if (prev == null) { // element.prev is "empty composite" + return getIndent(lastCompositePrev, includeNonSpace); + } + } + + String text = prev.getText(); + int index = Math.max(text.lastIndexOf('\n'), text.lastIndexOf('\r')); + + if (index >= 0) { + return getIndent(text.substring(index + 1), includeNonSpace); + } + + if (includeNonSpace) { + return getIndent(prev, includeNonSpace) + getIndent(text, includeNonSpace); + } + + if (element.getElementType() == ElementType.CODE_BLOCK) { + CompositeElement parent = element.getTreeParent(); + if (parent.getElementType() == ElementType.BLOCK_STATEMENT) { + parent = parent.getTreeParent(); + } + if (parent.getElementType() != ElementType.CODE_BLOCK) { + //Q: use some "anchor" part of parent for some elements? + // e.g. for method it could be declaration start, not doc-comment + return getIndent(parent, includeNonSpace); + } + } + else { + if (element.getElementType() == ElementType.LBRACE) { + return getIndent(element.getTreeParent(), includeNonSpace); + } + } + //Q: any other cases? + + CompositeElement parent = prev.getTreeParent(); + TreeElement child = prev; + while (parent != null) { + if (child.getTreePrev() != null) break; + child = parent; + parent = parent.getTreeParent(); + } + if (parent == null) { + return getIndent(text, includeNonSpace); + } + else { + if (prev.getTreeParent().getElementType() == ElementType.LABELED_STATEMENT) { + return getIndent(prev, true) + getIndent(text, true); + } + else + return getIndent(prev, includeNonSpace); + } + } + else { + if (element.getTreeParent() == null) { + return 0; + } + return getIndent(element.getTreeParent(), includeNonSpace); + } + } + + public static int addIndent(int indent) { + return modifyIndent(indent, INDENT_FACTOR, false); + } + + public static int modifyIndent(int old_indent, int change, boolean absolute) { + int indent = (absolute ? 0 : old_indent) + change; + if (indent < 0) indent = 0; + return indent; + } + + public int labelIndent(int old_indent) { + return modifyIndent(old_indent, + mySettings.getLabelIndentSize(getFileType()), + mySettings.getLabelIndentAbsolute(getFileType())); + } + + public int addContinuationIndent(int indent) { + return indent + mySettings.getContinuationIndentSize(getFileType()); + } + + public String fillIndent(int indent) { + int indentLevel = (indent + INDENT_FACTOR / 2) / INDENT_FACTOR; + int spaceCount = indent - indentLevel * INDENT_FACTOR; + int indentLevelSize = indentLevel * mySettings.getIndentSize(getFileType()); + int totalSize = indentLevelSize + spaceCount; + + StringBuffer buffer = new StringBuffer(); + if (mySettings.useTabCharacter(getFileType())) { + if (mySettings.isSmartTabs(getFileType())) { + int tabCount = indentLevelSize / mySettings.getTabSize(getFileType()); + int leftSpaces = indentLevelSize - tabCount * mySettings.getTabSize(getFileType()); + for (int i = 0; i < tabCount; i++) { + buffer.append('\t'); + } + for (int i = 0; i < leftSpaces + spaceCount; i++) { + buffer.append(' '); + } + } + else { + int size = totalSize; + while (size > 0) { + if (size >= mySettings.getTabSize(getFileType())) { + buffer.append('\t'); + size -= mySettings.getTabSize(getFileType()); + } + else { + buffer.append(' '); + size--; + } + } + } + } + else { + for (int i = 0; i < totalSize; i++) { + buffer.append(' '); + } + } + + return buffer.toString(); + } + + public int getIndent(String text, boolean includeNonSpace) { + int i; + for (i = text.length() - 1; i >= 0; i--) { + char c = text.charAt(i); + if (c == '\n' || c == '\r') break; + } + i++; + + int spaceCount = 0; + int tabCount = 0; + for (int j = i; j < text.length(); j++) { + char c = text.charAt(j); + if (c != '\t') { + if (!includeNonSpace && c != ' ') break; + spaceCount++; + } + else { + tabCount++; + } + } + + if (tabCount == 0) return spaceCount; + + int tabSize = mySettings.getTabSize(getFileType()); + int indentLevel = tabCount * tabSize / mySettings.getIndentSize(getFileType()); + return indentLevel * INDENT_FACTOR + spaceCount; + } + +//---------------------------------------------------------------------------------------------------- + + public TreeElement makeHorizontalSpace(CompositeElement parent, TreeElement child1, TreeElement child2, int size) { + return makeHorizontalSpace(parent, child1, child2, size, true); + } + + public TreeElement makeHorizontalSpace(CompositeElement parent, + TreeElement child1, + TreeElement child2, + int size, + boolean soft) { + if (soft) { + int lineBreaks = getLineBreakCount(parent, child1, child2); + if (lineBreaks > 0) { + boolean inCode = parent.getElementType() != ElementType.JAVA_FILE && parent.getElementType() != ElementType.CLASS; + int maxKeep = inCode ? mySettings.KEEP_BLANK_LINES_IN_CODE : mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS; + lineBreaks = Math.min(lineBreaks, maxKeep + 1); + if (lineBreaks == 1) { + lineBreaks = mySettings.KEEP_LINE_BREAKS ? 1 : 0; + } + if (lineBreaks > 0) { + return makeLineBreaks(parent, child1, child2, lineBreaks); + } + } + } + TreeElement leaf = child1; + if (child1 instanceof CompositeElement) { + ChameleonTransforming.transformChildren((CompositeElement)child1, true); + leaf = TreeUtil.findLastLeaf(child1); + } + if (leaf != null && leaf.getElementType() == ElementType.END_OF_LINE_COMMENT) { + return makeLineBreaks(parent, child1, child2, 1); + } + + String text; + if (size == 0) { + text = ""; + } + else { + if (size == 1) { + text = " "; + } + else { + text = ""; + for (int i = 0; i < size; i++) { + text += " "; + } + } + } + return makeSpace(parent, child1, child2, text); + } + + public static int getElementRightSideColumn(TreeElement elem) { + int len = 0; + do { + String text = elem.getText(); + int idx = text.lastIndexOf('\n'); + if (idx >= 0) { + len += text.length() - idx; + return len; + } + len += text.length(); + do { + TreeElement prev = elem.getTreePrev(); + if (prev != null) { + elem = prev; + break; + } + elem = elem.getTreeParent(); + } + while (elem != null); + } + while (elem != null); + + return len; + } + + public TreeElement makeVerticalSpace(CompositeElement parent, TreeElement child1, TreeElement child2, int size) { + return makeVerticalSpace(parent, child1, child2, size, true); + } + + private TreeElement makeVerticalSpace(CompositeElement parent, + TreeElement child1, + TreeElement child2, + int size, + boolean soft) { + if (soft) { + boolean inCode = parent.getElementType() != ElementType.JAVA_FILE && parent.getElementType() != ElementType.CLASS; + int maxKeep = inCode ? mySettings.KEEP_BLANK_LINES_IN_CODE : mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS; + int lineBreaks = getLineBreakCount(parent, child1, child2); + lineBreaks = Math.min(lineBreaks, maxKeep + 1); + lineBreaks = Math.max(lineBreaks, size + 1); + return makeLineBreaks(parent, child1, child2, lineBreaks); + } + else { + return makeLineBreaks(parent, child1, child2, size + 1); + } + } + + public TreeElement makeSpace(CompositeElement parent, TreeElement child1, TreeElement child2, String text) { + return makeSpace(parent, child1, child2, text, false); + } + +//---------------------------------------------------------------------------------------------------- + + public static String getSpaceText(CompositeElement parent, TreeElement child1, TreeElement child2) { + final LeafElement spaceElement = getSpaceElement(parent, child1, child2); + return spaceElement != null ? spaceElement.getText() : ""; + } + + public static LeafElement getSpaceElement(CompositeElement parent, TreeElement child1, TreeElement child2) { + final LeafElement leafElementAt = parent.findLeafElementAt(child1 != null ? child1.getStartOffsetInParent() + child1.getTextLength() : 0); + TreeElement check = leafElementAt; + while(check != null){ + if(check == child2) return null; + check = check.getTreeParent(); + } + if(leafElementAt == null || leafElementAt.getText().trim().length() > 0) return null; + return leafElementAt; + // + //LeafElement space = null; + //for (TreeElement child = child1 != null ? child1.getTreeNext() : ((parent != null) ? parent.firstChild : null); + // child != child2; + // child = child.getTreeNext()) { + // if (child instanceof CompositeElement && child.getTextLength() == 0) continue; + // LOG.assertTrue(child.getElementType() == ElementType.WHITE_SPACE); + // if (space != null) { + // LOG.assertTrue(false); + // } + // space = (LeafElement)child; + //} + //return space; + } + +//---------------------------------------------------------------------------------------------------- + + public int getLineBreakCount(CompositeElement parent, TreeElement child1, TreeElement child2) { + return StringUtil.getLineBreakCount(getSpaceText(parent, child1, child2)); + } + + public TreeElement makeLineBreaks(CompositeElement parent, TreeElement child1, TreeElement child2, int count) { + StringBuffer buffer = new StringBuffer(); + String lineSeparator = "\n"; + if (child1 == null) { + count--; + } + for (int i = 0; i < count; i++) { + buffer.append(lineSeparator); + } + String space = getSpaceText(parent, child1, child2); + int index = Math.max(space.lastIndexOf('\n'), space.lastIndexOf('\r')); + buffer.append(space.substring(index + 1)); + if (count > 0 && space.length() == 0 && mySettings.INSERT_FIRST_SPACE_IN_LINE) { + buffer.append(" "); // this prevents some elements (comments, labels) to stay at the first column + } + return makeSpace(parent, child1, child2, buffer.toString()); + } + +//---------------------------------------------------------------------------------------------------- + + public TreeElement makeSpace(CompositeElement parent, + TreeElement child1, + TreeElement child2, + String text, + boolean indentMultiline) { + LeafElement space = getSpaceElement(parent, child1, child2); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(parent); + int indentShift; + if (space == null) { + if (text.length() == 0) return child2; + LeafElement newSpace = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, text.toCharArray(), 0, text.length(), + charTableByTree, null); + ChangeUtil.addChild(parent, newSpace, child1 != null ? child1.getTreeNext() : parent.firstChild); + indentShift = getIndent(newSpace.getText(), true); + } + else { + final String oldSpace = space.getText(); + if (text.length() == 0) { + if (child1 != null && child2 != null) { + if (!canStickChildrenTogether(child1, child2)) { + return makeSpace(parent, child1, child2, " ", indentMultiline); + } + } + + ChangeUtil.removeChild(parent, space); + indentShift = -getIndent(oldSpace, true); + } + else { + if (text.length() == space.getTextLength()) { + int i; + for (i = 0; i < text.length(); i++) { + if (text.charAt(i) != space.charAt(i)) break; + } + if (i == text.length()) return child2; + } + TreeElement newSpace = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, text.toCharArray(), 0, text.length(), + charTableByTree, null); + ChangeUtil.replaceChild(space.getTreeParent(), space, newSpace); + indentShift = getIndent(newSpace.getText(), true) - getIndent(oldSpace, true); + } + } + if (indentMultiline) { + child2 = shiftIndentInside(child2, indentShift); + } + return child2; + } + + public boolean canStickChildrenTogether(TreeElement child1, TreeElement child2) { + LeafElement token1 = TreeUtil.findLastLeaf(child1); + LeafElement token2 = TreeUtil.findFirstLeaf(child2); + LOG.assertTrue(token1 != null); + LOG.assertTrue(token2 != null); + if (token1.getElementType() instanceof IJavaElementType && token2.getElementType() instanceof IJavaElementType) { + return canStickJavaTokens((PsiJavaToken)SourceTreeToPsiMap.treeElementToPsi(token1), + (PsiJavaToken)SourceTreeToPsiMap.treeElementToPsi(token2)); + } + else { + return true; //? + } + } + + private Map, Boolean> myCanStickJavaTokensMatrix = new HashMap, Boolean>(); + + public boolean canStickJavaTokens(PsiJavaToken token1, PsiJavaToken token2) { + IElementType type1 = token1.getTokenType(); + IElementType type2 = token2.getTokenType(); + + Pair pair = new Pair(type1, type2); + Boolean res = myCanStickJavaTokensMatrix.get(pair); + if (res == null) { + String text = token1.getText() + token2.getText(); + final LanguageLevel languageLevel = getProject() != null + ? LanguageLevel.HIGHEST + : PsiManager.getInstance(getProject()).getEffectiveLanguageLevel(); + Lexer lexer = new JavaLexer(languageLevel); + lexer.start(text.toCharArray(), 0, text.length()); + boolean canMerge = lexer.getTokenType() == type1; + res = Boolean.valueOf(canMerge); + myCanStickJavaTokensMatrix.put(pair, res); + } + return res.booleanValue(); + } + + public TreeElement normalizeIndent( final TreeElement dst ) { + if( !(dst instanceof CompositeElement) ) return dst; + + int newIndent = getIndent(dst); + + final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(dst).getContainingFile(); + FileElement fileElement = ((FileElement)SourceTreeToPsiMap.psiElementToTree(file)); + CharTable table = fileElement.getCharTable(); + indentSubtree((CompositeElement)dst, 0, newIndent, table); + + return dst; + } + + public void indentSubtree( final CompositeElement tree, final int oldIndent, final int newIndent, CharTable table) { + if( oldIndent == newIndent ) return; + + for( TreeElement son = tree.firstChild; son != null; ) { + if( son.getElementType() == ElementType.WHITE_SPACE ) { + final int indentLevelsDiff = newIndent/Helper.INDENT_FACTOR - oldIndent/Helper.INDENT_FACTOR; + final int indentSpacesDiff = newIndent%Helper.INDENT_FACTOR - oldIndent%Helper.INDENT_FACTOR; + + final String ws = son.getText(); + String newIndentString = indentWhitespace(ws, indentLevelsDiff, indentSpacesDiff); + + if( !ws.equals(newIndentString) ) { + TreeElement newWSElem = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, + newIndentString.toCharArray(), + 0, newIndentString.length(), table, null); + ChangeUtil.replaceChild((CompositeElement)tree, son, newWSElem); + son = newWSElem; + } + } + else if( son instanceof CompositeElement ) { + indentSubtree( (CompositeElement) son, oldIndent, newIndent, table); + } + son = son.getTreeNext(); + } + } + + public TreeElement shiftIndentInside(TreeElement element, int indentShift) { + if (indentShift == 0) return element; + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(element); + String text = element.getText(); + for (int offset = 0; offset < text.length(); offset++) { + char c = text.charAt(offset); + if (c == '\n' || c == '\r') { + int offset1; + for (offset1 = offset + 1; offset1 < text.length(); offset1++) { + c = text.charAt(offset1); + if (c != ' ' && c != '\t') break; + } + if (c == '\n' || c == '\r') continue; + String space = text.substring(offset + 1, offset1); + int indent = getIndent(space, true); + int newIndent = indent + indentShift; + newIndent = Math.max(newIndent, 0); + String newSpace = fillIndent(newIndent); + + TreeElement leaf = element.findLeafElementAt(offset); + if (leaf.getElementType() != ElementType.WHITE_SPACE + && leaf.getElementType() != ElementType.C_STYLE_COMMENT + && leaf.getElementType() != ElementType.JSP_TEMPLATE_DATA + && leaf.getElementType() != ElementType.JSP_DIRECTIVE_WHITE_SPACE + && leaf.getElementType() != ElementType.JSP_ACTION_WHITE_SPACE + && leaf.getElementType() != ElementType.DOC_COMMENT_DATA + && leaf.getElementType() != ElementType.XML_DATA_CHARACTERS + && leaf.getElementType() != ElementType.XML_ATTRIBUTE_VALUE_TOKEN + && leaf.getElementType() != ElementType.XML_COMMENT_CHARACTERS) { + LOG.error("Error", + new String[]{ + leaf.getElementType().toString(), + "Type: " + leaf.getElementType() + " text: " + leaf.getText() + }); + } + + if (offset1 < text.length()) { + TreeElement next = element.findLeafElementAt(offset1); + if ((next.getElementType() == ElementType.END_OF_LINE_COMMENT || next.getElementType() == ElementType.C_STYLE_COMMENT) && + next != element) { + if (mySettings.KEEP_FIRST_COLUMN_COMMENT) { + int commentIndent = getIndent(next, true); + if (commentIndent == 0) continue; + } + } + else if (next.getElementType() == ElementType.XML_DATA_CHARACTERS) { + continue; + } + } + + int leafOffset = getStartOffset(element, leaf); + if (leaf.getElementType() == ElementType.DOC_COMMENT_DATA && leafOffset + leaf.getTextLength() == offset + 1) { + TreeElement next = element.findLeafElementAt(offset + 1); + if (next.getElementType() == ElementType.WHITE_SPACE) { + leaf = next; + leafOffset = getStartOffset(element, leaf); + } + else { + if (newSpace.length() > 0) { + LeafElement newLeaf = Factory.createSingleLeafElement(ElementType.WHITE_SPACE, newSpace.toCharArray(), 0, + newSpace.length(), charTableByTree, null); + ChangeUtil.addChild(next.getTreeParent(), newLeaf, next); + } + text = text.substring(0, offset + 1) + newSpace + text.substring(offset1); + continue; + } + } + + int startOffset = offset + 1 - leafOffset; + int endOffset = offset1 - leafOffset; + if (!LOG.assertTrue(0 <= startOffset && startOffset <= endOffset && endOffset <= leaf.getTextLength())) { + continue; + } + String leafText = leaf.getText(); + String newLeafText = leafText.substring(0, startOffset) + newSpace + leafText.substring(endOffset); + if (newLeafText.length() > 0) { + LeafElement newLeaf = Factory.createSingleLeafElement(leaf.getElementType(), newLeafText.toCharArray(), 0, + newLeafText.length(), charTableByTree, null); + if (leaf.getTreeParent() != null) { + ChangeUtil.replaceChild(leaf.getTreeParent(), leaf, newLeaf); + } + if (leaf == element) { + element = newLeaf; + } + } + else { + CompositeElement parent = leaf.getTreeParent(); + if (parent != null) { + ChangeUtil.removeChild(parent, leaf); + } + } + text = text.substring(0, offset + 1) + newSpace + text.substring(offset1); + } + } + return element; + } + + public boolean isSpaceAtStartOfLine(CompositeElement parent, TreeElement child1, TreeElement child2) { + String space = getSpaceText(parent, child1, child2); + if (space.indexOf('\n') >= 0 || space.indexOf('\r') >= 0) return true; + if (child1 != null) { + String text = child1.getText(); + char c = text.charAt(text.length() - 1); + if (c == '\n' || c == '\r') return true; + } + //if (parent.parent == null && child1 == null && child2.getTextRange().getStartOffset() == space.length()) { // at the beginning of file + if (SourceTreeToPsiMap.treeElementToPsi(parent) instanceof PsiFile && child1 == null) { // at the beginning of file + return true; + } + return false; + } + + private int getIndentOffset( int indent ) { + return indent % INDENT_FACTOR + (indent / INDENT_FACTOR) * mySettings.getIndentSize(getFileType()); + } + + public String indentWhitespace( String whitespace, int indentLevelsDiff, int indentSpacesDiff ) { + final int posLF = whitespace.lastIndexOf('\n'); + if( (indentLevelsDiff == 0 && indentSpacesDiff == 0) || posLF < 0 ) return whitespace; + + final int oldIndent = getIndent(whitespace, false); + + int newLevels = oldIndent / INDENT_FACTOR + indentLevelsDiff; + int newSpaces = oldIndent % INDENT_FACTOR + indentSpacesDiff; + + if( newLevels < 0 ) { + newSpaces -= (-newLevels) * mySettings.getIndentSize(getFileType()); + newLevels = 0; + } + + if( newSpaces < 0 ) { + final int levels = (-newSpaces) / mySettings.getIndentSize(getFileType()); + newLevels -= levels + 1; + newSpaces += (levels + 1) * mySettings.getIndentSize(getFileType()); + + if( newLevels < 0 ) { // Too large unindent... Indentation has to be broken + newSpaces = 0; + newLevels = 0; + } + } + + return whitespace.substring(0,posLF+1) + fillIndent(newLevels * INDENT_FACTOR + newSpaces); + } + + public FileType getFileType() { + return myFileType; + } + + public Project getProject() { + return myProject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ImportHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ImportHelper.java new file mode 100644 index 00000000000..077d62e485b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ImportHelper.java @@ -0,0 +1,718 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable; +import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.EmptyLineEntry; +import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.Entry; +import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.PackageEntry; +import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.resolve.ResolveClassUtil; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.jsp.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.util.IncorrectOperationException; +import gnu.trove.TObjectIntHashMap; +import gnu.trove.TObjectIntProcedure; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class ImportHelper{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.ImportHelper"); + + private CodeStyleSettings mySettings; + + public ImportHelper(CodeStyleSettings settings){ + mySettings = settings; + } + + public PsiImportList prepareOptimizeImportsResult(CodeStyleManager codeStyleManager, final PsiJavaFile file) { + PsiManager manager = file.getManager(); + + final Set namesToImportStaticly = new HashSet(); + String[] names = collectNamesToImport(file, namesToImportStaticly); // Note: this array may contain ".*" for unresolved imports! + Arrays.sort(names); + + ArrayList namesList = new ArrayList(); + ImportLayoutTable table = mySettings.IMPORT_LAYOUT_TABLE; + if (table != null){ + int[] entriesForName = new int[names.length]; + for(int i = 0; i < names.length; i++){ + entriesForName[i] = findEntryIndex(names[i]); + } + + Entry[] entries = table.getEntries(); + for(int i = 0; i < entries.length; i++){ + Entry entry = entries[i]; + if (entry instanceof PackageEntry){ + for(int j = 0; j < names.length; j++){ + if (entriesForName[j] == i){ + namesList.add(names[j]); + names[j] = null; + } + } + } + } + } + for(int i = 0; i < names.length; i++){ + String name = names[i]; + if (name != null) namesList.add(name); + } + names = namesList.toArray(new String[namesList.size()]); + + TObjectIntHashMap packageToCountMap = new TObjectIntHashMap(); + TObjectIntHashMap classToCountMap = new TObjectIntHashMap(); + for(int i = 0; i < names.length; i++){ + String name = names[i]; + String packageOrClassName = getPackageOrClassName(name); + if (packageOrClassName.length() == 0) continue; + if (namesToImportStaticly.contains(name)) { + int count = classToCountMap.get(packageOrClassName); + classToCountMap.put(packageOrClassName, count + 1); + } + else { + int count = packageToCountMap.get(packageOrClassName); + packageToCountMap.put(packageOrClassName, count + 1); + } + } + + final Set classesOrPackagesToImportOnDemand = new HashSet(); + class MyVisitorProcedure implements TObjectIntProcedure { + boolean myIsVisitingPackages; + + public MyVisitorProcedure(boolean isVisitingPackages) { + myIsVisitingPackages = isVisitingPackages; + } + + public boolean execute(Object a, int count) { + String packageOrClassName = (String)a; + if (isToUseImportOnDemand(packageOrClassName, count, !myIsVisitingPackages)){ + classesOrPackagesToImportOnDemand.add(packageOrClassName); + } + return true; + } + } + classToCountMap.forEachEntry(new MyVisitorProcedure(false)); + packageToCountMap.forEachEntry(new MyVisitorProcedure(true)); + + Set classesToUseSingle = findSingleImports(file, names, classesOrPackagesToImportOnDemand, namesToImportStaticly); + + final PsiElementFactory factory = manager.getElementFactory(); + try { + final String text = buildImportListText(names, classesOrPackagesToImportOnDemand, classesToUseSingle, namesToImportStaticly); + String ext = StdFileTypes.JAVA.getDefaultExtension(); + final PsiJavaFile dummyFile = (PsiJavaFile)factory.createFileFromText("_Dummy_." + ext, text); + codeStyleManager.reformat(dummyFile); + + PsiImportList resultList = dummyFile.getImportList(); + PsiImportList oldList = file.getImportList(); + if (resultList.textMatches(oldList)) return null; + return resultList; + } + catch(IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + private HashSet findSingleImports(final PsiJavaFile file, + String[] names, + final Set onDemandImports, Set namesToImportStaticly) { + final GlobalSearchScope resolveScope = file.getResolveScope(); + HashSet namesToUseSingle = new HashSet(); + final String thisPackageName = file.getPackageName(); + final Set implicitlyImportedPackages = new HashSet(Arrays.asList(file.getImplicitlyImportedPackages())); + final PsiManager manager = file.getManager(); + for(int i = 0; i < names.length; i++){ + String name = names[i]; + String prefix = getPackageOrClassName(name); + if (prefix.length() == 0) continue; + final boolean isImplicitlyImported = implicitlyImportedPackages.contains(prefix); + if (!onDemandImports.contains(prefix) && !isImplicitlyImported) continue; + String shortName = PsiNameHelper.getShortClassName(name); + + String thisPackageClass = thisPackageName.length() > 0 ? thisPackageName + "." + shortName : shortName; + if (manager.findClass(thisPackageClass, resolveScope) != null){ + namesToUseSingle.add(name); + continue; + } + if (!isImplicitlyImported) { + String langPackageClass = "java.lang." + shortName; //TODO : JSP! + if (manager.findClass(langPackageClass, resolveScope) != null){ + namesToUseSingle.add(name); + continue; + } + } + for(Iterator iterator = onDemandImports.iterator(); iterator.hasNext();){ + String onDemandName = iterator.next(); + if (prefix.equals(onDemandName)) continue; + if (namesToImportStaticly.contains(name)) { + PsiClass aClass = manager.findClass(onDemandName, resolveScope); + if (aClass != null) { + PsiField field = aClass.findFieldByName(shortName, true); + if (field != null && field.hasModifierProperty(PsiModifier.STATIC)) { + namesToUseSingle.add(name); + } else { + PsiClass inner = aClass.findInnerClassByName(shortName, true); + if (inner != null && inner.hasModifierProperty(PsiModifier.STATIC)) { + namesToUseSingle.add(name); + } else { + PsiMethod[] methods = aClass.findMethodsByName(shortName, true); + for (int j = 0; j < methods.length; j++) { + PsiMethod method = methods[j]; + if (method.hasModifierProperty(PsiModifier.STATIC)) { + namesToUseSingle.add(name); + } + } + } + } + } + } + else { + PsiClass aClass = manager.findClass(onDemandName + "." + shortName, resolveScope); + if (aClass != null){ + namesToUseSingle.add(name); + } + } + } + } + return namesToUseSingle; + } + + private String buildImportListText(String[] names, + final Set packagesOrClassesToImportOnDemand, + final Set namesToUseSingle, Set namesToImportStaticly) { + final HashSet importedPackagesOrClasses = new HashSet(); + final StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < names.length; i++){ + String name = names[i]; + String packageOrClassName = getPackageOrClassName(name); + final boolean implicitlyImported = "java.lang".equals(packageOrClassName); + boolean useOnDemand = implicitlyImported || packagesOrClassesToImportOnDemand.contains(packageOrClassName); + if (useOnDemand && namesToUseSingle.contains(name)){ + useOnDemand = false; + } + if (useOnDemand && (importedPackagesOrClasses.contains(packageOrClassName) || implicitlyImported)) continue; + buffer.append("import "); + if (namesToImportStaticly.contains(name)) buffer.append("static "); + if (useOnDemand){ + importedPackagesOrClasses.add(packageOrClassName); + buffer.append(packageOrClassName); + buffer.append(".*"); + } + else{ + buffer.append(name); + } + buffer.append(";\n"); + } + + final String text = buffer.toString(); + return text; + } + + /** + * Adds import if it is needed. + * @return false when the FQ-name have to be used in code (e.g. when conflicting imports already exist) + */ + public boolean addImport(PsiFile file, PsiClass refClass){ + if (file instanceof PsiImportHolder){ + return ((PsiImportHolder)file).importClass(refClass); + } + + if (!(file instanceof PsiJavaFile) && !(file instanceof JspFile)) return false; + + PsiManager manager = file.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + PsiResolveHelper helper = manager.getResolveHelper(); + Project project = manager.getProject(); + + String className = refClass.getQualifiedName(); + if (className == null) return true; + String packageName = getPackageOrClassName(className); + String shortName = PsiNameHelper.getShortClassName(className); + + PsiClass conflictSingleRef = findSingleImportByShortName(file, shortName); + if (conflictSingleRef != null){ + return conflictSingleRef.getQualifiedName().equals(className); + } + + PsiClass curRefClass = helper.resolveReferencedClass(shortName, file); + if (refClass.equals(curRefClass)){ + return true; + } + + boolean useOnDemand = true; + if (packageName.length() == 0){ + useOnDemand = false; + } + + PsiElement conflictPackageRef = findImportOnDemand(file, packageName); + if (conflictPackageRef != null) { + useOnDemand = false; + } + + ArrayList classesToReimport = new ArrayList(); + + PsiJavaCodeReferenceElement[] importRefs = getImportsFromPackage(file, packageName); + if (useOnDemand){ + if (mySettings.USE_SINGLE_CLASS_IMPORTS){ + if (importRefs.length + 1 < mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND + && !mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(packageName) + ){ + useOnDemand = false; + } + } + // name of class we try to import is the same as of the class defined in this file + if (curRefClass != null) { + useOnDemand = true; + } + // check conflicts + if (useOnDemand){ + PsiElement[] onDemandRefs = file.getOnDemandImports(false, true); + if (onDemandRefs.length > 0){ + PsiPackage aPackage = manager.findPackage(packageName); + if (aPackage != null){ + PsiDirectory[] dirs = aPackage.getDirectories(); + for(int i = 0; i < dirs.length; i++){ + PsiDirectory dir = dirs[i]; + PsiFile[] files = dir.getFiles(); // do not iterate classes - too slow when not loaded + for(int j = 0; j < files.length; j++){ + PsiFile aFile = files[j]; + if (aFile instanceof PsiJavaFile){ + String name = aFile.getVirtualFile().getNameWithoutExtension(); + for(int k = 0; k < onDemandRefs.length; k++){ + PsiElement ref = onDemandRefs[k]; + String refName = ref instanceof PsiClass ? ((PsiClass) ref).getQualifiedName() : ((PsiPackage) ref).getQualifiedName(); + String conflictClassName = refName + "." + name; + GlobalSearchScope resolveScope = file.getResolveScope(); + PsiClass conflictClass = manager.findClass(conflictClassName, resolveScope); + if (conflictClass != null && helper.isAccessible(conflictClass, file, null)){ + String conflictClassName2 = aPackage.getQualifiedName() + "." + name; + PsiClass conflictClass2 = manager.findClass(conflictClassName2, resolveScope); + if (conflictClass2 != null && helper.isAccessible(conflictClass2, file, null)){ + PsiSearchHelper searchHelper = manager.getSearchHelper(); + PsiReference[] usages = searchHelper.findReferences(conflictClass, new LocalSearchScope(file), false); + if (usages.length > 0){ + classesToReimport.add(conflictClass); + } + } + } + } + } + } + } + } + } + } + } + + try{ + if (file instanceof PsiJavaFile){ + PsiImportList importList = ((PsiJavaFile)file).getImportList(); + PsiImportStatement statement; + if (useOnDemand){ + statement = factory.createImportStatementOnDemand(packageName); + } + else{ + statement = factory.createImportStatement(refClass); + } + importList.add(statement); + if (useOnDemand){ + for(int i = 0; i < importRefs.length; i++) { + PsiJavaCodeReferenceElement ref = importRefs[i]; + LOG.assertTrue(ref.getParent() instanceof PsiImportStatement); + if (!ref.isValid()) continue; // todo[dsl] Q? + classesToReimport.add(ref.resolve()); + PsiImportStatement importStatement = (PsiImportStatement)ref.getParent(); + importStatement.delete(); + } + } + } + else if (file instanceof JspFileImpl){ + JspFileImpl jspFile = (JspFileImpl)file; + + boolean added = false; + JspDirective[] directives = jspFile.getPageDirectives(); + for(int i = 0; i < directives.length; i++) { + JspDirective directive = directives[i]; + JspAttribute importAttr = JspUtil.findAttributeByName(directive.getAttributes(), "import"); + if (importAttr != null){ + JspImportValue importValue = (JspImportValue)importAttr.getValueElement(); + if (importValue != null){ + if (useOnDemand){ + PsiPackage aPackage = refClass.getContainingFile().getContainingDirectory().getPackage(); + importValue.addOnDemandImport(aPackage.getQualifiedName()); + } + else{ + importValue.addSingleClassImport(refClass.getQualifiedName()); + } + added = true; + break; + } + } + } + + if (!added){ + // no import directive yet + JspDirective directive = manager.getJspElementFactory().createDirectiveFromText("<%@ page import=\"\"%>"); + directive = (JspDirective)CodeStyleManager.getInstance(project).reformat(directive); + directive = (JspDirective)jspFile.add(directive); + JspAttribute importAttr = JspUtil.findAttributeByName(directive.getAttributes(), "import"); + JspImportValue importValue = (JspImportValue)importAttr.getValueElement(); + if (useOnDemand){ + PsiPackage aPackage = refClass.getContainingFile().getContainingDirectory().getPackage(); + importValue.addOnDemandImport(aPackage.getQualifiedName()); + } + else{ + importValue.addSingleClassImport(refClass.getQualifiedName()); + } + } + + if (useOnDemand){ + for(int i = 0; i < importRefs.length; i++) { + PsiJavaCodeReferenceElement ref = importRefs[i]; + if (ref.getContainingFile() == jspFile) { + classesToReimport.add(ref.resolve()); + ref.delete(); + } + } + } + } + + for(int i = 0; i < classesToReimport.size(); i++){ + PsiClass aClass = (PsiClass)classesToReimport.get(i); + if (aClass != null){ + addImport(file, aClass); + } + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + return true; + } + + private static PsiJavaCodeReferenceElement[] getImportsFromPackage(PsiFile file, String packageName){ + PsiClass[] refs = file.getSingleClassImports(true); + List array = new ArrayList(); + for(int i = 0; i < refs.length; i++){ + String className = refs[i].getQualifiedName(); + if (getPackageOrClassName(className).equals(packageName)){ + final PsiJavaCodeReferenceElement ref = file.findImportReferenceTo(refs[i]); + if (ref != null) { + array.add(ref); + } + } + } + return array.toArray(new PsiJavaCodeReferenceElement[array.size()]); + } + + private static PsiClass findSingleImportByShortName(PsiFile file, String shortClassName){ + PsiClass[] refs = file.getSingleClassImports(true); + for(int i = 0; i < refs.length; i++){ + PsiClass ref = refs[i]; + String className = ref.getQualifiedName(); + if (PsiNameHelper.getShortClassName(className).equals(shortClassName)){ + return ref; + } + } + return null; + } + + private static PsiPackage findImportOnDemand(PsiFile file, String packageName){ + PsiElement[] refs = file.getOnDemandImports(false, true); + for(int i = 0; i < refs.length; i++){ + PsiElement ref = refs[i]; + if (ref instanceof PsiPackage && ((PsiPackage) ref).getQualifiedName().equals(packageName)){ + return (PsiPackage) ref; + } + } + return null; + } + + public TreeElement getDefaultAnchor(PsiImportList list, PsiImportStatementBase statement){ + PsiJavaCodeReferenceElement ref = statement.getImportReference(); + if (ref == null) return null; + + int entryIndex = findEntryIndex(statement); + PsiImportStatementBase[] allStatements = list.getAllImportStatements(); + int[] entries = new int[allStatements.length]; + ArrayList array = new ArrayList(); + for(int i = 0; i < allStatements.length; i++){ + PsiImportStatementBase statement1 = allStatements[i]; + int entryIndex1 = findEntryIndex(statement1); + entries[i] = entryIndex1; + if (entryIndex1 == entryIndex){ + array.add(statement1); + } + } + PsiImportStatementBase[] statements = array.toArray(new PsiImportStatementBase[array.size()]); + + if (statements.length == 0){ + int index; + for(index = entries.length - 1; index >= 0; index--){ + if (entries[index] < entryIndex) break; + } + index++; + return index < entries.length ? SourceTreeToPsiMap.psiElementToTree(allStatements[index]) : null; + } + else{ + //TODO : alphabetical sorting + String text = ref.getCanonicalText(); + if (statement.isOnDemand()){ + text += "."; + } + int index = text.length(); + while(true){ + index = text.lastIndexOf('.', index - 1); + if (index < 0) break; + String prefix = text.substring(0, index + 1); + PsiImportStatementBase last = null; + PsiImportStatementBase lastStrict = null; + for(int i = 0; i < statements.length; i++) { + PsiImportStatementBase statement1 = statements[i]; + PsiJavaCodeReferenceElement ref1 = statement1.getImportReference(); + if (ref1 != null){ + String text1 = ref1.getCanonicalText(); + if (statement1.isOnDemand()){ + text1 += "."; + } + if (text1.startsWith(prefix)){ + last = statement1; + if (text1.indexOf('.', prefix.length()) < 0){ + lastStrict = statement1; + } + } + } + } + + if (lastStrict != null){ + return (SourceTreeToPsiMap.psiElementToTree(lastStrict)).getTreeNext(); + } + if (last != null){ + return (SourceTreeToPsiMap.psiElementToTree(last)).getTreeNext(); + } + } + return null; + } + } + + public int getEmptyLinesBetween(PsiImportStatementBase statement1, PsiImportStatementBase statement2){ + int index1 = findEntryIndex(statement1); + int index2 = findEntryIndex(statement2); + if (index1 == index2) return 0; + if (index1 > index2) { + int t = index1; + index1 = index2; + index2 = t; + } + Entry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries(); + int maxSpace = 0; + for(int i = index1 + 1; i < index2; i++){ + if (entries[i] instanceof EmptyLineEntry){ + int space = 0; + do{ + space++; + } while(entries[++i] instanceof EmptyLineEntry); + maxSpace = Math.max(maxSpace, space); + } + } + return maxSpace; + } + + private boolean isToUseImportOnDemand(String packageName, int classCount, boolean isStaticImportNeeded){ + if (!mySettings.USE_SINGLE_CLASS_IMPORTS) return true; + int limitCount = isStaticImportNeeded ? mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND : + mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND; + if (classCount >= limitCount) return true; + if (packageName.length() == 0) return false; + CodeStyleSettings.PackageTable table = mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND; + if (table == null) return false; + return table.contains(packageName); + } + + private int findEntryIndex(String packageName){ + Entry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries(); + PackageEntry bestEntry = null; + int bestEntryIndex = -1; + for(int i = 0; i < entries.length; i++){ + Entry entry = entries[i]; + if (entry instanceof PackageEntry){ + PackageEntry packageEntry = (PackageEntry)entry; + if (packageEntry.matchesPackageName(packageName)){ + if (bestEntry == null){ + bestEntry = packageEntry; + bestEntryIndex = i; + } + else{ + String package1 = bestEntry.getPackageName(); + String package2 = packageEntry.getPackageName(); + if (!bestEntry.isWithSubpackages()) continue; + if (!packageEntry.isWithSubpackages() || package2.length() > package1.length()) { + bestEntry = packageEntry; + bestEntryIndex = i; + } + } + } + } + } + return bestEntryIndex; + } + + public int findEntryIndex(PsiImportStatementBase statement){ + String packageName; + PsiJavaCodeReferenceElement ref = statement.getImportReference(); + if (ref == null) return -1; + if (statement.isOnDemand()){ + packageName = ref.getCanonicalText(); + } + else{ + String className = ref.getCanonicalText(); + packageName = getPackageOrClassName(className); + } + return findEntryIndex(packageName); + } + + private String[] collectNamesToImport(PsiFile file, Set namesToImportStaticly){ + HashSet names = new HashSet(); + String packageName = null; + if (file instanceof PsiJavaFile){ + packageName = ((PsiJavaFile)file).getPackageName(); + } + addNamesToImport(names, (CompositeElement)SourceTreeToPsiMap.psiElementToTree(file), packageName, namesToImportStaticly); + addUnresolvedImportNames(names, file, namesToImportStaticly); + + return names.toArray(new String[names.size()]); + } + + private void addNamesToImport(HashSet names, + CompositeElement scope, + String thisPackageName, + Set namesToImportStaticly){ + if (scope.getElementType() == ElementType.IMPORT_LIST) return; + + ChameleonTransforming.transformChildren(scope); + for(TreeElement child = scope.firstChild; child != null; child = child.getTreeNext()){ + if (child instanceof CompositeElement) { + addNamesToImport(names, (CompositeElement)child, thisPackageName, namesToImportStaticly); + + if (child.getElementType() == ElementType.JAVA_CODE_REFERENCE || child.getElementType() == ElementType.REFERENCE_EXPRESSION) { + final CompositeElement compositeChild = (CompositeElement)child; + if (compositeChild.findChildByRole(ChildRole.QUALIFIER) == null) { + + if (child.getElementType() == ElementType.JAVA_CODE_REFERENCE + && ((PsiJavaCodeReferenceElementImpl)child).getKind() == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) { + continue; + } + + PsiJavaCodeReferenceElement psiReference = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(child); + ResolveResult resolveResult = psiReference.advancedResolve(true); + PsiElement refElement = resolveResult.getElement(); + if (refElement == null) { + refElement = ResolveClassUtil.resolveClass(psiReference); // might be uncomplete code + } + + if (refElement != null) { + if (refElement instanceof PsiClass) { + PsiClass refClass = (PsiClass)refElement; + PsiElement parent = refClass.getParent(); + if (parent instanceof PsiClass) { + if (isInnerVisibleByShortName(refClass, psiReference)) continue; + } + else if (!(parent instanceof PsiFile)) continue; + + String qName = refClass.getQualifiedName(); + if (hasPackage(qName, thisPackageName)) continue; + names.add(qName); + } + else { + PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); + if (currentFileResolveScope instanceof PsiImportStaticStatement) { + PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement)currentFileResolveScope; + String name = importStaticStatement.getImportReference().getCanonicalText(); + if (importStaticStatement.isOnDemand()) { + String refName = psiReference.getReferenceName(); + if (refName != null) name = name + "." + refName; + } + names.add(name); + namesToImportStaticly.add(name); + } + } + } + } + } + } + } + } + + private static void addUnresolvedImportNames(HashSet set, PsiFile file, Set namesToImportStaticly) { + if (file instanceof PsiJavaFile){ + PsiImportStatementBase[] imports = ((PsiJavaFile)file).getImportList().getAllImportStatements(); + for(int i = 0; i < imports.length; i++){ + PsiImportStatementBase anImport = imports[i]; + PsiJavaCodeReferenceElement ref = anImport.getImportReference(); + if (ref == null) continue; + PsiElement refElement = ref.resolve(); + if (refElement == null){ + String text = ref.getCanonicalText(); + if (anImport.isOnDemand()){ + text += ".*"; + } + if (anImport instanceof PsiImportStaticStatement) { + namesToImportStaticly.add(text); + } + set.add(text); + } + } + } + else if (file instanceof JspFile){ + //TODO + } + } + + public static boolean isImplicitlyImported(String className, PsiFile file) { + String[] packageNames = file.getImplicitlyImportedPackages(); + for(int i = 0; i < packageNames.length; i++){ + String packageName = packageNames[i]; + if (hasPackage(className, packageName)) return true; + } + return false; + } + + public static boolean hasPackage(String className, String packageName){ + if (!className.startsWith(packageName)) return false; + if (className.length() == packageName.length()) return false; + if (packageName.length() > 0 && className.charAt(packageName.length()) != '.') return false; + return className.indexOf('.', packageName.length() + 1) < 0; + } + + private static String getPackageOrClassName(String className){ + int dotIndex = className.lastIndexOf('.'); + return dotIndex < 0 ? "" : className.substring(0, dotIndex); + } + + private static boolean isInnerVisibleByShortName(PsiClass inner, PsiElement place){ + PsiClass outerClass = inner.getContainingClass(); + PsiElement parent = place; + while(!(parent instanceof PsiFile)){ + if (parent instanceof PsiClass){ + if (parent == outerClass || ((PsiClass)parent).isInheritor(outerClass, true)) return true; + } + parent = parent.getParent(); + } + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/IndentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/IndentImpl.java new file mode 100644 index 00000000000..cb9defb710e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/IndentImpl.java @@ -0,0 +1,73 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.psi.codeStyle.Indent; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.openapi.fileTypes.FileType; + +public class IndentImpl implements Indent{ + private final CodeStyleSettings mySettings; + private final int myIndentLevel; + private final int mySpaceCount; + private final FileType myFileType; + + public IndentImpl(CodeStyleSettings settings, int indentLevel, int spaceCount, FileType fileType) { + mySettings = settings; + myIndentLevel = indentLevel; + mySpaceCount = spaceCount; + myFileType = fileType; + } + + int getIndentLevel() { + return myIndentLevel; + } + + int getSpaceCount() { + return mySpaceCount; + } + + public boolean equals(Object o) { + if (!(o instanceof IndentImpl)) return false; + + IndentImpl indent = (IndentImpl)o; + + if (myIndentLevel != indent.myIndentLevel) return false; + if (mySpaceCount != indent.mySpaceCount) return false; + if (!mySettings.equals(indent.mySettings)) return false; + + return true; + } + + public int hashCode() { + return myIndentLevel + mySpaceCount; + } + + public boolean isGreaterThan(Indent indent) { + return getSize() > ((IndentImpl)indent).getSize(); + } + + public Indent min(Indent anotherIndent) { + return isGreaterThan(anotherIndent) ? anotherIndent : this; + } + + public Indent max(Indent anotherIndent) { + return isGreaterThan(anotherIndent) ? this : anotherIndent; + } + + public Indent add(Indent indent) { + IndentImpl indent1 = (IndentImpl)indent; + return new IndentImpl(mySettings, myIndentLevel + indent1.myIndentLevel, mySpaceCount + indent1.mySpaceCount, myFileType); + } + + public Indent subtract(Indent indent) { + IndentImpl indent1 = (IndentImpl)indent; + return new IndentImpl(mySettings, myIndentLevel - indent1.myIndentLevel, mySpaceCount - indent1.mySpaceCount, myFileType); + } + + public boolean isZero() { + return myIndentLevel == 0 && mySpaceCount == 0; + } + + private int getSize(){ + return myIndentLevel * mySettings.getIndentSize(myFileType) + mySpaceCount; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java new file mode 100644 index 00000000000..abc754af7e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java @@ -0,0 +1,227 @@ +package com.intellij.psi.impl.source.codeStyle; + +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl; +import com.intellij.psi.impl.source.SourceJavaCodeReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.InheritanceUtil; + +import java.util.ArrayList; + +class ReferenceAdjuster implements Constants { + private final CodeStyleSettings mySettings; + private final ImportHelper myImportHelper; + private final boolean myUseFqClassnamesInJavadoc; + private final boolean myUseFqClassNames; + + public ReferenceAdjuster(CodeStyleSettings settings, boolean useFqInJavadoc, boolean useFqInCode) { + mySettings = settings; + myImportHelper = new ImportHelper(mySettings); + myUseFqClassnamesInJavadoc = useFqInJavadoc; + myUseFqClassNames = useFqInCode; + } + + public ReferenceAdjuster(CodeStyleSettings settings) { + this(settings, settings.USE_FQ_CLASS_NAMES_IN_JAVADOC, settings.USE_FQ_CLASS_NAMES); + } + + public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) { + IElementType elementType = element.getElementType(); + if (elementType == JAVA_CODE_REFERENCE || elementType == REFERENCE_EXPRESSION){ + if (elementType == JAVA_CODE_REFERENCE || element.getTreeParent().getElementType() == REFERENCE_EXPRESSION || uncompleteCode) { + final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(element); + final PsiTypeElement[] typeParameters = ref.getParameterList().getTypeParameterElements(); + for (int i = 0; i < typeParameters.length; i++) { + process(SourceTreeToPsiMap.psiElementToTree(typeParameters[i]), addImports, uncompleteCode); + } + + boolean rightKind = true; + if (elementType == JAVA_CODE_REFERENCE){ + int kind = ((PsiJavaCodeReferenceElementImpl)element).getKind(); + rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || + kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; + } + + if (rightKind) { + boolean isInsideDocComment = TreeUtil.findParent(element, ElementType.DOC_COMMENT) != null; + boolean isShort = !((SourceJavaCodeReference)element).isQualified(); + if (!makeFQ(isInsideDocComment)){ + if (isShort) return element; // short name already, no need to change + } + PsiElement refElement; + if (!uncompleteCode){ + refElement = ref.resolve(); + } + else{ + PsiResolveHelper helper = element.getManager().getResolveHelper(); + refElement = helper.resolveReferencedClass( + ((SourceJavaCodeReference)element).getClassNameText(), + SourceTreeToPsiMap.treeElementToPsi(element) + ); + } + if (refElement instanceof PsiClass){ + if (makeFQ(isInsideDocComment)){ + String qName = ((PsiClass)refElement).getQualifiedName(); + if (qName == null) return element; + PsiFile file = SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile(); + if (ImportHelper.isImplicitlyImported(qName, file)){ + if (isShort) return element; + return makeShortReference((CompositeElement)element, (PsiClass)refElement, addImports, uncompleteCode); + } + if (file instanceof PsiJavaFile){ + String thisPackageName = ((PsiJavaFile)file).getPackageName(); + if (ImportHelper.hasPackage(qName, thisPackageName)){ + if (!isShort) { + return makeShortReference( + (CompositeElement)element, + (PsiClass)refElement, + addImports, + uncompleteCode + ); + } + } + } + return replaceReferenceWithFQ((CompositeElement)element, (PsiClass)refElement); + } + else{ + return makeShortReference((CompositeElement)element, (PsiClass)refElement, addImports, uncompleteCode); + } + } + } + } + } + + if (element instanceof CompositeElement){ + ChameleonTransforming.transformChildren((CompositeElement)element); + for(TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()){ + child = process(child, addImports, uncompleteCode); + } + } + + return element; + } + + private boolean makeFQ(boolean isInsideDocComment) { + if (isInsideDocComment) { + return myUseFqClassnamesInJavadoc; + } else { + return myUseFqClassNames; + } + } + + public void processRange(TreeElement element, int startOffset, int endOffset) { + ArrayList array = new ArrayList(); + addReferencesInRange(array, element, startOffset, endOffset); + for(int i = 0; i < array.size(); i++){ + TreeElement ref = array.get(i); + if (SourceTreeToPsiMap.treeElementToPsi(ref).isValid()){ + process(ref, true, true); + } + } + } + + private static void addReferencesInRange(ArrayList array, TreeElement parent, int startOffset, int endOffset) { + if (parent.getElementType() == ElementType.JAVA_CODE_REFERENCE || parent.getElementType() == ElementType.REFERENCE_EXPRESSION){ + array.add(parent); + return; + } + if (parent instanceof CompositeElement){ + ChameleonTransforming.transformChildren((CompositeElement)parent); + int offset = 0; + for(TreeElement child = ((CompositeElement)parent).firstChild; child != null; child = child.getTreeNext()){ + int length = child.getTextLength(); + if (startOffset <= offset + length && offset <= endOffset){ + if (startOffset <= offset && offset + length <= endOffset){ + array.add(child); + } + addReferencesInRange(array, child, startOffset - offset, endOffset - offset); + } + offset += length; + } + } + } + + private CompositeElement makeShortReference( + CompositeElement reference, + PsiClass refClass, + boolean addImports, + boolean uncompleteCode + ) { + if (refClass.getContainingClass() != null){ + PsiClass parentClass = refClass.getContainingClass(); + PsiJavaCodeReferenceElement psiReference = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(reference); + PsiManager manager = parentClass.getManager(); + if (manager.getResolveHelper().isAccessible(refClass, psiReference, null)) { + for(TreeElement parent = reference.getTreeParent(); parent != null; parent = parent.getTreeParent()){ + PsiElement parentPsi = SourceTreeToPsiMap.treeElementToPsi(parent); + if (parentPsi instanceof PsiClass){ + PsiClass inner = ((PsiClass)parentPsi).findInnerClassByName(psiReference.getReferenceName(), true); + if (inner != null) { + if (inner == refClass) return replaceReferenceWithShort(reference); + return reference; + } + if (InheritanceUtil.isInheritorOrSelf((PsiClass)parentPsi, parentClass, true)){ + return replaceReferenceWithShort(reference); + } + } + } + } + + if (!mySettings.INSERT_INNER_CLASS_IMPORTS) { + final TreeElement qualifier = reference.findChildByRole(ChildRole.QUALIFIER); + if (qualifier != null){ + + makeShortReference((CompositeElement)qualifier, parentClass, addImports, uncompleteCode); + } + return reference; + } + } + + PsiFile file = SourceTreeToPsiMap.treeElementToPsi(reference).getContainingFile(); + PsiManager manager = file.getManager(); + PsiResolveHelper helper = manager.getResolveHelper(); + if (addImports){ + if (!myImportHelper.addImport(file, refClass)){ + return reference; + } + if (isSafeToShortenReference(reference, refClass, helper)) { + reference = replaceReferenceWithShort(reference); + } + } + else{ + PsiClass curRefClass = helper.resolveReferencedClass( + refClass.getName(), + SourceTreeToPsiMap.treeElementToPsi(reference) + ); + if (manager.areElementsEquivalent(refClass, curRefClass)){ + reference = replaceReferenceWithShort(reference); + } + } + return reference; + } + + private static boolean isSafeToShortenReference (CompositeElement reference, PsiClass refClass, PsiResolveHelper helper) { + PsiClass newRefClass = helper.resolveReferencedClass( + refClass.getName(), + SourceTreeToPsiMap.treeElementToPsi(reference) + ); + return refClass.getManager().areElementsEquivalent(refClass, newRefClass); + } + + private static CompositeElement replaceReferenceWithShort(CompositeElement reference) { + ((SourceJavaCodeReference) reference).dequalify(); + + return reference; + } + + private static CompositeElement replaceReferenceWithFQ(CompositeElement reference, PsiClass refClass) { + ((SourceJavaCodeReference)reference).fullyQualify(refClass); + return reference; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java new file mode 100644 index 00000000000..1a74d7706bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java @@ -0,0 +1,214 @@ +package com.intellij.psi.impl.source.codeStyle.javadoc; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.util.IncorrectOperationException; + +/** + * @author max + */ +public class CommentFormatter { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.psi.impl.source.codeStyle.javadoc.CommentFormatter"); + + private CodeStyleSettings mySettings; + private JDParser myParser; + private Project myProject; + + public CommentFormatter(Project project) { + mySettings = CodeStyleSettingsManager.getSettings(project); + myParser = new JDParser(mySettings); + myProject = project; + } + + public CodeStyleSettings getSettings() { + return mySettings; + } + + public JDParser getParser() { + return myParser; + } + + public TreeElement formatComment(TreeElement child) { + if (!getSettings().ENABLE_JAVADOC_FORMATTING) return child; + PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(child); + + if (psiElement instanceof PsiDocComment && psiElement.getParent() instanceof PsiDocCommentOwner && psiElement == ((PsiDocCommentOwner)psiElement.getParent()).getDocComment()) { + PsiDocCommentOwner parent = (PsiDocCommentOwner)psiElement.getParent(); + processElementComment(parent); + return SourceTreeToPsiMap.psiElementToTree(parent.getDocComment()); + } + + return child; + } + + public void process(TreeElement element) { + if (!getSettings().ENABLE_JAVADOC_FORMATTING) return; + + PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element); + processElementComment(psiElement); + } + + private void processElementComment(PsiElement psiElement) { + if (psiElement instanceof PsiClass) { + String newCommentText = formatClassComment((PsiClass)psiElement); + replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); + } + else if (psiElement instanceof PsiMethod) { + String newCommentText = formatMethodComment((PsiMethod)psiElement); + replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); + } + else if (psiElement instanceof PsiField) { + String newCommentText = formatFieldComment((PsiField)psiElement); + replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); + } + } + + private void replaceDocComment(String newCommentText, final PsiDocCommentOwner psiDocCommentOwner) { + final PsiDocComment oldComment = psiDocCommentOwner.getDocComment(); + if (newCommentText != null) newCommentText = stripSpaces(newCommentText); + if (newCommentText == null || oldComment == null || newCommentText.equals(oldComment.getText())) { + return; + } + try { + PsiComment newComment = PsiManager.getInstance(myProject).getElementFactory().createCommentFromText( + newCommentText, null); + oldComment.replace(newComment); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private static String stripSpaces(String text) { + String[] lines = LineTokenizer.tokenize(text.toCharArray(), false); + StringBuffer buf = new StringBuffer(text.length()); + for (int i = 0; i < lines.length; i++) { + if (i > 0) buf.append('\n'); + buf.append(rTrim(lines[i])); + } + return buf.toString(); + } + + private static String rTrim(String text) { + int idx = text.length(); + while (idx > 0) { + if (!Character.isWhitespace(text.charAt(idx-1))) break; + idx--; + } + return text.substring(0, idx); + } + + private String formatClassComment(PsiClass psiClass) { + final String info = getOrigCommentInfo(psiClass); + if (info == null) return null; + + JDComment comment = getParser().parse(info, new JDClassComment(this)); + return comment.generate(getIndent(psiClass)); + } + + private String formatMethodComment(PsiMethod psiMethod) { + final String info = getOrigCommentInfo(psiMethod); + if (info == null) return null; + + JDComment comment = getParser().parse(info, new JDMethodComment(this)); + return comment.generate(getIndent(psiMethod)); + } + + private String formatFieldComment(PsiField psiField) { + final String info = getOrigCommentInfo(psiField); + if (info == null) return null; + + JDComment comment = getParser().parse(info, new JDFieldComment(this)); + return comment.generate(getIndent(psiField)); + } + + /** + * Returns the original comment info of the specified element or null + * + * @param element the specified element + * @return text chunk + */ + private static String getOrigCommentInfo(PsiDocCommentOwner element) { + StringBuffer sb = new StringBuffer(); + PsiElement e = element.getFirstChild(); + if (!(e instanceof PsiComment)) { + // no comments for this element + return null; + } + else { + boolean first = true; + for (; ;) { + if (e instanceof PsiDocComment) { + PsiComment cm = (PsiComment)e; + String text = cm.getText(); + if (text.startsWith("//")) { + if (!first) sb.append('\n'); + sb.append(text.substring(2).trim()); + } + else if (text.startsWith("/*")) { + if (text.charAt(2) == '*') { + text = text.substring(3, Math.max(3, text.length() - 2)); + } + else { + text = text.substring(2, Math.max(2, text.length() - 2)); + } + sb.append(text); + } + } + else if (!(e instanceof PsiWhiteSpace) && !(e instanceof PsiComment)) { + break; + } + first = false; + e = e.getNextSibling(); + } + + return sb.toString(); + } + } + + /** + * For the specified element returns its indentation + * + * @param element the specified element + * @return indentation as string + */ + private static String getIndent(PsiElement element) { + PsiElement e = element.getFirstChild(); + PsiWhiteSpace lastWS = null; + for (; ; e = e.getNextSibling()) { + if (e instanceof PsiWhiteSpace) { + lastWS = (PsiWhiteSpace)e; + } + else if (e instanceof PsiComment) { + lastWS = null; + } + else { + break; + } + } + + e = lastWS == null ? element.getPrevSibling() : lastWS; + if (!(e instanceof PsiWhiteSpace)) return ""; + PsiWhiteSpace ws = (PsiWhiteSpace)e; + String t = ws.getText(); + int l = t.length(); + int i = l; + while (--i >= 0) { + char ch = t.charAt(i); + if (ch == '\n' || ch == '\r') break; + } + if (i < 0) return t; + i++; + if (i == l) return ""; + return t.substring(i); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java new file mode 100644 index 00000000000..3e852e14b2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.source.codeStyle.javadoc; + +import java.util.ArrayList; + +/** + * Class comment + * + * @author Dmitry Skavish + */ +public class JDClassComment extends JDComment { + public JDClassComment(CommentFormatter formatter) { + super(formatter); + } + + private ArrayList authorsList; + private String version; + + protected void generateSpecial(String prefix, StringBuffer sb) { + if (!isNull(authorsList)) { + for (int i = 0; i < authorsList.size(); i++) { + String s = (String) authorsList.get(i); + sb.append(prefix); + sb.append("@author "); + sb.append(myFormatter.getParser().splitIntoCLines(s, prefix + " ", false)); + } + } + if (!isNull(version)) { + sb.append(prefix); + sb.append("@version "); + sb.append(myFormatter.getParser().splitIntoCLines(version, prefix + " ", false)); + } + } + + public void addAuthor(String author) { + if (authorsList == null) { + authorsList = new ArrayList(); + } + authorsList.add(author); + } + + public ArrayList getAuthorsList() { + return authorsList; + } + + public void setAuthorsList(ArrayList authorsList) { + this.authorsList = authorsList; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java new file mode 100644 index 00000000000..4df5dc9a8b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java @@ -0,0 +1,193 @@ +package com.intellij.psi.impl.source.codeStyle.javadoc; + +import java.util.ArrayList; + +/** + * @author max + */ + +/** + * @author Dmitry Skavish + */ +public class JDComment { + protected CommentFormatter myFormatter; + + String description; + protected ArrayList unknownList; + protected ArrayList seeAlsoList; + protected String since; + String deprecated; + + //protected LinkedHashMap xdocTagMap = new LinkedHashMap(); + + public JDComment(CommentFormatter formatter) { + myFormatter = formatter; + } + + protected static boolean isNull(String s) { + return s == null || s.trim().length() == 0; + } + + protected static boolean isNull(ArrayList l) { + return l == null || l.size() == 0; + } + + public String generate(String indent) { + String prefix = indent + " * "; + + StringBuffer sb = new StringBuffer(); +// sb.append("/**\n"); + + int start = sb.length(); + + if (!isNull(description)) { + sb.append(myFormatter.getParser().splitIntoCLines(description, prefix)); + + if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_DESCRIPTION) { + sb.append(prefix); + sb.append('\n'); + } + } + + generateSpecial(prefix, sb); + + if (!isNull(unknownList) && myFormatter.getSettings().JD_KEEP_INVALID_TAGS) { + for (int i = 0; i < unknownList.size(); i++) { + String s = (String) unknownList.get(i); + sb.append(myFormatter.getParser().splitIntoCLines(s, prefix)); + } + } + + /* + if( xdocTagMap.size() > 0 ) { + Iterator it = xdocTagMap.values().iterator(); + while( it.hasNext() ) { + ArrayList list = (ArrayList) it.next(); + for( int i = 0; i max && l <= max_name_length) max = l; + } + } + + max = Math.max(max, min_name_length); + + // create filler + StringBuffer fill = new StringBuffer(prefix.length() + tag.length() + max + 1); + fill.append(prefix); + int k = max + 1 + tag.length(); + for (int i = 0; i < k; i++) fill.append(' '); + + for (int i = 0; i < list.size(); i++) { + NameDesc nd = (NameDesc) list.get(i); + if (isNull(nd.desc) && !generate_empty_tags) continue; + if (align_comments) { + sb.append(prefix); + sb.append(tag); + sb.append(nd.name); + + if (nd.name.length() > max_name_length) { + sb.append('\n'); + sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, fill, true)); + } + else { + int len = max - nd.name.length() + 1; + for (int j = 0; j < len; j++) sb.append(' '); + sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, fill, false)); + } + } + else { + sb.append(myFormatter.getParser().splitIntoCLines(tag + nd.name + " " + nd.desc, prefix, true)); + } + } + } + + protected void generateSpecial(String prefix, StringBuffer sb) { + + if (parmsList != null) { + int before = sb.length(); + generateList(prefix, sb, parmsList, PARAM_TAG, + myFormatter.getSettings().JD_ALIGN_PARAM_COMMENTS, + myFormatter.getSettings().JD_MIN_PARM_NAME_LENGTH, + myFormatter.getSettings().JD_MAX_PARM_NAME_LENGTH, + myFormatter.getSettings().JD_KEEP_EMPTY_PARAMETER + ); + + int size = sb.length() - before; + if (size > 0 && myFormatter.getSettings().JD_ADD_BLANK_AFTER_PARM_COMMENTS) { + sb.append(prefix); + sb.append('\n'); + } + } + + if (returnTag != null) { + if (returnTag.trim().length() != 0 || myFormatter.getSettings().JD_KEEP_EMPTY_RETURN) { + sb.append(prefix); + sb.append("@return "); + sb.append(myFormatter.getParser().splitIntoCLines(returnTag, prefix + " ", false)); + if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_RETURN) { + sb.append(prefix); + sb.append('\n'); + } + } + } + + if (throwsList != null) { + String tag = myFormatter.getSettings().JD_USE_THROWS_NOT_EXCEPTION ? THROWS_TAG : EXCEPTION_TAG; + generateList(prefix, sb, throwsList, tag, + myFormatter.getSettings().JD_ALIGN_EXCEPTION_COMMENTS, + myFormatter.getSettings().JD_MIN_EXCEPTION_NAME_LENGTH, + myFormatter.getSettings().JD_MAX_EXCEPTION_NAME_LENGTH, + myFormatter.getSettings().JD_KEEP_EMPTY_EXCEPTION + ); + } + } + + public String getReturnTag() { + return returnTag; + } + + public void setReturnTag(String returnTag) { + this.returnTag = returnTag; + } + + public NameDesc getParameter(String name) { + return getNameDesc(name, parmsList); + } + + public void removeParameter(NameDesc nd) { + if (parmsList == null) return; + parmsList.remove(nd); + } + + public void removeThrow(NameDesc nd) { + if (throwsList == null) return; + throwsList.remove(nd); + } + + private static NameDesc getNameDesc(String name, ArrayList list) { + if (list == null) return null; + for (int i = 0; i < list.size(); i++) { + NameDesc parameter = (NameDesc) list.get(i); + if (parameter.name.equals(name)) return parameter; + } + return null; + } + + public ArrayList getParmsList() { + return parmsList; + } + + public void addParameter(String name, String description) { + if (parmsList == null) { + parmsList = new ArrayList(); + } + parmsList.add(new NameDesc(name, description)); + } + + public ArrayList getThrowsList() { + return throwsList; + } + + public void addThrow(String className, String description) { + if (throwsList == null) { + throwsList = new ArrayList(); + } + throwsList.add(new NameDesc(className, description)); + } + + public NameDesc getThrow(String name) { + return getNameDesc(name, throwsList); + } + + public void setParmsList(ArrayList parmsList) { + this.parmsList = parmsList; + } + + public void setThrowsList(ArrayList throwsList) { + this.throwsList = throwsList; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java new file mode 100644 index 00000000000..02aaf789ff6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java @@ -0,0 +1,458 @@ +package com.intellij.psi.impl.source.codeStyle.javadoc; + +import com.intellij.psi.codeStyle.CodeStyleSettings; + +import java.util.ArrayList; +import java.util.StringTokenizer; + +/** + * Javadoc parser + * + * @author Dmitry Skavish + */ +public class JDParser { + private CodeStyleSettings mySettings; + + public JDParser(CodeStyleSettings settings) { + mySettings = settings; + } + + private static final char lineSeparator = '\n'; + + public JDComment parse(String text, JDComment c) { + if (text == null) return c; + + ArrayList markers = new ArrayList(); + ArrayList l = toArray(text, "\n", markers); + if (l == null) return c; + int size = l.size(); + if (size == 0) return c; + + // preprocess strings - removes first '*' + for (int i = 0; i < size; i++) { + String line = (String)l.get(i); + line = line.trim(); + if (line.length() > 0) { + if (line.charAt(0) == '*') { + if (((Boolean)markers.get(i)).booleanValue()) { + if (line.length() > 1 && line.charAt(1) == ' ') { + line = line.substring(2); + } + else { + line = line.substring(1); + } + } + else { + line = line.substring(1).trim(); + } + } + } + l.set(i, line); + } + + StringBuffer sb = new StringBuffer(); + String tag = null; + for (int i = 0; i <= size; i++) { + String line = i == size ? null : (String)l.get(i); + if (i == size || line.length() > 0) { + if (i == size || line.charAt(0) == '@') { + if (tag == null) { + c.setDescription(sb.toString()); + } + else { + int j = 0; + String myline = sb.toString(); + for (; j < tagParsers.length; j++) { + TagParser parser = tagParsers[j]; + if (parser.parse(tag, myline, c)) break; + } + if (j == tagParsers.length) { + c.addUnknownTag("@" + tag + " " + myline); + } + } + + if (i < size) { + int last_idx = line.indexOf(' '); + if (last_idx == -1) { + tag = line.substring(1); + line = ""; + } + else { + tag = line.substring(1, last_idx); + line = line.substring(last_idx).trim(); + } + sb.setLength(0); + sb.append(line); + } + } + else { + if (sb.length() > 0) { + sb.append(lineSeparator); + } + sb.append(line); + } + } + else { + if (sb.length() > 0) { + sb.append(lineSeparator); + } + } + } + + return c; + } + + /** + * Breaks the specified string by lineseparator into array of strings + * + * @param s the specified string + * @return array of strings (lines) + */ + public ArrayList toArrayByNL(String s) { + return toArray(s, "\n", null); + } + + /** + * Breaks the specified string by comma into array of strings + * + * @param s the specified string + * @return list of strings + */ + public ArrayList toArrayByComma(String s) { + return toArray(s, ",", null); + } + + /** + * Breaks the specified string by the specified separators into array of strings + * + * @param s the specified string + * @param separators the specified separators + * @param markers if this parameter is not null then it will be filled with Boolean values: + * true if the correspoding line in returned list is inside <pre> tag, + * false if it is outside + * @return array of strings (lines) + */ + private ArrayList toArray(String s, String separators, ArrayList markers) { + if (s == null) return null; + s = s.trim(); + if (s.length() == 0) return null; + boolean p2nl = markers != null && mySettings.JD_P_AT_EMPTY_LINES; + ArrayList list = new ArrayList(); + StringTokenizer st = new StringTokenizer(s, separators, true); + boolean first = true; + int preCount = 0; + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (separators.indexOf(token) >= 0) { + if (!first) { + list.add(""); + if (markers != null) markers.add(Boolean.valueOf(preCount > 0)); + } + first = false; + } + else { + first = true; + if (p2nl) { + boolean istagp = token.equals("

    ") || token.equals("

    "); + if (istagp) { + list.add(""); + markers.add(Boolean.valueOf(preCount > 0)); + continue; + } + } + if (preCount == 0) token = token.trim(); + + list.add(token); + + if (markers != null) { + if (token.indexOf("

    ") >= 0) preCount++;
    +          markers.add(Boolean.valueOf(preCount > 0));
    +          if (token.indexOf("
    ") >= 0) preCount--; + } + + } + } + return list; + } + + public static String toLines(ArrayList l) { + if (l == null || l.size() == 0) return null; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < l.size(); i++) { + String s = (String)l.get(i); + if (sb.length() > 0) { + sb.append(lineSeparator); + } + sb.append(s); + } + return sb.toString(); + } + + public static String toCommaSeparated(ArrayList l) { + if (l == null || l.size() == 0) return null; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < l.size(); i++) { + String s = (String)l.get(i); + if (i != 0) { + sb.append(", "); + } + sb.append(s); + } + return sb.toString(); + } + + /** + * Breaks the specified string by stripping all lineseparators and then wrapping the text to the + * specified width + * + * @param s the specified string + * @param width width of the wrapped text + * @return array of strings (lines) + */ + private ArrayList toArrayWrapping(String s, int width) { + if (s == null) return null; + s = s.trim(); + if (s.length() == 0) return null; + + ArrayList listParagraphs = new ArrayList(); + StringBuffer sb = new StringBuffer(); + ArrayList markers = new ArrayList(); + ArrayList list = toArray(s, "\n", markers); + Boolean[] marks = (Boolean[])markers.toArray(new Boolean[markers.size()]); + markers.clear(); + for (int i = 0; i < list.size(); i++) { + String s1 = (String)list.get(i); + if (marks[i].booleanValue()) { + if (sb.length() != 0) { + listParagraphs.add(sb.toString()); + markers.add(Boolean.valueOf(false)); + sb.setLength(0); + } + listParagraphs.add(s1); + markers.add(marks[i]); + } + else { + if (s1.length() == 0) { + if (sb.length() != 0) { + listParagraphs.add(sb.toString()); + markers.add(Boolean.valueOf(false)); + sb.setLength(0); + } + listParagraphs.add(""); + markers.add(marks[i]); + } + else { + if (sb.length() != 0) sb.append(' '); + sb.append(s1); + } + } + } + if (sb.length() != 0) { + listParagraphs.add(sb.toString()); + markers.add(Boolean.valueOf(false)); + } + + list.clear(); + // each line is a praragraph, which has to be wrapped later + for (int i = 0; i < listParagraphs.size(); i++) { + String seq = (String)listParagraphs.get(i); + + boolean isMarked = ((Boolean)markers.get(i)).booleanValue(); + + if (seq.length() == 0) { + // keep empty lines + list.add(""); + } + else { + for (; ;) { + if (seq.length() < width) { + // keep remaining line and proceed with next paragraph + seq = isMarked ? seq : seq.trim(); + list.add(seq); + break; + } + else { + // wrap paragraph + + int wrapPos = Math.min(seq.length() - 1, width); + wrapPos = seq.lastIndexOf(' ', wrapPos); + + // either the only word is too long or it looks better to wrap + // after the border + if (wrapPos <= 2 * width / 3) { + wrapPos = Math.min(seq.length() - 1, width); + wrapPos = seq.indexOf(' ', wrapPos); + } + + // wrap now + if (wrapPos >= seq.length() - 1 || wrapPos == -1) { + seq = isMarked ? seq : seq.trim(); + list.add(seq); + break; + } + else { + list.add(seq.substring(0, wrapPos)); + seq = seq.substring(wrapPos + 1); + } + } + } + } + } + + return list; + } + + static abstract class TagParser { + + abstract boolean parse(String tag, String line, JDComment c); + } + + private static TagParser[] tagParsers = { + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = "see".equals(tag); + if (isMyTag) { + c.addSeeAlso(line); + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = "since".equals(tag); + if (isMyTag) { + c.setSince(line); + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = c instanceof JDClassComment && "version".equals(tag); + if (isMyTag) { + ((JDClassComment)c).setVersion(line); + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = "deprecated".equals(tag); + if (isMyTag) { + c.setDeprecated(line); + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = c instanceof JDMethodComment && "return".equals(tag); + if (isMyTag) { + JDMethodComment mc = (JDMethodComment)c; + mc.setReturnTag(line); + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = c instanceof JDMethodComment && "param".equals(tag); + if (isMyTag) { + JDMethodComment mc = (JDMethodComment)c; + int idx; + for (idx = 0; idx < line.length(); idx++) { + char ch = line.charAt(idx); + if (Character.isWhitespace(ch)) break; + } + if (idx == line.length()) { + mc.addParameter(line, ""); + } + else { + String name = line.substring(0, idx); + String desc = line.substring(idx).trim(); + mc.addParameter(name, desc); + } + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = c instanceof JDMethodComment && ("throws".equals(tag) || "exception".equals(tag)); + if (isMyTag) { + JDMethodComment mc = (JDMethodComment)c; + int idx; + for (idx = 0; idx < line.length(); idx++) { + char ch = line.charAt(idx); + if (Character.isWhitespace(ch)) break; + } + if (idx == line.length()) { + mc.addThrow(line, ""); + } + else { + String name = line.substring(0, idx); + String desc = line.substring(idx).trim(); + mc.addThrow(name, desc); + } + } + return isMyTag; + } + }, + new TagParser() { + boolean parse(String tag, String line, JDComment c) { + boolean isMyTag = c instanceof JDClassComment && "author".equals(tag); + if (isMyTag) { + JDClassComment cl = (JDClassComment)c; + cl.addAuthor(line.trim()); + } + return isMyTag; + } + }, +/* new TagParser() { + boolean parse( String tag, String line, JDComment c ) { + XDTag xdtag = XDTag.parse(tag, line); + if( xdtag != null ) { + c.addXDocTag(xdtag); + } + return xdtag != null; + } + },*/ + }; + + protected StringBuffer splitIntoCLines(String s, String prefix) { + return splitIntoCLines(s, prefix, true); + } + + protected StringBuffer splitIntoCLines(String s, String prefix, boolean add_prefix_to_first_line) { + return splitIntoCLines(s, new StringBuffer(prefix), add_prefix_to_first_line); + } + + protected StringBuffer splitIntoCLines(String s, StringBuffer prefix, boolean add_prefix_to_first_line) { + StringBuffer sb = new StringBuffer(); + if (add_prefix_to_first_line) { + sb.append(prefix); + } + ArrayList list = mySettings.WRAP_COMMENTS + ? toArrayWrapping(s, mySettings.RIGHT_MARGIN - prefix.length()) + : toArray(s, "\n", new ArrayList()); + if (list == null) { + sb.append('\n'); + } + else { + for (int i = 0; i < list.size(); i++) { + String line = (String)list.get(i); + if (line.length() == 0 && !mySettings.JD_KEEP_EMPTY_LINES) continue; + if (i != 0) sb.append(prefix); + if (line.length() == 0 && mySettings.JD_P_AT_EMPTY_LINES) { + sb.append("

    "); + } + else { + sb.append(line); + } + sb.append('\n'); + } + } + + return sb; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java new file mode 100644 index 00000000000..b1c63f9bdb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java @@ -0,0 +1,28 @@ +package com.intellij.psi.impl.source.codeStyle.javadoc; + +/** +* +* @author Dmitry Skavish +*/ +public class NameDesc { + + public String name; + public String desc; + private String type; + + public NameDesc(String name, String desc) { + this.name = name; + this.desc = desc; + } + + public NameDesc(String name, String desc, String type) { + this.name = name; + this.desc = desc; + this.type = type; + } + + public String toString() { + if (type == null) return name; + return name + ": " + type; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlDocumentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlDocumentImpl.java new file mode 100644 index 00000000000..c9ed2527054 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlDocumentImpl.java @@ -0,0 +1,57 @@ +package com.intellij.psi.impl.source.html; + +import com.intellij.psi.impl.source.xml.XmlDocumentImpl; +import com.intellij.psi.impl.source.html.dtd.HtmlNSDescriptorImpl; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlDoctype; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.PsiManager; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.util.XmlUtil; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Nov 2, 2004 + * Time: 8:02:23 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlDocumentImpl extends XmlDocumentImpl { + private CachedValue myDescriptor; + + public HtmlDocumentImpl() { + super(HTML_DOCUMENT); + } + + public XmlTag getRootTag() { + return (XmlTag)findElementByTokenType(HTML_TAG); + } + + XmlNSDescriptor getDocumentDescriptor() { + if (myDescriptor==null) { + XmlDoctype doctype = getProlog().getDoctype(); + final XmlNSDescriptor xhtmlDescr; + + if (doctype == null || doctype.getDtdUri()==null) { + xhtmlDescr = PsiManager.getInstance(getProject()).getJspElementFactory().getXHTMLDescriptor(); + } else { + final XmlFile xmlFile = XmlUtil.findXmlFile(XmlUtil.getContainingFile(this), doctype.getDtdUri()); + if (xmlFile==null) return null; + xhtmlDescr = (XmlNSDescriptor)xmlFile.getDocument().getMetaData(); + } + myDescriptor = getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + final HtmlNSDescriptorImpl value = new HtmlNSDescriptorImpl(xhtmlDescr); + + return new Result( + value, + value.getDependences() + ); + } + }, false); + } + return myDescriptor.getValue(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlFileImpl.java new file mode 100644 index 00000000000..eab2409a984 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlFileImpl.java @@ -0,0 +1,38 @@ +package com.intellij.psi.impl.source.html; + +import com.intellij.psi.impl.source.xml.XmlFileImpl; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.fileTypes.FileType; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 02.11.2004 + * Time: 23:42:00 + * To change this template use File | Settings | File Templates. + */ +public class HtmlFileImpl extends XmlFileImpl { + public HtmlFileImpl(PsiManagerImpl manager, VirtualFile file) { + super(manager, file, XmlElementType.HTML_FILE, XmlElementType.HTML_FILE_TEXT); + } + + public HtmlFileImpl(PsiManagerImpl manager, String name, char[] text, int startOffset, int endOffset, FileType fileType) { + super(manager, name, text, startOffset, endOffset, fileType, XmlElementType.HTML_FILE); + } + + public String toString() { + return "HtmlFile:"+getName(); + } + + public XmlDocument getDocument() { + CompositeElement treeElement = calcTreeElement(); + ChameleonTransforming.transformChildren(treeElement); + return (XmlDocument)treeElement.findChildByRoleAsPsiElement(ChildRole.HTML_DOCUMENT); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlTagImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlTagImpl.java new file mode 100644 index 00000000000..100d6623809 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/HtmlTagImpl.java @@ -0,0 +1,104 @@ +package com.intellij.psi.impl.source.html; + +import com.intellij.psi.impl.source.xml.XmlTagImpl; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.html.HtmlTag; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.util.XmlUtil; + +import java.util.List; +import java.util.ArrayList; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Nov 2, 2004 + * Time: 3:52:51 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlTagImpl extends XmlTagImpl implements HtmlTag { + private XmlNSDescriptor documentDescriptor; + + public HtmlTagImpl() { + super(HTML_TAG); + } + + public XmlTag[] findSubTags(String name, String namespace) { + final XmlTag[] subTags = getSubTags(); + final List result = new ArrayList(); + + for (int i = 0; i < subTags.length; i++) { + final XmlTag subTag = subTags[i]; + if(namespace == null){ + final String tagName = subTag.getName().toLowerCase(); + + if(name == null || name.equals(tagName)){ + result.add(subTag); + } + } + else if (namespace.equals(subTag.getNamespace()) && + (name == null || name.equals(subTag.getLocalName())) + ) { + result.add(subTag); + } + } + + return result.toArray(new XmlTag[result.size()]); + } + + public XmlAttribute findAttribute(String name, String namespace) { + final XmlAttribute[] attributes = getAttributes(); + + for (int i = 0; i < attributes.length; i++) { + final XmlAttribute attribute = attributes[i]; + + if(namespace == null){ + final String attrName = attribute.getName().toLowerCase(); + + if(name == null || name.equals(attrName)){ + return attribute; + } + } + else if (namespace.equals(attribute.getNamespace()) && + (name == null || name.equals(attribute.getLocalName())) + ) { + return attribute; + } + } + + return null; + } + + public String getAttributeValue(String qname) { + qname = qname.toLowerCase(); + return super.getAttributeValue(qname); + } + + protected void cacheOneAttributeValue(String name, String value) { + name = name.toLowerCase(); + super.cacheOneAttributeValue(name, value); + } + + public String getAttributeValue(String name, String namespace) { + name = name.toLowerCase(); + return super.getAttributeValue(name, namespace); + } + + public String getNamespace() { + return XmlUtil.XHTML_URI; + } + + public XmlNSDescriptor getNSDescriptor(String namespace, boolean strict) { + if (documentDescriptor==null) { + HtmlDocumentImpl document = PsiTreeUtil.getParentOfType(this,HtmlDocumentImpl.class); + documentDescriptor = document.getDocumentDescriptor(); + } + return documentDescriptor; + } + + public String toString() { + return "HtmlTag:" + getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java new file mode 100644 index 00000000000..feb6e44fcf2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java @@ -0,0 +1,92 @@ +package com.intellij.psi.impl.source.html.dtd; + +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Nov 2, 2004 + * Time: 4:20:32 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlAttributeDescriptorImpl implements XmlAttributeDescriptor { + private XmlAttributeDescriptor delegate; + + public HtmlAttributeDescriptorImpl() { + assert false; + } + + public HtmlAttributeDescriptorImpl(XmlAttributeDescriptor _delegate) { + delegate = _delegate; + } + + public String getDefaultName() { + return delegate.getDefaultName(); + } + + public boolean isRequired() { + return delegate.isRequired(); + } + + public boolean isFixed() { + return delegate.isFixed(); + } + + public boolean hasIdType() { + return delegate.hasIdType(); + } + + public boolean hasIdRefType() { + return delegate.hasIdRefType(); + } + + public String getDefaultValue() { + return delegate.getDefaultValue(); + } + + //todo: refactor to hierarchy of value descriptor? + public boolean isEnumerated() { + return delegate.isEnumerated(); + } + + public String[] getEnumeratedValues() { + return delegate.getEnumeratedValues(); + } + + public String validateValue(XmlElement context, String value) { + value = value.toLowerCase(); + return delegate.validateValue(context, value); + } + + public PsiElement getDeclaration() { + return delegate.getDeclaration(); + } + + public boolean processDeclarations(PsiElement context, + PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastElement, + PsiElement place) { + return delegate.processDeclarations(context, processor, substitutor, lastElement, place); + } + + public String getName(PsiElement context) { + return delegate.getName(context); + } + + public String getName() { + return delegate.getName(); + } + + public void init(PsiElement element) { + delegate.init(element); + } + + public Object[] getDependences() { + return new Object[0]; //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlElementDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlElementDescriptorImpl.java new file mode 100644 index 00000000000..81a9d3a0cc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlElementDescriptorImpl.java @@ -0,0 +1,148 @@ +package com.intellij.psi.impl.source.html.dtd; + +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; + +import java.util.HashMap; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Nov 2, 2004 + * Time: 4:19:28 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlElementDescriptorImpl implements XmlElementDescriptor { + private XmlElementDescriptor delegate; + private HashMap cachedDescriptors; + private HashMap cachedAttributeDescriptors; + + public HtmlElementDescriptorImpl(XmlElementDescriptor _delegate) { + delegate = _delegate; + } + + public HtmlElementDescriptorImpl() { + assert false; + } + + public String getQualifiedName() { + return delegate.getQualifiedName(); + } + + public String getDefaultName() { + return delegate.getDefaultName(); + } + + private XmlElementDescriptor[] myElementDescriptors = null; + + public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { + + if (myElementDescriptors==null) { + XmlElementDescriptor[] elementsDescriptors = delegate.getElementsDescriptors(context); + myElementDescriptors = new XmlElementDescriptor[elementsDescriptors.length]; + + for (int i = 0; i < elementsDescriptors.length; i++) { + myElementDescriptors[i] = new HtmlElementDescriptorImpl( elementsDescriptors[i] ); + } + } + + return myElementDescriptors; + } + + public XmlElementDescriptor getElementDescriptor(XmlTag element) { + String name = element.getName(); + name = name.toLowerCase(); + + if (cachedDescriptors==null) { + cachedDescriptors = new HashMap(); + XmlElementDescriptor[] elementDescriptors = delegate.getElementsDescriptors(null); + + for (int i = 0; i < elementDescriptors.length; i++) { + XmlElementDescriptor elementDescriptor = elementDescriptors[i]; + cachedDescriptors.put(elementDescriptor.getName(),new HtmlElementDescriptorImpl(elementDescriptor)); + } + } + + return cachedDescriptors.get(name); + } + + private XmlAttributeDescriptor[] myAttributeDescriptors; + + public XmlAttributeDescriptor[] getAttributesDescriptors() { + + if (myAttributeDescriptors==null) { + final XmlAttributeDescriptor[] attributesDescriptors = delegate.getAttributesDescriptors(); + myAttributeDescriptors = new XmlAttributeDescriptor[attributesDescriptors.length]; + + for (int i = 0; i < attributesDescriptors.length; i++) { + myAttributeDescriptors[i] = new HtmlAttributeDescriptorImpl( attributesDescriptors[i] ); + } + } + return myAttributeDescriptors; + } + + public XmlAttributeDescriptor getAttributeDescriptor(String attributeName) { + attributeName = attributeName.toLowerCase(); + + if (cachedAttributeDescriptors==null) { + cachedAttributeDescriptors = new HashMap(); + XmlAttributeDescriptor[] elementAttributeDescriptors = delegate.getAttributesDescriptors(); + + for (int i = 0; i < elementAttributeDescriptors.length; i++) { + final XmlAttributeDescriptor attributeDescriptor = elementAttributeDescriptors[i]; + + cachedAttributeDescriptors.put( + attributeDescriptor.getName(), + new HtmlAttributeDescriptorImpl(attributeDescriptor) + ); + } + } + return cachedAttributeDescriptors.get(attributeName); + } + + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attr) { + return getAttributeDescriptor(attr.getName()); + } + + public XmlNSDescriptor getNSDescriptor() { + return delegate.getNSDescriptor(); + } + + public int getContentType() { + return delegate.getContentType(); + } + + public PsiElement getDeclaration() { + return delegate.getDeclaration(); + } + + public boolean processDeclarations(PsiElement context, + PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastElement, + PsiElement place) { + return delegate.processDeclarations(context, processor, substitutor, lastElement, place); + } + + public String getName(PsiElement context) { + return delegate.getName(context); + } + + public String getName() { + return delegate.getName(); + } + + public void init(PsiElement element) { + delegate.init(element); + } + + public Object[] getDependences() { + return delegate.getDependences(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java new file mode 100644 index 00000000000..96fead3e1eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java @@ -0,0 +1,96 @@ +package com.intellij.psi.impl.source.html.dtd; + +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Nov 2, 2004 + * Time: 4:18:58 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlNSDescriptorImpl implements XmlNSDescriptor { + private XmlNSDescriptor delegate; + private Map myCachedDecls; + + public HtmlNSDescriptorImpl(XmlNSDescriptor _delegate) { + delegate = _delegate; + } + + public HtmlNSDescriptorImpl() { + assert false; + } + + private Map buildDeclarationMap() { + + if (myCachedDecls == null) { + myCachedDecls = new HashMap(); + XmlElementDescriptor[] elements = (delegate!=null)?delegate.getRootElementsDescriptors():XmlElementDescriptor.EMPTY_ARRAY; + + for (int i = 0; i < elements.length; i++) { + XmlElementDescriptor element = elements[i]; + + myCachedDecls.put( + element.getName(), + new HtmlElementDescriptorImpl(element) + ); + }; + } + return myCachedDecls; + } + + public XmlElementDescriptor getElementDescriptor(XmlTag tag) { + String name = tag.getName(); + name = name.toLowerCase(); + + return buildDeclarationMap().get(name); + } + + public XmlElementDescriptor[] getRootElementsDescriptors() { + return (delegate!=null)?delegate.getRootElementsDescriptors():XmlElementDescriptor.EMPTY_ARRAY; + } + + public XmlFile getDescriptorFile() { + return (delegate!=null)?delegate.getDescriptorFile():null; + } + + public boolean isHierarhyEnabled() { + return false; + } + + public PsiElement getDeclaration() { + return (delegate!=null)?delegate.getDeclaration():null; + } + + public boolean processDeclarations(PsiElement context, + PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastElement, + PsiElement place) { + return (delegate!=null)?delegate.processDeclarations(context, processor, substitutor, lastElement, place):true; + } + + public String getName(PsiElement context) { + return (delegate!=null)?delegate.getName(context):""; + } + + public String getName() { + return (delegate!=null)?delegate.getName():""; + } + + public void init(PsiElement element) { + delegate.init(element); + } + + public Object[] getDependences() { + return (delegate!=null)?delegate.getDependences():null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ExceptionTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ExceptionTagInfo.java new file mode 100644 index 00000000000..42e1f592b93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ExceptionTagInfo.java @@ -0,0 +1,83 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.psi.*; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ArrayUtil; + +/** + * @author mike + */ +class ExceptionTagInfo implements JavadocTagInfo { + private String myName; + + public ExceptionTagInfo(String name) { + myName = name; + } + + public String checkTagValue(PsiDocTagValue value) { + if (value == null) return "Exception class expected"; + + if (!(value.getFirstChild() instanceof PsiJavaCodeReferenceElement)) return "Wrong tag value"; + + final PsiJavaCodeReferenceElement ref = ((PsiJavaCodeReferenceElement)value.getFirstChild()); + final PsiClass exceptionClass = (PsiClass)ref.resolve(); + if (exceptionClass == null) return null; + + final PsiClass throwable = value.getManager().findClass("java.lang.Throwable", value.getResolveScope()); + + if (throwable != null) { + if (!exceptionClass.equals(throwable) && !exceptionClass.isInheritor(throwable, true)) { + return "Class " + exceptionClass.getQualifiedName() + " is not a descendant of Throwable"; + } + } + + final PsiClass runtimeException = value.getManager().findClass("java.lang.RuntimeException", value.getResolveScope()); + + if (runtimeException != null && + (exceptionClass.isInheritor(runtimeException, true) || exceptionClass.equals(runtimeException))) { + return null; + } + + final PsiClass errorException = value.getManager().findClass("java.lang.Error", value.getResolveScope()); + + if (errorException != null && + (exceptionClass.isInheritor(errorException, true) || exceptionClass.equals(errorException))) { + return null; + } + + PsiMethod method = PsiTreeUtil.getParentOfType(value, PsiMethod.class); + final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); + + for (int i = 0; i < references.length; i++) { + final PsiClass psiClass = references[i].resolve(); + if (psiClass == null) continue; + if (exceptionClass.isInheritor(psiClass, true) || exceptionClass.equals(psiClass)) return null; + } + + return exceptionClass.getName() + " is not declared to be thrown by method " + method.getName(); + } + + public String getName() { + return myName; + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public PsiReference getReference(PsiDocTagValue value) { + return null; + } + + public boolean isValidInContext(PsiElement element) { + if (!(element instanceof PsiMethod)) return false; + return true; + } + + public boolean isInline() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/JavadocManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/JavadocManagerImpl.java new file mode 100644 index 00000000000..db2ab423d54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/JavadocManagerImpl.java @@ -0,0 +1,67 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.javadoc.JavadocManager; +import com.intellij.psi.javadoc.JavadocTagInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author mike + */ +public class JavadocManagerImpl implements JavadocManager { + private JavadocTagInfo[] myInfos; + + public JavadocManagerImpl() { + List infos = new ArrayList(); + + infos.add(new SimpleDocTagInfo("author", PsiClass.class, false, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("deprecated", PsiElement.class, false, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("serialData", PsiMethod.class, false, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("serialField", PsiField.class, false, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("since", PsiElement.class, false, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("version", PsiClass.class, false, LanguageLevel.JDK_1_3)); + + infos.add(new SimpleDocTagInfo("docRoot", PsiElement.class, true, LanguageLevel.JDK_1_3)); + infos.add(new SimpleDocTagInfo("inheritDoc", PsiElement.class, true, LanguageLevel.JDK_1_4)); + infos.add(new SimpleDocTagInfo("value", PsiElement.class, true, LanguageLevel.JDK_1_4)); + infos.add(new SimpleDocTagInfo("literal", PsiElement.class, true, LanguageLevel.JDK_1_5)); + infos.add(new SimpleDocTagInfo("code", PsiElement.class, true, LanguageLevel.JDK_1_5)); + + infos.add(new ParamDocTagInfo()); + infos.add(new ReturnDocTagInfo()); + infos.add(new SerialDocTagInfo()); + infos.add(new SeeDocTagInfo("see", false)); + infos.add(new SeeDocTagInfo("link", true)); + infos.add(new SeeDocTagInfo("linkplain", true)); + infos.add(new ExceptionTagInfo("exception")); + infos.add(new ExceptionTagInfo("throws")); + + myInfos = (JavadocTagInfo[])infos.toArray(new JavadocTagInfo[infos.size()]); + } + + public JavadocTagInfo[] getTagInfos(PsiElement context) { + List result = new ArrayList(); + + for (int i = 0; i < myInfos.length; i++) { + JavadocTagInfo info = myInfos[i]; + if (info.isValidInContext(context)) result.add(info); + } + + return (JavadocTagInfo[])result.toArray(new JavadocTagInfo[result.size()]); + } + + public JavadocTagInfo getTagInfo(String name) { + for (int i = 0; i < myInfos.length; i++) { + JavadocTagInfo info = myInfos[i]; + if (info.getName().equals(name)) return info; + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ParamDocTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ParamDocTagInfo.java new file mode 100644 index 00000000000..eaef7b086c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ParamDocTagInfo.java @@ -0,0 +1,109 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiReference; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.Factory; +import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.psi.impl.source.tree.SharedImplUtil; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.CharTable; + +/** + * @author mike + */ +class ParamDocTagInfo implements JavadocTagInfo { + public String getName() { + return "param"; + } + + public boolean isValidInContext(PsiElement element) { + return element instanceof PsiMethod; + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + PsiMethod method = (PsiMethod)context; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + return parameters; + } + + public String checkTagValue(PsiDocTagValue value) { + if (value == null) return "Parameter name expected"; + return null; + } + + public PsiReference getReference(final PsiDocTagValue value) { + return new PsiReference() { + public PsiElement resolve() { + return getParameter(value); + } + + public String getCanonicalText() { + return value.getText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(SourceTreeToPsiMap.psiElementToTree(value.getFirstChild())); + LeafElement newLeaf = Factory.createSingleLeafElement(ElementType.DOC_TAG_VALUE_TOKEN, newElementName.toCharArray(), 0, newElementName.length(), charTableByTree, null); + return value.getFirstChild().replace(SourceTreeToPsiMap.treeElementToPsi(newLeaf)); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException("Not Implemented"); + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof PsiParameter)) return false; + PsiParameter parameter = (PsiParameter)element; + if (!getCanonicalText().equals(parameter.getName())) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + return getParameters(value); + } + + public boolean isSoft(){ + return false; + } + + public TextRange getRangeInElement() { + return new TextRange(0, value.getTextLength()); + } + + public PsiElement getElement() { + return value; + } + }; + } + + private PsiParameter getParameter(PsiDocTagValue value) { + final PsiParameter[] parameters = getParameters(value); + + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (parameter.getName().equals(value.getText())) return parameter; + } + + return null; + } + + private PsiParameter[] getParameters(PsiDocTagValue value) { + PsiMethod method = PsiTreeUtil.getParentOfType(value, PsiMethod.class); + if (method == null) return PsiParameter.EMPTY_ARRAY; + return method.getParameterList().getParameters(); + } + + + public boolean isInline() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocCommentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocCommentImpl.java new file mode 100644 index 00000000000..b16206a3d48 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocCommentImpl.java @@ -0,0 +1,288 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.lexer.JavaDocLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; +import com.intellij.util.text.CharArrayCharSequence; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +public class PsiDocCommentImpl extends CompositePsiElement implements PsiDocComment, JavaTokenType, Reparseable { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl"); + + private static final TokenSet TAG_BIT_SET = TokenSet.create(new IElementType[]{DOC_TAG}); + private static final PsiElementArrayConstructor PSI_TAG_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length != 0 ? new PsiDocTag[length] : PsiDocTag.EMPTY_ARRAY; + } + }; + public static final Pattern WS_PATTERN = Pattern.compile("\\s*"); + + + public PsiDocCommentImpl() { + super(DOC_COMMENT); + } + + public PsiElement[] getDescriptionElements() { + ChameleonTransforming.transformChildren(this); + ArrayList array = new ArrayList(); + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + IElementType i = child.getElementType(); + if (i == DOC_TAG) break; + if (i != DOC_COMMENT_START && i != DOC_COMMENT_END && i != DOC_COMMENT_LEADING_ASTERISKS) { + array.add(child); + } + } + return (PsiElement[])array.toArray(new PsiElement[array.size()]); + } + + public PsiDocTag[] getTags() { + return (PsiDocTag[])getChildrenAsPsiElements(TAG_BIT_SET, PSI_TAG_ARRAY_CONSTRUCTOR); + } + + public PsiDocTag findTagByName(String name) { + if (firstChild.getElementType() == DOC_COMMENT_TEXT) { + if (firstChild.getText().indexOf(name) < 0) return null; + } + + char[] tagChars = new char[name.length() + 1]; + tagChars[0] = '@'; + name.getChars(0, name.length(), tagChars, 1); + + ChameleonTransforming.transformChildren(this); + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + if (child.getElementType() == DOC_TAG) { + PsiDocTag tag = (PsiDocTag)SourceTreeToPsiMap.treeElementToPsi(child); + if (tag.getNameElement().textMatches(new CharArrayCharSequence(tagChars))) { + return tag; + } + } + } + + return null; + } + + public PsiDocTag[] findTagsByName(String name) { + ArrayList array = new ArrayList(); + PsiDocTag[] tags = getTags(); + name = "@" + name; + for (int i = 0; i < tags.length; i++) { + PsiDocTag tag = tags[i]; + if (tag.getNameElement().getText().equals(name)) { + array.add(tag); + } + } + return (PsiDocTag[])array.toArray(new PsiDocTag[array.size()]); + } + + public IElementType getTokenType() { + return getElementType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + ChameleonTransforming.transformChildren(this); + switch (role) { + default: + return null; + + case ChildRole.DOC_COMMENT_START: + return firstChild; + + case ChildRole.DOC_COMMENT_END: + if (lastChild.getElementType() == DOC_COMMENT_END) { + return lastChild; + } + else { + return null; + } + } + } + + private static boolean isWhitespaceCommentData(TreeElement docCommentData) { + return WS_PATTERN.matcher(docCommentData.getText()).matches(); + } + + private static void addNewLineToTag(CompositeElement tag) { + LOG.assertTrue(tag != null && tag.getElementType() == DOC_TAG); + TreeElement current = tag.lastChild; + while (current != null && current.getElementType() == DOC_COMMENT_DATA && isWhitespaceCommentData(current)) { + current = current.getTreePrev(); + } + if (current != null && current.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) return; + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(tag); + final TreeElement newLine = Factory.createSingleLeafElement(/*DOC_COMMENT_DATA*/WHITE_SPACE, new char[]{'\n'}, 0, 1, treeCharTab, null); + ChangeUtil.addChild(tag, newLine, null); + final TreeElement leadingAsterisk = Factory.createSingleLeafElement(DOC_COMMENT_LEADING_ASTERISKS, new char[]{'*'}, 0, 1, treeCharTab, + null); + tag.addInternal(leadingAsterisk, leadingAsterisk, null, Boolean.TRUE); + final TreeElement commentData = Factory.createSingleLeafElement(DOC_COMMENT_DATA, new char[]{' '}, 0, 1, treeCharTab, null); + tag.addInternal(commentData, commentData, null, Boolean.TRUE); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + TreeElement firstAdded = null; + boolean needToAddNewline = false; + if (first == last && first.getElementType() == DOC_TAG) { + if (anchor == null) { + anchor = lastChild; // this is a '*/' + final TreeElement prevBeforeWS = TreeUtil.skipElementsBack(anchor.getTreePrev(), WHITE_SPACE_BIT_SET); + if (prevBeforeWS != null) { + anchor = prevBeforeWS; + before = Boolean.FALSE; + } + else { + before = Boolean.TRUE; + } + needToAddNewline = true; + } + if (!(anchor.getElementType() == DOC_TAG)) { + final CharTable charTable = SharedImplUtil.findCharTableByTree(this); + final TreeElement newLine = Factory.createSingleLeafElement(DOC_COMMENT_DATA, new char[]{'\n'}, 0, 1, charTable, null); + firstAdded = super.addInternal(newLine, newLine, anchor, before); + final TreeElement leadingAsterisk = Factory.createSingleLeafElement(DOC_COMMENT_LEADING_ASTERISKS, new char[]{'*'}, 0, 1, + charTable, null); + super.addInternal(leadingAsterisk, leadingAsterisk, newLine, Boolean.FALSE); + final TreeElement commentData = Factory.createSingleLeafElement(DOC_COMMENT_DATA, new char[]{' '}, 0, 1, charTable, null); + super.addInternal(commentData, commentData, leadingAsterisk, Boolean.FALSE); + anchor = commentData; + before = Boolean.FALSE; + } + else { + needToAddNewline = true; + } + } + + if (firstAdded != null) { + firstAdded = super.addInternal(first, last, anchor, before); + } + else { + super.addInternal(first, last, anchor, before); + } + if (needToAddNewline) { + if (first.getTreePrev() != null && first.getTreePrev().getElementType() == DOC_TAG) { + addNewLineToTag((CompositeElement)first.getTreePrev()); + } + if (first.getTreeNext() != null && first.getTreeNext().getElementType() == DOC_TAG) { + addNewLineToTag((CompositeElement)first); + } + else { + removeEndingAsterisksFromTag((CompositeElement)first); + } + } + return firstAdded; + } + + private static void removeEndingAsterisksFromTag(CompositeElement tag) { + TreeElement current = tag.lastChild; + while (current != null && current.getElementType() == DOC_COMMENT_DATA) { + current = current.getTreePrev(); + } + if (current != null && current.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) { + final TreeElement prevWhiteSpace = TreeUtil.skipElementsBack(current.getTreePrev(), WHITE_SPACE_BIT_SET); + TreeElement toBeDeleted = prevWhiteSpace.getTreeNext(); + while (toBeDeleted != null) { + TreeElement next = toBeDeleted.getTreeNext(); + tag.deleteChildInternal(toBeDeleted); + toBeDeleted = next; + } + } + } + + public void deleteChildInternal(TreeElement child) { + if (child.getElementType() == DOC_TAG) { + if (child.getTreeNext() == null || child.getTreeNext().getElementType() != DOC_TAG) { + TreeElement prev = child.getTreePrev(); + while (prev != null && prev.getElementType() == DOC_COMMENT_DATA) { + prev = prev.getTreePrev(); + } + if (prev != null && prev.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) { + TreeElement leadingAsterisk = prev; + if (leadingAsterisk.getTreePrev() != null) { + super.deleteChildInternal(leadingAsterisk.getTreePrev()); + super.deleteChildInternal(leadingAsterisk); + } + } + else if (prev != null && prev.getElementType() == DOC_TAG) { + final CompositeElement compositePrev = (CompositeElement)prev; + final TreeElement lastPrevChild = compositePrev.lastChild; + TreeElement prevChild = lastPrevChild; + while (prevChild != null && prevChild.getElementType() == DOC_COMMENT_DATA) { + prevChild = prevChild.getTreePrev(); + } + if (prevChild != null && prevChild.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) { + TreeElement current = prevChild; + while (current != null) { + final TreeElement next = current.getTreeNext(); + compositePrev.deleteChildInternal(current); + current = next; + } + } + } + } + + } + super.deleteChildInternal(child); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DOC_TAG) { + return ChildRole.DOC_TAG; + } + else if (i == DOC_COMMENT_TEXT || i == DOC_INLINE_TAG) { + return ChildRole.DOC_CONTENT; + } + else if (i == DOC_COMMENT_LEADING_ASTERISKS) { + return ChildRole.DOC_COMMENT_ASTERISKS; + } + else if (i == DOC_COMMENT_START) { + return ChildRole.DOC_COMMENT_START; + } + else if (i == DOC_COMMENT_END) { + return ChildRole.DOC_COMMENT_END; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocComment(this); + } + + public String toString() { + return "PsiDocComment"; + } + + public ChameleonElement createChameleon(char[] buffer, int start, int end) { + return new DocCommentChameleonElement(buffer, start, end, -1, SharedImplUtil.findCharTableByTree(this)); + } + + public int getErrorsCount(char[] buffer, int start, int end, int lengthShift) { + final JavaLexer lexer = new JavaLexer(LanguageLevel.JDK_1_5); + lexer.start(buffer, start, end); + if(lexer.getTokenType() != DOC_COMMENT_TEXT) return -1; + lexer.advance(); + if(lexer.getTokenType() != null) return -1; + return 0; + } + + public Class getLexerClass() { + return JavaDocLexer.class; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java new file mode 100644 index 00000000000..a56070f501c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java @@ -0,0 +1,290 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author mike + */ +public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDocTagValue { + public PsiDocMethodOrFieldRef() { + super(DOC_METHOD_OR_FIELD_REF); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocTagValue(this); + } + + public PsiReference getReference() { + final PsiElement scope = getScope(); + final PsiElement element = getNameElement(); + if (element == null) return new MyReference(null); + final String name = element.getText(); + + + PsiType[] signature = getSignature(); + + final PsiMethod[] methods = getAllMethods(scope, this); + + nextMethod: for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (!method.getName().equals(name)) continue; + + if (signature == null) { + return new MyReference(method); + } + else { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != signature.length) continue; + for (int j = 0; j < parameters.length; j++) { + PsiParameter parameter = parameters[j]; + if (!TypeConversionUtil.erasure(parameter.getType()).equals(signature[j])) continue nextMethod; + } + + return new MyReference(method){ + public Object[] getVariants(){ + final List lst = new ArrayList(); + for(int i = 0; i < methods.length; i++){ + final PsiMethod method = methods[i]; + if(name.equals(method.getName())){ + lst.add(method); + } + } + return lst.toArray(); + } + }; + } + } + + if (signature != null) return new MyReference(null); + + final PsiVariable[] vars = getAllVariables(scope, this); + for (int i = 0; i < vars.length; i++) { + PsiVariable var = vars[i]; + if (!var.getName().equals(name)) continue; + return new MyReference(var); + } + + return new MyReference(null); + } + + public static PsiVariable[] getAllVariables(PsiElement scope, PsiElement place) { + final List result = new ArrayList(); + PsiScopesUtil.processScope(scope, new FilterScopeProcessor(new ClassFilter(PsiVariable.class), place, result), PsiSubstitutor.UNKNOWN, null, place); + return (PsiVariable[]) result.toArray(new PsiVariable[result.size()]); + } + + public static PsiMethod[] getAllMethods(PsiElement scope, PsiElement place) { + final List result = new ArrayList(); + PsiScopesUtil.processScope(scope, new FilterScopeProcessor(new ClassFilter(PsiMethod.class), place, result), PsiSubstitutor.UNKNOWN, null, place); + return (PsiMethod[]) result.toArray(new PsiMethod[result.size()]); + } + + public int getTextOffset() { + final PsiElement element = getNameElement(); + + if (element != null) { + return element.getTextRange().getStartOffset(); + } + + return getTextRange().getEndOffset(); + } + + public PsiElement getNameElement() { + final TreeElement sharp = TreeUtil.findChild(this, DOC_TAG_VALUE_SHARP_TOKEN); + if (sharp == null) return null; + return SourceTreeToPsiMap.treeElementToPsi(sharp).getNextSibling(); + } + + + private PsiType[] getSignature() { + PsiElement element = getNameElement().getNextSibling(); + + while (element != null && !(element instanceof PsiDocTagValue)) { + element = element.getNextSibling(); + } + + if (element == null) return null; + + List types = new ArrayList(); + for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) { + if (child instanceof PsiTypeElement) { + PsiTypeElement type = (PsiTypeElement)child; + types.add(type.getType()); + } + } + + return (PsiType[])types.toArray(new PsiType[types.size()]); + } + + private PsiElement getScope(){ + ChameleonTransforming.transformChildren(this); + if (firstChild.getElementType() == ElementType.JAVA_CODE_REFERENCE || firstChild.getElementType() == ElementType.REFERENCE_EXPRESSION) { + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(firstChild); + final PsiElement referencedElement = referenceElement.resolve(); + if (referencedElement instanceof PsiClass) { + return referencedElement; + } + } + final PsiElement place = SourceTreeToPsiMap.treeElementToPsi(TreeUtil.findParent(this, TreeElement.CLASS)); + if(place == null) + return getContainingFile(); + return place; + } + + private class MyReference implements PsiReference { + private final PsiElement myReferencee; + + public MyReference(PsiElement referencee) { + myReferencee = referencee; + } + + public PsiElement resolve() { + return myReferencee; + } + + public Object[] getVariants(){ + final PsiElement scope = getScope(); + final List vars = new ArrayList(); + vars.addAll(Arrays.asList(getAllMethods(scope, PsiDocMethodOrFieldRef.this))); + vars.addAll(Arrays.asList(getAllVariables(scope, PsiDocMethodOrFieldRef.this))); + return vars.toArray(); + } + + public boolean isSoft(){ + return false; + } + + public String getCanonicalText() { + return getNameElement().getText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + final PsiElement element = getNameElement(); + final TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(element); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(treeElement); + LeafElement newToken = Factory.createSingleLeafElement(DOC_TAG_VALUE_TOKEN, newElementName.toCharArray(), 0, newElementName.length(), charTableByTree, getManager()); + treeElement.getTreeParent().replaceChildInternal(SourceTreeToPsiMap.psiElementToTree(element), newToken); + return SourceTreeToPsiMap.treeElementToPsi(newToken); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + if (isReferenceTo(element)) return PsiDocMethodOrFieldRef.this; + final String name = getNameElement().getText(); + final String newName; + + final PsiMethod method; + final PsiField field; + final boolean hasSignature; + final PsiClass containingClass; + if (element instanceof PsiMethod) { + method = (PsiMethod)element; + hasSignature = getSignature() != null; + containingClass = method.getContainingClass(); + newName = method.getName(); + } else if (element instanceof PsiField) { + field = (PsiField) element; + hasSignature = false; + containingClass = field.getContainingClass(); + method = null; + newName = field.getName(); + } else { + throw new IncorrectOperationException(); + } + + + if (getFirstChild() instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) getFirstChild(); + referenceElement.bindToElement(containingClass); + } + else { + if (!PsiTreeUtil.isAncestor(containingClass, PsiDocMethodOrFieldRef.this, true)) { + final PsiReferenceExpression ref = containingClass.getManager().getElementFactory().createReferenceExpression(containingClass); + addAfter(ref, null); + } + } + + if (hasSignature || !name.equals(newName)) { + String text = getText(); + + StringBuffer newText = new StringBuffer("/** @see "); + if (name.equals(newName)) { // hasSignature is true here, so we can search for '(' + newText.append(text.substring(0, text.indexOf('('))); + } + else { + final int sharpIndex = text.indexOf('#'); + if (sharpIndex >= 0) { + newText.append(text.substring(0, sharpIndex + 1)); + } + newText.append(newName); + } + if (hasSignature) { + newText.append('('); + PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (i > 0) newText.append(","); + newText.append(parameter.getType().getCanonicalText()); + } + newText.append(')'); + } + newText.append("*/"); + + PsiComment comment = containingClass.getManager().getElementFactory().createCommentFromText(newText.toString(), null); + PsiElement tag = PsiTreeUtil.getChildOfType(comment, PsiDocTag.class); + PsiElement ref = PsiTreeUtil.getChildOfType(tag, PsiDocMethodOrFieldRef.class); + return replace(ref); + } + + return PsiDocMethodOrFieldRef.this; + } + + public boolean isReferenceTo(PsiElement element) { + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public TextRange getRangeInElement() { + final TreeElement sharp = TreeUtil.findChild(PsiDocMethodOrFieldRef.this, DOC_TAG_VALUE_SHARP_TOKEN); + if (sharp == null) return new TextRange(0, getTextLength()); + final PsiElement nextSibling = SourceTreeToPsiMap.treeElementToPsi(sharp).getNextSibling(); + if(nextSibling != null){ + final int startOffset = nextSibling.getTextRange().getStartOffset() - getTextRange().getStartOffset(); + int endOffset = nextSibling.getTextRange().getEndOffset() - getTextRange().getStartOffset(); + final PsiElement nextParSibling = nextSibling.getNextSibling(); + if(nextParSibling != null && "(".equals(nextParSibling.getText())){ + endOffset ++; + PsiElement nextElement = nextParSibling.getNextSibling(); + if(nextElement != null && SourceTreeToPsiMap.psiElementToTree(nextElement).getElementType() == DOC_TAG_VALUE_TOKEN){ + endOffset += nextElement.getTextLength(); + nextElement = nextElement.getNextSibling(); + } + if(nextElement != null && ")".equals(nextElement.getText())){ + endOffset ++; + } + } + return new TextRange(startOffset, endOffset); + } + return new TextRange(getTextLength(), getTextLength()); + } + + public PsiElement getElement() { + return PsiDocMethodOrFieldRef.this; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java new file mode 100644 index 00000000000..99ae69653ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java @@ -0,0 +1,89 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.CharTable; + +/** + * @author mike + */ +public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValue { + public PsiDocParamRef() { + super(DOC_PARAMETER_REF); + } + + public PsiReference getReference() { + PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class); + final PsiElement parent = comment.getParent(); + if (!(parent instanceof PsiMethod)) return null; + final PsiMethod method = (PsiMethod)parent; + if (method.getDocComment() != comment) return null; + + return new PsiReference() { + public PsiElement resolve() { + String name = getText(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (parameter.getName().equals(name)) return parameter; + } + + return null; + } + + public String getCanonicalText() { + return getText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + final TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(PsiDocParamRef.this); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(treeElement); + LeafElement newElement = Factory.createSingleLeafElement(ElementType.DOC_TAG_VALUE_TOKEN, newElementName.toCharArray(), 0, newElementName.length(), charTableByTree, getManager()); + replaceChildInternal(firstChild, newElement); + return PsiDocParamRef.this; + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + if (isReferenceTo(element)) return PsiDocParamRef.this; + if(!(element instanceof PsiParameter)) { + throw new IncorrectOperationException("Unsupported operation"); + } + return handleElementRename(((PsiParameter) element).getName()); + } + + public boolean isReferenceTo(PsiElement element) { + if (!(element instanceof PsiParameter)) return false; + PsiParameter parameter = (PsiParameter)element; + if (!getCanonicalText().equals(parameter.getName())) return false; + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + return method.getParameterList().getParameters(); + } + + public boolean isSoft(){ + return false; + } + + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + public PsiElement getElement() { + return PsiDocParamRef.this; + } + }; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocTagValue(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java new file mode 100644 index 00000000000..13ec305849b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java @@ -0,0 +1,90 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.IncorrectOperationException; + +public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.javadoc.PsiDocTagImpl"); + + private static final TokenSet VALUE_BIT_SET = TokenSet.create(new IElementType[]{ + JAVA_CODE_REFERENCE, + DOC_TAG_VALUE_TOKEN, + DOC_METHOD_OR_FIELD_REF, + DOC_PARAMETER_REF, + DOC_COMMENT_DATA, + DOC_INLINE_TAG, + }); + + public PsiDocTagImpl() { + super(DOC_TAG); + } + + public PsiDocComment getContainingComment() { + return (PsiDocComment)SourceTreeToPsiMap.treeElementToPsi(getTreeParent()); + } + + public PsiElement getNameElement() { + return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME); + } + + public PsiDocTagValue getValueElement() { + return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE); + } + + public PsiElement[] getDataElements() { + return getChildrenAsPsiElements(VALUE_BIT_SET, PSI_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public String getName() { + if (getNameElement() == null) return ""; + return getNameElement().getText().substring(1); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameElement(), name); + return this; + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DOC_TAG_NAME) { + return ChildRole.DOC_TAG_NAME; + } + else if (i == DOC_COMMENT_TEXT || i == DOC_INLINE_TAG) { + return ChildRole.DOC_CONTENT; + } + else if (i == DOC_COMMENT_LEADING_ASTERISKS) { + return ChildRole.DOC_COMMENT_ASTERISKS; + } + else if (i == DOC_TAG_VALUE_TOKEN) { + return ChildRole.DOC_TAG_VALUE; + } + else if (i == DOC_METHOD_OR_FIELD_REF || i == DOC_PARAMETER_REF) { + return ChildRole.DOC_TAG_VALUE; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocTag(this); + } + + public String toString() { + return "PsiDocTag:" + getNameElement().getText(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagValueImpl.java new file mode 100644 index 00000000000..7716475d3ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTagValueImpl.java @@ -0,0 +1,33 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.javadoc.JavadocManager; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.PsiTreeUtil; + +/** + * @author mike + */ +public class PsiDocTagValueImpl extends CompositePsiElement implements PsiDocTagValue { + public PsiDocTagValueImpl() { + super(DOC_TAG_VALUE_TOKEN); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocTagValue(this); + } + + public PsiReference getReference() { + PsiDocTag docTag = PsiTreeUtil.getParentOfType(this, PsiDocTag.class); + final String name = docTag.getName(); + final JavadocManager manager = getManager().getJavadocManager(); + final JavadocTagInfo info = manager.getTagInfo(name); + if (info == null) return null; + + return info.getReference(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTokenImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTokenImpl.java new file mode 100644 index 00000000000..4dea81faf9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/PsiDocTokenImpl.java @@ -0,0 +1,25 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.psi.javadoc.PsiDocToken; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public class PsiDocTokenImpl extends LeafPsiElement implements PsiDocToken{ + public PsiDocTokenImpl(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, lexerState, table); + } + + public IElementType getTokenType() { + return getElementType(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDocToken(this); + } + + public String toString(){ + return "PsiDocToken:" + getTokenType().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ReturnDocTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ReturnDocTagInfo.java new file mode 100644 index 00000000000..46bb2ad6f46 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/ReturnDocTagInfo.java @@ -0,0 +1,42 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import com.intellij.util.ArrayUtil; + +/** + * @author mike + */ +class ReturnDocTagInfo implements JavadocTagInfo { + public String checkTagValue(PsiDocTagValue value) { + return null; + } + + public String getName() { + return "return"; + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public PsiReference getReference(PsiDocTagValue value) { + return null; + } + + public boolean isValidInContext(PsiElement element) { + if (!(element instanceof PsiMethod)) return false; + PsiMethod method = (PsiMethod)element; + final PsiType type = method.getReturnType(); + if (type == null) return false; + return type != PsiType.VOID; + } + + public boolean isInline() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java new file mode 100644 index 00000000000..1ebc3950a1c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java @@ -0,0 +1,114 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.javadoc.PsiDocToken; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author mike + */ +class SeeDocTagInfo implements JavadocTagInfo { + private String myName; + private boolean myInline; + + public SeeDocTagInfo(String name, boolean isInline) { + myName = name; + myInline = isInline; + } + + public String checkTagValue(PsiDocTagValue value) { + return null; + } + + public String getName() { + return myName; + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + if (place instanceof PsiDocToken) { + PsiDocToken token = (PsiDocToken) place; + if (token.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) { + return getPossibleMethodsAndFields(context, place, prefix); + } else if (token.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_LPAREN) { + if (token.getPrevSibling() == null) return ArrayUtil.EMPTY_OBJECT_ARRAY; + final String methodName = token.getPrevSibling().getText(); + + PsiElement targetContext = getTargetContext(context, place); + + List result = new ArrayList(); + final PsiMethod[] methods = PsiDocMethodOrFieldRef.getAllMethods(targetContext, place); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + if (method.getName().equals(methodName)) { + result.add(method); + } + } + return result.toArray(new Object[result.size()]); + } else if (token.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN && place.getParent() instanceof PsiDocMethodOrFieldRef) { + return getPossibleMethodsAndFields(context, place, prefix); + } + } + + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + private Object[] getPossibleMethodsAndFields(PsiElement context, PsiElement place, String prefix) { + List result = new ArrayList(); + + PsiElement targetContext = getTargetContext(context, place); + + final PsiMethod[] methods = PsiDocMethodOrFieldRef.getAllMethods(targetContext, place); + for (int i = 0; i < methods.length; i++) { + result.add(methods[i]); + } + + final PsiVariable[] variables = PsiDocMethodOrFieldRef.getAllVariables(targetContext, place); + for (int i = 0; i < variables.length; i++) { + result.add(variables[i]); + } + + return result.toArray(new Object[result.size()]); + } + + private PsiElement getTargetContext(PsiElement context, PsiElement place) { + PsiElement targetContext = context; + + if (place.getParent() instanceof PsiDocMethodOrFieldRef) { + PsiDocMethodOrFieldRef methodRef = (PsiDocMethodOrFieldRef) place.getParent(); + + final IElementType firstChildType = methodRef.firstChild.getElementType(); + if (firstChildType == ElementType.JAVA_CODE_REFERENCE || firstChildType == ElementType.REFERENCE_EXPRESSION) { + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(methodRef.firstChild); + final PsiElement element = referenceElement.resolve(); + if (element instanceof PsiClass) { + targetContext = element.getFirstChild(); + } + } + } + return targetContext; + } + + public boolean isValidInContext(PsiElement element) { + if (myInline && myName.equals("linkplain")) + return element.getManager().getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_4) >= 0; + + return true; + } + + public PsiReference getReference(PsiDocTagValue value) { + return null; + } + + public boolean isInline() { + return myInline; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SerialDocTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SerialDocTagInfo.java new file mode 100644 index 00000000000..a693dacb01b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SerialDocTagInfo.java @@ -0,0 +1,35 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiReference; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.util.ArrayUtil; + +public class SerialDocTagInfo implements JavadocTagInfo { + public String getName() { + return "serial"; + } + + public boolean isInline() { + return false; + } + + public boolean isValidInContext(PsiElement element) { + return element instanceof PsiClass || element instanceof PsiField; + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public String checkTagValue(PsiDocTagValue value) { + return null; + } + + public PsiReference getReference(PsiDocTagValue value) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java new file mode 100644 index 00000000000..a65df956f0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java @@ -0,0 +1,53 @@ +package com.intellij.psi.impl.source.javadoc; + +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.javadoc.JavadocTagInfo; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.util.ArrayUtil; + +/** + * @author mike + */ +class SimpleDocTagInfo implements JavadocTagInfo { + private String myName; + private Class myContext; + private boolean myInline; + private final LanguageLevel myLanguageLevel; + + public SimpleDocTagInfo(String name, Class context, boolean isInline, LanguageLevel level) { + myName = name; + myContext = context; + myInline = isInline; + myLanguageLevel = level; + } + + public String getName() { + return myName; + } + + public boolean isValidInContext(PsiElement element) { + if (element.getManager().getEffectiveLanguageLevel().compareTo(myLanguageLevel) < 0) { + return false; + } + + return myContext.isInstance(element); + } + + public Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix) { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public String checkTagValue(PsiDocTagValue value) { + return null; + } + + public PsiReference getReference(PsiDocTagValue value) { + return null; + } + + public boolean isInline() { + return myInline; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/jspJava/JspText.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/jspJava/JspText.java new file mode 100644 index 00000000000..20f8e6c7d48 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/jspJava/JspText.java @@ -0,0 +1,19 @@ +package com.intellij.psi.impl.source.jsp.jspJava; + +import com.intellij.psi.impl.source.tree.JspElementType; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.util.CharTable; + +public class JspText extends LeafPsiElement { + public JspText(char[] buffer, int start, int end, CharTable table) { + super(JspElementType.HOLDER_TEMPLATE_DATA, buffer, start, end, -1, table); + } + + public String toString() { + return "JspText"; + } + + public void setText(String text) { + super.setText(text); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/FileLoader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/FileLoader.java new file mode 100644 index 00000000000..14dd8274956 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/FileLoader.java @@ -0,0 +1,83 @@ +package com.intellij.psi.impl.source.jsp.tagLibrary; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import sun.misc.Resource; + +import java.io.*; +import java.net.URL; + +class FileLoader extends Loader { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.jsp.tagLibrary.FileLoader"); + Resource getResource(final String name, boolean flag) { + try { + final URL url = new URL(getBaseURL(), name); + if (!url.getFile().startsWith(getBaseURL().getFile())) return null; + final File file = new File(dir, name.replace('/', File.separatorChar)); + if (file.exists()) return new MyResource(name, url, file); + } + catch (Exception exception) { + return null; + } + return null; + } + + private File dir; + + FileLoader(URL url) + throws IOException { + super(url); + if (!"file".equals(url.getProtocol())) { + throw new IllegalArgumentException("url"); + } + else { + final String s = url.toExternalForm(); + + if (s.startsWith("file://")) { + String path = s.substring("file://".length()).replace('/', File.separatorChar); + if (SystemInfo.isUnix) path = "/" + path; + dir = new File(path); + } + else if (s.startsWith("file:/")) { + String path = s.substring("file:/".length()).replace('/', File.separatorChar); + if (SystemInfo.isUnix) path = "/" + path; + dir = new File(path); + } + else { + LOG.assertTrue(false, s); + } + } + } + + private class MyResource extends Resource { + private final String myName; + private final URL myUrl; + private final File myFile; + + public MyResource(String name, URL url, File file) { + myName = name; + myUrl = url; + myFile = file; + } + + public String getName() { + return myName; + } + + public URL getURL() { + return myUrl; + } + + public URL getCodeSourceURL() { + return getBaseURL(); + } + + public InputStream getInputStream() throws IOException { + return new BufferedInputStream(new FileInputStream(myFile)); + } + + public int getContentLength() throws IOException { + return (int)myFile.length(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/JarLoader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/JarLoader.java new file mode 100644 index 00000000000..79a9e3a905a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/JarLoader.java @@ -0,0 +1,112 @@ +package com.intellij.psi.impl.source.jsp.tagLibrary; + +import sun.misc.Resource; + +import java.io.*; +import java.net.URL; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +class JarLoader extends Loader { + private URL myURL; + + JarLoader(URL url) throws IOException { + super(new URL("jar", "", -1, url + "!/")); + myURL = url; + } + + private ZipFile getZipFile() throws IOException { + if ("file".equals(myURL.getProtocol())) { + String s = myURL.getFile().replace('/', File.separatorChar); + if (!(new File(s)).exists()) throw new FileNotFoundException(s); + else return new ZipFile(s); + } + + return null; + } + + Resource getResource(String name, boolean flag) { + try { + final ZipFile file = getZipFile(); + if (file == null) return null; + + try { + ZipEntry entry = file.getEntry(name); + if (entry != null) return new MyResource(name, new URL(getBaseURL(), name)); + } + finally { + file.close(); + } + } + catch (Exception e) { + } + + return null; + } + + private class MyResource extends Resource { + private final String myName; + private final URL myUrl; + + public MyResource(String name, URL url) { + myName = name; + myUrl = url; + } + + public String getName() { + return myName; + } + + public URL getURL() { + return myUrl; + } + + public URL getCodeSourceURL() { + return myURL; + } + + public InputStream getInputStream() throws IOException { + final ZipFile file = getZipFile(); + if (file == null) return null; + + try { + final ZipEntry entry = file.getEntry(myName); + if (entry == null) { + file.close(); + return null; + } + final InputStream inputStream = new BufferedInputStream(file.getInputStream(entry)); + return new FilterInputStream(inputStream) { + public void close() throws IOException { + super.close(); + file.close(); + } + }; + } + catch (IOException e) { + file.close(); + return null; + } + } + + public int getContentLength() { + try { + final ZipFile jarFile = getZipFile(); + if (jarFile == null) return -1; + + try { + final ZipEntry entry = jarFile.getEntry(myName); + if (entry == null) return -1; + + return (int)entry.getSize(); + } + finally { + jarFile.close(); + } + } + catch (IOException e) { + return -1; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/Loader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/Loader.java new file mode 100644 index 00000000000..6bbe518a223 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/jsp/tagLibrary/Loader.java @@ -0,0 +1,20 @@ +package com.intellij.psi.impl.source.jsp.tagLibrary; + +import sun.misc.Resource; + +import java.net.URL; + +abstract class Loader { + private final URL myURL; + + protected Loader(URL url) { + myURL = url; + } + + + protected URL getBaseURL() { + return myURL; + } + + abstract Resource getResource(final String name, boolean flag); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ChameleonTransforming.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ChameleonTransforming.java new file mode 100644 index 00000000000..fa6b95ed93b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ChameleonTransforming.java @@ -0,0 +1,79 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiLock; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; + +/** + * + */ +public class ChameleonTransforming implements Constants { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.source.parsing.ChameleonTransforming"); + + public static TreeElement transform(ChameleonElement chameleon) { + synchronized (PsiLock.LOCK) { + if (LOG.isDebugEnabled()) { + LOG.debug("\"transforming chameleon:\" + chameleon + \" in \" + chameleon.parent"); + } + final CompositeElement parent = chameleon.getTreeParent(); + parent.getTextLength(); + PsiFileImpl file = (PsiFileImpl)SourceTreeToPsiMap.treeElementToPsi(parent).getContainingFile(); + if (file == null) return null; + + TreeElement newElement = chameleon.transform(file.getTreeElement().getCharTable(), file.createLexer()); + if (DebugUtil.CHECK) { + if (newElement != null) { + DebugUtil.checkTreeStructure(newElement); + } + + String text1 = chameleon.getText(); + + int length2 = 0; + for (TreeElement element = newElement; element != null; element = element.getTreeNext()) { + length2 += element.getTextLength(); + } + char[] buffer = new char[length2]; + int offset = 0; + for (TreeElement element = newElement; element != null; element = element.getTreeNext()) { + offset = SourceUtil.toBuffer(element, buffer, offset); + } + String text2 = new String(buffer); + + if (!text1.equals(text2)) { + LOG.error("Text changed after chameleon transformation!\nWas:\n" + text1 + "\nbecame:\n" + text2); + } + } + TreeUtil.replace(chameleon, newElement); + return newElement; + } + } + + public static void transformChildren(CompositeElement element) { + transformChildren(element, false); + } + + public static void transformChildren(CompositeElement element, boolean recursive) { + synchronized (PsiLock.LOCK) { + TreeElement child = element.firstChild; + while (child != null) { + if (child instanceof ChameleonElement) { + TreeElement next = child.getTreeNext(); + child = transform((ChameleonElement)child); + if (child == null) { + child = next; + } + continue; + } + if (recursive && child instanceof CompositeElement) { + transformChildren((CompositeElement)child, recursive); + } + child = child.getTreeNext(); + } + ; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ClassBodyParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ClassBodyParsing.java new file mode 100644 index 00000000000..aa3eda1c072 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ClassBodyParsing.java @@ -0,0 +1,138 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.Lexer; +import com.intellij.lexer.FilterLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; + +/** + * + */ +public class ClassBodyParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ClassBodyParsing"); + public static final int CLASS = 0; + public static final int ANNOTATION = 1; + public static final int ENUM = 2; + + public ClassBodyParsing(ParsingContext context) { + super(context); + } + + + public static TreeElement parseClassBodyText(Lexer lexer, + char[] buffer, + int startOffset, + int endOffset, + int lexerState, + int context, + CharTable table, PsiManager manager){ + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (lexerState < 0) filterLexer.start(buffer, startOffset, endOffset); + else filterLexer.start(buffer, startOffset, endOffset, lexerState); + + final FileElement dummyRoot = new DummyHolder(manager, null, table).getTreeElement(); + ParsingContext parsingContext = new ParsingContext(table); + parsingContext.getClassBodyParsing().parseClassBody(dummyRoot, filterLexer, context); + ParseUtil.insertMissingTokens(dummyRoot, lexer, startOffset, endOffset, lexerState, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, parsingContext); + return dummyRoot.firstChild; + } + + private void parseEnumConstants(Lexer lexer, CompositeElement dummyRoot) { + while (lexer.getTokenType() != null) { + if (lexer.getTokenType() == JavaTokenType.SEMICOLON) { + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return; + } + + final TreeElement enumConstant = myContext.getDeclarationParsing().parseEnumConstant(lexer); + if (enumConstant != null) { + TreeUtil.addChildren(dummyRoot, enumConstant); + } + else { + TreeUtil.addChildren(dummyRoot, Factory.createErrorElement("Identifier expected")); + } + + if (lexer.getTokenType() == COMMA) { + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else if (lexer.getTokenType() != null && lexer.getTokenType() != SEMICOLON) { + TreeUtil.addChildren(dummyRoot, Factory.createErrorElement("',' or ';' expected")); + return; + } + } + } + + private void parseClassBodyDeclarations(int context, Lexer filterLexer, CompositeElement dummyRoot) { + CompositeElement invalidElementsGroup = null; + final int declarationParsingContext = calcDeclarationContext(context); + + while(true){ + IElementType tokenType = filterLexer.getTokenType(); + if (tokenType == null) break; + + if (tokenType == SEMICOLON){ + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(filterLexer, myContext.getCharTable())); + filterLexer.advance(); + invalidElementsGroup = null; + continue; + } + + TreeElement declaration = myContext.getDeclarationParsing().parseDeclaration(filterLexer, + declarationParsingContext); + if (declaration != null){ + TreeUtil.addChildren(dummyRoot, declaration); + invalidElementsGroup = null; + continue; + } + + if (invalidElementsGroup == null){ + invalidElementsGroup = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(dummyRoot, invalidElementsGroup); + } + + // adding a reference, not simple tokens allows "Browse .." to work well + CompositeElement ref = parseJavaCodeReference(filterLexer, true); + if (ref != null){ + TreeUtil.addChildren(invalidElementsGroup, ref); + continue; + } + + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(filterLexer, myContext.getCharTable())); + filterLexer.advance(); + } + } + + private static int calcDeclarationContext(int context) { + int declarationParsingContext = DeclarationParsing.CLASS_CONTEXT; + switch(context) { + default: + LOG.assertTrue(false); + break; + case CLASS: + case ENUM: + declarationParsingContext = DeclarationParsing.CLASS_CONTEXT; + break; + case ANNOTATION: + declarationParsingContext = DeclarationParsing.ANNOTATION_INTERFACE_CONTEXT; + break; + } + return declarationParsingContext; + } + + public void parseClassBody(CompositeElement root, Lexer lexer, int context) { + if (context == ENUM) { + parseEnumConstants (lexer, root); + } + parseClassBodyDeclarations(context, lexer, root); + } +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/DeclarationParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/DeclarationParsing.java new file mode 100644 index 00000000000..8fe484a2a71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/DeclarationParsing.java @@ -0,0 +1,982 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.text.CharArrayUtil; +import com.intellij.pom.java.LanguageLevel; + +/** + * + */ +public class DeclarationParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.DeclarationParsing"); + + public static final int FILE_CONTEXT = 1; + public static final int CLASS_CONTEXT = 2; + public static final int CODE_BLOCK_CONTEXT = 3; + public static final int ANNOTATION_INTERFACE_CONTEXT = 4; + + public DeclarationParsing(ParsingContext context) { + super(context); + } + + public static TreeElement parseDeclarationText(PsiManager manager, + LanguageLevel languageLevel, + char[] buffer, + int context, + CharTable charTable) { + Lexer originalLexer = new JavaLexer(languageLevel); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, 0, buffer.length); + ParsingContext parsingContext = new ParsingContext(charTable); + TreeElement first = parsingContext.getDeclarationParsing().parseDeclaration(lexer, context); + if (first == null) return null; + if (lexer.getTokenType() != null) return null; + + final FileElement dummyRoot = new DummyHolder(manager, null, charTable).getTreeElement(); + TreeUtil.addChildren(dummyRoot, first); + + ParseUtil.insertMissingTokens(dummyRoot, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, parsingContext); + return first; + } + + public static TreeElement parseMemberValueText(PsiManager manager, char[] buffer, CharTable table) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, 0, buffer.length); + final ParsingContext context = new ParsingContext(table); + TreeElement first = context.getDeclarationParsing().parseAnnotationMemberValue(lexer); + if (first == null) return null; + if (lexer.getTokenType() != null) return null; + + final FileElement dummyRoot = new DummyHolder(manager, null, table).getTreeElement(); + + TreeUtil.addChildren(dummyRoot, first); + + ParseUtil.insertMissingTokens(dummyRoot, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return first; + } + + protected TreeElement parseDeclaration(Lexer lexer, int context) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) return null; + + if (tokenType == LBRACE){ + if (context == FILE_CONTEXT || context == CODE_BLOCK_CONTEXT) return null; + } + else if (tokenType == IDENTIFIER || PRIMITIVE_TYPE_BIT_SET.isInSet(tokenType)){ + if (context == FILE_CONTEXT) return null; + } + else if (tokenType == JSP_HOLDER_TOKEN) { + LeafElement element = Factory.createLeafElement(HOLDER_TEMPLATE_DATA, lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), lexer.getState(), myContext.getCharTable()); + lexer.advance(); + return element; + } + else if (!MODIFIER_BIT_SET.isInSet(tokenType) && !CLASS_KEYWORD_BIT_SET.isInSet(tokenType) + && tokenType != AT && (context == CODE_BLOCK_CONTEXT || tokenType != LT)){ + return null; + } + + long startPos = ParseUtil.savePosition(lexer); + + CompositeElement modifierList = parseModifierList(lexer); + + tokenType = lexer.getTokenType(); + if (tokenType == AT) { + TreeElement atToken = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + tokenType = lexer.getTokenType(); + if (tokenType == INTERFACE_KEYWORD) { + return parseClassFromKeyword(lexer, modifierList, atToken); + } else { + ParseUtil.restorePosition(lexer, startPos); + return null; + } + } else if (CLASS_KEYWORD_BIT_SET.isInSet(tokenType)){ + return parseClassFromKeyword(lexer, modifierList, null); + } + + TreeElement classParameterList = null; + if (tokenType == LT){ + classParameterList = parseTypeParameterList(lexer); + tokenType = lexer.getTokenType(); + } + + if (context == FILE_CONTEXT){ + final CompositeElement errorElement = Factory.createErrorElement("'class' or 'interface' expected"); + TreeUtil.insertAfter(modifierList, errorElement); + if (classParameterList != null){ + TreeUtil.insertAfter(errorElement, classParameterList); + } + return modifierList; + } + + final TreeElement first = modifierList; + TreeElement last = modifierList; + + TreeElement type; + if (tokenType != null && PRIMITIVE_TYPE_BIT_SET.isInSet(tokenType)){ + type = parseType(lexer); + } + else if (tokenType == IDENTIFIER){ + long idPos = ParseUtil.savePosition(lexer); + type = parseType(lexer); + if (lexer.getTokenType() == LPARENTH){ //constructor + if (context == CODE_BLOCK_CONTEXT){ + ParseUtil.restorePosition(lexer, startPos); + return null; + } + ParseUtil.restorePosition(lexer, idPos); + CompositeElement method = Factory.createCompositeElement(METHOD); + TreeUtil.addChildren(method, first); + if (classParameterList == null){ + classParameterList = Factory.createCompositeElement(TYPE_PARAMETER_LIST); + } + TreeUtil.addChildren(method, classParameterList); + TreeUtil.addChildren(method, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (lexer.getTokenType() != LPARENTH){ + ParseUtil.restorePosition(lexer, startPos); + return null; + } + parseMethodFromLparenth(lexer, method, false); + return method; + } + } + else if (tokenType == LBRACE){ + if (context == CODE_BLOCK_CONTEXT){ + TreeElement errorElement = Factory.createErrorElement("Identifier or type expected"); + TreeUtil.insertAfter(last, errorElement); + last = errorElement; + return first; + } + + CompositeElement codeBlock = myContext.getStatementParsing().parseCodeBlock(lexer, false); + LOG.assertTrue(codeBlock != null); + + CompositeElement initializer = Factory.createCompositeElement(CLASS_INITIALIZER); + TreeUtil.addChildren(initializer, modifierList); + if (classParameterList != null){ + final CompositeElement errorElement = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(errorElement, classParameterList); + TreeUtil.addChildren(initializer, errorElement); + } + TreeUtil.addChildren(initializer, codeBlock); + return initializer; + } + else{ + CompositeElement errorElement = Factory.createErrorElement("Identifier or type expected"); + if (classParameterList != null){ + TreeUtil.addChildren(errorElement, classParameterList); + } + TreeUtil.insertAfter(last, errorElement); + last = errorElement; + return first; + } + + TreeUtil.insertAfter(last, type); + last = type; + + if (lexer.getTokenType() != IDENTIFIER){ + if (context == CODE_BLOCK_CONTEXT && modifierList.firstChild == null){ + ParseUtil.restorePosition(lexer, startPos); + return null; + } + else{ + TreeElement errorElement = Factory.createErrorElement("Identifier expected"); + if (classParameterList != null){ + final CompositeElement errorElement1 = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(errorElement1, classParameterList); + TreeUtil.insertBefore(last, errorElement1); + } + TreeUtil.insertAfter(last, errorElement); + last = errorElement; + return first; + } + } + + TreeElement identifier = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + TreeUtil.insertAfter(last, identifier); + last = identifier; + + if (lexer.getTokenType() == LPARENTH){ + if (context == CLASS_CONTEXT){ //method + CompositeElement method = Factory.createCompositeElement(METHOD); + if (classParameterList == null){ + classParameterList = Factory.createCompositeElement(TYPE_PARAMETER_LIST); + } + TreeUtil.insertAfter(first, classParameterList); + TreeUtil.addChildren(method, first); + parseMethodFromLparenth(lexer, method, false); + return method; + } else if (context == ANNOTATION_INTERFACE_CONTEXT) { + CompositeElement method = Factory.createCompositeElement(ANNOTATION_METHOD); + if (classParameterList == null){ + classParameterList = Factory.createCompositeElement(TYPE_PARAMETER_LIST); + } + TreeUtil.insertAfter(first, classParameterList); + TreeUtil.addChildren(method, first); + parseMethodFromLparenth(lexer, method, true); + return method; + } + else + return parseFieldOrLocalVariable(classParameterList, first, context, lexer, startPos); + } + else{ + return parseFieldOrLocalVariable(classParameterList, first, context, lexer, startPos); + } + } + + private TreeElement parseFieldOrLocalVariable(TreeElement classParameterList, + final TreeElement first, + int context, + Lexer lexer, long startPos) {//field or local variable + if (classParameterList != null){ + final CompositeElement errorElement = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(errorElement, classParameterList); + TreeUtil.insertAfter(first, errorElement); + } + CompositeElement variable; + if (context == CLASS_CONTEXT || context == ANNOTATION_INTERFACE_CONTEXT){ + variable = Factory.createCompositeElement(FIELD); + TreeUtil.addChildren(variable, first); + } + else if (context == CODE_BLOCK_CONTEXT){ + variable = Factory.createCompositeElement(LOCAL_VARIABLE); + TreeUtil.addChildren(variable, first); + } + else{ + LOG.assertTrue(false); + return null; + } + + CompositeElement variable1 = variable; + boolean unclosed = false; + boolean eatSemicolon = true; + while(true){ + while(lexer.getTokenType() == LBRACKET){ + TreeUtil.addChildren(variable1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (lexer.getTokenType() != RBRACKET){ + TreeUtil.addChildren(variable1, Factory.createErrorElement("']' expected")); + unclosed = true; + break; + } + TreeUtil.addChildren(variable1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + if (lexer.getTokenType() == EQ){ + TreeUtil.addChildren(variable1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr != null){ + TreeUtil.addChildren(variable1, expr); + } + else{ + TreeUtil.addChildren(variable1, Factory.createErrorElement("Expression expected")); + unclosed = true; + break; + } + } + + if (lexer.getTokenType() != COMMA) break; + + TreeElement comma = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + TreeUtil.insertAfter(variable1, comma); + + if (lexer.getTokenType() != IDENTIFIER){ + TreeUtil.insertAfter(comma, Factory.createErrorElement("Identifier expected")); + unclosed = true; + eatSemicolon = false; + break; + } + + CompositeElement variable2 = Factory.createCompositeElement(variable1.getElementType()); + TreeUtil.insertAfter(comma, variable2); + TreeUtil.addChildren(variable2, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + variable1 = variable2; + } + + if (lexer.getTokenType() == SEMICOLON && eatSemicolon){ + TreeUtil.addChildren(variable1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + // special treatment (see testMultiLineUnclosed()) + if (lexer.getTokenType() != null){ + int spaceStart = ((FilterLexer)lexer).getPrevTokenEnd(); + int spaceEnd = lexer.getTokenStart(); + char[] buffer = lexer.getBuffer(); + int lineStart = CharArrayUtil.shiftBackwardUntil(buffer, spaceEnd, "\n\r"); + if (ParseUtil.getStoredPosition(startPos) < lineStart && lineStart < spaceStart){ + ParseUtil.restorePosition(lexer, startPos); + int bufferEnd = lexer.getBufferEnd(); + int newBufferEnd = CharArrayUtil.shiftForward(buffer, lineStart, "\n\r \t"); + lexer.start(buffer, ParseUtil.getStoredPosition(startPos), newBufferEnd, ParseUtil.getStoredState(startPos)); + TreeElement result = parseDeclaration(lexer, context); + lexer.start(buffer, lexer.getTokenStart(), bufferEnd, lexer.getState()); + return result; + } + } + + if (!unclosed){ + TreeUtil.addChildren(variable1, Factory.createErrorElement("';' expected")); + } + } + + return variable; + } + + public CompositeElement parseAnnotationList (FilterLexer lexer) { + CompositeElement modifierList = Factory.createCompositeElement(MODIFIER_LIST); + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + if (tokenType == AT) { + long pos = ParseUtil.savePosition(lexer); + lexer.advance(); + IElementType nextTokenType = lexer.getTokenType(); + ParseUtil.restorePosition(lexer, pos); + if (nextTokenType != null && KEYWORD_BIT_SET.isInSet(nextTokenType)) { + break; + } + CompositeElement annotation = parseAnnotation (lexer); + TreeUtil.addChildren(modifierList, annotation); + } else { + break; + } + } + + return modifierList; + } + + public CompositeElement parseModifierList (Lexer lexer) { + CompositeElement modifierList = Factory.createCompositeElement(MODIFIER_LIST); + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + if (MODIFIER_BIT_SET.isInSet(tokenType)) { + TreeUtil.addChildren(modifierList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } else if (tokenType == AT) { + long pos = ParseUtil.savePosition(lexer); + lexer.advance(); + IElementType nextTokenType = lexer.getTokenType(); + ParseUtil.restorePosition(lexer, pos); + if (nextTokenType != null && KEYWORD_BIT_SET.isInSet(nextTokenType)) { + break; + } + CompositeElement annotation = parseAnnotation (lexer); + TreeUtil.addChildren(modifierList, annotation); + } else { + break; + } + } + + return modifierList; + } + + public static CompositeElement parseAnnotationFromText (PsiManager manager, String text, CharTable charTable) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + char[] buffer = text.toCharArray(); + lexer.start(buffer, 0, buffer.length); + ParsingContext context = new ParsingContext(charTable); + CompositeElement first = context.getDeclarationParsing().parseAnnotation(lexer); + if (first == null) return null; + if (lexer.getTokenType() != null) return null; + + final FileElement dummyRoot = new DummyHolder(manager, null, charTable).getTreeElement(); + TreeUtil.addChildren(dummyRoot, first); + + ParseUtil.insertMissingTokens(dummyRoot, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return first; + } + + private CompositeElement parseAnnotation(Lexer lexer) { + CompositeElement annotation = Factory.createCompositeElement(ANNOTATION); + TreeUtil.addChildren(annotation, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeElement classReference = parseJavaCodeReference(lexer, true); + if (classReference != null) { + TreeUtil.addChildren(annotation, classReference); + } else { + TreeUtil.addChildren(annotation, Factory.createErrorElement("Class reference expected")); + } + + TreeUtil.addChildren(annotation, parseAnnotationParameterList(lexer)); + + return annotation; + } + + private CompositeElement parseAnnotationParameterList(Lexer lexer) { + CompositeElement parameterList = Factory.createCompositeElement(ANNOTATION_PARAMETER_LIST); + if (lexer.getTokenType() == LPARENTH) { + TreeUtil.addChildren(parameterList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + IElementType tokenType = lexer.getTokenType(); + if (tokenType == RPARENTH) { + TreeUtil.addChildren(parameterList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return parameterList; + } + else { + TreeUtil.addChildren(parameterList, parseAnnotationParameter(lexer, true)); + } + + + while (true) { + tokenType = lexer.getTokenType(); + if (tokenType == RPARENTH) { + TreeUtil.addChildren(parameterList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return parameterList; + } + else if (tokenType == COMMA) { + TreeUtil.addChildren(parameterList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeUtil.addChildren(parameterList, parseAnnotationParameter(lexer, false)); + } + else { + TreeUtil.addChildren(parameterList, Factory.createErrorElement(") expected")); + parameterList.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + return parameterList; + } + } + } + else { + return parameterList; + } + } + + private CompositeElement parseAnnotationParameter(Lexer lexer, boolean mayBeSimple) { + CompositeElement pair = Factory.createCompositeElement(NAME_VALUE_PAIR); + if (mayBeSimple) { + long pos = ParseUtil.savePosition(lexer); + TreeElement value = parseAnnotationMemberValue(lexer); + if (value != null && lexer.getTokenType() == RPARENTH) { + TreeUtil.addChildren(pair, value); + return pair; + } else { + ParseUtil.restorePosition(lexer, pos); + } + } + + if (lexer.getTokenType() != IDENTIFIER) { + TreeUtil.addChildren(pair, Factory.createErrorElement("Identifier expected")); + } else { + TreeUtil.addChildren(pair, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + if (lexer.getTokenType() != EQ) { + TreeUtil.addChildren(pair, Factory.createErrorElement("= expected")); + } else { + TreeUtil.addChildren(pair, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + TreeUtil.addChildren(pair, parseAnnotationMemberValue(lexer)); + return pair; + } + + private TreeElement parseAnnotationMemberValue(Lexer lexer) { + TreeElement result; + if (lexer.getTokenType() == AT) { + result = parseAnnotation(lexer); + } else if (lexer.getTokenType() == LBRACE) { + result = parseArrayMemberValue (lexer); + } else { + result = myContext.getExpressionParsing().parseConditionalExpression(lexer); + } + + if (result == null) { + result = Factory.createErrorElement("Value expected"); + } + + return result; + } + + private CompositeElement parseArrayMemberValue(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == LBRACE); + CompositeElement memberList = Factory.createCompositeElement(ANNOTATION_ARRAY_INITIALIZER); + TreeUtil.addChildren(memberList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + IElementType tokenType = lexer.getTokenType(); + if (tokenType == RBRACE) { + TreeUtil.addChildren(memberList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return memberList; + } else { + TreeUtil.addChildren(memberList, parseAnnotationMemberValue(lexer)); + } + + + while (true) { + tokenType = lexer.getTokenType(); + if (tokenType == RBRACE) { + TreeUtil.addChildren(memberList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return memberList; + } else if (tokenType == COMMA) { + TreeUtil.addChildren(memberList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeUtil.addChildren(memberList, parseAnnotationMemberValue(lexer)); + if (lexer.getTokenType() == RBRACE) { + TreeUtil.addChildren(memberList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return memberList; + } + } else { + TreeUtil.addChildren(memberList, Factory.createErrorElement("} expected")); + memberList.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + return memberList; + } + } + } + + private TreeElement parseClassFromKeyword(Lexer lexer, TreeElement modifierList, TreeElement atToken) { + IElementType tokenType; + CompositeElement aClass = Factory.createCompositeElement(CLASS); + TreeUtil.addChildren(aClass, modifierList); + + if (atToken != null) { + TreeUtil.addChildren(aClass, atToken); + } + + final IElementType keywordTokenType = lexer.getTokenType(); + LOG.assertTrue(CLASS_KEYWORD_BIT_SET.isInSet(keywordTokenType)); + final boolean isEnum = keywordTokenType == ENUM_KEYWORD; + TreeUtil.addChildren(aClass, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (lexer.getTokenType() != IDENTIFIER){ + TreeElement errorElement = Factory.createErrorElement("Identifier expected"); + TreeUtil.addChildren(aClass, errorElement); + return aClass.firstChild; + } + + TreeUtil.addChildren(aClass, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement classParameterList = parseTypeParameterList(lexer); + TreeUtil.addChildren(aClass, classParameterList); + + if (!isEnum) { + TreeElement extendsList = parseExtendsList(lexer); + if (extendsList == null){ + extendsList = Factory.createCompositeElement(EXTENDS_LIST); + } + TreeUtil.addChildren(aClass, extendsList); + } + + TreeElement implementsList = parseImplementsList(lexer); + if (implementsList == null){ + implementsList = Factory.createCompositeElement(IMPLEMENTS_LIST); + } + TreeUtil.addChildren(aClass, implementsList); + + if (lexer.getTokenType() != LBRACE){ + CompositeElement invalidElementsGroup = Factory.createErrorElement("'{' expected"); + TreeUtil.addChildren(aClass, invalidElementsGroup); + Loop: + while(true){ + tokenType = lexer.getTokenType(); + if (tokenType == IDENTIFIER || tokenType == COMMA || tokenType == EXTENDS_KEYWORD || tokenType == IMPLEMENTS_KEYWORD) { + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + } + else { + break Loop; + } + lexer.advance(); + } + } + + parseClassBodyWithBraces(aClass, lexer, atToken != null, isEnum); + + return aClass; + } + + public TreeElement parseTypeParameterList(Lexer lexer) { + final CompositeElement result = Factory.createCompositeElement(TYPE_PARAMETER_LIST); + if (lexer.getTokenType() != LT){ + return result; + } + TreeUtil.addChildren(result, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + final TreeElement firstParameter = parseTypeParameter(lexer); + if (firstParameter != null){ + TreeUtil.addChildren(result, firstParameter); + } + + while(lexer.getTokenType() == COMMA){ + TreeUtil.addChildren(result, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + final TreeElement parameter = parseTypeParameter(lexer); + if (parameter != null){ + TreeUtil.addChildren(result, parameter); + } + } + + if (lexer.getTokenType() == GT){ + TreeUtil.addChildren(result, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + if (lexer.getTokenType() == IDENTIFIER) { + // hack for completion + final long position = ParseUtil.savePosition(lexer); + lexer.advance(); + final IElementType lookahead = lexer.getTokenType(); + ParseUtil.restorePosition(lexer, position); + if (lookahead == GT) { + final CompositeElement errorElement = Factory.createErrorElement("Unexpected identifier"); + TreeUtil.addChildren(errorElement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + TreeUtil.addChildren(result, errorElement); + lexer.advance(); + TreeUtil.addChildren(result, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } else { + TreeUtil.addChildren(result, Factory.createErrorElement("'>' expected.")); + } + } else { + TreeUtil.addChildren(result, Factory.createErrorElement("'>' expected.")); + } + } + + return result; + } + + public static TreeElement parseTypeParameterText(PsiManager manager, char[] buffer, CharTable charTable) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, 0, buffer.length); + ParsingContext context = new ParsingContext(charTable); + CompositeElement typeParameter = context.getDeclarationParsing().parseTypeParameter(lexer); + if (typeParameter == null) return null; + if (lexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(typeParameter, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return typeParameter; + } + + public CompositeElement parseTypeParameter(Lexer lexer) { + if (lexer.getTokenType() != IDENTIFIER) return null; + final CompositeElement result = Factory.createCompositeElement(TYPE_PARAMETER); + TreeUtil.addChildren(result, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement extendsBound = parseReferenceList(lexer, EXTENDS_BOUND_LIST, AND, EXTENDS_KEYWORD); + if (extendsBound == null){ + extendsBound = Factory.createCompositeElement(EXTENDS_BOUND_LIST); + } + TreeUtil.addChildren(result, extendsBound); + return result; + } + + protected TreeElement parseClassBodyWithBraces(CompositeElement root, Lexer lexer, boolean annotationInterface, boolean isEnum) { + if (lexer.getTokenType() != LBRACE) return null; + LeafElement lbrace = (LeafElement)ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + TreeUtil.addChildren(root, lbrace); + lexer.advance(); + final int chameleonStart = lexer.getTokenStart(); + LeafElement rbrace = null; + int braceCount = 1; + int chameleonEnd = chameleonStart; + while(braceCount > 0){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) + break; + if (tokenType == LBRACE){ + braceCount++; + } + else if (tokenType == RBRACE){ + braceCount--; + } + if (braceCount == 0){ + rbrace = (LeafElement)ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + } + chameleonEnd = lexer.getTokenEnd(); + lexer.advance(); + } + final int context = annotationInterface ? ClassBodyParsing.ANNOTATION : isEnum ? ClassBodyParsing.ENUM : ClassBodyParsing.CLASS; + final int bufferEnd = lexer.getBufferEnd(); + final int endOffset = rbrace != null ? chameleonEnd - 1: bufferEnd; + final int state = lexer.getState(); + lexer.start(lexer.getBuffer(), chameleonStart, endOffset, state); + myContext.getClassBodyParsing().parseClassBody(root, lexer, context); + lexer.start(lexer.getBuffer(), chameleonStart, bufferEnd, state); + if (rbrace != null){ + TreeUtil.addChildren(root, rbrace); + while(lexer.getTokenStart() < chameleonEnd) lexer.advance(); + } + else{ + TreeUtil.addChildren(root, Factory.createErrorElement("'}' expected")); + while(lexer.getTokenStart() < endOffset) lexer.advance(); + } + + return lbrace; + } + + public TreeElement parseEnumConstant (Lexer lexer) { + long pos = ParseUtil.savePosition(lexer); + CompositeElement modifierList = parseModifierList(lexer); + if (lexer.getTokenType() == IDENTIFIER) { + final CompositeElement element = Factory.createCompositeElement(ENUM_CONSTANT); + TreeUtil.addChildren(element, modifierList); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement argumentList = myContext.getExpressionParsing().parseArgumentList(lexer); + TreeUtil.addChildren(element, argumentList); + if (lexer.getTokenType() == LBRACE) { + CompositeElement classElement = Factory.createCompositeElement(ENUM_CONSTANT_INITIALIZER); + TreeUtil.addChildren(element, classElement); + parseClassBodyWithBraces(classElement, lexer, false, false); + } + return element; + } else { + ParseUtil.restorePosition(lexer, pos); + return null; + } + } + + private void parseMethodFromLparenth(Lexer lexer, CompositeElement method, boolean annotationMethod) { + CompositeElement parmList = parseParameterList(lexer); + TreeUtil.addChildren(method, parmList); + + while(lexer.getTokenType() == LBRACKET){ + TreeUtil.addChildren(method, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (lexer.getTokenType() != RBRACKET){ + TreeUtil.addChildren(method, Factory.createErrorElement("']' expected")); + break; + } + TreeUtil.addChildren(method, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + TreeElement throwsList = parseThrowsList(lexer); + if (throwsList == null){ + throwsList = Factory.createCompositeElement(THROWS_LIST); + } + TreeUtil.addChildren(method, throwsList); + + if (annotationMethod && lexer.getTokenType() == DEFAULT_KEYWORD) { + TreeUtil.addChildren(method, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeUtil.addChildren(method, parseAnnotationMemberValue(lexer)); + } + + IElementType tokenType = lexer.getTokenType(); + if (tokenType != SEMICOLON && tokenType != LBRACE){ + CompositeElement invalidElementsGroup = Factory.createErrorElement("'{' or ';' expected"); + TreeUtil.addChildren(method, invalidElementsGroup); + Loop: + while(true){ + tokenType = lexer.getTokenType(); + if (tokenType == IDENTIFIER || tokenType == COMMA || tokenType == THROWS_KEYWORD) { + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + } + else { + break Loop; + } + lexer.advance(); + } + } + + if (lexer.getTokenType() == SEMICOLON){ + TreeUtil.addChildren(method, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else if (lexer.getTokenType() == LBRACE){ + CompositeElement codeBlock = myContext.getStatementParsing().parseCodeBlock(lexer, false); + TreeUtil.addChildren(method, codeBlock); + } + } + + public CompositeElement parseParameterList(Lexer lexer) { + CompositeElement paramList = Factory.createCompositeElement(PARAMETER_LIST); + LOG.assertTrue(lexer.getTokenType() == LPARENTH); + TreeUtil.addChildren(paramList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + CompositeElement invalidElementsGroup = null; + boolean commaExpected = false; + int paramCount = 0; + while(true){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null || tokenType == RPARENTH){ + boolean noLastParm = !commaExpected && paramCount > 0; + if (noLastParm){ + TreeUtil.addChildren(paramList, Factory.createErrorElement("Identifier or type expected")); + } + + if (tokenType == RPARENTH){ + TreeUtil.addChildren(paramList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + if (!noLastParm){ + TreeUtil.addChildren(paramList, Factory.createErrorElement("')' expected")); + } + } + break; + } + + if (commaExpected){ + if (tokenType == COMMA){ + TreeUtil.addChildren(paramList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + commaExpected = false; + invalidElementsGroup = null; + continue; + } + } + else{ + TreeElement param = parseParameter(lexer, true); + if (param != null){ + TreeUtil.addChildren(paramList, param); + commaExpected = true; + invalidElementsGroup = null; + paramCount++; + continue; + } + } + + if (invalidElementsGroup == null){ + if (tokenType == COMMA){ + TreeUtil.addChildren(paramList, Factory.createErrorElement("Parameter expected")); + TreeUtil.addChildren(paramList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + continue; + } + else{ + invalidElementsGroup = Factory.createErrorElement(commaExpected ? "',' expected" : "Parameter expected"); + TreeUtil.addChildren(paramList, invalidElementsGroup); + } + } + + // adding a reference, not simple tokens allows "Browse .." to work well + CompositeElement ref = parseJavaCodeReference(lexer, true); + if (ref != null){ + TreeUtil.addChildren(invalidElementsGroup, ref); + } + else{ + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + } + + return paramList; + } + + public CompositeElement parseExtendsList(Lexer lexer) { + return parseReferenceList(lexer, EXTENDS_LIST, COMMA, EXTENDS_KEYWORD); + } + + public CompositeElement parseImplementsList(Lexer lexer) { + return parseReferenceList(lexer, IMPLEMENTS_LIST, COMMA, IMPLEMENTS_KEYWORD); + } + + public CompositeElement parseThrowsList(Lexer lexer) { + return parseReferenceList(lexer, THROWS_LIST, COMMA, THROWS_KEYWORD); + } + + public CompositeElement parseReferenceList(Lexer lexer, IElementType elementType, IElementType referenceDelimiter, IElementType keyword) { + if (lexer.getTokenType() != keyword) return null; + + CompositeElement list = Factory.createCompositeElement(elementType); + TreeUtil.addChildren(list, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement classReference = parseJavaCodeReference(lexer, true); + if (classReference != null){ + TreeUtil.addChildren(list, classReference); + while(true){ + if (lexer.getTokenType() != referenceDelimiter) break; + TreeElement comma = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + TreeUtil.addChildren(list, comma); + + classReference = parseJavaCodeReference(lexer, true); + if (classReference == null){ + TreeUtil.addChildren(list, Factory.createErrorElement("Identifier expected")); + break; + } + TreeUtil.addChildren(list, classReference); + } + } + else{ + TreeUtil.addChildren(list, Factory.createErrorElement("Identifier expected")); + } + + return list; + } + + public static CompositeElement parseParameterText(PsiManager manager, char[] buffer, CharTable charTable) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, 0, buffer.length); + ParsingContext context = new ParsingContext(charTable); + TreeElement first = context.getDeclarationParsing().parseParameter(lexer, true); + if (first == null || first.getElementType() != PARAMETER) return null; + if (lexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens((CompositeElement)first, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return (CompositeElement)first; + } + + public TreeElement parseParameter(Lexer lexer, boolean allowEllipsis) { + long pos = ParseUtil.savePosition(lexer); + + CompositeElement modifierList = parseModifierList(lexer); + + CompositeElement type = allowEllipsis ? parseTypeWithEllipsis(lexer) : parseType(lexer); + if (type == null){ + ParseUtil.restorePosition(lexer, pos); + return null; + } + + CompositeElement param = Factory.createCompositeElement(PARAMETER); + TreeUtil.addChildren(param, modifierList); + TreeUtil.addChildren(param, type); + + if (lexer.getTokenType() == IDENTIFIER){ + TreeUtil.addChildren(param, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + while(lexer.getTokenType() == LBRACKET){ + TreeUtil.addChildren(param, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (lexer.getTokenType() != RBRACKET){ + TreeUtil.addChildren(param, Factory.createErrorElement("']' expected")); + break; + } + TreeUtil.addChildren(param, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + return param; + } else{ + TreeUtil.addChildren(param, Factory.createErrorElement("Identifier expected")); + return param.firstChild; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ExpressionParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ExpressionParsing.java new file mode 100644 index 00000000000..27a789d6e05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ExpressionParsing.java @@ -0,0 +1,889 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; + +public class ExpressionParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ExpressionParsing"); + + public ExpressionParsing(ParsingContext context) { + super(context); + } + + public static CompositeElement parseExpressionText(PsiManager manager, char[] buffer, int startOffset, int endOffset, CharTable table) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, startOffset, endOffset); + ParsingContext context = new ParsingContext(table); + CompositeElement expression = context.getExpressionParsing().parseExpression(lexer); + if (expression == null) return null; + expression.putUserData(CharTable.CHAR_TABLE_KEY, table); + if (lexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(expression, originalLexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return expression; + } + + public TreeElement parseExpressionTextFragment(PsiManager manager, char[] buffer, int startOffset, int endOffset, int state) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (state >= 0) { + lexer.start(buffer, startOffset, endOffset, state); + } + else { + lexer.start(buffer, startOffset, endOffset); + } + + final FileElement dummyRoot = new DummyHolder(manager, null, myContext.getCharTable()).getTreeElement(); + + CompositeElement expression = parseExpression(lexer); + if (expression != null) { + TreeUtil.addChildren(dummyRoot, expression); + } + + if (lexer.getTokenType() != null) { + TreeUtil.addChildren(dummyRoot, Factory.createErrorElement("Unexpected token(s) beyond the end of expression")); + while (lexer.getTokenType() != null) { + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + } + + ParseUtil.insertMissingTokens(dummyRoot, originalLexer, 0, buffer.length, state, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, + myContext); + return dummyRoot.firstChild; + } + + public CompositeElement parseExpression(Lexer lexer) { + return parseConstruct((FilterLexer)lexer, PARSE_ASSIGNMENT); + } + + private static final int PARSE_ASSIGNMENT = 0; + private static final int PARSE_CONDITIONAL = 1; + private static final int PARSE_COND_OR = 2; + private static final int PARSE_COND_AND = 3; + private static final int PARSE_OR = 4; + private static final int PARSE_XOR = 5; + private static final int PARSE_AND = 6; + private static final int PARSE_EQUALITY = 7; + private static final int PARSE_RELATIONAL = 8; + private static final int PARSE_SHIFT = 9; + private static final int PARSE_ADDITIVE = 10; + private static final int PARSE_MULTIPLICATIVE = 11; + private static final int PARSE_UNARY = 12; + private static final int PARSE_POSTFIX = 13; + private static final int PARSE_PRIMARY = 14; + private static final int PARSE_CLASS_OBJECT_ACCESS = 15; + private static final int PARSE_ARGUMENT_LIST = 16; + private static final int PARSE_ARRAY_INITIALIZER = 17; + private static final int PARSE_TYPE = 18; + + private static final TokenSet COND_OR_SIGN_BIT_SET = TokenSet.create(new IElementType[]{OROR}); + private static final TokenSet COND_AND_SIGN_BIT_SET = TokenSet.create(new IElementType[]{ANDAND}); + private static final TokenSet OR_SIGN_BIT_SET = TokenSet.create(new IElementType[]{OR}); + private static final TokenSet XOR_SIGN_BIT_SET = TokenSet.create(new IElementType[]{XOR}); + private static final TokenSet AND_SIGN_BIT_SET = TokenSet.create(new IElementType[]{AND}); + private static final TokenSet EQUALITY_SIGN_BIT_SET = TokenSet.create(new IElementType[]{EQEQ, NE}); + private static final TokenSet SHIFT_SIGN_BIT_SET = TokenSet.create(new IElementType[]{LTLT, GTGT, GTGTGT}); + private static final TokenSet ADDITIVE_SIGN_BIT_SET = TokenSet.create(new IElementType[]{PLUS, MINUS}); + private static final TokenSet MULTIPLICATIVE_SIGN_BIT_SET = TokenSet.create(new IElementType[]{ASTERISK, DIV, PERC}); + + private CompositeElement parseConstruct(FilterLexer lexer, int number) { + switch (number) { + case PARSE_ASSIGNMENT: + return parseAssignmentExpression(lexer); + + case PARSE_CONDITIONAL: + return parseConditionalExpression(lexer); + + case PARSE_COND_OR: + return parseBinaryExpression(lexer, PARSE_COND_AND, COND_OR_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_COND_AND: + return parseBinaryExpression(lexer, PARSE_OR, COND_AND_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_OR: + return parseBinaryExpression(lexer, PARSE_XOR, OR_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_XOR: + return parseBinaryExpression(lexer, PARSE_AND, XOR_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_AND: + return parseBinaryExpression(lexer, PARSE_EQUALITY, AND_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_EQUALITY: + return parseBinaryExpression(lexer, PARSE_RELATIONAL, EQUALITY_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_RELATIONAL: + return parseRelationalExpression(lexer); + + case PARSE_SHIFT: + return parseBinaryExpression(lexer, PARSE_ADDITIVE, SHIFT_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_ADDITIVE: + return parseBinaryExpression(lexer, PARSE_MULTIPLICATIVE, ADDITIVE_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_MULTIPLICATIVE: + return parseBinaryExpression(lexer, PARSE_UNARY, MULTIPLICATIVE_SIGN_BIT_SET, BINARY_EXPRESSION); + + case PARSE_UNARY: + return parseUnaryExpression(lexer); + + case PARSE_POSTFIX: + return parsePostfixExpression(lexer); + + case PARSE_PRIMARY: + return parsePrimaryExpression(lexer); + + case PARSE_CLASS_OBJECT_ACCESS: + return parseClassObjectAccessExpression(lexer); + + case PARSE_ARGUMENT_LIST: + return parseArgumentList(lexer); + + case PARSE_ARRAY_INITIALIZER: + return parseArrayInitializerExpression(lexer); + + case PARSE_TYPE: + return parseType(lexer); + + default: + LOG.assertTrue(false); + return null; + } + } + + private CompositeElement parseBinaryExpression(FilterLexer lexer, int argNumber, TokenSet opSignBitSet, IElementType elementType) { + CompositeElement element = parseConstruct(lexer, argNumber); + if (element == null) return null; + + while (true) { + IElementType tokenType = GTTokens.getTokenType(lexer); + if (tokenType == null) break; + if (!opSignBitSet.isInSet(tokenType)) break; + + CompositeElement result = Factory.createCompositeElement(elementType); + TreeUtil.addChildren(result, element); + TreeUtil.addChildren(result, GTTokens.createTokenElementAndAdvance(tokenType, lexer, myContext.getCharTable())); + + TreeElement element1 = parseConstruct(lexer, argNumber); + if (element1 == null) { + TreeUtil.addChildren(result, Factory.createErrorElement("Expression expected")); + return result; + } + + TreeUtil.addChildren(result, element1); + + element = result; + } + + return element; + } + + private CompositeElement parseAssignmentExpression(FilterLexer lexer) { + CompositeElement element1 = parseConditionalExpression(lexer); + if (element1 == null) return null; + + IElementType tokenType = GTTokens.getTokenType(lexer); + if (tokenType == EQ || + tokenType == ASTERISKEQ || + tokenType == DIVEQ || + tokenType == PERCEQ || + tokenType == PLUSEQ || + tokenType == MINUSEQ || + tokenType == LTLTEQ || + tokenType == GTGTEQ || + tokenType == GTGTGTEQ || + tokenType == ANDEQ || + tokenType == OREQ || + tokenType == XOREQ) { + { + CompositeElement element = Factory.createCompositeElement(ASSIGNMENT_EXPRESSION); + TreeUtil.addChildren(element, element1); + + TreeUtil.addChildren(element, GTTokens.createTokenElementAndAdvance(tokenType, lexer, myContext.getCharTable())); + + TreeElement element2 = parseAssignmentExpression(lexer); + if (element2 == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + + TreeUtil.addChildren(element, element2); + return element; + } + } + else { + return element1; + } + } + + public CompositeElement parseConditionalExpression(Lexer lexer) { + CompositeElement element1 = parseConstruct((FilterLexer)lexer, PARSE_COND_OR); + if (element1 == null) return null; + + if (lexer.getTokenType() != QUEST) return element1; + + CompositeElement element = Factory.createCompositeElement(CONDITIONAL_EXPRESSION); + TreeUtil.addChildren(element, element1); + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + CompositeElement element2 = parseExpression(lexer); + if (element2 == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + + TreeUtil.addChildren(element, element2); + + if (lexer.getTokenType() != COLON) { + TreeUtil.addChildren(element, Factory.createErrorElement("':' expected")); + return element; + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + CompositeElement element3 = parseConditionalExpression(lexer); + if (element3 == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + + TreeUtil.addChildren(element, element3); + + return element; + } + + private CompositeElement parseRelationalExpression(FilterLexer lexer) { + CompositeElement element = parseConstruct(lexer, PARSE_SHIFT); + if (element == null) return null; + + Loop: + while (true) { + IElementType tokenType = GTTokens.getTokenType(lexer); + if (tokenType == null) break; + + IElementType elementType; + int argNumber; + if (tokenType == LT || tokenType == GT || tokenType == LE || tokenType == GE) { + elementType = BINARY_EXPRESSION; + argNumber = PARSE_SHIFT; + } + else if (tokenType == INSTANCEOF_KEYWORD) { + elementType = INSTANCE_OF_EXPRESSION; + argNumber = PARSE_TYPE; + } + else { + break Loop; + } + + CompositeElement result = Factory.createCompositeElement(elementType); + TreeUtil.addChildren(result, element); + TreeUtil.addChildren(result, GTTokens.createTokenElementAndAdvance(tokenType, lexer, myContext.getCharTable())); + + TreeElement element1 = parseConstruct(lexer, argNumber); + if (element1 == null) { + CompositeElement errorElement = Factory.createErrorElement(argNumber == PARSE_TYPE ? "Type expected" : "Expression expected"); + TreeUtil.addChildren(result, errorElement); + return result; + } + + TreeUtil.addChildren(result, element1); + + element = result; + } + + return element; + } + + private CompositeElement parseUnaryExpression(FilterLexer lexer) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == PLUS || tokenType == MINUS || tokenType == PLUSPLUS || tokenType == MINUSMINUS || tokenType == TILDE || tokenType == EXCL) { + { + CompositeElement element = Factory.createCompositeElement(PREFIX_EXPRESSION); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement element1 = parseUnaryExpression(lexer); + if (element1 == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + TreeUtil.addChildren(element, element1); + return element; + } + } + else if (tokenType == LPARENTH) { + { + long pos = ParseUtil.savePosition(lexer); + + TreeElement lparenth = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + TreeElement type = parseType(lexer); + if (type == null || lexer.getTokenType() != RPARENTH) { + ParseUtil.restorePosition(lexer, pos); + return parsePostfixExpression(lexer); + } + + final TreeElement rparenth = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + if (lexer.getTokenType() == PLUS || lexer.getTokenType() == MINUS || + lexer.getTokenType() == PLUSPLUS || lexer.getTokenType() == MINUSMINUS) { + if (!PRIMITIVE_TYPE_BIT_SET.isInSet(((CompositeElement)type).firstChild.getElementType())) { + ParseUtil.restorePosition(lexer, pos); + return parsePostfixExpression(lexer); + } + } + + final CompositeElement expr = parseUnaryExpression(lexer); + if (expr == null) { + ParseUtil.restorePosition(lexer, pos); + return parsePostfixExpression(lexer); + } + + CompositeElement element = Factory.createCompositeElement(TYPE_CAST_EXPRESSION); + TreeUtil.addChildren(element, lparenth); + TreeUtil.addChildren(element, type); + TreeUtil.addChildren(element, rparenth); + TreeUtil.addChildren(element, expr); + return element; + } + } + else { + return parsePostfixExpression(lexer); + } + } + + private CompositeElement parsePostfixExpression(FilterLexer lexer) { + CompositeElement element = parsePrimaryExpression(lexer); + if (element == null) return null; + + while (lexer.getTokenType() == PLUSPLUS || lexer.getTokenType() == MINUSMINUS) { + CompositeElement element1 = Factory.createCompositeElement(POSTFIX_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeUtil.addChildren(element1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + element = element1; + } + + return element; + } + + private CompositeElement parsePrimaryExpression(FilterLexer lexer) { + long startPos = ParseUtil.savePosition(lexer); + + CompositeElement element = parsePrimaryExpressionStart(lexer); + if (element == null) return null; + + while (true) { + IElementType i = lexer.getTokenType(); + if (i == DOT) { + { + long pos = ParseUtil.savePosition(lexer); + TreeElement dot = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + IElementType tokenType = lexer.getTokenType(); + if (tokenType == LT) { + final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false); + CompositeElement element1 = Factory.createCompositeElement(REFERENCE_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeUtil.addChildren(element1, dot); + + TreeUtil.addChildren(element1, referenceParameterList); + if (lexer.getTokenType() == IDENTIFIER) { + TreeUtil.addChildren(element1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else { + TreeUtil.addChildren(element1, Factory.createErrorElement("Identifier expected")); + return element1; + } + + element = element1; + //} + } + else if (tokenType == CLASS_KEYWORD && element.getElementType() == REFERENCE_EXPRESSION) { + long pos1 = ParseUtil.savePosition(lexer); + ParseUtil.restorePosition(lexer, startPos); + CompositeElement element1 = parseClassObjectAccessExpression(lexer); + if (lexer.getTokenStart() <= ParseUtil.getStoredPosition(pos1)) { + ParseUtil.restorePosition(lexer, pos1); + TreeUtil.addChildren(element, dot); + TreeUtil.addChildren(element, Factory.createErrorElement("Identifier expected")); + return element; + } + element = element1; + } + else if (tokenType == NEW_KEYWORD) { + //final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false); + element = parseNewExpression(lexer, element, dot/*, referenceParameterList*/); + } + else if ((tokenType == THIS_KEYWORD || tokenType == SUPER_KEYWORD) + && element.getElementType() == REFERENCE_EXPRESSION) { + + ParseUtil.restorePosition(lexer, startPos); + CompositeElement element1 = parseJavaCodeReference(lexer, false); // don't eat the last dot before "this" or "super"! + if (element1 == null || lexer.getTokenType() != DOT || lexer.getTokenStart() != ParseUtil.getStoredPosition(pos)) { + ParseUtil.restorePosition(lexer, pos); + return element; + } + + IElementType type = tokenType == THIS_KEYWORD ? THIS_EXPRESSION : SUPER_EXPRESSION; + CompositeElement element2 = Factory.createCompositeElement(type); + TreeUtil.addChildren(element2, element1); + TreeUtil.addChildren(element2, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (lexer.getTokenType() != tokenType) { + ParseUtil.restorePosition(lexer, pos); + return element; + } + TreeUtil.addChildren(element2, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + element = element2; + } + else if (tokenType == SUPER_KEYWORD) { + CompositeElement element1 = Factory.createCompositeElement(REFERENCE_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeUtil.addChildren(element1, dot); + TreeUtil.addChildren(element1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + element = element1; + } + else { + final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false); + CompositeElement element1 = Factory.createCompositeElement(REFERENCE_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeUtil.addChildren(element1, dot); + + TreeUtil.addChildren(element1, referenceParameterList); + if (lexer.getTokenType() == IDENTIFIER) { + TreeUtil.addChildren(element1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else { + TreeUtil.addChildren(element1, Factory.createErrorElement("Identifier expected")); + return element1; + } + + element = element1; + } + } + } + else if (i == LPARENTH) { + { + if (element.getElementType() != REFERENCE_EXPRESSION) { + if (element.getElementType() == SUPER_EXPRESSION) { + //convert to REFERENCE_EXPRESSION + long pos = ParseUtil.savePosition(lexer); + ParseUtil.restorePosition(lexer, startPos); + CompositeElement qualifier = parsePrimaryExpressionStart(lexer); + if (qualifier != null) { + CompositeElement element1 = Factory.createCompositeElement(REFERENCE_EXPRESSION); + TreeUtil.addChildren(element1, qualifier); + if (lexer.getTokenType() == DOT) { + TreeElement dot = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + TreeUtil.addChildren(element1, dot); + if (lexer.getTokenType() == SUPER_KEYWORD) { + TreeElement superKeyword = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + TreeUtil.addChildren(element1, superKeyword); + element = element1; + continue; + } + } + } + + ParseUtil.restorePosition(lexer, pos); + return element; + } else return element; + } + CompositeElement element1 = Factory.createCompositeElement(METHOD_CALL_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeElement argumentList = parseArgumentList(lexer); + TreeUtil.addChildren(element1, argumentList); + element = element1; + } + } + else if (i == LBRACKET) { + { + long pos = ParseUtil.savePosition(lexer); + TreeElement lbracket = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + if (lexer.getTokenType() == RBRACKET && element.getElementType() == REFERENCE_EXPRESSION) { + ParseUtil.restorePosition(lexer, startPos); + CompositeElement element1 = parseClassObjectAccessExpression(lexer); + if (lexer.getTokenStart() <= ParseUtil.getStoredPosition(pos)) { + ParseUtil.restorePosition(lexer, pos); + return element; + } + element = element1; + } + else { + CompositeElement element1 = Factory.createCompositeElement(ARRAY_ACCESS_EXPRESSION); + TreeUtil.addChildren(element1, element); + TreeUtil.addChildren(element1, lbracket); + + TreeElement expr = parseExpression(lexer); + if (expr == null) { + TreeUtil.addChildren(element1, Factory.createErrorElement("Expression expected")); + return element1; + } + + TreeUtil.addChildren(element1, expr); + + if (lexer.getTokenType() != RBRACKET) { + TreeUtil.addChildren(element1, Factory.createErrorElement("']' expected")); + return element1; + } + + TreeUtil.addChildren(element1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + element = element1; + } + } + } + else { + return element; + } + } + } + + private CompositeElement parsePrimaryExpressionStart(FilterLexer lexer) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == TRUE_KEYWORD || + tokenType == FALSE_KEYWORD || + tokenType == NULL_KEYWORD || + tokenType == INTEGER_LITERAL || + tokenType == LONG_LITERAL || + tokenType == FLOAT_LITERAL || + tokenType == DOUBLE_LITERAL || + tokenType == CHARACTER_LITERAL || + tokenType == STRING_LITERAL) { + { + CompositeElement element = Factory.createCompositeElement(LITERAL_EXPRESSION); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + } + else if (tokenType == LPARENTH) { + { + CompositeElement element = Factory.createCompositeElement(PARENTH_EXPRESSION); + //int pos = ParseUtil.savePosition(lexer); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expression = parseExpression(lexer); + if (expression == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + } + else { + TreeUtil.addChildren(element, expression); + } + + if (lexer.getTokenType() != RPARENTH) { + if (expression != null) { + TreeUtil.addChildren(element, Factory.createErrorElement("')' expected")); + } + } + else { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + return element; + } + } + else if (tokenType == LBRACE) { + return parseArrayInitializerExpression(lexer); + } + else if (tokenType == IDENTIFIER) { + CompositeElement element = Factory.createCompositeElement(REFERENCE_EXPRESSION); + TreeUtil.addChildren(element, Factory.createCompositeElement(REFERENCE_PARAMETER_LIST)); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + else if (tokenType == THIS_KEYWORD) { + { + TreeElement thisKeyword = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + CompositeElement element; + if (lexer.getTokenType() != LPARENTH) { + element = Factory.createCompositeElement(THIS_EXPRESSION); + } + else { + element = Factory.createCompositeElement(REFERENCE_EXPRESSION); + } + + TreeUtil.addChildren(element, thisKeyword); + return element; + } + } + else if (tokenType == SUPER_KEYWORD) { + { + TreeElement superKeyword = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + CompositeElement element; + if (lexer.getTokenType() != LPARENTH) { + element = Factory.createCompositeElement(SUPER_EXPRESSION); + } + else { + element = Factory.createCompositeElement(REFERENCE_EXPRESSION); + } + + TreeUtil.addChildren(element, superKeyword); + return element; + } + } + else if (tokenType == NEW_KEYWORD) {//final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false); + return parseNewExpression(lexer, null, null/*, referenceParameterList*/); + } + else { + if (tokenType != null && PRIMITIVE_TYPE_BIT_SET.isInSet(tokenType)) { + return parseClassObjectAccessExpression(lexer); + } + return null; + } + } + + private CompositeElement parseNewExpression(FilterLexer lexer, + TreeElement qualifier, + TreeElement dot/*, TreeElement referenceParameterList*/) { + LOG.assertTrue(lexer.getTokenType() == NEW_KEYWORD); + + CompositeElement element = Factory.createCompositeElement(NEW_EXPRESSION); + + if (qualifier != null) { + TreeUtil.addChildren(element, qualifier); + TreeUtil.addChildren(element, dot); + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeUtil.addChildren(element, parseReferenceParameterList(lexer, false)); + + boolean isPrimitive; + TreeElement refOrType; + if (lexer.getTokenType() == IDENTIFIER) { + isPrimitive = false; + refOrType = parseJavaCodeReference(lexer, true); + } + else if (lexer.getTokenType() != null && PRIMITIVE_TYPE_BIT_SET.isInSet(lexer.getTokenType())) { + isPrimitive = true; + refOrType = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("Identifier expected")); + return element; + } + + if (!isPrimitive && lexer.getTokenType() == LPARENTH) { + TreeElement argumentList = parseArgumentList(lexer); + if (lexer.getTokenType() == LBRACE && refOrType.getElementType() == JAVA_CODE_REFERENCE) { // anonymous class + CompositeElement classElement = Factory.createCompositeElement(ANONYMOUS_CLASS); + TreeUtil.addChildren(element, classElement); + TreeUtil.addChildren(classElement, refOrType); + TreeUtil.addChildren(classElement, argumentList); + myContext.getDeclarationParsing().parseClassBodyWithBraces(classElement, lexer, false, false); + } + else { + TreeUtil.addChildren(element, refOrType); + TreeUtil.addChildren(element, argumentList); + } + } + else { + TreeUtil.addChildren(element, refOrType); + + if (lexer.getTokenType() != LBRACKET) { + String description = isPrimitive ? "'[' expected" : "'(' or '[' expected"; + TreeUtil.addChildren(element, Factory.createErrorElement(description)); + return element; + } + + int bracketCount = 0; + int dimCount = 0; + while (true) { + if (lexer.getTokenType() != LBRACKET) break; + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement dimExpr = null; + if (bracketCount == dimCount) { + dimExpr = parseExpression(lexer); + if (dimExpr != null) { + TreeUtil.addChildren(element, dimExpr); + dimCount++; + } + } + bracketCount++; + + if (lexer.getTokenType() != RBRACKET) { + TreeUtil.addChildren(element, Factory.createErrorElement("']' expected")); + return element; + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + if (dimCount == 0) { + if (lexer.getTokenType() == LBRACE) { + TreeElement initializer = parseArrayInitializerExpression(lexer); + if (initializer != null) { + TreeUtil.addChildren(element, initializer); + } + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("Array initializer expected")); + } + } + } + + return element; + } + + private CompositeElement parseClassObjectAccessExpression(FilterLexer lexer) { + long pos = ParseUtil.savePosition(lexer); + CompositeElement type = parseType(lexer, false, false); // don't eat last dot before "class"! + if (type == null) return null; + if (lexer.getTokenType() != DOT) { + ParseUtil.restorePosition(lexer, pos); + return null; + } + TreeElement dot = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + if (lexer.getTokenType() != CLASS_KEYWORD) { + ParseUtil.restorePosition(lexer, pos); + return null; + } + CompositeElement element = Factory.createCompositeElement(CLASS_OBJECT_ACCESS_EXPRESSION); + TreeUtil.addChildren(element, type); + TreeUtil.addChildren(element, dot); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + + public CompositeElement parseArgumentList(Lexer lexer) { + if (lexer.getTokenType() != LPARENTH) { + // [dsl,ven] used in EnumConstant + return Factory.createCompositeElement(EXPRESSION_LIST); + } + LOG.assertTrue(lexer.getTokenType() == LPARENTH); + + CompositeElement element = Factory.createCompositeElement(EXPRESSION_LIST); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + int argCount = 0; + while (true) { + TreeElement arg = parseExpression(lexer); + if (arg == null) { + if (lexer.getTokenType() == COMMA || (lexer.getTokenType() == RPARENTH && argCount > 0)) { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + TreeUtil.addChildren(element, Factory.createCompositeElement(EMPTY_EXPRESSION)); + } + else { + break; + } + } + else { + TreeUtil.addChildren(element, arg); + } + argCount++; + + if (lexer.getTokenType() != COMMA) { + break; + } + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + if (lexer.getTokenType() == RPARENTH) { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("')' expected")); + element.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + } + + return element; + } + + private CompositeElement parseArrayInitializerExpression(FilterLexer lexer) { + if (lexer.getTokenType() != LBRACE) return null; + + CompositeElement element = Factory.createCompositeElement(ARRAY_INITIALIZER_EXPRESSION); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + while (true) { + if (lexer.getTokenType() == RBRACE) { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + + if (lexer.getTokenType() == null) { + TreeUtil.addChildren(element, Factory.createErrorElement("'}' expected")); + element.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + return element; + } + + TreeElement arg = parseExpression(lexer); + if (arg == null) { + if (lexer.getTokenType() != COMMA) { + CompositeElement errorElement = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(errorElement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeUtil.addChildren(element, errorElement); + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + } + } + else { + TreeUtil.addChildren(element, arg); + } + + if (lexer.getTokenType() == RBRACE) { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + + if (lexer.getTokenType() == COMMA) { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("',' expected")); + } + } + } +} + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/FileTextParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/FileTextParsing.java new file mode 100644 index 00000000000..4cf487b5a77 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/FileTextParsing.java @@ -0,0 +1,137 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; + +/** + * + */ +public class FileTextParsing extends Parsing { + public FileTextParsing(ParsingContext context) { + super(context); + } + + public static TreeElement parseFileText(PsiManager manager, Lexer lexer, char[] buffer, int startOffset, int endOffset, CharTable table) { + return parseFileText(manager, lexer, buffer, startOffset, endOffset, false, table); + } + + private static final TokenSet IMPORT_LIST_STOPPER_BIT_SET = TokenSet.create(new IElementType[]{CLASS_KEYWORD, INTERFACE_KEYWORD, ENUM_KEYWORD, ASPECT_ASPECT, AT}); + + public static TreeElement parseFileText(PsiManager manager, Lexer lexer, char[] buffer, int startOffset, int endOffset, boolean skipHeader, CharTable table) { + if (lexer == null){ + lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + } + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + filterLexer.start(buffer, startOffset, endOffset); + final FileElement dummyRoot = new DummyHolder(manager, null, table).getTreeElement(); + ParsingContext context = new ParsingContext(dummyRoot.getCharTable()); + + if (!skipHeader){ + TreeElement packageStatement = context.getFileTextParsing().parsePackageStatement(filterLexer); + if (packageStatement != null) { + TreeUtil.addChildren(dummyRoot, packageStatement); + } + + final TreeElement importList = context.getFileTextParsing().parseImportList(filterLexer); + TreeUtil.addChildren(dummyRoot, importList); + } + + CompositeElement invalidElementsGroup = null; + while (true) { + if (filterLexer.getTokenType() == null) break; + + if (filterLexer.getTokenType() == ElementType.SEMICOLON){ + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(filterLexer, dummyRoot.getCharTable())); + filterLexer.advance(); + invalidElementsGroup = null; + continue; + } + + TreeElement first = context.getDeclarationParsing().parseDeclaration(filterLexer, DeclarationParsing.FILE_CONTEXT); + if (first != null) { + TreeUtil.addChildren(dummyRoot, first); + invalidElementsGroup = null; + continue; + } + + if (invalidElementsGroup == null){ + invalidElementsGroup = Factory.createErrorElement("'class' or 'interface' expected"); + TreeUtil.addChildren(dummyRoot, invalidElementsGroup); + } + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(filterLexer, context.getCharTable())); + filterLexer.advance(); + } + + ParseUtil.insertMissingTokens(dummyRoot, lexer, startOffset, endOffset, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return dummyRoot.firstChild; + } + + public CompositeElement parseImportList(Lexer lexer) { + CompositeElement importList = Factory.createCompositeElement(IMPORT_LIST); + if (lexer.getTokenType() == IMPORT_KEYWORD) { + int startPos = lexer.getTokenStart(); + int lastPos = lexer.getTokenEnd(); + boolean prevImportKeyword = true; + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == IMPORT_KEYWORD) { + prevImportKeyword = true; + } + else if (prevImportKeyword && tokenType == STATIC_KEYWORD) { + prevImportKeyword = false; + } + else { + prevImportKeyword = WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(tokenType); + if (tokenType == null || IMPORT_LIST_STOPPER_BIT_SET.isInSet(tokenType) || MODIFIER_BIT_SET.isInSet(tokenType)) break; + } + lastPos = lexer.getTokenEnd(); + lexer.advance(); + } + LeafElement chameleon = Factory.createLeafElement(IMPORT_LIST_TEXT, lexer.getBuffer(), startPos, lastPos, lexer.getState(), myContext.getCharTable()); + TreeUtil.addChildren(importList, chameleon); + } + + return importList; + } + + public CompositeElement parsePackageStatement(Lexer lexer) { + long startPos = ParseUtil.savePosition(lexer); + CompositeElement packageStatement = Factory.createCompositeElement(PACKAGE_STATEMENT); + + if (lexer.getTokenType() != PACKAGE_KEYWORD) { + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + TreeUtil.addChildren(packageStatement, myContext.getDeclarationParsing().parseAnnotationList(filterLexer)); + if (lexer.getTokenType() != PACKAGE_KEYWORD) { + ParseUtil.restorePosition(lexer, startPos); + return null; + } + } + + TreeUtil.addChildren(packageStatement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + TreeElement packageReference = parseJavaCodeReference(lexer, true); + if (packageReference == null) { + ParseUtil.restorePosition(lexer, startPos); + return null; + } + TreeUtil.addChildren(packageStatement, packageReference); + if (lexer.getTokenType() == SEMICOLON) { + TreeUtil.addChildren(packageStatement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } else { + TreeUtil.addChildren(packageStatement, Factory.createErrorElement("';' expected")); + } + return packageStatement; + } +} + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/GTTokens.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/GTTokens.java new file mode 100644 index 00000000000..e48ede7b126 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/GTTokens.java @@ -0,0 +1,116 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.Factory; +import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author dsl + */ +class GTTokens implements JavaTokenType { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.GTTokens"); + static IElementType getTokenType(Lexer lexer) { + if (lexer.getTokenType() != GT) return lexer.getTokenType(); + final long originalPosition = ParseUtil.savePosition(lexer); + final int prevTokenEnd = lexer.getTokenEnd(); + lexer.advance(); + if (lexer.getTokenStart() != prevTokenEnd) { + ParseUtil.restorePosition(lexer, originalPosition); + return GT; + } + final IElementType resultType; + IElementType i1 = lexer.getTokenType(); + if (i1 == EQ) { + resultType = GE; + } + else if (i1 == GT) { + { + final int prevTokenEnd2 = lexer.getTokenEnd(); + lexer.advance(); + if (lexer.getTokenStart() != prevTokenEnd2) { + resultType = GTGT; + } + else { + IElementType i = lexer.getTokenType(); + if (i == GT) { + final int prevTokenEnd3 = lexer.getTokenEnd(); + lexer.advance(); + if (lexer.getTokenStart() != prevTokenEnd3 || lexer.getTokenType() != EQ) { + resultType = GTGTGT; + } + else { + resultType = GTGTGTEQ; + } + } + else if (i == EQ) { + resultType = GTGTEQ; + } + else { + resultType = GTGT; + } + } + } + } + else { + resultType = GT; + } + ParseUtil.restorePosition(lexer, originalPosition); + return resultType; + } + + static TreeElement createTokenElementAndAdvance(IElementType tokenType, Lexer lexer, CharTable table) { + final TreeElement result; + if (tokenType == GTGT || tokenType == GE) { + result = mergeTokens(1, lexer, tokenType, table); + } + else if (tokenType == GTGTEQ || tokenType == GTGTGT) { + result = mergeTokens(2, lexer, tokenType, table); + } + else if (tokenType == GTGTGTEQ) { + result = mergeTokens(3, lexer, tokenType, table); + } + else { + LOG.assertTrue(tokenType == lexer.getTokenType()); + result = ParseUtil.createTokenElement(lexer, table); + } + lexer.advance(); + return result; + } + + static void advance(IElementType tokenType, Lexer lexer) { + if(lexer.getTokenType() != GT){ + lexer.advance(); + } + else { + if (tokenType == GTGTGTEQ) { + lexer.advance(); + lexer.advance(); + lexer.advance(); + } + else if (tokenType == GTGTEQ || tokenType == GTGTGT) { + lexer.advance(); + lexer.advance(); + } + else if (tokenType == GTGT || tokenType == GE) { + lexer.advance(); + } + lexer.advance(); + } + } + + private static TreeElement mergeTokens(int nTokens, Lexer lexer, IElementType tokenType, CharTable table) { + final int tokenStart = lexer.getTokenStart(); + for (int i = 0; i < nTokens; i++) { + lexer.advance(); + } + final int tokenEnd = lexer.getTokenEnd(); + final LeafElement leafElement = Factory.createLeafElement(tokenType, lexer.getBuffer(), tokenStart, tokenEnd, lexer.getState(), table); + leafElement.setState(lexer.getState()); + return leafElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ImportsTextParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ImportsTextParsing.java new file mode 100644 index 00000000000..9830a1eb201 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ImportsTextParsing.java @@ -0,0 +1,132 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.FilterLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; + +/** + * + */ +public class ImportsTextParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ImportsTextParsing"); + + public ImportsTextParsing(ParsingContext context) { + super(context); + } + + /** + * @stereotype chameleon transforming + */ + public TreeElement parseImportsText(PsiManager manager, Lexer lexer, char[] buffer, int startOffset, int endOffset, int state) { + if (lexer == null){ + lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + } + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (state < 0) filterLexer.start(buffer, startOffset, endOffset); + else filterLexer.start(buffer, startOffset, endOffset, state); + + final FileElement dummyRoot = new DummyHolder(manager, null, myContext.getCharTable()).getTreeElement(); + + CompositeElement invalidElementsGroup = null; + while(filterLexer.getTokenType() != null){ + TreeElement element = parseImportStatement(filterLexer); + if (element != null){ + TreeUtil.addChildren(dummyRoot, element); + invalidElementsGroup = null; + continue; + } + + if (invalidElementsGroup == null){ + invalidElementsGroup = Factory.createErrorElement("Unexpected token"); + TreeUtil.addChildren(dummyRoot, invalidElementsGroup); + } + TreeUtil.addChildren(invalidElementsGroup, ParseUtil.createTokenElement(filterLexer, myContext.getCharTable())); + filterLexer.advance(); + } + + ParseUtil.insertMissingTokens(dummyRoot, lexer, startOffset, endOffset, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, myContext); + return dummyRoot.firstChild; + } + + private CompositeElement parseImportStatement(FilterLexer lexer) { + if (lexer.getTokenType() != IMPORT_KEYWORD) return null; + + final TreeElement importToken = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + final CompositeElement statement; + final boolean isStatic; + if (lexer.getTokenType() != STATIC_KEYWORD) { + statement = Factory.createCompositeElement(IMPORT_STATEMENT); + TreeUtil.addChildren(statement, importToken); + isStatic = false; + } + else { + statement = Factory.createCompositeElement(IMPORT_STATIC_STATEMENT); + TreeUtil.addChildren(statement, importToken); + TreeUtil.addChildren(statement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + isStatic = true; + } + + if (lexer.getTokenType() != IDENTIFIER){ + TreeUtil.addChildren(statement, Factory.createErrorElement("Identifier expected")); + return statement; + } + + CompositeElement refElement = parseJavaCodeReference(lexer, true); + if (refElement.lastChild.getElementType() == ERROR_ELEMENT){ + final TreeElement qualifier = refElement.findChildByRole(ChildRole.QUALIFIER); + LOG.assertTrue(qualifier != null); + TreeUtil.remove(refElement.lastChild); + TreeUtil.addChildren(statement, qualifier); + if (lexer.getTokenType() == ASTERISK){ + TreeUtil.addChildren(statement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + TreeUtil.addChildren(statement, Factory.createErrorElement("Identifier or '*' expected")); + return statement; + } + } + else{ + if (isStatic) { + // convert JAVA_CODE_REFERENCE into IMPORT_STATIC_REFERENCE + refElement = convertToImportStaticReference(refElement); + } + TreeUtil.addChildren(statement, refElement); + } + + if (lexer.getTokenType() == SEMICOLON){ + TreeUtil.addChildren(statement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + TreeUtil.addChildren(statement, Factory.createErrorElement("';' expected")); + } + + return statement; + } + + public CompositeElement convertToImportStaticReference(CompositeElement refElement) { + final CompositeElement importStaticReference = Factory.createCompositeElement(IMPORT_STATIC_REFERENCE); + final CompositeElement referenceParameterList = (CompositeElement)refElement.findChildByRole(ChildRole.REFERENCE_PARAMETER_LIST); + TreeUtil.addChildren(importStaticReference, refElement.firstChild); + if (referenceParameterList != null) { + if (referenceParameterList.firstChild == null) { + TreeUtil.remove(referenceParameterList); + } + else { + final CompositeElement errorElement = Factory.createErrorElement("Unexpected token"); + TreeUtil.replace(referenceParameterList, errorElement); + TreeUtil.addChildren(errorElement, referenceParameterList); + } + } + refElement = importStaticReference; + return refElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/JavadocParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/JavadocParsing.java new file mode 100644 index 00000000000..d2b9f3993c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/JavadocParsing.java @@ -0,0 +1,317 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaDocLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.ex.JdkUtil; +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +public class JavadocParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.JavadocParsing"); + + private final static TokenSet TOKEN_FILTER = TokenSet.create(new IElementType[]{ + JavaDocTokenType.DOC_SPACE, + JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS, + }); + + private final static TokenSet TAG_VALUE = TokenSet.create(new IElementType[]{ + JavaDocTokenType.DOC_TAG_VALUE_TOKEN, + JavaDocTokenType.DOC_TAG_VALUE_COMMA, + JavaDocTokenType.DOC_TAG_VALUE_DOT, + JavaDocTokenType.DOC_TAG_VALUE_LPAREN, + JavaDocTokenType.DOC_TAG_VALUE_RPAREN, + JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN, + }); + + private int myBraceScope = 0; + + public JavadocParsing(ParsingContext context) { + super(context); + } + + public TreeElement parseDocCommentText(PsiManager manager, char[] buffer, int startOffset, int endOffset) { + Lexer originalLexer = new JavaDocLexer(); // we need caching lexer because the lexer has states + + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(TOKEN_FILTER)); + lexer.start(buffer, startOffset, endOffset); + final FileElement dummyRoot = new DummyHolder(manager, null, myContext.getCharTable()).getTreeElement(); + + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + if (tokenType == JavaDocTokenType.DOC_TAG_NAME) { + CompositeElement tag = parseTag(manager, lexer); + TreeUtil.addChildren(dummyRoot, tag); + } + else { + TreeElement element = parseDataItem(manager, lexer, null, false); + TreeUtil.addChildren(dummyRoot, element); + } + } + + ParseUtil.insertMissingTokens(dummyRoot, originalLexer, startOffset, endOffset, new TokenProcessor(this), myContext); + return dummyRoot.firstChild; + } + + private CompositeElement parseTag(PsiManager manager, Lexer lexer) { + if (lexer.getTokenType() != JavaDocTokenType.DOC_TAG_NAME) return null; + CompositeElement tag = Factory.createCompositeElement(DOC_TAG); + TreeUtil.addChildren(tag, createTokenElement(lexer)); + String tagName = new String(lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd() - lexer.getTokenStart()); + lexer.advance(); + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null || tokenType == JavaDocTokenType.DOC_TAG_NAME || tokenType == JavaDocTokenType.DOC_COMMENT_END) break; + TreeElement element = parseDataItem(manager, lexer, tagName, false); + TreeUtil.addChildren(tag, element); + } + return tag; + } + + private TreeElement parseDataItem(PsiManager manager, Lexer lexer, String tagName, boolean isInlineItem) { + if (lexer.getTokenType() == JavaDocTokenType.DOC_INLINE_TAG_START) { + LeafElement justABrace = Factory.createLeafElement(JavaDocTokenType.DOC_COMMENT_DATA, + lexer.getBuffer(), + lexer.getTokenStart(), + lexer.getTokenEnd(), lexer.getState(), myContext.getCharTable()); + justABrace.setState(lexer.getState()); + CompositeElement tag = Factory.createCompositeElement(DOC_INLINE_TAG); + final LeafElement leafElement = Factory.createLeafElement(JavaDocTokenType.DOC_INLINE_TAG_START, lexer.getBuffer(), + lexer.getTokenStart(), lexer.getTokenEnd(), lexer.getState(), + myContext.getCharTable()); + leafElement.setState(lexer.getState()); + TreeUtil.addChildren(tag, leafElement); + + lexer.advance(); + + if (myBraceScope > 0) { + myBraceScope++; + return justABrace; + } + + if (lexer.getTokenType() != JavaDocTokenType.DOC_TAG_NAME && + lexer.getTokenType() != JavaDocTokenType.DOC_COMMENT_BAD_CHARACTER) { + return justABrace; + } + + myBraceScope++; + + String inlineTagName = ""; + + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == JavaDocTokenType.DOC_TAG_NAME) { + inlineTagName = new String(lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd() - lexer.getTokenStart()); + } + + if (tokenType == null || tokenType == JavaDocTokenType.DOC_COMMENT_END) break; + TreeElement element = parseDataItem(manager, lexer, inlineTagName, true); + TreeUtil.addChildren(tag, element); + if (tokenType == JavaDocTokenType.DOC_INLINE_TAG_END) { + if (myBraceScope > 0) myBraceScope--; + if (myBraceScope == 0) break; + } + } + return tag; + } + else if (TAG_VALUE.isInSet(lexer.getTokenType())) { + if (tagName != null && tagName.equals("@see") && !isInlineItem) { + return parseSeeTagValue(lexer); + } + else if (tagName != null && tagName.equals("@link") && isInlineItem) { + return parseSeeTagValue(lexer); + } + else if (tagName != null && JdkUtil.isJdk14(manager.getProject()) && tagName.equals("@linkplain") && isInlineItem) { + return parseSeeTagValue(lexer); + } + else if (tagName != null && !isInlineItem && (tagName.equals("@throws") || tagName.equals("@exception"))) { + final LeafElement element = parseReferenceOrType(lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), false, + lexer.getState()); + element.setState(lexer.getState()); + lexer.advance(); + final CompositeElement tagValue = Factory.createCompositeElement(DOC_TAG_VALUE_TOKEN); + TreeUtil.addChildren(tagValue, element); + return tagValue; + } + else if (!isInlineItem && tagName != null && tagName.equals("@param")) { + return parseParamTagValue(lexer); + } + else { + return parseSimpleTagValue(lexer); + } + } + else { + TreeElement token = createTokenElement(lexer); + lexer.advance(); + return token; + } + } + + private TreeElement parseParamTagValue(Lexer lexer) { + CompositeElement tagValue = Factory.createCompositeElement(DOC_PARAMETER_REF); + + while (TAG_VALUE.isInSet(lexer.getTokenType())) { + TreeElement value = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(tagValue, value); + } + + return tagValue; + } + + private TreeElement parseSimpleTagValue(Lexer lexer) { + CompositeElement tagValue = Factory.createCompositeElement(DOC_TAG_VALUE_TOKEN); + + while (TAG_VALUE.isInSet(lexer.getTokenType())) { + TreeElement value = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(tagValue, value); + } + + return tagValue; + } + + private CompositeElement parseMethodRef(Lexer lexer) { + CompositeElement ref = Factory.createCompositeElement(DOC_METHOD_OR_FIELD_REF); + + TreeElement sharp = createTokenElement(lexer); + TreeUtil.addChildren(ref, sharp); + lexer.advance(); + + if (lexer.getTokenType() != JavaDocTokenType.DOC_TAG_VALUE_TOKEN) return ref; + TreeElement value = createTokenElement(lexer); + TreeUtil.addChildren(ref, value); + lexer.advance(); + + if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_LPAREN) { + TreeElement lparen = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(ref, lparen); + + CompositeElement subValue = Factory.createCompositeElement(DOC_TAG_VALUE_TOKEN); + TreeUtil.addChildren(ref, subValue); + + while (TAG_VALUE.isInSet(lexer.getTokenType())) { + if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) { + final LeafElement reference = parseReferenceOrType(lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), true, + lexer.getState()); + reference.setState(lexer.getState()); + lexer.advance(); + TreeUtil.addChildren(subValue, reference); + + while (TAG_VALUE.isInSet(lexer.getTokenType()) && lexer.getTokenType() != JavaDocTokenType.DOC_TAG_VALUE_COMMA && + lexer.getTokenType() != JavaDocTokenType.DOC_TAG_VALUE_RPAREN) { + final TreeElement tokenElement = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(subValue, tokenElement); + } + } + else if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_RPAREN) { + TreeElement rparen = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(ref, rparen); + return ref; + } + else { + final TreeElement tokenElement = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(subValue, tokenElement); + } + } + } + + return ref; + } + + private TreeElement parseSeeTagValue(Lexer lexer) { + if (!TAG_VALUE.isInSet(lexer.getTokenType())) return null; + + if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) { + return parseMethodRef(lexer); + } + else if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) { + final LeafElement element = parseReferenceOrType(lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), false, + lexer.getState()); + element.setState(lexer.getState()); + lexer.advance(); + + if (lexer.getTokenType() == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) { + CompositeElement methodRef = parseMethodRef(lexer); + TreeUtil.insertBefore(methodRef.firstChild, element); + return methodRef; + } + else { + return element; + } + } + else { + CompositeElement tagValue = Factory.createCompositeElement(DOC_TAG_VALUE_TOKEN); + TreeElement element = createTokenElement(lexer); + lexer.advance(); + TreeUtil.addChildren(tagValue, element); + return tagValue; + } + } + + private LeafElement parseReferenceOrType(char[] buffer, int startOffset, int endOffset, boolean isType, int lexerState) { + return Factory.createLeafElement(isType ? JavaDocTokenType.DOC_TYPE_TEXT : JavaDocTokenType.DOC_REFERENCE_TEXT, buffer, startOffset, + endOffset, lexerState, myContext.getCharTable()); + } + + private LeafElement createTokenElement(Lexer lexer) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == JavaDocTokenType.DOC_SPACE) { + tokenType = WHITE_SPACE; + } + else if ((tokenType == JavaDocTokenType.DOC_INLINE_TAG_START || tokenType == JavaDocTokenType.DOC_INLINE_TAG_END) && myBraceScope != 1) { + tokenType = JavaDocTokenType.DOC_COMMENT_DATA; + } + + final LeafElement leafElement = Factory.createLeafElement(tokenType, lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), + lexer.getState(), myContext.getCharTable()); + leafElement.setState(lexer.getState()); + return leafElement; + } + + private static class TokenProcessor implements ParseUtil.TokenProcessor { + private JavadocParsing myParsing; + + private TokenProcessor(JavadocParsing theParsing) { + myParsing = theParsing; + } + + public TreeElement process(Lexer lexer, ParsingContext context) { + TreeElement first = null; + TreeElement last = null; + while (isTokenValid(lexer.getTokenType())) { + LeafElement tokenElement = myParsing.createTokenElement(lexer); + IElementType type = lexer.getTokenType(); + if (!TOKEN_FILTER.isInSet(type)) { + LOG.assertTrue(false, "Missed token should be space or asterisks:" + tokenElement); + throw new RuntimeException(); + } + if (last != null) { + last.setTreeNext(tokenElement); + tokenElement.setTreePrev(last); + last = tokenElement; + } + else { + first = last = tokenElement; + } + lexer.advance(); + } + return first; + } + + public boolean isTokenValid(IElementType tokenType) { + return tokenType != null && TOKEN_FILTER.isInSet(tokenType); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ParseUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ParseUtil.java new file mode 100644 index 00000000000..20a3388f158 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/ParseUtil.java @@ -0,0 +1,532 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.parsing.jsp.JspStep1Lexer; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.java.ModifierListElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.tree.IChameleonElementType; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.util.CharTable; + +/** + * + */ +public class ParseUtil implements Constants { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ParseUtil"); + + public static final Key UNCLOSED_ELEMENT_PROPERTY = Key.create("UNCLOSED_ELEMENT_PROPERTY"); + + public static boolean isStrongWhitespaceHolder(IElementType type){ + if (type == XmlElementType.XML_TEXT) return true; + return false; + } + + public static TreeElement createTokenElement(Lexer lexer, CharTable table) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) return null; + if (tokenType == DOC_COMMENT) { + CompositeElement element = Factory.createCompositeElement(tokenType); + LeafElement chameleon = Factory.createLeafElement(DOC_COMMENT_TEXT, lexer.getBuffer(), lexer.getTokenStart(), + lexer.getTokenEnd(), lexer.getState(), table); + TreeUtil.addChildren(element, chameleon); + return element; + } + else { + final LeafElement leafElement = Factory.createLeafElement(tokenType, lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), + lexer.getState(), table); + leafElement.setState(lexer.getState()); + return leafElement; + } + } + + public static long savePosition(Lexer lexer) { + return lexer.getTokenStart() | (long)lexer.getState() << 32; + } + + public static int getStoredPosition(long position) { + return (int)position & 0xFFFFFFFF; + } + + public static int getStoredState(long startPos) { + return (int)(startPos >> 32); + } + + public static void restorePosition(Lexer lexer, long position) { + lexer.start(lexer.getBuffer(), (int)position & 0xFFFFFFFF, lexer.getBufferEnd(), (int)(position >> 32)); + } + + public static int addTokens(CompositeElement parent, Lexer lexer, TokenSet typeBitSet, ParsingContext context) { + int count = 0; + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + if (!typeBitSet.isInSet(tokenType)) break; + if (parent != null) { + TreeUtil.addChildren(parent, ParseUtil.createTokenElement(lexer, context.getCharTable())); + } + lexer.advance(); + count++; + } + return count; + } + + public static int addTokensUntil(CompositeElement parent, Lexer lexer, IElementType stopType, ParsingContext context) { + int count = 0; + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + if (tokenType == stopType) break; + if (parent != null) { + TreeUtil.addChildren(parent, createTokenElement(lexer, context.getCharTable())); + } + lexer.advance(); + count++; + } + return count; + } + + public static String getTokenText(Lexer lexer) { + return StringFactory.createStringFromConstantArray(lexer.getBuffer(), lexer.getTokenStart(), + lexer.getTokenEnd() - lexer.getTokenStart()); + } + + public static interface TokenProcessor { + TreeElement process(Lexer lexer, ParsingContext context); + + boolean isTokenValid(IElementType tokenType); + } + + public static class WhiteSpaceAndCommentsProcessor implements TokenProcessor { + public static final TokenProcessor INSTANCE = new WhiteSpaceAndCommentsProcessor(); + + private WhiteSpaceAndCommentsProcessor() { + } + + public TreeElement process(Lexer lexer, ParsingContext context) { + TreeElement first = null; + TreeElement last = null; + while (isTokenValid(lexer.getTokenType())) { + TreeElement tokenElement = ParseUtil.createTokenElement(lexer, context.getCharTable()); + IElementType type = lexer.getTokenType(); + if (!WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(type)) { + LOG.error("Missed token should be white space or comment:" + tokenElement); + throw new RuntimeException(); + } + if (last != null) { + last.setTreeNext(tokenElement); + tokenElement.setTreePrev(last); + last = tokenElement; + } + else { + first = last = tokenElement; + } + lexer.advance(); + } + return first; + } + + public boolean isTokenValid(IElementType tokenType) { + return tokenType != null && WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(tokenType); + } + } + + public static final class CommonParentState { + TreeElement startLeafBranchStart = null; + TreeElement nextLeafBranchStart = null; + CompositeElement strongWhiteSpaceHolder = null; + boolean isStrongElementOnRisingSlope = true; + } + + public static void insertMissingTokens(CompositeElement root, + Lexer lexer, + int startOffset, + int endOffset, + TokenProcessor processor, ParsingContext context) { + insertMissingTokens(root, lexer, startOffset, endOffset, -1, processor, context); + } + + public static void insertMissingTokens(CompositeElement root, + Lexer lexer, + int startOffset, + int endOffset, int state, + TokenProcessor processor, ParsingContext context) { + if (state < 0) { + lexer.start(lexer.getBuffer(), startOffset, endOffset); + } + else { + lexer.start(lexer.getBuffer(), startOffset, endOffset, state); + } + + boolean gt = lexer instanceof JavaLexer || lexer instanceof JspStep1Lexer; + LeafElement leaf = TreeUtil.findFirstLeaf(root); + if (leaf == null) { + final TreeElement firstMissing = processor.process(lexer, context); + if (firstMissing != null) { + TreeUtil.addChildren(root, firstMissing); + } + return; + } + { + // Missing in the begining + final IElementType tokenType = gt ? GTTokens.getTokenType(lexer) : lexer.getTokenType(); + if (tokenType != leaf.getElementType() && processor.isTokenValid(tokenType)) { + final TreeElement firstMissing = processor.process(lexer, context); + if (firstMissing != null) { + TreeUtil.insertBefore(root.firstChild, firstMissing); + } + } + passTokenOrChameleon(leaf, lexer, gt); + } + // Missing in tree body + insertMissingTokensInTreeBody(leaf, gt, lexer, processor, context, null); + if(lexer.getTokenType() != null){ + // whitespaces at the end of the file + final TreeElement firstMissing = processor.process(lexer, context); + if(firstMissing != null){ + TreeElement current = root; + while(current instanceof CompositeElement){ + if(current.getUserData(UNCLOSED_ELEMENT_PROPERTY) != null) break; + current = ((CompositeElement)current).lastChild; + } + if(current instanceof CompositeElement){ + TreeUtil.addChildren((CompositeElement)current, firstMissing); + } + else{ + TreeUtil.insertAfter(root.lastChild, firstMissing); + } + } + } + bindComments(root); + } + + public static void insertMissingTokensInTreeBody(TreeElement leaf, + boolean gt, + Lexer lexer, + TokenProcessor processor, + ParsingContext context, + LeafElement endToken) { + final CommonParentState commonParents = new CommonParentState(); + while(leaf != null){ + commonParents.strongWhiteSpaceHolder = null; + final IElementType tokenType = gt ? GTTokens.getTokenType(lexer) : lexer.getTokenType(); + final TreeElement next; + if(tokenType instanceof IChameleonElementType) + next = nextLeaf(leaf, commonParents, tokenType); + else + next = nextLeaf(leaf, commonParents, null); + + if (next == null || tokenType == null || next == endToken) break; + if (tokenType != next.getElementType() && processor.isTokenValid(tokenType)) { + final TreeElement firstMissing = processor.process(lexer, context); + final CompositeElement unclosedElement = commonParents.strongWhiteSpaceHolder; + if (unclosedElement != null) { + if(commonParents.isStrongElementOnRisingSlope || unclosedElement.firstChild == null) + TreeUtil.addChildren(unclosedElement, firstMissing); + else + TreeUtil.insertBefore(unclosedElement.firstChild, firstMissing); + } + else { + final TreeElement insertBefore = commonParents.nextLeafBranchStart; + TreeElement insertAfter = commonParents.startLeafBranchStart; + TreeElement current = commonParents.startLeafBranchStart; + while (current != insertBefore) { + final TreeElement treeNext = current.getTreeNext(); + if (treeNext == insertBefore) { + insertAfter = current; + break; + } + if (treeNext instanceof ModifierListElement) { + insertAfter = current; + break; + } + if (treeNext.getUserData(UNCLOSED_ELEMENT_PROPERTY) != null) { + insertAfter = null; + TreeUtil.addChildren((CompositeElement)treeNext, firstMissing); + break; + } + current = treeNext; + } + if (insertAfter != null) TreeUtil.insertAfter(insertAfter, firstMissing); + } + } + passTokenOrChameleon(next, lexer, gt); + leaf = next; + } + } + + private static void passTokenOrChameleon(final TreeElement next, Lexer lexer, boolean gtUse) { + if (next instanceof ChameleonElement) { + final int endOfChameleon = next.getTextLength() + lexer.getTokenStart(); + while (lexer.getTokenType() != null && lexer.getTokenEnd() < endOfChameleon) { + lexer.advance(); + } + } + if (gtUse) { + GTTokens.advance(next.getElementType(), lexer); + } + else { + lexer.advance(); + } + } + + public static LeafElement nextLeaf(TreeElement start, CommonParentState commonParent) { + return (LeafElement)nextLeaf(start, commonParent, null); + } + + public static TreeElement nextLeaf(TreeElement start, CommonParentState commonParent, IElementType searchedType) { + TreeElement next = null; + if(commonParent != null){ + commonParent.startLeafBranchStart = start; + initStrongWhitespaceHolder(commonParent, start, true); + } + TreeElement nextTree = start; + while (next == null && (nextTree = nextTree.getTreeNext()) != null) { + if(nextTree.getElementType() == searchedType) + return nextTree; + next = findFirstLeaf(nextTree, searchedType, commonParent); + } + if(next != null){ + if(commonParent != null) commonParent.nextLeafBranchStart = nextTree; + return next; + } + final CompositeElement parent = start.getTreeParent(); + if (parent == null) return null; + return nextLeaf(parent, commonParent, searchedType); + } + + private static void initStrongWhitespaceHolder(CommonParentState commonParent, TreeElement start, boolean slopeSide) { + if(start instanceof CompositeElement + && (isStrongWhitespaceHolder(start.getElementType()) + || (start.getUserData(UNCLOSED_ELEMENT_PROPERTY) != null) && slopeSide)){ + commonParent.strongWhiteSpaceHolder = (CompositeElement)start; + commonParent.isStrongElementOnRisingSlope = slopeSide; + } + } + + private static TreeElement findFirstLeaf(TreeElement element, IElementType searchedType, CommonParentState commonParent) { + if(commonParent != null){ + initStrongWhitespaceHolder(commonParent, element, false); + } + if (element instanceof LeafElement || element.getElementType() == searchedType){ + return element; + } + else{ + for(TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()){ + TreeElement leaf = findFirstLeaf(child, searchedType, commonParent); + if (leaf != null) return leaf; + } + return null; + } + } + + public static LeafElement prevLeaf(TreeElement start, CommonParentState commonParent) { + LeafElement prev = null; + if(commonParent != null){ + if(commonParent.strongWhiteSpaceHolder != null && start.getUserData(UNCLOSED_ELEMENT_PROPERTY) != null) + commonParent.strongWhiteSpaceHolder = (CompositeElement)start; + commonParent.startLeafBranchStart = start; + } + TreeElement prevTree = start; + while (prev == null && (prevTree = prevTree.getTreePrev()) != null) { + prev = TreeUtil.findLastLeaf(prevTree); + } + if(prev != null){ + if(commonParent != null) commonParent.nextLeafBranchStart = prevTree; + return prev; + } + final CompositeElement parent = start.getTreeParent(); + if (parent == null) return null; + return prevLeaf(parent, commonParent); + } + + static void bindComments(CompositeElement root) { + TreeElement child = root.firstChild; + while (child != null) { + if (child.getElementType() == DOC_COMMENT) { + if (bindDocComment(child)) { + child = child.getTreeParent(); + continue; + } + } + + // bind "trailing comments" (like "int a; // comment") + if (child.getElementType() == END_OF_LINE_COMMENT || child.getElementType() == C_STYLE_COMMENT) { + if (bindTrailingComment(child)) { + child = child.getTreeParent(); + continue; + } + } + + // bind "preceding comments" (like "// comment \n void f();") + if (child.getElementType() == END_OF_LINE_COMMENT || child.getElementType() == C_STYLE_COMMENT) { + if (bindPrecedingComment(child)) { + child = child.getTreeParent(); + if (child.getTreePrev() != null) { + child = child.getTreePrev(); + } + continue; + } + } + + if (child instanceof CompositeElement) { + bindComments((CompositeElement)child); + } + child = child.getTreeNext(); + } + } + + private static boolean bindDocComment(TreeElement docComment) { + TreeElement element = docComment.getTreeNext(); + if (element == null) return false; + TreeElement startSpaces = null; + TreeElement endSpaces = null; + + // Bypass meaningless tokens and hold'em in hands + while (element.getElementType() == WHITE_SPACE || + element.getElementType() == C_STYLE_COMMENT || + element.getElementType() == END_OF_LINE_COMMENT || + (element.getElementType() == IMPORT_LIST && element.getTextLength() == 0) + ) { + if (startSpaces == null) startSpaces = element; + element = element.getTreeNext(); + if (element == null) return false; + } + + endSpaces = element; + + if (element.getElementType() == CLASS || element.getElementType() == FIELD || element.getElementType() == METHOD || + element.getElementType() == ENUM_CONSTANT) { + TreeElement first = ((CompositeElement)element).firstChild; + TreeUtil.remove(docComment); + TreeUtil.insertBefore(first, docComment); + if (startSpaces != null) { + element = startSpaces.getTreeNext(); + + if (startSpaces.getElementType() != IMPORT_LIST) { + TreeUtil.remove(startSpaces); + TreeUtil.insertBefore(first, startSpaces); + } + + TreeElement anchor = startSpaces; + + while (element != endSpaces) { + TreeElement next = element.getTreeNext(); + if (element.getElementType() != IMPORT_LIST) { + TreeUtil.remove(element); + TreeUtil.insertAfter(anchor, element); + anchor = element; + } + element = next; + } + } + return true; + } + return false; + } + + private static final TokenSet BIND_TRAINLING_COMMENT_BIT_SET = TokenSet.orSet(TokenSet.create(new IElementType[]{ + FIELD, + METHOD, + CLASS, + CLASS_INITIALIZER, + IMPORT_STATEMENT, + IMPORT_STATIC_STATEMENT, + PACKAGE_STATEMENT + }), + STATEMENT_BIT_SET); + + private static boolean bindTrailingComment(TreeElement comment) { + TreeElement element = comment.getTreePrev(); + if (element == null) return false; + TreeElement space = null; + if (element.getElementType() == WHITE_SPACE) { + space = element; + element = element.getTreePrev(); + } + if (element != null && BIND_TRAINLING_COMMENT_BIT_SET.isInSet(element.getElementType())) { + if (space == null || (!space.textContains('\n') && !space.textContains('\r'))) { + if (!comment.textContains('\n') && !comment.textContains('\r')) { + if (space != null) { + TreeUtil.remove(space); + TreeUtil.addChildren((CompositeElement)element, space); + } + TreeUtil.remove(comment); + TreeUtil.addChildren((CompositeElement)element, comment); + return true; + } + } + } + return false; + } + + private static final TokenSet BIND_PRECEDING_COMMENT_BIT_SET = TokenSet.create(new IElementType[]{ + FIELD, + METHOD, + CLASS, + CLASS_INITIALIZER, + }); + + private static final TokenSet PRECEDING_COMMENT_OR_SPACE_BIT_SET = TokenSet.create(new IElementType[]{ + C_STYLE_COMMENT, END_OF_LINE_COMMENT, WHITE_SPACE + }); + + private static boolean bindPrecedingComment(TreeElement comment) { + TreeElement element = TreeUtil.skipElements(comment, PRECEDING_COMMENT_OR_SPACE_BIT_SET); + if (element == null) return false; + + if (element.getElementType() == IMPORT_LIST && element.getTextLength() == 0) { + element = element.getTreeNext(); + } + + if (element != null && BIND_PRECEDING_COMMENT_BIT_SET.isInSet(element.getElementType())) { + for (TreeElement child = comment; child != element; child = child.getTreeNext()) { + if (child.getElementType() == WHITE_SPACE) { + int count = StringUtil.getLineBreakCount(child.getText()); + if (count > 1) return false; + } + else { + if (comment.getTreePrev() != null && comment.getTreePrev().getElementType() == ElementType.WHITE_SPACE) { + LeafElement prev = (LeafElement)comment.getTreePrev(); + char lastC = prev.charAt(prev.getTextLength() - 1); + if (lastC == '\n' || lastC == '\r') return false; + } + else { + return false; + } + } + } + + // check if the comment is on separate line + if (comment.getTreePrev() != null) { + TreeElement prev = comment.getTreePrev(); + if (prev.getElementType() != ElementType.WHITE_SPACE) { + return false; + } + else { + if (!prev.textContains('\n')) return false; + } + } + + TreeElement first = ((CompositeElement)element).firstChild; + TreeElement child = comment; + while (child != element) { + TreeElement next = child.getTreeNext(); + if (child.getElementType() != IMPORT_LIST) { + TreeUtil.remove(child); + TreeUtil.insertBefore(first, child); + } + child = next; + } + return true; + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/Parsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/Parsing.java new file mode 100644 index 00000000000..c3f31b27338 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/Parsing.java @@ -0,0 +1,260 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.FilterLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.CharTable; + +public class Parsing implements Constants{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.Parsing"); + public static /*final*/ boolean DEEP_PARSE_BLOCKS_IN_STATEMENTS = false; + protected final ParsingContext myContext; + + public Parsing(ParsingContext context) { + myContext = context; + } + + public static CompositeElement parseJavaCodeReferenceText(PsiManager manager, char[] buffer, CharTable table) { + return parseJavaCodeReferenceText(manager, buffer, 0, buffer.length, table); + } + + public static CompositeElement parseJavaCodeReferenceText(PsiManager manager, + char[] buffer, + int startOffset, + int endOffset, + CharTable table) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, startOffset, endOffset); + + ParsingContext context = new ParsingContext(table); + CompositeElement ref = context.getStatementParsing().parseJavaCodeReference(lexer, false); + if (ref == null) return null; + new DummyHolder(manager, ref, null, table); + if (lexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(ref, originalLexer, startOffset, endOffset, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return ref; + } + + public CompositeElement parseJavaCodeReference(Lexer lexer, boolean allowIncomplete) { + if (lexer.getTokenType() != IDENTIFIER) return null; + + TreeElement identifier = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + CompositeElement refElement = Factory.createCompositeElement(JAVA_CODE_REFERENCE); + TreeUtil.addChildren(refElement, identifier); + CompositeElement parameterList = parseReferenceParameterList(lexer, true); + TreeUtil.addChildren(refElement, parameterList); + + while (lexer.getTokenType() == DOT) { + long dotPos = ParseUtil.savePosition(lexer); + TreeElement dot = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + if (lexer.getTokenType() == IDENTIFIER) { + identifier = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + } + else{ + if (!allowIncomplete){ + ParseUtil.restorePosition(lexer, dotPos); + return refElement; + } + identifier = null; + } + + CompositeElement refElement1 = Factory.createCompositeElement(JAVA_CODE_REFERENCE); + TreeUtil.addChildren(refElement1, refElement); + TreeUtil.addChildren(refElement1, dot); + if (identifier == null){ + TreeUtil.addChildren(refElement1, Factory.createErrorElement("Identifier expected")); + return refElement1; + } + TreeUtil.addChildren(refElement1, identifier); + CompositeElement parameterList1 = parseReferenceParameterList(lexer, true); + TreeUtil.addChildren(refElement1, parameterList1); + refElement = refElement1; + } + + return refElement; + } + + public CompositeElement parseReferenceParameterList(Lexer lexer, boolean allowWildcard) { + final CompositeElement list = Factory.createCompositeElement(REFERENCE_PARAMETER_LIST); + if (lexer.getTokenType() != LT) return list; + final TreeElement lt = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + TreeUtil.addChildren(list, lt); + lexer.advance(); + while (true) { + final CompositeElement typeElement = parseType(lexer, true, allowWildcard); + if (typeElement != null) { + TreeUtil.addChildren(list, typeElement); + } else { + final CompositeElement errorElement = Factory.createErrorElement("Identifier expected"); + TreeUtil.addChildren(list, errorElement); + } + + if (lexer.getTokenType() == GT) { + final TreeElement gt = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + TreeUtil.addChildren(list, gt); + lexer.advance(); + return list; + } else if (lexer.getTokenType() == COMMA) { + final TreeElement comma = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + TreeUtil.addChildren(list, comma); + lexer.advance(); + } else { + final CompositeElement errorElement = Factory.createErrorElement("'>' or ',' expected."); + TreeUtil.addChildren(list, errorElement); + return list; + } + } + } + + public static CompositeElement parseTypeText(PsiManager manager, char[] buffer, int startOffset, int endOffset, CharTable table) { + Lexer originalLexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + FilterLexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, startOffset, endOffset); + final ParsingContext context = new ParsingContext(table); + CompositeElement type = context.getStatementParsing().parseTypeWithEllipsis(lexer); + if (type == null) return null; + if (lexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(type, originalLexer, startOffset, endOffset, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return type; + } + + public CompositeElement parseTypeWithEllipsis(Lexer lexer, boolean eatLastDot, boolean allowWilcard) { + CompositeElement type = parseType(lexer, eatLastDot, allowWilcard); + if (type == null) return null; + if (lexer.getTokenType() == ELLIPSIS) { + CompositeElement type1 = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(type1, type); + TreeUtil.addChildren(type1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + type = type1; + } + + return type; + + } + public CompositeElement parseTypeWithEllipsis(Lexer lexer) { + return parseTypeWithEllipsis(lexer, true, true); + } + + public CompositeElement parseType(Lexer lexer){ + return parseType(lexer, true, true); + } + + public CompositeElement parseType(Lexer lexer, boolean eatLastDot, boolean allowWildcard){ + IElementType tokenType = lexer.getTokenType(); + TreeElement refElement; + if (tokenType == null){ + return null; + } + else if (PRIMITIVE_TYPE_BIT_SET.isInSet(tokenType)){ + refElement = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + } + else if (tokenType == IDENTIFIER){ + refElement = parseJavaCodeReference(lexer, eatLastDot); + } + else if (allowWildcard && lexer.getTokenType() == QUEST) { + return parseWildcardType(lexer); + } + else{ + return null; + } + CompositeElement type = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(type, refElement); + while(lexer.getTokenType() == LBRACKET){ + long lbracketPos = ParseUtil.savePosition(lexer); + TreeElement lbracket = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + if (lexer.getTokenType() != RBRACKET){ + ParseUtil.restorePosition(lexer, lbracketPos); + break; + } + CompositeElement type1 = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(type1, type); + TreeUtil.addChildren(type1, lbracket); + TreeUtil.addChildren(type1, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + type = type1; + } + return type; + } + + private CompositeElement parseWildcardType(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == QUEST); + CompositeElement type = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(type, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (lexer.getTokenType() == SUPER_KEYWORD || lexer.getTokenType() == EXTENDS_KEYWORD) { + TreeUtil.addChildren(type, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement boundType = parseType(lexer, true, false); + if (boundType != null) { + TreeUtil.addChildren(type, boundType); + } + else { + TreeUtil.addChildren(type, Factory.createErrorElement("Type expected")); + } + } + return type; + } + + public static TreeElement parseTypeText(PsiManager manager, + Lexer lexer, + char[] buffer, + int startOffset, + int endOffset, + int state, + CharTable table) { + if (lexer == null){ + lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + } + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (state < 0) filterLexer.start(buffer, startOffset, endOffset); + else filterLexer.start(buffer, startOffset, endOffset, state); + final ParsingContext context = new ParsingContext(table); + final FileElement dummyRoot = new DummyHolder(manager, null, context.getCharTable()).getTreeElement(); + final CompositeElement root = context.getStatementParsing().parseType(filterLexer); + if (root != null) { + TreeUtil.addChildren(dummyRoot, root); + } + + if (filterLexer.getTokenType() == ELLIPSIS) { + TreeUtil.addChildren(dummyRoot, ParseUtil.createTokenElement(filterLexer, context.getCharTable())); + filterLexer.advance(); + } + + if (filterLexer.getTokenType() != null) { + final CompositeElement errorElement = Factory.createErrorElement("Unexpected tokens"); + while (filterLexer.getTokenType() != null) { + final TreeElement token = ParseUtil.createTokenElement(lexer, context.getCharTable()); + TreeUtil.addChildren(errorElement, token); + filterLexer.advance(); + } + TreeUtil.addChildren(dummyRoot, errorElement); + } + + ParseUtil.insertMissingTokens( + dummyRoot, + lexer, + startOffset, + endOffset, state, + ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return dummyRoot.firstChild; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/StatementParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/StatementParsing.java new file mode 100644 index 00000000000..11110ee0525 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/StatementParsing.java @@ -0,0 +1,923 @@ +package com.intellij.psi.impl.source.parsing; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.JavaWithJspTemplateDataLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.parsing.jsp.JspStep1Lexer; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.jsp.IJspElementType; +import com.intellij.util.CharTable; + +public class StatementParsing extends Parsing { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.StatementParsing"); + + public StatementParsing(ParsingContext context) { + super(context); + } + + public static CompositeElement parseCodeBlockText(PsiManager manager, char[] buffer, CharTable table) { + return parseCodeBlockText(manager, null, buffer, 0, buffer.length, -1, table); + } + + public static CompositeElement parseCodeBlockText(PsiManager manager, + Lexer lexer, + char[] buffer, + int startOffset, + int endOffset, + int state, CharTable table) { + if (lexer == null){ + lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + } + final ParsingContext context = new ParsingContext(table); + final FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (state < 0) filterLexer.start(buffer, startOffset, endOffset); + else filterLexer.start(buffer, startOffset, endOffset, state); + + final FileElement dummyRoot = new DummyHolder(manager, null, table).getTreeElement(); + CompositeElement block = Factory.createCompositeElement(CODE_BLOCK); + TreeUtil.addChildren(dummyRoot, block); + context.getStatementParsing().parseCodeBlockDeep(block, filterLexer, true); + if (block.firstChild == null) return null; + + ParseUtil.insertMissingTokens(block, lexer, startOffset, endOffset, state, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return block; + } + + public static TreeElement parseStatements(PsiManager manager, + Lexer lexer, + char[] buffer, + int startOffset, + int endOffset, + int state, CharTable table) { + if (lexer == null){ + lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + } + final ParsingContext context = new ParsingContext(table); + final FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + if (state < 0) filterLexer.start(buffer, startOffset, endOffset); + else filterLexer.start(buffer, startOffset, endOffset, state); + + final FileElement dummyRoot = new DummyHolder(manager, null, table).getTreeElement(); + context.getStatementParsing().parseStatements(dummyRoot, filterLexer, RBRACE_IS_ERROR); + + ParseUtil.insertMissingTokens(dummyRoot, + lexer, + startOffset, + endOffset, + state, + ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return dummyRoot.firstChild; + } + + public CompositeElement parseCodeBlock(Lexer lexer, boolean deep) { + if (lexer.getTokenType() != LBRACE) return null; + if (lexer instanceof FilterLexer){ + if (((FilterLexer)lexer).getOriginal() instanceof JspStep1Lexer || + ((FilterLexer)lexer).getOriginal() instanceof JavaWithJspTemplateDataLexer){ + deep = true; // deep parsing of code blocks in JSP would lead to incorrect parsing on transforming + } + } + + CompositeElement codeBlock = Factory.createCompositeElement(CODE_BLOCK); + if (!deep){ + int start = lexer.getTokenStart(); + lexer.advance(); + int braceCount = 1; + int end; + while(true){ + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null){ + end = lexer.getTokenStart(); + break; + } + if (tokenType == LBRACE){ + braceCount++; + } + else if (tokenType == RBRACE){ + braceCount--; + } + if (braceCount == 0){ + end = lexer.getTokenEnd(); + lexer.advance(); + break; + } + lexer.advance(); + } + if (braceCount != 0){ + codeBlock.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + } + TreeElement chameleon = Factory.createLeafElement(CODE_BLOCK_TEXT, lexer.getBuffer(), start, end, lexer.getState(), myContext.getCharTable()); + TreeUtil.addChildren(codeBlock, chameleon); + } + else{ + parseCodeBlockDeep(codeBlock, lexer, false); + } + + return codeBlock; + } + + private void parseCodeBlockDeep(CompositeElement elementToAdd, + Lexer lexer, + boolean parseToEndOfLexer) { + LOG.assertTrue(lexer.getTokenType() == LBRACE); + + TreeUtil.addChildren(elementToAdd, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + parseStatements(elementToAdd, lexer, parseToEndOfLexer ? LAST_RBRACE_IS_END : RBRACE_IS_END); + + if (elementToAdd.lastChild == null || elementToAdd.lastChild.getElementType() != RBRACE){ + CompositeElement errorElement = Factory.createErrorElement("'}' expected"); + TreeUtil.addChildren(elementToAdd, errorElement); + elementToAdd.putUserData(ParseUtil.UNCLOSED_ELEMENT_PROPERTY, ""); + } + } + + private static final int RBRACE_IS_ERROR = 1; + private static final int RBRACE_IS_END = 2; + private static final int LAST_RBRACE_IS_END = 3; + + private void parseStatements(CompositeElement elementToAdd, Lexer lexer, int rbraceMode){ + while(lexer.getTokenType() != null){ + CompositeElement statement = parseStatement(lexer); + if (statement != null){ + TreeUtil.addChildren(elementToAdd, statement); + continue; + } + + IElementType tokenType = lexer.getTokenType(); + TreeElement tokenElement = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + if (tokenType == RBRACE){ + Label: + if (rbraceMode == RBRACE_IS_ERROR) { + } + else if (rbraceMode == RBRACE_IS_END) { + TreeUtil.addChildren(elementToAdd, tokenElement); + return; + } + else if (rbraceMode == LAST_RBRACE_IS_END) { + if (lexer.getTokenType() == null) { + TreeUtil.addChildren(elementToAdd, tokenElement); + return; + } + else { + break Label; + } + } + else { + LOG.assertTrue(false); + } + } + + String error; + if (tokenType == ELSE_KEYWORD){ + error = "'else' without 'if'"; + } + else if (tokenType == CATCH_KEYWORD){ + error = "'catch' without 'try'"; + } + else if (tokenType == FINAL_KEYWORD){ + error = "'finally' without 'try'"; + } + else{ + error = "Unexpected token"; + } + CompositeElement errorElement = Factory.createErrorElement(error); + TreeUtil.addChildren(errorElement, tokenElement); + TreeUtil.addChildren(elementToAdd, errorElement); + } + } + + public static CompositeElement parseStatementText(PsiManager manager, char[] buffer, CharTable table) { + Lexer lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + final ParsingContext context = new ParsingContext(table); + final FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + filterLexer.start(buffer, 0, buffer.length); + + CompositeElement statement = context.getStatementParsing().parseStatement(filterLexer); + if (statement == null) return null; + if (filterLexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(statement, lexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return statement; + } + + public CompositeElement parseStatement(Lexer lexer) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == IF_KEYWORD) { + return parseIfStatement(lexer); + } + else if (tokenType == WHILE_KEYWORD) { + return parseWhileStatement(lexer); + } + else if (tokenType == FOR_KEYWORD) { + return parseForStatement(lexer); + } + else if (tokenType == DO_KEYWORD) { + return parseDoWhileStatement(lexer); + } + else if (tokenType == SWITCH_KEYWORD) { + return parseSwitchStatement(lexer); + } + else if (tokenType == CASE_KEYWORD || tokenType == DEFAULT_KEYWORD) { + return parseSwitchLabelStatement(lexer); + } + else if (tokenType == BREAK_KEYWORD) { + return parseBreakStatement(lexer); + } + else if (tokenType == CONTINUE_KEYWORD) { + return parseContinueStatement(lexer); + } + else if (tokenType == RETURN_KEYWORD) { + return parseReturnStatement(lexer); + } + else if (tokenType == THROW_KEYWORD) { + return parseThrowStatement(lexer); + } + else if (tokenType == SYNCHRONIZED_KEYWORD) { + return parseSynchronizedStatement(lexer); + } + else if (tokenType == TRY_KEYWORD) { + return parseTryStatement(lexer); + } + else if (tokenType == ASSERT_KEYWORD) { + return parseAssertStatement(lexer); + } + else if (tokenType == LBRACE) { + return parseBlockStatement(lexer); + } + else if (tokenType == JSP_HOLDER_TOKEN) { + CompositeElement statement = Factory.createCompositeElement(JSP_TEMPLATE_STATEMENT); + TreeUtil.addChildren(statement, Factory.createLeafElement(HOLDER_TEMPLATE_DATA, lexer.getBuffer(), lexer.getTokenStart(), lexer.getTokenEnd(), lexer.getState(), myContext.getCharTable())); + lexer.advance(); + return statement; + } + else if (tokenType == SEMICOLON) { + { + CompositeElement element = Factory.createCompositeElement(EMPTY_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + return element; + } + } + else { + { + if (tokenType instanceof IJspElementType) { + return myContext.getJspParsing().parseJspConstruction(lexer); + } + + if (lexer.getTokenType() == IDENTIFIER) { + long refPos = ParseUtil.savePosition(lexer); + skipQualifiedName(lexer); + final IElementType suspectedLT = lexer.getTokenType(); + ParseUtil.restorePosition(lexer, refPos); + LOG.assertTrue(lexer.getTokenType() == IDENTIFIER); + if (suspectedLT == LT) { + final TreeElement decl = myContext.getDeclarationParsing().parseDeclaration(lexer, + DeclarationParsing.CODE_BLOCK_CONTEXT); + CompositeElement declStatement = Factory.createCompositeElement(DECLARATION_STATEMENT); + if (decl != null) { + TreeUtil.addChildren(declStatement, decl); + } + else { + final CompositeElement type = parseType(lexer, false, false); + TreeUtil.addChildren(declStatement, type); + final CompositeElement errorElement = Factory.createErrorElement("Identifier expected"); + TreeUtil.addChildren(declStatement, errorElement); + } + return declStatement; + } + } + + long pos = ParseUtil.savePosition(lexer); + CompositeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + long pos1 = ParseUtil.savePosition(lexer); + if (expr != null) { + int count = 1; + CompositeElement element = null; + while (lexer.getTokenType() == COMMA) { + CompositeElement list = Factory.createCompositeElement(EXPRESSION_LIST); + element = Factory.createCompositeElement(EXPRESSION_LIST_STATEMENT); + TreeUtil.addChildren(element, list); + TreeUtil.addChildren(list, expr); + long commaPos = ParseUtil.savePosition(lexer); + TreeElement comma = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + CompositeElement expr1 = myContext.getExpressionParsing().parseExpression(lexer); + if (expr1 == null) { + ParseUtil.restorePosition(lexer, commaPos); + break; + } + TreeUtil.addChildren(list, comma); + TreeUtil.addChildren(list, expr1); + count++; + } + if (count > 1) { + processClosingSemicolon(element, lexer); + return element; + } + if (expr.getElementType() != REFERENCE_EXPRESSION) { + element = Factory.createCompositeElement(EXPRESSION_STATEMENT); + TreeUtil.addChildren(element, expr); + processClosingSemicolon(element, lexer); + return element; + } + ParseUtil.restorePosition(lexer, pos); + } + + TreeElement decl = myContext.getDeclarationParsing().parseDeclaration(lexer, + DeclarationParsing.CODE_BLOCK_CONTEXT); + if (decl != null) { + CompositeElement declStatement = Factory.createCompositeElement(DECLARATION_STATEMENT); + TreeUtil.addChildren(declStatement, decl); + return declStatement; + } + + if (lexer.getTokenType() == IDENTIFIER) { + TreeElement identifier = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + if (lexer.getTokenType() != COLON) { + ParseUtil.restorePosition(lexer, pos); + } + else { + CompositeElement element = Factory.createCompositeElement(LABELED_STATEMENT); + TreeUtil.addChildren(element, identifier); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement statement = parseStatement(lexer); + if (statement != null) { + TreeUtil.addChildren(element, statement); + } + return element; + } + } + + if (expr != null) { + ParseUtil.restorePosition(lexer, pos1); + CompositeElement element = Factory.createCompositeElement(EXPRESSION_STATEMENT); + TreeUtil.addChildren(element, expr); + processClosingSemicolon(element, lexer); + return element; + } + else { + return null; + } + } + } + } + + private static void skipQualifiedName(Lexer lexer) { + if (lexer.getTokenType() != IDENTIFIER) return; + while(true){ + lexer.advance(); + if (lexer.getTokenType() != DOT) return; + final long position = ParseUtil.savePosition(lexer); + lexer.advance(); + if (lexer.getTokenType() != IDENTIFIER){ + ParseUtil.restorePosition(lexer, position); + return; + } + } + } + + private CompositeElement parseIfStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == IF_KEYWORD); + CompositeElement element = Factory.createCompositeElement(IF_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (!processExpressionInParens(lexer, element)){ + return element; + } + + CompositeElement thenStatement = parseStatement(lexer); + if (thenStatement == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + return element; + } + + TreeUtil.addChildren(element, thenStatement); + + if (lexer.getTokenType() != ELSE_KEYWORD){ + return element; + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + CompositeElement elseStatement = parseStatement(lexer); + if (elseStatement == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + return element; + } + TreeUtil.addChildren(element, elseStatement); + return element; + } + + private CompositeElement parseWhileStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == WHILE_KEYWORD); + CompositeElement element = Factory.createCompositeElement(WHILE_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (!processExpressionInParens(lexer, element)){ + return element; + } + + CompositeElement statement = parseStatement(lexer); + if (statement == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + return element; + } + + TreeUtil.addChildren(element, statement); + return element; + } + + private CompositeElement parseForStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == FOR_KEYWORD); + final TreeElement forKeyword = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + if (lexer.getTokenType() != LPARENTH){ + CompositeElement errorForElement = Factory.createCompositeElement(FOR_STATEMENT); + TreeUtil.addChildren(errorForElement, forKeyword); + TreeUtil.addChildren(errorForElement, Factory.createErrorElement("'(' expected")); + return errorForElement; + } + + final TreeElement lparenth = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + final long afterLParenth = ParseUtil.savePosition(lexer); + final TreeElement parameter = myContext.getDeclarationParsing().parseParameter(lexer, false); + if (parameter == null || parameter.getElementType() != PARAMETER || lexer.getTokenType() != COLON) { + ParseUtil.restorePosition(lexer, afterLParenth); + return parseForLoopFromInitialization(forKeyword, lparenth, lexer); + } + else { + return parseForEachFromColon(forKeyword, lparenth, parameter, lexer); + } + } + + private CompositeElement parseForEachFromColon(TreeElement forKeyword, + TreeElement lparenth, + TreeElement parameter, + Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == COLON); + final CompositeElement element = Factory.createCompositeElement(Factory.FOREACH_STATEMENT); + TreeUtil.addChildren(element, forKeyword); + TreeUtil.addChildren(element, lparenth); + TreeUtil.addChildren(element, parameter); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + final CompositeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr != null) { + TreeUtil.addChildren(element, expr); + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + } + if (lexer.getTokenType() == RPARENTH) { + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + final CompositeElement body = parseStatement(lexer); + if (body != null) { + TreeUtil.addChildren(element, body); + } else { + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + } + } + else { + TreeUtil.addChildren(element, Factory.createErrorElement("')' expected")); + } + return element; + } + + private CompositeElement parseForLoopFromInitialization(final TreeElement forKeyword, + final TreeElement lparenth, + Lexer lexer) {// parsing normal for statement for statement + CompositeElement element = Factory.createCompositeElement(FOR_STATEMENT); + TreeUtil.addChildren(element, forKeyword); + TreeUtil.addChildren(element, lparenth); + CompositeElement init = parseStatement(lexer); + if (init == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + if (lexer.getTokenType() != RPARENTH){ + return element; + } + } + else{ + TreeUtil.addChildren(element, init); + + CompositeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr != null){ + TreeUtil.addChildren(element, expr); + } + + if (lexer.getTokenType() != SEMICOLON){ + TreeUtil.addChildren(element, Factory.createErrorElement("';' expected")); + if (lexer.getTokenType() != RPARENTH){ + return element; + } + } + else{ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + parseExpressionOrExpressionList(lexer, element); + if (lexer.getTokenType() != RPARENTH){ + TreeUtil.addChildren(element, Factory.createErrorElement("')' expected")); + return element; + } + } + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + CompositeElement statement = parseStatement(lexer); + if (statement == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + return element; + } + + TreeUtil.addChildren(element, statement); + + return element; + } + + private void parseExpressionOrExpressionList(Lexer lexer, CompositeElement element) { + CompositeElement expression = myContext.getExpressionParsing().parseExpression(lexer); + if (expression != null) { + final CompositeElement expressionStatement; + if (lexer.getTokenType() != COMMA) { + expressionStatement = Factory.createCompositeElement(EXPRESSION_STATEMENT); + TreeUtil.addChildren(expressionStatement, expression); + } else { + expressionStatement = Factory.createCompositeElement(EXPRESSION_LIST_STATEMENT); + final CompositeElement expressionList = Factory.createCompositeElement(EXPRESSION_LIST); + TreeUtil.addChildren(expressionList, expression); + do { + TreeUtil.addChildren(expressionList, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + final CompositeElement nextExpression = myContext.getExpressionParsing().parseExpression(lexer); + if (nextExpression != null) { + TreeUtil.addChildren(expressionList, nextExpression); + } else { + TreeUtil.addChildren(expressionList, Factory.createErrorElement("Expression expected")); + } + } while (lexer.getTokenType() == COMMA); + TreeUtil.addChildren(expressionStatement, expressionList); + } + TreeUtil.addChildren(element, expressionStatement); + } + } + + private CompositeElement parseDoWhileStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == DO_KEYWORD); + CompositeElement element = Factory.createCompositeElement(DO_WHILE_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement statement = parseStatement(lexer); + if (statement == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Statement expected")); + return element; + } + + TreeUtil.addChildren(element, statement); + + if (lexer.getTokenType() != WHILE_KEYWORD){ + TreeUtil.addChildren(element, Factory.createErrorElement("'while' expected")); + return element; + } + + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (!processExpressionInParens(lexer, element)){ + return element; + } + + processClosingSemicolon(element, lexer); + + return element; + } + + private CompositeElement parseSwitchStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == SWITCH_KEYWORD); + CompositeElement element = Factory.createCompositeElement(SWITCH_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (!processExpressionInParens(lexer, element)){ + return element; + } + + CompositeElement codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + if (codeBlock == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("'{' expected")); + return element; + } + + TreeUtil.addChildren(element, codeBlock); + return element; + } + + private CompositeElement parseSwitchLabelStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == CASE_KEYWORD || lexer.getTokenType() == DEFAULT_KEYWORD); + IElementType tokenType = lexer.getTokenType(); + long pos = ParseUtil.savePosition(lexer); + CompositeElement element = Factory.createCompositeElement(SWITCH_LABEL_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + if (tokenType == CASE_KEYWORD){ + TreeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr == null){ + ParseUtil.restorePosition(lexer, pos); + return null; + } + TreeUtil.addChildren(element, expr); + } + if (lexer.getTokenType() == COLON){ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + TreeUtil.addChildren(element, Factory.createErrorElement("':' expected")); + } + return element; + } + + private CompositeElement parseBreakStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == BREAK_KEYWORD); + CompositeElement element = Factory.createCompositeElement(BREAK_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (lexer.getTokenType() == IDENTIFIER){ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + processClosingSemicolon(element, lexer); + return element; + } + + private CompositeElement parseContinueStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == CONTINUE_KEYWORD); + CompositeElement element = Factory.createCompositeElement(CONTINUE_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (lexer.getTokenType() == IDENTIFIER){ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + + processClosingSemicolon(element, lexer); + return element; + } + + private CompositeElement parseReturnStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == RETURN_KEYWORD); + CompositeElement element = Factory.createCompositeElement(RETURN_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr != null){ + TreeUtil.addChildren(element, expr); + } + + processClosingSemicolon(element, lexer); + return element; + } + + private CompositeElement parseThrowStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == THROW_KEYWORD); + + CompositeElement element = Factory.createCompositeElement(THROW_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr != null){ + TreeUtil.addChildren(element, expr); + } + else{ + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + + processClosingSemicolon(element, lexer); + return element; + } + + private CompositeElement parseSynchronizedStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == SYNCHRONIZED_KEYWORD); + CompositeElement element = Factory.createCompositeElement(SYNCHRONIZED_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (!processExpressionInParens(lexer, element)){ + return element; + } + + CompositeElement codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + if (codeBlock == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("'{' expected")); + return element; + } + + TreeUtil.addChildren(element, codeBlock); + return element; + } + + private CompositeElement parseTryStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == TRY_KEYWORD); + + //int pos = ParseUtil.savePosition(lexer); + CompositeElement element = Factory.createCompositeElement(TRY_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + CompositeElement codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + if (codeBlock == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("'{' expected")); + return element; + } + TreeUtil.addChildren(element, codeBlock); + + if (lexer.getTokenType() != CATCH_KEYWORD && lexer.getTokenType() != FINALLY_KEYWORD){ + TreeUtil.addChildren(element, Factory.createErrorElement("'catch' or 'finally' expected")); + return element; + } + + while(lexer.getTokenType() == CATCH_KEYWORD){ + CompositeElement catchSection = parseCatchSection(lexer); + TreeUtil.addChildren(element, catchSection); + if (catchSection.lastChild.getElementType() == ERROR_ELEMENT) break; + } + + if (lexer.getTokenType() == FINALLY_KEYWORD){ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + if (codeBlock == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("'{' expected")); + return element; + } + TreeUtil.addChildren(element, codeBlock); + } + + return element; + } + + private CompositeElement parseCatchSection(Lexer lexer) { + CompositeElement codeBlock; + CompositeElement catchSection = Factory.createCompositeElement(CATCH_SECTION); + TreeUtil.addChildren(catchSection, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + if (lexer.getTokenType() != LPARENTH) { + TreeUtil.addChildren(catchSection, Factory.createErrorElement("'(' expected")); + return catchSection; + } + + TreeUtil.addChildren(catchSection, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement parm = myContext.getDeclarationParsing().parseParameter(lexer, false); + if (parm == null) { + TreeUtil.addChildren(catchSection, Factory.createErrorElement("Parameter expected")); + return catchSection; + } + TreeUtil.addChildren(catchSection, parm); + + if (lexer.getTokenType() != RPARENTH) { + TreeUtil.addChildren(catchSection, Factory.createErrorElement("')' expected")); + return catchSection; + } + + TreeUtil.addChildren(catchSection, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + if (codeBlock == null) { + TreeUtil.addChildren(catchSection, Factory.createErrorElement("'{' expected")); + return catchSection; + } + TreeUtil.addChildren(catchSection, codeBlock); + return catchSection; + } + + private CompositeElement parseAssertStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == ASSERT_KEYWORD); + + CompositeElement element = Factory.createCompositeElement(ASSERT_STATEMENT); + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Boolean expression expected")); + return element; + } + + TreeUtil.addChildren(element, expr); + + if (lexer.getTokenType() == COLON){ + TreeUtil.addChildren(element, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + TreeElement expr2 = myContext.getExpressionParsing().parseExpression(lexer); + if (expr2 == null){ + TreeUtil.addChildren(element, Factory.createErrorElement("Expression expected")); + return element; + } + + TreeUtil.addChildren(element, expr2); + } + + processClosingSemicolon(element, lexer); + return element; + } + + private CompositeElement parseBlockStatement(Lexer lexer) { + LOG.assertTrue(lexer.getTokenType() == LBRACE); + CompositeElement element = Factory.createCompositeElement(BLOCK_STATEMENT); + CompositeElement codeBlock = parseCodeBlock(lexer, DEEP_PARSE_BLOCKS_IN_STATEMENTS); + TreeUtil.addChildren(element, codeBlock); + return element; + } + + private boolean processExpressionInParens(Lexer lexer, CompositeElement parent) { + if (lexer.getTokenType() != LPARENTH){ + TreeUtil.addChildren(parent, Factory.createErrorElement("'(' expected")); + return false; + } + + TreeUtil.addChildren(parent, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + long beforeExprPos = ParseUtil.savePosition(lexer); + CompositeElement expr = myContext.getExpressionParsing().parseExpression(lexer); + if (expr == null || lexer.getTokenType() == SEMICOLON){ + if (expr != null){ + ParseUtil.restorePosition(lexer, beforeExprPos); + } + TreeUtil.addChildren(parent, Factory.createErrorElement("Expression expected")); + if (lexer.getTokenType() != RPARENTH){ + return false; + } + } + else{ + TreeUtil.addChildren(parent, expr); + + if (lexer.getTokenType() != RPARENTH){ + TreeUtil.addChildren(parent, Factory.createErrorElement("')' expected")); + return false; + } + } + + // add ')' + TreeUtil.addChildren(parent, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + + return true; + } + + private void processClosingSemicolon(CompositeElement statement, Lexer lexer) { + if (lexer.getTokenType() == SEMICOLON){ + TreeUtil.addChildren(statement, ParseUtil.createTokenElement(lexer, myContext.getCharTable())); + lexer.advance(); + } + else{ + TreeUtil.addChildren(statement, Factory.createErrorElement("';' expected")); + } + } + + public static TreeElement parseCatchSectionText(PsiManagerImpl manager, char[] buffer, CharTable table) { + Lexer lexer = new JavaLexer(manager.getEffectiveLanguageLevel()); + final ParsingContext context = new ParsingContext(table); + final FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(WHITE_SPACE_OR_COMMENT_BIT_SET)); + filterLexer.start(buffer, 0, buffer.length); + + CompositeElement catchSection = context.getStatementParsing().parseCatchSection(filterLexer); + if (catchSection == null) return null; + if (filterLexer.getTokenType() != null) return null; + + ParseUtil.insertMissingTokens(catchSection, lexer, 0, buffer.length, ParseUtil.WhiteSpaceAndCommentsProcessor.INSTANCE, context); + return catchSection; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java new file mode 100644 index 00000000000..eff4ceb7750 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java @@ -0,0 +1,768 @@ +package com.intellij.psi.impl.source.parsing.xml; + +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer._OldXmlLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.parsing.ParseUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.CharTable; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Mike + */ +public class XmlParsing implements ElementType { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.xml.XmlParser"); + + public static final TokenSet XML_WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.create(new IElementType[]{XML_WHITE_SPACE, XML_COMMENT_START, XML_COMMENT_CHARACTERS, + XML_COMMENT_END, XML_BAD_CHARACTER}); + + public static final TokenSet XML_COMMENT_BIT_SET = TokenSet.create(new IElementType[]{XML_COMMENT_START, XML_COMMENT_CHARACTERS, XML_COMMENT_END}); + + private ParsingContext myContext; + + public XmlParsing(ParsingContext context) { + myContext = context; + } + + + public TreeElement parse(Lexer originalLexer, char[] buffer, int startOffset, int endOffset, PsiManager manager) { + final Lexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(XML_WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(buffer, startOffset, endOffset); + + final FileElement dummyRoot = new DummyHolder(manager, null, myContext.getCharTable()).getTreeElement(); + + CompositeElement root = Factory.createCompositeElement(XML_DOCUMENT); + TreeUtil.addChildren(dummyRoot, root); + TreeUtil.addChildren(root, parseProlog(lexer)); + parseGenericXml(lexer, root, new HashSet()); + + ParseUtil.insertMissingTokens((CompositeElement)root, + originalLexer, + startOffset, + endOffset, + WhiteSpaceAndCommentsProcessor.INSTANCE, myContext); + return root; + } + + public static TreeElement parseTag(Lexer lexer, char[] buffer, int startOffset, int endOffset, CharTable table, TreeElement parent) { + ParsingContext context = new ParsingContext(table); + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(XML_WHITE_SPACE_OR_COMMENT_BIT_SET)); + filterLexer.start(buffer, startOffset, endOffset); + final FileElement holderElement = new DummyHolder(null, null, table).getTreeElement(); + final Set names = new HashSet(); + while (parent instanceof XmlTag) { + names.add(((XmlTag)parent).getName()); + parent = parent.getTreeParent(); + } + + context.getXmlParsing()._parseTag(holderElement, filterLexer, names); + while (filterLexer.getTokenType() != null) { + context.getXmlParsing().addToken(holderElement, filterLexer); + } + ParseUtil.insertMissingTokens(holderElement, lexer, startOffset, endOffset, WhiteSpaceAndCommentsProcessor.INSTANCE, context); + TreeElement result = holderElement.firstChild; + return result; + } + + public void parseGenericXml(Lexer lexer, CompositeElement root, Set names) { + boolean rootTagChecked = false; + while (lexer.getTokenType() != null) { + if (lexer.getTokenType() == XML_ATTLIST_DECL_START) { + TreeUtil.addChildren(root, parseAttlistDecl(lexer)); + } + else if (lexer.getTokenType() == XML_ELEMENT_DECL_START) { + TreeUtil.addChildren(root, parseElementDecl(lexer)); + } + else if (lexer.getTokenType() == XML_ENTITY_DECL_START) { + TreeUtil.addChildren(root, parseEntityDecl(lexer)); + } + else if (lexer.getTokenType() == XML_NOTATION_DECL_START) { + TreeUtil.addChildren(root, parseNotationDecl(lexer)); + } + else if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(root, parseEntityRef(lexer)); + } + else if (parseProcessingInstruction(root, lexer)) { + } + else if (_parseTag(root, lexer, names)) { + } + else if (lexer.getTokenType() != null) { + if (!rootTagChecked) { + //checkRootTag(root); + rootTagChecked = true; + } + + addToken(root, lexer); + } + } + + if (!rootTagChecked) { + //checkRootTag(root); + rootTagChecked = true; + } + } + + public TreeElement parseNotationDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(ElementType.XML_NOTATION_DECL); + + if (lexer.getTokenType() != XML_NOTATION_DECL_START) { + return decl; + } + + addToken(decl, lexer); + + if (!parseName(decl, lexer)) { + return decl; + } + + parseEntityDeclContent(decl, lexer); + + if (lexer.getTokenType() != null) { + addToken(decl, lexer); + } + + return decl; + } + + private TreeElement parseEntityDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(ElementType.XML_ENTITY_DECL); + + if (lexer.getTokenType() != XML_ENTITY_DECL_START) { + return decl; + } + + addToken(decl, lexer); + + if (lexer.getTokenType() == XML_PERCENT) { + addToken(decl, lexer); + } + + if (!parseName(decl, lexer)) { + return decl; + } + + parseEntityDeclContent(decl, lexer); + + if (lexer.getTokenType() != null) { + addToken(decl, lexer); + } + + return decl; + } + + public void parseEntityDeclContent(CompositeElement decl, Lexer lexer) { + while (lexer.getTokenType() != XML_TAG_END && lexer.getTokenType() != null) { + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(decl, lexer); + } + else { + addToken(decl, lexer); + } + } + } + + private boolean parseProcessingInstruction(CompositeElement parent, Lexer lexer) { + if (lexer.getTokenType() != XML_PI_START) { + return false; + } + CompositeElement tag = Factory.createCompositeElement(XML_PROCESSING_INSTRUCTION); + TreeUtil.addChildren(parent, tag); + + addToken(tag, lexer); + if (lexer.getTokenType() != XML_PI_TARGET) { + return true; + } + addToken(tag, lexer); + if (lexer.getTokenType() != XML_PI_END) { + return true; + } + addToken(tag, lexer); + return true; + } + + private boolean _parseTag(CompositeElement parent, Lexer lexer, Set names) { + if (lexer.getTokenType() != XML_START_TAG_START) { + return false; + } + + CompositeElement tag = Factory.createCompositeElement(XML_TAG); + TreeUtil.addChildren(parent, tag); + + addToken(tag, lexer); + + if (lexer.getTokenType() != XML_TAG_NAME) { + return true; + } + + String openedName = StringFactory.createStringFromConstantArray(lexer.getBuffer(), lexer.getTokenStart(), + lexer.getTokenEnd() - lexer.getTokenStart()); + addToken(tag, lexer); + + parseAttributeList(tag, lexer); + + while (lexer.getTokenType() == XML_BAD_CHARACTER || lexer.getTokenType() == XML_NAME) { + addToken(tag, lexer); + parseAttributeList(tag, lexer); + } + TreeElement tagEnd = null; + if (lexer.getTokenType() == XML_TAG_END) { + tagEnd = addToken(tag, lexer); + boolean setFlag = false; + if (!names.contains(openedName)) { + names.add(openedName); + setFlag = true; + } + while (true) { + if (parseProcessingInstruction(tag, lexer)) { + } + else if (_parseTag(tag, lexer, names)) { + } + else if (lexer.getTokenType() == XML_DATA_CHARACTERS) { + addToken(tag, lexer); + } + else if (lexer.getTokenType() == XML_CDATA_START) { + addToken(tag, lexer); + } + else if (lexer.getTokenType() == XML_CDATA_END) { + addToken(tag, lexer); + } + else if (lexer.getTokenType() == XML_CHAR_ENTITY_REF) { + addToken(tag, lexer); + } + else if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(tag, parseEntityRef(lexer)); + } + else { + break; + } + } + if (setFlag) { + names.remove(openedName); + } + + long pos = ParseUtil.savePosition(lexer); + + if (lexer.getTokenType() != XML_END_TAG_START) { + TreeUtil.insertAfter(tagEnd, Factory.createErrorElement("Element is not closed")); + + return false; + } + TreeElement endTagStart = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + lexer.advance(); + + if (lexer.getTokenType() != XML_TAG_NAME) { + TreeUtil.addChildren(tag, endTagStart); + return true; + } + + String closingName = StringFactory.createStringFromConstantArray(lexer.getBuffer(), lexer.getTokenStart(), + lexer.getTokenEnd() - lexer.getTokenStart()); + + if (!closingName.equals(openedName) && names.contains(closingName)) { + ParseUtil.restorePosition(lexer, pos); + if (tagEnd != null) { + final TreeElement start = tagEnd.getTreeNext(); + tagEnd.setTreeNext(null); + if (start != null) { + TreeUtil.addChildren(parent, start); + } + } + TreeUtil.insertAfter(tagEnd, Factory.createErrorElement("Element is not closed")); + return true; + } + + TreeUtil.addChildren(tag, endTagStart); + addToken(tag, lexer); + + if (lexer.getTokenType() != XML_TAG_END) { + return true; + } + + addToken(tag, lexer); + } + else if (lexer.getTokenType() == XML_EMPTY_ELEMENT_END) { + addToken(tag, lexer); + } + else { + TreeUtil.insertAfter(tag.lastChild, Factory.createErrorElement("Element is not closed")); + } + + return true; + } + + private TreeElement parseEntityRef(Lexer lexer) { + CompositeElement ref = Factory.createCompositeElement(XML_ENTITY_REF); + + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + addToken(ref, lexer); + } + + return ref; + } + + private TreeElement parseProlog(Lexer lexer) { + CompositeElement prolog = Factory.createCompositeElement(XML_PROLOG); + + while (parseProcessingInstruction(prolog, lexer)) { + } + + if (lexer.getTokenType() == XML_DECL_START) { + TreeUtil.addChildren(prolog, parseDecl(lexer)); + } + + while (parseProcessingInstruction(prolog, lexer)) { + } + + if (lexer.getTokenType() == XML_DOCTYPE_START) { + TreeUtil.addChildren(prolog, parseDocType(lexer)); + } + + while (parseProcessingInstruction(prolog, lexer)) { + } + + return prolog; + } + + private TreeElement parseDocType(Lexer lexer) { + CompositeElement docType = Factory.createCompositeElement(XML_DOCTYPE); + + if (lexer.getTokenType() != XML_DOCTYPE_START) { + return docType; + } + + addToken(docType, lexer); + + if (lexer.getTokenType() != XML_NAME) { + return docType; + } + + addToken(docType, lexer); + + if (lexer.getTokenType() == XML_DOCTYPE_SYSTEM) { + addToken(docType, lexer); + + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(docType, lexer); + } + } + else if (lexer.getTokenType() == XML_DOCTYPE_PUBLIC) { + addToken(docType, lexer); + + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(docType, lexer); + } + + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(docType, lexer); + } + } + + if (lexer.getTokenType() == XML_MARKUP_START) { + TreeUtil.addChildren(docType, parseMarkupDecl(lexer)); + } + + if (lexer.getTokenType() != XML_DOCTYPE_END) { + return docType; + } + + addToken(docType, lexer); + + return docType; + } + + private TreeElement parseMarkupDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(XML_MARKUP_DECL); + + parseMarkupContent(lexer, decl); + + return decl; + } + + private void parseMarkupContent(Lexer lexer, CompositeElement decl) { + if (lexer.getTokenType() == XML_MARKUP_START) { + addToken(decl, lexer); + } + + while (true) { + if (lexer.getTokenType() == XML_ELEMENT_DECL_START) { + TreeUtil.addChildren(decl, parseElementDecl(lexer)); + } + else if (lexer.getTokenType() == XML_ATTLIST_DECL_START) { + TreeUtil.addChildren(decl, parseAttlistDecl(lexer)); + } + else if (lexer.getTokenType() == XML_ENTITY_DECL_START) { + TreeUtil.addChildren(decl, parseEntityDecl(lexer)); + } + else if (lexer.getTokenType() == XML_NOTATION_DECL_START) { + TreeUtil.addChildren(decl, parseNotationDecl(lexer)); + } + else { + break; + } + } + + if (lexer.getTokenType() == XML_MARKUP_END) { + addToken(decl, lexer); + } + } + + private TreeElement parseElementDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(ElementType.XML_ELEMENT_DECL); + + if (lexer.getTokenType() != XML_ELEMENT_DECL_START) { + return decl; + } + + addToken(decl, lexer); + + if (!parseName(decl, lexer)) { + return decl; + } + + parseElementContentSpec(decl, lexer); + + if (lexer.getTokenType() == XML_TAG_END) { + addToken(decl, lexer); + } + + return decl; + } + + private boolean parseName(CompositeElement decl, Lexer lexer) { + if (lexer.getTokenType() == XML_NAME) { + addToken(decl, lexer); + + return true; + } + + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(decl, parseEntityRef(lexer)); + return true; + } + + return false; + } + + public TreeElement parseElementContentSpec(CompositeElement parent, Lexer lexer) { + CompositeElement spec = Factory.createCompositeElement(XML_ELEMENT_CONTENT_SPEC); + TreeUtil.addChildren(parent, spec); + + while ( + lexer.getTokenType() != null && + lexer.getTokenType() != XML_TAG_END && + lexer.getTokenType() != XML_START_TAG_START && + lexer.getTokenType() != XML_ELEMENT_DECL_START) { + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(spec, parseEntityRef(lexer)); + } + else { + addToken(spec, lexer); + } + } + + return spec; + } + + private TreeElement parseAttlistDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(XML_ATTLIST_DECL); + + if (lexer.getTokenType() != XML_ATTLIST_DECL_START) { + return decl; + } + + addToken(decl, lexer); + + if (lexer.getTokenType() != XML_NAME) { + return decl; + } + + addToken(decl, lexer); + + parseAttlistContent(decl, lexer); + + if (lexer.getTokenType() == XML_TAG_END) { + addToken(decl, lexer); + } + + return decl; + } + + public void parseAttlistContent(CompositeElement parent, Lexer lexer) { + while (true) { + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(parent, parseEntityRef(lexer)); + } + else if (parseAttributeDecl(parent, lexer)) { + } + else { + break; + } + } + } + + private boolean parseAttributeDecl(CompositeElement parent, Lexer lexer) { + if (lexer.getTokenType() != XML_NAME) { + return false; + } + + CompositeElement decl = Factory.createCompositeElement(ElementType.XML_ATTRIBUTE_DECL); + TreeUtil.addChildren(parent, decl); + + addToken(decl, lexer); + + return parseAttributeContentSpec(decl, lexer); + } + + public boolean parseAttributeContentSpec(CompositeElement parent, Lexer lexer) { + if (parseName(parent, lexer)) { + } + else if (lexer.getTokenType() == XML_LEFT_PAREN) { + TreeUtil.addChildren(parent, parseEnumeratedType(lexer)); + } + else { + return true; + } + + if (lexer.getTokenType() == XML_ATT_IMPLIED) { + addToken(parent, lexer); + } + else if (lexer.getTokenType() == XML_ATT_REQUIRED) { + addToken(parent, lexer); + } + else if (lexer.getTokenType() == XML_ATT_FIXED) { + addToken(parent, lexer); + + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(parent, lexer); + } + } + else if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(parent, lexer); + } + + return true; + } + + private CompositeElement parseEnumeratedType(Lexer lexer) { + CompositeElement enumeratedType = Factory.createCompositeElement(XML_ENUMERATED_TYPE); + addToken(enumeratedType, lexer); + + parseEnumeratedTypeContent(enumeratedType, lexer); + + if (lexer.getTokenType() == XML_RIGHT_PAREN) { + addToken(enumeratedType, lexer); + } + + return enumeratedType; + } + + public void parseEnumeratedTypeContent(CompositeElement enumeratedType, Lexer lexer) { + while (true) { + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(enumeratedType, parseEntityRef(lexer)); + continue; + } + + if (lexer.getTokenType() != XML_NAME && lexer.getTokenType() != XML_BAR) break; + addToken(enumeratedType, lexer); + } + } + + TreeElement parseDecl(Lexer lexer) { + CompositeElement decl = Factory.createCompositeElement(XML_DECL); + + if (lexer.getTokenType() != XML_DECL_START) { + return decl; + } + addToken(decl, lexer); + + parseAttributeList(decl, lexer); + + if (lexer.getTokenType() == XML_DECL_END) { + addToken(decl, lexer); + } + else { + TreeUtil.addChildren(decl, Factory.createErrorElement("'?>' expected")); + } + + return decl; + } + + private void parseAttributeList(CompositeElement tag, Lexer lexer) { + int lastPosition = -1; + while (true) { + if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(tag, parseEntityRef(lexer)); + continue; + } + + if (lexer.getTokenType() != XML_NAME) { + return; + } + + if (lastPosition != -1) { + if (lastPosition == lexer.getTokenStart()) { + TreeUtil.addChildren(tag, Factory.createErrorElement("Whitespace expected")); + lastPosition = -1; + } + } + + addToken(tag, lexer); + + if (lexer.getTokenType() != XML_EQ) { + TreeUtil.addChildren(tag, Factory.createErrorElement("'=' expected")); + continue; + } + + addToken(tag, lexer); + + if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { + return; + } + + addToken(tag, lexer); + + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(tag, lexer); + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_END_DELIMITER) { + lastPosition = lexer.getTokenEnd(); + addToken(tag, lexer); + } else { + lastPosition = -1; + } + } else { + lastPosition = -1; + } + } + } + + private int parseAttributeValue(CompositeElement parent, Lexer lexer) { + if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { + return -1; + } + + CompositeElement value = Factory.createCompositeElement(XML_ATTRIBUTE_VALUE); + + TreeUtil.addChildren(parent, value); + + addToken(value, lexer); + + while (true) { + if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(value, lexer); + } + else if (lexer.getTokenType() == XML_CHAR_ENTITY_REF) { + addToken(value, lexer); + } + else if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { + TreeUtil.addChildren(value, parseEntityRef(lexer)); + } + else { + break; + } + } + + if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_END_DELIMITER) { + return -1; + } + + int tokenEnd = lexer.getTokenEnd(); + addToken(value, lexer); + return tokenEnd; + } + + private TreeElement addToken(CompositeElement decl, Lexer lexer) { + final TreeElement element = ParseUtil.createTokenElement(lexer, myContext.getCharTable()); + TreeUtil.addChildren(decl, element); + lexer.advance(); + return element; + } + + public TreeElement parseMarkupDecl(Lexer originalLexer, char[] text, int start, int end) { + final Lexer lexer = new FilterLexer(originalLexer, new FilterLexer.SetFilter(XML_WHITE_SPACE_OR_COMMENT_BIT_SET)); + lexer.start(text, start, end, _OldXmlLexer.DOCTYPE); + + final FileElement dummyRoot = new DummyHolder(null, null, myContext.getCharTable()).getTreeElement(); + CompositeElement markupDecl = Factory.createCompositeElement(XmlElementType.XML_MARKUP_DECL); + TreeUtil.addChildren(dummyRoot, markupDecl); + parseMarkupContent(lexer, markupDecl); + while(lexer.getTokenType() != null){ + TreeUtil.addChildren(markupDecl, ParseUtil.createTokenElement(lexer, dummyRoot.getCharTable())); + lexer.advance(); + } + originalLexer.start(text, start, end, _OldXmlLexer.DOCTYPE); + ParseUtil.insertMissingTokens((CompositeElement)dummyRoot, + originalLexer, + start, + end, + WhiteSpaceAndCommentsProcessor.INSTANCE, myContext); + return dummyRoot.firstChild; + } + + public static class WhiteSpaceAndCommentsProcessor implements ParseUtil.TokenProcessor { + public static final ParseUtil.TokenProcessor INSTANCE = new WhiteSpaceAndCommentsProcessor(); + + private WhiteSpaceAndCommentsProcessor() { + } + + public TreeElement process(Lexer lexer, ParsingContext context) { + TreeElement first = null; + TreeElement last = null; + while (isTokenValid(lexer.getTokenType())) { + TreeElement tokenElement = null; + + IElementType type = lexer.getTokenType(); + if (!XML_WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(type)) { + LOG.assertTrue(false, "Missed token should be white space or comment:" + type); + throw new RuntimeException(); + } + + if (lexer.getTokenType() == XML_COMMENT_START) { + tokenElement = parseComment(lexer, context); + } + else { + tokenElement = ParseUtil.createTokenElement(lexer, context.getCharTable()); + lexer.advance(); + } + + if (last != null) { + last.setTreeNext(tokenElement); + tokenElement.setTreePrev(last); + last = tokenElement; + } + else { + first = last = tokenElement; + } + } + return first; + } + + public boolean isTokenValid(IElementType tokenType) { + return tokenType != null && XML_WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(tokenType); + } + + private TreeElement parseComment(Lexer lexer, ParsingContext context) { + final CompositeElement comment = Factory.createCompositeElement(ElementType.XML_COMMENT); + + while (lexer.getTokenType() != null && XML_COMMENT_BIT_SET.isInSet(lexer.getTokenType())) { + final TreeElement tokenElement = ParseUtil.createTokenElement(lexer, context.getCharTable()); + lexer.advance(); + TreeUtil.addChildren(comment, tokenElement); + } + + return comment; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java new file mode 100644 index 00000000000..2dbd1b17c23 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java @@ -0,0 +1,24 @@ +package com.intellij.psi.impl.source.parsing.xml; + +import com.intellij.lexer.OldXmlLexer; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.tree.IElementType; + +/** + * @author Mike + */ +public class XmlPsiLexer extends OldXmlLexer{ + public XmlPsiLexer() { + } + + public IElementType getTokenType() { + IElementType type = super.getTokenType(); + + if (type == XmlTokenType.XML_WHITE_SPACE) { + return ElementType.WHITE_SPACE; + } + + return type; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java new file mode 100644 index 00000000000..4bcb5289d19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java @@ -0,0 +1,205 @@ +package com.intellij.psi.impl.source.resolve; + +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.infos.ClassCandidateInfo; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.processor.PsiResolverProcessor; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ClassResolverProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint, PsiResolverProcessor { + private final String myClassName; + private PsiElement myPlace; + private PsiClass myAccessClass = null; + private boolean myAccessibleResultsFlag = false; + private List myCandidates = null; + private ResolveResult[] myResult = ResolveResult.EMPTY_ARRAY; + private PsiElement myCurrentFileContext; + + public ClassResolverProcessor(String className, PsiElement place) { + myClassName = className; + myPlace = place; + final PsiFile file = myPlace.getContainingFile(); + if (file instanceof PsiCodeFragment) { + if (((PsiCodeFragment)file).getVisibilityChecker() != null) myPlace = null; + } + if (place instanceof PsiReferenceExpression) { + final PsiReferenceExpression expression = (PsiReferenceExpression)place; + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null) { + final PsiType type = qualifierExpression.getType(); + if (type instanceof PsiClassType) { + myAccessClass = ((PsiClassType)type).resolve(); + } + } + } + } + + public ResolveResult[] getResult() { + if (myResult != null) return myResult; + if (myCandidates == null) return myResult = ResolveResult.EMPTY_ARRAY; + + { + // normalizing + if (myAccessibleResultsFlag && myCandidates.size() > 1) { + final ClassCandidateInfo[] infos = myCandidates.toArray(new ClassCandidateInfo[myCandidates.size()]); + for (int i = 0; i < infos.length; i++) { + final ClassCandidateInfo info = infos[i]; + if (!info.isAccessible()) { + myCandidates.remove(info); + } + } + } + } + myResult = myCandidates.toArray(new ResolveResult[myCandidates.size()]); + return myResult; + } + + public String getName() { + return myClassName; + } + + public boolean shouldProcess(Class elementClass) { + return PsiClass.class.isAssignableFrom(elementClass); + } + + private boolean myGrouped = false; + private boolean myStaticContext = false; + + public void handleEvent(Event event, Object associated) { + if (event == Event.BEGIN_GROUP) { + myGrouped = true; + } + else if (event == Event.END_GROUP) { + myGrouped = false; + } + else if (event == Event.START_STATIC) { + myStaticContext = true; + } else if (event == Event.SET_CURRENT_FILE_CONTEXT) { + myCurrentFileContext = (PsiElement)associated; + } + else if (event == Event.SET_DECLARATION_HOLDER) { + } + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + final String name = aClass.getName(); + if (myClassName.equals(name)) { + boolean accessible; + + if (myPlace != null) { + accessible = checkAccessibility(aClass); + } + else { + accessible = true; + } + + if (accessible) { + myAccessibleResultsFlag = true; + if (!myGrouped) { + myCandidates = null; + myResult = new ResolveResult[]{new CandidateInfo(aClass, substitutor, null, null, false, myCurrentFileContext)}; + return false; + } + } + + myResult = null; + if (myCandidates == null) { + myCandidates = new ArrayList(); + } + else { + String fqName = aClass.getQualifiedName(); + if (fqName != null) { + final Iterator iterator = myCandidates.iterator(); + while (iterator.hasNext()) { + final ClassCandidateInfo info = (ClassCandidateInfo)iterator.next(); + if (fqName.equals(info.getCandidate().getQualifiedName())) { + return true; + } + } + } + } + myCandidates.add(new ClassCandidateInfo(aClass, substitutor, !accessible, myGrouped, myCurrentFileContext)); + } + } + return true; + } + + private boolean checkAccessibility(final PsiClass aClass) { + //We don't care about accessibility in javadocs + + if (ResolveUtil.findParentContextOfClass(myPlace, PsiDocComment.class, false) != null) { + return true; + } + + boolean accessible = true; + + if (aClass.getContainingFile() instanceof JspFile) { + PsiFile file = ResolveUtil.getContextFile(myPlace); + if (file instanceof JspFile) { + return true; + } + } + + if (aClass instanceof PsiTypeParameter) { + accessible = !(myStaticContext); + } + + PsiManager manager = aClass.getManager(); + if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { + PsiElement parent = aClass.getParent(); + while (true) { + PsiElement parentScope = parent.getParent(); + if (parentScope instanceof PsiJavaFile) break; + parent = parentScope; + if (!(parentScope instanceof PsiClass)) break; + } + if (parent instanceof PsiDeclarationStatement) { + parent = parent.getParent(); + } + accessible = false; + for (PsiElement placeParent = myPlace; placeParent != null; placeParent = placeParent.getContext()) { + if (manager.areElementsEquivalent(placeParent, parent)) accessible = true; + } + } + if (aClass.hasModifierProperty(PsiModifier.PROTECTED)) { + accessible = false; + if (manager.arePackagesTheSame(aClass, myPlace)) { + accessible = true; + } + else { + if (aClass.getContainingClass() != null) { + if (myAccessClass != null) { + accessible = manager.getResolveHelper().isAccessible(aClass, myPlace, myAccessClass); + } + else { + accessible = true; + } + } + } + } + if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { + if (!manager.arePackagesTheSame(aClass, myPlace)) { + accessible = false; + } + } + return accessible; + } + + public void forceResult(ResolveResult[] result) { + myResult = result; + } + + public String getProcessorType() { + return "class resolver"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java new file mode 100644 index 00000000000..7a4fc19327a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -0,0 +1,438 @@ +package com.intellij.psi.impl.source.resolve; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.jsp.JspImplicitVariable; +import com.intellij.psi.scope.MethodProcessorSetupFailedException; +import com.intellij.psi.scope.processor.MethodCandidatesProcessor; +import com.intellij.psi.scope.processor.MethodResolverProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.xml.XmlFile; + +public class PsiResolveHelperImpl implements PsiResolveHelper, Constants { + private final PsiManager myManager; + + public PsiResolveHelperImpl(PsiManager manager) { + myManager = manager; + } + + public ResolveResult resolveConstructor(PsiClassType classType, PsiExpressionList argumentList, PsiElement place) { + ResolveResult[] result = multiResolveConstructor(classType, argumentList, place); + if (result.length != 1) return ResolveResult.EMPTY; + return result[0]; + } + + public ResolveResult[] multiResolveConstructor(PsiClassType type, PsiExpressionList argumentList, PsiElement place) { + final MethodResolverProcessor processor; + PsiClassType.ClassResolveResult classResolveResult = type.resolveGenerics(); + final PsiClass aClass = classResolveResult.getElement(); + final ResolveResult[] result; + if (aClass == null) { + result = ResolveResult.EMPTY_ARRAY; + } + else { + if (argumentList.getParent() instanceof PsiAnonymousClass) { + processor = new MethodResolverProcessor((PsiClass)argumentList.getParent(), argumentList, place); + } + else { + processor = new MethodResolverProcessor(aClass, argumentList, place); + } + PsiScopesUtil.processScope(aClass, processor, classResolveResult.getSubstitutor(), aClass, place); + + // getting the most suitable myResult + result = processor.getResult(); + } + return result; + } + + public PsiClass resolveReferencedClass(String referenceText, PsiElement context) { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + CompositeElement ref = Parsing.parseJavaCodeReferenceText(myManager, referenceText.toCharArray(), holderElement.getCharTable()); + if (ref == null) return null; + if (!SourceTreeToPsiMap.hasTreeElement(context)) { //??? + return myManager.findClass(referenceText, context.getResolveScope()); + } + TreeUtil.addChildren(holderElement, ref); + + return ResolveClassUtil.resolveClass((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(ref)); + } + + public PsiVariable resolveReferencedVariable(String referenceText, PsiElement context) { + final FileElement holderElement = new DummyHolder(myManager, context).getTreeElement(); + TreeElement ref = Parsing.parseJavaCodeReferenceText(myManager, referenceText.toCharArray(), holderElement.getCharTable()); + if (ref == null) return null; + TreeUtil.addChildren(holderElement, ref); + PsiJavaCodeReferenceElement psiRef = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(ref); + return ResolveVariableUtil.resolveVariable(psiRef, null, null); + } + + public boolean isAccessible(PsiMember member, PsiElement place, PsiClass accessObjectClass) { + return isAccessible(member, member.getModifierList(), place, accessObjectClass); + } + + + public boolean isAccessible(PsiMember member, PsiModifierList modifierList, PsiElement place, PsiClass accessObjectClass) { + if (modifierList == null) return true; + final PsiFile placeContainingFile = place.getContainingFile(); + final PsiManager manager = placeContainingFile.getManager(); + if (placeContainingFile instanceof PsiCodeFragment) { + PsiCodeFragment fragment = (PsiCodeFragment)placeContainingFile; + PsiCodeFragment.VisibilityChecker visibilityChecker = fragment.getVisibilityChecker(); + if (visibilityChecker != null) { + PsiCodeFragment.VisibilityChecker.Visibility visibility = visibilityChecker.isDeclarationVisible(member, place); + if (visibility == PsiCodeFragment.VisibilityChecker.Visibility.VISIBLE) return true; + if (visibility == PsiCodeFragment.VisibilityChecker.Visibility.NOT_VISIBLE) return false; + } + } + else if (placeContainingFile instanceof XmlFile) return true; + // We don't care about access rights in javadoc + if (ResolveUtil.findParentContextOfClass(place, PsiDocComment.class, false) != null) return true; + + // access modifier of member as it seen from the place. + // In case of methods it can be different from member modifier, + // if method is overridden in subclass with different access modifier. See SCR 9547 + if (accessObjectClass != null && !isAccessible(accessObjectClass, place, null)) return false; + + int effectiveAccessLevel = PsiUtil.getAccessLevel(modifierList); + PsiFile file = ResolveUtil.getContextFile(place); //TODO: implementation method!!!! + if (file instanceof JspFile && (member.getContainingFile() instanceof JspFile || member instanceof JspImplicitVariable)) return true; + if (file instanceof XmlFile) return true; + if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC) { + return true; + } + else if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) { + if (manager.arePackagesTheSame(member, place)) return true; + PsiClass memberClass = member.getContainingClass(); + if (memberClass == null) return false; + + for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) { + if (placeParent instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)placeParent, memberClass, true)) { + if (member instanceof PsiClass || modifierList.hasModifierProperty(PsiModifier.STATIC)) return true; + if (accessObjectClass == null) return true; + if (manager.areElementsEquivalent(accessObjectClass, placeParent) + || accessObjectClass.isInheritor((PsiClass)placeParent, true)) { + return true; + } + } + if (placeParent instanceof JspFileImpl && InheritanceUtil.isInheritorOrSelf(((JspFileImpl)placeParent).getBaseClass(), memberClass, true)) { + if (accessObjectClass == null) return true; + if (accessObjectClass.isInheritor(((JspFileImpl)placeParent).getBaseClass(), true)) return true; + } + } + return false; + } + else if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) { + final PsiClass memberClass = member.getContainingClass(); + if (accessObjectClass != null) { + if (!manager.areElementsEquivalent(memberClass, accessObjectClass)) return false; + } + + boolean isConstructor = member instanceof PsiMethod && ((PsiMethod)member).isConstructor(); + PsiClass placeClass = getPlaceTopLevelClass (place, memberClass, isConstructor); + if (placeClass != null) { + for (PsiElement memberClassParent = memberClass; memberClassParent != null; memberClassParent = memberClassParent.getContext()) { + if (manager.areElementsEquivalent(placeClass, memberClassParent)) return true; + } + for (PsiElement placeClassParent = placeClass; placeClassParent != null; placeClassParent = placeClassParent.getContext()) { + if (manager.areElementsEquivalent(memberClass, placeClassParent)) return true; + } + } + + return false; + } + else { + if (!manager.arePackagesTheSame(member, place)) return false; + if (modifierList.hasModifierProperty(PsiModifier.STATIC)) return true; + // maybe inheritance lead through package local class in other package ? + final PsiClass memberClass = member.getContainingClass(); + final PsiClass placeClass = ResolveUtil.getContextClass(place); + if (memberClass == null || placeClass == null) return true; + // check only classes since interface members are public, and if placeClass is interface, + // then its members are static, and cannot refer to nonstatic members of memberClass + if (memberClass.isInterface() || placeClass.isInterface()) return true; + if (placeClass.isInheritor(memberClass, true)) { + PsiClass superClass = placeClass.getSuperClass(); + while (!manager.areElementsEquivalent(superClass, memberClass)) { + if (!manager.arePackagesTheSame(superClass, memberClass)) return false; + superClass = superClass.getSuperClass(); + } + } + + return true; + } + } + + private PsiClass getPlaceTopLevelClass(PsiElement place, PsiClass memberClass, boolean isPrivateConstructor) { + PsiManager manager = place.getManager(); + PsiClass lastClass = null; + for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) { + if (placeParent instanceof PsiClass) { + PsiClass aClass = (PsiClass)placeParent; + + //what we see is the member from the base class rather than enclosing one + //Private constructors are the exceptions: they ARE accessible from decendants + if (!isPrivateConstructor && manager.areElementsEquivalent(memberClass, aClass.getSuperClass())) return aClass; + lastClass = aClass; + } + } + + return lastClass; + } + + public CandidateInfo[] getReferencedMethodCandidates(PsiCallExpression expr, boolean dummyImplicitConstructor) { + final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr); + try { + PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor); + } + catch (MethodProcessorSetupFailedException e) { + return CandidateInfo.EMPTY_ARRAY; + } + return processor.getCandidates(); + } + + public PsiType inferTypeForMethodTypeParameter(final PsiTypeParameter typeParameter, + final PsiParameter[] parameters, + PsiExpression[] arguments, PsiSubstitutor partialSubstitutor, PsiElement parent) { + PsiType substitution = PsiType.NULL; + if (parameters.length > 0) { + for (int j = 0; j < arguments.length; j++) { + PsiExpression argument = arguments[j]; + final PsiParameter parameter = parameters[Math.min(j, parameters.length - 1)]; + if (j >= parameters.length && !parameter.isVarArgs()) break; + final PsiType currentSubstitution = getSubstitutionForTypeParameter(typeParameter, parameter.getType(), + argument.getType(), true); + if (currentSubstitution == null) { + substitution = null; + break; + } else if (currentSubstitution instanceof PsiWildcardType) { + if (substitution instanceof PsiWildcardType) return PsiType.NULL; + } else if (currentSubstitution == PsiType.NULL) continue; + + if (substitution == PsiType.NULL) { + substitution = currentSubstitution; + continue; + } + if (!substitution.equals(currentSubstitution) && !substitution.isAssignableFrom(currentSubstitution)) { + substitution = GenericsUtil.getLeastUpperBound(substitution, currentSubstitution, typeParameter.getManager()); + if (substitution == null) { + break; + } + } + } + } + + if (substitution == PsiType.NULL) { + substitution = inferMethodTypeParameterFromParent(typeParameter, partialSubstitutor, parent); + } + return substitution; + } + + private PsiType processArgType(PsiType arg, boolean captureWildcard) { + if (arg instanceof PsiWildcardType) { + return captureWildcard ? arg : PsiType.NULL; + } else { + if (arg == null || arg.getDeepComponentType() instanceof PsiPrimitiveType || + PsiUtil.resolveClassInType(arg) != null) return arg; + } + + return PsiType.NULL; + } + + private PsiType inferMethodTypeParameterFromParent(final PsiTypeParameter typeParameter, + PsiSubstitutor substitutor, + PsiElement parent) { + PsiTypeParameterListOwner owner = typeParameter.getOwner(); + PsiType substitution = PsiType.NULL; + if (owner instanceof PsiMethod) { + if (parent instanceof PsiMethodCallExpression) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)parent; + substitution = inferMethodTypeParameterFromParent(methodCall.getParent(), methodCall, typeParameter, substitutor); + } + } + return substitution; + } + + public PsiType getSubstitutionForTypeParameter(PsiTypeParameter typeParam, + PsiType param, + PsiType arg, + boolean isContraVariantPosition) { + if (param instanceof PsiEllipsisType) { + if (arg instanceof PsiArrayType) arg = ((PsiArrayType)arg).getComponentType(); + return getSubstitutionForTypeParameter(typeParam, ((PsiEllipsisType)param).getComponentType(), arg, isContraVariantPosition); + } + + if (param instanceof PsiArrayType && arg instanceof PsiArrayType) { + return getSubstitutionForTypeParameter(typeParam, ((PsiArrayType)param).getComponentType(), ((PsiArrayType)arg).getComponentType(), + isContraVariantPosition); + } + + if (param instanceof PsiClassType) { + PsiManager manager = typeParam.getManager(); + if (arg instanceof PsiPrimitiveType) { + arg = ((PsiPrimitiveType)arg).getBoxedType(manager, typeParam.getResolveScope()); + if (arg == null) return PsiType.NULL; + } + + ResolveResult paramResult = ((PsiClassType)param).resolveGenerics(); + PsiClass paramClass = (PsiClass)paramResult.getElement(); + if (typeParam == paramClass) { + return arg == null || arg.getDeepComponentType() instanceof PsiPrimitiveType || + PsiUtil.resolveClassInType(arg) != null ? arg : PsiType.NULL; + } + if (paramClass == null) return PsiType.NULL; + + if (arg instanceof PsiClassType) { + ResolveResult argResult = ((PsiClassType)arg).resolveGenerics(); + PsiClass argClass = (PsiClass)argResult.getElement(); + if (argClass == null) return PsiType.NULL; + + PsiElementFactory factory = manager.getElementFactory(); + PsiType patternType = factory.createType(typeParam); + if (isContraVariantPosition) { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(paramClass, argClass, argResult.getSubstitutor()); + if (substitutor == null) return PsiType.NULL; + arg = factory.createType(paramClass, substitutor); + } + else { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(argClass, paramClass, paramResult.getSubstitutor()); + if (substitutor == null) return PsiType.NULL; + param = factory.createType(argClass, substitutor); + } + + PsiType substitution = getSubstitutionForTypeParameterInner(param, arg, patternType, false); + return substitution != PsiType.NULL ? substitution : getSubstitutionForTypeParameterInner(param, arg, patternType, true); + } + } + + return PsiType.NULL; + } + + private PsiType getSubstitutionForTypeParameterInner(PsiType param, + PsiType arg, + PsiType patternType, + boolean captureWildcard) { + if (param instanceof PsiWildcardType) { + if (arg instanceof PsiWildcardType && ((PsiWildcardType)arg).isExtends() == ((PsiWildcardType)param).isExtends()) { + PsiType res = getSubstitutionForTypeParameterInner(((PsiWildcardType)param).getBound(), ((PsiWildcardType)arg).getBound(), + patternType, captureWildcard); + if (res != PsiType.NULL) return res; + } + else if (patternType.equals(((PsiWildcardType)param).getBound())) { + if (((PsiWildcardType)param).isExtends()) { + return processArgType(arg, captureWildcard); + } + } + } + else if (patternType.equals(param)) { + return processArgType(arg, captureWildcard); + } + + if (param instanceof PsiArrayType && arg instanceof PsiArrayType) { + return getSubstitutionForTypeParameterInner(((PsiArrayType)param).getComponentType(), ((PsiArrayType)arg).getComponentType(), + patternType, captureWildcard); + } + + if (param instanceof PsiClassType && arg instanceof PsiClassType) { + PsiClass paramClass = ((PsiClassType)param).resolve(); + if (paramClass == null) return PsiType.NULL; + + PsiClass argClass = ((PsiClassType)arg).resolve(); + if (argClass != paramClass) return PsiType.NULL; + + PsiType[] paramTypes = ((PsiClassType)param).getParameters(); + PsiType[] argTypes = ((PsiClassType)arg).getParameters(); + if (paramTypes.length != argTypes.length) return PsiType.NULL; + PsiType capturedWildcard = PsiType.NULL; + for (int i = 0; i < argTypes.length; i++) { + PsiType res = getSubstitutionForTypeParameterInner(paramTypes[i], argTypes[i], patternType, captureWildcard); + if (res != PsiType.NULL) { + if (!captureWildcard) { + return res; + } + else { + if (capturedWildcard != PsiType.NULL) { + return PsiType.NULL; + } + else { + capturedWildcard = res; + } + } + } + } + + return capturedWildcard; + } + + return PsiType.NULL; + } + + private PsiType inferMethodTypeParameterFromParent(PsiElement parent, + PsiMethodCallExpression methodCall, + final PsiTypeParameter typeParameter, + PsiSubstitutor substitutor) { + PsiType type = null; + + if (parent instanceof PsiVariable && methodCall.equals(((PsiVariable)parent).getInitializer())) { + type = ((PsiVariable)parent).getType(); + } + else if (parent instanceof PsiAssignmentExpression && methodCall.equals(((PsiAssignmentExpression)parent).getRExpression())) { + type = ((PsiAssignmentExpression)parent).getLExpression().getType(); + } + else if (parent instanceof PsiTypeCastExpression && methodCall.equals(((PsiTypeCastExpression)parent).getOperand())) { + type = ((PsiTypeCastExpression)parent).getType(); + } + else if (parent instanceof PsiReturnStatement) { + PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); + if (method != null) { + type = method.getReturnType(); + } + } + + if (type == null) { + type = PsiType.getJavaLangObject(methodCall.getManager(), methodCall.getResolveScope()); + } + + PsiType returnType = ((PsiMethod)typeParameter.getOwner()).getReturnType(); + PsiType guess = getSubstitutionForTypeParameter(typeParameter, returnType, type, false); + + if (guess == PsiType.NULL) { + PsiType superType = substitutor.substitute(typeParameter.getSuperTypes()[0]); + return superType == null ? PsiType.getJavaLangObject(methodCall.getManager(), methodCall.getResolveScope()) : superType; + } + + //The following code is the result of deep thought, do not shit it out before discussing with [ven] + if (returnType instanceof PsiClassType && typeParameter.equals(((PsiClassType)returnType).resolve())) { + PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); + PsiSubstitutor newSubstitutor = substitutor.put(typeParameter, guess); + for (int i = 0; i < extendsTypes.length; i++) { + PsiType extendsType = newSubstitutor.substitute(extendsTypes[i]); + if (!extendsType.isAssignableFrom(guess)) { + if (guess.isAssignableFrom(extendsType)) { + guess = extendsType; + newSubstitutor = substitutor.put(typeParameter, guess); + } + else { + break; + } + } + } + } + + return guess; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveCache.java new file mode 100644 index 00000000000..5bba4bf78cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveCache.java @@ -0,0 +1,220 @@ +package com.intellij.psi.impl.source.resolve; + +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.containers.WeakHashMap; + +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.Set; + +public class ResolveCache { + private static final Key JAVA_RESOLVE_MAP = Key.create("ResolveCache.JAVA_RESOLVE_MAP"); + private static final Key RESOLVE_MAP = Key.create("ResolveCache.RESOLVE_MAP"); + private static final Key JAVA_RESOLVE_MAP_INCOMPLETE = Key.create("ResolveCache.JAVA_RESOLVE_MAP_INCOMPLETE"); + private static final Key RESOLVE_MAP_INCOMPLETE = Key.create("ResolveCache.RESOLVE_MAP_INCOMPLETE"); + private static final Key IS_BEING_RESOLVED_KEY = Key.create("ResolveCache.IS_BEING_RESOLVED_KEY"); + private static final Key VAR_TO_CONST_VALUE_MAP_KEY = Key.create("ResolveCache.VAR_TO_CONST_VALUE_MAP_KEY"); + + private static final Object NULL = Key.create("NULL"); + + private final PsiManagerImpl myManager; + + private final WeakHashMap myVarToConstValueMap1; + + private final WeakHashMap[] myJavaResolveMaps = new WeakHashMap[4]; + private final WeakHashMap[] myResolveMaps = new WeakHashMap[4]; + + private final WeakHashMap myVarToConstValueMap2; + + public static interface GenericsResolver{ + ResolveResult[] resolve(PsiJavaReference ref, boolean incompleteCode); + } + + public static interface Resolver{ + PsiElement resolve(PsiReference ref, boolean incompleteCode); + } + + public ResolveCache(PsiManagerImpl manager) { + myManager = manager; + + myVarToConstValueMap1 = getOrCreateWeakMap(myManager, VAR_TO_CONST_VALUE_MAP_KEY, true); + myJavaResolveMaps[0] = getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP, true); + myJavaResolveMaps[1] = getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP_INCOMPLETE, true); + myResolveMaps[0] = getOrCreateWeakMap(myManager, RESOLVE_MAP, true); + myResolveMaps[1] = getOrCreateWeakMap(myManager, RESOLVE_MAP_INCOMPLETE, true); + + myVarToConstValueMap2 = getOrCreateWeakMap(myManager, VAR_TO_CONST_VALUE_MAP_KEY, false); + myJavaResolveMaps[2] = getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP, false); + myJavaResolveMaps[3] = getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP_INCOMPLETE, false); + + myResolveMaps[2] = getOrCreateWeakMap(myManager, RESOLVE_MAP, false); + myResolveMaps[3] = getOrCreateWeakMap(myManager, RESOLVE_MAP_INCOMPLETE, false); + } + + public void clearCache() { + synchronized (PsiLock.LOCK) { + getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP, true).clear(); + getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP_INCOMPLETE, true).clear(); + getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP, false).clear(); + getOrCreateWeakMap(myManager, JAVA_RESOLVE_MAP_INCOMPLETE, false).clear(); + getOrCreateWeakMap(myManager, RESOLVE_MAP, true).clear(); + getOrCreateWeakMap(myManager, RESOLVE_MAP_INCOMPLETE, true).clear(); + getOrCreateWeakMap(myManager, RESOLVE_MAP, false).clear(); + getOrCreateWeakMap(myManager, RESOLVE_MAP_INCOMPLETE, false).clear(); + } + } + + public PsiElement resolveWithCaching(PsiReference ref, + Resolver resolver, + boolean needToPreventRecursion, + boolean incompleteCode) { + ProgressManager.getInstance().checkCanceled(); + + synchronized (PsiLock.LOCK) { + // lock is necessary here because of needToPreventRecursion + boolean physical = ref.getElement().isPhysical(); + final Reference cached = getCachedResolve(ref, physical, incompleteCode); + if (cached != null) return cached.get(); + ; + if (incompleteCode) { + final PsiElement results = resolveWithCaching(ref, resolver, needToPreventRecursion, false); + if (results != null) { + setCachedResolve(ref, results, physical, true); + return results; + } + } + if (needToPreventRecursion) { + PsiElement element = ref.getElement(); + if (element.getUserData(IS_BEING_RESOLVED_KEY) != null) return null; + element.putUserData(IS_BEING_RESOLVED_KEY, ""); + } + final PsiElement result = resolver.resolve(ref, incompleteCode); + if (needToPreventRecursion) { + PsiElement element = ref.getElement(); + element.putUserData(IS_BEING_RESOLVED_KEY, null); + } + setCachedResolve(ref, result, physical, incompleteCode); + return result; + } + } + + private void setCachedResolve(PsiReference ref, PsiElement results, boolean physical, boolean incompleteCode) { + int index = getIndex(physical, incompleteCode); + myResolveMaps[index].put(ref, new SoftReference(results)); + } + + private Reference getCachedResolve(PsiReference ref, boolean physical, boolean incompleteCode) { + int index = getIndex(physical, incompleteCode); + final Reference reference = (Reference)myResolveMaps[index].get(ref); + if(reference == null) return null; + return reference; + } + + public ResolveResult[] resolveWithCaching(PsiJavaReference ref, + GenericsResolver resolver, + boolean needToPreventRecursion, + boolean incompleteCode) { + ProgressManager.getInstance().checkCanceled(); + + synchronized (PsiLock.LOCK) { + // lock is necessary here because of needToPreventRecursion + boolean physical = ref.getElement().isPhysical(); + final ResolveResult[] cached = getCachedJavaResolve(ref, physical, incompleteCode); + if (cached != null) return cached; + ; + if (incompleteCode) { + final ResolveResult[] results = resolveWithCaching(ref, resolver, needToPreventRecursion, false); + if (results != null && results.length > 0) { + setCachedJavaResolve(ref, results, physical, true); + return results; + } + } + if (needToPreventRecursion) { + PsiElement element = ref.getElement(); + if (element.getUserData(IS_BEING_RESOLVED_KEY) != null) return ResolveResult.EMPTY_ARRAY; + element.putUserData(IS_BEING_RESOLVED_KEY, ""); + } + final ResolveResult[] result = resolver.resolve(ref, incompleteCode); + if (needToPreventRecursion) { + PsiElement element = ref.getElement(); + element.putUserData(IS_BEING_RESOLVED_KEY, null); + } + setCachedJavaResolve(ref, result, physical, incompleteCode); + return result; + } + } + + private int getIndex(boolean physical, boolean ic){ + return (physical ? 0 : 1) << 1 | (ic ? 1 : 0); + } + + public void setCachedJavaResolve(PsiReference ref, ResolveResult[] result, boolean physical, boolean ic){ + int index = getIndex(physical, ic); + myJavaResolveMaps[index].put(ref, new SoftReference(result)); + } + + private ResolveResult[] getCachedJavaResolve(PsiReference ref, boolean physical, boolean ic){ + int index = getIndex(physical, ic); + final Reference reference = (Reference)myJavaResolveMaps[index].get(ref); + if(reference == null) return null; + return (ResolveResult[]) reference.get(); + } + + public static interface ConstValueComputer{ + Object execute(PsiVariable variable, Set visitedVars); + } + + public Object computeConstantValueWithCaching(PsiVariable variable, ConstValueComputer computer, Set visitedVars){ + boolean physical = variable.isPhysical(); + + Object cached = (physical ? myVarToConstValueMap1 : myVarToConstValueMap2).get(variable); + if (cached == NULL) return null; + if (cached != null) return cached; + + Object result = computer.execute(variable, visitedVars); + + (physical ? myVarToConstValueMap1 : myVarToConstValueMap2).put(variable, result != null ? result : NULL); + + return result; + } + + public static WeakHashMap getOrCreateWeakMap(final PsiManagerImpl manager, final Key key, boolean forPhysical) { + MapPair pair = (MapPair)manager.getUserData(key); + if (pair == null){ + pair = new MapPair(); + manager.putUserData(key, pair); + + final MapPair _pair = pair; + manager.registerRunnableToRunOnChange( + new Runnable() { + public void run() { + //_pair.physicalMap = new WeakHashMap(); + _pair.physicalMap.clear(); + } + } + ); + manager.registerRunnableToRunOnAnyChange( + new Runnable() { + public void run() { + //_pair.nonPhysicalMap = new WeakHashMap(); + _pair.nonPhysicalMap.clear(); + } + } + ); + } + return forPhysical ? pair.physicalMap : pair.nonPhysicalMap; + } + + private static class MapPair{ + public WeakHashMap physicalMap; + public WeakHashMap nonPhysicalMap; + + public MapPair() { + physicalMap = new WeakHashMap(); + nonPhysicalMap = new WeakHashMap(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java new file mode 100644 index 00000000000..45e3524314c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java @@ -0,0 +1,63 @@ + +package com.intellij.psi.impl.source.resolve; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.PsiUtil; + +public class ResolveClassUtil implements Constants{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.ResolveClassUtil"); + + public static PsiClass resolveClass(PsiJavaCodeReferenceElement ref) { + if (ref instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl)ref).getKind() == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND){ + PsiExpression qualifier; + PsiElement parent = ref.getParent(); + if (parent instanceof PsiAnonymousClass){ + parent = parent.getParent(); + } + if (parent instanceof PsiNewExpression){ + qualifier = ((PsiNewExpression)parent).getQualifier(); + LOG.assertTrue(qualifier != null); + } + else if (parent instanceof PsiJavaCodeReferenceElement){ + return null; + } + else{ + LOG.assertTrue(false); + return null; + } + + PsiType qualifierType = qualifier.getType(); + if (qualifierType == null) return null; + if (!(qualifierType instanceof PsiClassType)) return null; + PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType); + if (qualifierClass == null) return null; + String name = ref.getText(); + return qualifierClass.findInnerClassByName(name, true); + } + + final PsiElement classNameElement; + classNameElement = ref.getReferenceNameElement(); + if (!(classNameElement instanceof PsiIdentifier)) return null; + String className = classNameElement.getText(); + + /* + long time1 = System.currentTimeMillis(); + */ + + ClassResolverProcessor processor = new ClassResolverProcessor(className, ref); + PsiScopesUtil.resolveAndWalk(processor, ref, null); + + + /* + long time2 = System.currentTimeMillis(); + Statistics.resolveClassTime += (time2 - time1); + Statistics.resolveClassCount++; + */ + + return processor.getResult().length == 1 ? (PsiClass)processor.getResult()[0].getElement() : null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java new file mode 100644 index 00000000000..007df0a12a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java @@ -0,0 +1,43 @@ + +package com.intellij.psi.impl.source.resolve; + +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiVariable; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.scope.util.PsiScopesUtil; + +public class ResolveVariableUtil { + public static PsiVariable resolveVariable( + PsiJavaCodeReferenceElement ref, + boolean[] problemWithAccess, + boolean[] problemWithStatic + ) { + + /* + long time1 = System.currentTimeMillis(); + */ + + final VariableResolverProcessor processor = new VariableResolverProcessor(ref); + PsiScopesUtil.resolveAndWalk(processor, ref, null); + + /* + long time2 = System.currentTimeMillis(); + Statistics.resolveVariableTime += (time2 - time1); + Statistics.resolveVariableCount++; + */ + final ResolveResult[] result = processor.getResult(); + if(result.length != 1) return null; + final PsiVariable refVar = (PsiVariable) result[0].getElement(); + + if (problemWithAccess != null){ + problemWithAccess[0] = !result[0].isAccessible(); + } + if (problemWithStatic != null){ + problemWithStatic[0] = !result[0].isStaticsScopeCorrect(); + } + + + return refVar; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java new file mode 100644 index 00000000000..6b9b293f358 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java @@ -0,0 +1,78 @@ +package com.intellij.psi.impl.source.resolve; + +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.conflictResolvers.JavaVariableConflictResolver; +import com.intellij.psi.scope.processor.ConflictFilterProcessor; +import com.intellij.psi.scope.processor.PsiResolverProcessor; +import com.intellij.psi.util.PsiUtil; + +import java.util.ArrayList; + +/** + * @author ik, dsl + */ +public class VariableResolverProcessor extends ConflictFilterProcessor implements NameHint, ElementClassHint, PsiResolverProcessor { + private static final ClassFilter ourFilter = new ClassFilter(PsiVariable.class); + + private final PsiElement myFromElement; + private boolean myStaticScopeFlag = false; + private PsiClass myAccessClass = null; + private PsiElement myCurrentFileContext = null; + + public VariableResolverProcessor(String name, PsiElement place, PsiClass accessClass){ + super(name, null, ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new ArrayList()); + myFromElement = place; + myAccessClass = accessClass; + } + + public VariableResolverProcessor(PsiJavaCodeReferenceElement fromElement) { + super(fromElement.getText(), null, ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new ArrayList()); + myFromElement = fromElement; + + PsiElement qualifier = fromElement.getQualifier(); + PsiElement referenceName = fromElement.getReferenceNameElement(); + + if (referenceName instanceof PsiIdentifier){ + setName(referenceName.getText()); + } + if (qualifier instanceof PsiExpression){ + final ResolveResult accessClass = PsiUtil.getAccessObjectClass((PsiExpression)qualifier); + final PsiElement element = accessClass.getElement(); + if (element instanceof PsiTypeParameter) { + final PsiManager manager = element.getManager(); + final PsiClassType type = manager.getElementFactory().createType((PsiTypeParameter) element); + final PsiType accessType = accessClass.getSubstitutor().substitute(type); + if(accessType instanceof PsiArrayType) + myAccessClass = manager.getElementFactory().getArrayClass(); + else if(accessType instanceof PsiClassType) + myAccessClass = ((PsiClassType)accessType).resolve(); + } + else if (element instanceof PsiClass) + myAccessClass = (PsiClass) element; + } + } + + public final void handleEvent(Event event, Object associated) { + super.handleEvent(event, associated); + if(event == Event.START_STATIC){ + myStaticScopeFlag = true; + } + else if (Event.SET_CURRENT_FILE_CONTEXT.equals(event)) { + myCurrentFileContext = (PsiElement)associated; + } + } + + public void add(PsiElement element, PsiSubstitutor substitutor) { + final boolean staticProblem = myStaticScopeFlag && !(((PsiVariable)element).hasModifierProperty(PsiModifier.STATIC)); + super.add(new CandidateInfo(element, substitutor, myFromElement, myAccessClass, staticProblem, myCurrentFileContext)); + } + + public String getProcessorType(){ + return "variables resolver"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ElementManipulator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ElementManipulator.java new file mode 100644 index 00000000000..570fc050a51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ElementManipulator.java @@ -0,0 +1,16 @@ +package com.intellij.psi.impl.source.resolve.reference; + +import com.intellij.psi.PsiElement; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.IncorrectOperationException; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 03.04.2003 + * Time: 11:22:05 + * To change this template use Options | File Templates. + */ +public interface ElementManipulator{ + PsiElement handleContentChange(PsiElement element, TextRange range, String newContent) throws IncorrectOperationException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java new file mode 100644 index 00000000000..98182eb868b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java @@ -0,0 +1,54 @@ +package com.intellij.psi.impl.source.resolve.reference; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 01.04.2003 + * Time: 16:52:28 + * To change this template use Options | File Templates. + */ +public class ProviderBinding{ + private final ElementFilter myPosition; + private final List myScopes = new ArrayList(); + private final List myProviders = new ArrayList(); + + public ProviderBinding(ElementFilter filter, Class scope){ + myScopes.add(scope); + myPosition = filter; + } + + public ProviderBinding(Class scope){ + this(null, scope); + } + + public ProviderBinding(){ + myPosition = null; + } + + public boolean isAcceptable(PsiElement position){ + if(position == null) return false; + final Iterator iter = myScopes.iterator(); + while(iter.hasNext()){ + final Class scopeClass = (Class) iter.next(); + if(scopeClass.isAssignableFrom(position.getClass())){ + return myPosition == null || myPosition.isAcceptable(position, position); + } + } + return false; + } + + public void registerProvider(PsiReferenceProvider provider){ + myProviders.add(provider); + } + + public PsiReferenceProvider[] getProviders(){ + return (PsiReferenceProvider[]) myProviders.toArray(new PsiReferenceProvider[myProviders.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/PsiReferenceProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/PsiReferenceProvider.java new file mode 100644 index 00000000000..6cfab3a3c53 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/PsiReferenceProvider.java @@ -0,0 +1,26 @@ +package com.intellij.psi.impl.source.resolve.reference; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.scope.PsiScopeProcessor; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.03.2003 + * Time: 16:59:58 + * To change this template use Options | File Templates. + */ +public interface PsiReferenceProvider{ + PsiReference[] getReferencesByElement(PsiElement element); + /** + * @deprecated + */ + PsiReference[] getReferencesByElement(PsiElement element, ReferenceType type); + /** + * @deprecated + */ + PsiReference[] getReferencesByString(String str, PsiElement position, ReferenceType type, int offsetInPosition); + + void handleEmptyContext(PsiScopeProcessor processor, PsiElement position); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java new file mode 100644 index 00000000000..bc1f1d8d7d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java @@ -0,0 +1,187 @@ +package com.intellij.psi.impl.source.resolve.reference; + +import com.intellij.ant.impl.dom.impl.RegisterInPsi; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.PsiPlainTextFile; +import com.intellij.psi.filters.*; +import com.intellij.psi.filters.position.NamespaceFilter; +import com.intellij.psi.filters.position.ParentElementFilter; +import com.intellij.psi.filters.position.TokenTypeFilter; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.JspAttributeValueManipulator; +import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.PlainFileManipulator; +import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.XmlAttributeValueManipulator; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JSPActionReferenceProvider; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassListReferenceProvider; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; +import com.intellij.psi.jsp.JspAction; +import com.intellij.psi.jsp.JspAttributeValue; +import com.intellij.psi.jsp.JspDirective; +import com.intellij.psi.jsp.JspToken; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.xml.util.XmlUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.03.2003 + * Time: 17:13:45 + * To change this template use Options | File Templates. + */ +public class ReferenceProvidersRegistry implements ProjectComponent { + private final List myTempScopes = new ArrayList(); + private final List myBindings = new ArrayList(); + private final List myManipulators = new ArrayList(); + + public final static ReferenceProvidersRegistry getInstance(Project project) { + return project.getComponent(ReferenceProvidersRegistry.class); + } + + private ReferenceProvidersRegistry() { + // Temp scopes declarations + { + myTempScopes.add(JspToken.class); + myTempScopes.add(PsiIdentifier.class); + } + + // Manipulators mapping + { + registerManipulator(JspAttributeValue.class, new JspAttributeValueManipulator()); + registerManipulator(XmlAttributeValue.class, new XmlAttributeValueManipulator()); + registerManipulator(PsiPlainTextFile.class, new PlainFileManipulator()); + } + // Binding declarations + { + registerReferenceProvider( + new ScopeFilter( + new AndFilter( + new ParentElementFilter( + new TextFilter(new String[] { "class", "type" }) + ), + new ParentElementFilter( + new TextFilter("useBean"), 2 + ) + ) + ), + JspAttributeValue.class, + new JavaClassReferenceProvider() + ); + + RegisterInPsi.referenceProviders(this); + registerReferenceProvider( + new ScopeFilter( + new ParentElementFilter( + new AndFilter( + new TextFilter("extends"), + new ParentElementFilter( + new AndFilter( + new ClassFilter(JspDirective.class), + new TextFilter("page") + ) + ) + ) + ) + ), + JspAttributeValue.class, + new JavaClassReferenceProvider() + ); + + //registerReferenceProvider(new ScopeFilter(new ParentElementFilter(new AndFilter(new TextFilter("target"), + // new ParentElementFilter(new AndFilter( + // new NamespaceFilter(XmlUtil.ANT_URI), + // new TextFilter("antcall")))))), + // XmlAttributeValue.class, new AntTargetReferenceProvider()); + registerReferenceProvider(JspAction.class, new JSPActionReferenceProvider()); + registerReferenceProvider(new NotFilter(new ParentElementFilter(new NamespaceFilter(XmlUtil.ANT_URI), 2)), + XmlAttributeValue.class, new JavaClassListReferenceProvider()); + registerReferenceProvider(new TokenTypeFilter(XmlTokenType.XML_DATA_CHARACTERS), XmlToken.class, new JavaClassListReferenceProvider()); + } + + { + registerReferenceProvider(PsiPlainTextFile.class, new JavaClassListReferenceProvider()); + } + } + + public void registerReferenceProvider(ElementFilter elementFilter, Class scope, PsiReferenceProvider provider) { + final ProviderBinding binding = new ProviderBinding(elementFilter, scope); + binding.registerProvider(provider); + myBindings.add(binding); + } + + public void registerReferenceProvider(Class scope, PsiReferenceProvider provider) { + final ProviderBinding binding = new ProviderBinding(scope); + binding.registerProvider(provider); + myBindings.add(binding); + } + + public PsiReferenceProvider[] getProvidersByElement(PsiElement element) { + final List ret = new ArrayList(); + PsiElement current; + do { + current = element; + final Iterator iter = myBindings.iterator(); + + while (iter.hasNext()) { + final ProviderBinding binding = iter.next(); + if (binding.isAcceptable(current)) { + ret.addAll(Arrays.asList(binding.getProviders())); + } + } + element = ResolveUtil.getContext(element); + } + while (!isScopeFinal(current.getClass())); + + return ret.toArray(new PsiReferenceProvider[ret.size()]); + } + + public ElementManipulator getManipulator(PsiElement element) { + final Iterator iter = myManipulators.iterator(); + + while (iter.hasNext()) { + final Object[] pair = iter.next(); + if (((Class)pair[0]).isAssignableFrom(element.getClass())) { + return (ElementManipulator)pair[1]; + } + } + + return null; + } + + public void registerManipulator(Class elementClass, ElementManipulator manipulator) { + myManipulators.add(new Object[]{elementClass, manipulator}); + } + + private boolean isScopeFinal(Class scopeClass) { + final Iterator iter = myTempScopes.iterator(); + + while (iter.hasNext()) { + final Class currentClass = (Class)iter.next(); + if (currentClass.isAssignableFrom(scopeClass)) { + return false; + } + } + return true; + } + + public void projectOpened() {} + + public void projectClosed() {} + + public String getComponentName() { + return "Reference providers registry"; + } + + public void initComponent() {} + + public void disposeComponent() {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/GenericReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/GenericReference.java new file mode 100644 index 00000000000..d602ae0f7f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/GenericReference.java @@ -0,0 +1,109 @@ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.resolve.reference.*; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.scope.processor.ConflictFilterProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.util.ArrayUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.03.2003 + * Time: 17:33:24 + * To change this template use Options | File Templates. + */ +public abstract class GenericReference implements PsiReference{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.reference.impl.GenericReference"); + public static final GenericReference[] EMPTY_ARRAY = new GenericReference[0]; + private final PsiReferenceProvider myProvider; + + public boolean isSoft(){ + return false; + } + + public GenericReference(final PsiReferenceProvider provider){ + myProvider = provider; + } + + public PsiElement resolve(){ + final PsiManager manager = getElement().getManager(); + if(manager instanceof PsiManagerImpl){ + return ((PsiManagerImpl)manager).getResolveCache().resolveWithCaching(this, new ResolveCache.Resolver() { + public PsiElement resolve(PsiReference ref, boolean incompleteCode) { + return resolveInner(); + } + }, false, false); + } + return resolveInner(); + } + + public PsiElement resolveInner(){ + final List resultSet = new ArrayList(); + final ConflictFilterProcessor processor; + try{ + processor = ProcessorRegistry.getInstance().getProcessorByType(getType(), resultSet, needToCheckAccessibility() ? getElement() : null); + processor.setName(getCanonicalText()); + } + catch(ProcessorRegistry.IncompartibleReferenceTypeException e){ + LOG.error(e); + return null; + } + + processVariants(processor); + final ResolveResult[] result = processor.getResult(); + if(result.length != 1) return null; + return result[0].getElement(); + } + + public boolean isReferenceTo(final PsiElement element){ + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants(){ + final List ret = new ArrayList(); + final FilterScopeProcessor proc; + try{ + proc = ProcessorRegistry.getInstance().getProcessorByType(getSoftenType(), ret, needToCheckAccessibility() ? getElement() : null); + } + catch(ProcessorRegistry.IncompartibleReferenceTypeException e){ + LOG.error(e); + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + processVariants(proc); + + return ret.toArray(); + } + + public void processVariants(final PsiScopeProcessor processor){ + final PsiElement context = getContext(); + if(context != null){ + PsiScopesUtil.processScope(context, processor, PsiSubstitutor.EMPTY, getElement(), getElement()); + } + else if(getContextReference() == null){ + myProvider.handleEmptyContext(processor, getElement()); + } + } + + protected ElementManipulator getManipulator(PsiElement currentElement){ + return ReferenceProvidersRegistry.getInstance(currentElement.getProject()).getManipulator(currentElement); + } + + public String getUnresolvedMessage(){ + return getType().getUnresolvedMessage(); + } + + public abstract PsiElement getContext(); + public abstract PsiReference getContextReference(); + public abstract ReferenceType getType(); + public abstract ReferenceType getSoftenType(); + public abstract boolean needToCheckAccessibility(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/PsiMultiReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/PsiMultiReference.java new file mode 100644 index 00000000000..1106d3fd1d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/PsiMultiReference.java @@ -0,0 +1,107 @@ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 02.04.2003 + * Time: 12:22:03 + * To change this template use Options | File Templates. + */ + +public class PsiMultiReference implements PsiReference{ + private final PsiReference[] myReferences; + private final PsiElement myElement; + + public PsiMultiReference(PsiReference[] references, PsiElement element){ + myReferences = references; + myElement = element; + } + + private int myChoosenOne = -1; + + private PsiReference chooseReference(){ + if(myChoosenOne > 0){ + return myReferences[myChoosenOne]; + } + boolean flag = false; + myChoosenOne = 0; + boolean strict = false; + for(int i = 0; i < myReferences.length; i++){ + final PsiReference reference = myReferences[i]; + if(reference.isSoft() && flag) continue; + if(!reference.isSoft() && !flag){ + myChoosenOne = i; + flag = true; + continue; + } + if(reference instanceof GenericReference){ + if(((GenericReference)reference).getContext() != null){ + myChoosenOne = i; + strict = true; + } + } + if(reference.resolve() != null){ + myChoosenOne = i; + strict = true; + } + if(!strict){ + // One reference inside other + final TextRange rangeInElement1 = reference.getRangeInElement(); + final TextRange rangeInElement2 = myReferences[myChoosenOne].getRangeInElement(); + if(rangeInElement1.getStartOffset() >= rangeInElement2.getStartOffset() + && rangeInElement1.getEndOffset() <= rangeInElement2.getEndOffset()){ + myChoosenOne = i; + } + } + } + return myReferences[myChoosenOne]; + } + + public PsiElement getElement(){ + return myElement; + } + + public TextRange getRangeInElement(){ + return chooseReference().getRangeInElement(); + } + + public PsiElement resolve(){ + return chooseReference().resolve(); + } + + public String getCanonicalText(){ + return chooseReference().getCanonicalText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException{ + return chooseReference().handleElementRename(newElementName); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException{ + return chooseReference().bindToElement(element); + } + + public boolean isReferenceTo(PsiElement element){ + return chooseReference().isReferenceTo(element); + } + + public Object[] getVariants(){ + return chooseReference().getVariants(); + } + + public boolean isSoft(){ + return false; + } + + public void processVariants(final PsiScopeProcessor processor, PsiSubstitutor substitutor){ + if(chooseReference() instanceof GenericReference) + ((GenericReference)chooseReference()).processVariants(processor); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PlainFileManipulator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PlainFileManipulator.java new file mode 100644 index 00000000000..8bf2b04bbf4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PlainFileManipulator.java @@ -0,0 +1,28 @@ +package com.intellij.psi.impl.source.resolve.reference.impl.manipulators; + +import com.intellij.psi.impl.source.resolve.reference.ElementManipulator; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.util.IncorrectOperationException; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 09.12.2003 + * Time: 14:10:35 + * To change this template use Options | File Templates. + */ +public class PlainFileManipulator implements ElementManipulator { + public PsiElement handleContentChange(PsiElement element, TextRange range, String newContent) + throws IncorrectOperationException { + final Document document = FileDocumentManager.getInstance().getDocument(((PsiFile)element).getVirtualFile()); + document.replaceString(range.getStartOffset(), range.getEndOffset(), newContent); + PsiDocumentManager.getInstance(element.getProject()).commitDocument(document); + + return element; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java new file mode 100644 index 00000000000..13dfd7ff03e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java @@ -0,0 +1,53 @@ +package com.intellij.psi.impl.source.resolve.reference.impl.manipulators; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.resolve.reference.ElementManipulator; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.Factory; +import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.psi.impl.source.tree.SharedImplUtil; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.IncorrectOperationException; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 06.01.2004 + * Time: 20:00:23 + * To change this template use Options | File Templates. + */ +public class XmlAttributeValueManipulator implements ElementManipulator{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.reference.impl.manipulators.XmlAttributeValueManipulator"); + public PsiElement handleContentChange(PsiElement element, TextRange range, String newContent) throws IncorrectOperationException{ + final CompositeElement compositeElement = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(element); + final PsiElement nextSibling = element.getFirstChild().getNextSibling(); + + CheckUtil.checkWritable(element); + String text; + try { + text = element.getText(); + String textBeforeRange = text.substring(1, range.getStartOffset()); + String textAfterRange = text.substring(range.getEndOffset(), text.length() - 1); + text = textBeforeRange + newContent + textAfterRange; + } catch(StringIndexOutOfBoundsException e) { + LOG.error("Range: " + range + " in text: '" + element.getText() + "'", e); + throw e; + } + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(compositeElement); + final LeafElement newValueElement = Factory.createSingleLeafElement( + XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, + text.toCharArray(), + 0, + text.length(), charTableByTree, element.getManager()); + + + compositeElement.replaceChildInternal(SourceTreeToPsiMap.psiElementToTree(nextSibling), newValueElement); + return element; + //return ((XmlAttributeValueImpl) element).replaceRangeInText(range, newContent); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/GenericReferenceProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/GenericReferenceProvider.java new file mode 100644 index 00000000000..ae3631841e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/GenericReferenceProvider.java @@ -0,0 +1,33 @@ +package com.intellij.psi.impl.source.resolve.reference.impl.providers; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.reference.PsiReferenceProvider; +import com.intellij.psi.impl.source.resolve.reference.impl.GenericReference; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.scope.util.PsiScopesUtil; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.03.2003 + * Time: 17:23:43 + * To change this template use Options | File Templates. + */ +public abstract class GenericReferenceProvider implements PsiReferenceProvider{ + protected static final GenericReference[] EMPTY_ARRAY = new GenericReference[0]; + + public void handleEmptyContext(PsiScopeProcessor processor, PsiElement position){ + PsiScopesUtil.treeWalkUp(processor, position, null); + } + + private boolean mySoft = false; + + public void setSoft(boolean softFlag){ + mySoft = softFlag; + } + + public boolean isSoft(){ + return mySoft; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassListReferenceProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassListReferenceProvider.java new file mode 100644 index 00000000000..b91ddcd4eb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassListReferenceProvider.java @@ -0,0 +1,50 @@ +package com.intellij.psi.impl.source.resolve.reference.impl.providers; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.source.resolve.reference.ReferenceType; +import com.intellij.psi.impl.source.resolve.reference.impl.GenericReference; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 05.06.2003 + * Time: 20:27:59 + * To change this template use Options | File Templates. + */ +public class JavaClassListReferenceProvider extends JavaClassReferenceProvider{ + final static Pattern pattern = Pattern.compile("([A-Za-z]\\w*\\s*(\\.\\s*[A-Za-z]\\w*\\s*)+)"); + + public PsiReference[] getReferencesByString(String str, PsiElement position, ReferenceType type, int offsetInPosition){ + final List results = new ArrayList(); + final Set knownTopLevelPackages = new HashSet(); + final List defaultPackages = getDefaultPackages(position); + final Iterator iterator = defaultPackages.iterator(); + while (iterator.hasNext()) { + final PsiElement pack = iterator.next(); + if(pack instanceof PsiPackage) + knownTopLevelPackages.add(((PsiPackage)pack).getName()); + } + + final Matcher matcher = pattern.matcher(str); + + while(matcher.find()){ + final String identifier = matcher.group().trim(); + final int dotPosition = identifier.indexOf('.'); + if(identifier.lastIndexOf('.') != dotPosition + || knownTopLevelPackages.contains(identifier.substring(0, identifier.indexOf('.')))){ + results.addAll(Arrays.asList(new ReferenceSet(identifier, position, offsetInPosition + matcher.start(), type){ + protected boolean isSoft(){ + return true; + } + }.getAllReferences())); + } + } + return (GenericReference[])results.toArray(new GenericReference[results.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java new file mode 100644 index 00000000000..1e9f5138581 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java @@ -0,0 +1,246 @@ +package com.intellij.psi.impl.source.resolve.reference.impl.providers; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.resolve.reference.ElementManipulator; +import com.intellij.psi.impl.source.resolve.reference.ReferenceType; +import com.intellij.psi.impl.source.resolve.reference.impl.GenericReference; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +import java.lang.ref.SoftReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 27.03.2003 + * Time: 17:30:38 + * To change this template use Options | File Templates. + */ +public class JavaClassReferenceProvider extends GenericReferenceProvider{ + private static final char SEPARATOR = '.'; + + public PsiReference[] getReferencesByElement(PsiElement element){ + return getReferencesByString(element.getText(), element, new ReferenceType(ReferenceType.JAVA_CLASS), 0); + } + + public PsiReference[] getReferencesByElement(PsiElement element, ReferenceType type){ + return getReferencesByString(element.getText(), element, type, 0); + } + + public PsiReference[] getReferencesByString(String str, PsiElement position, ReferenceType type, int offsetInPosition){ + return new ReferenceSet(str, position, offsetInPosition, type).getAllReferences(); + } + + private static final SoftReference> NULL_REFERENCE = new SoftReference>(null); + private SoftReference> myDefaultPackageContent = NULL_REFERENCE; + private Runnable myPackagesEraser = null; + + public void handleEmptyContext(PsiScopeProcessor processor, PsiElement position){ + final ElementClassHint hint = processor.getHint(ElementClassHint.class); + if(position == null) return; + if(hint == null || hint.shouldProcess(PsiPackage.class) || hint.shouldProcess(PsiClass.class)){ + final List cachedPackages = getDefaultPackages(position); + final Iterator iterator = cachedPackages.iterator(); + while (iterator.hasNext()) { + final PsiElement psiPackage = iterator.next(); + if(!processor.execute(psiPackage, PsiSubstitutor.EMPTY)) return; + } + } + } + + protected List getDefaultPackages(PsiElement position) { + List cachedPackages = myDefaultPackageContent.get(); + if(cachedPackages == null){ + final List psiPackages = new ArrayList(); + final PsiManager manager = position.getManager(); + final PsiPackage rootPackage = manager.findPackage(""); + if(rootPackage != null){ + rootPackage.processDeclarations(new BaseScopeProcessor() { + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + psiPackages.add(element); + return true; + } + }, PsiSubstitutor.EMPTY, position, position); + } + if(myPackagesEraser == null){ + myPackagesEraser = new Runnable() { + public void run() { + myDefaultPackageContent = NULL_REFERENCE; + } + }; + } + cachedPackages = psiPackages; + ((PsiManagerImpl)manager).registerWeakRunnableToRunOnChange(myPackagesEraser); + myDefaultPackageContent = new SoftReference>(cachedPackages); + } + return cachedPackages; + } + + public String findPrefix(PsiElement element, int position){ + final String text = element.getText().substring(0, position + 1); + return text.substring(text.lastIndexOf(SEPARATOR) + 1); + } + + // Not implemented yet + public PsiElement handleElementRename(PsiElement element, String newElementName) throws IncorrectOperationException{ + return null; + } + + + // Not implemented yet + public PsiElement bindToElement(GenericReference reference, PsiElement element) throws IncorrectOperationException{ + return null; + } + + protected class ReferenceSet{ + private JavaReference[] myReferences; + private final PsiElement myElement; + private final int myStartInElement; + private final ReferenceType myType; + + ReferenceSet(String str, PsiElement element, int startInElement, ReferenceType type){ + myType = type; + myElement = element; + myStartInElement = startInElement; + reparse(str); + } + + private void reparse(String str){ + final List referencesList = new ArrayList(); + int currentDot = -1; + int index = 0; + JavaReference currentContextRef; + + while(true){ + final int nextDot = str.indexOf(SEPARATOR, currentDot + 1); + final String subreferenceText = nextDot > 0 ? str.substring(currentDot + 1, nextDot) : str.substring(currentDot + 1); + currentContextRef = new JavaReference(new TextRange(myStartInElement + currentDot + 1, + myStartInElement + (nextDot > 0 ? nextDot : str.length())), + index++, subreferenceText); + referencesList.add(currentContextRef); + if((currentDot = nextDot) < 0) + break; + } + + myReferences = referencesList.toArray(new JavaReference[referencesList.size()]); + } + + private void reparse(){ + reparse(myElement.getText()); + } + + private JavaReference getReference(int index){ + return myReferences[index]; + } + + protected JavaReference[] getAllReferences(){ + return myReferences; + } + + private ReferenceType getType(int index){ + if(index != myReferences.length - 1){ + return new ReferenceType(myType, ReferenceType.JAVA_PACKAGE); + } + return myType; + } + + public class JavaReference extends GenericReference{ + private final int myIndex; + private TextRange myRange; + private final String myText; + + public JavaReference(TextRange range, int index, String text){ + super(JavaClassReferenceProvider.this); + myIndex = index; + myRange = range; + myText = text; + } + + public PsiElement getContext(){ + final PsiReference contextRef = getContextReference(); + return contextRef != null ? contextRef.resolve() : null; + } + + public PsiReference getContextReference(){ + return myIndex > 0 ? getReference(myIndex - 1) : null; + } + + public ReferenceType getType(){ + return ReferenceSet.this.getType(myIndex); + } + + public ReferenceType getSoftenType(){ + return new ReferenceType(ReferenceType.JAVA_CLASS, ReferenceType.JAVA_PACKAGE); + } + + public boolean needToCheckAccessibility() { + return false; + } + + public PsiElement getElement(){ + return myElement; + } + + public boolean isReferenceTo(PsiElement element) { + if(element instanceof PsiClass || element instanceof PsiPackage) + return super.isReferenceTo(element); + return false; + } + + public TextRange getRangeInElement(){ + return myRange; + } + + public String getCanonicalText(){ + return myText; + } + + public boolean isSoft(){ + return ReferenceSet.this.isSoft(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException{ + final ElementManipulator manipulator = getManipulator(getElement()); + if(manipulator != null){ + final PsiElement element = manipulator.handleContentChange(getElement(), getRangeInElement(), newElementName); + myRange = new TextRange(getRangeInElement().getStartOffset(), getRangeInElement().getStartOffset() + newElementName.length()); + return element; + } + throw new IncorrectOperationException("Manipulator for this element is not defined"); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException{ + if (isReferenceTo(element)) return getElement(); + + final String qualifiedName; + if (element instanceof PsiClass) { + PsiClass psiClass = (PsiClass)element; + qualifiedName = psiClass.getQualifiedName(); + } + else if (element instanceof PsiPackage) { + PsiPackage psiPackage = (PsiPackage)element; + qualifiedName = psiPackage.getQualifiedName(); + } + else + throw new IncorrectOperationException("Cannot bind to " + element); + + final String newName = qualifiedName; + final TextRange range = new TextRange(getReference(0).getRangeInElement().getStartOffset(), getRangeInElement().getEndOffset()); + final PsiElement finalElement = getManipulator(getElement()).handleContentChange(getElement(), range, newName); + reparse(); + return finalElement; + } + } + + protected boolean isSoft(){ + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/text/BlockSupportImpl.java new file mode 100644 index 00000000000..e4fb456cab3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -0,0 +1,159 @@ +package com.intellij.psi.impl.source.text; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPlainTextFile; +import com.intellij.psi.impl.PsiElementFactoryImpl; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.CodeFragmentElement; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.parsing.tabular.ParsingUtil; +import com.intellij.psi.impl.source.parsing.tabular.grammar.Grammar; +import com.intellij.psi.impl.source.parsing.tabular.grammar.GrammarUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.text.BlockSupport; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +public class BlockSupportImpl extends BlockSupport implements Constants, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.text.BlockSupportImpl"); + + public String getComponentName() { + return "BlockSupport"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public void reparseRange(PsiFile file, int startOffset, int endOffset, String newTextS) throws IncorrectOperationException{ + LOG.assertTrue(file.isValid()); + char[] newText = newTextS.toCharArray(); + int fileLength = file.getTextLength(); + int lengthShift = newText.length - (endOffset - startOffset); + + final PsiFileImpl fileImpl = (PsiFileImpl)file; + final char[] newFileText = lengthShift > 0 ? new char[fileLength + lengthShift] : new char[fileLength]; + SourceUtil.toBuffer(fileImpl.getTreeElement(), newFileText, 0); + + System.arraycopy(newFileText, endOffset, newFileText, endOffset + lengthShift, fileLength - endOffset); + System.arraycopy(newText, 0, newFileText, startOffset, newText.length); + + reparseRange(file, startOffset, endOffset, lengthShift, newFileText); + } + + + public void reparseRange(PsiFile file, int startOffset, int endOffset, int lengthShift, char[] newFileText){ + // adjust editor offsets to damage area markers + if(startOffset > 0) startOffset--; + reparseRangeInternal(file, startOffset, endOffset, lengthShift, newFileText); + } + + public void reparseRangeInternal(PsiFile file, int startOffset, int endOffset, int lengthShift, char[] newFileText){ + final PsiFileImpl fileImpl = (PsiFileImpl)file; + // hack + final int textLength = file.getTextLength() + lengthShift; + + if(fileImpl.getFileType() == StdFileTypes.JSP){ + makeFullParse(fileImpl.getTreeElement(), newFileText, textLength, fileImpl, fileImpl.getFileType()); + return; + } + final FileElement treeFileElement = fileImpl.getTreeElement(); + + final LeafElement leafAtStart = treeFileElement.findLeafElementAt(startOffset); + final LeafElement leafAtEnd = treeFileElement.findLeafElementAt(endOffset); + TreeElement parent = leafAtStart != null && leafAtEnd != null ? TreeUtil.findCommonParent(leafAtStart, leafAtEnd) : treeFileElement; + + int minErrorLevel = Integer.MAX_VALUE; + Reparseable bestReparseable = null; + Reparseable prevReparseable = null; + boolean theOnlyReparseable = false; + while(parent != null && !(parent instanceof FileElement)){ + if(parent instanceof Reparseable){ + final TextRange textRange = parent.getTextRange(); + final Reparseable reparseable = (Reparseable)parent; + boolean lexerChanged = false; + if(prevReparseable != null){ + lexerChanged = prevReparseable.getLexerClass().equals(reparseable.getLexerClass()); + } + + int currentErrorLevel = reparseable.getErrorsCount(newFileText, textRange.getStartOffset(), textRange.getEndOffset(), lengthShift); + if(currentErrorLevel == Reparseable.NO_ERRORS){ + final FileElement treeElement = new DummyHolder(parent.getManager(), null, treeFileElement.getCharTable()).getTreeElement(); + final ChameleonElement chameleon = reparseable.createChameleon(newFileText, textRange.getStartOffset(), textRange.getEndOffset() + lengthShift); + TreeUtil.addChildren(treeElement, chameleon); + ChangeUtil.replaceAllChildren((CompositeElement)parent, chameleon.transform(treeFileElement.getCharTable(), fileImpl.createLexer()).getTreeParent()); + return; + } + else if(currentErrorLevel == Reparseable.FATAL_ERROR){ + prevReparseable = reparseable; + } + else if(Math.abs(currentErrorLevel) < Math.abs(minErrorLevel)){ + theOnlyReparseable = bestReparseable == null; + bestReparseable = reparseable; + minErrorLevel = currentErrorLevel; + if (lexerChanged) break; + } + // invalid content; + } + parent = parent.getTreeParent(); + } + + if(bestReparseable != null && !theOnlyReparseable){ + // best reparseable available + final CompositeElement treeElement = ((CompositeElement)bestReparseable); + final TextRange textRange = treeElement.getTextRange(); + final ChameleonElement chameleon = bestReparseable.createChameleon(newFileText, textRange.getStartOffset(), textRange.getEndOffset() + lengthShift); + chameleon.putUserData(CharTable.CHAR_TABLE_KEY, treeFileElement.getCharTable()); + chameleon.setTreeParent((CompositeElement)parent); + ChangeUtil.replaceAllChildren(treeElement, chameleon.transform(treeFileElement.getCharTable(), fileImpl.createLexer()).getTreeParent()); + } + else{ + // file reparse + FileType fileType = file.getFileType(); + if (file instanceof PsiPlainTextFile){ + fileType = StdFileTypes.PLAIN_TEXT; + } + // + final Grammar grammarByFileType = GrammarUtil.getGrammarByFileType(fileType); + if(grammarByFileType != null){ + ParsingUtil.reparse(grammarByFileType, treeFileElement.getCharTable(), treeFileElement, newFileText, startOffset, endOffset, lengthShift); + } + else{ + makeFullParse(parent, newFileText, textLength, fileImpl, fileType); + } + } + } + + private void makeFullParse(TreeElement parent, + char[] newFileText, + int textLength, + final PsiFileImpl fileImpl, + FileType fileType) { + if(parent instanceof CodeFragmentElement){ + final FileElement holderElement = new DummyHolder(fileImpl.getManager(), null).getTreeElement(); + LeafElement chameleon = Factory.createLeafElement(fileImpl.getContentElementType(), newFileText, 0, textLength, -1, holderElement.getCharTable()); + TreeUtil.addChildren(holderElement, chameleon); + ChangeUtil.replaceAllChildren((CompositeElement)parent, holderElement); + } + else{ + final PsiFileImpl newFile = (PsiFileImpl)PsiElementFactoryImpl.createFileFromText((PsiManagerImpl)fileImpl.getManager(), fileType, fileImpl.getName(), newFileText, 0, textLength); + final CompositeElement newFileElement = newFile.getTreeElement(); + ChangeUtil.replaceAllChildren(fileImpl.getTreeElement(), newFileElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChangeUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChangeUtil.java new file mode 100644 index 00000000000..a914554ceae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChangeUtil.java @@ -0,0 +1,697 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.editor.Document; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiTreeChangeEventImpl; +import com.intellij.psi.impl.PsiDocumentManagerImpl; +import com.intellij.psi.impl.compiled.ClsFileImpl; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.light.LightClassReference; +import com.intellij.psi.impl.light.LightTypeElement; +import com.intellij.psi.impl.source.*; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerEx; +import com.intellij.psi.impl.source.parsing.*; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +public class ChangeUtil implements Constants { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.ChangeUtil"); + + public static void addChild(final CompositeElement parent, final TreeElement child, TreeElement anchorBefore) { + LOG.assertTrue(anchorBefore == null || anchorBefore.getTreeParent() == parent); + + int childLength = child.getTextLength(); + int offset = anchorBefore != null + ? anchorBefore.getStartOffset() + : parent.getStartOffset() + parent.getTextLength(); + + PsiTreeChangeEventImpl event = null; + PsiElement parentPsiElement = SourceTreeToPsiMap.treeElementToPsi(parent); + PsiFile file = parentPsiElement.getContainingFile(); + boolean physical = parentPsiElement.isPhysical(); + if (physical){ + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (file != null){ + manager.invalidateFile(file); + } + event = new PsiTreeChangeEventImpl(manager); + event.setParent(parentPsiElement); + event.setFile(file); + event.setOffset(offset); + event.setOldLength(0); + manager.beforeChildAddition(event); + + RepositoryManager repositoryManager = manager.getRepositoryManager(); + if (repositoryManager != null){ + repositoryManager.beforeChildAddedOrRemoved(file, parent, child); + } + } + + child.setTreeNext(null); + final CharTable newCharTab = SharedImplUtil.findCharTableByTree(parent); + final CharTable oldCharTab = SharedImplUtil.findCharTableByTree(child); + if(newCharTab != oldCharTab) + registerLeafsInCharTab(newCharTab, child, oldCharTab); + if (anchorBefore != null){ + TreeUtil.insertBefore(anchorBefore, child); + } + else{ + TreeUtil.addChildren(parent, child); + } + + //updateCachedLengths(parent, childLength); + parent.subtreeChanged(); + + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (physical){ + event.setChild(SourceTreeToPsiMap.treeElementToPsi(child)); + manager.childAdded(event); + } + else if (manager != null){ + manager.nonPhysicalChange(); + } + + checkConsistency(file); + } + + private static void checkConsistency(PsiFile file) { + if (LOG.isDebugEnabled() && file != null) { + Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); + if (document != null) { + PsiDocumentManagerImpl.checkConsistency(file, document); + } + } + } + + public static void registerLeafsInCharTab(CharTable newCharTab, TreeElement child, CharTable oldCharTab) { + if(newCharTab == oldCharTab) return; + while(child != null){ + CharTable charTable = child.getUserData(CharTable.CHAR_TABLE_KEY); + if (child instanceof LeafElement) { + ((LeafElement)child).registerInCharTable(newCharTab, oldCharTab); + } + else { + registerLeafsInCharTab(newCharTab, ((CompositeElement)child).firstChild, charTable != null ? charTable : oldCharTab); + } + if (charTable != null) { + child.putUserData(CharTable.CHAR_TABLE_KEY, null); + } + child = child.getTreeNext(); + } + } + + public static void removeChild(final CompositeElement parent, final TreeElement child) { + LOG.assertTrue(child.getTreeParent() == parent); + + int offset = child.getStartOffset(); + int childLength = child.getTextLength(); + + PsiTreeChangeEventImpl event = null; + PsiElement parentPsiElement = SourceTreeToPsiMap.treeElementToPsi(parent); + PsiFile file = parentPsiElement.getContainingFile(); + boolean physical = parentPsiElement.isPhysical(); + if (physical){ + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (file != null){ + manager.invalidateFile(file); + } + event = new PsiTreeChangeEventImpl(manager); + event.setParent(parentPsiElement); + event.setChild(SourceTreeToPsiMap.treeElementToPsi(child)); + event.setFile(file); + event.setOffset(offset); + event.setOldLength(childLength); + manager.beforeChildRemoval(event); + + RepositoryManager repositoryManager = manager.getRepositoryManager(); + if (repositoryManager != null){ + repositoryManager.beforeChildAddedOrRemoved(file, parent, child); + } + } + + child.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(child)); + TreeUtil.remove(child); + + parent.subtreeChanged(); + //updateCachedLengths(parent, -childLength); + + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (physical){ + manager.childRemoved(event); + } + else if (manager != null){ + manager.nonPhysicalChange(); + } + checkConsistency(file); + } + + public static void replaceChild(final CompositeElement parent, final TreeElement oldChild, final TreeElement newChild) { + if (oldChild.getTreeParent() != parent){ + LOG.assertTrue(oldChild.getTreeParent() == parent); + } + + int offset = oldChild.getStartOffset(); + int oldLength = oldChild.getTextLength(); + int newLength = newChild.getTextLength(); + final CharTable newCharTable = SharedImplUtil.findCharTableByTree(parent); + final CharTable oldCharTable = SharedImplUtil.findCharTableByTree(newChild); + + PsiTreeChangeEventImpl event = null; + PsiElement parentPsiElement = SourceTreeToPsiMap.treeElementToPsi(parent); + PsiFile file = parentPsiElement.getContainingFile(); + boolean physical = parentPsiElement.isPhysical(); + if (physical){ + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (file != null){ + manager.invalidateFile(file); + } + event = new PsiTreeChangeEventImpl(manager); + event.setParent(parentPsiElement); + event.setOldChild(SourceTreeToPsiMap.treeElementToPsi(oldChild)); + event.setFile(file); + event.setOffset(offset); + event.setOldLength(oldLength); + manager.beforeChildReplacement(event); + + RepositoryManager repositoryManager = manager.getRepositoryManager(); + if (repositoryManager != null){ + repositoryManager.beforeChildAddedOrRemoved(file, parent, oldChild); + repositoryManager.beforeChildAddedOrRemoved(file, parent, newChild); + } + } + + newChild.setTreeNext(null); + if(oldCharTable != newCharTable){ + registerLeafsInCharTab(newCharTable, newChild, oldCharTable); + } + oldChild.putUserData(CharTable.CHAR_TABLE_KEY, newCharTable); + if(oldChild != newChild) TreeUtil.replace(oldChild, newChild); + + parent.subtreeChanged(); + //updateCachedLengths(parent, newLength - oldLength); + + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (physical){ + event.setNewChild(SourceTreeToPsiMap.treeElementToPsi(newChild)); + manager.childReplaced(event); + } + else if (manager != null){ + manager.nonPhysicalChange(); + } + checkConsistency(file); + } + + public static void replaceAllChildren(final CompositeElement parent, final CompositeElement newChildrenParent) { + int offset = parent.getStartOffset(); + int oldLength = parent.getTextLength(); + int newLength = newChildrenParent.getTextLength(); + + PsiTreeChangeEventImpl event = null; + PsiElement parentPsiElement = SourceTreeToPsiMap.treeElementToPsi(parent); + boolean physical = parentPsiElement.isPhysical(); + PsiFile file = parentPsiElement.getContainingFile(); + ChameleonTransforming.transformChildren(newChildrenParent); + final TreeElement firstChild = newChildrenParent.firstChild; + if (physical){ + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + manager.invalidateFile(file); + event = new PsiTreeChangeEventImpl(manager); + event.setParent(parentPsiElement); + event.setFile(file); + event.setOffset(offset); + event.setOldLength(oldLength); + manager.beforeChildrenChange(event); + + VirtualFile vFile = file.getVirtualFile(); + if (vFile != null){ + RepositoryManager repositoryManager = manager.getRepositoryManager(); + if (repositoryManager != null){ + ChameleonTransforming.transformChildren(parent); + for(TreeElement child = parent.firstChild; child != null; child = child.getTreeNext()){ + repositoryManager.beforeChildAddedOrRemoved(file, parent, child); + } + + for(TreeElement child = firstChild; child != null; child = child.getTreeNext()){ + repositoryManager.beforeChildAddedOrRemoved(file, parent, child); + } + } + } + } + final CharTable newCharTab = SharedImplUtil.findCharTableByTree(parent); + TreeElement oldChild = parent.firstChild; + while(oldChild != null){ + oldChild.putUserData(CharTable.CHAR_TABLE_KEY, newCharTab); + oldChild = oldChild.getTreeNext(); + } + TreeUtil.removeRange(parent.firstChild, null); + + if (firstChild != null){ + final CharTable oldCharTab = SharedImplUtil.findCharTableByTree(newChildrenParent); + registerLeafsInCharTab(newCharTab, firstChild, oldCharTab); + TreeUtil.addChildren(parent, firstChild); + } + parent.setCachedLength(newLength); + parent.subtreeChanged(); + //if (parent.getTreeParent() != null){ + // updateCachedLengths(parent.getTreeParent(), newLength - oldLength); + //} + + PsiManagerImpl manager = (PsiManagerImpl)parent.getManager(); + if (physical){ + manager.childrenChanged(event); + } + else if (manager != null){ + manager.nonPhysicalChange(); + } + checkConsistency(file); + } + + public static void encodeInformation(TreeElement element) { + encodeInformation(element, element); + } + + private static void encodeInformation(TreeElement element, TreeElement original) { + boolean encodeRefTargets = true; + if (original.getTreeParent() instanceof DummyHolderElement){ + DummyHolder dummyHolder = (DummyHolder)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent()); + if (dummyHolder.getContext() == null && !dummyHolder.hasImports()){ // optimization + encodeRefTargets = false; + } + } + _encodeInformation(element, original, encodeRefTargets); + } + + private static void _encodeInformation(TreeElement element, TreeElement original, boolean encodeRefTargets) { + if (original instanceof CompositeElement){ + if (original.getElementType() == ElementType.JAVA_CODE_REFERENCE || original.getElementType() == ElementType.REFERENCE_EXPRESSION){ + if (encodeRefTargets){ + encodeInformationInRef(element, original); + } + } + else if (original.getElementType() == ElementType.MODIFIER_LIST){ + if ((original.getTreeParent().getElementType() == ElementType.FIELD || original.getTreeParent().getElementType() == ElementType.METHOD) + && original.getTreeParent().getTreeParent().getElementType() == ElementType.CLASS && + ((PsiClass)SourceTreeToPsiMap.treeElementToPsi(original.getTreeParent().getTreeParent())).isInterface()){ + element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, Boolean.TRUE); + } + } + + ChameleonTransforming.transformChildren((CompositeElement)element); + ChameleonTransforming.transformChildren((CompositeElement)original); + TreeElement child = ((CompositeElement)element).firstChild; + TreeElement child1 = ((CompositeElement)original).firstChild; + while(child != null){ + _encodeInformation(child, child1, encodeRefTargets); + child = child.getTreeNext(); + child1 = child1.getTreeNext(); + } + } + } + + private static void encodeInformationInRef(TreeElement ref, TreeElement original) { + if (original.getElementType() == REFERENCE_EXPRESSION){ + if (original.getTreeParent().getElementType() != REFERENCE_EXPRESSION) return; // cannot refer to class (optimization) + PsiElement target = ((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(original)).resolve(); + if (target instanceof PsiClass){ + ref.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)target); + } + } + else if (original.getElementType() == JAVA_CODE_REFERENCE){ + switch(((PsiJavaCodeReferenceElementImpl)original).getKind()){ + case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND: + { + final PsiElement target = ((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(original)).resolve(); + if (target instanceof PsiClass){ + ref.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)target); + } + } + break; + + case PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND: + break; + + default: + LOG.assertTrue(false); + } + } + else{ + LOG.assertTrue(false, "Wrong element type: " + original.getElementType()); + return; + } + } + + public static TreeElement decodeInformation(TreeElement element) { + if (element instanceof CompositeElement){ + ChameleonTransforming.transformChildren((CompositeElement)element); + TreeElement child = ((CompositeElement)element).firstChild; + while(child != null){ + child = decodeInformation(child); + child = child.getTreeNext(); + } + + if (element.getElementType() == ElementType.JAVA_CODE_REFERENCE || element.getElementType() == ElementType.REFERENCE_EXPRESSION){ + PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(element); + final PsiClass refClass = element.getCopyableUserData(REFERENCED_CLASS_KEY); + if (refClass != null){ + element.putCopyableUserData(REFERENCED_CLASS_KEY, null); + + if (refClass.isPhysical() || !ref.isPhysical()){ //? + PsiManager manager = refClass.getManager(); + CodeStyleManagerEx codeStyleManager = (CodeStyleManagerEx)manager.getCodeStyleManager(); + PsiElement refElement1 = ref.resolve(); + try{ + if (refClass != refElement1 && !manager.areElementsEquivalent(refClass, refElement1)){ + if (((CompositeElement)element).findChildByRole(ChildRole.QUALIFIER) == null){ // can restore only if short (otherwise qualifier should be already restored) + ref = (PsiJavaCodeReferenceElement)ref.bindToElement(refClass); + } + } + else{ + // shorten references to the same package and to inner classes that can be accessed by short name + ref = (PsiJavaCodeReferenceElement)codeStyleManager.shortenClassReferences(ref, CodeStyleManagerEx.DO_NOT_ADD_IMPORTS); + } + element = SourceTreeToPsiMap.psiElementToTree(ref); + } + catch(IncorrectOperationException e){ + codeStyleManager.addImport(ref.getContainingFile(), refClass); // it may fail for local class, let's try for DummyHolder + } + } + } + } + else if (element.getElementType() == ElementType.MODIFIER_LIST){ + if (element.getUserData(INTERFACE_MODIFIERS_FLAG_KEY) != null){ + element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, null); + try{ + PsiModifierList modifierList = (PsiModifierList)SourceTreeToPsiMap.treeElementToPsi(element); + if (element.getTreeParent().getElementType() == ElementType.FIELD){ + modifierList.setModifierProperty(PsiModifier.PUBLIC, true); + modifierList.setModifierProperty(PsiModifier.STATIC, true); + modifierList.setModifierProperty(PsiModifier.FINAL, true); + } + else if (element.getTreeParent().getElementType() == ElementType.METHOD){ + modifierList.setModifierProperty(PsiModifier.PUBLIC, true); + modifierList.setModifierProperty(PsiModifier.ABSTRACT, true); + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + } + } + return element; + } + + public static TreeElement copyElement(TreeElement original, CharTable table) { + final TreeElement element = (TreeElement)original.clone(); + final PsiManager manager = original.getManager(); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(original); + registerLeafsInCharTab(table, element, charTableByTree); + new DummyHolder(manager, element, null, table).getTreeElement(); + encodeInformation(element, original); +// CodeEditUtil.normalizeCloneIndent(element, original, table); + CodeEditUtil.unindentSubtree(element, original, table); + return element; + } + + public static TreeElement copyToElement(PsiElement original) { + final DummyHolder holder = new DummyHolder(original.getManager(), null); + final FileElement holderElement = holder.getTreeElement(); + final TreeElement treeElement = _copyToElement(original, holderElement.getCharTable()); +// TreeElement treePrev = treeElement.getTreePrev(); // This is hack to support bug used in formater + TreeUtil.addChildren(holderElement, treeElement); +// treeElement.setTreePrev(treePrev); + return treeElement; + } + + private static TreeElement _copyToElement(PsiElement original, CharTable table) { + LOG.assertTrue(original.isValid()); + if (SourceTreeToPsiMap.hasTreeElement(original)){ + return copyElement(SourceTreeToPsiMap.psiElementToTree(original), table); + } + else if (original instanceof PsiIdentifier){ + final String text = original.getText(); + return Factory.createLeafElement(IDENTIFIER, text.toCharArray(), 0, text.length(), -1, table); + } + else if (original instanceof PsiKeyword){ + final String text = original.getText(); + return Factory.createLeafElement(((PsiKeyword)original).getTokenType(), text.toCharArray(), 0, text.length(), -1, table); + } + else if (original instanceof PsiReferenceExpression){ + TreeElement element = createReferenceExpression(original.getManager(), original.getText(), table); + PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve(); + if (refElement instanceof PsiClass){ + element.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)refElement); + } + return element; + } + else if (original instanceof PsiJavaCodeReferenceElement){ + PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve(); + if (refElement instanceof PsiClass){ + if (refElement instanceof PsiAnonymousClass){ + PsiJavaCodeReferenceElement ref = ((PsiAnonymousClass)refElement).getBaseClassReference(); + original = ref; + refElement = ref.resolve(); + } + + boolean isFQ = false; + if (original instanceof PsiJavaCodeReferenceElementImpl){ + int kind = ((PsiJavaCodeReferenceElementImpl)original).getKind(); + switch(kind){ + case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND: + isFQ = false; + break; + + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_NAME_KIND: + case PsiJavaCodeReferenceElementImpl.CLASS_FQ_OR_PACKAGE_NAME_KIND: + isFQ = true; + break; + + default: + LOG.assertTrue(false); + } + } + + String text = isFQ ? ((PsiClass)refElement).getQualifiedName() : original.getText(); + TreeElement element = createReference(original.getManager(), text, table); + element.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)refElement); + return element; + } + else if (refElement instanceof PsiPackage){ + return createReference(original.getManager(), original.getText(), table); + } + else{ + return createReference(original.getManager(), original.getText(), table); + } + } + else if (original instanceof PsiCompiledElement){ + PsiElement sourceVersion = original.getNavigationElement(); + if (sourceVersion != original){ + return _copyToElement(sourceVersion, table); + } + TreeElement mirror = SourceTreeToPsiMap.psiElementToTree(((PsiCompiledElement)original).getMirror()); + return _copyToElement(SourceTreeToPsiMap.treeElementToPsi(mirror), table); + } + else if (original instanceof PsiTypeElement){ + PsiTypeElement typeElement = (PsiTypeElement)original; + PsiType type = typeElement.getType(); + if (type instanceof PsiEllipsisType) { + TreeElement componentTypeCopy = _copyToElement( + new LightTypeElement(original.getManager(), ((PsiEllipsisType)type).getComponentType()), + table + ); + if (componentTypeCopy == null) return null; + CompositeElement element = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(element, componentTypeCopy); + TreeUtil.addChildren(element, Factory.createLeafElement(ELLIPSIS, new char[]{'.', '.', '.'}, 0, 3, -1, table)); + return element; + } + else if (type instanceof PsiArrayType){ + TreeElement componentTypeCopy = _copyToElement( + new LightTypeElement(original.getManager(), ((PsiArrayType)type).getComponentType()), + table + ); + if (componentTypeCopy == null) return null; + CompositeElement element = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(element, componentTypeCopy); + TreeUtil.addChildren(element, Factory.createLeafElement(LBRACKET, new char[]{'['}, 0, 1, -1, table)); + TreeUtil.addChildren(element, Factory.createLeafElement(RBRACKET, new char[]{']'}, 0, 1, -1, table)); + return element; + } + else if (type instanceof PsiPrimitiveType){ + String text = typeElement.getText(); + if (text.equals("null")) return null; + Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3); + lexer.start(text.toCharArray()); + TreeElement keyword = ParseUtil.createTokenElement(lexer, table); + CompositeElement element = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(element, keyword); + return element; + } else if (type instanceof PsiWildcardType) { + char[] buffer = original.getText().toCharArray(); + return DeclarationParsing.parseTypeText(original.getManager(), buffer, 0, buffer.length, table); + } else { + final PsiJavaCodeReferenceElement ref; + if (type instanceof PsiClassReferenceType){ + PsiClassReferenceType refType = (PsiClassReferenceType)type; + ref = refType.getReference(); + } else if (type instanceof PsiImmediateClassType) { + final PsiImmediateClassType classType = (PsiImmediateClassType) type; + final CompositeElement reference = createReference(original.getManager(), classType.getPresentableText(), table); + final CompositeElement immediateTypeElement = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(immediateTypeElement, reference); + encodeInfoInTypeElement(immediateTypeElement, classType); + return immediateTypeElement; + } + else{ + String text = original.getText(); + ref = new LightClassReference(original.getManager(), text, type.getCanonicalText(), original); + } + CompositeElement element = Factory.createCompositeElement(TYPE); + TreeUtil.addChildren(element, _copyToElement(ref, table)); + return element; + } + } + else{ + LOG.error("ChangeUtil.copyToElement() unknown element " + original); + return null; + } + } + + private static CompositeElement createReference(PsiManager manager, String text, CharTable table){ + return Parsing.parseJavaCodeReferenceText(manager, text.toCharArray(), table); + } + + private static TreeElement createReferenceExpression(PsiManager manager, String text, CharTable table) { + return ExpressionParsing.parseExpressionText(manager, text.toCharArray(), 0, text.toCharArray().length, table); + } + + + private static void encodeInfoInTypeElement(CompositeElement typeElement, PsiType type) { + if (type instanceof PsiPrimitiveType) return; + LOG.assertTrue(typeElement.getElementType() == TYPE); + if (type instanceof PsiArrayType) { + final TreeElement firstChild = typeElement.firstChild; + LOG.assertTrue(firstChild.getElementType() == TYPE); + encodeInfoInTypeElement((CompositeElement) firstChild, ((PsiArrayType) type).getComponentType()); + return; + } + else if (type instanceof PsiWildcardType) { + final PsiType bound = ((PsiWildcardType)type).getBound(); + if (bound == null) return; + final TreeElement lastChild = typeElement.lastChild; + if (lastChild.getElementType() != TYPE) return; + encodeInfoInTypeElement((CompositeElement)lastChild, bound); + } + else if (type instanceof PsiCapturedWildcardType) { + final PsiType bound = ((PsiCapturedWildcardType)type).getWildcard().getBound(); + if (bound == null) return; + final TreeElement lastChild = typeElement.lastChild; + if (lastChild.getElementType() != TYPE) return; + encodeInfoInTypeElement((CompositeElement)lastChild, bound); + } + else if (type instanceof PsiIntersectionType) { + encodeInfoInTypeElement(typeElement, ((PsiIntersectionType)type).getRepresentative()); + return; + } + else { + LOG.assertTrue(type instanceof PsiClassType); + final PsiClassType classType = (PsiClassType) type; + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass referencedClass = resolveResult.getElement(); + if (referencedClass == null) return; + final TreeElement reference = typeElement.firstChild; + LOG.assertTrue(reference.getElementType() == JAVA_CODE_REFERENCE); + + encodeClassTypeInfoInReference((CompositeElement) reference, resolveResult.getElement(), resolveResult.getSubstitutor()); + } + } + + private static void encodeClassTypeInfoInReference(CompositeElement reference, PsiClass referencedClass, PsiSubstitutor substitutor) { + LOG.assertTrue(referencedClass != null); + reference.putCopyableUserData(REFERENCED_CLASS_KEY, referencedClass); + + final PsiTypeParameterList typeParameterList = referencedClass.getTypeParameterList(); + if (typeParameterList == null) return; + final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + if (typeParameters.length == 0) return; + + final CompositeElement referenceParameterList = (CompositeElement) reference.findChildByRole(ChildRole.REFERENCE_PARAMETER_LIST); + int index = 0; + for (TreeElement child = referenceParameterList.firstChild; child != null; child = child.getTreeNext()) { + if (child.getElementType() == TYPE) { + final PsiType substitutedType = substitutor.substitute(typeParameters[index]); + if (substitutedType != null) { + encodeInfoInTypeElement((CompositeElement) child, substitutedType); + } + index++; + } + } + + final TreeElement qualifier = reference.findChildByRole(ChildRole.QUALIFIER); + if (qualifier != null) { + if (referencedClass.hasModifierProperty(PsiModifier.STATIC)) return; + final PsiClass outerClass = referencedClass.getContainingClass(); + if (outerClass != null) { + encodeClassTypeInfoInReference((CompositeElement) qualifier, outerClass, substitutor); + } + } + } + + private static final Key REFERENCED_CLASS_KEY = Key.create("REFERENCED_CLASS_KEY"); + private static final Key INTERFACE_MODIFIERS_FLAG_KEY = Key.create("INTERFACE_MODIFIERS_FLAG_KEY"); + + public static void addChildren(final CompositeElement parent, + TreeElement firstChild, + final TreeElement lastChild, + final TreeElement anchorBefore) { + while(firstChild != lastChild){ + final TreeElement next = firstChild.getTreeNext(); + addChild(parent, firstChild, anchorBefore); + firstChild = next; + } + } + + public static void replaceAll(LeafElement[] leafElements, LeafElement merged) { + if(leafElements.length == 0) return; + final CompositeElement parent = leafElements[0].getTreeParent(); + if(LOG.isDebugEnabled()){ + for (int i = 0; i < leafElements.length; i++) { + final LeafElement leafElement = leafElements[i]; + LOG.assertTrue(leafElement.getTreeParent() == parent); + } + } + + final PsiElement psiParent = SourceTreeToPsiMap.treeElementToPsi(parent); + final PsiFile containingFile = psiParent.getContainingFile(); + final PsiManagerImpl manager = (PsiManagerImpl)containingFile.getManager(); + final PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); + if(containingFile.isPhysical()){ + event.setParent(psiParent); + event.setFile(containingFile); + event.setOffset(parent.getStartOffset()); + event.setOldLength(parent.getTextLength()); + manager.beforeChildrenChange(event); + } + TreeUtil.insertAfter(leafElements[0], merged); + for (int i = 0; i < leafElements.length; i++) TreeUtil.remove(leafElements[i]); + + parent.subtreeChanged(); + if(containingFile.isPhysical()) manager.childrenChanged(event); + checkConsistency(containingFile); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChildRole.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChildRole.java new file mode 100644 index 00000000000..0d422d260c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ChildRole.java @@ -0,0 +1,230 @@ +package com.intellij.psi.impl.source.tree; + +public class ChildRole { + public static final int NONE = 0; + public static final int PACKAGE_STATEMENT = 1; // in FILE + public static final int IMPORT_LIST = 2; // in FILE + public static final int CLASS = 3; // in FILE, CLASS + public static final int FIELD = 4; // in CLASS + public static final int METHOD = 5; // in CLASS + public static final int CLASS_INITIALIZER = 6; // in CLASS + public static final int DOC_COMMENT = 7; // in CLASS, FIELD, METHOD + public static final int MODIFIER_LIST = 8; // in CLASS, FIELD, METHOD, CLASS_INITIALIZER, PARAMETER, LOCAL_VARIABLE + public static final int NAME = 9; // in CLASS, FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, NAME_VALUE_PAIR + public static final int TYPE = 10; // in FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_CAST_EXPRESSION, INSTANCEOF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION + public static final int CLASS_OR_INTERFACE_KEYWORD = 11; // in CLASS + public static final int EXTENDS_LIST = 12; // in CLASS + public static final int IMPLEMENTS_LIST = 13; // in CLASS + public static final int PARAMETER_LIST = 14; // in METHOD, ANNOTATION + public static final int PARAMETER = 15; // in PARAMETER_LIST, CATCH_SECTION + public static final int THROWS_LIST = 16; // in METHOD + public static final int METHOD_BODY = 17; // in METHOD, CLASS_INITIALIZER + public static final int LBRACE = 18; // in CLASS, CODE_BLOCK, ARRAY_INITIALIZER_EXPRESSION + public static final int RBRACE = 19; // in CLASS, CODE_BLOCK, ARRAY_INITIALIZER_EXPRESSION + public static final int INITIALIZER_EQ = 20; // in FIELD, LOCAL_VARIABLE + public static final int INITIALIZER = 21; // in FIELD, LOCAL_VARIABLE + public static final int CLOSING_SEMICOLON = 22; // in FIELD, METHOD, LOCAL_VARIABLE, DO_WHILE_STATEMENT, + // THROW_STATEMENT, RETURN_STATEMENT, BREAK_STATEMENT, CONTINUE_STATEMENT, + // EXPRESSION_LIST_STATEMENT, EXPRESSION_STATEMENT, PACKAGE_STATEMENT, + // IMPORT_STATEMENT, ASSERT_STATEMENT + public static final int COMMA = 23; // in PARAMETER_LIST, EXTENDS_LIST, IMPLEMENTS_LIST, THROWS_LIST, EXPRESSION_LIST, ARRAY_INITIALIZER_EXPRESSION, JSP_IMPORT_VALUE, DECLARATION_STATEMENT + public static final int LPARENTH = 24; // in PARAMETER_LIST, IF_STATEMENT, FOR_STATEMENT, WHILE_STATEMENT, DO_WHILE_STATEMENT, SWITCH_STATEMENT, PARENTHESIZED_EXPRESSION, TYPE_CAST_EXPRESSION, SYNCHRONIZED_STATEMENT + public static final int RPARENTH = 25; // in PARAMETER_LIST, IF_STATEMENT, FOR_STATEMENT, WHILE_STATEMENT, DO_WHILE_STATEMENT, SWITCH_STATEMENT, PARENTHESIZED_EXPRESSION, TYPE_CAST_EXPRESSION, SYNCHRONIZED_STATEMENT + public static final int EXTENDS_KEYWORD = 26; // in EXTENDS_LIST + public static final int IMPLEMENTS_KEYWORD = 27; // in IMPLEMENTS_LIST + public static final int THROWS_KEYWORD = 28; // in THROWS_LIST + public static final int REFERENCE_IN_LIST = 29; // in EXTENDS_LIST, IMPLEMENTS_LIST, THROWS_LIST + public static final int IF_KEYWORD = 30; // in IF_STATEMENT + public static final int ELSE_KEYWORD = 31; // in IF_STATEMENT + public static final int CONDITION = 32; // in IF_STATEMENT, WHILE_STATEMENT, DO_WHILE_STATEMENT, FOR_STATEMENT, CONDITIONAL_EXPRESSION, ASSERT_STATEMENT + public static final int THEN_BRANCH = 33; // in IF_STATEMENT + public static final int ELSE_BRANCH = 34; // in IF_STATEMENT + public static final int WHILE_KEYWORD = 35; // in WHILE_STATEMENT, DO_WHILE_STATEMENT + public static final int DO_KEYWORD = 36; // in DO_WHILE_STATEMENT + public static final int FOR_KEYWORD = 37; // in FOR_STATEMENT, FOREACH_STATEMENT + public static final int LOOP_BODY = 38; // in WHILE_STATEMENT, DO_WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT + public static final int FOR_INITIALIZATION = 39; // in FOR_STATEMENT + public static final int FOR_UPDATE = 40; // in FOR_STATEMENT + public static final int FOR_SEMICOLON = 41; // in FOR_STATEMENT + public static final int SWITCH_KEYWORD = 42; // in SWITCH_STATEMENT + public static final int SWITCH_EXPRESSION = 43; // in SWITCH_STATEMENT + public static final int SWITCH_BODY = 44; // in SWITCH_STATEMENT + public static final int TRY_KEYWORD = 45; // in TRY_STATEMENT + public static final int CATCH_KEYWORD = 46; // in CATCH_SECTION + public static final int FINALLY_KEYWORD = 47; // in TRY_STATEMENT + public static final int TRY_BLOCK = 48; // in TRY_STATEMENT + public static final int CATCH_BLOCK = 49; // in CATCH_SECTION + public static final int CATCH_BLOCK_PARAMETER_LPARENTH = 50; // in CATCH_SECTION + public static final int CATCH_BLOCK_PARAMETER_RPARENTH = 51; // in CATCH_SECTION + public static final int FINALLY_BLOCK = 52; // in TRY_STATEMENT + public static final int REFERENCE_NAME = 53; // in JAVA_CODE_REFERENCE, REFERENCE_EXPRESSION + public static final int QUALIFIER = 54; // in JAVA_CODE_REFERENCE, REFERENCE_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, NEW_EXPRESSION + public static final int DOT = 55; // in JAVA_CODE_REFERENCE, REFERENCE_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, NEW_EXPRESSION + public static final int STATEMENT_IN_BLOCK = 56; // in CODE_BLOCK, JSP_FILE + public static final int THROW_KEYWORD = 57; // in THROW_STATEMENT + public static final int EXCEPTION = 58; // in THROW_STATEMENT + public static final int EXPRESSION_IN_LIST = 59; // in EXPRESSION_LIST. ARRAY_INITIALIZER_EXPRESSION + public static final int BLOCK = 60; // in BLOCK_STATEMENT, SYNCHRONIZED_STATEMENT, CATCH_SECTION + public static final int LOPERAND = 61; // in ASSIGNMENT_EXPRESSION, BINARY_EXPRESSION + public static final int ROPERAND = 62; // in ASSIGNMENT_EXPRESSION, BINARY_EXPRESSION + public static final int OPERATION_SIGN = 63; // in ASSIGNMENT_EXPRESSION, BINARY_EXPRESSION + public static final int EXPRESSION = 64; // in EXPRESSION_STATEMENT, PARENTHESIZED_EXPRESSION + public static final int RETURN_KEYWORD = 65; // in RETURN_STATEMENT + public static final int RETURN_VALUE = 66; // in RETURN_STATEMENT + public static final int OPERAND = 67; // in /*PREFIX_EXPRESSION, POSTFIX_EXPRESSION*/, TYPE_CAST_EXPRESSION, INSTANCEOF_EXPRESSION + public static final int INSTANCEOF_KEYWORD = 68; // in INSTANCEOF_EXPRESSION + public static final int NEW_KEYWORD = 69; // in NEW_EXPRESSION + public static final int ANONYMOUS_CLASS = 70; // in NEW_EXPRESSION + public static final int TYPE_REFERENCE = 71; // in NEW_EXPRESSION + public static final int TYPE_KEYWORD = 72; // in NEW_EXPRESSION, TYPE + public static final int ARGUMENT_LIST = 73; // in METHOD_CALL_EXPRESSION, NEW_EXPRESSION, ANONYMOUS_CLASS + public static final int LBRACKET = 74; // in NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, TYPE + public static final int RBRACKET = 75; // in NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, TYPE + public static final int ARRAY_DIMENSION = 76; // in NEW_EXPRESSION + public static final int ARRAY_INITIALIZER = 77; // in NEW_EXPRESSION + public static final int BASE_CLASS_REFERENCE = 78; // in ANONYMOUS_CLASS + public static final int SYNCHRONIZED_KEYWORD = 79; // in SYNCHRONIZED_STATEMENT + public static final int LOCK = 80; // in SYNCHRONIZED_STATEMENT + public static final int BREAK_KEYWORD = 81; // in BREAK_STATEMENT + public static final int CONTINUE_KEYWORD = 82; // in CONTINUE_STATEMENT + public static final int LABEL = 83; // in BREAK_STATEMENT, CONTINUE_STATEMENT + public static final int CASE_KEYWORD = 84; // in SWITCH_LABEL_STATEMENT + public static final int DEFAULT_KEYWORD = 85; // in SWITCH_LABEL_STATEMENT + public static final int CASE_EXPRESSION = 86; // in SWITCH_LABEL_STATEMENT + public static final int COLON = 87; // in SWITCH_LABEL_STATEMENT, LABELED_STATEMENT, CONDITIONAL_EXPRESSION, ASSERT_STATEMENT + public static final int ARRAY = 88; // in ARRAY_ACCESS_EXPRESSION + public static final int INDEX = 89; // in ARRAY_ACCESS_EXPRESSION + public static final int CLASS_KEYWORD = 90; // in CLASS_OBJECT_ACCESS_EXPRESSION + public static final int METHOD_EXPRESSION = 91; // in METHOD_CALL_EXPRESSION + public static final int EXPRESSION_LIST = 92; // in EXPRESSION_LIST_STATEMENT + public static final int LABEL_NAME = 93; // in LABELED_STATEMENT + public static final int STATEMENT = 94; // in LABELED_STATEMENT + public static final int THIS_KEYWORD = 95; // in THIS_EXPRESSION + public static final int SUPER_KEYWORD = 96; // in SUPER_EXPRESSION + public static final int DECLARED_ELEMENT = 97; // in /*DECLARATION_STATEMENT*/, JSP_DECLARATION + public static final int IMPORT_KEYWORD = 98; // in IMPORT_STATEMENT + public static final int IMPORT_REFERENCE = 99; // in IMPORT_STATEMENT + public static final int IMPORT_ON_DEMAND_DOT = 100; // in IMPORT_STATEMENT + public static final int IMPORT_ON_DEMAND_ASTERISK = 101; // in IMPORT_STATEMENT + public static final int PACKAGE_KEYWORD = 102; // in PACKAGE_STATEMENT + public static final int PACKAGE_REFERENCE = 103; // in PACKAGE_STATEMENT + public static final int DOC_TAG = 104; // in DOC_COMMENT + public static final int DOC_TAG_NAME = 105; // in DOC_TAG, DOC_INLINE_TAG + public static final int DOC_CONTENT = 106; // in DOC_COMMENT, DOC_TAG, DOC_INLINE_TAG + public static final int DOC_COMMENT_ASTERISKS = 107; // in DOC_COMMENT, DOC_TAG + public static final int DOC_INLINE_TAG_START = 108; // in DOC_INLINE_TAG + public static final int DOC_INLINE_TAG_END = 109; // in DOC_INLINE_TAG + public static final int DOC_COMMENT_START = 110; // in DOC_COMMENT + public static final int DOC_COMMENT_END = 111; // in DOC_COMMENT + public static final int THEN_EXPRESSION = 112; // in CONDITIONAL_EXPRESSION + public static final int ELSE_EXPRESSION = 113; // in CONDITIONAL_EXPRESSION + public static final int QUEST = 114; // in CONDITIONAL_EXPRESSION + public static final int PRECEDING_COMMENT = 115; // in FIELD, METHOD, CLASS, CLASS_INITIALIZER + public static final int ASSERT_KEYWORD = 116; // in ASSERT_STATEMENT + public static final int ASSERT_DESCRIPTION = 117; // in ASSERT_DESCRIPTION + public static final int COMPONENT_TYPE = 118; // in TYPE + public static final int CLASS_REFERENCE = 119; // in TYPE, ANNOTATION + public static final int TYPE_IN_REFERENCE_PARAMETER_LIST = 120; // in REFERENCE_PARAMETER_LIST + public static final int LT_IN_TYPE_LIST = 121; + public static final int GT_IN_TYPE_LIST = 122; + public static final int AMPERSAND_IN_BOUNDS_LIST = 123; + + public static final int FOR_ITERATED_VALUE = 124; // in FOREACH_STATEMENT + public static final int FOR_ITERATION_PARAMETER = 125; // in FOREACH_STATEMENT + + public static final int ENUM_CONSTANT_LIST_DELIMITER = 126; // in CLASS + public static final int ENUM_CONSTANT_DELIMITER = 127; // in CLASS + + + public static final int JSP_DIRECTIVE_START = 200; // in JSP_DIRECTIVE + public static final int JSP_DIRECTIVE_END = 201; // in JSP_DIRECTIVE + public static final int JSP_DIRECTIVE_NAME = 202; // in JSP_DIRECTIVE + public static final int JSP_DIRECTIVE_ATTRIBUTE = 203; // in JSP_DIRECTIVE + public static final int JSP_ACTION_START = 204; // in JSP_ACTION + public static final int JSP_ACTION_END = 205; // in JSP_ACTION + public static final int JSP_ACTION_NAME = 206; // in JSP_ACTION + public static final int JSP_ACTION_ATTRIBUTE = 207; // in JSP_ACTION + public static final int JSP_ATTRIBUTE_NAME = 208; // in JSP_DIRECTIVE_ATTRIBUTE, JSP_ACTION_ATTRIBUTE + public static final int JSP_ATTRIBUTE_EQ = 209; // in JSP_DIRECTIVE_ATTRIBUTE, JSP_ACTION_ATTRIBUTE + public static final int JSP_ATTRIBUTE_VALUE_START_DELIMITER = 210; // in JSP_DIRECTIVE_ATTRIBUTE, JSP_ACTION_ATTRIBUTE + public static final int JSP_ATTRIBUTE_VALUE_END_DELIMITER = 211; // in JSP_DIRECTIVE_ATTRIBUTE, JSP_ACTION_ATTRIBUTE + public static final int JSP_ATTRIBUTE_VALUE = 212; // in JSP_DIRECTIVE_ATTRIBUTE, JSP_ACTION_ATTRIBUTE + public static final int JSP_IMPORT_REFERENCE = 213; // in JSP_IMPORT_VALUE + public static final int JSP_IMPORT_ON_DEMAND_DOT = 214; // in JSP_IMPORT_VALUE + public static final int JSP_IMPORT_ON_DEMAND_ASTERISK = 215; // in JSP_IMPORT_VALUE + public static final int JSP_ACTION = 216; // in JSP_FILE + public static final int JSP_DIRECTIVE = 217; // in JSP_FILE + public static final int JSP_DECLARATION = 218; // in JSP_FILE + public static final int JSP_EXPRESSION = 219; // in JSP_FILE + public static final int JSP_SCRIPTLET_START = 220; // in JSP_FILE + public static final int JSP_SCRIPTLET_END = 221; // in JSP_FILE + public static final int JSP_TEMPLATE_DATA = 222; // in JSP_FILE + + public static final int XML_DOCUMENT = 223; + public static final int XML_TAG_NAME = 224; + public static final int XML_PROLOG = 225; + public static final int XML_DOCTYPE = 226; + public static final int XML_DOCTYPE_PUBLIC = 227; + public static final int XML_DOCTYPE_SYSTEM = 228; + public static final int XML_NAME = 229; + public static final int XML_ELEMENT_CONTENT_SPEC = 230; + public static final int XML_CONTENT_ANY = 231; + public static final int XML_CONTENT_EMPTY = 232; + public static final int XML_PCDATA = 233; + public static final int XML_ATT_REQUIRED = 234; + public static final int XML_ATT_IMPLIED = 235; + public static final int XML_ATT_FIXED = 236; + public static final int XML_DEFAULT_VALUE = 237; + public static final int XML_ENUMERATED_TYPE = 238; + public static final int XML_ATTRIBUTE = 240; + public static final int XML_TAG = 241; + public static final int DOC_TAG_VALUE = 242; + public static final int XML_ATTRIBUTE_VALUE = 243; + + public static final int TYPE_PARAMETER_IN_LIST = 244; + public static final int TYPE_PARAMETER_LIST = 245; + public static final int REFERENCE_PARAMETER_LIST = 246; + public static final int AT = 247; // in CLASS + public static final int ANNOTATION_DEFAULT_VALUE = 248; //in ANNOTATION_METHOD + public static final int ANNOTATION_VALUE = 249; // in NAME_VALUE_PAIR, ANNOTATION_ARRAY_INITIALIZER + public static final int ANNOTATION = 250; // in MODIFIER_LIST + public static final int CATCH_SECTION = 251; // in TRY_STATEMENT + + public static final int HTML_DOCUMENT = 252; + public static final int HTML_TAG = 253; + + public static final int LAST = HTML_TAG; + + public static boolean isUnique(int role) { + switch(role){ + default: + return true; + + case NONE: + case CLASS: + case FIELD: + case METHOD: + case PARAMETER: + case CLASS_INITIALIZER: + case COMMA: + case REFERENCE_IN_LIST: + case EXPRESSION_IN_LIST: + case ARRAY_DIMENSION: + case STATEMENT_IN_BLOCK: + case JSP_DIRECTIVE_ATTRIBUTE: + case JSP_IMPORT_REFERENCE: + case JSP_IMPORT_ON_DEMAND_DOT: + case JSP_IMPORT_ON_DEMAND_ASTERISK: + case JSP_ACTION: + case JSP_DIRECTIVE: + case JSP_DECLARATION: + case JSP_EXPRESSION: + case JSP_SCRIPTLET_START: + case JSP_SCRIPTLET_END: + case JSP_TEMPLATE_DATA: + case TYPE_PARAMETER_IN_LIST: + case ANNOTATION_VALUE: + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositeElement.java new file mode 100644 index 00000000000..aeb18ce813b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositeElement.java @@ -0,0 +1,301 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLock; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; + +public class CompositeElement extends TreeElement implements Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.CompositeElement"); + + public TreeElement prev = null; + public CompositeElement parent = null; + public TreeElement firstChild = null; // might be modified by transforming chameleons + public TreeElement lastChild = null; // might be modified by transforming chameleons + private final IElementType type; + private int myParentModifications = -1; + private int myStartOffset = 0; + private int myModificationsCount = 0; + + public CompositeElement(IElementType type) { + this.type = type; + } + + public int getModificationCount(){ + return myModificationsCount; + } + + public int getStartOffset() { + CompositeElement parent = this; + int sum = 0; + while(parent != null){ + sum += parent.getModificationCount(); + parent = parent.getTreeParent(); + } + if(sum != myParentModifications){ + myParentModifications = sum; + if(prev != null) myStartOffset = prev.getStartOffset() + prev.getTextLength(); + else { + if(this.parent != null) + myStartOffset = this.parent.getStartOffset(); + else myStartOffset = 0; + } + } + return myStartOffset; + } + + public Object clone() { + CompositeElement clone = (CompositeElement)super.clone(); + + synchronized (PsiLock.LOCK) { + clone.clearCaches(); + clone.parent = null; + clone.prev = null; + clone.firstChild = null; + clone.lastChild = null; + clone.myModificationsCount = 0; + clone.myParentModifications = -1; + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + TreeUtil.addChildren(clone, (TreeElement)child.clone()); + } + } + return clone; + } + + public void subtreeChanged() { + clearCaches(); + CompositeElement treeParent = getTreeParent(); + if(treeParent != null) treeParent.subtreeChanged(); + } + + public void clearCaches() { + setCachedLength(-1); + myModificationsCount++; + } + + public IElementType getElementType() { + return type; + } + + public CompositeElement getTreeParent() { + return parent; + } + + public TreeElement getTreePrev() { + return prev; + } + + public void setTreePrev(TreeElement prev) { + this.prev = prev; + } + + public void setTreeParent(CompositeElement parent) { + this.parent = parent; + } + + public int getTextLength(CharTable charTableByTree) { + return myCachedLength > 0 ? myCachedLength : getLengthInner(charTableByTree); + } + + public LeafElement findLeafElementAt(int offset) { + + synchronized (PsiLock.LOCK) { + final CharTable table = SharedImplUtil.findCharTableByTree(this); + TreeElement child = firstChild; + while (child != null) { + final int textLength = child.getTextLength(table); + if (textLength > offset) { + if (child instanceof ChameleonElement) { + child = ChameleonTransforming.transform((ChameleonElement)child); + continue; + } + return child.findLeafElementAt(offset); + } + offset -= textLength; + child = child.getTreeNext(); + } + return null; + } + } + + public String getText() { + return getText(SharedImplUtil.findCharTableByTree(this)); + } + + public String getText(CharTable table) { + synchronized (PsiLock.LOCK) { + // check if all elements are laid out consequently in the same buffer (optimization): + char[] buffer = new char[getTextLength()]; + SourceUtil.toBuffer(this, buffer, 0, table); +//return StringFactory.createStringFromConstantArray(buffer); + return new String(buffer); + } + } + + public char[] textToCharArray() { + synchronized (PsiLock.LOCK) { + char[] buffer = new char[getTextLength()]; + SourceUtil.toBuffer(this, buffer, 0); + return buffer; + } + } + + public boolean textContains(char c) { + return getText().indexOf(c) >= 0; + } + + public final PsiElement findChildByRoleAsPsiElement(int role) { + TreeElement element = findChildByRole(role); + if (element == null) return null; + return SourceTreeToPsiMap.treeElementToPsi(element); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + synchronized (PsiLock.LOCK) { + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + if (getChildRole(child) == role) return child; + } + ; + } + return null; + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + return ChildRole.NONE; + } + + protected final int getChildRole(TreeElement child, int roleCandidate) { + if (findChildByRole(roleCandidate) == child){ + return roleCandidate; + } + else{ + return ChildRole.NONE; + } + } + + public TreeElement[] getChildren(TokenSet filter) { + int count = countChildren(filter); + if (count == 0) { + return TreeElement.EMPTY_ARRAY; + } + final TreeElement[] result = new TreeElement[count]; + count = 0; + for(TreeElement child = firstChild; child != null; child = child.getTreeNext()){ + if (filter == null || filter.isInSet(child.getElementType())){ + result[count++] = child; + } + } + return result; + } + + + public PsiElement[] getChildrenAsPsiElements(TokenSet filter, PsiElementArrayConstructor constructor) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + + int count = countChildren(filter); + + if (count == 0){ + return constructor.newPsiElementArray(0); + } + + PsiElement[] result = constructor.newPsiElementArray(count); + count = 0; + for(TreeElement child = firstChild; child != null; child = child.getTreeNext()){ + if (filter == null || filter.isInSet(child.getElementType())){ + result[count++] = SourceTreeToPsiMap.treeElementToPsi(child); + } + } + return result; + } + + public int countChildren(TokenSet filter) { + ChameleonTransforming.transformChildren(this); + + // no lock is needed because all chameleons are expanded already + int count = 0; + for(TreeElement child = firstChild; child != null; child = child.getTreeNext()){ + if (filter == null || filter.isInSet(child.getElementType())) { + count++; + } + } + + return count; + } + + /** + * @return First element that was appended (for example whitespaces could be skipped) + */ + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + TreeElement anchorBefore; + if (anchor != null){ + anchorBefore = before.booleanValue() ? anchor : anchor.getTreeNext(); + } + else{ + if (before != null && !before.booleanValue()){ + anchorBefore = firstChild; + } + else{ + anchorBefore = null; + } + } + return CodeEditUtil.addChildren(this, first, last, anchorBefore); + } + + public void deleteChildInternal(TreeElement child) { + CodeEditUtil.removeChild(this, child); + } + + public void replaceChildInternal(TreeElement child, TreeElement newElement) { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement); + if (needParenth) { + newElement = SourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); + } + } + CodeEditUtil.replaceChild(this, child, newElement); + } + + private int myCachedLength = -1; + + public int getTextLength() { + if (myCachedLength < 0){ + myCachedLength = getLengthInner(SharedImplUtil.findCharTableByTree(this)); + } + if (DebugUtil.CHECK) { + int trueLength = getLengthInner(SharedImplUtil.findCharTableByTree(this)); + if (myCachedLength != trueLength) { + LOG.error("myCachedLength != trueLength"); + myCachedLength = trueLength; + } + } + return myCachedLength; + } + + public int getCachedLength() { + return myCachedLength; + } + + protected int getLengthInner(CharTable charTableByTree) { + synchronized (PsiLock.LOCK) { + int length = 0; + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + length += child.getTextLength(charTableByTree); + } + return length; + } + } + + public void setCachedLength(int length) { + myCachedLength = length; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositePsiElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositePsiElement.java new file mode 100644 index 00000000000..77cdb68e2d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/CompositePsiElement.java @@ -0,0 +1,266 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; + +public abstract class CompositePsiElement extends CompositeElement implements PsiElement, NavigationItem { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.CompositePsiElement"); + + protected CompositePsiElement(IElementType type) { + super(type); + } + + public final PsiElement[] getChildren() { + return getChildrenAsPsiElements(null, PSI_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiElement getFirstChild() { + return SharedImplUtil.getFirstChild(this); + } + + public PsiElement getLastChild() { + return SharedImplUtil.getLastChild(this); + } + + public void acceptChildren(PsiElementVisitor visitor) { + for (PsiElement child = getFirstChild(); child != null; ) { + final PsiElement nextSibling = child.getNextSibling(); + child.accept(visitor); + child = nextSibling; + } + } + + public PsiElement getParent() { + return SharedImplUtil.getParent(this); + } + + public PsiElement getNextSibling() { + return SharedImplUtil.getNextSibling(this); + } + + public PsiElement getPrevSibling() { + return SharedImplUtil.getPrevSibling(this); + } + + public PsiFile getContainingFile() { + return SharedImplUtil.getContainingFile(this); + } + + public PsiElement findElementAt(int offset) { + TreeElement leaf = findLeafElementAt(offset); + return SourceTreeToPsiMap.treeElementToPsi(leaf); + } + + public PsiReference findReferenceAt(int offset) { + return SharedPsiElementImplUtil.findReferenceAt(this, offset); + } + + public PsiElement copy() { + TreeElement elementCopy = copyElement(); + return SourceTreeToPsiMap.treeElementToPsi(elementCopy); + } + + public boolean isValid() { + return SharedImplUtil.isValid(this); + } + + public boolean isWritable() { + return SharedImplUtil.isWritable(this); + } + + public PsiReference getReference() { + return null; + } + + public PsiReference[] getReferences() { + return SharedPsiElementImplUtil.getReferences(this); + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + TreeElement elementCopy = ChangeUtil.copyToElement(element); + elementCopy = addInternal(elementCopy, elementCopy, null, null); + elementCopy = ChangeUtil.decodeInformation(elementCopy); + return SourceTreeToPsiMap.treeElementToPsi(elementCopy); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + TreeElement elementCopy = ChangeUtil.copyToElement(element); + elementCopy = addInternal(elementCopy, elementCopy, SourceTreeToPsiMap.psiElementToTree(anchor), Boolean.TRUE); + elementCopy = ChangeUtil.decodeInformation(elementCopy); + return SourceTreeToPsiMap.treeElementToPsi(elementCopy); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + TreeElement elementCopy = ChangeUtil.copyToElement(element); + elementCopy = addInternal(elementCopy, elementCopy, SourceTreeToPsiMap.psiElementToTree(anchor), Boolean.FALSE); + elementCopy = ChangeUtil.decodeInformation(elementCopy); + return SourceTreeToPsiMap.treeElementToPsi(elementCopy); + } + + public final void checkAdd(PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public final void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public final void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public final PsiElement addRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + return SharedImplUtil.addRange(this, first, last, null, null); + } + + public final PsiElement addRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + return SharedImplUtil.addRange(this, first, last, SourceTreeToPsiMap.psiElementToTree(anchor), Boolean.TRUE); + } + + public final PsiElement addRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + return SharedImplUtil.addRange(this, first, last, SourceTreeToPsiMap.psiElementToTree(anchor), Boolean.FALSE); + } + + public final void checkAddRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public final void checkAddRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public final void checkAddRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public void delete() throws IncorrectOperationException { + LOG.assertTrue(getTreeParent() != null); + CheckUtil.checkWritable(this); + getTreeParent().deleteChildInternal(this); + } + + public void checkDelete() throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public void deleteChildRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + TreeElement firstElement = SourceTreeToPsiMap.psiElementToTree(first); + TreeElement lastElement = SourceTreeToPsiMap.psiElementToTree(last); + LOG.assertTrue(firstElement.getTreeParent() == this); + LOG.assertTrue(lastElement.getTreeParent() == this); + CodeEditUtil.removeChildren(this, firstElement, lastElement); + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + LOG.assertTrue(getTreeParent() != null); + CheckUtil.checkWritable(this); + TreeElement elementCopy = ChangeUtil.copyToElement(newElement); + getTreeParent().replaceChildInternal(this, elementCopy); + elementCopy = ChangeUtil.decodeInformation(elementCopy); + final PsiElement result = SourceTreeToPsiMap.treeElementToPsi(elementCopy); + + // invalidate replaced element + setTreeNext(null); + setTreePrev(null); + setTreeParent(null); + return result; + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public void accept(PsiElementVisitor visitor) { //TODO: remove this method!! + visitor.visitElement(this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + return true; + } + + public String toString() { + return "PsiElement" + "(" + getElementType().toString() + ")"; + } + + public PsiElement getContext() { + return ResolveUtil.getContext(this); + } + + public PsiElement getNavigationElement() { + return this; + } + + public PsiElement getOriginalElement() { + return this; + } + + public boolean isPhysical() { + PsiFile file = getContainingFile(); + if (file == null) return false; + return file.isPhysical(); + } + + public GlobalSearchScope getResolveScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getResolveScope(this); + } + + public GlobalSearchScope getUseScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getUseScope(this); + } + + public ItemPresentation getPresentation() { + return null; + } + + public String getName() { + return null; + } + + public void navigate(boolean requestFocus) { + EditSourceUtil.getDescriptor(getNavigationElement()).navigate(requestFocus); + } + + public boolean canNavigate() { + return true; + } + + public FileStatus getFileStatus() { + if (!isPhysical()) return FileStatus.NOT_CHANGED; + PsiFile contFile = getContainingFile(); + if (contFile == null) return FileStatus.NOT_CHANGED; + VirtualFile vFile = contFile.getVirtualFile(); + return vFile != null ? FileStatusManager.getInstance(getProject()).getStatus(vFile) : FileStatus.NOT_CHANGED; + } + + public Project getProject() { + return getManager().getProject(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ElementType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ElementType.java new file mode 100644 index 00000000000..608bcfc1ee3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/ElementType.java @@ -0,0 +1,97 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiTypeElement; +import com.intellij.psi.TokenType; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.xml.dtd.DTDElementType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlElementType; + +public interface ElementType extends + TokenType, + DTDElementType, + JavaElementType, + JavaDocElementType, + JspElementType, + XmlElementType, + AspectElementType { + IElementType PLAIN_TEXT_FILE = new IElementType("PLAIN_TEXT_FILE"); + IElementType PLAIN_TEXT = new IElementType("PLAIN_TEXT"); + IElementType NEW_LINE_INDENT = new IElementType("NEW_LINE_INDENT"); + IElementType CODE_FRAGMENT = new IElementType("CODE_FRAGMENT"); + IElementType DUMMY_HOLDER = new IElementType("DUMMY_HOLDER"); + IElementType GRAMMAR_CHAMELEON = new IElementType("GRAMMAR_CHAMELEON"); + + TokenSet WHITE_SPACE_BIT_SET = TokenSet.create(new IElementType[]{WHITE_SPACE, JSP_DIRECTIVE_WHITE_SPACE, JSP_ACTION_WHITE_SPACE}); + + TokenSet COMMENT_BIT_SET = TokenSet.create(new IElementType[]{END_OF_LINE_COMMENT, C_STYLE_COMMENT, DOC_COMMENT, JSP_COMMENT, + XML_COMMENT}); + + TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.orSet(WHITE_SPACE_BIT_SET, COMMENT_BIT_SET); + + TokenSet KEYWORD_BIT_SET = TokenSet.create(new IElementType[]{ + ABSTRACT_KEYWORD, ASSERT_KEYWORD, BOOLEAN_KEYWORD, BREAK_KEYWORD, BYTE_KEYWORD, CASE_KEYWORD, + CATCH_KEYWORD, CHAR_KEYWORD, CLASS_KEYWORD, CONST_KEYWORD, CONTINUE_KEYWORD, + DEFAULT_KEYWORD, DO_KEYWORD, DOUBLE_KEYWORD, ELSE_KEYWORD, EXTENDS_KEYWORD, + FINAL_KEYWORD, FINALLY_KEYWORD, FLOAT_KEYWORD, FOR_KEYWORD, GOTO_KEYWORD, + IF_KEYWORD, IMPLEMENTS_KEYWORD, IMPORT_KEYWORD, INSTANCEOF_KEYWORD, INT_KEYWORD, + INTERFACE_KEYWORD, LONG_KEYWORD, NATIVE_KEYWORD, NEW_KEYWORD, PACKAGE_KEYWORD, + PRIVATE_KEYWORD, PUBLIC_KEYWORD, SHORT_KEYWORD, SUPER_KEYWORD, SWITCH_KEYWORD, STRICTFP_KEYWORD, + SYNCHRONIZED_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, PROTECTED_KEYWORD, TRANSIENT_KEYWORD, + RETURN_KEYWORD, VOID_KEYWORD, STATIC_KEYWORD, WHILE_KEYWORD, TRY_KEYWORD, VOLATILE_KEYWORD, + THROWS_KEYWORD, ENUM_KEYWORD + }); + + TokenSet MODIFIER_BIT_SET = TokenSet.create(new IElementType[]{ + PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, STATIC_KEYWORD, + ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD, SYNCHRONIZED_KEYWORD, + STRICTFP_KEYWORD, TRANSIENT_KEYWORD, VOLATILE_KEYWORD + }); + + TokenSet PRIMITIVE_TYPE_BIT_SET = TokenSet.create(new IElementType[]{ + BOOLEAN_KEYWORD, BYTE_KEYWORD, SHORT_KEYWORD, INT_KEYWORD, + LONG_KEYWORD, CHAR_KEYWORD, FLOAT_KEYWORD, DOUBLE_KEYWORD, + VOID_KEYWORD + }); + + TokenSet EXPRESSION_BIT_SET = TokenSet.create(new IElementType[]{ + REFERENCE_EXPRESSION, LITERAL_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, PARENTH_EXPRESSION, + METHOD_CALL_EXPRESSION, TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, + BINARY_EXPRESSION, CONDITIONAL_EXPRESSION, ASSIGNMENT_EXPRESSION, NEW_EXPRESSION, + ARRAY_ACCESS_EXPRESSION, ARRAY_INITIALIZER_EXPRESSION, INSTANCE_OF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION, + EMPTY_EXPRESSION + }); + + TokenSet ANNOTATION_MEMBER_VALUE_BIT_SET = TokenSet.orSet(EXPRESSION_BIT_SET, TokenSet.create(new IElementType[]{ + ANNOTATION, ANNOTATION_ARRAY_INITIALIZER + })); + + TokenSet ARRAY_DIMENSION_BIT_SET = TokenSet.create(new IElementType[]{ + REFERENCE_EXPRESSION, LITERAL_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, PARENTH_EXPRESSION, + METHOD_CALL_EXPRESSION, TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, + BINARY_EXPRESSION, CONDITIONAL_EXPRESSION, ASSIGNMENT_EXPRESSION, NEW_EXPRESSION, + ARRAY_ACCESS_EXPRESSION, INSTANCE_OF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION, + EMPTY_EXPRESSION + }); + + TokenSet STATEMENT_BIT_SET = TokenSet.create(new IElementType[]{ + EMPTY_STATEMENT, BLOCK_STATEMENT, EXPRESSION_STATEMENT, EXPRESSION_LIST_STATEMENT, + DECLARATION_STATEMENT, IF_STATEMENT, WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT, + DO_WHILE_STATEMENT, SWITCH_STATEMENT, SWITCH_LABEL_STATEMENT, BREAK_STATEMENT, + CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT, + TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT + }); + TokenSet TYPES_BIT_SET = TokenSet.create(new IElementType[]{TYPE}); + Constants.PsiElementArrayConstructor PSI_TYPE_ELEMENT_ARRAY_CONSTRUCTOR = new Constants.PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length > 0 ? new PsiTypeElement[length] : PsiTypeElement.EMPTY_ARRAY; + } + }; + TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(new IElementType[]{IMPORT_STATEMENT}); + TokenSet IMPORT_STATIC_STATEMENT_BIT_SET = TokenSet.create(new IElementType[]{IMPORT_STATIC_STATEMENT}); + TokenSet IMPORT_STATEMENT_BASE_BIT_SET = TokenSet.create(new IElementType[]{IMPORT_STATEMENT, IMPORT_STATIC_STATEMENT}); + TokenSet CLASS_KEYWORD_BIT_SET = TokenSet.create(new IElementType[]{CLASS_KEYWORD, INTERFACE_KEYWORD, ENUM_KEYWORD}); + TokenSet MEMBER_BIT_SET = TokenSet.create(new IElementType[]{CLASS, FIELD, CLASS_INITIALIZER, METHOD}); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/Factory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/Factory.java new file mode 100644 index 00000000000..238ab8e606e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/Factory.java @@ -0,0 +1,544 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.aspects.psi.IAspectElementType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.*; +import com.intellij.psi.impl.source.html.HtmlDocumentImpl; +import com.intellij.psi.impl.source.html.HtmlTagImpl; +import com.intellij.psi.impl.source.javadoc.*; +import com.intellij.psi.impl.source.jsp.*; +import com.intellij.psi.impl.source.jsp.jspJava.JspTemplateStatement; +import com.intellij.psi.impl.source.jsp.jspJava.JspText; +import com.intellij.psi.impl.source.tree.java.*; +import com.intellij.psi.impl.source.xml.*; +import com.intellij.psi.jsp.JspTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaDocElementType; +import com.intellij.psi.tree.java.IJavaElementType; +import com.intellij.psi.tree.jsp.IJspElementType; +import com.intellij.psi.tree.xml.IXmlElementType; +import com.intellij.util.CharTable; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +public class Factory implements Constants { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.Factory"); + + private static final List ourElementFactories = new ArrayList(); + + public static void addElementFactory(ElementFactory factory) { + ourElementFactories.add(factory); + } + + public interface ElementFactory { + LeafElement createLeafElement(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table); + + CompositeElement createCompositeElement(IElementType type); + + boolean isMyElementType(IElementType type); + } + + public static LeafElement createSingleLeafElement(IElementType type, char[] buffer, int startOffset, int endOffset, CharTable table, PsiManager manager) { + final LeafElement newElement; + if(table != null){ + newElement = Factory.createLeafElement(type, buffer, startOffset, endOffset, -1, table); + newElement.putUserData(CharTable.CHAR_TABLE_KEY, table); + } + else{ + final FileElement holderElement = new DummyHolder(manager, null, table).getTreeElement(); + newElement = Factory.createLeafElement(type, buffer, startOffset, endOffset, -1, holderElement.getCharTable()); + TreeUtil.addChildren(holderElement, newElement); + } + return newElement; + } + + public static LeafElement createLeafElement(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + LeafElement element = null; + if (type == JAVA_FILE_TEXT) { + element = new JavaFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type instanceof IXmlElementType) { + element = new XmlTokenImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type == JSP_FILE_TEXT) { + element = new JspFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == XML_FILE_TEXT) { + element = new XmlFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } else if (type == XHTML_FILE_TEXT) { + element = new XHtmlFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == HTML_FILE_TEXT) { + element = new HTMLFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == DTD_FILE_TEXT) { + element = new DTDFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == IMPORT_LIST_TEXT) { + element = new ImportListChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == CODE_BLOCK_TEXT) { + element = new CodeBlockChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == DOC_COMMENT_TEXT) { + element = new DocCommentChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == ASPECT_FILE_TEXT) { + element = new AspectFileChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == EXPRESSION_TEXT) { + element = new ExpressionChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == STATEMENTS) { + element = new StatementsChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == TYPE_TEXT) { + element = new TypeChameleonElement(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == PLAIN_TEXT) { + element = new PsiPlainTextImpl(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == WHITE_SPACE) { + element = new PsiWhiteSpaceImpl(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == C_STYLE_COMMENT || type == END_OF_LINE_COMMENT) { + element = new PsiCommentImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type == IDENTIFIER) { + element = new PsiIdentifierImpl(buffer, startOffset, endOffset, lexerState, table); + } + else if (type == JavaDocTokenType.DOC_TYPE_TEXT) { + element = new JavaDocReferenceChameleon(type, buffer, startOffset, endOffset, true, lexerState, table); + } + else if (type == JavaDocTokenType.DOC_REFERENCE_TEXT) { + element = new JavaDocReferenceChameleon(type, buffer, startOffset, endOffset, false, lexerState, table); + } + else if (type == JspTokenType.JSP_IMPORT_ATTRIBUTE_CHAMELEON) { + element = new JspImportAttributeChameleonElement(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type == JspElementType.JSP_DECLARATION_TEXT) { + element = new JspDeclarationChameleonElement(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type == JspElementType.HOLDER_TEMPLATE_DATA) { + element = new JspText(buffer, startOffset, endOffset, table); + } + else { + if (KEYWORD_BIT_SET.isInSet(type)) { + element = new PsiKeywordImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type instanceof IJavaElementType) { + element = new PsiJavaTokenImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type instanceof IJspElementType) { + element = new JspTokenImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type instanceof IJavaDocElementType) { + element = new PsiDocTokenImpl(type, buffer, startOffset, endOffset, lexerState, table); + } + else if (type instanceof IAspectElementType) { + element = com.intellij.aspects.psi.gen.impl.Factory.createLeafElement(type, buffer, startOffset, endOffset, table); + } + else { + for (int size = ourElementFactories.size(), i = 0; i < size; i++) { + ElementFactory elementFactory = ourElementFactories.get(i); + if (elementFactory.isMyElementType(type)) { + element = elementFactory.createLeafElement(type, buffer, startOffset, endOffset, lexerState, table); + } + } + //LOG.error("Unknown leaf:" + type); + //return null; + if (element == null) { + element = new LeafPsiElement(type, buffer, startOffset, endOffset, lexerState, table); + } + } + } + LOG.assertTrue(element.getElementType() == type); + return element; + } + + public static CompositeElement createCompositeElement(IElementType type) { + + //TODO: Replace whole method with type.createPsiElement(); + CompositeElement element = null; + if (type == TYPE_PARAMETER_LIST) { + element = new TypeParameterListElement(); + } + else if (type == XML_TAG) { + element = new XmlTagImpl(); + } else if (type == HTML_TAG) { + element = new HtmlTagImpl(); + } + else if (type == XML_TEXT) { + element = new XmlTextImpl(); + } + else if (type == XML_PROCESSING_INSTRUCTION) { + element = new XmlProcessingInstructionImpl(); + } + else if (type == TYPE_PARAMETER) { + element = new TypeParameterElement(); + } + else if (type == EXTENDS_BOUND_LIST) { + element = new TypeParameterExtendsBoundsListElement(); + } + else if (type == ERROR_ELEMENT) { + element = new PsiErrorElementImpl(); + } + else if (type == JAVA_FILE) { + element = new JavaFileElement(); + } + else if (type == PLAIN_TEXT_FILE) { + element = new PlainTextFileElement(); + } + else if (type == JSP_FILE) { + element = new JspFileElement(); + } + else if (type == XML_FILE) { + element = new XmlFileElement(); + } else if (type == HTML_FILE) { + element = new HtmlFileElement(); + } + else if (type == CODE_FRAGMENT) { + element = new CodeFragmentElement(); + } + else if (type == DUMMY_HOLDER) { + element = new DummyHolderElement(); + } + else if (type == ASPECT_FILE) { + element = new AspectFileElement(); + } + else if (type == DOC_COMMENT) { + element = new PsiDocCommentImpl(); + } + else if (type == DOC_TAG) { + element = new PsiDocTagImpl(); + } + else if (type == DOC_TAG_VALUE_TOKEN) { + element = new PsiDocTagValueImpl(); + } + else if (type == DOC_METHOD_OR_FIELD_REF) { + element = new PsiDocMethodOrFieldRef(); + } + else if (type == DOC_PARAMETER_REF) { + element = new PsiDocParamRef(); + } + else if (type == DOC_INLINE_TAG) { + element = new PsiInlineDocTagImpl(); + } + else if (type == CLASS) { + element = new ClassElement(type); + } + else if (type == ANONYMOUS_CLASS) { + element = new AnonymousClassElement(); + } + else if (type == ENUM_CONSTANT_INITIALIZER) { + element = new EnumConstantInitializerElement(); + } + else if (type == FIELD) { + element = new FieldElement(); + } + else if (type == ENUM_CONSTANT) { + element = new EnumConstantElement(); + } + else if (type == METHOD) { + element = new MethodElement(); + } + else if (type == LOCAL_VARIABLE) { + element = new PsiLocalVariableImpl(); + } + else if (type == PARAMETER) { + element = new ParameterElement(); + } + else if (type == PARAMETER_LIST) { + element = new ParameterListElement(); + } + else if (type == CLASS_INITIALIZER) { + element = new ClassInitializerElement(); + } + else if (type == PACKAGE_STATEMENT) { + element = new PsiPackageStatementImpl(); + } + else if (type == IMPORT_LIST) { + element = new ImportListElement(); + } + else if (type == IMPORT_STATEMENT) { + element = new ImportStatementElement(); + } + else if (type == IMPORT_STATIC_STATEMENT) { + element = new ImportStaticStatementElement(); + } + else if (type == IMPORT_STATIC_REFERENCE) { + element = new PsiImportStaticReferenceElementImpl(); + } + else if (type == JAVA_CODE_REFERENCE) { + element = new PsiJavaCodeReferenceElementImpl(); + } + else if (type == REFERENCE_PARAMETER_LIST) { + element = new PsiReferenceParameterListImpl(); + } + else if (type == TYPE) { + element = new PsiTypeElementImpl(); + } + else if (type == MODIFIER_LIST) { + element = new ModifierListElement(); + } + else if (type == EXTENDS_LIST) { + element = new ExtendsListElement(); + } + else if (type == IMPLEMENTS_LIST) { + element = new ImplementsListElement(); + } + else if (type == THROWS_LIST) { + element = new PsiThrowsListImpl(); + } + else if (type == EXPRESSION_LIST) { + element = new PsiExpressionListImpl(); + } + else if (type == REFERENCE_EXPRESSION) { + element = new PsiReferenceExpressionImpl(); + } + else if (type == LITERAL_EXPRESSION) { + element = new PsiLiteralExpressionImpl(); + } + else if (type == THIS_EXPRESSION) { + element = new PsiThisExpressionImpl(); + } + else if (type == SUPER_EXPRESSION) { + element = new PsiSuperExpressionImpl(); + } + else if (type == PARENTH_EXPRESSION) { + element = new PsiParenthesizedExpressionImpl(); + } + else if (type == METHOD_CALL_EXPRESSION) { + element = new PsiMethodCallExpressionImpl(); + } + else if (type == TYPE_CAST_EXPRESSION) { + element = new PsiTypeCastExpressionImpl(); + } + else if (type == PREFIX_EXPRESSION) { + element = new PsiPrefixExpressionImpl(); + } + else if (type == POSTFIX_EXPRESSION) { + element = new PsiPostfixExpressionImpl(); + } + else if (type == BINARY_EXPRESSION) { + element = new PsiBinaryExpressionImpl(); + } + else if (type == CONDITIONAL_EXPRESSION) { + element = new PsiConditionalExpressionImpl(); + } + else if (type == ASSIGNMENT_EXPRESSION) { + element = new PsiAssignmentExpressionImpl(); + } + else if (type == NEW_EXPRESSION) { + element = new PsiNewExpressionImpl(); + } + else if (type == ARRAY_ACCESS_EXPRESSION) { + element = new PsiArrayAccessExpressionImpl(); + } + else if (type == ARRAY_INITIALIZER_EXPRESSION) { + element = new PsiArrayInitializerExpressionImpl(); + } + else if (type == INSTANCE_OF_EXPRESSION) { + element = new PsiInstanceOfExpressionImpl(); + } + else if (type == CLASS_OBJECT_ACCESS_EXPRESSION) { + element = new PsiClassObjectAccessExpressionImpl(); + } + else if (type == EMPTY_EXPRESSION) { + element = new PsiEmptyExpressionImpl(); + } + else if (type == EMPTY_STATEMENT) { + element = new PsiEmptyStatementImpl(); + } + else if (type == BLOCK_STATEMENT) { + element = new PsiBlockStatementImpl(); + } + else if (type == EXPRESSION_STATEMENT) { + element = new PsiExpressionStatementImpl(); + } + else if (type == EXPRESSION_LIST_STATEMENT) { + element = new PsiExpressionListStatementImpl(); + } + else if (type == DECLARATION_STATEMENT) { + element = new PsiDeclarationStatementImpl(); + } + else if (type == IF_STATEMENT) { + element = new PsiIfStatementImpl(); + } + else if (type == WHILE_STATEMENT) { + element = new PsiWhileStatementImpl(); + } + else if (type == FOR_STATEMENT) { + element = new PsiForStatementImpl(); + } + else if (type == FOREACH_STATEMENT) { + element = new PsiForeachStatementImpl(); + } + else if (type == DO_WHILE_STATEMENT) { + element = new PsiDoWhileStatementImpl(); + } + else if (type == SWITCH_STATEMENT) { + element = new PsiSwitchStatementImpl(); + } + else if (type == SWITCH_LABEL_STATEMENT) { + element = new PsiSwitchLabelStatementImpl(); + } + else if (type == BREAK_STATEMENT) { + element = new PsiBreakStatementImpl(); + } + else if (type == CONTINUE_STATEMENT) { + element = new PsiContinueStatementImpl(); + } + else if (type == RETURN_STATEMENT) { + element = new PsiReturnStatementImpl(); + } + else if (type == THROW_STATEMENT) { + element = new PsiThrowStatementImpl(); + } + else if (type == SYNCHRONIZED_STATEMENT) { + element = new PsiSynchronizedStatementImpl(); + } + else if (type == ASSERT_STATEMENT) { + element = new PsiAssertStatementImpl(); + } + else if (type == TRY_STATEMENT) { + element = new PsiTryStatementImpl(); + } + else if (type == LABELED_STATEMENT) { + element = new PsiLabeledStatementImpl(); + } + else if (type == CODE_BLOCK) { + element = new PsiCodeBlockImpl(); + } + else if (type == CATCH_SECTION) { + element = new PsiCatchSectionImpl(); + } + else if (type == JSP_DIRECTIVE) { + element = new JspDirectiveImpl(); + } + else if (type == JSP_ACTION) { + element = new JspActionImpl(); + } + else if (type == JSP_DIRECTIVE_ATTRIBUTE || type == JSP_ACTION_ATTRIBUTE) { + element = new JspAttributeImpl(type); + } + else if (type == JSP_IMPORT_VALUE) { + element = new JspImportValueImpl(); + } + else if (type == JSP_DECLARATION) { + element = new JspDeclarationImpl(); + } + else if (type == JSP_EXPRESSION) { + element = new JspExpressionImpl(); + } + else if (type == JSP_ACTION_ATTRIBUTE_VALUE) { + element = new JspAttributeValueImpl(); + } + else if (type == JSP_TEMPLATE_STATEMENT) { + element = new JspTemplateStatement(); + } + else if (type == JSP_FILE_REFERENCE) { + element = new JspFileReferenceImpl(); + } + else if (type == XML_DOCUMENT) { + element = new XmlDocumentImpl(); + } else if (type == HTML_DOCUMENT) { + element = new HtmlDocumentImpl(); + } + else if (type == XML_PROLOG) { + element = new XmlPrologImpl(); + } + else if (type == XML_DECL) { + element = new XmlDeclImpl(); + } + else if (type == XML_ATTRIBUTE) { + element = new XmlAttributeImpl(); + } + else if (type == XML_ATTRIBUTE_VALUE) { + element = new XmlAttributeValueImpl(); + } + else if (type == XML_COMMENT) { + element = new XmlCommentImpl(); + } + else if (type == XML_DOCTYPE) { + element = new XmlDoctypeImpl(); + } + else if (type == XML_MARKUP_DECL) { + element = new XmlMarkupDeclImpl(); + } + else if (type == XML_ELEMENT_DECL) { + element = new XmlElementDeclImpl(); + } + else if (type == XML_ENTITY_DECL) { + element = new XmlEntityDeclImpl(); + } + else if (type == XML_ATTLIST_DECL) { + element = new XmlAttlistDeclImpl(); + } + else if (type == XML_ATTRIBUTE_DECL) { + element = new XmlAttributeDeclImpl(); + } + else if (type == XML_NOTATION_DECL) { + element = new XmlNotationDeclImpl(); + } + else if (type == XML_ELEMENT_CONTENT_SPEC) { + element = new XmlElementContentSpecImpl(); + } + else if (type == XML_ENTITY_REF) { + element = new XmlEntityRefImpl(); + } + else if (type == XML_ENUMERATED_TYPE) { + element = new XmlEnumeratedTypeImpl(); + } + else if (type == XML_PROCESSING_INSTRUCTION) { + element = new XmlProcessingInstructionImpl(); + } + else if (type == ANNOTATION_METHOD) { + element = new AnnotationMethodElement(); + } + else if (type == ANNOTATION) { + element = new PsiAnnotationImpl(); + } + else if (type == ANNOTATION_ARRAY_INITIALIZER) { + element = new PsiArrayInitializerMemberValueImpl(); + } + else if (type == NAME_VALUE_PAIR) { + element = new PsiNameValuePairImpl(); + } + else if (type == ANNOTATION_PARAMETER_LIST) { + element = new PsiAnnotationParameterListImpl(); + } + else { + if (type instanceof IAspectElementType) { + element = com.intellij.aspects.psi.gen.impl.Factory.createCompositeElement(type); + } + else { + for (int size = ourElementFactories.size(), i = 0; i < size; i++) { + ElementFactory elementFactory = ourElementFactories.get(i); + if (elementFactory.isMyElementType(type)) { + element = elementFactory.createCompositeElement(type); + } + } + + if (element == null) { + //LOG.assertTrue(false, "Unknown composite element type:" + BitSetUtil.toString(ElementType.class, type)); + element = new CompositePsiElement(type){}; + } + } + } + LOG.assertTrue(element.getElementType() == type, "Type created: " + element.getElementType() + " wanted: " + type); + return element; + } + + public static CompositeElement createErrorElement(String description) { + CompositeElement errorElement = createCompositeElement(ERROR_ELEMENT); + ((PsiErrorElementImpl)errorElement).setErrorDescription(description); + return errorElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/FileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/FileElement.java new file mode 100644 index 00000000000..c29c936bba1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/FileElement.java @@ -0,0 +1,77 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.psi.PsiLock; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.CharTableImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.SrcRepositoryPsiElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public abstract class FileElement extends RepositoryTreeElement{ + private Document myDocument; // only to hold document + private CharTable myCharTable = new CharTableImpl(); + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.FileElement"); + + public CharTable getCharTable() { + return myCharTable; + } + + protected FileElement(IElementType type) { + super(type); + } + + public void setDocument(Document document){ + myDocument = document; + } + + public PsiManager getManager() { + final PsiManager manager = getUserData(MANAGER_KEY); + if (manager == null) { + return SourceTreeToPsiMap.treeElementToPsi(this).getManager(); //TODO: cache? + } + else { + return manager; + } + } + + public TreeElement copyElement() { + SrcRepositoryPsiElement psiElement = getPsiElement(); + SrcRepositoryPsiElement psiElementCopy = (SrcRepositoryPsiElement)psiElement.copy(); + return psiElementCopy.getTreeElement(); + } + + public Object clone() { + FileElement clone = (FileElement)super.clone(); + clone.myDocument = null; + return clone; + } + + public char[] textToCharArray() { + synchronized (PsiLock.LOCK) { + final int textLength = getTextLength(); + char[] buffer = new char[textLength]; + SourceUtil.toBuffer(this, buffer, 0); + return buffer; + } + } + + public void setCharTable(CharTable table) { + myCharTable = table; + } + + public void replaceChildInternal(TreeElement child, TreeElement newElement) { + if (newElement.getElementType() == ElementType.IMPORT_LIST) { + LOG.assertTrue(child.getElementType() == ElementType.IMPORT_LIST); + if (((CompositeElement)newElement).firstChild == null) { //empty import list + TreeElement next = child.getTreeNext(); + if (next.getElementType() == ElementType.WHITE_SPACE) { + ChangeUtil.removeChild(this, next); + } + } + } + super.replaceChildInternal(child, newElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/HtmlFileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/HtmlFileElement.java new file mode 100644 index 00000000000..e00a75a284f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/HtmlFileElement.java @@ -0,0 +1,21 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; + +public class HtmlFileElement extends FileElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.HtmlFileElement"); + + public HtmlFileElement() { + super(HTML_FILE); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == HTML_DOCUMENT) { + return ChildRole.HTML_DOCUMENT; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaDocElementType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaDocElementType.java new file mode 100644 index 00000000000..c566f13036d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaDocElementType.java @@ -0,0 +1,15 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaDocElementType; + +public interface JavaDocElementType { + //chameleon + IElementType DOC_COMMENT_TEXT = new IJavaDocElementType("DOC_COMMENT_TEXT"); + + IElementType DOC_TAG = new IJavaDocElementType("DOC_TAG"); + IElementType DOC_TAG_VALUE = new IJavaDocElementType("DOC_TAG_VALUE"); + IElementType DOC_INLINE_TAG = new IJavaDocElementType("DOC_INLINE_TAG"); + IElementType DOC_METHOD_OR_FIELD_REF = new IJavaDocElementType("DOC_METHOD_OR_FIELD_REF"); + IElementType DOC_PARAMETER_REF = new IJavaDocElementType("DOC_PARAMETER_REF"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaElementType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaElementType.java new file mode 100644 index 00000000000..dd560e2cade --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -0,0 +1,95 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.java.IJavaElementType; + +public interface JavaElementType { + //chameleons + IElementType JAVA_FILE_TEXT = new IJavaElementType("JAVA_FILE_TEXT"); + IElementType IMPORT_LIST_TEXT = new IJavaElementType("IMPORT_LIST_TEXT"); + IElementType CODE_BLOCK_TEXT = new IJavaElementType("CODE_BLOCK_TEXT"); + IElementType EXPRESSION_TEXT = new IJavaElementType("EXPRESSION_TEXT"); + IElementType JAVA_FILE = new IJavaElementType("JAVA_FILE"); + IElementType TYPE_PARAMETER = new IJavaElementType("TYPE_PARAMETER"); + IElementType TYPE_PARAMETER_LIST = new IJavaElementType("TYPE_PARAMETER_LIST"); + IElementType STATEMENTS = new IJavaElementType("STATEMENTS"); + IElementType TYPE_TEXT = new IJavaElementType("TYPE_TEXT"); + + IElementType ERROR_ELEMENT = new IJavaElementType("ERROR_ELEMENT"); + + IElementType JAVA_CODE_REFERENCE = new IJavaElementType("JAVA_CODE_REFERENCE"); + + IElementType PACKAGE_STATEMENT = new IJavaElementType("PACKAGE_STATEMENT"); + IElementType CLASS = new IJavaElementType("CLASS"); + IElementType ANONYMOUS_CLASS = new IJavaElementType("ANONYMOUS_CLASS"); + IElementType ENUM_CONSTANT_INITIALIZER = new IJavaElementType("ENUM_CONSTANT_INITIALIZER"); + IElementType IMPORT_LIST = new IJavaElementType("IMPORT_LIST"); + IElementType IMPORT_STATEMENT = new IJavaElementType("IMPORT_STATEMENT"); + IElementType IMPORT_STATIC_STATEMENT = new IJavaElementType("IMPORT_STATIC_STATEMENT"); + IElementType IMPORT_STATIC_REFERENCE = new IJavaElementType("IMPORT_STATIC_REFERENCE"); + IElementType MODIFIER_LIST = new IJavaElementType("MODIFIER_LIST"); + IElementType EXTENDS_LIST = new IJavaElementType("EXTENDS_LIST"); + IElementType IMPLEMENTS_LIST = new IJavaElementType("IMPLEMENTS_LIST"); + IElementType CODE_BLOCK = new IJavaElementType("CODE_BLOCK"); + IElementType FIELD = new IJavaElementType("FIELD"); + IElementType ENUM_CONSTANT = new IJavaElementType("ENUM_CONSTANT"); + IElementType METHOD = new IJavaElementType("METHOD"); + IElementType LOCAL_VARIABLE = new IJavaElementType("LOCAL_VARIABLE"); + IElementType CLASS_INITIALIZER = new IJavaElementType("CLASS_INITIALIZER"); + IElementType PARAMETER = new IJavaElementType("PARAMETER"); + IElementType TYPE = new IJavaElementType("TYPE"); + IElementType PARAMETER_LIST = new IJavaElementType("PARAMETER_LIST"); + IElementType EXTENDS_BOUND_LIST = new IJavaElementType("EXTENDS_BOUND_LIST"); + IElementType THROWS_LIST = new IJavaElementType("THROWS_LIST"); + IElementType REFERENCE_PARAMETER_LIST = new IJavaElementType("REFERENCE_PARAMETER_LIST"); + + IElementType REFERENCE_EXPRESSION = new IJavaElementType("REFERENCE_EXPRESSION"); + IElementType LITERAL_EXPRESSION = new IJavaElementType("LITERAL_EXPRESSION"); + IElementType THIS_EXPRESSION = new IJavaElementType("THIS_EXPRESSION"); + IElementType SUPER_EXPRESSION = new IJavaElementType("SUPER_EXPRESSION"); + IElementType PARENTH_EXPRESSION = new IJavaElementType("PARENTH_EXPRESSION"); + IElementType METHOD_CALL_EXPRESSION = new IJavaElementType("METHOD_CALL_EXPRESSION"); + IElementType TYPE_CAST_EXPRESSION = new IJavaElementType("TYPE_CAST_EXPRESSION"); + IElementType PREFIX_EXPRESSION = new IJavaElementType("PREFIX_EXPRESSION"); + IElementType POSTFIX_EXPRESSION = new IJavaElementType("POSTFIX_EXPRESSION"); + IElementType BINARY_EXPRESSION = new IJavaElementType("BINARY_EXPRESSION"); + IElementType CONDITIONAL_EXPRESSION = new IJavaElementType("CONDITIONAL_EXPRESSION"); + IElementType ASSIGNMENT_EXPRESSION = new IJavaElementType("ASSIGNMENT_EXPRESSION"); + IElementType NEW_EXPRESSION = new IJavaElementType("NEW_EXPRESSION"); + IElementType ARRAY_ACCESS_EXPRESSION = new IJavaElementType("ARRAY_ACCESS_EXPRESSION"); + IElementType ARRAY_INITIALIZER_EXPRESSION = new IJavaElementType("ARRAY_INITIALIZER_EXPRESSION"); + IElementType INSTANCE_OF_EXPRESSION = new IJavaElementType("INSTANCE_OF_EXPRESSION"); + IElementType CLASS_OBJECT_ACCESS_EXPRESSION = new IJavaElementType("CLASS_OBJECT_ACCESS_EXPRESSION"); + IElementType EMPTY_EXPRESSION = new IJavaElementType("EMPTY_EXPRESSION"); + + IElementType EXPRESSION_LIST = new IJavaElementType("EXPRESSION_LIST"); + + IElementType EMPTY_STATEMENT = new IJavaElementType("EMPTY_STATEMENT"); + IElementType BLOCK_STATEMENT = new IJavaElementType("BLOCK_STATEMENT"); + IElementType EXPRESSION_STATEMENT = new IJavaElementType("EXPRESSION_STATEMENT"); + IElementType EXPRESSION_LIST_STATEMENT = new IJavaElementType("EXPRESSION_LIST_STATEMENT"); + IElementType DECLARATION_STATEMENT = new IJavaElementType("DECLARATION_STATEMENT"); + IElementType IF_STATEMENT = new IJavaElementType("IF_STATEMENT"); + IElementType WHILE_STATEMENT = new IJavaElementType("WHILE_STATEMENT"); + IElementType FOR_STATEMENT = new IJavaElementType("FOR_STATEMENT"); + IElementType FOREACH_STATEMENT = new IJavaElementType("FOREACH_STATEMENT"); + IElementType DO_WHILE_STATEMENT = new IJavaElementType("DO_WHILE_STATEMENT"); + IElementType SWITCH_STATEMENT = new IJavaElementType("SWITCH_STATEMENT"); + IElementType SWITCH_LABEL_STATEMENT = new IJavaElementType("SWITCH_LABEL_STATEMENT"); + IElementType BREAK_STATEMENT = new IJavaElementType("BREAK_STATEMENT"); + IElementType CONTINUE_STATEMENT = new IJavaElementType("CONTINUE_STATEMENT"); + IElementType RETURN_STATEMENT = new IJavaElementType("RETURN_STATEMENT"); + IElementType THROW_STATEMENT = new IJavaElementType("THROW_STATEMENT"); + IElementType SYNCHRONIZED_STATEMENT = new IJavaElementType("SYNCHRONIZED_STATEMENT"); + IElementType TRY_STATEMENT = new IJavaElementType("TRY_STATEMENT"); + IElementType LABELED_STATEMENT = new IJavaElementType("LABELED_STATEMENT"); + IElementType ASSERT_STATEMENT = new IJavaElementType("ASSERT_STATEMENT"); + + IElementType CATCH_SECTION = new IElementType("CATCH_SECTION"); + + IElementType ANNOTATION_METHOD = new IJavaElementType("ANNOTATION_METHOD"); + IElementType ANNOTATION_ARRAY_INITIALIZER = new IJavaElementType("ANNOTATION_ARRAY_INITIALIZER"); + IElementType ANNOTATION = new IJavaElementType("ANNOTATION"); + IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR"); + IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafElement.java new file mode 100644 index 00000000000..af92e10abdd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafElement.java @@ -0,0 +1,117 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.text.StringSearcher; + +public abstract class LeafElement extends TreeElement { + private volatile int myState = 0; // 16 bit for type, 15 bit for state and 1 bit for parentFlag + public abstract char charAt(int position); + public abstract int searchWord(int startOffset, StringSearcher searcher); + public abstract int copyTo(char[] buffer, int start); + + public int copyTo(char[] buffer, int start, CharTable table){ + return copyTo(buffer, start); + } + + public int getTextLength(CharTable table){ + return getTextLength(); + } + + protected LeafElement(IElementType type) { + myState = myState | type.getIndex(); + } + + public final LeafElement findLeafElementAt(int offset) { + return this; + } + + public String getText() { + return getText(SharedImplUtil.findCharTableByTree(this)); //To change body of implemented methods use File | Settings | File Templates. + } + + public abstract int textMatches(CharSequence buffer, int start); + + public void registerInCharTable(CharTable table, CharTable oldCharTab) {} + + //boolean isLast = false; + public synchronized void setState(int state){ + myState = myState & 0x8000FFFF | (((state + 1) & 0x7FFF) << 16); + } + + public IElementType getElementType() { + short sh = 0; + sh |= (short)(myState & 0xFFFF); + return IElementType.find(sh); + } + + public int getState(){ + return (myState >> 16) & 0x7FFF - 1; + } + + private boolean isLast(){ + return (myState & 0x80000000) != 0; + } + + private void setLast(boolean last){ + if(last) + myState |= 0x80000000; + else + myState &= 0x7FFFFFFF; + } + + public synchronized TreeElement getTreeNext() { + if(!isLast()) return next; + return null; + } + + public synchronized CompositeElement getTreeParent() { + if(isLast()) + return (CompositeElement)next; + TreeElement next = this.next; + while(next instanceof LeafElement && !((LeafElement)next).isLast()) next = next.next; + if(next != null) return next.getTreeParent(); + return null; + } + + public synchronized TreeElement getTreePrev() { + final CompositeElement parent = getTreeParent(); + if(parent == null) return null; + TreeElement firstChild = parent.firstChild; + if(firstChild == this) return null; + while(firstChild != null && firstChild.next != this) firstChild = firstChild.next; + return firstChild; + } + + public synchronized void setTreeParent(CompositeElement parent) { + if(next == null || isLast()){ + next = parent; + setLast(true); + } + } + + public synchronized void setTreeNext(TreeElement next) { + if(next != null){ + setLast(false); + this.next = next; + } + else{ + if(!isLast()){ + this.next = getTreeParent(); + setLast(true); + } + } + } + + public void setTreePrev(TreeElement prev) { + } + + public Object clone() { + LeafElement clone = (LeafElement)super.clone(); + clone.setState(-1); + clone.setLast(false); + return clone; + } + + public abstract int getCharTabIndex(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafPsiElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafPsiElement.java new file mode 100644 index 00000000000..8764e2e3354 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/LeafPsiElement.java @@ -0,0 +1,214 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +public class LeafPsiElement extends LeafElementImpl implements PsiElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.LeafPsiElement"); + + protected LeafPsiElement(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, table); + setState(lexerState); + } + + public PsiElement[] getChildren() { + return PsiElement.EMPTY_ARRAY; + } + + public PsiElement getFirstChild() { + return null; + } + + public PsiElement getLastChild() { + return null; + } + + public void acceptChildren(PsiElementVisitor visitor) { + } + + public PsiElement getParent() { + return SharedImplUtil.getParent(this); + } + + public PsiElement getNextSibling() { + return SharedImplUtil.getNextSibling(this); + } + + public PsiElement getPrevSibling() { + return SharedImplUtil.getPrevSibling(this); + } + + public PsiFile getContainingFile() { + return SharedImplUtil.getContainingFile(this); + } + + public PsiElement findElementAt(int offset) { + return this; + } + + public PsiReference findReferenceAt(int offset) { + return SharedPsiElementImplUtil.findReferenceAt(this, offset); + } + + public PsiElement copy() { + TreeElement elementCopy = copyElement(); + return SourceTreeToPsiMap.treeElementToPsi(elementCopy); + } + + public boolean isValid() { + return SharedImplUtil.isValid(this); + } + + public boolean isWritable() { + return SharedImplUtil.isWritable(this); + } + + public PsiReference getReference() { + return null; + } + + public PsiReference[] getReferences() { + return SharedPsiElementImplUtil.getReferences(this); + } + + public PsiElement add(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAdd(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddBefore(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddAfter(PsiElement element, PsiElement anchor) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement addRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRangeBefore(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void checkAddRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) + throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public void delete() throws IncorrectOperationException { + LOG.assertTrue(getTreeParent() != null); + CheckUtil.checkWritable(this); + getTreeParent().deleteChildInternal(this); + } + + public void checkDelete() throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public void deleteChildRange(PsiElement first, PsiElement last) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement replace(PsiElement newElement) throws IncorrectOperationException { + LOG.assertTrue(getTreeParent() != null); + CheckUtil.checkWritable(this); + TreeElement elementCopy = ChangeUtil.copyToElement(newElement); + getTreeParent().replaceChildInternal(this, elementCopy); + elementCopy = ChangeUtil.decodeInformation(elementCopy); + final PsiElement result = SourceTreeToPsiMap.treeElementToPsi(elementCopy); + + // invalidate replaced element + setTreeNext(null); + setTreePrev(null); + setTreeParent(null); + return result; + } + + public void checkReplace(PsiElement newElement) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + } + + public String toString() { + return "PsiElement" + "(" + getElementType().toString() + ")"; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitElement(this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, + PsiSubstitutor substitutor, + PsiElement lastParent, + PsiElement place) { + return true; + } + + public PsiElement getContext() { + return ResolveUtil.getContext(this); + } + + public PsiElement getNavigationElement() { + return this; + } + + public PsiElement getOriginalElement() { + return this; + } + + public boolean isPhysical() { + PsiFile file = getContainingFile(); + if (file == null) return false; + return file.isPhysical(); + } + + public GlobalSearchScope getResolveScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getResolveScope(this); + } + + public GlobalSearchScope getUseScope() { + return ((PsiManagerImpl)getManager()).getFileManager().getUseScope(this); + } + + public Project getProject() { + return getManager().getProject(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PlainTextFileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PlainTextFileElement.java new file mode 100644 index 00000000000..08f35e45ef6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PlainTextFileElement.java @@ -0,0 +1,7 @@ +package com.intellij.psi.impl.source.tree; + +public class PlainTextFileElement extends FileElement{ + public PlainTextFileElement() { + super(PLAIN_TEXT_FILE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiCommentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiCommentImpl.java new file mode 100644 index 00000000000..180153cc9af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiCommentImpl.java @@ -0,0 +1,25 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public class PsiCommentImpl extends LeafPsiElement implements PsiComment, JavaTokenType { + protected PsiCommentImpl(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, lexerState, table); + } + + public IElementType getTokenType() { + return getElementType(); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitComment(this); + } + + public String toString(){ + return "PsiComment(" + getElementType().toString() + ")"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiErrorElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiErrorElementImpl.java new file mode 100644 index 00000000000..8132bcb18dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiErrorElementImpl.java @@ -0,0 +1,43 @@ + +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.*; + +public class PsiErrorElementImpl extends CompositePsiElement implements PsiErrorElement{ + private String myErrorDescription; + + public PsiErrorElementImpl() { + super(ERROR_ELEMENT); + } + + public void setErrorDescription(String errorDescription) { + myErrorDescription = errorDescription; + } + + public String getErrorDescription() { + return myErrorDescription; + } + + public String getExpectedToken() { + //TODO: hack should be specified when error element is created. Just give it a try + if (myErrorDescription.indexOf("expected") >= 0) { + if (myErrorDescription.toLowerCase().indexOf("statement") >= 0) return "{}"; + int startApos = myErrorDescription.indexOf("\'"); + if (startApos >= 0) { + int stopApos = myErrorDescription.indexOf("\'", startApos + 1); + if (stopApos >= 0) { + return myErrorDescription.substring(startApos + 1, stopApos); + } + } + } + return null; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitErrorElement(this); + } + + public String toString(){ + return "PsiErrorElement:" + getErrorDescription(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiPlainTextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiPlainTextImpl.java new file mode 100644 index 00000000000..6a62d01ead6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiPlainTextImpl.java @@ -0,0 +1,19 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiPlainText; +import com.intellij.util.CharTable; + +public class PsiPlainTextImpl extends LeafPsiElement implements PsiPlainText { + protected PsiPlainTextImpl(char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(PLAIN_TEXT, buffer, startOffset, endOffset, lexerState, table); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitPlainText(this); + } + + public String toString(){ + return "PsiPlainText"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiWhiteSpaceImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiWhiteSpaceImpl.java new file mode 100644 index 00000000000..c2234b44e87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/PsiWhiteSpaceImpl.java @@ -0,0 +1,20 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.TokenType; +import com.intellij.util.CharTable; + +public class PsiWhiteSpaceImpl extends LeafPsiElement implements PsiWhiteSpace { + protected PsiWhiteSpaceImpl(char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(TokenType.WHITE_SPACE, buffer, startOffset, endOffset, lexerState, table); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitWhiteSpace(this); + } + + public String toString(){ + return "PsiWhiteSpace"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SharedImplUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SharedImplUtil.java new file mode 100644 index 00000000000..8c0d67bdc89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SharedImplUtil.java @@ -0,0 +1,194 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.PsiTypeElementImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.Helper; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +//TODO: rename/regroup? +public class SharedImplUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.SharedImplUtil"); + + public static PsiElement getParent(TreeElement thisElement) { + return SourceTreeToPsiMap.treeElementToPsi(thisElement.getTreeParent()); + } + + public static PsiElement getFirstChild(CompositeElement element) { + if (element.firstChild == null) return null; + return SourceTreeToPsiMap.treeElementToPsi(element.firstChild.getTransformedFirstOrSelf()); + } + + public static PsiElement getLastChild(CompositeElement element) { + if (element.lastChild == null) return null; + return SourceTreeToPsiMap.treeElementToPsi(element.lastChild.getTransformedLastOrSelf()); + } + + public static PsiElement getNextSibling(TreeElement thisElement) { + final TreeElement treeNext = thisElement.getTreeNext(); + return treeNext != null ? SourceTreeToPsiMap.treeElementToPsi(treeNext.getTransformedFirstOrSelf()) : null; + } + + public static PsiElement getPrevSibling(TreeElement thisElement) { + final TreeElement treePrev = thisElement.getTreePrev(); + return treePrev != null ? SourceTreeToPsiMap.treeElementToPsi(treePrev.getTransformedLastOrSelf()) : null; + } + + public static PsiFile getContainingFile(TreeElement thisElement) { + TreeElement element; + for(element = thisElement; element.getTreeParent() != null; element = element.getTreeParent()){ + } + + if (element.getManager() == null) return null; // otherwise treeElementToPsi may crash! + PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element); + if(psiElement instanceof DummyHolder) return psiElement.getContainingFile(); + if (!(psiElement instanceof PsiFile)) return null; + return (PsiFile)psiElement; + } + + public static boolean isValid(TreeElement thisElement) { + LOG.assertTrue(thisElement instanceof PsiElement); + PsiFile file = getContainingFile(thisElement); + if (file == null) return false; + return file.isValid(); + } + + public static boolean isWritable(TreeElement thisElement) { + PsiFile file = (SourceTreeToPsiMap.treeElementToPsi(thisElement)).getContainingFile(); + return file != null ? file.isWritable() : true; + } + + public static CharTable findCharTableByTree(TreeElement tree){ + while(tree != null){ + final CharTable userData = tree.getUserData(CharTable.CHAR_TABLE_KEY); + if(userData != null) return userData; + if(tree instanceof FileElement) return ((FileElement)tree).getCharTable(); + tree = tree.getTreeParent(); + } + LOG.assertTrue(false, "Invalid root element"); + return null; + } + + public static PsiElement addRange(PsiElement thisElement, PsiElement first, PsiElement last, TreeElement anchor, Boolean before) throws IncorrectOperationException{ + CheckUtil.checkWritable(thisElement); + final CharTable table = findCharTableByTree(SourceTreeToPsiMap.psiElementToTree(thisElement)); + FileType fileType = thisElement.getContainingFile().getFileType(); + Project project = thisElement.getProject(); + Helper helper = new Helper(fileType, project); + + TreeElement copyFirst = null; + TreeElement copyLast = null; + TreeElement next = SourceTreeToPsiMap.psiElementToTree(last).getTreeNext(); + CompositeElement parent = null; + for(TreeElement element = SourceTreeToPsiMap.psiElementToTree(first); element != next; element = element.getTreeNext()){ + TreeElement elementCopy = ChangeUtil.copyElement(element, table); + if (element == first){ + copyFirst = elementCopy; + } + if (element == last){ + copyLast = elementCopy; + } + if(parent == null) parent = elementCopy.getTreeParent(); + else { + ChangeUtil.addChild(parent, elementCopy, null); + helper.normalizeIndent(elementCopy); + } + } + if (copyFirst == null) return null; + copyFirst = ((CompositeElement)SourceTreeToPsiMap.psiElementToTree(thisElement)).addInternal(copyFirst, copyLast, anchor, before); + for(TreeElement element = copyFirst; element != null; element = element.getTreeNext()){ + element = ChangeUtil.decodeInformation(element); + if (element.getTreePrev() == null){ + copyFirst = element; + } + } + return SourceTreeToPsiMap.treeElementToPsi(copyFirst); + } + + public static PsiType getType(PsiVariable variable){ + PsiTypeElement typeElement = variable.getTypeElement(); + int arrayCount = 0; + TreeElement name = SourceTreeToPsiMap.psiElementToTree(variable.getNameIdentifier()); + Loop: + for(TreeElement child = name.getTreeNext(); child != null; child = child.getTreeNext()){ + IElementType i = child.getElementType(); + if (i == ElementType.LBRACKET) { + arrayCount++; + } + else if (i == ElementType.RBRACKET || + i == ElementType.WHITE_SPACE || + i == ElementType.C_STYLE_COMMENT || + i == ElementType.DOC_COMMENT || + i == ElementType.END_OF_LINE_COMMENT) { + } + else { + break Loop; + } + } + PsiType type; + if (!(typeElement instanceof PsiTypeElementImpl)) { + type = typeElement.getType(); + } + else { + type = ((PsiTypeElementImpl)typeElement).getDetachedType(variable); + } + + for(int i = 0; i < arrayCount; i++){ + type = type.createArrayType(); + } + return type; + } + + public static void normalizeBrackets(PsiVariable variable){ + CompositeElement variableElement = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(variable); + CompositeElement type = (CompositeElement)variableElement.findChildByRole(ChildRole.TYPE); + LOG.assertTrue(type.getTreeParent() == variableElement); + TreeElement name = variableElement.findChildByRole(ChildRole.NAME); + + TreeElement firstBracket = null; + TreeElement lastBracket = null; + int arrayCount = 0; + TreeElement element = name; + while(true){ + element = TreeUtil.skipElements(element.getTreeNext(), ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET); + if (element == null || element.getElementType() != ElementType.LBRACKET) break; + if (firstBracket == null) firstBracket = element; + lastBracket = element; + arrayCount++; + + element = TreeUtil.skipElements(element.getTreeNext(), ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET); + if (element == null || element.getElementType() != ElementType.RBRACKET) break; + lastBracket = element; + } + + if (firstBracket != null){ + element = firstBracket; + while(true){ + TreeElement next = element.getTreeNext(); + ChangeUtil.removeChild(variableElement, element); + if (element == lastBracket) break; + element = next; + } + + CompositeElement newType = (CompositeElement)type.clone(); + final CharTable treeCharTable = SharedImplUtil.findCharTableByTree(type); + for(int i = 0; i < arrayCount; i++){ + CompositeElement newType1 = Factory.createCompositeElement(ElementType.TYPE); + TreeUtil.addChildren(newType1, newType); + + TreeUtil.addChildren(newType1, Factory.createLeafElement(ElementType.LBRACKET, new char[]{'['}, 0, 1, -1, treeCharTable)); + TreeUtil.addChildren(newType1, Factory.createLeafElement(ElementType.RBRACKET, new char[]{']'}, 0, 1, -1, treeCharTable)); + newType = newType1; + } + newType.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(type)); + ChangeUtil.replaceChild(variableElement, type, newType); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SourceUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SourceUtil.java new file mode 100644 index 00000000000..c3b073c4a6d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/SourceUtil.java @@ -0,0 +1,128 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.SourceJavaCodeReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.parsing.ExpressionParsing; +import com.intellij.psi.impl.source.parsing.Parsing; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +/** + * + */ +public class SourceUtil implements Constants { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.SourceUtil"); + + public static int toBuffer(TreeElement element, char[] buffer, int offset) { + return toBuffer(element, buffer, offset, null, SharedImplUtil.findCharTableByTree(element)); + } + + public static int toBuffer(TreeElement element, char[] buffer, int offset, CharTable table) { + return toBuffer(element, buffer, offset, null, table); + } + + private static int toBuffer(TreeElement element, char[] buffer, int offset, TokenSet skipTypes, CharTable table) { + synchronized (PsiLock.LOCK) { + if (skipTypes != null && skipTypes.isInSet(element.getElementType())) return offset; + if (element instanceof LeafElement) { + return ((LeafElement)element).copyTo(buffer, offset, table); + } + else { + int curOffset = offset; + for (TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()) { + curOffset = toBuffer(child, buffer, curOffset, skipTypes, table); + } + return curOffset; + } + } + } + + public static String getTextSkipWhiteSpaceAndComments(TreeElement element) { + final CharTable table = SharedImplUtil.findCharTableByTree(element); + int length = toBuffer(element, null, 0, WHITE_SPACE_OR_COMMENT_BIT_SET, table); + char[] buffer = new char[length]; + toBuffer(element, buffer, 0, WHITE_SPACE_OR_COMMENT_BIT_SET, table); + return new String(buffer); + } + + public static TreeElement addParenthToReplacedChild(final IElementType parenthType, + TreeElement newChild, + PsiManager manager) { + CompositeElement parenthExpr = Factory.createCompositeElement(parenthType); + + TreeElement dummyExpr = (TreeElement)newChild.clone(); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(newChild); + new DummyHolder(manager, parenthExpr, null, charTableByTree); + parenthExpr.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + TreeUtil.addChildren(parenthExpr, Factory.createLeafElement(JavaTokenType.LPARENTH, new char[]{'('}, 0, 1, -1, charTableByTree)); + TreeUtil.addChildren(parenthExpr, dummyExpr); + TreeUtil.addChildren(parenthExpr, Factory.createLeafElement(JavaTokenType.RPARENTH, new char[]{')'}, 0, 1, -1, charTableByTree)); + + + try { + CodeStyleManager codeStyleManager = manager.getCodeStyleManager(); + parenthExpr = + (CompositeElement)SourceTreeToPsiMap.psiElementToTree( + codeStyleManager.reformat(SourceTreeToPsiMap.treeElementToPsi(parenthExpr))); + } + catch (IncorrectOperationException e) { + LOG.error(e); // should not happen + } + + newChild.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(newChild)); + TreeUtil.replace(dummyExpr, newChild); + + newChild = parenthExpr; + return newChild; + } + + public static void fullyQualifyReference(CompositeElement reference, PsiClass targetClass) { + if (((SourceJavaCodeReference)reference).isQualified()) { // qualifed reference + final PsiClass parentClass = targetClass.getContainingClass(); + if (parentClass == null) return; + final TreeElement qualifier = reference.findChildByRole(ChildRole.QUALIFIER); + if (qualifier instanceof SourceJavaCodeReference) { + ((SourceJavaCodeReference)qualifier).fullyQualify(parentClass); + } + } + else { // unqualified reference, need to qualify with package name + final String qName = targetClass.getQualifiedName(); + if (qName == null) { + return; // todo: local classes? + } + final int i = qName.lastIndexOf('.'); + if (i > 0) { + final String prefix = qName.substring(0, i); + PsiManager manager = reference.getManager(); + char[] chars = prefix.toCharArray(); + final CharTable table = SharedImplUtil.findCharTableByTree(reference); + final CompositeElement qualifier; + if (reference instanceof PsiReferenceExpression) { + qualifier = ExpressionParsing.parseExpressionText(manager, chars, 0, chars.length, table); + } + else { + qualifier = Parsing.parseJavaCodeReferenceText(manager, chars, table); + } + if (qualifier != null) { + final CharTable systemCharTab = SharedImplUtil.findCharTableByTree(qualifier); + final LeafElement dot = Factory.createSingleLeafElement(DOT, new char[]{'.'}, 0, 1, systemCharTab, null); + TreeUtil.insertAfter(qualifier, dot); + reference.addInternal(qualifier, dot, null, Boolean.FALSE); + } + } + } + } + + public static void dequalifyImpl(CompositeElement reference) { + final TreeElement qualifier = reference.findChildByRole(ChildRole.QUALIFIER); + if (qualifier == null) return; + reference.deleteChildInternal(qualifier); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeElement.java new file mode 100644 index 00000000000..850e8864279 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeElement.java @@ -0,0 +1,184 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLock; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.ElementBase; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public abstract class TreeElement extends ElementBase implements Constants, Cloneable { + public static final TreeElement[] EMPTY_ARRAY = new TreeElement[0]; + protected TreeElement next = null; // this var could be not only next element pointer in ChildElements + // use it _VERY_ carefuly!! If you are not sure use apropariate getter (getTreeNext()). + + public static final Key MANAGER_KEY = Key.create("Element.MANAGER_KEY"); + + public Object clone(){ + TreeElement clone = (TreeElement)super.clone(); + clone.clearCaches(); + clone.next = null; + return clone; + } + + public TreeElement copyElement() { + if (getTreeParent() != null) { + CompositeElement parentCopy = (CompositeElement)getTreeParent().copyElement(); + synchronized (PsiLock.LOCK) { + int index = 0; + for (TreeElement child = getTreeParent().firstChild; child != this; child = child.getTreeNext()) { + index++; + } + TreeElement child; + for (child = parentCopy.firstChild; index > 0; child = child.getTreeNext(), index--) { + } +//child.putUserData(MANAGER_KEY, getManager()); //? + return child; + } + } + else { + final TreeElement clone = (TreeElement)clone(); + clone.putUserData(MANAGER_KEY, getManager()); //? + return clone; + } + } + + public PsiManager getManager() { + TreeElement element; + for(element = this; element.getTreeParent() != null; element = element.getTreeParent()){ + } + + if (element instanceof FileElement){ //TODO!! + return element.getManager(); + } + else{ + if (getTreeParent() != null) { + return getTreeParent().getManager(); + } + else{ + return getUserData(MANAGER_KEY); + } + } + } + + public abstract int getTextLength(); + + public abstract LeafElement findLeafElementAt(int offset); + + public abstract String getText(); + public abstract String getText(CharTable table); + + public abstract char[] textToCharArray(); + + public abstract boolean textContains(char c); + + public TextRange getTextRange() { + synchronized (PsiLock.LOCK) { + int start = getStartOffset(); + return new TextRange(start, start + getTextLength()); + } + } + + public int getStartOffset() { + synchronized (PsiLock.LOCK) { + final CompositeElement parent = getTreeParent(); + if (parent == null) return 0; + int offset = parent.getStartOffset(); + final CharTable table = SharedImplUtil.findCharTableByTree(this); + for (TreeElement element1 = parent.firstChild; element1 != this; element1 = element1.getTreeNext()) { + offset += element1.getTextLength(table); + } + return offset; + } + } + + public final int getStartOffsetInParent(){ + if (getTreeParent() == null) return -1; + int offset = 0; + for(TreeElement child = getTreeParent().firstChild; child != this; child = child.getTreeNext()){ + offset += child.getTextLength(); + } + return offset; + } + + public int getTextOffset(){ + return getStartOffset(); + } + + public boolean textMatches(CharSequence buffer, int startOffset, int endOffset) { + return textMatches(this, buffer, startOffset, endOffset) == endOffset; + } + + public int textStartsWith(CharSequence buffer, int startOffset, int endOffset){ + return textMatches(this, buffer, startOffset, endOffset); + } + + private static int textMatches(TreeElement element, CharSequence buffer, int startOffset, int endOffset) { + synchronized (PsiLock.LOCK) { + if (element instanceof LeafElement) { + final LeafElement leaf = (LeafElement)element; + return leaf.textMatches(buffer, startOffset); + } + else { + int curOffset = startOffset; + for (TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()) { + curOffset = textMatches(child, buffer, curOffset, endOffset); + if (curOffset == -1) return -1; + } + return curOffset; + } + } + } + + public boolean textMatches(CharSequence seq) { + return textMatches(seq, 0, seq.length()); + } + + public boolean textMatches(PsiElement element) { + if (getTextLength() != element.getTextLength()) return false; + return textMatches(element.getText()); + } + + public String toString(){ + return "Element" + "(" + getElementType().toString() + ")"; + } + + public abstract IElementType getElementType(); + + public abstract CompositeElement getTreeParent(); + + public TreeElement getTreeNext() { + return next; + } + + public abstract TreeElement getTreePrev(); + + public abstract void setTreePrev(TreeElement prev); + public void setTreeNext(TreeElement next){ + this.next = next; + } + public abstract void setTreeParent(CompositeElement parent); + public abstract int getTextLength(CharTable charTableByTree); + + public TreeElement getTransformedFirstOrSelf(){ + return this; + } + + public TreeElement getTransformedLastOrSelf(){ + return this; + } + + public void clearCaches(){} + + public final boolean equals(Object obj){ + return super.equals(obj); + } + + public final int hashCode(){ + return super.hashCode(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeUtil.java new file mode 100644 index 00000000000..21e2d0f9969 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/TreeUtil.java @@ -0,0 +1,342 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; + +import java.util.HashSet; +import java.util.Set; + +public class TreeUtil { + public static TreeElement findChild(CompositeElement parent, IElementType type) { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){ + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + for(TreeElement element = parent.firstChild; element != null; element = element.getTreeNext()){ + if (element.getElementType() == type) return element; + } + return null; + } + + public static TreeElement findChild(CompositeElement parent, TokenSet types) { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){ + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + for(TreeElement element = parent.firstChild; element != null; element = element.getTreeNext()){ + if (types.isInSet(element.getElementType())) return element; + } + return null; + } + + public static TreeElement findChildBackward(CompositeElement parent, IElementType type) { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){ + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + for(TreeElement element = parent.lastChild; element != null; element = element.getTreePrev()){ + if (element.getElementType() == type) return element; + } + return null; + } + + public static TreeElement findChildBackward(CompositeElement parent, TokenSet types) { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){ + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + for(TreeElement element = parent.lastChild; element != null; element = element.getTreePrev()){ + if (types.isInSet(element.getElementType())) return element; + } + return null; + } + + public static TreeElement skipElements(TreeElement element, TokenSet types) { + while(true){ + if (element == null) return null; + if (!types.isInSet(element.getElementType())) break; + element = element.getTreeNext(); + } + return element; + } + + public static TreeElement skipElementsBack(TreeElement element, TokenSet types) { + while(true){ + if (element == null) return null; + if (!types.isInSet(element.getElementType())) break; + element = element.getTreePrev(); + } + return element; + } + + public static TreeElement findParent(TreeElement element, IElementType type) { + for(TreeElement parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()){ + if (parent.getElementType() == type) return parent; + } + return null; + } + + public static TreeElement findParent(TreeElement element, TokenSet types) { + for(TreeElement parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()){ + if (types.isInSet(parent.getElementType())) return parent; + } + return null; + } + + public static boolean isInRange(TreeElement element, TreeElement start, TreeElement end) { + for(TreeElement child = start; child != end; child = child.getTreeNext()){ + if (child == element) return true; + } + return false; + } + + public static LeafElement findFirstLeaf(TreeElement element) { + if (element instanceof LeafElement){ + return (LeafElement)element; + } + else{ + for(TreeElement child = ((CompositeElement)element).firstChild; child != null; child = child.getTreeNext()){ + LeafElement leaf = findFirstLeaf(child); + if (leaf != null) return leaf; + } + return null; + } + } + + public static LeafElement findLastLeaf(TreeElement element) { + if (element instanceof LeafElement){ + return (LeafElement)element; + } + else{ + for(TreeElement child = ((CompositeElement)element).lastChild; child != null; child = child.getTreePrev()){ + LeafElement leaf = findLastLeaf(child); + if (leaf != null) return leaf; + } + return null; + } + } + + public static void addChildren(CompositeElement parent, TreeElement first) { + final TreeElement lastChild = parent.lastChild; + if (lastChild == null){ + parent.firstChild = first; + first.setTreePrev(null); + while(true){ + final TreeElement treeNext = first.getTreeNext(); + if(first instanceof CompositeElement) first.setTreeParent(parent); + if(treeNext == null) break; + first = treeNext; + } + parent.lastChild = first; + first.setTreeParent(parent); + } + else insertAfter(lastChild, first); + if (DebugUtil.CHECK){ + DebugUtil.checkTreeStructure(parent); + } + } + + public static void insertBefore(TreeElement anchor, TreeElement firstNew) { + final TreeElement anchorPrev = anchor.getTreePrev(); + if(anchorPrev == null){ + final CompositeElement parent = anchor.getTreeParent(); + if(parent != null) parent.firstChild = firstNew; + while(true){ + final TreeElement treeNext = firstNew.getTreeNext(); + if(firstNew instanceof CompositeElement){ + firstNew.setTreeParent(parent); + } + if(treeNext == null) break; + firstNew = treeNext; + } + anchor.setTreePrev(firstNew); + firstNew.setTreeNext(anchor); + } + else insertAfter(anchorPrev, firstNew); + + if (DebugUtil.CHECK){ + DebugUtil.checkTreeStructure(anchor); + } + } + + public static void insertAfter(TreeElement anchor, TreeElement firstNew) { + final CompositeElement parent = anchor.getTreeParent(); + final TreeElement treeNext = anchor.getTreeNext(); + firstNew.setTreePrev(anchor); + anchor.setTreeNext(firstNew); + while(true){ + final TreeElement next = firstNew.getTreeNext(); + if(firstNew instanceof CompositeElement){ + firstNew.setTreeParent(parent); + } + if(next == null) break; + firstNew = next; + } + + if(treeNext == null){ + if(parent != null){ + firstNew.setTreeParent(parent); + parent.lastChild = firstNew; + } + } + else{ + firstNew.setTreeNext(treeNext); + treeNext.setTreePrev(firstNew); + } + if (DebugUtil.CHECK){ + DebugUtil.checkTreeStructure(anchor); + } + } + + public static void remove(TreeElement element) { + final TreeElement next = element.getTreeNext(); + final CompositeElement parent = element.getTreeParent(); + final TreeElement prev = element.getTreePrev(); + if(prev != null){ + prev.setTreeNext(next); + } + else if(parent != null){ + parent.firstChild = next; + } + + if(next != null){ + next.setTreePrev(prev); + } + else if(parent != null){ + parent.lastChild = prev; + } + + if (DebugUtil.CHECK){ + if (element.getTreeParent() != null){ + DebugUtil.checkTreeStructure(element.getTreeParent()); + } + if (element.getTreePrev() != null){ + DebugUtil.checkTreeStructure(element.getTreePrev()); + } + if (element.getTreeNext() != null){ + DebugUtil.checkTreeStructure(element.getTreeNext()); + } + } + element.setTreePrev(null); + element.setTreeParent(null); + element.setTreeNext(null); + } + + public static void removeRange(TreeElement start, TreeElement end) { + if (start == null) return; + if(start == end) return; + final CompositeElement parent = start.getTreeParent(); + final TreeElement startPrev = start.getTreePrev(); + final TreeElement endPrev = end != null ? end.getTreePrev() : null; + if (parent != null){ + if (start == parent.firstChild){ + parent.firstChild = end; + } + if (end == null){ + parent.lastChild = startPrev; + } + } + if (startPrev != null){ + startPrev.setTreeNext(end); + } + if (end != null){ + end.setTreePrev(startPrev); + } + + start.setTreePrev(null); + if (endPrev != null){ + endPrev.setTreeNext(null); + } + if (parent != null){ + for(TreeElement element = start; element != null; element = element.getTreeNext()){ + if(element instanceof CompositeElement) + element.setTreeParent(null); + } + } + + if (DebugUtil.CHECK){ + if (parent != null){ + DebugUtil.checkTreeStructure(parent); + } + DebugUtil.checkTreeStructure(start); + } + } + + public static void replace(TreeElement old, TreeElement firstNew) { + if (firstNew != null){ + insertAfter(old, firstNew); + } + remove(old); + } + + public static TreeElement findSibling(TreeElement start, IElementType elementType) { + TreeElement child = start; + while (true) { + if (child == null) return null; + if (child.getElementType() == elementType) return child; + child = child.getTreeNext(); + } + } + + public static TreeElement findSibling(TreeElement start, TokenSet types) { + TreeElement child = start; + while (true) { + if (child == null) return null; + if (types.isInSet(child.getElementType())) return child; + child = child.getTreeNext(); + } + } + + public static TreeElement findCommonParent(TreeElement one, TreeElement two){ + // optimization + if(one == two) return one; + final Set parents = new HashSet(20); + do{ + parents.add(one); + } while((one = one.getTreeParent()) != null); + + while((two = two.getTreeParent()) != null){ + if(parents.contains(two)) return two; + } + return null; + } + + public static int getNotCachedLength(TreeElement tree, CharTable table) { + int length = 0; + + if (tree instanceof LeafElement) { + length += tree.getTextLength(table); + } + else{ + final CompositeElement composite = (CompositeElement)tree; + TreeElement firstChild = composite.firstChild; + while(firstChild != null){ + length += getNotCachedLength(firstChild, table); + firstChild = firstChild.getTreeNext(); + } + } + return length; + } + + public static int countLeafs(CompositeElement composite) { + int count = 0; + TreeElement child = composite.firstChild; + while(child != null){ + if(child instanceof LeafElement) count++; + else count += countLeafs((CompositeElement)child); + child = child.getTreeNext(); + } + return count; + } + + public static void clearCaches(TreeElement tree) { + tree.clearCaches(); + if(tree instanceof CompositeElement){ + final CompositeElement composite = ((CompositeElement)tree); + TreeElement child = composite.firstChild; + while(child != null){ + clearCaches(child); + child = child.getTreeNext(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/XmlFileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/XmlFileElement.java new file mode 100644 index 00000000000..ebfb034b13f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/XmlFileElement.java @@ -0,0 +1,21 @@ +package com.intellij.psi.impl.source.tree; + +import com.intellij.openapi.diagnostic.Logger; + +public class XmlFileElement extends FileElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.XmlFileElement"); + + public XmlFileElement() { + super(XML_FILE); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == XML_DOCUMENT) { + return ChildRole.XML_DOCUMENT; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java new file mode 100644 index 00000000000..e7a2569d56a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java @@ -0,0 +1,36 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.impl.source.tree.TreeElement; + + +/** + * @author ven + */ +public class AnnotationMethodElement extends MethodElement { + public AnnotationMethodElement() { + super(ANNOTATION_METHOD); + } + + public TreeElement findChildByRole(int role) { + if (role == ChildRole.ANNOTATION_DEFAULT_VALUE) { + return TreeUtil.findChild(this, ANNOTATION_MEMBER_VALUE_BIT_SET); + } else if (role == ChildRole.DEFAULT_KEYWORD) { + return TreeUtil.findChild(this, DEFAULT_KEYWORD); + } + + return super.findChildByRole(role); + } + + public int getChildRole(TreeElement child) { + if (child.getElementType() == DEFAULT_KEYWORD) { + return ChildRole.DEFAULT_KEYWORD; + } else if (ANNOTATION_MEMBER_VALUE_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.ANNOTATION_DEFAULT_VALUE; + } + + return super.getChildRole(child); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElement.java new file mode 100644 index 00000000000..2171e6f226d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElement.java @@ -0,0 +1,12 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.JavaTokenType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.JavaTokenType; + +public class AnonymousClassElement extends AnonymousClassElementBase { + public AnonymousClassElement() { + super(ANONYMOUS_CLASS); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElementBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElementBase.java new file mode 100644 index 00000000000..c9324768e4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/AnonymousClassElementBase.java @@ -0,0 +1,69 @@ +/* + * Created by IntelliJ IDEA. + * User: ven + * Date: Jun 10, 2004 + * Time: 8:05:20 PM + */ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public abstract class AnonymousClassElementBase extends ClassElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.AnonymousClassElement"); + + public AnonymousClassElementBase(IElementType type) { + super(type); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.BASE_CLASS_REFERENCE: + return firstChild.getElementType() == JavaElementType.JAVA_CODE_REFERENCE ? firstChild : null; + + case ChildRole.ARGUMENT_LIST: + return TreeUtil.findChild(this, JavaElementType.EXPRESSION_LIST); + + case ChildRole.LBRACE: + return TreeUtil.findChild(this, JavaTokenType.LBRACE); + + case ChildRole.RBRACE: + return TreeUtil.findChildBackward(this, JavaTokenType.RBRACE); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JavaElementType.JAVA_CODE_REFERENCE) { + return getChildRole(child, ChildRole.BASE_CLASS_REFERENCE); + } + else if (i == JavaElementType.EXPRESSION_LIST) { + return ChildRole.ARGUMENT_LIST; + } + else if (i == JavaElementType.FIELD) { + return ChildRole.FIELD; + } + else if (i == JavaElementType.METHOD) { + return ChildRole.METHOD; + } + else if (i == JavaElementType.CLASS_INITIALIZER) { + return ChildRole.CLASS_INITIALIZER; + } + else if (i == JavaTokenType.LBRACE) { + return getChildRole(child, ChildRole.LBRACE); + } + else if (i == JavaTokenType.RBRACE) { + return getChildRole(child, ChildRole.RBRACE); + } + else { + return ChildRole.NONE; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassElement.java new file mode 100644 index 00000000000..ec8a574f23f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassElement.java @@ -0,0 +1,284 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.CharTable; + +public class ClassElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ClassElement"); + + public ClassElement(IElementType type) { + super(type); + } + + public int getTextOffset() { + TreeElement name = findChildByRole(ChildRole.NAME); + if (name != null) { + return name.getTextOffset(); + } + else { + return super.getTextOffset(); + } + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + + PsiClass psiClass = (PsiClass)SourceTreeToPsiMap.treeElementToPsi(this); + if (anchor == null) { + if (before == null) { + if (first == last) { + PsiElement firstPsi = SourceTreeToPsiMap.treeElementToPsi(first); + PsiElement psiElement = firstPsi instanceof PsiMember ? CodeEditUtil.getDefaultAnchor(psiClass, (PsiMember)firstPsi) : null; + anchor = psiElement != null ? SourceTreeToPsiMap.psiElementToTree(psiElement) : null; + } + else { + anchor = findChildByRole(ChildRole.RBRACE); + } + before = Boolean.TRUE; + } + else if (!before.booleanValue()) { + anchor = findChildByRole(ChildRole.LBRACE); + } + else { + anchor = findChildByRole(ChildRole.RBRACE); + } + } + + if (isEnum()) { + if (!ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET.isInSet(first.getElementType())) { + TreeElement semicolonPlace = findEnumConstantListDelimiterPlace(); + if (semicolonPlace.getElementType() != SEMICOLON) { + final LeafElement semicolon = Factory.createSingleLeafElement(SEMICOLON, new char[]{';'}, 0, 1, + SharedImplUtil.findCharTableByTree(this), getManager()); + addInternal(semicolon, semicolon, semicolonPlace, Boolean.FALSE); + semicolonPlace = semicolon; + } + for (TreeElement run = anchor; run != null; run = run.getTreeNext()) { + if (run == semicolonPlace) { + anchor = before.booleanValue() ? semicolonPlace.getTreeNext() : semicolonPlace; + break; + } + } + } + } + + TreeElement afterLast = last.getTreeNext(); + TreeElement next; + for (TreeElement child = first; child != afterLast; child = next) { + next = child.getTreeNext(); + if (child.getElementType() == ElementType.METHOD && ((PsiMethod)SourceTreeToPsiMap.treeElementToPsi(child)).isConstructor()) { + TreeElement oldIdentifier = ((CompositeElement)child).findChildByRole(ChildRole.NAME); + TreeElement newIdentifier = (TreeElement)findChildByRole(ChildRole.NAME).clone(); + newIdentifier.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(this)); + ChangeUtil.replaceChild((CompositeElement)child, oldIdentifier, newIdentifier); + } + } + + if (psiClass.isEnum()) { + for (TreeElement child = first; child != afterLast; child = next) { + next = child.getTreeNext(); + if ((child.getElementType() == ElementType.METHOD && ((PsiMethod)SourceTreeToPsiMap.treeElementToPsi(child)).isConstructor()) || + child.getElementType() == ElementType.ENUM_CONSTANT) { + CompositeElement modifierList = (CompositeElement)((CompositeElement)child).findChildByRole(ChildRole.MODIFIER_LIST); + while (true) { + TreeElement modifier = TreeUtil.findChild(modifierList, MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET); + if (modifier == null) break; + modifierList.deleteChildInternal(modifier); + } + } + } + } + else if (psiClass.isInterface()) { + for (TreeElement child = first; child != afterLast; child = next) { + next = child.getTreeNext(); + if (child.getElementType() == ElementType.METHOD || child.getElementType() == ElementType.FIELD) { + CompositeElement modifierList = (CompositeElement)((CompositeElement)child).findChildByRole(ChildRole.MODIFIER_LIST); + while (true) { + TreeElement modifier = TreeUtil.findChild(modifierList, MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET); + if (modifier == null) break; + modifierList.deleteChildInternal(modifier); + } + } + } + } + + return super.addInternal(first, last, anchor, before); + } + + public boolean isEnum() { + final TreeElement keyword = findChildByRole(ChildRole.CLASS_OR_INTERFACE_KEYWORD); + return keyword != null && keyword.getElementType() == ENUM_KEYWORD; + } + + public boolean isAnnotationType() { + return findChildByRole(ChildRole.AT) != null; + } + + private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET = TokenSet.create(new IElementType[]{ + PUBLIC_KEYWORD, ABSTRACT_KEYWORD, + STATIC_KEYWORD, FINAL_KEYWORD, + NATIVE_KEYWORD + }); + + private static final TokenSet MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET = TokenSet.create(new IElementType[]{ + PUBLIC_KEYWORD, FINAL_KEYWORD + }); + + private static final TokenSet ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET = TokenSet.create(new IElementType[]{ + ENUM_CONSTANT, COMMA, SEMICOLON + }); + + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch (role) { + default: + return null; + + case ChildRole.DOC_COMMENT: + if (firstChild.getElementType() == DOC_COMMENT) { + return firstChild; + } + else { + return null; + } + + case ChildRole.ENUM_CONSTANT_LIST_DELIMITER: + if (!isEnum()) { + return null; + } + return findEnumConstantListDelimiter(); + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, MODIFIER_LIST); + + case ChildRole.EXTENDS_LIST: + if (isAnnotationType() || isEnum()) return null; + return TreeUtil.findChild(this, EXTENDS_LIST); + + case ChildRole.IMPLEMENTS_LIST: + return TreeUtil.findChild(this, IMPLEMENTS_LIST); + + case ChildRole.TYPE_PARAMETER_LIST: + return TreeUtil.findChild(this, TYPE_PARAMETER_LIST); + + case ChildRole.CLASS_OR_INTERFACE_KEYWORD: + for (TreeElement child = firstChild; child != null; child = child.getTreeNext()) { + if (CLASS_KEYWORD_BIT_SET.isInSet(child.getElementType())) return child; + } + LOG.assertTrue(false); + return null; + + case ChildRole.NAME: + return TreeUtil.findChild(this, IDENTIFIER); + + case ChildRole.LBRACE: + return TreeUtil.findChild(this, LBRACE); + + case ChildRole.RBRACE: + return TreeUtil.findChildBackward(this, RBRACE); + + case ChildRole.AT: + return TreeUtil.findChild(this, AT); + } + } + + private TreeElement findEnumConstantListDelimiter() { + TreeElement candidate = findEnumConstantListDelimiterPlace(); + return candidate.getElementType() == SEMICOLON ? candidate : null; + } + + private TreeElement findEnumConstantListDelimiterPlace() { + final TreeElement first = findChildByRole(ChildRole.LBRACE); + if (first == null) return null; + for (TreeElement child = first.getTreeNext(); ; child = child.getTreeNext()) { + final IElementType childType = child.getElementType(); + if (WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(childType) || + childType == ERROR_ELEMENT || childType == ENUM_CONSTANT) continue; + else if (childType == COMMA) continue; + else if (childType == SEMICOLON) return child; + else { + return TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == SEMICOLON) { + if (!isEnum()) return ChildRole.NONE; + if (child == findEnumConstantListDelimiter()) { + return ChildRole.ENUM_CONSTANT_LIST_DELIMITER; + } + else { + return ChildRole.NONE; + } + } + else if (i == CLASS) { + return ChildRole.CLASS; + } + else if (i == FIELD) { + return ChildRole.FIELD; + } + else if (i == METHOD || i == ANNOTATION_METHOD) { + return ChildRole.METHOD; + } + else if (i == CLASS_INITIALIZER) { + return ChildRole.CLASS_INITIALIZER; + } + else if (i == TYPE_PARAMETER_LIST) { + return ChildRole.TYPE_PARAMETER_LIST; + } + else if (i == DOC_COMMENT) { + return getChildRole(child, ChildRole.DOC_COMMENT); + } + else if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) { + { + if (TreeUtil.skipElementsBack(child, WHITE_SPACE_OR_COMMENT_BIT_SET) == null) { + return ChildRole.PRECEDING_COMMENT; + } + else { + return ChildRole.NONE; + } + } + } + else if (i == MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == EXTENDS_LIST) { + return ChildRole.EXTENDS_LIST; + } + else if (i == IMPLEMENTS_LIST) { + return ChildRole.IMPLEMENTS_LIST; + } + else if (i == CLASS_KEYWORD || i == INTERFACE_KEYWORD || i == ENUM_KEYWORD) { + return getChildRole(child, ChildRole.CLASS_OR_INTERFACE_KEYWORD); + } + else if (i == IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == LBRACE) { + return getChildRole(child, ChildRole.LBRACE); + } + else if (i == RBRACE) { + return getChildRole(child, ChildRole.RBRACE); + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == AT) { + return ChildRole.AT; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassInitializerElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassInitializerElement.java new file mode 100644 index 00000000000..c14435024d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ClassInitializerElement.java @@ -0,0 +1,51 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; + +public class ClassInitializerElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ClassInitializerElement"); + + public ClassInitializerElement() { + super(CLASS_INITIALIZER); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, MODIFIER_LIST); + + case ChildRole.METHOD_BODY: + return TreeUtil.findChild(this, CODE_BLOCK); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) { + { + if (TreeUtil.skipElementsBack(child, WHITE_SPACE_OR_COMMENT_BIT_SET) == null) { + return ChildRole.PRECEDING_COMMENT; + } + else { + return ChildRole.NONE; + } + } + } + else if (i == MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == CODE_BLOCK) { + return ChildRole.METHOD_BODY; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantElement.java new file mode 100644 index 00000000000..5b0b486d0f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantElement.java @@ -0,0 +1,81 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +/** + * @author dsl + */ +public class EnumConstantElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.EnumConstantElement"); + public EnumConstantElement() { + super(ENUM_CONSTANT); + } + + public int getTextOffset() { + return findChildByRole(ChildRole.NAME).getTextOffset(); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.DOC_COMMENT: + if (firstChild.getElementType() == JavaTokenType.DOC_COMMENT){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.NAME: + return TreeUtil.findChild(this, JavaTokenType.IDENTIFIER); + + case ChildRole.ARGUMENT_LIST: + return TreeUtil.findChild(this, EXPRESSION_LIST); + + case ChildRole.ANONYMOUS_CLASS: + return TreeUtil.findChild(this, ENUM_CONSTANT_INITIALIZER); + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, JavaElementType.MODIFIER_LIST); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JavaTokenType.DOC_COMMENT) { + return getChildRole(child, ChildRole.DOC_COMMENT); + } + else if (i == JavaTokenType.C_STYLE_COMMENT || i == JavaTokenType.END_OF_LINE_COMMENT) { + { + if (TreeUtil.skipElementsBack(child, ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET) == null) { + return ChildRole.PRECEDING_COMMENT; + } + else { + return ChildRole.NONE; + } + } + } + else if (i == JavaTokenType.IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == ENUM_CONSTANT_INITIALIZER) { + return ChildRole.ANONYMOUS_CLASS; + } + else if (i == EXPRESSION_LIST) { + return ChildRole.ARGUMENT_LIST; + } + else if (i == MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantInitializerElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantInitializerElement.java new file mode 100644 index 00000000000..f82e406eca9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/EnumConstantInitializerElement.java @@ -0,0 +1,13 @@ +/* + * Created by IntelliJ IDEA. + * User: ven + * Date: Jun 10, 2004 + * Time: 8:05:56 PM + */ +package com.intellij.psi.impl.source.tree.java; + +public class EnumConstantInitializerElement extends AnonymousClassElementBase { + public EnumConstantInitializerElement() { + super(ENUM_CONSTANT_INITIALIZER); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ExtendsListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ExtendsListElement.java new file mode 100644 index 00000000000..4be7ea6860a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ExtendsListElement.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author dsl + */ +public class ExtendsListElement extends ReferenceListElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ExtendsListElement"); + + public ExtendsListElement() { + super(EXTENDS_LIST); + } + + protected String getKeywordText() { + return PsiKeyword.EXTENDS; + } + + protected IElementType getKeywordType() { + return EXTENDS_KEYWORD; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.EXTENDS_KEYWORD: + return TreeUtil.findChild(this, EXTENDS_KEYWORD); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == EXTENDS_KEYWORD) { + return ChildRole.EXTENDS_KEYWORD; + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.REFERENCE_IN_LIST; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/FieldElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/FieldElement.java new file mode 100644 index 00000000000..8031e1f7deb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/FieldElement.java @@ -0,0 +1,101 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class FieldElement extends RepositoryTreeElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.FieldElement"); + + public FieldElement() { + super(FIELD); + } + + public int getTextOffset() { + return findChildByRole(ChildRole.NAME).getTextOffset(); + } + + public void deleteChildInternal(TreeElement child) { + if (getChildRole(child) == ChildRole.INITIALIZER){ + TreeElement eq = findChildByRole(ChildRole.INITIALIZER_EQ); + if (eq != null){ + deleteChildInternal(eq); + } + } + super.deleteChildInternal(child); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.DOC_COMMENT: + if (firstChild.getElementType() == JavaTokenType.DOC_COMMENT){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, JavaElementType.MODIFIER_LIST); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, JavaElementType.TYPE); + + case ChildRole.NAME: + return TreeUtil.findChild(this, JavaTokenType.IDENTIFIER); + + case ChildRole.INITIALIZER_EQ: + return TreeUtil.findChild(this, JavaTokenType.EQ); + + case ChildRole.INITIALIZER: + return TreeUtil.findChild(this, ElementType.EXPRESSION_BIT_SET); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, JavaTokenType.SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JavaTokenType.DOC_COMMENT) { + return getChildRole(child, ChildRole.DOC_COMMENT); + } + else if (i == JavaTokenType.C_STYLE_COMMENT || i == JavaTokenType.END_OF_LINE_COMMENT) { + { + if (TreeUtil.skipElementsBack(child, ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET) == null) { + return ChildRole.PRECEDING_COMMENT; + } + else { + return ChildRole.NONE; + } + } + } + else if (i == JavaElementType.MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == JavaElementType.TYPE) { + return getChildRole(child, ChildRole.TYPE); + } + else if (i == JavaTokenType.IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == JavaTokenType.EQ) { + return getChildRole(child, ChildRole.INITIALIZER_EQ); + } + else if (i == JavaTokenType.SEMICOLON) { + return getChildRole(child, ChildRole.CLOSING_SEMICOLON); + } + else { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.INITIALIZER; + } + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImplementsListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImplementsListElement.java new file mode 100644 index 00000000000..6a7adf594e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImplementsListElement.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.impl.source.tree.TreeElement; + +/** + * @author dsl + */ +public class ImplementsListElement extends ReferenceListElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ImplementsListElement"); + + public ImplementsListElement() { + super(IMPLEMENTS_LIST); + } + + protected String getKeywordText() { + return PsiKeyword.IMPLEMENTS; + } + + protected IElementType getKeywordType() { + return IMPLEMENTS_KEYWORD; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.EXTENDS_KEYWORD: + return TreeUtil.findChild(this, EXTENDS_KEYWORD); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == IMPLEMENTS_KEYWORD) { + return ChildRole.IMPLEMENTS_KEYWORD; + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.REFERENCE_IN_LIST; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportListElement.java new file mode 100644 index 00000000000..cdcea30a913 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportListElement.java @@ -0,0 +1,29 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.PsiImportList; +import com.intellij.psi.PsiImportStatementBase; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ImportListElement extends RepositoryTreeElement{ + public ImportListElement() { + super(IMPORT_LIST); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before){ + ChameleonTransforming.transformChildren(this); + if (before == null){ + if (first == last && (first.getElementType() == ElementType.IMPORT_STATEMENT || first.getElementType() == ElementType.IMPORT_STATIC_STATEMENT)){ + anchor = CodeEditUtil.getDefaultAnchor((PsiImportList)SourceTreeToPsiMap.treeElementToPsi(this), + (PsiImportStatementBase)SourceTreeToPsiMap.treeElementToPsi(first)); + before = Boolean.TRUE; + } + } + return super.addInternal(first, last, anchor, before); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementBaseElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementBaseElement.java new file mode 100644 index 00000000000..5b0e889ecd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementBaseElement.java @@ -0,0 +1,58 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; + +/** + * @author dsl + */ +public class ImportStatementBaseElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ImportStatementBaseElement"); + public ImportStatementBaseElement(IElementType type) { + super(type); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.IMPORT_KEYWORD: + return firstChild; + + case ChildRole.IMPORT_ON_DEMAND_DOT: + return TreeUtil.findChild(this, DOT); + + case ChildRole.IMPORT_ON_DEMAND_ASTERISK: + return TreeUtil.findChild(this, ASTERISK); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == IMPORT_KEYWORD) { + return ChildRole.IMPORT_KEYWORD; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.IMPORT_REFERENCE; + } + else if (i == DOT) { + return ChildRole.IMPORT_ON_DEMAND_DOT; + } + else if (i == ASTERISK) { + return ChildRole.IMPORT_ON_DEMAND_ASTERISK; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementElement.java new file mode 100644 index 00000000000..60373b0808d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStatementElement.java @@ -0,0 +1,24 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.*; + +public class ImportStatementElement extends ImportStatementBaseElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ImportStatementElement"); + + public ImportStatementElement() { + super(IMPORT_STATEMENT); + } + + + public TreeElement findChildByRole(int role) { + final TreeElement result = super.findChildByRole(role); + if (result != null) return result; + switch (role) { + default: + return null; + case ChildRole.IMPORT_REFERENCE: + return TreeUtil.findChild(this, JAVA_CODE_REFERENCE); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStaticStatementElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStaticStatementElement.java new file mode 100644 index 00000000000..0d107f5f4d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ImportStaticStatementElement.java @@ -0,0 +1,43 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class ImportStaticStatementElement extends ImportStatementBaseElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ImportStatementElement"); + + public ImportStaticStatementElement() { + super(IMPORT_STATIC_STATEMENT); + } + + public TreeElement findChildByRole(int role) { + final TreeElement result = super.findChildByRole(role); + if (result != null) return result; + switch (role) { + default: + return null; + + case ChildRole.IMPORT_REFERENCE: + final TreeElement importStaticReference = TreeUtil.findChild(this, IMPORT_STATIC_REFERENCE); + if (importStaticReference != null) { + return importStaticReference; + } + else { + return TreeUtil.findChild(this, JAVA_CODE_REFERENCE); + } + } + } + + public int getChildRole(TreeElement child) { + final int role = super.getChildRole(child); + if (role != ChildRole.NONE) return role; + if (child.getElementType() == IMPORT_STATIC_REFERENCE) { + return ChildRole.IMPORT_REFERENCE; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/JavaFileElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/JavaFileElement.java new file mode 100644 index 00000000000..899933ae4d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/JavaFileElement.java @@ -0,0 +1,74 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.IncorrectOperationException; + +public class JavaFileElement extends FileElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.JavaFileElement"); + + public JavaFileElement() { + super(JAVA_FILE); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + if (before == null && first == last && first.getElementType() == ElementType.PACKAGE_STATEMENT){ //? + anchor = firstChild; + before = Boolean.TRUE; + } + return super.addInternal(first, last, anchor, before); + } + + public void deleteChildInternal(TreeElement child){ + if (child.getElementType() == CLASS){ + PsiJavaFile file = (PsiJavaFile)SourceTreeToPsiMap.treeElementToPsi(this); + if (file.getClasses().length == 1){ + try{ + file.delete(); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + return; + } + } + super.deleteChildInternal(child); + } + + public TreeElement findChildByRole(int role) { + ChameleonTransforming.transformChildren(this); + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.PACKAGE_STATEMENT: + return TreeUtil.findChild(this, PACKAGE_STATEMENT); + + case ChildRole.IMPORT_LIST: + return TreeUtil.findChild(this, IMPORT_LIST); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == PACKAGE_STATEMENT) { + return ChildRole.PACKAGE_STATEMENT; + } + else if (i == IMPORT_LIST) { + return ChildRole.IMPORT_LIST; + } + else if (i == CLASS) { + return ChildRole.CLASS; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/MethodElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/MethodElement.java new file mode 100644 index 00000000000..66c935b1add --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/MethodElement.java @@ -0,0 +1,126 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; + +public class MethodElement extends RepositoryTreeElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.MethodElement"); + + public MethodElement() { + super(METHOD); + } + + protected MethodElement(IElementType type) { + super(type); + } + + public int getTextOffset() { + return findChildByRole(ChildRole.NAME).getTextOffset(); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + if (first == last && first.getElementType() == ElementType.CODE_BLOCK){ + TreeElement semicolon = findChildByRole(ChildRole.CLOSING_SEMICOLON); + if (semicolon != null){ + deleteChildInternal(semicolon); + } + } + return super.addInternal(first, last, anchor, before); + } + + public void deleteChildInternal(TreeElement child) { + super.deleteChildInternal(child); + if (child.getElementType() == CODE_BLOCK){ + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + LeafElement semicolon = Factory.createSingleLeafElement(SEMICOLON, new char[]{';'}, 0, 1, treeCharTab, getManager()); + this.addInternal(semicolon, semicolon, null, Boolean.TRUE); + } + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.DOC_COMMENT: + if (firstChild.getElementType() == DOC_COMMENT){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, MODIFIER_LIST); + + case ChildRole.TYPE_PARAMETER_LIST: + return TreeUtil.findChild(this, TYPE_PARAMETER_LIST); + + case ChildRole.NAME: + return TreeUtil.findChild(this, IDENTIFIER); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, TYPE); + + case ChildRole.METHOD_BODY: + return TreeUtil.findChild(this, CODE_BLOCK); + + case ChildRole.PARAMETER_LIST: + return TreeUtil.findChild(this, PARAMETER_LIST); + + case ChildRole.THROWS_LIST: + return TreeUtil.findChild(this, THROWS_LIST); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DOC_COMMENT) { + return getChildRole(child, ChildRole.DOC_COMMENT); + } + else if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) { + { + if (TreeUtil.skipElementsBack(child, WHITE_SPACE_OR_COMMENT_BIT_SET) == null) { + return ChildRole.PRECEDING_COMMENT; + } + else { + return ChildRole.NONE; + } + } + } + else if (i == MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == TYPE_PARAMETER_LIST) { + return ChildRole.TYPE_PARAMETER_LIST; + } + else if (i == CODE_BLOCK) { + return ChildRole.METHOD_BODY; + } + else if (i == PARAMETER_LIST) { + return ChildRole.PARAMETER_LIST; + } + else if (i == THROWS_LIST) { + return ChildRole.THROWS_LIST; + } + else if (i == TYPE) { + return getChildRole(child, ChildRole.TYPE); + } + else if (i == IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == SEMICOLON) { + return getChildRole(child, ChildRole.CLOSING_SEMICOLON); + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ModifierListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ModifierListElement.java new file mode 100644 index 00000000000..c3924452e90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ModifierListElement.java @@ -0,0 +1,33 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.PsiModifierList; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.openapi.diagnostic.Logger; + +public class ModifierListElement extends RepositoryTreeElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ModifierListElement"); + + public ModifierListElement() { + super(MODIFIER_LIST); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + if (before == null){ + if (first == last && ElementType.KEYWORD_BIT_SET.isInSet(first.getElementType())){ + anchor = CodeEditUtil.getDefaultAnchor((PsiModifierList)SourceTreeToPsiMap.treeElementToPsi(this), + (PsiKeyword)SourceTreeToPsiMap.treeElementToPsi(first)); + before = Boolean.TRUE; + } + } + return super.addInternal(first, last, anchor, before); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == JavaElementType.ANNOTATION) return ChildRole.ANNOTATION; + return ChildRole.NONE; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterElement.java new file mode 100644 index 00000000000..57c24ad2e3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterElement.java @@ -0,0 +1,58 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class ParameterElement extends RepositoryTreeElement{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterElement"); + + public ParameterElement() { + super(PARAMETER); + } + + protected ParameterElement(IElementType type) { + super(type); + } + + public int getTextOffset() { + return findChildByRole(ChildRole.NAME).getTextOffset(); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, JavaElementType.MODIFIER_LIST); + + case ChildRole.NAME: + return TreeUtil.findChild(this, JavaTokenType.IDENTIFIER); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, JavaElementType.TYPE); + + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JavaElementType.MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == JavaElementType.TYPE) { + return getChildRole(child, ChildRole.TYPE); + } + else if (i == JavaTokenType.IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else { + return ChildRole.NONE; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterListElement.java new file mode 100644 index 00000000000..d275437acbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ParameterListElement.java @@ -0,0 +1,130 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; + +public class ParameterListElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterListElement"); + + public ParameterListElement() { + super(PARAMETER_LIST); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + if (anchor == null) { + if (before == null || before.booleanValue()) { + anchor = findChildByRole(ChildRole.RPARENTH); + before = Boolean.TRUE; + } + else { + anchor = findChildByRole(ChildRole.LPARENTH); + before = Boolean.FALSE; + } + } + TreeElement firstAdded = super.addInternal(first, last, anchor, before); + if (first == last && first.getElementType() == PARAMETER) { + TreeElement element = first; + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + for (TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()) { + if (child.getElementType() == COMMA) break; + if (child.getElementType() == PARAMETER) { + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for (TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()) { + if (child.getElementType() == COMMA) break; + if (child.getElementType() == PARAMETER) { + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + + //todo[max] hack? + try { + CodeStyleManager.getInstance(getManager().getProject()).reformat(getPsiElement()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return firstAdded; + } + + public void deleteChildInternal(TreeElement child) { + if (child.getElementType() == PARAMETER) { + TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == COMMA) { + deleteChildInternal(next); + } + else { + TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null && prev.getElementType() == COMMA) { + deleteChildInternal(prev); + } + } + } + super.deleteChildInternal(child); + + //todo[max] hack? + try { + CodeStyleManager.getInstance(getManager().getProject()).reformat(getPsiElement()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + ChameleonTransforming.transformChildren(this); + switch (role) { + default: + return null; + + case ChildRole.LPARENTH: + if (firstChild.getElementType() == LPARENTH) { + return firstChild; + } + else { + return null; + } + + case ChildRole.RPARENTH: + if (lastChild.getElementType() == RPARENTH) { + return lastChild; + } + else { + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == PARAMETER) { + return ChildRole.PARAMETER; + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LPARENTH) { + return getChildRole(child, ChildRole.LPARENTH); + } + else if (i == RPARENTH) { + return getChildRole(child, ChildRole.RPARENTH); + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java new file mode 100644 index 00000000000..1432d41efe9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java @@ -0,0 +1,70 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.impl.PsiImplUtil; + +/** + * @author ven + */ +public class PsiAnnotationImpl extends CompositePsiElement implements PsiModifier, PsiAnnotation { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl"); + + public PsiAnnotationImpl() { + super(ANNOTATION); + } + + public PsiJavaCodeReferenceElement getNameReferenceElement() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.CLASS_REFERENCE); + } + + public PsiAnnotationMemberValue findAttributeValue(String attributeName) { + return PsiImplUtil.findAttributeValue(this, attributeName); + } + + public String toString() { + return "PsiAnnotation"; + } + + public PsiAnnotationParameterList getParameterList() { + return (PsiAnnotationParameterList)findChildByRoleAsPsiElement(ChildRole.PARAMETER_LIST); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + + IElementType i = child.getElementType(); + if (i == ANNOTATION_PARAMETER_LIST) { + return ChildRole.PARAMETER_LIST; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.CLASS_REFERENCE; + } + else { + return ChildRole.NONE; + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch (role) { + default: + return null; + + case ChildRole.PARAMETER_LIST: + return TreeUtil.findChild(this, ANNOTATION_PARAMETER_LIST); + + case ChildRole.CLASS_REFERENCE: + return TreeUtil.findChild(this, JAVA_CODE_REFERENCE); + } + } + + public final void accept(PsiElementVisitor visitor) { + visitor.visitAnnotation(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationParameterListImpl.java new file mode 100644 index 00000000000..c0bb27ffa18 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAnnotationParameterListImpl.java @@ -0,0 +1,77 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiAnnotationParameterList; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiNameValuePair; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +/** + * @author ven + */ +public class PsiAnnotationParameterListImpl extends CompositePsiElement implements PsiAnnotationParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAnnotationParameterListImpl"); + private PsiNameValuePair[] myCachedMembers = null; + + public PsiAnnotationParameterListImpl() { + super(ANNOTATION_PARAMETER_LIST); + } + + public void clearCaches() { + super.clearCaches(); + myCachedMembers = null; + } + + public PsiNameValuePair[] getAttributes() { + if (myCachedMembers == null) { + myCachedMembers = (PsiNameValuePair[])getChildrenAsPsiElements(NAME_VALUE_PAIR_BIT_SET, PSI_NAME_VALUE_PAIR_ARRAY_CONSTRUCTOR); + } + + return myCachedMembers; + } + + public int getChildRole(TreeElement child) { + IElementType i = child.getElementType(); + if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (ANNOTATION_MEMBER_VALUE_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.ANNOTATION_VALUE; + } + else { + return ChildRole.NONE; + } + } + } + + public TreeElement findChildByRole(int role) { + switch (role) { + default: + LOG.assertTrue(false); + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + } + } + + public String toString() { + return "PsiAnnotationParameterList"; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAnnotationParameterList(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayAccessExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayAccessExpressionImpl.java new file mode 100644 index 00000000000..bc7ee6e3ef9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayAccessExpressionImpl.java @@ -0,0 +1,88 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiArrayAccessExpressionImpl extends CompositePsiElement implements PsiArrayAccessExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiArrayAccessExpressionImpl"); + + public PsiArrayAccessExpressionImpl() { + super(ARRAY_ACCESS_EXPRESSION); + } + + public PsiExpression getArrayExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.ARRAY); + } + + public PsiExpression getIndexExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.INDEX); + } + + public PsiType getType() { + PsiType arrayType = getArrayExpression().getType(); + if (!(arrayType instanceof PsiArrayType)) return null; + return ((PsiArrayType)arrayType).getComponentType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.ARRAY: + return firstChild; + + case ChildRole.INDEX: + { + TreeElement lbracket = findChildByRole(ChildRole.LBRACKET); + if (lbracket == null) return null; + for(TreeElement child = lbracket.getTreeNext(); child != null; child = child.getTreeNext()){ + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())){ + return child; + } + } + return null; + } + + case ChildRole.LBRACKET: + return TreeUtil.findChild(this, LBRACKET); + + case ChildRole.RBRACKET: + return TreeUtil.findChild(this, RBRACKET); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == LBRACKET) { + return ChildRole.LBRACKET; + } + else if (i == RBRACKET) { + return ChildRole.RBRACKET; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return child == firstChild ? ChildRole.ARRAY : ChildRole.INDEX; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitArrayAccessExpression(this); + } + + public String toString() { + return "PsiArrayAccessExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java new file mode 100644 index 00000000000..35d4f7752cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerExpressionImpl.java @@ -0,0 +1,84 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiArrayInitializerExpressionImpl extends CompositePsiElement implements PsiArrayInitializerExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiArrayInitializerExpressionImpl"); + + public PsiArrayInitializerExpressionImpl() { + super(ARRAY_INITIALIZER_EXPRESSION); + } + + public PsiExpression[] getInitializers(){ + return (PsiExpression[])getChildrenAsPsiElements(EXPRESSION_BIT_SET, PSI_EXPRESSION_ARRAY_CONSTRUCTOR); + } + + public PsiType getType(){ + if (getTreeParent() instanceof PsiNewExpression){ + if (getTreeParent().getChildRole(this) == ChildRole.ARRAY_INITIALIZER){ + return ((PsiNewExpression)getTreeParent()).getType(); + } + } + else if (getTreeParent() instanceof PsiVariable){ + return ((PsiVariable)getTreeParent()).getType(); + } + else if (getTreeParent() instanceof PsiArrayInitializerExpression){ + PsiType parentType = ((PsiArrayInitializerExpression)getTreeParent()).getType(); + if (!(parentType instanceof PsiArrayType)) return null; + return ((PsiArrayType) parentType).getComponentType(); + } + else if (getTreeParent() instanceof FieldElement){ + return ((PsiField)getParent()).getType(); + } + + return null; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.LBRACE: + return TreeUtil.findChild(this, LBRACE); + + case ChildRole.RBRACE: + return TreeUtil.findChild(this, RBRACE); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LBRACE) { + return ChildRole.LBRACE; + } + else if (i == RBRACE) { + return ChildRole.RBRACE; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.EXPRESSION_IN_LIST; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitArrayInitializerExpression(this); + } + + public String toString(){ + return "PsiArrayInitializerExpression:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java new file mode 100644 index 00000000000..2f36aa8ae72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java @@ -0,0 +1,65 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiAnnotationMemberValue; +import com.intellij.psi.PsiArrayInitializerMemberValue; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +/** + * @author ven + */ +public class PsiArrayInitializerMemberValueImpl extends CompositePsiElement implements PsiArrayInitializerMemberValue { + private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.source.tree.java.PsiArrayInitializerMemberValueImpl"); + public PsiArrayInitializerMemberValueImpl() { + super(ANNOTATION_ARRAY_INITIALIZER); + } + + public PsiAnnotationMemberValue[] getInitializers() { + return (PsiAnnotationMemberValue[])getChildrenAsPsiElements(ANNOTATION_MEMBER_VALUE_BIT_SET, + PSI_ANNOTATION_MEMBER_VALUE_ARRAY_CONSTRUCTOR); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.LBRACE: + return TreeUtil.findChild(this, LBRACE); + + case ChildRole.RBRACE: + return TreeUtil.findChild(this, RBRACE); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LBRACE) { + return ChildRole.LBRACE; + } + else if (i == RBRACE) { + return ChildRole.RBRACE; + } + else { + if (ANNOTATION_MEMBER_VALUE_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.ANNOTATION_VALUE; + } + return ChildRole.NONE; + } + } + + public String toString(){ + return "PsiArrayInitializerMemerValue:" + getText(); + } + + public final void accept(PsiElementVisitor visitor) { + visitor.visitAnnotationArrayInitializer(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssertStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssertStatementImpl.java new file mode 100644 index 00000000000..2339a209873 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssertStatementImpl.java @@ -0,0 +1,88 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiAssertStatement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiAssertStatementImpl extends CompositePsiElement implements PsiAssertStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAssertStatementImpl"); + + public PsiAssertStatementImpl() { + super(ASSERT_STATEMENT); + } + + public PsiExpression getAssertCondition() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public PsiExpression getAssertDescription() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.ASSERT_DESCRIPTION); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.ASSERT_KEYWORD: + return TreeUtil.findChild(this, ASSERT_KEYWORD); + + case ChildRole.CONDITION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.COLON: + return TreeUtil.findChild(this, COLON); + + case ChildRole.ASSERT_DESCRIPTION: + { + TreeElement colon = findChildByRole(ChildRole.COLON); + if (colon == null) return null; + TreeElement child; + for(child = colon.getTreeNext(); child != null; child = child.getTreeNext()){ + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) break; + } + return child; + } + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChild(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == ASSERT_KEYWORD) { + return ChildRole.ASSERT_KEYWORD; + } + else if (i == COLON) { + return ChildRole.COLON; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + int role = getChildRole(child, ChildRole.CONDITION); + if (role != ChildRole.NONE) return role; + return ChildRole.ASSERT_DESCRIPTION; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitAssertStatement(this); + } + + public String toString() { + return "PsiAssertStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssignmentExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssignmentExpressionImpl.java new file mode 100644 index 00000000000..764f9cf1ccc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiAssignmentExpressionImpl.java @@ -0,0 +1,78 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.impl.source.tree.*; + +public class PsiAssignmentExpressionImpl extends CompositePsiElement implements PsiAssignmentExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAssignmentExpressionImpl"); + + public PsiAssignmentExpressionImpl() { + super(ASSIGNMENT_EXPRESSION); + } + + public PsiExpression getLExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.LOPERAND); + } + + public PsiExpression getRExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.ROPERAND); + } + + public PsiJavaToken getOperationSign() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.OPERATION_SIGN); + } + + public PsiType getType() { + return getLExpression().getType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch (role) { + default: + return null; + + case ChildRole.LOPERAND: + return firstChild; + + case ChildRole.ROPERAND: + return EXPRESSION_BIT_SET.isInSet(lastChild.getElementType()) ? lastChild : null; + + case ChildRole.OPERATION_SIGN: + return TreeUtil.findChild(this, OUR_OPERATIONS_BIT_SET); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + if (child == firstChild) return ChildRole.LOPERAND; + if (child == lastChild) return ChildRole.ROPERAND; + return ChildRole.NONE; + } + else if (OUR_OPERATIONS_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.OPERATION_SIGN; + } + else { + return ChildRole.NONE; + } + } + + private static final TokenSet OUR_OPERATIONS_BIT_SET = TokenSet.create(new IElementType[]{ + EQ, ASTERISKEQ, DIVEQ, PERCEQ, + PLUSEQ, MINUSEQ, LTLTEQ, GTGTEQ, + GTGTGTEQ, ANDEQ, OREQ, XOREQ + }); + + public void accept(PsiElementVisitor visitor) { + visitor.visitAssignmentExpression(this); + } + + public String toString() { + return "PsiAssignmentExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java new file mode 100644 index 00000000000..049390f2856 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java @@ -0,0 +1,130 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiBinaryExpressionImpl extends CompositePsiElement implements PsiBinaryExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiBinaryExpressionImpl"); + + public PsiBinaryExpressionImpl() { + super(BINARY_EXPRESSION); + } + + public PsiExpression getLOperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.LOPERAND); + } + + public PsiExpression getROperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.ROPERAND); + } + + public PsiJavaToken getOperationSign() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.OPERATION_SIGN); + } + + public PsiType getType() { + PsiExpression lOperand = getLOperand(); + PsiExpression rOperand = getROperand(); + if (rOperand == null) return null; + PsiType type1 = lOperand.getType(); + PsiType type2 = rOperand.getType(); + + IElementType i = (SourceTreeToPsiMap.psiElementToTree(getOperationSign())).getElementType(); + if (i == PLUS) { + if (type1 == null || type2 == null) return null; + if (type1.equalsToText("java.lang.String") || type2.equalsToText("java.lang.String")) { + return PsiType.getJavaLangString(getManager(), getResolveScope()); + } + + if (type1 == null && type2 == null) return null; + if (type1 == PsiType.DOUBLE || type2 == PsiType.DOUBLE) return PsiType.DOUBLE; + if (type1 == PsiType.FLOAT || type2 == PsiType.FLOAT) return PsiType.FLOAT; + if (type1 == PsiType.LONG || type2 == PsiType.LONG) return PsiType.LONG; + return PsiType.INT; + } + else if (i == MINUS || i == ASTERISK || i == DIV || i == PERC) { + if (type1 == null && type2 == null) return null; + if (type1 == PsiType.DOUBLE || type2 == PsiType.DOUBLE) return PsiType.DOUBLE; + if (type1 == PsiType.FLOAT || type2 == PsiType.FLOAT) return PsiType.FLOAT; + if (type1 == PsiType.LONG || type2 == PsiType.LONG) return PsiType.LONG; + return PsiType.INT; + } + else if (i == LTLT || i == GTGT || i == GTGTGT) { + if (type1 == PsiType.BYTE || type1 == PsiType.CHAR || type1 == PsiType.SHORT) { + return PsiType.INT; + } + else { + return type1; + } + } + else if (i == EQEQ || i == NE || i == LT || i == GT || i == LE || i == GE || i == OROR || i == ANDAND) { + return PsiType.BOOLEAN; + } + else if (i == OR || i == XOR || i == AND) { + if (type1 == null && type2 == null) return null; + if (type1 == PsiType.BOOLEAN || type2 == PsiType.BOOLEAN) return PsiType.BOOLEAN; + if (type1 == PsiType.LONG || type2 == PsiType.LONG) return PsiType.LONG; + return PsiType.INT; + } + else { + LOG.assertTrue(false); + return null; + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch (role) { + default: + return null; + + case ChildRole.LOPERAND: + return firstChild; + + case ChildRole.ROPERAND: + return EXPRESSION_BIT_SET.isInSet(lastChild.getElementType()) ? lastChild : null; + + case ChildRole.OPERATION_SIGN: + return TreeUtil.findChild(this, OUR_OPERATIONS_BIT_SET); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + if (child == firstChild) return ChildRole.LOPERAND; + if (child == lastChild) return ChildRole.ROPERAND; + return ChildRole.NONE; + } + else if (OUR_OPERATIONS_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.OPERATION_SIGN; + } + else { + return ChildRole.NONE; + } + } + + private static final TokenSet OUR_OPERATIONS_BIT_SET = TokenSet.create(new IElementType[]{ + OROR, ANDAND, OR, XOR, + AND, EQEQ, NE, LT, + GT, LE, GE, LTLT, + GTGT, GTGTGT, PLUS, MINUS, + ASTERISK, DIV, PERC + }); + + public void accept(PsiElementVisitor visitor) { + visitor.visitBinaryExpression(this); + } + + public String toString() { + return "PsiBinaryExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBlockStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBlockStatementImpl.java new file mode 100644 index 00000000000..769b3d9ed44 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBlockStatementImpl.java @@ -0,0 +1,51 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiBlockStatement; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiBlockStatementImpl extends CompositePsiElement implements PsiBlockStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiBlockStatementImpl"); + + public PsiBlockStatementImpl() { + super(BLOCK_STATEMENT); + } + + public PsiCodeBlock getCodeBlock() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.BLOCK); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.BLOCK: + return TreeUtil.findChild(this, CODE_BLOCK); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == CODE_BLOCK) { + return ChildRole.BLOCK; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitBlockStatement(this); + } + + public String toString() { + return "PsiBlockStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBreakStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBreakStatementImpl.java new file mode 100644 index 00000000000..90dae8c17c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiBreakStatementImpl.java @@ -0,0 +1,104 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiLabelReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; + +public class PsiBreakStatementImpl extends CompositePsiElement implements PsiBreakStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiBreakStatementImpl"); + + public PsiBreakStatementImpl() { + super(BREAK_STATEMENT); + } + + public PsiIdentifier getLabelIdentifier() { + return (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.LABEL); + } + + public PsiStatement findExitedStatement() { + PsiIdentifier label = getLabelIdentifier(); + if (label == null){ + for(CompositeElement parent = getTreeParent(); parent != null; parent = parent.getTreeParent()){ + IElementType i = parent.getElementType(); + if (i == FOR_STATEMENT || i == WHILE_STATEMENT || i == DO_WHILE_STATEMENT || i == SWITCH_STATEMENT || i == FOREACH_STATEMENT) { + return (PsiStatement)SourceTreeToPsiMap.treeElementToPsi(parent); + } + else if (i == METHOD || i == CLASS_INITIALIZER) { + return null; // do not pass through anonymous/local class + } + } + } + else{ + String labelName = label.getText(); + for(CompositeElement parent = getTreeParent(); parent != null; parent = parent.getTreeParent()){ + if (parent.getElementType() == LABELED_STATEMENT){ + TreeElement statementLabel = parent.findChildByRole(ChildRole.LABEL_NAME); + if (statementLabel.textMatches(labelName)){ + return ((PsiLabeledStatement)SourceTreeToPsiMap.treeElementToPsi(parent)).getStatement(); + } + } + + if (parent.getElementType() == METHOD || parent.getElementType() == CLASS_INITIALIZER) return null; // do not pass through anonymous/local class + } + } + return null; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.BREAK_KEYWORD: + return TreeUtil.findChild(this, BREAK_KEYWORD); + + case ChildRole.LABEL: + return TreeUtil.findChild(this, IDENTIFIER); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == BREAK_KEYWORD) { + return ChildRole.BREAK_KEYWORD; + } + else if (i == IDENTIFIER) { + return ChildRole.LABEL; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitBreakStatement(this); + } + + public PsiReference getReference() { + final PsiReference[] references = getReferences(); + if (references != null && references.length > 0) + return references[0]; + return null; + } + + public PsiReference[] getReferences() { + if (getLabelIdentifier() == null) + return PsiReference.EMPTY_ARRAY; + return new PsiReference[]{new PsiLabelReference(this, getLabelIdentifier())}; + } + + public String toString() { + return "PsiBreakStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java new file mode 100644 index 00000000000..96d6faf330f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java @@ -0,0 +1,86 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author ven + */ +public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatchSection { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiCatchSectionImpl"); + + public PsiCatchSectionImpl() { + super(CATCH_SECTION); + } + + public PsiParameter getParameter() { + return (PsiParameter)findChildByRoleAsPsiElement(ChildRole.PARAMETER); + } + + public PsiCodeBlock getCatchBlock() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.CATCH_BLOCK); + } + + public PsiType getCatchType() { + PsiParameter parameter = getParameter(); + if (parameter == null) return null; + return parameter.getType(); + } + + public PsiTryStatement getTryStatement() { + return (PsiTryStatement)getParent(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitCatchSection(this); + } + + public String toString() { + return "PsiCatchSection"; + } + + public TreeElement findChildByRole(int role) { + switch(role) { + default: + return null; + + case ChildRole.PARAMETER: + return TreeUtil.findChild(this, PARAMETER); + + case ChildRole.CATCH_KEYWORD: + return TreeUtil.findChild(this, CATCH_KEYWORD); + + case ChildRole.CATCH_BLOCK_PARAMETER_LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.CATCH_BLOCK_PARAMETER_RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.CATCH_BLOCK: + return TreeUtil.findChild(this, CODE_BLOCK); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == PARAMETER) { + return ChildRole.PARAMETER; + } else if (i == CODE_BLOCK) { + return ChildRole.CATCH_BLOCK; + } else if (i == CATCH_KEYWORD) { + return ChildRole.CATCH_KEYWORD; + } else if (i == LPARENTH) { + return ChildRole.CATCH_BLOCK_PARAMETER_LPARENTH; + } else if (i == RPARENTH) { + return ChildRole.CATCH_BLOCK_PARAMETER_RPARENTH; + } + + return ChildRole.NONE; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiClassObjectAccessExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiClassObjectAccessExpressionImpl.java new file mode 100644 index 00000000000..4a8e9502009 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiClassObjectAccessExpressionImpl.java @@ -0,0 +1,72 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClassObjectAccessExpression; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiClassObjectAccessExpressionImpl extends CompositePsiElement implements PsiClassObjectAccessExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiClassObjectAccessExpressionImpl"); + + public PsiClassObjectAccessExpressionImpl() { + super(CLASS_OBJECT_ACCESS_EXPRESSION); + } + + public PsiType getType() { + return PsiImplUtil.getType(this); + } + + public PsiTypeElement getOperand() { + return (PsiTypeElement)findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.TYPE: + return TreeUtil.findChild(this, TYPE); + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + + case ChildRole.CLASS_KEYWORD: + return TreeUtil.findChild(this, CLASS_KEYWORD); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == TYPE) { + return ChildRole.TYPE; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == CLASS_KEYWORD) { + return ChildRole.CLASS_KEYWORD; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitClassObjectAccessExpression(this); + } + + public String toString() { + return "PsiClassObjectAccessExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java new file mode 100644 index 00000000000..41ce69742b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java @@ -0,0 +1,197 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; + +import java.util.HashSet; +import java.util.Set; + +public class PsiCodeBlockImpl extends CompositePsiElement implements PsiCodeBlock, Reparseable { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiCodeBlockImpl"); + + public PsiCodeBlockImpl() { + super(CODE_BLOCK); + } + + public void clearCaches() { + super.clearCaches(); + myProcessed = false; + myConflict = false; + myVariablesSet = null; + myClassesSet = null; + } + + public PsiStatement[] getStatements() { + return (PsiStatement[])getChildrenAsPsiElements(STATEMENT_BIT_SET, PSI_STATEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiJavaToken getLBrace() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.LBRACE); + } + + public PsiJavaToken getRBrace() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.RBRACE); + } + + private Set myVariablesSet = null; + private Set myClassesSet = null; + private boolean myConflict = false; + private boolean myProcessed = false; + + private void buildMaps(){ + if(myProcessed) return; + myProcessed = true; + PsiScopesUtil.walkChildrenScopes(this, new BaseScopeProcessor() { + public boolean execute(PsiElement element, PsiSubstitutor substitutor) { + if(element instanceof PsiLocalVariable){ + final PsiLocalVariable variable = (PsiLocalVariable)element; + final String name = variable.getName(); + if(myVariablesSet == null) + myVariablesSet = new HashSet(); + if(myVariablesSet.contains(name)){ + myConflict = true; + myVariablesSet = null; + myClassesSet = null; + } + else + myVariablesSet.add(name); + } + else if(element instanceof PsiClass){ + final PsiClass psiClass = (PsiClass)element; + final String name = psiClass.getName(); + if(myClassesSet == null) + myClassesSet = new HashSet(); + if(myClassesSet.contains(name)){ + myConflict = true; + myVariablesSet = null; + myClassesSet = null; + } + else myClassesSet.add(name); + } + return !myConflict; + } + }, PsiSubstitutor.EMPTY, this, this); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + if (anchor == null){ + if (before == null || before.booleanValue()){ + anchor = findChildByRole(ChildRole.RBRACE); + before = Boolean.TRUE; + } + else{ + anchor = findChildByRole(ChildRole.LBRACE); + before = Boolean.FALSE; + } + } + return super.addInternal(first, last, anchor, before); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + ChameleonTransforming.transformChildren(this); + switch(role){ + default: + return null; + + case ChildRole.LBRACE: + return TreeUtil.findChild(this, LBRACE); + + case ChildRole.RBRACE: + return TreeUtil.findChildBackward(this, RBRACE); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == LBRACE) { + return getChildRole(child, ChildRole.LBRACE); + } + else if (i == RBRACE) { + return getChildRole(child, ChildRole.RBRACE); + } + else { + if (ElementType.STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.STATEMENT_IN_BLOCK; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitCodeBlock(this); + } + + public String toString() { + return "PsiCodeBlock"; + } + + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null) + // Parent element should not see our vars + return true; + buildMaps(); + final NameHint hint = processor.getHint(NameHint.class); + if(hint != null && !myConflict){ + final ElementClassHint elementClassHint = processor.getHint(ElementClassHint.class); + final String name = hint.getName(); + if(myClassesSet != null && (elementClassHint == null || elementClassHint.shouldProcess(PsiClass.class))){ + if(myClassesSet.contains(name)){ + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } + } + if(myVariablesSet != null && (elementClassHint == null || elementClassHint.shouldProcess(PsiVariable.class))){ + if(myVariablesSet.contains(name)){ + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } + } + } + else{ + if(myConflict || (myVariablesSet != null || myClassesSet != null)) + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } + return true; + } + + public ChameleonElement createChameleon(char[] buffer, int start, int end) { + LeafElement firstLeaf = TreeUtil.findFirstLeaf(this); + return new CodeBlockChameleonElement(buffer, start, end, firstLeaf != null ? firstLeaf.getState() : -1, SharedImplUtil.findCharTableByTree(this)); + } + + public int getErrorsCount(char[] buffer, int start, int end, int lengthShift) { + final JavaLexer lexer = new JavaLexer(getManager().getEffectiveLanguageLevel()); + lexer.start(buffer, start, end + lengthShift); + int balance = 0; + while(true){ + IElementType type = lexer.getTokenType(); + if (type == null) break; + if (type == LBRACE) { + balance++; + } + else if (type == RBRACE) { + balance--; + } + lexer.advance(); + } + return balance; + } + + public Class getLexerClass() { + return JavaLexer.class; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java new file mode 100644 index 00000000000..523d018736c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java @@ -0,0 +1,139 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.util.TypeConversionUtil; + +public class PsiConditionalExpressionImpl extends CompositePsiElement implements PsiConditionalExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiConditionalExpressionImpl"); + + public PsiConditionalExpressionImpl() { + super(CONDITIONAL_EXPRESSION); + } + + public PsiExpression getCondition() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public PsiExpression getThenExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.THEN_EXPRESSION); + } + + public PsiExpression getElseExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.ELSE_EXPRESSION); + } + + /** + * JLS 15.25 + */ + public PsiType getType() { + PsiExpression expr1 = getThenExpression(); + PsiExpression expr2 = getElseExpression(); + PsiType type1 = expr1 != null ? expr1.getType() : null; + PsiType type2 = expr2 != null ? expr2.getType() : null; + if (type1 == null) return type2; + if (type2 == null) return type1; + + if (type1.equals(type2)) return type1; + final int typeRank1 = TypeConversionUtil.getTypeRank(type1); + final int typeRank2 = TypeConversionUtil.getTypeRank(type2); + if (TypeConversionUtil.isNumericType(typeRank1) && TypeConversionUtil.isNumericType(typeRank2)){ + if (typeRank1 == TypeConversionUtil.BYTE_RANK && typeRank2 == TypeConversionUtil.SHORT_RANK) return type2; + if (typeRank1 == TypeConversionUtil.SHORT_RANK && typeRank2 == TypeConversionUtil.BYTE_RANK) return type1; + if (typeRank1 == TypeConversionUtil.BYTE_RANK || typeRank1 == TypeConversionUtil.SHORT_RANK || typeRank1 == TypeConversionUtil.CHAR_RANK){ + if (TypeConversionUtil.areTypesAssignmentCompatible(type1, expr2)) return type1; + } + if (typeRank2 == TypeConversionUtil.BYTE_RANK || typeRank2 == TypeConversionUtil.SHORT_RANK || typeRank2 == TypeConversionUtil.CHAR_RANK){ + if (TypeConversionUtil.areTypesAssignmentCompatible(type2, expr1)) return type2; + } + return TypeConversionUtil.binaryNumericPromotion(type1, type2); + } + if (TypeConversionUtil.isNullType(type1) && !(type2 instanceof PsiPrimitiveType)) return type2; + if (TypeConversionUtil.isNullType(type2) && !(type1 instanceof PsiPrimitiveType)) return type1; + + if (type1.isAssignableFrom(type2)) return type1; + if (type2.isAssignableFrom(type1)) return type2; + if (getManager().getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) { + return null; + } + else { + if (type1 instanceof PsiPrimitiveType) type1 = ((PsiPrimitiveType)type1).getBoxedType(getManager(), getResolveScope()); + if (type1 == null) return null; + if (type2 instanceof PsiPrimitiveType) type2 = ((PsiPrimitiveType)type2).getBoxedType(getManager(), getResolveScope()); + if (type2 == null) return null; + + return GenericsUtil.getLeastUpperBound(type1, type2, getManager()); + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.CONDITION: + return firstChild; + + case ChildRole.QUEST: + return TreeUtil.findChild(this, QUEST); + + case ChildRole.THEN_EXPRESSION: + { + TreeElement quest = findChildByRole(ChildRole.QUEST); + TreeElement child = quest.getTreeNext(); + while(true){ + if (child == null) return null; + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) break; + child = child.getTreeNext(); + } + return child; + } + + case ChildRole.COLON: + return TreeUtil.findChild(this, COLON); + + case ChildRole.ELSE_EXPRESSION: + { + TreeElement colon = findChildByRole(ChildRole.COLON); + if (colon == null) return null; + return EXPRESSION_BIT_SET.isInSet(lastChild.getElementType()) ? lastChild : null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())){ + int role = getChildRole(child, ChildRole.CONDITION); + if (role != ChildRole.NONE) return role; + role = getChildRole(child, ChildRole.THEN_EXPRESSION); + if (role != ChildRole.NONE) return role; + role = getChildRole(child, ChildRole.ELSE_EXPRESSION); + return role; + } + else if (child.getElementType() == QUEST){ + return ChildRole.QUEST; + } + else if (child.getElementType() == COLON){ + return ChildRole.COLON; + } + else{ + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitConditionalExpression(this); + } + + public String toString() { + return "PsiConditionalExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiContinueStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiContinueStatementImpl.java new file mode 100644 index 00000000000..ee509a56042 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiContinueStatementImpl.java @@ -0,0 +1,103 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiLabelReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; + +public class PsiContinueStatementImpl extends CompositePsiElement implements PsiContinueStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiContinueStatementImpl"); + + public PsiContinueStatementImpl() { + super(CONTINUE_STATEMENT); + } + + public PsiIdentifier getLabelIdentifier() { + return (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.LABEL); + } + + public PsiStatement findContinuedStatement() { + PsiIdentifier label = getLabelIdentifier(); + if (label == null){ + for(CompositeElement parent = getTreeParent(); parent != null; parent = parent.getTreeParent()){ + IElementType i = parent.getElementType(); + if (i == FOR_STATEMENT || i == FOREACH_STATEMENT || i == WHILE_STATEMENT || i == DO_WHILE_STATEMENT) { + return (PsiStatement)SourceTreeToPsiMap.treeElementToPsi(parent); + } + if (i == METHOD || i == CLASS_INITIALIZER) { + return null; + } + } + } + else{ + String labelName = label.getText(); + for(CompositeElement parent = getTreeParent(); parent != null; parent = parent.getTreeParent()){ + if (parent.getElementType() == LABELED_STATEMENT){ + TreeElement statementLabel = parent.findChildByRole(ChildRole.LABEL_NAME); + if (statementLabel.textMatches(labelName)){ + return ((PsiLabeledStatement)SourceTreeToPsiMap.treeElementToPsi(parent)).getStatement(); + } + } + if (parent.getElementType() == METHOD || parent.getElementType() == CLASS_INITIALIZER) return null; // do not pass through anonymous/local class + } + } + return null; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.CONTINUE_KEYWORD: + return TreeUtil.findChild(this, CONTINUE_KEYWORD); + + case ChildRole.LABEL: + return TreeUtil.findChild(this, IDENTIFIER); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == CONTINUE_KEYWORD) { + return ChildRole.CONTINUE_KEYWORD; + } + else if (i == IDENTIFIER) { + return ChildRole.LABEL; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitContinueStatement(this); + } + + public String toString() { + return "PsiContinueStatement"; + } + + public PsiReference getReference() { + final PsiReference[] references = getReferences(); + if (references != null && references.length > 0) + return references[0]; + return null; + } + + public PsiReference[] getReferences() { + if (getLabelIdentifier() == null) + return PsiReference.EMPTY_ARRAY; + return new PsiReference[]{new PsiLabelReference(this, getLabelIdentifier())}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDeclarationStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDeclarationStatementImpl.java new file mode 100644 index 00000000000..1f66083b01a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDeclarationStatementImpl.java @@ -0,0 +1,93 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +public class PsiDeclarationStatementImpl extends CompositePsiElement implements PsiDeclarationStatement { + public PsiDeclarationStatementImpl() { + super(DECLARATION_STATEMENT); + } + + public PsiElement[] getDeclaredElements() { + return getChildrenAsPsiElements(DECLARED_ELEMENT_BIT_SET, PSI_ELEMENT_ARRAY_CONSTRUCTOR); + } + + private static final TokenSet DECLARED_ELEMENT_BIT_SET = TokenSet.create(new IElementType[]{LOCAL_VARIABLE, CLASS}); + + public int getChildRole(TreeElement child) { + if (child.getElementType() == ElementType.COMMA) return ChildRole.COMMA; + return super.getChildRole(child); + } + + public void deleteChildInternal(TreeElement child) { + if (DECLARED_ELEMENT_BIT_SET.isInSet(child.getElementType())) { + PsiElement[] declaredElements = getDeclaredElements(); + int length = declaredElements.length; + if (length > 0) { + if (length == 1) { + getTreeParent().deleteChildInternal(this); + return; + } else { + if (SourceTreeToPsiMap.psiElementToTree(declaredElements[length - 1]) == child) { + removeCommaBefore(child); + final LeafElement semicolon = Factory.createSingleLeafElement(SEMICOLON, new char[]{';'}, 0, 1, + SharedImplUtil.findCharTableByTree(this), getManager()); + ChangeUtil.addChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(declaredElements[length - 2]), semicolon, null); + } + else if (SourceTreeToPsiMap.psiElementToTree(declaredElements[0]) == child) { + CompositeElement next = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(declaredElements[1]); + TreeElement copyChild = child.copyElement(); + TreeElement nameChild = ((CompositeElement)copyChild).findChildByRole(ChildRole.NAME); + removeCommaBefore(next); + next.addInternal(((CompositeElement)copyChild).firstChild, nameChild.getTreePrev(), null, Boolean.FALSE); + } + else { + removeCommaBefore (child); + } + } + } + } + super.deleteChildInternal(child); + } + + private void removeCommaBefore(TreeElement child) { + TreeElement prev = child; + do { + prev = prev.getTreePrev(); + } while (prev != null && JavaTokenType.WHITE_SPACE_OR_COMMENT_BIT_SET.isInSet(prev.getElementType())); + if (prev != null && prev.getElementType() == COMMA) deleteChildInternal(prev); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitDeclarationStatement(this); + } + + public String toString() { + return "PsiDeclarationStatement"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + PsiElement[] decls = getDeclaredElements(); + for (int i = 0; i < decls.length; i++) { + if (decls[i] != lastParent) { + if (!processor.execute(decls[i], substitutor)) return false; + } + else { + final ElementClassHint hint = processor.getHint(ElementClassHint.class); + if (lastParent instanceof PsiClass) { + if (hint == null || hint.shouldProcess(PsiClass.class)) { + processor.execute(lastParent, substitutor); + } + } + } + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDoWhileStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDoWhileStatementImpl.java new file mode 100644 index 00000000000..e8af6d8c9ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiDoWhileStatementImpl.java @@ -0,0 +1,105 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiDoWhileStatementImpl extends CompositePsiElement implements PsiDoWhileStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiDoWhileStatementImpl"); + + public PsiDoWhileStatementImpl() { + super(DO_WHILE_STATEMENT); + } + + public PsiExpression getCondition(){ + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public PsiStatement getBody(){ + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.LOOP_BODY); + } + + public PsiKeyword getWhileKeyword() { + return (PsiKeyword) findChildByRoleAsPsiElement(ChildRole.WHILE_KEYWORD); + } + + public PsiJavaToken getLParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.LPARENTH); + } + + public PsiJavaToken getRParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.RPARENTH); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.DO_KEYWORD: + return TreeUtil.findChild(this, DO_KEYWORD); + + case ChildRole.LOOP_BODY: + return TreeUtil.findChild(this, STATEMENT_BIT_SET); + + case ChildRole.WHILE_KEYWORD: + return TreeUtil.findChild(this, WHILE_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.CONDITION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DO_KEYWORD) { + return ChildRole.DO_KEYWORD; + } + else if (i == WHILE_KEYWORD) { + return ChildRole.WHILE_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.CONDITION; + } + else if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.LOOP_BODY; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitDoWhileStatement(this); + } + + public String toString(){ + return "PsiDoWhileStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyExpressionImpl.java new file mode 100644 index 00000000000..680fae87ebd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyExpressionImpl.java @@ -0,0 +1,22 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.CompositePsiElement; + +public class PsiEmptyExpressionImpl extends CompositePsiElement implements PsiExpression{ + public PsiEmptyExpressionImpl() { + super(EMPTY_EXPRESSION); + } + + public PsiType getType() { + return null; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitExpression(this); + } + + public String toString() { + return "PsiExpression(empty)"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyStatementImpl.java new file mode 100644 index 00000000000..e35a7f42f4a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiEmptyStatementImpl.java @@ -0,0 +1,18 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.CompositePsiElement; + +public class PsiEmptyStatementImpl extends CompositePsiElement implements PsiEmptyStatement { + public PsiEmptyStatementImpl() { + super(EMPTY_STATEMENT); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitEmptyStatement(this); + } + + public String toString(){ + return "PsiEmptyStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java new file mode 100644 index 00000000000..bf0a35b95eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java @@ -0,0 +1,138 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionList; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.CharTable; + +public class PsiExpressionListImpl extends CompositePsiElement implements PsiExpressionList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiExpressionListImpl"); + + public PsiExpressionListImpl() { + super(EXPRESSION_LIST); + } + + public PsiExpression[] getExpressions() { + return (PsiExpression[])getChildrenAsPsiElements(EXPRESSION_BIT_SET, PSI_EXPRESSION_ARRAY_CONSTRUCTOR); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch (role) { + default: + return null; + + case ChildRole.LPARENTH: + return firstChild != null && firstChild.getElementType() == LPARENTH ? firstChild : null; + + case ChildRole.RPARENTH: + if (lastChild != null && lastChild.getElementType() == RPARENTH) { + return lastChild; + } + else { + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.EXPRESSION_IN_LIST; + } + return ChildRole.NONE; + } + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + TreeElement firstAdded = null; + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + if (anchor == null) { + if (before == null || before.booleanValue()) { + anchor = findChildByRole(ChildRole.RPARENTH); + if (anchor == null) { + LeafElement lparenth = Factory.createSingleLeafElement(LPARENTH, new char[]{'('}, 0, 1, treeCharTab, getManager()); + firstAdded = super.addInternal(lparenth, lparenth, null, Boolean.FALSE); + LeafElement rparenth = Factory.createSingleLeafElement(RPARENTH, new char[]{')'}, 0, 1, treeCharTab, getManager()); + super.addInternal(rparenth, rparenth, null, Boolean.TRUE); + anchor = findChildByRole(ChildRole.RPARENTH); + LOG.assertTrue(anchor != null); + } + before = Boolean.TRUE; + } + else { + anchor = findChildByRole(ChildRole.LPARENTH); + if (anchor == null) { + LeafElement lparenth = Factory.createSingleLeafElement(LPARENTH, new char[]{'('}, 0, 1, treeCharTab, getManager()); + firstAdded = super.addInternal(lparenth, lparenth, null, Boolean.FALSE); + LeafElement rparenth = Factory.createSingleLeafElement(RPARENTH, new char[]{')'}, 0, 1, treeCharTab, getManager()); + super.addInternal(rparenth, rparenth, null, Boolean.TRUE); + anchor = findChildByRole(ChildRole.LPARENTH); + LOG.assertTrue(anchor != null); + } + before = Boolean.FALSE; + } + } + if(firstAdded != null) firstAdded = super.addInternal(first, last, anchor, before); + else firstAdded = super.addInternal(first, last, anchor, before); + if (first == last && ElementType.EXPRESSION_BIT_SET.isInSet(first.getElementType())) { + TreeElement element = first; + for (TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()) { + if (child.getElementType() == COMMA) break; + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for (TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()) { + if (child.getElementType() == COMMA) break; + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + return firstAdded; + } + + public void deleteChildInternal(TreeElement child) { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == COMMA) { + deleteChildInternal(next); + } + else { + TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null && prev.getElementType() == COMMA) { + deleteChildInternal(prev); + } + } + } + super.deleteChildInternal(child); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitExpressionList(this); + } + + public String toString() { + return "PsiExpressionList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListStatementImpl.java new file mode 100644 index 00000000000..ff703a355f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionListStatementImpl.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpressionList; +import com.intellij.psi.PsiExpressionListStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiExpressionListStatementImpl extends CompositePsiElement implements PsiExpressionListStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiExpressionListStatementImpl"); + + public PsiExpressionListStatementImpl() { + super(EXPRESSION_LIST_STATEMENT); + } + + public PsiExpressionList getExpressionList() { + return (PsiExpressionList)findChildByRoleAsPsiElement(ChildRole.EXPRESSION_LIST); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.EXPRESSION_LIST: + return TreeUtil.findChild(this, EXPRESSION_LIST); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == EXPRESSION_LIST) { + return ChildRole.EXPRESSION_LIST; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitExpressionListStatement(this); + } + + public String toString() { + return "PsiExpressionListStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java new file mode 100644 index 00000000000..669f3fc24fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java @@ -0,0 +1,57 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; + +public class PsiExpressionStatementImpl extends CompositePsiElement implements PsiExpressionStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiExpressionStatementImpl"); + + public PsiExpressionStatementImpl() { + super(EXPRESSION_STATEMENT); + } + + public PsiExpression getExpression() { + return (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(TreeUtil.findChild(this, EXPRESSION_BIT_SET)); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.EXPRESSION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.EXPRESSION; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitExpressionStatement(this); + } + + public String toString() { + return "PsiExpressionStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForStatementImpl.java new file mode 100644 index 00000000000..b3dc8bc12d1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForStatementImpl.java @@ -0,0 +1,160 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.util.CharTable; + +public class PsiForStatementImpl extends CompositePsiElement implements PsiForStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiForStatementImpl"); + + public PsiForStatementImpl() { + super(FOR_STATEMENT); + } + + public PsiStatement getInitialization(){ + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.FOR_INITIALIZATION); + } + + public PsiExpression getCondition(){ + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public PsiStatement getUpdate(){ + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.FOR_UPDATE); + } + + public PsiStatement getBody(){ + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.LOOP_BODY); + } + + public PsiJavaToken getLParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.LPARENTH); + } + + public PsiJavaToken getRParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.RPARENTH); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.FOR_KEYWORD: + return TreeUtil.findChild(this, FOR_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.FOR_INITIALIZATION: + final TreeElement initialization = TreeUtil.findChild(this, STATEMENT_BIT_SET); + // should be inside parens + for(TreeElement child = initialization; child != null; child = child.getTreeNext()){ + if (child.getElementType() == RPARENTH) return initialization; + } + return null; + + case ChildRole.CONDITION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.FOR_SEMICOLON: + return TreeUtil.findChild(this, SEMICOLON); + + case ChildRole.FOR_UPDATE: + { + TreeElement semicolon = findChildByRole(ChildRole.FOR_SEMICOLON); + for(TreeElement child = semicolon; child != null; child = child.getTreeNext()){ + if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return child; + } + if (child.getElementType() == RPARENTH) break; + } + return null; + } + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.LOOP_BODY: + { + TreeElement rparenth = findChildByRole(ChildRole.RPARENTH); + for(TreeElement child = rparenth; child != null; child = child.getTreeNext()){ + if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return child; + } + } + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == FOR_KEYWORD) { + return ChildRole.FOR_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else if (i == SEMICOLON) { + return ChildRole.FOR_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.CONDITION; + } + else if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + int role = getChildRole(child, ChildRole.FOR_INITIALIZATION); + if (role != ChildRole.NONE) return role; + role = getChildRole(child, ChildRole.FOR_UPDATE); + if (role != ChildRole.NONE) return role; + return ChildRole.LOOP_BODY; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitForStatement(this); + } + + public String toString(){ + return "PsiForStatement"; + } + + public void deleteChildInternal(TreeElement child) { + final boolean isForInitialization = getChildRole(child) == ChildRole.FOR_INITIALIZATION; + + if (isForInitialization) { + final CompositeElement emptyStatement = Factory.createCompositeElement(EMPTY_STATEMENT); + final LeafElement comma = Factory.createSingleLeafElement(SEMICOLON, new char[]{';'}, 0, 1, SharedImplUtil.findCharTableByTree(this), getManager()); + emptyStatement.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(comma)); + TreeUtil.addChildren(emptyStatement, comma); + super.replaceChildInternal(child, emptyStatement); + } + else { + super.deleteChildInternal(child); + } + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null || lastParent.getParent() != this) + // Parent element should not see our vars + return true; + + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForeachStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForeachStatementImpl.java new file mode 100644 index 00000000000..0502d4ab9ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiForeachStatementImpl.java @@ -0,0 +1,122 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; + +/** + * @author dsl + */ +public class PsiForeachStatementImpl extends CompositePsiElement implements PsiForeachStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiForeachStatementImpl"); + public PsiForeachStatementImpl() { + super(FOREACH_STATEMENT); + } + + public PsiParameter getIterationParameter() { + return (PsiParameter) findChildByRoleAsPsiElement(ChildRole.FOR_ITERATION_PARAMETER); + } + + public PsiExpression getIteratedValue() { + return (PsiExpression) findChildByRoleAsPsiElement(ChildRole.FOR_ITERATED_VALUE); + } + + public PsiStatement getBody() { + return (PsiStatement) findChildByRoleAsPsiElement(ChildRole.LOOP_BODY); + } + + public PsiJavaToken getLParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.LPARENTH); + } + + public PsiJavaToken getRParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.RPARENTH); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + + switch(role) { + case ChildRole.LOOP_BODY: + return TreeUtil.findChild(this, STATEMENT_BIT_SET); + + case ChildRole.FOR_ITERATED_VALUE: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.FOR_KEYWORD: + return firstChild; + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.FOR_ITERATION_PARAMETER: + return TreeUtil.findChild(this, PARAMETER); + + case ChildRole.COLON: + return TreeUtil.findChild(this, COLON); + + default: + return null; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + + IElementType i = child.getElementType(); + if (i == FOR_KEYWORD) { + return ChildRole.FOR_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else if (i == PARAMETER) { + return ChildRole.FOR_ITERATION_PARAMETER; + } + else if (i == COLON) { + return ChildRole.COLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.FOR_ITERATED_VALUE; + } + else if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.LOOP_BODY; + } + else { + return ChildRole.NONE; + } + } + } + + public String toString() { + return "PsiForeachStatement"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null || lastParent.getParent() != this) + // Parent element should not see our vars + return true; + + final PsiParameter iterationParameter = getIterationParameter(); + if (iterationParameter != null) { + return processor.execute(iterationParameter, substitutor); + } + + return PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitForeachStatement(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIdentifierImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIdentifierImpl.java new file mode 100644 index 00000000000..3e2a00eebeb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIdentifierImpl.java @@ -0,0 +1,28 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.util.CharTable; + +public class PsiIdentifierImpl extends LeafPsiElement implements PsiIdentifier, PsiJavaToken { + public PsiIdentifierImpl(char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(IDENTIFIER, buffer, startOffset, endOffset, lexerState, table); + } + + public IElementType getTokenType() { + return JavaTokenType.IDENTIFIER; + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitIdentifier(this); + } + + public String toString(){ + return "PsiIdentifier:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIfStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIfStatementImpl.java new file mode 100644 index 00000000000..3e686dd01de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiIfStatementImpl.java @@ -0,0 +1,139 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.IncorrectOperationException; + +public class PsiIfStatementImpl extends CompositePsiElement implements PsiIfStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiIfStatementImpl"); + + public PsiIfStatementImpl() { + super(IF_STATEMENT); + } + + public PsiExpression getCondition() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public void deleteChildInternal(TreeElement child) { + if (child == getElseBranch()) { + TreeElement elseKeyword = findChildByRole(ChildRole.ELSE_KEYWORD); + if (elseKeyword != null) { + super.deleteChildInternal(elseKeyword); + } + } + super.deleteChildInternal(child); + } + + public PsiStatement getThenBranch() { + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.THEN_BRANCH); + } + + public PsiStatement getElseBranch() { + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.ELSE_BRANCH); + } + + public PsiJavaToken getLParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.LPARENTH); + } + + public PsiJavaToken getRParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.RPARENTH); + } + + public PsiKeyword getElseElement() { + return (PsiKeyword)findChildByRoleAsPsiElement(ChildRole.ELSE_KEYWORD); + } + + public void setElseBranch(PsiStatement statement) throws IncorrectOperationException { + PsiStatement elseBranch = getElseBranch(); + if (elseBranch != null) elseBranch.delete(); + PsiKeyword elseElement = getElseElement(); + if (elseElement != null) elseElement.delete(); + + PsiElementFactory elementFactory = getManager().getElementFactory(); + PsiIfStatement ifStatement = (PsiIfStatement)elementFactory.createStatementFromText("if (true) {} else {}", null); + ifStatement.getElseBranch().replace(statement); + + addRange(ifStatement.getElseElement(), ifStatement.getLastChild()); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.IF_KEYWORD: + return TreeUtil.findChild(this, IF_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.CONDITION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.THEN_BRANCH: + return TreeUtil.findChild(this, STATEMENT_BIT_SET); + + case ChildRole.ELSE_KEYWORD: + return TreeUtil.findChild(this, ELSE_KEYWORD); + + case ChildRole.ELSE_BRANCH: + { + TreeElement elseKeyword = findChildByRole(ChildRole.ELSE_KEYWORD); + if (elseKeyword == null) return null; + for(TreeElement child = elseKeyword.getTreeNext(); child != null; child = child.getTreeNext()){ + if (STATEMENT_BIT_SET.isInSet(child.getElementType())) return child; + } + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == IF_KEYWORD) { + return ChildRole.IF_KEYWORD; + } + else if (i == ELSE_KEYWORD) { + return ChildRole.ELSE_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.CONDITION; + } + else if (ElementType.STATEMENT_BIT_SET.isInSet(child.getElementType())) { + if (findChildByRoleAsPsiElement(ChildRole.THEN_BRANCH) == child) { + return ChildRole.THEN_BRANCH; + } + else { + return ChildRole.ELSE_BRANCH; + } + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitIfStatement(this); + } + + public String toString() { + return "PsiIfStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java new file mode 100644 index 00000000000..c5221365cec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java @@ -0,0 +1,98 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiInlineDocTag; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.IncorrectOperationException; + +public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl"); + + private static final TokenSet VALUE_BIT_SET = TokenSet.create(new IElementType[]{ + JAVA_CODE_REFERENCE, + DOC_TAG_VALUE_TOKEN, + DOC_METHOD_OR_FIELD_REF, + DOC_COMMENT_DATA, + DOC_INLINE_TAG, + }); + + public PsiInlineDocTagImpl() { + super(DOC_INLINE_TAG); + } + + public PsiDocComment getContainingComment() { + TreeElement scope = getTreeParent(); + while (scope.getElementType() != DOC_COMMENT) { + scope = scope.getTreeParent(); + } + return (PsiDocComment)SourceTreeToPsiMap.treeElementToPsi(scope); + } + + public PsiElement getNameElement() { + return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME); + } + + public PsiElement[] getDataElements() { + return getChildrenAsPsiElements(VALUE_BIT_SET, PSI_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiDocTagValue getValueElement() { + return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE); + } + + public String getName() { + final PsiElement nameElement = getNameElement(); + if (nameElement == null) return ""; + return nameElement.getText().substring(1); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DOC_TAG_NAME) { + return ChildRole.DOC_TAG_NAME; + } + else if (i == DOC_COMMENT_TEXT || i == DOC_INLINE_TAG) { + return ChildRole.DOC_CONTENT; + } + else if (i == DOC_INLINE_TAG_START) { + return ChildRole.DOC_INLINE_TAG_START; + } + else if (i == DOC_INLINE_TAG_END) { + return ChildRole.DOC_INLINE_TAG_END; + } + else if (i == DOC_TAG_VALUE_TOKEN) { + return ChildRole.DOC_TAG_VALUE; + } + else if (i == DOC_METHOD_OR_FIELD_REF) { + return ChildRole.DOC_TAG_VALUE; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitInlineDocTag(this); + } + + public String toString() { + PsiElement nameElement = getNameElement(); + return "PsiInlineDocTag:" + (nameElement != null ? nameElement.getText() : null); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameElement(), name); + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInstanceOfExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInstanceOfExpressionImpl.java new file mode 100644 index 00000000000..de2461aebf2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiInstanceOfExpressionImpl.java @@ -0,0 +1,69 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiInstanceOfExpressionImpl extends CompositePsiElement implements PsiInstanceOfExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiInstanceOfExpressionImpl"); + + public PsiInstanceOfExpressionImpl() { + super(INSTANCE_OF_EXPRESSION); + } + + public PsiExpression getOperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.OPERAND); + } + + public PsiTypeElement getCheckType() { + return (PsiTypeElement)findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public PsiType getType() { + return PsiType.BOOLEAN; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.OPERAND: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.INSTANCEOF_KEYWORD: + return TreeUtil.findChild(this, INSTANCEOF_KEYWORD); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, TYPE); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == TYPE) { + return ChildRole.TYPE; + } + else if (i == INSTANCEOF_KEYWORD) { + return ChildRole.INSTANCEOF_KEYWORD; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.OPERAND; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitInstanceOfExpression(this); + } + + public String toString() { + return "PsiInstanceofExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiJavaTokenImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiJavaTokenImpl.java new file mode 100644 index 00000000000..efcc287981f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiJavaTokenImpl.java @@ -0,0 +1,26 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public class PsiJavaTokenImpl extends LeafPsiElement implements PsiJavaToken, JavaTokenType{ + public PsiJavaTokenImpl(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, lexerState, table); + } + + public IElementType getTokenType() { + return getElementType(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitJavaToken(this); + } + + public String toString(){ + return "PsiJavaToken:" + getElementType().toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiKeywordImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiKeywordImpl.java new file mode 100644 index 00000000000..1719b69d5f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiKeywordImpl.java @@ -0,0 +1,41 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.CharTable; + +import java.util.ArrayList; +import java.util.List; + +public class PsiKeywordImpl extends LeafPsiElement implements PsiKeyword, PsiJavaToken { + public PsiElement[] create(Class parentClass, PsiElementFactory factory, String prefix) + throws IncorrectOperationException{ + List ret = new ArrayList(); + if(parentClass.isAssignableFrom(PsiClass.class)){ + if("class".startsWith(prefix)){ + ret.add(factory.createKeyword("class")); + } + } + + return (PsiElement[])ret.toArray(new PsiElement[ret.size()]); + } + + public PsiKeywordImpl(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, lexerState, table); + } + + public IElementType getTokenType(){ + return getElementType(); + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitKeyword(this); + } + + public String toString(){ + return "PsiKeyword:" + getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLabeledStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLabeledStatementImpl.java new file mode 100644 index 00000000000..cc8603c2b6f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLabeledStatementImpl.java @@ -0,0 +1,92 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.util.IncorrectOperationException; + +public class PsiLabeledStatementImpl extends CompositePsiElement implements PsiLabeledStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl"); + + public PsiLabeledStatementImpl() { + super(LABELED_STATEMENT); + } + + public PsiIdentifier getLabelIdentifier() { + return (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.LABEL_NAME); + } + + public PsiStatement getStatement() { + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.STATEMENT); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.STATEMENT: + return TreeUtil.findChild(this, STATEMENT_BIT_SET); + + case ChildRole.COLON: + return TreeUtil.findChild(this, COLON); + + case ChildRole.LABEL_NAME: + return firstChild; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == IDENTIFIER) { + return ChildRole.LABEL_NAME; + } + else if (i == COLON) { + return ChildRole.COLON; + } + else { + if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.STATEMENT; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitLabeledStatement(this); + } + + public String toString() { + return "PsiLabeledStatement"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + if (lastParent != null && lastParent.getParent() != this){ + PsiElement[] children = getChildren(); + for(int i = 0; i < children.length; i++){ + if (!PsiScopesUtil.processScope(children[i], processor, substitutor, null, place)){ + return false; + } + } + } + return true; + } + + public String getName() { + return getLabelIdentifier().getText(); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getLabelIdentifier(), name); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java new file mode 100644 index 00000000000..73c0b642264 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java @@ -0,0 +1,384 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.CompositePsiElement; + +public class PsiLiteralExpressionImpl extends CompositePsiElement implements PsiLiteralExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl"); + + + public PsiLiteralExpressionImpl() { + super(LITERAL_EXPRESSION); + } + + public PsiType getType() { + IElementType i = firstChild.getElementType(); + if (i == INTEGER_LITERAL) { + return PsiType.INT; + } + else if (i == LONG_LITERAL) { + return PsiType.LONG; + } + else if (i == FLOAT_LITERAL) { + return PsiType.FLOAT; + } + else if (i == DOUBLE_LITERAL) { + return PsiType.DOUBLE; + } + else if (i == CHARACTER_LITERAL) { + return PsiType.CHAR; + } + else if (i == STRING_LITERAL) { + return PsiType.getJavaLangString(getManager()); + } + else if (i == TRUE_KEYWORD || i == FALSE_KEYWORD) { + return PsiType.BOOLEAN; + } + else if (i == NULL_KEYWORD) { + return PsiType.NULL; + } + else { + LOG.assertTrue(false); + return null; + } + } + + private static final String _2_IN_63 = Long.toString(-1L << 63).substring(1); + private static final String _2_IN_31 = Long.toString(-1L << 31).substring(1); + private static final String _2_IN_63_L = _2_IN_63 + "l"; + + public Object getValue() { + String text = firstChild.getText(); + int textLength = text.length(); + IElementType i = firstChild.getElementType(); + if (i == INTEGER_LITERAL) { + try { + if (text.startsWith("0x") || text.startsWith("0X")) { + // should fit in 32 bits + if (textLength <= 9) return Integer.valueOf(text.substring(2), 16); + final Long value = parseDigits(text.substring(2), 4, 32); + return value == null ? null : new Integer(value.intValue()); + } + else if (StringUtil.startsWithChar(text, '0')) { + // should fit in 32 bits + if (textLength <= 12) return Integer.valueOf(text, 8); + final Long value = parseDigits(text, 3, 32); + return value == null ? null : new Integer(value.intValue()); + } + else { + final long l = Long.parseLong(text, 10); + if (text.equals(_2_IN_31)) return new Integer((int)l); + long converted = (int)l; + return l == converted ? new Integer((int)l) : null; + } + } + catch (Exception e) { + return null; + } + } + else if (i == LONG_LITERAL) { + if (StringUtil.endsWithChar(text, 'L') || StringUtil.endsWithChar(text, 'l')) { + text = text.substring(0, textLength - 1); + textLength = text.length(); + } + try { + if (text.startsWith("0x") || text.startsWith("0X")) { + if (textLength <= 17) return Long.valueOf(text.substring(2), 16); + return parseDigits(text.substring(2), 4, 64); + } + else if (StringUtil.startsWithChar(text, '0')) { + // should fit in 64 bits + if (textLength <= 23) return Long.valueOf(text, 8); + return parseDigits(text, 3, 64); + } + else { + if (_2_IN_63.equals(text)) return new Long(-1L << 63); + return Long.valueOf(text, 10); + } + } + catch (Exception e) { + return null; + } + } + else if (i == FLOAT_LITERAL) { + try { + return Float.valueOf(text); + } + catch (Exception e) { + return null; + } + } + else if (i == DOUBLE_LITERAL) { + try { + return Double.valueOf(text); + } + catch (Exception e) { + return null; + } + } + else if (i == CHARACTER_LITERAL) { + if (StringUtil.endsWithChar(text, '\'')) { + if (textLength == 1) return null; + text = text.substring(1, textLength - 1); + } + else { + text = text.substring(1, textLength); + } + String s = parseStringCharacters(text); + if (s == null) return null; + if (s.length() != 1) return null; + return new Character(s.charAt(0)); + } + else if (i == STRING_LITERAL) { + if (StringUtil.endsWithChar(text, '\"')) { + if (textLength == 1) return null; + text = text.substring(1, textLength - 1); + } + else { +// text = text.substring(1, textLength); + return null; + } + return parseStringCharacters(text); + } + else if (i == TRUE_KEYWORD) { + return Boolean.TRUE; + } + else if (i == FALSE_KEYWORD) { + return Boolean.FALSE; + } + else if (i == NULL_KEYWORD) { + return null; + } + else { + LOG.assertTrue(false); + return null; + } + } + + // convert text to number according to radix specified + // if number is more than maxbits bits long, return null + private static Long parseDigits(String text, int bitsInRadix, int maxBits) { + final int radix = 1 << bitsInRadix; + int textLength = text.length(); + long integer = Long.parseLong(text.substring(0, textLength - 1), radix); + final int lastDigit = Integer.parseInt("" + text.charAt(textLength - 1), radix); + if ((integer & (-1L << maxBits - 4)) != 0) return null; + integer <<= bitsInRadix; + integer |= lastDigit; + return new Long(integer); + } + + public String getParsingError() { + final Object value = getValue(); + String text = firstChild.getText(); + IElementType i = firstChild.getElementType(); + if (i == INTEGER_LITERAL) { + text = text.toLowerCase(); + //literal 2147483648 may appear only as the operand of the unary negation operator -. + if (!(text.equals(_2_IN_31) + && getParent() instanceof PsiPrefixExpression + && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == JavaTokenType.MINUS)) { + if (text.equals("0x")) return "Hexadecimal numbers must contain at least one hexadecimal digit"; + if (value == null || text.equals(_2_IN_31)) { + return "Integer number too large"; + } + } + } + else if (i == LONG_LITERAL) { + text = text.toLowerCase(); + //literal 9223372036854775808L may appear only as the operand of the unary negation operator -. + if (!(text.equals(_2_IN_63_L) + && getParent() instanceof PsiPrefixExpression + && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == JavaTokenType.MINUS)) { + if (text.equals("0x") || text.equals("0xl")) return "Hexadecimal numbers must contain at least one hexadecimal digit"; + if (value == null || text.equals(_2_IN_63_L)) { + return "Long number too large"; + } + } + } + else if (i == FLOAT_LITERAL || i == DOUBLE_LITERAL) { + if (value == null) { + return "Malformed floating point literal"; + } + } + else if (i == TRUE_KEYWORD || i == FALSE_KEYWORD || i == NULL_KEYWORD) { + // TODO + } + else if (i == CHARACTER_LITERAL) { + if (value == null) { + if (StringUtil.endsWithChar(text, '\'')) { + if (text.length() == 1) return "Illegal line end in character literal"; + text = text.substring(1, text.length() - 1); + } + else { + return "Illegal line end in character literal"; + } + String s = parseStringCharacters(text); + if (s == null) return "Illegal escape character in character literal"; + if (s.length() > 1) { + return "Too many characters in character literal"; + } + else if (s.length() == 0) return "Empty character literal"; + } + } + else if (i == STRING_LITERAL) { + if (value == null) { + if (StringUtil.endsWithChar(text, '\"')) { + if (text.length() == 1) return "Illegal line end in string literal"; + text = text.substring(1, text.length() - 1); + } + else { + return "Illegal line end in string literal"; + } + if (parseStringCharacters(text) == null) return "Illegal escape character in string literal"; + } + } + + if (value instanceof Float) { + final Float number = (Float)value; + if (number.isInfinite()) return "Floating point number too large"; + if (number.floatValue() == 0 && !isFPZero()) return "Floating point number too small"; + } + if (value instanceof Double) { + final Double number = (Double)value; + if (number.isInfinite()) return "Floating point number too large"; + if (number.doubleValue() == 0 && !isFPZero()) return "Floating point number too small"; + } + return null; + } + + /** + * @return true if floating point literal consists of zeros only + */ + private boolean isFPZero() { + String text = firstChild.getText(); + for(int i = 0; i < text.length(); i++){ + char c = text.charAt(i); + if (Character.isDigit(c) && c != '0') return false; + if (Character.toUpperCase(c) == 'E') break; + } + return true; + } + + private static String parseStringCharacters(String chars) { + if (chars.indexOf('\\') < 0) return chars.intern(); + StringBuffer buffer = new StringBuffer(chars.length()); + int index = 0; + while(index < chars.length()){ + char c = chars.charAt(index++); + if (c != '\\'){ + buffer.append(c); + } + else{ + if (index == chars.length()) return null; + c = chars.charAt(index++); + switch(c){ + case 'b': + buffer.append('\b'); + break; + + case 't': + buffer.append('\t'); + break; + + case 'n': + buffer.append('\n'); + break; + + case 'f': + buffer.append('\f'); + break; + + case 'r': + buffer.append('\r'); + break; + + case '"': + buffer.append('"'); + break; + + case '\'': + buffer.append('\''); + break; + + case '\\': + buffer.append('\\'); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + char startC = c; + int v = (int)c - '0'; + if (index < chars.length()){ + c = chars.charAt(index++); + if ('0' <= c && c <= '7'){ + v <<= 3; + v += c - '0'; + if (startC <= '3' && index < chars.length()){ + c = chars.charAt(index++); + if ('0' <= c && c <= '7'){ + v <<= 3; + v += c - '0'; + } + else{ + index--; + } + } + } + else{ + index--; + } + } + buffer.append((char)v); + } + break; + + case 'u': + if (index + 4 <= chars.length()){ + try{ + int v = Integer.parseInt(chars.substring(index, index + 4), 16); + //line separators are invalid here + if (v == 0x000a || v == 0x000d) return null; + c = chars.charAt(index); + if (c == '+' || c == '-'){ + return null; + } + buffer.append((char)v); + index += 4; + } + catch(Exception e){ + return null; + } + } + else{ + return null; + } + break; + + default: + return null; + } + } + } + return buffer.toString().intern(); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitLiteralExpression(this); + } + + public String toString() { + return "PsiLiteralExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLocalVariableImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLocalVariableImpl.java new file mode 100644 index 00000000000..4ef54bc6e84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiLocalVariableImpl.java @@ -0,0 +1,238 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiConstantEvaluationHelperImpl; +import com.intellij.psi.impl.PsiVariableEx; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + +import java.util.HashSet; +import java.util.Set; + +public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLocalVariable, PsiVariableEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLocalVariableImpl"); + + private String myCachedName = null; + + public PsiLocalVariableImpl() { + super(LOCAL_VARIABLE); + } + + public void clearCaches() { + super.clearCaches(); + myCachedName = null; + } + + public final PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME); + } + + public final String getName() { + if (myCachedName == null){ + myCachedName = getNameIdentifier().getText(); + } + return myCachedName; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public final PsiType getType() { + return SharedImplUtil.getType(this); + } + + public PsiTypeElement getTypeElement() { + CompositeElement first = (CompositeElement)TreeUtil.findChild(getTreeParent(), LOCAL_VARIABLE); + return (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(TreeUtil.findChild(first, TYPE)); + } + + public PsiModifierList getModifierList() { + CompositeElement first = (CompositeElement)TreeUtil.findChild(getTreeParent(), LOCAL_VARIABLE); + return (PsiModifierList)first.findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + + public boolean hasModifierProperty(String name) { + return getModifierList().hasModifierProperty(name); + } + + public PsiExpression getInitializer() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.INITIALIZER); + } + + public boolean hasInitializer() { + return getInitializer() != null; + } + + public Object computeConstantValue() { + return computeConstantValue(new HashSet()); + } + + public Object computeConstantValue(Set visitedVars) { + if (!hasModifierProperty(PsiModifier.FINAL)) return null; + + PsiType type = getType(); + if (type == null) return null; + // javac rejects all non primitive and non String constants, although JLS states constants "variables whose initializers are constant expressions" + if (!(type instanceof PsiPrimitiveType) && !type.equalsToText("java.lang.String")) return null; + + PsiExpression initializer = getInitializer(); + if (initializer == null) return null; + return PsiConstantEvaluationHelperImpl.computeCastTo(initializer, getType(), visitedVars); + } + + public int getTextOffset() { + return getNameIdentifier().getTextOffset(); + } + + public void normalizeDeclaration() throws IncorrectOperationException { + CheckUtil.checkWritable(this); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + + CompositeElement statement = getTreeParent(); + PsiElement[] variables = ((PsiDeclarationStatement)SourceTreeToPsiMap.treeElementToPsi(statement)).getDeclaredElements(); + if (variables.length > 1){ + //CodeStyleManagerImpl codeStyleManager = (CodeStyleManagerImpl)getManager().getCodeStyleManager(); + TreeElement type = SourceTreeToPsiMap.psiElementToTree(getTypeElement()); + TreeElement modifierList = SourceTreeToPsiMap.psiElementToTree(getModifierList()); + TreeElement last = statement; + for(int i = 1; i < variables.length; i++){ + CompositeElement variable = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(variables[i]); + + TreeElement comma = TreeUtil.skipElementsBack(variable.getTreePrev(), ElementType.WHITE_SPACE_OR_COMMENT_BIT_SET); + if (comma != null && comma.getElementType() == JavaTokenType.COMMA){ + CodeEditUtil.removeChildren(statement, comma, variable.getTreePrev()); + } + + CodeEditUtil.removeChild(statement, variable); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(statement); + variable.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + CompositeElement statement1 = Factory.createCompositeElement(DECLARATION_STATEMENT); + statement1.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + ChangeUtil.addChild(statement1, variable, null); + + TreeElement space = Factory.createSingleLeafElement(JavaTokenType.WHITE_SPACE, new char[]{' '}, 0, 1, treeCharTab, getManager()); + ChangeUtil.addChild(variable, space, variable.firstChild); + + TreeElement typeClone = (TreeElement)type.clone(); + typeClone.putUserData(CharTable.CHAR_TABLE_KEY, treeCharTab); + ChangeUtil.addChild(variable, typeClone, variable.firstChild); + + if (modifierList.getTextLength() > 0){ + space = Factory.createSingleLeafElement(JavaTokenType.WHITE_SPACE, new char[]{' '}, 0, 1, treeCharTab, getManager()); + ChangeUtil.addChild(variable, space, variable.firstChild); + } + + TreeElement modifierListClone = (TreeElement)modifierList.clone(); + modifierListClone.putUserData(CharTable.CHAR_TABLE_KEY, treeCharTab); + ChangeUtil.addChild(variable, modifierListClone, variable.firstChild); + + TreeElement semicolon = Factory.createSingleLeafElement(JavaTokenType.SEMICOLON, new char[]{';'}, 0, 1, treeCharTab, getManager()); + ChangeUtil.addChild((CompositeElement)SourceTreeToPsiMap.psiElementToTree(variables[i - 1]), semicolon, null); + + CodeEditUtil.addChild(statement.getTreeParent(), statement1, last.getTreeNext()); + + //? + //codeStyleManager.adjustInsertedCode(statement1); + last = statement1; + } + } + + SharedImplUtil.normalizeBrackets(this); + } + + public void deleteChildInternal(TreeElement child) { + if (getChildRole(child) == ChildRole.INITIALIZER){ + TreeElement eq = findChildByRole(ChildRole.INITIALIZER_EQ); + if (eq != null){ + deleteChildInternal(eq); + } + } + super.deleteChildInternal(child); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.MODIFIER_LIST: + return TreeUtil.findChild(this, MODIFIER_LIST); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, TYPE); + + case ChildRole.NAME: + return TreeUtil.findChild(this, JavaTokenType.IDENTIFIER); + + case ChildRole.INITIALIZER_EQ: + return TreeUtil.findChild(this, JavaTokenType.EQ); + + case ChildRole.INITIALIZER: + return TreeUtil.findChild(this, ElementType.EXPRESSION_BIT_SET); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, JavaTokenType.SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == MODIFIER_LIST) { + return ChildRole.MODIFIER_LIST; + } + else if (i == TYPE) { + return getChildRole(child, ChildRole.TYPE); + } + else if (i == JavaTokenType.IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == JavaTokenType.EQ) { + return getChildRole(child, ChildRole.INITIALIZER_EQ); + } + else if (i == JavaTokenType.SEMICOLON) { + return getChildRole(child, ChildRole.CLOSING_SEMICOLON); + } + else { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.INITIALIZER; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitLocalVariable(this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + if (lastParent == null) return true; + if (lastParent.getParent() != this) return true; + final TreeElement lastParentTree = SourceTreeToPsiMap.psiElementToTree(lastParent); + + if (getChildRole(lastParentTree) == ChildRole.INITIALIZER) + return processor.execute(this, substitutor); + return true; + } + + public ItemPresentation getPresentation() { + return SymbolPresentationUtil.getVariablePresentation(this); + } + + public String toString() { + return "PsiLocalVariable:" + getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java new file mode 100644 index 00000000000..6b215133579 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java @@ -0,0 +1,114 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.util.containers.HashMap; + +import java.util.Map; + +public class PsiMethodCallExpressionImpl extends CompositePsiElement implements PsiMethodCallExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl"); + + public PsiMethodCallExpressionImpl() { + super(METHOD_CALL_EXPRESSION); + } + + public PsiType getType() { + PsiReferenceExpression methodExpression = getMethodExpression(); + final ResolveResult result = methodExpression.advancedResolve(false); + final PsiMethod method = (PsiMethod)result.getElement(); + if (method == null) return null; + + PsiManager manager = getManager(); + if (manager.getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) >= 0) { + //JLS3 15.8.2 + if ("getClass".equals(method.getName()) && "java.lang.Object".equals(method.getContainingClass().getQualifiedName())) { + PsiExpression qualifier = methodExpression.getQualifierExpression(); + if (qualifier != null) { + PsiClass javaLangClass = manager.findClass("java.lang.Class", getResolveScope()); + if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) { + Map map = new HashMap(); + map.put(javaLangClass.getTypeParameters()[0], + PsiWildcardType.createExtends(manager, TypeConversionUtil.erasure(qualifier.getType()))); + PsiSubstitutor substitutor = manager.getElementFactory().createSubstitutor(map); + return manager.getElementFactory().createType(javaLangClass, substitutor); + } + } + } + } + + final PsiType ret = method.getReturnType(); + if (ret == null) return null; + PsiType substitutedReturnType = result.getSubstitutor().substituteAndCapture(ret); + return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedReturnType, this); + } + + public PsiMethod resolveMethod() { + return (PsiMethod)getMethodExpression().resolve(); + } + + public ResolveResult resolveMethodGenerics() { + return getMethodExpression().advancedResolve(false); + } + + public PsiReferenceParameterList getTypeArgumentList() { + return getMethodExpression().getParameterList(); + } + + public PsiType[] getTypeArguments() { + return getMethodExpression().getTypeParameters(); + } + + public PsiReferenceExpression getMethodExpression() { + return (PsiReferenceExpression)findChildByRoleAsPsiElement(ChildRole.METHOD_EXPRESSION); + } + + public PsiExpressionList getArgumentList() { + return (PsiExpressionList)findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.METHOD_EXPRESSION: + return firstChild; + + case ChildRole.ARGUMENT_LIST: + return TreeUtil.findChild(this, EXPRESSION_LIST); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == EXPRESSION_LIST) { + return ChildRole.ARGUMENT_LIST; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.METHOD_EXPRESSION; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitMethodCallExpression(this); + } + + public String toString() { + return "PsiMethodCallExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java new file mode 100644 index 00000000000..275a438bc28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java @@ -0,0 +1,197 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; + +/** + * @author ven + */ + +//Retrieves method reference from this pair, do NOT reuse!!! +public class PsiNameValuePairImpl extends CompositePsiElement implements PsiNameValuePair { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNameValuePairImpl"); + private String myCachedName = null; + private PsiIdentifier myCachedNameIdentifier = null; + private PsiAnnotationMemberValue myCachedValue = null; + private boolean myNameCached = false; + + public void clearCaches() { + myCachedName = null; + myCachedNameIdentifier = null; + myCachedValue = null; + myNameCached = false; + super.clearCaches(); + } + + public PsiNameValuePairImpl() { + super(NAME_VALUE_PAIR); + } + + public PsiIdentifier getNameIdentifier() { + if (!myNameCached) { + myCachedNameIdentifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME); + myCachedName = myCachedNameIdentifier == null ? null : myCachedNameIdentifier.getText(); + myNameCached = true; + } + return myCachedNameIdentifier; + } + + public String getName() { + if (!myNameCached) { + myCachedNameIdentifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME); + myCachedName = myCachedNameIdentifier == null ? null : myCachedNameIdentifier.getText(); + myNameCached = true; + } + return myCachedName; + } + + public PsiAnnotationMemberValue getValue() { + if (myCachedValue == null) { + myCachedValue = (PsiAnnotationMemberValue)findChildByRoleAsPsiElement(ChildRole.ANNOTATION_VALUE); + } + + return myCachedValue; + } + + public int getChildRole(TreeElement child) { + if (ANNOTATION_MEMBER_VALUE_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.ANNOTATION_VALUE; + } else if (child.getElementType() == IDENTIFIER) { + return ChildRole.NAME; + } else if (child.getElementType() == EQ) { + return ChildRole.OPERATION_SIGN; + } + + return ChildRole.NONE; + } + + public TreeElement findChildByRole(int role) { + if (role == ChildRole.NAME) { + return TreeUtil.findChild(this, IDENTIFIER); + } else if (role == ChildRole.ANNOTATION_VALUE) { + return TreeUtil.findChild(this, ANNOTATION_MEMBER_VALUE_BIT_SET); + } else if (role == ChildRole.OPERATION_SIGN) { + return TreeUtil.findChild(this, EQ); + } + + return null; + } + + public String toString() { + return "PsiNameValuePair"; + } + + public PsiReference getReference() { + return new PsiReference() { + private PsiClass getReferencedClass () { + LOG.assertTrue(getTreeParent().getElementType() == ANNOTATION_PARAMETER_LIST && getTreeParent().getTreeParent().getElementType() == ANNOTATION); + PsiAnnotationImpl annotation = (PsiAnnotationImpl)getTreeParent().getTreeParent(); + PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); + return nameRef == null ? null : (PsiClass)nameRef.resolve(); + }; + + public PsiElement getElement() { + PsiIdentifier nameIdentifier = getNameIdentifier(); + if (nameIdentifier != null) { + return nameIdentifier; + } else { + return PsiNameValuePairImpl.this; + } + } + + public TextRange getRangeInElement() { + PsiIdentifier id = getNameIdentifier(); + if (id != null) { + return new TextRange(0, id.getTextLength()); + } + else { + return new TextRange(0, getTextLength()); + } + } + + public PsiElement resolve() { + PsiClass refClass = getReferencedClass(); + if (refClass == null) return null; + String name = getName(); + if (name == null) name = PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME; + MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, PsiType.EMPTY_ARRAY, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + return MethodSignatureUtil.findMethodBySignature(refClass, signature, false); + } + + public String getCanonicalText() { + String name = getName(); + return name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME; + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + PsiIdentifier nameIdentifier = getNameIdentifier(); + if (nameIdentifier != null) { + SharedPsiElementImplUtil.setName(nameIdentifier, newElementName); + } else if (ANNOTATION_MEMBER_VALUE_BIT_SET.isInSet(firstChild.getElementType())) { + PsiElementFactory factory = getManager().getElementFactory(); + nameIdentifier = factory.createIdentifier(newElementName); + addBefore(nameIdentifier, SourceTreeToPsiMap.treeElementToPsi(firstChild)); + } + + return PsiNameValuePairImpl.this; + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException("Not implemented"); + } + + public boolean isReferenceTo(PsiElement element) { + if (element instanceof PsiMethod) { + return element.equals(resolve()); + } + + return false; + } + + public Object[] getVariants() { + PsiClass aClass = getReferencedClass(); + if (aClass != null) { + return aClass.getMethods(); + } else { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + } + + public boolean isSoft() { + return false; + } + }; + } + + public final void accept(PsiElementVisitor visitor) { + visitor.visitNameValuePair(this); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + final TreeElement treeElement = super.addInternal(first, last, anchor, before); + if (first == last && first.getElementType() == ElementType.IDENTIFIER) { + LeafElement eq = Factory.createSingleLeafElement(ElementType.EQ, new char[]{'='}, 0, 1, treeCharTab, getManager()); + super.addInternal(eq, eq, first, Boolean.FALSE); + } + return treeElement; + } + + public void deleteChildInternal(TreeElement child) { + super.deleteChildInternal(child); + if (child.getElementType() == ElementType.IDENTIFIER) { + super.deleteChildInternal(findChildByRole(ChildRole.OPERATION_SIGN)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java new file mode 100644 index 00000000000..c9a26d41324 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java @@ -0,0 +1,244 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; + +public class PsiNewExpressionImpl extends CompositePsiElement implements PsiNewExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl"); + + public PsiNewExpressionImpl() { + super(NEW_EXPRESSION); + } + + public PsiType getType(){ + PsiType type = null; + for(TreeElement child = firstChild; child != null; child = child.getTreeNext()){ + if (child.getElementType() == JAVA_CODE_REFERENCE){ + LOG.assertTrue(type == null); + type = new PsiClassReferenceType((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(child)); + } + else if (PRIMITIVE_TYPE_BIT_SET.isInSet(child.getElementType())){ + LOG.assertTrue(type == null); + type = getManager().getElementFactory().createPrimitiveType(child.getText()); + } + else if (child.getElementType() == LBRACKET){ + LOG.assertTrue(type != null); + type = type.createArrayType(); + } + else if (child.getElementType() == ANONYMOUS_CLASS){ + PsiElementFactory factory = getManager().getElementFactory(); + type = factory.createType((PsiClass)SourceTreeToPsiMap.treeElementToPsi(child)); + } + } + return type; + } + + public PsiExpressionList getArgumentList() { + PsiExpressionList list = (PsiExpressionList)findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); + if (list != null) return list; + CompositeElement anonymousClass = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(findChildByRoleAsPsiElement(ChildRole.ANONYMOUS_CLASS)); + if (anonymousClass != null){ + return (PsiExpressionList)anonymousClass.findChildByRoleAsPsiElement(ChildRole.ARGUMENT_LIST); + } + return null; + } + + public PsiExpression[] getArrayDimensions() { + PsiExpression[] expressions = (PsiExpression[])getChildrenAsPsiElements(ARRAY_DIMENSION_BIT_SET, PSI_EXPRESSION_ARRAY_CONSTRUCTOR); + PsiExpression qualifier = getQualifier(); + if (qualifier == null){ + return expressions; + } + else{ + LOG.assertTrue(expressions[0] == qualifier); + PsiExpression[] expressions1 = new PsiExpression[expressions.length - 1]; + System.arraycopy(expressions, 1, expressions1, 0, expressions1.length); + return expressions1; + } + } + + public PsiArrayInitializerExpression getArrayInitializer() { + return (PsiArrayInitializerExpression)findChildByRoleAsPsiElement(ChildRole.ARRAY_INITIALIZER); + } + + public PsiMethod resolveMethod() { + return resolveConstructor(); + } + + public ResolveResult resolveMethodGenerics() { + TreeElement classRef = findChildByRole(ChildRole.TYPE_REFERENCE); + if (classRef != null){ + TreeElement argumentList = TreeUtil.skipElements(classRef.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (argumentList != null && argumentList.getElementType() == EXPRESSION_LIST) { + PsiType aClass = getManager().getElementFactory().createType( + (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(classRef)); + if (aClass != null) { + return getManager().getResolveHelper().resolveConstructor((PsiClassType)aClass, + (PsiExpressionList)SourceTreeToPsiMap.treeElementToPsi(argumentList), + this); + } + } + } + else{ + TreeElement anonymousClass = TreeUtil.findChild(this, ANONYMOUS_CLASS); + if (anonymousClass != null) { + PsiType aClass = ((PsiAnonymousClass)SourceTreeToPsiMap.treeElementToPsi(anonymousClass)).getBaseClassType(); + if (aClass != null) { + TreeElement argumentList = TreeUtil.findChild((CompositeElement)anonymousClass, EXPRESSION_LIST); + return getManager().getResolveHelper().resolveConstructor((PsiClassType)aClass, + (PsiExpressionList)SourceTreeToPsiMap.treeElementToPsi(argumentList), + this); + } + } + } + + return ResolveResult.EMPTY; + } + + public PsiExpression getQualifier() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiReferenceParameterList getTypeArgumentList() { + return (PsiReferenceParameterList) findChildByRoleAsPsiElement(ChildRole.REFERENCE_PARAMETER_LIST); + } + + public PsiType[] getTypeArguments() { + return getTypeArgumentList().getTypeArguments(); + } + + public PsiMethod resolveConstructor(){ + return (PsiMethod)resolveMethodGenerics().getElement(); + } + + public PsiJavaCodeReferenceElement getClassReference() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.TYPE_REFERENCE); + } + + public PsiAnonymousClass getAnonymousClass() { + TreeElement anonymousClass = TreeUtil.findChild(this, ANONYMOUS_CLASS); + if (anonymousClass == null) return null; + return (PsiAnonymousClass)SourceTreeToPsiMap.treeElementToPsi(anonymousClass); + } + + public void deleteChildInternal(TreeElement child) { + if (getChildRole(child) == ChildRole.QUALIFIER){ + TreeElement dot = findChildByRole(ChildRole.DOT); + super.deleteChildInternal(child); + deleteChildInternal(dot); + } + else{ + super.deleteChildInternal(child); + } + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.REFERENCE_PARAMETER_LIST: + return TreeUtil.findChild(this, REFERENCE_PARAMETER_LIST); + + case ChildRole.QUALIFIER: + return firstChild.getElementType() != NEW_KEYWORD ? firstChild : null; + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + + case ChildRole.NEW_KEYWORD: + return TreeUtil.findChild(this, NEW_KEYWORD); + + case ChildRole.ANONYMOUS_CLASS: + return TreeUtil.findChild(this, ANONYMOUS_CLASS); + + case ChildRole.TYPE_REFERENCE: + return TreeUtil.findChild(this, JAVA_CODE_REFERENCE); + + case ChildRole.TYPE_KEYWORD: + return TreeUtil.findChild(this, PRIMITIVE_TYPE_BIT_SET); + + case ChildRole.ARGUMENT_LIST: + return TreeUtil.findChild(this, EXPRESSION_LIST); + + case ChildRole.LBRACKET: + return TreeUtil.findChild(this, LBRACKET); + + case ChildRole.RBRACKET: + return TreeUtil.findChild(this, RBRACKET); + + case ChildRole.ARRAY_INITIALIZER: + if (lastChild.getElementType() == ARRAY_INITIALIZER_EXPRESSION){ + return lastChild; + } + else{ + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == REFERENCE_PARAMETER_LIST) { + return ChildRole.REFERENCE_PARAMETER_LIST; + } + else if (i == NEW_KEYWORD) { + return ChildRole.NEW_KEYWORD; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.TYPE_REFERENCE; + } + else if (i == EXPRESSION_LIST) { + return ChildRole.ARGUMENT_LIST; + } + else if (i == LBRACKET) { + return ChildRole.LBRACKET; + } + else if (i == RBRACKET) { + return ChildRole.RBRACKET; + } + else if (i == ARRAY_INITIALIZER_EXPRESSION) { + if (child == lastChild) { + return ChildRole.ARRAY_INITIALIZER; + } + else if (child == firstChild) { + return ChildRole.QUALIFIER; + } + else { + return ChildRole.ARRAY_DIMENSION; + } + } + else if (i == ANONYMOUS_CLASS) { + return ChildRole.ANONYMOUS_CLASS; + } + else { + if (PRIMITIVE_TYPE_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.TYPE_KEYWORD; + } + else if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return child == firstChild ? ChildRole.QUALIFIER : ChildRole.ARRAY_DIMENSION; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitNewExpression(this); + } + + public String toString(){ + return "PsiNewExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java new file mode 100644 index 00000000000..b85cd65aeee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java @@ -0,0 +1,73 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiModifierList; +import com.intellij.psi.PsiPackageStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; + +public class PsiPackageStatementImpl extends CompositePsiElement implements PsiPackageStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiPackageStatementImpl"); + + public PsiPackageStatementImpl() { + super(PACKAGE_STATEMENT); + } + + public PsiJavaCodeReferenceElement getPackageReference() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.PACKAGE_REFERENCE); + } + + public String getPackageName() { + PsiJavaCodeReferenceElement ref = getPackageReference(); + return SourceUtil.getTextSkipWhiteSpaceAndComments(SourceTreeToPsiMap.psiElementToTree(ref)); + } + + public PsiModifierList getAnnotationList() { + return (PsiModifierList)findChildByRoleAsPsiElement(ChildRole.MODIFIER_LIST); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.PACKAGE_KEYWORD: + return firstChild; + + case ChildRole.PACKAGE_REFERENCE: + return TreeUtil.findChild(this, JAVA_CODE_REFERENCE); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == PACKAGE_KEYWORD) { + return ChildRole.PACKAGE_KEYWORD; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.PACKAGE_REFERENCE; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPackageStatement(this); + } + + public String toString() { + return "PsiPackageStatement:" + getPackageName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiParenthesizedExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiParenthesizedExpressionImpl.java new file mode 100644 index 00000000000..4586e1a5cb7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiParenthesizedExpressionImpl.java @@ -0,0 +1,71 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiParenthesizedExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiParenthesizedExpressionImpl extends CompositePsiElement implements PsiParenthesizedExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiParenthesizedExpressionImpl"); + + public PsiParenthesizedExpressionImpl() { + super(PARENTH_EXPRESSION); + } + + public PsiExpression getExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.EXPRESSION); + } + + public PsiType getType() { + PsiExpression expr = getExpression(); + if (expr == null) return null; + return expr.getType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.EXPRESSION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.EXPRESSION; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitParenthesizedExpression(this); + } + + public String toString() { + return "PsiParenthesizedExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java new file mode 100644 index 00000000000..4e8ea4f17a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java @@ -0,0 +1,58 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class PsiPostfixExpressionImpl extends CompositePsiElement implements PsiPostfixExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiPostfixExpressionImpl"); + + public PsiPostfixExpressionImpl() { + super(POSTFIX_EXPRESSION); + } + + public PsiExpression getOperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.OPERAND); + } + + public PsiJavaToken getOperationSign() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.OPERATION_SIGN); + } + + public PsiType getType() { + return getOperand().getType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.OPERAND: + return firstChild; + + case ChildRole.OPERATION_SIGN: + return lastChild; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child == firstChild) return ChildRole.OPERAND; + if (child == lastChild) return ChildRole.OPERATION_SIGN; + return ChildRole.NONE; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPostfixExpression(this); + } + + public String toString() { + return "PsiPostfixExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java new file mode 100644 index 00000000000..be998d84d85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java @@ -0,0 +1,84 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiElementFactoryImpl; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class PsiPrefixExpressionImpl extends CompositePsiElement implements PsiPrefixExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiPrefixExpressionImpl"); + + public PsiPrefixExpressionImpl() { + super(PREFIX_EXPRESSION); + } + + public PsiExpression getOperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.OPERAND); + } + + public PsiJavaToken getOperationSign() { + return (PsiJavaToken)findChildByRoleAsPsiElement(ChildRole.OPERATION_SIGN); + } + + public PsiType getType() { + PsiElementFactoryImpl factory = (PsiElementFactoryImpl)getManager().getElementFactory(); + PsiExpression operand = getOperand(); + if (operand == null) return null; + PsiType type = operand.getType(); + IElementType opCode = (SourceTreeToPsiMap.psiElementToTree(getOperationSign())).getElementType(); + if (opCode == PLUS || opCode == MINUS || opCode == TILDE) { + if (type == null) return null; + if (type == PsiType.BYTE || type == PsiType.CHAR || type == PsiType.SHORT) { + return PsiType.INT; + } + else { + return type; + } + } + else if (opCode == PLUSPLUS || opCode == MINUSMINUS) { + return type; + } + else if (opCode == EXCL) { + return PsiType.BOOLEAN; + } + else { + LOG.assertTrue(false); + return null; + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.OPERATION_SIGN: + return firstChild; + + case ChildRole.OPERAND: + return EXPRESSION_BIT_SET.isInSet(lastChild.getElementType()) ? lastChild : null; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child == firstChild) return ChildRole.OPERATION_SIGN; + if (child == lastChild && EXPRESSION_BIT_SET.isInSet(child.getElementType())) return ChildRole.OPERAND; + return ChildRole.NONE; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitPrefixExpression(this); + } + + public String toString() { + return "PsiPrefixExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java new file mode 100644 index 00000000000..9ae3c4442e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -0,0 +1,569 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.filters.ConstructorFilter; +import com.intellij.psi.filters.NotFilter; +import com.intellij.psi.filters.OrFilter; +import com.intellij.psi.impl.CheckUtil; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiSubstitutorEx; +import com.intellij.psi.impl.source.SourceJavaCodeReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerEx; +import com.intellij.psi.impl.source.parsing.ExpressionParsing; +import com.intellij.psi.impl.source.resolve.ClassResolverProcessor; +import com.intellij.psi.impl.source.resolve.ResolveCache; +import com.intellij.psi.impl.source.resolve.VariableResolverProcessor; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.MethodProcessorSetupFailedException; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.processor.MethodResolverProcessor; +import com.intellij.psi.scope.processor.VariablesProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; + + +public class PsiReferenceExpressionImpl extends CompositePsiElement implements PsiReferenceExpression, SourceJavaCodeReference { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl"); + + private String myCachedQName = null; + private String myCachedTextSkipWhiteSpaceAndComments = null; + + public PsiReferenceExpressionImpl() { + super(REFERENCE_EXPRESSION); + } + + public PsiExpression getQualifierExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiElement bindToElementViaStaticImport(PsiClass qualifierClass) throws IncorrectOperationException { + if (qualifierClass == null || qualifierClass.getQualifiedName() == null) throw new IncorrectOperationException(); + + String staticName = getReferenceName(); + if (getQualifierExpression() == null) { + PsiImportList importList = ((PsiJavaFile)getContainingFile()).getImportList(); + PsiImportStatementBase singleImportStatement = importList.findSingleImportStatement(staticName); + if (singleImportStatement != null) { + if (singleImportStatement instanceof PsiImportStaticStatement) { + String qName = qualifierClass.getQualifiedName() + "." + staticName; + if (singleImportStatement.getImportReference().getQualifiedName().equals(qName)) return this; + } + String qualifiedName = qualifierClass.getQualifiedName(); + if (qualifiedName != null) { + PsiReferenceExpression classRef = getManager().getElementFactory().createReferenceExpression(qualifierClass); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + LeafElement dot = Factory.createSingleLeafElement(ElementType.DOT, new char[]{'.'}, 0, 1, treeCharTab, getManager()); + addInternal(dot, dot, SourceTreeToPsiMap.psiElementToTree(getParameterList()), Boolean.TRUE); + addBefore(classRef, SourceTreeToPsiMap.treeElementToPsi(dot)); + return this; + } + } + else { + importList.add(getManager().getElementFactory().createImportStaticStatement(qualifierClass, staticName)); + return this; + } + } + + throw new IncorrectOperationException(); + } + + public PsiElement getQualifier() { + return getQualifierExpression(); + } + + // very special method + public void setCachedResolveResult(PsiElement result, Boolean problemWithAccess, Boolean problemWithStatic) { + ResolveCache resolveCache = ((PsiManagerImpl)getManager()).getResolveCache(); + resolveCache.setCachedJavaResolve(this, new ResolveResult[]{new CandidateInfo(result, PsiSubstitutor.EMPTY)}, true, true); + } + + public PsiReference getReference() { + return this; + } + + public PsiElement resolve() { + return advancedResolve(false).getElement(); + } + + public void clearCaches() { + myCachedQName = null; + myCachedTextSkipWhiteSpaceAndComments = null; + super.clearCaches(); + } + + private static final class OurGenericsResolver implements ResolveCache.GenericsResolver { + public static final OurGenericsResolver INSTANCE = new OurGenericsResolver(); + + public ResolveResult[] _resolve(PsiJavaReference ref, boolean incompleteCode) { + final PsiReferenceExpressionImpl _ref = (PsiReferenceExpressionImpl)ref; + IElementType parentType = _ref.getTreeParent() != null ? _ref.getTreeParent().getElementType() : null; + final ResolveResult[] result = _ref._resolve(parentType); + + if (incompleteCode && parentType != REFERENCE_EXPRESSION && result.length == 0){ + return _ref._resolve(REFERENCE_EXPRESSION); + } + return result; + } + + public ResolveResult[] resolve(PsiJavaReference ref, boolean incompleteCode) { + final ResolveResult[] result = _resolve(ref, incompleteCode); + if (result.length > 0 && result[0].getElement() instanceof PsiClass){ + final PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters(); + final ResolveResult[] newResult = new ResolveResult[result.length]; + for(int i = 0; i < result.length; i++){ + final CandidateInfo resolveResult = (CandidateInfo)result[i]; + newResult[i] = new CandidateInfo( + resolveResult, + ((PsiSubstitutorEx)resolveResult.getSubstitutor()).inplacePutAll((PsiClass)resolveResult.getElement(), parameters) + ); + } + return newResult; + } + return result; + } + } + + private ResolveResult[] _resolve(IElementType parentType) { + if (parentType == null) + parentType = getTreeParent() != null ? getTreeParent().getElementType() : null; + if (parentType == REFERENCE_EXPRESSION) { + { + { + final VariableResolverProcessor processor = new VariableResolverProcessor(this); + PsiScopesUtil.resolveAndWalk(processor, this, null); + ResolveResult[] result = processor.getResult(); + + if (result.length > 0) { + return processor.getResult(); + } + } + { + final PsiElement classNameElement; + classNameElement = getReferenceNameElement(); + if (!(classNameElement instanceof PsiIdentifier)) return ResolveResult.EMPTY_ARRAY; + final String className = classNameElement.getText(); + + final ClassResolverProcessor processor = new ClassResolverProcessor(className, this); + PsiScopesUtil.resolveAndWalk(processor, this, null); + ResolveResult[] result = processor.getResult(); + if (result.length > 0) { + return processor.getResult(); + } + } + { + final String packageName = getCachedTextSkipWhiteSpaceAndComments(); + final PsiManager manager = getManager(); + final PsiPackage aPackage = manager.findPackage(packageName); + if (aPackage == null) { + if (!manager.isPartOfPackagePrefix(packageName)) { + return ResolveResult.EMPTY_ARRAY; + } + else { + return CandidateInfo.RESOLVE_RESULT_FOR_PACKAGE_PREFIX_PACKAGE; + } + } + return new ResolveResult[]{new CandidateInfo(aPackage, PsiSubstitutor.EMPTY)}; + } + } + } + else if (parentType == METHOD_CALL_EXPRESSION) { + { + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)getParent(); + final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall); + try { + PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); + } + catch (MethodProcessorSetupFailedException e) { + return ResolveResult.EMPTY_ARRAY; + } + return processor.getResult(); + } + } + else if (parentType == SWITCH_LABEL_STATEMENT) { + if (!isQualified()) { + PsiSwitchStatement switchStatement = ((PsiSwitchLabelStatement)SourceTreeToPsiMap.treeElementToPsi(getTreeParent())).getEnclosingSwitchStatement(); + if (switchStatement != null) { + PsiExpression expression = switchStatement.getExpression(); + if (expression != null && expression.getType() instanceof PsiClassType) { + PsiClass aClass = ((PsiClassType)expression.getType()).resolve(); + if (aClass != null && aClass.isEnum()) { + VariablesProcessor processor = new VariablesProcessor(true) { + protected boolean check(PsiVariable var, PsiSubstitutor substitutor) { + return var instanceof PsiEnumConstant && var.getName().equals(getReferenceName()); + } + }; + PsiScopesUtil.treeWalkUp(processor, aClass, aClass); + if (processor.size() == 1) { + return new ResolveResult[]{new CandidateInfo(processor.getResult(0), PsiSubstitutor.EMPTY)}; + } + + return ResolveResult.EMPTY_ARRAY; + } + } + } + } + //fall through + { + final VariableResolverProcessor processor = new VariableResolverProcessor(this); + PsiScopesUtil.resolveAndWalk(processor, this, null); + return processor.getResult(); + } + } + else { + { + final VariableResolverProcessor processor = new VariableResolverProcessor(this); + PsiScopesUtil.resolveAndWalk(processor, this, null); + return processor.getResult(); + } + } + } + + public ResolveResult[] multiResolve(boolean incompleteCode) { + final PsiManager manager = getManager(); + if (manager == null){ + LOG.assertTrue(false, "getManager() == null!"); + return null; + } + + final ResolveCache resolveCache = ((PsiManagerImpl)manager).getResolveCache(); + return resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, false, incompleteCode); + } + + public String getCanonicalText() { + PsiElement element = resolve(); + if (element instanceof PsiClass) return ((PsiClass)element).getQualifiedName(); + return getCachedTextSkipWhiteSpaceAndComments(); + } + + public String getQualifiedName() { + return getCanonicalText(); + } + + public String getReferenceName() { + PsiElement element = getReferenceNameElement(); + if (element == null) return null; + return element.getText(); + } + + public static final String LENGTH = "length"; + + public PsiType getType() { + ResolveResult result = advancedResolve(false); + PsiElement resolve = result.getElement(); + if (resolve == null){ + TreeElement refName = findChildByRole(ChildRole.REFERENCE_NAME); + if (refName != null && refName.textMatches(LENGTH)){ + TreeElement qualifier = findChildByRole(ChildRole.QUALIFIER); + if (qualifier != null && ElementType.EXPRESSION_BIT_SET.isInSet(qualifier.getElementType())){ + PsiType type = ((PsiExpression)SourceTreeToPsiMap.treeElementToPsi(qualifier)).getType(); + if (type != null && type instanceof PsiArrayType){ + return PsiType.INT; + } + } + } + return null; + } + + final PsiType ret; + if (resolve instanceof PsiVariable){ + PsiType type = ((PsiVariable)resolve).getType(); + ret = type instanceof PsiEllipsisType ? ((PsiEllipsisType)type).toArrayType() : type; + } + else if (resolve instanceof PsiMethod){ + ret = ((PsiMethod)resolve).getReturnType(); + } + else{ + return null; + } + + PsiType substitutedType = result.getSubstitutor().substitute(ret); + return PsiImplUtil.normalizeWildcardTypeByPosition(substitutedType, this); + } + + public boolean isReferenceTo(PsiElement element) { + IElementType i = lastChild.getElementType(); + if (i == IDENTIFIER) { + { + if (!(element instanceof PsiPackage)) { + if (!(element instanceof PsiNamedElement)) return false; + String name = ((PsiNamedElement)element).getName(); + if (name == null) return false; + if (!name.equals(lastChild.getText())) return false; + } + } + } + else if (i == SUPER_KEYWORD || i == THIS_KEYWORD) { + if (!(element instanceof PsiMethod)) return false; + if (!((PsiMethod)element).isConstructor()) return false; + } + else { + LOG.assertTrue(false); + } + + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + LOG.assertTrue(false, "This method should _not_ be used for PsiJavaReference!"); + return null; + } + + public boolean isSoft() { + return false; + } + + public void processVariants(PsiScopeProcessor processor) { + OrFilter filter = new OrFilter(); + filter.addFilter(new ClassFilter(PsiClass.class)); + filter.addFilter(new ClassFilter(PsiPackage.class)); + filter.addFilter(new NotFilter(new ConstructorFilter())); + filter.addFilter(new ClassFilter(PsiVariable.class)); + + FilterScopeProcessor proc = new FilterScopeProcessor(filter, this, processor); + PsiScopesUtil.resolveAndWalk(proc, this, null, true); + } + + public ResolveResult advancedResolve(boolean incompleteCode) { + final ResolveResult[] results = multiResolve(incompleteCode); + if (results.length == 1) return results[0]; + return ResolveResult.EMPTY; + } + + public PsiElement getReferenceNameElement() { + return findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + } + + public PsiReferenceParameterList getParameterList() { + return (PsiReferenceParameterList) findChildByRoleAsPsiElement(ChildRole.REFERENCE_PARAMETER_LIST); + } + + public int getTextOffset() { + TreeElement refName = findChildByRole(ChildRole.REFERENCE_NAME); + if (refName != null){ + return refName.getStartOffset(); + } + else{ + return super.getTextOffset(); + } + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + if (getQualifierExpression() != null) { + return renameDirectly(newElementName); + } + final ResolveResult resolveResult = advancedResolve(false); + if (resolveResult.getElement() == null) { + return renameDirectly(newElementName); + } + PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); + if (!(currentFileResolveScope instanceof PsiImportStaticStatement)|| ((PsiImportStaticStatement)currentFileResolveScope).isOnDemand()) { + return renameDirectly(newElementName); + } + final PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement)currentFileResolveScope; + final String referenceName = importStaticStatement.getReferenceName(); + LOG.assertTrue(referenceName != null); + final PsiElement element = importStaticStatement.getImportReference().resolve(); + if (getManager().areElementsEquivalent(element, resolveResult.getElement())) { + return renameDirectly(newElementName); + } + final PsiClass psiClass = importStaticStatement.resolveTargetClass(); + if (psiClass == null) return renameDirectly(newElementName); + final PsiElementFactory factory = getManager().getElementFactory(); + final PsiReferenceExpression expression = (PsiReferenceExpression)factory.createExpressionFromText("X." + newElementName, this); + final PsiReferenceExpression result = ((PsiReferenceExpression)this.replace(expression)); + ((PsiReferenceExpression)result.getQualifierExpression()).bindToElement(psiClass); + return result; + } + + private PsiElement renameDirectly(String newElementName) throws IncorrectOperationException { + PsiElement oldIdentifier = findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + if (oldIdentifier == null){ + throw new IncorrectOperationException(); + } + PsiIdentifier identifier = getManager().getElementFactory().createIdentifier(newElementName); + oldIdentifier.replace(identifier); + return this; + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + CheckUtil.checkWritable(this); + + if (isReferenceTo(element)) return this; + + PsiManager manager = getManager(); + if (element instanceof PsiClass){ + String qName = ((PsiClass)element).getQualifiedName(); + if (qName == null){ + qName = ((PsiClass)element).getName(); + final PsiClass psiClass = getManager().getResolveHelper().resolveReferencedClass(qName, this); + if(!getManager().areElementsEquivalent(psiClass, element)){ + throw new IncorrectOperationException(); + } + } + else { + if (getManager().findClass(qName, getResolveScope()) == null) { + return this; + } + } + boolean wasFullyQualified = isFullyQualified(this); + final CharTable table = SharedImplUtil.findCharTableByTree(getTreeParent()); + TreeElement ref = ExpressionParsing.parseExpressionText(manager, qName.toCharArray(), 0, qName.toCharArray().length, table); + getTreeParent().replaceChildInternal(this, ref); + CodeStyleManagerEx codeStyleManager = (CodeStyleManagerEx)manager.getCodeStyleManager(); + if (!wasFullyQualified){ + ref = SourceTreeToPsiMap.psiElementToTree( + codeStyleManager.shortenClassReferences(SourceTreeToPsiMap.treeElementToPsi(ref), CodeStyleManagerEx.UNCOMPLETE_CODE) + ); + } + return SourceTreeToPsiMap.treeElementToPsi(ref); + } + else if (element instanceof PsiPackage){ + String qName = ((PsiPackage)element).getQualifiedName(); + if (qName.length() == 0){ + throw new IncorrectOperationException(); + } + final CharTable table = SharedImplUtil.findCharTableByTree(getTreeParent()); + TreeElement ref = ExpressionParsing.parseExpressionText(manager, qName.toCharArray(), 0, qName.length(), table); + getTreeParent().replaceChildInternal(this, ref); + return SourceTreeToPsiMap.treeElementToPsi(ref); + } + else{ + throw new IncorrectOperationException(); + } + } + + private static boolean isFullyQualified(CompositeElement classRef) { + TreeElement qualifier = classRef.findChildByRole(ChildRole.QUALIFIER); + if (qualifier == null) return false; + if (qualifier.getElementType() != REFERENCE_EXPRESSION) return false; + PsiElement refElement = ((PsiReference)qualifier).resolve(); + if (refElement instanceof PsiPackage) return true; + return isFullyQualified((CompositeElement)qualifier); + } + + public void deleteChildInternal(TreeElement child) { + if (getChildRole(child) == ChildRole.QUALIFIER){ + TreeElement dot = findChildByRole(ChildRole.DOT); + super.deleteChildInternal(child); + deleteChildInternal(dot); + } + else{ + super.deleteChildInternal(child); + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.REFERENCE_NAME: + return getChildRole(lastChild) == role ? lastChild : null; + + case ChildRole.QUALIFIER: + if (getChildRole(firstChild) == ChildRole.QUALIFIER){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.REFERENCE_PARAMETER_LIST: + return TreeUtil.findChild(this, REFERENCE_PARAMETER_LIST); + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == DOT) { + return ChildRole.DOT; + } + else if (i == REFERENCE_PARAMETER_LIST) { + return ChildRole.REFERENCE_PARAMETER_LIST; + } + else if (i == IDENTIFIER || i == THIS_KEYWORD || i == SUPER_KEYWORD) { + return ChildRole.REFERENCE_NAME; + } + else { + if (ElementType.EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.QUALIFIER; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceExpression(this); + } + + public String toString() { + return "PsiReferenceExpression:" + getText(); + } + + public TextRange getRangeInElement() { + TreeElement nameChild = findChildByRole(ChildRole.REFERENCE_NAME); + return new TextRange(nameChild != null ? nameChild.getStartOffsetInParent() : 0, getTextLength()); + } + + public PsiElement getElement() { + return this; + } + + public PsiType[] getTypeParameters() { + final PsiReferenceParameterList parameterList = getParameterList(); + if (parameterList == null) return PsiType.EMPTY_ARRAY; + PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); + + PsiType[] types = new PsiType[typeElements.length]; + for(int i = 0; i < types.length; i++){ + types[i] = typeElements[i].getType(); + } + return types; + } + + + public String getClassNameText() { + if (myCachedQName == null) { + myCachedQName = PsiNameHelper.getQualifiedClassName(getCachedTextSkipWhiteSpaceAndComments(), false); + } + return myCachedQName; + } + + public void fullyQualify(PsiClass targetClass) { + SourceUtil.fullyQualifyReference(this, targetClass); + } + + public boolean isQualified() { + return getChildRole(firstChild) == ChildRole.QUALIFIER; + } + + public TreeElement getTreeQualifier() { + return findChildByRole(ChildRole.QUALIFIER); + } + + public void dequalify() { + SourceUtil.dequalifyImpl(this); + } + + private String getCachedTextSkipWhiteSpaceAndComments() { + if (myCachedTextSkipWhiteSpaceAndComments == null) { + myCachedTextSkipWhiteSpaceAndComments = SourceUtil.getTextSkipWhiteSpaceAndComments(this); + } + return myCachedTextSkipWhiteSpaceAndComments; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java new file mode 100644 index 00000000000..edc44041692 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java @@ -0,0 +1,164 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReferenceParameterList; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; + +/** + * @author dsl + */ +public class PsiReferenceParameterListImpl extends CompositePsiElement implements PsiReferenceParameterList{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceParameterListImpl"); + + public PsiReferenceParameterListImpl() { + super(REFERENCE_PARAMETER_LIST); + } + + public PsiTypeElement[] getTypeParameterElements() { + return (PsiTypeElement[]) getChildrenAsPsiElements(TYPES_BIT_SET, PSI_TYPE_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiType[] getTypeArguments() { + return PsiImplUtil.typesByReferenceParameterList(this); + } + + public int getChildRole(TreeElement child) { + IElementType i = child.getElementType(); + if (i == TYPE) { + return ChildRole.TYPE_IN_REFERENCE_PARAMETER_LIST; + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == LT) { + return ChildRole.LT_IN_TYPE_LIST; + } + else if (i == GT) { + return ChildRole.GT_IN_TYPE_LIST; + } + else { + return ChildRole.NONE; + } + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + ChameleonTransforming.transformChildren(this); + switch(role){ + default: + return null; + + case ChildRole.LT_IN_TYPE_LIST: + if (firstChild != null && firstChild.getElementType() == LT){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.GT_IN_TYPE_LIST: + if (lastChild != null && lastChild.getElementType() == GT){ + return lastChild; + } + else{ + return null; + } + } + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before){ + if (first == last && first.getElementType() == TYPE){ + if (lastChild != null && lastChild.getElementType() == ERROR_ELEMENT){ + super.deleteChildInternal(lastChild); + } + } + + if (anchor == null){ + if (before == null || before.booleanValue()){ + anchor = findChildByRole(ChildRole.GT_IN_TYPE_LIST); + before = Boolean.TRUE; + } + else{ + anchor = findChildByRole(ChildRole.LT_IN_TYPE_LIST); + before = Boolean.FALSE; + } + } + + final TreeElement firstAdded = super.addInternal(first, last, anchor, before); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + + if (first == last && first.getElementType() == TYPE){ + TreeElement element = first; + for(TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == TYPE){ + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for(TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == TYPE){ + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + + if (firstChild.getElementType() != LT){ + TreeElement lt = Factory.createSingleLeafElement(LT, new char[]{'<'}, 0, 1, treeCharTab, getManager()); + super.addInternal(lt, lt, firstChild, Boolean.TRUE); + } + if (lastChild.getElementType() != GT){ + TreeElement gt = Factory.createSingleLeafElement(GT, new char[]{'>'}, 0, 1, treeCharTab, getManager()); + super.addInternal(gt, gt, lastChild, Boolean.FALSE); + } + return firstAdded; + } + + public void deleteChildInternal(TreeElement child) { + if (child.getElementType() == TYPE){ + TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == COMMA){ + deleteChildInternal(next); + } + else{ + TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null && prev.getElementType() == COMMA){ + deleteChildInternal(prev); + } + } + } + + super.deleteChildInternal(child); + + if (getTypeParameterElements().length == 0){ + TreeElement lt = findChildByRole(ChildRole.LT_IN_TYPE_LIST); + if (lt != null){ + deleteChildInternal(lt); + } + + TreeElement gt = findChildByRole(ChildRole.GT_IN_TYPE_LIST); + if (gt != null){ + deleteChildInternal(gt); + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceParameterList(this); + } + + public String toString() { + return "PsiReferenceParameterList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReturnStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReturnStatementImpl.java new file mode 100644 index 00000000000..790162770c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiReturnStatementImpl.java @@ -0,0 +1,64 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiReturnStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiReturnStatementImpl extends CompositePsiElement implements PsiReturnStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReturnStatementImpl"); + + public PsiReturnStatementImpl() { + super(RETURN_STATEMENT); + } + + public PsiExpression getReturnValue() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.RETURN_VALUE); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.RETURN_KEYWORD: + return TreeUtil.findChild(this, RETURN_KEYWORD); + + case ChildRole.RETURN_VALUE: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == RETURN_KEYWORD) { + return ChildRole.RETURN_KEYWORD; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.RETURN_VALUE; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReturnStatement(this); + } + + public String toString() { + return "PsiReturnStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSuperExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSuperExpressionImpl.java new file mode 100644 index 00000000000..730b1940f69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSuperExpressionImpl.java @@ -0,0 +1,129 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.tree.IElementType; + +public class PsiSuperExpressionImpl extends CompositePsiElement implements PsiSuperExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiSuperExpressionImpl"); + + public PsiSuperExpressionImpl() { + super(SUPER_EXPRESSION); + } + + public PsiJavaCodeReferenceElement getQualifier() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiType getType() { + PsiJavaCodeReferenceElement qualifier = getQualifier(); + if (qualifier != null){ + PsiClass aClass = (PsiClass)qualifier.resolve(); + if (aClass == null) return null; + return getSuperType(aClass); + } + for(PsiElement scope = ResolveUtil.getContext(this); scope != null; scope = ResolveUtil.getContext(scope)){ + if (scope instanceof PsiClass){ + PsiClass aClass = (PsiClass)scope; + return getSuperType(aClass); + } + else if (scope instanceof JspFileImpl){ + return getManager().getElementFactory().createType(((JspFileImpl)scope).getBaseClass()); + } + if (scope instanceof PsiExpressionList && scope.getParent() instanceof PsiAnonymousClass){ + scope = scope.getParent(); + } + } + return null; + } + + private PsiType getSuperType(PsiClass aClass) { + if (aClass.isInterface()) { + return getManager().getElementFactory().createType(getManager().findClass("java.lang.Object", getResolveScope())); + } + + if (aClass instanceof PsiAnonymousClass) { + final PsiClassType baseClassType = ((PsiAnonymousClass)aClass).getBaseClassType(); + final PsiClass psiClass = baseClassType.resolve(); + if(psiClass != null && !psiClass.isInterface()){ + return baseClassType; + } + + return PsiType.getJavaLangObject(getManager(), getResolveScope()); + } + + if ("java.lang.Object".equals(aClass.getQualifiedName())) return null; + PsiClassType[] superTypes = aClass.getExtendsListTypes(); + PsiReferenceList[] introducedExtendsList = new PsiReferenceList[1]; + PsiReferenceList[] introducedImplementsList = new PsiReferenceList[1]; + + getManager().getAspectManager().getIntroducedParents(aClass, introducedExtendsList, + introducedImplementsList); + if (introducedExtendsList[0] != null) superTypes = introducedExtendsList[0].getReferencedTypes(); + + if (superTypes.length == 0) { + final PsiClass javaLangObject = getManager().findClass("java.lang.Object", getResolveScope()); + if (javaLangObject != null) { + return getManager().getElementFactory().createType(javaLangObject); + } + else { + return null; + } + } + + return superTypes[0]; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.QUALIFIER: + if (firstChild.getElementType() == JAVA_CODE_REFERENCE){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + + case ChildRole.SUPER_KEYWORD: + return lastChild; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JAVA_CODE_REFERENCE) { + return ChildRole.QUALIFIER; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == SUPER_KEYWORD) { + return ChildRole.SUPER_KEYWORD; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitSuperExpression(this); + } + + public String toString() { + return "PsiSuperExpression:" + getText(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java new file mode 100644 index 00000000000..d5c98642f2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java @@ -0,0 +1,81 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiSwitchLabelStatement; +import com.intellij.psi.PsiSwitchStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.*; + +public class PsiSwitchLabelStatementImpl extends CompositePsiElement implements PsiSwitchLabelStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiSwitchLabelStatementImpl"); + + public PsiSwitchLabelStatementImpl() { + super(SWITCH_LABEL_STATEMENT); + } + + public boolean isDefaultCase() { + return findChildByRoleAsPsiElement(ChildRole.DEFAULT_KEYWORD) != null; + } + + public PsiExpression getCaseValue() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CASE_EXPRESSION); + } + + public PsiSwitchStatement getEnclosingSwitchStatement() { + if (getTreeParent().getTreeParent().getElementType() == SWITCH_STATEMENT) return (PsiSwitchStatement)SourceTreeToPsiMap.treeElementToPsi(getTreeParent().getTreeParent()); + return null; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.CASE_KEYWORD: + return TreeUtil.findChild(this, CASE_KEYWORD); + + case ChildRole.DEFAULT_KEYWORD: + return TreeUtil.findChild(this, DEFAULT_KEYWORD); + + case ChildRole.CASE_EXPRESSION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.COLON: + return TreeUtil.findChild(this, COLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == CASE_KEYWORD) { + return ChildRole.CASE_KEYWORD; + } + else if (i == DEFAULT_KEYWORD) { + return ChildRole.DEFAULT_KEYWORD; + } + else if (i == COLON) { + return ChildRole.COLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.CASE_EXPRESSION; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitSwitchLabelStatement(this); + } + + public String toString() { + return "PsiSwitchLabelStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchStatementImpl.java new file mode 100644 index 00000000000..e83cd3cd168 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSwitchStatementImpl.java @@ -0,0 +1,84 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiSwitchStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +public class PsiSwitchStatementImpl extends CompositePsiElement implements PsiSwitchStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiSwitchStatementImpl"); + + public PsiSwitchStatementImpl() { + super(SWITCH_STATEMENT); + } + + public PsiExpression getExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.SWITCH_EXPRESSION); + } + + public PsiCodeBlock getBody() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.SWITCH_BODY); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.SWITCH_KEYWORD: + return TreeUtil.findChild(this, SWITCH_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.SWITCH_EXPRESSION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.SWITCH_BODY: + return TreeUtil.findChild(this, CODE_BLOCK); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == SWITCH_KEYWORD) { + return ChildRole.SWITCH_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.SWITCH_EXPRESSION; + } + else if (child.getElementType() == CODE_BLOCK) { + return ChildRole.SWITCH_BODY; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitSwitchStatement(this); + } + + public String toString() { + return "PsiSwitchStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSynchronizedStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSynchronizedStatementImpl.java new file mode 100644 index 00000000000..2109c52e418 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiSynchronizedStatementImpl.java @@ -0,0 +1,79 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiSynchronizedStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiSynchronizedStatementImpl extends CompositePsiElement implements PsiSynchronizedStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiSynchronizedStatementImpl"); + + public PsiSynchronizedStatementImpl() { + super(SYNCHRONIZED_STATEMENT); + } + + public PsiExpression getLockExpression() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.LOCK); + } + + public PsiCodeBlock getBody() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.BLOCK); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.SYNCHRONIZED_KEYWORD: + return TreeUtil.findChild(this, SYNCHRONIZED_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.LOCK: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.BLOCK: + return TreeUtil.findChild(this, CODE_BLOCK); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == SYNCHRONIZED_KEYWORD) { + return ChildRole.SYNCHRONIZED_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else if (i == CODE_BLOCK) { + return ChildRole.BLOCK; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.LOCK; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitSynchronizedStatement(this); + } + + public String toString() { + return "PsiSynchronizedStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java new file mode 100644 index 00000000000..f54da913d05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java @@ -0,0 +1,102 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.PsiImmediateClassType; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.jsp.JspFile; + +public class PsiThisExpressionImpl extends CompositePsiElement implements PsiThisExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiThisExpressionImpl"); + + public PsiThisExpressionImpl() { + super(THIS_EXPRESSION); + } + + public PsiJavaCodeReferenceElement getQualifier() { + return (PsiJavaCodeReferenceElement)findChildByRoleAsPsiElement(ChildRole.QUALIFIER); + } + + public PsiType getType() { + PsiJavaCodeReferenceElement qualifier = getQualifier(); + if (qualifier != null){ + PsiClass qualifierResolve = (PsiClass)qualifier.resolve(); + if (qualifierResolve != null) return new PsiImmediateClassType(qualifierResolve, PsiSubstitutor.EMPTY); + + return new PsiClassReferenceType(qualifier); + } + for(PsiElement scope = getContext(); scope != null; scope = scope.getContext()){ + if (scope instanceof PsiClass){ + PsiClass aClass = (PsiClass)scope; + return new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY); + } + else if (scope instanceof JspFileImpl){ + // Not too correct but much better then HttpJspPage :) + PsiClass baseClass = ((JspFileImpl)scope).getBaseClass(); + if(baseClass == null) baseClass = getManager().findClass("javax.servlet.jsp.HttpJspPage", getResolveScope()); + if(baseClass == null) return PsiType.getJavaLangObject(getManager(), getResolveScope()); + final PsiClassType type = getManager().getElementFactory().createType(baseClass); + return type; + } + else if (scope instanceof PsiExpressionList && scope.getParent() instanceof PsiAnonymousClass){ + scope = scope.getParent(); + } + else if (scope instanceof PsiCodeFragment){ + PsiType fragmentThisType = ((PsiCodeFragment)scope).getThisType(); + if (fragmentThisType != null) return fragmentThisType; + } + } + return null; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.QUALIFIER: + if (firstChild.getElementType() == JAVA_CODE_REFERENCE){ + return firstChild; + } + else{ + return null; + } + + case ChildRole.DOT: + return TreeUtil.findChild(this, DOT); + + case ChildRole.THIS_KEYWORD: + return lastChild; + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == JAVA_CODE_REFERENCE) { + return ChildRole.QUALIFIER; + } + else if (i == DOT) { + return ChildRole.DOT; + } + else if (i == THIS_KEYWORD) { + return ChildRole.THIS_KEYWORD; + } + else { + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitThisExpression(this); + } + + public String toString() { + return "PsiThisExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowStatementImpl.java new file mode 100644 index 00000000000..f989f18608d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowStatementImpl.java @@ -0,0 +1,64 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiThrowStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiThrowStatementImpl extends CompositePsiElement implements PsiThrowStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiThrowStatementImpl"); + + public PsiThrowStatementImpl() { + super(THROW_STATEMENT); + } + + public PsiExpression getException() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.EXCEPTION); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.THROW_KEYWORD: + return TreeUtil.findChild(this, THROW_KEYWORD); + + case ChildRole.EXCEPTION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.CLOSING_SEMICOLON: + return TreeUtil.findChildBackward(this, SEMICOLON); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == THROW_KEYWORD) { + return ChildRole.THROW_KEYWORD; + } + else if (i == SEMICOLON) { + return ChildRole.CLOSING_SEMICOLON; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.EXCEPTION; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitThrowStatement(this); + } + + public String toString() { + return "PsiThrowStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowsListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowsListImpl.java new file mode 100644 index 00000000000..8bf68f1fbfe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiThrowsListImpl.java @@ -0,0 +1,55 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; + +/** + * @author dsl + */ +public class PsiThrowsListImpl extends ReferenceListElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiThrowsListImpl"); + + public PsiThrowsListImpl() { + super(THROWS_LIST); + } + + protected String getKeywordText() { + return PsiKeyword.THROWS; + } + + protected IElementType getKeywordType() { + return THROWS_KEYWORD; + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.THROWS_KEYWORD: + return TreeUtil.findChild(this, THROWS_KEYWORD); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == THROWS_KEYWORD) { + return ChildRole.THROWS_KEYWORD; + } + else if (i == COMMA) { + return ChildRole.COMMA; + } + else if (i == JAVA_CODE_REFERENCE) { + return ChildRole.REFERENCE_IN_LIST; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTryStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTryStatementImpl.java new file mode 100644 index 00000000000..dcb16aed0e0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTryStatementImpl.java @@ -0,0 +1,154 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.tree.IElementType; + +import java.util.ArrayList; + +public class PsiTryStatementImpl extends CompositePsiElement implements PsiTryStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiTryStatementImpl"); + private PsiParameter[] myCachedCatchParameters = null; + + public void clearCaches() { + super.clearCaches(); + myCachedCatchParameters = null; + } + + public PsiTryStatementImpl() { + super(TRY_STATEMENT); + } + + public PsiCodeBlock getTryBlock() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.TRY_BLOCK); + } + + public PsiCodeBlock[] getCatchBlocks() { + TreeElement tryBlock = SourceTreeToPsiMap.psiElementToTree(getTryBlock()); + if (tryBlock != null) { + PsiCatchSection[] catchSections = getCatchSections(); + if (catchSections.length == 0) return PsiCodeBlock.EMPTY_ARRAY; + boolean lastIncomplete = catchSections[catchSections.length - 1].getCatchBlock() == null; + PsiCodeBlock[] blocks = new PsiCodeBlock[lastIncomplete ? catchSections.length - 1 : catchSections.length]; + for (int i = 0; i < blocks.length; i++) { + blocks[i] = catchSections[i].getCatchBlock(); + } + return blocks; + } + return PsiCodeBlock.EMPTY_ARRAY; + } + + public PsiParameter[] getCatchBlockParameters() { + if (myCachedCatchParameters == null) { + PsiCatchSection[] catchSections = getCatchSections(); + if (catchSections.length == 0) return PsiParameter.EMPTY_ARRAY; + boolean lastIncomplete = catchSections[catchSections.length - 1].getCatchBlock() == null; + int limit = lastIncomplete ? catchSections.length - 1 : catchSections.length; + ArrayList parameters = new ArrayList(); + for (int i = 0; i < limit; i++) { + PsiParameter parameter = catchSections[i].getParameter(); + if (parameter != null) parameters.add(parameter); + } + myCachedCatchParameters = parameters.toArray(new PsiParameter[parameters.size()]); + } + return myCachedCatchParameters; + } + + public PsiCatchSection[] getCatchSections() { + return (PsiCatchSection[])getChildrenAsPsiElements(CATCH_SECTION_BIT_SET, PSI_CATCH_SECTION_ARRAYS_CONSTRUCTOR); + } + + public PsiCodeBlock getFinallyBlock() { + return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.FINALLY_BLOCK); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.TRY_KEYWORD: + return TreeUtil.findChild(this, TRY_KEYWORD); + + case ChildRole.TRY_BLOCK: + return TreeUtil.findChild(this, CODE_BLOCK); + + case ChildRole.FINALLY_KEYWORD: + return TreeUtil.findChild(this, FINALLY_KEYWORD); + + case ChildRole.FINALLY_BLOCK: + { + TreeElement finallyKeyword = findChildByRole(ChildRole.FINALLY_KEYWORD); + if (finallyKeyword == null) return null; + for(TreeElement child = finallyKeyword.getTreeNext(); child != null; child = child.getTreeNext()){ + if (child.getElementType() == CODE_BLOCK){ + return child; + } + } + return null; + } + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == TRY_KEYWORD) { + return ChildRole.TRY_KEYWORD; + } + else if (i == FINALLY_KEYWORD) { + return ChildRole.FINALLY_KEYWORD; + } + else if (i == CATCH_SECTION) { + return ChildRole.CATCH_SECTION; + } + else { + if (child.getElementType() == CODE_BLOCK) { + int role = getChildRole(child, ChildRole.TRY_BLOCK); + if (role != ChildRole.NONE) return role; + return getChildRole(child, ChildRole.FINALLY_BLOCK); + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTryStatement(this); + } + + public String toString() { + return "PsiTryStatement"; + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + if (lastParent == null){ + // Outside members should not know about inner elements + return true; + } + + if (!PsiScopesUtil.walkChildrenScopes(this, processor, substitutor, lastParent, place)) return false; + + PsiCatchSection[] sections = getCatchSections(); + for(int i = 0; i < sections.length; i++){ + if (lastParent.equals(sections[i])){ + PsiParameter parameter = sections[i].getParameter(); + if (parameter != null && !processor.execute(parameter, substitutor)){ + return false; + } + } + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java new file mode 100644 index 00000000000..12f8221cb50 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java @@ -0,0 +1,75 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiTypeCastExpressionImpl extends CompositePsiElement implements PsiTypeCastExpression { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiTypeCastExpressionImpl"); + + public PsiTypeCastExpressionImpl() { + super(TYPE_CAST_EXPRESSION); + } + + public PsiTypeElement getCastType() { + return (PsiTypeElement)findChildByRoleAsPsiElement(ChildRole.TYPE); + } + + public PsiExpression getOperand() { + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.OPERAND); + } + + public PsiType getType() { + return getCastType().getType(); + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.TYPE: + return TreeUtil.findChild(this, TYPE); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.OPERAND: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else if (i == TYPE) { + return ChildRole.TYPE; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.OPERAND; + } + return ChildRole.NONE; + } + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeCastExpression(this); + } + + public String toString() { + return "PsiTypeCastExpression:" + getText(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java new file mode 100644 index 00000000000..799b5349924 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java @@ -0,0 +1,90 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.SlaveRepositoryPsiElement; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.SrcRepositoryPsiElement; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; + +/** + * @author max + */ +public class PsiTypeParameterExtendsBoundsListImpl extends SlaveRepositoryPsiElement implements PsiReferenceList { + private PsiClassType[] myCachedTypes; + + public PsiTypeParameterExtendsBoundsListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiTypeParameterExtendsBoundsListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + protected Object clone() { + PsiTypeParameterExtendsBoundsListImpl clone = (PsiTypeParameterExtendsBoundsListImpl) super.clone(); + clone.myCachedTypes = null; + return clone; + } + + public void setOwner(SrcRepositoryPsiElement owner) { + super.setOwner(owner); + myCachedTypes = null; + } + + public PsiJavaCodeReferenceElement[] getReferenceElements() { + return (PsiJavaCodeReferenceElement[]) calcTreeElement().getChildrenAsPsiElements(Constants.JAVA_CODE_REFERENCE_BIT_SET, + PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR); + } + + public PsiClassType[] getReferencedTypes() { + synchronized (PsiLock.LOCK) { + if (myCachedTypes == null) { + long repositoryId = getRepositoryId(); + if (getTreeElement() == null && repositoryId >= 0) { + myCachedTypes = createTypes(getMirrorElement().getReferenceElements()); + } + else { + return createTypes(getReferenceElements()); + } + } + return myCachedTypes; + } + } + + private PsiClassType[] createTypes(final PsiJavaCodeReferenceElement[] refs) { + final PsiElementFactory factory = getManager().getElementFactory(); + PsiClassType[] types = new PsiClassType[refs.length]; + for (int i = 0; i < refs.length; i++) { + types[i] = factory.createType(refs[i]); + } + return types; + } + + private CompositeElement getMirrorTreeElement() { + CompositeElement mirror = ((PsiTypeParameterImpl) getParent()).getMirrorTreeElement(); + CompositeElement myselfTree = (CompositeElement) mirror.findChildByRole(ChildRole.EXTENDS_LIST); + return myselfTree; + } + + private PsiTypeParameterExtendsBoundsListImpl getMirrorElement() { + final CompositeElement treeElement = getMirrorTreeElement(); + return (PsiTypeParameterExtendsBoundsListImpl)SourceTreeToPsiMap.treeElementToPsi(treeElement); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitReferenceList(this); + } + + public String toString() { + return "PsiElement(EXTENDS_BOUND_LIST)"; + } + + public void treeElementSubTreeChanged() { + super.treeElementSubTreeChanged(); + myCachedTypes = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java new file mode 100644 index 00000000000..ea8037312ef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java @@ -0,0 +1,343 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.pom.java.PomMemberOwner; +import com.intellij.psi.*; +import com.intellij.psi.impl.InheritanceImplUtil; +import com.intellij.psi.impl.PsiClassImplUtil; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.SharedPsiElementImplUtil; +import com.intellij.psi.impl.light.LightEmptyImplementsList; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.IndexedRepositoryPsiElement; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.SrcRepositoryPsiElement; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; + +import java.util.HashSet; +import java.util.List; + +/** + * @author dsl + */ +public class PsiTypeParameterImpl extends IndexedRepositoryPsiElement implements PsiTypeParameter { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiTypeParameterImpl"); + + private CompositeElement myParsedFromRepository; + private PsiTypeParameterExtendsBoundsListImpl myExtendsBoundsList; + private LightEmptyImplementsList myLightEmptyImplementsList; + + public PsiTypeParameterImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiTypeParameterImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner, int index) { + super(manager, owner, index); + } + + public PsiTypeParameterImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + public String getQualifiedName() { + return null; + } + + public boolean isInterface() { + return false; + } + + public boolean isAnnotationType() { + return false; + } + + public boolean isEnum() { + return false; + } + + public PsiField[] getFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + public PsiField findFieldByName(String name, boolean checkBases) { + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + public PsiMethod[] findMethodsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + public List> findMethodsAndTheirSubstitutorsByName(String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + public PsiClass findInnerClassByName(String name, boolean checkBases) { + return PsiClassImplUtil.findInnerByName(this, name, checkBases); + } + + public PsiTypeParameterList getTypeParameterList() { + return null; + } + + public boolean hasTypeParameters() { + return false; + } + + // very special method! + public PsiElement getScope() { + return getParent().getParent(); + } + + public boolean isInheritor(PsiClass baseClass, boolean checkDeep) { + return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep); + } + + public PomMemberOwner getPom() { + //TODO: + return null; + } + + CompositeElement getMirrorTreeElement() { + CompositeElement actualTree = getTreeElement(); + if (actualTree != null) { + myParsedFromRepository = null; + return actualTree; + } + + if (myParsedFromRepository != null) return myParsedFromRepository; + long repositoryId = getRepositoryId(); + if (repositoryId >= 0) { + String text; + PsiElement owner = myOwner.getParent(); + if (owner instanceof PsiClass) { + text = getRepositoryManager().getClassView().getParameterText(repositoryId, getIndex()); + } + else if (owner instanceof PsiMethod) { + text = getRepositoryManager().getMethodView().getTypeParameterText(repositoryId, getIndex()); + } + else { + LOG.error("Wrong owner"); + text = ""; + } + try{ + PsiTypeParameter typeParameter = myManager.getElementFactory().createTypeParameterFromText(text, this); + myParsedFromRepository = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(typeParameter); + new DummyHolder(myManager, myParsedFromRepository, this); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + return myParsedFromRepository; + } + + return calcTreeElement(); + } + + public PsiTypeParameterListOwner getOwner() { + final PsiElement parent = getParent(); + if (parent == null) return null; + final PsiElement parentParent = parent.getParent(); + if (parentParent instanceof PsiTypeParameterListOwner) return (PsiTypeParameterListOwner) parentParent; + return null; + } + + + public int getIndex() { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0) { + return super.getIndex(); + } + else { + int ret = 0; + PsiElement element = getPrevSibling(); + while(element != null){ + if(element instanceof PsiTypeParameter) + ret++; + element = element.getPrevSibling(); + } + return ret; + } + } + + public PsiIdentifier getNameIdentifier() { + return (PsiIdentifier) getMirrorTreeElement().findChildByRole(ChildRole.NAME); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + return PsiClassImplUtil.processDeclarationsInClass(this, processor, substitutor, new HashSet(), lastParent, place); + } + + public String getName() { + return getNameIdentifier().getText(); + } + + public PsiElement setName(String name) throws IncorrectOperationException { + SharedPsiElementImplUtil.setName(getNameIdentifier(), name); + return this; + } + + public PsiMethod[] getConstructors() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiDocComment getDocComment() { + return null; + } + + public boolean isDeprecated() { + return false; + } + + public void subtreeChanged() { + super.subtreeChanged(); + myExtendsBoundsList = null; + myParsedFromRepository = null; + } + + public PsiReferenceList getExtendsList() { + if (myOwner != null) { + if (myExtendsBoundsList == null) { + myExtendsBoundsList = new PsiTypeParameterExtendsBoundsListImpl(myManager, this); + } + return myExtendsBoundsList; + } + else { + return (PsiReferenceList) calcTreeElement().findChildByRoleAsPsiElement(ChildRole.EXTENDS_LIST); + } + } + + protected Object clone() { + PsiTypeParameterImpl clone = (PsiTypeParameterImpl)super.clone(); + clone.myExtendsBoundsList = null; + clone.myLightEmptyImplementsList = null; + clone.myParsedFromRepository = null; + return super.clone(); + } + + public PsiReferenceList getImplementsList() { + if (myLightEmptyImplementsList == null) { + myLightEmptyImplementsList = new LightEmptyImplementsList(myManager); + } + return myLightEmptyImplementsList; + } + + public PsiClassType[] getExtendsListTypes() { + return PsiClassImplUtil.getExtendsListTypes(this); + } + + public PsiClassType[] getImplementsListTypes() { + return PsiClassType.EMPTY_ARRAY; + } + + public PsiClass[] getInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public PsiField[] getAllFields() { + return PsiField.EMPTY_ARRAY; + } + + public PsiMethod[] getAllMethods() { + return PsiMethod.EMPTY_ARRAY; + } + + public PsiClass[] getAllInnerClasses() { + return PsiClass.EMPTY_ARRAY; + } + + public void setOwnerAndIndex(SrcRepositoryPsiElement owner, int index) { + super.setOwnerAndIndex(owner, index); + if (myOwner == null) { + if (myExtendsBoundsList != null) { + myExtendsBoundsList.setOwner(this); + } + } + else { + myExtendsBoundsList = (PsiTypeParameterExtendsBoundsListImpl)bindSlave(ChildRole.EXTENDS_LIST); + } + } + + public PsiClassInitializer[] getInitializers() { + return PsiClassInitializer.EMPTY_ARRAY; + } + + public PsiTypeParameter[] getTypeParameters() { + return PsiTypeParameter.EMPTY_ARRAY; + } + + public PsiClass getSuperClass() { + return PsiClassImplUtil.getSuperClass(this); + } + + public PsiClass[] getInterfaces() { + return PsiClassImplUtil.getInterfaces(this); + } + + public PsiClass[] getSupers() { + return PsiClassImplUtil.getSupers(this); + } + + public PsiClassType[] getSuperTypes() { + return PsiClassImplUtil.getSuperTypes(this); + } + + public PsiClass getContainingClass() { + return null; + } + + public PsiModifierList getModifierList() { + return null; + } + + public boolean hasModifierProperty(String name) { + return false; + } + + public PsiJavaToken getLBrace() { + return null; + } + + public PsiJavaToken getRBrace() { + return null; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeParameter(this); + } + + public String toString() { + return "PsiTypeParameter"; + } + + public PsiMetaData getMetaData(){ + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough(){ + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterListImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterListImpl.java new file mode 100644 index 00000000000..77c91478793 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiTypeParameterListImpl.java @@ -0,0 +1,122 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.cache.RepositoryManager; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.SlaveRepositoryPsiElement; +import com.intellij.psi.impl.source.SrcRepositoryPsiElement; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.RepositoryTreeElement; +import com.intellij.psi.scope.PsiScopeProcessor; + +/** + * @author dsl + */ +public class PsiTypeParameterListImpl extends SlaveRepositoryPsiElement implements PsiTypeParameterList { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiTypeParameterListImpl"); + + private static final TokenSet CLASS_PARAMETER_BIT_SET = TokenSet.create(new IElementType[]{TYPE_PARAMETER}); + private static final PsiElementArrayConstructor CLASS_PARAMETER_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor() { + public PsiElement[] newPsiElementArray(int length) { + return length > 0 ? new PsiTypeParameter[length] : PsiTypeParameter.EMPTY_ARRAY; + } + }; + + private PsiTypeParameter[] myRepositoryClassParameters; + private static final TokenSet TYPE_PARAMETER_BIT_SET = TokenSet.create(new IElementType[]{ElementType.TYPE_PARAMETER}); + + public PsiTypeParameterListImpl(PsiManagerImpl manager, RepositoryTreeElement treeElement) { + super(manager, treeElement); + } + + public PsiTypeParameterListImpl(PsiManagerImpl manager, SrcRepositoryPsiElement owner) { + super(manager, owner); + } + + protected Object clone() { + PsiTypeParameterListImpl clone = (PsiTypeParameterListImpl)super.clone(); + clone.myRepositoryClassParameters = null; + return clone; + } + + public void setOwner(SrcRepositoryPsiElement owner) { + super.setOwner(owner); + + if (myOwner == null) { + if (myRepositoryClassParameters != null) { + for (int i = 0; i < myRepositoryClassParameters.length; i++) { + PsiTypeParameterImpl ref = (PsiTypeParameterImpl)myRepositoryClassParameters[i]; + ref.setOwnerAndIndex(this, i); + } + } + myRepositoryClassParameters = null; + } + else { + myRepositoryClassParameters = (PsiTypeParameter[])bindIndexedSlaves(TYPE_PARAMETER_BIT_SET, CLASS_PARAMETER_ARRAY_CONSTRUCTOR); + } + } + + public PsiTypeParameter[] getTypeParameters() { + long repositoryId = getRepositoryId(); + if (repositoryId >= 0) { + if (myRepositoryClassParameters == null) { + RepositoryManager repositoryManager = getRepositoryManager(); + CompositeElement treeElement = getTreeElement(); + int count; + if (treeElement == null) { + if (myOwner instanceof PsiClass) { + count = repositoryManager.getClassView().getParametersListSize(repositoryId); + } + else if (myOwner instanceof PsiMethod) { + count = repositoryManager.getMethodView().getTypeParametersCount(repositoryId); + } + else { + count = 0; + LOG.error("Wrong owner"); + } + } + else { + count = treeElement.countChildren(CLASS_PARAMETER_BIT_SET); + } + + myRepositoryClassParameters = new PsiTypeParameter[count]; + for (int i = 0; i < myRepositoryClassParameters.length; i++) { + myRepositoryClassParameters[i] = new PsiTypeParameterImpl(myManager, this, i); + } + } + + return myRepositoryClassParameters; + } + else { + return (PsiTypeParameter[])calcTreeElement().getChildrenAsPsiElements(CLASS_PARAMETER_BIT_SET, CLASS_PARAMETER_ARRAY_CONSTRUCTOR); + } + } + + public int getTypeParameterIndex(PsiTypeParameter typeParameter) { + LOG.assertTrue(typeParameter.getParent() == this); + return PsiImplUtil.getTypeParameterIndex(typeParameter, this); + } + + public boolean processDeclarations(PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + final PsiTypeParameter[] parameters = getTypeParameters(); + for (int i = 0; i < parameters.length; i++) { + final PsiTypeParameter parameter = parameters[i]; + if (!processor.execute(parameter, substitutor)) return false; + } + return true; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitTypeParameterList(this); + } + + public String toString() { + return "PsiTypeParameterList"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiWhileStatementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiWhileStatementImpl.java new file mode 100644 index 00000000000..5fe27af8fba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/PsiWhileStatementImpl.java @@ -0,0 +1,86 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +public class PsiWhileStatementImpl extends CompositePsiElement implements PsiWhileStatement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiWhileStatementImpl"); + + public PsiWhileStatementImpl() { + super(WHILE_STATEMENT); + } + + public PsiExpression getCondition(){ + return (PsiExpression)findChildByRoleAsPsiElement(ChildRole.CONDITION); + } + + public PsiStatement getBody(){ + return (PsiStatement)findChildByRoleAsPsiElement(ChildRole.LOOP_BODY); + } + + public PsiJavaToken getLParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.LPARENTH); + } + + public PsiJavaToken getRParenth() { + return (PsiJavaToken) findChildByRoleAsPsiElement(ChildRole.RPARENTH); + } + + public TreeElement findChildByRole(int role){ + LOG.assertTrue(ChildRole.isUnique(role)); + switch(role){ + default: + return null; + + case ChildRole.WHILE_KEYWORD: + return TreeUtil.findChild(this, WHILE_KEYWORD); + + case ChildRole.LPARENTH: + return TreeUtil.findChild(this, LPARENTH); + + case ChildRole.CONDITION: + return TreeUtil.findChild(this, EXPRESSION_BIT_SET); + + case ChildRole.RPARENTH: + return TreeUtil.findChild(this, RPARENTH); + + case ChildRole.LOOP_BODY: + return TreeUtil.findChild(this, STATEMENT_BIT_SET); + } + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == WHILE_KEYWORD) { + return ChildRole.WHILE_KEYWORD; + } + else if (i == LPARENTH) { + return ChildRole.LPARENTH; + } + else if (i == RPARENTH) { + return ChildRole.RPARENTH; + } + else { + if (EXPRESSION_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.CONDITION; + } + else if (STATEMENT_BIT_SET.isInSet(child.getElementType())) { + return ChildRole.LOOP_BODY; + } + else { + return ChildRole.NONE; + } + } + } + + public void accept(PsiElementVisitor visitor){ + visitor.visitWhileStatement(this); + } + + public String toString(){ + return "PsiWhileStatement"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReferenceListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReferenceListElement.java new file mode 100644 index 00000000000..811b0aa27a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReferenceListElement.java @@ -0,0 +1,76 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +public abstract class ReferenceListElement extends RepositoryTreeElement{ + public ReferenceListElement(IElementType type) { + super(type); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before){ + if (first == last && first.getElementType() == JAVA_CODE_REFERENCE){ + if (lastChild != null && lastChild.getElementType() == ERROR_ELEMENT){ + super.deleteChildInternal(lastChild); + } + } + + final TreeElement firstAdded = super.addInternal(first, last, anchor, before); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + if (first == last && first.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement element = first; + for(TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for(TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + + IElementType keywordType; + String keywordText; + keywordType = getKeywordType(); + keywordText = getKeywordText(); + if (TreeUtil.findChild(this, keywordType) == null && TreeUtil.findChild(this, JAVA_CODE_REFERENCE) != null){ + LeafElement keyword = Factory.createSingleLeafElement(keywordType, keywordText.toCharArray(), 0, keywordText.length(), SharedImplUtil.findCharTableByTree(this), getManager()); + super.addInternal(keyword, keyword, firstChild, Boolean.TRUE); + } + return firstAdded; + } + + public void deleteChildInternal(TreeElement child) { + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == COMMA){ + deleteChildInternal(next); + } + else{ + TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null){ + if (prev.getElementType() == COMMA + || prev.getElementType() == getKeywordType() + ){ + deleteChildInternal(prev); + } + } + } + } + super.deleteChildInternal(child); + } + + protected abstract String getKeywordText(); + + protected abstract IElementType getKeywordType(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReplaceExpressionUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReplaceExpressionUtil.java new file mode 100644 index 00000000000..ba1b6d4ed8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/ReplaceExpressionUtil.java @@ -0,0 +1,143 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiBinaryExpression; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.Constants; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeElement; + +public class ReplaceExpressionUtil implements Constants { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil"); + + public static boolean isNeedParenthesis(TreeElement oldExpr, TreeElement newExpr) { + if (!ElementType.EXPRESSION_BIT_SET.isInSet(oldExpr.getTreeParent().getElementType())) return false; + int priority = getExpressionPriority(newExpr); + int parentPriority = getExpressionPriority(oldExpr.getTreeParent()); + if (priority > parentPriority) return false; + IElementType i = oldExpr.getTreeParent().getElementType(); + if (i == ASSIGNMENT_EXPRESSION) { + if (priority < parentPriority) return true; + return oldExpr.getTreeParent().getChildRole(oldExpr) == ChildRole.LOPERAND ? true : false; + } + else if (i == CONDITIONAL_EXPRESSION) { + int role = oldExpr.getTreeParent().getChildRole(oldExpr); + if (role == ChildRole.THEN_EXPRESSION) return false; + if (priority < parentPriority) return true; + return role == ChildRole.ELSE_EXPRESSION ? false : true; + } + else if (i == BINARY_EXPRESSION) { + if (priority < parentPriority) return true; + return oldExpr.getTreeParent().getChildRole(oldExpr) == ChildRole.LOPERAND ? false : true; + } + else if (i == INSTANCE_OF_EXPRESSION) { + return priority < parentPriority; + } + else if (i == PREFIX_EXPRESSION || i == TYPE_CAST_EXPRESSION) { + return priority < parentPriority; + } + else if (i == POSTFIX_EXPRESSION) { + return priority <= parentPriority; + } + else if (i == REFERENCE_EXPRESSION) { + return priority < parentPriority; + } + else if (i == METHOD_CALL_EXPRESSION) { + return false; + } + else if (i == NEW_EXPRESSION) { + return false; + } + else if (i == ARRAY_ACCESS_EXPRESSION) { + int role = oldExpr.getTreeParent().getChildRole(oldExpr); + if (role == ChildRole.ARRAY_DIMENSION) return false; + return priority < parentPriority; + } + else if (i == ARRAY_INITIALIZER_EXPRESSION) { + return false; + } + else if (i == PARENTH_EXPRESSION) { + return false; + } + else if (i == LITERAL_EXPRESSION || i == THIS_EXPRESSION || i == SUPER_EXPRESSION || i == CLASS_OBJECT_ACCESS_EXPRESSION) { + return false; + } + + LOG.assertTrue(false); + return false; + } + + private static int getExpressionPriority(TreeElement expr) { + IElementType i = expr.getElementType(); + if (i == ASSIGNMENT_EXPRESSION) { + return 0; + } + else if (i == CONDITIONAL_EXPRESSION) { + return 1; + } + else if (i == BINARY_EXPRESSION) { + { + IElementType opType = ((PsiBinaryExpression)SourceTreeToPsiMap.treeElementToPsi(expr)).getOperationSign().getTokenType(); + if (opType == OROR) { + return 2; + } + else if (opType == ANDAND) { + return 3; + } + else if (opType == OR) { + return 4; + } + else if (opType == XOR) { + return 5; + } + else if (opType == AND) { + return 6; + } + else if (opType == EQEQ || opType == NE) { + return 7; + } + else if (opType == LT || opType == GT || opType == LE || opType == GE) { + return 8; + } + else if (opType == LTLT || opType == GTGT || opType == GTGTGT) { + return 9; + } + else if (opType == PLUS || opType == MINUS) { + return 10; + } + else if (opType == ASTERISK || opType == DIV || opType == PERC) { + return 11; + } + } + + + return 8; + } + else if (i == INSTANCE_OF_EXPRESSION) { + return 8; + } + else if (i == PREFIX_EXPRESSION || i == TYPE_CAST_EXPRESSION) { + return 12; + } + else if (i == POSTFIX_EXPRESSION) { + return 13; + } + else if (i == LITERAL_EXPRESSION || i == REFERENCE_EXPRESSION || i == THIS_EXPRESSION || i == SUPER_EXPRESSION || i == + PARENTH_EXPRESSION || + i == METHOD_CALL_EXPRESSION || + i == CLASS_OBJECT_ACCESS_EXPRESSION || + i == NEW_EXPRESSION || + i == ARRAY_ACCESS_EXPRESSION || + i == ARRAY_INITIALIZER_EXPRESSION || + i == JAVA_CODE_REFERENCE || + i == EMPTY_EXPRESSION) { + return 14; + } + else { + LOG.assertTrue(false, "Unknown element type:"+i); + return -1; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterElement.java new file mode 100644 index 00000000000..648e9bac04d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterElement.java @@ -0,0 +1,46 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.*; + +/** + * @author max + */ +public class TypeParameterElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.TypeParameterElement"); + + public TypeParameterElement() { + super(ElementType.TYPE_PARAMETER); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + final IElementType i = child.getElementType(); + if (i == JavaTokenType.IDENTIFIER) { + return getChildRole(child, ChildRole.NAME); + } + else if (i == JavaElementType.EXTENDS_BOUND_LIST) { + return getChildRole(child, ChildRole.EXTENDS_LIST); + } + else { + return ChildRole.NONE; + } + } + + public TreeElement findChildByRole(int role) { + LOG.assertTrue(ChildRole.isUnique(role)); + + switch (role) { + default: + return null; + + case ChildRole.NAME: + return TreeUtil.findChild(this, JavaTokenType.IDENTIFIER); + + case ChildRole.EXTENDS_LIST: + return TreeUtil.findChild(this, JavaElementType.EXTENDS_BOUND_LIST); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterExtendsBoundsListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterExtendsBoundsListElement.java new file mode 100644 index 00000000000..2cdb097dda8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterExtendsBoundsListElement.java @@ -0,0 +1,102 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.SrcRepositoryPsiElement; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.util.CharTable; + +/** + * @author dsl + */ +public class TypeParameterExtendsBoundsListElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.TypeParameterExtendsBoundsListElement"); + + public TypeParameterExtendsBoundsListElement() { + super(JavaElementType.EXTENDS_BOUND_LIST); + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean before) { + if (first == last && first.getElementType() == JAVA_CODE_REFERENCE){ + if (lastChild != null && lastChild.getElementType() == ERROR_ELEMENT){ + super.deleteChildInternal(lastChild); + } + } + + final TreeElement firstAdded = super.addInternal(first, last, anchor, before); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + if (first == last && first.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement element = first; + for(TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()){ + if (child.getElementType() == AND) break; + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement comma = Factory.createSingleLeafElement(AND, new char[]{'&'}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for(TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()){ + if (child.getElementType() == AND) break; + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement comma = Factory.createSingleLeafElement(AND, new char[]{'&'}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + + final IElementType keywordType = JavaTokenType.EXTENDS_KEYWORD; + final String keywordText = "extends"; + if (TreeUtil.findChild(this, keywordType) == null && TreeUtil.findChild(this, JAVA_CODE_REFERENCE) != null){ + LeafElement keyword = Factory.createSingleLeafElement(keywordType, keywordText.toCharArray(), 0, keywordText.length(), treeCharTab, getManager()); + super.addInternal(keyword, keyword, firstChild, Boolean.TRUE); + } + return firstAdded; + } + + public void deleteChildInternal(TreeElement child) { + if (child.getElementType() == JAVA_CODE_REFERENCE){ + TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == AND){ + deleteChildInternal(next); + } + else{ + TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null){ + if (prev.getElementType() == AND || prev.getElementType() == EXTENDS_KEYWORD){ + deleteChildInternal(prev); + } + } + } + } + super.deleteChildInternal(child); + } + + public void subtreeChanged() { + super.subtreeChanged(); + final SrcRepositoryPsiElement psiElement = getPsiElement(); + if (psiElement != null){ + psiElement.treeElementSubTreeChanged(); + } + } + + public int getChildRole(final TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + + final IElementType elType = child.getElementType(); + if (elType == AND) { + return ChildRole.AMPERSAND_IN_BOUNDS_LIST; + } + else if (elType == ElementType.JAVA_CODE_REFERENCE) { + return ChildRole.BASE_CLASS_REFERENCE; + } + else if (elType == JavaTokenType.EXTENDS_KEYWORD) { + return ChildRole.EXTENDS_KEYWORD; + } + else { + return ChildRole.NONE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java new file mode 100644 index 00000000000..e87a8426c2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java @@ -0,0 +1,113 @@ +package com.intellij.psi.impl.source.tree.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.CharTable; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.CharTable; + +/** + * @author max + */ +public class TypeParameterListElement extends RepositoryTreeElement { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.TypeParameterListElement"); + + public TypeParameterListElement() { + super(ElementType.TYPE_PARAMETER_LIST); + } + + public int getChildRole(final TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + final IElementType elType = child.getElementType(); + if (elType == TYPE_PARAMETER) { + return ChildRole.TYPE_PARAMETER_IN_LIST; + } + else if (elType == COMMA) { + return ChildRole.COMMA; + } + else if (elType == LT) { + return ChildRole.LT_IN_TYPE_LIST; + } + else if (elType == GT) { + return ChildRole.GT_IN_TYPE_LIST; + } + else { + return ChildRole.NONE; + } + } + + public TreeElement addInternal(final TreeElement first, final TreeElement last, TreeElement anchor, Boolean before) { + ChameleonTransforming.transformChildren(this); + TreeElement lt = findChildByRole(ChildRole.LT_IN_TYPE_LIST); + final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + if (lt == null) { + lt = Factory.createSingleLeafElement(LT, new char[]{'<'}, 0, 1, treeCharTab, getManager()); + super.addInternal(lt, lt, firstChild, Boolean.TRUE); + } + + TreeElement gt = findChildByRole(ChildRole.GT_IN_TYPE_LIST); + if (gt == null) { + gt = Factory.createSingleLeafElement(GT, new char[]{'>'}, 0, 1, treeCharTab, getManager()); + super.addInternal(gt, gt, lastChild, Boolean.FALSE); + } + + if (anchor == null) { + if (before == null || before.booleanValue()){ + anchor = gt; + before = Boolean.TRUE; + } + else{ + anchor = lt; + before = Boolean.FALSE; + } + } + + final TreeElement firstAdded = super.addInternal(first, last, anchor, before); + + if (first == last && first.getElementType() == TYPE_PARAMETER) { + final TreeElement element = first; + for(TreeElement child = element.getTreeNext(); child != null; child = child.getTreeNext()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == TYPE_PARAMETER){ + final TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, element, Boolean.FALSE); + break; + } + } + for(TreeElement child = element.getTreePrev(); child != null; child = child.getTreePrev()){ + if (child.getElementType() == COMMA) break; + if (child.getElementType() == TYPE_PARAMETER){ + final TreeElement comma = Factory.createSingleLeafElement(COMMA, new char[]{','}, 0, 1, treeCharTab, getManager()); + super.addInternal(comma, comma, child, Boolean.FALSE); + break; + } + } + } + return firstAdded; + } + + public void deleteChildInternal(final TreeElement child) { + if (child.getElementType() == TYPE_PARAMETER){ + final TreeElement next = TreeUtil.skipElements(child.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == COMMA){ + deleteChildInternal(next); + } + else{ + final TreeElement prev = TreeUtil.skipElementsBack(child.getTreePrev(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (prev != null && prev.getElementType() == COMMA){ + deleteChildInternal(prev); + } + } + } + super.deleteChildInternal(child); + if (child.getElementType() == TYPE_PARAMETER) { + final TreeElement lt = findChildByRole(ChildRole.LT_IN_TYPE_LIST); + final TreeElement next = TreeUtil.skipElements(lt.getTreeNext(), WHITE_SPACE_OR_COMMENT_BIT_SET); + if (next != null && next.getElementType() == GT) { + deleteChildInternal(lt); + deleteChildInternal(next); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/TagNameReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/TagNameReference.java new file mode 100644 index 00000000000..6af5c3e8853 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/TagNameReference.java @@ -0,0 +1,140 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiElement; +import com.intellij.psi.html.HtmlTag; +import com.intellij.psi.meta.PsiMetaOwner; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.openapi.util.TextRange; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.util.XmlUtil; +import com.intellij.xml.util.HtmlUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +class TagNameReference implements PsiReference { + private final boolean myStartTagFlag; + private final TreeElement myNameElement; + + public TagNameReference(TreeElement nameElement, boolean startTagFlag) { + myStartTagFlag = startTagFlag; + myNameElement = nameElement; + } + + public XmlTag getElement() { + TreeElement parent = TreeUtil.findParent(myNameElement, XmlElementType.XML_TAG); + if(parent == null) parent = TreeUtil.findParent(myNameElement, XmlElementType.HTML_TAG); + return (XmlTag)SourceTreeToPsiMap.treeElementToPsi(parent); + } + + public TextRange getRangeInElement() { + if (getNameElement() == null){ + return new TextRange(0, 0); + } + final int parentOffset = getNameElement().getStartOffsetInParent(); + return new TextRange(parentOffset, parentOffset + getNameElement().getTextLength()); + } + + private TreeElement getNameElement() { + return myNameElement; + } + + public PsiElement resolve() { + final XmlElementDescriptor descriptor = getElement().getDescriptor(); + if (descriptor != null){ + return descriptor.getDeclaration(); + } + return null; + } + + public String getCanonicalText() { + return getNameElement().getText(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return getElement().setName(newElementName); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiMetaOwner){ + final PsiMetaOwner owner = (PsiMetaOwner)element; + if (owner.getMetaData() instanceof XmlElementDescriptor){ + getElement().setName(owner.getMetaData().getName(getElement())); + } + } + throw new IncorrectOperationException("Cant bind to not a xml element definition!"); + } + + public boolean isReferenceTo(PsiElement element) { + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants(){ + final List variants = new ArrayList(); + final XmlTag element = getElement(); + if(!myStartTagFlag) return new Object[]{element.getName()}; + final Map descriptorsMap = new HashMap(); + + { + PsiElement curElement = element.getParent(); + while(curElement instanceof XmlTag){ + final XmlTag declarationTag = (XmlTag)curElement; + final String namespace = declarationTag.getNamespace(); + if(!descriptorsMap.containsKey(namespace)) { + final XmlElementDescriptor descriptor = declarationTag.getDescriptor(); + if(descriptor != null) + descriptorsMap.put(namespace, descriptor); + } + curElement = curElement.getContext(); + } + } + final List namespaces = new ArrayList(Arrays.asList(element.knownNamespaces())); + namespaces.add(XmlUtil.EMPTY_NAMESPACE); // empty namespace + final Iterator nsIterator = namespaces.iterator(); + + final Set visited = new HashSet(); + while (nsIterator.hasNext()) { + final String namespace = nsIterator.next(); + + if(descriptorsMap.containsKey(namespace)){ + final XmlElementDescriptor descriptor = descriptorsMap.get(namespace); + variants.addAll(Arrays.asList(descriptor.getElementsDescriptors(element))); + + if (element instanceof HtmlTag) { + HtmlUtil.addHtmlSpecificCompletions(descriptor, element, variants); + } + visited.add(descriptor.getNSDescriptor()); + } + else{ + // Don't use default namespace in case there are other namespaces in scope + // If there are tags from default namespace they will be handeled via + // their element descriptors (prev if section) + if(namespace.length() == 0 && !visited.isEmpty()) continue; + final XmlNSDescriptor NSDescriptor = element.getNSDescriptor(namespace, false); + if(NSDescriptor != null && !visited.contains(NSDescriptor)){ + visited.add(NSDescriptor); + variants.addAll(Arrays.asList(NSDescriptor.getRootElementsDescriptors())); + } + } + } + + final Iterator iterator = variants.iterator(); + String[] ret = new String[variants.size()]; + int index = 0; + while(iterator.hasNext()){ + final XmlElementDescriptor descriptor = iterator.next(); + ret[index++] = descriptor.getName(element.getParent()); + } + return ret; + } + + public boolean isSoft() { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttlistDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttlistDeclImpl.java new file mode 100644 index 00000000000..77d432208c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttlistDeclImpl.java @@ -0,0 +1,44 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.scope.processor.FilterElementProcessor; +import com.intellij.psi.xml.XmlAttlistDecl; +import com.intellij.psi.xml.XmlAttributeDecl; +import com.intellij.psi.xml.XmlElement; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Mike + */ +public class XmlAttlistDeclImpl extends XmlElementImpl implements XmlAttlistDecl { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlAttlistDeclImpl"); + + public XmlAttlistDeclImpl() { + super(XML_ATTLIST_DECL); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == XML_NAME) { + return ChildRole.XML_NAME; + } + else { + return ChildRole.NONE; + } + } + + public XmlElement getNameElement() { + return (XmlElement)findChildByRoleAsPsiElement(ChildRole.XML_NAME); + } + + public XmlAttributeDecl[] getAttributeDecls() { + final List result = new ArrayList(); + processElements(new FilterElementProcessor(new ClassFilter(XmlAttributeDecl.class), result), this); + return (XmlAttributeDecl[])result.toArray(new XmlAttributeDecl[result.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeDeclImpl.java new file mode 100644 index 00000000000..784b55e1c34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeDeclImpl.java @@ -0,0 +1,123 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.xml.XmlAttributeDecl; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlEnumeratedType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.util.IncorrectOperationException; + +/** + * @author Mike + */ +public class XmlAttributeDeclImpl extends XmlElementImpl implements XmlAttributeDecl { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlAttributeDeclImpl"); + + public XmlAttributeDeclImpl() { + super(XML_ATTRIBUTE_DECL); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_NAME) { + return ChildRole.XML_NAME; + } + else if (i == XML_ATT_REQUIRED) { + return ChildRole.XML_ATT_REQUIRED; + } + else if (i == XML_ATT_FIXED) { + return ChildRole.XML_ATT_FIXED; + } + else if (i == XML_ATT_IMPLIED) { + return ChildRole.XML_ATT_IMPLIED; + } + else if (i == XML_ATTRIBUTE_VALUE) { + return ChildRole.XML_DEFAULT_VALUE; + } + else if (i == XML_ENUMERATED_TYPE) { + return ChildRole.XML_ENUMERATED_TYPE; + } + else { + return ChildRole.NONE; + } + } + + public XmlElement getNameElement() { + return (XmlElement)findElementByTokenType(XML_NAME); + } + + public boolean isAttributeRequired() { + return findElementByTokenType(XML_ATT_REQUIRED) != null; + } + + public boolean isAttributeFixed() { + return findElementByTokenType(XML_ATT_FIXED) != null; + } + + public boolean isAttributeImplied() { + return findElementByTokenType(XML_ATT_IMPLIED) != null; + } + + public XmlAttributeValue getDefaultValue() { + return (XmlAttributeValue)findElementByTokenType(XML_ATTRIBUTE_VALUE); + } + + public boolean isEnumerated() { + return findElementByTokenType(XML_ENUMERATED_TYPE) != null; + } + + public XmlElement[] getEnumeratedValues() { + XmlEnumeratedType enumeratedType = (XmlEnumeratedType)findElementByTokenType(XML_ENUMERATED_TYPE); + if (enumeratedType != null){ + return enumeratedType.getEnumeratedValues(); + } + else{ + return XmlElement.EMPTY_ARRAY; + } + } + + public boolean isIdAttribute() { + final PsiElement elementType = findElementType(); + + return elementType!=null && elementType.getText().equals("ID"); + } + + private PsiElement findElementType() { + final PsiElement elementName = findElementByTokenType(XML_NAME); + final PsiElement nextSibling = (elementName!=null)?elementName.getNextSibling():null; + final PsiElement elementType = (nextSibling instanceof PsiWhiteSpace)?nextSibling.getNextSibling():nextSibling; + + return elementType; + } + + public boolean isIdRefAttribute() { + final PsiElement elementType = findElementType(); + + return elementType!=null && elementType.getText().equals("IDREF"); + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return true; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + return null; + } + + public String getName() { + XmlElement name = getNameElement(); + return (name != null )? name.getText():null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java new file mode 100644 index 00000000000..b48475bff6f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java @@ -0,0 +1,225 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.xml.aspect.XmlAttributeSet; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.meta.PsiMetaOwner; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; +import com.intellij.pom.PomModel; +import com.intellij.pom.PomTransaction; +import com.intellij.pom.event.PomModelEvent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Mike + */ +public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlAttributeImpl"); + + public XmlAttributeImpl() { + super(XML_ATTRIBUTE); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_NAME) { + return ChildRole.XML_NAME; + } + else if (i == XML_ATTRIBUTE_VALUE) { + return ChildRole.XML_ATTRIBUTE_VALUE; + } + else { + return ChildRole.NONE; + } + } + + public XmlAttributeValue getValueElement() { + return (XmlAttributeValue)XmlChildRole.ATTRIBUTE_VALUE_FINDER.findChild(this); + } + + public void setValue(String valueText) throws IncorrectOperationException{ + final TreeElement value = XmlChildRole.ATTRIBUTE_VALUE_FINDER.findChild(this); + final PomModel model = getProject().getModel(); + final TreeElement newValue = XmlChildRole.ATTRIBUTE_VALUE_FINDER.findChild((CompositeElement)getManager().getElementFactory().createXmlAttribute("a", valueText)); + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + if(value != null){ + CodeEditUtil.replaceChild(XmlAttributeImpl.this, value, newValue); + } + else CodeEditUtil.addChild(XmlAttributeImpl.this, newValue, null); + return XmlAttributeSet.createXmlAttributeSet(model, getParent(), getName(), value != null ? value.getText() : null); + } + }, model.getModelAspect(XmlAspect.class)); + } + + public XmlElement getNameElement() { + return (XmlElement)XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(this); + } + + public String getNamespace() { + return getName() != null ? getParent().getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(getName())) : XmlUtil.EMPTY_NAMESPACE; + } + + public XmlTag getParent(){ + return (XmlTag)super.getParent(); + } + + public String getLocalName() { + return getName() != null ? XmlUtil.findLocalNameByQualifiedName(getName()) : ""; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlAttribute(this); + } + + public String getValue() { + final XmlAttributeValue valueElement = getValueElement(); + return valueElement != null ? valueElement.getValue() : null; + } + + public String getName() { + XmlElement element = getNameElement(); + return element != null ? element.getText() : ""; + } + + public boolean isNamespaceDeclaration() { + final String name = getName(); + return name.startsWith("xmlns:") || name.equals("xmlns"); + } + + public PsiElement setName(final String nameText) throws IncorrectOperationException { + final TreeElement name = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(this); + final String oldName = name.getText(); + final PomModel model = getProject().getModel(); + final TreeElement newName = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild((CompositeElement)getManager().getElementFactory().createXmlAttribute(nameText, "")); + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + CodeEditUtil.replaceChild(XmlAttributeImpl.this, name, newName); + return XmlAttributeSet.createXmlAttributeSet(model, getParent(), nameText, getValue()); + } + }, model.getModelAspect(XmlAspect.class)); + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + return XmlAttributeSet.createXmlAttributeSet(model, getParent(), oldName, null); + } + }, model.getModelAspect(XmlAspect.class)); + + return this; + } + + public PsiReference getReference() { + final PsiReference[] refs = getReferences(); + if (refs != null && refs.length > 0){ + return refs[0]; + } + return null; + } + + public PsiReference[] getReferences() { + final PsiElement parent = getParent(); + if (!(parent instanceof XmlTag)) return PsiReference.EMPTY_ARRAY; + final XmlElementDescriptor descr = ((XmlTag)parent).getDescriptor(); + if (descr != null){ + return new PsiReference[]{new MyPsiReference(descr)}; + } + return PsiReference.EMPTY_ARRAY; + } + + public XmlAttributeDescriptor getDescriptor() { + final PsiElement parent = getParent(); + if (parent instanceof XmlDecl) return null; + final XmlElementDescriptor descr = ((XmlTag)parent).getDescriptor(); + if (descr == null) return null; + final XmlAttributeDescriptor attributeDescr = descr.getAttributeDescriptor(this); + return attributeDescr == null ? descr.getAttributeDescriptor(getName()) : attributeDescr; + } + + private class MyPsiReference implements PsiReference { + private final XmlElementDescriptor myDescr; + + public MyPsiReference(XmlElementDescriptor descr) { + myDescr = descr; + } + + public PsiElement getElement() { + return XmlAttributeImpl.this; + } + + public TextRange getRangeInElement() { + final int parentOffset = getNameElement().getStartOffsetInParent(); + return new TextRange(parentOffset, parentOffset + getNameElement().getTextLength()); + } + + public PsiElement resolve() { + final XmlAttributeDescriptor descriptor = myDescr.getAttributeDescriptor(XmlAttributeImpl.this.getName()); + if (descriptor != null) + return descriptor.getDeclaration(); + return null; + } + + public String getCanonicalText() { + return XmlAttributeImpl.this.getName(); + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return setName(newElementName); + } + + // TODO[ik]: namespace support + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiMetaOwner){ + final PsiMetaOwner owner = (PsiMetaOwner)element; + if (owner.getMetaData() instanceof XmlElementDescriptor){ + setName(owner.getMetaData().getName()); + } + } + throw new IncorrectOperationException("Cant bind to not a xml element definition!"); + } + + public boolean isReferenceTo(PsiElement element) { + return element.getManager().areElementsEquivalent(element, resolve()); + } + + public Object[] getVariants() { + final List variants = new ArrayList(); + + final XmlElementDescriptor parentDescriptor = getParent().getDescriptor(); + if (parentDescriptor != null){ + final XmlTag declarationTag = getParent(); + final XmlAttribute[] attributes = declarationTag.getAttributes(); + final XmlAttributeDescriptor[] descriptors = parentDescriptor.getAttributesDescriptors(); + outer: + for(int i = 0; i < descriptors.length; i++){ + for (int j = 0; j < attributes.length; j++) { + final XmlAttribute attribute = attributes[j]; + if(attribute == XmlAttributeImpl.this) continue; + final String name = attribute.getName(); + if(name != null && name.equals(descriptors[i].getName())) continue outer; + } + final XmlAttributeDescriptor descriptor = descriptors[i]; + variants.add(descriptor.getName()); + } + } + return variants.toArray(); + } + + public boolean isSoft() { + return false; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeValueImpl.java new file mode 100644 index 00000000000..d53ab67bfa1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlAttributeValueImpl.java @@ -0,0 +1,57 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.source.ReplaceableTextPsiElement; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.impl.ant.AntPropertyDeclaration; + +/** + * @author Mike + */ +public class XmlAttributeValueImpl extends XmlElementImpl implements XmlAttributeValue, ReplaceableTextPsiElement{ + public XmlAttributeValueImpl() { + super(XML_ATTRIBUTE_VALUE); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlAttributeValue(this); + } + + public String getValue() { + String text = getText(); + if (StringUtil.startsWithChar(text, '\"') || StringUtil.startsWithChar(text, '\'')) text = text.substring(1); + if (StringUtil.endsWithChar(text, '\"') || StringUtil.endsWithChar(text, '\'')) text = text.substring(0, text.length() - 1); + + return text; + } + + public PsiReference[] getReferences() { + return ResolveUtil.getReferencesFromProviders(this); + } + + public PsiElement replaceRangeInText(final TextRange range, String newSubText) + throws IncorrectOperationException { + XmlFile file = (XmlFile) getManager().getElementFactory().createFileFromText("dummy.xml", ""); + return XmlAttributeValueImpl.this.replace(file.getDocument().getRootTag().getAttributes()[0].getValueElement()); + } + + private String getNewText(final TextRange range, String newSubstring) { + final String text = XmlAttributeValueImpl.this.getText(); + return text.substring(0, range.getStartOffset()) + newSubstring + text.substring(range.getEndOffset()); + } + + public int getTextOffset() { + return getTextRange().getStartOffset() + 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlCommentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlCommentImpl.java new file mode 100644 index 00000000000..93ecf357306 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlCommentImpl.java @@ -0,0 +1,17 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.xml.XmlComment; + +/** + * @author Mike + */ +public class XmlCommentImpl extends XmlElementImpl implements XmlComment { + public XmlCommentImpl() { + super(XML_COMMENT); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlComment(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDeclImpl.java new file mode 100644 index 00000000000..02e69c80e5a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDeclImpl.java @@ -0,0 +1,17 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.xml.XmlDecl; + +/** + * @author Mike + */ +public class XmlDeclImpl extends XmlElementImpl implements XmlDecl{ + public XmlDeclImpl() { + super(XML_DECL); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlDecl(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java new file mode 100644 index 00000000000..0804aa1cb22 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java @@ -0,0 +1,163 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.util.XmlUtil; + +/** + * @author Mike + */ +public class XmlDoctypeImpl extends XmlElementImpl implements XmlDoctype { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlDoctypeImpl"); + + public XmlDoctypeImpl() { + super(XML_DOCTYPE); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_DOCTYPE_PUBLIC) { + return ChildRole.XML_DOCTYPE_PUBLIC; + } + else if (i == XML_DOCTYPE_SYSTEM) { + return ChildRole.XML_DOCTYPE_SYSTEM; + } + else if (i == XML_NAME) { + return ChildRole.XML_NAME; + } + else { + return ChildRole.NONE; + } + } + + + public String getDtdUri() { + final XmlElement dtdUrlElement = getDtdUrlElement(); + if (dtdUrlElement == null) return null; + return extractValue(dtdUrlElement); + } + + private String extractValue(PsiElement element) { + String text = element.getText(); + return text.substring(1, text.length() - 1); + } + + public XmlElement getDtdUrlElement() { + PsiElement docTypePublic = findChildByRoleAsPsiElement(ChildRole.XML_DOCTYPE_PUBLIC); + + if (docTypePublic != null){ + PsiElement element = docTypePublic.getNextSibling(); + + while(element instanceof PsiWhiteSpace || element instanceof XmlComment){ + element = element.getNextSibling(); + } + + //element = element.getNextSibling(); // pass qoutes + if (element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN){ + element = element.getNextSibling(); + + while(element instanceof PsiWhiteSpace || element instanceof XmlComment){ + element = element.getNextSibling(); + } + + if (element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN){ + return (XmlElement)element; + } + } + } + + PsiElement docTypeSystem = findChildByRoleAsPsiElement(ChildRole.XML_DOCTYPE_SYSTEM); + + if (docTypeSystem != null){ + PsiElement element = docTypeSystem.getNextSibling(); + + //element = element.getNextSibling(); // pass qoutes + while(element instanceof PsiWhiteSpace || element instanceof XmlComment){ + element = element.getNextSibling(); + } + + if (element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN){ + return (XmlElement)element; + } + } + + return null; + } + + public XmlElement getNameElement() { + return (XmlElement)findChildByRoleAsPsiElement(ChildRole.XML_NAME); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlDoctype(this); + } + + public XmlMarkupDecl getMarkupDecl() { + for(PsiElement child = this.getFirstChild(); child != null; child = child.getNextSibling()){ + if (child instanceof XmlMarkupDecl){ + XmlMarkupDecl decl = (XmlMarkupDecl)child; + return decl; + } + } + + return null; + } + + public PsiReference getReference() { + final XmlElement dtdUrlElement = getDtdUrlElement(); + if (dtdUrlElement == null) return null; + + final String uri = extractValue(dtdUrlElement); + + return new PsiReference() { + public PsiElement getElement() { + return XmlDoctypeImpl.this; + } + + public TextRange getRangeInElement() { + return new TextRange( + dtdUrlElement.getTextRange().getStartOffset() - getTextRange().getStartOffset(), + dtdUrlElement.getTextRange().getEndOffset() - getTextRange().getStartOffset() + ); + } + + public PsiElement resolve() { + return XmlUtil.findXmlFile(XmlUtil.getContainingFile(XmlDoctypeImpl.this), uri); + } + + public String getCanonicalText() { + return uri; + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + public boolean isReferenceTo(PsiElement element) { + return element == dtdUrlElement; + } + + public Object[] getVariants() { + return null; + } + + public boolean isSoft() { + return false; + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDocumentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDocumentImpl.java new file mode 100644 index 00000000000..7e8b23603d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlDocumentImpl.java @@ -0,0 +1,116 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.ant.impl.dom.xmlBridge.AntDOMNSDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.*; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.util.XmlNSDescriptorSequence; +import com.intellij.xml.util.XmlUtil; +import gnu.trove.TObjectIntHashMap; + +import java.lang.ref.WeakReference; + +/** + * @author Mike + */ +public class XmlDocumentImpl extends XmlElementImpl implements XmlDocument { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlDocumentImpl"); + + private CachedValue myDescriptor = null; + + public XmlDocumentImpl() { + this(XML_DOCUMENT); + } + + protected XmlDocumentImpl(IElementType type) { + super(type); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlDocument(this); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_PROLOG) { + return ChildRole.XML_PROLOG; + } + else if (i == XML_TAG) { + return ChildRole.XML_TAG; + } + else { + return ChildRole.NONE; + } + } + + public XmlProlog getProlog() { + return (XmlProlog)findElementByTokenType(XML_PROLOG); + } + + public XmlTag getRootTag() { + return (XmlTag)findElementByTokenType(XML_TAG); + } + + public XmlNSDescriptor getRootTagNSDescriptor() { + XmlTag rootTag = getRootTag(); + return rootTag != null ? rootTag.getNSDescriptor(rootTag.getNamespace(), false) : null; + } + + public PsiElement copy() { + final XmlDocumentImpl copy = (XmlDocumentImpl)super.copy(); + copy.myDescriptor = null; + + return copy; + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return true; + } + + public void dumpStatistics(){ + System.out.println("Statistics:"); + final TObjectIntHashMap map = new TObjectIntHashMap(); + + final PsiRecursiveElementVisitor psiRecursiveElementVisitor = new PsiRecursiveElementVisitor(){ + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitXmlToken(XmlToken token) { + inc("Tokens"); + } + + public void visitElement(PsiElement element) { + inc("Elements"); + super.visitElement(element); + } + + private void inc(final String key) { + map.put(key, map.get(key) + 1); + } + }; + + this.accept(psiRecursiveElementVisitor); + + final Object[] keys = map.keys(); + for (int i = 0; i < keys.length; i++) { + final Object key = keys[i]; + System.out.println(key + ": " + map.get(key)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementContentSpecImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementContentSpecImpl.java new file mode 100644 index 00000000000..7d5e91b489c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementContentSpecImpl.java @@ -0,0 +1,52 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.xml.XmlElementContentSpec; +import com.intellij.psi.tree.IElementType; + +/** + * @author Mike + */ +public class XmlElementContentSpecImpl extends XmlElementImpl implements XmlElementContentSpec { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlElementContentSpecImpl"); + + public XmlElementContentSpecImpl() { + super(XML_ELEMENT_CONTENT_SPEC); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_CONTENT_ANY) { + return ChildRole.XML_CONTENT_ANY; + } + else if (i == XML_CONTENT_EMPTY) { + return ChildRole.XML_CONTENT_EMPTY; + } + else if (i == XML_PCDATA) { + return ChildRole.XML_PCDATA; + } + else { + return ChildRole.NONE; + } + } + + public boolean isEmpty() { + return findElementByTokenType(XML_CONTENT_EMPTY) != null; + } + + public boolean isAny() { + return findElementByTokenType(XML_CONTENT_ANY) != null; + } + + public boolean isMixed() { + return findElementByTokenType(XML_PCDATA) != null; + } + + public boolean hasChildren() { + return !(isEmpty() || isAny() || isMixed()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementDeclImpl.java new file mode 100644 index 00000000000..dd1d2e08bd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementDeclImpl.java @@ -0,0 +1,80 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.Factory; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.xml.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +/** + * @author Mike + */ +public class XmlElementDeclImpl extends XmlElementImpl implements XmlElementDecl { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlElementDeclImpl"); + + public XmlElementDeclImpl() { + super(XML_ELEMENT_DECL); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_NAME) { + return ChildRole.XML_NAME; + } + else if (i == XML_ELEMENT_CONTENT_SPEC) { + return ChildRole.XML_ELEMENT_CONTENT_SPEC; + } + else { + return ChildRole.NONE; + } + } + + public XmlElement getNameElement() { + return (XmlElement)findChildByRoleAsPsiElement(ChildRole.XML_NAME); + } + + public XmlElementContentSpec getContentSpecElement() { + return (XmlElementContentSpec)findChildByRoleAsPsiElement(ChildRole.XML_ELEMENT_CONTENT_SPEC); + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return true; + } + + public PsiElement setName(String name) throws IncorrectOperationException { + if (isWritable() && isInProjectContent(getProject(),getContainingFile().getVirtualFile())) { + final XmlElement nameElement = getNameElement(); + + if (nameElement!=null) { + nameElement.replace( + SourceTreeToPsiMap.treeElementToPsi(Factory.createSingleLeafElement(XmlTokenType.XML_NAME,name.toCharArray(),0, name.length(),null,getManager())) + ); + } + } + + return null; + } + + private static boolean isInProjectContent(Project project, VirtualFile vfile) { + return vfile== null || ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(vfile)!=null; + } + + public String getName() { + XmlElement name = getNameElement(); + return (name != null )? name.getText():null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementImpl.java new file mode 100644 index 00000000000..6b77f65af4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlElementImpl.java @@ -0,0 +1,61 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Aug 26, 2002 + * Time: 6:25:08 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.xml.XmlElement; +import com.intellij.xml.util.XmlUtil; + +public abstract class XmlElementImpl extends CompositePsiElement implements XmlElement { + public XmlElementImpl(IElementType type) { + super(type); + } + + public boolean processElements(PsiElementProcessor processor, PsiElement place){ + return XmlUtil.processXmlElements(this, processor, false); + } + + public XmlElement findElementByTokenType(final IElementType type){ + final XmlElement[] result = new XmlElement[1]; + result[0] = null; + + processElements(new PsiBaseElementProcessor(){ + public boolean execute(PsiElement element){ + if(element instanceof TreeElement && ((TreeElement)element).getElementType() == type){ + result[0] = (XmlElement)element; + return false; + } + return true; + } + }, this); + + return result[0]; + } + + public PsiElement getContext() { + final PsiElement data = getUserData(ORIGINAL_ELEMENT); + if(data != null) return (XmlElement)data; + return super.getParent(); + } + + public PsiElement getParent(){ + return getContext(); + } + + public TextRange getTextRange() { + final int textOffset = getStartOffset(); + return new TextRange(textOffset, textOffset + getTextLength()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java new file mode 100644 index 00000000000..174b6b32f44 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java @@ -0,0 +1,216 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.TokenTypeLinks; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.xml.IXmlElementType; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.ParsingContext; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.lexer.FilterLexer; +import com.intellij.lexer.*; +import com.intellij.psi.impl.source.parsing.xml.XmlParsing; +import com.intellij.psi.impl.source.parsing.xml.XmlPsiLexer; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.xml.*; +import com.intellij.xml.util.XmlUtil; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author mike + */ +public class XmlEntityDeclImpl extends XmlElementImpl implements XmlEntityDecl { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlEntityDeclImpl"); + + public XmlEntityDeclImpl() { + super(XML_ENTITY_DECL); + } + + public String getName() { + for (TreeElement e = firstChild; e != null; e = e.getTreeNext()) { + if (e instanceof XmlTokenImpl) { + XmlTokenImpl xmlToken = (XmlTokenImpl)e; + + if (xmlToken.getTokenType() == XmlTokenType.XML_NAME) return xmlToken.getText(); + } + } + + return ""; + } + + public PsiElement parse(PsiFile baseFile, int context, final XmlEntityRef originalElement) { + PsiElement dependsOnElement = getValueElement(baseFile); + String value = null; + if (dependsOnElement instanceof XmlAttributeValue) { + XmlAttributeValue attributeValue = (XmlAttributeValue)dependsOnElement; + value = attributeValue.getValue(); + } + else if (dependsOnElement instanceof PsiFile) { + PsiFile file = (PsiFile)dependsOnElement; + value = file.getText(); + } + + if (value == null) return null; + final FileElement holderElement = new DummyHolder(originalElement.getManager(), originalElement).getTreeElement(); + char[] buffer = value.toCharArray(); + Lexer lexer = getLexer(context, buffer); + final ParsingContext parsingContext = new ParsingContext(holderElement.getCharTable()); + final CompositeElement element = Factory.createCompositeElement(XML_ELEMENT_DECL); + TreeUtil.addChildren(holderElement, element); + + switch (context) { + default : + LOG.assertTrue(false, "Entity: " + getName() + " context: " + context); + return null; + + case CONTEXT_ELEMENT_CONTENT_SPEC: + { + parsingContext.getXmlParsing().parseElementContentSpec(element, lexer); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild().getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + + case CONTEXT_ATTRIBUTE_SPEC: + { + parsingContext.getXmlParsing().parseAttributeContentSpec(element, lexer); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + + case CONTEXT_ATTLIST_SPEC: + { + parsingContext.getXmlParsing().parseAttlistContent(element, lexer); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + + case CONTEXT_ENTITY_DECL_CONTENT: + { + parsingContext.getXmlParsing().parseEntityDeclContent(element, lexer); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + + case CONTEXT_GENERIC_XML: + { + + Set names = new HashSet(); + { + // calculating parent names + PsiElement parent = originalElement; + while(parent != null){ + if(parent instanceof XmlTag){ + names.add(((XmlTag)parent).getName()); + } + parent = parent.getParent(); + } + } + parsingContext.getXmlParsing().parseGenericXml(lexer, element, names); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + + case CONTEXT_ENUMERATED_TYPE: + { + parsingContext.getXmlParsing().parseEnumeratedTypeContent(element, lexer); + final PsiElement generated = SourceTreeToPsiMap.treeElementToPsi(element).getFirstChild(); + setDependsOnElement(generated, dependsOnElement); + return setOriginalElement(generated, originalElement); + } + } + } + + private PsiElement setDependsOnElement(PsiElement generated, PsiElement dependsOnElement) { + PsiElement e = generated; + while (e != null) { + e.putUserData(XmlElement.DEPENDING_ELEMENT, dependsOnElement); + e = e.getNextSibling(); + } + return generated; + } + + private PsiElement setOriginalElement(PsiElement element, PsiElement valueElement) { + PsiElement e = element; + while (e != null) { + e.putUserData(XmlElement.ORIGINAL_ELEMENT, (XmlElement)valueElement); + e = e.getNextSibling(); + } + return element; + } + + private Lexer getLexer(int context, char[] buffer) { + Lexer lexer = new XmlPsiLexer(); + FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(XmlParsing.XML_WHITE_SPACE_OR_COMMENT_BIT_SET)); + short state = 0; + + switch (context) { + case CONTEXT_ELEMENT_CONTENT_SPEC: + case CONTEXT_ATTRIBUTE_SPEC: + case CONTEXT_ATTLIST_SPEC: + case CONTEXT_ENUMERATED_TYPE: + case CONTEXT_ENTITY_DECL_CONTENT: + { + state = _OldXmlLexer.DOCTYPE_MARKUP; + break; + } + + case CONTEXT_GENERIC_XML: { + break; + } + + + default: LOG.error("context: " + context); + } + + filterLexer.start(buffer, 0, buffer.length, state); + return filterLexer; + } + + private PsiElement getValueElement(PsiFile baseFile) { + if (isInternalReference()) { + for (TreeElement e = firstChild; e != null; e = e.getTreeNext()) { + if (e.getElementType() == ElementType.XML_ATTRIBUTE_VALUE) { + XmlAttributeValue value = (XmlAttributeValue)SourceTreeToPsiMap.treeElementToPsi(e); + return value; + } + } + } + else { + for (TreeElement e = lastChild; e != null; e = e.getTreePrev()) { + if (e.getElementType() == ElementType.XML_ATTRIBUTE_VALUE) { + XmlAttributeValue value = (XmlAttributeValue)SourceTreeToPsiMap.treeElementToPsi(e); + final XmlFile xmlFile = XmlUtil.findXmlFile(baseFile, value.getValue()); + if (xmlFile != null) { + return xmlFile; + } + + return null; + } + } + } + + return null; + } + + private boolean isInternalReference() { + for (TreeElement e = firstChild; e != null; e = e.getTreeNext()) { + if (e.getElementType() instanceof IXmlElementType) { + XmlToken token = (XmlToken)SourceTreeToPsiMap.treeElementToPsi(e); + if (token.getTokenType() == XmlTokenType.XML_DOCTYPE_PUBLIC || token.getTokenType() == XmlToken.XML_DOCTYPE_SYSTEM) { + return false; + } + } + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java new file mode 100644 index 00000000000..4c05bc48ada --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java @@ -0,0 +1,116 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.*; +import com.intellij.xml.util.XmlUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author mike + */ +public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { + private static final Key XML_ENTITY_DECL_MAP = Key.create("XML_ENTITY_DECL_MAP"); + + public XmlEntityRefImpl() { + super(XML_ENTITY_REF); + } + + public XmlEntityDecl resolve(PsiFile targetFile) { + String text = getText(); + if (text.equals(">") || text.equals(""")) return null; + final String entityName = text.substring(1, text.length() - 1); + + final PsiElement targetElement = targetFile != null ? (PsiElement)targetFile : this; + Map> map = (Map>)targetElement.getUserData(XML_ENTITY_DECL_MAP); + if (map == null){ + map = new HashMap>(); + targetElement.putUserData(XML_ENTITY_DECL_MAP, map); + } + CachedValue value = map.get(entityName); + if (value == null) { + if(getManager() == null){ + return resolveEntity(targetElement, entityName).getValue(); + } + value = getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + return resolveEntity(targetElement, entityName); + } + }); + + + map.put(entityName, value); + } + + return value.getValue(); + } + + private CachedValueProvider.Result resolveEntity(final PsiElement targetElement, final String entityName) { + final List deps = new ArrayList(); + final XmlEntityDecl[] result = new XmlEntityDecl[]{null}; + + PsiElementProcessor processor = new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + if (element instanceof XmlDoctype) { + XmlDoctype xmlDoctype = (XmlDoctype)element; + final String dtdUri = xmlDoctype.getDtdUri(); + if (dtdUri != null) { + final XmlFile xmlFile = XmlUtil.findXmlFile(XmlUtil.getContainingFile(element), dtdUri); + if (xmlFile != null) { + if (xmlFile != targetElement) { + deps.add(xmlFile); + if(!PsiTreeUtil.processElements(xmlFile, this)) return false; + } + } + } + final XmlMarkupDecl markupDecl = xmlDoctype.getMarkupDecl(); + if(markupDecl != null) + if(!PsiTreeUtil.processElements(markupDecl, this)) return false; + } + else if (element instanceof XmlEntityDecl) { + XmlEntityDecl entityDecl = (XmlEntityDecl)element; + final String declName = entityDecl.getName(); + if (declName.equals(entityName)) { + result[0] = entityDecl; + return false; + } + } + + return true; + } + }; + deps.add(targetElement); + + PsiTreeUtil.processElements(targetElement, processor); + + return new CachedValueProvider.Result(result[0], deps.toArray(new Object[deps.size()])); + } + + public XmlTag getParentTag() { + final XmlElement parent = (XmlElement)getParent(); + if(parent instanceof XmlTag) return (XmlTag)parent; + return null; + } + + public XmlTagChild getNextSiblingInTag() { + PsiElement nextSibling = getNextSibling(); + if(nextSibling instanceof XmlTagChild) return (XmlTagChild)nextSibling; + return null; + } + + public XmlTagChild getPrevSiblingInTag() { + final PsiElement prevSibling = getPrevSibling(); + if(prevSibling instanceof XmlTagChild) return (XmlTagChild)prevSibling; + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEnumeratedTypeImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEnumeratedTypeImpl.java new file mode 100644 index 00000000000..a1c26c93f26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlEnumeratedTypeImpl.java @@ -0,0 +1,28 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.scope.processor.FilterScopeProcessor; +import com.intellij.psi.scope.processor.FilterElementProcessor; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlEnumeratedType; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.filters.position.TokenTypeFilter; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author mike + */ +public class XmlEnumeratedTypeImpl extends XmlElementImpl implements XmlEnumeratedType { + public XmlEnumeratedTypeImpl() { + super(XML_ENUMERATED_TYPE); + } + + public XmlElement[] getEnumeratedValues() { + final List result = new ArrayList(); + processElements(new FilterElementProcessor(new TokenTypeFilter(XmlTokenType.XML_NAME), result), this); + return (XmlElement[])result.toArray(new XmlElement[result.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlFileImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlFileImpl.java new file mode 100644 index 00000000000..1f44dc1b066 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlFileImpl.java @@ -0,0 +1,90 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.parsing.ChameleonTransforming; +import com.intellij.psi.impl.source.parsing.xml.XmlPsiLexer; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; + +/** + * @author Mike + */ +public class XmlFileImpl extends PsiFileImpl implements XmlFile { + public XmlFileImpl(PsiManagerImpl manager, VirtualFile file) { + super(manager, XML_FILE, getChameleonTypeByFile(file), file); + } + + public XmlFileImpl(PsiManagerImpl manager, VirtualFile file, IElementType elementType, IElementType contentElementType) { + super(manager, elementType, contentElementType, file); + } + + private static IElementType getChameleonTypeByFile(VirtualFile file) { + final FileType fileTypeByFile = FileTypeManager.getInstance().getFileTypeByFile(file); + return getElementType(fileTypeByFile); + } + + private static IElementType getElementType(final FileType fileTypeByFile) { + if(fileTypeByFile == StdFileTypes.XML) { + return XML_FILE_TEXT; + } + if (fileTypeByFile == StdFileTypes.XHTML) { + return XHTML_FILE_TEXT; + } + if(fileTypeByFile == StdFileTypes.HTML) return HTML_FILE_TEXT; + if(fileTypeByFile == StdFileTypes.DTD) return DTD_FILE_TEXT; + return null; + } + + public IElementType getContentElementType() { + return getElementType(myType); + } + + public XmlFileImpl(PsiManagerImpl manager, String name, char[] text, int startOffset, int endOffset, FileType fileType) { + super(manager, XML_FILE, getElementType(fileType), name, text, startOffset, endOffset); + } + + public XmlFileImpl(PsiManagerImpl manager, String name, char[] text, int startOffset, int endOffset, FileType fileType, IElementType elementType) { + super(manager, elementType, getElementType(fileType), name, text, startOffset, endOffset); + } + + public XmlDocument getDocument() { + CompositeElement treeElement = calcTreeElement(); + ChameleonTransforming.transformChildren(treeElement); + return (XmlDocument)treeElement.findChildByRoleAsPsiElement(ChildRole.XML_DOCUMENT); + } + + public boolean processElements(PsiElementProcessor processor, PsiElement place){ + final XmlDocument document = getDocument(); + return document != null ? document.processElements(processor, place) : true; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlFile(this); + } + + public String toString() { + return "XmlFile:" + getName(); + } + + private FileType myType = null; + public FileType getFileType() { + if(myType != null) return myType; + return myType = FileTypeManager.getInstance().getFileTypeByFileName(getName()); + } + + public Lexer createLexer() { + return new XmlPsiLexer(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlMarkupDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlMarkupDeclImpl.java new file mode 100644 index 00000000000..09d8b8f6a47 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlMarkupDeclImpl.java @@ -0,0 +1,22 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.xml.XmlMarkupDecl; + +/** + * @author Mike + */ +public class XmlMarkupDeclImpl extends XmlElementImpl implements XmlMarkupDecl { + public XmlMarkupDeclImpl() { + super(XML_MARKUP_DECL); + } + + public PsiMetaData getMetaData(){ + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough(){ + return true; //To change body of implemented methods use Options | File Templates. + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlNotationDeclImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlNotationDeclImpl.java new file mode 100644 index 00000000000..31f8432088f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlNotationDeclImpl.java @@ -0,0 +1,39 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlElementContentSpec; +import com.intellij.psi.xml.XmlNotationDecl; +import com.intellij.psi.tree.IElementType; + +/** + * @author Mike + */ +public class XmlNotationDeclImpl extends XmlElementImpl implements XmlNotationDecl { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlElementDeclImpl"); + + public XmlNotationDeclImpl() { + super(XML_NOTATION_DECL); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == XML_ELEMENT_CONTENT_SPEC) { + return ChildRole.XML_ELEMENT_CONTENT_SPEC; + } + else { + return ChildRole.NONE; + } + } + + public XmlElement getNameElement() { + return (XmlElement)findChildByRoleAsPsiElement(ChildRole.XML_NAME); + } + + public XmlElementContentSpec getContentSpecElement() { + return (XmlElementContentSpec)findChildByRoleAsPsiElement(ChildRole.XML_ELEMENT_CONTENT_SPEC); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlProcessingInstructionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlProcessingInstructionImpl.java new file mode 100644 index 00000000000..6274c5a6f9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlProcessingInstructionImpl.java @@ -0,0 +1,44 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jul 31, 2002 + * Time: 9:03:01 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlProcessingInstruction; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlTagChild; +import com.intellij.psi.xml.XmlElement; + +public class XmlProcessingInstructionImpl extends XmlElementImpl implements XmlProcessingInstruction { + public XmlProcessingInstructionImpl() { + super(XML_PROCESSING_INSTRUCTION); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlElement(this); + } + + public XmlTag getParentTag() { + final PsiElement parent = getParent(); + if(parent instanceof XmlTag) return (XmlTag)parent; + return null; + } + + public XmlTagChild getNextSiblingInTag() { + PsiElement nextSibling = getNextSibling(); + if(nextSibling instanceof XmlTagChild) return (XmlTagChild)nextSibling; + return null; + } + + public XmlTagChild getPrevSiblingInTag() { + final PsiElement prevSibling = getPrevSibling(); + if(prevSibling instanceof XmlTagChild) return (XmlTagChild)prevSibling; + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlPrologImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlPrologImpl.java new file mode 100644 index 00000000000..3aadaec514a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlPrologImpl.java @@ -0,0 +1,37 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.xml.XmlDoctype; +import com.intellij.psi.xml.XmlProlog; + +/** + * @author Mike + */ +public class XmlPrologImpl extends XmlElementImpl implements XmlProlog { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlPrologImpl"); + + public XmlPrologImpl() { + super(XML_PROLOG); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlProlog(this); + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + if (child.getElementType() == XML_DOCTYPE) { + return ChildRole.XML_DOCTYPE; + } + else { + return ChildRole.NONE; + } + } + + public XmlDoctype getDoctype() { + return (XmlDoctype)findChildByRoleAsPsiElement(ChildRole.XML_DOCTYPE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java new file mode 100644 index 00000000000..df8a14d6500 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java @@ -0,0 +1,965 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.ant.impl.dom.xmlBridge.AntDOMNSDescriptor; +import com.intellij.j2ee.ExternalResourceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.pom.PomModel; +import com.intellij.pom.PomTransaction; +import com.intellij.pom.event.PomModelEvent; +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.meta.MetaRegistry; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.jsp.tagLibrary.TldUtil; +import com.intellij.psi.impl.source.html.dtd.HtmlNSDescriptorImpl; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.xml.aspect.*; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.*; +import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.BidirectionalMap; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.impl.schema.XmlNSDescriptorImpl; +import com.intellij.xml.util.XmlNSDescriptorSequence; +import com.intellij.xml.util.XmlTagTextUtil; +import com.intellij.xml.util.XmlUtil; + +import java.lang.ref.WeakReference; +import java.util.*; + +/** + * @author Mike + */ + +public class XmlTagImpl extends XmlElementImpl implements XmlTag/*, ModificationTracker */{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTagImpl"); + + private String myName = null; + private XmlAttribute[] myAttributes = null; + private Map myAttributeValueMap = null; + private XmlTag[] myTags = null; + private XmlTagValue myValue = null; + private Map> myNSDescriptorsMap = null; + + private boolean myHaveNamespaceDeclarations = false; + private BidirectionalMap myNamespaceMap = null; + private String myNamespace = null; + + public XmlTagImpl() { + this(XML_TAG); + } + + protected XmlTagImpl(IElementType type) { + super(type); + } + + public void clearCaches() { + myName = null; + myNamespaceMap = null; + myNamespace = null; + myAttributes = null; + myAttributeValueMap = null; + myHaveNamespaceDeclarations = false; + myValue = null; + myTags = null; + myNSDescriptorsMap = null; + super.clearCaches(); + } + + public PsiReference[] getReferences() { + ProgressManager.getInstance().checkCanceled(); + final TreeElement startTagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(this); + if (startTagName == null) return PsiReference.EMPTY_ARRAY; + final TreeElement endTagName = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(this); + final PsiReference[] referencesFromProviders = ResolveUtil.getReferencesFromProviders(this); + if (endTagName != null){ + final PsiReference[] psiReferences = new PsiReference[referencesFromProviders.length + 2]; + psiReferences[0] = new TagNameReference(startTagName, true); + psiReferences[1] = new TagNameReference(endTagName, false); + + for (int i = 0; i < referencesFromProviders.length; i++) { + psiReferences[i + 2] = referencesFromProviders[i]; + } + return psiReferences; + } + else{ + final PsiReference[] psiReferences = new PsiReference[referencesFromProviders.length + 1]; + psiReferences[0] = new TagNameReference(startTagName, true); + + for (int i = 0; i < referencesFromProviders.length; i++) { + psiReferences[i + 1] = referencesFromProviders[i]; + } + return psiReferences; + } + } + + public XmlNSDescriptor getNSDescriptor(final String namespace, boolean strict) { + initNSDescriptorsMap(); + if(myNSDescriptorsMap.isEmpty()) return ((XmlTag)getParent()).getNSDescriptor(namespace, strict); + CachedValue descriptor = myNSDescriptorsMap.get(namespace); + if(descriptor != null) { + final XmlNSDescriptor value = descriptor.getValue(); + if(value != null) return value; + } + + if(!strict) { + descriptor = myNSDescriptorsMap.get(XmlUtil.ALL_NAMESPACE); + } + + return descriptor != null ? descriptor.getValue() : null; + } + + public boolean isEmpty() { + return XmlChildRole.CLOSING_TAG_START_FINDER.findChild(this) == null; + } + + private Map> initNSDescriptorsMap() { + boolean exceptionOccurred = false; + + if(myNSDescriptorsMap == null){ + try{ + { + // XSD aware attributes processing + final String noNamespaceDeclaration = getAttributeValue("noNamespaceSchemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI); + final String schemaLocationDeclaration = getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI); + if(noNamespaceDeclaration != null){ + initializeSchema(XmlUtil.EMPTY_NAMESPACE, noNamespaceDeclaration); + } + if(schemaLocationDeclaration != null){ + final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration); + while(tokenizer.hasMoreTokens()){ + final String uri = tokenizer.nextToken(); + if(tokenizer.hasMoreTokens()){ + initializeSchema(uri, tokenizer.nextToken()); + } + } + } + } + { + // namespace attributes processing (XSD declaration via ExternalResourceManager) + if(containNamespaceDeclarations()){ + final XmlAttribute[] attributes = getAttributes(); + for (int i = 0; i < attributes.length; i++) { + final XmlAttribute attribute = attributes[i]; + if(attribute.isNamespaceDeclaration()){ + String ns = attribute.getValue(); + if (ns == null) ns = XmlUtil.EMPTY_NAMESPACE; + if(myNSDescriptorsMap == null || !myNSDescriptorsMap.containsKey(ns)) initializeSchema(ns, ns); + } + } + } + } + + final XmlElement parent = getParent(); + if((myNSDescriptorsMap == null || myNSDescriptorsMap.isEmpty()) && parent instanceof XmlDocument){ + // Top most level + final XmlDocument document = (XmlDocument)parent; + myNSDescriptorsMap = new HashMap>(1); + + final String defaultNamespace = XmlUtil.getDefaultNamespace(document); + if (XmlUtil.ANT_URI.equals(defaultNamespace)){ + myNSDescriptorsMap.put(defaultNamespace, getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public Result compute() { + final XmlNSDescriptor antNSDescriptor = new AntDOMNSDescriptor(); + antNSDescriptor.init(document); + return new Result(antNSDescriptor, antNSDescriptor.getDependences()); + } + }, false)); + } + else if(XmlUtil.XHTML_URI.equals(defaultNamespace)){ + initializeSchema(defaultNamespace, defaultNamespace); + if (document.getContainingFile().getFileType() == StdFileTypes.HTML) { + final XmlNSDescriptor xhtmlDescriptor = myNSDescriptorsMap.get(defaultNamespace).getValue(); + myNSDescriptorsMap.put(defaultNamespace, getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public Result compute() { + final XmlNSDescriptor htmlNSDescriptor = new HtmlNSDescriptorImpl(xhtmlDescriptor); + return new Result(htmlNSDescriptor, htmlNSDescriptor.getDependences()); + } + }, false)); + } + } + else if(defaultNamespace != null && defaultNamespace != XmlUtil.EMPTY_NAMESPACE){ + initializeSchema(defaultNamespace, defaultNamespace); + } + + myNSDescriptorsMap.put(XmlUtil.ALL_NAMESPACE, getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public Result compute() { + XmlNSDescriptor descr = null; + final XmlDoctype doctype = document.getProlog().getDoctype(); + + if (doctype != null){ + if (doctype.getMarkupDecl() != null){ + descr = (XmlNSDescriptor)doctype.getMarkupDecl().getMetaData(); + } + if (doctype.getDtdUri() != null){ + final XmlFile xmlFile = XmlUtil.findXmlFile(XmlUtil.getContainingFile(document), doctype.getDtdUri()); + final XmlNSDescriptor descr1 = xmlFile == null ? null : (XmlNSDescriptor)xmlFile.getDocument().getMetaData(); + if (descr != null && descr1 != null){ + descr = new XmlNSDescriptorSequence(new XmlNSDescriptor[]{descr, descr1}); + } + else if (descr1 != null) { + descr = descr1; + } + } + } + + if(descr == null && myNSDescriptorsMap.size() == 1){ + String dtdStructure = XmlUtil.generateDocumentDTD(document); + try{ + final PsiFile fileFromText = getManager().getElementFactory().createFileFromText( + XmlUtil.getContainingFile(document).getName() + ".dtd", + dtdStructure + ); + if (fileFromText instanceof XmlFile) { + final XmlFile file = (XmlFile)fileFromText; + return new Result((XmlNSDescriptor)file.getDocument().getMetaData(), new Object[]{new WeakReference(document)}); + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + if(descr != null) return new Result(descr, new Object[]{new WeakReference(doctype), descr.getDependences()}); + return new Result(null, new Object[0]); + } + }, false)); + } + } + catch(RuntimeException e){ + myNSDescriptorsMap = null; + exceptionOccurred = true; + throw e; + } + finally{ + if(myNSDescriptorsMap == null && !exceptionOccurred) { + myNSDescriptorsMap = Collections.EMPTY_MAP; + } + } + } + return myNSDescriptorsMap; + } + + private boolean initializeSchema(String namespace, final String fileLocation) { + XmlNSDescriptor descriptor; + if(myNSDescriptorsMap == null) myNSDescriptorsMap = new HashMap>(); + + final XmlFile containingFile = XmlUtil.getContainingFile(XmlTagImpl.this); + XmlFile file = XmlUtil.findXmlFile(containingFile, ExternalResourceManager.getInstance().getResourceLocation(fileLocation)); + if (file == null && containingFile instanceof JspFile) { + file = TldUtil.getTldFileByUri(namespace,(JspFile)containingFile); + } + + if (file != null){ + descriptor = (XmlNSDescriptor)file.getDocument().getMetaData(); + + if(descriptor != null){ + final XmlFile file1 = file; + + myNSDescriptorsMap.put(namespace, getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + return new Result( + (XmlNSDescriptor)file1.getDocument().getMetaData(), + new Object[]{file1} + ); + } + }, false)); + return true; + } + } + return true; + } + + public PsiReference getReference() { + final PsiReference[] references = getReferences(); + if (references != null && references.length > 0){ + return references[0]; + } + return null; + } + + public XmlElementDescriptor getDescriptor() { + final XmlNSDescriptor nsDescriptor = getNSDescriptor(getNamespace(), false); + XmlElementDescriptor elementDescriptor = (nsDescriptor != null) ? nsDescriptor.getElementDescriptor(this) : null; + + if(elementDescriptor == null){ + final String type = getAttributeValue("type", XmlUtil.XML_SCHEMA_INSTANCE_URI); + if(type != null){ + final String namespaceByPrefix = XmlUtil.findNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(type), this); + final XmlNSDescriptor typeDecr = getNSDescriptor(namespaceByPrefix, true); + if(typeDecr instanceof XmlNSDescriptorImpl){ + final XmlNSDescriptorImpl schemaDescriptor = ((XmlNSDescriptorImpl)typeDecr); + final XmlElementDescriptor descriptorByType = schemaDescriptor.getDescriptorByType(type, this); + elementDescriptor = descriptorByType; + } + } + } + + return elementDescriptor; + } + + public int getChildRole(TreeElement child) { + LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); + if (i == XML_NAME || i == XML_TAG_NAME) { + return ChildRole.XML_TAG_NAME; + } + else if (i == XML_ATTRIBUTE) { + return ChildRole.XML_ATTRIBUTE; + } + else { + return ChildRole.NONE; + } + } + + public String getName() { + if (myName != null) return myName; + + final TreeElement nameElement = XmlChildRole.START_TAG_NAME_FINDER.findChild(this); + if (nameElement != null){ + myName = nameElement.getText(); + } + else{ + myName = ""; + } + + return myName; + } + + public PsiElement setName(final String name) throws IncorrectOperationException { + final PomModel model = getProject().getModel(); + model.runTransaction(new PomTransaction() { + public PomModelEvent run() throws IncorrectOperationException{ + final String oldName = getName(); + final XmlTagImpl dummyTag = (XmlTagImpl)getManager().getElementFactory().createTagFromText(XmlTagTextUtil.composeTagText(name, "aa")); + final XmlTagImpl tag = XmlTagImpl.this; + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(tag); + ChangeUtil.replaceChild(tag, XmlChildRole.START_TAG_NAME_FINDER.findChild(tag), ChangeUtil.copyElement(XmlChildRole.START_TAG_NAME_FINDER.findChild(dummyTag), charTableByTree)); + final TreeElement childByRole = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(tag); + if(childByRole != null) ChangeUtil.replaceChild(tag, childByRole, ChangeUtil.copyElement(XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(dummyTag), charTableByTree)); + + return XmlTagNameChanged.createXmlTagNameChanged(model, tag, oldName); + } + }, model.getModelAspect(XmlAspect.class)); + return this; + } + + public XmlAttribute[] getAttributes() { + if(myAttributes != null) return myAttributes; + myAttributeValueMap = new HashMap(); + + final List result = new ArrayList(); + processElements( + new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + if (element instanceof XmlAttribute){ + XmlAttribute attribute = (XmlAttribute)element; + result.add(attribute); + cacheOneAttributeValue(attribute.getName(),attribute.getValue()); + myHaveNamespaceDeclarations = myHaveNamespaceDeclarations || attribute.isNamespaceDeclaration(); + } + else if (element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_TAG_END) + return false; + return true; + } + }, this + ); + if(result.isEmpty()) myAttributeValueMap = Collections.EMPTY_MAP; + myAttributes = result.toArray(new XmlAttributeImpl[result.size()]); + + return myAttributes; + } + + protected void cacheOneAttributeValue(String name, String value) { + myAttributeValueMap.put(name, value); + } + + public String getAttributeValue(String qname) { + if(myAttributeValueMap == null) getAttributes(); + return myAttributeValueMap.get(qname); + } + + public String getAttributeValue(String name, String namespace) { + final String prefix = getPrefixByNamespace(namespace); + if(prefix != null && prefix.length() > 0) name = prefix + ":" + name; + return getAttributeValue(name); + } + + public XmlTag[] getSubTags() { + if(myTags != null) return myTags; + final List result = new ArrayList(); + + processElements( + new PsiBaseElementProcessor() { + public boolean execute(PsiElement element) { + if (element instanceof XmlTag) result.add((XmlTag)element); + return true; + } + }, this); + + myTags = result.toArray(new XmlTag[result.size()]); + return myTags; + } + + public XmlTag[] findSubTags(String name) { + return findSubTags(name, null); + } + + public XmlTag[] findSubTags(final String name, final String namespace) { + final XmlTag[] subTags = getSubTags(); + final List result = new ArrayList(); + for (int i = 0; i < subTags.length; i++) { + final XmlTag subTag = subTags[i]; + if(namespace == null){ + if(name.equals(subTag.getName())) result.add(subTag); + } + else if(name.equals(subTag.getLocalName()) && namespace.equals(subTag.getNamespace())){ + result.add(subTag); + } + } + return result.toArray(new XmlTag[result.size()]); + } + + public XmlTag findFirstSubTag(String name) { + final XmlTag[] subTags = findSubTags(name); + if(subTags.length > 0) return subTags[0]; + return null; + } + + public XmlAttribute getAttribute(String name, String namespace) { + String qname = name; + final String prefix = getPrefixByNamespace(namespace); + qname = prefix != null && prefix.length() > 0 ? prefix + ":" + qname : qname; + return getAttribute(qname); + } + + private XmlAttribute getAttribute(String qname){ + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(this); + final XmlAttributeImpl[] attributes = (XmlAttributeImpl[])getAttributes(); + + final int charTableIndex = charTableByTree.checkId(qname); + if(charTableIndex <= 0) return null; + + for (int i = 0; i < attributes.length; i++) { + final XmlAttributeImpl attribute = attributes[i]; + final LeafElement attrNameElement = (LeafElement)XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(attribute); + if(attrNameElement.getCharTabIndex() == charTableIndex) return attribute; + } + return null; + } + + public String getNamespace() { + if(myNamespace != null) return myNamespace; + final String namespace = getNamespaceByPrefix(getNamespacePrefix()); + return myNamespace = (namespace != null ? namespace : XmlUtil.EMPTY_NAMESPACE); + } + + private String getNamespacePrefix() { + final String name = getName(); + final int index = name.indexOf(':'); + if(index >= 0){ + return name.substring(0, index); + } + return ""; + } + + public String getNamespaceByPrefix(String prefix){ + final XmlElement parent = getParent(); + initNamespaceMaps(parent); + if(myNamespaceMap != null){ + final String ns = myNamespaceMap.get(prefix); + if(ns != null) return ns; + } + if(parent instanceof XmlTag) return ((XmlTag)parent).getNamespaceByPrefix(prefix); + return XmlUtil.EMPTY_NAMESPACE; + } + + public String getPrefixByNamespace(String namespace){ + if(namespace == XmlUtil.EMPTY_NAMESPACE || namespace == XmlUtil.ALL_NAMESPACE) return ""; + final XmlElement parent = getParent(); + initNamespaceMaps(parent); + if(myNamespaceMap != null){ + List keysByValue = myNamespaceMap.getKeysByValue(namespace); + final String ns = keysByValue == null ? null : keysByValue.get(0); + if(ns != null) return ns; + } + if(parent instanceof XmlTag) return ((XmlTag)parent).getPrefixByNamespace(namespace); + return null; + } + + public String[] knownNamespaces(){ + final XmlElement parent = getParent(); + initNamespaceMaps(parent); + List known = Collections.EMPTY_LIST; + if(myNamespaceMap != null){ + known = new ArrayList(myNamespaceMap.values()); + } + if(parent instanceof XmlTag){ + if(known.isEmpty()) return ((XmlTag)parent).knownNamespaces(); + known.addAll(Arrays.asList(((XmlTag)parent).knownNamespaces())); + } + return known.toArray(new String[known.size()]); + } + + private void initNamespaceMaps(XmlElement parent) { + if(myNamespaceMap == null && containNamespaceDeclarations()){ + myNamespaceMap = new BidirectionalMap(); + final XmlAttribute[] attributes = getAttributes(); + for (int i = 0; i < attributes.length; i++) { + final XmlAttribute attribute = attributes[i]; + if(attribute.isNamespaceDeclaration()){ + final String name = attribute.getName(); + int splitIndex = name.indexOf(':'); + if(splitIndex < 0) myNamespaceMap.put("", attribute.getValue()); + else myNamespaceMap.put(XmlUtil.findLocalNameByQualifiedName(name), attribute.getValue()); + + } + } + } + if(parent instanceof XmlDocument && myNamespaceMap == null){ + myNamespaceMap = new BidirectionalMap(); + final String defaultNamespace = XmlUtil.getDefaultNamespace((XmlDocument)parent); + if(defaultNamespace == XmlUtil.EMPTY_NAMESPACE){ + final XmlFile xmlFile = (XmlFile)getContainingFile(); + + if(xmlFile != null){ + final String dtdUri = XmlUtil.getDtdUri(xmlFile.getDocument()); + if(dtdUri != null){ + myNamespaceMap.put("", dtdUri); + return; + } + } + + myNamespaceMap.put("", XmlUtil.EMPTY_NAMESPACE); + } + else myNamespaceMap.put("", defaultNamespace); + } + } + + private boolean containNamespaceDeclarations() { + if(myAttributes == null) + getAttributes(); + return myHaveNamespaceDeclarations; + } + + public String getLocalName() { + final String name = getName(); + return name.substring(name.indexOf(':') + 1); + } + + public XmlAttribute setAttribute(String qname, String value) throws IncorrectOperationException { + final XmlAttribute attribute = getAttribute(qname); + + if(attribute != null){ + if(value == null){ + deleteChildInternal(SourceTreeToPsiMap.psiElementToTree(attribute)); + return null; + } + attribute.setValue(value); + return attribute; + } + PsiElement xmlAttribute = add(getManager().getElementFactory().createXmlAttribute(qname, value)); + while(!(xmlAttribute instanceof XmlAttribute)) xmlAttribute = xmlAttribute.getNextSibling(); + return (XmlAttribute)xmlAttribute; + } + + public XmlAttribute setAttribute(String name, String namespace, String value) throws IncorrectOperationException { + final String prefix = getPrefixByNamespace(namespace); + if(prefix != null && prefix.length() > 0) name = prefix + ":" + name; + return setAttribute(name, value); + } + + public XmlTag createChildTag(String localName, String namespace, String bodyText, boolean enforseNamespacesDeep) { + String qname; + final String prefix = getPrefixByNamespace(namespace); + if(prefix != null && prefix.length() > 0) qname = prefix + ":" + localName; + else qname = localName; + try { + String tagStart = qname; + if (getPrefixByNamespace(namespace) == null) { + tagStart += " xmlns=\"" + namespace + "\""; + } + XmlTag retTag; + if(bodyText != null && bodyText.length() > 0){ + retTag = getManager().getElementFactory().createTagFromText("<" + tagStart + ">" + bodyText + ""); + if(enforseNamespacesDeep){ + retTag.acceptChildren(new PsiRecursiveElementVisitor() { + public void visitXmlTag(XmlTag tag){ + final String namespacePrefix = ((XmlTagImpl)tag).getNamespacePrefix(); + if(namespacePrefix.length() == 0 || getNamespaceByPrefix(namespacePrefix) == null){ + String qname; + if(prefix != null && prefix.length() > 0) qname = prefix + ":" + tag.getLocalName(); + else qname = tag.getLocalName(); + try { + tag.setName(qname); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + super.visitXmlTag(tag); + } + public void visitReferenceExpression(PsiReferenceExpression expression) {} + }); + } + } + else + retTag = getManager().getElementFactory().createTagFromText("<" + tagStart + "/>"); + return retTag; + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return null; + } + + public XmlTagValue getValue() { + if(myValue != null) return myValue; + final PsiElement[] elements = getElements(); + final List bodyElements = new ArrayList(elements.length); + + boolean insideBody = false; + for (int i = 0; i < elements.length; i++) { + final PsiElement element = elements[i]; + final TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(element); + if(insideBody){ + if(treeElement.getElementType() == XmlTokenType.XML_END_TAG_START) break; + if(!(treeElement instanceof XmlTagChild)) continue; + bodyElements.add(element); + } + else if(treeElement.getElementType() == XmlTokenType.XML_TAG_END) insideBody = true; + } + + return myValue = new XmlTagValueImpl(bodyElements.toArray(XmlTagChild.EMPTY_ARRAY), this); + } + + private PsiElement[] getElements() { + final List elements = new ArrayList(); + processElements(new PsiBaseElementProcessor() { + public boolean execute(PsiElement psiElement) { + elements.add(psiElement); + return true; + } + }, this); + return elements.toArray(new PsiElement[elements.size()]); + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlTag(this); + } + + public String toString() { + return "XmlTag:" + getName(); + } + + public PsiMetaData getMetaData() { + return MetaRegistry.getMeta(this); + } + + public boolean isMetaEnough() { + return true; + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean beforeB) { + //ChameleonTransforming.transformChildren(this); + TreeElement firstAppended = null; + boolean before = beforeB != null ? beforeB.booleanValue() : true; + try{ + do { + if (firstAppended == null) { + firstAppended = addInternal(first, anchor, before); + anchor = firstAppended; + } + else anchor = addInternal(first, anchor, false); + } + while (first != last && (first = first.getTreeNext()) != null); + } + catch(IncorrectOperationException ioe){} + return firstAppended; + } + + public TreeElement addInternal(final TreeElement child, final TreeElement anchor, final boolean before) throws IncorrectOperationException{ + final PsiFile containingFile = getContainingFile(); + final FileType fileType = containingFile.getFileType(); + final PomModel model = getProject().getModel(); + final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + final TreeElement[] retHolder = new TreeElement[1]; + if (child.getElementType() == XmlElementType.XML_ATTRIBUTE) { + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + final String value = ((XmlAttribute)child).getValue(); + final String name = ((XmlAttribute)child).getName(); + TreeElement treeElement; + if(anchor == null){ + TreeElement startTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this); + if(startTagEnd == null) startTagEnd = XmlChildRole.EMPTY_TAG_END_FINDER.findChild(XmlTagImpl.this); + + if(startTagEnd == null) treeElement = addInternalHack(child, child, null, null,fileType); + else treeElement = addInternalHack(child, child, startTagEnd, Boolean.TRUE, fileType); + } + else treeElement = addInternalHack(child, child, anchor, Boolean.valueOf(before), fileType); + final TreeElement treePrev = treeElement.getTreePrev(); + if(treePrev.getElementType() != XmlTokenType.XML_WHITE_SPACE){ + final LeafElement singleLeafElement = Factory.createSingleLeafElement(XmlTokenType.XML_WHITE_SPACE, new char[]{' '}, 0, 1, + SharedImplUtil.findCharTableByTree(XmlTagImpl.this), null); + ChangeUtil.addChild(XmlTagImpl.this, singleLeafElement, treeElement); + treeElement = singleLeafElement; + } + + retHolder[0] = treeElement; + return XmlAttributeSet.createXmlAttributeSet(model, XmlTagImpl.this, name, value); + } + + }, aspect); + } + else if (child.getElementType() == XmlElementType.XML_TAG || child.getElementType() == XmlElementType.XML_TEXT) { + final BodyInsertTransaction transaction = new BodyInsertTransaction(model, child, anchor, before, fileType); + model.runTransaction(transaction, aspect); + return transaction.getNewElement(); + } + else{ + model.runTransaction(new PomTransaction() { + public PomModelEvent run() { + final TreeElement treeElement = addInternalHack(child, child, anchor, Boolean.valueOf(before), fileType); + retHolder[0] = treeElement; + return XmlTagChildAdd.createXmlTagChildAdd(model, XmlTagImpl.this, (XmlTagChild)SourceTreeToPsiMap.treeElementToPsi(treeElement)); + } + }, aspect); + } + return retHolder[0]; + } + + public void deleteChildInternal(final TreeElement child) { + final PsiFile containingFile = getContainingFile(); + final FileType fileType = containingFile.getFileType(); + final PomModel model = getProject().getModel(); + final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + try { + final TreeElement treePrev = child.getTreePrev(); + final TreeElement treeNext = child.getTreeNext(); + + if (child.getElementType() != XmlElementType.XML_TEXT) { + if (treePrev.getElementType() == XmlElementType.XML_TEXT && treeNext.getElementType() == XmlElementType.XML_TEXT) { + final XmlText xmlText = ((XmlText)SourceTreeToPsiMap.treeElementToPsi(treePrev)); + xmlText.add(SourceTreeToPsiMap.treeElementToPsi(treeNext)); + model.runTransaction(new PomTransaction() { + public PomModelEvent run() { + final PomModelEvent event = new PomModelEvent(model); + final XmlAspectChangeSet xmlAspectChangeSet = new XmlAspectChangeSet(model, (XmlFile)getContainingFile()); + xmlAspectChangeSet.add(new XmlTagChildRemoved(XmlTagImpl.this, (XmlTagChild)treeNext)); + xmlAspectChangeSet.add(new XmlTagChildRemoved(XmlTagImpl.this, (XmlTagChild)child)); + event.registerChangeSet(model.getModelAspect(XmlAspect.class), xmlAspectChangeSet); + + ChangeUtil.removeChild(XmlTagImpl.this, treeNext); + ChangeUtil.removeChild(XmlTagImpl.this, child); + return event; + } + }, aspect); + + // TODO[ik]: remove this hack + if(fileType != StdFileTypes.XHTML){ + model.runTransaction(new PomTransaction() { + public PomModelEvent run() throws IncorrectOperationException{ + final Project project = getProject(); + CodeStyleManager instance = CodeStyleManager.getInstance(project); + instance.reformat(XmlTagImpl.this); + + XmlElement parent = getParent(); + if(parent instanceof XmlTag) + return XmlTagChildChanged.createXmlTagChildChanged(model, (XmlTag)parent, XmlTagImpl.this); + else + return XmlDocumentChanged.createXmlDocumentChanged(model, (XmlDocument)parent); + } + }, aspect); + } + return; + } + } + + model.runTransaction(new PomTransaction() { + public PomModelEvent run() { + if(child.getElementType() == XmlElementType.XML_ATTRIBUTE){ + final String name = ((XmlAttribute)child).getName(); + XmlTagImpl.super.deleteChildInternal(child); + + return XmlAttributeSet.createXmlAttributeSet(model, XmlTagImpl.this, name, null); + } + XmlTagImpl.super.deleteChildInternal(child); + return XmlTagChildRemoved.createXmlTagChildRemoved(model, XmlTagImpl.this, (XmlTagChild)SourceTreeToPsiMap.treeElementToPsi(child)); + } + }, aspect); + + } + catch (IncorrectOperationException e) {} + } + + public void replaceChildInternal(TreeElement child, TreeElement newElement) { + try { + addInternal(newElement, child, false); + deleteChildInternal(child); + } + catch (IncorrectOperationException e) {} + } + + private LeafElement expandTag() throws IncorrectOperationException{ + LeafElement endTagStart = (LeafElement)XmlChildRole.CLOSING_TAG_START_FINDER.findChild(XmlTagImpl.this); + if(endTagStart == null){ + final XmlTagImpl tagFromText = (XmlTagImpl)getManager().getElementFactory().createTagFromText("<" + getName() + ">"); + final TreeElement startTagStart = XmlChildRole.START_TAG_END_FINDER.findChild(tagFromText); + endTagStart = (LeafElement)XmlChildRole.CLOSING_TAG_START_FINDER.findChild(tagFromText); + final LeafElement emptyTagEnd = (LeafElement)XmlChildRole.EMPTY_TAG_END_FINDER.findChild(this); + if(emptyTagEnd != null) ChangeUtil.removeChild(this, emptyTagEnd); + ChangeUtil.addChildren(this, startTagStart, null, null); + } + return endTagStart; + } + + public XmlTag getParentTag() { + final XmlElement parent = getParent(); + if(parent instanceof XmlTag) return (XmlTag)parent; + return null; + } + + public XmlTagChild getNextSiblingInTag() { + final PsiElement nextSibling = getNextSibling(); + if(nextSibling instanceof XmlTagChild) return (XmlTagChild)nextSibling; + return null; + } + + public XmlTagChild getPrevSiblingInTag() { + final PsiElement prevSibling = getPrevSibling(); + if(prevSibling instanceof XmlTagChild) return (XmlTagChild)prevSibling; + return null; + } + + private class BodyInsertTransaction implements PomTransaction{ + private TreeElement myChild; + private TreeElement myAnchor; + private TreeElement myNewElement; + private PomModel myModel; + private boolean myBeforeFlag; + private FileType myFileType ; + + public BodyInsertTransaction(PomModel model, TreeElement child, TreeElement anchor, boolean beforeFlag, FileType fileType) { + this.myModel = model; + this.myChild = child; + this.myAnchor = anchor; + this.myBeforeFlag = beforeFlag; + myFileType = fileType; + } + + public PomModelEvent run() throws IncorrectOperationException { + TreeElement treeElement; + if(myChild.getElementType() == XmlElementType.XML_TEXT){ + TreeElement left; + TreeElement right; + if(myBeforeFlag){ + left = myAnchor != null ? myAnchor.getTreePrev() : lastChild; + right = myAnchor; + } + else{ + left = myAnchor != null ? myAnchor : lastChild; + right = myAnchor != null ? myAnchor.getTreeNext() : null; + } + if(left.getElementType() == XmlElementType.XML_TEXT){ + ((XmlText)left).add((PsiElement)myChild); + myNewElement = left; + return null; + } + if(right != null && right.getElementType() == XmlElementType.XML_TEXT){ + ((XmlText)right).addBefore((PsiElement)myChild, (PsiElement)((XmlTextImpl)right).firstChild); + myNewElement = right; + return null; + } + } + + if (myAnchor == null) { + TreeElement anchor = expandTag(); + if(myChild.getElementType() == XmlElementType.XML_TAG){ + final XmlElementDescriptor parentDescriptor = getDescriptor(); + final XmlTag[] subTags = getSubTags(); + if (parentDescriptor != null && subTags.length > 0){ + final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(XmlTagImpl.this); + int subTagNum = -1; + for (int i = 0; i < childElementDescriptors.length; i++) { + final XmlElementDescriptor childElementDescriptor = childElementDescriptors[i]; + final String childElementName = childElementDescriptor.getName(); + while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) { + subTagNum++; + } + if (childElementName.equals(XmlChildRole.START_TAG_NAME_FINDER.findChild((CompositeElement)myChild).getText())) { + // insert child just after anchor + // insert into the position specified by index + if(subTagNum >= 0){ + final TreeElement subTag = (TreeElement)subTags[subTagNum]; + if(subTag.getTreeParent() != XmlTagImpl.this){ + // in entity + final XmlEntityRef entityRef = PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class); + throw new IncorrectOperationException("Can't insert subtag to entity! Entity reference text: " + entityRef.getText()); + } + treeElement = addInternalHack(myChild, myChild, subTag, Boolean.FALSE, myFileType); + } + else{ + final TreeElement child = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this); + treeElement = addInternalHack(myChild, myChild, child, Boolean.FALSE, myFileType); + } + myNewElement = treeElement; + return XmlTagChildAdd.createXmlTagChildAdd(myModel, XmlTagImpl.this, (XmlTagChild)SourceTreeToPsiMap.treeElementToPsi(treeElement)); + } + } + } + } + treeElement = addInternalHack(myChild, myChild, anchor, Boolean.TRUE, myFileType); + } + else { + treeElement = addInternalHack(myChild, myChild, myAnchor, Boolean.valueOf(myBeforeFlag), myFileType); + } + if(treeElement.getElementType() == XmlTokenType.XML_END_TAG_START){ + // whitespace add + treeElement = treeElement.getTreePrev(); + if(treeElement.getElementType() == XmlTokenType.XML_TAG_END){ + // empty tag + final XmlElement parent = getParent(); + if(parent instanceof XmlTag) + return XmlTagChildChanged.createXmlTagChildChanged(myModel, (XmlTag)parent, XmlTagImpl.this); + return XmlDocumentChanged.createXmlDocumentChanged(myModel, (XmlDocument)parent); + } + } + myNewElement = treeElement; + return XmlTagChildAdd.createXmlTagChildAdd(myModel, XmlTagImpl.this, (XmlTagChild)SourceTreeToPsiMap.treeElementToPsi(treeElement)); + } + + TreeElement getNewElement(){ + return myNewElement; + } + } + + private TreeElement addInternalHack(TreeElement first, + TreeElement last, + TreeElement anchor, + Boolean beforeFlag, + FileType fileType) { + if(first instanceof XmlTagChild && fileType == StdFileTypes.XHTML){ + if (beforeFlag == null || !beforeFlag.booleanValue()) ChangeUtil.addChildren(this, first, last.getTreeNext(), anchor.getTreeNext()); + else ChangeUtil.addChildren(this, first, last.getTreeNext(), anchor); + return first; + } + return super.addInternal(first, last, anchor, beforeFlag); + } + + public XmlElement getParent() { + return (XmlElement)super.getParent(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagValueImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagValueImpl.java new file mode 100644 index 00000000000..3b5b629250e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTagValueImpl.java @@ -0,0 +1,84 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.xml.*; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; +import java.util.ArrayList; + +public class XmlTagValueImpl implements XmlTagValue{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTagValueImpl"); + + private final XmlTag myTag; + private final XmlTagChild[] myElements; + private XmlText[] myTextElements = null; + private String myText = null; + private String myTrimmedText = null; + + public XmlTagValueImpl(XmlTagChild[] bodyElements, XmlTag tag) { + myTag = tag; + myElements = bodyElements; + } + + public XmlTagChild[] getChildren() { + return myElements; + } + + public XmlText[] getTextElements() { + if(myTextElements != null) return myTextElements; + final List textElements = new ArrayList(); + for (int i = 0; i < myElements.length; i++) { + final XmlTagChild element = myElements[i]; + if(element instanceof XmlText) textElements.add((XmlText)element); + } + return myTextElements = textElements.toArray(new XmlText[textElements.size()]); + } + + public String getText() { + if(myText != null) return myText; + final StringBuffer consolidatedText = new StringBuffer(); + for (int i = 0; i < myElements.length; i++) { + final XmlTagChild element = myElements[i]; + consolidatedText.append(element.getText()); + } + return consolidatedText.toString(); + } + + public TextRange getTextRange() { + if(myElements.length == 0){ + final TreeElement child = XmlChildRole.START_TAG_END_FINDER.findChild( (CompositeElement)myTag); + if(child != null) + return new TextRange(child.getTextOffset() + 1, child.getTextOffset() + 1); + return new TextRange(myTag.getTextRange().getEndOffset(), myTag.getTextRange().getEndOffset()); + } + return new TextRange(myElements[0].getTextRange().getStartOffset(), myElements[myElements.length - 1].getTextRange().getEndOffset()); + } + + public String getTrimmedText() { + if(myTrimmedText != null) return myTrimmedText; + + final StringBuffer consolidatedText = new StringBuffer(); + final XmlText[] textElements = getTextElements(); + for (int i = 0; i < textElements.length; i++) { + final XmlText textElement = textElements[i]; + consolidatedText.append(textElement.getValue()); + } + return myTrimmedText = consolidatedText.toString().trim(); + } + + public void setText(String value) { + try { + if(myElements.length > 0){ + myTag.deleteChildRange(myElements[0], myElements[myElements.length - 1]); + } + if(value != null && value.length() > 0) myTag.add(myTag.getManager().getElementFactory().createDisplayText(value)); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTextImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTextImpl.java new file mode 100644 index 00000000000..c3fc17ce025 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTextImpl.java @@ -0,0 +1,612 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.psi.xml.*; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.xml.aspect.XmlTextChanged; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.CharTable; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.xml.util.XmlTagTextUtil; +import com.intellij.pom.PomModel; +import com.intellij.pom.PomTransaction; +import com.intellij.pom.event.PomModelEvent; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +public class XmlTextImpl extends XmlElementImpl implements XmlText{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTextImpl"); + private String myDisplayText = null; + + public XmlTextImpl() { + super(XML_TEXT); + } + + public String toString() { + return "XmlText"; + } + + public XmlText split(int displayIndex) { + final int phyIndex = displayToPhysical(displayIndex); + final String text = getText(); + final int phyTextLength = text.length(); + if (phyIndex == 0 || phyIndex == phyTextLength) { + return this; + } + try { + setValue(text.substring(0, phyIndex)); + final XmlText element = getManager().getElementFactory().createDisplayText(text.substring(phyIndex)); + getParent().addAfter(element, this); + return element; + } catch (IncorrectOperationException e) { + LOG.error(e); + } + return null; + } + + private int[] myGaps = null; + + public String getValue() { + if(myDisplayText != null) return myDisplayText; + StringBuffer buffer = new StringBuffer(); + TreeElement child = firstChild; + final List gaps = new ArrayList(); + while(child != null){ + final int start = buffer.length(); + IElementType elementType = child.getElementType(); + if(elementType == XmlElementType.XML_CDATA){ + final CompositeElement cdata = (CompositeElement)child; + child = cdata.firstChild; + } + else if(elementType == XmlTokenType.XML_CHAR_ENTITY_REF){ + buffer.append(getChar(child.getText())); + } + else if(elementType == XmlTokenType.XML_WHITE_SPACE + || elementType == XmlTokenType.XML_DATA_CHARACTERS + || elementType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN){ + buffer.append(child.getText()); + } + int end = buffer.length(); + int originalLength = child.getTextLength(); + if(end - start != originalLength){ + gaps.add(new Integer(start)); + gaps.add(new Integer(originalLength - (end - start))); + } + final TreeElement next = child.getTreeNext(); + if(next == null && child.getTreeParent().getElementType() == XmlElementType.XML_CDATA) + child = child.getTreeParent().getTreeNext(); + else child = next; + } + myGaps = new int[gaps.size()]; + int index = 0; + final Iterator iterator = gaps.iterator(); + while (iterator.hasNext()) { + final Integer integer = iterator.next(); + myGaps[index++] = integer.intValue(); + } + + return myDisplayText = buffer.toString(); + } + + private char getChar(String text) { + //LOG.assertTrue(text.startsWith("&#") && text.endsWith(";")); + if(text.charAt(1) != '#'){ + text = text.substring(1, text.length() - 1); + return XmlTagTextUtil.getCharacterByEntityName(text).charValue(); + } + text = text.substring(2, text.length() - 1); + int code; + if (text.startsWith("x")) { + text = text.substring(1); + code = Integer.parseInt(text, 16); + } + else { + code = Integer.parseInt(text); + } + return (char) code; + } + + public int physicalToDisplay(int offset) { + getValue(); + if(myGaps.length == 0) return offset; + int gapIndex = 0; + int displayIndex = 0; + int physicalOffset = 0; + + while(physicalOffset < offset){ + if(displayIndex == getGapStartOffset(gapIndex)){ + final int gap = getGap(gapIndex); + physicalOffset += gap; + gapIndex++; + } + else { + physicalOffset++; + displayIndex++; + } + } + return displayIndex; + } + + public int displayToPhysical(int displayIndex) { + getValue(); + if(myGaps.length == 0) return displayIndex; + int gapIndex = 0; + int displayOffset = 0; + int physicalOffset = 0; + while(displayOffset <= displayIndex){ + if(displayOffset > getGapStartOffset(gapIndex)){ + final int gap = getGap(gapIndex); + physicalOffset += gap; + gapIndex++; + } + else if(displayOffset < displayIndex){ + physicalOffset++; + displayOffset++; + } + else displayOffset++; + } + return physicalOffset; + } + + public void setValue(String s) throws IncorrectOperationException{ + final XmlTextImpl element = (XmlTextImpl)getManager().getElementFactory().createDisplayText(s); + replace(element); + } + + public XmlElement insertAtOffset(final XmlElement element, int physicalOffset) throws IncorrectOperationException{ + final PsiElement elementAt = findElementAt(physicalOffset); + final int localOffset; + if(elementAt != null) + localOffset = physicalOffset - elementAt.getStartOffsetInParent(); + else + localOffset = element.getTextLength(); + final PomModel model = getManager().getProject().getModel(); + final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + final TreeElement[] retHolder = new TreeElement[1]; + final TreeElement insertedElement = SourceTreeToPsiMap.psiElementToTree(element); + final String oldText = getText(); + final TreeElement second; + if(elementAt != null){ + final TreeElement treeElement = SourceTreeToPsiMap.psiElementToTree(elementAt); + second = split((LeafElement)treeElement, localOffset); + } + else second = null; + + + if(element instanceof XmlTagChild){ + final XmlElement parent = getParent(); + if(second != null){ + final XmlText xmlText = getManager().getElementFactory().createTagFromText(" ").getValue().getTextElements()[0]; + final CompositeElement compositeElement = (CompositeElement)SourceTreeToPsiMap.psiElementToTree(xmlText); + TreeUtil.removeRange(compositeElement.firstChild, null); + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + TreeElement current = second; + while(current != null){ + final TreeElement next = current.getTreeNext(); + ChangeUtil.removeChild(XmlTextImpl.this, current); + ChangeUtil.addChild(compositeElement, current, null); + current = next; + } + return XmlTextChanged.createXmlTextChanged(model, XmlTextImpl.this, oldText); + } + }, aspect); + + XmlElement xmlElement = (XmlElement)parent.addAfter(element, this); + parent.addAfter(xmlText, xmlElement); + return xmlElement; + } + else{ + return (XmlElement)parent.addAfter(element, this); + } + } + else{ + model.runTransaction(new PomTransaction() { + public PomModelEvent run() { + retHolder[0] = addInternal(insertedElement, insertedElement, retHolder[0], Boolean.TRUE); + return XmlTextChanged.createXmlTextChanged(model, XmlTextImpl.this, oldText); + } + }, aspect); + } + return (XmlElement)SourceTreeToPsiMap.treeElementToPsi(retHolder[0]); + } + +// public XmlElement insertAtOffset(final XmlElement element, int physicalOffset) throws IncorrectOperationException{ +// final PomModel model = getManager().getProject().getModel(); +// final XmlAspect aspect = model.getModelAspect(XmlAspect.class); +// final int displayOffset = physicalToDisplay(physicalOffset); +// final String value = getValue(); +// final String part1, part2; +// if(element instanceof XmlText){ +// part1 = value.substring(0, displayOffset) + ((XmlText) element).getValue() + value.substring(displayOffset); +// part2 = null; +// } +// else{ +// part1 = value.substring(0, displayOffset); +// part2 = value.substring(displayOffset); +// } +// if(part2 != null){ +// if(part1.length() > 0){ +// setValue(part1); +// final PsiElement elementCopy = getParent().addAfter(element, this); +// if(part2.length() > 0){ +// final FileElement treeElement = new DummyHolder(null, null, SharedImplUtil.findCharTableByTree(this)).getTreeElement(); +// final XmlTextImpl newText = new XmlTextImpl(); +// TreeUtil.addChildren(treeElement, newText); +// TreeUtil.addChildren(newText, createElementsByDisplayText(part2, getPolicy())); +// getParent().addAfter(newText, elementCopy); +// } +// } +// else { +// getParent().addBefore(element, this); +// } +// } +// else{ +// setValue(part1); +// } +// return this; +// } + + private int getPolicy() { + return CDATA_ON_TEXT; + } + + private static LeafElement split(LeafElement element, int offset) throws IncorrectOperationException{ + final CharTable table = SharedImplUtil.findCharTableByTree(element); + int textLength = element.getTextLength(table); + if(textLength < offset) throw new ArrayIndexOutOfBoundsException(offset); + if(offset == 0 || textLength == offset) return element; + if(element.getElementType() != XmlTokenType.XML_DATA_CHARACTERS + && element.getElementType() != XmlTokenType.XML_WHITE_SPACE) + throw new IncorrectOperationException("Element " + element.getElementType() + " can not be split!"); + final char[] buffer = new char[textLength]; + element.copyTo(buffer, 0); + final LeafElement firstPart = Factory.createSingleLeafElement(element.getElementType(), buffer, 0, offset, table, null); + final LeafElement secondPart = Factory.createSingleLeafElement(element.getElementType(), buffer, offset, buffer.length, table, null); + final CompositeElement parent = element.getTreeParent(); + ChangeUtil.replaceChild(parent, element, firstPart); + ChangeUtil.addChild(parent, secondPart, firstPart.getTreeNext()); + return secondPart; + } + + public void insertText(String text, int displayOffset) throws IncorrectOperationException{ + final XmlText displayText = getManager().getElementFactory().createDisplayText(text); + final int phyOffset = displayToPhysical(displayOffset); + insertAtOffset(displayText, phyOffset); + } + + public void removeText(int displayStart, int displayEnd) { + final int start = displayToPhysical(displayStart); + final int end = displayToPhysical(displayEnd); + final PomModel model = getProject().getModel(); + final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + final CharTable table = SharedImplUtil.findCharTableByTree(this); + if(start == end) return; + + try { + model.runTransaction(new PomTransaction() { + public PomModelEvent run() throws IncorrectOperationException { + final String oldText = getText(); + + final LeafElement firstAffectedLeaf = findLeafElementAt(start); + final LeafElement lastAffectedLeaf; + final int lastAffectedLeafOffset; + final int startOffsetInStartToken = start - firstAffectedLeaf.getStartOffsetInParent(); + { + // remove elements inside the affected area + LeafElement current = firstAffectedLeaf; + int endOffset = current.getStartOffsetInParent(); + + while(current != null && (endOffset += current.getTextLength(table)) <= end){ + final LeafElement toDelete = current; + current = (LeafElement)current.getTreeNext(); + if(toDelete != firstAffectedLeaf) ChangeUtil.removeChild(XmlTextImpl.this, toDelete); + } + lastAffectedLeaf = current; + lastAffectedLeafOffset = endOffset - (current != null ? current.getTextLength(table) : 0); + } + + LeafElement tokenToChange; + int deletedAreaStartOffset = 0; + int deletedAreaEndOffset = 0; + if(lastAffectedLeafOffset < end && lastAffectedLeaf != firstAffectedLeaf){ + // merging tokens + final LeafElement merged = mergeElements(firstAffectedLeaf, lastAffectedLeaf, table); + if(merged == null){ + ChangeUtil.removeChild(XmlTextImpl.this, split(firstAffectedLeaf, startOffsetInStartToken)); + ChangeUtil.removeChild(XmlTextImpl.this, split(lastAffectedLeaf, end - lastAffectedLeafOffset).getTreePrev()); + } + else{ + ChangeUtil.replaceAll(new LeafElement[]{firstAffectedLeaf, lastAffectedLeaf}, merged); + deletedAreaStartOffset = startOffsetInStartToken; + deletedAreaEndOffset = end - lastAffectedLeafOffset + firstAffectedLeaf.getTextLength(table) - startOffsetInStartToken; + } + tokenToChange = merged; + } + else{ + // replacing first token + tokenToChange = firstAffectedLeaf; + final int textLength = firstAffectedLeaf.getTextLength(table); + deletedAreaStartOffset = startOffsetInStartToken; + deletedAreaEndOffset = Math.min(end - firstAffectedLeaf.getStartOffsetInParent(), textLength); + } + + if(tokenToChange != null){ + final int textLength = tokenToChange.getTextLength(table); + if(deletedAreaStartOffset > 0 || deletedAreaEndOffset < textLength) { + String text = tokenToChange.getText(table); + text = text.substring(0, deletedAreaStartOffset) + text.substring(deletedAreaEndOffset); + final LeafElement newLeaf = Factory.createSingleLeafElement(firstAffectedLeaf.getElementType(), + text.toCharArray(), 0, text.length(), table, null); + ChangeUtil.replaceChild(XmlTextImpl.this, tokenToChange, newLeaf); + } + else{ + final TreeElement treeNext = tokenToChange.getTreeNext(); + final TreeElement treePrev = tokenToChange.getTreePrev(); + final LeafElement merged = mergeElements((LeafElement)treePrev, (LeafElement)treeNext, table); + ChangeUtil.removeChild(XmlTextImpl.this, tokenToChange); + if(merged != null) ChangeUtil.replaceAll(new LeafElement[]{(LeafElement)treePrev, (LeafElement)treeNext}, merged); + } + } + + return XmlTextChanged.createXmlTextChanged(model, XmlTextImpl.this, oldText); + } + }, aspect); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + public XmlElement getParent() { + return (XmlElement)super.getParent(); + } + + private int getGapStartOffset(int gapIndex){ + int index = gapIndex * 2; + return index < myGaps.length ? myGaps[index] : Integer.MAX_VALUE; + } + + private int getGap(int gapIndex){ + return myGaps[gapIndex * 2 + 1]; + } + + public XmlTag getParentTag() { + final XmlElement parent = getParent(); + if(parent instanceof XmlTag) return (XmlTag)parent; + return null; + } + + public XmlTagChild getNextSiblingInTag() { + PsiElement nextSibling = getNextSibling(); + if(nextSibling instanceof XmlTagChild) return (XmlTagChild)nextSibling; + return null; + } + + public XmlTagChild getPrevSiblingInTag() { + PsiElement prevSibling = getPrevSibling(); + if(prevSibling instanceof XmlTagChild) return (XmlTagChild)prevSibling; + return null; + } + + public TreeElement addInternal(TreeElement first, TreeElement last, TreeElement anchor, Boolean beforeB) { + //ChameleonTransforming.transformChildren(this); + TreeElement firstAppended = null; + boolean before = beforeB != null ? beforeB.booleanValue() : true; + try{ + do { + if (firstAppended == null) { + firstAppended = addInternal(first, anchor, before); + anchor = firstAppended; + } + else anchor = addInternal(first, anchor, false); + } + while (first != last && (first = first.getTreeNext()) != null); + } + catch(IncorrectOperationException ioe){} + return firstAppended; + } + + public TreeElement addInternal(final TreeElement child, final TreeElement anchor, final boolean before) throws IncorrectOperationException{ + final PomModel model = getProject().getModel(); + final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + final TreeElement[] retHolder = new TreeElement[1]; + if (child.getElementType() == XmlElementType.XML_TEXT) { + if(child.getTextLength() == 0) return this; + final XmlTextImpl text = (XmlTextImpl)child; + model.runTransaction(new PomTransaction() { + public PomModelEvent run(){ + final String oldText = getText(); + TreeElement childBefore = anchor != null ? (before ? anchor.getTreePrev() : anchor) : lastChild; + if(childBefore != null && childBefore.getElementType() == text.firstChild.getElementType()){ + final LeafElement newText = mergeElements((LeafElement)childBefore, (LeafElement)text.firstChild, SharedImplUtil.findCharTableByTree(XmlTextImpl.this)); + if(newText != null){ + replaceChildInternal(childBefore, newText); + if(text.lastChild != text.firstChild){ + addChildren(XmlTextImpl.this, text.firstChild.getTreeNext(), null, anchor, before); + } + } + else addChildren(XmlTextImpl.this, text.firstChild, null, anchor, before); + } + else{ + TreeElement childAfter = anchor != null ? (before ? anchor : anchor.getTreeNext()) : lastChild; + if(childAfter != null && childAfter.getElementType() == text.firstChild.getElementType()){ + final LeafElement newText = mergeElements((LeafElement)text.firstChild, (LeafElement)childAfter, SharedImplUtil.findCharTableByTree(XmlTextImpl.this)); + if(newText != null){ + replaceChildInternal(childAfter, newText); + if(text.lastChild != text.firstChild){ + addChildren(XmlTextImpl.this, text.firstChild.getTreeNext(), null, anchor, before); + } + } + else addChildren(XmlTextImpl.this, text.firstChild, null, anchor, before); + } + + addChildren(XmlTextImpl.this, text.firstChild, null, anchor, before); + } + + retHolder[0] = XmlTextImpl.this; + return XmlTextChanged.createXmlTextChanged(model, XmlTextImpl.this, oldText); + } + }, aspect); + } + else{ + model.runTransaction(new PomTransaction() { + public PomModelEvent run() { + final String oldText = getText(); + final TreeElement treeElement = addChildren(XmlTextImpl.this, child, child.getTreeNext(), anchor, before); + retHolder[0] = treeElement; + return XmlTextChanged.createXmlTextChanged(model, XmlTextImpl.this, oldText); + } + }, aspect); + } + return retHolder[0]; + } + + private LeafElement mergeElements(final LeafElement one, LeafElement two, CharTable table) { + if(one == null || two == null || one.getElementType() != two.getElementType()) return null; + if(one.getElementType() == XmlTokenType.XML_DATA_CHARACTERS){ + final char[] buffer = new char[one.getTextLength() + two.getTextLength()]; + two.copyTo(buffer, one.copyTo(buffer, 0)); + return Factory.createSingleLeafElement(one.getElementType(), buffer, 0, buffer.length, table, null); + } + else if(one.getElementType() == XmlTokenType.XML_WHITE_SPACE){ + return (LeafElement)ChangeUtil.copyElement(two, SharedImplUtil.findCharTableByTree(this)); + //final LeafElement prevLeaf = ParseUtil.prevLeaf(one, null); + //final LeafElement nextLeaf = ParseUtil.nextLeaf(two, null); + //final PsiFile file = getContainingFile(); + //final FileType fileType = file.getFileType(); + // + //final Helper helper = new Helper(fileType, getManager().getProject()); + //helper.getPrevWhitespace(nextLeaf); + } + return null; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlText(this); + } + + public void clearCaches() { + super.clearCaches(); + myDisplayText = null; + myGaps = null; + } + + private static TreeElement addChildren(final XmlTextImpl xmlText, + final TreeElement firstChild, + final TreeElement lastChild, + final TreeElement anchor, + final boolean isBefore) { + if(isBefore){ + ChangeUtil.addChildren(xmlText, firstChild, lastChild, anchor); + } + else{ + ChangeUtil.addChildren(xmlText, firstChild, lastChild, anchor.getTreeNext()); + } + return firstChild; + } + + public static final int CDATA_ON_TEXT = 0; + public static final int ENCODE_SYMS = 1; + + public static TreeElement createElementsByDisplayText(String displayText, int policy){ + if(!toCode(displayText)) + return Factory.createSingleLeafElement( + XmlTokenType.XML_DATA_CHARACTERS, + displayText.toCharArray(), + 0, + displayText.length(), + null, null); + final FileElement dummyParent = new DummyHolder(null, null).getTreeElement(); + if(policy == CDATA_ON_TEXT) { + TreeUtil.addChildren( + dummyParent, + Factory.createLeafElement( + XmlTokenType.XML_CDATA_START, + "".toCharArray(), + 0, 3, -1, + dummyParent.getCharTable())); + } + else if(policy == ENCODE_SYMS){ + int sectionStartOffset = 0; + int offset = 0; + while(offset < displayText.length()){ + if(toCode(displayText.charAt(offset))){ + final String plainSection = displayText.substring(sectionStartOffset, offset); + if(plainSection.length() > 0) + TreeUtil.addChildren( + dummyParent, + Factory.createLeafElement( + XmlTokenType.XML_DATA_CHARACTERS, + plainSection.toCharArray(), + 0, plainSection.length(), -1, + dummyParent.getCharTable())); + TreeUtil.addChildren(dummyParent, createCharEntity(displayText.charAt(offset), dummyParent.getCharTable())); + } + } + } + + return dummyParent.firstChild; + } + + private static TreeElement createCharEntity(char ch, CharTable charTable) { + switch(ch){ + case '<': + return Factory.createLeafElement( + XmlTokenType.XML_CHAR_ENTITY_REF, + "<".toCharArray(), + 0, 4, -1, + charTable); + case '>': + return Factory.createLeafElement( + XmlTokenType.XML_CHAR_ENTITY_REF, + ">".toCharArray(), + 0, 4, -1, + charTable); + case '&': + return Factory.createLeafElement( + XmlTokenType.XML_CHAR_ENTITY_REF, + "&".toCharArray(), + 0, 5, -1, + charTable); + default: + final String charEncoding = "&#" + (int) ch + ";"; + return Factory.createLeafElement( + XmlTokenType.XML_CHAR_ENTITY_REF, + charEncoding.toCharArray(), + 0, charEncoding.length(), -1, + charTable); + } + } + + public static final boolean toCode(String str){ + for(int i = 0; i < str.length(); i++){ + if(toCode(str.charAt(i))) return true; + } + return false; + } + + public static final boolean toCode(char ch) { + return "<&>".indexOf(ch) >= 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTokenImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTokenImpl.java new file mode 100644 index 00000000000..c760394660b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/XmlTokenImpl.java @@ -0,0 +1,56 @@ +package com.intellij.psi.impl.source.xml; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.xml.IDTDElementType; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.CharTable; +import com.intellij.xml.util.XmlUtil; + +/** + * @author ik + */ +public class XmlTokenImpl extends LeafPsiElement implements XmlToken { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTokenImpl"); + + public XmlTokenImpl(IElementType type, char[] buffer, int startOffset, int endOffset, int lexerState, CharTable table) { + super(type, buffer, startOffset, endOffset, lexerState, table); + } + + public boolean processElements(PsiElementProcessor processor, PsiElement place) { + return false; + } + + public void accept(PsiElementVisitor visitor) { + visitor.visitXmlToken(this); + } + + public String toString() { + if(getTokenType() instanceof IDTDElementType){ + return "DTDToken:" + getTokenType().toString(); + } + return "XmlToken:" + getTokenType().toString(); + } + +// Implementation specific + + public IElementType getTokenType() { + return getElementType(); + } + + public PsiReference[] getReferences() { + if (getElementType() == XmlTokenType.XML_DATA_CHARACTERS) { + return ResolveUtil.getReferencesFromProviders(this); + } else { + return super.getReferences(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/dtd/DTDElementType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/dtd/DTDElementType.java new file mode 100644 index 00000000000..3f32e22dcd6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/impl/source/xml/dtd/DTDElementType.java @@ -0,0 +1,39 @@ +package com.intellij.psi.impl.source.xml.dtd; + +import com.intellij.psi.tree.xml.IDTDElementType; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 18.08.2004 + * Time: 17:27:48 + * To change this template use File | Settings | File Templates. + */ +public interface DTDElementType { + IDTDElementType DTD_FILE = new IDTDElementType("DTD_FILE"); + IDTDElementType DTD_DOCUMENT = new IDTDElementType("DTD_DOCUMENT"); + IDTDElementType DTD_ELEMENT_DECL = new IDTDElementType("DTD_ELEMENT_DECL"); + IDTDElementType DTD_ATTLIST_DECL = new IDTDElementType("DTD_ATTLIST_DECL"); + IDTDElementType DTD_NOTATION_DECL = new IDTDElementType("DTD_NOTATION_DECL"); + IDTDElementType DTD_ENTITY_DECL = new IDTDElementType("DTD_ENTITY_DECL"); + + IDTDElementType DTD_ELEMENT_CONTENT_SPEC = new IDTDElementType("DTD_ELEMENT_CONTENT_SPEC"); + IDTDElementType DTD_GROUP = new IDTDElementType("DTD_GROUP"); + + IDTDElementType DTD_ATTR_DECL = new IDTDElementType("DTD_ATTR_DECL"); + IDTDElementType DTD_ENUMERATION = new IDTDElementType("DTD_ENUMERATION"); + IDTDElementType DTD_NOTATION = new IDTDElementType("DTD_NOTATION"); + + IDTDElementType DTD_ATTRIBUTE_VALUE = new IDTDElementType("DTD_ATTRIBUTE_VALUE"); + IDTDElementType DTD_NDATA = new IDTDElementType("DTD_NDATA"); + + IDTDElementType DTD_ENTITY_REF = new IDTDElementType("DTD_ENTITY_REF"); + IDTDElementType DTD_ENUMERATED_TYPE = new IDTDElementType("DTD_ENUMERATED_TYPE"); + IDTDElementType DTD_PROCESSING_INSTRUCTION = new IDTDElementType("DTD_PROCESSING_INSTRUCTION"); + IDTDElementType DTD_CDATA = new IDTDElementType("DTD_CDATA"); + IDTDElementType DTD_DTD_DECL = new IDTDElementType("DTD_DTD_DECL"); + IDTDElementType DTD_WHITE_SPACE_HOLDER = new IDTDElementType("DTD_WHITE_SPACE_HOLDER"); + IDTDElementType DTD_EXTERNAL_ID = new IDTDElementType("DTD_EXTERNAL_ID"); + + IDTDElementType DTD_COMMENT = new IDTDElementType("DTD_COMMENT"); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/ClassPresentationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/ClassPresentationUtil.java new file mode 100644 index 00000000000..bf3ff76b8b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/ClassPresentationUtil.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.psi.presentation.java; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.*; + +import javax.swing.*; + +public class ClassPresentationUtil { + public static String getNameForClass(PsiClass aClass, boolean qualified) { + if (aClass instanceof PsiAnonymousClass) { + return "Anonymous in " + getContextName(aClass, qualified); + } + else { + if (qualified){ + String qName = aClass.getQualifiedName(); + if (qName != null) return qName; + } + + String className = aClass.getName(); + String contextName = getContextName(aClass, qualified); + return contextName != null ? className + " in " + contextName : className; + } + } + + private static String getNameForElement(PsiElement element, boolean qualified) { + if (element instanceof PsiClass){ + return getNameForClass((PsiClass)element, qualified); + } + else if (element instanceof PsiMethod){ + PsiMethod method = (PsiMethod)element; + String methodName = method.getName(); + return methodName + "() in " + getContextName(method, qualified); + } + else if (element instanceof PsiJavaFile){ + return null; + } + else if (element instanceof PsiFile){ + return ((PsiFile)element).getName(); + } + else{ + return null; + } + } + + private static String getContextName(PsiElement element, boolean qualified) { + PsiElement parent = element instanceof PsiClass ? ((PsiClass)element).getScope() : element.getParent(); + while(true){ + String name = getNameForElement(parent, qualified); + if (name != null) return name; + if (parent instanceof PsiFile) return null; + parent = parent.getParent(); + } + } + + public static ItemPresentation getPresentation(final PsiClass psiClass) { + if (psiClass instanceof PsiAnonymousClass) return null; + return new ItemPresentation() { + public String getPresentableText() { + return getNameForClass(psiClass, false); + } + + public String getLocationString() { + PsiFile file = psiClass.getContainingFile(); + if (file instanceof PsiJavaFile) { + PsiJavaFile javaFile = (PsiJavaFile)file; + String packageName = javaFile.getPackageName(); + if (packageName.length() == 0) return null; + return "(" + packageName + ")"; + } + return null; + } + + public Icon getIcon(boolean open) { + return psiClass.getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS); + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/SymbolPresentationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/SymbolPresentationUtil.java new file mode 100644 index 00000000000..1bd2f1a9342 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/presentation/java/SymbolPresentationUtil.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.psi.presentation.java; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; + +import javax.swing.*; + +public class SymbolPresentationUtil { + public static String getSymbolPresentableText(PsiElement element) { + if (element instanceof PsiMethod){ + return PsiFormatUtil.formatMethod( + (PsiMethod)element, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + } + else{ + return ((PsiNamedElement)element).getName(); + } + } + + public static String getSymbolContainerText(PsiElement element) { + String result; + PsiElement container = element instanceof PsiClass ? ((PsiClass)element).getScope() : element.getParent(); + if (container instanceof PsiClass){ + String qName = ((PsiClass)container).getQualifiedName(); + if (qName != null){ + result = qName; + } + else{ + result = ((PsiClass)container).getName(); + } + } + else if (container instanceof PsiJavaFile){ + result = ((PsiJavaFile)container).getPackageName(); + } + else{//TODO: local classes + result = null; + } + + String text = result; + if (text == null || text.trim().length() == 0) return null; + return "(in " + text + ")"; + } + + public static ItemPresentation getMethodPresentation(final PsiMethod psiMethod) { + return new ItemPresentation() { + public String getPresentableText() { + return getSymbolPresentableText(psiMethod); + } + + public String getLocationString() { + return getSymbolContainerText(psiMethod); + } + + public Icon getIcon(boolean open) { + return psiMethod.getIcon(Iconable.ICON_FLAG_VISIBILITY); + } + }; + } + + public static ItemPresentation getFieldPresentation(final PsiField psiField) { + return new ItemPresentation() { + public String getPresentableText() { + return getSymbolPresentableText(psiField); + } + + public String getLocationString() { + return getSymbolContainerText(psiField); + } + + public Icon getIcon(boolean open) { + return psiField.getIcon(Iconable.ICON_FLAG_VISIBILITY); + } + }; + } + + public static ItemPresentation getVariablePresentation(final PsiVariable variable) { + return new ItemPresentation() { + public String getPresentableText() { + return PsiFormatUtil.formatVariable(variable, PsiFormatUtil.SHOW_TYPE, PsiSubstitutor.EMPTY); + } + + public String getLocationString() { + return ""; + } + + public Icon getIcon(boolean open) { + return variable.getIcon(Iconable.ICON_FLAG_OPEN); + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/BaseScopeProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/BaseScopeProcessor.java new file mode 100644 index 00000000000..a4c5d50628e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/BaseScopeProcessor.java @@ -0,0 +1,15 @@ +package com.intellij.psi.scope; + +public abstract class BaseScopeProcessor implements PsiScopeProcessor{ + + public T getHint(Class hintClass) { + if (hintClass.isAssignableFrom(this.getClass())){ + return (T)this; + } + else{ + return null; + } + } + + public void handleEvent(PsiScopeProcessor.Event event, Object associated){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/ElementClassHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/ElementClassHint.java new file mode 100644 index 00000000000..cc981d1a6a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/ElementClassHint.java @@ -0,0 +1,5 @@ +package com.intellij.psi.scope; + +public interface ElementClassHint { + boolean shouldProcess(Class elementClass); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/MethodProcessorSetupFailedException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/MethodProcessorSetupFailedException.java new file mode 100644 index 00000000000..d38def0ba42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/MethodProcessorSetupFailedException.java @@ -0,0 +1,14 @@ +package com.intellij.psi.scope; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 31.01.2003 + * Time: 20:17:26 + * To change this template use Options | File Templates. + */ +public class MethodProcessorSetupFailedException extends Exception{ + public MethodProcessorSetupFailedException(String message){ + super(message); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/NameHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/NameHint.java new file mode 100644 index 00000000000..4a8c28a7166 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/NameHint.java @@ -0,0 +1,5 @@ +package com.intellij.psi.scope; + +public interface NameHint { + String getName(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/PsiConflictResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/PsiConflictResolver.java new file mode 100644 index 00000000000..1c6f74570f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/PsiConflictResolver.java @@ -0,0 +1,17 @@ +package com.intellij.psi.scope; + +import com.intellij.psi.infos.CandidateInfo; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 31.03.2003 + * Time: 13:20:20 + * To change this template use Options | File Templates. + */ +public interface PsiConflictResolver { + CandidateInfo resolveConflict(List conflicts); + void handleProcessorEvent(PsiScopeProcessor.Event event, Object associatied); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/DuplicateConflictResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/DuplicateConflictResolver.java new file mode 100644 index 00000000000..97cd16f60fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/DuplicateConflictResolver.java @@ -0,0 +1,49 @@ +package com.intellij.psi.scope.conflictResolvers; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.HashMap; + +import java.util.List; +import java.util.Map; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 31.03.2003 + * Time: 17:21:42 + * To change this template use Options | File Templates. + */ +public class DuplicateConflictResolver implements PsiConflictResolver{ + public CandidateInfo resolveConflict(List conflicts){ + final Map uniqueItems = new HashMap(); + + Object[] elements = conflicts.toArray(); + for(int i = 0; i < elements.length; i++){ + final CandidateInfo info = ((CandidateInfo)elements[i]); + final PsiElement element = info.getElement(); + Object key; + if(element instanceof PsiMethod){ + key = ((PsiMethod)element).getSignature(info.getSubstitutor()); + } + else { + key = PsiUtil.getName(element); + } + + if(!uniqueItems.containsKey(key)){ + uniqueItems.put(key, element); + } + else{ + conflicts.remove(elements[i]); + } + } + if(uniqueItems.size() == 1) return conflicts.get(0); + return null; + } + + public void handleProcessorEvent(PsiScopeProcessor.Event event, Object associatied){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java new file mode 100644 index 00000000000..08e78f9d3bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -0,0 +1,253 @@ +package com.intellij.psi.scope.conflictResolvers; + +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.TypeConversionUtil; + +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 10.06.2003 + * Time: 19:41:51 + * To change this template use Options | File Templates. + */ +public class JavaMethodsConflictResolver implements PsiConflictResolver{ + private PsiExpressionList myArgumentsList; + + public JavaMethodsConflictResolver(PsiExpressionList list){ + myArgumentsList = list; + } + + public void setArgumentsList(PsiExpressionList argumentsList){ + myArgumentsList = argumentsList; + } + + public CandidateInfo resolveConflict(List conflicts){ + int conflictsCount = conflicts.size(); + if (conflictsCount <= 0) return null; + if (conflictsCount == 1) return conflicts.get(0); + if (conflictsCount > 1){ + final PsiExpression[] args = myArgumentsList.getExpressions(); + + int maxCheckLevel = -1; + int[] checkLevels = new int[conflictsCount]; + int index = 0; + Iterator iterator = conflicts.iterator(); + while (iterator.hasNext()) { + final MethodCandidateInfo method = (MethodCandidateInfo)iterator.next(); + final int level = getCheckLevel(method, args); + checkLevels[index++] = level; + maxCheckLevel = Math.max(maxCheckLevel, level); + } + + for(int i = conflictsCount - 1; i>= 0; i--){ + // check for level + if (checkLevels[i] < maxCheckLevel){ + conflicts.remove(i); + } + } + + conflictsCount = conflicts.size(); + if(conflictsCount == 1) return conflicts.get(0); + checkApplicability(conflicts); + + conflictsCount = conflicts.size(); + if(conflictsCount == 1) return conflicts.get(0); + CandidateInfo[] conflictsArray; + conflictsArray = conflicts.toArray(new CandidateInfo[conflictsCount]); +outer: + for(int i = 0; i < conflictsCount; i++){ + final CandidateInfo method = conflictsArray[i]; + iterator = conflicts.iterator(); + // check overloading + while(iterator.hasNext()){ + final CandidateInfo info = iterator.next(); + if(info == method) break; + // candidates should go in order of class hierarchy traversal + // in order for this to work + if(checkOverriding(method, info)){ + conflicts.remove(method); + continue outer; + } + } + + // Specifics + if (maxCheckLevel >= VISIBLE_AND_PARMS_COUNT){ + final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]); + + for(int j = 0; j < i; j++){ + final CandidateInfo conflict = newConflictsArray[j]; + if (conflict == method) break; + switch(isMoreSpecific((MethodCandidateInfo)method, (MethodCandidateInfo)conflict)){ + case Specifics.TRUE: + conflicts.remove(conflict); + break; + case Specifics.FALSE: + conflicts.remove(method); + continue; + case Specifics.CONFLICT: + break; + } + } + } + } + } + if (conflicts.size() == 1){ + return conflicts.get(0); + } + + return null; + } + + private void checkApplicability(List conflicts) { + boolean applicableFound = false; + for (int i = conflicts.size() - 1; i >= 0; i--) { + final MethodCandidateInfo info = (MethodCandidateInfo)conflicts.get(i); + final boolean applicable = info.isApplicable(); + if(applicableFound){ + if(!applicable) conflicts.remove(i); + } + else if(applicable){ + for(int k = conflicts.size() - 1; k > i; k--){ + conflicts.remove(k); + } + applicableFound = true; + } + } + } + + + private int getCheckLevel(MethodCandidateInfo method, PsiExpression[] args){ + boolean visible = method.isAccessible();// && !method.myStaticProblem; + boolean available = method.isStaticsScopeCorrect(); + boolean paramsCount = method.getElement().isVarArgs() || method.getElement().getParameterList().getParameters().length == args.length; + return (visible ? 1 : 0) << 3 | (available ? 1 : 0) << 2 | (paramsCount ? 1 : 0) << 1; + } + + private final int VISIBLE_AND_PARMS_COUNT = 14; + + private final class Specifics { + public static final int FALSE = 0; + public static final int TRUE = 1; + public static final int CONFLICT = 2; + } + + private boolean checkOverriding(final CandidateInfo one, final CandidateInfo two){ + final PsiMethod method1 = (PsiMethod)one.getElement(); + final PsiMethod method2 = (PsiMethod)two.getElement(); + if (method1 != method2 && method1.getContainingClass() == method2.getContainingClass()) return false; + final PsiParameter[] params1 = method1.getParameterList().getParameters(); + final PsiParameter[] params2 = method2.getParameterList().getParameters(); + if(params1.length != params2.length) return false; + for(int i = 0; i < params1.length; i++){ + final PsiType type1 = one.getSubstitutor().substitute(params1[i].getType()); + final PsiType type2 = two.getSubstitutor().substitute(params2[i].getType()); + if (type1 == null || !type1.equals(type2)) { + return false; + } + } + return true; + } + + private int isMoreSpecific(final MethodCandidateInfo info1, final MethodCandidateInfo info2) { + PsiMethod method1 = info1.getElement(); + PsiMethod method2 = info2.getElement(); + final PsiClass class1 = method1.getContainingClass(); + final PsiClass class2 = method2.getContainingClass(); + Boolean isMoreSpecific = null; + + final PsiParameter[] params1 = method1.getParameterList().getParameters(); + final PsiParameter[] params2 = method2.getParameterList().getParameters(); + + PsiExpression[] args = myArgumentsList.getExpressions(); + + for(int i = 0; i < args.length; i++){ + if (i >= params1.length || i >= params2.length) break; + + boolean varArgs1 = params1[i].isVarArgs(); + boolean varArgs2 = params2[i].isVarArgs(); + if (!varArgs1 && varArgs2) return Specifics.TRUE; + if (varArgs1 && !varArgs2) return Specifics.FALSE; + + final PsiType type1 = info1.getSubstitutor().substitute(params1[i].getType()); + final PsiType type2 = info2.getSubstitutor().substitute(params2[i].getType()); + + final PsiType argType = args[i].getType(); + Boolean lessBoxing = isLessBoxing(argType, type1, type2); + if (lessBoxing != null) { + if (isMoreSpecific != null && !lessBoxing.equals(isMoreSpecific)) return Specifics.CONFLICT; + isMoreSpecific = lessBoxing; + continue; + } + + final boolean assignable2From1 = type1 != null && type2 != null && type2.isAssignableFrom(type1); + final boolean assignable1From2 = type1 != null && type2 != null && type1.isAssignableFrom(type2); + if (assignable1From2 && assignable2From1) { + //prefer less generic candidate + PsiType erased1 = TypeConversionUtil.erasure(params1[i].getType()); + PsiType erased2 = TypeConversionUtil.erasure(params2[i].getType()); + if (!erased2.isAssignableFrom(erased1)) { + if (isMoreSpecific == Boolean.TRUE) return Specifics.CONFLICT; + isMoreSpecific = Boolean.FALSE; + } + if (!erased1.isAssignableFrom(erased2)) { + if (isMoreSpecific == Boolean.FALSE) return Specifics.CONFLICT; + isMoreSpecific = Boolean.TRUE; + } + continue; + } + else if (assignable1From2){ + if (isMoreSpecific == Boolean.TRUE) return Specifics.CONFLICT; + isMoreSpecific = Boolean.FALSE; + } + else if (assignable2From1){ + if (isMoreSpecific == Boolean.FALSE) return Specifics.CONFLICT; + isMoreSpecific = Boolean.TRUE; + } + else{ + return Specifics.CONFLICT; + } + } + + if (isMoreSpecific == null) { + if (method1.isVarArgs() && !method2.isVarArgs()) return Specifics.FALSE; + if (method2.isVarArgs() && !method1.isVarArgs()) return Specifics.TRUE; + } + + if (isMoreSpecific == null){ + if (class1 != class2){ + if (class2.isInheritor(class1, true) + || class1.isInterface() && !class2.isInterface()){ + isMoreSpecific = Boolean.FALSE; + } + else if (class1.isInheritor(class2, true) + || class2.isInterface()){ + isMoreSpecific = Boolean.TRUE; + } + } + } + if (isMoreSpecific == null){ + return Specifics.CONFLICT; + } + + return isMoreSpecific.booleanValue() ? Specifics.TRUE : Specifics.FALSE; + } + + private Boolean isLessBoxing(PsiType argType, PsiType type1, PsiType type2) { + if (argType == null) return null; + final boolean boxing1 = TypeConversionUtil.boxingConversionApplicable(type1, argType); + final boolean boxing2 = TypeConversionUtil.boxingConversionApplicable(type2, argType); + if (boxing1 == boxing2) return null; + if (boxing1) return Boolean.FALSE; + return Boolean.TRUE; + } + + public void handleProcessorEvent(PsiScopeProcessor.Event event, Object associatied){} + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaVariableConflictResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaVariableConflictResolver.java new file mode 100644 index 00000000000..19685bfaed7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/conflictResolvers/JavaVariableConflictResolver.java @@ -0,0 +1,103 @@ +package com.intellij.psi.scope.conflictResolvers; + +import com.intellij.aspects.psi.PsiIntertypeField; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.PsiScopeProcessor; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 10.06.2003 + * Time: 16:36:05 + * To change this template use Options | File Templates. + */ +public class JavaVariableConflictResolver implements PsiConflictResolver{ + public CandidateInfo resolveConflict(List conflicts){ + final int size = conflicts.size(); + if(size == 1){ + return (CandidateInfo) conflicts.get(0); + } + if(size > 0){ + final CandidateInfo[] uncheckedResult = (CandidateInfo[])conflicts.toArray(new CandidateInfo[size]); + CandidateInfo currentResult = uncheckedResult[0]; + + if(currentResult.getElement() instanceof PsiField){ + for(int i = 1; i < uncheckedResult.length; i++){ + //TODO[ik]: Handle introduced fields properly. + final CandidateInfo candidate = uncheckedResult[i]; + if(currentResult == candidate || currentResult.getElement() == candidate.getElement()) continue; + if(candidate.getElement() == null || candidate.getElement() instanceof PsiIntertypeField) continue; + + if (!(candidate.getElement() instanceof PsiField)) { + if(candidate.getElement() instanceof PsiLocalVariable) { + return candidate; + } + else { + if (!currentResult.isAccessible()) return candidate; + conflicts.remove(candidate); + continue; + } + } + + final PsiClass newClass = ((PsiField)candidate.getElement()).getContainingClass(); + final PsiClass oldClass = ((PsiField)currentResult.getElement()).getContainingClass(); + + // Hack for JSP + if(newClass == null && candidate.getElement().getContainingFile() instanceof JspFile){ + conflicts.remove(currentResult); + currentResult = candidate; + } + + if(oldClass == null && currentResult.getElement().getContainingFile() instanceof JspFile){ + conflicts.remove(candidate); + continue; + } + + if(newClass.isInheritor(oldClass, true)){ + // current is better + conflicts.remove(currentResult); + currentResult = candidate; + } + else if(oldClass.isInheritor(newClass, true)){ + // current is worse + conflicts.remove(candidate); + continue; + } + else{ + if(!candidate.isAccessible()){ + conflicts.remove(candidate); + continue; + } + if(!currentResult.isAccessible()){ + conflicts.remove(currentResult); + currentResult = candidate; + continue; + } + + return null; + } + if(!candidate.isAccessible()){ + conflicts.remove(candidate); + continue; + } + if(!currentResult.isAccessible()){ + conflicts.remove(currentResult); + currentResult = candidate; + continue; + } + } + } + return currentResult; + } + return null; + } + + public void handleProcessorEvent(PsiScopeProcessor.Event event, Object associatied){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/ConflictFilterProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/ConflictFilterProcessor.java new file mode 100644 index 00000000000..d04d4de7eca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/ConflictFilterProcessor.java @@ -0,0 +1,109 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.util.PsiUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 31.03.2003 + * Time: 14:46:31 + * To change this template use Options | File Templates. + */ +public class ConflictFilterProcessor extends FilterScopeProcessor + implements NameHint{ + protected final PsiConflictResolver[] myResolvers; + private ResolveResult[] myCachedResult = null; + private String myName; + + public ConflictFilterProcessor(String name, PsiElement element, ElementFilter filter, PsiConflictResolver[] resolvers, List container){ + super(filter, element, container); + myResolvers = resolvers; + myName = name; + } + + public PsiConflictResolver[] getResolvers(){ + return myResolvers; + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor){ + if(myCachedResult != null){ + if (myCachedResult.length == 1) + if(!(myCachedResult[0].getElement() instanceof PsiField) || myCachedResult[0].isAccessible()) + return false; + } + + if(myName == null || PsiUtil.checkName(element, myName)){ + return super.execute(element, substitutor); + } + return true; + } + + protected void add(PsiElement element, PsiSubstitutor substitutor){ + add(new CandidateInfo(element, substitutor)); + } + + protected void add(CandidateInfo info){ + myCachedResult = null; + myResults.add(info); + } + + + public void handleEvent(Event event, Object associated){ + if(event == Event.CHANGE_LEVEL && myName != null){ + myCachedResult = getResult(); + } + for(int i = 0; i < myResolvers.length; i++){ + myResolvers[i].handleProcessorEvent(event, associated); + } + } + + public void forceResult(ResolveResult[] result){ + myCachedResult = result; + } + + + public ResolveResult[] getResult(){ + if(myCachedResult == null){ + CandidateInfo candidate; + + final List conflicts = new ArrayList((List)super.getResults()); + for(int i = 0; i < myResolvers.length; i++){ + if((candidate = myResolvers[i].resolveConflict(conflicts)) != null){ + conflicts.clear(); conflicts.add(candidate); + break; + } + } + myCachedResult = conflicts.toArray(new ResolveResult[conflicts.size()]); + } + + return myCachedResult; + } + + public String getName(){ + return myName; + } + + public void setName(String name){ + myName = name; + } + + public T getHint(Class hintClass) { + if (hintClass.equals(NameHint.class)){ + if(myName == null){ + return null; + } + } + return super.getHint(hintClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterElementProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterElementProcessor.java new file mode 100644 index 00000000000..da24c15d73a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterElementProcessor.java @@ -0,0 +1,64 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.search.PsiElementProcessor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 10.06.2003 + * Time: 14:33:56 + * To change this template use Options | File Templates. + */ +public class FilterElementProcessor extends PsiBaseElementProcessor{ + private final List myResults; + private final ElementFilter myFilter; + private final PsiElementProcessor myProcessor; + + public FilterElementProcessor(ElementFilter filter, PsiElementProcessor processor, List container){ + myFilter = filter; + myProcessor = processor; + myResults = container; + } + + + public FilterElementProcessor(ElementFilter filter, List container){ + this(filter, null, container); + } + + public FilterElementProcessor(ElementFilter filter, PsiElementProcessor proc){ + this(filter, proc, new ArrayList()); + } + + + public FilterElementProcessor(ElementFilter filter){ + this(filter, null, new ArrayList()); + } + + public boolean execute(PsiElement element){ + if(myFilter.isClassAcceptable(element.getClass()) && myFilter.isAcceptable(element, element.getParent())){ + if(myProcessor != null){ + return myProcessor.execute(element); + } + add(element); + } + return true; + } + + protected void add(PsiElement element){ + myResults.add(element); + } + + public List getResults(){ + return myResults; + } + + public boolean shouldProcess(Class elementClass){ + return myFilter.isClassAcceptable(elementClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterScopeProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterScopeProcessor.java new file mode 100644 index 00000000000..3f3b73cfb90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/FilterScopeProcessor.java @@ -0,0 +1,87 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.PsiScopeProcessor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 13.02.2003 + * Time: 15:21:27 + * To change this template use Options | File Templates. + */ +public class FilterScopeProcessor extends BaseScopeProcessor + implements ElementClassHint{ + private final PsiElement myElement; + protected final List myResults; + private PsiElement myCurrentDeclarationHolder; + private final ElementFilter myFilter; + private final PsiScopeProcessor myProcessor; + + public FilterScopeProcessor(ElementFilter filter, PsiElement element, PsiScopeProcessor processor, List container){ + myFilter = filter; + myElement = element; + myProcessor = processor; + myResults = container; + } + + + public FilterScopeProcessor(ElementFilter filter, PsiElement element, List container){ + this(filter, element, null, container); + } + + public FilterScopeProcessor(ElementFilter filter, PsiScopeProcessor processor){ + this(filter, null, processor, null); + } + + public FilterScopeProcessor(ElementFilter filter, PsiElement element, PsiScopeProcessor proc){ + this(filter, element, proc, new ArrayList()); + } + + + public FilterScopeProcessor(ElementFilter filter, PsiElement element){ + this(filter, element, null, new ArrayList()); + } + + public void handleEvent(Event event, Object associated){ + if(myProcessor != null){ + myProcessor.handleEvent(event, associated); + } + if(event == Event.SET_DECLARATION_HOLDER && associated instanceof PsiElement){ + myCurrentDeclarationHolder = (PsiElement)associated; + } + } + + public boolean execute(PsiElement element, PsiSubstitutor substitutor){ + if (myFilter.isAcceptable(element, myCurrentDeclarationHolder)){ + if(myProcessor != null){ + return myProcessor.execute(element, substitutor); + } + add(element, substitutor); + } + return true; + } + + public PsiElement getPlace(){ + return myElement; + } + + protected void add(PsiElement element, PsiSubstitutor substitutor){ + myResults.add(element); + } + + public List getResults(){ + return myResults; + } + + public boolean shouldProcess(Class elementClass){ + return myFilter.isClassAcceptable(elementClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java new file mode 100644 index 00000000000..a116570614c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java @@ -0,0 +1,53 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.*; +import com.intellij.psi.infos.MethodCandidateInfo; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.conflictResolvers.DuplicateConflictResolver; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 31.01.2003 + * Time: 19:31:12 + * To change this template use Options | File Templates. + */ +public class MethodCandidatesProcessor extends MethodsProcessor{ + private PsiElement myPlace; + + protected MethodCandidatesProcessor(PsiElement place, PsiConflictResolver[] resolvers, List container){ + super(null, resolvers, container); + myPlace = place; + } + + public MethodCandidatesProcessor(PsiElement place){ + super(null, new PsiConflictResolver[]{new DuplicateConflictResolver()}, new ArrayList()); + myPlace = place; + } + + public void add(PsiElement element, PsiSubstitutor substitutor) { + if (element instanceof PsiMethod){ + final PsiMethod currentMethod = (PsiMethod)element; + boolean staticProblem = isInStaticScope() && !currentMethod.hasModifierProperty(PsiModifier.STATIC); + + if ((!isConstructor() && getName().equals(currentMethod.getName())) + || (currentMethod.isConstructor() + && myAccessClass != null + && myAccessClass == currentMethod.getContainingClass())){ + add(new MethodCandidateInfo(currentMethod, substitutor, myPlace, currentMethod.isConstructor() ? null : myAccessClass, staticProblem, + getArgumentList(), myCurrentFileContext, getTypeArguments())); + } + } + } + + public CandidateInfo[] getCandidates(){ + final ResolveResult[] resolveResult = getResult(); + CandidateInfo[] infos = new CandidateInfo[resolveResult.length]; + System.arraycopy(resolveResult, 0, infos, 0, resolveResult.length); + return infos; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodResolverProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodResolverProcessor.java new file mode 100644 index 00000000000..5c25aa9d750 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodResolverProcessor.java @@ -0,0 +1,59 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.*; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiConflictResolver; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver; + +import java.util.ArrayList; + +public class MethodResolverProcessor extends MethodCandidatesProcessor implements NameHint, ElementClassHint, PsiResolverProcessor { + private boolean myStopAcceptingCandidates = false; + + public MethodResolverProcessor(PsiMethodCallExpression place){ + super(place, new PsiConflictResolver[]{new JavaMethodsConflictResolver(place.getArgumentList())}, new ArrayList()); + setArguments(place.getArgumentList()); + obtainTypeArguments(place); + } + + public MethodResolverProcessor(PsiClass classConstr, PsiExpressionList argumentList, PsiElement place) { + super(place, new PsiConflictResolver[]{new JavaMethodsConflictResolver(argumentList)}, new ArrayList()); + setIsConstructor(true); + setAccessClass(classConstr); + setArguments(argumentList); + } + + public MethodResolverProcessor(String name, PsiClass accessClass, PsiExpressionList argumentList, PsiElement place) { + super(place, new PsiConflictResolver[]{new JavaMethodsConflictResolver(argumentList)}, new ArrayList()); + + setName(name); + setIsConstructor(false); + setAccessClass(accessClass); + setArguments(argumentList); + } + + public void setArguments(PsiExpressionList argList){ + super.setArgumentList(argList); + // todo[dsl]: push type arguments thru to JavaMethodsConflictResolver + ((JavaMethodsConflictResolver)getResolvers()[0]).setArgumentsList(argList); + } + + public String getProcessorType(){ + return "method resolver"; + } + + public void handleEvent(Event event, Object associated) { + super.handleEvent(event, associated); + if (event == Event.CHANGE_LEVEL) { + myStopAcceptingCandidates = myResults.size() > 0; + } + } + + public void add(PsiElement element, PsiSubstitutor substitutor) { + if (!myStopAcceptingCandidates) { + super.add(element, substitutor); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodsProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodsProcessor.java new file mode 100644 index 00000000000..7d67e89244e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/MethodsProcessor.java @@ -0,0 +1,95 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.*; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiConflictResolver; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: igork + * Date: Dec 12, 2002 + * Time: 8:24:29 PM + * To change this template use Options | File Templates. + */ +public abstract class MethodsProcessor extends ConflictFilterProcessor { + private static final ClassFilter ourFilter = new ClassFilter(PsiMethod.class); + + private boolean myStaticScopeFlag = false; + private boolean myIsConstructor = false; + protected PsiElement myCurrentFileContext = null; + protected PsiClass myAccessClass = null; + private PsiExpressionList myArgumentList; + private PsiType[] myTypeArguments; + + + public PsiExpressionList getArgumentList() { + return myArgumentList; + } + + public void setArgumentList(PsiExpressionList argList) { + myArgumentList = argList; + } + + public void obtainTypeArguments(PsiCallExpression callExpression) { + final PsiType[] typeArguments = callExpression.getTypeArguments(); + if (typeArguments.length > 0) { + setTypeArguments(typeArguments); + } + } + + protected void setTypeArguments(PsiType[] typeParameters) { + myTypeArguments = typeParameters; + } + + public PsiType[] getTypeArguments() { + return myTypeArguments; + } + + public MethodsProcessor(PsiElement place, PsiConflictResolver[] resolvers, List container) { + super(null, place, ourFilter, resolvers, container); + } + + + public boolean isInStaticScope() { + return myStaticScopeFlag; + } + + public void handleEvent(Event event, Object associated) { + if (event == Event.START_STATIC) { + myStaticScopeFlag = true; + } + else if (Event.SET_CURRENT_FILE_CONTEXT.equals(event)) { + myCurrentFileContext = (PsiElement)associated; + } + for (int i = 0; i < myResolvers.length; i++) { + myResolvers[i].handleProcessorEvent(event, associated); + } + } + + public void setAccessClass(PsiClass accessClass) { + if (isConstructor() && accessClass instanceof PsiAnonymousClass) { + myAccessClass = ((PsiAnonymousClass)accessClass).getBaseClassType().resolve(); + } + else { + myAccessClass = accessClass; + } + if (isConstructor() && myAccessClass != null) { + setName(myAccessClass.getName()); + } + } + + public boolean isConstructor() { + return myIsConstructor; + } + + public void setIsConstructor(boolean myIsConstructor) { + this.myIsConstructor = myIsConstructor; + } + + public void forceAddResult(PsiMethod method) { + add(new CandidateInfo(method, PsiSubstitutor.EMPTY, false, false, myCurrentFileContext)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesNotProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesNotProcessor.java new file mode 100644 index 00000000000..1e1173d5996 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesNotProcessor.java @@ -0,0 +1,31 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.PsiVariable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: igork + * Date: Dec 12, 2002 + * Time: 4:09:53 PM + * To change this template use Options | File Templates. + */ +public class VariablesNotProcessor extends VariablesProcessor{ + private final PsiVariable myVariable; + + public VariablesNotProcessor(PsiVariable var, boolean staticSensitive, List list){ + super(staticSensitive, list); + myVariable = var; + } + + public VariablesNotProcessor(PsiVariable var, boolean staticSensitive){ + this(var, staticSensitive, new ArrayList()); + } + + protected boolean check(PsiVariable var, PsiSubstitutor substitutor) { + return var.getName() != null && var.getName().equals(myVariable.getName()) && !var.equals(myVariable); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesProcessor.java new file mode 100644 index 00000000000..bb49526b316 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/processor/VariablesProcessor.java @@ -0,0 +1,76 @@ +package com.intellij.psi.scope.processor; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.PsiVariable; +import com.intellij.psi.scope.BaseScopeProcessor; +import com.intellij.psi.scope.ElementClassHint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: igork + * Date: Dec 12, 2002 + * Time: 4:06:54 PM + * To change this template use Options | File Templates. + */ +public abstract class VariablesProcessor extends BaseScopeProcessor implements ElementClassHint { + private boolean myStaticScopeFlag = false; + private final boolean myStaticSensitiveFlag; + private final List myResultList; + + /** Collecting _all_ variables in scope */ + public VariablesProcessor(boolean staticSensitive){ + this(staticSensitive, new ArrayList()); + } + + /** Collecting _all_ variables in scope */ + public VariablesProcessor(boolean staticSensitive, List list){ + myStaticSensitiveFlag = staticSensitive; + myResultList = list; + } + + protected abstract boolean check(PsiVariable var, PsiSubstitutor substitutor); + + public boolean shouldProcess(Class elementClass) { + return PsiVariable.class.isAssignableFrom(elementClass); + } + + /** Always return true since we wanna get all vars in scope */ + public boolean execute(PsiElement pe, PsiSubstitutor substitutor){ + final boolean ret = true; + + if(pe instanceof PsiVariable){ + final PsiVariable pvar = (PsiVariable)pe; + if(!myStaticSensitiveFlag || (!myStaticScopeFlag || pvar.hasModifierProperty(PsiModifier.STATIC))){ + if(check(pvar, substitutor)){ + myResultList.add(pvar); + } + } + } + + return ret; + } + + public final void handleEvent(Event event, Object associated){ + if(event == Event.START_STATIC) + myStaticScopeFlag = true; + } + + public int size(){ + return myResultList.size(); + } + + public PsiVariable getResult(int i){ + return (PsiVariable)myResultList.get(i); + } + /** sometimes it is important to get results as array */ + public PsiVariable[] getResultsAsArray(){ + PsiVariable[] ret = new PsiVariable[myResultList.size()]; + myResultList.toArray(ret); + return ret; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/util/PsiScopesUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/util/PsiScopesUtil.java new file mode 100644 index 00000000000..721bbf994ba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/scope/util/PsiScopesUtil.java @@ -0,0 +1,346 @@ +/** + * Created by IntelliJ IDEA. + * User: igork + * Date: Nov 25, 2002 + * Time: 2:05:49 PM + * To change this template use Options | File Templates. + */ +package com.intellij.psi.scope.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiSubstitutorEx; +import com.intellij.psi.impl.source.resolve.ResolveUtil; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.meta.PsiMetaOwner; +import com.intellij.psi.scope.MethodProcessorSetupFailedException; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.MethodsProcessor; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.IncorrectOperationException; + +public class PsiScopesUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.scope.util.PsiScopesUtil"); + public static boolean treeWalkUp(PsiScopeProcessor processor, PsiElement entrance, PsiElement maxScope) { + PsiElement prevParent = entrance; + PsiElement scope = entrance; + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + + while(scope != null){ + if(scope instanceof PsiClass){ + processor.handleEvent(PsiScopeProcessor.Event.SET_CURRENT_FILE_CONTEXT, scope); + } + if (!processScope(scope, processor, substitutor, prevParent, entrance)) return false; + + if (scope instanceof PsiModifierListOwner && !(scope instanceof PsiParameter/* important for not loading tree! */)){ + PsiModifierList modifierList = ((PsiModifierListOwner)scope).getModifierList(); + if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC)){ + processor.handleEvent(PsiScopeProcessor.Event.START_STATIC, null); + } + } + if (scope == maxScope) break; + prevParent = scope; + scope = prevParent.getContext(); + processor.handleEvent(PsiScopeProcessor.Event.CHANGE_LEVEL, null); + } + + return true; + } + + public static boolean processScope(PsiElement scope, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place){ + if(scope instanceof PsiMetaOwner){ + final PsiMetaOwner owner = (PsiMetaOwner) scope; + if (!owner.isMetaEnough()) { + if (!scope.processDeclarations(processor, substitutor, lastParent, place)) return false; + } + + final PsiMetaData data = owner.getMetaData(); + if(data != null) { + if(!data.processDeclarations(scope, processor, substitutor, lastParent, place)) + return false; + } + + return true; + } + else{ + return scope.processDeclarations(processor, substitutor, lastParent, place); + } + } + + public static boolean walkChildrenScopes(PsiElement thisElement, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastParent, PsiElement place) { + PsiElement child = null; + if (lastParent != null && lastParent.getParent() == thisElement){ + child = lastParent.getPrevSibling(); + if (child == null) return true; // first element + } + + if (child == null){ + child = thisElement.getLastChild(); + } + + while(child != null){ + if (!processScope(child, processor, substitutor, null, place)) return false; + child = child.getPrevSibling(); + } + + return true; + } + + public static boolean resolveAndWalk(PsiScopeProcessor processor, PsiJavaCodeReferenceElement ref, PsiElement maxScope) { + return resolveAndWalk(processor, ref, maxScope, false); + } + + public static boolean resolveAndWalk(PsiScopeProcessor processor, PsiJavaCodeReferenceElement ref, PsiElement maxScope, boolean incompleteCode) { + final PsiElement qualifier = ref.getQualifier(); + final PsiElement classNameElement = ref.getReferenceNameElement(); + if(classNameElement == null) return true; + if (qualifier != null){ + // Composite expression + final PsiElementFactory factory = ref.getManager().getElementFactory(); + PsiElement target = null; + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + PsiType type = null; + if (qualifier instanceof PsiExpression || qualifier instanceof PsiJavaCodeReferenceElement){ + if(qualifier instanceof PsiExpression){ + type = ((PsiExpression)qualifier).getType(); + final ResolveResult result = PsiUtil.resolveGenericsClassInType(type); + target = result.getElement(); + substitutor = result.getSubstitutor(); + } + + if(type == null && qualifier instanceof PsiJavaCodeReferenceElement) { + // In case of class qualifier + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)qualifier; + final ResolveResult result = referenceElement.advancedResolve(incompleteCode); + target = result.getElement(); + substitutor = result.getSubstitutor(); + + if(target instanceof PsiVariable){ + type = substitutor.substitute(((PsiVariable) target).getType()); + if(type instanceof PsiClassType){ + final ResolveResult typeResult = ((PsiClassType) type).resolveGenerics(); + target = typeResult.getElement(); + substitutor = substitutor.merge(typeResult.getSubstitutor()); + } + else target = null; + } + else if(target instanceof PsiMethod){ + type = substitutor.substitute(((PsiMethod) target).getReturnType()); + if(type instanceof PsiClassType){ + final ResolveResult typeResult = ((PsiClassType) type).resolveGenerics(); + target = typeResult.getElement(); + substitutor = substitutor.merge(typeResult.getSubstitutor()); + } + else target = null; + } + else if(target instanceof PsiClass){ + type = factory.createType((PsiClass)target); + processor.handleEvent(PsiScopeProcessor.Event.START_STATIC, null); + } + final PsiType[] types = referenceElement.getTypeParameters(); + if(target instanceof PsiClass) { + substitutor = ((PsiSubstitutorEx)substitutor).inplacePutAll((PsiClass)target, types); + } + } + + if (type instanceof PsiArrayType){ + target = factory.getArrayClass(); + } + } + + if(target != null) return processScope(target, processor, substitutor, target, ref); + } + else{ + // simple expression -> trying to resolve variable or method + return treeWalkUp(processor, ref, maxScope); + } + + return true; + } + + public static void setupAndRunProcessor(MethodsProcessor processor, PsiCallExpression call, boolean dummyImplicitConstructor) + throws MethodProcessorSetupFailedException{ + if (call instanceof PsiMethodCallExpression){ + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)call; + final PsiJavaCodeReferenceElement ref = methodCall.getMethodExpression(); + + processor.setArgumentList(methodCall.getArgumentList()); + processor.obtainTypeArguments(methodCall); + if (!ref.isQualified() || ref.getReferenceNameElement() instanceof PsiKeyword){ + final PsiElement referenceNameElement = ref.getReferenceNameElement(); + if (referenceNameElement == null) return; + if (referenceNameElement instanceof PsiKeyword){ + final PsiKeyword keyword = (PsiKeyword)referenceNameElement; + + if (keyword.getTokenType() == JavaTokenType.THIS_KEYWORD){ + final PsiClass aClass = ResolveUtil.getContextClass(methodCall); + if (aClass == null) { + throw new MethodProcessorSetupFailedException("Cant resolve class for this expression"); + } + + processor.setIsConstructor(true); + processor.setAccessClass(aClass); + processScope(aClass, processor, PsiSubstitutor.EMPTY, null, call); + + if (dummyImplicitConstructor){ + processDummyConstructor(processor, aClass); + } + } + else if (keyword.getTokenType() == JavaTokenType.SUPER_KEYWORD){ + PsiClass aClass = ResolveUtil.getContextClass(methodCall); + if (aClass == null) { + throw new MethodProcessorSetupFailedException("Cant resolve class for super expression"); + } + + final PsiClass superClass = aClass.getSuperClass(); + if (superClass != null) { //null for java.lang.Object only + PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); + LOG.assertTrue(substitutor != null); + processor.setIsConstructor(true); + processor.setAccessClass(superClass); + processScope(superClass, processor, substitutor, null, call); + + if (dummyImplicitConstructor) processDummyConstructor(processor, superClass); + } + } + else{ + LOG.assertTrue(false, "Unknown name element " + referenceNameElement + " in reference " + ref.getText() + "(" + ref + ")"); + } + } + else if (referenceNameElement instanceof PsiIdentifier){ + processor.setIsConstructor(false); + processor.setName(referenceNameElement.getText()); + processor.setAccessClass(null); + PsiScopesUtil.resolveAndWalk(processor, ref, null); + } + else{ + LOG.assertTrue(false, "Unknown name element " + referenceNameElement + " in reference " + ref.getText() + "(" + ref + ")"); + } + } + else{ + // Complex expression + final PsiElement referenceName = methodCall.getMethodExpression().getReferenceNameElement(); + final PsiManager manager = call.getManager(); + final PsiElement qualifier = ref.getQualifier(); + + if (referenceName instanceof PsiIdentifier && qualifier instanceof PsiExpression){ + PsiType type = ((PsiExpression) qualifier).getType(); + if (type == null) { + if (qualifier instanceof PsiJavaCodeReferenceElement) { + final ResolveResult result = ((PsiJavaCodeReferenceElement) qualifier).advancedResolve(false); + if (result.getElement() instanceof PsiClass) { + processor.handleEvent(PsiScopeProcessor.Event.START_STATIC, null); + processQualifierResult(result, processor, methodCall); + } + } + else { + throw new MethodProcessorSetupFailedException("Cant determine qualifier type!"); + } + } else if (type instanceof PsiIntersectionType) { + final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); + for (int i = 0; i < conjuncts.length; i++) { + if (!processQualifierType (conjuncts[i], processor, manager, methodCall)) break; + } + } else { + processQualifierType(type, processor, manager, methodCall); + } + } + else{ + LOG.assertTrue(false); + } + } + } else{ + LOG.assertTrue(call instanceof PsiNewExpression); + PsiNewExpression newExpr = (PsiNewExpression)call; + PsiJavaCodeReferenceElement classRef = newExpr.getClassReference(); + if (classRef == null) { + PsiAnonymousClass anonymousClass = newExpr.getAnonymousClass(); + if (anonymousClass != null) { + classRef = anonymousClass.getBaseClassReference(); + } + if (classRef == null) { + throw new MethodProcessorSetupFailedException("Cant get reference to class in new expression"); + } + } + + final ResolveResult result = classRef.advancedResolve(false); + PsiClass aClass = (PsiClass) result.getElement(); + if (aClass == null) + throw new MethodProcessorSetupFailedException("Cant resolve class in new expression"); + processor.setIsConstructor(true); + processor.setAccessClass(aClass); + processor.setArgumentList(newExpr.getArgumentList()); + processor.obtainTypeArguments(newExpr); + processScope(aClass, processor, result.getSubstitutor(), null, call); + + if (dummyImplicitConstructor){ + processDummyConstructor(processor, aClass); + } + } + } + + private static boolean processQualifierType(final PsiType type, + final MethodsProcessor processor, + PsiManager manager, + PsiMethodCallExpression call) throws MethodProcessorSetupFailedException { + if (type instanceof PsiClassType) { + ResolveResult qualifierResult = ((PsiClassType)type).resolveGenerics(); + return processQualifierResult(qualifierResult, processor, call); + } + else if (type instanceof PsiArrayType) { + ResolveResult qualifierResult = manager.getElementFactory().getArrayClassType(((PsiArrayType)type).getComponentType()).resolveGenerics(); + return processQualifierResult(qualifierResult, processor, call); + } + + return true; + } + + private static boolean processQualifierResult(ResolveResult qualifierResult, + final MethodsProcessor processor, + PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException { + PsiElement resolve = qualifierResult.getElement(); + + if (resolve == null) + throw new MethodProcessorSetupFailedException("Cant determine qualifier class!"); + + if (resolve instanceof PsiTypeParameter) { + final PsiType paramType = qualifierResult.getSubstitutor().substitute((PsiTypeParameter)resolve); + qualifierResult = PsiUtil.resolveGenericsClassInType(paramType); + resolve = qualifierResult.getElement(); + } else if (resolve instanceof PsiClass) { + PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); + if (qualifier instanceof PsiSuperExpression) { + processor.setAccessClass((PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement()); + } + else + processor.setAccessClass((PsiClass)resolve); + } + + processor.setIsConstructor(false); + processor.setName(methodCall.getMethodExpression().getReferenceName()); + return processScope(resolve, processor, qualifierResult.getSubstitutor(), methodCall, methodCall); + } + + private static void processDummyConstructor(MethodsProcessor processor, PsiClass aClass) { + if (aClass instanceof PsiAnonymousClass) return; + try{ + PsiMethod[] methods = aClass.getMethods(); + for(int i = 0; i < methods.length; i++){ + PsiMethod method = methods[i]; + if(method.isConstructor()){ + return; + } + } + final PsiElementFactory factory = aClass.getManager().getElementFactory(); + final PsiMethod dummyConstructor = factory.createConstructor(); + if(aClass.getNameIdentifier() != null){ + dummyConstructor.getNameIdentifier().replace(aClass.getNameIdentifier()); + } + processor.forceAddResult(dummyConstructor); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java new file mode 100644 index 00000000000..9b052a8e997 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java @@ -0,0 +1,279 @@ + +package com.intellij.psi.statistics.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.source.codeStyle.StatisticsManagerEx; +import com.intellij.psi.statistics.StatisticsManager; +import com.intellij.util.ScrambledInputStream; +import com.intellij.util.ScrambledOutputStream; + +import java.io.*; +import java.lang.ref.SoftReference; +import java.util.*; + +public class StatisticsManagerImpl extends StatisticsManager implements StatisticsManagerEx, ApplicationComponent { + + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.statistics.impl.StatisticsManagerImpl"); + + public String getComponentName() { + return "StatisticsManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + private static final int UNIT_COUNT = 997; + + private static final String STORE_PATH = PathManager.getSystemPath() + File.separator + "stat"; + + private SoftReference[] myUnits = new SoftReference[UNIT_COUNT]; + private HashSet myModifiedUnits = new HashSet(); + + private StatisticsManagerImpl() { + } + + public int getMemberUseCount(PsiType qualifierType, PsiMember member, Map normalizedItems) { + if (qualifierType != null && normalizedItems != null) { + if(normalizedItems.containsKey(qualifierType)) + qualifierType = normalizedItems.get(qualifierType); + else + normalizedItems.put(qualifierType, qualifierType = normalizeType(qualifierType, member.getManager())); + } + String key1 = getMemberUseKey1(qualifierType); + if (key1 == null) return 0; + String key2 = getMemberUseKey2(member); + if (key2 == null) return 0; + int unitNumber = getUnitNumber(key1); + StatisticsUnit unit = getUnit(unitNumber); + return unit.getData(key1, key2); + } + + private PsiType normalizeType(PsiType type, PsiManager manager){ + if(type instanceof PsiClassType){ + return manager.getElementFactory().createType(((PsiClassType) type).resolve()); + } + else if(type instanceof PsiArrayType){ + final PsiType componentType = normalizeType(((PsiArrayType) type).getComponentType(), manager); + final int dimension = type.getArrayDimensions(); + type = componentType; + for(int i = 0; i < dimension; i++) + type = new PsiArrayType(type); + return type; + } + + return type; + } + + public void incMemberUseCount(PsiType qualifierType, PsiMember member) { + qualifierType = normalizeType(qualifierType, member.getManager()); + String key1 = getMemberUseKey1(qualifierType); + if (key1 == null) return; + String key2 = getMemberUseKey2(member); + if (key2 == null) return; + int unitNumber = getUnitNumber(key1); + StatisticsUnit unit = getUnit(unitNumber); + int count = unit.getData(key1, key2); + unit.putData(key1, key2, count + 1); + myModifiedUnits.add(unit); + } + + public int getVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) { + String key1 = getVariableNameUseKey1(propertyName, type); + String key2 = getVariableNameUseKey2(variableKind, name); + int unitNumber = getUnitNumber(key1); + StatisticsUnit unit = getUnit(unitNumber); + return unit.getData(key1, key2); + } + + public void incVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) { + String key1 = getVariableNameUseKey1(propertyName, type); + String key2 = getVariableNameUseKey2(variableKind, name); + int unitNumber = getUnitNumber(key1); + StatisticsUnit unit = getUnit(unitNumber); + int count = unit.getData(key1, key2); + unit.putData(key1, key2, count + 1); + myModifiedUnits.add(unit); + } + + public String[] getAllVariableNamesUsed(VariableKind variableKind, String propertyName, PsiType type) { + String key1 = getVariableNameUseKey1(propertyName, type); + int unitNumber = getUnitNumber(key1); + StatisticsUnit unit = getUnit(unitNumber); + String[] keys2 = unit.getKeys2(key1); + + ArrayList list = new ArrayList(); + + for(int i = 0; i < keys2.length; i++){ + String key2 = keys2[i]; + VariableKind variableKind1 = getVariableKindFromKey2(key2); + if (variableKind1 != variableKind) continue; + String name = getVariableNameFromKey2(key2); + list.add(name); + } + + return list.toArray(new String[list.size()]); + } + + public void save() { + if (!ApplicationManager.getApplication().isUnitTestMode()){ + for(Iterator iterator = myModifiedUnits.iterator(); iterator.hasNext();){ + StatisticsUnit unit = iterator.next(); + saveUnit(unit.getNumber()); + } + } + myModifiedUnits.clear(); + } + + private StatisticsUnit getUnit(int unitNumber) { + SoftReference ref = myUnits[unitNumber]; + if (ref != null){ + StatisticsUnit unit = (StatisticsUnit)ref.get(); + if (unit != null) return unit; + } + StatisticsUnit unit = loadUnit(unitNumber); + if (unit == null){ + unit = new StatisticsUnit(unitNumber); + } + myUnits[unitNumber] = new SoftReference(unit); + return unit; + } + + private StatisticsUnit loadUnit(int unitNumber) { + StatisticsUnit unit = new StatisticsUnit(unitNumber); + if (!ApplicationManager.getApplication().isUnitTestMode()){ + String path = getPathToUnit(unitNumber); + try{ + InputStream in = new BufferedInputStream(new FileInputStream(path)); + in = new ScrambledInputStream(in); + try{ + unit.read(in); + } + finally{ + in.close(); + } + } + catch(IOException e){ + } + catch(WrongFormatException e){ + } + } + return unit; + } + + private void saveUnit(int unitNumber){ + if (!createStoreFolder()) return; + StatisticsUnit unit = getUnit(unitNumber); + String path = getPathToUnit(unitNumber); + try{ + OutputStream out = new BufferedOutputStream(new FileOutputStream(path)); + out = new ScrambledOutputStream(out); + try { + unit.write(out); + } + finally{ + out.close(); + } + } + catch(IOException e){ + Messages.showMessageDialog( + "Error saving system information: " + e.getMessage(), + "Error", + Messages.getErrorIcon() + ); + } + } + + private static int getUnitNumber(String key1) { + return Math.abs(key1.hashCode()) % UNIT_COUNT; + } + + private static String getMemberUseKey1(PsiType qualifierType) { + return "member#" + (qualifierType == null ? "" : qualifierType.getCanonicalText()); + } + + private static String getMemberUseKey2(PsiMember member) { + if (member instanceof PsiMethod){ + PsiMethod method = (PsiMethod)member; + StringBuffer buffer = new StringBuffer(); + buffer.append("method#"); + buffer.append(method.getName()); + PsiParameter[] parms = method.getParameterList().getParameters(); + for(int i = 0; i < parms.length; i++){ + buffer.append("#"); + buffer.append(parms[i].getType().getPresentableText()); + } + return buffer.toString(); + } + else if (member instanceof PsiField){ + return "field#" + ((PsiField)member).getName(); + } + else if (member instanceof PsiClass){ + return "class#" + ((PsiClass)member).getQualifiedName(); + } + else{ + return null; + } + } + + private String getVariableNameUseKey1(String propertyName, PsiType type) { + StringBuffer buffer = new StringBuffer(); + buffer.append("variableName#"); + if (propertyName != null){ + buffer.append(propertyName); + } + buffer.append("#"); + if (type != null){ + buffer.append(type.getCanonicalText()); + } + return buffer.toString(); + } + + private String getVariableNameUseKey2(VariableKind kind, String name) { + StringBuffer buffer = new StringBuffer(); + buffer.append(kind); + buffer.append("#"); + buffer.append(name); + return buffer.toString(); + } + + private VariableKind getVariableKindFromKey2(String key2){ + int index = key2.indexOf("#"); + LOG.assertTrue(index >= 0); + String s = key2.substring(0, index); + return VariableKind.fromString(s); + } + + private String getVariableNameFromKey2(String key2){ + int index = key2.indexOf("#"); + LOG.assertTrue(index >= 0); + return key2.substring(index + 1); + } + + private boolean createStoreFolder(){ + File homeFile = new File(STORE_PATH); + if (!homeFile.exists()){ + if (!homeFile.mkdirs()){ + Messages.showMessageDialog( + "Cannot create folder " + STORE_PATH + " to save system information.", + "Error", + Messages.getErrorIcon() + ); + return false; + } + } + return true; + } + + private String getPathToUnit(int unitNumber) { + return STORE_PATH + File.separator + "unit." + unitNumber; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsUnit.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsUnit.java new file mode 100644 index 00000000000..7cc3b2d152b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/StatisticsUnit.java @@ -0,0 +1,118 @@ + +package com.intellij.psi.statistics.impl; + +import gnu.trove.TObjectIntHashMap; +import gnu.trove.TObjectIntProcedure; +import gnu.trove.TObjectProcedure; + +import java.io.*; +import java.util.HashSet; + +class StatisticsUnit { + private static final int FORMAT_VERSION_NUMBER = 4; + + private static final class MyDataKey { + public final String key1; + public final String key2; + + public MyDataKey(String key1, String key2) { + this.key1 = key1; + this.key2 = key2; + } + + public boolean equals(Object o) { + if (!(o instanceof MyDataKey)) return false; + MyDataKey key = (MyDataKey)o; + if (!key1.equals(key.key1)) return false; + if (!key2.equals(key.key2)) return false; + return true; + } + + public int hashCode() { + return key1.hashCode() + key2.hashCode(); + } + } + + private final int myNumber; + + private TObjectIntHashMap myDataMap = new TObjectIntHashMap(); + + public StatisticsUnit(int number) { + myNumber = number; + } + + public int getData(String key1, String key2) { + return myDataMap.get(new MyDataKey(key1, key2)); + } + + public void putData(String key1, String key2, int data) { + MyDataKey key = new MyDataKey(key1, key2); + myDataMap.put(key, data); + } + + public String[] getKeys2(final String key1){ + final HashSet keys = new HashSet(); + myDataMap.forEachKey( + new TObjectProcedure() { + public boolean execute(Object object) { + MyDataKey dataKey = (MyDataKey)object; + if (dataKey.key1.equals(key1)){ + keys.add(dataKey.key2); + } + return true; + } + } + ); + return (String[])keys.toArray(new String[keys.size()]); + } + + public int getNumber() { + return myNumber; + } + + public void write(OutputStream out) throws IOException{ + final DataOutputStream dataOut = new DataOutputStream(out); + dataOut.writeInt(FORMAT_VERSION_NUMBER); + + dataOut.writeInt(myDataMap.size()); + + final IOException[] ex = new IOException[1]; + myDataMap.forEachEntry( + new TObjectIntProcedure() { + public boolean execute(Object key, int value) { + try{ + dataOut.writeUTF(((MyDataKey)key).key1); + dataOut.writeUTF(((MyDataKey)key).key2); + dataOut.writeInt(value); + return true; + } + catch(IOException e){ + ex[0] = e; + return false; + } + } + } + ); + + if (ex[0] != null){ + throw ex[0]; + } + } + + public void read(InputStream in) throws IOException, WrongFormatException { + DataInputStream dataIn = new DataInputStream(in); + int formatVersion = dataIn.readInt(); + if (formatVersion != FORMAT_VERSION_NUMBER){ + throw new WrongFormatException(); + } + + myDataMap.clear(); + int size = dataIn.readInt(); + for(int i = 0; i < size; i++){ + String key1 = dataIn.readUTF(); + String key2 = dataIn.readUTF(); + int value = dataIn.readInt(); + myDataMap.put(new MyDataKey(key1, key2), value); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/WrongFormatException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/WrongFormatException.java new file mode 100644 index 00000000000..04c5bc84d71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/statistics/impl/WrongFormatException.java @@ -0,0 +1,5 @@ + +package com.intellij.psi.statistics.impl; + +class WrongFormatException extends Exception{ +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/text/BlockSupport.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/text/BlockSupport.java new file mode 100644 index 00000000000..452d46cf845 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/text/BlockSupport.java @@ -0,0 +1,14 @@ +package com.intellij.psi.text; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; + +public abstract class BlockSupport { + public static BlockSupport getInstance(Project project) { + return project.getComponent(BlockSupport.class); + } + + public abstract void reparseRange(PsiFile file, int startOffset, int endOffset, String newText) throws IncorrectOperationException; + public abstract void reparseRange(PsiFile file, int startOffset, int endOffset, int lengthShift, char[] newText) throws IncorrectOperationException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/DefaultRoleFinder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/DefaultRoleFinder.java new file mode 100644 index 00000000000..48c69bd42d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/DefaultRoleFinder.java @@ -0,0 +1,26 @@ +package com.intellij.psi.tree; + +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.openapi.diagnostic.Logger; + +public class DefaultRoleFinder implements RoleFinder{ + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.tree.DefaultRoleFinder"); + final IElementType myElementType; + final IElementType myParentType; + + public DefaultRoleFinder(IElementType elementType, IElementType parentType) { + myElementType = elementType; + myParentType = parentType; + } + + public TreeElement findChild(CompositeElement parent) { + if(myParentType != null) LOG.assertTrue(parent.getElementType() == myParentType); + TreeElement current = parent.firstChild; + while(current != null && current.getElementType() != myElementType) + current = current.getTreeNext(); + return current; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/RoleFinder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/RoleFinder.java new file mode 100644 index 00000000000..ba042d30100 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/tree/RoleFinder.java @@ -0,0 +1,8 @@ +package com.intellij.psi.tree; + +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.TreeElement; + +public interface RoleFinder { + TreeElement findChild(CompositeElement parent); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/xml/XmlChildRole.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/xml/XmlChildRole.java new file mode 100644 index 00000000000..a873ed64b34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/psi/xml/XmlChildRole.java @@ -0,0 +1,54 @@ +package com.intellij.psi.xml; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.RoleFinder; +import com.intellij.psi.tree.DefaultRoleFinder; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.openapi.diagnostic.Logger; + +public class XmlChildRole { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.xml.XmlChildRole"); + + public static final RoleFinder START_TAG_NAME_FINDER = new RoleFinder() { + public LeafElement findChild(CompositeElement parent) { + //LOG.assertTrue(parent.getElementType() == XmlElementType.XML_TAG); + TreeElement current = parent.firstChild; + IElementType elementType; + while(current != null + && (elementType = current.getElementType()) != XmlTokenType.XML_NAME + && elementType != XmlTokenType.XML_TAG_NAME){ + current = current.getTreeNext(); + } + return (LeafElement)current; + } + }; + + public static final RoleFinder CLOSING_TAG_NAME_FINDER = new RoleFinder() { + public TreeElement findChild(CompositeElement parent) { + //LOG.assertTrue(parent.getElementType() == XmlElementType.XML_TAG); + TreeElement current = parent.firstChild; + int state = 0; + while(current != null){ + final IElementType elementType = current.getElementType(); + switch(state){ + case 0: + if(elementType == XmlTokenType.XML_END_TAG_START) state = 1; + break; + case 1: + if(elementType == XmlTokenType.XML_NAME || elementType == XmlTokenType.XML_TAG_NAME) + return current; + } + current = current.getTreeNext(); + } + return current; + } + }; + + public static final RoleFinder CLOSING_TAG_START_FINDER = new DefaultRoleFinder(XmlTokenType.XML_END_TAG_START, null); + public static final RoleFinder EMPTY_TAG_END_FINDER = new DefaultRoleFinder(XmlTokenType.XML_EMPTY_ELEMENT_END, null); + public static final RoleFinder ATTRIBUTE_NAME_FINDER = new DefaultRoleFinder(XmlTokenType.XML_NAME, null); + public static final RoleFinder ATTRIBUTE_VALUE_FINDER = new DefaultRoleFinder(XmlElementType.XML_ATTRIBUTE_VALUE, null); + public static final RoleFinder START_TAG_END_FINDER = new DefaultRoleFinder(XmlTokenType.XML_TAG_END, null); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/BaseRefactoringProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/BaseRefactoringProcessor.java new file mode 100644 index 00000000000..c1d86deb4f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -0,0 +1,381 @@ +package com.intellij.refactoring; + +import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringListenerManager; +import com.intellij.refactoring.listeners.impl.RefactoringListenerManagerImpl; +import com.intellij.refactoring.listeners.impl.RefactoringTransaction; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.RefactoringChangeMarker; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.usages.*; +import com.intellij.util.Processor; + +import javax.swing.*; +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +public abstract class BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.BaseRefactoringProcessor"); + public static final Runnable EMPTY_CALLBACK = EmptyRunnable.getInstance(); + protected final Project myProject; + + private Object myMarkerId; + private RefactoringTransaction myTransaction; + private boolean myIsPreviewUsages; + protected Runnable myPrepareSuccessfulSwingThreadCallback = EMPTY_CALLBACK; + + + public BaseRefactoringProcessor(Project project) { + this(project, null); + } + + public BaseRefactoringProcessor(Project project, Runnable prepareSuccessfulCallback) { + myProject = project; + myPrepareSuccessfulSwingThreadCallback = prepareSuccessfulCallback; + } + + protected abstract UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand); + + /** + * Is called inside atomic action. + */ + protected abstract UsageInfo[] findUsages(); + + /** + * is called when usage search is re-run. + * @param elements - refreshed elements that are returned by UsageViewDescriptor.getElements() + */ + protected abstract void refreshElements(PsiElement[] elements); + + /** + * Is called inside atomic action. + */ + protected boolean preprocessUsages(UsageInfo[][] usages) { + prepareSuccessful(); + return true; + } + + /** + * Is called inside atomic action. + */ + protected boolean isPreviewUsages(UsageInfo[] usages) { + if (UsageViewUtil.hasReadOnlyUsages(usages)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + return true; + } + return myIsPreviewUsages; + } + + boolean isPreviewUsages() { + return myIsPreviewUsages; + } + + + public void setPreviewUsages(boolean isPreviewUsages) { + myIsPreviewUsages = isPreviewUsages; + } + + public void setPrepareSuccessfulSwingThreadCallback(Runnable prepareSuccessfulSwingThreadCallback) { + myPrepareSuccessfulSwingThreadCallback = prepareSuccessfulSwingThreadCallback; + } + + protected RefactoringTransaction getTransaction() { + return myTransaction; + } + + /** + * Is called in a command and inside atomic action. + */ + protected abstract void performRefactoring(UsageInfo[] usages); + + /** + * If this method returns true, it means that element to rename is variable, and in the findUsages tree it + * will be shown with read-access or write-access icons. + * @return true if element to rename is variable(local, field, or parameter). + */ + protected boolean isVariable() { + return false; + } + + protected abstract String getCommandName(); + + public void run(Object markerId) { + myMarkerId = markerId; + + final UsageInfo[][] usages = new UsageInfo[1][]; + + final Runnable findUsagesRunnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + usages[0] = findUsages(); + } + }); + } + }; + + if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously(findUsagesRunnable, "Looking For Usages...", true, myProject)) return; + + LOG.assertTrue(usages[0] != null); + if (!preprocessUsages(usages)) return; + boolean toPreview = isPreviewUsages(usages[0]); + if (toPreview) { + FindUsagesCommand findUsagesCommand = new FindUsagesCommand() { + public UsageInfo[] execute(PsiElement[] elementsToSearch) { + refreshElements(elementsToSearch); + findUsagesRunnable.run(); + return usages[0]; + } + }; + UsageViewDescriptor descriptor = createUsageViewDescriptor(usages[0], findUsagesCommand); + showUsageView(descriptor, isVariable(), isVariable()); + } else { + final UsageInfo[] usages1 = usages[0]; + execute(usages1); + } + } + + void execute(final UsageInfo[] usages) { + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + doRefactoring(usages, null); + } + }); + } + }, + getCommandName(), + null + ); + } + + private UsageViewPresentation createPresentation(UsageViewDescriptor descriptor) { + UsageViewPresentation presentation = new UsageViewPresentation(); + presentation.setTabText("Refactoring preview"); + presentation.setTargetsNodeText(descriptor.getProcessedElementsHeader()); + presentation.setShowReadOnlyStatusAsRed(true); + presentation.setShowCancelButton(true); + presentation.setCodeUsagesString(descriptor.getCodeReferencesText(1, 1)); //TODO + presentation.setNonCodeUsagesString(descriptor.getCommentReferencesText(1, 1)); //TODO + return presentation; + } + + private void showUsageView(final UsageViewDescriptor viewDescriptor, boolean showReadAccessIcon, boolean showWriteAccessIcon) { + UsageViewManager viewManager = myProject.getComponent(UsageViewManager.class); + + final UsageTarget[] targets = PsiElement2UsageTargetAdapter.convert(viewDescriptor.getElements()); + + Factory searcherFactory = new Factory() { + boolean myRequireRefresh = false; + + public UsageSearcher create() { + UsageSearcher usageSearcher = new UsageSearcher() { + public void generate(Processor processor) { + if (myRequireRefresh) { + List elements = new ArrayList(); + for (int i = 0; i < targets.length; i++) { + UsageTarget target = targets[i]; + if (target.isValid()) { + elements.add(((PsiElement2UsageTargetAdapter)target).getElement()); + } + } + viewDescriptor.refresh(elements.toArray(new PsiElement[elements.size()])); + } + else { + myRequireRefresh = true; + } + + UsageInfo[] usageInfos = viewDescriptor.getUsages(); + final Usage[] usages = UsageInfo2UsageAdapter.convert(usageInfos); + + for (int i = 0; i < usages.length; i++) { + Usage usage = usages[i]; + if (!processor.process(usage)) return; + } + + if (usages.length > 0) { + ApplicationManager.getApplication().invokeLater(new Runnable() { // some people call processors in write action + public void run() { + RefactoringUtil.showInfoDialog(getInfo(), myProject); + } + }, ModalityState.NON_MMODAL); + } + } + }; + + return usageSearcher; + } + }; + + final com.intellij.usages.UsageView usageView = viewManager.searchAndShowUsages(targets, searcherFactory, true, false, createPresentation(viewDescriptor)); + + final Runnable refactoringRunnable = new Runnable() { + public void run() { + final Set excludedUsageInfos = getExcludedUsages(usageView); + doRefactoring(viewDescriptor.getUsages(), excludedUsageInfos); + } + }; + + String canNotMakeString = "Cannot perform the refactoring operation.\n" + + "There were changes in code after the usages have been found.\n" + + "Please, perform the usage search again."; + + usageView.addPerformOperationAction(refactoringRunnable, getCommandName(), canNotMakeString, "Do Refactor", SystemInfo.isMac ? 0 : 'D'); + } + + private Set getExcludedUsages(final UsageView usageView) { + Set usages = usageView.getExcludedUsages(); + + Set excludedUsageInfos = new HashSet(); + for (Iterator i = usages.iterator(); i.hasNext();) { + Usage usage = i.next(); + if (usage instanceof UsageInfo2UsageAdapter) { + excludedUsageInfos.add(((UsageInfo2UsageAdapter)usage).getUsageInfo()); + } + } + return excludedUsageInfos; + } + + private static String getInfo() { + return "Press the \"Do Refactor\" button at the bottom of the search results panel\n" + + "to complete the refactoring operation."; + } + + private void doRefactoring(UsageInfo[] usages, Set excludedUsages) { + if (usages != null) { + ArrayList array = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (excludedUsages != null && excludedUsages.contains(usage)) { + continue; + } + //if (usage.isExcluded()) continue; + final PsiElement element = usage.getElement(); + if (element == null) continue; + if (!element.isWritable()) continue; + array.add(usage); + } + usages = array.toArray(new UsageInfo[array.size()]); + } + + com.intellij.openapi.localVcs.LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + + try { + final UsageInfo[] _usages = usages; + ApplicationManager.getApplication().runWriteAction(new RefactoringChangeMarker() { + public Object getId() { + return myMarkerId; + } + + public void run() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + RefactoringListenerManagerImpl listenerManager = + (RefactoringListenerManagerImpl) RefactoringListenerManager.getInstance(myProject); + myTransaction = listenerManager.startTransaction(); + performRefactoring(_usages); + myTransaction.commit(); + performPsiSpoilingRefactoring(); + } + }); + } finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + + if (usages != null) { + int count = usages.length; + if (count > 0) { + WindowManager.getInstance().getStatusBar(myProject).setInfo(count + " occurrence" + (count > 1 ? "s" : "") + " changed"); + } else { + if (!isPreviewUsages(usages)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo("No occurrences found"); + } + } + } + } + + /** + * Refactorings that spoil PSI (write something directly to documents etc.) should + * do that in this method.
    + * This method is called immediately after + * {@link #performRefactoring(com.intellij.usageView.UsageInfo[])}. + */ + protected void performPsiSpoilingRefactoring() { + + } + + protected void prepareSuccessful() { + if (myPrepareSuccessfulSwingThreadCallback != null) { + // make sure that dialog is closed in swing thread + if (!ApplicationManager.getApplication().isDispatchThread()) { + try { + SwingUtilities.invokeAndWait(myPrepareSuccessfulSwingThreadCallback); + } catch (InterruptedException e) { + LOG.error(e); + } catch (InvocationTargetException e) { + LOG.error(e); + } + } else { + myPrepareSuccessfulSwingThreadCallback.run(); + } +// ToolWindowManager.getInstance(myProject).invokeLater(myPrepareSuccessfulSwingThreadCallback); + } + } + + /** + * Override in subclasses + */ + protected void prepareTestRun() { + + } + + public final void testRun() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + prepareTestRun(); + UsageInfo[] usages = findUsages(); + UsageInfo[][] u = new UsageInfo[][]{usages}; + preprocessUsages(u); + RefactoringListenerManagerImpl listenerManager = + (RefactoringListenerManagerImpl) RefactoringListenerManager.getInstance(myProject); + myTransaction = listenerManager.startTransaction(); + performRefactoring(u[0]); + myTransaction.commit(); + performPsiSpoilingRefactoring(); + } + + public boolean showConflicts(final ArrayList conflicts, UsageInfo[][] usages) { + boolean result; + if (conflicts.size() > 0 && myPrepareSuccessfulSwingThreadCallback != null) { + final ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), myProject); + conflictsDialog.show(); + result = conflictsDialog.isOK(); + } + else { + result = true; + } + if (result) { + prepareSuccessful(); + return true; + } + else { + return false; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/HelpID.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/HelpID.java new file mode 100644 index 00000000000..c1099f4241a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/HelpID.java @@ -0,0 +1,100 @@ + +package com.intellij.refactoring; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.psi.*; + +/** + * + */ +public class HelpID { + private static final String RENAME_PACKAGE = "refactoring.renamePackage"; + private static final String RENAME_CLASS = "refactoring.renameClass"; + private static final String RENAME_METHOD = "refactoring.renameMethod"; + private static final String RENAME_FIELD = "refactoring.renameField"; + private static final String RENAME_VARIABLE = "refactoring.renameVariable"; + private static final String RENAME_PARAMETER = "refactoring.renameParameter"; + private static final String RENAME_NAMED_POINTCUT = "refactoring.renamePointcutDef"; + + private static final String MOVE_PACKAGE = "refactoring.movePackage"; + private static final String MOVE_CLASS = "refactoring.moveClass"; + + public static final String INTRODUCE_VARIABLE = "refactoring.introduceVariable"; + public static final String INTRODUCE_FIELD = "refactoring.introduceField"; + public static final String INTRODUCE_CONSTANT = "refactoring.introduceConstant"; + public static final String EXTRACT_METHOD = "refactoring.extractMethod"; + + public static final String ANONYMOUS_TO_INNER = "refactoring.convertAnonymous"; + public static final String LOCAL_TO_FIELD = "refactoring.convertLocal"; + public static final String CHANGE_SIGNATURE = "refactoring.changeSignature"; + public static final String ENCAPSULATE_FIELDS = "refactoring.encapsulateFields"; + public static final String EXTRACT_INTERFACE = "refactoring.extractInterface"; + public static final String EXTRACT_SUPERCLASS = "refactoring.extractSuperclass"; + public static final String MOVE_INNER_UPPER = "refactoring.moveInner"; + public static final String REPLACE_TEMP_WITH_QUERY = "refactoring.replaceTemp"; + public static final String MOVE_MEMBERS = "refactoring.moveMembers"; + public static final String INLINE_METHOD = "refactoring.inlineMethod"; + public static final String INLINE_VARIABLE = "refactoring.inlineVariable"; + public static final String INLINE_POINTCUT = "refactoring.inlinePointcut"; + public static final String INLINE_FIELD = "refactoring.inlineField"; + + public static final String MIGRATION = "refactoring.migration"; + + public static final String COPY_CLASS = "refactoring.copyClass"; + + public static final String MAKE_METHOD_STATIC = "refactoring.makeMethodStatic"; + public static final String MAKE_METHOD_STATIC_SIMPLE = "refactoring.makeMethodStatic"; + + public static final String INTRODUCE_PARAMETER = "refactoring.introduceParameter"; + public static final String TURN_REFS_TO_SUPER = "refactoring.useInterface"; + public static final String MEMBERS_PULL_UP = "refactoring.pullMembersUp"; + public static final String MEMBERS_PUSH_DOWN = "refactoring.pushMembersDown"; + public static final String INHERITANCE_TO_DELEGATION = "refactoring.replaceInheritWithDelegat"; + public static final String REPLACE_CONSTRUCTOR_WITH_FACTORY = "refactoring.replaceConstrWithFactory"; + public static final String SAFE_DELETE = "refactoring.safeDelete"; + public static final String SAFE_DELETE_OVERRIDING = "refactoring.safeDelete.overridingMethods"; + public static final String EJB_RENAME = "refactoring.rename.ejbRename"; + public static final String TYPE_COOK = "refactoring.generify"; + public static final String TYPE_MIGRATION = "refactoring.migrateType"; + public static final String CONVERT_TO_INSTANCE_METHOD = "refactoring.convertToInstanceMethod"; + public static final String METHOD_DUPLICATES = "refactoring.replaceMethodCodeDuplicates"; + public static final String CHANGE_CLASS_SIGNATURE = "refactoring.changeClassSignature"; + + public static String getRenameHelpID(PsiElement element) { + String helpID = null; + if (element instanceof PsiDirectory){ + helpID = HelpID.RENAME_PACKAGE; + } + else if (element instanceof PsiClass){ + helpID = HelpID.RENAME_CLASS; + } + else if (element instanceof PsiMethod){ + helpID = HelpID.RENAME_METHOD; + } + else if (element instanceof PsiField){ + helpID = HelpID.RENAME_FIELD; + } + else if (element instanceof PsiLocalVariable){ + helpID = HelpID.RENAME_VARIABLE; + } + else if (element instanceof PsiParameter){ + helpID = HelpID.RENAME_PARAMETER; + } + else if (element instanceof PsiPointcutDef) { + helpID = HelpID.RENAME_NAMED_POINTCUT; + } + return helpID; + } + + public static String getMoveHelpID(PsiElement element) { + if (element instanceof PsiPackage){ + return MOVE_PACKAGE; + } + else if (element instanceof PsiClass){ + return MOVE_CLASS; + } + else{ + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/IntroduceHandlerBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/IntroduceHandlerBase.java new file mode 100644 index 00000000000..08202055520 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/IntroduceHandlerBase.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +/** + * @author dsl + */ +public abstract class IntroduceHandlerBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.IntroduceHandlerBase"); + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiExpression, "incorrect invoke() parameters"); + final PsiElement tempExpr = elements[0]; + final Editor editor; + if (dataContext != null) { + final Editor editorFromDC = (Editor)dataContext.getData(DataConstants.EDITOR); + final PsiFile cachedPsiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(editorFromDC.getDocument()); + if (cachedPsiFile != null && PsiTreeUtil.isAncestor(cachedPsiFile, tempExpr, false)) { + editor = editorFromDC; + } + else { + editor = null; + } + } + else { + editor = null; + } + if (tempExpr instanceof PsiExpression) { + invokeImpl(project, (PsiExpression)tempExpr, editor); + } + else if(tempExpr instanceof PsiLocalVariable) { + invokeImpl(project, (PsiLocalVariable)tempExpr, editor); + } + else { + LOG.assertTrue(false, "elements[0] should be PsiExpression or PsiLocalVariable"); + } + } + + /** + * @param project + * @param tempExpr + * @param editor editor to highlight stuff in. Should accept null + * @return + */ + protected abstract boolean invokeImpl(Project project, PsiExpression tempExpr, + Editor editor); + + /** + * @param project + * @param localVariable + * @param editor editor to highlight stuff in. Should accept null + * @return + */ + protected abstract boolean invokeImpl(Project project, PsiLocalVariable localVariable, + Editor editor); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringDialog.java new file mode 100644 index 00000000000..e8b85c56542 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringDialog.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.refactoring; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.event.ActionEvent; + +/** + * Author: msk + */ +public abstract class RefactoringDialog extends DialogWrapper { + + /** The default exit code for "Refactor" action. */ + public static final int REFACTOR_EXIT_CODE = 3; + + /** The default exit code for "Preview" action. */ + public static final int PREVIEW_EXIT_CODE = 4; + + private Action myRefactorAction; + private Action myPreviewAction; + private boolean myCbPreviewResults; + + protected RefactoringDialog(Project project, boolean canBeParent) { + super (project, canBeParent); + myCbPreviewResults = true; + } + + final public boolean isPreviewUsages() { + return myCbPreviewResults; + } + + protected void createDefaultActions() { + super.createDefaultActions (); + myRefactorAction = new RefactorAction(); + myPreviewAction = new PreviewAction(); + } + + /** + * @return default implementation of "Refactor" action. + */ + final protected Action getRefactorAction() { + return myRefactorAction; + } + + /** + * @return default implementation of "Preview" action. + */ + final protected Action getPreviewAction() { + return myPreviewAction; + } + + protected abstract void doAction(); + + final protected void doPreviewAction () { + validateButtons(); + if (!isOKActionEnabled()) return; + myCbPreviewResults = true; + doAction (); + } + + final protected void doRefactorAction () { + validateButtons(); + if (!isOKActionEnabled()) return; + myCbPreviewResults = false; + doAction (); + } + + + final protected void closeOKAction() { super.doOKAction(); } + + final protected void doOKAction() { + validateButtons(); + + if (!isOKActionEnabled()) return; + doAction(); + + } + + protected boolean areButtonsValid () { return true; } + + protected void validateButtons() { + final boolean enabled = areButtonsValid (); + getPreviewAction().setEnabled(enabled); + getRefactorAction().setEnabled(enabled); + } + + final protected boolean isActionsEnabled () { + return getRefactorAction ().isEnabled () && getPreviewAction ().isEnabled (); + } + + protected boolean hasHelpAction () { + return true; + } + + final protected Action[] createActions() { + if (hasHelpAction ()) + return new Action[]{getRefactorAction(), getPreviewAction(), getCancelAction(), getHelpAction()}; + else + return new Action[]{getRefactorAction(), getPreviewAction(), getCancelAction()}; + } + + private class RefactorAction extends AbstractAction { + public RefactorAction() { + putValue(Action.NAME, "Refactor"); + putValue(DEFAULT_ACTION, Boolean.TRUE); + } + + public void actionPerformed(ActionEvent e) { + doRefactorAction (); + } + } + + private class PreviewAction extends AbstractAction { + public PreviewAction() { + putValue(Action.NAME, "Preview"); + } + + public void actionPerformed(ActionEvent e) { + doPreviewAction (); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringImpl.java new file mode 100644 index 00000000000..cae59ca11ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringImpl.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring; + +import com.intellij.openapi.util.Ref; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public abstract class RefactoringImpl implements Refactoring { + protected final T myProcessor; + + public RefactoringImpl(T refactoringProcessor) { + myProcessor = refactoringProcessor; + } + + public void setPreviewUsages(boolean value) { + myProcessor.setPreviewUsages(value); + } + + public boolean isPreviewUsages() { + return myProcessor.isPreviewUsages(); + } + + public void setInteractive(Runnable prepareSuccessfulCallback) { + myProcessor.setPrepareSuccessfulSwingThreadCallback(prepareSuccessfulCallback); + } + + public boolean isInteractive() { + return myProcessor.myPrepareSuccessfulSwingThreadCallback != null; + } + + public UsageInfo[] findUsages() { + return myProcessor.findUsages(); + } + + public boolean preprocessUsages(Ref usages) { + final UsageInfo[][] usagesArray = new UsageInfo[][]{usages.get()}; + final boolean result = myProcessor.preprocessUsages(usagesArray); + usages.set(usagesArray[0]); + return result; + } + + public boolean shouldPreviewUsages(UsageInfo[] usages) { + return myProcessor.isPreviewUsages(usages); + } + + public void doRefactoring(UsageInfo[] usages) { + myProcessor.execute(usages); + } + + public void run() { + myProcessor.run(null); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringManager.java new file mode 100644 index 00000000000..4f320122635 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringManager.java @@ -0,0 +1,52 @@ +package com.intellij.refactoring; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.refactoring.migration.MigrationManager; +import com.intellij.refactoring.typeMigration.ui.TypeMigrationDialog; + +public class RefactoringManager implements ProjectComponent { + private MigrationManager myMigrateManager; + private TypeMigrationDialog myMigrationDialog; + + public static RefactoringManager getInstance(Project project) { + return project.getComponent(RefactoringManager.class); + } + + private RefactoringManager(Project project) { + myMigrateManager = new MigrationManager(project); + myMigrationDialog = null; + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public MigrationManager getMigrateManager() { + return myMigrateManager; + } + + public String getComponentName() { + return "RefactoringManager"; + } + + public void startTypeMigrationSession(final TypeMigrationDialog d){ + myMigrationDialog = d; + } + + public TypeMigrationDialog getTypeMigrationDialog (){ + return myMigrationDialog; + } + + public void endTypeMigrationSession(){ + myMigrationDialog = null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringSettings.java new file mode 100644 index 00000000000..49e19bd805f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/RefactoringSettings.java @@ -0,0 +1,222 @@ + +package com.intellij.refactoring; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +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.psi.*; +import com.intellij.psi.xml.XmlAttributeValue; +import org.jdom.Element; + +public class RefactoringSettings implements JDOMExternalizable, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.RefactoringSettings"); + // properties should be public in order to get saved by DefaultExternalizable implementation + public boolean IS_SHOW_ACTION_INFO = true; + + //public boolean RENAME_PREVIEW_USAGES = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_CLASS = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_METHOD = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_FIELD = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE = true; + public boolean RENAME_SEARCH_IN_COMMENTS_FOR_POINTCUT_DEF = true; + + public boolean RENAME_SEARCH_IN_NONJAVA_FOR_PACKAGE = true; + public boolean RENAME_SEARCH_IN_NONJAVA_FOR_CLASS = true; + //public boolean RENAME_SEARCH_IN_NONJAVA_FOR_METHOD; + //public boolean RENAME_SEARCH_IN_NONJAVA_FOR_FIELD; + //public boolean RENAME_SEARCH_IN_NONJAVA_FOR_VARIABLE; + + //public boolean ENCAPSULATE_FIELDS_PREVIEW_USAGES = true; + public boolean ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = true; + + public boolean EXTRACT_INTERFACE_PREVIEW_USAGES = true; + + public boolean MOVE_PREVIEW_USAGES = true; + public boolean MOVE_SEARCH_IN_COMMENTS = true; + public boolean MOVE_SEARCH_IN_NONJAVA_FILES = true; + + + //public boolean INLINE_METHOD_PREVIEW_USAGES = true; + //public boolean INLINE_FIELD_PREVIEW_USAGES = true; + + //public boolean CHANGE_SIGNATURE_PREVIEW_USAGES = true; + public boolean CHANGE_CLASS_SIGNATURE_PREVIEW_USAGES = true; + + public boolean MOVE_INNER_PREVIEW_USAGES = true; + + //public boolean TYPE_COOK_PREVIEW_USAGES = true; + public boolean TYPE_COOK_DROP_CASTS = true; + public boolean TYPE_COOK_PRESERVE_RAW_ARRAYS = true; + public boolean TYPE_COOK_LEAVE_OBJECT_PARAMETERIZED_TYPES_RAW = true; + + public boolean TYPE_MIGRATION_PREVIEW_USAGES = true; + + //public boolean MAKE_METHOD_STATIC_PREVIEW_USAGES; + //public boolean INTRODUCE_PARAMETER_PREVIEW_USAGES; + public int INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS; + public int EXTRACT_INTERFACE_JAVADOC; + public int EXTRACT_SUPERCLASS_JAVADOC; + public boolean TURN_REFS_TO_SUPER_PREVIEW_USAGES; + public boolean INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE; + public String INTRODUCE_FIELD_VISIBILITY; + public int PULL_UP_MEMBERS_JAVADOC; + public boolean PUSH_DOWN_PREVIEW_USAGES; + public boolean INLINE_METHOD_THIS; + public boolean INLINE_FIELD_THIS; + //public boolean INHERITANCE_TO_DELEGATION_PREVIEW_USAGES; + public boolean INHERITANCE_TO_DELEGATION_DELEGATE_OTHER; + //public boolean REPLACE_CONSTRUCTOR_WITH_FACTORY_PREVIEW_USAGES; + public boolean SAFE_DELETE_SEARCH_IN_COMMENTS = true; + public boolean SAFE_DELETE_SEARCH_IN_NON_JAVA = true; + public boolean SAFE_DELETE_WHEN_DELETE = true; + public String INTRODUCE_CONSTANT_VISIBILITY; + public boolean CONVERT_TO_INSTANCE_METHOD_PREVIEW_USAGES = true; + + public static RefactoringSettings getInstance() { + return ApplicationManager.getApplication().getComponent(RefactoringSettings.class); + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public boolean isToSearchInCommentsForRename(PsiElement element) { + if (element instanceof PsiDirectory) { + element = ((PsiDirectory)element).getPackage(); + } + if (element instanceof PsiPackage){ + return RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE; + } + else if (element instanceof PsiClass){ + return RENAME_SEARCH_IN_COMMENTS_FOR_CLASS; + } + else if (element instanceof PsiMethod){ + return RENAME_SEARCH_IN_COMMENTS_FOR_METHOD; + } + else if (element instanceof PsiField){ + return RENAME_SEARCH_IN_COMMENTS_FOR_FIELD; + } + else if (element instanceof PsiVariable){ + return RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE; + } + else if (element instanceof PsiPointcutDef) { + return RENAME_SEARCH_IN_COMMENTS_FOR_POINTCUT_DEF; + } + else if (element instanceof XmlAttributeValue) { + return false; + } + else if (element instanceof PsiNamedElement) { + return false; + } + else{ + LOG.assertTrue(false); + return false; + } + } + + public boolean isToSearchInNonJavaFilesForRename(PsiElement element) { + if (element instanceof PsiDirectory) { + element = ((PsiDirectory)element).getPackage(); + } + if (element instanceof PsiPackage){ + return RENAME_SEARCH_IN_NONJAVA_FOR_PACKAGE; + } + else if (element instanceof PsiClass){ + return RENAME_SEARCH_IN_NONJAVA_FOR_CLASS; + } + /* + else if (element instanceof PsiMethod){ + return RENAME_SEARCH_IN_NONJAVA_FOR_METHOD; + } + else if (element instanceof PsiField){ + return RENAME_SEARCH_IN_NONJAVA_FOR_FIELD; + } + else if (element instanceof PsiVariable){ + return RENAME_SEARCH_IN_NONJAVA_FOR_VARIABLE; + } + */ + else{ + /* + LOG.assertTrue(false); + */ + return false; + } + } + + public void setToSearchInCommentsForRename(PsiElement element, boolean value) { + if (element instanceof PsiDirectory) { + element = ((PsiDirectory)element).getPackage(); + } + if (element instanceof PsiPackage){ + RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE = value; + } + else if (element instanceof PsiClass){ + RENAME_SEARCH_IN_COMMENTS_FOR_CLASS = value; + } + else if (element instanceof PsiMethod){ + RENAME_SEARCH_IN_COMMENTS_FOR_METHOD = value; + } + else if (element instanceof PsiField){ + RENAME_SEARCH_IN_COMMENTS_FOR_FIELD = value; + } + else if (element instanceof PsiVariable){ + RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE = value; + } + else if (element instanceof PsiPointcutDef){ + RENAME_SEARCH_IN_COMMENTS_FOR_POINTCUT_DEF = value; + } + else if (element instanceof PsiNamedElement) { + + } + else{ + LOG.assertTrue(false); + } + } + + public void setToSearchInNonJavaFilesForRename(PsiElement element, boolean value) { + if (element instanceof PsiDirectory) { + element = ((PsiDirectory)element).getPackage(); + } + if (element instanceof PsiPackage){ + RENAME_SEARCH_IN_NONJAVA_FOR_PACKAGE = value; + } + else if (element instanceof PsiClass){ + RENAME_SEARCH_IN_NONJAVA_FOR_CLASS = value; + } + else if (element instanceof PsiMethod){ + //RENAME_SEARCH_IN_NONJAVA_FOR_METHOD = value; + } + else if (element instanceof PsiField){ + //RENAME_SEARCH_IN_NONJAVA_FOR_FIELD = value; + } + else if (element instanceof PsiVariable){ + //RENAME_SEARCH_IN_NONJAVA_FOR_VARIABLE = value; + } + else if (element instanceof XmlAttributeValue) { + + } + else{ + LOG.assertTrue(false); + } + } + + public String getComponentName() { + return "RefactoringSettings"; + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/AnonymousToInnerAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/AnonymousToInnerAction.java new file mode 100644 index 00000000000..82bdc09b281 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/AnonymousToInnerAction.java @@ -0,0 +1,21 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler; + +public class AnonymousToInnerAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return true; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new AnonymousToInnerHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/BaseRefactoringAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/BaseRefactoringAction.java new file mode 100644 index 00000000000..7440f8335c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/BaseRefactoringAction.java @@ -0,0 +1,91 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.RefactoringActionHandler; + +public abstract class BaseRefactoringAction extends AnAction { + protected abstract boolean isAvailableInEditorOnly(); + + protected abstract boolean isEnabledOnElements(PsiElement[] elements); + + protected abstract RefactoringActionHandler getHandler(DataContext dataContext); + + public final void actionPerformed(AnActionEvent e) { + DataContext dataContext = e.getDataContext(); + final Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) return; + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final Editor editor = (Editor) dataContext.getData(DataConstants.EDITOR); + final PsiElement[] elements = getPsiElementArray(dataContext); + RefactoringActionHandler handler = getHandler(dataContext); + if (handler == null) return; + if (editor != null) { + final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null) return; + handler.invoke(project, editor, file, dataContext); + } else { + handler.invoke(project, elements, dataContext); + } + } + + protected boolean isEnabledOnDataContext(DataContext dataContext) { + return false; + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + DataContext dataContext = e.getDataContext(); + Project project = (Project) dataContext.getData(DataConstants.PROJECT); + if (project == null) { + presentation.setEnabled(false); + return; + } + + Editor editor = (Editor) dataContext.getData(DataConstants.EDITOR); + if (editor != null) { + final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file == null || !isAvaiableForFile(file)) { + presentation.setEnabled(false); + } else { + presentation.setEnabled(true); + } + } else { + if (isAvailableInEditorOnly()) { + presentation.setEnabled(false); + return; + } + final PsiElement[] elements = getPsiElementArray(dataContext); + if (elements != null && elements.length != 0) { + presentation.setEnabled(isEnabledOnElements(elements)); + } else if (isEnabledOnDataContext(dataContext)) { + presentation.setEnabled(true); + return; + } else { + presentation.setEnabled(false); + return; + } + } + } + + protected boolean isAvaiableForFile(PsiFile file) { + return file.canContainJavaCode(); + } + + public static PsiElement[] getPsiElementArray(DataContext dataContext) { + PsiElement[] psiElements = (PsiElement[]) dataContext.getData(DataConstantsEx.PSI_ELEMENT_ARRAY); + if (psiElements == null || psiElements.length == 0) { + PsiElement element = (PsiElement) dataContext.getData(DataConstants.PSI_ELEMENT); + if (element != null) { + psiElements = new PsiElement[]{element}; + } + } + return psiElements; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ChangeSignatureAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ChangeSignatureAction.java new file mode 100644 index 00000000000..ca31bde9409 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ChangeSignatureAction.java @@ -0,0 +1,23 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; + +public class ChangeSignatureAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && (elements[0] instanceof PsiMethod || elements[0] instanceof PsiClass); + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new ChangeSignatureHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java new file mode 100644 index 00000000000..cca7bd688d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java @@ -0,0 +1,24 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return false; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && elements[0] instanceof PsiMethod; + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new ConvertToInstanceMethodHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/EncapsulateFieldsAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/EncapsulateFieldsAction.java new file mode 100644 index 00000000000..ca3a563dc86 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/EncapsulateFieldsAction.java @@ -0,0 +1,43 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler; + +public class EncapsulateFieldsAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + if (elements.length == 1) { + return elements[0] instanceof PsiClass || isAcceptedField(elements[0]); + } + else if (elements.length > 1){ + for (int idx = 0; idx < elements.length; idx++) { + if (!isAcceptedField(elements[idx])) { + return false; + } + } + return true; + } + return false; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new EncapsulateFieldsHandler(); + } + + private static boolean isAcceptedField(PsiElement element) { + if (element instanceof PsiField) { + if (((PsiField)element).getContainingClass() != null) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractInterfaceAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractInterfaceAction.java new file mode 100644 index 00000000000..6e5674da436 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractInterfaceAction.java @@ -0,0 +1,35 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler; + +public class ExtractInterfaceAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + /* + if (elements.length == 1) { + return elements[0] instanceof PsiClass || elements[0] instanceof PsiField || elements[0] instanceof PsiMethod; + } + else if (elements.length > 1){ + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiField || element instanceof PsiMethod)) return false; + } + return true; + } + return false; + */ + return elements.length == 1 && elements[0] instanceof PsiClass; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new ExtractInterfaceHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractMethodAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractMethodAction.java new file mode 100644 index 00000000000..67bd77a56bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractMethodAction.java @@ -0,0 +1,24 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.extractMethod.ExtractMethodHandler; + +/** + * + */ +public class ExtractMethodAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return true; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new ExtractMethodHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractSuperclassAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractSuperclassAction.java new file mode 100644 index 00000000000..c1e7ba9e4e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ExtractSuperclassAction.java @@ -0,0 +1,35 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler; + +public class ExtractSuperclassAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + /* + if (elements.length == 1) { + return elements[0] instanceof PsiClass || elements[0] instanceof PsiField || elements[0] instanceof PsiMethod; + } + else if (elements.length > 1){ + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiField || element instanceof PsiMethod)) return false; + } + return true; + } + return false; + */ + return elements.length == 1 && elements[0] instanceof PsiClass && !((PsiClass) elements[0]).isInterface(); + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new ExtractSuperclassHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InheritanceToDelegationAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InheritanceToDelegationAction.java new file mode 100644 index 00000000000..78620e23b78 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InheritanceToDelegationAction.java @@ -0,0 +1,21 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler; + +public class InheritanceToDelegationAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && elements[0] instanceof PsiClass && !((PsiClass) elements[0]).isInterface(); + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new InheritanceToDelegationHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InlineAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InlineAction.java new file mode 100644 index 00000000000..42b465fbd59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/InlineAction.java @@ -0,0 +1,28 @@ +/** + * class InlineAction + * created Aug 28, 2001 + * @author Jeka + */ +package com.intellij.refactoring.actions; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.inline.InlineHandler; + +public class InlineAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && + (elements[0] instanceof PsiMethod || elements[0] instanceof PsiPointcutDef); + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new InlineHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceConstantAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceConstantAction.java new file mode 100644 index 00000000000..3d261590950 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceConstantAction.java @@ -0,0 +1,22 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.introduceField.IntroduceConstantHandler; + +public class IntroduceConstantAction extends BaseRefactoringAction { + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new IntroduceConstantHandler(); + } + + protected boolean isAvailableInEditorOnly() { + return true; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceFieldAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceFieldAction.java new file mode 100644 index 00000000000..aacd0c175d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceFieldAction.java @@ -0,0 +1,21 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.introduceField.IntroduceFieldHandler; + +public class IntroduceFieldAction extends BaseRefactoringAction { + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new IntroduceFieldHandler(); + } + + protected boolean isAvailableInEditorOnly() { + return true; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceParameterAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceParameterAction.java new file mode 100644 index 00000000000..da5300a4071 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceParameterAction.java @@ -0,0 +1,28 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 14:03:43 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; + +public class IntroduceParameterAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return true; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new IntroduceParameterHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceVariableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceVariableAction.java new file mode 100644 index 00000000000..2ea0a60b8cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/IntroduceVariableAction.java @@ -0,0 +1,24 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler; + +/** + * + */ +public class IntroduceVariableAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return true; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new IntroduceVariableHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MakeMethodStaticAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MakeMethodStaticAction.java new file mode 100644 index 00000000000..cd2425de84e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MakeMethodStaticAction.java @@ -0,0 +1,30 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: Apr 15, 2002 + * Time: 1:32:20 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.makeMethodStatic.MakeMethodStaticHandler; + +public class MakeMethodStaticAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return false; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return (elements.length == 1) && (elements[0] instanceof PsiMethod) && + !((PsiMethod)elements[0]).isConstructor(); + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new MakeMethodStaticHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MethodDuplicatesAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MethodDuplicatesAction.java new file mode 100644 index 00000000000..93fb69b3516 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MethodDuplicatesAction.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; + +/** + * @author dsl + */ +public class MethodDuplicatesAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return true; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new MethodDuplicatesHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MigrateAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MigrateAction.java new file mode 100644 index 00000000000..22e165a35bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MigrateAction.java @@ -0,0 +1,22 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.refactoring.RefactoringManager; + +public class MigrateAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + RefactoringManager.getInstance(project).getMigrateManager().showMigrationDialog(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MoveAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MoveAction.java new file mode 100644 index 00000000000..8299e5fda79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/MoveAction.java @@ -0,0 +1,35 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.move.MoveHandler; + +public class MoveAction extends BaseRefactoringAction { + + private MoveHandler.TargetContainerFinder myFinder = new MoveHandler.TargetContainerFinder() { + public PsiElement getTargetContainer(DataContext dataContext) { + return (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT); + } + }; + + public boolean isAvailableInEditorOnly() { + return false; + } + + protected boolean isAvaiableForFile(PsiFile file){ + // move is supported for any file + return true; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return MoveHandler.canMove(elements, null); + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new MoveHandler(myFinder); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PullUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PullUpAction.java new file mode 100644 index 00000000000..8e62086d6b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PullUpAction.java @@ -0,0 +1,36 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.memberPullUp.PullUpHandler; + +public class PullUpAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + /* + if (elements.length == 1) { + return elements[0] instanceof PsiClass || elements[0] instanceof PsiField || elements[0] instanceof PsiMethod; + } + else if (elements.length > 1){ + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiField || element instanceof PsiMethod)) return false; + } + return true; + } + return false; + */ + // todo: multiple selection etc + return elements.length == 1 && elements[0] instanceof PsiClass; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new PullUpHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PushDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PushDownAction.java new file mode 100644 index 00000000000..3e34927aaa1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/PushDownAction.java @@ -0,0 +1,37 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.memberPushDown.PushDownHandler; + + +public class PushDownAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + /* + if (elements.length == 1) { + return elements[0] instanceof PsiClass || elements[0] instanceof PsiField || elements[0] instanceof PsiMethod; + } + else if (elements.length > 1){ + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiField || element instanceof PsiMethod)) return false; + } + return true; + } + return false; + */ + // todo: multiple selection etc + return elements.length == 1 && elements[0] instanceof PsiClass; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new PushDownHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/RenameElementAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/RenameElementAction.java new file mode 100644 index 00000000000..b3d6dbc1eae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/RenameElementAction.java @@ -0,0 +1,54 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.fileTypes.FileTypeSupportCapabilities; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.impl.source.jsp.JspxFileImpl; +import com.intellij.psi.xml.XmlFile; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.rename.RenameHandlerRegistry; +import com.intellij.xml.util.XmlUtil; + +public class RenameElementAction extends BaseRefactoringAction { + + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + if (elements.length != 1) return false; + + PsiElement element = elements[0]; + + if (element instanceof PsiNamedElement) + return true; + + if (element.getContainingFile() instanceof XmlFile){ + XmlFile xmlFile = (XmlFile)element.getContainingFile(); + return XmlUtil.isInAntBuildFile(xmlFile); + } + + return false; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return RenameHandlerRegistry.getInstance().getRenameHandler(dataContext); + } + + protected boolean isEnabledOnDataContext(DataContext dataContext) { + return RenameHandlerRegistry.getInstance().getRenameHandler(dataContext) != null; + } + + protected boolean isAvaiableForFile(PsiFile file) { + final FileTypeSupportCapabilities supportCapabilities = file.getFileType().getSupportCapabilities(); + + if (supportCapabilities != null && supportCapabilities.hasRename()) { + return true; + } + + if (file instanceof XmlFile) return true; + return super.isAvaiableForFile(file); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java new file mode 100644 index 00000000000..74759a1975a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java @@ -0,0 +1,27 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryHandler; + +/** + * @author dsl + */ +public class ReplaceConstructorWithFactoryAction extends BaseRefactoringAction { + protected boolean isAvailableInEditorOnly() { + return false; + } + + protected boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && + ((elements[0] instanceof PsiMethod && ((PsiMethod) elements[0]).isConstructor()) || + (elements[0] instanceof PsiClass)); + } + + protected RefactoringActionHandler getHandler(DataContext dataContext) { + return new ReplaceConstructorWithFactoryHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/SafeDeleteAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/SafeDeleteAction.java new file mode 100644 index 00000000000..dcb6537813e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/SafeDeleteAction.java @@ -0,0 +1,36 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.j2ee.j2eeDom.ejb.CmpField; +import com.intellij.j2ee.j2eeDom.ejb.CmrField; +import com.intellij.j2ee.module.view.J2EEProjectViewPane; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; + +public class SafeDeleteAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if(!SafeDeleteProcessor.validElement(element)) return false; + } + return true; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new SafeDeleteHandler(); + } + + protected boolean isEnabledOnDataContext(DataContext dataContext) { + final Object ejbElement = dataContext.getData(J2EEProjectViewPane.SELECTED_ELEMENT); + // CMP/CMR fields should be deleted from EjbImpl View + if (ejbElement instanceof CmpField || ejbElement instanceof CmrField) return false; + return super.isEnabledOnDataContext(dataContext); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TempWithQueryAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TempWithQueryAction.java new file mode 100644 index 00000000000..54ee96f8e4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TempWithQueryAction.java @@ -0,0 +1,21 @@ + +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.tempWithQuery.TempWithQueryHandler; + +public class TempWithQueryAction extends BaseRefactoringAction{ + public boolean isAvailableInEditorOnly() { + return true; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return false; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new TempWithQueryHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TurnRefsToSuperAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TurnRefsToSuperAction.java new file mode 100644 index 00000000000..09ed674cd0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TurnRefsToSuperAction.java @@ -0,0 +1,21 @@ +package com.intellij.refactoring.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperHandler; + +public class TurnRefsToSuperAction extends BaseRefactoringAction { + public boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + return elements.length == 1 && elements[0] instanceof PsiClass; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return new TurnRefsToSuperHandler(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TypeCookAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TypeCookAction.java new file mode 100644 index 00000000000..7644cefcea5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/actions/TypeCookAction.java @@ -0,0 +1,59 @@ +package com.intellij.refactoring.actions; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.typeCook.TypeCookHandler; + +public class TypeCookAction extends BaseRefactoringAction { + + protected boolean isAvailableInEditorOnly() { + return false; + } + + public boolean isAvailableInEditorOnlyTyp() { + return false; + } + + public boolean isAvaiableForFile(PsiFile file) { + return isEnabledOnElements(new PsiElement[]{file}); + } + + public boolean isEnabledOnElements(PsiElement[] elements) { + Project project = (Project)DataManager.getInstance().getDataContext().getData(DataConstants.PROJECT); + + if (project == null) { + return false; + } + LanguageLevel languageLevel = PsiManager.getInstance(project).getEffectiveLanguageLevel(); + if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) return false; + + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + + if ( + !(element instanceof PsiClass || + element instanceof PsiJavaFile || + element instanceof PsiDirectory || + element instanceof PsiPackage + ) + ) { + return false; + } + } + + return true; + } + + public RefactoringActionHandler getHandler(DataContext dataContext) { + return getHandler(); + } + public RefactoringActionHandler getHandler() { + return new TypeCookHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java new file mode 100644 index 00000000000..88f1793ff8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java @@ -0,0 +1,217 @@ + +package com.intellij.refactoring.anonymousToInner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.util.Map; + +class AnonymousToInnerDialog extends DialogWrapper{ + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.anonymousToInner.AnonymousToInnerDialog"); + + private final Project myProject; + private final PsiAnonymousClass myAnonClass; + private final boolean myNeedsThis; + + private EditorTextField myNameField; + private final ParameterTablePanel.VariableData[] myVariableData; + private Map myVariableToInfoMap = new HashMap(); + private static final String REFACTORING_NAME = "Convert Anonymous to Inner"; + private JCheckBox myCbMakeStatic; + + public AnonymousToInnerDialog(Project project, PsiAnonymousClass anonClass, final VariableInfo[] variableInfos, + boolean needsThis) { + super(project, true); + myProject = project; + myAnonClass = anonClass; + myNeedsThis = needsThis; + + setTitle(REFACTORING_NAME); + + for (int idx = 0; idx < variableInfos.length; idx++) { + VariableInfo info = variableInfos[idx]; + myVariableToInfoMap.put(info.variable, info); + } + myVariableData = new ParameterTablePanel.VariableData[variableInfos.length]; + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + for(int idx = 0; idx < variableInfos.length; idx++){ + VariableInfo info = variableInfos[idx]; + String name = info.variable.getName(); + VariableKind kind = codeStyleManager.getVariableKind(info.variable); + name = codeStyleManager.variableNameToPropertyName(name, kind); + name = codeStyleManager.propertyNameToVariableName(name, VariableKind.PARAMETER); + ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(info.variable); + data.name = name; + data.passAsParameter = true; + myVariableData[idx] = data; + } + + init(); + + String name = myAnonClass.getBaseClassReference().getReferenceName(); + name = "My" + name; //? + myNameField.setText(name); + myNameField.selectAll(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + public boolean isMakeStatic() { + if(myNeedsThis) { + return false; + } + else { + return myCbMakeStatic.isSelected(); + } + } + + public String getClassName() { + return myNameField.getText().trim(); + } + + public VariableInfo[] getVariableInfos() { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + VariableInfo[] infos = new VariableInfo[myVariableData.length]; + for (int idx = 0; idx < myVariableData.length; idx++) { + ParameterTablePanel.VariableData data = myVariableData[idx]; + VariableInfo info = myVariableToInfoMap.get(data.variable); + + info.passAsParameter = data.passAsParameter; + info.parameterName = data.name; + info.parameterName = data.name; + String propertyName = codeStyleManager.variableNameToPropertyName(data.name, VariableKind.PARAMETER); + info.fieldName = codeStyleManager.propertyNameToVariableName(propertyName, VariableKind.FIELD); + + infos[idx] = info; + } + return infos; + } + + protected void doOKAction(){ + String errorString = null; + final String innerClassName = getClassName(); + final PsiManager manager = PsiManager.getInstance(myProject); + if ("".equals(innerClassName)) { + errorString = "Class name should be specified"; + } + else if (!manager.getNameHelper().isIdentifier(innerClassName)) { + errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(innerClassName); + } + else{ + PsiElement targetContainer = AnonymousToInnerHandler.findTargetContainer(myAnonClass); + if (targetContainer instanceof PsiClass) { + PsiClass targetClass = (PsiClass)targetContainer; + PsiClass[] innerClasses = targetClass.getInnerClasses(); + for (int idx = 0; idx < innerClasses.length; idx++) { + PsiClass innerClass = innerClasses[idx]; + if (innerClassName.equals(innerClass.getName())) { + errorString = + "Inner class named '" + innerClassName + "' is already defined\n" + + "in the class " + targetClass.getName(); + break; + } + } + } + else { + LOG.assertTrue(false); + } + } + + if (errorString != null) { + RefactoringMessageUtil.showErrorMessage( + REFACTORING_NAME, + errorString, + HelpID.ANONYMOUS_TO_INNER, + myProject); + myNameField.requestFocusInWindow(); + return; + } + super.doOKAction(); + myNameField.requestFocusInWindow(); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.anchor = GridBagConstraints.EAST; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + JLabel namePrompt = new JLabel("Class name: "); + panel.add(namePrompt, gbConstraints); + + myNameField = new EditorTextField(""); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 1; + gbConstraints.gridx = 1; + gbConstraints.gridy = 0; + panel.add(myNameField, gbConstraints); + + if(!myNeedsThis) { + myCbMakeStatic = new NonFocusableCheckBox("Make class static"); + myCbMakeStatic.setMnemonic(KeyEvent.VK_S); + myCbMakeStatic.setDisplayedMnemonicIndex(11); + gbConstraints.gridx = 0; + gbConstraints.gridy++; + gbConstraints.gridwidth = 2; + panel.add(myCbMakeStatic, gbConstraints); + myCbMakeStatic.setSelected(true); + } + return panel; + } + + private JComponent createParametersPanel() { + JPanel panel = new ParameterTablePanel(myProject, myVariableData) { + protected void updateSignature() { + } + + protected void doEnterAction() { + AnonymousToInnerDialog.this.clickDefaultButton(); + } + + protected void doCancelAction() { + AnonymousToInnerDialog.this.doCancelAction(); + } + }; + panel.setBorder(IdeBorderFactory.createTitledBorder("Constructor Parameters")); + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(createParametersPanel(), BorderLayout.CENTER); + return panel; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.ANONYMOUS_TO_INNER); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java new file mode 100644 index 00000000000..2697dbe061a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java @@ -0,0 +1,491 @@ +package com.intellij.refactoring.anonymousToInner; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.text.BlockSupport; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.ElementNeedsThis; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class AnonymousToInnerHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler"); + + private static final String REFACTORING_NAME = "Convert Anonymous to Inner"; + + private Project myProject; + + private PsiManager myManager; + + private PsiAnonymousClass myAnonClass; + private PsiClass myTargetClass; + + private VariableInfo[] myVariableInfos; + private AnonymousToInnerDialog myDialog; + private boolean myMakeStatic; + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + } + + public void invoke(final Project project, Editor editor, final PsiFile file, DataContext dataContext) { + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return; + } + + final int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + final PsiAnonymousClass anonymousClass = findAnonymousClass(file, offset); + if (anonymousClass == null) { + RefactoringMessageUtil.showErrorMessage( + REFACTORING_NAME, + "Cannot perform the refactoring.\nThe caret should be positioned inside the anonymous class.", + HelpID.ANONYMOUS_TO_INNER, + project); + return; + } + invoke(project, anonymousClass); + } + + public void invoke(final Project project, final PsiAnonymousClass anonymousClass) { + myProject = project; + + myManager = PsiManager.getInstance(myProject); + myAnonClass = anonymousClass; + + PsiClassType baseRef = myAnonClass.getBaseClassType(); + + if (baseRef.resolve() == null) { + String message = "Cannot resolve " + baseRef.getCanonicalText(); + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ANONYMOUS_TO_INNER, project); + return; + } + PsiElement targetContainer = findTargetContainer(myAnonClass); + if (targetContainer instanceof JspFile) { + String message = REFACTORING_NAME + " refactoring is not supported for JSP"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ANONYMOUS_TO_INNER, project); + return; + } + boolean condition = targetContainer instanceof PsiClass; + LOG.assertTrue(condition); + myTargetClass = (PsiClass) targetContainer; + + if (!myTargetClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, myTargetClass); + return; + } + + HashMap variableInfoMap = new HashMap(); + ArrayList variableInfoVector = new ArrayList(); + collectUsedVariables(variableInfoMap, variableInfoVector, myAnonClass); + myVariableInfos = variableInfoVector.toArray(new VariableInfo[variableInfoVector.size()]); + final boolean needsThis = needsThis() || PsiUtil.isInnerClass(myTargetClass); + myDialog = new AnonymousToInnerDialog( + myProject, + myAnonClass, + myVariableInfos, + needsThis); + myDialog.show(); + if (!myDialog.isOK()) { + return; + } + myVariableInfos = myDialog.getVariableInfos(); + myMakeStatic = myDialog.isMakeStatic(); + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + doRefactoring(); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + REFACTORING_NAME, + null + ); + + } + + private void doRefactoring() throws IncorrectOperationException { + PsiClass aClass = createClass(myDialog.getClassName()); + myTargetClass.add(aClass); + + PsiNewExpression newExpr = (PsiNewExpression) myAnonClass.getParent(); + StringBuffer buf = new StringBuffer("new "); + buf.append(aClass.getName()); + buf.append("("); + boolean isFirstParameter = true; + for (int idx = 0; idx < myVariableInfos.length; idx++) { + VariableInfo info = myVariableInfos[idx]; + if (info.passAsParameter) { + if (isFirstParameter) { + isFirstParameter = false; + } else { + buf.append(","); + } + buf.append(info.variable.getName()); + } + } + buf.append(")"); + PsiExpression newClassExpression = myManager.getElementFactory().createExpressionFromText(buf.toString(), null); + newClassExpression = (PsiExpression) CodeStyleManager.getInstance(myProject).reformat(newClassExpression); + newExpr.replace(newClassExpression); + } + + private PsiAnonymousClass findAnonymousClass(PsiFile file, int offset) { + PsiElement element = file.findElementAt(offset); + while (element != null) { + if (element instanceof PsiAnonymousClass) { + return (PsiAnonymousClass) element; + } + element = element.getParent(); + } + return null; + } + + public static PsiElement findTargetContainer(PsiAnonymousClass anonClass) { + PsiElement parent = anonClass.getParent(); + while (true) { + if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { + return parent; + } + if (parent instanceof PsiFile) { + return parent; + } + parent = parent.getParent(); + } + } + + private void collectUsedVariables(HashMap variableInfoMap, ArrayList variableInfoVector, PsiElement scope) { + if (scope instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression) scope; + if (refExpr.getQualifierExpression() == null) { + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiVariable) { + PsiVariable var = (PsiVariable) refElement; + PsiElement parent = var.getParent(); + while (true) { + if (parent instanceof PsiFile) break; + if (myAnonClass.equals(parent)) break; + if (myTargetClass.equals(parent.getParent())) { + saveVariable(variableInfoMap, variableInfoVector, var, refExpr); + break; + } + parent = parent.getParent(); + } + } + } + } + + PsiElement[] children = scope.getChildren(); + for (int idx = 0; idx < children.length; idx++) { + collectUsedVariables(variableInfoMap, variableInfoVector, children[idx]); + } + } + + private Boolean cachedNeedsThis = null; + private boolean needsThis() { + if(cachedNeedsThis == null) { + + ElementNeedsThis memberNeedsThis = new ElementNeedsThis(myTargetClass, myAnonClass); + myAnonClass.accept(memberNeedsThis); + class HasExplicitThis extends PsiRecursiveElementVisitor { + boolean hasExplicitThis = false; + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitThisExpression(PsiThisExpression expression) { + hasExplicitThis = true; + } + } + final HasExplicitThis hasExplicitThis = new HasExplicitThis(); + ((PsiNewExpression) myAnonClass.getParent()).getArgumentList().accept(hasExplicitThis); + cachedNeedsThis = new Boolean(memberNeedsThis.usesMembers() || hasExplicitThis.hasExplicitThis); + } + return cachedNeedsThis.booleanValue(); + } + + + private void saveVariable(HashMap variableInfoMap, ArrayList variableInfoVector, PsiVariable var, PsiReferenceExpression usage) { + VariableInfo info = variableInfoMap.get(var); + if (info == null) { + info = new VariableInfo(var); + variableInfoMap.put(var, info); + variableInfoVector.add(info); + } + if (!isUsedInInitializer(usage)) { + info.saveInField = true; + } + } + + private boolean isUsedInInitializer(PsiElement usage) { + PsiElement parent = usage.getParent(); + while (!myAnonClass.equals(parent)) { + if (parent instanceof PsiExpressionList) { + PsiExpressionList expressionList = (PsiExpressionList) parent; + if (myAnonClass.equals(expressionList.getParent())) { + return true; + } + } else if (parent instanceof PsiClassInitializer && myAnonClass.equals(((PsiClassInitializer)parent).getContainingClass())) { + //class initializers will be moved to constructor to be generated + return true; + } + parent = parent.getParent(); + } + return false; + } + + private PsiClass createClass(String name) throws IncorrectOperationException { + PsiElementFactory factory = myAnonClass.getManager().getElementFactory(); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + final PsiNewExpression newExpression = (PsiNewExpression) myAnonClass.getParent(); + final PsiMethod superConstructor = newExpression.resolveConstructor(); + + PsiClass aClass = factory.createClass(name); + if (!myTargetClass.isInterface()) { + aClass.getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + } + PsiModifierListOwner owner = PsiTreeUtil.getParentOfType(myAnonClass, PsiModifierListOwner.class); + if (owner != null && owner.hasModifierProperty(PsiModifier.STATIC)) { + aClass.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + PsiJavaCodeReferenceElement baseClassRef = myAnonClass.getBaseClassReference(); + PsiClass baseClass = (PsiClass)baseClassRef.resolve(); + if (baseClass != null && baseClass.isInterface()) { + aClass.getImplementsList().add(baseClassRef); + } + else { + aClass.getExtendsList().add(baseClassRef); + } + + renameReferences(myAnonClass); + copyClassBody(myAnonClass, aClass, myVariableInfos.length > 0); + + if (myVariableInfos.length > 0) { + createFields(aClass); + } + + PsiExpressionList exprList = newExpression.getArgumentList(); + PsiExpression[] originalExpressions = exprList.getExpressions(); + final PsiReferenceList superConstructorThrowsList = + superConstructor != null && superConstructor.getThrowsList().getReferencedTypes().length > 0 + ? superConstructor.getThrowsList() + : null; + if (myVariableInfos.length > 0 || originalExpressions.length > 0 || superConstructorThrowsList != null) { + PsiMethod constructor = factory.createConstructor(); + if (superConstructorThrowsList != null) { + constructor.getThrowsList().replace(superConstructorThrowsList); + } + if (originalExpressions.length > 0) { + createSuperStatement(constructor, originalExpressions); + } + if (myVariableInfos.length > 0) { + fillParameterList(constructor); + createAssignmentStatements(constructor); + + appendClassInitializers(constructor); + } + + constructor = (PsiMethod) codeStyleManager.reformat(constructor); + aClass.add(constructor); + } + + if (!needsThis() && myMakeStatic) { + aClass.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + PsiElement lastChild = aClass.getLastChild(); + if (lastChild instanceof PsiJavaToken && ((PsiJavaToken)lastChild).getTokenType() == JavaTokenType.SEMICOLON) { + lastChild.delete(); + } + + return aClass; + } + + private void appendClassInitializers(final PsiMethod constructor) throws IncorrectOperationException { + final PsiClassInitializer[] initializers = myAnonClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + PsiClassInitializer initializer = initializers[i]; + if (!initializer.hasModifierProperty(PsiModifier.STATIC)) { + final PsiCodeBlock body = initializer.getBody(); + if (body != null) { + final PsiJavaToken lBrace = body.getLBrace(); + final PsiJavaToken rBrace = body.getRBrace(); + constructor.getBody().addRange(lBrace.getNextSibling(), rBrace == null ? body.getLastChild() : rBrace.getPrevSibling()); + } + } + } + } + + private static void copyClassBody(PsiClass sourceClass, + PsiClass targetClass, + boolean appendClassInitializersToConstructor) throws IncorrectOperationException { + PsiElement lbrace = sourceClass.getLBrace(); + PsiElement rbrace = sourceClass.getRBrace(); + if (lbrace != null) { + targetClass.addRange(lbrace.getNextSibling(), rbrace != null ? rbrace.getPrevSibling() : sourceClass.getLastChild()); + if (appendClassInitializersToConstructor) { //see SCR 41692 + final PsiClassInitializer[] initializers = targetClass.getInitializers(); + for (int i = 0; i < initializers.length; i++) { + PsiClassInitializer initializer = initializers[i]; + if (!initializer.hasModifierProperty(PsiModifier.STATIC)) initializer.delete(); + } + } + } + } + + private void fillParameterList(PsiMethod constructor) throws IncorrectOperationException { + PsiElementFactory factory = constructor.getManager().getElementFactory(); + PsiParameterList parameterList = constructor.getParameterList(); + for (int i = 0; i < myVariableInfos.length; i++) { + VariableInfo info = myVariableInfos[i]; + if (info.passAsParameter) { + PsiParameter parameter = factory.createParameter(info.parameterName, info.variable.getType()); + parameterList.add(parameter); + } + } + } + + private void createFields(PsiClass aClass) throws IncorrectOperationException { + PsiElementFactory factory = myManager.getElementFactory(); + for (int i = 0; i < myVariableInfos.length; i++) { + VariableInfo info = myVariableInfos[i]; + if (info.saveInField) { + PsiField field = factory.createField(info.fieldName, info.variable.getType()); + field.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + aClass.add(field); + } + } + } + + private void createAssignmentStatements(PsiMethod constructor) throws IncorrectOperationException { + PsiElementFactory factory = constructor.getManager().getElementFactory(); + for (int i = 0; i < myVariableInfos.length; i++) { + VariableInfo info = myVariableInfos[i]; + if (info.saveInField) { + String text = info.fieldName + "=a;"; + boolean useThis = info.passAsParameter && info.parameterName.equals(info.fieldName); + if (useThis) { + text = "this." + text; + } + PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(text, null); + statement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(statement); + // in order for "..." trick to work, the statement must be added to constructor first + statement = (PsiExpressionStatement)constructor.getBody().add(statement); + + PsiAssignmentExpression assignment = (PsiAssignmentExpression) statement.getExpression(); + PsiReferenceExpression rExpr = (PsiReferenceExpression) assignment.getRExpression(); + PsiIdentifier identifier = (PsiIdentifier) rExpr.getReferenceNameElement(); + if (info.passAsParameter) { + identifier.replace(factory.createIdentifier(info.parameterName)); + } else { + TextRange range = rExpr.getTextRange(); + BlockSupport blockSupport = myProject.getComponent(BlockSupport.class); + blockSupport.reparseRange(statement.getContainingFile(), range.getStartOffset(), range.getEndOffset(), "..."); + } + } + } + } + + private void renameReferences(PsiElement scope) throws IncorrectOperationException { + PsiSearchHelper helper = myManager.getSearchHelper(); + PsiElementFactory factory = myManager.getElementFactory(); + for (int i = 0; i < myVariableInfos.length; i++) { + VariableInfo info = myVariableInfos[i]; + PsiReference[] references = helper.findReferences(info.variable, new LocalSearchScope(scope), false); + if (references.length > 0) { + for (int j = 0; j < references.length; j++) { + PsiElement ref = references[j].getElement(); + PsiIdentifier identifier = (PsiIdentifier) ((PsiJavaCodeReferenceElement) ref).getReferenceNameElement(); + boolean renameToFieldName = !isUsedInInitializer(ref); + PsiIdentifier newNameIdentifier = factory.createIdentifier(renameToFieldName? info.fieldName : info.parameterName); + if (renameToFieldName) { + identifier.replace(newNameIdentifier); + } else { + if (info.passAsParameter) { + identifier.replace(newNameIdentifier); + /*} else { + PsiCodeBlock dummyBlock = factory.createCodeBlockFromText("{...}", null); + PsiElement[] children = dummyBlock.getChildren(); + identifier.replace(children[1]); + ref.addRange(children[2], children[children.length - 2]);*/ + } + } + } + } + } + } + + private void createSuperStatement(PsiMethod constructor, PsiExpression[] paramExpressions) throws IncorrectOperationException { + PsiCodeBlock body = constructor.getBody(); + final PsiElementFactory factory = constructor.getManager().getElementFactory(); + + PsiStatement statement = factory.createStatementFromText("super();", null); + statement = (PsiStatement) CodeStyleManager.getInstance(myProject).reformat(statement); + statement = (PsiStatement) body.add(statement); + + PsiMethodCallExpression methodCall = (PsiMethodCallExpression) ((PsiExpressionStatement) statement).getExpression(); + PsiExpressionList exprList = methodCall.getArgumentList(); + + + { + final PsiThisExpression qualifiedThis = + (PsiThisExpression) factory.createExpressionFromText("A.this", null); + final PsiJavaCodeReferenceElement targetClassRef = factory.createClassReferenceElement(myTargetClass); + qualifiedThis.getQualifier().replace(targetClassRef); + + for (int idx = 0; idx < paramExpressions.length; idx++) { + PsiExpression expr = paramExpressions[idx]; + ChangeContextUtil.encodeContextInfo(expr, true); + final PsiElement newExpr = exprList.add(expr); + ChangeContextUtil.decodeContextInfo(newExpr, myTargetClass, qualifiedThis); + } + } + + class SupersConvertor extends PsiRecursiveElementVisitor { + public void visitThisExpression(PsiThisExpression expression) { + try { + final PsiThisExpression qualifiedThis = + (PsiThisExpression) factory.createExpressionFromText("A.this", null); + final PsiJavaCodeReferenceElement targetClassRef = factory.createClassReferenceElement(myTargetClass); + qualifiedThis.getQualifier().replace(targetClassRef); + expression.replace(qualifiedThis); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + } + + final SupersConvertor supersConvertor = new SupersConvertor(); + methodCall.getArgumentList().accept(supersConvertor); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/VariableInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/VariableInfo.java new file mode 100644 index 00000000000..e8084e25d38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/anonymousToInner/VariableInfo.java @@ -0,0 +1,19 @@ +/** + * created at Sep 7, 2001 + * @author Jeka + */ +package com.intellij.refactoring.anonymousToInner; + +import com.intellij.psi.*; + +public class VariableInfo { + public PsiVariable variable; + public boolean saveInField = false; + public boolean passAsParameter = true; + public String parameterName; + public String fieldName; + + public VariableInfo(PsiVariable variable) { + this.variable = variable; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java new file mode 100644 index 00000000000..856cbfcfda0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java @@ -0,0 +1,255 @@ +package com.intellij.refactoring.changeClassSignature; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.*; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.*; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +public class ChangeClassSignatureDialog extends BaseRefactoringDialog { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeClassSignature.ChangeClassSignatureDialog"); + private static final int NAME_COLUMN = 0; + private static final int VALUE_COLUMN = 1; + + private final List myTypeParameterInfos; + private final List myTypeCodeFragments; + private final PsiClass myClass; + private final PsiTypeParameter[] myOriginalParameters; + private final PsiManager myManager; + private final MyTableModel myTableModel; + private Table myTable; + + public ChangeClassSignatureDialog(PsiClass aClass) { + super(aClass.getProject(), true); + setTitle("Change Class Signature"); + myClass = aClass; + myManager = myClass.getManager(); + myTypeParameterInfos = new ArrayList(); + myTypeCodeFragments = new ArrayList(); + myOriginalParameters = myClass.getTypeParameters(); + for (int i = 0; i < myOriginalParameters.length; i++) { + myTypeParameterInfos.add(new TypeParameterInfo(i)); + myTypeCodeFragments.add(null); + } + myTableModel = new MyTableModel(); + init(); + } + + private PsiTypeCodeFragment createValueCodeFragment() { + return myManager.getElementFactory().createTypeCodeFragment( + "", + myClass.getLBrace(), + false, true, false + ); + } + + protected JComponent createNorthPanel() { + Box box = Box.createHorizontalBox(); + JLabel label = new JLabel("Change signature of " + UsageViewUtil.getDescriptiveName(myClass)); + box.add(label); + box.add(Box.createHorizontalGlue()); + return box; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.CHANGE_CLASS_SIGNATURE); + } + + protected JComponent createCenterPanel() { + myTable = new Table(myTableModel); + TableColumn nameColumn = myTable.getColumnModel().getColumn(NAME_COLUMN); + TableColumn valueColumn = myTable.getColumnModel().getColumn(VALUE_COLUMN); + Project project = myClass.getProject(); + nameColumn.setCellRenderer(new MyCellRenderer()); + nameColumn.setCellEditor(new StringTableCellEditor(project)); + valueColumn.setCellRenderer(new MyCodeFragmentTableCellRenderer()); + valueColumn.setCellEditor(new CodeFragmentTableCellEditor(project)); + EditableRowTableManager manager = new EditableRowTableManager(myTable, myTableModel, true); + + myTable.setPreferredScrollableViewportSize(new Dimension(210, myTable.getRowHeight() * 4)); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.getSelectionModel().setSelectionInterval(0, 0); + myTable.setSurrendersFocusOnKeystroke(true); + myTable.setFocusCycleRoot(true); + + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(IdeBorderFactory.createTitledBorder("Parameters")); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + + panel.add(scrollPane, BorderLayout.CENTER); + panel.add(manager.getButtonsPanel(), BorderLayout.EAST); + return panel; + } + + protected void doAction() { + TableUtil.stopEditing(myTable); + String message = validateAndCommitData(); + if (message != null) { + RefactoringMessageUtil.showErrorMessage("Incorrect Data", message, HelpID.CHANGE_SIGNATURE, myClass.getProject()); + return; + } + ChangeClassSignatureProcessor processor = + new ChangeClassSignatureProcessor(myClass.getProject(), myClass, + myTypeParameterInfos.toArray(new TypeParameterInfo[myTypeParameterInfos.size()])); + invokeRefactoring(processor); + } + + private String validateAndCommitData() { + for (int i = 0; i < myTypeParameterInfos.size(); i++) { + final TypeParameterInfo info = myTypeParameterInfos.get(i); + if (!info.isForExistingParameter() && !myClass.getManager().getNameHelper().isIdentifier(info.getNewName())) { + return "Wrong name: " + info.getNewName(); + } + } + LOG.assertTrue(myTypeCodeFragments.size() == myTypeParameterInfos.size()); + for (int i = 0; i < myTypeCodeFragments.size(); i++) { + final PsiTypeCodeFragment codeFragment = myTypeCodeFragments.get(i); + TypeParameterInfo info = myTypeParameterInfos.get(i); + if (info.getOldParameterIndex() >= 0) continue; + PsiType type = null; + try { + type = codeFragment.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return "Wrong default value: '" + codeFragment.getText() + "' for parameter " + info.getNewName(); + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return "Specify a type for parameter" + info.getNewName(); + } + info.setDefaultValue(type); + } + return null; + } + + private class MyTableModel extends AbstractTableModel implements RowEditableTableModel { + public int getColumnCount() { + return 2; + } + + public int getRowCount() { + return myTypeParameterInfos.size(); + } + + public Class getColumnClass(int columnIndex) { + switch(columnIndex) { + case NAME_COLUMN: + return String.class; + + default: + return null; + } + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch(columnIndex) { + case NAME_COLUMN: + TypeParameterInfo info = myTypeParameterInfos.get(rowIndex); + if (info.isForExistingParameter()) { + return myOriginalParameters[info.getOldParameterIndex()].getName(); + } + else { + return info.getNewName(); + } + case VALUE_COLUMN: + return myTypeCodeFragments.get(rowIndex); + } + LOG.assertTrue(false); + return null; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return !myTypeParameterInfos.get(rowIndex).isForExistingParameter(); + } + + public String getColumnName(int column) { + switch(column) { + case NAME_COLUMN: + return "Name"; + case VALUE_COLUMN: + return "Default Value"; + default: + LOG.assertTrue(false); + return null; + } + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + switch(columnIndex) { + case NAME_COLUMN: + myTypeParameterInfos.get(rowIndex).setNewName((String) aValue); + break; + case VALUE_COLUMN: + break; + default: + LOG.assertTrue(false); + } + } + + public void addRow() { + TableUtil.stopEditing(myTable); + myTypeParameterInfos.add(new TypeParameterInfo("", null)); + myTypeCodeFragments.add(createValueCodeFragment()); + int index = myTypeParameterInfos.size() - 1; + fireTableDataChanged(); + //fireTableRowsInserted(index, index); + } + + public void removeRow(int index) { + myTypeParameterInfos.remove(index); + myTypeCodeFragments.remove(index); + fireTableDataChanged(); + //fireTableRowsDeleted(index, index); + } + + public void exchangeRows(int index1, int index2) { + ContainerUtil.swapElements(myTypeParameterInfos, index1, index2); + ContainerUtil.swapElements(myTypeCodeFragments, index1, index2); + fireTableDataChanged(); + //fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2)); + } + } + + private class MyCellRenderer extends ColoredTableCellRenderer { + + public void customizeCellRenderer(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + if (!myTableModel.isCellEditable(row, column)) { + setBackground(getBackground().darker()); + } + append((String)value, new SimpleTextAttributes(Font.PLAIN, null)); + } + } + + private class MyCodeFragmentTableCellRenderer extends CodeFragmentTableCellRenderer { + + public MyCodeFragmentTableCellRenderer() { + super(myProject); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (!myTableModel.isCellEditable(row, column)) { + component.setBackground(component.getBackground().darker()); + } + + return component; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java new file mode 100644 index 00000000000..cebeff48aff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -0,0 +1,195 @@ +package com.intellij.refactoring.changeClassSignature; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.changeSignature.ChangeSignatureUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author dsl + */ +public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeClassSignature.ChangeClassSignatureProcessor"); + private PsiClass myClass; + private final TypeParameterInfo[] myNewSignature; + + public ChangeClassSignatureProcessor(Project project, + PsiClass aClass, + TypeParameterInfo[] newSignature) { + super(project); + myClass = aClass; + myNewSignature = newSignature; + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == 1); + LOG.assertTrue(elements[0] instanceof PsiClass); + myClass = (PsiClass) elements[0]; + } + + protected String getCommandName() { + return "Change Class Signature"; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new ChangeClassSigntaureViewDescriptor(myClass, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + PsiSearchHelper searchHelper = myClass.getManager().getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + PsiReference[] references = searchHelper.findReferences(myClass, projectScope, false); + List result = new ArrayList(); + + boolean hadTypeParameters = myClass.getTypeParameters().length > 0; + for (int i = 0; i < references.length; i++) { + final PsiReference reference = references[i]; + if (reference.getElement() instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement referenceElement = ((PsiJavaCodeReferenceElement)reference.getElement()); + PsiElement parent = referenceElement.getParent(); + if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression + || parent instanceof PsiAnonymousClass || parent instanceof PsiReferenceList) { + if (!hadTypeParameters || referenceElement.getTypeParameters().length > 0) { + result.add(new UsageInfo(referenceElement)); + } + } + } + } + return (UsageInfo[])result.toArray(new UsageInfo[result.size()]); + } + + protected void performRefactoring(UsageInfo[] usages) { + LvcsAction lvcsAction = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + try { + doRefactoring(usages); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, lvcsAction); + } + } + + private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { + final PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); + boolean[] toRemoveParms = detectRemovedParameters(typeParameters); + + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + LOG.assertTrue(usage.getElement() instanceof PsiJavaCodeReferenceElement); + processUsage(usage, typeParameters, toRemoveParms); + } + + changeClassSignature(typeParameters, toRemoveParms); + } + + private void changeClassSignature(final PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) + throws IncorrectOperationException { + PsiElementFactory factory = myClass.getManager().getElementFactory(); + List newTypeParameters = new ArrayList(); + for (int i = 0; i < myNewSignature.length; i++) { + final TypeParameterInfo info = myNewSignature[i]; + int oldIndex = info.getOldParameterIndex(); + if(oldIndex >= 0) { + newTypeParameters.add(originalTypeParameters[oldIndex]); + } + else { + newTypeParameters.add(factory.createTypeParameterFromText(info.getNewName(), null)); + } + } + ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), + newTypeParameters, + TypeParameterList.INSTANCE, + toRemoveParms); + } + + private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) { + final boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; + Arrays.fill(toRemoveParms, true); + for (int i = 0; i < myNewSignature.length; i++) { + final TypeParameterInfo info = myNewSignature[i]; + int oldParameterIndex = info.getOldParameterIndex(); + if (oldParameterIndex >= 0) { + toRemoveParms[oldParameterIndex] = false; + } + } + return toRemoveParms; + } + + private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms) + throws IncorrectOperationException { + PsiElementFactory factory = myClass.getManager().getElementFactory(); + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); + PsiSubstitutor usageSubstitutor = determineUsageSubstitutor(referenceElement); + + PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList(); + PsiTypeElement[] oldValues = referenceParameterList.getTypeParameterElements(); + if (oldValues.length != originalTypeParameters.length) return; + List newValues = new ArrayList(); + for (int j = 0; j < myNewSignature.length; j++) { + final TypeParameterInfo info = myNewSignature[j]; + int oldIndex = info.getOldParameterIndex(); + if (oldIndex >= 0) { + newValues.add(oldValues[oldIndex]); + } + else { + PsiType type = info.getDefaultValue().getType(myClass.getLBrace()); + + PsiTypeElement newValue = factory.createTypeElement(usageSubstitutor.substitute(type)); + newValues.add(newValue); + } + } + ChangeSignatureUtil.synchronizeList( + referenceParameterList, + newValues, + ReferenceParameterList.INSTANCE, toRemoveParms + ); + } + + private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement referenceElement) { + PsiType[] typeArguments = referenceElement.getTypeParameters(); + PsiSubstitutor usageSubstitutor = PsiSubstitutor.EMPTY; + PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); + if (typeParameters.length == typeArguments.length) { + for (int i = 0; i < typeParameters.length; i++) { + usageSubstitutor = usageSubstitutor.put(typeParameters[i], typeArguments[i]); + } + } + return usageSubstitutor; + } + + private static class ReferenceParameterList + implements ChangeSignatureUtil.ChildrenGenerator { + private static final ReferenceParameterList INSTANCE = new ReferenceParameterList(); + public List getChildren(PsiReferenceParameterList list) { + return Arrays.asList(list.getTypeParameterElements()); + } + } + + private static class TypeParameterList + implements ChangeSignatureUtil.ChildrenGenerator { + private static final TypeParameterList INSTANCE = new TypeParameterList(); + + public List getChildren(PsiTypeParameterList psiTypeParameterList) { + return Arrays.asList(psiTypeParameterList.getTypeParameters()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSigntaureViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSigntaureViewDescriptor.java new file mode 100644 index 00000000000..06ec541ceab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/ChangeClassSigntaureViewDescriptor.java @@ -0,0 +1,43 @@ +package com.intellij.refactoring.changeClassSignature; + +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author dsl + */ +public class ChangeClassSigntaureViewDescriptor extends UsageViewDescriptorAdapter { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeClassSignature.ChangeClassSigntaureViewDescriptor"); + private PsiClass myClass; + + public ChangeClassSigntaureViewDescriptor(PsiClass aClass, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + super(usages, refreshCommand); + myClass = aClass; + } + + public PsiElement[] getElements() { + return new PsiElement[]{myClass}; + } + + public void refresh(PsiElement[] elements) { + if (elements.length == 1 && elements[0] instanceof PsiClass) { + myClass = (PsiClass)elements[0]; + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return UsageViewUtil.capitalize(UsageViewUtil.getType(myClass)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/TypeParameterInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/TypeParameterInfo.java new file mode 100644 index 00000000000..e16a6f003d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeClassSignature/TypeParameterInfo.java @@ -0,0 +1,64 @@ +package com.intellij.refactoring.changeClassSignature; + +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiClass; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +class TypeParameterInfo { + private final int myOldParameterIndex; + private String myNewName; + private CanonicalTypes.Type myDefaultValue; + + TypeParameterInfo(int oldIndex) { + myOldParameterIndex = oldIndex; + myDefaultValue = null; + } + + TypeParameterInfo(String name, PsiType aType) { + myOldParameterIndex = -1; + myNewName = name; + if (aType != null) { + myDefaultValue = CanonicalTypes.createTypeWrapper(aType); + } + else { + myDefaultValue = null; + } + } + + TypeParameterInfo(PsiClass aClass, String name, String defaultValue) throws IncorrectOperationException { + this(name, aClass.getManager().getElementFactory().createTypeFromText(defaultValue, aClass.getLBrace())); + } + + + public int getOldParameterIndex() { + return myOldParameterIndex; + } + + public String getNewName() { + return myNewName; + } + + public void setNewName(String newName) { + myNewName = newName; + } + + public CanonicalTypes.Type getDefaultValue() { + return myDefaultValue; + } + + public void setDefaultValue(CanonicalTypes.Type defaultValue) { + myDefaultValue = defaultValue; + } + + public void setDefaultValue(PsiType aType) { + setDefaultValue(CanonicalTypes.createTypeWrapper(aType)); + } + + boolean isForExistingParameter() { + return myOldParameterIndex >= 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeInfo.java new file mode 100644 index 00000000000..885428b7a23 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeInfo.java @@ -0,0 +1,189 @@ +/** + * created at Sep 17, 2001 + * @author Jeka + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.util.IncorrectOperationException; + +import java.util.Arrays; + +class ChangeInfo { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeInfo"); + + final String newVisibility; + private PsiMethod method; + final String oldName; + final String oldType; + final String[] oldParameterNames; + final String[] oldParameterTypes; + final String newName; + final CanonicalTypes.Type newReturnType; + final ParameterInfo[] newParms; + final ThrownExceptionInfo[] newExceptions; + final boolean[] toRemoveParm; + boolean isVisibilityChanged = false; + boolean isNameChanged = false; + boolean isReturnTypeChanged = false; + boolean isParameterSetOrOrderChanged = false; + boolean isExceptionSetChanged = false; + boolean isExceptionSetOrOrderChanged = false; + boolean isParameterNamesChanged = false; + boolean isParameterTypesChanged = false; + final boolean wasVararg; + final boolean retainsVarargs; + final boolean obtainsVarags; + PsiIdentifier newNameIdentifier; + PsiType newTypeElement; + PsiExpression[] defaultValues; + final EjbMethodRole ejbRole; + + /** + * @param newExceptions null if not changed + */ + public ChangeInfo(String newVisibility, + PsiMethod method, + String newName, + CanonicalTypes.Type newType, + ParameterInfo[] newParms, + ThrownExceptionInfo[] newExceptions) { + this.newVisibility = newVisibility; + this.method = method; + this.newName = newName; + this.newReturnType = newType; + this.newParms = newParms; + wasVararg = method.isVarArgs(); + + this.oldName = method.getName(); + if (!method.isConstructor()){ + this.oldType = method.getManager().getElementFactory().createTypeElement(method.getReturnType()).getText(); + } + else{ + this.oldType = null; + } + PsiParameter[] parameters = method.getParameterList().getParameters(); + this.oldParameterNames = new String[parameters.length]; + this.oldParameterTypes = new String[parameters.length]; + for(int i = 0; i < parameters.length; i++){ + PsiParameter parameter = parameters[i]; + this.oldParameterNames[i] = parameter.getName(); + this.oldParameterTypes[i] = parameter.getManager().getElementFactory().createTypeElement(parameter.getType()).getText(); + } + + this.isVisibilityChanged = !method.hasModifierProperty(newVisibility); + + this.isNameChanged = !newName.equals(oldName); + if (!method.isConstructor()){ + try { + this.isReturnTypeChanged = !newReturnType.getType(this.method).equals(this.method.getReturnType()); + } + catch (IncorrectOperationException e) { + this.isReturnTypeChanged = true; + } + } + if (parameters.length != newParms.length){ + this.isParameterSetOrOrderChanged = true; + } + else{ + for(int i = 0; i < newParms.length; i++){ + ParameterInfo parmInfo = newParms[i]; + PsiParameter parameter = parameters[i]; + if (i != parmInfo.oldParameterIndex){ + this.isParameterSetOrOrderChanged = true; + break; + } + if (!parmInfo.getName().equals(parameter.getName())){ + this.isParameterNamesChanged = true; + } + try { + if (!parmInfo.createType(method).equals(parameter.getType())){ + this.isParameterTypesChanged = true; + } + } + catch (IncorrectOperationException e) { + this.isParameterTypesChanged = true; + } + } + } + + if (newExceptions == null) newExceptions = extractExceptions(method); + + this.newExceptions = newExceptions; + + PsiClassType[] types = method.getThrowsList().getReferencedTypes(); + isExceptionSetChanged = newExceptions.length != types.length; + if (!isExceptionSetChanged) { + for (int i = 0; i < newExceptions.length; i++) { + try { + if (newExceptions[i].oldIndex < 0 || !types[i].equals(newExceptions[i].myType.getType(method))) { + isExceptionSetChanged = true; + break; + } + } + catch (IncorrectOperationException e) { + isExceptionSetChanged = true; + } + if (newExceptions[i].oldIndex != i) isExceptionSetOrOrderChanged = true; + } + } + + isExceptionSetOrOrderChanged |= isExceptionSetChanged; + + this.toRemoveParm = new boolean[parameters.length]; + Arrays.fill(this.toRemoveParm, true); + for(int i = 0; i < newParms.length; i++){ + ParameterInfo info = newParms[i]; + if (info.oldParameterIndex < 0) continue; + this.toRemoveParm[info.oldParameterIndex] = false; + } + + PsiElementFactory factory = method.getManager().getElementFactory(); + this.defaultValues = new PsiExpression[newParms.length]; + for(int i = 0; i < newParms.length; i++){ + ParameterInfo info = newParms[i]; + if (info.oldParameterIndex < 0 && !info.isVarargType()){ + try{ + this.defaultValues[i] = factory.createExpressionFromText(info.defaultValue, method); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + } + + if (this.newParms.length == 0) { + retainsVarargs = false; + obtainsVarags = false; + } + else { + final ParameterInfo lastNewParm = this.newParms[this.newParms.length - 1]; + obtainsVarags = lastNewParm.isVarargType(); + retainsVarargs = lastNewParm.oldParameterIndex >= 0 && obtainsVarags; + } + + ejbRole = J2EERolesUtil.getEjbRole(method); + } + + //create identity mapping + private static ThrownExceptionInfo[] extractExceptions(PsiMethod method) { + PsiClassType[] types = method.getThrowsList().getReferencedTypes(); + ThrownExceptionInfo[] result = new ThrownExceptionInfo[types.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new ThrownExceptionInfo(i, types[i]); + } + return result; + } + + public PsiMethod getMethod() { + return method; + } + + public void updateMethod(PsiMethod method) { + this.method = method; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java new file mode 100644 index 00000000000..352d680351b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java @@ -0,0 +1,666 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.CharFilter; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.ui.*; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.ui.*; +import com.intellij.util.Alarm; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.StringTokenizer; + +public class ChangeSignatureDialog extends RefactoringDialog { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.changeSignature.ChangeSignatureDialog"); + private Project myProject; + private PsiMethod myMethod; + private final Callback myCallback; + private final boolean myAllowDelegation; + private EditorTextField myNameField; + private EditorTextField myReturnTypeField; + private JTable myParametersTable; + private ParameterTableModel myParametersTableModel; + private JTextArea mySignatureArea; + private Alarm myUpdateSignatureAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + private VisibilityPanel myVisibilityPanel; + private PsiTypeCodeFragment myReturnTypeCodeFragment; + private DelegationPanel myDelegationPanel; + private JTable myExceptionsTable; + private ExceptionsTableModel myExceptionsTableModel; + + public interface Callback { + void run(ChangeSignatureDialog dialog); + } + + public ChangeSignatureDialog(Project project, PsiMethod method, boolean allowDelegation, Callback callback) { + super(project, true); + myProject = project; + myMethod = method; + myParametersTableModel = new ParameterTableModel(myMethod.getParameterList(), this); + myExceptionsTableModel = new ExceptionsTableModel(myMethod.getThrowsList()); + myCallback = callback; + myAllowDelegation = allowDelegation; + + setParameterInfos(getParameterInfos(method)); + myExceptionsTableModel.setTypeInfos(method); + + setTitle("Change Method Signature"); + init(); + doUpdateSignature(); + } + + public void setParameterInfos(List parameterInfos) { + myParametersTableModel.setParameterInfos(parameterInfos, myMethod.getParameterList()); + updateSignature(); + } + + private static List getParameterInfos(PsiMethod method) { + final ArrayList result = new ArrayList(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + ParameterInfo info = new ParameterInfo(i, parameter.getName(), parameter.getType()); + info.defaultValue = ""; + result.add(info); + } + return result; + } + + public String getMethodName() { + if (myNameField != null) { + return myNameField.getText().trim(); + } + else { + return myMethod.getName(); + } + } + + public CanonicalTypes.Type getReturnType() { + if (myReturnTypeField != null) { + try { + final PsiType type = myReturnTypeCodeFragment.getType(); + return CanonicalTypes.createTypeWrapper(type); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return null; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return null; + } + } + else { + return null; + } + } + + public String getVisibility() { + if (myVisibilityPanel != null) { + return myVisibilityPanel.getVisibility(); + } + else { + return VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()); + } + } + + public ParameterInfo[] getParameters() { + return myParametersTableModel.getParameters(); + } + + public ThrownExceptionInfo[] getExceptions() { + return myExceptionsTableModel.getThrownExceptions(); + } + + public boolean isGenerateDelegate() { + return myAllowDelegation && myDelegationPanel.isGenerateDelegate(); + } + + public JComponent getPreferredFocusedComponent() { + return myParametersTableModel.getRowCount() > 0 ? (JComponent)myParametersTable : myNameField; + } + + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP)); + //panel.setBorder(BorderFactory.createTitledBorder("Method")); + + if (myAllowDelegation) + { + myDelegationPanel = createDelegationPanel(); + panel.add(myDelegationPanel); + } + if (!myMethod.isConstructor()) { + JLabel namePrompt = new JLabel("Name:"); + panel.add(namePrompt); + myNameField = new EditorTextField(myMethod.getName()); + namePrompt.setLabelFor(myNameField); + namePrompt.setDisplayedMnemonic('N'); + panel.add(myNameField); + + JLabel typePrompt = new JLabel("Return type:"); + panel.add(typePrompt); + final PsiElementFactory factory = myMethod.getManager().getElementFactory(); + myReturnTypeCodeFragment = factory.createTypeCodeFragment(myMethod.getReturnTypeElement().getText(), myMethod.getParameterList(), true, true); + final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment); + myReturnTypeField = new EditorTextField(document, myProject, StdFileTypes.JAVA); + typePrompt.setLabelFor(myReturnTypeField); + typePrompt.setDisplayedMnemonic('t'); + panel.add(myReturnTypeField); + myReturnTypeField.setText(factory.createTypeElement(myMethod.getReturnType()).getText()); + + final DocumentListener documentListener = new DocumentListener() { + public void beforeDocumentChange(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + updateSignature(); + } + }; + + myNameField.addDocumentListener(documentListener); + myReturnTypeField.addDocumentListener(documentListener); + } + + return panel; + } + + private DelegationPanel createDelegationPanel() { + return new DelegationPanel() { + protected void stateModified() { + myParametersTableModel.fireTableStructureChanged(); + configureParameterTableEditors(); + } + }; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + JPanel subPanel = new JPanel(new BorderLayout()); + subPanel.add(createParametersPanel(), BorderLayout.CENTER); + + if (myMethod.getContainingClass() != null + && !myMethod.getContainingClass().isInterface()) { + myVisibilityPanel = new VisibilityPanel(false); + myVisibilityPanel.setVisibility(VisibilityUtil.getVisibilityModifier(myMethod.getModifierList())); + myVisibilityPanel.addStateChangedListener(new VisibilityPanel.StateChanged() { + public void visibilityChanged(String s) { + updateSignature(); + } + }); + subPanel.add(myVisibilityPanel, BorderLayout.EAST); + } + + panel.add(subPanel, BorderLayout.CENTER); + + JPanel subPanel1 = new JPanel(new GridBagLayout()); + subPanel1.add(createExceptionsPanel(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(4,4,4,0), 0, 0)); + subPanel1.add(createSignaturePanel(), new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(4,0,4,4), 0, 0)); + panel.add(subPanel1, BorderLayout.SOUTH); + + return panel; + } + + + private JPanel createParametersPanel() { + myParametersTable = new Table(myParametersTableModel); + myParametersTable.setFocusCycleRoot(true); + + configureParameterTableEditors(); + return createTablePanelImpl(myParametersTable, myParametersTableModel, "Parameters", true); + } + + private JPanel createExceptionsPanel() { + myExceptionsTable = new Table(myExceptionsTableModel); + configureExceptionTableEditors(); + JPanel panel = createTablePanelImpl(myExceptionsTable, myExceptionsTableModel, "Exceptions", false); + return panel; + } + + private JPanel createTablePanelImpl (JTable table, RowEditableTableModel tableModel, String borderTitle, boolean addMnemonics) { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(IdeBorderFactory.createTitledBorder(borderTitle)); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table); + + JPanel tablePanel = new JPanel(new BorderLayout()); + tablePanel.add(scrollPane, BorderLayout.CENTER); + + tablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + panel.add(tablePanel, BorderLayout.CENTER); + + table.setPreferredScrollableViewportSize(new Dimension(450, table.getRowHeight() * 8)); + table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + table.getSelectionModel().setSelectionInterval(0, 0); + table.setSurrendersFocusOnKeystroke(true); + + final EditableRowTableManager editableRowTableManager = new EditableRowTableManager(table, tableModel, addMnemonics); + JPanel buttonsPanel = editableRowTableManager.getButtonsPanel(); + + panel.add(buttonsPanel, BorderLayout.EAST); + + tableModel.addTableModelListener( + new TableModelListener() { + public void tableChanged(TableModelEvent e) { + updateSignature(); + } + } + ); + + return panel; + } + + private void configureParameterTableEditors() { + myParametersTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject)); + myParametersTable.getColumnModel().getColumn(1).setCellRenderer(new MyCellRenderer()); + myParametersTable.getColumnModel().getColumn(2).setCellRenderer(new CodeFragmentTableCellRenderer(myProject)); + if (myParametersTable.getColumnCount() == 4) { + myParametersTable.getColumnModel().getColumn(3).setCellRenderer(new BooleanTableCellRenderer() { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) { + setBackground(getBackground().darker()); + } + return this; + } + }); + } + myParametersTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject)); + myParametersTable.getColumnModel().getColumn(1).setCellEditor(new MyNameTableCellEditor(myProject)); + myParametersTable.getColumnModel().getColumn(2).setCellEditor(new CodeFragmentTableCellEditor(myProject)); + } + + private void configureExceptionTableEditors () { + myExceptionsTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject)); + myExceptionsTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject)); + } + + private void completeVariable(EditorTextField editorTextField, PsiType type) { + Editor editor = editorTextField.getEditor(); + String prefix = editorTextField.getText(); + if (prefix == null) prefix = ""; + LinkedHashSet set = new LinkedHashSet(); + CompletionUtil.completeVariableName(myProject, set, prefix, type, VariableKind.PARAMETER); + + LookupItem[] lookupItems = set.toArray(new LookupItem[set.size()]); + editor.getCaretModel().moveToOffset(prefix.length()); + editor.getSelectionModel().removeSelection(); + LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix, null, new CharFilter() { + public int accept(char c) { + if (Character.isJavaIdentifierPart(c)) return CharFilter.ADD_TO_PREFIX; + return CharFilter.SELECT_ITEM_AND_FINISH_LOOKUP; + } + }); + } + + private JComponent createSignaturePanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createCompoundBorder(IdeBorderFactory.createTitledBorder("Signature Preview"), IdeBorderFactory.createEmptyBorder(new Insets(4, 4, 4, 4)))); + + String s = calculateSignature(); + s = StringUtil.convertLineSeparators(s, "\n"); + int height = new StringTokenizer(s, "\n\r").countTokens() + 2; + if (height > 10) height = 10; + mySignatureArea = new JTextArea(height, 50); + mySignatureArea.setEditable(false); + mySignatureArea.setBackground(this.getContentPane().getBackground()); + //mySignatureArea.setFont(myTableFont); + JScrollPane scrollPane = new JScrollPane(mySignatureArea); + scrollPane.setBorder(IdeBorderFactory.createEmptyBorder(new Insets(0,0,0,0))); + panel.add(scrollPane, BorderLayout.CENTER); + + updateSignature(); + return panel; + } + + private void updateSignature() { + if (mySignatureArea == null) return; + + myUpdateSignatureAlarm.cancelAllRequests(); + myUpdateSignatureAlarm.addRequest(new Runnable() { + public void run() { + doUpdateSignature(); + } + }, 100, ModalityState.stateForComponent(mySignatureArea)); + } + + private void doUpdateSignature() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + String signature = calculateSignature(); + mySignatureArea.setText(signature); + } + + private String calculateSignature() { + StringBuffer buffer = new StringBuffer(); + + PsiModifierList modifierList = myMethod.getModifierList(); + String modifiers = modifierList.getText(); + String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList); + String newModifier = getVisibility(); + String newModifierStr = VisibilityUtil.getVisibilityString(newModifier); + if (!newModifier.equals(oldModifier)) { + int index = modifiers.indexOf(oldModifier); + if (index >= 0) { + StringBuffer buf = new StringBuffer(modifiers); + buf.replace(index, + index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0), + newModifierStr); + modifiers = buf.toString(); + } + else { + if (!"".equals(newModifierStr)) newModifierStr += " "; + modifiers = newModifierStr + modifiers; + } + } + + buffer.append(modifiers); + if (modifiers.length() > 0 && + !StringUtil.endsWithChar(modifiers, '\n') && !StringUtil.endsWithChar(modifiers, '\r') && !StringUtil.endsWithChar(modifiers, ' ')) { + buffer.append(" "); + } + if (!myMethod.isConstructor()) { + final CanonicalTypes.Type returnType = getReturnType(); + if (returnType != null) { + buffer.append(returnType.getTypeText()); + } + buffer.append(" "); + } + buffer.append(getMethodName()); + buffer.append("("); + + final String indent = " "; + final List codeFraments = myParametersTableModel.getCodeFraments(); + + final ParameterInfo[] parameterInfos = myParametersTableModel.getParameters(); + LOG.assertTrue(codeFraments.size() == parameterInfos.length); + for (int i = 0; i < parameterInfos.length; i++) { + ParameterInfo info = parameterInfos[i]; + if (i > 0) { + buffer.append(","); + } + buffer.append("\n"); + buffer.append(indent); + buffer.append(codeFraments.get(i).getText()); + buffer.append(" "); + buffer.append(info.getName()); + } + if (parameterInfos.length > 0) { + buffer.append("\n"); + } + buffer.append(")"); + PsiTypeCodeFragment[] thrownExceptionsFragments = myExceptionsTableModel.getTypeCodeFragments(); + if (thrownExceptionsFragments.length > 0) { + buffer.append("\n"); + buffer.append("throws\n"); + for (int i = 0; i < thrownExceptionsFragments.length; i++) { + String text = thrownExceptionsFragments[i].getText(); + buffer.append(indent); + buffer.append(text); + buffer.append("\n"); + } + } + return buffer.toString(); + } + + protected void doAction() { + stopEditing(); + String message = validateAndCommitData(); + if (message != null) { + RefactoringMessageUtil.showErrorMessage("Incorrect Data", message, HelpID.CHANGE_SIGNATURE, myProject); + return; + } + if (!checkMethodConflicts()) { + return; + } + + myCallback.run(this); + } + + private String validateAndCommitData() { + PsiManager manager = PsiManager.getInstance(myProject); + PsiElementFactory factory = manager.getElementFactory(); + + String name = getMethodName(); + if (!manager.getNameHelper().isIdentifier(name)) { + return RefactoringMessageUtil.getIncorrectIdentifierMessage(name); + } + + if (!myMethod.isConstructor()) { + try { + myReturnTypeCodeFragment.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + myReturnTypeField.requestFocus(); + return "Wrong return type: '" + myReturnTypeCodeFragment.getText() +"'"; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + myReturnTypeField.requestFocus(); + return "Specify return type"; + } + } + + final List codeFraments = myParametersTableModel.getCodeFraments(); + final List defaultValueFraments = myParametersTableModel.getDefaultValueFraments(); + ParameterInfo[] parameterInfos = myParametersTableModel.getParameters(); + final int newParametersNumber = parameterInfos.length; + LOG.assertTrue(codeFraments.size() == newParametersNumber); + + for (int i = 0; i < newParametersNumber; i++) { + ParameterInfo info = parameterInfos[i]; + PsiTypeCodeFragment psiCodeFragment = codeFraments.get(i); + PsiCodeFragment defaultValueFragment = defaultValueFraments.get(i); + + if (!manager.getNameHelper().isIdentifier(info.getName())) { + return RefactoringMessageUtil.getIncorrectIdentifierMessage(info.getName()); + } + + final PsiType type; + try { + type = psiCodeFragment.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return "Wrong type: '" + psiCodeFragment.getText() + "' for parameter " + info.getName(); + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return "Specify a type for parameter" + info.getName(); + } + + info.setType(type); + + if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) { + return "Vararg parameter should be the last in method signature"; + } + + if (info.oldParameterIndex < 0) { + info.defaultValue = defaultValueFragment.getText(); + String def = info.defaultValue; + def = def.trim(); + if (!(type instanceof PsiEllipsisType)) { + if (def.length() == 0) { + return "New parameter " + info.getName() + " has been added.\n" + + "Specify a default value to be used in all existing calls of this method."; + } + + try { + factory.createExpressionFromText(info.defaultValue, null); + } + catch (IncorrectOperationException e) { + return e.getMessage(); + } + } + } + } + + ThrownExceptionInfo[] exceptionInfos = myExceptionsTableModel.getThrownExceptions(); + PsiTypeCodeFragment[] typeCodeFragments = myExceptionsTableModel.getTypeCodeFragments(); + for (int i = 0; i < exceptionInfos.length; i++) { + ThrownExceptionInfo exceptionInfo = exceptionInfos[i]; + PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i]; + try { + PsiType type = typeCodeFragment.getType(); + if (!(type instanceof PsiClassType)) { + return "Wrong type: '" + typeCodeFragment.getText() + "' for exception"; + } + + PsiClassType throwable = myMethod.getManager().getElementFactory().createTypeByFQClassName("java.lang.Throwable", type.getResolveScope()); + if (!throwable.isAssignableFrom(type)) { + return "Wrong type: '" + typeCodeFragment.getText() + "' for exception, should extend java.lang.Throwable"; + } + exceptionInfo.setType((PsiClassType)type); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return "Wrong type: '" + typeCodeFragment.getText() + "' for exception"; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return "Specify a type for exception"; + } + } + + return null; + } + + private boolean checkMethodConflicts() { + String newMethodName = getMethodName(); + + PsiMethod prototype; + try { + PsiManager manager = PsiManager.getInstance(myProject); + PsiElementFactory factory = manager.getElementFactory(); + final CanonicalTypes.Type returnType = getReturnType(); + if (returnType != null) { + prototype = factory.createMethod(newMethodName, returnType.getType(myMethod)); + } + else { + prototype = null; + } + ParameterInfo[] parameters = getParameters(); + + for (int idx = 0; idx < parameters.length; idx++) { + ParameterInfo info = parameters[idx]; + final PsiType parameterType = info.createType(myMethod); + + if (!RefactoringUtil.isResolvableType(parameterType)) { + final int ret = Messages.showOkCancelDialog(myProject, + "Type " + info.getTypeText() + " cannot be resolved.\nContinue?", + "Change Method Signature", Messages.getErrorIcon() + ); + if (ret != 0) return false; + } + if (prototype != null) { + PsiParameter param = factory.createParameter(info.getName(), parameterType); + prototype.getParameterList().add(param); + } + } + + /*ThrownExceptionInfo[] exceptions = getExceptions(); + for (int i = 0; i < exceptions.length; i++) { + ThrownExceptionInfo info = exceptions[i]; + PsiType exceptionType = info.createType(myMethod); + if (!RefactoringUtil.isResolvableType(exceptionType)) { + final int ret = Messages.showOkCancelDialog(myProject, + "Type " + info.getTypeText() + " cannot be resolved.\nContinue?", + "Change Method Signature", Messages.getErrorIcon() + ); + if (ret != 0) return false; + } + }*/ + } + catch (IncorrectOperationException e) { + prototype = null; + } + if (prototype == null) return true; + PsiClass aClass = myMethod.getContainingClass(); + return RefactoringMessageUtil.checkMethodConflicts( + aClass != null ? (PsiElement)aClass : (PsiElement)myMethod.getContainingFile(), + myMethod, + prototype + ); + } + + private void stopEditing() { + TableUtil.stopEditing(myParametersTable); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.CHANGE_SIGNATURE); + } + + private class MyCellRenderer extends ColoredTableCellRenderer { + + public void customizeCellRenderer(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + //setFont(myTableFont); + if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) { + setBackground(getBackground().darker()); + } + append((String)value, new SimpleTextAttributes(Font.PLAIN, null)); + } + } + + public void addParameter(String name, String type, String defaultValue) { + myParametersTableModel.addRow(); + final int index = myParametersTableModel.getRowCount() - 1; + myParametersTableModel.setValueAt(type, index, 0); + myParametersTableModel.setValueAt(name, index, 1); + myParametersTableModel.setValueAt(defaultValue, index, 2); + + myParametersTable.setRowSelectionInterval(index, index); + myParametersTable.setColumnSelectionInterval(2, 2); + myParametersTable.editCellAt(index, 2); + } + + private class MyNameTableCellEditor extends StringTableCellEditor { + public MyNameTableCellEditor(Project project) { + super(project); + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + final EditorTextField textField = (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column); + textField.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int column = myParametersTable.convertColumnIndexToModel(myParametersTable.getEditingColumn()); + if (column == 1) { + int row = myParametersTable.getEditingRow(); + PsiType type = myParametersTableModel.getTypeByRow(row); + if (type != null) { + completeVariable(textField, type); + } + } + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); + return textField; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java new file mode 100644 index 00000000000..5efbbf8204a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java @@ -0,0 +1,111 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.changeClassSignature.ChangeClassSignatureDialog; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +public class ChangeSignatureHandler implements RefactoringActionHandler { + public static final String REFACTORING_NAME = "Change Signature"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = (PsiElement) dataContext.getData(DataConstants.PSI_ELEMENT); + if (element instanceof PsiMethod) { + PsiElement resolutionContext = file.findElementAt(editor.getCaretModel().getOffset()); + if(resolutionContext == null) resolutionContext = element; + resolutionContext = ChangeSignatureProcessor.normalizeResolutionContext(resolutionContext); + invoke((PsiMethod) element, project, resolutionContext); + } + else if (element instanceof PsiClass) { + invoke((PsiClass) element); + } + else { + String message = "Cannot perform the refactoring.\n" + + "The caret should be positioned at the name of the method to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.CHANGE_SIGNATURE, project); + } + } + + public void invoke(final Project project, final PsiElement[] elements, final DataContext dataContext) { + if (elements.length != 1) return; + if (elements[0] instanceof PsiMethod) { + PsiMethod method = (PsiMethod)elements[0]; + final PsiMethod resolutionContext = method; + + invoke(method, project, resolutionContext); + } + else if (elements[0] instanceof PsiClass){ + invoke((PsiClass) elements[0]); + } + } + + private void invoke(final PsiMethod method, final Project project, final PsiElement resolutionContext) { + if (!method.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, method); + return; + } + + PsiMethod newMethod = SuperMethodWarningUtil.checkSuperMethod(method, "refactor"); + if (newMethod == null) return; + + newMethod = (PsiMethod) EjbUtil.checkDeclMethod(newMethod, "refactor"); + if (newMethod == null) return; + + if (!newMethod.equals(method)) { + final PsiMethod methodCopy = newMethod; + invoke(methodCopy, project, resolutionContext); + return; + } + + if (!method.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, method); + return; + } + + final PsiClass containingClass = method.getContainingClass(); + final ChangeSignatureDialog dialog = new ChangeSignatureDialog(project, method, containingClass != null && !containingClass.isInterface(), new ChangeSignatureDialog.Callback() { + public void run(final ChangeSignatureDialog dialog) { + new ChangeSignatureProcessor( + project, + method, + dialog.isGenerateDelegate(), + dialog.getVisibility(), + dialog.getMethodName(), + dialog.getReturnType(), + dialog.getParameters(), + dialog.getExceptions(), + dialog.isPreviewUsages(), + new Runnable() { + public void run() { + dialog.close(DialogWrapper.OK_EXIT_CODE); + } + }).run(null); + } + }); + dialog.show(); + } + + private void invoke(final PsiClass aClass) { + Project project = aClass.getProject(); + if (!aClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, aClass); + return; + } + + ChangeClassSignatureDialog dialog = new ChangeClassSignatureDialog(aClass); + dialog.show(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java new file mode 100644 index 00000000000..435b0e1c1a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -0,0 +1,1018 @@ +/** + * created at Sep 17, 2001 + * @author Jeka + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbDeclMethodRole; +import com.intellij.j2ee.ejb.role.EjbImplMethodRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.scope.processor.VariablesProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.*; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.*; +import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo; +import com.intellij.refactoring.util.usageInfo.DefaultConstructorUsageCollector; +import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class ChangeSignatureProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureProcessor"); + + private final String myNewVisibility; + private String myNewName; + private CanonicalTypes.Type myNewType; + private ParameterInfo[] myParameterInfo; + private boolean myToPreviewUsages; + private ChangeInfo myChangeInfo; + private PsiManager myManager; + private PsiElementFactory myFactory; + private static final Class[] NORMALIZED_RESOLUTION_CONTEXT_CLASSES = + new Class[]{PsiStatement.class, PsiClass.class, PsiFile.class}; + private HashSet myMethodsToBeChanged; + private final boolean myGenerateDelegate; + + public ChangeSignatureProcessor(Project project, PsiMethod method, + final boolean generateDelegate, String newVisibility, + String newName, PsiType newType, + ParameterInfo[] parameterInfo, boolean toPreviewUsages, + Runnable prepareSuccessfulCallback) { + this(project, method, generateDelegate, newVisibility, newName, + newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, + parameterInfo, null, toPreviewUsages, prepareSuccessfulCallback); + } + + public ChangeSignatureProcessor(Project project, PsiMethod method, + final boolean generateDelegate, String newVisibility, + String newName, PsiType newType, + ParameterInfo[] parameterInfo, + ThrownExceptionInfo[] exceptionInfos, + boolean toPreviewUsages, + Runnable prepareSuccessfulCallback) { + this(project, method, generateDelegate, newVisibility, newName, + newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, + parameterInfo, exceptionInfos, toPreviewUsages, prepareSuccessfulCallback); + } + + public ChangeSignatureProcessor(Project project, + PsiMethod method, + boolean generateDelegate, + String newVisibility, + String newName, + CanonicalTypes.Type newType, + ParameterInfo[] parameterInfo, + ThrownExceptionInfo[] thrownExceptions, + boolean toPreviewUsages, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myGenerateDelegate = generateDelegate; + LOG.assertTrue(method.isValid()); + if (newVisibility == null) { + myNewVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList()); + } else { + myNewVisibility = newVisibility; + } + myNewName = newName; + myNewType = newType; + myParameterInfo = parameterInfo; + myToPreviewUsages = toPreviewUsages; + + myChangeInfo = new ChangeInfo(myNewVisibility, method, myNewName, myNewType, myParameterInfo, thrownExceptions); + LOG.assertTrue(myChangeInfo.getMethod().isValid()); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new ChangeSignatureViewDescriptor(myChangeInfo.getMethod(), usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + myManager = PsiManager.getInstance(myProject); + myFactory = myManager.getElementFactory(); + + ArrayList result = new ArrayList(); + final PsiMethod method = myChangeInfo.getMethod(); + + findSimpleUsages(method, result); + findEjbUsages(result); + + + final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + private void findSimpleUsages(final PsiMethod method, final ArrayList result) { + PsiManager manager = method.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + PsiMethod[] overridingMethods = helper.findOverridingMethods(method, projectScope, true); + + for (int i = 0; i < overridingMethods.length; i++) { + PsiMethod overridingMethod = overridingMethods[i]; + result.add(new UsageInfo(overridingMethod)); + } + + boolean needToChangeCalls = !myGenerateDelegate && (needToChangeCalls() || myChangeInfo.isVisibilityChanged/*for checking inaccessible*/); + if (needToChangeCalls) { + List l = new ArrayList(); + PsiReference[] refs = helper.findReferencesIncludingOverriding(method, projectScope, true); + for (int i = 0; i < refs.length; i++) { + PsiReference reference = refs[i]; + l.add(reference.getElement()); + } + + int parameterCount = method.getParameterList().getParameters().length; + for (Iterator iterator = l.iterator(); iterator.hasNext();) { + PsiElement ref = iterator.next(); + if (myChangeInfo.isParameterSetOrOrderChanged) { + if (RefactoringUtil.isMethodUsage(ref)) { + PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference((PsiJavaCodeReferenceElement)ref); + if (!method.isVarArgs() && list.getExpressions().length != parameterCount) continue; + } + } + result.add(new UsageInfo(ref)); + } + + if (method.isConstructor() && parameterCount == 0) { + RefactoringUtil.visitImplicitConstructorUsages(method.getContainingClass(), + new DefaultConstructorUsageCollector(result)); + } + } else if (myChangeInfo.isParameterTypesChanged) { + PsiReference[] refs = helper.findReferencesIncludingOverriding(method, projectScope, true); + for (int i = 0; i < refs.length; i++) { + PsiReference reference = refs[i]; + if (reference.getElement() instanceof PsiDocTagValue) { //types are mentioned in e.g @link, see SCR 40895 + result.add(new UsageInfo(reference.getElement())); + } + } + } + + findParametersUsage(method, result, overridingMethods); + + // Conflicts + detectLocalsCollisionsInMethod(method, result); + for (int j = 0; j < overridingMethods.length; j++) { + final PsiMethod overridingMethod = overridingMethods[j]; + detectLocalsCollisionsInMethod(overridingMethod, result); + } + } + + private boolean needToChangeCalls() { + return myChangeInfo.isNameChanged || myChangeInfo.isParameterSetOrOrderChanged || myChangeInfo.isExceptionSetChanged; + } + + private void detectLocalsCollisionsInMethod(final PsiMethod method, + final ArrayList result) { + final PsiParameter[] overridingParameters = method.getParameterList().getParameters(); + final Set deletedParameters = + new HashSet(Arrays.asList(overridingParameters)); + + for (int i = 0; i < myParameterInfo.length; i++) { + ParameterInfo parameterInfo = myParameterInfo[i]; + if (parameterInfo.oldParameterIndex >= 0 && + parameterInfo.getName().equals(overridingParameters[parameterInfo.oldParameterIndex].getName())) { + deletedParameters.remove(overridingParameters[parameterInfo.oldParameterIndex]); + } + } + for (int i = 0; i < myParameterInfo.length; i++) { + ParameterInfo parameterInfo = myParameterInfo[i]; + final int oldParameterIndex = parameterInfo.oldParameterIndex; + final String newName = parameterInfo.getName(); + if (oldParameterIndex >= 0) { + final PsiParameter parameter = overridingParameters[oldParameterIndex]; + if (!newName.equals(parameter.getName())) { + RenameUtil.visitLocalsCollisions(parameter, newName, method.getBody(), null, new RenameUtil.CollidingVariableVisitor() { + public void visitCollidingElement(final PsiVariable collidingVariable) { + if (!(collidingVariable instanceof PsiField) && !deletedParameters.contains(collidingVariable)) { + result.add(new RenamedParameterCollidesWithLocalUsageInfo(parameter, collidingVariable, method)); + } + } + }); + } + } else { + RenameUtil.visitLocalsCollisions(method, newName, method.getBody(), null, new RenameUtil.CollidingVariableVisitor() { + public void visitCollidingElement(PsiVariable collidingVariable) { + if (!(collidingVariable instanceof PsiField) && !deletedParameters.contains(collidingVariable)) { + result.add(new NewParameterCollidesWithLocalUsageInfo(collidingVariable, collidingVariable, method)); + } + } + }); + } + } + } + + private void findParametersUsage(final PsiMethod method, ArrayList result, PsiMethod[] overriders) { + PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < myChangeInfo.newParms.length; i++) { + ParameterInfo info = myChangeInfo.newParms[i]; + if (info.oldParameterIndex >= 0) { + PsiParameter parameter = parameters[info.oldParameterIndex]; + if (!info.getName().equals(parameter.getName())) { + addParameterUsages(parameter, result, info); + + for (int j = 0; j < overriders.length; j++) { + PsiParameter parameter1 = overriders[j].getParameterList().getParameters()[info.oldParameterIndex]; + if (parameter.getName().equals(parameter1.getName())) { + addParameterUsages(parameter1, result, info); + } + } + } + } + } + } + + private void findEjbUsages(ArrayList result) { + if (myChangeInfo.ejbRole == null) return; + if (!(myChangeInfo.ejbRole instanceof EjbDeclMethodRole)) return; + + final PsiMethod[] implementations = EjbUtil.findEjbImplementations(myChangeInfo.getMethod()); + for (int i = 0; i < implementations.length; i++) { + PsiMethod implementation = implementations[i]; + result.add(new EjbUsageInfo(implementation)); + findSimpleUsages(implementation, result); + } + } + + protected void refreshElements(PsiElement[] elements) { + boolean condition = elements.length == 1 && elements[0] instanceof PsiMethod; + LOG.assertTrue(condition); + myChangeInfo.updateMethod((PsiMethod) elements[0]); + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages) || myToPreviewUsages; + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + Set conflictDescriptions = new HashSet(); + conflictDescriptions.addAll(Arrays.asList(RenameUtil.getConflictDescriptions(usages[0]))); + Set usagesSet = new HashSet(Arrays.asList(usages[0])); + RenameUtil.removeConflictUsages(usagesSet); + if (myChangeInfo.isVisibilityChanged) { + try { + addInaccessibilityDescriptions(usagesSet, conflictDescriptions); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + if (myPrepareSuccessfulSwingThreadCallback != null && conflictDescriptions.size() > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflictDescriptions.toArray(new String[conflictDescriptions.size()]), myProject); + dialog.show(); + if (!dialog.isOK()) return false; + } + + if (myChangeInfo.isReturnTypeChanged) { + askToRemoveCovariantOverriders (usagesSet); + } + + usages[0] = usagesSet.toArray(new UsageInfo[usagesSet.size()]); + prepareSuccessful(); + return true; + } + + private void addInaccessibilityDescriptions(Set usages, Set conflictDescriptions) throws IncorrectOperationException { + PsiMethod method = myChangeInfo.getMethod(); + PsiModifierList modifierList = (PsiModifierList)method.getModifierList().copy(); + RefactoringUtil.setVisibility(modifierList, myNewVisibility); + + for (Iterator iterator = usages.iterator(); iterator.hasNext();) { + UsageInfo usageInfo = iterator.next(); + PsiElement element = usageInfo.getElement(); + if (element != null) { + PsiClass accessObjectClass = null; + if (element instanceof PsiReferenceExpression) { + PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression(); + if (qualifier != null) { + accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); + } + + if (!element.getManager().getResolveHelper().isAccessible(method, modifierList, element, accessObjectClass)) { + String message = + ConflictsUtil.getDescription(method, true) + " with " + myNewVisibility + " visibility is not accesible from " + + ConflictsUtil.getDescription(ConflictsUtil.getContainer(element), true); + conflictDescriptions.add(message); + if (!needToChangeCalls()) { + iterator.remove(); + } + } + } + } + } + } + + private void askToRemoveCovariantOverriders(Set usages) { + if (myManager.getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) >= 0) { + List covariantOverriderInfos = new ArrayList(); + PsiSubstitutor substitutor = calculateSubstitutor(myChangeInfo.getMethod()); + PsiType type; + try { + type = substitutor.substitute(myChangeInfo.newReturnType.getType(myChangeInfo.getMethod())); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return; + } + + for (Iterator iterator = usages.iterator(); iterator.hasNext();) { + UsageInfo usageInfo = iterator.next(); + if (usageInfo.getElement() instanceof PsiMethod) { + PsiMethod overrider = (PsiMethod)usageInfo.getElement(); + if (type.isAssignableFrom(overrider.getReturnType())) { + covariantOverriderInfos.add(usageInfo); + } + } + } + + if (covariantOverriderInfos.size() > 0) { + if (ApplicationManager.getApplication().isUnitTestMode() || + Messages.showYesNoDialog(myProject, "Do you want to process overriding methods\n" + + "with covariant return type?", + "Change Method Signature", Messages.getQuestionIcon()) + != DialogWrapper.OK_EXIT_CODE) { + for (Iterator iterator = covariantOverriderInfos.iterator(); iterator.hasNext();) { + usages.remove(iterator.next()); + } + } + } + } + } + + protected void performRefactoring(UsageInfo[] usages) { + PsiElementFactory factory = myManager.getElementFactory(); + + + List postponedUsages = new ArrayList(); + + try { + if (myChangeInfo.isNameChanged) { + myChangeInfo.newNameIdentifier = factory.createIdentifier(myChangeInfo.newName); + } + + if (myChangeInfo.isReturnTypeChanged) { + myChangeInfo.newTypeElement = myChangeInfo.newReturnType.getType(myChangeInfo.getMethod()); + } + + myMethodsToBeChanged = new HashSet(); + + if (myGenerateDelegate) { + generateDelegate(); + } + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!(usage instanceof DefaultConstructorImplicitUsageInfo) && usage.getElement() instanceof PsiMethod) { + myMethodsToBeChanged.add((PsiMethod) usage.getElement()); + } + } + + if (myChangeInfo.isExceptionSetOrOrderChanged) { + fixThrowsLists(getChangedExceptionInfo(myChangeInfo)); + } + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) continue; + + if (usage instanceof DefaultConstructorImplicitUsageInfo) { + addSuperCall(((DefaultConstructorImplicitUsageInfo) usage).getConstructor()); + } else if (usage instanceof NoConstructorClassUsageInfo) { + addDefaultConstructor(((NoConstructorClassUsageInfo) usage).getPsiClass()); + } else if (usage.getElement() instanceof PsiMethod) { + processMethod((PsiMethod) usage.getElement(), false); + } else if (usage.getElement() instanceof PsiJavaCodeReferenceElement) { + if (RefactoringUtil.isMethodUsage(usage.getElement())) { + processMethodUsage((PsiJavaCodeReferenceElement) usage.getElement(), myChangeInfo); + } else { + String newName = ((MyParameterUsageInfo) usage).newParameterName; + String oldName = ((MyParameterUsageInfo) usage).oldParameterName; + processParameterUsage((PsiReferenceExpression) usage.getElement(), oldName, newName); + } + } else if (usage.getElement() instanceof PsiEnumConstant) { + fixActualArgumentsList(((PsiEnumConstant)usage.getElement()).getArgumentList(), myChangeInfo, false); + } else { + postponedUsages.add(usage); + } + } + + LOG.assertTrue(myChangeInfo.getMethod().isValid()); + + processMethod(myChangeInfo.getMethod(), true); + + for (Iterator i = postponedUsages.iterator(); i.hasNext();) { + UsageInfo usageInfo = i.next(); + PsiReference reference = usageInfo.getElement().getReference(); + if (reference != null) { + PsiElement target = null; + if (usageInfo instanceof MyParameterUsageInfo) { + String newParameterName = ((MyParameterUsageInfo) usageInfo).newParameterName; + PsiParameter[] newParams = myChangeInfo.getMethod().getParameterList().getParameters(); + for (int j = 0; j < newParams.length; j++) { + PsiParameter newParam = newParams[j]; + if (newParam.getName().equals(newParameterName)) { + target = newParam; + break; + } + } + } else { + target = myChangeInfo.getMethod(); + } + if (target != null) { + reference.bindToElement(target); + } + } + } + + fixJavadocsForChangedMethod(myChangeInfo.getMethod()); + for (Iterator iterator = myMethodsToBeChanged.iterator(); iterator.hasNext();) { + PsiMethod method = iterator.next(); + fixJavadocsForChangedMethod(method); + } + LOG.assertTrue(myChangeInfo.getMethod().isValid()); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private void generateDelegate() throws IncorrectOperationException { + final PsiMethod delegate = (PsiMethod)myChangeInfo.getMethod().copy(); + final PsiClass targetClass = myChangeInfo.getMethod().getContainingClass(); + LOG.assertTrue(!targetClass.isInterface()); + makeEmptyBody(delegate); + final PsiCallExpression callExpression = addDelegatingCallTemplate(delegate); + addDelegateArguments(callExpression); + targetClass.addBefore(delegate, myChangeInfo.getMethod()); + } + + private void addDelegateArguments(final PsiCallExpression callExpression) throws IncorrectOperationException { + final ParameterInfo[] newParms = myChangeInfo.newParms; + for (int i = 0; i < newParms.length; i++) { + ParameterInfo newParm = newParms[i]; + final PsiExpression actualArg; + if (newParm.oldParameterIndex >= 0) { + actualArg = myFactory.createExpressionFromText(myChangeInfo.oldParameterNames[newParm.oldParameterIndex], callExpression); + } + else { + actualArg = myChangeInfo.defaultValues[i]; + } + callExpression.getArgumentList().add(actualArg); + } + } + + private void makeEmptyBody(final PsiMethod delegate) throws IncorrectOperationException { + if (delegate.getBody() != null) { + delegate.getBody().replace(myFactory.createCodeBlock()); + } + else { + delegate.add(myFactory.createCodeBlock()); + } + delegate.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false); + } + + private PsiCallExpression addDelegatingCallTemplate(final PsiMethod delegate) throws IncorrectOperationException { + final PsiCallExpression callExpression; + if (delegate.isConstructor()) { + PsiElement callStatement = myFactory.createStatementFromText("this();", null); + callStatement = CodeStyleManager.getInstance(myProject).reformat(callStatement); + callStatement = delegate.getBody().add(callStatement); + callExpression = (PsiCallExpression)((PsiExpressionStatement) callStatement).getExpression(); + } else { + if (PsiType.VOID.equals(delegate.getReturnType())) { + PsiElement callStatement = myFactory.createStatementFromText(myChangeInfo.newName + "();", null); + callStatement = CodeStyleManager.getInstance(myProject).reformat(callStatement); + callStatement = delegate.getBody().add(callStatement); + callExpression = (PsiCallExpression)((PsiExpressionStatement) callStatement).getExpression(); + } + else { + PsiElement callStatement = myFactory.createStatementFromText("return " + myChangeInfo.newName + "();", null); + callStatement = CodeStyleManager.getInstance(myProject).reformat(callStatement); + callStatement = delegate.getBody().add(callStatement); + callExpression = (PsiCallExpression)((PsiReturnStatement) callStatement).getReturnValue(); + } + } + return callExpression; + } + + private void addDefaultConstructor(PsiClass aClass) throws IncorrectOperationException { + if (!(aClass instanceof PsiAnonymousClass)) { + PsiMethod defaultConstructor = myFactory.createMethodFromText(aClass.getName() + "(){}", aClass); + defaultConstructor = (PsiMethod) CodeStyleManager.getInstance(myProject).reformat(defaultConstructor); + defaultConstructor = (PsiMethod) aClass.add(defaultConstructor); + defaultConstructor.getModifierList().setModifierProperty(VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true); + addSuperCall(defaultConstructor); + } else { + final PsiElement parent = aClass.getParent(); + if (parent instanceof PsiNewExpression) { + final PsiExpressionList argumentList = ((PsiNewExpression) parent).getArgumentList(); + fixActualArgumentsList(argumentList, myChangeInfo, false); + } + } + } + + private void addSuperCall(PsiMethod constructor) throws IncorrectOperationException { + PsiExpressionStatement superCall = (PsiExpressionStatement) myFactory.createStatementFromText("super();", constructor); + PsiStatement[] statements = constructor.getBody().getStatements(); + if (statements.length > 0) { + superCall = (PsiExpressionStatement) constructor.getBody().addBefore(superCall, statements[0]); + } else { + superCall = (PsiExpressionStatement) constructor.getBody().add(superCall); + } + PsiMethodCallExpression callExpression = (PsiMethodCallExpression) superCall.getExpression(); + processMethodUsage(callExpression.getMethodExpression(), myChangeInfo); + } + + private PsiParameter createNewParameter(ParameterInfo newParm, PsiSubstitutor substitutor) throws IncorrectOperationException { + final PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + final PsiParameter newParameter = factory.createParameterFromText("X " + newParm.getName(), null); + final PsiType type = substitutor.substitute(newParm.createType(myChangeInfo.getMethod().getParameterList())); + newParameter.getTypeElement().replace(factory.createTypeElement(type)); + return newParameter; + } + + protected String getCommandName() { + return "Changing signature of " + UsageViewUtil.getDescriptiveName(myChangeInfo.getMethod()); + } + + private void processMethodUsage(PsiJavaCodeReferenceElement ref, ChangeInfo changeInfo) + throws IncorrectOperationException { + + if (changeInfo.isNameChanged) { + PsiElement last = ref.getReferenceNameElement(); + if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.oldName)) { + last.replace(changeInfo.newNameIdentifier); + } + } + final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); + + boolean isSuperCall = false; + if (ref instanceof PsiReferenceExpression) { + final PsiExpression qualifierExpression = ((PsiReferenceExpression) ref).getQualifierExpression(); + if (qualifierExpression instanceof PsiSuperExpression) { + + for (Iterator iterator = myMethodsToBeChanged.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement) iterator.next(); + if (PsiTreeUtil.isAncestor(element, ref, false)) { + isSuperCall = true; + break; + } + } + } + } + + fixActualArgumentsList(list, changeInfo, isSuperCall); + + if (changeInfo.isExceptionSetChanged) { + PsiClassType[] newExceptions = getChangedExceptionInfo(changeInfo); + fixExceptions(ref, newExceptions); + } + } + + private PsiClassType[] getChangedExceptionInfo(ChangeInfo changeInfo) throws IncorrectOperationException { + PsiClassType[] newExceptions = new PsiClassType[changeInfo.newExceptions.length]; + for (int i = 0; i < newExceptions.length; i++) { + newExceptions[i] = (PsiClassType)changeInfo.newExceptions[i].myType.getType(myChangeInfo.getMethod()); //context really does not matter here + } + return newExceptions; + } + + private void fixExceptions(PsiJavaCodeReferenceElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { + + fixThrowsLists(newExceptions); + + newExceptions = filterCheckedExceptions(newExceptions); + //Now that methods' throws lists are modified, may use ExceptionUtil.collectUnhandledExceptions + + PsiElement context = PsiTreeUtil.getParentOfType(ref, new Class[]{PsiTryStatement.class, PsiMethod.class}); + if (context instanceof PsiTryStatement) { + PsiTryStatement tryStatement = (PsiTryStatement)context; + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + + //Remove unused catches + PsiClassType[] classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); + PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); + for (int i = 0; i < catchParameters.length; i++) { + PsiParameter parameter = catchParameters[i]; + final PsiType caughtType = parameter.getType(); + + if (!(caughtType instanceof PsiClassType)) continue; + if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)caughtType)) continue; + + if (!isCatchParameterRedundant((PsiClassType)caughtType, classes)) continue; + parameter.getParent().delete(); //delete catch section + } + + PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); + addExceptions(exceptionsToAdd, tryStatement); + + adjustPossibleEmptyTryStatement(tryStatement); + } + else { + newExceptions = filterUnhandledExceptions(newExceptions, ref); + if (newExceptions.length > 0) { + //Add new try statement + PsiElementFactory elementFactory = myManager.getElementFactory(); + PsiTryStatement tryStatement = (PsiTryStatement)elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); + PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); + LOG.assertTrue(anchor != null); + tryStatement.getTryBlock().add(anchor); + tryStatement = (PsiTryStatement)anchor.getParent().addAfter(tryStatement, anchor); + + addExceptions(newExceptions, tryStatement); + anchor.delete(); + tryStatement.getCatchSections()[0].delete(); //Delete dummy catch section + } + } + } + + private PsiClassType[] filterCheckedExceptions(PsiClassType[] exceptions) { + List result = new ArrayList(); + for (int i = 0; i < exceptions.length; i++) { + PsiClassType exceptionType = exceptions[i]; + if (!ExceptionUtil.isUncheckedException(exceptionType)) result.add(exceptionType); + } + return result.toArray(new PsiClassType[result.size()]); + } + + private void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement) throws IncorrectOperationException { + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (tryBlock != null) { + if (tryStatement.getCatchSections().length == 0 && + tryStatement.getFinallyBlock() == null) { + if (tryBlock.getLBrace() != null && tryBlock.getRBrace() != null) { + tryStatement.getParent().addRangeAfter(tryBlock.getLBrace().getNextSibling(), tryBlock.getRBrace().getPrevSibling(), tryStatement); + tryStatement.delete(); + } + } + } + } + + private void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatement tryStatement) throws IncorrectOperationException { + for (int i = 0; i < exceptionsToAdd.length; i++) { + PsiClassType type = exceptionsToAdd[i]; + final CodeStyleManager styleManager = tryStatement.getManager().getCodeStyleManager(); + String name = styleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type).names[0]; + name = styleManager.suggestUniqueVariableName(name, tryStatement, false); + + PsiCatchSection catchSection = tryStatement.getManager().getElementFactory().createCatchSection(type, name, tryStatement); + tryStatement.add(catchSection); + } + } + + private void fixThrowsLists(PsiClassType[] newExceptions) throws IncorrectOperationException { + PsiElementFactory elementFactory = myManager.getElementFactory(); + PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length]; + for (int i = 0; i < refs.length; i++) { + refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]); + } + PsiReferenceList throwsList = elementFactory.createReferenceList(refs); + + replaceThrowsList(myChangeInfo.getMethod(), throwsList); + for (Iterator iterator = myMethodsToBeChanged.iterator(); iterator.hasNext();) { + PsiMethod method = iterator.next(); + replaceThrowsList(method, throwsList); + } + } + + private void replaceThrowsList(PsiMethod method, PsiReferenceList throwsList) throws IncorrectOperationException { + PsiReferenceList methodThrowsList = (PsiReferenceList)method.getThrowsList().replace(throwsList); + methodThrowsList = (PsiReferenceList)myManager.getCodeStyleManager().shortenClassReferences(methodThrowsList); + myManager.getCodeStyleManager().reformatRange(method, method.getParameterList().getTextRange().getEndOffset(), + methodThrowsList.getTextRange().getEndOffset()); + } + + private PsiClassType[] filterUnhandledExceptions(PsiClassType[] exceptions, PsiElement place) { + List result = new ArrayList(); + for (int i = 0; i < exceptions.length; i++) { + PsiClassType exception = exceptions[i]; + if (!ExceptionUtil.isHandled(exception, place)) result.add(exception); + } + return result.toArray(new PsiClassType[result.size()]); + } + + private boolean isCatchParameterRedundant (PsiClassType catchParamType, PsiType[] thrownTypes) { + for (int j = 0; j < thrownTypes.length; j++) { + PsiType exceptionType = thrownTypes[j]; + if (exceptionType.isConvertibleFrom(catchParamType)) return false; + } + return true; + } + + private int getNonVarargCount(ChangeInfo changeInfo, PsiExpression[] args) { + if (!changeInfo.wasVararg) return args.length; + return changeInfo.getMethod().getParameterList().getParameters().length - 1; + } + + private void fixActualArgumentsList(PsiExpressionList list, ChangeInfo changeInfo, boolean isSuperCall) throws IncorrectOperationException { + final PsiElementFactory factory = list.getManager().getElementFactory(); + if (changeInfo.isParameterSetOrOrderChanged) { + final PsiExpression[] args = list.getExpressions(); + final int nonVarargCount = getNonVarargCount(changeInfo, args); + final int varargCount = args.length - nonVarargCount; + + final int newArgsLength; + final int newNonVarargCount; + if (changeInfo.retainsVarargs) { + newNonVarargCount = changeInfo.newParms.length - 1; + newArgsLength = newNonVarargCount + varargCount; + } + else if (changeInfo.obtainsVarags) { + newNonVarargCount = changeInfo.newParms.length - 1; + newArgsLength = newNonVarargCount; + } + else { + newNonVarargCount = changeInfo.newParms.length; + newArgsLength = changeInfo.newParms.length; + } + final PsiExpression[] newArgs = new PsiExpression[newArgsLength]; + for (int i = 0; i < newNonVarargCount; i++) { + final ParameterInfo info = changeInfo.newParms[i]; + final int index = info.oldParameterIndex; + if (index >= 0) { + newArgs[i] = args[index]; + } else { + if (!isSuperCall) { + newArgs[i] = createDefaultValue(factory, info, list); + } else { + newArgs[i] = factory.createExpressionFromText(info.getName(), list); + } + } + } + final int newVarargCount = newArgsLength - newNonVarargCount; + LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount); + for (int i = 0; i < newVarargCount; i++) { + newArgs[newNonVarargCount + i] = args[nonVarargCount + i]; + } + ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm); + } + } + + private PsiExpression createDefaultValue(final PsiElementFactory factory, final ParameterInfo info, final PsiExpressionList list) + throws IncorrectOperationException { + if (info.useAnySingleVariable) { + final PsiResolveHelper resolveHelper = list.getManager().getResolveHelper(); + final PsiType type = info.getTypeWrapper().getType(myChangeInfo.getMethod()); + final VariablesProcessor processor = new VariablesProcessor(false) { + protected boolean check(PsiVariable var, PsiSubstitutor substitutor) { + if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField)var, list, null)) return false; + final PsiType varType = substitutor.substitute(var.getType()); + return type.isAssignableFrom(varType); + } + + public boolean execute(PsiElement pe, PsiSubstitutor substitutor) { + super.execute(pe, substitutor); + return size() < 2; + } + }; + PsiScopesUtil.treeWalkUp(processor, list, null); + if (processor.size() == 1) { + final PsiVariable result = processor.getResult(0); + return factory.createExpressionFromText(result.getName(), list); + } + } + return factory.createExpressionFromText(info.defaultValue, list); + } + + private void addParameterUsages(PsiParameter parameter, + ArrayList results, + ParameterInfo info) { + PsiManager manager = parameter.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + PsiReference[] parmRefs = helper.findReferences(parameter, projectScope, false); + for (int k = 0; k < parmRefs.length; k++) { + PsiElement parmRef = parmRefs[k].getElement(); + UsageInfo usageInfo = new MyParameterUsageInfo(parmRef, parameter.getName(), info.getName()); + results.add(usageInfo); + } + } + + private void processMethod(PsiMethod method, boolean isOriginal) throws IncorrectOperationException { + PsiElementFactory factory = method.getManager().getElementFactory(); + + if (myChangeInfo.isVisibilityChanged) { + PsiModifierList modifierList = method.getModifierList(); + final String highestVisibility = + (isOriginal ? myNewVisibility : + VisibilityUtil.getHighestVisibility(myNewVisibility, + VisibilityUtil.getVisibilityModifier(modifierList))); + RefactoringUtil.setVisibility(modifierList, highestVisibility); + } + + final PsiSubstitutor substitutor = calculateSubstitutor(method); + + if (myChangeInfo.isNameChanged) { + final EjbMethodRole role = J2EERolesUtil.getEjbRole(method); + if (role instanceof EjbImplMethodRole && myChangeInfo.ejbRole instanceof EjbDeclMethodRole) { + EjbDeclMethodRole declRole = (EjbDeclMethodRole) myChangeInfo.ejbRole; + + String newName = myChangeInfo.newName; + final PsiMethod[] oldImpl = declRole.suggestImplementations(); + for (int i = 0; i < oldImpl.length; i++) { + PsiMethod oldMethod = oldImpl[i]; + if (oldMethod.getName().equals(method.getName())) { + PsiMethod newDeclMethod = (PsiMethod) method.copy(); + newDeclMethod.getNameIdentifier().replace(myChangeInfo.newNameIdentifier); + EjbDeclMethodRole newDeclRole = new EjbDeclMethodRole(newDeclMethod, declRole.getEjb(), declRole.getType()); + + newName = newDeclRole.suggestImplementations()[i].getName(); + break; + } + } + method.getNameIdentifier().replace(factory.createIdentifier(newName)); + } else { + method.getNameIdentifier().replace(myChangeInfo.newNameIdentifier); + } + } + + if (myChangeInfo.isReturnTypeChanged) { + //TODO : normalize brackets! + + final PsiType returnType = substitutor.substitute(myChangeInfo.newTypeElement); + method.getReturnTypeElement().replace(factory.createTypeElement(returnType)); + } + + PsiParameterList list = method.getParameterList(); + PsiParameter[] parameters = list.getParameters(); + + PsiParameter[] newParms = new PsiParameter[myChangeInfo.newParms.length]; + for (int i = 0; i < newParms.length; i++) { + ParameterInfo info = myChangeInfo.newParms[i]; + int index = info.oldParameterIndex; + if (index >= 0) { + PsiParameter parameter = parameters[index]; + newParms[i] = parameter; + + String oldName = myChangeInfo.oldParameterNames[index]; + if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) { + PsiIdentifier newIdentifier = factory.createIdentifier(info.getName()); + parameter.getNameIdentifier().replace(newIdentifier); + } + + String oldType = myChangeInfo.oldParameterTypes[index]; + if (!oldType.equals(info.getTypeText())) { + parameter.normalizeDeclaration(); + PsiType newType = substitutor.substitute(info.createType(myChangeInfo.getMethod().getParameterList())); + + parameter.getTypeElement().replace(factory.createTypeElement(newType)); + } + } else { + newParms[i] = createNewParameter(info, substitutor); +// newParms[i] = factory.createParameterFromText(info.type + " " + info.name, myResolutionContext); +// newParms[i].getTypeElement().replace(getTypeFromName(type)); + } + } + + List conflictResolvers = new ArrayList(); + final ParameterInfo[] newParmsInfo = myChangeInfo.newParms; + for (int i = 0; i < newParmsInfo.length; i++) { + ParameterInfo parameterInfo = newParmsInfo[i]; + conflictResolvers.add(new FieldConflictsResolver(parameterInfo.getName(), method.getBody())); + } + ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newParms), ParameterList.INSTANCE, myChangeInfo.toRemoveParm); + for (int i = 0; i < conflictResolvers.size(); i++) { + FieldConflictsResolver fieldConflictsResolver = conflictResolvers.get(i); + fieldConflictsResolver.fix(); + } + } + + private PsiSubstitutor calculateSubstitutor(PsiMethod method) { + PsiSubstitutor substitutor; + if (method.getManager().areElementsEquivalent(method, myChangeInfo.getMethod())) { + substitutor = PsiSubstitutor.EMPTY; + } else { + final PsiClass sourceClass = myChangeInfo.getMethod().getContainingClass(); + final PsiClass containingClass = method.getContainingClass(); + if(sourceClass != null && containingClass != null && InheritanceUtil.isInheritorOrSelf(containingClass, sourceClass, true)) { + final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(sourceClass, containingClass, PsiSubstitutor.EMPTY); + final MethodSignature superMethodSignature = myChangeInfo.getMethod().getSignature(superClassSubstitutor); + final MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY); + final PsiSubstitutor superMethodSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superMethodSignature); + if (superMethodSubstitutor != null) { + substitutor = superMethodSubstitutor; + } + else { + substitutor = superClassSubstitutor; + } + } else { + substitutor = PsiSubstitutor.EMPTY; + } + } + return substitutor; + } + + private static void processParameterUsage(PsiReferenceExpression ref, String oldName, String newName) + throws IncorrectOperationException { + + PsiElement last = ref.getReferenceNameElement(); + if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { + PsiElementFactory factory = ref.getManager().getElementFactory(); + PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); + last.replace(newNameIdentifier); + } + } + + private static class MyParameterUsageInfo extends UsageInfo { + final String oldParameterName; + final String newParameterName; + + public MyParameterUsageInfo(PsiElement element, String oldParameterName, String newParameterName) { + super(element); + this.oldParameterName = oldParameterName; + this.newParameterName = newParameterName; + } + } + + public static class EjbUsageInfo extends UsageInfo { + public EjbUsageInfo(PsiMethod implementation) { + super(implementation); + } + } + + public static PsiElement normalizeResolutionContext(PsiElement resolutionContext) { + PsiElement result = PsiTreeUtil.getParentOfType(resolutionContext, NORMALIZED_RESOLUTION_CONTEXT_CLASSES, false); + if (result != null) { + return result; + } else { + return resolutionContext; + } + } + + private static class RenamedParameterCollidesWithLocalUsageInfo extends UnresolvableCollisionUsageInfo { + private final PsiElement myCollidingElement; + private final PsiMethod myMethod; + + public RenamedParameterCollidesWithLocalUsageInfo(PsiParameter parameter, PsiElement collidingElement, PsiMethod method) { + super(parameter, collidingElement); + myCollidingElement = collidingElement; + myMethod = method; + } + + public String getDescription() { + StringBuffer buffer = new StringBuffer(); + buffer.append("There is already a "); + buffer.append(ConflictsUtil.getDescription(myCollidingElement, true)); + buffer.append(" in the "); + buffer.append(ConflictsUtil.getDescription(myMethod, true)); + buffer.append(". It will conflict with the renamed parameter."); + return buffer.toString(); + } + } + + private void fixJavadocsForChangedMethod(PsiMethod method) throws IncorrectOperationException { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final ParameterInfo[] newParms = myChangeInfo.newParms; + LOG.assertTrue(parameters.length == newParms.length); + final Set newParameters = new HashSet(); + for (int i = 0; i < newParms.length; i++) { + ParameterInfo newParm = newParms[i]; + if (newParm.oldParameterIndex < 0) { + newParameters.add(parameters[i]); + } + } + RefactoringUtil.fixJavadocsForParams(method, newParameters); + } + + private static class ExpressionList implements ChangeSignatureUtil.ChildrenGenerator { + public static final ExpressionList INSTANCE = new ExpressionList(); + private ExpressionList() {} + public List getChildren(PsiExpressionList psiExpressionList) { + return Arrays.asList(psiExpressionList.getExpressions()); + } + } + + private static class ParameterList implements ChangeSignatureUtil.ChildrenGenerator { + public static final ParameterList INSTANCE = new ParameterList(); + private ParameterList() {} + public List getChildren(PsiParameterList psiParameterList) { + return Arrays.asList(psiParameterList.getParameters()); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java new file mode 100644 index 00000000000..5dc5404ed2c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java @@ -0,0 +1,62 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +/** + * @author dsl + */ +public class ChangeSignatureUtil { + private ChangeSignatureUtil() {} + + public static + void synchronizeList(Parent list, + final List newElements, ChildrenGenerator generator, final boolean[] shouldRemoveChild) + throws IncorrectOperationException { + + ArrayList elementsToRemove = null; + List elements; + + int index = 0; + while (true) { + elements = generator.getChildren(list); + if (index == newElements.size()) break; + + if (elementsToRemove == null) { + elementsToRemove = new ArrayList(); + for (int i = 0; i < shouldRemoveChild.length; i++) { + if (shouldRemoveChild[i]) { + elementsToRemove.add(elements.get(i)); + } + } + } + + Child oldElement = index < elements.size() ? elements.get(index) : null; + Child newElement = newElements.get(index); + if (!newElement.equals(oldElement)) { + if (oldElement != null && elementsToRemove.contains(oldElement)) { + oldElement.delete(); + index--; + } else { + list.addBefore(newElement, oldElement); + if (list.equals(newElement.getParent())) { + newElement.delete(); + } + } + } + index++; + } + for (int i = newElements.size(); i < elements.size(); i++) { + Child element = elements.get(i); + element.delete(); + } + } + + public static interface ChildrenGenerator { + List getChildren(Parent parent); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java new file mode 100644 index 00000000000..982b82f1644 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java @@ -0,0 +1,102 @@ +/** + * created at Sep 17, 2001 + * @author Jeka + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class ChangeSignatureViewDescriptor implements UsageViewDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureViewDescriptor"); + + private PsiMethod myMethod; + private UsageInfo[] myUsages; + private final String myProcessedElementsHeader; + private FindUsagesCommand myRefreshCommand; + + public ChangeSignatureViewDescriptor(PsiMethod method, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myMethod = method; + myUsages = usages; + myRefreshCommand = refreshCommand; + myProcessedElementsHeader = UsageViewUtil.capitalize(UsageViewUtil.getType(method) + " to change signature"); + } + + public PsiElement[] getElements() { + return new PsiElement[] {myMethod}; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + if (elements.length == 1 && elements[0] instanceof PsiMethod) { + myMethod = (PsiMethod)elements[0]; + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myProcessedElementsHeader; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References to be changed " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, getCodeReferencesWord()); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return true; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ExceptionsTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ExceptionsTableModel.java new file mode 100644 index 00000000000..cdb31a355ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ExceptionsTableModel.java @@ -0,0 +1,130 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.refactoring.ui.RowEditableTableModel; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.psi.*; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.table.AbstractTableModel; +import java.util.List; +import java.util.Collections; +import java.util.ArrayList; + +/** + * @author ven + */ +class ExceptionsTableModel extends AbstractTableModel implements RowEditableTableModel { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterTableModel"); + + private List myTypeCodeFraments; + private final PsiElement myContext; + private List myExceptionInfos; + + public ExceptionsTableModel(PsiElement context) { + myContext = context; + } + + public ThrownExceptionInfo[] getThrownExceptions() { + return myExceptionInfos.toArray(new ThrownExceptionInfo[myExceptionInfos.size()]); + } + + public void addRow() { + myExceptionInfos.add(new ThrownExceptionInfo()); + myTypeCodeFraments.add(createParameterTypeCodeFragment("", myContext)); + fireTableRowsInserted(myTypeCodeFraments.size() - 1, myTypeCodeFraments.size() - 1); + } + + public void removeRow(int index) { + myExceptionInfos.remove(index); + myTypeCodeFraments.remove(index); + fireTableRowsDeleted(index, index); + } + + public void exchangeRows(int index1, int index2) { + Collections.swap(myExceptionInfos, index1, index2); + Collections.swap(myTypeCodeFraments, index1, index2); + if (index1 < index2) { + fireTableRowsUpdated(index1, index2); + } + else { + fireTableRowsUpdated(index2, index1); + } + } + + public int getRowCount() { + return myTypeCodeFraments.size(); + } + + public int getColumnCount() { + return 1; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + if (columnIndex == 0) { + return myTypeCodeFraments.get(rowIndex); + } + + throw new IllegalArgumentException(); + } + + public String getColumnName(int column) { + switch (column) { + case 0: + return "Type"; + default: + throw new IllegalArgumentException(); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case 0: + return true; + + default: + throw new IllegalArgumentException(); + } + } + + PsiType getTypeByRow(int row) { + Object typeValueAt = getValueAt(row, 0); + LOG.assertTrue(typeValueAt instanceof PsiTypeCodeFragment); + PsiType type; + try { + type = ((PsiTypeCodeFragment)typeValueAt).getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e1) { + type = null; + } + catch (PsiTypeCodeFragment.NoTypeException e1) { + type = null; + } + return type; + } + + public void setTypeInfos(PsiMethod method) { + PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes(); + myTypeCodeFraments = new ArrayList(referencedTypes.length); + myExceptionInfos = new ArrayList(referencedTypes.length); + for (int i = 0; i < referencedTypes.length; i++) { + CanonicalTypes.Type typeWrapper = CanonicalTypes.createTypeWrapper(referencedTypes[i]); + myTypeCodeFraments.add(createParameterTypeCodeFragment(typeWrapper.getTypeText(), method.getThrowsList())); + myExceptionInfos.add(new ThrownExceptionInfo(i, referencedTypes[i])); + } + } + + PsiTypeCodeFragment createParameterTypeCodeFragment(final String typeText, PsiElement context) { + return myContext.getManager().getElementFactory().createTypeCodeFragment( + typeText, context, false, true, true + ); + } + + PsiTypeCodeFragment[] getTypeCodeFragments() { + return myTypeCodeFraments.toArray(new PsiTypeCodeFragment[myTypeCodeFraments.size()]); + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + super.setValueAt(aValue, rowIndex, columnIndex); + fireTableCellUpdated(rowIndex, columnIndex); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/NewParameterCollidesWithLocalUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/NewParameterCollidesWithLocalUsageInfo.java new file mode 100644 index 00000000000..1ec09e420dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/NewParameterCollidesWithLocalUsageInfo.java @@ -0,0 +1,33 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo; +import com.intellij.refactoring.util.ConflictsUtil; + +/** + * @author dsl + */ +public class NewParameterCollidesWithLocalUsageInfo extends UnresolvableCollisionUsageInfo { + private final PsiElement myConflictingElement; + private final PsiMethod myMethod; + + public NewParameterCollidesWithLocalUsageInfo(PsiElement element, PsiElement referencedElement, + PsiMethod method) { + super(element, referencedElement); + myConflictingElement = referencedElement; + myMethod = method; + } + + public String getDescription() { + StringBuffer buffer = new StringBuffer(); + + buffer.append("There is already a "); + buffer.append(ConflictsUtil.getDescription(myConflictingElement, true)); + buffer.append("in a "); + buffer.append(ConflictsUtil.getDescription(myMethod, true)); + buffer.append(". It will conflict with the new parameter."); + + return ConflictsUtil.capitalize(buffer.toString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterInfo.java new file mode 100644 index 00000000000..84462451459 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterInfo.java @@ -0,0 +1,127 @@ +/** + * created at Sep 17, 2001 + * @author Jeka + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; +import java.util.ArrayList; + +public class ParameterInfo { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterInfo"); + int oldParameterIndex; + boolean useAnySingleVariable; + private String name = ""; + private CanonicalTypes.Type myType; + + String defaultValue = ""; + + public ParameterInfo(int oldParameterIndex) { + this.oldParameterIndex = oldParameterIndex; + } + + public ParameterInfo(int oldParameterIndex, String name, PsiType aType) { + setName(name); + this.oldParameterIndex = oldParameterIndex; + setType(aType); + } + + public ParameterInfo(int oldParameterIndex, String name, PsiType aType, String defaultValue) { + this(oldParameterIndex, name, aType, defaultValue, false); + } + + public ParameterInfo(int oldParameterIndex, String name, PsiType aType, String defaultValue, boolean useAnyVariable) { + this(oldParameterIndex, name, aType); + this.defaultValue = defaultValue; + this.useAnySingleVariable = useAnyVariable; + } + + public void setUseAnySingleVariable(boolean useAnySingleVariable) { + this.useAnySingleVariable = useAnySingleVariable; + } + + public void updateFromMethod(PsiMethod method) { + if (getTypeWrapper() != null) return; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + LOG.assertTrue(oldParameterIndex >= 0 && oldParameterIndex < parameters.length); + final PsiParameter parameter = parameters[oldParameterIndex]; + setName(parameter.getName()); + setType(parameter.getType()); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ParameterInfo)) return false; + + ParameterInfo parameterInfo = (ParameterInfo) o; + + if (oldParameterIndex != parameterInfo.oldParameterIndex) return false; + if (defaultValue != null ? !defaultValue.equals(parameterInfo.defaultValue) : parameterInfo.defaultValue != null) return false; + if (!getName().equals(parameterInfo.getName())) return false; + if (!getTypeText().equals(parameterInfo.getTypeText())) return false; + + return true; + } + + public int hashCode() { + int result; + result = getName().hashCode(); + result = 29 * result + getTypeText().hashCode(); + return result; + } + + public String getTypeText() { + if (getTypeWrapper() != null) { + return getTypeWrapper().getTypeText(); + } + else { + return ""; + } + } + + PsiType createType(PsiElement context) throws IncorrectOperationException { + if (getTypeWrapper() != null) { + return getTypeWrapper().getType(context); + } else { + return null; + } + } + + void setType(PsiType type) { + myType = CanonicalTypes.createTypeWrapper(type); + } + + public String getName() { + return name; + } + + public CanonicalTypes.Type getTypeWrapper() { + return myType; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isVarargType() { + return getTypeText().endsWith("..."); + } + + public static ParameterInfo[] fromMethod(PsiMethod method) { + List result = new ArrayList(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + result.add(new ParameterInfo(i, parameter.getName(), parameter.getType())); + } + return result.toArray(new ParameterInfo[result.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterTableModel.java new file mode 100644 index 00000000000..8e11caa12ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ParameterTableModel.java @@ -0,0 +1,205 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.refactoring.ui.RowEditableTableModel; +import com.intellij.psi.*; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.table.AbstractTableModel; +import java.util.List; +import java.util.Collections; +import java.util.ArrayList; + +/** + * @author ven + */ +class ParameterTableModel extends AbstractTableModel implements RowEditableTableModel { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterTableModel"); + private List myParameterInfos; + private List myTypeCodeFraments; + private List myDefaultValuesCodeFragments; + private final PsiElement myContext; + private final ChangeSignatureDialog myDialog; + + public ParameterTableModel(PsiElement context, ChangeSignatureDialog dialog) { + myContext = context; + myDialog = dialog; + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == 3) return Boolean.class; + return super.getColumnClass(columnIndex); + } + + public List getCodeFraments() { + return Collections.unmodifiableList(myTypeCodeFraments); + } + + public List getDefaultValueFraments() { + return Collections.unmodifiableList(myDefaultValuesCodeFragments); + } + + public ParameterInfo[] getParameters() { + return myParameterInfos.toArray(new ParameterInfo[myParameterInfos.size()]); + } + + + public void addRow() { + ParameterInfo info = new ParameterInfo(-1); + myParameterInfos.add(info); + myTypeCodeFraments.add(createParameterTypeCodeFragment("", myContext)); + myDefaultValuesCodeFragments.add(createDefaultValueCodeFragment("")); + fireTableRowsInserted(myParameterInfos.size() - 1, myParameterInfos.size() - 1); + } + + public void removeRow(int index) { + myParameterInfos.remove(index); + myTypeCodeFraments.remove(index); + myDefaultValuesCodeFragments.remove(index); + fireTableRowsDeleted(index, index); + } + + public void exchangeRows(int index1, int index2) { + Collections.swap(myParameterInfos, index1, index2); + Collections.swap(myTypeCodeFraments, index1, index2); + Collections.swap(myDefaultValuesCodeFragments, index1, index2); + if (index1 < index2) { + fireTableRowsUpdated(index1, index2); + } + else { + fireTableRowsUpdated(index2, index1); + } + } + + public int getRowCount() { + return myParameterInfos.size(); + } + + public int getColumnCount() { + return myDialog.isGenerateDelegate() ? 3 : 4; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + ParameterInfo info = myParameterInfos.get(rowIndex); + switch (columnIndex) { + case 0: + return myTypeCodeFraments.get(rowIndex); + case 1: + return info.getName(); + case 2: + return myDefaultValuesCodeFragments.get(rowIndex); + case 3: + return Boolean.valueOf(info.useAnySingleVariable); + + default: + throw new IllegalArgumentException(); + } + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex < 0 || rowIndex >= myParameterInfos.size()) return; + String s = aValue instanceof String ? (String)aValue : null; + if (s == null) s = ""; + s = s.trim(); + ParameterInfo info = myParameterInfos.get(rowIndex); + switch (columnIndex) { + case 0: + //info.setType(); + break; + + case 1: + info.setName(s); + break; + + case 2: + break; + + case 3: + info.setUseAnySingleVariable(((Boolean) aValue).booleanValue()); + break; + + default: + throw new IllegalArgumentException(); + } + fireTableCellUpdated(rowIndex, columnIndex); + } + + public String getColumnName(int column) { + switch (column) { + case 0: + return "Type"; + case 1: + return "Name"; + case 2: + return "Default value"; + case 3: + return "Any var"; + default: + throw new IllegalArgumentException(); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case 0: + case 1: + return true; + + case 2: + { + final PsiType typeByRow = getTypeByRow(rowIndex); + final boolean isEllipsis = typeByRow instanceof PsiEllipsisType; + ParameterInfo info = myParameterInfos.get(rowIndex); + return !isEllipsis && info.oldParameterIndex < 0; + } + + case 3: + { + final PsiType typeByRow = getTypeByRow(rowIndex); + final boolean isEllipsis = typeByRow instanceof PsiEllipsisType; + return !isEllipsis && myParameterInfos.get(rowIndex).oldParameterIndex < 0; + } + + default: + throw new IllegalArgumentException(); + } + } + + private PsiCodeFragment createDefaultValueCodeFragment(final String expressionText) { + PsiExpressionCodeFragment codeFragment = myContext.getManager().getElementFactory().createExpressionCodeFragment(expressionText, null, true); + codeFragment.setEverythingAcessible(true); + return codeFragment; + } + + PsiType getTypeByRow(int row) { + Object typeValueAt = getValueAt(row, 0); + LOG.assertTrue(typeValueAt instanceof PsiTypeCodeFragment); + PsiType type; + try { + type = ((PsiTypeCodeFragment)typeValueAt).getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e1) { + type = null; + } + catch (PsiTypeCodeFragment.NoTypeException e1) { + type = null; + } + return type; + } + + public void setParameterInfos(List parameterInfos, PsiElement context) { + myParameterInfos = parameterInfos; + myTypeCodeFraments = new ArrayList(parameterInfos.size()); + myDefaultValuesCodeFragments = new ArrayList(parameterInfos.size()); + for (int i = 0; i < parameterInfos.size(); i++) { + ParameterInfo parameterInfo = parameterInfos.get(i); + myTypeCodeFraments.add(createParameterTypeCodeFragment(parameterInfo.getTypeText(), context)); + myDefaultValuesCodeFragments.add(createDefaultValueCodeFragment(parameterInfo.defaultValue)); + } + } + + PsiTypeCodeFragment createParameterTypeCodeFragment(final String typeText, PsiElement context) { + return myContext.getManager().getElementFactory().createTypeCodeFragment( + typeText, context, false, true, true + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ThrownExceptionInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ThrownExceptionInfo.java new file mode 100644 index 00000000000..ce870936f38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/changeSignature/ThrownExceptionInfo.java @@ -0,0 +1,55 @@ +package com.intellij.refactoring.changeSignature; + +import com.intellij.psi.*; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.util.IncorrectOperationException; + +/** + * @author ven + */ +public class ThrownExceptionInfo { + int oldIndex; + CanonicalTypes.Type myType; + + public ThrownExceptionInfo() { + oldIndex = -1; + } + + public ThrownExceptionInfo(int oldIndex) { + this.oldIndex = oldIndex; + } + + public ThrownExceptionInfo(int oldIndex, PsiClassType type) { + this.oldIndex = oldIndex; + setType(type); + } + + void setType(PsiClassType type) { + myType = CanonicalTypes.createTypeWrapper(type); + } + + public PsiType createType(PsiElement context) throws IncorrectOperationException { + if (myType != null) { + return myType.getType(context); + } else { + return null; + } + } + + String getTypeText() { + if (myType != null) { + return myType.getTypeText(); + } + else { + return ""; + } + } + + public void updateFromMethod(PsiMethod method) { + if (myType != null) return; + PsiClassType[] types = method.getThrowsList().getReferencedTypes(); + if (oldIndex >= 0) { + setType(types[oldIndex]); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java new file mode 100644 index 00000000000..521683e4e4c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java @@ -0,0 +1,124 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.ui.BaseRefactoringDialog; +import com.intellij.refactoring.ui.VisibilityPanel; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.usageView.UsageViewUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodDialog extends BaseRefactoringDialog { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodDialog"); + private final PsiMethod myMethod; + private final PsiParameter[] myParameters; + private JList myList; + + private VisibilityPanel myVisibilityPanel; + + ConvertToInstanceMethodDialog(final PsiMethod method, final PsiParameter[] parameters) { + super(method.getProject(), true); + myMethod = method; + myParameters = parameters; + setTitle(ConvertToInstanceMethodHandler.REFACTORING_NAME); + init(); + } + + protected JComponent createCenterPanel() { + final Box vBox = Box.createVerticalBox(); + final Box labelBox = Box.createHorizontalBox(); + final JLabel jLabel = new JLabel("Select an instance parameter:"); + jLabel.setDisplayedMnemonic('i'); + labelBox.add(jLabel); + labelBox.add(Box.createHorizontalGlue()); + vBox.add(labelBox); + vBox.add(Box.createVerticalStrut(4)); + myList = new JList(new MyListModel()); + myList.setCellRenderer(new MyListCellRenderer()); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myList.setSelectedIndex(0); + myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + getOKAction().setEnabled(!myList.getSelectionModel().isSelectionEmpty()); + } + }); + final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myList); + final JPanel hBox = new JPanel(new GridBagLayout()); + final GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.weighty = 0; + gbConstraints.gridheight = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + gbConstraints.insets = new Insets(0, 0, 0, 0); + hBox.add(scrollPane, gbConstraints); + hBox.add(Box.createHorizontalStrut(4)); + gbConstraints.weightx = 0; + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.gridx++; + myVisibilityPanel = createVisibilityPanel (); + hBox.add (myVisibilityPanel, gbConstraints); + + vBox.add(hBox); + return vBox; + } + + private VisibilityPanel createVisibilityPanel() { + final VisibilityPanel visibilityPanel = new VisibilityPanel (false); + visibilityPanel.setVisibility (VisibilityUtil.getVisibilityModifier (myMethod.getModifierList())); + return visibilityPanel; + } + + protected void doAction() { + final PsiParameter targetParameter = (PsiParameter)myList.getSelectedValue(); + LOG.assertTrue(targetParameter != null); + final ConvertToInstanceMethodProcessor processor = new ConvertToInstanceMethodProcessor(myMethod.getProject(), + myMethod, targetParameter, myVisibilityPanel.getVisibility()); + final PsiClass targetClass = processor.getTargetClass(); + if (targetClass.isInterface()) { + final String message = UsageViewUtil.getDescriptiveName(targetClass) + " is an interface. \n" + + "Method implementation will be added to all directly implementing classes.\n Proceed?"; + + final int result = Messages.showYesNoDialog(myProject, message, ConvertToInstanceMethodHandler.REFACTORING_NAME, + Messages.getQuestionIcon()); + if (result != 0) return; + } + invokeRefactoring(processor); + } + + private class MyListModel extends AbstractListModel { + public int getSize() { + return myParameters.length; + } + + public Object getElementAt(int index) { + return myParameters[index]; + } + } + + private static class MyListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + final PsiParameter psiParameter = (PsiParameter)value; + final String text = PsiFormatUtil.formatVariable(psiParameter, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE, + PsiSubstitutor.EMPTY); + setText(text); + return this; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodHandler.java new file mode 100644 index 00000000000..0b398f9d5d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodHandler.java @@ -0,0 +1,98 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler"); + static final String REFACTORING_NAME = "Convert To Instance Method"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + if (element == null) { + element = file.findElementAt(editor.getCaretModel().getOffset()); + } + + if (element == null) return; + if (element instanceof PsiIdentifier) element = element.getParent(); + + if(!(element instanceof PsiMethod)) { + String message = "Cannot perform the refactoring.\n" + + "The caret should be positioned at the name of the method to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.CONVERT_TO_INSTANCE_METHOD, project); + return; + } + if(LOG.isDebugEnabled()) { + LOG.debug("MakeMethodStaticHandler invoked"); + } + invoke(project, new PsiElement[]{element}, dataContext); + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1 || !(elements[0] instanceof PsiMethod)) return; + final PsiMethod method = ((PsiMethod)elements[0]); + if (!method.hasModifierProperty(PsiModifier.STATIC)) { + String message = "Cannot perform the refactoring\n" + + "Method " + method.getName() + " is not static."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.CONVERT_TO_INSTANCE_METHOD, project); + return; + } + final PsiParameter[] parameters = method.getParameterList().getParameters(); + List suitableParameters = new ArrayList(); + boolean classTypesFound = false; + boolean resolvableClassesFound = false; + boolean classesInProjectFound = false; + for (int i = 0; i < parameters.length; i++) { + final PsiParameter parameter = parameters[i]; + final PsiType type = parameter.getType(); + if (type instanceof PsiClassType) { + classTypesFound = true; + final PsiClass psiClass = ((PsiClassType)type).resolve(); + if (psiClass != null) { + resolvableClassesFound = true; + final boolean inProject = method.getManager().isInProject(psiClass); + if (inProject) { + classesInProjectFound = true; + suitableParameters.add(parameter); + } + } + } + } + if (suitableParameters.isEmpty()) { + String message = null; + if (!classTypesFound) { + message = "There are no parameters that have a reference type"; + } + else if (!resolvableClassesFound) { + message = "All reference type parametres have unknown types"; + } + else if (!classesInProjectFound) { + message = "All reference type parameters have types that are not in project"; + } + LOG.assertTrue(message != null); + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, + "Cannot perform refactoring.\n" + message, + HelpID.CONVERT_TO_INSTANCE_METHOD, project); + return; + } + final ConvertToInstanceMethodDialog dialog = new ConvertToInstanceMethodDialog( + method, + (PsiParameter[])suitableParameters.toArray(new PsiParameter[suitableParameters.size()])); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java new file mode 100644 index 00000000000..483219de47d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java @@ -0,0 +1,350 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodProcessor"); + private PsiMethod myMethod; + private PsiParameter myTargetParameter; + private PsiClass myTargetClass; + private Map myTypeParameterReplacements; + private static final Key BIND_TO_TYPE_PARAMETER = Key.create("REPLACEMENT"); + private final String myOldVisibility; + private final String myNewVisibility; + + + public ConvertToInstanceMethodProcessor(final Project project, + final PsiMethod method, + final PsiParameter targetParameter, + final String newVisibility) { + super(project); + myMethod = method; + myTargetParameter = targetParameter; + LOG.assertTrue(method.hasModifierProperty(PsiModifier.STATIC)); + LOG.assertTrue(myTargetParameter.getDeclarationScope() == myMethod); + LOG.assertTrue(myTargetParameter.getType() instanceof PsiClassType); + final PsiType type = myTargetParameter.getType(); + LOG.assertTrue(type instanceof PsiClassType); + final PsiClass targetClass = ((PsiClassType) type).resolve(); + myTargetClass = targetClass; + myOldVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList ()); + myNewVisibility = newVisibility; + } + + public PsiClass getTargetClass() { + return myTargetClass; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new ConvertToInstanceMethodViewDescriptor(usages, refreshCommand, myMethod, myTargetParameter, myTargetClass); + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == 3); + myMethod = (PsiMethod) elements[0]; + myTargetParameter = (PsiParameter) elements[1]; + myTargetClass = (PsiClass) elements[2]; + } + + protected UsageInfo[] findUsages() { + LOG.assertTrue(myTargetParameter.getDeclarationScope() == myMethod); + final PsiManager manager = myMethod.getManager(); + final Project project = manager.getProject(); + PsiSearchHelper searchHelper = manager.getSearchHelper(); + + final PsiReference[] methodReferences = searchHelper.findReferences(myMethod, GlobalSearchScope.projectScope(project), false); + List result = new ArrayList(); + for (int i = 0; i < methodReferences.length; i++) { + final PsiReference ref = methodReferences[i]; + if (ref.getElement() instanceof PsiReferenceExpression) { + if (ref.getElement().getParent() instanceof PsiMethodCallExpression) { + result.add(new MethodCallUsageInfo((PsiMethodCallExpression) ref.getElement().getParent())); + } + } + else if (ref.getElement() instanceof PsiDocTagValue) { + result.add(new JavaDocUsageInfo(ref)); + } + } + + PsiReference[] parameterReferences = searchHelper.findReferences(myTargetParameter, new LocalSearchScope(myMethod), false); + for (int i = 0; i < parameterReferences.length; i++) { + final PsiReference ref = parameterReferences[i]; + if (ref.getElement() instanceof PsiReferenceExpression) { + result.add(new ParameterUsageInfo((PsiReferenceExpression) ref)); + } + } + + if (myTargetClass.isInterface()) { + PsiClass[] implementingClasses = RefactoringHierarchyUtil.findImplementingClasses(myTargetClass); + for (int i = 0; i < implementingClasses.length; i++) { + final PsiClass implementingClass = implementingClasses[i]; + result.add(new ImplementingClassUsageInfo(implementingClass)); + } + } + + + return result.toArray(new UsageInfo[result.size()]); + } + + + protected boolean preprocessUsages(UsageInfo[][] usages) { + final UsageInfo[] usageList = usages[0]; + ArrayList conflicts = new ArrayList(); + final Set methods = Collections.singleton(((PsiMember)myMethod)); + if (!myTargetClass.isInterface()) { + final String original = VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()); + conflicts.addAll(Arrays.asList(MoveMembersProcessor.analyzeAccessibilityConflicts(methods, myTargetClass, new LinkedHashSet(), original))); + } + else { + for (int i = 0; i < usageList.length; i++) { + final UsageInfo usage = usageList[i]; + if (usage instanceof ImplementingClassUsageInfo) { + conflicts.addAll(Arrays.asList(MoveMembersProcessor.analyzeAccessibilityConflicts( + methods, ((ImplementingClassUsageInfo)usage).getPsiClass(), new LinkedHashSet(), PsiModifier.PUBLIC))); + } + } + } + + for (int i = 0; i < usageList.length; i++) { + final UsageInfo usageInfo = usageList[i]; + if (usageInfo instanceof MethodCallUsageInfo) { + final PsiMethodCallExpression methodCall = ((MethodCallUsageInfo)usageInfo).getMethodCall(); + final PsiExpression[] expressions = methodCall.getArgumentList().getExpressions(); + final int index = myMethod.getParameterList().getParameterIndex(myTargetParameter); + if (index < expressions.length) { + PsiExpression instanceValue = expressions[index]; + instanceValue = RefactoringUtil.unparenthesizeExpression(instanceValue); + if (instanceValue instanceof PsiLiteralExpression && ((PsiLiteralExpression)instanceValue).getValue() == null) { + String message = + ConflictsUtil.getDescription(ConflictsUtil.getContainer(methodCall), true) + " contains call with null argument for parameter " + + ConflictsUtil.htmlEmphasize(myTargetParameter.getName()); + conflicts.add(message); + } + } + } + } + + if (conflicts.size() != 0) { + final ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), myProject); + conflictsDialog.show(); + if (!conflictsDialog.isOK()) return false; + } + return super.preprocessUsages(usages); + } + + protected void performRefactoring(UsageInfo[] usages) { + final LvcsAction lvcsAction = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + try { + doRefactoring(usages); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + finally{ + LvcsIntegration.checkinFilesAfterRefactoring(myProject, lvcsAction); + } + } + + private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { + myTypeParameterReplacements = buildTypeParameterReplacements(); + List inheritors = new ArrayList(); + // Process usages + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + if (usage instanceof MethodCallUsageInfo) { + processMethodCall((MethodCallUsageInfo) usage); + } + else if (usage instanceof ParameterUsageInfo) { + processParameterUsage((ParameterUsageInfo) usage); + } + else if (usage instanceof ImplementingClassUsageInfo) { + inheritors.add(((ImplementingClassUsageInfo)usage).getPsiClass()); + } + } + + prepareTypeParameterReplacement(); + myTargetParameter.delete(); + ChangeContextUtil.encodeContextInfo(myMethod, true); + if (!myTargetClass.isInterface()) { + addMethodToClass(myTargetClass); + } + else { + final PsiMethod interfaceMethod = addMethodToClass(myTargetClass); + RefactoringUtil.abstractizeMethod(myTargetClass, interfaceMethod); + for (Iterator iterator = inheritors.iterator(); iterator.hasNext();) { + final PsiClass psiClass = iterator.next(); + final PsiMethod newMethod = addMethodToClass(psiClass); + newMethod.getModifierList().setModifierProperty((myNewVisibility != null ? myNewVisibility : PsiModifier.PUBLIC), true); + } + } + myMethod.delete(); + } + + private void prepareTypeParameterReplacement() throws IncorrectOperationException { + if (myTypeParameterReplacements == null) return; + final Collection typeParameters = myTypeParameterReplacements.keySet(); + for (Iterator iterator = typeParameters.iterator(); iterator.hasNext();) { + final PsiTypeParameter parameter = iterator.next(); + final PsiReference[] references = myMethod.getManager().getSearchHelper().findReferences(parameter, new LocalSearchScope(myMethod), false); + for (int i = 0; i < references.length; i++) { + final PsiReference reference = references[i]; + if (reference.getElement() instanceof PsiJavaCodeReferenceElement) { + reference.getElement().putCopyableUserData(BIND_TO_TYPE_PARAMETER, myTypeParameterReplacements.get(parameter)); + } + } + } + final Set methodTypeParameters = myTypeParameterReplacements.keySet(); + for (Iterator iterator = methodTypeParameters.iterator(); iterator.hasNext();) { + final PsiTypeParameter methodTypeParameter = iterator.next(); + methodTypeParameter.delete(); + } + } + + private PsiMethod addMethodToClass(final PsiClass targetClass) throws IncorrectOperationException { + final PsiMethod newMethod = (PsiMethod)targetClass.add(myMethod); + final PsiModifierList modifierList = newMethod.getModifierList(); + modifierList.setModifierProperty(PsiModifier.STATIC, false); + if (myNewVisibility != null && myNewVisibility != myOldVisibility) { + modifierList.setModifierProperty(myNewVisibility, true); + } + ChangeContextUtil.decodeContextInfo(newMethod, null, null); + if (myTypeParameterReplacements == null) return newMethod; + final Map additionalReplacements; + if (targetClass != myTargetClass) { + final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(myTargetClass, targetClass, PsiSubstitutor.EMPTY); + final Map map = calculateReplacementMap(superClassSubstitutor, myTargetClass, targetClass); + if (map == null) return newMethod; + additionalReplacements = new com.intellij.util.containers.HashMap(); + final Set entries = map.entrySet(); + for (Iterator iterator = entries.iterator(); iterator.hasNext();) { + final Map.Entry entry = iterator.next(); + additionalReplacements.put((PsiTypeParameter)entry.getValue(), (PsiTypeParameter)entry.getKey()); + } + } + else { + additionalReplacements = null; + } + newMethod.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + PsiTypeParameter typeParameterToBind = reference.getCopyableUserData(BIND_TO_TYPE_PARAMETER); + if (typeParameterToBind != null) { + reference.putCopyableUserData(BIND_TO_TYPE_PARAMETER, null); + try { + if (additionalReplacements != null) { + typeParameterToBind = additionalReplacements.get(typeParameterToBind); + } + reference.bindToElement(typeParameterToBind); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + else { + visitElement(reference); + } + } + }); + return newMethod; + } + + private void processParameterUsage(ParameterUsageInfo usage) throws IncorrectOperationException { + final PsiJavaCodeReferenceElement referenceExpression = usage.getReferenceExpression(); + if (referenceExpression.getParent() instanceof PsiReferenceExpression) { + // todo: check for correctness + referenceExpression.delete(); + } + else { + final PsiExpression expression = myMethod.getManager().getElementFactory().createExpressionFromText("this" , null); + referenceExpression.replace(expression); + } + } + + private void processMethodCall(MethodCallUsageInfo usageInfo) throws IncorrectOperationException { + PsiMethodCallExpression methodCall = usageInfo.getMethodCall(); + PsiParameterList parameterList = myMethod.getParameterList(); + PsiElementFactory factory = myMethod.getManager().getElementFactory(); + int parameterIndex = parameterList.getParameterIndex(myTargetParameter); + PsiExpression[] arguments = methodCall.getArgumentList().getExpressions(); + if (arguments.length <= parameterIndex) return; + final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); + final PsiExpression qualifier; + if (methodExpression.getQualifierExpression() != null) { + qualifier = methodExpression.getQualifierExpression(); + } + else { + final PsiReferenceExpression newRefExpr = (PsiReferenceExpression)factory.createExpressionFromText("x." + myMethod.getName(), null); + qualifier = ((PsiReferenceExpression)methodExpression.replace(newRefExpr)).getQualifierExpression(); + } + qualifier.replace(arguments[parameterIndex]); + arguments[parameterIndex].delete(); + } + + protected String getCommandName() { + return "Convert To Instance Method"; + } + + public Map buildTypeParameterReplacements() { + final PsiClassType type = (PsiClassType)myTargetParameter.getType(); + final PsiSubstitutor substitutor = type.resolveGenerics().getSubstitutor(); + return calculateReplacementMap(substitutor, myTargetClass, myMethod); + } + + private Map calculateReplacementMap(final PsiSubstitutor substitutor, + final PsiClass targetClass, + final PsiElement containingElement) { + final HashMap result = new HashMap(); + final Iterator iterator = PsiUtil.typeParametersIterator(targetClass); + while (iterator.hasNext()) { + final PsiTypeParameter classTypeParameter = iterator.next(); + final PsiType substitution = substitutor.substitute(classTypeParameter); + if (!(substitution instanceof PsiClassType)) return null; + final PsiClass aClass = ((PsiClassType)substitution).resolve(); + if (!(aClass instanceof PsiTypeParameter)) return null; + final PsiTypeParameter methodTypeParameter = ((PsiTypeParameter)aClass); + if (methodTypeParameter.getOwner() != containingElement) return null; + if (result.keySet().contains(methodTypeParameter)) return null; + result.put(methodTypeParameter, classTypeParameter); + } + return result; + } + + public PsiMethod getMethod() { + return myMethod; + } + + public PsiParameter getTargetParameter() { + return myTargetParameter; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodViewDescriptor.java new file mode 100644 index 00000000000..9d7e7f9a734 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodViewDescriptor.java @@ -0,0 +1,59 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodViewDescriptor extends UsageViewDescriptorAdapter { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodViewDescriptor"); + private PsiMethod myMethod; + private PsiParameter myTargetParameter; + private PsiClass myTargetClass; + + public ConvertToInstanceMethodViewDescriptor(UsageInfo[] usages, + FindUsagesCommand refreshCommand, + PsiMethod method, + PsiParameter targetParameter, + PsiClass targetClass) { + super(usages, refreshCommand); + myMethod = method; + myTargetParameter = targetParameter; + myTargetClass = targetClass; + } + + public PsiElement[] getElements() { + return new PsiElement[] {myMethod, myTargetParameter, myTargetClass}; + } + + public String getProcessedElementsHeader() { + return "Convert to instance method"; + } + + public boolean canRefresh() { + return false; + } + + public void refresh(PsiElement[] elements) { + if (elements.length == 3 && elements[0] instanceof PsiMethod && elements[1] instanceof PsiParameter) { + myMethod = (PsiMethod)elements[0]; + myTargetParameter = (PsiParameter) elements[1]; + myTargetClass = (PsiClass) elements[2]; + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ImplementingClassUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ImplementingClassUsageInfo.java new file mode 100644 index 00000000000..e31178fab1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ImplementingClassUsageInfo.java @@ -0,0 +1,20 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.usageView.UsageInfo; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiClass; + +/** + * @author dsl + */ +public class ImplementingClassUsageInfo extends UsageInfo { + private final PsiClass myClass; + public ImplementingClassUsageInfo(PsiClass aClass) { + super(aClass); + myClass = aClass; + } + + public PsiClass getPsiClass() { + return myClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/JavaDocUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/JavaDocUsageInfo.java new file mode 100644 index 00000000000..385d614de16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/JavaDocUsageInfo.java @@ -0,0 +1,19 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.usageView.UsageInfo; +import com.intellij.psi.PsiReference; + +/** + * @author dsl + */ +class JavaDocUsageInfo extends UsageInfo { + private final PsiReference myReference; + JavaDocUsageInfo(PsiReference ref) { + super(ref.getElement()); + myReference = ref; + } + + public PsiReference getReference() { + return myReference; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/MethodCallUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/MethodCallUsageInfo.java new file mode 100644 index 00000000000..cced1f8f3aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/MethodCallUsageInfo.java @@ -0,0 +1,23 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.usageView.UsageInfo; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiCallExpression; +import com.intellij.psi.PsiCall; +import com.intellij.psi.PsiMethodCallExpression; + +/** + * @author dsl + */ +class MethodCallUsageInfo extends UsageInfo { + private final PsiMethodCallExpression myMethodCall; + + public MethodCallUsageInfo(PsiMethodCallExpression methodCall) { + super(methodCall); + myMethodCall = methodCall; + } + + public PsiMethodCallExpression getMethodCall() { + return myMethodCall; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ParameterUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ParameterUsageInfo.java new file mode 100644 index 00000000000..a946fc83484 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/convertToInstanceMethod/ParameterUsageInfo.java @@ -0,0 +1,22 @@ +package com.intellij.refactoring.convertToInstanceMethod; + +import com.intellij.usageView.UsageInfo; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiReferenceExpression; + +/** + * @author dsl + */ +class ParameterUsageInfo extends UsageInfo { + private PsiReferenceExpression myReferenceExpression; + + public ParameterUsageInfo(PsiReferenceExpression refereneceElement) { + super(refereneceElement); + myReferenceExpression = refereneceElement; + } + + public PsiJavaCodeReferenceElement getReferenceExpression() { + return myReferenceExpression; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyClassDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyClassDialog.java new file mode 100644 index 00000000000..e1beca326b8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyClassDialog.java @@ -0,0 +1,185 @@ +package com.intellij.refactoring.copy; + +import com.intellij.ide.util.PackageChooserDialog; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class CopyClassDialog extends DialogWrapper{ + private JLabel myInformationLabel = new JLabel("X"); + private JLabel myNameLabel = new JLabel("Name:"); + private EditorTextField myNameField; + private JLabel myPackageLabel = new JLabel("Destination package:"); + private TextFieldWithBrowseButton myTfPackage; + private Project myProject; + private PsiDirectory myTargetDirectory; + private boolean myDoClone; + private final PsiDirectory myDefaultTargetDirectory; + + public CopyClassDialog(PsiClass aClass, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { + super(project, true); + init(); + myProject = project; + myDoClone = doClone; + myInformationLabel.setText((myDoClone ? "Clone " : "Copy ") + UsageViewUtil.getType(aClass) + " " + UsageViewUtil.getLongName(aClass)); + myNameField.setText(UsageViewUtil.getShortName(aClass)); + myDefaultTargetDirectory = defaultTargetDirectory; + if (myDefaultTargetDirectory != null) { + PsiPackage aPackage = myDefaultTargetDirectory.getPackage(); + if (aPackage != null) { + myTfPackage.setText(aPackage.getQualifiedName()); + } + } + if (myDoClone) { + myTfPackage.setVisible(false); + myPackageLabel.setVisible(false); + } + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + return panel; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + panel.setBorder(IdeBorderFactory.createBorder()); + + gbConstraints.insets = new Insets(4,8,4,8); + gbConstraints.weightx = 1; + gbConstraints.gridwidth = 2; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.anchor = GridBagConstraints.WEST; + panel.add(myInformationLabel, gbConstraints); + + gbConstraints.gridwidth = 1; + gbConstraints.gridy = 1; + gbConstraints.weighty = 1; + gbConstraints.weightx = 0; + panel.add(myNameLabel, gbConstraints); + myNameLabel.setLabelFor(myNameField); + myNameLabel.setDisplayedMnemonic('N'); + + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + myNameField = new EditorTextField(""); + panel.add(myNameField, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridy = 2; + gbConstraints.weightx = 0; + panel.add(myPackageLabel, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + myTfPackage = new TextFieldWithBrowseButton(); + myPackageLabel.setLabelFor(myTfPackage.getTextField()); + myPackageLabel.setDisplayedMnemonic('D'); + + myTfPackage.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PackageChooserDialog chooser=new PackageChooserDialog("Choose Destination Package",myProject); + chooser.selectPackage(myTfPackage.getText()); + chooser.show(); + PsiPackage aPackage = chooser.getSelectedPackage(); + if (aPackage != null) { + myTfPackage.setText(aPackage.getQualifiedName()); + } + } + }); + panel.add(myTfPackage, gbConstraints); + + return panel; + } + + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + private String getPackageName() { + String name = myTfPackage.getText(); + return name != null ? name.trim() : ""; + } + + public String getClassName() { + return myNameField.getText(); + } + + protected void doOKAction(){ + final String packageName = getPackageName(); + final String className = getClassName(); + + final String[] errorString = new String[1]; + final PsiManager manager = PsiManager.getInstance(myProject); + if ("".equals(className)) { + errorString[0] = "No class name specified"; + } + else if (!manager.getNameHelper().isIdentifier(className)) { + errorString[0] = RefactoringMessageUtil.getIncorrectIdentifierMessage(className); + } + else if (!myDoClone) { + try { + myTargetDirectory = PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, myDefaultTargetDirectory, true); + if (myTargetDirectory == null) { + errorString[0] = ""; // message already reported by PackageUtil + } else { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + errorString[0] = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, className); + } + }); + } + }, "Create directory", null); + } + } + catch (IncorrectOperationException e) { + errorString[0] = e.getMessage(); + } + } + + if (errorString[0] != null) { + if (errorString[0].length() > 0) { + Messages.showMessageDialog(myProject, errorString[0], "Error", Messages.getErrorIcon()); + } + myNameField.requestFocusInWindow(); + return; + } + super.doOKAction(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.COPY_CLASS); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java new file mode 100644 index 00000000000..482619ba5f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java @@ -0,0 +1,196 @@ +package com.intellij.refactoring.copy; + +import com.intellij.ide.util.DirectoryUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.io.File; + +class CopyFilesOrDirectoriesDialog extends DialogWrapper{ + private JLabel myInformationLabel; + private TextFieldWithBrowseButton myTargetDirectoryField; + private JTextField myNewNameField; + private Project myProject; + private boolean myShowDirectoryField; + private boolean myShowNewNameField; + + private PsiDirectory myTargetDirectory; + + public CopyFilesOrDirectoriesDialog(PsiElement[] elements, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { + super(project, true); + myProject = project; + myShowDirectoryField = !doClone; + myShowNewNameField = elements.length == 1; + + if (doClone && elements.length != 1) { + throw new IllegalArgumentException("wrong number of elements to clone: " + elements.length); + } + + setTitle(doClone ? "Clone" : "Copy"); + init(); + + if (elements.length == 1) { + String text; + if (elements[0] instanceof PsiFile) { + PsiFile file = (PsiFile)elements[0]; + text = (doClone ? "Clone file " : "Copy file ") + file.getVirtualFile().getPresentableUrl(); + myNewNameField.setText(file.getName()); + } + else { + PsiDirectory directory = (PsiDirectory)elements[0]; + text = (doClone ? "Clone directory" : "Copy directory ") + directory.getVirtualFile().getPresentableUrl(); + myNewNameField.setText(directory.getName()); + } + myInformationLabel.setText(text); + } + else { + myInformationLabel.setText((elements[0] instanceof PsiFile)? "Copy specified files" : "Copy specified directories"); + } + + if (myShowDirectoryField) { + myTargetDirectoryField.setText(defaultTargetDirectory == null ? "" : defaultTargetDirectory.getVirtualFile().getPresentableUrl()); + } + validateOKButton(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myShowDirectoryField ? myTargetDirectoryField.getTextField() : myNewNameField; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + return panel; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + + panel.setBorder(IdeBorderFactory.createBorder()); + + myInformationLabel = new JLabel(); + + panel.add(myInformationLabel, new GridBagConstraints(0,0,2,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); + + DocumentListener documentListener = new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + validateOKButton(); + } + }; + + if (myShowDirectoryField) { + panel.add(new JLabel("To directory: "), new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); + + myTargetDirectoryField = new TextFieldWithBrowseButton(); + myTargetDirectoryField.addBrowseFolderListener("Select target directory", "The file will be copied to this directory", null, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + myTargetDirectoryField.setTextFieldPreferredWidth(60); + panel.add(myTargetDirectoryField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0)); + + myTargetDirectoryField.getTextField().getDocument().addDocumentListener(documentListener); + } + + if (myShowNewNameField) { + myNewNameField = new JTextField(); + Dimension size = myNewNameField.getPreferredSize(); + FontMetrics fontMetrics = myNewNameField.getFontMetrics(myNewNameField.getFont()); + size.width = fontMetrics.charWidth('a') * 60; + myNewNameField.setPreferredSize(size); + + panel.add(new JLabel("New name: "), new GridBagConstraints(0,2,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); + + panel.add(myNewNameField, new GridBagConstraints(1,2,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0)); + + myNewNameField.getDocument().addDocumentListener(documentListener); + } + + return panel; + } + + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + public String getNewName() { + return myNewNameField != null ? myNewNameField.getText().trim() : null; + } + + protected void doOKAction(){ + if (myShowNewNameField) { + String newName = getNewName(); + + if (newName.length() == 0) { + Messages.showMessageDialog(myProject, "No new name specified", "Error", Messages.getErrorIcon()); + return; + } + } + + if (myShowDirectoryField) { + final String targetDirectoryName = myTargetDirectoryField.getText(); + + if (targetDirectoryName.length() == 0) { + Messages.showMessageDialog(myProject, "No target directory specified", "Error", Messages.getErrorIcon()); + return; + } + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + myTargetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(myProject), targetDirectoryName.replace(File.separatorChar, '/')); + } + catch (IncorrectOperationException e) { + } + } + }); + } + }, "Create directory", null); + + if (myTargetDirectory == null) { + Messages.showMessageDialog(myProject, "Cannot create directory", "Error", Messages.getErrorIcon()); + return; + } + } + + super.doOKAction(); + } + + private void validateOKButton() { + if (myShowDirectoryField) { + if (myTargetDirectoryField.getText().length() == 0) { + setOKActionEnabled(false); + return; + } + } + if (myShowNewNameField) { + if (getNewName().length() == 0) { + setOKActionEnabled(false); + return; + } + } + setOKActionEnabled(true); + } + + protected void doHelpAction() { +// HelpManager.getInstance().invokeHelp(HelpID.COPY_CLASS, getRootPane()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyHandler.java new file mode 100644 index 00000000000..e12e530d9d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/copy/CopyHandler.java @@ -0,0 +1,410 @@ +package com.intellij.refactoring.copy; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.commander.Commander; +import com.intellij.ide.commander.CommanderPanel; +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.structureView.StructureViewFactory; +import com.intellij.ide.util.DeleteUtil; +import com.intellij.ide.util.EditorHelper; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.util.HashSet; + +public class CopyHandler { + public static final int NOT_SUPPORTED = 0; + public static final int CLASS = 1; + public static final int FILES = 2; + public static final int DIRECTORIES = 3; + + public static boolean canCopy(PsiElement[] elements) { + int moveType = getCopyType(elements); + return moveType != NOT_SUPPORTED; + } + + private static int getCopyType(PsiElement[] elements) { + if (elements.length == 0) { + return NOT_SUPPORTED; + } + + if (elements.length == 1) { + if (elements[0] instanceof PsiClass && elements[0].getParent() instanceof PsiFile) { + return CLASS; + } + } + + if (canCopyFiles(elements)) { + return FILES; + } + + if (canCopyDirectories(elements)) { + return DIRECTORIES; + } + + return NOT_SUPPORTED; + } + + private static boolean canCopyFiles(PsiElement[] elements) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!(element instanceof PsiFile) || (element instanceof PsiJavaFile)) { + return false; + } + } + + // the second 'for' statement is for effectivity - to prevent creation of the 'names' array + HashSet names = new HashSet(); + for (int i = 0; i < elements.length; i++) { + PsiFile file = (PsiFile)elements[i]; + String name = file.getName(); + if (names.contains(name)) { + return false; + } + + names.add(name); + } + + return true; + } + + private static boolean canCopyDirectories(PsiElement[] elements) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!(element instanceof PsiDirectory)) { + return false; + } + } + + for (int i = 0; i < elements.length; i++) { + PsiDirectory directory = (PsiDirectory)elements[i]; + + if (hasPackages(directory)) { + return false; + } + } + + PsiElement[] filteredElements = DeleteUtil.filterElements(elements); + if (filteredElements.length != elements.length) { + // there are nested dirs + return false; + } + + return true; + } + + private static boolean hasPackages(PsiDirectory directory) { + if (directory.getPackage() != null) { + return true; + } + PsiDirectory[] subdirectories = directory.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + PsiDirectory subdirectory = subdirectories[i]; + if (hasPackages(subdirectory)) { + return true; + } + } + return false; + } + + + public static void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) { + int type = getCopyType(elements); + if (type == NOT_SUPPORTED) { + return; + } + + Project project = elements[0].getProject(); + + if (type == CLASS) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass"); + PsiClass aClass = (PsiClass)elements[0]; + if (defaultTargetDirectory == null) { + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile != null) { // ??? + defaultTargetDirectory = containingFile.getContainingDirectory(); + } + } + CopyClassDialog dialog = new CopyClassDialog(aClass, defaultTargetDirectory, project, false); + dialog.setTitle("Copy Class"); + dialog.show(); + if (dialog.isOK()) { + PsiDirectory targetDirectory = dialog.getTargetDirectory(); + String className = dialog.getClassName(); + copyClassImpl(className, project, aClass, targetDirectory, "Copy class", false); + } + } + else if (type == FILES || type == DIRECTORIES) { + if (defaultTargetDirectory == null) { + defaultTargetDirectory = getCommonParentDirectory(elements); + } + + CopyFilesOrDirectoriesDialog dialog = new CopyFilesOrDirectoriesDialog(elements, defaultTargetDirectory, project, false); + dialog.show(); + if (dialog.isOK()) { + String newName = elements.length == 1 ? dialog.getNewName() : null; + copyImpl(elements, newName, dialog.getTargetDirectory(), false); + } + } + else { + throw new IllegalArgumentException("wrong type " + type); + } + } + + private static PsiDirectory getCommonParentDirectory(PsiElement[] elements){ + PsiDirectory result = null; + + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + PsiDirectory directory; + + if (element instanceof PsiDirectory) { + directory = (PsiDirectory)element; + directory = directory.getParentDirectory(); + } + else if (element instanceof PsiFile) { + directory = ((PsiFile)element).getContainingDirectory(); + } + else { + throw new IllegalArgumentException("unexpected element " + element); + } + + if (directory == null) continue; + + if (result == null) { + result = directory; + } + else { + if (PsiTreeUtil.isAncestor(directory, result, true)) { + result = directory; + } + } + } + + return result; + } + + public static void doClone(PsiElement element) { + PsiElement[] elements = new PsiElement[]{element}; + int type = getCopyType(elements); + if (type == NOT_SUPPORTED) { + return; + } + + Project project = element.getProject(); + + PsiDirectory targetDirectory; + if (element instanceof PsiFile) { + targetDirectory = ((PsiFile)element).getContainingDirectory(); + } + else if (element instanceof PsiDirectory) { + targetDirectory = ((PsiDirectory)element).getParentDirectory(); + } + else { + PsiFile file = element.getContainingFile(); + targetDirectory = file.getContainingDirectory(); + } + + if (type == CLASS) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass"); + PsiClass aClass = (PsiClass)element; + + CopyClassDialog dialog = new CopyClassDialog(aClass, null, project, true); + dialog.setTitle("Clone Class"); + dialog.show(); + if (dialog.isOK()) { + String className = dialog.getClassName(); + copyClassImpl(className, project, aClass, targetDirectory, "Clone class", true); + } + } + else if (type == FILES || type == DIRECTORIES) { + CopyFilesOrDirectoriesDialog dialog = new CopyFilesOrDirectoriesDialog(elements, null, project, true); + dialog.show(); + if (dialog.isOK()) { + String newName = dialog.getNewName(); + copyImpl(elements, newName, targetDirectory, true); + } + } + else { + throw new IllegalArgumentException("wrong type " + type); + } + } + + private static void copyClassImpl(final String copyClassName, final Project project, final PsiElement psiElement, final PsiDirectory targetDirectory, String commandName, final boolean selectInActivePanel) { + if (copyClassName == null || copyClassName.length() == 0) return; + final boolean[] result = new boolean[] {false}; + Runnable command = new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + ChangeContextUtil.encodeContextInfo(psiElement.getNavigationElement(), true); + PsiClass classCopy = (PsiClass) psiElement.getNavigationElement().copy(); + ChangeContextUtil.clearContextInfo(psiElement); + classCopy.setName(copyClassName); + PsiClass newClass = (PsiClass) targetDirectory.add(classCopy); + ChangeContextUtil.decodeContextInfo(newClass, null, null); + final PsiManager psiManager = PsiManager.getInstance(project); + PsiReference[] refs = psiManager.getSearchHelper().findReferences(psiElement, new LocalSearchScope(newClass), true); + + for (int i = 0; i < refs.length; i++) { + final PsiReference ref = refs[i]; + if (!ref.getElement().isValid()) continue; + ref.bindToElement(newClass); + } + + + updateSelectionInActiveProjectView(newClass, project, selectInActivePanel); + EditorHelper.openInEditor(newClass); + + result[0] = true; + } catch (final IncorrectOperationException ex) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(project, ex.getMessage(), "Error", Messages.getErrorIcon()); + } + }); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }; + CommandProcessor processor = CommandProcessor.getInstance(); + processor.executeCommand(project, command, commandName, null); + + if (result[0]) { + ToolWindowManager.getInstance(project).invokeLater(new Runnable() { + public void run() { + ToolWindowManager.getInstance(project).activateEditorComponent(); + } + }); + } + } + + private static void updateSelectionInActiveProjectView(PsiElement newElement, Project project, boolean selectInActivePanel) { + String id = ToolWindowManager.getInstance(project).getActiveToolWindowId(); + if (ToolWindowId.COMMANDER.equals(id)) { + Commander commander = Commander.getInstance(project); + CommanderPanel panel = selectInActivePanel ? commander.getActivePanel() : commander.getInactivePanel(); + panel.getBuilder().selectElement(newElement); + } else if (ToolWindowId.PROJECT_VIEW.equals(id)) { + ProjectView.getInstance(project).selectPsiElement(newElement, true); + } else if (ToolWindowId.STRUCTURE_VIEW.equals(id)) { + VirtualFile virtualFile = newElement.getContainingFile().getVirtualFile(); + FileEditor editor = FileEditorManager.getInstance(newElement.getProject()).getSelectedEditor(virtualFile); + StructureViewFactory.getInstance(project).getStructureView().select(newElement,editor, true); + } + } + + /** + * @param elementToCopy PsiFile or PsiDirectory + * @param newName can be not null only if elements.length == 1 + * @return first copied PsiFile (recursivly); null if no PsiFiles copied + */ + private static PsiFile copyToDirectory(final PsiElement elementToCopy, String newName, final PsiDirectory targetDirectory) throws IncorrectOperationException{ + if (elementToCopy instanceof PsiFile) { + PsiFile file = (PsiFile)elementToCopy; + if (newName != null) { + file = (PsiFile)file.copy(); + file = (PsiFile) file.setName(newName); + } + PsiFile newFile = (PsiFile)targetDirectory.add(file); + return newFile; + } + else if (elementToCopy instanceof PsiDirectory) { + PsiDirectory directory = (PsiDirectory)elementToCopy; + if (directory.equals(targetDirectory)) { + return null; + } + PsiDirectory subdirectory = targetDirectory.createSubdirectory(newName == null ? directory.getName() : newName); + PsiFile firstFile = null; + PsiElement[] children = directory.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + PsiFile f = copyToDirectory(child, null, subdirectory); + if (firstFile == null) { + firstFile = f; + } + } + return firstFile; + } + else { + throw new IllegalArgumentException("unexpected elementToCopy: " + elementToCopy); + } + } + + + /** + * + * @param elements + * @param newName can be not null only if elements.length == 1 + * @param targetDirectory + */ + private static void copyImpl(final PsiElement[] elements, final String newName, final PsiDirectory targetDirectory, final boolean doClone) { + if (doClone && elements.length != 1) { + throw new IllegalArgumentException("invalid number of elements to clone:" + elements.length); + } + + if (newName != null && elements.length != 1) { + throw new IllegalArgumentException("no new name should be set; number of elements is: " + elements.length); + } + + final Project project = targetDirectory.getProject(); + Runnable command = new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + PsiFile firstFile = null; + + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + + PsiFile f = copyToDirectory(element, newName, targetDirectory); + if (firstFile == null) { + firstFile = f; + } + } + + if (firstFile != null) { + updateSelectionInActiveProjectView(firstFile, project, doClone); + if (!(firstFile instanceof PsiBinaryFile)){ + EditorHelper.openInEditor(firstFile); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ToolWindowManager.getInstance(project).activateEditorComponent(); + } + }); + } + } + + } catch (final IncorrectOperationException ex) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(project, ex.getMessage(), "Error", Messages.getErrorIcon()); + } + }); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }; + CommandProcessor.getInstance().executeCommand(project, command, doClone ? "Clone files/directories" : "Copy files/directories", null); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java new file mode 100644 index 00000000000..df7941c355e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java @@ -0,0 +1,686 @@ +package com.intellij.refactoring.encapsulateFields; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.*; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.RowIcon; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.awt.event.*; +import java.util.Set; + +public class EncapsulateFieldsDialog extends RefactoringDialog { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsDialog" + ); + + public static interface Callback { + void run(EncapsulateFieldsDialog dialog); + } + + private static final int CHECKED_COLUMN = 0; + private static final int FIELD_COLUMN = 1; + private static final int GETTER_COLUMN = 2; + private static final int SETTER_COLUMN = 3; + + private final Project myProject; + private final PsiClass myClass; + private final Callback myCallback; + + private PsiField[] myFields; + private boolean[] myCheckedMarks; + private boolean[] myFinalMarks; + private String[] myFieldNames; + private String[] myGetterNames; + private PsiMethod[] myGetterPrototypes; + private String[] mySetterNames; + private PsiMethod[] mySetterPrototypes; + + private JTable myTable; + private MyTableModel myTableModel; + + private JCheckBox myCbEncapsulateGet = new JCheckBox("Get access"); + private JCheckBox myCbEncapsulateSet = new JCheckBox("Set access"); + private JCheckBox myCbUseAccessorsWhenAccessible = new JCheckBox("Use accessors even when field is accessible"); + private JRadioButton myRbFieldPrivate = new JRadioButton("Private"); + private JRadioButton myRbFieldProtected = new JRadioButton("Protected"); + private JRadioButton myRbFieldPackageLocal = new JRadioButton("Package local"); + private JRadioButton myRbFieldAsIs = new JRadioButton("As is"); + private JRadioButton myRbAccessorPublic = new JRadioButton("Public"); + private JRadioButton myRbAccessorProtected = new JRadioButton("Protected"); + private JRadioButton myRbAccessorPrivate = new JRadioButton("Private"); + private JRadioButton myRbAccessorPackageLocal = new JRadioButton("Package local"); + + { + myCbEncapsulateGet.setFocusable(false); + myCbEncapsulateSet.setFocusable(false); + myCbUseAccessorsWhenAccessible.setFocusable(false); + + myRbAccessorPackageLocal.setFocusable(false); + myRbAccessorPrivate.setFocusable(false); + myRbAccessorProtected.setFocusable(false); + myRbAccessorPublic.setFocusable(false); + + myRbFieldAsIs.setFocusable(false); + myRbFieldPackageLocal.setFocusable(false); + myRbFieldPrivate.setFocusable(false); + myRbFieldProtected.setFocusable(false); + } + + public EncapsulateFieldsDialog(Project project, PsiClass aClass, final Set preselectedFields, Callback callback) { + super(project, true); + myProject = project; + myClass = aClass; + myCallback = callback; + + String title = "Encapsulate Fields"; + String qName = myClass.getQualifiedName(); + if (qName != null) { + title += " - " + qName; + } + setTitle(title); + + myFields = myClass.getFields(); + myFieldNames = new String[myFields.length]; + myCheckedMarks = new boolean[myFields.length]; + myFinalMarks = new boolean[myFields.length]; + myGetterNames = new String[myFields.length]; + mySetterNames = new String[myFields.length]; + myGetterPrototypes = new PsiMethod[myFields.length]; + mySetterPrototypes = new PsiMethod[myFields.length]; + for (int idx = 0; idx < myFields.length; idx++) { + PsiField field = myFields[idx]; + myCheckedMarks[idx] = preselectedFields.contains(field); + myFinalMarks[idx] = field.hasModifierProperty(PsiModifier.FINAL); + myFieldNames[idx] = + PsiFormatUtil.formatVariable(field, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, + PsiSubstitutor.EMPTY + ); + myGetterNames[idx] = PropertyUtil.suggestGetterName(myProject, field); + mySetterNames[idx] = PropertyUtil.suggestSetterName(myProject, field); + myGetterPrototypes[idx] = generateMethodPrototype(field, myGetterNames[idx], true); + mySetterPrototypes[idx] = generateMethodPrototype(field, mySetterNames[idx], false); + } + + init(); + } + + public PsiField[] getSelectedFields() { + int[] rows = getCheckedRows(); + PsiField[] selectedFields = new PsiField[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedFields[idx] = myFields[rows[idx]]; + } + return selectedFields; + } + + public String[] getGetterNames() { + int[] rows = getCheckedRows(); + String[] selectedGetters = new String[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedGetters[idx] = myGetterNames[rows[idx]]; + } + return selectedGetters; + } + + public String[] getSetterNames() { + int[] rows = getCheckedRows(); + String[] selectedSetters = new String[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedSetters[idx] = mySetterNames[rows[idx]]; + } + return selectedSetters; + } + + public PsiMethod[] getGetterPrototypes() { + if (isToEncapsulateGet()) { + int[] rows = getCheckedRows(); + PsiMethod[] selectedGetters = new PsiMethod[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedGetters[idx] = myGetterPrototypes[rows[idx]]; + } + return selectedGetters; + } else { + return null; + } + } + + public PsiMethod[] getSetterPrototypes() { + if (isToEncapsulateSet()) { + int[] rows = getCheckedRows(); + PsiMethod[] selectedSetters = new PsiMethod[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedSetters[idx] = mySetterPrototypes[rows[idx]]; + } + return selectedSetters; + } else { + return null; + } + } + + public boolean isToEncapsulateGet() { + return myCbEncapsulateGet.isSelected(); + } + + public boolean isToEncapsulateSet() { + return myCbEncapsulateSet.isSelected(); + } + + public boolean isToUseAccessorsWhenAccessible() { + if (getFieldsVisibility() == null) { + // "as is" + return true; + } + return myCbUseAccessorsWhenAccessible.isSelected(); + } + + public String getFieldsVisibility() { + if (myRbFieldPrivate.isSelected()) { + return PsiModifier.PRIVATE; + } else if (myRbFieldPackageLocal.isSelected()) { + return PsiModifier.PACKAGE_LOCAL; + } else if (myRbFieldProtected.isSelected()) { + return PsiModifier.PROTECTED; + } else if (myRbFieldAsIs.isSelected()) { + return null; + } else { + LOG.assertTrue(false); + return null; + } + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.encapsulateFields.EncalpsulateFieldsDialog"; + } + + public String getAccessorsVisibility() { + if (myRbAccessorPublic.isSelected()) { + return PsiModifier.PUBLIC; + } else if (myRbAccessorProtected.isSelected()) { + return PsiModifier.PROTECTED; + } else if (myRbAccessorPackageLocal.isSelected()) { + return PsiModifier.PACKAGE_LOCAL; + } else if (myRbAccessorPrivate.isSelected()) { + return PsiModifier.PRIVATE; + } else { + LOG.assertTrue(false); + return null; + } + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(createTable(), BorderLayout.CENTER); + + myCbEncapsulateGet.setMnemonic('G'); + myCbEncapsulateSet.setMnemonic('S'); + myCbUseAccessorsWhenAccessible.setMnemonic('U'); + myRbFieldPrivate.setMnemonic('i'); + myRbFieldProtected.setMnemonic('r'); + myRbFieldPackageLocal.setMnemonic('c'); + myRbFieldAsIs.setMnemonic('A'); + myRbAccessorPublic.setMnemonic('b'); + myRbAccessorProtected.setMnemonic('o'); + myRbAccessorPrivate.setMnemonic('v'); + myRbAccessorPackageLocal.setMnemonic('k'); + + ButtonGroup fieldGroup = new ButtonGroup(); + fieldGroup.add(myRbFieldAsIs); + fieldGroup.add(myRbFieldPackageLocal); + fieldGroup.add(myRbFieldPrivate); + fieldGroup.add(myRbFieldProtected); + + ButtonGroup methodGroup = new ButtonGroup(); + methodGroup.add(myRbAccessorPackageLocal); + methodGroup.add(myRbAccessorPrivate); + methodGroup.add(myRbAccessorProtected); + methodGroup.add(myRbAccessorPublic); + + myCbEncapsulateGet.setSelected(true); + myCbEncapsulateSet.setSelected(true); + ActionListener checkboxListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myCbEncapsulateGet.equals(e.getSource())) { + if (!myCbEncapsulateGet.isSelected()) { + myCbEncapsulateSet.setSelected(true); + } + } else { + // myCbEncapsulateSet is the source + if (!myCbEncapsulateSet.isSelected()) { + myCbEncapsulateGet.setSelected(true); + } + } + int[] rows = myTable.getSelectedRows(); + myTableModel.fireTableDataChanged(); + TableUtil.selectRows(myTable, rows); + } + }; + myCbEncapsulateGet.addActionListener(checkboxListener); + myCbEncapsulateSet.addActionListener(checkboxListener); + myRbFieldAsIs.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + myCbUseAccessorsWhenAccessible.setEnabled(!myRbFieldAsIs.isSelected()); + } + } + ); + myCbUseAccessorsWhenAccessible.setSelected( + RefactoringSettings.getInstance().ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE + ); + + myRbFieldPrivate.setSelected(true); + myRbAccessorPublic.setSelected(true); + + Box leftBox = Box.createVerticalBox(); + myCbEncapsulateGet.setPreferredSize(myCbUseAccessorsWhenAccessible.getPreferredSize()); + leftBox.add(myCbEncapsulateGet); + leftBox.add(myCbEncapsulateSet); + JPanel leftPanel = new JPanel(new BorderLayout()); + leftPanel.setBorder(IdeBorderFactory.createTitledBorder("Encapsulate")); + leftPanel.add(leftBox, BorderLayout.CENTER); + leftPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST); + + Box rightBox = Box.createVerticalBox(); + rightBox.add(myCbUseAccessorsWhenAccessible); + JPanel rightPanel = new JPanel(new BorderLayout()); + rightPanel.setBorder(IdeBorderFactory.createTitledBorder("Options")); + rightPanel.add(rightBox, BorderLayout.CENTER); + rightPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST); + + Box encapsulateBox = Box.createHorizontalBox(); + encapsulateBox.add(leftPanel); + encapsulateBox.add(Box.createHorizontalStrut(5)); + encapsulateBox.add(rightPanel); + + Box fieldsBox = Box.createVerticalBox(); + fieldsBox.add(myRbFieldPrivate); + fieldsBox.add(myRbFieldPackageLocal); + fieldsBox.add(myRbFieldProtected); + fieldsBox.add(myRbFieldAsIs); + JPanel fieldsVisibilityPanel = new JPanel(new BorderLayout()); + fieldsVisibilityPanel.setBorder(IdeBorderFactory.createTitledBorder("Encapsulated Fields' Visibility")); + fieldsVisibilityPanel.add(fieldsBox, BorderLayout.CENTER); + fieldsVisibilityPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST); + + Box methodsBox = Box.createVerticalBox(); + methodsBox.add(myRbAccessorPublic); + methodsBox.add(myRbAccessorProtected); + methodsBox.add(myRbAccessorPackageLocal); + methodsBox.add(myRbAccessorPrivate); + JPanel methodsVisibilityPanel = new JPanel(new BorderLayout()); + methodsVisibilityPanel.setBorder(IdeBorderFactory.createTitledBorder("Accessors' Visibility")); + methodsVisibilityPanel.add(methodsBox, BorderLayout.CENTER); + methodsVisibilityPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST); + + Box visibilityBox = Box.createHorizontalBox(); + visibilityBox.add(fieldsVisibilityPanel); + visibilityBox.add(Box.createHorizontalStrut(5)); + visibilityBox.add(methodsVisibilityPanel); + + Box box = Box.createVerticalBox(); + box.add(encapsulateBox); + box.add(Box.createVerticalStrut(5)); + box.add(visibilityBox); + + JPanel boxPanel = new JPanel(new BorderLayout()); + boxPanel.add(box, BorderLayout.CENTER); + boxPanel.add(Box.createVerticalStrut(5), BorderLayout.NORTH); + panel.add(boxPanel, BorderLayout.SOUTH); + + return panel; + } + + private JComponent createTable() { + myTableModel = new MyTableModel(); + myTable = new Table(myTableModel); + myTable.setSurrendersFocusOnKeystroke(true); + MyTableRenderer renderer = new MyTableRenderer(); + TableColumnModel columnModel = myTable.getColumnModel(); + columnModel.getColumn(FIELD_COLUMN).setCellRenderer(renderer); + columnModel.getColumn(GETTER_COLUMN).setCellRenderer(renderer); + columnModel.getColumn(SETTER_COLUMN).setCellRenderer(renderer); + columnModel.getColumn(CHECKED_COLUMN).setMaxWidth(new JCheckBox().getPreferredSize().width); + + myTable.setPreferredScrollableViewportSize(new Dimension(550, myTable.getRowHeight() * 12)); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); +// JLabel label = new JLabel("Fields to Encapsulate"); +// CompTitledBorder titledBorder = new CompTitledBorder(label); + Border titledBorder = IdeBorderFactory.createTitledBorder("Fields to Encapsulate"); + Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5); + Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder); + scrollPane.setBorder(border); + // make ESC and ENTER work when focus is in the table + myTable.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.cancelCellEditing(); + } else { + doCancelAction(); + } + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + // make SPACE check/uncheck selected rows + InputMap inputMap = myTable.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + myTable.getActionMap().put("enable_disable", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] rows = myTable.getSelectedRows(); + if (rows.length > 0) { + boolean valueToBeSet = false; + for (int idx = 0; idx < rows.length; idx++) { + if (!myCheckedMarks[rows[idx]]) { + valueToBeSet = true; + break; + } + } + for (int idx = 0; idx < rows.length; idx++) { + myCheckedMarks[rows[idx]] = valueToBeSet; + } + myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); + TableUtil.selectRows(myTable, rows); + } + } + } + ); + // make ENTER work when the table has focus + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl"); + myTable.getActionMap().put("invokeImpl", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } else { + clickDefaultButton(); + } + } + } + ); + return scrollPane; + } + + public JComponent getPreferredFocusedComponent() { + return myTable; + } + + protected void doAction() { + if (myTable.isEditing()) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + } + String errorString = validateData(); + if (errorString == null) { + myCallback.run(this); + RefactoringSettings settings = RefactoringSettings.getInstance(); + settings.ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = myCbUseAccessorsWhenAccessible.isSelected(); + } else { // were errors + RefactoringMessageUtil.showErrorMessage("Encapsulate Fields", errorString, HelpID.ENCAPSULATE_FIELDS, myProject); + } + } + + /** + * @return error string if errors were found, or null if everything is ok + */ + private String validateData() { + PsiManager manager = PsiManager.getInstance(myProject); + for (int idx = 0; idx < myFields.length; idx++) { + if (myCheckedMarks[idx]) { + String name; + if (isToEncapsulateGet()) { + name = myGetterNames[idx]; + if (!manager.getNameHelper().isIdentifier(name)) { + return RefactoringMessageUtil.getIncorrectIdentifierMessage(name); + } + } + if (!myFinalMarks[idx] && isToEncapsulateSet()) { + name = mySetterNames[idx]; + if (!manager.getNameHelper().isIdentifier(name)) { + return RefactoringMessageUtil.getIncorrectIdentifierMessage(name); + } + } + } + } + return null; + } + + private PsiMethod generateMethodPrototype(PsiField field, String methodName, boolean isGetter) { + PsiMethod prototype = isGetter + ? PropertyUtil.generateGetterPrototype(field) + : PropertyUtil.generateSetterPrototype(field); + try { + PsiElementFactory factory = field.getManager().getElementFactory(); + PsiIdentifier identifier = factory.createIdentifier(methodName); + prototype.getNameIdentifier().replace(identifier); + //prototype.getModifierList().setModifierProperty(getAccessorsVisibility(), true); + return prototype; + } catch (IncorrectOperationException e) { + return null; + } + } + + private int[] getCheckedRows() { + int count = 0; + for (int idx = 0; idx < myCheckedMarks.length; idx++) { + if (myCheckedMarks[idx]) { + count++; + } + } + int[] rows = new int[count]; + int currentRow = 0; + for (int idx = 0; idx < myCheckedMarks.length; idx++) { + if (myCheckedMarks[idx]) { + rows[currentRow++] = idx; + } + } + return rows; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.ENCAPSULATE_FIELDS); + } + + private class MyTableModel extends AbstractTableModel { + public int getColumnCount() { + return 4; + } + + public int getRowCount() { + return myFields.length; + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECKED_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKED_COLUMN: + return myCheckedMarks[rowIndex] ? Boolean.TRUE : Boolean.FALSE; + case FIELD_COLUMN: + return myFieldNames[rowIndex]; + case GETTER_COLUMN: + return myGetterNames[rowIndex]; + case SETTER_COLUMN: + return mySetterNames[rowIndex]; + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public String getColumnName(int column) { + switch (column) { + case CHECKED_COLUMN: + return " "; + case FIELD_COLUMN: + return "Field"; + case GETTER_COLUMN: + return "Getter"; + case SETTER_COLUMN: + return "Setter"; + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + if (columnIndex == CHECKED_COLUMN) return true; + if (myCheckedMarks[rowIndex]) { + if (columnIndex == GETTER_COLUMN && myCbEncapsulateGet.isSelected()) return true; + if (columnIndex == SETTER_COLUMN) { + if (!myFinalMarks[rowIndex] && myCbEncapsulateSet.isSelected()) return true; + } + } + return false; + } + + public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) { + if (columnIndex == CHECKED_COLUMN) { + myCheckedMarks[rowIndex] = ((Boolean) aValue).booleanValue(); + fireTableRowsUpdated(rowIndex, rowIndex); + } else { + String name = (String) aValue; + PsiField field = myFields[rowIndex]; + switch (columnIndex) { + case GETTER_COLUMN: + myGetterNames[rowIndex] = name; + myGetterPrototypes[rowIndex] = generateMethodPrototype(field, name, true); + break; + + case SETTER_COLUMN: + mySetterNames[rowIndex] = name; + mySetterPrototypes[rowIndex] = generateMethodPrototype(field, name, false); + break; + + default: + throw new RuntimeException("Incorrect column index"); + } + } + } + } + + private static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/general/overridingMethod.png"); + private static final Icon IMPLEMENTING_METHOD_ICON = IconLoader.getIcon("/general/implementingMethod.png"); + private static final Icon EMPTY_OVERRIDE_ICON = EmptyIcon.create(16, 16); + + private class MyTableRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, final Object value, + boolean isSelected, boolean hasFocus, final int row, + final int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + final int modelColumn = myTable.convertColumnIndexToModel(column); + + this.setIconTextGap(0); + PsiField field = myFields[row]; + switch (modelColumn) { + case FIELD_COLUMN: + { + Icon icon = field.getIcon(Iconable.ICON_FLAG_VISIBILITY); + MyTableRenderer.this.setIcon(icon); + MyTableRenderer.this.setDisabledIcon(icon); + configureColors(isSelected, table, hasFocus, row, column); + break; + } + + case GETTER_COLUMN: + case SETTER_COLUMN: + { + Icon methodIcon = IconUtilEx.getEmptyIcon(true); + Icon overrideIcon = EMPTY_OVERRIDE_ICON; + + PsiMethod prototype = modelColumn == GETTER_COLUMN ? myGetterPrototypes[row] : mySetterPrototypes[row]; + if (prototype != null) { +// MyTableRenderer.this.setForeground(Color.black); + configureColors(isSelected, table, hasFocus, row, column); + + PsiMethod existing = myClass.findMethodBySignature(prototype, false); + if (existing != null) { + methodIcon = existing.getIcon(Iconable.ICON_FLAG_VISIBILITY); + } + + PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(prototype, myClass); + if (superMethods.length > 0) { + if (!superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT)) { + overrideIcon = OVERRIDING_METHOD_ICON; + } else { + overrideIcon = IMPLEMENTING_METHOD_ICON; + } + } + } else { + MyTableRenderer.this.setForeground(Color.red); + } + + RowIcon icon = new RowIcon(2); + icon.setIcon(methodIcon, 0); + icon.setIcon(overrideIcon, 1); + MyTableRenderer.this.setIcon(icon); + MyTableRenderer.this.setDisabledIcon(icon); + break; + } + + default: + { + MyTableRenderer.this.setIcon(null); + MyTableRenderer.this.setDisabledIcon(null); + } + } + boolean enabled = myCheckedMarks[row]; + if (enabled) { + if (modelColumn == GETTER_COLUMN) { + enabled = myCbEncapsulateGet.isSelected(); + } else if (modelColumn == SETTER_COLUMN) { + enabled = !myFinalMarks[row] && myCbEncapsulateSet.isSelected(); + } + } + this.setEnabled(enabled); + return this; + } + + private void configureColors(boolean isSelected, JTable table, boolean hasFocus, final int row, final int column) { + if (isSelected) { + setForeground(table.getSelectionForeground()); + } else { + setForeground(UIManager.getColor("Table.foreground")); + } + + if (hasFocus) { + if (table.isCellEditable(row, column)) { + super.setForeground(UIManager.getColor("Table.focusCellForeground")); + super.setBackground(UIManager.getColor("Table.focusCellBackground")); + } + } + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java new file mode 100644 index 00000000000..44c33c9c370 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java @@ -0,0 +1,111 @@ +package com.intellij.refactoring.encapsulateFields; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import java.util.HashSet; + +public class EncapsulateFieldsHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler"); + public static final String REFACTORING_NAME = "Encapsulate Fields"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the class to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ENCAPSULATE_FIELDS, project); + return; + } + if (element instanceof PsiField) { + if (((PsiField) element).getContainingClass() == null) { + String message = "Cannot perform the refactoring.\n" + + "The field should be declared in a class."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ENCAPSULATE_FIELDS, project); + return; + } + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + if (element instanceof PsiClass) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + /** + * if elements.length == 1 the expected value is either PsiClass or PsiField + * if elements.length > 1 the expected values are PsiField objects only + */ + public void invoke(final Project project, final PsiElement[] elements, DataContext dataContext) { + PsiClass aClass = null; + final HashSet preselectedFields = new HashSet(); + if (elements.length == 1) { + if (elements[0] instanceof PsiClass) { + aClass = (PsiClass) elements[0]; + } else if (elements[0] instanceof PsiField) { + PsiField field = (PsiField) elements[0]; + aClass = field.getContainingClass(); + preselectedFields.add(field); + } else { + return; + } + } else { + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiField)) { + return; + } + PsiField field = (PsiField) element; + if (aClass == null) { + aClass = field.getContainingClass(); + preselectedFields.add(field); + } else { + if (aClass.equals(field.getContainingClass())) { + preselectedFields.add(field); + } else { + String message = "Cannot perform the refactoring.\nFields to be refactored should belong to the same class."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ENCAPSULATE_FIELDS, project); + return; + } + } + } + } + + LOG.assertTrue(aClass != null); + + if (aClass.isInterface()) { + String message = REFACTORING_NAME + " refactoring cannot be applied to interface"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.ENCAPSULATE_FIELDS, project); + return; + } + + if (!aClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, aClass); + return; + } + + EncapsulateFieldsDialog dialog = new EncapsulateFieldsDialog( + project, + aClass, + preselectedFields, + new EncapsulateFieldsProcessor(project) + ); + dialog.show(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java new file mode 100644 index 00000000000..2fcdf6e167b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java @@ -0,0 +1,530 @@ + +package com.intellij.refactoring.encapsulateFields; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor implements EncapsulateFieldsDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsProcessor"); + + private PsiClass myClass; + private EncapsulateFieldsDialog myDialog; + private PsiField[] myFields; + + private HashMap myNameToGetter; + private HashMap myNameToSetter; + + public EncapsulateFieldsProcessor(Project project) { + super(project); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + PsiField[] fields = new PsiField[myFields.length]; + for (int idx = 0; idx < myFields.length; idx++) { + fields[idx] = myFields[idx]; + } + return new EncapsulateFieldsViewDescriptor(fields, usages, refreshCommand); + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myDialog.isPreviewUsages(); + return super.isPreviewUsages(usages) || toPreview; + } + + protected String getCommandName() { + return "Encapsulating fields in " + UsageViewUtil.getDescriptiveName(myClass); + } + + public void run(EncapsulateFieldsDialog dialog) { + myDialog = dialog; + run((Object)null); + } + + public void run(Object markerId) { + myFields = myDialog.getSelectedFields(); + if (myFields.length == 0){ + String message = "No fields selected"; + RefactoringMessageUtil.showErrorMessage(EncapsulateFieldsHandler.REFACTORING_NAME, message, HelpID.ENCAPSULATE_FIELDS, myProject); + return; + } + myClass = myFields[0].getContainingClass(); + + super.run(markerId); + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + ArrayList conflicts = new ArrayList(); + + if (myDialog != null) { + checkExistingMethods(myDialog.getGetterPrototypes(), conflicts, "getter"); + checkExistingMethods(myDialog.getSetterPrototypes(), conflicts, "setter"); + + if(conflicts.size() > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), myProject); + dialog.show(); + if(!dialog.isOK()) return false; + } + // make sure that dialog is closed in swing thread + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + } + + return true; + } + + private void checkExistingMethods(PsiMethod[] prototypes, ArrayList conflicts, String methodRole) { + if(prototypes == null) return; + for (int i = 0; i < prototypes.length; i++) { + PsiMethod prototype = prototypes[i]; + final PsiType prototypeReturnType = prototype.getReturnType(); + PsiMethod existing = myClass.findMethodBySignature(prototype, true); + if(existing != null) { + final PsiType returnType = existing.getReturnType(); + if(!RefactoringUtil.equivalentTypes(prototypeReturnType, returnType, myClass.getManager())) { + final String descr = PsiFormatUtil.formatMethod(existing, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_TYPE, + PsiFormatUtil.SHOW_TYPE + ); + String message = "There already is a method " + ConflictsUtil.htmlEmphasize(descr) + " which differs from " + + methodRole + " " + ConflictsUtil.htmlEmphasize(prototype.getName()) + " by return type only."; + conflicts.add(message); + } + } + } + } + + protected UsageInfo[] findUsages() { + boolean findGet = myDialog.isToEncapsulateGet(); + boolean findSet = myDialog.isToEncapsulateSet(); + PsiModifierList newModifierList = null; + if (!myDialog.isToUseAccessorsWhenAccessible()){ + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + try{ + PsiField field = factory.createField("a", PsiType.INT); + setNewFieldVisibility(field); + newModifierList = field.getModifierList(); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + PsiMethod[] getterPrototypes = myDialog.getGetterPrototypes(); + PsiMethod[] setterPrototypes = myDialog.getSetterPrototypes(); + ArrayList array = new ArrayList(); + PsiField[] fields = myFields; + for(int i = 0; i < fields.length; i++){ + PsiField field = fields[i]; + PsiSearchHelper helper = field.getManager().getSearchHelper(); + PsiReference[] refs = helper.findReferences(field, GlobalSearchScope.projectScope(myProject), false); + for(int j = 0; j < refs.length; j++){ + final PsiReference reference = refs[j]; + if (!(reference instanceof PsiReferenceExpression)) continue; + PsiReferenceExpression ref = (PsiReferenceExpression)reference; + // [Jeka] to avoid recursion in the field's accessors + if (findGet && isUsedInExistingAccessor(getterPrototypes[i], ref)) continue; + if (findSet && isUsedInExistingAccessor(setterPrototypes[i], ref)) continue; + if (!findGet){ + if (!PsiUtil.isAccessedForWriting(ref)) continue; + } + if (!findSet || field.hasModifierProperty(PsiModifier.FINAL)){ + if (!PsiUtil.isAccessedForReading(ref)) continue; + } + if (!myDialog.isToUseAccessorsWhenAccessible()){ + PsiClass accessObjectClass = null; + PsiExpression qualifier = ref.getQualifierExpression(); + if (qualifier != null){ + accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass(qualifier).getElement(); + } + if (PsiManager.getInstance(myProject).getResolveHelper().isAccessible(field, newModifierList, ref, accessObjectClass)) continue; + } + UsageInfo usageInfo = new MyUsageInfo(ref, i); + array.add(usageInfo); + } + } + MyUsageInfo[] usageInfos = array.toArray(new MyUsageInfo[array.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == myFields.length); + + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + + LOG.assertTrue(element instanceof PsiField); + + myFields[idx] = (PsiField)element; + } + + myClass = myFields[0].getContainingClass(); + } + + protected void performRefactoring(UsageInfo[] usages) { + // change visibility of fields + if (myDialog.getFieldsVisibility() != null){ + // "as is" + for(int i = 0; i < myFields.length; i++){ + setNewFieldVisibility(myFields[i]); + } + } + + // generate accessors + myNameToGetter = new com.intellij.util.containers.HashMap(); + myNameToSetter = new com.intellij.util.containers.HashMap(); + for(int i = 0; i < myFields.length; i++){ + PsiField field = myFields[i]; + if (myDialog.isToEncapsulateGet()){ + PsiMethod[] prototypes = myDialog.getGetterPrototypes(); + addOrChangeAccessor(prototypes[i], myNameToGetter); + } + if (myDialog.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL)){ + PsiMethod[] prototypes = myDialog.getSetterPrototypes(); + addOrChangeAccessor(prototypes[i], myNameToSetter); + } + } + + HashSet allFiles = new HashSet(); + HashMap treeSkeletonMap = new com.intellij.util.containers.HashMap(); + for(int i = 0; i < usages.length; i++){ + MyUsageInfo usage = (MyUsageInfo)usages[i]; + if (!usage.getElement().isValid()) continue; + PsiElement element = usage.getElement(); + treeSkeletonMap.put(element, usage); + while(!(element instanceof PsiFile)){ + element = element.getParent(); + if (!treeSkeletonMap.containsKey(element)){ + treeSkeletonMap.put(element, null); + } + } + allFiles.add(element); + } + + for(Iterator iterator = allFiles.iterator(); iterator.hasNext();){ + PsiFile file = (PsiFile)iterator.next(); + processSubtree(file, treeSkeletonMap); + } + } + + private void setNewFieldVisibility(PsiField field) { + try{ + if (myDialog.getFieldsVisibility() != null){ + field.getModifierList().setModifierProperty(myDialog.getFieldsVisibility(), true); + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + + private void addOrChangeAccessor(PsiMethod prototype, HashMap nameToAncestor) { + PsiMethod existing = myClass.findMethodBySignature(prototype, false); + PsiMethod result = existing; + try{ + if (existing == null){ + prototype.getModifierList().setModifierProperty(myDialog.getAccessorsVisibility(), true); + result = (PsiMethod) myClass.add(prototype); + } + else{ + //TODO : change visibility + } + nameToAncestor.put(prototype.getName(), result); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + + private boolean isUsedInExistingAccessor(PsiMethod prototype, PsiElement element) { + PsiMethod existingAccessor = myClass.findMethodBySignature(prototype, false); + if (existingAccessor != null) { + PsiElement parent = element; + while (parent != null) { + if (existingAccessor.equals(parent)) return true; + parent = parent.getParent(); + } + } + return false; + } + + private void processSubtree(PsiElement root, HashMap treeSkeletonMap) { + if (!treeSkeletonMap.containsKey(root)) return; + if (root instanceof PsiAssignmentExpression){ + PsiAssignmentExpression assignment = (PsiAssignmentExpression)root; + PsiExpression rExpr = assignment.getRExpression(); + if (rExpr != null){ + processSubtree(rExpr, treeSkeletonMap); + } + processSubtree(assignment.getLExpression(), treeSkeletonMap); + } + else{ + PsiElement[] children = root.getChildren(); + for(int i = 0; i < children.length; i++){ + processSubtree(children[i], treeSkeletonMap); + } + } + MyUsageInfo usage = treeSkeletonMap.get(root); + if (usage != null){ + processUsage(usage); + } + } + + private void processUsage(MyUsageInfo usage) { + PsiField field = myFields[usage.fieldIndex]; + boolean processGet = myDialog.isToEncapsulateGet(); + boolean processSet = myDialog.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL); + if (!processGet && !processSet) return; + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + + try{ + final PsiReferenceExpression expr = (PsiReferenceExpression)usage.getElement(); + final PsiElement parent = expr.getParent(); + if (parent instanceof PsiAssignmentExpression && expr.equals(((PsiAssignmentExpression)parent).getLExpression())){ + PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent; + if (assignment.getRExpression() == null) return; + PsiJavaToken opSign = assignment.getOperationSign(); + IElementType opType = opSign.getTokenType(); + if (opType == JavaTokenType.EQ) { + { + if (!processSet) return; + final int fieldIndex = usage.fieldIndex; + final PsiExpression setterArgument = assignment.getRExpression(); + + PsiMethodCallExpression methodCall = createSetterCall(fieldIndex, setterArgument, expr); + + if (methodCall != null) { + assignment.replace(methodCall); + } + //TODO: check if value is used!!! + } + } + else if (opType == JavaTokenType.ASTERISKEQ || opType == JavaTokenType.DIVEQ || opType == JavaTokenType.PERCEQ || + opType == JavaTokenType.PLUSEQ || + opType == JavaTokenType.MINUSEQ || + opType == JavaTokenType.LTLTEQ || + opType == JavaTokenType.GTGTEQ || + opType == JavaTokenType.GTGTGTEQ || + opType == JavaTokenType.ANDEQ || + opType == JavaTokenType.OREQ || + opType == JavaTokenType.XOREQ) { + { + // Q: side effects of qualifier??! + + String opName = opSign.getText(); + LOG.assertTrue(StringUtil.endsWithChar(opName, '=')); + opName = opName.substring(0, opName.length() - 1); + + PsiExpression getExpr = expr; + if (processGet) { + final int fieldIndex = usage.fieldIndex; + final PsiMethodCallExpression getterCall = createGetterCall(fieldIndex, expr); + if (getterCall != null) { + getExpr = getterCall; + } + } + + String text = "a" + opName + "b"; + PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, expr); + binExpr = (PsiBinaryExpression)CodeStyleManager.getInstance(myProject).reformat(binExpr); + binExpr.getLOperand().replace(getExpr); + binExpr.getROperand().replace(assignment.getRExpression()); + + PsiExpression setExpr; + if (processSet) { + PsiMethodCallExpression methodCall = createSetterCall(usage.fieldIndex, binExpr, expr); + setExpr = methodCall; + } + else { + text = "a = b"; + PsiAssignmentExpression assignment1 = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); + assignment1 = (PsiAssignmentExpression)CodeStyleManager.getInstance(myProject).reformat(assignment1); + assignment1.getLExpression().replace(expr); + assignment1.getRExpression().replace(binExpr); + setExpr = assignment1; + } + + assignment.replace(setExpr); + //TODO: check if value is used!!! + } + } + } + else if (isPlusPlusOrMinusMinus(parent)){ + PsiJavaToken sign; + if (parent instanceof PsiPrefixExpression){ + sign = ((PsiPrefixExpression)parent).getOperationSign(); + } + else{ + sign = ((PsiPostfixExpression)parent).getOperationSign(); + } + IElementType tokenType = sign.getTokenType(); + + PsiExpression getExpr = expr; + if (processGet){ + final int fieldIndex = usage.fieldIndex; + final PsiMethodCallExpression getterCall = createGetterCall(fieldIndex, expr); + if(getterCall != null) { + getExpr = getterCall; + } + } + + String text; + if (tokenType == JavaTokenType.PLUSPLUS){ + text = "a+1"; + } + else{ + text = "a-1"; + } + PsiBinaryExpression binExpr = (PsiBinaryExpression)factory.createExpressionFromText(text, null); + binExpr = (PsiBinaryExpression)CodeStyleManager.getInstance(myProject).reformat(binExpr); + binExpr.getLOperand().replace(getExpr); + + PsiExpression setExpr; + if (processSet){ + final int fieldIndex = usage.fieldIndex; + final PsiMethodCallExpression setterCall = createSetterCall(fieldIndex, binExpr, expr); + setExpr = setterCall; + } + else{ + text = "a = b"; + PsiAssignmentExpression assignment = (PsiAssignmentExpression)factory.createExpressionFromText(text, null); + assignment = (PsiAssignmentExpression)CodeStyleManager.getInstance(myProject).reformat(assignment); + assignment.getLExpression().replace(expr); + assignment.getRExpression().replace(binExpr); + setExpr = assignment; + } + parent.replace(setExpr); + } + else{ + if (!processGet) return; + PsiMethodCallExpression methodCall = createGetterCall(usage.fieldIndex, expr); + + if (methodCall != null) { + expr.replace(methodCall); + } + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + + private PsiMethodCallExpression createSetterCall(final int fieldIndex, final PsiExpression setterArgument, PsiReferenceExpression expr) throws IncorrectOperationException { + String[] setterNames = myDialog.getSetterNames(); + PsiElementFactory factory = expr.getManager().getElementFactory(); + final String setterName = setterNames[fieldIndex]; + String text = setterName + "(a)"; + PsiExpression qualifier = expr.getQualifierExpression(); + if (qualifier != null){ + text = "q." + text; + } + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); + methodCall = (PsiMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(methodCall); + + methodCall.getArgumentList().getExpressions()[0].replace(setterArgument); + if (qualifier != null){ + methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); + } + final PsiMethod targetMethod = myNameToSetter.get(setterName); + methodCall = checkMethodResolvable(methodCall, targetMethod, expr); + if (methodCall == null) { + VisibilityUtil.escalateVisibility(myFields[fieldIndex], expr); + } + return methodCall; + } + + private PsiMethodCallExpression createGetterCall(final int fieldIndex, PsiReferenceExpression expr) + throws IncorrectOperationException { + String[] getterNames = myDialog.getGetterNames(); + PsiElementFactory factory = expr.getManager().getElementFactory(); + final String getterName = getterNames[fieldIndex]; + String text = getterName + "()"; + PsiExpression qualifier = expr.getQualifierExpression(); + if (qualifier != null){ + text = "q." + text; + } + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)factory.createExpressionFromText(text, expr); + methodCall = (PsiMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(methodCall); + + if (qualifier != null){ + methodCall.getMethodExpression().getQualifierExpression().replace(qualifier); + } + + final PsiMethod targetMethod = myNameToGetter.get(getterName); + methodCall = checkMethodResolvable(methodCall, targetMethod, expr); + if(methodCall == null) { + VisibilityUtil.escalateVisibility(myFields[fieldIndex], expr); + } + return methodCall; + } + + private PsiMethodCallExpression checkMethodResolvable(PsiMethodCallExpression methodCall, final PsiMethod targetMethod, PsiReferenceExpression context) throws IncorrectOperationException { + PsiElementFactory factory = targetMethod.getManager().getElementFactory(); + final PsiElement resolved = methodCall.getMethodExpression().resolve(); + if (resolved != targetMethod) { + LOG.assertTrue(resolved instanceof PsiMethod); + final PsiClass containingClass = ((PsiMethod) resolved).getContainingClass(); + if(containingClass.isInheritor(myClass, false)) { + final PsiExpression newMethodExpression = + factory.createExpressionFromText("super." + targetMethod.getName(), context); + methodCall.getMethodExpression().replace(newMethodExpression); + } else { + methodCall = null; + } + } + return methodCall; + } + + private boolean isPlusPlusOrMinusMinus(PsiElement expression) { + if (expression instanceof PsiPrefixExpression){ + PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression; + PsiJavaToken sign = prefixExpression.getOperationSign(); + IElementType tokenType = sign.getTokenType(); + return tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS; + } + if (expression instanceof PsiPostfixExpression){ + PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression; + PsiJavaToken sign = postfixExpression.getOperationSign(); + IElementType tokenType = sign.getTokenType(); + return tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS; + } + return false; + } + + private static class MyUsageInfo extends UsageInfo { + public final int fieldIndex; + + public MyUsageInfo(PsiJavaCodeReferenceElement ref, int fieldIndex) { + super(ref); + this.fieldIndex = fieldIndex; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java new file mode 100644 index 00000000000..b435371bb86 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsViewDescriptor.java @@ -0,0 +1,93 @@ + +package com.intellij.refactoring.encapsulateFields; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class EncapsulateFieldsViewDescriptor implements UsageViewDescriptor { + private PsiField[] myFields; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public EncapsulateFieldsViewDescriptor(PsiField[] fields, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myFields = fields; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public String getProcessedElementsHeader() { + return "Fields to be encapsulated"; + } + + public PsiElement[] getElements() { + return myFields; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + if (elements.length > 1) { + myFields = new PsiField[elements.length]; + for (int idx = 0; idx < elements.length; idx++) { + myFields[idx] = (PsiField)elements[idx]; + } + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References to be changed " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractClassUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractClassUtil.java new file mode 100644 index 00000000000..b87dbc88032 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractClassUtil.java @@ -0,0 +1,50 @@ +package com.intellij.refactoring.extractInterface; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessor; +import com.intellij.refactoring.ui.YesNoPreviewUsagesDialog; + +/** + * @author dsl + */ +public class ExtractClassUtil { + public static void askAndTurnRefsToSuper(final Project project, PsiClass aClass, final PsiClass aSuperClass) { + final SmartPsiElementPointer classPointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(aClass); + final SmartPsiElementPointer interfacePointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(aSuperClass); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final PsiElement classElement = classPointer.getElement(); + final PsiElement interfaceElement = interfacePointer.getElement(); + if (classElement != null && classElement instanceof PsiClass && interfaceElement != null && interfaceElement instanceof PsiClass) { + final PsiClass superClass = (PsiClass) interfaceElement; + String interfaceName = superClass.getName(); + String className = ((PsiClass) classElement).getName(); + String message = (superClass.isInterface() ? "Interface " : "Class ") + + interfaceName + " has been successfully created.\n" + + "At this stage, IDEA can analyze usages of " + className + "\nand replace them with usages of the " + + (superClass.isInterface() ? "interface " : "superclass ") + + "where possible.\n" + + "Do you want to proceed?"; + YesNoPreviewUsagesDialog dialog = new YesNoPreviewUsagesDialog( + "Analyze and Replace Usages", + message, + RefactoringSettings.getInstance().EXTRACT_INTERFACE_PREVIEW_USAGES, + /*HelpID.TURN_REFS_TO_SUPER*/null, project); + dialog.show(); + if (dialog.isOK()) { + RefactoringSettings.getInstance().EXTRACT_INTERFACE_PREVIEW_USAGES = dialog.isPreviewUsages(); + TurnRefsToSuperProcessor processor = + new TurnRefsToSuperProcessor(project, (PsiClass) classElement, (PsiClass) interfaceElement, true, dialog.isPreviewUsages()); + processor.run(null); + } + } + } + }); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java new file mode 100644 index 00000000000..77bad27eea3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java @@ -0,0 +1,295 @@ +package com.intellij.refactoring.extractInterface; + +import com.intellij.ide.util.PackageChooserDialog; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.extractSuperclass.ExtractSuperBaseDialog; +import com.intellij.refactoring.memberPullUp.JavaDocPanel; +import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.DelegatingMemberInfoModel; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class ExtractInterfaceDialog extends ExtractSuperBaseDialog { + + private final Project myProject; + private final PsiClass myClass; + + private PsiDirectory myTargetDirectory; + + private MemberInfo[] myMemberInfos; + + private JTextField myInterfaceNameField; + private final JTextField myTfPackageName; + private final FixedSizeButton myBtnPackageChooser; + private JTextField mySourceClassField; + + private JavaDocPanel myJavaDocPanel; + private JLabel myInterfaceNameLabel; + private JLabel myPackageLabel; + + public ExtractInterfaceDialog(Project project, PsiClass aClass) { + super(project, true); + setTitle(ExtractInterfaceHandler.REFACTORING_NAME); + + myProject = project; + myClass = aClass; + + myTfPackageName = new JTextField(); + myBtnPackageChooser = new FixedSizeButton(myTfPackageName); + + init(); + } + + public int getJavaDocPolicy() { + return myJavaDocPanel.getPolicy(); + } + + protected void init() { + myTargetDirectory = myClass.getContainingFile().getContainingDirectory(); + myMemberInfos = MemberInfo.extractClassMembers( + myClass, new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + if (element instanceof PsiMethod) { + return !((PsiMethod)element).isConstructor() + && element.hasModifierProperty(PsiModifier.PUBLIC) + && !element.hasModifierProperty(PsiModifier.STATIC); + } + else if (element instanceof PsiField) { + return element.hasModifierProperty(PsiModifier.FINAL) + && element.hasModifierProperty(PsiModifier.STATIC) + && element.hasModifierProperty(PsiModifier.PUBLIC); + } + else if (element instanceof PsiClass && ((PsiClass)element).isInterface()) { + return true; + } + return false; + } + } + ); + + super.init(); + + mySourceClassField.setText(myClass.getQualifiedName()); + + PsiFile file = myClass.getContainingFile(); + if (file instanceof PsiJavaFile) { + myTfPackageName.setText(((PsiJavaFile)file).getPackageName()); + } + + updateDialogForExtractSuperclass(); + } + + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + + + public MemberInfo[] getSelectedMembers() { + int[] rows = getCheckedRows(); + MemberInfo[] selectedMethods = new MemberInfo[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + selectedMethods[idx] = myMemberInfos[rows[idx]]; + } + return selectedMethods; + } + + private String getTargetPackageName() { + return myTfPackageName.getText().trim(); + } + + public String getInterfaceName() { + return myInterfaceNameField.getText().trim(); + } + + protected JComponent createNorthPanel() { + Box box = Box.createVerticalBox(); + + mySourceClassField = new JTextField(); + mySourceClassField.setEditable(false); + JPanel _panel = new JPanel(new BorderLayout()); + _panel.add(new JLabel("Extract interface from:"), BorderLayout.NORTH); + _panel.add(mySourceClassField, BorderLayout.CENTER); + box.add(_panel); + + box.add(Box.createVerticalStrut(10)); + + box.add(createActionComponent()); + + box.add(Box.createVerticalStrut(10)); + + myInterfaceNameLabel = new JLabel("Interface name:"); + myInterfaceNameField = new JTextField(); + myInterfaceNameLabel.setLabelFor(myInterfaceNameField); + myInterfaceNameLabel.setDisplayedMnemonic('I'); + _panel = new JPanel(new BorderLayout()); + _panel.add(myInterfaceNameLabel, BorderLayout.NORTH); + _panel.add(myInterfaceNameField, BorderLayout.CENTER); + box.add(_panel); + box.add(Box.createVerticalStrut(5)); + + myBtnPackageChooser.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PackageChooserDialog chooser = new PackageChooserDialog("Choose Destination Package", myProject); + chooser.selectPackage(myTfPackageName.getText()); + chooser.show(); + PsiPackage aPackage = chooser.getSelectedPackage(); + if (aPackage != null) { + myTfPackageName.setText(aPackage.getQualifiedName()); + } + } + }); + _panel = new JPanel(new BorderLayout()); + myPackageLabel = new JLabel("Package for new interface:"); + myPackageLabel.setLabelFor(myTfPackageName); + myPackageLabel.setDisplayedMnemonic('P'); + _panel.add(myPackageLabel, BorderLayout.NORTH); + _panel.add(myTfPackageName, BorderLayout.CENTER); + _panel.add(myBtnPackageChooser, BorderLayout.EAST); + box.add(_panel); + box.add(Box.createVerticalStrut(10)); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(box, BorderLayout.CENTER); + return panel; + } + + protected JLabel getClassNameLabel() { + return myInterfaceNameLabel; + } + + protected JLabel getPackageNameLabel() { + return myPackageLabel; + } + + protected String getEntityName() { + return "Interface"; + } + + protected boolean getInitialPreviewResults() { + return false; + } + + protected void setInitialPreviewResults(boolean value) { + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + //panel.setBorder(BorderFactory.createLineBorder(Color.gray)); + final MemberSelectionPanel memberSelectionPanel = new MemberSelectionPanel("Members to Form Interface", + myMemberInfos, null); + memberSelectionPanel.getTable().setMemberInfoModel( + new DelegatingMemberInfoModel(memberSelectionPanel.getTable().getMemberInfoModel()) { + public Boolean isFixedAbstract(MemberInfo member) { + return Boolean.TRUE; + } + } + ); + panel.add(memberSelectionPanel, BorderLayout.CENTER); + + myJavaDocPanel = new JavaDocPanel("JavaDoc"); + final int oldJavaDocPolicy = RefactoringSettings.getInstance().EXTRACT_INTERFACE_JAVADOC; + myJavaDocPanel.setPolicy(oldJavaDocPolicy); + panel.add(myJavaDocPanel, BorderLayout.EAST); + + return panel; + } + + + public JComponent getPreferredFocusedComponent() { + return myInterfaceNameField; + } + + protected void doAction() { + final String[] errorString = new String[]{null}; + final String interfaceName = getInterfaceName(); + final String packageName = getTargetPackageName(); + final PsiManager manager = PsiManager.getInstance(myProject); + if ("".equals(interfaceName)) { + errorString[0] = "No interface name specified"; + myInterfaceNameField.requestFocusInWindow(); + } + else if (!manager.getNameHelper().isIdentifier(interfaceName)) { + errorString[0] = RefactoringMessageUtil.getIncorrectIdentifierMessage(interfaceName); + myInterfaceNameField.requestFocusInWindow(); + } + else { + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + try { + myTargetDirectory = + PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, myTargetDirectory, true); + if (myTargetDirectory == null) { + errorString[0] = ""; // message already reported by PackageUtil + return; + } + } + catch (IncorrectOperationException e) { + errorString[0] = e.getMessage(); + return; + } + final Runnable action = new Runnable() { + public void run() { + errorString[0] = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, interfaceName); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, "Create directory", null); + } + if (errorString[0] != null) { + if (errorString[0].length() > 0) { + RefactoringMessageUtil.showErrorMessage(ExtractInterfaceHandler.REFACTORING_NAME, errorString[0], + HelpID.EXTRACT_INTERFACE, myProject); + } + return; + } + + if (!isExtractSuperclass()) { + final ExtractInterfaceProcessor processor = new ExtractInterfaceProcessor( + myProject, false, getTargetDirectory(), interfaceName, myClass, + getSelectedMembers(), new JavaDocPolicy(getJavaDocPolicy())); + invokeRefactoring(processor); + } + + RefactoringSettings.getInstance().EXTRACT_INTERFACE_JAVADOC = getJavaDocPolicy(); + closeOKAction(); + } + + private int[] getCheckedRows() { + int count = 0; + for (int idx = 0; idx < myMemberInfos.length; idx++) { + if (myMemberInfos[idx].isChecked()) { + count++; + } + } + int[] rows = new int[count]; + int currentRow = 0; + for (int idx = 0; idx < myMemberInfos.length; idx++) { + if (myMemberInfos[idx].isChecked()) { + rows[currentRow++] = idx; + } + } + return rows; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.EXTRACT_INTERFACE); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java new file mode 100644 index 00000000000..e57429bff09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java @@ -0,0 +1,138 @@ +package com.intellij.refactoring.extractInterface; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +public class ExtractInterfaceHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractInterface.ExtractInterfaceHandler"); + + public static final String REFACTORING_NAME = "Extract Interface"; + + + private Project myProject; + private PsiClass myClass; + + private String myInterfaceName; + private MemberInfo[] mySelectedMembers; + private PsiDirectory myTargetDir; + private JavaDocPolicy myJavaDocPolicy; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the class to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_INTERFACE, project); + return; + } + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + + myProject = project; + myClass = (PsiClass) elements[0]; + + + if (!myClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, myClass); + return; + } + + final ExtractInterfaceDialog dialog = new ExtractInterfaceDialog( + myProject, + myClass + ); + dialog.show(); + if (!dialog.isOK() || !dialog.isExtractSuperclass()) return; + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myInterfaceName = dialog.getInterfaceName(); + mySelectedMembers = dialog.getSelectedMembers(); + myTargetDir = dialog.getTargetDirectory(); + myJavaDocPolicy = new JavaDocPolicy(dialog.getJavaDocPolicy()); + try { + doRefactoring(); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }); + } + }, + REFACTORING_NAME, + null + ); + + } + + + private void doRefactoring() throws IncorrectOperationException { + LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + PsiClass anInterface = null; + try { + anInterface = extractInterface(myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy); + } catch(IncorrectOperationException ex) { + throw ex; + } finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + + /*PsiJavaCodeReferenceElement ref = myManager.getElementFactory().createClassReferenceElement(anInterface); + sourceClassRefList.add(ref);*/ + if (anInterface != null) { + ExtractClassUtil.askAndTurnRefsToSuper(myProject, myClass, anInterface); + } + } + + static PsiClass extractInterface(PsiDirectory targetDir1, + PsiClass aClass, + String interfaceName, + MemberInfo[] selectedMembers, + JavaDocPolicy javaDocPolicy) throws IncorrectOperationException { + PsiClass anInterface; + final PsiDirectory targetDir = targetDir1; + anInterface = targetDir.createInterface(interfaceName); + PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy); + pullUpHelper.moveMembersToBase(); + final PsiManager manager = aClass.getManager(); + PsiJavaCodeReferenceElement ref = manager.getElementFactory().createClassReferenceElement(anInterface); + final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList(); + referenceList.add(ref); + return anInterface; + } + + private String getCommandName() { + return "Extracting interface " + myInterfaceName + " from " + UsageViewUtil.getDescriptiveName(myClass); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceProcessor.java new file mode 100644 index 00000000000..53160c1cd97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractInterface/ExtractInterfaceProcessor.java @@ -0,0 +1,49 @@ +package com.intellij.refactoring.extractInterface; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.extractSuperclass.ExtractSuperBaseProcessor; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class ExtractInterfaceProcessor extends ExtractSuperBaseProcessor { + public ExtractInterfaceProcessor(Project project, + boolean replaceInstanceOf, + PsiDirectory targetDirectory, + String newClassName, + PsiClass aClass, + MemberInfo[] memberInfos, + JavaDocPolicy javaDocPolicy) { + super(project, replaceInstanceOf, targetDirectory, newClassName, aClass, memberInfos, javaDocPolicy); + } + + protected PsiClass extractSuper(String superClassName) throws IncorrectOperationException { + final PsiClass anInterface = ExtractInterfaceHandler.extractInterface(myTargetDirectory, myClass, superClassName, myMemberInfos, myJavaDocPolicy); + return anInterface; + } + + protected boolean isSuperInheritor(PsiClass aClass) { + if (!aClass.isInterface()) { + return myClass.isInheritor(aClass, true); + } + else { + return doesAnyExtractedInterfaceExtends(aClass); + } + } + + protected boolean isInSuper(PsiElement member) { + if (member instanceof PsiField) { + final PsiField field = ((PsiField)member); + return doMemberInfosContain(field); + } + else if (member instanceof PsiMethod) { + PsiMethod method = (PsiMethod) member; + return doMemberInfosContain(method); + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java new file mode 100644 index 00000000000..353d8eac696 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -0,0 +1,309 @@ +package com.intellij.refactoring.extractMethod; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.ui.VisibilityPanel; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; + + +class ExtractMethodDialog extends DialogWrapper { + private final Project myProject; + private final PsiType myReturnType; + private final PsiTypeParameterList myTypeParameterList; + private final PsiType[] myExceptions; + private final boolean myStaticFlag; + private final boolean myCanBeStatic; + private final String myHelpId; + + private final JTextField myTfName; + private final JTextArea mySignatureArea; + private final JCheckBox myCbMakeStatic; + + private final ParameterTablePanel.VariableData[] myVariableData; + private final PsiClass myTargetClass; + private VisibilityPanel myVisibilityPanel; + + + // TODO : choose visibility? + public ExtractMethodDialog(Project project, + PsiClass targetClass, final PsiVariable[] inputVariables, PsiType returnType, + PsiTypeParameterList typeParameterList, PsiType[] exceptions, boolean isStatic, boolean canBeStatic, String initialMethodName, + String title, String helpId) { + super(project, true); + myProject = project; + myTargetClass = targetClass; + myReturnType = returnType; + myTypeParameterList = typeParameterList; + myExceptions = exceptions; + myStaticFlag = isStatic; + myCanBeStatic = canBeStatic; + + final java.util.List variableData = new ArrayList(inputVariables.length); + for (int i = 0; i < inputVariables.length; i++) { + PsiVariable var = inputVariables[i]; + String name = var.getName(); + if (!(var instanceof PsiParameter)) { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + VariableKind kind = codeStyleManager.getVariableKind(var); + name = codeStyleManager.variableNameToPropertyName(name, kind); + name = codeStyleManager.propertyNameToVariableName(name, VariableKind.PARAMETER); + } + ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(var); + data.name = name; + data.passAsParameter = true; + variableData.add(data); + } + myVariableData = (ParameterTablePanel.VariableData[]) variableData.toArray(new ParameterTablePanel.VariableData[variableData.size()]); + + setTitle(title); + myHelpId = helpId; + + // Create UI components + + myTfName = new JTextField(30); + myTfName.setText(initialMethodName); + + int height = myVariableData.length + 2; + if (myExceptions.length > 0) { + height += myExceptions.length + 1; + } + mySignatureArea = new JTextArea(height, 30); + myCbMakeStatic = new NonFocusableCheckBox("Declare static"); + + // Initialize UI + + init(); + } + + public boolean isMakeStatic() { + if (myStaticFlag) return true; + if (!myCanBeStatic) return false; + return myCbMakeStatic.isSelected(); + } + + protected Action[] createActions() { + if (myHelpId != null) { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } else { + return new Action[]{getOKAction(), getCancelAction()}; + } + } + + public String getChoosenMethodName() { + return myTfName.getText(); + } + + public ParameterTablePanel.VariableData[] getChoosenParameters() { + return myVariableData; + } + + public JComponent getPreferredFocusedComponent() { + return myTfName; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpId); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP)); + panel.setBorder(IdeBorderFactory.createTitledBorder("Method")); + + JLabel lblName = new JLabel("Name:"); + lblName.setDisplayedMnemonic('N'); + lblName.setLabelFor(myTfName); + panel.add(lblName); + + panel.add(myTfName); + + myTfName.getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + update(); + } + }); + setOKActionEnabled(false); + myCbMakeStatic.setMnemonic('s'); + panel.add(myCbMakeStatic); + if (myStaticFlag || myCanBeStatic) { + myCbMakeStatic.setEnabled(!myStaticFlag); + myCbMakeStatic.setSelected(myStaticFlag); + myCbMakeStatic.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateSignature(); + } + }); + } else { + myCbMakeStatic.setSelected(false); + myCbMakeStatic.setEnabled(false); + } + setOKActionEnabled(PsiManager.getInstance(myProject).getNameHelper().isIdentifier(myTfName.getText())); + + return panel; + } + private void update() { + updateSignature(); + setOKActionEnabled(PsiManager.getInstance(myProject).getNameHelper().isIdentifier(myTfName.getText())); + } + + public String getVisibility() { + return myVisibilityPanel.getVisibility(); + } + + + protected JComponent createCenterPanel() { + myVisibilityPanel = new VisibilityPanel(false); + myVisibilityPanel.setVisibility(PsiModifier.PRIVATE); + myVisibilityPanel.addStateChangedListener(new VisibilityPanel.StateChanged() { + public void visibilityChanged(String newVisibility) { + updateSignature(); + } + }); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(createParametersPanel(), BorderLayout.CENTER); + panel.add(createSignaturePanel(), BorderLayout.SOUTH); + panel.add(myVisibilityPanel, BorderLayout.EAST); + return panel; + } + + private JComponent createParametersPanel() { + JPanel panel = new ParameterTablePanel(myProject, myVariableData) { + protected void updateSignature() { + ExtractMethodDialog.this.updateSignature(); + } + + protected void doEnterAction() { + ExtractMethodDialog.this.clickDefaultButton(); + } + + protected void doCancelAction() { + ExtractMethodDialog.this.doCancelAction(); + } + }; + panel.setBorder(IdeBorderFactory.createTitledBorder("Parameters")); + return panel; + } + + private JComponent createSignaturePanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(IdeBorderFactory.createTitledBorder("Signature Preview")); + + mySignatureArea.setEditable(false); + mySignatureArea.setBackground(this.getContentPane().getBackground()); + panel.add(mySignatureArea, BorderLayout.CENTER); + + updateSignature(); + Dimension size = mySignatureArea.getPreferredSize(); + mySignatureArea.setMaximumSize(size); + mySignatureArea.setMinimumSize(size); + return panel; + } + + protected void doOKAction() { + if (!checkMethodConflicts()) { + return; + } + super.doOKAction(); + } + + private boolean checkMethodConflicts() { + PsiMethod prototype; + try { + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + prototype = factory.createMethod( + myTfName.getText().trim(), + myReturnType + ); + if (myTypeParameterList != null) prototype.getTypeParameterList().replace(myTypeParameterList); + for (int idx = 0; idx < myVariableData.length; idx++) { + ParameterTablePanel.VariableData data = myVariableData[idx]; + if (data.passAsParameter) { + prototype.getParameterList().add(factory.createParameter(data.name, data.variable.getType())); + } + } + // set the modifiers with which the method is supposed to be created + prototype.getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + } catch (IncorrectOperationException e) { + prototype = null; + } + return RefactoringMessageUtil.checkMethodConflicts( + myTargetClass, + null, + prototype + ); + } + + private void updateSignature() { + if (mySignatureArea == null) return; + StringBuffer buffer = new StringBuffer(); + final String visibilityString = VisibilityUtil.getVisibilityString(myVisibilityPanel.getVisibility()); + buffer.append(visibilityString); + if (buffer.length() > 0) { + buffer.append(" "); + } + if (isMakeStatic()) { + buffer.append("static "); + } + if (myTypeParameterList != null) { + buffer.append(myTypeParameterList.getText()); + buffer.append(" "); + } + + buffer.append(PsiFormatUtil.formatType(myReturnType, 0, PsiSubstitutor.EMPTY)); + buffer.append(" "); + buffer.append(myTfName.getText()); + buffer.append("("); + int count = 0; + final String INDENT = " "; + for (int idx = 0; idx < myVariableData.length; idx++) { + ParameterTablePanel.VariableData data = myVariableData[idx]; + if (data.passAsParameter) { + //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable, + // PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE); + String type = PsiManager.getInstance(myProject).getElementFactory().createTypeElement(data.variable.getType()).getText(); + if (count > 0) { + buffer.append(","); + } + buffer.append("\n"); + buffer.append(INDENT); + buffer.append(type); + buffer.append(" "); + buffer.append(data.name); + count++; + } + } + if (count > 0) { + buffer.append("\n"); + } + buffer.append(")"); + if (myExceptions.length > 0) { + buffer.append("\n"); + buffer.append("throws\n"); + for (int i = 0; i < myExceptions.length; i++) { + PsiType exception = myExceptions[i]; + buffer.append(INDENT); + buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY)); + buffer.append("\n"); + } + } + mySignatureArea.setText(buffer.toString()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java new file mode 100644 index 00000000000..db356eb8f54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java @@ -0,0 +1,127 @@ +package com.intellij.refactoring.extractMethod; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.duplicates.DuplicatesImpl; +import com.intellij.util.IncorrectOperationException; + +public class ExtractMethodHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractMethod.ExtractMethodHandler"); + + public static final String REFACTORING_NAME = "Extract Method"; + + public void invoke(final Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + if (!editor.getSelectionModel().hasSelection()) { + editor.getSelectionModel().selectLineAtCaret(); + } + int startOffset = editor.getSelectionModel().getSelectionStart(); + int endOffset = editor.getSelectionModel().getSelectionEnd(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiElement[] elements; + PsiExpression expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset); + if (expr != null) { + elements = new PsiElement[]{expr}; + } else { + elements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); + } + + if (elements == null || elements.length == 0) { + String message = "Cannot perform the refactoring.\n" + + "Selected block should represent a set of statements or an expression."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_METHOD, project); + return; + } + + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return; + } + + + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if(element instanceof PsiStatement && RefactoringUtil.isSuperOrThisCall((PsiStatement) element, true, true)) { + String message = + "Cannot perform the refactoring.\n" + + "Selected block contains invocation of another class constructor."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_METHOD, project); + return; + } + } + + final ExtractMethodProcessor processor = new ExtractMethodProcessor(project, editor, file, elements, null, REFACTORING_NAME, "", HelpID.EXTRACT_METHOD); + + try { + if (!processor.prepare()) return; + + + if (processor.showDialog()) { + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + processor.doRefactoring(); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + REFACTORING_NAME, + null + ); + + DuplicatesImpl.processDuplicates(processor, project, editor, REFACTORING_NAME); + } + } + catch (PrepareFailedException e) { + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, e.getMessage(), HelpID.EXTRACT_METHOD, project); + highlightPrepareError(e, file, editor, project); + } + } + + public static void highlightPrepareError(PrepareFailedException e, + PsiFile file, + Editor editor, + final Project project) { + if (e.getFile() == file) { + final TextRange textRange = e.getTextRange(); + final HighlightManager highlightManager = HighlightManager.getInstance(project); + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + highlightManager.addRangeHighlight(editor, textRange.getStartOffset(), textRange.getEndOffset(), + attributes, true, null); + final LogicalPosition logicalPosition = editor.offsetToLogicalPosition(textRange.getStartOffset()); + editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.MAKE_VISIBLE); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java new file mode 100644 index 00000000000..b49bb591d1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -0,0 +1,877 @@ +package com.intellij.refactoring.extractMethod; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.controlFlow.ControlFlow; +import com.intellij.psi.controlFlow.ControlFlowAnalyzer; +import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.controlFlow.LocalsControlFlowPolicy; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.text.BlockSupport; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.classMembers.ElementNeedsThis; +import com.intellij.refactoring.util.duplicates.DuplicatesFinder; +import com.intellij.refactoring.util.duplicates.Match; +import com.intellij.refactoring.util.duplicates.MatchProvider; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.IntArrayList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ExtractMethodProcessor implements MatchProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractMethod.ExtractMethodProcessor"); + + private final Project myProject; + private final Editor myEditor; + private final PsiFile myFile; + private final PsiElement[] myElements; + private final PsiBlockStatement myEnclosingBlockStatement; + private final PsiType myForcedReturnType; + private final String myRefactoringName; + private final String myInitialMethodName; + private final String myHelpId; + + private final PsiManager myManager; + private final PsiElementFactory myElementFactory; + private final CodeStyleManager myStyleManager; + + private PsiExpression myExpression; + + private PsiElement myCodeFragment; // "code fragment" (code block or expression) containing the code to extract + private PsiElement myCodeFragementMember; // parent of myCodeFragment + + private String myMethodName; // name for extracted method + private PsiType myReturnType; // return type for extracted method + private PsiTypeParameterList myTypeParameterList; //type parameter list of extracted method + private ParameterTablePanel.VariableData[] myVariableDatas; // parameter data for extracted method + private PsiClassType[] myThrownExceptions; // exception to declare as thrown by extracted method + private boolean myStatic; // whether to declare extracted method static + + private PsiClass myTargetClass; // class to create the extracted method in + private PsiElement myAnchor; // anchor to insert extracted method after it + + private ControlFlow myControlFlow; // control flow of myCodeFragment + private int myFlowStart; // offset in control flow corresponding to the start of the code to be extracted + private int myFlowEnd; // offset in control flow corresponding to position just after the end of the code to be extracted + + private PsiVariable[] myInputVariables; // input variables + private PsiVariable[] myOutputVariables; // output variables + private PsiVariable myOutputVariable; // the only output variable + private int myExitPoint; + private List myExitStatements; + + private boolean myHasReturnStatement; // there is a return statement + private boolean myHasReturnStatementOutput; // there is a return statement and its type is not void + private boolean myHasExpressionOutput; // extracted code is an expression with non-void type + private boolean myNeedChangeContext; // target class is not immediate container of the code to be extracted + + private boolean myShowErrorDialogs = true; + private boolean myCanBeStatic; + private List myDuplicates; + private DuplicatesFinder myDuplicatesFinder; + private String myMethodVisibility = PsiModifier.PRIVATE; + + public ExtractMethodProcessor(Project project, Editor editor, PsiFile file, PsiElement[] elements, + PsiType forcedReturnType, String refactoringName, + String initialMethodName, String helpId) { + myProject = project; + myEditor = editor; + myFile = file; + if (elements.length != 1 || (elements.length == 1 && !(elements[0] instanceof PsiBlockStatement))) { + myElements = elements; + myEnclosingBlockStatement = null; + } + else { + myEnclosingBlockStatement = (PsiBlockStatement)elements[0]; + PsiElement[] codeBlockChildren = myEnclosingBlockStatement.getCodeBlock().getChildren(); + myElements = processCodeBlockChildren(codeBlockChildren); + } + myForcedReturnType = forcedReturnType; + myRefactoringName = refactoringName; + myInitialMethodName = initialMethodName; + myHelpId = helpId; + + myManager = PsiManager.getInstance(myProject); + myElementFactory = myManager.getElementFactory(); + myStyleManager = CodeStyleManager.getInstance(myProject); + } + + private static PsiElement[] processCodeBlockChildren(PsiElement[] codeBlockChildren) { + int resultStart = 0; + int resultLast = codeBlockChildren.length; + + if (codeBlockChildren.length == 0) return PsiElement.EMPTY_ARRAY; + + final PsiElement first = codeBlockChildren[0]; + if (first instanceof PsiJavaToken && ((PsiJavaToken)first).getTokenType() == JavaTokenType.LBRACE) { + resultStart++; + } + final PsiElement last = codeBlockChildren[codeBlockChildren.length - 1]; + if (last instanceof PsiJavaToken && ((PsiJavaToken)last).getTokenType() == JavaTokenType.RBRACE) { + resultLast--; + } + final ArrayList result = new ArrayList(); + for (int i = resultStart; i < resultLast; i++) { + PsiElement element = codeBlockChildren[i]; + if (!(element instanceof PsiWhiteSpace)) { + result.add(element); + } + } + + return result.toArray(new PsiElement[result.size()]); + } + + /** + * Method for test purposes + */ + public void setShowErrorDialogs(boolean showErrorDialogs) { + myShowErrorDialogs = showErrorDialogs; + } + + /** + * Invoked in atomic action + */ + public boolean prepare() throws PrepareFailedException { + myExpression = null; + if (myElements.length == 1 && myElements[0] instanceof PsiExpression) { + final PsiExpression expression = (PsiExpression)myElements[0]; + if (expression.getParent() instanceof PsiExpressionStatement) { + myElements[0] = expression.getParent(); + } + else { + myExpression = expression; + } + } + + //TODO temporary for testing JSPX + if (myFile instanceof JspFileImpl) { + if (myShowErrorDialogs) { + RefactoringMessageUtil.showErrorMessage(myRefactoringName, + myRefactoringName + " refactoring is not supported for JSP", myHelpId, + myProject); + } + return false; + } + + myCodeFragment = ControlFlowUtil.findCodeFragment(myElements[0]); + myCodeFragementMember = myCodeFragment.getParent(); + + ControlFlowAnalyzer analyzer = new ControlFlowAnalyzer(myCodeFragment, new LocalsControlFlowPolicy(myCodeFragment), false); + try { + myControlFlow = analyzer.buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + throw new PrepareFailedException("Code contains syntax errors." + + "Cannot perform neccessary analysis.", + e.getErrorElement()); + } + + if (LOG.isDebugEnabled()) { + LOG.debug(myControlFlow.toString()); + } + + calculateFlowStartAndEnd(); + + IntArrayList exitPoints = new IntArrayList(); + myExitStatements = new ArrayList(); + + ControlFlowUtil.findExitPointsAndStatements + (myControlFlow, myFlowStart, myFlowEnd, exitPoints, myExitStatements, + ControlFlowUtil.DEFAULT_EXIT_STATEMENTS_CLASSES); + + if (LOG.isDebugEnabled()) { + LOG.debug("exit points:"); + for (int i = 0; i < exitPoints.size(); i++) { + LOG.debug(" " + exitPoints.get(i)); + } + LOG.debug("exit statements:"); + for (int i = 0; i < myExitStatements.size(); i++) { + LOG.debug(" " + myExitStatements.get(i)); + } + } + if (exitPoints.size() == 0) { + // if the fragment never exits assume as if it exits in the end + exitPoints.add(myControlFlow.getEndOffset(myElements[myElements.length - 1])); + } + if (exitPoints.size() != 1) { + showMultipleExitPointsMessage(); + return false; + } + myExitPoint = exitPoints.get(0); + + myHasReturnStatement = myExpression == null && + ControlFlowUtil.returnPresentBetween(myControlFlow, myFlowStart, myFlowEnd); + /*myHasReturnStatement = false; + for (int i = 0; i < myExitStatements.size(); i++) { + PsiStatement statement = (PsiStatement) myExitStatements.get(i); + if (statement instanceof PsiReturnStatement) { + myHasReturnStatement = true; + break; + } + }*/ + + myInputVariables = ControlFlowUtil.getInputVariables(myControlFlow, myFlowStart, myFlowEnd); + myOutputVariables = ControlFlowUtil.getOutputVariables(myControlFlow, myFlowStart, myFlowEnd, myExitPoint); + + chooseTargetClass(); + + PsiType expressionType = null; + if (myExpression != null) { +// expressionType = myExpresssion.getType(); + if (myForcedReturnType != null) { + expressionType = myForcedReturnType; + } + else { + expressionType = RefactoringUtil.getTypeByExpressionWithExpectedType(myExpression); + } + } + if (expressionType == null) { + expressionType = PsiType.VOID; + } + myHasExpressionOutput = expressionType != PsiType.VOID; + + PsiType returnStatementType = null; + if (myHasReturnStatement) { + returnStatementType = myCodeFragementMember instanceof PsiMethod + ? ((PsiMethod)myCodeFragementMember).getReturnType() + : null; + } + myHasReturnStatementOutput = returnStatementType != null && returnStatementType != PsiType.VOID; + + if (!myHasReturnStatementOutput) { + int outputCount = (myHasExpressionOutput ? 1 : 0) + myOutputVariables.length; + if (outputCount > 1) { + showMultipleOutputMessage(expressionType); + return false; + } + } + + myOutputVariable = myOutputVariables.length > 0 ? myOutputVariables[0] : null; + if (myHasReturnStatementOutput) { + myReturnType = returnStatementType; + } + else if (myOutputVariable != null) { + myReturnType = myOutputVariable.getTypeElement().getType(); + } + else { + myReturnType = expressionType; + } + + PsiElement container = PsiTreeUtil.getParentOfType(myElements[0], new Class[]{PsiClass.class, PsiMethod.class}); + if (container instanceof PsiMethod) { + myTypeParameterList = ((PsiMethod)container).getTypeParameterList(); + } + myThrownExceptions = ExceptionUtil.getThrownCheckedExceptions(myElements); + myStatic = shouldBeStatic(); + + if (myTargetClass.getContainingClass() == null || + myTargetClass.hasModifierProperty(PsiModifier.STATIC)) { + ElementNeedsThis needsThis = new ElementNeedsThis(myTargetClass); + for (int i = 0; i < myElements.length && !needsThis.usesMembers(); i++) { + PsiElement element = myElements[i]; + element.accept(needsThis); + } + myCanBeStatic = !needsThis.usesMembers(); + } + else { + myCanBeStatic = false; + } + + if (myExpression != null) { + myDuplicatesFinder = new DuplicatesFinder(myElements, Arrays.asList(myInputVariables), new ArrayList(), false); + myDuplicates = myDuplicatesFinder.findDuplicates(myTargetClass); + } + else { + myDuplicatesFinder = new DuplicatesFinder(myElements, Arrays.asList(myInputVariables), Arrays.asList(myOutputVariables), false); + myDuplicates = myDuplicatesFinder.findDuplicates(myTargetClass); + } + + return true; + } + + private boolean shouldBeStatic() { + PsiElement codeFragementMember = myCodeFragementMember; + while (codeFragementMember != null && PsiTreeUtil.isAncestor(myTargetClass, codeFragementMember, true)) { + if (((PsiModifierListOwner)codeFragementMember).hasModifierProperty(PsiModifier.STATIC)) { + return true; + } + codeFragementMember = PsiTreeUtil.getParentOfType(codeFragementMember, PsiModifierListOwner.class, true); + } + return false; + } + + public boolean showDialog() { + ExtractMethodDialog dialog = new ExtractMethodDialog(myProject, + myTargetClass, + myInputVariables, + myReturnType, + myTypeParameterList, + myThrownExceptions, + myStatic, + myCanBeStatic, myInitialMethodName, + myRefactoringName, + myHelpId); + dialog.show(); + if (!dialog.isOK()) return false; + myMethodName = dialog.getChoosenMethodName(); + myVariableDatas = dialog.getChoosenParameters(); + myStatic = myStatic || dialog.isMakeStatic(); + myMethodVisibility = dialog.getVisibility(); + return true; + } + + public void testRun() throws IncorrectOperationException { + ExtractMethodDialog dialog = new ExtractMethodDialog(myProject, + myTargetClass, + myInputVariables, + myReturnType, + myTypeParameterList, myThrownExceptions, + myStatic, + myCanBeStatic, myInitialMethodName, + myRefactoringName, + myHelpId); + myMethodName = dialog.getChoosenMethodName(); + myVariableDatas = dialog.getChoosenParameters(); + doRefactoring(); + } + + /** + * Invoked in command and in atomic action + */ + public void doRefactoring() throws IncorrectOperationException { + chooseAnchor(); + + int col = myEditor.getCaretModel().getLogicalPosition().column; + int line = myEditor.getCaretModel().getLogicalPosition().line; + LogicalPosition pos = new LogicalPosition(0, 0); + myEditor.getCaretModel().moveToLogicalPosition(pos); + + PsiMethodCallExpression methodCall = doExtract(); + + LogicalPosition pos1 = new LogicalPosition(line, col); + myEditor.getCaretModel().moveToLogicalPosition(pos1); + int offset = methodCall.getMethodExpression().getTextRange().getStartOffset(); + myEditor.getCaretModel().moveToOffset(offset); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + myEditor.getSelectionModel().removeSelection(); + myEditor.getSelectionModel().removeSelection(); + } + + private PsiMethodCallExpression doExtract() throws IncorrectOperationException { + renameInputVariables(); + + PsiMethod newMethod = generateEmptyMethod(myThrownExceptions, myStatic); + + LOG.assertTrue(myElements[0].isValid()); + + PsiCodeBlock body = newMethod.getBody(); + PsiMethodCallExpression methodCall = generateMethodCall(null); + + LOG.assertTrue(myElements[0].isValid()); + + if (myExpression == null) { + String outVariableName = myOutputVariable != null ? getNewVariableName(myOutputVariable) : null; + PsiReturnStatement returnStatement; + if (myOutputVariable != null) { + returnStatement = + (PsiReturnStatement)myElementFactory.createStatementFromText("return " + outVariableName + ";", null); + } + else { + returnStatement = (PsiReturnStatement)myElementFactory.createStatementFromText("return;", null); + } + + boolean hasNormalExit = false; + PsiElement lastElement = myElements[myElements.length - 1]; + if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement || + lastElement instanceof PsiContinueStatement)) { + hasNormalExit = true; + } + + PsiStatement exitStatementCopy = null; + // replace all exit-statements such as break's or continue's with appropriate return + for (int i = 0; i < myExitStatements.size(); i++) { + PsiStatement exitStatement = myExitStatements.get(i); + if (exitStatement instanceof PsiReturnStatement) { + continue; + } + else if (exitStatement instanceof PsiBreakStatement) { + PsiStatement statement = ((PsiBreakStatement)exitStatement).findExitedStatement(); + if (statement == null) continue; + int startOffset = myControlFlow.getStartOffset(statement); + int endOffset = myControlFlow.getEndOffset(statement); + if (myFlowStart <= startOffset && endOffset <= myFlowEnd) continue; + } + else if (exitStatement instanceof PsiContinueStatement) { + PsiStatement statement = ((PsiContinueStatement)exitStatement).findContinuedStatement(); + if (statement == null) continue; + int startOffset = myControlFlow.getStartOffset(statement); + int endOffset = myControlFlow.getEndOffset(statement); + if (myFlowStart <= startOffset && endOffset <= myFlowEnd) continue; + } + else { + LOG.assertTrue(false, exitStatement.toString()); + continue; + } + + int index = -1; + for (int j = 0; j < myElements.length; j++) { + if (exitStatement.equals(myElements[j])) { + index = j; + break; + } + } + if (exitStatementCopy == null) { + exitStatementCopy = (PsiStatement)exitStatement.copy(); + } + PsiElement result = exitStatement.replace(returnStatement); + if (index >= 0) { + myElements[index] = result; + } + } + + declareNecessaryVariablesInsideBody(myFlowStart, myFlowEnd, body); + + if (myNeedChangeContext) { + for (int i = 0; i < myElements.length; i++) { + ChangeContextUtil.encodeContextInfo(myElements[i], false); + } + } + + body.addRange(myElements[0], myElements[myElements.length - 1]); + if (!myHasReturnStatement && hasNormalExit && myOutputVariable != null) { + body.add(returnStatement); + } + + if (myOutputVariable != null) { + String name = myOutputVariable.getName(); + boolean toDeclare = isDeclaredInside(myOutputVariable); + if (!toDeclare) { + PsiExpressionStatement statement = (PsiExpressionStatement)myElementFactory.createStatementFromText( + name + "=x;", null); + statement = (PsiExpressionStatement)myStyleManager.reformat(statement); + statement = (PsiExpressionStatement)addToMethodCallLocation(statement); + PsiAssignmentExpression assignment = (PsiAssignmentExpression)statement.getExpression(); + methodCall = (PsiMethodCallExpression)assignment.getRExpression().replace(methodCall); + } + else { + PsiDeclarationStatement statement = myElementFactory.createVariableDeclarationStatement(name, + myOutputVariable.getType(), + methodCall); + statement = (PsiDeclarationStatement)addToMethodCallLocation(statement); + PsiVariable var = (PsiVariable)statement.getDeclaredElements()[0]; + methodCall = (PsiMethodCallExpression)var.getInitializer(); + var.getModifierList().replace(myOutputVariable.getModifierList()); + } + } + else if (myHasReturnStatementOutput) { + PsiStatement statement = myElementFactory.createStatementFromText("return x;", null); + statement = (PsiStatement)addToMethodCallLocation(statement); + methodCall = (PsiMethodCallExpression)((PsiReturnStatement)statement).getReturnValue().replace(methodCall); + } + else { + PsiStatement statement = myElementFactory.createStatementFromText("x();", null); + statement = (PsiStatement)addToMethodCallLocation(statement); + methodCall = + (PsiMethodCallExpression)((PsiExpressionStatement)statement).getExpression().replace(methodCall); + } + if (myHasReturnStatement && !myHasReturnStatementOutput && !hasNormalExit) { + PsiStatement statement = myElementFactory.createStatementFromText("return;", null); + addToMethodCallLocation(statement); + } + else if (exitStatementCopy != null) { + addToMethodCallLocation(exitStatementCopy); + } + + declareNecessaryVariablesAfterCall(myFlowEnd, myOutputVariable); + + deleteExtracted(); + } + else { + if (myHasExpressionOutput) { + PsiReturnStatement returnStatement = + (PsiReturnStatement)myElementFactory.createStatementFromText("return x;", null); + final PsiExpression returnValue; + returnValue = RefactoringUtil.convertInitializerToNormalExpression(myExpression, myForcedReturnType); + returnStatement.getReturnValue().replace(returnValue); + body.add(returnStatement); + } + else { + PsiExpressionStatement statement = (PsiExpressionStatement)myElementFactory.createStatementFromText("x;", null); + statement.getExpression().replace(myExpression); + body.add(statement); + } + methodCall = (PsiMethodCallExpression)myExpression.replace(methodCall); + } + + if (myAnchor instanceof PsiField) { + ((PsiField)myAnchor).normalizeDeclaration(); + } + newMethod = (PsiMethod)myTargetClass.addAfter(newMethod, myAnchor); + if (myNeedChangeContext) { + ChangeContextUtil.decodeContextInfo(newMethod, myTargetClass, + RefactoringUtil.createThisExpression(myManager, null)); + } + + return methodCall; + } + + public List getDuplicates() { + return myDuplicates; + } + + public void processMatch(Match match) throws IncorrectOperationException { + final PsiMethodCallExpression methodCallExpression = generateMethodCall(match.getInstanceExpression()); + final PsiExpression[] expressions = methodCallExpression.getArgumentList().getExpressions(); + + ArrayList datas = new ArrayList(); + for (int i = 0; i < myVariableDatas.length; i++) { + final ParameterTablePanel.VariableData variableData = myVariableDatas[i]; + if (variableData.passAsParameter) { + datas.add(variableData); + } + } + LOG.assertTrue(expressions.length == datas.size()); + for (int i = 0; i < datas.size(); i++) { + ParameterTablePanel.VariableData data = datas.get(i); + final PsiElement parameterValue = match.getParameterValue(data.variable); + expressions[i].replace(parameterValue); + } + match.replace(methodCallExpression, myOutputVariable); + } + + private void deleteExtracted() throws IncorrectOperationException { + if (myEnclosingBlockStatement == null) { + for (int i = 0; i < myElements.length; i++) { + myElements[i].delete(); + } + } + else { + myEnclosingBlockStatement.delete(); + } + } + + private PsiElement addToMethodCallLocation(PsiElement statement) throws IncorrectOperationException { + if (myEnclosingBlockStatement == null) { + return myElements[0].getParent().addBefore(statement, myElements[0]); + } + else { + return myEnclosingBlockStatement.getParent().addBefore(statement, myEnclosingBlockStatement); + } + } + + + private void calculateFlowStartAndEnd() { + int index = 0; + myFlowStart = -1; + while (index < myElements.length) { + myFlowStart = myControlFlow.getStartOffset(myElements[index]); + if (myFlowStart >= 0) break; + index++; + } + if (myFlowStart < 0) { + // no executable code + myFlowStart = 0; + myFlowEnd = 0; + } + else { + index = myElements.length - 1; + while (true) { + myFlowEnd = myControlFlow.getEndOffset(myElements[index]); + if (myFlowEnd >= 0) break; + index--; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("start offset:" + myFlowStart); + LOG.debug("end offset:" + myFlowEnd); + } + } + + private void renameInputVariables() throws IncorrectOperationException { + for (int i = 0; i < myVariableDatas.length; i++) { + ParameterTablePanel.VariableData data = myVariableDatas[i]; + PsiVariable variable = data.variable; + if (!data.name.equals(variable.getName())) { + for (int j = 0; j < myElements.length; j++) { + PsiElement element = myElements[j]; + RefactoringUtil.renameVariableReferences(variable, data.name, new LocalSearchScope(element)); + } + } + } + } + + public PsiClass getTargetClass() { + return myTargetClass; + } + + private PsiMethod generateEmptyMethod(PsiClassType[] exceptions, boolean isStatic) throws IncorrectOperationException { + + PsiMethod newMethod = myElementFactory.createMethod(myMethodName, myReturnType); + newMethod.getModifierList().setModifierProperty(myMethodVisibility, true); + newMethod.getModifierList().setModifierProperty(PsiModifier.STATIC, isStatic); + if (myTypeParameterList != null) { + newMethod.getTypeParameterList().replace(myTypeParameterList); + } + PsiCodeBlock body = newMethod.getBody(); + + PsiParameterList list = newMethod.getParameterList(); + for (int i = 0; i < myVariableDatas.length; i++) { + ParameterTablePanel.VariableData data = myVariableDatas[i]; + boolean isFinal = data.variable.hasModifierProperty(PsiModifier.FINAL); + if (data.passAsParameter) { + PsiParameter parm = myElementFactory.createParameter(data.name, data.variable.getType()); + if (isFinal) { + parm.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + list.add(parm); + } + else { + StringBuffer buffer = new StringBuffer(); + if (isFinal) { + buffer.append("final "); + } + buffer.append("int "); + buffer.append(data.name); + buffer.append("=x;"); + String text = buffer.toString(); + + PsiDeclarationStatement declaration = (PsiDeclarationStatement)myElementFactory.createStatementFromText(text, + null); + declaration = (PsiDeclarationStatement)myStyleManager.reformat(declaration); + ((PsiVariable)declaration.getDeclaredElements()[0]).getTypeElement().replace(data.variable.getTypeElement()); + declaration = (PsiDeclarationStatement)body.add(declaration); + + PsiExpression initializer = ((PsiVariable)declaration.getDeclaredElements()[0]).getInitializer(); + TextRange range = initializer.getTextRange(); + BlockSupport blockSupport = myProject.getComponent(BlockSupport.class); + blockSupport.reparseRange(body.getContainingFile(), range.getStartOffset(), range.getEndOffset(), "..."); + } + } + + PsiReferenceList throwsList = newMethod.getThrowsList(); + for (int i = 0; i < exceptions.length; i++) { + PsiClassType exception = exceptions[i]; + throwsList.add(myManager.getElementFactory().createReferenceElementByType(exception)); + } + + return (PsiMethod)myStyleManager.reformat(newMethod); + } + + private PsiMethodCallExpression generateMethodCall(PsiExpression instanceQualifier) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + + final boolean skipInstanceQualifier = instanceQualifier == null || instanceQualifier instanceof PsiThisExpression; + if (skipInstanceQualifier) { + if (myNeedChangeContext) { + boolean needsThisQualifier = false; + PsiElement parent = myCodeFragementMember; + while (!myTargetClass.equals(parent)) { + if (parent instanceof PsiMethod) { + String methodName = ((PsiMethod)parent).getName(); + if (methodName.equals(myMethodName)) { + needsThisQualifier = true; + break; + } + } + parent = parent.getParent(); + } + if (needsThisQualifier) { + buffer.append(myTargetClass.getName()); + buffer.append(".this."); + } + } + } + else { + buffer.append("qqq."); + } + + buffer.append(myMethodName); + buffer.append("("); + int count = 0; + for (int i = 0; i < myVariableDatas.length; i++) { + ParameterTablePanel.VariableData data = myVariableDatas[i]; + if (data.passAsParameter) { + if (count > 0) { + buffer.append(","); + } + buffer.append(data.variable.getName()); + count++; + } + } + buffer.append(")"); + String text = buffer.toString(); + + PsiMethodCallExpression expr = (PsiMethodCallExpression)myElementFactory.createExpressionFromText(text, null); + expr = (PsiMethodCallExpression)myStyleManager.reformat(expr); + if (!skipInstanceQualifier) { + expr.getMethodExpression().getQualifierExpression().replace(instanceQualifier); + } + return expr; + } + + private void declareNecessaryVariablesInsideBody(int start, int end, PsiCodeBlock body) throws IncorrectOperationException { + PsiVariable[] usedVariables = ControlFlowUtil.getUsedVariables(myControlFlow, start, end); + for (int i = 0; i < usedVariables.length; i++) { + PsiVariable variable = usedVariables[i]; + boolean toDeclare = !isDeclaredInside(variable) && !contains(myInputVariables, variable); + if (toDeclare) { + String name = variable.getName(); + PsiDeclarationStatement statement = myElementFactory.createVariableDeclarationStatement(name, + variable.getType(), + null); + body.add(statement); + } + } + } + + private void declareNecessaryVariablesAfterCall(int end, PsiVariable outputVariable) throws IncorrectOperationException { + PsiVariable[] usedVariables = ControlFlowUtil.getUsedVariables(myControlFlow, end, myControlFlow.getSize()); + for (int i = 0; i < usedVariables.length; i++) { + PsiVariable variable = usedVariables[i]; + boolean toDeclare = isDeclaredInside(variable) && !variable.equals(outputVariable); + if (toDeclare) { + String name = variable.getName(); + PsiDeclarationStatement statement = myElementFactory.createVariableDeclarationStatement(name, + variable.getType(), + null); + addToMethodCallLocation(statement); + } + } + } + + private boolean isDeclaredInside(PsiVariable variable) { + int startOffset = myElements[0].getTextRange().getStartOffset(); + int endOffset = myElements[myElements.length - 1].getTextRange().getEndOffset(); + int offset = variable.getNameIdentifier().getTextRange().getStartOffset(); + return startOffset <= offset && offset <= endOffset; + } + + private String getNewVariableName(PsiVariable variable) { + for (int i = 0; i < myVariableDatas.length; i++) { + ParameterTablePanel.VariableData data = myVariableDatas[i]; + if (data.variable.equals(variable)) { + return data.name; + } + } + return variable.getName(); + } + + private static boolean contains(Object[] array, Object object) { + for (int i = 0; i < array.length; i++) { + if (Comparing.equal(array[i], object)) return true; + } + return false; + } + + private void chooseTargetClass() { + myNeedChangeContext = false; + myTargetClass = (PsiClass)myCodeFragementMember.getParent(); + if (myTargetClass instanceof PsiAnonymousClass) { + PsiElement target = myTargetClass.getParent(); + PsiElement targetMember = myTargetClass; + while (true) { + if (target instanceof PsiFile) break; + if (target instanceof PsiClass && !(target instanceof PsiAnonymousClass)) break; + targetMember = target; + target = target.getParent(); + } + if (target instanceof PsiClass) { + PsiClass newTargetClass = (PsiClass)target; + List array = new ArrayList(); + boolean success = true; + for (int i = 0; i < myElements.length; i++) { + if (!ControlFlowUtil.collectOuterLocals(array, myElements[i], myCodeFragementMember, targetMember)) { + success = false; + break; + } + } + if (success) { + myTargetClass = newTargetClass; + PsiVariable[] newInputVariables = new PsiVariable[myInputVariables.length + array.size()]; + System.arraycopy(myInputVariables, 0, newInputVariables, 0, myInputVariables.length); + for (int i = 0; i < array.size(); i++) { + newInputVariables[myInputVariables.length + i] = array.get(i); + } + myInputVariables = newInputVariables; + myNeedChangeContext = true; + } + } + } + } + + private void chooseAnchor() { + myAnchor = myCodeFragementMember; + while (!myAnchor.getParent().equals(myTargetClass)) { + myAnchor = myAnchor.getParent(); + } + } + + private void showMultipleExitPointsMessage() { + if (myShowErrorDialogs) { + HighlightManager highlightManager = HighlightManager.getInstance(myProject); + PsiStatement[] exitStatementsArray = myExitStatements.toArray(new PsiStatement[myExitStatements.size()]); + EditorColorsManager manager = EditorColorsManager.getInstance(); + TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + highlightManager.addOccurrenceHighlights(myEditor, exitStatementsArray, attributes, true, null); + String message = + "Cannot perform the refactoring.\n" + + "There are multiple exit points in the selected code fragment."; + RefactoringMessageUtil.showErrorMessage(myRefactoringName, message, myHelpId, myProject); + WindowManager.getInstance().getStatusBar(myProject).setInfo("Press Escape to remove the highlighting"); + } + } + + private void showMultipleOutputMessage(PsiType expressionType) { + if (myShowErrorDialogs) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Cannot perform the refactoring.\n"); + buffer.append("There are multiple output values for the selected code fragment:\n"); + if (myHasExpressionOutput) { + buffer.append(" expression result : "); + buffer.append(PsiFormatUtil.formatType(expressionType, 0, PsiSubstitutor.EMPTY)); + buffer.append(",\n"); + } + for (int i = 0; i < myOutputVariables.length; i++) { + PsiVariable var = myOutputVariables[i]; + buffer.append(" "); + buffer.append(var.getName()); + buffer.append(" : "); + buffer.append(PsiFormatUtil.formatType(var.getType(), 0, PsiSubstitutor.EMPTY)); + if (i < myOutputVariables.length - 1) { + buffer.append(",\n"); + } + else { + buffer.append("."); + } + } + RefactoringMessageUtil.showErrorMessage(myRefactoringName, buffer.toString(), myHelpId, myProject); + } + } + + public boolean hasDuplicates() { + final List duplicates = getDuplicates(); + final boolean hasDuplicates = duplicates != null && !duplicates.isEmpty(); + return hasDuplicates; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/PrepareFailedException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/PrepareFailedException.java new file mode 100644 index 00000000000..11cbdfd0c19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractMethod/PrepareFailedException.java @@ -0,0 +1,27 @@ +package com.intellij.refactoring.extractMethod; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +/** + * @author dsl + */ +public class PrepareFailedException extends Exception { + private final PsiFile myContainingFile; + private final TextRange myTextRange; + + PrepareFailedException(String message, PsiElement errorElement) { + super(message); + myContainingFile = errorElement.getContainingFile(); + myTextRange = errorElement.getTextRange(); + } + + PsiFile getFile() { + return myContainingFile; + } + + TextRange getTextRange() { + return myTextRange; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/BindToOldUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/BindToOldUsageInfo.java new file mode 100644 index 00000000000..08067491c2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/BindToOldUsageInfo.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.refactoring.util.MoveRenameUsageInfo; + +/** + * @author dsl + */ +public class BindToOldUsageInfo extends MoveRenameUsageInfo { + public BindToOldUsageInfo(PsiElement element, PsiReference reference, PsiClass referencedElement) { + super(element, reference, referencedElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java new file mode 100644 index 00000000000..ae6a230cdbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java @@ -0,0 +1,69 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.refactoring.ui.BaseRefactoringDialog; + +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author dsl + */ +public abstract class ExtractSuperBaseDialog extends BaseRefactoringDialog { + protected JRadioButton myRbExtractSuperclass; + private JRadioButton myRbExtractSubclass; + + public ExtractSuperBaseDialog(Project project, boolean canBeParent) { + super(project, canBeParent); + } + + protected JComponent createActionComponent() { + Box box = Box.createHorizontalBox(); + final String s = StringUtil.decapitalize(getEntityName()); + myRbExtractSuperclass = new JRadioButton("Extract " + s); + myRbExtractSubclass = new JRadioButton("Rename original class and use " + s + " where possible"); + box.add(myRbExtractSuperclass); + box.add(myRbExtractSubclass); + box.add(Box.createHorizontalGlue()); + final ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbExtractSuperclass); + buttonGroup.add(myRbExtractSubclass); + myRbExtractSuperclass.setSelected(true); + myRbExtractSuperclass.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateDialogForExtractSuperclass(); + } + }); + + myRbExtractSubclass.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateDialogForExtractSubclass(); + } + }); + return box; + } + + private void updateDialogForExtractSubclass() { + getClassNameLabel().setText("Rename original class to:"); + getClassNameLabel().setDisplayedMnemonic('R'); + getPreviewAction().setEnabled (true); + } + + protected abstract JLabel getClassNameLabel(); + + protected abstract JLabel getPackageNameLabel(); + + protected void updateDialogForExtractSuperclass() { + getClassNameLabel().setText(StringUtil.capitalize(getEntityName()) + " name:"); + getClassNameLabel().setDisplayedMnemonic('S'); + getPreviewAction().setEnabled (false); + } + + protected abstract String getEntityName(); + + public boolean isExtractSuperclass() { + return myRbExtractSuperclass.isSelected(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java new file mode 100644 index 00000000000..5a410c55aed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseProcessor.java @@ -0,0 +1,144 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessorBase; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; + +/** + * @author dsl + */ +public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessorBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.ExtractSuperClassProcessor"); + protected PsiDirectory myTargetDirectory; + protected final String myNewClassName; + protected PsiClass myClass; + protected MemberInfo[] myMemberInfos; + protected final JavaDocPolicy myJavaDocPolicy; + + + public ExtractSuperBaseProcessor(Project project, + boolean replaceInstanceOf, + PsiDirectory targetDirectory, + String newClassName, + PsiClass aClass, MemberInfo[] memberInfos, JavaDocPolicy javaDocPolicy) { + super(project, replaceInstanceOf); + myTargetDirectory = targetDirectory; + myNewClassName = newClassName; + myClass = aClass; + myMemberInfos = memberInfos; + myJavaDocPolicy = javaDocPolicy; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new ExtractSuperClassViewDescriptor(usages, myTargetDirectory, myClass, myMemberInfos, refreshCommand); + } + + protected boolean doesAnyExtractedInterfaceExtends(PsiClass aClass) { + for (int i = 0; i < myMemberInfos.length; i++) { + final MemberInfo memberInfo = myMemberInfos[i]; + final PsiElement member = memberInfo.getMember(); + if (member instanceof PsiClass && memberInfo.getOverrides() != null) { + if (InheritanceUtil.isInheritorOrSelf((PsiClass) member, aClass, true)) { + return true; + } + } + } + return false; + } + + protected boolean doMemberInfosContain(PsiMethod method) { + for (int i = 0; i < myMemberInfos.length; i++) { + final MemberInfo info = myMemberInfos[i]; + if (info.getMember() instanceof PsiMethod) { + if (MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod) info.getMember())) return true; + } + else if (info.getMember() instanceof PsiClass && info.getOverrides() != null) { + final PsiMethod methodBySignature = ((PsiClass)info.getMember()).findMethodBySignature(method, true); + if (methodBySignature != null) { + return true; + } + } + } + return false; + } + + protected boolean doMemberInfosContain(final PsiField field) { + for (int i = 0; i < myMemberInfos.length; i++) { + final MemberInfo info = myMemberInfos[i]; + if (myManager.areElementsEquivalent(field, info.getMember())) return true; + } + return false; + } + + protected UsageInfo[] findUsages() { + PsiReference[] refs = mySearchHelper.findReferences(myClass, GlobalSearchScope.projectScope(myProject), false); + final ArrayList result = new ArrayList(); + detectTurnToSuperRefs(refs, result); + final PsiPackage originalPackage = myClass.getContainingFile().getContainingDirectory().getPackage(); + if (Comparing.equal(myTargetDirectory.getPackage(), originalPackage)) { + result.clear(); + } + for (int i = 0; i < refs.length; i++) { + final PsiReference ref = refs[i]; + final PsiElement element = ref.getElement(); + if (!canTurnToSuper(element)) { + result.add(new BindToOldUsageInfo(element, ref, myClass)); + } + } + UsageInfo[] usageInfos = (UsageInfo[]) result.toArray(new UsageInfo[result.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + final String superClassName = myClass.getName(); + final String oldQualifiedName = myClass.getQualifiedName(); + myClass.setName(myNewClassName); + PsiClass superClass = extractSuper(superClassName); + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + if (usage instanceof BindToOldUsageInfo) { + final PsiReference reference = ((BindToOldUsageInfo)usage).reference; + if (reference.getElement().isValid()) { + reference.bindToElement(myClass); + } + } + } + if (!Comparing.equal(oldQualifiedName, superClass.getQualifiedName())) { + processTurnToSuperRefs(usages, superClass); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + protected abstract PsiClass extractSuper(String superClassName) throws IncorrectOperationException; + + protected void refreshElements(PsiElement[] elements) { + myClass = (PsiClass)elements[0]; + myTargetDirectory = (PsiDirectory)elements[1]; + for (int i = 0; i < myMemberInfos.length; i++) { + final MemberInfo info = myMemberInfos[i]; + info.updateMember((PsiMember)elements[i + 2]); + } + } + + protected String getCommandName() { + return "Extract Subclass"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassProcessor.java new file mode 100644 index 00000000000..2ab8799afa2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassProcessor.java @@ -0,0 +1,55 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class ExtractSuperClassProcessor extends ExtractSuperBaseProcessor { + + public ExtractSuperClassProcessor(Project project, + PsiDirectory targetDirectory, String newClassName, PsiClass aClass, MemberInfo[] memberInfos, boolean replaceInstanceOf, + JavaDocPolicy javaDocPolicy) { + super(project, replaceInstanceOf, targetDirectory, newClassName, aClass, memberInfos, javaDocPolicy); + } + + + protected PsiClass extractSuper(final String superClassName) throws IncorrectOperationException { + final PsiClass superClass = ExtractSuperClassUtil.extractSuperClass(myProject, myTargetDirectory, superClassName, myClass, myMemberInfos, myJavaDocPolicy); + return superClass; + } + + protected boolean isSuperInheritor(PsiClass aClass) { + if (!aClass.isInterface()) { + return myClass.isInheritor(aClass, true); + } + else { + return doesAnyExtractedInterfaceExtends(aClass); + } + } + + protected boolean isInSuper(PsiElement member) { + if (member instanceof PsiField) { + final PsiClass containingClass = ((PsiField)member).getContainingClass(); + if (myClass.isInheritor(containingClass, true)) return true; + final PsiField field = ((PsiField)member); + return doMemberInfosContain(field); + } + else if (member instanceof PsiMethod) { + PsiMethod method = (PsiMethod) member; + final PsiClass currentSuperClass = myClass.getSuperClass(); + if (currentSuperClass != null) { + final PsiMethod methodBySignature = currentSuperClass.findMethodBySignature(method, true); + if (methodBySignature != null) return true; + } + return doMemberInfosContain(method); + } + return false; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java new file mode 100644 index 00000000000..3c8ef871f1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java @@ -0,0 +1,141 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.codeInsight.generation.OverrideImplementUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.MethodSignature; +import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.util.IncorrectOperationException; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author dsl + */ +public class ExtractSuperClassUtil { + public static PsiClass extractSuperClass(final Project project, + final PsiDirectory targetDirectory, + final String superclassName, + final PsiClass subclass, + final MemberInfo[] selectedMemberInfos, + final JavaDocPolicy javaDocPolicy) + throws IncorrectOperationException { + PsiClass superclass; + PsiElementFactory factory = PsiManager.getInstance(project).getElementFactory(); + superclass = targetDirectory.createClass(superclassName); + copyPsiReferenceList(subclass.getExtendsList(), superclass.getExtendsList()); + + // create constructors if neccesary + PsiMethod[] constructors = getCalledBaseConstructors(subclass); + if (constructors.length > 0) { + createConstructorsByPattern(project, superclass, constructors); + } + + // clear original class' "extends" list + clearPsiReferenceList(subclass.getExtendsList()); + + // make original class extend extracted superclass + PsiJavaCodeReferenceElement ref = factory.createClassReferenceElement(superclass); + subclass.getExtendsList().add(ref); + + PullUpHelper pullUpHelper = new PullUpHelper(subclass, superclass, selectedMemberInfos, + javaDocPolicy + ); + + pullUpHelper.moveMembersToBase(); + pullUpHelper.moveFieldInitializations(); + + MethodSignature[] toImplement = OverrideImplementUtil.getMethodSignaturesToImplement(superclass); + if (toImplement.length > 0) { + superclass.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true); + } + return superclass; + } + + private static void createConstructorsByPattern(Project project, final PsiClass superclass, PsiMethod[] patternConstructors) throws IncorrectOperationException { + PsiElementFactory factory = PsiManager.getInstance(project).getElementFactory(); + CodeStyleManager styleManager = CodeStyleManager.getInstance(project); + for (int idx = 0; idx < patternConstructors.length; idx++) { + PsiMethod baseConstructor = patternConstructors[idx]; + /*if (baseConstructor instanceof PsiCompiledElement) { // to get some parameter names + PsiClass dummyClass = factory.createClass("Dummy"); + baseConstructor = (PsiMethod) dummyClass.add(baseConstructor); + }*/ + PsiMethod constructor = (PsiMethod) superclass.add(factory.createConstructor()); + PsiParameterList paramList = constructor.getParameterList(); + PsiParameter[] baseParams = baseConstructor.getParameterList().getParameters(); + StringBuffer superCallText = new StringBuffer("super("); + for (int i = 0; i < baseParams.length; i++) { + PsiParameter baseParam = baseParams[i]; + paramList.add(baseParam); + if (i > 0) { + superCallText.append(","); + } + superCallText.append(baseParam.getName()); + } + superCallText.append(");"); + PsiStatement statement = factory.createStatementFromText(superCallText.toString(), null); + statement = (PsiStatement) styleManager.reformat(statement); + constructor.getBody().add(statement); + PsiReferenceList baseThrowsList = baseConstructor.getThrowsList(); + if (baseThrowsList != null) { + final PsiJavaCodeReferenceElement[] thrown = baseThrowsList.getReferenceElements(); + for (int i = 0; i < thrown.length; i++) { + PsiJavaCodeReferenceElement psiReferenceElement = thrown[i]; + constructor.getThrowsList().add(psiReferenceElement); + } + } + } + } + + private static PsiMethod[] getCalledBaseConstructors(final PsiClass subclass) { + Set baseConstructors = new HashSet(); + PsiMethod[] constructors = subclass.getConstructors(); + for (int idx = 0; idx < constructors.length; idx++) { + PsiMethod constructor = constructors[idx]; + PsiCodeBlock body = constructor.getBody(); + if (body == null) continue; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + PsiExpression expression = ((PsiExpressionStatement) first).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + PsiReferenceExpression calledMethod = ((PsiMethodCallExpression) expression).getMethodExpression(); + String text = calledMethod.getText(); + if ("super".equals(text)) { + PsiMethod baseConstructor = (PsiMethod) calledMethod.resolve(); + if (baseConstructor != null) { + baseConstructors.add(baseConstructor); + } + } + } + } + } + } + return (PsiMethod[]) baseConstructors.toArray(new PsiMethod[baseConstructors.size()]); + } + + private static void clearPsiReferenceList(PsiReferenceList refList) throws IncorrectOperationException { + PsiJavaCodeReferenceElement[] refs = refList.getReferenceElements(); + if (refs != null) { + for (int idx = 0; idx < refs.length; idx++) { + refs[idx].delete(); + } + } + } + + private static void copyPsiReferenceList(PsiReferenceList sourceList, PsiReferenceList destinationList) throws IncorrectOperationException { + clearPsiReferenceList(destinationList); + PsiJavaCodeReferenceElement[] refs = sourceList.getReferenceElements(); + if (refs != null) { + for (int idx = 0; idx < refs.length; idx++) { + destinationList.add(refs[idx]); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassViewDescriptor.java new file mode 100644 index 00000000000..a6f927918d1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperClassViewDescriptor.java @@ -0,0 +1,46 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class ExtractSuperClassViewDescriptor extends UsageViewDescriptorAdapter { + final PsiElement[] myElements; + + public ExtractSuperClassViewDescriptor(UsageInfo[] usages, + PsiDirectory targetDirectory, + PsiClass subclass, + MemberInfo[] infos, + FindUsagesCommand refreshCommand) { + super(usages, refreshCommand); + myElements = new PsiElement[infos.length + 2]; + myElements[0] = subclass; + myElements[1] = targetDirectory; + for (int i = 0; i < infos.length; i++) { + final MemberInfo info = infos[i]; + myElements[i + 2] = info.getMember(); + } + } + + public PsiElement[] getElements() { + return myElements; + } + + public void refresh(PsiElement[] elements) { + System.arraycopy(elements, 0, myElements, 0, elements.length); + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return "Extract supreclass with members to directory"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java new file mode 100644 index 00000000000..55abf34c48c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java @@ -0,0 +1,249 @@ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.ide.util.PackageChooserDialog; +import com.intellij.ide.util.PackageUtil; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.memberPullUp.JavaDocPanel; +import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.*; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +class ExtractSuperclassDialog extends ExtractSuperBaseDialog { + private final InterfaceContainmentVerifier myContainmentVerifier = new InterfaceContainmentVerifier() { + public boolean checkedInterfacesContain(PsiMethod psiMethod) { + return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod); + }; + }; + private JLabel myClassNameLabel; + private JLabel myPackageLabel; + + public static interface Callback { + boolean checkConflicts(ExtractSuperclassDialog dialog); + } + + private final Project myProject; + private MemberInfo[] myMemberInfos; + private Callback myCallback; + private PsiDirectory myTargetDirectory; + private JTextField mySourceClassField; + private JTextField myClassNameField; + private final JTextField myTfPackageName; + private PsiClass mySourceClass; + private final FixedSizeButton myBtnPackageChooser; + + private JavaDocPanel myJavaDocPanel; + + + public ExtractSuperclassDialog(Project project, final PsiClass sourceClass, MemberInfo[] selectedMembers, String targetPackageName, Callback callback) { + super(project, true); + myProject = project; + myMemberInfos = selectedMembers; + myCallback = callback; + setTitle(ExtractSuperclassHandler.REFACTORING_NAME); + mySourceClass = sourceClass; + + myTfPackageName=new JTextField(targetPackageName); + myBtnPackageChooser=new FixedSizeButton(myTfPackageName); + + init(); + updateDialogForExtractSuperclass(); + mySourceClassField.setText(sourceClass.getQualifiedName()); + } + + public MemberInfo[] getSelectedMemberInfos() { + ArrayList list = new ArrayList(myMemberInfos.length); + for (int idx = 0; idx < myMemberInfos.length; idx++) { + MemberInfo info = myMemberInfos[idx]; + if (info.isChecked()) { + list.add(info); + } + } + return (MemberInfo[]) list.toArray(new MemberInfo[list.size()]); + } + + InterfaceContainmentVerifier getContainmentVerifier() { + return myContainmentVerifier; + } + + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + public String getSuperclassName() { + return myClassNameField.getText().trim(); + } + + public int getJavaDocPolicy() { + return myJavaDocPanel.getPolicy(); + } + + protected boolean getInitialPreviewResults() { + return false; + } + + protected void setInitialPreviewResults(boolean value) { + } + + protected JComponent createNorthPanel() { + Box box = Box.createVerticalBox(); + + mySourceClassField = new JTextField(); + mySourceClassField.setEditable(false); + JPanel _panel = new JPanel(new BorderLayout()); + _panel.add(new JLabel("Extract superclass from:"), BorderLayout.NORTH); + _panel.add(mySourceClassField, BorderLayout.CENTER); + box.add(_panel); + + box.add(Box.createVerticalStrut(10)); + + box.add(createActionComponent()); + + box.add(Box.createVerticalStrut(10)); + + myClassNameLabel = new JLabel(); + myClassNameField = new JTextField(); + myClassNameLabel.setLabelFor(myClassNameField); + _panel = new JPanel(new BorderLayout()); + _panel.add(myClassNameLabel, BorderLayout.NORTH); + _panel.add(myClassNameField, BorderLayout.CENTER); + box.add(_panel); + box.add(Box.createVerticalStrut(5)); + + myBtnPackageChooser.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PackageChooserDialog chooser = new PackageChooserDialog("Choose Destination Package", myProject); + chooser.selectPackage(myTfPackageName.getText()); + chooser.show(); + PsiPackage aPackage = chooser.getSelectedPackage(); + if (aPackage != null) { + myTfPackageName.setText(aPackage.getQualifiedName()); + } + } + }); + _panel = new JPanel(new BorderLayout()); + myPackageLabel = new JLabel("Package for new superclass:"); + myPackageLabel.setLabelFor(myTfPackageName); + myPackageLabel.setDisplayedMnemonic('P'); + _panel.add(myPackageLabel, BorderLayout.NORTH); + _panel.add(myTfPackageName, BorderLayout.CENTER); + _panel.add(myBtnPackageChooser, BorderLayout.EAST); + box.add(_panel); + box.add(Box.createVerticalStrut(10)); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(box, BorderLayout.CENTER); + return panel; + } + + protected JLabel getClassNameLabel() { + return myClassNameLabel; + } + + protected JLabel getPackageNameLabel() { + return myPackageLabel; + } + + protected String getEntityName() { + return "Superclass"; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + final MemberSelectionPanel memberSelectionPanel = + new MemberSelectionPanel("Members to Form Superclass", myMemberInfos, "Make abstract"); + panel.add(memberSelectionPanel, BorderLayout.CENTER); + final MemberInfoModel memberInfoModel = new UsesAndInterfacesDependencyMemberInfoModel(mySourceClass, null, false, + myContainmentVerifier) { + public Boolean isFixedAbstract(MemberInfo member) { + return Boolean.TRUE; + } + }; + memberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + memberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel); + memberSelectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel); + + myJavaDocPanel = new JavaDocPanel("JavaDoc for abstracts"); + myJavaDocPanel.setPolicy(RefactoringSettings.getInstance().EXTRACT_SUPERCLASS_JAVADOC); + panel.add(myJavaDocPanel, BorderLayout.EAST); + + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myClassNameField; + } + + protected void doAction() { + final String[] errorString = new String[]{null}; + final String superclassName = getSuperclassName(); + final String packageName = myTfPackageName.getText().trim(); + final PsiManager manager = PsiManager.getInstance(myProject); + if ("".equals(superclassName)) { + errorString[0] = "No superclass name specified"; + mySourceClassField.requestFocusInWindow(); + } + else if (!manager.getNameHelper().isIdentifier(superclassName)) { + errorString[0] = RefactoringMessageUtil.getIncorrectIdentifierMessage(superclassName); + mySourceClassField.requestFocusInWindow(); + } + else { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + try { + myTargetDirectory = PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, myTargetDirectory, true); + if (myTargetDirectory == null) { + errorString[0] = ""; // message already reported by PackageUtil + return; + } + errorString[0] = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, superclassName); + } + catch (IncorrectOperationException e) { + errorString[0] = e.getMessage(); + myTfPackageName.requestFocusInWindow(); + } + } + }, "Create directory", null); + } + if (errorString[0] != null) { + if (errorString[0].length() > 0) { + RefactoringMessageUtil.showErrorMessage(ExtractSuperclassHandler.REFACTORING_NAME, errorString[0], HelpID.EXTRACT_SUPERCLASS, myProject); + } + return; + } + + if (!myCallback.checkConflicts(this)) { + return; + } + RefactoringSettings.getInstance().EXTRACT_SUPERCLASS_JAVADOC = getJavaDocPolicy(); + if (!isExtractSuperclass()) { + final ExtractSuperClassProcessor processor = new ExtractSuperClassProcessor(myProject, + getTargetDirectory(), getSuperclassName(), + mySourceClass, getSelectedMemberInfos(), false, + new JavaDocPolicy(getJavaDocPolicy())); + invokeRefactoring(processor); + } else { + closeOKAction(); + } + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.EXTRACT_SUPERCLASS); + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java new file mode 100644 index 00000000000..d3c80ec2e6f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java @@ -0,0 +1,157 @@ +/** + * created at Oct 25, 2001 + * @author Jeka + */ +package com.intellij.refactoring.extractSuperclass; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.extractInterface.ExtractClassUtil; +import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +public class ExtractSuperclassHandler implements RefactoringActionHandler, ExtractSuperclassDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler"); + + public static final String REFACTORING_NAME = "Extract Superclass"; + + private PsiClass mySubclass; + private Project myProject; + + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + int offset = editor.getCaretModel().getOffset(); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the class to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_SUPERCLASS, project); + return; + } + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + + myProject = project; + mySubclass = (PsiClass) elements[0]; + + if (!mySubclass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, mySubclass); + return; + } + + if (mySubclass.isInterface()) { + String message = + "Cannot perform the refactoring.\n" + + "Superclass cannot be extracted from an interface."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_SUPERCLASS, project); + return; + } + + + final MemberInfo[] memberInfos = MemberInfo.extractClassMembers(mySubclass, new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + if (element instanceof PsiMethod) { + return !((PsiMethod) element).isConstructor(); + } else { + return true; + } + } + }); + final String targetPackageName = (mySubclass.getContainingFile() instanceof PsiJavaFile)? ((PsiJavaFile) mySubclass.getContainingFile()).getPackageName() : null; + + + final ExtractSuperclassDialog dialog = new ExtractSuperclassDialog( + project, mySubclass, memberInfos, targetPackageName, ExtractSuperclassHandler.this + ); + dialog.show(); + if (!dialog.isOK() || !dialog.isExtractSuperclass()) return; + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + doRefactoring(project, mySubclass, dialog); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, "Extract Superclass", null); + + } + + public boolean checkConflicts(ExtractSuperclassDialog dialog) { + final MemberInfo[] infos = dialog.getSelectedMemberInfos(); + final PsiDirectory targetDirectory = dialog.getTargetDirectory(); + final PsiPackage targetPackage; + if (targetDirectory != null) { + targetPackage = targetDirectory.getPackage(); + } else { + targetPackage = null; + } + String[] conflicts = PullUpConflictsUtil.checkConflicts(infos, mySubclass, null, targetPackage, targetDirectory, dialog.getContainmentVerifier()); + if (conflicts.length > 0) { + ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts, myProject); + conflictsDialog.show(); + return conflictsDialog.isOK(); + } + return true; + } + + // invoked inside Command and Atomic action + private void doRefactoring(final Project project, final PsiClass subclass, final ExtractSuperclassDialog dialog) { + final String superclassName = dialog.getSuperclassName(); + final PsiDirectory targetDirectory = dialog.getTargetDirectory(); + final MemberInfo[] selectedMemberInfos = dialog.getSelectedMemberInfos(); + final JavaDocPolicy javaDocPolicy = new JavaDocPolicy(dialog.getJavaDocPolicy()); + LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, + getCommandName(subclass, superclassName)); + try { + PsiClass superclass = null; + + try { + superclass = ExtractSuperClassUtil.extractSuperClass(project, targetDirectory, superclassName, subclass, selectedMemberInfos, javaDocPolicy); + } finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + + // ask whether to search references to subclass and turn them into refs to superclass if possible + if (superclass != null) { + ExtractClassUtil.askAndTurnRefsToSuper(project, subclass, superclass); + } + } catch (IncorrectOperationException e) { + LOG.error(e); + } + + } + + private String getCommandName(final PsiClass subclass, String newName) { + return "Extracting superclass " + newName + " from " + UsageViewUtil.getDescriptiveName(subclass); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java new file mode 100644 index 00000000000..8265d980168 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java @@ -0,0 +1,272 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.help.HelpManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiType; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.ui.ClassCellRenderer; +import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.ui.NameSuggestionsField; +import com.intellij.refactoring.util.classMembers.InterfaceMemberDependencyGraph; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoChange; +import com.intellij.refactoring.util.classMembers.MemberInfoModel; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; + +public class InheritanceToDelegationDialog extends RefactoringDialog { + private PsiClass[] mySuperClasses; + + public static interface Callback { + void run(InheritanceToDelegationDialog dialog); + } + + private PsiClass myClass; + private Callback myCallback; + private HashMap myBasesToMemberInfos; + + private NameSuggestionsField myFieldNameField; + private NameSuggestionsField myInnerClassNameField; + private JCheckBox myCbGenerateGetter; + private MemberSelectionPanel myMemberSelectionPanel; + private JComboBox myClassCombo; + private Project myProject; + + public InheritanceToDelegationDialog(Project project, PsiClass aClass, + PsiClass[] superClasses, HashMap basesToMemberInfos, Callback callback) { + super(project, true); + myProject = project; + myClass = aClass; + myCallback = callback; + mySuperClasses = superClasses; + myBasesToMemberInfos = basesToMemberInfos; + + setTitle(InheritanceToDelegationHandler.REFACTORING_NAME); + init(); + } + + public String getFieldName() { + return myFieldNameField.getName(); + } + + public String getInnerClassName() { + if(myInnerClassNameField != null) { + return myInnerClassNameField.getName(); + } + else { + return null; + } + } + + public boolean isGenerateGetter() { + return myCbGenerateGetter.isSelected(); + } + + public MemberInfo[] getSelectedMemberInfos() { + return myMemberSelectionPanel.getTable().getSelectedMemberInfos(); + } + + public PsiClass getSelectedTargetClass() { + return (PsiClass) myClassCombo.getSelectedItem(); + } + + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.INHERITANCE_TO_DELEGATION); + } + + protected void doAction() { + if(!isOKActionEnabled()) return; + RefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER = myCbGenerateGetter.isSelected(); + myCallback.run(this); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.WEST; + gbc.gridy = 0; + gbc.gridx = 0; + + + gbc.insets = new Insets(4, 8, 0, 8); + myClassCombo = new JComboBox(mySuperClasses); + myClassCombo.setRenderer(new ClassCellRenderer()); + gbc.gridwidth = 2; + final JLabel classComboLabel = new JLabel("Replace with delegation inheritance from:"); + panel.add(classComboLabel, gbc); + gbc.gridy++; + panel.add(myClassCombo, gbc); + classComboLabel.setLabelFor(myClassCombo); + classComboLabel.setDisplayedMnemonic('R'); + + myClassCombo.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if(e.getStateChange() == ItemEvent.SELECTED) { + updateTargetClass(); + } + } + }); + + gbc.gridy++; + gbc.gridwidth = 1; + gbc.insets = new Insets(4, 8, 4, 0); + final JLabel fieldNameLabel = new JLabel("Field name:"); + panel.add(fieldNameLabel, gbc); + + myFieldNameField = new NameSuggestionsField(myProject); + gbc.gridx++; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(4, 4, 4, 8); + gbc.weightx = 1.0; + panel.add(myFieldNameField.getComponent(), gbc); + fieldNameLabel.setDisplayedMnemonic('F'); + fieldNameLabel.setLabelFor(myFieldNameField.getComponent()); + +// if(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, mySuperClass)) { + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.insets = new Insets(4, 8, 4, 0); + gbc.weightx = 0.0; + final JLabel innerClassNameLabel = new JLabel("Inner class name:"); + panel.add(innerClassNameLabel, gbc); + + /*String[] suggestions = new String[mySuperClasses.length]; + for (int i = 0; i < suggestions.length; i++) { + suggestions[i] = "My" + mySuperClasses[i].getName(); + }*/ + myInnerClassNameField = new NameSuggestionsField(myProject); + gbc.gridx++; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(4, 4, 4, 8); + gbc.weightx = 1.0; + panel.add(myInnerClassNameField.getComponent(), gbc); + innerClassNameLabel.setDisplayedMnemonic('I'); + innerClassNameLabel.setLabelFor(myInnerClassNameField.getComponent()); +// } + + + return panel; + } + + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.WEST; + gbc.gridy = 0; + gbc.gridx = 0; + gbc.weightx = 1.0; + + gbc.weighty = 1.0; + gbc.gridwidth = 1; + gbc.insets = new Insets(4, 8, 4, 4); + + myMemberSelectionPanel = new MemberSelectionPanel("Delegate members", new MemberInfo[0], null); + panel.add(myMemberSelectionPanel, gbc); + MyMemberInfoModel memberInfoModel = new InheritanceToDelegationDialog.MyMemberInfoModel(); + myMemberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel); + myMemberSelectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel); + + + gbc.gridy++; + gbc.insets = new Insets(4, 8, 0, 8); + gbc.weighty = 0.0; + myCbGenerateGetter = new JCheckBox("Generate getter for delegated component"); + myCbGenerateGetter.setMnemonic(KeyEvent.VK_G); + myCbGenerateGetter.setFocusable(false); + panel.add(myCbGenerateGetter, gbc); + myCbGenerateGetter.setSelected(RefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER); + updateTargetClass(); + + return panel; + } + + private void updateTargetClass() { + final PsiClass targetClass = getSelectedTargetClass(); + PsiManager psiManager = myClass.getManager(); + PsiType superType = psiManager.getElementFactory().createType(targetClass); + SuggestedNameInfo suggestedNameInfo = + CodeStyleManager.getInstance(psiManager.getProject()).suggestVariableName(VariableKind.FIELD, null, null, superType); + myFieldNameField.setSuggestions(suggestedNameInfo.names); + myInnerClassNameField.getComponent().setEnabled(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, targetClass)); + myInnerClassNameField.setSuggestions(new String[]{"My" + targetClass.getName()}); + myMemberSelectionPanel.getTable().setMemberInfos((MemberInfo[]) myBasesToMemberInfos.get(targetClass)); + myMemberSelectionPanel.getTable().fireExternalDataChange(); + } + + private class MyMemberInfoModel implements MemberInfoModel { + final HashMap myGraphs; + public MyMemberInfoModel() { + myGraphs = new HashMap(); + for (int i = 0; i < mySuperClasses.length; i++) { + PsiClass superClass = mySuperClasses[i]; + myGraphs.put(superClass, new InterfaceMemberDependencyGraph(superClass)); + } + } + + public boolean isMemberEnabled(MemberInfo memberInfo) { + if(getGraph().getDependent().contains(memberInfo.getMember())) { + return false; + } + else { + return true; + } + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return true; + } + + public boolean isAbstractEnabled(MemberInfo member) { + return false; + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + return false; + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } + + public int checkForProblems(MemberInfo member) { + return OK; + } + + public String getTooltipText(MemberInfo member) { + return null; + } + + public void memberInfoChanged(MemberInfoChange event) { + final MemberInfo[] changedMembers = event.getChangedMembers(); + + for (int i = 0; i < changedMembers.length; i++) { + getGraph().memberChanged(changedMembers[i]); + } + } + + private InterfaceMemberDependencyGraph getGraph() { + return (InterfaceMemberDependencyGraph) myGraphs.get(getSelectedTargetClass()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java new file mode 100644 index 00000000000..edeec48bde1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java @@ -0,0 +1,155 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.08.2002 + * Time: 17:17:27 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoStorage; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; + +public class InheritanceToDelegationHandler implements RefactoringActionHandler, InheritanceToDelegationDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler"); + public static final String REFACTORING_NAME = "Replace Inheritance With Delegation"; + + private Project myProject; + private PsiClass myClass; + private static final MemberInfo.Filter MEMBER_INFO_FILTER = new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + if (element instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)element; + return !method.isConstructor() + && !method.hasModifierProperty(PsiModifier.STATIC) + && !method.hasModifierProperty(PsiModifier.PRIVATE); + } + else if (element instanceof PsiClass && ((PsiClass)element).isInterface()) { + return true; + } + return false; + } + }; + + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + int offset = editor.getCaretModel().getOffset(); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the class to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.INHERITANCE_TO_DELEGATION*/, project); + return; + } + + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + + myProject = project; + myClass = (PsiClass) elements[0]; + + if (myClass.isInterface()) { + String message = + "Cannot perform the refactoring.\n" + + myClass.getQualifiedName() + " is an interface."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.INHERITANCE_TO_DELEGATION*/, project); + return; + } + + if (!myClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, myClass); + return; + } + + final PsiClass[] bases = myClass.getSupers(); + if (bases.length == 0 || bases.length == 1 && "java.lang.Object".equals(bases[0].getQualifiedName())) { + String message = + "Cannot perform the refactoring.\n" + + "Class " + myClass.getQualifiedName() + " does not have base classes or interfaces."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.INHERITANCE_TO_DELEGATION*/, project); + return; + } + + final HashMap basesToMemberInfos = new HashMap(); + + for (int i = 0; i < bases.length; i++) { + PsiClass base = bases[i]; + basesToMemberInfos.put(base, createBaseClassMemberInfos(base)); + } + + + new InheritanceToDelegationDialog(project, myClass, + bases, basesToMemberInfos, this + ).show(); + } + + private MemberInfo[] createBaseClassMemberInfos(PsiClass baseClass) { + final PsiClass deepestBase = RefactoringHierarchyUtil.getDeepestNonObjectBase(baseClass); + LOG.assertTrue(deepestBase != null); + + final MemberInfoStorage memberInfoStorage = new MemberInfoStorage(baseClass, MEMBER_INFO_FILTER); + + ArrayList memberInfoList = new ArrayList(memberInfoStorage.getClassMemberInfos(deepestBase)); + MemberInfo[] memberInfos = memberInfoStorage.getMemberInfosList(deepestBase); + for (int i = 0; i < memberInfos.length; i++) { + final MemberInfo memberInfo = memberInfos[i]; + + memberInfoList.add(memberInfo); + } + + final MemberInfo[] targetClassMemberInfos = memberInfoList.toArray(new MemberInfo[memberInfoList.size()]); + return targetClassMemberInfos; + } + + public void run(final InheritanceToDelegationDialog dialog) { + final MemberInfo[] selectedMemberInfos = dialog.getSelectedMemberInfos(); + final ArrayList implementedInterfaces = new ArrayList(); + final ArrayList delegatedMethods = new ArrayList(); + + for (int i = 0; i < selectedMemberInfos.length; i++) { + MemberInfo memberInfo = selectedMemberInfos[i]; + final PsiElement member = memberInfo.getMember(); + if (member instanceof PsiClass && Boolean.FALSE.equals(memberInfo.getOverrides())) { + implementedInterfaces.add((PsiClass)member); + } else if (member instanceof PsiMethod) { + delegatedMethods.add((PsiMethod)member); + } + } + new InheritanceToDelegationProcessor(myProject, myClass, + dialog.getSelectedTargetClass(), dialog.getFieldName(), dialog.getInnerClassName(), + implementedInterfaces.toArray(new PsiClass[implementedInterfaces.size()]), + delegatedMethods.toArray(new PsiMethod[delegatedMethods.size()]), + dialog.isGenerateGetter(), dialog.isGenerateGetter(), + dialog.isPreviewUsages(), new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + ).run(null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java new file mode 100644 index 00000000000..522208f78e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java @@ -0,0 +1,1195 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.inheritanceToDelegation.usageInfo.*; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; +import com.intellij.refactoring.util.classRefs.ClassInstanceScanner; +import com.intellij.refactoring.util.classRefs.ClassReferenceScanner; +import com.intellij.refactoring.util.classRefs.ClassReferenceSearchingScanner; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.usages.UsageInfo2UsageAdapter; +import com.intellij.usages.UsageTarget; +import com.intellij.usages.UsageViewManager; +import com.intellij.usages.UsageViewPresentation; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +/** + * @author dsl + */ +public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationProcessor"); + private final PsiClass myClass; + private final String myInnerClassName; + private boolean myIsDelegateOtherMembers; + private final LinkedHashSet myDelegatedInterfaces; + private final LinkedHashSet myDelegatedMethods; + private final com.intellij.util.containers.HashMap myDelegatedMethodsVisibility; + private final LinkedHashSet myOverridenMethods; + + private boolean myPreviewUsages; + + private final PsiClass myBaseClass; + private final Set myBaseClassMembers; + private final String myFieldName; + private final String myGetterName; + private final boolean myGenerateGetter; + private Set myBaseClassBases; + private Set myClassImplementedInterfaces; + private PsiElementFactory myFactory; + private final PsiType myBaseClassType; + private final PsiManager myManager; + private final boolean myIsInnerClassNeeded; + private Set myClassInheritors; + private HashSet myAbstractDelegatedMethods; + + + public InheritanceToDelegationProcessor(Project project, + PsiClass aClass, + PsiClass targetBaseClass, String fieldName, String innerClassName, + PsiClass[] delegatedInterfaces, PsiMethod[] delegatedMethods, + boolean delegateOtherMembers, boolean generateGetter, + boolean previewUsages, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + + myClass = aClass; + myInnerClassName = innerClassName; + myIsDelegateOtherMembers = delegateOtherMembers; + myManager = myClass.getManager(); + myFactory = myManager.getElementFactory(); + myPreviewUsages = previewUsages; + + myBaseClass = targetBaseClass; + LOG.assertTrue( + myBaseClass != null // && !myBaseClass.isInterface() + && (myBaseClass.getQualifiedName() == null || !myBaseClass.getQualifiedName().equals("java.lang.Object")) + ); + myBaseClassMembers = getAllBaseClassMembers(); + myBaseClassBases = getAllBases(); + myBaseClassType = myFactory.createType(myBaseClass); + + myIsInnerClassNeeded = InheritanceToDelegationUtil.isInnerClassNeeded(myClass, myBaseClass); + + + myFieldName = fieldName; + final String propertyName = CodeStyleManager.getInstance(myProject).variableNameToPropertyName(myFieldName, VariableKind.FIELD); + myGetterName = PropertyUtil.suggestGetterName(propertyName, myBaseClassType); + myGenerateGetter = generateGetter; + + myDelegatedInterfaces = new LinkedHashSet(); + addAll(myDelegatedInterfaces, delegatedInterfaces); + myDelegatedMethods = new LinkedHashSet(); + addAll(myDelegatedMethods, delegatedMethods); + myDelegatedMethodsVisibility = new com.intellij.util.containers.HashMap(); + for (Iterator iterator = myDelegatedMethods.iterator(); iterator.hasNext();) { + PsiMethod method = (PsiMethod) iterator.next(); + PsiMethod overridingMethod = myClass.findMethodBySignature(method, false); + if (overridingMethod != null) { + myDelegatedMethodsVisibility.put(method, + VisibilityUtil.getVisibilityModifier(overridingMethod.getModifierList())); + } + } + + myOverridenMethods = getOverriddenMethods(); + } + + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages) || myPreviewUsages; + } + + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new InheritanceToDelegationViewDescriptor(myClass, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + ArrayList usages = new ArrayList(); + PsiSearchHelper searchHelper = myManager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + final PsiClass[] inheritors = searchHelper.findInheritors(myClass, projectScope, true); + myClassInheritors = new HashSet(); + myClassInheritors.add(myClass); + addAll(myClassInheritors, inheritors); + + { + ClassReferenceScanner scanner = new ClassReferenceSearchingScanner(myClass); + final MyClassInstanceReferenceVisitor instanceReferenceVisitor = new MyClassInstanceReferenceVisitor(myClass, usages); + scanner.processReferences(new ClassInstanceScanner(myClass, instanceReferenceVisitor)); + + MyClassMemberReferencesVisitor visitor = new MyClassMemberReferencesVisitor(usages, instanceReferenceVisitor); + myClass.accept(visitor); + + myClassImplementedInterfaces = instanceReferenceVisitor.getImplementedInterfaces(); + } + for (int i = 0; i < inheritors.length; i++) { + processClass(inheritors[i], usages); + } + + return (UsageInfo[]) usages.toArray(new UsageInfo[usages.size()]); + } + + private FieldAccessibility getFieldAccessibility(PsiElement element) { + for (Iterator iterator = myClassInheritors.iterator(); iterator.hasNext();) { + PsiClass aClass = (PsiClass) iterator.next(); + if (PsiTreeUtil.isAncestor(aClass, element, false)) { + return new FieldAccessibility(true, aClass); + } + } + return FieldAccessibility.INVISIBLE; + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + ArrayList oldUsages = new ArrayList(); + addAll(oldUsages, usages[0]); + final ObjectUpcastedUsageInfo[] objectUpcastedUsageInfos = objectUpcastedUsages(usages[0]); + if (myPrepareSuccessfulSwingThreadCallback != null) { + ArrayList conflicts = new ArrayList(); + if (objectUpcastedUsageInfos.length > 0) { + final String message = "Instances of " + ConflictsUtil.getDescription(myClass, true) + " upcasted to " + + ConflictsUtil.htmlEmphasize("java.lang.Object") + " were found. If you continue, they will be shown " + + "in a separate Find tab."; + + conflicts.add(message); + } + + analyzeConflicts(usages[0], conflicts); + if (!conflicts.isEmpty()) { + ConflictsDialog conflictsDialog = + new ConflictsDialog((String[]) conflicts.toArray(new String[conflicts.size()]), myProject); + conflictsDialog.show(); + if (!conflictsDialog.isOK()) return false; + } + + if (objectUpcastedUsageInfos.length > 0) { + showObjectUpcastedUsageView(objectUpcastedUsageInfos); + myPreviewUsages = true; + } + } + ArrayList filteredUsages = filterUsages(oldUsages); + usages[0] = (UsageInfo[]) filteredUsages.toArray(new UsageInfo[filteredUsages.size()]); + prepareSuccessful(); + return true; + } + + private void analyzeConflicts(UsageInfo[] usage, ArrayList conflicts) { + com.intellij.util.containers.HashMap reportedNonDelegatedUsages = new com.intellij.util.containers.HashMap(); + com.intellij.util.containers.HashMap reportedUpcasts = new com.intellij.util.containers.HashMap(); +// HashSet reportedObjectUpcasts = new HashSet(); + +// final String nameJavaLangObject = ConflictsUtil.htmlEmphasize("java.lang.Object"); + final String classDescription = ConflictsUtil.getDescription(myClass, false); + + for (int i = 0; i < usage.length; i++) { + if (usage[i] instanceof InheritanceToDelegationUsageInfo) { + InheritanceToDelegationUsageInfo usageInfo = (InheritanceToDelegationUsageInfo) usage[i]; + /*if (usageInfo instanceof ObjectUpcastedUsageInfo) { + PsiElement container = ConflictsUtil.getContainer(usageInfo.element); + if (!reportedObjectUpcasts.contains(container)) { + String message = "An instance of " + classDescription + " is upcasted to " + + nameJavaLangObject + " in " + ConflictsUtil.getDescription(container, true) + "."; + conflicts.add(message); + reportedObjectUpcasts.add(container); + } + } else*/ + if (!myIsDelegateOtherMembers && !usageInfo.getDelegateFieldAccessible().isAccessible()) { + if (usageInfo instanceof NonDelegatedMemberUsageInfo) { + final PsiElement nonDelegatedMember = ((NonDelegatedMemberUsageInfo) usageInfo).nonDelegatedMember; + HashSet reportedContainers = (HashSet) reportedNonDelegatedUsages.get(nonDelegatedMember); + if (reportedContainers == null) { + reportedContainers = new HashSet(); + reportedNonDelegatedUsages.put(nonDelegatedMember, reportedContainers); + } + final PsiElement container = ConflictsUtil.getContainer(usageInfo.getElement()); + if (!reportedContainers.contains(container)) { + String message = ConflictsUtil.getDescription(container, true) + " uses " + + ConflictsUtil.getDescription(nonDelegatedMember, true) + " of an instance of a " + + classDescription + "."; + conflicts.add(ConflictsUtil.capitalize(message)); + reportedContainers.add(container); + } + } else if (usageInfo instanceof UpcastedUsageInfo) { + final PsiClass upcastedTo = ((UpcastedUsageInfo) usageInfo).upcastedTo; + HashSet reportedContainers = (HashSet) reportedUpcasts.get(upcastedTo); + if (reportedContainers == null) { + reportedContainers = new HashSet(); + reportedUpcasts.put(upcastedTo, reportedContainers); + } + final PsiElement container = ConflictsUtil.getContainer(usageInfo.getElement()); + if (!reportedContainers.contains(container)) { + String message = ConflictsUtil.getDescription(container, true) + " upcasts an instance of " + + classDescription + " to " + ConflictsUtil.getDescription(upcastedTo, false) + "."; + conflicts.add(ConflictsUtil.capitalize(message)); + reportedContainers.add(container); + } + } + } + } else if (usage[i] instanceof NoLongerOverridingSubClassMethodUsageInfo) { + NoLongerOverridingSubClassMethodUsageInfo info = (NoLongerOverridingSubClassMethodUsageInfo) usage[i]; + String message = ConflictsUtil.getDescription(info.getSubClassMethod(), true) + " will no longer override " + + ConflictsUtil.getDescription(info.getOverridenMethod(), true); + conflicts.add(message); + } + } + } + + private ObjectUpcastedUsageInfo[] objectUpcastedUsages(UsageInfo[] usages) { + ArrayList result = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage instanceof ObjectUpcastedUsageInfo) { + result.add(((ObjectUpcastedUsageInfo) usage)); + } + } + return (ObjectUpcastedUsageInfo[]) result.toArray(new ObjectUpcastedUsageInfo[result.size()]); + } + + private ArrayList filterUsages(ArrayList usages) { + ArrayList result = new ArrayList(); + + for (int i = 0; i < usages.size(); i++) { + UsageInfo usageInfo = (UsageInfo) usages.get(i); + + if (!(usageInfo instanceof InheritanceToDelegationUsageInfo)) { + continue; + } + if (usageInfo instanceof ObjectUpcastedUsageInfo) { + continue; + } + + if (!myIsDelegateOtherMembers) { + final FieldAccessibility delegateFieldAccessible = ((InheritanceToDelegationUsageInfo) usageInfo).getDelegateFieldAccessible(); + if (!delegateFieldAccessible.isAccessible()) continue; + } + + result.add(usageInfo); + } + return result; + } + + private void processClass(PsiClass inheritor, ArrayList usages) { + ClassReferenceScanner scanner = new ClassReferenceSearchingScanner(inheritor); + final MyClassInstanceReferenceVisitor instanceVisitor = new MyClassInstanceReferenceVisitor(inheritor, usages); + scanner.processReferences( + new ClassInstanceScanner(inheritor, + instanceVisitor) + ); + MyClassInheritorMemberReferencesVisitor classMemberVisitor = new MyClassInheritorMemberReferencesVisitor(inheritor, usages, instanceVisitor); + inheritor.accept(classMemberVisitor); + + PsiMethod[] methods = inheritor.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + + if (method.isConstructor() || method.hasModifierProperty(PsiModifier.PRIVATE)) return; + final PsiMethod baseMethod = myBaseClass.findMethodBySignature(method, true); + if (baseMethod != null) { + final PsiMethod classMethod = myClass.findMethodBySignature(method, false); + if (!baseMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + usages.add(new NoLongerOverridingSubClassMethodUsageInfo(method, baseMethod)); + } else { + if (classMethod != null && !classMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + usages.add(new NoLongerOverridingSubClassMethodUsageInfo(method, baseMethod)); + } + } + } + } + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + for (int i = 0; i < usages.length; i++) { + InheritanceToDelegationUsageInfo usage = (InheritanceToDelegationUsageInfo) usages[i]; + + + if (usage instanceof UnqualifiedNonDelegatedMemberUsageInfo) { + delegateUsageFromClass(usage.getElement(), ((NonDelegatedMemberUsageInfo) usage).nonDelegatedMember, + usage.getDelegateFieldAccessible()); + } else { + upcastToDelegation(usage.getElement(), usage.getDelegateFieldAccessible()); + } + } + + myAbstractDelegatedMethods = new HashSet(); + addInnerClass(); + addField(usages); + delegateMethods(); + addImplementingInterfaces(); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private void addInnerClass() throws IncorrectOperationException { + if (!myIsInnerClassNeeded) return; + + PsiClass innerClass = myFactory.createClass(myInnerClassName); + final PsiJavaCodeReferenceElement baseClassReferenceElement = myFactory.createClassReferenceElement(myBaseClass); + if (!myBaseClass.isInterface()) { + innerClass.getExtendsList().add(baseClassReferenceElement); + } else { + innerClass.getImplementsList().add(baseClassReferenceElement); + } + innerClass.getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + innerClass = (PsiClass) myClass.add(innerClass); + + List innerClassMethods = getInnerClassMethods(); + for (Iterator iterator = innerClassMethods.iterator(); iterator.hasNext();) { + InnerClassMethod innerClassMethod = (InnerClassMethod) iterator.next(); + innerClassMethod.createMethod(innerClass, myClass); + } + } + + private void delegateUsageFromClass(PsiElement element, PsiElement nonDelegatedMember, + FieldAccessibility fieldAccessibility) throws IncorrectOperationException { + if (element instanceof PsiReferenceExpression) { + PsiReferenceExpression referenceExpression = (PsiReferenceExpression) element; + if (referenceExpression.getQualifierExpression() != null) { + upcastToDelegation(referenceExpression.getQualifierExpression(), fieldAccessibility); + } else { + final String name = ((PsiNamedElement) nonDelegatedMember).getName(); + final String qualifier; + if (isStatic (nonDelegatedMember)) { + qualifier = myBaseClass.getName(); + } + else if (!fieldAccessibility.isAccessible() && myGenerateGetter) { + qualifier = myGetterName + "()"; + } + else { + qualifier = myFieldName; + } + + PsiExpression newExpr = myFactory.createExpressionFromText(qualifier + "." + name, element); + newExpr = (PsiExpression) CodeStyleManager.getInstance(myProject).reformat(newExpr); + element.replace(newExpr); + } + } + else if (element instanceof PsiJavaCodeReferenceElement) { + final String name = ((PsiNamedElement) nonDelegatedMember).getName(); + + PsiElement parent = element.getParent (); + if (!isStatic (nonDelegatedMember) && parent instanceof PsiNewExpression) { + final PsiNewExpression newExpr = (PsiNewExpression) parent; + if (newExpr.getQualifier() != null) { + upcastToDelegation(newExpr.getQualifier(), fieldAccessibility); + } else { + final String qualifier; + if (!fieldAccessibility.isAccessible() && myGenerateGetter) { + qualifier = myGetterName + "()"; + } + else { + qualifier = myFieldName; + } + final PsiExpression template = myFactory.createExpressionFromText(qualifier + ".new C()", parent); + final PsiElement qual = template.getFirstChild (); + final PsiElement dot = qual.getNextSibling(); + parent.addBefore(dot, parent.getFirstChild()); + parent.addBefore(qual, parent.getFirstChild()); + } + } + else { + final String qualifier = myBaseClass.getName(); + PsiJavaCodeReferenceElement newRef = myFactory.createFQClassNameReferenceElement(qualifier + "." + name, element.getResolveScope ()); + //newRef = (PsiJavaCodeReferenceElement) CodeStyleManager.getInstance(myProject).reformat(newRef); + element.replace(newRef); + } + } else { + LOG.assertTrue(false); + } + } + + private boolean isStatic(PsiElement member) { + if (member instanceof PsiModifierListOwner) { + final PsiModifierListOwner method = (PsiModifierListOwner) member; + return method.hasModifierProperty ("static"); + } + return false; + } + + private void upcastToDelegation(PsiElement element, FieldAccessibility fieldAccessibility) throws IncorrectOperationException { + final PsiExpression expression = (PsiExpression) element; + + final PsiExpression newExpr; + final PsiReferenceExpression ref; + final String delegateQualifier; + if (!(expression instanceof PsiThisExpression || expression instanceof PsiSuperExpression)) { + delegateQualifier = "a."; + } else { + PsiResolveHelper resolveHelper = myManager.getResolveHelper(); + final PsiVariable psiVariable = resolveHelper.resolveReferencedVariable(myFieldName, element); + if (psiVariable == null) { + delegateQualifier = ""; + } else { + delegateQualifier = "a."; + } + } + if (!fieldAccessibility.isAccessible() && myGenerateGetter) { + newExpr = myFactory.createExpressionFromText(delegateQualifier + myGetterName + "()", expression); + ref = (PsiReferenceExpression) ((PsiMethodCallExpression) newExpr).getMethodExpression().getQualifierExpression(); + } else { + newExpr = myFactory.createExpressionFromText(delegateQualifier + myFieldName, expression); + ref = (PsiReferenceExpression) ((PsiReferenceExpression) newExpr).getQualifierExpression(); + } +// LOG.debug("upcastToDelegation:" + element + ":newExpr = " + newExpr); +// LOG.debug("upcastToDelegation:" + element + ":ref = " + ref); + if (ref != null) { + ref.replace(expression); + } + expression.replace(newExpr); +// LOG.debug("upcastToDelegation:" + element + ":replaced = " + replaced); + } + + private void delegateMethods() throws IncorrectOperationException { + for (Iterator iterator = myDelegatedMethods.iterator(); iterator.hasNext();) { + PsiMethod method = (PsiMethod) iterator.next(); + + if (!myAbstractDelegatedMethods.contains(method)) { + PsiMethod methodToAdd = delegateMethod(myFieldName, method); + + String visibility = (String) myDelegatedMethodsVisibility.get(method); + if (visibility != null) { + methodToAdd.getModifierList().setModifierProperty(visibility, true); + } + + myClass.add(methodToAdd); + } + } + } + + private String getMethodHeaderText(PsiMethod method) { + StringBuffer buf = new StringBuffer(); + buf.append("public "); + PsiTypeElement typeElt = method.getReturnTypeElement(); + if (typeElt != null) { + buf.append(typeElt.getText()); + buf.append(' '); + } + buf.append(method.getName()); + buf.append('('); + PsiParameter[] params = method.getParameterList().getParameters(); + for (int i = 0; i < params.length; i++) { + PsiParameter param = params[i]; + if (i > 0) buf.append(','); + buf.append(param.getTypeElement().getText()); + buf.append(' '); + buf.append(param.getName()); + } + buf.append(')'); + buf.append(method.getThrowsList().getText()); + return buf.toString(); + } + + private PsiMethod delegateMethod(String delegationTarget, PsiMethod method) throws IncorrectOperationException { + PsiMethod methodToAdd = (PsiMethod) method.copy(); + + PsiCodeBlock oldBody = methodToAdd.getBody(); + StringBuffer buffer = new StringBuffer(); + if (oldBody == null) { + buffer.append(getMethodHeaderText(method)); + } + + appendDelegationBody(buffer, methodToAdd, method, delegationTarget); + + + if (oldBody != null) { + PsiCodeBlock newBody; + newBody = myFactory.createCodeBlockFromText(buffer.toString(), method); + oldBody.replace(newBody); + } else { + methodToAdd = myFactory.createMethodFromText(buffer.toString(), method); + } + + if (methodToAdd.getDocComment() != null) { + methodToAdd.getDocComment().delete(); // todo: maintain JavaDoc + } + methodToAdd.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false); + methodToAdd = (PsiMethod) CodeStyleManager.getInstance(myProject).reformat(methodToAdd); + return methodToAdd; + } + + private void appendDelegationBody(StringBuffer buffer, PsiMethod methodToAdd, PsiMethod originalMethod, String delegationTarget) { + buffer.append("{\n"); + + if (methodToAdd.getReturnType() != PsiType.VOID) { + buffer.append("return "); + } + + buffer.append(delegationTarget); + buffer.append("."); + buffer.append(methodToAdd.getName()); + buffer.append("("); + PsiParameter[] params = methodToAdd.getParameterList().getParameters(); + for (int i = 0; i < params.length; i++) { + PsiParameter param = params[i]; + if (i > 0) { + buffer.append(","); + } + buffer.append(param.getName()); + } + buffer.append(");\n}"); + } + + private void addImplementingInterfaces() throws IncorrectOperationException { + final PsiReferenceList implementsList = myClass.getImplementsList(); + for (Iterator iterator = myDelegatedInterfaces.iterator(); iterator.hasNext();) { + PsiClass delegatedInterface = (PsiClass) iterator.next(); + + if (!myClassImplementedInterfaces.contains(delegatedInterface)) { + implementsList.add(myFactory.createClassReferenceElement(delegatedInterface)); + } + } + + if (!myBaseClass.isInterface()) { + final PsiReferenceList extendsList = myClass.getExtendsList(); + extendsList.getReferenceElements()[0].delete(); + } else { + final PsiJavaCodeReferenceElement[] interfaceRefs = implementsList.getReferenceElements(); + for (int i = 0; i < interfaceRefs.length; i++) { + PsiJavaCodeReferenceElement interfaceRef = interfaceRefs[i]; + final PsiElement resolved = interfaceRef.resolve(); + if (myManager.areElementsEquivalent(myBaseClass, resolved)) { + interfaceRef.delete(); + break; + } + } + } + } + + private void addField(UsageInfo[] usages) throws IncorrectOperationException { + final String fieldVisibility = getFieldVisibility(usages); + + final boolean fieldInitializerNeeded = isFieldInitializerNeeded(); + + PsiField field = createField(fieldVisibility, fieldInitializerNeeded, defaultClassFieldType()); + + if (!myIsInnerClassNeeded) { + PsiType fieldType = myBaseClassType; + field.getTypeElement().replace(myFactory.createTypeElement(fieldType)); + if (fieldInitializerNeeded) { + final PsiJavaCodeReferenceElement classReferenceElement = myFactory.createClassReferenceElement(myBaseClass); + PsiNewExpression newExpression = (PsiNewExpression) field.getInitializer(); + newExpression.getClassReference().replace(classReferenceElement); + } + } + + field = (PsiField) CodeStyleManager.getInstance(myProject).reformat(field); + myClass.add(field); + if (!fieldInitializerNeeded) { + fixConstructors(); + } + + if (myGenerateGetter) { + final String getterVisibility = PsiModifier.PUBLIC; + StringBuffer getterBuffer = new StringBuffer(); + getterBuffer.append(getterVisibility); + getterBuffer.append(" Object "); + getterBuffer.append(myGetterName); + getterBuffer.append("() {\n return "); + getterBuffer.append(myFieldName); + getterBuffer.append(";\n}"); + PsiMethod getter = myFactory.createMethodFromText(getterBuffer.toString(), myClass); + getter.getReturnTypeElement().replace(myFactory.createTypeElement(myBaseClassType)); + getter = (PsiMethod) CodeStyleManager.getInstance(myProject).reformat(getter); + myClass.add(getter); + } + } + + private String getFieldVisibility(UsageInfo[] usages) { + if (myIsDelegateOtherMembers && !myGenerateGetter) { + return PsiModifier.PUBLIC; + } + + for (int i = 0; i < usages.length; i++) { + InheritanceToDelegationUsageInfo usage = (InheritanceToDelegationUsageInfo) usages[i]; + final FieldAccessibility delegateFieldAccessible = usage.getDelegateFieldAccessible(); + if (delegateFieldAccessible.isAccessible() && delegateFieldAccessible.getContainingClass() != myClass) { + return PsiModifier.PROTECTED; + } + } + return PsiModifier.PRIVATE; + } + + private String defaultClassFieldType() { + return (myIsInnerClassNeeded ? myInnerClassName : "Object"); + } + + private PsiField createField(final String fieldVisibility, final boolean fieldInitializerNeeded, String defaultTypeName) throws IncorrectOperationException { + StringBuffer buffer = new StringBuffer(); + buffer.append(fieldVisibility); + buffer.append(" final " + defaultTypeName + " "); + buffer.append(myFieldName); + if (fieldInitializerNeeded) { + buffer.append(" = new " + defaultTypeName + "()"); + } + buffer.append(";"); + PsiField field = myFactory.createFieldFromText(buffer.toString(), myClass); + return field; + } + + private void fixConstructors() throws IncorrectOperationException { + if (myBaseClass.isInterface()) return; + final PsiJavaCodeReferenceElement baseClassReference = myFactory.createClassReferenceElement(myBaseClass); + + PsiMethod[] constructors = myClass.getConstructors(); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + PsiCodeBlock body = constructor.getBody(); + final PsiStatement[] statements = body.getStatements(); + String fieldQualifier = ""; + PsiParameter[] constructorParams = constructor.getParameterList().getParameters(); + for (int j = 0; j < constructorParams.length; j++) { + PsiParameter constructorParam = constructorParams[j]; + if (myFieldName.equals(constructorParam.getName())) { + fieldQualifier = "this."; + break; + } + } + final String assignmentText = fieldQualifier + myFieldName + "= new " + defaultClassFieldType() + "()"; + if (statements.length < 1 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) { + PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) myFactory.createStatementFromText( + assignmentText, body + ); + if (!myIsInnerClassNeeded) { + ((PsiNewExpression) assignmentStatement.getExpression()).getClassReference().replace(baseClassReference); + } + + assignmentStatement = (PsiExpressionStatement) CodeStyleManager.getInstance(myProject).reformat(assignmentStatement); + if (statements.length > 0) { + if (!RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) { + body.addBefore(assignmentStatement, statements[0]); + } else { + body.addAfter(assignmentStatement, statements[0]); + } + } else { + body.add(assignmentStatement); + } + } else { + final PsiExpressionStatement callStatement = ((PsiExpressionStatement) statements[0]); + if (!RefactoringUtil.isSuperOrThisCall(callStatement, false, true)) { + final PsiMethodCallExpression superConstructorCall = + (PsiMethodCallExpression) callStatement.getExpression(); + PsiAssignmentExpression assignmentExpression = + (PsiAssignmentExpression) myFactory.createExpressionFromText( + assignmentText, superConstructorCall + ); + PsiNewExpression newExpression = + (PsiNewExpression) assignmentExpression.getRExpression(); + if (!myIsInnerClassNeeded) { + newExpression.getClassReference().replace(baseClassReference); + } + assignmentExpression = (PsiAssignmentExpression) CodeStyleManager.getInstance(myProject).reformat(assignmentExpression); + newExpression.getArgumentList().replace(superConstructorCall.getArgumentList()); + superConstructorCall.replace(assignmentExpression); + } + } + } + } + + private boolean isFieldInitializerNeeded() { + if (myBaseClass.isInterface()) return true; + PsiMethod[] constructors = myClass.getConstructors(); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + final PsiStatement[] statements = constructor.getBody().getStatements(); + if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) return false; + } + return true; + } + + private List getInnerClassMethods() { + ArrayList result = new ArrayList(); + + // find all neccessary constructors + if (!myBaseClass.isInterface()) { + PsiMethod[] constructors = myClass.getConstructors(); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + final PsiStatement[] statements = constructor.getBody().getStatements(); + if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) { + final PsiMethodCallExpression superConstructorCall = + (PsiMethodCallExpression) ((PsiExpressionStatement) statements[0]).getExpression(); + PsiElement superConstructor = superConstructorCall.getMethodExpression().resolve(); + if (superConstructor instanceof PsiMethod && ((PsiMethod) superConstructor).isConstructor()) { + result.add(new InnerClassConstructor((PsiMethod) superConstructor)); + } + } + } + } + + // find overriding/implementing method + { + class InnerClassOverridingMethod extends InnerClassMethod { + public InnerClassOverridingMethod(PsiMethod method) { + super(method); + } + + public void createMethod(PsiClass innerClass, PsiClass outerClass) + throws IncorrectOperationException { + OverridenMethodClassMemberReferencesVisitor visitor = new OverridenMethodClassMemberReferencesVisitor(); + myMethod.accept(visitor); + final List actions = visitor.getPsiActions(); + for (Iterator iterator = actions.iterator(); iterator.hasNext();) { + PsiAction action = (PsiAction) iterator.next(); + action.run(); + } + innerClass.add(myMethod); + myMethod.delete(); + // myMethod.replace(delegateMethod(myMethod)); + } + } + + for (Iterator iterator = myOverridenMethods.iterator(); iterator.hasNext();) { + PsiMethod method = (PsiMethod) iterator.next(); + result.add(new InnerClassOverridingMethod(method)); + } + } + + // fix abstract methods + { + class InnerClassAbstractMethod extends InnerClassMethod { + public InnerClassAbstractMethod(PsiMethod method) { + super(method); + LOG.assertTrue(method.hasModifierProperty(PsiModifier.ABSTRACT)); + } + + public void createMethod(PsiClass innerClass, PsiClass outerClass) + throws IncorrectOperationException { + PsiMethod method = delegateMethod(outerClass.getName() + ".this", myMethod); + final PsiClass containingClass = myMethod.getContainingClass(); + if (myBaseClass.isInterface() || containingClass.isInterface()) { + method.getModifierList().setModifierProperty(PsiModifier.PUBLIC, true); + } + innerClass.add(method); + PsiMethod outerMethod = outerClass.findMethodBySignature(myMethod, false); + if (outerMethod == null) { + final String visibility = checkOuterClassAbstractMethod(myMethod); + PsiMethod newOuterMethod = (PsiMethod) outerClass.add(myMethod); + newOuterMethod.getModifierList().setModifierProperty(visibility, true); + if (newOuterMethod.getDocComment() != null) { + newOuterMethod.getDocComment().delete(); + } + } + } + + } + PsiMethod[] methods = myBaseClass.getAllMethods(); + + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + PsiMethod classMethod = myClass.findMethodBySignature(method, true); + if (classMethod == null || classMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + result.add(new InnerClassAbstractMethod(method)); + } + } + } + } + + + return result; + } + + private void showObjectUpcastedUsageView(final ObjectUpcastedUsageInfo[] usages) { + UsageViewPresentation presentation = new UsageViewPresentation(); + presentation.setTargetsNodeText("Replacing inheritance with delegation"); + presentation.setCodeUsagesString("Instances casted to java.lang.Object"); + presentation.setUsagesString("Instances upcasted to Object"); + presentation.setTabText("Instances upcasted to Object"); + + UsageViewManager manager = myProject.getComponent(UsageViewManager.class); + manager.showUsages(new UsageTarget[]{new PsiElement2UsageTargetAdapter(myClass)}, + UsageInfo2UsageAdapter.convert(usages), + presentation); + + WindowManager.getInstance().getStatusBar(myProject).setInfo("Instances upcasted to java.lang.Object found"); + } + + /** + * + * @param methodSignature + * @return Visibility + */ + private String checkOuterClassAbstractMethod(PsiMethod methodSignature) { + String visibility = PsiModifier.PROTECTED; + for (Iterator iterator = myDelegatedMethods.iterator(); iterator.hasNext();) { + PsiMethod method = (PsiMethod) iterator.next(); + + if (MethodSignatureUtil.areSignaturesEqual(method, methodSignature)) { + visibility = VisibilityUtil.getHighestVisibility(visibility, + VisibilityUtil.getVisibilityModifier(method.getModifierList())); + myAbstractDelegatedMethods.add(method); + } + } + return visibility; + } + + private LinkedHashSet getOverriddenMethods() { + LinkedHashSet result = new LinkedHashSet(); + + PsiMethod[] methods = myClass.getMethods(); + + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + + if (method.isConstructor() || method.hasModifierProperty(PsiModifier.PRIVATE)) continue; + PsiMethod baseMethod = myBaseClass.findMethodBySignature(method, true); + if (baseMethod != null) { + PsiClass containingClass = baseMethod.getContainingClass(); + String qName = containingClass.getQualifiedName(); + if (qName == null || !"java.lang.Object".equals(qName)) { + result.add(method); + } + } + } + return result; + } + + + protected String getCommandName() { + return "Replacing inheritance with delegation in " + UsageViewUtil.getDescriptiveName(myClass); + } + + private Set getAllBaseClassMembers() { + HashSet result = new HashSet(); + addAll(result, myBaseClass.getAllFields()); + addAll(result, myBaseClass.getAllInnerClasses()); + addAll(result, myBaseClass.getAllMethods()); + + ArrayList javaLangObjectMembers = new ArrayList(); + + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement) iterator.next(); + String qName = null; + if (element instanceof PsiField) { + qName = ((PsiField) element).getContainingClass().getQualifiedName(); + } else if (element instanceof PsiMethod) { + qName = ((PsiMethod) element).getContainingClass().getQualifiedName(); + } + if (qName != null && qName.equals("java.lang.Object")) { + javaLangObjectMembers.add(element); + } + } + result.removeAll(javaLangObjectMembers); + return Collections.unmodifiableSet(result); + } + + private Set getAllBases() { + HashSet temp = new HashSet(); + RefactoringHierarchyUtil.getSuperClasses(myBaseClass, temp, true); + temp.add(myBaseClass); + return Collections.unmodifiableSet(temp); + } + + private static void addAll(Collection collection, Object[] objs) { + for (int i = 0; i < objs.length; i++) { + collection.add(objs[i]); + } + } + + private boolean isDelegated(PsiElement classMember) { + if(!(classMember instanceof PsiMethod)) return false; + final PsiMethod method = (PsiMethod) classMember; + for (Iterator iterator = myDelegatedMethods.iterator(); iterator.hasNext();) { + PsiMethod delegatedMethod = (PsiMethod) iterator.next(); + if (MethodSignatureUtil.areSignaturesEqual(method, delegatedMethod)) return true; + } + return false; + } + + private class MyClassInheritorMemberReferencesVisitor extends ClassMemberReferencesVisitor { + private final List myUsageInfoStorage; + private ClassInstanceScanner.ClassInstanceReferenceVisitor myInstanceVisitor; + + MyClassInheritorMemberReferencesVisitor(PsiClass aClass, List usageInfoStorage, + ClassInstanceScanner.ClassInstanceReferenceVisitor instanceScanner) { + super(aClass); + + myUsageInfoStorage = usageInfoStorage; + myInstanceVisitor = instanceScanner; + } + + public void visitTypeElement(PsiTypeElement type) { + super.visitTypeElement (type); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement element) { + super.visitReferenceElement (element); + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if ("super".equals(classMemberReference.getText()) && classMemberReference.getParent() instanceof PsiMethodCallExpression) { + return; + } + + if (classMember != null && myBaseClassMembers.contains(classMember) && !isDelegated(classMember)) { + final FieldAccessibility delegateFieldVisibility = new FieldAccessibility(true, getPsiClass()); + final InheritanceToDelegationUsageInfo usageInfo; + if (classMemberReference instanceof PsiReferenceExpression) { + if (((PsiReferenceExpression) classMemberReference).getQualifierExpression() == null) { + usageInfo = new UnqualifiedNonDelegatedMemberUsageInfo(classMemberReference, classMember, + delegateFieldVisibility); + } else { + usageInfo = new NonDelegatedMemberUsageInfo( + ((PsiReferenceExpression) classMemberReference).getQualifierExpression(), + classMember, delegateFieldVisibility + ); + } + myUsageInfoStorage.add(usageInfo); + } + else /*if (classMemberReference instanceof PsiJavaCodeReferenceElement)*/ { + usageInfo = new UnqualifiedNonDelegatedMemberUsageInfo(classMemberReference, classMember, + delegateFieldVisibility); + myUsageInfoStorage.add(usageInfo); + + } + } + } + + public void visitThisExpression(PsiThisExpression expression) { + ClassInstanceScanner.processNonArrayExpression(myInstanceVisitor, expression, null); + } + } + + private class MyClassMemberReferencesVisitor extends MyClassInheritorMemberReferencesVisitor { + MyClassMemberReferencesVisitor(List usageInfoStorage, + ClassInstanceScanner.ClassInstanceReferenceVisitor instanceScanner) { + super(InheritanceToDelegationProcessor.this.myClass, usageInfoStorage, instanceScanner); + } + + public void visitMethod(PsiMethod method) { + if (!myOverridenMethods.contains(method)) { + super.visitMethod(method); + } + } + } + + interface PsiAction { + void run() throws IncorrectOperationException; + } + + /** + * This visitor should be called for overriden methods before they are moved to an inner class + */ + private class OverridenMethodClassMemberReferencesVisitor extends ClassMemberReferencesVisitor { + private final ArrayList myPsiActions; + private final PsiThisExpression myQualifiedThis; + private final PsiJavaCodeReferenceElement myClassReferenceElement; + + OverridenMethodClassMemberReferencesVisitor() throws IncorrectOperationException { + super(myClass); + myPsiActions = new ArrayList(); + myClassReferenceElement = myFactory.createClassReferenceElement(myClass); + myQualifiedThis = (PsiThisExpression) myFactory.createExpressionFromText("A.this", null); + myQualifiedThis.getQualifier().replace(myClassReferenceElement); + } + + public List getPsiActions() { + return myPsiActions; + } + + class QualifyThis implements PsiAction { + private final PsiThisExpression myThisExpression; + + QualifyThis(PsiThisExpression thisExpression) { + myThisExpression = thisExpression; + } + + public void run() throws IncorrectOperationException { + myThisExpression.replace(myQualifiedThis); + } + } + + class QualifyName implements PsiAction { + private final PsiReferenceExpression myRef; + private final String myReferencedName; + + QualifyName(PsiReferenceExpression ref, String name) { + myRef = ref; + myReferencedName = name; + } + + public void run() throws IncorrectOperationException { + PsiReferenceExpression newRef = + (PsiReferenceExpression) myFactory.createExpressionFromText("a." + myReferencedName, null); + newRef.getQualifierExpression().replace(myQualifiedThis); + myRef.replace(newRef); + } + } + + protected void visitClassMemberReferenceExpression(PsiMember classMember, + PsiReferenceExpression classMemberReference) { + if (classMember instanceof PsiField) { + final PsiField field = (PsiField) classMember; + + if (field.getContainingClass().equals(myClass)) { + final String name = field.getName(); + final PsiField baseField = myBaseClass.findFieldByName(name, true); + if (baseField != null) { + myPsiActions.add(new QualifyName(classMemberReference, name)); + } else if (classMemberReference.getQualifierExpression() instanceof PsiThisExpression) { + myPsiActions.add(new QualifyThis((PsiThisExpression) classMemberReference.getQualifierExpression())); + } + } + } else if (classMember instanceof PsiMethod && !myOverridenMethods.contains(classMember)) { + final PsiMethod method = (PsiMethod) classMember; + + if (method.getContainingClass().equals(myClass)) { + final PsiMethod baseMethod = myBaseClass.findMethodBySignature(method, true); + if (baseMethod != null) { + myPsiActions.add(new QualifyName(classMemberReference, baseMethod.getName())); + } else if (classMemberReference.getQualifierExpression() instanceof PsiThisExpression) { + myPsiActions.add(new QualifyThis((PsiThisExpression) classMemberReference.getQualifierExpression())); + } + } + } + } + + public void visitThisExpression(final PsiThisExpression expression) { + class Visitor implements ClassInstanceScanner.ClassInstanceReferenceVisitor { + public void visitQualifier(PsiReferenceExpression qualified, PsiExpression instanceRef, PsiElement referencedInstance) { + LOG.assertTrue(false); + } + + public void visitTypeCast(PsiTypeCastExpression typeCastExpression, PsiExpression instanceRef, PsiElement referencedInstance) { + processType(typeCastExpression.getCastType().getType()); + } + + public void visitReadUsage(PsiExpression instanceRef, PsiType expectedType, PsiElement referencedInstance) { + processType(expectedType); + } + + public void visitWriteUsage(PsiExpression instanceRef, PsiType assignedType, PsiElement referencedInstance) { + LOG.assertTrue(false); + } + + private void processType(PsiType type) { + if (type == null || type instanceof PsiPrimitiveType) return; + final PsiClass resolved = PsiUtil.resolveClassInType(type); + if (resolved != null && !myBaseClassBases.contains(resolved)) { + myPsiActions.add(new QualifyThis(expression)); + } + } + } + Visitor visitor = new Visitor(); + ClassInstanceScanner.processNonArrayExpression(visitor, expression, null); + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + } + + } + + + private final class MyClassInstanceReferenceVisitor implements ClassInstanceScanner.ClassInstanceReferenceVisitor { + private final PsiClass myClass; + private final List myUsageInfoStorage; + private final Set myImplementedInterfaces; + + public MyClassInstanceReferenceVisitor(PsiClass aClass, List usageInfoStorage) { + myClass = aClass; + myUsageInfoStorage = usageInfoStorage; + myImplementedInterfaces = getImplementedInterfaces(); + } + + public Set getImplementedInterfaces() { + PsiClass aClass = myClass; + HashSet result = new HashSet(); + while (aClass != null && !myManager.areElementsEquivalent(aClass, myBaseClass)) { + final PsiReferenceList referenceList = aClass.getImplementsList(); + if (referenceList != null) { + final PsiClassType[] implementsList = referenceList.getReferencedTypes(); + for (int i = 0; i < implementsList.length; i++) { + PsiClassType superType = implementsList[i]; + PsiElement resolved = superType.resolve(); + if (resolved instanceof PsiClass && !myManager.areElementsEquivalent(resolved, myBaseClass)) { + result.add(resolved); + RefactoringHierarchyUtil.getSuperClasses((PsiClass) resolved, result, true); + } + } + } + if (aClass.getExtendsList() != null) { + final PsiClassType[] extendsList = aClass.getExtendsList().getReferencedTypes(); + aClass = null; + if (extendsList.length > 0) { + PsiElement resolved = extendsList[0].resolve(); + if (resolved instanceof PsiClass) { + aClass = (PsiClass) resolved; + } + } + } + } + return result; + } + + + public void visitQualifier(PsiReferenceExpression qualified, PsiExpression instanceRef, PsiElement referencedInstance) { + final PsiExpression qualifierExpression = qualified.getQualifierExpression(); + + // do not add usages inside a class + if (qualifierExpression == null + || qualifierExpression instanceof PsiThisExpression + || qualifierExpression instanceof PsiSuperExpression) { + return; + } + + PsiElement resolved = qualified.resolve(); + if (resolved != null && (myBaseClassMembers.contains(resolved) || myOverridenMethods.contains(resolved)) + && !isDelegated(resolved)) { + myUsageInfoStorage.add(new NonDelegatedMemberUsageInfo(instanceRef, resolved, getFieldAccessibility(instanceRef))); + } + } + + public void visitTypeCast(PsiTypeCastExpression typeCastExpression, PsiExpression instanceRef, PsiElement referencedInstance) { + processTypedUsage(typeCastExpression.getCastType().getType(), instanceRef); + } + + + public void visitReadUsage(PsiExpression instanceRef, PsiType expectedType, PsiElement referencedInstance) { + processTypedUsage(expectedType, instanceRef); + } + + public void visitWriteUsage(PsiExpression instanceRef, PsiType assignedType, PsiElement referencedInstance) { + } + + private void processTypedUsage(PsiType type, PsiExpression instanceRef) { + if (type == null || type instanceof PsiPrimitiveType) return; + PsiClass aClass = PsiUtil.resolveClassInType(type); + String qName = aClass.getQualifiedName(); + if (qName != null && "java.lang.Object".equals(qName)) { + myUsageInfoStorage.add(new ObjectUpcastedUsageInfo(instanceRef, getFieldAccessibility(instanceRef))); + } else { + if (myBaseClassBases.contains(aClass) + && !myImplementedInterfaces.contains(aClass) && !myDelegatedInterfaces.contains(aClass)) { + myUsageInfoStorage.add(new UpcastedUsageInfo(instanceRef, aClass, getFieldAccessibility(instanceRef))); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationUtil.java new file mode 100644 index 00000000000..faaa120950a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationUtil.java @@ -0,0 +1,27 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class InheritanceToDelegationUtil { + public static boolean isInnerClassNeeded(PsiClass aClass, PsiClass baseClass) { + if(baseClass.isInterface()) return true; + if(baseClass.hasModifierProperty(PsiModifier.ABSTRACT)) return true; + PsiMethod[] methods = aClass.getMethods(); + + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + + if(method.isConstructor() || method.hasModifierProperty(PsiModifier.PRIVATE)) continue; + PsiMethod baseMethod = baseClass.findMethodBySignature(method, true); + if(baseMethod != null) { + PsiClass containingClass = baseMethod.getContainingClass(); + String qName = containingClass.getQualifiedName(); + if(qName == null || !"java.lang.Object".equals(qName)) return true; + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationViewDescriptor.java new file mode 100644 index 00000000000..2039e4c165a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationViewDescriptor.java @@ -0,0 +1,33 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.psi.*; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class InheritanceToDelegationViewDescriptor extends UsageViewDescriptorAdapter { + private PsiClass myClass; + + public InheritanceToDelegationViewDescriptor(PsiClass aClass, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + super(usages, refreshCommand); + myClass = aClass; + } + + public boolean canRefresh() { + return false; + } + + public PsiElement[] getElements() { + return new PsiElement[] { myClass }; + } + + public void refresh(PsiElement[] elements) { + } + + public String getProcessedElementsHeader() { + return "Replace inheritance with delegation"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassConstructor.java new file mode 100644 index 00000000000..6086bf4420f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassConstructor.java @@ -0,0 +1,34 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class InnerClassConstructor extends InnerClassMethod { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InnerClassConstructor"); + public InnerClassConstructor(PsiMethod method) { + super(method); + LOG.assertTrue(method.isConstructor()); + } + + public void createMethod(PsiClass innerClass, PsiClass outerClass) throws IncorrectOperationException { + final PsiElementFactory factory = outerClass.getManager().getElementFactory(); + final PsiMethod constructor = factory.createConstructor(); + constructor.getNameIdentifier().replace(innerClass.getNameIdentifier()); + final PsiParameterList parameterList = myMethod.getParameterList(); + constructor.getParameterList().replace(parameterList); + PsiExpressionStatement superCallStatement = + (PsiExpressionStatement) factory.createStatementFromText("super();", null); + + PsiExpressionList arguments = ((PsiMethodCallExpression) superCallStatement.getExpression()).getArgumentList(); + PsiParameter[] parameters = parameterList.getParameters(); + for (int i = 0; i < parameters.length; i++) { + arguments.add(factory.createExpressionFromText(parameters[i].getName(), null)); + } + constructor.getBody().add(superCallStatement); + innerClass.add(constructor); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassMethod.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassMethod.java new file mode 100644 index 00000000000..6f6896d7ef4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/InnerClassMethod.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.inheritanceToDelegation; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +abstract class InnerClassMethod { + final PsiMethod myMethod; + + public InnerClassMethod(PsiMethod method) { + myMethod = method; + } + + public abstract void createMethod(PsiClass innerClass, PsiClass outerClass) + throws IncorrectOperationException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/FieldAccessibility.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/FieldAccessibility.java new file mode 100644 index 00000000000..e1a6fea1297 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/FieldAccessibility.java @@ -0,0 +1,26 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class FieldAccessibility { + public static final FieldAccessibility INVISIBLE = new FieldAccessibility(false, null); + + private final boolean myIsVisible; + private final PsiClass myContainingClass; + + public FieldAccessibility(boolean visible, PsiClass containingClass) { + myIsVisible = visible; + myContainingClass = containingClass; + } + + public boolean isAccessible() { + return myIsVisible; + } + + public PsiClass getContainingClass() { + return myContainingClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/InheritanceToDelegationUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/InheritanceToDelegationUsageInfo.java new file mode 100644 index 00000000000..541f2958d88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/InheritanceToDelegationUsageInfo.java @@ -0,0 +1,20 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class InheritanceToDelegationUsageInfo extends UsageInfo { + private final FieldAccessibility myDelegateFieldVisibility; + + public InheritanceToDelegationUsageInfo(PsiElement element, FieldAccessibility delegateFieldVisibility) { + super(element); + myDelegateFieldVisibility = delegateFieldVisibility; + } + + public FieldAccessibility getDelegateFieldAccessible() { + return myDelegateFieldVisibility; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NoLongerOverridingSubClassMethodUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NoLongerOverridingSubClassMethodUsageInfo.java new file mode 100644 index 00000000000..4c9fa95f5c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NoLongerOverridingSubClassMethodUsageInfo.java @@ -0,0 +1,25 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.PsiMethod; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class NoLongerOverridingSubClassMethodUsageInfo extends UsageInfo { + private final PsiMethod myOverridenMethod; + + public NoLongerOverridingSubClassMethodUsageInfo(PsiMethod subClassMethod, PsiMethod overridenMethod) { + super(subClassMethod); + myOverridenMethod = overridenMethod; + } + + public PsiMethod getSubClassMethod() { + return (PsiMethod) getElement(); + } + + public PsiMethod getOverridenMethod() { + return myOverridenMethod; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NonDelegatedMemberUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NonDelegatedMemberUsageInfo.java new file mode 100644 index 00000000000..20c8b3420ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/NonDelegatedMemberUsageInfo.java @@ -0,0 +1,16 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class NonDelegatedMemberUsageInfo extends InheritanceToDelegationUsageInfo { + public PsiElement nonDelegatedMember; + + public NonDelegatedMemberUsageInfo(PsiElement element, PsiElement nonDelegatedMember, + FieldAccessibility delegateFieldVisibility) { + super(element, delegateFieldVisibility); + this.nonDelegatedMember = nonDelegatedMember; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/ObjectUpcastedUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/ObjectUpcastedUsageInfo.java new file mode 100644 index 00000000000..c66a3720f0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/ObjectUpcastedUsageInfo.java @@ -0,0 +1,12 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class ObjectUpcastedUsageInfo extends UpcastedUsageInfo { + public ObjectUpcastedUsageInfo(PsiElement element, FieldAccessibility delegateFieldVisibility) { + super(element, null, delegateFieldVisibility); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UnqualifiedNonDelegatedMemberUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UnqualifiedNonDelegatedMemberUsageInfo.java new file mode 100644 index 00000000000..951413bc8a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UnqualifiedNonDelegatedMemberUsageInfo.java @@ -0,0 +1,13 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class UnqualifiedNonDelegatedMemberUsageInfo extends NonDelegatedMemberUsageInfo{ + + public UnqualifiedNonDelegatedMemberUsageInfo(PsiElement element, PsiElement nonDelegatedMember, FieldAccessibility delegateFieldVisibility) { + super(element, nonDelegatedMember, delegateFieldVisibility); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UpcastedUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UpcastedUsageInfo.java new file mode 100644 index 00000000000..f71bf25bde6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inheritanceToDelegation/usageInfo/UpcastedUsageInfo.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.inheritanceToDelegation.usageInfo; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class UpcastedUsageInfo extends InheritanceToDelegationUsageInfo{ + public final PsiClass upcastedTo; + + public UpcastedUsageInfo(PsiElement element, PsiClass upcastedTo, FieldAccessibility delegateFieldVisibility) { + super(element, delegateFieldVisibility); + this.upcastedTo = upcastedTo; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldHandler.java new file mode 100644 index 00000000000..476e4707835 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldHandler.java @@ -0,0 +1,60 @@ +package com.intellij.refactoring.inline; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +/** + * @author ven + */ +public class InlineConstantFieldHandler { + private static final String REFACTORING_NAME = "Inline field"; + + public void invoke(Project project, Editor editor, PsiField field) { + if (!field.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, field); + return; + } + + if (!field.hasModifierProperty(PsiModifier.FINAL)) { + String message = REFACTORING_NAME + " refactoring is supported only for final fields"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_FIELD, project); + return; + } + + if (!field.hasInitializer()) { + String message = "No initializer present for the field"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_FIELD, project); + return; + } + + PsiSearchHelper searchHelper = PsiManager.getInstance(project).getSearchHelper(); + final PsiReference[] refs = searchHelper.findReferences(field, GlobalSearchScope.projectScope(project), false); + + if (refs.length == 0){ + String message = "Field " + field.getName() + " is never used"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + return; + } + + PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null; + if (reference != null && !field.equals(reference.resolve())) { + reference = null; + } + + final boolean invokedOnReference = (reference != null); + if (!invokedOnReference && !field.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, field); + return; + } + PsiReferenceExpression element = reference != null ? (PsiReferenceExpression)reference.getElement() : null; + final InlineConstantFieldProcessor processor = new InlineConstantFieldProcessor(field, project, element, editor); + InlineFieldDialog dialog = new InlineFieldDialog(project, field, invokedOnReference, processor); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java new file mode 100644 index 00000000000..7dac63ba439 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java @@ -0,0 +1,223 @@ +package com.intellij.refactoring.inline; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author ven + */ +class InlineConstantFieldProcessor extends BaseRefactoringProcessor implements InlineFieldDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineConstantFieldProcessor"); + private PsiField myField; + private InlineFieldDialog myDialog; + private PsiReferenceExpression myRefExpr; + private Editor myEditor; + + public InlineConstantFieldProcessor(PsiField field, Project project, PsiReferenceExpression ref, Editor editor) { + super(project); + myField = field; + myRefExpr = ref; + myEditor = editor; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new InlineViewDescriptor(myField, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + PsiManager manager = myField.getManager(); + if (myDialog.isInlineThisOnly()) return new UsageInfo[]{new UsageInfo(myRefExpr)}; + + PsiSearchHelper helper = manager.getSearchHelper(); + PsiReference[] refs = helper.findReferences(myField, GlobalSearchScope.projectScope(myProject), false); + UsageInfo[] infos = new UsageInfo[refs.length]; + for (int i = 0; i < refs.length; i++) { + PsiElement element = refs[i].getElement(); + if (element instanceof PsiReferenceExpression) { + infos[i] = new UsageInfo(element); + } + } + return infos; + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiField); + myField = (PsiField)elements[0]; + } + + protected void performRefactoring(UsageInfo[] usages) { + int col = -1; + int line = -1; + if (myEditor != null) { + col = myEditor.getCaretModel().getLogicalPosition().column; + line = myEditor.getCaretModel().getLogicalPosition().line; + LogicalPosition pos = new LogicalPosition(0, 0); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + + PsiExpression initializer = myField.getInitializer(); + LOG.assertTrue(initializer != null); + + PsiConstantEvaluationHelper evalHelper = myField.getManager().getConstantEvaluationHelper(); + initializer = normalize ((PsiExpression)initializer.copy()); + for (int i = 0; i < usages.length; i++) { + PsiExpression initializer1 = initializer; + PsiExpression expr = (PsiExpression)usages[i].getElement(); + while (expr.getParent() instanceof PsiArrayAccessExpression) { + PsiArrayAccessExpression arrayAccess = ((PsiArrayAccessExpression)expr.getParent()); + Object value = evalHelper.computeConstantExpression(arrayAccess.getIndexExpression()); + if (value instanceof Integer) { + int intValue = ((Integer)value).intValue(); + if (initializer1 instanceof PsiNewExpression) { + PsiExpression[] arrayInitializers = ((PsiNewExpression)initializer1).getArrayInitializer().getInitializers(); + if (0 <= intValue && intValue < arrayInitializers.length) { + expr = (PsiExpression)expr.getParent(); + initializer1 = normalize(arrayInitializers[intValue]); + continue; + } + } + } + + break; + } + + try { + myField.normalizeDeclaration(); + ChangeContextUtil.encodeContextInfo(initializer1, true); + PsiElement element = expr.replace(initializer1); + ChangeContextUtil.decodeContextInfo(element, null, null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + if (!myDialog.isInlineThisOnly()) { + try { + myField.delete(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + if (myEditor != null) { + LogicalPosition pos = new LogicalPosition(line, col); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + } + + private PsiExpression normalize(PsiExpression expression) { + if (expression instanceof PsiArrayInitializerExpression) { + PsiElementFactory factory = expression.getManager().getElementFactory(); + try { + String typeString = expression.getType().getCanonicalText(); + PsiNewExpression result = (PsiNewExpression)factory.createExpressionFromText("new " + typeString + "{}", expression); + result.getArrayInitializer().replace(expression); + return result; + } + catch (IncorrectOperationException e) { + LOG.error(e); + return expression; + } + } + + return expression; + } + + protected String getCommandName() { + return "Inline field " + UsageViewUtil.getDescriptiveName(myField); + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + ArrayList conflicts = new ArrayList(); + + ReferencedElementsCollector collector = new ReferencedElementsCollector(); + PsiExpression initializer = myField.getInitializer(); + LOG.assertTrue(initializer != null); + initializer.accept(collector); + HashSet referencedWithVisibility = collector.myReferencedMembers; + + UsageInfo[] plainUsages = usages[0]; + PsiResolveHelper resolveHelper = myField.getManager().getResolveHelper(); + for (int i = 0; i < plainUsages.length; i++) { + UsageInfo info = plainUsages[i]; + PsiElement element = info.getElement(); + LOG.assertTrue(element instanceof PsiReferenceExpression); + if (isAccessedForWriting((PsiExpression)element)) { + String message = ConflictsUtil.getDescription(myField, true) + " is used for writing in " + + ConflictsUtil.getDescription(ConflictsUtil.getContainer(element), true); + conflicts.add(message); + } + + for (Iterator iterator = referencedWithVisibility.iterator(); iterator.hasNext();) { + PsiMember member = iterator.next(); + if (!resolveHelper.isAccessible(member, element, null)) { + String message = ConflictsUtil.getDescription(member, true) + + " will not be accessible from " + + ConflictsUtil.getDescription(ConflictsUtil.getContainer(element), true) + + " after inlining"; + conflicts.add(message); + } + } + } + + if (myDialog != null && conflicts.size() > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), + myProject); + dialog.show(); + if (!dialog.isOK()) return false; + } + + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + return true; + } + + private boolean isAccessedForWriting (PsiExpression expr) { + while(expr.getParent() instanceof PsiArrayAccessExpression) { + expr = (PsiExpression)expr.getParent(); + } + + return PsiUtil.isAccessedForWriting(expr); + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myDialog.isPreviewUsages(); + if (UsageViewUtil.hasReadOnlyUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + return toPreview; + } + + public void run(InlineFieldDialog dialog) { + myDialog = dialog; + this.run((Object)null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineFieldDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineFieldDialog.java new file mode 100644 index 00000000000..07972bff82b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineFieldDialog.java @@ -0,0 +1,111 @@ + +package com.intellij.refactoring.inline; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +public class InlineFieldDialog extends RefactoringDialog implements InlineOptions { + public static final String REFACTORING_NAME = "Inline Field"; + public static interface Callback { + void run(InlineFieldDialog dialog); + } + + private JLabel myFieldNameLabel = new JLabel(); + + private final PsiField myField; + private final boolean myInvokedOnReference; + private final Callback myCallback; + + private JRadioButton myRbInlineAll; + private JRadioButton myRbInlineThisOnly; + + public InlineFieldDialog(Project project, PsiField field, boolean invokedOnReference, Callback callback) { + super(project, true); + myField = field; + myInvokedOnReference = invokedOnReference; + myCallback = callback; + + setTitle(REFACTORING_NAME); + + init(); + + String fieldText = PsiFormatUtil.formatVariable(myField, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE ,PsiSubstitutor.EMPTY); + myFieldNameLabel.setText("Field " + fieldText); + } + + public boolean isInlineThisOnly() { + return myRbInlineThisOnly.isSelected(); + } + + protected JComponent createNorthPanel() { + return myFieldNameLabel; + } + + protected JComponent createCenterPanel() { + JPanel optionsPanel = new JPanel(); + optionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Inline")); + optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.Y_AXIS)); + + myRbInlineAll = new JRadioButton("All references and remove the field", true); + myRbInlineAll.setMnemonic('A'); + myRbInlineThisOnly = new JRadioButton("This reference only and keep the field"); + myRbInlineThisOnly.setMnemonic('t'); + + optionsPanel.add(myRbInlineAll); + optionsPanel.add(myRbInlineThisOnly); + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbInlineAll); + bg.add(myRbInlineThisOnly); + + myRbInlineThisOnly.setEnabled(myInvokedOnReference); + final boolean writable = myField.isWritable(); + myRbInlineAll.setEnabled(writable); + if(myInvokedOnReference) { + if (writable) { + final boolean inlineThis = RefactoringSettings.getInstance().INLINE_FIELD_THIS; + myRbInlineThisOnly.setSelected(inlineThis); + myRbInlineAll.setSelected(!inlineThis); + } + else { + myRbInlineAll.setSelected(false); + myRbInlineThisOnly.setSelected(true); + } + } + else { + myRbInlineAll.setSelected(true); + myRbInlineThisOnly.setSelected(false); + } + getPreviewAction().setEnabled(myRbInlineAll.isSelected()); + myRbInlineAll.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + boolean enabled = myRbInlineAll.isSelected(); + getPreviewAction().setEnabled(enabled); + } + } + ); + + return optionsPanel; + } + + protected void doAction() { + myCallback.run(this); + RefactoringSettings settings = RefactoringSettings.getInstance(); + if(myRbInlineThisOnly.isEnabled() && myRbInlineAll.isEnabled()) { + settings.INLINE_FIELD_THIS = isInlineThisOnly(); + } + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineHandler.java new file mode 100644 index 00000000000..fadd61a0d65 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineHandler.java @@ -0,0 +1,55 @@ +/** + * created at Nov 21, 2001 + * @author Jeka + */ +package com.intellij.refactoring.inline; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +public class InlineHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineHandler"); + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + LOG.assertTrue(elements.length == 1); + if (elements[0] instanceof PsiMethod) { + new InlineMethodHandler().invoke(project, null, (PsiMethod) elements[0]); + } else if (elements[0] instanceof PsiPointcutDef) { + new InlinePointcutHandler().invoke(project, null, (PsiPointcutDef) elements[0]); + } else if (elements[0] instanceof PsiField) { + new InlineConstantFieldHandler().invoke(project, null, (PsiField) elements[0]); + } else if (elements[0] instanceof PsiLocalVariable) { + new InlineLocalHandler().invoke(project, null, (PsiLocalVariable)elements[0]); + } else { + LOG.error("Unknown element type to inline:" + elements[0]); + } + } + + public void invoke(final Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = (PsiElement) dataContext.getData(DataConstants.PSI_ELEMENT); + if (element instanceof PsiLocalVariable) { + new InlineLocalHandler().invoke(project, editor, (PsiLocalVariable) element); + } else if (element instanceof PsiPointcutDef) { + new InlinePointcutHandler().invoke(project, editor, (PsiPointcutDef) element); + } else if (element instanceof PsiMethod) { + new InlineMethodHandler().invoke(project, editor, (PsiMethod) element); + } else if (element instanceof PsiField) { + new InlineConstantFieldHandler().invoke(project, editor, (PsiField) element); + } else { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned at the name of\n" + + "the method or local variable to be refactored."; + RefactoringMessageUtil.showErrorMessage("Inline", message, null, project); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineLocalHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineLocalHandler.java new file mode 100644 index 00000000000..3ba681d377a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineLocalHandler.java @@ -0,0 +1,283 @@ + +package com.intellij.refactoring.inline; + +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.controlFlow.ControlFlow; +import com.intellij.psi.controlFlow.ControlFlowAnalyzer; +import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.controlFlow.LocalsControlFlowPolicy; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.util.RefactoringMessageDialog; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Iterator; + +class InlineLocalHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineLocalHandler"); + + private static final String REFACTORING_NAME = "Inline Variable"; + + /** + * should be called in AtomicAction + */ + public void invoke(final Project project, final Editor editor, final PsiLocalVariable local) { + if (!local.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, local); + return; + } + + final HighlightManager highlightManager = HighlightManager.getInstance(project); + + final String localName = local.getName(); + final PsiExpression initializer = local.getInitializer(); + if (initializer == null){ + String message = + "Cannot perform the refactoring.\n" + + "Variable " + localName + " has no initializer."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + return; + } + + PsiSearchHelper searchHelper = PsiManager.getInstance(project).getSearchHelper(); + final PsiReference[] refs = searchHelper.findReferences(local, GlobalSearchScope.projectScope(project), false); + + if (refs.length == 0){ + String message = "Variable " + localName + " is never used"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + return; + } + + final ArrayList toInline = new ArrayList(refs.length); + final PsiJavaCodeReferenceElement firstWriteUsage = (PsiJavaCodeReferenceElement)filterUsagesToInline(refs, toInline); + if (toInline.size() == 0) { + String message = "Variable " + localName + " is never used before modification"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + return; + } + final PsiElement lastUsage = (toInline.get(toInline.size() - 1)).getElement(); + final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(local); + EditorColorsManager manager = EditorColorsManager.getInstance(); + final TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + ControlFlow controlFlow; + try { + controlFlow = new ControlFlowAnalyzer(codeFragment, new LocalsControlFlowPolicy(codeFragment), false).buildControlFlow(); + PsiElement commonParent = PsiTreeUtil.findCommonParent(local, lastUsage); + PsiElement anchor = lastUsage; + while (!commonParent.equals(anchor.getParent())) { + anchor = anchor.getParent(); + } + while (controlFlow.getEndOffset(anchor) < 0) { + anchor = anchor.getParent(); + } + int offset = controlFlow.getEndOffset(anchor); + if (ControlFlowUtil.needVariableValueAt(local, controlFlow, offset)){ + ArrayList refsForWriting = new ArrayList(refs.length); + for (int idx = 0; idx < refs.length; idx++) { + PsiReference ref = refs[idx]; + if (PsiUtil.isAccessedForWriting((PsiExpression)ref.getElement())) { + refsForWriting.add(ref); + } + } + if (refsForWriting.size() > 0) { + highlightManager.addOccurrenceHighlights( + editor, + refsForWriting.toArray(new PsiReference[refsForWriting.size()]), + attributes, true, null + ); + String message = + "Cannot perform the refactoring.\n" + + "Variable " + localName + " is accessed for writing."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + return; + } + } + + if (firstWriteUsage != null) { + PsiElement tmp = firstWriteUsage; + int writeInstructionOffset; + do { + writeInstructionOffset = controlFlow.getEndOffset(tmp); + tmp = tmp.getParent(); + } while(writeInstructionOffset < 0); + + for (Iterator iterator = toInline.iterator(); iterator.hasNext();) { + PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)iterator.next(); + if (ControlFlowUtil.isInstructionReachable(controlFlow, controlFlow.getStartOffset(ref), writeInstructionOffset)) { + String message = "Cannot perform the refactoring.\n" + + "Variable initializer does not dominate its usages."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_VARIABLE, project); + return; + } + } + } + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + } + + if (!ApplicationManager.getApplication().isUnitTestMode()) { + // TODO : check if initializer uses fieldNames that possibly will be hidden by other + // locals with the same names after inlining + highlightManager.addOccurrenceHighlights( + editor, + toInline.toArray(new PsiReference[toInline.size()]), + attributes, true, null + ); + int occurrencesCount = toInline.size(); + RefactoringMessageDialog dialog = new RefactoringMessageDialog( + REFACTORING_NAME, + "Inline local variable " + localName + "? (" + occurrencesCount + (occurrencesCount == 1? " occurrence)" : " occurrences)"), + HelpID.INLINE_VARIABLE, + "OptionPane.questionIcon", + true, + project); + dialog.show(); + if (!dialog.isOK()){ + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + return; + } + } + + final Runnable runnable = new Runnable() { + public void run() { + try{ + final PsiExpression initializer = local.getInitializer(); + PsiExpression[] exprs = new PsiExpression[toInline.size()]; + for(int idx = 0; idx < toInline.size(); idx++){ + PsiReference ref = toInline.get(idx); + PsiJavaCodeReferenceElement refElement = (PsiJavaCodeReferenceElement)ref.getElement(); + exprs[idx] = RefactoringUtil.inlineVariable(local, initializer, refElement); + } + if (firstWriteUsage != null) { +// PsiReference firstWriteUsage = refs[toInline.size()]; + ControlFlow controlFlow; + try { + controlFlow = new ControlFlowAnalyzer(codeFragment, new LocalsControlFlowPolicy(codeFragment), false).buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + controlFlow = ControlFlow.EMPTY; + } + PsiElement insertAnchor = firstWriteUsage.getElement(); + PsiElement parent = PsiTreeUtil.findCommonParent(local, insertAnchor); + while (!parent.equals(insertAnchor.getParent())) { + insertAnchor = insertAnchor.getParent(); + } + int startOffset = controlFlow.getStartOffset(insertAnchor); + if (startOffset != -1) { + insertAnchor = controlFlow.getElement(startOffset); + } + parent = PsiTreeUtil.findCommonParent(local, insertAnchor); + while (!parent.equals(insertAnchor.getParent())) { + insertAnchor = insertAnchor.getParent(); + } + if (initializer != null) { + initializer.delete(); + } + PsiAssignmentExpression assignment = getAssignmentExpression(firstWriteUsage); + PsiDeclarationStatement newDeclaration = createDeclarationStatement(local, assignment); + parent.addBefore(newDeclaration, insertAnchor); + if (assignment != null && local.getParent().getParent().equals(assignment.getParent().getParent())) { + // there is a first assignment and it is on the _same_ level with the local variable declaration + assignment.getParent().delete(); + } + } + local.delete(); + + if (!ApplicationManager.getApplication().isUnitTestMode()) { + highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + }; + + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, "Inline " + localName, null); + } + + /** + * + * @param refs occurences + * @param toInline where to put results + * @return first write usage of a variable + */ + private static PsiReference filterUsagesToInline(final PsiReference[] refs, ArrayList toInline) { + PsiReference firstWriteUsage = null; + PsiExpression assignmentExpression = null; + for (int idx = 0; idx < refs.length; idx++) { + PsiReference ref = refs[idx]; + PsiElement refElement = ref.getElement(); + if (PsiUtil.isAccessedForWriting((PsiExpression)refElement)) { + if(assignmentExpression != null) break; + assignmentExpression = (PsiExpression) refElement.getParent(); + firstWriteUsage = ref; + continue; + } + if(assignmentExpression != null) { + if(!PsiTreeUtil.isAncestor(assignmentExpression, refElement, true)) break; + } + toInline.add(ref); + } + return firstWriteUsage; + } + + private PsiDeclarationStatement createDeclarationStatement(PsiLocalVariable local, PsiAssignmentExpression assignment) { + PsiDeclarationStatement declaration = (PsiDeclarationStatement)local.getParent(); + try { + if (assignment == null || !declaration.getParent().equals(assignment.getParent().getParent())) { + declaration = (PsiDeclarationStatement)declaration.copy(); + PsiExpression initializer = ((PsiVariable)declaration.getDeclaredElements()[0]).getInitializer(); + if (initializer != null) { + initializer.delete(); + } + } + else { + PsiElementFactory factory = local.getManager().getElementFactory(); + declaration = factory.createVariableDeclarationStatement( + local.getName(), + local.getType(), + assignment.getRExpression() + ); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return declaration; + } + + private static PsiAssignmentExpression getAssignmentExpression(PsiJavaCodeReferenceElement ref) { + PsiElement parent = ref; + while (parent != null) { + if (parent instanceof PsiMethod) return null; + if (parent instanceof PsiAssignmentExpression) { + return (PsiAssignmentExpression)parent; + } + parent = parent.getParent(); + } + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodDialog.java new file mode 100644 index 00000000000..ca8cdb2d962 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodDialog.java @@ -0,0 +1,110 @@ + +package com.intellij.refactoring.inline; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +public class InlineMethodDialog extends RefactoringDialog implements InlineOptions { + public static final String REFACTORING_NAME = "Inline Method"; + public static interface Callback { + void run(InlineMethodDialog dialog); + } + + private JLabel myMethodNameLabel = new JLabel(); + + private final PsiMethod myMethod; + private final boolean myInvokedOnReference; + private final Callback myCallback; + + private JRadioButton myRbInlineAll; + private JRadioButton myRbInlineThisOnly; + + public InlineMethodDialog(Project project, PsiMethod method, boolean invokedOnReference, Callback callback) { + super(project, true); + myMethod = method; + myInvokedOnReference = invokedOnReference; + myCallback = callback; + + setTitle(REFACTORING_NAME); + + init(); + + String methodText = PsiFormatUtil.formatMethod(myMethod, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, PsiFormatUtil.SHOW_TYPE); + myMethodNameLabel.setText("Method " + methodText); + } + + public boolean isInlineThisOnly() { + return myRbInlineThisOnly.isSelected(); + } + + protected JComponent createNorthPanel() { + return myMethodNameLabel; + } + + protected JComponent createCenterPanel() { + JPanel optionsPanel = new JPanel(); + optionsPanel.setBorder(IdeBorderFactory.createTitledBorder("Inline")); + optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.Y_AXIS)); + + myRbInlineAll = new JRadioButton("All invocations and remove the method", true); + myRbInlineAll.setMnemonic('A'); + myRbInlineThisOnly = new JRadioButton("This invocation only and keep the method"); + myRbInlineThisOnly.setMnemonic('t'); + + optionsPanel.add(myRbInlineAll); + optionsPanel.add(myRbInlineThisOnly); + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbInlineAll); + bg.add(myRbInlineThisOnly); + + myRbInlineThisOnly.setEnabled(myInvokedOnReference); + final boolean writable = myMethod.isWritable(); + myRbInlineAll.setEnabled(writable); + if(myInvokedOnReference) { + if (writable) { + final boolean inline_method_this = RefactoringSettings.getInstance().INLINE_METHOD_THIS; + myRbInlineThisOnly.setSelected(inline_method_this); + myRbInlineAll.setSelected(!inline_method_this); + } + else { + myRbInlineAll.setSelected(false); + myRbInlineThisOnly.setSelected(true); + } + } + else { + myRbInlineAll.setSelected(true); + myRbInlineThisOnly.setSelected(false); + } + getPreviewAction().setEnabled(myRbInlineAll.isSelected()); + myRbInlineAll.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + boolean enabled = myRbInlineAll.isSelected(); + getPreviewAction().setEnabled(enabled); + } + } + ); + + return optionsPanel; + } + + protected void doAction() { + myCallback.run(this); + RefactoringSettings settings = RefactoringSettings.getInstance(); + if(myRbInlineThisOnly.isEnabled() && myRbInlineAll.isEnabled()) { + settings.INLINE_METHOD_THIS = isInlineThisOnly(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodHandler.java new file mode 100644 index 00000000000..85311f6801a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodHandler.java @@ -0,0 +1,102 @@ + +package com.intellij.refactoring.inline; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; + +class InlineMethodHandler { + private static final String REFACTORING_NAME = "Inline Method"; + + public void invoke(final Project project, Editor editor, final PsiMethod method) { + if (method.getBody() == null){ + String message = REFACTORING_NAME + " refactoring cannot be applied to abstract methods"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_METHOD, project); + return; + } + + if (InlineMethodProcessor.checkBadReturns(method)) { + String message = REFACTORING_NAME + " refactoring is not supported when return statement interrupts the execution flow"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_METHOD, project); + return; + } + + if (checkRecursive(method)) { + String message = REFACTORING_NAME + " refactoring is not supported for recursive methods"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_METHOD, project); + return; + } + + PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null; + if (method.isConstructor()) { + if (method.isVarArgs()) { + String message = REFACTORING_NAME + " refactoring cannot be applied to vararg constructors"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_METHOD, project); + return; + } + if (!checkChainingConstructor(method)) { + String message = REFACTORING_NAME + " refactoring cannot be applied to inline non-chaining constructors"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INLINE_METHOD, project); + return; + } + if (reference != null) { + PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall((PsiJavaCodeReferenceElement)reference.getElement()); + if (constructorCall == null || !method.equals(constructorCall.resolveMethod())) reference = null; + } + } + else { + if (reference != null && !method.equals(reference.resolve())) { + reference = null; + } + } + + final boolean invokedOnReference = reference != null; + if (!invokedOnReference && !method.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, method); + return; + } + PsiJavaCodeReferenceElement element = reference != null ? (PsiJavaCodeReferenceElement)reference.getElement() : null; + final InlineMethodProcessor processor = new InlineMethodProcessor(project, method, element, editor); + InlineMethodDialog dialog = new InlineMethodDialog(project, method, invokedOnReference, processor); + dialog.show(); + } + + private boolean checkChainingConstructor(PsiMethod constructor) { + PsiCodeBlock body = constructor.getBody(); + if (body != null) { + PsiStatement[] statements = body.getStatements(); + if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { + PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + PsiReferenceExpression methodExpr = ((PsiMethodCallExpression)expression).getMethodExpression(); + if (methodExpr != null) { + PsiElement resolved = methodExpr.resolve(); + return resolved instanceof PsiMethod && ((PsiMethod)resolved).isConstructor(); + } + } + } + } + return false; + } + + private boolean checkRecursive(PsiMethod method) { + return checkCalls(method.getBody(), method); + } + + private boolean checkCalls(PsiElement scope, PsiMethod method) { + if (scope instanceof PsiMethodCallExpression){ + PsiMethod refMethod = (PsiMethod)((PsiMethodCallExpression)scope).getMethodExpression().resolve(); + if (method.equals(refMethod)) return true; + } + + for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){ + if (checkCalls(child, method)) return true; + } + + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodProcessor.java new file mode 100644 index 00000000000..1f5925db3c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -0,0 +1,1162 @@ +package com.intellij.refactoring.inline; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.controlFlow.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.introduceParameter.Util; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +public class InlineMethodProcessor extends BaseRefactoringProcessor implements InlineMethodDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineMethodProcessor"); + + private PsiMethod myMethod; + private PsiJavaCodeReferenceElement myReference; + private Editor myEditor; + private InlineOptions myDialog; + + private PsiManager myManager; + private PsiElementFactory myFactory; + private CodeStyleManager myCodeStyleManager; + + private PsiBlockStatement[] myAddedBraces; + private final String myDescriptiveName; + private Map myAddedClassInitializers; + private PsiMethod myMethodCopy; + + public InlineMethodProcessor(Project project, + PsiMethod method, + PsiJavaCodeReferenceElement reference, + Editor editor) { + super(project); + myMethod = method; + myReference = reference; + myEditor = editor; + + myManager = PsiManager.getInstance(myProject); + myFactory = myManager.getElementFactory(); + myCodeStyleManager = CodeStyleManager.getInstance(myProject); + myDescriptiveName = UsageViewUtil.getDescriptiveName(myMethod); + } + + protected String getCommandName() { + return "Inlining method " + myDescriptiveName; + } + + public void run(InlineMethodDialog dialog) { + myDialog = dialog; + this.run((Object)null); + } + + public void testRun(InlineOptions dialog) { + myDialog = dialog; + UsageInfo[] usages = findUsages(); + performRefactoring(usages); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new InlineViewDescriptor(myMethod, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + if (myDialog.isInlineThisOnly()) return new UsageInfo[]{new UsageInfo(myReference)}; + PsiSearchHelper helper = myManager.getSearchHelper(); + PsiReference[] refs = helper.findReferences(myMethod, GlobalSearchScope.projectScope(myProject), true); + UsageInfo[] infos = new UsageInfo[refs.length]; + for (int i = 0; i < refs.length; i++) { + infos[i] = new UsageInfo(refs[i].getElement()); + } + return infos; + } + + protected void refreshElements(PsiElement[] elements) { + boolean condition = elements.length == 1 && elements[0] instanceof PsiMethod; + LOG.assertTrue(condition); + myMethod = (PsiMethod)elements[0]; + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + final ReferencedElementsCollector collector = new ReferencedElementsCollector(); + myMethod.accept(collector); + final HashMap> containersToReferenced; + String fromForReference = null; + if (usages[0] != null) { + containersToReferenced = getInaccessible(collector.myReferencedMembers, usages[0]); + } + else { + containersToReferenced = getInaccessible(collector.myReferencedMembers, + new UsageInfo[]{new UsageInfo(myReference)}); + fromForReference = ConflictsUtil.getDescription(ConflictsUtil.getContainer(myReference), true); + } + ArrayList conflicts = new ArrayList(); + final Set containers = containersToReferenced.keySet(); + for (Iterator iterator = containers.iterator(); iterator.hasNext();) { + PsiMember container = iterator.next(); + HashSet referencedInaccessible = containersToReferenced.get(container); + for (Iterator iterator1 = referencedInaccessible.iterator(); iterator1.hasNext();) { + PsiElement referenced = iterator1.next(); + String message = ConflictsUtil.getDescription(referenced, true) + " that is used in inlined method, " + + " is not accessible from " + + (fromForReference == null ? + "call site(s) in " + ConflictsUtil.getDescription(container, true) : fromForReference); + conflicts.add(ConflictsUtil.capitalize(message)); + } + } + + if (myDialog != null && conflicts.size() > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), + myProject); + dialog.show(); + if (!dialog.isOK()) return false; + } + + // make sure that dialog is closed in swing thread + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + return true; + } + + /** + * Given a set of referencedElements, returns a map from containers (in a sense of ConflictsUtil.getContainer) + * to subsets of referencedElemens that are not accessible from that container + * + * @param referencedElements + * @param usages + * @return + */ + private static HashMap> getInaccessible(HashSet referencedElements, UsageInfo[] usages) { + HashMap> result = new com.intellij.util.containers.HashMap>(); + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + final PsiMember container = ConflictsUtil.getContainer(usage.getElement()); + HashSet inaccessibleReferenced = result.get(container); + if (inaccessibleReferenced == null) { + inaccessibleReferenced = new HashSet(); + result.put(container, inaccessibleReferenced); + for (Iterator iterator = referencedElements.iterator(); iterator.hasNext();) { + PsiMember member = iterator.next(); + if (!PsiUtil.isAccessible(member, usage.getElement(), null)) { + inaccessibleReferenced.add(member); + } + } + } + } + + return result; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + //if (myDialog.isInlineThisOnly()) return false; + boolean toPreview = myDialog.isPreviewUsages(); + if (UsageViewUtil.hasReadOnlyUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + return toPreview; + } + + protected void performRefactoring(UsageInfo[] usages) { + int col = -1; + int line = -1; + if (myEditor != null) { + col = myEditor.getCaretModel().getLogicalPosition().column; + line = myEditor.getCaretModel().getLogicalPosition().line; + LogicalPosition pos = new LogicalPosition(0, 0); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + + final LvcsAction lvcsAction = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + try { + doRefactoring(usages); + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, lvcsAction); + } + + if (myEditor != null) { + LogicalPosition pos = new LogicalPosition(line, col); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + } + + private void doRefactoring(UsageInfo[] usages) { + try { + if (myDialog.isInlineThisOnly()) { + if (myMethod.isConstructor()) { + PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall(myReference); + if (constructorCall != null) { + inlineConstructorCall(constructorCall); + } + } + else { + myReference = addBracesWhenNeeded(new PsiReferenceExpression[]{(PsiReferenceExpression)myReference})[0]; + inlineMethodCall((PsiReferenceExpression)myReference); + } + } + else { + if (myMethod.isConstructor()) { + for (int i = 0; i < usages.length; i++) { + PsiElement element = usages[i].getElement(); + if (element instanceof PsiJavaCodeReferenceElement) { + PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall((PsiJavaCodeReferenceElement)element); + if (constructorCall != null) { + inlineConstructorCall(constructorCall); + } + } + } + myMethod.delete(); + } + else { + ArrayList tempRefs = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + if (usage.getElement() instanceof PsiReferenceExpression) { + tempRefs.add((PsiReferenceExpression)usage.getElement()); + } + } + PsiReferenceExpression[] refs = tempRefs.toArray( + new PsiReferenceExpression[tempRefs.size()]); + refs = addBracesWhenNeeded(refs); + for (int i = 0; i < refs.length; i++) { + inlineMethodCall(refs[i]); + } + myMethod.delete(); + } + } + removeAddedBracesWhenPossible(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private void inlineConstructorCall(PsiCall constructorCall) { + final PsiMethod oldConstructor = constructorCall.resolveMethod(); + if (oldConstructor == null) return; + final PsiManager manager = oldConstructor.getManager(); + final PsiExpression[] instanceCreationArguments = constructorCall.getArgumentList().getExpressions(); + final PsiParameter[] parameters = oldConstructor.getParameterList().getParameters(); + if (parameters.length != instanceCreationArguments.length) return; + + PsiCodeBlock body = oldConstructor.getBody(); + if (body == null) return; + PsiStatement[] statements = body.getStatements(); + if (statements.length != 1 || !(statements[0] instanceof PsiExpressionStatement)) return; + PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); + if (!(expression instanceof PsiMethodCallExpression)) return; + + PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression(); + if (methodExpression != null && "this".equals(methodExpression.getReferenceName())) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression.copy(); + final PsiExpression[] args = methodCall.getArgumentList().getExpressions(); + for (int i = 0; i < args.length; i++) { + PsiExpression arg = args[i]; + arg.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + PsiElement resolved = expression.resolve(); + //For some unknown reason declarationScope != oldConstructor, though equivalent + if (resolved instanceof PsiParameter && manager.areElementsEquivalent(((PsiParameter)resolved).getDeclarationScope(), oldConstructor)) { + PsiElement declarationScope = ((PsiParameter)resolved).getDeclarationScope(); + PsiParameter[] declarationParameters = ((PsiMethod)declarationScope).getParameterList().getParameters(); + for (int j = 0; j < declarationParameters.length; j++) { + if (declarationParameters[j] == resolved) { + try { + expression.replace(instanceCreationArguments[j]); + break; + } + catch (IncorrectOperationException e) { LOG.error(e); } + } + } + } + } + }); + } + try { + constructorCall.getArgumentList().replace(methodCall.getArgumentList()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + private void inlineMethodCall(PsiReferenceExpression ref) throws IncorrectOperationException { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)ref.getParent(); + + BlockData blockData = prepareBlock(ref); + solveVariableNameConflicts(blockData.block, ref); + substituteMethodTypeParams(blockData.block, methodCall); + addParmAndThisVarInitializers(blockData, methodCall); + + PsiElement anchor = RefactoringUtil.getParentStatement(methodCall, true); + if (anchor == null) return; //TODO!! (JSP, field initializer) + PsiElement anchorParent = anchor.getParent(); + PsiLocalVariable thisVar = null; + PsiLocalVariable[] parmVars = new PsiLocalVariable[blockData.parmVars.length]; + PsiLocalVariable resultVar = null; + PsiElement[] methodStatements = blockData.block.getChildren(); + if (methodStatements.length > 2) { + PsiElement first = methodStatements[1]; + PsiElement last = methodStatements[methodStatements.length - 2]; + + PsiStatement[] statements = blockData.block.getStatements(); + if (statements.length > 0 && statements[statements.length - 1] instanceof PsiReturnStatement) { + last = statements[statements.length - 1].getPrevSibling(); + } + + PsiElement firstAdded = anchorParent.addRangeBefore(first, last, anchor); + + PsiElement current = firstAdded; + if (blockData.thisVar != null) { + while (current != null && !(current instanceof PsiStatement)) { + current = current.getNextSibling(); + } + if (current == null) { + current = firstAdded; + } + thisVar = (PsiLocalVariable)((PsiDeclarationStatement)current).getDeclaredElements()[0]; + current = current.getNextSibling(); + } + for (int i = 0; i < parmVars.length; i++) { + final PsiElement oldCurrent = current; + while (current != null && !(current instanceof PsiStatement)) { + current = current.getNextSibling(); + } + if (current == null) { + current = oldCurrent; + } + parmVars[i] = (PsiLocalVariable)((PsiDeclarationStatement)current).getDeclaredElements()[0]; + current = current.getNextSibling(); + } + if (blockData.resultVar != null) { + final PsiElement oldCurrent = current; + while (current != null && !(current instanceof PsiStatement)) { + current = current.getNextSibling(); + } + if (current == null) { + current = oldCurrent; + } + resultVar = (PsiLocalVariable)((PsiDeclarationStatement)current).getDeclaredElements()[0]; + current = current.getNextSibling(); + } + } + + if (methodCall.getParent() instanceof PsiExpressionStatement) { + methodCall.getParent().delete(); + } + else { + if (blockData.resultVar != null) { + PsiExpression expr = myFactory.createExpressionFromText(blockData.resultVar.getName(), null); + methodCall.replace(expr); + } + else { + //?? + } + } + + PsiClass thisClass = myMethod.getContainingClass(); + PsiExpression thisAccessExpr = thisVar != null + ? myFactory.createExpressionFromText(thisVar.getName(), null) + : null; + ChangeContextUtil.decodeContextInfo(anchorParent, thisClass, thisAccessExpr); + + if (thisVar != null) { + inlineParmOrThisVariable(thisVar, false); + } + final PsiParameter[] parameters = myMethod.getParameterList().getParameters(); + for (int i = 0; i < parmVars.length; i++) { + final boolean strictlyFinal; + final PsiParameter parameter = parameters[i]; + if (parameter.hasModifierProperty(PsiModifier.FINAL)) { + strictlyFinal = isStrictlyFinal(parameter); + } + else { + strictlyFinal = false; + } + inlineParmOrThisVariable(parmVars[i], strictlyFinal); + } + if (resultVar != null) { + inlineResultVariable(resultVar); + } + + ChangeContextUtil.clearContextInfo(anchorParent); + } + + private void substituteMethodTypeParams(PsiCodeBlock block, PsiMethodCallExpression methodCall) { + ResolveResult resolveResult = methodCall.getMethodExpression().advancedResolve(false); + LOG.assertTrue (resolveResult.getElement() == myMethod); + if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) { + PsiTypeParameter[] oldTypeParameters = myMethod.getTypeParameterList().getTypeParameters(); + PsiTypeParameter[] newTypeParameters = myMethodCopy.getTypeParameterList().getTypeParameters(); + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + for (int i = 0; i < newTypeParameters.length; i++) { + substitutor = substitutor.put(newTypeParameters[i], resolveResult.getSubstitutor().substitute(oldTypeParameters[i])); + } + substituteMethodTypeParamsInner(block, substitutor); + } + } + + private void substituteMethodTypeParamsInner(PsiElement scope, final PsiSubstitutor substitutor) { + scope.accept(new PsiRecursiveElementVisitor() { + public void visitTypeElement(PsiTypeElement typeElement) { + PsiType type = typeElement.getType(); + + if (type instanceof PsiClassType) { + ResolveResult resolveResult = ((PsiClassType)type).resolveGenerics(); + PsiElement resolved = resolveResult.getElement(); + if (resolved instanceof PsiTypeParameter && ((PsiTypeParameter)resolved).getOwner() == myMethodCopy) { + PsiType newType = resolveResult.getSubstitutor().putAll(substitutor).substitute((PsiTypeParameter)resolved); + try { + typeElement.replace(myFactory.createTypeElement(newType)); + return; + } + catch (IncorrectOperationException e) { LOG.error(e); } + } + } + super.visitTypeElement(typeElement); + } + }); + } + + private boolean isStrictlyFinal(PsiParameter parameter) { + PsiSearchHelper searchHelper = myManager.getSearchHelper(); + final PsiReference[] references = searchHelper.findReferences(parameter, + GlobalSearchScope.projectScope(myProject), + false); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement refElement = reference.getElement(); + final PsiElement anonymousClass = PsiTreeUtil.getParentOfType(refElement, PsiAnonymousClass.class); + if (anonymousClass != null && PsiTreeUtil.isAncestor(myMethod, anonymousClass, true)) { + return true; + } + } + return false; + } + + + private boolean syncNeeded (final Object thisVar, final PsiReferenceExpression ref) { + if (thisVar == null) return false; + if (!myMethod.hasModifierProperty(PsiModifier.SYNCHRONIZED)) return false; + final PsiMethod containingMethod = Util.getContainingMethod(ref); + if (containingMethod == null) return true; + if (!containingMethod.hasModifierProperty(PsiModifier.SYNCHRONIZED)) return true; + final PsiClass sourceContainingClass = myMethod.getContainingClass(); + final PsiClass targetContainingClass = containingMethod.getContainingClass(); + if (sourceContainingClass.equals (targetContainingClass)) return false; + return true; + } + + private BlockData prepareBlock(PsiReferenceExpression ref) throws IncorrectOperationException { + ChangeContextUtil.encodeContextInfo(myMethod, false); + myMethodCopy = (PsiMethod)myMethod.copy(); + + ChangeContextUtil.clearContextInfo(myMethod); + final PsiCodeBlock block = myMethodCopy.getBody(); + final PsiStatement[] originalStatements = block.getStatements(); + + PsiLocalVariable resultVar = null; + PsiType returnType = myMethod.getReturnType(); + String resultName = null; + if (returnType != null && returnType != PsiType.VOID) { + resultName = myCodeStyleManager.propertyNameToVariableName("result", VariableKind.LOCAL_VARIABLE); + resultName = myCodeStyleManager.suggestUniqueVariableName(resultName, block.getFirstChild(), true); + PsiDeclarationStatement declaration = myFactory.createVariableDeclarationStatement(resultName, returnType, null); + declaration = (PsiDeclarationStatement)block.addAfter(declaration, null); + resultVar = (PsiLocalVariable)declaration.getDeclaredElements()[0]; + } + + PsiParameter[] parms = myMethodCopy.getParameterList().getParameters(); + PsiLocalVariable[] parmVars = new PsiLocalVariable[parms.length]; + for (int i = parms.length - 1; i >= 0; i--) { + PsiParameter parm = parms[i]; + String parmName = parm.getName(); + String name = parmName; + name = myCodeStyleManager.variableNameToPropertyName(name, VariableKind.PARAMETER); + name = myCodeStyleManager.propertyNameToVariableName(name, VariableKind.LOCAL_VARIABLE); + if (!name.equals(parmName)) { + name = myCodeStyleManager.suggestUniqueVariableName(name, block.getFirstChild(), true); + } + RefactoringUtil.renameVariableReferences(parm, name, GlobalSearchScope.projectScope(myProject)); + String defaultValue = CodeInsightUtil.getDefaultValueOfType(parm.getType()); + PsiExpression initializer = myFactory.createExpressionFromText(defaultValue, null); + PsiDeclarationStatement declaration = myFactory.createVariableDeclarationStatement(name, parm.getType(), + initializer); + declaration = (PsiDeclarationStatement)block.addAfter(declaration, null); + parmVars[i] = (PsiLocalVariable)declaration.getDeclaredElements()[0]; + if (parm.hasModifierProperty(PsiModifier.FINAL)) { + parmVars[i].getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + } + + PsiLocalVariable thisVar = null; + if (!myMethod.hasModifierProperty(PsiModifier.STATIC)) { + String thisVarName; + PsiClass containingClass = myMethod.getContainingClass(); + + if (containingClass != null) { + PsiType thisType = myFactory.createType(containingClass); + String[] names = myCodeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, thisType) + .names; + thisVarName = names[0]; + thisVarName = myCodeStyleManager.suggestUniqueVariableName(thisVarName, block.getFirstChild(), true); + PsiExpression initializer = myFactory.createExpressionFromText("null", null); + PsiDeclarationStatement declaration = myFactory.createVariableDeclarationStatement(thisVarName, thisType, + initializer); + declaration = (PsiDeclarationStatement)block.addAfter(declaration, null); + thisVar = (PsiLocalVariable)declaration.getDeclaredElements()[0]; + } + } + + //if (myMethod.hasModifierProperty(PsiModifier.SYNCHRONIZED) && thisVar != null) + if (syncNeeded (thisVar, ref)) { + PsiSynchronizedStatement synchronizedStatement = + (PsiSynchronizedStatement)myFactory.createStatementFromText("synchronized(" + thisVar.getName() + "){}", block); + synchronizedStatement = + (PsiSynchronizedStatement)CodeStyleManager.getInstance(myProject).reformat(synchronizedStatement); + synchronizedStatement = (PsiSynchronizedStatement)block.add(synchronizedStatement); + final PsiCodeBlock synchronizedBody = synchronizedStatement.getBody(); + for (int i = 0; i < originalStatements.length; i++) { + final PsiStatement originalStatement = originalStatements[i]; + synchronizedBody.add(originalStatement); + originalStatement.delete(); + } + } + + if (resultName != null) { + PsiReturnStatement[] returnStatements = RefactoringUtil.findReturnStatements(myMethodCopy); + for (int i = 0; i < returnStatements.length; i++) { + PsiReturnStatement returnStatement = returnStatements[i]; + if (returnStatement.getReturnValue() == null) continue; + PsiStatement statement = myFactory.createStatementFromText(resultName + "=0;", null); + statement = (PsiStatement)myCodeStyleManager.reformat(statement); + PsiAssignmentExpression assignment = (PsiAssignmentExpression)((PsiExpressionStatement)statement).getExpression(); + assignment.getRExpression().replace(returnStatement.getReturnValue()); + returnStatement.replace(statement); + } + } + + return new BlockData(block, thisVar, parmVars, resultVar); + } + + private void solveVariableNameConflicts(PsiElement scope, final PsiElement placeToInsert) + throws IncorrectOperationException { + if (scope instanceof PsiVariable) { + PsiVariable var = (PsiVariable)scope; + String name = var.getName(); + String oldName = name; + while (true) { + String newName = myCodeStyleManager.suggestUniqueVariableName(name, placeToInsert, true); + if (newName.equals(name)) break; + name = newName; + newName = myCodeStyleManager.suggestUniqueVariableName(name, var, true); + if (newName.equals(name)) break; + name = newName; + } + if (!name.equals(oldName)) { + RefactoringUtil.renameVariableReferences(var, name, GlobalSearchScope.projectScope(myProject)); + var.getNameIdentifier().replace(myFactory.createIdentifier(name)); + } + } + + PsiElement[] children = scope.getChildren(); + for (int i = 0; i < children.length; i++) { + solveVariableNameConflicts(children[i], placeToInsert); + } + } + + private void addParmAndThisVarInitializers(BlockData blockData, PsiMethodCallExpression methodCall) + throws IncorrectOperationException { + PsiExpression[] args = methodCall.getArgumentList().getExpressions(); + for (int i = 0; i < blockData.parmVars.length; i++) { + if (i >= args.length) break; + blockData.parmVars[i].getInitializer().replace(args[i]); + } + + if (blockData.thisVar != null) { + PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); + if (qualifier == null) { + PsiElement parent = methodCall.getParent(); + while (true) { + if (parent instanceof PsiClass) break; + if (parent instanceof PsiFile) break; + parent = parent.getParent(); + } + if (parent instanceof PsiClass) { + final PsiClass parentClass = (PsiClass) parent; + final PsiClass containingClass = myMethod.getContainingClass(); + if (InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) { + qualifier = myFactory.createExpressionFromText("this", null); + } + else { + String name = containingClass.getName(); + if (name != null) { + qualifier = myFactory.createExpressionFromText(name + ".this", null); + } + else { //? + qualifier = myFactory.createExpressionFromText("this", null); + } + } + } + else { + qualifier = myFactory.createExpressionFromText("this", null); + } + } else if (qualifier instanceof PsiSuperExpression) { + qualifier = myFactory.createExpressionFromText("this", null); + } + blockData.thisVar.getInitializer().replace(qualifier); + } + } + + private void inlineParmOrThisVariable(PsiLocalVariable variable, boolean strictlyFinal) + throws IncorrectOperationException { + PsiReference[] refs = myManager.getSearchHelper().findReferences(variable, + GlobalSearchScope.projectScope(myProject), + false); + + if (refs.length == 0) { + variable.getParent().delete(); //Q: side effects? + return; + } + + + boolean isAccessedForWriting = false; + for (int i = 0; i < refs.length; i++) { + PsiElement refElement = refs[i].getElement(); + if (refElement instanceof PsiExpression) { + if (PsiUtil.isAccessedForWriting(((PsiExpression)refElement))) { + isAccessedForWriting = true; + } + } + } + + PsiExpression initializer = variable.getInitializer(); + boolean shouldBeFinal = variable.hasModifierProperty(PsiModifier.FINAL) && strictlyFinal; + if (canInlineParmOrThisVariable(initializer, shouldBeFinal, strictlyFinal, refs.length, isAccessedForWriting)) { + if (shouldBeFinal) { + declareUsedLocalsFinal(initializer, strictlyFinal); + } + for (int j = 0; j < refs.length; j++) { + PsiExpression expr = RefactoringUtil.inlineVariable(variable, initializer, + (PsiJavaCodeReferenceElement)refs[j]); + + //Q: move the following code to some util? (addition to inline?) + if (expr instanceof PsiThisExpression) { + if (expr.getParent() instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)expr.getParent(); + PsiElement refElement = refExpr.resolve(); + PsiExpression exprCopy = (PsiExpression)refExpr.copy(); + refExpr = + (PsiReferenceExpression)refExpr.replace( + myFactory.createExpressionFromText(refExpr.getReferenceName(), null)); + if (refElement != null) { + PsiElement newRefElement = refExpr.resolve(); + if (!refElement.equals(newRefElement)) { + // change back + refExpr = (PsiReferenceExpression)refExpr.replace(exprCopy); + } + } + } + } + } + variable.getParent().delete(); + } + } + + private boolean canInlineParmOrThisVariable(PsiExpression initializer, + boolean shouldBeFinal, + boolean strictlyFinal, + int accessCount, + boolean isAccessedForWriting) { + if (strictlyFinal) { + class CanAllLocalsBeDeclaredFinal extends PsiRecursiveElementVisitor { + boolean success = true; + + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiElement psiElement = expression.resolve(); + if (psiElement instanceof PsiLocalVariable || psiElement instanceof PsiParameter) { + if (!RefactoringUtil.canBeDeclaredFinal((PsiVariable)psiElement)) { + success = false; + } + } + } + + public void visitElement(PsiElement element) { + if (success) { + super.visitElement(element); + } + } + } + + final CanAllLocalsBeDeclaredFinal canAllLocalsBeDeclaredFinal = new CanAllLocalsBeDeclaredFinal(); + initializer.accept(canAllLocalsBeDeclaredFinal); + if (!canAllLocalsBeDeclaredFinal.success) return false; + } + if (initializer instanceof PsiReferenceExpression) { + PsiVariable refVar = (PsiVariable)((PsiReferenceExpression)initializer).resolve(); + if (refVar == null) { + return !isAccessedForWriting; + } + if (refVar instanceof PsiField) { + if (isAccessedForWriting) return false; + /* + PsiField field = (PsiField)refVar; + if (isFieldNonModifiable(field)){ + return true; + } + //TODO: other cases + return false; + */ + return true; //TODO: "suspicous" places to review by user! + } + else { + if (isAccessedForWriting) { + if (refVar.hasModifierProperty(PsiModifier.FINAL) || shouldBeFinal) return false; + PsiReference[] refs = myManager.getSearchHelper().findReferences(refVar, + GlobalSearchScope.projectScope( + myProject), + false); + return refs.length == 1; //TODO: control flow + } + else { + if (shouldBeFinal) { + if (refVar.hasModifierProperty(PsiModifier.FINAL)) return true; + return RefactoringUtil.canBeDeclaredFinal(refVar); + } + return true; + } + } + } + else if (isAccessedForWriting) { + return false; + } + else if (initializer instanceof PsiCallExpression) { + if (accessCount > 1) return false; + final PsiExpressionList argumentList = ((PsiCallExpression)initializer).getArgumentList(); + if (argumentList == null) return false; + final PsiExpression[] expressions = argumentList.getExpressions(); + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; + if (!canInlineParmOrThisVariable(expression, shouldBeFinal, strictlyFinal, accessCount, false)) { + return false; + } + } + return true; //TODO: "suspicous" places to review by user! + } + else if (initializer instanceof PsiLiteralExpression) { + return true; + } + else if (initializer instanceof PsiArrayAccessExpression) { + final PsiExpression arrayExpression = ((PsiArrayAccessExpression)initializer).getArrayExpression(); + final PsiExpression indexExpression = ((PsiArrayAccessExpression)initializer).getIndexExpression(); + return canInlineParmOrThisVariable(arrayExpression, shouldBeFinal, strictlyFinal, accessCount, false) + && canInlineParmOrThisVariable(indexExpression, shouldBeFinal, strictlyFinal, accessCount, false); + } + else if (initializer instanceof PsiParenthesizedExpression) { + PsiExpression expr = ((PsiParenthesizedExpression)initializer).getExpression(); + if (expr == null) return true; + return canInlineParmOrThisVariable(expr, shouldBeFinal, strictlyFinal, accessCount, false); + } + else if (initializer instanceof PsiTypeCastExpression) { + PsiExpression operand = ((PsiTypeCastExpression)initializer).getOperand(); + if (operand == null) return false; + return canInlineParmOrThisVariable(operand, shouldBeFinal, strictlyFinal, accessCount, false); + } + else if (initializer instanceof PsiBinaryExpression) { + PsiBinaryExpression binExpr = (PsiBinaryExpression)initializer; + PsiExpression lOperand = binExpr.getLOperand(); + PsiExpression rOperand = binExpr.getROperand(); + if (rOperand == null) return false; + return canInlineParmOrThisVariable(lOperand, shouldBeFinal, strictlyFinal, accessCount, false) + && canInlineParmOrThisVariable(rOperand, shouldBeFinal, strictlyFinal, accessCount, false); + } + else if (initializer instanceof PsiClassObjectAccessExpression) { + return true; + } + else if (initializer instanceof PsiThisExpression) { + return true; + } + else if (initializer instanceof PsiSuperExpression) { + return true; + } + else { + return false; + } + } + + private void declareUsedLocalsFinal(PsiElement expr, boolean strictlyFinal) throws IncorrectOperationException { + if (expr instanceof PsiReferenceExpression) { + PsiElement refElement = ((PsiReferenceExpression)expr).resolve(); + if (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) { + if (strictlyFinal || RefactoringUtil.canBeDeclaredFinal((PsiVariable)refElement)) { + ((PsiVariable)refElement).getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + } + } + PsiElement[] children = expr.getChildren(); + for (int i = 0; i < children.length; i++) { + declareUsedLocalsFinal(children[i], strictlyFinal); + } + } + + /* + private boolean isFieldNonModifiable(PsiField field) { + if (field.hasModifierProperty(PsiModifier.FINAL)){ + return true; + } + PsiElement[] refs = myManager.getSearchHelper().findReferences(field, null, false); + for(int i = 0; i < refs.length; i++){ + PsiReferenceExpression ref = (PsiReferenceExpression)refs[i]; + if (PsiUtil.isAccessedForWriting(ref)) { + PsiElement container = ref.getParent(); + while(true){ + if (container instanceof PsiMethod || + container instanceof PsiField || + container instanceof PsiClassInitializer || + container instanceof PsiFile) break; + container = container.getParent(); + } + if (container instanceof PsiMethod && ((PsiMethod)container).isConstructor()) continue; + return false; + } + } + return true; + } + */ + + private void inlineResultVariable(PsiVariable resultVar) throws IncorrectOperationException { + PsiReference[] refs = myManager.getSearchHelper().findReferences(resultVar, + GlobalSearchScope.projectScope(myProject), + false); + PsiAssignmentExpression assignment = null; + boolean isAssignmentUnique = false; + PsiReferenceExpression resultUsage = null; + for (int i = 0; i < refs.length; i++) { + PsiReferenceExpression ref = (PsiReferenceExpression)refs[i]; + if (ref.getParent() instanceof PsiAssignmentExpression + && ((PsiAssignmentExpression)ref.getParent()).getLExpression().equals(ref)) { + if (assignment != null) { + isAssignmentUnique = false; + } + else { + assignment = (PsiAssignmentExpression)ref.getParent(); + isAssignmentUnique = true; + } + } + else { + LOG.assertTrue(resultUsage == null); + resultUsage = ref; + } + } + + if (!isAssignmentUnique) return; + boolean condition = assignment.getParent() instanceof PsiExpressionStatement; + LOG.assertTrue(condition); + // SCR3175 fixed: inline only if declaration and assignment is in the same code block. + if (!(assignment.getParent().getParent() == resultVar.getParent().getParent())) return; + if (resultUsage != null) { + String name = resultVar.getName(); + PsiDeclarationStatement declaration = myFactory.createVariableDeclarationStatement( + name, resultVar.getType(), assignment.getRExpression()); + declaration = (PsiDeclarationStatement)assignment.getParent().replace(declaration); + resultVar.getParent().delete(); + resultVar = (PsiVariable)declaration.getDeclaredElements()[0]; + + PsiElement parentStatement = RefactoringUtil.getParentStatement(resultUsage, true); + PsiElement next = declaration.getNextSibling(); + boolean canInline = false; + while (true) { + if (next == null) break; + if (parentStatement.equals(next)) { + canInline = true; + break; + } + if (next instanceof PsiStatement) break; + next = next.getNextSibling(); + } + + if (canInline) { + final PsiExpression initializer = resultVar.getInitializer(); + final PsiClass thisClass = ChangeContextUtil.getThisClass(initializer); + ChangeContextUtil.encodeContextInfo(initializer, false); + final PsiElement element = resultUsage.replace(resultVar.getInitializer()); + ChangeContextUtil.decodeContextInfo(element, thisClass, + element.getManager().getElementFactory().createExpressionFromText("this", + null)); + declaration.delete(); + } + } + else { + PsiExpression expr = (PsiExpression)assignment.replace(assignment.getRExpression()); + resultVar.getParent().delete(); + if (expr.getParent() instanceof PsiExpressionStatement && isSimpleExpression(expr)) { + expr.getParent().delete(); + } + } + } + + private boolean isSimpleExpression(PsiExpression expr) { + if (expr instanceof PsiLiteralExpression) { + return true; + } + else if (expr instanceof PsiReferenceExpression) { + PsiExpression qualifier = ((PsiReferenceExpression)expr).getQualifierExpression(); + return qualifier == null || isSimpleExpression(qualifier); + } + else if (expr instanceof PsiArrayAccessExpression) { + PsiArrayAccessExpression accessExpr = (PsiArrayAccessExpression)expr; + return isSimpleExpression(accessExpr.getArrayExpression()) && + isSimpleExpression(accessExpr.getIndexExpression()); + } + else if (expr instanceof PsiBinaryExpression) { + PsiBinaryExpression binExpr = (PsiBinaryExpression)expr; + PsiExpression lOperand = binExpr.getLOperand(); + PsiExpression rOperand = binExpr.getROperand(); + if (rOperand == null) return false; + return isSimpleExpression(lOperand) && isSimpleExpression(rOperand); + } + else if (expr instanceof PsiClassObjectAccessExpression) { + return true; + } + else if (expr instanceof PsiThisExpression) { + return true; + } + else if (expr instanceof PsiSuperExpression) { + return true; + } + else if (expr instanceof PsiTypeCastExpression) { + PsiExpression operand = ((PsiTypeCastExpression)expr).getOperand(); + if (operand == null) return false; + return isSimpleExpression(operand); + } + else { //TODO: some other cases + return false; + } + } + + private static final Key MARK_KEY = Key.create(""); + + private PsiReferenceExpression[] addBracesWhenNeeded(PsiReferenceExpression[] refs) + throws IncorrectOperationException { + ArrayList refsVector = new ArrayList(); + ArrayList addedBracesVector = new ArrayList(); + myAddedClassInitializers = new HashMap(); + + for (int i = 0; i < refs.length; i++) { + refs[i].putCopyableUserData(MARK_KEY, ""); + } + + RefLoop: + for (int i = 0; i < refs.length; i++) { + PsiReferenceExpression ref = refs[i]; + if (!ref.isValid()) continue; + + PsiElement parentStatement = RefactoringUtil.getParentStatement(ref, true); + if (parentStatement != null) { + PsiElement parent = ref.getParent(); + while (!parent.equals(parentStatement)) { + if (parent instanceof PsiStatement && !(parent instanceof PsiDeclarationStatement)) { + String text = "{\n}"; + PsiBlockStatement blockStatement = (PsiBlockStatement)myFactory.createStatementFromText(text, null); + blockStatement = (PsiBlockStatement)myCodeStyleManager.reformat(blockStatement); + blockStatement = (PsiBlockStatement)parent.getParent().addAfter(blockStatement, parent); + + PsiCodeBlock body = blockStatement.getCodeBlock(); + PsiElement newStatement = body.add(parent); + parent.delete(); + addMarkedElements(refsVector, newStatement); + addedBracesVector.add(blockStatement); + continue RefLoop; + } + parent = parent.getParent(); + } + } else { + final PsiField field = PsiTreeUtil.getParentOfType(ref, PsiField.class); + if (field != null) { + field.normalizeDeclaration(); + final PsiExpression initializer = field.getInitializer(); + LOG.assertTrue(initializer != null); + PsiClassInitializer classInitializer = myFactory.createClassInitializer(); + final PsiClass containingClass = field.getContainingClass(); + classInitializer = (PsiClassInitializer)containingClass.addAfter(classInitializer, field); + final PsiCodeBlock body = classInitializer.getBody(); + PsiExpressionStatement statement = (PsiExpressionStatement)myFactory.createStatementFromText(field.getName() + " = 0;", body); + statement = (PsiExpressionStatement)body.add(statement); + final PsiAssignmentExpression assignment = (PsiAssignmentExpression)statement.getExpression(); + assignment.getLExpression().replace(RenameUtil.createFieldReference(field, assignment)); + assignment.getRExpression().replace(initializer); + addMarkedElements(refsVector, statement); + if (field.hasModifierProperty(PsiModifier.STATIC)) { + classInitializer.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + myAddedClassInitializers.put(field, classInitializer); + continue RefLoop; + } + } + + refsVector.add(ref); + } + + for (int i = 0; i < refs.length; i++) { + refs[i].putCopyableUserData(MARK_KEY, null); + } + + myAddedBraces = addedBracesVector.toArray(new PsiBlockStatement[addedBracesVector.size()]); + return refsVector.toArray(new PsiReferenceExpression[refsVector.size()]); + } + + private void addMarkedElements(ArrayList array, PsiElement scope) { + if (scope.getCopyableUserData(MARK_KEY) != null) { + array.add(scope); + scope.putCopyableUserData(MARK_KEY, null); + } + for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) { + addMarkedElements(array, child); + } + } + + private void removeAddedBracesWhenPossible() throws IncorrectOperationException { + if (myAddedBraces == null) return; + + for (int i = 0; i < myAddedBraces.length; i++) { + PsiBlockStatement blockStatement = myAddedBraces[i]; + PsiStatement[] statements = blockStatement.getCodeBlock().getStatements(); + if (statements.length == 1) { + blockStatement.replace(statements[0]); + } + } + + final Set fields = myAddedClassInitializers.keySet(); + for (Iterator iterator = fields.iterator(); iterator.hasNext();) { + PsiField psiField = iterator.next(); + final PsiClassInitializer classInitializer = myAddedClassInitializers.get(psiField); + final PsiExpression initializer = getSimpleFieldInitializer(psiField, classInitializer); + if (initializer != null) { + psiField.getInitializer().replace(initializer); + classInitializer.delete(); + } else { + psiField.getInitializer().delete(); + } + } + } + + private PsiExpression getSimpleFieldInitializer(PsiField field, PsiClassInitializer initializer) { + final PsiStatement[] statements = initializer.getBody().getStatements(); + if (statements.length != 1) return null; + if (!(statements[0] instanceof PsiExpressionStatement)) return null; + final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); + if (!(expression instanceof PsiAssignmentExpression)) return null; + final PsiExpression lExpression = ((PsiAssignmentExpression)expression).getLExpression(); + if (!(lExpression instanceof PsiReferenceExpression)) return null; + final PsiElement resolved = ((PsiReferenceExpression)lExpression).resolve(); + if (!myManager.areElementsEquivalent(field, resolved)) return null; + return ((PsiAssignmentExpression)expression).getRExpression(); + } + + public static boolean checkBadReturns(PsiMethod method) { + PsiReturnStatement[] returns = RefactoringUtil.findReturnStatements(method); + if (returns.length == 0) return false; + PsiCodeBlock body = method.getBody(); + ControlFlow controlFlow; + try { + controlFlow = new ControlFlowAnalyzer(body, new LocalsControlFlowPolicy(body), false).buildControlFlow(); + } + catch (ControlFlowAnalyzer.AnalysisCanceledException e) { + return false; + } + if (LOG.isDebugEnabled()) { + LOG.debug("Control flow:"); + LOG.debug(controlFlow.toString()); + } + + Instruction[] instructions = controlFlow.getInstructions(); + + // temporary replace all return's with empty statements in the flow + for (int i = 0; i < returns.length; i++) { + PsiReturnStatement aReturn = returns[i]; + int offset = controlFlow.getStartOffset(aReturn); + int endOffset = controlFlow.getEndOffset(aReturn); + while (offset <= endOffset && !(instructions[offset] instanceof GoToInstruction)) { + offset++; + } + LOG.assertTrue(instructions[offset] instanceof GoToInstruction); + instructions[offset] = new EmptyInstruction(); + } + + for (int i = 0; i < returns.length; i++) { + PsiReturnStatement aReturn = returns[i]; + int offset = controlFlow.getEndOffset(aReturn); + while (true) { + if (offset == instructions.length) break; + Instruction instruction = instructions[offset]; + if ((instruction instanceof GoToInstruction)) { + offset = ((GoToInstruction)instruction).offset; + } + else if (instruction instanceof ThrowToInstruction) { + offset = ((ThrowToInstruction)instruction).offset; + } + else if (instruction instanceof ConditionalThrowToInstruction) { + // In case of "conditional throw to", control flow will not be altered + // If exception handler is in method, we will inline it to ivokation site + // If exception handler is at invocation site, execution will continue to get there + offset++; + } + else { + return true; + } + } + } + + return false; + } + + private static class BlockData { + final PsiCodeBlock block; + final PsiLocalVariable thisVar; + final PsiLocalVariable[] parmVars; + final PsiLocalVariable resultVar; + + public BlockData(PsiCodeBlock block, + PsiLocalVariable thisVar, + PsiLocalVariable[] parmVars, + PsiLocalVariable resultVar) { + this.block = block; + this.thisVar = thisVar; + this.parmVars = parmVars; + this.resultVar = resultVar; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineOptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineOptions.java new file mode 100644 index 00000000000..d59bb391f05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineOptions.java @@ -0,0 +1,11 @@ +package com.intellij.refactoring.inline; + +/** + * @author dyoma + */ +public interface InlineOptions { + boolean isInlineThisOnly(); + void close(int exitCode); + + boolean isPreviewUsages(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineViewDescriptor.java new file mode 100644 index 00000000000..d0a898b6d56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/InlineViewDescriptor.java @@ -0,0 +1,104 @@ + +package com.intellij.refactoring.inline; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class InlineViewDescriptor implements UsageViewDescriptor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineViewDescriptor"); + + private PsiElement myElement; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public InlineViewDescriptor(PsiElement element, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myElement = element; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public PsiElement[] getElements() { + return new PsiElement[] {myElement}; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + if (elements.length == 1) { + if (elements[0] instanceof PsiMethod && myElement instanceof PsiMethod) { + myElement = elements[0]; + } else if (elements[0] instanceof PsiField && myElement instanceof PsiField) { + myElement = elements[0]; + } else { + LOG.assertTrue(false); + } + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myElement instanceof PsiMethod ? "Method" : "Field" + " to inline"; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return INVOCATION_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "Invocations to be inlined " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "invocation"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/ReferencedElementsCollector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/ReferencedElementsCollector.java new file mode 100644 index 00000000000..5628face6f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/inline/ReferencedElementsCollector.java @@ -0,0 +1,23 @@ +package com.intellij.refactoring.inline; + +import com.intellij.psi.*; + +import java.util.HashSet; + +/** + * @author ven + */ +class ReferencedElementsCollector extends PsiRecursiveElementVisitor { + HashSet myReferencedMembers = new HashSet(); + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + final PsiElement psiElement = reference.resolve(); + if (psiElement instanceof PsiMember) { + myReferencedMembers.add((PsiMember)psiElement); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java new file mode 100644 index 00000000000..d25898c7b29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -0,0 +1,530 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 29.05.2002 + * Time: 13:05:34 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.IntroduceHandlerBase; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.occurences.OccurenceManager; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler"); + public static final int IN_CURRENT_METHOD = 1; + public static final int IN_FIELD_DECLARATION = 2; + public static final int IN_CONSTRUCTOR = 3; + private PsiClass myParentClass; + + protected boolean invokeImpl(final Project project, final PsiExpression selectedExpr, final Editor editor) { + LOG.assertTrue(selectedExpr != null); + final PsiFile file = selectedExpr.getContainingFile(); + LOG.assertTrue(file != null, "expr.getContainingFile() == null"); + + if (LOG.isDebugEnabled()) { + LOG.debug("expression:" + selectedExpr); + } + + myParentClass = getParentClass(selectedExpr); + if (myParentClass == null) { + if (file instanceof JspFile) { + RefactoringMessageUtil.showErrorMessage(getRefactoringName(), + getRefactoringName() + " refactoring is not supported for JSP", getHelpID(), project + ); + return false; + } + else { + LOG.assertTrue(false); + return false; + } + } + + if (!validClass(myParentClass)) { + return false; + } + + PsiType tempType = getTypeByExpression(selectedExpr); + if (tempType == null) { + String message = + "Cannot perform the refactoring.\n" + + "Unknown expression type."; + RefactoringMessageUtil.showErrorMessage(getRefactoringName(), message, getHelpID(), project); + return false; + } + + if (tempType == PsiType.VOID) { + String message = + "Cannot perform the refactoring.\n" + + "Selected expression has void type."; + RefactoringMessageUtil.showErrorMessage(getRefactoringName(), message, getHelpID(), project); + return false; + } + + PsiElement tempAnchorElement = RefactoringUtil.getParentExpressionAnchorElement(selectedExpr); + if (tempAnchorElement == null) { + //TODO : work outside code block (e.g. field initializer) + String message = getRefactoringName() + " refactoring is not supported in the current context"; + RefactoringMessageUtil.showErrorMessage(getRefactoringName(), message, getHelpID(), project); + return false; + } + + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return false; + } + + final PsiClass parentClass = myParentClass; + final OccurenceManager occurenceManager = createOccurenceManager(selectedExpr, parentClass); + final PsiExpression[] occurrences = occurenceManager.getOccurences(); + final PsiElement anchorStatementIfAll = occurenceManager.getAnchorStatementForAll(); + + ArrayList highlighters = null; + if (editor != null) { + final HighlightManager highlightManager; + highlighters = new ArrayList(); + highlightManager = HighlightManager.getInstance(project); + if (occurrences.length > 1) { + highlightManager.addOccurrenceHighlights(editor, occurrences, highlightAttributes(), true, highlighters); + } + } + + + final Settings settings = + showRefactoringDialog(project, myParentClass, selectedExpr, tempType, + occurrences, tempAnchorElement, anchorStatementIfAll + ); + + if (settings == null) return false; + + if (settings.getForcedType() != null) { + tempType = settings.getForcedType(); + } + final PsiType type = tempType; + + final String fieldName = settings.getFieldName(); + final PsiElement anchorElementIfOne = tempAnchorElement; + final boolean replaceAll = settings.isReplaceAll(); + if (replaceAll) { + tempAnchorElement = anchorStatementIfAll; + } + final PsiElement anchorElement = tempAnchorElement; + + + if (editor != null) { + HighlightManager highlightManager = HighlightManager.getInstance(project); + for (int i = 0; i < highlighters.size(); i++) { + RangeHighlighter highlighter = highlighters.get(i); + highlightManager.removeSegmentHighlighter(editor, highlighter); + } + } + + PsiElement anchor = getNormalizedAnchor(anchorElement); + + boolean tempDeleteSelf = false; + if (selectedExpr.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorElement)) { + PsiStatement statement = (PsiStatement)selectedExpr.getParent(); + if (statement.getParent() instanceof PsiCodeBlock) { + tempDeleteSelf = true; + } + } + final boolean deleteSelf = tempDeleteSelf; + /* + int col = editor.getCaretColumnNumber(); + int line = editor.getCaretLineNumber(); + if (deleteSelf){ + editor.moveCaret(0, 0); // this prevents autoscrolling + } + */ + + final Runnable runnable = new Runnable() { + public void run() { + try { + PsiExpression expr = selectedExpr; + int initializerPlace = settings.getInitializerPlace(); + final PsiLocalVariable localVariable = settings.getLocalVariable(); + final boolean deleteLocalVariable = settings.isDeleteLocalVariable(); + PsiExpression initializer; + if (localVariable != null) { + initializer = localVariable.getInitializer(); + } + else { + initializer = expr; + } + + final PsiMethod enclosingConstructor = getEnclosingConstructor(myParentClass, anchorElement); + final PsiClass destClass = settings.getDestinationClass() == null ? myParentClass : settings.getDestinationClass(); + + if (!destClass.getContainingFile().isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, destClass.getContainingFile()); + return; + } + + PsiField field = createField(fieldName, type, initializer, + initializerPlace == IN_FIELD_DECLARATION && initializer != null + ); + field.getModifierList().setModifierProperty(settings.getFieldVisibility(), true); + if (settings.isDeclareFinal()) { + field.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + if (settings.isDeclareStatic()) { + field.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + PsiElement finalAnchorElement = null; + if (destClass == myParentClass) { + for (finalAnchorElement = anchorElement; + finalAnchorElement != null && finalAnchorElement.getParent() != destClass; + finalAnchorElement = finalAnchorElement.getParent()); + } + PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? ((PsiMember)finalAnchorElement) : null; + + if ((anchorMember instanceof PsiField || anchorMember instanceof PsiClassInitializer) && + anchorMember.hasModifierProperty(PsiModifier.STATIC) == field.hasModifierProperty(PsiModifier.STATIC)) { + field = (PsiField)destClass.addBefore(field, anchorMember); + } + else { + field = (PsiField)destClass.add(field); + } + PsiStatement assignStatement; + if ((initializerPlace == IN_CURRENT_METHOD && initializer != null) + || (initializerPlace == IN_CONSTRUCTOR && enclosingConstructor != null && initializer != null)) { + final PsiElement anchorElementHere; + if (replaceAll) { + if (enclosingConstructor != null) { + final PsiElement anchorInConstructor = occurenceManager.getAnchorStatementForAllInScope(enclosingConstructor); + anchorElementHere = anchorInConstructor != null ? anchorInConstructor : anchorStatementIfAll; + } else { + anchorElementHere = anchorStatementIfAll; + } + } + else { + anchorElementHere = anchorElementIfOne; + } + assignStatement = createAssignment(field, initializer, anchorElementHere); + anchorElementHere.getParent().addBefore(assignStatement, getNormalizedAnchor(anchorElementHere)); + } + if (initializerPlace == IN_CONSTRUCTOR && initializer != null) { + addInitializationToConstructors(initializer, field, enclosingConstructor); + } + if (expr.getParent() instanceof PsiParenthesizedExpression) { + expr = (PsiExpression)expr.getParent(); + } + if (deleteSelf) { + PsiStatement statement = (PsiStatement)expr.getParent(); + statement.delete(); + } + + if (replaceAll) { + List array = new ArrayList(); + for (int i = 0; i < occurrences.length; i++) { + PsiExpression occurrence = occurrences[i]; + if (occurrence instanceof PsiExpression) { + occurrence = RefactoringUtil.outermostParenthesizedExpression(occurrence); + } + if (deleteSelf && occurrence.equals(expr)) continue; + array.add(RefactoringUtil.replaceOccurenceWithFieldRef(occurrence, field, destClass)); + } + + if (editor != null) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { + PsiElement[] exprsToHighlight = array.toArray(new PsiElement[array.size()]); + HighlightManager highlightManager = HighlightManager.getInstance(project); + highlightManager.addOccurrenceHighlights(editor, exprsToHighlight, highlightAttributes(), true, null); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + } + } + else { + if (!deleteSelf) { + expr = RefactoringUtil.outermostParenthesizedExpression(expr); + RefactoringUtil.replaceOccurenceWithFieldRef(expr, field, destClass); + } + } + + + if (localVariable != null) { + if (deleteLocalVariable) { + localVariable.normalizeDeclaration(); + localVariable.getParent().delete(); + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + + CommandProcessor.getInstance().executeCommand( + project, + new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, + getRefactoringName(), null + ); + + return true; + } + + private TextAttributes highlightAttributes() { + return EditorColorsManager.getInstance().getGlobalScheme().getAttributes( + EditorColors.SEARCH_RESULT_ATTRIBUTES + ); + } + + protected abstract OccurenceManager createOccurenceManager(PsiExpression selectedExpr, PsiClass parentClass); + + protected final PsiClass getParentClass() { + return myParentClass; + } + + abstract protected boolean validClass(PsiClass parentClass); + + protected boolean isStaticField() { + return false; + } + + private PsiElement getNormalizedAnchor(PsiElement anchorElement) { + PsiElement child = anchorElement; + while (child != null) { + PsiElement prev = child.getPrevSibling(); + if (RefactoringUtil.isExpressionAnchorElement(prev)) break; + if (prev instanceof PsiJavaToken && ((PsiJavaToken)prev).getTokenType() == JavaTokenType.LBRACE) break; + child = prev; + } + + child = PsiTreeUtil.skipSiblingsForward(child, new Class[] {PsiWhiteSpace.class, PsiComment.class}); + PsiElement anchor; + if (child != null) { + anchor = child; + } + else { + anchor = anchorElement; + } + return anchor; + } + + protected abstract String getHelpID(); + + protected abstract Settings showRefactoringDialog(Project project, PsiClass parentClass, PsiExpression expr, + PsiType type, PsiExpression[] occurences, PsiElement anchorElement, + PsiElement anchorElementIfAll); + + + private PsiType getTypeByExpression(PsiExpression expr) { + return RefactoringUtil.getTypeByExpressionWithExpectedType(expr); + } + + public PsiClass getParentClass(PsiExpression initializerExpression) { + PsiElement parent = initializerExpression.getParent(); + while (parent != null) { + if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { + return (PsiClass)parent; + } + parent = parent.getParent(); + } + return null; + } + + public static PsiMethod getEnclosingConstructor(PsiClass parentClass, PsiElement element) { + if (element == null) return null; + final PsiMethod[] constructors = parentClass.getConstructors(); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + if (PsiTreeUtil.isAncestor(constructor, element, false)) return constructor; + } + return null; + } + + private void addInitializationToConstructors(PsiExpression initializerExpression, PsiField field, PsiMethod enclosingConstructor) { + try { + PsiClass aClass = field.getContainingClass(); + PsiMethod[] constructors = aClass.getConstructors(); + + boolean added = false; + for (int idx = 0; idx < constructors.length; idx++) { + PsiMethod constructor = constructors[idx]; + if (constructor == enclosingConstructor) continue; + PsiCodeBlock body = constructor.getBody(); + if (body == null) continue; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + String text = ((PsiMethodCallExpression)expression).getMethodExpression().getText(); + if ("this".equals(text)) { + continue; + } + } + } + } + PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild()); + body.add(assignment); + added = true; + } + if (!added && enclosingConstructor == null) { + PsiElementFactory factory = field.getManager().getElementFactory(); + PsiMethod constructor = factory.createConstructor(); + final PsiCodeBlock body = constructor.getBody(); + PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild()); + body.add(assignment); + aClass.add(constructor); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private PsiField createField(String fieldName, PsiType type, PsiExpression initializerExpr, boolean includeInitializer) { + StringBuffer pattern = new StringBuffer(); + pattern.append("private int "); + pattern.append(fieldName); + if (includeInitializer) { + pattern.append("=0"); + } + pattern.append(";"); + PsiManager psiManager = myParentClass.getManager(); + PsiElementFactory factory = psiManager.getElementFactory(); + try { + PsiField field = factory.createFieldFromText(pattern.toString(), null); + field = (PsiField)CodeStyleManager.getInstance(psiManager.getProject()).reformat(field); + field.getTypeElement().replace(factory.createTypeElement(type)); + if (includeInitializer) { + field.getInitializer().replace(initializerExpr); + } + return field; + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + private PsiStatement createAssignment(PsiField field, PsiExpression initializerExpr, PsiElement context) { + try { + String pattern = "x=0;"; + PsiManager psiManager = myParentClass.getManager(); + PsiElementFactory factory = psiManager.getElementFactory(); + PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null); + statement = (PsiExpressionStatement)CodeStyleManager.getInstance(psiManager.getProject()).reformat(statement); + + PsiAssignmentExpression expr = (PsiAssignmentExpression)statement.getExpression(); + expr.getRExpression().replace(initializerExpr); + final PsiReferenceExpression fieldReference = RenameUtil.createFieldReference(field, context); + expr.getLExpression().replace(fieldReference); + + return statement; + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + protected abstract String getRefactoringName(); + + public boolean startInWriteAction() { + return false; + } + + public static class Settings { + private final String myFieldName; + private final PsiType myForcedType; + + private boolean myReplaceAll; + private final boolean myDeclareStatic; + private final boolean myDeclareFinal; + private final int myInitializerPlace; + private final String myVisibility; + private final boolean myDeleteLocalVariable; + private final PsiClass myTargetClass; + + public PsiLocalVariable getLocalVariable() { + return myLocalVariable; + } + + public boolean isDeleteLocalVariable() { + return myDeleteLocalVariable; + } + + private final PsiLocalVariable myLocalVariable; + + public String getFieldName() { + return myFieldName; + } + + public boolean isDeclareStatic() { + return myDeclareStatic; + } + + public boolean isDeclareFinal() { + return myDeclareFinal; + } + + public int getInitializerPlace() { + return myInitializerPlace; + } + + public String getFieldVisibility() { + return myVisibility; + } + + public PsiClass getDestinationClass() { return myTargetClass; } + + public PsiType getForcedType() { + return myForcedType; + } + + public boolean isReplaceAll() { + return myReplaceAll; + } + + public Settings(String fieldName, boolean replaceAll, + boolean declareStatic, boolean declareFinal, + int initializerPlace, String visibility, PsiLocalVariable localVariableToRemove, PsiType forcedType, + boolean deleteLocalVariable, PsiClass targetClass) { + + myFieldName = fieldName; + myReplaceAll = replaceAll; + myDeclareStatic = declareStatic; + myDeclareFinal = declareFinal; + myInitializerPlace = initializerPlace; + myVisibility = visibility; + myLocalVariable = localVariableToRemove; + myDeleteLocalVariable = deleteLocalVariable; + myForcedType = forcedType; + myTargetClass = targetClass; + } + + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/ElementToWorkOn.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/ElementToWorkOn.java new file mode 100644 index 00000000000..89adf3401ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/ElementToWorkOn.java @@ -0,0 +1,86 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +/** + * @author dsl + */ +public class ElementToWorkOn { + private final PsiExpression myExpression; + private final PsiLocalVariable myLocalVariable; + + private ElementToWorkOn(PsiLocalVariable localVariable, PsiExpression expr) { + myLocalVariable = localVariable; + myExpression = expr; + } + + public PsiExpression getExpression() { + return myExpression; + } + + public PsiLocalVariable getLocalVariable() { + return myLocalVariable; + } + + public boolean isInvokedOnDeclaration() { + return myExpression == null; + } + + public static ElementToWorkOn getElementToWorkOn(Editor editor, PsiFile file, String refactoringName, String helpId, Project project) { + PsiLocalVariable localVar = null; + PsiExpression expr = null; + + if (!editor.getSelectionModel().hasSelection()) { + PsiElement element = + TargetElementUtil.findTargetElement(editor, + TargetElementUtil.ELEMENT_NAME_ACCEPTED + | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + | TargetElementUtil.LOOKUP_ITEM_ACCEPTED); + if (element instanceof PsiLocalVariable) { + localVar = (PsiLocalVariable) element; + final PsiElement elementAt = file.findElementAt(editor.getCaretModel().getOffset()); + if (elementAt instanceof PsiIdentifier && elementAt.getParent() instanceof PsiReferenceExpression) { + expr = (PsiExpression) elementAt.getParent(); + } + } else { + editor.getSelectionModel().selectLineAtCaret(); + } + } + + + int startOffset = 0; + int endOffset = 0; + if (localVar == null) { + startOffset = editor.getSelectionModel().getSelectionStart(); + endOffset = editor.getSelectionModel().getSelectionEnd(); + expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset); + } + + if (expr == null && localVar == null) { + PsiElement[] statements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); + if (statements != null && statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { + expr = ((PsiExpressionStatement) statements[0]).getExpression(); + } else if (statements != null && statements.length == 1 && statements[0] instanceof PsiDeclarationStatement) { + PsiDeclarationStatement decl = (PsiDeclarationStatement) statements[0]; + PsiElement[] declaredElements = decl.getDeclaredElements(); + if (declaredElements.length == 1 && declaredElements[0] instanceof PsiLocalVariable) { + localVar = (PsiLocalVariable) declaredElements[0]; + } + } + } + + if (localVar == null && expr == null) { + String message = + "Cannot perform the refactoring.\n" + + "Select expression or position the caret on a name of local variable."; + RefactoringMessageUtil.showErrorMessage(refactoringName, message, helpId, project); + return null; + } + return new ElementToWorkOn(localVar, expr); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java new file mode 100644 index 00000000000..a6b2d696908 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java @@ -0,0 +1,446 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.*; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.ui.StateRestoringCheckBox; +import com.intellij.ide.util.TreeClassChooserDialog; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.LinkedHashSet; +import java.util.Set; + +class IntroduceConstantDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceConstantDialog"); + + private Project myProject; + private final PsiClass myParentClass; + private final PsiExpression myInitializerExpression; + private final PsiLocalVariable myLocalVariable; + private final boolean myInvokedOnDeclaration; + private final int myOccurrencesCount; + private final PsiClass myTargetClass; + private final TypeSelectorManager myTypeSelectorManager; + + private NameSuggestionsField myNameField; + private JCheckBox myCbReplaceAll; + + private JRadioButton myRbPrivate; + private JRadioButton myRbProtected; + private JRadioButton myRbpackageLocal; + private JRadioButton myRbPublic; + + private TypeSelector myTypeSelector; + private StateRestoringCheckBox myCbDeleteVariable; + private NameSuggestionsManager myNameSuggestionsManager; + private final CodeStyleManager myCodeStyleManager; + private TextFieldWithBrowseButton myTfTargetClassName; + private PsiClass myDestinationClass; + + public IntroduceConstantDialog(Project project, + PsiClass parentClass, + PsiExpression initializerExpression, + PsiLocalVariable localVariable, boolean isInvokedOnDeclaration, + int occurrencesCount, PsiClass targetClass, TypeSelectorManager typeSelectorManager) { + + super(project, true); + myProject = project; + myParentClass = parentClass; + myInitializerExpression = initializerExpression; + myLocalVariable = localVariable; + myInvokedOnDeclaration = isInvokedOnDeclaration; + myOccurrencesCount = occurrencesCount; + myTargetClass = targetClass; + myTypeSelectorManager = typeSelectorManager; + myDestinationClass = null; + + setTitle(IntroduceConstantHandler.REFACTORING_NAME); + myCodeStyleManager = CodeStyleManager.getInstance(myProject); + init(); + + final String ourLastVisibility = RefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY; + if (PsiModifier.PUBLIC.equals(ourLastVisibility)) { + myRbPublic.setSelected(true); + } else if (PsiModifier.PROTECTED.equals(ourLastVisibility)) { + myRbProtected.setSelected(true); + } else if (PsiModifier.PACKAGE_LOCAL.equals(ourLastVisibility)) { + myRbpackageLocal.setSelected(true); + } else if (PsiModifier.PRIVATE.equals(ourLastVisibility)) { + myRbPrivate.setSelected(true); + } else { + myRbPrivate.setSelected(true); + } + } + + public String getEnteredName() { + return myNameField.getName(); + } + + private String getTargetClassName() { + return myTfTargetClassName.getText(); + } + + public PsiClass getDestinationClass () { + return myDestinationClass; + } + + public String getFieldVisibility() { + if (myRbPublic.isSelected()) { + return PsiModifier.PUBLIC; + } + if (myRbpackageLocal.isSelected()) { + return PsiModifier.PACKAGE_LOCAL; + } + if (myRbProtected.isSelected()) { + return PsiModifier.PROTECTED; + } + if (myRbPrivate.isSelected()) { + return PsiModifier.PRIVATE; + } + LOG.assertTrue(false); + return null; + } + + public boolean isReplaceAllOccurrences() { + if (myOccurrencesCount <= 1) return false; + return myCbReplaceAll.isSelected(); + } + + public PsiType getSelectedType() { + return myTypeSelector.getSelectedType(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.INTRODUCE_CONSTANT); + } + + protected JComponent createNorthPanel() { + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.anchor = GridBagConstraints.EAST; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.insets = new Insets(4, 4, 4, 0); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + JLabel type = new JLabel("Constant (static final field) of type: "); + panel.add(type, gbConstraints); + + gbConstraints.gridx++; + gbConstraints.insets = new Insets(4, 0, 4, 4); + myTypeSelector = myTypeSelectorManager.getTypeSelector(); + panel.add(myTypeSelector.getComponent(), gbConstraints); + if (myTypeSelector.getFocusableComponent() != null) { + type.setDisplayedMnemonic(KeyEvent.VK_T); + type.setLabelFor(myTypeSelector.getFocusableComponent()); + } + + + final JLabel namePrompt; + JPanel nameInputPanel; + { + nameInputPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.insets = new Insets(0, 0, 0, 2); + gbc.anchor = GridBagConstraints.EAST; + gbc.fill = GridBagConstraints.BOTH; + gbc.gridwidth = 1; + gbc.weightx = 0; + gbc.weighty = 1; + gbc.gridx = 0; + gbc.gridy = 0; + namePrompt = new JLabel("Name: "); + nameInputPanel.add(namePrompt, gbc); + + gbc.gridx++; + gbc.insets = new Insets(0, 2, 0, 0); + gbc.weightx = 1; + myNameField = new NameSuggestionsField(myProject); + nameInputPanel.add(myNameField.getComponent(), gbc); + namePrompt.setDisplayedMnemonic(KeyEvent.VK_N); + namePrompt.setLabelFor(myNameField.getFocusableComponent()); + } + + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.gridwidth = 2; + gbConstraints.weightx = 1; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + panel.add(nameInputPanel, gbConstraints); + + { + myTfTargetClassName = new TextFieldWithBrowseButton(new ChooseClassAction()); + JPanel _panel = new JPanel(new BorderLayout()); + JLabel label = new JLabel("To (fully qualified name):"); + label.setLabelFor(myTfTargetClassName); + _panel.add(label, BorderLayout.NORTH); + _panel.add(myTfTargetClassName, BorderLayout.CENTER); + gbConstraints.gridy++; + panel.add(_panel, gbConstraints); + } + + /*gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + + panel.add(namePrompt, gbConstraints); + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 1; + gbConstraints.gridx = 1; + gbConstraints.gridy = 1;*/ + +// panel.add(myNameField.getComponent(), gbConstraints); + + final String propertyName; + if(myLocalVariable != null) { + propertyName = myCodeStyleManager.variableNameToPropertyName(myLocalVariable.getName(), VariableKind.LOCAL_VARIABLE); + } else { + propertyName = null; + } + myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField, + new NameSuggestionsGenerator() { + public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { + return myCodeStyleManager.suggestVariableName( + VariableKind.STATIC_FINAL_FIELD, propertyName, myInitializerExpression, type + ); + } + + public Pair> completeVariableName(String prefix, PsiType type) { + LinkedHashSet set = new LinkedHashSet(); + LookupItemPreferencePolicy policy = CompletionUtil.completeVariableName(myProject, set, prefix, type, VariableKind.STATIC_FINAL_FIELD); + return new Pair> (policy, set); + } + }, + myProject); + + myNameSuggestionsManager.setMnemonics(type, namePrompt); + + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.weightx = 1; + gbConstraints.weighty = 0; + gbConstraints.gridwidth = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + gbConstraints.insets = new Insets(0, 0, 0, 0); + + panel.add(createVisibilityPanel(), gbConstraints); + ItemListener itemListener = new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateTypeSelector(); + + myNameField.requestFocusInWindow(); + } + }; + if (myOccurrencesCount > 1) { + myCbReplaceAll = new NonFocusableCheckBox("Replace all occurrences of expression (" + myOccurrencesCount + " occurrences)"); + myCbReplaceAll.setMnemonic('R'); + myCbReplaceAll.setFocusable(false); + gbConstraints.gridy++; + panel.add(myCbReplaceAll, gbConstraints); + myCbReplaceAll.addItemListener(itemListener); + } + + if (myLocalVariable != null) { + gbConstraints.gridy++; + if (myCbReplaceAll != null) { + gbConstraints.insets = new Insets(0, 8, 0, 0); + } + myCbDeleteVariable = new StateRestoringCheckBox("Delete variable declaration"); + myCbDeleteVariable.setFocusable(false); + panel.add(myCbDeleteVariable, gbConstraints); + myCbDeleteVariable.setMnemonic(KeyEvent.VK_D); + if (myInvokedOnDeclaration) { + myCbDeleteVariable.setEnabled(false); + myCbDeleteVariable.setSelected(true); + } else if (myCbReplaceAll != null) { + updateCbDeleteVariable(); + myCbReplaceAll.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateCbDeleteVariable(); + } + } + ); + } + } + updateTypeSelector(); + return panel; + } + + public boolean isDeleteVariable() { + if (myInvokedOnDeclaration) return true; + if (myCbDeleteVariable == null) return false; + return myCbDeleteVariable.isSelected(); + } + + private void updateCbDeleteVariable() { + if (!myCbReplaceAll.isSelected()) { + myCbDeleteVariable.makeUnselectable(false); + } else { + myCbDeleteVariable.makeSelectable(); + } + } + + private void updateTypeSelector() { + if (myCbReplaceAll != null) { + myTypeSelectorManager.setAllOccurences(myCbReplaceAll.isSelected()); + } else { + myTypeSelectorManager.setAllOccurences(false); + } + } + + private JComponent createVisibilityPanel() { + JPanel visibilityPanel = new JPanel(); + visibilityPanel.setBorder(IdeBorderFactory.createTitledBorder("Visibility")); + visibilityPanel.setLayout(new BoxLayout(visibilityPanel, BoxLayout.Y_AXIS)); + + + myRbPrivate = new JRadioButton("Private"); + myRbPrivate.setMnemonic('v'); + myRbPrivate.setFocusable(false); + myRbpackageLocal = new JRadioButton("Package local"); + myRbpackageLocal.setMnemonic('k'); + myRbpackageLocal.setFocusable(false); + myRbProtected = new JRadioButton("Protected"); + myRbProtected.setMnemonic('o'); + myRbProtected.setFocusable(false); + myRbPublic = new JRadioButton("Public"); + myRbPublic.setMnemonic('b'); + myRbPublic.setFocusable(false); + + + visibilityPanel.add(myRbPrivate); + visibilityPanel.add(myRbpackageLocal); + visibilityPanel.add(myRbProtected); + visibilityPanel.add(myRbPublic); + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbPrivate); + bg.add(myRbpackageLocal); + bg.add(myRbProtected); + bg.add(myRbPublic); + + + if (myTargetClass.isInterface()) { + myRbPrivate.setEnabled(false); + myRbProtected.setEnabled(false); + myRbpackageLocal.setEnabled(false); + myRbPublic.setEnabled(true); + myRbPublic.setSelected(true); + } + + return visibilityPanel; + } + + protected void doOKAction() { + + final String targetClassName = getTargetClassName(); + if (!"".equals (targetClassName)) { + final PsiManager manager = PsiManager.getInstance(myProject); + final PsiClass newClass = manager.findClass(targetClassName); + if (newClass == null) { + RefactoringMessageUtil.showErrorMessage( + IntroduceConstantHandler.REFACTORING_NAME, + "Class does not exist", + HelpID.INTRODUCE_FIELD, + myProject); + return; + } + myDestinationClass = newClass; + } + + String fieldName = getEnteredName(); + String errorString = null; + if ("".equals(fieldName)) { + errorString = "No field name specified"; + } else if (!PsiManager.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) { + errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName); + } + if (errorString != null) { + RefactoringMessageUtil.showErrorMessage( + IntroduceFieldHandler.REFACTORING_NAME, + errorString, + HelpID.INTRODUCE_FIELD, + myProject); + return; + } + PsiField oldField = myParentClass.findFieldByName(fieldName, true); + + if (oldField != null) { + int answer = Messages.showYesNoDialog( + myProject, + "The field with the name " + fieldName + "\nalready exists in class '" + + oldField.getContainingClass().getQualifiedName() + "'.\nContinue?", + IntroduceFieldHandler.REFACTORING_NAME, + Messages.getWarningIcon() + ); + if (answer != 0) { + return; + } + } + + RefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY = getFieldVisibility(); + + super.doOKAction(); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField.getComponent(); + } + + private class ChooseClassAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + TreeClassChooserDialog chooser = TreeClassChooserDialog.withInnerClasses("Choose Destination Class", myProject, GlobalSearchScope.projectScope(myProject), new TreeClassChooserDialog.ClassFilter() { + public boolean isAccepted(PsiClass aClass) { + return aClass.getParent() instanceof PsiJavaFile || aClass.hasModifierProperty(PsiModifier.STATIC); + } + }, null); + chooser.selectDirectory(myTargetClass.getContainingFile().getContainingDirectory()); + chooser.show(); + PsiClass aClass = chooser.getSelectedClass(); + if (aClass != null) { + myTfTargetClassName.setText(aClass.getQualifiedName()); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java new file mode 100644 index 00000000000..0ce98da6d72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java @@ -0,0 +1,191 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; +import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager; +import com.intellij.refactoring.util.occurences.OccurenceManager; + +public class IntroduceConstantHandler extends BaseExpressionToFieldHandler { + public static final String REFACTORING_NAME = "Introduce Constant"; + + protected String getHelpID() { + return /*HelpID.INTRODUCE_CONSTANT*/ null; + } + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final ElementToWorkOn elementToWorkOn = ElementToWorkOn.getElementToWorkOn(editor, file, + REFACTORING_NAME, getHelpID(), project + ); + + if (elementToWorkOn == null) return; + + if (elementToWorkOn.getExpression() == null) { + final PsiLocalVariable localVariable = elementToWorkOn.getLocalVariable(); + final boolean result = invokeImpl(project, localVariable, editor); + if (result) { + editor.getSelectionModel().removeSelection(); + } + } else if (invokeImpl(project, elementToWorkOn.getExpression(), editor)) { + editor.getSelectionModel().removeSelection(); + } + } + + protected boolean invokeImpl(Project project, final PsiLocalVariable localVariable, Editor editor) { + final LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, true); + final boolean result = localToFieldHandler.convertLocalToField(localVariable, editor); + return result; + } + + + protected BaseExpressionToFieldHandler.Settings showRefactoringDialog(Project project, PsiClass parentClass, + PsiExpression expr, + PsiType type, PsiExpression[] occurences, + PsiElement anchorElement, + PsiElement anchorElementIfAll) { + PsiLocalVariable localVariable = null; + if (expr instanceof PsiReferenceExpression) { + PsiElement ref = ((PsiReferenceExpression) expr).resolve(); + if (ref instanceof PsiLocalVariable) { + localVariable = (PsiLocalVariable) ref; + } + } + + if (localVariable == null) { + if (!isStaticFinalInitializer(expr)) { + String message = + "Cannot perform the refactoring.\n" + + "Selected expression cannot be a constant initializer."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, getHelpID(), project); + return null; + } + } else { + final PsiExpression initializer = localVariable.getInitializer(); + if (initializer == null) { + String message = + "Cannot perform the refactoring.\n" + + "Variable " + localVariable.getName() + " does not have an initializer."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, getHelpID(), project); + return null; + } + if (!isStaticFinalInitializer(initializer)) { + String message = + "Cannot perform the refactoring.\n" + + "Initializer for variable " + localVariable.getName() + " cannot be a constant initializer."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, getHelpID(), project); + return null; + } + } + + int occurencesNumber = occurences.length; + IntroduceConstantDialog dialog = new IntroduceConstantDialog( + project, parentClass, expr, localVariable, false, occurencesNumber, + getParentClass(), new TypeSelectorManagerImpl(project, type, expr, occurences) + ); + dialog.show(); + if (!dialog.isOK()) { + if (occurencesNumber > 1) { + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + return null; + } + return new Settings(dialog.getEnteredName(), dialog.isReplaceAllOccurrences(), + true, true, BaseExpressionToFieldHandler.IN_FIELD_DECLARATION, + dialog.getFieldVisibility(), + localVariable, + dialog.getSelectedType(), dialog.isDeleteVariable(), + dialog.getDestinationClass()); + } + + + protected String getRefactoringName() { + return REFACTORING_NAME; + } + + private boolean isStaticFinalInitializer(PsiExpression expr) { + PsiClass parentClass = getParentClass(expr); + if (parentClass == null) return true; + IsStaticFinalInitializerExpression visitor = new IsStaticFinalInitializerExpression(parentClass, expr); + expr.accept(visitor); + return visitor.isStaticFinalInitializer(); + } + + protected OccurenceManager createOccurenceManager(final PsiExpression selectedExpr, final PsiClass parentClass) { + OccurenceManager occurenceManager = new ExpressionOccurenceManager(selectedExpr, parentClass, null); + return occurenceManager; + } + + private static class IsStaticFinalInitializerExpression extends ClassMemberReferencesVisitor { + private boolean myIsStaticFinalInitializer = true; + private final PsiExpression myInitializer; + + public IsStaticFinalInitializerExpression(PsiClass aClass, PsiExpression initializer) { + super(aClass); + myInitializer = initializer; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiElement psiElement = expression.resolve(); + if ((psiElement instanceof PsiLocalVariable || psiElement instanceof PsiParameter) + && !PsiTreeUtil.isAncestor(myInitializer, psiElement, false)) { + myIsStaticFinalInitializer = false; + } else { + super.visitReferenceExpression(expression); + } + } + + + protected void visitClassMemberReferenceElement(PsiMember classMember, + PsiJavaCodeReferenceElement classMemberReference) { + myIsStaticFinalInitializer = classMember.hasModifierProperty(PsiModifier.STATIC); + } + + public void visitElement(PsiElement element) { + if (!myIsStaticFinalInitializer) return; + super.visitElement(element); + } + + public boolean isStaticFinalInitializer() { + return myIsStaticFinalInitializer; + } + } + + public PsiClass getParentClass(PsiExpression initializerExpression) { + final PsiType type = initializerExpression.getType(); + + if (type != null && PsiUtil.isConstantExpression(initializerExpression)) { + if (type instanceof PsiPrimitiveType || + PsiType.getJavaLangString(initializerExpression.getManager()).equals(type)) { + return super.getParentClass(initializerExpression); + } + } + + PsiClass aClass = PsiTreeUtil.getParentOfType(initializerExpression, PsiClass.class); + while (aClass != null) { + if (aClass.hasModifierProperty(PsiModifier.STATIC)) return aClass; + if (aClass.getParent() instanceof PsiJavaFile) return aClass; + aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class); + } + return null; + } + + protected boolean validClass(PsiClass parentClass) { + return true; + } + + protected boolean isStaticField() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java new file mode 100644 index 00000000000..7b643499998 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java @@ -0,0 +1,547 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.*; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.util.LinkedHashSet; +import java.util.Set; + +class IntroduceFieldDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog"); + + private static boolean ourLastCbFinalState = false; + private static int ourLastInializerPlace; + + private Project myProject; + private final PsiClass myParentClass; + private final PsiExpression myInitializerExpression; + private final PsiLocalVariable myLocalVariable; + private final boolean myIsCurrentMethodConstructor; + private final boolean myIsInvokedOnDeclaration; + private boolean myWillBeDeclaredStatic; + private final int myOccurrencesCount; + private final boolean myAllowInitInMethod; + private final boolean myAllowInitInMethodIfAll; + private final TypeSelectorManager myTypeSelectorManager; + + private NameSuggestionsField myNameField; + private JCheckBox myCbReplaceAll; + private StateRestoringCheckBox myCbDeleteVariable; + private StateRestoringCheckBox myCbFinal; + + private JRadioButton myRbInConstructor; + private JRadioButton myRbInCurrentMethod; + private JRadioButton myRbInFieldDeclaration; + + private JRadioButton myRbPrivate; + private JRadioButton myRbProtected; + private JRadioButton myRbPackageLocal; + private JRadioButton myRbPublic; + private TypeSelector myTypeSelector; + private NameSuggestionsManager myNameSuggestionsManager; + + public IntroduceFieldDialog(Project project, + PsiClass parentClass, + PsiExpression initializerExpression, + PsiLocalVariable localVariable, + boolean isCurrentMethodConstructor, boolean isInvokedOnDeclaration, boolean willBeDeclaredStatic, + int occurrencesCount, boolean allowInitInMethod, boolean allowInitInMethodIfAll, + TypeSelectorManager typeSelectorManager) { + super(project, true); + myProject = project; + myParentClass = parentClass; + myInitializerExpression = initializerExpression; + myLocalVariable = localVariable; + myIsCurrentMethodConstructor = isCurrentMethodConstructor; + myIsInvokedOnDeclaration = isInvokedOnDeclaration; + myWillBeDeclaredStatic = willBeDeclaredStatic; + myOccurrencesCount = occurrencesCount; + myAllowInitInMethod = allowInitInMethod; + myAllowInitInMethodIfAll = allowInitInMethodIfAll; + myTypeSelectorManager = typeSelectorManager; + + setTitle("Introduce Field"); + init(); + + initializeControls(initializerExpression); + + } + + private void initializeControls(PsiExpression initializerExpression) { + if (initializerExpression != null) { + setEnabledInitializationPlaces(initializerExpression, initializerExpression); + if (!myAllowInitInMethod) { + myRbInCurrentMethod.setEnabled(false); + } + } else { + myRbInConstructor.setEnabled(false); + myRbInCurrentMethod.setEnabled(false); + myRbInFieldDeclaration.setEnabled(false); + } + + if (ourLastInializerPlace == IntroduceFieldHandler.IN_CONSTRUCTOR) { + if (myRbInConstructor.isEnabled()) { + myRbInConstructor.setSelected(true); + } else { + selectInCurrentMethod(); + } + } else if (ourLastInializerPlace == IntroduceFieldHandler.IN_FIELD_DECLARATION) { + if (myRbInFieldDeclaration.isEnabled()) { + myRbInFieldDeclaration.setSelected(true); + } else { + selectInCurrentMethod(); + } + } else { + selectInCurrentMethod(); + } + String ourLastVisibility = RefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY; + if (PsiModifier.PUBLIC.equals(ourLastVisibility)) { + myRbPublic.setSelected(true); + } else if (PsiModifier.PROTECTED.equals(ourLastVisibility)) { + myRbProtected.setSelected(true); + } else if (PsiModifier.PACKAGE_LOCAL.equals(ourLastVisibility)) { + myRbPackageLocal.setSelected(true); + } else if (PsiModifier.PRIVATE.equals(ourLastVisibility)) { + myRbPrivate.setSelected(true); + } else { + myRbPrivate.setSelected(true); + } + myCbFinal.setSelected(myCbFinal.isEnabled() ? ourLastCbFinalState : false); + } + + private void selectInCurrentMethod() { + if (myRbInCurrentMethod.isEnabled()) { + myRbInCurrentMethod.setSelected(true); + } + else if (myRbInFieldDeclaration.isEnabled()) { + myRbInFieldDeclaration.setSelected(true); + } + else { + myRbInCurrentMethod.setSelected(true); + } + } + + public String getEnteredName() { + return myNameField.getName(); + } + + public int getInitializerPlace() { + if (myRbInConstructor.isSelected()) { + return IntroduceFieldHandler.IN_CONSTRUCTOR; + } + if (myRbInCurrentMethod.isSelected()) { + return IntroduceFieldHandler.IN_CURRENT_METHOD; + } + if (myRbInFieldDeclaration.isSelected()) { + return IntroduceFieldHandler.IN_FIELD_DECLARATION; + } + LOG.assertTrue(false); + return -1; + } + + public String getFieldVisibility() { + if (myRbPublic.isSelected()) { + return PsiModifier.PUBLIC; + } + if (myRbPackageLocal.isSelected()) { + return PsiModifier.PACKAGE_LOCAL; + } + if (myRbProtected.isSelected()) { + return PsiModifier.PROTECTED; + } + if (myRbPrivate.isSelected()) { + return PsiModifier.PRIVATE; + } + LOG.assertTrue(false); + return null; + } + + public boolean isReplaceAllOccurrences() { + if (myIsInvokedOnDeclaration) return true; + if (myOccurrencesCount <= 1) return false; + return myCbReplaceAll.isSelected(); + } + + public boolean isDeleteVariable() { + if (myIsInvokedOnDeclaration) return true; + if (myCbDeleteVariable == null) return false; + return myCbDeleteVariable.isSelected(); + } + + public boolean isDeclareFinal() { + return myCbFinal.isSelected(); + } + + public PsiType getFieldType() { + return myTypeSelector.getSelectedType(); + } + + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + + protected JComponent createNorthPanel() { + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 0); + gbConstraints.anchor = GridBagConstraints.EAST; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + + JLabel type = new JLabel(getTypeLabel()); + + panel.add(type, gbConstraints); + + gbConstraints.gridx++; + gbConstraints.insets = new Insets(4, 0, 4, 4); + gbConstraints.weightx = 0; + myTypeSelector = myTypeSelectorManager.getTypeSelector(); + panel.add(myTypeSelector.getComponent(), gbConstraints); + + gbConstraints.insets = new Insets(4, 4, 4, 0); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + JLabel namePrompt = new JLabel("Name: "); + panel.add(namePrompt, gbConstraints); + + gbConstraints.insets = new Insets(4, 0, 4, 4); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 1; + gbConstraints.gridx = 1; + gbConstraints.gridy = 1; + myNameField = new NameSuggestionsField(myProject); + panel.add(myNameField.getComponent(), gbConstraints); + namePrompt.setLabelFor(myNameField.getFocusableComponent()); + + myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField, createGenerator(), myProject); + myNameSuggestionsManager.setMnemonics(type, namePrompt); + + return panel; + } + + private String getTypeLabel() { + return (myWillBeDeclaredStatic ? "Static field " : "Field") + " of type: "; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.weightx = 1; + gbConstraints.weighty = 0; + gbConstraints.gridwidth = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + final Insets standardInsets = new Insets(0, 0, 0, 0); + gbConstraints.insets = standardInsets; + + panel.add(createInitializerPlacePanel(), gbConstraints); + ItemListener itemListener = new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (myCbReplaceAll != null && myAllowInitInMethod) { + myRbInCurrentMethod.setEnabled(myAllowInitInMethodIfAll || !myCbReplaceAll.isSelected()); + if (!myRbInCurrentMethod.isEnabled() && myRbInCurrentMethod.isSelected()) { + myRbInCurrentMethod.setSelected(false); + myRbInFieldDeclaration.setSelected(true); + } + } + updateTypeSelector(); + + myNameField.requestFocusInWindow(); + } + }; + ItemListener finalUpdater = new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateCbFinal(); + } + }; + myRbInConstructor.addItemListener(itemListener); + myRbInCurrentMethod.addItemListener(itemListener); + myRbInFieldDeclaration.addItemListener(itemListener); + myRbInConstructor.addItemListener(finalUpdater); + myRbInCurrentMethod.addItemListener(finalUpdater); + myRbInFieldDeclaration.addItemListener(finalUpdater); + if (myOccurrencesCount > 1) { + myCbReplaceAll = new NonFocusableCheckBox( + "Replace all occurrences of expression (" + myOccurrencesCount + " occurrences)"); + myCbReplaceAll.setMnemonic('R'); + gbConstraints.gridy++; + panel.add(myCbReplaceAll, gbConstraints); + myCbReplaceAll.addItemListener(itemListener); + if (myIsInvokedOnDeclaration) { + myCbReplaceAll.setEnabled(false); + myCbReplaceAll.setSelected(true); + } + } + + if (myLocalVariable != null) { + gbConstraints.gridy++; + if (myCbReplaceAll != null) { + gbConstraints.insets = new Insets(0, 8, 0, 0); + } + myCbDeleteVariable = new StateRestoringCheckBox("Delete variable declaration"); + panel.add(myCbDeleteVariable, gbConstraints); + myCbDeleteVariable.setMnemonic(KeyEvent.VK_D); + if (myIsInvokedOnDeclaration) { + myCbDeleteVariable.setEnabled(false); + myCbDeleteVariable.setSelected(true); + } else if (myCbReplaceAll != null) { + updateCbDeleteVariable(); + myCbReplaceAll.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateCbDeleteVariable(); + } + } + ); + } + gbConstraints.insets = standardInsets; + } + myCbFinal.addItemListener(itemListener); +// myCbStatic.addItemListener(itemListener); +// myCbStatic.addItemListener(finalUpdater); +// myCbStatic.addItemListener( +// new ItemListener() { +// public void itemStateChanged(ItemEvent e) { +// updateNameList(); +// } +// } +// ); + + updateTypeSelector(); + return panel; + } + + private void updateTypeSelector() { + if (myCbReplaceAll != null) { + myTypeSelectorManager.setAllOccurences(myCbReplaceAll.isSelected()); + } else { + myTypeSelectorManager.setAllOccurences(false); + } + } + + private void updateCbDeleteVariable() { + if (!myCbReplaceAll.isSelected()) { + myCbDeleteVariable.makeUnselectable(false); + } else { + myCbDeleteVariable.makeSelectable(); + } + } + + private JComponent createInitializerPlacePanel() { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + + JPanel initializationPanel = new JPanel(); + initializationPanel.setBorder(IdeBorderFactory.createTitledBorder("Initialize in")); + initializationPanel.setLayout(new BoxLayout(initializationPanel, BoxLayout.Y_AXIS)); + + JPanel visibilityPanel = new JPanel(); + visibilityPanel.setBorder(IdeBorderFactory.createTitledBorder("Visibility")); + visibilityPanel.setLayout(new BoxLayout(visibilityPanel, BoxLayout.Y_AXIS)); + + /*JPanel modifiersPanel = new GroupPanel(); + modifiersPanel.setBorder(BorderFactory.createTitledBorder("Other Modifiers")); + modifiersPanel.setLayout(new BoxLayout(modifiersPanel, BoxLayout.Y_AXIS));*/ + + myRbInCurrentMethod = new JRadioButton("Current method"); + myRbInCurrentMethod.setMnemonic('m'); + myRbInCurrentMethod.setEnabled(myAllowInitInMethod); + myRbInFieldDeclaration = new JRadioButton("Field declaration"); + myRbInFieldDeclaration.setMnemonic('d'); + myRbInConstructor = new JRadioButton("Class constructor(s)"); + myRbInConstructor.setMnemonic('C'); + + myRbPrivate = new JRadioButton("Private"); + myRbPrivate.setFocusable(false); + myRbPrivate.setMnemonic('v'); + myRbPackageLocal = new JRadioButton("Package local"); + myRbPackageLocal.setMnemonic('k'); + myRbPackageLocal.setFocusable(false); + myRbProtected = new JRadioButton("Protected"); + myRbProtected.setFocusable(false); + myRbProtected.setMnemonic('o'); + myRbPublic = new JRadioButton("Public"); + myRbPublic.setFocusable(false); + myRbPublic.setMnemonic('b'); + + myCbFinal = new StateRestoringCheckBox("Declare final"); + myCbFinal.setMnemonic('f'); +// myCbStatic.setMnemonic('S'); + + initializationPanel.add(myRbInCurrentMethod); + initializationPanel.add(myRbInFieldDeclaration); + initializationPanel.add(myRbInConstructor); + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbInCurrentMethod); + bg.add(myRbInFieldDeclaration); + bg.add(myRbInConstructor); + + visibilityPanel.add(myRbPrivate); + visibilityPanel.add(myRbPackageLocal); + visibilityPanel.add(myRbProtected); + visibilityPanel.add(myRbPublic); + bg = new ButtonGroup(); + bg.add(myRbPrivate); + bg.add(myRbPackageLocal); + bg.add(myRbProtected); + bg.add(myRbPublic); + +// modifiersPanel.add(myCbFinal); +// modifiersPanel.add(myCbStatic); + + JPanel groupPanel = new JPanel(new GridLayout(1, 2)); + groupPanel.add(initializationPanel); + groupPanel.add(visibilityPanel); + mainPanel.add(groupPanel, BorderLayout.CENTER); + mainPanel.add(myCbFinal, BorderLayout.SOUTH); + + return mainPanel; + } + + private void updateCbFinal() { + boolean allowFinal = myRbInFieldDeclaration.isSelected() || (myRbInConstructor.isSelected() && !myWillBeDeclaredStatic); + if (myRbInCurrentMethod.isSelected() && myIsCurrentMethodConstructor) { + final PsiMethod[] constructors = myParentClass.getConstructors(); + allowFinal = constructors.length <= 1; + } + if (!allowFinal) { + myCbFinal.makeUnselectable(false); + } else { + myCbFinal.makeSelectable(); + } + } + + + private NameSuggestionsGenerator createGenerator() { + return new NameSuggestionsGenerator() { + private CodeStyleManager myCodeStyleManager = CodeStyleManager.getInstance(myProject); + public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { + VariableKind variableKind = myWillBeDeclaredStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD; + + String propertyName = null; + if (myIsInvokedOnDeclaration) { + propertyName = myCodeStyleManager.variableNameToPropertyName(myLocalVariable.getName(), + VariableKind.LOCAL_VARIABLE + ); + } + return myCodeStyleManager.suggestVariableName(variableKind, propertyName, myInitializerExpression, type); + } + + public Pair> completeVariableName(String prefix, PsiType type) { + LinkedHashSet set = new LinkedHashSet(); + VariableKind kind = myWillBeDeclaredStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD; + LookupItemPreferencePolicy policy = CompletionUtil.completeVariableName(myProject, set, prefix, type, kind); + return new Pair> (policy, set); + } + }; + } + + + protected void doOKAction() { + String fieldName = getEnteredName(); + String errorString = null; + if ("".equals(fieldName)) { + errorString = "No field name specified"; + } else if (!PsiManager.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) { + errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName); + } + if (errorString != null) { + RefactoringMessageUtil.showErrorMessage( + IntroduceFieldHandler.REFACTORING_NAME, + errorString, + HelpID.INTRODUCE_FIELD, + myProject + ); + return; + } + + PsiField oldField = myParentClass.findFieldByName(fieldName, true); + + if (oldField != null) { + int answer = Messages.showYesNoDialog( + myProject, + "The field with the name " + fieldName + "\nalready exists in class '" + + oldField.getContainingClass().getQualifiedName() + "'.\nContinue?", + IntroduceFieldHandler.REFACTORING_NAME, + Messages.getWarningIcon() + ); + if (answer != 0) { + return; + } + } + + ourLastCbFinalState = myCbFinal.isSelected(); + ourLastInializerPlace = getInitializerPlace(); + RefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY = getFieldVisibility(); + + myNameSuggestionsManager.nameSelected(); + super.doOKAction(); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField.getComponent(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.INTRODUCE_FIELD); + } + + private boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { + if (initializerPart instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression) initializerPart; + if (refExpr.getQualifierExpression() == null) { + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) { + if (!PsiTreeUtil.isAncestor(initializer, refElement, true)) { + myRbInFieldDeclaration.setEnabled(false); + myRbInConstructor.setEnabled(false); + myCbFinal.setEnabled(false); + return false; + } + } + } + } + PsiElement[] children = initializerPart.getChildren(); + for (int i = 0; i < children.length; i++) { + if (!setEnabledInitializationPlaces(children[i], initializer)) return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java new file mode 100644 index 00000000000..8b8118724e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java @@ -0,0 +1,150 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.occurences.*; + +public class IntroduceFieldHandler extends BaseExpressionToFieldHandler { + + public static final String REFACTORING_NAME = "Introduce Field"; + private static final MyOccurenceFilter MY_OCCURENCE_FILTER = new MyOccurenceFilter(); + + protected String getRefactoringName() { + return REFACTORING_NAME; + } + + protected boolean validClass(PsiClass parentClass) { + if (parentClass.isInterface()) { + String message = "Cannot introduce field in interface"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, getHelpID(), + parentClass.getProject()); + return false; + } + else { + return true; + } + } + + protected String getHelpID() { + return HelpID.INTRODUCE_FIELD; + } + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + ElementToWorkOn elementToWorkOn = + ElementToWorkOn.getElementToWorkOn(editor, file, REFACTORING_NAME, HelpID.INTRODUCE_FIELD, null); + + if (elementToWorkOn == null) return; + + if (elementToWorkOn.getExpression() == null) { + final PsiLocalVariable localVariable = elementToWorkOn.getLocalVariable(); + final boolean result = invokeImpl(project, localVariable, editor); + if (result) { + editor.getSelectionModel().removeSelection(); + } + } + else if (invokeImpl(project, elementToWorkOn.getExpression(), editor)) { + editor.getSelectionModel().removeSelection(); + } + } + + protected Settings showRefactoringDialog(Project project, PsiClass parentClass, PsiExpression expr, + PsiType type, + PsiExpression[] occurences, PsiElement anchorElement, PsiElement anchorElementIfAll) { + final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr, PsiMethod.class); + final PsiElement staticParentElement = HighlightUtil.getPossibleStaticParentElement(expr, parentClass); + boolean declareStatic = staticParentElement instanceof PsiModifierListOwner + && ((PsiModifierListOwner)staticParentElement).hasModifierProperty(PsiModifier.STATIC); + + boolean isInSuperOrThis = false; + if (!declareStatic) { + for (int i = 0; !declareStatic & i < occurences.length; i++) { + PsiExpression occurence = occurences[i]; + isInSuperOrThis = isInSuperOrThis(occurence); + declareStatic = isInSuperOrThis; + } + } + + PsiLocalVariable localVariable = null; + if (expr instanceof PsiReferenceExpression) { + PsiElement ref = ((PsiReferenceExpression)expr).resolve(); + if (ref instanceof PsiLocalVariable) { + localVariable = (PsiLocalVariable)ref; + } + } + + int occurencesNumber = occurences.length; + final boolean currentMethodConstructor = (containingMethod != null ? containingMethod.isConstructor() : false); + final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && (anchorElement instanceof PsiStatement); + final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && (anchorElementIfAll instanceof PsiStatement); + IntroduceFieldDialog dialog = new IntroduceFieldDialog( + project, parentClass, expr, localVariable, + currentMethodConstructor, + false, declareStatic, occurencesNumber, + allowInitInMethod, allowInitInMethodIfAll, + new TypeSelectorManagerImpl(project, type, expr, occurences) + ); + dialog.show(); + + if (!dialog.isOK()) { + if (occurencesNumber > 1) { + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + return null; + } + + if (!dialog.isDeleteVariable()) { + localVariable = null; + } + + + return new Settings(dialog.getEnteredName(), dialog.isReplaceAllOccurrences(), + declareStatic, dialog.isDeclareFinal(), + dialog.getInitializerPlace(), dialog.getFieldVisibility(), + localVariable, + dialog.getFieldType(), localVariable != null, null); + } + + private static boolean isInSuperOrThis(PsiExpression occurence) { + if (!NotInSuperCallOccurenceFilter.INSTANCE.isOK(occurence)) { + return true; + } + + if (!NotInThisCallFilter.INSTANCE.isOK(occurence)) { + return true; + } + return false; + } + + protected OccurenceManager createOccurenceManager(final PsiExpression selectedExpr, final PsiClass parentClass) { + final OccurenceFilter occurenceFilter = isInSuperOrThis(selectedExpr) ? null : MY_OCCURENCE_FILTER; + OccurenceManager occurenceManager = new ExpressionOccurenceManager(selectedExpr, parentClass, + occurenceFilter, + true); + return occurenceManager; + } + + protected boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) { + LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, false); + return localToFieldHandler.convertLocalToField(localVariable, editor); + } + + private static class MyOccurenceFilter implements OccurenceFilter { + public boolean isOK(PsiExpression occurence) { + return !isInSuperOrThis(occurence); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/LocalToFieldHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/LocalToFieldHandler.java new file mode 100644 index 00000000000..a5f0c030ced --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceField/LocalToFieldHandler.java @@ -0,0 +1,286 @@ +package com.intellij.refactoring.introduceField; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +public class LocalToFieldHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.LocalToFieldHandler"); + + public static final String REFACTORING_NAME = "Convert Local to Field"; + private final Project myProject; + private final boolean myIsConstant; + private final PsiManager myManager; + + public LocalToFieldHandler(Project project, boolean isConstant) { + myProject = project; + myManager = PsiManager.getInstance(myProject); + myIsConstant = isConstant; + } + + public boolean convertLocalToField(final PsiLocalVariable local, Editor editor) { + PsiClass aClass; + boolean tempIsStatic = myIsConstant; + PsiElement parent = local.getParent(); + + while (true) { + if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { + aClass = (PsiClass)parent; + break; + } + if (parent instanceof JspFile) { + String message = REFACTORING_NAME + " refactoring is not supported for JSP"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.LOCAL_TO_FIELD, myProject); + return false; + } + if (parent instanceof PsiModifierListOwner &&((PsiModifierListOwner)parent).hasModifierProperty(PsiModifier.STATIC)) { + tempIsStatic = true; + } + parent = parent.getParent(); + } + + final boolean isStatic = tempIsStatic; + + PsiExpression[] occurences = CodeInsightUtil.findReferenceExpressions(RefactoringUtil.getVariableScope(local), + local + ); + if (editor != null) { + RefactoringUtil.highlightOccurences(myProject, occurences, editor); + } + + //LocalToFieldDialog dialog = new LocalToFieldDialog(project, aClass, local, isStatic); + final String variableName; + final String fieldName; + final int initializerPlace; + final boolean declareFinal; + final String fieldVisibility; + final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(myProject, local.getType(), + occurences + ); + + boolean rebindNeeded = false; + if (!myIsConstant) { + PsiMethod method = PsiTreeUtil.getParentOfType(local, PsiMethod.class); + IntroduceFieldDialog dialog = new IntroduceFieldDialog(myProject, aClass, + local.getInitializer(), local, + method != null ? method.isConstructor() : false, + true, isStatic, + occurences.length, method != null, method != null, + typeSelectorManager + ); + dialog.show(); + if (!dialog.isOK()) return false; + variableName = local.getName(); + fieldName = dialog.getEnteredName(); + initializerPlace = dialog.getInitializerPlace(); + declareFinal = dialog.isDeclareFinal(); + fieldVisibility = dialog.getFieldVisibility(); + } + else { + IntroduceConstantDialog dialog = new IntroduceConstantDialog(myProject, aClass, + local.getInitializer(), local, true, occurences.length, aClass, typeSelectorManager + ); + dialog.show(); + if (!dialog.isOK()) return false; + variableName = local.getName(); + fieldName = dialog.getEnteredName(); + declareFinal = true; + initializerPlace = IntroduceFieldHandler.IN_FIELD_DECLARATION; + fieldVisibility = dialog.getFieldVisibility(); + final PsiClass destinationClass = dialog.getDestinationClass(); + if (destinationClass != null) { + aClass = destinationClass; + rebindNeeded = true; + } + } + + final PsiClass aaClass = aClass; + final boolean rebindNeeded1 = rebindNeeded; + final Runnable runnable = new Runnable() { + public void run() { + try { + final boolean rebindNeeded2 = !variableName.equals(fieldName) || rebindNeeded1; + final PsiReference[] refs; + if (rebindNeeded2) { + PsiManager manager = local.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + refs = helper.findReferences(local, GlobalSearchScope.projectScope(myProject), false); + } + else { + refs = null; + } + + final PsiMethod enclosingConstructor = BaseExpressionToFieldHandler.getEnclosingConstructor(aaClass, local); + PsiField field = createField(local, fieldName, + initializerPlace == IntroduceFieldHandler.IN_FIELD_DECLARATION + ); + if (isStatic) { + field.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + if (declareFinal) { + field.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + field.getModifierList().setModifierProperty(fieldVisibility, true); + + field = (PsiField)aaClass.add(field); + local.normalizeDeclaration(); + PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)local.getParent(); + final int finalInitializerPlace; + if (local.getInitializer() == null) { + finalInitializerPlace = IntroduceFieldHandler.IN_FIELD_DECLARATION; + } + else { + finalInitializerPlace = initializerPlace; + } + final PsiElementFactory factory = myManager.getElementFactory(); + + switch (finalInitializerPlace) { + case IntroduceFieldHandler.IN_FIELD_DECLARATION: + declarationStatement.delete(); + break; + + case IntroduceFieldHandler.IN_CURRENT_METHOD: + PsiStatement statement = createAssignment(local, fieldName, factory); + declarationStatement.replace(statement); + break; + + case IntroduceFieldHandler.IN_CONSTRUCTOR: + addInitializationToConstructors(local, field, enclosingConstructor, factory); + if (enclosingConstructor == null) { + declarationStatement.delete(); + } + break; + } + + if (enclosingConstructor != null && initializerPlace == IntroduceFieldHandler.IN_CONSTRUCTOR) { + PsiStatement statement = createAssignment(local, fieldName, factory); + declarationStatement.replace(statement); + } + + if (rebindNeeded2) { + for (int i = 0; i < refs.length; i++) { + final PsiReference reference = refs[i]; + if (reference != null) { + //expr = RefactoringUtil.outermostParenthesizedExpression(expr); + RefactoringUtil.replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass); + //replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass); + } + } + //RefactoringUtil.renameVariableReferences(local, pPrefix + fieldName, GlobalSearchScope.projectScope(myProject)); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, REFACTORING_NAME, null); + return true; + } + + private PsiField createField(PsiLocalVariable local, String fieldName, boolean includeInitializer) { + StringBuffer pattern = new StringBuffer(); + pattern.append("private int "); + pattern.append(fieldName); + if (local.getInitializer() == null) { + includeInitializer = false; + } + if (includeInitializer) { + pattern.append("=0"); + } + pattern.append(";"); + PsiElementFactory factory = myManager.getElementFactory(); + try { + PsiField field = factory.createFieldFromText(pattern.toString(), null); + field = (PsiField)CodeStyleManager.getInstance(myProject).reformat(field); + + field.getTypeElement().replace(factory.createTypeElement(local.getType())); + if (includeInitializer) { + PsiExpression initializer = + RefactoringUtil.convertInitializerToNormalExpression(local.getInitializer(), local.getType()); + field.getInitializer().replace(initializer); + } + + return field; + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + private PsiStatement createAssignment(PsiLocalVariable local, String fieldname, PsiElementFactory factory) { + try { + String pattern = fieldname + "=0;"; + PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null); + statement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(statement); + + PsiAssignmentExpression expr = (PsiAssignmentExpression)statement.getExpression(); + final PsiExpression initializer = RefactoringUtil.convertInitializerToNormalExpression(local.getInitializer(), local.getType()); + expr.getRExpression().replace(initializer); + + return statement; + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + + private void addInitializationToConstructors(PsiLocalVariable local, PsiField field, PsiMethod enclosingConstructor, + PsiElementFactory factory) { + try { + PsiClass aClass = field.getContainingClass(); + PsiMethod[] constructors = aClass.getConstructors(); + PsiStatement assignment = createAssignment(local, field.getName(), factory); + boolean added = false; + for (int idx = 0; idx < constructors.length; idx++) { + PsiMethod constructor = constructors[idx]; + if (constructor == enclosingConstructor) continue; + PsiCodeBlock body = constructor.getBody(); + if (body == null) continue; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + String text = ((PsiMethodCallExpression)expression).getMethodExpression().getText(); + if ("this".equals(text)) { + continue; + } + } + } + } + body.add(assignment); + added = true; + } + if (!added && enclosingConstructor == null) { + PsiMethod constructor = factory.createConstructor(); + constructor.getBody().add(assignment); + aClass.add(constructor); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ChangedMethodCallInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ChangedMethodCallInfo.java new file mode 100644 index 00000000000..95aeeb35cef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ChangedMethodCallInfo.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 04.06.2002 + * Time: 22:09:32 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.*; + +class ChangedMethodCallInfo extends InternalUsageInfo { + ChangedMethodCallInfo(PsiElement e) { + super(e); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ClassMemberInExprUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ClassMemberInExprUsageInfo.java new file mode 100644 index 00000000000..12ec07b8297 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ClassMemberInExprUsageInfo.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 15:07:17 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.*; + +class ClassMemberInExprUsageInfo extends InExprUsageInfo { + ClassMemberInExprUsageInfo(PsiElement elem) { + super(elem); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/EnclosingMethodSelectionDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/EnclosingMethodSelectionDialog.java new file mode 100644 index 00000000000..4f7a32ee0a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/EnclosingMethodSelectionDialog.java @@ -0,0 +1,107 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.06.2002 + * Time: 11:30:13 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperHandler; +import com.intellij.refactoring.ui.ClassCellRenderer; +import com.intellij.refactoring.ui.MethodCellRenderer; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.util.List; +import java.util.ArrayList; + +public class EnclosingMethodSelectionDialog extends DialogWrapper { + private final List myEnclosingMethods; + + private JList myEnclosingMethodsList = null; + private final JCheckBox myCbReplaceInstanceOf = new JCheckBox("Use interface/superclass in instanceof"); + + EnclosingMethodSelectionDialog(Project project, List enclosingMethods) { + super(project, true); + + myEnclosingMethods = enclosingMethods; + + setTitle("Introduce Parameter"); + init(); + } + + public PsiMethod getSelectedMethod() { + if(myEnclosingMethodsList != null) { + return (PsiMethod) myEnclosingMethodsList.getSelectedValue(); + } + else { + return null; + } + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction()/*, getHelpAction()*/}; + } + + public JComponent getPreferredFocusedComponent() { + return myEnclosingMethodsList; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createBorder()); + + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 0; + gbConstraints.weightx = 1; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.gridheight = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.anchor = GridBagConstraints.WEST; + panel.add(new JLabel("Introduce parameter to method:"), gbConstraints); + + gbConstraints.weighty = 1; + myEnclosingMethodsList = new JList(myEnclosingMethods.toArray()); + myEnclosingMethodsList.setCellRenderer(new MethodCellRenderer()); + myEnclosingMethodsList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + int indexToSelect = 0; + myEnclosingMethodsList.setSelectedIndex(indexToSelect); + gbConstraints.gridy++; + panel.add(new JScrollPane(myEnclosingMethodsList), gbConstraints); + + return panel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.introduceParameter.EnclosingMethodSelectonDialog"; + } + + protected void doOKAction() { + if (!isOKActionEnabled()) + return; + + super.doOKAction(); + } + + protected JComponent createCenterPanel() { + return null; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ExternalUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ExternalUsageInfo.java new file mode 100644 index 00000000000..658c074ad90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ExternalUsageInfo.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class ExternalUsageInfo extends UsageInfo { + public ExternalUsageInfo(PsiElement element) { + super(element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InExprUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InExprUsageInfo.java new file mode 100644 index 00000000000..436da1ae5ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InExprUsageInfo.java @@ -0,0 +1,22 @@ +/* +* Created by IntelliJ IDEA. +* User: dsl +* Date: 06.05.2002 +* Time: 15:02:15 +* To change template for new class use +* Code Style | Class Templates options (Tools | IDE Options). +*/ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.UsageInfo; + +/** + * Usage inside an expression + */ +public class InExprUsageInfo extends UsageInfo { + InExprUsageInfo(PsiElement elem) { + super(elem); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InternalUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InternalUsageInfo.java new file mode 100644 index 00000000000..916fc3d56f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/InternalUsageInfo.java @@ -0,0 +1,21 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 07.05.2002 + * Time: 11:26:45 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.UsageInfo; + +/** + * Usage of an expression in method + */ +public class InternalUsageInfo extends UsageInfo { + InternalUsageInfo(PsiElement e) { + super(e); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java new file mode 100644 index 00000000000..74c4dbeba92 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java @@ -0,0 +1,372 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 16:54:19 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiType; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.IntroduceParameterRefactoring; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.ui.*; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.List; + +public class IntroduceParameterDialog extends RefactoringDialog { + private TypeSelector myTypeSelector; + private NameSuggestionsManager myNameSuggestionsManager; + + public static interface Callback { + void run(IntroduceParameterDialog dialog); + } + + private Project myProject; + private List myClassMembersList; + private int myOccurenceNumber; + private final boolean myIsInvokedOnDeclaration; + private boolean myIsLocalVariable; + private boolean myHasInitializer; + +// private JComponent myParameterNameField = null; + private NameSuggestionsField myParameterNameField; + private JCheckBox myCbReplaceAllOccurences = null; + private JCheckBox myCbDeclareFinal = null; + private StateRestoringCheckBox myCbDeleteLocalVariable = null; + private StateRestoringCheckBox myCbUseInitializer = null; + + private JRadioButton myReplaceFieldsWithGettersNoneRadio = null; + private JRadioButton myReplaceFieldsWithGettersInaccessibleRadio = null; + private JRadioButton myReplaceFieldsWithGettersAllRadio = null; + + private ButtonGroup myReplaceFieldsWithGettersButtonGroup = new ButtonGroup(); + + private Callback myCallback; + private final NameSuggestionsGenerator myNameSuggestionsGenerator; + private final TypeSelectorManager myTypeSelectorManager; + + + IntroduceParameterDialog(Project project, List localVarsList, + List parameterList, List classMembersList, int occurenceNumber, + boolean isInvokedOnDeclaration, boolean isLocalVariable, + boolean hasInitializer, Callback callback, NameSuggestionsGenerator generator, + TypeSelectorManager typeSelectorManager) { + super(project, true); + myProject = project; + myClassMembersList = classMembersList; + myOccurenceNumber = occurenceNumber; + myIsInvokedOnDeclaration = isInvokedOnDeclaration; + myIsLocalVariable = isLocalVariable; + myHasInitializer = hasInitializer; + myCallback = callback; + myNameSuggestionsGenerator = generator; + myTypeSelectorManager = typeSelectorManager; + + setTitle("Introduce Parameter"); + init(); + } + + public boolean isDeclareFinal() { + if (myCbDeclareFinal != null) { + return myCbDeclareFinal.isSelected(); + } else { + return false; + } + } + + public boolean isReplaceAllOccurences() { + if(myIsInvokedOnDeclaration) + return true; + if (myCbReplaceAllOccurences != null) { + return myCbReplaceAllOccurences.isSelected(); + } + else + return false; + } + + public boolean isDeleteLocalVariable() { + if(myIsInvokedOnDeclaration) + return true; + if(myCbDeleteLocalVariable != null) { + return myCbDeleteLocalVariable.isSelected(); + } + else + return false; + } + + public boolean isUseInitializer() { + if(myIsInvokedOnDeclaration) + return myHasInitializer; + if(myCbUseInitializer != null) { + return myCbUseInitializer.isSelected(); + } + else + return false; + } + + public String getParameterName() { + return myParameterNameField.getName(); + } + + public int getReplaceFieldsWithGetters() { + if(myReplaceFieldsWithGettersAllRadio != null && myReplaceFieldsWithGettersAllRadio.isSelected()) { + return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL; + } + else if(myReplaceFieldsWithGettersInaccessibleRadio != null + && myReplaceFieldsWithGettersInaccessibleRadio.isSelected()) { + return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE; + } + else if(myReplaceFieldsWithGettersNoneRadio != null && myReplaceFieldsWithGettersNoneRadio.isSelected()) { + return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE; + } + + return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE; + } + + public JComponent getPreferredFocusedComponent() { + return myParameterNameField.getComponent(); + } + + public PsiType getSelectedType() { + return myTypeSelector.getSelectedType(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.INTRODUCE_PARAMETER); + } + + protected JComponent createNorthPanel() { + GridBagConstraints gbConstraints = new GridBagConstraints(); + + JPanel panel = new JPanel(new GridBagLayout()); + + gbConstraints.anchor = GridBagConstraints.WEST; + gbConstraints.fill = GridBagConstraints.NONE; + gbConstraints.gridx = 0; + + gbConstraints.insets = new Insets(4, 4, 4, 0); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 0; + gbConstraints.gridy = 0; + JLabel type = new JLabel("Parameter of type: "); + panel.add(type, gbConstraints); + + gbConstraints.insets = new Insets(4, 4, 4, 8); + gbConstraints.gridx++; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myTypeSelector = myTypeSelectorManager.getTypeSelector(); + panel.add(myTypeSelector.getComponent(), gbConstraints); + + + gbConstraints.insets = new Insets(4, 4, 4, 8); + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + gbConstraints.fill = GridBagConstraints.NONE; + final JLabel nameLabel = new JLabel("Name: "); + panel.add(nameLabel, gbConstraints); + +/* + if (myNameSuggestions.length > 1) { + myParameterNameField = createComboBoxForName(); + } + else { + myParameterNameField = createTextFieldForName(); + } +*/ + myParameterNameField = new NameSuggestionsField(myProject); + gbConstraints.gridx++; + gbConstraints.insets = new Insets(4, 4, 4, 8); + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + panel.add(myParameterNameField.getComponent(), gbConstraints); + myParameterNameField.addDataChangedListener(new NameSuggestionsField.DataChanged() { + public void dataChanged() { + validateButtons(); + } + }); + + myNameSuggestionsManager = + new NameSuggestionsManager(myTypeSelector, myParameterNameField, myNameSuggestionsGenerator, myProject); + myNameSuggestionsManager.setMnemonics(type, nameLabel); + + gbConstraints.gridx = 0; + gbConstraints.insets = new Insets(4, 0, 4, 8); + gbConstraints.gridwidth = 2; + if (myOccurenceNumber > 1 && !myIsInvokedOnDeclaration) { + gbConstraints.gridy++; + myCbReplaceAllOccurences = new NonFocusableCheckBox("Replace all occurences (" + myOccurenceNumber + " occurences)"); + myCbReplaceAllOccurences.setMnemonic('R'); + panel.add(myCbReplaceAllOccurences, gbConstraints); + myCbReplaceAllOccurences.setSelected(false); + } + + RefactoringSettings settings = RefactoringSettings.getInstance(); + + gbConstraints.gridy++; + myCbDeclareFinal = new NonFocusableCheckBox("Declare final"); + myCbDeclareFinal.setMnemonic('n'); + myCbDeclareFinal.setSelected(CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS); + panel.add(myCbDeclareFinal, gbConstraints); + + + if(myIsLocalVariable && !myIsInvokedOnDeclaration) { + myCbDeleteLocalVariable = new StateRestoringCheckBox("Delete variable definition"); + myCbDeleteLocalVariable.setMnemonic('D'); + if(myCbReplaceAllOccurences != null) { + gbConstraints.insets = new Insets(0, 16, 4, 8); + } + gbConstraints.gridy++; + panel.add(myCbDeleteLocalVariable, gbConstraints); + myCbDeleteLocalVariable.setSelected(settings.INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE); + + gbConstraints.insets = new Insets(4, 0, 4, 8); + if(myHasInitializer) { + myCbUseInitializer = new StateRestoringCheckBox("Use variable initializer to initialize parameter"); + myCbUseInitializer.setMnemonic('U'); + gbConstraints.gridy++; + panel.add(myCbUseInitializer, gbConstraints); + } + } + + updateControls(); + if (myCbReplaceAllOccurences != null) { + myCbReplaceAllOccurences.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateControls(); + } + } + ); + } + return panel; + } + + private void updateControls() { + if(myCbReplaceAllOccurences != null) { + myTypeSelectorManager.setAllOccurences(myCbReplaceAllOccurences.isSelected()); + if(myCbReplaceAllOccurences.isSelected()) { + if (myCbDeleteLocalVariable != null) { + myCbDeleteLocalVariable.makeSelectable(); + } + } + else { + if (myCbDeleteLocalVariable != null) { + myCbDeleteLocalVariable.makeUnselectable(false); + } + } + } else { + myTypeSelectorManager.setAllOccurences(myIsInvokedOnDeclaration); + } + + } + + private JPanel createReplaceFieldsWithGettersPanel() { + JPanel radioButtonPanel = new JPanel(new GridBagLayout()); + + radioButtonPanel.setBorder(IdeBorderFactory.createBorder()); + + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.anchor = GridBagConstraints.WEST; + radioButtonPanel.add( + new JLabel("Replace fields used in expressions with their getters"), gbConstraints); + + myReplaceFieldsWithGettersNoneRadio = + new JRadioButton("Do not replace"); + myReplaceFieldsWithGettersNoneRadio.setMnemonic('N'); + myReplaceFieldsWithGettersInaccessibleRadio = + new JRadioButton("Replace fields inaccessble in usage context"); + myReplaceFieldsWithGettersInaccessibleRadio.setMnemonic('I'); + myReplaceFieldsWithGettersAllRadio = + new JRadioButton("Replace all fields"); + myReplaceFieldsWithGettersAllRadio.setMnemonic('A'); + + gbConstraints.gridy++; + radioButtonPanel.add(myReplaceFieldsWithGettersNoneRadio, gbConstraints); + gbConstraints.gridy++; + radioButtonPanel.add(myReplaceFieldsWithGettersInaccessibleRadio, gbConstraints); + gbConstraints.gridy++; + radioButtonPanel.add(myReplaceFieldsWithGettersAllRadio, gbConstraints); + + final int currentSetting = RefactoringSettings.getInstance().INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS; + + myReplaceFieldsWithGettersButtonGroup.add(myReplaceFieldsWithGettersNoneRadio); + myReplaceFieldsWithGettersButtonGroup.add(myReplaceFieldsWithGettersInaccessibleRadio); + myReplaceFieldsWithGettersButtonGroup.add(myReplaceFieldsWithGettersAllRadio); + + if(currentSetting == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL) { + myReplaceFieldsWithGettersAllRadio.setSelected(true); + } + else if(currentSetting == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE) { + myReplaceFieldsWithGettersInaccessibleRadio.setSelected(true); + } + else if(currentSetting == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) { + myReplaceFieldsWithGettersNoneRadio.setSelected(true); + } + + return radioButtonPanel; + } + + protected JComponent createCenterPanel() { + if(Util.anyFieldsWithGettersPresent(myClassMembersList)) { + return createReplaceFieldsWithGettersPanel(); + } + else + return null; + } + + protected void doAction() { + if (!isOKActionEnabled()) return; + + final RefactoringSettings settings = RefactoringSettings.getInstance(); + settings.INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS = + getReplaceFieldsWithGetters(); + + if(myCbDeleteLocalVariable != null) { + settings.INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE = + myCbDeleteLocalVariable.isSelectedWhenSelectable(); + } + + myNameSuggestionsManager.nameSelected(); + myCallback.run(this); + myParameterNameField.requestFocusInWindow(); + } + + + protected boolean areButtonsValid () { + String name = getParameterName(); + if (name == null) { + return false; + } + else { + return PsiManager.getInstance(myProject).getNameHelper().isIdentifier(name.trim()); + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java new file mode 100644 index 00000000000..e0b881c0560 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -0,0 +1,279 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 13:36:30 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.IntroduceParameterRefactoring; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.IntroduceHandlerBase; +import com.intellij.refactoring.introduceField.ElementToWorkOn; +import com.intellij.refactoring.ui.NameSuggestionsGenerator; +import com.intellij.refactoring.ui.TypeSelectorManager; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + + +public class IntroduceParameterHandler extends IntroduceHandlerBase implements RefactoringActionHandler, IntroduceParameterDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.IntroduceParameterHandler"); + private static final String REFACTORING_NAME = "Introduce Parameter"; + private PsiExpression myParameterInitializer; + private PsiExpression myExpressionToSearchFor; + private PsiLocalVariable myLocalVar; + private PsiMethod myMethod; + private PsiMethod myMethodToSearchFor; + private Project myProject; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + ElementToWorkOn elementToWorkOn = + ElementToWorkOn.getElementToWorkOn(editor, file, REFACTORING_NAME, HelpID.INTRODUCE_PARAMETER, project); + if(elementToWorkOn == null) return; + + final PsiExpression expr = elementToWorkOn.getExpression(); + final PsiLocalVariable localVar = elementToWorkOn.getLocalVariable(); + final boolean isInvokedOnDeclaration = elementToWorkOn.isInvokedOnDeclaration(); + + if (invoke(editor, project, expr, localVar, isInvokedOnDeclaration)) { + editor.getSelectionModel().removeSelection(); + } + } + + protected boolean invokeImpl(Project project, PsiExpression tempExpr, Editor editor) { + return invoke(editor, project, tempExpr, null, false); + } + + protected boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) { + return invoke(editor, project, null, localVariable, true); + } + + private boolean invoke(Editor editor, Project project, final PsiExpression expr, + PsiLocalVariable localVar, boolean invokedOnDeclaration) { + + final PsiMethod method; + if (expr != null) { + method = Util.getContainingMethod(expr); + } else { + method = Util.getContainingMethod(localVar); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("expression:" + expr); + } + + myLocalVar = localVar; + myProject = project; + if (expr == null && myLocalVar == null) { + String message = + "Cannot perform the refactoring.\n" + + "Selected block should represent an expression."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INTRODUCE_PARAMETER, myProject); + return false; + } + + + myMethod = method; + if (myMethod == null) { + String message = + "Cannot perform the refactoring.\n" + + REFACTORING_NAME + " is not supported in the current context."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INTRODUCE_PARAMETER, myProject); + return false; + } + + if (!myMethod.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, myMethod); + return false; + } + + final PsiType typeByExpression = !invokedOnDeclaration ? RefactoringUtil.getTypeByExpressionWithExpectedType(expr) : null; + if (!invokedOnDeclaration && typeByExpression == null) { + String message = + "Cannot perform the refactoring.\n" + + "Type of the selected expression cannot be determined."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INTRODUCE_PARAMETER, myProject); + return false; + } + + if (!invokedOnDeclaration && typeByExpression == PsiType.VOID) { + String message = + "Cannot perform the refactoring.\n" + + "Selected expression has void type."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INTRODUCE_PARAMETER, project); + return false; + } + + final List validEnclosingMethods = getEnclosingMethods(myMethod); + if (validEnclosingMethods.size() > 1 && !ApplicationManager.getApplication().isUnitTestMode()) { + final EnclosingMethodSelectionDialog dialog = new EnclosingMethodSelectionDialog(project, validEnclosingMethods); + dialog.show(); + if (!dialog.isOK()) return false; + myMethod = dialog.getSelectedMethod(); + } + + myMethodToSearchFor = SuperMethodWarningUtil.checkSuperMethod(myMethod, "refactor"); + + if (myMethodToSearchFor == null) { + return false; + } + if (!myMethodToSearchFor.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, myMethodToSearchFor); + return false; + } + + PsiExpression[] occurences; + if (expr != null) { + occurences = CodeInsightUtil.findExpressionOccurrences(myMethod, expr); + } else { // local variable + occurences = CodeInsightUtil.findReferenceExpressions(myMethod, myLocalVar); + } + if (editor != null) { + RefactoringUtil.highlightOccurences(myProject, occurences, editor); + } + + ArrayList localVars = new ArrayList(); + ArrayList classMemberRefs = new ArrayList(); + ArrayList params = new ArrayList(); + + + if (expr != null) { + Util.analyzeExpression(expr, localVars, classMemberRefs, params); + } + + boolean previewUsages = false; + String parameterName = "anObject"; + boolean replaceAllOccurences = true; + boolean isDeleteLocalVariable = true; + myParameterInitializer = expr; + myExpressionToSearchFor = expr; + + if (expr instanceof PsiReferenceExpression) { + PsiElement resolved = ((PsiReferenceExpression) expr).resolve(); + if (resolved instanceof PsiLocalVariable) { + myLocalVar = (PsiLocalVariable) resolved; + } + } + + + if (!ApplicationManager.getApplication().isUnitTestMode()) { + final String propName = myLocalVar != null ? CodeStyleManager.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; + final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, expr, myLocalVar); + + TypeSelectorManager typeSelectorManager = + (expr != null ? + new TypeSelectorManagerImpl(project, initializerType, expr, occurences) : + new TypeSelectorManagerImpl(project, initializerType, occurences)); + + final IntroduceParameterDialog dialog = + new IntroduceParameterDialog( + myProject, localVars, params, classMemberRefs, + occurences.length, + expr == null, myLocalVar != null, + (myLocalVar != null) && (myLocalVar.getInitializer() != null), + this, + new NameSuggestionsGenerator() { + public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { + return CodeStyleManager.getInstance(myProject).suggestVariableName(VariableKind.PARAMETER, propName, expr, initializerType); + } + + public Pair> completeVariableName(String prefix, + PsiType type) { + LinkedHashSet set = new LinkedHashSet(); + LookupItemPreferencePolicy policy = CompletionUtil.completeVariableName(myProject, set, prefix, type, VariableKind.PARAMETER); + return new Pair> (policy, set); + } + }, + typeSelectorManager); + dialog.show(); + + if (!dialog.isOK()) { + return true; + } + + return true; + } + + new IntroduceParameterProcessor( + myProject, myMethod, myMethodToSearchFor, + myParameterInitializer, myExpressionToSearchFor, + myLocalVar, isDeleteLocalVariable, + parameterName, previewUsages, replaceAllOccurences, + IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, null, null).run(null); + return true; + } + + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + // Never called + /* do nothing */ + } + + public void run(final IntroduceParameterDialog dialog) { + boolean isDeleteLocalVariable = false; + + if (myLocalVar != null) { + if (dialog.isUseInitializer()) { + PsiExpression varInitializer = myLocalVar.getInitializer(); + if (varInitializer != null) { + myParameterInitializer = varInitializer; + } + } + isDeleteLocalVariable = dialog.isDeleteLocalVariable(); + } + + new IntroduceParameterProcessor( + myProject, myMethod, myMethodToSearchFor, + myParameterInitializer, myExpressionToSearchFor, + myLocalVar, isDeleteLocalVariable, + dialog.getParameterName(), dialog.isPreviewUsages(), dialog.isReplaceAllOccurences(), + dialog.getReplaceFieldsWithGetters(), dialog.isDeclareFinal(), + dialog.getSelectedType(), new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }).run(null); + } + + + private static List getEnclosingMethods(PsiMethod nearest) { + List enclosingMethods = new ArrayList(); + enclosingMethods.add(nearest); + PsiMethod method = nearest; + while(true) { + method = PsiTreeUtil.getParentOfType(method, PsiMethod.class, true); + if (method == null) break; + enclosingMethods.add(method); + } + return enclosingMethods; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java new file mode 100644 index 00000000000..19e8a1462fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java @@ -0,0 +1,778 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 07.05.2002 + * Time: 11:17:31 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.IntroduceParameterRefactoring; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.FieldConflictsResolver; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.refactoring.util.javadoc.MethodJavaDocHelper; +import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager; +import com.intellij.refactoring.util.occurences.LocalVariableOccurenceManager; +import com.intellij.refactoring.util.occurences.OccurenceManager; +import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo; +import com.intellij.refactoring.util.usageInfo.DefaultConstructorUsageCollector; +import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashSet; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class IntroduceParameterProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.IntroduceParameterProcessor"); + + private PsiMethod myMethodToReplaceIn; + private PsiMethod myMethodToSearchFor; + private PsiExpression myParameterInitializer; + private final PsiExpression myExpressionToSearch; + private final PsiLocalVariable myLocalVariable; + private final boolean myRemoveLocalVariable; + private String myParameterName; + private boolean myPreviewUsages; + private boolean myReplaceAllOccurences; + + private int myReplaceFieldsWithGetters; + private final boolean myDeclareFinal; + private PsiType myForcedType; + private PsiManager myManager; + + /** + * if expressionToSearch is null, search for localVariable + */ + public IntroduceParameterProcessor(Project project, PsiMethod methodToReplaceIn, PsiMethod methodToSearchFor, + PsiExpression parameterInitializer, + PsiExpression expressionToSearch, + PsiLocalVariable localVariable, + boolean removeLocalVariable, String parameterName, boolean previewUsages, boolean replaceAllOccurences, + int replaceFieldsWithGetters, boolean declareFinal, PsiType forcedType, Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + + myMethodToReplaceIn = methodToReplaceIn; + myMethodToSearchFor = methodToSearchFor; + myParameterInitializer = parameterInitializer; + myExpressionToSearch = expressionToSearch; + + myLocalVariable = localVariable; + myRemoveLocalVariable = removeLocalVariable; + myParameterName = parameterName; + myPreviewUsages = previewUsages; + myReplaceAllOccurences = replaceAllOccurences; + myReplaceFieldsWithGetters = replaceFieldsWithGetters; + myDeclareFinal = declareFinal; + myForcedType = forcedType; + myManager = PsiManager.getInstance(project); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new IntroduceParameterViewDescriptor(myMethodToSearchFor, usages, refreshCommand); + } + + public PsiType getForcedType() { + return myForcedType; + } + + public void setForcedType(PsiType forcedType) { + myForcedType = forcedType; + } + + public int getReplaceFieldsWithGetters() { + return myReplaceFieldsWithGetters; + } + + public void setReplaceFieldsWithGetters(int replaceFieldsWithGetters) { + myReplaceFieldsWithGetters = replaceFieldsWithGetters; + } + + protected UsageInfo[] findUsages() { + ArrayList result = new ArrayList(); + PsiSearchHelper helper = myManager.getSearchHelper(); + + PsiMethod[] overridingMethods = helper.findOverridingMethods(myMethodToSearchFor, GlobalSearchScope.projectScope(myProject), true); + for (int j = 0; j < overridingMethods.length; j++) { + result.add(new UsageInfo(overridingMethods[j])); + } + + if(myMethodToSearchFor.isConstructor()) { + final PsiParameter[] parameters = myMethodToSearchFor.getParameterList().getParameters(); + if(parameters.length == 0) { + addImplicitDefaultConstructorUsages(result, myMethodToSearchFor.getContainingClass()); + } + } + + PsiReference[] refs = helper.findReferencesIncludingOverriding(myMethodToSearchFor, GlobalSearchScope.projectScope(myProject), true); + + int i; + for (i = 0; i < refs.length; i++) { + PsiElement ref = refs[i].getElement(); + if (!insideMethodToBeReplaced(ref)) { + result.add(new ExternalUsageInfo(ref)); + } + else { + result.add(new ChangedMethodCallInfo(ref)); + } + } + + if (myReplaceAllOccurences) { + PsiElement[] exprs; + final OccurenceManager occurenceManager; + if(myLocalVariable == null) { + occurenceManager = new ExpressionOccurenceManager(myExpressionToSearch, myMethodToReplaceIn, null); + } else { + occurenceManager = new LocalVariableOccurenceManager(myLocalVariable, null); + } + exprs = occurenceManager.getOccurences(); + for (i = 0; i < exprs.length; i++) { + PsiElement expr = exprs[i]; + + result.add(new InternalUsageInfo(expr)); + } + } + else { + if (myExpressionToSearch != null) { + result.add(new InternalUsageInfo(myExpressionToSearch)); + } + } + + final UsageInfo[] usageInfos = result.toArray(new UsageInfo[0]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + private void addImplicitDefaultConstructorUsages(final ArrayList result, PsiClass aClass) { + final RefactoringUtil.ImplicitConstructorUsageVisitor implicitConstructorUsageVistor + = new DefaultConstructorUsageCollector(result); + + RefactoringUtil.visitImplicitConstructorUsages(aClass, implicitConstructorUsageVistor); + } + + private static class ReferencedElementsCollector extends PsiRecursiveElementVisitor { + private Set myResult = new HashSet(); + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + super.visitReferenceElement(reference); + final PsiElement element = reference.resolve(); + if (element != null) { + myResult.add(element); + } + } + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + ArrayList conflicts = new ArrayList (); + + AnySameNameVariables anySameNameVariables = new AnySameNameVariables(); + myMethodToReplaceIn.accept(anySameNameVariables); + if (anySameNameVariables.getConflict() != null) { + conflicts.add(anySameNameVariables.getConflict()); + } + + final UsageInfo[] usageArray = usages[0]; + detectAccessibilityConflicts(usageArray, conflicts); + + if (myParameterInitializer != null && !myMethodToReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) { + final AnySupers anySupers = new AnySupers(); + myParameterInitializer.accept(anySupers); + if (anySupers.isResult()) { + final UsageInfo[] u = usages[0]; + for (int i = 0; i < u.length; i++) { + UsageInfo usageInfo = u[i]; + if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) { + final PsiElement element = usageInfo.getElement(); + if (!PsiTreeUtil.isAncestor(myMethodToReplaceIn.getContainingClass(), element, false)) { + conflicts.add("Parameter initializer contains " + ConflictsUtil.htmlEmphasize("super") + + ", but not all calls to method are in its class."); + break; + } + } + } + } + } + if(conflicts.size() > 0 && myPrepareSuccessfulSwingThreadCallback!= null) { + ConflictsDialog dialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), myProject); + dialog.show(); + if(!dialog.isOK()) return false; + } + + prepareSuccessful(); + return true; + } + + private void detectAccessibilityConflicts(final UsageInfo[] usageArray, ArrayList conflicts) { + if (myParameterInitializer != null) { + final ReferencedElementsCollector collector = new ReferencedElementsCollector(); + myParameterInitializer.accept(collector); + final Set result = collector.myResult; + if (!result.isEmpty()) { + for (int i = 0; i < usageArray.length; i++) { + final UsageInfo usageInfo = usageArray[i]; + if (usageInfo instanceof ExternalUsageInfo && RefactoringUtil.isMethodUsage(usageInfo.getElement())) { + final PsiElement place = usageInfo.getElement(); + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + final PsiElement element = iterator.next(); + if (element instanceof PsiMember && + !myManager.getResolveHelper().isAccessible((PsiMember)element, place, null)) { + String message = + ConflictsUtil.getDescription(element, true) + " is not accesible from " + + ConflictsUtil.getDescription(ConflictsUtil.getContainer(place), true) + ". " + + "Value for introduced parameter in that method call will be incorrect."; + conflicts.add(message); + } + } + } + } + } + } + } + + + public class AnySupers extends PsiRecursiveElementVisitor { + private boolean myResult = false; + public void visitSuperExpression(PsiSuperExpression expression) { + myResult = true; + } + + public boolean isResult() { + return myResult; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + } + + public class AnySameNameVariables extends PsiRecursiveElementVisitor { + private String conflict = null; + + public String getConflict() { + return conflict; + } + + public void visitVariable(PsiVariable variable) { + if (variable == myLocalVariable) return; + if (variable.getName().equals(myParameterName)) { + StringBuffer buffer = new StringBuffer(); + + buffer.append("There is already a "); + buffer.append(ConflictsUtil.getDescription(variable, true)); + buffer.append(". It will conflict with an introduced parameter"); + + conflict = ConflictsUtil.capitalize(buffer.toString()); + } + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + } + + public void visitElement(PsiElement element) { + if(conflict != null) return; + super.visitElement(element); + } + } + + private boolean insideMethodToBeReplaced(PsiElement methodUsage) { + PsiElement parent = methodUsage.getParent(); + while(parent != null) { + if(parent.equals(myMethodToReplaceIn)) + return true; + parent = parent.getParent(); + } + return false; + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return myPreviewUsages || super.isPreviewUsages(usages); + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + PsiElementFactory factory = myMethodToReplaceIn.getManager().getElementFactory(); + + PsiType initializerType = getInitializerType(myForcedType, myParameterInitializer, myLocalVariable); + + + // Converting myParameterInitializer + if (myParameterInitializer != null) { + myParameterInitializer = + RefactoringUtil.convertInitializerToNormalExpression(myParameterInitializer, initializerType); + } else { + LOG.assertTrue(myLocalVariable != null); + myParameterInitializer = factory.createExpressionFromText(myLocalVariable.getName(), myLocalVariable); + } + + + // Changing external occurences (the tricky part) + ChangeContextUtil.encodeContextInfo(myParameterInitializer, true); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + + if (!(usage instanceof InternalUsageInfo)) { + if(usage instanceof DefaultConstructorImplicitUsageInfo) { + addSuperCall(((DefaultConstructorImplicitUsageInfo) usage).getConstructor()); + } else if(usage instanceof NoConstructorClassUsageInfo) { + addDefaultConstructor(((NoConstructorClassUsageInfo) usage).getPsiClass()); + } else if (usage.getElement() instanceof PsiMethod) { + if (!myManager.areElementsEquivalent(usage.getElement(), myMethodToReplaceIn)) { + changeMethodSignatureAndResolveFieldConflicts((PsiMethod)usage.getElement(), initializerType); + } + } + else { + changeExternalUsage(usage); + } + } + } + // Changing signature of initial method + // (signature of myMethodToReplaceIn will be either changed now or have already been changed) + LOG.assertTrue(initializerType.isValid()); + final FieldConflictsResolver fieldConflictsResolver = + new FieldConflictsResolver(myParameterName, myMethodToReplaceIn.getBody()); + changeMethodSignature(myMethodToReplaceIn, initializerType); + if (myMethodToSearchFor != myMethodToReplaceIn) { + changeMethodSignatureAndResolveFieldConflicts(myMethodToSearchFor, initializerType); + } + ChangeContextUtil.clearContextInfo(myParameterInitializer); + + // Replacing expression occurences + for (int j = 0; j < usages.length; j++) { + UsageInfo usage = usages[j]; + + if(usage instanceof ChangedMethodCallInfo) { + PsiElement element = usage.getElement(); + + processChangedMethodCall(element); + } + else if (usage instanceof InternalUsageInfo) { + PsiElement element = usage.getElement(); + if(element instanceof PsiExpression) { + element = RefactoringUtil.outermostParenthesizedExpression((PsiExpression) element); + } + PsiElement newExpr = factory.createExpressionFromText(myParameterName, element); + element.replace(newExpr); + } + } + + if(myLocalVariable != null && myRemoveLocalVariable) { + myLocalVariable.normalizeDeclaration(); + myLocalVariable.getParent().delete(); + } + fieldConflictsResolver.fix(); + } + catch (IncorrectOperationException ex) { + LOG.assertTrue(false); + } + } + + private void addDefaultConstructor(PsiClass aClass) throws IncorrectOperationException { + if (!(aClass instanceof PsiAnonymousClass)) { + final PsiElementFactory factory = myManager.getElementFactory(); + PsiMethod constructor = factory.createMethodFromText(aClass.getName() + "(){}", aClass); + constructor = (PsiMethod) CodeStyleManager.getInstance(myProject).reformat(constructor); + constructor = (PsiMethod) aClass.add(constructor); + constructor.getModifierList().setModifierProperty(VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true); + addSuperCall(constructor); + } + } + + private void addSuperCall(PsiMethod constructor) throws IncorrectOperationException { + final PsiElementFactory factory = myManager.getElementFactory(); + PsiExpressionStatement superCall = + (PsiExpressionStatement) factory.createStatementFromText("super();", constructor); + superCall = (PsiExpressionStatement) CodeStyleManager.getInstance(myProject).reformat(superCall); + final PsiStatement[] statements = constructor.getBody().getStatements(); + if(statements.length > 0) { + superCall = (PsiExpressionStatement) constructor.getBody().addBefore(superCall, statements[0]); + } else { + superCall = (PsiExpressionStatement) constructor.getBody().add(superCall); + } + PsiCallExpression expression = (PsiCallExpression) superCall.getExpression(); + fixActualArgumentsList(expression); + } + + private void fixActualArgumentsList(PsiCallExpression expression) throws IncorrectOperationException { + PsiExpression newArg = (PsiExpression) expression.getArgumentList().add(myParameterInitializer); + new OldReferencesResolver(expression, newArg, myReplaceFieldsWithGetters).resolve(); + } + + static PsiType getInitializerType(PsiType forcedType, PsiExpression parameterInitializer, PsiLocalVariable localVariable) { + final PsiType initializerType; + if (forcedType == null) { + if (parameterInitializer == null) { + if (localVariable != null) { + initializerType = localVariable.getType(); + } else { + LOG.assertTrue(false); + initializerType = null; + } + } else { + if (localVariable == null) { + initializerType = RefactoringUtil.getTypeByExpressionWithExpectedType(parameterInitializer); + } else { + initializerType = localVariable.getType(); + } + } + } else { + initializerType = forcedType; + } + return initializerType; + } + + private void processChangedMethodCall(PsiElement element) + throws IncorrectOperationException { + if(element.getParent() instanceof PsiMethodCallExpression) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression) element.getParent(); + + PsiElementFactory factory = methodCall.getManager().getElementFactory(); + PsiElement newArg = factory.createExpressionFromText(myParameterName, null); + PsiExpressionList argList = methodCall.getArgumentList(); + PsiExpression[] exprs = argList.getExpressions(); + + if (exprs.length > 0) { + argList.addAfter(newArg, exprs[exprs.length - 1]); + } + else { + argList.add(newArg); + } + } + else { + LOG.assertTrue(false); + } + } + + private void changeExternalUsage(UsageInfo usage) throws IncorrectOperationException { + if(!RefactoringUtil.isMethodUsage(usage.getElement())) + return; + + PsiCallExpression callExpression = + RefactoringUtil.getCallExpressionByMethodReference((PsiJavaCodeReferenceElement) usage.getElement()); + PsiExpressionList argList = callExpression.getArgumentList(); + PsiExpression[] oldArgs = argList.getExpressions(); + + PsiExpression newArg; + final PsiExpression anchor; + if (!myMethodToSearchFor.isVarArgs()) { + anchor = getLast(oldArgs); + } + else { + final PsiParameter[] parameters = myMethodToSearchFor.getParameterList().getParameters(); + if (parameters.length > oldArgs.length) { + anchor = getLast(oldArgs); + } + else { + LOG.assertTrue(parameters.length > 0); + final int lastNonVararg = parameters.length - 2; + anchor = lastNonVararg >= 0 ? oldArgs[lastNonVararg] : null; + } + } + newArg = (PsiExpression) argList.addAfter(myParameterInitializer, anchor); + ChangeContextUtil.decodeContextInfo(newArg, null, null); + + // here comes some postprocessing... + new OldReferencesResolver(callExpression, newArg, myReplaceFieldsWithGetters).resolve(); + } + + private PsiExpression getLast(PsiExpression[] oldArgs) { + PsiExpression anchor; + if (oldArgs.length > 0) { + anchor = oldArgs[oldArgs.length - 1]; + } + else { + anchor = null; + } + return anchor; + } + + static PsiElement getClassContainingResolve (final ResolveResult result) { + final PsiElement elem = result.getElement (); + if (elem != null) { + if (elem instanceof PsiLocalVariable || elem instanceof PsiParameter) { + return PsiTreeUtil.getParentOfType (elem, PsiClass.class); + } + else { + return result.getCurrentFileResolveScope(); + } + } + return null; + } + + + private class OldReferencesResolver { + private PsiCallExpression myContext; + private PsiExpression myExpr; + private HashMap myTempVars; + private PsiExpression myInstanceRef; + private PsiExpression[] myActualArgs; + private final int myReplaceFieldsWithGetters; + + public OldReferencesResolver(PsiCallExpression context, PsiExpression expr, int replaceFieldsWithGetters) { + myContext = context; + myExpr = expr; + myTempVars = new com.intellij.util.containers.HashMap(); + myActualArgs = myContext.getArgumentList().getExpressions(); + if(myContext instanceof PsiMethodCallExpression) { + myInstanceRef = ((PsiMethodCallExpression)myContext).getMethodExpression().getQualifierExpression(); + } + else { + // todo: distinguish between 'null' instance ref (when instance ref is "this") + // and unavailable instance ref (as in 'new A()') + myInstanceRef = null; + } + myReplaceFieldsWithGetters = replaceFieldsWithGetters; + } + + public void resolve() throws IncorrectOperationException { + resolveOldReferences(myExpr, myParameterInitializer); + + Set> mappingsSet = myTempVars.entrySet(); + + PsiElementFactory factory = myContext.getManager().getElementFactory(); + + for (Iterator> iterator = mappingsSet.iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + + PsiExpression oldRef = entry.getKey(); + PsiElement newRef = factory.createExpressionFromText(entry.getValue(), null); + oldRef.replace(newRef); + } + } + + + private void resolveOldReferences(PsiElement expr, PsiElement oldExpr) + throws IncorrectOperationException { + if (expr == null || oldExpr == null) return; + PsiManager manager = myParameterInitializer.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + PsiElement newExpr = expr; // references continue being resolved in the children of newExpr + + if (oldExpr instanceof PsiReferenceExpression) { + final PsiReferenceExpression oldRef = (PsiReferenceExpression) oldExpr; + final ResolveResult adv = oldRef.advancedResolve(false); + final PsiElement scope = getClassContainingResolve (adv); + final PsiClass clss = PsiTreeUtil.getParentOfType (oldExpr, PsiClass.class); + if (PsiTreeUtil.isAncestor (clss, scope, false)) { + + final PsiElement subj = adv.getElement (); + + + // Parameters + if (subj instanceof PsiParameter) { + PsiParameterList formalArgList = myMethodToReplaceIn.getParameterList(); + if (formalArgList != null) { + PsiParameter[] formalArgs = formalArgList.getParameters(); + + int index; + for (index = 0; index < formalArgs.length; index++) { + if (subj.equals(formalArgs[index])) break; + } + if (index < formalArgs.length) { + PsiExpression actualArg; + try { + actualArg = myActualArgs[index]; + } + catch (NullPointerException $ex) { + return; + } + catch (ArrayIndexOutOfBoundsException $ex) { + return; + } + int copyingSafetyLevel = RefactoringUtil.verifySafeCopyExpression(actualArg); + if(copyingSafetyLevel == RefactoringUtil.EXPR_COPY_PROHIBITED) { + actualArg = factory.createExpressionFromText(getTempVar(actualArg), null); + } + newExpr = newExpr.replace(actualArg); + } + } + } + // "naked" field and methods (should become qualified) + else if ((subj instanceof PsiField || subj instanceof PsiMethod) + && oldRef.getQualifierExpression() == null) { + + boolean isStatic = + ((subj instanceof PsiField) + && ((PsiField) subj).hasModifierProperty(PsiModifier.STATIC)) + || ((subj instanceof PsiMethod) + && ((PsiMethod) subj).hasModifierProperty(PsiModifier.STATIC)); + + if (myInstanceRef != null && !isStatic) { + String name = ((PsiNamedElement) subj).getName(); + PsiReferenceExpression newRef = (PsiReferenceExpression) factory.createExpressionFromText("a." + name, null); + newRef = (PsiReferenceExpression) CodeStyleManager.getInstance(myProject).reformat(newRef); + + PsiExpression instanceRef = getInstanceRef(factory); + + newRef.getQualifierExpression().replace(instanceRef); + newRef = (PsiReferenceExpression) expr.replace(newRef); + newExpr = newRef.getReferenceNameElement(); + } + } + + if (subj instanceof PsiField) { + // probably replacing field with a getter + if (myReplaceFieldsWithGetters != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) { + if (myReplaceFieldsWithGetters == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL || + (myReplaceFieldsWithGetters == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE && + !manager.getResolveHelper().isAccessible((PsiMember)subj, newExpr, null))) { + newExpr = replaceFieldWithGetter(newExpr, (PsiField) subj); + } + } + } + } + } + else if (oldExpr instanceof PsiThisExpression) { + if (myInstanceRef != null) { + expr.replace(getInstanceRef(factory)); + } + return; + } + else if (oldExpr instanceof PsiSuperExpression) { + if (myInstanceRef != null) { + expr.replace(getInstanceRef(factory)); + } + return; + } + + PsiElement[] oldChildren = RefactoringUtil.getChilderenWithoutWhitespaceOrComments(oldExpr); + PsiElement[] newChildren = RefactoringUtil.getChilderenWithoutWhitespaceOrComments(newExpr); + + if (oldChildren != null && newChildren != null & oldChildren.length == newChildren.length) { + for (int i = 0; i < oldChildren.length; i++) { + PsiElement oldChild = oldChildren[i]; + PsiElement newChild = newChildren[i]; + + resolveOldReferences(newChild, oldChild); + } + } + } + + private PsiExpression getInstanceRef(PsiElementFactory factory) throws IncorrectOperationException { + int copyingSafetyLevel = RefactoringUtil.verifySafeCopyExpression(myInstanceRef); + + PsiExpression instanceRef = myInstanceRef; + if(copyingSafetyLevel == RefactoringUtil.EXPR_COPY_PROHIBITED) { + instanceRef = factory.createExpressionFromText(getTempVar(myInstanceRef), null); + } + return instanceRef; + } + + private String getTempVar(PsiExpression expr) throws IncorrectOperationException { + String id = myTempVars.get(expr); + if(id != null) { + return id; + } + else { + id = RefactoringUtil.createTempVar(expr, myContext, true); + myTempVars.put(expr, id); + return id; + } + } + } + + private PsiElement replaceFieldWithGetter(PsiElement expr, PsiField psiField) + throws IncorrectOperationException { + if (RefactoringUtil.isAssignmentLHS(expr)) { + // todo: warning + return expr; + } + PsiElement newExpr = expr; + + PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField); + + PsiMethod getter = psiField.getContainingClass().findMethodBySignature(getterPrototype, true); + + if (getter != null) { + + if (psiField.getManager().getResolveHelper().isAccessible(getter, newExpr, null)) { + PsiElementFactory factory = newExpr.getManager().getElementFactory(); + String id = getter.getName(); + PsiMethodCallExpression getterCall = + (PsiMethodCallExpression) factory.createExpressionFromText(id + "()", null); + getterCall = (PsiMethodCallExpression) CodeStyleManager.getInstance(myProject).reformat(getterCall); + if(newExpr.getParent() != null) { + newExpr = newExpr.replace(getterCall); + } + else { + newExpr = getterCall; + } + } + else { + // todo: warning + } + } + + return newExpr; + } + + + protected String getCommandName() { + return "Introducing parameter to " + UsageViewUtil.getDescriptiveName(myMethodToReplaceIn); + } + + private void changeMethodSignatureAndResolveFieldConflicts(PsiMethod overridingMethod, PsiType parameterType) throws IncorrectOperationException { + final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(myParameterName, overridingMethod.getBody()); + changeMethodSignature(overridingMethod, parameterType); + fieldConflictsResolver.fix(); + } + + private void changeMethodSignature(PsiMethod methodToReplaceIn, PsiType initializerType) throws IncorrectOperationException { + final MethodJavaDocHelper javaDocHelper = new MethodJavaDocHelper(methodToReplaceIn); + PsiManager manager = methodToReplaceIn.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + + PsiParameter parameter = factory.createParameter(myParameterName, initializerType); + parameter.getModifierList().setModifierProperty(PsiModifier.FINAL, myDeclareFinal); + final PsiParameter anchorParameter = getAnchorParameter(methodToReplaceIn); + PsiParameterList parameterList = methodToReplaceIn.getParameterList(); + parameter = (PsiParameter)parameterList.addAfter(parameter, anchorParameter); + manager.getCodeStyleManager().shortenClassReferences(parameter); + final PsiDocTag tagForAnchorParameter = javaDocHelper.getTagForParameter(anchorParameter); + javaDocHelper.addParameterAfter(myParameterName, tagForAnchorParameter); + } + + private PsiParameter getAnchorParameter(PsiMethod methodToReplaceIn) { + PsiParameterList parameterList = methodToReplaceIn.getParameterList(); + final PsiParameter anchorParameter; + final PsiParameter[] parameters = parameterList.getParameters(); + final int length = parameters.length; + if (!methodToReplaceIn.isVarArgs()) { + anchorParameter = length > 0 ? parameters[length-1] : null; + } + else { + LOG.assertTrue(length > 0); + LOG.assertTrue(parameters[length-1].isVarArgs()); + anchorParameter = length > 1 ? parameters[length - 1] : null; + } + return anchorParameter; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterViewDescriptor.java new file mode 100644 index 00000000000..75213de1d28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/IntroduceParameterViewDescriptor.java @@ -0,0 +1,56 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 16.04.2002 + * Time: 15:54:37 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; + +class IntroduceParameterViewDescriptor extends UsageViewDescriptorAdapter { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.makeMethodStatic.MakeMethodStaticViewDescriptor"); + + private PsiMethod myMethodToSearchFor; + + public IntroduceParameterViewDescriptor(PsiMethod methodToSearchFor, + UsageInfo[] usages, FindUsagesCommand refreshCommand) { + super(usages, refreshCommand); + myMethodToSearchFor = methodToSearchFor; + + } + + public PsiElement[] getElements() { +// if(myMethodToReplaceIn.equals(myMethodToSearchFor)) { +// return new PsiElement[] {myMethodToReplaceIn}; +// } + return new PsiElement[]{myMethodToSearchFor}; + } + + + public void refresh(PsiElement[] elements) { + if(elements.length == 1 && elements[0] instanceof PsiMethod ) { + myMethodToSearchFor = (PsiMethod) elements[0]; + } + else { + // should not happen + LOG.assertTrue(false); + } + refreshUsages(elements); + } + + public boolean canRefresh() { + return false; + } + + public String getProcessedElementsHeader() { + return "Adding parameter to a method"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/LocalVariableInExprUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/LocalVariableInExprUsageInfo.java new file mode 100644 index 00000000000..0b9e079c1e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/LocalVariableInExprUsageInfo.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 15:08:11 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.*; + +class LocalVariableInExprUsageInfo extends InExprUsageInfo { + LocalVariableInExprUsageInfo(PsiElement elem) { + super(elem); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ParameterInExprUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ParameterInExprUsageInfo.java new file mode 100644 index 00000000000..88732ca6d3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/ParameterInExprUsageInfo.java @@ -0,0 +1,21 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 15:01:44 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.*; + +/** + * Parameters used in expression + */ +class ParameterInExprUsageInfo extends InExprUsageInfo { + ParameterInExprUsageInfo(PsiElement elem) { + super(elem); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/Util.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/Util.java new file mode 100644 index 00000000000..203c6a9bd20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceParameter/Util.java @@ -0,0 +1,91 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.05.2002 + * Time: 14:38:40 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.introduceParameter; + +import com.intellij.psi.*; +import com.intellij.psi.jsp.JspAction; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.usageView.UsageInfo; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +public class Util { + + public static final void analyzeExpression(PsiExpression expr, + ArrayList localVars, ArrayList classMemberRefs, ArrayList params) + { + + if (expr instanceof PsiThisExpression || expr instanceof PsiSuperExpression) { + classMemberRefs.add(new ClassMemberInExprUsageInfo(expr)); + } + else if (expr instanceof PsiReferenceExpression) { + final PsiReferenceExpression refExpr = (PsiReferenceExpression) expr; + + PsiElement subj = refExpr.resolve(); + + if (subj instanceof PsiParameter) { + params.add(new ParameterInExprUsageInfo(refExpr)); + } + else if (subj instanceof PsiLocalVariable) { + localVars.add(new LocalVariableInExprUsageInfo(refExpr)); + } + else if (subj instanceof PsiField || subj instanceof PsiMethod) { + classMemberRefs.add(new ClassMemberInExprUsageInfo(refExpr)); + } + + } + + PsiElement[] children = expr.getChildren(); + + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + + if (child instanceof PsiExpression) { + analyzeExpression((PsiExpression) child, localVars, classMemberRefs, params); + } + } + } + + public static PsiMethod getContainingMethod(PsiElement expr) { + PsiElement p; + + for (p = expr; p != null; p = p.getParent()) { + if (p instanceof PsiMethod) return (PsiMethod) p; + if (p instanceof PsiFile || p instanceof JspAction || p instanceof JspFile) return null; + } + return null; + } + + public static boolean anyFieldsWithGettersPresent(List classMemberRefs) { + ListIterator it = classMemberRefs.listIterator(); + + while (it.hasNext()) { + UsageInfo usageInfo = (UsageInfo)it.next(); + + if(usageInfo.getElement() instanceof PsiReferenceExpression) { + PsiElement e = ((PsiReferenceExpression)usageInfo.getElement()).resolve(); + + if(e instanceof PsiField) { + PsiField psiField = (PsiField)e; + PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField); + + PsiMethod getter = psiField.getContainingClass().findMethodBySignature(getterPrototype, true); + + if(getter != null) + return true; + } + } + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java new file mode 100644 index 00000000000..c9bc9ff495e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -0,0 +1,492 @@ +/** + * Created by IntelliJ IDEA. + * User: dsl + * Date: Nov 15, 2002 + * Time: 5:21:33 PM + * To change this template use Options | File Templates. + */ +package com.intellij.refactoring.introduceVariable; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.jsp.JspAction; +import com.intellij.psi.jsp.JspExpression; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.jsp.JspToken; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.IntroduceHandlerBase; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.FieldConflictsResolver; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager; +import com.intellij.refactoring.util.occurences.NotInSuperCallOccurenceFilter; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashSet; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public abstract class IntroduceVariableBase extends IntroduceHandlerBase implements RefactoringActionHandler { + protected static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceVariable.IntroduceVariableBase"); + protected static String REFACTORING_NAME = "Introduce Variable"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + if (!editor.getSelectionModel().hasSelection()) { + editor.getSelectionModel().selectLineAtCaret(); + } + if (invoke(project, editor, file, editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd())) { + editor.getSelectionModel().removeSelection(); + } + } + + private boolean invoke(final Project project, final Editor editor, PsiFile file, int startOffset, int endOffset) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.introduceVariable"); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + + PsiExpression tempExpr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset); + if (tempExpr == null) { + PsiElement[] statements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); + if (statements != null && statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { + tempExpr = ((PsiExpressionStatement) statements[0]).getExpression(); + } + } + return invokeImpl(project, tempExpr, editor); + } + + protected boolean invokeImpl(final Project project, final PsiExpression expr, + final Editor editor) { + if (expr != null && expr.getParent() instanceof PsiExpressionStatement) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.introduceVariable.incompleteStatement"); + } + if (IntroduceVariableBase.LOG.isDebugEnabled()) { + IntroduceVariableBase.LOG.debug("expression:" + expr); + } + + if (expr == null) { + String message = + "Cannot perform the refactoring.\n" + + "Selected block should represent an expression."; + showErrorMessage(message, project); + return false; + } + final PsiFile file = expr.getContainingFile(); + LOG.assertTrue(file != null, "expr.getContainingFile() == null"); + final PsiElementFactory factory = PsiManager.getInstance(project).getElementFactory(); + + + PsiType originalType = RefactoringUtil.getTypeByExpressionWithExpectedType(expr); + if (originalType == null) { + String message = + "Cannot perform the refactoring.\n" + + "Unknown expression type."; + showErrorMessage(message, project); + return false; + } + + if(originalType == PsiType.VOID) { + String message = + "Cannot perform the refactoring.\n" + + "Selected expression has void type."; + showErrorMessage(message, project); + return false; + } + + PsiElement anchorStatement = RefactoringUtil.getParentStatement(expr, false); + if (anchorStatement == null) { + return parentStatementNotFound(project, expr, editor, file); + } + if (anchorStatement instanceof PsiExpressionStatement) { + PsiExpression enclosingExpr = ((PsiExpressionStatement)anchorStatement).getExpression(); + if (enclosingExpr instanceof PsiMethodCallExpression) { + PsiMethod method = ((PsiMethodCallExpression)enclosingExpr).resolveMethod(); + if (method != null && method.isConstructor()) { + //This is either 'this' or 'super', both must be the first in the respective contructor + String message = + "Cannot perform the refactoring.\n" + + "Invalid expression context."; + showErrorMessage(message, project); + return false; + } + } + } + + PsiElement tempContainer = anchorStatement.getParent(); + + if (invalidContainer(tempContainer)) { + String message = IntroduceVariableBase.REFACTORING_NAME + " refactoring is not supported in the current context"; + showErrorMessage(message, project); + return false; + } + + if(!NotInSuperCallOccurenceFilter.INSTANCE.isOK(expr)) { + String message = "Cannot introduce variable in super constructor call"; + showErrorMessage(message, project); + return false; + } + + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return false; + } + + PsiElement containerParent = tempContainer; + PsiElement lastScope = tempContainer; + while (true) { + if (containerParent instanceof PsiFile) break; + if (containerParent instanceof PsiMethod) break; + containerParent = containerParent.getParent(); + if (containerParent instanceof PsiCodeBlock + || containerParent instanceof JspFile + || containerParent instanceof JspAction + ) { + lastScope = containerParent; + } + } + + ExpressionOccurenceManager occurenceManager = new ExpressionOccurenceManager(expr, lastScope, + NotInSuperCallOccurenceFilter.INSTANCE); + final PsiExpression[] occurrences = occurenceManager.getOccurences(); + final PsiElement anchorStatementIfAll = occurenceManager.getAnchorStatementForAll(); + boolean declareFinalIfAll = occurenceManager.isInFinalContext(); + + + boolean anyAssignmentLHS = false; + for (int i = 0; i < occurrences.length; i++) { + PsiExpression occurrence = occurrences[i]; + if (RefactoringUtil.isAssignmentLHS(occurrence)) { + anyAssignmentLHS = true; + break; + } + } + + + IntroduceVariableSettings settings = getSettings(project, editor, expr, occurrences, anyAssignmentLHS, declareFinalIfAll, + originalType, + new TypeSelectorManagerImpl(project, originalType, expr, occurrences), + new InputValidator(project, anchorStatementIfAll, anchorStatement, occurenceManager)); + + if (!settings.isOK()) { + return false; + } + + final String variableName = settings.getEnteredName(); + + final PsiType type = settings.getSelectedType(); + final boolean replaceAll = settings.isReplaceAllOccurrences(); + final boolean replaceWrite = settings.isReplaceLValues(); + final boolean declareFinal = replaceAll && declareFinalIfAll || settings.isDeclareFinal(); + if (replaceAll) { + anchorStatement = anchorStatementIfAll; + tempContainer = anchorStatement.getParent(); + } + + final PsiElement container = tempContainer; + + PsiElement child = anchorStatement; + if (!IntroduceVariableBase.isLoopOrIf(container)) { + child = locateAnchor(child); + } + final PsiElement anchor = child == null ? anchorStatement : child; + + boolean tempDeleteSelf = false; + final boolean replaceSelf = replaceWrite || !RefactoringUtil.isAssignmentLHS(expr); + if (!IntroduceVariableBase.isLoopOrIf(container)) { + if (expr.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorStatement)) { + PsiStatement statement = (PsiStatement) expr.getParent(); + if (statement.getParent() instanceof PsiCodeBlock + || statement.getParent() instanceof JspFile + || statement.getParent() instanceof JspAction) { + tempDeleteSelf = true; + } + } + tempDeleteSelf = tempDeleteSelf && replaceSelf; + } + final boolean deleteSelf = tempDeleteSelf; + + + final int col = editor != null ? editor.getCaretModel().getLogicalPosition().column : 0; + final int line = editor != null ? editor.getCaretModel().getLogicalPosition().line : 0; + if (deleteSelf) { + if (editor != null) { + LogicalPosition pos = new LogicalPosition(0, 0); + editor.getCaretModel().moveToLogicalPosition(pos); + } + } + + final PsiCodeBlock newDeclarationScope = PsiTreeUtil.getParentOfType(container, PsiCodeBlock.class, false); + final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(variableName, newDeclarationScope); + + final PsiElement finalAnchorStatement = anchorStatement; + final Runnable runnable = new Runnable() { + public void run() { + try { + PsiStatement statement = null; + final boolean isInsideLoop = isLoopOrIf(container); + if (!isInsideLoop && deleteSelf) { + statement = (PsiStatement) expr.getParent(); + } + final PsiExpression expr1 = fieldConflictsResolver.fixInitializer(expr); + PsiDeclarationStatement declaration = factory.createVariableDeclarationStatement(variableName, type, expr1); + if (!isInsideLoop) { + declaration = (PsiDeclarationStatement) container.addBefore(declaration, anchor); + if (deleteSelf) { // never true + if (statement.getLastChild() instanceof PsiComment) { // keep trailing comment + declaration.addBefore(statement.getLastChild(), null); + } + statement.delete(); + if (editor != null) { + LogicalPosition pos = new LogicalPosition(line, col); + editor.getCaretModel().moveToLogicalPosition(pos); + editor.getCaretModel().moveToOffset(declaration.getTextRange().getEndOffset()); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } + } + } + + PsiExpression ref = factory.createExpressionFromText(variableName, null); + if (replaceAll) { + ArrayList array = new ArrayList(); + for (int i = 0; i < occurrences.length; i++) { + PsiElement occurrence = occurrences[i]; + if (deleteSelf && occurrence.equals(expr)) continue; + if (occurrence.equals(expr)) { + occurrence = expr1; + } + if (occurrence instanceof PsiExpression) { + occurrence = RefactoringUtil.outermostParenthesizedExpression((PsiExpression) occurrence); + } + if (replaceWrite || !RefactoringUtil.isAssignmentLHS(occurrence)) { + array.add(occurrence.replace(ref)); + } + } + + if (editor != null) { + final PsiElement[] replacedOccurences = array.toArray(new PsiElement[array.size()]); + highlightReplacedOccurences(project, editor, replacedOccurences); + } + } else { + if (!deleteSelf && replaceSelf) { + final PsiExpression expr2 = RefactoringUtil.outermostParenthesizedExpression(expr1); + expr2.replace(ref); + } + } + + if(IntroduceVariableBase.isLoopOrIf(container)) { + PsiStatement loopBody = getLoopBody(container, finalAnchorStatement); + PsiStatement loopBodyCopy = (PsiStatement) loopBody.copy(); + PsiBlockStatement blockStatement = (PsiBlockStatement) factory.createStatementFromText("{}", null); + blockStatement = (PsiBlockStatement) CodeStyleManager.getInstance(project).reformat(blockStatement); + final PsiElement prevSibling = loopBody.getPrevSibling(); + if(prevSibling instanceof PsiWhiteSpace) { + prevSibling.delete(); + } + blockStatement = (PsiBlockStatement) loopBody.replace(blockStatement); + final PsiCodeBlock codeBlock = blockStatement.getCodeBlock(); + declaration = (PsiDeclarationStatement) codeBlock.add(declaration); + declaration.getManager().getCodeStyleManager().shortenClassReferences(declaration); + codeBlock.add(loopBodyCopy); + } + PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0]; + var.getModifierList().setModifierProperty(PsiModifier.FINAL, declareFinal); + + fieldConflictsResolver.fix(); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + + CommandProcessor.getInstance().executeCommand( + project, + new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, REFACTORING_NAME, null); + return true; + } + + protected boolean parentStatementNotFound(final Project project, PsiExpression expr, Editor editor, PsiFile file) { + String message = IntroduceVariableBase.REFACTORING_NAME + " refactoring is not supported in the current context"; + showErrorMessage(message, project); + return false; + } + + /** + * @fabrique + * @param tempContainer + * @return + */ + protected static boolean invalidContainer(PsiElement tempContainer) { + return !(tempContainer instanceof PsiCodeBlock) + && !(tempContainer instanceof JspFile) + && !(tempContainer instanceof JspAction) + && !IntroduceVariableBase.isLoopOrIf(tempContainer); + } + + protected boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) { + throw new UnsupportedOperationException(); + } + + private static PsiElement locateAnchor(PsiElement child) { + while (child != null) { + PsiElement prev = child.getPrevSibling(); + if (prev instanceof PsiStatement) break; + if (prev instanceof PsiJavaToken && ((PsiJavaToken)prev).getTokenType() == JavaTokenType.LBRACE) break; + if (prev instanceof JspToken && ((JspToken) prev).getTokenType() == JspToken.JSP_SCRIPTLET_START) break; + child = prev; + if (child instanceof JspToken && ((JspToken) child).getTokenType() == JspToken.JSP_SCRIPTLET_END) break; + } + if (!(child instanceof JspToken && ((JspToken) child).getTokenType() == JspToken.JSP_SCRIPTLET_END)) { + while (true) { + if (!(child instanceof PsiWhiteSpace) + && !(child instanceof PsiComment) + && !(child instanceof JspExpression) + && !(child instanceof JspToken) + ) + break; + child = child.getNextSibling(); + } + } + return child; + } + + protected abstract void highlightReplacedOccurences(Project project, Editor editor, PsiElement[] replacedOccurences); + + protected abstract IntroduceVariableSettings getSettings(Project project, Editor editor, PsiExpression expr, PsiElement[] occurrences, boolean anyAssignmentLHS, boolean declareFinalIfAll, PsiType type, TypeSelectorManagerImpl typeSelectorManager, InputValidator validator); + + protected abstract void showErrorMessage(String message, Project project); + + private static PsiStatement getLoopBody(PsiElement container, PsiElement anchorStatement) { + if(container instanceof PsiWhileStatement) { + return ((PsiWhileStatement) container).getBody(); + } else if(container instanceof PsiForStatement) { + return ((PsiForStatement) container).getBody(); + } else if (container instanceof PsiForeachStatement) { + return ((PsiForeachStatement)container).getBody(); + } else if (container instanceof PsiIfStatement) { + final PsiStatement thenBranch = ((PsiIfStatement)container).getThenBranch(); + if (thenBranch != null && PsiTreeUtil.isAncestor(thenBranch, anchorStatement, false)) { + return thenBranch; + } + final PsiStatement elseBranch = ((PsiIfStatement)container).getElseBranch(); + if (elseBranch != null && PsiTreeUtil.isAncestor(elseBranch, anchorStatement, false)) { + return elseBranch; + } + LOG.assertTrue(false); + } + IntroduceVariableBase.LOG.assertTrue(false); + return null; + } + + private static boolean isLoopOrIf(PsiElement element) { + return PsiUtil.isLoopStatement(element) + || element instanceof PsiIfStatement; + } + + public interface Validator { + boolean isOK(IntroduceVariableSettings dialog); + } + + protected class InputValidator implements Validator { + private final Project myProject; + private final PsiElement myAnchorStatementIfAll; + private final PsiElement myAnchorStatement; + private final ExpressionOccurenceManager myOccurenceManager; + + public boolean isOK(IntroduceVariableSettings settings) { + String name = settings.getEnteredName(); + final PsiElement anchor; + final boolean replaceAllOccurrences = settings.isReplaceAllOccurrences(); + if (replaceAllOccurrences) { + anchor = myAnchorStatementIfAll; + } else { + anchor = myAnchorStatement; + } + final PsiElement scope = anchor.getParent(); + if(scope == null) return true; + final ArrayList conflicts = new ArrayList(); + final HashSet reportedVariables = new HashSet(); + RenameUtil.CollidingVariableVisitor visitor = new RenameUtil.CollidingVariableVisitor() { + public void visitCollidingElement(PsiVariable collidingVariable) { + if (collidingVariable instanceof PsiField) return; + if (!reportedVariables.contains(collidingVariable)) { + reportedVariables.add(collidingVariable); + String message = "Introduced variable will conflict with " + ConflictsUtil.getDescription(collidingVariable, true); + conflicts.add(message); + } + } + }; + RenameUtil.visitLocalsCollisions(anchor, name, scope, anchor, visitor); + if (replaceAllOccurrences) { + final PsiExpression[] occurences = myOccurenceManager.getOccurences(); + for (int i = 0; i < occurences.length; i++) { + PsiExpression occurence = occurences[i]; + checkInLoopCondition(occurence, conflicts); + } + } else { + checkInLoopCondition(myOccurenceManager.getMainOccurence(), conflicts); + } + + if (conflicts.size() > 0) { + return reportConflicts(conflicts, myProject); + } else { + return true; + } + } + + + public InputValidator(Project project, PsiElement anchorStatementIfAll, PsiElement anchorStatement, + ExpressionOccurenceManager occurenceManager) { + myProject = project; + myAnchorStatementIfAll = anchorStatementIfAll; + myAnchorStatement = anchorStatement; + myOccurenceManager = occurenceManager; + } + } + + protected abstract boolean reportConflicts(ArrayList conflicts, final Project project); + + + public static void checkInLoopCondition(PsiExpression occurence, List conflicts) { + final PsiElement loopForLoopCondition = RefactoringUtil.getLoopForLoopCondition(occurence); + if (loopForLoopCondition == null) return; + final List referencedVariables = RefactoringUtil.collectReferencedVariables(occurence); + final List modifiedInBody = new ArrayList(); + for (Iterator iterator = referencedVariables.iterator(); iterator.hasNext();) { + PsiVariable psiVariable = iterator.next(); + if (RefactoringUtil.isModifiedInScope(psiVariable, loopForLoopCondition)) { + modifiedInBody.add(psiVariable); + } + } + + if (!modifiedInBody.isEmpty()) { + for (Iterator iterator = modifiedInBody.iterator(); iterator.hasNext();) { + PsiVariable variable = iterator.next(); + final String message = ConflictsUtil.getDescription(variable, false) + " is modified in loop body.\n"; + conflicts.add(ConflictsUtil.capitalize(message)); + } + conflicts.add("Introducing variable may break code logic."); + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java new file mode 100644 index 00000000000..313e8e58572 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java @@ -0,0 +1,253 @@ +package com.intellij.refactoring.introduceVariable; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiType; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.*; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.ui.StateRestoringCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.LinkedHashSet; +import java.util.Set; + +class IntroduceVariableDialog extends DialogWrapper implements IntroduceVariableSettings { + private Project myProject; + private final PsiExpression myExpression; + private final int myOccurrencesCount; + private boolean myAnyLValueOccurences; + private final boolean myDeclareFinalIfAll; + private final TypeSelectorManager myTypeSelectorManager; + private final IntroduceVariableHandler.Validator myValidator; + + private NameSuggestionsField myNameField; + private JCheckBox myCbReplaceAll; + private StateRestoringCheckBox myCbReplaceWrite = null; + private JCheckBox myCbFinal; + private boolean myCbFinalState; + private TypeSelector myTypeSelector; + private NameSuggestionsManager myNameSuggestionsManager; + + public IntroduceVariableDialog(Project project, + PsiExpression expression, int occurrencesCount, boolean anyLValueOccurences, + boolean declareFinalIfAll, TypeSelectorManager typeSelectorManager, + IntroduceVariableHandler.Validator validator) { + super(project, true); + myProject = project; + myExpression = expression; + myOccurrencesCount = occurrencesCount; + myAnyLValueOccurences = anyLValueOccurences; + myDeclareFinalIfAll = declareFinalIfAll; + myTypeSelectorManager = typeSelectorManager; + myValidator = validator; + + setTitle("Introduce Variable"); + init(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + protected void init() { + super.init(); + updateOkStatus(); + } + + public String getEnteredName() { + return myNameField.getName(); + } + + public boolean isReplaceAllOccurrences() { + if (myOccurrencesCount <= 1) return false; + return myCbReplaceAll.isSelected(); + } + + public boolean isDeclareFinal() { + if (myCbFinal.isEnabled()) { + return myCbFinalState; + } else { + return true; + } + } + + public boolean isReplaceLValues() { + if (myOccurrencesCount <= 1 || !myAnyLValueOccurences || myCbReplaceWrite == null) { + return true; + } else + return myCbReplaceWrite.isSelected(); + } + + public PsiType getSelectedType() { + return myTypeSelector.getSelectedType(); + } + + protected JComponent createNorthPanel() { + myNameField = new NameSuggestionsField(myProject); + myNameField.addDataChangedListener(new NameSuggestionsField.DataChanged() { + public void dataChanged() { + updateOkStatus(); + } + }); + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.anchor = GridBagConstraints.WEST; + gbConstraints.fill = GridBagConstraints.BOTH; + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 0; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + JLabel type = new JLabel("Variable of type: "); + panel.add(type, gbConstraints); + + gbConstraints.gridx++; + myTypeSelector = myTypeSelectorManager.getTypeSelector(); + panel.add(myTypeSelector.getComponent(), gbConstraints); + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 0; + gbConstraints.weighty = 0; + gbConstraints.gridx = 0; + gbConstraints.gridy = 1; + JLabel namePrompt = new JLabel("Name: "); + panel.add(namePrompt, gbConstraints); + + gbConstraints.gridwidth = 1; + gbConstraints.weightx = 1; + gbConstraints.gridx = 1; + gbConstraints.gridy = 1; + panel.add(myNameField.getComponent(), gbConstraints); + + myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField, + new NameSuggestionsGenerator() { + public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { + return CodeStyleManager.getInstance(myProject).suggestVariableName(VariableKind.LOCAL_VARIABLE, null, myExpression, type); + } + + public Pair> completeVariableName(String prefix, PsiType type) { + LinkedHashSet set = new LinkedHashSet(); + LookupItemPreferencePolicy policy = CompletionUtil.completeVariableName(myProject, set, prefix, type, VariableKind.LOCAL_VARIABLE); + return new Pair> (policy, set); + } + }, myProject); + myNameSuggestionsManager.setMnemonics(type, namePrompt); + + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.weightx = 1; + gbConstraints.weighty = 0; + gbConstraints.gridwidth = 1; + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + gbConstraints.insets = new Insets(0, 0, 0, 0); + + if (myOccurrencesCount > 1) { + myCbReplaceAll = new NonFocusableCheckBox("Replace all occurrences of expression (" + myOccurrencesCount + " occurrences)"); + myCbReplaceAll.setMnemonic('R'); + panel.add(myCbReplaceAll, gbConstraints); + myCbReplaceAll.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateControls(); + } + } + ); + + if (myAnyLValueOccurences) { + myCbReplaceWrite = new StateRestoringCheckBox("Replace write access occurrences"); + myCbReplaceWrite.setMnemonic('l'); + gbConstraints.insets = new Insets(0, 8, 0, 0); + gbConstraints.gridy++; + panel.add(myCbReplaceWrite, gbConstraints); + } + } + + myCbFinal = new NonFocusableCheckBox("Declare final"); + myCbFinal.setMnemonic('f'); + myCbFinalState = CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_LOCALS; + gbConstraints.insets = new Insets(0, 0, 0, 0); + gbConstraints.gridy++; + panel.add(myCbFinal, gbConstraints); + myCbFinal.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (myCbFinal.isEnabled()) { + myCbFinalState = myCbFinal.isSelected(); + } + } + } + ); + + updateControls(); + + return panel; + } + + private void updateControls() { + if (myCbReplaceWrite != null) { + if (myCbReplaceAll.isSelected()) { + myCbReplaceWrite.makeSelectable(); + } else { + myCbReplaceWrite.makeUnselectable(true); + } + } + + if (myCbReplaceAll != null) { + myTypeSelectorManager.setAllOccurences(myCbReplaceAll.isSelected()); + } else { + myTypeSelectorManager.setAllOccurences(false); + } + + if (myDeclareFinalIfAll && myCbReplaceAll != null && myCbReplaceAll.isSelected()) { + myCbFinal.setEnabled(false); + myCbFinal.setSelected(true); + } else { + myCbFinal.setEnabled(true); + myCbFinal.setSelected(myCbFinalState); + } + } + + protected void doOKAction() { + if (!myValidator.isOK(this)) return; + myNameSuggestionsManager.nameSelected(); + super.doOKAction(); + } + + private void updateOkStatus() { + String text = getEnteredName(); + setOKActionEnabled(PsiManager.getInstance(myProject).getNameHelper().isIdentifier(text)); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField.getComponent(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.INTRODUCE_VARIABLE); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java new file mode 100644 index 00000000000..dfa845c7506 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java @@ -0,0 +1,79 @@ +package com.intellij.refactoring.introduceVariable; + +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import java.util.ArrayList; + +public class IntroduceVariableHandler extends IntroduceVariableBase { + + protected IntroduceVariableSettings getSettings(final Project project, Editor editor, PsiExpression expr, + PsiElement[] occurrences, boolean anyAssignmentLHS, + boolean declareFinalIfAll, PsiType type, + TypeSelectorManagerImpl typeSelectorManager, + IntroduceVariableBase.InputValidator validator) { + ArrayList highlighters = new ArrayList(); + HighlightManager highlightManager = null; + if (editor != null) { + highlightManager = HighlightManager.getInstance(project); + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + if (occurrences.length > 1 ) { + highlightManager.addOccurrenceHighlights(editor, occurrences, attributes, true, highlighters); + } + } + + IntroduceVariableDialog dialog = new IntroduceVariableDialog( + project, expr, occurrences.length, anyAssignmentLHS, declareFinalIfAll, + typeSelectorManager, + validator); + dialog.show(); + if (!dialog.isOK()) { + if (occurrences.length > 1) { + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + } else { + if (editor != null) { + for (int i = 0; i < highlighters.size(); i++) { + RangeHighlighter highlighter = (RangeHighlighter) highlighters.get(i); + highlightManager.removeSegmentHighlighter(editor, highlighter); + } + } + } + + return dialog; + } + + protected void showErrorMessage(String message, final Project project) { + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.INTRODUCE_VARIABLE, project); + } + + protected void highlightReplacedOccurences(final Project project, Editor editor, final PsiElement[] replacedOccurences) { + if (editor == null) return; + HighlightManager highlightManager = HighlightManager.getInstance(project); + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + PsiElement[] exprsToHighlight = replacedOccurences; + highlightManager.addOccurrenceHighlights(editor, exprsToHighlight, attributes, true, null); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + + protected boolean reportConflicts(final ArrayList conflicts, final Project project) { + ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), project); + conflictsDialog.show(); + return conflictsDialog.isOK(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableSettings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableSettings.java new file mode 100644 index 00000000000..e601755b036 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/introduceVariable/IntroduceVariableSettings.java @@ -0,0 +1,24 @@ +/** + * Created by IntelliJ IDEA. + * User: dsl + * Date: Nov 15, 2002 + * Time: 4:12:48 PM + * To change this template use Options | File Templates. + */ +package com.intellij.refactoring.introduceVariable; + +import com.intellij.psi.PsiType; + +public interface IntroduceVariableSettings { + String getEnteredName(); + + boolean isReplaceAllOccurrences(); + + boolean isDeclareFinal(); + + boolean isReplaceLValues(); + + PsiType getSelectedType(); + + boolean isOK(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringListenerManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringListenerManagerImpl.java new file mode 100644 index 00000000000..03fbd2fc7cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringListenerManagerImpl.java @@ -0,0 +1,56 @@ +package com.intellij.refactoring.listeners.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.refactoring.listeners.RefactoringElementListenerProvider; +import com.intellij.refactoring.listeners.RefactoringListenerManager; +import com.intellij.refactoring.listeners.impl.impl.RefactoringTransactionImpl; + +import java.util.ArrayList; + +/** + * @author dsl + */ +public class RefactoringListenerManagerImpl extends RefactoringListenerManager implements ProjectComponent { + private final ArrayList myListenerProviders; + private final Project myProject; + + public RefactoringListenerManagerImpl(Project project) { + myProject = project; + myListenerProviders = new ArrayList(); + } + + public void addListenerProvider(RefactoringElementListenerProvider provider) { + myListenerProviders.add(provider); + } + + public void removeListenerProvider(RefactoringElementListenerProvider provider) { + myListenerProviders.remove(provider); + } + + public RefactoringTransaction startTransaction() { + return new RefactoringTransactionImpl(myListenerProviders); + } + + // + // ProjectComponent implementation + // + + public void projectOpened() { + // do nothing + } + + public void projectClosed() { + // do nothing + } + + public String getComponentName() { + return "RefactoringListenerManager"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringTransaction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringTransaction.java new file mode 100644 index 00000000000..ebdc02173b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/RefactoringTransaction.java @@ -0,0 +1,22 @@ +package com.intellij.refactoring.listeners.impl; + +import com.intellij.psi.*; +import com.intellij.refactoring.listeners.RefactoringElementListener; + +/** + * @author dsl + */ +public interface RefactoringTransaction { + /** + * Returns listener for element (element must belong to set of affected elements). + * Refactorings should call appropriate methods of a listener, giving a modified (or new) element. + * @param element + * @return + */ + RefactoringElementListener getElementListener(PsiElement element); + + /** + * + */ + void commit(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/impl/RefactoringTransactionImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/impl/RefactoringTransactionImpl.java new file mode 100644 index 00000000000..e8f3c220376 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/listeners/impl/impl/RefactoringTransactionImpl.java @@ -0,0 +1,94 @@ +package com.intellij.refactoring.listeners.impl.impl; + +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.listeners.RefactoringElementListenerProvider; +import com.intellij.refactoring.listeners.impl.RefactoringTransaction; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class RefactoringTransactionImpl implements RefactoringTransaction { + /** + * Actions to be performed at commit. + */ + private final ArrayList myRunnables = new ArrayList(); + private final List myListenerProviders; + private final HashMap> myOldElementToListenerListMap = new com.intellij.util.containers.HashMap>(); + private final HashMap myOldElementToTransactionListenerMap = new com.intellij.util.containers.HashMap(); + + public RefactoringTransactionImpl(List listenerProviders) { + myListenerProviders = listenerProviders; + } + + private void addAffectedElement(PsiElement oldElement) { + if(myOldElementToListenerListMap.get(oldElement) != null) return; + ArrayList listenerList = new ArrayList(); + for (int i = 0; i < myListenerProviders.size(); i++) { + RefactoringElementListenerProvider provider = myListenerProviders.get(i); + final RefactoringElementListener listener = provider.getListener(oldElement); + if(listener != null) { + listenerList.add(listener); + } + } + myOldElementToListenerListMap.put(oldElement, listenerList); + } + + + public RefactoringElementListener getElementListener(PsiElement oldElement) { + RefactoringElementListener listener = + myOldElementToTransactionListenerMap.get(oldElement); + if(listener == null) { + listener = new MyRefactoringElementListener(oldElement); + myOldElementToTransactionListenerMap.put(oldElement, listener); + } + return listener; + } + + private class MyRefactoringElementListener implements RefactoringElementListener { + private final ArrayList myListenerList; + private MyRefactoringElementListener(PsiElement oldElement) { + addAffectedElement(oldElement); + myListenerList = myOldElementToListenerListMap.get(oldElement); + } + + public void elementMoved(final PsiElement newElement) { + myRunnables.add( + new Runnable() { + public void run() { + for (Iterator iterator = myListenerList.iterator(); iterator.hasNext();) { + RefactoringElementListener refactoringElementListener = iterator.next(); + refactoringElementListener.elementMoved(newElement); + } + } + } + ); + } + + public void elementRenamed(final PsiElement newElement) { + myRunnables.add( + new Runnable() { + public void run() { + for (Iterator iterator = myListenerList.iterator(); iterator.hasNext();) { + RefactoringElementListener refactoringElementListener = iterator.next(); + refactoringElementListener.elementRenamed(newElement); + } + } + } + ); + } + } + + public void commit() { + for (int i = 0; i < myRunnables.size(); i++) { + Runnable runnable = myRunnables.get(i); + runnable.run(); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/InternalUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/InternalUsageInfo.java new file mode 100644 index 00000000000..9e675609e49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/InternalUsageInfo.java @@ -0,0 +1,45 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 16.04.2002 + * Time: 17:09:40 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.makeMethodStatic; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.UsageInfo; + +class InternalUsageInfo extends UsageInfo{ + private final PsiElement myReferencedElement; + private Boolean myIsInsideAnonymous; + + InternalUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element); + myReferencedElement = referencedElement; + myIsInsideAnonymous = null; + isInsideAnonymous(); + } + + public PsiElement getReferencedElement() { + return myReferencedElement; + } + + public boolean isInsideAnonymous() { + if(myIsInsideAnonymous == null) { + myIsInsideAnonymous = Boolean.valueOf(RefactoringUtil.isInsideAnonymous(getElement(), null)); + } + + return myIsInsideAnonymous.booleanValue(); + } + + public boolean isWriting() { + return myReferencedElement instanceof PsiField && + getElement() instanceof PsiReferenceExpression && PsiUtil.isAccessedForWriting(((PsiReferenceExpression)getElement())); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/MakeMethodStaticProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/MakeMethodStaticProcessor.java new file mode 100644 index 00000000000..29ec766672f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/MakeMethodStaticProcessor.java @@ -0,0 +1,521 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 16.04.2002 + * Time: 15:37:30 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.makeMethodStatic; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.javadoc.MethodJavaDocHelper; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class MakeMethodStaticProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.makeMethodStatic.MakeMethodStaticProcessor"); + + private PsiMethod myMethod; + private PsiClass myMethodClass; + private boolean myPreviewUsages; + private Settings mySettings; + + public MakeMethodStaticProcessor(Project project, + PsiMethod method, + boolean previewUsages, Settings settings, Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myMethod = method; + mySettings = settings; + myMethodClass = method.getContainingClass(); + myPreviewUsages = previewUsages; + } + + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new MakeMethodStaticViewDescriptor(myMethod, usages, refreshCommand); + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + if (myPrepareSuccessfulSwingThreadCallback != null) { + String[] conflicts = getConflictDescriptions(usages[0]); + if (conflicts.length > 0) { + ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts, myProject); + conflictsDialog.show(); + if (!conflictsDialog.isOK()) { + return false; + } + } + if(!mySettings.isChangeSignature()) { + usages[0] = filterInternalUsages(usages[0]); + } + } + usages[0] = filterOverriding(usages[0]); + + prepareSuccessful(); + return true; + } + + private UsageInfo[] filterOverriding(UsageInfo[] usages) { + ArrayList result = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!(usage instanceof OverridingMethodUsageInfo)) { + result.add(usage); + } + } + return result.toArray(new UsageInfo[result.size()]); + } + + private UsageInfo[] filterInternalUsages(UsageInfo[] usage) { + ArrayList result = new ArrayList(); + for (int i = 0; i < usage.length; i++) { + UsageInfo usageInfo = usage[i]; + if(!(usageInfo instanceof InternalUsageInfo)) { + result.add(usageInfo); + } + } + return result.toArray(new UsageInfo[result.size()]); + } + + private String[] getConflictDescriptions(UsageInfo[] usages) { + ArrayList conflicts = new ArrayList(); + HashSet processed = new HashSet(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usageInfo = usages[i]; + + if (usageInfo instanceof InternalUsageInfo && !(usageInfo instanceof SelfUsageInfo)) { + PsiElement referencedElement = ((InternalUsageInfo) usageInfo).getReferencedElement(); + if (!mySettings.isMakeClassParameter()) { + if (referencedElement instanceof PsiModifierListOwner) { + if (((PsiModifierListOwner) referencedElement).hasModifierProperty(PsiModifier.STATIC)) { + continue; + } + } + + if (processed.contains(referencedElement)) continue; + processed.add(referencedElement); + if (referencedElement instanceof PsiField) { + PsiField field = (PsiField) referencedElement; + + if (mySettings.getNameForField(field) == null) { + String message = "Method uses non-static " + ConflictsUtil.getDescription(field, true) + + ", which is not passed as a parameter"; + conflicts.add(message); + } + } + else { + String message = "Method uses " + ConflictsUtil.getDescription(referencedElement, true) + + ", which needs class instance."; + conflicts.add(message); + } + } + } if (usageInfo instanceof OverridingMethodUsageInfo) { + final PsiMethod overridingMethod = ((PsiMethod) usageInfo.getElement()); + String message = "Method " + ConflictsUtil.getDescription(myMethod, false) + " is overriden by " + + ConflictsUtil.getDescription(overridingMethod, true) + "."; + conflicts.add(message); + } + else { + PsiElement element = usageInfo.getElement(); + PsiElement container = ConflictsUtil.getContainer(element); + if (processed.contains(container)) continue; + processed.add(container); + List fieldParameters = mySettings.getParameterOrderList(); + ArrayList inaccessible = new ArrayList(); + + for (Iterator iterator = fieldParameters.iterator(); iterator.hasNext();) { + Settings.FieldParameter fieldParameter = (Settings.FieldParameter) iterator.next(); + + if (!PsiUtil.isAccessible(fieldParameter.field, element, null)) { + inaccessible.add(fieldParameter.field); + } + } + + if (inaccessible.isEmpty()) continue; + + conflicts.add(createInaccessibleFieldsConflictDescription(inaccessible, container)); + } + } + return conflicts.toArray(new String[0]); + } + + private String createInaccessibleFieldsConflictDescription(ArrayList inaccessible, PsiElement container) { + StringBuffer buf = new StringBuffer("Field"); + if (inaccessible.size() == 1) { + buf.append(" "); + } + else { + buf.append("s "); + } + + for (int j = 0; j < inaccessible.size(); j++) { + PsiField field = inaccessible.get(j); + + if (j > 0) { + if (j + 1 < inaccessible.size()) { + buf.append(", "); + } + else { + buf.append(" and "); + } + } + buf.append(ConflictsUtil.htmlEmphasize(field.getName())); + } + buf.append(" is not accessible from "); + buf.append(ConflictsUtil.getDescription(container, true)); + return buf.toString(); + } + + protected UsageInfo[] findUsages() { + ArrayList result = new ArrayList(); + PsiManager manager = myMethod.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + + if (mySettings.isReplaceUsages()) { + PsiReference[] refs = helper.findReferences(myMethod, GlobalSearchScope.projectScope(myProject), true); + for (int i = 0; i < refs.length; i++) { + PsiElement ref = refs[i].getElement(); + PsiElement qualifier = null; + if (ref instanceof PsiReferenceExpression) { + qualifier = ((PsiReferenceExpression) ref).getQualifierExpression(); + if (qualifier instanceof PsiThisExpression) qualifier = null; + } + if (!PsiTreeUtil.isAncestor(myMethod, ref, true) || qualifier != null) { + result.add(new UsageInfo(ref)); + } + } + } + final PsiMethod[] overridingMethods = helper.findOverridingMethods(myMethod, GlobalSearchScope.allScope(myProject), false); + for (int i = 0; i < overridingMethods.length; i++) { + PsiMethod overridingMethod = overridingMethods[i]; + if (overridingMethod != myMethod) { + result.add(new OverridingMethodUsageInfo(overridingMethod)); + } + } + + UsageInfo[] externalUsages = result.toArray(new UsageInfo[0]); + UsageInfo[] internalUsages; + +// if (mySettings.isChangeSignature()) { + internalUsages = MakeMethodStaticUtil.findClassRefsInMethod(myMethod, true); +// } +// else { +// internalUsages = new UsageInfo[0]; +// } + + UsageInfo[] resultArray = ArrayUtil.mergeArrays(internalUsages, externalUsages, UsageInfo.class); + return resultArray; + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages) || myPreviewUsages; + } + + protected void performRefactoring(UsageInfo[] usages) { + PsiManager manager = myMethod.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + + try { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if(usage instanceof SelfUsageInfo) { + changeSelfUsage((SelfUsageInfo) usage); + } + else if (usage instanceof InternalUsageInfo) { + changeInternalUsage((InternalUsageInfo) usage, factory); + } + else { + changeExternalUsage(usage, factory); + } + } + changeMethodSignature(factory, usages); + } + catch (IncorrectOperationException ex) { + LOG.assertTrue(false); + } + } + + private void changeSelfUsage(SelfUsageInfo usageInfo) throws IncorrectOperationException { + PsiElement parent = usageInfo.getElement().getParent(); + LOG.assertTrue(parent instanceof PsiMethodCallExpression); + PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parent; + PsiElementFactory factory = methodCall.getManager().getElementFactory(); + PsiExpressionList args = methodCall.getArgumentList(); + PsiElement addParameterAfter = null; + + if(mySettings.isMakeClassParameter()) { + PsiElement arg = factory.createExpressionFromText(mySettings.getClassParameterName(), null); + addParameterAfter = args.addAfter(arg, null); + } + + if(mySettings.isMakeFieldParameters()) { + List parameters = mySettings.getParameterOrderList(); + for (Iterator iterator = parameters.iterator(); iterator.hasNext();) { + Settings.FieldParameter fieldParameter = (Settings.FieldParameter) iterator.next(); + PsiElement arg = factory.createExpressionFromText(fieldParameter.name, null); + if(addParameterAfter == null) { + addParameterAfter = args.addAfter(arg, null); + } + else { + addParameterAfter = args.addAfter(arg, addParameterAfter); + } + } + } + } + + private void changeMethodSignature(PsiElementFactory factory, UsageInfo[] usages) + throws IncorrectOperationException { + final MethodJavaDocHelper javaDocHelper = new MethodJavaDocHelper(myMethod); + PsiParameterList paramList = myMethod.getParameterList(); + PsiElement addParameterAfter = null; + PsiDocTag anchor = null; + List addedTypes = new ArrayList(); + + if (mySettings.isMakeClassParameter()) { + // Add parameter for object + PsiType parameterType = factory.createType(myMethodClass, PsiSubstitutor.EMPTY); + addedTypes.add(parameterType); + + final String classParameterName = mySettings.getClassParameterName(); + PsiParameter parameter = factory.createParameter(classParameterName, parameterType); + if(makeClassParameterFinal(usages)) { + parameter.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + addParameterAfter = paramList.addAfter(parameter, null); + anchor = javaDocHelper.addParameterAfter(classParameterName, anchor); + } + + if (mySettings.isMakeFieldParameters()) { + List parameters = mySettings.getParameterOrderList(); + + for (Iterator iterator = parameters.iterator(); iterator.hasNext();) { + Settings.FieldParameter fieldParameter = (Settings.FieldParameter) iterator.next(); + final PsiType fieldParameterType = fieldParameter.field.getType(); + final PsiParameter parameter = factory.createParameter(fieldParameter.name, fieldParameterType); + addedTypes.add(fieldParameterType); + if (makeFieldParameterFinal(fieldParameter.field, usages)) { + parameter.getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + addParameterAfter = paramList.addAfter(parameter, addParameterAfter); + anchor = javaDocHelper.addParameterAfter(fieldParameter.name, anchor); + } + } + addTypeParameters(addedTypes); + // Add static modifier + final PsiModifierList modifierList = myMethod.getModifierList(); + modifierList.setModifierProperty(PsiModifier.STATIC, true); + modifierList.setModifierProperty(PsiModifier.FINAL, false); + } + + private void addTypeParameters(List addedTypes) throws IncorrectOperationException { + final PsiManager manager = myMethod.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + final List typeParametersToAdd = new ArrayList(); + + final PsiMethod methodFromText = factory.createMethodFromText("void utterGarbage();", myMethod); + for (Iterator iterator = addedTypes.iterator(); iterator.hasNext();) { + final PsiType type = iterator.next(); + methodFromText.getParameterList().add(factory.createParameter("p", type)); + } + final LocalSearchScope searchScope = new LocalSearchScope(methodFromText); + final Iterator tpIterator = PsiUtil.typeParametersIterator(myMethodClass); + while (tpIterator.hasNext()) { + final PsiTypeParameter psiTypeParameter = tpIterator.next(); + if (manager.getSearchHelper().findReferences(psiTypeParameter, searchScope, false).length > 0) { + typeParametersToAdd.add(psiTypeParameter); + } + } + Collections.reverse(typeParametersToAdd); + for (Iterator iterator = typeParametersToAdd.iterator(); iterator.hasNext();) { + final PsiTypeParameter typeParameter = iterator.next(); + myMethod.getTypeParameterList().add(typeParameter); + } + } + + private boolean makeClassParameterFinal(UsageInfo[] usages) { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if(usage instanceof InternalUsageInfo) { + final InternalUsageInfo internalUsageInfo = (InternalUsageInfo) usage; + PsiElement referencedElement = internalUsageInfo.getReferencedElement(); + if(!(referencedElement instanceof PsiField) + || mySettings.getNameForField((PsiField) referencedElement) == null) { + if(internalUsageInfo.isInsideAnonymous()) { + return true; + } + } + } + } + return false; + } + + private boolean makeFieldParameterFinal(PsiField field, UsageInfo[] usages) { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage instanceof InternalUsageInfo) { + final InternalUsageInfo internalUsageInfo = (InternalUsageInfo) usage; + PsiElement referencedElement = internalUsageInfo.getReferencedElement(); + if (referencedElement instanceof PsiField && field.equals(referencedElement)) { + if (internalUsageInfo.isInsideAnonymous()) { + return true; + } + } + } + } + return false; + } + + private void changeInternalUsage(InternalUsageInfo usage, PsiElementFactory factory) + throws IncorrectOperationException { + if (!mySettings.isChangeSignature()) return; + + PsiElement element = usage.getElement(); + + if (element instanceof PsiReferenceExpression) { + PsiReferenceExpression newRef = null; + + if (mySettings.isMakeFieldParameters()) { + PsiElement resolved = ((PsiReferenceExpression) element).resolve(); + if (resolved instanceof PsiField) { + String name = mySettings.getNameForField((PsiField) resolved); + if (name != null) { + newRef = (PsiReferenceExpression) factory.createExpressionFromText(name, null); + } + } + } + + if (newRef == null && mySettings.isMakeClassParameter()) { + newRef = + (PsiReferenceExpression) factory.createExpressionFromText( + mySettings.getClassParameterName() + "." + element.getText(), null); + } + + if (newRef != null) { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + newRef = (PsiReferenceExpression) codeStyleManager.reformat(newRef); + element.replace(newRef); + } + } + else if (element instanceof PsiThisExpression && mySettings.isMakeClassParameter()) { + element.replace(factory.createExpressionFromText(mySettings.getClassParameterName(), null)); + } + else if (element instanceof PsiSuperExpression && mySettings.isMakeClassParameter()) { + element.replace(factory.createExpressionFromText(mySettings.getClassParameterName(), null)); + } + } + + private void changeExternalUsage(UsageInfo usage, PsiElementFactory factory) + throws IncorrectOperationException { + if (!(usage.getElement() instanceof PsiReferenceExpression)) return; + + PsiReferenceExpression methodRef = (PsiReferenceExpression) usage.getElement(); + PsiElement parent = methodRef.getParent(); + LOG.assertTrue(parent instanceof PsiMethodCallExpression); + + PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parent; + PsiExpression instanceRef; + + instanceRef = methodRef.getQualifierExpression(); + PsiElement newQualifier; + + if (instanceRef == null || instanceRef instanceof PsiSuperExpression) { + instanceRef = factory.createExpressionFromText("this", null); + newQualifier = null; + } + else { + newQualifier = factory.createReferenceExpression(myMethodClass); + } + + if (mySettings.getNewParametersNumber() > 1) { + int copyingSafetyLevel = RefactoringUtil.verifySafeCopyExpression(instanceRef); + if (copyingSafetyLevel == RefactoringUtil.EXPR_COPY_PROHIBITED) { + String tempVar = RefactoringUtil.createTempVar(instanceRef, methodCall, true); + instanceRef = factory.createExpressionFromText(tempVar, null); + } + } + + + PsiElement anchor = null; + PsiExpressionList argList = methodCall.getArgumentList(); + PsiExpression[] exprs = argList.getExpressions(); + if (mySettings.isMakeClassParameter()) { + if (exprs.length > 0) { + anchor = argList.addBefore(instanceRef, exprs[0]); + } + else { + anchor = argList.add(instanceRef); + } + } + + + if (mySettings.isMakeFieldParameters()) { + List parameters = mySettings.getParameterOrderList(); + + for (Iterator iterator = parameters.iterator(); iterator.hasNext();) { + Settings.FieldParameter fieldParameter = (Settings.FieldParameter) iterator.next(); + + PsiReferenceExpression fieldRef; + if (newQualifier != null) { + fieldRef = (PsiReferenceExpression) factory.createExpressionFromText( + "a." + fieldParameter.field.getName(), null); + fieldRef.getQualifierExpression().replace(instanceRef); + } + else { + fieldRef = (PsiReferenceExpression) factory.createExpressionFromText(fieldParameter.field.getName(), null); + } + + if (anchor != null) { + anchor = argList.addAfter(fieldRef, anchor); + } + else { + if (exprs.length > 0) { + anchor = argList.addBefore(fieldRef, exprs[0]); + } + else { + anchor = argList.add(fieldRef); + } + } + } + } + + if (newQualifier != null) { + methodRef.getQualifierExpression().replace(newQualifier); + } + + } + + protected String getCommandName() { + return "Making " + UsageViewUtil.getDescriptiveName(myMethod) + " static"; + } + + public PsiMethod getMethod() { + return myMethod; + } + + public Settings getSettings() { + return mySettings; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/OverridingMethodUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/OverridingMethodUsageInfo.java new file mode 100644 index 00000000000..c95611cddb5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/OverridingMethodUsageInfo.java @@ -0,0 +1,13 @@ +package com.intellij.refactoring.makeMethodStatic; + +import com.intellij.psi.PsiMethod; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class OverridingMethodUsageInfo extends UsageInfo { + public OverridingMethodUsageInfo(PsiMethod overridingMethod) { + super(overridingMethod); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/SelfUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/SelfUsageInfo.java new file mode 100644 index 00000000000..eb7924074ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/SelfUsageInfo.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 12:39:20 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.makeMethodStatic; + +import com.intellij.psi.*; + +public class SelfUsageInfo extends InternalUsageInfo { + SelfUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, referencedElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/Settings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/Settings.java new file mode 100644 index 00000000000..d8a0847978c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/makeMethodStatic/Settings.java @@ -0,0 +1,118 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 01.07.2002 + * Time: 15:48:33 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.makeMethodStatic; + +import com.intellij.psi.PsiField; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.List; + +public final class Settings { + private final boolean myMakeClassParameter; + private final String myClassParameterName; + private final boolean myMakeFieldParameters; + private final HashMap myFieldToNameMapping; + private final ArrayList myFieldToNameList; + private final boolean myReplaceUsages; + + + public static final class FieldParameter { + public FieldParameter(PsiField field, String name) { + this.field = field; + this.name = name; + } + + public final PsiField field; + public final String name; + } + + + public Settings(boolean replaceUsages, String classParameterName, + ParameterTablePanel.VariableData[] variableDatum) { + myReplaceUsages = replaceUsages; + myMakeClassParameter = classParameterName != null; + myClassParameterName = classParameterName; + myMakeFieldParameters = variableDatum != null; + myFieldToNameList = new ArrayList(); + if(myMakeFieldParameters) { + myFieldToNameMapping = new com.intellij.util.containers.HashMap(); + for (int i = 0; i < variableDatum.length; i++) { + ParameterTablePanel.VariableData data = variableDatum[i]; + if (data.passAsParameter) { + myFieldToNameMapping.put((PsiField)data.variable, data.name); + myFieldToNameList.add(new FieldParameter((PsiField) data.variable, data.name)); + } + } + } + else { + myFieldToNameMapping = null; + } + } + + public Settings(boolean replaceUsages, String classParameterName, + PsiField[] fields, String[] names) { + myReplaceUsages = replaceUsages; + myMakeClassParameter = classParameterName != null; + myClassParameterName = classParameterName; + myMakeFieldParameters = fields.length > 0; + myFieldToNameList = new ArrayList(); + if (myMakeFieldParameters) { + myFieldToNameMapping = new HashMap(); + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + final String name = names[i]; + myFieldToNameMapping.put(field, name); + myFieldToNameList.add(new FieldParameter(field, name)); + } + } + else { + myFieldToNameMapping = null; + } + } + + public boolean isReplaceUsages() { + return myReplaceUsages; + } + + public boolean isMakeClassParameter() { + return myMakeClassParameter; + } + + public String getClassParameterName() { + return myClassParameterName; + } + + public boolean isMakeFieldParameters() { + return myMakeFieldParameters; + } + + public String getNameForField(PsiField field) { + if (myFieldToNameMapping != null) { + return myFieldToNameMapping.get(field); + } + else { + return null; + } + } + + public List getParameterOrderList() { + return myFieldToNameList; + } + + public boolean isChangeSignature() { + return isMakeClassParameter() || isMakeFieldParameters(); + } + + public int getNewParametersNumber() { + final int result = isMakeFieldParameters() ? myFieldToNameList.size() : 0; + return result + (isMakeClassParameter() ? 1 : 0); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/JavaDocPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/JavaDocPanel.java new file mode 100644 index 00000000000..892a109e672 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/JavaDocPanel.java @@ -0,0 +1,82 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 17.06.2002 + * Time: 20:38:33 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.*; + +public class JavaDocPanel extends JPanel { + private JRadioButton myRbJavaDocAsIs = null; + private JRadioButton myRbJavaDocMove = null; + private JRadioButton myRbJavaDocCopy = null; + private TitledBorder myBorder; + + public JavaDocPanel(String title) { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + myBorder = IdeBorderFactory.createTitledBorder(title); + this.setBorder(myBorder); + + myRbJavaDocAsIs = new JRadioButton("As is"); + this.add(myRbJavaDocAsIs); + myRbJavaDocAsIs.setMnemonic('A'); + myRbJavaDocAsIs.setFocusable(false); + + myRbJavaDocCopy = new JRadioButton("Copy"); + myRbJavaDocCopy.setMnemonic('C'); + myRbJavaDocCopy.setFocusable(false); + this.add(myRbJavaDocCopy); + + myRbJavaDocMove = new JRadioButton("Move"); + myRbJavaDocMove.setMnemonic('M'); + myRbJavaDocMove.setFocusable(false); + this.add(myRbJavaDocMove); + + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbJavaDocAsIs); + bg.add(myRbJavaDocCopy); + bg.add(myRbJavaDocMove); + bg.setSelected(myRbJavaDocMove.getModel(), true); + } + + public Dimension getPreferredSize() { + final Dimension preferredSize = super.getPreferredSize(); + final Dimension borderSize = myBorder.getMinimumSize(this); + return new Dimension( + Math.max(preferredSize.width, borderSize.width + 10), + Math.max(preferredSize.height, borderSize.height) + ); + } + + public void setPolicy(final int javaDocPolicy) { + if (javaDocPolicy == JavaDocPolicy.COPY) { + myRbJavaDocCopy.setSelected(true); + } + else if (javaDocPolicy == JavaDocPolicy.MOVE) { + myRbJavaDocMove.setSelected(true); + } + else { + myRbJavaDocAsIs.setSelected(true); + } + } + + public int getPolicy() { + if (myRbJavaDocCopy != null && myRbJavaDocCopy.isSelected()) { + return JavaDocPolicy.COPY; + } + if (myRbJavaDocMove != null && myRbJavaDocMove.isSelected()) { + return JavaDocPolicy.MOVE; + } + + return JavaDocPolicy.ASIS; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java new file mode 100644 index 00000000000..0f086030c7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java @@ -0,0 +1,223 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 17.06.2002 + * Time: 15:40:16 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; +import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; +import com.intellij.refactoring.util.classMembers.MemberInfo; + +import java.util.*; + +public class PullUpConflictsUtil { + public static String[] checkConflicts(final MemberInfo[] infos, + PsiClass subclass, + PsiClass superClass, + PsiPackage targetPackage, + PsiDirectory targetDirectory, + final InterfaceContainmentVerifier interfaceContainmentVerifier) { + final Set movedMembers = new HashSet(); + final Set abstractMethods = new HashSet(); + final boolean isInterfaceTarget; + final PsiElement targetRepresentativeElement; + if (superClass != null) { + isInterfaceTarget = superClass.isInterface(); + targetRepresentativeElement = superClass; + } + else { + isInterfaceTarget = false; + targetRepresentativeElement = targetDirectory; + } + for (int idx = 0; idx < infos.length; idx++) { + PsiElement member = infos[idx].getMember(); + if (member instanceof PsiMethod) { + if (!infos[idx].isToAbstract() && !isInterfaceTarget) { + movedMembers.add(member); + } + else { + abstractMethods.add((PsiMethod)member); + } + } + else { + movedMembers.add(member); + } + } + final LinkedHashSet conflictsList = new LinkedHashSet(); + if (superClass != null) { + checkSuperclassMembers(superClass, infos, conflictsList); + if (isInterfaceTarget) { + checkInterfaceTarget(infos, conflictsList); + } + } + // check if moved methods use other members in the classes between Subclass and Superclass + List checkModuleConflictsList = new ArrayList(); + for (Iterator it = movedMembers.iterator(); it.hasNext();) { + PsiElement member = it.next(); + if (member instanceof PsiMethod || member instanceof PsiClass) { + ConflictingUsagesOfSubClassMembers visitor = + new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass, + superClass != null ? null : targetPackage, conflictsList, + interfaceContainmentVerifier); + member.accept(visitor); + } + checkModuleConflictsList.add(member); + } + for (Iterator iterator = abstractMethods.iterator(); iterator.hasNext();) { + final PsiMethod method = iterator.next(); + checkModuleConflictsList.add(method.getParameterList()); + checkModuleConflictsList.add(method.getReturnTypeElement()); + } + RefactoringUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, + targetRepresentativeElement, conflictsList); + String[] conflicts = conflictsList.toArray(new String[conflictsList.size()]); + return conflicts; + } + + private static void checkInterfaceTarget(MemberInfo[] infos, LinkedHashSet conflictsList) { + for (int i = 0; i < infos.length; i++) { + PsiElement member = infos[i].getMember(); + + if (member instanceof PsiField || member instanceof PsiClass) { + + if (!((PsiModifierListOwner)member).hasModifierProperty(PsiModifier.STATIC) + && !(member instanceof PsiClass && ((PsiClass)member).isInterface())) { + String message = + ConflictsUtil.getDescription(member, false) + " is not static. " + + " It cannot be moved to the interface"; + message = ConflictsUtil.capitalize(message); + conflictsList.add(message); + } + } + + if (member instanceof PsiField && ((PsiField)member).getInitializer() == null) { + String message = + ConflictsUtil.getDescription(member, false) + " is not initialized in declaration. " + + "Such fields are not allowed in interfaces."; + conflictsList.add(ConflictsUtil.capitalize(message)); + } + } + } + + private static void checkSuperclassMembers(PsiClass superClass, + MemberInfo[] infos, + LinkedHashSet conflictsList) { + for (int i = 0; i < infos.length; i++) { + PsiElement member = infos[i].getMember(); + boolean isConflict = false; + if (member instanceof PsiField) { + String name = ((PsiField)member).getName(); + + isConflict = superClass.findFieldByName(name, false) != null; + } + else if (member instanceof PsiMethod) { + final PsiMethod superClassMethod = superClass.findMethodBySignature((PsiMethod)member, false); + isConflict = superClassMethod != null + && !superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT); + } + + if (isConflict) { + String message = + ConflictsUtil.getDescription(superClass, false) + " already contains a " + + ConflictsUtil.getDescription(member, false); + message = ConflictsUtil.capitalize(message); + conflictsList.add(message); + } + } + + } + + private static class ConflictingUsagesOfSubClassMembers extends ClassMemberReferencesVisitor { + private final PsiElement myScope; + private final Set myMovedMembers; + private final Set myAbstractMethods; + private final PsiClass mySubclass; + private final PsiClass mySuperClass; + private final PsiPackage myTargetPackage; + private final Set myConflictsList; + private final InterfaceContainmentVerifier myInterfaceContainmentVerifier; + + ConflictingUsagesOfSubClassMembers(PsiElement scope, + Set movedMembers, Set abstractMethods, + PsiClass subclass, PsiClass superClass, + PsiPackage targetPackage, Set conflictsList, + InterfaceContainmentVerifier interfaceContainmentVerifier) { + super(subclass); + myScope = scope; + myMovedMembers = movedMembers; + myAbstractMethods = abstractMethods; + mySubclass = subclass; + mySuperClass = superClass; + myTargetPackage = targetPackage; + myConflictsList = conflictsList; + myInterfaceContainmentVerifier = interfaceContainmentVerifier; + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, + PsiJavaCodeReferenceElement classMemberReference) { + if (classMember != null + && RefactoringHierarchyUtil.isMemberBetween(mySuperClass, mySubclass, classMember)) { + if (classMember.hasModifierProperty(PsiModifier.STATIC) + && !willBeMoved(classMember)) { + final boolean isAccessible; + if (mySuperClass != null) { + isAccessible = PsiUtil.isAccessible(classMember, mySuperClass, null); + } + else if (myTargetPackage != null) { + isAccessible = PsiUtil.isAccessibleFromPackage(classMember, myTargetPackage); + } + else { + isAccessible = classMember.hasModifierProperty(PsiModifier.PUBLIC); + } + if (!isAccessible) { + String message = + ConflictsUtil.getDescription(myScope, false) + " uses " + + ConflictsUtil.getDescription(classMember, true) + ", which is not accessible from the superclass"; + message = ConflictsUtil.capitalize(message); + myConflictsList.add(message); + + } + return; + } + if (!myAbstractMethods.contains(classMember) && !willBeMoved(classMember)) { + if (!existsInSuperClass(classMember)) { + String message = + ConflictsUtil.getDescription(myScope, false) + " uses " + + ConflictsUtil.getDescription(classMember, true) + ", which is not moved to the superclass"; + message = ConflictsUtil.capitalize(message); + myConflictsList.add(message); + } + } + } + } + + private boolean willBeMoved(PsiElement element) { + PsiElement parent = element; + while (parent != null) { + if (myMovedMembers.contains(parent)) return true; + parent = parent.getParent(); + } + return false; + } + + private boolean existsInSuperClass(PsiElement classMember) { + if (!(classMember instanceof PsiMethod)) return false; + final PsiMethod method = ((PsiMethod)classMember); + if (myInterfaceContainmentVerifier.checkedInterfacesContain(method)) return true; + if (mySuperClass == null) return false; + final PsiMethod methodBySignature = mySuperClass.findMethodBySignature(method, true); + return methodBySignature != null; + } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpDialog.java new file mode 100644 index 00000000000..84f2d59b1b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -0,0 +1,251 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 18.06.2002 + * Time: 13:16:29 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.ClassCellRenderer; +import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.classMembers.*; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; + +public class PullUpDialog extends RefactoringDialog { + private final Callback myCallback; + private MemberSelectionPanel myMemberSelectionPanel; + private MyMemberInfoModel myMemberInfoModel; + private final PsiClass myClass; + private final List mySuperClasses; + private final MemberInfoStorage myMemberInfoStorage; + private MemberInfo[] myMemberInfos; + private JavaDocPanel myJavaDocPanel; + + private JComboBox myClassCombo; + + public static interface Callback { + boolean checkConflicts(PullUpDialog dialog); + } + + + public PullUpDialog(Project project, PsiClass aClass, List superClasses, + MemberInfoStorage memberInfoStorage, Callback callback) { + super(project, true); + myClass = aClass; + mySuperClasses = superClasses; + myMemberInfoStorage = memberInfoStorage; + myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass).toArray(new MemberInfo[0]); + myCallback = callback; + + setTitle(PullUpHandler.REFACTORING_NAME); + + init(); + } + + public PsiClass getSuperClass() { + if (myClassCombo != null) { + return (PsiClass) myClassCombo.getSelectedItem(); + } + else { + return null; + } + } + + public int getJavaDocPolicy() { + return myJavaDocPanel.getPolicy(); + } + + public MemberInfo[] getSelectedMemberInfos() { + ArrayList list = new ArrayList(myMemberInfos.length); + for (int idx = 0; idx < myMemberInfos.length; idx++) { + MemberInfo info = myMemberInfos[idx]; + if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) { + list.add(info); + } + } + return list.toArray(new MemberInfo[list.size()]); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.memberPullUp.PullUpDialog"; + } + + InterfaceContainmentVerifier getContainmentVerifier() { + return myInterfaceContainmentVerifier; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(); + + panel.setBorder(IdeBorderFactory.createBorder()); + + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.anchor = GridBagConstraints.WEST; + final JLabel classComboLabel = new JLabel("Pull up members of " + myClass.getQualifiedName() + + " to:"); + panel.add(classComboLabel, gbConstraints); + + myClassCombo = new JComboBox(mySuperClasses.toArray()); + myClassCombo.setRenderer(new ClassCellRenderer()); + classComboLabel.setLabelFor(myClassCombo); + classComboLabel.setDisplayedMnemonic('P'); +// myClassCombo.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + PsiClass nearestBase = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false); + int indexToSelect = 0; + if (nearestBase != null) { + indexToSelect = mySuperClasses.indexOf(nearestBase); + } + myClassCombo.setSelectedIndex(indexToSelect); + myClassCombo.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + updateMemberInfo(); + if (myMemberSelectionPanel != null) { + myMemberInfoModel.setSuperClass(getSuperClass()); + myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos); + myMemberSelectionPanel.getTable().fireExternalDataChange(); + } + } + } + }); + gbConstraints.gridy++; + panel.add(myClassCombo, gbConstraints); + + return panel; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP); + } + + private void updateMemberInfo() { + final PsiClass targetClass = (PsiClass) myClassCombo.getSelectedItem(); + myMemberInfos = myMemberInfoStorage.getMemberInfosList(targetClass); + /*Set duplicated = myMemberInfoStorage.getDuplicatedMemberInfos(targetClass); + for (Iterator iterator = duplicated.iterator(); iterator.hasNext();) { + ((MemberInfo) iterator.next()).setChecked(false); + }*/ + } + + /*protected JComponent createSouthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(super.createSouthPanel(), BorderLayout.CENTER); + myCbPreviewUsages.setSelected(RefactoringSettings.getInstance().PULL_UP_MEMBERS_PREVIEW_USAGES); + myCbPreviewUsages.setMnemonic('P'); + panel.add(myCbPreviewUsages, BorderLayout.WEST); + return panel; + }*/ + + protected void doAction() { + if (!myCallback.checkConflicts(this)) return; + RefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy(); + close(OK_EXIT_CODE); + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myMemberSelectionPanel = new MemberSelectionPanel("Members to be pulled up", myMemberInfos, "Make abstract"); + myMemberInfoModel = new MyMemberInfoModel(); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel); + myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel); + panel.add(myMemberSelectionPanel, BorderLayout.CENTER); + + myJavaDocPanel = new JavaDocPanel("JavaDoc for abstracts"); + myJavaDocPanel.setPolicy(RefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC); + panel.add(myJavaDocPanel, BorderLayout.EAST); + return panel; + } + private InterfaceContainmentVerifier myInterfaceContainmentVerifier = + new InterfaceContainmentVerifier() { + public boolean checkedInterfacesContain(PsiMethod psiMethod) { + return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod); + } + }; + + private class MyMemberInfoModel extends UsesAndInterfacesDependencyMemberInfoModel { + public MyMemberInfoModel() { + super(myClass, getSuperClass(), false, myInterfaceContainmentVerifier); + } + + + public boolean isMemberEnabled(MemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if(currentSuperClass == null) return true; + if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; + if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; + if (!currentSuperClass.isInterface()) return true; + + PsiElement element = member.getMember(); + if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; + if (element instanceof PsiField) { + return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); + } + return true; + } + + public boolean isAbstractEnabled(MemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if (currentSuperClass == null || !currentSuperClass.isInterface()) return true; + return false; + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + PsiClass currentSuperClass = getSuperClass(); + if(currentSuperClass == null) return false; + if (currentSuperClass.isInterface()) { + if (member.getMember() instanceof PsiMethod) { + return true; + } + } + return false; + } + + public int checkForProblems(MemberInfo member) { + if (member.isChecked()) return OK; + PsiClass currentSuperClass = getSuperClass(); + + if (currentSuperClass != null && currentSuperClass.isInterface()) { + PsiElement element = member.getMember(); + if (element instanceof PsiModifierListOwner) { + if (((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) { + return super.checkForProblems(member); + } + } + return OK; + } + else { + return super.checkForProblems(member); + } + } + + public Boolean isFixedAbstract(MemberInfo member) { + return Boolean.TRUE; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHandler.java new file mode 100644 index 00000000000..45c6d50c86f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHandler.java @@ -0,0 +1,202 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 18.06.2002 + * Time: 12:45:30 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoStorage; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + +public class PullUpHandler implements RefactoringActionHandler, PullUpDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHandler"); + public static final String REFACTORING_NAME = "Pull Members Up"; + private PsiClass mySubclass; + private Project myProject; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside a class to pull members from."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.MEMBERS_PULL_UP*/, project); + return; + } + + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return; + } + + if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + myProject = project; + + PsiElement element = elements[0]; + PsiClass aClass; + PsiElement aMember = null; + + if (element instanceof PsiClass) { + aClass = (PsiClass) element; + } else if (element instanceof PsiMethod) { + aClass = ((PsiMethod) element).getContainingClass(); + aMember = element; + } else if (element instanceof PsiField) { + aClass = ((PsiField) element).getContainingClass(); + aMember = element; + } else return; + + if(aClass == null) { + String message = + "Cannot perform the refactoring.\n" + + "Refactoring is not supported in current context."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.MEMBERS_PULL_UP*/, project); + return; + } + + ArrayList bases = RefactoringHierarchyUtil.createBasesList(aClass, false, true); + + if (bases.isEmpty()) { + String message = + "Cannot perform the refactoring.\n" + + aClass.getQualifiedName() + " does not have base classes/interfaces in current project."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.MEMBERS_PULL_UP*/, project); + return; + } + + + mySubclass = aClass; + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + if (element instanceof PsiMethod) { + return !((PsiMethod) element).isConstructor(); + } else { + return true; + } + } + }); + List members = memberInfoStorage.getClassMemberInfos(mySubclass); + PsiManager manager = mySubclass.getManager(); + + for (int i = 0; i < members.size(); i++) { + MemberInfo member = members.get(i); + + if (manager.areElementsEquivalent(member.getMember(), aMember)) { + member.setChecked(true); + break; + } + } + + final PullUpDialog dialog = new PullUpDialog(project, aClass, bases, memberInfoStorage, this); + + + dialog.show(); + + if (!dialog.isOK()) return; + + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + doRefactoring(dialog); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + REFACTORING_NAME, + null + ); + + } + + + private void doRefactoring(PullUpDialog dialog) { + com.intellij.openapi.localVcs.LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + try { + try { + PullUpHelper helper = new PullUpHelper(mySubclass, + dialog.getSuperClass(), + dialog.getSelectedMemberInfos(), + new JavaDocPolicy(dialog.getJavaDocPolicy()) + ); + helper.moveMembersToBase(); + helper.moveFieldInitializations(); + } finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + } + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private String getCommandName() { + return "Pulling members up from " + UsageViewUtil.getDescriptiveName(mySubclass); + } + + public boolean checkConflicts(PullUpDialog dialog) { + final MemberInfo[] infos = dialog.getSelectedMemberInfos(); + PsiClass superClass = dialog.getSuperClass(); + if (!checkWritable(superClass, infos)) return false; + String[] conflicts = PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, null, null, dialog.getContainmentVerifier()); + if (conflicts.length > 0) { + ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts, myProject); + conflictsDialog.show(); + return conflictsDialog.isOK(); + } + return true; + } + + private boolean checkWritable(PsiClass superClass, MemberInfo[] infos) { + if (!superClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, superClass); + return false; + } + for (int i = 0; i < infos.length; i++) { + MemberInfo info = infos[i]; + + if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; + if (!info.getMember().isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, info.getMember()); + return false; + } + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHelper.java new file mode 100644 index 00000000000..7d155c06ae7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -0,0 +1,642 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 14.06.2002 + * Time: 22:35:19 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Condition; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +public class PullUpHelper { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper"); + private final PsiClass mySourceClass; + private final PsiClass myTargetSuperClass; + private final boolean myIsTargetInterface; + private final MemberInfo[] myMembersToMove; + private final JavaDocPolicy myJavaDocPolicy; + private HashSet myMembersAfterMove = null; + private final PsiManager myManager; + + + public PullUpHelper(PsiClass sourceClass, PsiClass targetSuperClass, MemberInfo[] membersToMove, + JavaDocPolicy javaDocPolicy) { + mySourceClass = sourceClass; + myTargetSuperClass = targetSuperClass; + myMembersToMove = membersToMove; + myJavaDocPolicy = javaDocPolicy; + myIsTargetInterface = targetSuperClass.isInterface(); + myManager = mySourceClass.getManager(); + } + + public void moveMembersToBase() + throws IncorrectOperationException { + final HashSet movedMembers = new HashSet(); + myMembersAfterMove = new HashSet(); + + // build aux sets + for (int idx = 0; idx < myMembersToMove.length; idx++) { + PsiMember member = myMembersToMove[idx].getMember(); + movedMembers.add(member); + } + + // correct private member visibility + for (int idx = 0; idx < myMembersToMove.length; idx++) { + MemberInfo info = myMembersToMove[idx]; + if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; + PsiModifierListOwner modifierListOwner = info.getMember(); + if (myIsTargetInterface) { + modifierListOwner.getModifierList().setModifierProperty(PsiModifier.PUBLIC, true); + } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) { + if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) { + modifierListOwner.getModifierList().setModifierProperty(PsiModifier.PROTECTED, true); + } + } + ChangeContextUtil.encodeContextInfo(info.getMember(), true); + } + + // do actual move + for (int idx = 0; idx < myMembersToMove.length; idx++) { + MemberInfo info = myMembersToMove[idx]; + if (info.getMember() instanceof PsiMethod) { + PsiMethod method = (PsiMethod) info.getMember(); + final boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); + if (myIsTargetInterface || info.isToAbstract()) { + PsiMethod methodCopy = (PsiMethod) method.copy(); + ChangeContextUtil.clearContextInfo(method); + RefactoringUtil.abstractizeMethod(myTargetSuperClass, methodCopy); + + myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract); + + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(methodCopy); + myMembersAfterMove.add(movedElement); + if (isOriginalMethodAbstract) { + method.delete(); + } + } else { + if (isOriginalMethodAbstract) { + myTargetSuperClass.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true); + } + fixReferencesToStatic(method, movedMembers); + final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(method, false); + if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + superClassMethod.replace(method); + } else { + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(method); + myMembersAfterMove.add(movedElement); + } + method.delete(); + } + } else if (info.getMember() instanceof PsiField) { + PsiField field = (PsiField) info.getMember(); + field.normalizeDeclaration(); + fixReferencesToStatic(field, movedMembers); + if (myIsTargetInterface) { + field.getModifierList().setModifierProperty(PsiModifier.PUBLIC, true); + } + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field); + myMembersAfterMove.add(movedElement); + field.delete(); + } else if (info.getMember() instanceof PsiClass) { + PsiClass aClass = (PsiClass) info.getMember(); + if (Boolean.FALSE.equals(info.getOverrides())) { + final PsiReferenceList sourceReferenceList; + if (!mySourceClass.isInterface()) { + sourceReferenceList = mySourceClass.getImplementsList(); + } else { + sourceReferenceList = mySourceClass.getExtendsList(); + } + PsiJavaCodeReferenceElement ref = RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass); + if (ref != null) { + final PsiReferenceList referenceList; + if (!myTargetSuperClass.isInterface()) { + referenceList = myTargetSuperClass.getImplementsList(); + } else { + referenceList = myTargetSuperClass.getExtendsList(); + } + referenceList.add(ref); + } + } else { + fixReferencesToStatic(aClass, movedMembers); + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass); + myMembersAfterMove.add(movedElement); + aClass.delete(); + } + } + } + + ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter(); + for (Iterator iterator = myMembersAfterMove.iterator(); iterator.hasNext();) { + PsiMember element = iterator.next(); + if (!(element instanceof PsiClass)) { + element.accept(explicitSuperDeleter); + } + } + explicitSuperDeleter.fixSupers(); + + ChangeContextUtil.decodeContextInfo(myTargetSuperClass, null, null); + } + + public void moveFieldInitializations() throws IncorrectOperationException { + LOG.assertTrue(myMembersAfterMove != null); + + final HashSet movedFields = new HashSet(); + for (Iterator iterator = myMembersAfterMove.iterator(); iterator.hasNext();) { + PsiMember member = iterator.next(); + if (member instanceof PsiField) { + movedFields.add((PsiField)member); + } + } + + if (movedFields.isEmpty()) return; + PsiMethod[] constructors = myTargetSuperClass.getConstructors(); + + if (constructors.length == 0) { + constructors = new PsiMethod[]{null}; + } + + HashMap> constructorsToSubConstructors = buildConstructorsToSubConstructorsMap(constructors); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + HashSet subConstructors = constructorsToSubConstructors.get(constructor); + tryToMoveInitializers(constructor, subConstructors, movedFields); + } + } + + private static class Initializer { + public final PsiExpression initializer; + public final HashSet movedFieldsUsed; + public final ArrayList statementsToRemove; + + public Initializer(PsiExpression initializer, HashSet movedFieldsUsed, ArrayList statementsToRemove) { + this.initializer = initializer; + this.movedFieldsUsed = movedFieldsUsed; + this.statementsToRemove = statementsToRemove; + } + + } + + private void tryToMoveInitializers(PsiMethod constructor, HashSet subConstructors, HashSet movedFields) throws IncorrectOperationException { + final HashMap fieldsToInitializers = new HashMap(); + boolean anyFound = false; + + for (Iterator iterator = movedFields.iterator(); iterator.hasNext();) { + PsiField field = iterator.next(); + PsiExpression commonInitializer = null; + final ArrayList fieldInitializersToRemove = new ArrayList(); + for (Iterator subIterator = subConstructors.iterator(); subIterator.hasNext();) { + PsiMethod subConstructor = subIterator.next(); + commonInitializer = hasCommonInitializer(commonInitializer, subConstructor, field, fieldInitializersToRemove); + if (commonInitializer == null) break; + } + if (commonInitializer != null) { + final MovedFieldsUsed visitor = new MovedFieldsUsed(movedFields); + commonInitializer.accept(visitor); + fieldsToInitializers.put(field, new Initializer(commonInitializer, + visitor.getUsedFields(), fieldInitializersToRemove)); + anyFound = true; + } + } + + if (!anyFound) return; + + + + { + final Set initializedFields = fieldsToInitializers.keySet(); + Set unmovable = RefactoringUtil.transitiveClosure( + new RefactoringUtil.Graph() { + public Set getVertices() { + return initializedFields; + } + + public Set getTargets(PsiField source) { + return fieldsToInitializers.get(source).movedFieldsUsed; + } + }, + new Condition() { + public boolean value(PsiField object) { + return !initializedFields.contains(object); + } + } + ); + + for (Iterator iterator = unmovable.iterator(); iterator.hasNext();) { + PsiField psiField = iterator.next(); + fieldsToInitializers.remove(psiField); + } + } + + final PsiElementFactory factory = myManager.getElementFactory(); + + if (constructor == null) { + constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); + final String visibilityModifier = VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList()); + constructor.getModifierList().setModifierProperty(visibilityModifier, true); + } + + + ArrayList initializedFields = new ArrayList(fieldsToInitializers.keySet()); + + Collections.sort(initializedFields, new Comparator() { + public int compare(Object o1, Object o2) { + Initializer i1 = fieldsToInitializers.get(o1); + Initializer i2 = fieldsToInitializers.get(o2); + if(i1.movedFieldsUsed.contains(o2)) return 1; + if(i2.movedFieldsUsed.contains(o1)) return -1; + return 0; + } + }); + + for (Iterator iterator = initializedFields.iterator(); iterator.hasNext();) { + PsiField field = (PsiField) iterator.next(); + Initializer initializer = fieldsToInitializers.get(field); + + // create assignment statement + PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) factory.createStatementFromText(field.getName() + "=0;", constructor.getBody()); + assignmentStatement = (PsiExpressionStatement) CodeStyleManager.getInstance(myManager.getProject()).reformat(assignmentStatement); + assignmentStatement = (PsiExpressionStatement) constructor.getBody().add(assignmentStatement); + PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) assignmentStatement.getExpression(); + + // check whether we really assign a new field + PsiReferenceExpression fieldRef = (PsiReferenceExpression) assignmentExpression.getLExpression(); + PsiElement resolved = fieldRef.resolve(); + if (resolved != field) { + PsiElement qualifiedRef = factory.createExpressionFromText("this." + field.getName(), fieldRef); + qualifiedRef = CodeStyleManager.getInstance(myManager.getProject()).reformat(qualifiedRef); + fieldRef.replace(qualifiedRef); + } + + // add initializer + final PsiElement newInitializer = assignmentExpression.getRExpression().replace(initializer.initializer); + ChangeContextUtil.decodeContextInfo(newInitializer, + myTargetSuperClass, RefactoringUtil.createThisExpression(myManager, null)); + for (int i = 0; i < initializer.statementsToRemove.size(); i++) { + PsiElement psiElement = initializer.statementsToRemove.get(i); + psiElement.delete(); + } + } + + return; + } + + private PsiExpression hasCommonInitializer(PsiExpression commonInitializer, PsiMethod subConstructor, PsiField field, ArrayList statementsToRemove) { + PsiExpression commonInitializerCandidate = null; + final PsiCodeBlock body = subConstructor.getBody(); + if (body == null) return null; + final PsiStatement[] statements = body.getStatements(); + + // Algorithm: there should be only one write usage of field in a subConstructor, + // and in that usage field must be a target of top-level assignment, and RHS of assignment + // should be the same as commonInitializer if latter is non-null. + // + // There should be no usages before that initializer, and there should be + // no write usages afterwards. + for (int i = 0; i < statements.length; i++) { + PsiStatement statement = statements[i]; + boolean doLookup = true; + if (statement instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement) statement).getExpression(); + if (expression instanceof PsiAssignmentExpression) { + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) expression; + final PsiExpression lExpression = assignmentExpression.getLExpression(); + if (lExpression instanceof PsiReferenceExpression) { + final PsiReferenceExpression lRef = ((PsiReferenceExpression) lExpression); + if (lRef.getQualifierExpression() == null || lRef.getQualifierExpression() instanceof PsiThisExpression) { + final PsiElement resolved = lRef.resolve(); + if (resolved == field) { + doLookup = false; + if (commonInitializerCandidate == null) { + final PsiExpression initializer = assignmentExpression.getRExpression(); + if (commonInitializer == null) { + final IsMovableInitializerVisitor visitor = new IsMovableInitializerVisitor(); + initializer.accept(visitor); + if (visitor.isMovable()) { + ChangeContextUtil.encodeContextInfo(initializer, true); + PsiExpression initializerCopy = (PsiExpression) initializer.copy(); + ChangeContextUtil.clearContextInfo(initializer); + statementsToRemove.add(statement); + commonInitializerCandidate = initializerCopy; + } else { + return null; + } + } else { + if (CodeInsightUtil.areExpressionsEquivalent(commonInitializer, initializer)) { + statementsToRemove.add(statement); + commonInitializerCandidate = commonInitializer; + } else { + return null; + } + } + } else { + return null; + } + } + } + } + } + } + + if(doLookup) { + final PsiReference[] references = + myManager.getSearchHelper().findReferences(field, new LocalSearchScope(statement), false); + if(commonInitializerCandidate == null && references.length > 0) { + return null; + } + + for (int j = 0; j < references.length; j++) { + PsiReference reference = references[j]; + if(RefactoringUtil.isAssignmentLHS(reference.getElement())) return null; + } + } + } + return commonInitializerCandidate; + } + + private static class MovedFieldsUsed extends PsiRecursiveElementVisitor { + private final HashSet myMovedFields; + private final HashSet myUsedFields; + + public MovedFieldsUsed(HashSet movedFields) { + myMovedFields = movedFields; + myUsedFields = new HashSet(); + } + + public HashSet getUsedFields() { + return myUsedFields; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null + && !(qualifierExpression instanceof PsiThisExpression)) { + return; + } + final PsiElement resolved = expression.resolve(); + if (myMovedFields.contains(resolved)) { + myUsedFields.add((PsiField)resolved); + } + } + } + + private class IsMovableInitializerVisitor extends PsiRecursiveElementVisitor { + private boolean myIsMovable = true; + + public boolean isMovable() { + return myIsMovable; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement referenceElement) { + if (!myIsMovable) return; + final PsiExpression qualifier; + if (referenceElement instanceof PsiReferenceExpression) { + qualifier = ((PsiReferenceExpression) referenceElement).getQualifierExpression(); + } else { + qualifier = null; + } + if (qualifier == null || qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) { + final PsiElement resolved = referenceElement.resolve(); + PsiClass containingClass = null; + if (resolved instanceof PsiField) { + containingClass = ((PsiField) resolved).getContainingClass(); + } else if (resolved instanceof PsiMethod) { + containingClass = ((PsiMethod) resolved).getContainingClass(); + } else if (resolved instanceof PsiClass) { + final PsiElement parent = resolved.getParent(); + if (parent instanceof PsiClass && !((PsiClass) resolved).hasModifierProperty(PsiModifier.STATIC)) { + containingClass = (PsiClass) resolved; + } else { + return; + } + } + if (containingClass != null) { + myIsMovable = + myManager.areElementsEquivalent(myTargetSuperClass, containingClass) + || myTargetSuperClass.isInheritor(containingClass, true); + } else { + myIsMovable = false; + } + } else { + qualifier.accept(this); + } + } + + public void visitElement(PsiElement element) { + if (myIsMovable) { + super.visitElement(element); + } + } + } + + private HashMap> buildConstructorsToSubConstructorsMap(final PsiMethod[] constructors) { + final com.intellij.util.containers.HashMap> constructorsToSubConstructors = new com.intellij.util.containers.HashMap>(); + for (int i = 0; i < constructors.length; i++) { + PsiMethod constructor = constructors[i]; + final HashSet referencingSubConstructors = new HashSet(); + constructorsToSubConstructors.put(constructor, referencingSubConstructors); + if (constructor != null) { + final PsiReference[] references + = myManager.getSearchHelper().findReferences(constructor, new LocalSearchScope(mySourceClass), false); + // find references + for (int j = 0; j < references.length; j++) { + PsiReference reference = references[j]; + final PsiElement element = reference.getElement(); + if (element != null && "super".equals(element.getText())) { + PsiMethod parentMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (parentMethod != null && parentMethod.isConstructor()) { + referencingSubConstructors.add(parentMethod); + } + } + } + } + + // check default constructor + if (constructor == null || constructor.getParameterList().getParameters().length == 0) { + RefactoringUtil.visitImplicitSuperConstructorUsages(mySourceClass, new RefactoringUtil.ImplicitConstructorUsageVisitor() { + public void visitConstructor(PsiMethod constructor) { + referencingSubConstructors.add(constructor); + } + + public void visitClassWithoutConstructors(PsiClass aClass) { + } + }); + + } + } + return constructorsToSubConstructors; + } + + private void fixReferencesToStatic(PsiElement classMember, Set movedMembers) throws IncorrectOperationException { + StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers); + classMember.accept(collector); + ArrayList refs = collector.getReferences(); + ArrayList members = collector.getReferees(); + ArrayList classes = collector.getRefereeClasses(); + PsiElementFactory factory = classMember.getManager().getElementFactory(); + + for (int i = 0; i < refs.size(); i++) { + PsiJavaCodeReferenceElement ref = refs.get(i); + PsiElement namedElement = members.get(i); + PsiClass aClass = classes.get(i); + + if (namedElement instanceof PsiNamedElement) { + PsiReferenceExpression newRef = + (PsiReferenceExpression) factory.createExpressionFromText + ("a." + ((PsiNamedElement) namedElement).getName(), + null); + newRef = (PsiReferenceExpression) CodeStyleManager.getInstance(myManager.getProject()).reformat(newRef); + newRef.getQualifierExpression().replace(factory.createReferenceExpression(aClass)); + ref.replace(newRef); + } + } + } + + private class StaticReferencesCollector extends ClassMemberReferencesVisitor { + ArrayList myReferences; + ArrayList myReferees; + ArrayList myRefereeClasses; + private final Set myMovedMembers; + + public StaticReferencesCollector(Set movedMembers) { + super(mySourceClass); + myMovedMembers = movedMembers; + myReferees = new ArrayList(); + myRefereeClasses = new ArrayList(); + myReferences = new ArrayList(); + } + + public ArrayList getReferees() { + return myReferees; + } + + public ArrayList getRefereeClasses() { + return myRefereeClasses; + } + + public ArrayList getReferences() { + return myReferences; + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if (classMember instanceof PsiClass) return; + if (classMember.hasModifierProperty(PsiModifier.STATIC) + && !myMovedMembers.contains(classMember) + && RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) { + myReferences.add(classMemberReference); + myReferees.add(classMember); + myRefereeClasses.add(classMember.getContainingClass()); + } + } + } + + private class ExplicitSuperDeleter extends PsiRecursiveElementVisitor { + private ArrayList mySupersToDelete = new ArrayList(); + private ArrayList mySupersToChangeToThis = new ArrayList(); + + public void visitReferenceExpression(PsiReferenceExpression expression) { + if(expression.getQualifierExpression() instanceof PsiSuperExpression) { + PsiElement resolved = expression.resolve(); + if (resolved == null || (resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved))) { + mySupersToDelete.add(expression.getQualifierExpression()); + } + } + } + + public void visitSuperExpression(PsiSuperExpression expression) { + mySupersToChangeToThis.add(expression); + } + + public void visitClass(PsiClass aClass) { + // do nothing + } + + private boolean shouldFixSuper(PsiMethod method) { + for (Iterator iterator = myMembersAfterMove.iterator(); iterator.hasNext();) { + PsiMember element = iterator.next(); + if(element instanceof PsiMethod) { + PsiMethod member = ((PsiMethod) element); + // if there is such member among moved members, super qualifier + // should not be removed + final PsiManager manager = method.getManager(); + if(manager.areElementsEquivalent(member.getContainingClass(), method.getContainingClass()) && + MethodSignatureUtil.areSignaturesEqual(member, method)) { + return false; + } + } + } + + final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); + if(methodFromSuper != null) { + return false; + } + return true; + } + + public void fixSupers() throws IncorrectOperationException { + final PsiElementFactory factory = myManager.getElementFactory(); + PsiThisExpression thisExpression = (PsiThisExpression) factory.createExpressionFromText("this", null); + for (int i = 0; i < mySupersToDelete.size(); i++) { + PsiExpression psiExpression = mySupersToDelete.get(i); + psiExpression.delete(); + } + + for (int i = 0; i < mySupersToChangeToThis.size(); i++) { + PsiSuperExpression psiSuperExpression = mySupersToChangeToThis.get(i); + psiSuperExpression.replace(thisExpression); + } + } + } + + private static boolean willBeUsedInSubclass(PsiElement member, Set movedMembers, PsiClass superclass, PsiClass subclass) { + PsiSearchHelper helper = member.getManager().getSearchHelper(); + PsiReference[] refs = helper.findReferences(member, new LocalSearchScope(subclass), false); + for (int idx = 0; idx < refs.length; idx++) { + PsiElement ref = refs[idx].getElement(); + if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, movedMembers, superclass, false)) { + return true; + } + } + return false; + } + + public static boolean checkedInterfacesContain(MemberInfo[] memberInfos, PsiMethod psiMethod) { + for (int i = 0; i < memberInfos.length; i++) { + MemberInfo memberInfo = memberInfos[i]; + if (memberInfo.isChecked() && + memberInfo.getMember() instanceof PsiClass && + Boolean.FALSE.equals(memberInfo.getOverrides())) { + if( ((PsiClass) memberInfo.getMember()).findMethodBySignature(psiMethod, true) != null) { + return true; + } + } + } + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownConflicts.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownConflicts.java new file mode 100644 index 00000000000..b8210f22397 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownConflicts.java @@ -0,0 +1,109 @@ +package com.intellij.refactoring.memberPushDown; + +import com.intellij.psi.*; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; +import com.intellij.refactoring.util.classMembers.MemberInfo; + +import java.util.*; + +public class PushDownConflicts { + private PsiClass myClass; + private Set myMovedMembers; + private Set myAbstractMembers; + private ArrayList myConflicts; + + + public PushDownConflicts(PsiClass aClass, MemberInfo[] memberInfos) { + myClass = aClass; + + myMovedMembers = new HashSet(); + myAbstractMembers = new HashSet(); + for (int i = 0; i < memberInfos.length; i++) { + MemberInfo memberInfo = memberInfos[i]; + final PsiElement member = memberInfo.getMember(); + if(memberInfo.isChecked() && (!(memberInfo.getMember() instanceof PsiClass) || memberInfo.getOverrides() == null)) { + myMovedMembers.add(member); + if(memberInfo.isToAbstract()) { + myAbstractMembers.add(member); + } + } + } + + myConflicts = new ArrayList(); + } + + public boolean isAnyConflicts() { + return !myConflicts.isEmpty(); + } + + public String[] getConflicts() { + return (String[]) myConflicts.toArray(new String[myConflicts.size()]); + } + + public void checkSourceClassConflicts() { + final PsiElement[] children = myClass.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + if(child instanceof PsiClass || child instanceof PsiMethod || child instanceof PsiField) { + if (!myMovedMembers.contains(child)) { + child.accept(new UsedMovedMembersConflictsCollector(child)); + } + } + } + } + + public void checkTargetClassConflicts(PsiClass targetClass) { + for (Iterator iterator = myMovedMembers.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement) iterator.next(); + if(element instanceof PsiField) { + String name = ((PsiField) element).getName(); + if(targetClass.findFieldByName(name, false) != null) { + String message = ConflictsUtil.getDescription(targetClass, false) + " already contains field " + + ConflictsUtil.htmlEmphasize(name) + "."; + myConflicts.add(ConflictsUtil.capitalize(message)); + } + } + else if(element instanceof PsiMethod) { + PsiMethod method = (PsiMethod) element; + if(targetClass.findMethodBySignature(method, false) != null) { + String message = ConflictsUtil.getDescription(method, true) + " is already overridden in " + + ConflictsUtil.getDescription(targetClass, false) + ". Method will not be pushed down to that class."; + myConflicts.add(ConflictsUtil.capitalize(message)); + } + } + else if(element instanceof PsiClass) { + PsiClass aClass = (PsiClass) element; + final String name = aClass.getName(); + final PsiClass[] allInnerClasses = targetClass.getAllInnerClasses(); + for (int i = 0; i < allInnerClasses.length; i++) { + PsiClass innerClass = allInnerClasses[i]; + + if(name.equals(innerClass.getName())) { + String message = ConflictsUtil.getDescription(targetClass, false) + " already contains inner class named " + + ConflictsUtil.htmlEmphasize(name) + "."; + myConflicts.add(message); + } + } + } + } + } + + private class UsedMovedMembersConflictsCollector extends ClassMemberReferencesVisitor { + private final PsiElement mySource; + + public UsedMovedMembersConflictsCollector(PsiElement source) { + super(myClass); + mySource = source; + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if(myMovedMembers.contains(classMember) && !myAbstractMembers.contains(classMember)) { + String message = ConflictsUtil.getDescription(mySource, false) + + " uses " + ConflictsUtil.getDescription(classMember, false) + ", which is pushed down"; + message = ConflictsUtil.capitalize(message); + myConflicts.add(message); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownDialog.java new file mode 100644 index 00000000000..3112e0a690a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownDialog.java @@ -0,0 +1,112 @@ +package com.intellij.refactoring.memberPushDown; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.memberPullUp.JavaDocPanel; +import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoChange; +import com.intellij.refactoring.util.classMembers.MemberInfoModel; +import com.intellij.refactoring.util.classMembers.UsedByDependencyMemberInfoModel; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +public class PushDownDialog extends RefactoringDialog { + private MemberInfo[] myMemberInfos; + private PsiClass myClass; + private final Callback myCallback; + private MemberSelectionPanel myMemberSelectionPanel; + private JavaDocPanel myJavaDocPanel; + private MemberInfoModel myMemberInfoModel; + + public static interface Callback { + void run(PushDownDialog dialog); + } + + public PushDownDialog(Project project, MemberInfo[] memberInfos, PsiClass aClass, Callback callback) { + super(project, true); + myMemberInfos = memberInfos; + myClass = aClass; + myCallback = callback; + + setTitle(PushDownHandler.REFACTORING_NAME); + + init(); + } + + public int getJavaDocPolicy() { + return myJavaDocPanel.getPolicy(); + } + + public MemberInfo[] getSelectedMemberInfos() { + ArrayList list = new ArrayList(myMemberInfos.length); + for (int idx = 0; idx < myMemberInfos.length; idx++) { + MemberInfo info = myMemberInfos[idx]; + if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) { + list.add(info); + } + } + return (MemberInfo[]) list.toArray(new MemberInfo[list.size()]); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PUSH_DOWN); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.memberPushDown.PushDownDialog"; + } + + protected JComponent createNorthPanel() { + GridBagConstraints gbConstraints = new GridBagConstraints(); + + JPanel panel = new JPanel(new GridBagLayout()); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.anchor = GridBagConstraints.WEST; + panel.add(new JLabel("Push members from " + myClass.getQualifiedName() + " down"), gbConstraints); + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myMemberSelectionPanel = new MemberSelectionPanel("Members to be pushed down", myMemberInfos, "Keep abstract"); + panel.add(myMemberSelectionPanel, BorderLayout.CENTER); + + myMemberInfoModel = new MyMemberInfoModel(); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel); + myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel); + + + myJavaDocPanel = new JavaDocPanel("JavaDoc for abstracts"); + myJavaDocPanel.setPolicy(RefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC); + panel.add(myJavaDocPanel, BorderLayout.EAST); + return panel; + } + + protected void doAction() { + if(!isOKActionEnabled()) return; + + RefactoringSettings.getInstance().PUSH_DOWN_PREVIEW_USAGES = isPreviewUsages(); + myCallback.run(this); + } + + private class MyMemberInfoModel extends UsedByDependencyMemberInfoModel { + public MyMemberInfoModel() { + super(myClass); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownHandler.java new file mode 100644 index 00000000000..c6dc39a5f6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownHandler.java @@ -0,0 +1,116 @@ +package com.intellij.refactoring.memberPushDown; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoStorage; + +import java.util.List; + +/** + * @author dsl + */ +public class PushDownHandler implements RefactoringActionHandler, PushDownDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPushDown.PushDownHandler"); + public static final String REFACTORING_NAME = "Push Members Down"; + private PsiClass myClass; + private Project myProject; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside a class to push members from"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.MEMBERS_PUSH_DOWN*/, project); + return; + } + + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return; + } + + if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + myProject = project; + + PsiElement element = elements[0]; + PsiClass aClass; + PsiElement aMember = null; + + if (element instanceof PsiClass) { + aClass = (PsiClass) element; + } else if (element instanceof PsiMethod) { + aClass = ((PsiMethod) element).getContainingClass(); + aMember = element; + } else if (element instanceof PsiField) { + aClass = ((PsiField) element).getContainingClass(); + aMember = element; + } else + return; + + myClass = aClass; + if (!myClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, myClass); + return; + } + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(myClass, new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + if (element instanceof PsiMethod) { + return !((PsiMethod) element).isConstructor(); + } else { + return true; + } + } + }); + List members = memberInfoStorage.getClassMemberInfos(myClass); + PsiManager manager = myClass.getManager(); + + for (int i = 0; i < members.size(); i++) { + MemberInfo member = members.get(i); + + if (manager.areElementsEquivalent(member.getMember(), aMember)) { + member.setChecked(true); + break; + } + } + PushDownDialog dialog = new PushDownDialog( + project, + members.toArray(new MemberInfo[members.size()]), + myClass, this + ); + dialog.show(); + } + + public void run(final PushDownDialog dialog) { + new PushDownProcessor( + myProject, dialog.getSelectedMemberInfos(), myClass, + new JavaDocPolicy(dialog.getJavaDocPolicy()), dialog.isPreviewUsages(), new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + ).run(null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownProcessor.java new file mode 100644 index 00000000000..9da14e88583 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownProcessor.java @@ -0,0 +1,183 @@ +package com.intellij.refactoring.memberPushDown; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.JavaDocPolicy; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.IncorrectOperationException; + +public class PushDownProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPushDown.PushDownProcessor"); + private MemberInfo myMemberInfos[]; + private PsiClass myClass; + private boolean myIsPreviewUsages; + private JavaDocPolicy myJavaDocPolicy; + + public PushDownProcessor(Project project, MemberInfo[] memberInfos, PsiClass aClass, JavaDocPolicy javaDocPolicy, boolean previewUsages, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myMemberInfos = memberInfos; + myClass = aClass; + myIsPreviewUsages = previewUsages; + myJavaDocPolicy = javaDocPolicy; + } + + protected String getCommandName() { + return PushDownHandler.REFACTORING_NAME; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new PushDownUsageViewDescriptor(myClass, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + PsiManager manager = PsiManager.getInstance(myProject); + final PsiSearchHelper searchHelper = manager.getSearchHelper(); + final PsiClass[] inheritors = searchHelper.findInheritors(myClass, GlobalSearchScope.projectScope(myProject), false); + UsageInfo[] usages = new UsageInfo[inheritors.length]; + for (int i = 0; i < inheritors.length; i++) { + usages[i] = new UsageInfo(inheritors[i]); + } + return usages; + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + final PushDownConflicts pushDownConflicts = new PushDownConflicts(myClass, myMemberInfos); + pushDownConflicts.checkSourceClassConflicts(); + + if (usages[0].length == 0) { + final String message = (myClass.isInterface() ? "Interface " : "Class ") + + myClass.getQualifiedName() + " does not have inheritors.\n" + + "Pushing memebers down will result in them being deleted. Continue?"; + final int answer = Messages.showYesNoDialog(message, "Push Down", Messages.getWarningIcon()); + if (answer != 0) return false; + } + for (int i = 0; i < usages[0].length; i++) { + final PsiElement element = usages[0][i].getElement(); + if(element instanceof PsiClass) { + pushDownConflicts.checkTargetClassConflicts((PsiClass) element); + } + } + if(pushDownConflicts.isAnyConflicts()) { + final String[] conflicts = pushDownConflicts.getConflicts(); + ConflictsDialog dialog = new ConflictsDialog(conflicts, myProject); + dialog.show(); + if(!dialog.isOK()) return false; + } + + prepareSuccessful(); + + return true; + } + + protected void refreshElements(PsiElement[] elements) { + if(elements.length == 1 && elements[0] instanceof PsiClass) { + myClass = (PsiClass) elements[0]; + } + else { + LOG.assertTrue(false); + } + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages) || myIsPreviewUsages; + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + + if(usage.getElement() instanceof PsiClass) { + pushDownToClass((PsiClass) usage.getElement()); + } + } + removeFromTargetClass(); + } + catch (IncorrectOperationException e) { + LOG.assertTrue(false); + } + } + + private void removeFromTargetClass() throws IncorrectOperationException { + for (int i = 0; i < myMemberInfos.length; i++) { + MemberInfo memberInfo = myMemberInfos[i]; + final PsiElement member = memberInfo.getMember(); + + if(member instanceof PsiField) { + member.delete(); + } + else if(member instanceof PsiMethod) { + if(memberInfo.isToAbstract()) { + final PsiMethod method = (PsiMethod) member; + if (method.hasModifierProperty(PsiModifier.PRIVATE)) { + method.getModifierList().setModifierProperty(PsiModifier.PROTECTED, true); + } + RefactoringUtil.abstractizeMethod(myClass, method); + myJavaDocPolicy.processOldJavaDoc(method.getDocComment()); + } + else { + member.delete(); + } + } + else if(member instanceof PsiClass) { + if(Boolean.FALSE.equals(memberInfo.getOverrides())) { + RefactoringUtil.removeFromReferenceList(myClass.getImplementsList(), (PsiClass) member); + } + else { + member.delete(); + } + } + } + } + + + private void pushDownToClass(PsiClass targetClass) throws IncorrectOperationException { + PsiElementFactory factory = myClass.getManager().getElementFactory(); + for (int i = 0; i < myMemberInfos.length; i++) { + MemberInfo memberInfo = myMemberInfos[i]; + final PsiElement member = memberInfo.getMember(); + + if(member instanceof PsiField) { + targetClass.add(member); + } + else if(member instanceof PsiMethod) { + PsiMethod method = (PsiMethod) member; + + if(targetClass.findMethodBySignature(method, false) == null) { + PsiMethod newMethod = (PsiMethod) targetClass.add(method); + if(memberInfo.isToAbstract()) { + if (newMethod.hasModifierProperty(PsiModifier.PRIVATE)) { + newMethod.getModifierList().setModifierProperty(PsiModifier.PROTECTED, true); + } + myJavaDocPolicy.processNewJavaDoc(newMethod.getDocComment()); + } + } + } + else if(member instanceof PsiClass) { + if(Boolean.FALSE.equals(memberInfo.getOverrides())) { + final PsiClass aClass = (PsiClass) member; + if (!targetClass.isInheritor(aClass, false)) { + PsiJavaCodeReferenceElement classRef = factory.createClassReferenceElement(aClass); + targetClass.getImplementsList().add(classRef); + } + } + else { + targetClass.add(member); + } + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownUsageViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownUsageViewDescriptor.java new file mode 100644 index 00000000000..f1946b6deee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/memberPushDown/PushDownUsageViewDescriptor.java @@ -0,0 +1,96 @@ +package com.intellij.refactoring.memberPushDown; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class PushDownUsageViewDescriptor implements UsageViewDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPushDown.PushDownUsageViewDescriptor"); + private PsiClass myClass; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + private final String myProcessedElementsHeader = "Push down members from"; + + public PushDownUsageViewDescriptor(PsiClass aClass, UsageInfo[] usages, FindUsagesCommand refreshComamnd) { + myClass = aClass; + myUsages = usages; + myRefreshCommand = refreshComamnd; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + if (elements.length == 1 && elements[0] instanceof PsiClass) { + myClass = (PsiClass) elements[0]; + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myProcessedElementsHeader; + } + + public PsiElement[] getElements() { + return new PsiElement[]{myClass}; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "Classes to push down members to " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, REFERENCE_WORD); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public boolean canRefresh() { + return false; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public String getHelpID() { + return null/*HelpID.MEMBERS_PUSH_DOWN*/; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationDialog.java new file mode 100644 index 00000000000..9e5ecd95fa8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationDialog.java @@ -0,0 +1,322 @@ + +package com.intellij.refactoring.migration; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class EditMigrationDialog extends DialogWrapper{ + private JTable myTable; + private JButton myEditButton; + private JButton myAddButton; + private JButton myRemoveButton; + private JButton myMoveUpButton; + private JButton myMoveDownButton; + private JTextField myNameField; + private JTextArea myDescriptionTextArea; + private Project myProject; + private MigrationMap myMigrationMap; + + public EditMigrationDialog(Project project, MigrationMap migrationMap) { + super(project, true); + myProject = project; + myMigrationMap = migrationMap; + setHorizontalStretch(1.2f); + setTitle("Edit Migration Map"); + init(); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + public String getName() { + return myNameField.getText(); + } + + public String getDescription() { + return myDescriptionTextArea.getText(); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.anchor = GridBagConstraints.EAST; + JLabel promptLabel = new JLabel("Map name:"); + panel.add(promptLabel, gbConstraints); + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + myNameField = new JTextField(myMigrationMap.getName()); + panel.add(myNameField, gbConstraints); + + gbConstraints.fill = GridBagConstraints.VERTICAL; + gbConstraints.weightx = 0; + gbConstraints.weighty = 1; + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.anchor = GridBagConstraints.EAST; + JLabel descriptionPromptLabel = new JLabel("Map description:"); + panel.add(descriptionPromptLabel, gbConstraints); + + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + + myDescriptionTextArea = new JTextArea(myMigrationMap.getDescription(), 3, 40); + myDescriptionTextArea.setLineWrap(true); + myDescriptionTextArea.setWrapStyleWord(true); + JScrollPane scrollPane = new JScrollPane(myDescriptionTextArea); + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + myDescriptionTextArea.setFont(myNameField.getFont()); + myDescriptionTextArea.setBackground(myNameField.getBackground()); + scrollPane.setBorder(myNameField.getBorder()); + panel.add(scrollPane, gbConstraints); + + return panel; + } + + protected JComponent createCenterPanel() { + JPanel tablePanel = new JPanel(new BorderLayout()); + tablePanel.setBorder(IdeBorderFactory.createBorder()); + tablePanel.add(createTable(), BorderLayout.CENTER); + + JPanel tableButtonsPanel = new JPanel(); + tableButtonsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + tableButtonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(5,0,5,0); + + myAddButton = new JButton("Add..."); + tableButtonsPanel.add(myAddButton, gbConstraints); + myEditButton = new JButton("Edit..."); + tableButtonsPanel.add(myEditButton, gbConstraints); + myRemoveButton = new JButton("Remove"); + tableButtonsPanel.add(myRemoveButton, gbConstraints); + myMoveUpButton = new JButton("Move Up"); + tableButtonsPanel.add(myMoveUpButton, gbConstraints); + myMoveDownButton = new JButton("Move Down"); + tableButtonsPanel.add(myMoveDownButton, gbConstraints); + + gbConstraints.weighty = 1; + tableButtonsPanel.add(new JPanel(), gbConstraints); + + tablePanel.add(tableButtonsPanel, BorderLayout.EAST); + + myEditButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + edit(); + } + } + ); + + myAddButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + addRow(); + } + } + ); + + myRemoveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + removeRow(); + } + } + ); + + myMoveUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + moveUp(); + } + } + ); + + myMoveDownButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + moveDown(); + } + } + ); + + myTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener(){ + public void valueChanged(ListSelectionEvent e){ + enableButtons(); + } + } + ); + + enableButtons(); + return tablePanel; + } + + private void edit() { + EditMigrationEntryDialog dialog = new EditMigrationEntryDialog(myProject); + int selected = myTable.getSelectedRow(); + if (selected < 0) + return; + MigrationMapEntry entry = myMigrationMap.getEntryAt(selected); + dialog.setEntry(entry); + dialog.show(); + if (!dialog.isOK()){ + return; + } + dialog.updateEntry(entry); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsUpdated(selected, selected); + } + + private void addRow() { + EditMigrationEntryDialog dialog = new EditMigrationEntryDialog(myProject); + MigrationMapEntry entry = new MigrationMapEntry(); + dialog.setEntry(entry); + dialog.show(); + if (!dialog.isOK()){ + return; + } + dialog.updateEntry(entry); + myMigrationMap.addEntry(entry); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsInserted(myMigrationMap.getEntryCount() - 1, myMigrationMap.getEntryCount() - 1); + myTable.setRowSelectionInterval(myMigrationMap.getEntryCount() - 1, myMigrationMap.getEntryCount() - 1); + } + + private void removeRow() { + int selected = myTable.getSelectedRow(); + if (selected < 0) + return; + myMigrationMap.removeEntryAt(selected); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsDeleted(selected, selected); + if (selected >= myMigrationMap.getEntryCount()){ + selected--; + } + if (selected >= 0){ + myTable.setRowSelectionInterval(selected, selected); + } + } + + private void moveUp() { + int selected = myTable.getSelectedRow(); + if (selected < 1) + return; + MigrationMapEntry entry = myMigrationMap.getEntryAt(selected); + MigrationMapEntry previousEntry = myMigrationMap.getEntryAt(selected - 1); + myMigrationMap.setEntryAt(previousEntry, selected); + myMigrationMap.setEntryAt(entry, selected - 1); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsUpdated(selected - 1, selected); + myTable.setRowSelectionInterval(selected - 1, selected - 1); + } + + private void moveDown() { + int selected = myTable.getSelectedRow(); + if (selected >= myMigrationMap.getEntryCount() - 1) + return; + MigrationMapEntry entry = myMigrationMap.getEntryAt(selected); + MigrationMapEntry nextEntry = myMigrationMap.getEntryAt(selected + 1); + myMigrationMap.setEntryAt(nextEntry, selected); + myMigrationMap.setEntryAt(entry, selected + 1); + AbstractTableModel model = (AbstractTableModel)myTable.getModel(); + model.fireTableRowsUpdated(selected, selected + 1); + myTable.setRowSelectionInterval(selected + 1, selected + 1); + } + + private JScrollPane createTable() { + final String[] names = {"Type", "Old name", "New name"}; + + // Create a model of the data. + TableModel dataModel = new AbstractTableModel() { + public int getColumnCount() { + return 3; + } + + public int getRowCount() { + return myMigrationMap.getEntryCount(); + } + + public Object getValueAt(int row, int col) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(row); + if (col == 0){ + if (entry.getType() == MigrationMapEntry.PACKAGE && entry.isRecursive()){ + return "Package with subpackages"; + } + else if (entry.getType() == MigrationMapEntry.PACKAGE && !entry.isRecursive()){ + return "Package"; + } + else{ + return "Class"; + } + } + + String suffix = (entry.getType() == MigrationMapEntry.PACKAGE ? ".*" : ""); + if (col == 1){ + return entry.getOldName() + suffix; + } + else{ + return entry.getNewName() + suffix; + } + } + + public String getColumnName(int column) { + return names[column]; + } + + public Class getColumnClass(int c) { + return String.class; + } + + public boolean isCellEditable(int row, int col) { + return false; + } + + public void setValueAt(Object aValue, int row, int column) { + } + }; + + // Create the table + myTable = new Table(dataModel); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + myTable.setPreferredScrollableViewportSize(new Dimension(300, myTable.getRowHeight() * 10)); + + JScrollPane scrollpane = ScrollPaneFactory.createScrollPane(myTable); + return scrollpane; + } + + private void enableButtons() { + int selectedIndex = myTable.getSelectedRow(); + myEditButton.setEnabled(selectedIndex != -1); + myRemoveButton.setEnabled(selectedIndex != -1); + myMoveDownButton.setEnabled(selectedIndex != -1 && selectedIndex < myTable.getRowCount() - 1); + myMoveUpButton.setEnabled(selectedIndex > 0); + } + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationEntryDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationEntryDialog.java new file mode 100644 index 00000000000..492e3da3fa6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/EditMigrationEntryDialog.java @@ -0,0 +1,136 @@ + +package com.intellij.refactoring.migration; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiManager; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; + +public class EditMigrationEntryDialog extends DialogWrapper{ + private JRadioButton myRbPackage; + private JRadioButton myRbClass; + private JTextField myOldNameField; + private JTextField myNewNameField; + private Project myProject; + + public EditMigrationEntryDialog(Project project) { + super(project, true); + myProject = project; + setTitle("Edit Class/Package Migration Description"); + setHorizontalStretch(1.2f); + init(); + } + + public JComponent getPreferredFocusedComponent() { + return myOldNameField; + } + + protected JComponent createCenterPanel() { + return null; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + panel.setBorder(IdeBorderFactory.createBorder()); + gbConstraints.insets = new Insets(4, 4, 4, 4); + gbConstraints.weighty = 1; + + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 0; + myRbPackage = new JRadioButton("Package"); + panel.add(myRbPackage, gbConstraints); + + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 0; + myRbClass = new JRadioButton("Class"); + panel.add(myRbClass, gbConstraints); + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + panel.add(new JPanel(), gbConstraints); + + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbPackage); + buttonGroup.add(myRbClass); + + gbConstraints.weightx = 0; + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.fill = GridBagConstraints.VERTICAL; + JLabel oldNamePrompt = new JLabel("Old name:"); + panel.add(oldNamePrompt, gbConstraints); + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + myOldNameField = new JTextField(); + panel.add(myOldNameField, gbConstraints); + + gbConstraints.weightx = 0; + gbConstraints.gridwidth = GridBagConstraints.RELATIVE; + gbConstraints.fill = GridBagConstraints.VERTICAL; + JLabel newNamePrompt = new JLabel("New name:"); + panel.add(newNamePrompt, gbConstraints); + + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + myNewNameField = new JTextField(); + panel.setPreferredSize(new Dimension(300, panel.getPreferredSize().height)); + panel.add(myNewNameField, gbConstraints); + + DocumentListener documentListener = new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + validateOKButton(); + } + }; + myOldNameField.getDocument().addDocumentListener(documentListener); + myNewNameField.getDocument().addDocumentListener(documentListener); + return panel; + } + + private void validateOKButton() { + boolean isEnabled = true; + String text = myOldNameField.getText(); + text = text.trim(); + PsiManager manager = PsiManager.getInstance(myProject); + if (!manager.getNameHelper().isQualifiedName(text)){ + isEnabled = false; + } + text = myNewNameField.getText(); + text = text.trim(); + if (!manager.getNameHelper().isQualifiedName(text)){ + isEnabled = false; + } + setOKActionEnabled(isEnabled); + } + + public void setEntry(MigrationMapEntry entry) { + myOldNameField.setText(entry.getOldName()); + myNewNameField.setText(entry.getNewName()); + myRbPackage.setSelected(entry.getType() == MigrationMapEntry.PACKAGE); + myRbClass.setSelected(entry.getType() == MigrationMapEntry.CLASS); + validateOKButton(); + } + + public void updateEntry(MigrationMapEntry entry) { + entry.setOldName(myOldNameField.getText().trim()); + entry.setNewName(myNewNameField.getText().trim()); + if (myRbPackage.isSelected()){ + entry.setType(MigrationMapEntry.PACKAGE); + entry.setRecursive(true); + } + else{ + entry.setType(MigrationMapEntry.CLASS); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationDialog.java new file mode 100644 index 00000000000..631d189380b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationDialog.java @@ -0,0 +1,248 @@ + +package com.intellij.refactoring.migration; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.refactoring.HelpID; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.io.IOException; + +public class MigrationDialog extends DialogWrapper{ + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.migration.MigrationDialog"); + + private JPanel myPanel; + private JComboBox myMapComboBox; + private JTextArea myDescriptionTextArea; + private JButton myEditMapButton; + private JButton myNewMapButton; + private JButton myRemoveMapButton; + private Project myProject; + private MigrationMapSet myMigrationMapSet; + private JLabel promptLabel; + private JSeparator mySeparator; + private JScrollPane myDescriptionScroll; + + + public MigrationDialog(Project project, MigrationMapSet migrationMapSet) { + super(project, true); + myProject = project; + myMigrationMapSet = migrationMapSet; + setTitle("Package and Class Migration"); + setHorizontalStretch(1.2f); + setOKButtonText("Run"); + init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myMapComboBox; + } + + protected JComponent createCenterPanel() { + class MyTextArea extends JTextArea { + public MyTextArea(String s, int a, int b) { + super(s, a, b); + setFocusable(false); + } + } + + initMapCombobox(); + myDescriptionTextArea = new MyTextArea("", 3, 40); + JScrollPane scrollPane = new JScrollPane(myDescriptionTextArea); + myDescriptionScroll.getViewport().add(myDescriptionTextArea); + myDescriptionScroll.setBorder(null); + myDescriptionScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + myDescriptionScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + myDescriptionTextArea.setEditable(false); + myDescriptionTextArea.setFont(promptLabel.getFont()); + myDescriptionTextArea.setBackground(myPanel.getBackground()); + myDescriptionTextArea.setLineWrap(true); + updateDescription(); + + myMapComboBox.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + updateDescription(); + } + } + ); + + myEditMapButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + editMap(); + } + } + ); + + myRemoveMapButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + removeMap(); + } + } + ); + + myNewMapButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + addNewMap(); + } + } + ); + + myMapComboBox.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myMapComboBox.isPopupVisible()){ + myMapComboBox.setPopupVisible(false); + } + else{ + clickDefaultButton(); + } + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + + return myPanel; + } + + protected JComponent createNorthPanel() { + return null; + } + + private void updateDescription() { + if (myDescriptionTextArea == null){ + return; + } + MigrationMap map = getMigrationMap(); + if (map == null){ + myDescriptionTextArea.setText(""); + return; + } + myDescriptionTextArea.setText(map.getDescription()); + } + + private void editMap() { + MigrationMap oldMap = getMigrationMap(); + if (oldMap == null){ + return; + } + MigrationMap newMap = oldMap.cloneMap(); + if (editMap(newMap)){ + if (newMap.getName() == null || newMap.getName().length() == 0 || newMap.getEntryCount() == 0){ + String warningString; + if (newMap.getEntryCount() == 0){ + warningString = "Migration map is empty.\n"; + } + else{ + warningString = "Migration map has empty name.\n"; + } + int result = Messages.showYesNoDialog( + warningString + "Do you want to delete it?", "Empty Name", + Messages.getWarningIcon()); + if (result == 0){ + myMigrationMapSet.removeMap(oldMap); + MigrationMap[] maps = myMigrationMapSet.getMaps(); + initMapCombobox(); + if (maps.length > 0){ + myMapComboBox.setSelectedItem(maps[0]); + } + try { + myMigrationMapSet.saveMaps(); + } + catch (IOException e) { + LOG.error("Cannot save migration maps", e); + } + } + return; + } + myMigrationMapSet.replaceMap(oldMap, newMap); + initMapCombobox(); + myMapComboBox.setSelectedItem(newMap); + try { + myMigrationMapSet.saveMaps(); + } + catch (IOException e) { + LOG.error("Cannot save migration maps", e); + } + } + } + + private boolean editMap(MigrationMap map) { + if (map == null) + return false; + EditMigrationDialog dialog = new EditMigrationDialog(myProject, map); + dialog.show(); + if (!dialog.isOK()) + return false; + map.setName(dialog.getName()); + map.setDescription(dialog.getDescription()); + return true; + } + + private void addNewMap() { + MigrationMap migrationMap = new MigrationMap(); + if (editMap(migrationMap)){ + myMigrationMapSet.addMap(migrationMap); + initMapCombobox(); + myMapComboBox.setSelectedItem(migrationMap); + try { + myMigrationMapSet.saveMaps(); + } + catch (IOException e) { + LOG.error("Cannot save migration maps", e); + } + } + } + + private void removeMap() { + MigrationMap map = getMigrationMap(); + if (map == null){ + return; + } + myMigrationMapSet.removeMap(map); + MigrationMap[] maps = myMigrationMapSet.getMaps(); + initMapCombobox(); + if (maps.length > 0){ + myMapComboBox.setSelectedItem(maps[0]); + } + try { + myMigrationMapSet.saveMaps(); + } + catch (IOException e) { + LOG.error("Cannot save migration maps", e); + } + } + + public MigrationMap getMigrationMap() { + return (MigrationMap)myMapComboBox.getSelectedItem(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.MIGRATION); + } + + private void initMapCombobox() { + if (myMapComboBox.getItemCount() > 0){ + myMapComboBox.removeAllItems(); + } + MigrationMap[] maps = myMigrationMapSet.getMaps(); + for(int i = 0; i < maps.length; i++){ + myMapComboBox.addItem(maps[i]); + } + updateDescription(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationManager.java new file mode 100644 index 00000000000..c248f37fb5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationManager.java @@ -0,0 +1,24 @@ +package com.intellij.refactoring.migration; + +import com.intellij.openapi.project.Project; + +public class MigrationManager { + private Project myProject; + private MigrationMapSet myMigrationMapSet = new MigrationMapSet(); + + public MigrationManager(Project project) { + myProject = project; + } + + public void showMigrationDialog() { + final MigrationDialog migrationDialog = new MigrationDialog(myProject, myMigrationMapSet); + migrationDialog.show(); + if (!migrationDialog.isOK()) { + return; + } + MigrationMap migrationMap = migrationDialog.getMigrationMap(); + if (migrationMap == null) return; + + new MigrationProcessor(myProject, migrationMap).run(null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMap.java new file mode 100644 index 00000000000..90b868375b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMap.java @@ -0,0 +1,82 @@ + +package com.intellij.refactoring.migration; + +import java.util.ArrayList; + +/** + * + */ +public class MigrationMap { + private String myName; + private String myDescription; + private ArrayList myEntries = new ArrayList(); + + public MigrationMap() { + + } + + public MigrationMap(MigrationMapEntry[] entries) { + for (int i = 0; i < entries.length; i++) { + MigrationMapEntry entry = entries[i]; + addEntry(entry); + } + } + + public MigrationMap cloneMap() { + MigrationMap newMap = new MigrationMap(); + newMap.myName = myName; + newMap.myDescription = myDescription; + for(int i = 0; i < myEntries.size(); i++){ + MigrationMapEntry entry = getEntryAt(i); + newMap.addEntry(entry.cloneEntry()); + } + return newMap; + } + + public String getName() { + return myName; + } + + public void setName(String name) { + myName = name; + } + + public String getDescription() { + return myDescription; + } + + public void setDescription(String description) { + myDescription = description; + } + + public void addEntry(MigrationMapEntry entry) { + myEntries.add(entry); + } + + public void removeEntryAt(int index) { + myEntries.remove(index); + } + + public void removeAllEntries() { + myEntries.clear(); + } + + public int getEntryCount() { + return myEntries.size(); + } + + public MigrationMapEntry getEntryAt(int index) { + return myEntries.get(index); + } + + public void setEntryAt(MigrationMapEntry entry, int index) { + myEntries.set(index, entry); + } + + public String toString() { + return getName(); + } +} + + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapEntry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapEntry.java new file mode 100644 index 00000000000..f6d6d29974b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapEntry.java @@ -0,0 +1,67 @@ + +package com.intellij.refactoring.migration; + +/** + * + */ +public class MigrationMapEntry implements Cloneable { + private String myOldName; + private String myNewName; + private int myType; + private boolean isRecursive; + + public static final int PACKAGE = 0; + public static final int CLASS = 1; + + public MigrationMapEntry() { + + } + + public MigrationMapEntry(String oldName, String newName, int type, boolean recursive) { + myOldName = oldName; + myNewName = newName; + myType = type; + isRecursive = recursive; + } + + public MigrationMapEntry cloneEntry() { + MigrationMapEntry newEntry = new MigrationMapEntry(); + newEntry.myOldName = myOldName; + newEntry.myNewName = myNewName; + newEntry.myType = myType; + newEntry.isRecursive = isRecursive; + return newEntry; + } + + public String getOldName() { + return myOldName; + } + + public String getNewName() { + return myNewName; + } + + public boolean isRecursive() { + return isRecursive; + } + + public int getType() { + return myType; + } + + public void setOldName(String name) { + myOldName = name; + } + + public void setNewName(String name) { + myNewName = name; + } + + public void setType(int type) { + myType = type; + } + + public void setRecursive(boolean val) { + isRecursive = val; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapSet.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapSet.java new file mode 100644 index 00000000000..95fa2421fc7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationMapSet.java @@ -0,0 +1,284 @@ + +package com.intellij.refactoring.migration; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.UniqueFileNamesProvider; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; + +import java.io.*; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * + */ +public class MigrationMapSet implements ExportableApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.migration.MigrationMapSet"); + + private ArrayList myMaps = null; + private static final String MIGRATION_MAP = "migrationMap"; + private static final String ENTRY = "entry"; + private static final String NAME = "name"; + private static final String OLD_NAME = "oldName"; + private static final String NEW_NAME = "newName"; + private static final String DESCRIPTION = "description"; + private static final String VALUE = "value"; + private static final String TYPE = "type"; + private static final String PACKAGE_TYPE = "package"; + private static final String CLASS_TYPE = "class"; + private static final String RECURSIVE = "recursive"; + + private static final String[] DEFAULT_MAPS = new String[] { + "/com/intellij/refactoring/migration/res/Swing__1_0_3____1_1_.xml", + }; + + public MigrationMapSet() { + } + + public File[] getExportFiles() { + return new File[]{getMapDirectory()}; + } + + public String getPresentableName() { + return "Migration maps"; + } + + public String getComponentName() { + return "MigrationManager"; + } + + public void initComponent() { + + } + + public void disposeComponent() { + + } + + public void addMap(MigrationMap map) { + if (myMaps == null){ + loadMaps(); + } + myMaps.add(map); +// saveMaps(); + } + + public void replaceMap(MigrationMap oldMap, MigrationMap newMap) { + for(int i = 0; i < myMaps.size(); i++){ + if (myMaps.get(i) == oldMap){ + myMaps.set(i, newMap); + } + } + } + + public void removeMap(MigrationMap map) { + if (myMaps == null){ + loadMaps(); + } + myMaps.remove(map); + } + + public MigrationMap[] getMaps() { + if (myMaps == null){ + loadMaps(); + } + MigrationMap[] ret = new MigrationMap[myMaps.size()]; + for(int i = 0; i < myMaps.size(); i++){ + ret[i] = myMaps.get(i); + } + return ret; + } + + private File getMapDirectory() { + String directoryPath = PathManager.getConfigPath() + File.separator + "migration"; + File dir = new File(directoryPath); + + if (!dir.exists()){ + if (!dir.mkdir()){ + LOG.error("cannot create directory: " + dir.getAbsolutePath()); + return null; + } + + for (int i = 0; i < DEFAULT_MAPS.length; i++) { + String defaultTemplate = DEFAULT_MAPS[i]; + java.net.URL url = MigrationMapSet.class.getResource(defaultTemplate); + LOG.assertTrue(url != null); + String fileName = defaultTemplate.substring(defaultTemplate.lastIndexOf("/") + 1); + File targetFile = new File(dir, fileName); + + try { + FileOutputStream outputStream = new FileOutputStream(targetFile); + InputStream inputStream = url.openStream(); + + try { + FileUtil.copy(inputStream, outputStream); + } + finally { + outputStream.close(); + inputStream.close(); + } + } + catch (Exception e) { + LOG.error(e); + } + } + } + + return dir; + } + + private File[] getMapFiles() { + File dir = getMapDirectory(); + if (dir == null){ + return new File[0]; + } + File[] ret = dir.listFiles(new FileFilter() { + public boolean accept(File file){ + return !file.isDirectory() && file.getName().toLowerCase().endsWith(".xml"); + } + }); + if (ret == null){ + LOG.error("cannot read directory: " + dir.getAbsolutePath()); + return new File[0]; + } + return ret; + } + + private void loadMaps() { + myMaps = new ArrayList(); + + File[] files = getMapFiles(); + for(int i = 0; i < files.length; i++){ + try{ + MigrationMap map = readMap(files[i]); + if (map != null){ + myMaps.add(map); + } + } + catch(InvalidDataException e){ + LOG.error("Invalid data in file: " + files[i].getAbsolutePath()); + } + catch (JDOMException e) { + LOG.error("Invalid data in file: " + files[i].getAbsolutePath()); + } + catch (IOException e) { + LOG.error(e); + } + } + } + + private MigrationMap readMap(File file) throws JDOMException, InvalidDataException, IOException { + if (!file.exists()) return null; + Document document = JDOMUtil.loadDocument(file); + + Element root = document.getRootElement(); + if (root == null || !MIGRATION_MAP.equals(root.getName())){ + throw new InvalidDataException(); + } + + MigrationMap map = new MigrationMap(); + + for(Iterator i = root.getChildren().iterator(); i.hasNext(); ){ + Element node = (Element)i.next(); + if (NAME.equals(node.getName())){ + String name = node.getAttributeValue(VALUE); + map.setName(name); + } + if (DESCRIPTION.equals(node.getName())){ + String description = node.getAttributeValue(VALUE); + map.setDescription(description); + } + + if (ENTRY.equals(node.getName())){ + MigrationMapEntry entry = new MigrationMapEntry(); + String oldName = node.getAttributeValue(OLD_NAME); + if (oldName == null){ + throw new InvalidDataException(); + } + entry.setOldName(oldName); + String newName = node.getAttributeValue(NEW_NAME); + if (newName == null){ + throw new InvalidDataException(); + } + entry.setNewName(newName); + String typeStr = node.getAttributeValue(TYPE); + if (typeStr == null){ + throw new InvalidDataException(); + } + entry.setType(MigrationMapEntry.CLASS); + if (typeStr.equals(PACKAGE_TYPE)){ + entry.setType(MigrationMapEntry.PACKAGE); + String isRecursiveStr = node.getAttributeValue(RECURSIVE); + if (isRecursiveStr != null && isRecursiveStr.equals("true")){ + entry.setRecursive(true); + } + else{ + entry.setRecursive(false); + } + } + map.addEntry(entry); + } + } + + return map; + } + + public void saveMaps() throws IOException{ + File dir = getMapDirectory(); + if (dir == null) { + return; + } + + File[] files = getMapFiles(); + + String[] filePaths = new String[myMaps.size()]; + Document[] documents = new Document[myMaps.size()]; + + UniqueFileNamesProvider namesProvider = new UniqueFileNamesProvider(); + for(int i = 0; i < myMaps.size(); i++){ + MigrationMap map = myMaps.get(i); + + filePaths[i] = dir + File.separator + namesProvider.suggestName(map.getName()) + ".xml"; + documents[i] = saveMap(map); + } + + JDOMUtil.updateFileSet(files, filePaths, documents, CodeStyleSettingsManager.getSettings(null).getLineSeparator()); + } + + private Document saveMap(MigrationMap map) { + Element root = new Element(MIGRATION_MAP); + + Element nameElement = new Element(NAME); + nameElement.setAttribute(VALUE, map.getName()); + root.addContent(nameElement); + + Element descriptionElement = new Element(DESCRIPTION); + descriptionElement.setAttribute(VALUE, map.getDescription()); + root.addContent(descriptionElement); + + for(int i = 0; i < map.getEntryCount(); i++){ + MigrationMapEntry entry = map.getEntryAt(i); + Element element = new Element(ENTRY); + element.setAttribute(OLD_NAME, entry.getOldName()); + element.setAttribute(NEW_NAME, entry.getNewName()); + if (entry.getType() == MigrationMapEntry.PACKAGE){ + element.setAttribute(TYPE, PACKAGE_TYPE); + element.setAttribute(RECURSIVE, entry.isRecursive() ? "true" : "false"); + } + else{ + element.setAttribute(TYPE, CLASS_TYPE); + } + root.addContent(element); + } + + return new Document(root); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationProcessor.java new file mode 100644 index 00000000000..a27398a5371 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationProcessor.java @@ -0,0 +1,155 @@ +package com.intellij.refactoring.migration; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiMigration; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; + +import java.util.ArrayList; + +/** + * @author ven + */ +class MigrationProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.migration.MigrationProcessor"); + private final MigrationMap myMigrationMap; + + public MigrationProcessor(Project project, MigrationMap migrationMap) { + super(project); + myMigrationMap = migrationMap; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new MigrationUsagesViewDescriptor(myMigrationMap, false, usages); + } + + private PsiMigration startMigration(final PsiManager psiManager) { + final PsiMigration migration = psiManager.startMigration(); + + final Application application = ApplicationManager.getApplication(); + if (!application.isUnitTestMode()) { + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + LOG.assertTrue(progressIndicator != null); + application.invokeAndWait( + new Runnable() { + public void run() { + findOrCreateEntries(psiManager, migration, application); + } + }, progressIndicator.getModalityState()); + } else { + findOrCreateEntries(psiManager, migration, application); + } + + return migration; + } + + private void findOrCreateEntries(final PsiManager psiManager, final PsiMigration migration, Application application) { + application.runWriteAction( + new Runnable() { + public void run() { + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + if (entry.getType() == MigrationMapEntry.PACKAGE) { + MigrationUtil.findOrCreatePackage(psiManager, migration, + entry.getOldName()); + } + else { + MigrationUtil.findOrCreateClass(psiManager, migration, entry.getOldName()); + } + } + } + }); + } + + protected UsageInfo[] findUsages() { + ArrayList usagesVector = new ArrayList(); + PsiManager psiManager = PsiManager.getInstance(myProject); + PsiMigration psiMigration = startMigration(psiManager); + try { + if (myMigrationMap == null) { + return null; + } + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + UsageInfo[] usages; + if (entry.getType() == MigrationMapEntry.PACKAGE) { + usages = MigrationUtil.findPackageUsages(psiManager, psiMigration, entry.getOldName()); + } + else { + usages = MigrationUtil.findClassUsages(psiManager, psiMigration, entry.getOldName()); + } + + for (int j = 0; j < usages.length; j++) { + usagesVector.add(new MigrationUsageInfo(usages[j], entry)); + } + } + } + finally { + psiMigration.finish(); + } + return usagesVector.toArray(new MigrationUsageInfo[usagesVector.size()]); + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + if (usages[0].length == 0) { + Messages.showInfoMessage(myProject, "No Usages Found in the Project", "Migration"); + return false; + } + return true; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return true; + } + + protected void performRefactoring(UsageInfo[] usages) { + PsiManager psiManager = PsiManager.getInstance(myProject); + final PsiMigration psiMigration = psiManager.startMigration(); + LvcsAction action = LvcsIntegration.checkinFilesBeforeRefactoring(myProject, getCommandName()); + + try { + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + if (entry.getType() == MigrationMapEntry.PACKAGE) { + MigrationUtil.doPackageMigration(psiManager, psiMigration, entry.getNewName(), usages); + } + if (entry.getType() == MigrationMapEntry.CLASS) { + MigrationUtil.doClassMigration(psiManager, psiMigration, entry.getNewName(), usages); + } + } + } + finally { + LvcsIntegration.checkinFilesAfterRefactoring(myProject, action); + psiMigration.finish(); + } + } + + + protected String getCommandName() { + return "Migration"; + } + + public static class MigrationUsageInfo extends UsageInfo { + public MigrationMapEntry mapEntry; + + public MigrationUsageInfo(UsageInfo info, MigrationMapEntry mapEntry) { + super(info.getElement(), info.startOffset, info.endOffset); + this.mapEntry = mapEntry; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUsagesViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUsagesViewDescriptor.java new file mode 100644 index 00000000000..506330e073a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUsagesViewDescriptor.java @@ -0,0 +1,97 @@ +/** + * created at Nov 24, 2001 + * @author Jeka + */ +package com.intellij.refactoring.migration; + +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.HelpID; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class MigrationUsagesViewDescriptor implements UsageViewDescriptor { + private boolean isSearchInComments; + private MigrationMap myMigrationMap; + private UsageInfo[] myUsages; + + public MigrationUsagesViewDescriptor(MigrationMap migrationMap, boolean isSearchInComments, UsageInfo[] usages) { + myMigrationMap = migrationMap; + this.isSearchInComments = isSearchInComments; + myUsages = usages; + } + + public MigrationMap getMigrationMap() { + return myMigrationMap; + } + + public PsiElement[] getElements() { + return PsiElement.EMPTY_ARRAY; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + //No elements => no refresh + } + + public String getProcessedElementsHeader() { + return null; + } + + public boolean isSearchInText() { + return isSearchInComments; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References in code to elements from migration map \"" + myMigrationMap.getName() + "\" " + + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public String getInfo() { + return "Press the \"Do Migrate\" button at the bottom of the search results panel\n" + + "to migrate using the migration map \"" + myMigrationMap.getName() + "\"\n"; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return HelpID.MIGRATION; + } + + public boolean canRefresh() { + return false; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUtil.java new file mode 100644 index 00000000000..f3a4218b5df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/migration/MigrationUtil.java @@ -0,0 +1,112 @@ + +package com.intellij.refactoring.migration; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; + +/** + * + */ +public class MigrationUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.migration.MigrationUtil"); + + private static final Key ROOT = Key.create("ROOT"); + + public static UsageInfo[] findPackageUsages(PsiManager manager, + PsiMigration migration, + String qName) { + PsiPackage aPackage = findOrCreatePackage(manager, migration, qName); + + final ArrayList results = new ArrayList(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + PsiReference[] usages = manager.getSearchHelper().findReferences(aPackage, projectScope, false); + for(int i = 0; i < usages.length; i++){ + results.add(new UsageInfo(usages[i].getElement())); + } + + return results.toArray(new UsageInfo[results.size()]); + } + + public static void doPackageMigration(PsiManager manager, + PsiMigration migration, String newQName, + UsageInfo[] usages) { + try{ + PsiPackage aPackage = findOrCreatePackage(manager, migration, newQName); + + // rename all references + for(int i = 0; i < usages.length; i++){ + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) continue; + if (usage.getElement() instanceof PsiJavaCodeReferenceElement){ + ((PsiJavaCodeReferenceElement)usage.getElement()).bindToElement(aPackage); + } + } + } + catch(IncorrectOperationException e){ + // should not happen! + LOG.error(e); + } + } + + public static UsageInfo[] findClassUsages(PsiManager manager, + PsiMigration migration, + String qName) { + PsiClass aClass = findOrCreateClass(manager, migration, qName); + + final ArrayList results = new ArrayList(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + PsiReference[] usages = manager.getSearchHelper().findReferences(aClass, projectScope, false); + for(int i = 0; i < usages.length; i++){ + results.add(new UsageInfo(usages[i].getElement())); + } + + return results.toArray(new UsageInfo[results.size()]); + } + + public static void doClassMigration(PsiManager manager, + PsiMigration migration, + String newQName, + UsageInfo[] usages) { + try{ + PsiClass aClass = findOrCreateClass(manager, migration, newQName); + + // rename all references + for(int i = 0; i < usages.length; i++){ + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) continue; + if (usage.getElement() instanceof PsiJavaCodeReferenceElement){ + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); + referenceElement.bindToElement(aClass); + } + } + } + catch(IncorrectOperationException e){ + // should not happen! + LOG.error(e); + } + } + + static PsiPackage findOrCreatePackage(PsiManager manager, PsiMigration migration, String qName) { + PsiPackage aPackage = manager.findPackage(qName); + if (aPackage != null){ + return aPackage; + } + else{ + return migration.createPackage(qName); + } + } + + static PsiClass findOrCreateClass(PsiManager manager, PsiMigration migration, String qName) { + PsiClass aClass = manager.findClass(qName); + if (aClass == null){ + aClass = migration.createClass(qName); + } + return aClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveCallback.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveCallback.java new file mode 100644 index 00000000000..ec1dd2762e3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveCallback.java @@ -0,0 +1,9 @@ +/** + * created at Nov 27, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move; + +public interface MoveCallback { + void refactoringCompleted(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveHandler.java new file mode 100644 index 00000000000..e76953d3207 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/MoveHandler.java @@ -0,0 +1,458 @@ +/** + * created at Nov 26, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.*; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler; +import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesImpl; +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil; +import com.intellij.refactoring.move.moveInner.MoveInnerImpl; +import com.intellij.refactoring.move.moveMembers.MoveMembersImpl; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.util.containers.HashSet; + +import javax.swing.*; +import java.awt.*; + +public class MoveHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.MoveHandler"); + + public static final int NOT_SUPPORTED = 0; + public static final int CLASSES = 1; + public static final int PACKAGES = 2; + public static final int MEMBERS = 3; + public static final int INNER_TO_UPPER = 4; + public static final int INNER_TO_UPPER_OR_MEMBERS = 5; + public static final int FILES = 6; + public static final int DIRECTORIES = 7; + public static final int MOVE_OR_REARRANGE_PACKAGE = 8; + + + public static interface TargetContainerFinder { + PsiElement getTargetContainer(DataContext dataContext); + } + + TargetContainerFinder myTargetContainerFinder; + + public MoveHandler(TargetContainerFinder finder) { + myTargetContainerFinder = finder; + } + + /** + * called by an Action in AtomicAction when refactoring is invoked from Editor + */ + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + while(true){ + + if (element == null) { + if (!(file instanceof PsiJavaFile)) { + PsiElement[] elements = new PsiElement[]{file}; + if (MoveFilesOrDirectoriesUtil.canMoveFiles(elements)) { + doMove(project, elements, null, null); + } + return; + } + + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned at the class, method or field to be refactored."; + RefactoringMessageUtil.showErrorMessage("Move", message, null, project); + return; + } + if (element instanceof PsiField) { + MoveMembersImpl.doMove(project, new PsiElement[] {element}, null, null); + return; + } + if (element instanceof PsiMethod) { + MoveMembersImpl.doMove(project, new PsiElement[] {element}, null, null); + return; + } + if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass)element; + if (aClass.getContainingClass() != null) { // this is inner class + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.move.moveInner"); + if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { + MoveInnerImpl.doMove(project, new PsiElement[] {aClass}, null); + } + else { + SelectInnerOrMembersRefactoringDialog dialog = new SelectInnerOrMembersRefactoringDialog(aClass, project); + dialog.show(); + if (dialog.isOK()) { + int type = dialog.getRefactoringType(); + if (type == INNER_TO_UPPER) { + MoveInnerImpl.doMove(project, new PsiElement[] {aClass}, null); + } + else if (type == MEMBERS){ + MoveMembersImpl.doMove(project, new PsiElement[] {aClass}, null, null); + } + } + } + return; + } + if (!(element instanceof PsiAnonymousClass)) { + MoveClassesOrPackagesImpl.doMove(project, new PsiElement[] {aClass}, myTargetContainerFinder.getTargetContainer(dataContext), null); + } else { + new AnonymousToInnerHandler().invoke(project, (PsiAnonymousClass) element); + } + + return; + } + element = element.getParent(); + } + } + /** + * called by an Action in AtomicAction + */ + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + doMove(project, elements, dataContext != null ? myTargetContainerFinder.getTargetContainer(dataContext) : null, null); + } + + /** + * must be invoked in AtomicAction + */ + public static void doMove(Project project, PsiElement[] elements, PsiElement targetContainer, MoveCallback callback) { + if (elements == null) { + throw new IllegalArgumentException("elements cannot be null"); + } + if (elements.length == 0) return; + + int moveType = getMoveType(elements); + if (moveType == CLASSES || moveType == PACKAGES) { + MoveClassesOrPackagesImpl.doMove(project, elements, targetContainer, callback); + } + else if (moveType == FILES || moveType == DIRECTORIES) { + if (!LOG.assertTrue(targetContainer == null || (targetContainer instanceof PsiDirectory))) { + return; + } + MoveFilesOrDirectoriesUtil.doMove(project, elements, (PsiDirectory)targetContainer, callback); + } + else if (moveType == MEMBERS) { + MoveMembersImpl.doMove(project, elements, targetContainer, callback); + } + else if (moveType == INNER_TO_UPPER) { + MoveInnerImpl.doMove(project, elements, callback); + } + else if (moveType == INNER_TO_UPPER_OR_MEMBERS) { + SelectInnerOrMembersRefactoringDialog dialog = new SelectInnerOrMembersRefactoringDialog((PsiClass)elements[0], project); + dialog.show(); + if (!dialog.isOK()) { + return; + } + moveType = dialog.getRefactoringType(); + if (moveType == INNER_TO_UPPER) { + MoveInnerImpl.doMove(project, elements, callback); + } + else if (moveType == MEMBERS) { + MoveMembersImpl.doMove(project, elements, targetContainer, callback); + } + } + else if (moveType == MOVE_OR_REARRANGE_PACKAGE) { + PsiDirectory[] directories = convertToDirectories(moveType, elements); + SelectMoveOrRearrangePackageDialog dialog = new SelectMoveOrRearrangePackageDialog(project, directories); + dialog.show(); + if (!dialog.isOK()) return; + moveType = dialog.getRefactoringType(); + if (moveType == PACKAGES) { + MoveClassesOrPackagesImpl.doMove(project, elements, targetContainer, callback); + } else { + MoveClassesOrPackagesImpl.doRearrangePackage(project, directories); + } + } + } + + private static PsiDirectory[] convertToDirectories(int moveType, PsiElement[] elements) { + LOG.assertTrue(moveType == MOVE_OR_REARRANGE_PACKAGE); + PsiDirectory[] directories = new PsiDirectory[elements.length]; + for (int i = 0; i < directories.length; i++) { + directories[i] = (PsiDirectory)elements[i]; + } + return directories; + } + + /** + * Must be invoked in AtomicAction + * target container can be null => means that container is not determined yet and must be spacify by the user + */ + public static boolean canMove(PsiElement[] elements, PsiElement targetContainer) { + if (elements == null) { + throw new IllegalArgumentException("elements cannot be null"); + } + int moveType = getMoveType(elements); + if (moveType == NOT_SUPPORTED) { + return false; + } + if (targetContainer == null) { + return true; + } + if (moveType == INNER_TO_UPPER) { + return targetContainer.equals(MoveInnerImpl.getTargetContainer((PsiClass)elements[0])); + } + else if (moveType == MEMBERS) { + return (targetContainer instanceof PsiClass) && !(targetContainer instanceof PsiAnonymousClass); + } + else if (moveType == CLASSES || moveType == PACKAGES) { + if (targetContainer instanceof PsiPackage) { + return true; + } + if (targetContainer instanceof PsiDirectory) { + return ((PsiDirectory)targetContainer).getPackage() != null; + } + return false; + } + else if (moveType == FILES || moveType == DIRECTORIES) { + if (targetContainer instanceof PsiDirectory) { + return true; + } + return false; + } + else { + return false; + } + } + + /** + * Must be invoked in AtomicAction + */ + public static int getMoveType(PsiElement[] elements) { + if (elements == null) { + throw new IllegalArgumentException("elements cannot be null"); + } + if (MoveFilesOrDirectoriesUtil.canMoveFiles(elements)) { + return FILES; + } + if (MoveFilesOrDirectoriesUtil.canMoveDirectories(elements)) { + return DIRECTORIES; + } + + if (MoveFilesOrDirectoriesUtil.canMoveOrRearrangePackages(elements)) { + return MOVE_OR_REARRANGE_PACKAGE; + } + + if (elements.length == 1) { + PsiElement element = elements[0]; + if (element instanceof PsiPackage) { + return PACKAGES; + } + if (element instanceof PsiDirectory) { + PsiDirectory directory = (PsiDirectory)element; + return directory.getPackage() != null ? PACKAGES : NOT_SUPPORTED; + } + else if (element instanceof PsiField || element instanceof PsiMethod) { + return MEMBERS; + } + else if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass)element; + if (aClass.getParent() instanceof PsiFile) { // top-level class + return CLASSES; + } + else if (aClass.getParent() instanceof PsiClass) { // is inner class + if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { + return INNER_TO_UPPER; + } + return INNER_TO_UPPER_OR_MEMBERS; + } + } + return NOT_SUPPORTED; + } + // the case of multiple members + // check if this is move packages + int type = PACKAGES; + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (element instanceof PsiPackage) { + continue; + } + if (!(element instanceof PsiDirectory)) { + type = NOT_SUPPORTED; + break; + } + PsiDirectory directory = (PsiDirectory)element; + if (directory.getPackage() == null) { + type = NOT_SUPPORTED; + break; + } + } + if (type != NOT_SUPPORTED) return type; + // check if this is move classes + type = CLASSES; + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!(element instanceof PsiClass)) { + type = NOT_SUPPORTED; + break; + } + if (!(element.getParent() instanceof PsiFile)) { + type = NOT_SUPPORTED; + break; + } + } + if (type != NOT_SUPPORTED) return type; + // check if this is move members + type = MEMBERS; + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (element instanceof PsiClass) { + if (!(element.getParent() instanceof PsiClass)) { // is not inner + type = NOT_SUPPORTED; + break; + } + } + else if (!(element instanceof PsiField || element instanceof PsiMethod)) { + type = NOT_SUPPORTED; + break; + } + } + return type; + } + + private static class SelectMoveOrRearrangePackageDialog extends DialogWrapper{ + private JRadioButton myRbMovePackage; + private JRadioButton myRbRearrangePackage; + private final PsiDirectory[] myDirectories; + + public SelectMoveOrRearrangePackageDialog(Project project, PsiDirectory[] directories) { + super(project, true); + myDirectories = directories; + setTitle("Select Refactoring"); + init(); + } + + protected JComponent createNorthPanel() { + return new JLabel("What would you like to do?"); + } + + public JComponent getPreferredFocusedComponent() { + return myRbMovePackage; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.move.MoveHandler.SelectRefactoringDialog"; + } + + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + + final HashSet packages = new HashSet(); + for (int i = 0; i < myDirectories.length; i++) { + PsiDirectory directory = myDirectories[i]; + packages.add(directory.getPackage().getQualifiedName()); + } + final String moveDescription; + LOG.assertTrue(myDirectories.length > 0); + LOG.assertTrue(packages.size() > 0); + if (packages.size() > 1) { + moveDescription = "Move " + packages.size() + " packages to another package"; + } + else { + final String qName = packages.iterator().next(); + moveDescription = "Move package '" + qName + "' to another package"; + } + + myRbMovePackage = new JRadioButton(moveDescription, true); + + final String rearrangeDescription; + if (myDirectories.length > 1) { + rearrangeDescription = "Move " + myDirectories.length + " directories to another source root"; + } + else { + rearrangeDescription = "Move directory " + myDirectories[0].getVirtualFile().getPresentableUrl() + " to another source root"; + } + myRbRearrangePackage = new JRadioButton(rearrangeDescription); + + + myRbMovePackage.setMnemonic('p'); + myRbRearrangePackage.setMnemonic('r'); + ButtonGroup gr = new ButtonGroup(); + gr.add(myRbMovePackage); + gr.add(myRbRearrangePackage); + + Box box = Box.createVerticalBox(); + box.add(Box.createVerticalStrut(5)); + box.add(myRbMovePackage); + box.add(myRbRearrangePackage); + panel.add(box, BorderLayout.CENTER); + return panel; + } + + public int getRefactoringType() { + if (myRbMovePackage.isSelected()) { + return MoveHandler.PACKAGES; + } + if (myRbRearrangePackage.isSelected()) { + return MoveHandler.MOVE_OR_REARRANGE_PACKAGE; + } + return MoveHandler.NOT_SUPPORTED; + } + } + + private static class SelectInnerOrMembersRefactoringDialog extends DialogWrapper{ + private JRadioButton myRbMoveInner; + private JRadioButton myRbMoveMembers; + private String myClassName; + + public SelectInnerOrMembersRefactoringDialog(final PsiClass innerClass, Project project) { + super(project, true); + setTitle("Select Refactoring"); + myClassName = innerClass.getName(); + init(); + } + + protected JComponent createNorthPanel() { + return new JLabel("What would you like to do?"); + } + + public JComponent getPreferredFocusedComponent() { + return myRbMoveInner; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.move.MoveHandler.SelectRefactoringDialog"; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myRbMoveInner = new JRadioButton("Move inner class "+myClassName+" to upper level", true); + myRbMoveMembers = new JRadioButton("Move inner class " + myClassName + " to another class"); + + + myRbMoveInner.setMnemonic('i'); + myRbMoveMembers.setMnemonic('M'); + ButtonGroup gr = new ButtonGroup(); + gr.add(myRbMoveInner); + gr.add(myRbMoveMembers); + + Box box = Box.createVerticalBox(); + box.add(Box.createVerticalStrut(5)); + box.add(myRbMoveInner); + box.add(myRbMoveMembers); + panel.add(box, BorderLayout.CENTER); + return panel; + } + + public int getRefactoringType() { + if (myRbMoveInner.isSelected()) { + return MoveHandler.INNER_TO_UPPER; + } + if (myRbMoveMembers.isSelected()) { + return MoveHandler.MEMBERS; + } + return MoveHandler.NOT_SUPPORTED; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingMoveDestination.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingMoveDestination.java new file mode 100644 index 00000000000..4491ed06137 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingMoveDestination.java @@ -0,0 +1,43 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public abstract class AutocreatingMoveDestination implements MoveDestination { + protected final PackageWrapper myPackage; + protected final PsiManager myManager; + protected final ProjectFileIndex myFileIndex; + + public AutocreatingMoveDestination(PackageWrapper targetPackage) { + myPackage = targetPackage; + myManager = myPackage.getManager(); + myFileIndex = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex(); + } + + public abstract PackageWrapper getTargetPackage(); + + public abstract PsiDirectory getTargetDirectory(PsiDirectory source) throws IncorrectOperationException; + + public abstract PsiDirectory getTargetDirectory(PsiFile source) throws IncorrectOperationException; + + protected String checkCanCreateInSourceRoot(final VirtualFile targetSourceRoot) { + final String targetQName = myPackage.getQualifiedName(); + final String sourceRootPackage = myFileIndex.getPackageNameByDirectory(targetSourceRoot); + if (!targetQName.startsWith(sourceRootPackage)) { + String message = "Source folder " + targetSourceRoot.getPresentableUrl() + " has package prefix '" + sourceRootPackage + "'\n" + + "Package '" + targetQName + "' cannot be created there."; + return message; + } + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java new file mode 100644 index 00000000000..7007ec633cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java @@ -0,0 +1,72 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author dsl + */ +public class AutocreatingSingleSourceRootMoveDestination extends AutocreatingMoveDestination { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination"); + private final VirtualFile mySourceRoot; + + public AutocreatingSingleSourceRootMoveDestination(PackageWrapper targetPackage, VirtualFile sourceRoot) { + super(targetPackage); + mySourceRoot = sourceRoot; + } + + public PackageWrapper getTargetPackage() { + return myPackage; + } + + public PsiDirectory getTargetIfExists(PsiDirectory source) { + return RefactoringUtil.findPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + } + + public PsiDirectory getTargetIfExists(PsiFile source) { + return RefactoringUtil.findPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + } + + public PsiDirectory getTargetDirectory(PsiDirectory source) throws IncorrectOperationException { + return getDirectory(); + } + + public PsiDirectory getTargetDirectory(PsiFile source) throws IncorrectOperationException { + return getDirectory(); + } + + public String verify(PsiFile source) { + return checkCanCreateInSourceRoot(mySourceRoot); + } + + public String verify(PsiDirectory source) { + return checkCanCreateInSourceRoot(mySourceRoot); + } + + public String verify(PsiPackage aPackage) { + return checkCanCreateInSourceRoot(mySourceRoot); + } + + public void analyzeModuleConflicts(final Collection elements, + ArrayList conflicts) { + RefactoringUtil.analyzeModuleConflicts(getTargetPackage().getManager().getProject(), elements, mySourceRoot, conflicts); + } + + PsiDirectory myTargetDirectory = null; + private PsiDirectory getDirectory() throws IncorrectOperationException { + if (myTargetDirectory == null) { + myTargetDirectory = RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + } + return RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java new file mode 100644 index 00000000000..8158507cdb2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java @@ -0,0 +1,345 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.ide.util.DirectoryChooser; +import com.intellij.ide.util.DirectoryChooserModuleTreeView; +import com.intellij.ide.util.PackageChooserDialog; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class MoveClassesOrPackagesDialog extends RefactoringDialog { + public static interface Callback { + void run(MoveClassesOrPackagesDialog dialog); + } + + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesDialog"); + + + private final JLabel myNameLabel; + private final JLabel myPromptTo; + private final TextFieldWithBrowseButton myTextFieldWithBrowseButton; + private JCheckBox myCbSearchInComments; + private JCheckBox myCbSearchInNonJavaFiles; + private JCheckBox myCbPreserveSourceFolders; + private String myHelpID; + private Project myProject; + private final Callback myCallback; + private boolean mySearchInNonJavaEnabled; + private PsiDirectory myInitialTargetDirectory; + private final PsiManager myManager; + private MoveDestination myMoveDestination; + private boolean myTargetDirectoryFixed; + + + public MoveClassesOrPackagesDialog(Project project, Callback callback, boolean searchInNonJavaEnabled) { + super(project, true); + setTitle("Move"); + myProject = project; + myCallback = callback; + mySearchInNonJavaEnabled = searchInNonJavaEnabled; + + myNameLabel = new JLabel(); + myPromptTo = new JLabel("To package: "); + myTextFieldWithBrowseButton = new TextFieldWithBrowseButton(); + + init(); + myManager = PsiManager.getInstance(myProject); + } + + public JComponent getPreferredFocusedComponent() { + return myTextFieldWithBrowseButton.getTextField(); + } + + protected JComponent createCenterPanel() { + return null; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + panel.setBorder(IdeBorderFactory.createBorder()); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + panel.add(myNameLabel, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.anchor = GridBagConstraints.CENTER; + myTextFieldWithBrowseButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + PackageChooserDialog chooser = new PackageChooserDialog("Choose Destination Package", myProject); + chooser.selectPackage(myTextFieldWithBrowseButton.getText()); + chooser.show(); + PsiPackage aPackage = chooser.getSelectedPackage(); + if (aPackage != null) { + myTextFieldWithBrowseButton.setText(aPackage.getQualifiedName()); + validateOKButton(); + } + } + } + ); + JPanel _panel = new JPanel(new BorderLayout(4, 0)); + _panel.add(myPromptTo, BorderLayout.WEST); + _panel.add(myTextFieldWithBrowseButton, BorderLayout.CENTER); + panel.add(_panel, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbSearchInComments = + new NonFocusableCheckBox("Search in comments and strings"); + myCbSearchInComments.setMnemonic('S'); + panel.add(myCbSearchInComments, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbSearchInNonJavaFiles = + new NonFocusableCheckBox("Search in non-java files"); + myCbSearchInNonJavaFiles.setMnemonic('e'); + panel.add(myCbSearchInNonJavaFiles, gbConstraints); + + + if (!mySearchInNonJavaEnabled) { + myCbSearchInNonJavaFiles.setEnabled(false); + myCbSearchInNonJavaFiles.setVisible(false); + myCbSearchInNonJavaFiles.setSelected(false); + } + + gbConstraints.gridx = 0; + //gbConstraints.gridy = 1; + gbConstraints.gridwidth = 2; + myCbPreserveSourceFolders = + new NonFocusableCheckBox("Preserve source folders"); + myCbPreserveSourceFolders.setMnemonic('r'); + panel.add(myCbPreserveSourceFolders, gbConstraints); + + + myTextFieldWithBrowseButton.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + validateOKButton(); + } + }); + + return panel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesDialog"; + } + + public void setData(PsiElement[] psiElements, + String targetPackageName, + PsiDirectory initialTargetDirectory, + boolean isTargetDirectoryFixed, + boolean searchInComments, + boolean searchInNonJavaFiles, + String helpID) { + myInitialTargetDirectory = initialTargetDirectory; + myTargetDirectoryFixed = isTargetDirectoryFixed; + if (psiElements.length == 1) { + PsiElement firstElement = psiElements[0]; + PsiElement parent = firstElement.getParent(); + LOG.assertTrue(parent != null); + String parentLongName = UsageViewUtil.getLongName(parent); + String text = "Move " + UsageViewUtil.getType(firstElement) + " "; + if (!"".equals(parentLongName)) { + text += UsageViewUtil.getShortName(firstElement) + " from " + parentLongName; + } + else { + text += UsageViewUtil.getLongName(firstElement); + } + myNameLabel.setText(text); + } + else if (psiElements.length > 1) { + myNameLabel.setText((psiElements[0] instanceof PsiClass) ? "Move specified classes" : "Move specified packages"); + } + myTextFieldWithBrowseButton.setText(targetPackageName); + //myTextFieldWithBrowseButton.setEnabled(!myTargetDirectoryFixed); + + myCbSearchInComments.setSelected(searchInComments); + myCbSearchInNonJavaFiles.setSelected(searchInNonJavaFiles); + + if (getSourceRoots().length == 1) { + myCbPreserveSourceFolders.setSelected(true); + myCbPreserveSourceFolders.setEnabled(false); + } + else { + myCbPreserveSourceFolders.setSelected(!myTargetDirectoryFixed); + //myCbPreserveSourceFolders.setEnabled(!myTargetDirectoryFixed); + } + + validateOKButton(); + myHelpID = helpID; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpID); + } + + public boolean isSearchInComments() { + return myCbSearchInComments.isSelected(); + } + + private void validateOKButton() { + String name = myTextFieldWithBrowseButton.getText(); + if (name.length() == 0) { + setOKActionEnabled(true); + } + else { + PsiManager manager = myManager; + setOKActionEnabled(manager.getNameHelper().isQualifiedName(name.trim())); + } + } + + public MoveDestination getMoveDestination() { + return myMoveDestination; + } + + + protected void doAction() { + myMoveDestination = selectDestination(); + if (myMoveDestination == null) return; + RefactoringSettings.getInstance().MOVE_PREVIEW_USAGES = isPreviewUsages(); + myCallback.run(this); + } + + public boolean isSearchInNonJavaFiles() { + return myCbSearchInNonJavaFiles.isSelected(); + } + + private MoveDestination selectDestination() { + final String packageName = myTextFieldWithBrowseButton.getText(); + PackageWrapper targetPackage = new PackageWrapper(myManager, packageName); + if (!targetPackage.exists()) { + final int ret = Messages.showYesNoDialog(myProject, "Package " + packageName + " does not exist.\n" + + "Do you want to create it?", "Move", Messages.getQuestionIcon()); + if (ret != 0) return null; + } + + if (myCbPreserveSourceFolders.isSelected()) { + return new MultipleRootsMoveDestination(targetPackage); + } + + /* + if (myTargetDirectoryFixed) { + final VirtualFile sourceRootForFile = ProjectRootManager.getInstance(myProject).getFileIndex().getSourceRootForFile(myInitialTargetDirectory.getVirtualFile()); + if(sourceRootForFile != null) { + return new AutocreatingSingleSourceRootMoveDestination(targetPackage, sourceRootForFile); + } + } + */ + + final VirtualFile[] contentSourceRoots = getSourceRoots(); + if (contentSourceRoots.length == 1) { + return new AutocreatingSingleSourceRootMoveDestination(targetPackage, contentSourceRoots[0]); + } + List targetDirectories = new ArrayList(); + Map relativePathsToCreate = new HashMap(); + buildDirectoryList(targetPackage, contentSourceRoots, targetDirectories, relativePathsToCreate); + final DirectoryChooser chooser = new DirectoryChooser(myProject, new DirectoryChooserModuleTreeView(myProject)); + chooser.setTitle("Choose Destination Directory"); + chooser.fillList( + targetDirectories.toArray(new PsiDirectory[targetDirectories.size()]), + myInitialTargetDirectory, + myProject, + relativePathsToCreate + ); + chooser.show(); + if (!chooser.isOK()) return null; + final PsiDirectory selectedDirectory = chooser.getSelectedDirectory(); + final VirtualFile virt = selectedDirectory.getVirtualFile(); + final VirtualFile sourceRootForFile = ProjectRootManager.getInstance(myProject).getFileIndex().getSourceRootForFile(virt); + LOG.assertTrue(sourceRootForFile != null); + return new AutocreatingSingleSourceRootMoveDestination(targetPackage, sourceRootForFile); + } + + private VirtualFile[] getSourceRoots() { + return ProjectRootManager.getInstance(myProject).getContentSourceRoots(); + } + + private void buildDirectoryList(PackageWrapper aPackage, + VirtualFile[] contentSourceRoots, + List targetDirectories, + Map relativePathsToCreate) { + + sourceRoots: + for (int i = 0; i < contentSourceRoots.length; i++) { + VirtualFile root = contentSourceRoots[i]; + + final PsiDirectory[] directories = aPackage.getDirectories(); + for (int j = 0; j < directories.length; j++) { + PsiDirectory directory = directories[j]; + if (VfsUtil.isAncestor(root, directory.getVirtualFile(), false)) { + targetDirectories.add(directory); + continue sourceRoots; + } + } + String qNameToCreate; + try { + qNameToCreate = RefactoringUtil.qNameToCreateInSourceRoot(aPackage, root); + } + catch (IncorrectOperationException e) { + continue sourceRoots; + } + PsiDirectory currentDirectory = myManager.findDirectory(root); + if (currentDirectory == null) continue; + final String[] shortNames = qNameToCreate.split("\\."); + for (int j = 0; j < shortNames.length; j++) { + String shortName = shortNames[j]; + final PsiDirectory subdirectory = currentDirectory.findSubdirectory(shortName); + if (subdirectory == null) { + targetDirectories.add(currentDirectory); + final StringBuffer postfix = new StringBuffer(); + for (int k = j; k < shortNames.length; k++) { + String name = shortNames[k]; + postfix.append(File.separatorChar); + postfix.append(name); + } + relativePathsToCreate.put(currentDirectory, postfix.toString()); + continue sourceRoots; + } else { + currentDirectory = subdirectory; + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java new file mode 100644 index 00000000000..cf4c2eb9936 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java @@ -0,0 +1,436 @@ +/** + * created at Nov 27, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.ide.util.DirectoryChooser; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.localVcs.LvcsAction; +import com.intellij.openapi.localVcs.impl.LvcsIntegration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; + + +public class MoveClassesOrPackagesImpl { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesImpl"); + + public static void doMove(final Project project, + PsiElement[] elements, + PsiElement initialTargetElement, + final MoveCallback moveCallback) { + final PsiElement[] psiElements = new PsiElement[elements.length]; + List readOnly = new ArrayList(); + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (element instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)element).getPackage(); + LOG.assertTrue(aPackage != null); + if (aPackage.getQualifiedName().length() == 0) { //is default package + String message = "Move Package refactoring cannot be applied to default package"; + RefactoringMessageUtil.showErrorMessage("Move", message, HelpID.getMoveHelpID(element), project); + return; + } + element = checkMovePackage(project, aPackage, readOnly); + if (element == null) return; + } + else if (element instanceof PsiPackage) { + element = checkMovePackage(project, (PsiPackage) element, readOnly); + if (element == null) return; + } + else if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass)element; + if (aClass instanceof PsiAnonymousClass) { + String message = "Move Class refactoring cannot be applied to anonymous classes"; + RefactoringMessageUtil.showErrorMessage("Move", message, HelpID.getMoveHelpID(element), project); + return; + } + boolean condition = aClass.getParent() instanceof PsiFile; + if (!condition) { + String message = + "Cannot perform the refactoring.\n" + + "Moving local classes is not supported."; + RefactoringMessageUtil.showErrorMessage("Move", message, HelpID.getMoveHelpID(element), project); + return; + } + if (!aClass.isWritable()) { + readOnly.add(aClass.getContainingFile().getVirtualFile()); + } + } + psiElements[idx] = element; + } + + if (!readOnly.isEmpty()) { + Messages.showErrorDialog(project, "Cannot perform refactorings.\n Some files or directories are read only.", "Move"); + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + (VirtualFile[])readOnly.toArray(new VirtualFile[readOnly.size()])); + return; + } + + final String initialTargetPackageName = getInitialTargetPackageName(initialTargetElement, psiElements); + final PsiDirectory initialTargetDirectory = getInitialTargetDirectory(initialTargetElement, psiElements); + final boolean isTargetDirectoryFixed = getContainerDirectory(initialTargetElement) != null; + + final MoveClassesOrPackagesDialog.Callback doRun = new MoveClassesOrPackagesDialog.Callback() { + public void run(final MoveClassesOrPackagesDialog moveDialog) { + final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance(); + final boolean searchInComments = moveDialog.isSearchInComments(); + final boolean searchInNonJavaFiles = moveDialog.isSearchInNonJavaFiles(); + refactoringSettings.MOVE_SEARCH_IN_COMMENTS = searchInComments; + refactoringSettings.MOVE_SEARCH_IN_NONJAVA_FILES = searchInNonJavaFiles; + + final MoveDestination moveDestination = moveDialog.getMoveDestination(); + + PsiManager manager = PsiManager.getInstance(project); + for (int i = 0; i < psiElements.length; i++) { + final PsiElement element = psiElements[i]; + String message = verifyDestinationForElement(element, moveDestination); + if (message != null) { + String helpId = HelpID.getMoveHelpID(psiElements[0]); + RefactoringMessageUtil.showErrorMessage("Error", message, helpId, project); + return; + } + } + try { + for (int idx = 0; idx < psiElements.length; idx++) { + PsiElement psiElement = psiElements[idx]; + if (psiElement instanceof PsiClass) { + final PsiDirectory targetDirectory = moveDestination.getTargetIfExists(psiElement.getContainingFile()); + if (targetDirectory != null) { + manager.checkMove(psiElement, targetDirectory); + } + } + } + + new MoveClassesOrPackagesProcessor( + project, + psiElements, + moveDestination, searchInComments, + searchInNonJavaFiles, + moveDialog.isPreviewUsages(), + moveCallback, + new Runnable() { + public void run() { + moveDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }).run(null); + } + catch (IncorrectOperationException e) { + String helpId = HelpID.getMoveHelpID(psiElements[0]); + RefactoringMessageUtil.showErrorMessage("Error", e.getMessage(), helpId, project); + return; + } + } + }; + + + boolean searchInNonJavaEnabled = false; + for (int i = 0; i < psiElements.length && !searchInNonJavaEnabled; i++) { + PsiElement psiElement = psiElements[i]; + searchInNonJavaEnabled = RefactoringUtil.isSearchInNonJavaEnabled(psiElement); + } + final MoveClassesOrPackagesDialog moveDialog = new MoveClassesOrPackagesDialog(project, doRun, + searchInNonJavaEnabled); + boolean searchInComments = RefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS; + boolean searchInNonJavaFiles = RefactoringSettings.getInstance().MOVE_SEARCH_IN_NONJAVA_FILES; + moveDialog.setData( + psiElements, + initialTargetPackageName, + initialTargetDirectory, + isTargetDirectoryFixed, searchInComments, + searchInNonJavaFiles, + HelpID.getMoveHelpID(psiElements[0]) + ); + moveDialog.show(); + } + + private static String verifyDestinationForElement(final PsiElement element, final MoveDestination moveDestination) { + final String message; + if (element instanceof PsiDirectory) { + message = moveDestination.verify((PsiDirectory) element); + } + else if (element instanceof PsiPackage) { + message = moveDestination.verify((PsiPackage) element); + } + else { + message = moveDestination.verify(element.getContainingFile()); + } + return message; + } + + private static PsiElement checkMovePackage(Project project, PsiPackage aPackage, List readOnly) { + PsiElement element; + final PsiDirectory[] directories = aPackage.getDirectories(); + final VirtualFile[] virtualFiles = aPackage.occursInPackagePrefixes(); + if (directories.length > 1 || virtualFiles.length > 0) { + final StringBuffer message = new StringBuffer(); + RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, aPackage.getQualifiedName()); + if (directories.length > 1) { + RenameUtil.buildMultipleDirectoriesInPackageMessage(message, aPackage, directories); + message.append("\n\nAll these directories will be moved and all references to \n"); + message.append(aPackage.getQualifiedName()); + message.append("\nwill be changed."); + } + message.append("\nDo you wish to continue?"); + int ret = Messages.showYesNoDialog(project, message.toString(), "Warning", Messages.getWarningIcon()); + if (ret != 0) { + return null; + } + } + checkMove(aPackage, readOnly); + element = aPackage; + return element; + } + + private static String getInitialTargetPackageName(PsiElement initialTargetElement, final PsiElement[] movedElements) { + String name = getContainerPackageName(initialTargetElement); + if (name == null) { + if (movedElements != null) { + name = getTargetPackageNameForMovedElement(movedElements[0]); + } + if (name == null) { + final PsiDirectory commonDirectory = getCommonDirectory(movedElements); + if (commonDirectory != null && commonDirectory.getPackage() != null) { + name = commonDirectory.getPackage().getQualifiedName(); + } + } + } + if (name == null) { + name = ""; + } + return name; + } + + private static PsiDirectory getCommonDirectory(PsiElement[] movedElements) { + PsiDirectory commonDirectory = null; + + for (int i = 0; i < movedElements.length; i++) { + PsiElement movedElement = movedElements[i]; + final PsiFile containingFile = movedElement.getContainingFile(); + if (containingFile != null) { + final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + if (containingDirectory != null) { + if (commonDirectory == null) { + commonDirectory = containingDirectory; + } + else { + if (commonDirectory != containingDirectory) { + return null; + } + } + } + } + } + if (commonDirectory != null) { + return commonDirectory; + } + else { + return null; + } + } + + private static String getContainerPackageName(final PsiElement psiElement) { + if (psiElement instanceof PsiPackage) { + return ((PsiPackage)psiElement).getQualifiedName(); + } + else if (psiElement instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)psiElement).getPackage(); + return (aPackage != null) ? aPackage.getQualifiedName() : ""; + } + else if (psiElement != null) { + PsiPackage aPackage = psiElement.getContainingFile().getContainingDirectory().getPackage(); + return (aPackage != null) ? aPackage.getQualifiedName() : ""; + } + else { + return null; + } + } + + private static String getTargetPackageNameForMovedElement(final PsiElement psiElement) { + if (psiElement instanceof PsiPackage) { + final PsiPackage psiPackage = ((PsiPackage)psiElement); + final PsiPackage parentPackage = psiPackage.getParentPackage(); + return parentPackage != null ? parentPackage.getQualifiedName() : ""; + } + else if (psiElement instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)psiElement).getPackage(); + return (aPackage != null) ? getTargetPackageNameForMovedElement(aPackage) : ""; + } + else if (psiElement != null) { + PsiPackage aPackage = psiElement.getContainingFile().getContainingDirectory().getPackage(); + return (aPackage != null) ? aPackage.getQualifiedName() : ""; + } + else { + return null; + } + } + + + private static PsiDirectory getInitialTargetDirectory(PsiElement initialTargetElement, + final PsiElement[] movedElements) { + PsiDirectory initialTargetDirectory = getContainerDirectory(initialTargetElement); + if (initialTargetDirectory == null) { + if (movedElements != null) { + final PsiDirectory commonDirectory = getCommonDirectory(movedElements); + if (commonDirectory != null) { + initialTargetDirectory = commonDirectory; + } + else { + initialTargetDirectory = getContainerDirectory(movedElements[0]); + } + } + } + return initialTargetDirectory; + } + + private static void checkMove(PsiElement elementToMove, List readOnly) { + if (elementToMove instanceof PsiPackage) { + final PsiDirectory[] directories = ((PsiPackage)elementToMove).getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + checkMove(directory, readOnly); + } + } else if (elementToMove instanceof PsiDirectory) { + final PsiFile[] files = ((PsiDirectory)elementToMove).getFiles(); + if (!elementToMove.isWritable()) { + readOnly.add(((PsiDirectory)elementToMove).getVirtualFile()); + return; + } + for (int i = 0; i < files.length; i++) { + PsiFile file = files[i]; + checkMove(file, readOnly); + } + final PsiDirectory[] subdirectories = ((PsiDirectory)elementToMove).getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + PsiDirectory subdirectory = subdirectories[i]; + checkMove(subdirectory, readOnly); + } + } else if (elementToMove instanceof PsiFile) { + if (!elementToMove.isWritable()) { + readOnly.add(((PsiFile)elementToMove).getVirtualFile()); + return; + } + } + } + + private static PsiDirectory getContainerDirectory(final PsiElement psiElement) { + if (psiElement instanceof PsiPackage) { + return null; //?? + } + else if (psiElement instanceof PsiDirectory) { + return (PsiDirectory)psiElement; + } + else if (psiElement != null) { + return psiElement.getContainingFile().getContainingDirectory(); + } + else { + return null; + } + } + + public static void doRearrangePackage(final Project project, final PsiDirectory[] directories) { + final ArrayList readOnly = new ArrayList(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + checkMove(directory, readOnly); + } + if (!readOnly.isEmpty()) { + Messages.showErrorDialog(project, "Cannot perform refactorings.\n Some files or directories are read only.", "Move"); + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + (VirtualFile[])readOnly.toArray(new VirtualFile[readOnly.size()])); + return; + } + List sourceRootDirectories = buildRearrangeTargetsList(project, directories); + DirectoryChooser chooser = new DirectoryChooser(project); + chooser.setTitle("Select source root"); + chooser.fillList((PsiDirectory[])sourceRootDirectories.toArray(new PsiDirectory[sourceRootDirectories.size()]), null, project, ""); + chooser.show(); + if (!chooser.isOK()) return; + final PsiDirectory selectedTarget = chooser.getSelectedDirectory(); + if (selectedTarget == null) return; + final Ref ex = Ref.create(null); + final String commandDescription = "Moving directories"; + Runnable runnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final LvcsAction lvcsAction = LvcsIntegration.checkinFilesBeforeRefactoring(project, commandDescription); + try { + rearrangeDirectoriesToTarget(directories, selectedTarget); + } + catch (IncorrectOperationException e) { + ex.set(e); + } + finally{ + LvcsIntegration.checkinFilesAfterRefactoring(project, lvcsAction); + } + } + }); + } + }; + CommandProcessor.getInstance().executeCommand(project, runnable, commandDescription, null); + if (ex.get() != null) { + RefactoringUtil.processIncorrectOperation(project, ex.get()); + } + } + + private static List buildRearrangeTargetsList(final Project project, final PsiDirectory[] directories) { + final VirtualFile[] sourceRoots = ProjectRootManager.getInstance(project).getContentSourceRoots(); + List sourceRootDirectories = new ArrayList(); + sourceRoots: + for (int i = 0; i < sourceRoots.length; i++) { + final VirtualFile sourceRoot = sourceRoots[i]; + PsiDirectory sourceRootDirectory = PsiManager.getInstance(project).findDirectory(sourceRoot); + if (sourceRootDirectory == null) { + LOG.error("Cannot find PsiDirectory for: " + sourceRoot.getPresentableUrl()); + continue sourceRoots; + } + final PsiPackage aPackage = sourceRootDirectory.getPackage(); + if (aPackage == null) continue; + final String packagePrefix = aPackage.getQualifiedName(); + for (int j = 0; j < directories.length; j++) { + final PsiDirectory directory = directories[j]; + String qualifiedName = directory.getPackage().getQualifiedName(); + if (!qualifiedName.startsWith(packagePrefix)) { + continue sourceRoots; + } + } + sourceRootDirectories.add(sourceRootDirectory); + } + return sourceRootDirectories; + } + + private static void rearrangeDirectoriesToTarget(PsiDirectory[] directories, PsiDirectory selectedTarget) + throws IncorrectOperationException { + final VirtualFile sourceRoot = selectedTarget.getVirtualFile(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + final PsiPackage parentPackage = directory.getPackage().getParentPackage(); + final PackageWrapper wrapper = new PackageWrapper(parentPackage); + final PsiDirectory moveTarget = RefactoringUtil.createPackageDirectoryInSourceRoot(wrapper, sourceRoot); + MoveClassesOrPackagesUtil.moveDirectoryRecursively(directory, moveTarget); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java new file mode 100644 index 00000000000..a9388ae5795 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java @@ -0,0 +1,601 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.j2ee.ejb.EjbUsagesUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.refactoring.util.classRefs.ClassInstanceScanner; +import com.intellij.refactoring.util.classRefs.ClassReferenceScanner; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author Jeka,dsl + */ +public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor"); + + private PsiElement[] myElementsToMove; + private boolean mySearchInComments; + private boolean mySearchInNonJavaFiles; + private boolean myPreviewUsages; + private PackageWrapper myTargetPackage; + private MoveCallback myMoveCallback; + private final MoveDestination myMoveDestination; + private UsageInfo[] myUsages; + + public MoveClassesOrPackagesProcessor( + Project project, + PsiElement[] elements, + final MoveDestination moveDestination, boolean searchInComments, + boolean searchInNonJavaFiles, + boolean previewUsages, + MoveCallback moveCallback, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myElementsToMove = elements; + myMoveDestination = moveDestination; + myTargetPackage = myMoveDestination.getTargetPackage(); + mySearchInComments = searchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + myPreviewUsages = previewUsages; + myMoveCallback = moveCallback; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + PsiElement[] elements = new PsiElement[myElementsToMove.length]; + for (int idx = 0; idx < myElementsToMove.length; idx++) { + elements[idx] = myElementsToMove[idx]; + } + return new MoveClassesOrPackagesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles, myTargetPackage, + usages, refreshCommand); + } + + public boolean isSearchInComments() { + return mySearchInComments; + } + + public boolean isSearchInNonJavaFiles() { + return mySearchInNonJavaFiles; + } + + public void setSearchInComments(boolean searchInComments) { + mySearchInComments = searchInComments; + } + + public void setSearchInNonJavaFiles(boolean searchInNonJavaFiles) { + mySearchInNonJavaFiles = searchInNonJavaFiles; + } + + + protected UsageInfo[] findUsages() { + List allUsages = new ArrayList(); + ArrayList conflicts = new ArrayList(); + for (int idx = 0; idx < myElementsToMove.length; idx++) { + PsiElement element = myElementsToMove[idx]; + String newName = getNewQName(element); + final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(element, mySearchInComments, + mySearchInNonJavaFiles, newName); + ArrayList usageInfos = new ArrayList(Arrays.asList(usages)); + EjbUsagesUtil.adjustEjbUsages(element, newName, usageInfos); + allUsages.addAll(usageInfos); + } + myMoveDestination.analyzeModuleConflicts(Arrays.asList(myElementsToMove), conflicts); + final UsageInfo[] usageInfos = allUsages.toArray(new UsageInfo[allUsages.size()]); + detectPackageLocalsMoved(usageInfos, conflicts); + detectPackageLocalsUsed(conflicts); + if (conflicts.size() > 0) { + allUsages.add(new ConflictsUsageInfo(myElementsToMove[0], conflicts)); + } + + return UsageViewUtil.removeDuplicatedUsages(allUsages.toArray(new UsageInfo[allUsages.size()])); + } + + public List getElements() { + return Collections.unmodifiableList(Arrays.asList(myElementsToMove)); + } + + public PackageWrapper getTargetPackage() { + return myMoveDestination.getTargetPackage(); + } + + private static class ConflictsUsageInfo extends UsageInfo { + private final ArrayList myConflicts; + + public ConflictsUsageInfo(PsiElement pseudoElement, ArrayList conflicts) { + super(pseudoElement); + myConflicts = conflicts; + } + + public ArrayList getConflicts() { + return myConflicts; + } + } + + + + protected boolean preprocessUsages(UsageInfo[][] u) { + final UsageInfo[] usages = u[0]; + final ArrayList conflicts = new ArrayList(); + ArrayList filteredUsages = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage instanceof ConflictsUsageInfo) { + conflicts.addAll(((ConflictsUsageInfo)usage).getConflicts()); + } + else { + filteredUsages.add(usage); + } + } + + u[0] = filteredUsages.toArray(new UsageInfo[filteredUsages.size()]); + return showConflicts(conflicts, u); + } + + private boolean isInsideMoved(PsiElement place) { + for (int i = 0; i < myElementsToMove.length; i++) { + PsiElement element = myElementsToMove[i]; + if (element instanceof PsiClass) { + if (PsiTreeUtil.isAncestor(element, place, false)) return true; + } + } + return false; + } + + private class PackageLocalsVisitor extends PsiRecursiveElementVisitor { + private HashMap> myReported = new com.intellij.util.containers.HashMap>(); + private final ArrayList myConflicts; + + public PackageLocalsVisitor(ArrayList conflicts) { + myConflicts = conflicts; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + PsiElement resolved = reference.resolve(); + visitResolvedReference(resolved, reference); + } + + + private void visitResolvedReference(PsiElement resolved, PsiJavaCodeReferenceElement reference) { + if (resolved instanceof PsiModifierListOwner) { + final PsiModifierList modifierList = ((PsiModifierListOwner)resolved).getModifierList(); + if (PsiModifier.PACKAGE_LOCAL.equals(VisibilityUtil.getVisibilityModifier(modifierList))) { + PsiFile aFile = resolved.getContainingFile(); + if (aFile != null && !isInsideMoved(resolved)) { + final PsiDirectory containingDirectory = aFile.getContainingDirectory(); + if (containingDirectory != null) { + PsiPackage aPackage = containingDirectory.getPackage(); + if (aPackage != null && !myTargetPackage.equalToPackage(aPackage)) { + HashSet reportedRefs = myReported.get(resolved); + if (reportedRefs == null) { + reportedRefs = new HashSet(); + myReported.put(resolved, reportedRefs); + } + PsiElement container = ConflictsUtil.getContainer(reference); + if (!reportedRefs.contains(container)) { + final String message = ConflictsUtil.getDescription(container, true) + " uses a package-local " + + ConflictsUtil.getDescription(resolved, true) + "."; + myConflicts.add(ConflictsUtil.capitalize(message)); + reportedRefs.add(container); + } + } + } + } + } + } + } + } + + private void detectPackageLocalsUsed(final ArrayList conflicts) { + PackageLocalsVisitor visitor = new PackageLocalsVisitor(conflicts); + + for (int i = 0; i < myElementsToMove.length; i++) { + PsiElement element = myElementsToMove[i]; + if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass)element; + aClass.accept(visitor); + } + } + } + + private void detectPackageLocalsMoved(final UsageInfo[] usages, final ArrayList conflicts) { +// final HashSet reportedPackageLocalUsed = new HashSet(); + final HashSet movedClasses = new HashSet(); + final HashMap reportedClassToContainers = new com.intellij.util.containers.HashMap(); + final PackageWrapper aPackage = myTargetPackage; + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage instanceof MoveRenameUsageInfo && ((MoveRenameUsageInfo)usage).referencedElement instanceof PsiClass) { + PsiClass aClass = (PsiClass)((MoveRenameUsageInfo)usage).referencedElement; + if (!movedClasses.contains(aClass)) { + movedClasses.add(aClass); + } + String visibility = VisibilityUtil.getVisibilityModifier(aClass.getModifierList()); + if (PsiModifier.PACKAGE_LOCAL.equals(visibility)) { + PsiElement container = ConflictsUtil.getContainer(usage.getElement()); + if (PsiTreeUtil.getParentOfType(usage.getElement(), PsiImportStatement.class) != null) continue; + HashSet reported = reportedClassToContainers.get(aClass); + if (reported == null) { + reported = new HashSet(); + reportedClassToContainers.put(aClass, reported); + } + + if (!reported.contains(container)) { + PsiFile containingFile = usage.getElement().getContainingFile(); + if (containingFile != null && !isInsideMoved(usage.getElement())) { + PsiDirectory directory = containingFile.getContainingDirectory(); + if (directory != null) { + PsiPackage usagePackage = directory.getPackage(); + if (aPackage != null && usagePackage != null && !aPackage.equalToPackage(usagePackage)) { + + final String message = "A package-local class " + ConflictsUtil.htmlEmphasize(aClass.getName()) + + " will no longer be accessible from " + ConflictsUtil.getDescription( + container, true); + conflicts.add(message); + } + } + } + } + } + } + } + + final MyClassInstanceReferenceVisitor instanceReferenceVisitor = new MyClassInstanceReferenceVisitor(conflicts); + for (Iterator it = movedClasses.iterator(); it.hasNext(); ) { + final PsiClass aClass = it.next(); + + String visibility = VisibilityUtil.getVisibilityModifier(aClass.getModifierList()); + if (PsiModifier.PACKAGE_LOCAL.equals(visibility)) { + findInstancesOfPackageLocal(aClass, usages, instanceReferenceVisitor); + } + else { + // public classes + findPublicClassConflicts(aClass, instanceReferenceVisitor); + } + } + } + + static class ClassMemberWrapper { + final PsiNamedElement myElement; + final PsiModifierListOwner myMember; + + public ClassMemberWrapper(PsiNamedElement element) { + myElement = element; + myMember = (PsiModifierListOwner) element; + } + + PsiModifierListOwner getMember() { + return myMember; + } + + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ClassMemberWrapper)) return false; + + ClassMemberWrapper wrapper = (ClassMemberWrapper)o; + + if (myElement instanceof PsiMethod) { + if (!(wrapper.myElement instanceof PsiMethod)) return false; + return MethodSignatureUtil.areSignaturesEqual((PsiMethod)myElement, (PsiMethod)wrapper.myElement); + } + + + return Comparing.equal(myElement.getName(), wrapper.myElement.getName()); + } + + public int hashCode() { + final String name = myElement.getName(); + if (name != null) { + return name.hashCode(); + } + else { + return 0; + } + } + } + + private void findPublicClassConflicts(PsiClass aClass, MyClassInstanceReferenceVisitor instanceReferenceVisitor) { + NonPublicClassMemberWrappersSet members = new NonPublicClassMemberWrappersSet(); + + members.addElements(aClass.getFields()); + members.addElements(aClass.getMethods()); + members.addElements(aClass.getInnerClasses()); + /*final ArrayList basesList = RefactoringHierarchyUtil.createBasesList(aClass, true, false); + basesList.add(aClass); + for (Iterator iterator = basesList.iterator(); iterator.hasNext();) { + PsiClass superClass = (PsiClass)iterator.next(); + if (superClass.isInterface()) continue; + members.addElements(superClass.getFields()); + members.addElements(superClass.getMethods()); + members.addElements(superClass.getInnerClasses()); + }*/ + + final PsiSearchHelper searchHelper = aClass.getManager().getSearchHelper(); + RefactoringUtil.IsDescendantOf isDescendantOf = new RefactoringUtil.IsDescendantOf(aClass); + final PsiPackage aPackage = aClass.getContainingFile().getContainingDirectory().getPackage(); + final GlobalSearchScope packageScope = GlobalSearchScope.packageScopeWithoutLibraries(aPackage, false); + for (Iterator iterator = members.iterator(); iterator.hasNext();) { + ClassMemberWrapper memberWrapper = (ClassMemberWrapper)iterator.next(); + final PsiReference[] references = searchHelper.findReferences(memberWrapper.getMember(), packageScope, false); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression) { + final PsiReferenceExpression expression = ((PsiReferenceExpression)element); + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null) { + final PsiType type = qualifierExpression.getType(); + if (type != null) { + final PsiClass resolvedTypeClass = PsiUtil.resolveClassInType(type); + if (isDescendantOf.value(resolvedTypeClass)) { + instanceReferenceVisitor.visitMemberReference(memberWrapper.getMember(), expression, isDescendantOf); + } + } + } + else { + instanceReferenceVisitor.visitMemberReference(memberWrapper.getMember(), expression, isDescendantOf); + } + } + } + } + } + + private void findInstancesOfPackageLocal(final PsiClass aClass, + final UsageInfo[] usages, + final MyClassInstanceReferenceVisitor instanceReferenceVisitor) { + ClassReferenceScanner referenceScanner = new ClassReferenceScanner(aClass) { + public PsiReference[] findReferences() { + ArrayList result = new ArrayList(); + for (int j = 0; j < usages.length; j++) { + UsageInfo usage = usages[j]; + if (usage instanceof MoveRenameUsageInfo && ((MoveRenameUsageInfo)usage).referencedElement == aClass) { + final PsiReference reference = ((MoveRenameUsageInfo)usage).reference; + if (reference != null) { + result.add(reference); + } + } + } + return result.toArray(new PsiReference[result.size()]); + } + }; + referenceScanner.processReferences(new ClassInstanceScanner(aClass, instanceReferenceVisitor)); + } + + + private String getNewQName(PsiElement element) { + final String qualifiedName = myTargetPackage.getQualifiedName(); + if (element instanceof PsiClass) { + return qualifiedName + (qualifiedName.equals("") ? "" : ".") + ((PsiClass)element).getName(); + } + else if (element instanceof PsiPackage) { + return qualifiedName + (qualifiedName.equals("") ? "" : ".") + ((PsiPackage)element).getName(); + } + else { + LOG.assertTrue(false); + return null; + } + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == myElementsToMove.length); + for (int idx = 0; idx < elements.length; idx++) { + myElementsToMove[idx] = elements[idx]; + } + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myPreviewUsages; + if (UsageViewUtil.hasNonCodeUsages(usages)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo( + "Occurrences found in comments, strings and non-java files"); + return true; + } + else { + return super.isPreviewUsages(usages) || toPreview; + } + } + + protected void performRefactoring(UsageInfo[] usages) { + // If files are being moved then I need to collect some information to delete these + // filese from CVS. I need to know all common parents of the moved files and releative + // paths. + + // Move files with correction of references. + + try { + for (int idx = 0; idx < myElementsToMove.length; idx++) { + PsiElement element = myElementsToMove[idx]; + final RefactoringElementListener elementListener = getTransaction().getElementListener(element); + if (element instanceof PsiPackage) { + + element = MoveClassesOrPackagesUtil.doMovePackage((PsiPackage)element, myMoveDestination, + extractElementUsages(element, usages)); + + } + else if (element instanceof PsiClass) { + ChangeContextUtil.encodeContextInfo(element, true); + element = + MoveClassesOrPackagesUtil.doMoveClass((PsiClass)element, myMoveDestination, extractElementUsages(element, usages)); + } else { + LOG.error("Unexpected element to move: " + element); + } + elementListener.elementMoved(element); + myElementsToMove[idx] = element; + } + + for (int idx = 0; idx < myElementsToMove.length; idx++) { + PsiElement element = myElementsToMove[idx]; + if (element instanceof PsiClass) { + ChangeContextUtil.decodeContextInfo(element, null, null); + } + } + + myUsages = usages; + } + catch (IncorrectOperationException e) { + myUsages = new UsageInfo[0]; + RefactoringUtil.processIncorrectOperation(myProject, e); + } + } + + protected void performPsiSpoilingRefactoring() { + RefactoringUtil.renameNonCodeUsages(myProject, myUsages); + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + } + + private static MoveRenameUsageInfo[] extractElementUsages(PsiElement element, UsageInfo[] allUsages) { + ArrayList usages = new ArrayList(); + for (int idx = 0; idx < allUsages.length; idx++) { + UsageInfo usage = allUsages[idx]; + if (usage instanceof MoveRenameUsageInfo && element.equals(((MoveRenameUsageInfo)usage).referencedElement)) { + usages.add((MoveRenameUsageInfo)usage); + } + } + return usages.toArray(new MoveRenameUsageInfo[usages.size()]); + } + + protected String getCommandName() { + final StringBuffer buffer = new StringBuffer(); + buffer.append("Moving "); + return RefactoringUtil.calculatePsiElementDescriptionList(myElementsToMove, buffer); + } + + private class MyClassInstanceReferenceVisitor implements ClassInstanceScanner.ClassInstanceReferenceVisitor { + private final ArrayList myConflicts; + private final HashMap> myReportedElementToContainer = new com.intellij.util.containers.HashMap>(); + private final HashMap myIsDescendantOfCache = new HashMap(); + private PackageWrapper myTargetPackage; + + public MyClassInstanceReferenceVisitor(ArrayList conflicts) { + myConflicts = conflicts; + myTargetPackage = MoveClassesOrPackagesProcessor.this.myTargetPackage; + } + + public void visitQualifier(PsiReferenceExpression qualified, + PsiExpression instanceRef, + PsiElement referencedInstance) { + PsiElement resolved = qualified.resolve(); + + if (resolved instanceof PsiMember) { + final PsiMember member = (PsiMember)resolved; + final PsiClass containingClass = member.getContainingClass(); + RefactoringUtil.IsDescendantOf isDescendantOf = myIsDescendantOfCache.get(containingClass); + if (isDescendantOf == null) { + isDescendantOf = new RefactoringUtil.IsDescendantOf(containingClass); + myIsDescendantOfCache.put(containingClass, isDescendantOf); + } + visitMemberReference(member, qualified, isDescendantOf); + } + } + + private void visitMemberReference(final PsiModifierListOwner member, PsiReferenceExpression qualified, final RefactoringUtil.IsDescendantOf descendantOf) { + if (member.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { + visitPackageLocalMemberReference(qualified, member); + } else if (member.hasModifierProperty(PsiModifier.PROTECTED)) { + final PsiExpression qualifier = qualified.getQualifierExpression(); + if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) { + visitPackageLocalMemberReference(qualified, member); + } else { + if (!isInInheritor(qualified, descendantOf)) { + visitPackageLocalMemberReference(qualified, member); + } + } + } + } + + private boolean isInInheritor(PsiReferenceExpression qualified, final RefactoringUtil.IsDescendantOf descendantOf) { + PsiClass aClass = PsiTreeUtil.getParentOfType(qualified, PsiClass.class); + while (aClass != null) { + if (descendantOf.value(aClass)) return true; + aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class); + } + return false; + } + + private void visitPackageLocalMemberReference(PsiJavaCodeReferenceElement qualified, PsiModifierListOwner member) { + PsiElement container = ConflictsUtil.getContainer(qualified); + HashSet reportedContainers = myReportedElementToContainer.get(member); + if (reportedContainers == null) { + reportedContainers = new HashSet(); + myReportedElementToContainer.put(member, reportedContainers); + } + + if (!reportedContainers.contains(container)) { + reportedContainers.add(container); + if (!isInsideMoved(container)) { + PsiFile containingFile = container.getContainingFile(); + if (containingFile != null) { + PsiDirectory directory = containingFile.getContainingDirectory(); + if (directory != null) { + PsiPackage aPackage = directory.getPackage(); + if (!myTargetPackage.equalToPackage(aPackage)) { + String message = ConflictsUtil.getDescription(member, true) + " will be inaccessible from " + + ConflictsUtil.getDescription(container, true); + myConflicts.add(ConflictsUtil.capitalize(message)); + } + } + } + } + } + } + + public void visitTypeCast(PsiTypeCastExpression typeCastExpression, + PsiExpression instanceRef, + PsiElement referencedInstance) { + } + + public void visitReadUsage(PsiExpression instanceRef, PsiType expectedType, PsiElement referencedInstance) { + } + + public void visitWriteUsage(PsiExpression instanceRef, PsiType assignedType, PsiElement referencedInstance) { + } + } + + private static class NonPublicClassMemberWrappersSet extends HashSet { + public void addElement(PsiElement element) { + final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)element; + final PsiNamedElement namedElement = (PsiNamedElement)element; + if (modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC)) return; + if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) return; + add(new ClassMemberWrapper(namedElement)); + } + + public void addElements(PsiElement[] elements) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + addElement(element); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java new file mode 100644 index 00000000000..7d87bbc3301 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java @@ -0,0 +1,306 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.NonCodeUsageInfo; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class MoveClassesOrPackagesUtil { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil"); + + public static UsageInfo[] findUsages(final PsiElement element, + boolean searchInStringsAndComments, + boolean searchInNonJavaFiles, + final String newQName) { + PsiManager manager = element.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + + if (Comparing.equal(getQualfiedName(element), newQName)) return new UsageInfo[0]; + + ArrayList results = new ArrayList(); + Set foundReferences = new HashSet(); + + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + PsiReference[] references = helper.findReferences(element, projectScope, false); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + TextRange range = reference.getRangeInElement(); + if (foundReferences.contains(reference)) continue; + results.add( + new MoveRenameUsageInfo(reference.getElement(), reference, range.getStartOffset(), range.getEndOffset(), + element, false)); + foundReferences.add(reference); + } + + findNonCodeUsages(searchInStringsAndComments, searchInNonJavaFiles, element, newQName, results); + + return (UsageInfo[])results.toArray(new UsageInfo[results.size()]); + } + + private static String getQualfiedName(final PsiElement element) { + final String oldQName; + if (element instanceof PsiClass) { + oldQName = ((PsiClass)element).getQualifiedName(); + } + else if (element instanceof PsiPackage) { + oldQName = ((PsiPackage)element).getQualifiedName(); + } + else if (element instanceof PsiDirectory) { + final PsiPackage aPackage = ((PsiDirectory)element).getPackage(); + oldQName = aPackage != null ? aPackage.getQualifiedName() : null; + } + else { + oldQName = null; + } + return oldQName; + } + + public static void findNonCodeUsages(boolean searchInStringsAndComments, + boolean searchInNonJavaFiles, + final PsiElement element, + final String newQName, + ArrayList results) { + if (searchInStringsAndComments || searchInNonJavaFiles) { + final String stringToSearch = getStringToSearch(element); + RefactoringUtil.UsageInfoFactory factory = createUsageInfoFactory(element, newQName); + + if (searchInStringsAndComments) { + RefactoringUtil.addUsagesInStringsAndComments(element, stringToSearch, results, factory); + } + + if (searchInNonJavaFiles) { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(element.getProject()); + RefactoringUtil.addUsagesInNonJavaFiles(element, stringToSearch, projectScope, results, factory); + } + } + } + + private static RefactoringUtil.UsageInfoFactory createUsageInfoFactory(final PsiElement element, + final String newQName) { + return new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + int start = usage.getTextRange().getStartOffset(); + return NonCodeUsageInfo.create(usage.getContainingFile(), start + startOffset, start + endOffset, element, + newQName); + } + }; + } + + public static String getStringToSearch(PsiElement element) { + if (element instanceof PsiPackage) { + return ((PsiPackage)element).getQualifiedName(); + } + else if (element instanceof PsiClass) { + return ((PsiClass)element).getQualifiedName(); + } + else { + LOG.error("Unknown element type"); + return null; + } + } + + // Does not process non-code usages! + public static PsiPackage doMovePackage(PsiPackage aPackage, MoveDestination moveDestination, UsageInfo[] usages) + throws IncorrectOperationException { + PsiManager manager = aPackage.getManager(); + final PackageWrapper targetPackage = moveDestination.getTargetPackage(); + + // Collect destination packages + Map targetPackages = new HashMap(); + final String newPrefix; + if ("".equals(targetPackage.getQualifiedName())) { + newPrefix = ""; + } + else { + newPrefix = targetPackage.getQualifiedName() + "."; + } + + final String newPackageQualifiedName = newPrefix + aPackage.getName(); + + for (int i = 0; i < usages.length; i++) { + MoveRenameUsageInfo usage = (MoveRenameUsageInfo)usages[i]; + LOG.assertTrue(usage.referencedElement instanceof PsiPackage); + final PsiPackage oldPackage = (PsiPackage)usage.referencedElement; + LOG.assertTrue(!"".equals(oldPackage.getName())); + targetPackages.put(usage, newPrefix + oldPackage.getName()); + } + + // do actual move + final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(aPackage.getProject()); + PsiDirectory[] dirs = aPackage.getDirectories(projectScope); + for (int i = 0; i < dirs.length; i++) { + PsiDirectory dir = dirs[i]; + final PsiDirectory targetDirectory = moveDestination.getTargetDirectory(dir); + if (targetDirectory != null) { + moveDirectoryRecursively(dir, targetDirectory); + } + } + + // rename all references + for (int i = 0; i < usages.length; i++) { + MoveRenameUsageInfo usage = (MoveRenameUsageInfo)usages[i]; + if (!usage.getElement().isValid()) continue; + PsiReference reference = usage.reference; + if (reference != null) { + final String newQName = targetPackages.get(usage); + final PsiPackage newPackage = manager.findPackage(newQName); + reference.bindToElement(newPackage); + } + } + + aPackage.handleQualifiedNameChange(newPackageQualifiedName); + + return manager.findPackage(newPackageQualifiedName); + } + + public static void moveDirectoryRecursively(PsiDirectory dir, PsiDirectory destination) + throws IncorrectOperationException { + moveDirectoryRecursively(dir, destination, new HashSet()); + } + + public static void moveDirectoryRecursively(PsiDirectory dir, PsiDirectory destination, HashSet movedPaths) + throws IncorrectOperationException { + final PsiManager manager = dir.getManager(); + final VirtualFile destVFile = destination.getVirtualFile(); + final VirtualFile sourceVFile = dir.getVirtualFile(); + if (movedPaths.contains(sourceVFile)) return; + String targetName = dir.getName(); + final String sourcePackageName = dir.getPackage().getName(); + if (!targetName.equals(sourcePackageName)) { + targetName = sourcePackageName; + } + final PsiDirectory subdirectoryInDest; + final boolean isSourceRoot = RefactoringUtil.isSourceRoot(dir); + if (VfsUtil.isAncestor(sourceVFile, destVFile, false) || isSourceRoot) { + PsiDirectory exitsingSubdir = destination.findSubdirectory(targetName); + if (exitsingSubdir == null) { + subdirectoryInDest = destination.createSubdirectory(targetName); + movedPaths.add(subdirectoryInDest.getVirtualFile()); + } else { + subdirectoryInDest = exitsingSubdir; + } + } else { + subdirectoryInDest = destination.findSubdirectory(targetName); + } + + if (subdirectoryInDest == null) { + VirtualFile virtualFile = dir.getVirtualFile(); + manager.moveDirectory(dir, destination); + movedPaths.add(virtualFile); + } + else { + final PsiFile[] files = dir.getFiles(); + for (int i = 0; i < files.length; i++) { + PsiFile file = files[i]; + try { + subdirectoryInDest.checkAdd(file); + } + catch (IncorrectOperationException e) { + continue; + } + manager.moveFile(file, subdirectoryInDest); + } + + final PsiDirectory[] subdirectories = dir.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + PsiDirectory subdirectory = subdirectories[i]; + if (!subdirectory.equals(subdirectoryInDest)) { + moveDirectoryRecursively(subdirectory, subdirectoryInDest, movedPaths); + } + } + if (!isSourceRoot && dir.getFiles().length == 0 && dir.getSubdirectories().length == 0) { + dir.delete(); + } + } + } +// Does not process non-code usages! + public static PsiClass doMoveClass(PsiClass aClass, MoveDestination moveDestination, UsageInfo[] usages) + throws IncorrectOperationException { + PsiManager manager = aClass.getManager(); + +// the class is already there, this is true when multiple classes are defined in the same file + PsiFile file = aClass.getContainingFile(); + PsiDirectory newDirectory = moveDestination.getTargetDirectory(file); + if (!newDirectory.equals(file.getContainingDirectory())) { +// do actual move + manager.moveFile(file, newDirectory); + + if (file instanceof PsiJavaFile) { // Q: move this code into some util? + PsiPackage newPackage = newDirectory.getPackage(); + PsiJavaFile javaFile = (PsiJavaFile)file; + PsiPackageStatement packageStatement = javaFile.getPackageStatement(); + String packageName = newPackage.getQualifiedName(); + if (packageStatement != null) { + if (packageName.length() > 0) { + packageStatement.getPackageReference().bindToElement(newPackage); + } + else { + packageStatement.delete(); + } + } + else { + if (packageName.length() > 0) { + String text = "package " + packageName + ";"; + String ext = StdFileTypes.JAVA.getDefaultExtension(); + PsiJavaFile dummyFile = (PsiJavaFile)manager.getElementFactory().createFileFromText("_Dummy_." + ext, text); + packageStatement = dummyFile.getPackageStatement(); + file.add(packageStatement); + } + } + } + } + +// rename all references + for (int i = 0; i < usages.length; i++) { + MoveRenameUsageInfo usage = (MoveRenameUsageInfo)usages[i]; + if (usage.getElement() == null || !usage.getElement().isValid()) continue; + PsiReference reference = usage.reference; + if (reference != null) { + PsiElement parent = reference.getElement().getParent(); + if (parent instanceof PsiImportStatement) { + if (parent.getContainingFile().getContainingDirectory().equals(newDirectory)) { + parent.delete(); // remove import statement to the class in the same package + continue; + } + } + + reference.bindToElement(aClass); + } + } + + return aClass; + } + + public static String getPackageName(PackageWrapper aPackage) { + if (aPackage == null) { + return null; + } + String name = aPackage.getQualifiedName(); + if (name.length() > 0) { + return name; + } + else { + return UsageViewUtil.DEFAULT_PACKAGE_NAME; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java new file mode 100644 index 00000000000..94bcfa07134 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java @@ -0,0 +1,125 @@ +/** + * created at Sep 17, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class MoveClassesOrPackagesViewDescriptor implements UsageViewDescriptor { + private PsiElement[] myPsiElements; + private final boolean mySearchInComments; + private final boolean mySearchInNonJavaFiles; + private PackageWrapper myTargetPackage; + private String myNewParentPackageName; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + private String myProcessedElementsHeader; + private String myCodeReferencesText; + private final String myHelpID; + + public MoveClassesOrPackagesViewDescriptor(PsiElement[] psiElements, + boolean isSearchInComments, + boolean searchInNonJavaFiles, PackageWrapper newParent, + UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myPsiElements = psiElements; + myUsages = usages; + myRefreshCommand = refreshCommand; + mySearchInComments = isSearchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + myTargetPackage = newParent; + myNewParentPackageName = MoveClassesOrPackagesUtil.getPackageName(myTargetPackage); + if (psiElements.length == 1) { + myProcessedElementsHeader = UsageViewUtil.capitalize(UsageViewUtil.getType(psiElements[0]) + " to be moved to " + myNewParentPackageName); + myCodeReferencesText = "References in code to " + UsageViewUtil.getType(psiElements[0]) + " " + UsageViewUtil.getLongName(psiElements[0]) + " "; + } + else { + if (psiElements[0] instanceof PsiClass) { + myProcessedElementsHeader = UsageViewUtil.capitalize("Classes to be moved to " + myNewParentPackageName); + } + else if (psiElements[0] instanceof PsiDirectory){ + myProcessedElementsHeader = UsageViewUtil.capitalize("Packages to be moved to " + myNewParentPackageName); + } + myCodeReferencesText = "References found in code "; + } + myHelpID = HelpID.getMoveHelpID(psiElements[0]); + } + + public PsiElement[] getElements() { + return myPsiElements; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + myPsiElements = new PsiElement[elements.length]; + for (int idx = 0; idx < elements.length; idx++) { + myPsiElements[idx] = elements[idx]; + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myProcessedElementsHeader; + } + + public boolean isSearchInText() { + return mySearchInComments || mySearchInNonJavaFiles; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return OCCURRENCE_WORD; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return myCodeReferencesText + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return "Occurrences found in comments, strings and non-java files " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "occurrence"); + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return myHelpID; + } + + public boolean canRefresh() { + return true; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MultipleRootsMoveDestination.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MultipleRootsMoveDestination.java new file mode 100644 index 00000000000..96a46bba8de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/MultipleRootsMoveDestination.java @@ -0,0 +1,100 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author dsl + */ +public class MultipleRootsMoveDestination extends AutocreatingMoveDestination { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination"); + + public MultipleRootsMoveDestination(PackageWrapper aPackage) { + super(aPackage); + } + + public PackageWrapper getTargetPackage() { + return myPackage; + } + + + public PsiDirectory getTargetDirectory(PsiDirectory source) throws IncorrectOperationException { + if (source.isSourceRoot()) return null; + return getOrCreateDirectoryForSource(source.getVirtualFile()); + } + + public PsiDirectory getTargetDirectory(PsiFile source) throws IncorrectOperationException { + return getOrCreateDirectoryForSource(source.getVirtualFile()); + } + + public PsiDirectory getTargetIfExists(PsiFile source) { + return findTargetDirectoryForSource(source.getVirtualFile()); + } + + public String verify(PsiFile source) { + VirtualFile virtualFile = source.getVirtualFile(); + if (virtualFile.isDirectory()) { + virtualFile = virtualFile.getParent(); + LOG.assertTrue(virtualFile.isDirectory()); + } + + final VirtualFile sourceRootForFile = myFileIndex.getSourceRootForFile(virtualFile); + if (sourceRootForFile == null) { + return ""; + } + return checkCanCreateInSourceRoot(sourceRootForFile); + } + + public String verify(PsiDirectory source) { + VirtualFile virtualFile = source.getVirtualFile(); + final VirtualFile sourceRootForFile = myFileIndex.getSourceRootForFile(virtualFile); + if (sourceRootForFile == null) { + return ""; + } + if (virtualFile.equals(sourceRootForFile)) return null; + return checkCanCreateInSourceRoot(sourceRootForFile); + } + + public String verify(PsiPackage source) { + PsiDirectory[] directories = source.getDirectories(); + for (int i = 0; i < directories.length; i++) { + final PsiDirectory directory = directories[i]; + String s = verify(directory); + if (s != null) return s; + } + return null; + } + + public void analyzeModuleConflicts(final Collection elements, + ArrayList conflicts) { + } + + public PsiDirectory getTargetIfExists(PsiDirectory source) { + return findTargetDirectoryForSource(source.getVirtualFile()); + } + + + protected PsiDirectory findTargetDirectoryForSource(final VirtualFile file) { + final VirtualFile sourceRoot = myFileIndex.getSourceRootForFile(file); + LOG.assertTrue(sourceRoot != null); + return RefactoringUtil.findPackageDirectoryInSourceRoot(myPackage, sourceRoot); + } + + protected PsiDirectory getOrCreateDirectoryForSource(final VirtualFile file) + throws IncorrectOperationException { + final VirtualFile sourceRoot = myFileIndex.getSourceRootForFile(file); + LOG.assertTrue(sourceRoot != null); + return RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, sourceRoot); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java new file mode 100644 index 00000000000..6ea3a52e323 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java @@ -0,0 +1,67 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.MoveDestination; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Collection; + +/** + * @author dsl + */ +public class SingleSourceRootMoveDestination implements MoveDestination { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination"); + private final PackageWrapper myPackage; + private final PsiDirectory myTagretDirectory; + + public SingleSourceRootMoveDestination(PackageWrapper aPackage, PsiDirectory tagretDirectory) { + LOG.assertTrue(aPackage.equalToPackage(tagretDirectory.getPackage())); + myPackage = aPackage; + myTagretDirectory = tagretDirectory; + } + + public PackageWrapper getTargetPackage() { + return myPackage; + } + + public PsiDirectory getTargetIfExists(PsiDirectory source) { + return myTagretDirectory; + } + + public PsiDirectory getTargetIfExists(PsiFile source) { + return myTagretDirectory; + } + + public PsiDirectory getTargetDirectory(PsiDirectory source) { + return myTagretDirectory; + } + + public String verify(PsiFile source) { + return null; + } + + public String verify(PsiDirectory source) { + return null; + } + + public String verify(PsiPackage source) { + return null; + } + + public void analyzeModuleConflicts(final Collection elements, + ArrayList conflicts) { + RefactoringUtil.analyzeModuleConflicts(myPackage.getManager().getProject(), elements, myTagretDirectory, conflicts); + } + + public PsiDirectory getTargetDirectory(PsiFile source) { + return myTagretDirectory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java new file mode 100644 index 00000000000..64e43221a9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java @@ -0,0 +1,137 @@ + +package com.intellij.refactoring.move.moveFilesOrDirectories; + +import com.intellij.ide.util.DirectoryUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.io.File; + +public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ + public static interface Callback { + void run(MoveFilesOrDirectoriesDialog dialog); + } + + private JLabel myNameLabel; + private TextFieldWithBrowseButton myTargetDirectoryField; + private String myHelpID; + private Project myProject; + private final Callback myCallback; + private PsiDirectory myTargetDirectory; + + public MoveFilesOrDirectoriesDialog(Project project, Callback callback) { + super(project, true); + myProject = project; + myCallback = callback; + setTitle("Move"); + init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + public JComponent getPreferredFocusedComponent() { + return myTargetDirectoryField.getTextField(); + } + + protected JComponent createCenterPanel() { + return null; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + + panel.setBorder(IdeBorderFactory.createBorder()); + + myNameLabel = new JLabel(); + panel.add(myNameLabel, new GridBagConstraints(0,0,2,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); + + panel.add(new JLabel("To directory: "), new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); + + myTargetDirectoryField = new TextFieldWithBrowseButton(); + myTargetDirectoryField.addBrowseFolderListener("Select target directory", "The file will be moved to this directory", null, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + myTargetDirectoryField.setTextFieldPreferredWidth(60); + panel.add(myTargetDirectoryField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0)); + + myTargetDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + validateOKButton(); + } + }); + + return panel; + } + + public void setData(PsiElement[] psiElements, PsiDirectory initialTargetDirectory, boolean searchInComments, boolean searchInNonJavaFiles, String helpID) { + if (psiElements.length == 1) { + String text; + if (psiElements[0] instanceof PsiFile) { + text = "Move file " + ((PsiFile)psiElements[0]).getVirtualFile().getPresentableUrl(); + } + else { + text = "Move directory " + ((PsiDirectory)psiElements[0]).getVirtualFile().getPresentableUrl(); + } + myNameLabel.setText(text); + } + else { + myNameLabel.setText((psiElements[0] instanceof PsiFile)? "Move specified files" : "Move specified directories"); + } + myTargetDirectoryField.setText(initialTargetDirectory == null ? "" : initialTargetDirectory.getVirtualFile().getPresentableUrl()); + + validateOKButton(); + myHelpID = helpID; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpID); + } + + private void validateOKButton() { + setOKActionEnabled(myTargetDirectoryField.getText().length() > 0); + } + + protected void doOKAction() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + String directoryName = myTargetDirectoryField.getText().replace(File.separatorChar, '/'); + try { + myTargetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(myProject), directoryName); + } + catch (IncorrectOperationException e) { + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, "Create directory", null); + if (myTargetDirectory == null){ + RefactoringMessageUtil.showErrorMessage(MoveFilesOrDirectoriesDialog.this.getTitle(), "Cannot create directory", myHelpID, myProject); + return; + } + myCallback.run(this); + } + + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesProcessor.java new file mode 100644 index 00000000000..e2918c23019 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesProcessor.java @@ -0,0 +1,151 @@ +package com.intellij.refactoring.move.moveFilesOrDirectories; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; + +public class MoveFilesOrDirectoriesProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor"); + + private PsiElement[] myElementsToMove; + private final boolean mySearchInComments; + private final boolean mySearchInNonJavaFiles; + private PsiDirectory myNewParent; + private MoveCallback myMoveCallback; + private UsageInfo[] myUsagesAfterRefactoring; + + public MoveFilesOrDirectoriesProcessor( + Project project, + PsiElement[] elements, + PsiDirectory newParent, + boolean searchInComments, + boolean searchInNonJavaFiles, + MoveCallback moveCallback, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myElementsToMove = elements; + myNewParent = newParent; + mySearchInComments = searchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + myMoveCallback = moveCallback; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + PsiElement[] elements = new PsiElement[myElementsToMove.length]; + for (int idx = 0; idx < myElementsToMove.length; idx++) { + elements[idx] = myElementsToMove[idx]; + } + return new MoveFilesOrDirectoriesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles, myNewParent, + usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + return new UsageInfo[0]; + } + + protected boolean preprocessUsages(UsageInfo[][] u) { + final UsageInfo[] usages = u[0]; + ArrayList filteredUsages = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + filteredUsages.add(usage); + } + + u[0] = (UsageInfo[])filteredUsages.toArray(new UsageInfo[filteredUsages.size()]); + prepareSuccessful(); + return true; + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == myElementsToMove.length); + for (int idx = 0; idx < elements.length; idx++) { + myElementsToMove[idx] = elements[idx]; + } + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return false; + } + + protected void performRefactoring(UsageInfo[] usages) { + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + arrayList.add(usage); + } + + // If files are being moved then I need to collect some information to delete these + // filese from CVS. I need to know all common parents of the moved files and releative + // paths. + + // Move files with correction of references. + + try { + for (int idx = 0; idx < myElementsToMove.length; idx++) { + PsiElement element = myElementsToMove[idx]; + final RefactoringElementListener elementListener = getTransaction().getElementListener(element); + if (element instanceof PsiDirectory) { + + element = MoveFilesOrDirectoriesUtil.doMoveDirectory((PsiDirectory)element, myNewParent); + + } + else if (element instanceof PsiFile) { + element = MoveFilesOrDirectoriesUtil.doMoveFile((PsiFile)element, myNewParent); + } + + elementListener.elementMoved(element); + myElementsToMove[idx] = element; + } + + myUsagesAfterRefactoring = usages; + + // Perform CVS "add", "remove" commands on moved files. + + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + + } + catch (IncorrectOperationException e) { + final String message = e.getMessage(); + final int index = (message != null) ? message.indexOf("java.io.IOException") : -1; + if (index >= 0) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(myProject, message.substring(index + "java.io.IOException".length()), "Error", + Messages.getErrorIcon()); + } + }); + } + else { + LOG.error(e); + } + } + } + + protected void performPsiSpoilingRefactoring() { + if (myUsagesAfterRefactoring != null) { + RefactoringUtil.renameNonCodeUsages(myProject, myUsagesAfterRefactoring); + } + } + + protected String getCommandName() { + return "Move"; //TODO!! + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java new file mode 100644 index 00000000000..0d850af1a73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java @@ -0,0 +1,260 @@ +package com.intellij.refactoring.move.moveFilesOrDirectories; + +import com.intellij.ide.util.DeleteUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.HashSet; + +public class MoveFilesOrDirectoriesUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil"); + + // Does not process non-code usages! + public static PsiDirectory doMoveDirectory(PsiDirectory aDirectory, PsiDirectory destDirectory) throws IncorrectOperationException{ + PsiManager manager = aDirectory.getManager(); + // do actual move + manager.moveDirectory(aDirectory, destDirectory); + return aDirectory; + } + + // Does not process non-code usages! + public static PsiFile doMoveFile(PsiFile file, PsiDirectory newDirectory) throws IncorrectOperationException{ + PsiManager manager = file.getManager(); + // the class is already there, this is true when multiple classes are defined in the same file + if (!newDirectory.equals(file.getContainingDirectory())) { + // do actual move + manager.moveFile(file, newDirectory); + } + return file; + } + + /** + * @param elements should contain PsiDirectories or PsiFiles only + */ + public static void doMove(final Project project, final PsiElement[] elements, PsiDirectory initialTargetElement, final MoveCallback moveCallback) { + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (element instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)element).getPackage(); + LOG.assertTrue(aPackage == null); + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return; + } + } + else if (element instanceof PsiFile) { + PsiFile aFile = (PsiFile)element; + if (!aFile.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, aFile); + return; + } + } + else { + throw new IllegalArgumentException("unexpected element type: " + element); + } + } + + final PsiDirectory initialTargetDirectory = getInitialTargetDirectory(initialTargetElement, elements); + + final MoveFilesOrDirectoriesDialog.Callback doRun = new MoveFilesOrDirectoriesDialog.Callback() { + public void run(final MoveFilesOrDirectoriesDialog moveDialog) { + final PsiDirectory targetDirectory = moveDialog.getTargetDirectory(); + + LOG.assertTrue(targetDirectory != null); + + PsiManager manager = PsiManager.getInstance(project); + try { + for (int idx = 0; idx < elements.length; idx++) { + PsiElement psiElement = elements[idx]; + manager.checkMove(psiElement, targetDirectory); + } + + new MoveFilesOrDirectoriesProcessor( + project, + elements, + targetDirectory, + false, + false, + moveCallback, + new Runnable() { + public void run() { + moveDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }).run(null); + } + catch (IncorrectOperationException e) { + String helpId = HelpID.getMoveHelpID(elements[0]); + RefactoringMessageUtil.showErrorMessage("Error", e.getMessage(), helpId, project); + return; + } + } + }; + + final MoveFilesOrDirectoriesDialog moveDialog = new MoveFilesOrDirectoriesDialog(project, doRun); + boolean searchInComments = RefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS; + boolean searchInNonJavaFiles = RefactoringSettings.getInstance().MOVE_SEARCH_IN_NONJAVA_FILES; + moveDialog.setData( + elements, + initialTargetDirectory, + searchInComments, + searchInNonJavaFiles, + HelpID.getMoveHelpID(elements[0]) + ); + moveDialog.show(); + } + + private static PsiDirectory getCommonDirectory(PsiElement[] movedElements) { + PsiDirectory commonDirectory = null; + + for (int i = 0; i < movedElements.length; i++) { + PsiElement movedElement = movedElements[i]; + final PsiFile containingFile = movedElement.getContainingFile(); + if(containingFile != null) { + final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + if(containingDirectory != null) { + if(commonDirectory == null) { + commonDirectory = containingDirectory; + } + else { + if(commonDirectory != containingDirectory) { + return null; + } + } + } + } + } + if(commonDirectory != null) { + return commonDirectory; + } + else { + return null; + } + } + + private static PsiDirectory getInitialTargetDirectory(PsiDirectory initialTargetElement, final PsiElement[] movedElements) { + PsiDirectory initialTargetDirectory = initialTargetElement; + if (initialTargetDirectory == null) { + if (movedElements != null) { + final PsiDirectory commonDirectory = getCommonDirectory(movedElements); + if (commonDirectory != null) { + initialTargetDirectory = commonDirectory; + } else { + initialTargetDirectory = getContainerDirectory(movedElements[0]); + } + } + } + return initialTargetDirectory; + } + + private static PsiDirectory getContainerDirectory(final PsiElement psiElement) { + if (psiElement instanceof PsiDirectory) { + return (PsiDirectory)psiElement; + } + else if (psiElement != null) { + return psiElement.getContainingFile().getContainingDirectory(); + } + else { + return null; + } + } + + public static boolean canMoveFiles(PsiElement[] elements) { + if (elements == null) { + throw new IllegalArgumentException("elements cannot be null"); + } + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!(element instanceof PsiFile) || (element instanceof PsiJavaFile)) { + return false; + } + } + + // the second 'for' statement is for effectivity - to prevent creation of the 'names' array + HashSet names = new HashSet(); + for (int i = 0; i < elements.length; i++) { + PsiFile file = (PsiFile)elements[i]; + String name = file.getName(); + if (names.contains(name)) { + return false; + } + + names.add(name); + } + + return true; + } + + public static boolean canMoveOrRearrangePackages(PsiElement[] elements) { + if (elements.length == 0) return false; + final Project project = elements[0].getProject(); + if (ProjectRootManager.getInstance(project).getContentSourceRoots().length == 1) { + return false; + } + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!(element instanceof PsiDirectory)) return false; + final PsiDirectory directory = ((PsiDirectory)element); + if (RefactoringUtil.isSourceRoot(directory)) { + return false; + } + final PsiPackage aPackage = directory.getPackage(); + if (aPackage == null) return false; + if ("".equals(aPackage.getQualifiedName())) return false; + final VirtualFile sourceRootForFile = ProjectRootManager.getInstance(element.getProject()).getFileIndex().getSourceRootForFile(directory.getVirtualFile()); + if (sourceRootForFile == null) return false; + } + return true; + } + + public static boolean canMoveDirectories(PsiElement[] elements) { + if (elements == null) { + throw new IllegalArgumentException("elements cannot be null"); + } + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!(element instanceof PsiDirectory)) { + return false; + } + } + + for (int i = 0; i < elements.length; i++) { + PsiDirectory directory = (PsiDirectory)elements[i]; + + if (hasPackages(directory)) { + return false; + } + } + + PsiElement[] filteredElements = DeleteUtil.filterElements(elements); + if (filteredElements.length != elements.length) { + // there are nested dirs + return false; + } + + return true; + } + + private static boolean hasPackages(PsiDirectory directory) { + if (directory.getPackage() != null) { + return true; + } + PsiDirectory[] subdirectories = directory.getSubdirectories(); + for (int i = 0; i < subdirectories.length; i++) { + PsiDirectory subdirectory = subdirectories[i]; + if (hasPackages(subdirectory)) { + return true; + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesViewDescriptor.java new file mode 100644 index 00000000000..3cde050fab6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesViewDescriptor.java @@ -0,0 +1,113 @@ +package com.intellij.refactoring.move.moveFilesOrDirectories; + +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.HelpID; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class MoveFilesOrDirectoriesViewDescriptor implements UsageViewDescriptor { + private PsiElement[] myElementsToMove; + private final boolean mySearchInComments; + private final boolean mySearchInNonJavaFiles; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + private String myProcessedElementsHeader; + private String myCodeReferencesText; + private final String myHelpID; + + public MoveFilesOrDirectoriesViewDescriptor(PsiElement[] elementsToMove, boolean isSearchInComments, boolean searchInNonJavaFiles, PsiDirectory newParent, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myElementsToMove = elementsToMove; + myUsages = usages; + myRefreshCommand = refreshCommand; + mySearchInComments = isSearchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + if (elementsToMove.length == 1) { + myProcessedElementsHeader = UsageViewUtil.capitalize(UsageViewUtil.getType(elementsToMove[0]) + " to be moved to " + newParent.getVirtualFile().getPresentableUrl()); + myCodeReferencesText = "References in code to " + UsageViewUtil.getType(elementsToMove[0]) + " " + UsageViewUtil.getLongName(elementsToMove[0]) + " "; + } + else { + if (elementsToMove[0] instanceof PsiFile) { + myProcessedElementsHeader = UsageViewUtil.capitalize("Files to be moved to " + newParent.getVirtualFile().getPresentableUrl()); + } + else if (elementsToMove[0] instanceof PsiDirectory){ + myProcessedElementsHeader = UsageViewUtil.capitalize("Directories to be moved to " + newParent.getVirtualFile().getPresentableUrl()); + } + myCodeReferencesText = "References found in code "; + } + myHelpID = HelpID.getMoveHelpID(elementsToMove[0]); + } + + public PsiElement[] getElements() { + return myElementsToMove; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + myElementsToMove = new PsiElement[elements.length]; + for (int idx = 0; idx < elements.length; idx++) { + myElementsToMove[idx] = elements[idx]; + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myProcessedElementsHeader; + } + + public boolean isSearchInText() { + return mySearchInComments || mySearchInNonJavaFiles; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return OCCURRENCE_WORD; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return myCodeReferencesText + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return "Occurrences found in comments, strings and non-java files " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "occurrence"); + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return myHelpID; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java new file mode 100644 index 00000000000..6da13590d9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java @@ -0,0 +1,263 @@ +/** + * created at Sep 24, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveInner; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.NameSuggestionsField; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.NonFocusableCheckBox; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +public class MoveInnerDialog extends RefactoringDialog { + private Project myProject; + private PsiClass myInnerClass; + private MoveInnerProcessor myProcessor; + + private EditorTextField myClassNameField = new EditorTextField(""); +// private JTextField myParameterField = new JTextField(); + private NameSuggestionsField myParameterField; + private JCheckBox myCbPassOuterClass; + private JCheckBox myCbSearchInComments; + private JCheckBox myCbSearchInNonJavaFiles; + private SuggestedNameInfo mySuggestedNameInfo; + private static final String PASS_OUTER_CLASS_TEXT = "Pass outer class' instance as a parameter"; + private PsiClass myOuterClass; + + public MoveInnerDialog(Project project, PsiClass innerClass, MoveInnerProcessor processor) { + super(project, true); + myProject = project; + myInnerClass = innerClass; + myOuterClass = myInnerClass.getContainingClass(); + myProcessor = processor; + setTitle(MoveInnerImpl.REFACTORING_NAME); + init(); + } + + public boolean isSearchInComments() { + return myCbSearchInComments.isSelected(); + } + + public boolean isSearchInNonJavaFiles() { + return myCbSearchInNonJavaFiles.isSelected(); + } + + public String getClassName() { + return myClassNameField.getText().trim(); + } + + public String getParameterName() { + if (myParameterField != null) { + return myParameterField.getName(); + } + else { + return null; + } + } + + public boolean isPassOuterClass() { + return myCbPassOuterClass.isSelected(); + } + + public PsiClass getInnerClass() { + return myInnerClass; + } + + protected void init() { + final PsiManager manager = myInnerClass.getManager(); + myClassNameField.setText(myInnerClass.getName()); + myClassNameField.selectAll(); + + if (!myInnerClass.hasModifierProperty(PsiModifier.STATIC)) { + PsiType outerType = manager.getElementFactory().createType(myInnerClass.getContainingClass()); + mySuggestedNameInfo = + CodeStyleManager.getInstance(myProject).suggestVariableName(VariableKind.PARAMETER, null, null, outerType); + String[] variants = mySuggestedNameInfo.names; + myParameterField = new NameSuggestionsField(variants, myProject); + myCbPassOuterClass = new NonFocusableCheckBox(PASS_OUTER_CLASS_TEXT); + myCbPassOuterClass.setSelected(true); + myCbPassOuterClass.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + myParameterField.setEnabled(myCbPassOuterClass.isSelected()); + } + }); + } + else { + myParameterField = new NameSuggestionsField(new String[]{""}, myProject); + myParameterField.getComponent().setEnabled(false); + myCbPassOuterClass = new NonFocusableCheckBox(PASS_OUTER_CLASS_TEXT); + myCbPassOuterClass.setSelected(false); + myCbPassOuterClass.setEnabled(false); + myParameterField.setEnabled(false); + } + myCbSearchInComments = new NonFocusableCheckBox("Search in comments"); + myCbSearchInComments.setMnemonic('S'); + myCbSearchInNonJavaFiles = new NonFocusableCheckBox("Search in non-java files"); + myCbSearchInNonJavaFiles.setMnemonic('e'); + super.init(); + } + + public JComponent getPreferredFocusedComponent() { + return myClassNameField; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.move.moveInner.MoveInnerDialog"; + } + + protected JComponent createNorthPanel() { + Box options = Box.createVerticalBox(); + + JPanel panel = new JPanel(new BorderLayout()); + JLabel label = new JLabel("Class name:"); + label.setLabelFor(myClassNameField); + label.setDisplayedMnemonic('n'); + panel.add(label, BorderLayout.NORTH); + panel.add(myClassNameField, BorderLayout.CENTER); + options.add(panel); + + options.add(Box.createVerticalStrut(10)); + + panel = new JPanel(new BorderLayout()); + label = new JLabel("Parameter name:"); + label.setLabelFor(myParameterField.getComponent()); + label.setDisplayedMnemonic('r'); + panel.add(label, BorderLayout.NORTH); + panel.add(myParameterField.getComponent(), BorderLayout.CENTER); + options.add(panel); + + JPanel _panel = new JPanel(new BorderLayout()); + _panel.add(myCbPassOuterClass, BorderLayout.NORTH); + myCbPassOuterClass.setMnemonic('o'); + _panel.add(panel, BorderLayout.CENTER); + _panel.add(Box.createHorizontalStrut(15), BorderLayout.WEST); + options.add(_panel); + options.add(Box.createVerticalStrut(10)); + + if (myCbPassOuterClass.isEnabled()) { + final MyClassReferencesVisitor visitor = new MyClassReferencesVisitor(); + myInnerClass.accept(visitor); + myCbPassOuterClass.setSelected(visitor.myIsFound); + myParameterField.setEnabled(visitor.myIsFound); + } + + final Box searchOptions = Box.createHorizontalBox(); + searchOptions.add(myCbSearchInComments); + searchOptions.add(Box.createHorizontalStrut(10)); + searchOptions.add(myCbSearchInNonJavaFiles); + searchOptions.add(Box.createHorizontalGlue()); + options.add(searchOptions); + + myCbPassOuterClass.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + boolean selected = myCbPassOuterClass.isSelected(); + myParameterField.getComponent().setEnabled(selected); + } + }); + + panel = new JPanel(new BorderLayout()); + panel.add(options, BorderLayout.CENTER); + return panel; + } + + protected JComponent createCenterPanel() { + return null; + } + + protected void doAction() { + String message = null; + final String className = getClassName(); + PsiManager manager = PsiManager.getInstance(myProject); + if ("".equals(className)) { + message = "No class name specified"; + } + else if (!manager.getNameHelper().isIdentifier(className)) { + message = RefactoringMessageUtil.getIncorrectIdentifierMessage(className); + } + else { + if (myCbPassOuterClass.isSelected()) { + String parameterName = getParameterName(); + if ("".equals(parameterName)) { + message = "No parameter name specified"; + } + else if (!manager.getNameHelper().isIdentifier(parameterName)) { + message = RefactoringMessageUtil.getIncorrectIdentifierMessage(parameterName); + } + } + if (message == null) { + PsiElement targetContainer = MoveInnerImpl.getTargetContainer(myInnerClass); + if (targetContainer instanceof PsiClass) { + PsiClass targetClass = (PsiClass)targetContainer; + PsiClass[] classes = targetClass.getInnerClasses(); + if (classes != null) { + for (int idx = 0; idx < classes.length; idx++) { + PsiClass aClass = classes[idx]; + if (className.equals(aClass.getName())) { + message = + "Inner class named '" + className + "' is already defined\n" + + "in the class " + targetClass.getName(); + break; + } + } + } + } + else if (targetContainer instanceof PsiDirectory) { + message = RefactoringMessageUtil.checkCanCreateClass((PsiDirectory)targetContainer, className); + } + } + } + + if (message != null) { + RefactoringMessageUtil.showErrorMessage( + MoveInnerImpl.REFACTORING_NAME, + message, + HelpID.MOVE_INNER_UPPER, + myProject); + return; + } + + RefactoringSettings.getInstance().MOVE_INNER_PREVIEW_USAGES = isPreviewUsages(); + if (myCbPassOuterClass.isSelected() && mySuggestedNameInfo != null) { + mySuggestedNameInfo.nameChoosen(getParameterName()); + } + + myProcessor.run(this); + } + + class MyClassReferencesVisitor extends PsiRecursiveElementVisitor { + boolean myIsFound = false; + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (expression.getQualifierExpression() != null) { + expression.getQualifierExpression().accept(this); + } + else { + final PsiElement psiElement = expression.resolve(); + if (psiElement instanceof PsiMember && !((PsiMember)psiElement).hasModifierProperty(PsiModifier.STATIC)) { + final PsiClass containingClass = ((PsiMember)psiElement).getContainingClass(); + if (InheritanceUtil.isInheritorOrSelf(myOuterClass, containingClass, true)) { + myIsFound = true; + } + } + } + } + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.MOVE_INNER_UPPER); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java new file mode 100644 index 00000000000..00eef67b24a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java @@ -0,0 +1,59 @@ +/** + * created at Nov 12, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveInner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +public class MoveInnerImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveInner.MoveInnerImpl"); + + public static final String REFACTORING_NAME = "Move Inner to Upper Level"; + + public static void doMove(final Project project, PsiElement[] elements, final MoveCallback moveCallback) { + if (elements.length != 1) return; + final PsiClass aClass = (PsiClass) elements[0]; + boolean condition = aClass.getParent() instanceof PsiClass; + LOG.assertTrue(condition); + + if (!aClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, aClass); + return; + } + + + final MoveInnerDialog dialog = new MoveInnerDialog( + project, + aClass, + new MoveInnerProcessor(project, moveCallback) + ); + dialog.show(); + + } + + /** + * must be called in atomic action + */ + public static PsiElement getTargetContainer(PsiClass innerClass) { + PsiElement outerClassParent = innerClass.getParent().getParent(); + while (outerClassParent != null) { + if (outerClassParent instanceof PsiClass && !(outerClassParent instanceof PsiAnonymousClass)) { + return outerClassParent; + } else if (outerClassParent instanceof PsiFile) { + return innerClass.getContainingFile().getContainingDirectory(); + } + outerClassParent = outerClassParent.getParent(); + } + // should not happen + LOG.assertTrue(false); + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java new file mode 100644 index 00000000000..51518f784e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java @@ -0,0 +1,506 @@ +/** + * created at Sep 24, 2001 + * @author Jeka + */ + +package com.intellij.refactoring.move.moveInner; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +public class MoveInnerProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveInner.MoveInnerProcessor"); + + private MoveCallback myMoveCallback; + + private PsiClass myInnerClass; + private PsiClass myOuterClass; + private PsiElement myTargetContainer; + private String myParameterNameOuterClass; + private String myFieldNameOuterClass; + private String myDescriptiveName = ""; + private String myNewClassName; + private boolean myPreviewUsages; + private boolean mySearchInComments; + private boolean mySearchInNonJavaFiles; + private UsageInfo[] myUsagesAfterRefactoring; + + public MoveInnerProcessor(Project project, MoveCallback moveCallback) { + super(project); + myMoveCallback = moveCallback; + } + + public MoveInnerProcessor(Project project, PsiClass innerClass, String name, boolean passOuterClass, String parameterName) { + super(project); + setup(innerClass, name, passOuterClass, parameterName, true, true, true); + } + + protected String getCommandName() { + return "Moving inner class " + myDescriptiveName; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new MoveInnerViewDescriptor(myInnerClass, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + PsiManager manager = PsiManager.getInstance(myProject); + PsiSearchHelper helper = manager.getSearchHelper(); + + PsiReference[] innerClassRefs = helper.findReferences(myInnerClass, GlobalSearchScope.projectScope(myProject), false); + ArrayList usageInfos = new ArrayList(innerClassRefs.length); + for (int idx = 0; idx < innerClassRefs.length; idx++) { + PsiElement ref = innerClassRefs[idx].getElement(); + if (!PsiTreeUtil.isAncestor(myInnerClass, ref, true)) { // do not show self-references + usageInfos.add(new UsageInfo(ref)); + } + } + + final String newQName; + if (myTargetContainer instanceof PsiDirectory) { + final PsiDirectory targetDirectory = ((PsiDirectory)myTargetContainer); + final PsiPackage aPackage = targetDirectory.getPackage(); + LOG.assertTrue(aPackage != null); + newQName = aPackage.getQualifiedName() + "." + myNewClassName; + } + else if (myTargetContainer instanceof PsiClass) { + final String qName = ((PsiClass)myTargetContainer).getQualifiedName(); + if (qName != null) { + newQName = qName + "." + myNewClassName; + } + else { + newQName = myNewClassName; + } + } + else { + newQName = myNewClassName; + } + MoveClassesOrPackagesUtil.findNonCodeUsages(mySearchInComments, mySearchInNonJavaFiles, + myInnerClass, newQName, usageInfos); + UsageInfo[] usages = usageInfos.toArray(new UsageInfo[usageInfos.size()]); + return usages; + } + + protected void refreshElements(PsiElement[] elements) { + boolean condition = elements.length == 1 && elements[0] instanceof PsiClass; + LOG.assertTrue(condition); + myInnerClass = (PsiClass)elements[0]; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myPreviewUsages; + if (UsageViewUtil.hasReadOnlyUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + return toPreview; + } + + public boolean isSearchInComments() { + return mySearchInComments; + } + + public void setSearchInComments(boolean searchInComments) { + mySearchInComments = searchInComments; + } + + public boolean isSearchInNonJavaFiles() { + return mySearchInNonJavaFiles; + } + + public void setSearchInNonJavaFiles(boolean searchInNonJavaFiles) { + mySearchInNonJavaFiles = searchInNonJavaFiles; + } + + + protected void performRefactoring(final UsageInfo[] usages) { + PsiManager manager = PsiManager.getInstance(myProject); + final PsiElementFactory factory = manager.getElementFactory(); + + final RefactoringElementListener elementListener = getTransaction().getElementListener(myInnerClass); + String newClassName = myNewClassName; + try { + PsiField field = null; + if (myParameterNameOuterClass != null) { + // pass outer as a parameter + field = factory.createField(myFieldNameOuterClass, factory.createType(myOuterClass)); + field = (PsiField)myInnerClass.add(field); + addFieldInitializationToConstructors(myInnerClass, field, myParameterNameOuterClass); + } + + ChangeContextUtil.encodeContextInfo(myInnerClass, false); + + PsiClass newClass; + if (myTargetContainer instanceof PsiDirectory) { + newClass = ((PsiDirectory)myTargetContainer).createClass(newClassName); + PsiDocComment defaultDocComment = newClass.getDocComment(); + if (defaultDocComment != null) { + defaultDocComment = (PsiDocComment)defaultDocComment.copy(); + } + newClass = (PsiClass)newClass.replace(myInnerClass); + if (defaultDocComment != null && myInnerClass.getDocComment() == null) { + newClass.addBefore(defaultDocComment, newClass.getFirstChild()); + } + + newClass.getModifierList().setModifierProperty(PsiModifier.STATIC, false); + newClass.getModifierList().setModifierProperty(PsiModifier.PRIVATE, false); + newClass.getModifierList().setModifierProperty(PsiModifier.PROTECTED, false); + if (myOuterClass.isInterface()) { + newClass.getModifierList().setModifierProperty(PsiModifier.PUBLIC, true); + } + + } + else { + newClass = (PsiClass)myTargetContainer.add(myInnerClass); + } + newClass.setName(newClassName); + + // replace references in a new class to old inner class with references to itself + PsiReference[] refs = manager.getSearchHelper().findReferences(myInnerClass, new LocalSearchScope(newClass), + true); + for (int idx = 0; idx < refs.length; idx++) { + PsiElement ref = refs[idx].getElement(); + if (ref.getParent() instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement parentRef = (PsiJavaCodeReferenceElement)ref.getParent(); + PsiElement parentRefElement = parentRef.resolve(); + if (parentRefElement instanceof PsiClass) { // reference to inner class inside our inner + parentRef.getFirstChild().delete(); + continue; + } + } + ref.getReference().bindToElement(newClass); + } + + myInnerClass.delete(); + + // correct references in usages + for (int idx = 0; idx < usages.length; idx++) { + UsageInfo usage = usages[idx]; + if (usage.isNonCodeUsage) continue; + PsiElement ref = usage.getElement(); + if (myParameterNameOuterClass != null) { // should pass outer as parameter + PsiElement refParent = ref.getParent(); + if (refParent instanceof PsiNewExpression || refParent instanceof PsiAnonymousClass) { + PsiNewExpression newExpr = refParent instanceof PsiNewExpression + ? (PsiNewExpression)refParent + : (PsiNewExpression)refParent.getParent(); + + PsiExpressionList argList = newExpr.getArgumentList(); + + if (argList != null) { // can happen in incomplete code + if (newExpr.getQualifier() == null) { + PsiThisExpression thisExpr; + PsiClass parentClass = RefactoringUtil.getThisClass(newExpr); + if (myOuterClass.equals(parentClass)) { + thisExpr = RefactoringUtil.createThisExpression(manager, null); + } + else { + thisExpr = RefactoringUtil.createThisExpression(manager, myOuterClass); + } + argList.addAfter(thisExpr, null); + } + else { + argList.addAfter(newExpr.getQualifier(), null); + newExpr.getQualifier().delete(); + } + } + } + } + ref.getReference().bindToElement(newClass); + } + + if (field != null) { + PsiExpression accessExpression = factory.createExpressionFromText(myFieldNameOuterClass, null); + ChangeContextUtil.decodeContextInfo(newClass, myOuterClass, accessExpression); + } + else { + ChangeContextUtil.decodeContextInfo(newClass, null, null); + } + + PsiFile targetFile = newClass.getContainingFile(); + OpenFileDescriptor descriptor = new OpenFileDescriptor(myProject, targetFile.getVirtualFile(), newClass.getTextOffset()); + FileEditorManager.getInstance(myProject).openTextEditor(descriptor, true); + + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + elementListener.elementMoved(newClass); + + myUsagesAfterRefactoring = usages; + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + protected void performPsiSpoilingRefactoring() { + if (myUsagesAfterRefactoring != null) { + RefactoringUtil.renameNonCodeUsages(myProject, myUsagesAfterRefactoring); + } + } + + protected boolean preprocessUsages(UsageInfo[][] u) { + final ArrayList conflicts = new ArrayList(); + + class Visitor extends PsiRecursiveElementVisitor { + private final com.intellij.util.containers.HashMap reported = new com.intellij.util.containers.HashMap(); + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + PsiElement resolved = reference.resolve(); + final boolean isInInnerClass; + + final PsiManager manager = myOuterClass.getManager(); + if (resolved instanceof PsiField) { + isInInnerClass = manager.areElementsEquivalent(((PsiField)resolved).getContainingClass(), myInnerClass); + } + else if (resolved instanceof PsiMethod) { + isInInnerClass = manager.areElementsEquivalent(((PsiMethod)resolved).getContainingClass(), myInnerClass); + } + else { + isInInnerClass = false; + } + + if (isInInnerClass && + resolved instanceof PsiModifierListOwner && becomesInaccessible(((PsiModifierListOwner)resolved))) { + final PsiElement container = ConflictsUtil.getContainer(reference); + HashSet containerSet = (HashSet)reported.get(resolved); + if (containerSet == null) { + containerSet = new HashSet(); + reported.put(resolved, containerSet); + } + if (!containerSet.contains(container)) { + containerSet.add(container); + String message = ConflictsUtil.getDescription(resolved, true) + " will become inaccessible from " + + ConflictsUtil.getDescription(container, true) + "."; + conflicts.add(message); + } + } + } + + private boolean becomesInaccessible(PsiModifierListOwner element) { + final String visibilityModifier = VisibilityUtil.getVisibilityModifier(element.getModifierList()); + if (PsiModifier.PRIVATE.equals(visibilityModifier)) return true; + if (PsiModifier.PUBLIC.equals(visibilityModifier)) return false; + final PsiFile containingFile = myOuterClass.getContainingFile(); + if (myTargetContainer instanceof PsiPackage) { + return !isInPackage(containingFile, (PsiPackage)myTargetContainer); + } + else { // target container is a class + PsiFile targetFile = myTargetContainer.getContainingFile(); + if (targetFile != null) { + final PsiDirectory containingDirectory = targetFile.getContainingDirectory(); + if (containingDirectory != null) { + final PsiPackage targetPackage = containingDirectory.getPackage(); + return isInPackage(containingFile, targetPackage); + } + } + } + return false; + } + + + public void visitClass(PsiClass aClass) { + if (aClass == myInnerClass) return; + super.visitClass(aClass); + } + } + +// if (myInnerClass.hasModifierProperty(PsiModifier.)) { + myOuterClass.accept(new Visitor()); + + RefactoringUtil.analyzeModuleConflicts(myProject, Collections.singletonList(myInnerClass), myTargetContainer, conflicts); + + return showConflicts(conflicts, u); + } + + private static boolean isInPackage(final PsiFile containingFile, PsiPackage aPackage) { + if (containingFile != null) { + final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + if (containingDirectory != null) { + PsiPackage filePackage = containingDirectory.getPackage(); + if (filePackage != null && !filePackage.getQualifiedName().equals( + aPackage.getQualifiedName())) { + return false; + } + } + } + return true; + } + + public void run(final MoveInnerDialog dialog) { + myPrepareSuccessfulSwingThreadCallback = new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }; + + final boolean previewUsages = dialog.isPreviewUsages(); + final String className = dialog.getClassName(); + final PsiClass innerClass = dialog.getInnerClass(); + final boolean passOuterClass = dialog.isPassOuterClass(); + final String parameterName = dialog.getParameterName(); + + setup(innerClass, className, passOuterClass, parameterName, previewUsages, + dialog.isSearchInComments(), dialog.isSearchInNonJavaFiles()); + + run((Object)null); + } + + public void setup(final PsiClass innerClass, + final String className, + final boolean passOuterClass, + final String parameterName, + final boolean previewUsages, + boolean searchInComments, + boolean searchInNonJava) { + myPreviewUsages = previewUsages; + myNewClassName = className; + myInnerClass = innerClass; + myDescriptiveName = UsageViewUtil.getDescriptiveName(myInnerClass); + myOuterClass = myInnerClass.getContainingClass(); + myTargetContainer = MoveInnerImpl.getTargetContainer(myInnerClass); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + myParameterNameOuterClass = passOuterClass ? parameterName : null; + if (myParameterNameOuterClass != null) { + myFieldNameOuterClass = + codeStyleManager.variableNameToPropertyName(myParameterNameOuterClass, VariableKind.PARAMETER); + myFieldNameOuterClass = codeStyleManager.propertyNameToVariableName(myFieldNameOuterClass, VariableKind.FIELD); + } + mySearchInComments = searchInComments; + mySearchInNonJavaFiles = searchInNonJava; + } + + private void addFieldInitializationToConstructors(PsiClass aClass, PsiField field, String parameterName) + throws IncorrectOperationException { + + PsiMethod[] constructors = aClass.getConstructors(); + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + if (constructors.length > 0) { + for (int idx = 0; idx < constructors.length; idx++) { + PsiMethod constructor = constructors[idx]; + if (parameterName != null) { + PsiParameterList parameterList = constructor.getParameterList(); + PsiParameter parameter = factory.createParameter(parameterName, field.getType()); + parameterList.addAfter(parameter, null); + } + PsiCodeBlock body = constructor.getBody(); + if (body == null) continue; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + String text = ((PsiMethodCallExpression)expression).getMethodExpression().getText(); + if ("this".equals(text)) { + continue; + } + } + } + } + createAssignmentStatement(constructor, field.getName(), parameterName); + } + } + else { + PsiMethod constructor = factory.createConstructor(); + if (parameterName != null) { + PsiParameterList parameterList = constructor.getParameterList(); + PsiParameter parameter = factory.createParameter(parameterName, field.getType()); + parameterList.add(parameter); + } + createAssignmentStatement(constructor, field.getName(), parameterName); + aClass.add(constructor); + } + } + + private PsiStatement createAssignmentStatement(PsiMethod constructor, String fieldname, String parameterName) + throws IncorrectOperationException { + + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + String pattern = fieldname + "=a;"; + if (fieldname.equals(parameterName)) { + pattern = "this." + pattern; + } + + PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null); + statement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(statement); + + PsiCodeBlock body = constructor.getBody(); + statement = (PsiExpressionStatement)body.addAfter(statement, getAnchorElement(body)); + + PsiAssignmentExpression assignment = (PsiAssignmentExpression)statement.getExpression(); + PsiReferenceExpression rExpr = (PsiReferenceExpression)assignment.getRExpression(); + PsiIdentifier identifier = (PsiIdentifier)rExpr.getReferenceNameElement(); + identifier.replace(factory.createIdentifier(parameterName)); + return statement; + } + + private static PsiElement getAnchorElement(PsiCodeBlock body) { + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + PsiStatement first = statements[0]; + if (first instanceof PsiExpressionStatement) { + + PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + PsiReferenceExpression methodCall = ((PsiMethodCallExpression)expression).getMethodExpression(); + String text = methodCall.getText(); + if ("super".equals(text)) { + return first; + } + } + } + } + return null; + } + + public PsiClass getInnerClass() { + return myInnerClass; + } + + public String getNewClassName() { + return myNewClassName; + } + + public boolean shouldPassParameter() { + return myParameterNameOuterClass != null; + } + + + public String getParameterName() { + return myParameterNameOuterClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerViewDescriptor.java new file mode 100644 index 00000000000..abb4a580979 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveInner/MoveInnerViewDescriptor.java @@ -0,0 +1,101 @@ +/** + * created at Sep 11, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveInner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class MoveInnerViewDescriptor implements UsageViewDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveInner.MoveInnerViewDescriptor"); + + private PsiClass myInnerClass; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public MoveInnerViewDescriptor(PsiClass innerClass, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myInnerClass = innerClass; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public PsiElement[] getElements() { + return new PsiElement[] {myInnerClass}; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + // TODO + if (elements.length == 1 && elements[0] instanceof PsiClass) { + myInnerClass = (PsiClass)elements[0]; + } + else { + // should not happen + LOG.assertTrue(false); + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return null; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References to change " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMemberViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMemberViewDescriptor.java new file mode 100644 index 00000000000..e3f7eda079d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMemberViewDescriptor.java @@ -0,0 +1,92 @@ +/** + * created at Sep 11, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveMembers; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class MoveMemberViewDescriptor implements UsageViewDescriptor { + private PsiElement[] myElementsToMove; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public MoveMemberViewDescriptor(PsiElement[] elementsToMove, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myElementsToMove = elementsToMove; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public PsiElement[] getElements() { + return myElementsToMove; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + for (int idx = 0; idx < elements.length; idx++) { + myElementsToMove[idx] = elements[idx]; + } + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return "Members to be moved"; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References to be changed " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java new file mode 100644 index 00000000000..fab738a947d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java @@ -0,0 +1,373 @@ +package com.intellij.refactoring.move.moveMembers; + +import com.intellij.ide.util.PackageUtil; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.MemberSelectionTable; +import com.intellij.refactoring.ui.VisibilityPanel; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoChange; +import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Set; + +public class MoveMembersDialog extends RefactoringDialog implements MoveMembersOptions { + private MyMemberInfoModel myMemberInfoModel; + + public static interface Callback { + void invoke(MoveMembersDialog dialog); + } + + private Project myProject; + private Callback myCallback; + private PsiClass mySourceClass; + private String mySourceClassName; + private MemberInfo[] myMemberInfos; + private final TextFieldWithBrowseButton myTfTargetClassName; + private MemberSelectionTable myTable; + private Set myPreselectMembers; + + VisibilityPanel myVisibilityPanel; + + public MoveMembersDialog(Project project, PsiClass sourceClass, final PsiClass initialTargetClass, + Set preselectMembers, Callback callback) { + + + super(project, true); + myProject = project; + myCallback = callback; + mySourceClass = sourceClass; + myPreselectMembers = preselectMembers; + setTitle(MoveMembersImpl.REFACTORING_NAME); + + mySourceClassName = mySourceClass.getQualifiedName(); + + PsiField[] fields = mySourceClass.getFields(); + PsiMethod[] methods = mySourceClass.getMethods(); + PsiClass[] innerClasses = mySourceClass.getInnerClasses(); + ArrayList memberList = new ArrayList(fields.length + methods.length); + + for (int idx = 0; idx < innerClasses.length; idx++) { + PsiClass innerClass = innerClasses[idx]; + if (!innerClass.hasModifierProperty(PsiModifier.STATIC)) continue; + MemberInfo info = new MemberInfo(innerClass); + if (myPreselectMembers.contains(innerClass)) { + info.setChecked(true); + } + memberList.add(info); + } + for (int idx = 0; idx < fields.length; idx++) { + PsiField field = fields[idx]; + if (field.hasModifierProperty(PsiModifier.STATIC)) { + MemberInfo info = new MemberInfo(field); + if (myPreselectMembers.contains(field)) { + info.setChecked(true); + } + memberList.add(info); + } + } + for (int idx = 0; idx < methods.length; idx++) { + PsiMethod method = methods[idx]; + if (method.hasModifierProperty(PsiModifier.STATIC)) { + MemberInfo info = new MemberInfo(method); + if (myPreselectMembers.contains(method)) { + info.setChecked(true); + } + memberList.add(info); + } + } + myMemberInfos = memberList.toArray(new MemberInfo[memberList.size()]); + myTfTargetClassName = new TextFieldWithBrowseButton(new ChooseClassAction()); + + init(); + + if (initialTargetClass != null && !sourceClass.equals(initialTargetClass)) { + myTfTargetClassName.setText(initialTargetClass.getQualifiedName()); + } + } + + public String getMemberVisibility() { + return myVisibilityPanel.getVisibility(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.move.moveMembers.MoveMembersDialog"; + } + + private JTable createTable() { + myMemberInfoModel = new MyMemberInfoModel(); + myTable = new MemberSelectionTable(myMemberInfos, null); + myTable.setMemberInfoModel(myMemberInfoModel); + myTable.addMemberInfoChangeListener(myMemberInfoModel); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + return myTable; + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + + JPanel _panel; + Box box = Box.createVerticalBox(); + + _panel = new JPanel(new BorderLayout()); + JTextField sourceClassField = new JTextField(); + sourceClassField.setText(mySourceClassName); + sourceClassField.setEditable(false); + _panel.add(new JLabel("Move members from:"), BorderLayout.NORTH); + _panel.add(sourceClassField, BorderLayout.CENTER); + box.add(_panel); + + box.add(Box.createVerticalStrut(10)); + + _panel = new JPanel(new BorderLayout()); + JLabel label = new JLabel("To (fully qualified name):"); + label.setLabelFor(myTfTargetClassName); + _panel.add(label, BorderLayout.NORTH); + _panel.add(myTfTargetClassName, BorderLayout.CENTER); + box.add(_panel); + + myTfTargetClassName.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + myMemberInfoModel.updateTargetClass(); + } + }); + + panel.add(box, BorderLayout.CENTER); + panel.add(Box.createVerticalStrut(10), BorderLayout.SOUTH); + + return panel; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + JTable table = createTable(); + if (table.getRowCount() > 0) { + table.getSelectionModel().addSelectionInterval(0, 0); + } + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table); + Border titledBorder = IdeBorderFactory.createTitledBorder("Members to be moved (static only)"); + Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5); + Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder); + scrollPane.setBorder(border); + panel.add(scrollPane, BorderLayout.CENTER); + + myVisibilityPanel = new VisibilityPanel(true); + myVisibilityPanel.setVisibility(null); + panel.add(myVisibilityPanel, BorderLayout.EAST); + + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myTfTargetClassName.getTextField(); + } + + public PsiMember[] getSelectedMembers() { + final MemberInfo[] selectedMemberInfos = myTable.getSelectedMemberInfos(); + ArrayList list = new ArrayList(); + for (int i = 0; i < selectedMemberInfos.length; i++) { + list.add(selectedMemberInfos[i].getMember()); + } + return list.toArray(new PsiMember[list.size()]); + } + + public String getTargetClassName() { + return myTfTargetClassName.getText(); + } + + protected void doAction() { + String message = validateInputData(); + + if (message != null) { + if (message.length() != 0) { + RefactoringMessageUtil.showErrorMessage( + MoveMembersImpl.REFACTORING_NAME, + message, + HelpID.MOVE_MEMBERS, + myProject); + } + return; + } + + myCallback.invoke(this); + RefactoringSettings.getInstance().MOVE_PREVIEW_USAGES = isPreviewUsages(); + } + + private String validateInputData() { + final PsiManager manager = PsiManager.getInstance(myProject); + final String fqName = getTargetClassName(); + if ("".equals(fqName)) { + return "No destination class specified"; + } + else if (!manager.getNameHelper().isQualifiedName(fqName)) { + return "'" + fqName + "' is not a legal FQ-name"; + } + else { + final PsiClass[] targetClass = new PsiClass[]{null}; + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + try { + targetClass[0] = findOrCreateTargetClass(manager, fqName); + } + catch (IncorrectOperationException e) { + RefactoringMessageUtil.showErrorMessage( + MoveMembersImpl.REFACTORING_NAME, + e.getMessage(), + HelpID.MOVE_MEMBERS, + myProject); + } + } + + }, "Create class " + fqName, null); + + if (targetClass[0] == null) { + return ""; + } + + if (mySourceClass.equals(targetClass[0])) { + return "Source and destination classes should be different"; + } + else { + for (int i = 0; i < myMemberInfos.length; i++) { + MemberInfo info = myMemberInfos[i]; + if (!info.isChecked()) continue; + if (PsiTreeUtil.isAncestor(info.getMember(), targetClass[0], false)) { + return "Cannot move inner class " + info.getDisplayName() + " into itself."; + } + } + + if (!targetClass[0].isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, targetClass[0]); + return ""; +// return "Cannot perform the refactoring.\nDestination class " + targetClass[0].getQualifiedName() + " is read-only."; + } + + return null; + } + } + } + + private PsiClass findOrCreateTargetClass(final PsiManager manager, final String fqName) throws IncorrectOperationException { + final String className; + final String packageName; + int dotIndex = fqName.lastIndexOf('.'); + if (dotIndex >= 0) { + packageName = fqName.substring(0, dotIndex); + className = (dotIndex + 1 < fqName.length())? fqName.substring(dotIndex + 1) : ""; + } + else { + packageName = ""; + className = fqName; + } + + + PsiClass aClass = manager.findClass(fqName, GlobalSearchScope.projectScope(myProject)); + if (aClass != null) return aClass; + + final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage( + myProject, + packageName, + mySourceClass.getContainingFile().getContainingDirectory(), + true); + + if (directory == null) { + return null; + } + + int answer = Messages.showYesNoDialog( + myProject, + "Class " + fqName + " does not exist.\nDo you want to create it?", + MoveMembersImpl.REFACTORING_NAME, + Messages.getQuestionIcon() + ); + if (answer != 0) return null; + final Ref eRef = new Ref(); + final PsiClass newClass = ApplicationManager.getApplication().runWriteAction(new Computable() { + public PsiClass compute() { + try { + return directory.createClass(className); + } + catch (IncorrectOperationException e) { + eRef.set(e); + return null; + } + } + }); + if (!eRef.isNull()) throw eRef.get(); + return newClass; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.MOVE_MEMBERS); + } + + private class ChooseClassAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + TreeClassChooserDialog chooser = TreeClassChooserDialog.withInnerClasses("Choose Destination Class", myProject, GlobalSearchScope.projectScope(myProject), new TreeClassChooserDialog.ClassFilter() { + public boolean isAccepted(PsiClass aClass) { + return aClass.getParent() instanceof PsiJavaFile || aClass.hasModifierProperty(PsiModifier.STATIC); + } + }, null); + chooser.selectDirectory(mySourceClass.getContainingFile().getContainingDirectory()); + chooser.show(); + PsiClass aClass = chooser.getSelectedClass(); + if (aClass != null) { + myTfTargetClassName.setText(aClass.getQualifiedName()); + myMemberInfoModel.updateTargetClass(); + } + } + } + + private class MyMemberInfoModel extends UsesAndInterfacesDependencyMemberInfoModel { + PsiClass myTargetClass = null; + public MyMemberInfoModel() { + super(mySourceClass, null, false, DEFAULT_CONTAINMENT_VERIFIER); + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return false; + } + + public boolean isMemberEnabled(MemberInfo member) { + if(myTargetClass != null && myTargetClass.isInterface()) { + return !(member.getMember() instanceof PsiMethod); + } + return super.isMemberEnabled(member); + } + + public void updateTargetClass() { + final PsiManager manager = PsiManager.getInstance(myProject); + myTargetClass = manager.findClass(getTargetClassName(), GlobalSearchScope.projectScope(myProject)); + myTable.fireExternalDataChange(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersImpl.java new file mode 100644 index 00000000000..a6c74daec33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersImpl.java @@ -0,0 +1,105 @@ +/** + * created at Nov 21, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveMembers; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import java.util.HashSet; +import java.util.Set; + +public class MoveMembersImpl { + public static final String REFACTORING_NAME = "Move Members"; + + /** + * element should be either not anonymous PsiClass whose members should be moved + * or PsiMethod of a non-anonymous PsiClass + * or PsiField of a non-anonymous PsiClass + * or Inner PsiClass + */ + public static void doMove(final Project project, PsiElement[] elements, PsiElement targetContainer, MoveCallback moveCallback) { + if (elements.length == 0) { + return; + } + final PsiClass sourceClass; + if (elements[0].getParent() instanceof PsiClass) { + sourceClass = (PsiClass) elements[0].getParent(); + } else { + return; + } + final Set preselectMembers = new HashSet(); + for (int idx = 0; idx < elements.length; idx++) { + PsiElement element = elements[idx]; + if (!sourceClass.equals(element.getParent())) { + String message = "Cannot perform the refactoring.\nMembers to be moved should belong to the same class."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, project); + return; + } + if (element instanceof PsiField) { + PsiField field = (PsiField) element; + if (!field.hasModifierProperty(PsiModifier.STATIC)) { + String fieldName = PsiFormatUtil.formatVariable( + field, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, + PsiSubstitutor.EMPTY); + String message = "Field " + fieldName + " is not static.\n" + + REFACTORING_NAME + " refactoring is supported for static members only."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, project); + return; + } + preselectMembers.add(field); + } else if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod) element; + String methodName = PsiFormatUtil.formatMethod( + method, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + if (method.isConstructor()) { + String message = REFACTORING_NAME + " refactoring cannot be applied to constructors"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, project); + return; + } + if (!method.hasModifierProperty(PsiModifier.STATIC)) { + String message = "Method " + methodName + " is not static.\n" + + REFACTORING_NAME + " refactoring is supported for static members only."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, project); + return; + } + preselectMembers.add(method); + } else if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass) element; + if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { + String message = "Inner class " + aClass.getQualifiedName() + " is not static.\n" + + REFACTORING_NAME + " refactoring is supported for static members only."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, project); + return; + } + preselectMembers.add(aClass); + } + } + + if (!sourceClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, sourceClass); + return; + } + + final MoveMembersProcessor callback = new MoveMembersProcessor(project, moveCallback); + final PsiClass initialTargerClass = targetContainer instanceof PsiClass? (PsiClass) targetContainer : (PsiClass) null; + + MoveMembersDialog dialog = new MoveMembersDialog( + project, + sourceClass, + initialTargerClass, + preselectMembers, + callback + ); + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersOptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersOptions.java new file mode 100644 index 00000000000..3691fa6da94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersOptions.java @@ -0,0 +1,18 @@ +package com.intellij.refactoring.move.moveMembers; + +import com.intellij.psi.PsiMember; + +/** + * @author dyoma + */ +public interface MoveMembersOptions { + PsiMember[] getSelectedMembers(); + + String getTargetClassName(); + + String getMemberVisibility(); + + boolean isPreviewUsages(); + + void close(int exitCode); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java new file mode 100644 index 00000000000..52479ae7427 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java @@ -0,0 +1,497 @@ +/** + * created at Sep 11, 2001 + * @author Jeka + */ +package com.intellij.refactoring.move.moveMembers; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.*; + +public class MoveMembersProcessor extends BaseRefactoringProcessor implements MoveMembersDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveMembers.MoveMembersProcessor"); + + private PsiClass myTargetClass; + private MoveMembersOptions myDialog; + private LinkedHashSet myMembersToMove = new LinkedHashSet(); + private MoveCallback myMoveCallback; + private String myNewVisibility; // "null" means "as is" + + public MoveMembersProcessor(Project project, MoveCallback moveCallback) { + super(project); + myMoveCallback = moveCallback; + } + + public MoveMembersProcessor(Project project, MoveMembersOptions options) { + super(project); + setOptions(options); + } + + protected String getCommandName() { + return MoveMembersImpl.REFACTORING_NAME; + } + + public void invoke(final MoveMembersDialog dialog) { + setOptions(dialog); + setPrepareSuccessfulSwingThreadCallback(new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + run(null); + } + + public void testRun(MoveMembersOptions dialog) { + setOptions(dialog); + super.testRun(); + } + + private void setOptions(MoveMembersOptions dialog) { + myDialog = dialog; + PsiMember[] members = myDialog.getSelectedMembers(); + myMembersToMove.clear(); + for (int idx = 0; idx < members.length; idx++) { + myMembersToMove.add(members[idx]); + } + final PsiManager manager = PsiManager.getInstance(myProject); + myTargetClass = manager.findClass(myDialog.getTargetClassName(), GlobalSearchScope.allScope(myProject)); + myNewVisibility = dialog.getMemberVisibility(); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new MoveMemberViewDescriptor(myMembersToMove.toArray(new PsiElement[myMembersToMove.size()]), usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + final PsiManager manager = PsiManager.getInstance(myProject); + final PsiSearchHelper helper = manager.getSearchHelper(); + final List usagesList = new ArrayList(); + for (Iterator it = myMembersToMove.iterator(); it.hasNext();) { + PsiMember member = it.next(); + PsiReference[] refs = helper.findReferences(member, GlobalSearchScope.projectScope(myProject), false); + for (int i = 0; i < refs.length; i++) { + PsiElement ref = refs[i].getElement(); + if (ref instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)ref; + PsiExpression qualifier = refExpr.getQualifierExpression(); + if (RefactoringHierarchyUtil.willBeInTargetClass(refExpr, myMembersToMove, myTargetClass, true)) { + // both member and the reference to it will be in target class + if (!isInMovedElement(refExpr)) { + if (qualifier != null) { + usagesList.add(new MyUsageInfo(member, refExpr, null, qualifier)); // remove qualifier + } + } else { + if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).isReferenceTo(member.getContainingClass())) { + usagesList.add(new MyUsageInfo(member, refExpr, null, qualifier)); // change qualifier + } + } + } + else { + // member in target class, the reference will be outside target class + if (qualifier == null) { + usagesList.add(new MyUsageInfo(member, refExpr, myTargetClass, refExpr)); // add qualifier + } + else { + usagesList.add(new MyUsageInfo(member, refExpr, myTargetClass, qualifier)); // change qualifier + } + } + } + else { + if (!isInMovedElement(ref)) { + usagesList.add(new MyUsageInfo(member, ref, null, ref)); + } + } + } + } + UsageInfo[] usageInfos = usagesList.toArray(new UsageInfo[usagesList.size()]); + usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos); + return usageInfos; + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(myMembersToMove.size() == elements.length); + myMembersToMove.clear(); + for (int idx = 0; idx < elements.length; idx++) { + myMembersToMove.add((PsiMember)elements[idx]); + } + } + + private boolean isInMovedElement(PsiElement element) { + PsiElement parent = element; + while (parent != null) { + if (parent instanceof PsiFile) break; + if (parent instanceof PsiMethod || parent instanceof PsiField || parent instanceof PsiClass) { + if (myMembersToMove.contains(parent)) return true; + } + parent = parent.getParent(); + } + return false; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myDialog.isPreviewUsages(); + if (UsageViewUtil.hasReadOnlyUsages(usages)){ + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + return toPreview; + } + + protected void performRefactoring(final UsageInfo[] usages) { + try { + // correct references to moved members from the outside + ArrayList otherUsages = new ArrayList(); + for (int idx = 0; idx < usages.length; idx++) { + MyUsageInfo usage = (MyUsageInfo)usages[idx]; + if (!usage.reference.isValid()) continue; + if (usage.reference instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)usage.reference; + PsiExpression qualifier = refExpr.getQualifierExpression(); + if (qualifier != null) { + if (usage.qualifierClass != null) { + changeQualifier(refExpr, usage.qualifierClass); + } + else { + removeQualifier(refExpr); + } + } + else { // no qualifier + if (usage.qualifierClass != null) { + addQualifier(refExpr, usage.qualifierClass); + } + } + } + else { + otherUsages.add(usage); + } + } + + // correct references inside moved members and outer references to Inner Classes + for (Iterator it = myMembersToMove.iterator(); it.hasNext();) { + PsiElement member = (PsiElement)it.next(); + if (member instanceof PsiVariable) { + ((PsiVariable) member).normalizeDeclaration(); + } + final RefactoringElementListener elementListener = getTransaction().getElementListener(member); + ChangeContextUtil.encodeContextInfo(member, true); + final PsiElement memberCopy = member.copy(); + ArrayList refsToBeRebind = new ArrayList(); + for (Iterator iterator = otherUsages.iterator(); iterator.hasNext();) { + MyUsageInfo info = iterator.next(); + if (member.equals(info.member)) { + PsiReference ref = info.reference.getReference(); + if (ref != null) { + refsToBeRebind.add(ref); + } + iterator.remove(); + } + } + member.delete(); + + PsiElement newMember = myTargetClass.add(memberCopy); + + fixVisibility(newMember); + for (int i = 0; i < refsToBeRebind.size(); i++) { + PsiReference reference = refsToBeRebind.get(i); + reference.bindToElement(newMember); + } + + elementListener.elementMoved(newMember); + } + + // qualifier info must be decoded after members are moved + ChangeContextUtil.decodeContextInfo(myTargetClass, null, null); + myMembersToMove.clear(); + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private void fixVisibility(PsiElement newMember) throws IncorrectOperationException { + PsiModifierList modifierList = ((PsiModifierListOwner) newMember).getModifierList(); + + if(myTargetClass.isInterface()) { + modifierList.setModifierProperty(PsiModifier.PUBLIC, false); + modifierList.setModifierProperty(PsiModifier.PROTECTED, false); + modifierList.setModifierProperty(PsiModifier.PRIVATE, false); + return; + } + + if(myNewVisibility == null) return; + + RefactoringUtil.setVisibility(modifierList, myNewVisibility); + } + + + private void removeQualifier(PsiReferenceExpression refExpr) throws IncorrectOperationException{ + PsiIdentifier identifier = (PsiIdentifier)refExpr.getReferenceNameElement(); + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + PsiExpression expr = factory.createExpressionFromText(identifier.getText(), null); + refExpr.replace(expr); + } + + private PsiReferenceExpression addQualifier(PsiReferenceExpression refExpr, PsiClass aClass) throws IncorrectOperationException{ + PsiIdentifier identifier = (PsiIdentifier)refExpr.getReferenceNameElement(); + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + PsiReferenceExpression expr = (PsiReferenceExpression)factory.createExpressionFromText("q."+identifier.getText(), null); + expr = (PsiReferenceExpression)CodeStyleManager.getInstance(myProject).reformat(expr); + + PsiReferenceExpression qualifier = factory.createReferenceExpression(aClass); + expr.getQualifierExpression().replace(qualifier); + + if (refExpr.getParent() != null) { + return (PsiReferenceExpression) refExpr.replace(expr); + } else { + return expr; + } + } + + private void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass) throws IncorrectOperationException{ + PsiElementFactory factory = PsiManager.getInstance(myProject).getElementFactory(); + PsiReferenceExpression qualifier = factory.createReferenceExpression(aClass); + refExpr.getQualifierExpression().replace(qualifier); + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + final ArrayList conflicts = new ArrayList(); + for (Iterator iterator = myMembersToMove.iterator(); iterator.hasNext();) { + final PsiElement member = iterator.next(); + RefactoringUtil.analyzeModuleConflicts(myProject, Collections.singletonList(member), myTargetClass, conflicts); + } + return showConflicts(conflicts, usages); + } + + public void run(Object markerId) { + if (myMembersToMove.size() == 0){ + String message = "No members selected"; + RefactoringMessageUtil.showErrorMessage(MoveMembersImpl.REFACTORING_NAME, message, HelpID.MOVE_MEMBERS, myProject); + return; + } + if (canRefactor()) { + super.run(markerId); + } + } + + private boolean canRefactor() { + final String[] conflicts = analyzeMoveConflicts(myMembersToMove, myTargetClass, myNewVisibility); + if (conflicts.length > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflicts, myProject); + dialog.show(); + return dialog.isOK(); + } + return true; + } + + private static String[] analyzeMoveConflicts(final Set membersToMove, final PsiClass targetClass, String newVisibility) { + final LinkedHashSet conflicts = new LinkedHashSet(); + for (Iterator iterator = membersToMove.iterator(); iterator.hasNext();) { + final PsiMember element = iterator.next(); + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + if (hasMethod(targetClass, method)) { + String message = ConflictsUtil.getDescription(method, false) + " already exists in the target class."; + message = ConflictsUtil.capitalize(message); + conflicts.add(message); + } + } + else if (element instanceof PsiField) { + PsiField field = (PsiField)element; + if (hasField(targetClass, field)) { + String message = ConflictsUtil.getDescription(field, false) + " already exists in the target class."; + message = ConflictsUtil.capitalize(message); + conflicts.add(message); + } + } + } + return analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility); + } + + public static String[] analyzeAccessibilityConflicts(final Set membersToMove, + final PsiClass targetClass, + final LinkedHashSet conflicts, String newVisibility) { + for (Iterator it = membersToMove.iterator(); it.hasNext();) { + PsiMember member = it.next(); + + + checkUsedElements(member, member, membersToMove, targetClass, conflicts); + + PsiModifierList modifierList = (PsiModifierList)member.getModifierList().copy(); + + if(newVisibility != null) { + try { + RefactoringUtil.setVisibility(modifierList, newVisibility); + } + catch(IncorrectOperationException ex) { + /* do nothing and hope for the best */ + } + } + final boolean isMemberPublic = + modifierList.hasModifierProperty(PsiModifier.PUBLIC) + || targetClass.isInterface() + || (newVisibility != null && PsiModifier.PUBLIC.equals(newVisibility)); + if (!isMemberPublic) { + PsiManager manager = member.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + PsiReference[] references = helper.findReferences(member, projectScope, false); + for (int i = 0; i < references.length; i++) { + PsiElement ref = references[i].getElement(); + if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) { + if (!manager.getResolveHelper().isAccessible(member, modifierList, ref, null)) { + String message = ConflictsUtil.getDescription(member, true) + + " is " + getVisiblityString(member) + + " and will not be accessible from " + + ConflictsUtil.getDescription(ConflictsUtil.getContainer(ref), true) + + " when moved to the target class."; + message = ConflictsUtil.capitalize(message); + conflicts.add(message); + } + } + } + } + } + return conflicts.toArray(new String[conflicts.size()]); + } + + private static void checkUsedElements(PsiMember member, PsiElement scope, Set membersToMove, PsiClass newContext, LinkedHashSet conflicts) { + if(scope instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ + PsiExpression qualifier = refExpr.getQualifierExpression(); + PsiClass accessClass = (PsiClass) (qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); + checkAccessibility(((PsiMember)refElement), newContext, accessClass, member, conflicts); + } + } + } + else if (scope instanceof PsiNewExpression) { + final PsiMethod refElement = ((PsiNewExpression)scope).resolveConstructor(); + if (refElement != null) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)) { + checkAccessibility(refElement, newContext, null, member, conflicts); + } + } + } + else if (scope instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ + checkAccessibility(((PsiMember)refElement), newContext, null, member, conflicts); + } + } + } + + PsiElement[] children = scope.getChildren(); + for (int idx = 0; idx < children.length; idx++) { + PsiElement child = children[idx]; + if (!(child instanceof PsiWhiteSpace)) { + checkUsedElements(member, child, membersToMove, newContext, conflicts); + } + } + } + + private static void checkAccessibility(PsiMember refMember, + PsiClass newContext, + PsiClass accessClass, + PsiMember member, + LinkedHashSet conflicts) { + if (!PsiUtil.isAccessible(refMember, newContext, accessClass)) { + String message = ConflictsUtil.getDescription(refMember, true) + + " is " + getVisiblityString(refMember) + + " and will not be accessible from " + + ConflictsUtil.getDescription(member, false) + + " in the target class."; + message = ConflictsUtil.capitalize(message); + conflicts.add(message); + } + } + + private static boolean hasMethod(PsiClass targetClass, PsiMethod method) { + PsiMethod[] targetClassMethods = targetClass.getMethods(); + for (int i = 0; i < targetClassMethods.length; i++) { + if (MethodSignatureUtil.areSignaturesEqual(method.getSignature(PsiSubstitutor.EMPTY), + targetClassMethods[i].getSignature(PsiSubstitutor.EMPTY))) { + return true; + } + } + return false; + } + + private static String getVisiblityString(PsiMember member) { + if (member.hasModifierProperty(PsiModifier.PUBLIC)) { + return "public"; + } + if (member.hasModifierProperty(PsiModifier.PROTECTED)) { + return "protected"; + } + if (member.hasModifierProperty(PsiModifier.PRIVATE)) { + return "private"; + } + return "package local"; + } + + private static boolean hasField(PsiClass targetClass, PsiField field) { + String fieldName = field.getName(); + PsiField[] targetClassFields = targetClass.getFields(); + for (int i = 0; i < targetClassFields.length; i++) { + PsiField targetClassField = targetClassFields[i]; + if (fieldName.equals(targetClassField.getName())) { + return true; + } + } + return false; + } + + public List getMembers() { + return new ArrayList(myMembersToMove); + } + + public PsiClass getTargetClass() { + return myTargetClass; + } + + + private static class MyUsageInfo extends UsageInfo { + public final PsiClass qualifierClass; + public final PsiElement reference; + public final PsiElement member; + + public MyUsageInfo(PsiElement member, PsiElement reference, PsiClass qualifierClass, PsiElement highlightElement) { + super(highlightElement); + this.member = member; + this.qualifierClass = qualifierClass; + this.reference = reference; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ConvertToInstanceMethodRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ConvertToInstanceMethodRefactoringImpl.java new file mode 100644 index 00000000000..93afa396af5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ConvertToInstanceMethodRefactoringImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.refactoring.ConvertToInstanceMethodRefactoring; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodProcessor; + +/** + * @author dsl + */ +public class ConvertToInstanceMethodRefactoringImpl extends RefactoringImpl implements ConvertToInstanceMethodRefactoring { + ConvertToInstanceMethodRefactoringImpl(Project project, PsiMethod method, PsiParameter targetParameter) { + super(new ConvertToInstanceMethodProcessor(project, method, targetParameter, null)); + } + + public PsiMethod getMethod() { + return myProcessor.getMethod(); + } + + public PsiParameter getTargetParameter() { + return myProcessor.getTargetParameter(); + } + + public PsiClass getTargetClass() { + return myProcessor.getTargetClass(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/IntroduceParameterRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/IntroduceParameterRefactoringImpl.java new file mode 100644 index 00000000000..819a2a23eb0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/IntroduceParameterRefactoringImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.IntroduceParameterRefactoring; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.introduceParameter.IntroduceParameterProcessor; + +/** + * @author dsl + */ +public class IntroduceParameterRefactoringImpl extends RefactoringImpl + implements IntroduceParameterRefactoring { + + private IntroduceParameterRefactoringImpl(Project project, + PsiMethod methodToReplaceIn, + PsiMethod methodToSearchFor, + String parameterName, PsiExpression parameterInitializer, + PsiExpression expressionToSearch, PsiLocalVariable localVariable, + boolean removeLocalVariable, boolean declareFinal, final boolean replaceAllOccurences) { + super( + new IntroduceParameterProcessor(project, methodToReplaceIn, methodToSearchFor, + parameterInitializer, expressionToSearch, localVariable, removeLocalVariable, parameterName, true, replaceAllOccurences, + REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, declareFinal, null, + BaseRefactoringProcessor.EMPTY_CALLBACK)); + } + + IntroduceParameterRefactoringImpl(Project project, + PsiMethod methodToReplaceIn, + PsiMethod methodToSearchFor, + String parameterName, PsiExpression parameterInitializer, + PsiLocalVariable localVariable, + boolean removeLocalVariable, boolean declareFinal) { + this(project, methodToReplaceIn, methodToSearchFor, parameterName, parameterInitializer, null, localVariable, removeLocalVariable, declareFinal, false); + + } + + IntroduceParameterRefactoringImpl(Project project, + PsiMethod methodToReplaceIn, + PsiMethod methodToSearchFor, + String parameterName, PsiExpression parameterInitializer, + PsiExpression expressionToSearchFor, + boolean declareFinal, final boolean replaceAllOccurences) { + this(project, methodToReplaceIn, methodToSearchFor, parameterName, parameterInitializer, expressionToSearchFor, null, false, declareFinal, replaceAllOccurences); + + } + + public void enforceParameterType(PsiType forcedType) { + myProcessor.setForcedType(forcedType); + } + + public void setFieldReplacementPolicy(int policy) { + myProcessor.setReplaceFieldsWithGetters(policy); + } + + public PsiType getForcedType() { + return myProcessor.getForcedType(); + } + + public int getFieldReplacementPolicy() { + return myProcessor.getReplaceFieldsWithGetters(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MakeMethodStaticRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MakeMethodStaticRefactoringImpl.java new file mode 100644 index 00000000000..5ace22b9cec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MakeMethodStaticRefactoringImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.MakeMethodStaticRefactoring; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.makeMethodStatic.MakeMethodStaticProcessor; +import com.intellij.refactoring.makeMethodStatic.Settings; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class MakeMethodStaticRefactoringImpl extends RefactoringImpl implements MakeMethodStaticRefactoring { + MakeMethodStaticRefactoringImpl(Project project, + PsiMethod method, + boolean replaceUsages, + String classParameterName, + PsiField[] fields, + String[] names) { + super(new MakeMethodStaticProcessor(project, method, true, + new Settings(replaceUsages, classParameterName, fields, names), + BaseRefactoringProcessor.EMPTY_CALLBACK)); + } + + public PsiMethod getMethod() { + return myProcessor.getMethod(); + } + + public boolean isReplaceUsages() { + return myProcessor.getSettings().isReplaceUsages(); + } + + public String getClassParameterName() { + return myProcessor.getSettings().getClassParameterName(); + } + + public List getFields() { + final Settings settings = myProcessor.getSettings(); + List result = new ArrayList(); + final List parameterOrderList = settings.getParameterOrderList(); + for (Iterator iterator = parameterOrderList.iterator(); iterator.hasNext();) { + final Settings.FieldParameter fieldParameter = iterator.next(); + result.add(fieldParameter.field); + } + + return result; + } + + public String getParameterNameForField(PsiField field) { + return myProcessor.getSettings().getNameForField(field); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveClassesOrPackagesRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveClassesOrPackagesRefactoringImpl.java new file mode 100644 index 00000000000..45a3905b24a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveClassesOrPackagesRefactoringImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.*; +import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor; + +import java.util.List; + +/** + * @author dsl + */ +public class MoveClassesOrPackagesRefactoringImpl extends RefactoringImpl implements MoveClassesOrPackagesRefactoring { + + + public MoveClassesOrPackagesRefactoringImpl(Project project, PsiElement[] elements, MoveDestination moveDestination) { + super(new MoveClassesOrPackagesProcessor(project, elements, moveDestination, true, true, true, null, BaseRefactoringProcessor.EMPTY_CALLBACK)); + } + + public List getElements() { + return myProcessor.getElements(); + } + + public PackageWrapper getTargetPackage() { + return myProcessor.getTargetPackage(); + } + + public void setSearchInComments(boolean value) { + myProcessor.setSearchInComments(value); + } + + public void setSearchInNonJavaFiles(boolean value) { + myProcessor.setSearchInNonJavaFiles(value); + } + + public boolean isSearchInComments() { + return myProcessor.isSearchInComments(); + } + + public boolean isSearchInNonJavaFiles() { + return myProcessor.isSearchInNonJavaFiles(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveInnerRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveInnerRefactoringImpl.java new file mode 100644 index 00000000000..8593ae0e5f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveInnerRefactoringImpl.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.refactoring.MoveInnerRefactoring; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.move.moveInner.MoveInnerProcessor; + +/** + * @author dsl + */ +public class MoveInnerRefactoringImpl extends RefactoringImpl implements MoveInnerRefactoring { + public MoveInnerRefactoringImpl(Project project, PsiClass innerClass, String name, boolean passOuterClass, String parameterName) { + super(new MoveInnerProcessor(project, innerClass, name, passOuterClass, parameterName)); + } + + public PsiClass getInnerClass() { + return myProcessor.getInnerClass(); + } + + public String getNewClassName() { + return myProcessor.getNewClassName(); + } + + public boolean shouldPassParameter() { + return myProcessor.shouldPassParameter(); + } + + public String getParameterName() { + return myProcessor.getParameterName(); + } + + public void setSearchInComments(boolean value) { + myProcessor.setSearchInComments(value); + } + + public void setSearchInNonJavaFiles(boolean value) { + myProcessor.setSearchInNonJavaFiles(value); + } + + public boolean isSearchInComments() { + return myProcessor.isSearchInComments(); + } + + public boolean isSearchInNonJavaFiles() { + return myProcessor.isSearchInNonJavaFiles(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveMembersRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveMembersRefactoringImpl.java new file mode 100644 index 00000000000..482e42eaf8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/MoveMembersRefactoringImpl.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMember; +import com.intellij.refactoring.MoveMembersRefactoring; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.move.moveMembers.MoveMembersOptions; +import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; + +import java.util.List; + +/** + * @author dsl + */ +public class MoveMembersRefactoringImpl extends RefactoringImpl implements MoveMembersRefactoring { + MoveMembersRefactoringImpl(Project project, final PsiMember[] elements, final String targetClassQualifiedName, final String newVisibility) { + super(new MoveMembersProcessor(project, new MoveMembersOptions() { + public PsiMember[] getSelectedMembers() { + return elements; + } + + public String getTargetClassName() { + return targetClassQualifiedName; + } + + public String getMemberVisibility() { + return newVisibility; + } + + public boolean isPreviewUsages() { + return true; + } + + public void close(int exitCode) { + } + })); + } + + public List getMembers() { + return myProcessor.getMembers(); + } + + public PsiClass getTargetClass() { + return myProcessor.getTargetClass(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringActionHandlerFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringActionHandlerFactoryImpl.java new file mode 100644 index 00000000000..737ed4ff376 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringActionHandlerFactoryImpl.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.RefactoringActionHandlerFactory; +import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler; +import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler; +import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler; +import com.intellij.refactoring.extractMethod.ExtractMethodHandler; +import com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler; +import com.intellij.refactoring.inline.InlineHandler; +import com.intellij.refactoring.introduceField.IntroduceConstantHandler; +import com.intellij.refactoring.introduceField.IntroduceFieldHandler; +import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; +import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler; +import com.intellij.refactoring.makeMethodStatic.MakeMethodStaticHandler; +import com.intellij.refactoring.memberPullUp.PullUpHandler; +import com.intellij.refactoring.memberPushDown.PushDownHandler; +import com.intellij.refactoring.move.MoveHandler; +import com.intellij.refactoring.rename.PsiElementRenameHandler; +import com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryHandler; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.refactoring.tempWithQuery.TempWithQueryHandler; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperHandler; +import com.intellij.refactoring.typeCook.TypeCookHandler; +import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; + +/** + * @author dsl + */ +public class RefactoringActionHandlerFactoryImpl extends RefactoringActionHandlerFactory implements ApplicationComponent { + public String getComponentName() { + return "RefactoringActionHandlerFactory"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public RefactoringActionHandler createSafeDeleteHandler() { + return new SafeDeleteHandler(); + } + + public RefactoringActionHandler createAnonymousToInnerHandler() { + return new AnonymousToInnerHandler(); + } + + public RefactoringActionHandler createPullUpHandler() { + return new PullUpHandler(); + } + + public RefactoringActionHandler createPushDownHandler() { + return new PushDownHandler(); + } + + public RefactoringActionHandler createTurnRefsToSuperHandler() { + return new TurnRefsToSuperHandler(); + } + + public RefactoringActionHandler createTempWithQueryHandler() { + return new TempWithQueryHandler(); + } + + public RefactoringActionHandler createIntroduceParameterHandler() { + return new IntroduceParameterHandler(); + } + + public RefactoringActionHandler createMakeMethodStaticHandler() { + return new MakeMethodStaticHandler(); + } + + public RefactoringActionHandler createConvertToInstanceMethodHandler() { + return new ConvertToInstanceMethodHandler(); + } + + public RefactoringActionHandler createReplaceConstructorWithFactoryHandler() { + return new ReplaceConstructorWithFactoryHandler(); + } + + public RefactoringActionHandler createEncapsulateFieldsHandler() { + return new EncapsulateFieldsHandler(); + } + + public RefactoringActionHandler createMethodDuplicatesHandler() { + return new MethodDuplicatesHandler(); + } + + public RefactoringActionHandler createChangeSignatureHandler() { + return new ChangeSignatureHandler(); + } + + public RefactoringActionHandler createExtractSuperclassHandler() { + return new ChangeSignatureHandler(); + } + + public RefactoringActionHandler createTypeCookHandler() { + return new TypeCookHandler(); + } + + public RefactoringActionHandler createInlineHandler() { + return new InlineHandler(); + } + + public RefactoringActionHandler createExtractMethodHandler() { + return new ExtractMethodHandler(); + } + + public RefactoringActionHandler createInheritanceToDelegationHandler() { + return new InheritanceToDelegationHandler(); + } + + public RefactoringActionHandler createExtractInterfaceHandler() { + return new ExtractInterfaceHandler(); + } + + public RefactoringActionHandler createMoveHandler() { + return new MoveHandler(new MoveHandler.TargetContainerFinder() { + public PsiElement getTargetContainer(DataContext dataContext) { + return (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT); + } + }); + } + + public RefactoringActionHandler createRenameHandler() { + return new PsiElementRenameHandler(); + } + + public RefactoringActionHandler createIntroduceFieldHandler() { + return new IntroduceFieldHandler(); + } + + public RefactoringActionHandler createIntroduceVariableHandler() { + return new IntroduceVariableHandler(); + } + + + + public RefactoringActionHandler createIntroduceConstantHandler() { + return new IntroduceConstantHandler(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringFactoryImpl.java new file mode 100644 index 00000000000..81e32746e5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RefactoringFactoryImpl.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.refactoring.*; +import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination; +import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination; + +/** + * @author dsl + */ +public class RefactoringFactoryImpl extends RefactoringFactory implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.openapi.impl.RefactoringFactoryImpl"); + private final Project myProject; + + public RefactoringFactoryImpl(Project project) { + myProject = project; + } + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "RefactoringFactory"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public RenameRefactoring createRename(PsiElement element, String newName) { + return new RenameRefactoringImpl(myProject, element, newName, true, true); + } + + public MoveInnerRefactoring createMoveInner(PsiClass innerClass, String newName, boolean passOuterClass, String parameterName) { + return new MoveInnerRefactoringImpl(myProject, innerClass, newName, passOuterClass, parameterName); + } + + public MoveDestination createSourceFolderPreservingMoveDestination(String targetPackage) { + return new MultipleRootsMoveDestination(createPackageWrapper(targetPackage)); + } + + private PackageWrapper createPackageWrapper(String targetPackage) { + return new PackageWrapper(PsiManager.getInstance(myProject), targetPackage); + } + + public MoveDestination createSourceRootMoveDestination(String targetPackageQualifiedName, VirtualFile sourceRoot) { + final PsiDirectory directory = PsiManager.getInstance(myProject).findDirectory(sourceRoot); + LOG.assertTrue(directory != null && !directory.isSourceRoot(), "Should pass source root"); + return new AutocreatingSingleSourceRootMoveDestination(createPackageWrapper(targetPackageQualifiedName), + sourceRoot); + } + + + public MoveClassesOrPackagesRefactoring createMoveClassesOrPackages(PsiElement[] elements, MoveDestination moveDestination) { + return new MoveClassesOrPackagesRefactoringImpl(myProject, elements, moveDestination); + } + + public MoveMembersRefactoring createMoveMembers(final PsiMember[] elements, + final String targetClassQualifiedName, + final String newVisibility) { + return new MoveMembersRefactoringImpl(myProject, elements, targetClassQualifiedName, newVisibility); + } + + public MakeMethodStaticRefactoring createMakeMethodStatic(PsiMethod method, + boolean replaceUsages, + String classParameterName, + PsiField[] fields, + String[] names) { + return new MakeMethodStaticRefactoringImpl(myProject, method, replaceUsages, classParameterName, fields, names); + } + + public ConvertToInstanceMethodRefactoring createConvertToInstanceMethod(PsiMethod method, + PsiParameter targetParameter) { + return new ConvertToInstanceMethodRefactoringImpl(myProject, method, targetParameter); + } + + public SafeDeleteRefactoring createSafeDelete(PsiElement[] elements) { + return new SafeDeleteRefactoringImpl(myProject, elements); + } + + public TurnRefsToSuperRefactoring createTurnRefsToSuper(PsiClass aClass, + PsiClass aSuper, + boolean replaceInstanceOf) { + return new TurnRefsToSuperRefactoringImpl(myProject, aClass, aSuper, replaceInstanceOf); + } + + public ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiMethod method, + PsiClass targetClass, + String factoryName) { + return new ReplaceConstructorWithFactoryRefactoringImpl(myProject, method, targetClass, factoryName); + } + + public ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiClass originalClass, + PsiClass targetClass, + String factoryName) { + return new ReplaceConstructorWithFactoryRefactoringImpl(myProject, originalClass, targetClass, factoryName); + } + + public TypeCookRefactoring createTypeCook(PsiElement[] elements) { + return new TypeCookRefactoringImpl(myProject, elements); + } + + public IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn, + PsiMethod methodToSearchFor, + String parameterName, PsiExpression parameterInitializer, + PsiLocalVariable localVariable, + boolean removeLocalVariable, boolean declareFinal) { + return new IntroduceParameterRefactoringImpl(myProject, methodToReplaceIn, methodToSearchFor, parameterName, parameterInitializer, + localVariable, removeLocalVariable, declareFinal); + } + + public IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn, + PsiMethod methodToSearchFor, + String parameterName, PsiExpression parameterInitializer, + PsiExpression expressionToSearchFor, + boolean declareFinal, final boolean replaceAllOccurences) { + return new IntroduceParameterRefactoringImpl(myProject, methodToReplaceIn, methodToSearchFor, parameterName, parameterInitializer, + expressionToSearchFor, declareFinal, replaceAllOccurences); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RenameRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RenameRefactoringImpl.java new file mode 100644 index 00000000000..3e5e4aa1557 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/RenameRefactoringImpl.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.RenameRefactoring; +import com.intellij.refactoring.rename.RenameProcessor; + +import java.util.List; + +/** + * @author dsl + */ +public class RenameRefactoringImpl extends RefactoringImpl implements RenameRefactoring { + + public RenameRefactoringImpl(Project project, + PsiElement element, + String newName, + boolean toSearchInComments, + boolean toSearchInNonJavaFiles) { + super(new RenameProcessor(project, element, newName, toSearchInComments, toSearchInNonJavaFiles, true)); + } + + public void addElement(PsiElement element, String newName) { + myProcessor.addElement(element, newName); + } + + public List getElements() { + return myProcessor.getElements(); + } + + public List getNewNames() { + return myProcessor.getNewNames(); + } + + public void setShouldRenameVariables(boolean value) { + myProcessor.setShouldRenameVariables(value); + } + + public void setShouldRenameInheritors(boolean value) { + myProcessor.setShouldRenameInheritors(value); + } + + public void setSearchInComments(boolean value) { + myProcessor.setSearchInComments(value); + } + + public void setSearchInNonJavaFiles(boolean value) { + myProcessor.setSearchInNonJavaFiles(value); + } + + public boolean isSearchInComments() { + return myProcessor.isSearchInComments(); + } + + public boolean isSearchInNonJavaFiles() { + return myProcessor.isSearchInNonJavaFiles(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ReplaceConstructorWithFactoryRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ReplaceConstructorWithFactoryRefactoringImpl.java new file mode 100644 index 00000000000..9a1632d2fae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/ReplaceConstructorWithFactoryRefactoringImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.ReplaceConstructorWithFactoryRefactoring; +import com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryProcessor; + +/** + * @author dsl + */ +public class ReplaceConstructorWithFactoryRefactoringImpl extends RefactoringImpl implements ReplaceConstructorWithFactoryRefactoring { + ReplaceConstructorWithFactoryRefactoringImpl(Project project, PsiMethod method, PsiClass targetClass, String factoryName) { + super(new ReplaceConstructorWithFactoryProcessor(project, method, targetClass, factoryName, true, BaseRefactoringProcessor.EMPTY_CALLBACK)); + } + + ReplaceConstructorWithFactoryRefactoringImpl(Project project, PsiClass originalClass, PsiClass targetClass, String factoryName) { + super(new ReplaceConstructorWithFactoryProcessor(project, originalClass, targetClass, factoryName, true, BaseRefactoringProcessor.EMPTY_CALLBACK)); + } + + public PsiClass getOriginalClass() { + return myProcessor.getOriginalClass(); + } + + public PsiClass getTargetClass() { + return myProcessor.getTargetClass(); + } + + public PsiMethod getConstructor() { + return myProcessor.getConstructor(); + } + + public String getFactoryName() { + return myProcessor.getFactoryName(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/SafeDeleteRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/SafeDeleteRefactoringImpl.java new file mode 100644 index 00000000000..08c45e5b2d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/SafeDeleteRefactoringImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.SafeDeleteRefactoring; +import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author dsl + */ +public class SafeDeleteRefactoringImpl extends RefactoringImpl implements SafeDeleteRefactoring { + SafeDeleteRefactoringImpl(Project project, PsiElement[] elements) { + super(SafeDeleteProcessor.createInstance(project, BaseRefactoringProcessor.EMPTY_CALLBACK, elements, true, true)); + } + + public List getElements() { + final PsiElement[] elements = myProcessor.getElements(); + return Collections.unmodifiableList(Arrays.asList(elements)); + } + + public boolean isSearchInComments() { + return myProcessor.isSearchInCommentsAndStrings(); + } + + public void setSearchInComments(boolean value) { + myProcessor.setSearchInCommentsAndStrings(value); + } + + public void setSearchInNonJavaFiles(boolean value) { + myProcessor.setSearchNonJava(value); + } + + public boolean isSearchInNonJavaFiles() { + return myProcessor.isSearchNonJava(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TurnRefsToSuperRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TurnRefsToSuperRefactoringImpl.java new file mode 100644 index 00000000000..b628ecf6ba3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TurnRefsToSuperRefactoringImpl.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.TurnRefsToSuperRefactoring; +import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessor; + +/** + * @author dsl + */ +public class TurnRefsToSuperRefactoringImpl extends RefactoringImpl implements TurnRefsToSuperRefactoring { + TurnRefsToSuperRefactoringImpl(Project project, PsiClass aClass, PsiClass aSuper, boolean replaceInstanceOf) { + super(new TurnRefsToSuperProcessor(project, aClass, aSuper, replaceInstanceOf, true)); + } + + public PsiClass getSuper() { + return myProcessor.getSuper(); + } + + public PsiClass getTarget() { + return myProcessor.getTarget(); + } + + public boolean isReplaceInstanceOf() { + return myProcessor.isReplaceInstanceOf(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TypeCookRefactoringImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TypeCookRefactoringImpl.java new file mode 100644 index 00000000000..5ab0399071e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/openapi/impl/TypeCookRefactoringImpl.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.openapi.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringImpl; +import com.intellij.refactoring.TypeCookRefactoring; +import com.intellij.refactoring.typeCook.TypeCookProcessor; + +import java.util.List; + +/** + * @author dsl + */ +public class TypeCookRefactoringImpl extends RefactoringImpl implements TypeCookRefactoring { + TypeCookRefactoringImpl(Project project, PsiElement[] elements) { + super(new TypeCookProcessor(project, elements)); + } + + public List getElements() { + return myProcessor.getElements(); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/AutomaticRenamingDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/AutomaticRenamingDialog.java new file mode 100644 index 00000000000..c06f75f2221 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/AutomaticRenamingDialog.java @@ -0,0 +1,246 @@ +package com.intellij.refactoring.rename; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.refactoring.rename.naming.AutomaticRenamer; +import com.intellij.refactoring.ui.EnableDisableAction; +import com.intellij.refactoring.ui.StringTableCellEditor; +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; + +/** + * @author dsl + */ +public class AutomaticRenamingDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.AutomaticRenamingDialog"); + private static final int CHECK_COLUMN = 0; + private static final int OLD_NAME_COLUMN = 1; + private static final int NEW_NAME_COLUMN = 2; + private final AutomaticRenamer myRenamer; + private boolean[] myShouldRename; + private String[] myOldNames; + private String[] myNewNames; + private MyTableModel myTableModel; + private Table myTable; + private final Project myProject; + + + public AutomaticRenamingDialog(Project project, AutomaticRenamer renamer) { + super(project, true); + myProject = project; + myRenamer = renamer; + populateData(); + setTitle(myRenamer.getDialogTitle()); + init(); + } + + private void populateData() { + List oldNames = new ArrayList(); + final Map renames = myRenamer.getRenames(); + for (Iterator iterator = renames.keySet().iterator(); iterator.hasNext();) { + final String oldName = iterator.next(); + if (renames.get(oldName) != null) { + oldNames.add(oldName); + } + } + myOldNames = (String[])oldNames.toArray(new String[oldNames.size()]); + myShouldRename = new boolean[myOldNames.length]; + myNewNames = new String[myOldNames.length]; + Arrays.sort(myOldNames); + for (int i = 0; i < myOldNames.length; i++) { + final String oldName = myOldNames[i]; + myShouldRename[i] = true; + myNewNames[i] = renames.get(oldName); + } + } + + protected JComponent createNorthPanel() { + final Box box = Box.createHorizontalBox(); + box.add(new JLabel(myRenamer.getDialogDescription())); + box.add(Box.createHorizontalGlue()); + return box; + } + + protected void handleChanges() { + } + + protected JComponent createCenterPanel() { + final Box box = Box.createVerticalBox(); + myTableModel = new MyTableModel(); + myTable = new Table(myTableModel); + myTableModel.getSpaceAction().register(); + myTableModel.addTableModelListener(new TableModelListener() { + public void tableChanged(TableModelEvent e) { + handleChanges(); + } + }); + + final TableColumnModel columnModel = myTable.getColumnModel(); + columnModel.getColumn(CHECK_COLUMN).setCellRenderer(new BooleanTableCellRenderer()); + final int checkBoxWidth = new JCheckBox().getPreferredSize().width; + columnModel.getColumn(CHECK_COLUMN).setMaxWidth(checkBoxWidth); + columnModel.getColumn(CHECK_COLUMN).setMinWidth(checkBoxWidth); + + columnModel.getColumn(NEW_NAME_COLUMN).setCellEditor(new StringTableCellEditor(myProject)); + final JScrollPane jScrollPane2 = ScrollPaneFactory.createScrollPane(myTable); + box.add(jScrollPane2); + final Box buttonBox = Box.createHorizontalBox(); + buttonBox.add(Box.createHorizontalGlue()); + final JButton selectAllButton = new JButton("Select all"); + buttonBox.add(selectAllButton); + buttonBox.add(Box.createHorizontalStrut(4)); + final JButton deselectAllButton = new JButton("Unselect all"); + buttonBox.add(deselectAllButton); + selectAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + for (int i = 0; i < myShouldRename.length; i++) { + myShouldRename[i] = true; + } + myTableModel.fireTableDataChanged(); + } + }); + selectAllButton.setMnemonic('S'); + + deselectAllButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + for (int i = 0; i < myShouldRename.length; i++) { + myShouldRename[i] = false; + } + myTableModel.fireTableDataChanged(); + } + }); + deselectAllButton.setMnemonic('U'); + box.add(Box.createVerticalStrut(4)); + box.add(buttonBox); + box.add(Box.createVerticalStrut(4)); + + return box; + } + + protected void doOKAction() { + TableUtil.stopEditing(myTable); + updateRenamer(); + super.doOKAction(); + } + + protected void updateRenamer() { + for (int i = 0; i < myOldNames.length; i++) { + String oldName = myOldNames[i]; + if (myShouldRename[i]) { + myRenamer.setRename(oldName, myNewNames[i]); + } + else { + myRenamer.doNotRename(oldName); + } + } + } + + protected void setChecked(int rowIndex, boolean checked) { + myTableModel.setValueAt(Boolean.valueOf(checked), rowIndex, CHECK_COLUMN); + } + + protected String[] getNewNames() { + return myNewNames; + } + + protected String[] getOldNames() { + return myOldNames; + } + + private class MyTableModel extends AbstractTableModel { + public int getColumnCount() { + return 3; + } + + public int getRowCount() { + return myShouldRename.length; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch(columnIndex) { + case CHECK_COLUMN: + return Boolean.valueOf(myShouldRename[rowIndex]); + case OLD_NAME_COLUMN: + return myOldNames[rowIndex]; + case NEW_NAME_COLUMN: + return myNewNames[rowIndex]; + default: + LOG.assertTrue(false); + return null; + } + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + switch(columnIndex) { + case CHECK_COLUMN: + myShouldRename[rowIndex] = ((Boolean)aValue).booleanValue(); + break; + case NEW_NAME_COLUMN: + myNewNames[rowIndex] = (String) aValue; + break; + default: + LOG.assertTrue(false); + } + handleChanges(); + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex != OLD_NAME_COLUMN; + } + + public Class getColumnClass(int columnIndex) { + switch(columnIndex) { + case CHECK_COLUMN: return Boolean.class; + case OLD_NAME_COLUMN: return String.class; + case NEW_NAME_COLUMN: return String.class; + default: return null; + } + } + + public String getColumnName(int column) { + switch(column) { + case OLD_NAME_COLUMN: + return myRenamer.entityName() + " name"; + case NEW_NAME_COLUMN: + return "Rename To"; + default: + return " "; + } + } + + private MyEnableDisable getSpaceAction() { + return this.new MyEnableDisable(); + } + + private class MyEnableDisable extends EnableDisableAction { + protected JTable getTable() { + return myTable; + } + + protected boolean isRowChecked(int row) { + return myShouldRename[row]; + } + + protected void applyValue(int[] rows, boolean valueToBeSet) { + for (int i = 0; i < rows.length; i++) { + final int row = rows[i]; + myShouldRename[row] = valueToBeSet; + } + fireTableDataChanged(); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesImportedClassUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesImportedClassUsageInfo.java new file mode 100644 index 00000000000..7f0f31c812b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesImportedClassUsageInfo.java @@ -0,0 +1,36 @@ +package com.intellij.refactoring.rename; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class ClassHidesImportedClassUsageInfo extends ResolvableCollisionUsageInfo { + private final PsiClass myHiddenClass; + private PsiJavaCodeReferenceElement myCollisionReference; + + public ClassHidesImportedClassUsageInfo(PsiJavaCodeReferenceElement collisionReference, PsiClass renamedClass, PsiClass hiddenClass) { + super(collisionReference, renamedClass); + myHiddenClass = hiddenClass; + myCollisionReference = collisionReference; + } + + private boolean isResolvable() { + return myHiddenClass.getQualifiedName() != null; + } + + public void resolveCollision() throws IncorrectOperationException { + final PsiManager manager = myCollisionReference.getManager(); + if(manager == null) return; + final PsiElementFactory factory = manager.getElementFactory(); + + if (!isResolvable()) return; + final String qName = myHiddenClass.getQualifiedName(); + if (myCollisionReference instanceof PsiReferenceExpression) { + myCollisionReference.replace(factory.createExpressionFromText(qName, myCollisionReference)); + } else { + myCollisionReference.replace(factory.createFQClassNameReferenceElement(qName, myCollisionReference.getResolveScope())); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesUnqualifiableClassUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesUnqualifiableClassUsageInfo.java new file mode 100644 index 00000000000..c26a1e87aa3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ClassHidesUnqualifiableClassUsageInfo.java @@ -0,0 +1,26 @@ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.refactoring.util.ConflictsUtil; + +/** + * @author dsl + */ +public class ClassHidesUnqualifiableClassUsageInfo extends UnresolvableCollisionUsageInfo { + private final PsiClass myHiddenClass; + private PsiClass myRenamedClass; + + public ClassHidesUnqualifiableClassUsageInfo(PsiJavaCodeReferenceElement element, PsiClass renamedClass, PsiClass hiddenClass) { + super(element, renamedClass); + myRenamedClass = renamedClass; + myHiddenClass = hiddenClass; + } + + public String getDescription() { + final PsiElement container = ConflictsUtil.getContainer(myHiddenClass); + return "Renamed class will hide " + ConflictsUtil.getDescription(myHiddenClass, false) + " in " + + ConflictsUtil.getDescription(container, false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollidingClassImportUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollidingClassImportUsageInfo.java new file mode 100644 index 00000000000..4d617662ad2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollidingClassImportUsageInfo.java @@ -0,0 +1,21 @@ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiImportStatement; + +/** + * @author dsl + */ +public class CollidingClassImportUsageInfo extends ResolvableCollisionUsageInfo { + private PsiImportStatement myImportStatement; + + public CollidingClassImportUsageInfo(PsiImportStatement element, PsiElement referencedElement) { + super(element, referencedElement); + myImportStatement = element; + } + + public PsiImportStatement getImportStatement() { + return myImportStatement; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollisionUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollisionUsageInfo.java new file mode 100644 index 00000000000..9dcc26758f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/CollisionUsageInfo.java @@ -0,0 +1,18 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 05.06.2002 + * Time: 12:25:03 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.psi.PsiElement; + +public class CollisionUsageInfo extends MoveRenameUsageInfo { + public CollisionUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, null, referencedElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesFieldUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesFieldUsageInfo.java new file mode 100644 index 00000000000..66be168c187 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesFieldUsageInfo.java @@ -0,0 +1,19 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 30.05.2002 + * Time: 13:43:25 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + + +import com.intellij.psi.PsiElement; + +class LocalHidesFieldUsageInfo extends ResolvableCollisionUsageInfo { + public LocalHidesFieldUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, referencedElement); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java new file mode 100644 index 00000000000..9738d181cbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java @@ -0,0 +1,33 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 05.06.2002 + * Time: 13:38:29 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.usageView.UsageViewUtil; + +public class LocalHidesRenamedLocalUsageInfo extends UnresolvableCollisionUsageInfo { + private final PsiElement myConflictingElement; + + public LocalHidesRenamedLocalUsageInfo(PsiElement element, PsiElement conflictingElement) { + super(element, null); + myConflictingElement = conflictingElement; + } + + public String getDescription() { + StringBuffer buffer = new StringBuffer(); + + buffer.append("There is already a "); + buffer.append(ConflictsUtil.getDescription(myConflictingElement, true)); + buffer.append(". It will conflict with the renamed "); + buffer.append(UsageViewUtil.getType(getElement())); + + return ConflictsUtil.capitalize(buffer.toString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/PsiElementRenameHandler.java new file mode 100644 index 00000000000..cf04c17d255 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/PsiElementRenameHandler.java @@ -0,0 +1,189 @@ +package com.intellij.refactoring.rename; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.actions.BaseRefactoringAction; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.xml.util.XmlUtil; + +/** + * created at Nov 13, 2001 + * @author Jeka, dsl + */ +public class PsiElementRenameHandler implements RenameHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.PsiElementRenameHandler"); + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset()); + invoke(element, project, nameSuggestionContext); + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + PsiElement element = elements != null && elements.length == 1 ? elements[0] : null; + LOG.assertTrue(element != null); + invoke(element, project, element); + } + + public void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext) { + if (element != null && !canRename(element, project)) { + return; + } + FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.rename"); + + if (element instanceof PsiFile) { + renameFileOrDirectory(element, project); + } + else if (element instanceof PsiDirectory) { + PsiDirectory psiDirectory = (PsiDirectory)element; + PsiPackage aPackage = psiDirectory.getPackage(); + final String qualifiedName = aPackage != null ? aPackage.getQualifiedName() : ""; + if (aPackage == null || qualifiedName.length() == 0/*default package*/) { + renameFileOrDirectory(element, project); + } + else { + PsiDirectory[] directories = aPackage.getDirectories(); + final VirtualFile[] virtualFiles = aPackage.occursInPackagePrefixes(); + if (virtualFiles.length == 0 && directories.length == 1) { + rename(aPackage, project, nameSuggestionContext); + } + else { // the directory corresponds to a package that has multiple associated directories + StringBuffer message = new StringBuffer(); + RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, qualifiedName); + RenameUtil.buildMultipleDirectoriesInPackageMessage(message, aPackage, directories); + message.append("\n\nAll these directories and all references to package \n"); + message.append(qualifiedName); + message.append("\nwill be renamed."); + message.append("\nDo you wish to continue?"); + int ret = Messages.showYesNoDialog(project, message.toString(), "Warning", Messages.getWarningIcon()); + if (ret != 0) { + return; + } + // if confirmed + rename(aPackage, project, nameSuggestionContext); + } + } + } + else { + rename(element, project, nameSuggestionContext); + } + } + + private boolean canRename(PsiElement element, Project project) { + if (element instanceof XmlAttributeValue) { + XmlAttribute value = (XmlAttribute)element.getParent(); + if (XmlUtil.isAntTargetDefinition(value) || XmlUtil.isAntPropertyDefinition(value)) { + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return false; + } + return true; + } + } + + final String REFACTORING_NAME = "Rename"; + if (element == null || + !((element instanceof PsiFile) || + (element instanceof PsiPointcutDef) || + (element instanceof PsiPackage) || + (element instanceof PsiDirectory) || + (element instanceof PsiClass) || + (element instanceof PsiVariable) || + (element instanceof PsiMethod) || + (element instanceof PsiNamedElement) + )) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned at the symbol to be renamed."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null, project); + return false; + } + + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return false; + } + return true; + } + + + private void rename(PsiElement element, final Project project, PsiElement nameSuggestionContext) { + if (element instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)element; + if (psiMethod.isConstructor()) { + PsiClass containingClass = psiMethod.getContainingClass(); + if (containingClass == null) return; + String classType = UsageViewUtil.getType(containingClass); + String className = UsageViewUtil.getShortName(containingClass); + int ret = Messages.showYesNoDialog( + project, + "Constructor cannot be renamed.\nWould you like to rename " + classType + " " + className + "?", + "Warning", + Messages.getQuestionIcon()); + if (ret != 0) { + return; + } + element = containingClass; + if (!canRename(element, project)) { + return; + } + } + } + + PsiElement elementToRename = element; + if (elementToRename instanceof PsiMethod) { + elementToRename = SuperMethodWarningUtil.checkSuperMethod((PsiMethod)elementToRename, "rename"); + if (elementToRename == null) return; + + elementToRename = EjbUtil.checkDeclMethod((PsiMethod)elementToRename, "rename"); + if (elementToRename == null) return; + + if (!elementToRename.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, elementToRename); + return; + } + } + String helpID = HelpID.getRenameHelpID(elementToRename); + final RenameDialog dialog = + new RenameDialog(project, elementToRename, nameSuggestionContext, helpID, + new RenameProcessor(project, elementToRename) + ); + + dialog.show(); + } + + + /** + * renames an arbitrary file or a directory that has no packages associated with + */ + private void renameFileOrDirectory(final PsiElement element, final Project project) { + if (element instanceof PsiFile || element instanceof PsiDirectory) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + FileRenameUtil.rename(project, element); + } + }); + } + } + + public boolean isAvailableOnDataContext(DataContext dataContext) { + PsiElement[] elementArray = BaseRefactoringAction.getPsiElementArray(dataContext); + return (elementArray != null && elementArray.length == 1 && elementArray[0] != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameDialog.java new file mode 100644 index 00000000000..2586fda1ec1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameDialog.java @@ -0,0 +1,511 @@ +package com.intellij.refactoring.rename; + +import com.intellij.ant.PsiAntElement; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.CharFilter; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerEx; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.NameSuggestionsField; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; + +public class RenameDialog extends RefactoringDialog { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameDialog"); + private SuggestedNameInfo mySuggestedNameInfo; + + public static interface Callback { + void run(RenameDialog dialog); + } + + private JLabel myNameLabel; + private NameSuggestionsField myNameSuggestionsField; + private JCheckBox myCbSearchInComments; + private JCheckBox myCbSearchInNonJavaFiles; + private JCheckBox myCbRenameVariables; + private JCheckBox myCbRenameInheritors; + private JCheckBox myCbRenameBoundForms; + private JLabel myNewNamePrefix = new JLabel(""); + + + private String myHelpID; + private Project myProject; + private PsiElement myPsiElement; + private final PsiElement myNameSuggestionContext; + private Callback myCallback; + + + public RenameDialog(Project project, PsiElement psiElement, + PsiElement nameSuggestionContext, String helpID, Callback callback) { + super(project, true); + myProject = project; + myPsiElement = psiElement; + myNameSuggestionContext = nameSuggestionContext; + myCallback = callback; + setTitle("Rename"); + + createNewNameComponent(); + init(); + + myNameLabel.setText("Rename " + getFullName() + " and its usages to:"); + boolean toSearchInComments = + RefactoringSettings.getInstance().isToSearchInCommentsForRename(myPsiElement); + boolean toSearchInNonJava = + RefactoringSettings.getInstance().isToSearchInNonJavaFilesForRename(myPsiElement); + myCbSearchInComments.setSelected(toSearchInComments); + + if (myCbSearchInNonJavaFiles.isEnabled()) { + myCbSearchInNonJavaFiles.setSelected(toSearchInNonJava); + } + + if (!showSearchCheckboxes(myPsiElement)) { + myCbSearchInComments.setVisible(false); + myCbSearchInNonJavaFiles.setVisible(false); + } + + validateButtons(); + myHelpID = helpID; + } + + private String getFullName() { + return (UsageViewUtil.getType(myPsiElement) + " " + UsageViewUtil.getDescriptiveName(myPsiElement)).trim(); + } + + private boolean showSearchCheckboxes(PsiElement e) { + if (e instanceof PsiAntElement) return false; + + return true; + } + + private void createNewNameComponent() { + String[] suggestedNames = getSuggestedNames(); + myNameSuggestionsField = new NameSuggestionsField(suggestedNames, myProject, myPsiElement instanceof PsiAntElement ? StdFileTypes.PLAIN_TEXT : StdFileTypes.JAVA); + myNameSuggestionsField.addDataChangedListener(new NameSuggestionsField.DataChanged() { + public void dataChanged() { + validateButtons(); + } + }); + + if (myPsiElement instanceof PsiVariable) { + myNameSuggestionsField.getComponent().registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + completeVariable(myNameSuggestionsField.getEditor()); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); + } + } + + private void completeVariable(Editor editor) { + String prefix = myNameSuggestionsField.getName(); + PsiVariable var = (PsiVariable)myPsiElement; + VariableKind kind = CodeStyleManager.getInstance(myProject).getVariableKind(var); + LinkedHashSet set = new LinkedHashSet(); + CompletionUtil.completeVariableName(myProject, set, prefix, var.getType(), kind); + + if (prefix.length() == 0) { + String[] suggestedNames = getSuggestedNames(); + for (int i = 0; i < suggestedNames.length; i++) { + LookupItemUtil.addLookupItem(set, suggestedNames[i], ""); + } + } + + LookupItem[] lookupItems = set.toArray(new LookupItem[set.size()]); + editor.getCaretModel().moveToOffset(prefix.length()); + editor.getSelectionModel().removeSelection(); + LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix, null, new CharFilter() { + public int accept(char c) { + if (Character.isJavaIdentifierPart(c)) return CharFilter.ADD_TO_PREFIX; + return CharFilter.SELECT_ITEM_AND_FINISH_LOOKUP; + } + }); + } + + private String[] getSuggestedNames() { + String initialName = UsageViewUtil.getShortName(myPsiElement); + mySuggestedNameInfo = suggestNamesForElement(myPsiElement); + + String parameterName = null; + if (myNameSuggestionContext != null) { + final PsiElement nameSuggestionContextParent = myNameSuggestionContext.getParent(); + if (nameSuggestionContextParent.getParent() instanceof PsiExpressionList) { + final PsiExpressionList expressionList = (PsiExpressionList)nameSuggestionContextParent.getParent(); + final PsiElement parent = expressionList.getParent(); + if (parent instanceof PsiCallExpression) { + final PsiMethod method = ((PsiCallExpression)parent).resolveMethod(); + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final PsiExpression[] expressions = expressionList.getExpressions(); + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; + if (expression == nameSuggestionContextParent) { + if (i < parameters.length) { + parameterName = parameters[i].getName(); + } + break; + } + } + } + } + } + } + final String[] strings = mySuggestedNameInfo != null ? mySuggestedNameInfo.names : ArrayUtil.EMPTY_STRING_ARRAY; + ArrayList list = new ArrayList(Arrays.asList(strings)); + final String properlyCased = suggestProperlyCasedName(myPsiElement); + if (!list.contains(initialName)) { + list.add(0, initialName); + } + else { + int i = list.indexOf(initialName); + list.remove(i); + list.add(0, initialName); + } + if (properlyCased != null && !properlyCased.equals(initialName)) { + list.add(1, properlyCased); + } + if (parameterName != null && !list.contains(parameterName)) { + list.add(parameterName); + } + ContainerUtil.removeDuplicates(list); + return (String[])list.toArray(new String[list.size()]); + } + + private String suggestProperlyCasedName(PsiElement psiElement) { + if (!(psiElement instanceof PsiNamedElement)) return null; + String name = ((PsiNamedElement)psiElement).getName(); + if (psiElement instanceof PsiVariable) { + final CodeStyleManagerEx codeStyleManager = (CodeStyleManagerEx)CodeStyleManager.getInstance(myProject); + final VariableKind kind = codeStyleManager.getVariableKind((PsiVariable)psiElement); + final String prefix = codeStyleManager.getPrefixByVariableKind(kind); + if (name.startsWith(prefix)) { + name = name.substring(prefix.length()); + } + final String[] words = PsiNameHelper.splitNameIntoWords(name); + if (VariableKind.STATIC_FINAL_FIELD.equals(kind)) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (i > 0) buffer.append('_'); + buffer.append(word.toUpperCase()); + } + return buffer.toString(); + } + else { + StringBuffer buffer = new StringBuffer(prefix); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + final boolean prefixRequiresCapitalization = prefix.length() > 0 && !StringUtil.endsWithChar(prefix, '_'); + if (i > 0 || prefixRequiresCapitalization) { + buffer.append(StringUtil.capitalize(word)); + } + else { + buffer.append(StringUtil.decapitalize(word)); + } + } + return buffer.toString(); + } + + } + return name; + } + + private SuggestedNameInfo suggestNamesForElement(final PsiElement element) { + PsiVariable var = null; + if (element instanceof PsiVariable) { + var = (PsiVariable)element; + } + else if (element instanceof PsiIdentifier) { + PsiIdentifier identifier = (PsiIdentifier)element; + if (identifier.getParent() instanceof PsiVariable) { + var = (PsiVariable)identifier.getParent(); + } + } + + if (var == null) return null; + + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); + VariableKind variableKind = codeStyleManager.getVariableKind(var); + return codeStyleManager.suggestVariableName(variableKind, null, var.getInitializer(), var.getType()); + } + + public String getNewName() { + return myNameSuggestionsField.getName().trim(); + } + + public boolean isSearchInComments() { + return myCbSearchInComments.isSelected(); + } + + public boolean isSearchInNonJavaFiles() { + return myCbSearchInNonJavaFiles.isSelected(); + } + + public JComponent getPreferredFocusedComponent() { + return myNameSuggestionsField.getComponent(); + } + + protected JComponent createCenterPanel() { + return null; + } + + public boolean shouldRenameVariables() { + return myCbRenameVariables != null ? myCbRenameVariables.isSelected() : false; + } + + public boolean shouldRenameInheritors() { + return myCbRenameInheritors != null ? myCbRenameInheritors.isSelected() : false; + } + + public boolean shouldRenameForms() { + return myCbRenameBoundForms != null ? myCbRenameBoundForms.isSelected() : false; + } + + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + panel.setBorder(IdeBorderFactory.createBorder()); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + myNameLabel = new JLabel(); + panel.add(myNameLabel, gbConstraints); + + gbConstraints.insets = new Insets(4, 8, 4, ("".equals(myNewNamePrefix.getText()) ? 0 : 1)); + gbConstraints.gridwidth = 1; + gbConstraints.fill = GridBagConstraints.NONE; + gbConstraints.weightx = 0; + gbConstraints.gridx = 0; + gbConstraints.anchor = GridBagConstraints.WEST; + panel.add(myNewNamePrefix, gbConstraints); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridwidth = 2; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.weightx = 1; + gbConstraints.gridx = 0; + panel.add(myNameSuggestionsField.getComponent(), gbConstraints); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridwidth = 1; + gbConstraints.gridx = 0; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbSearchInComments = new NonFocusableCheckBox("Search in comments and strings"); + myCbSearchInComments.setMnemonic('S'); + myCbSearchInComments.setSelected(true); + panel.add(myCbSearchInComments, gbConstraints); + + gbConstraints.insets = new Insets(4, 4, 4, 8); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbSearchInNonJavaFiles = new NonFocusableCheckBox("Search in non-java files"); + myCbSearchInNonJavaFiles.setMnemonic('e'); + myCbSearchInNonJavaFiles.setSelected(true); + panel.add(myCbSearchInNonJavaFiles, gbConstraints); + if (!RefactoringUtil.isSearchInNonJavaEnabled(myPsiElement)) { + myCbSearchInNonJavaFiles.setEnabled(false); + myCbSearchInNonJavaFiles.setSelected(false); + myCbSearchInNonJavaFiles.setVisible(false); + } + + if (myPsiElement instanceof PsiClass) { + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridwidth = 1; + gbConstraints.gridx = 0; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbRenameVariables = new NonFocusableCheckBox("Rename variables"); + myCbRenameVariables.setMnemonic('v'); + myCbRenameVariables.setSelected(true); + panel.add(myCbRenameVariables, gbConstraints); + + gbConstraints.insets = new Insets(4, 4, 4, 8); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbRenameInheritors = new NonFocusableCheckBox("Rename inheritors"); + myCbRenameInheritors.setMnemonic('i'); + myCbRenameInheritors.setSelected(true); + panel.add(myCbRenameInheritors, gbConstraints); + + String qName = ((PsiClass)myPsiElement).getQualifiedName(); + if (qName != null) { + PsiFile[] forms = myPsiElement.getManager().getSearchHelper().findFormsBoundToClass(qName); + if (forms.length > 0) { + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.gridx = 0; + gbConstraints.weightx = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + myCbRenameBoundForms = new NonFocusableCheckBox("Rename bound forms"); + myCbRenameBoundForms.setMnemonic('f'); + myCbRenameBoundForms.setSelected(true); + panel.add(myCbRenameBoundForms, gbConstraints); + } + } + } + + return panel; + } + + /* + protected JComponent createSouthPanel() { + myCbPreviewResults = new NonFocusableCheckBox("Preview usages to be changed"); + myCbPreviewResults.setSelected(RefactoringSettings.getInstance().RENAME_PREVIEW_USAGES); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(super.createSouthPanel(), BorderLayout.CENTER); + myCbPreviewResults.setMnemonic('P'); + panel.add(myCbPreviewResults, BorderLayout.WEST); + return panel; + } + */ + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpID); + } + + protected void doAction() { + LOG.assertTrue(myPsiElement.isValid()); + + final RefactoringSettings settings = RefactoringSettings.getInstance(); + if (!checkNameConflicts()) { + myNameSuggestionsField.requestFocusInWindow(); + return; + } + + settings.setToSearchInCommentsForRename(myPsiElement, isSearchInComments()); + if (myCbSearchInNonJavaFiles.isEnabled()) { + settings.setToSearchInNonJavaFilesForRename(myPsiElement, isSearchInNonJavaFiles()); + } + if (mySuggestedNameInfo != null) { + mySuggestedNameInfo.nameChoosen(getNewName()); + } + + myCallback.run(this); + } + + private boolean checkNameConflicts() { + final PsiManager manager = PsiManager.getInstance(myProject); + String newName = getNewName(); + try { + PsiElementFactory factory = manager.getElementFactory(); + if (myPsiElement instanceof PsiMethod) { + PsiMethod refactoredMethod = (PsiMethod)myPsiElement; + if (newName.equals(refactoredMethod.getName())) { + return true; + } + PsiMethod prototype = (PsiMethod)refactoredMethod.copy(); + prototype.getNameIdentifier().replace(factory.createIdentifier(newName)); + PsiClass aClass = refactoredMethod.getContainingClass(); + return RefactoringMessageUtil.checkMethodConflicts( + aClass != null ? (PsiElement)aClass : (PsiElement)refactoredMethod.getContainingFile(), + refactoredMethod, + prototype + ); + } + else if (myPsiElement instanceof PsiField) { + PsiField refactoredField = (PsiField)myPsiElement; + if (newName.equals(refactoredField.getName())) { + return true; + } + PsiClass aClass = refactoredField.getContainingClass(); + return RefactoringMessageUtil.checkFieldConflicts( + aClass != null ? (PsiElement)aClass : (PsiElement)refactoredField.getContainingFile(), + newName + ); + } + else if (myPsiElement instanceof PsiClass) { + final PsiClass aClass = ((PsiClass)myPsiElement); + if (newName.equals(aClass.getName())) { + return true; + } + if (myPsiElement.getParent() instanceof PsiClass) { // innerClass + PsiClass containingClass = (PsiClass)myPsiElement.getParent(); + PsiClass[] innerClasses = containingClass.getInnerClasses(); + for (int idx = 0; idx < innerClasses.length; idx++) { + PsiClass innerClass = innerClasses[idx]; + if (newName.equals(innerClass.getName())) { + int ret = Messages.showYesNoDialog( + myProject, + "Inner class " + newName + " is already defined in class " + containingClass.getQualifiedName() + + ".\nContinue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + break; + } + } + } + else { + final String qualifiedNameAfterRename = RenameUtil.getQualifiedNameAfterRename(aClass, newName); + final PsiClass conflictingClass = PsiManager.getInstance(myProject).findClass(qualifiedNameAfterRename); + if (conflictingClass != null) { + RefactoringMessageUtil.showErrorMessage("Error", "Class " + qualifiedNameAfterRename + " already exists", + null, myProject); + return false; + } + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + return true; + } + + + protected boolean areButtonsValid() { + final String newName = getNewName(); + final boolean enabled; + if (newName == null) { + return false; + } + else { + if (myPsiElement instanceof PsiAntElement) { + return newName.trim().matches("[\\d\\w\\_\\.\\-]*"); + } + else { + return PsiManager.getInstance(myProject).getNameHelper().isIdentifier(newName.trim()); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandler.java new file mode 100644 index 00000000000..0346c129231 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandler.java @@ -0,0 +1,11 @@ +package com.intellij.refactoring.rename; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.refactoring.RefactoringActionHandler; + +/** + * @author dsl + */ +public interface RenameHandler extends RefactoringActionHandler { + boolean isAvailableOnDataContext(DataContext dataContext); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandlerRegistry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandlerRegistry.java new file mode 100644 index 00000000000..35be0e2a3c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameHandlerRegistry.java @@ -0,0 +1,40 @@ +package com.intellij.refactoring.rename; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.util.containers.HashSet; + +import java.util.Iterator; +import java.util.Set; + +/** + * @author dsl + */ +public class RenameHandlerRegistry { + private Set myHandlers = new HashSet(); + private static final RenameHandlerRegistry INSTANCE = new RenameHandlerRegistry(); + private PsiElementRenameHandler myDefaultElementRenameHandler; + + public static RenameHandlerRegistry getInstance() { + return INSTANCE; + } + + private RenameHandlerRegistry() { + myDefaultElementRenameHandler = new PsiElementRenameHandler(); + } + + public PsiElementRenameHandler getDefaultElementRenameHandler() { + return myDefaultElementRenameHandler; + } + + public RenameHandler getRenameHandler(DataContext dataContext) { + for (Iterator iterator = myHandlers.iterator(); iterator.hasNext();) { + RenameHandler renameHandler = iterator.next(); + if (renameHandler.isAvailableOnDataContext(dataContext)) return renameHandler; + } + return myDefaultElementRenameHandler.isAvailableOnDataContext(dataContext) ? myDefaultElementRenameHandler : null; + } + + public void registerHandler(RenameHandler handler) { + myHandlers.add(handler); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameProcessor.java new file mode 100644 index 00000000000..ec2f916c314 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameProcessor.java @@ -0,0 +1,560 @@ +package com.intellij.refactoring.rename; + +import com.intellij.ant.PsiAntElement; +import com.intellij.j2ee.J2EERolesUtil; +import com.intellij.j2ee.ejb.EjbUsagesUtil; +import com.intellij.j2ee.ejb.EjbUtil; +import com.intellij.j2ee.ejb.role.EjbDeclMethodRole; +import com.intellij.j2ee.ejb.role.EjbMethodRole; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlTag; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.rename.naming.AutomaticRenamer; +import com.intellij.refactoring.rename.naming.AutomaticVariableRenamer; +import com.intellij.refactoring.rename.naming.FormsRenamer; +import com.intellij.refactoring.rename.naming.InheritorRenamer; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.*; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class RenameProcessor extends BaseRefactoringProcessor implements RenameDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameProcessor"); + + protected ArrayList myElements = new ArrayList(); + protected ArrayList myNames = new ArrayList(); + + private RenameDialog myDialog; + private PsiElement myElement; + private String myNewName = null; + + boolean mySearchInComments; + private boolean mySearchInNonJavaFiles; + private boolean myPreviewUsages; + private String myCommandName; + private boolean myShouldRenameVariables; + private boolean myShouldRenameInheritors; + private boolean myShouldRenameForms; + private UsageInfo[] myUsagesForNonCodeRenaming; + private List> myRenamers = new ArrayList>(); + + public RenameProcessor(Project project, PsiElement element, String newName, + boolean isSearchInComments, boolean toSearchInNonJavaFiles, boolean isPreviewUsages) { + super(project); + myDialog = null; + myElement = element; + + mySearchInComments = isSearchInComments; + mySearchInNonJavaFiles = toSearchInNonJavaFiles; + myPreviewUsages = isPreviewUsages; + + setNewName(newName); + } + + public List getElements() { + return Collections.unmodifiableList(myElements); + } + + + public void setShouldRenameVariables(boolean shouldRenameVariables) { + myShouldRenameVariables = shouldRenameVariables; + } + + public void setShouldRenameInheritors(boolean shouldRenameInheritors) { + myShouldRenameInheritors = shouldRenameInheritors; + } + + + + public RenameProcessor(Project project, PsiElement element) { + super(project); + myElement = element; + } + + public boolean isVariable() { + return myElement instanceof PsiVariable; + } + + public void run(Object markerId) { + String message = null; + prepareRenaming(); + try { + for (int i = 0; i < myElements.size(); i++) { + PsiElement element = myElements.get(i); + String name = myNames.get(i); + RenameUtil.checkRename(element, name); + } + } catch (IncorrectOperationException e) { + message = e.getMessage(); + } + + if (message != null) { + RefactoringMessageUtil.showErrorMessage("Rename", message, getHelpID(), myProject); + return; + } + + super.run(markerId); + } + + public void prepareRenaming() { + if (myElement instanceof PsiField) { + prepareFieldRenaming((PsiField) myElement, myNewName); + } else if (myElement instanceof PsiMethod) { + prepareMethodRenaming((PsiMethod) myElement, myNewName); + } else if (myElement instanceof PsiPackage) { + preparePackageRenaming((PsiPackage) myElement, myNewName); + } + } + + private void preparePackageRenaming(PsiPackage psiPackage, String newName) { + final PsiDirectory[] directories = psiPackage.getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (!directory.isSourceRoot()) { + myElements.add(directory); + myNames.add(newName); + } + } + } + + protected String getHelpID() { + return HelpID.getRenameHelpID(myElement); + } + + public void run(RenameDialog dialog) { + myDialog = dialog; + setNewName(dialog.getNewName()); + + mySearchInComments = dialog.isSearchInComments(); + mySearchInNonJavaFiles = dialog.isSearchInNonJavaFiles(); + myPreviewUsages = dialog.isPreviewUsages(); + myShouldRenameVariables = dialog.shouldRenameVariables(); + myShouldRenameInheritors = dialog.shouldRenameInheritors(); + myShouldRenameForms = dialog.shouldRenameForms(); + + run((Object) null); + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + if (myDialog != null) { + String[] conflicts = RenameUtil.getConflictDescriptions(usages[0]); + if (conflicts.length > 0) { + ConflictsDialog conflictsDialog = new ConflictsDialog(conflicts, myProject); + conflictsDialog.show(); + if (!conflictsDialog.isOK()) { + return false; + } + } + } + Set usagesSet = new HashSet(Arrays.asList(usages[0])); + RenameUtil.removeConflictUsages(usagesSet); + + final List variableUsages = new ArrayList(); + if (!myRenamers.isEmpty()) { + boolean isOK = findRenamedVariables(variableUsages); + + if (!isOK) return false; + } + + if (!variableUsages.isEmpty()) { + usagesSet.addAll(variableUsages); + usages[0] = usagesSet.toArray(new UsageInfo[usagesSet.size()]); + } + + if (myDialog != null) { + // make sure that dialog is closed in swing thread + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }); + } + return true; + } + + private boolean findRenamedVariables(final List variableUsages) { + for (Iterator> iterator = myRenamers.iterator(); iterator.hasNext();) { + final AutomaticRenamer automaticVariableRenamer = iterator.next(); + if (!automaticVariableRenamer.hasAnythingToRename()) continue; + final AutomaticRenamingDialog dialog = new AutomaticRenamingDialog(myProject, automaticVariableRenamer); + dialog.show(); + if (!dialog.isOK()) return false; + } + + for (Iterator> iterator = myRenamers.iterator(); iterator.hasNext();) { + final AutomaticRenamer renamer = iterator.next(); + final List variables = renamer.getElements(); + for (Iterator iterator1 = variables.iterator(); iterator1.hasNext();) { + final PsiNamedElement variable = iterator1.next(); + addElement(variable, renamer.getNewName(variable)); + } + } + + Runnable runnable = new Runnable() { + public void run() { + for (Iterator> iterator = myRenamers.iterator(); iterator.hasNext();) { + final AutomaticRenamer renamer = iterator.next(); + renamer.findUsages(variableUsages, mySearchInComments, mySearchInNonJavaFiles); + } + } + }; + + final boolean isOK = ApplicationManager.getApplication().runProcessWithProgressSynchronously( + runnable, "Searching for variables", true, myProject + ); + return isOK; + } + + public void addElement(PsiElement element, String newName) { + myElements.add(element); + myNames.add(newName); + } + + private void setNewName(String newName) { + if (myElement == null) { + myCommandName = "Renaming something"; + return; + } + int oldIndex = myElements.indexOf(myElement); + if (oldIndex >= 0) { + myElements.remove(oldIndex); + myNames.remove(oldIndex); + } + + myNewName = newName; + myElements.add(myElement); + myNames.add(newName); + myCommandName = "Renaming " + UsageViewUtil.getType(myElement) + " " + UsageViewUtil.getDescriptiveName(myElement) + " to " + newName; + } + + protected void prepareFieldRenaming(PsiField field, String newName) { + // search for getters/setters + PsiClass aClass = field.getContainingClass(); + + final CodeStyleManager manager = CodeStyleManager.getInstance(myProject); + + final String propertyName = + manager.variableNameToPropertyName(field.getName(), VariableKind.FIELD); + String newPropertyName = manager.variableNameToPropertyName(newName, VariableKind.FIELD); + + boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); + PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false); + PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false); + + boolean shouldRenameSetterParameter = false; + + if (setter != null) { + String parameterName = manager.propertyNameToVariableName(propertyName, VariableKind.PARAMETER); + PsiParameter setterParameter = setter.getParameterList().getParameters()[0]; + shouldRenameSetterParameter = parameterName.equals(setterParameter.getName()); + } + + String newGetterName = ""; + String newSetterName = ""; + + if (getter != null) { + String getterId = getter.getName(); + newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId); + if (newGetterName.equals(getterId)) { + getter = null; + newGetterName = null; + } + } + + if (setter != null) { + newSetterName = PropertyUtil.suggestSetterName(newPropertyName); + final String newSetterParameterName = manager.propertyNameToVariableName(newPropertyName, VariableKind.PARAMETER); + if (newSetterName.equals(setter.getName())) { + setter = null; + newSetterName = null; + shouldRenameSetterParameter = false; + } else if (newSetterParameterName.equals(setter.getParameterList().getParameters()[0].getName())) { + shouldRenameSetterParameter = false; + } + } + + if (getter != null || setter != null) { + if (askToRenameAccesors(getter, setter, newName)) { + getter = null; + setter = null; + shouldRenameSetterParameter = false; + } + } + + if (getter != null) { + addOverriddenAndImplemented(aClass, getter, newGetterName); + } + + if (setter != null) { + addOverriddenAndImplemented(aClass, setter, newSetterName); + } + + if (shouldRenameSetterParameter) { + PsiParameter parameter = setter.getParameterList().getParameters()[0]; + myElements.add(parameter); + myNames.add(manager.propertyNameToVariableName(newPropertyName, VariableKind.PARAMETER)); + } + } + + protected boolean askToRenameAccesors(PsiMethod getter, PsiMethod setter, String newName) { + String text = RefactoringMessageUtil.getGetterSetterMessage(newName, "Rename", getter, setter); + return Messages.showYesNoDialog(myProject, text, "Rename", Messages.getQuestionIcon()) != 0; + } + + private void addOverriddenAndImplemented(PsiClass aClass, PsiMethod methodPrototype, String newName) { + final HashSet superClasses = new HashSet(); + RefactoringHierarchyUtil.getSuperClasses(aClass, superClasses, true); + superClasses.add(aClass); + + for (Iterator iterator = superClasses.iterator(); iterator.hasNext();) { + PsiClass superClass = iterator.next(); + + PsiMethod method = superClass.findMethodBySignature(methodPrototype, false); + + if (method != null) { + myElements.add(method); + myNames.add(newName); + } + } + } + + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new RenameViewDescriptor(myElement, myElements, myNames, mySearchInComments, mySearchInNonJavaFiles, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + myRenamers.clear(); + if (myElement instanceof PsiDirectory) { + final UsageInfo[] usages = RenameUtil.findUsages(((PsiDirectory) myElement).getPackage(), myNewName, mySearchInComments, mySearchInNonJavaFiles); + return UsageViewUtil.removeDuplicatedUsages(usages); + } + + ArrayList result = new ArrayList(); + + for (int i = 0; i < myElements.size(); i++) { + PsiElement element = myElements.get(i); + final String newName = myNames.get(i); + if (element instanceof PsiDirectory) continue; + final UsageInfo[] usages = RenameUtil.findUsages(element, newName, + mySearchInComments, mySearchInNonJavaFiles); + result.addAll(Arrays.asList(usages)); + if (element instanceof PsiClass && myShouldRenameVariables) { + myRenamers.add(new AutomaticVariableRenamer((PsiClass) element, newName, Arrays.asList(usages))); + } + if (element instanceof PsiClass && myShouldRenameInheritors) { + if (((PsiClass)element).getName() != null) { + myRenamers.add(new InheritorRenamer((PsiClass) element, newName)); + } + } + + if (element instanceof PsiClass && myShouldRenameForms) { + myRenamers.add(new FormsRenamer((PsiClass) element, newName)); + } + } + // add usages in ejb-jar.xml regardless of mySearchInNonJavaFiles setting + // delete erroneous usages in ejb-jar.xml (e.g. belonging to another ejb) + EjbUsagesUtil.adjustEjbUsages(myElements, myNames, result); + + if (myElement != null) { + // add usages in ejb-jar.xml regardless of mySearchInNonJavaFiles setting + // delete erroneous usages in ejb-jar.xml (e.g. belonging to another ejb) + EjbUsagesUtil.adjustEjbUsages(myElement, myNewName, result); + } + + UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos); + return usageInfos; + } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length > 0); + if (myElement != null) { + myElement = elements[0]; + } + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + myElements.set(i, element); + } + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myPreviewUsages; + if (!isNonCodeElements() && UsageViewUtil.hasNonCodeUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in comments, strings and non-java files"); + } else if (UsageViewUtil.hasReadOnlyUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + return toPreview; + } + + private boolean isNonCodeElements() { + for (Iterator iterator = myElements.iterator(); iterator.hasNext();) { + PsiElement element = iterator.next(); + if (!(element instanceof PsiAntElement) && //TODO:find a better way + !(element instanceof XmlElement)) return false; + } + return true; + } + + protected void performRefactoring(UsageInfo[] usages) { + HashSet xmlTagsSet = new HashSet(); + ArrayList specialRenaming = findXmlTags(usages, xmlTagsSet); + + List> listenersForPackages = new ArrayList>(); + for (int i = 0; i < myElements.size(); i++) { + PsiElement element = myElements.get(i); + if (element instanceof XmlTag && xmlTagsSet.contains(element)) continue; + String newName = myNames.get(i); + + final RefactoringElementListener elementListener = getTransaction().getElementListener(element); + RenameUtil.doRename(element, newName, extractUsagesForElement(element, usages), myProject, elementListener); + if (element instanceof PsiPackage) { + final PsiPackage psiPackage = (PsiPackage) element; + final String newQualifiedName = RenameUtil.getQualifiedNameAfterRename(psiPackage.getQualifiedName(), newName); + listenersForPackages.add(Pair.create(newQualifiedName, elementListener)); + } + } + + final PsiManager psiManager = PsiManager.getInstance(myProject); + for (int i = 0; i < listenersForPackages.size(); i++) { + Pair pair = listenersForPackages.get(i); + final PsiPackage aPackage = psiManager.findPackage(pair.getFirst()); + LOG.assertTrue(aPackage != null); + pair.getSecond().elementRenamed(aPackage); + } + + final UsageInfo[] usagesForNonCodeRenaming; + if (specialRenaming.isEmpty()) { + usagesForNonCodeRenaming = usages; + } else { + specialRenaming.addAll(Arrays.asList(usages)); + usagesForNonCodeRenaming = specialRenaming.toArray(new UsageInfo[specialRenaming.size()]); + } + myUsagesForNonCodeRenaming = usagesForNonCodeRenaming; + } + + protected void performPsiSpoilingRefactoring() { + RefactoringUtil.renameNonCodeUsages(myProject, myUsagesForNonCodeRenaming); + } + + private ArrayList findXmlTags(UsageInfo[] usages, HashSet xmlTagsSet) { + ArrayList specialRenaming = new ArrayList(); + for (int i = 0; i < myElements.size(); i++) { + PsiElement element = myElements.get(i); + if (element instanceof XmlTag) { + final PsiFile containingFile = element.getContainingFile(); + usagesLoop: + for (int j = 0; j < usages.length; j++) { + UsageInfo usage = usages[j]; + if (usage.isNonCodeUsage) { + final PsiFile usageFile = usage.getElement().getContainingFile(); + if (usageFile.getManager().areElementsEquivalent(usageFile, containingFile)) { + xmlTagsSet.add((XmlTag)element); + final XmlTag xmlTag = (XmlTag) element; + final String newName = myNames.get(i); + String newText = + "<" + xmlTag.getName() + ">" + newName + ""; + TextRange range = xmlTag.getTextRange(); + specialRenaming.add(NonCodeUsageInfo.create(xmlTag.getContainingFile(), range.getStartOffset(), range.getEndOffset(), xmlTag, newText)); + break usagesLoop; + } + } + } + } + } + return specialRenaming; + } + + + protected String getCommandName() { + return myCommandName; + } + + private static UsageInfo[] extractUsagesForElement(PsiElement element, UsageInfo[] usages) { + if (element instanceof PsiDirectory) { + element = ((PsiDirectory) element).getPackage(); + LOG.assertTrue(element != null); + } + + final ArrayList extractedUsages = new ArrayList(usages.length); + for (int idx = 0; idx < usages.length; idx++) { + UsageInfo usage = usages[idx]; + + LOG.assertTrue(usage instanceof MoveRenameUsageInfo); + + MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo) usage; + if (element.equals(usageInfo.referencedElement)) { + extractedUsages.add(usageInfo); + } + } + return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); + } + + protected void prepareMethodRenaming(PsiMethod method, String newName) { + final EjbMethodRole role = J2EERolesUtil.getEjbRole(method); + if (role == null) return; + + if (role instanceof EjbDeclMethodRole) { + final PsiMethod[] implementations = EjbUtil.findEjbImplementations(method); + if (implementations.length == 0) return; + + final String[] names = EjbDeclMethodRole.suggestImplNames(newName, role.getType(), role.getEjb()); + for (int i = 0; i < implementations.length; i++) { + if (i < names.length && names[i] != null) { + myElements.add(implementations[i]); + myNames.add(names[i]); + } + } + } + } + + protected void prepareTestRun() { + prepareRenaming(); + } + + public List getNewNames() { + return Collections.unmodifiableList(myNames); + } + + public void setSearchInComments(boolean value) { + mySearchInComments = value; + } + + public void setSearchInNonJavaFiles(boolean searchInNonJavaFiles) { + mySearchInNonJavaFiles = searchInNonJavaFiles; + } + + public boolean isSearchInComments() { + return mySearchInComments; + } + + public boolean isSearchInNonJavaFiles() { + return mySearchInNonJavaFiles; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameUtil.java new file mode 100644 index 00000000000..f0d61ea0015 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameUtil.java @@ -0,0 +1,884 @@ +package com.intellij.refactoring.rename; + +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.NonCodeUsageInfo; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.Queue; + +import java.util.*; +import java.util.regex.Pattern; + +public class RenameUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameUtil"); + public static boolean ourRenameXmlAttributeValuesInReverseOrder = false; + + public static UsageInfo[] findUsages(final PsiElement element, + String newName, + boolean searchInStringsAndComments, + boolean searchInNonJavaFiles) { + final List results = new ArrayList(); + + PsiManager manager = element.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + + PsiReference[] refs = helper.findReferencesIncludingOverriding(method, projectScope, true); + for (int i = 0; i < refs.length; i++) { + PsiReference ref = refs[i]; + results.add(new MoveRenameUsageInfo(ref.getElement(), ref, element)); + } + + PsiElement[] overridings = helper.findOverridingMethods(method, projectScope, true); + for (int i = 0; i < overridings.length; i++) { + PsiElement element1 = overridings[i]; + results.add(new MoveRenameUsageInfo(element1, null, element)); + } + } + else { + PsiReference[] refs = helper.findReferences(element, projectScope, false); + final ClassCollisionsDetector classCollisionsDetector; + if (element instanceof PsiClass) { + classCollisionsDetector = new ClassCollisionsDetector((PsiClass)element); + } + else { + classCollisionsDetector = null; + } + for (int i = 0; i < refs.length; i++) { + PsiReference ref = refs[i]; + PsiElement referenceElement = ref.getElement(); + results.add( + new MoveRenameUsageInfo(referenceElement, ref, ref.getRangeInElement().getStartOffset(), + ref.getRangeInElement().getEndOffset(), element, + referenceElement instanceof XmlElement)); + if (classCollisionsDetector == null) { + addLocalsCollisions(element, referenceElement, newName, results); + } + else { + classCollisionsDetector.addClassCollisions(referenceElement, newName, results); + } + } + } + + RenameUtil.findUnresolvableLocalsCollisions(element, newName, results); + RenameUtil.findUnresolvableMemberCollisions(element, newName, results); + + + if (searchInStringsAndComments && !(element instanceof PsiDirectory)) { + String stringToSearch = RefactoringUtil.getStringToSearch(element, false); + if (stringToSearch != null) { + final String stringToReplace = getStringToReplace(element, newName, false); + RefactoringUtil.UsageInfoFactory factory = new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + int start = usage.getTextRange().getStartOffset(); + return NonCodeUsageInfo.create(usage.getContainingFile(), start + startOffset, start + endOffset, element, stringToReplace); + } + }; + RefactoringUtil.addUsagesInStringsAndComments(element, stringToSearch, results, factory); + } + } + + + if (searchInNonJavaFiles && !(element instanceof PsiDirectory)) { + String stringToSearch = RefactoringUtil.getStringToSearch(element, true); + + if (stringToSearch != null) { + final String stringToReplace = getStringToReplace(element, newName, true); + RefactoringUtil.UsageInfoFactory factory = new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + int start = usage.getTextRange().getStartOffset(); + return NonCodeUsageInfo.create(usage.getContainingFile(), start + startOffset, start + endOffset, element, stringToReplace); + } + }; + RefactoringUtil.addUsagesInNonJavaFiles(element, stringToSearch, projectScope, results, factory); + + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + if (aClass.getParent() instanceof PsiClass) { + final String dollaredStringToSearch = RefactoringUtil.getInnerClassNameForClassLoader(aClass); + final String dollaredStringToReplace = + RefactoringUtil.getNewInnerClassName(aClass, dollaredStringToSearch, newName); + RefactoringUtil.UsageInfoFactory dollaredFactory = new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + int start = usage.getTextRange().getStartOffset(); + return NonCodeUsageInfo.create(usage.getContainingFile(), start + startOffset, start + endOffset, element, dollaredStringToReplace); + } + }; + RefactoringUtil.addUsagesInNonJavaFiles(aClass, dollaredStringToSearch, projectScope, results, + dollaredFactory); + } + } + } + } + + return results.toArray(new UsageInfo[results.size()]); + } + + public static void buildPackagePrefixChangedMessage(final VirtualFile[] virtualFiles, StringBuffer message, final String qualifiedName) { + if (virtualFiles.length > 0) { + message.append("Package " + qualifiedName + " occurs in package prefixes of the following source folders:\n"); + for (int i = 0; i < virtualFiles.length; i++) { + final VirtualFile virtualFile = virtualFiles[i]; + message.append(virtualFile.getPresentableUrl() + "\n"); + } + message.append("These package prefixes will be changed."); + } + } + + private static class ClassCollisionsDetector { + final HashSet myProcessedFiles = new HashSet(); + final PsiClass myRenamedClass; + private String myRenamedClassQualifiedName; + + public ClassCollisionsDetector(PsiClass renamedClass) { + myRenamedClass = renamedClass; + myRenamedClassQualifiedName = myRenamedClass.getQualifiedName(); + } + + public void addClassCollisions(PsiElement referenceElement, String newName, List results) { + final PsiClass renamedClass = myRenamedClass; + final PsiResolveHelper resolveHelper = referenceElement.getManager().getResolveHelper(); + final PsiSearchHelper searchHelper = referenceElement.getManager().getSearchHelper(); + final PsiClass aClass = resolveHelper.resolveReferencedClass(newName, referenceElement); + if (aClass == null) return; + final PsiFile containingFile = referenceElement.getContainingFile(); + final String text = referenceElement.getText(); + if (Comparing.equal(myRenamedClassQualifiedName, removeSpaces(text))) return; + if (myProcessedFiles.contains(containingFile)) return; + final PsiReference[] references = searchHelper.findReferences(aClass, new LocalSearchScope(containingFile), + false); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement collisionReferenceElement = reference.getElement(); + if (collisionReferenceElement instanceof PsiJavaCodeReferenceElement) { + final PsiElement parent = collisionReferenceElement.getParent(); + if (!(parent instanceof PsiImportStatement)) { + if (aClass.getQualifiedName() != null) { + results.add(new ClassHidesImportedClassUsageInfo((PsiJavaCodeReferenceElement)collisionReferenceElement, + renamedClass, aClass)); + } else { + results.add(new ClassHidesUnqualifiableClassUsageInfo((PsiJavaCodeReferenceElement) collisionReferenceElement, + renamedClass, aClass)); + } + } + else { + results.add(new CollidingClassImportUsageInfo((PsiImportStatement)parent, renamedClass)); + } + } + } + myProcessedFiles.add(containingFile); + } + } + + private static final Pattern WHITE_SPACE_PATTERN = Pattern.compile("\\s"); + + private static String removeSpaces(String s) { + return WHITE_SPACE_PATTERN.matcher(s).replaceAll(""); + } + + public static void findUnresolvableMemberCollisions(final PsiElement element, final String newName, List result) { + try { + PsiManager manager = element.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + final PsiSearchHelper helper = manager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod)element; + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) return; + if (method.hasModifierProperty(PsiModifier.PRIVATE)) return; + PsiClass[] inheritors = helper.findInheritors(containingClass, projectScope, true); + + PsiMethod prototype = (PsiMethod)element.copy(); + prototype.getNameIdentifier().replace(factory.createIdentifier(newName)); + + final PsiMethod existingMethod = containingClass.findMethodBySignature(prototype, true); + if (existingMethod != null && manager.getResolveHelper().isAccessible(existingMethod, containingClass, null)) { + result.add(new MemberExistsUsageInfo(existingMethod, method)); + } + + for (int i = 0; i < inheritors.length; i++) { + PsiClass inheritor = inheritors[i]; + + PsiMethod conflictingMethod = inheritor.findMethodBySignature(prototype, false); + if (conflictingMethod != null) { + result.add(new SubmemberHidesMemberUsageInfo(conflictingMethod, method)); + } + } + + } + else if (element instanceof PsiField) { + final PsiField field = (PsiField)element; + if (field.getContainingClass() == null) return; + if (field.hasModifierProperty(PsiModifier.PRIVATE)) return; + final PsiClass containingClass = field.getContainingClass(); + final PsiField existingField = containingClass.findFieldByName(newName, true); + if (existingField != null && manager.getResolveHelper().isAccessible(existingField, containingClass, null)) { + result.add(new MemberExistsUsageInfo(existingField, field)); + } + PsiClass[] inheritors = helper.findInheritors(containingClass, projectScope, true); + for (int i = 0; i < inheritors.length; i++) { + PsiClass inheritor = inheritors[i]; + + PsiField conflictingField = inheritor.findFieldByName(newName, false); + if (conflictingField != null) { + result.add(new SubmemberHidesMemberUsageInfo(conflictingField, field)); + } + } + } + else if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + if (aClass.getParent() instanceof PsiClass) { + PsiClass[] inheritors = helper.findInheritors((PsiClass)aClass.getParent(), projectScope, true); + for (int i = 0; i < inheritors.length; i++) { + PsiClass inheritor = inheritors[i]; + + PsiClass[] inners = inheritor.getInnerClasses(); + for (int j = 0; j < inners.length; j++) { + PsiClass inner = inners[j]; + + if (inner.getName().equals(newName)) { + result.add(new SubmemberHidesMemberUsageInfo(inner, aClass)); + } + } + } + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + public static class ConflictingLocalVariablesVisitor extends PsiRecursiveElementVisitor { + protected final String myName; + protected RenameUtil.CollidingVariableVisitor myCollidingNameVisitor; + + public ConflictingLocalVariablesVisitor(String newName, RenameUtil.CollidingVariableVisitor collidingNameVisitor) { + myName = newName; + myCollidingNameVisitor = collidingNameVisitor; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitElement(expression); + } + + public void visitClass(PsiClass aClass) { + } + + public void visitVariable(PsiVariable variable) { + if (myName.equals(variable.getName())) { + myCollidingNameVisitor.visitCollidingElement(variable); + } + } + } + + public static void findUnresolvableLocalsCollisions(final PsiElement element, final String newName, + final List result) { + if (!(element instanceof PsiLocalVariable || element instanceof PsiParameter)) { + return; + } + + + PsiElement scope; + PsiElement anchor = null; + if (element instanceof PsiLocalVariable) { + scope = RefactoringUtil.getVariableScope((PsiLocalVariable)element); + if (!(element instanceof ImplicitVariable)) { + anchor = element.getParent(); + } + } + else { + // element is a PsiParameter + scope = ((PsiParameter)element).getDeclarationScope(); + } + LOG.assertTrue(scope != null); + + final CollidingVariableVisitor collidingNameVisitor = new CollidingVariableVisitor() { + public void visitCollidingElement(PsiVariable collidingVariable) { + if (collidingVariable.equals(element) || collidingVariable instanceof PsiField) return; + LocalHidesRenamedLocalUsageInfo collision = new LocalHidesRenamedLocalUsageInfo(element, collidingVariable); + result.add(collision); + } + }; + + visitLocalsCollisions(element, newName, scope, anchor, collidingNameVisitor); + + + /*PsiElement place = scope.getLastChild(); + PsiResolveHelper helper = place.getManager().getResolveHelper(); + PsiVariable refVar = helper.resolveReferencedVariable(newName, place, null); + + if (refVar != null) { + LocalHidesRenamedLocalUsageInfo collision = new LocalHidesRenamedLocalUsageInfo(element, refVar); + result.add(collision); + }*/ + } + + public static void visitLocalsCollisions(PsiElement element, final String newName, + PsiElement scope, + PsiElement place, + final CollidingVariableVisitor collidingNameVisitor) { + if (scope == null) return; + visitDownstreamCollisions(scope, place, newName, collidingNameVisitor); + visitUpstreamLocalCollisions(element, scope, newName, collidingNameVisitor); + } + + private static void visitDownstreamCollisions(PsiElement scope, PsiElement place, final String newName, + final CollidingVariableVisitor collidingNameVisitor + ) { + ConflictingLocalVariablesVisitor collector = + new ConflictingLocalVariablesVisitor(newName, collidingNameVisitor); + if (place == null) { + scope.accept(collector); + } + else { + LOG.assertTrue(place.getParent() == scope); + for (PsiElement sibling = place; sibling != null; sibling = sibling.getNextSibling()) { + sibling.accept(collector); + } + + } + } + + public interface CollidingVariableVisitor { + void visitCollidingElement(PsiVariable collidingVariable); + } + + public static void visitUpstreamLocalCollisions(PsiElement element, PsiElement scope, + String newName, + final CollidingVariableVisitor collidingNameVisitor) { + final PsiVariable collidingVariable = scope.getManager().getResolveHelper().resolveReferencedVariable(newName, + scope); + if (collidingVariable instanceof PsiLocalVariable || collidingVariable instanceof PsiParameter) { + final PsiElement commonParent = PsiTreeUtil.findCommonParent(element, collidingVariable); + if (commonParent != null) { + PsiElement current = element; + while (current != null && current != commonParent) { + if (current instanceof PsiMethod || current instanceof PsiClass) { + return; + } + current = current.getParent(); + } + } + } + + if (collidingVariable != null) { + collidingNameVisitor.visitCollidingElement(collidingVariable); + } + } + + + private static void addLocalsCollisions(PsiElement element, PsiElement ref, + String newName, List results) { + if (!(element instanceof PsiLocalVariable) && !(element instanceof PsiParameter)) return; + + PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class); + if (containingClass == null) return; + + + PsiElement scopeElement; + if (element instanceof PsiLocalVariable) { + scopeElement = RefactoringUtil.getVariableScope((PsiLocalVariable)element); + } + else { // Parameter + scopeElement = ((PsiParameter) element).getDeclarationScope(); + } + + LOG.assertTrue(scopeElement != null); + + PsiField field = containingClass.findFieldByName(newName, true); + if (field == null) return; + + PsiSearchHelper helper = ref.getManager().getSearchHelper(); + PsiReference[] collidingRefs = helper.findReferences(field, new LocalSearchScope(scopeElement), false); + for (int i = 0; i < collidingRefs.length; i++) { + PsiElement collidingRef = collidingRefs[i].getElement(); + + if (collidingRef instanceof PsiReferenceExpression + && ((PsiReferenceExpression)collidingRef).getQualifierExpression() == null) { + results.add(new LocalHidesFieldUsageInfo(collidingRef, element)); + } + } + } + + private static String getStringToReplace(PsiElement element, String newName, boolean nonJava) { + if (element instanceof PsiDirectory) { // normalize a directory to a corresponding package + element = ((PsiDirectory)element).getPackage(); + } + + if (element instanceof PsiPackage) { + if (nonJava) { + String qName = ((PsiPackage)element).getQualifiedName(); + int index = qName.lastIndexOf('.'); + return index < 0 ? newName : qName.substring(0, index + 1) + newName; + } + else { + return newName; + } + } + else if (element instanceof PsiClass) { + if (nonJava) { + final PsiClass aClass = (PsiClass)element; + return getQualifiedNameAfterRename(aClass, newName); + } + else { + return newName; + } + } + else if (element instanceof PsiNamedElement) { + return newName; + } + else { + LOG.error("Unknown element type"); + return null; + } + } + + public static String getQualifiedNameAfterRename(final PsiClass aClass, String newName) { + String qName = aClass.getQualifiedName(); + return getQualifiedNameAfterRename(qName, newName); + } + + static String getQualifiedNameAfterRename(String qName, String newName) { + int index = qName != null ? qName.lastIndexOf('.') : -1; + return index < 0 ? newName : qName.substring(0, index + 1) + newName; + } + + public static void checkRename(PsiElement element, String newName) throws IncorrectOperationException { + if (element instanceof PsiDirectory) { + ((PsiDirectory)element).checkSetName(newName); + } + if (element instanceof PsiPackage) { + ((PsiPackage)element).checkSetName(newName); + } + } + + public static void doRename(final PsiElement element, String newName, UsageInfo[] usages, final Project project, + RefactoringElementListener listener) { + try { + if (element instanceof PsiDirectory) { + doRenameDirectory((PsiDirectory)element, newName, usages, listener); + } + else if (element instanceof PsiClass) { + doRenameClass((PsiClass)element, newName, usages, listener); + } + else if (element instanceof PsiMethod) { + doRenameMethod((PsiMethod)element, newName, usages, listener); + } + else if (element instanceof PsiVariable) { + doRenameVariable((PsiVariable)element, newName, usages, listener); + } + else if (element instanceof XmlTag) { + doRenameXmlTag((XmlTag)element, newName, listener); + } + else if (element instanceof XmlAttribute) { + doRenameXmlAttribute((XmlAttribute)element, newName, listener); + } + else if (element instanceof XmlAttributeValue) { + doRenameXmlAttributeValue((XmlAttributeValue)element, newName, usages, listener); + } + else if (element instanceof PsiPointcutDef) { + doRenamePointcutDef((PsiPointcutDef)element, newName, usages, listener); + } + else if (element instanceof PsiPackage) { + final PsiPackage psiPackage = (PsiPackage)element; + psiPackage.handleQualifiedNameChange(getQualifiedNameAfterRename(psiPackage.getQualifiedName(), newName)); + } + else if (element instanceof PsiNamedElement) { + doRenameGenericNamedElement((PsiNamedElement) element, newName, usages, listener); + } + else { + LOG.error("Unknown element type"); + } + } + catch (final IncorrectOperationException e) { + // may happen if the file or package cannot be renamed. e.g. locked by another application + if (ApplicationManager.getApplication().isUnitTestMode()) { + LOG.error(e); + return; + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + RefactoringMessageUtil.showErrorMessage("Rename", e.getMessage(), HelpID.getRenameHelpID(element), project); + } + }); + } + } + + private static void doRenameGenericNamedElement(PsiNamedElement namedElement, String newName, UsageInfo[] usages, RefactoringElementListener listener) + throws IncorrectOperationException { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + rename(usage, newName); + } + namedElement.setName(newName); + listener.elementRenamed(namedElement); + } + + private static void doRenamePointcutDef(PsiPointcutDef pointcutDef, + String newName, + UsageInfo[] usages, + RefactoringElementListener listener) throws IncorrectOperationException { + PsiManager manager = pointcutDef.getManager(); + PsiElementFactory factory = manager.getElementFactory(); + PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); + + pointcutDef.getNameIdentifier().replace(newNameIdentifier); + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + rename(usage, newName); + } + + listener.elementRenamed(pointcutDef); + } + + private static void doRenameXmlAttribute(XmlAttribute attribute, + String newName, + RefactoringElementListener listener) { + try { + final PsiElement element = attribute.setName(newName); + listener.elementRenamed(element); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private static void doRenameXmlAttributeValue(XmlAttributeValue value, + String newName, + UsageInfo[] infos, + RefactoringElementListener listener) + throws IncorrectOperationException { + LOG.assertTrue(value != null); + LOG.assertTrue(value.isValid()); + + renameAll(value, infos, newName, value.getValue()); + + PsiManager psiManager = value.getManager(); + LOG.assertTrue(psiManager != null); + PsiElementFactory elementFactory = psiManager.getElementFactory(); + LOG.assertTrue(elementFactory != null); + + XmlFile file = (XmlFile)elementFactory.createFileFromText("dummy.xml", "
    "); + final PsiElement element = value.replace(file.getDocument().getRootTag().getAttributes()[0].getValueElement()); + listener.elementRenamed(element); + } + + private static void renameAll(PsiElement originalElement, UsageInfo[] infos, String newName, String originalName) + throws IncorrectOperationException { + if (newName.equals(originalName)) return; + final PsiSearchHelper searchHelper = originalElement.getManager().getSearchHelper(); + Queue queue = new Queue(infos.length); + if (ourRenameXmlAttributeValuesInReverseOrder) { + LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode()); + ArrayList tmp = new ArrayList(Arrays.asList(infos)); + Collections.reverse(tmp); + infos = tmp.toArray(new UsageInfo[tmp.size()]); + } + for (int i = 0; i < infos.length; i++) { + UsageInfo info = infos[i]; + if (info.getElement() == null || !info.getElement().isValid()) continue; + PsiReference ref = ((MoveRenameUsageInfo)info).reference; + if (ref == null) continue; + queue.addLast(ref); + } + + while(!queue.isEmpty()) { + final PsiReference reference = queue.pullFirst(); + final PsiElement oldElement = reference.getElement(); + if (!oldElement.isValid()) continue; + final PsiElement newElement = reference.handleElementRename(newName); + if (!oldElement.isValid()) { + final PsiReference[] references = searchHelper.findReferences(originalElement, new LocalSearchScope(newElement), false); + for (int i = 0; i < references.length; i++) { + PsiReference psiReference = references[i]; + queue.addLast(psiReference); + } + } + } + } + + private static void doRenameXmlTag(XmlTag xmlTag, String newName, RefactoringElementListener listener) { + try { + XmlTag newTag = xmlTag.getManager().getElementFactory().createTagFromText( + "<" + xmlTag.getName() + ">" + newName + ""); + final PsiElement element = xmlTag.replace(newTag); + listener.elementRenamed(element); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + /** + * renames a directory and corrects references to the package that corresponds to this directory + */ + private static void doRenameDirectory(PsiDirectory aDirectory, + String newName, + UsageInfo[] usages, + RefactoringElementListener listener) throws IncorrectOperationException { + // rename all non-package statement references + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (PsiTreeUtil.getParentOfType(usage.getElement(), PsiPackageStatement.class) != null) continue; + rename(usage, newName); + } + + //rename package statement + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (PsiTreeUtil.getParentOfType(usage.getElement(), PsiPackageStatement.class) == null) continue; + rename(usage, newName); + } + + aDirectory.setName(newName); + listener.elementRenamed(aDirectory); + } + + private static void rename(UsageInfo info, String newName) throws IncorrectOperationException { + if (info.getElement() == null || !info.getElement().isValid()) return; + PsiReference ref = ((MoveRenameUsageInfo)info).reference; + if (ref == null) return; + ref.handleElementRename(newName); + } + + private static void doRenameClass(PsiClass aClass, + String newName, + UsageInfo[] usages, + RefactoringElementListener listener) throws IncorrectOperationException { + ArrayList postponedCollisions = new ArrayList(); + // rename all references + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + if (!(usage instanceof ResolvableCollisionUsageInfo)) { + rename(usage, newName); + } + else { + if (usage instanceof CollidingClassImportUsageInfo) { + ((CollidingClassImportUsageInfo)usage).getImportStatement().delete(); + } + else { + postponedCollisions.add(usage); + } + } + } + + // do actual rename + aClass.setName(newName); + + // resolve collisions + for (int i = 0; i < postponedCollisions.size(); i++) { + ClassHidesImportedClassUsageInfo collision = (ClassHidesImportedClassUsageInfo)postponedCollisions.get(i); + collision.resolveCollision(); + } + listener.elementRenamed(aClass); + } + + private static void doRenameMethod(PsiMethod method, + String newName, + UsageInfo[] usages, + RefactoringElementListener listener) throws IncorrectOperationException { + // do actual rename of overriding/implementing methods and of references to all them + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) { + continue; + } + if (!(usage.getElement() instanceof PsiMethod)) { + final PsiReference ref; + if (usage instanceof MoveRenameUsageInfo) { + ref = ((MoveRenameUsageInfo) usage).reference; + } + else { + ref = usage.getElement().getReference(); + } + if (ref != null) { + ref.handleElementRename(newName); + } + } + } + + // do actual rename of method + method.setName(newName); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) { + continue; + } + if (usage.getElement() instanceof PsiMethod) { + ((PsiMethod)usage.getElement()).setName(newName); + } + } + listener.elementRenamed(method); + } + + private static void doRenameVariable(PsiVariable variable, + String newName, + UsageInfo[] usages, + RefactoringElementListener listener) throws IncorrectOperationException { + // rename all references + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!usage.getElement().isValid()) { + continue; + } + + if (!(usage instanceof LocalHidesFieldUsageInfo)) { + final PsiReference ref; + if (!(usage instanceof MoveRenameUsageInfo)) { + ref = usage.getElement().getReference(); + } + else { + ref = ((MoveRenameUsageInfo)usage).reference; + } + if (ref != null) { + PsiElement newElem = ref.handleElementRename(newName); + if (variable instanceof PsiField) { + fixPossibleNameCollisionsForFieldRenaming((PsiField)variable, newName, newElem); + } + } + } + else { + PsiJavaCodeReferenceElement collidingRef = (PsiJavaCodeReferenceElement)usage.getElement(); + PsiElement resolved = collidingRef.resolve(); + + if (resolved instanceof PsiField) { + qualifyField((PsiField)resolved, collidingRef, newName); + } + else { + // do nothing + } + } + } + // do actual rename + //PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); + //variable.getNameIdentifier().replace(newNameIdentifier); + variable.setName(newName); + listener.elementRenamed(variable); + } + + + private static void fixPossibleNameCollisionsForFieldRenaming(PsiField field, String newName, + PsiElement replacedOccurence) + throws IncorrectOperationException { + if (!(replacedOccurence instanceof PsiReferenceExpression)) return; + PsiElement elem = ((PsiReferenceExpression)replacedOccurence).resolve(); + + if (elem == null) { + // If reference is unresolved, then field is not hidden by anyone... + return; + } + + if (elem instanceof PsiLocalVariable || elem instanceof PsiParameter) { + qualifyField(field, replacedOccurence, newName); + } + } + + private static void qualifyField(PsiField field, PsiElement occurence, String newName) + throws IncorrectOperationException { + PsiManager psiManager = occurence.getManager(); + PsiElementFactory factory = psiManager.getElementFactory(); + if (!field.hasModifierProperty(PsiModifier.STATIC)) { + PsiReferenceExpression qualified = + (PsiReferenceExpression)factory.createExpressionFromText("this." + newName, null); + qualified = (PsiReferenceExpression)CodeStyleManager.getInstance(psiManager.getProject()).reformat(qualified); + occurence.replace(qualified); + } + else { + PsiReferenceExpression qualified = + (PsiReferenceExpression)factory.createExpressionFromText("a." + newName, null); + qualified = (PsiReferenceExpression)CodeStyleManager.getInstance(psiManager.getProject()).reformat(qualified); + qualified.getQualifierExpression().replace( + factory.createReferenceExpression(field.getContainingClass())); + occurence.replace(qualified); + } + } + + public static PsiReferenceExpression createFieldReference(PsiField field, PsiElement context) throws IncorrectOperationException { + final PsiManager manager = field.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + final String name = field.getName(); + PsiReferenceExpression ref = (PsiReferenceExpression) factory.createExpressionFromText(name, context); + PsiElement resolved = ref.resolve(); + if (manager.areElementsEquivalent(resolved, field)) return ref; + final PsiJavaCodeReferenceElement qualifier; + if (!field.hasModifierProperty(PsiModifier.STATIC)) { + ref = (PsiReferenceExpression)factory.createExpressionFromText("this." + name, context); + resolved = ref.resolve(); + if (manager.areElementsEquivalent(resolved, field)) return ref; + ref = (PsiReferenceExpression) factory.createExpressionFromText("A.this." + name, null); + qualifier = ((PsiThisExpression)ref.getQualifierExpression()).getQualifier(); + final PsiClass containingClass = field.getContainingClass(); + final PsiJavaCodeReferenceElement classReference = factory.createClassReferenceElement(containingClass); + qualifier.replace(classReference); + } else { + ref = (PsiReferenceExpression)factory.createExpressionFromText("A." + name, context); + qualifier = (PsiReferenceExpression)ref.getQualifierExpression(); + final PsiClass containingClass = field.getContainingClass(); + final PsiReferenceExpression classReference = factory.createReferenceExpression(containingClass); + qualifier.replace(classReference); + } + return ref; + } + + public static void removeConflictUsages(Set usages) { + for (Iterator iterator = usages.iterator(); iterator.hasNext();) { + UsageInfo usageInfo = iterator.next(); + if (usageInfo instanceof UnresolvableCollisionUsageInfo) { + iterator.remove(); + } + } + } + + public static String[] getConflictDescriptions(UsageInfo[] usages) { + ArrayList descriptions = new ArrayList(); + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + + if (usage instanceof UnresolvableCollisionUsageInfo) { + descriptions.add(((UnresolvableCollisionUsageInfo)usage).getDescription()); + } + + } + return descriptions.toArray(ArrayUtil.EMPTY_STRING_ARRAY); + } + + public static void buildMultipleDirectoriesInPackageMessage(StringBuffer message, + PsiPackage aPackage, + PsiDirectory[] directories) { + message.append("Multiple directories correspond to package\n"); + message.append(aPackage.getQualifiedName()); + message.append(" :\n\n"); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (i > 0) { + message.append("\n"); + } + message.append(directory.getVirtualFile().getPresentableUrl()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameVariableUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameVariableUsageInfo.java new file mode 100644 index 00000000000..674b6d80fff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameVariableUsageInfo.java @@ -0,0 +1,21 @@ +package com.intellij.refactoring.rename; + +import com.intellij.usageView.UsageInfo; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiVariable; + +/** + * @author dsl + */ +public class RenameVariableUsageInfo extends UsageInfo { + private String myNewName; + + public RenameVariableUsageInfo(PsiVariable element, String newName) { + super(element); + myNewName = newName; + } + + public String getNewName() { + return myNewName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameViewDescriptor.java new file mode 100644 index 00000000000..40b2d3d6a72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/RenameViewDescriptor.java @@ -0,0 +1,143 @@ + +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.HelpID; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +import java.util.ArrayList; + +class RenameViewDescriptor implements UsageViewDescriptor{ + private final boolean mySearchInComments; + private final boolean mySearchInNonJavaFiles; + private UsageInfo[] myUsages; + private String myProcessedElementsHeader; + private String myCodeReferencesText; + private final String myHelpID; + private FindUsagesCommand myRefreshCommand; + private ArrayList myElements; + + public RenameViewDescriptor( + PsiElement primaryElement, + ArrayList elements, + ArrayList names, + boolean isSearchInComments, + boolean isSearchInNonJavaFiles, + UsageInfo[] usages, + FindUsagesCommand refreshCommand) { + + myElements = elements; + + mySearchInComments = isSearchInComments; + mySearchInNonJavaFiles = isSearchInNonJavaFiles; + myUsages = usages; + myRefreshCommand = refreshCommand; + + StringBuffer processedElementsHeader = new StringBuffer(); + StringBuffer codeReferencesText = new StringBuffer(); + codeReferencesText.append("References in code to "); + + for (int i = 0; i < elements.size(); i++) { + final PsiElement element = (PsiElement)elements.get(i); + String newName = (String)names.get(i); + + String prefix = ""; + if (element instanceof PsiDirectory/* || element instanceof PsiClass*/){ + String fullName = UsageViewUtil.getLongName(element); + int lastDot = fullName.lastIndexOf('.'); + if (lastDot >= 0){ + prefix = fullName.substring(0, lastDot + 1); + } + } + + processedElementsHeader.append(UsageViewUtil.capitalize( + UsageViewUtil.getType(element) + " to be renamed to " + prefix + newName)); + codeReferencesText.append(UsageViewUtil.getType(element) + " " + UsageViewUtil.getLongName(element)); + + if (i < elements.size() - 1) { + processedElementsHeader.append(", "); + codeReferencesText.append(", "); + } + } + codeReferencesText.append(" "); + + myProcessedElementsHeader = processedElementsHeader.toString(); + myCodeReferencesText = codeReferencesText.toString(); + myHelpID = HelpID.getRenameHelpID(primaryElement); + } + + public PsiElement[] getElements() { + return (PsiElement[])myElements.toArray(new PsiElement[myElements.size()]); + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + myElements.set(i, element); + } + + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return myProcessedElementsHeader; + } + + public boolean isSearchInText() { + return mySearchInComments || mySearchInNonJavaFiles; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return OCCURRENCE_WORD; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return myCodeReferencesText + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return "Occurrences found in comments, strings and non-java files " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "occurrence"); + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return myHelpID; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ResolvableCollisionUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ResolvableCollisionUsageInfo.java new file mode 100644 index 00000000000..1c9a6c8f6b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/ResolvableCollisionUsageInfo.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 05.06.2002 + * Time: 12:27:26 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiElement; + +public abstract class ResolvableCollisionUsageInfo extends CollisionUsageInfo { + public ResolvableCollisionUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, referencedElement); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/SubmemberHidesMemberUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/SubmemberHidesMemberUsageInfo.java new file mode 100644 index 00000000000..38139faaed8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/SubmemberHidesMemberUsageInfo.java @@ -0,0 +1,34 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 05.06.2002 + * Time: 12:43:27 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.usageView.UsageViewUtil; + +public class SubmemberHidesMemberUsageInfo extends UnresolvableCollisionUsageInfo { + public SubmemberHidesMemberUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, referencedElement); + } + + public String getDescription() { + StringBuffer buffer = new StringBuffer(); + + buffer.append(ConflictsUtil.getDescription(getElement(), true)); + if (!(getElement() instanceof PsiMethod)) { + buffer.append(" will hide renamed "); + } + else { + buffer.append(" will override renamed "); + } + buffer.append(UsageViewUtil.getType(getElement())); + return ConflictsUtil.capitalize(buffer.toString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/UnresolvableCollisionUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/UnresolvableCollisionUsageInfo.java new file mode 100644 index 00000000000..85cf718cca9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/UnresolvableCollisionUsageInfo.java @@ -0,0 +1,19 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 05.06.2002 + * Time: 12:42:12 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.rename; + +import com.intellij.psi.PsiElement; + +public abstract class UnresolvableCollisionUsageInfo extends CollisionUsageInfo { + public UnresolvableCollisionUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element, referencedElement); + } + + public abstract String getDescription(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticRenamer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticRenamer.java new file mode 100644 index 00000000000..892771da6d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticRenamer.java @@ -0,0 +1,128 @@ +package com.intellij.refactoring.rename.naming; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiNamedElement; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author dsl + */ +public abstract class AutomaticRenamer { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.naming.AutomaticRenamer"); + protected final Map myRenames = new HashMap(); + protected final List myElements; + + protected AutomaticRenamer() { + myElements = new ArrayList(); + } + + public boolean hasAnythingToRename() { + final Collection strings = myRenames.values(); + for (Iterator iterator = strings.iterator(); iterator.hasNext();) { + final String s = iterator.next(); + if (s != null) return true; + } + return false; + } + + public void findUsages(List result, final boolean searchInStringsAndComments, final boolean searchInNonJavaFiles) { + for (Iterator iterator = myElements.iterator(); iterator.hasNext();) { + final PsiNamedElement variable = iterator.next(); + final boolean success = findUsagesForElement(variable, result, searchInStringsAndComments, searchInNonJavaFiles); + if (!success) { + iterator.remove(); + } + } + } + + private boolean findUsagesForElement(PsiNamedElement element, + List result, + final boolean searchInStringsAndComments, + final boolean searchInNonJavaFiles) { + final UsageInfo[] usages = RenameUtil.findUsages(element, myRenames.get(element.getName()), searchInStringsAndComments, searchInNonJavaFiles); + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + if (usage instanceof UnresolvableCollisionUsageInfo) return false; + } + result.addAll(Arrays.asList(usages)); + return true; + } + + public List getElements() { + return Collections.unmodifiableList(myElements); + } + + public String getNewName(PsiNamedElement var) { + return myRenames.get(var.getName()); + } + + public Map getRenames() { + return Collections.unmodifiableMap(myRenames); + } + + public void setRename(String name, String replacement) { + LOG.assertTrue(myRenames.containsKey(name)); + myRenames.put(name, replacement); + } + + public void doNotRename(String name) { + LOG.assertTrue(myRenames.containsKey(name)); + myRenames.remove(name); + for (int i = myElements.size() - 1; i >= 0; i--) { + final PsiNamedElement element = myElements.get(i); + if (name.equals(element.getName())) { + myElements.remove(i); + } + } + } + + protected void suggestAllNames(final String oldClassName, String newClassName) { + final NameSuggester suggester = new NameSuggester(oldClassName, newClassName); + for (int varIndex = myElements.size() - 1; varIndex >= 0; varIndex--) { + final T element = myElements.get(varIndex); + final String name = element.getName(); + if (!myRenames.containsKey(name)) { + String canonicalName = nameToCanonicalName(name, element); + final String newCanonicalName = suggester.suggestName(canonicalName); + if (newCanonicalName.length() == 0) { + LOG.assertTrue(false, + "oldClassName = " + oldClassName + + ", newClassName = " + newClassName + + ", name = " + name + + ", canonicalName = " + canonicalName + + ", newCanonicalName = " + newCanonicalName + ); + } + String newName = canonicalNameToName(newCanonicalName, element); + if (!newName.equals(name)) { + myRenames.put(name, newName); + } + else { + myRenames.put(name, null); + } + } + if (myRenames.get(name) == null) { + myElements.remove(varIndex); + } + } + } + + protected String canonicalNameToName(String canonicalName, T element) { + return canonicalName; + } + + protected String nameToCanonicalName(String name, T element) { + return name; + } + + public abstract String getDialogTitle(); + + public abstract String getDialogDescription(); + + public abstract String entityName(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticVariableRenamer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticVariableRenamer.java new file mode 100644 index 00000000000..35bd3f089ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/AutomaticVariableRenamer.java @@ -0,0 +1,59 @@ +package com.intellij.refactoring.rename.naming; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiTypeElement; +import com.intellij.psi.PsiVariable; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.usageView.UsageInfo; + +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class AutomaticVariableRenamer extends AutomaticRenamer { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.naming.AutomaticVariableRenamer"); + + public AutomaticVariableRenamer(PsiClass aClass, String newClassName, List usages) { + for (Iterator iterator = usages.iterator(); iterator.hasNext();) { + final UsageInfo info = iterator.next(); + if (info.getElement() instanceof PsiJavaCodeReferenceElement + && info.getElement().getParent() instanceof PsiTypeElement + && info.getElement().getParent().getParent() instanceof PsiVariable + ) { + myElements.add(((PsiVariable)info.getElement().getParent().getParent())); + } + } + suggestAllNames(aClass.getName(), newClassName); + } + + public String getDialogTitle() { + return "Rename Variables"; + } + + public String getDialogDescription() { + return "Rename variables with the following names to:"; + } + + public String entityName() { + return "Variable"; + } + + public void findUsages(List result, boolean searchInStringsAndComments, boolean searchInNonJavaFiles) { + super.findUsages(result, searchInStringsAndComments, searchInNonJavaFiles); + } + + public String nameToCanonicalName(String name, PsiVariable psiVariable) { + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(psiVariable.getManager()); + return codeStyleManager.variableNameToPropertyName(name, codeStyleManager.getVariableKind(psiVariable)); + } + + public String canonicalNameToName(String canonicalName, PsiVariable psiVariable) { + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(psiVariable.getManager()); + return codeStyleManager.propertyNameToVariableName(canonicalName, codeStyleManager.getVariableKind(psiVariable)); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/FormsRenamer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/FormsRenamer.java new file mode 100644 index 00000000000..32f93bc7331 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/FormsRenamer.java @@ -0,0 +1,44 @@ +package com.intellij.refactoring.rename.naming; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; + +/** + * @author ven + */ +public class FormsRenamer extends AutomaticRenamer { + public String nameToCanonicalName(String name, PsiFile psiFile) { + if (name.endsWith(".form")) return name.substring(0, name.length() - ".form".length()); + return name; + } + + public String canonicalNameToName(String canonicalName, PsiFile psiFile) { + return canonicalName.indexOf(".") < 0 ? canonicalName + ".form" : canonicalName; + } + + public FormsRenamer(PsiClass aClass, String newClassName) { + if (aClass.getQualifiedName() != null) { + PsiFile[] forms = aClass.getManager().getSearchHelper().findFormsBoundToClass(aClass.getQualifiedName()); + for (int i = 0; i < forms.length; i++) { + final PsiFile form = forms[i]; + if (form.getName() != null) { + myElements.add(form); + } + } + + suggestAllNames(aClass.getName(), newClassName); + } + } + + public String getDialogTitle() { + return "Rename bound forms"; + } + + public String getDialogDescription() { + return "Rename forms with the following names to:"; + } + + public String entityName() { + return "Form"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/InheritorRenamer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/InheritorRenamer.java new file mode 100644 index 00000000000..3dacfbb17fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/InheritorRenamer.java @@ -0,0 +1,32 @@ +package com.intellij.refactoring.rename.naming; + +import com.intellij.psi.PsiClass; + +/** + * @author dsl + */ +public class InheritorRenamer extends AutomaticRenamer { + public InheritorRenamer(PsiClass aClass, String newClassName) { + final PsiClass[] inheritors = aClass.getManager().getSearchHelper().findInheritors(aClass, aClass.getUseScope(), true); + for (int i = 0; i < inheritors.length; i++) { + final PsiClass inheritor = inheritors[i]; + if (inheritor.getName() != null) { + myElements.add(inheritor); + } + } + + suggestAllNames(aClass.getName(), newClassName); + } + + public String getDialogTitle() { + return "Rename Inheritors"; + } + + public String getDialogDescription() { + return "Rename inheritors with the following names to:"; + } + + public String entityName() { + return "Inheritor"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/NameSuggester.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/NameSuggester.java new file mode 100644 index 00000000000..4b573b2cd34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/rename/naming/NameSuggester.java @@ -0,0 +1,287 @@ +package com.intellij.refactoring.rename.naming; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiNameHelper; +import gnu.trove.TIntIntHashMap; + +import java.util.*; + +/** + * @author dsl + */ +public class NameSuggester { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.naming.NameSuggester"); + private final String[] myOldClassName; + private final String[] myNewClassName; + private final List myChanges; // sorted from right to left + private final String myOldClassNameAsGiven; + private final String myNewClassNameAsGiven; + + + public NameSuggester(String oldClassName, String newClassName) { + myOldClassNameAsGiven = oldClassName; + myNewClassNameAsGiven = newClassName; + myOldClassName = PsiNameHelper.splitNameIntoWords(oldClassName); + myNewClassName = PsiNameHelper.splitNameIntoWords(newClassName); + + myChanges = new ArrayList(); + int oldIndex = myOldClassName.length - 1; + int oldLastMatch = myOldClassName.length; + int newLastMatch = myNewClassName.length; + + while(oldIndex >= 0) { + final String patternWord = myOldClassName[oldIndex]; + final int matchingWordIndex = findInNewBackwardsFromIndex(patternWord, newLastMatch - 1); + if (matchingWordIndex < 0) { // no matching word + oldIndex--; + } + else { // matching word found + if (oldIndex + 1 <= oldLastMatch - 1 || matchingWordIndex + 1 <= newLastMatch - 1) { + final OriginalToNewChange change = new OriginalToNewChange( + oldIndex + 1, oldLastMatch - 1, matchingWordIndex + 1, newLastMatch - 1); + myChanges.add(change); + } + oldLastMatch = oldIndex; + newLastMatch = matchingWordIndex; + oldIndex--; + } + } + if (0 <= oldLastMatch - 1 || 0 <= newLastMatch - 1) { + myChanges.add(new OriginalToNewChange(0, oldLastMatch - 1, 0, newLastMatch - 1)); + } + } + + private int findInNewBackwardsFromIndex(String patternWord, int newIndex) { + for (int i = newIndex; i >= 0; i--) { + final String s = myNewClassName[i]; + if (s.equals(patternWord)) return i; + } + return -1; + } + + List> getChanges() { + final ArrayList> result = new ArrayList>(); + for (int i = myChanges.size() - 1; i >=0; i--) { + final OriginalToNewChange change = myChanges.get(i); + result.add(Pair.create(change.getOldString(), change.getNewString())); + } + return result; + } + + public String suggestName(final String propertyName) { + final String[] propertyWords = PsiNameHelper.splitNameIntoWords(propertyName); + TIntIntHashMap matches = calculateMatches(propertyWords); + if (matches.isEmpty()) return propertyName; + TreeMap, String> replacements = calculateReplacements(propertyWords, matches); + if (replacements.isEmpty()) return propertyName; + final String newName = calculateNewName(replacements, propertyWords, propertyName); + return newName; + } + + + private static Pair calculateWordPositions(String s, String[] words) { + int[] starts = new int[words.length + 1]; + int[] prevEnds = new int[words.length + 1]; + int pos = 0; + prevEnds[0] = -1; + for (int i = 0; i < words.length; i++) { + final String word = words[i]; + final int index = s.indexOf(word, pos); + LOG.assertTrue(index >= 0); + starts[i] = index; + pos = index + word.length(); + prevEnds[i + 1] = pos - 1; + } + starts[words.length] = s.length(); + return Pair.create(starts, prevEnds); + } + + private String calculateNewName(TreeMap, String> replacements, + final String[] propertyWords, + String propertyName) { + StringBuffer resultingWords = new StringBuffer(); + int currentWord = 0; + final Pair wordIndicies = calculateWordPositions(propertyName, propertyWords); + for (Iterator,String>> iterator = replacements.entrySet().iterator(); iterator.hasNext();) { + final Map.Entry,String> entry = iterator.next(); + final int first = entry.getKey().getFirst().intValue(); + final int last = entry.getKey().getSecond().intValue(); + for (int i = currentWord; i < first; i++) { + resultingWords.append(calculateBetween(wordIndicies, i, propertyName)); + final String propertyWord = propertyWords[i]; + appendWord(resultingWords, propertyWord); + } + resultingWords.append(calculateBetween(wordIndicies, first, propertyName)); + appendWord(resultingWords, entry.getValue()); + currentWord = last + 1; + } + for(; currentWord < propertyWords.length; currentWord++) { + resultingWords.append(calculateBetween(wordIndicies, currentWord, propertyName)); + appendWord(resultingWords, propertyWords[currentWord]); + } + resultingWords.append(calculateBetween(wordIndicies, propertyWords.length, propertyName)); + if (resultingWords.length() == 0) return propertyName; + return decapitalizeProbably(resultingWords.toString(), propertyName); + } + + private void appendWord(StringBuffer resultingWords, String propertyWord) { + if (resultingWords.length() > 0) { + final char lastChar = resultingWords.charAt(resultingWords.length() - 1); + if (Character.isLetterOrDigit(lastChar)) { + propertyWord = StringUtil.capitalize(propertyWord); + } + } + resultingWords.append(propertyWord); + } + + private String calculateBetween(final Pair wordIndicies, int i, String propertyName) { + final int thisWordStart = wordIndicies.getFirst()[i]; + final int prevWordEnd = wordIndicies.getSecond()[i]; + final String between = propertyName.substring(prevWordEnd + 1, thisWordStart); + return between; + } + + /** + * Calculates a map of replacements. Result has a form:
    + * {<first,last> -> replacement}
    + * where start and end are indices of property words range (inclusive), and replacement is a + * string that this range must be replaced with.
    + * It is valid situation that last == first - 1: in this case replace means insertion + * before first word. Furthermore, first may be equal to propertyWords.length - in + * that case replacements transormates to appending. + * @param propertyWords + * @param matches + * @return + */ + private TreeMap, String> calculateReplacements(String[] propertyWords, TIntIntHashMap matches) { + TreeMap, String> replacements = new TreeMap, String>(new Comparator>() { + public int compare(Pair pair, Pair pair1) { + return pair.getFirst().compareTo(pair1.getFirst()); + } + }); + for (Iterator iterator = myChanges.iterator(); iterator.hasNext();) { + final OriginalToNewChange change = iterator.next(); + final int first = change.oldFirst; + final int last = change.oldLast; + if (change.getOldLength() > 0) { + if (containsAllBetween(matches, first, last)) { + final String newString = change.getNewString(); + final int propertyWordFirst = matches.get(first); + + if (first >= myOldClassName.length || last >= myOldClassName.length) { + LOG.assertTrue(false, "old class name = " + myOldClassNameAsGiven + + ", new class name = " + myNewClassNameAsGiven + + ", propertyWords = " + Arrays.asList(propertyWords).toString()); + } + + final String replacement = suggestReplacement(myOldClassName[first], propertyWords[propertyWordFirst], newString); + replacements.put(Pair.create(new Integer(propertyWordFirst), + new Integer(matches.get(last))), replacement); + } + } + else { + final String newString = change.getNewString(); + final int propertyWordToInsertBefore; + if (matches.containsKey(first)) { + propertyWordToInsertBefore = matches.get(first); + } + else { + propertyWordToInsertBefore = propertyWords.length; + } + replacements.put(Pair.create(new Integer(propertyWordToInsertBefore), new Integer(propertyWordToInsertBefore - 1)), newString); + } + } + return replacements; + } + + private String suggestReplacement(String classNameWord, String propertyWord, String newClassNameWords) { + return decapitalizeProbably(newClassNameWords, propertyWord); + } + + private static String decapitalizeProbably(String word, String originalWord) { + if (originalWord.length() == 0) return word; + if (Character.isLowerCase(originalWord.charAt(0))) { + return StringUtil.decapitalize(word); + } + return word; + } + + private boolean containsAllBetween(TIntIntHashMap matches, int first, int last) { + for (int i = first; i <= last; i++) { + if (!matches.containsKey(i)) return false; + } + return true; + } + + private TIntIntHashMap calculateMatches(final String[] propertyWords) { + int classNameIndex = myOldClassName.length - 1; + TIntIntHashMap matches = new TIntIntHashMap(); + for (int i = propertyWords.length - 1; i >= 0; i--) { + final String propertyWord = propertyWords[i]; + Match match = null; + for (int j = classNameIndex; j >= 0 && match == null; j--) { + match = checkMatch(j, i, propertyWord); + } + if (match != null) { + matches.put(match.oldClassNameIndex, i); + classNameIndex = match.oldClassNameIndex - 1; + } + } + return matches; + } + + private class OriginalToNewChange { + final int oldFirst; + final int oldLast; + final int newFirst; + final int newLast; + + public OriginalToNewChange(int firstInOld, int lastInOld, int firstInNew, int lastInNew) { + this.oldFirst = firstInOld; + this.oldLast = lastInOld; + this.newFirst = firstInNew; + this.newLast = lastInNew; + } + + int getOldLength() { + return oldLast - oldFirst + 1; + } + + String getOldString() { + final StringBuffer buffer = new StringBuffer(); + for (int i = oldFirst; i <= oldLast; i++) { + buffer.append(myOldClassName[i]); + } + return buffer.toString(); + } + + String getNewString() { + final StringBuffer buffer = new StringBuffer(); + for (int i = newFirst; i <= newLast; i++) { + buffer.append(myNewClassName[i]); + } + return buffer.toString(); + } + } + + private class Match { + final int oldClassNameIndex; + final int propertyNameIndex; + final String propertyWord; + + public Match(int oldClassNameIndex, int propertyNameIndex, String propertyWord) { + this.oldClassNameIndex = oldClassNameIndex; + this.propertyNameIndex = propertyNameIndex; + this.propertyWord = propertyWord; + } + } + + private Match checkMatch(final int oldClassNameIndex, final int propertyNameIndex, final String propertyWord) { + if (propertyWord.equalsIgnoreCase(myOldClassName[oldClassNameIndex])) { + return new Match(oldClassNameIndex, propertyNameIndex, propertyWord); + } + else return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java new file mode 100644 index 00000000000..150705a61a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java @@ -0,0 +1,171 @@ +package com.intellij.refactoring.replaceConstructorWithFactory; + +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiNameHelper; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.ui.NameSuggestionsField; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +/** + * @author dsl + */ +public class ReplaceConstructorWithFactoryDialog extends RefactoringDialog { + private final Callback myCallback; + + private NameSuggestionsField myNameField; + private final TextFieldWithBrowseButton myTfTargetClassName; + private JComboBox myTargetClassNameCombo; + private Project myProject; + private PsiClass myContainingClass; + private final boolean myIsInner; + + public interface Callback { + void run(ReplaceConstructorWithFactoryDialog dialog); + } + + ReplaceConstructorWithFactoryDialog(Project project, PsiClass containingClass, Callback callback) { + super(project, true); + myProject = project; + + myCallback = callback; + myContainingClass = containingClass; + myIsInner = myContainingClass.getContainingClass() != null + && !myContainingClass.hasModifierProperty(PsiModifier.STATIC); + + setTitle(ReplaceConstructorWithFactoryHandler.REFACTORING_NAME); + + myTfTargetClassName = new TextFieldWithBrowseButton(new ChooseClassAction()); + + init(); + } + + public String getName() { + return myNameField.getName(); + } + + protected boolean hasHelpAction () { return false; } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField.getComponent(); + } + + public String getTargetClassName() { + if (!myIsInner) { + return myTfTargetClassName.getText(); + } else { + return (String) myTargetClassNameCombo.getSelectedItem(); + } + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.BOTH; + + gbc.insets = new Insets(4, 0, 4, 8); + gbc.gridwidth = 1; + gbc.gridx = 0; + gbc.gridy = 0; + panel.add(new JLabel("Factory method name:"), gbc); + + gbc.gridx++; + gbc.weightx = 1.0; + final String[] nameSuggestions = new String[]{ + "create" + myContainingClass.getName(), + "new" + myContainingClass.getName(), + "getInstance" + }; + myNameField = new NameSuggestionsField(nameSuggestions, myProject); + myNameField.addDataChangedListener(new NameSuggestionsField.DataChanged() { + public void dataChanged() { + validateButtons(); + } + }); + panel.add(myNameField.getComponent(), gbc); + + JPanel targetClassPanel = createTargetPanel(); + + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 2; + panel.add(targetClassPanel, gbc); + + + return panel; + + } + + private JPanel createTargetPanel() { + JPanel targetClassPanel = new JPanel(new BorderLayout()); + if (!myIsInner) { + JLabel label = new JLabel("In (fully qualified name):"); + label.setLabelFor(myTfTargetClassName); + targetClassPanel.add(label, BorderLayout.NORTH); + targetClassPanel.add(myTfTargetClassName, BorderLayout.CENTER); + myTfTargetClassName.setText(myContainingClass.getQualifiedName()); + } else { + ArrayList list = new ArrayList(); + PsiElement parent = myContainingClass; + while (parent instanceof PsiClass) { + list.add(((PsiClass) parent).getQualifiedName()); + parent = parent.getParent(); + } + + myTargetClassNameCombo = new JComboBox(list.toArray(new String[list.size()])); + JLabel label = new JLabel("In (fully qualified name):"); + label.setLabelFor(myTargetClassNameCombo.getEditor().getEditorComponent()); + targetClassPanel.add(label, BorderLayout.NORTH); + targetClassPanel.add(myTargetClassNameCombo, BorderLayout.CENTER); + } + return targetClassPanel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryDialog"; + } + + private class ChooseClassAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Destination Class", myProject); + chooser.selectDirectory(myContainingClass.getContainingFile().getContainingDirectory()); + chooser.show(); + PsiClass aClass = chooser.getSelectedClass(); + if (aClass != null) { + myTfTargetClassName.setText(aClass.getQualifiedName()); + } + } + } + + + protected JComponent createCenterPanel() { + return null; + } + + protected void doAction() { + myCallback.run(this); + } + + protected boolean areButtonsValid() { + final String name = myNameField.getName(); + final PsiNameHelper nameHelper = myContainingClass.getManager().getNameHelper(); + return nameHelper.isIdentifier(name); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryHandler.java new file mode 100644 index 00000000000..e376c90842f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryHandler.java @@ -0,0 +1,194 @@ +package com.intellij.refactoring.replaceConstructorWithFactory; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +/** + * @author dsl + */ +public class ReplaceConstructorWithFactoryHandler + implements RefactoringActionHandler { + public static final String REFACTORING_NAME = "Replace Constructor With Factory Method"; + private Project myProject; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the constructor to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY*/, project); + return; + } + + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass) + && ((PsiClass) element).getConstructors().length == 0) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + if (element instanceof PsiMethod && ((PsiMethod) element).isConstructor()) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + + myProject = project; + if (elements[0] instanceof PsiMethod) { + final PsiMethod method = (PsiMethod) elements[0]; + invoke(method); + } else if (elements[0] instanceof PsiClass) { + invoke((PsiClass) elements[0]); + } + + } + + private void invoke(PsiClass aClass) { + String qualifiedName = aClass.getQualifiedName(); + if(qualifiedName == null) { + showJspOrLocalClassMessage(); + return; + } + if (!checkAbstractClassOrInterfaceMessage(aClass)) return; + final PsiMethod[] constructors = aClass.getConstructors(); + if (constructors.length > 0) { + String message = + "Class " + aClass.getQualifiedName() + " does not have implicit default consructor." ; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY*/, myProject); + return; + } + final int answer = Messages.showYesNoCancelDialog(myProject, + "Would you like to replace default constructor of " + aClass.getQualifiedName() + " with factory method?", + REFACTORING_NAME, Messages.getQuestionIcon() + ); + if (answer != 0) return; + if (!aClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, aClass); + return; + } + final ReplaceConstructorWithFactoryDialog dialog = + new ReplaceConstructorWithFactoryDialog(myProject, aClass, new MyCallbackForClass(aClass)); + dialog.show(); + } + + private void showJspOrLocalClassMessage() { + String message = + "Cannot perform the refactoring.\n" + + "Refactoring is not supported for local and JSP classes."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY*/, myProject); + } + private boolean checkAbstractClassOrInterfaceMessage(PsiClass aClass) { + if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) return true; + final String reason = aClass.isInterface() ? "an interface" : "abstract"; + String message = + "Cannot perform the refactoring.\n" + + aClass.getQualifiedName() + " is " + reason + "."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY, myProject); + return false; + } + + private void invoke(final PsiMethod method) { + if (!method.isConstructor()) { + String message = + "Cannot perform the refactoring.\n" + + "Method is not a constructor."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY, myProject); + return; + } + + PsiClass aClass = method.getContainingClass(); + if(aClass == null || aClass.getQualifiedName() == null) { + showJspOrLocalClassMessage(); + return; + } + + if (!checkAbstractClassOrInterfaceMessage(aClass)) return; + + if (!method.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, method); + return; + } + final ReplaceConstructorWithFactoryDialog dialog = + new ReplaceConstructorWithFactoryDialog(myProject, + method.getContainingClass(), new MyCallbackForMethod(method)); + dialog.show(); + } + + + private class MyCallbackForMethod implements ReplaceConstructorWithFactoryDialog.Callback { + private PsiMethod myMethod; + + public MyCallbackForMethod(PsiMethod method) { + myMethod = method; + } + + public void run(final ReplaceConstructorWithFactoryDialog dialog) { + final PsiManager manager = myMethod.getManager(); + final String targetClassName = dialog.getTargetClassName(); + final PsiClass targetClass = manager.findClass(targetClassName, GlobalSearchScope.allScope(myProject)); + if (targetClass == null) { + String message = + "Cannot perform the refactoring.\n" + + "Class " + targetClassName + " not found."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY*/, myProject); + return; + } + if (!targetClass.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(myProject, targetClass); + return; + } + + new ReplaceConstructorWithFactoryProcessor(myProject, myMethod, + targetClass, dialog.getName(), dialog.isPreviewUsages(), new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + ).run(null); + } + } + + private class MyCallbackForClass implements ReplaceConstructorWithFactoryDialog.Callback { + private PsiClass myClass; + + public MyCallbackForClass(PsiClass aClass) { + myClass = aClass; + } + + public void run(final ReplaceConstructorWithFactoryDialog dialog) { + final PsiManager manager = myClass.getManager(); + final String targetClassName = dialog.getTargetClassName(); + final PsiClass targetClass = manager.findClass(targetClassName, GlobalSearchScope.allScope(myProject)); + if (targetClass == null) { + String message = + "Cannot perform the refactoring.\n" + + "Class " + targetClassName + " not found."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.REPLACE_CONSTRUCTOR_WITH_FACTORY*/, myProject); + return; + } + new ReplaceConstructorWithFactoryProcessor(myProject, myClass, + targetClass, dialog.getName(), dialog.isPreviewUsages(), new Runnable() { + public void run() { + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + } + ).run(null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java new file mode 100644 index 00000000000..37ea4fc861f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java @@ -0,0 +1,348 @@ +package com.intellij.refactoring.replaceConstructorWithFactory; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.VisibilityUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class ReplaceConstructorWithFactoryProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryProcessor"); + private final PsiMethod myConstructor; + private final String myFactoryName; + private final boolean myPreviewUsages; + private final PsiElementFactory myFactory; + private final PsiClass myOriginalClass; + private final PsiClass myTargetClass; + private PsiManager myManager; + private boolean myIsInner; + + public ReplaceConstructorWithFactoryProcessor(Project project, PsiMethod constructor, + PsiClass targetClass, String factoryName, boolean previewUsages, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myOriginalClass = null; + myConstructor = constructor; + myFactoryName = factoryName; + myPreviewUsages = previewUsages; + myTargetClass = targetClass; + LOG.assertTrue(myConstructor.isConstructor()); + myManager = PsiManager.getInstance(project); + myFactory = PsiManager.getInstance(project).getElementFactory(); + + myIsInner = isInner(myConstructor.getContainingClass()); + } + + public ReplaceConstructorWithFactoryProcessor(Project project, PsiClass aClass, PsiClass targetClass, + String factoryName, boolean previewUsages, + Runnable prepareSuccessfulCallback) { + super(project, prepareSuccessfulCallback); + myOriginalClass = aClass; + myConstructor = null; + myTargetClass = targetClass; + myFactoryName = factoryName; + myPreviewUsages = previewUsages; + myManager = PsiManager.getInstance(project); + myFactory = myManager.getElementFactory(); + + myIsInner = isInner(myOriginalClass); + } + + private boolean isInner(PsiClass originalClass) { + final boolean result = PsiUtil.isInnerClass(originalClass); + if (result) { + LOG.assertTrue(PsiTreeUtil.isAncestor(myTargetClass, originalClass, false)); + } + return result; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + if (myConstructor != null) { + return new ReplaceConstructorWithFactoryViewDescriptor(usages, refreshCommand, myConstructor); + } + else { + return new ReplaceConstructorWithFactoryViewDescriptor(usages, refreshCommand, myOriginalClass); + } + } + + private List myNonNewConstructorUsages; + + protected UsageInfo[] findUsages() { + final PsiSearchHelper searchHelper = myManager.getSearchHelper(); + final PsiReference[] references; + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + if (myConstructor != null) { + references = searchHelper.findReferences(myConstructor, projectScope, false); + } + else { + references = searchHelper.findReferences(myOriginalClass, projectScope, false); + } + + ArrayList usages = new ArrayList(); + myNonNewConstructorUsages = new ArrayList(); + + for (int i = 0; i < references.length; i++) { + PsiElement element = references[i].getElement(); + + if (element.getParent() instanceof PsiNewExpression) { + usages.add(new UsageInfo(element.getParent())); + } + else { + if ("super".equals(element.getText()) || "this".equals(element.getText())) { + myNonNewConstructorUsages.add(element); + } + } + } + + if (myConstructor != null && myConstructor.getParameterList().getParameters().length == 0) { + RefactoringUtil.visitImplicitConstructorUsages(getConstructorContainingClass(), new RefactoringUtil.ImplicitConstructorUsageVisitor() { + public void visitConstructor(PsiMethod constructor) { + myNonNewConstructorUsages.add(constructor); + } + + public void visitClassWithoutConstructors(PsiClass aClass) { + myNonNewConstructorUsages.add(aClass); + } + }); + } + + return usages.toArray(new UsageInfo[usages.size()]); + } + + protected boolean preprocessUsages(UsageInfo[][] u) { + UsageInfo[] usages = u[0]; + + ArrayList conflicts = new ArrayList(); + if (!myManager.getResolveHelper().isAccessible(getConstructorContainingClass(), myTargetClass, null)) { + String message = "Class " + ConflictsUtil.getDescription(getConstructorContainingClass(), true) + + " is not accessible from target " + ConflictsUtil.getDescription(myTargetClass, true) + "."; + conflicts.add(message); + } + + HashSet reportedContainers = new HashSet(); + final String targetClassDescription = ConflictsUtil.getDescription(myTargetClass, true); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + final PsiElement container = ConflictsUtil.getContainer(usage.getElement()); + if (!reportedContainers.contains(container)) { + reportedContainers.add(container); + if (!myManager.getResolveHelper().isAccessible(myTargetClass, usage.getElement(), null)) { + String message = "Target " + targetClassDescription + " is not accessible from " + + ConflictsUtil.getDescription(container, true) + "."; + conflicts.add(message); + } + } + } + + if (myIsInner) { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + final PsiField field = PsiTreeUtil.getParentOfType(usage.getElement(), PsiField.class); + if (field != null) { + final PsiClass containingClass = field.getContainingClass(); + + if (PsiTreeUtil.isAncestor(containingClass, myTargetClass, true)) { + String message = "Constructor being refactored is used in initializer of " + + ConflictsUtil.getDescription(field, true) + + ". Non-static factory of inner class" + + ConflictsUtil.getDescription(getConstructorContainingClass(), false) + + " cannot be used in this context. Resulting code will not compile."; + conflicts.add(message); + } + } + } + } + + + if (myPrepareSuccessfulSwingThreadCallback != null && conflicts.size() > 0) { + ConflictsDialog dialog = new ConflictsDialog(conflicts.toArray(new String[conflicts.size()]), + myProject); + dialog.show(); + if (!dialog.isOK()) return false; + } + + prepareSuccessful(); + return true; + } + + private PsiClass getConstructorContainingClass() { + if (myConstructor != null) { + return myConstructor.getContainingClass(); + } + else { + return myOriginalClass; + } + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + return super.isPreviewUsages(usages) || myPreviewUsages; + } + + protected void performRefactoring(UsageInfo[] usages) { + + try { + PsiReferenceExpression classReferenceExpression = + myFactory.createReferenceExpression(myTargetClass); + PsiReferenceExpression qualifiedMethodReference = + (PsiReferenceExpression)myFactory.createExpressionFromText("A." + myFactoryName, null); + PsiMethod factoryMethod = (PsiMethod)myTargetClass.add(createFactoryMethod()); + if (myConstructor != null) { + myConstructor.getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + VisibilityUtil.escalateVisibility(myConstructor, factoryMethod); + for (Iterator iterator = myNonNewConstructorUsages.iterator(); iterator.hasNext();) { + PsiElement place = iterator.next(); + VisibilityUtil.escalateVisibility(myConstructor, place); + } + } + + if (myConstructor == null) { + PsiMethod constructor = myFactory.createConstructor(); + constructor.getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + constructor = (PsiMethod)getConstructorContainingClass().add(constructor); + VisibilityUtil.escalateVisibility(constructor, myTargetClass); + } + + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + PsiNewExpression newExpression = (PsiNewExpression)usage.getElement(); + + VisibilityUtil.escalateVisibility(factoryMethod, newExpression); + PsiMethodCallExpression factoryCall = + (PsiMethodCallExpression)myFactory.createExpressionFromText(myFactoryName + "()", newExpression); + factoryCall.getArgumentList().replace(newExpression.getArgumentList()); + + boolean replaceMethodQualifier = false; + PsiExpression newQualifier = newExpression.getQualifier(); + + if (newQualifier != null) { + newQualifier = (PsiExpression)newQualifier.copy(); + } + + PsiElement resolvedFactoryMethod = factoryCall.getMethodExpression().resolve(); + if (resolvedFactoryMethod != factoryMethod || newQualifier != null) { + factoryCall.getMethodExpression().replace(qualifiedMethodReference); + replaceMethodQualifier = true; + } + factoryCall = (PsiMethodCallExpression)newExpression.replace(factoryCall); + + if (replaceMethodQualifier) { + if (newQualifier == null) { + factoryCall.getMethodExpression().getQualifierExpression().replace(classReferenceExpression); + } + else { + factoryCall.getMethodExpression().getQualifierExpression().replace(newQualifier); + } + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + private PsiMethod createFactoryMethod() throws IncorrectOperationException { + final PsiClass containingClass = getConstructorContainingClass(); + PsiClassType type = myFactory.createType(containingClass, PsiSubstitutor.EMPTY); + final PsiMethod factoryMethod = myFactory.createMethod(myFactoryName, type); + if (myConstructor != null) { + factoryMethod.getParameterList().replace(myConstructor.getParameterList()); + factoryMethod.getThrowsList().replace(myConstructor.getThrowsList()); + + Iterator iterator = PsiUtil.typeParametersIterator(myConstructor); + List names = new ArrayList(); + while(iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + if (!names.contains(typeParameter.getName())) { //Otherwise type parameter is hidden in the constructor + names.add(typeParameter.getName()); + factoryMethod.getTypeParameterList().add(typeParameter); + } + } + } + PsiReturnStatement returnStatement = + (PsiReturnStatement)myFactory.createStatementFromText("return new A();", null); + PsiNewExpression newExpression = (PsiNewExpression)returnStatement.getReturnValue(); + PsiJavaCodeReferenceElement classRef = myFactory.createReferenceElementByType(type); + newExpression.getClassReference().replace(classRef); + final PsiExpressionList argumentList = newExpression.getArgumentList(); + + PsiParameter[] params = factoryMethod.getParameterList().getParameters(); + + for (int i = 0; i < params.length; i++) { + PsiExpression paramRef = myFactory.createExpressionFromText(params[i].getName(), null); + argumentList.add(paramRef); + } + factoryMethod.getBody().add(returnStatement); + + factoryMethod.getModifierList().setModifierProperty( + getDefaultFactoryVisibility(), true); + + if (!myIsInner) { + factoryMethod.getModifierList().setModifierProperty(PsiModifier.STATIC, true); + } + + return (PsiMethod)CodeStyleManager.getInstance(myProject).reformat(factoryMethod); + } + + private String getDefaultFactoryVisibility() { + final PsiModifierList modifierList; + if (myConstructor != null) { + modifierList = myConstructor.getModifierList(); + } + else { + modifierList = myOriginalClass.getModifierList(); + } + return VisibilityUtil.getVisibilityModifier(modifierList); + } + + + protected String getCommandName() { + if (myConstructor != null) { + return "Replace constructor " + UsageViewUtil.getDescriptiveName(myConstructor) + " with a factory method"; + } + else { + return "Replace default constructor of " + UsageViewUtil.getDescriptiveName(myOriginalClass) + + " with a factory method"; + } + } + + public PsiClass getOriginalClass() { + return getConstructorContainingClass(); + } + + public PsiClass getTargetClass() { + return myTargetClass; + } + + public PsiMethod getConstructor() { + return myConstructor; + } + + public String getFactoryName() { + return myFactoryName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryViewDescriptor.java new file mode 100644 index 00000000000..e6e451004be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryViewDescriptor.java @@ -0,0 +1,54 @@ +package com.intellij.refactoring.replaceConstructorWithFactory; + +import com.intellij.psi.*; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +class ReplaceConstructorWithFactoryViewDescriptor extends UsageViewDescriptorAdapter { + private PsiMethod myConstructor; + private PsiClass myClass; + + public ReplaceConstructorWithFactoryViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand, + PsiMethod constructor) { + super(usages, refreshCommand); + myConstructor = constructor; + myClass = null; + } + + public ReplaceConstructorWithFactoryViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand, PsiClass aClass) { + super(usages, refreshCommand); + myClass = aClass; + myConstructor = null; + } + + public PsiElement[] getElements() { + if (myConstructor != null) { + return new PsiElement[] {myConstructor}; + } else { + return new PsiElement[] {myClass}; + } + } + + public void refresh(PsiElement[] elements) { + if(elements[0] instanceof PsiMethod && ((PsiMethod) elements[0]).isConstructor()) { + myConstructor = (PsiMethod) elements[0]; + myClass = null; + } else if(elements[0] instanceof PsiClass) { + myClass = (PsiClass) elements[0]; + myConstructor = null; + } + refreshUsages(elements); + } + + public String getProcessedElementsHeader() { + if (myConstructor != null) { + return "Replace constructor with factory method"; + } else { + return "Replace default constructor with factory method"; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/OverridingMethodsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/OverridingMethodsDialog.java new file mode 100644 index 00000000000..a1deaadc46f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/OverridingMethodsDialog.java @@ -0,0 +1,195 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo; +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.util.ui.Table; +import com.intellij.usageView.UsageInfo; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsl + */ +class OverridingMethodsDialog extends DialogWrapper { + private final List myOverridingMethods; + private final String[] myMethodText; + private final boolean[] myChecked; + + private static final int CHECK_COLUMN = 0; + private Table myTable; + + public OverridingMethodsDialog(Project project, List overridingMethods) { + super(project, true); + myOverridingMethods = overridingMethods; + myChecked = new boolean[myOverridingMethods.size()]; + for (int i = 0; i < myChecked.length; i++) { + myChecked[i] = true; + } + + myMethodText = new String[myOverridingMethods.size()]; + for (int i = 0; i < myMethodText.length; i++) { + myMethodText[i] = PsiFormatUtil.formatMethod( + ((SafeDeleteOverridingMethodUsageInfo) myOverridingMethods.get(i)).getOverridingMethod(), + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_CONTAINING_CLASS + | PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_TYPE, + PsiFormatUtil.SHOW_TYPE + ); + } + + setTitle("Unused Overriding Methods"); + init(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.safeDelete.OverridingMethodsDialog"; + } + + public ArrayList getSelected() { + ArrayList result = new ArrayList(); + for (int i = 0; i < myChecked.length; i++) { + if(myChecked[i]) { + result.add(myOverridingMethods.get(i)); + } + } + return result; + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction()/*, getHelpAction()*/}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.SAFE_DELETE_OVERRIDING); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(new JLabel("There are unused methods that override methods you delete.")); + panel.add(new JLabel("Choose the ones you want to be deleted.")); + return panel; + } + + public JComponent getPreferredFocusedComponent() { + return myTable; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 4, 0)); + final MyTableModel tableModel = new MyTableModel(); + myTable = new Table(tableModel); + myTable.setShowGrid(false); + + TableColumnModel columnModel = myTable.getColumnModel(); +// columnModel.getColumn(DISPLAY_NAME_COLUMN).setCellRenderer(new MemberSelectionTable.MyTableRenderer()); + final int checkBoxWidth = new JCheckBox().getPreferredSize().width; + columnModel.getColumn(CHECK_COLUMN).setCellRenderer(new BooleanTableCellRenderer()); + columnModel.getColumn(CHECK_COLUMN).setMaxWidth(checkBoxWidth); + columnModel.getColumn(CHECK_COLUMN).setMinWidth(checkBoxWidth); + + + // make SPACE check/uncheck selected rows + InputMap inputMap = myTable.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + myTable.getActionMap().put("enable_disable", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] rows = myTable.getSelectedRows(); + if (rows.length > 0) { + boolean valueToBeSet = false; + for (int idx = 0; idx < rows.length; idx++) { + if (!myChecked[rows[idx]]) { + valueToBeSet = true; + break; + } + } + for (int idx = 0; idx < rows.length; idx++) { + myChecked[rows[idx]] = valueToBeSet; + } + + tableModel.updateData(); + } + } + }); + + + + /*Border titledBorder = BorderFactory.createTitledBorder("Select methods"); + Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5); + Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder); + panel.setBorder(border);*/ + panel.setLayout(new BorderLayout()); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + + panel.add(scrollPane, BorderLayout.CENTER); + return panel; + } + + class MyTableModel extends AbstractTableModel { + public int getRowCount() { + return myChecked.length; + } + + public String getColumnName(int column) { + switch(column) { + case CHECK_COLUMN: + return " "; + default: + return "Method"; + } + } + + public Class getColumnClass(int columnIndex) { + switch(columnIndex) { + case CHECK_COLUMN: + return Boolean.class; + default: + return String.class; + } + } + + + public int getColumnCount() { + return 2; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + if(columnIndex == CHECK_COLUMN) { + return Boolean.valueOf(myChecked[rowIndex]); + } + else { + return myMethodText[rowIndex]; + } + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if(columnIndex == CHECK_COLUMN) { + myChecked[rowIndex] = ((Boolean) aValue).booleanValue(); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == CHECK_COLUMN; + } + + void updateData() { + fireTableDataChanged(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java new file mode 100644 index 00000000000..88a8fd96cec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java @@ -0,0 +1,124 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.ide.util.DeleteUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.util.RefactoringUtil; + +import javax.swing.*; +import java.awt.*; + +/** + * @author dsl + */ +public class SafeDeleteDialog extends DialogWrapper { + private final PsiElement[] myElements; + private final Callback myCallback; + + private JCheckBox myCbSearchInComments; + private JCheckBox myCbSearchInNonJava; + + public interface Callback { + void run(SafeDeleteDialog dialog); + } + + public SafeDeleteDialog(Project project, PsiElement[] elements, Callback callback) { + super(project, true); + myElements = elements; + myCallback = callback; + + setTitle(SafeDeleteHandler.REFACTORING_NAME); + init(); + } + + public boolean isSearchInComments() { + return myCbSearchInComments.isSelected(); + } + + public boolean isSearchInNonJava() { + if (myCbSearchInNonJava != null) { + return myCbSearchInNonJava.isSelected(); + } else { + return false; + } + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.SAFE_DELETE); + } + + protected JComponent createNorthPanel() { + final JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints gbc = new GridBagConstraints(); + + final String warningMessage = DeleteUtil.generateWarningMessage("Search for usages of and delete", myElements); + + gbc.insets = new Insets(4, 8, 4, 8); + gbc.weighty = 1; + gbc.weightx = 1; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.WEST; + panel.add(new JLabel(warningMessage), gbc); + + gbc.gridy++; + gbc.gridx = 0; + gbc.weightx = 0.0; + gbc.gridwidth = 1; + myCbSearchInComments = new JCheckBox("Search in comments and strings"); + myCbSearchInComments.setMnemonic('S'); + panel.add(myCbSearchInComments, gbc); + + if (needSearchInNonJava()) { + gbc.gridx++; + myCbSearchInNonJava = new JCheckBox("Search in non-java files"); + myCbSearchInNonJava.setMnemonic('e'); + panel.add(myCbSearchInNonJava, gbc); + } + + final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance(); + myCbSearchInComments.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS); + if (myCbSearchInNonJava != null) { + myCbSearchInNonJava.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA); + } + return panel; + } + + protected JComponent createCenterPanel() { + return null; + } + + private boolean needSearchInNonJava() { + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + if(RefactoringUtil.isSearchInNonJavaEnabled(element)) { + return true; + } + } + return false; + } + + + protected void doOKAction() { + if (myCallback != null) { + myCallback.run(this); + } else { + super.doOKAction(); + } + final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance(); + refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS = isSearchInComments(); + if (myCbSearchInNonJava != null) { + refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA = isSearchInNonJava(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java new file mode 100644 index 00000000000..24d8e3841c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java @@ -0,0 +1,90 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.ide.util.DeleteUtil; +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.util.containers.HashSet; + +import java.util.Arrays; +import java.util.Set; + +/** + * @author dsl + */ +public class SafeDeleteHandler implements RefactoringActionHandler { + public static final String REFACTORING_NAME = "Safe Delete"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + PsiElement element = (PsiElement) dataContext.getData(DataConstants.PSI_ELEMENT); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + if (!SafeDeleteProcessor.validElement(element)) { + String message = + "Cannot perform the refactoring.\n" + + "Caret should be positioned on the name of a class, a field, or a method to be deleted"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, /*HelpID.SAFE_DELETE*/null, project); + return; + } + invoke(project, new PsiElement[]{element}, dataContext); + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + invoke(project, elements, true); + } + + public void invoke(final Project project, PsiElement[] elements, boolean checkSuperMethods) { + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + if (!SafeDeleteProcessor.validElement(element)) { + return; + } + } + final PsiElement[] elementsToDelete = DeleteUtil.filterElements(elements); + Set elementsSet = new HashSet(Arrays.asList(elementsToDelete)); + + if (checkSuperMethods) { + for (int i = 0; i < elementsToDelete.length; i++) { + PsiElement element = elementsToDelete[i]; + if (element instanceof PsiMethod) { + final PsiMethod deepestSuperMethod = PsiSuperMethodUtil.findDeepestSuperMethod((PsiMethod) element); + if (!elementsSet.contains(deepestSuperMethod)) { + final PsiMethod method = SuperMethodWarningUtil.checkSuperMethod((PsiMethod)element, + "delete (with usage search)"); + if (method == null) return; + elementsToDelete[i] = method; + } + } + } + } + + for (int i = 0; i < elementsToDelete.length; i++) { + PsiElement psiElement = elementsToDelete[i]; + if (!psiElement.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, psiElement); + return; + } + } + + SafeDeleteDialog dialog = new SafeDeleteDialog(project, elementsToDelete, new SafeDeleteDialog.Callback() { + public void run(final SafeDeleteDialog dialog) { + SafeDeleteProcessor.createInstance(project, new Runnable() { + public void run() { + dialog.close(SafeDeleteDialog.CANCEL_EXIT_CODE); + } + }, elementsToDelete, dialog.isSearchInComments(), dialog.isSearchInNonJava(), true).run(null); + } + + }); + + dialog.show(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java new file mode 100644 index 00000000000..d0e41b791d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java @@ -0,0 +1,728 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.safeDelete.usageInfo.*; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author dsl + */ +public class SafeDeleteProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.safeDelete.SafeDeleteProcessor"); + private PsiElement[] myElements; + private boolean mySearchInCommentsAndStrings; + private boolean mySearchNonJava; + private boolean myPreviewNonCodeUsages = true; + + private SafeDeleteProcessor(Project project, Runnable prepareSuccessfulCallback, + PsiElement[] elementsToDelete, boolean isSearchInComments, boolean isSearchNonJava) { + super(project, prepareSuccessfulCallback); + myElements = elementsToDelete; + mySearchInCommentsAndStrings = isSearchInComments; + mySearchNonJava = isSearchNonJava; + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new SafeDeleteUsageViewDescriptor(usages, refreshCommand, myElements, this); + } + + void setElements(PsiElement[] elements) { + myElements = elements; + } + + private boolean isInside(PsiElement place, PsiElement[] ancestors) { + return isInside(place, Arrays.asList(ancestors)); + } + private boolean isInside(PsiElement place, Collection ancestors) { + for (Iterator iterator = ancestors.iterator(); iterator.hasNext();) { + PsiElement element = iterator.next(); + if (PsiTreeUtil.isAncestor(element, place, false)) return true; + if (place instanceof PsiComment && element instanceof PsiClass) { + final PsiClass aClass = ((PsiClass)element); + if (aClass.getParent() instanceof PsiJavaFile) { + final PsiJavaFile file = ((PsiJavaFile)aClass.getParent()); + if (PsiTreeUtil.isAncestor(file, place, false)) { + if (file.getClasses().length == 1) { // file will be deleted on class deletion + return true; + } + } + } + } + } + return false; + } + + protected UsageInfo[] findUsages() { + ArrayList usages = new ArrayList(); + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + if (element instanceof PsiClass) { + findClassUsages(((PsiClass) element), usages); + } else if (element instanceof PsiMethod) { + findMethodUsages(((PsiMethod) element), usages); + } else if (element instanceof PsiField) { + findFieldUsages((PsiField) element, usages); + } + } + final UsageInfo[] result = usages.toArray(new UsageInfo[usages.size()]); + return UsageViewUtil.removeDuplicatedUsages(result); + } + + protected boolean preprocessUsages(UsageInfo[][] u) { + UsageInfo[] usages = u[0]; + final HashMap elementsToUsageHolders = sortUsages(usages); + ArrayList conflicts = new ArrayList(); + + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + + if(element instanceof PsiMethod) { + final PsiClass containingClass = ((PsiMethod) element).getContainingClass(); + + if (!containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods((PsiMethod) element); + for (int j = 0; j < superMethods.length; j++) { + PsiMethod superMethod = superMethods[j]; + if (isInside(superMethod, myElements)) continue; + if(superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + String message = ConflictsUtil.getDescription(element, true) + " implements " + + ConflictsUtil.getDescription(superMethod, true) + "."; + conflicts.add(message); + break; + } + } + } + } + + UsageHolder usageHolder = elementsToUsageHolders.get(element); + if (usageHolder != null) { + + if (usageHolder.getNonCodeUsagesNumber() != usageHolder.getNonSafeUsagesNumber()) { + final String description = usageHolder.getDescription(); + if (description != null) { + conflicts.add(description); + } + } + } + } + if (conflicts.size() > 0) { + UnsafeUsagesDialog dialog = new UnsafeUsagesDialog(conflicts.toArray(new String[conflicts.size()]), myProject); + dialog.show(); + if (!dialog.isOK()) { + final int exitCode = dialog.getExitCode(); + prepareSuccessful(); // dialog is always dismissed + if (exitCode == UnsafeUsagesDialog.VIEW_USAGES_EXIT_CODE) { + showUsages(usages); + } + return false; + } + else { + myPreviewNonCodeUsages = false; + } + } + + final UsageInfo[] filteredUsages = filterAndQueryOverriding(usages); + prepareSuccessful(); // dialog is always dismissed + if(filteredUsages == null) { + return false; + } + u[0] = filteredUsages; + return true; + } + + private void showUsages(final UsageInfo[] usages) { + class Descriptor extends UsageViewDescriptorAdapter { + Descriptor() { + super(usages, null); + } + + public PsiElement[] getElements() { + return myElements; + } + + public void refresh(PsiElement[] elements) { + refreshUsages(elements); + } + + public String getProcessedElementsHeader() { + return "Attempting to delete"; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References in code " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return "Occurrences found in comments, strings and non-java files " + + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "occurrence"); + } + + public boolean isSearchInText() { + return mySearchInCommentsAndStrings || mySearchNonJava; + } + + public boolean canRefresh() { + return false; + } + + public boolean isCancelInCommonGroup() { + return true; + } + } + final UsageView usageView = UsageViewManager.getInstance(myProject).addContent("Unsuccessful safe delete", new Descriptor(), false, + true, true, true, true); + usageView.addDoProcessAction(new RerunSafeDelete(myProject, myElements, usageView), "Retry", null, "&Rerun Safe Delete"); + } + + public PsiElement[] getElements() { + return myElements; + } + + private static class RerunSafeDelete implements Runnable { + final SmartPsiElementPointer[] myPointers; + private final Project myProject; + private final UsageView myUsageView; + + RerunSafeDelete(Project project, PsiElement[] elements, UsageView usageView) { + myProject = project; + myUsageView = usageView; + myPointers = new SmartPsiElementPointer[elements.length]; + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + myPointers[i] = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(element); + } + } + + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + UsageViewManager.getInstance(myProject).closeContent(myUsageView); + ArrayList elements = new ArrayList(); + for (int i = 0; i < myPointers.length; i++) { + SmartPsiElementPointer pointer = myPointers[i]; + final PsiElement element = pointer.getElement(); + if(element != null) { + elements.add(element); + } + } + if(elements.size() > 0) { + new SafeDeleteHandler().invoke(myProject, elements.toArray(new PsiElement[elements.size()]), true); + } + } + }); + } + } + + private UsageInfo[] filterAndQueryOverriding(UsageInfo[] usages) { + ArrayList result = new ArrayList(); + ArrayList overridingMethods = new ArrayList(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if(usage.isNonCodeUsage) { + result.add(usage); + } else if (usage instanceof SafeDeleteOverridingMethodUsageInfo) { + overridingMethods.add(usage); + } else { + result.add(usage); + } + } + + if(overridingMethods.size() > 0) { + OverridingMethodsDialog dialog = new OverridingMethodsDialog(myProject, overridingMethods); + dialog.show(); + if(!dialog.isOK()) return null; + result.addAll(dialog.getSelected()); + } + + final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + /** + * @param usages + * @return Map from elements to UsageHolders + */ + private HashMap sortUsages(UsageInfo[] usages) { + HashMap result = new HashMap(); + + for (int i = 0; i < usages.length; i++) { + final UsageInfo usage = usages[i]; + + if (usage instanceof SafeDeleteUsageInfo) { + final PsiElement referencedElement = ((SafeDeleteUsageInfo) usage).getReferencedElement(); + if (!result.containsKey(referencedElement)) { + result.put(referencedElement, new UsageHolder(referencedElement, usages)); + } + } + } + return result; + } + + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == myElements.length); + for (int i = 0; i < elements.length; i++) { + myElements[i] = elements[i]; + } + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + if(myPreviewNonCodeUsages && UsageViewUtil.hasNonCodeUsages(usages)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in comments, strings and non-java files"); + return true; + } + + return super.isPreviewUsages(filterToBeDeleted(usages)); + } + + private UsageInfo[] filterToBeDeleted(UsageInfo[] infos) { + ArrayList list = new ArrayList(); + for (int i = 0; i < infos.length; i++) { + UsageInfo info = infos[i]; + if(!(info instanceof SafeDeleteReferenceUsageInfo) || (((SafeDeleteReferenceUsageInfo) info).isSafeDelete())) { + list.add(info); + } + } + return list.toArray(new UsageInfo[list.size()]); + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage instanceof SafeDeleteReferenceUsageInfo && ((SafeDeleteReferenceUsageInfo) usage).isSafeDelete()) { + ((SafeDeleteReferenceUsageInfo) usage).deleteElement(); + } else if (usage instanceof SafeDeletePrivatizeMethod) { + ((SafeDeletePrivatizeMethod) usage).getMethod().getModifierList().setModifierProperty(PsiModifier.PRIVATE, true); + } else if (usage instanceof SafeDeleteOverridingMethodUsageInfo) { + ((SafeDeleteOverridingMethodUsageInfo) usage).getOverridingMethod().delete(); + + } + } + + for (int i = 0; i < myElements.length; i++) { + PsiElement element = myElements[i]; + if(element instanceof PsiVariable) { + ((PsiVariable) element).normalizeDeclaration(); + } + + if (element instanceof PsiTypeParameter) { + deleteTypeParameterExternalUsages((PsiTypeParameter)element); + } + element.delete(); + } + } catch (IncorrectOperationException e) { + RefactoringUtil.processIncorrectOperation(myProject, e); + } + } + + private void deleteTypeParameterExternalUsages(PsiTypeParameter typeParameter) throws IncorrectOperationException { + PsiTypeParameterListOwner owner = typeParameter.getOwner(); + int index = owner.getTypeParameterList().getTypeParameterIndex(typeParameter); + + PsiSearchHelper searchHelper = typeParameter.getManager().getSearchHelper(); + PsiReference[] ownerReferences = searchHelper.findReferences(owner, typeParameter.getResolveScope(), false); + for (int j = 0; j < ownerReferences.length; j++) { + PsiReference reference = ownerReferences[j]; + if (reference instanceof PsiJavaCodeReferenceElement) { + PsiTypeElement[] typeArgs = ((PsiJavaCodeReferenceElement)reference).getParameterList().getTypeParameterElements(); + if (typeArgs.length > index) { + typeArgs[index].delete(); + } + } + } + } + + private String calcCommandName() { + StringBuffer buffer = new StringBuffer(); + buffer.append("Deleting "); + return RefactoringUtil.calculatePsiElementDescriptionList(myElements, buffer); + } + + private String myCachedCommandName = null; + protected String getCommandName() { + if (myCachedCommandName == null) { + myCachedCommandName = calcCommandName(); + } + return myCachedCommandName; + } + + private void findClassUsages(final PsiClass psiClass, ArrayList usages) { + PsiManager manager = psiClass.getManager(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + final PsiReference[] references = manager.getSearchHelper().findReferences(psiClass, projectScope, false); + + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement element = reference.getElement(); + + if (!isInside(element, myElements)) { + PsiElement parent = element.getParent(); + if (parent instanceof PsiImportStatement) { + usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(parent, psiClass, true)); + } else { + usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, psiClass, false)); + } + } + } + + addNonCodeUsages(psiClass, usages, myInsideDeletedElements); + } + + private void findMethodUsages(PsiMethod psiMethod, ArrayList usages) { + PsiManager manager = psiMethod.getManager(); + final PsiSearchHelper searchHelper = manager.getSearchHelper(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + final PsiReference[] references = searchHelper.findReferences(psiMethod, projectScope, false); + + if(psiMethod.isConstructor()) { + findConstructorUsages(psiMethod, references, usages); + return; + } + final PsiMethod[] overridingMethods = + removeDeletedMethods(searchHelper.findOverridingMethods(psiMethod, projectScope, true)); + + boolean anyRefs = false; + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement element = reference.getElement(); + if (!isInside(element, myElements) && !isInside(element, overridingMethods)) { + usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, psiMethod, false)); + anyRefs = true; + } + } + + final UsageInsideDeleted usageInsideDeleted; + if (!anyRefs) { + HashMap methodToReferences = new HashMap(); + for (int i = 0; i < overridingMethods.length; i++) { + PsiMethod overridingMethod = overridingMethods[i]; + final PsiReference[] overridingReferences = searchHelper.findReferences(overridingMethod, projectScope, false); + methodToReferences.put(overridingMethod, overridingReferences); + } + final HashSet validOverriding = + validateOverridingMethods(psiMethod, references, Arrays.asList(overridingMethods), methodToReferences, usages); + usageInsideDeleted = new UsageInsideDeleted() { + public boolean isInsideDeleted(PsiElement usage) { + if(usage instanceof PsiFile) return false; + return isInside(usage, myElements) || isInside(usage, validOverriding); + } + }; + } + else { + usageInsideDeleted = myInsideDeletedElements; + } + + addNonCodeUsages(psiMethod, usages, usageInsideDeleted); + } + + private PsiMethod[] removeDeletedMethods(PsiMethod[] methods) { + ArrayList list = new ArrayList(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + boolean isDeleted = false; + for (int j = 0; j < myElements.length; j++) { + PsiElement element = myElements[j]; + if(element == method) { + isDeleted = true; break; + } + } + if(!isDeleted) { + list.add(method); + } + } + return list.toArray(new PsiMethod[list.size()]); + } + + private void findConstructorUsages(PsiMethod constructor, PsiReference[] originalReferences, ArrayList usages) { + final PsiSearchHelper searchHelper = constructor.getManager().getSearchHelper(); + + HashMap constructorsToRefs = new HashMap(); + HashSet newConstructors = new HashSet(); + newConstructors.add(constructor); + constructorsToRefs.put(constructor, originalReferences); + HashSet passConstructors = new HashSet(); + do { + passConstructors.clear(); + for (Iterator iterator = newConstructors.iterator(); iterator.hasNext();) { + PsiMethod method = iterator.next(); + final PsiReference[] references = constructorsToRefs.get(method); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + PsiMethod overridingConstructor = getOverridingConstructorOfSuperCall(reference.getElement()); + if(overridingConstructor != null && !constructorsToRefs.containsKey(overridingConstructor)) { + PsiReference[] overridingConstructorReferences = + searchHelper.findReferences(overridingConstructor, GlobalSearchScope.projectScope(myProject), false); + constructorsToRefs.put(overridingConstructor, overridingConstructorReferences); + passConstructors.add(overridingConstructor); + } + } + } + newConstructors.clear(); + newConstructors.addAll(passConstructors); + } + while(!newConstructors.isEmpty()); + + final HashSet validOverriding = + validateOverridingMethods(constructor, originalReferences, constructorsToRefs.keySet(), constructorsToRefs, usages); + + addNonCodeUsages(constructor, usages, new UsageInsideDeleted() { + public boolean isInsideDeleted(PsiElement usage) { + if(usage instanceof PsiFile) return false; + return isInside(usage, myElements) || isInside(usage, validOverriding); + } + }); + } + + private HashSet validateOverridingMethods(PsiMethod originalMethod, final PsiReference[] originalReferences, + Collection overridingMethods, HashMap methodToReferences, ArrayList usages) { + LinkedHashSet validOverriding = new LinkedHashSet(overridingMethods); + boolean anyNewBadRefs; + do { + anyNewBadRefs = false; + for (Iterator iterator = overridingMethods.iterator(); iterator.hasNext();) { + PsiMethod overridingMethod = iterator.next(); + + if (validOverriding.contains(overridingMethod)) { + final PsiReference[] overridingReferences = methodToReferences.get(overridingMethod); + boolean anyOverridingRefs = false; + for (int j = 0; j < overridingReferences.length && !anyOverridingRefs; j++) { + final PsiElement element = overridingReferences[j].getElement(); + if (!isInside(element, myElements) && !isInside(element, validOverriding)) { + anyOverridingRefs = true; + } + } + + if (anyOverridingRefs) { + validOverriding.remove(overridingMethod); + anyNewBadRefs = true; + + for (int j = 0; j < originalReferences.length; j++) { + PsiReference reference = originalReferences[j]; + final PsiElement element = reference.getElement(); + if (!isInside(element, myElements) && !isInside(element, overridingMethods)) { + usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, originalMethod, false)); + validOverriding.clear(); + } + } + } + } + } + } + while(anyNewBadRefs && !validOverriding.isEmpty()); + + for (Iterator iterator = validOverriding.iterator(); iterator.hasNext();) { + PsiMethod method = iterator.next(); + if (method != originalMethod) { + + usages.add(new SafeDeleteOverridingMethodUsageInfo(method, originalMethod)); + } + } + + for (Iterator iterator = overridingMethods.iterator(); iterator.hasNext();) { + PsiMethod method = iterator.next(); + if(!validOverriding.contains(method)) { + final boolean methodCanBePrivate = + canBePrivate(method, methodToReferences.get(method), validOverriding); + if (methodCanBePrivate) { + usages.add(new SafeDeletePrivatizeMethod(method, originalMethod)); + } + } + } + return validOverriding; + } + + private static PsiMethod getOverridingConstructorOfSuperCall(final PsiElement element) { + PsiMethod overridingConstructor = null; + if(element instanceof PsiReferenceExpression && "super".equals(element.getText())) { + PsiElement parent = element.getParent(); + if(parent instanceof PsiMethodCallExpression) { + parent = parent.getParent(); + if(parent instanceof PsiExpressionStatement) { + parent = parent.getParent(); + if(parent instanceof PsiCodeBlock) { + parent = parent.getParent(); + if(parent instanceof PsiMethod && ((PsiMethod) parent).isConstructor()) { + overridingConstructor = (PsiMethod) parent; + } + } + } + } + } + return overridingConstructor; + } + + private boolean canBePrivate(PsiMethod method, PsiReference[] references, Collection deleted) { + final PsiClass containingClass = method.getContainingClass(); + if(containingClass == null) { + return false; + } + + PsiManager manager = method.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + final PsiModifierList privateModifierList; + try { + final PsiMethod newMethod = factory.createMethod("x3", PsiType.VOID); + privateModifierList = newMethod.getModifierList(); + privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true); + } catch (IncorrectOperationException e) { + LOG.assertTrue(false); + return false; + } + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement element = reference.getElement(); + if(!isInside(element, myElements) && !isInside(element, deleted) + && !manager.getResolveHelper().isAccessible(method, privateModifierList, element, null)) { + return false; + } + } + return true; + } + + private void findFieldUsages(PsiField psiField, ArrayList usages) { + PsiManager manager = psiField.getManager(); + final PsiReference[] references = manager.getSearchHelper().findReferences(psiField, GlobalSearchScope.projectScope(myProject), false); + + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + if (!myInsideDeletedElements.isInsideDeleted(reference.getElement())) { + final PsiElement element = reference.getElement(); + final PsiElement parent = element.getParent(); + if(parent instanceof PsiAssignmentExpression && element == ((PsiAssignmentExpression) parent).getLExpression()) { + usages.add(new SafeDeleteFieldWriteReference(((PsiAssignmentExpression) parent), psiField)); + } else { + usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(reference.getElement(), psiField, false)); + } + } + + } + + addNonCodeUsages(psiField, usages, myInsideDeletedElements); + } + + + private interface UsageInsideDeleted { + boolean isInsideDeleted(PsiElement usage); + } + + private final UsageInsideDeleted myInsideDeletedElements = new UsageInsideDeleted() { + public boolean isInsideDeleted(PsiElement usage) { + if(usage instanceof PsiFile) return false; + return isInside(usage, myElements); + } + }; + + private void addNonCodeUsages(final PsiElement element, ArrayList usages, final UsageInsideDeleted insideElements) { + RefactoringUtil.UsageInfoFactory nonCodeUsageFactory = new RefactoringUtil.UsageInfoFactory() { + public UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset) { + if (!insideElements.isInsideDeleted(usage)) { + return new SafeDeleteReferenceSimpleDeleteUsageInfo(usage, element, startOffset, endOffset, true, false); + } else { + return null; + } + } + }; + if (mySearchInCommentsAndStrings) { + String stringToSearch = RefactoringUtil.getStringToSearch(element, false); + if (stringToSearch != null) { + RefactoringUtil.addUsagesInStringsAndComments(element, stringToSearch, usages, nonCodeUsageFactory); + } + } + if (mySearchNonJava && (element instanceof PsiClass || element instanceof PsiPackage)) { + String stringToSearch = RefactoringUtil.getStringToSearch(element, true); + if (stringToSearch != null) { + RefactoringUtil.addUsagesInNonJavaFiles(element, stringToSearch, GlobalSearchScope.projectScope(myProject), usages, nonCodeUsageFactory); + } + } + } + + public static boolean validElement(PsiElement element) { + return element instanceof PsiClass + || element instanceof PsiMethod + || element instanceof PsiField; + } + + public static SafeDeleteProcessor createInstance(Project project, Runnable prepareSuccessfulCallback, + PsiElement[] elementsToDelete, boolean isSearchInComments, boolean isSearchNonJava) { + return new SafeDeleteProcessor(project, prepareSuccessfulCallback, elementsToDelete, isSearchInComments, isSearchNonJava); + } + + public static SafeDeleteProcessor createInstance(Project project, Runnable prepareSuccessfulCallBack, + PsiElement[] elementsToDelete, boolean isSearchInComments, boolean isSearchNonJava, + boolean askForAccessors) { + PsiManager manager = PsiManager.getInstance(project); + ArrayList elements = new ArrayList(Arrays.asList(elementsToDelete)); + HashSet elementsToDeleteSet = new HashSet(Arrays.asList(elementsToDelete)); + + for (int i = 0; i < elementsToDelete.length; i++) { + PsiElement psiElement = elementsToDelete[i]; + if (psiElement instanceof PsiField) { + PsiField field = (PsiField) psiElement; + final String propertyName = + manager.getCodeStyleManager().variableNameToPropertyName(field.getName(), VariableKind.FIELD); + + PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); + PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false); + if (elementsToDeleteSet.contains(getter)) getter = null; + PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false); + if (elementsToDeleteSet.contains(setter)) setter = null; + if (askForAccessors && (getter != null || setter != null)) { + final String message = RefactoringMessageUtil.getGetterSetterMessage(field.getName(), "Delete", getter, setter); + if (Messages.showYesNoDialog(project, message, "Safe Delete", Messages.getQuestionIcon()) != 0) { + getter = null; + setter = null; + } + } + if (setter != null) elements.add(setter); + if (getter != null) elements.add(getter); + } + } + } + + return new SafeDeleteProcessor(project, prepareSuccessfulCallBack, + elements.toArray(new PsiElement[elements.size()]), + isSearchInComments, isSearchNonJava); + } + + public boolean isSearchInCommentsAndStrings() { + return mySearchInCommentsAndStrings; + } + + public void setSearchInCommentsAndStrings(boolean searchInCommentsAndStrings) { + mySearchInCommentsAndStrings = searchInCommentsAndStrings; + } + + public boolean isSearchNonJava() { + return mySearchNonJava; + } + + public void setSearchNonJava(boolean searchNonJava) { + mySearchNonJava = searchNonJava; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteUsageViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteUsageViewDescriptor.java new file mode 100644 index 00000000000..c37aac78449 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/SafeDeleteUsageViewDescriptor.java @@ -0,0 +1,77 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewUtil; + +/** + * @author dsl + */ +public class SafeDeleteUsageViewDescriptor extends UsageViewDescriptorAdapter { + private final PsiElement[] myElementsToDelete; + private final SafeDeleteProcessor myProcessor; + + public SafeDeleteUsageViewDescriptor(UsageInfo[] usages, + FindUsagesCommand refreshCommand, + PsiElement[] elementsToDelete, + SafeDeleteProcessor processor) { + super(usages, refreshCommand); + myElementsToDelete = elementsToDelete; + myProcessor = processor; + } + + public PsiElement[] getElements() { + return myElementsToDelete; + } + + public void refresh(PsiElement[] elements) { + myProcessor.setElements(elements); + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return "Items to be deleted"; + } + + public boolean isSearchInText() { + return true; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord() { + return "occurences"; + } + + public String getCommentReferencesWord() { + return "occurences"; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public boolean canRefresh() { + return true; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return !usageInfo.isNonCodeUsage; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References in code " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return "Occurrences found in comments, strings and non-java files " + + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "occurrence") + + ". Those occurrences will not be changed"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UnsafeUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UnsafeUsagesDialog.java new file mode 100644 index 00000000000..1577a77277c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UnsafeUsagesDialog.java @@ -0,0 +1,84 @@ +/** + * created at Sep 12, 2001 + * @author Jeka + */ +package com.intellij.refactoring.safeDelete; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +public class UnsafeUsagesDialog extends DialogWrapper { + private JEditorPane myMessagePane; + private String[] myConflictDescriptions; + static final int VIEW_USAGES_EXIT_CODE = NEXT_USER_EXIT_CODE; + + public UnsafeUsagesDialog(String[] conflictDescriptions, Project project) { + super(project, true); + myConflictDescriptions = conflictDescriptions; + setTitle("Usages Detected"); + setOKButtonText("Ignore"); + getOKAction().putValue(Action.MNEMONIC_KEY, new Integer('I')); + init(); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(), new ViewUsagesAction(), new CancelAction()}; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myMessagePane = new JEditorPane("text/html", ""); + myMessagePane.setEditable(false); + JScrollPane scrollPane = new JScrollPane(myMessagePane); + scrollPane.setPreferredSize(new Dimension(500, 400)); + panel.add(new JLabel("The following problems were found:"), BorderLayout.NORTH); + panel.add(scrollPane, BorderLayout.CENTER); + + StringBuffer buf = new StringBuffer(); + for (int idx = 0; idx < myConflictDescriptions.length; idx++) { + String description = myConflictDescriptions[idx]; + buf.append(description).append("

    "); + } + myMessagePane.setText(buf.toString()); + return panel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog"; + } + +/* + protected JComponent createSouthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(super.createSouthPanel(), BorderLayout.CENTER); +// panel.add(new JLabel("Do you wish to ignore them and continue?"), BorderLayout.WEST); + return panel; + } +*/ + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + } + + public void actionPerformed(ActionEvent e) { + doCancelAction(); + } + } + + private class ViewUsagesAction extends AbstractAction { + public ViewUsagesAction() { + super("View usages"); + putValue(Action.MNEMONIC_KEY, new Integer('V')); + putValue(DialogWrapper.DEFAULT_ACTION, Boolean.TRUE); + } + + public void actionPerformed(ActionEvent e) { + close(VIEW_USAGES_EXIT_CODE); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UsageHolder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UsageHolder.java new file mode 100644 index 00000000000..3edb8818e52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/UsageHolder.java @@ -0,0 +1,95 @@ +package com.intellij.refactoring.safeDelete; + +import com.intellij.psi.*; +import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceUsageInfo; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.usageView.UsageInfo; + +import java.util.ArrayList; + +/** + * @author dsl + */ +class UsageHolder { + private final PsiElement myElement; + private final SafeDeleteReferenceUsageInfo[] myUsages; + private Integer myNonSafeUsages; + private Integer myNonCodeUsages; + + public UsageHolder(PsiElement element, UsageInfo[] usageInfos) { + myElement = element; + + ArrayList elementUsages = new ArrayList(); + for (int i = 0; i < usageInfos.length; i++) { + UsageInfo usageInfo = usageInfos[i]; + if(usageInfo instanceof SafeDeleteReferenceUsageInfo) { + final SafeDeleteReferenceUsageInfo referenceUsageInfo = (SafeDeleteReferenceUsageInfo) usageInfo; + if(referenceUsageInfo.getReferencedElement() == myElement) { + elementUsages.add(referenceUsageInfo); + } + } + } + myUsages = + elementUsages.toArray(new SafeDeleteReferenceUsageInfo[elementUsages.size()]); + } + + public int getNonCodeUsagesNumber() { + if(myNonCodeUsages == null) { + int nonCodeUsages = 0; + for (int i = 0; i < myUsages.length; i++) { + SafeDeleteReferenceUsageInfo usage = myUsages[i]; + if(usage.isNonCodeUsage) { nonCodeUsages++; } + } + myNonCodeUsages = new Integer(nonCodeUsages); + } + return myNonCodeUsages.intValue(); + } + + public int getNonSafeUsagesNumber() { + if(myNonSafeUsages == null) { + int nonSafeUsages = 0; + for (int i = 0; i < myUsages.length; i++) { + SafeDeleteReferenceUsageInfo usage = myUsages[i]; + if(!usage.isSafeDelete()) { nonSafeUsages++; } + } + myNonSafeUsages = new Integer(nonSafeUsages); + } + return myNonSafeUsages.intValue(); + } + + public String getDescription() { + final int nonCodeUsages = getNonCodeUsagesNumber(); + final int nonSafeUsages = getNonSafeUsagesNumber(); + + if(nonSafeUsages == 0) return null; + + StringBuffer buffer = new StringBuffer(); + buffer.append(ConflictsUtil.getDescription(myElement, true)); + buffer.append(" has "); + if(nonCodeUsages == nonSafeUsages) { + buffer.append(nonCodeUsages + getCorrectForm(nonCodeUsages, " usage", " usages")); + buffer.append(" in strings, comments, or non-Java files."); + } + else { + buffer.append(nonSafeUsages + getCorrectForm(nonSafeUsages, " usage", " usages")); + buffer.append(" that " + getCorrectForm(nonSafeUsages, "is", "are") + " not safe to delete."); + if(nonCodeUsages > 0) { + buffer.append(" Of those, "); + buffer.append(nonCodeUsages); + buffer.append(getCorrectForm(nonCodeUsages, " usage is", " usages are")); + buffer.append(" in strings, comments, or non-Java files."); + } + } + return buffer.toString(); + } + + private String getCorrectForm(final int itemsNumber, String singleForm, String multipleForm) { + if (itemsNumber == 1) { + return singleForm; + } + else { + return multipleForm; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteFieldWriteReference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteFieldWriteReference.java new file mode 100644 index 00000000000..7f965195666 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteFieldWriteReference.java @@ -0,0 +1,30 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.*; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class SafeDeleteFieldWriteReference extends SafeDeleteReferenceUsageInfo { + private final PsiAssignmentExpression myExpression; + + public SafeDeleteFieldWriteReference(PsiAssignmentExpression expr, PsiField referencedElement) { + super(expr, referencedElement, safeRemoveRHS(expr)); + myExpression = expr; + } + + private static boolean safeRemoveRHS(PsiAssignmentExpression expression) { + final PsiExpression rExpression = expression.getRExpression(); + final PsiElement parent = expression.getParent(); + return RefactoringUtil.verifySafeCopyExpression(rExpression) == RefactoringUtil.EXPR_COPY_SAFE + && parent instanceof PsiExpressionStatement + && ((PsiExpressionStatement) parent).getExpression() == expression; + } + + public void deleteElement() throws IncorrectOperationException { + myExpression.getParent().delete(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteOverridingMethodUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteOverridingMethodUsageInfo.java new file mode 100644 index 00000000000..2c293109892 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteOverridingMethodUsageInfo.java @@ -0,0 +1,21 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.PsiMethod; + +/** + * @author dsl + */ +public class SafeDeleteOverridingMethodUsageInfo extends SafeDeleteUsageInfo { + + public SafeDeleteOverridingMethodUsageInfo(PsiMethod overridingMethod, PsiMethod method) { + super(overridingMethod, method); + } + + public PsiMethod getOverridingMethod() { + return (PsiMethod) getElement(); + } + + public PsiMethod getReferencedMethod() { + return (PsiMethod) getReferencedElement(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeletePrivatizeMethod.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeletePrivatizeMethod.java new file mode 100644 index 00000000000..069ac257563 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeletePrivatizeMethod.java @@ -0,0 +1,16 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.PsiMethod; + +/** + * @author dsl + */ +public class SafeDeletePrivatizeMethod extends SafeDeleteUsageInfo { + public SafeDeletePrivatizeMethod(PsiMethod method, PsiMethod overridenMethod) { + super(method, overridenMethod); + } + + public PsiMethod getMethod() { + return (PsiMethod) getElement(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceSimpleDeleteUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceSimpleDeleteUsageInfo.java new file mode 100644 index 00000000000..ad7af018747 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceSimpleDeleteUsageInfo.java @@ -0,0 +1,25 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class SafeDeleteReferenceSimpleDeleteUsageInfo extends SafeDeleteReferenceUsageInfo { + + public SafeDeleteReferenceSimpleDeleteUsageInfo(PsiElement element, PsiElement referencedElement, boolean isSafeDelete) { + super(element, referencedElement, isSafeDelete); + } + + public SafeDeleteReferenceSimpleDeleteUsageInfo(PsiElement element, PsiElement referencedElement, + int startOffset, int endOffset, boolean isNonCodeUsage, boolean isSafeDelete) { + super(element, referencedElement, startOffset, endOffset, isNonCodeUsage, isSafeDelete); + } + + public void deleteElement() throws IncorrectOperationException { + if(isSafeDelete()) { + getElement().delete(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceUsageInfo.java new file mode 100644 index 00000000000..5f6c49b3efc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteReferenceUsageInfo.java @@ -0,0 +1,28 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public abstract class SafeDeleteReferenceUsageInfo extends SafeDeleteUsageInfo { + protected final boolean mySafeDelete; + + public boolean isSafeDelete() { + return !isNonCodeUsage && mySafeDelete; + } + + public abstract void deleteElement() throws IncorrectOperationException; + + public SafeDeleteReferenceUsageInfo(PsiElement element, PsiElement referencedElement, + int startOffset, int endOffset, boolean isNonCodeUsage, boolean isSafeDelete) { + super(element, referencedElement, startOffset, endOffset, isNonCodeUsage); + mySafeDelete = isSafeDelete; + } + + public SafeDeleteReferenceUsageInfo(PsiElement element, PsiElement referencedElement, boolean safeDelete) { + super(element, referencedElement); + mySafeDelete = safeDelete; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteUsageInfo.java new file mode 100644 index 00000000000..d7bd873181a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteUsageInfo.java @@ -0,0 +1,29 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.psi.*; +import com.intellij.usageView.UsageInfo; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author dsl + */ +public class SafeDeleteUsageInfo extends UsageInfo { + private static final Logger LOG = Logger.getInstance( + "#com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteUsageInfo"); + private final PsiElement myReferencedElement; + + public SafeDeleteUsageInfo(PsiElement element, PsiElement referencedElement) { + super(element); + LOG.assertTrue(element != null); + myReferencedElement = referencedElement; + } + + public SafeDeleteUsageInfo(PsiElement element, PsiElement referencedElement, + int startOffset, int endOffset, boolean isNonCodeUsage) { + super(element, startOffset, endOffset, isNonCodeUsage); + myReferencedElement = referencedElement; + } + public PsiElement getReferencedElement() { + return myReferencedElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/tempWithQuery/TempWithQueryHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/tempWithQuery/TempWithQueryHandler.java new file mode 100644 index 00000000000..0a8fea67ce3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/tempWithQuery/TempWithQueryHandler.java @@ -0,0 +1,161 @@ +package com.intellij.refactoring.tempWithQuery; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.extractMethod.ExtractMethodHandler; +import com.intellij.refactoring.extractMethod.ExtractMethodProcessor; +import com.intellij.refactoring.extractMethod.PrepareFailedException; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.refactoring.util.duplicates.DuplicatesImpl; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; + +public class TempWithQueryHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.tempWithQuery.TempWithQueryHandler"); + + private static final String REFACTORING_NAME = "Replace Temp with Query"; + + public void invoke(final Project project, final Editor editor, PsiFile file, DataContext dataContext) { + PsiElement element = TargetElementUtil.findTargetElement(editor, + TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.LOOKUP_ITEM_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + ); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + if (!(element instanceof PsiLocalVariable)) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned at the name of the local variable to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_TEMP_WITH_QUERY, project); + return; + } + + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, file); + return; + } + + final PsiLocalVariable local = (PsiLocalVariable) element; + + String localName = local.getName(); + final PsiExpression initializer = local.getInitializer(); + if (initializer == null) { + String message = + "Cannot perform the refactoring.\n" + + "Variable " + localName + " has no initializer."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_TEMP_WITH_QUERY, project); + return; + } + + PsiSearchHelper searchHelper = PsiManager.getInstance(project).getSearchHelper(); + final PsiReference[] refs = searchHelper.findReferences(local, GlobalSearchScope.projectScope(project), false); + + if (refs.length == 0) { + String message = "Variable " + localName + " is never used"; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_TEMP_WITH_QUERY, project); + return; + } + + final HighlightManager highlightManager = HighlightManager.getInstance(project); + ArrayList array = new ArrayList(); + EditorColorsManager manager = EditorColorsManager.getInstance(); + final TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + for (int idx = 0; idx < refs.length; idx++) { + PsiReference ref = refs[idx]; + PsiElement refElement = ref.getElement(); + if (PsiUtil.isAccessedForWriting((PsiExpression) refElement)) { + array.add(ref); + } + if (array.size() > 0) { + PsiReference[] refsForWriting = array.toArray(new PsiReference[array.size()]); + highlightManager.addOccurrenceHighlights(editor, refsForWriting, attributes, true, null); + String message = + "Cannot perform the refactoring.\n" + + "Variable " + localName + " is accessed for writing."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_TEMP_WITH_QUERY, project); + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + return; + } + } + + final ExtractMethodProcessor processor = new ExtractMethodProcessor( + project, editor, file, + new PsiElement[]{initializer}, local.getType(), + REFACTORING_NAME, localName, HelpID.REPLACE_TEMP_WITH_QUERY + ); + + try { + if (!processor.prepare()) return; + } + catch (PrepareFailedException e) { + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, e.getMessage(), HelpID.REPLACE_TEMP_WITH_QUERY, project); + ExtractMethodHandler.highlightPrepareError(e, file, editor, project); + return; + } + final PsiClass targetClass = processor.getTargetClass(); + if (targetClass != null && targetClass.isInterface()) { + String message = "Cannot replace temp with query in interface."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.REPLACE_TEMP_WITH_QUERY, project); + return; + } + + + if (processor.showDialog()) { + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + processor.doRefactoring(); + + local.normalizeDeclaration(); + + PsiExpression initializer = local.getInitializer(); + + PsiExpression[] exprs = new PsiExpression[refs.length]; + for (int idx = 0; idx < refs.length; idx++) { + PsiElement ref = refs[idx].getElement(); + exprs[idx] = (PsiExpression) ref.replace(initializer); + } + PsiDeclarationStatement declaration = (PsiDeclarationStatement) local.getParent(); + declaration.delete(); + + highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + REFACTORING_NAME, + null + ); + DuplicatesImpl.processDuplicates(processor, project, editor, REFACTORING_NAME); + } + + + WindowManager.getInstance().getStatusBar(project).setInfo("Press Escape to remove the highlighting"); + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/RefsToSuperViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/RefsToSuperViewDescriptor.java new file mode 100644 index 00000000000..5accdb22b85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/RefsToSuperViewDescriptor.java @@ -0,0 +1,103 @@ + +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class RefsToSuperViewDescriptor implements UsageViewDescriptor{ + private final TurnRefsToSuperProcessor myProcessor; + private PsiClass myClass; + private PsiClass mySuper; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public RefsToSuperViewDescriptor(TurnRefsToSuperProcessor processor, PsiClass aClass, PsiClass anInterface, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myProcessor = processor; + myClass = aClass; + mySuper = anInterface; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public PsiElement[] getElements() { + return new PsiElement[] {myClass, mySuper}; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + myClass = (PsiClass)elements[0]; + mySuper = (PsiClass)elements[1]; + myProcessor.setClasses(myClass, mySuper); + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return null; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + StringBuffer buffer = new StringBuffer(); + buffer.append("References to "); + buffer.append(myClass.isInterface() ? "interface " : "class "); + buffer.append(myClass.getName()); + buffer.append(" to be replaced with references to "); + buffer.append(mySuper.isInterface() ? "interface " : "class "); + buffer.append(mySuper.getName()); + buffer.append(" "); + buffer.append(UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference")); + return buffer.toString(); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperDialog.java new file mode 100644 index 00000000000..d6a67767ed4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperDialog.java @@ -0,0 +1,118 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 06.06.2002 + * Time: 11:30:13 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.refactoring.ui.ClassCellRenderer; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; +import java.util.List; + +public class TurnRefsToSuperDialog extends RefactoringDialog { + private final PsiClass mySubClass; + private final List mySuperClasses; + + private JList mySuperClassesList = null; + private final JCheckBox myCbReplaceInstanceOf = new JCheckBox("Use interface/superclass in instanceof"); + + TurnRefsToSuperDialog(Project project, PsiClass subClass, List superClasses) { + super(project, true); + + mySubClass = subClass; + mySuperClasses = superClasses; + + setTitle(TurnRefsToSuperHandler.REFACTORING_NAME); + init(); + } + + public PsiClass getSuperClass() { + if(mySuperClassesList != null) { + return (PsiClass) mySuperClassesList.getSelectedValue(); + } + else { + return null; + } + } + + public boolean isUseInInstanceOf() { + return myCbReplaceInstanceOf.isSelected(); + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.TURN_REFS_TO_SUPER); + } + + public JComponent getPreferredFocusedComponent() { + return mySuperClassesList; + } + + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createBorder()); + + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridy = 0; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + gbConstraints.anchor = GridBagConstraints.WEST; + final JLabel classListLabel = new JLabel("Change usages of " + mySubClass.getQualifiedName() + " to:"); + panel.add(classListLabel, gbConstraints); + + mySuperClassesList = new JList(mySuperClasses.toArray()); + mySuperClassesList.setCellRenderer(new ClassCellRenderer()); + mySuperClassesList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + classListLabel.setLabelFor(mySuperClassesList); + classListLabel.setDisplayedMnemonic('C'); + + PsiClass nearestBase = RefactoringHierarchyUtil.getNearestBaseClass(mySubClass, true); + int indexToSelect = 0; + if(nearestBase != null) { + indexToSelect = mySuperClasses.indexOf(nearestBase); + } + mySuperClassesList.setSelectedIndex(indexToSelect); + gbConstraints.gridy++; + panel.add(new JScrollPane(mySuperClassesList), gbConstraints); + + gbConstraints.gridy++; + myCbReplaceInstanceOf.setMnemonic('U'); + myCbReplaceInstanceOf.setSelected(false); + myCbReplaceInstanceOf.setFocusable(false); + panel.add(myCbReplaceInstanceOf, gbConstraints); + + return panel; + } + + protected String getDimensionServiceKey() { + return "#com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperDialog"; + } + + protected void doAction() { + RefactoringSettings.getInstance().TURN_REFS_TO_SUPER_PREVIEW_USAGES = isPreviewUsages(); + close(OK_EXIT_CODE); + } + + protected JComponent createCenterPanel() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperHandler.java new file mode 100644 index 00000000000..35381b74c20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperHandler.java @@ -0,0 +1,79 @@ +/** + * created at Oct 25, 2001 + * @author Jeka + */ +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +import java.util.ArrayList; + +public class TurnRefsToSuperHandler implements RefactoringActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperHandler"); + + public static final String REFACTORING_NAME = "Use Interface Where Possible"; + + private Project myProject; + + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + int offset = editor.getCaretModel().getOffset(); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = file.findElementAt(offset); + while (true) { + if (element == null || element instanceof PsiFile) { + String message = + "Cannot perform the refactoring.\n" + + "The caret should be positioned inside the class to be refactored."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.EXTRACT_SUPERCLASS, project); + return; + } + if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) { + invoke(project, new PsiElement[]{element}, dataContext); + return; + } + element = element.getParent(); + } + } + + public void invoke(final Project project, PsiElement[] elements, DataContext dataContext) { + if (elements.length != 1) return; + + myProject = project; + PsiClass subClass = (PsiClass) elements[0]; + + ArrayList basesList = RefactoringHierarchyUtil.createBasesList(subClass, true, true); + + if (basesList.isEmpty()) { + String message = + "Cannot perform the refactoring.\n" + + "Interface " + subClass.getQualifiedName() + " does not have base interfaces."; + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, null/*HelpID.TURN_REFS_TO_SUPER*/, project); + return; + } + + TurnRefsToSuperDialog dialog = new TurnRefsToSuperDialog(myProject, subClass, basesList); + dialog.show(); + if (!dialog.isOK()) { + return; + } + + new TurnRefsToSuperProcessor( + myProject, subClass, dialog.getSuperClass(), dialog.isUseInInstanceOf(), + dialog.isPreviewUsages() + ).run(null); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java new file mode 100644 index 00000000000..bdbc6b9f7ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java @@ -0,0 +1,126 @@ +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; + +public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessor"); + + private PsiClass mySuper; + private final boolean myPreviewUsages; + + public TurnRefsToSuperProcessor(Project project, + PsiClass aClass, + PsiClass aSuper, + boolean replaceInstanceOf, + boolean previewUsages + ) { + super(project, replaceInstanceOf); + myClass = aClass; + mySuper = aSuper; + myPreviewUsages = previewUsages; + } + + protected String getCommandName() { + return "Replacing usages of " + UsageViewUtil.getDescriptiveName(myClass) + " with " + UsageViewUtil.getDescriptiveName(mySuper); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new RefsToSuperViewDescriptor(this, myClass, mySuper, usages, refreshCommand); + } + + void setClasses(final PsiClass aClass, final PsiClass aSuper) { + myClass = aClass; + mySuper = aSuper; + } + + protected UsageInfo[] findUsages() { + final PsiReference[] refs = mySearchHelper.findReferences(myClass, GlobalSearchScope.projectScope(myProject), false); + + final ArrayList result = detectTurnToSuperRefs(refs, new ArrayList()); + + final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); + } + + protected void refreshElements(final PsiElement[] elements) { + final boolean condition = elements.length == 2 && elements[0] instanceof PsiClass && elements[1] instanceof PsiClass; + LOG.assertTrue(condition); + myClass = (PsiClass) elements[0]; + mySuper = (PsiClass) elements[1]; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myPreviewUsages; + return super.isPreviewUsages(usages) || toPreview; + } + + protected boolean preprocessUsages(UsageInfo[][] usages) { + if (!ApplicationManager.getApplication().isUnitTestMode() && usages[0].length == 0) { + String message = "No usages of " + myClass.getQualifiedName() + "\n" + + "can be replaced with usages of " + mySuper.getQualifiedName(); + Messages.showInfoMessage(myProject, message, TurnRefsToSuperHandler.REFACTORING_NAME); + return false; + } + return true; + } + + protected void performRefactoring(UsageInfo[] usages) { + try { + final PsiClass aSuper = mySuper; + processTurnToSuperRefs(usages, aSuper); + + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + protected boolean isInSuper(PsiElement member) { + if (member instanceof PsiField) { + final PsiClass containingClass = ((PsiField) member).getContainingClass(); + final PsiManager manager = member.getManager(); + if (manager.areElementsEquivalent(containingClass, manager.getElementFactory().getArrayClass())) { + return true; + } + return manager.areElementsEquivalent(containingClass, mySuper) + || mySuper.isInheritor(containingClass, true); + } else if (member instanceof PsiMethod) { + if (member.getParent().equals(mySuper)) return true; + PsiMethod methodInSuper2 = mySuper.findMethodBySignature((PsiMethod) member, true); + if (methodInSuper2 != null) { + return true; + } + return false; + } else { + return false; //? + } + } + + protected boolean isSuperInheritor(PsiClass aClass) { + return InheritanceUtil.isInheritorOrSelf(mySuper, aClass, true); + } + + public PsiClass getSuper() { + return mySuper; + } + + public PsiClass getTarget() { + return myClass; + } + + public boolean isReplaceInstanceOf() { + return myReplaceInstanceOf; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java new file mode 100644 index 00000000000..6f3e311f476 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java @@ -0,0 +1,549 @@ +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.internal.diGraph.analyzer.GlobalAnalyzer; +import com.intellij.internal.diGraph.analyzer.Mark; +import com.intellij.internal.diGraph.analyzer.OneEndFunctor; +import com.intellij.internal.diGraph.analyzer.MarkedNode; +import com.intellij.internal.diGraph.impl.EdgeImpl; +import com.intellij.internal.diGraph.impl.NodeImpl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.search.PsiSearchHelperImpl; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.Queue; +import com.intellij.util.containers.HashSet; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * @author dsl + */ +public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessorBase"); + protected PsiClass myClass; + protected final boolean myReplaceInstanceOf; + protected PsiManager myManager; + protected PsiSearchHelper mySearchHelper; + protected HashSet myMarkedNodes = new HashSet(); + private Queue myExpressionsQueue; + protected HashMap myElementToNode = new HashMap(); + + public TurnRefsToSuperProcessorBase(Project project, boolean replaceInstanceOf) { + super(project); + myManager = PsiManager.getInstance(project); + mySearchHelper = myManager.getSearchHelper(); + myManager = PsiManager.getInstance(myProject); + myReplaceInstanceOf = replaceInstanceOf; + } + + protected ArrayList detectTurnToSuperRefs(PsiReference[] refs, final ArrayList result) { + buildGraph(refs); + + for (int idx = 0; idx < refs.length; idx++) { + final PsiElement ref = refs[idx].getElement(); + if (canTurnToSuper(ref)) { + result.add(new TurnToSuperReferenceUsageInfo(ref)); + } + } + return result; + } + + protected boolean canTurnToSuper(PsiElement ref) { + return !myMarkedNodes.contains(ref); + } + + protected void processTurnToSuperRefs(UsageInfo[] usages, final PsiClass aSuper) throws IncorrectOperationException { + HashSet fileSet = new HashSet(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (usage.getElement() == null || !usage.getElement().isValid()) continue; + if (!(usage instanceof TurnToSuperReferenceUsageInfo)) continue; + fileSet.add(usage.getElement().getContainingFile()); + PsiElement newElement = usage.getElement().getReference().bindToElement(aSuper); + + if (newElement.getParent() instanceof PsiTypeElement) { + if (newElement.getParent().getParent() instanceof PsiTypeCastExpression) { + fixPossiblyRedundantCast((PsiTypeCastExpression)newElement.getParent().getParent()); + } + } + } + + // remove unnecessary imports of the class + for (Iterator iterator = fileSet.iterator(); iterator.hasNext();) { + PsiFile file = iterator.next(); + PsiReference[] refs = mySearchHelper.findReferences(myClass, new LocalSearchScope(file), false); + if (refs.length == 1 && refs[0].getElement().getParent() instanceof PsiImportStatement) { + refs[0].getElement().getParent().delete(); + } + } + } + + private void fixPossiblyRedundantCast(PsiTypeCastExpression cast) throws IncorrectOperationException { + PsiClass castClass = PsiUtil.resolveClassInType(cast.getCastType().getType()); + if (castClass == null) return; + + PsiExpression operand = cast.getOperand(); + if (operand == null) return; + PsiClass operandClass = PsiUtil.resolveClassInType(RefactoringUtil.getTypeByExpression(operand)); + if (operandClass == null) return; + + if (!castClass.getManager().areElementsEquivalent(castClass, operandClass) && + !operandClass.isInheritor(castClass, true)) { + return; + } + // OK, cast is redundant + PsiExpression exprToReplace = cast; + while (exprToReplace.getParent() instanceof PsiParenthesizedExpression) { + exprToReplace = (PsiExpression)exprToReplace.getParent(); + } + exprToReplace.replace(operand); + } + + private void buildGraph(PsiReference[] refs) { + myMarkedNodes.clear(); + myExpressionsQueue = new Queue(refs.length); + myElementToNode.clear(); + for (int i = 0; i < refs.length; i++) { + processUsage(refs[i].getElement()); + } + + processQueue(); + + markNodes(); + + spreadMarks(); + } + + private void processUsage(PsiElement ref) { + if (ref instanceof PsiReferenceExpression) { + final PsiElement parent = ref.getParent(); + if (parent instanceof PsiReferenceExpression) { + final PsiReferenceExpression refExpr = (PsiReferenceExpression)parent; + final PsiElement refMember = refExpr.resolve(); + if (!isInSuper(refMember)) { + markNode(ref); + } + } + return; + } + + PsiElement parent = ref.getParent(); + if (parent instanceof PsiTypeElement) { + PsiElement pparent = parent.getParent(); + while (pparent instanceof PsiTypeElement) { + addLink(pparent, parent); + addLink(parent, pparent); + parent = pparent; + pparent = parent.getParent(); + } + final PsiTypeElement type = (PsiTypeElement)parent; + + addLink(type, ref); + addLink(ref, type); + if (pparent instanceof PsiVariable) { + processVariableType((PsiVariable)pparent); + } + else if (pparent instanceof PsiMethod) { + processMethodReturnType((PsiMethod)pparent); + } + else if (pparent instanceof PsiTypeCastExpression) { + addLink(pparent, type); + addLink(type, pparent); + } + } + else if (parent instanceof PsiNewExpression) { + PsiNewExpression newExpression = (PsiNewExpression)parent; + if (newExpression.getType() instanceof PsiArrayType) { + addLink(newExpression, ref); + addLink(ref, newExpression); + PsiArrayInitializerExpression initializer = newExpression.getArrayInitializer(); + if (initializer != null) { + addLink(ref, initializer); + } + checkToArray(ref, newExpression); + } + else { + markNode(ref); + } + } + else { + markNode(ref); + } + } + + private void addArgumentParameterLink(PsiElement arg, PsiExpressionList actualArgsList, PsiMethod method) { + PsiParameter[] params = method.getParameterList().getParameters(); + PsiExpression[] actualArgs = actualArgsList.getExpressions(); + int argIndex = -1; + for (int i = 0; i < actualArgs.length; i++) { + PsiExpression actualArg = actualArgs[i]; + if (actualArg.equals(arg)) { + argIndex = i; + break; + } + } + + if (argIndex >= 0 && argIndex < params.length) { + addLink(params[argIndex], arg); + } + else if (method.isVarArgs() && argIndex >= params.length) { + addLink(params[params.length - 1], arg); + } + } + + private void checkToArray(PsiElement ref, PsiNewExpression newExpression) { + PsiElement tmp; + + final PsiClass javaUtilCollectionClass = myManager.findClass("java.util.Collection", ref.getResolveScope()); + if (javaUtilCollectionClass == null) return; + tmp = newExpression.getParent(); + if (!(tmp instanceof PsiExpressionList)) return; + tmp = tmp.getParent(); + if (!(tmp instanceof PsiMethodCallExpression)) return; + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)tmp; + tmp = tmp.getParent(); + if (!(tmp instanceof PsiTypeCastExpression)) return; + PsiTypeCastExpression typeCast = (PsiTypeCastExpression)tmp; + + PsiReferenceExpression methodRef = methodCall.getMethodExpression(); + if (methodRef == null) return; + tmp = methodRef.resolve(); + if (!(tmp instanceof PsiMethod)) return; + PsiMethod method = (PsiMethod)tmp; + if (!method.getName().equals("toArray")) return; + + PsiClass methodClass = method.getContainingClass(); + if (!methodClass.isInheritor(javaUtilCollectionClass, true)) return; + + // ok, this is an implementation of java.util.Collection.toArray + addLink(typeCast, ref); + + } + + private void processVariableType(PsiVariable variable) { + final PsiTypeElement type = variable.getTypeElement(); + final PsiExpression initializer = variable.getInitializer(); + if (initializer != null) { + addLink(type, initializer); + } + + final PsiReference[] refs = mySearchHelper.findReferences(variable, GlobalSearchScope.projectScope(myProject), false); + for (int i = 0; i < refs.length; i++) { + final PsiElement ref = refs[i].getElement(); + addLink(ref, type); + addLink(type, ref); + } + + if (variable instanceof PsiParameter) { + final PsiElement declScope = ((PsiParameter)variable).getDeclarationScope(); + if (declScope instanceof PsiTryStatement) { + markNode(type); + } + else if (declScope instanceof PsiForeachStatement) { + markNode(type); // todo[dsl] + } + else if (declScope instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)declScope; + final int index = method.getParameterList().getParameterIndex((PsiParameter)variable); + + { + // todo[dsl]: do we really really want to to all this??? + PsiReference[] calls = mySearchHelper.findReferences(method, GlobalSearchScope.projectScope(myProject), false); + for (int i = 0; i < calls.length; i++) { + PsiElement ref = calls[i].getElement(); + PsiExpressionList argumentList; + if (ref.getParent() instanceof PsiCall) { + argumentList = ((PsiCall)ref.getParent()).getArgumentList(); + } + else if (ref.getParent() instanceof PsiAnonymousClass) { + argumentList = ((PsiConstructorCall)ref.getParent().getParent()).getArgumentList(); + } + else { + continue; + } + PsiExpression[] args = argumentList.getExpressions(); + if (index >= args.length) continue; + addLink(type, args[index]); + } + } + + final class Inner { + void linkInheritors(final PsiMethod[] methods) { + for (int i = 0; i < methods.length; i++) { + final PsiMethod superMethod = methods[i]; + final PsiParameter[] parameters = superMethod.getParameterList().getParameters(); + if (index >= parameters.length) continue; + final PsiTypeElement superType = parameters[index].getTypeElement(); + addLink(superType, type); + addLink(type, superType); + } + } + }; + + final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method); + new Inner().linkInheritors(superMethods); + final PsiClass[] subClasses = mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false); + // ??? In the theory this is non-efficient way: too many inheritors can be processed. + // ??? But in real use it seems reasonably fast. If poor performance problems emerged, + // ??? should be optimized + for (int i1 = 0; i1 != subClasses.length; ++ i1) { + final PsiMethod[] mBSs = subClasses [i1].findMethodsBySignature(method, true); + new Inner().linkInheritors(mBSs); + } + } + else { + LOG.assertTrue(false); + } + } + } + + private void processMethodReturnType(final PsiMethod method) { + final PsiTypeElement returnType = method.getReturnTypeElement(); + final PsiReference[] calls = mySearchHelper.findReferences(method, GlobalSearchScope.projectScope(myProject), false); + for (int i = 0; i < calls.length; i++) { + final PsiElement ref = calls[i].getElement(); + if (PsiTreeUtil.getParentOfType(ref, PsiDocComment.class) != null) continue; + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)ref.getParent(); + addLink(methodCall, returnType); + } + + final PsiReturnStatement[] returnStatements = RefactoringUtil.findReturnStatements(method); + for (int idx = 0; idx < returnStatements.length; idx++) { + final PsiReturnStatement returnStatement = returnStatements[idx]; + final PsiExpression returnValue = returnStatement.getReturnValue(); + if (returnValue != null) { + addLink(returnType, returnValue); + } + } + + final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method); + final class Inner { + public void linkInheritors(final PsiMethod[] methods) { + for (int i = 0; i < methods.length; i++) { + final PsiMethod superMethod = methods[i]; + final PsiTypeElement superType = superMethod.getReturnTypeElement(); + addLink(superType, returnType); + addLink(returnType, superType); + } + } + }; + new Inner().linkInheritors(superMethods); + // ??? In the theory this is non-efficient way: too many inheritors can be processed (and multiple times). + // ??? But in real use it seems reasonably fast. If poor performance problems emerged, + // ??? should be optimized + final PsiClass[] subClasses = mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false); + for (int i1 = 0; i1 != subClasses.length; ++ i1) { + final PsiMethod[] mBSs = subClasses [i1].findMethodsBySignature(method, true); + new Inner ().linkInheritors(mBSs); + } + } + + private void processQueue() { + while (!myExpressionsQueue.isEmpty()) { + PsiExpression expr = myExpressionsQueue.pullFirst(); + PsiElement parent = expr.getParent(); + if (parent instanceof PsiAssignmentExpression) { + PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent; + if (assignment.getRExpression() != null) { + addLink(assignment.getLExpression(), assignment.getRExpression()); + } + addLink(assignment, assignment.getLExpression()); + addLink(assignment.getLExpression(), assignment); + } + else if (parent instanceof PsiArrayAccessExpression) { + PsiArrayAccessExpression arrayAccess = (PsiArrayAccessExpression)parent; + if (expr.equals(arrayAccess.getArrayExpression())) { + addLink(arrayAccess, expr); + addLink(expr, arrayAccess); + } + } + else if (parent instanceof PsiParenthesizedExpression) { + addLink(parent, expr); + addLink(expr, parent); + } + else if (parent instanceof PsiArrayInitializerExpression) { + PsiArrayInitializerExpression arrayInitializerExpr = (PsiArrayInitializerExpression)parent; + PsiExpression[] initializers = arrayInitializerExpr.getInitializers(); + for (int idx = 0; idx < initializers.length; idx++) { + addLink(arrayInitializerExpr, initializers[idx]); + } + } + else if (parent instanceof PsiExpressionList) { + PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiCallExpression) { + PsiMethod method = ((PsiCallExpression)pparent).resolveMethod(); + if (method != null) { + addArgumentParameterLink(expr, (PsiExpressionList)parent, method); + } + } + } + } + } + + protected void markNodes() { + //for (Iterator iterator = myDependencyMap.keySet().iterator(); iterator.hasNext();) { + for (Iterator iterator = myElementToNode.keySet().iterator(); iterator.hasNext();) { + final PsiElement element = iterator.next(); + if (element instanceof PsiExpression) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiReferenceExpression) { + final PsiReferenceExpression refExpr = (PsiReferenceExpression)parent; + if (element.equals(refExpr.getQualifierExpression())) { + final PsiElement refElement = refExpr.resolve(); + if (refElement != null && !isInSuper(refElement)) { + markNode(element); + } + } + } + } + else if (!myReplaceInstanceOf && element.getParent() != null + && element.getParent().getParent() instanceof PsiInstanceOfExpression) { + markNode(element); + } + else if (element.getParent() instanceof PsiClassObjectAccessExpression) { + markNode(element); + } + else if (element instanceof PsiParameter) { + final PsiType type = ((PsiParameter)element).getType(); + final PsiClass aClass = PsiUtil.resolveClassInType(type); + if (aClass != null) { + if (!myManager.isInProject(element) || !myManager.areElementsEquivalent(aClass, myClass)) { + if (!isSuperInheritor(aClass)) { + markNode(element); + } + } + } + else { // unresolvable class + markNode(element); + } + } + } + } + + protected abstract boolean isSuperInheritor(PsiClass aClass); + + protected abstract boolean isInSuper(PsiElement member); + + protected void addLink(PsiElement source, PsiElement target) { + Node from = myElementToNode.get(source); + Node to = myElementToNode.get(target); + + if (from == null) { + from = new Node(source); + if (source instanceof PsiExpression) myExpressionsQueue.addLast((PsiExpression)source); + myElementToNode.put(source, from); + } + + if (to == null) { + to = new Node(target); + if (target instanceof PsiExpression) myExpressionsQueue.addLast((PsiExpression)target); + myElementToNode.put(target, to); + } + + Edge.connect(from, to); + } + + private void spreadMarks() { + final LinkedList markedNodes = new LinkedList(); + + for (Iterator i = myMarkedNodes.iterator(); i.hasNext();) { + final Node node = myElementToNode.get(i.next()); + if (node != null) markedNodes.addFirst(node); + } + + GlobalAnalyzer.doOneEnd(markedNodes, new Colorer()); + } + + private void markNode(final PsiElement node) { + myMarkedNodes.add(node); + } + + class Colorer implements OneEndFunctor { + public Mark compute(Mark from, Mark edge, Mark to) { + VisitMark mark = new VisitMark((VisitMark)to); + + myMarkedNodes.add(mark.getElement()); + mark.switchOn(); + + return mark; + } + } + + private static class Edge extends EdgeImpl { + private Edge(Node from, Node to) { + super(from, to); + } + + public static boolean connect(Node from, Node to) { + if (from.mySuccessors.add(to)) { + new Edge(from, to); + return true; + } + + return false; + } + } + + private static class VisitMark implements Mark { + private boolean myVisited; + private PsiElement myElement; + + public boolean coincidesWith(Mark x) { + return ((VisitMark)x).myVisited == myVisited; + } + + public VisitMark(VisitMark m) { + myVisited = false; + myElement = m.myElement; + } + + public VisitMark(PsiElement e) { + myVisited = false; + myElement = e; + } + + public void switchOn() { + myVisited = true; + } + + public void switchOff() { + myVisited = false; + } + + public PsiElement getElement() { + return myElement; + } + } + + private static class Node extends NodeImpl { + private HashSet mySuccessors = new HashSet(); + private VisitMark myMark; + + public Node(PsiElement x) { + super(); + myMark = new VisitMark(x); + } + + public Mark getMark() { + return myMark; + } + + public void setMark(Mark x) { + myMark = (VisitMark)x; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnToSuperReferenceUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnToSuperReferenceUsageInfo.java new file mode 100644 index 00000000000..33d29e902b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/turnRefsToSuper/TurnToSuperReferenceUsageInfo.java @@ -0,0 +1,13 @@ +package com.intellij.refactoring.turnRefsToSuper; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class TurnToSuperReferenceUsageInfo extends UsageInfo { + public TurnToSuperReferenceUsageInfo(PsiElement element) { + super(element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Bottom.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Bottom.java new file mode 100644 index 00000000000..26e27f3eb44 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Bottom.java @@ -0,0 +1,60 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeVisitor; +import com.intellij.psi.search.GlobalSearchScope; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 18.12.2003 + * Time: 18:55:48 + * To change this template use Options | File Templates. + */ +public class Bottom extends PsiType { + public final static Bottom BOTTOM = new Bottom(); + + private Bottom() { + + } + + public String getPresentableText() { + return "_"; + } + + public String getCanonicalText() { + return "_"; + } + + public String getInternalCanonicalText() { + return getCanonicalText(); + } + + public boolean isValid() { + return true; + } + + public boolean equalsToText(String text) { + return text.equals("_"); + } + + public boolean equals(Object o) { + if (o instanceof Bottom) { + return true; + } + + return false; + } + + public
    A accept(PsiTypeVisitor visitor) { + return null; + } + + public PsiType[] getSuperTypes() { + throw new UnsupportedOperationException(); + } + + public GlobalSearchScope getResolveScope() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Settings.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Settings.java new file mode 100644 index 00000000000..eabf8e29f73 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Settings.java @@ -0,0 +1,14 @@ +package com.intellij.refactoring.typeCook; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 30.12.2003 + * Time: 19:25:26 + * To change this template use Options | File Templates. + */ +public interface Settings { + boolean dropObsoleteCasts(); + boolean preserveRawArrays(); + boolean leaveObjectParameterizedTypesRaw(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookDialog.java new file mode 100644 index 00000000000..99d8747c62d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookDialog.java @@ -0,0 +1,161 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.help.HelpManager; +import com.intellij.psi.*; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.RefactoringDialog; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.*; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 30.07.2003 + * Time: 21:36:29 + * To change this template use Options | File Templates. + */ +public class TypeCookDialog extends RefactoringDialog { + + public static final String REFACTORING_NAME = "Generify"; + + public static interface Callback { + void run(TypeCookDialog dialog); + } + + private final Callback myCallback; + private JLabel myClassNameLabel = new JLabel(); + private JCheckBox myCbDropCasts = new JCheckBox("Drop obsolete casts"); + private JCheckBox myCbPreserveRawArrays = new JCheckBox("Preserve raw arrays"); + private JCheckBox myCbLeaveObjectParameterizedTypesRaw = new JCheckBox("Leave Object-parameterized types raw"); + + public TypeCookDialog(Project project, PsiElement[] elements, Callback callback) { + super(project, true); + + myCallback = callback; + + setTitle(REFACTORING_NAME); + + init(); + + StringBuffer name = new StringBuffer(""); + + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + + if (element instanceof PsiClass) { + name.append("Class " + ((PsiClass)element).getQualifiedName()); + } + else if (element instanceof PsiFile) { + name.append("File " + ((PsiFile)element).getName()); + } + else if (element instanceof PsiDirectory) { + name.append("Directory " + ((PsiDirectory)element).getName()); + } + else if (element instanceof PsiPackage) { + name.append("Package " + ((PsiPackage)element).getQualifiedName()); + } + + if (i < elements.length - 1) { + name.append("
    "); + } + } + + name.append(""); + + myClassNameLabel.setText(name.toString()); + } + + protected JComponent createCenterPanel() { + return null; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(HelpID.TYPE_COOK); + } + + protected JComponent createNorthPanel() { + JPanel optionsPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + + optionsPanel.setBorder(IdeBorderFactory.createBorder()); + + if (myCbDropCasts.isEnabled()) { + myCbDropCasts.setSelected(RefactoringSettings.getInstance().TYPE_COOK_DROP_CASTS); + } + + if (myCbPreserveRawArrays.isEnabled()) { + myCbPreserveRawArrays.setSelected(RefactoringSettings.getInstance().TYPE_COOK_PRESERVE_RAW_ARRAYS); + } + + if (myCbLeaveObjectParameterizedTypesRaw.isEnabled()) { + myCbLeaveObjectParameterizedTypesRaw.setSelected( + RefactoringSettings.getInstance().TYPE_COOK_LEAVE_OBJECT_PARAMETERIZED_TYPES_RAW); + } + + myCbDropCasts.setMnemonic('D'); + myCbPreserveRawArrays.setMnemonic('P'); + myCbLeaveObjectParameterizedTypesRaw.setMnemonic('L'); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + + gbConstraints.weighty = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + optionsPanel.add(myClassNameLabel, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = 1; + gbConstraints.fill = GridBagConstraints.BOTH; + optionsPanel.add(myCbDropCasts, gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.BOTH; + optionsPanel.add(myCbPreserveRawArrays, gbConstraints); + + gbConstraints.gridx = 0; + gbConstraints.gridwidth = 2; + optionsPanel.add(myCbLeaveObjectParameterizedTypesRaw, gbConstraints); + + return optionsPanel; + } + + protected void doAction() { + myCallback.run(this); + + RefactoringSettings settings = RefactoringSettings.getInstance(); + + settings.TYPE_COOK_DROP_CASTS = myCbDropCasts.isSelected(); + settings.TYPE_COOK_PRESERVE_RAW_ARRAYS = myCbPreserveRawArrays.isSelected(); + settings.TYPE_COOK_LEAVE_OBJECT_PARAMETERIZED_TYPES_RAW = myCbLeaveObjectParameterizedTypesRaw.isSelected(); + } + + public Settings getSettings() { + final boolean dropCasts = myCbDropCasts.isSelected(); + final boolean preserveRawArrays = true; //myCbPreserveRawArrays.isSelected(); + final boolean leaveObjectParameterizedTypesRaw = myCbLeaveObjectParameterizedTypesRaw.isSelected(); + + return new Settings() { + public boolean dropObsoleteCasts() { + return dropCasts; + } + + public boolean preserveRawArrays() { + return preserveRawArrays; + } + + public boolean leaveObjectParameterizedTypesRaw() { + return leaveObjectParameterizedTypesRaw; + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookHandler.java new file mode 100644 index 00000000000..367e75f018d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookHandler.java @@ -0,0 +1,41 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; + +public class TypeCookHandler implements RefactoringActionHandler { + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + invoke(project, new PsiElement[]{file}, dataContext); + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + if (elements == null || elements.length == 0) { + return; + } + + for (int i = 0; i < elements.length; i++) { + if (!canCook(elements[i], project)) { + return; + } + } + + TypeCookDialog dialog = new TypeCookDialog(project, elements, new TypeCookProcessor(project, elements)); + dialog.show(); + } + + private boolean canCook(PsiElement element, Project project) { + + if (!element.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, element); + return false; + } + + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookProcessor.java new file mode 100644 index 00000000000..364f77442d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookProcessor.java @@ -0,0 +1,101 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.openapi.command.undo.DummyComplexUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +import java.util.*; + +public class TypeCookProcessor extends BaseRefactoringProcessor implements TypeCookDialog.Callback { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.TypeCookProcessor"); + + private PsiElement[] myElements; + private Kitchen myKitchen; + private TypeCookDialog myDialog; + + public TypeCookProcessor(Project project, PsiElement[] elements) { + super(project); + + myElements = elements; + myKitchen = new Kitchen(PsiManager.getInstance(project)); + } + + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + return new TypeCookViewDescriptor(myElements, usages, refreshCommand); + } + + protected UsageInfo[] findUsages() { + HashSet victims = myKitchen.getVictims(myElements, myDialog.getSettings()); + + UsageInfo[] usages = new UsageInfo[victims.size()]; + int i = 0; + + for (Iterator j = victims.iterator(); j.hasNext(); i++) { + final PsiElement element = j.next(); + usages[i] = new UsageInfo(element){ + public String getTooltipText() { + return myKitchen.getCookedType(element).getCanonicalText(); + } + }; + } + + return usages; + } + + protected void refreshElements(PsiElement[] elements) { + myElements = elements; + } + + protected boolean isPreviewUsages(UsageInfo[] usages) { + boolean toPreview = myDialog.isPreviewUsages(); + + if (UsageViewUtil.hasReadOnlyUsages(usages)) { + toPreview = true; + WindowManager.getInstance().getStatusBar(myProject).setInfo("Occurrences found in read-only files"); + } + + return toPreview; + } + + protected void performRefactoring(UsageInfo[] usages) { + HashSet victims = new HashSet(); + + for (int i = 0; i < usages.length; i++) + victims.add(usages[i].getElement()); + + myKitchen.perform(victims); + + UndoManager.getInstance(myProject).undoableActionPerformed(new DummyComplexUndoableAction()); // force confirmation dialog for undo + } + + protected String getCommandName() { + return "Generify"; + } + + public void run(TypeCookDialog dialog) { + myDialog = dialog; + + final Runnable runnable = new Runnable() { + public void run() { + myDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + } + }; + + setPrepareSuccessfulSwingThreadCallback(runnable); + run((Object) null); + } + + public List getElements() { + return Collections.unmodifiableList(Arrays.asList(myElements)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookViewDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookViewDescriptor.java new file mode 100644 index 00000000000..a906b2806c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/TypeCookViewDescriptor.java @@ -0,0 +1,88 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +class TypeCookViewDescriptor implements UsageViewDescriptor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.TypeCookViewDescriptor"); + + private PsiElement[] myElements; + private UsageInfo[] myUsages; + private FindUsagesCommand myRefreshCommand; + + public TypeCookViewDescriptor(PsiElement[] elements, UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myElements = elements; + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + public PsiElement[] getElements() { + return myElements; + } + + public UsageInfo[] getUsages() { + return myUsages; + } + + public void refresh(PsiElement[] elements) { + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + public String getProcessedElementsHeader() { + return "Scope(s) to generify"; + } + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord() { + return REFERENCE_WORD; + } + + public String getCommentReferencesWord() { + return null; + } + + public boolean cancelAvailable() { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "Declaration(s) to be generified " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public boolean canFilterMethods() { + return true; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Util.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Util.java new file mode 100644 index 00000000000..e2563336c43 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/Util.java @@ -0,0 +1,741 @@ +package com.intellij.refactoring.typeCook; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.refactoring.typeCook.deductive.PsiTypeIntersection; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 30.07.2003 + * Time: 18:57:30 + * To change this template use Options | File Templates. + */ +public class Util { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.Util"); + + private static final int HEIGHT_BOUND = 6; + + public static int getArrayLevel(PsiType t) { + if (t instanceof PsiArrayType) { + return 1 + getArrayLevel(((PsiArrayType)t).getComponentType()); + } + + return 0; + } + + public static PsiType createArrayType(PsiType theType, int level) { + while (level-- > 0) { + theType = theType.createArrayType(); + } + + return theType; + } + + public static PsiClassType.ClassResolveResult resolveType(PsiType type) { + type = avoidAnonymous(type); + + if (type == null) { + return PsiClassType.ClassResolveResult.EMPTY; + } + + if (type instanceof PsiClassType) { + return ((PsiClassType)type).resolveGenerics(); + } + else if (type instanceof PsiArrayType) { + return resolveType(((PsiArrayType)type).getComponentType()); + } + else if (type instanceof SubtypeOf) { + return resolveType(((SubtypeOf)type).getSuperType()); + } + else if (type instanceof SupertypeOf) { + return resolveType(((SupertypeOf)type).getSubType()); + } + else { + return PsiClassType.ClassResolveResult.EMPTY; + } + } + + public static PsiElement getParentElement(PsiElement element) { + PsiElement parent = element; + + while ((parent = parent.getParent()) instanceof PsiParenthesizedExpression) ; + + return parent; + } + + public static boolean isSonOfReferenceExpression(PsiElement he) { + PsiElement wormlet = he; + + while ((wormlet = wormlet.getParent()) instanceof PsiParenthesizedExpression) ; + + return wormlet instanceof PsiReferenceExpression; + } + + public static PsiType normalize(PsiType t, boolean objectBottom) { + if (t instanceof SubtypeOf) { + return normalize(((SubtypeOf)t).getSuperType(), objectBottom); + } + else if (t instanceof SupertypeOf) { + return normalize(((SupertypeOf)t).getSubType(), objectBottom); + } + else if (t instanceof PsiArrayType) { + PsiType normType = normalize(((PsiArrayType)t).getComponentType(), objectBottom); + + return normType == null ? null : normType.createArrayType(); + } + else if (t instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = resolveType(t); + + if (result == null) { + return null; + } + + PsiClass aclass = result.getElement(); + PsiSubstitutor subst = result.getSubstitutor(); + PsiManager manager = aclass.getManager(); + + if (aclass.hasTypeParameters()) { + PsiTypeParameter[] parms = getTypeParametersList(aclass); + PsiSubstitutor newbst = PsiSubstitutor.EMPTY; + + boolean anyBottom = false; + + for (int i = 0; i < parms.length; i++) { + PsiType p = subst.substitute(parms[i]); + + if (p != null) { + PsiType pp = normalize(p, objectBottom); + + if (pp == null) { + return null; + } + + if (pp == Bottom.BOTTOM || (objectBottom && pp.getCanonicalText().equals("java.lang.Object"))) { + anyBottom = true; + } + + newbst = newbst.put(parms[i], pp); + } + else { + anyBottom = true; + } + } + + if (anyBottom || newbst == PsiSubstitutor.EMPTY) { + newbst = manager.getElementFactory().createRawSubstitutor(aclass); + } + + return manager.getElementFactory().createType(aclass, newbst); + } + + return manager.getElementFactory().createType(aclass); + } + else { + return t; + } + } + + public static boolean hasNoParameters(PsiType t) { + if (t instanceof PsiClassType) { + PsiClassType.ClassResolveResult resolveResult = resolveType(t); + + if (resolveResult == null) { + return true; + } + + if (PsiClassType.isRaw(resolveResult)) { + return true; + } + + PsiSubstitutor subst = resolveResult.getSubstitutor(); + PsiClass element = resolveResult.getElement(); + + if (element instanceof PsiTypeParameter) { + return false; + } + + PsiTypeParameter[] parameters = getTypeParametersList(element); + + for (int i = 0; i < parameters.length; i++) { + PsiType actual = subst.substitute(parameters[i]); + if (hasNoParameters(actual)) { + return true; + } + } + } + else if (t instanceof PsiArrayType) { + return hasNoParameters(((PsiArrayType)t).getComponentType()); + } + + return false; + } + + public static boolean isRaw(PsiType t) { + return isRaw(t, true); + } + + public static boolean isRaw(PsiType t, boolean arrays) { + if (t instanceof PsiClassType) { + final PsiClassType.ClassResolveResult resolveResult = resolveType(t); + + if (resolveResult.getElement() == null) { + return false; + } + + if (PsiClassType.isRaw(resolveResult)) { + return true; + } + + final PsiSubstitutor subst = resolveResult.getSubstitutor(); + final PsiClass element = resolveResult.getElement(); + + final PsiTypeParameter[] parameters = getTypeParametersList(element); + + for (int i = 0; i < parameters.length; i++) { + final PsiType actual = subst.substitute(parameters[i]); + if (!(actual instanceof PsiTypeParameter) && isRaw(actual, arrays)) return true; + } + + return false; + } + else if (t instanceof PsiArrayType) { + return arrays ? false : isRaw(((PsiArrayType)t).getComponentType(), arrays); + } + + return false; + } + + public static boolean isTypeParameter(PsiType t) { + + PsiClassType.ClassResolveResult result = resolveType(t); + + if (result == null) { + return false; + } + + return result.getElement() instanceof PsiTypeParameter; + } + + public static PsiType banalize(PsiType t) { + if (t instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = resolveType(t); + + if (result == null) { + return null; + } + + PsiClass theClass = result.getElement(); + PsiSubstitutor theSubst = result.getSubstitutor(); + PsiManager theManager = theClass.getManager(); + + PsiTypeParameter[] theParms = Util.getTypeParametersList(theClass); + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + + for (int i = 0; i < theParms.length; i++) { + PsiTypeParameter theParm = theParms[i]; + + PsiType actualType = theSubst.substitute(theParm); + + if (actualType == null || actualType instanceof PsiWildcardType) {// || isTypeParameter(actualType)) { + subst = subst.put(theParm, Bottom.BOTTOM); + } + else { + PsiType banType = banalize(actualType); + + if (banType == null) { + return null; + } + + subst = subst.put(theParm, banType); + } + } + + return theManager.getElementFactory().createType(theClass, subst); + } + + return t; + } + + public static PsiSubstitutor composeSubstitutors(PsiSubstitutor f, PsiSubstitutor g) { + if (f == PsiSubstitutor.EMPTY) { + return g; + } + + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + Set base = g.getSubstitutionMap().keySet(); + + for (Iterator i = base.iterator(); i.hasNext();) { + PsiTypeParameter p = i.next(); + PsiType type = g.substitute(p); + subst = subst.put(p, type == null ? null : f.substitute(type)); + } + + return subst; + } + + public static boolean bindsTypeParameters(PsiSubstitutor theSubst, HashSet params) { + Collection values = theSubst.getSubstitutionMap().values(); + + for (Iterator i = values.iterator(); i.hasNext();) { + PsiType type = i.next(); + PsiClassType.ClassResolveResult result = Util.resolveType(type); + + if (result == null) { + return false; + } + + PsiClass aClass = result.getElement(); + + if (aClass instanceof PsiTypeParameter) { + return params.contains(aClass); + } + else { + if (bindsTypeParameters(result.getSubstitutor(), params)) { + return true; + } + } + } + + return false; + } + + public static boolean bindsTypeParameters(PsiType t, HashSet params) { + if (t instanceof PsiWildcardType) { + final PsiWildcardType wct = ((PsiWildcardType)t); + final PsiType bound = wct.getBound(); + + if (bound != null && wct.isExtends()) { + return bindsTypeParameters(bound, params); + } + + return false; + } + + PsiClassType.ClassResolveResult result = Util.resolveType(t); + + if (result == null) { + return false; + } + + PsiClass theClass = result.getElement(); + PsiSubstitutor theSubst = result.getSubstitutor(); + + if (theClass == null) { + return false; + } + + if (theClass instanceof PsiTypeParameter) { + return params == null || params.contains(theClass); + } + else if (theClass.hasTypeParameters()) { + PsiTypeParameter[] parms = Util.getTypeParametersList(theClass); + + for (int i = 0; i < parms.length; i++) { + PsiType bound = theSubst.substitute(parms[i]); + + if (bound != null && bindsTypeParameters(bound, params)) { + return true; + } + } + } + + return false; + } + + public static boolean bindsTypeParameters(PsiType t) { + return bindsTypeParameters(t, null); + } + + public static PsiSubstitutor createIdentitySubstitutor(PsiTypeParameterList p) { + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + PsiTypeParameter[] parms = p.getTypeParameters(); + + for (int i = 0; i < parms.length; i++) { + PsiTypeParameter pp = parms[i]; + subst = subst.put(pp, pp.getManager().getElementFactory().createType(pp)); + } + + return subst; + } + + public static PsiSubstitutor createIdentitySubstitutor(Set params) { + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + + for (Iterator i = params.iterator(); i.hasNext();) { + PsiTypeParameter p = i.next(); + subst = subst.put(p, p.getManager().getElementFactory().createType(p)); + } + + return subst; + } + + public static PsiType getNCA(PsiClass aClass, PsiClass bClass) { + if (InheritanceUtil.isCorrectDescendant(aClass, bClass, true)) { + return aClass.getManager().getElementFactory() + .createType(bClass); + } + if (InheritanceUtil.isCorrectDescendant(bClass, aClass, true)) { + return aClass.getManager().getElementFactory() + .createType(aClass); + } + ; + + return PsiType.getJavaLangObject(aClass.getManager()); + } + + public static PsiType cloneType(PsiType t, PsiManager manager) { + return manager.getElementFactory().detachType(t); + } + + public static TypeNode killOthers(TypeNode baseNode, + TypeNode objectNode, + PsiClass mainClass, + HashSet boundParameters) { + if (!mainClass.hasTypeParameters()) { + return baseNode; + } + + PsiTypeParameter[] mainParms = getTypeParametersList(mainClass); + + for (int i = 0; i < mainParms.length; i++) { + PsiTypeParameter p = mainParms[i]; + + if (!boundParameters.contains(p)) { + TypeEdge.connectParameter(baseNode, objectNode, p.getIndex()); + } + } + + return baseNode; + } + + public static PsiType getType(PsiElement element) { + if (element instanceof PsiVariable) { + return ((PsiVariable)element).getType(); + } + else if (element instanceof PsiExpression) { + return ((PsiExpression)element).getType(); + } + else if (element instanceof PsiMethod) { + return ((PsiMethod)element).getReturnType(); + } + + return null; + } + + public static boolean equals(PsiClass a, PsiClass b) { + if (a.getManager().areElementsEquivalent(a, b)) { + return getTypeParametersList(a).length == getTypeParametersList(b).length; + } + + return false; + } + + private static boolean clashes(PsiClass a, PsiClass b) { + return + a.getManager().areElementsEquivalent(a, b) && + (getTypeParametersList(a).length != getTypeParametersList(b).length); + } + + public static boolean isDescendant(PsiClass a, PsiClass b) { + boolean semi = InheritanceUtil.isCorrectDescendant(a, b, true); + + if (semi && clashes(a, b)) { + return false; + } + + return semi; + } + + public static int getTypeKind(PsiType t) { + if (t instanceof PsiClassType) return 0; + if (t instanceof PsiArrayType) return 1; + if (t instanceof SupertypeOf) return 2; + if (t instanceof SubtypeOf) return 3; + if (t instanceof Bottom) return 4; + + LOG.error("Class/Array/Super/Sub-type expected in getTypeKind."); + + return 5; // PsiPrimitiveType + } + + public static PsiType balanceSubtype(PsiClass aClass, PsiClass bClass, PsiSubstitutor aSubst) { + PsiSubstitutor subSubst = TypeConversionUtil.getClassSubstitutor(bClass, aClass, PsiSubstitutor.EMPTY); + PsiSubstitutor theSubst = Util.composeSubstitutors(aSubst, subSubst); + + return aClass.getManager().getElementFactory().createType(bClass, theSubst); + } + + public static PsiTypeParameter[] getTypeParametersList(PsiClass a) { + PsiTypeParameterList list = a.getTypeParameterList(); + + if (list == null) { + return PsiTypeParameter.EMPTY_ARRAY; + } + else { + return list.getTypeParameters(); + } + } + + public static boolean isGeneric(PsiType a) { + if (a instanceof PsiArrayType) { + return isGeneric(((PsiArrayType)a).getDeepComponentType()); + } + + if (a instanceof SubtypeOf) { + return isGeneric(((SubtypeOf)a).getSuperType()); + } + + if (a instanceof SupertypeOf) { + return isGeneric(((SupertypeOf)a).getSubType()); + } + + if (a instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = resolveType(a); + + if (result == null) { + return false; + } + + PsiClass aClass = result.getElement(); + + return aClass != null && aClass.hasTypeParameters(); + } + + return a == Bottom.BOTTOM; + } + + public static PsiType undress(PsiType t) { + if (t instanceof SupertypeOf) { + return undress(((SupertypeOf)t).getSubType()); + } + + if (t instanceof SubtypeOf) { + return undress(((SubtypeOf)t).getSuperType()); + } + + return t; + } + + public static PsiType avoidAnonymous(PsiType type) { + if (type instanceof PsiClassType) { + final PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics(); + final PsiClass aClass = result.getElement(); + + if (result.getElement() == null) { + return null; + } + + if (aClass instanceof PsiAnonymousClass) { + return aClass.getSuperTypes()[0]; + } + + final PsiSubstitutor aSubst = result.getSubstitutor(); + + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (Iterator i = aSubst.getSubstitutionMap().keySet().iterator(); i.hasNext();) { + final PsiTypeParameter p = i.next(); + PsiType t = aSubst.substitute(p); + + if (t != null) { + t = avoidAnonymous(t); + } + + theSubst = theSubst.put(p, t); + } + + return aClass.getManager().getElementFactory().createType(aClass, theSubst); + } + else if (type instanceof PsiArrayType) { + PsiType avoided = avoidAnonymous(((PsiArrayType)type).getComponentType()); + + return avoided == null ? null : avoided.createArrayType(); + } + + return type; + } + + private static boolean isValidType(PsiType type, PsiElement context) { + if (type instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = resolveType(type); + + if (result == null) { + return false; + } + + PsiClass aClass = result.getElement(); + PsiSubstitutor aSubst = result.getSubstitutor(); + + if (!PsiUtil.isAccessible(aClass, context, null)) { + return false; + } + + PsiTypeParameter[] aParms = getTypeParametersList(aClass); + + for (int i = 0; i < aParms.length; i++) { + if (!isValidType(aSubst.substitute(aParms[i]), context)) { + return false; + } + } + + return true; + } + + if (type instanceof PsiArrayType) { + return isValidType(((PsiArrayType)type).getComponentType(), context); + } + + return true; + } + + public static boolean isValidTypeInContext(PsiType type, PsiElement context) { + try { + return isValidType(context.getManager().getElementFactory().createTypeFromText(type.getCanonicalText(), context), + context); + } + catch (IncorrectOperationException e) { + LOG.error("Incorrect operation during factory.createTypeFromText"); + } + + return false; + } + + private static int getHeight(PsiType t) { + if (t instanceof PsiClassType) { + PsiClassType.ClassResolveResult result = ((PsiClassType)t).resolveGenerics(); + PsiClass aClass = result.getElement(); + PsiSubstitutor aSubst = result.getSubstitutor(); + + if (aClass == null) { + return 0; + } + + PsiTypeParameter[] parms = getTypeParametersList(aClass); + + int max = 0; + + for (int i = 0; i < parms.length; i++) { + max = Math.max(max, getHeight(aSubst.substitute(parms[i]))); + if (max > HEIGHT_BOUND) { + break; + } + } + + return 1 + max; + } + else if (t instanceof PsiArrayType) { + return getHeight(((PsiArrayType)t).getDeepComponentType()); + } + else if (t instanceof SubtypeOf) { + return getHeight(((SubtypeOf)t).getSuperType()); + } + else if (t instanceof SupertypeOf) { + return getHeight(((SupertypeOf)t).getSubType()); + } + + return 0; + } + + public static boolean prunedType(PsiType t) { + return getHeight(t) > HEIGHT_BOUND; + } + + public static PsiType createParameterizedType(final PsiType t, final PsiTypeVariableFactory factory) { + if (t == null) { + return factory.create(); + } + + if (t instanceof PsiClassType) { + final PsiClassType.ClassResolveResult result = resolveType(t); + final PsiSubstitutor aSubst = result.getSubstitutor(); + final PsiClass aClass = result.getElement(); + + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (Iterator i = aSubst.getSubstitutionMap().keySet().iterator(); i.hasNext();) { + final PsiTypeParameter parm = i.next(); + theSubst = theSubst.put(parm, createParameterizedType(aSubst.substitute(parm), factory)); + } + + return aClass.getManager().getElementFactory().createType(aClass, theSubst); + } + else if (t instanceof PsiArrayType) { + return createParameterizedType(((PsiArrayType)t).getComponentType(), factory).createArrayType(); + } + + return t; + } + + public static PsiType substituteType(final PsiType type, final PsiSubstitutor subst) { + final int level = getArrayLevel(type); + final PsiClassType.ClassResolveResult result = resolveType(type); + + if (result.getElement() != null) { + final PsiClass aClass = result.getElement(); + final PsiSubstitutor aSubst = result.getSubstitutor(); + final PsiManager manager = aClass.getManager(); + + if (aClass instanceof PsiTypeParameter) { + final PsiType sType = subst.substitute(((PsiTypeParameter)aClass)); + + return createArrayType(sType == null ? PsiType.getJavaLangObject(manager): sType, level); + } + + final PsiTypeParameter[] aParms = getTypeParametersList(aClass); + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (int i = 0; i < aParms.length; i++) { + PsiTypeParameter aParm = aParms[i]; + + theSubst = theSubst.put(aParm, substituteType(aSubst.substitute(aParm), subst)); + } + + return createArrayType(aClass.getManager().getElementFactory().createType(aClass, theSubst), level); + } + + return createArrayType(type, level); + } + + public static boolean bindsTypeVariables(final PsiType t) { + if (t == null){ + return false; + } + + if (t instanceof PsiTypeVariable) { + return true; + } + + if (t instanceof PsiTypeIntersection){ + final PsiTypeIntersection itype = ((PsiTypeIntersection)t); + + return bindsTypeVariables(itype.getLeft()) || bindsTypeVariables(itype.getRight()); + } + + final PsiClassType.ClassResolveResult result = resolveType(t); + + if (result.getElement() != null) { + final PsiSubstitutor subst = result.getSubstitutor(); + + for (Iterator types = subst.getSubstitutionMap().values().iterator(); types.hasNext();) { + if (bindsTypeVariables(types.next())) { + return true; + } + } + } + + return false; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java new file mode 100644 index 00000000000..579c125cc87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java @@ -0,0 +1,14 @@ +package com.intellij.refactoring.typeCook.deductive; + +import com.intellij.psi.PsiTypeVisitor; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Dec 27, 2004 + * Time: 7:20:09 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class PsiExtendedTypeVisitor extends PsiTypeVisitor { + public abstract X visitTypeVariable(PsiTypeVariable var); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java new file mode 100644 index 00000000000..afd9fe3ff0e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java @@ -0,0 +1,81 @@ +package com.intellij.refactoring.typeCook.deductive; + +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeVisitor; +import com.intellij.psi.search.GlobalSearchScope; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jan 12, 2005 + * Time: 9:41:45 PM + * To change this template use File | Settings | File Templates. + */ +public class PsiTypeVariableFactory { + private int myCurrent = 0; + + public final int getNumber() { + return myCurrent; + } + + public final PsiTypeVariable create(){ + return new PsiTypeVariable (){ + private int myIndex = myCurrent++; + + public String getPresentableText() { + return "$" + myIndex; + } + + public String getCanonicalText() { + return getPresentableText(); + } + + public String getInternalCanonicalText() { + return getCanonicalText(); + } + + public boolean isValid() { + return true; + } + + public boolean equalsToText(String text) { + return text.equals(getPresentableText()); + } + + public
    A accept(PsiTypeVisitor visitor) { + if (visitor instanceof PsiExtendedTypeVisitor) { + return ((PsiExtendedTypeVisitor)visitor).visitTypeVariable(this); + } + + return null; + } + + public GlobalSearchScope getResolveScope() { + return null; + } + + public PsiType[] getSuperTypes() { + return new PsiType[0]; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PsiTypeVariable)) return false; + + final PsiTypeVariable psiTypeVariable = (PsiTypeVariable)o; + + if (myIndex != psiTypeVariable.getIndex()) return false; + + return true; + } + + public int hashCode() { + return myIndex; + } + + public int getIndex() { + return myIndex; + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java new file mode 100644 index 00000000000..db5334d3596 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java @@ -0,0 +1,64 @@ +package com.intellij.refactoring.typeCook.deductive.builder; + +import com.intellij.psi.PsiType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.refactoring.typeCook.deductive.resolver.Binding; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jul 20, 2004 + * Time: 6:00:28 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class Constraint { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.builder.Constraint"); + + PsiType myLeft; + PsiType myRight; + + public Constraint(PsiType left, PsiType right) { + LOG.assertTrue(left != null, " left type"); + LOG.assertTrue(right != null, " right type"); + + myLeft = left; + myRight = right; + } + + public PsiType getRight() { + return myRight; + } + + public PsiType getLeft() { + return myLeft; + } + + abstract String relationString(); + + abstract int relationType(); + + public String toString() { + return myLeft.getCanonicalText() + " " + relationString() + " " + myRight.getCanonicalText(); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Constraint)) return false; + + final Constraint constraint = (Constraint)o; + + if (myLeft != null ? !myLeft.equals(constraint.myLeft) : constraint.myLeft != null) return false; + if (myRight != null ? !myRight.equals(constraint.myRight) : constraint.myRight != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myLeft != null ? myLeft.hashCode() : 0); + result = 29 * result + (myRight != null ? myRight.hashCode() : 0); + return result + relationType(); + } + + public abstract Constraint apply(final Binding b); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java new file mode 100644 index 00000000000..62c8c8bb357 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java @@ -0,0 +1,29 @@ +package com.intellij.refactoring.typeCook.deductive.builder; + +import com.intellij.psi.PsiType; +import com.intellij.refactoring.typeCook.deductive.resolver.Binding; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jul 20, 2004 + * Time: 6:02:29 PM + * To change this template use File | Settings | File Templates. + */ +public class Subtype extends Constraint { + public Subtype(PsiType left, PsiType right) { + super(left, right); + } + + String relationString() { + return "<:"; + } + + int relationType() { + return 1; + } + + public Constraint apply(final Binding b) { + return new Subtype(b.apply(myLeft), b.apply(myRight)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/System.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/System.java new file mode 100644 index 00000000000..c0f52cd3ad6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/System.java @@ -0,0 +1,256 @@ +package com.intellij.refactoring.typeCook.deductive.builder; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.typeCook.Util; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.refactoring.typeCook.deductive.PsiTypeIntersection; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; + +import java.util.LinkedList; +import java.util.Iterator; +import java.util.HashSet; +import java.util.HashMap; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jul 20, 2004 + * Time: 6:03:14 PM + * To change this template use File | Settings | File Templates. + */ +public class System { + final HashSet myConstraints = new HashSet(); + final HashSet myElements; + final HashMap myTypes; + final PsiTypeVariableFactory myTypeVariableFactory; + + public System(final HashSet elements, final HashMap types, final PsiTypeVariableFactory factory) { + myElements = elements; + myTypes = types; + myTypeVariableFactory = factory; + } + + public HashSet getConstraints() { + return myConstraints; + } + + private void addConstraint(final Constraint constraint) { + myConstraints.add(constraint); + } + + public void addSubtypeConstraint(final PsiType left, final PsiType right) { + if ((Util.bindsTypeVariables(left) || Util.bindsTypeVariables(right)) && + !(left instanceof PsiPrimitiveType || right instanceof PsiPrimitiveType) + ) { + final Subtype c = new Subtype(left, right); + if (!myConstraints.contains(c)) { + myConstraints.add(c); + } + } + } + + private String memberString(final PsiMember member) { + return member.getContainingClass().getQualifiedName() + "." + ((PsiNamedElement)member).getName(); + } + + private String variableString(final PsiLocalVariable var) { + final PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class); + + return memberString(method) + "#" + var.getName(); + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + + buffer.append("Victims:\n"); + + for (Iterator i = myElements.iterator(); i.hasNext();) { + final PsiElement element = i.next(); + final PsiType type = myTypes.get(element); + + if (element instanceof PsiParameter) { + final PsiParameter parm = (PsiParameter)element; + final PsiMethod method = (PsiMethod)parm.getDeclarationScope(); + + buffer.append(" parameter " + method.getParameterList().getParameterIndex(parm) + " of " + memberString(method)); + } + else if (element instanceof PsiField) { + buffer.append(" field " + memberString(((PsiField)element))); + } + else if (element instanceof PsiLocalVariable) { + buffer.append(" local " + variableString(((PsiLocalVariable)element))); + } + else if (element instanceof PsiMethod) { + buffer.append(" return of " + memberString(((PsiMethod)element))); + } + else if (element instanceof PsiNewExpression) { + buffer.append(" " + element.getText()); + } + else if (element instanceof PsiTypeCastExpression) { + buffer.append(" " + element.getText()); + } + else { + buffer.append(" unknown: " + (element == null ? "null" : element.getClass().getName())); + } + + buffer.append(" " + type.getCanonicalText() + "\n"); + } + + buffer.append("Variables: " + myTypeVariableFactory.getNumber() + "\n"); + buffer.append("Constraints: " + myConstraints.size() + "\n"); + + for (Iterator i = myConstraints.iterator(); i.hasNext();) { + buffer.append(" " + i.next() + "\n"); + } + + return buffer.toString(); + } + + public System[] isolate() { + class Node { + int myVar; + int myComponent = -1; + HashSet myNeighbours = new HashSet(); + + public Node(int var) { + myVar = var; + } + + public void addEdge(final Node n) { + if (!myNeighbours.contains(n)) { + myNeighbours.add(n); + } + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + + final Node node = (Node)o; + + if (myVar != node.myVar) return false; + + return true; + } + + public int hashCode() { + return myVar; + } + } + + final Node[] nodes = new Node[myTypeVariableFactory.getNumber()]; + + for (int i = 0; i < nodes.length; i++) { + nodes[i] = new Node(i); + } + + final HashMap constraintVar = new HashMap(); + + for (Iterator i = myConstraints.iterator(); i.hasNext();) { + final HashSet boundVariables = new HashSet(); + + new Object () { + private Constraint myCurrent; + + void visit(final Constraint c){ + myCurrent = c; + + visit(c.getLeft()); + visit(c.getRight()); + } + + private void visit(final PsiType t) { + if (t instanceof PsiTypeVariable) { + final Integer index = new Integer(((PsiTypeVariable)t).getIndex()); + + boundVariables.add(index); + + if (constraintVar.get(myCurrent) == null){ + constraintVar.put(myCurrent, index); + } + } + else if (t instanceof PsiArrayType) { + visit(((PsiArrayType)t).getDeepComponentType()); + } + else if (t instanceof PsiClassType) { + final PsiSubstitutor subst = Util.resolveType(t).getSubstitutor(); + + for (Iterator j = subst.getSubstitutionMap().values().iterator(); j.hasNext();) { + visit(j.next()); + } + } + else if (t instanceof PsiTypeIntersection){ + visit (((PsiTypeIntersection)t).getLeft()); + visit (((PsiTypeIntersection)t).getRight()); + } + } + }.visit (i.next ()); + + final Integer[] bound = boundVariables.toArray(new Integer[]{}); + + for (int j = 0; j < bound.length; j++) { + final int x = bound[j].intValue(); + + for (int k = j + 1; k < bound.length; k++) { + final int y = bound[k].intValue(); + + nodes[x].addEdge(nodes[y]); + } + } + } + + int currComponent = 0; + + for (int i = 0; i < nodes.length; i++) { + final Node node = nodes[i]; + + if (node.myComponent == -1) { + final int component = currComponent; + new Object() { + void selectComponent(final Node n) { + final LinkedList frontier = new LinkedList(); + + frontier.addFirst(n); + + while (frontier.size() > 0) { + final Node curr = frontier.removeFirst(); + + curr.myComponent = component; + + for (Iterator i = curr.myNeighbours.iterator(); i.hasNext();) { + final Node p = i.next(); + + if (p.myComponent == -1) { + frontier.addFirst(p); + } + } + } + } + }.selectComponent(node); + + currComponent++; + } + } + + final System[] systems = new System[currComponent]; + + for (Iterator c = myConstraints.iterator(); c.hasNext();){ + final Constraint constraint = c.next(); + final Integer variable = constraintVar.get(constraint); + final int index = nodes[variable.intValue()].myComponent; + + if (systems[index] == null){ + systems[index] = new System(myElements, myTypes, myTypeVariableFactory); + } + + systems[index].addConstraint(constraint); + } + + return systems; + } + + public PsiTypeVariableFactory getVariableFactory() { + return myTypeVariableFactory; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java new file mode 100644 index 00000000000..d4e26248e65 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java @@ -0,0 +1,711 @@ +package com.intellij.refactoring.typeCook.deductive.builder; + +import com.intellij.dupLocator.util.PsiAnchor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiSuperMethodUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.typeCook.Settings; +import com.intellij.refactoring.typeCook.Util; +import com.intellij.refactoring.typeCook.deductive.PsiTypeIntersection; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; +import com.intellij.refactoring.typeCook.deductive.util.VictimCollector; +import com.intellij.util.containers.HashMap; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 27.06.2003 + * Time: 22:48:08 + * To change this template use Options | File Templates. + */ +public class SystemBuilder { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.builder.SystemBuilder"); + + private PsiManager myManager; + private HashMap myMethodCache; + private HashMap myParameters; + private HashMap mySuper; + private HashMap myTypes; + private HashSet myVisitedConstructions; + private Settings mySettings; + private PsiTypeVariableFactory myTypeVariableFactory; + + public SystemBuilder(PsiManager manager, final Settings settings) { + myManager = manager; + mySettings = settings; + myMethodCache = new HashMap(); + myParameters = new HashMap(); + mySuper = new HashMap(); + myTypes = new HashMap(); + myVisitedConstructions = new HashSet(); + myTypeVariableFactory = new PsiTypeVariableFactory(); + } + + public HashSet collect(final PsiElement[] scopes) { + return new VictimCollector(scopes, mySettings).getVictims(); + } + + private boolean verifyMethod(final PsiElement element, final HashSet victims, final PsiSearchHelper helper) { + PsiMethod method = null; + PsiParameter parameter = null; + int index = 0; + + if (element instanceof PsiMethod) { + method = (PsiMethod)element; + } + else if (element instanceof PsiParameter) { + parameter = (PsiParameter)element; + method = (PsiMethod)parameter.getDeclarationScope(); + index = method.getParameterList().getParameterIndex(parameter); + } + else { + LOG.error("Parameter or method expected, but found " + (element == null ? "null" : element.getClass().getName())); + return false; + } + + final PsiMethod superMethod = PsiSuperMethodUtil.findDeepestSuperMethod(method); + PsiMethod keyMethod; + PsiParameter keyParameter = null; + + if (superMethod != null) { + Boolean good = myMethodCache.get(superMethod); + + if (good != null && !good.booleanValue()) { + return false; + } + + final PsiElement e = + parameter == null ? (PsiElement)superMethod : superMethod.getParameterList().getParameters()[index]; + + if (!victims.contains(e)) { + myMethodCache.put(superMethod, new Boolean(false)); + return false; + } + + keyMethod = superMethod; + + if (parameter != null) { + keyParameter = (PsiParameter)e; + myParameters.put(parameter, keyParameter); + } + } + else { + Boolean good = myMethodCache.get(method); + + if (good != null) { + return good.booleanValue(); + } + + keyMethod = method; + keyParameter = parameter; + } + + final PsiMethod[] overriders = helper.findOverridingMethods(keyMethod, helper.getAccessScope(keyMethod), true); + PsiMethod prev = keyMethod; + + for (int i = 0; i < overriders.length; i++) { + PsiMethod overrider = overriders[i]; + + if (prev != null) { + mySuper.put(overrider, prev); + prev = overrider; + } + + PsiElement e = + parameter == null ? (PsiElement)overrider : overrider.getParameterList().getParameters()[index]; + + if (!victims.contains(e)) { + myMethodCache.put(keyMethod, new Boolean(false)); + return false; + } + + if (parameter != null) { + myParameters.put(parameter, keyParameter); + } + } + + myMethodCache.put(keyMethod, new Boolean(true)); + + return true; + } + + private void setType(final PsiElement e, final PsiType t) { + myTypes.put(e, t); + } + + private PsiType defineType(final PsiElement e) { + PsiType t = myTypes.get(e); + + if (t != null) { + return t; + } + + if (e instanceof PsiVariable) { + t = ((PsiVariable)e).getType(); + } + else if (e instanceof PsiTypeCastExpression) { + t = ((PsiTypeCastExpression)e).getCastType().getType(); + } + else if (e instanceof PsiNewExpression) { + t = ((PsiNewExpression)e).getType(); + } + else if (e instanceof PsiMethod) { + t = ((PsiMethod)e).getReturnType(); + } + else { + LOG.error("Variable, method, new or cast expected but found " + (e == null ? " null" : e.getClass().getName())); + } + + final PsiType parameterizedType = Util.createParameterizedType(t, myTypeVariableFactory); + + myTypes.put(e, parameterizedType); + + return parameterizedType; + } + + private PsiType getType(final PsiElement e) { + final PsiType t = myTypes.get(e); + + if (t != null) { + return t; + } + + if (e instanceof PsiVariable) { + return ((PsiVariable)e).getType(); + } + else if (e instanceof PsiExpression) { + return ((PsiExpression)e).getType(); + } + + return null; + } + + private boolean isCooked(final PsiElement element) { + return myTypes.get(element) != null; + } + + private void addUsage(final System system, final PsiElement element) { + + class TypeEvaluator { + PsiType valuateType(final PsiExpression expr) { + return evaluateType(expr); + } + + PsiType evaluateType(final PsiExpression expr) { + if (expr instanceof PsiArrayAccessExpression && !mySettings.preserveRawArrays()) { + final PsiType at = evaluateType(((PsiArrayAccessExpression)expr).getArrayExpression()); + + if (at instanceof PsiArrayType) { + return ((PsiArrayType)at).getComponentType(); + } + } + else if (expr instanceof PsiAssignmentExpression) { + return evaluateType(((PsiAssignmentExpression)expr).getLExpression()); + } + else if (expr instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression call = ((PsiMethodCallExpression)expr); + final PsiMethod method = call.resolveMethod(); + + if (method != null) { + final PsiClass aClass = method.getContainingClass(); + final PsiTypeParameter[] aTypeParms = method.getTypeParameterList().getTypeParameters(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final PsiExpression[] arguments = call.getArgumentList().getExpressions(); + final PsiExpression aQualifier = call.getMethodExpression().getQualifierExpression(); + final PsiExpression[] actualParms = call.getArgumentList().getExpressions(); + final HashSet typeParameters = new HashSet(); + + for (int i = 0; i < aTypeParms.length; i++) { + typeParameters.add(aTypeParms[i]); + } + + PsiSubstitutor qualifierSubstitutor = PsiSubstitutor.EMPTY; + PsiSubstitutor supertypeSubstitutor = PsiSubstitutor.EMPTY; + + PsiType aType = method.getReturnType(); + + if (aQualifier != null) { + final PsiType qualifierType = evaluateType(aQualifier); + final PsiClassType.ClassResolveResult result = Util.resolveType(qualifierType); + + if (result.getElement() != null) { + final PsiClass qualifierClass = result.getElement(); + + qualifierSubstitutor = result.getSubstitutor(); + + if (!qualifierClass.equals(aClass)) { + supertypeSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(aClass, qualifierClass, PsiSubstitutor.EMPTY); + + aType = Util.substituteType(aType, supertypeSubstitutor); + } + + aType = Util.substituteType(aType, qualifierSubstitutor); + } + } + + // Bind method type parameters here. Remember: intersection types are needed :(( + // Example: + // T foo (List a, List b) {...} + // class List {...} + // + // List x; -- List<'a> x + // List y; -- List<'b> y + // + // foo (x, y) -- type is 'a ^ 'b. Woof, woof.... + + final HashMap mapping = new HashMap(); + + for (int i = 0; i < Math.min(parameters.length, arguments.length); i++) { + final PsiType argumenType = evaluateType(arguments[i]); + final PsiType parmType = getType(parameters[i]); + + if (isCooked(parameters[i])) { + system.addSubtypeConstraint(argumenType, parmType); + } + else { + final PsiType theType = + new Object() { + PsiType introduceAdditionalTypeVariables(final PsiType type, + final PsiSubstitutor qualifier, + final PsiSubstitutor supertype) { + final PsiClassType.ClassResolveResult result = Util.resolveType(type); + final PsiClass aClass = result.getElement(); + + if (aClass != null) { + if (aClass instanceof PsiTypeParameter){ + final PsiTypeParameter tp = ((PsiTypeParameter)aClass); + + PsiType pv = mapping.get(tp); + + if (pv == null) { + pv = myTypeVariableFactory.create(); + mapping.put(tp, pv); + } + + return pv; + } + + final Map substitutionMap = result.getSubstitutor().getSubstitutionMap(); + + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (Iterator t = substitutionMap.keySet().iterator(); t.hasNext();) { + final PsiTypeParameter p = t.next(); + final PsiType pType = substitutionMap.get(p); + + if (pType instanceof PsiWildcardType) { + final PsiWildcardType wildcard = ((PsiWildcardType)pType); + final PsiType theBound = wildcard.getBound(); + + if (theBound != null) { + final PsiType bound = Util.substituteType(Util.substituteType(theBound, supertype), qualifier); + + if (Util.bindsTypeVariables(bound)) { + final PsiType var = myTypeVariableFactory.create(); + + if (wildcard.isExtends()) { + system.addSubtypeConstraint(bound, var); + } + else { + system.addSubtypeConstraint(var, bound); + } + + theSubst = theSubst.put(p, var); + } + else if (Util.bindsTypeParameters(bound, typeParameters)) { + final PsiType var = myTypeVariableFactory.create(); + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + + for (int i = 0; i < aTypeParms.length; i++) { + final PsiTypeParameter aTypeParm = aTypeParms[i]; + + PsiType parmVar = mapping.get(aTypeParm); + + if (parmVar == null) { + parmVar = myTypeVariableFactory.create(); + mapping.put(aTypeParm, parmVar); + } + + subst = subst.put(aTypeParm, parmVar); + } + + final PsiType bnd = Util.substituteType(bound, subst); + + if (wildcard.isExtends()) { + system.addSubtypeConstraint(bnd, var); + } + else { + system.addSubtypeConstraint(var, bnd); + } + + theSubst = theSubst.put(p, var); + } + else { + theSubst = theSubst.put(p, pType); + } + } + } + else { + theSubst = theSubst.put(p, introduceAdditionalTypeVariables(pType, qualifier, supertype)); + } + } + + return aClass.getManager().getElementFactory().createType(aClass, theSubst); + } + + return type; + } + }.introduceAdditionalTypeVariables(Util.substituteType(Util.substituteType(parmType, supertypeSubstitutor), qualifierSubstitutor), qualifierSubstitutor, supertypeSubstitutor); + + system.addSubtypeConstraint(argumenType, theType); + //Util.substituteType(Util.substituteType(theType, supertypeSubstitutor), qualifierSubstitutor)); + } + + new Object() { + private void update(final PsiTypeParameter p, final PsiType t) { + final PsiType binding = mapping.get(p); + + if (binding == null) { + mapping.put(p, t); + } + else if (t != null) { + mapping.put(p, new PsiTypeIntersection(binding, t)); + } + } + + void bindTypeParameters(final PsiType formal, final PsiType actual) { + final PsiClassType.ClassResolveResult resultF = Util.resolveType(formal); + + if (resultF.getElement() != null) { + final PsiClass classF = resultF.getElement(); + + if (classF instanceof PsiTypeParameter) { + update((PsiTypeParameter)classF, actual); + return; + } + + final PsiClassType.ClassResolveResult resultA = Util.resolveType(actual); + + if (resultA.getElement() == null) { + return; + } + + final PsiClass classA = resultA.getElement(); + + if (!classA.equals(classF)) { + final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(classF, classA, + PsiSubstitutor.EMPTY); + final PsiType aligned = classF.getManager().getElementFactory().createType(classF, superClassSubstitutor); + + bindTypeParameters(formal, Util.substituteType(aligned, resultA.getSubstitutor())); + } + + final PsiTypeParameter[] typeParms = Util.getTypeParametersList(classA); + final PsiSubstitutor substA = resultA.getSubstitutor(); + final PsiSubstitutor substF = resultF.getSubstitutor(); + + for (int i = 0; i < typeParms.length; i++) { + PsiTypeParameter typeParm = typeParms[i]; + bindTypeParameters(substF.substitute(typeParm), substA.substitute(typeParm)); + } + } + } + }.bindTypeParameters(parmType, evaluateType(actualParms[i])); + } + + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (Iterator i = mapping.keySet().iterator(); i.hasNext();){ + final PsiTypeParameter parm = i.next(); + final PsiType type = mapping.get(parm); + + theSubst = theSubst.put(parm, type); + } + + return Util.substituteType(aType, theSubst); + } + } + else if (expr instanceof PsiParenthesizedExpression) { + return evaluateType(((PsiParenthesizedExpression)expr).getExpression()); + } + else if (expr instanceof PsiConditionalExpression) { + return evaluateType(((PsiConditionalExpression)expr).getThenExpression()); + } + else if (expr instanceof PsiNewExpression) { + final PsiExpression qualifier = ((PsiNewExpression)expr).getQualifier(); + + if (qualifier != null) { + final PsiClassType.ClassResolveResult qualifierResult = Util.resolveType(evaluateType(qualifier)); + + if (qualifierResult.getElement() != null) { + final PsiSubstitutor qualifierSubs = qualifierResult.getSubstitutor(); + final PsiClassType.ClassResolveResult result = Util.resolveType(expr.getType()); + + if (result.getElement() != null) { + final PsiClass aClass = result.getElement(); + + return aClass.getManager().getElementFactory().createType(aClass, result.getSubstitutor().putAll(qualifierSubs)); + } + } + } + } + else if (expr instanceof PsiReferenceExpression) { + final PsiReferenceExpression ref = ((PsiReferenceExpression)expr); + final PsiExpression qualifier = ref.getQualifierExpression(); + + if (qualifier == null) { + return getType(ref.resolve()); + } + else { + final PsiType qualifierType = evaluateType(qualifier); + final PsiElement element = ref.resolve(); + + final PsiClassType.ClassResolveResult result = Util.resolveType(qualifierType); + + if (result.getElement() != null) { + final PsiClass aClass = result.getElement(); + final PsiSubstitutor aSubst = result.getSubstitutor(); + + if (element instanceof PsiField) { + final PsiField field = (PsiField)element; + final PsiType fieldType = getType(field); + final PsiClass superClass = field.getContainingClass(); + + PsiType aType = fieldType; + + if (!aClass.equals(superClass)) { + aType = + Util.substituteType(aType, TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY)); + } + + return Util.substituteType(aType, aSubst); + } + } + } + } + + return getType(expr); + } + } + + final TypeEvaluator e = new TypeEvaluator(); + + if (element instanceof PsiVariable) { + final PsiExpression initializer = ((PsiVariable)element).getInitializer(); + + if (initializer != null) { + system.addSubtypeConstraint(e.valuateType(initializer), getType(element)); + } + + return; + } + + final PsiStatement root = (PsiStatement)PsiTreeUtil.getParentOfType(element, PsiStatement.class); + + if (root != null) { + final PsiAnchor anchor = new PsiAnchor(root); + + if (!myVisitedConstructions.contains(anchor)) { + root.accept(new PsiRecursiveElementVisitor() { + public void visitAssignmentExpression(final PsiAssignmentExpression expression) { + super.visitAssignmentExpression(expression); + + system.addSubtypeConstraint(e.valuateType(expression.getRExpression()), e.valuateType(expression.getLExpression())); + } + + public void visitConditionalExpression(final PsiConditionalExpression expression) { + super.visitConditionalExpression(expression); + + system.addSubtypeConstraint(e.valuateType(expression.getThenExpression()), e.valuateType(expression.getElseExpression())); + system.addSubtypeConstraint(e.valuateType(expression.getElseExpression()), e.valuateType(expression.getThenExpression())); + } + + public void visitMethodCallExpression(final PsiMethodCallExpression expression) { + e.valuateType(expression); + } + + public void visitReturnStatement(final PsiReturnStatement statement) { + super.visitReturnStatement(statement); + + final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class); + + if (method != null) { + system.addSubtypeConstraint(method.getReturnType(), e.valuateType(statement.getReturnValue())); + } + } + + public void visitTypeCastExpression(final PsiTypeCastExpression expression) { + super.visitTypeCastExpression(expression); + + system.addSubtypeConstraint(e.valuateType(expression.getOperand()), e.valuateType(expression)); + } + + public void visitReferenceExpression(final PsiReferenceExpression expression) { + } + }); + + myVisitedConstructions.add(anchor); + } + } + } + + private void addBoundConstraints(final System system, final PsiType definedType, final PsiElement element) { + final PsiType elemenType = + (element instanceof PsiMethod) ? ((PsiMethod)element).getReturnType() : + (element instanceof PsiVariable) ? ((PsiVariable)element).getType() : null; + + if (elemenType != null) { + new Object() { + void brrrr(final PsiType defined, final PsiType type) { + final PsiClassType.ClassResolveResult resultDefined = Util.resolveType(defined); + final PsiClassType.ClassResolveResult resultType = Util.resolveType(type); + final PsiClass definedClass = resultDefined.getElement(); + + if (definedClass == null || !definedClass.equals(resultType.getElement())) { + return; + } + + final PsiSubstitutor definedSubst = resultDefined.getSubstitutor(); + final PsiSubstitutor typeSubst = resultType.getSubstitutor(); + + for (Iterator i = definedSubst.getSubstitutionMap().keySet().iterator(); i.hasNext();) { + final PsiTypeParameter parameter = i.next(); + final PsiClassType[] extendsList = parameter.getExtendsList().getReferencedTypes(); + final PsiType definedType = definedSubst.substitute(parameter); + + if (definedType instanceof PsiTypeVariable) { + for (int j = 0; j < extendsList.length; j++) { + final PsiType extendsType = + new Object() { + PsiType replaceWildCards(final PsiType type) { + if (type instanceof PsiWildcardType) { + final PsiWildcardType wildcard = ((PsiWildcardType)type); + final PsiType var = myTypeVariableFactory.create(); + final PsiType bound = wildcard.getBound(); + + if (bound != null) { + if (wildcard.isExtends()) { + system.addSubtypeConstraint(Util.substituteType(replaceWildCards(bound), definedSubst), var); + } + else { + system.addSubtypeConstraint(var, Util.substituteType(replaceWildCards(bound), definedSubst)); + } + } + + return var; + } + else if (type instanceof PsiClassType) { + final PsiClassType.ClassResolveResult result = Util.resolveType(type); + final PsiClass aClass = result.getElement(); + final PsiSubstitutor aSubst = result.getSubstitutor(); + + if (aClass != null) { + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + for (Iterator i = aSubst.getSubstitutionMap().keySet().iterator(); i.hasNext();) { + final PsiTypeParameter p = i.next(); + + theSubst = theSubst.put(p, replaceWildCards(aSubst.substitute(p))); + } + + return aClass.getManager().getElementFactory().createType(aClass, theSubst); + } + } + + return type; + } + }.replaceWildCards(extendsList[j]); + + system.addSubtypeConstraint(Util.substituteType(extendsType, definedSubst), definedType); + } + } + else { + brrrr(definedType, typeSubst.substitute(parameter)); + } + } + } + }.brrrr(definedType, elemenType); + } + } + + public System build(final HashSet victims) { + final PsiSearchHelper helper = myManager.getSearchHelper(); + + System system = new System(victims, myTypes, myTypeVariableFactory); + + for (Iterator i = victims.iterator(); i.hasNext();) { + final PsiElement element = i.next(); + + if (element instanceof PsiParameter) { + if (!verifyMethod(element, victims, helper)) { + continue; + } + } + else if (element instanceof PsiMethod) { + if (!verifyMethod(element, victims, helper)) { + continue; + } + } + } + + PsiType definedType; + + for (Iterator i = victims.iterator(); i.hasNext();) { + final PsiElement element = i.next(); + + if (element instanceof PsiParameter) { + final PsiParameter p = myParameters.get(element); + + if (p != null) { + setType(element, definedType = defineType(p)); + } + else { + definedType = defineType(element); + } + } + else if (element instanceof PsiMethod) { + final PsiMethod m = mySuper.get(element); + + if (m != null) { + system.addSubtypeConstraint(defineType(element), definedType = defineType(m)); + } + else { + definedType = defineType(element); + } + } + else { + definedType = defineType(element); + } + + addBoundConstraints(system, definedType, element); + } + + for (Iterator i = victims.iterator(); i.hasNext();) { + final PsiElement element = i.next(); + + addUsage(system, element); + + if (!(element instanceof PsiExpression)) { + PsiReference[] refs = helper.findReferences(element, helper.getAccessScope(element), true); + + for (int k = 0; k < refs.length; k++) { + final PsiElement ref = refs[k].getElement(); + + if (ref != null) { + addUsage(system, ref); + } + } + } + } + + return system; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java new file mode 100644 index 00000000000..885b7e3a897 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java @@ -0,0 +1,17 @@ +package com.intellij.refactoring.typeCook.deductive.resolver; + +import com.intellij.psi.PsiType; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jan 13, 2005 + * Time: 3:44:56 PM + * To change this template use File | Settings | File Templates. + */ +public interface Binding { + PsiType apply (PsiType type); + Binding compose (Binding b); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java new file mode 100644 index 00000000000..6ed96d56d6a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java @@ -0,0 +1,259 @@ +package com.intellij.refactoring.typeCook.deductive.resolver; + +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.refactoring.typeCook.Util; +import com.intellij.refactoring.typeCook.Bottom; +import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.openapi.diagnostic.Logger; + +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jan 13, 2005 + * Time: 3:46:59 PM + * To change this template use File | Settings | File Templates. + */ +public class BindingFactory { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.resolver.BindingFactory"); + + private PsiTypeVariableFactory myTypeVariableFactory; + + private class BindingImpl implements Binding { + private PsiType[] myBindings; + + BindingImpl(final PsiTypeVariable var, final PsiType type) { + myBindings = new PsiType[myTypeVariableFactory.getNumber()]; + + myBindings[var.getIndex()] = type; + } + + BindingImpl(final int n) { + myBindings = new PsiType[n]; + } + + public PsiType apply(final PsiType type) { + if (type instanceof PsiTypeVariable) { + final PsiType t = myBindings[((PsiTypeVariable)type).getIndex()]; + return (t == null) ? type : t; + } + else if (type instanceof PsiArrayType) { + return apply(((PsiArrayType)type).getComponentType()).createArrayType(); + } + else if (type instanceof PsiClassType) { + final PsiClassType.ClassResolveResult result = Util.resolveType(type); + final PsiClass theClass = result.getElement(); + final PsiSubstitutor aSubst = result.getSubstitutor(); + + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + + if (theClass != null) { + for (Iterator p = aSubst.getSubstitutionMap().keySet().iterator(); p.hasNext();) { + final PsiTypeParameter aParm = p.next(); + final PsiType aType = aSubst.substitute(aParm); + + theSubst = theSubst.put(aParm, apply(aType)); + } + + return theClass.getManager().getElementFactory().createType(theClass, theSubst); + } + else { + return null; + } + } + else { + return type; + } + } + + public Binding compose(final Binding b) { + LOG.assertTrue(b instanceof BindingImpl); + + final BindingImpl b1 = this; + final BindingImpl b2 = (BindingImpl)b; + + LOG.assertTrue(b1.myBindings.length == b2.myBindings.length); + + final BindingImpl b3 = new BindingImpl(b1.myBindings.length); + + for (int i = 0; i < myBindings.length; i++) { + final PsiType b1i = b1.myBindings[i]; + final PsiType b2i = b2.myBindings[i]; + + final int flag = (b1i == null ? 0 : 1) + (b2i == null ? 0 : 2); + + switch (flag) { + case 0: + break; + + case 1: /* b1(i)\b2(i) */ + b3.myBindings[i] = b2.apply(b1i); + break; + + case 2: /* b2(i)\b1(i) */ + b3.myBindings[i] = b1.apply(b2i); + break; + + case 3: /* b2(i) \cap b1(i) */ + final Binding common = rise(b1i, b2i); + + if (common == null) { + return null; + } + + b3.myBindings[i] = b2.apply(common.apply(b1i)); + } + } + + return b3; + } + + public String toString() { + final StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < myBindings.length; i++) { + final PsiType binding = myBindings[i]; + + if (binding != null){ + buffer.append("#" + i + " -> " + binding.getPresentableText() + "; "); + } + } + + return buffer.toString(); + } + } + + interface Balancer { + Binding varType(PsiTypeVariable x, PsiType y); + + Binding varVar(PsiTypeVariable x, PsiTypeVariable y); + + Binding typeVar(PsiType x, PsiTypeVariable y); + } + + public Binding balance(final PsiType x, final PsiType y, final Balancer balancer) { + final int indicator = (x instanceof PsiTypeVariable ? 1 : 0) + (y instanceof PsiTypeVariable ? 2 : 0); + + switch (indicator) { + case 0: + if (x instanceof PsiArrayType && y instanceof PsiArrayType) { + return balance(((PsiArrayType)x).getComponentType(), ((PsiArrayType)y).getComponentType(), balancer); + } + else if (x instanceof PsiClassType && y instanceof PsiClassType) { + final PsiClassType.ClassResolveResult resultX = Util.resolveType(x); + final PsiClassType.ClassResolveResult resultY = Util.resolveType(y); + + final PsiClass xClass = resultX.getElement(); + final PsiClass yClass = resultY.getElement(); + + if (xClass != null && yClass != null) { + final PsiSubstitutor xSubst = resultX.getSubstitutor(); + + PsiSubstitutor ySubst = resultY.getSubstitutor(); + + if (!xClass.equals(yClass)) { + if (InheritanceUtil.isCorrectDescendant(yClass, xClass, true)) { + ySubst = + Util.composeSubstitutors(ySubst, TypeConversionUtil.getSuperClassSubstitutor(xClass, yClass, PsiSubstitutor.EMPTY)); + } + + return null; + } + + Binding b = create(); + + for (Iterator p = xSubst.getSubstitutionMap().keySet().iterator(); p.hasNext();) { + final PsiTypeParameter aParm = p.next(); + final PsiType xType = xSubst.substitute(aParm); + final PsiType yType = ySubst.substitute(aParm); + + final Binding b1 = balance(xType, yType, balancer); + + if (b1 == null) { + return null; + } + + b = b.compose(b1); + } + + return b; + } + } + else { + return null; + } + + case 1: + return balancer.varType((PsiTypeVariable)x, y); + + case 2: + return balancer.typeVar(x, (PsiTypeVariable)y); + + case 3: + return balancer.varVar((PsiTypeVariable)x, (PsiTypeVariable)y); + } + + return null; + } + + public Binding rise(final PsiType x, final PsiType y) { + return balance(x, y, new Balancer() { + + public Binding varType(PsiTypeVariable x, PsiType y) { + return create(x, y); + } + + public Binding varVar(PsiTypeVariable x, PsiTypeVariable y) { + final int xi = x.getIndex(); + final int yi = y.getIndex(); + + if (xi < yi) { + return create(((PsiTypeVariable)x), y); + } + else if (yi < xi) { + return create(((PsiTypeVariable)y), x); + } + else { + return create(); + } + } + + public Binding typeVar(PsiType x, PsiTypeVariable y) { + return create(y, x); + } + }); + } + + public Binding sink(final PsiType x, final PsiType y) { + return balance(x, y, new Balancer() { + + public Binding varType(PsiTypeVariable x, PsiType y) { + return create(x, Bottom.BOTTOM); + } + + public Binding varVar(PsiTypeVariable x, PsiTypeVariable y) { + return create(x, Bottom.BOTTOM); + } + + public Binding typeVar(PsiType x, PsiTypeVariable y) { + return create(y, x); + } + }); + } + + public BindingFactory(final PsiTypeVariableFactory typeVariableFactory) { + myTypeVariableFactory = typeVariableFactory; + } + + public Binding create(final PsiTypeVariable var, final PsiType type) { + return new BindingImpl(var, type); + } + + public Binding create() { + return new BindingImpl(myTypeVariableFactory.getNumber()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java new file mode 100644 index 00000000000..620c32df66e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java @@ -0,0 +1,122 @@ +package com.intellij.refactoring.typeCook.deductive.resolver; + +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor; +import com.intellij.refactoring.typeCook.deductive.builder.Constraint; + +import javax.swing.text.html.HTMLDocument; +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Dec 27, 2004 + * Time: 4:57:07 PM + * To change this template use File | Settings | File Templates. + */ +public class ResolverTree { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.resolver.ResolverTree"); + + private HashSet myConstraints; + private ResolverTree myParent; + private ResolverTree[] mySons = new ResolverTree[0]; + private BindingFactory myBindingFactory; + private Binding myCurrentBinding; + + public ResolverTree(final com.intellij.refactoring.typeCook.deductive.builder.System system) { + myBindingFactory = new BindingFactory(system.getVariableFactory()); + myConstraints = system.getConstraints(); + myCurrentBinding = myBindingFactory.create(); + myParent = null; + } + + private ResolverTree(final ResolverTree parent, final HashSet constaints, final Binding binding) { + myBindingFactory = parent.myBindingFactory; + myConstraints = constaints; + myCurrentBinding = binding; + myParent = parent; + } + + private HashSet apply(final Binding b, final Constraint omit) { + final HashSet result = new HashSet(); + + for (Iterator c = myConstraints.iterator(); c.hasNext();) { + final Constraint constr = c.next(); + + if (constr == omit) { + continue; + } + + result.add(constr.apply(b)); + } + + return result; + } + + private ResolverTree applyRule(final Binding b, final Constraint omit) { + return new ResolverTree(this, apply(b, omit), myCurrentBinding.compose(b)); + } + + private boolean reduceTypeType() { + for (Iterator c = myConstraints.iterator(); c.hasNext();) { + final Constraint constr = c.next(); + + final PsiType left = constr.getLeft(); + final PsiType right = constr.getRight(); + + if (!(left instanceof PsiTypeVariable) && !(right instanceof PsiTypeVariable)) { + final Binding riseBinding = myBindingFactory.rise(left, right); + final Binding sinkBinding = myBindingFactory.sink(left, right); + + final int indicator = (riseBinding == null ? 0 : 1) + (sinkBinding == null ? 0 : 1); + + if (indicator == 0) { + return false; + } + + mySons = new ResolverTree[indicator]; + + int n = 0; + + if (riseBinding != null) { + mySons[n++] = applyRule(riseBinding, constr); + } + + if (sinkBinding != null) { + mySons[n++] = applyRule(sinkBinding, constr); + } + + return true; + } + } + + return false; + } + + private boolean solved (){ + return myConstraints.size() == 0; + } + + private void resolve (final List solutions){ + if (solved()){ + solutions.add(myCurrentBinding); + } + + if (reduceTypeType ()){ + for (int i = 0; i < mySons.length; i++) { + mySons[i].resolve(solutions); + } + } + } + + public List resolve (){ + final LinkedList list = new LinkedList(); + + resolve(list); + + return list; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java new file mode 100644 index 00000000000..975e7c7fd99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java @@ -0,0 +1,86 @@ +package com.intellij.refactoring.typeCook.deductive.util; + +import com.intellij.refactoring.typeCook.Util; +import com.intellij.refactoring.typeCook.Settings; +import com.intellij.psi.*; + +import java.util.HashSet; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jul 5, 2004 + * Time: 6:45:51 PM + * To change this template use File | Settings | File Templates. + */ +public class VictimCollector extends Visitor { + final HashSet myVictims = new HashSet(); + final PsiElement[] myElements; + final Settings mySettings; + + public VictimCollector(final PsiElement[] elements, final Settings settings) { + myElements = elements; + mySettings = settings; + } + + private void testNAdd(final PsiElement element, final PsiType t) { + if (Util.isRaw(t, mySettings.preserveRawArrays())) { + myVictims.add(element); + } + } + + public void visitLocalVariable(final PsiLocalVariable variable) { + testNAdd(variable, variable.getType()); + + super.visitLocalVariable(variable); + } + + public void visitField(final PsiField field) { + testNAdd(field, field.getType()); + + super.visitField(field); + } + + public void visitMethod(final PsiMethod method) { + final PsiParameter[] parms = method.getParameterList().getParameters(); + + for (int i = 0; i < parms.length; i++) { + testNAdd(parms[i], parms[i].getType()); + } + + if (Util.isRaw(method.getReturnType(), mySettings.preserveRawArrays())) { + myVictims.add(method); + } + + final PsiCodeBlock body = method.getBody(); + + if (body != null) { + body.accept(this); + } + } + + public void visitNewExpression(final PsiNewExpression expression) { + if (expression.getClassReference() != null) { + testNAdd(expression, expression.getType()); + } + + super.visitNewExpression(expression); + } + + public void visitTypeCastExpression (final PsiTypeCastExpression cast){ + testNAdd(cast, cast.getCastType().getType()); + + super.visitTypeCastExpression(cast); + } + + public void visitReferenceExpression(final PsiReferenceExpression expression) { + } + + public HashSet getVictims() { + for (int i = 0; i < myElements.length; i++) { + myElements[i].accept(this); + } + + return myVictims; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/Visitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/Visitor.java new file mode 100644 index 00000000000..4285c75efc2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/typeCook/deductive/util/Visitor.java @@ -0,0 +1,28 @@ +package com.intellij.refactoring.typeCook.deductive.util; + +import com.intellij.psi.*; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: Jul 5, 2004 + * Time: 6:44:49 PM + * To change this template use File | Settings | File Templates. + */ +public abstract class Visitor extends PsiRecursiveElementVisitor { + public void visitPackage(final PsiPackage aPackage) { + final PsiDirectory[] dirs = aPackage.getDirectories(); + + for (int i = 0; i < dirs.length; i++) { + final PsiFile[] files = dirs[i].getFiles(); + + for (int j = 0; j < files.length; j++) { + final PsiFile file = files[j]; + + if (file instanceof PsiJavaFile) { + super.visitJavaFile(((PsiJavaFile)file)); + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ClassCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ClassCellRenderer.java new file mode 100644 index 00000000000..7091987cce9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ClassCellRenderer.java @@ -0,0 +1,69 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 18.06.2002 + * Time: 13:47:11 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiClass; + +import javax.swing.*; +import java.awt.*; + +/** + * Renders a list cell which contains a class + */ +public class ClassCellRenderer extends DefaultListCellRenderer { + private final boolean myShowReadOnly; + public ClassCellRenderer() { + setOpaque(true); + myShowReadOnly = true; + } + + public ClassCellRenderer(boolean showReadOnly) { + setOpaque(true); + myShowReadOnly = showReadOnly; + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + PsiClass aClass = (PsiClass) value; + setText(getClassText(aClass)); + + final int flags; + if (myShowReadOnly) { + flags = Iconable.ICON_FLAG_READ_STATUS | Iconable.ICON_FLAG_VISIBILITY; + } else { + flags = Iconable.ICON_FLAG_VISIBILITY; + } + Icon icon = aClass.getIcon(flags); + if(icon != null) setIcon(icon); + return this; + } + + static String getClassText(PsiClass aClass) { + String qualifiedName = aClass.getQualifiedName(); + String text; + if (qualifiedName != null) { + text = qualifiedName; + } else { + String name = aClass.getName(); + if (name != null) { + text = name; + } else { + text = "Anonymous class"; + } + } + return text; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellEditor.java new file mode 100644 index 00000000000..93b621a7a3c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellEditor.java @@ -0,0 +1,50 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.ui.EditorTextField; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; + +/** + * @author dsl + */ +public class CodeFragmentTableCellEditor extends AbstractCellEditor implements TableCellEditor { + private Document myDocument; + private PsiCodeFragment myCodeFragment; + private Project myProject; + + public CodeFragmentTableCellEditor(final Project project) { + CodeFragmentTableCellEditor.this.myProject = project; + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + myCodeFragment = (PsiCodeFragment)value; + + myDocument = PsiDocumentManager.getInstance(myProject).getDocument(myCodeFragment); + return new EditorTextField(myDocument, myProject, StdFileTypes.JAVA) { + protected boolean shouldHaveBorder() { + return false; + } + }; + } + + public PsiCodeFragment getCellEditorValue() { + return myCodeFragment; + } + + public void cancelCellEditing() { + super.cancelCellEditing(); + } + + public boolean stopCellEditing() { + super.stopCellEditing(); + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java new file mode 100644 index 00000000000..9555a40b121 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java @@ -0,0 +1,43 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.ui.EditorTextField; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import java.awt.*; + +/** + * @author dsl + */ +public class CodeFragmentTableCellRenderer implements TableCellRenderer { + private final Project myProject; + + public CodeFragmentTableCellRenderer(Project project) { + myProject = project; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + PsiCodeFragment codeFragment = (PsiCodeFragment)value; + + if (codeFragment != null) { + Document document = PsiDocumentManager.getInstance(myProject).getDocument(codeFragment); + return new EditorTextField(document, myProject, StdFileTypes.JAVA) { + protected boolean shouldHaveBorder() { + return false; + } + }; + } + else { + return new EditorTextField("", myProject, StdFileTypes.JAVA) { + protected boolean shouldHaveBorder() { + return false; + } + }; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ColorConfiguringCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ColorConfiguringCellRenderer.java new file mode 100644 index 00000000000..610fd106c9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ColorConfiguringCellRenderer.java @@ -0,0 +1,28 @@ +package com.intellij.refactoring.ui; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; + +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: Oct 18, 2002 + * Time: 5:09:33 PM + * To change this template use Options | File Templates. + */ +public class ColorConfiguringCellRenderer extends DefaultTableCellRenderer { + protected void configureColors(boolean isSelected, JTable table, boolean hasFocus, final int row, final int column) { + + if (isSelected) { + setForeground(table.getSelectionForeground()); + } + else { + setForeground(UIManager.getColor("Table.foreground")); + } + + + if (hasFocus) { + setForeground(UIManager.getColor("Table.focusCellForeground")); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ConflictsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ConflictsDialog.java new file mode 100644 index 00000000000..d42741d3406 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/ConflictsDialog.java @@ -0,0 +1,65 @@ +/** + * created at Sep 12, 2001 + * @author Jeka + */ +package com.intellij.refactoring.ui; + +import java.awt.*; +import java.awt.event.ActionEvent; +import javax.swing.*; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.project.Project; + +public class ConflictsDialog extends DialogWrapper{ + private JEditorPane myMessagePane; + private String[] myConflictDescriptions; + + public ConflictsDialog(String[] conflictDescriptions, Project project) { + super(project, true); + myConflictDescriptions = conflictDescriptions; + setTitle("Problems Detected"); + setOKButtonText("Continue"); + init(); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction(),new CancelAction()}; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + myMessagePane = new JEditorPane("text/html", ""); + myMessagePane.setEditable(false); + JScrollPane scrollPane = new JScrollPane(myMessagePane); + scrollPane.setPreferredSize(new Dimension(500, 400)); + panel.add(new JLabel("The following problems were found:"), BorderLayout.NORTH); + panel.add(scrollPane, BorderLayout.CENTER); + + StringBuffer buf = new StringBuffer(); + for (int idx = 0; idx < myConflictDescriptions.length; idx++) { + String description = myConflictDescriptions[idx]; + buf.append(description).append("

    "); + } + myMessagePane.setText(buf.toString()); + return panel; + } + + protected JComponent createSouthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(super.createSouthPanel(), BorderLayout.CENTER); + panel.add(new JLabel("Do you wish to ignore them and continue?"), BorderLayout.WEST); + return panel; + } + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + putValue(DialogWrapper.DEFAULT_ACTION,Boolean.TRUE); + } + + public void actionPerformed(ActionEvent e) { + doCancelAction(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/DelegationPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/DelegationPanel.java new file mode 100644 index 00000000000..56044525059 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/DelegationPanel.java @@ -0,0 +1,52 @@ +package com.intellij.refactoring.ui; + +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author dsl + */ +public class DelegationPanel extends JPanel { + private final JRadioButton myRbModifyCalls; + private final JRadioButton myRbGenerateDelegate; + + public DelegationPanel() { + final BoxLayout boxLayout = new BoxLayout(this, BoxLayout.X_AXIS); + setLayout(boxLayout); + add(new JLabel("Method calls:")); + myRbModifyCalls = new JRadioButton("Modify"); + myRbModifyCalls.setMnemonic('M'); + add(myRbModifyCalls); + myRbGenerateDelegate = new JRadioButton("Delegate via overloading method"); + myRbGenerateDelegate.setMnemonic('l'); + add(myRbGenerateDelegate); + myRbModifyCalls.setSelected(true); + final ButtonGroup bg = new ButtonGroup(); + bg.add(myRbModifyCalls); + bg.add(myRbGenerateDelegate); + add(Box.createHorizontalGlue()); + myRbModifyCalls.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + stateModified(); + } + }); + myRbGenerateDelegate.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + stateModified(); + } + }); + } + + protected void stateModified() { + + } + + public boolean isModifyCalls() { + return myRbModifyCalls.isSelected(); + } + + public boolean isGenerateDelegate() { + return myRbGenerateDelegate.isSelected(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EditableRowTableManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EditableRowTableManager.java new file mode 100644 index 00000000000..10f51957c3f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EditableRowTableManager.java @@ -0,0 +1,163 @@ +package com.intellij.refactoring.ui; + +import com.intellij.ui.TableUtil; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author dsl + */ +public class EditableRowTableManager { + private JButton myAddButton; + private JButton myRemoveButton; + private JButton myUpButton; + private JButton myDownButton; + private final JTable myTable; + private final RowEditableTableModel myTableModel; + private final JPanel myButtonsPanel; + + public EditableRowTableManager(final JTable table, final RowEditableTableModel tableModel, boolean addMnemonics) { + myTable = table; + myTableModel = tableModel; + myButtonsPanel = createButtonsPanel(addMnemonics); + } + + public JPanel getButtonsPanel() { + return myButtonsPanel; + } + + private JPanel createButtonsPanel(boolean addMnemonics) { + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + + buttonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(2, 4, 2, 4); + + myAddButton = new JButton("Add"); + if (addMnemonics) myAddButton.setMnemonic('A'); + myAddButton.setDefaultCapable(false); + buttonsPanel.add(myAddButton, gbConstraints); + + myRemoveButton = new JButton("Remove"); + if (addMnemonics) myRemoveButton.setMnemonic('R'); + myRemoveButton.setDefaultCapable(false); + buttonsPanel.add(myRemoveButton, gbConstraints); + + myUpButton = new JButton("Move Up"); + if (addMnemonics) myUpButton.setMnemonic('U'); + myUpButton.setDefaultCapable(false); + buttonsPanel.add(myUpButton, gbConstraints); + + myDownButton = new JButton("Move Down"); + if (addMnemonics) myDownButton.setMnemonic('D'); + myDownButton.setDefaultCapable(false); + buttonsPanel.add(myDownButton, gbConstraints); + + gbConstraints.weighty = 1; + buttonsPanel.add(new JPanel(), gbConstraints); + + myAddButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + TableUtil.stopEditing(myTable); + myTableModel.addRow(); + final int index = myTableModel.getRowCount() - 1; + myTable.editCellAt(index, 0); + myTable.setRowSelectionInterval(index, index); + myTable.setColumnSelectionInterval(0, 0); + final Component editorComponent = myTable.getEditorComponent(); + if (editorComponent != null) { + final Rectangle bounds = editorComponent.getBounds(); + myTable.scrollRectToVisible(bounds); + editorComponent.requestFocus(); + } + } + } + ); + + myRemoveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + TableUtil.stopEditing(myTable); + int index = myTable.getSelectedRow(); + if (0 <= index && index < myTableModel.getRowCount()) { + myTableModel.removeRow(index); + if (index < myTableModel.getRowCount()) { + myTable.setRowSelectionInterval(index, index); + } + else { + if (index > 0) { + myTable.setRowSelectionInterval(index - 1, index - 1); + } + } + updateButtons(); + } + + myTable.requestFocus(); + } + } + ); + + myUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + TableUtil.stopEditing(myTable); + int index = myTable.getSelectedRow(); + if (0 < index && index < myTableModel.getRowCount()) { + myTableModel.exchangeRows(index, index - 1); + myTable.setRowSelectionInterval(index - 1, index - 1); + } + myTable.requestFocus(); + } + } + ); + + myDownButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + TableUtil.stopEditing(myTable); + int index = myTable.getSelectedRow(); + if (0 <= index && index < myTableModel.getRowCount() - 1) { + myTableModel.exchangeRows(index, index + 1); + myTable.setRowSelectionInterval(index + 1, index + 1); + } + myTable.requestFocus(); + } + } + ); + + myTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateButtons(); + } + } + ); + updateButtons(); + + return buttonsPanel; + } + + public void updateButtons() { + int index = myTable.getSelectedRow(); + if (0 <= index && index < myTableModel.getRowCount()) { + myRemoveButton.setEnabled(true); + myUpButton.setEnabled(index > 0); + myDownButton.setEnabled(index < myTableModel.getRowCount() - 1); + } + else { + myRemoveButton.setEnabled(false); + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + myAddButton.setEnabled(true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EnableDisableAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EnableDisableAction.java new file mode 100644 index 00000000000..65819b11f26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/EnableDisableAction.java @@ -0,0 +1,41 @@ +package com.intellij.refactoring.ui; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +/** + * @author dsl + */ +public abstract class EnableDisableAction extends AbstractAction { + public void actionPerformed(ActionEvent e) { + if (getTable().isEditing()) return; + int[] rows = getTable().getSelectedRows(); + if (rows.length > 0) { + boolean valueToBeSet = false; + for (int idx = 0; idx < rows.length; idx++) { + final int row = rows[idx]; + if (!isRowChecked(row)) { + valueToBeSet = true; + break; + } + } + applyValue(rows, valueToBeSet); +// myMyTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); + } + getTable().requestFocus(); + } + + protected abstract JTable getTable(); + + protected abstract void applyValue(int[] rows, boolean valueToBeSet); + + protected abstract boolean isRowChecked(int row); + + public void register() {// make SPACE check/uncheck selected rows + JTable table = getTable(); + InputMap inputMap = table.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + table.getActionMap().put("enable_disable", this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/InfoDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/InfoDialog.java new file mode 100644 index 00000000000..5878857fd95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/InfoDialog.java @@ -0,0 +1,70 @@ + +package com.intellij.refactoring.ui; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.*; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.project.Project; + +public class InfoDialog extends DialogWrapper{ + private JCheckBox myShowInFutureCheckBox; + private JTextArea myTextArea; + private String myText; + private boolean isToShowInFuture; + + public InfoDialog(String text, Project project) { + super(project, false); + myText = text; + setButtonsAlignment(SwingUtilities.CENTER); + setTitle("Information"); + setButtonsMargin(null); + init(); + setOKButtonText("OK"); + } + + protected Action[] createActions(){ + return new Action[]{getOKAction()}; + } + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(); + panel.setBorder(BorderFactory.createEtchedBorder()); + panel.setLayout(new BorderLayout()); + + JPanel cbPanel = new JPanel(new BorderLayout()); + cbPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10)); + myShowInFutureCheckBox = new JCheckBox("Do not show this message in the future"); + myShowInFutureCheckBox.setMnemonic('D'); + panel.add(cbPanel, BorderLayout.SOUTH); + cbPanel.add(myShowInFutureCheckBox, BorderLayout.WEST); + + JPanel textPanel = new JPanel(new BorderLayout()); + textPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + panel.add(textPanel, BorderLayout.CENTER); + + myTextArea = new JTextArea(myText); + textPanel.add(myTextArea, BorderLayout.CENTER); + myTextArea.setEditable(false); + myTextArea.setBackground(UIManager.getColor("Panel.background")); + Font font = myShowInFutureCheckBox.getFont(); + font = new Font(font.getName(), font.getStyle(), font.getSize() + 1); + myTextArea.setFont(font); + myShowInFutureCheckBox.setFont(font); + isToShowInFuture = true; + myShowInFutureCheckBox.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent event) { + isToShowInFuture = !myShowInFutureCheckBox.isSelected(); + } + } + ); + return panel; + } + + public boolean isToShowInFuture() { + return isToShowInFuture; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionPanel.java new file mode 100644 index 00000000000..ae1beba44a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionPanel.java @@ -0,0 +1,42 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 18.06.2002 + * Time: 13:19:44 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.ui; + +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; + +public class MemberSelectionPanel extends JPanel { + private final MemberSelectionTable myTable; + + public MemberSelectionPanel(String title, MemberInfo[] memberInfo, String abstractColumnHeader) { + super(); + Border titledBorder = IdeBorderFactory.createTitledBorder(title); + Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5); + Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder); + setBorder(border); + setLayout(new BorderLayout()); + + myTable = new MemberSelectionTable(memberInfo, abstractColumnHeader); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + + + add(scrollPane, BorderLayout.CENTER); + } + + public MemberSelectionTable getTable() { + return myTable; + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionTable.java new file mode 100644 index 00000000000..7bf53db0ce6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MemberSelectionTable.java @@ -0,0 +1,393 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 17.06.2002 + * Time: 16:35:43 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.ui; + +import com.intellij.ide.IconUtilEx; +import com.intellij.openapi.actionSystem.impl.EmptyIcon; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.*; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoChange; +import com.intellij.refactoring.util.classMembers.MemberInfoChangeListener; +import com.intellij.refactoring.util.classMembers.MemberInfoModel; +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.ui.RowIcon; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.util.ArrayList; + +public class MemberSelectionTable extends Table { + private static final int CHECKED_COLUMN = 0; + private static final int DISPLAY_NAME_COLUMN = 1; + private static final int ABSTRACT_COLUMN = 2; + private static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/general/overridingMethod.png"); + private static final Icon IMPLEMENTING_METHOD_ICON = IconLoader.getIcon("/general/implementingMethod.png"); + private static final Icon EMPTY_OVERRIDE_ICON = EmptyIcon.create(16, 16); + private final String myAbstractColumnHeader; + private static final String DISPLAY_NAME_COLUMN_HEADER = "Member"; + + private MemberInfo[] myMemberInfos; + private final boolean myAbstractEnabled; + private MemberInfoModel myMemberInfoModel; + private MyTableModel myMyTableModel; + + + private static class DefaultMemberInfoModel implements MemberInfoModel { + public boolean isMemberEnabled(MemberInfo member) { + return true; + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return false; + } + + public boolean isAbstractEnabled(MemberInfo member) { + return true; + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + return false; + } + + + public int checkForProblems(MemberInfo member) { + return OK; + } + + public void memberInfoChanged(MemberInfoChange event) { + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } + + public String getTooltipText(MemberInfo member) { + return null; + } + } + + private static final DefaultMemberInfoModel defaultMemberInfoModel = new DefaultMemberInfoModel(); + + public MemberSelectionTable(final MemberInfo[] memberInfos, String abstractColumnHeader) { + this(memberInfos, null, abstractColumnHeader); + } + + public MemberSelectionTable(final MemberInfo[] memberInfos, + MemberInfoModel memberInfoModel, + String abstractColumnHeader) { + super(); + myAbstractEnabled = abstractColumnHeader != null; + myAbstractColumnHeader = abstractColumnHeader; + myMyTableModel = new MyTableModel(); + setModel(myMyTableModel); + myMemberInfos = memberInfos; + if (memberInfoModel != null) { + myMemberInfoModel = memberInfoModel; + } + else { + myMemberInfoModel = defaultMemberInfoModel; + } + + + +// myTable.setTableHeader(null); +// this.setDefaultRenderer(Boolean.class, new MyBooleanRenderer()); + TableColumnModel columnModel = this.getColumnModel(); + columnModel.getColumn(DISPLAY_NAME_COLUMN).setCellRenderer(new MyTableRenderer()); + columnModel.getColumn(CHECKED_COLUMN).setCellRenderer(new MyBooleanRenderer()); + final int checkBoxWidth = new JCheckBox().getPreferredSize().width; + columnModel.getColumn(CHECKED_COLUMN).setMaxWidth(checkBoxWidth); + columnModel.getColumn(CHECKED_COLUMN).setMinWidth(checkBoxWidth); + + if (myAbstractEnabled) { + int width = + (int)(1.3 * + this.getFontMetrics(this.getFont()).charsWidth(myAbstractColumnHeader.toCharArray(), 0, + myAbstractColumnHeader.length())); + columnModel.getColumn(ABSTRACT_COLUMN).setMaxWidth(width); + columnModel.getColumn(ABSTRACT_COLUMN).setPreferredWidth(width); + columnModel.getColumn(ABSTRACT_COLUMN).setCellRenderer(new MyBooleanRenderer()); + } + + this.setPreferredScrollableViewportSize(new Dimension(400, this.getRowHeight() * 12)); + this.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + this.setShowGrid(false); + this.setIntercellSpacing(new Dimension(0, 0)); + + new MyEnableDisableAction().register(); + } + + public MemberInfo[] getSelectedMemberInfos() { + ArrayList list = new ArrayList(myMemberInfos.length); + for (int idx = 0; idx < myMemberInfos.length; idx++) { + MemberInfo info = myMemberInfos[idx]; + final boolean memberEnabled = myMemberInfoModel.isMemberEnabled(info); + if ((memberEnabled && info.isChecked()) || (!memberEnabled && myMemberInfoModel.isCheckedWhenDisabled(info))) { +// if (info.isChecked() || (!myMemberInfoModel.isMemberEnabled(info) && myMemberInfoModel.isCheckedWhenDisabled(info))) { + list.add(info); + } + } + return list.toArray(new MemberInfo[list.size()]); + } + + public MemberInfoModel getMemberInfoModel() { + return myMemberInfoModel; + } + + public void setMemberInfoModel(MemberInfoModel memberInfoModel) { + myMemberInfoModel = memberInfoModel; + } + + public void fireExternalDataChange() { + myMyTableModel.fireTableDataChanged(); + } + + public void setMemberInfos(MemberInfo[] memberInfos) { + myMemberInfos = memberInfos; + fireMemberInfoChange(memberInfos); + myMyTableModel.fireTableDataChanged(); + } + + public void addMemberInfoChangeListener(MemberInfoChangeListener l) { + listenerList.add(MemberInfoChangeListener.class, l); + } + + protected void fireMemberInfoChange(MemberInfo[] changedMembers) { + Object[] list = listenerList.getListenerList(); + + MemberInfoChange event = new MemberInfoChange(changedMembers); + for (int i = 0; i < list.length; i++) { + if (list[i] instanceof MemberInfoChangeListener) { + ((MemberInfoChangeListener)list[i]).memberInfoChanged(event); + } + } + } + + private class MyTableModel extends AbstractTableModel { + public int getColumnCount() { + if (myAbstractEnabled) { + return 3; + } + else { + return 2; + } + } + + public int getRowCount() { + return myMemberInfos.length; + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == MemberSelectionTable.CHECKED_COLUMN || columnIndex == MemberSelectionTable.ABSTRACT_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + final MemberInfo memberInfo = myMemberInfos[rowIndex]; + switch (columnIndex) { + case MemberSelectionTable.CHECKED_COLUMN: + if (myMemberInfoModel.isMemberEnabled(memberInfo)) { + return memberInfo.isChecked() ? Boolean.TRUE : Boolean.FALSE; + } + else { + return Boolean.valueOf(myMemberInfoModel.isCheckedWhenDisabled(memberInfo)); + } + case MemberSelectionTable.ABSTRACT_COLUMN: + { + if (!(memberInfo.getMember() instanceof PsiMethod)) return null; + if (memberInfo.isStatic()) return null; + + PsiMethod method = (PsiMethod)memberInfo.getMember(); + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + final Boolean fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo); + if (fixedAbstract != null) return fixedAbstract; + } + + if (!myMemberInfoModel.isAbstractEnabled(memberInfo)) { + return Boolean.valueOf(myMemberInfoModel.isAbstractWhenDisabled(memberInfo)); + } + else { + return memberInfo.isToAbstract() ? Boolean.TRUE : Boolean.FALSE; + } + } + case MemberSelectionTable.DISPLAY_NAME_COLUMN: + return memberInfo.getDisplayName(); + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public String getColumnName(int column) { + switch (column) { + case MemberSelectionTable.CHECKED_COLUMN: + return " "; + case MemberSelectionTable.ABSTRACT_COLUMN: + return myAbstractColumnHeader; + case MemberSelectionTable.DISPLAY_NAME_COLUMN: + return MemberSelectionTable.DISPLAY_NAME_COLUMN_HEADER; + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case MemberSelectionTable.CHECKED_COLUMN: + return myMemberInfoModel.isMemberEnabled(myMemberInfos[rowIndex]); + case MemberSelectionTable.ABSTRACT_COLUMN: + { + MemberInfo info = myMemberInfos[rowIndex]; + if (!(info.getMember() instanceof PsiMethod)) return false; + + PsiMethod method = (PsiMethod)info.getMember(); + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (myMemberInfoModel.isFixedAbstract(info) != null) { + return false; + } + } + + return info.isChecked() && myMemberInfoModel.isAbstractEnabled(info); + } + } + return false; + } + + public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) { + if (columnIndex == MemberSelectionTable.CHECKED_COLUMN) { + myMemberInfos[rowIndex].setChecked(((Boolean)aValue).booleanValue()); + } + else if (columnIndex == MemberSelectionTable.ABSTRACT_COLUMN) { + myMemberInfos[rowIndex].setToAbstract(((Boolean)aValue).booleanValue()); + } + + MemberInfo[] changed = {myMemberInfos[rowIndex]}; + fireMemberInfoChange(changed); + fireTableDataChanged(); +// fireTableRowsUpdated(rowIndex, rowIndex); + } + } + + private class MyTableRenderer extends ColoredTableCellRenderer { + public void customizeCellRenderer(JTable table, final Object value, + boolean isSelected, boolean hasFocus, final int row, final int column) { + + final int modelColumn = convertColumnIndexToModel(column); + final MemberInfo memberInfo = myMemberInfos[row]; + this.setToolTipText(myMemberInfoModel.getTooltipText(memberInfo)); + PsiElement member = memberInfo.getMember(); + switch (modelColumn) { + case MemberSelectionTable.DISPLAY_NAME_COLUMN: + { + Icon memberIcon = member.getIcon(0); + Icon overrideIcon = MemberSelectionTable.EMPTY_OVERRIDE_ICON; + if (member instanceof PsiMethod) { + if (Boolean.TRUE.equals(memberInfo.getOverrides())) { + overrideIcon = MemberSelectionTable.OVERRIDING_METHOD_ICON; + } + else if (Boolean.FALSE.equals(memberInfo.getOverrides())) { + overrideIcon = MemberSelectionTable.IMPLEMENTING_METHOD_ICON; + } + else { + overrideIcon = MemberSelectionTable.EMPTY_OVERRIDE_ICON; + } + } + + RowIcon icon = new RowIcon(3); + icon.setIcon(memberIcon, 0); + PsiModifierList modifiers = member instanceof PsiModifierListOwner ? ((PsiModifierListOwner)member).getModifierList() : null; + if (modifiers != null) { + IconUtilEx.setVisibilityIcon(modifiers, icon); + } + else { + icon.setIcon(IconUtilEx.getEmptyIcon(true), 1); + } + icon.setIcon(overrideIcon, 2); + MyTableRenderer.this.setIcon(icon); + break; + } + default: + { + MyTableRenderer.this.setIcon(null); + } + } + final boolean cellEditable = myMemberInfoModel.isMemberEnabled(memberInfo); + this.setEnabled(cellEditable); + + final int problem = myMemberInfoModel.checkForProblems(memberInfo); + Color c = null; + if (problem == MemberInfoModel.ERROR) { + c = Color.red; + } + else if (problem == MemberInfoModel.WARNING && !isSelected) { + c = Color.blue; + } + append((String)value, new SimpleTextAttributes(Font.PLAIN, c)); + } + } + + private class MyBooleanRenderer extends BooleanTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (component instanceof JComponent) { + JComponent jComponent = (JComponent)component; + int modelColumn = convertColumnIndexToModel(column); + final MemberInfo memberInfo = myMemberInfos[row]; + boolean fixedAbstract = false; + final PsiElement member = memberInfo.getMember(); + if (modelColumn == ABSTRACT_COLUMN && member instanceof PsiMethod + && ((PsiMethod)member).hasModifierProperty(PsiModifier.ABSTRACT)) { + fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo) != null; + } + + jComponent.setEnabled( + (modelColumn == MemberSelectionTable.CHECKED_COLUMN + && myMemberInfoModel.isMemberEnabled(memberInfo) + || (modelColumn == ABSTRACT_COLUMN + && memberInfo.isChecked() + && memberInfo.getMember() instanceof PsiMethod + && !fixedAbstract + && myMemberInfoModel.isAbstractEnabled(memberInfo))) + ); + } + return component; + } + } + + private class MyEnableDisableAction extends EnableDisableAction { + + protected JTable getTable() { + return MemberSelectionTable.this; + } + + protected void applyValue(int[] rows, boolean valueToBeSet) { + MemberInfo[] changedInfo = new MemberInfo[rows.length]; + for (int idx = 0; idx < rows.length; idx++) { + final MemberInfo memberInfo = myMemberInfos[rows[idx]]; + memberInfo.setChecked(valueToBeSet); + changedInfo[idx] = memberInfo; + } + fireMemberInfoChange(changedInfo); + myMyTableModel.fireTableDataChanged(); + } + + protected boolean isRowChecked(final int row) { + return myMemberInfos[row].isChecked(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MethodCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MethodCellRenderer.java new file mode 100644 index 00000000000..25e586ac3b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/MethodCellRenderer.java @@ -0,0 +1,37 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.util.Iconable; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiFormatUtil; + +import javax.swing.*; +import java.awt.*; + +/** + * @author dsl + */ +public class MethodCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + PsiMethod method = (PsiMethod) value; + + final String text = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + setText(text); + + final int flags = Iconable.ICON_FLAG_VISIBILITY; + + Icon icon = method.getIcon(flags); + if(icon != null) setIcon(icon); + return this; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsField.java new file mode 100644 index 00000000000..6c8dd32de54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsField.java @@ -0,0 +1,205 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.*; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.EventListener; + +public class NameSuggestionsField implements Focusable { + private final JComponent myComponent; + private EventListenerList myListenerList = new EventListenerList(); + private final MyComboBoxModel myComboBoxModel; + private final Project myProject; + + public NameSuggestionsField(Project project) { + myProject = project; + myComboBoxModel = new MyComboBoxModel(); + final ComboBox comboBox = new ComboBox(myComboBoxModel,-1); + myComponent = comboBox; + setupComboBox(comboBox, StdFileTypes.JAVA); + } + + public NameSuggestionsField(String[] nameSuggestions, Project project) { + this(nameSuggestions, project, StdFileTypes.JAVA); + } + + public NameSuggestionsField(String[] nameSuggestions, Project project, FileType fileType) { + myProject = project; + if (nameSuggestions == null || nameSuggestions.length <= 1) { + myComponent = createTextFieldForName(nameSuggestions, fileType); + } + else { + final ComboBox combobox = new ComboBox(nameSuggestions,-1); + combobox.setSelectedIndex(0); + setupComboBox(combobox, fileType); + myComponent = combobox; + } + myComboBoxModel = null; + } + + public void setSuggestions(final String[] suggestions) { + if(myComboBoxModel == null) return; + JComboBox comboBox = (JComboBox) myComponent; + final String oldSelectedItem = (String)comboBox.getSelectedItem(); + final String oldItemFromTextField = (String) comboBox.getEditor().getItem(); + final boolean shouldUpdateTextField = + oldItemFromTextField.equals(oldSelectedItem) || oldItemFromTextField.trim().length() == 0; + myComboBoxModel.setSuggestions(suggestions); + if(suggestions.length > 0 && shouldUpdateTextField) { + comboBox.setSelectedIndex(0); + } + } + + public boolean isNameSuggestionsChangeable() { + return myComboBoxModel != null; + } + + public JComponent getComponent(){ + return myComponent; + } + + public Component getFocusableComponent() { + if(myComponent instanceof JComboBox) { + return ((JComboBox) myComponent).getEditor().getEditorComponent(); + } else { + return myComponent; + } + } + + public String getName() { + if (myComponent instanceof JComboBox) { + return (String)((JComboBox)myComponent).getEditor().getItem(); + } else { + return ((EditorTextField) myComponent).getText(); + } + } + + private JComponent createTextFieldForName(String[] nameSuggestions, FileType fileType) { + final String text; + if (nameSuggestions != null && nameSuggestions.length > 0) { + text = nameSuggestions[0]; + } + else { + text = ""; + } + + EditorTextField field = new EditorTextField(text, myProject, fileType); + field.selectAll(); + field.addDocumentListener(new DocumentListener() { + public void beforeDocumentChange(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + fireDataChanged(); + } + }); + + return field; + } + + private static class MyComboBoxModel extends DefaultComboBoxModel { + private String[] mySuggestions; + + MyComboBoxModel() { + mySuggestions = ArrayUtil.EMPTY_STRING_ARRAY; + } + + // implements javax.swing.ListModel + public int getSize() { + return mySuggestions.length; + } + + // implements javax.swing.ListModel + public Object getElementAt(int index) { + return mySuggestions[index]; + } + + public void setSuggestions(String[] suggestions) { + fireIntervalRemoved(this, 0, mySuggestions.length); + mySuggestions = suggestions; + fireIntervalAdded(this, 0, mySuggestions.length); + } + + } + + private void setupComboBox(final ComboBox combobox, FileType fileType) { + final EditorComboBoxEditor comboEditor = new StringComboboxEditor(myProject, fileType); + + combobox.setEditor(comboEditor); + combobox.setRenderer(new EditorComboBoxRenderer(comboEditor)); + + combobox.setEditable(true); + combobox.setMaximumRowCount(8); + + combobox.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + fireDataChanged(); + } + } + ); + + + ((EditorTextField)combobox.getEditor().getEditorComponent()).addDocumentListener(new DocumentListener() { + public void beforeDocumentChange(DocumentEvent event) { + + } + + public void documentChanged(DocumentEvent event) { + fireDataChanged(); + } + } + ); + } + + public Editor getEditor () { + if (myComponent instanceof EditorTextField) { + return ((EditorTextField)myComponent).getEditor(); + } else { + return ((EditorTextField)(((JComboBox)myComponent).getEditor().getEditorComponent())).getEditor(); + } + } + + public static interface DataChanged extends EventListener { + void dataChanged(); + } + + public void addDataChangedListener(DataChanged listener) { + myListenerList.add(DataChanged.class, listener); + } + + private void fireDataChanged() { + Object[] list = myListenerList.getListenerList(); + + for (int i = 0; i < list.length; i++) { + if (list[i] instanceof DataChanged) { + ((DataChanged) list[i]).dataChanged(); + } + } + } + + public void requestFocusInWindow() { + if(myComponent instanceof JComboBox) { + ((JComboBox) myComponent).getEditor().getEditorComponent().requestFocusInWindow(); + } + else { + myComponent.requestFocusInWindow(); + } + } + + public void setEnabled (boolean enabled) { + myComponent.setEnabled(enabled); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsGenerator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsGenerator.java new file mode 100644 index 00000000000..37eb2100c38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsGenerator.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.ui; + +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.*; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.openapi.util.Pair; + +import java.util.Set; + +public interface NameSuggestionsGenerator { + SuggestedNameInfo getSuggestedNameInfo(PsiType type); + + Pair> completeVariableName(String prefix, PsiType type); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsManager.java new file mode 100644 index 00000000000..d4cf61b4618 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/NameSuggestionsManager.java @@ -0,0 +1,95 @@ +package com.intellij.refactoring.ui; + +import com.intellij.codeInsight.lookup.CharFilter; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiType; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.awt.event.*; +import java.util.Set; + +/** + * @author dsl + */ +public class NameSuggestionsManager { + private final TypeSelector myTypeSelector; + private final NameSuggestionsField myNameField; + private final NameSuggestionsGenerator myGenerator; + private final Project myProject; + + private final HashMap myTypesToSuggestions = new HashMap(); + + public NameSuggestionsManager(TypeSelector typeSelector, NameSuggestionsField nameField, + NameSuggestionsGenerator generator, Project project) { + myTypeSelector = typeSelector; + myNameField = nameField; + myGenerator = generator; + myProject = project; + + myTypeSelector.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + updateSuggestions(myTypeSelector.getSelectedType()); + } + } + }); + updateSuggestions(myTypeSelector.getSelectedType()); + + myNameField.getComponent().registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + completeVariable(myNameField.getEditor()); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + private void completeVariable(Editor editor) { + String prefix = myNameField.getName(); + Pair> pair = myGenerator.completeVariableName(prefix, myTypeSelector.getSelectedType()); + LookupItem[] lookupItems = pair.second.toArray(new LookupItem[pair.second.size()]); + editor.getCaretModel().moveToOffset(prefix.length()); + editor.getSelectionModel().removeSelection(); + LookupItemPreferencePolicy first = pair.first; + LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix, first, new CharFilter() { + public int accept(char c) { + if (Character.isJavaIdentifierPart(c)) return CharFilter.ADD_TO_PREFIX; + return CharFilter.SELECT_ITEM_AND_FINISH_LOOKUP; + } + }); + } + + public void nameSelected() { + SuggestedNameInfo nameInfo = myTypesToSuggestions.get(myTypeSelector.getSelectedType()); + + if (nameInfo != null) { + nameInfo.nameChoosen(myNameField.getName()); + } + } + + private void updateSuggestions(PsiType selectedType) { + SuggestedNameInfo nameInfo = myTypesToSuggestions.get(selectedType); + if (nameInfo == null) { + nameInfo = myGenerator.getSuggestedNameInfo(selectedType); + myTypesToSuggestions.put(selectedType, nameInfo); + } + myNameField.setSuggestions(nameInfo.names); + } + + public void setMnemonics(JLabel typeSelectorLabel, JLabel nameLabel) { + if(myTypeSelector.getFocusableComponent() != null) { + typeSelectorLabel.setDisplayedMnemonic(KeyEvent.VK_T); + typeSelectorLabel.setLabelFor(myTypeSelector.getFocusableComponent()); + } + + if(myNameField.getFocusableComponent() != null) { + nameLabel.setDisplayedMnemonic(KeyEvent.VK_N); + nameLabel.setLabelFor(myNameField.getFocusableComponent()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/RowEditableTableModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/RowEditableTableModel.java new file mode 100644 index 00000000000..538a8af8eef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/RowEditableTableModel.java @@ -0,0 +1,14 @@ +package com.intellij.refactoring.ui; + +import javax.swing.table.TableModel; + +/** + * @author dsl + */ +public interface RowEditableTableModel extends TableModel { + void addRow(); + + void removeRow(int index); + + void exchangeRows(int index1, int index2); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/StringTableCellEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/StringTableCellEditor.java new file mode 100644 index 00000000000..f0e6de15094 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/StringTableCellEditor.java @@ -0,0 +1,36 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.ui.EditorTextField; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; + +/** + * @author dsl + */ +public class StringTableCellEditor extends AbstractCellEditor implements TableCellEditor { + private Document myDocument; + private final Project myProject; + + public StringTableCellEditor(final Project project) { + myProject = project; + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + final EditorTextField editorTextField = new EditorTextField((String) value, myProject, StdFileTypes.JAVA) { + protected boolean shouldHaveBorder() { + return false; + } + }; + myDocument = editorTextField.getDocument(); + return editorTextField; + } + + public Object getCellEditorValue() { + return myDocument.getText(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeListCreatingVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeListCreatingVisitor.java new file mode 100644 index 00000000000..de09f206727 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeListCreatingVisitor.java @@ -0,0 +1,34 @@ +package com.intellij.refactoring.ui; + +import com.intellij.psi.*; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; + +import java.util.ArrayList; +import java.util.HashSet; + +class TypeListCreatingVisitor implements RefactoringHierarchyUtil.SuperTypeVisitor { + private final ArrayList myList; + private final PsiElementFactory myFactory; + private final HashSet mySet; + + public TypeListCreatingVisitor(ArrayList result, PsiElementFactory factory) { + myList = result; + myFactory = factory; + mySet = new HashSet(); + } + + public void visitType(PsiType aType) { + if (!mySet.contains(aType)) { + myList.add(aType); + mySet.add(aType); + } + } + + public void visitClass(PsiClass aClass) { + final PsiType type = myFactory.createType(aClass); + if (!mySet.contains(type)) { + myList.add(type); + mySet.add(type); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelector.java new file mode 100644 index 00000000000..39815b96c57 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelector.java @@ -0,0 +1,137 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.ui.ComboBox; +import com.intellij.psi.PsiType; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemListener; + +/** + * @author dsl + */ +public class TypeSelector { + private final PsiType myType; + private final JComponent myComponent; + private final MyComboBoxModel myComboBoxModel; + + public TypeSelector(PsiType type) { + myType = type; + myComponent = new JLabel(myType.getCanonicalText()); + myComboBoxModel = null; + } + + public TypeSelector() { + myComboBoxModel = new MyComboBoxModel(); + myComponent = new ComboBox(); + ((ComboBox) myComponent).setModel(myComboBoxModel); + ((ComboBox) myComponent).setRenderer(new MyListCellRenderer()); + myType = null; + } + + public void setTypes(PsiType[] types) { + if(myComboBoxModel == null) return; + PsiType oldType; + if (myComboBoxModel.getSize() > 0) { + oldType = (PsiType) myComboBoxModel.getSelectedItem(); + } else { + oldType = null; + } + myComboBoxModel.setSuggestions(types); + if(oldType != null) { + for (int i = 0; i < types.length; i++) { + PsiType type = types[i]; + if(type.equals(oldType)) { + ((JComboBox) myComponent).setSelectedIndex(i); + return; + } + } + } + ((JComboBox) myComponent).setSelectedIndex(0); + } + + + public void addItemListener(ItemListener aListener) { + if(myComponent instanceof JComboBox) { + ((JComboBox) myComponent).addItemListener(aListener); + } + } + + public void removeItemListener(ItemListener aListener) { + if (myComponent instanceof JComboBox) { + ((JComboBox) myComponent).removeItemListener(aListener); + } + } + + public ItemListener[] getItemListeners() { + if (myComponent instanceof JComboBox) { + return ((JComboBox) myComponent).getItemListeners(); + } else { + return new ItemListener[0]; + } + } + + public JComponent getComponent() { + return myComponent; + } + + public JComponent getFocusableComponent() { + if (myComponent instanceof JComboBox) { + return myComponent; + } else { + return null; + } + } + + public PsiType getSelectedType() { + if (myComponent instanceof JLabel) { + return myType; + } else { + return (PsiType) ((JComboBox) myComponent).getSelectedItem(); + } + } + + private static class MyComboBoxModel extends DefaultComboBoxModel { + private PsiType[] mySuggestions; + + MyComboBoxModel() { + mySuggestions = new PsiType[0]; + } + + // implements javax.swing.ListModel + public int getSize() { + return mySuggestions.length; + } + + // implements javax.swing.ListModel + public Object getElementAt(int index) { + return mySuggestions[index]; + } + + public void setSuggestions(PsiType[] suggestions) { + fireIntervalRemoved(this, 0, mySuggestions.length); + mySuggestions = suggestions; + fireIntervalAdded(this, 0, mySuggestions.length); + } + } + + + + private class MyListCellRenderer extends DefaultListCellRenderer { + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + if (value != null) { + setText(((PsiType) value).getCanonicalText()); + } + + return this; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManager.java new file mode 100644 index 00000000000..0b8cf85faa1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManager.java @@ -0,0 +1,10 @@ +package com.intellij.refactoring.ui; + +/** + * @author dsl + */ +public interface TypeSelectorManager { + TypeSelector getTypeSelector(); + + void setAllOccurences(boolean allOccurences); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java new file mode 100644 index 00000000000..3ce3f56fa57 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -0,0 +1,200 @@ +package com.intellij.refactoring.ui; + +import com.intellij.codeInsight.*; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author dsl + */ +public class TypeSelectorManagerImpl implements TypeSelectorManager { + private final PsiType myDefaultType; + private final PsiExpression myMainOccurence; + private final PsiExpression[] myOccurences; + private final PsiType[] myTypesForMain; + private final PsiType[] myTypesForAll; + private final boolean myIsOneSuggestion; + private TypeSelector myTypeSelector; + private final PsiElementFactory myFactory; + private ExpectedTypesProviderImpl.ExpectedClassProvider myOccurrenceClassProvider; + private ExpectedTypesProvider myExpectedTypesProvider; + + public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurence, PsiExpression[] occurences) { + myFactory = PsiManager.getInstance(project).getElementFactory(); + myDefaultType = type; + myMainOccurence = mainOccurence; + myOccurences = occurences; + myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); + + myOccurrenceClassProvider = createOccurrenceClassProvider(); + myTypesForMain = getTypesForMain(); + myTypesForAll = getTypesForAll(); + + myIsOneSuggestion = + myTypesForMain.length == 1 && myTypesForAll.length == 1 && + myTypesForAll[0].equals(myTypesForMain[0]); + if (myIsOneSuggestion) { + myTypeSelector = new TypeSelector(myTypesForAll[0]); + } + else { + myTypeSelector = new TypeSelector(); + } + } + + public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression[] occurences) { + myFactory = PsiManager.getInstance(project).getElementFactory(); + myDefaultType = type; + myMainOccurence = null; + myOccurences = occurences; + myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); + myOccurrenceClassProvider = createOccurrenceClassProvider(); + myTypesForAll = getTypesForAll(); + myTypesForMain = null; + myIsOneSuggestion = true; + myTypeSelector = new TypeSelector(); + myTypeSelector.setTypes(myTypesForAll); + } + + private ExpectedTypesProvider.ExpectedClassProvider createOccurrenceClassProvider() { + final Set occurrenceClasses = new HashSet(); + for (int i = 0; i < myOccurences.length; i++) { + final PsiExpression occurence = myOccurences[i]; + final PsiType occurrenceType = occurence.getType(); + final PsiClass aClass = PsiUtil.resolveClassInType(occurrenceType); + if (aClass != null) { + occurrenceClasses.add(aClass); + } + } + final ExpectedTypesProvider.ExpectedClassProvider expectedClassProvider = new ExpectedTypeUtil.ExpectedClassesFromSetProvider(occurrenceClasses); + return expectedClassProvider; + } + + private PsiType[] getTypesForMain() { + final ExpectedTypeInfo[] expectedTypes = myExpectedTypesProvider.getExpectedTypes(myMainOccurence, false, myOccurrenceClassProvider); + final ArrayList allowedTypes = new ArrayList(); + RefactoringHierarchyUtil.processSuperTypes(myDefaultType, new RefactoringHierarchyUtil.SuperTypeVisitor() { + public void visitType(PsiType aType) { + checkIfAllowed(aType); + } + + public void visitClass(PsiClass aClass) { + checkIfAllowed(myFactory.createType(aClass)); + } + + private void checkIfAllowed(PsiType type) { + if (expectedTypes.length > 0) { + final ExpectedTypeInfo + typeInfo = myExpectedTypesProvider.createInfo(type, ExpectedTypeInfo.TYPE_STRICTLY, type, TailType.NONE); + for (int i = 0; i < expectedTypes.length; i++) { + ExpectedTypeInfo expectedType = expectedTypes[i]; + if (expectedType.intersect(typeInfo).length != 0) { + allowedTypes.add(type); + break; + } + } + } + else { + allowedTypes.add(type); + } + } + }); + + ArrayList result = normalizeTypeList(allowedTypes); + return result.toArray(new PsiType[result.size()]); + +// return getSuggestions(expectedTypeInfos); + } + + private PsiType[] getTypesForAll() { + final ArrayList expectedTypesFromAll = new ArrayList(); + for (int i = 0; i < myOccurences.length; i++) { + + final ExpectedTypeInfo[] expectedTypes = myExpectedTypesProvider.getExpectedTypes(myOccurences[i], false, myOccurrenceClassProvider); + if (expectedTypes.length > 0) { + expectedTypesFromAll.add(expectedTypes); + } + } + + final ArrayList allowedTypes = new ArrayList(); + RefactoringHierarchyUtil.processSuperTypes(myDefaultType, new RefactoringHierarchyUtil.SuperTypeVisitor() { + public void visitType(PsiType aType) { + checkIfAllowed(aType); + } + + public void visitClass(PsiClass aClass) { + checkIfAllowed(myFactory.createType(aClass)); + } + + private void checkIfAllowed(PsiType type) { + final ExpectedTypeInfo + typeInfo = myExpectedTypesProvider.createInfo(type, ExpectedTypeInfo.TYPE_STRICTLY, type, TailType.NONE); + for (Iterator iterator = expectedTypesFromAll.iterator(); iterator.hasNext();) { + ExpectedTypeInfo[] expectedTypes = iterator.next(); + boolean validFound = false; + for (int i = 0; i < expectedTypes.length; i++) { + ExpectedTypeInfo expectedType = expectedTypes[i]; + if (expectedType.intersect(typeInfo).length != 0) { + validFound = true; + break; + } + } + if (!validFound) return; + } + allowedTypes.add(type); + + } + }); + + final ArrayList result = normalizeTypeList(allowedTypes); + return result.toArray(new PsiType[result.size()]); +// expectedTypesFromAll.add(new ExpectedTypeInfoImpl[]{myDefaultExpectedTypeInfo}); +// final ExpectedTypeInfoImpl[] expectedTypeInfos = ExpectedTypeUtil.intersect(expectedTypesFromAll); +// return getSuggestions(expectedTypeInfos); + } + + private ArrayList normalizeTypeList(final ArrayList typeList) { + ArrayList result = new ArrayList(); + TypeListCreatingVisitor visitor = new TypeListCreatingVisitor(result, myFactory); + for (int i = 0; i < typeList.size(); i++) { + PsiType psiType = typeList.get(i); + visitor.visitType(psiType); + } + + for (int index = 0; index < result.size(); index++) { + PsiType psiType = result.get(index); + if (psiType.equals(myDefaultType)) { + result.remove(index); + break; + } + } + result.add(0, myDefaultType); + final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(myDefaultType); + if (unboxedType != null) { + result.remove(unboxedType); + result.add(0, unboxedType); + } + return result; + } + + public void setAllOccurences(boolean allOccurences) { + if (myIsOneSuggestion) return; + if (allOccurences) { + myTypeSelector.setTypes(myTypesForAll); + } + else { + myTypeSelector.setTypes(myTypesForMain); + } + } + + public TypeSelector getTypeSelector() { + return myTypeSelector; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/UsageViewDescriptorAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/UsageViewDescriptorAdapter.java new file mode 100644 index 00000000000..1ffb3cbfb16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/UsageViewDescriptorAdapter.java @@ -0,0 +1,81 @@ +package com.intellij.refactoring.ui; + +import com.intellij.psi.PsiElement; +import com.intellij.usageView.FindUsagesCommand; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; + +/** + * @author dsl + */ +public abstract class UsageViewDescriptorAdapter implements UsageViewDescriptor { + protected UsageInfo[] myUsages; + + public UsageViewDescriptorAdapter(UsageInfo[] usages, FindUsagesCommand refreshCommand) { + myUsages = usages; + myRefreshCommand = refreshCommand; + } + + + protected FindUsagesCommand myRefreshCommand; + + public UsageInfo[] getUsages() { + return myUsages; + } + + protected void refreshUsages(PsiElement[] elements) { + if (myRefreshCommand != null) { + myUsages = myRefreshCommand.execute(elements); + } + } + + + public boolean isSearchInText() { + return false; + } + + public boolean toMarkInvalidOrReadonlyUsages() { + return true; + } + + public String getCodeReferencesWord(){ + return REFERENCE_WORD; + } + + public String getCommentReferencesWord(){ + return null; + } + + public boolean isCancelInCommonGroup() { + return false; + } + + public boolean cancelAvailable() { + return true; + } + + public boolean canRefresh() { + return myRefreshCommand != null; + } + + public boolean willUsageBeChanged(UsageInfo usageInfo) { + return true; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "References to be changed " + UsageViewUtil.getUsageCountInfo(usagesCount, filesCount, "reference"); + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + + public String getHelpID() { + return "find.refactoringPreview"; + } + + public boolean canFilterMethods() { + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/VisibilityPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/VisibilityPanel.java new file mode 100644 index 00000000000..7227ede5005 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/VisibilityPanel.java @@ -0,0 +1,142 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 07.06.2002 + * Time: 18:16:19 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiModifier; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.EventListener; + +public class VisibilityPanel extends JPanel { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.ui.VisibilityPanel"); + + private JRadioButton myRbAsIs; + private JRadioButton myRbPrivate; + private JRadioButton myRbProtected; + private JRadioButton myRbPackageLocal; + private JRadioButton myRbPublic; + + public VisibilityPanel(boolean hasAsIs) { + setBorder(IdeBorderFactory.createTitledBorder("Visibility")); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + ButtonGroup bg = new ButtonGroup(); + + ItemListener listener = new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if(e.getStateChange() == ItemEvent.SELECTED) { + fireStateChanged(); + } + }; + }; + + if(hasAsIs) { + myRbAsIs = new JRadioButton("As is"); + myRbAsIs.setMnemonic('a'); + myRbAsIs.addItemListener(listener); + add(myRbAsIs); + bg.add(myRbAsIs); + } + + + + myRbPrivate = new JRadioButton("Private"); + myRbPrivate.setMnemonic('v'); + myRbPrivate.addItemListener(listener); + myRbPrivate.setFocusable(false); + add(myRbPrivate); + bg.add(myRbPrivate); + + myRbPackageLocal = new JRadioButton("Package local"); + myRbPackageLocal.setMnemonic('k'); + myRbPackageLocal.addItemListener(listener); + myRbPackageLocal.setFocusable(false); + add(myRbPackageLocal); + bg.add(myRbPackageLocal); + + myRbProtected = new JRadioButton("Protected"); + myRbProtected.setMnemonic('o'); + myRbProtected.addItemListener(listener); + myRbProtected.setFocusable(false); + add(myRbProtected); + bg.add(myRbProtected); + + myRbPublic = new JRadioButton("Public"); + myRbPublic.setMnemonic('b'); + myRbPublic.addItemListener(listener); + myRbPublic.setFocusable(false); + add(myRbPublic); + bg.add(myRbPublic); + } + + + public String getVisibility() { + if (myRbPublic.isSelected()) { + return PsiModifier.PUBLIC; + } + if (myRbPackageLocal.isSelected()) { + return PsiModifier.PACKAGE_LOCAL; + } + if (myRbProtected.isSelected()) { + return PsiModifier.PROTECTED; + } + if (myRbPrivate.isSelected()) { + return PsiModifier.PRIVATE; + } + + return null; + } + + public void setVisibilityEnabled(String visibility, boolean value) { + if(PsiModifier.PRIVATE.equals(visibility)) myRbPrivate.setEnabled(value); + else if(PsiModifier.PROTECTED.equals(visibility)) myRbProtected.setEnabled(value); + else if(PsiModifier.PACKAGE_LOCAL.equals(visibility)) myRbPackageLocal.setEnabled(value); + else if(PsiModifier.PUBLIC.equals(visibility)) myRbPublic.setEnabled(value); + } + + public void setVisibility(String visibility) { + if (PsiModifier.PUBLIC.equals(visibility)) { + myRbPublic.setSelected(true); + } + else if (PsiModifier.PROTECTED.equals(visibility)) { + myRbProtected.setSelected(true); + } + else if (PsiModifier.PACKAGE_LOCAL.equals(visibility)) { + myRbPackageLocal.setSelected(true); + } + else if (PsiModifier.PRIVATE.equals(visibility)) { + myRbPrivate.setSelected(true); + } + else { + LOG.assertTrue(myRbAsIs != null); + myRbAsIs.setSelected(true); + } + } + + public static interface StateChanged extends EventListener { + void visibilityChanged(String newVisibility); + } + + public void addStateChangedListener(StateChanged l) { + listenerList.add(StateChanged.class, l); + } + public void fireStateChanged() { + Object[] list = listenerList.getListenerList(); + + String visibility = getVisibility(); + for (int i = 0; i < list.length; i++) { + if(list[i] instanceof StateChanged) { + ((StateChanged) list[i]).visibilityChanged(visibility); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/YesNoPreviewUsagesDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/YesNoPreviewUsagesDialog.java new file mode 100644 index 00000000000..32fb5fb1674 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/ui/YesNoPreviewUsagesDialog.java @@ -0,0 +1,77 @@ +/** + * created at Oct 8, 2001 + * @author Jeka + */ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MultiLineLabelUI; + +import javax.swing.*; +import java.awt.*; + +public class YesNoPreviewUsagesDialog extends DialogWrapper { + private JCheckBox myCbPreviewResults; + private boolean myToPreviewUsages; + private final String myMessage; + private String myHelpID; + + public YesNoPreviewUsagesDialog(String title, String message, boolean previewUsages, + String helpID, Project project) { + super(project, false); + myHelpID = helpID; + setTitle(title); + myMessage = message; + myToPreviewUsages = previewUsages; + setOKButtonText("&Yes"); + setCancelButtonText("&No"); + setButtonsAlignment(SwingUtilities.CENTER); + init(); + } + + protected JComponent createNorthPanel() { + JLabel label = new JLabel(myMessage); + label.setUI(new MultiLineLabelUI()); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(label, BorderLayout.CENTER); + Icon icon = UIManager.getIcon("OptionPane.questionIcon"); + if (icon != null) { + label.setIcon(icon); + label.setIconTextGap(7); + } + return panel; + } + + protected JComponent createCenterPanel() { + return null; + } + + public boolean isPreviewUsages() { + return myCbPreviewResults.isSelected(); + } + + protected JComponent createSouthPanel() { + myCbPreviewResults = new JCheckBox("Preview usages to be changed"); + myCbPreviewResults.setSelected(myToPreviewUsages); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(super.createSouthPanel(), BorderLayout.CENTER); + myCbPreviewResults.setMnemonic('P'); + panel.add(myCbPreviewResults, BorderLayout.WEST); + return panel; + } + + protected Action[] createActions() { + if(myHelpID != null){ + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + else { + return new Action[]{getOKAction(), getCancelAction()}; + } + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpID); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/CanonicalTypes.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/CanonicalTypes.java new file mode 100644 index 00000000000..5e78ae4c583 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/CanonicalTypes.java @@ -0,0 +1,200 @@ +package com.intellij.refactoring.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.Iterator; +import java.util.Map; + +/** + * @author dsl + */ +public class CanonicalTypes { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.CanonicalTypes"); + public static abstract class Type { + public abstract PsiType getType(PsiElement context) throws IncorrectOperationException; + public abstract String getTypeText(); + } + + private static class Primitive extends Type { + private PsiPrimitiveType myType; + private Primitive(PsiPrimitiveType type) { + myType = type; + } + + public PsiType getType(PsiElement context) { + return myType; + } + + public String getTypeText() { + return myType.getPresentableText(); + } + } + + private static class Array extends Type { + private Type myComponentType; + + private Array(Type componentType) { + myComponentType = componentType; + } + + public PsiType getType(PsiElement context) throws IncorrectOperationException { + return myComponentType.getType(context).createArrayType(); + } + + public String getTypeText() { + return myComponentType.getTypeText() + "[]"; + } + } + + private static class Ellipsis extends Type { + private Type myComponentType; + + private Ellipsis(Type componentType) { + myComponentType = componentType; + } + + public PsiType getType(PsiElement context) throws IncorrectOperationException { + return new PsiEllipsisType(myComponentType.getType(context)); + } + + public String getTypeText() { + return myComponentType.getTypeText() + "..."; + } + } + + private static class WildcardType extends Type { + private final boolean myIsExtending; + private final Type myBound; + + private WildcardType(boolean isExtending, Type bound) { + myIsExtending = isExtending; + myBound = bound; + } + + public PsiType getType(PsiElement context) throws IncorrectOperationException { + if(myBound == null) return PsiWildcardType.createUnbounded(context.getManager()); + if (myIsExtending) { + return PsiWildcardType.createExtends(context.getManager(), myBound.getType(context)); + } + else { + return PsiWildcardType.createSuper(context.getManager(), myBound.getType(context)); + } + } + + public String getTypeText() { + if (myBound == null) return "?"; + return "? " + (myIsExtending ? "extends " : "super ") + myBound.getTypeText(); + } + } + + private static class WrongType extends Type { + private String myText; + + private WrongType(String text) { + myText = text; + } + + public PsiType getType(PsiElement context) throws IncorrectOperationException { + return context.getManager().getElementFactory().createTypeFromText(myText, context); + } + + public String getTypeText() { + return myText; + } + } + + + private static class Class extends Type { + private final String myOriginalText; + private String myClassQName; + private Map mySubstitutor; + + private Class(String originalText, String classQName, Map substitutor) { + myOriginalText = originalText; + myClassQName = classQName; + mySubstitutor = substitutor; + } + + public PsiType getType(PsiElement context) throws IncorrectOperationException { + final PsiManager manager = context.getManager(); + final PsiElementFactory factory = manager.getElementFactory(); + final PsiResolveHelper resolveHelper = manager.getResolveHelper(); + final PsiClass aClass = resolveHelper.resolveReferencedClass(myClassQName, context); + if (aClass == null) { + return factory.createTypeFromText(myClassQName, context); + } + Map substMap = new HashMap(); + final Iterator iterator = PsiUtil.typeParametersIterator(aClass); + while (iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + final String name = typeParameter.getName(); + final Type type = mySubstitutor.get(name); + if (type != null) { + substMap.put(typeParameter, type.getType(context)); + } else { + substMap.put(typeParameter, null); + } + } + return factory.createType(aClass, factory.createSubstitutor(substMap)); + } + + public String getTypeText() { + return myOriginalText; + } + } + + private static class Creator extends PsiTypeVisitor { + public static final Creator INSTANCE = new Creator(); + public Type visitPrimitiveType(PsiPrimitiveType primitiveType) { + return new Primitive(primitiveType); + } + + public Type visitEllipsisType(PsiEllipsisType ellipsisType) { + return new Ellipsis(ellipsisType.getComponentType().accept(this)); + } + + public Type visitArrayType(PsiArrayType arrayType) { + return new Array(arrayType.getComponentType().accept(this)); + } + + public Type visitWildcardType(PsiWildcardType wildcardType) { + final PsiType wildcardBound = wildcardType.getBound(); + final Type bound = wildcardBound == null ? null : wildcardBound.accept(this); + return new WildcardType(wildcardType.isExtends(), bound); + } + + public Type visitClassType(PsiClassType classType) { + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass aClass = resolveResult.getElement(); + final String originalText = classType.getPresentableText(); + if (aClass == null) { + return new WrongType(originalText); + } else { + Map substMap = new HashMap(); + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + final Iterator iterator = PsiUtil.typeParametersIterator(aClass); + while (iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + final PsiType substType = substitutor.substitute(typeParameter); + final String name = typeParameter.getName(); + if (substType == null) { + substMap.put(name, null); + } else { + substMap.put(name, substType.accept(this)); + } + } + final String qualifiedName = aClass.getQualifiedName(); + LOG.assertTrue(aClass.getName() != null); + return new Class(originalText, qualifiedName != null ? qualifiedName : aClass.getName(), substMap); + } + } + } + + public static Type createTypeWrapper(PsiType type) { + return type.accept(Creator.INSTANCE); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ConflictsUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ConflictsUtil.java new file mode 100644 index 00000000000..6a2b5e72c4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ConflictsUtil.java @@ -0,0 +1,87 @@ +/** + * created at Oct 8, 2001 + * @author Jeka + */ +package com.intellij.refactoring.util; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; + +public class ConflictsUtil { + public static PsiMember getContainer(PsiElement place) { + PsiElement parent = place; + while (true) { + if (parent instanceof PsiMember && !(parent instanceof PsiTypeParameter)) + return (PsiMember)parent; + if (parent instanceof PsiFile) return null; + parent = parent.getParent(); + } + } + + public static String getDescription(PsiElement element, boolean includeParent) { + if (element instanceof PsiField) { + int options = PsiFormatUtil.SHOW_NAME; + if (includeParent) { + options |= PsiFormatUtil.SHOW_CONTAINING_CLASS; + } + return "field " + htmlEmphasize(PsiFormatUtil.formatVariable((PsiVariable) element, options, PsiSubstitutor.EMPTY)); + } + + if (element instanceof PsiMethod) { + int options = PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS; + if (includeParent) { + options |= PsiFormatUtil.SHOW_CONTAINING_CLASS; + } + final PsiMethod method = (PsiMethod) element; + final String descr = method.isConstructor() ? "constructor" : "method"; + return descr + " " + htmlEmphasize(PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, options, PsiFormatUtil.SHOW_TYPE)); + } + + if (element instanceof PsiClassInitializer) { + PsiClassInitializer initializer = (PsiClassInitializer) element; + boolean isStatic = initializer.hasModifierProperty(PsiModifier.STATIC); + String s = isStatic ? "static initializer" : "instance initializer"; + if (includeParent) { + s += " of class " + getDescription(initializer.getContainingClass(), false); + } + return s; + } + + if (element instanceof PsiParameter) { + return "parameter " + htmlEmphasize(((PsiParameter) element).getName()); + } + + if (element instanceof PsiLocalVariable) { + return "local variable " + htmlEmphasize(((PsiVariable) element).getName()); + } + + if (element instanceof PsiPackage) { + return "package " + htmlEmphasize(((PsiPackage) element).getName()); + } + + if ((element instanceof PsiClass)) { + //TODO : local & anonymous + PsiClass psiClass = (PsiClass) element; + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName != null) { + return htmlEmphasize(qualifiedName); + } else if(psiClass.getName() == null) { + return htmlEmphasize("anonymous class"); + } else { + return htmlEmphasize(psiClass.getName()); + } + } + + return htmlEmphasize("???"); + + + } + + public static String htmlEmphasize(String text) { + return "" + text + ""; + } + + public static String capitalize(String text) { + return Character.toUpperCase(text.charAt(0)) + text.substring(1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/FieldConflictsResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/FieldConflictsResolver.java new file mode 100644 index 00000000000..a79e324934b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/FieldConflictsResolver.java @@ -0,0 +1,119 @@ +package com.intellij.refactoring.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Resolves conflicts with fields in a class, when new local variable is + * introduced in code block + * @author dsl + */ +public class FieldConflictsResolver { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.FieldConflictsResolver"); + private final String myName; + private final PsiCodeBlock myScope; + private PsiField myField; + private List myReferenceExpressions; + private PsiClass myQualifyingClass; + + public FieldConflictsResolver(String name, PsiCodeBlock scope) { + this(name, scope, new ArrayList()); + } + + public FieldConflictsResolver(String name, PsiCodeBlock scope, List excludeFromScope) { + myName = name; + myScope = scope; + if (myScope == null) return; + PsiManager manager = myScope.getManager(); + final PsiVariable oldVariable = manager.getResolveHelper().resolveReferencedVariable(myName, myScope); + if (!(oldVariable instanceof PsiField)) return; + myField = (PsiField) oldVariable; + final PsiReference[] references = manager.getSearchHelper().findReferences(myField, new LocalSearchScope(myScope), false); + myReferenceExpressions = new ArrayList(); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + final PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression) { + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) element; + if (referenceExpression.getQualifierExpression() == null) { + myReferenceExpressions.add(referenceExpression); + } + } + } + if (myField.hasModifierProperty(PsiModifier.STATIC)) { + myQualifyingClass = myField.getContainingClass(); + } + } + + public PsiExpression fixInitializer(PsiExpression initializer) { + if (myField == null) return initializer; + final PsiReferenceExpression[] replacedRef = new PsiReferenceExpression[] { null }; + initializer.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null) { + qualifierExpression.accept(this); + } else { + final PsiElement result = expression.resolve(); + if (expression.getManager().areElementsEquivalent(result, myField)) { + try { + replacedRef[0] = qualifyReference(expression); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + } + }); + if (!initializer.isValid()) return replacedRef[0]; + return initializer; + } + + public void fix() throws IncorrectOperationException { + if (myField == null) return; + final PsiManager manager = myScope.getManager(); + for (Iterator iterator = myReferenceExpressions.iterator(); iterator.hasNext();) { + PsiReferenceExpression referenceExpression = iterator.next(); + if (!referenceExpression.isValid()) continue; + final PsiElement newlyResolved = referenceExpression.resolve(); + if (!manager.areElementsEquivalent(newlyResolved, myField)) { + qualifyReference(referenceExpression); + } + } + } + + + private PsiReferenceExpression qualifyReference(PsiReferenceExpression referenceExpression) throws IncorrectOperationException { + PsiManager manager = referenceExpression.getManager(); + PsiReferenceExpression expressionFromText; + final PsiElementFactory factory = manager.getElementFactory(); + if (myQualifyingClass == null) { + final PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class); + final PsiClass containingClass = myField.getContainingClass(); + if (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) { + expressionFromText = (PsiReferenceExpression)factory.createExpressionFromText("A.this." + myField.getName(), null); + final PsiJavaCodeReferenceElement classQualifier = ((PsiThisExpression)expressionFromText.getQualifierExpression()).getQualifier(); + classQualifier.replace(factory.createClassReferenceElement(containingClass)); + } else { + expressionFromText = (PsiReferenceExpression) factory.createExpressionFromText("this." + myField.getName(), null); + } + } else { + expressionFromText = (PsiReferenceExpression) factory.createExpressionFromText("A." + myField.getName(), null); + final PsiReferenceExpression qualifier = factory.createReferenceExpression(myQualifyingClass); + expressionFromText.getQualifierExpression().replace(qualifier); + } + CodeStyleManager codeStyleManager = manager.getCodeStyleManager(); + expressionFromText = (PsiReferenceExpression) codeStyleManager.reformat(expressionFromText); + return (PsiReferenceExpression) referenceExpression.replace(expressionFromText); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/JavaDocPolicy.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/JavaDocPolicy.java new file mode 100644 index 00000000000..5b2de704307 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/JavaDocPolicy.java @@ -0,0 +1,48 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 30.05.2002 + * Time: 19:24:56 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util; + +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.util.IncorrectOperationException; + +public class JavaDocPolicy { + public static final int ASIS = 0; + public static final int MOVE = 1; + public static final int COPY = 2; + + private final int myJavaDocPolicy; + + public JavaDocPolicy(int javaDocPolicy) { + myJavaDocPolicy = javaDocPolicy; + } + + public void processCopiedJavaDoc(PsiDocComment newDocComment, PsiDocComment docComment, boolean willOldBeDeletedAnyway) + throws IncorrectOperationException{ + if(myJavaDocPolicy == COPY || docComment == null) return; + + if(myJavaDocPolicy == MOVE) { + docComment.delete(); + } + else if(myJavaDocPolicy == ASIS && newDocComment != null && !willOldBeDeletedAnyway) { + newDocComment.delete(); + } + } + + public void processNewJavaDoc(PsiDocComment newDocComment) throws IncorrectOperationException { + if(myJavaDocPolicy == ASIS && newDocComment != null) { + newDocComment.delete(); + } + } + + public void processOldJavaDoc(PsiDocComment oldDocComment) throws IncorrectOperationException { + if(myJavaDocPolicy == MOVE && oldDocComment != null) { + oldDocComment.delete(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ParameterTablePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ParameterTablePanel.java new file mode 100644 index 00000000000..194f825af34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/ParameterTablePanel.java @@ -0,0 +1,324 @@ + +package com.intellij.refactoring.util; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiVariable; +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +public abstract class ParameterTablePanel extends JPanel{ + private final Project myProject; + private final VariableData[] myVariableData; + + private final Table myTable; + private MyTableModel myTableModel; + private JButton myUpButton; + private JButton myDownButton; + + public static class VariableData { + public final PsiVariable variable; + public String name; + public boolean passAsParameter; + + public VariableData(PsiVariable variable) { + this.variable = variable; + } + } + + protected abstract void updateSignature(); + protected abstract void doEnterAction(); + protected abstract void doCancelAction(); + + public ParameterTablePanel(Project project, VariableData[] variableData) { + super(new BorderLayout()); + myProject = project; + myVariableData = variableData; + + myTableModel = new MyTableModel(); + myTable = new Table(myTableModel); + DefaultCellEditor defaultEditor=(DefaultCellEditor)myTable.getDefaultEditor(Object.class); + defaultEditor.setClickCountToStart(1); + + myTable.setTableHeader(null); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.getColumnModel().getColumn(myTableModel.CHECKMARK_COLUMN).setCellRenderer(new CheckBoxTableCellRenderer()); + myTable.getColumnModel().getColumn(myTableModel.CHECKMARK_COLUMN).setMaxWidth(new JCheckBox().getPreferredSize().width); + myTable.getColumnModel().getColumn(myTableModel.PARAMETER_COLUMN).setCellRenderer(new ParameterTableCellRenderer()); + myTable.setPreferredScrollableViewportSize(new Dimension(250, myTable.getRowHeight() * 5)); + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + myTable.getActionMap().put("enable_disable", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] rows = myTable.getSelectedRows(); + if (rows.length > 0){ + boolean valueToBeSet = false; + for(int idx = 0; idx < rows.length; idx++){ + if (!myVariableData[rows[idx]].passAsParameter){ + valueToBeSet = true; + break; + } + } + for(int idx = 0; idx < rows.length; idx++){ + myVariableData[rows[idx]].passAsParameter = valueToBeSet; + } + myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); + TableUtil.selectRows(myTable, rows); + } + } + }); + // F2 should edit the name + myTable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "edit_parameter_name"); + myTable.getActionMap().put("edit_parameter_name", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (!myTable.isEditing()){ + int row = myTable.getSelectedRow(); + if (row >=0 && row < myTableModel.getRowCount()) { + TableUtil.editCellAt(myTable, row, myTableModel.PARAMETER_COLUMN); + } + } + } + }); + + // make ENTER work when the table has focus + myTable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl"); + myTable.getActionMap().put("invokeImpl", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null){ + editor.stopCellEditing(); + } + else{ + doEnterAction(); + } + } + }); + + // make ESCAPE work when the table has focus + myTable.getActionMap().put("doCancel", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null){ + editor.stopCellEditing(); + } + else{ + doCancelAction(); + } + } + }); + + JPanel listPanel = new JPanel(new BorderLayout()); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + listPanel.add(scrollPane, BorderLayout.CENTER); + listPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + this.add(listPanel, BorderLayout.CENTER); + + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + this.add(buttonsPanel, BorderLayout.EAST); + + buttonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(2, 4, 2, 4); + + myUpButton = new JButton("Move Up"); + myUpButton.setMnemonic('u'); + myUpButton.setDefaultCapable(false); + buttonsPanel.add(myUpButton, gbConstraints); + + myDownButton = new JButton("Move Down"); + myDownButton.setMnemonic('d'); + myDownButton.setDefaultCapable(false); + buttonsPanel.add(myDownButton, gbConstraints); + + gbConstraints.weighty = 1; + buttonsPanel.add(new JPanel(), gbConstraints); + + myUpButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(myTable.isEditing()) { + final boolean isStopped = myTable.getCellEditor().stopCellEditing(); + if(!isStopped) return; + } + moveSelectedItem(-1); + updateSignature(); + myTable.requestFocus(); + } + } + ); + + myDownButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(myTable.isEditing()) { + final boolean isStopped = myTable.getCellEditor().stopCellEditing(); + if(!isStopped) return; + } + moveSelectedItem(+1); + updateSignature(); + myTable.requestFocus(); + } + } + ); + + myTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateMoveButtons(); + } + } + ); + if (myVariableData.length <= 1) { + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + else { + myTable.getSelectionModel().setSelectionInterval(0, 0); + } + updateMoveButtons(); + } + + private void updateMoveButtons() { + int row = myTable.getSelectedRow(); + if (0 <= row && row < myVariableData.length){ + myUpButton.setEnabled(row > 0); + myDownButton.setEnabled(row < myVariableData.length - 1); + } + else{ + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + } + + private void moveSelectedItem(int moveIncrement) { + int row = myTable.getSelectedRow(); + if (row < 0 || row >= myVariableData.length) return; + int targetRow = row + moveIncrement; + if (targetRow < 0 || targetRow >= myVariableData.length) return; + VariableData currentItem = myVariableData[row]; + myVariableData[row] = myVariableData[targetRow]; + myVariableData[targetRow] = currentItem; + myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row)); + myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow); + } + + public void setEnabled(boolean enabled) { + myTable.setEnabled(enabled); + if (!enabled) { + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + else { + updateMoveButtons(); + } + super.setEnabled(enabled); + } + + private class MyTableModel extends AbstractTableModel { + public final int CHECKMARK_COLUMN = 0; + public final int PARAMETER_COLUMN = 1; + + public int getRowCount() { + return myVariableData.length; + } + + public int getColumnCount() { + return 2; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN : { + return myVariableData[rowIndex].passAsParameter? Boolean.TRUE : Boolean.FALSE; + } + case PARAMETER_COLUMN : { + return myVariableData[rowIndex].name; + } + } + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN : { + myVariableData[rowIndex].passAsParameter = ((Boolean)aValue).booleanValue(); + fireTableRowsUpdated(rowIndex, rowIndex); + myTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex); + updateSignature(); + break; + } + case PARAMETER_COLUMN : { + VariableData data = myVariableData[rowIndex]; + String name = (String)aValue; + if (PsiManager.getInstance(myProject).getNameHelper().isIdentifier(name)) { + data.name = name; + } + updateSignature(); + break; + } + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN : + return ParameterTablePanel.this.isEnabled(); + case PARAMETER_COLUMN : + return ParameterTablePanel.this.isEnabled() && myVariableData[rowIndex].passAsParameter; + default: + return false; + } + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECKMARK_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + } + + private class CheckBoxTableCellRenderer extends BooleanTableCellRenderer { + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + rendererComponent.setEnabled(ParameterTablePanel.this.isEnabled()); + return rendererComponent; + } + } + private class ParameterTableCellRenderer extends DefaultTableCellRenderer { + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + VariableData data = myVariableData[row]; + String type = data.variable.getType().getPresentableText(); + setText(type+" "+data.name); + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringHierarchyUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringHierarchyUtil.java new file mode 100644 index 00000000000..0bcb9ddd3a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringHierarchyUtil.java @@ -0,0 +1,234 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 18.06.2002 + * Time: 14:28:03 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.util.containers.HashSet; + +import java.util.*; + +public class RefactoringHierarchyUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.RefactoringHierarchyUtil"); + private static final List PRIMITIVE_TYPES = Arrays.asList( + new PsiType[]{PsiType.BYTE, PsiType.CHAR, PsiType.SHORT, PsiType.INT, PsiType.LONG, PsiType.FLOAT, PsiType.DOUBLE, } + ); + + public static boolean willBeInTargetClass(PsiElement place, + Set membersToMove, + PsiClass targetClass, + boolean includeSubclasses) { + PsiElement parent = place; + while (parent != null) { + if (membersToMove.contains(parent)) return true; + if (parent instanceof PsiClass) { + if (targetClass.equals(parent)) return true; + if (includeSubclasses && ((PsiClass) parent).isInheritor(targetClass, true)) return true; + } + parent = parent.getParent(); + } + return false; + } + + public static PsiClass getDeepestNonObjectBase(PsiClass aClass) { + PsiClass current = aClass; + while (current != null) { + PsiClassType[] supers = current.getExtendsList().getReferencedTypes(); + if (supers.length == 0) { + return current; + } + PsiClass base = supers[0].resolve(); + if (base != null) { + current = base; + } + else { + return current; + } + } + return null; + } + + public static PsiClass getNearestBaseClass(PsiClass subClass, boolean includeNonProject) { + PsiClassType[] superTypes = subClass.getSuperTypes(); + + if (superTypes != null && superTypes.length > 0) { + PsiClass resolved = superTypes[0].resolve(); + if (resolved != null) { + if (!includeNonProject) { + if (resolved.getManager().isInProject(resolved)) { + return resolved; + } + } + else { + return resolved; + } + } + } + return null; + } + + /** + * + * @param subClass + * @param includeNonProject + * @param sortAlphabetically if false, sorted in DFS order + * @return + */ + public static ArrayList createBasesList(PsiClass subClass, boolean includeNonProject, boolean sortAlphabetically) { + LinkedHashSet bases = new LinkedHashSet(); + getSuperClasses(subClass, bases, includeNonProject); + + if (!subClass.isInterface()) { + final PsiManager manager = subClass.getManager(); + PsiClass javaLangObject = manager.findClass("java.lang.Object", subClass.getResolveScope()); + if (includeNonProject && javaLangObject != null && !manager.areElementsEquivalent(javaLangObject, subClass)) { + bases.add(javaLangObject); + } + } + + ArrayList basesList = new ArrayList(bases); + + if (sortAlphabetically) { + Collections.sort( + basesList, new Comparator() { + public int compare(PsiClass c1, PsiClass c2) { + return c1.getQualifiedName().compareTo(c2.getQualifiedName()); + } + } + ); + } + + return basesList; + } + + /** + * Checks whether given element is below the given superClass in class hierarchy. + * @param superClass + * @return + * @param subClass + * @param member + */ + public static boolean isMemberBetween(PsiClass superClass, PsiClass subClass, PsiMember member) { + PsiClass elementClass = null; + if (member instanceof PsiField || member instanceof PsiMethod) { + elementClass = member.getContainingClass(); + } + + if (elementClass == null) return false; + if (superClass != null) { + return !superClass.getManager().areElementsEquivalent(superClass, elementClass) && + elementClass.isInheritor(superClass, true); + } + else { + return subClass.getManager().areElementsEquivalent(subClass, elementClass); + } + } + + /** + * Gets all superclasses. Classes are added to result in DFS order + * @param aClass + * @param results + * @param includeNonProject + */ + public static void getSuperClasses(PsiClass aClass, Set results, boolean includeNonProject) { + getSuperClassesOfList(aClass.getSuperTypes(), results, includeNonProject); + } + + private static void getSuperClassesOfList(PsiClassType[] types, Set results, + boolean includeNonProject) { + for (int i = 0; i < types.length; i++) { + PsiClass resolved = types[i].resolve(); + if (resolved != null) { + if (!results.contains(resolved)) { + if (includeNonProject || resolved.getManager().isInProject(resolved)) { + results.add(resolved); + } + getSuperClasses(resolved, results, includeNonProject); + } + } + } + } + + public static void processSuperTypes(PsiType type, SuperTypeVisitor visitor) { + processSuperTypes(type, visitor, new HashSet()); + } + public static void processSuperTypes(PsiType type, SuperTypeVisitor visitor, Set visited) { + if (visited.contains(type)) return; + visited.add(type); + if (type instanceof PsiPrimitiveType) { + int index = PRIMITIVE_TYPES.indexOf(type); + if (index >= 0) { + for (int i = index + 1; i < PRIMITIVE_TYPES.size(); i++) { + visitor.visitType(PRIMITIVE_TYPES.get(i)); + } + } + } + else { + final PsiType[] superTypes = type.getSuperTypes(); + for (int i = 0; i < superTypes.length; i++) { + PsiType superType = superTypes[i]; + visitor.visitType(superType); + processSuperTypes(superType, visitor, visited); + } + } + } + + public static PsiClass[] findImplementingClasses(PsiClass anInterface) { + List result = new ArrayList(); + _findImplementingClasses(anInterface, new HashSet(), result); + loop1: + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + final PsiClass psiClass = iterator.next(); + for (Iterator iterator1 = result.iterator(); iterator1.hasNext();) { + final PsiClass aClass = iterator1.next(); + if (psiClass.isInheritor(aClass, true)) { + iterator.remove(); + break loop1; + } + } + } + return result.toArray(new PsiClass[result.size()]); + } + + private static void _findImplementingClasses(PsiClass anInterface, final Set visited, final List result) { + LOG.assertTrue(anInterface.isInterface()); + PsiManager manager = anInterface.getManager(); + visited.add(anInterface); + PsiSearchHelper searchHelper = manager.getSearchHelper(); + searchHelper.processInheritors(new PsiElementProcessor() { + public boolean execute(PsiClass element) { + final PsiClass psiClass = element; + if (!psiClass.isInterface()) { + result.add(psiClass); + } + else if (!visited.contains(psiClass)){ + _findImplementingClasses(psiClass, visited, result); + } + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + }, + anInterface, + GlobalSearchScope.projectScope(manager.getProject()), + false); + } + + + public static interface SuperTypeVisitor { + void visitType(PsiType aType); + + void visitClass(PsiClass aClass); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageDialog.java new file mode 100644 index 00000000000..e4125c675a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageDialog.java @@ -0,0 +1,65 @@ +package com.intellij.refactoring.util; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MultiLineLabelUI; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +public class RefactoringMessageDialog extends DialogWrapper{ + private String myMessage; + private String myHelpTopic; + private Icon myIcon; + private boolean myIsCancelButtonVisible; + + public RefactoringMessageDialog(String title, String message, String helpTopic, String iconId, boolean showCancelButton, Project project) { + super(project, false); + constructor(title, message, helpTopic, showCancelButton, iconId); + } + + private void constructor(String title, String message, String helpTopic, boolean isCancelButtonVisible, String iconId) { + setTitle(title); + myMessage = message; + myHelpTopic = helpTopic; + myIsCancelButtonVisible=isCancelButtonVisible; + setButtonsAlignment(SwingUtilities.CENTER); + myIcon = UIManager.getIcon(iconId); + init(); + } + + protected Action[] createActions(){ + ArrayList actions=new ArrayList(); + actions.add(getOKAction()); + if(myIsCancelButtonVisible){ + actions.add(getCancelAction()); + } + if(myHelpTopic!=null){ + actions.add(getHelpAction()); + } + return (Action[])actions.toArray(new Action[actions.size()]); + } + + protected JComponent createNorthPanel() { + JLabel label = new JLabel(myMessage); + label.setUI(new MultiLineLabelUI()); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(label, BorderLayout.CENTER); + if (myIcon != null) { + label.setIcon(myIcon); + label.setIconTextGap(10); + } + panel.add(Box.createVerticalStrut(7), BorderLayout.SOUTH); + return panel; + } + + protected JComponent createCenterPanel() { + return null; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp(myHelpTopic); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageUtil.java new file mode 100644 index 00000000000..c6c6cd3b3c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringMessageUtil.java @@ -0,0 +1,310 @@ + +package com.intellij.refactoring.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.jsp.JspFileImpl; +import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.util.PsiFormatUtil; + +import java.util.ArrayList; +import java.util.List; + +public class RefactoringMessageUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.RefactoringMessageUtil"); + + public static void showErrorMessage(String title, String message, String helpId, Project project) { + RefactoringMessageDialog dialog=new RefactoringMessageDialog(title,message,helpId,"OptionPane.errorIcon",false, project); + dialog.show(); + } + + public static void showReadOnlyElementRefactoringMessage(Project project, PsiElement element) { + showReadOnlyElementMessage(element, project, "Refactoring cannot be performed"); + } + + public static void showReadOnlyElementMessage(PsiElement element, + Project project, + final String messagePrefix) { + if (element instanceof PsiDirectory) { + PsiDirectory dir = (PsiDirectory)element; + final VirtualFile vFile = dir.getVirtualFile(); + if (vFile.getFileSystem() instanceof JarFileSystem) { + String message1 = messagePrefix + ".\n Directory " + vFile.getPresentableUrl() + " is located in a jar file."; + showErrorMessage("Cannot Modify Jar", message1, null, project); + } + else { + String message1 = messagePrefix + ".\n Directory " + vFile.getPresentableUrl() + " is read-only."; + showErrorMessage("Read-only Directory", message1, null, project); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt(new VirtualFile[]{vFile}); + } + }); + } + } + else if (element instanceof PsiPackage) { + final PsiDirectory[] directories = ((PsiPackage) element).getDirectories(); + StringBuffer message = new StringBuffer(messagePrefix); + message.append('\n'); + final List readOnlyDirs = new ArrayList(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (!directory.isWritable()) { + final VirtualFile virtualFile = directory.getVirtualFile(); + final String presentableUrl = virtualFile.getPresentableUrl(); + if (virtualFile.getFileSystem() instanceof JarFileSystem) { + message.append("Directory " + presentableUrl + " is located in a jar file.\n"); + } else { + message.append("Directory " + presentableUrl + " is read-only.\n"); + readOnlyDirs.add(virtualFile); + } + } + } + showErrorMessage("Read-only package", message.toString(), null, project); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + VirtualFileManager.getInstance().fireReadOnlyModificationAttempt( + (VirtualFile[])readOnlyDirs.toArray(new VirtualFile[readOnlyDirs.size()]) + ); + } + }); + } + else if (element instanceof PsiCompiledElement) { + PsiFile file = element.getContainingFile(); + String qName = ((PsiJavaFile)file).getClasses()[0].getQualifiedName(); + showErrorMessage("Compiled Class", messagePrefix + " on compiled class " + qName + ".", null, project); + } + else{ + PsiFile file = element.getContainingFile(); + if (file == null) { + + if (element instanceof PsiVariable) { + String message1 = "Variable " + element.getText() + " cannot be renamed."; + showErrorMessage("Read-only entity", message1, null, project); + } + else { + String message1 = "Cannot rename " + element.getText() + "."; + showErrorMessage("Read-only entity", message1, null, project); + } + + return; + } + VirtualFile vFile = file.getVirtualFile(); + if (vFile.getFileSystem() instanceof JarFileSystem) { + String message1 = messagePrefix + ".\n File " + vFile.getPresentableUrl() + " is located in a jar file."; + showErrorMessage("Cannot Modify Jar", message1, null, project); + } + else { + String message1 = messagePrefix + ".\n File " + vFile.getPresentableUrl() + " is read-only."; + showErrorMessage("Read-only File", message1, null, project); + final Document document = PsiDocumentManager.getInstance(project).getDocument(file); + if (document != null) { + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run(){ + document.fireReadOnlyModificationAttempt(); + } + }); + } + } + } + } + + public static String getIncorrectIdentifierMessage(String identifierName) { + return "'" + identifierName + "' is not a legal java identifier"; + } + + /** + * Must be invoked in AtomicAction + * @return true - can continue, false return to editing + */ + public static boolean checkMethodConflicts(PsiElement scope, PsiMethod refactoredMethod, PsiMethod prototype) { + if (prototype == null) return true; + + PsiMethod method = null; + if (scope instanceof PsiClass) { + method = ((PsiClass)scope).findMethodBySignature(prototype, true); + } + else if (scope instanceof JspFileImpl) { + method = ((JspFileImpl)scope).findMethodBySignature(prototype, true); + } + else { + LOG.assertTrue(false); + } + if (method != null && method != refactoredMethod) { + String methodInfo = PsiFormatUtil.formatMethod( + method, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + if (scope instanceof PsiClass) { + PsiClass aClass = (PsiClass)scope; + if (method.getContainingClass().equals(aClass)) { + String className = !(aClass instanceof PsiAnonymousClass) ? "class " + aClass.getName() : "current class"; + int ret = Messages.showYesNoDialog( + "Method " + methodInfo + " is already defined in the " + className + ".\nContinue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + else { // method somewhere in base class + if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { + String protoMethodInfo = PsiFormatUtil.formatMethod( + prototype, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE + ); + String className = method.getContainingClass().getName(); + if (!prototype.hasModifierProperty(PsiModifier.PRIVATE)) { + boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); + boolean isMyMethodAbstract = refactoredMethod != null? refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT) : false; + int ret = Messages.showYesNoDialog( + "Method " + protoMethodInfo + " will " + ((isMethodAbstract && !isMyMethodAbstract) ? "implement" : "override") + + "\nmethod of the base class " + className + ".\n" + + "Continue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + else { // prototype is private, will be compile-error + int ret = Messages.showYesNoDialog( + "Method " + protoMethodInfo+ " will hide\nmethod of the base class " + className + ".\n" + + "Continue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + } + } + } + else { // scope instanceof JspFile + PsiFile file = method.getContainingFile(); + int toContinue = Messages.showYesNoDialog( + "Method " + methodInfo + " is already defined in the file\n" + file.getVirtualFile().getPresentableUrl() + ".\nContinue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (toContinue != 0) { + return false; + } + } + } + return true; + } + + /** + * Must be invoked in AtomicAction + * @return true - can continue, false return to editing + */ + public static boolean checkFieldConflicts(PsiElement scope, String newName) { + PsiField existingField = null; + String name = newName; + if (scope instanceof PsiClass) { + existingField = ((PsiClass)scope).findFieldByName(name, true); + } + else if (scope instanceof JspFileImpl) { + existingField = ((JspFileImpl)scope).findFieldByName(name, true); + } + else { + LOG.assertTrue(false); + } + if (existingField != null) { + if (scope instanceof PsiClass) { + PsiClass aClass = (PsiClass)scope; + if (existingField.getContainingClass().equals(aClass)) { + String className = !(aClass instanceof PsiAnonymousClass) ? "class " + aClass.getName() : "current class"; + int ret = Messages.showYesNoDialog( + "Field " + existingField.getName() + " is already defined in the " + className + ".\nContinue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + else { // method somewhere in base class + if (!existingField.hasModifierProperty(PsiModifier.PRIVATE)) { + String fieldInfo = PsiFormatUtil.formatVariable(existingField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY); + String protoFieldInfo = newName; + String className = existingField.getContainingClass().getName(); + int ret = Messages.showYesNoDialog( + "Field " + protoFieldInfo + " will hide\n field " + fieldInfo + " of the base class " + className + ".\n" + + "Continue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + } + } + else { // scope instanceof JspFile + PsiFile psiFile = existingField.getContainingFile(); + int ret = Messages.showYesNoDialog( + "Field " + existingField.getName() + " is already defined in the file\n" + psiFile.getVirtualFile().getPresentableUrl() + ".\nContinue anyway?", + "Warning", + Messages.getWarningIcon() + ); + if (ret != 0) { + return false; + } + } + } + return true; + } + + /** + * @return null, if can create a class + * an error message, if cannot create a class + * + */ + public static String checkCanCreateClass(PsiDirectory destinationDirectory, String className) { + PsiClass[] classes = destinationDirectory.getClasses(); + VirtualFile file = destinationDirectory.getVirtualFile(); + for (int idx = 0; idx < classes.length; idx++) { + PsiClass aClass = classes[idx]; + if (className.equals(aClass.getName())) { + return "Directory " + file.getPresentableUrl() + "\nalready contains " + (aClass.isInterface()? "an interface" : "a class") + " named '" + className + "'"; + } + } + String fileName = className+".java"; + return checkCanCreateFile(destinationDirectory, fileName); + } + public static String checkCanCreateFile(PsiDirectory destinationDirectory, String fileName) { + VirtualFile file = destinationDirectory.getVirtualFile(); + VirtualFile child = file.findChild(fileName); + if (child != null) { + return "Directory " + file.getPresentableUrl() + "\nalready contains a file named '" + fileName + "'"; + } + return null; + } + + public static String getGetterSetterMessage(String newName, String action, PsiMethod getter, PsiMethod setter) { + String text; + if (getter != null && setter != null) { + text = "Getter and setter methods found for the field " + newName + ". \n" + action + " them as well?"; + } else if (getter != null) { + text = "Getter method found for the field " + newName + ". \n" + action + " the getter as well?"; + } else { + text = "Setter method found for the field " + newName + ". \n" + action + " the setter as well?"; + } + return text; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringUtil.java new file mode 100644 index 00000000000..eeb68fd9030 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/RefactoringUtil.java @@ -0,0 +1,1474 @@ +package com.intellij.refactoring.util; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.ExpectedTypesProvider; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.jsp.JspExpression; +import com.intellij.psi.search.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.RefactoringSettings; +import com.intellij.refactoring.ui.InfoDialog; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.Processor; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +public class RefactoringUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.RefactoringUtil"); + public static final int EXPR_COPY_SAFE = 0; + public static final int EXPR_COPY_UNSAFE = 1; + public static final int EXPR_COPY_PROHIBITED = 2; + + public static void showInfoDialog(String info, Project project) { + RefactoringSettings settings = RefactoringSettings.getInstance(); + if (settings.IS_SHOW_ACTION_INFO) { + InfoDialog usagesWarning = new InfoDialog(info, project); + usagesWarning.show(); + settings.IS_SHOW_ACTION_INFO = usagesWarning.isToShowInFuture(); + } + } + + public static boolean isSourceRoot(final PsiDirectory directory) { + if (directory.getManager() == null) return false; + final Project project = directory.getProject(); + if (project == null) return false; + final VirtualFile virtualFile = directory.getVirtualFile(); + final VirtualFile sourceRootForFile = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFile); + return Comparing.equal(virtualFile, sourceRootForFile); + } + + public static boolean isInStaticContext(PsiElement element) { + final PsiElement staticParentElement = HighlightUtil.getPossibleStaticParentElement(element, null); + if (staticParentElement == null) return false; + return staticParentElement instanceof PsiModifierListOwner + && ((PsiModifierListOwner)staticParentElement).hasModifierProperty(PsiModifier.STATIC); + } + + public static boolean isResolvableType(PsiType type) { + return type.accept(new PsiTypeVisitor() { + public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) { + return Boolean.TRUE; + } + + public Boolean visitArrayType(PsiArrayType arrayType) { + return arrayType.getComponentType().accept(this); + } + + public Boolean visitClassType(PsiClassType classType) { + if (classType.resolve() == null) return Boolean.FALSE; + PsiType[] parameters = classType.getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiType parameter = parameters[i]; + if (parameter != null && !parameter.accept(this).booleanValue()) return Boolean.FALSE; + } + + return Boolean.TRUE; + } + + public Boolean visitWildcardType(PsiWildcardType wildcardType) { + if (wildcardType.getBound() != null) return wildcardType.getBound().accept(this); + return Boolean.TRUE; + } + }).booleanValue(); + } + + public static PsiElement replaceOccurenceWithFieldRef(PsiExpression occurrence, PsiField newField, PsiClass destinationClass) + throws IncorrectOperationException { + final PsiManager manager = occurrence.getManager(); + final String fieldName = newField.getName(); + final PsiVariable psiVariable = manager.getResolveHelper().resolveReferencedVariable(fieldName, occurrence); + final PsiElementFactory factory = manager.getElementFactory(); + if (psiVariable != null && psiVariable.equals(newField)) { + return occurrence.replace(factory.createExpressionFromText(fieldName, null)); + } + else { + final PsiReferenceExpression ref = (PsiReferenceExpression)factory.createExpressionFromText("this." + fieldName, null); + if (newField.hasModifierProperty(PsiModifier.STATIC)) { + final PsiReferenceExpression referenceExpression = + factory.createReferenceExpression(destinationClass); + ref.getQualifierExpression().replace(referenceExpression); + } + return occurrence.replace(ref); + } + } + + public static interface UsageInfoFactory { + UsageInfo createUsageInfo(PsiElement usage, int startOffset, int endOffset); + } + + public static void addUsagesInStringsAndComments(PsiElement element, String stringToSearch, List results, + UsageInfoFactory factory) { + PsiManager manager = element.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + SearchScope scope = helper.getAccessScope(element); + scope = scope.intersectWith(GlobalSearchScope.projectScope(manager.getProject())); + int index = stringToSearch.lastIndexOf('.'); + String identifierToSearch = index >= 0 ? stringToSearch.substring(index + 1) : stringToSearch; + + PsiLiteralExpression[] literals = helper.findStringLiteralsContainingIdentifier(identifierToSearch, scope); + for (int i = 0; i < literals.length; i++) { + processStringOrComment(literals[i], stringToSearch, results, factory); + } + + PsiElement[] comments = helper.findCommentsContainingIdentifier(identifierToSearch, scope); + for (int i = 0; i < comments.length; i++) { + processStringOrComment(comments[i], stringToSearch, results, factory); + } + } + + public static boolean isSearchInNonJavaEnabled(PsiElement element) { + return element instanceof PsiPackage || element instanceof PsiDirectory + || (element instanceof PsiClass && ((PsiClass)element).getQualifiedName() != null); + } + + public static PsiElement getVariableScope(PsiLocalVariable localVar) { + if (!(localVar instanceof ImplicitVariable)) { + return localVar.getParent().getParent(); + } + else { + return ((ImplicitVariable)localVar).getDeclarationScope(); + } + } + + public static void addUsagesInNonJavaFiles(PsiElement element, String stringToSearch, GlobalSearchScope searchScope, + final List results, final UsageInfoFactory factory) { + processUsagesInNonJavaFiles(element, stringToSearch, searchScope, new Processor() { + public boolean process(UsageInfo t) { + results.add(t); + return true; + } + }, factory); + } + + public static void processUsagesInNonJavaFiles(PsiElement element, String stringToSearch, GlobalSearchScope searchScope, + final Processor processor, final UsageInfoFactory factory) { + PsiSearchHelper helper = element.getManager().getSearchHelper(); + + helper.processUsagesInNonJavaFiles(stringToSearch, + new PsiNonJavaFileReferenceProcessor() { + public boolean process(PsiFile psiFile, int startOffset, int endOffset) { + UsageInfo usageInfo = factory.createUsageInfo(psiFile, startOffset, endOffset); + if (usageInfo != null) { + if (!processor.process(usageInfo)) return false; + } + return true; + } + }, + searchScope); + } + + private static void processStringOrComment(PsiElement element, String stringToSearch, List results, + UsageInfoFactory factory) { + String elementText = element.getText(); + for (int index = 0; index < elementText.length(); index++) { + index = elementText.indexOf(stringToSearch, index); + if (index < 0) break; + + if (index > 0) { + char c = elementText.charAt(index - 1); + if (Character.isJavaIdentifierPart(c) && c != '$') { + continue; + } + } + + if (index + stringToSearch.length() < elementText.length()) { + char c = elementText.charAt(index + stringToSearch.length()); + if (Character.isJavaIdentifierPart(c) && c != '$') { + continue; + } + } + + UsageInfo usageInfo = factory.createUsageInfo(element, index, index + stringToSearch.length()); + if (usageInfo != null) { + results.add(usageInfo); + } + + index += stringToSearch.length(); + } + } + + public static void renameNonCodeUsages(final Project project, final UsageInfo[] usages) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + HashMap> filesToOffsetsMap = new HashMap>(); + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + final PsiElement element = usage.getElement(); + + if (element == null || !element.isValid()) continue; + if (usage instanceof NonCodeUsageInfo) { + final PsiFile containingFile = element.getContainingFile(); + int fileOffset = element.getTextRange().getStartOffset() + usage.startOffset; + + ArrayList list = filesToOffsetsMap.get(containingFile); + if (list == null) { + list = new ArrayList(); + filesToOffsetsMap.put(containingFile, list); + } + list.add(new UsageOffset(fileOffset, fileOffset + usage.endOffset - usage.startOffset, + ((NonCodeUsageInfo)usage).newText)); + } + } + + Iterator iter = filesToOffsetsMap.keySet().iterator(); + while (iter.hasNext()) { + PsiFile file = iter.next(); + final Document editorDocument = PsiDocumentManager.getInstance(project).getDocument(file); + + ArrayList list = filesToOffsetsMap.get(file); + UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]); + Arrays.sort(offsets); + + for (int i = offsets.length - 1; i >= 0; i--) { + UsageOffset usageOffset = offsets[i]; + editorDocument.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText); + } + PsiDocumentManager.getInstance(project).commitDocument(editorDocument); + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + } + + private static class UsageOffset implements Comparable { + final int startOffset; + final int endOffset; + final String newText; + + public UsageOffset(int startOffset, int endOffset, String newText) { + this.startOffset = startOffset; + this.endOffset = endOffset; + this.newText = newText; + } + + public int compareTo(Object o) { + return startOffset - ((UsageOffset)o).startOffset; + } + } + + public static PsiReturnStatement[] findReturnStatements(PsiMethod method) { + ArrayList vector = new ArrayList(); + PsiCodeBlock body = method.getBody(); + if (body != null) { + addReturnStatements(vector, body); + } + return vector.toArray(new PsiReturnStatement[vector.size()]); + } + + private static void addReturnStatements(ArrayList vector, PsiElement element) { + if (element instanceof PsiReturnStatement) { + vector.add(element); + } + else if (element instanceof PsiClass) { + return; + } + else { + PsiElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + addReturnStatements(vector, child); + } + } + } + + + public static PsiElement getParentStatement(PsiElement place, boolean skipScopingStatements) { + PsiElement parent = place; + while (true) { + if (parent instanceof PsiStatement) break; + if (parent instanceof JspExpression) break; + parent = parent.getParent(); + if (parent == null) return null; + } + PsiElement parentStatement = parent; + parent = parentStatement instanceof PsiStatement ? parentStatement : parentStatement.getParent(); + while (parent instanceof PsiStatement) { + if (!skipScopingStatements && + ((parent instanceof PsiForStatement && parentStatement == ((PsiForStatement)parent).getBody()) + || (parent instanceof PsiForeachStatement && parentStatement == ((PsiForeachStatement)parent).getBody()) + || (parent instanceof PsiWhileStatement && parentStatement == ((PsiWhileStatement)parent).getBody()) + || (parent instanceof PsiIfStatement && + (parentStatement == ((PsiIfStatement)parent).getThenBranch() || parentStatement == ((PsiIfStatement)parent).getElseBranch()))) + ) { + return parentStatement; + } + parentStatement = parent; + parent = parent.getParent(); + } + return parentStatement; + } + + + public static PsiElement getParentExpressionAnchorElement(PsiElement place) { + PsiElement parent = place; + while (true) { + if (isExpressionAnchorElement(parent)) break; + parent = parent.getParent(); + if (parent == null) return null; + } + PsiElement parentStatement = parent; + parent = parentStatement.getParent(); + while (parent instanceof PsiStatement) { + parentStatement = parent; + parent = parent.getParent(); + } + return parentStatement; + } + + + public static boolean isExpressionAnchorElement(PsiElement element) { + return element instanceof PsiStatement || element instanceof JspExpression + || element instanceof PsiClassInitializer + || element instanceof PsiField || element instanceof PsiMethod; + } + + /** + * @param expression + * @return loop body if expression is part of some loop's condition or for loop's increment part + * null otherwise + */ + public static PsiElement getLoopForLoopCondition(PsiExpression expression) { + PsiExpression outermost = expression; + while (outermost.getParent() instanceof PsiExpression) { + outermost = (PsiExpression)outermost.getParent(); + } + if (outermost.getParent() instanceof PsiForStatement) { + final PsiForStatement forStatement = (PsiForStatement)outermost.getParent(); + if (forStatement.getCondition() == outermost) { + return forStatement; + } + else { + return null; + } + } + if (outermost.getParent() instanceof PsiExpressionStatement && outermost.getParent().getParent() instanceof PsiForStatement) { + final PsiForStatement forStatement = (PsiForStatement)outermost.getParent().getParent(); + if (forStatement.getUpdate() == outermost.getParent()) { + return forStatement; + } + else { + return null; + } + } + if (outermost.getParent() instanceof PsiWhileStatement) { + return outermost.getParent(); + } + if (outermost.getParent() instanceof PsiDoWhileStatement) { + return outermost.getParent(); + } + return null; + } + + public static PsiClass getThisClass(PsiElement place) { + PsiElement parent = place.getContext(); + PsiElement prev = null; + while (true) { + if (parent instanceof PsiClass) { + if (!(parent instanceof PsiAnonymousClass && ((PsiAnonymousClass)parent).getArgumentList() == prev)) + return (PsiClass)parent; + } + prev = parent; + parent = parent.getContext(); + if (parent == null) return null; + } + } + + public static PsiClass getThisResolveClass(final PsiReferenceExpression place) { + final ResolveResult resolveResult = place.advancedResolve(false); + final PsiElement scope = resolveResult.getCurrentFileResolveScope(); + if (scope instanceof PsiClass) + return (PsiClass) scope; + return null; + /* + PsiElement parent = place.getContext(); + PsiElement prev = null; + while (true) { + if (parent instanceof PsiClass) { + if (!(parent instanceof PsiAnonymousClass && ((PsiAnonymousClass)parent).getArgumentList() == prev)) + return (PsiClass)parent; + } + prev = parent; + parent = parent.getContext(); + if (parent == null) return null; + } + */ + } + + public static PsiCall getEnclosingConstructorCall (PsiJavaCodeReferenceElement ref) { + PsiElement parent = ref.getParent(); + if (ref instanceof PsiReferenceExpression && parent instanceof PsiMethodCallExpression) return (PsiCall)parent; + + if (parent instanceof PsiAnonymousClass) { + parent = parent.getParent(); + } + + return parent instanceof PsiNewExpression ? (PsiNewExpression)parent : null; + } + + public static void renameVariableReferences(PsiVariable variable, String newName, SearchScope scope) + throws IncorrectOperationException { + PsiManager manager = variable.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + PsiReference[] refs = helper.findReferences(variable, scope, false); + for (int i = 0; i < refs.length; i++) { + PsiReference reference = refs[i]; + if (reference != null) { + reference.handleElementRename(newName); + } + } + } + + public static boolean canBeDeclaredFinal(PsiVariable variable) { + PsiManager manager = variable.getManager(); + PsiSearchHelper helper = manager.getSearchHelper(); + PsiReference[] refs = helper.findReferences(variable, GlobalSearchScope.projectScope(manager.getProject()), false); + for (int i = 0; i < refs.length; i++) { + PsiReferenceExpression ref = (PsiReferenceExpression)refs[i].getElement(); + if (PsiUtil.isAccessedForWriting(ref)) { + return false; // TODO: more correct check based on control flow + } + } + return true; + } + + public static PsiExpression inlineVariable(PsiLocalVariable variable, PsiExpression initializer, + PsiJavaCodeReferenceElement ref) throws IncorrectOperationException { + PsiManager manager = initializer.getManager(); + + PsiClass variableParent = RefactoringUtil.getThisClass(initializer); + PsiClass refParent = RefactoringUtil.getThisClass(ref); + initializer = convertInitializerToNormalExpression(initializer, variable.getType()); + + ChangeContextUtil.encodeContextInfo(initializer, false); + PsiExpression expr = (PsiExpression)ref.replace(initializer); + PsiType exprType = expr.getType(); + if (exprType != null && !variable.getType().isAssignableFrom(exprType)) { //can happen if initalizer's type was inferred using variable type + PsiTypeCastExpression cast = (PsiTypeCastExpression)manager.getElementFactory().createExpressionFromText("(t)a", null); + cast.getCastType().replace(variable.getTypeElement()); + cast.getOperand().replace(expr); + expr = (PsiExpression)expr.replace(cast); + } + + ChangeContextUtil.clearContextInfo(initializer); + + PsiClass thisClass = variableParent; + PsiThisExpression thisAccessExpr = null; + if (Comparing.equal(variableParent, refParent)) { + thisAccessExpr = createThisExpression(manager, null); + } + else { + if (!(thisClass instanceof PsiAnonymousClass)) { + thisAccessExpr = createThisExpression(manager, thisClass); + } + } + return (PsiExpression)ChangeContextUtil.decodeContextInfo(expr, thisClass, thisAccessExpr); + } + + public static PsiThisExpression createThisExpression(PsiManager manager, PsiClass qualifierClass) + throws IncorrectOperationException { + PsiElementFactory factory = manager.getElementFactory(); + if (qualifierClass != null) { + PsiThisExpression qualifiedThis = (PsiThisExpression)factory.createExpressionFromText("q.this", null); + qualifiedThis = (PsiThisExpression)CodeStyleManager.getInstance(manager.getProject()).reformat(qualifiedThis); + qualifiedThis.getQualifier().bindToElement(qualifierClass); + return qualifiedThis; + } + else { + return (PsiThisExpression)factory.createExpressionFromText("this", null); + } + } + + /** + * removes a reference to the specified class from the reference list given + * + * @return if removed - a reference to the class or null if there were no references to this class in the reference list + */ + public static PsiJavaCodeReferenceElement removeFromReferenceList(PsiReferenceList refList, PsiClass aClass) + throws IncorrectOperationException { + PsiJavaCodeReferenceElement[] refs = refList.getReferenceElements(); + if (refs != null) { + for (int i = 0; i < refs.length; i++) { + PsiJavaCodeReferenceElement ref = refs[i]; + if (aClass.equals(ref.resolve())) { + PsiJavaCodeReferenceElement refCopy = (PsiJavaCodeReferenceElement)ref.copy(); + ref.delete(); + return refCopy; + } + } + } + return null; + } + + public static PsiType getTypeByExpressionWithExpectedType(PsiExpression expr) { + PsiType type = getTypeByExpression(expr); + if (type != null) return type; + ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getInstance(expr.getProject()).getExpectedTypes(expr, false); + if (expectedTypes.length == 1) { + type = expectedTypes[0].getType(); + if (!type.equalsToText("java.lang.Object")) return type; + } + return null; + } + + public static PsiType getTypeByExpression(PsiExpression expr) { + PsiElementFactory factory = expr.getManager().getElementFactory(); + return getTypeByExpression(expr, factory); + } + + private static PsiType getTypeByExpression(PsiExpression expr, final PsiElementFactory factory) { + PsiType type = expr.getType(); + if (type == null) { + if (expr instanceof PsiArrayInitializerExpression) { + PsiExpression[] initializers = ((PsiArrayInitializerExpression)expr).getInitializers(); + if (initializers != null && initializers.length > 0) { + PsiType initType = getTypeByExpression(initializers[0]); + if (initType == null) return null; + return initType.createArrayType(); + } + } + return null; + } + PsiClass refClass = PsiUtil.resolveClassInType(type); + if (refClass instanceof PsiAnonymousClass) { + type = ((PsiAnonymousClass)refClass).getBaseClassType(); + } + if (type == PsiType.NULL) { + ExpectedTypeInfo[] infos = ExpectedTypesProvider.getInstance(expr.getProject()).getExpectedTypes(expr, false); + if (infos.length == 1) { + type = infos[0].getType(); + } + else { + type = factory.createTypeByFQClassName("java.lang.Object", expr.getResolveScope()); + } + } + + type = type.accept(new PsiTypeVisitor() { + public PsiType visitArrayType(PsiArrayType arrayType) { + PsiType componentType = arrayType.getComponentType(); + PsiType type = componentType.accept(this); + if (type == componentType) return arrayType; + return type.createArrayType(); + } + + public PsiType visitType(PsiType type) { + return type; + } + + public PsiType visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) { + return capturedWildcardType.getWildcard(); + } + + public PsiType visitClassType(PsiClassType classType) { + PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + PsiClass aClass = resolveResult.getElement(); + if (aClass == null) return classType; + boolean toExtend = false; + Iterator iterator = PsiUtil.typeParametersIterator(aClass); + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + while(iterator.hasNext()) { + PsiTypeParameter typeParameter = iterator.next(); + PsiType typeArgument = resolveResult.getSubstitutor().substitute(typeParameter); + if (typeArgument instanceof PsiCapturedWildcardType) toExtend = true; + substitutor = substitutor.put(typeParameter, typeArgument == null ? null : typeArgument.accept(this)); + } + + PsiType result = factory.createType(aClass, substitutor); + if (toExtend) result = PsiWildcardType.createExtends(aClass.getManager(), result); + return result; + } + }); + + PsiType componentType = type.getDeepComponentType(); + if (componentType instanceof PsiWildcardType) { + componentType = ((PsiWildcardType)componentType).getExtendsBound(); + int dims = type.getArrayDimensions(); + for (int i = 0; i < dims; i++) componentType = componentType.createArrayType(); + return componentType; + } + + return type; + } + + public static boolean isAssignmentLHS(PsiElement element) { + PsiElement parent = element.getParent(); + + if (parent instanceof PsiAssignmentExpression + && element.equals(((PsiAssignmentExpression)parent).getLExpression())) { + return true; + } + else { + return isPlusPlusOrMinusMinus(parent); + } + } + + public static boolean isPlusPlusOrMinusMinus(PsiElement element) { + if (element instanceof PsiPrefixExpression) { + PsiJavaToken operandSign = ((PsiPrefixExpression)element).getOperationSign(); + return operandSign.getTokenType() == JavaTokenType.PLUSPLUS + || operandSign.getTokenType() == JavaTokenType.MINUSMINUS; + } + else if (element instanceof PsiPostfixExpression) { + PsiJavaToken operandSign = ((PsiPostfixExpression)element).getOperationSign(); + return operandSign.getTokenType() == JavaTokenType.PLUSPLUS + || operandSign.getTokenType() == JavaTokenType.MINUSMINUS; + } + else { + return false; + } + } + + public static void removeFinalParameters(PsiMethod method) + throws IncorrectOperationException { + // Remove final parameters + PsiParameterList paramList = method.getParameterList(); + if (paramList != null) { + PsiParameter[] params = paramList.getParameters(); + + for (int i = 0; i < params.length; i++) { + PsiParameter param = params[i]; + + if (param.hasModifierProperty(PsiModifier.FINAL)) { + param.getModifierList().setModifierProperty(PsiModifier.FINAL, false); + } + } + } + } + + public static PsiElement getAnchorElementForMultipleExpressions(PsiExpression[] occurrences, PsiElement scope) { + PsiElement anchor = null; + for (int i = 0; i < occurrences.length; i++) { + PsiExpression occurrence = occurrences[i]; + if (scope != null && !PsiTreeUtil.isAncestor(scope, occurrence, false)) { + continue; + } + PsiElement anchor1 = getParentExpressionAnchorElement(occurrence); + if (anchor1 == null) { + return null; + } + if (anchor == null) { + anchor = anchor1; + } + else { + PsiElement commonParent = PsiTreeUtil.findCommonParent(anchor, anchor1); + PsiElement firstAnchor = anchor.getTextOffset() < anchor1.getTextOffset() ? anchor : anchor1; + if (commonParent.equals(firstAnchor)) { + anchor = firstAnchor; + } + else { + PsiElement parent = firstAnchor; + while (!parent.getParent().equals(commonParent)) { + parent = parent.getParent(); + } + final PsiElement newAnchor = getParentExpressionAnchorElement(parent); + if (newAnchor != null) { + anchor = newAnchor; + } + else { + anchor = parent; + } + } + } + } + + if (occurrences.length > 1 && anchor.getParent().getParent() instanceof PsiSwitchStatement) { + PsiSwitchStatement switchStatement = (PsiSwitchStatement)anchor.getParent().getParent(); + if (switchStatement.getBody().equals(anchor.getParent())) { + int startOffset = occurrences[0].getTextRange().getStartOffset(); + int endOffset = occurrences[occurrences.length - 1].getTextRange().getEndOffset(); + PsiStatement[] statements = switchStatement.getBody().getStatements(); + boolean isInDifferentCases = false; + for (int i = 0; i < statements.length; i++) { + PsiStatement statement = statements[i]; + if (statement instanceof PsiSwitchLabelStatement) { + int caseOffset = statement.getTextOffset(); + if (startOffset < caseOffset && caseOffset < endOffset) { + isInDifferentCases = true; + break; + } + } + } + if (isInDifferentCases) { + anchor = switchStatement; + } + } + } + + return anchor; + } + + public static void setVisibility(PsiModifierList modifierList, String newVisibility) + throws IncorrectOperationException { + modifierList.setModifierProperty(PsiModifier.PRIVATE, false); + modifierList.setModifierProperty(PsiModifier.PUBLIC, false); + modifierList.setModifierProperty(PsiModifier.PROTECTED, false); + modifierList.setModifierProperty(newVisibility, true); + } + + public static boolean isMethodUsage(PsiElement element) { + if (!(element instanceof PsiJavaCodeReferenceElement)) return false; + PsiElement parent = element.getParent(); + if (parent instanceof PsiCall) { + return true; + } + else if (parent instanceof PsiAnonymousClass) { + return element.equals(((PsiAnonymousClass)parent).getBaseClassReference()); + } + else { + return false; + } + } + + public static PsiExpressionList getArgumentListByMethodReference(PsiJavaCodeReferenceElement ref) { + PsiElement parent = ref.getParent(); + if (parent instanceof PsiCall) { + return ((PsiCall)parent).getArgumentList(); + } + else if (parent instanceof PsiAnonymousClass) { + return ((PsiNewExpression)parent.getParent()).getArgumentList(); + } + else { + LOG.assertTrue(false); + return null; + } + } + + public static PsiCallExpression getCallExpressionByMethodReference(PsiJavaCodeReferenceElement ref) { + PsiElement parent = ref.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return (PsiMethodCallExpression)parent; + } + else if (parent instanceof PsiNewExpression) { + return (PsiNewExpression)parent; + } + else if (parent instanceof PsiAnonymousClass) { + return (PsiNewExpression)parent.getParent(); + } + else { + LOG.assertTrue(false); + return null; + } + } + + /** + * @return List of highlighters + */ + public static ArrayList highlightAllOccurences(Project project, PsiElement[] occurences, Editor editor) { + ArrayList highlighters = new ArrayList(); + HighlightManager highlightManager = HighlightManager.getInstance(project); + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + highlightManager.addOccurrenceHighlights(editor, occurences, attributes, true, highlighters); + return highlighters; + } + + public static ArrayList highlightOccurences(Project project, PsiElement[] occurences, Editor editor) { + if (occurences.length > 1) { + return highlightAllOccurences(project, occurences, editor); + } + return new ArrayList(); + } + + public static String createTempVar(PsiExpression expr, PsiElement context, boolean declareFinal) + throws IncorrectOperationException { + PsiElement anchorStatement = getParentStatement(context, true); + LOG.assertTrue(anchorStatement != null && anchorStatement.getParent() != null); + + Project project = expr.getProject(); + String[] suggestedNames = + CodeStyleManager.getInstance(project).suggestVariableName(VariableKind.LOCAL_VARIABLE, null, expr, null).names; + final String prefix = suggestedNames[0]; + final String id = CodeStyleManager.getInstance(project).suggestUniqueVariableName(prefix, context, true); + + PsiElementFactory factory = expr.getManager().getElementFactory(); + + if (expr instanceof PsiParenthesizedExpression) { + PsiExpression expr1 = ((PsiParenthesizedExpression)expr).getExpression(); + if (expr1 != null) { + expr = expr1; + } + } + PsiDeclarationStatement decl = + factory.createVariableDeclarationStatement(id, expr.getType(), expr); + if (declareFinal) { + ((PsiLocalVariable)decl.getDeclaredElements()[0]).getModifierList().setModifierProperty(PsiModifier.FINAL, true); + } + anchorStatement.getParent().addBefore(decl, anchorStatement); + + return id; + } + + public static int verifySafeCopyExpression(PsiElement expr) { + return verifySafeCopyExpressionSubElement(expr); + + } + + private static int verifySafeCopyExpressionSubElement(PsiElement element) { + int result = EXPR_COPY_SAFE; + if (element == null) return result; + + if (element instanceof PsiThisExpression + || element instanceof PsiSuperExpression + || element instanceof PsiIdentifier + ) { + return EXPR_COPY_SAFE; + } + + if (element instanceof PsiMethodCallExpression) { + result = EXPR_COPY_UNSAFE; + } + + if (element instanceof PsiNewExpression) { + return EXPR_COPY_PROHIBITED; + } + + if (element instanceof PsiAssignmentExpression) { + return EXPR_COPY_PROHIBITED; + } + + if (isPlusPlusOrMinusMinus(element)) { + return EXPR_COPY_PROHIBITED; + } + + PsiElement[] children = element.getChildren(); + + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + + int childResult = verifySafeCopyExpressionSubElement(child); + result = Math.max(result, childResult); + } + return result; + } + + public static PsiExpression convertInitializerToNormalExpression(PsiExpression expression, + PsiType forcedReturnType) + throws IncorrectOperationException { + PsiExpression returnValue; + if (expression instanceof PsiArrayInitializerExpression) { + returnValue = + createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression)expression, + forcedReturnType); + } + else { + returnValue = expression; + } + return returnValue; + } + + public static PsiExpression createNewExpressionFromArrayInitializer(PsiArrayInitializerExpression initializer, + PsiType forcedType) + throws IncorrectOperationException { + PsiType initializerType = null; + if (initializer != null) { +// initializerType = myExpresssion.getType(); + if (forcedType != null) { + initializerType = forcedType; + } + else { + initializerType = getTypeByExpression(initializer); + } + } + if (initializerType == null) { + return initializer; + } + LOG.assertTrue(initializerType instanceof PsiArrayType); + PsiElementFactory factory = initializer.getManager().getElementFactory(); + PsiNewExpression result = + (PsiNewExpression)factory.createExpressionFromText("new " + initializerType.getPresentableText() + "{}", null); + result = (PsiNewExpression)CodeStyleManager.getInstance(initializer.getProject()).reformat(result); + result.getArrayInitializer().replace(initializer); + return result; + } + + public static void abstractizeMethod(PsiClass targetClass, PsiMethod method) throws IncorrectOperationException { + PsiCodeBlock body = method.getBody(); + if (body != null) { + body.delete(); + } + + method.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true); + method.getModifierList().setModifierProperty(PsiModifier.FINAL, false); + method.getModifierList().setModifierProperty(PsiModifier.SYNCHRONIZED, false); + method.getModifierList().setModifierProperty(PsiModifier.NATIVE, false); + + if (!targetClass.isInterface()) { + targetClass.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true); + } + + removeFinalParameters(method); + } + + public static boolean isInsideAnonymous(PsiElement element, PsiElement upTo) { + for (PsiElement current = element; + current != null && current != upTo; + current = current.getParent()) { + if (current instanceof PsiAnonymousClass) return true; + } + return false; + } + + public static PsiExpression unparenthesizeExpression(PsiExpression expression) { + while (expression instanceof PsiParenthesizedExpression) { + final PsiExpression innerExpression = ((PsiParenthesizedExpression)expression).getExpression(); + if (innerExpression == null) return expression; + expression = innerExpression; + } + return expression; + } + + /** + * @param expression + * @return + */ + public static PsiExpression outermostParenthesizedExpression(PsiExpression expression) { + while (expression.getParent() instanceof PsiParenthesizedExpression) { + expression = (PsiParenthesizedExpression)expression.getParent(); + } + return expression; + } + + public static String getStringToSearch(PsiElement element, boolean nonJava) { + if (element instanceof PsiDirectory) { // normalize a directory to a corresponding package + element = ((PsiDirectory)element).getPackage(); + } + + if (element instanceof PsiPackage) { + return nonJava ? ((PsiPackage)element).getQualifiedName() : ((PsiPackage)element).getName(); + } + else if (element instanceof PsiClass) { + return nonJava ? ((PsiClass)element).getQualifiedName() : ((PsiClass)element).getName(); + } + else if (element instanceof XmlTag) { + return ((XmlTag)element).getValue().getTrimmedText(); + } + else if (element instanceof XmlAttribute) { + return ((XmlAttribute)element).getValue(); + } + else if (element instanceof PsiNamedElement) { + return ((PsiNamedElement)element).getName(); + } + else { + LOG.error("Unknown element type"); + return null; + } + } + + public static String getInnerClassNameForClassLoader(PsiClass aClass) { + final String qName = aClass.getQualifiedName(); + return replaceDotsWithDollars(qName, aClass); + + } + + public static String replaceDotsWithDollars(final String qName, PsiClass aClass) { + StringBuffer qNameBuffer = new StringBuffer(qName); + + int fromIndex = qNameBuffer.length(); + PsiElement parent = aClass.getParent(); + while (parent instanceof PsiClass) { + final int dotIndex = qNameBuffer.lastIndexOf(".", fromIndex); + if (dotIndex < 0) break; + qNameBuffer.replace(dotIndex, dotIndex + 1, "$"); + fromIndex = dotIndex - 1; + parent = parent.getParent(); + } + return qNameBuffer.toString(); + } + + public static String getNewInnerClassName(PsiClass aClass, String oldInnerClassName, String newName) { + if (!oldInnerClassName.endsWith(aClass.getName())) return newName; + StringBuffer buffer = new StringBuffer(oldInnerClassName); + buffer.replace(buffer.length() - aClass.getName().length(), buffer.length(), newName); + return buffer.toString(); + } + + public static boolean isSuperOrThisCall(PsiStatement statement, boolean testForSuper, boolean testForThis) { + if (!(statement instanceof PsiExpressionStatement)) return false; + PsiExpression expression = ((PsiExpressionStatement)statement).getExpression(); + if (!(expression instanceof PsiMethodCallExpression)) return false; + final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression(); + if (testForSuper) { + if ("super".equals(methodExpression.getText())) return true; + } + if (testForThis) { + if ("this".equals(methodExpression.getText())) return true; + } + + return false; + } + + public static void visitImplicitConstructorUsages(PsiClass aClass, + final ImplicitConstructorUsageVisitor implicitConstructorUsageVistor) { + PsiManager manager = aClass.getManager(); + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); + final PsiClass[] inheritors = manager.getSearchHelper().findInheritors(aClass, projectScope, false); + + for (int i = 0; i < inheritors.length; i++) { + PsiClass inheritor = inheritors[i]; + + visitImplicitSuperConstructorUsages(inheritor, implicitConstructorUsageVistor); + } + } + + public static void visitImplicitSuperConstructorUsages(PsiClass subClass, + final ImplicitConstructorUsageVisitor implicitConstructorUsageVistor) { + final PsiMethod[] constructors = subClass.getConstructors(); + if (constructors.length > 0) { + for (int j = 0; j < constructors.length; j++) { + PsiMethod constructor = constructors[j]; + final PsiStatement[] statements = constructor.getBody().getStatements(); + if (statements.length < 1 || !isSuperOrThisCall(statements[0], true, true)) { + implicitConstructorUsageVistor.visitConstructor(constructor); + } + } + } + else { + implicitConstructorUsageVistor.visitClassWithoutConstructors(subClass); +// visitImplicitConstructorUsages(inheritor, implicitConstructorUsageVistor); + } + } + + public static interface ImplicitConstructorUsageVisitor { + void visitConstructor(PsiMethod constructor); + + void visitClassWithoutConstructors(PsiClass aClass); + } + + public interface Graph { + Set getVertices(); + + Set getTargets(T source); + } + + /** + * Returns subset of graph.getVertices() that is a tranistive closure (by graph.getTargets()) + * of the following property: initialRelation.value() of vertex or graph.getTargets(vertex) is true. + *

    + * Note that graph.getTargets() is not neccesrily a subset of graph.getVertex() + * + * @param graph + * @param initialRelation + * @return subset of graph.getVertices() + */ + public static Set transitiveClosure(Graph graph, Condition initialRelation) { + Set result = new HashSet(); + + final Set vertices = graph.getVertices(); + boolean anyChanged; + do { + anyChanged = false; + for (Iterator iterator = vertices.iterator(); iterator.hasNext();) { + T currentVertex = iterator.next(); + if (!result.contains(currentVertex)) { + if (!initialRelation.value(currentVertex)) { + Set targets = graph.getTargets(currentVertex); + for (Iterator targetsIterator = targets.iterator(); targetsIterator.hasNext();) { + T currentTarget = targetsIterator.next(); + if (result.contains(currentTarget) || initialRelation.value(currentTarget)) { + result.add(currentVertex); + anyChanged = true; + break; + } + } + } + else { + result.add(currentVertex); + } + } + } + } + while (anyChanged); + return result; + } + + public static boolean equivalentTypes(PsiType t1, PsiType t2, PsiManager manager) { + while (t1 instanceof PsiArrayType) { + if (!(t2 instanceof PsiArrayType)) return false; + t1 = ((PsiArrayType)t1).getComponentType(); + t2 = ((PsiArrayType)t2).getComponentType(); + } + + if (t1 instanceof PsiPrimitiveType) { + if (t2 instanceof PsiPrimitiveType) { + return t1.equals(t2); + } + else { + return false; + } + } + + return manager.areElementsEquivalent(PsiUtil.resolveClassInType(t1), PsiUtil.resolveClassInType(t2)); + } + + public static List collectReferencedVariables(PsiElement scope) { + final List result = new ArrayList(); + scope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiElement element = expression.resolve(); + if (element instanceof PsiVariable) { + result.add((PsiVariable)element); + } + final PsiExpression qualifier = expression.getQualifierExpression(); + if (qualifier != null) { + qualifier.accept(this); + } + } + }); + return result; + } + + public static boolean isModifiedInScope(PsiVariable variable, PsiElement scope) { + final PsiReference[] references = variable.getManager().getSearchHelper().findReferences(variable, new LocalSearchScope(scope), false); + for (int i = 0; i < references.length; i++) { + PsiReference reference = references[i]; + if (isAssignmentLHS(reference.getElement())) return true; + } + return false; + } + + public static String getNameOfReferencedParameter(PsiDocTag tag) { + LOG.assertTrue("param".equals(tag.getName())); + final PsiElement[] dataElements = tag.getDataElements(); + if (dataElements.length < 1) return null; + return dataElements[0].getText(); + } + + public static void fixJavadocsForParams(PsiMethod method, Set newParameters) throws IncorrectOperationException { + final PsiDocComment docComment = method.getDocComment(); + if (docComment == null) return; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final PsiDocTag[] paramTags = docComment.findTagsByName("param"); + if (parameters.length > 0 && newParameters.size() < parameters.length && paramTags.length == 0) return; + Map tagForParam = new HashMap(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + boolean found = false; + for (int j = 0; j < paramTags.length; j++) { + PsiDocTag paramTag = paramTags[j]; + if (parameter.getName().equals(getNameOfReferencedParameter(paramTag))) { + tagForParam.put(parameter, paramTag); + found = true; + break; + } + } + if (!found && !newParameters.contains(parameter)) { + tagForParam.put(parameter, null); + } + } + + List newTags = new ArrayList(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (tagForParam.containsKey(parameter)) { + final PsiDocTag psiDocTag = tagForParam.get(parameter); + if (psiDocTag != null) { + newTags.add((PsiDocTag)psiDocTag.copy()); + } + } + else { + newTags.add(method.getManager().getElementFactory().createParamTag(parameter.getName(), "")); + } + } + PsiDocTag anchor = paramTags.length > 0 ? paramTags[paramTags.length - 1] : null; + for (Iterator iterator = newTags.iterator(); iterator.hasNext();) { + PsiDocTag psiDocTag = iterator.next(); + anchor = (PsiDocTag)docComment.addAfter(psiDocTag, anchor); + } + for (int i = 0; i < paramTags.length; i++) { + PsiDocTag paramTag = paramTags[i]; + paramTag.delete(); + } + } + + public static PsiDirectory createPackageDirectoryInSourceRoot(PackageWrapper aPackage, final VirtualFile sourceRoot) + throws IncorrectOperationException { + final PsiDirectory[] directories = aPackage.getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (VfsUtil.isAncestor(sourceRoot, directory.getVirtualFile(), false)) { + return directory; + } + } + String qNameToCreate = qNameToCreateInSourceRoot(aPackage, sourceRoot); + final String[] shortNames = qNameToCreate.split("\\."); + PsiDirectory current = aPackage.getManager().findDirectory(sourceRoot); + LOG.assertTrue(current != null); + for (int i = 0; i < shortNames.length; i++) { + String shortName = shortNames[i]; + PsiDirectory subdirectory = current.findSubdirectory(shortName); + if (subdirectory == null) { + subdirectory = current.createSubdirectory(shortName); + } + current = subdirectory; + } + return current; + } + + public static String qNameToCreateInSourceRoot(PackageWrapper aPackage, final VirtualFile sourceRoot) + throws IncorrectOperationException { + String targetQName = aPackage.getQualifiedName(); + String sourceRootPackage = ProjectRootManager.getInstance(aPackage.getManager().getProject()).getFileIndex().getPackageNameByDirectory(sourceRoot); + if (sourceRootPackage == null || !targetQName.startsWith(sourceRootPackage)) { + throw new IncorrectOperationException("Cannot create package '" + targetQName + "' in source folder " + sourceRoot.getPresentableUrl()); + } + String temp = targetQName.substring(sourceRootPackage.length()); + if (StringUtil.startsWithChar(temp, '.')) temp = temp.substring(1); // remove initial '.' + String qNameToCreate = temp; + return qNameToCreate; + } + + + public static PsiDirectory findPackageDirectoryInSourceRoot(PackageWrapper aPackage, final VirtualFile sourceRoot) { + final PsiDirectory[] directories = aPackage.getDirectories(); + for (int i = 0; i < directories.length; i++) { + PsiDirectory directory = directories[i]; + if (VfsUtil.isAncestor(sourceRoot, directory.getVirtualFile(), false)) { + return directory; + } + } + String qNameToCreate; + try { + qNameToCreate = qNameToCreateInSourceRoot(aPackage, sourceRoot); + } + catch (IncorrectOperationException e) { + return null; + } + final String[] shortNames = qNameToCreate.split("\\."); + PsiDirectory current = aPackage.getManager().findDirectory(sourceRoot); + LOG.assertTrue(current != null); + for (int i = 0; i < shortNames.length; i++) { + String shortName = shortNames[i]; + PsiDirectory subdirectory = current.findSubdirectory(shortName); + if (subdirectory == null) { + return null; + } + current = subdirectory; + } + return current; + } + + public static String calculatePsiElementDescriptionList(PsiElement[] elements, StringBuffer buffer) { + if (elements.length == 1) { + buffer.append(UsageViewUtil.getType(elements[0])); + buffer.append(' '); + buffer.append(UsageViewUtil.getDescriptiveName(elements[0])); + } + else { + Map> map = new HashMap>(); + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + final String type = UsageViewUtil.getType(element); + Ref ref = map.get(type); + if (ref == null) { + ref = Ref.create(new Integer(0)); + } + ref.set(new Integer(ref.get().intValue() + 1)); + } + + // !!! do not insert type parameters while JDK 1.4 still used as main DK for IDEA development + Set entries = map.entrySet(); + int index = 0; + for (Iterator iterator = entries.iterator(); iterator.hasNext(); index++) { + Map.Entry entry = (Map.Entry) iterator.next(); + final String type = (String) entry.getKey(); + final int count = ((Ref) entry.getValue()).get().intValue(); + if (index > 0 && index + 1 < entries.size()) { + buffer.append(" ,"); + } + else if (index > 0 && index == entries.size()) { + buffer.append(" and "); + } + buffer.append(count); + buffer.append(" "); + buffer.append(count > 1 ? type : StringUtil.pluralize(type)); + } + } + return buffer.toString(); + } + + + public static class ConditionCache implements Condition { + private final Condition myCondition; + private final HashSet myProcessedSet = new HashSet(); + private final HashSet myTrueSet = new HashSet(); + + public ConditionCache(Condition condition) { + myCondition = condition; + } + + public boolean value(T object) { + if (!myProcessedSet.contains(object)) { + myProcessedSet.add(object); + final boolean value = myCondition.value(object); + if (value) { + myTrueSet.add(object); + return true; + } + return false; + } + return myTrueSet.contains(object); + } + } + + public static class IsInheritorOf implements Condition { + private final PsiClass myClass; + private final ConditionCache myConditionCache; + + public IsInheritorOf(PsiClass aClass) { + myClass = aClass; + myConditionCache = new ConditionCache(new MyCondition()); + } + + public boolean value(PsiClass object) { + return myConditionCache.value(object); + } + + private class MyCondition implements Condition { + public boolean value(PsiClass aClass) { + return aClass.isInheritor(myClass, true); + } + } + } + + public static class IsDescendantOf implements Condition { + private final PsiClass myClass; + private final ConditionCache myConditionCache; + + public IsDescendantOf(PsiClass aClass) { + myClass = aClass; + myConditionCache = new ConditionCache(new Condition() { + public boolean value(PsiClass aClass) { + return InheritanceUtil.isInheritorOrSelf(aClass, myClass, true); + } + }); + } + + public boolean value(PsiClass aClass) { + return myConditionCache.value(aClass); + } + } + + public static PsiElement[] getChilderenWithoutWhitespaceOrComments(PsiElement parent) { + List result = new ArrayList(); + for (PsiElement current = parent.getFirstChild(); current != null; current = current.getNextSibling()) { + if (!(current instanceof PsiWhiteSpace || current instanceof PsiComment)) { + result.add(current); + } + } + return result.toArray(new PsiElement[result.size()]); + } + + public static void processIncorrectOperation(final Project project, IncorrectOperationException e) { + final String message = e.getMessage(); + final int index = message != null ? message.indexOf("java.io.IOException") : -1; + if (index >= 0) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showMessageDialog(project, message.substring(index + "java.io.IOException".length()), "Error", + Messages.getErrorIcon()); + } + }); + } + else { + LOG.error(e); + } + } + + public static > T analyzeModuleConflicts(Project project, + Collection scope, + PsiElement target, + final T conflicts) { + if (scope == null) return conflicts; + final VirtualFile vFile; + if (!(target instanceof PsiDirectory)) { + vFile = target.getContainingFile().getVirtualFile(); + } + else { + vFile = ((PsiDirectory)target).getVirtualFile(); + } + if (vFile == null) return conflicts; + return analyzeModuleConflicts(project, scope, vFile, conflicts); + } + + public static > T analyzeModuleConflicts(Project project, + final Collection scopes, + final VirtualFile vFile, + final T conflicts) { + if (scopes == null) return conflicts; + + for (Iterator iterator = scopes.iterator(); iterator.hasNext();) { + final PsiElement scope = iterator.next(); + if (scope instanceof PsiPackage || scope instanceof PsiDirectory) return conflicts; + } + + final Module targetModule = ModuleUtil.getModuleForFile(project, vFile); + if (targetModule == null) return conflicts; + final GlobalSearchScope resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule); + final HashSet reported = new HashSet(); + for (Iterator iterator = scopes.iterator(); iterator.hasNext();) { + final PsiElement scope = iterator.next(); + scope.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + super.visitReferenceElement(reference); + final PsiElement resolved = reference.resolve(); + if (resolved != null && !reported.contains(resolved) + && !isAncestor(resolved, scopes) + && !PsiSearchScopeUtil.isInScope(resolveScope, resolved)) { + final String scopeDescription = ConflictsUtil.htmlEmphasize(ConflictsUtil.getDescription(ConflictsUtil.getContainer(reference), true)); + final String message = + ConflictsUtil.capitalize(ConflictsUtil.htmlEmphasize(ConflictsUtil.getDescription(resolved, true))) + + ", referenced in " + scopeDescription + + ", will not be accessible in module " + + ConflictsUtil.htmlEmphasize(targetModule.getName()); + conflicts.add(message); + reported.add(resolved); + } + } + }); + + } + return conflicts; + } + + private static boolean isAncestor(final PsiElement resolved, final Collection scopes) { + for (Iterator iterator = scopes.iterator(); iterator.hasNext();) { + final PsiElement scope = iterator.next(); + if (PsiTreeUtil.isAncestor(scope, resolved, false)) return true; + } + return false; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/VisibilityUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/VisibilityUtil.java new file mode 100644 index 00000000000..f6afce73c1c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/VisibilityUtil.java @@ -0,0 +1,73 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 07.06.2002 + * Time: 18:48:01 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util; + +import com.intellij.psi.*; +import com.intellij.psi.util.*; +import com.intellij.util.IncorrectOperationException; + + +public class VisibilityUtil { + private static final String[] visibilityModifiers = { + PsiModifier.PRIVATE, + PsiModifier.PACKAGE_LOCAL, + PsiModifier.PROTECTED, + PsiModifier.PUBLIC + }; + + public static String getHighestVisibility(String v1, String v2) { + if(v1.equals(v2)) return v1; + + if(PsiModifier.PRIVATE.equals(v1)) return v2; + if(PsiModifier.PUBLIC.equals(v1)) return PsiModifier.PUBLIC; + if(PsiModifier.PRIVATE.equals(v2)) return v1; + if(PsiModifier.PUBLIC.equals(v2)) return PsiModifier.PUBLIC; + + return PsiModifier.PUBLIC; + } + + public static void escalateVisibility(PsiMember modifierListOwner, PsiElement place) + throws IncorrectOperationException { + final String visibilityModifier = getVisibilityModifier(modifierListOwner.getModifierList()); + int index; + for (index = 0; index < visibilityModifiers.length; index++) { + String modifier = visibilityModifiers[index]; + if(modifier.equals(visibilityModifier)) break; + } + for(;index < visibilityModifiers.length && !PsiUtil.isAccessible(modifierListOwner, place, null); index++) { + modifierListOwner.getModifierList().setModifierProperty(visibilityModifiers[index], true); + } + } + + public static String getVisibilityModifier(PsiModifierList list) { + if (list == null) return PsiModifier.PACKAGE_LOCAL; + for (int i = 0; i < visibilityModifiers.length; i++) { + String modifier = visibilityModifiers[i]; + if(list.hasModifierProperty(modifier)) + return modifier; + } + return PsiModifier.PACKAGE_LOCAL; + } + + public static boolean isVisibilityModifier(String s) { + for (int i = 0; i < visibilityModifiers.length; i++) { + String modifier = visibilityModifiers[i]; + if(modifier.equals(s)) return true; + } + + return false; + } + + public static String getVisibilityString(String visibilityModifier) { + if(PsiModifier.PACKAGE_LOCAL.equals(visibilityModifier)) { + return ""; + } + else return visibilityModifier; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java new file mode 100644 index 00000000000..a77d81c5f88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java @@ -0,0 +1,72 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:20:25 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +public class ANDCombinedMemberInfoModel implements MemberInfoModel { + private final MemberInfoModel myModel1; + private final MemberInfoModel myModel2; + private final MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(MemberInfo memberInfo) { + final String tooltipText1 = myModel1.getTooltipText(memberInfo); + if (tooltipText1 != null) return tooltipText1; + return myModel2.getTooltipText(memberInfo); + } + }); + + + public ANDCombinedMemberInfoModel(MemberInfoModel model1, MemberInfoModel model2) { + myModel1 = model1; + myModel2 = model2; + } + + public boolean isMemberEnabled(MemberInfo member) { + return myModel1.isMemberEnabled(member) && myModel2.isMemberEnabled(member); + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return myModel1.isCheckedWhenDisabled(member) && myModel2.isCheckedWhenDisabled(member); + } + + public boolean isAbstractEnabled(MemberInfo member) { + return myModel1.isAbstractEnabled(member) && myModel2.isAbstractEnabled(member); + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + return myModel1.isAbstractWhenDisabled(member) && myModel2.isAbstractWhenDisabled(member); + } + + public int checkForProblems(MemberInfo member) { + return Math.max(myModel1.checkForProblems(member), myModel2.checkForProblems(member)); + } + + public void memberInfoChanged(MemberInfoChange event) { + myTooltipManager.invalidate(); + myModel1.memberInfoChanged(event); + myModel2.memberInfoChanged(event); + } + + public Boolean isFixedAbstract(MemberInfo member) { + final Boolean fixedAbstract1 = myModel1.isFixedAbstract(member); + if(fixedAbstract1 == null) return null; + if(fixedAbstract1.equals(myModel2.isFixedAbstract(member))) return fixedAbstract1; + return null; + } + + public MemberInfoModel getModel1() { + return myModel1; + } + + public MemberInfoModel getModel2() { + return myModel2; + } + + public String getTooltipText(MemberInfo member) { + return myTooltipManager.getTooltip(member); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMemberReferencesVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMemberReferencesVisitor.java new file mode 100644 index 00000000000..3aa46a97e3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMemberReferencesVisitor.java @@ -0,0 +1,84 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 24.06.2002 + * Time: 18:22:48 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.psi.util.*; + +public abstract class ClassMemberReferencesVisitor extends PsiRecursiveElementVisitor { + private final PsiClass myClass; + + public ClassMemberReferencesVisitor(PsiClass aClass) { + myClass = aClass; + } + + public void visitReferenceExpression(PsiReferenceExpression expression) { + PsiExpression qualifier = expression.getQualifierExpression(); + if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) { + qualifier.accept(this); + if (!(qualifier instanceof PsiReferenceExpression) + || !(((PsiReferenceExpression) qualifier).resolve() instanceof PsiClass)) { + return; + } + } + + PsiElement referencedElement = expression.resolve(); + + if (referencedElement != null) { + PsiClass containingClass = null; + if (referencedElement instanceof PsiField) { + containingClass = ((PsiField) referencedElement).getContainingClass(); + } else if (referencedElement instanceof PsiMethod) { + containingClass = ((PsiMethod) referencedElement).getContainingClass(); + } else if (referencedElement instanceof PsiClass) { + if (PsiTreeUtil.isAncestor(myClass, referencedElement, true)) { + visitClassMemberReferenceExpression((PsiMember)referencedElement, expression); + return; + } + } + if (isPartOf(myClass, containingClass)) { + visitClassMemberReferenceExpression((PsiMember)referencedElement, expression); + } + } + } + + private static boolean isPartOf(PsiClass elementClass, PsiClass containingClass) { + if (containingClass == null) return false; + if (elementClass.equals(containingClass) || elementClass.isInheritor(containingClass, true)) { + return true; + } else { + return false; + } + } + + protected void visitClassMemberReferenceExpression(PsiMember classMember, + PsiReferenceExpression classMemberReferenceExpression) { + visitClassMemberReferenceElement(classMember, classMemberReferenceExpression); + } + + protected abstract void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference); + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + PsiElement referencedElement = reference.resolve(); + if (referencedElement instanceof PsiClass) { + final PsiClass referencedClass = (PsiClass) referencedElement; + if (PsiTreeUtil.isAncestor(myClass, referencedElement, true)) { + visitClassMemberReferenceElement((PsiMember)referencedElement, reference); + } + else if (isPartOf (myClass, referencedClass.getContainingClass())) + { + visitClassMemberReferenceElement((PsiMember)referencedElement, reference); + } + } + } + + protected final PsiClass getPsiClass() { + return myClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java new file mode 100644 index 00000000000..25bb83da59c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +public class ClassMembersUtil { + public static boolean isProperMember(MemberInfo memberInfo) { + final PsiElement member = memberInfo.getMember(); + return member instanceof PsiField || member instanceof PsiMethod + || (member instanceof PsiClass && memberInfo.getOverrides() == null); + } + + public static boolean isImplementedInterface(MemberInfo memberInfo) { + return memberInfo.getMember() instanceof PsiClass && Boolean.FALSE.equals(memberInfo.getOverrides()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassThisReferencesVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassThisReferencesVisitor.java new file mode 100644 index 00000000000..cc53a2257d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ClassThisReferencesVisitor.java @@ -0,0 +1,91 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.HashMap; + +import java.util.HashSet; + +/** + * Visits explicit and implicit references to 'this' + * @author dsl + */ +public abstract class ClassThisReferencesVisitor extends ClassMemberReferencesVisitor { + HashSet myClassSuperClasses; + HashMap mySupers; + public ClassThisReferencesVisitor(PsiClass aClass) { + super(aClass); + myClassSuperClasses = new HashSet(); + myClassSuperClasses.add(aClass); + mySupers = new HashMap(); + } + + public void visitThisExpression(PsiThisExpression expression) { + PsiJavaCodeReferenceElement ref = expression.getQualifier(); + if(ref != null) { + PsiElement element = ref.resolve(); + if(element instanceof PsiClass) { + PsiClass aClass = (PsiClass) element; + if(myClassSuperClasses.contains(aClass)) { + visitExplicitThis(aClass, expression); + } + if(aClass.isInheritor(getPsiClass(), true)) { + myClassSuperClasses.add(aClass); + visitExplicitThis(aClass, expression); + } + } + ref.accept(this); + } + else { + PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); + if(containingClass != null) { + if(getPsiClass().getManager().areElementsEquivalent(getPsiClass(), containingClass)) { + visitExplicitThis(getPsiClass(), expression); + } + } + } + } + + public void visitSuperExpression(PsiSuperExpression expression) { + PsiJavaCodeReferenceElement ref = expression.getQualifier(); + if (ref != null) { + PsiElement element = ref.resolve(); + if (element instanceof PsiClass) { + PsiClass aClass = (PsiClass) element; + if (myClassSuperClasses.contains(aClass)) { + visitExplicitSuper(getSuper(aClass), expression); + } + if (aClass.isInheritor(getPsiClass(), true)) { + myClassSuperClasses.add(aClass); + visitExplicitSuper(getSuper(aClass), expression); + } + } + ref.accept(this); + } + else { + PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); + if (containingClass != null) { + if (getPsiClass().getManager().areElementsEquivalent(getPsiClass(), containingClass)) { + visitExplicitSuper(getSuper(getPsiClass()), expression); + } + } + } + } + + private PsiClass getSuper(final PsiClass aClass) { + PsiClass result = (PsiClass) mySupers.get(aClass); + if(result == null) { + PsiClass[] supers = aClass.getSupers(); + if(supers.length > 0) { + result = supers[0]; + mySupers.put(aClass, result); + } + } + return result; + } + + + protected abstract void visitExplicitThis(PsiClass referencedClass, PsiThisExpression reference); + protected abstract void visitExplicitSuper(PsiClass referencedClass, PsiSuperExpression reference); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java new file mode 100644 index 00000000000..e1084cd9ad7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java @@ -0,0 +1,57 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:44:58 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +public class DelegatingMemberInfoModel implements MemberInfoModel { + private MemberInfoModel myDelegatingTarget; + + public DelegatingMemberInfoModel(MemberInfoModel delegatingTarget) { + myDelegatingTarget = delegatingTarget; + } + + protected DelegatingMemberInfoModel() { + + } + + public MemberInfoModel getDelegatingTarget() { + return myDelegatingTarget; + } + + public boolean isMemberEnabled(MemberInfo member) { + return myDelegatingTarget.isMemberEnabled(member); + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return myDelegatingTarget.isCheckedWhenDisabled(member); + } + + public boolean isAbstractEnabled(MemberInfo member) { + return myDelegatingTarget.isAbstractEnabled(member); + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + return myDelegatingTarget.isAbstractWhenDisabled(member); + } + + public int checkForProblems(MemberInfo member) { + return myDelegatingTarget.checkForProblems(member); + } + + public void memberInfoChanged(MemberInfoChange event) { + myDelegatingTarget.memberInfoChanged(event); + } + + public Boolean isFixedAbstract(MemberInfo member) { + return myDelegatingTarget.isFixedAbstract(member); + } + + public String getTooltipText(MemberInfo member) { + return myDelegatingTarget.getTooltipText(member); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java new file mode 100644 index 00000000000..51ee161b36d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java @@ -0,0 +1,71 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:03:42 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +public abstract class DependencyMemberInfoModel implements MemberInfoModel { + protected MemberDependencyGraph myMemberDependencyGraph; + private final int myProblemLevel; + private MemberInfoTooltipManager myTooltipManager; + + public DependencyMemberInfoModel(MemberDependencyGraph memberDependencyGraph, int problemLevel) { + myMemberDependencyGraph = memberDependencyGraph; + myProblemLevel = problemLevel; + } + + public void setTooltipProvider(MemberInfoTooltipManager.TooltipProvider tooltipProvider) { + myTooltipManager = new MemberInfoTooltipManager(tooltipProvider); + } + + public boolean isAbstractEnabled(MemberInfo member) { + return true; + } + + public boolean isAbstractWhenDisabled(MemberInfo member) { + return false; + } + + public boolean isMemberEnabled(MemberInfo member) { + return true; + } + + public int checkForProblems(MemberInfo memberInfo) { + if (memberInfo.isChecked()) return OK; + final PsiElement member = memberInfo.getMember(); + + if (myMemberDependencyGraph.getDependent().contains(member)) { + return myProblemLevel; + } + return OK; + } + + public void setMemberDependencyGraph(MemberDependencyGraph memberDependencyGraph) { + myMemberDependencyGraph = memberDependencyGraph; + } + + public void memberInfoChanged(MemberInfoChange event) { + memberInfoChanged(event.getChangedMembers()); + } + + public void memberInfoChanged(final MemberInfo[] changedMembers) { + if (myTooltipManager != null) myTooltipManager.invalidate(); + for (int i = 0; i < changedMembers.length; i++) { + myMemberDependencyGraph.memberChanged(changedMembers[i]); + } + } + + public String getTooltipText(MemberInfo member) { + if (myTooltipManager != null) { + return myTooltipManager.getTooltip(member); + } else { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java new file mode 100644 index 00000000000..db0902af0e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java @@ -0,0 +1,44 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class ElementNeedsThis extends ClassThisReferencesVisitor { + private boolean myResult = false; + private PsiElement myMember; + + public ElementNeedsThis(PsiClass aClass, PsiElement member) { + super(aClass); + myMember = member; + } + + public ElementNeedsThis(PsiClass aClass) { + super(aClass); + myMember = null; + } + public boolean usesMembers() { + return myResult; + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if (classMember == null || classMember.equals(myMember)) return; + if (classMember.hasModifierProperty(PsiModifier.STATIC)) return; + + myResult = true; + } + + protected void visitExplicitThis(PsiClass referencedClass, PsiThisExpression reference) { + myResult = true; + } + + protected void visitExplicitSuper(PsiClass referencedClass, PsiSuperExpression reference) { + myResult = true; + } + + public void visitElement(PsiElement element) { + if (myResult) return; + super.visitElement(element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceContainmentVerifier.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceContainmentVerifier.java new file mode 100644 index 00000000000..90dc19cd59c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceContainmentVerifier.java @@ -0,0 +1,10 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.PsiMethod; + +/** + * @author dsl + */ +public interface InterfaceContainmentVerifier { + boolean checkedInterfacesContain(PsiMethod psiMethod); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java new file mode 100644 index 00000000000..026ef873534 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java @@ -0,0 +1,31 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:18:10 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +public class InterfaceDependencyMemberInfoModel extends DependencyMemberInfoModel { + + public InterfaceDependencyMemberInfoModel(PsiClass aClass) { + super(new InterfaceMemberDependencyGraph(aClass), WARNING); + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(MemberInfo memberInfo) { + return ((InterfaceMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); + } + }); + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return false; + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java new file mode 100644 index 00000000000..68d0cdf80f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java @@ -0,0 +1,125 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class InterfaceMemberDependencyGraph implements MemberDependencyGraph { + protected HashSet myInterfaceDependencies = null; + protected com.intellij.util.containers.HashMap myMembersToInterfacesMap = new com.intellij.util.containers.HashMap(); + protected HashSet myImplementedInterfaces; + protected com.intellij.util.containers.HashMap myMethodsFromInterfaces; + protected PsiClass myClass; + + public InterfaceMemberDependencyGraph(PsiClass aClass) { + myClass = aClass; + myImplementedInterfaces = new HashSet(); + myMethodsFromInterfaces = new com.intellij.util.containers.HashMap(); + } + + public void memberChanged(MemberInfo memberInfo) { + if (ClassMembersUtil.isImplementedInterface(memberInfo)) { + final PsiClass aClass = (PsiClass) memberInfo.getMember(); + myInterfaceDependencies = null; + myMembersToInterfacesMap = null; + if(memberInfo.isChecked()) { + myImplementedInterfaces.add(aClass); + } + else { + myImplementedInterfaces.remove(aClass); + } + } + } + + public Set getDependent() { + if(myInterfaceDependencies == null) { + myInterfaceDependencies = new HashSet(); + myMembersToInterfacesMap = new com.intellij.util.containers.HashMap(); + for (Iterator iterator = myImplementedInterfaces.iterator(); iterator.hasNext();) { + addInterfaceDeps((PsiClass) iterator.next()); + } + } + return myInterfaceDependencies; + } + + public Set getDependenciesOf(PsiElement element) { + final Set dependent = getDependent(); + if(dependent.contains(element)) return (Set) myMembersToInterfacesMap.get(element); + return null; + } + + public String getElementTooltip(PsiElement element) { + final Set dependencies = getDependenciesOf(element); + if(dependencies == null || dependencies.size() == 0) return null; + StringBuffer buffer = new StringBuffer("required by "); + if(dependencies.size() == 1) { + buffer.append("interface "); + } else { + buffer.append("intefaces "); + } + + for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) { + PsiClass aClass = (PsiClass) iterator.next(); + buffer.append(aClass.getName()); + if(iterator.hasNext()) { + buffer.append(", "); + } + } + return buffer.toString(); + } + + protected void addInterfaceDeps(PsiClass intf) { + HashSet interfaceMethods = (HashSet) myMethodsFromInterfaces.get(intf); + + if(interfaceMethods == null) { + interfaceMethods = new HashSet(); + buildInterfaceMethods(interfaceMethods, intf); + myMethodsFromInterfaces.put(intf, interfaceMethods); + } + for (Iterator iterator = interfaceMethods.iterator(); iterator.hasNext();) { + PsiMethod method = (PsiMethod) iterator.next(); + HashSet interfaces = (HashSet) myMembersToInterfacesMap.get(method); + if(interfaces == null) { + interfaces = new HashSet(); + myMembersToInterfacesMap.put(method, interfaces); + } + interfaces.add(intf); + } + myInterfaceDependencies.addAll(interfaceMethods); + } + + private void buildInterfaceMethods(HashSet interfaceMethods, PsiClass intf) { + PsiMethod[] methods = intf.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = myClass.findMethodBySignature(methods[i], true); + if(method != null) { + interfaceMethods.add(method); + } + } + + PsiReferenceList implementsList = intf.getImplementsList(); + if (implementsList != null) { + PsiClassType[] implemented = implementsList.getReferencedTypes(); + for (int i = 0; i < implemented.length; i++) { + PsiClass resolved = implemented[i].resolve(); + if(resolved != null) { + buildInterfaceMethods(interfaceMethods, resolved); + } + } + } + + PsiReferenceList extendsList = intf.getExtendsList(); + if (extendsList != null) { + PsiClassType[] extended = extendsList.getReferencedTypes(); + for (int i = 0; i < extended.length; i++) { + PsiClass ref = extended[i].resolve(); + if (ref != null) { + buildInterfaceMethods(interfaceMethods, ref); + } + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java new file mode 100644 index 00000000000..bb07e85666a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java @@ -0,0 +1,56 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.util.containers.HashMap; + +import java.util.HashSet; + + +class MemberDependenciesStorage { + protected final PsiClass myClass; + private final PsiClass mySuperClass; + private HashMap myDependencyGraph; + + MemberDependenciesStorage(PsiClass aClass, PsiClass superClass) { + myClass = aClass; + mySuperClass = superClass; + myDependencyGraph = new HashMap(); + } + + protected HashSet getMemberDependencies(PsiElement member) { + HashSet result = (HashSet) myDependencyGraph.get(member); + if (result == null) { + DependentMembersCollector collector = new DependentMembersCollector(); + member.accept(collector); + result = collector.getCollection(); + myDependencyGraph.put(member, result); + } + return result; + } + + class DependentMembersCollector extends ClassMemberReferencesVisitor { + private HashSet myCollection = new HashSet(); + + DependentMembersCollector() { + super(myClass); + } + + public HashSet getCollection() { + return myCollection; + } + + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if (!existsInSuperClass(classMember)) { + myCollection.add(classMember); + } + } + } + + private boolean existsInSuperClass(PsiElement classMember) { + if(mySuperClass == null) return false; + if (!(classMember instanceof PsiMethod)) return false; + final PsiMethod method = ((PsiMethod) classMember); + final PsiMethod methodBySignature = mySuperClass.findMethodBySignature(method, true); + return methodBySignature != null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java new file mode 100644 index 00000000000..ca06c62c6f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java @@ -0,0 +1,36 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 08.07.2002 + * Time: 17:53:29 + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +import java.util.Set; + +public interface MemberDependencyGraph { + /** + * Call this to notify that a new member info have been added + * or a state of some memberInfo have been changed. + * @param memberInfo + */ + void memberChanged(MemberInfo memberInfo); + + /** + * Returns class members that are dependent on checked MemberInfos. + * @return set of PsiElements + */ + Set getDependent(); + + /** + * Returns PsiElements of checked MemberInfos that element depends on. + * element should belong to getDependent() + * @param element + * @return set of PsiElements + */ + Set getDependenciesOf(PsiElement element); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfo.java new file mode 100644 index 00000000000..9c27fe67c00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfo.java @@ -0,0 +1,188 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 14.06.2002 + * Time: 20:31:59 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiSuperMethodUtil; + +import java.util.ArrayList; +import java.util.List; + +public class MemberInfo { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.MemberInfo"); + private PsiMember member; + final private boolean isStatic; + final private String displayName; + private boolean isChecked = false; + private boolean toAbstract = false; + /** + * TRUE if is overriden, FALSE if implemented, null if not implemented or overriden + */ + final private Boolean overrides; + + public boolean isStatic() { + return isStatic; + } + + public String getDisplayName() { + return displayName; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + public boolean isToAbstract() { + return toAbstract; + } + + public void setToAbstract(boolean toAbstract) { + this.toAbstract = toAbstract; + } + + /** + * Returns Boolean.TRUE if getMember() overrides something, Boolean.FALSE if getMember() + * implements something, null if neither is the case. + * If getMember() is a PsiClass, returns Boolean.TRUE if this class comes + * from 'extends', Boolean.FALSE if it comes from 'implements' list, null + * if it is an inner class. + */ + public Boolean getOverrides() { + return overrides; + } + + public MemberInfo(PsiMember member) { + this(member, false); + } + public MemberInfo(PsiMember member, boolean isSuperClass) { + LOG.assertTrue(member.isValid()); + this.member = member; + if (member instanceof PsiMethod) { + PsiMethod method = (PsiMethod) member; + displayName = PsiFormatUtil.formatMethod(method, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER + ); + PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method); + if (superMethods.length > 0) { + overrides = !superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT) ? Boolean.TRUE : Boolean.FALSE; + } + else { + overrides = null; + } + isStatic = method.hasModifierProperty(PsiModifier.STATIC); + } + else if (member instanceof PsiField) { + PsiField field = (PsiField) member; + displayName = PsiFormatUtil.formatVariable( + field, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, + PsiSubstitutor.EMPTY); + isStatic = field.hasModifierProperty(PsiModifier.STATIC); + overrides = null; + } + else if (member instanceof PsiClass) { + PsiClass aClass = (PsiClass) member; + + if(isSuperClass) { + if (aClass.isInterface()) { + displayName = "implements " + aClass.getName(); + overrides = Boolean.FALSE; + } + else { + displayName = "extends " + aClass.getName(); + overrides = Boolean.TRUE; + } + } + else { + displayName = aClass.getName(); + overrides = null; + } + isStatic = aClass.hasModifierProperty(PsiModifier.STATIC); + } + else { + LOG.assertTrue(false); + isStatic = false; + displayName = ""; + overrides = null; + } + } + + public PsiMember getMember() { + LOG.assertTrue(member.isValid()); + return member; + } + + /** + * Use this method solely to update element from smart pointer and the likes + * @param element + */ + public void updateMember(PsiMember element) { + member = element; + } + + + public static interface Filter { + boolean includeMember(PsiMember element); + } + + public static MemberInfo[] extractClassMembers(PsiClass subclass, Filter filter) { + List members = new ArrayList(); + extractClassMembers(subclass, members, filter); + return (MemberInfo[]) members.toArray(new MemberInfo[members.size()]); + } + + public static void extractClassMembers(PsiClass subclass, List result, Filter filter) { + if (!subclass.isInterface()) { + final PsiClass[] interfaces = subclass.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + PsiClass anInterface = interfaces[i]; + if (filter.includeMember(anInterface)) { + result.add(new MemberInfo(anInterface, true)); + } + } + } else { + final PsiClass[] superTypes = subclass.getSupers(); + for (int i = 0; i < superTypes.length; i++) { + PsiClass superType = superTypes[i]; + if (superType.isInterface()) { + if (filter.includeMember(superType)) { + result.add(new MemberInfo(superType, true)); + } + } + } + } + + PsiClass[] innerClasses = subclass.getInnerClasses(); + for (int idx = 0; idx < innerClasses.length; idx++) { + if(filter.includeMember(innerClasses[idx])) { + result.add(new MemberInfo(innerClasses[idx])); + } + } + PsiMethod[] methods = subclass.getMethods(); + for (int idx = 0; idx < methods.length; idx++) { + PsiMethod method = methods[idx]; + if (!(filter.includeMember(method))) continue; + result.add(new MemberInfo(method)); + } + PsiField[] fields = subclass.getFields(); + for (int idx = 0; idx < fields.length; idx++) { + final PsiField field = fields[idx]; + if (filter.includeMember(field)) { + result.add(new MemberInfo(field)); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChange.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChange.java new file mode 100644 index 00000000000..0a5089d3160 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChange.java @@ -0,0 +1,23 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:41:29 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.refactoring.util.classMembers.MemberInfo; + +public class MemberInfoChange { + private final MemberInfo[] myChangedMembers; + + public MemberInfoChange(MemberInfo[] changedMembers) { + myChangedMembers = changedMembers; + } + + public MemberInfo[] getChangedMembers() { + return myChangedMembers; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java new file mode 100644 index 00000000000..ea15f17d424 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java @@ -0,0 +1,15 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:41:09 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import java.util.EventListener; + +public interface MemberInfoChangeListener extends EventListener { + void memberInfoChanged(MemberInfoChange event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoModel.java new file mode 100644 index 00000000000..222ed4e3b90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoModel.java @@ -0,0 +1,36 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 14:58:46 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + + + +public interface MemberInfoModel extends MemberInfoChangeListener { + int OK = 0; + int WARNING = 1; + int ERROR = 2; + + boolean isMemberEnabled(MemberInfo member); + + boolean isCheckedWhenDisabled(MemberInfo member); + + boolean isAbstractEnabled(MemberInfo member); + + boolean isAbstractWhenDisabled(MemberInfo member); + + /** + * Returns state of abstract checkbox for particular abstract member. + * @param member MemberInfo for an ABSTRACT member + * @return TRUE if fixed and true, FALSE if fixed and false, null if dont care + */ + Boolean isFixedAbstract(MemberInfo member); + + int checkForProblems(MemberInfo member); + + String getTooltipText(MemberInfo member); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java new file mode 100644 index 00000000000..0dc3992dfeb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java @@ -0,0 +1,164 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.containers.HashMap; + +import java.util.*; + + +public class MemberInfoStorage { + private PsiClass myClass; + private HashMap> myClassToMemberInfoMap = new HashMap>(); + private HashMap> myClassToSubclassesMap = new HashMap>(); + private HashMap> myTargetClassToExtendingMap = new HashMap>(); + private HashMap myTargetClassToMemberInfosMap = new HashMap(); + private HashMap> myTargetClassToMemberInfosListMap = new HashMap>(); + private HashMap> myTargetClassToDuplicatedMemberInfosMap = new HashMap>(); + private final MemberInfo.Filter myFilter; + + public MemberInfoStorage(PsiClass aClass, MemberInfo.Filter memberInfoFilter) { + myClass = aClass; + buildSubClassesMap(aClass); + myFilter = memberInfoFilter; + } + + private Set getAllClasses() { + return myClassToSubclassesMap.keySet(); + } + + public Set getExtending(PsiClass baseClass) { + Set result = myTargetClassToExtendingMap.get(baseClass); + if(result == null) { + result = new HashSet(); + result.add(baseClass); + final Set allClasses = getAllClasses(); + for (Iterator iterator = allClasses.iterator(); iterator.hasNext();) { + PsiClass aClass = iterator.next(); + if(aClass.isInheritor(baseClass, true)) { + result.add(aClass); + } + } + myTargetClassToExtendingMap.put(baseClass, result); + } + + return result; + } + + public List getClassMemberInfos(PsiClass aClass) { + List result = myClassToMemberInfoMap.get(aClass); + if(result == null) { + ArrayList temp = new ArrayList(); + MemberInfo.extractClassMembers(aClass, temp, myFilter); + result = Collections.unmodifiableList(temp); + myClassToMemberInfoMap.put(aClass, result); + } + return result; + } + + public MemberInfo[] getMemberInfosList(PsiClass baseClass) { + MemberInfo[] result = myTargetClassToMemberInfosMap.get(baseClass); + + if (result == null) { + LinkedHashSet list = getIntermediateClassesMemberInfosList(baseClass); + result = list.toArray(new MemberInfo[list.size()]); + myTargetClassToMemberInfosMap.put(baseClass, result); + } + + return result; + } + + public Set getDuplicatedMemberInfos(PsiClass baseClass) { + HashSet result = myTargetClassToDuplicatedMemberInfosMap.get(baseClass); + + if(result == null) { + result = buildDuplicatedMemberInfos(baseClass); + myTargetClassToDuplicatedMemberInfosMap.put(baseClass, result); + } + return result; + } + + private HashSet buildDuplicatedMemberInfos(PsiClass baseClass) { + HashSet result = new HashSet(); + MemberInfo[] memberInfos = getMemberInfosList(baseClass); + + for (int i = 0; i < memberInfos.length; i++) { + final MemberInfo memberInfo = memberInfos[i]; + final PsiElement member = memberInfo.getMember(); + + for(int j = 0; j < i; j++) { + final MemberInfo memberInfo1 = memberInfos[j]; + final PsiElement member1 = memberInfo1.getMember(); + if(memberConflict(member1, member)) { + result.add(memberInfo); +// We let the first one be... +// result.add(memberInfo1); + } + } + } + return result; + } + + private boolean memberConflict(PsiElement member1, PsiElement member) { + if(member instanceof PsiMethod && member1 instanceof PsiMethod) { + return MethodSignatureUtil.areSignaturesEqual((PsiMethod) member, (PsiMethod) member1); + } + else if(member instanceof PsiField && member1 instanceof PsiField + || member instanceof PsiClass && member1 instanceof PsiClass) { + return ((PsiNamedElement) member).getName().equals(((PsiNamedElement) member1).getName()); + } + return false; + } + + + private LinkedHashSet getIntermediateClassesMemberInfosList(PsiClass targetClass) { + LinkedHashSet result = myTargetClassToMemberInfosListMap.get(targetClass); + if(result == null) { + result = new LinkedHashSet(); + LinkedHashSet subclasses = getSubclasses(targetClass); + for (Iterator iterator = subclasses.iterator(); iterator.hasNext();) { + PsiClass subclass = iterator.next(); + List memberInfos = getClassMemberInfos(subclass); + result.addAll(memberInfos); + } + for (Iterator iterator = subclasses.iterator(); iterator.hasNext();) { + PsiClass subclass = iterator.next(); + result.addAll(getIntermediateClassesMemberInfosList(subclass)); + } + myTargetClassToMemberInfosListMap.put(targetClass, result); + } + return result; + } + + private LinkedHashSet getSubclasses(PsiClass aClass) { + LinkedHashSet result = myClassToSubclassesMap.get(aClass); + if(result == null) { + result = new LinkedHashSet(); + myClassToSubclassesMap.put(aClass, result); + } + return result; + } + + private void buildSubClassesMap(PsiClass aClass) { + final PsiReferenceList extendsList = aClass.getExtendsList(); + if (extendsList != null) { + buildSubClassesMapForList(extendsList.getReferencedTypes(), aClass); + } + final PsiReferenceList implementsList = aClass.getImplementsList(); + if (implementsList != null) { + buildSubClassesMapForList(implementsList.getReferencedTypes(), aClass); + } + } + + private void buildSubClassesMapForList(final PsiClassType[] classesList, PsiClass aClass) { + for (int i = 0; i < classesList.length; i++) { + PsiClassType element = classesList[i]; + PsiClass resolved = element.resolve(); + if(resolved != null) { + PsiClass superClass = resolved; + getSubclasses(superClass).add(aClass); + buildSubClassesMap(superClass); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java new file mode 100644 index 00000000000..6adffe85430 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java @@ -0,0 +1,41 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.util.containers.HashMap; + +/** + * @author dsl + */ +public class MemberInfoTooltipManager { + private final HashMap myTooltips; + private final TooltipProvider myProvider; + + public interface TooltipProvider { + String getTooltip(MemberInfo memberInfo); + } + + public static class DefaultTooltipProvider implements TooltipProvider { + public static final DefaultTooltipProvider INSTANCE = new DefaultTooltipProvider(); + private DefaultTooltipProvider() {} + public String getTooltip(MemberInfo memberInfo) { + return null; + } + } + + public MemberInfoTooltipManager(TooltipProvider provider) { + myProvider = provider; + myTooltips = new HashMap(); + } + + public void invalidate() { + myTooltips.clear(); + } + + public String getTooltip(MemberInfo member) { + if(myTooltips.keySet().contains(member)) { + return (String) myTooltips.get(member); + } + String tooltip = myProvider.getTooltip(member); + myTooltips.put(member, tooltip); + return tooltip; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java new file mode 100644 index 00000000000..c837448a8fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java @@ -0,0 +1,26 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class UsedByDependencyMemberInfoModel extends DependencyMemberInfoModel { + + public UsedByDependencyMemberInfoModel(PsiClass aClass) { + super(new UsedByMemberDependencyGraph(aClass), ERROR); + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(MemberInfo memberInfo) { + return ((UsedByMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); + } + }); + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return false; + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java new file mode 100644 index 00000000000..82a2d0b79a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java @@ -0,0 +1,110 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class UsedByMemberDependencyGraph implements MemberDependencyGraph { + protected HashSet mySelectedNormal; + protected HashSet mySelectedAbstract; + protected HashSet myMembers; + protected HashSet myDependencies = null; + protected com.intellij.util.containers.HashMap myDependenciesToDependent = null; + private final MemberDependenciesStorage myMemberDependenciesStorage; + + UsedByMemberDependencyGraph(PsiClass aClass) { + myMemberDependenciesStorage = new MemberDependenciesStorage(aClass, null); + mySelectedNormal = new HashSet(); + mySelectedAbstract = new HashSet(); + myMembers = new HashSet(); + } + + public void memberChanged(MemberInfo memberInfo) { + if(ClassMembersUtil.isProperMember(memberInfo)) + { + myDependencies = null; + myDependenciesToDependent = null; + PsiElement member = memberInfo.getMember(); + myMembers.add(member); + if (!memberInfo.isChecked()) { + mySelectedNormal.remove(member); + mySelectedAbstract.remove(member); + } + else { + if (memberInfo.isToAbstract()) { + mySelectedNormal.remove(member); + mySelectedAbstract.add(member); + } + else { + mySelectedNormal.add(member); + mySelectedAbstract.remove(member); + } + } + } + } + + public Set getDependent() { + if(myDependencies == null) { + myDependencies = new HashSet(); + myDependenciesToDependent = new com.intellij.util.containers.HashMap(); + for (Iterator iterator = myMembers.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement) iterator.next(); + Set dependent = myMemberDependenciesStorage.getMemberDependencies(element); + for (Iterator iterator1 = dependent.iterator(); iterator1.hasNext();) { + PsiElement dependentOn = (PsiElement) iterator1.next(); + if(mySelectedNormal.contains(dependentOn) && !mySelectedAbstract.contains(dependentOn)) { + myDependencies.add(element); + HashSet deps = (HashSet) myDependenciesToDependent.get(element); + if(deps == null) { + deps = new HashSet(); + myDependenciesToDependent.put(element, deps); + } + deps.add(dependentOn); + } + } + } + } + + return myDependencies; + } + + public Set getDependenciesOf(PsiElement element) { + final Set dependent = getDependent(); + if(!dependent.contains(element)) return null; + return (Set) myDependenciesToDependent.get(element); + } + + public String getElementTooltip(PsiElement element) { + final Set dependencies = getDependenciesOf(element); + if (dependencies == null || dependencies.size() == 0) return null; + + ArrayList strings = new ArrayList(); + for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) { + PsiElement dep = (PsiElement) iterator.next(); + if (dep instanceof PsiNamedElement) { + final String name = ((PsiNamedElement) dep).getName(); + if (name != null) { + strings.add(name); + } + } + } + + if (strings.isEmpty()) return null; + StringBuffer buffer = new StringBuffer("uses "); + final int size = strings.size(); + for (int i = 0; i < size; i++) { + String s = (String) strings.get(i); + buffer.append(s); + if (i < size - 1) { + buffer.append(", "); + } + } + return buffer.toString(); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java new file mode 100644 index 00000000000..9c1d6f0cc9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java @@ -0,0 +1,44 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 25.06.2002 + * Time: 14:01:08 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; + +public class UsesAndInterfacesDependencyMemberInfoModel extends DelegatingMemberInfoModel { + public static final InterfaceContainmentVerifier DEFAULT_CONTAINMENT_VERIFIER = new InterfaceContainmentVerifier() { + public boolean checkedInterfacesContain(PsiMethod psiMethod) { + return false; + } + }; + + public UsesAndInterfacesDependencyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive, + final InterfaceContainmentVerifier interfaceContainmentVerifier) { + super(new ANDCombinedMemberInfoModel( + new UsesDependencyMemberInfoModel(aClass, superClass, recursive) { + public int checkForProblems(MemberInfo memberInfo) { + final int problem = super.checkForProblems(memberInfo); + if (problem == OK) return OK; + if (memberInfo.getMember() instanceof PsiMethod) { + if (interfaceContainmentVerifier.checkedInterfacesContain((PsiMethod) memberInfo.getMember())) return OK; + } + return problem; + } + }, + new InterfaceDependencyMemberInfoModel(aClass)) + ); + } + + + public void setSuperClass(PsiClass superClass) { + ((UsesDependencyMemberInfoModel) ((ANDCombinedMemberInfoModel) getDelegatingTarget()).getModel1()).setSuperClass(superClass); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java new file mode 100644 index 00000000000..778c7a3be1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java @@ -0,0 +1,48 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 08.07.2002 + * Time: 17:55:02 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; + +public class UsesDependencyMemberInfoModel extends DependencyMemberInfoModel { + private PsiClass myClass; + + public UsesDependencyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) { + super(new UsesMemberDependencyGraph(aClass, superClass, recursive), ERROR); + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(MemberInfo memberInfo) { + return ((UsesMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); + } + }); + myClass = aClass; + } + + public int checkForProblems(MemberInfo memberInfo) { + final int problem = super.checkForProblems(memberInfo); + final PsiElement member = memberInfo.getMember(); + if(problem == ERROR + && member instanceof PsiModifierListOwner + && ((PsiModifierListOwner) member).hasModifierProperty(PsiModifier.STATIC)) { + return WARNING; + } + return problem; + } + + public void setSuperClass(PsiClass superClass) { + setMemberDependencyGraph(new UsesMemberDependencyGraph(myClass, superClass, false)); + } + + public boolean isCheckedWhenDisabled(MemberInfo member) { + return false; + } + + public Boolean isFixedAbstract(MemberInfo member) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java new file mode 100644 index 00000000000..6d46588e355 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java @@ -0,0 +1,129 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 08.07.2002 + * Time: 18:22:48 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class UsesMemberDependencyGraph implements MemberDependencyGraph { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.classMembers.UsesMemberDependencyGraph"); + protected HashSet mySelectedNormal; + protected HashSet mySelectedAbstract; + protected HashSet myDependencies = null; + protected com.intellij.util.containers.HashMap myDependenciesToDependentMap = null; + private final PsiClass mySuperClass; + private final boolean myRecursive; + private MemberDependenciesStorage myMemberDependenciesStorage; + private PsiClass myClass; + + public UsesMemberDependencyGraph(PsiClass aClass, PsiClass superClass, boolean recursive) { + mySuperClass = superClass; + myRecursive = recursive; + mySelectedNormal = new HashSet(); + mySelectedAbstract = new HashSet(); + myClass = aClass; + myMemberDependenciesStorage = new MemberDependenciesStorage(myClass, superClass); + } + + + public Set getDependent() { + if (myDependencies == null) { + myDependencies = new HashSet(); + myDependenciesToDependentMap = new com.intellij.util.containers.HashMap(); + buildDeps(null, mySelectedNormal, myDependencies, myDependenciesToDependentMap, true); + } + return myDependencies; + } + + public Set getDependenciesOf(PsiElement element) { + final Set dependent = getDependent(); + if(!dependent.contains(element)) return null; + return (Set) myDependenciesToDependentMap.get(element); + } + + public String getElementTooltip(PsiElement element) { + final Set dependencies = getDependenciesOf(element); + if(dependencies == null || dependencies.size() == 0) return null; + + ArrayList strings = new ArrayList(); + for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) { + PsiElement dep = (PsiElement) iterator.next(); + if(dep instanceof PsiNamedElement) { + final String name = ((PsiNamedElement) dep).getName(); + if(name != null) { + strings.add(name); + } + } + } + + if(strings.isEmpty()) return null; + StringBuffer buffer = new StringBuffer("used by "); + final int size = strings.size(); + for (int i = 0; i < size; i++) { + String s = (String) strings.get(i); + buffer.append(s); + if(i < size - 1) { + buffer.append(", "); + } + } + return buffer.toString(); + } + + + protected void buildDeps(PsiElement sourceElement, Set elements, Set result, com.intellij.util.containers.HashMap relationMap, boolean recurse) { + for (Iterator iterator = elements.iterator(); iterator.hasNext();) { + PsiElement element = (PsiElement) iterator.next(); + + if (!result.contains(element)) { + if (LOG.isDebugEnabled()) { + LOG.debug(element.toString()); + } + result.add(element); + if (sourceElement != null) { + HashSet relations = (HashSet) relationMap.get(element); + if(relations == null) { + relations = new HashSet(); + relationMap.put(element, relations); + } + relations.add(sourceElement); + } + if (recurse && !mySelectedAbstract.contains(element)) { + buildDeps(element, myMemberDependenciesStorage.getMemberDependencies(element), result, relationMap, myRecursive); + } + } + } + } + + public void memberChanged(MemberInfo memberInfo) { + if (ClassMembersUtil.isProperMember(memberInfo)) { + myDependencies = null; + myDependenciesToDependentMap = null; + PsiElement member = memberInfo.getMember(); + if (!memberInfo.isChecked()) { + mySelectedNormal.remove(member); + mySelectedAbstract.remove(member); + } else { + if (memberInfo.isToAbstract()) { + mySelectedNormal.remove(member); + mySelectedAbstract.add(member); + } else { + mySelectedNormal.add(member); + mySelectedAbstract.remove(member); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassInstanceScanner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassInstanceScanner.java new file mode 100644 index 00000000000..0deff3ab06d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassInstanceScanner.java @@ -0,0 +1,181 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.RefactoringUtil; + +/** + * @author dsl + */ +public class ClassInstanceScanner extends DelegatingClassReferenceVisitor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.classRefs.ClassInstanceScanner"); + private PsiClass myClass; + private ClassInstanceReferenceVisitor myVisitor; + private PsiSearchHelper mySearchHelper; + + public interface ClassInstanceReferenceVisitor { + void visitQualifier(PsiReferenceExpression qualified, PsiExpression instanceRef, PsiElement referencedInstance); + void visitTypeCast(PsiTypeCastExpression typeCastExpression, PsiExpression instanceRef, PsiElement referencedInstance); + void visitReadUsage(PsiExpression instanceRef, PsiType expectedType, PsiElement referencedInstance); + void visitWriteUsage(PsiExpression instanceRef, PsiType assignedType, PsiElement referencedInstance); + } + + public ClassInstanceScanner(PsiClass aClass, ClassInstanceReferenceVisitor visitor) { + this(aClass, ClassReferenceVisitorAdapter.INSTANCE, visitor); + } + + public ClassInstanceScanner(PsiClass aClass, ClassReferenceVisitor delegate, + ClassInstanceReferenceVisitor visitor) { + super(delegate); + myClass = aClass; + mySearchHelper = myClass.getManager().getSearchHelper(); + myVisitor = visitor; + } + + public void visitLocalVariableDeclaration(PsiLocalVariable variable, ClassReferenceVisitor.TypeOccurence occurence) { + visitVariable(variable, occurence); + } + + public void visitFieldDeclaration(PsiField field, ClassReferenceVisitor.TypeOccurence occurence) { + visitVariable(field, occurence); + } + + public void visitParameterDeclaration(PsiParameter parameter, ClassReferenceVisitor.TypeOccurence occurence) { + visitVariable(parameter, occurence); + } + + private void visitVariable(PsiVariable variable, ClassReferenceVisitor.TypeOccurence occurence) { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myClass.getProject()); + PsiReference[] references = mySearchHelper.findReferences(variable, projectScope, false); + for (int i = 0; i < references.length; i++) { + PsiElement element = references[i].getElement(); + + // todo: handle arrays + if (element instanceof PsiExpression) { + processExpression((PsiExpression) element, occurence, variable); + } else { + // todo: java doc processing? +// LOG.assertTrue(false); + } + } + } + + public void visitMethodReturnType(PsiMethod method, ClassReferenceVisitor.TypeOccurence occurence) { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myClass.getProject()); + PsiReference[] refs = mySearchHelper.findReferences(method, projectScope, false); + + for (int i = 0; i < refs.length; i++) { + PsiElement element = refs[i].getElement(); + if(element instanceof PsiReferenceExpression) { + PsiElement parent = element.getParent(); + if(parent instanceof PsiMethodCallExpression) { + processExpression((PsiMethodCallExpression) parent, occurence, method); + } + } + } + } + + public void visitTypeCastExpression(PsiTypeCastExpression typeCastExpression, ClassReferenceVisitor.TypeOccurence occurence) { + processExpression(typeCastExpression, occurence, null); + } + + public void visitNewExpression(PsiNewExpression newExpression, ClassReferenceVisitor.TypeOccurence occurence) { + processExpression(newExpression, occurence, null); + } + + private void processExpression(PsiExpression expression, ClassReferenceVisitor.TypeOccurence occurence, PsiElement referencedElement) { + if(occurence.outermostType == null || !(occurence.outermostType instanceof PsiArrayType)) { + processNonArrayExpression(myVisitor, expression, referencedElement); + } + else { + PsiType type = occurence.outermostType; + PsiExpression result = RefactoringUtil.outermostParenthesizedExpression(expression); + while(type != null && type instanceof PsiArrayType && result.getParent() instanceof PsiArrayAccessExpression) { + type = ((PsiArrayType) type).getComponentType(); + result = RefactoringUtil.outermostParenthesizedExpression((PsiArrayAccessExpression) result.getParent()); + } + if(type == null || !(type instanceof PsiArrayType)) { + processNonArrayExpression(myVisitor, result, referencedElement); + } + } + } + + public static void processNonArrayExpression(ClassInstanceReferenceVisitor visitor, PsiExpression expression, PsiElement referencedElement) { + expression = RefactoringUtil.outermostParenthesizedExpression(expression); + PsiElement parent = expression.getParent(); + if(parent instanceof PsiReferenceExpression && expression == ((PsiReferenceExpression) parent).getQualifierExpression()) { + visitor.visitQualifier((PsiReferenceExpression) parent, expression, referencedElement); + } + else if(parent instanceof PsiTypeCastExpression) { + visitor.visitTypeCast((PsiTypeCastExpression) parent, expression, referencedElement); + } + else if(parent instanceof PsiReturnStatement) { + final PsiReturnStatement returnStatement = (PsiReturnStatement) parent; + PsiMethod enclosingMethod = PsiTreeUtil.getParentOfType(returnStatement, PsiMethod.class); + final PsiType returnType; + if(enclosingMethod != null) { + returnType = enclosingMethod.getReturnType(); + } + else { + returnType = null; + } + visitor.visitReadUsage(expression, returnType, referencedElement); + } + else if(parent instanceof PsiStatement) { + visitor.visitReadUsage(expression, null, referencedElement); + } + else if(parent instanceof PsiExpressionList) { + PsiExpressionList expressionList = (PsiExpressionList) parent; + PsiElement pparent = expressionList.getParent(); + if(pparent instanceof PsiStatement) { + visitor.visitReadUsage(expression, null, referencedElement); + } + else if(pparent instanceof PsiCallExpression) { + PsiCallExpression callExpression = (PsiCallExpression) pparent; + PsiExpression[] arguments = callExpression.getArgumentList().getExpressions(); + PsiMethod method = callExpression.resolveMethod(); + if(method != null) { + int index = -1; + for (int i = 0; i < arguments.length; i++) { + PsiExpression argument = arguments[i]; + if(argument.equals(expression)) { + index = i; break; + } + } + if(index >= 0) { + PsiParameter[] parameters = method.getParameterList().getParameters(); + if(parameters.length > index) { + visitor.visitReadUsage(expression, parameters[index].getType(), referencedElement); + } + } + } + } + } + else if(parent instanceof PsiAssignmentExpression) { + PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent; + if(expression.equals(assignmentExpression.getRExpression())) { + visitor.visitReadUsage(expression, assignmentExpression.getLExpression().getType(), referencedElement); + } + else { // LExpression + visitor.visitWriteUsage(expression, assignmentExpression.getRExpression().getType(), referencedElement); + } + } + else if(RefactoringUtil.isAssignmentLHS(expression)) { + visitor.visitWriteUsage(expression, null, referencedElement); + } + else if(parent instanceof PsiVariable) { + visitor.visitReadUsage(expression, ((PsiVariable) parent).getType(), referencedElement); + } + else if(parent instanceof PsiExpression) { + // for usages in expressions other than above, we do not care about the type + visitor.visitReadUsage(expression, null, referencedElement); + } + else { + LOG.assertTrue(false, "Unknown variation of class instance usage"); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceScanner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceScanner.java new file mode 100644 index 00000000000..62794073ff8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceScanner.java @@ -0,0 +1,71 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public abstract class ClassReferenceScanner { + protected PsiClass myClass; + private PsiReference[] myReferences = null; + + public abstract PsiReference[] findReferences(); + + public ClassReferenceScanner(PsiClass aClass) { + myClass = aClass; + } + + public void processReferences(ClassReferenceVisitor visitor) { + if(myReferences == null) { + myReferences = findReferences(); + } + + for (int i = 0; i < myReferences.length; i++) { + processUsage(myReferences[i].getElement(), visitor); + } + } + + private void processUsage(PsiElement ref, ClassReferenceVisitor visitor) { + if (ref instanceof PsiReferenceExpression){ + visitor.visitReferenceExpression((PsiReferenceExpression) ref); + return; + } + + PsiElement parent = ref.getParent(); + if (parent instanceof PsiTypeElement){ + PsiElement pparent = parent.getParent(); + while(pparent instanceof PsiTypeElement){ + parent = pparent; + pparent = parent.getParent(); + } + ClassReferenceVisitor.TypeOccurence occurence = + new ClassReferenceVisitor.TypeOccurence(ref, ((PsiTypeElement) parent).getType()); + + + if (pparent instanceof PsiLocalVariable){ + visitor.visitLocalVariableDeclaration((PsiLocalVariable) pparent, occurence); + } + else if(pparent instanceof PsiParameter) { + PsiParameter parameter = (PsiParameter) pparent; + visitor.visitParameterDeclaration(parameter, occurence); + } + else if(pparent instanceof PsiField) { + visitor.visitFieldDeclaration((PsiField) pparent, occurence); + } + else if (pparent instanceof PsiMethod){ + visitor.visitMethodReturnType((PsiMethod) pparent, occurence); + } + else if (pparent instanceof PsiTypeCastExpression){ + visitor.visitTypeCastExpression((PsiTypeCastExpression) pparent, occurence); + } + } + else if (parent instanceof PsiNewExpression){ + visitor.visitNewExpression((PsiNewExpression) parent, + new ClassReferenceVisitor.TypeOccurence(ref, ((PsiNewExpression) parent).getType()) + ); + } + else{ + visitor.visitOther(ref); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceSearchingScanner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceSearchingScanner.java new file mode 100644 index 00000000000..4781bd5a9f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceSearchingScanner.java @@ -0,0 +1,26 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchHelper; + +/** + * @author dsl + */ +public class ClassReferenceSearchingScanner extends ClassReferenceScanner { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.classRefs.ClassReferenceSearchingScanner"); + private PsiSearchHelper mySearchHelper; + + public ClassReferenceSearchingScanner(PsiClass aClass) { + super(aClass); + mySearchHelper = myClass.getManager().getSearchHelper(); + } + + public PsiReference[] findReferences() { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myClass.getProject()); + return mySearchHelper.findReferences(myClass, projectScope, false); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitor.java new file mode 100644 index 00000000000..53ff4c93e88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitor.java @@ -0,0 +1,28 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.psi.*; + +public interface ClassReferenceVisitor { + static class TypeOccurence { + + public TypeOccurence(PsiElement element, PsiType outermostType) { + this.element = element; + this.outermostType = outermostType; + } + + public final PsiElement element; + public final PsiType outermostType; + } + + void visitReferenceExpression(PsiReferenceExpression referenceExpression); + + void visitLocalVariableDeclaration(PsiLocalVariable variable, TypeOccurence occurence); + void visitFieldDeclaration(PsiField field, TypeOccurence occurence); + void visitParameterDeclaration(PsiParameter parameter, TypeOccurence occurence); + void visitMethodReturnType(PsiMethod method, TypeOccurence occurence); + void visitTypeCastExpression(PsiTypeCastExpression typeCastExpression, TypeOccurence occurence); + + void visitNewExpression(PsiNewExpression newExpression, TypeOccurence occurence); + + void visitOther(PsiElement ref); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitorAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitorAdapter.java new file mode 100644 index 00000000000..0ee52bd75d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/ClassReferenceVisitorAdapter.java @@ -0,0 +1,36 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.psi.*; + +/** + * ClassReferenceVisitor that does nothing. + * @author dsl + */ +public class ClassReferenceVisitorAdapter implements ClassReferenceVisitor { + public static final ClassReferenceVisitorAdapter INSTANCE = new ClassReferenceVisitorAdapter(); + + public void visitReferenceExpression(PsiReferenceExpression referenceExpression) { + } + + public void visitLocalVariableDeclaration(PsiLocalVariable variable, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitFieldDeclaration(PsiField field, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitParameterDeclaration(PsiParameter parameter, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitMethodReturnType(PsiMethod method, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitTypeCastExpression(PsiTypeCastExpression typeCastExpression, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitNewExpression(PsiNewExpression newExpression, ClassReferenceVisitor.TypeOccurence occurence) { + } + + public void visitOther(PsiElement ref) { + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/DelegatingClassReferenceVisitor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/DelegatingClassReferenceVisitor.java new file mode 100644 index 00000000000..adf87131e25 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/classRefs/DelegatingClassReferenceVisitor.java @@ -0,0 +1,48 @@ +package com.intellij.refactoring.util.classRefs; + +import com.intellij.psi.*; + +/** + * @author dsl + */ +public class DelegatingClassReferenceVisitor implements ClassReferenceVisitor { + private final ClassReferenceVisitor myDelegate; + + public DelegatingClassReferenceVisitor(ClassReferenceVisitor delegate) { + + myDelegate = delegate; + } + + public void visitReferenceExpression(PsiReferenceExpression referenceExpression) { + myDelegate.visitReferenceExpression(referenceExpression); + } + + public void visitLocalVariableDeclaration(PsiLocalVariable variable, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitLocalVariableDeclaration(variable, occurence); + } + + public void visitFieldDeclaration(PsiField field, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitFieldDeclaration(field, occurence); + } + + public void visitParameterDeclaration(PsiParameter parameter, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitParameterDeclaration(parameter, occurence); + } + + public void visitMethodReturnType(PsiMethod method, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitMethodReturnType(method, occurence); + } + + public void visitTypeCastExpression(PsiTypeCastExpression typeCastExpression, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitTypeCastExpression(typeCastExpression, occurence); + } + + public void visitNewExpression(PsiNewExpression newExpression, ClassReferenceVisitor.TypeOccurence occurence) { + myDelegate.visitNewExpression(newExpression, occurence); + } + + public void visitOther(PsiElement ref) { + myDelegate.visitOther(ref); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java new file mode 100644 index 00000000000..ef55c805664 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java @@ -0,0 +1,273 @@ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author dsl + */ +public class DuplicatesFinder { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.DuplicatesFinder"); + private static final Key PARAMETER = Key.create("PARAMETER"); + private final PsiElement[] myPattern; + private final boolean mySkipStaticContext; + private final List myParameters; + private final List myOutputParameters; + private final List myPatternAsList; + + public DuplicatesFinder(PsiElement[] pattern, + List parameters, + List outputParameters, + boolean maintainStaticContext) { + LOG.assertTrue(pattern.length > 0); + myPattern = pattern; + myPatternAsList = Arrays.asList(myPattern); + myParameters = parameters; + myOutputParameters = outputParameters; + mySkipStaticContext = maintainStaticContext && !RefactoringUtil.isInStaticContext(myPattern[0]); + } + + + public List findDuplicates(PsiElement scope) { + annotatePattern(); + final ArrayList result = new ArrayList(); + findPatternOccurrences(result, scope); + deannotatePattern(); + return result; + } + + private void annotatePattern() { + for (int i = 0; i < myPattern.length; i++) { + final PsiElement patternComponent = myPattern[i]; + patternComponent.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + final PsiElement element = reference.resolve(); + if (myParameters.contains(element)) { + reference.putUserData(PARAMETER, (PsiVariable) element); + } + if (myOutputParameters.contains(element)) { + reference.putUserData(PARAMETER, (PsiVariable) element); + } + PsiElement qualifier = reference.getQualifier(); + if (qualifier != null) { + qualifier.accept(this); + } + } + }); + } + } + + private void deannotatePattern() { + for (int i = 0; i < myPattern.length; i++) { + final PsiElement patternComponent = myPattern[i]; + patternComponent.accept(new PsiRecursiveElementVisitor() { + public void visitReferenceExpression(PsiReferenceExpression expression) { + visitReferenceElement(expression); + } + + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + if (reference.getUserData(PARAMETER) != null) { + reference.putUserData(PARAMETER, null); + } + } + }); + } + } + + + private void findPatternOccurrences(List array, PsiElement scope) { + if (mySkipStaticContext && RefactoringUtil.isInStaticContext(scope)) return; + PsiElement[] children = scope.getChildren(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + final Match match = isDuplicateFragment(child); + if (match != null) { + array.add(match); + continue; + } + findPatternOccurrences(array, child); + } + } + + + public Match isDuplicateFragment(PsiElement candidate) { + if (candidate == myPattern[0]) return null; + PsiElement sibling = candidate; + ArrayList candidates = new ArrayList(); + for (int i = 0; i < myPattern.length; i++) { + final PsiElement element = myPattern[i]; + if (sibling == null) return null; + if (!canBeEquivalent(element, sibling)) return null; + candidates.add(sibling); + sibling = sibling.getNextSibling(); + while(sibling instanceof PsiWhiteSpace) { + sibling = sibling.getNextSibling(); + } + } + LOG.assertTrue(myPattern.length == candidates.size()); + if (myPattern.length == 1 && myPattern[0] instanceof PsiExpression) { + if (candidates.get(0) instanceof PsiExpression) { + final PsiType patternType = ((PsiExpression)myPattern[0]).getType(); + final PsiType candidateType = ((PsiExpression)candidates.get(0)).getType(); + if (patternType != null && candidateType != null && !candidateType.isAssignableFrom(patternType)) { + return null; + } + } + else { + return null; + } + + } + final Match match = new Match(candidates.get(0), candidates.get(candidates.size() - 1)); + for (int i = 0; i < myPattern.length; i++) { + if (!matchPattern(myPattern[i], candidates.get(i), candidates, match)) return null; + } + + return match; + } + + private boolean canBeEquivalent(final PsiElement pattern, PsiElement candidate) { + if (pattern instanceof PsiReturnStatement && candidate instanceof PsiExpressionStatement) return true; + if (pattern instanceof PsiReturnStatement && candidate instanceof PsiDeclarationStatement) return true; + return pattern.getClass().equals(candidate.getClass()); + } + + private boolean matchPattern(PsiElement pattern, + PsiElement candidate, + List candidates, + Match match) { + if ((pattern == null || candidate == null)) return pattern == candidate; + if (pattern.getUserData(PARAMETER) != null) { + final PsiVariable parameter = pattern.getUserData(PARAMETER); + return match.putParameter(parameter, candidate); + } + + if (!canBeEquivalent(pattern, candidate)) return false; // Q : is it correct to check implementation classes? + + PsiReference ref1 = pattern.getReference(); + if (ref1 != null) { + PsiReference ref2 = candidate.getReference(); + if (ref2 == null) return false; + final PsiElement resolveResult1 = ref1.resolve(); + final PsiElement resolveResult2 = ref2.resolve(); + if (isUnder(resolveResult1, myPatternAsList) && isUnder(resolveResult2, candidates)) { + return match.putDeclarationCorrespondence(resolveResult1, resolveResult2); + } + if (!equivalentResolve(resolveResult1, resolveResult2)) { + return false; + } + } + + if (pattern instanceof PsiReturnStatement) { + final PsiReturnStatement patternReturnStatement = ((PsiReturnStatement)pattern); + return matchReturnStatement(patternReturnStatement, candidate, candidates, match); + } + + if (pattern instanceof PsiReferenceExpression && candidate instanceof PsiReferenceExpression) { + final PsiReferenceExpression patternRefExpr = ((PsiReferenceExpression)pattern); + final PsiReferenceExpression candidateRefExpr = ((PsiReferenceExpression)candidate); + if (patternRefExpr.getQualifierExpression() == null) { + return match.registerInstanceExpression(candidateRefExpr.getQualifierExpression()); + } + } + + PsiElement[] children1 = getFilteredChildren(pattern); + PsiElement[] children2 = getFilteredChildren(candidate); + if (children1.length != children2.length) return false; + + + for (int i = 0; i < children1.length; i++) { + PsiElement child1 = children1[i]; + PsiElement child2 = children2[i]; + if (!matchPattern(child1, child2, candidates, match)) return false; + } + + if (children1.length == 0) { + if (pattern.getParent() instanceof PsiVariable && ((PsiVariable)pattern.getParent()).getNameIdentifier() == pattern) { + return match.putDeclarationCorrespondence(pattern.getParent(), candidate.getParent()); + } + if (!pattern.textMatches(candidate)) return false; + } + + return true; + } + + private boolean matchReturnStatement(final PsiReturnStatement patternReturnStatement, + PsiElement candidate, + List candidates, + Match match) { + if (candidate instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)candidate).getExpression(); + if (expression instanceof PsiAssignmentExpression) { + final PsiExpression returnValue = patternReturnStatement.getReturnValue(); + final PsiExpression rExpression = ((PsiAssignmentExpression)expression).getRExpression(); + if (!matchPattern(returnValue, rExpression, candidates, match)) return false; + final PsiExpression lExpression = ((PsiAssignmentExpression)expression).getLExpression(); + return match.registerReturnValue(new ExpressionReturnValue(lExpression)); + } + else return false; + } + else if (candidate instanceof PsiDeclarationStatement) { + final PsiElement[] declaredElements = ((PsiDeclarationStatement)candidate).getDeclaredElements(); + if (declaredElements.length != 1) return false; + if (!(declaredElements[0] instanceof PsiVariable)) return false; + final PsiVariable variable = ((PsiVariable)declaredElements[0]); + if (!matchPattern(patternReturnStatement.getReturnValue(), variable.getInitializer(), candidates, match)) return false; + return match.registerReturnValue(new VariableReturnValue(variable)); + } + else if (candidate instanceof PsiReturnStatement) { + if (!match.registerReturnValue(ReturnStatementReturnValue.INSTANCE)) return false; + return matchPattern(patternReturnStatement.getReturnValue(), ((PsiReturnStatement)candidate).getReturnValue(), candidates, match); + } + else return false; + } + + private boolean equivalentResolve(final PsiElement resolveResult1, final PsiElement resolveResult2) { + final boolean b = Comparing.equal(resolveResult1, resolveResult2); + if (b) return b; + if (resolveResult1 instanceof PsiMethod && resolveResult2 instanceof PsiMethod) { + final PsiMethod method1 = ((PsiMethod)resolveResult1); + final PsiMethod method2 = ((PsiMethod)resolveResult2); + if (Arrays.asList(method1.findSuperMethods()).contains(method2)) return true; + if (Arrays.asList(method2.findSuperMethods()).contains(method1)) return true; + return false; + } + else { + return false; + } + } + + private static boolean isUnder(PsiElement element, List parents) { + if (element == null) return false; + for (int i = 0; i < parents.size(); i++) { + final PsiElement parent = parents.get(i); + if (PsiTreeUtil.isAncestor(parent, element, false)) return true; + } + return false; + } + + private static PsiElement[] getFilteredChildren(PsiElement element1) { + PsiElement[] children1 = element1.getChildren(); + ArrayList array = new ArrayList(); + for (int i = 0; i < children1.length; i++) { + PsiElement child = children1[i]; + if (!(child instanceof PsiWhiteSpace) && !(child instanceof PsiComment)) { + array.add(child); + } + } + return array.toArray(new PsiElement[array.size()]); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java new file mode 100644 index 00000000000..399ce635e4f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.codeInsight.folding.CodeFoldingManager; +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.TextRange; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class DuplicatesImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.DuplicatesImpl"); + public static void invoke(final Project project, Editor editor, final String commandName, final MatchProvider provider) { + final List duplicates = provider.getDuplicates(); + for (Iterator iterator = duplicates.iterator(); iterator.hasNext();) { + final Match match = iterator.next(); + final ArrayList highlighters = new ArrayList(); + highlightMatch(project, editor, match, highlighters); + final TextRange textRange = match.getTextRange(); + final LogicalPosition logicalPosition = editor.offsetToLogicalPosition(textRange.getStartOffset()); + expandAllRegionsCoveringRange(project, editor, textRange); + editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.MAKE_VISIBLE); + final int matchAnswer = Messages.showYesNoCancelDialog(project, "Replace this code fragment?", "Process Duplicates", Messages.getQuestionIcon()); + HighlightManager.getInstance(project).removeSegmentHighlighter(editor, (RangeHighlighter)highlighters.get(0)); + if (matchAnswer == 0) { + CommandProcessor.getInstance().executeCommand( + project, new Runnable() { + public void run() { + final Runnable action = new Runnable() { + public void run() { + try { + provider.processMatch(match); + } catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + commandName, + null + ); + + } + else if (matchAnswer == 2) { + break; + } + } + } + + private static void expandAllRegionsCoveringRange(final Project project, Editor editor, final TextRange textRange) { + final FoldRegion[] foldRegions = CodeFoldingManager.getInstance(project).getFoldRegionsAtOffset(editor, textRange.getStartOffset()); + boolean anyCollapsed = false; + for (int i = 0; i < foldRegions.length; i++) { + final FoldRegion foldRegion = foldRegions[i]; + if (!foldRegion.isExpanded()) { + anyCollapsed = true; + break; + } + } + if (anyCollapsed) { + editor.getFoldingModel().runBatchFoldingOperation(new Runnable() { + public void run() { + for (int i = 0; i < foldRegions.length; i++) { + final FoldRegion foldRegion = foldRegions[i]; + if (!foldRegion.isExpanded()) { + foldRegion.setExpanded(true); + } + } + } + }); + } + } + + public static void highlightMatch(final Project project, Editor editor, final Match match, final ArrayList highlighters) { + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + HighlightManager.getInstance(project).addRangeHighlight(editor, match.getTextRange().getStartOffset(), match.getTextRange().getEndOffset(), + attributes, true, highlighters); + } + + public static void processDuplicates(final MatchProvider provider, final Project project, Editor editor, final String commandName) { + boolean hasDuplicates = provider.hasDuplicates(); + if (hasDuplicates) { + final int answer = Messages.showYesNoDialog(project, "IDEA has detected " + provider.getDuplicates().size() + + " code fragments in this file that can be replaced with " + + "a call to extracted method. Would you like to review and replace them?", + "Process Duplicates", Messages.getQuestionIcon()); + if (answer == 0) { + invoke(project, editor, commandName, provider); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java new file mode 100644 index 00000000000..6a5977a81c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class ExpressionReturnValue implements ReturnValue { + private final PsiExpression myExpression; + + public ExpressionReturnValue(PsiExpression expression) { + myExpression = expression; + } + + public PsiExpression getExpression() { + return myExpression; + } + + public boolean isEquivalent(ReturnValue other) { + if (!(other instanceof ExpressionReturnValue)) return false; + return CodeInsightUtil.areElementsEquivalent(myExpression, ((ExpressionReturnValue)other).myExpression); + } + + public PsiStatement createReplacement(final PsiMethodCallExpression methodCallExpression) + throws IncorrectOperationException { + final PsiElementFactory elementFactory = methodCallExpression.getManager().getElementFactory(); + final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject()); + PsiExpressionStatement expressionStatement; + expressionStatement = (PsiExpressionStatement)elementFactory.createStatementFromText("x = y();", null); + expressionStatement = (PsiExpressionStatement)styleManager.reformat(expressionStatement); + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expressionStatement.getExpression(); + assignmentExpression.getLExpression().replace(getExpression()); + assignmentExpression.getRExpression().replace(methodCallExpression); + return expressionStatement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/Match.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/Match.java new file mode 100644 index 00000000000..57af52864b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/Match.java @@ -0,0 +1,204 @@ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author dsl + */ +public final class Match { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.Match"); + private final PsiElement myMatchStart; + private final PsiElement myMatchEnd; + private final Map myParameterValues = new HashMap(); + private final Map> myParameterOccurences = new HashMap>(); + private final Map myDeclarationCorrespondence = new HashMap(); + private ReturnValue myReturnValue = null; + private Ref myInstanceExpression = null; + + Match(PsiExpression expression) { + myMatchStart = expression; + myMatchEnd = expression; + } + + Match(PsiElement start, PsiElement end) { + LOG.assertTrue(start.getParent() == end.getParent()); + myMatchStart = start; + myMatchEnd = end; + } + + + public PsiElement getMatchStart() { + return myMatchStart; + } + + public PsiElement getMatchEnd() { + return myMatchEnd; + } + + public PsiElement getParameterValue(PsiVariable parameter) { + return myParameterValues.get(parameter); + } + + /** + * Returns either local variable declaration or expression + * @param outputParameter + * @return + */ + public ReturnValue getOutputVariableValue(PsiVariable outputParameter) { + final PsiElement decl = myDeclarationCorrespondence.get(outputParameter); + if (decl != null && decl instanceof PsiVariable) { + return new VariableReturnValue((PsiVariable) decl); + } + final PsiElement parameterValue = getParameterValue(outputParameter); + if (parameterValue instanceof PsiExpression) { + return new ExpressionReturnValue((PsiExpression) parameterValue); + } + else { + return null; + } + } + + + boolean putParameter(PsiVariable parameter, PsiElement value) { + final PsiElement currentValue = myParameterValues.get(parameter); + if (currentValue == null) { + if (!(value instanceof PsiExpression)) return false; + final PsiType type = ((PsiExpression)value).getType(); + final PsiType parameterType = parameter.getType(); + if (type == null || !parameterType.isAssignableFrom(type)) return false; + myParameterValues.put(parameter, value); + final ArrayList elements = new ArrayList(); + myParameterOccurences.put(parameter, elements); + return true; + } + else { + if (!CodeInsightUtil.areElementsEquivalent(currentValue, value)) { + return false; + } + myParameterOccurences.get(parameter).add(value); + return true; + } + } + + public ReturnValue getReturnValue() { + return myReturnValue; + } + + boolean registerReturnValue(ReturnValue returnValue) { + if (myReturnValue == null) { + myReturnValue = returnValue; + return true; + } + else { + if (!myReturnValue.isEquivalent(returnValue)) { + return false; + } + else { + return true; + } + } + } + + boolean registerInstanceExpression(PsiExpression instanceExpression) { + if (myInstanceExpression == null) { + myInstanceExpression = Ref.create(instanceExpression); + return true; + } + else { + if (myInstanceExpression.get() == null) { + if (instanceExpression instanceof PsiThisExpression) { + myInstanceExpression.set(instanceExpression); + return true; + } + else return myInstanceExpression != null; + } + else { + if (instanceExpression != null) { + return CodeInsightUtil.areElementsEquivalent(instanceExpression, myInstanceExpression.get()); + } + else { + return myInstanceExpression.get() == null || myInstanceExpression.get() instanceof PsiThisExpression; + } + } + } + } + + boolean putDeclarationCorrespondence(PsiElement patternDeclaration, PsiElement matchDeclaration) { + LOG.assertTrue(matchDeclaration != null); + PsiElement originalValue = myDeclarationCorrespondence.get(patternDeclaration); + if (originalValue == null) { + myDeclarationCorrespondence.put(patternDeclaration, matchDeclaration); + return true; + } + else { + return originalValue == matchDeclaration; + } + } + + private void replaceWith(final PsiStatement statement) throws IncorrectOperationException { + final PsiElement matchStart = getMatchStart(); + final PsiElement matchEnd = getMatchEnd(); + matchStart.getParent().addBefore(statement, matchStart); + matchStart.getParent().deleteChildRange(matchStart, matchEnd); + } + + public void replaceByStatement(final PsiMethodCallExpression methodCallExpression, + final PsiVariable outputVariable) throws IncorrectOperationException { + final PsiStatement statement; + if (outputVariable != null) { + statement = getOutputVariableValue(outputVariable).createReplacement(methodCallExpression); + } + else if (getReturnValue() != null) { + statement = getReturnValue().createReplacement(methodCallExpression); + } + else { + final PsiElementFactory elementFactory = methodCallExpression.getManager().getElementFactory(); + PsiExpressionStatement expressionStatement = (PsiExpressionStatement) elementFactory.createStatementFromText("x();", null); + final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getManager()); + expressionStatement = (PsiExpressionStatement)styleManager.reformat(expressionStatement); + expressionStatement.getExpression().replace(methodCallExpression); + statement = expressionStatement; + } + replaceWith(statement); + } + + public PsiExpression getInstanceExpression() { + if (myInstanceExpression == null) { + return null; + } + else { + return myInstanceExpression.get(); + } + } + + public void replace(final PsiMethodCallExpression methodCallExpression, PsiVariable outputVariable) throws IncorrectOperationException { + if (getMatchStart() == getMatchEnd() && getMatchStart() instanceof PsiExpression) { + replaceWithExpression(methodCallExpression); + } + else { + replaceByStatement(methodCallExpression, outputVariable); + } + } + + private void replaceWithExpression(final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException { + LOG.assertTrue(getMatchStart() == getMatchEnd()); + getMatchStart().replace(methodCallExpression); + } + + TextRange getTextRange() { + final TextRange textRange = + new TextRange(getMatchStart().getTextRange().getStartOffset(), + getMatchEnd().getTextRange().getEndOffset()); + return textRange; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MatchProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MatchProvider.java new file mode 100644 index 00000000000..8b178ee9445 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MatchProvider.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.util.IncorrectOperationException; + +import java.util.List; + +/** + * @author dsl + */ +public interface MatchProvider { + void processMatch(Match match) throws IncorrectOperationException; + + List getDuplicates(); + + boolean hasDuplicates(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java new file mode 100644 index 00000000000..3ddc03444be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * @author dsl + */ +public class MethodDuplicatesHandler implements RefactoringActionHandler { + public static final String REFACTORING_NAME = "Replace Method Code Duplicates"; + + public void invoke(Project project, Editor editor, PsiFile file, DataContext dataContext) { + final int offset = editor.getCaretModel().getOffset(); + final PsiElement element = file.findElementAt(offset); + final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (method == null) { + String message = "Cannot perform the refactoring.\n" + + "Locate caret inside a method."; + showErrorMessage(message, project); + return; + } + if (!file.isWritable()) { + RefactoringMessageUtil.showReadOnlyElementRefactoringMessage(project, method); + return; + } + if (method.isConstructor()) { + String message = "Cannot perform refactoring.\n" + + "Replace With Method Call does not work for constructors"; + showErrorMessage(message, project); + } + final PsiCodeBlock body = method.getBody(); + if (body == null) { + String message = "Cannot perform refactring.\n" + + "Method " + method.getName() + " does not have a body"; + showErrorMessage(message, project); + return; + } + final PsiStatement[] statements = body.getStatements(); + if (statements.length == 0) { + String message = "Cannot perform refactoring.\n" + + "Method " + method.getName() + " has an empty body"; + + showErrorMessage(message, project); + return; + } + final DuplicatesFinder duplicatesFinder; + final PsiElement[] pattern; + if (statements.length != 1 || !(statements[0] instanceof PsiReturnStatement)) { + pattern = statements; + } else { + final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue(); + if (returnValue != null) { + pattern = new PsiElement[]{returnValue}; + } + else { + pattern = statements; + } + } + duplicatesFinder = new DuplicatesFinder(pattern, Arrays.asList(method.getParameterList().getParameters()), + new ArrayList(), !method.hasModifierProperty(PsiModifier.STATIC)); + + PsiElement scope = file; + final List duplicates = duplicatesFinder.findDuplicates(scope); + if (duplicates.isEmpty()) { + final String message = "IDEA has not found any code that can be replaced with method call"; + Messages.showInfoMessage(project, message, REFACTORING_NAME); + return; + } + final int duplicatesNo = duplicates.size(); + final ArrayList highlighters = new ArrayList(); + for (Iterator iterator = duplicates.iterator(); iterator.hasNext();) { + final Match match = iterator.next(); + DuplicatesImpl.highlightMatch(project, editor, match, highlighters); + } + final MethodDuplicatesDialog dialog = new MethodDuplicatesDialog(project, method, duplicatesNo); + dialog.show(); + for (Iterator iterator = highlighters.iterator(); iterator.hasNext();) { + final RangeHighlighter rangeHighlighter = (RangeHighlighter)iterator.next(); + HighlightManager.getInstance(project).removeSegmentHighlighter(editor, rangeHighlighter); + } + if (!dialog.isOK()) return; + WindowManager.getInstance().getStatusBar(project).setInfo(getStatusMessage(duplicatesNo)); + DuplicatesImpl.invoke(project, editor, REFACTORING_NAME, new MethodDuplicatesMatchProvider(method, duplicates)); + WindowManager.getInstance().getStatusBar(project).setInfo(""); + } + + static String getStatusMessage(final int duplicatesNo) { + return duplicatesNo + " code " + (duplicatesNo == 1 ? "fragment" : "framents") + " found"; + } + + private void showErrorMessage(String message, Project project) { + RefactoringMessageUtil.showErrorMessage(REFACTORING_NAME, message, HelpID.METHOD_DUPLICATES, project); + } + + public void invoke(Project project, PsiElement[] elements, DataContext dataContext) { + throw new UnsupportedOperationException(); + } + + private static class MethodDuplicatesMatchProvider implements MatchProvider { + private final PsiMethod myMethod; + private final List myDuplicates; + + public MethodDuplicatesMatchProvider(PsiMethod method, List duplicates) { + myMethod = method; + myDuplicates = duplicates; + } + + public void processMatch(Match match) throws IncorrectOperationException { + final PsiElementFactory factory = myMethod.getManager().getElementFactory(); + final boolean needQualifier = match.getInstanceExpression() != null; + final String text = needQualifier ? "q." + myMethod.getName() + "()": myMethod.getName() + "()"; + PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)factory.createExpressionFromText(text, null); + methodCallExpression = (PsiMethodCallExpression)CodeStyleManager.getInstance(myMethod.getManager()).reformat(methodCallExpression); + final PsiParameter[] parameters = myMethod.getParameterList().getParameters(); + for (int i = 0; i < parameters.length; i++) { + final PsiParameter parameter = parameters[i]; + methodCallExpression.getArgumentList().add(match.getParameterValue(parameter)); + } + if (needQualifier) { + methodCallExpression.getMethodExpression().getQualifierExpression().replace(match.getInstanceExpression()); + } + match.replace(methodCallExpression, null); + } + + public List getDuplicates() { + return myDuplicates; + } + + public boolean hasDuplicates() { + return myDuplicates.isEmpty(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java new file mode 100644 index 00000000000..7236291358d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiReturnStatement; +import com.intellij.psi.PsiStatement; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class ReturnStatementReturnValue implements ReturnValue { + public static final ReturnStatementReturnValue INSTANCE = new ReturnStatementReturnValue(); + + private ReturnStatementReturnValue() {} + + public boolean isEquivalent(ReturnValue other) { + return other instanceof ReturnStatementReturnValue; + } + + public PsiStatement createReplacement(final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException { + final PsiElementFactory elementFactory = methodCallExpression.getManager().getElementFactory(); + final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject()); + PsiReturnStatement returnStatement = (PsiReturnStatement)elementFactory.createStatementFromText("return x;", null); + returnStatement = (PsiReturnStatement) styleManager.reformat(returnStatement); + returnStatement.getReturnValue().replace(methodCallExpression); + return returnStatement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnValue.java new file mode 100644 index 00000000000..d93b213b2ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/ReturnValue.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiStatement; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public interface ReturnValue { + boolean isEquivalent(ReturnValue other); + + PsiStatement createReplacement(PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/VariableReturnValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/VariableReturnValue.java new file mode 100644 index 00000000000..db3826c461a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/duplicates/VariableReturnValue.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.duplicates; + +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class VariableReturnValue implements ReturnValue { + private final PsiVariable myVariable; + + public VariableReturnValue(PsiVariable variable) { + myVariable = variable; + } + + public boolean isEquivalent(ReturnValue other) { + if (!(other instanceof VariableReturnValue)) return false; + return myVariable == ((VariableReturnValue)other).myVariable; + } + + public PsiVariable getVariable() { + return myVariable; + } + + public PsiStatement createReplacement(final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException { + final PsiDeclarationStatement statement; + + final PsiElementFactory elementFactory = methodCallExpression.getManager().getElementFactory(); + final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject()); + statement = (PsiDeclarationStatement)styleManager.reformat( + elementFactory.createVariableDeclarationStatement(myVariable.getName(), myVariable.getType(), methodCallExpression) + ); + ((PsiVariable)statement.getDeclaredElements()[0]).getModifierList().replace(myVariable.getModifierList()); + return statement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/javadoc/MethodJavaDocHelper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/javadoc/MethodJavaDocHelper.java new file mode 100644 index 00000000000..440ea8aabce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/javadoc/MethodJavaDocHelper.java @@ -0,0 +1,84 @@ +package com.intellij.refactoring.util.javadoc; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiElement; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.util.IncorrectOperationException; + +/** + * @author dsl + */ +public class MethodJavaDocHelper { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.javadoc.MethodJavaDocHelper"); + private final PsiMethod myMethod; + private final boolean myDoCorrectJavaDoc; + private final PsiDocComment myDocComment; + + public MethodJavaDocHelper(PsiMethod method) { + myMethod = method; + myDocComment = myMethod.getDocComment(); + if (myDocComment == null) { + myDoCorrectJavaDoc = false; + return; + } + final PsiParameter[] parameters = myMethod.getParameterList().getParameters(); + if (parameters.length != 0) { + final PsiDocTag[] paramTags = myDocComment.findTagsByName("param"); + if (paramTags.length > 0) { + myDoCorrectJavaDoc = true; + } else { + myDoCorrectJavaDoc = false; + } + } else { + myDoCorrectJavaDoc = true; + } + } + + public PsiDocTag getTagForParameter(PsiParameter parameter) { + if (!myDoCorrectJavaDoc) return null; + if (parameter == null) return null; + final String name = parameter.getName(); + final PsiDocTag[] paramTags = myDocComment.findTagsByName("param"); + for (int i = 0; i < paramTags.length; i++) { + final PsiDocTag paramTag = paramTags[i]; + final PsiElement[] dataElements = paramTag.getDataElements(); + if (dataElements.length > 0 && dataElements[0].getText().equals(name)) { + return paramTag; + } + } + return null; + } + + public PsiDocTag addParameterAfter(String name, PsiDocTag anchor) throws IncorrectOperationException { + if (!myDoCorrectJavaDoc) return null; + if (anchor == null) return prependParameter(name); + LOG.assertTrue(anchor.getParent() == myDocComment); + final PsiDocTag paramTag = myMethod.getManager().getElementFactory().createParamTag(name, ""); + return (PsiDocTag)myDocComment.addAfter(paramTag, anchor); + } + + public PsiDocTag prependParameter(String name) throws IncorrectOperationException { + if (!myDoCorrectJavaDoc) return null; + final PsiDocTag[] paramTags = myDocComment.findTagsByName("param"); + final PsiDocTag newTag = myMethod.getManager().getElementFactory().createParamTag(name, ""); + if (paramTags.length > 0) { + return (PsiDocTag)myDocComment.addBefore(newTag, paramTags[0]); + } else { + return (PsiDocTag)myDocComment.add(newTag); + } + } + + public PsiDocTag appendParameter(String name) throws IncorrectOperationException { + if (!myDoCorrectJavaDoc) return null; + final PsiDocTag[] paramTags = myDocComment.findTagsByName("param"); + final PsiDocTag newTag = myMethod.getManager().getElementFactory().createParamTag(name, ""); + if (paramTags.length > 0) { + return (PsiDocTag)myDocComment.addAfter(newTag, paramTags[paramTags.length - 1]); + } else { + return (PsiDocTag)myDocComment.add(newTag); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/BaseOccurenceManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/BaseOccurenceManager.java new file mode 100644 index 00000000000..a48e60d5af3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/BaseOccurenceManager.java @@ -0,0 +1,92 @@ +package com.intellij.refactoring.util.occurences; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; + +/** + * @author dsl + */ +public abstract class BaseOccurenceManager implements OccurenceManager { + private PsiExpression[] myOccurences = null; + private PsiElement myAnchorStatement = null; + protected final OccurenceFilter myFilter; + + public BaseOccurenceManager(OccurenceFilter filter) { + myFilter = filter; + } + + public PsiExpression[] getOccurences() { + if(myOccurences == null) { + myOccurences = findOccurences(); + + if(myFilter != null) { + ArrayList result = new ArrayList(); + for (int i = 0; i < myOccurences.length; i++) { + PsiExpression occurence = myOccurences[i]; + if(myFilter.isOK(occurence)) { result.add(occurence); } + } + if(result.size() > 0) { + myOccurences = (PsiExpression[]) result.toArray(new PsiExpression[result.size()]); + } else { + myOccurences = defaultOccurences(); + } + } + + if (getAnchorStatementForAll() == null) { + myOccurences = defaultOccurences(); + } + } + return myOccurences; + } + + protected abstract PsiExpression[] defaultOccurences(); + + protected abstract PsiExpression[] findOccurences(); + + public boolean isInFinalContext() { + return needToDeclareFinal(myOccurences); + } + + public PsiElement getAnchorStatementForAll() { + if(myAnchorStatement == null) { + myAnchorStatement = getAnchorStatementForAllInScope(null); + } + return myAnchorStatement; + + } + public PsiElement getAnchorStatementForAllInScope(PsiElement scope) { + return RefactoringUtil.getAnchorElementForMultipleExpressions(myOccurences, scope); + } + + public static boolean needToDeclareFinal(PsiExpression[] occurrences) { + PsiElement scopeToDeclare = null;; + for (int i = 0; i < occurrences.length; i++) { + PsiExpression occurrence = occurrences[i]; + if(scopeToDeclare == null) { + scopeToDeclare = occurrence; + } else { + scopeToDeclare = PsiTreeUtil.findCommonParent(scopeToDeclare, occurrence); + } + } + if(scopeToDeclare == null) { + return false; + } + + for (int i = 0; i < occurrences.length; i++) { + PsiExpression occurrence = occurrences[i]; + PsiElement parent = occurrence; + while (!parent.equals(scopeToDeclare)) { + parent = parent.getParent(); + if (parent instanceof PsiClass) { + return true; + } + } + } + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/ExpressionOccurenceManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/ExpressionOccurenceManager.java new file mode 100644 index 00000000000..a85dfc58e1e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/ExpressionOccurenceManager.java @@ -0,0 +1,61 @@ +package com.intellij.refactoring.util.occurences; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +/** + * @author dsl + */ +public class ExpressionOccurenceManager extends BaseOccurenceManager { + private PsiExpression myMainOccurence; + private final PsiElement myScope; + private final boolean myMaintainStaticContext; + + public ExpressionOccurenceManager(PsiExpression mainOccurence, PsiElement scope, OccurenceFilter filter) { + this(mainOccurence, scope, filter, false); + } + + public ExpressionOccurenceManager(PsiExpression mainOccurence, PsiElement scope, OccurenceFilter filter, boolean maintainStaticContext) { + super(filter); + myMainOccurence = mainOccurence; + myScope = scope; + myMaintainStaticContext = maintainStaticContext; + } + protected PsiExpression[] defaultOccurences() { + return new PsiExpression[]{myMainOccurence}; + } + + public PsiExpression getMainOccurence() { + return myMainOccurence; + } + + protected PsiExpression[] findOccurences() { + if("null".equals(myMainOccurence.getText())) { + return defaultOccurences(); + } + if(myFilter != null && !myFilter.isOK(myMainOccurence)) { + return defaultOccurences(); + } + final PsiExpression[] expressionOccurrences = CodeInsightUtil.findExpressionOccurrences(myScope, myMainOccurence); + if (myMaintainStaticContext && expressionOccurrences.length > 1 && !RefactoringUtil.isInStaticContext(myMainOccurence)) { + final ArrayList expressions = new ArrayList(Arrays.asList(expressionOccurrences)); + for (Iterator iterator = expressions.iterator(); iterator.hasNext();) { + final PsiExpression expression = iterator.next(); + if(RefactoringUtil.isInStaticContext(expression)) { + iterator.remove(); + } + } + return (PsiExpression[])expressions.toArray(new PsiExpression[expressions.size()]); + } + else { + return expressionOccurrences; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/LocalVariableOccurenceManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/LocalVariableOccurenceManager.java new file mode 100644 index 00000000000..cbd99cbc452 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/LocalVariableOccurenceManager.java @@ -0,0 +1,29 @@ +package com.intellij.refactoring.util.occurences; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiLocalVariable; +import com.intellij.refactoring.util.RefactoringUtil; + +/** + * @author dsl + */ +public class LocalVariableOccurenceManager extends BaseOccurenceManager { + final PsiLocalVariable myLocalVariable; + + public LocalVariableOccurenceManager(PsiLocalVariable localVariable, OccurenceFilter filter) { + super(filter); + myLocalVariable = localVariable; + } + + public PsiExpression[] defaultOccurences() { + return PsiExpression.EMPTY_ARRAY; + } + + public PsiExpression[] findOccurences() { + return CodeInsightUtil.findReferenceExpressions(RefactoringUtil.getVariableScope(myLocalVariable), myLocalVariable); + } + + +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperCallOccurenceFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperCallOccurenceFilter.java new file mode 100644 index 00000000000..9365e44519f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperCallOccurenceFilter.java @@ -0,0 +1,14 @@ +package com.intellij.refactoring.util.occurences; + + + +/** + * @author dsl + */ +public class NotInSuperCallOccurenceFilter extends NotInSuperOrThisCallFilterBase { + public static final OccurenceFilter INSTANCE = new NotInSuperCallOccurenceFilter(); + + protected String getKeywordText() { + return "super"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperOrThisCallFilterBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperOrThisCallFilterBase.java new file mode 100644 index 00000000000..bdf4367975e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInSuperOrThisCallFilterBase.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.occurences; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionList; +import com.intellij.psi.PsiMethodCallExpression; + +/** + * @author dsl + */ +public abstract class NotInSuperOrThisCallFilterBase implements OccurenceFilter { + public boolean isOK(PsiExpression occurence) { + PsiElement parent = occurence.getParent(); + while(parent instanceof PsiExpression) { + parent = parent.getParent(); + } + if(!(parent instanceof PsiExpressionList)) return true; + parent = parent.getParent(); + if(!(parent instanceof PsiMethodCallExpression)) return true; + final String text = ((PsiMethodCallExpression) parent).getMethodExpression().getText(); + return !getKeywordText().equals(text); + } + + protected abstract String getKeywordText(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInThisCallFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInThisCallFilter.java new file mode 100644 index 00000000000..e98e7202295 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/NotInThisCallFilter.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.refactoring.util.occurences; + +/** + * @author dsl + */ +public class NotInThisCallFilter extends NotInSuperOrThisCallFilterBase { + public static final NotInThisCallFilter INSTANCE = new NotInThisCallFilter(); + protected String getKeywordText() { + return "this"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceFilter.java new file mode 100644 index 00000000000..0b19e36565d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceFilter.java @@ -0,0 +1,7 @@ +package com.intellij.refactoring.util.occurences; + +import com.intellij.psi.*; + +public interface OccurenceFilter { + boolean isOK(PsiExpression occurence); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceManager.java new file mode 100644 index 00000000000..31ccad0675e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/occurences/OccurenceManager.java @@ -0,0 +1,15 @@ +package com.intellij.refactoring.util.occurences; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; + +/** + * @author dsl + */ +public interface OccurenceManager { + PsiExpression[] getOccurences(); + boolean isInFinalContext(); + PsiElement getAnchorStatementForAll(); + + PsiElement getAnchorStatementForAllInScope(PsiElement scope); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorImplicitUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorImplicitUsageInfo.java new file mode 100644 index 00000000000..197f777bc56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorImplicitUsageInfo.java @@ -0,0 +1,20 @@ +package com.intellij.refactoring.util.usageInfo; + +import com.intellij.psi.*; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class DefaultConstructorImplicitUsageInfo extends UsageInfo { + private final PsiMethod myOverridingConstructor; + + public DefaultConstructorImplicitUsageInfo(PsiMethod overridingConstructor) { + super(overridingConstructor); + myOverridingConstructor = overridingConstructor; + } + + public PsiMethod getConstructor() { + return myOverridingConstructor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorUsageCollector.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorUsageCollector.java new file mode 100644 index 00000000000..82c31edac5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/DefaultConstructorUsageCollector.java @@ -0,0 +1,22 @@ +package com.intellij.refactoring.util.usageInfo; + +import com.intellij.psi.*; +import com.intellij.refactoring.util.RefactoringUtil; + +import java.util.ArrayList; + +public class DefaultConstructorUsageCollector implements RefactoringUtil.ImplicitConstructorUsageVisitor { + private final ArrayList myUsages; + + public void visitConstructor(PsiMethod constructor) { + myUsages.add(new DefaultConstructorImplicitUsageInfo(constructor)); + } + + public void visitClassWithoutConstructors(PsiClass aClass) { + myUsages.add(new NoConstructorClassUsageInfo(aClass)); + } + + public DefaultConstructorUsageCollector(ArrayList result) { + myUsages = result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/NoConstructorClassUsageInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/NoConstructorClassUsageInfo.java new file mode 100644 index 00000000000..f35730e6586 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/refactoring/util/usageInfo/NoConstructorClassUsageInfo.java @@ -0,0 +1,20 @@ +package com.intellij.refactoring.util.usageInfo; + +import com.intellij.psi.*; +import com.intellij.usageView.UsageInfo; + +/** + * @author dsl + */ +public class NoConstructorClassUsageInfo extends UsageInfo { + private PsiClass myClass; + + public NoConstructorClassUsageInfo(PsiClass aClass) { + super(aClass); + myClass = aClass; + } + + public PsiClass getPsiClass() { + return myClass; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/EditorActionTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/EditorActionTestCase.java new file mode 100644 index 00000000000..f110f49ff34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/EditorActionTestCase.java @@ -0,0 +1,84 @@ +package com.intellij.testFramework; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +import java.io.IOException; + +/** + * A TestCase for testing some action in editor + */ +public abstract class EditorActionTestCase extends LightCodeInsightTestCase { + /** + * @return id of the action to be tested. + */ + protected abstract String getActionId(); + + /** + * Perform action test using text before and after action perform. Useas <caret> marker where caret should be + * placed when file is loaded in editor and <selection></selection> denoting selection bounds. + * @param fileName name of the file. Mostly used to create proper instance of the PsiFile + * @param textBefore text with markers before action + * @param textAfter expected text with markers after action + * @throws IOException + */ + protected void doTextTest(String fileName, String textBefore, String textAfter) throws IOException { + doTextTest(fileName, textBefore, textAfter, false); + } + + /** + * Perform action test using text before and after action perform. Useas <caret> marker where caret should be + * placed when file is loaded in editor and <selection></selection> denoting selection bounds. + * @param fileName name of the file. Mostly used to create proper instance of the PsiFile + * @param textBefore text with markers before action + * @param textAfter expected text with markers after action + * @param ignoreTrailingSpaces true if trailing spaces should be ignored. + * @throws IOException + */ + protected void doTextTest(String fileName, String textBefore, String textAfter, boolean ignoreTrailingSpaces) throws IOException { + configureFromFileText(fileName, textBefore); + invokeAction(); + checkResultByText(null, textAfter, ignoreTrailingSpaces); + } + + /** + * Same as doTextTest but texts are retreived from the data files. + * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @throws Exception + */ + protected void doFileTest(String filePathBefore, String filePathAfter) throws Exception { + doFileTest(filePathBefore, filePathAfter, false); + } + + /** + * Same as doTextTest but texts are retreived from the data files. + * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @param ignoreTrailingSpaces true if trailing spaces should be ignored. + * @throws Exception + */ + protected void doFileTest(String filePathBefore, String filePathAfter, boolean ignoreTrailingSpaces) throws Exception { + configureByFile(filePathBefore); + invokeAction(); + checkResultByFile(null, filePathAfter, ignoreTrailingSpaces); + } + + private void invokeAction() { + final String actionId = getActionId(); + final AnAction action = ActionManager.getInstance().getAction(actionId); + assertNotNull("Can find registered action with id=" + actionId, action); + action.actionPerformed( + new AnActionEvent( + null, + DataManager.getInstance().getDataContext(), + "", + action.getTemplatePresentation(), + ActionManager.getInstance(), + 0 + ) + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/IdeaTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/IdeaTestCase.java new file mode 100644 index 00000000000..78098257e96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/IdeaTestCase.java @@ -0,0 +1,476 @@ +package com.intellij.testFramework; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.idea.IdeaLogger; +import com.intellij.idea.IdeaTestApplication; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl; +import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.psi.PsiDocumentManager; +import junit.framework.TestCase; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.InvocationEvent; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author mike + */ +public abstract class IdeaTestCase extends TestCase implements DataProvider { + + static { + Logger.setFactory(TestLoggerFactory.getInstance()); + } + + protected static IdeaTestApplication ourApplication; + + protected boolean myRunCommandForTest = false; + + protected ProjectManagerEx myProjectManager; + protected Project myProject; + protected Module myModule; + protected static List myFilesToDelete; + protected boolean myAssertionsInTestDetected; + protected static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.IdeaTestCase"); + public static Thread ourTestThread; + private static TestCase ourTestCase = null; + public static final long DEFAULT_TEST_TIME = 300L; + public static long ourTestTime = DEFAULT_TEST_TIME; + private static final MyThreadGroup MY_THREAD_GROUP = new MyThreadGroup(); + + protected long getTimeRequired() { + return DEFAULT_TEST_TIME; + } + + protected String getTestName(boolean lowercaseFirstLetter) { + String name = getName(); + assertTrue(name.startsWith("test")); + name = name.substring("test".length()); + if (lowercaseFirstLetter) { + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + return name; + } + + protected void initApplication() throws Exception { + ourApplication = IdeaTestApplication.getInstance(); + ourApplication.setDataProvider(this); + } + + protected void setUp() throws Exception { + super.setUp(); + if (ourTestCase != null) { + String message = "Previous test " + ourTestCase + + " haven't called tearDown(). Probably overriden without super call."; + ourTestCase = null; + assertTrue(message, false); + } + ourTestCase = this; + IdeaLogger.ourErrorsOccurred = null; + + LOG.info("" + this.getClass().getName() + ".setUp()"); + + initApplication(); + + cleanupVfs(); + + myFilesToDelete = new ArrayList(); + + setUpProject(); + + DaemonCodeAnalyzerSettings.getInstance().setInspectionProfile(InspectionProfileImpl.EMPTY_PROFILE); + } + + protected void setUpProject() throws IOException { + myProjectManager = ProjectManagerEx.getInstanceEx(); + LOG.assertTrue(myProjectManager != null, "Cannot instaitiate ProjectManager component"); + + File projectFile = File.createTempFile("temp", ".ipr"); + myFilesToDelete.add(projectFile); + + myProject = myProjectManager.newProject(projectFile.getPath(), false, false); + + setUpModule(); + + setUpJdk(); + + ((StartupManagerImpl)StartupManager.getInstance(myProject)).runStartupActivities(); + } + + protected void setUpModule() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myModule = createMainModule(); + } + }); + } + + protected Module createMainModule() { + return createModule(myProject.getName()); + } + + protected Module createModule(final String moduleName) { + final VirtualFile projectFile = myProject.getProjectFile(); + assertNotNull(projectFile); + final File moduleFile = new File(projectFile.getParent().getPath().replace('/', File.separatorChar), + moduleName + ".iml"); + try { + moduleFile.createNewFile(); + } + catch (IOException e) { + LOG.error(e); + } + myFilesToDelete.add(moduleFile); + final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleFile); + Module module = ModuleManager.getInstance(myProject).newModule(virtualFile.getPath()); + module.getModuleFile(); + return module; + } + + private static void cleanupVfs() { + LocalFileSystemImpl localFileSystem = (LocalFileSystemImpl)LocalFileSystem.getInstance(); + if (localFileSystem != null) { + localFileSystem.cleanupForNextTest(); + } + VirtualFilePointerManagerImpl virtualFilePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance(); + if (virtualFilePointerManager != null) { + virtualFilePointerManager.cleanupForNextTest(); + } + } + + protected void tearDown() throws Exception { + try { + assertNotNull("Application components damaged", ProjectManager.getInstance()); + + FileDocumentManager.getInstance().saveAllDocuments(); + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + try { + ((ProjectEx)myProject).dispose(); + + for (Iterator iterator = myFilesToDelete.iterator(); iterator.hasNext();) { + File file = (File)iterator.next(); + delete(file); + } + + Throwable fromThreadGroup = MY_THREAD_GROUP.popThrowable(); + if (fromThreadGroup != null) { + throw new RuntimeException(fromThreadGroup); + } + + if (!myAssertionsInTestDetected) { + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; + } + assertTrue("Logger errors occurred in " + getFullName(), IdeaLogger.ourErrorsOccurred == null); + } + + ourApplication.setDataProvider(null); + + } + finally { + ourTestCase = null; + } + super.tearDown(); + + assertEquals(0, EditorFactory.getInstance().getAllEditors().length); + } + finally { + myProjectManager = null; + myProject = null; + myModule = null; + myFilesToDelete = null; + } + + + } + + private String getFullName() { + return getClass().getName() + "." + getName(); + } + + private void delete(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + delete(files[i]); + } + } + + boolean b = file.delete(); + if (!b && file.exists() && !myAssertionsInTestDetected) { + assertTrue("Can't delete " + file.getAbsolutePath() + " in " + getFullName(), false); + } + } + + protected void setUpJdk() { + //final ProjectJdkEx jdk = ProjectJdkUtil.getDefaultJdk("java 1.4"); + final ProjectJdk jdk = getTestProjectJdk(); +// ProjectJdkImpl jdk = ProjectJdkTable.getInstance().addJdk(defaultJdk); + final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + rootModel.setJdk(jdk); + rootModel.commit(); + } + }); + } + + protected ProjectJdk getTestProjectJdk() { + return JavaSdkImpl.getMockJdk("java 1.4"); + } + + public void runBare() throws Throwable { + final Throwable[] throwable = new Throwable[1]; + + Thread thread = new Thread(MY_THREAD_GROUP, new Runnable() { + public void run() { + try { + runBareImpl(); + } + catch (Throwable th) { + throwable[0] = th; + } + } + }); + thread.start(); + thread.join(); + + if (throwable[0] != null) { + throw throwable[0]; + } + } + + private void runBareImpl() throws Throwable { + final Throwable[] throwables = new Throwable[1]; + Runnable runnable = new Runnable() { + public void run() { + ourTestThread = Thread.currentThread(); + ourTestTime = getTimeRequired(); + try { + setUp(); + try { + myAssertionsInTestDetected = true; + runTest(); + myAssertionsInTestDetected = false; + } + finally { + tearDown(); + } + } + catch (Throwable throwable) { + throwables[0] = throwable; + } + finally { + ourTestThread = null; + } + } + }; + + runBareRunnable(runnable); + + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; + } + + if (throwables[0] != null) { + throw throwables[0]; + } + + // just to make sure all deffered Runnable's to finish + waitForAllLaters(); + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; + } + } + + private static void waitForAllLaters() throws InterruptedException, InvocationTargetException { + for (int i = 0; i < 3; i++) { + SwingUtilities.invokeAndWait(EmptyRunnable.getInstance()); + } + } + + protected void runBareRunnable(Runnable runnable) throws Throwable, InvocationTargetException { + SwingUtilities.invokeAndWait(runnable); + } + + protected void runTest() throws Throwable { + /* + Method runMethod = null; + try { + runMethod = getClass().getMethod(getName(), new Class[0]); + } + catch (NoSuchMethodException e) { + fail("Method \"" + getName() + "\" not found"); + } + if (runMethod != null && !Modifier.isPublic(runMethod.getModifiers())) { + fail("Method \"" + getName() + "\" should be public"); + } + + final Method method = runMethod; + */ + + final Throwable[] throwables = new Throwable[1]; + + Runnable runnable = new Runnable() { + public void run() { + try { + IdeaTestCase.super.runTest(); + /* + method.invoke(IdeaTestCase.this, new Class[0]); + */ + } + catch (InvocationTargetException e) { + e.fillInStackTrace(); + throwables[0] = e.getTargetException(); + } + catch (IllegalAccessException e) { + e.fillInStackTrace(); + throwables[0] = e; + } + catch (Throwable e) { + throwables[0] = e; + } + } + }; + + invokeTestRunnable(runnable); + + if (throwables[0] != null) { + throw throwables[0]; + } + } + + protected void invokeTestRunnable(final Runnable runnable) throws Exception { + final Exception[] e = new Exception[1]; + Runnable runnable1 = new Runnable() { + public void run() { + if (ApplicationManager.getApplication().isDispatchThread()) { + try { + ApplicationManager.getApplication().runWriteAction(runnable); + } + catch (Exception e1) { + e[0] = e1; + } + } + else { + runnable.run(); + } + } + }; + + if (myRunCommandForTest) { + CommandProcessor.getInstance().executeCommand(myProject, runnable1, "", null); + } + else { + runnable1.run(); + } + + if (e[0] != null) { + throw e[0]; + } + } + + public Object getData(String dataId) { + if (dataId.equals(DataConstants.PROJECT)) { + return myProject; + } + else if (dataId.equals(DataConstants.EDITOR)) { + return FileEditorManager.getInstance(myProject).getSelectedTextEditor(); + } + else { + return null; + } + } + + public static void dispatchAllInvocationEvents() { + final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + while (true) { + AWTEvent event = eventQueue.peekEvent(); + if (event == null) break; + try { + AWTEvent event1 = eventQueue.getNextEvent(); + if (event1 instanceof InvocationEvent) { + ((InvocationEvent)event1).dispatch(); + } + } + catch (Exception e) { + LOG.error(e); //? + } + } + } + + public static File createTempDir(final String prefix) throws IOException { + final File tempDirectory = FileUtil.createTempDirectory(prefix, null); + myFilesToDelete.add(tempDirectory); + getVirtualFile(tempDirectory); + return tempDirectory; + } + + protected static VirtualFile getVirtualFile(final File file) { + VirtualFile virtualFile; + try { + virtualFile = LocalFileSystem.getInstance().findFileByPath(file.getCanonicalPath().replace(File.separatorChar, '/')); + } + catch (IOException e) { + assertTrue(false); + virtualFile = null; + } + return virtualFile; + } + + private static class MyThreadGroup extends ThreadGroup { + private Throwable myThrowable; + + public MyThreadGroup() { + super("IDEATest"); + } + + public void uncaughtException(Thread t, Throwable e) { + myThrowable = e; + super.uncaughtException(t, e); + } + + public Throwable popThrowable() { + try { + return myThrowable; + } + finally { + myThrowable = null; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightCodeInsightTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightCodeInsightTestCase.java new file mode 100644 index 00000000000..c972b86c798 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightCodeInsightTestCase.java @@ -0,0 +1,358 @@ +package com.intellij.testFramework; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.impl.DocumentImpl; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.PsiFileImpl; + +import java.io.File; +import java.io.IOException; +import java.io.Writer; + +/** + * A TestCase for single PsiFile being opened in Editor conversion. See configureXXX and checkResultXXX method docs. + */ +public class LightCodeInsightTestCase extends LightIdeaTestCase { + private static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.LightCodeInsightTestCase"); + + protected Editor myEditor; + protected PsiFile myFile; + private VirtualFile myVFile; + + private static final String CARET_MARKER = ""; + private static final String SELECTION_START_MARKER = ""; + private static final String SELECTION_END_MARKER = ""; + + protected void runTest() throws Throwable { + final Throwable[] throwable = new Throwable[] {null}; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + public void run() { + + try { + LightCodeInsightTestCase.super.runTest(); + } catch (Throwable t) { + throwable[0] = t; + } + } + }, "", null); + } + }); + + if (throwable[0] != null) { + throw throwable[0]; + } + } + + /** + * Configure test from data file. Data file is usual java, xml or whatever file that needs to be tested except it + * has <caret> marker where caret should be placed when file is loaded in editor and <selection></selection> + * denoting selection bounds. + * @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @throws Exception + */ + protected void configureByFile(String filePath) throws Exception { + String fullPath = getTestDataPath() + filePath; + + final File ioFile = new File(fullPath); + String fileText = new String(FileUtil.loadFileText(ioFile)); + fileText = StringUtil.convertLineSeparators(fileText, "\n"); + + configureFromFileText(ioFile.getName(), fileText); + } + + protected String getTestDataPath() { + return PathManagerEx.getTestDataPath(); + } + + /** + * Same as configureByFile but text is provided directly. + * @param fileName - name of the file. + * @param fileText - data file text. + * @throws IOException + */ + protected void configureFromFileText(final String fileName, String fileText) throws IOException { + final Document fakeDocument = new DocumentImpl(fileText); + + int caretIndex = fileText.indexOf(CARET_MARKER); + int selStartIndex = fileText.indexOf(SELECTION_START_MARKER); + int selEndIndex = fileText.indexOf(SELECTION_END_MARKER); + + final RangeMarker caretMarker = caretIndex >= 0 ? fakeDocument.createRangeMarker(caretIndex, caretIndex) : null; + final RangeMarker selStartMarker = selStartIndex >= 0 ? fakeDocument.createRangeMarker(selStartIndex, selStartIndex) : null; + final RangeMarker selEndMarker = selEndIndex >= 0 ? fakeDocument.createRangeMarker(selEndIndex, selEndIndex) : null; + + if (caretMarker != null) { + fakeDocument.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length()); + } + if (selStartMarker != null) { + fakeDocument.deleteString(selStartMarker.getStartOffset(), + selStartMarker.getStartOffset() + SELECTION_START_MARKER.length()); + } + if (selEndMarker != null) { + fakeDocument.deleteString(selEndMarker.getStartOffset(), + selEndMarker.getStartOffset() + SELECTION_END_MARKER.length()); + } + + String newFileText = fakeDocument.getText(); + setupFileEditorAndDocument(fileName, newFileText); + setupCaret(caretMarker, newFileText); + setupSelection(selStartMarker, selEndMarker); + } + + private void setupSelection(final RangeMarker selStartMarker, final RangeMarker selEndMarker) { + if (selStartMarker != null) { + myEditor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset()); + } + } + + private void setupCaret(final RangeMarker caretMarker, String fileText) { + if (caretMarker != null) { + int caretLine = StringUtil.offsetToLineNumber(fileText, caretMarker.getStartOffset()); + int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(fileText, caretLine, 0); + LogicalPosition pos = new LogicalPosition(caretLine, caretCol); + myEditor.getCaretModel().moveToLogicalPosition(pos); + } + } + + private Editor createEditor(VirtualFile file) { + return FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false); + } + + private void setupFileEditorAndDocument(final String fileName, String fileText) throws IOException { + deleteVFile(); + myVFile = getSourceRoot().createChildData(this, fileName); + Writer writer = myVFile.getWriter(this); + writer.write(fileText); + writer.close(); + + myFile = getPsiManager().findFile(myVFile); + assertNotNull("Can't create PsiFile for '" + fileName + "'. Unknown file type most probably.", myFile); + ((PsiFileImpl) myFile).setIsPhysicalExplicitly(true); + myEditor = createEditor(myVFile); + } + + private void deleteVFile() { + if (myVFile != null) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + myVFile.delete(this); + } catch (IOException e) { + LOG.error(e); + } + } + }); + } + } + + protected void tearDown() throws Exception { + FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); + VirtualFile[] openFiles = editorManager.getOpenFiles(); + for (int i = 0; i < openFiles.length; i++) { + editorManager.closeFile(openFiles[i]); + } + deleteVFile(); + myEditor = null; + myFile = null; + myVFile = null; + super.tearDown(); + } + + /** + * Validates that content of the editor as well as caret and selection matches one specified in data file that + * should be formed with the same format as one used in configureByFile + * @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @throws Exception + */ + protected void checkResultByFile(String filePath) throws Exception { + checkResultByFile(null, filePath, false); + } + + /** + * Validates that content of the editor as well as caret and selection matches one specified in data file that + * should be formed with the same format as one used in configureByFile + * @param message - this check specific message. Added to text, caret position, selection checking. May be null + * @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/ + * @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing. + * @throws Exception + */ + protected void checkResultByFile(String message, final String filePath, final boolean ignoreTrailingSpaces) throws Exception { + if (ignoreTrailingSpaces) { + ((DocumentEx) myEditor.getDocument()).stripTrailingSpaces(false); + } + + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + + String fullPath = getTestDataPath() + filePath; + + File ioFile = new File(fullPath); + + assertTrue(getMessage("Cannot find file " + fullPath, message), ioFile.exists()); + String fileText = null; + try { + fileText = new String(FileUtil.loadFileText(ioFile)); + } catch (IOException e) { + LOG.error(e); + } + checkResultByText(message, StringUtil.convertLineSeparators(fileText, "\n"), ignoreTrailingSpaces); + } + + /** + * Same as checkResultByFile but text is provided directly. + * @param fileText + */ + protected void checkResultByText(String fileText) { + checkResultByText(null, fileText, false); + } + + /** + * Same as checkResultByFile but text is provided directly. + * @param message - this check specific message. Added to text, caret position, selection checking. May be null + * @param fileText + * @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing. + */ + protected void checkResultByText(String message, String fileText, final boolean ignoreTrailingSpaces) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + } + }); + final Document document = EditorFactory.getInstance().createDocument(fileText); + + int caretIndex = fileText.indexOf(CARET_MARKER); + int selStartIndex = fileText.indexOf(SELECTION_START_MARKER); + int selEndIndex = fileText.indexOf(SELECTION_END_MARKER); + + final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null; + final RangeMarker selStartMarker = selStartIndex >= 0 + ? document.createRangeMarker(selStartIndex, selStartIndex) + : null; + final RangeMarker selEndMarker = selEndIndex >= 0 + ? document.createRangeMarker(selEndIndex, selEndIndex) + : null; + + if (caretMarker != null) { + document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length()); + } + if (selStartMarker != null) { + document.deleteString(selStartMarker.getStartOffset(), + selStartMarker.getStartOffset() + SELECTION_START_MARKER.length()); + } + if (selEndMarker != null) { + document.deleteString(selEndMarker.getStartOffset(), + selEndMarker.getStartOffset() + SELECTION_END_MARKER.length()); + } + + String newFileText = document.getText(); + String newFileText1 = newFileText; + if (ignoreTrailingSpaces) { + Document document1 = EditorFactory.getInstance().createDocument(newFileText); + ((DocumentEx) document1).stripTrailingSpaces(false); + newFileText1 = document1.getText(); + } + + String text = myFile.getText(); + text = StringUtil.convertLineSeparators(text, "\n"); + + assertEquals(getMessage("Text mismatch", message), newFileText1, text); + + checkCaretPosition(caretMarker, newFileText, message); + checkSelection(selStartMarker, selEndMarker, newFileText, message); + } + + private static String getMessage(String engineMessage, String userMessage) { + if (userMessage == null) return engineMessage; + StringBuffer buf = new StringBuffer(userMessage); + buf.append(" [").append(engineMessage).append("]"); + return buf.toString(); + } + + private void checkSelection(final RangeMarker selStartMarker, final RangeMarker selEndMarker, String newFileText, String message) { + if (selStartMarker != null && selEndMarker != null) { + int selStartLine = StringUtil.offsetToLineNumber(newFileText, selStartMarker.getStartOffset()); + int selStartCol = selStartMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0); + + int selEndLine = StringUtil.offsetToLineNumber(newFileText, selEndMarker.getEndOffset()); + int selEndCol = selEndMarker.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0); + + assertEquals( + getMessage("selectionStartLine", message), + selStartLine + 1, + StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1); + + assertEquals( + getMessage("selectionStartCol", message), + selStartCol + 1, + myEditor.getSelectionModel().getSelectionStart() - + StringUtil.lineColToOffset(newFileText, selStartLine, 0) + + 1); + + assertEquals( + getMessage("selectionEndLine", message), + selEndLine + 1, + StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1); + + assertEquals( + getMessage("selectionEndCol", message), + selEndCol + 1, + myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + + 1); + } else { + assertTrue(getMessage("has no selection", message), !myEditor.getSelectionModel().hasSelection()); + } + } + + private void checkCaretPosition(final RangeMarker caretMarker, String newFileText, String message) { + if (caretMarker != null) { + int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset()); + int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0); + + assertEquals(getMessage("caretLine", message), caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1); + assertEquals(getMessage("caretColumn", message), caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1); + } + } + + public Object getData(String dataId) { + if (dataId.equals(DataConstants.EDITOR)) { + return myEditor; + } + else if (dataId.equals(DataConstants.PSI_FILE)) { + return myFile; + } + else { + return super.getData(dataId); + } + } + + /** + * @return Editor used in test. + */ + protected Editor getEditor() { + return myEditor; + } + + /** + * @return PsiFile opened in editor used in test + */ + protected PsiFile getFile() { + return myFile; + } + + protected VirtualFile getVFile() { + return myVFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightIdeaTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightIdeaTestCase.java new file mode 100644 index 00000000000..519ddef77e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LightIdeaTestCase.java @@ -0,0 +1,317 @@ +package com.intellij.testFramework; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.idea.IdeaLogger; +import com.intellij.idea.IdeaTestApplication; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.ModuleListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem; +import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.IncorrectOperationException; +import junit.framework.TestCase; + +import javax.swing.*; +import java.io.IOException; +import java.util.List; + +/** + * A testcase that provides IDEA application and project. Note both are reused for each test run in the session so + * be careful to return all the modification made to application and project components (such as settings) after + * test is finished so other test aren't affected. The project is initialized with single module that have single + * content&source entry. For your convinience the project may be equipped with some mock JDK so your tests may + * refer to external classes. In order to enable this feature you have to have a folder named "mockJDK" under + * idea installation home that is used for test running. Place src.zip under that folder. We'd suggest this is real mock + * so it contains classes that is really needed in order to speed up tests startup. + */ +public class LightIdeaTestCase extends TestCase implements DataProvider { + private static IdeaTestApplication ourApplication; + private static Project ourProject; + private static Module ourModule; + private static PsiManager ourPsiManager; + private boolean myAssertionsInTestDetected; + private static VirtualFile ourSourceRoot; + private static TestCase ourTestCase = null; + public static Thread ourTestThread; + private String oldCodeStyleSettings; + + /** + * @return Project to be used in tests for example for project components retrieval. + */ + public static Project getProject() { + return ourProject; + } + + /** + * @return Module to be used in tests for example for module components retrieval. + */ + protected static Module getModule() { + return ourModule; + } + + /** + * Shortcut to PsiManager.getInstance(getProject()) + */ + protected static PsiManager getPsiManager() { + if (ourPsiManager == null) { + ourPsiManager = PsiManager.getInstance(ourProject); + } + return ourPsiManager; + } + + private void initApplication() throws Exception { + ourApplication = IdeaTestApplication.getInstance(); + ourApplication.setDataProvider(this); + cleanupApplicationCaches(); + } + + private void cleanupApplicationCaches() { + ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).cleanupForNextTest(); + if (ourProject != null) { + UndoManager.getInstance(ourProject).dropHistory(); + } + + /* + if (ourPsiManager != null) { + ((PsiManagerImpl)ourPsiManager).cleanupForNextTest(); + } + */ + } + + private void initProject() throws Exception { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + ourProject = ProjectManagerEx.getInstanceEx().newProject("", false, false); + ourPsiManager = null; + ourModule = createMainModule(); + setUpJdk(); + + ourSourceRoot = DummyFileSystem.getInstance().createRoot("src"); + + final ModuleRootManager rootManager = ModuleRootManager.getInstance(ourModule); + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + final ContentEntry contentEntry = rootModel.addContentEntry(ourSourceRoot); + contentEntry.addSourceFolder(ourSourceRoot, false); + rootModel.commit(); + + ProjectRootManager.getInstance(ourProject).addModuleRootListener(new ModuleRootListener() { + public void beforeRootsChange(ModuleRootEvent event) { + if (!event.isCausedByFileTypesChange()) { + fail("Root modification in LightIdeaTestCase is not allowed."); + } + } + + public void rootsChanged(ModuleRootEvent event) { + + } + }); + + ModuleManager.getInstance(ourProject).addModuleListener(new ModuleListener() { + public void moduleAdded(Project project, Module module) { + fail("Adding modules is not permitted in LightIdeaTestCase."); + } + + public void beforeModuleRemoved(Project project, Module module) { + } + + public void moduleRemoved(Project project, Module module) { + + } + + public void modulesRenamed(Project project, List modules) { + } + + }); + + //((PsiManagerImpl) PsiManager.getInstance(ourProject)).runStartupActivity(); + ((StartupManagerImpl)StartupManager.getInstance(getProject())).runStartupActivities(); + } + }); + } + + protected Module createMainModule() { + return ApplicationManager.getApplication().runWriteAction(new Computable() { + public Module compute() { + return ModuleManager.getInstance(ourProject).newModule(""); + } + }); + } + + /** + * @return The only source root + */ + protected static VirtualFile getSourceRoot() { + return ourSourceRoot; + } + + protected void setUp() throws Exception { + super.setUp(); + assertNull("Previous test " + ourTestCase + " haven't called tearDown(). Probably overriden without super call.", + ourTestCase); + IdeaLogger.ourErrorsOccurred = null; + + initApplication(); + + if (ourProject == null) { + initProject(); + } + + DaemonCodeAnalyzerSettings.getInstance().setInspectionProfile(InspectionProfileImpl.EMPTY_PROFILE); + + assertFalse(getPsiManager().isDisposed()); + + CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(new CodeStyleSettings()); + } + + protected void tearDown() throws Exception { + assertNotNull("Application components damaged", ProjectManager.getInstance()); + final IOException[] exception = new IOException[1]; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + final VirtualFile[] children = ourSourceRoot.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].delete(this); + } + } + catch (IOException e) { + e.printStackTrace(); + } + } + }); + if (exception[0] != null) throw exception[0]; +// final Project[] openProjects = ProjectManagerEx.getInstanceEx().getOpenProjects(); +// assertTrue(Arrays.asList(openProjects).contains(ourProject)); + assertFalse(PsiManager.getInstance(getProject()).isDisposed()); + if (!myAssertionsInTestDetected) { + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; + } + //assertTrue("Logger errors occurred. ", IdeaLogger.ourErrorsOccurred == null); + } + + ourApplication.setDataProvider(null); + ourTestCase = null; + ((PsiManagerImpl)ourPsiManager).cleanupForNextTest(); + super.tearDown(); + + assertEquals(0, EditorFactory.getInstance().getAllEditors().length); + } + + public final void runBare() throws Throwable { + final Throwable[] throwables = new Throwable[1]; + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + try { + ourTestThread = Thread.currentThread(); + startRunAndTear(); + } + catch (Throwable throwable) { + throwables[0] = throwable; + } + finally { + ourTestThread = null; + } + } + }); + + if (throwables[0] != null) { + throw throwables[0]; + } + + // just to make sure all deffered Runnable's to finish + SwingUtilities.invokeAndWait(EmptyRunnable.getInstance()); + + if (IdeaLogger.ourErrorsOccurred != null) { + throw IdeaLogger.ourErrorsOccurred; + } + } + + private void startRunAndTear() throws Throwable { + setUp(); + try { + myAssertionsInTestDetected = true; + runTest(); + myAssertionsInTestDetected = false; + } + finally { + tearDown(); + } + } + + public Object getData(String dataId) { + if (dataId.equals(DataConstants.PROJECT)) { + return ourProject; + } + else { + return null; + } + } + + protected void setUpJdk() { + final ProjectJdk jdk = JavaSdkImpl.getMockJdk("java 1.4"); + if (jdk == null) return; + final ModuleRootManager rootManager = ModuleRootManager.getInstance(ourModule); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + rootModel.setJdk(jdk); + rootModel.commit(); + } + }); + } + + /** + * Creates dummy source file. One is not placed under source root so some PSI functions like resolve to external classes + * may not work. Though it works significantly faster and yet can be used if you need to create some PSI structures for + * test purposes + * + * @param fileName - name of the file to create. Extension is used to choose what PSI should be created like java, jsp, aj, xml etc. + * @param text - file text. + * @return dummy psi file. + * @throws IncorrectOperationException + */ + protected PsiFile createFile(String fileName, String text) throws IncorrectOperationException { + return getPsiManager().getElementFactory().createFileFromText(fileName, text); + } + + /** + * Convinient conversion of testSomeTest -> someTest | SomeTest where testSomeTest is the name of current test. + * + * @param lowercaseFirstLetter - whether first letter after test should be lowercased. + */ + protected String getTestName(boolean lowercaseFirstLetter) { + String name = getName(); + assertTrue("Test name should start with 'test'", name.startsWith("test")); + name = name.substring("test".length()); + if (lowercaseFirstLetter) { + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + return name; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LoggedErrorProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LoggedErrorProcessor.java new file mode 100644 index 00000000000..7df32c4e4b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/LoggedErrorProcessor.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.testFramework; + +public abstract class LoggedErrorProcessor { + + private final static LoggedErrorProcessor DEFAULT = new LoggedErrorProcessor() { + public void processError(String message, Throwable t, String[] details, org.apache.log4j.Logger logger) { + logger.info(message, t); + System.err.println("ERROR: " + message); + t.printStackTrace(); + if (details != null && details.length > 0) { + System.out.println("details: "); + for (int i = 0; i < details.length; i++) { + System.out.println(details[i]); + } + } + + throw new AssertionError(message); + } + }; + + private static LoggedErrorProcessor ourInstance = DEFAULT; + + public static LoggedErrorProcessor getInstance() { + return ourInstance; + } + + public static void setNewInstance(LoggedErrorProcessor newInstance) { + ourInstance = newInstance; + } + + public static void restoreDefaultProcessor() { + ourInstance = DEFAULT; + } + + public abstract void processError(String message, Throwable t, String[] details, org.apache.log4j.Logger logger); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/MockVirtualFile.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/MockVirtualFile.java new file mode 100644 index 00000000000..97978097b76 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/MockVirtualFile.java @@ -0,0 +1,162 @@ +package com.intellij.testFramework; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.VirtualFileListener; +import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.util.LocalTimeCounter; +import junit.framework.Assert; + +import java.io.*; + +public class MockVirtualFile extends VirtualFile { + protected String myContent = ""; + protected String myName = ""; + protected long myModStamp = LocalTimeCounter.currentTime(); + protected long myTimeStamp = System.currentTimeMillis(); + protected long myActualTimeStamp = myTimeStamp; + private boolean myIsWritable = true; + private VirtualFileListener myListener = null; + + public MockVirtualFile() { + } + + public MockVirtualFile(String name) { + myName = name; + } + + public MockVirtualFile(String name, String content) { + myName = name; + myContent = content; + } + + public void setListener(VirtualFileListener listener) { + myListener = listener; + } + + public VirtualFileSystem getFileSystem() { + return null; + } + + public String getPath() { + return "/" + getName(); + } + + public String getName() { + return myName; + } + + public void rename(Object requestor, String newName) throws IOException { + } + + public boolean isWritable() { + return myIsWritable; + } + + public boolean isDirectory() { + return false; + } + + public boolean isValid() { + return true; + } + + public VirtualFile getParent() { + return null; + } + + public VirtualFile[] getChildren() { + return VirtualFile.EMPTY_ARRAY; + } + + public VirtualFile createChildDirectory(Object requestor, String name) throws IOException { + return null; + } + + public VirtualFile createChildData(Object requestor, String name) throws IOException { + return null; + } + + public void delete(Object requestor) throws IOException { + } + + public void move(Object requestor, VirtualFile newParent) throws IOException { + } + + public InputStream getInputStream() throws IOException { + return null; + } + + public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException { + return null; + } + + public byte[] contentsToByteArray() throws IOException { + return myContent.getBytes(); + } + + public char[] contentsToCharArray() throws IOException { + return myContent.toCharArray(); + } + + public long getModificationStamp() { + return myModStamp; + } + + public long getTimeStamp() { + return myTimeStamp; + } + + public long getActualTimeStamp() { + return myActualTimeStamp; + } + + public void setActualTimeStamp(long actualTimeStamp) { + myActualTimeStamp = actualTimeStamp; + } + + public long getLength() { + try { + return contentsToByteArray().length; + } + catch (IOException e) { + e.printStackTrace(); + Assert.assertTrue(false); + return 0; + } + } + + public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) { + } + + public Reader getReader() throws IOException { + return new CharArrayReader(contentsToCharArray()); + } + + public Writer getWriter(Object requestor, final long newModificationStamp, long newTimeStamp) throws IOException { + return new CharArrayWriter() { + public void close() { + super.close(); + myModStamp = newModificationStamp; + myContent = toString(); + } + }; + } + + public void setContent(Object requestor, String content, boolean fireEvent) { + long oldStamp = myModStamp; + myContent = content; + if (fireEvent) { + myModStamp = LocalTimeCounter.currentTime(); + myListener.contentsChanged(new VirtualFileEvent(requestor, this, null, oldStamp, myModStamp)); + } + } + + public VirtualFile self() { + return this; + } + + public void setWritable(boolean b) { + myIsWritable = b; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/ModuleTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/ModuleTestCase.java new file mode 100644 index 00000000000..3fc29d4422e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/ModuleTestCase.java @@ -0,0 +1,123 @@ +package com.intellij.testFramework; + +import com.intellij.j2ee.j2eeDom.J2EEModuleProperties; +import com.intellij.j2ee.make.ModuleBuildProperties; +import com.intellij.j2ee.make.ModuleBuildPropertiesEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.impl.ModuleImpl; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public abstract class ModuleTestCase extends IdeaTestCase { + protected final Collection myModulesToDispose = new ArrayList(); + + protected void setUp() throws Exception { + super.setUp(); + myModulesToDispose.clear(); + } + + protected void tearDown() throws Exception { + final ModuleManager moduleManager = ModuleManager.getInstance(myProject); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + for (Iterator iterator = myModulesToDispose.iterator(); iterator.hasNext();) { + Module module = iterator.next(); + String moduleName = module.getName(); + if (moduleManager.findModuleByName(moduleName) != null) { + moduleManager.disposeModule(module); + } + } + } + }); + myModulesToDispose.clear(); + super.tearDown(); + } + + protected Module createModule(final File moduleFile) { + return createModule(moduleFile, ModuleType.JAVA); + } + + protected Module createModule(final File moduleFile, final ModuleType moduleType) { + final String path = moduleFile.getAbsolutePath(); + return createModule(path, moduleType); + } + + protected Module createModule(final String path) { + return createModule(path, ModuleType.JAVA); + } + + protected Module createModule(final String path, final ModuleType moduleType) { + Module module = ApplicationManager.getApplication().runWriteAction( + new Computable() { + public Module compute() { + return ModuleManager.getInstance(myProject).newModule(path, moduleType); + } + } + ); + + myModulesToDispose.add(module); + return module; + } + + protected Module loadModule(final File moduleFile) { + Module module = ApplicationManager.getApplication().runWriteAction( + new Computable() { + public Module compute() { + try { + return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath()); + } + catch (Exception e) { + LOG.error(e); + return null; + } + } + } + ); + + myModulesToDispose.add(module); + return module; + } + + protected ModuleImpl loadAllModulesUnder(VirtualFile rootDir) throws Exception { + ModuleImpl module = null; + final VirtualFile[] children = rootDir.getChildren(); + for (int i = 0; i < children.length; i++) { + VirtualFile child = children[i]; + if (child.isDirectory()) { + final ModuleImpl childModule = loadAllModulesUnder(child); + if (module == null) module = childModule; + } + else if (child.getName().endsWith(".iml")) { + String modulePath = child.getPath(); + module = (ModuleImpl)loadModule(new File(modulePath)); + readJdomExternalizables(module); + } + } + return module; + } + + private static void readJdomExternalizables(ModuleImpl module) { + final ModuleRootManagerImpl moduleRootManager = (ModuleRootManagerImpl)ModuleRootManager.getInstance(module); + module.doInitJdomExternalizable(ModuleRootManager.class, moduleRootManager); + + ModuleBuildPropertiesEx moduleBuildProperties = (ModuleBuildPropertiesEx)ModuleBuildProperties.getInstance(module); + if (moduleBuildProperties != null) { + module.doInitJdomExternalizable(ModuleBuildPropertiesEx.class, moduleBuildProperties); + } + + J2EEModuleProperties moduleProperties = J2EEModuleProperties.getInstance(module); + if (moduleProperties != null){ + module.doInitJdomExternalizable(J2EEModuleProperties.class, moduleProperties); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestCase.java new file mode 100644 index 00000000000..8aacd87c162 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestCase.java @@ -0,0 +1,196 @@ +package com.intellij.testFramework; + +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.util.IncorrectOperationException; +import org.jdom.Document; +import org.jdom.Element; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.List; +import java.util.StringTokenizer; + +/** + * @author Mike + */ +public abstract class PsiTestCase extends ModuleTestCase { + protected PsiManagerImpl myPsiManager; + + protected PsiFile myFile; + protected PsiTestData myTestDataBefore; + protected PsiTestData myTestDataAfter; + private String myDataRoot; + + protected void setUp() throws Exception { + super.setUp(); + myPsiManager = (PsiManagerImpl) PsiManager.getInstance(myProject); + } + + protected void tearDown() throws Exception { + myPsiManager = null; + myFile = null; + myTestDataBefore = null; + myTestDataAfter = null; + super.tearDown(); + } + + protected PsiFile createDummyFile(String fileName, String text) throws IncorrectOperationException { + return myPsiManager.getElementFactory().createFileFromText(fileName, text); + } + + protected PsiFile createFile(String fileName, String text) throws Exception { + return createFile(myModule, fileName, text); + } + protected PsiFile createFile(Module module, String fileName, String text) throws Exception { + File dir = createTempDir("unitTest"); + VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/')); + + return createFile(module, vDir, fileName, text); + } + + protected PsiFile createFile(Module module, VirtualFile vDir, String fileName, String text) throws IOException { + if (!ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vDir)) { + PsiTestUtil.addSourceContentToRoots(module, vDir); + } + + final VirtualFile vFile = vDir.createChildData(vDir, fileName); + final Writer out = new OutputStreamWriter(vFile.getOutputStream(myPsiManager)); + out.write(text.toCharArray()); + out.close(); + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + assertNotNull(vFile); + final PsiFile file = myPsiManager.findFile(vFile); + assertNotNull(file); + return file; + } + + protected PsiElement configureByFileWithMarker(String filePath, String marker) throws Exception{ + final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(filePath.replace(File.separatorChar, '/')); + assertNotNull("file " + filePath + " not found", vFile); + + String fileText = new String(vFile.contentsToCharArray()); + fileText = StringUtil.convertLineSeparators(fileText, "\n"); + + int offset = fileText.indexOf(marker); + assertTrue(offset >= 0); + fileText = fileText.substring(0, offset) + fileText.substring(offset + marker.length()); + + myFile = createFile(vFile.getName(), fileText); + + return myFile.findElementAt(offset); + } + + protected void configure(String path, String dataName) throws Exception { + myDataRoot = PathManagerEx.getTestDataPath() + path; + + myTestDataBefore = loadData(dataName); + + PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk("java 1.4")); + VirtualFile vDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, myDataRoot, myFilesToDelete); + + final VirtualFile vFile = vDir.findChild(myTestDataBefore.getTextFile()); + myFile = myPsiManager.findFile(vFile); + } + + private PsiTestData loadData(String dataName) throws Exception { + Document document = JDOMUtil.loadDocument(new File(myDataRoot + "/" + "data.xml")); + + PsiTestData data = createData(); + Element documentElement = document.getRootElement(); + + final List nodes = documentElement.getChildren("data"); + + for (int i = 0; i < nodes.size(); i++) { + Element node = (Element)nodes.get(i); + String value = node.getAttributeValue("name"); + + if (value.equals(dataName)) { + DefaultJDOMExternalizer.readExternal(data, node); + data.loadText(myDataRoot); + + return data; + } + } + + throw new IllegalArgumentException("Cannot find data chunk '" + dataName + "'"); + } + + protected PsiTestData createData() { + return new PsiTestData(); + } + + protected void checkResult(String dataName) throws Exception { + myTestDataAfter = loadData(dataName); + + final String textExpected = myTestDataAfter.getText(); + final String actualText = myFile.getText(); + + if (!textExpected.equals(actualText)) { + System.out.println("Text mismatch: " + getName() + "(" + getClass().getName() + ")"); + System.out.println("Text expected:"); + printText(textExpected); + System.out.println("Text found:"); + printText(actualText); + + assertTrue("text", false); + } + +// assertEquals(myTestDataAfter.getText(), myFile.getText()); + } + + protected static void printText(String text) { + final String q = "\""; + System.out.print(q); + + text = StringUtil.convertLineSeparators(text, "\n"); + + StringTokenizer tokenizer = new StringTokenizer(text, "\n", true); + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken(); + + if (token.equals("\n")) { + System.out.print(q); + System.out.println(); + System.out.print(q); + continue; + } + + System.out.print(token); + } + + System.out.print(q); + System.out.println(); + } + + protected void addLibraryToRoots(final VirtualFile jarFile, OrderRootType rootType) { + final ModuleRootManager manager = ModuleRootManager.getInstance(myModule); + final ModifiableRootModel rootModel = manager.getModifiableModel(); + final Library jarLibrary = rootModel.getModuleLibraryTable().createLibrary(); + final Library.ModifiableModel libraryModel = jarLibrary.getModifiableModel(); + libraryModel.addRoot(jarFile, rootType); + libraryModel.commit(); + rootModel.commit(); + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestData.java new file mode 100644 index 00000000000..fde6f0430fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestData.java @@ -0,0 +1,42 @@ +package com.intellij.testFramework; + +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.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Element; + +import java.io.File; +import java.io.IOException; + +/** + * @author Mike + */ +public class PsiTestData implements JDOMExternalizable { + public String TEXT_FILE = ""; + private String myText; + + public String getTextFile() { + return TEXT_FILE; + } + + public String getText() { + return myText; + } + + public void loadText(String root) throws IOException{ + String fileName = root + "/" + TEXT_FILE; + myText = new String(FileUtil.loadFileText(new File(fileName))); + myText = StringUtil.convertLineSeparators(myText, "\n"); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestUtil.java new file mode 100644 index 00000000000..18c283a30af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/PsiTestUtil.java @@ -0,0 +1,88 @@ +package com.intellij.testFramework; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdk; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.util.IncorrectOperationException; +import junit.framework.Assert; + +import java.io.File; +import java.util.List; + +public class PsiTestUtil { + public static VirtualFile createTestProjectStructure(Project project, + Module module, + String rootPath, + List filesToDelete) throws Exception { + return createTestProjectStructure(project, module, rootPath, filesToDelete, true); + } + + public static VirtualFile createTestProjectStructure(Project project, Module module, List filesToDelete) + throws Exception { + return createTestProjectStructure(project, module, null, filesToDelete, true); + } + + public static VirtualFile createTestProjectStructure(Project project, + Module module, + String rootPath, + List filesToDelete, + boolean addProjectRoots) throws Exception { + File dir = FileUtil.createTempDirectory("unitTest", null); + filesToDelete.add(dir); + + VirtualFile vDir2 = LocalFileSystem.getInstance().refreshAndFindFileByPath( + dir.getCanonicalPath().replace(File.separatorChar, '/')); + + if (rootPath != null) { + VirtualFile vDir1 = LocalFileSystem.getInstance().findFileByPath(rootPath.replace(File.separatorChar, '/')); + if (vDir1 == null) { + throw new Exception(rootPath + " not found"); + } + VfsUtil.copyDirectory(null, vDir1, vDir2, null); + } + + VirtualFile vDir = vDir2; + if (addProjectRoots) { + addSourceContentToRoots(module, vDir); + } + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + return vDir; + } + + public static void removeAllRoots(Module module, final ProjectJdk jdk) { + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + rootModel.clear(); + rootModel.setJdk(jdk); + rootModel.commit(); + } + + public static void addSourceContentToRoots(Module module, VirtualFile vDir) { + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + final ContentEntry contentEntry = rootModel.addContentEntry(vDir); + contentEntry.addSourceFolder(vDir, false); + rootModel.commit(); + } + + public static void checkFileStructure(PsiFile file) throws IncorrectOperationException { + String originalTree = DebugUtil.psiTreeToString(file, false); + PsiElementFactory factory = file.getManager().getElementFactory(); + PsiFile dummyFile = factory.createFileFromText(file.getName(), file.getText()); + String reparsedTree = DebugUtil.psiTreeToString(dummyFile, false); + Assert.assertEquals(reparsedTree, originalTree); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestEditorManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestEditorManagerImpl.java new file mode 100644 index 00000000000..290666b4505 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestEditorManagerImpl.java @@ -0,0 +1,294 @@ +package com.intellij.testFramework; + +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.impl.EditorComposite; +import com.intellij.openapi.fileEditor.impl.EditorWindow; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.containers.HashMap; +import org.jdom.Element; + +import javax.swing.*; +import java.util.Map; + +public class TestEditorManagerImpl extends FileEditorManagerEx implements ApplicationComponent, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.idea.test.TestEditorManagerImpl"); + + private final Project myProject; + + private Map myVirtualFile2Editor = new HashMap(); + private VirtualFile myActiveFile = null; + private static final MockVirtualFile MOCK_VIRTUAL_FILE = new MockVirtualFile("Dummy.java"); + + public Pair openFileWithProviders(VirtualFile file, boolean focusEditor) { + Editor editor = openTextEditor(new OpenFileDescriptor(myProject, file), focusEditor); + final FileEditor fileEditor = TextEditorProvider.getInstance().getTextEditor(editor); + return Pair.create (new FileEditor[] {fileEditor}, new FileEditorProvider[] {getProvider (fileEditor)}); + } + + public void moveFocusToNextEditor() { + throw new UnsupportedOperationException(); + } + + public void createSplitter(int orientation) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void changeSplitterOrientation() { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void flipTabs() { + //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean tabsMode() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean isInSplitter() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean hasOpenedFile() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public VirtualFile getCurrentFile() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public Pair getSelectedEditorWithProvider(VirtualFile file) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean isChanged(EditorComposite editor) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public EditorWindow getNextWindow(EditorWindow window) { + return null; + } + + public EditorWindow getPrevWindow(EditorWindow window) { + return null; + } + + public void closeAllFiles() { + } + + public FileEditorProvider getProvider(FileEditor editor) { + return new FileEditorProvider() { + public boolean accept(Project project, VirtualFile file) { + return false; + } + + public FileEditor createEditor(Project project, VirtualFile file) { + return null; + } + + public void disposeEditor(FileEditor editor) { + + } + + public FileEditorState readState(Element sourceElement, Project project, VirtualFile file) { + return null; + } + + public void writeState(FileEditorState state, Project project, Element targetElement) { + + } + + public String getEditorTypeId() { + return ""; + } + + public FileEditorPolicy getPolicy() { + return null; + } + }; + } + + public EditorWindow getCurrentWindow() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public void setCurrentWindow(EditorWindow window) { + } + + public VirtualFile getFile(FileEditor editor) { + return MOCK_VIRTUAL_FILE; + } + + public boolean hasSplitters() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean hasTabGroups() { + throw new UnsupportedOperationException(); + } + + public boolean isFilePinned(VirtualFile file) { + throw new UnsupportedOperationException(); + } + + public void setFilePinned(VirtualFile file, boolean pinned) { + throw new UnsupportedOperationException(); + } + + public void unsplitWindow() { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void unsplitAllWindow() { + //To change body of implemented methods use File | Settings | File Templates. + } + + public EditorWindow[] getWindows() { + return new EditorWindow[0]; //To change body of implemented methods use File | Settings | File Templates. + } + + public int getTabGroupsOrientation() { + throw new UnsupportedOperationException(); + } + + public void setTabGroupsOrientation(int orientation) { + throw new UnsupportedOperationException(); + } + + public void moveToOppositeTabGroup(VirtualFile file) { + throw new UnsupportedOperationException(); + } + + public FileEditor getSelectedEditor(VirtualFile file) { + final Editor editor = getEditor(file); + return editor == null ? null : TextEditorProvider.getInstance().getTextEditor(editor); + } + + public boolean isFileOpen(VirtualFile file) { + return getEditor(file) != null; + } + + public FileEditor[] getEditors(VirtualFile file) { + return new FileEditor[] {getSelectedEditor(file)}; + } + + public TestEditorManagerImpl(Project project) { + myProject = project; + } + + public VirtualFile[] getSiblings(VirtualFile file) { + throw new UnsupportedOperationException(); + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public void projectClosed() { + } + + public void projectOpened() { + } + + public void closeFile(VirtualFile file) { + Editor editor = myVirtualFile2Editor.get(file); + if (editor != null){ + EditorFactory.getInstance().releaseEditor(editor); + myVirtualFile2Editor.remove(file); + } + } + + public VirtualFile[] getSelectedFiles() { + return myActiveFile == null ? VirtualFile.EMPTY_ARRAY : new VirtualFile[]{myActiveFile}; + } + + public FileEditor[] getSelectedEditors() { + return new FileEditor[0]; + } + + public Editor getSelectedTextEditor() { + return myActiveFile != null ? getEditor(myActiveFile) : null; + } + + public JComponent getComponent() { + throw new UnsupportedOperationException(); + } + + public VirtualFile[] getOpenFiles() { + return myVirtualFile2Editor.keySet().toArray(new VirtualFile[myVirtualFile2Editor.size()]); + } + + public Editor getEditor(VirtualFile file) { + return myVirtualFile2Editor.get(myActiveFile); + } + + public FileEditor[] getAllEditors(){ + throw new UnsupportedOperationException(); + } + + public void registerFileAsOpened(VirtualFile file, Editor editor) { + myVirtualFile2Editor.put(file, editor); + myActiveFile = file; + } + + public Editor openTextEditor(OpenFileDescriptor descriptor, boolean focusEditor) { + final VirtualFile file = descriptor.getFile(); + Editor editor = myVirtualFile2Editor.get(file); + + if (editor == null) { + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); + LOG.assertTrue(psiFile != null); + Document document = PsiDocumentManager.getInstance(myProject).getDocument(psiFile); + editor = EditorFactory.getInstance().createEditor(document, myProject); + ((EditorEx) editor).setHighlighter(HighlighterFactory.createHighlighter(myProject, file)); + + myVirtualFile2Editor.put(file, editor); + } + + if (descriptor.getOffset() >= 0){ + editor.getCaretModel().moveToOffset(descriptor.getOffset()); + } + else if (descriptor.getLine() >= 0 && descriptor.getColumn() >= 0){ + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(descriptor.getLine(), descriptor.getColumn())); + } + editor.getSelectionModel().removeSelection(); + myActiveFile = file; + + return editor; + } + + public void addFileEditorManagerListener(FileEditorManagerListener listener) { + } + + public void removeFileEditorManagerListener(FileEditorManagerListener listener) { + } + + public JComponent getPreferredFocusedComponent() { + throw new UnsupportedOperationException(); + } + + public Pair getEditorsWithProviders(VirtualFile file) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public String getComponentName() { + return "TestEditorManager"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLogger.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLogger.java new file mode 100644 index 00000000000..9aecd8db23a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLogger.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.testFramework; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; + +public class TestLogger extends com.intellij.openapi.diagnostic.Logger { + private org.apache.log4j.Logger myLogger; + + public TestLogger(Logger logger) { + myLogger = logger; + } + + public boolean isDebugEnabled() { + return false; + } + + public void debug(String message) { + myLogger.debug(message); + } + + public void debug(Throwable t) { + myLogger.debug(t); + } + + public void error(String message, Throwable t, String[] details) { + LoggedErrorProcessor.getInstance().processError(message, t, details, myLogger); + } + + public void info(String message) { + myLogger.info(message); + } + + public void info(String message, Throwable t) { + myLogger.info(message, t); + } + + public void setLevel(Level level) { + myLogger.setLevel(level); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLoggerFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLoggerFactory.java new file mode 100644 index 00000000000..e2064a62cc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestLoggerFactory.java @@ -0,0 +1,82 @@ +package com.intellij.testFramework; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.apache.log4j.LogManager; +import org.apache.log4j.xml.DOMConfigurator; + +import java.io.File; +import java.io.StringReader; + +public class TestLoggerFactory implements Logger.Factory { + private static final String SYSTEM_MACRO = "$SYSTEM_DIR$"; + private static final String APPLICATION_MACRO = "$APPLICATION_DIR$"; + private static final String LOGDIR_MACRO = "$LOG_DIR$"; + + private boolean myInitialized = false; + + private static final TestLoggerFactory ourInstance = new TestLoggerFactory(); + public static final String LOG_DIR = "testlog"; + + public static TestLoggerFactory getInstance() { + return ourInstance; + } + + private TestLoggerFactory() { + } + + public Logger getLoggerInstance(String name) { + synchronized (this) { + try { + if (!isInitialized()) { + init(); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return new TestLogger(org.apache.log4j.Logger.getLogger(name)); + } + } + + private void init() { + try { + System.setProperty("log4j.defaultInitOverride", "true"); + String fileName = PathManager.getBinPath() + File.separator + "log.xml"; + File logXmlFile = new File(fileName); + if (!logXmlFile.exists()) { + throw new RuntimeException("log.xml file does not exist! Path: [" + fileName + "]"); + } + String text = new String(FileUtil.loadFileText(logXmlFile)); + text = StringUtil.replace(text, SYSTEM_MACRO, StringUtil.replace(PathManager.getSystemPath(), "\\", "\\\\")); + text = StringUtil.replace(text, APPLICATION_MACRO, StringUtil.replace(PathManager.getHomePath(), "\\", "\\\\")); + text = StringUtil.replace(text, LOGDIR_MACRO, StringUtil.replace(LOG_DIR, "\\", "\\\\")); + + File file = new File(PathManager.getSystemPath() + File.separator + LOG_DIR); + file.mkdirs(); + + DOMConfigurator domConfigurator = new DOMConfigurator(); + try { + domConfigurator.doConfigure(new StringReader(text), LogManager.getLoggerRepository()); + } + catch (ClassCastException e) { + // shit :-E + System.out.println("log.xml content:\n" + text); + throw e; + } + myInitialized = true; + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private boolean isInitialized() { + return myInitialized; + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestSourceBasedTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestSourceBasedTestCase.java new file mode 100644 index 00000000000..6ab7648c00a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/testFramework/TestSourceBasedTestCase.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.testFramework; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; + +import java.io.File; + +public abstract class TestSourceBasedTestCase extends IdeaTestCase { + private File myTempDirectory; + + protected void setUp() throws Exception { + super.setUp(); + myTempDirectory = FileUtil.createTempDirectory("testCopy", "test"); + myFilesToDelete.add(getTestContentFile()); + final File testRoot = new File(PathManagerEx.getTestDataPath(), getTestPath()); + assertTrue(testRoot.getAbsolutePath(), testRoot.isDirectory()); + + final File currentTestRoot = new File(testRoot, getTestDirectoryName()); + assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory()); + + FileUtil.copyDir(currentTestRoot, new File(myTempDirectory, getTestDirectoryName())); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + setupContentRoot(); + } + }); + + } + + protected abstract String getTestPath(); + + private File getTestContentFile() { + return new File(myTempDirectory, getTestDirectoryName()); + } + + private void setupContentRoot() { + ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); + ContentEntry contentEntry = modifiableModel.addContentEntry(getContentRoot()); + VirtualFile src = getContentRoot().findChild("src"); + if (src != null) { + contentEntry.addSourceFolder(src, false); + } + modifiableModel.commit(); + } + + private VirtualFile getContentRoot() { + File file = getTestContentFile(); + VirtualFile content = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + return content; + } + + protected String getTestDirectoryName() { + return getTestName(true); + } + + + protected PsiDirectory getPackageDirectory(final String packageRelativePath) { + return PsiManager.getInstance(myProject).findDirectory(getContentRoot().findFileByRelativePath("src/" + packageRelativePath)); + } + + protected PsiDirectory getSrcDirectory() { + return PsiManager.getInstance(myProject).findDirectory(getContentRoot().findFileByRelativePath("src")); + } + + protected PsiDirectory getContentDirectory() { + return PsiManager.getInstance(myProject).findDirectory(getContentRoot()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ExternalToolsGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ExternalToolsGroup.java new file mode 100644 index 00000000000..03e1ead13d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ExternalToolsGroup.java @@ -0,0 +1,84 @@ +package com.intellij.tools; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; + +/** + * @author Eugene Belyaev + */ +public class ExternalToolsGroup extends SimpleActionGroup { + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + removeAll(); + String context = event.getPlace(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + if (project == null) { + presentation.setVisible(false); + presentation.setEnabled(false); + return; + } + presentation.setEnabled(true); + String[] groups = ToolManager.getInstance().getGroups(); + for (int i = 0; i < groups.length; i++) { + String groupName = groups[i]; + if (groupName != null && groupName.trim().length() > 0) { + SimpleActionGroup subgroup = new SimpleActionGroup(); + subgroup.getTemplatePresentation().setText(groupName, false); + subgroup.setPopup(true); + fillGroup(context, groupName, subgroup); + if (subgroup.getChildrenCount() > 0) { + add(subgroup); + } + } + else { + fillGroup(context, null, this); + } + } + presentation.setVisible(getChildrenCount() > 0); + } + + private void fillGroup(String context, String groupName, SimpleActionGroup group) { + Tool[] tools = ToolManager.getInstance().getTools(groupName); + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + if (isToolVisible(tool, context)) { + addToolToGroup(tool, group); + } + } + } + + private void addToolToGroup(Tool tool, SimpleActionGroup group) { + String id = tool.getActionId(); + AnAction action = ActionManager.getInstance().getAction(id); + if (action == null) { + action = new ToolAction(tool); + } + + group.add(action); + } + + private boolean isToolVisible(Tool tool, String context) { + if (!tool.isEnabled()) return false; + if (ActionPlaces.EDITOR_POPUP.equals(context)) { + return tool.isShownInEditor(); + } + else if ( + ActionPlaces.PROJECT_VIEW_POPUP.equals(context) || + ActionPlaces.COMMANDER_POPUP.equals(context) || + ActionPlaces.J2EE_VIEW_POPUP.equals(context) || + ActionPlaces.TYPE_HIERARCHY_VIEW_POPUP.equals(context) || + ActionPlaces.CALL_HIERARCHY_VIEW_POPUP.equals(context) || + ActionPlaces.METHOD_HIERARCHY_VIEW_POPUP.equals(context) + ){ + return tool.isShownInProjectViews(); + } + else if (ActionPlaces.MAIN_MENU.equals(context)) { + return tool.isShownInMainMenu(); + } + else if (ActionPlaces.USAGE_VIEW_POPUP.equals(context)) { + return tool.isShownInSearchResultsPopup(); + } + return false; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterDialog.java new file mode 100644 index 00000000000..2f0f4485a2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterDialog.java @@ -0,0 +1,174 @@ +/** + * @author Yura Cangea + */ +package com.intellij.tools; + +import com.intellij.execution.filters.InvalidExpressionException; +import com.intellij.execution.filters.RegexpFilter; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.PopupHandler; + +import javax.swing.*; +import javax.swing.text.BadLocationException; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class FilterDialog extends DialogWrapper { + private final JTextField myRegexpField = new JTextField(); + private final JTextField myNameField = new JTextField(); + private final JTextField myDescriptionField = new JTextField(); + + private JPopupMenu myPopup; + + private FilterDialog(Component component) { + super(component, true); + init(); + setOKActionEnabled(true); + myRegexpField.setToolTipText("Press the right mouse button to see the list of available macros"); + } + + public static boolean editFilter(FilterInfo filterInfo, JComponent parentComponent, String title) throws InvalidExpressionException { + FilterDialog dialog = new FilterDialog(parentComponent); + dialog.setTitle(title); + dialog.myNameField.setText(filterInfo.getName()); + dialog.myDescriptionField.setText(filterInfo.getDescription()); + dialog.myRegexpField.setText(filterInfo.getRegExp()); + dialog.show(); + if (!dialog.isOK()) return false; + filterInfo.setName(dialog.myNameField.getText()); + filterInfo.setDescription(dialog.myDescriptionField.getText()); + filterInfo.setRegExp(dialog.myRegexpField.getText()); + return true; + } + + public JComponent getPreferredFocusedComponent() { + return myRegexpField; + } + + protected JComponent createCenterPanel() { + JPanel mainPanel = new JPanel(new BorderLayout()); + + JPanel panel = new JPanel(new GridBagLayout()); + + GridBagConstraints constr; + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 0; + constr.anchor = GridBagConstraints.WEST; + constr.weighty = 0; + constr.gridwidth = 1; + constr.insets = new Insets(5, 0, 0, 0); + panel.add(new JLabel("Name:"), constr); + + constr.gridx = 0; + constr.gridy = 1; + constr.weightx = 1; + constr.gridwidth = 3; + constr.fill = GridBagConstraints.HORIZONTAL; + panel.add(myNameField, constr); + + constr.gridx = 0; + constr.gridy = 2; + constr.weightx = 0; + panel.add(new JLabel("Description:"), constr); + + constr.gridx = 0; + constr.gridy = 3; + constr.gridwidth = 2; + constr.weightx = 1; + panel.add(myDescriptionField, constr); + + constr.gridy = 4; + constr.gridx = 0; + constr.gridwidth = 2; + constr.weightx = 0; + panel.add(new JLabel("Regular expression to match output:"), constr); + + constr.gridx = 0; + constr.gridy = 5; + constr.gridwidth = 3; + panel.add(myRegexpField, constr); + + makePopup(); + + panel.setPreferredSize(new Dimension(335, 150)); + + mainPanel.add(panel, BorderLayout.NORTH); + + return mainPanel; + } + + private void makePopup() { + myPopup = new JPopupMenu(); + String[] macrosName = RegexpFilter.getMacrosName(); + JMenuItem[] items = new JMenuItem[macrosName.length]; + for (int i = 0; i < macrosName.length; i++) { + items[i] = myPopup.add(macrosName[i]); + items[i].addActionListener(new MenuItemListener(macrosName[i])); + } + myRegexpField.addMouseListener(new PopupListener()); + } + + protected void doOKAction() { + String errorMessage = null; + if (noText(myNameField.getText())) { + errorMessage = "Filter name is not defined"; + } else if (noText(myRegexpField.getText())) { + errorMessage = "Regular expression must be defined"; + } + + if (errorMessage != null) { + Messages.showMessageDialog(getContentPane(), errorMessage, "Error", Messages.getErrorIcon()); + return; + } + + try { + checkRegexp(myRegexpField.getText()); + } catch (InvalidExpressionException e) { + Messages.showMessageDialog(getContentPane(), e.getMessage(), "Invalid Regular Expression", Messages.getErrorIcon()); + return; + } + super.doOKAction(); + } + + private void checkRegexp(String regexpText) { + RegexpFilter.validate(regexpText); + } + + private boolean noText(String text) { + return "".equals(text); + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.tools.FilterDialog"; + } + + private class MenuItemListener implements ActionListener { + private final String myMacrosName; + + private MenuItemListener(String macrosName) { + myMacrosName = macrosName; + } + + public void actionPerformed(ActionEvent e) { + int position = myRegexpField.getCaretPosition(); + try { + if (myRegexpField.getText().indexOf(myMacrosName) == -1) { + myRegexpField.getDocument().insertString(position, myMacrosName, null); + myRegexpField.setCaretPosition(position + myMacrosName.length()); + } + } catch (BadLocationException ex) { + } + myRegexpField.requestFocus(); + } + } + + private class PopupListener extends PopupHandler { + public void invokePopup(Component comp, int x, int y) { + myPopup.show(comp, x, y); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterInfo.java new file mode 100644 index 00000000000..1ed7fbf66ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/FilterInfo.java @@ -0,0 +1,117 @@ +package com.intellij.tools; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.JDOMExternalizable; +import org.jdom.Element; + +import java.util.Iterator; + +/** + * @author dyoma + */ +class FilterInfo implements JDOMExternalizable { + private static final String FILTER_NAME="NAME"; + private static final String FILTER_DESCRIPTION="DESCRIPTION"; + private static final String FILTER_REGEXP="REGEXP"; + + private String myName = "No name"; + private String myDescription; + private String myRegExp; + + public FilterInfo() {} + + public FilterInfo(String regExp, String name, String description) { + myRegExp = regExp; + myName = name; + myDescription = description; + } + + public String getDescription() { + return myDescription; + } + + public void setDescription(String description) { + myDescription = description; + } + + public String getName() { + return myName; + } + + public void setName(String name) { + myName = name; + } + + public String getRegExp() { + return myRegExp; + } + + public void setRegExp(String regExp) { + myRegExp = regExp; + } + + public int hashCode() { + return Comparing.hashcode(myName) + + Comparing.hashcode(myDescription) + + Comparing.hashcode(myRegExp); + } + + public boolean equals(Object object) { + if (!(object instanceof FilterInfo)) return false; + FilterInfo other = (FilterInfo)object; + return Comparing.equal(myName, other.myName) && + Comparing.equal(myDescription, other.myDescription) && + Comparing.equal(myRegExp, other.myRegExp); + } + + public FilterInfo createCopy() { + return new FilterInfo(myRegExp, myName, myDescription); + } + + public void readExternal(Element element) { + for (Iterator i2 = element.getChildren("option").iterator(); i2.hasNext(); ) { + Element optionElement = (Element)i2.next(); + String value = optionElement.getAttributeValue("value"); + String name = optionElement.getAttributeValue("name"); + + if (FILTER_NAME.equals(name)) { + if (value != null) { + myName = convertString(value); + } + } + if (FILTER_DESCRIPTION.equals(name)) { + myDescription = convertString(value); + } + if (FILTER_REGEXP.equals(name)) { + myRegExp = convertString(value); + } + } + } + + public void writeExternal(Element filterElement) { + Element option = new Element("option"); + filterElement.addContent(option); + option.setAttribute("name", FILTER_NAME); + if (myName != null ) { + option.setAttribute("value", myName); + } + + option = new Element("option"); + filterElement.addContent(option); + option.setAttribute("name", FILTER_DESCRIPTION); + if (myDescription != null ) { + option.setAttribute("value", myDescription); + } + + option = new Element("option"); + filterElement.addContent(option); + option.setAttribute("name", FILTER_REGEXP); + if (myRegExp != null ) { + option.setAttribute("value", myRegExp); + } + } + + public static String convertString(String s) { + return ToolSettings.convertString(s); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/OutputFiltersDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/OutputFiltersDialog.java new file mode 100644 index 00000000000..4e29d79240f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/OutputFiltersDialog.java @@ -0,0 +1,210 @@ +/** + * @author Yura Cangea + */ +package com.intellij.tools; + +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.*; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class OutputFiltersDialog extends DialogWrapper { + private final DefaultListModel myFiltersModel = new DefaultListModel(); + private final JList myFiltersList = new JList(myFiltersModel); + private final JButton myAddButton = new JButton("Add..."); + private final JButton myEditButton = new JButton("Edit..."); + private final JButton myRemoveButton = new JButton("Remove"); + private final JButton myMoveUpButton = new JButton("Move Up"); + private final JButton myMoveDownButton = new JButton("Move Down"); + private final CommandButtonGroup myButtonGroup = new CommandButtonGroup(BoxLayout.Y_AXIS); + private boolean myModified = false; + private FilterInfo[] myFilters; + + public OutputFiltersDialog(Component parent, FilterInfo[] filters) { + super(parent, true); + myFilters = filters; + + setTitle("Output Filters"); + init(); + initGui(); + + myAddButton.setMnemonic('A'); + myEditButton.setMnemonic('d'); + myRemoveButton.setMnemonic('R'); + myMoveUpButton.setMnemonic('U'); + myMoveDownButton.setMnemonic('o'); + } + + protected Action[] createActions() { + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("preferences.externalToolsFilters"); + } + + private void initGui() { + myFiltersList.setCellRenderer(new ColoredListCellRenderer() { + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + FilterInfo info = (FilterInfo)value; + append(info.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + }); + + myButtonGroup.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + + myButtonGroup.addButton(myAddButton); + myButtonGroup.addButton(myEditButton); + myButtonGroup.addButton(myRemoveButton); + myButtonGroup.addButton(myMoveUpButton); + myButtonGroup.addButton(myMoveDownButton); + + myEditButton.setEnabled(false); + myRemoveButton.setEnabled(false); + myMoveUpButton.setEnabled(false); + myMoveDownButton.setEnabled(false); + + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FilterInfo filterInfo = new FilterInfo(); + filterInfo.setName(suggestFilterName()); + boolean wasCreated = FilterDialog.editFilter(filterInfo, myAddButton, "Add Filter"); + if (wasCreated) { + myFiltersModel.addElement(filterInfo); + setModified(true); + enableButtons(); + } + myFiltersList.requestFocus(); + } + }); + + myEditButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int index = myFiltersList.getSelectedIndex(); + FilterInfo filterInfo = (FilterInfo)myFiltersModel.getElementAt(index); + boolean wasEdited = FilterDialog.editFilter(filterInfo, myEditButton, "Edit filter"); + if (wasEdited) { + setModified(true); + enableButtons(); + } + myFiltersList.requestFocus(); + } + }); + + + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myFiltersList.getSelectedIndex() >= 0) { + myFiltersModel.removeElementAt(myFiltersList.getSelectedIndex()); + setModified(true); + } + enableButtons(); + myFiltersList.requestFocus(); + } + }); + myMoveUpButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int movedCount = ListUtil.moveSelectedItemsUp(myFiltersList); + if (movedCount > 0) { + setModified(true); + } + myFiltersList.requestFocus(); + } + }); + myMoveDownButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int movedCount = ListUtil.moveSelectedItemsDown(myFiltersList); + if (movedCount > 0) { + setModified(true); + } + myFiltersList.requestFocus(); + } + }); + + myFiltersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + myFiltersList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + enableButtons(); + } + }); + + ListScrollingUtil.ensureSelectionExists(myFiltersList); + } + + private String suggestFilterName(){ + String prefix = "Filter "; + + int number = 1; + for (int i=0; i < myFiltersModel.getSize(); i++) { + FilterInfo wrapper = (FilterInfo)myFiltersModel.getElementAt(i); + String name = wrapper.getName(); + if (name.startsWith(prefix)) { + try { + int n = Integer.valueOf(name.substring(prefix.length()).trim()).intValue(); + number = Math.max(number, n + 1); + } + catch (NumberFormatException e) { + } + } + } + + return prefix + number; + } + + protected void doOKAction() { + if (myModified) { + myFilters = new FilterInfo[myFiltersModel.getSize()]; + for (int i = 0; i < myFiltersModel.getSize(); i++) { + myFilters[i] = (FilterInfo)myFiltersModel.get(i); + } + } + super.doOKAction(); + } + + protected JComponent createCenterPanel() { + for (int i = 0; i < myFilters.length; i++) { + myFiltersModel.addElement(myFilters[i].createCopy()); + } + + JPanel panel = new JPanel(new BorderLayout()); + + panel.add(new JScrollPane(myFiltersList), BorderLayout.CENTER); + panel.add(myButtonGroup, BorderLayout.EAST); + + panel.setPreferredSize(new Dimension(400, 200)); + + return panel; + } + + private void enableButtons() { + int size = myFiltersModel.getSize(); + int index = myFiltersList.getSelectedIndex(); + myEditButton.setEnabled(size != 0 && index != -1); + myRemoveButton.setEnabled(size != 0 & index != -1); + myMoveUpButton.setEnabled(ListUtil.canMoveSelectedItemsUp(myFiltersList)); + myMoveDownButton.setEnabled(ListUtil.canMoveSelectedItemsDown(myFiltersList)); + } + + public JComponent getPreferredFocusedComponent() { + return myFiltersList; + } + + private void setModified(boolean modified) { + myModified = modified; + } + + public FilterInfo[] getData() { + return myFilters; + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.tools.OutputFiltersDialog"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/SimpleActionGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/SimpleActionGroup.java new file mode 100644 index 00000000000..7ac2acf8a3a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/SimpleActionGroup.java @@ -0,0 +1,32 @@ +package com.intellij.tools; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +import java.util.ArrayList; + +class SimpleActionGroup extends ActionGroup { + private final ArrayList myChildren = new ArrayList(); + + public SimpleActionGroup() { + super(null, false); + } + + public void add(AnAction action) { + myChildren.add(action); + } + + public AnAction[] getChildren(AnActionEvent e) { + return (AnAction[])myChildren.toArray(new AnAction[myChildren.size()]); + } + + public int getChildrenCount() { + return myChildren.size(); + } + + public void removeAll() { + myChildren.clear(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/Tool.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/Tool.java new file mode 100644 index 00000000000..97794435304 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/Tool.java @@ -0,0 +1,367 @@ +package com.intellij.tools; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.ExecutionUtil; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.RegexpFilter; +import com.intellij.execution.filters.TextConsoleBuidlerFactory; +import com.intellij.execution.filters.TextConsoleBuilder; +import com.intellij.execution.process.*; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.ide.macro.Macro; +import com.intellij.ide.macro.MacroManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.WindowManager; + +import java.util.ArrayList; + +public class Tool implements RunProfile { + public final static String ACTION_ID_PREFIX = "Tool_"; + + private String myName; + private String myDescription; + private String myGroup; + private boolean myShownInMainMenu; + private boolean myShownInEditor; + private boolean myShownInProjectViews; + private boolean myShownInSearchResultsPopup; + private boolean myEnabled; + + private boolean myUseConsole; + private boolean mySynchronizeAfterExecution; + + private String myWorkingDirectory; + private String myProgram; + private String myParameters; + + private ArrayList myOutputFilters = new ArrayList(); + + public Tool() { + } + + public RunProfileState getState(DataContext context, + RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + final Project project = (Project)context.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + final GeneralCommandLine commandLine = createCommandLine(context); + if (commandLine == null) { + return null; // can return null if creation of cmd line has been cancelled + } + CommandLineState commandLineState = new CommandLineState(runnerSettings, configurationSettings) { + protected GeneralCommandLine createCommandLine() { + return commandLine; + } + + public ExecutionResult execute() throws ExecutionException { + final ExecutionResult result = super.execute(); + final ProcessHandler processHandler = result.getProcessHandler(); + if (processHandler != null) { + processHandler.addProcessListener(new MyProcessAdapter(project)); + } + return result; + } + }; + TextConsoleBuilder builder = TextConsoleBuidlerFactory.getInstance().createBuilder(project); + for (int i = 0; i < myOutputFilters.size(); i++) { + FilterInfo filter = myOutputFilters.get(i); + builder.addFilter(new RegexpFilter(project, filter.getRegExp())); + } + + commandLineState.setConsoleBuilder(builder); + return commandLineState; + } + + public String getName() { + return myName; + } + + public void checkConfiguration() throws RuntimeConfigurationException { + } + + public Module[] getModules() { + return null; + } + + public String getDescription() { + return myDescription; + } + + public String getGroup() { + return myGroup; + } + + public boolean isShownInMainMenu() { + return myShownInMainMenu; + } + + public boolean isShownInEditor() { + return myShownInEditor; + } + + public boolean isShownInProjectViews() { + return myShownInProjectViews; + } + + public boolean isShownInSearchResultsPopup() { + return myShownInSearchResultsPopup; + } + + public boolean isEnabled() { + return myEnabled; + } + + public void setEnabled(boolean enabled) { + myEnabled = enabled; + } + + public boolean isUseConsole() { + return myUseConsole; + } + + public boolean synchronizeAfterExecution() { + return mySynchronizeAfterExecution; + } + + void setName(String name) { + myName = name; + } + + void setDescription(String description) { + myDescription = description; + } + + void setGroup(String group) { + myGroup = group; + } + + void setShownInMainMenu(boolean shownInMainMenu) { + myShownInMainMenu = shownInMainMenu; + } + + void setShownInEditor(boolean shownInEditor) { + myShownInEditor = shownInEditor; + } + + void setShownInProjectViews(boolean shownInProjectViews) { + myShownInProjectViews = shownInProjectViews; + } + + public void setShownInSearchResultsPopup(boolean shownInSearchResultsPopup) { + myShownInSearchResultsPopup = shownInSearchResultsPopup; + } + + void setUseConsole(boolean useConsole) { + myUseConsole = useConsole; + } + + public void setFilesSynchronizedAfterRun(boolean synchronizeAfterRun) { + mySynchronizeAfterExecution = synchronizeAfterRun; + } + + public String getWorkingDirectory() { + return myWorkingDirectory; + } + + public void setWorkingDirectory(String workingDirectory) { + myWorkingDirectory = workingDirectory; + } + + public String getProgram() { + return myProgram; + } + + public void setProgram(String program) { + myProgram = program; + } + + public String getParameters() { + return myParameters; + } + + public void setParameters(String parameters) { + myParameters = parameters; + } + + public void addOutputFilter(FilterInfo filter) { + myOutputFilters.add(filter); + } + + public void setOutputFilters(FilterInfo[] filters) { + myOutputFilters = new ArrayList(); + for (int i = 0; i < filters.length; i++) { + myOutputFilters.add(filters[i]); + } + } + + public FilterInfo[] getOutputFilters() { + return myOutputFilters.toArray(new FilterInfo[myOutputFilters.size()]); + } + + public void copyFrom(Tool source) { + myName = source.myName; + myDescription = source.myDescription; + myGroup = source.myGroup; + myShownInMainMenu = source.myShownInMainMenu; + myShownInEditor = source.myShownInEditor; + myShownInProjectViews = source.myShownInProjectViews; + myShownInSearchResultsPopup = source.myShownInSearchResultsPopup; + myEnabled = source.myEnabled; + myUseConsole = source.myUseConsole; + mySynchronizeAfterExecution = source.mySynchronizeAfterExecution; + myWorkingDirectory = source.myWorkingDirectory; + myProgram = source.myProgram; + myParameters = source.myParameters; + myOutputFilters = (ArrayList)source.myOutputFilters.clone(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Tool)) return false; + Tool secondTool = (Tool)obj; + + Tool source = secondTool; + + return + Comparing.equal(myName, source.myName) && + Comparing.equal(myDescription, source.myDescription) && + Comparing.equal(myGroup, source.myGroup) && + myShownInMainMenu == source.myShownInMainMenu && + myShownInEditor == source.myShownInEditor && + myShownInProjectViews == source.myShownInProjectViews && + myShownInSearchResultsPopup == source.myShownInSearchResultsPopup && + myEnabled == source.myEnabled && + myUseConsole == source.myUseConsole && + mySynchronizeAfterExecution == source.mySynchronizeAfterExecution && + Comparing.equal(myWorkingDirectory, source.myWorkingDirectory) && + Comparing.equal(myProgram, source.myProgram) && + Comparing.equal(myParameters, source.myParameters) && + Comparing.equal(myOutputFilters, source.myOutputFilters); + } + + public String getActionId() { + StringBuffer name = new StringBuffer(ACTION_ID_PREFIX); + if (myGroup != null) { + name.append(myGroup); + name.append('_'); + } + if (myName != null) { + name.append(myName); + } + return name.toString(); + } + + public void execute(DataContext dataContext) { + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return; + } + FileDocumentManager.getInstance().saveAllDocuments(); + try { + if (isUseConsole()) { + RunStrategy.getInstance().executeDefault(this, dataContext); + } + else { + GeneralCommandLine commandLine = createCommandLine(dataContext); + if (commandLine == null) { + return; + } + OSProcessHandler handler = new DefaultJavaProcessHandler(commandLine); + handler.addProcessListener(new MyProcessAdapter(project)); + handler.startNotify(); + /* + ContentManager contentManager = RunManager.getInstance(project).getContentManager(); + ExecutionView.Descriptor descriptor = new ExecutionView.Descriptor(project, getName(), contentManager, + ToolWindowId.RUN); + descriptor.canBreak = false; + Content contentToReuse = RunManager.getInstance(project).getContentToReuse(); + executionView = ExecutionView.openExecutionView(descriptor, contentToReuse, true, DefaultConsoleViewFactory.getInstance()); + executionView.addAction(new EditToolAction(executionView), 1); + WindowManager.getInstance().getStatusBar(project).setInfo("External tool '" + getName() + "' started"); + if (executionView.enterCriticalSection()) { + OSProcessHandler handler = commandLine.createProcessHandler(); + executionView.getConsoleView().print(handler.getCommandLine() + "\n", ConsoleViewContentType.SYSTEM_OUTPUT); + executionView.setProcessHandler(handler); + handler.addProcessListener(new MyProcessAdapter(executionView, project)); + // Add filters; + for (int i = 0; i < myOutputFilters.size(); i++) { + RegexpFilter filter = myOutputFilters.get(i); + if (filter != null) { + executionView.getConsoleView().addMessageFilter(filter); + } + } + handler.startNotify(); + } + */ + } + } + catch (ExecutionException ex) { + ExecutionUtil.showExecutionErrorMessage(ex, "Could Not Start Process", project); + } + } + + private GeneralCommandLine createCommandLine(DataContext dataContext) { + if (getWorkingDirectory() != null && getWorkingDirectory().trim().length() == 0) { + setWorkingDirectory(null); + } + + GeneralCommandLine commandLine = new GeneralCommandLine(); + try { + String paramString = MacroManager.getInstance().expandMacrosInString(getParameters(), true, dataContext); + String workingDir = MacroManager.getInstance().expandMacrosInString(getWorkingDirectory(), true, dataContext); + String exePath = MacroManager.getInstance().expandMacrosInString(getProgram(), true, dataContext); + + commandLine.getParametersList().addParametersString( + MacroManager.getInstance().expandMacrosInString(paramString, false, dataContext)); + commandLine.setWorkDirectory(MacroManager.getInstance().expandMacrosInString(workingDir, false, dataContext)); + exePath = MacroManager.getInstance().expandMacrosInString(exePath, false, dataContext); + if (exePath == null) return null; + commandLine.setExePath(exePath); + } + catch (Macro.ExecutionCancelledException e) { + return null; + } + return commandLine; + } + + private class MyProcessAdapter extends ProcessAdapter { + private final Project myProject; + + public MyProcessAdapter(Project project) { + myProject = project; + } + + public void processTerminated(ProcessEvent event) { + final String message = "External tool '" + getName() + "' completed with exit code " + event.getExitCode(); + + if (synchronizeAfterExecution()) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + VirtualFileManager.getInstance().refresh(true, new Runnable() { + public void run() { + if (ProjectManagerEx.getInstanceEx().isProjectOpened(myProject)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo(message); + } + } + }); + } + }); + } + if (ProjectManagerEx.getInstanceEx().isProjectOpened(myProject)) { + WindowManager.getInstance().getStatusBar(myProject).setInfo(message); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolAction.java new file mode 100644 index 00000000000..91629b1b216 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolAction.java @@ -0,0 +1,30 @@ +package com.intellij.tools; + +import com.intellij.ide.macro.MacroManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +/** + * @author Eugene Belyaev + */ +public class ToolAction extends AnAction { + private final String myActionId; + + public ToolAction(Tool tool) { + myActionId = tool.getActionId(); + getTemplatePresentation().setText(tool.getName(), false); + getTemplatePresentation().setDescription(tool.getDescription()); + } + + public void actionPerformed(AnActionEvent e) { + MacroManager.getInstance().cacheMacrosPreview(e.getDataContext()); + Tool[] tools = ToolManager.getInstance().getTools(); + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + if (myActionId.equals(tool.getActionId())) { + tool.execute(e.getDataContext()); + break; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolConfigurable.java new file mode 100644 index 00000000000..c04338b671f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolConfigurable.java @@ -0,0 +1,63 @@ +package com.intellij.tools; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.io.IOException; + +public class ToolConfigurable implements Configurable, ApplicationComponent { + private static final Icon ourIcon = IconLoader.getIcon("/general/externalTools.png"); + + private ToolsPanel myPanel; + + public String getComponentName() { + return "ExternalToolsConfigurable"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public String getDisplayName() { + return "External Tools"; + } + + public JComponent createComponent() { + myPanel = new ToolsPanel(); + return myPanel; + } + + public Icon getIcon() { + return ourIcon; + } + + public void apply() throws ConfigurationException { + try { + myPanel.apply(); + } + catch (IOException e) { + throw new ConfigurationException(e.getMessage()); + } + } + + public boolean isModified() { + return myPanel.isModified(); + } + + public void reset() { + myPanel.reset(); + } + + public void disposeUIResources() { + myPanel = null; + } + + public String getHelpTopic() { + return "preferences.externalTools"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolEditorDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolEditorDialog.java new file mode 100644 index 00000000000..bc483924b0a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolEditorDialog.java @@ -0,0 +1,480 @@ +package com.intellij.tools; + +import com.intellij.ide.DataManager; +import com.intellij.ide.macro.MacroManager; +import com.intellij.ide.macro.MacrosDialog; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +public class ToolEditorDialog extends DialogWrapper { + private final JTextField myNameField = new JTextField(); + private final JTextField myDescriptionField = new JTextField(); + private final ComboBox myGroupCombo = new ComboBox(-1); + private final JCheckBox myShowInMainMenuCheckbox = new JCheckBox("Main menu"); + private final JCheckBox myShowInEditorCheckbox = new JCheckBox("Editor menu"); + private final JCheckBox myShowInProjectTreeCheckbox = new JCheckBox("Project views"); + private final JCheckBox myShowInSearchResultsPopupCheckbox = new JCheckBox("Search results"); + private final JCheckBox myUseConsoleCheckbox = new JCheckBox("Open console"); + private final JCheckBox mySynchronizedAfterRunCheckbox = new JCheckBox("Synchronize files after execution"); + private boolean myEnabled; + + // command fields + private final JTextField myTfCommandWorkingDirectory = new JTextField(); + private final JTextField myTfCommand = new JTextField(); + private final JTextField myParametersField = new JTextField(); + private JButton myInsertWorkingDirectoryMacroButton; + private JButton myInsertCommandMacroButton; + private JButton myInsertParametersMacroButton; + + private final JButton myOutputFiltersButton; + // panels + private final JPanel mySimpleProgramPanel = createCommandPane(); + private FilterInfo[] myOutputFilters; + private final Project myProject; + + protected JComponent createCenterPanel() { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints constr; + + // name and group + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 0; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 0, 0, 0); + panel.add(new JLabel("Name:"), constr); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 0; + constr.weightx = 1; + constr.insets = new Insets(5, 10, 0, 10); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + panel.add(myNameField, constr); + + constr = new GridBagConstraints(); + constr.gridx = 2; + constr.gridy = 0; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 10, 0, 0); + panel.add(new JLabel("Group:"), constr); + + constr = new GridBagConstraints(); + constr.gridx = 3; + constr.gridy = 0; + constr.weightx = 0.7; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + panel.add(myGroupCombo, constr); + myGroupCombo.setEditable(true); + myGroupCombo.setFont(myNameField.getFont()); + Dimension comboSize = myNameField.getPreferredSize(); + myGroupCombo.setMinimumSize(comboSize); + myGroupCombo.setPreferredSize(comboSize); + + // description + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 1; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 0, 0, 0); + panel.add(new JLabel("Description:"), constr); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 1; + constr.weightx = 1; + constr.gridwidth = 3; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + panel.add(myDescriptionField, constr); + + // check boxes + JPanel panel0 = new JPanel(new GridBagLayout()); + constr = new GridBagConstraints(); + constr.gridheight = 2; + panel0.add(getShowInPanel(), constr); + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.weightx = 1.0; + constr.anchor = GridBagConstraints.NORTHEAST; + constr.fill = GridBagConstraints.HORIZONTAL; + constr.insets = new Insets(5, 10, 0, 0); + panel0.add(myUseConsoleCheckbox, constr); + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 1; + constr.weightx = 1.0; + constr.anchor = GridBagConstraints.NORTHEAST; + constr.fill = GridBagConstraints.HORIZONTAL; + constr.insets = new Insets(0, 10, 0, 0); + panel0.add(mySynchronizedAfterRunCheckbox, constr); + + // Placed temporarily here, might be moved elsewhere in the future. + panel0.add(myOutputFiltersButton); + + constr = new GridBagConstraints(); + constr.gridy = 4; + constr.gridwidth = 4; + constr.fill = GridBagConstraints.HORIZONTAL; + constr.weightx = 1.0; + constr.insets = new Insets(5, 0, 0, 0); + panel.add(panel0, constr); + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 6; + constr.gridwidth = 2; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(10, 0, 0, 0); + panel.add(Box.createVerticalStrut(10), constr); + + // custom panels (put into same place) + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 7/*8*/; + constr.gridwidth = 4; + constr.fill = GridBagConstraints.BOTH; + constr.weightx = 1.0; + constr.weighty = 1.0; + constr.anchor = GridBagConstraints.NORTH; + panel.add(mySimpleProgramPanel, constr); + + return panel; + } + + protected Action[] createActions() { + return new Action[]{getOKAction(),getCancelAction(),getHelpAction()}; + } + + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("preferences.externalToolsEdit"); + } + + public ToolEditorDialog(JComponent parent) { + super(parent, true); + + myOutputFiltersButton = new JButton("Output Filters..."); + myOutputFiltersButton.setMnemonic('F'); + + DataContext dataContext = DataManager.getInstance().getDataContext(parent); + myProject = (Project)dataContext.getData(DataConstants.PROJECT); + MacroManager.getInstance().cacheMacrosPreview(dataContext); + setTitle("Edit Tool"); + init(); + addListeners(); + } + + private JPanel createCommandPane() { + JPanel pane = new JPanel(new GridBagLayout()); + pane.setBorder( + BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(), + BorderFactory.createEmptyBorder(5, 5, 5, 5) + ) + ); + GridBagConstraints constr; + + // program + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 0; + constr.insets = new Insets(5, 0, 0, 10); + constr.anchor = GridBagConstraints.WEST; + pane.add(new JLabel("Program:"), constr); + + FixedSizeButton browseCommandButton = new FixedSizeButton(myTfCommand); + browseCommandButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myProject, descriptor); + if (files.length != 0) { + VirtualFile file = files[0]; + myTfCommand.setText(file.getPresentableUrl()); + String workingDirectory = myTfCommandWorkingDirectory.getText(); + if (workingDirectory == null || workingDirectory.length() == 0){ + VirtualFile parent = file.getParent(); + if (parent != null && parent.isDirectory()) { + myTfCommandWorkingDirectory.setText(parent.getPresentableUrl()); + } + } + } + } + } + ); + JPanel _pane0 = new JPanel(new BorderLayout()); + _pane0.add(myTfCommand, BorderLayout.CENTER); + _pane0.add(browseCommandButton, BorderLayout.EAST); + TextFieldWithBrowseButton.MyDoClickAction.addTo(browseCommandButton, myTfCommand); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 0; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + constr.weightx = 1.0; + pane.add(_pane0, constr); + + constr = new GridBagConstraints(); + constr.gridx = 2; + constr.gridy = 0; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + myInsertCommandMacroButton = new JButton("Insert macro..."); + myInsertCommandMacroButton.setMnemonic('m'); + pane.add(myInsertCommandMacroButton, constr); + + // parameters + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 1; + constr.insets = new Insets(5, 0, 0, 0); + constr.anchor = GridBagConstraints.WEST; + pane.add(new JLabel("Parameters:"), constr); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 1; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + constr.weightx = 1.0; + pane.add(myParametersField, constr); + + constr = new GridBagConstraints(); + constr.gridx = 2; + constr.gridy = 1; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + myInsertParametersMacroButton = new JButton("Insert macro..."); + myInsertParametersMacroButton.setMnemonic('a'); + pane.add(myInsertParametersMacroButton, constr); + + // working directory + + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 2; + constr.insets = new Insets(5, 0, 5, 10); + constr.anchor = GridBagConstraints.WEST; + pane.add(new JLabel("Working directory:"), constr); + + FixedSizeButton browseDirectoryButton = new FixedSizeButton(myTfCommandWorkingDirectory); + TextFieldWithBrowseButton.MyDoClickAction.addTo(browseDirectoryButton, myTfCommandWorkingDirectory); + browseDirectoryButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myProject, descriptor); + if (files.length != 0) { + myTfCommandWorkingDirectory.setText(files[0].getPresentableUrl()); + } + } + } + ); + JPanel _pane1 = new JPanel(new BorderLayout()); + _pane1.add(myTfCommandWorkingDirectory, BorderLayout.CENTER); + _pane1.add(browseDirectoryButton, BorderLayout.EAST); + + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 2; + constr.gridwidth = 1; + constr.insets = new Insets(5, 10, 5, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + constr.weightx = 1.0; + pane.add(_pane1, constr); + + constr = new GridBagConstraints(); + constr.gridx = 2; + constr.gridy = 2; + constr.insets = new Insets(5, 10, 0, 0); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.anchor = GridBagConstraints.WEST; + myInsertWorkingDirectoryMacroButton = new JButton("Insert macro..."); + myInsertWorkingDirectoryMacroButton.setMnemonic('c'); + pane.add(myInsertWorkingDirectoryMacroButton, constr); + + // for normal resizing + constr = new GridBagConstraints(); + constr.gridy = 3; + constr.fill = GridBagConstraints.VERTICAL; + constr.weighty = 1.0; + pane.add(new JLabel(), constr); + + pane.setPreferredSize(new Dimension(600, 100)); + + return pane; + } + + private class InsertMacroActionListener implements ActionListener { + private final JTextField myTextField; + + public InsertMacroActionListener(JTextField textField) { + myTextField = textField; + } + + public void actionPerformed(ActionEvent e) { + MacrosDialog dialog = new MacrosDialog(myProject); + dialog.show(); + if (dialog.isOK() && dialog.getSelectedMacro() != null) { + String macro = dialog.getSelectedMacro().getName(); + int position = myTextField.getCaretPosition(); + try { + myTextField.getDocument().insertString(position, "$" + macro + "$", null); + myTextField.setCaretPosition(position + macro.length() + 2); + } + catch(BadLocationException ex){ + } + myTextField.requestFocus(); + } + } + } + + private void addListeners() { + myOutputFiltersButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + OutputFiltersDialog dialog = new OutputFiltersDialog(myOutputFiltersButton, getData().getOutputFilters()); + dialog.show(); + if (dialog.isOK()) { + myOutputFilters = dialog.getData(); + } + } + }); + myInsertCommandMacroButton.addActionListener(new InsertMacroActionListener(myTfCommand)); + myInsertParametersMacroButton.addActionListener(new InsertMacroActionListener(myParametersField)); + myInsertWorkingDirectoryMacroButton.addActionListener(new InsertMacroActionListener(myTfCommandWorkingDirectory)); + + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + public void textChanged(DocumentEvent event) { + handleOKButton(); + } + }); + } + + private void handleOKButton() { + setOKActionEnabled(myNameField.getText().trim().length() > 0); + } + + public Tool getData() { + Tool tool = new Tool(); + + tool.setName(convertString(myNameField.getText())); + tool.setDescription(convertString(myDescriptionField.getText())); + tool.setGroup(myGroupCombo.getSelectedItem() != null ? convertString(myGroupCombo.getSelectedItem().toString()) : null); + tool.setShownInMainMenu(myShowInMainMenuCheckbox.isSelected()); + tool.setShownInEditor(myShowInEditorCheckbox.isSelected()); + tool.setShownInProjectViews(myShowInProjectTreeCheckbox.isSelected()); + tool.setShownInSearchResultsPopup(myShowInSearchResultsPopupCheckbox.isSelected()); + tool.setUseConsole(myUseConsoleCheckbox.isSelected()); + tool.setFilesSynchronizedAfterRun(mySynchronizedAfterRunCheckbox.isSelected()); + tool.setEnabled(myEnabled); + + tool.setWorkingDirectory(toSystemIndependentFormat(myTfCommandWorkingDirectory.getText())); + tool.setProgram(convertString(myTfCommand.getText())); + tool.setParameters(convertString(myParametersField.getText())); + + tool.setOutputFilters(myOutputFilters); + + return tool; + } + + protected String getDimensionServiceKey(){ + return "#com.intellij.tools.ToolEditorDialog"; + } + + /** + * Initialize controls + */ + void setData(Tool tool, String[] existingGroups) { + myNameField.setText(tool.getName()); + myDescriptionField.setText(tool.getDescription()); + if (myGroupCombo.getItemCount() > 0){ + myGroupCombo.removeAllItems(); + } + for (int i = 0; i < existingGroups.length; i++) { + if (existingGroups[i] != null) { + myGroupCombo.addItem(existingGroups[i]); + } + } + myGroupCombo.setSelectedItem(tool.getGroup()); + myShowInMainMenuCheckbox.setSelected(tool.isShownInMainMenu()); + myShowInEditorCheckbox.setSelected(tool.isShownInEditor()); + myShowInProjectTreeCheckbox.setSelected(tool.isShownInProjectViews()); + myShowInSearchResultsPopupCheckbox.setSelected(tool.isShownInSearchResultsPopup()); + myUseConsoleCheckbox.setSelected(tool.isUseConsole()); + mySynchronizedAfterRunCheckbox.setSelected(tool.synchronizeAfterExecution()); + myEnabled = tool.isEnabled(); + myTfCommandWorkingDirectory.setText(toCurrentSystemFormat(tool.getWorkingDirectory())); + myTfCommand.setText(tool.getProgram()); + myParametersField.setText(tool.getParameters()); + myOutputFilters = tool.getOutputFilters(); + mySimpleProgramPanel.setVisible(true); + handleOKButton(); + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + private JPanel getShowInPanel() { + JPanel panel = new JPanel(new GridLayout(2, 2, 10, 3)); + panel.setBorder(IdeBorderFactory.createTitledBorder("Menu")); + panel.add(myShowInMainMenuCheckbox); + panel.add(myShowInEditorCheckbox); + panel.add(myShowInProjectTreeCheckbox); + panel.add(myShowInSearchResultsPopupCheckbox); + return panel; + } + + private String convertString(String s) { + if (s != null && s.trim().length() == 0) return null; + return s; + } + + private String toSystemIndependentFormat(String s) { + if (s == null) return null; + s = s.trim(); + if (s.length() == 0) return null; + return s.replace(File.separatorChar, '/'); + } + + private String toCurrentSystemFormat(String s) { + if (s == null) return null; + s = s.trim(); + if (s.length() == 0) return null; + return s.replace('/', File.separatorChar); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolManager.java new file mode 100644 index 00000000000..d227c40736d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolManager.java @@ -0,0 +1,131 @@ + +package com.intellij.tools; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.util.Comparing; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +public class ToolManager implements ExportableApplicationComponent { + private final ArrayList myTools = new ArrayList(); + private ActionManagerEx myActionManager; + + public static ToolManager getInstance() { + return ApplicationManager.getApplication().getComponent(ToolManager.class); + } + + public ToolManager(ActionManagerEx actionManagerEx) { + myActionManager = actionManagerEx; + + Tool[] tools = new ToolSettings().loadTools(); + setTools(tools); + } + + public File[] getExportFiles() { + return new File[]{ToolSettings.getToolDirectory()}; + } + + public String getPresentableName() { + return "Tools"; + } + + public void disposeComponent() { + } + + public void initComponent() { } + + public Tool[] getTools() { + return myTools.toArray(new Tool[myTools.size()]); + } + + public Tool[] getTools(String group) { + ArrayList list = new ArrayList(); + for (Iterator iterator = myTools.iterator(); iterator.hasNext();) { + Tool tool = iterator.next(); + if (Comparing.equal(group, tool.getGroup())) { + list.add(tool); + } + } + return list.toArray(new Tool[list.size()]); + } + + /** + * Get all not empty group names of tools in array + */ + String[] getGroups(Tool[] tools) { + ArrayList list = new ArrayList(); + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + if (!list.contains(tool.getGroup())) { + list.add(tool.getGroup()); + } + } + return list.toArray(new String[list.size()]); + } + + public String getGroupByActionId(String actionId) { + for (Iterator iterator = myTools.iterator(); iterator.hasNext();) { + Tool tool = iterator.next(); + if (Comparing.equal(actionId, tool.getActionId())) { + return tool.getGroup(); + } + } + return null; + } + + public String[] getGroups() { + return getGroups(myTools.toArray(new Tool[myTools.size()])); + } + + public void setTools(Tool[] tools) { + myTools.clear(); + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + myTools.add(tool); + } + registerActions(); + } + + void writeTools() throws IOException{ + new ToolSettings().saveTools(getTools()); + } + + void registerActions() { + unregisterActions(); + + // register + HashSet registeredIds = new HashSet(); // to prevent exception if 2 or more targets have the same name + + Tool[] tools = getTools(); + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + String actionId = tool.getActionId(); + + if (!registeredIds.contains(actionId)) { + registeredIds.add(actionId); + myActionManager.registerAction(actionId, new ToolAction(tool)); + } + } + } + + private void unregisterActions() { + // unregister Tool actions + String[] oldIds = myActionManager.getActionIds(Tool.ACTION_ID_PREFIX); + for (int i = 0; i < oldIds.length; i++) { + String oldId = oldIds[i]; + myActionManager.unregisterAction(oldId); + } + } + + public String getComponentName() { + return "ToolManager"; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolsPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolsPanel.java new file mode 100644 index 00000000000..a6abc85ab03 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/tools/ToolsPanel.java @@ -0,0 +1,444 @@ +package com.intellij.tools; + +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.util.ui.ItemRemovable; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.awt.event.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +class ToolsPanel extends JPanel { + private final MyModel myModel; + private final JTable myTable; + private final JButton myAddButton = new JButton("Add..."); + private final JButton myCopyButton = new JButton("Copy..."); + private final JButton myEditButton = new JButton("Edit..."); + private final JButton myMoveUpButton = new JButton("Move Up"); + private final JButton myMoveDownButton = new JButton("Move Down"); + private final JButton myRemoveButton = new JButton("Remove"); + + ToolsPanel() { + myModel = new MyModel(); + myTable = new Table(myModel); + + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + myTable.setColumnSelectionAllowed(false); + myTable.setPreferredScrollableViewportSize(new Dimension(400, 300)); + JScrollPane tableScrollPane = ScrollPaneFactory.createScrollPane(myTable); + + int width = new JCheckBox().getPreferredSize().width; + TableColumnModel columnModel = myTable.getColumnModel(); + TableColumn column = columnModel.getColumn(0); + column.setPreferredWidth(width); + column.setMaxWidth(width); + + DefaultTableCellRenderer renderer = new MyTableCellRenderer(); + columnModel.getColumn(1).setCellRenderer(renderer); + columnModel.getColumn(2).setCellRenderer(renderer); + columnModel.getColumn(3).setCellRenderer(renderer); + + setLayout(new GridBagLayout()); + GridBagConstraints constr; + + // tools label + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 0; + constr.anchor = GridBagConstraints.WEST; + constr.insets = new Insets(5, 5, 0, 0); + add(new JLabel("Tools:"), constr); + + // tools list + constr = new GridBagConstraints(); + constr.gridx = 0; + constr.gridy = 1; + constr.weightx = 1; + constr.weighty = 1; + constr.insets = new Insets(0, 5, 0, 0); + constr.fill = GridBagConstraints.BOTH; + constr.anchor = GridBagConstraints.WEST; + add(tableScrollPane, constr); + myTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + // right side buttons + constr = new GridBagConstraints(); + constr.gridx = 1; + constr.gridy = 1; + constr.anchor = GridBagConstraints.NORTH; + add(createRightButtonPane(), constr); + +// // for align +// constr = new GridBagConstraints(); +// constr.gridx = 2; +// constr.weightx = 1; +// constr.fill = GridBagConstraints.HORIZONTAL; +// add(new JPanel(), constr); + + addListeners(); + + } + + // add/edit/remove buttons + private JPanel createRightButtonPane() { + JPanel pane = new JPanel(new GridBagLayout()); + GridBagConstraints constr = new GridBagConstraints(); + constr.insets = new Insets(0, 5, 5, 5); + constr.fill = GridBagConstraints.HORIZONTAL; + constr.weightx = 1.0; + constr.gridy = 0; + myAddButton.setMnemonic('A'); + pane.add(myAddButton, constr); + constr.gridy = 1; + myCopyButton.setMnemonic('C'); + pane.add(myCopyButton, constr); + constr.gridy = 2; + myEditButton.setMnemonic('E'); + pane.add(myEditButton, constr); + constr.gridy = 3; + myRemoveButton.setMnemonic('R'); + pane.add(myRemoveButton, constr); + constr.gridy = 4; + myMoveUpButton.setMnemonic('U'); + pane.add(myMoveUpButton, constr); + constr.gridy = 5; + myMoveDownButton.setMnemonic('D'); + pane.add(myMoveDownButton, constr); + return pane; + } + + void reset() { + Tool[] tools = ToolManager.getInstance().getTools(); + while (myModel.getRowCount() > 0) { + myModel.removeRow(0); + } + for (int i = 0; i < tools.length; i++) { + Tool tool = tools[i]; + Tool toolCopy = new Tool(); + toolCopy.copyFrom(tool); + addRow(new ToolWrapper(toolCopy)); + } + if (myModel.getRowCount() > 0) { + myTable.setRowSelectionInterval(0, 0); + } + else { + myTable.getSelectionModel().clearSelection(); + } + update(); + } + + private void addRow(ToolWrapper toolWrapper) { + myModel.addRow(new Object[]{toolWrapper.getTool().isEnabled() ? Boolean.TRUE : Boolean.FALSE, toolWrapper}); + } + + void apply() throws IOException{ + // unregister removed tools + ToolManager toolManager = ToolManager.getInstance(); + + ArrayList tools = new ArrayList(); + for (int i = 0; i < myModel.getRowCount(); i++) { + ToolWrapper wrapper = myModel.getToolWrapper(i); + Tool tool = wrapper.getTool(); + tools.add(tool); + wrapper.commit(); + } + toolManager.setTools(getTools()); + toolManager.writeTools(); + } + + boolean isModified() { + Tool[] tools = new Tool[myModel.getRowCount()]; + for (int i = 0; i < myModel.getRowCount(); i++) { + ToolWrapper wrapper = myModel.getToolWrapper(i); + tools[i] = wrapper.getTool(); + } + return !Arrays.equals(ToolManager.getInstance().getTools(), tools); + } + + /** + * Tool info shown in list + */ + private static class ToolWrapper { + private Tool myTool; + + public ToolWrapper(Tool tool) { + myTool = tool; + } + + public String toString() { + return myTool.getName(); + } + + public Tool getTool() { + return myTool; + } + + public void commit() { + Tool newTool = new Tool(); + newTool.copyFrom(myTool); + myTool = newTool; + } + } + + private void addListeners() { + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + update(); + } + }); + + myTable.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2 && myTable.columnAtPoint(e.getPoint()) != 0) { + editSelected(); + } + } + }); + + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ToolEditorDialog dlg = new ToolEditorDialog(ToolsPanel.this); + Tool tool = new Tool(); + tool.setUseConsole(true); + tool.setFilesSynchronizedAfterRun(true); + tool.setShownInMainMenu(true); + tool.setShownInEditor(true); + tool.setShownInProjectViews(true); + tool.setShownInSearchResultsPopup(true); + tool.setEnabled(true); + dlg.setData(tool, ToolManager.getInstance().getGroups(getTools())); + dlg.show(); + if (dlg.isOK()) { + addRow(new ToolWrapper(dlg.getData())); + int lastIndex = myModel.getRowCount()-1; + myTable.setRowSelectionInterval(lastIndex, lastIndex); + } + myTable.requestFocus(); + } + }); + + myCopyButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + int index = myTable.getSelectionModel().getMinSelectionIndex(); + if (index == -1 || myTable.getSelectionModel().getMaxSelectionIndex() != index) return; + + ToolWrapper toolWrapper = myModel.getToolWrapper(index); + Tool originalTool = toolWrapper.getTool(); + + ToolEditorDialog dlg = new ToolEditorDialog(ToolsPanel.this); + Tool toolCopy = new Tool(); + toolCopy.copyFrom(originalTool); + dlg.setData(toolCopy, ToolManager.getInstance().getGroups(getTools())); + dlg.show(); + if (dlg.isOK()) { + addRow(new ToolWrapper(dlg.getData())); + int lastIndex = myModel.getRowCount()-1; + myTable.getSelectionModel().setSelectionInterval(lastIndex, lastIndex); + } + myTable.requestFocus(); + } + } + ); + + myEditButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editSelected(); + myTable.requestFocus(); + } + }); + + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + removeSelected(); + } + }); + + myMoveUpButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myModel.setSynchronize(false); + TableUtil.moveSelectedItemsUp(myTable); + myModel.setSynchronize(true); + myTable.requestFocus(); + } + }); + + myMoveDownButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myModel.setSynchronize(false); + TableUtil.moveSelectedItemsDown(myTable); + myModel.setSynchronize(true); + myTable.requestFocus(); + } + }); + + + InputMap inputMap = myTable.getInputMap(); + Object o = inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)); + if (o == null) { + o = "enable_disable"; + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), o); + } + myTable.getActionMap().put(o, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + ListSelectionModel selectionModel = myTable.getSelectionModel(); + for (int i = 0; i < myModel.getRowCount(); i++) { + if (selectionModel.isSelectedIndex(i)) { + Boolean aValue = (Boolean)myModel.getValueAt(i, 0); + myModel.setValueAt(aValue.booleanValue() ? Boolean.FALSE : Boolean.TRUE, i, 0); + } + } + } + }); + + o = inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); + if (o == null) { + o = "edit_selected"; + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), o); + } + myTable.getActionMap().put(o, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + editSelected(); + } + }); + + o = inputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)); + if (o == null) { + o = "remove_selected"; + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), o); + } + myTable.getActionMap().put(o, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + removeSelected(); + } + }); + } + + private void update() { + int minSelectionIndex = myTable.getSelectionModel().getMinSelectionIndex(); + int maxSelectionIndex = myTable.getSelectionModel().getMaxSelectionIndex(); + + // enable buttons + myRemoveButton.setEnabled(minSelectionIndex != -1); + myMoveUpButton.setEnabled(minSelectionIndex > 0); + myMoveDownButton.setEnabled(maxSelectionIndex != -1 && maxSelectionIndex < myModel.getRowCount()-1); + boolean selectedOne = minSelectionIndex != -1 && minSelectionIndex == maxSelectionIndex; + myCopyButton.setEnabled(selectedOne); + myEditButton.setEnabled(selectedOne); + + myTable.repaint(); + } + + private Tool[] getTools() { + Tool[] tools = new Tool[myModel.getRowCount()]; + for (int i = 0; i < tools.length; i++) { + tools[i] = myModel.getToolWrapper(i).getTool(); + } + return tools; + } + + private void removeSelected() { + int result = Messages.showYesNoDialog( + this, + "Do you want to delete the external tool(s)?", + "Warning", + Messages.getWarningIcon() + ); + if (result != 0) { + return; + } + TableUtil.removeSelectedItems(myTable); + update(); + myTable.requestFocus(); + } + + private void editSelected() { + int index = myTable.getSelectionModel().getMinSelectionIndex(); + if (index == -1 || index != myTable.getSelectionModel().getMaxSelectionIndex()) return; + ToolWrapper toolWrapper = myModel.getToolWrapper(index); + if (toolWrapper != null) { + ToolEditorDialog dlg = new ToolEditorDialog(this); + dlg.setData(toolWrapper.getTool(), ToolManager.getInstance().getGroups(getTools())); + dlg.show(); + if (dlg.isOK()) { + toolWrapper.getTool().copyFrom(dlg.getData()); + update(); + } + } + } + + class MyModel extends DefaultTableModel implements ItemRemovable { + private boolean myDoSynchronize = true; + + public MyModel() { + super(new Object[0][], new Object[]{" ", "Name", "Group", "Description"}); + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == 0) return Boolean.class; + return super.getColumnClass(columnIndex); + } + + public boolean isCellEditable(int row, int column) { + return column == 0; + } + + public void setValueAt(Object aValue, int row, int column) { + if (myDoSynchronize) { + if (column == 0) { + getToolWrapper(row).getTool().setEnabled(((Boolean)aValue).booleanValue()); + } + } + super.setValueAt(aValue, row, column); + myTable.repaint(); + } + + public Object getValueAt(int row, int column) { + switch (column) { + case 2: + return getToolWrapper(row).getTool().getGroup(); + case 3: + return getToolWrapper(row).getTool().getDescription(); + default: + return super.getValueAt(row, column); + } + } + + public ToolWrapper getToolWrapper(int row) { + return (ToolWrapper)getValueAt(row, 1); + } + + public void setSynchronize(boolean flag) { + myDoSynchronize = flag; + } + } + + private final class MyTableCellRenderer extends DefaultTableCellRenderer{ + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setEnabled(myModel.getToolWrapper(row).getTool().isEnabled()); + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AbstractToolTipHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AbstractToolTipHandler.java new file mode 100644 index 00000000000..3a793ac1d0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AbstractToolTipHandler.java @@ -0,0 +1,249 @@ +package com.intellij.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; + +abstract public class AbstractToolTipHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.AbstractToolTipHandler"); + + protected final ComponentType myComponent; + protected final CellRendererPane myRendererPane = new CellRendererPane(); + private final TipComponent myTipComponent; + + private Hint myHint; + /** + * A sort of unique key that identify the cell at point + */ + private KeyType myKey; + protected BufferedImage myImage; + + protected AbstractToolTipHandler(final ComponentType component) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + myComponent = component; + myComponent.add(myRendererPane); + myComponent.validate(); + + myTipComponent = new TipComponent(); + myComponent.addMouseListener( + new MouseListener() { + public void mouseEntered(MouseEvent e) { + handleMouseEvent(e); + } + + public void mouseExited(MouseEvent e) { + hideHint(); + } + + public void mouseClicked(MouseEvent e) {} + + public void mousePressed(MouseEvent e) { + handleMouseEvent(e); + } + + public void mouseReleased(MouseEvent e) { + handleMouseEvent(e); + } + } + ); + + myComponent.addMouseMotionListener( + new MouseMotionListener() { + public void mouseDragged(MouseEvent e) { + handleMouseEvent(e); + } + + public void mouseMoved(MouseEvent e) { + handleMouseEvent(e); + } + } + ); + + myComponent.addFocusListener( + new FocusAdapter() { + public void focusLost(FocusEvent e) { + hideHint(); + } + + public void focusGained(FocusEvent e) { + repaintHint(); + } + } + ); + + myComponent.addComponentListener( + new ComponentAdapter() { + public void componentHidden(ComponentEvent e){ + hideHint(); + } + + public void componentMoved(ComponentEvent e) { + hideHint(); + } + } + ); + myComponent.addHierarchyListener( + new HierarchyListener() { + public void hierarchyChanged(HierarchyEvent e){ + hideHint(); + } + } + ); + } + + private class TipComponent extends JComponent { + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getPreferredSize() { + return new Dimension(myImage.getWidth(), myImage.getHeight()); + } + + public void paint(Graphics g) { + g.drawImage(myImage, 0, 0, null); + } + } + + /** + * @return "key" that can unique identify some cell at the specified point. + * null means that the point doesn't correspond to + * any cell. Please note that the point is in coordinate system + * of the component which was passed into the class constructor. + */ + protected abstract KeyType getCellKeyForPoint(Point point); + + /** + * Hides tool tip + */ + protected final void hideHint() { + if (myHint != null) { + myHint.hide(); + myHint = null; + } + } + + private void handleMouseEvent(MouseEvent e){ + Object oldKey = myKey; + myKey = getCellKeyForPoint(e.getPoint()); + if(myKey == null || !myComponent.isShowing()){ + hideHint(); + return; + } + + Point location = createToolTipImage(myKey); + + if (location == null) { + hideHint(); + } + else if (myHint == null) { + show(location); + } + else if (!Comparing.equal(oldKey, myKey)){ + hideHint(); + show(location); + } + } + + private void show(Point location) { + LOG.assertTrue(myHint == null); + + if (!myComponent.isShowing()) { + return; + } + + JLayeredPane layeredPane = myComponent.getRootPane().getLayeredPane(); + Point layeredPanePoint = SwingUtilities.convertPoint(myComponent, location.x + myTipComponent.getPreferredSize().width, 0, layeredPane); + boolean fitIntoLayeredPane = layeredPanePoint.x < layeredPane.getWidth(); + + if (fitIntoLayeredPane) { + myHint = new LightweightHint(myTipComponent); + } else { + MenuElement[] selectedPath = MenuSelectionManager.defaultManager().getSelectedPath(); + if (selectedPath.length > 0) { + // do not show heavyweight hints when menu is shown to avoid their overlapping + return; + } + myHint = new HeavyweightHint(myTipComponent, false); + } + myHint.show(myComponent, location.x, location.y, myComponent); + } + + protected void repaintHint() { + if (myHint != null && myKey != null && myComponent.isShowing()) { + createToolTipImage(myKey); + myTipComponent.repaint(); + } + } + + /** + * @return point (in myComponent coordinates) for the cell which is specified + * by key. The method can return null in case if + * key does not define any valid cell. + */ + protected Point createToolTipImage(KeyType key) { + if (key == null) { + throw new IllegalArgumentException("key cannot be null"); + } + + Component rComponent; + rComponent = getRendererComponent(key); + + if (!(rComponent instanceof JComponent)) { + return null; + } + + Rectangle cellBounds = getCellBounds(key, rComponent); + if (cellBounds == null) return null; + Point cellLocation = cellBounds.getLocation(); + Rectangle visibleRect = getVisibleRect(key); + int height = cellBounds.height; + + if (visibleRect.contains(cellLocation.x + cellBounds.width, cellLocation.y + height)) return null; + + Point visibleRightTop = new Point(visibleRect.x + visibleRect.width, cellLocation.y); + int rightLimit = cellLocation.x + cellBounds.width; + int width = rightLimit - visibleRightTop.x; + if (width <= 0 || height <= 0) return null; + + myImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + Graphics2D g = myImage.createGraphics(); + g.setClip(null); + g.setColor(myComponent.getBackground()); + g.fillRect(0, 0, width, height); + g.translate(-(visibleRect.x + visibleRect.width - cellLocation.x), 0); + //rComponent.paint(g); + myRendererPane.paintComponent(g, rComponent, myComponent, 0, 0, cellBounds.width, height, true); + + g.translate((visibleRect.x + visibleRect.width - cellLocation.x), 0); + g.setColor(Color.black); + int rightX = myImage.getWidth() - 1; + g.drawLine(0, 0, rightX, 0); + g.drawLine(rightX, 0, rightX, height); + g.drawLine(0, height - 1, rightX, height - 1); + g.dispose(); + + myComponent.remove(rComponent); + + return visibleRightTop; + } + + protected Rectangle getVisibleRect(KeyType key) { + return myComponent.getVisibleRect(); + } + + protected abstract Rectangle getCellBounds(KeyType key, Component rendererComponent); + + protected abstract Component getRendererComponent(KeyType key); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ActivatableLineBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ActivatableLineBorder.java new file mode 100644 index 00000000000..7c6a1cf913b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ActivatableLineBorder.java @@ -0,0 +1,35 @@ +package com.intellij.ui; + +import javax.swing.border.Border; +import java.awt.*; + +public class ActivatableLineBorder implements Border { + private static Color ACTIVE_COLOR = new Color(160, 186, 213); + private static Color INACTIVE_COLOR = new Color(128, 128, 128); + + private boolean active = false; + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public Insets getBorderInsets(Component c) { + return new Insets(1, 1, 1, 1); + } + + public boolean isBorderOpaque() { + return false; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(active ? ACTIVE_COLOR : INACTIVE_COLOR); + g.drawLine(x + 1, y, x + width - 2, y); + g.drawLine(x + 1, y + height - 1, x + width - 2, y + height - 1); + g.drawLine(x, y + 1, x, y + height - 2); + g.drawLine(x + width - 1, y + 1, x + width - 1, y + height - 2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AnimatingSurface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AnimatingSurface.java new file mode 100644 index 00000000000..87894df0e82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AnimatingSurface.java @@ -0,0 +1,54 @@ +package com.intellij.ui; + + + +/** + * Demos that animate extend this class. + */ +public abstract class AnimatingSurface extends Surface implements Runnable { + public Thread thread; + + public abstract void step(int w, int h); + + public abstract void reset(int newwidth, int newheight); + + public void start() { + if (thread == null && !dontThread){ + thread = new Thread(this, "Animating surface"); + thread.setPriority(Thread.MIN_PRIORITY); + thread.setName(name + " Demo"); + thread.start(); + } + } + + public synchronized void stop() { + if (thread != null){ + thread.interrupt(); + } + thread = null; + notifyAll(); + } + + public void run() { + + Thread me = Thread.currentThread(); + + while(thread == me && !isShowing() || getSize().width == 0){ + try{ + Thread.sleep(200); + } + catch(InterruptedException e){ + } + } + + while(thread == me){ + repaint(); + try{ + Thread.sleep(sleepAmount); + } + catch(InterruptedException e){ + } + } + thread = null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollFromSourceHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollFromSourceHandler.java new file mode 100644 index 00000000000..2af144efe10 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollFromSourceHandler.java @@ -0,0 +1,32 @@ +package com.intellij.ui; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +public abstract class AutoScrollFromSourceHandler { + protected final Project myProject; + + protected AutoScrollFromSourceHandler(Project project) { + myProject = project; + } + + protected abstract boolean isAutoScrollMode(); + protected abstract void setAutoScrollMode(boolean state); + public abstract void install(); + public abstract void dispose(); + + public ToggleAction createToggleAction() { + return new ToggleAction("Autoscroll from Source", "Autoscroll from Source", IconLoader.getIcon("/general/autoscrollFromSource.png")) { + public boolean isSelected(AnActionEvent event) { + return isAutoScrollMode(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + setAutoScrollMode(flag); + } + }; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollToSourceHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollToSourceHandler.java new file mode 100644 index 00000000000..84b6c95aa14 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/AutoScrollToSourceHandler.java @@ -0,0 +1,94 @@ +package com.intellij.ui; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.pom.Navigatable; +import com.intellij.util.Alarm; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public abstract class AutoScrollToSourceHandler { + private final Project myProject; + private Alarm myAutoScrollAlarm; + + protected AutoScrollToSourceHandler(Project project) { + myProject = project; + } + + public void install(final JTree tree) { + myAutoScrollAlarm = new Alarm(); + tree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) return; + + TreePath location = tree.getPathForLocation(e.getPoint().x, e.getPoint().y); + if (location == null) return; + + myAutoScrollAlarm.cancelAllRequests(); + if (isAutoScrollMode()){ + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + scrollToSource(tree); + } + }); + } + } + }); + tree.addTreeSelectionListener( + new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + if (!isAutoScrollMode()) { + return; + } + if (!tree.hasFocus()) { + return; + } + myAutoScrollAlarm.cancelAllRequests(); + myAutoScrollAlarm.addRequest( + new Runnable() { + public void run() { + scrollToSource(tree); + } + }, + 500 + ); + } + } + ); + } + + protected abstract boolean isAutoScrollMode(); + protected abstract void setAutoScrollMode(boolean state); + + protected void scrollToSource(JTree tree) { + DataContext dataContext=DataManager.getInstance().getDataContext(tree); + Navigatable navigatable = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE); + if (navigatable != null && navigatable.canNavigate()) { + navigatable.navigate(false); + } + } + + public ToggleAction createToggleAction() { + return new ToggleAction("Autoscroll to Source", "Autoscroll to Source", IconLoader.getIcon("/general/autoscrollToSource.png")) { + public boolean isSelected(AnActionEvent event) { + return isAutoScrollMode(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + setAutoScrollMode(flag); + } + }; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/BooleanTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/BooleanTableCellRenderer.java new file mode 100644 index 00000000000..afb7824c017 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/BooleanTableCellRenderer.java @@ -0,0 +1,42 @@ +/** + * created at Oct 5, 2001 + * @author Jeka + */ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import java.awt.*; + +public class BooleanTableCellRenderer extends JCheckBox implements TableCellRenderer { + private final JPanel myPanel = new JPanel(); + + public BooleanTableCellRenderer() { + super(); + setHorizontalAlignment(JLabel.CENTER); + } + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + if(value == null) { + if(isSelected) { + myPanel.setBackground(table.getSelectionBackground()); + } + else { + myPanel.setBackground(table.getBackground()); + } + return myPanel; + } + if(isSelected) { + setForeground(table.getSelectionForeground()); + super.setBackground(table.getSelectionBackground()); + } + else { + setForeground(table.getForeground()); + setBackground(table.getBackground()); + } + setSelected(((Boolean)value).booleanValue()); + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckboxTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckboxTree.java new file mode 100644 index 00000000000..fea9acff7b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckboxTree.java @@ -0,0 +1,147 @@ +package com.intellij.ui; + +import com.intellij.util.ui.tree.TreeUtil; +import com.intellij.util.ui.Tree; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * User: lex + * Date: Sep 18, 2003 + * Time: 5:40:20 PM + */ +public class CheckboxTree extends Tree { + public CheckboxTree(final CheckboxTreeCellRenderer cellRenderer, CheckedTreeNode root) { + setCellRenderer(cellRenderer); + setRootVisible(false); + setShowsRootHandles(true); + putClientProperty("JTree.lineStyle", "Angled"); + TreeToolTipHandler.install(this); + TreeUtil.installActions(this); + new TreeSpeedSearch(this); + + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + int row = getRowForLocation(e.getX(), e.getY()); + if (row >= 0) { + Rectangle rowBounds = getRowBounds(row); + cellRenderer.setBounds(rowBounds); + Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); + checkBounds.setLocation(rowBounds.getLocation()); + + if (checkBounds.contains(e.getPoint())) { + CheckedTreeNode node = (CheckedTreeNode) getPathForRow(row).getLastPathComponent(); + toggleNode(node); + e.consume(); + setSelectionRow(row); + } + } + } + }); + + addKeyListener( + new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if(e.getKeyCode() == KeyEvent.VK_SPACE) { + TreePath treePath = getLeadSelectionPath(); + CheckedTreeNode firstNode = (CheckedTreeNode)treePath.getLastPathComponent(); + boolean checked = toggleNode(firstNode); + + TreePath[] selectionPaths = getSelectionPaths(); + for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) { + final TreePath selectionPath = selectionPaths[i]; + CheckedTreeNode node = (CheckedTreeNode)selectionPath.getLastPathComponent(); + checkNode(node,checked); + } + + e.consume(); + } + } + } + ); + + setSelectionRow(0); + setModel(new DefaultTreeModel(root)); + } + + protected boolean toggleNode(CheckedTreeNode node) { + boolean checked = !node.isChecked(); + checkNode(node, checked); + return checked; + } + + protected void checkNode(CheckedTreeNode node, boolean checked) { + node.setChecked(checked); + repaint(); + } + + public static abstract class CheckboxTreeCellRenderer extends JPanel implements TreeCellRenderer { + private final ColoredTreeCellRenderer myTextRenderer; + public final JCheckBox myCheckbox; + + public CheckboxTreeCellRenderer() { + super(new BorderLayout()); + myCheckbox = new JCheckBox(); + myTextRenderer = new ColoredTreeCellRenderer() { + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + } + }; + add(myCheckbox, BorderLayout.WEST); + add(myTextRenderer, BorderLayout.CENTER); + } + + public final Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + invalidate(); + if (value instanceof CheckedTreeNode) { + CheckedTreeNode node = (CheckedTreeNode)value; + myCheckbox.setSelected(node.isChecked()); + + myCheckbox.setBackground(null); + setBackground(null); + + myTextRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + CheckboxTreeCellRenderer.this.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus); + } + return this; + } + + /** + * This method is invoked only for customization of component. + * All component attributes are cleared when this method is being invoked. + */ + public abstract void customizeCellRenderer( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus + ); + + public SimpleColoredComponent getTextRenderer () { return myTextRenderer; } + public JCheckBox getCheckbox() { return myCheckbox; } + } + + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckedTreeNode.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckedTreeNode.java new file mode 100644 index 00000000000..a4aa965e81d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CheckedTreeNode.java @@ -0,0 +1,24 @@ +package com.intellij.ui; + +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * User: lex + * Date: Sep 20, 2003 + * Time: 5:14:07 PM + */ +public class CheckedTreeNode extends DefaultMutableTreeNode { + private boolean isChecked = true; + public CheckedTreeNode(Object userObject) { + super(userObject); + } + + public boolean isChecked() { + return isChecked; + } + + + public void setChecked(boolean checked) { + isChecked = checked; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsiblePanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsiblePanel.java new file mode 100644 index 00000000000..3bf757c7778 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsiblePanel.java @@ -0,0 +1,125 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Eugene Zhuravlev + * Date: Oct 29 + * @author 2003 + */ +public class CollapsiblePanel extends JPanel { + private final JButton myToggleCollapseButton; + private final JComponent myContent; + private boolean myIsCollapsed; + private final Collection myListeners = new ArrayList(); + private boolean myIsInitialized = false; + private final Icon myExpandIcon; + private final Icon myCollapseIcon; + + public CollapsiblePanel(JComponent content, boolean collapseButtonAtLeft, boolean isCollapsed, Icon collapseIcon, Icon expandIcon) { + super(new GridBagLayout()); + myContent = content; + this.setBackground(content.getBackground()); + myExpandIcon = expandIcon; + myCollapseIcon = collapseIcon; + final Dimension buttonDimension = getButtonDimension(); + myToggleCollapseButton = new JButton(); + myToggleCollapseButton.setSize(buttonDimension); + myToggleCollapseButton.setPreferredSize(buttonDimension); + myToggleCollapseButton.setMinimumSize(buttonDimension); + myToggleCollapseButton.setMaximumSize(buttonDimension); + + this.add(myToggleCollapseButton, + new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, + collapseButtonAtLeft ? GridBagConstraints.WEST : GridBagConstraints.EAST, + GridBagConstraints.NONE, + new Insets(-5, collapseButtonAtLeft ? 0 : -5, 0, collapseButtonAtLeft ? -5 : 0), 0, + 0)); + myToggleCollapseButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + setCollapsed(!myIsCollapsed); + } + }); + setCollapsed(isCollapsed); + + } + + private Dimension getButtonDimension() { + if (myExpandIcon == null) + return new Dimension(7, 7); + else + return new Dimension(myExpandIcon.getIconWidth(), myExpandIcon.getIconHeight()); + } + + public CollapsiblePanel(JComponent content, boolean collapseButtonAtLeft) { + this(content, collapseButtonAtLeft, false, null, null); + } + + protected void setCollapsed(boolean collapse) { + try { + if (collapse) { + if (myIsInitialized) this.remove(myContent); + } + else { + this.add(myContent, + new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + } + myIsCollapsed = collapse; + + Icon icon = getIcon(); + if (icon != null){ + myToggleCollapseButton.setIcon(icon); + myToggleCollapseButton.setBorder(null); + myToggleCollapseButton.setBorderPainted(false); + myToggleCollapseButton.setToolTipText(getToggleButtonToolTipText()); + } + + notifyListners(); + + revalidate(); + repaint(); + } + finally { + myIsInitialized = true; + } + } + + private String getToggleButtonToolTipText() { + if (myIsCollapsed) + return "Expand Panel"; + else + return "Collapse Panel"; + } + + private Icon getIcon() { + if (myIsCollapsed) + return myExpandIcon; + else + return myCollapseIcon; + } + + private void notifyListners() { + CollapsingListener[] listeners = myListeners.toArray(new CollapsingListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].onCollapsingChanged(this, isCollapsed()); + } + } + + public void addCollapsingListener(CollapsingListener listener) { + myListeners.add(listener); + } + + public void removeCollapsingListener(CollapsingListener listener) { + myListeners.remove(listener); + } + + public boolean isCollapsed() { + return myIsCollapsed; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsingListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsingListener.java new file mode 100644 index 00000000000..e852eb7fa93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CollapsingListener.java @@ -0,0 +1,8 @@ +package com.intellij.ui; + +/** + * author: lesya + */ +public interface CollapsingListener { + void onCollapsingChanged(CollapsiblePanel panel, boolean newValue); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColorPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColorPanel.java new file mode 100644 index 00000000000..59b40abf3c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColorPanel.java @@ -0,0 +1,313 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ColorPanel extends JPanel { + public static final Color[] fixedColors; + public static final Color DARK_MAGENTA = new Color(128, 0, 128); + public static final Color DARK_BLUE = new Color(0, 0, 128); + public static final Color DARK_GREEN = new Color(0, 128, 0); + public static final Color BLUE_GREEN = new Color(0, 128, 128); + public static final Color DARK_YELLOW = new Color(128, 128, 0); + public static final Color DARK_RED = new Color(128, 0, 0); + public static final Color DISABLED_COLOR = UIManager.getColor("Panel.background"); + private static Color[] myCustomColors; + private String myActionCommand = "colorPanelChanged"; + private boolean isFiringEvent = false; + private int myBoxSize; + private GridLayout myCustomGridLayout; + private GridLayout myFixedGridLayout; + private ColorBox[] myFgFixedColorBoxes; + private ColorBox[] myFgCustomColorBoxes; + private ColorBox myFgSelectedColorBox; + + static { + fixedColors = new Color[]{Color.white, Color.lightGray, Color.red, Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta, + Color.black, Color.gray, DARK_RED, DARK_YELLOW, DARK_GREEN, BLUE_GREEN, DARK_BLUE, DARK_MAGENTA}; + } + + public ColorPanel() { + this(null, 10); + } + + public ColorPanel(Color[] colors, int boxSize) { + myBoxSize = boxSize; + myFgSelectedColorBox = new ColorBox(null, (myBoxSize + 2) * 2, true); + myFgSelectedColorBox.setSelectColorAction( + new Runnable() { + public void run() { + fireActionEvent(); + } + } + ); + + myFgFixedColorBoxes = new ColorBox[16]; + myFixedGridLayout = new GridLayout(2, 0, 2, 2); + myCustomGridLayout = new GridLayout(2, 0, 2, 2); + myFgCustomColorBoxes = new ColorBox[8]; + if (colors == null){ + if (myCustomColors == null){ + myCustomColors = + new Color[]{ + Color.lightGray, Color.lightGray, Color.lightGray, Color.lightGray, Color.lightGray, Color.lightGray, Color.lightGray, Color.lightGray + }; + } + } + else{ + myCustomColors = colors; + } + + JPanel selectedColorPanel = new JPanel(new GridBagLayout()); + selectedColorPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + myFgSelectedColorBox.setBorder(BorderFactory.createEtchedBorder()); + selectedColorPanel.add(myFgSelectedColorBox, new GridBagConstraints()); + + initializeColorBoxes(); + JPanel fixedColorsPanel = new JPanel(myFixedGridLayout); + for(int i = 0; i < myFgFixedColorBoxes.length; i++){ + JPanel jpanel2 = new JPanel(new BorderLayout()); + jpanel2.setBorder(BorderFactory.createEtchedBorder()); + jpanel2.add(myFgFixedColorBoxes[i], BorderLayout.CENTER); + fixedColorsPanel.add(jpanel2); + } + + JPanel customColorsPanel = new JPanel(myCustomGridLayout); + EdgeBorder edgeborder = new EdgeBorder(EdgeBorder.EDGE_LEFT); + Border border = BorderFactory.createEmptyBorder(0, 2, 0, 0); + customColorsPanel.setBorder(BorderFactory.createCompoundBorder(edgeborder, border)); + for(int k = 0; k < myFgCustomColorBoxes.length; k++){ + JPanel jpanel4 = new JPanel(new BorderLayout()); + jpanel4.setBorder(BorderFactory.createEtchedBorder()); + jpanel4.add(myFgCustomColorBoxes[k], BorderLayout.CENTER); + customColorsPanel.add(jpanel4); + } + + JPanel allColorsPanel = new JPanel(new GridBagLayout()); + allColorsPanel.setBorder(BorderFactory.createEtchedBorder()); + allColorsPanel.add(fixedColorsPanel, new GridBagConstraints(1, 0, 1, 1, 0.1D, 0.1D, 10, 0, new Insets(2, 2, 2, 1), 0, 0)); + allColorsPanel.add(customColorsPanel, new GridBagConstraints(2, 0, 1, 1, 0.1D, 0.1D, 17, 0, new Insets(2, 2, 2, 2), 0, 0)); + setLayout(new BorderLayout()); + add(selectedColorPanel, BorderLayout.WEST); + add(allColorsPanel, BorderLayout.CENTER); + } + + public void setEnabled(boolean enabled) { + for(int i = 0; i < myFgFixedColorBoxes.length; i++){ + ColorBox colorBox = myFgFixedColorBoxes[i]; + colorBox.setEnabled(enabled); + } + for(int i = 0; i < myFgCustomColorBoxes.length; i++){ + ColorBox colorBox = myFgCustomColorBoxes[i]; + colorBox.setEnabled(enabled); + } + myFgSelectedColorBox.setEnabled(enabled); + super.setEnabled(enabled); + repaint(); + } + + void updateColorBoxes() { + for(int i = 0; i < myFgCustomColorBoxes.length; i++){ + myFgCustomColorBoxes[i].setColor(myCustomColors[i]); + } + } + + protected void initializeColorBoxes() { + for(int i = 0; i < myFgFixedColorBoxes.length; i++){ + myFgFixedColorBoxes[i] = new ColorBox(fixedColors[i], myBoxSize, false); + } + for(int i = 0; i < myFgCustomColorBoxes.length; i++){ + myFgCustomColorBoxes[i] = new ColorBox(Color.orange, myBoxSize, true); + final int customColorIndex = i; + final ColorBox customColorBox = myFgCustomColorBoxes[i]; + myFgCustomColorBoxes[i].setSelectColorAction( + new Runnable() { + public void run() { + myCustomColors[customColorIndex] = customColorBox.getColor(); + } + } + ); + } + updateColorBoxes(); + } + + public void setActionCommand(String actionCommand) { + myActionCommand = actionCommand; + } + + public String getActionCommand() { + return myActionCommand; + } + + private void fireActionEvent() { + if (!isFiringEvent){ + isFiringEvent = true; + ActionEvent actionevent = null; + Object[] listeners = listenerList.getListenerList(); + for(int i = listeners.length - 2; i >= 0; i -= 2){ + if (listeners[i] != ActionListener.class) continue; + if (actionevent == null){ + actionevent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getActionCommand()); + } + ((ActionListener)listeners[i + 1]).actionPerformed(actionevent); + } + isFiringEvent = false; + } + } + + public void removeActionListener(ActionListener actionlistener) { + listenerList.remove(ActionListener.class, actionlistener); + } + + public void addActionListener(ActionListener actionlistener) { + listenerList.add(ActionListener.class, actionlistener); + } + + public void setCustomColor(int index, Color color1) { + myCustomColors[index - myFgFixedColorBoxes.length] = color1; + } + + public Color getSelectedColor() { + return myFgSelectedColorBox.getColor(); + } + + public void setSelectedColor(Color color) { + myFgSelectedColorBox.setColor(color); + } + + public Color[] getCustomColors() { + return myCustomColors; + } + + public void setPanelGridHeight(int i) { + myFixedGridLayout.setRows(i); + myCustomGridLayout.setRows(i); + doLayout(); + } + + public void setCustomColors(Color[] colors) { + myCustomColors = colors; + if (myCustomColors == null){ + myCustomColors = fixedColors; + } + if (colors != null){ + updateColorBoxes(); + } + } + + private class ColorBox extends JComponent { + private Dimension mySize; + private boolean isSelectable; + private Runnable mySelectColorAction = null; + private Color myColor; + + public ColorBox(Color color, int size, boolean isSelectable) { + mySize = new Dimension(size, size); + this.isSelectable = isSelectable; + myColor = color; + updateToolTip(); + //TODO[anton,vova] investigate + addMouseListener(new MouseAdapter(){ + public void mouseReleased(MouseEvent mouseevent) { + if (!isEnabled()){ + return; + } + if (mouseevent.isPopupTrigger()){ + selectColor(); + } + } + + public void mousePressed(MouseEvent mouseevent) { + if (!isEnabled()){ + return; + } + if (mouseevent.getClickCount() == 2){ + selectColor(); + } + else{ + if (SwingUtilities.isLeftMouseButton(mouseevent)){ + setSelectedColor(myColor); + fireActionEvent(); + } + else{ + if (mouseevent.isPopupTrigger()){ + selectColor(); + } + } + } + } + }); + } + + public void setSelectColorAction(Runnable selectColorAction) { + mySelectColorAction = selectColorAction; + } + + private void selectColor() { + if (isSelectable){ + Color color = JColorChooser.showDialog(ColorPanel.this, "Select a color", myColor); + if (color != null){ + setColor(color); + if (mySelectColorAction != null){ + mySelectColorAction.run(); + } + } + } + } + + public Dimension getMinimumSize() { + return mySize; + } + + public Dimension getMaximumSize() { + return mySize; + } + + public Dimension getPreferredSize() { + return mySize; + } + + public void paintComponent(Graphics g) { + if (isEnabled()){ + g.setColor(myColor); + } + else{ + g.setColor(DISABLED_COLOR); + } + g.fillRect(0, 0, getWidth(), getHeight()); + } + + private void updateToolTip() { + if (myColor == null){ + return; + } + StringBuffer buffer = new StringBuffer(64); + buffer.append("RGB: "); + buffer.append(myColor.getRed()); + buffer.append(", "); + buffer.append(myColor.getGreen()); + buffer.append(", "); + buffer.append(myColor.getBlue()); + + if (isSelectable) { + buffer.append(" (Right-click to customize)"); + } + setToolTipText(buffer.toString()); + } + + public void setColor(Color color) { + myColor = color; + updateToolTip(); + repaint(); + } + + public Color getColor() { + return myColor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColoredTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColoredTableCellRenderer.java new file mode 100644 index 00000000000..03f9be35f99 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ColoredTableCellRenderer.java @@ -0,0 +1,25 @@ +package com.intellij.ui; + +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; +import java.awt.*; + +public abstract class ColoredTableCellRenderer extends SimpleColoredRenderer implements TableCellRenderer { + public final Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column + ){ + clear(); + setPaintFocusBorder(hasFocus); + acquireState(table, isSelected, hasFocus, row, column); + getCellState().updateRenderer(this); + customizeCellRenderer(table, value, isSelected, hasFocus, row, column); + return this; + } + + protected abstract void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CompTitledBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CompTitledBorder.java new file mode 100644 index 00000000000..53639769509 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/CompTitledBorder.java @@ -0,0 +1,178 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.TitledBorder; +import java.awt.*; + +public class CompTitledBorder extends TitledBorder { + protected JComponent component; + + public CompTitledBorder(JComponent component) { + this(null, component, LEFT, TOP); + } + + public CompTitledBorder(Border border) { + this(border, null, LEFT, TOP); + } + + public CompTitledBorder(Border border, JComponent component) { + this(border, component, LEFT, TOP); + } + + public CompTitledBorder(Border border, + JComponent component, + int titleJustification, + int titlePosition) { + super(border, null, titleJustification, + titlePosition, null, null); + this.component = component; + if (border == null) { + this.border = super.getBorder(); + } + } + + + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) { + Rectangle borderR = new Rectangle(x + EDGE_SPACING, + y + EDGE_SPACING, + width - (EDGE_SPACING * 2), + height - (EDGE_SPACING * 2)); + Insets borderInsets; + if (border != null) { + borderInsets = border.getBorderInsets(c); + } else { + borderInsets = new Insets(0, 0, 0, 0); + } + + Rectangle rect = new Rectangle(x, y, width, height); + Insets insets = getBorderInsets(c); + Rectangle compR = getComponentRect(rect, insets); + int diff; + switch (titlePosition) { + case ABOVE_TOP: + diff = compR.height + TEXT_SPACING; + borderR.y += diff; + borderR.height -= diff; + break; + case TOP: + case DEFAULT_POSITION: + diff = insets.top / 2 - borderInsets.top - EDGE_SPACING; + borderR.y += diff; + borderR.height -= diff; + break; + case BELOW_TOP: + case ABOVE_BOTTOM: + break; + case BOTTOM: + diff = insets.bottom / 2 - borderInsets.bottom - EDGE_SPACING; + borderR.height -= diff; + break; + case BELOW_BOTTOM: + diff = compR.height + TEXT_SPACING; + borderR.height -= diff; + break; + } + border.paintBorder(c, g, borderR.x, borderR.y, + borderR.width, borderR.height); + Color col = g.getColor(); + g.setColor(c.getBackground()); + g.fillRect(compR.x, compR.y, compR.width, compR.height); + g.setColor(col); + component.repaint(); + } + + + public Insets getBorderInsets(Component c, Insets insets) { + Insets borderInsets; + if (border != null) { + borderInsets = border.getBorderInsets(c); + } else { + borderInsets = new Insets(0, 0, 0, 0); + } + insets.top = EDGE_SPACING + TEXT_SPACING + borderInsets.top; + insets.right = EDGE_SPACING + TEXT_SPACING + borderInsets.right; + insets.bottom = EDGE_SPACING + TEXT_SPACING + borderInsets.bottom; + insets.left = EDGE_SPACING + TEXT_SPACING + borderInsets.left; + + if (c == null || component == null) { + return insets; + } + + int compHeight = component.getPreferredSize().height; + + switch (titlePosition) { + case ABOVE_TOP: + insets.top += compHeight + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + insets.top += Math.max(compHeight, borderInsets.top) - borderInsets.top; + break; + case BELOW_TOP: + insets.top += compHeight + TEXT_SPACING; + break; + case ABOVE_BOTTOM: + insets.bottom += compHeight + TEXT_SPACING; + break; + case BOTTOM: + insets.bottom += Math.max(compHeight, borderInsets.bottom) - borderInsets.bottom; + break; + case BELOW_BOTTOM: + insets.bottom += compHeight + TEXT_SPACING; + break; + } + return insets; + } + + public JComponent getTitleComponent() { + return component; + } + + public void setTitleComponent(JComponent component) { + this.component = component; + } + + + public Rectangle getComponentRect(Rectangle rect, Insets borderInsets) { + Dimension compD = component.getPreferredSize(); + Rectangle compR = new Rectangle(0, 0, compD.width, compD.height); + switch (titlePosition) { + case ABOVE_TOP: + compR.y = EDGE_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + compR.y = EDGE_SPACING + + (borderInsets.top - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + break; + case BELOW_TOP: + compR.y = borderInsets.top - compD.height - TEXT_SPACING; + break; + case ABOVE_BOTTOM: + compR.y = rect.height - borderInsets.bottom + TEXT_SPACING; + break; + case BOTTOM: + compR.y = rect.height - borderInsets.bottom + TEXT_SPACING + + (borderInsets.bottom - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + break; + case BELOW_BOTTOM: + compR.y = rect.height - compD.height - EDGE_SPACING; + break; + } + switch (titleJustification) { + case LEFT: + case DEFAULT_JUSTIFICATION: + compR.x = TEXT_INSET_H + borderInsets.left; + break; + case RIGHT: + compR.x = rect.width - borderInsets.right - TEXT_INSET_H - compR.width; + break; + case CENTER: + compR.x = (rect.width - compR.width) / 2; + break; + } + return compR; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/DialogButtonGroup.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/DialogButtonGroup.java new file mode 100644 index 00000000000..5a1e94d254b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/DialogButtonGroup.java @@ -0,0 +1,106 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +public class DialogButtonGroup extends JPanel { + public static final int TOP = 1; + public static final int BOTTOM = 2; + private int myPreferredH = 0; + private int myPreferredW = 0; + + public DialogButtonGroup() { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + registerKeyboardAction(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + upPressed(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + registerKeyboardAction(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + downPressed(); + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + public void addButton(AbstractButton button) { + addButton(button, BOTTOM); + } + + public void addButton(AbstractButton button, int position) { + if (TOP == position) { + add(button, 0); + add(Box.createVerticalStrut(5), 1); + } + else { + add(Box.createVerticalStrut(5)); + add(button); + } + Dimension prefSize = button.getPreferredSize(); + if (prefSize.height > myPreferredH) { + myPreferredH = prefSize.height; + } + if (prefSize.width > myPreferredW) { + myPreferredW = prefSize.width; + } + updateButtonSizes(); + } + + public void remove(AbstractButton button) { + remove(button); + updateButtonSizes(); + } + + public void grabFocus() { + ((JComponent)getComponent(0)).grabFocus(); + } + + private void updateButtonSizes() { + Dimension dim = new Dimension(myPreferredW, myPreferredH); + Component[] components = getComponents(); + if (components == null) return; + for (int i = 0; i < components.length; i++) { + if (components[i] instanceof AbstractButton) { + AbstractButton button = (AbstractButton)components[i]; + button.setPreferredSize(dim); + button.setMaximumSize(dim); + button.setMinimumSize(dim); + } + } + } + + private void upPressed() { + Component[] components = getComponents(); + for (int i = 0; i < components.length; i++) { + if (components[i].hasFocus()) { + if (i == 0) { + components[components.length - 1].requestFocus(); + return; + } + components[i - 1].requestFocus(); + return; + } + } + } + + private void downPressed() { + Component[] components = getComponents(); + for (int i = 0; i < components.length; i++) { + if (components[i].hasFocus()) { + if (i == components.length - 1) { + components[0].requestFocus(); + return; + } + components[i + 1].requestFocus(); + return; + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EdgeBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EdgeBorder.java new file mode 100644 index 00000000000..87281ae6199 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EdgeBorder.java @@ -0,0 +1,68 @@ + +package com.intellij.ui; + +import java.awt.*; +import javax.swing.*; +import javax.swing.border.Border; + +public class EdgeBorder implements Border { + public static final int EDGE_RIGHT = 61440; + public static final int EDGE_BOTTOM = 3840; + public static final int EDGE_LEFT = 240; + public static final int EDGE_TOP = 15; + public static final int EDGE_ALL = 65535; + private Insets myInsets; + private int b; + + public EdgeBorder(int i) { + myInsets = new Insets(2, 2, 2, 2); + b = i; + recalcInsets(); + } + + public boolean isBorderOpaque() { + return true; + } + + public Insets getBorderInsets(Component component) { + return myInsets; + } + + public void paintBorder(Component component, Graphics g, int x, int y, int width, int height) { + java.awt.Color color = UIManager.getColor("Separator.shadow"); + java.awt.Color color1 = UIManager.getColor("Separator.highlight"); + java.awt.Color color2 = g.getColor(); + if ((b & 0xf) != 0){ + g.setColor(color); + g.drawLine(x, y, (x + width) - 1, y); + g.setColor(color1); + g.drawLine(x, y + 1, (x + width) - 1, y + 1); + } + if ((b & 0xf0) != 0){ + g.setColor(color); + g.drawLine(x, y, x, (y + height) - 1); + g.setColor(color1); + g.drawLine(x + 1, y, x + 1, (y + height) - 1); + } + if ((b & 0xf00) != 0){ + g.setColor(color); + g.drawLine(x, (y + height) - 2, (x + width) - 1, (y + height) - 2); + g.setColor(color1); + g.drawLine(x, (y + height) - 1, (x + width) - 1, (y + height) - 1); + } + if ((b & 0xf000) != 0){ + g.setColor(color); + g.drawLine((x + width) - 2, y, (x + width) - 2, (y + height) - 1); + g.setColor(color1); + g.drawLine((x + width) - 1, y, (x + width) - 1, (y + height) - 1); + } + g.setColor(color2); + } + + protected void recalcInsets() { + myInsets.top = (b & 0xf) == 0 ? 0 : 2; + myInsets.left = (b & 0xf0) == 0 ? 0 : 2; + myInsets.bottom = (b & 0xf00) == 0 ? 0 : 2; + myInsets.right = (b & 0xf000) == 0 ? 0 : 2; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxEditor.java new file mode 100644 index 00000000000..4057d6756b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxEditor.java @@ -0,0 +1,52 @@ +package com.intellij.ui; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.project.Project; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionListener; + +/** + * Combobox items are Documents for this combobox + * @author max + */ +public class EditorComboBoxEditor implements ComboBoxEditor{ + private EditorTextField myTextField; + + public EditorComboBoxEditor(Project project, FileType fileType) { + myTextField = new EditorTextField((Document)null, project, fileType); + myTextField.setName("ComboBox.textField"); + } + + public void selectAll() { + myTextField.selectAll(); + myTextField.requestFocus(); + } + + public Editor getEditor() { + return myTextField.getEditor(); + } + + public Component getEditorComponent() { + return myTextField; + } + + public void addActionListener(ActionListener l) { + + } + + public void removeActionListener(ActionListener l) { + + } + + public Object getItem() { + return myTextField.getDocument(); + } + + public void setItem(Object anObject) { + myTextField.setDocument((Document)anObject); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxRenderer.java new file mode 100644 index 00000000000..4d258742c5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorComboBoxRenderer.java @@ -0,0 +1,29 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicComboBoxRenderer; +import java.awt.*; + +/** + * @author max + */ +public class EditorComboBoxRenderer extends BasicComboBoxRenderer { + private EditorComboBoxEditor myEditor; + + public EditorComboBoxRenderer(EditorComboBoxEditor editor) { + myEditor = editor; + } + + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + Font editorFont = myEditor.getEditorComponent().getFont(); + + final Component component = super.getListCellRendererComponent(list, value, index, + isSelected, cellHasFocus); + component.setFont(editorFont); + return component; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorTextField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorTextField.java new file mode 100644 index 00000000000..5571c05d539 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/EditorTextField.java @@ -0,0 +1,358 @@ +package com.intellij.ui; + +import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; + +/** + * @author max + */ +public class EditorTextField extends JPanel implements DocumentListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.EditorTextField"); + + private Document myDocument; + private Project myProject; + private FileType myFileType; + private EditorEx myEditor = null; + private Component myNextFocusable = null; + private boolean myWholeTextSelected = false; + private ArrayList myDocumentListeners = new ArrayList(); + private boolean myIsListenerInstalled = false; + private boolean myIsViewer; + + public EditorTextField(String text) { + this(EditorFactory.getInstance().createDocument(text), null, StdFileTypes.PLAIN_TEXT); + } + + public EditorTextField(String text, Project project, FileType fileType) { + this(EditorFactory.getInstance().createDocument(text), project, fileType, false); + } + + public EditorTextField(Document document, Project project, FileType fileType) { + this(document, project, fileType, false); + } + + public EditorTextField(Document document, Project project, FileType fileType, boolean isViewer) { + myIsViewer = isViewer; + setDocument(document); + myProject = project; + myFileType = fileType; + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + enableEvents(AWTEvent.KEY_EVENT_MASK); + // todo[dsl,max] + setFocusable(true); + // dsl: this is a weird way of doing things.... + addFocusListener(new FocusListener() { + public void focusGained(FocusEvent e) { + requestFocus(); + } + + public void focusLost(FocusEvent e) { + } + }); + } + + + + public String getText() { + return myDocument.getText(); + } + + public void addDocumentListener(DocumentListener listener) { + myDocumentListeners.add(listener); + installDocumentListener(); + } + + public void removeDocumentListener(DocumentListener listener) { + myDocumentListeners.remove(listener); + uninstallDocumentListener(false); + } + + public void beforeDocumentChange(DocumentEvent event) { + for (int i = 0; i < myDocumentListeners.size(); i++) { + DocumentListener documentListener = myDocumentListeners.get(i); + documentListener.beforeDocumentChange(event); + } + } + + public void documentChanged(DocumentEvent event) { + for (int i = 0; i < myDocumentListeners.size(); i++) { + DocumentListener documentListener = myDocumentListeners.get(i); + documentListener.documentChanged(event); + } + } + + public Project getProject() { + return myProject; + } + + public Document getDocument() { + return myDocument; + } + + public void setDocument(Document document) { + if (myDocument != null) { + /* + final UndoManager undoManager = myProject != null + ? UndoManager.getInstance(myProject) + : UndoManager.getGlobalInstance(); + undoManager.clearUndoRedoQueue(myDocument); + */ + + uninstallDocumentListener(true); + } + + myDocument = document; + installDocumentListener(); + if (myEditor == null) return; + + //MainWatchPanel watches the oldEditor's focus in order to remove debugger combobox when focus is lost + //we should first transfer focus to new oldEditor and only then remove current oldEditor + //MainWatchPanel check that oldEditor.getParent == newEditor.getParent and does not remove oldEditor in such cases + + boolean isFocused = isFocusOwner(); + Editor editor = myEditor; + myEditor = createEditor(); + add(myEditor.getComponent()); + releaseEditor(editor); + + validate(); + if (isFocused) { + myEditor.getContentComponent().requestFocus(); + } + } + + private void installDocumentListener() { + if (myDocument != null && myDocumentListeners.size() > 0 && !myIsListenerInstalled) { + myIsListenerInstalled = true; + myDocument.addDocumentListener(this); + } + } + + private void uninstallDocumentListener(boolean force) { + if (myDocument != null && myIsListenerInstalled && (force || myDocumentListeners.size() == 0)) { + myIsListenerInstalled = false; + myDocument.removeDocumentListener(this); + } + } + + public void setText(final String text) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + public void run() { + myDocument.replaceString(0, myDocument.getTextLength(), text); + if (myEditor != null) { + myEditor.getCaretModel().moveToOffset(myDocument.getTextLength()); + } + } + }, null, null); + } + }); + } + + public void selectAll() { + if (myEditor != null) { + myEditor.getSelectionModel().setSelection(0, myDocument.getTextLength()); + } + else { + myWholeTextSelected = true; + } + } + + public void removeSelection() { + if (myEditor != null) { + myEditor.getSelectionModel().removeSelection(); + } + else { + myWholeTextSelected = false; + } + } + + public CaretModel getCaretModel() { + return myEditor.getCaretModel(); + } + + public boolean isFocusOwner() { + if (myEditor != null) { + return IJSwingUtilities.hasFocus(myEditor.getContentComponent()); + } + return super.isFocusOwner(); + } + + private void releaseEditor(final Editor editor) { + remove(editor.getComponent()); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + EditorFactory.getInstance().releaseEditor(editor); + } + }); + } + + public void addNotify() { + LOG.assertTrue(myEditor == null); + + boolean isFocused = isFocusOwner(); + + myEditor = createEditor(); + add(myEditor.getComponent()); + + super.addNotify(); + + if (myNextFocusable != null) { + myEditor.getContentComponent().setNextFocusableComponent(myNextFocusable); + myNextFocusable = null; + } + revalidate(); + if (isFocused) { + requestFocus(); + } + } + + public void removeNotify() { + super.removeNotify(); + LOG.assertTrue(myEditor != null); + releaseEditor(myEditor); + myEditor = null; + } + + public void setFont(Font font) { + super.setFont(font); + if (myEditor != null) { + myEditor.getColorsScheme().setEditorFontName(getFont().getFontName()); + myEditor.getColorsScheme().setEditorFontSize(getFont().getSize()); + } + } + + protected EditorEx createEditor() { + LOG.assertTrue(myDocument != null); + + final EditorFactory factory = EditorFactory.getInstance(); + EditorEx editor; + if (!myIsViewer) { + editor = myProject != null + ? (EditorEx)factory.createEditor(myDocument, myProject) + : (EditorEx)factory.createEditor(myDocument); + } + else { + editor = myProject != null + ? (EditorEx)factory.createViewer(myDocument, myProject) + : (EditorEx)factory.createViewer(myDocument); + } + + final EditorSettings settings = editor.getSettings(); + settings.setAdditionalLinesCount(0); + settings.setAdditionalColumnsCount(1); + settings.setRightMarginShown(false); + settings.setFoldingOutlineShown(false); + settings.setLineNumbersShown(false); + settings.setLineMarkerAreaShown(false); + settings.setVirtualSpace(false); + editor.setHorizontalScrollbarVisible(false); + editor.setVerticalScrollbarVisible(false); + settings.setLineCursorWidth(1); + + editor.getColorsScheme().setEditorFontName(getFont().getFontName()); + editor.getColorsScheme().setEditorFontSize(getFont().getSize()); + + if (myProject != null) { + editor.setHighlighter(HighlighterFactory.createHighlighter(myProject, myFileType)); + } + editor.getColorsScheme().setColor(EditorColors.CARET_ROW_COLOR, null); + editor.setOneLineMode(true); + editor.getCaretModel().moveToOffset(myDocument.getTextLength()); + if (!shouldHaveBorder()) { + editor.getScrollPane().setBorder(null); + } + + if (myIsViewer) { + editor.getSelectionModel().removeSelection(); + } + else if (myWholeTextSelected) { + editor.getSelectionModel().setSelection(0, myDocument.getTextLength()); + } + + editor.setBackgroundColor(getBackgroundColor(!myIsViewer)); + return editor; + } + + protected boolean shouldHaveBorder() { + return true; + } + + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + myIsViewer = !enabled; + if (myEditor == null) return; + Editor editor = myEditor; + myEditor = createEditor(); + add(myEditor.getComponent()); + revalidate(); + releaseEditor(editor); + } + + private Color getBackgroundColor(boolean enabled){ + return enabled ? UIManager.getColor("textActiveText") + : UIManager.getColor("textInactiveText"); + } + + public Dimension getPreferredSize() { + if (myEditor != null) return myEditor.getComponent().getPreferredSize(); + return new Dimension(100, 20); + } + + public Component getNextFocusableComponent() { + if (myEditor == null && myNextFocusable == null) return super.getNextFocusableComponent(); + if (myEditor == null) return myNextFocusable; + return myEditor.getContentComponent().getNextFocusableComponent(); + } + + public void setNextFocusableComponent(Component aComponent) { + if (myEditor != null) { + myEditor.getContentComponent().setNextFocusableComponent(aComponent); + return; + } + myNextFocusable = aComponent; + } + + + protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { + if (!myEditor.processKeyTyped(e)) { + return super.processKeyBinding(ks, e, condition, pressed); + } + return true; + } + + + public void requestFocus() { + if (myEditor != null) { + myEditor.getContentComponent().requestFocus(); + myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + else { + super.requestFocus(); + } + } + + public Editor getEditor() { + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/FieldPanelWithChangeSupport.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/FieldPanelWithChangeSupport.java new file mode 100644 index 00000000000..c38840bea26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/FieldPanelWithChangeSupport.java @@ -0,0 +1,15 @@ +package com.intellij.ui; + +import com.intellij.openapi.options.BaseConfigurableWithChangeSupport; + +public class FieldPanelWithChangeSupport { + public static AbstractFieldPanel createPanel(AbstractFieldPanel panel, final BaseConfigurableWithChangeSupport configurable) { + panel.setChangeListener(new Runnable() { + public void run() { + configurable.fireStateChanged(); + } + }); + return panel; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Focusable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Focusable.java new file mode 100644 index 00000000000..67e9d684014 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Focusable.java @@ -0,0 +1,8 @@ +package com.intellij.ui; + +/** + * @author dsl + */ +public interface Focusable { + void requestFocusInWindow(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HeavyweightHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HeavyweightHint.java new file mode 100644 index 00000000000..f281553fc3c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HeavyweightHint.java @@ -0,0 +1,99 @@ +package com.intellij.ui; + +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.util.EventListener; +import java.util.EventObject; + +public class HeavyweightHint implements Hint { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.LightweightHint"); + + private final JComponent myComponent; + private final boolean myFocusableWindowState; + private final EventListenerList myListenerList; + + private JWindow myWindow; + + public HeavyweightHint(final JComponent component) { + this(component, true); + } + + public HeavyweightHint(final JComponent component, final boolean focusableWindowState) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + myComponent = component; + myFocusableWindowState = focusableWindowState; + myListenerList = new EventListenerList(); + } + + /** + * Shows the hint as the window + */ + public void show(JComponent parentComponent, int x, int y, JComponent focusBackComponent) { + Dimension preferredSize = myComponent.getPreferredSize(); + + LOG.assertTrue(parentComponent.isShowing()); + + Window windowAncestor = SwingUtilities.getWindowAncestor(parentComponent); + LOG.assertTrue(windowAncestor != null); + + myWindow = new JWindow(windowAncestor); + myWindow.setFocusableWindowState(myFocusableWindowState); + + Point locationOnScreen = parentComponent.getLocationOnScreen(); + + myWindow.getContentPane().setLayout(new BorderLayout()); + myWindow.getContentPane().add(myComponent, BorderLayout.CENTER); + myWindow.setBounds(locationOnScreen.x + x, locationOnScreen.y + y, preferredSize.width, preferredSize.height); + myWindow.pack(); + myWindow.show(); + } + + protected void fireHintHidden() { + final EventListener[] listeners = myListenerList.getListeners(HintListener.class); + for (int i = 0; i < listeners.length; i++) { + HintListener listener = (HintListener)listeners[i]; + listener.hintHidden(new EventObject(this)); + } + } + + public Dimension getPreferredSize(){ + return myComponent.getPreferredSize(); + } + + public boolean isVisible() { + return myComponent.isShowing(); + } + + /** + * @return location of the hint on the screen. It's allowed to invoke this method + * only if hind is visible. + */ + public Point getLocationOnScreen(){ + LOG.assertTrue(myWindow.isShowing()); + return myWindow.getLocationOnScreen(); + } + + /** + * Hides and disposes hint window + */ + public void hide() { + if(myWindow != null){ + myWindow.dispose(); + myWindow = null; + } + fireHintHidden(); + } + + public void addHintListener(HintListener listener) { + myListenerList.add(HintListener.class, listener); + } + + public void removeHintListener(HintListener listener) { + myListenerList.remove(HintListener.class, listener); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableCellRenderer.java new file mode 100644 index 00000000000..5e347cf72cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableCellRenderer.java @@ -0,0 +1,35 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.tree.TreeCellRenderer; +import java.awt.*; + +public class HighlightableCellRenderer extends HighlightableComponent implements TreeCellRenderer, ListCellRenderer { + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus + ) { + setText(tree.convertValueToText(value, selected, expanded, leaf, row, hasFocus)); + setFont(UIManager.getFont("Tree.font")); + setIcon(null); + + myIsSelected = selected; + myHasFocus = hasFocus; + return this; + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + setText((value == null) ? "" : value.toString()); + setFont(UIManager.getFont("List.font")); + setIcon(null); + + myIsSelected = isSelected; + myHasFocus = cellHasFocus; + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableComponent.java new file mode 100644 index 00000000000..d5888e71b4d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HighlightableComponent.java @@ -0,0 +1,371 @@ +package com.intellij.ui; + +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.ui.plaf.beg.BegTreeHandleUtil; +import gnu.trove.TIntObjectHashMap; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev + */ +public class HighlightableComponent extends JComponent { + protected String myText = ""; + protected Icon myIcon; + protected int myIconTextGap; + protected ArrayList myHighlightedRegions; + protected TIntObjectHashMap myFontMetrics; + protected boolean myIsSelected; + protected boolean myHasFocus; + + public HighlightableComponent() { + myIconTextGap = 4; + myFontMetrics = new TIntObjectHashMap(); + setText(""); + fillFontMetricsMap(); + setOpaque(true); + } + + protected void fillFontMetricsMap() { + Font font = getFont(); + if (font != null){ + myFontMetrics.put(Font.PLAIN, getFontMetrics(font.deriveFont(Font.PLAIN))); + myFontMetrics.put(Font.BOLD, getFontMetrics(font.deriveFont(Font.BOLD))); + myFontMetrics.put(Font.ITALIC, getFontMetrics(font.deriveFont(Font.ITALIC))); + myFontMetrics.put(Font.BOLD | Font.ITALIC, getFontMetrics(font.deriveFont(Font.BOLD | Font.ITALIC))); + } + } + + public void setText(String text) { + if (text == null) { + text = ""; + } + myText = text; + myHighlightedRegions = new ArrayList(4); + } + + public void setIcon(Icon icon) { + myIcon = icon; + } + + public void setFont(Font font) { + if (!font.equals(getFont())){ + super.setFont(font); + fillFontMetricsMap(); + } + } + + public void addHighlighter(int startOffset, int endOffset, TextAttributes attributes) { + addHighlighter(0, startOffset, endOffset, attributes); + } + + private void addHighlighter(int startIndex, int startOffset, int endOffset, TextAttributes attributes) { + if (startOffset < 0) startOffset = 0; + if (endOffset > myText.length()) endOffset = myText.length(); + + if (startOffset >= endOffset) return; + + if (myHighlightedRegions.size() == 0){ + myHighlightedRegions.add(new HighlightedRegion(startOffset, endOffset, attributes)); + } + else{ + for(int i = startIndex; i < myHighlightedRegions.size(); i++){ + HighlightedRegion hRegion = (HighlightedRegion)myHighlightedRegions.get(i); + + // must be before + if (startOffset < hRegion.startOffset && endOffset <= hRegion.startOffset){ + myHighlightedRegions.add(i, new HighlightedRegion(startOffset, endOffset, attributes)); + break; + } + + // must be after + if (startOffset >= hRegion.endOffset){ + if (i == myHighlightedRegions.size() - 1){ + myHighlightedRegions.add(new HighlightedRegion(startOffset, endOffset, attributes)); + break; + } + } + + // must be before and overlap + if (startOffset < hRegion.startOffset && endOffset > hRegion.startOffset){ + + if (endOffset < hRegion.endOffset){ + myHighlightedRegions.add(i, new HighlightedRegion(startOffset, hRegion.startOffset, attributes)); + myHighlightedRegions.add(i + 1, new HighlightedRegion(hRegion.startOffset, endOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + hRegion.startOffset = endOffset; + break; + } + + if (endOffset == hRegion.endOffset){ + myHighlightedRegions.remove(hRegion); + myHighlightedRegions.add(i, new HighlightedRegion(startOffset, hRegion.startOffset, attributes)); + myHighlightedRegions.add(i + 1, new HighlightedRegion(hRegion.startOffset, endOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + break; + } + + if (endOffset > hRegion.endOffset){ + myHighlightedRegions.remove(hRegion); + myHighlightedRegions.add(i, new HighlightedRegion(startOffset, hRegion.startOffset, attributes)); + myHighlightedRegions.add(i + 1, new HighlightedRegion(hRegion.startOffset, hRegion.endOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + + if (i < myHighlightedRegions.size() - 1){ + addHighlighter(i + 1, hRegion.endOffset, endOffset, attributes); + } + else{ + myHighlightedRegions.add(i + 2, new HighlightedRegion(hRegion.endOffset, endOffset, attributes)); + } + break; + } + } + + // must be after and overlap or full overlap + if (startOffset >= hRegion.startOffset && startOffset < hRegion.endOffset){ + + int oldEndOffset = hRegion.endOffset; + + hRegion.endOffset = startOffset; + + if (endOffset < oldEndOffset){ + myHighlightedRegions.add(i + 1, new HighlightedRegion(startOffset, endOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + myHighlightedRegions.add(i + 2, new HighlightedRegion(endOffset, oldEndOffset, hRegion.textAttributes)); + + if (startOffset == hRegion.startOffset){ + myHighlightedRegions.remove(hRegion); + } + + break; + } + + if (endOffset == oldEndOffset){ + myHighlightedRegions.add(i + 1, new HighlightedRegion(startOffset, oldEndOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + + if (startOffset == hRegion.startOffset){ + myHighlightedRegions.remove(hRegion); + } + + break; + } + + if (endOffset > oldEndOffset){ + myHighlightedRegions.add(i + 1, new HighlightedRegion(startOffset, oldEndOffset, TextAttributes.merge(hRegion.textAttributes, attributes))); + if (i < myHighlightedRegions.size() - 1){ + addHighlighter(i + 1, oldEndOffset, endOffset, attributes); + } + else{ + myHighlightedRegions.add(i + 2, new HighlightedRegion(hRegion.endOffset, endOffset, attributes)); + } + + if (startOffset == hRegion.startOffset){ + myHighlightedRegions.remove(hRegion); + } + + break; + } + } + } + } + } + + public void setIconTextGap(int gap) { + myIconTextGap = Math.max(gap, 2); + } + + public int getIconTextGap() { + return myIconTextGap; + } + + private Color myEnforcedBackground = null; + protected void enforceBackgroundOutsideText(Color bg) { + myEnforcedBackground = bg; + } + + protected void paintComponent(Graphics g) { + + // determine color of background + + Color bgColor; + Color fgColor; + boolean paintHighlightsBackground; + boolean paintHighlightsForeground; + if (myIsSelected && myHasFocus) { + bgColor = UIManager.getColor("Tree.selectionBackground"); + fgColor = UIManager.getColor("Tree.selectionForeground"); + paintHighlightsBackground = false; + paintHighlightsForeground = false; + } + else { + bgColor = myEnforcedBackground == null ? UIManager.getColor("Tree.textBackground") : myEnforcedBackground; + fgColor = getForeground(); + paintHighlightsBackground = isOpaque(); + paintHighlightsForeground = true; + } + + // paint background + + int textOffset = getTextOffset(); + int offset = textOffset; + + if (isOpaque()) { + g.setColor(getBackground()); + g.fillRect(0,0,textOffset-2,getHeight()-1); + g.setColor(bgColor); + g.fillRect(textOffset-2, 0, getWidth()-1, getHeight()-1); + } + + // paint icon + + if (myIcon != null) { + myIcon.paintIcon(this, g, 0, (getHeight() - myIcon.getIconHeight()) / 2); + } + + // paint text + + FontMetrics defFontMetrics = getFontMetrics(getFont()); + + if (myText == null) { + myText = ""; + } + // center text inside the component: + final int yOffset = (getHeight() - defFontMetrics.getMaxAscent() - defFontMetrics.getMaxDescent()) / 2 + defFontMetrics.getMaxAscent() - 1; + if (myHighlightedRegions.size() == 0){ + g.setColor(fgColor); + g.drawString(myText, textOffset, yOffset/*defFontMetrics.getMaxAscent()*/); + } + else{ + int endIndex = 0; + for(int i = 0; i < myHighlightedRegions.size(); i++){ + HighlightedRegion hRegion = (HighlightedRegion)myHighlightedRegions.get(i); + + String text = myText.substring(endIndex, hRegion.startOffset); + endIndex = hRegion.endOffset; + + // draw plain text + + if (text.length() != 0){ + g.setColor(fgColor); + g.setFont(defFontMetrics.getFont()); + + g.drawString(text, offset, yOffset/*defFontMetrics.getMaxAscent()*/); + + offset += defFontMetrics.stringWidth(text); + } + + FontMetrics fontMetrics = (FontMetrics)myFontMetrics.get(hRegion.textAttributes.getFontType()); + + text = myText.substring(hRegion.startOffset, hRegion.endOffset); + + // paint highlight background + + if (hRegion.textAttributes.getBackgroundColor() != null && paintHighlightsBackground){ + g.setColor(hRegion.textAttributes.getBackgroundColor()); + g.fillRect(offset, 0, fontMetrics.stringWidth(text), fontMetrics.getHeight() + fontMetrics.getLeading()); + } + + // draw highlight text + + if (hRegion.textAttributes.getForegroundColor() != null && paintHighlightsForeground){ + g.setColor(hRegion.textAttributes.getForegroundColor()); + } + else{ + g.setColor(fgColor); + } + + g.setFont(fontMetrics.getFont()); + g.drawString(text, offset, yOffset/*fontMetrics.getMaxAscent()*/); + + // draw highlight underscored line + + if (hRegion.textAttributes.getEffectColor() != null){ + g.setColor(hRegion.textAttributes.getEffectColor()); + int y = yOffset/*fontMetrics.getMaxAscent()*/ + 2; + g.drawLine(offset, y, offset + fontMetrics.stringWidth(text) - 1, y); + } + + // draw highlight border + + if (hRegion.textAttributes.getEffectColor() != null && hRegion.textAttributes.getEffectType() == EffectType.BOXED){ + g.setColor(hRegion.textAttributes.getEffectColor()); + g.drawRect(offset, 0, fontMetrics.stringWidth(text) - 1, + fontMetrics.getHeight() + fontMetrics.getLeading() - 1); + } + + offset += fontMetrics.stringWidth(text); + } + + String text = myText.substring(endIndex, myText.length()); + + if (text.length() != 0){ + g.setColor(fgColor); + g.setFont(defFontMetrics.getFont()); + + g.drawString(text, offset, yOffset/*defFontMetrics.getMaxAscent()*/); + } + } + + // paint border + + if (myIsSelected){ + g.setColor(UIManager.getColor("Tree.selectionBorderColor")); + BegTreeHandleUtil.drawDottedRectangle(g, textOffset - 2, 0, getWidth() - 1, getHeight() - 1); + } + + super.paintComponent(g); + } + + private int getTextOffset() { + if (myIcon == null){ + return 2; + } + return myIcon.getIconWidth() + myIconTextGap; + } + + public Dimension getPreferredSize() { + FontMetrics defFontMetrics = getFontMetrics(getFont()); + + int width = getTextOffset(); + + if (myText.length() != 0){ + if (myHighlightedRegions.size() == 0){ + width += defFontMetrics.stringWidth(myText); + } + else{ + int endIndex = 0; + for(int i = 0; i < myHighlightedRegions.size(); i++){ + HighlightedRegion hRegion = (HighlightedRegion)myHighlightedRegions.get(i); + + String text = myText.substring(endIndex, hRegion.startOffset); + endIndex = hRegion.endOffset; + + width += defFontMetrics.stringWidth(text); + + if(hRegion.endOffset>myText.length()){ + if(hRegion.startOffsetnull. + * + * @param x x coordinate of hint in parent coordinate system + * + * @param y y coordinate of hint in parent coordinate system + * + * @param focusBackComponent component which should get focus when the hint will + * be hidden. If null then the hint doesn't manage focus after closing. + */ + void show(JComponent parentComponent, int x, int y, JComponent focusBackComponent); + + /** + * @return whether the hint is showing or not + */ + boolean isVisible(); + + void hide(); + + void addHintListener(HintListener listener); + + void removeHintListener(HintListener listener); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HintListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HintListener.java new file mode 100644 index 00000000000..a715cd769fb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HintListener.java @@ -0,0 +1,11 @@ +package com.intellij.ui; + +import java.util.EventListener; +import java.util.EventObject; + +/** + * @author mike + */ +public interface HintListener extends EventListener{ + void hintHidden(EventObject event); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HorizontalLabeledIcon.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HorizontalLabeledIcon.java new file mode 100644 index 00000000000..552f12bc345 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HorizontalLabeledIcon.java @@ -0,0 +1,108 @@ +package com.intellij.ui; + +import com.intellij.util.text.StringTokenizer; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +public class HorizontalLabeledIcon implements Icon { + private final Icon myIcon; + private final String[] myStrings; + private final String myMnemonic; + + /** + * @param icon not null icon. + * @param text to be painted under the icon. This parameter can + * be null if text isn't specified. In that case LabeledIcon + */ + public HorizontalLabeledIcon(Icon icon, String text, String mnemonic) { + myIcon = icon; + if (text != null) { + StringTokenizer tokenizer = new StringTokenizer(text, "\n"); + myStrings = new String[tokenizer.countTokens()]; + for (int i = 0; tokenizer.hasMoreTokens(); i++) { + myStrings[i] = tokenizer.nextToken(); + } + } + else { + myStrings = null; + } + myMnemonic = mnemonic; + } + + public int getIconHeight() { + return Math.max(myIcon.getIconHeight(), getTextHeight()); + } + + public int getIconWidth() { + return myIcon.getIconWidth() + getTextWidth() + 5; + } + + private int getTextHeight() { + if (myStrings != null) { + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + return fontMetrics.getHeight() * myStrings.length; + } + else { + return 0; + } + } + + private int getTextWidth() { + if (myStrings != null) { + int width = 0; + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + for (int i = 0; i < myStrings.length; i++) { + String string = myStrings[i]; + if (myMnemonic != null && i == myStrings.length-1) { + string += " "+myMnemonic; + } + width = Math.max(width, fontMetrics.stringWidth(string)); + } + + return width; + } + else { + return 0; + } + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + // Draw icon + int height = getIconHeight(); + int iconHeight = myIcon.getIconHeight(); + if (height > iconHeight) { + myIcon.paintIcon(c, g, x, y + (height - iconHeight) / 2); + } + else { + myIcon.paintIcon(c, g, x, y); + } + + // Draw text + if (myStrings != null) { + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + g.setFont(fontMetrics.getFont()); + g.setColor(UIManager.getColor("Label.foreground")); + + x += myIcon.getIconWidth() + 5; + y += (height - getTextHeight()) / 2 + fontMetrics.getHeight() - fontMetrics.getDescent(); + for (int i = 0; i < myStrings.length; i++) { + String string = myStrings[i]; + g.drawString(string, x, y); + y += fontMetrics.getHeight(); + } + if (myMnemonic != null) { + g.setColor(UIManager.getColor("textInactiveText")); + int offset = fontMetrics.stringWidth(myStrings[myStrings.length-1]+" "); + y -= fontMetrics.getHeight(); + g.drawString(myMnemonic, x + offset, y); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HoverHyperlinkLabel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HoverHyperlinkLabel.java new file mode 100644 index 00000000000..a9341f2260c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HoverHyperlinkLabel.java @@ -0,0 +1,76 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.plaf.basic.BasicHTML; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev + */ +public class HoverHyperlinkLabel extends JLabel { + private String myOriginalText; + private ArrayList myListeners = new ArrayList(); + + public HoverHyperlinkLabel(String text) { + this(text, Color.BLUE); + } + + public HoverHyperlinkLabel(String text, Color color) { + super(text); + myOriginalText = text; + setForeground(color); + setupListener(); + } + + private void setupListener() { + addMouseListener(new MouseHandler()); + } + + public void setText(String text) { + if (BasicHTML.isHTMLString(getText())) { // if is currently showing string as html + super.setText("" + text + ""); + } + else { + super.setText(text); + } + myOriginalText = text; + } + + public String getOriginalText() { + return myOriginalText; + } + + private class MouseHandler extends MouseAdapter { + public void mouseClicked(MouseEvent e) { + HyperlinkListener[] listeners = myListeners.toArray(new HyperlinkListener[myListeners.size()]); + HyperlinkEvent event = new HyperlinkEvent(HoverHyperlinkLabel.this, HyperlinkEvent.EventType.ACTIVATED, null); + for (int i = 0; i < listeners.length; i++) { + HyperlinkListener listener = listeners[i]; + listener.hyperlinkUpdate(event); + } + } + + public void mouseEntered(MouseEvent e) { + HoverHyperlinkLabel.super.setText("" + myOriginalText + ""); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void mouseExited(MouseEvent e) { + HoverHyperlinkLabel.super.setText(myOriginalText); + setCursor(Cursor.getDefaultCursor()); + } + } + + public void addHyperlinkListener(HyperlinkListener listener) { + myListeners.add(listener); + } + + public void removeHyperlinkListener(HyperlinkListener listener) { + myListeners.remove(listener); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HyperlinkLabel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HyperlinkLabel.java new file mode 100644 index 00000000000..11f8998a849 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/HyperlinkLabel.java @@ -0,0 +1,96 @@ +package com.intellij.ui; + +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +/** + * @author Eugene Belyaev + */ +public class HyperlinkLabel extends HighlightableComponent { + private HighlightedText myHighlightedText; + private ArrayList myListeners = new ArrayList(); + private final Color myTextForegroundColor; + private final Color myTextBackgroundColor; + private final Color myTextEffectColor; + + public HyperlinkLabel(String text) { + this(text, Color.BLUE, UIManager.getColor("Label.background"), Color.BLUE); + } + + public HyperlinkLabel(String text, final Color textForegroundColor, final Color textBackgroundColor, final Color textEffectColor) { + myTextForegroundColor = textForegroundColor; + myTextBackgroundColor = textBackgroundColor; + myTextEffectColor = textEffectColor; + enforceBackgroundOutsideText(textBackgroundColor); + setHyperlinkText(text); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + } + + public void addNotify() { + super.addNotify(); + adjustSize(); + } + + public void setHyperlinkText(String text) { + prepareText(text, myTextForegroundColor, myTextBackgroundColor, myTextEffectColor); + revalidate(); + adjustSize(); + } + + private void adjustSize() { + final Dimension preferredSize = this.getPreferredSize(); + this.setMinimumSize(preferredSize); + } + + + protected void processMouseEvent(MouseEvent e) { + if (e.getID() == MouseEvent.MOUSE_ENTERED) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else if (e.getID() == MouseEvent.MOUSE_EXITED) { + setCursor(Cursor.getDefaultCursor()); + } + else if (e.getID() == MouseEvent.MOUSE_CLICKED) { + fireHyperlinkEvent(); + } + super.processMouseEvent(e); + } + + private void prepareText(String text, final Color textForegroundColor, final Color textBackgroundColor, final Color textEffectColor) { + setFont(UIManager.getFont("Label.font")); + myHighlightedText = new HighlightedText(); + myHighlightedText.appendText(text, new TextAttributes( + textForegroundColor, textBackgroundColor, textEffectColor, EffectType.LINE_UNDERSCORE, Font.PLAIN + )); + myHighlightedText.applyToComponent(this); + adjustSize(); + } + + public void addHyperlinkListener(HyperlinkListener listener) { + myListeners.add(listener); + } + + public void removeHyperlinkListener(HyperlinkListener listener) { + myListeners.remove(listener); + } + + String getText() { + return myHighlightedText.getText(); + } + + protected void fireHyperlinkEvent() { + HyperlinkEvent e = new HyperlinkEvent(this, HyperlinkEvent.EventType.ACTIVATED, null, null); + HyperlinkListener[] listeners = (HyperlinkListener[]) myListeners.toArray(new HyperlinkListener[myListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + HyperlinkListener listener = listeners[i]; + listener.hyperlinkUpdate(e); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeGraphics2D.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeGraphics2D.java new file mode 100644 index 00000000000..9654635f815 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeGraphics2D.java @@ -0,0 +1,312 @@ +package com.intellij.ui; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.awt.font.GlyphVector; +import java.awt.font.FontRenderContext; +import java.util.Map; +import java.text.AttributedCharacterIterator; + +/** + * @author Vladimir Kondratyev + */ +public class IdeGraphics2D extends Graphics2D{ + private Graphics2D myDelegate; + + public IdeGraphics2D(Graphics2D g2d){ + myDelegate=g2d; + setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + + public void addRenderingHints(Map hints) { + myDelegate.addRenderingHints(hints); + } + + public void clearRect(int x, int y, int width, int height) { + myDelegate.clearRect(x, y, width, height); + } + + public void clip(Shape s) { + myDelegate.clip(s); + } + + public void clipRect(int x, int y, int width, int height) { + myDelegate.clipRect(x, y, width, height); + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + myDelegate.copyArea(x, y, width, height, dx, dy); + } + + public Graphics create() { + return new IdeGraphics2D((Graphics2D)myDelegate.create()); + } + + public void dispose() { + myDelegate.dispose(); + } + + public void draw(Shape s) { + myDelegate.draw(s); + } + + public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + myDelegate.drawArc(x, y, width, height, startAngle, arcAngle); + } + + public void drawGlyphVector(GlyphVector g, float x, float y) { + myDelegate.drawGlyphVector(g, x, y); + } + + public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { + myDelegate.drawImage(img, op, x, y); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { + return myDelegate.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + return myDelegate.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer); + } + + public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { + return myDelegate.drawImage(img, x, y, bgcolor, observer); + } + + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + return myDelegate.drawImage(img, x, y, observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { + return myDelegate.drawImage(img, x, y, width, height, bgcolor, observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { + return myDelegate.drawImage(img, x, y, width, height, observer); + } + + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { + return myDelegate.drawImage(img, xform, obs); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + myDelegate.drawLine(x1, y1, x2, y2); + } + + public void drawOval(int x, int y, int width, int height) { + myDelegate.drawOval(x, y, width, height); + } + + public void drawPolygon(int xPoints[], int yPoints[], int nPoints) { + myDelegate.drawPolygon(xPoints, yPoints, nPoints); + } + + public void drawPolyline(int xPoints[], int yPoints[], int nPoints) { + myDelegate.drawPolyline(xPoints, yPoints, nPoints); + } + + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + myDelegate.drawRenderableImage(img, xform); + } + + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + myDelegate.drawRenderedImage(img, xform); + } + + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + myDelegate.drawRoundRect(x, y, width, height, arcWidth, arcHeight); + } + + public void drawString(AttributedCharacterIterator iterator, float x, float y) { + myDelegate.drawString(iterator, x, y); + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + myDelegate.drawString(iterator, x, y); + } + + public void drawString(String s, float x, float y) { + myDelegate.drawString(s, x, y); + } + + public void drawString(String str, int x, int y) { + myDelegate.drawString(str, x, y); + } + + public void fill(Shape s) { + myDelegate.fill(s); + } + + public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + myDelegate.fillArc(x, y, width, height, startAngle, arcAngle); + } + + public void fillOval(int x, int y, int width, int height) { + myDelegate.fillOval(x, y, width, height); + } + + public void fillPolygon(int xPoints[], int yPoints[], int nPoints) { + myDelegate.fillPolygon(xPoints, yPoints, nPoints); + } + + public void fillRect(int x, int y, int width, int height) { + myDelegate.fillRect(x, y, width, height); + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + myDelegate.fillRoundRect(x, y, width, height, arcWidth, arcHeight); + } + + public Color getBackground() { + return myDelegate.getBackground(); + } + + public Shape getClip() { + return myDelegate.getClip(); + } + + public Rectangle getClipBounds() { + return myDelegate.getClipBounds(); + } + + public Color getColor() { + return myDelegate.getColor(); + } + + public Composite getComposite() { + return myDelegate.getComposite(); + } + + public GraphicsConfiguration getDeviceConfiguration() { + return myDelegate.getDeviceConfiguration(); + } + + public Font getFont() { + return myDelegate.getFont(); + } + + public FontMetrics getFontMetrics(Font f) { + return myDelegate.getFontMetrics(f); + } + + public FontRenderContext getFontRenderContext() { + return myDelegate.getFontRenderContext(); + } + + public Paint getPaint() { + return myDelegate.getPaint(); + } + + public Object getRenderingHint(RenderingHints.Key hintKey) { + return myDelegate.getRenderingHint(hintKey); + } + + public RenderingHints getRenderingHints() { + return myDelegate.getRenderingHints(); + } + + public Stroke getStroke() { + return myDelegate.getStroke(); + } + + public AffineTransform getTransform() { + return myDelegate.getTransform(); + } + + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + return myDelegate.hit(rect, s, onStroke); + } + + public void rotate(double theta) { + myDelegate.rotate(theta); + } + + public void rotate(double theta, double x, double y) { + myDelegate.rotate(theta, x, y); + } + + public void scale(double sx, double sy) { + myDelegate.scale(sx, sy); + } + + public void setBackground(Color color) { + myDelegate.setBackground(color); + } + + public void setClip(Shape sh) { + myDelegate.setClip(sh); + } + + public void setClip(int x, int y, int w, int h) { + myDelegate.setClip(x, y, w, h); + } + + public void setColor(Color color) { + myDelegate.setColor(color); + } + + public void setComposite(Composite comp) { + myDelegate.setComposite(comp); + } + + public void setFont(Font font) { + myDelegate.setFont(font); + } + + public void setPaint(Paint paint) { + myDelegate.setPaint(paint); + } + + public void setPaintMode() { + myDelegate.setPaintMode(); + } + + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { + myDelegate.setRenderingHint(hintKey, hintValue); + } + + public void setRenderingHints(Map hints) { + myDelegate.setRenderingHints(hints); + } + + /* + * Sets the Stroke in the current graphics state. + * @param s The Stroke object to be used to stroke a Path in + * the rendering process. + * @see BasicStroke + */ + public void setStroke(Stroke s) { + myDelegate.setStroke(s); + } + + public void setTransform(AffineTransform Tx) { + myDelegate.setTransform(Tx); + } + + public void setXORMode(Color c) { + myDelegate.setXORMode(c); + } + + public void shear(double shx, double shy) { + myDelegate.shear(shx, shy); + } + + public void transform(AffineTransform xform) { + myDelegate.transform(xform); + } + + public void translate(double tx, double ty) { + myDelegate.translate(tx, ty); + } + + public void translate(int x, int y) { + myDelegate.translate(x, y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeaBlueMetalTheme.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeaBlueMetalTheme.java new file mode 100644 index 00000000000..cd132420b7b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/IdeaBlueMetalTheme.java @@ -0,0 +1,66 @@ + +package com.intellij.ui; + +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.metal.DefaultMetalTheme; +import java.awt.*; + +public class IdeaBlueMetalTheme extends DefaultMetalTheme { + public String getName() { + return "beg blue"; + } + + private static ColorUIResource darkGray = new ColorUIResource(132, 130, 132); + private static ColorUIResource white = new ColorUIResource(255, 255, 255); + private static ColorUIResource darkBlue = new ColorUIResource(82, 108, 164); +// private static ColorUIResource lightGray = new ColorUIResource(214, 211, 206); + private static ColorUIResource lightGray = new ColorUIResource(214, 214, 214); + + public ColorUIResource getControl() { + return lightGray; + } + + public ColorUIResource getSeparatorBackground() { + return white; + } + + public ColorUIResource getSeparatorForeground() { + return darkGray; + } + + public ColorUIResource getMenuBackground() { + return lightGray; + } + + public ColorUIResource getMenuSelectedBackground() { + return darkBlue; + } + + public ColorUIResource getMenuSelectedForeground() { + return white; + } + + public ColorUIResource getAcceleratorSelectedForeground() { + return white; + } + + public static final ColorUIResource primary1 = new ColorUIResource(10, 36, 106); + private static final ColorUIResource primary2 = new ColorUIResource(91, 135, 206); + private static final ColorUIResource primary3 = new ColorUIResource(166, 202, 240); + + public ColorUIResource getFocusColor() { + return new ColorUIResource(Color.black); + } + + protected ColorUIResource getPrimary1() { + return primary1; + } + + protected ColorUIResource getPrimary2() { + return primary2; + } + + protected ColorUIResource getPrimary3() { + return primary3; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LabeledIcon.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LabeledIcon.java new file mode 100644 index 00000000000..357badaffc6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LabeledIcon.java @@ -0,0 +1,108 @@ +package com.intellij.ui; + +import com.intellij.util.text.StringTokenizer; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +public class LabeledIcon implements Icon { + private final Icon myIcon; + private String myMnemonic; + private final String[] myStrings; + + /** + * @param icon not null icon. + * @param text to be painted under the icon. This parameter can + * be null if text isn't specified. In that case LabeledIcon + * @param mnemonic + */ + public LabeledIcon(Icon icon, String text, String mnemonic) { + myIcon = icon; + myMnemonic = mnemonic; + if (text != null) { + StringTokenizer tokenizer = new StringTokenizer(text, "\n"); + myStrings = new String[tokenizer.countTokens()]; + for (int i = 0; tokenizer.hasMoreTokens(); i++) { + myStrings[i] = tokenizer.nextToken(); + } + } + else { + myStrings = null; + } + } + + public int getIconHeight() { + return myIcon.getIconHeight() + getTextHeight() + 0/*gap between icon and text*/; + } + + public int getIconWidth() { + return Math.max(myIcon.getIconWidth(), getTextWidth()); + } + + private int getTextHeight() { + if (myStrings != null) { + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + return fontMetrics.getHeight() * myStrings.length; + } + else { + return 0; + } + } + + private int getTextWidth() { + if (myStrings != null) { + int width = 0; + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + for (int i = 0; i < myStrings.length; i++) { + String string = myStrings[i]; + width = fontMetrics.stringWidth(string); + } + + if (myMnemonic != null) width += fontMetrics.stringWidth(myMnemonic); + return width; + } + else { + return 0; + } + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + // Draw icon + int width = getIconWidth(); + int iconWidth = myIcon.getIconWidth(); + if (width > iconWidth) { + myIcon.paintIcon(c, g, x + (width - iconWidth) / 2, y); + } + else { + myIcon.paintIcon(c, g, x, y); + } + // Draw text + if (myStrings != null) { + Font font = UIManager.getFont("Label.font"); + FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + g.setFont(fontMetrics.getFont()); + if (myMnemonic != null) { + width -= fontMetrics.stringWidth(myMnemonic); + } + g.setColor(UIManager.getColor("Label.foreground")); + y += myIcon.getIconHeight() + fontMetrics.getMaxAscent() + 0/*gap beween icon and text*/; + for (int i = 0; i < myStrings.length; i++) { + String string = myStrings[i]; + g.drawString(string, x + (width - fontMetrics.stringWidth(string)) / 2, y); + y += fontMetrics.getHeight(); + } + + if (myMnemonic != null) { + y -= fontMetrics.getHeight(); + g.setColor(UIManager.getColor("textInactiveText")); + int offset = getTextWidth() - fontMetrics.stringWidth(myMnemonic); + g.drawString(myMnemonic, x + offset, y); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LightweightHint.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LightweightHint.java new file mode 100644 index 00000000000..eda48d72ffe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/LightweightHint.java @@ -0,0 +1,151 @@ +package com.intellij.ui; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.UserDataHolder; +import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; +import gnu.trove.THashMap; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.EventListener; +import java.util.EventObject; + +public class LightweightHint implements Hint, UserDataHolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.LightweightHint"); + + private final JComponent myComponent; + private JComponent myFocusBackComponent; + private final THashMap myUserMap = new THashMap(1); + private final EventListenerList myListenerList = new EventListenerList(); + private MyEscListener myEscListener; + + public LightweightHint(final JComponent component) { + LOG.assertTrue(component != null); + myComponent = component; + } + + /** + * Shows the hint in the layered pane. Coordinates x and y + * are in parentComponent coordinate system. Note that the component + * appears on 250 layer. + */ + public void show(final JComponent parentComponent, final int x, final int y, final JComponent focusBackComponent) { + LOG.assertTrue(parentComponent != null); + + myFocusBackComponent = focusBackComponent; + + final Dimension preferredSize = myComponent.getPreferredSize(); + + LOG.assertTrue(parentComponent.isShowing()); + myEscListener = new MyEscListener(); + myComponent.registerKeyboardAction(myEscListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + final JLayeredPane layeredPane = parentComponent.getRootPane().getLayeredPane(); + final Point layeredPanePoint = SwingUtilities.convertPoint(parentComponent, x, y, layeredPane); + + myComponent.setBounds(layeredPanePoint.x, layeredPanePoint.y, preferredSize.width, preferredSize.height); + + layeredPane.add(myComponent, new Integer(250 + layeredPane.getComponentCount())); + + myComponent.validate(); + myComponent.repaint(); + } + + private void fireHintHidden() { + final EventListener[] listeners = myListenerList.getListeners(HintListener.class); + for (int i = 0; i < listeners.length; i++) { + final HintListener listener = (HintListener)listeners[i]; + listener.hintHidden(new EventObject(this)); + } + } + + /** + * Sets location of the hint in the layered pane coordinate system. + */ + public final void setLocation(final int x, final int y) { + myComponent.setLocation(x, y); + myComponent.validate(); + myComponent.repaint(); + } + + /** + * x and y are in layered pane coordinate system + */ + public final void setBounds(final int x, final int y, final int width, final int height) { + myComponent.setBounds(x, y, width, height); + myComponent.setLocation(x, y); + myComponent.validate(); + myComponent.repaint(); + } + + /** + * @return bounds of hint component in the layered pane. + */ + public final Rectangle getBounds() { + return myComponent.getBounds(); + } + + public boolean isVisible() { + return myComponent.isShowing(); + } + + public void hide() { + if (isVisible()) { + final Rectangle bounds = myComponent.getBounds(); + final JLayeredPane layeredPane = myComponent.getRootPane().getLayeredPane(); + + try { + if(myFocusBackComponent != null){ + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(myFocusBackComponent); + } + layeredPane.remove(myComponent); + } + finally { + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(null); + } + layeredPane.paintImmediately(bounds.x, bounds.y, bounds.width, bounds.height); + } + if (myEscListener != null) { + myComponent.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); + } + fireHintHidden(); + } + + public final JComponent getComponent() { + return myComponent; + } + + public T getUserData(final Key key) { + return (T)myUserMap.get(key); + } + + public void putUserData(final Key key, final T value) { + if (value != null) { + myUserMap.put(key, value); + } + else { + myUserMap.remove(key); + } + } + + public final void addHintListener(final HintListener listener) { + myListenerList.add(HintListener.class, listener); + } + + public final void removeHintListener(final HintListener listener) { + myListenerList.remove(HintListener.class, listener); + } + + private final class MyEscListener implements ActionListener { + public final void actionPerformed(final ActionEvent e) { + LightweightHint.this.hide(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListSpeedSearch.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListSpeedSearch.java new file mode 100644 index 00000000000..82c1122aa5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListSpeedSearch.java @@ -0,0 +1,35 @@ +package com.intellij.ui; + +import javax.swing.*; + +public class ListSpeedSearch extends SpeedSearchBase { + public ListSpeedSearch(JList list) { + super(list); + } + + protected void selectElement(Object element, String selectedText) { + ListScrollingUtil.selectItem(myComponent, element); + } + + protected int getSelectedIndex() { + return myComponent.getSelectedIndex(); + } + + protected Object[] getAllElements() { + ListModel model = myComponent.getModel(); + if (model instanceof DefaultListModel){ // optimization + return ((DefaultListModel)model).toArray(); + } + else{ + Object[] elements = new Object[model.getSize()]; + for(int i = 0; i < elements.length; i++){ + elements[i] = model.getElementAt(i); + } + return elements; + } + } + + protected String getElementText(Object element) { + return element.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListToolTipHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListToolTipHandler.java new file mode 100644 index 00000000000..7f73aac6b5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListToolTipHandler.java @@ -0,0 +1,74 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; + +public final class ListToolTipHandler extends AbstractToolTipHandler{ + public ListToolTipHandler(JList list) { + super(list); + + list.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + repaintHint(); + } + } + ); + + list.getModel().addListDataListener( + new ListDataListener() { + public void intervalAdded(ListDataEvent e) { + hideHint(); + } + + public void intervalRemoved(ListDataEvent e) { + hideHint(); + } + + public void contentsChanged(ListDataEvent e) { + hideHint(); + } + } + ); + } + + /** + * @return java.lang.Integer which rpresent index of the row under the + * specified point + */ + protected Integer getCellKeyForPoint(Point point) { + int rowIndex = myComponent.locationToIndex(point); + return rowIndex != -1 ? new Integer(rowIndex) : null; + } + + protected Rectangle getCellBounds(Integer key, Component rendererComponent) { + int rowIndex = key.intValue(); + Rectangle cellBounds = myComponent.getCellBounds(rowIndex, rowIndex); + cellBounds.width = rendererComponent.getPreferredSize().width; + return cellBounds; + } + + protected Component getRendererComponent(Integer key) { + ListCellRenderer renderer = myComponent.getCellRenderer(); + if (renderer == null) { + return null; + } + ListModel model = myComponent.getModel(); + int rowIndex = key.intValue(); + if (rowIndex >= model.getSize()) { + return null; + } + + return renderer.getListCellRendererComponent( + myComponent, + model.getElementAt(rowIndex), + rowIndex, + myComponent.isSelectedIndex(rowIndex), + myComponent.hasFocus() + ); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListenerUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListenerUtil.java new file mode 100644 index 00000000000..055c19194a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/ListenerUtil.java @@ -0,0 +1,58 @@ +package com.intellij.ui; + +import java.awt.*; +import java.awt.event.MouseListener; +import java.awt.event.FocusListener; +import java.awt.event.KeyListener; + +public class ListenerUtil { + public static void addFocusListener(Component component, FocusListener l) { + component.addFocusListener(l); + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + addFocusListener(container.getComponent(i), l); + } + } + } + + public static void removeFocusListener(Component component, FocusListener l) { + component.removeFocusListener(l); + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + removeFocusListener(container.getComponent(i), l); + } + } + } + + public static void addMouseListener(Component component, MouseListener l) { + component.addMouseListener(l); + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + addMouseListener(container.getComponent(i), l); + } + } + } + + public static void addKeyListener(Component component, KeyListener l) { + component.addKeyListener(l); + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + addKeyListener(container.getComponent(i), l); + } + } + } + + public static void removeKeyListener(Component component, KeyListener l) { + component.removeKeyListener(l); + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + removeKeyListener(container.getComponent(i), l); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultiLineTooltipUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultiLineTooltipUI.java new file mode 100644 index 00000000000..c846177d42f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultiLineTooltipUI.java @@ -0,0 +1,53 @@ +/* + * Class MultiLineTooltipUI + * @author Jeka + */ +package com.intellij.ui; + +import com.intellij.openapi.util.text.LineTokenizer; + +import javax.swing.*; +import javax.swing.plaf.metal.MetalToolTipUI; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; + +public class MultiLineTooltipUI extends MetalToolTipUI { + private java.util.List myLines = new ArrayList(); + + public void paint(Graphics g, JComponent c) { + FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(g.getFont()); + Dimension size = c.getSize(); + g.setColor(c.getBackground()); + g.fillRect(0, 0, size.width, size.height); + g.setColor(c.getForeground()); + int idx = 0; + for (Iterator it = myLines.iterator(); it.hasNext(); idx++) { + String line = (String)it.next(); + g.drawString(line, 3, (metrics.getHeight()) * (idx + 1)); + } + } + + public Dimension getPreferredSize(JComponent c) { + FontMetrics metrics = c.getToolkit().getFontMetrics(c.getFont()); + String tipText = ((JToolTip)c).getTipText(); + if (tipText == null) { + tipText = ""; + } + int maxWidth = 0; + myLines.clear(); + + final String[] lines = LineTokenizer.tokenize(tipText.toCharArray(), false); + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + myLines.add(line); + int width = SwingUtilities.computeStringWidth(metrics, line); + if (width > maxWidth) { + maxWidth = width; + } + } + + int height = metrics.getHeight() * ((lines.length < 1)? 1 : lines.length); + return new Dimension(maxWidth + 6, height + 4); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultilineTreeCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultilineTreeCellRenderer.java new file mode 100644 index 00000000000..d835f990e34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/MultilineTreeCellRenderer.java @@ -0,0 +1,450 @@ +package com.intellij.ui; + +import com.intellij.ui.plaf.beg.BegTreeHandleUtil; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.plaf.TreeUI; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeCellRenderer; +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; + +public abstract class MultilineTreeCellRenderer extends JComponent implements javax.swing.tree.TreeCellRenderer { + + private boolean myWrapsCalculated = false; + private boolean myTooSmall = false; + private int myHeightCalculated = -1; + private int myWrapsCalculatedForWidth = -1; + + private ArrayList myWraps = new ArrayList(); + + private int myMinHeight = 1; + private Insets myTextInsets; + private Insets myLabelInsets = new Insets(1, 2, 1, 2); + + private boolean mySelected; + private boolean myHasFocus; + + private Icon myIcon; + private String[] myLines = ArrayUtil.EMPTY_STRING_ARRAY; + private String myPrefix; + private int myTextLength; + private int myPrefixWidth; + + + public MultilineTreeCellRenderer() { + myTextInsets = new Insets(0,0,0,0); + + addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + onSizeChanged(); + } + }); + + addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if ("font".equalsIgnoreCase(evt.getPropertyName())) { + onFontChanged(); + } + } + }); + + } + + protected void setMinHeight(int height) { + myMinHeight = height; + myHeightCalculated = Math.max(myMinHeight, myHeightCalculated); + } + + protected void setTextInsets(Insets textInsets) { + myTextInsets = textInsets; + onSizeChanged(); + } + + private void onFontChanged() { + myWrapsCalculated = false; + } + + private void onSizeChanged() { + int currWidth = getWidth(); + if (currWidth != myWrapsCalculatedForWidth) { + myWrapsCalculated = false; + myHeightCalculated = -1; + myWrapsCalculatedForWidth = -1; + } + } + + private FontMetrics getCurrFontMetrics() { + return getFontMetrics(getFont()); + } + + public void paint(Graphics g) { + int height = getHeight(); + int width = getWidth(); + int borderX = myLabelInsets.left - 1; + int borderY = myLabelInsets.top - 1; + int borderW = width - borderX - myLabelInsets.right + 2; + int borderH = height - borderY - myLabelInsets.bottom + 1; + + if (myIcon != null) { + int verticalIconPosition = (height - myIcon.getIconHeight())/2; + myIcon.paintIcon(this, g, 0, verticalIconPosition); + borderX += myIcon.getIconWidth(); + borderW -= myIcon.getIconWidth(); + } + + Color bgColor; + Color fgColor; + if (mySelected && myHasFocus){ + bgColor = UIManager.getColor("Tree.selectionBackground"); + fgColor = UIManager.getColor("Tree.selectionForeground"); + } + else{ + bgColor = UIManager.getColor("Tree.textBackground"); + fgColor = getForeground(); + } + + // fill background + g.setColor(bgColor); + g.fillRect(borderX, borderY, borderW, borderH); + + // draw border + if (mySelected) { + g.setColor(UIManager.getColor("Tree.selectionBorderColor")); + BegTreeHandleUtil.drawDottedRectangle(g, borderX, borderY, borderX + borderW - 1, borderY + borderH - 1); + } + + // paint text + recalculateWraps(); + + if (myTooSmall) { // TODO ??? + return; + } + + int fontHeight = getCurrFontMetrics().getHeight(); + int currBaseLine = getCurrFontMetrics().getAscent(); + currBaseLine += myTextInsets.top; + g.setFont(getFont()); + g.setColor(fgColor); + + if (myPrefix != null) { + g.drawString(myPrefix, myTextInsets.left - myPrefixWidth + 1, currBaseLine); + } + + for (int i = 0; i < myWraps.size(); i++) { + String currLine = (String)myWraps.get(i); + g.drawString(currLine, myTextInsets.left, currBaseLine); + currBaseLine += fontHeight; // first is getCurrFontMetrics().getAscent() + } + } + + public void setText(String[] lines, String prefix) { + myLines = lines; + myTextLength = 0; + for (int i = 0; i < lines.length; i++) { + myTextLength += lines[i].length(); + } + myPrefix = prefix; + + myWrapsCalculated = false; + myHeightCalculated = -1; + myWrapsCalculatedForWidth = -1; + } + + public void setIcon(Icon icon) { + myIcon = icon; + + myWrapsCalculated = false; + myHeightCalculated = -1; + myWrapsCalculatedForWidth = -1; + } + + public Dimension getMinimumSize() { + if (getFont() != null) { + int minHeight = getCurrFontMetrics().getHeight(); + return new Dimension(minHeight, minHeight); + } + return new Dimension( + MIN_WIDTH + myTextInsets.left + myTextInsets.right, + MIN_WIDTH + myTextInsets.top + myTextInsets.bottom + ); + } + + private static final int MIN_WIDTH = 10; + + // Calculates height for current width. + public Dimension getPreferredSize() { + recalculateWraps(); + return new Dimension(myWrapsCalculatedForWidth, myHeightCalculated); + } + + // Calculate wraps for the current width + private void recalculateWraps() { + int currwidth = getWidth(); + if (myWrapsCalculated) { + if (currwidth == myWrapsCalculatedForWidth) { + return; + } + else { + myWrapsCalculated = false; + } + } + int wrapsCount = calculateWraps(currwidth); + myTooSmall = (wrapsCount == -1); + if (myTooSmall) { + wrapsCount = myTextLength; + } + int fontHeight = getCurrFontMetrics().getHeight(); + myHeightCalculated = wrapsCount * fontHeight + myTextInsets.top + myTextInsets.bottom; + myHeightCalculated = Math.max(myMinHeight, myHeightCalculated); + + int maxWidth = 0; + for (int i=0; i < myWraps.size(); i++) { + String s = (String)myWraps.get(i); + int width = getCurrFontMetrics().stringWidth(s); + maxWidth = Math.max(maxWidth, width); + } + + myWrapsCalculatedForWidth = myTextInsets.left + maxWidth + myTextInsets.right; + myWrapsCalculated = true; + } + + private int calculateWraps(int width) { + myTooSmall = width < MIN_WIDTH; + if (myTooSmall) { + return -1; + } + + int result = 0; + myWraps = new ArrayList(); + + for (int i = 0; i < myLines.length; i++) { + String aLine = myLines[i]; + int lineFirstChar = 0; + int lineLastChar = aLine.length() - 1; + int currFirst = lineFirstChar; + int printableWidth = width - myTextInsets.left - myTextInsets.right; + if (aLine.length() == 0) { + myWraps.add(aLine); + result++; + } + else { + while (currFirst <= lineLastChar) { + int currLast = calculateLastVisibleChar(aLine, printableWidth, currFirst, lineLastChar); + if (currLast < lineLastChar) { + int currChar = currLast + 1; + if (!Character.isWhitespace(aLine.charAt(currChar))) { + while (currChar >= currFirst) { + if (Character.isWhitespace(aLine.charAt(currChar))) { + break; + } + currChar--; + } + if (currChar > currFirst) { + currLast = currChar; + } + } + } + myWraps.add(aLine.substring(currFirst, currLast + 1)); + currFirst = currLast + 1; + while ((currFirst <= lineLastChar) && (Character.isWhitespace(aLine.charAt(currFirst)))) { + currFirst++; + } + result++; + } + } + } + return result; + } + + private int calculateLastVisibleChar(String line, int viewWidth, int firstChar, int lastChar) { + if (firstChar == lastChar) return lastChar; + if (firstChar > lastChar) throw new IllegalArgumentException("firstChar=" + firstChar + ", lastChar=" + lastChar); + int totalWidth = getCurrFontMetrics().stringWidth(line.substring(firstChar, lastChar + 1)); + if (totalWidth == 0 || viewWidth > totalWidth) { + return lastChar; + } + else { + int newApprox = (lastChar - firstChar + 1) * viewWidth / totalWidth; + int currChar = firstChar + Math.max(newApprox - 1, 0); + int currWidth = getCurrFontMetrics().stringWidth(line.substring(firstChar, currChar + 1)); + while (true) { + if (currWidth > viewWidth) { + currChar--; + if (currChar <= firstChar) { + return firstChar; + } + currWidth -= getCurrFontMetrics().charWidth(line.charAt(currChar + 1)); + if (currWidth <= viewWidth) { + return currChar; + } + } + else { + currChar++; + if (currChar > lastChar) { + return lastChar; + } + currWidth += getCurrFontMetrics().charWidth(line.charAt(currChar)); + if (currWidth >= viewWidth) { + return currChar - 1; + } + } + } + } + } + + private int getChildIndent(JTree tree) { + TreeUI newUI = tree.getUI(); + if (newUI instanceof javax.swing.plaf.basic.BasicTreeUI) { + javax.swing.plaf.basic.BasicTreeUI btreeui = (javax.swing.plaf.basic.BasicTreeUI)newUI; + return btreeui.getLeftChildIndent() + btreeui.getRightChildIndent(); + } + else { + return ((Integer)UIManager.get("Tree.leftChildIndent")).intValue() + ((Integer)UIManager.get("Tree.rightChildIndent")).intValue(); + } + } + + private int getAvailableWidth(Object forValue, JTree tree) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)forValue; + int busyRoom = tree.getInsets().left + tree.getInsets().right + getChildIndent(tree) * node.getLevel(); + return tree.getVisibleRect().width - busyRoom - 2; + } + + protected abstract void initComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus); + + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + setFont(UIManager.getFont("Tree.font")); + + initComponent(tree, value, selected, expanded, leaf, row, hasFocus); + + mySelected = selected; + myHasFocus = hasFocus; + + int availWidth = getAvailableWidth(value, tree); + if (availWidth > 0) { + setSize(availWidth, 100); // height will be calculated automatically + } + + int leftInset = myLabelInsets.left; + + if (myIcon != null) { + leftInset += myIcon.getIconWidth() + 2; + } + + if (myPrefix != null) { + myPrefixWidth = getCurrFontMetrics().stringWidth(myPrefix) + 5; + leftInset += myPrefixWidth; + } + + setTextInsets(new Insets(myLabelInsets.top, leftInset, myLabelInsets.bottom, myLabelInsets.right)); + if (myIcon != null) { + setMinHeight(myIcon.getIconHeight()); + } + else { + setMinHeight(1); + } + + setSize(getPreferredSize()); + recalculateWraps(); + + return this; + } + + public static JScrollPane installRenderer(final JTree tree, final MultilineTreeCellRenderer renderer) { + final TreeCellRenderer defaultRenderer = tree.getCellRenderer(); + + JScrollPane scrollpane = new JScrollPane(tree){ + private int myAddRemoveCounter = 0; + private boolean myShouldResetCaches = false; + public void setSize(Dimension d) { + boolean isChanged = getWidth() != d.width || myShouldResetCaches; + super.setSize(d); + if (isChanged) resetCaches(); + } + + public void reshape(int x, int y, int w, int h) { + boolean isChanged = w != getWidth() || myShouldResetCaches; + super.reshape(x, y, w, h); + if (isChanged) resetCaches(); + } + + private void resetCaches() { + resetHeightCache(tree, defaultRenderer, renderer); + myShouldResetCaches = false; + } + + public void addNotify() { + super.addNotify(); //To change body of overriden methods use Options | File Templates. + if (myAddRemoveCounter == 0) myShouldResetCaches = true; + myAddRemoveCounter++; + } + + public void removeNotify() { + super.removeNotify(); //To change body of overriden methods use Options | File Templates. + myAddRemoveCounter--; + } + }; + scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + tree.setCellRenderer(renderer); + + scrollpane.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + resetHeightCache(tree, defaultRenderer, renderer); + } + + public void componentShown(ComponentEvent e) { + // componentResized not called when adding to opened tool window. + // Seems to be BUG#4765299, however I failed to create same code to reproduce it. + // To reproduce it with IDEA: 1. remove this method, 2. Start any Ant task, 3. Keep message window open 4. start Ant task again. + resetHeightCache(tree, defaultRenderer, renderer); + } + }); + + return scrollpane; + } + + private static void resetHeightCache(final JTree tree, + final TreeCellRenderer defaultRenderer, + final MultilineTreeCellRenderer renderer) { + tree.setCellRenderer(defaultRenderer); + tree.setCellRenderer(renderer); + } + +// private static class DelegatingScrollablePanel extends JPanel implements Scrollable { +// private final Scrollable myDelegatee; +// +// public DelegatingScrollablePanel(Scrollable delegatee) { +// super(new BorderLayout(0, 0)); +// myDelegatee = delegatee; +// add((JComponent)delegatee, BorderLayout.CENTER); +// } +// +// public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { +// return myDelegatee.getScrollableUnitIncrement(visibleRect, orientation, direction); +// } +// +// public boolean getScrollableTracksViewportWidth() { +// return myDelegatee.getScrollableTracksViewportWidth(); +// } +// +// public Dimension getPreferredScrollableViewportSize() { +// return myDelegatee.getPreferredScrollableViewportSize(); +// } +// +// public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { +// return myDelegatee.getScrollableBlockIncrement(visibleRect, orientation, direction); +// } +// +// public boolean getScrollableTracksViewportHeight() { +// return myDelegatee.getScrollableTracksViewportHeight(); +// } +// } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/NonFocusableCheckBox.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/NonFocusableCheckBox.java new file mode 100644 index 00000000000..61caa42effd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/NonFocusableCheckBox.java @@ -0,0 +1,13 @@ +package com.intellij.ui; + +import javax.swing.*; + +/** + * @author dsl + */ +public class NonFocusableCheckBox extends JCheckBox { + public NonFocusableCheckBox(String text) { + super(text); + setFocusable(false); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/OneSideRoundedLineBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/OneSideRoundedLineBorder.java new file mode 100644 index 00000000000..350a98c71d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/OneSideRoundedLineBorder.java @@ -0,0 +1,82 @@ +package com.intellij.ui; + +import javax.swing.border.LineBorder; +import java.awt.*; + +/** + * @author Eugene Zhuravlev + */ +public class OneSideRoundedLineBorder extends LineBorder { + private final int myArcSize; + private final int myRadius; + private boolean myIsTopRounded; + private boolean myIsBottomRounded; + private boolean myDrawDottedAngledSide; + private static final float[] DASH = new float[]{0, 2, 0, 2}; + + + public OneSideRoundedLineBorder(Color color, int arcSize) { + this(color, arcSize, 1, true, false, false); + } + + public OneSideRoundedLineBorder(Color color, int arcSize, int thickness, boolean isTopRounded, boolean isBottomRounded, boolean drawDottedAngledSide) { + super(color, thickness); + myArcSize = arcSize; + myIsTopRounded = isTopRounded; + myIsBottomRounded = isBottomRounded; + myRadius = myArcSize / 2; + myDrawDottedAngledSide = drawDottedAngledSide; + } + + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + final Graphics2D g2 = (Graphics2D) g; + + final Object oldAntialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + final Color oldColor = g2.getColor(); + g2.setColor(lineColor); + + for (int idx = 0; idx < thickness; idx++) { + final int correctedHeight = height - idx - idx - 1; + final int correctedWidth = width - idx - idx - 1; + final int startX = x + idx; + final int startY = y + idx; + + if (myIsTopRounded && myIsBottomRounded) { + g2.drawRoundRect(startX, startY, correctedWidth, correctedHeight, myArcSize, myArcSize); + } + else if (myIsTopRounded){ + g2.drawLine(startX + myRadius, startY, startX + correctedWidth - myRadius, startY); // top + if (myDrawDottedAngledSide) { + drawDottedLine(g2, startX, startY + correctedHeight, startX + correctedWidth, startY + correctedHeight); // bottom + } + else { + g2.drawLine(startX, startY + correctedHeight, startX + correctedWidth, startY + correctedHeight); // bottom + } + g2.drawArc(startX, startY, myArcSize, myArcSize, 90, 90); + g2.drawArc(startX + correctedWidth - myArcSize, startY, myArcSize, myArcSize, 0, 90); + g2.drawLine(startX, startY + myRadius + 1, startX, startY + correctedHeight); // left + g2.drawLine(startX + correctedWidth, startY + myRadius + 1, startX + correctedWidth, startY + correctedHeight); // right + } + else if (myIsBottomRounded) { + // todo + } + else { + g2.drawRect(startX, startY, correctedWidth, correctedHeight); + } + } + + g2.setColor(oldColor); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialiasing); + } + + private void drawDottedLine(Graphics2D g, int x1, int y1, int x2, int y2) { + final Stroke saved = g.getStroke(); + g.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, DASH, y1 % 2)); + + g.drawLine(x1, y1, x2, y2); + + g.setStroke(saved); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/PasswordFieldPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/PasswordFieldPanel.java new file mode 100644 index 00000000000..633fbd4b919 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/PasswordFieldPanel.java @@ -0,0 +1,9 @@ +package com.intellij.ui; + +import javax.swing.*; + +public class PasswordFieldPanel extends FieldPanel { + public PasswordFieldPanel() { + super(new JPasswordField(30)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RightAlignedLabelUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RightAlignedLabelUI.java new file mode 100644 index 00000000000..fd94928246a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RightAlignedLabelUI.java @@ -0,0 +1,301 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicGraphicsUtils; +import javax.swing.plaf.basic.BasicLabelUI; +import java.awt.*; + +public class RightAlignedLabelUI extends BasicLabelUI { + + protected String layoutCL( + JLabel label, + FontMetrics fontMetrics, + String text, + Icon icon, + Rectangle viewR, + Rectangle iconR, + Rectangle textR) { + String s = layoutCompoundLabel( + label, + fontMetrics, + text, + icon, + label.getVerticalAlignment(), + label.getHorizontalAlignment(), + label.getVerticalTextPosition(), + label.getHorizontalTextPosition(), + viewR, + iconR, + textR, + label.getIconTextGap()); + + if (s.equals("")) + return text; + return s; + } + + static final int LEADING = SwingConstants.LEADING; + static final int TRAILING = SwingConstants.TRAILING; + static final int LEFT = SwingConstants.LEFT; + static final int RIGHT = SwingConstants.RIGHT; + static final int TOP = SwingConstants.TOP; + static final int CENTER = SwingConstants.CENTER; + + /** + * Compute and return the location of the icons origin, the + * location of origin of the text baseline, and a possibly clipped + * version of the compound labels string. Locations are computed + * relative to the viewR rectangle. + * The JComponents orientation (LEADING/TRAILING) will also be taken + * into account and translated into LEFT/RIGHT values accordingly. + */ + public static String layoutCompoundLabel(JComponent c, + FontMetrics fm, + String text, + Icon icon, + int verticalAlignment, + int horizontalAlignment, + int verticalTextPosition, + int horizontalTextPosition, + Rectangle viewR, + Rectangle iconR, + Rectangle textR, + int textIconGap) { + boolean orientationIsLeftToRight = true; + int hAlign = horizontalAlignment; + int hTextPos = horizontalTextPosition; + + + if (c != null) { + if (!(c.getComponentOrientation().isLeftToRight())) { + orientationIsLeftToRight = false; + } + } + + + // Translate LEADING/TRAILING values in horizontalAlignment + // to LEFT/RIGHT values depending on the components orientation + switch (horizontalAlignment) { + case LEADING: + hAlign = (orientationIsLeftToRight) ? LEFT : RIGHT; + break; + case TRAILING: + hAlign = (orientationIsLeftToRight) ? RIGHT : LEFT; + break; + } + + // Translate LEADING/TRAILING values in horizontalTextPosition + // to LEFT/RIGHT values depending on the components orientation + switch (horizontalTextPosition) { + case LEADING: + hTextPos = (orientationIsLeftToRight) ? LEFT : RIGHT; + break; + case TRAILING: + hTextPos = (orientationIsLeftToRight) ? RIGHT : LEFT; + break; + } + + return layoutCompoundLabel(fm, + text, + icon, + verticalAlignment, + hAlign, + verticalTextPosition, + hTextPos, + viewR, + iconR, + textR, + textIconGap); + } + + /** + * Compute and return the location of the icons origin, the + * location of origin of the text baseline, and a possibly clipped + * version of the compound labels string. Locations are computed + * relative to the viewR rectangle. + * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING + * values in horizontalTextPosition (they will default to RIGHT) and in + * horizontalAlignment (they will default to CENTER). + * Use the other version of layoutCompoundLabel() instead. + */ + public static String layoutCompoundLabel( + FontMetrics fm, + String text, + Icon icon, + int verticalAlignment, + int horizontalAlignment, + int verticalTextPosition, + int horizontalTextPosition, + Rectangle viewR, + Rectangle iconR, + Rectangle textR, + int textIconGap) { + /* Initialize the icon bounds rectangle iconR. + */ + + if (icon != null) { + iconR.width = icon.getIconWidth(); + iconR.height = icon.getIconHeight(); + } + else { + iconR.width = iconR.height = 0; + } + + /* Initialize the text bounds rectangle textR. If a null + * or and empty String was specified we substitute "" here + * and use 0,0,0,0 for textR. + */ + + // Fix for textIsEmpty sent by Paulo Santos + boolean textIsEmpty = (text == null) || (text.equals("")); + + String rettext = ""; + if (textIsEmpty) { + textR.width = textR.height = 0; + } + else { + Dimension dim = new Dimension(SwingUtilities.computeStringWidth(fm, text), fm.getHeight()); + textR.width = dim.width; + textR.height = dim.height; + } + + /* Unless both text and icon are non-null, we effectively ignore + * the value of textIconGap. The code that follows uses the + * value of gap instead of textIconGap. + */ + + int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap; + + if (!textIsEmpty) { + + /* If the label text string is too wide to fit within the available + * space "..." and as many characters as will fit will be + * displayed instead. + */ + + int availTextWidth; + + if (horizontalTextPosition == CENTER) { + availTextWidth = viewR.width; + } + else { + availTextWidth = viewR.width - (iconR.width + gap); + } + + + if (textR.width > availTextWidth) { + String clipString = "..."; + int totalWidth = SwingUtilities.computeStringWidth(fm, clipString); + int nChars; + rettext = ""; + for (nChars = text.length() - 1; nChars >= 0; nChars--) { + totalWidth += fm.charWidth(text.charAt(nChars)); + if (totalWidth > availTextWidth) { + break; + } + rettext = text.charAt(nChars) + rettext; + } + rettext = clipString + rettext; + textR.width = SwingUtilities.computeStringWidth(fm, rettext); + } + } + + + /* Compute textR.x,y given the verticalTextPosition and + * horizontalTextPosition properties + */ + + if (verticalTextPosition == TOP) { + if (horizontalTextPosition != CENTER) { + textR.y = 0; + } + else { + textR.y = -(textR.height + gap); + } + } + else if (verticalTextPosition == CENTER) { + textR.y = (iconR.height / 2) - (textR.height / 2); + } + else { + // (verticalTextPosition == BOTTOM) + if (horizontalTextPosition != CENTER) { + textR.y = iconR.height - textR.height; + } + else { + textR.y = (iconR.height + gap); + } + } + + if (horizontalTextPosition == LEFT) { + textR.x = -(textR.width + gap); + } + else if (horizontalTextPosition == CENTER) { + textR.x = (iconR.width / 2) - (textR.width / 2); + } + else { + // (horizontalTextPosition == RIGHT) + textR.x = (iconR.width + gap); + } + + /* labelR is the rectangle that contains iconR and textR. + * Move it to its proper position given the labelAlignment + * properties. + * + * To avoid actually allocating a Rectangle, Rectangle.union + * has been inlined below. + */ + int labelR_x = Math.min(iconR.x, textR.x); + int labelR_width = Math.max(iconR.x + iconR.width, textR.x + textR.width) - labelR_x; + int labelR_y = Math.min(iconR.y, textR.y); + int labelR_height = Math.max(iconR.y + iconR.height, textR.y + textR.height) - labelR_y; + + int dx, dy; + + if (verticalAlignment == TOP) { + dy = viewR.y - labelR_y; + } + else if (verticalAlignment == CENTER) { + dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2)); + } + else { + // (verticalAlignment == BOTTOM) + dy = (viewR.y + viewR.height) - (labelR_y + labelR_height); + } + + if (horizontalAlignment == LEFT) { + dx = viewR.x - labelR_x; + } + else if (horizontalAlignment == RIGHT) { + dx = (viewR.x + viewR.width) - (labelR_x + labelR_width); + } + else { + // (horizontalAlignment == CENTER) + dx = (viewR.x + (viewR.width / 2)) - + (labelR_x + (labelR_width / 2)); + } + + /* Translate textR and glypyR by dx,dy. + */ + + textR.x += dx; + textR.y += dy; + + iconR.x += dx; + iconR.y += dy; + + return rettext; + } + + protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int accChar = l.getDisplayedMnemonic(); + g.setColor(l.getForeground()); + BasicGraphicsUtils.drawString(g, s, accChar, textX, textY); + } + + protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int accChar = l.getDisplayedMnemonic(); + g.setColor(l.getBackground()); + BasicGraphicsUtils.drawString(g, s, accChar, textX, textY); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RowIcon.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RowIcon.java new file mode 100644 index 00000000000..a8526c7f45e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/RowIcon.java @@ -0,0 +1,80 @@ + +package com.intellij.ui; + +import java.awt.*; +import java.util.Arrays; +import javax.swing.*; + +/** + * + */ +public class RowIcon implements Icon { + public static final int HORIZONTAL = 1; + public static final int VERTICAL = 2; + private Icon[] myIcons; + private int myWidth; + private int myHeight; + + public RowIcon(int iconCount/*, int orientation*/) { + myIcons = new Icon[iconCount]; + //myOrientation = orientation; + } + + public int hashCode() { + return myIcons.length > 0 ? myIcons[0].hashCode() : 0; + } + + public boolean equals(Object obj) { + if (obj instanceof RowIcon){ + return Arrays.equals(((RowIcon)obj).myIcons, myIcons); + } + return false; + } + + public int getIconCount() { + return myIcons.length; + } + + public void setIcon(Icon icon, int layer) { + myIcons[layer] = icon; + recalculateSize(); + } + + public Icon getIcon(int index) { + return myIcons[index]; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + int _x = x; + int _y = y; + for(int i = 0; i < myIcons.length; i++){ + Icon icon = myIcons[i]; + if (icon == null) continue; + icon.paintIcon(c, g, _x, _y); + _x += icon.getIconWidth(); + //_y += icon.getIconHeight(); + } + } + + public int getIconWidth() { + return myWidth; + } + + public int getIconHeight() { + return myHeight; + } + + private void recalculateSize() { + int width = 0; + int height = 0; + for(int i = 0; i < myIcons.length; i++){ + Icon icon = myIcons[i]; + if (icon == null) continue; + width += icon.getIconWidth(); + //height += icon.getIconHeight(); + height = Math.max(height, icon.getIconHeight()); + } + myWidth = width; + myHeight = height; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SelectionSaver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SelectionSaver.java new file mode 100644 index 00000000000..fdbc339ffd0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SelectionSaver.java @@ -0,0 +1,80 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collection; + +public class SelectionSaver implements TreeSelectionListener, TreeModelListener, PropertyChangeListener{ + + private final JTree myTree; + private Collection myCurrentSelection = new ArrayList(); + + + private SelectionSaver(JTree tree) { + myTree = tree; + } + + public static void installOn(JTree tree){ + new SelectionSaver(tree).install(); + } + + private void install(){ + myTree.getModel().addTreeModelListener(this); + myTree.getSelectionModel().addTreeSelectionListener(this); + myTree.addPropertyChangeListener(this); + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(JTree.TREE_MODEL_PROPERTY)){ + ((TreeModel)evt.getOldValue()).removeTreeModelListener(this); + ((TreeModel)evt.getNewValue()).addTreeModelListener(this); + } + } + + public void treeNodesRemoved(TreeModelEvent treeModelEvent) { + TreePath pathToDelete = treeModelEvent.getTreePath(); + Object[] children = treeModelEvent.getChildren(); + + for (int i = 0; i < children.length; i++) { + Object nodeToDelete = children[i]; + if (myCurrentSelection.contains(nodeToDelete)){ + int deletedRow = myTree.getRowForPath(pathToDelete.pathByAddingChild(nodeToDelete)); + if (deletedRow == 0) return; + TreePath treePath = new TreePath(myTree.getPathForRow(deletedRow - 1)); + myTree.getSelectionModel().addSelectionPath((TreePath)treePath.getLastPathComponent()); + } + } + + } + + public void valueChanged(TreeSelectionEvent e) { + myCurrentSelection = new ArrayList(); + TreePath[] selection = myTree.getSelectionModel().getSelectionPaths(); + if (selection == null) return; + for (int i = 0; i < selection.length; i++) { + TreePath treePath = selection[i]; + myCurrentSelection.add((TreeNode)treePath.getLastPathComponent()); + } + } + + public void treeNodesChanged(TreeModelEvent e) { + + } + + public void treeNodesInserted(TreeModelEvent e) { + + } + + public void treeStructureChanged(TreeModelEvent e) { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder.java new file mode 100644 index 00000000000..8df4ee7c5a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder.java @@ -0,0 +1,61 @@ +package com.intellij.ui; + +import javax.swing.border.LineBorder; +import java.awt.*; + +public class SideBorder extends LineBorder { + public static final int LEFT = 0x01; + public static final int TOP = 0x02; + public static final int RIGHT = 0x04; + public static final int BOTTOM = 0x08; + public static final int ALL = LEFT | TOP | RIGHT | BOTTOM; + private int mySideMask; + + public SideBorder(Color color, int mask) { + super(color, 1); + mySideMask = mask; + } + + public Insets getBorderInsets(Component component) { + return new Insets( + (mySideMask & TOP) != 0 ? getThickness() : 0, + (mySideMask & LEFT) != 0 ? getThickness() : 0, + (mySideMask & BOTTOM) != 0 ? getThickness() : 0, + (mySideMask & RIGHT) != 0 ? getThickness() : 0 + ); + } + + public Insets getBorderInsets(Component component, Insets insets) { + insets.top = (mySideMask & TOP) != 0 ? getThickness() : 0; + insets.left = (mySideMask & LEFT) != 0 ? getThickness() : 0; + insets.bottom = (mySideMask & BOTTOM) != 0 ? getThickness() : 0; + insets.right = (mySideMask & RIGHT) != 0 ? getThickness() : 0; + return insets; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Color oldColor = g.getColor(); + int i; + + g.setColor(getLineColor()); + for(i = 0; i < getThickness(); i++){ + if ((mySideMask & LEFT) != 0){ + g.drawLine(x + i, y + i, x + i, height - i - i - 1); + } + if ((mySideMask & TOP) != 0){ + g.drawLine(x + i, y + i, width - i - i - 1, y + i); + } + if ((mySideMask & RIGHT) != 0){ + g.drawLine(width - i - i - 1, y + i, width - i - i - 1, height - i - i - 1); + } + if ((mySideMask & BOTTOM) != 0){ + g.drawLine(x + i, height - i - i - 1, width - i - i - 1, height - i - i - 1); + } + } + g.setColor(oldColor); + } + + public void setLineColor(Color color) { + lineColor = color; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder2.java new file mode 100644 index 00000000000..0d41f2064bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SideBorder2.java @@ -0,0 +1,70 @@ +package com.intellij.ui; + +import java.awt.*; +import javax.swing.border.Border; + +public class SideBorder2 implements Border { + public boolean isBorderOpaque() { + return false; + } + + private Color myLeftColor; + private Color myRightColor; + private Color myTopColor; + private Color myBottomColor; + private int myThickness; + + public SideBorder2(Color topColor, Color leftColor, Color bottomColor, Color rightColor, int thickness) { + myTopColor = topColor; + myLeftColor = leftColor; + myRightColor = rightColor; + myBottomColor = bottomColor; + myThickness = thickness; + } + + public Insets getBorderInsets(Component component) { + return new Insets( + myTopColor != null ? getThickness() : 0, + myLeftColor != null ? getThickness() : 0, + myBottomColor != null ? getThickness() : 0, + myRightColor != null ? getThickness() : 0 + ); + } + + public Insets getBorderInsets(Component component, Insets insets) { + insets.top = myTopColor != null ? getThickness() : 0; + insets.left = myLeftColor != null ? getThickness() : 0; + insets.bottom = myBottomColor != null ? getThickness() : 0; + insets.right = myRightColor != null ? getThickness() : 0; + return insets; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Color oldColor = g.getColor(); + int i; + + for(i = 0; i < getThickness(); i++){ + if (myLeftColor != null){ + g.setColor(myLeftColor); + g.drawLine(x + i, y + i, x + i, height - i - i - 1); + } + if (myTopColor != null){ + g.setColor(myTopColor); + g.drawLine(x + i, y + i, width - i - i - 1, y + i); + } + if (myRightColor != null){ + g.setColor(myRightColor); + g.drawLine(width - i - i - 1, y + i, width - i - i - 1, height - i - i - 1); + } + if (myBottomColor != null){ + g.setColor(myBottomColor); + g.drawLine(x + i, height - i - i - 1, width - i - i - 1, height - i - i - 1); + } + } + g.setColor(oldColor); + } + + public int getThickness() { + return myThickness; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SpeedSearchBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SpeedSearchBase.java new file mode 100644 index 00000000000..8ebf02bbc8e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SpeedSearchBase.java @@ -0,0 +1,440 @@ +package com.intellij.ui; + +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.openapi.wm.ex.ToolWindowManagerListener; + +import javax.swing.*; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.regex.Matcher; + +public abstract class SpeedSearchBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.SpeedSearchBase"); + private SearchPopup mySearchPopup; + private JLayeredPane myPopupLayeredPane; + protected final Comp myComponent; + private final Project myProject; + private final ToolWindowManagerListener myWindowManagerListener=new MyToolWindowManagerListener(); + private final PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this); + private String myRecentEnteredPrefix; + private SpeedSearchComparator myComparator = new SpeedSearchComparator(); + + private static final Key SPEED_SEARCH_COMPONENT_MARKER = new Key("SPEED_SEARCH_COMPONENT_MARKER"); + + public SpeedSearchBase(Comp component) { + myComponent = component; + + if (ApplicationManager.getApplication() != null) { + myProject=(Project)DataManager.getInstance().getDataContext(component).getData(DataConstants.PROJECT); + } + else { + myProject = null; + } + + myComponent.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + manageSearchPopup(null); + } + }); + myComponent.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + processKeyEvent(e); + } + public void keyPressed(KeyEvent e) { + processKeyEvent(e); + } + }); + + component.putClientProperty(SPEED_SEARCH_COMPONENT_MARKER, this); + } + + public static boolean hasActiveSpeedSearch(JComponent component) { + SpeedSearchBase speedSearch = (SpeedSearchBase)component.getClientProperty(SPEED_SEARCH_COMPONENT_MARKER); + return speedSearch != null && speedSearch.mySearchPopup != null && speedSearch.mySearchPopup.isVisible(); + } + + protected abstract int getSelectedIndex(); + protected abstract Object[] getAllElements(); + protected abstract String getElementText(Object element); + protected abstract void selectElement(Object element, String selectedText); + + public void addChangeListener(PropertyChangeListener listener) { + myChangeSupport.addPropertyChangeListener(listener); + } + + public void removeChangeListener(PropertyChangeListener listener) { + myChangeSupport.removePropertyChangeListener(listener); + } + + private void fireStateChanged() { + String enteredPrefix = getEnteredPrefix(); + myChangeSupport.firePropertyChange("enteredPrefix", myRecentEnteredPrefix, enteredPrefix); + myRecentEnteredPrefix = enteredPrefix; + } + + protected boolean isMatchingElement(Object element, String pattern) { + String str = getElementText(element); + return str!=null && compare(str,pattern); + } + + protected boolean compare(String text, String pattern) { + return myComparator.doCompare(pattern, text); + } + + public static class SpeedSearchComparator { + private Pattern myRecentSearchPattern; + private Matcher myRecentSearchMatcher; + private String myRecentSearchText; + + public boolean doCompare(String pattern, String text) { + //final int asteriskIndex = pattern.indexOf('*'); + + // asterisk on is of no interest + //if (asteriskIndex==-1 || asteriskIndex == pattern.length()-1) { + // return text.startsWith( pattern ); + //} + + if (myRecentSearchText!=null && + myRecentSearchText.equals(pattern) + ) { + myRecentSearchMatcher.reset(text); + return myRecentSearchMatcher.find(); + } else { + myRecentSearchText = pattern; + final StringBuffer buf = new StringBuffer(pattern.length()); + final int len = pattern.length(); + boolean hasCapitals = false; + buf.append('^'); + + for(int i=0;i= 0; i--) { + Object element = elements[i]; + if (isMatchingElement(element, _s)) return element; + } + return selectedIndex != -1 ? elements[selectedIndex] : null; // return current + } + + private Object findElement(String s) { + String _s = s.trim(); + Object[] elements = getAllElements(); + int selectedIndex = getSelectedIndex(); + if (selectedIndex < 0) { + selectedIndex = 0; + } + for (int i = selectedIndex; i < elements.length; i++) { + Object element = elements[i]; + if (isMatchingElement(element, _s)) return element; + } + for (int i = 0; i < selectedIndex; i++) { + Object element = elements[i]; + if (isMatchingElement(element, _s)) return element; + } + return null; + } + + private Object findFirstElement(String s) { + String _s = s.trim(); + Object[] elements = getAllElements(); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + if (isMatchingElement(element, _s)) return element; + } + return null; + } + + private Object findLastElement(String s) { + String _s = s.trim(); + Object[] elements = getAllElements(); + for (int i = elements.length - 1; i >= 0; i--) { + Object element = elements[i]; + if (isMatchingElement(element, _s)) return element; + } + return null; + } + + private void processKeyEvent(KeyEvent e) { + if (e.isAltDown()) return; + if (mySearchPopup != null) { + mySearchPopup.processKeyEvent(e); + return; + } + if (e.getID() == KeyEvent.KEY_TYPED) { + char c = e.getKeyChar(); + if (Character.isLetterOrDigit(c) || c == '_' || c == '*') { + manageSearchPopup(new SearchPopup(String.valueOf(c))); + e.consume(); + } + } + } + + public String getEnteredPrefix() { + return mySearchPopup != null ? mySearchPopup.mySearchField.getText() : null; + } + + private class SearchPopup extends JPanel { + private final SearchField mySearchField; + private final JLabel mySearchLabel; + + public SearchPopup(String initialString) { + final Color foregroundColor = UIManager.getColor("ToolTip.foreground"); + Color color1 = UIManager.getColor("ToolTip.background"); + mySearchField = new SearchField(); + mySearchLabel = new JLabel(" Search for: "); + mySearchLabel.setFont(mySearchLabel.getFont().deriveFont(Font.BOLD)); + mySearchLabel.setForeground(foregroundColor); + mySearchField.setBorder(null); + mySearchField.setBackground(color1.brighter()); + mySearchField.setForeground(foregroundColor); + + mySearchField.setDocument(new PlainDocument(){ + public void insertString(int offs, String str, AttributeSet a) throws BadLocationException{ + String oldText; + try { + oldText = getText(0, getLength()); + } + catch (BadLocationException e1) { + oldText = ""; + } + + String newText = oldText.substring(0, offs) + str + oldText.substring(offs); + super.insertString(offs, str, a); + if (findElement(newText) == null) { + mySearchField.setForeground(Color.RED); + } else mySearchField.setForeground(foregroundColor); + } + }); + mySearchField.setText(initialString); + + setBorder(BorderFactory.createLineBorder(Color.gray, 1)); + setBackground(color1.brighter()); + setLayout(new BorderLayout()); + add(mySearchLabel, BorderLayout.WEST); + add(mySearchField, BorderLayout.EAST); + Object element = findElement(mySearchField.getText()); + updateSelection(element); + } + + public void processKeyEvent(KeyEvent e) { + mySearchField.processKeyEvent(e); + if (e.isConsumed()) { + int keyCode = e.getKeyCode(); + String s = mySearchField.getText(); + Object element; + if (keyCode == KeyEvent.VK_UP) { + element = findPreviousElement(s); + } + else if (keyCode == KeyEvent.VK_DOWN) { + element = findNextElement(s); + } + else if (keyCode == KeyEvent.VK_HOME) { + element = findFirstElement(s); + } + else if (keyCode == KeyEvent.VK_END) { + element = findLastElement(s); + } + else { + element = findElement(s); + } + updateSelection(element); + } + } + + private void updateSelection(Object element) { + if (element != null) { + selectElement(element, mySearchField.getText()); + mySearchField.setForeground(Color.black); + } + else { + mySearchField.setForeground(Color.red); + } + if (mySearchPopup != null) { + mySearchPopup.setSize(mySearchPopup.getPreferredSize()); + mySearchPopup.validate(); + } + + fireStateChanged(); + } + } + + + private class SearchField extends JTextField { + SearchField() { + setFocusable(false); + } + + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.width = getFontMetrics(getFont()).stringWidth(getText()) + 10; + return dim; + } + + /** + * I made this method public in order to be able to call it from the outside. + * This is needed for delegating calls. + */ + public void processKeyEvent(KeyEvent e) { + int i = e.getKeyCode(); + if (i == KeyEvent.VK_BACK_SPACE && getDocument().getLength() == 0) { + e.consume(); + return; + } + if ( + i == KeyEvent.VK_ENTER || + i == KeyEvent.VK_ESCAPE || + i == KeyEvent.VK_PAGE_UP || + i == KeyEvent.VK_PAGE_DOWN || + i == KeyEvent.VK_LEFT || + i == KeyEvent.VK_RIGHT + ) { + manageSearchPopup(null); + if (i == KeyEvent.VK_ESCAPE) { + e.consume(); + } + return; + } + super.processKeyEvent(e); + if ( + i == KeyEvent.VK_BACK_SPACE || + i == KeyEvent.VK_HOME || + i == KeyEvent.VK_END || + i == KeyEvent.VK_UP || + i == KeyEvent.VK_DOWN + ) { + e.consume(); + } + } + } + + private void manageSearchPopup(SearchPopup searchPopup) { + if (mySearchPopup != null) { + myPopupLayeredPane.remove(mySearchPopup); + myPopupLayeredPane.validate(); + myPopupLayeredPane.repaint(); + myPopupLayeredPane = null; + + if(myProject!=null){ + ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).removeToolWindowManagerListener(myWindowManagerListener); + } + } + else if (searchPopup != null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("ui.tree.speedsearch"); + } + + if (!myComponent.isShowing()) { + mySearchPopup = null; + } + else { + mySearchPopup = searchPopup; + } + + fireStateChanged(); + + if (mySearchPopup == null || !myComponent.isDisplayable()) return; + + if(myProject!=null){ + ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(myWindowManagerListener); + } + JRootPane rootPane = myComponent.getRootPane(); + if (rootPane != null) myPopupLayeredPane = rootPane.getLayeredPane(); + else myPopupLayeredPane = null; + if (myPopupLayeredPane == null) { + LOG.error(this.toString() + " in " + String.valueOf(myComponent)); + return; + } + myPopupLayeredPane.add(mySearchPopup, JLayeredPane.POPUP_LAYER); + if (myPopupLayeredPane == null) return; // See # 27482. Somewho it does happen... + Point lPaneP = myPopupLayeredPane.getLocationOnScreen(); + Point componentP = myComponent.getLocationOnScreen(); + Rectangle r = myComponent.getVisibleRect(); + Dimension prefSize = mySearchPopup.getPreferredSize(); + Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, myComponent); + Point windowP; + if (window instanceof JDialog){ + windowP = ((JDialog)window).getContentPane().getLocationOnScreen(); + } + else if (window instanceof JFrame){ + windowP = ((JFrame)window).getContentPane().getLocationOnScreen(); + } + else{ + windowP = window.getLocationOnScreen(); + } + int y = r.y + componentP.y - lPaneP.y - prefSize.height; + y = Math.max(y, windowP.y - lPaneP.y); + mySearchPopup.setLocation(componentP.x - lPaneP.x + r.x, y); + mySearchPopup.setSize(prefSize); + mySearchPopup.setVisible(true); + mySearchPopup.validate(); + } + + private class MyToolWindowManagerListener extends ToolWindowManagerAdapter { + public void stateChanged(){ + manageSearchPopup(null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Splash.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Splash.java new file mode 100644 index 00000000000..e89ef06610f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Splash.java @@ -0,0 +1,70 @@ +package com.intellij.ui; + +import com.intellij.ide.license.LicenseManager; +import com.intellij.openapi.application.impl.ApplicationInfoImpl; +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; + +public class Splash extends JWindow { + private static final Color ideaDARK_BLUE = new Color(40, 60, 180); + private Icon myImage; + private JLabel myLabel; + private boolean myShowLicenseeInfo; + + public Splash(String imageName) { + Icon originalImage = IconLoader.getIcon(imageName); + myShowLicenseeInfo = ApplicationInfoImpl.getShadowInstance().showLicenseeInfo(); + myImage = new MyIcon(originalImage); + myLabel = new JLabel(myImage); + Container contentPane = getContentPane(); + contentPane.setLayout(new BorderLayout()); + contentPane.add(myLabel, BorderLayout.CENTER); + Dimension size = getPreferredSize(); + setSize(size); + pack(); + setLocationRelativeTo(null); + } + + public void show() { + super.show(); + myLabel.paintImmediately(0, 0, myImage.getIconWidth(), myImage.getIconHeight()); + } + + private final class MyIcon implements Icon { + private Icon myOriginalIcon; + + public MyIcon(Icon originalIcon) { + myOriginalIcon = originalIcon; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + yeild(); + myOriginalIcon.paintIcon(c, g, x, y); + + if (myShowLicenseeInfo) { + g.setFont(new Font("Arial", Font.BOLD, 11)); + g.setColor(ideaDARK_BLUE); + g.drawString(LicenseManager.getInstance().licensedToMessage(), x + 20, y + getIconHeight() - 80); + g.drawString(LicenseManager.getInstance().licensedRestrictionsMessage(), x + 20, y + getIconHeight() - 60); + } + } + + private void yeild() { + try { + Thread.sleep(10); + } + catch (InterruptedException e) { + } + } + + public int getIconWidth() { + return myOriginalIcon.getIconWidth(); + } + + public int getIconHeight() { + return myOriginalIcon.getIconHeight(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SplittingUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SplittingUtil.java new file mode 100644 index 00000000000..01fd8aa3836 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/SplittingUtil.java @@ -0,0 +1,43 @@ +package com.intellij.ui; + +import java.awt.*; +import java.util.ArrayList; + +public class SplittingUtil { + public static String[] splitText(String text, FontMetrics fontMetrics, int widthLimit, char separator){ + ArrayList lines = new ArrayList(); + String currentLine = ""; + StringBuffer currentAtom = new StringBuffer(); + + for (int i=0; i < text.length(); i++) { + char ch = text.charAt(i); + currentAtom.append(ch); + + if (ch == separator) { + currentLine += currentAtom.toString(); + currentAtom.setLength(0); + } + + String s = currentLine + currentAtom.toString(); + int width = fontMetrics.stringWidth(s); + + if (width >= widthLimit - fontMetrics.charWidth('w')) { + if (currentLine.length() > 0) { + lines.add(currentLine); + currentLine = ""; + } + else { + lines.add(currentAtom.toString()); + currentAtom.setLength(0); + } + } + } + + String s = currentLine + currentAtom.toString(); + if (s.length() > 0) { + lines.add(s); + } + + return (String[])lines.toArray(new String[lines.size()]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StateRestoringCheckBox.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StateRestoringCheckBox.java new file mode 100644 index 00000000000..68d768e88a2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StateRestoringCheckBox.java @@ -0,0 +1,88 @@ +/* + * @author Eugene Zhuravlev + */ +package com.intellij.ui; + +import javax.swing.*; + +/** + * When enabled the checkbox behaves like the ordinary checkbox + * If to use special methods to enable/disable it, + * it will manage different selected/unselected states for each mode - enabled or disabled + */ +public class StateRestoringCheckBox extends JCheckBox { + private boolean myIsSelectedWhenSelectable; + + public StateRestoringCheckBox() { + super(); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(Icon icon) { + super(icon); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(Icon icon, boolean selected) { + super(icon, selected); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(String text) { + super(text); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(Action a) { + super(a); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(String text, boolean selected) { + super(text, selected); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(String text, Icon icon) { + super(text, icon); + myIsSelectedWhenSelectable = isSelected(); + } + + public StateRestoringCheckBox(String text, Icon icon, boolean selected) { + super(text, icon, selected); + myIsSelectedWhenSelectable = isSelected(); + } + + /** + * The method should be used instead of setEnabled(false) or disable() in order to support selected state saving/recovering + * Remembers the selected state of the checkbox when the checkbox is enabled, disables it + * and sets the selected state according to tha parameter pased + * @param isSelected the parameter telling whetheer the checkbox is selected when disabled + */ + public void makeUnselectable(boolean isSelected) { + if (isEnabled()) { + myIsSelectedWhenSelectable = isSelected(); + setEnabled(false); + } + setSelected(isSelected); + } + + /** + * The method should be used instead of setEnabled(true) or enable() in order to support selected state saving/recovering + * Enables the checkbox and restores the selected state of the checkbox to the one, that it had before the makeUnselectable() method was called + * that was before the checkbox was disabled + */ + public void makeSelectable() { + if (!isEnabled()) { + setEnabled(true); + setSelected(myIsSelectedWhenSelectable); + } + } + + public boolean isSelectedWhenSelectable() { + if (isEnabled()) { + return isSelected(); + } + return myIsSelectedWhenSelectable; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StrikeoutLabel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StrikeoutLabel.java new file mode 100644 index 00000000000..23ec1c2c06e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/StrikeoutLabel.java @@ -0,0 +1,33 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; + +public class StrikeoutLabel extends JLabel{ + private boolean myStrikeout = false; + + public StrikeoutLabel(String text, int horizontalAlignment) { + super(text, horizontalAlignment); + } + + public void setStrikeout(boolean strikeout) { + myStrikeout = strikeout; + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (myStrikeout){ + Dimension size = getSize(); + Dimension prefSize = getPreferredSize(); + int width = Math.min(size.width, prefSize.width); + int iconWidth = 0; + Icon icon = StrikeoutLabel.this.getIcon(); + if (icon != null){ + iconWidth = icon.getIconWidth(); + iconWidth += getIconTextGap(); + } + g.setColor(this.getForeground()); + g.drawLine(iconWidth, size.height / 2, width, size.height / 2); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Surface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Surface.java new file mode 100644 index 00000000000..7468cff1db2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/Surface.java @@ -0,0 +1,344 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.*; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; + +/** + * Surface is the base class for the 2d rendering demos. Demos must + * implement the render() method. Subclasses for Surface are + * AnimatingSurface, ControlsSurface and AnimatingControlsSurface. + */ +public abstract class Surface extends JPanel implements Printable { + public Object AntiAlias = RenderingHints.VALUE_ANTIALIAS_ON; + public Object Rendering = RenderingHints.VALUE_RENDER_SPEED; + public AlphaComposite composite; + public Paint texture; + public String perfStr; + // PerformanceMonitor + public BufferedImage bimg; + public int imageType; + public String name; + public boolean clearSurface = true; + // Demos using animated gif's that implement ImageObserver set dontThread. + public boolean dontThread; + public AnimatingSurface animating; + protected long sleepAmount = 50; + private long orig + , + start + , + frame; + private Toolkit toolkit; + private boolean perfMonitor + , + outputPerf; + private int biw + , + bih; + private boolean clearOnce; + + public Surface() { + setDoubleBuffered(this instanceof AnimatingSurface); + toolkit = getToolkit(); + name = this.getClass().getName(); + name = name.substring(name.indexOf(".", 7) + 1); + setImageType(0); + + // To launch an individual demo with the performance str output : + // java -Djava2demo.perf= -cp Java2Demo.jar demos.Clipping.ClipAnim + try{ + if (System.getProperty("java2demo.perf") != null){ + perfMonitor = outputPerf = true; + } + } + catch(Exception ex){ + } + if (this instanceof AnimatingSurface){ + animating = (AnimatingSurface)this; + } + } + + /* + protected Image getImage(String name) { + return DemoImages.getImage(name, this); + } + + + protected Font getFont(String name) { + return DemoFonts.getFont(name); + } + */ + + public int getImageType() { + return imageType; + } + + public void setImageType(int imgType) { + if (imgType == 0){ + if (this instanceof AnimatingSurface){ + imageType = 2; + } + else{ + imageType = 1; + } + } + else{ + imageType = imgType; + } + bimg = null; + } + + public void setTexture(Object obj) { + if (obj instanceof GradientPaint){ + texture = new GradientPaint(0, 0, Color.white, + getSize().width * 2, 0, Color.green); + } + else{ + texture = (Paint)obj; + } + } + + public void setComposite(boolean cp) { + composite = cp + ? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f) + : null; + } + + public void setMonitor(boolean pm) { + perfMonitor = pm; + } + + public void setSleepAmount(long amount) { + sleepAmount = amount; + } + + public long getSleepAmount() { + return sleepAmount; + } + + public BufferedImage createBufferedImage(int w, int h, int imgType) { + BufferedImage bi = null; + if (imgType == 0){ + bi = (BufferedImage)createImage(w, h); + } + else + if (imgType > 0 && imgType < 14){ + bi = new BufferedImage(w, h, imgType); + } + else + if (imgType == 14){ + bi = createBinaryImage(w, h, 2); + } + else + if (imgType == 15){ + bi = createBinaryImage(w, h, 4); + } + biw = w; + bih = h; + return bi; + } + + // Lookup tables for BYTE_BINARY 1, 2 and 4 bits. + static byte[] lut1Arr = new byte[]{0, (byte)255 }; + static byte[] lut2Arr = new byte[]{0, (byte)85, (byte)170, (byte)255}; + static byte[] lut4Arr = new byte[]{0, (byte)17, (byte)34, (byte)51, + (byte)68, (byte)85,(byte)102, (byte)119, + (byte)136, (byte)153, (byte)170, (byte)187, + (byte)204, (byte)221, (byte)238, (byte)255}; + + private BufferedImage createBinaryImage(int w, int h, int pixelBits) { + + int bytesPerRow = w * pixelBits / 8; + if (w * pixelBits % 8 != 0){ + bytesPerRow++; + } + byte[] imageData = new byte[h * bytesPerRow]; + IndexColorModel cm = null; + switch(pixelBits){ + case 1: + cm = new IndexColorModel(pixelBits, lut1Arr.length, + lut1Arr, lut1Arr, lut1Arr); + break; + case 2: + cm = new IndexColorModel(pixelBits, lut2Arr.length, + lut2Arr, lut2Arr, lut2Arr); + break; + case 4: + cm = new IndexColorModel(pixelBits, lut4Arr.length, + lut4Arr, lut4Arr, lut4Arr); + break; + default: + { + new Exception("Invalid # of bit per pixel").printStackTrace(); + } + } + + DataBuffer db = new DataBufferByte(imageData, imageData.length); + WritableRaster r = Raster.createPackedRaster(db, w, h, pixelBits, null); + return new BufferedImage(cm, r, false, null); + } + + public Graphics2D createGraphics2D(int width, + int height, + BufferedImage bi, + Graphics g) { + + Graphics2D g2; + if (bi != null){ + g2 = bi.createGraphics(); + } + else{ + g2 = (Graphics2D)g; + } + + g2.setBackground(getBackground()); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, AntiAlias); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, Rendering); + + if (clearSurface || clearOnce){ + g2.clearRect(0, 0, width, height); + clearOnce = false; + } + + if (texture != null){ + // set composite to opaque for texture fills + g2.setComposite(AlphaComposite.SrcOver); + g2.setPaint(texture); + g2.fillRect(0, 0, width, height); + } + + if (composite != null){ + g2.setComposite(composite); + } + + return g2; + } + + // ...demos that extend Surface must implement this routine... + + public abstract void render(int w, int h, Graphics2D g2); + + /** + * It's possible to turn off double-buffering for just the repaint + * calls invoked directly on the non double buffered component. + * This can be done by overriding paintImmediately() (which is called + * as a result of repaint) and getting the current RepaintManager and + * turning off double buffering in the RepaintManager before calling + * super.paintImmediately(g). + */ + public void paintImmediately(int x, int y, int w, int h) { + RepaintManager repaintManager = null; + boolean save = true; + if (!isDoubleBuffered()){ + repaintManager = RepaintManager.currentManager(this); + save = repaintManager.isDoubleBufferingEnabled(); + repaintManager.setDoubleBufferingEnabled(false); + } + super.paintImmediately(x, y, w, h); + + if (repaintManager != null){ + repaintManager.setDoubleBufferingEnabled(save); + } + } + + public void paint(Graphics g) { + + Dimension d = getSize(); + + if (imageType == 1){ + bimg = null; + startClock(); + } + else + if (bimg == null || biw != d.width || bih != d.height){ + if (animating != null && (biw != d.width || bih != d.height)){ + animating.reset(d.width, d.height); + } + bimg = createBufferedImage(d.width, d.height, imageType - 2); + clearOnce = true; + startClock(); + } + + if (animating != null && animating.thread != null){ + animating.step(d.width, d.height); + } + Graphics2D g2 = createGraphics2D(d.width, d.height, bimg, g); + render(d.width, d.height, g2); + g2.dispose(); + + if (bimg != null){ + g.drawImage(bimg, 0, 0, null); + toolkit.sync(); + } + + if (perfMonitor){ + LogPerformance(); + } + } + + public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { + if (pi >= 1){ + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g2d.translate(pf.getImageableWidth() / 2, + pf.getImageableHeight() / 2); + + Dimension d = getSize(); + + double scale = Math.min(pf.getImageableWidth() / d.width, + pf.getImageableHeight() / d.height); + if (scale < 1.0){ + g2d.scale(scale, scale); + } + + g2d.translate(-d.width / 2.0, -d.height / 2.0); + + if (bimg == null){ + Graphics2D g2 = createGraphics2D(d.width, d.height, null, g2d); + render(d.width, d.height, g2); + g2.dispose(); + } + else{ + g2d.drawImage(bimg, 0, 0, this); + } + + return Printable.PAGE_EXISTS; + } + + private void startClock() { + orig = System.currentTimeMillis(); + start = orig; + } + + private static final int REPORTFRAMES = 30; + + private void LogPerformance() { + if ((frame % REPORTFRAMES) == 0){ + long end = System.currentTimeMillis(); + long rel = (end - start); + if (frame == 0){ + perfStr = name + " " + rel + " ms"; + if (animating == null || animating.thread == null){ + frame = -1; + } + } + else{ + String s1 = Float.toString((REPORTFRAMES / (rel / 1000.0f))); + s1 = (s1.length() < 4) ? s1.substring(0, s1.length()) : s1.substring(0, 4); + perfStr = name + " " + s1 + " fps"; + } + if (outputPerf){ + System.out.println(perfStr); + } + start = end; + } + ++frame; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TabbedPaneWrapper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TabbedPaneWrapper.java new file mode 100644 index 00000000000..c0fe126bf19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TabbedPaneWrapper.java @@ -0,0 +1,558 @@ +package com.intellij.ui; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.TabbedPaneUI; +import javax.swing.plaf.basic.BasicTabbedPaneUI; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class TabbedPaneWrapper { + protected final TabbedPane myTabbedPane; + protected final JComponent myTabbedPaneHolder; + + public TabbedPaneWrapper(){ + this(SwingConstants.TOP); + } + + /** + * Creates tabbed pane wrapper with specified tab placement + * + * @param tabPlacement tab placement. It one of the SwingConstants.TOP, + * SwingConstants.LEFT, SwingConstants.BOTTOM or + * SwingConstants.RIGHT. + */ + public TabbedPaneWrapper(final int tabPlacement) { + assertIsDispatchThread(); + + myTabbedPane = createTabbedPane(tabPlacement); + myTabbedPaneHolder = createTabbedPaneHolder(); + myTabbedPaneHolder.add(myTabbedPane, BorderLayout.CENTER); + myTabbedPaneHolder.setFocusCycleRoot(true); + myTabbedPaneHolder.setFocusTraversalPolicy(new _MyFocusTraversalPolicy()); + } + + private static void assertIsDispatchThread() { + final Application application = ApplicationManager.getApplication(); + if (application != null){ + application.assertIsDispatchThread(); + } + } + + public final void addChangeListener(final ChangeListener listener){ + assertIsDispatchThread(); + myTabbedPane.addChangeListener(listener); + } + + public final void removeChangeListener(final ChangeListener listener){ + assertIsDispatchThread(); + myTabbedPane.removeChangeListener(listener); + } + + protected JComponent createTabbedPaneHolder() { + return new TabbedPaneHolder(); + } + + public final JComponent getComponent() { + assertIsDispatchThread(); + return myTabbedPaneHolder; + } + + /** + * @see javax.swing.JTabbedPane#addTab(java.lang.String, javax.swing.Icon, java.awt.Component, java.lang.String) + */ + public final synchronized void addTab(final String title, final Icon icon, final JComponent component, final String tip) { + insertTab(title, icon, component, tip, myTabbedPane.getTabCount()); + } + + public final synchronized void addTab(final String title, final JComponent component) { + insertTab(title, null, component, null, myTabbedPane.getTabCount()); + } + + public synchronized void insertTab(final String title, final Icon icon, final JComponent component, final String tip, final int index) { + myTabbedPane.insertTab(title, icon, new TabWrapper(component), tip, index); + } + + protected TabbedPane createTabbedPane(final int tabPlacement) { + return new TabbedPane(tabPlacement); + } + + /** + * @see javax.swing.JTabbedPane#setTabPlacement + */ + public final void setTabPlacement(final int tabPlacement) { + assertIsDispatchThread(); + myTabbedPane.setTabPlacement(tabPlacement); + } + + public final void addMouseListener(final MouseListener listener) { + assertIsDispatchThread(); + myTabbedPane.addMouseListener(listener); + } + + public final synchronized int getSelectedIndex() { + return myTabbedPane.getSelectedIndex(); + } + + /** + * @see javax.swing.JTabbedPane#getSelectedComponent() + */ + public final synchronized JComponent getSelectedComponent() { + final TabWrapper tabWrapper = (TabWrapper)myTabbedPane.getSelectedComponent(); + return tabWrapper != null ? tabWrapper.getComponent() : null; + } + + public final void setSelectedIndex(final int index) { + assertIsDispatchThread(); + + final boolean hadFocus = IJSwingUtilities.hasFocus2(myTabbedPaneHolder); + myTabbedPane.setSelectedIndex(index); + if (hadFocus) { + myTabbedPaneHolder.requestFocus(); + } + } + + public final void setSelectedComponent(final JComponent component){ + assertIsDispatchThread(); + + final int index=indexOfComponent(component); + if(index==-1){ + throw new IllegalArgumentException("component not found in tabbed pane wrapper"); + } + setSelectedIndex(index); + } + + public final synchronized void removeTabAt(final int index) { + assertIsDispatchThread(); + + final boolean hadFocus = IJSwingUtilities.hasFocus2(myTabbedPaneHolder); + myTabbedPane.removeTabAt(index); + if (myTabbedPane.getTabCount() == 0) { + // to clear BasicTabbedPaneUI.visibleComponent field + myTabbedPane.revalidate(); + } + if (hadFocus) { + myTabbedPaneHolder.requestFocus(); + } + } + + public final synchronized int getTabCount() { + return myTabbedPane.getTabCount(); + } + + public final Color getForegroundAt(final int index){ + assertIsDispatchThread(); + return myTabbedPane.getForegroundAt(index); + } + + /** + * @see javax.swing.JTabbedPane#setForegroundAt(int, java.awt.Color) + */ + public final void setForegroundAt(final int index,final Color color){ + assertIsDispatchThread(); + myTabbedPane.setForegroundAt(index,color); + } + + /** + * @see javax.swing.JTabbedPane#setComponentAt(int, java.awt.Component) + */ + public final synchronized JComponent getComponentAt(final int i) { + return ((TabWrapper)myTabbedPane.getComponentAt(i)).getComponent(); + } + + public final void setTitleAt(final int index, final String title) { + assertIsDispatchThread(); + myTabbedPane.setTitleAt(index, title); + } + + public final void setToolTipTextAt(final int index, final String toolTipText) { + assertIsDispatchThread(); + myTabbedPane.setToolTipTextAt(index, toolTipText); + } + + /** + * @see javax.swing.JTabbedPane#setComponentAt(int, java.awt.Component) + */ + public final synchronized void setComponentAt(final int index, final JComponent component) { + assertIsDispatchThread(); + myTabbedPane.setComponentAt(index, new TabWrapper(component)); + } + + /** + * @see javax.swing.JTabbedPane#setIconAt(int, javax.swing.Icon) + */ + public final void setIconAt(final int index, final Icon icon) { + assertIsDispatchThread(); + myTabbedPane.setIconAt(index, icon); + } + + public final void setEnabledAt(final int index, final boolean enabled) { + assertIsDispatchThread(); + myTabbedPane.setEnabledAt(index, enabled); + } + + /** + * @see javax.swing.JTabbedPane#indexOfComponent(java.awt.Component) + */ + public final synchronized int indexOfComponent(final JComponent component) { + for (int i=0; i < myTabbedPane.getTabCount(); i++) { + final JComponent c = ((TabWrapper)myTabbedPane.getComponentAt(i)).getComponent(); + if (c == component) { + return i; + } + } + return -1; + } + + /** + * @see javax.swing.JTabbedPane#getTabLayoutPolicy + */ + public final synchronized int getTabLayoutPolicy(){ + return myTabbedPane.getTabLayoutPolicy(); + } + + /** + * @see javax.swing.JTabbedPane#setTabLayoutPolicy + */ + public final synchronized void setTabLayoutPolicy(final int policy){ + myTabbedPane.setTabLayoutPolicy(policy); + final int index=myTabbedPane.getSelectedIndex(); + if(index!=-1){ + myTabbedPane.scrollTabToVisible(index); + } + } + + /** + * Installs tab navigation via IdeActions.ACTION_NEXT_TAB and IdeActions.ACTION_PREVIOUS_TAB shortcuts. + */ + public final void installKeyboardNavigation(){ + final AnAction nextTabAction=new AnAction() { + { + setEnabledInModalContext(true); + } + public void actionPerformed(final AnActionEvent e) { + int index = getSelectedIndex() + 1; + if (index >= getTabCount()) { + index = 0; + } + setSelectedIndex(index); + } + }; + nextTabAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_TAB).getShortcutSet(), + getComponent() + ); + // make action work in modal dialog box + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JRootPane rootPane = SwingUtilities.getRootPane(getComponent()); + if (rootPane != null) { + nextTabAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_TAB).getShortcutSet(), + rootPane); + } + } + }); + final AnAction previousTabAction=new AnAction() { + { + setEnabledInModalContext(true); + } + public void actionPerformed(final AnActionEvent e) { + int index = getSelectedIndex() - 1; + if (index < 0) { + index = getTabCount() - 1; + } + setSelectedIndex(index); + } + }; + previousTabAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_TAB).getShortcutSet(), + getComponent() + ); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JRootPane rootPane = SwingUtilities.getRootPane(getComponent()); + if (rootPane != null) { + previousTabAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_TAB).getShortcutSet(), + rootPane + ); + } + } + }); + } + + public final String getTitleAt(final int i) { + return myTabbedPane.getTitleAt(i); + } + + private static final class TabWrapper extends JPanel implements DataProvider{ + private final JComponent myComponent; + + public TabWrapper(final JComponent component) { + super(new BorderLayout()); + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + myComponent = component; + add(component, BorderLayout.CENTER); + } + + /* + * Make possible to search down for DataProviders + */ + public Object getData(final String dataId) { + if(myComponent instanceof DataProvider){ + return ((DataProvider)myComponent).getData(dataId); + } else { + return null; + } + } + + public JComponent getComponent() { + return myComponent; + } + + public boolean requestDefaultFocus() { + final JComponent preferredFocusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myComponent); + if (preferredFocusedComponent != null) { + if (!preferredFocusedComponent.requestFocusInWindow()) { + preferredFocusedComponent.requestFocus(); + } + return true; + } else { + return myComponent.requestDefaultFocus(); + } + } + + public void requestFocus() { + requestDefaultFocus(); + } + + public boolean requestFocusInWindow() { + return requestDefaultFocus(); + } + } + + protected static class TabbedPane extends JTabbedPane { + private ScrollableTabSupport myScrollableTabSupport; + + public TabbedPane(final int tabPlacement) { + super(tabPlacement); + setFocusable(false); + addMouseListener( + new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + _requestDefaultFocus(); + } + } + ); + } + + public final void setUI(final TabbedPaneUI ui){ + super.setUI(ui); + if(ui instanceof BasicTabbedPaneUI){ + myScrollableTabSupport=new ScrollableTabSupport((BasicTabbedPaneUI)ui); + }else{ + myScrollableTabSupport=null; + } + } + + /** + * Scrolls tab to visible area. If tabbed pane has JTabbedPane.WRAP_TAB_LAYOUT layout policy then + * the method does nothing. + * @param index index of tab to be scrolled. + */ + public final void scrollTabToVisible(final int index){ + if(myScrollableTabSupport==null||JTabbedPane.WRAP_TAB_LAYOUT==getTabLayoutPolicy()){ // tab scrolling isn't supported by UI + return; + } + final TabbedPaneUI tabbedPaneUI=getUI(); + Rectangle tabBounds=tabbedPaneUI.getTabBounds(this,index); + final int tabPlacement=getTabPlacement(); + if(SwingConstants.TOP==tabPlacement || SwingConstants.BOTTOM==tabPlacement){ + if(tabBounds.x+tabBounds.width>getWidth()-50){ // if tab's right side is out of visible range + int leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + while(leadingTabIndexgetWidth()-50){ + myScrollableTabSupport.setLeadingTabIndex(leadingTabIndex+1); + leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + tabBounds=tabbedPaneUI.getTabBounds(this,index); + } + }else if(tabBounds.x<50){ + int leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + while(leadingTabIndex>0 && tabBounds.x<50){ + myScrollableTabSupport.setLeadingTabIndex(leadingTabIndex-1); + leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + tabBounds=tabbedPaneUI.getTabBounds(this,index); + } + } + }else{ // tabs are on left or right side + if(tabBounds.y+tabBounds.height>getHeight()-30){ + int leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + while(leadingTabIndexgetHeight()-30){ + myScrollableTabSupport.setLeadingTabIndex(leadingTabIndex+1); + leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + tabBounds=tabbedPaneUI.getTabBounds(this,index); + } + }else if(tabBounds.y<30){ + int leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + while(leadingTabIndex>0 && tabBounds.y<30){ + myScrollableTabSupport.setLeadingTabIndex(leadingTabIndex-1); + leadingTabIndex=myScrollableTabSupport.getLeadingTabIndex(); + tabBounds=tabbedPaneUI.getTabBounds(this,index); + } + } + } + } + + public final void setSelectedIndex(final int index){ + super.setSelectedIndex(index); + scrollTabToVisible(index); + doLayout(); + } + + public final void removeTabAt (final int index) { + final int oldIndex = getSelectedIndex (); + super.removeTabAt (index); + if (getSelectedIndex () == oldIndex) { + fireStateChanged(); + } + } + + private void _requestDefaultFocus() { + final TabWrapper selectedComponent = (TabWrapper)getSelectedComponent(); + if (selectedComponent != null) { + selectedComponent.requestDefaultFocus(); + } + else { + super.requestDefaultFocus(); + } + } + + protected final int getTabIndexAt(final int x,final int y){ + final TabbedPaneUI ui=getUI(); + for (int i = 0; i < getTabCount(); i++) { + final Rectangle bounds = ui.getTabBounds(this, i); + if (bounds.contains(x, y)) { + return i; + } + } + return -1; + } + + /** + * That is hack-helper for working with scrollable tab layout. The problem is BasicTabbedPaneUI doesn't + * have any API to scroll tab to visible area. Therefore we have to implement it... + */ + private final class ScrollableTabSupport{ + private final BasicTabbedPaneUI myUI; + + public ScrollableTabSupport(final BasicTabbedPaneUI ui){ + myUI=ui; + } + + /** + * @return value of leadingTabIndex field of BasicTabbedPaneUI.ScrollableTabSupport class. + */ + public int getLeadingTabIndex(){ + try{ + final Field tabScrollerField=BasicTabbedPaneUI.class.getDeclaredField("tabScroller"); + tabScrollerField.setAccessible(true); + final Object tabScrollerValue=tabScrollerField.get(myUI); + + final Field leadingTabIndexField=tabScrollerValue.getClass().getDeclaredField("leadingTabIndex"); + leadingTabIndexField.setAccessible(true); + return leadingTabIndexField.getInt(tabScrollerValue); + }catch(Exception exc){ + final StringWriter writer=new StringWriter(); + exc.printStackTrace(new PrintWriter(writer)); + throw new IllegalStateException("myUI="+myUI+"; cause="+writer.getBuffer()); + } + } + + public void setLeadingTabIndex(final int leadingIndex){ + try{ + final Field tabScrollerField=BasicTabbedPaneUI.class.getDeclaredField("tabScroller"); + tabScrollerField.setAccessible(true); + final Object tabScrollerValue=tabScrollerField.get(myUI); + + Method setLeadingIndexMethod=null; + final Method[] methods=tabScrollerValue.getClass().getDeclaredMethods(); + for(int i=0;i= myClickCountToStart; + } + return true; + } + + public boolean shouldSelectCell(EventObject anEvent) { + return true; + } + + public boolean stopCellEditing() { + fireEditingStopped(); + return true; + } + + public void cancelCellEditing() { + fireEditingCanceled(); + } + + public void actionPerformed(ActionEvent e) { + TableCellEditorWithButton.this.stopCellEditing(); + } + + public void itemStateChanged(ItemEvent e) { + TableCellEditorWithButton.this.stopCellEditing(); + } + } + + private class MyComponent extends JPanel { + private final JTextField myTextField; + private final FixedSizeButton myButton; + + public MyComponent() { + super(new GridBagLayout()); + + myTextField = new JTextField(); + myButton = new FixedSizeButton(myTextField); + + add(myTextField, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + add(myButton, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + } + + public FixedSizeButton getButton() { + return myButton; + } + + public JTextField getTextField() { + return myTextField; + } + + public boolean requestDefaultFocus() { + myTextField.requestFocus(); + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableCellKey.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableCellKey.java new file mode 100644 index 00000000000..03ba8df72fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableCellKey.java @@ -0,0 +1,33 @@ +package com.intellij.ui; + +/** + * (rowIndex, columnIndex) is a unique key to identify cell inside JTable + */ +final class TableCellKey{ + public final int myRowIndex; + public final int myColumnIndex; + + public TableCellKey(int rowIndex, int columnIndex) { + myRowIndex = rowIndex; + myColumnIndex = columnIndex; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TableCellKey)) return false; + + final TableCellKey myKey = (TableCellKey)o; + + if (myColumnIndex != myKey.myColumnIndex) return false; + if (myRowIndex != myKey.myRowIndex) return false; + + return true; + } + + public int hashCode() { + int result; + result = myRowIndex; + result = 29 * result + myColumnIndex; + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableToolTipHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableToolTipHandler.java new file mode 100644 index 00000000000..52a2667f90f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TableToolTipHandler.java @@ -0,0 +1,73 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; + +public class TableToolTipHandler extends AbstractToolTipHandler { + public TableToolTipHandler(JTable table) { + super(table); + } + + public static void install(JTable table) { + new TableToolTipHandler(table); + } + + public Rectangle getCellBounds(TableCellKey tableCellKey, Component rendererComponent) { + Rectangle cellRect = getCellRect(tableCellKey); + cellRect.width = rendererComponent.getPreferredSize().width; + return cellRect; + } + + private Rectangle getCellRect(TableCellKey tableCellKey) { + return myComponent.getCellRect(tableCellKey.myRowIndex, tableCellKey.myColumnIndex, false); + } + + public Component getRendererComponent(TableCellKey key) { + int modelColumnIndex = myComponent.convertColumnIndexToModel(key.myColumnIndex); + return myComponent.getCellRenderer(key.myRowIndex, key.myColumnIndex). + getTableCellRendererComponent(myComponent, + myComponent.getModel().getValueAt(key.myRowIndex, modelColumnIndex), + myComponent.getSelectionModel().isSelectedIndex(key.myRowIndex), + myComponent.hasFocus(), + key.myRowIndex,key.myColumnIndex + ); + } + + public Rectangle getVisibleRect(TableCellKey key) { + Rectangle columnVisibleRect = myComponent.getVisibleRect(); + Rectangle cellRect = getCellRect(key); + int visibleRight = Math.min(columnVisibleRect.x + columnVisibleRect.width, cellRect.x + cellRect.width); + columnVisibleRect.x = Math.min(columnVisibleRect.x, cellRect.x); + columnVisibleRect.width = Math.max(0, visibleRight - columnVisibleRect.x); + return columnVisibleRect; + } + + //private Rectangle getColumnRectangle(int columnIndex) { + // TableColumnModel cm = getColumnModel(); + // if (getComponentOrientation().isLeftToRight()) { + // for (int i = 0; i < column; i++) { + // r.x += cm.getColumn(i).getWidth(); + // } + // } + // else { + // for (int i = cm.getColumnCount() - 1; i > column; i--) { + // r.x += cm.getColumn(i).getWidth(); + // } + // } + // r.width = cm.getColumn(column).getWidth(); + //} + + public TableCellKey getCellKeyForPoint(Point point) { + int rowIndex = myComponent.rowAtPoint(point); + if (rowIndex == -1) { + return null; + } + + int columnIndex = myComponent.columnAtPoint(point); // column index in visible coordinates + if (columnIndex == -1) { + return null; + } + + return new TableCellKey(rowIndex, columnIndex); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeExpandCollapse.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeExpandCollapse.java new file mode 100644 index 00000000000..593b82f0aa1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeExpandCollapse.java @@ -0,0 +1,53 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeModel; + +public class TreeExpandCollapse { + public static void collapse(JTree tree) { + TreePath selectionPath = tree.getSelectionPath(); + tree.collapsePath(selectionPath); + } + + public static void expand(JTree tree) { + TreePath selectionPath = tree.getSelectionPath(); + tree.expandPath(selectionPath); + } + + public static void expandAll(JTree tree) { + TreePath path = tree.getSelectionPath(); + if (path == null) path = new TreePath(tree.getModel().getRoot()); + new ExpandContext(300, 10).expand(tree, path); + } + + private static class ExpandContext { + private int myLevelsLeft; + private int myExpansionLimit; + + public ExpandContext(int expansionLimit, int levelsLeft) { + myExpansionLimit = expansionLimit; + myLevelsLeft = levelsLeft; + } + + public int expand(JTree tree, TreePath path) { + if (myLevelsLeft == 0) return myExpansionLimit; + TreeModel model = tree.getModel(); + Object node = path.getLastPathComponent(); + int levelDecrement = 0; + if (!tree.isExpanded(path) && !model.isLeaf(node)) { + tree.expandPath(path); + levelDecrement = 1; + myExpansionLimit--; + } + for (int i = 0; i < model.getChildCount(node); i++) { + Object child = model.getChild(node, i); + if (model.isLeaf(child)) continue; + ExpandContext childContext = new ExpandContext(myExpansionLimit, myLevelsLeft - levelDecrement); + myExpansionLimit = childContext.expand(tree, path.pathByAddingChild(child)); + if (myExpansionLimit <= 0) return 0; + } + return myExpansionLimit; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeList.java new file mode 100644 index 00000000000..4a6c18e947a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeList.java @@ -0,0 +1,169 @@ +package com.intellij.ui; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Enumeration; +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.ListModel; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; + +/** + * @author Eugene Belyaev + */ +public class TreeList extends JList implements TreeModelListener { + private TreeModel myTreeModel; + private boolean myRootVisible = false; + private DefaultListModel myListModel = new DefaultListModel(); + + /** + * Constructs a JList with an empty model. + */ + public TreeList(TreeModel treeModel) { + super.setModel(myListModel); + myTreeModel = treeModel; + myTreeModel.addTreeModelListener(this); + Object root = myTreeModel.getRoot(); + if (root instanceof TreeNode) { + TreeNode node = (TreeNode) root; + myListModel.addElement(node); + if (myTreeModel instanceof DefaultTreeModel && ((DefaultTreeModel)myTreeModel).asksAllowsChildren() && node.getAllowsChildren()) { + Enumeration enumeration = node.children(); + while (enumeration.hasMoreElements()) { + Object object = enumeration.nextElement(); + myListModel.addElement(object); + } + } + } + } + + public boolean isRootVisible() { + return myRootVisible; + } + + public void setRootVisible(boolean rootVisible) { + myRootVisible = rootVisible; + } + + /** + * Sets the model that represents the contents or "value" of the + * list and clears the list selection after notifying + * PropertyChangeListeners. + *

    + * This is a JavaBeans bound property. + * + * @param model the ListModel that provides the + * list of items for display + * @exception IllegalArgumentException if model is + * null + * @see #getModel + * @beaninfo + * bound: true + * attribute: visualUpdate true + * description: The object that contains the data to be drawn by this JList. + */ + public void setModel(ListModel model) { + throw new UnsupportedOperationException("TreeList accepts only TreeModel as a model"); + } + + /** + *

    Invoked after a node (or a set of siblings) has changed in some + * way. The node(s) have not changed locations in the tree or + * altered their children arrays, but other attributes have + * changed and may affect presentation. Example: the name of a + * file has changed, but it is in the same location in the file + * system.

    + *

    To indicate the root has changed, childIndices and children + * will be null.

    + * + *

    Use e.getPath() + * to get the parent of the changed node(s). + * e.getChildIndices() + * returns the index(es) of the changed node(s).

    + */ + public void treeNodesChanged(TreeModelEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + /** + *

    Invoked after nodes have been inserted into the tree.

    + * + *

    Use e.getPath() + * to get the parent of the new node(s). + * e.getChildIndices() + * returns the index(es) of the new node(s) + * in ascending order.

    + */ + public void treeNodesInserted(TreeModelEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + /** + *

    Invoked after nodes have been removed from the tree. Note that + * if a subtree is removed from the tree, this method may only be + * invoked once for the root of the removed subtree, not once for + * each individual set of siblings removed.

    + * + *

    Use e.getPath() + * to get the former parent of the deleted node(s). + * e.getChildIndices() + * returns, in ascending order, the index(es) + * the node(s) had before being deleted.

    + */ + public void treeNodesRemoved(TreeModelEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + /** + *

    Invoked after the tree has drastically changed structure from a + * given node down. If the path returned by e.getPath() is of length + * one and the first element does not identify the current root node + * the first element should become the new root of the tree.

    + * + *

    Use e.getPath() + * to get the path to the node. + * e.getChildIndices() + * returns null.

    + */ + public void treeStructureChanged(TreeModelEvent e) { + //To change body of implemented methods use Options | File Templates. + } + + + + public static void main(String[] args) { + JFrame frame = new JFrame("TreeList Showcase"); + frame.setLocation(0, 0); + frame.setSize(800, 600); + frame.addWindowListener( + new WindowAdapter() { + /** + * Invoked when a window is in the process of being closed. + * The close operation can be overridden at this point. + */ + public void windowClosing(WindowEvent e) { + System.exit(0); + } + } + ); + Container contentPane = frame.getContentPane(); + contentPane.setLayout(new BorderLayout()); + DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Sample root node"); + for (int i = 0; i < 5; i++) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode("Node #" + (i + 1)); + rootNode.add(node); + } + DefaultTreeModel treeModel = new DefaultTreeModel(rootNode, true); + TreeList treeList = new TreeList(treeModel); + contentPane.add(treeList); + frame.setVisible(true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeSpeedSearch.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeSpeedSearch.java new file mode 100644 index 00000000000..9c25a4821bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeSpeedSearch.java @@ -0,0 +1,73 @@ +package com.intellij.ui; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.util.containers.Convertor; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; + +public class TreeSpeedSearch extends SpeedSearchBase { + private static final Convertor TO_STRING = new Convertor() { + public String convert(TreePath object) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)object.getLastPathComponent(); + return node.toString(); + } + }; + private final Convertor myToStringConvertor; + public static final Convertor NODE_DESCRIPTOR_TOSTRING = new Convertor() { + public String convert(TreePath path) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + final Object userObject = node.getUserObject(); + if (userObject instanceof NodeDescriptor) { + NodeDescriptor descr = (NodeDescriptor) userObject; + return descr.toString(); + } + return TO_STRING.convert(path); + } + }; + + /** + * @deprecated You should use {@link TreeSpeedSearch#TreeSpeedSearch(JTree)} + * @see com.intellij.util.ui.Tree#getNextMatch(String, int, javax.swing.text.Position.Bias) + */ + public TreeSpeedSearch(JTree tree, Convertor toStringConvertor) { + super(tree); + myToStringConvertor = toStringConvertor; + } + + public TreeSpeedSearch(JTree tree) { + this(tree, TO_STRING); + } + + public TreeSpeedSearch(Tree tree, Convertor toString) { + super(tree); + myToStringConvertor = toString; + } + + protected void selectElement(Object element, String selectedText) { + TreeUtil.selectPath(myComponent, (TreePath)element); + } + + protected int getSelectedIndex() { + int[] selectionRows = myComponent.getSelectionRows(); + return selectionRows == null || selectionRows.length == 0 ? -1 : selectionRows[0]; + } + + protected Object[] getAllElements() { + TreePath[] paths = new TreePath[myComponent.getRowCount()]; + for(int i = 0; i < paths.length; i++){ + paths[i] = myComponent.getPathForRow(i); + } + return paths; + } + + protected String getElementText(Object element) { + TreePath path = (TreePath)element; + String string = myToStringConvertor.convert(path); + if (string == null) return TO_STRING.convert(path); + return string; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeToolTipHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeToolTipHandler.java new file mode 100644 index 00000000000..c138fc7123f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/TreeToolTipHandler.java @@ -0,0 +1,63 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.*; + +public final class TreeToolTipHandler extends AbstractToolTipHandler{ + protected TreeToolTipHandler(JTree tree) { + super(tree); + tree.getSelectionModel().addTreeSelectionListener( + new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + repaintHint(); + } + } + ); + } + + public static void install(JTree tree) { + new TreeToolTipHandler(tree); + } + + protected Integer getCellKeyForPoint(Point point) { + int rowIndex = myComponent.getRowForLocation(point.x, point.y); + return rowIndex != -1 ? new Integer(rowIndex) : null; + } + + protected Rectangle getCellBounds(Integer key, Component rendererComponent) { + int rowIndex = key.intValue(); + TreePath path = myComponent.getPathForRow(rowIndex); + Rectangle cellBounds = myComponent.getPathBounds(path); + return cellBounds; + } + + protected Component getRendererComponent(Integer key) { + int rowIndex = key.intValue(); + Component rComponent; + TreeCellRenderer renderer = myComponent.getCellRenderer(); + if (renderer == null) { + rComponent = null; + } else { + TreePath path = myComponent.getPathForRow(rowIndex); + if (path == null) { + rComponent = null; + } else { + Object node = path.getLastPathComponent(); + rComponent = renderer.getTreeCellRendererComponent( + myComponent, + node, + myComponent.isRowSelected(rowIndex), + myComponent.isExpanded(rowIndex), + myComponent.getModel().isLeaf(node), + rowIndex, + myComponent.hasFocus() + ); + } + } + return rComponent; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ComponentContentUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ComponentContentUI.java new file mode 100644 index 00000000000..dfe4ad56396 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ComponentContentUI.java @@ -0,0 +1,53 @@ +package com.intellij.ui.content; + + +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.DataProvider; + +import javax.swing.*; +import java.awt.*; + +public class ComponentContentUI implements ContentUI { + private ContentManager myManager; + private JPanel myPanel; + + public ComponentContentUI() { + myPanel = new MyPanel(); + } + + public JComponent getComponent() { + return myPanel; + } + + public void setManager(ContentManager manager) { + myManager = manager; + myManager.addContentManagerListener(new MyContentManagerListener()); + } + + private class MyContentManagerListener extends ContentManagerAdapter { + public void selectionChanged(ContentManagerEvent event) { + myPanel.removeAll(); + Content content = event.getContent(); + if (content != null) { + myPanel.add(content.getComponent(), BorderLayout.CENTER); + myPanel.validate(); + myPanel.repaint(); + } + } + } + + private class MyPanel extends JPanel implements DataProvider { + public MyPanel() { + super(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + } + + public Object getData(String dataId) { + if (DataConstantsEx.CONTENT_MANAGER.equals(dataId)) { + return myManager; + } + return null; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentFactoryImpl.java new file mode 100644 index 00000000000..b7603945713 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentFactoryImpl.java @@ -0,0 +1,22 @@ +package com.intellij.ui.content; + +import com.intellij.ui.content.impl.ContentImpl; +import com.intellij.ui.content.impl.ContentManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; + +import javax.swing.*; + +public class ContentFactoryImpl implements ContentFactory { + public ContentImpl createContent(JComponent component, String displayName, boolean isLockable) { + return new ContentImpl(component, displayName, isLockable); + } + + public ContentManagerImpl createContentManager(ContentUI contentUI, boolean canCloseContents, Project project) { + return new ContentManagerImpl(contentUI, canCloseContents, project, ProjectManager.getInstance()); + } + + public ContentManager createContentManager(boolean canCloseContents, Project project) { + return new ContentManagerImpl(new TabbedPaneContentUI(), canCloseContents, project, ProjectManager.getInstance()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentManagerUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentManagerUtil.java new file mode 100644 index 00000000000..512abeb7fc8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/ContentManagerUtil.java @@ -0,0 +1,44 @@ +package com.intellij.ui.content; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.ide.DataManager; + +import javax.swing.*; + +public class ContentManagerUtil { + /** + * This is utility method. It returns ContentManager from the current context. + */ + public static ContentManager getContentManagerFromContext(DataContext dataContext, boolean requiresVisibleToolWindow){ + Project project = (Project)dataContext.getData(DataConstants.PROJECT); + if (project == null) { + return null; + } + + ToolWindowManagerEx mgr=ToolWindowManagerEx.getInstanceEx(project); + + String id = mgr.getActiveToolWindowId(); + if (id == null) { + if(mgr.isEditorComponentActive()){ + id = mgr.getLastActiveToolWindowId(); + } + } + if(id == null){ + return null; + } + + ToolWindowEx toolWindow = (ToolWindowEx)mgr.getToolWindow(id); + if (requiresVisibleToolWindow && !toolWindow.isVisible()) { + return null; + } + + JComponent component = toolWindow.getComponent(); + ContentManager contentManager = (ContentManager)DataManager.getInstance().getDataContext(component).getData(DataConstantsEx.CONTENT_MANAGER); + return contentManager; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/MessageView.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/MessageView.java new file mode 100644 index 00000000000..c830c474089 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/MessageView.java @@ -0,0 +1,4 @@ +package com.intellij.ui.content; + +public interface MessageView extends ContentManager { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/TabbedPaneContentUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/TabbedPaneContentUI.java new file mode 100644 index 00000000000..03c6b7ccfc9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/TabbedPaneContentUI.java @@ -0,0 +1,392 @@ +package com.intellij.ui.content; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.TabbedPaneUI; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * @author Eugene Belyaev + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class TabbedPaneContentUI implements ContentUI, PropertyChangeListener { + private ContentManager myManager; + private TabbedPaneWrapper myTabbedPaneWrapper; + + /** + * Creates TabbedPaneContentUI with bottom tab placement. + */ + public TabbedPaneContentUI() { + this(JTabbedPane.BOTTOM); + } + + /** + * Creates TabbedPaneContentUI with cpecified tab placement. + * + * @param tabPlacement constant which defines where the tabs are located. + * Acceptable values are javax.swing.JTabbedPane#TOP, + * javax.swing.JTabbedPane#LEFT, javax.swing.JTabbedPane#BOTTOM + * and javax.swing.JTabbedPane#RIGHT. + */ + public TabbedPaneContentUI(int tabPlacement) { + myTabbedPaneWrapper = new MyTabbedPaneWrapper(tabPlacement); + } + + public JComponent getComponent() { + return myTabbedPaneWrapper.getComponent(); + } + + public void setManager(ContentManager manager) { + if (myManager != null) { + throw new IllegalStateException(); + } + myManager = manager; + myManager.addContentManagerListener(new MyContentManagerListener()); + } + + public void propertyChange(PropertyChangeEvent e) { + if (Content.PROP_DISPLAY_NAME.equals(e.getPropertyName())) { + Content content = (Content)e.getSource(); + int index = myTabbedPaneWrapper.indexOfComponent(content.getComponent()); + if (index != -1) { + myTabbedPaneWrapper.setTitleAt(index, content.getDisplayName()); + } + } + else if (Content.PROP_DESCRIPTION.equals(e.getPropertyName())) { + Content content = (Content)e.getSource(); + int index = myTabbedPaneWrapper.indexOfComponent(content.getComponent()); + if (index != -1) { + myTabbedPaneWrapper.setToolTipTextAt(index, content.getDescription()); + } + } + else if (Content.PROP_COMPONENT.equals(e.getPropertyName())) { + Content content = (Content)e.getSource(); + JComponent oldComponent = (JComponent)e.getOldValue(); + int index = myTabbedPaneWrapper.indexOfComponent(oldComponent); + if (index != -1) { + boolean hasFocus = IJSwingUtilities.hasFocus2(oldComponent); + myTabbedPaneWrapper.setComponentAt(index, content.getComponent()); + if (hasFocus) { + (content.getComponent()).requestDefaultFocus(); + } + } + } + else if (Content.PROP_ICON.equals(e.getPropertyName())) { + Content content = (Content)e.getSource(); + int index = myTabbedPaneWrapper.indexOfComponent(content.getComponent()); + if (index != -1) { + myTabbedPaneWrapper.setIconAt(index, (Icon)e.getNewValue()); + } + } + } + + private Content getSelectedContent() { + JComponent selectedComponent = myTabbedPaneWrapper.getSelectedComponent(); + return myManager.getContent(selectedComponent); + } + + /** + * Removes specified content. + */ + private class CloseAction extends AnAction { + private Content myContent; + + public CloseAction(Content content) { + myContent = content; + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE_ACTIVE_TAB)); + getTemplatePresentation().setText("Close Tab"); + } + + public void actionPerformed(AnActionEvent e) { + myManager.removeContent(myContent); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myContent != null && myManager.canCloseContents()); + presentation.setVisible(myManager.canCloseContents()); + } + } + + /** + * Removes all contents. + */ + private class CloseAllAction extends AnAction { + public CloseAllAction() { + super("Close All"); + } + + public void actionPerformed(AnActionEvent e) { + myManager.removeAllContents(); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myManager.getContentCount() > 0 && myManager.canCloseContents()); + presentation.setVisible(myManager.canCloseContents()); + } + } + + /** + * Removes all contents but specified. + */ + private class CloseAllButThisAction extends AnAction { + private Content myContent; + + public CloseAllButThisAction(Content content) { + super("Close All But This"); + myContent = content; + } + + public void actionPerformed(AnActionEvent e) { + Content[] contents = myManager.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (myContent != content) { + myManager.removeContent(content); + } + } + myManager.setSelectedContent(myContent); + } + + public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + presentation.setEnabled(myContent != null && myManager.canCloseContents() && myManager.getContentCount() > 1); + presentation.setVisible(myManager.canCloseContents()); + } + } + + /** + * Pins tab that corresponds to the content + */ + private class MyPinTabAction extends ToggleAction { + private Content myContent; + + public MyPinTabAction(Content content) { + myContent = content; + Presentation presentation = getTemplatePresentation(); + presentation.setText("Pin Tab"); + presentation.setDescription("Pin tool window tab"); + } + + public boolean isSelected(AnActionEvent event) { + return myContent != null && myContent.isPinned(); + } + + public void setSelected(AnActionEvent event, boolean flag) { + myContent.setPinned(flag); + } + + public void update(AnActionEvent event) { + super.update(event); + Presentation presentation = event.getPresentation(); + boolean enabled = myContent != null && myContent.isPinnable(); + presentation.setEnabled(enabled); + presentation.setVisible(enabled); + } + } + + private final class MyNextTabAction extends AnAction { + public MyNextTabAction() { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_TAB)); + } + + public void actionPerformed(AnActionEvent e) { + myManager.selectNextContent(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myManager.getContentCount() > 1); + } + } + + private final class MyPreviousTabAction extends AnAction { + public MyPreviousTabAction() { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_TAB)); + } + + public void actionPerformed(AnActionEvent e) { + myManager.selectPreviousContent(); + } + + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myManager.getContentCount() > 1); + } + } + + + private class MyTabbedPaneWrapper extends TabbedPaneWrapper { + public MyTabbedPaneWrapper(int tabPlacement) { + super(tabPlacement); + } + + protected TabbedPaneWrapper.TabbedPane createTabbedPane(int tabPlacement) { + return new MyTabbedPane(tabPlacement); + } + + protected JComponent createTabbedPaneHolder() { + return new MyTabbedPaneHolder(); + } + + private class MyTabbedPane extends TabbedPane { + public MyTabbedPane(int tabPlacement) { + super(tabPlacement); + addMouseListener(new MyPopupHandler()); + enableEvents(MouseEvent.MOUSE_EVENT_MASK); + } + + private void closeTabAt(int x, int y) { + TabbedPaneUI ui = getUI(); + int index = ui.tabForCoordinate(this, x, y); + if (index < 0 || !myManager.canCloseContents()) { + return; + } + myManager.removeContent(myManager.getContent(index)); + } + + /** + * Hides selected menu. + */ + private void hideMenu() { + MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); + menuSelectionManager.clearSelectedPath(); + } + + protected void processMouseEvent(MouseEvent e) { + if (e.isPopupTrigger()) { // Popup doesn't activate clicked tab. + showPopup(e.getX(), e.getY()); + return; + } + + if (!e.isShiftDown() && (MouseEvent.BUTTON1_MASK & e.getModifiers()) > 0) { // RightClick without Shift modifiers just select tab + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + TabbedPaneUI ui = getUI(); + int index = ui.tabForCoordinate(this, e.getX(), e.getY()); + if (index != -1) { + setSelectedIndex(index); + } + hideMenu(); + } + } + else if (e.isShiftDown() && (MouseEvent.BUTTON1_MASK & e.getModifiers()) > 0) { // Shift+LeftClick closes the tab + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + closeTabAt(e.getX(), e.getY()); + hideMenu(); + } + } + else if ((MouseEvent.BUTTON2_MASK & e.getModifiers()) > 0) { // MouseWheelClick closes the tab + if (MouseEvent.MOUSE_RELEASED == e.getID()) { + closeTabAt(e.getX(), e.getY()); + hideMenu(); + } + } + else if ((MouseEvent.BUTTON3_MASK & e.getModifiers()) > 0 && SystemInfo.isWindows) { // Right mouse button doesn't activate tab + } + else { + super.processMouseEvent(e); + } + } + + protected ChangeListener createChangeListener() { + return new MyModelListener(); + } + + private class MyModelListener extends JTabbedPane.ModelListener { + public void stateChanged(ChangeEvent e) { + Content content = getSelectedContent(); + if (content != null) { + myManager.setSelectedContent(content); + } + super.stateChanged(e); + } + } + + /** + * @return content at the specified location. x and y are in + * tabbed pane coordinate system. The method returns null if there is no contnt at the + * specified location. + */ + private Content getContentAt(int x, int y) { + TabbedPaneUI ui = getUI(); + int index = ui.tabForCoordinate(this, x, y); + if (index < 0) { + return null; + } + return myManager.getContent(index); + } + + protected class MyPopupHandler extends PopupHandler { + public void invokePopup(Component comp, int x, int y) { + if (myManager.getContentCount() == 0) return; + showPopup(x, y); + } + } + + /** + * Shows showPopup menu at the specified location. The x and y coordinates + * are in JTabbedPane coordinate system. + */ + private void showPopup(int x, int y) { + Content content = getContentAt(x, y); + if (content == null) { + return; + } + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new CloseAction(content)); + if (myTabbedPaneWrapper.getTabCount() > 1) { + group.add(new CloseAllAction()); + group.add(new CloseAllButThisAction(content)); + } + group.addSeparator(); + group.add(new MyPinTabAction(content)); + group.addSeparator(); + group.add(new MyNextTabAction()); + group.add(new MyPreviousTabAction()); + ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); + menu.getComponent().show(myTabbedPaneWrapper.getComponent(), x, y); + } + } + + private class MyTabbedPaneHolder extends TabbedPaneHolder implements DataProvider { + public Object getData(String dataId) { + if (DataConstantsEx.CONTENT_MANAGER.equals(dataId)) { + return myManager; + } + return null; + } + } + } + + private class MyContentManagerListener extends ContentManagerAdapter { + public void contentAdded(ContentManagerEvent event) { + Content content = event.getContent(); + myTabbedPaneWrapper.insertTab(content.getDisplayName(), + content.getIcon(), + content.getComponent(), + content.getDescription(), + event.getIndex()); + content.addPropertyChangeListener(TabbedPaneContentUI.this); + } + + public void contentRemoved(ContentManagerEvent event) { + event.getContent().removePropertyChangeListener(TabbedPaneContentUI.this); + myTabbedPaneWrapper.removeTabAt(event.getIndex()); + } + + public void selectionChanged(ContentManagerEvent event) { + myTabbedPaneWrapper.setSelectedIndex(event.getIndex()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentImpl.java new file mode 100644 index 00000000000..10f734bf362 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentImpl.java @@ -0,0 +1,162 @@ + +package com.intellij.ui.content.impl; + +import com.intellij.openapi.Disposeable; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Key; +import com.intellij.ui.LayeredIcon; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Hashtable; + +public class ContentImpl implements Content { + private String myDisplayName; + private String myDescription; + private JComponent myComponent; + private Icon myIcon; + private PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this); + private ContentManager myManager = null; + private Hashtable myUserData = new Hashtable(); + private boolean myIsLocked = false; + private boolean myPinnable = true; + private LayeredIcon myLayeredIcon = new LayeredIcon(2); + private Disposeable myDisposer = null; + + public ContentImpl(JComponent component, String displayName, boolean isPinnable) { + myComponent = component; + myDisplayName = displayName; + myPinnable = isPinnable; + } + + public JComponent getComponent() { + return myComponent; + } + + public void setComponent(JComponent component) { + Component oldComponent = myComponent; + myComponent = component; + myChangeSupport.firePropertyChange(PROP_COMPONENT, oldComponent, myComponent); + } + + public void setIcon(Icon icon) { + Icon oldValue = getIcon(); + myIcon = icon; + myLayeredIcon.setIcon(myIcon, 0); + myLayeredIcon.setIcon(IconLoader.getIcon("/nodes/tabPin.png"), 1); + myChangeSupport.firePropertyChange(PROP_ICON, oldValue, getIcon()); + } + + public Icon getIcon() { + if (myIsLocked) { + return myIcon == null ? IconLoader.getIcon("/nodes/pin.png") : myLayeredIcon; + } + else { + return myIcon; + } + } + + public void setDisplayName(String displayName) { + String oldValue = myDisplayName; + myDisplayName = displayName; + myChangeSupport.firePropertyChange(PROP_DISPLAY_NAME, oldValue, myDisplayName); + } + + public String getDisplayName() { + return myDisplayName; + } + + public Disposeable getDisposer() { + return myDisposer; + } + + public void setDisposer(Disposeable disposer) { + myDisposer = disposer; + } + + public String getDescription() { + return myDescription; + } + + public void setDescription(String description) { + String oldValue = myDescription; + myDescription = description; + myChangeSupport.firePropertyChange(PROP_DESCRIPTION, oldValue, myDescription); + } + + public void addPropertyChangeListener(PropertyChangeListener l) { + myChangeSupport.addPropertyChangeListener(l); + } + + public void removePropertyChangeListener(PropertyChangeListener l) { + myChangeSupport.removePropertyChangeListener(l); + } + + public void setManager(ContentManager manager) { + myManager = manager; + } + + public ContentManager getManager() { + return myManager; + } + + public boolean isSelected() { + if (myManager == null) return false; + return (myManager.getSelectedContent() == this); + } + + public void putUserData(Key key, T value) { + if (key == null) return; + if (value != null){ + myUserData.put(key, value); + } + else{ + myUserData.remove(key); + } + } + + public T getUserData(Key key) { + if (key == null) return null; + return (T)myUserData.get(key); + } + + public final void release() { + myComponent = null; + myManager = null; + if (myUserData != null) { + myUserData.clear(); + } + myUserData = null; + + if (myDisposer != null) { + myDisposer.dispose(); + myDisposer = null; + } + } + + //TODO[anton,vova] investigate + public boolean isValid() { + return myManager != null; + } + + public boolean isPinned() { + return myIsLocked; + } + + public void setPinned(boolean locked) { + if (isPinnable()) { + Icon oldIcon = getIcon(); + myIsLocked = locked; + Icon newIcon = getIcon(); + myChangeSupport.firePropertyChange(PROP_ICON, oldIcon, newIcon); + } + } + + public boolean isPinnable() { + return myPinnable; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentManagerImpl.java new file mode 100644 index 00000000000..fe32425cc03 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/ContentManagerImpl.java @@ -0,0 +1,272 @@ +package com.intellij.ui.content.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.content.*; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class ContentManagerImpl implements ContentManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.content.impl.ContentManagerImpl"); + + private ContentUI myUI; + private ArrayList myContents; + private EventListenerList myListeners; + private Content mySelectedContent; + private boolean myCanCloseContents; + + private final Project myProject; + + private final ProjectManagerAdapter myProjectManagerListener; + private boolean myListenerAdded; + + /** + * WARNING: as this class adds listener to the ProjectManager which is removed on projectClosed event, all instances of this class + * must be created on already OPENED projects, otherwise there will be memory leak! + */ + public ContentManagerImpl(ContentUI contentUI, boolean canCloseContents, Project project, final ProjectManager projectManager) { + myCanCloseContents = canCloseContents; + myContents = new ArrayList(); + myListeners = new EventListenerList(); + myUI = contentUI; + myUI.setManager(this); + myProject = project; + + myProjectManagerListener = new ProjectManagerAdapter() { + public void projectClosed(Project project) { + if (project == myProject) { + Content[] contents = myContents.toArray(new Content[myContents.size()]); + for (int i = 0; i < contents.length; i++) { + removeContent(contents[i]); + } + } + } + }; + } + + public boolean canCloseContents() { + return myCanCloseContents; + } + + public JComponent getComponent() { + return myUI.getComponent(); + } + + public void addContent(Content content) { + try { + ((ContentImpl)content).setManager(this); + myContents.add(content); + fireContentAdded(content, myContents.size() - 1); + if (mySelectedContent == null) { + setSelectedContent(content); + } + } finally { + addProjectManagerListener(); + } + + } + + // [Valentin] Q: throw exception when failed? + public boolean removeContent(Content content) { + try { + int selectedIndex = myContents.indexOf(mySelectedContent); + int indexToBeRemoved = myContents.indexOf(content); + if (indexToBeRemoved < 0) { + return false; + } + if (!fireContentRemoveQuery(content, indexToBeRemoved)) { + return false; + } + if (!content.isValid()) { + return false; // the content has already been invalidated by another thread or something + } + + + boolean wasSelected = (content == mySelectedContent); + int indexToSelect = -1; + if (wasSelected) { + int i = indexToBeRemoved - 1; + if (i >= 0) { + indexToSelect = i; + } + else if (getContentCount() > 1) { + indexToSelect = 0; + } + } + else if (selectedIndex > indexToBeRemoved) { + indexToSelect = selectedIndex - 1; + } + + myContents.remove(content); + + int newSize = myContents.size(); + if (newSize > 0) { + if (indexToSelect > -1) { + setSelectedContent(myContents.get(indexToSelect)); + } + } + else { + setSelectedContent(null); + } + fireContentRemoved(content, indexToBeRemoved); + ((ContentImpl)content).setManager(null); + + return true; + } finally { + removeProjectManagerListener(); + } + } + + private void addProjectManagerListener() { + if (!myListenerAdded && myContents.size() > 0) { + ProjectManager.getInstance().addProjectManagerListener(myProjectManagerListener); + myListenerAdded = true; + } + } + + private void removeProjectManagerListener() { + if (myListenerAdded && myContents.size()==0) { + ProjectManager.getInstance().removeProjectManagerListener(myProjectManagerListener); + myListenerAdded = false; + } + } + + public void removeAllContents() { + Content[] contents = getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + removeContent(content); + } + } + + public int getContentCount() { + return myContents.size(); + } + + public Content[] getContents() { + return (Content[])myContents.toArray(new ContentImpl[myContents.size()]); + } + + //TODO[anton,vova] is this method needed? + public Content findContent(String displayName) { + for (int i = 0; i < myContents.size(); i++) { + Content content = myContents.get(i); + if (content.getDisplayName().equals(displayName)) { + return content; + } + } + return null; + } + + public Content getContent(int index) { + return myContents.get(index); + } + + public Content getContent(JComponent component) { + Content[] contents = getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (Comparing.equal(component, content.getComponent())) { + return content; + } + } + return null; + } + + public int getIndexOfContent(Content content) { + return myContents.indexOf(content); + } + + public Content getSelectedContent() { + return mySelectedContent; + } + + public void setSelectedContent(Content content) { + int index; + if (content != null) { + index = getIndexOfContent(content); + if (index == -1) { + throw new IllegalArgumentException("content not found: " + content); + } + } + else { + index = -1; + } + if (mySelectedContent != content) { + mySelectedContent = content; + fireSelectionChanged(content, index); + } + } + + public void selectPreviousContent() { + int contentCount = getContentCount(); + LOG.assertTrue(contentCount > 1); + Content selectedContent = getSelectedContent(); + int index = getIndexOfContent(selectedContent); + index = (index - 1 + contentCount) % contentCount; + setSelectedContent(getContent(index)); + } + + public void selectNextContent() { + int contentCount = getContentCount(); + LOG.assertTrue(contentCount > 1); + Content selectedContent = getSelectedContent(); + int index = getIndexOfContent(selectedContent); + index = (index + 1) % contentCount; + setSelectedContent(getContent(index)); + } + + public void addContentManagerListener(ContentManagerListener l) { + myListeners.add(ContentManagerListener.class, l); + } + + public void removeContentManagerListener(ContentManagerListener l) { + myListeners.remove(ContentManagerListener.class, l); + } + + + protected void fireContentAdded(Content content, int newIndex) { + ContentManagerEvent event = new ContentManagerEvent(this, content, newIndex); + ContentManagerListener[] listeners = (ContentManagerListener[])myListeners.getListeners(ContentManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].contentAdded(event); + } + } + + protected void fireContentRemoved(Content content, int oldIndex) { + ContentManagerEvent event = new ContentManagerEvent(this, content, oldIndex); + ContentManagerListener[] listeners = (ContentManagerListener[])myListeners.getListeners(ContentManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].contentRemoved(event); + } + } + + protected void fireSelectionChanged(Content content, int index) { + ContentManagerEvent event = new ContentManagerEvent(this, content, index); + ContentManagerListener[] listeners = (ContentManagerListener[])myListeners.getListeners(ContentManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].selectionChanged(event); + } + } + + protected boolean fireContentRemoveQuery(Content content, int oldIndex) { + ContentManagerEvent event = new ContentManagerEvent(this, content, oldIndex); + ContentManagerListener[] listeners = (ContentManagerListener[])myListeners.getListeners(ContentManagerListener.class); + for (int i = 0; i < listeners.length; i++) { + listeners[i].contentRemoveQuery(event); + if (event.isConsumed()) { + return false; + } + } + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/MessageViewImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/MessageViewImpl.java new file mode 100644 index 00000000000..307e4a56857 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/content/impl/MessageViewImpl.java @@ -0,0 +1,47 @@ + +package com.intellij.ui.content.impl; + +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.ui.content.MessageView; +import com.intellij.ui.content.TabbedPaneContentUI; + +/** + * @author Eugene Belyaev + */ +public class MessageViewImpl extends ContentManagerImpl implements ProjectComponent, MessageView { + private Project myProject; + + public MessageViewImpl(Project project, ProjectManager projectManager) { + super(new TabbedPaneContentUI(), true, project, projectManager); + myProject = project; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public void projectOpened() { + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow=toolWindowManager.registerToolWindow(ToolWindowId.MESSAGES_WINDOW,getComponent(),ToolWindowAnchor.BOTTOM); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowMessages.png")); + new ContentManagerWatcher(toolWindow,this); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.MESSAGES_WINDOW); + } + + public String getComponentName() { + return "MessageViewImpl"; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/errorView/impl/ErrorViewFactoryImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/errorView/impl/ErrorViewFactoryImpl.java new file mode 100644 index 00000000000..a62c4764547 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/errorView/impl/ErrorViewFactoryImpl.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij.ui.errorView.impl; + +import com.intellij.ui.errorView.ErrorViewFactory; +import com.intellij.ui.errorView.ContentManagerProvider; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; + +public class ErrorViewFactoryImpl implements ErrorViewFactory { + public ErrorTreeView createErrorTreeView(Project project, + String helpId, + boolean createExitAction, + final AnAction[] extraPopupMenuActions, + final AnAction[] extraRightToolbarGroupActions, + final ContentManagerProvider contentManagerProvider) { + return new NewErrorTreeViewPanel(project, helpId, createExitAction) { + protected void addExtraPopupMenuActions(DefaultActionGroup group) { + super.addExtraPopupMenuActions(group); + if (extraPopupMenuActions != null){ + for (int i = 0; i < extraPopupMenuActions.length; i++) { + group.add(extraPopupMenuActions[i]); + } + } + } + + protected void fillRightToolbarGroup(DefaultActionGroup group) { + super.fillRightToolbarGroup(group); + if (extraRightToolbarGroupActions != null){ + for (int i = 0; i < extraRightToolbarGroupActions.length; i++) { + group.add(extraRightToolbarGroupActions[i]); + } + } + } + + public void close() { + ContentManager contentManager = contentManagerProvider.getParentContent(); + Content content = contentManager.getContent(this); + if (content != null) { + contentManager.removeContent(content); + } + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegBorders.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegBorders.java new file mode 100644 index 00000000000..bfcdb626adb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegBorders.java @@ -0,0 +1,255 @@ +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.border.AbstractBorder; +import javax.swing.border.Border; +import javax.swing.border.LineBorder; +import javax.swing.plaf.BorderUIResource; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicBorders; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.text.JTextComponent; +import java.awt.*; + +/** + * @author Eugene Belyaev + */ +public class BegBorders { + private static Border ourButtonBorder; + private static Border ourTextFieldBorder; + private static Border ourScrollPaneBorder; + + public static Border getButtonBorder() { + if (ourButtonBorder == null) { + ourButtonBorder = new BorderUIResource.CompoundBorderUIResource( + new ButtonBorder(), + new BasicBorders.MarginBorder()); + } + return ourButtonBorder; + } + + public static Border getTextFieldBorder() { + if (ourTextFieldBorder == null) { + ourTextFieldBorder = new BorderUIResource.CompoundBorderUIResource( + new TextFieldBorder(), + //new FlatLineBorder(), + BorderFactory.createEmptyBorder(2, 2, 2, 2)); + } + return ourTextFieldBorder; + } + + public static Border getScrollPaneBorder() { + if (ourScrollPaneBorder == null) { + ourScrollPaneBorder = new BorderUIResource.LineBorderUIResource(MetalLookAndFeel.getControlDarkShadow()); + //ourScrollPaneBorder = new FlatLineBorder(); + } + return ourScrollPaneBorder; + } + + + public static class FlatLineBorder extends LineBorder implements UIResource { + public FlatLineBorder() { + super(new Color(127, 157, 185), 1, true); + } + } + + public static class ButtonBorder extends AbstractBorder implements UIResource { + protected static Insets borderInsets = new Insets(3, 3, 3, 3); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + + if (model.isEnabled()) { + boolean isPressed = model.isPressed() && model.isArmed(); + boolean isDefault = (button instanceof JButton && ((JButton) button).isDefaultButton()); + + if (isPressed && isDefault) { + drawDefaultButtonPressedBorder(g, x, y, w, h); + } else if (isPressed) { + drawPressed3DBorder(g, x, y, w, h); + } else if (isDefault) { + drawDefaultButtonBorder(g, x, y, w, h, false); + } else { + drawButtonBorder(g, x, y, w, h, false); + } + } else { // disabled state + drawDisabledBorder(g, x, y, w - 1, h - 1); + } + } + + public Insets getBorderInsets(Component c) { + return borderInsets; + } + + public Insets getBorderInsets(Component c, Insets newInsets) { + newInsets.top = borderInsets.top; + newInsets.left = borderInsets.left; + newInsets.bottom = borderInsets.bottom; + newInsets.right = borderInsets.right; + return newInsets; + } + } + + public static class ScrollPaneBorder extends AbstractBorder implements UIResource { + private static final Insets insets = new Insets(1, 1, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, + int w, int h) { + JScrollPane scroll = (JScrollPane) c; + JComponent colHeader = scroll.getColumnHeader(); + int colHeaderHeight = 0; + if (colHeader != null) + colHeaderHeight = colHeader.getHeight(); + + JComponent rowHeader = scroll.getRowHeader(); + int rowHeaderWidth = 0; + if (rowHeader != null) + rowHeaderWidth = rowHeader.getWidth(); + + /* + g.translate(x, y); + + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawRect(0, 0, w - 2, h - 2); + g.setColor(MetalLookAndFeel.getControlHighlight()); + + g.drawLine(w - 1, 1, w - 1, h - 1); + g.drawLine(1, h - 1, w - 1, h - 1); + + g.setColor(MetalLookAndFeel.getControl()); + if (colHeaderHeight > 0) { + g.drawLine(w - 2, 2 + colHeaderHeight, w - 2, 2 + colHeaderHeight); + } + if (rowHeaderWidth > 0) { + g.drawLine(1 + rowHeaderWidth, h - 2, 1 + rowHeaderWidth, h - 2); + } + + g.translate(-x, -y); + */ + + drawLineBorder(g, x, y, w, h); + } + + public Insets getBorderInsets(Component c) { + return insets; + } + } + + public static class TextFieldBorder /*extends MetalBorders.Flush3DBorder*/ extends LineBorder implements UIResource { + public TextFieldBorder() { + super(null, 1); + } + + public boolean isBorderOpaque() { + return false; + } + + public void paintBorder(Component c, Graphics g, int x, int y, + int w, int h) { + if (!(c instanceof JTextComponent)) { + // special case for non-text components (bug ID 4144840) + if (c.isEnabled()) { + drawFlush3DBorder(g, x, y, w, h); + } else { + drawDisabledBorder(g, x, y, w, h); + } + return; + } + + if (c.isEnabled() && ((JTextComponent) c).isEditable()) { + drawLineBorder(g, x, y, w, h); + /* + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawLine(1, 0, w - 2, 0); + g.drawLine(0, 1, 0, h - 2); + g.drawLine(w - 1, 1, w - 1, h - 2); + g.drawLine(1, h - 1, w - 2, h - 1); + g.translate(-x, -y); + */ + + } else { + drawDisabledBorder(g, x, y, w, h); + } + } + } + + static void drawLineBorder(Graphics g, int x, int y, int w, int h) { + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawRect(0, 0, w - 1, h - 1); + g.translate(-x, -y); + } + + static void drawFlush3DBorder(Graphics g, int x, int y, int w, int h) { + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlHighlight()); + g.drawRect(1, 1, w - 2, h - 2); + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawRect(0, 0, w - 2, h - 2); + g.translate(-x, -y); + } + + static void drawDisabledBorder(Graphics g, int x, int y, int w, int h) { + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlShadow()); + g.drawRect(0, 0, w - 1, h - 1); + g.translate(-x, -y); + } + + static void drawDefaultButtonPressedBorder(Graphics g, int x, int y, int w, int h) { + drawPressed3DBorder(g, x + 1, y + 1, w - 1, h - 1); + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawRect(0, 0, w - 3, h - 3); + g.drawLine(w - 2, 0, w - 2, 0); + g.drawLine(0, h - 2, 0, h - 2); + g.translate(-x, -y); + } + + static void drawPressed3DBorder(Graphics g, int x, int y, int w, int h) { + g.translate(x, y); + + drawFlush3DBorder(g, 0, 0, w, h); + + g.setColor(MetalLookAndFeel.getControlShadow()); + g.drawLine(1, 1, 1, h - 1); + g.drawLine(1, 1, w - 1, 1); + g.translate(-x, -y); + } + + static void drawDefaultButtonBorder(Graphics g, int x, int y, int w, int h, boolean active) { + drawButtonBorder(g, x + 1, y + 1, w - 1, h - 1, active); + g.translate(x, y); + g.setColor(MetalLookAndFeel.getControlDarkShadow()); + g.drawRect(0, 0, w - 3, h - 3); + g.drawLine(w - 2, 0, w - 2, 0); + g.drawLine(0, h - 2, 0, h - 2); + g.translate(-x, -y); + } + + static void drawButtonBorder(Graphics g, int x, int y, int w, int h, boolean active) { + if (active) { + drawActiveButtonBorder(g, x, y, w, h); + } else { + drawFlush3DBorder(g, x, y, w, h); + /* + drawLineBorder(g, x, y, w - 1, h - 1); + g.setColor(MetalLookAndFeel.getControlHighlight()); + g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1); + g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1); + */ + } + } + + static void drawActiveButtonBorder(Graphics g, int x, int y, int w, int h) { + drawFlush3DBorder(g, x, y, w, h); + g.setColor(MetalLookAndFeel.getPrimaryControl()); + g.drawLine(x + 1, y + 1, x + 1, h - 3); + g.drawLine(x + 1, y + 1, w - 3, x + 1); + g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); + g.drawLine(x + 2, h - 2, w - 2, h - 2); + g.drawLine(w - 2, y + 2, w - 2, h - 2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegButtonUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegButtonUI.java new file mode 100644 index 00000000000..6344bf3bcd2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegButtonUI.java @@ -0,0 +1,98 @@ +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalButtonUI; +import java.awt.*; + +public class BegButtonUI extends MetalButtonUI { + private final static BegButtonUI begButtonUI = new BegButtonUI(); + private Rectangle viewRect = new Rectangle(); + private Rectangle textRect = new Rectangle(); + private Rectangle iconRect = new Rectangle(); + + public static ComponentUI createUI(JComponent c) { + return begButtonUI; + } + +/* + protected BasicButtonListener createButtonListener(AbstractButton b) { + return new BasicButtonListener(b); + } +*/ + + public void paint(Graphics g, JComponent c) { + AbstractButton b = (AbstractButton)c; + ButtonModel model = b.getModel(); + + FontMetrics fm = g.getFontMetrics(); + + Insets i = c.getInsets(); + + viewRect.x = i.left; + viewRect.y = i.top; + viewRect.width = b.getWidth() - (i.right + viewRect.x); + viewRect.height = b.getHeight() - (i.bottom + viewRect.y); + + textRect.x = textRect.y = textRect.width = textRect.height = 0; + iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; + + Font f = c.getFont(); + g.setFont(f); + + // layout the text and icon + String text = SwingUtilities.layoutCompoundLabel( + c, fm, b.getText(), b.getIcon(), + b.getVerticalAlignment(), b.getHorizontalAlignment(), + b.getVerticalTextPosition(), b.getHorizontalTextPosition(), + viewRect, iconRect, textRect, + b.getText() == null ? 0 : defaultTextIconGap + ); + + clearTextShiftOffset(); + + // perform UI specific press action, e.g. Windows L&F shifts text + if (model.isArmed() && model.isPressed()){ + paintButtonPressed(g, b); + } + + // Paint the Icon + if (b.getIcon() != null){ + paintIcon(g, c, iconRect); + } + + if (text != null && !text.equals("")){ + paintText(g, c, textRect, text); + } + + if (b.isFocusPainted() && b.hasFocus()){ + // paint UI specific focus + paintFocus(g, b, viewRect, textRect, iconRect); + } + } + + protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { + Rectangle focusRect = new Rectangle(); + String text = b.getText(); + boolean isIcon = b.getIcon() != null; + + // If there is text + if (text != null && !text.equals("")){ + if (!isIcon){ + focusRect.setBounds(textRect); + } + else{ + focusRect.setBounds(iconRect.union(textRect)); + } + } + // If there is an icon and no text + else + if (isIcon){ + focusRect.setBounds(iconRect); + } + + g.setColor(getFocusColor()); +// g.drawRect(focusRect.x - 1, focusRect.y - 1, focusRect.width + 1, focusRect.height + 1); + BegTreeHandleUtil.drawDottedRectangle(g, viewRect.x, viewRect.y, viewRect.x + viewRect.width, viewRect.y + viewRect.height); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCellRenderer.java new file mode 100644 index 00000000000..9cdad49b877 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCellRenderer.java @@ -0,0 +1,247 @@ + +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.tree.TreeCellRenderer; +import java.awt.*; + +public class BegCellRenderer extends JLabel implements TreeCellRenderer, ListCellRenderer { + protected Icon myLeafIcon; + protected Color myTextBackground; + protected boolean mySelected; + protected Color mySelectionForeground; + protected Color mySelectionBorderColor; + protected Icon myOpenIcon; + protected boolean myHasFocus; + protected Color myTextForeground; + protected boolean myDrawsFocusBorderAroundIcon; + protected Color mySelectionBackground; + protected Icon myClosedIcon; + + public BegCellRenderer() { + setHorizontalAlignment(SwingConstants.LEFT); + } + + public void setSelectionBorderColor(Color color) { + mySelectionBorderColor = color; + } + + public Component getTreeCellRendererComponent(JTree tree, Object obj, boolean selected, boolean expanded, boolean leaf, int i1, boolean hasFocus) { + setFont(UIManager.getFont("Label.font")); + setLeafIcon(UIManager.getIcon("Tree.leafIcon")); + setClosedIcon(UIManager.getIcon("Tree.closedIcon")); + setOpenIcon(UIManager.getIcon("Tree.openIcon")); + setSelectionForeground(UIManager.getColor("Tree.selectionForeground")); + setTextForeground(UIManager.getColor("Tree.textForeground")); + setSelectionBackground(UIManager.getColor("Tree.selectionBackground")); + setTextBackground(UIManager.getColor("Tree.textBackground")); + setSelectionBorderColor(UIManager.getColor("Tree.selectionBorderColor")); + Object obj1 = UIManager.get("Tree.drawsFocusBorderAroundIcon"); + myDrawsFocusBorderAroundIcon = obj1 != null && ((Boolean)obj1).booleanValue(); + + myHasFocus = hasFocus; + mySelected = selected; + String text = tree.convertValueToText(obj, selected, expanded, leaf, i1, hasFocus); + setText(text); + if (selected){ + if(hasFocus){ + setForeground(getSelectionForeground()); + }else{ + setForeground(getTextForeground()); + } + } + else{ + setForeground(getTextForeground()); + } + Icon icon = getIcon(tree, obj, selected, expanded, leaf, i1, hasFocus); + setIcon(icon); + return this; + } + + public Component getListCellRendererComponent(JList list, Object obj, int index, boolean selected, boolean hasFocus) { + setFont(UIManager.getFont("Label.font")); + setSelectionForeground(UIManager.getColor("List.selectionForeground")); + setTextForeground(UIManager.getColor("List.foreground")); + setSelectionBackground(UIManager.getColor("List.selectionBackground")); + setTextBackground(UIManager.getColor("List.background")); + setSelectionBorderColor(UIManager.getColor("Tree.selectionBorderColor")); + Object obj1 = UIManager.get("Tree.drawsFocusBorderAroundIcon"); + myDrawsFocusBorderAroundIcon = obj1 != null && ((Boolean)obj1).booleanValue(); + + myHasFocus = hasFocus; + mySelected = selected; + String text = String.valueOf(obj); + setText(text); + if (hasFocus && selected){ + setForeground(getSelectionForeground()); + }else{ + setForeground(getTextForeground()); + } + return this; + } + + + public void setSelectionBackground(Color color) { + mySelectionBackground = color; + } + + public Icon getClosedIcon() { + return myClosedIcon; + } + + public Dimension getPreferredSize() { + Dimension dimension = super.getPreferredSize(); + if (dimension != null){ + dimension = new Dimension(dimension.width + 3, dimension.height); + } + return dimension; + } + + public Icon getOriginalClosedIcon() { + return UIManager.getIcon("Tree.closedIcon"); + } + + public Color getSelectionBorderColor() { + return mySelectionBorderColor; + } + + public Color getSelectionForeground() { + return mySelectionForeground; + } + + public Color getTextBackground() { + return myTextBackground; + } + + public void setClosedIcon(Icon icon) { + myClosedIcon = icon; + } + + public void setTextBackground(Color color) { + myTextBackground = color; + } + + public void setTextForeground(Color color) { + myTextForeground = color; + } + + protected Icon getIcon(JTree jtree, Object obj, boolean selected, boolean expanded, boolean leaf, int i1, boolean flag3) { + Icon icon; + if (leaf){ + icon = getLeafIcon(); + } + else + if (expanded) + icon = getOpenIcon(); + else + icon = getClosedIcon(); + return icon; + } + + public Icon getLeafIcon() { + return myLeafIcon; + } + + public void setOpenIcon(Icon icon) { + myOpenIcon = icon; + } + + protected void paintNode(Graphics g) { + Color color; + if (mySelected) { + if (myHasFocus){ + color = getSelectionBackground(); + } + else{ + color = new Color(223, 223, 223); + } + } + else{ + color = getTextBackground(); + if (color == null){ + color = getBackground(); + } + } + if (color != null){ + int i1 = getBorderLeft(); + g.setColor(color); + g.fillRect(i1 - 1, 0, getWidth() - i1, getHeight()); + } + } + + protected void paintBorder(Graphics g) { +// if (/*myHasFocus ||*/ mySelected) { + if (myHasFocus){ + int i1 = getBorderLeft(); + if (myDrawsFocusBorderAroundIcon){ + i1 = 0; + } + else + if (i1 == -1){ + i1 = getBorderLeft(); + } + Color color = getSelectionBorderColor(); + if (color != null){ + g.setColor(color); + int j1 = getWidth() - 1; + int k1 = getHeight() - 1; + BegTreeHandleUtil.drawDottedRectangle(g, i1 > 0 ? i1 - 1 : i1, 0, j1, k1); + } + } + } + + public void paint(Graphics g) { + paintNode(g); + paintBorder(g); + super.paint(g); + } + + public Icon getOpenIcon() { + return myOpenIcon; + } + + public void setSelectionForeground(Color color) { + mySelectionForeground = color; + } + + public Icon getOriginalOpenIcon() { + return UIManager.getIcon("Tree.openIcon"); + } + + public void setLeafIcon(Icon icon) { + myLeafIcon = icon; + } + + public void setBackground(Color color) { + if (color instanceof ColorUIResource){ + color = null; + } + super.setBackground(color); + } + + public Color getSelectionBackground() { + return mySelectionBackground; + } + + + public Icon getOriginalLeafIcon() { + return UIManager.getIcon("Tree.leafIcon"); + } + + protected int getBorderLeft() { + Icon icon = getIcon(); + if (icon != null && getText() != null){ + return icon.getIconWidth() + Math.max(0, getIconTextGap() - 1); + //return 0; + } + else{ + return 0; + } + } + + public Color getTextForeground() { + return myTextForeground; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCheckBoxUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCheckBoxUI.java new file mode 100644 index 00000000000..a6e475c00aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegCheckBoxUI.java @@ -0,0 +1,19 @@ +package com.intellij.ui.plaf.beg; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalCheckBoxUI; + +public class BegCheckBoxUI extends MetalCheckBoxUI { + private static final BegCheckBoxUI begCheckBoxUI = new BegCheckBoxUI(); + + public static ComponentUI createUI(JComponent c) { + return begCheckBoxUI; + } + + protected void paintFocus(Graphics g, Rectangle t, Dimension d) { + g.setColor(getFocusColor()); + BegTreeHandleUtil.drawDottedRectangle(g, t.x - 2, t.y - 1, t.x + t.width + 1, t.y + t.height); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxButton.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxButton.java new file mode 100644 index 00000000000..8f9932583f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxButton.java @@ -0,0 +1,179 @@ + +package com.intellij.ui.plaf.beg; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.metal.MetalComboBoxButton; +import javax.swing.plaf.metal.MetalLookAndFeel; + +public class BegComboBoxButton extends MetalComboBoxButton { + public BegComboBoxButton(JComboBox cb, Icon i, boolean onlyIcon, CellRendererPane pane, JList list) { + super(cb, i, onlyIcon, pane, list); + } + + public BegComboBoxButton(JComboBox cb, Icon i, CellRendererPane pane, JList list) { + super(cb, i, pane, list); + } + +/* + protected JComboBox comboBox; + protected JList listBox; + protected CellRendererPane rendererPane; + protected Icon comboIcon; + protected boolean iconOnly = false; + + public final JComboBox getComboBox() { return comboBox;} + public final void setComboBox( JComboBox cb ) { comboBox = cb;} + + public final Icon getComboIcon() { return comboIcon;} + public final void setComboIcon( Icon i ) { comboIcon = i;} + + public final boolean isIconOnly() { return iconOnly;} + public final void setIconOnly( boolean isIconOnly ) { iconOnly = isIconOnly;} + + BegComboBoxButton() { + super( "" ); + DefaultButtonModel model = new DefaultButtonModel() { + public void setArmed( boolean armed ) { + super.setArmed( isPressed() ? true : armed ); + } + }; + + setModel( model ); + } + + public BegComboBoxButton( JComboBox cb, Icon i, + CellRendererPane pane, JList list ) { + this(); + comboBox = cb; + comboIcon = i; + rendererPane = pane; + listBox = list; + setEnabled( comboBox.isEnabled() ); + setRequestFocusEnabled( comboBox.isEnabled() ); + } + + public BegComboBoxButton( JComboBox cb, Icon i, boolean onlyIcon, + CellRendererPane pane, JList list ) { + this( cb, i, pane, list ); + iconOnly = onlyIcon; + } + + public boolean isFocusTraversable() { + return (!comboBox.isEditable()) && comboBox.isEnabled(); + } +*/ + + public void paintComponent(Graphics g) { + boolean leftToRight = comboBox.getComponentOrientation().isLeftToRight(); + + // Paint the button as usual + if (comboBox.isEditable()){ + super.paintComponent(g); + } + else{ + if (getModel().isPressed()){ + Color selectColor = UIManager.getColor("Button.select"); + g.setColor(selectColor); + } + else{ + g.setColor(getBackground()); + } + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } + + Insets insets = getInsets(); + + int width = getWidth() - (insets.left + insets.right); + int height = getHeight() - (insets.top + insets.bottom); + + if (height <= 0 || width <= 0){ + return; + } + + int left = insets.left; + int top = insets.top; + int bottom = top + (height - 1); + + int iconWidth = 0; + + // Paint the icon + if (comboIcon != null){ + iconWidth = comboIcon.getIconWidth(); + int iconHeight = comboIcon.getIconHeight(); + + int iconTop; + int iconLeft; + if (iconOnly){ + iconLeft = (getWidth() / 2) - (iconWidth / 2); + iconTop = (getHeight() / 2) - (iconHeight / 2); + } + else{ + if (leftToRight){ + iconLeft = (left + (width - 1)) - iconWidth; + } + else{ + iconLeft = left; + } + iconTop = (top + ((bottom - top) / 2)) - (iconHeight / 2); + } + + comboIcon.paintIcon(this, g, iconLeft, iconTop); + + // Paint the focus + if (hasFocus()){ + g.setColor(MetalLookAndFeel.getFocusColor()); +// g.drawRect( left - 1, top - 1, width + 3, height + 1 ); + BegTreeHandleUtil.drawDottedRectangle(g, left - 1, top - 1, left + width, top + height); + } + } + + // Let the renderer paint + if (!iconOnly && comboBox != null){ + ListCellRenderer renderer = comboBox.getRenderer(); + Component c; + boolean renderPressed = getModel().isPressed(); + c = renderer.getListCellRendererComponent(listBox, + comboBox.getSelectedItem(), + -1, + renderPressed, + false); + c.setFont(rendererPane.getFont()); + + if (model.isArmed() && model.isPressed()){ + if (isOpaque()){ + c.setBackground(UIManager.getColor("Button.select")); + } + c.setForeground(comboBox.getForeground()); + } + else + if (!comboBox.isEnabled()){ + if (isOpaque()){ + c.setBackground(UIManager.getColor("ComboBox.disabledBackground")); + } + c.setForeground(UIManager.getColor("ComboBox.disabledForeground")); + } + else{ +// c.setForeground(comboBox.getForeground()); +// c.setBackground(comboBox.getBackground()); + } + + + int cWidth = width - (insets.right + iconWidth); + if (leftToRight){ + rendererPane.paintComponent(g, c, this, + left, top, cWidth, height); + } + else{ + rendererPane.paintComponent(g, c, this, + left + iconWidth, top, cWidth, height); + } + } + } + + // TODO[vova,anton] replace this code with setFocusable method + public boolean isFocusTraversable() { + return !comboBox.isEditable(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxUI.java new file mode 100644 index 00000000000..e4f7696208a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegComboBoxUI.java @@ -0,0 +1,25 @@ +package com.intellij.ui.plaf.beg; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalComboBoxIcon; +import javax.swing.plaf.metal.MetalComboBoxUI; + +public class BegComboBoxUI extends MetalComboBoxUI { + public static ComponentUI createUI(JComponent c) { + return new BegComboBoxUI(); + } + + protected JButton createArrowButton() { + JButton button = new BegComboBoxButton( + comboBox, new MetalComboBoxIcon(), comboBox.isEditable() ? true : false, + currentValuePane, listBox + ); + button.setFocusPainted(false); + button.setMargin(new Insets(0, 1, 1, 3)); +// button.setMargin(new Insets(0, 0, 0, 0)); + button.setDefaultCapable(false); + return button; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegListUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegListUI.java new file mode 100644 index 00000000000..e90815fb010 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegListUI.java @@ -0,0 +1,65 @@ + +package com.intellij.ui.plaf.beg; + +import java.awt.event.MouseEvent; +import javax.swing.*; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.basic.BasicListUI; + +public class BegListUI extends BasicListUI { + protected MouseInputListener createMouseInputListener() { + return new PatchedInputHandler(this.list); + } + + protected int convertYToRow(int y) { + return super.convertYToRow(y); + } + + public class PatchedInputHandler extends MouseInputHandler { + private JList myList; + + PatchedInputHandler(JList list) { + myList = list; + } + + public void mousePressed(MouseEvent e) { + if (!myList.isEnabled()){ + return; + } + + /* Request focus before updating the list selection. This implies + * that the current focus owner will see a focusLost() event + * before the lists selection is updated IF requestFocus() is + * synchronous (it is on Windows). See bug 4122345 + */ + if (!myList.hasFocus()){ + myList.requestFocus(); + } + + int row = BegListUI.this.convertYToRow(e.getY()); + if (row != -1){ + myList.setValueIsAdjusting(true); + int anchorIndex = myList.getAnchorSelectionIndex(); + if (e.isControlDown()){ + if (myList.isSelectedIndex(row)){ + myList.removeSelectionInterval(row, row); + } + else{ + myList.addSelectionInterval(row, row); + } + } + else + if (e.isShiftDown() && (anchorIndex != -1)){ + myList.setSelectionInterval(anchorIndex, row); + } + else{ + myList.setSelectionInterval(row, row); + } + } + } + + public void mouseReleased(MouseEvent e) { + myList.setValueIsAdjusting(false); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuBorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuBorder.java new file mode 100644 index 00000000000..75e92b92f05 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuBorder.java @@ -0,0 +1,59 @@ + +package com.intellij.ui.plaf.beg; + +import java.awt.*; +import javax.swing.*; +import javax.swing.border.AbstractBorder; +import javax.swing.plaf.UIResource; + +/** + * + */ +public class BegMenuBorder extends AbstractBorder implements UIResource { + protected static Insets borderInsets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + JMenuItem b = (JMenuItem)c; + ButtonModel model = b.getModel(); + + g.translate(x, y); + if (c.getParent() instanceof JMenuBar){ + if (model.isArmed() || model.isSelected()){ + /* + g.setColor( MetalLookAndFeel.getControlDarkShadow() ); + g.drawLine( 0, 0, w - 2, 0 ); + g.drawLine( 0, 0, 0, h - 1 ); + g.drawLine( w - 2, 2, w - 2, h - 1 ); + + g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); + g.drawLine( w - 1, 1, w - 1, h - 1 ); + + g.setColor( MetalLookAndFeel.getMenuBackground() ); + g.drawLine( w - 1, 0, w - 1, 0 ); + */ + } + } + else{ + if (model.isArmed() || (c instanceof JMenu && model.isSelected())){ + /* + g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); + g.drawLine( 0, 0, w - 1, 0 ); + + g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); + g.drawLine( 0, h - 1, w - 1, h - 1 ); + */ + } + else{ + /* + g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); + g.drawLine( 0, 0, 0, h - 1 ); + */ + } + } + g.translate(-x, -y); + } + + public Insets getBorderInsets(Component c) { + return borderInsets; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuItemUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuItemUI.java new file mode 100644 index 00000000000..f1fa30ad5ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegMenuItemUI.java @@ -0,0 +1,517 @@ + +package com.intellij.ui.plaf.beg; + +import com.intellij.openapi.actionSystem.impl.ActionMenuItem; +import com.intellij.openapi.util.SystemInfo; + +import javax.swing.*; +import javax.swing.event.MenuDragMouseEvent; +import javax.swing.event.MenuDragMouseListener; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicGraphicsUtils; +import javax.swing.plaf.basic.BasicLookAndFeel; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.lang.reflect.Method; + +/** + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public class BegMenuItemUI extends BasicMenuItemUI { + private static Rectangle b = new Rectangle(0, 0, 0, 0); + private static Rectangle j = new Rectangle(); + private static Rectangle d = new Rectangle(); + private int myMaxGutterIconWidth; + private int a; + private static Rectangle i = new Rectangle(); + private int k; + private int e; + private static Rectangle c = new Rectangle(); + private static Rectangle h = new Rectangle(); + private static Rectangle l = new Rectangle(); + private static Rectangle f = new Rectangle(32767, 32767); + + /** invoked by reflection */ + public static ComponentUI createUI(JComponent component) { + return new BegMenuItemUI(); + } + + public BegMenuItemUI() { + myMaxGutterIconWidth = 18; + } + + protected void installDefaults() { + super.installDefaults(); + Integer integer = (Integer)UIManager.get(getPropertyPrefix() + ".maxGutterIconWidth"); + if (integer != null){ + myMaxGutterIconWidth = integer.intValue(); + } + } + + public void paint(Graphics g, JComponent comp) { + JMenuItem jmenuitem = (JMenuItem)comp; + ButtonModel buttonmodel = jmenuitem.getModel(); + Icon icon1 = getIcon(); + Icon icon2 = getAllowedIcon(); + int j1 = jmenuitem.getWidth(); + int k1 = jmenuitem.getHeight(); + Insets insets = comp.getInsets(); + initBounds(); + f.setBounds(0, 0, j1, k1); + f.x += insets.left; + f.y += insets.top; + f.width -= insets.right + f.x; + f.height -= insets.bottom + f.y; + Font font = g.getFont(); + Font font1 = comp.getFont(); + g.setFont(font1); + FontMetrics fontmetrics = g.getFontMetrics(font1); + FontMetrics fontmetrics1 = g.getFontMetrics(acceleratorFont); + String keyStrokeText; + if (jmenuitem instanceof ActionMenuItem) { + keyStrokeText = ((ActionMenuItem)jmenuitem).getFirstShortcutText(); + }else{ + keyStrokeText = getKeyStrokeText(jmenuitem.getAccelerator()); + } + String s1 = layoutMenuItem(fontmetrics, jmenuitem.getText(), fontmetrics1, keyStrokeText, icon1, icon2, arrowIcon, jmenuitem.getVerticalAlignment(), jmenuitem.getHorizontalAlignment(), jmenuitem.getVerticalTextPosition(), jmenuitem.getHorizontalTextPosition(), f, l, j, c, h, d, jmenuitem.getText() != null ? defaultTextIconGap : 0, defaultTextIconGap); + Color color2 = g.getColor(); + if (comp.isOpaque()){ + g.setColor(jmenuitem.getBackground()); + g.fillRect(0, 0, j1, k1); + if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){ + g.setColor(selectionBackground); + if (icon2 != null){ + g.fillRect(k, 0, j1 - k, k1); + } + else{ + g.fillRect(0, 0, j1, k1); + //graphics.setColor(BegResources.q); + //graphics.drawLine(0, 0, 0, k1); + g.setColor(selectionBackground); + } + //graphics.setColor(BegResources.r); + //graphics.drawLine(j1 - 1, 0, j1 - 1, k1); + } + g.setColor(color2); + } + if (icon2 != null){ + if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + else{ + g.setColor(jmenuitem.getForeground()); + } + if (useCheckAndArrow()){ + icon2.paintIcon(comp, g, h.x, h.y); + } + g.setColor(color2); + if (menuItem.isArmed()){ + drawIconBorder(g); + } + } + if (icon1 != null){ + if (!buttonmodel.isEnabled()){ + icon1 = jmenuitem.getDisabledIcon(); + } + else + if (buttonmodel.isPressed() && buttonmodel.isArmed()){ + icon1 = jmenuitem.getPressedIcon(); + if (icon1 == null){ + icon1 = jmenuitem.getIcon(); + } + } + if (icon1 != null){ + icon1.paintIcon(comp, g, l.x, l.y); + } + } + if (s1 != null && s1.length() > 0){ + if (buttonmodel.isEnabled()){ + if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + else{ + g.setColor(jmenuitem.getForeground()); + } + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), j.x, j.y + fontmetrics.getAscent()); + } + else + if (UIManager.get("MenuItem.disabledForeground") instanceof Color){ + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), j.x, j.y + fontmetrics.getAscent()); + } + else{ + g.setColor(jmenuitem.getBackground().brighter()); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), j.x, j.y + fontmetrics.getAscent()); + g.setColor(jmenuitem.getBackground().darker()); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), j.x - 1, (j.y + fontmetrics.getAscent()) - 1); + } + } + if (keyStrokeText != null && !keyStrokeText.equals("")){ + g.setFont(acceleratorFont); + if (buttonmodel.isEnabled()){ + if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){ + g.setColor(acceleratorSelectionForeground); + } + else{ + g.setColor(acceleratorForeground); + } + BasicGraphicsUtils.drawString(g, keyStrokeText, 0, c.x, c.y + fontmetrics.getAscent()); + } + else + if (disabledForeground != null){ + g.setColor(disabledForeground); + BasicGraphicsUtils.drawString(g, keyStrokeText, 0, c.x, c.y + fontmetrics.getAscent()); + } + else{ + g.setColor(jmenuitem.getBackground().brighter()); + BasicGraphicsUtils.drawString(g, keyStrokeText, 0, c.x, c.y + fontmetrics.getAscent()); + g.setColor(jmenuitem.getBackground().darker()); + BasicGraphicsUtils.drawString(g, keyStrokeText, 0, c.x - 1, (c.y + fontmetrics.getAscent()) - 1); + } + } + if (arrowIcon != null){ + if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + if (useCheckAndArrow()){ + arrowIcon.paintIcon(comp, g, d.x, d.y); + } + } + g.setColor(color2); + g.setFont(font); + } + + private String getKeyStrokeText(KeyStroke keystroke) { + String s1 = ""; + if (keystroke != null){ + int j1 = keystroke.getModifiers(); + if (j1 > 0){ + if (SystemInfo.isMac) { + try { + Class appleLaf = Class.forName("apple.laf.AquaLookAndFeel"); + Method getModifiers = appleLaf.getMethod("getKeyModifiersText", new Class[] {int.class, boolean.class}); + s1 = (String)getModifiers.invoke(appleLaf, new Object[] {new Integer(j1), Boolean.FALSE}); + } + catch (Exception e) { + s1 = KeyEvent.getKeyModifiersText(j1) + '+'; + } + } + else { + s1 = KeyEvent.getKeyModifiersText(j1) + '+'; + } + + } + s1 = s1 + KeyEvent.getKeyText(keystroke.getKeyCode()); + } + return s1; + } + + private boolean useCheckAndArrow() { + if ((menuItem instanceof JMenu) && ((JMenu)menuItem).isTopLevelMenu()){ + return false; + } + return true; + } + + public MenuElement[] getPath() { + MenuSelectionManager menuselectionmanager = MenuSelectionManager.defaultManager(); + MenuElement amenuelement[] = menuselectionmanager.getSelectedPath(); + int i1 = amenuelement.length; + if (i1 == 0){ + return new MenuElement[0]; + } + java.awt.Container container = menuItem.getParent(); + MenuElement amenuelement1[]; + if (amenuelement[i1 - 1].getComponent() == container){ + amenuelement1 = new MenuElement[i1 + 1]; + System.arraycopy(amenuelement, 0, amenuelement1, 0, i1); + amenuelement1[i1] = menuItem; + } + else{ + int j1; + for(j1 = amenuelement.length - 1; j1 >= 0; j1--){ + if (amenuelement[j1].getComponent() == container){ + break; + } + } + amenuelement1 = new MenuElement[j1 + 2]; + System.arraycopy(amenuelement, 0, amenuelement1, 0, j1 + 1); + amenuelement1[j1 + 1] = menuItem; + } + return amenuelement1; + } + + public Dimension getMinimumSize(JComponent jcomponent) { + return null; + } + + private String layoutMenuItem( + FontMetrics fontmetrics, + String text, + FontMetrics fontmetrics1, + String keyStrokeText, + Icon icon, + Icon checkIcon, + Icon arrowIcon, + int verticalAlignment, + int horizontalAlignment, + int verticalTextPosition, + int horizontalTextPosition, + Rectangle viewRect, + Rectangle iconRect, + Rectangle textRect, + Rectangle acceleratorRect, + Rectangle checkIconRect, + Rectangle arrowIconRect, + int textIconGap, + int menuItemGap + ) { + SwingUtilities.layoutCompoundLabel(menuItem, fontmetrics, text, icon, verticalAlignment, horizontalAlignment, verticalTextPosition, horizontalTextPosition, viewRect, iconRect, textRect, textIconGap); + if (keyStrokeText == null || "".equals(keyStrokeText)){ + acceleratorRect.width = acceleratorRect.height = 0; + } + else{ + acceleratorRect.width = SwingUtilities.computeStringWidth(fontmetrics1, keyStrokeText); + acceleratorRect.height = fontmetrics1.getHeight(); + } + + /* Initialize the checkIcon bounds rectangle's width & height. + */ + if (useCheckAndArrow()){ + if (checkIcon != null){ + checkIconRect.width = checkIcon.getIconWidth(); + checkIconRect.height = checkIcon.getIconHeight(); + }else{ + checkIconRect.width = checkIconRect.height = 0; + } + + /* Initialize the arrowIcon bounds rectangle width & height. + */ + if (arrowIcon != null){ + arrowIconRect.width = arrowIcon.getIconWidth(); + arrowIconRect.height = arrowIcon.getIconHeight(); + }else{ + arrowIconRect.width = arrowIconRect.height = 0; + } + textRect.x += myMaxGutterIconWidth; + iconRect.x += myMaxGutterIconWidth; + } + textRect.x += menuItemGap; + iconRect.x += menuItemGap; + Rectangle labelRect = iconRect.union(textRect); + + // Position the Accelerator text rect + + acceleratorRect.x += viewRect.width - arrowIconRect.width - menuItemGap - acceleratorRect.width; + acceleratorRect.y = (viewRect.y + viewRect.height / 2) - acceleratorRect.height / 2; + + // Position the Check and Arrow Icons + + if (useCheckAndArrow()){ + arrowIconRect.x += viewRect.width - arrowIconRect.width; + arrowIconRect.y = (viewRect.y + labelRect.height / 2) - arrowIconRect.height / 2; + if (checkIcon != null){ + checkIconRect.y = (viewRect.y + labelRect.height / 2) - checkIconRect.height / 2; + checkIconRect.x += (viewRect.x + myMaxGutterIconWidth / 2) - checkIcon.getIconWidth() / 2; + a = viewRect.x; + e = (viewRect.y + labelRect.height / 2) - myMaxGutterIconWidth / 2; + k = viewRect.x + myMaxGutterIconWidth + 2; + } + else{ + checkIconRect.x = checkIconRect.y = 0; + } + } + return text; + } + + private Icon getIcon() { + Icon icon = menuItem.getIcon(); + if (icon != null && getAllowedIcon() != null){ + icon = null; + } + return icon; + } + + public Dimension getPreferredSize(JComponent comp) { + JMenuItem jmenuitem = (JMenuItem)comp; + Icon icon1 = getIcon(); + Icon icon2 = getAllowedIcon(); + String text = jmenuitem.getText(); + String keyStrokeText; + if (jmenuitem instanceof ActionMenuItem) { + keyStrokeText = ((ActionMenuItem)jmenuitem).getFirstShortcutText(); + }else{ + keyStrokeText = getKeyStrokeText(jmenuitem.getAccelerator()); + } + Font font = jmenuitem.getFont(); + FontMetrics fontmetrics = comp.getFontMetrics(font); + FontMetrics fontmetrics1 = comp.getFontMetrics(acceleratorFont); + initBounds(); + layoutMenuItem(fontmetrics, text, fontmetrics1, keyStrokeText, icon1, icon2, arrowIcon, jmenuitem.getVerticalAlignment(), jmenuitem.getHorizontalAlignment(), jmenuitem.getVerticalTextPosition(), jmenuitem.getHorizontalTextPosition(), f, l, j, c, h, d, text != null ? defaultTextIconGap : 0, defaultTextIconGap); + i.setBounds(j); + i = SwingUtilities.computeUnion(l.x, l.y, l.width, l.height, i); + if (!(keyStrokeText == null || "".equals(keyStrokeText))){ + i.width += c.width; + i.width += 7 * defaultTextIconGap; + } + if (useCheckAndArrow()){ + i.width += myMaxGutterIconWidth; + i.width += defaultTextIconGap; + i.width += defaultTextIconGap; + i.width += d.width; + } + i.width += 2 * defaultTextIconGap; + Insets insets = jmenuitem.getInsets(); + if (insets != null){ + i.width += insets.left + insets.right; + i.height += insets.top + insets.bottom; + } + if (i.width % 2 == 0){ + i.width++; + } + if (i.height % 2 == 0){ + i.height++; + } + return i.getSize(); + } + + private void drawIconBorder(Graphics g) { +/* + int i1 = a - 1; + int j1 = e - 2; + int k1 = i1 + myMaxGutterIconWidth + 1; + int l1 = j1 + myMaxGutterIconWidth + 4; + g.setColor(BegResources.m); + g.drawLine(i1, j1, i1, l1); + g.drawLine(i1, j1, k1, j1); + g.setColor(BegResources.j); + g.drawLine(k1, j1, k1, l1); + g.drawLine(i1, l1, k1, l1); +*/ + } + + private void initBounds() { + l.setBounds(b); + j.setBounds(b); + c.setBounds(b); + h.setBounds(b); + d.setBounds(b); + f.setBounds(0, 0, 32767, 32767); + i.setBounds(b); + } + + private Icon getAllowedIcon() { + Icon icon = menuItem.isEnabled() ? menuItem.getIcon() : menuItem.getDisabledIcon(); + if (icon != null && icon.getIconWidth() > myMaxGutterIconWidth){ + icon = null; + } + return icon; + } + + public Dimension getMaximumSize(JComponent comp) { + return null; + } + + public void update(Graphics g, JComponent comp) { + paint(g, comp); + } + + /** Copied from BasicMenuItemUI */ + private boolean isInternalFrameSystemMenu(){ + String actionCommand=menuItem.getActionCommand(); + if( + ("Close".equals(actionCommand))|| + ("Minimize".equals(actionCommand))|| + ("Restore".equals(actionCommand))|| + ("Maximize".equals(actionCommand)) + ){ + return true; + } else{ + return false; + } + } + + /** Copied from BasicMenuItemUI */ + private void doClick(MenuSelectionManager msm,MouseEvent e) { + // Auditory cue + if(!isInternalFrameSystemMenu()){ + ActionMap map=menuItem.getActionMap(); + if(map!=null){ + Action audioAction=map.get(getPropertyPrefix()+".commandSound"); + if(audioAction!=null){ + // pass off firing the Action to a utility method + BasicLookAndFeel lf=(BasicLookAndFeel)UIManager.getLookAndFeel(); + // It's a hack. The method BasicLookAndFeel.playSound has protected access, so + // it's imposible to mormally invoke it. + try { + Method playSoundMethod=BasicLookAndFeel.class.getDeclaredMethod("playSound",new Class[]{Action.class}); + playSoundMethod.setAccessible(true); + playSoundMethod.invoke(lf,new Object[]{audioAction}); + } catch(Exception ignored) {} + } + } + } + // Visual feedback + if(msm==null){ + msm=MenuSelectionManager.defaultManager(); + } + msm.clearSelectedPath(); + ((ActionMenuItem)menuItem).fireActionPerformed( + new ActionEvent( + menuItem, + ActionEvent.ACTION_PERFORMED, + null, + e.getWhen(), + e.getModifiers() + ) + ); + } + + protected MouseInputListener createMouseInputListener(JComponent c){ + return new MyMouseInputHandler(); + } + + private class MyMouseInputHandler extends MouseInputHandler{ + public void mouseReleased(MouseEvent e){ + MenuSelectionManager manager=MenuSelectionManager.defaultManager(); + Point p=e.getPoint(); + if(p.x>=0&&p.x=0&&p.y=0&&p.x=0&&p.yMetalBorders.ScrollPaneBorder
    , the client property + * FREE_STANDING_PROP of the scrollbars + * is set to false, otherwise it is set to true. + */ + private void updateScrollbarsFreeStanding() { + if (scrollpane == null) { + return; + } + Object value = Boolean.FALSE; + scrollpane.getHorizontalScrollBar().putClientProperty + (MetalScrollBarUI.FREE_STANDING_PROP, value); + scrollpane.getVerticalScrollBar().putClientProperty + (MetalScrollBarUI.FREE_STANDING_PROP, value); + } + + protected PropertyChangeListener createScrollBarSwapListener() { + return new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + String propertyName = e.getPropertyName(); + if (propertyName.equals("verticalScrollBar") || + propertyName.equals("horizontalScrollBar")) { + ((JScrollBar) e.getOldValue()).putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, + null); + ((JScrollBar) e.getNewValue()).putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, + Boolean.FALSE); + } + else if ("border".equals(propertyName)) { + updateScrollbarsFreeStanding(); + } + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTabbedPaneUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTabbedPaneUI.java new file mode 100644 index 00000000000..58b003316c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTabbedPaneUI.java @@ -0,0 +1,372 @@ +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalTabbedPaneUI; +import java.awt.*; + +public class BegTabbedPaneUI extends MetalTabbedPaneUI { + private static Color LIGHT = new Color(247, 243, 239); + private static Color DARK = new Color(189, 187, 182); + + private boolean myNoIconSpace = false; + private boolean myPaintContentBorder = true; + + public void installUI(JComponent c) { + super.installUI(c); + Object clientProperty = c.getClientProperty("TabbedPane.paintContentBorder"); + if (clientProperty instanceof Boolean) { + Boolean aBoolean = (Boolean)clientProperty; + myPaintContentBorder = aBoolean.booleanValue(); + } + } + + protected Insets getContentBorderInsets(int tabPlacement) { + if (tabPlacement == TOP && !myPaintContentBorder) { + return new Insets(1, 0, 0, 0); + } + if (tabPlacement == BOTTOM && !myPaintContentBorder) { + return new Insets(0, 0, 1, 0); + } + if (tabPlacement == LEFT && !myPaintContentBorder) { + return new Insets(0, 1, 0, 0); + } + if (tabPlacement == RIGHT && !myPaintContentBorder) { + return new Insets(0, 0, 0, 1); + } + return new Insets(1, 1, 1, 1); + } + + protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { + g.setColor(darkShadow); + switch (tabPlacement) { + case TOP: + { + if (isSelected) { + // left + g.drawLine(x, y + 1, x, y + h - 1); + // top + g.drawLine(x + 1, y, x + w - 3, y); + // right + g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 1); + } + else { + // left + g.drawLine(x, y + 1, x, y + h - 1); + // top + g.drawLine(x + 1, y, x + w - 3, y); + // right + g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 1); + } + break; + } + case LEFT: + { + // top + g.drawLine(x + 1, y + 1, x + w - 1, y + 1); + // left + g.drawLine(x, y + 2, x, y + h - 2); + //bottom + g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1); + break; + } + case BOTTOM: + { + if (isSelected) { + // left + g.drawLine(x, y, x, y + h - 2); + // bottom + g.drawLine(x + 1, y + h - 1, x + w - 2, y + h - 1); + // right + g.drawLine(x + w - 1, y, x + w - 1, y + h - 2); + } + else { + // left + g.drawLine(x, y, x, y + h - 1); + // bottom + g.drawLine(x + 1, y + h - 1, x + w - 3, y + h - 1); + // right + g.drawLine(x + w - 2, y, x + w - 2, y + h - 1); + } + break; + } + case RIGHT: + { + // top + g.drawLine(x, y + 1, x + w - 2, y + 1); + // right + g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 2); + //bottom + g.drawLine(x, y + h - 1, x + w - 2, y + h - 1); + break; + } + default: + { + throw new IllegalArgumentException("unknown tabPlacement: " + tabPlacement); + } + } + } + + protected void paintText(Graphics g, int tabPlacement, + Font font, FontMetrics metrics, int tabIndex, + String title, Rectangle textRect, + boolean isSelected) { + if (isSelected) { + font = font.isBold()? font : font.deriveFont(Font.BOLD); + metrics = metrics.getFont().isBold()? metrics : g.getFontMetrics(font); + } + else { + font = font.isPlain()? font : font.deriveFont(Font.PLAIN); + metrics = metrics.getFont().isPlain()? metrics : g.getFontMetrics(font); + } + g.setFont(font); + if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) { + g.setColor(tabPane.getForegroundAt(tabIndex)); + g.drawString(title, textRect.x - (myNoIconSpace ? 5 : 0), textRect.y + metrics.getAscent()); + } + else { + // tab disabled + g.setColor(tabPane.getBackgroundAt(tabIndex).brighter()); + g.drawString(title, textRect.x, textRect.y + metrics.getAscent()); + g.setColor(tabPane.getBackgroundAt(tabIndex).darker()); + g.drawString(title, textRect.x - (myNoIconSpace ? 6 : 1), textRect.y + metrics.getAscent() - 1); + } + } + + protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { + if (isSelected) { + g.setColor(LIGHT); + } + else { + g.setColor(DARK); + } + switch (tabPlacement) { + case LEFT: + g.fillRect(x + 1, y + 2, w - 2, h - 3); + break; + case RIGHT: + g.fillRect(x, y + 2, w - 1, h - 3); + break; + case BOTTOM: + g.fillRect(x + 1, y, w - 3, h - 1); + break; + case TOP: + default: + g.fillRect(x + 1, y + 1, w - 2, h); + } + } + + protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + if (tabPlacement == TOP || myPaintContentBorder) { + boolean leftToRight = isLeftToRight(tabPane); + int right = x + w - 1; + Rectangle selRect = selectedIndex < 0 ? null : + getTabBounds(selectedIndex, calcRect); + g.setColor(darkShadow); + + // Draw unbroken line if tabs are not on TOP, OR + // selected tab is not in run adjacent to content, OR + // selected tab is not visible (SCROLL_TAB_LAYOUT) + // + if (tabPlacement != TOP || selectedIndex < 0 || + (selRect.y + selRect.height + 1 < y) || + (selRect.x < x || selRect.x > x + w)) { + g.drawLine(x, y, x + w - 1, y); + } + else { + // Break line to show visual connection to selected tab + boolean lastInRun = isLastInRun(selectedIndex); + + g.drawLine(x, y, selRect.x, y); + + if (selRect.x + selRect.width < right - 1) { + if (leftToRight && !lastInRun) { + g.drawLine(selRect.x + selRect.width - 2, y, right, y); + } + else { + g.drawLine(selRect.x + selRect.width - 2, y, right, y); + } + } + else { + g.drawLine(x + w - 2, y, x + w - 2, y); + } + } + } + } + + protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + if (tabPlacement == BOTTOM || myPaintContentBorder) { + boolean leftToRight = isLeftToRight(tabPane); + int bottom = y + h - 1; + int right = x + w - 1; + Rectangle selRect = selectedIndex < 0 ? null : + getTabBounds(selectedIndex, calcRect); + g.setColor(darkShadow); + + // Draw unbroken line if tabs are not on BOTTOM, OR + // selected tab is not in run adjacent to content, OR + // selected tab is not visible (SCROLL_TAB_LAYOUT) + // + if (tabPlacement != BOTTOM || selectedIndex < 0 || + (selRect.y - 1 > h) || + (selRect.x < x || selRect.x > x + w)) { + g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); + } + else { + // Break line to show visual connection to selected tab + boolean lastInRun = isLastInRun(selectedIndex); + + if (leftToRight || lastInRun) { + g.drawLine(x, bottom, selRect.x, bottom); + } + else { + g.drawLine(x, bottom, selRect.x - 1, bottom); + } + + if (selRect.x + selRect.width < x + w - 2) { + if (leftToRight && !lastInRun) { + g.drawLine(selRect.x + selRect.width, bottom, + right, bottom); + } + else { + g.drawLine(selRect.x + selRect.width - 1, bottom, + right, bottom); + } + } + } + } + } + + protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + if (tabPlacement == LEFT || myPaintContentBorder) { + Rectangle selRect = selectedIndex < 0 ? null : + getTabBounds(selectedIndex, calcRect); + g.setColor(darkShadow); + + // Draw unbroken line if tabs are not on LEFT, OR + // selected tab is not in run adjacent to content, OR + // selected tab is not visible (SCROLL_TAB_LAYOUT) + // + if (tabPlacement != LEFT || selectedIndex < 0 || + (selRect.x + selRect.width + 1 < x) || + (selRect.y < y || selRect.y > y + h)) { + g.drawLine(x, y, x, y + h - 2); + } + else { + // Break line to show visual connection to selected tab + g.drawLine(x, y, x, selRect.y + 1); + if (selRect.y + selRect.height < y + h - 2) { + g.drawLine(x, selRect.y + selRect.height + 1, + x, y + h + 2); + } + } + } + } + + protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + if (tabPlacement == RIGHT || myPaintContentBorder) { + Rectangle selRect = selectedIndex < 0 ? null : + getTabBounds(selectedIndex, calcRect); + g.setColor(darkShadow); + + // Draw unbroken line if tabs are not on RIGHT, OR + // selected tab is not in run adjacent to content, OR + // selected tab is not visible (SCROLL_TAB_LAYOUT) + // + if (tabPlacement != RIGHT || selectedIndex < 0 || + (selRect.x - 1 > w) || + (selRect.y < y || selRect.y > y + h)) { + g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); + } + else { + // Break line to show visual connection to selected tab + g.drawLine(x + w - 1, y, x + w - 1, selRect.y); + + if (selRect.y + selRect.height < y + h - 2) { + g.drawLine(x + w - 1, selRect.y + selRect.height, + x + w - 1, y + h - 2); + } + } + } + } + + private boolean isLastInRun(int tabIndex) { + int run = getRunForTab(tabPane.getTabCount(), tabIndex); + int lastIndex = lastTabInRun(tabPane.getTabCount(), run); + return tabIndex == lastIndex; + } + + static boolean isLeftToRight(Component c) { + return c.getComponentOrientation().isLeftToRight(); + } + + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + return (int)(super.calculateTabHeight(tabPlacement, tabIndex, fontHeight) * 1.0); + } + + protected int calculateMaxTabHeight(int tabPlacement) { + FontMetrics metrics = getFontMetrics(); + int tabCount = tabPane.getTabCount(); + int result = 0; + int fontHeight = metrics.getHeight(); + for (int i = 0; i < tabCount; i++) { + result = Math.max(calculateTabHeight(tabPlacement, i, fontHeight), result); + } + return result; + } + + /** + * invoked by reflection + */ + public static ComponentUI createUI(JComponent c) { + return new BegTabbedPaneUI(); + } + + /** + * IdeaTabbedPaneUI uses bold font for selected tab. Bold width of some fonts is + * less then width of plain font. To handle correctly this "anomaly" we have to + * determine maximum of these two widths. + */ + protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { + final Font font = metrics.getFont(); + final FontMetrics plainMetrics = font.isPlain()? metrics : tabPane.getFontMetrics(font.deriveFont(Font.PLAIN)); + final int widthPlain = super.calculateTabWidth(tabPlacement, tabIndex, plainMetrics); + + final FontMetrics boldMetrics = font.isBold()? metrics : tabPane.getFontMetrics(font.deriveFont(Font.BOLD)); + final int widthBold = super.calculateTabWidth(tabPlacement, tabIndex, boldMetrics); + + final int width = Math.max(widthPlain, widthBold); + + myLayoutMetrics = (width == widthPlain)? plainMetrics : boldMetrics; + + return width; + } + + private FontMetrics myLayoutMetrics = null; + + protected void layoutLabel(int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, Rectangle tabRect, + Rectangle iconRect, Rectangle textRect, boolean isSelected) { + + final FontMetrics _metrics = (myLayoutMetrics != null)? myLayoutMetrics : metrics; + super.layoutLabel(tabPlacement, _metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected); + } + + public void setNoIconSpace(boolean noIconSpace) { + myNoIconSpace = noIconSpace; + } + + public void setPaintContentBorder(boolean paintContentBorder) { + myPaintContentBorder = paintContentBorder; + } + + protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight) { + for (int i = 0; i < tabPane.getTabCount(); i++) { + Component component = tabPane.getComponentAt(i); + if (component != null) { + return super.calculateTabAreaHeight(tabPlacement, horizRunCount, maxTabHeight); + } + } + return maxTabHeight + tabRunOverlay; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTableUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTableUI.java new file mode 100644 index 00000000000..011d289cae5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTableUI.java @@ -0,0 +1,68 @@ +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicTableUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * @author mike + */ +public class BegTableUI extends BasicTableUI { + private KeyAdapter myAdapter= new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + if (table.isEditing()) { + e.consume(); + table.removeEditor(); + + if (e.getSource() != table) { + ((JComponent)e.getSource()).removeKeyListener(this); + } + } + } + } + }; + + public static ComponentUI createUI(JComponent c) { + return new BegTableUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + c.getActionMap().put("startEditing", new StartEditingAction()); + } + + protected KeyListener createKeyListener() { + return myAdapter; + } + + private class StartEditingAction extends AbstractAction { + public void actionPerformed(ActionEvent e) { + JTable table = (JTable)e.getSource(); + if (!table.hasFocus()) { + CellEditor cellEditor = table.getCellEditor(); + if (cellEditor != null && !cellEditor.stopCellEditing()) { + return; + } + table.requestFocus(); + return; + } + ListSelectionModel rsm = table.getSelectionModel(); + int anchorRow = rsm.getAnchorSelectionIndex(); + ListSelectionModel csm = table.getColumnModel().getSelectionModel(); + int anchorColumn = csm.getAnchorSelectionIndex(); + table.editCellAt(anchorRow, anchorColumn); + Component editorComp = table.getEditorComponent(); + if (editorComp != null) { + editorComp.addKeyListener(myAdapter); + editorComp.requestFocus(); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeHandleUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeHandleUtil.java new file mode 100644 index 00000000000..44f8776def4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeHandleUtil.java @@ -0,0 +1,45 @@ + +package com.intellij.ui.plaf.beg; + +import java.awt.*; + +public class BegTreeHandleUtil { + public static void a(Graphics g, int i, int j, int k, int l) { + g.translate(i, j); + boolean flag = false; + for(int i1 = 0; i1 < k; i1++){ + // beg: unknown start value for j1 + for(int j1 = 0; j1 < l; j1 += 2){ + g.drawLine(i1, j1, i1, j1); + } + flag = !flag; + } + g.translate(-i, -j); + } + + /** + * @param g + * @param x top left X coordinate. + * @param y top left Y coordinate. + * @param x1 right bottom X coordinate. + * @param y1 right bottom Y coordinate. + */ + public static void drawDottedRectangle(Graphics g, int x, int y, int x1, int y1) { + int i1; + for(i1 = x; i1 <= x1; i1 += 2){ + g.drawLine(i1, y, i1, y); + } + + for(i1 = i1 != x1 + 1 ? y + 2 : y + 1; i1 <= y1; i1 += 2){ + g.drawLine(x1, i1, x1, i1); + } + + for(i1 = i1 != y1 + 1 ? x1 - 2 : x1 - 1; i1 >= x; i1 -= 2){ + g.drawLine(i1, y1, i1, y1); + } + + for(i1 = i1 != x - 1 ? y1 - 2 : y1 - 1; i1 >= y; i1 -= 2){ + g.drawLine(x, i1, x, i1); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeUI.java new file mode 100644 index 00000000000..afea9c42b00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/BegTreeUI.java @@ -0,0 +1,25 @@ +package com.intellij.ui.plaf.beg; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalTreeUI; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeListener; + +public class BegTreeUI extends MetalTreeUI { + protected static final String PROP_LINE_STYLE = "JTree.lineStyle"; + protected static final int DASHED = 0; + protected static final int SOLID = 1; + protected static final int NONE = 2; + protected int myLineStyle; + protected PropertyChangeListener myPropertyChangeListener; + + /* Invoked by reflection */ + public static ComponentUI createUI(JComponent c) { + return new BegTreeUI(); + } + + protected boolean isToggleSelectionEvent(MouseEvent e) { + return SwingUtilities.isLeftMouseButton(e) && e.isControlDown() && !e.isPopupTrigger(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/IdeaMenuUI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/IdeaMenuUI.java new file mode 100644 index 00000000000..c2b6093c47a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/ui/plaf/beg/IdeaMenuUI.java @@ -0,0 +1,468 @@ +package com.intellij.ui.plaf.beg; + +import com.intellij.Patches; + +import javax.swing.*; +import javax.swing.event.MenuKeyEvent; +import javax.swing.event.MenuKeyListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicGraphicsUtils; +import javax.swing.plaf.basic.BasicMenuUI; +import java.awt.*; + +/** + * @author Vladimir Kondratyev + */ +public class IdeaMenuUI extends BasicMenuUI{ + private static Rectangle ourZeroRect = new Rectangle(0, 0, 0, 0); + private static Rectangle ourTextRect = new Rectangle(); + private static Rectangle ourArrowIconRect = new Rectangle(); + private int myMaxGutterIconWidth; + private int a; + private static Rectangle ourPreferredSizeRect = new Rectangle(); + private int k; + private int e; + private static Rectangle ourAcceleratorRect = new Rectangle(); + private static Rectangle ourCheckIconRect = new Rectangle(); + private static Rectangle ourIconRect = new Rectangle(); + private static Rectangle ourViewRect = new Rectangle(32767, 32767); + + /** invoked by reflection */ + public static ComponentUI createUI(JComponent component) { + return new IdeaMenuUI(); + } + + public IdeaMenuUI() { + myMaxGutterIconWidth = 18; + } + + protected MenuKeyListener createMenuKeyListener(JComponent c){ + if (Patches.SUN_BUG_ID_4738042) { + return new SUN_BUG_ID_4738042_Patch(); + } + return super.createMenuKeyListener(c); + } + + protected void installDefaults() { + super.installDefaults(); + Integer integer = (Integer)UIManager.get(getPropertyPrefix() + ".maxGutterIconWidth"); + if (integer != null){ + myMaxGutterIconWidth = integer.intValue(); + } + } + + public void paint(Graphics g, JComponent comp) { + JMenu jMenu = (JMenu)comp; + ButtonModel buttonmodel = jMenu.getModel(); + Icon icon = getIcon(); + Icon allowedIcon = getAllowedIcon(); + Insets insets = comp.getInsets(); + resetRects(); + ourViewRect.setBounds(0, 0, jMenu.getWidth(), jMenu.getHeight()); + ourViewRect.x += insets.left; + ourViewRect.y += insets.top; + ourViewRect.width -= insets.right + ourViewRect.x; + ourViewRect.height -= insets.bottom + ourViewRect.y; + Font font = g.getFont(); + Font font1 = comp.getFont(); + g.setFont(font1); + FontMetrics fontmetrics = g.getFontMetrics(font1); + String s1 = layoutMenuItem( + fontmetrics, + jMenu.getText(), + icon, + allowedIcon, + arrowIcon, + jMenu.getVerticalAlignment(), + jMenu.getHorizontalAlignment(), + jMenu.getVerticalTextPosition(), + jMenu.getHorizontalTextPosition(), + ourViewRect, + ourIconRect, + ourTextRect, + ourAcceleratorRect, + ourCheckIconRect, + ourArrowIconRect, + jMenu.getText() != null ? defaultTextIconGap : 0, + defaultTextIconGap + ); + Color color2 = g.getColor(); + if (comp.isOpaque()){ + g.setColor(jMenu.getBackground()); + g.fillRect(0, 0, jMenu.getWidth(), jMenu.getHeight()); + if (buttonmodel.isArmed() || buttonmodel.isSelected()){ + g.setColor(selectionBackground); + if (allowedIcon != null){ + g.fillRect(k, 0, jMenu.getWidth() - k, jMenu.getHeight()); + }else{ + g.fillRect(0, 0, jMenu.getWidth(), jMenu.getHeight()); + g.setColor(selectionBackground); + } + } + g.setColor(color2); + } + if (allowedIcon != null){ + if (buttonmodel.isArmed() || buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + else{ + g.setColor(jMenu.getForeground()); + } + if (useCheckAndArrow()){ + allowedIcon.paintIcon(comp, g, ourCheckIconRect.x, ourCheckIconRect.y); + } + g.setColor(color2); + if (menuItem.isArmed()){ + drawIconBorder(g); + } + } + if (icon != null){ + if (!buttonmodel.isEnabled()){ + icon = jMenu.getDisabledIcon(); + } + else + if (buttonmodel.isPressed() && buttonmodel.isArmed()){ + icon = jMenu.getPressedIcon(); + if (icon == null){ + icon = jMenu.getIcon(); + } + } + if (icon != null){ + icon.paintIcon(comp, g, ourIconRect.x, ourIconRect.y); + } + } + if (s1 != null && s1.length() > 0){ + if (buttonmodel.isEnabled()){ + if (buttonmodel.isArmed() || buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + else{ + g.setColor(jMenu.getForeground()); + } + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), ourTextRect.x, ourTextRect.y + fontmetrics.getAscent()); + } + else + if (UIManager.get("MenuItem.disabledForeground") instanceof Color){ + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), ourTextRect.x, ourTextRect.y + fontmetrics.getAscent()); + } + else{ + g.setColor(jMenu.getBackground().brighter()); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), ourTextRect.x, ourTextRect.y + fontmetrics.getAscent()); + g.setColor(jMenu.getBackground().darker()); + BasicGraphicsUtils.drawString(g, s1, buttonmodel.getMnemonic(), ourTextRect.x - 1, (ourTextRect.y + fontmetrics.getAscent()) - 1); + } + } + if (arrowIcon != null){ + if (buttonmodel.isArmed() || buttonmodel.isSelected()){ + g.setColor(selectionForeground); + } + if (useCheckAndArrow()){ + arrowIcon.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y); + } + } + g.setColor(color2); + g.setFont(font); + } + + private boolean useCheckAndArrow() { + return !((JMenu)menuItem).isTopLevelMenu(); + } + + public MenuElement[] getPath() { + MenuSelectionManager menuselectionmanager = MenuSelectionManager.defaultManager(); + MenuElement amenuelement[] = menuselectionmanager.getSelectedPath(); + int i1 = amenuelement.length; + if (i1 == 0){ + return new MenuElement[0]; + } + java.awt.Container container = menuItem.getParent(); + MenuElement amenuelement1[]; + if (amenuelement[i1 - 1].getComponent() == container){ + amenuelement1 = new MenuElement[i1 + 1]; + System.arraycopy(amenuelement, 0, amenuelement1, 0, i1); + amenuelement1[i1] = menuItem; + } + else{ + int j1; + for(j1 = amenuelement.length - 1; j1 >= 0; j1--){ + if (amenuelement[j1].getComponent() == container){ + break; + } + } + amenuelement1 = new MenuElement[j1 + 2]; + System.arraycopy(amenuelement, 0, amenuelement1, 0, j1 + 1); + amenuelement1[j1 + 1] = menuItem; + } + return amenuelement1; + } + + private String layoutMenuItem( + FontMetrics fontmetrics, + String text, + Icon icon, + Icon checkIcon, + Icon arrowIcon, + int verticalAlignment, + int horizontalAlignment, + int verticalTextPosition, + int horizontalTextPosition, + Rectangle viewRect, + Rectangle iconRect, + Rectangle textRect, + Rectangle acceleratorRect, + Rectangle checkIconRect, + Rectangle arrowIconRect, + int textIconGap, + int menuItemGap + ) { + SwingUtilities.layoutCompoundLabel(menuItem, fontmetrics, text, icon, verticalAlignment, horizontalAlignment, verticalTextPosition, horizontalTextPosition, viewRect, iconRect, textRect, textIconGap); + acceleratorRect.width = acceleratorRect.height = 0; + + /* Initialize the checkIcon bounds rectangle's width & height. + */ + if (useCheckAndArrow()){ + if (checkIcon != null){ + checkIconRect.width = checkIcon.getIconWidth(); + checkIconRect.height = checkIcon.getIconHeight(); + }else{ + checkIconRect.width = checkIconRect.height = 0; + } + + /* Initialize the arrowIcon bounds rectangle width & height. + */ + if (arrowIcon != null){ + arrowIconRect.width = arrowIcon.getIconWidth(); + arrowIconRect.height = arrowIcon.getIconHeight(); + }else{ + arrowIconRect.width = arrowIconRect.height = 0; + } + textRect.x += myMaxGutterIconWidth; + iconRect.x += myMaxGutterIconWidth; + } + textRect.x += menuItemGap; + iconRect.x += menuItemGap; + Rectangle labelRect = iconRect.union(textRect); + + // Position the Accelerator text rect + + acceleratorRect.x += viewRect.width - arrowIconRect.width - menuItemGap - acceleratorRect.width; + acceleratorRect.y = (viewRect.y + viewRect.height / 2) - acceleratorRect.height / 2; + + // Position the Check and Arrow Icons + + if (useCheckAndArrow()){ + arrowIconRect.x += viewRect.width - arrowIconRect.width; + arrowIconRect.y = (viewRect.y + labelRect.height / 2) - arrowIconRect.height / 2; + if (checkIcon != null){ + checkIconRect.y = (viewRect.y + labelRect.height / 2) - checkIconRect.height / 2; + checkIconRect.x += (viewRect.x + myMaxGutterIconWidth / 2) - checkIcon.getIconWidth() / 2; + a = viewRect.x; + e = (viewRect.y + labelRect.height / 2) - myMaxGutterIconWidth / 2; + k = viewRect.x + myMaxGutterIconWidth + 2; + } + else{ + checkIconRect.x = checkIconRect.y = 0; + } + } + return text; + } + + private Icon getIcon() { + Icon icon = menuItem.getIcon(); + if (icon != null && getAllowedIcon() != null){ + icon = null; + } + return icon; + } + + protected Dimension getPreferredMenuItemSize( + JComponent comp, + Icon checkIcon, + Icon arrowIcon, + int defaultTextIconGap + ){ + JMenu jMenu = (JMenu)comp; + Icon icon1 = getIcon(); + Icon icon2 = getAllowedIcon(); + String text = jMenu.getText(); + Font font = jMenu.getFont(); + FontMetrics fontmetrics = jMenu.getToolkit().getFontMetrics(font); + resetRects(); + layoutMenuItem( + fontmetrics, + text, + icon1, + icon2, + arrowIcon, + jMenu.getVerticalAlignment(), + jMenu.getHorizontalAlignment(), + jMenu.getVerticalTextPosition(), + jMenu.getHorizontalTextPosition(), + ourViewRect, + ourIconRect, + ourTextRect, + ourAcceleratorRect, + ourCheckIconRect, + ourArrowIconRect, + text != null ? defaultTextIconGap : 0, + defaultTextIconGap + ); + ourPreferredSizeRect.setBounds(ourTextRect); + ourPreferredSizeRect = SwingUtilities.computeUnion(ourIconRect.x, ourIconRect.y, ourIconRect.width, ourIconRect.height, ourPreferredSizeRect); + if (useCheckAndArrow()){ + ourPreferredSizeRect.width += myMaxGutterIconWidth; + ourPreferredSizeRect.width += defaultTextIconGap; + ourPreferredSizeRect.width += defaultTextIconGap; + ourPreferredSizeRect.width += ourArrowIconRect.width; + } + ourPreferredSizeRect.width += 2 * defaultTextIconGap; + Insets insets = jMenu.getInsets(); + if (insets != null){ + ourPreferredSizeRect.width += insets.left + insets.right; + ourPreferredSizeRect.height += insets.top + insets.bottom; + } + if (ourPreferredSizeRect.width % 2 == 0){ + ourPreferredSizeRect.width++; + } + if (ourPreferredSizeRect.height % 2 == 0){ + ourPreferredSizeRect.height++; + } + return ourPreferredSizeRect.getSize(); + } + + private void drawIconBorder(Graphics g) { + int i1 = a - 1; + int j1 = e - 2; + int k1 = i1 + myMaxGutterIconWidth + 1; + int l1 = j1 + myMaxGutterIconWidth + 4; + g.setColor(BegResources.m); + g.drawLine(i1, j1, i1, l1); + g.drawLine(i1, j1, k1, j1); + g.setColor(BegResources.j); + g.drawLine(k1, j1, k1, l1); + g.drawLine(i1, l1, k1, l1); + } + + private void resetRects() { + ourIconRect.setBounds(ourZeroRect); + ourTextRect.setBounds(ourZeroRect); + ourAcceleratorRect.setBounds(ourZeroRect); + ourCheckIconRect.setBounds(ourZeroRect); + ourArrowIconRect.setBounds(ourZeroRect); + ourViewRect.setBounds(0, 0, Short.MAX_VALUE, Short.MAX_VALUE); + ourPreferredSizeRect.setBounds(ourZeroRect); + } + + private Icon getAllowedIcon() { + Icon icon = menuItem.isEnabled() ? menuItem.getIcon() : menuItem.getDisabledIcon(); + if (icon != null && icon.getIconWidth() > myMaxGutterIconWidth){ + icon = null; + } + return icon; + } + + public void update(Graphics g, JComponent comp) { + paint(g, comp); + } + + /** + * Handles the mnemonic handling for the JMenu and JMenuItems. + */ + private final class SUN_BUG_ID_4738042_Patch implements MenuKeyListener { + private final boolean crossMenuMnemonic = UIManager.getBoolean("Menu.crossMenuMnemonic"); + + private JPopupMenu getActivePopupMenu(){ + MenuElement[] path = MenuSelectionManager.defaultManager(). + getSelectedPath(); + for (int i = path.length - 1; i >= 0; i--) { + MenuElement elem = path[i]; + if (elem instanceof JPopupMenu) { + return (JPopupMenu)elem; + } + } + return null; + } + + /** + * Opens the SubMenu + */ + public void menuKeyTyped(MenuKeyEvent e){ + if (!crossMenuMnemonic) { + JPopupMenu pm = getActivePopupMenu(); + if (pm != null && pm != menuItem.getParent()) { + return; + } + } + + int key = menuItem.getMnemonic(); + if (key == 0) + return; + MenuElement path[] = e.getPath(); + if (lower((char)key) == lower(e.getKeyChar())) { + JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu(); + MenuElement sub[] = popupMenu.getSubElements(); + if (sub.length > 0) { + MenuSelectionManager manager = e.getMenuSelectionManager(); + MenuElement newPath[] = new MenuElement[path.length + 2]; + System.arraycopy(path, 0, newPath, 0, path.length); + newPath[path.length] = popupMenu; + newPath[path.length + 1] = sub[0]; + manager.setSelectedPath(newPath); + } + e.consume(); + } + } + + /** + * Handles the mnemonics for the menu items. Will also handle duplicate mnemonics. + * Perhaps this should be moved into BasicPopupMenuUI. See 4670831 + */ + public void menuKeyPressed(MenuKeyEvent e){ + // Handle the case for Escape or Enter... + char keyChar = e.getKeyChar(); + if (!Character.isLetterOrDigit(keyChar)) + return; + + MenuSelectionManager manager = e.getMenuSelectionManager(); + MenuElement selectedPath[] = manager.getSelectedPath(); + + for (int i = selectedPath.length - 1; i >= 0; i--) { + if (selectedPath[i] == menuItem) { + JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu(); + MenuElement items[] = popupMenu.getSubElements(); + + int index = -1; + + for (int j = 0; j < items.length; j++) { + int key = ((JMenuItem)items[j]).getMnemonic(); + if (Character.toLowerCase((char)key) == Character.toLowerCase(keyChar)) { + index = j; + break; + } + } + + if (index != -1) { + // Invoke the menu action + JMenuItem item = (JMenuItem)items[index]; + if (!(item instanceof JMenu)) { + // Let Submenus be handled by menuKeyTyped + manager.clearSelectedPath(); + item.doClick(); + } + } + + e.consume(); + return; + } + } + } + + public void menuKeyReleased(MenuKeyEvent e){ + } + + private char lower(char keyChar){ + return Character.toLowerCase(keyChar); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ActiveDecorationLayer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ActiveDecorationLayer.java new file mode 100644 index 00000000000..57c8b059266 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ActiveDecorationLayer.java @@ -0,0 +1,267 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.core.GridLayoutManager; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Decoration layer is over COMPONENT_LAYER (layer where all components are located). + * It contains all necessary decorators. Decorators are: + * - special mini-buttons to perform editing of grids (add/remove of columns) + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ActiveDecorationLayer extends JComponent{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.ActiveDecorationLayer"); + + private final GuiEditor myEditor; + private final HashMap> myHorizontalSpots; + private final HashMap> myVerticalSpots; + /** + * Cache of invalid items which can be reused later for better performance + */ + private final ArrayList myInvalidSpotCache; + + public ActiveDecorationLayer(final GuiEditor editor) { + LOG.assertTrue(editor != null); + + myEditor = editor; + myHorizontalSpots = new HashMap>(); + myVerticalSpots = new HashMap>(); + myInvalidSpotCache = new ArrayList(); + } + + /** + * Creates new item or return invalid cached item + */ + private ActiveSpot createSpot(final ArrayList spots){ + final ActiveSpot result; + if(!myInvalidSpotCache.isEmpty()){ + result = myInvalidSpotCache.remove(myInvalidSpotCache.size() - 1); + } + else{ + result = new ActiveSpot(myEditor); + } + LOG.assertTrue(!spots.contains(result)); + add(result); + spots.add(result); + return result; + } + + /** + * Puts specified spot into invalid spot cache + */ + private void disposeSpot(final ActiveSpot spot){ + remove(spot); + myInvalidSpotCache.add(spot); + } + + /** + * Layouts all items in horizontal dimension + */ + private void layoutVerticalSpots(){ + // First of all we have to remove all invalid spots + final RadRootContainer rootContainer = myEditor.getRootContainer(); + for(Iterator>> i = myVerticalSpots.entrySet().iterator(); i.hasNext();){ + final Map.Entry> entry = i.next(); + final RadContainer container = (RadContainer)FormEditingUtil.findComponent(rootContainer, entry.getKey().getId()); + final ArrayList spots = entry.getValue(); + if(container == null || !container.hasDragger() || !container.isGrid()){ + // If RadContainer was deleted or breaked we need to invalidate all spots + for(int j = spots.size() - 1; j >= 0; j--){ + disposeSpot(spots.get(j)); + } + i.remove(); + } + else{ + // The RadContainer can be valid but number of spots might be wrong. + // We need to make number of spots the same as number of rows. + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final int rowCount = layout.getRowCount(); + if(rowCount > spots.size()){ // add necessary spots + for(int j = rowCount - spots.size() - 1; j >= 0; j--){ + createSpot(spots); + } + } + else if(rowCount < spots.size()){ // remove unnecessary spots + for(int j = spots.size() - rowCount - 1; j >= 0; j--){ + disposeSpot(spots.remove(j)); + } + } + } + } + + // Now we have to iterate through all items and insert ActiveSpots + // for components which should have decorations but do not have items yet. + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if(!(component instanceof RadContainer)){ + return true; + } + final RadContainer container = (RadContainer)component; + if(!container.isGrid() || !container.hasDragger() || myVerticalSpots.containsKey(container)){ + return true; + } + + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final ArrayList spots = new ArrayList(); + myVerticalSpots.put(container, spots); + for(int i = layout.getRowCount() -1; i >= 0; i--){ + createSpot(spots); + } + + return true; + } + } + ); + + // Now we are ready to layout all horizontal items + for(Iterator>> i = myVerticalSpots.entrySet().iterator(); i.hasNext();){ + final Map.Entry> entry = i.next(); + final RadContainer container = entry.getKey(); + LOG.assertTrue(container.isGrid()); + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final ArrayList spots = entry.getValue(); + LOG.assertTrue(spots.size() == layout.getRowCount()); + final int[] heights = layout.getHeights(); + final int[] ys = layout.getYs(); + final JComponent delegee = container.getDelegee(); + final Point topLeftPoint = SwingUtilities.convertPoint(delegee, 0, 0, ActiveDecorationLayer.this); + for(int j = heights.length - 1; j >= 0; j--){ + final ActiveSpot spot = spots.get(j); + + spot.setContainer(container); + spot.setCell(j); + spot.setOrientation(SwingConstants.VERTICAL); + spot.setCellSize(heights[j]); + spot.updateActions(); + + final Dimension prefSize = spot.getPreferredSize(); + final int width = prefSize.width; + final int shift = Math.max(0, heights[j] - prefSize.height)/2; + spot.setBounds( + topLeftPoint.x - width, + topLeftPoint.y + ys[j] + shift, + width, + heights[j] - shift + ); + spot.validate(); + } + } + } + + /** + * Layouts all items in vertical dimension + */ + private void layoutHorizontalSpots(){ + // First of all we have to remove all invalid spots + final RadRootContainer rootContainer = myEditor.getRootContainer(); + for(Iterator>> i = myHorizontalSpots.entrySet().iterator(); i.hasNext();){ + final Map.Entry> entry = i.next(); + final RadContainer container = (RadContainer)FormEditingUtil.findComponent(rootContainer, entry.getKey().getId()); + final ArrayList spots = entry.getValue(); + if(container == null || !container.hasDragger() || !container.isGrid()){ + // If RadContainer was deleted or breaked we need to invalidate all spots + for(int j = spots.size() - 1; j >= 0; j--){ + disposeSpot(spots.get(j)); + } + i.remove(); + } + else{ + // The RadContainer can be valid but number of spots might be wrong. + // We need to make number of spots the same as number of columns. + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final int columnCount = layout.getColumnCount(); + if(columnCount > spots.size()){ // add necessary spots + for(int j = columnCount - spots.size() - 1; j >= 0; j--){ + createSpot(spots); + } + } + else if(columnCount < spots.size()){ // remove unnecessary spots + for(int j = spots.size() - columnCount - 1; j >= 0; j--){ + disposeSpot(spots.remove(j)); + } + } + } + } + + // Now we have to iterate through all items and insert ActiveSpots + // for components which should have decorations but do not have items yet. + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if(!(component instanceof RadContainer)){ + return true; + } + final RadContainer container = (RadContainer)component; + if(!container.isGrid() || !container.hasDragger() || myHorizontalSpots.containsKey(container)){ + return true; + } + + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final ArrayList spots = new ArrayList(); + myHorizontalSpots.put(container, spots); + for(int i = layout.getColumnCount() -1; i >= 0; i--){ + createSpot(spots); + } + + return true; + } + } + ); + + // Now we are ready to layout all horizontal items + for(Iterator>> i = myHorizontalSpots.entrySet().iterator(); i.hasNext();){ + final Map.Entry> entry = i.next(); + final RadContainer container = entry.getKey(); + LOG.assertTrue(container.isGrid()); + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + final ArrayList spots = entry.getValue(); + LOG.assertTrue(spots.size() == layout.getColumnCount()); + final int[] widths = layout.getWidths(); + final int[] xs = layout.getXs(); + final JComponent delegee = container.getDelegee(); + final Point topLeftPoint = SwingUtilities.convertPoint(delegee, 0, 0, ActiveDecorationLayer.this); + for(int j = widths.length - 1; j >= 0; j--){ + final ActiveSpot spot = spots.get(j); + + spot.setContainer(container); + spot.setCell(j); + spot.setOrientation(SwingConstants.HORIZONTAL); + spot.setCellSize(widths[j]); + spot.updateActions(); + + final Dimension prefSize = spot.getPreferredSize(); + final int height = prefSize.height; + final int shift = Math.max(0, widths[j] - prefSize.width)/2; + spot.setBounds( + topLeftPoint.x + xs[j] + shift, + topLeftPoint.y - height, + widths[j] - shift, + height + ); + spot.validate(); + } + } + } + + public void paint(final Graphics g){ + // Active spots + layoutHorizontalSpots(); + layoutVerticalSpots(); + LOG.assertTrue(myVerticalSpots.size() == myHorizontalSpots.size()); + + // Paint active decorators + paintChildren(g); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/CutCopyPasteSupport.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/CutCopyPasteSupport.java new file mode 100644 index 00000000000..78eec4cec3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/CutCopyPasteSupport.java @@ -0,0 +1,269 @@ +package com.intellij.uiDesigner; + +import com.intellij.ide.CopyProvider; +import com.intellij.ide.CutProvider; +import com.intellij.ide.PasteProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.LwComponent; +import com.intellij.uiDesigner.lw.LwContainer; +import gnu.trove.TIntArrayList; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.*; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class CutCopyPasteSupport implements CopyProvider, CutProvider, PasteProvider{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.CutCopyPasteSupport"); + + private static String myRecentyCopiedString; + private static int myRecentyCopiedStringCount; + + private final GuiEditor myEditor; + + public CutCopyPasteSupport(final GuiEditor uiEditor) { + myEditor = uiEditor; + } + + public boolean isCopyEnabled(final DataContext dataContext) { + return FormEditingUtil.getSelectedComponents(myEditor).size() > 0; + } + + public void performCopy(final DataContext dataContext) { + doCopy(); + } + + private boolean doCopy() { + final ArrayList selectedComponents = FormEditingUtil.getSelectedComponents(myEditor); + final MyData data = new MyData(serializeForCopy(selectedComponents)); + final MyTransferable transferable = new MyTransferable(data); + try { + final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(transferable, new MyClipboardOwner()); + return true; + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug(e); + } + return false; + } + } + + public boolean isCutEnabled(final DataContext dataContext) { + return isCopyEnabled(dataContext); + } + + public void performCut(final DataContext dataContext) { + if (doCopy()) { + FormEditingUtil.deleteSelection(myEditor); + } + } + + public boolean isPastePossible(final DataContext dataContext) { + return isPasteEnabled(dataContext); + } + + public boolean isPasteEnabled(final DataContext dataContext) { + return getSerializedComponents() != null; + } + + public void performPaste(final DataContext dataContext) { + final String serializedComponents = getSerializedComponents(); + + if (serializedComponents.equals(myRecentyCopiedString)) { + myRecentyCopiedStringCount++; + } + else { + myRecentyCopiedString = serializedComponents; + myRecentyCopiedStringCount = 1; + } + + final PsiPropertiesProvider provider = new PsiPropertiesProvider(myEditor.getModule()); + + final ArrayList componentsToPaste = new ArrayList(); + final TIntArrayList xs = new TIntArrayList(); + final TIntArrayList ys = new TIntArrayList(); + + try { + final org.jdom.Document document = new SAXBuilder().build(new StringReader(serializedComponents), "UTF-8"); + + final Element rootElement = document.getRootElement(); + if (!rootElement.getName().equals("serialized")) { + return; + } + + // we need to add component to a container in order to read them + final LwContainer container = new LwContainer(JPanel.class.getName()); + + final java.util.List children = rootElement.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + final Element e = (Element)iterator.next(); + + final int x = Integer.parseInt(e.getAttributeValue("x")); + final int y = Integer.parseInt(e.getAttributeValue("y")); + + xs.add(x); + ys.add(y); + + final Element componentElement = (Element)e.getChildren().get(0); + final LwComponent lwComponent = LwContainer.createComponentFromTag(componentElement); + + container.addComponent(lwComponent); + + lwComponent.read(componentElement, provider); + + // pasted components should have no bindings + lwComponent.setBinding(null); + lwComponent.setId(myEditor.generateId()); + FormEditingUtil.iterate(lwComponent, new FormEditingUtil.ComponentVisitor() { + public boolean visit(final LwComponent c) { + c.setBinding(null); + c.setId(myEditor.generateId()); + return true; + } + }); + + final Module module = myEditor.getModule(); + final ClassLoader loader = LoaderFactory.getInstance(module.getProject()).getLoader(myEditor.getFile()); + final RadComponent radComponent = XmlReader.createComponent(module, lwComponent, loader); + componentsToPaste.add(radComponent); + } + } + catch (Exception e) { + } + + final RadRootContainer rootContainer = myEditor.getRootContainer(); + FormEditingUtil.clearSelection(rootContainer); + for (int i = 0; i < componentsToPaste.size(); i++) { + final RadComponent component = componentsToPaste.get(i); + final int delta = myRecentyCopiedStringCount * 10; + component.setLocation(new Point(xs.get(i) + delta, ys.get(i) + delta)); + rootContainer.addComponent(component); + + FormEditingUtil.iterate(component, new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent c) { + c.setSelected(true); + return true; + } + }); + } + + myEditor.refreshAndSave(true); + } + + private static final class MyData { + private final String mySerializedComponents; + + public MyData(final String components) { + mySerializedComponents = components; + } + + public String getSerializedComponents() { + return mySerializedComponents; + } + } + + private String getSerializedComponents() { + try { + final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + final Transferable content = clipboard.getContents(this); + final Object transferData; + try { + transferData = content.getTransferData(ourDataFlavor); + } catch (UnsupportedFlavorException e) { + return null; + } catch (IOException e) { + return null; + } + + if (!(transferData instanceof MyData)) { + return null; + } + final MyData dataProxy = (MyData) transferData; + return dataProxy.getSerializedComponents(); + } catch (Exception e) { + return null; + } + } + + private static final DataFlavor ourDataFlavor; + static { + try { + ourDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + MyData.class.getName()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + private static final class MyClipboardOwner implements ClipboardOwner { + public void lostOwnership(final Clipboard clipboard, final Transferable contents) { + } + } + + private String serializeForCopy(final ArrayList components) { + final XmlWriter writer = new XmlWriter(); + + writer.startElement("serialized", Utils.FORM_NAMESPACE); + + for (int i = 0; i < components.size(); i++) { + final RadComponent component = components.get(i); + + final Point shift = SwingUtilities.convertPoint( + component.getParent().getDelegee(), + component.getX(), + component.getY(), + myEditor.getRootContainer().getDelegee() + ); + + component.getX(); + + writer.startElement("item"); + writer.addAttribute("x", shift.x); + writer.addAttribute("y", shift.y); + component.write(writer); + + writer.endElement(); + } + + writer.endElement(); + + return writer.getText(); + } + + + public static final class MyTransferable implements Transferable { + private final MyData myDataProxy; + + public MyTransferable(final MyData data) { + myDataProxy = data; + } + + public Object getTransferData(final DataFlavor flavor) { + if (!ourDataFlavor.equals(flavor)) { + return null; + } + return myDataProxy; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{ourDataFlavor}; + } + + public boolean isDataFlavorSupported(final DataFlavor flavor) { + return flavor.equals(ourDataFlavor); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DesignSpacer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DesignSpacer.java new file mode 100644 index 00000000000..1236e7b4632 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DesignSpacer.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner; + +import com.intellij.uiDesigner.core.Spacer; + +import java.awt.*; + +/** + * Used in design time only. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +abstract class DesignSpacer extends Spacer{ + protected static final int HANDLE_ATOM_WIDTH = 5; + protected static final int HANDLE_ATOM_HEIGHT = 3; + protected static final int HANDLE_ATOM_SPACE = 1; + + protected static final int SPRING_PRERIOD = 4; + + protected static final Color ourColor1 = new Color(8,8,108); + protected static final Color ourColor2 = new Color(3,26,142); + protected static final Color ourColor3 = Color.BLACK; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragLayer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragLayer.java new file mode 100644 index 00000000000..90eef13f7c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragLayer.java @@ -0,0 +1,33 @@ +package com.intellij.uiDesigner; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class DragLayer extends PassiveDecorationLayer { + public DragLayer(final GuiEditor editor) { + super(editor); + } + + public void paint(final Graphics g){ + ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f)); + + // Paint passive decoration of dragged components + for(int i = getComponentCount() - 1; i >= 0; i--){ + final Component child = getComponent(i); + if(child instanceof JComponent){ + final Object prop = ((JComponent)child).getClientProperty(RadComponent.CLIENT_PROP_RAD_COMPONENT); + if(prop != null){ + final RadComponent radComponent = (RadComponent)prop; + paintPassiveDecoration(radComponent, g); + } + } + } + + // Paint selection rectangle + paintChildren(g); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragSelectionProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragSelectionProcessor.java new file mode 100644 index 00000000000..203d5140e9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/DragSelectionProcessor.java @@ -0,0 +1,338 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.core.GridConstraints; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class DragSelectionProcessor extends EventProcessor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.DragSelectionProcessor"); + + /** + * We have not start drag/cancel drop if mouse pointer trembles in small area + */ + private static final int TREMOR = 3; + + private final GuiEditor myEditor; + private MyPreviewer myPreviewer; + private Point myLastPoint; + + private Point myPressPoint; + + /** + * Arrays of components to be dragged + */ + private ArrayList mySelection; + private GridConstraints[] myOriginalConstraints; + private Rectangle[] myOriginalBounds; + private RadContainer[] myOriginalParents; + + /* + * Required to undo drop + */ + private DropInfo myDropInfo; + private boolean myDragStarted; + + public DragSelectionProcessor(final GuiEditor editor){ + LOG.assertTrue(editor!=null); + + myEditor = editor; + } + + private void processStartDrag(final MouseEvent e){ + myPreviewer = new MyPreviewer(); + + // Store selected components + mySelection = FormEditingUtil.getSelectedComponents(myEditor); + + // Store original constraints and parents. This information is required + // to restore initial state if drag is canceled. + myOriginalConstraints = new GridConstraints[mySelection.size()]; + myOriginalBounds = new Rectangle[mySelection.size()]; + myOriginalParents = new RadContainer[mySelection.size()]; + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent component = mySelection.get(i); + myOriginalConstraints[i] = component.getConstraints().store(); + myOriginalBounds[i] = component.getBounds(); + myOriginalParents[i] = component.getParent(); + } + + // It's very important to get component under mouse before the components are + // removed from their parents. + final RadComponent componentUnderMouse = FormEditingUtil.getRadComponentAt(myEditor, myPressPoint.x, myPressPoint.y); + int dx = 0; + int dy = 0; + + // Remove components from their parents. + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent c = mySelection.get(i); + c.getParent().removeComponent(c); + } + + // Place selected components to the drag layer. + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent c = mySelection.get(i); + final JComponent delegee = c.getDelegee(); + final Point point = SwingUtilities.convertPoint( + myOriginalParents[i].getDelegee(), + delegee.getLocation(), + myEditor.getDragLayer() + ); + delegee.setLocation(point); + myEditor.getDragLayer().add(delegee); + + // make sure mouse cursor is inside the component being dragged + if (c == componentUnderMouse) { + if (delegee.getX() > e.getX() || delegee.getX() + delegee.getWidth() < e.getX()) { + dx = e.getX() - (delegee.getX() + delegee.getWidth() / 2); + } + if (delegee.getY() > e.getY() || delegee.getY() + delegee.getHeight() < e.getY()) { + dy = e.getY() - (delegee.getY() + delegee.getHeight() / 2); + } + } + } + + for (int i = 0; i < mySelection.size(); i++) { + mySelection.get(i).shift(dx, dy); + } + + myEditor.refresh(); + myLastPoint=e.getPoint(); + } + + /** + * "Drops" selection at the specified point. + * + * @param point point in coordinates of drag layer (it's convenient here). + * + * @return true if the selected components were successfully dropped + */ + private boolean dropSelection(final Point point){ + LOG.assertTrue(point!=null); + + + if (!FormEditingUtil.canDrop(myEditor, point.x, point.y, mySelection.size())) { + return false; + } + + final int[] dx = new int[mySelection.size()]; + final int[] dy = new int[mySelection.size()]; + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent component = mySelection.get(i); + dx[i] = component.getX() - point.x; + dy[i] = component.getY() - point.y; + } + + myDropInfo = FormEditingUtil.drop( + myEditor, + point.x, + point.y, + mySelection.toArray(new RadComponent[mySelection.size()]), + dx, + dy + ); + return true; + } + + private void cancelDrop(){ + // Remove dropped preview + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent component = mySelection.get(i); + final RadContainer parent = component.getParent(); + LOG.assertTrue(parent != null); + parent.removeComponent(component); + } + + if (myDropInfo != null && myDropInfo.myTopmostContainer!=null) { + myDropInfo.myTopmostContainer.setSize(myDropInfo.myTopmostContainerSize); + } + } + + private void processMouseReleased(){ + // Cancel all pending requests for preview. + myPreviewer.dispose(); + + // Try to drop selection at the point of mouse event. + if(dropSelection(myLastPoint)){ + myEditor.refreshAndSave(true); + }else{ + cancelDrag(); + } + + myEditor.repaintLayeredPane(); + } + + protected boolean cancelOperation(){ + if (!myDragStarted) { + return true; + } + // Cancel all pending requests for preview. + myPreviewer.dispose(); + // Try to drop selection at the point of mouse event. + cancelDrag(); + myEditor.repaintLayeredPane(); + return true; + } + + /** + * Cancels drag of component. The method returns all dragged components + * to their original places and returns them their original sizes. + */ + private void cancelDrag() { + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent c = mySelection.get(i); + c.getConstraints().restore(myOriginalConstraints[i]); + c.setBounds(myOriginalBounds[i]); + myOriginalParents[i].addComponent(c); + } + myEditor.refresh(); + } + + protected void processKeyEvent(final KeyEvent e) { } + + protected void processMouseEvent(final MouseEvent e){ + if(e.getID()==MouseEvent.MOUSE_PRESSED){ + myPressPoint = e.getPoint(); + } + else if(e.getID()==MouseEvent.MOUSE_RELEASED){ + if (myDragStarted) { + processMouseReleased(); + } + } + else if(e.getID()==MouseEvent.MOUSE_DRAGGED){ + if (!myDragStarted) { + if ((Math.abs(e.getX() - myPressPoint.getX()) > TREMOR || Math.abs(e.getY() - myPressPoint.getY()) > TREMOR)) { + processStartDrag(e); + myDragStarted = true; + } + } + + if (myDragStarted) { + processMouseDragged(e); + } + } + } + + private void processMouseDragged(final MouseEvent e){ + // Restart previewer. + myPreviewer.processMouseDragged(e); + if(myPreviewer.isPreview()){ + return; + } + + // Move components in the drag layer. + final int dx = e.getX() - myLastPoint.x; + final int dy = e.getY() - myLastPoint.y; + for (int i = 0; i < mySelection.size(); i++) { + mySelection.get(i).shift(dx, dy); + } + + myLastPoint=e.getPoint(); + myEditor.getDragLayer().repaint(); + + setCursor(FormEditingUtil.getDropCursor(myEditor, e.getX(), e.getY(), mySelection.size())); + } + + /** + * This class gets notifications from "gusture" timer. It's responsible for + * drop preview. + */ + private final class MyPreviewer implements ActionListener{ + private static final int DROP_DELAY = 500; + /** + * This timer is responsible for drop preview. The timer is restarted each time user + * is dragging the component. When user stop dragging and drag isn't completed then + * the timer fires event and user gets drop preview. + */ + private final Timer myTimer; + private boolean myPreview; + private Point myDropPoint; + /** + * These are bounds of selection before dropping. This field + * is required to bring the dropped selection back to the drad layer + * if user is contining mouse drag. + */ + private Rectangle[] myOriginalBounds; + + public MyPreviewer(){ + myTimer = new Timer(DROP_DELAY,this); + myTimer.setRepeats(false); + myTimer.start(); + } + + public void actionPerformed(final ActionEvent e){ + LOG.assertTrue(!myPreview); + + // Store current bounds of the selection + myOriginalBounds=new Rectangle[mySelection.size()]; + for(int i=0;i TREMOR || Math.abs(e.getY()-myDropPoint.getY()) > TREMOR) + ){ + cancelPreview(); + myEditor.refresh(); + } + } + + /** + * Disposes the previewer. The method remove preview (if any). + */ + public void dispose(){ + myTimer.stop(); + cancelPreview(); + } + + /** + * Cancels preview: removes dropped selection form container and bring it back to + * the drag layer. + */ + private void cancelPreview(){ + if(myPreview){ + cancelDrop(); + + // Bring selection back to the dragged layer + for (int i = 0; i < mySelection.size(); i++) { + final RadComponent component = mySelection.get(i); + component.setBounds(myOriginalBounds[i]); + myEditor.getDragLayer().add(component.getDelegee()); + } + + myPreview=false; + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorAnalizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorAnalizer.java new file mode 100644 index 00000000000..dff8ef6eb67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorAnalizer.java @@ -0,0 +1,247 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.uiDesigner.lw.IComponent; +import com.intellij.uiDesigner.lw.IContainer; +import com.intellij.uiDesigner.lw.IRootContainer; +import com.intellij.uiDesigner.quickFixes.CreateClassToBindFix; +import com.intellij.uiDesigner.quickFixes.CreateFieldFix; +import com.intellij.uiDesigner.quickFixes.QuickFix; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ErrorAnalizer { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.ErrorAnalyzer"); + + /** + * Value {@link ErrorInfo} + */ + public static final String CLIENT_PROP_CLASS_TO_BIND_ERROR = "classToBindError"; + /** + * Value {@link ErrorInfo} + */ + public static final String CLIENT_PROP_BINDING_ERROR = "bindingError"; + /** + * Value {@link ErrorInfo} + */ + public static final String CLIENT_PROP_GENERAL_ERROR = "generalError"; + + public static void analyzeErrors(final GuiEditor editor, final IRootContainer rootContainer){ + analyzeErrors(editor.getModule(), editor.getFile(), editor, rootContainer); + } + + /** + * @param editor if null, no quick fixes are created. This is used in form to source compiler. + */ + public static void analyzeErrors( + final Module module, + final VirtualFile formFile, + final GuiEditor editor, + final IRootContainer rootContainer + ){ + LOG.assertTrue(module != null); + LOG.assertTrue(formFile != null); + LOG.assertTrue(rootContainer != null); + + // 1. Validate class to bind + final String classToBind = rootContainer.getClassToBind(); + final PsiClass psiClass; + if(classToBind != null){ + psiClass = FormEditingUtil.findClassToBind(module, classToBind); + if(psiClass == null){ + final QuickFix[] fixes = editor != null ? new QuickFix[]{new CreateClassToBindFix(editor, classToBind)} : QuickFix.EMPTY_ARRAY; + final ErrorInfo errorInfo = new ErrorInfo("Class \"" + classToBind + "\" does not exist", fixes); + rootContainer.putClientProperty(CLIENT_PROP_CLASS_TO_BIND_ERROR, errorInfo); + } + else{ + rootContainer.putClientProperty(CLIENT_PROP_CLASS_TO_BIND_ERROR, null); + } + } + else{ + psiClass = null; + } + + // 2. Validate bindings to fields + // field name -> error message + final ArrayList usedBindings = new ArrayList(); // for performance reasons + final HashMap className2Type = new HashMap(); // for performance reasons + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final IComponent component) { + // Reset previous error (if any) + component.putClientProperty(CLIENT_PROP_BINDING_ERROR, null); + + final String binding = component.getBinding(); + if(binding == null){ + return true; + } + + // a. Check that field exists and field is not static + if(psiClass != null){ + final PsiField[] fields = psiClass.getFields(); + PsiField field = null; + for(int i = fields.length - 1; i >=0 ; i--){ + if(binding.equals(fields[i].getName())){ + field = fields[i]; + break; + } + } + if(field == null){ + final QuickFix[] fixes = editor != null ? new QuickFix[]{ + new CreateFieldFix(editor, psiClass, component.getComponentClassName(), binding)} : + QuickFix.EMPTY_ARRAY; + component.putClientProperty( + CLIENT_PROP_BINDING_ERROR, + new ErrorInfo( + "Field \"" + binding + "\" does not exist in class \"" + classToBind +"\"", + fixes + ) + ); + return true; + } + else if(field.hasModifierProperty(PsiModifier.STATIC)){ + component.putClientProperty( + CLIENT_PROP_BINDING_ERROR, + new ErrorInfo( + "Cannot bind to static field \"" + binding + "\"", + QuickFix.EMPTY_ARRAY + ) + ); + return true; + } + + // Check that field has correct fieldType + try { + final PsiType componentType; + final String className = component.getComponentClassName().replace('$', '.'); // workaround for PSI + if(className2Type.containsKey(className)){ + componentType = className2Type.get(className); + } + else{ + componentType = PsiManager.getInstance(module.getProject()).getElementFactory().createTypeFromText( + className, + null + ); + } + final PsiType fieldType = field.getType(); + if(fieldType != null && componentType != null && !fieldType.isAssignableFrom(componentType)){ + // TODO[vova] implement + component.putClientProperty( + CLIENT_PROP_BINDING_ERROR, + new ErrorInfo( + "Incompatible types. Found \"" + fieldType.getPresentableText() + "\", required \"" + className + "\"", + QuickFix.EMPTY_ARRAY + ) + ); + } + } + catch (IncorrectOperationException e) { + } + } + + // b. Check that binding is unique + if(usedBindings.contains(binding)){ + // TODO[vova] implement + component.putClientProperty( + CLIENT_PROP_BINDING_ERROR, + new ErrorInfo( + "Binding to field \"" + binding + "\" already exists", + QuickFix.EMPTY_ARRAY + ) + ); + return true; + } + + usedBindings.add(binding); + + return true; + } + } + ); + + // Check that there are no panels in XY with children + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final IComponent component) { + if(!(component instanceof IContainer)){ + return true; + } + + // Clear previous error (if any) + component.putClientProperty(CLIENT_PROP_GENERAL_ERROR, null); + + final IContainer container = (IContainer)component; + if(container instanceof IRootContainer){ + final IRootContainer rootContainer = (IRootContainer)container; + if(rootContainer.getComponentCount() > 1){ + // TODO[vova] implement + component.putClientProperty( + CLIENT_PROP_GENERAL_ERROR, + new ErrorInfo( + "Form cannot be compiled because it contains more than one component at the top level", + QuickFix.EMPTY_ARRAY + ) + ); + } + } + else if(container.isXY() && container.getComponentCount() > 0){ + // TODO[vova] implement + component.putClientProperty( + CLIENT_PROP_GENERAL_ERROR, + new ErrorInfo( + "Form cannot be compiled until this panel is layed out in a grid", + QuickFix.EMPTY_ARRAY + ) + ); + } + return true; + } + } + ); + } + + /** + * @return first ErrorInfo for the specified component. If component doesn't contain + * any error then the method returns null. + */ + public static ErrorInfo getErrorForComponent(final IComponent component){ + LOG.assertTrue(component != null); + + // Check bind to class errors + { + final ErrorInfo errorInfo = (ErrorInfo)component.getClientProperty(CLIENT_PROP_CLASS_TO_BIND_ERROR); + if(errorInfo != null){ + return errorInfo; + } + } + + // Check binding errors + { + final ErrorInfo error = (ErrorInfo)component.getClientProperty(CLIENT_PROP_BINDING_ERROR); + if(error != null){ + return error; + } + } + + // General error + { + final ErrorInfo errorInfo = (ErrorInfo)component.getClientProperty(CLIENT_PROP_GENERAL_ERROR); + if(errorInfo != null){ + return errorInfo; + } + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorInfo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorInfo.java new file mode 100644 index 00000000000..fb4db90170a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ErrorInfo.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner; + +import com.intellij.uiDesigner.quickFixes.QuickFix; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ErrorInfo { + public final String myDescription; + public final QuickFix[] myFixes; + + public ErrorInfo(final String description, final QuickFix[] fixes) { + if (description == null) { + throw new IllegalArgumentException("description cannot be null"); + } + if (fixes == null) { + throw new IllegalArgumentException("fixes cannot be null"); + } + myDescription = description; + myFixes = fixes; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/EventProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/EventProcessor.java new file mode 100644 index 00000000000..1014cae4f3c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/EventProcessor.java @@ -0,0 +1,30 @@ +package com.intellij.uiDesigner; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class EventProcessor { + private Cursor myCursor; + + public final Cursor getCursor(){ + return myCursor; + } + + public final void setCursor(final Cursor cursor){ + myCursor = cursor; + } + + protected abstract void processKeyEvent(KeyEvent e); + + protected abstract void processMouseEvent(MouseEvent e); + + /** + * @return true if processor cancelled its operation; false otherwise + */ + protected abstract boolean cancelOperation(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/FormEditingUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/FormEditingUtil.java new file mode 100644 index 00000000000..db8484219ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/FormEditingUtil.java @@ -0,0 +1,691 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.core.Util; +import com.intellij.uiDesigner.lw.IComponent; +import com.intellij.uiDesigner.lw.IContainer; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.Palette; +import com.intellij.uiDesigner.shared.XYLayoutManager; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class FormEditingUtil { + private static final Logger LOG=Logger.getInstance("#com.intellij.uiDesigner.FormEditingUtil"); + + private final static int HORIZONTAL_GRID = 1; + private final static int VERTICAL_GRID = 2; + private final static int GRID = 3; + + /** + * TODO[anton,vova]: most likely should be equal to "xy grid step" when available + */ + private static final int GRID_TREMOR = 5; + + public static void breakGrid(final GuiEditor editor) { + final ArrayList selection = getSelectedComponents(editor); + if (selection.size() != 1){ + return; + } + if (!(selection.get(0) instanceof RadContainer)) { + return; + } + final RadContainer container = (RadContainer)selection.get(0); + if ( + container instanceof RadScrollPane || + container instanceof RadSplitPane || + container instanceof RadTabbedPane + ){ + return; + } + + final RadContainer parent = container.getParent(); + + if (parent instanceof RadRootContainer) { + editor.getRootContainer().setMainComponentBinding(container.getBinding()); + } + + // XY can be broken only if its parent is also XY. + // In other words, breaking of XY is a deletion of unnecessary intermediate panel + if (container.isXY() && !parent.isXY()) { + return; + } + + if (parent != null && parent.isXY()) { + // parent is XY + // put the contents of the container into 'parent' and remove 'container' + + final int dx = container.getX(); + final int dy = container.getY(); + + while (container.getComponentCount() > 0) { + final RadComponent component = container.getComponent(0); + component.shift(dx, dy); + parent.addComponent(component); + } + + parent.removeComponent(container); + } + else { + // container becomes XY + final XYLayoutManager xyLayout = new XYLayoutManagerImpl(); + container.setLayout(xyLayout); + xyLayout.setPreferredSize(container.getSize()); + } + + editor.refreshAndSave(true); + } + + public static void convertToVerticalGrid(final GuiEditor editor){ + convertToGridImpl(editor, VERTICAL_GRID); + } + + public static void convertToHorizontalGrid(final GuiEditor editor){ + convertToGridImpl(editor, HORIZONTAL_GRID); + } + + public static void convertToGrid(final GuiEditor editor){ + convertToGridImpl(editor, GRID); + } + + private static void convertToGridImpl(final GuiEditor editor, final int gridType) { + final boolean createNewContainer; + + final RadContainer parent; + final RadComponent[] componentsToConvert; + { + final ArrayList selection = getSelectedComponents(editor); + if (selection.size() == 0) { + // root container selected + final RadRootContainer rootContainer = editor.getRootContainer(); + if (rootContainer.getComponentCount() < 2) { + // nothing to convert + return; + } + + componentsToConvert = new RadComponent[rootContainer.getComponentCount()]; + for (int i = 0; i < componentsToConvert.length; i++) { + componentsToConvert[i] = rootContainer.getComponent(i); + } + parent = rootContainer; + createNewContainer = true; + } + else if (selection.size() == 1 && selection.get(0) instanceof RadContainer) { + parent = (RadContainer)selection.get(0); + componentsToConvert = new RadComponent[parent.getComponentCount()]; + for (int i = 0; i < componentsToConvert.length; i++) { + componentsToConvert[i] = parent.getComponent(i); + } + createNewContainer = false; + } + else { + componentsToConvert = selection.toArray(new RadComponent[selection.size()]); + parent = selection.get(0).getParent(); + createNewContainer = true; + } + } + + if (!parent.isXY()) { + // only components in XY can be layed out in grid + return; + } + for (int i = 1; i < componentsToConvert.length; i++) { + final RadComponent component = componentsToConvert[i]; + if (component.getParent() != parent) { + return; + } + } + + final GridLayoutManager gridLayoutManager; + if (componentsToConvert.length == 0) { + // we convert empty XY panel to grid + gridLayoutManager = new GridLayoutManager(1,1); + } + else { + if (gridType == VERTICAL_GRID) { + gridLayoutManager = createOneDimensionGrid(componentsToConvert, true); + } + else if (gridType == HORIZONTAL_GRID) { + gridLayoutManager = createOneDimensionGrid(componentsToConvert, false); + } + else if (gridType == GRID) { + gridLayoutManager = createTwoDimensionGrid(componentsToConvert); + } + else { + throw new IllegalArgumentException("invalid grid type: " + gridType); + } + } + + for (int i = 0; i < componentsToConvert.length; i++) { + final RadComponent component = componentsToConvert[i]; + if (component instanceof RadContainer) { + final LayoutManager layout = ((RadContainer)component).getLayout(); + if (layout instanceof XYLayoutManager) { + ((XYLayoutManager)layout).setPreferredSize(component.getSize()); + } + } + } + + if (createNewContainer) { + // we should create a new panel + + final Module module = editor.getModule(); + final ComponentItem panelItem = Palette.getInstance(editor.getProject()).getPanelItem(); + final RadContainer newContainer = new RadContainer(module, editor.generateId()); + newContainer.setLayout(gridLayoutManager); + newContainer.init(panelItem); + + for (int i = 0; i < componentsToConvert.length; i++) { + newContainer.addComponent(componentsToConvert[i]); + } + + final Point topLeftPoint = getTopLeftPoint(componentsToConvert); + newContainer.setLocation(topLeftPoint); + + final Point bottomRightPoint = getBottomRightPoint(componentsToConvert); + final Dimension size = new Dimension(bottomRightPoint.x - topLeftPoint.x, bottomRightPoint.y - topLeftPoint.y); + Util.adjustSize(newContainer.getDelegee(), newContainer.getConstraints(), size); + newContainer.getDelegee().setSize(size); + + parent.addComponent(newContainer); + + clearSelection(editor.getRootContainer()); + newContainer.setSelected(true); + + // restore binding of main component + { + final String mainComponentBinding = editor.getRootContainer().getMainComponentBinding(); + if (mainComponentBinding != null && parent instanceof RadRootContainer) { + newContainer.setBinding(mainComponentBinding); + editor.getRootContainer().setMainComponentBinding(null); + } + } + } + else { + // convert entire 'parent' to grid + + parent.setLayout(gridLayoutManager); + + clearSelection(editor.getRootContainer()); + parent.setSelected(true); + } + + editor.refreshAndSave(true); + } + + private static GridLayoutManager createOneDimensionGrid(final RadComponent[] selection, final boolean isVertical){ + Arrays.sort( + selection, + new Comparator() { + public int compare(final Object o1, final Object o2){ + final Rectangle bounds1 = ((RadComponent)o1).getBounds(); + final Rectangle bounds2 = ((RadComponent)o2).getBounds(); + + if (isVertical) { + return (bounds1.y + bounds1.height / 2) - (bounds2.y + bounds2.height / 2); + } + else { + return (bounds1.x + bounds1.width / 2) - (bounds2.x + bounds2.width / 2); + } + } + } + ); + + for (int i = 0; i < selection.length; i++) { + final RadComponent component = selection[i]; + final GridConstraints constraints = component.getConstraints(); + if (isVertical) { + constraints.setRow(i); + constraints.setColumn(0); + } + else { + constraints.setRow(0); + constraints.setColumn(i); + } + constraints.setRowSpan(1); + constraints.setColSpan(1); + } + + final GridLayoutManager gridLayoutManager; + if (isVertical) { + gridLayoutManager = new GridLayoutManager(selection.length, 1); + } + else { + gridLayoutManager = new GridLayoutManager(1, selection.length); + } + return gridLayoutManager; + } + + /** + * @param x array of X coordinates of components that should be layed out in a grid. + * This is input/output parameter. + * + * @param y array of Y coordinates of components that should be layed out in a grid. + * This is input/output parameter. + * + * @param rowSpans output parameter. + * + * @param colSpans output parameter. + * + * @return pair that says how many (rows, columns) are in the composed grid. + */ + public static Pair layoutInGrid( + final int[] x, + final int[] y, + final int[] rowSpans, + final int[] colSpans + ){ + LOG.assertTrue(x.length == y.length); + LOG.assertTrue(y.length == colSpans.length); + LOG.assertTrue(colSpans.length == rowSpans.length); + + for (int i = 0; i < x.length; i++) { + colSpans[i] = Math.max(colSpans[i], 1); + rowSpans[i] = Math.max(rowSpans[i], 1); + + if (colSpans[i] > GRID_TREMOR * 4) { + colSpans[i] -= GRID_TREMOR * 2; + x[i] += GRID_TREMOR; + } + if (rowSpans[i] > GRID_TREMOR * 4) { + rowSpans[i] -= GRID_TREMOR * 2; + y[i] += GRID_TREMOR; + } + } + + + return new Pair( + new Integer(Util.eliminate(y, rowSpans, null)), + new Integer(Util.eliminate(x, colSpans, null)) + ); + } + + private static GridLayoutManager createTwoDimensionGrid(final RadComponent[] selection){ + final int[] x = new int[selection.length]; + final int[] y = new int[selection.length]; + final int[] colSpans = new int[selection.length]; + final int[] rowSpans = new int[selection.length]; + + for (int i = selection.length - 1; i >= 0; i--) { + x[i] = selection[i].getX(); + y[i] = selection[i].getY(); + rowSpans[i] = selection[i].getHeight(); + colSpans[i] = selection[i].getWidth(); + } + + final Pair pair = layoutInGrid(x, y, rowSpans, colSpans); + for (int i = 0; i < selection.length; i++) { + final RadComponent component = selection[i]; + final GridConstraints constraints = component.getConstraints(); + + constraints.setRow(y[i]); + constraints.setRowSpan(rowSpans[i]); + + constraints.setColumn(x[i]); + constraints.setColSpan(colSpans[i]); + } + final GridLayoutManager gridLayoutManager = new GridLayoutManager(pair.first.intValue(), pair.second.intValue()); + + return gridLayoutManager; + } + + public static boolean canDeleteSelection(final GuiEditor editor){ + if (!editor.isEditable()) { + return false; + } + final ArrayList selection = getSelectedComponents(editor); + return !selection.isEmpty(); + } + + /** + * This method must be executed in command + */ + public static void deleteSelection(final GuiEditor editor){ + final ArrayList selection = getSelectedComponents(editor); + for (int i = 0; i < selection.size(); i++) { + final RadComponent component = selection.get(i); + component.getParent().removeComponent(component); + } + + editor.refreshAndSave(true); + } + + /** + * @param x in editor pane coordinates + * @param y in editor pane coordinates + */ + public static RadComponent getRadComponentAt(final GuiEditor editor, final int x, final int y){ + final RadContainer rootContainer = editor.getRootContainer(); + Component c = SwingUtilities.getDeepestComponentAt(rootContainer.getDelegee(), x, y); + + RadComponent result = null; + + while (c != null) { + if (c instanceof JComponent){ + final RadComponent component = (RadComponent)((JComponent)c).getClientProperty(RadComponent.CLIENT_PROP_RAD_COMPONENT); + if (component != null) { + + if (result == null) { + result = component; + } + else { + final Point p = SwingUtilities.convertPoint(rootContainer.getDelegee(), x, y, c); + if (Painter.getResizeMask(component, p.x, p.y) != 0) { + result = component; + } + } + } + } + c = c.getParent(); + } + + return result; + } + + /** + * @return component which has dragger. There is only one component with the dargger + * at a time. + */ + public static RadComponent getDraggerHost(final GuiEditor editor){ + LOG.assertTrue(editor != null); + + final RadComponent[] result = new RadComponent[1]; + iterate( + editor.getRootContainer(), + new ComponentVisitor() { + public boolean visit(final RadComponent component) { + if(component.hasDragger()){ + result[0] = component; + return false; + } + return true; + } + } + ); + + return result[0]; + } + + /** + * @param x in editor pane coordinates + * @param y in editor pane coordinates + */ + public static Cursor getDropCursor(final GuiEditor editor, final int x, final int y, final int componentCount){ + Cursor cursor = Cursor.getDefaultCursor(); + if (canDrop(editor, x, y, componentCount)) { + try { + cursor = Cursor.getSystemCustomCursor("MoveDrop.32x32"); + } + catch (Exception ex) { + } + } + else { + try { + cursor = Cursor.getSystemCustomCursor("MoveNoDrop.32x32"); + } + catch (Exception ex) { + } + } + return cursor; + } + + /** + * @param x in editor pane coordinates + * @param y in editor pane coordinates + */ + public static boolean canDrop(final GuiEditor editor, final int x, final int y, final int componentCount){ + if (!editor.isEditable()) { + return false; + } + + if (componentCount == 0) { + return false; + } + + final RadComponent componentAt = getRadComponentAt(editor, x, y); + if (componentAt == null) { + return false; + } + + final Point targetPoint = SwingUtilities.convertPoint(editor.getDragLayer(), x, y, componentAt.getDelegee()); + return componentAt.canDrop(targetPoint.x, targetPoint.y, componentCount); + } + + /** + * @param x in editor pane coordinates + * @param y in editor pane coordinates + * @param dx x coordinate of components relative to x + * @param dx shift of component relative to x + * @param dx shift of component relative to y + */ + public static DropInfo drop(final GuiEditor editor, final int x, final int y, final RadComponent[] components, final int[] dx, final int[] dy){ + if (!canDrop(editor, x, y, components.length)) { + throw new IllegalArgumentException("cannot drop"); + } + + final RadContainer targetContainer = (RadContainer)getRadComponentAt(editor, x, y); + final Point targetPoint = SwingUtilities.convertPoint(editor.getDragLayer(), x, y, targetContainer.getDelegee()); + return targetContainer.drop(targetPoint.x, targetPoint.y, components, dx, dy); + } + + /** + * @return currently selected components. Method returns the minimal amount of + * selected component which contains all selected components. It means that if the + * selected container contains some selected children then only this container + * will be added to the returned array. + */ + public static ArrayList getSelectedComponents(final GuiEditor editor){ + LOG.assertTrue(editor != null); + + final ArrayList result = new ArrayList(); + calcSelectedComponentsImpl(result, editor.getRootContainer()); + return result; + } + + private static void calcSelectedComponentsImpl(final ArrayList result, final RadContainer container){ + if (container.isSelected()) { + if (container.getParent() != null) { // ignore RadRootContainer + result.add(container); + return; + } + } + + for (int i = 0; i < container.getComponentCount(); i++) { + final RadComponent component = container.getComponent(i); + if (component instanceof RadContainer) { + calcSelectedComponentsImpl(result, (RadContainer)component); + } + else { + if (component.isSelected()) { + result.add(component); + } + } + } + } + + /** + * @return all selected component inside the editor + */ + public static ArrayList getAllSelectedComponents(final GuiEditor editor){ + LOG.assertTrue(editor != null); + + final ArrayList result = new ArrayList(); + iterate( + editor.getRootContainer(), + new ComponentVisitor(){ + public boolean visit(final RadComponent component) { + if(component.isSelected()){ + result.add(component); + } + return true; + } + } + ); + return result; + } + + public static String getExceptionMessage(Throwable ex) { + if (ex instanceof RuntimeException) { + final Throwable cause = ex.getCause(); + if (cause != null && cause != ex) { + return getExceptionMessage(cause); + } + } + else + if (ex instanceof InvocationTargetException) { + final Throwable target = ((InvocationTargetException)ex).getTargetException(); + if (target != null && target != ex) { + return getExceptionMessage(target); + } + } + String message = ex.getMessage(); + if (ex instanceof ClassNotFoundException) { + message = message != null? "Class not found: " + message : "Class not found"; + } + else if (ex instanceof NoClassDefFoundError) { + message = message != null? "Required class not found: " + message : "Required class not found"; + } + return message; + } + + public static interface ComponentVisitor { + /** + * @return true if iteration should continue + */ + public boolean visit(Type component); + } + + /** + * Iterates component and its children (if any) + */ + public static void iterate(final IComponent component, final ComponentVisitor visitor){ + LOG.assertTrue(component != null); + LOG.assertTrue(visitor != null); + + iterateImpl(component, visitor); + } + + + private static boolean iterateImpl(final IComponent component, final ComponentVisitor visitor) { + final boolean shouldContinue = visitor.visit(component); + if (!shouldContinue) { + return false; + } + + if (!(component instanceof IContainer)) { + return true; + } + + final IContainer container = (IContainer)component; + + for (int i = 0; i < container.getComponentCount(); i++) { + final IComponent c = container.getComponent(i); + if (!iterateImpl(c, visitor)) { + return false; + } + } + + return true; + } + + /** + * Find top left point of component group, i.e. (minimum X of all components; minimum Y of all components) + * @param components array should contain at least one element + */ + private static Point getTopLeftPoint(final RadComponent[] components){ + LOG.assertTrue(components.length > 0); + + final Point point = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); + for (int i = 0; i < components.length; i++) { + final RadComponent component = components[i]; + point.x = Math.min(component.getX(), point.x); + point.y = Math.min(component.getY(), point.y); + } + + return point; + } + + /** + * Find bottom right point of component group, i.e. (maximum (x + width) of all components; maximum (y + height) of all components) + * @param components array should contain at least one element + */ + private static Point getBottomRightPoint(final RadComponent[] components){ + LOG.assertTrue(components.length > 0); + + final Point point = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); + for (int i = 0; i < components.length; i++) { + final RadComponent component = components[i]; + point.x = Math.max(component.getX() + component.getWidth(), point.x); + point.y = Math.max(component.getY() + component.getHeight(), point.y); + } + + return point; + } + + public static void clearSelection(final RadContainer container){ + container.setSelected(false); + + for (int i = 0; i < container.getComponentCount(); i++) { + final RadComponent c = container.getComponent(i); + if (c instanceof RadContainer) { + clearSelection((RadContainer)c); + } + else { + c.setSelected(false); + } + } + } + + /** + * Finds component with the specified id starting from the + * container. The method goes recursively through the hierarchy + * of components. Note, that if container itself has id + * then the method immediately retuns it. + */ + public static RadComponent findComponent(final RadComponent component, final String id) { + LOG.assertTrue(component != null); + LOG.assertTrue(id != null); + + if (id.equals(component.getId())) { + return component; + } + if (!(component instanceof RadContainer)) { + return null; + } + + final RadContainer uiContainer = (RadContainer)component; + for (int i=0; i < uiContainer.getComponentCount(); i++){ + final RadComponent found = findComponent(uiContainer.getComponent(i), id); + if (found != null){ + return found; + } + } + return null; + } + + public static PsiClass findClassToBind(final Module module, final String classToBindName) { + LOG.assertTrue(module != null); + LOG.assertTrue(classToBindName != null); + + return PsiManager.getInstance(module.getProject()).findClass( + classToBindName.replace('$','.'), + GlobalSearchScope.moduleScope(module) + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GlassLayer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GlassLayer.java new file mode 100644 index 00000000000..bc91e8abc16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GlassLayer.java @@ -0,0 +1,81 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.uiDesigner.actions.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class GlassLayer extends JComponent implements DataProvider{ + private final GuiEditor myEditor; + + public GlassLayer(final GuiEditor editor){ + myEditor = editor; + enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + + final MoveSelectionToRightAction moveSelectionToRightAction = new MoveSelectionToRightAction(myEditor); + moveSelectionToRightAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT).getShortcutSet(), + this + ); + + final MoveSelectionToLeftAction moveSelectionToLeftAction = new MoveSelectionToLeftAction(myEditor); + moveSelectionToLeftAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT).getShortcutSet(), + this + ); + + final MoveSelectionToUpAction moveSelectionToUpAction = new MoveSelectionToUpAction(myEditor); + moveSelectionToUpAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP).getShortcutSet(), + this + ); + + final MoveSelectionToDownAction moveSelectionToDownAction = new MoveSelectionToDownAction(myEditor); + moveSelectionToDownAction.registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN).getShortcutSet(), + this + ); + + // F2 should start inplace editing + final StartInplaceEditingAction startInplaceEditingAction = new StartInplaceEditingAction(editor); + startInplaceEditingAction.registerCustomShortcutSet( + new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), + this + ); + } + + protected void processKeyEvent(final KeyEvent e){ + myEditor.myProcessor.processKeyEvent(e); + } + + protected void processMouseEvent(final MouseEvent e){ + if(e.getID() == MouseEvent.MOUSE_PRESSED){ + requestFocusInWindow(); + } + myEditor.myProcessor.processMouseEvent(e); + } + + protected void processMouseMotionEvent(final MouseEvent e){ + myEditor.myProcessor.processMouseEvent(e); + } + + /** + * Provides {@link DataConstants#NAVIGATABLE} to navigate to + * binding of currently selected component (if any) + */ + public Object getData(final String dataId) { + if(DataConstants.NAVIGATABLE.equals(dataId)){ + return myEditor.getComponentTree().getData(dataId); + } + else{ + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GridChangeUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GridChangeUtil.java new file mode 100644 index 00000000000..d68ac4d287b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GridChangeUtil.java @@ -0,0 +1,231 @@ +package com.intellij.uiDesigner; + +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class GridChangeUtil { + public static void insertRowBefore(final RadContainer grid, final int rowIndex) { + insertRowOrColumn(grid, rowIndex, true, true); + } + + public static void insertRowAfter(final RadContainer grid, final int rowIndex) { + insertRowOrColumn(grid, rowIndex, true, false); + } + + public static void insertColumnBefore(final RadContainer grid, final int columnIndex) { + insertRowOrColumn(grid, columnIndex, false, true); + } + + public static void insertColumnAfter(final RadContainer grid, final int columnIndex) { + insertRowOrColumn(grid, columnIndex, false, false); + } + + public static void splitColumn(final RadContainer grid, final int columnIndex) { + splitCell(grid, columnIndex, false); + } + + public static void splitRow(final RadContainer grid, final int rowIndex) { + splitCell(grid, rowIndex, true); + } + + public static boolean canDeleteColumn(final RadContainer grid, final int columnIndex) { + return canDeleteCell(grid, columnIndex, false); + } + + public static void deleteColumn(final RadContainer grid, final int columnIndex) { + deleteCell(grid, columnIndex, false); + } + + public static boolean canDeleteRow(final RadContainer grid, final int rowIndex) { + return canDeleteCell(grid, rowIndex, true); + } + + public static void deleteRow(final RadContainer grid, final int rowIndex) { + deleteCell(grid, rowIndex, true); + } + + /** + * @param cellIndex column or row index, depending on isRow parameter; must be in the range 0..grid.get{Row|Column}Count()-1 + * @param isRow if true, row inserted, otherwise column + * @param isBefore if true, row/column will be inserted before row/column with given index, otherwise after + */ + private static void insertRowOrColumn(final RadContainer grid, final int cellIndex, final boolean isRow, final boolean isBefore) { + check(grid, isRow, cellIndex); + + final GridLayoutManager oldLayout = (GridLayoutManager)grid.getLayout(); + + int beforeIndex = cellIndex; + if (!isBefore) { + // beforeIndex can actually be equal to get{Row|Column}Count an case we add row after the last row/column + beforeIndex++; + } + + final GridLayoutManager newLayout = copyLayout(oldLayout, isRow ? 1 : 0, isRow ? 0 : 1); + + for (int i=grid.getComponentCount() - 1; i >= 0; i--){ + final GridConstraints constraints = grid.getComponent(i).getConstraints(); + + if (getCell(constraints, isRow) >= beforeIndex) { + addToCell(constraints, isRow, 1); + } + else if (isCellInsideComponent(constraints, isRow, beforeIndex)) { + // component belongs to the cell being resized - increment component's span + addToSpan(constraints, isRow, 1); + } + } + + grid.setLayout(newLayout); + } + + /** + * @param cellIndex column or row index, depending on isRow parameter; must be in the range 0..grid.get{Row|Column}Count()-1 + * @param isRow if true, row is splitted, otherwise column + */ + private static void splitCell(final RadContainer grid, final int cellIndex, final boolean isRow) { + check(grid, isRow, cellIndex); + + final GridLayoutManager oldLayout = (GridLayoutManager)grid.getLayout(); + + final GridLayoutManager newLayout = copyLayout(oldLayout, isRow ? 1 : 0, isRow ? 0 : 1); + + for (int i=grid.getComponentCount() - 1; i >= 0; i--){ + final GridConstraints constraints = grid.getComponent(i).getConstraints(); + + if (getCell(constraints, isRow) > cellIndex) { + // component starts after the cell being splitted - move it + addToCell(constraints, isRow, 1); + } + else if (isCellInsideComponent(constraints, isRow, cellIndex)) { + // component belongs to the cell being resized - increment component's span + addToSpan(constraints, isRow, 1); + } + } + + grid.setLayout(newLayout); + } + + /** + * @param cellIndex column or row index, depending on isRow parameter; must be in the range 0..grid.get{Row|Column}Count()-1 + * @param isRow if true, row is deleted, otherwise column + * @return true if specified row/column can be deleted + */ + private static boolean canDeleteCell(final RadContainer grid, final int cellIndex, final boolean isRow) { + check(grid, isRow, cellIndex); + + // Do not allow to delete the single row/column + final GridLayoutManager layout = (GridLayoutManager)grid.getLayout(); + if(isRow && layout.getRowCount() < 2){ + return false; + } + else if(!isRow && layout.getColumnCount() < 2){ + return false; + } + + for (int i = 0; i < grid.getComponentCount(); i++) { + final GridConstraints constraints = grid.getComponent(i).getConstraints(); + final int cell = getCell(constraints, isRow); + final int span = getSpan(constraints, isRow); + + if (cell == cellIndex && span == 1) { + // only cells where components with span 1 are located cannot be deleted + return false; + } + } + + return true; + } + + /** + * @param cellIndex column or row index, depending on isRow parameter; must be in the range 0..grid.get{Row|Column}Count()-1 + * @param isRow if true, row is deleted, otherwise column + */ + private static void deleteCell(final RadContainer grid, final int cellIndex, final boolean isRow) { + check(grid, isRow, cellIndex); + if (!canDeleteCell(grid, cellIndex, isRow)) { + throw new IllegalArgumentException("cell cannot be deleted"); + } + + final GridLayoutManager oldLayout = (GridLayoutManager)grid.getLayout(); + + final GridLayoutManager newLayout = copyLayout(oldLayout, isRow ? -1 : 0, isRow ? 0 : -1); + + for (int i=grid.getComponentCount() - 1; i >= 0; i--){ + final GridConstraints constraints = grid.getComponent(i).getConstraints(); + + if (getCell(constraints, isRow) > cellIndex) { + // component starts after the cell being deleted - move it + addToCell(constraints, isRow, -1); + } + else if (isCellInsideComponent(constraints, isRow, cellIndex)) { + // component belongs to the cell being deleted - decrement component's span + addToSpan(constraints, isRow, -1); + } + } + + grid.setLayout(newLayout); + } + + + private static boolean isCellInsideComponent(final GridConstraints constraints, final boolean isRow, final int cellIndex) { + final int cell = getCell(constraints, isRow); + final int span = getSpan(constraints, isRow); + return cell <= cellIndex && cellIndex <= cell + span - 1; + } + + /** + * check whether passed container is grid and cellIndex is in proper range + */ + private static void check(final RadContainer grid, final boolean isRow, final int cellIndex){ + if (grid == null){ + throw new IllegalArgumentException("grid cannot be null"); + } + if (!grid.isGrid()){ + throw new IllegalArgumentException("container must be grid"); + } + + final GridLayoutManager layout = (GridLayoutManager)grid.getLayout(); + + final int cellCount = isRow ? layout.getRowCount() : layout.getColumnCount(); + if (cellIndex < 0 || cellIndex >= cellCount) { + throw new IllegalArgumentException("invalid index: " + cellIndex); + } + } + + private static GridLayoutManager copyLayout(final GridLayoutManager oldLayout, final int rowDelta, final int columnDelta){ + final GridLayoutManager newLayout = new GridLayoutManager(oldLayout.getRowCount() + rowDelta, oldLayout.getColumnCount() + columnDelta); + newLayout.setMargin(oldLayout.getMargin()); + newLayout.setHGap(oldLayout.getHGap()); + newLayout.setVGap(oldLayout.getVGap()); + return newLayout; + } + + private static int getSpan(final GridConstraints constraints, final boolean isRow){ + return isRow ? constraints.getRowSpan() : constraints.getColSpan(); + } + + private static int getCell(final GridConstraints constraints, final boolean isRow){ + return isRow ? constraints.getRow() : constraints.getColumn(); + } + + private static void addToCell(final GridConstraints constraints, final boolean isRow, final int delta){ + if (isRow) { + constraints.setRow(constraints.getRow() + delta); + } + else { + constraints.setColumn(constraints.getColumn() + delta); + } + } + + private static void addToSpan(final GridConstraints constraints, final boolean isRow, final int delta){ + if (isRow) { + constraints.setRowSpan(constraints.getRowSpan() + delta); + } + else { + constraints.setColSpan(constraints.getColSpan() + delta); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GroupSelectionProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GroupSelectionProcessor.java new file mode 100644 index 00000000000..b4bd595eaf4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GroupSelectionProcessor.java @@ -0,0 +1,127 @@ +package com.intellij.uiDesigner; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class GroupSelectionProcessor extends EventProcessor{ + private final GuiEditor myEditor; + private final RadContainer myContainer; + private Point myStartPoint; + private final MyRectanglePainter myRectangePainter; + + /** + * @param container group where drag is started. This group should not be selected + * after drag is complete. + */ + public GroupSelectionProcessor(final GuiEditor editor,final RadContainer container){ + myEditor = editor; + myContainer = container; + myRectangePainter=new MyRectanglePainter(); + } + + protected void processKeyEvent(final KeyEvent e){ + } + + protected void processMouseEvent(final MouseEvent e){ + if (e.getID() == MouseEvent.MOUSE_PRESSED) { + myStartPoint = e.getPoint(); + myEditor.getDragLayer().add(myRectangePainter); + } + else if (e.getID() == MouseEvent.MOUSE_DRAGGED) { + final Rectangle rectangle = getRectangle(e); + myRectangePainter.setBounds(rectangle); + myEditor.getDragLayer().repaint(); + } + else if (e.getID() == MouseEvent.MOUSE_RELEASED) { + final Rectangle rectangle = getRectangle(e); + + markRectangle(myEditor.getRootContainer(), rectangle, e.getComponent()); + + final JComponent dragLayer = myEditor.getDragLayer(); + dragLayer.remove(myRectangePainter); + dragLayer.repaint(); + + myStartPoint = null; + } + } + + protected boolean cancelOperation(){ + final JComponent dragLayer = myEditor.getDragLayer(); + dragLayer.remove(myRectangePainter); + dragLayer.repaint(); + return true; + } + + private Rectangle getRectangle(final MouseEvent e){ + final int x = Math.min(myStartPoint.x, e.getX()); + final int y = Math.min(myStartPoint.y, e.getY()); + + final int width = Math.abs(myStartPoint.x - e.getX()); + final int height = Math.abs(myStartPoint.y - e.getY()); + + return new Rectangle(x, y, width, height); + } + + private void markRectangle( + final RadComponent component, + final Rectangle rectangle, + final Component coordinateOriginComponent + ){ + if (!(component instanceof RadRootContainer) && !component.equals(myContainer)) { + final Rectangle bounds = component.getBounds(); + final Point point = SwingUtilities.convertPoint(component.getDelegee().getParent(), bounds.x, bounds.y, coordinateOriginComponent); + bounds.setLocation(point); + + if(rectangle.intersects(bounds)){ + component.setSelected(true); + return; + } + } + + if (component instanceof RadContainer){ + final RadContainer container = (RadContainer)component; + // [anton] it is very important to iterate through a STORED array because setSelected can + // change order of components so iteration via getComponent(i) is incorrect + final RadComponent[] components = container.getComponents(); + for (int i = 0; i < components.length; i++) { + markRectangle(components[i], rectangle, coordinateOriginComponent); + } + } + } + + private static final class MyRectanglePainter extends JComponent{ + private final AlphaComposite myComposite1; + private final AlphaComposite myComposite2; + private final Color myColor; + + + public MyRectanglePainter() { + myComposite1 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f); + myComposite2 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.6f); + myColor = new Color(47, 67, 96); + } + + protected void paintComponent(final Graphics g){ + final Graphics2D g2d = (Graphics2D)g; + super.paintComponent(g); + final Composite oldComposite = g2d.getComposite(); + final Color oldColor = g2d.getColor(); + g2d.setColor(myColor); + + g2d.setComposite(myComposite1); + g2d.fillRect(0, 0, getWidth(), getHeight()); + + g2d.setComposite(myComposite2); + g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1); + + g2d.setColor(oldColor); + g2d.setComposite(oldComposite); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfigurable.java new file mode 100644 index 00000000000..9589dd765e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfigurable.java @@ -0,0 +1,814 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.DispatchThreadProgressWindow; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.make.FormSourceCodeGenerator; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.ComponentItemDialog; +import com.intellij.uiDesigner.palette.GroupItem; +import com.intellij.uiDesigner.palette.Palette; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class GuiDesignerConfigurable implements Configurable, ProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.GuiDesignerConfigurable"); + + private final Project myProject; + private MyGeneralUI myGeneralUI; + private MyPaletteUI myPaletteUI; + + /** Invoked by reflection */ + GuiDesignerConfigurable(final Project project) { + myProject = project; + } + + public void projectOpened() {} + + public void projectClosed() {} + + public String getComponentName() { + return "uidesigner-configurable"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public String getDisplayName() { + return "GUI Designer"; + } + + public Icon getIcon() { + return IconLoader.getIcon("/general/uiDesigner.png"); + } + + public String getHelpTopic() { + return "project.propGUI"; + } + + public JComponent createComponent() { + LOG.assertTrue(myGeneralUI == null); + LOG.assertTrue(myPaletteUI == null); + + myGeneralUI = new MyGeneralUI(); + myPaletteUI = new MyPaletteUI(); + + final TabbedPaneWrapper wrapper = new TabbedPaneWrapper(); + wrapper.addTab("General", myGeneralUI.myPanel); + wrapper.addTab("Palette", myPaletteUI.myPanel); + + return wrapper.getComponent(); + } + + private boolean isPalatteModified(){ + final ArrayList oldGroups = Palette.getInstance(myProject).getGroups(); + final ArrayList newGroups = getGroupsFromTree(); + + if (newGroups.size() != oldGroups.size()) { + return true; + } + + for (int i = 0; i < newGroups.size(); i++){ + final GroupItem _groupItem = newGroups.get(i); + + if (!_groupItem.getName().equals(oldGroups.get(i).getName())) { + return true; + } + + final ArrayList _items = _groupItem.getItems(); + final ArrayList items = oldGroups.get(i).getItems(); + + if (!items.equals(_items)) { + return true; + } + } + + return false; + } + + public boolean isModified() { + final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject); + + if (myGeneralUI.myChkCopyFormsRuntime.isSelected() != configuration.COPY_FORMS_RUNTIME_TO_OUTPUT) { + return true; + } + + if (configuration.INSTRUMENT_CLASSES != myGeneralUI.myRbInstrumentClasses.isSelected()) { + return true; + } + + // compare palettes + if(isPalatteModified()){ + return true; + } + + return false; + } + + private static boolean isRemovable(final GroupItem group){ + LOG.assertTrue(group != null); + + final ArrayList items = group.getItems(); + for(int i = items.size() - 1; i >=0; i--){ + if(!items.get(i).isRemovable()){ + return false; + } + } + return true; + } + + public void apply() { + final DispatchThreadProgressWindow progressWindow = new DispatchThreadProgressWindow(false, myProject); + progressWindow.setTitle("Converting project..."); + progressWindow.start(); + + GuiDesignerConfiguration.getInstance(myProject).COPY_FORMS_RUNTIME_TO_OUTPUT = myGeneralUI.myChkCopyFormsRuntime.isSelected(); + + // We have to store value of the radio button here because myGeneralUI will be cleared + // just after apply is invoked (applyImpl is invoked later) + final boolean instrumentClasses = myGeneralUI.myRbInstrumentClasses.isSelected(); + ApplicationManager.getApplication().invokeLater(new MyApplyRunnable(progressWindow, instrumentClasses), progressWindow.getModalityState()); + + /*Set new palette if it was modified*/ + if(isPalatteModified()){ + final ArrayList groupList = getGroupsFromTree(); + final ArrayList clonedGroupList = new ArrayList(); + for(int i = 0; i < groupList.size(); i++){ + // We have to clone GroupItem here becouse after applying changes user can continue + // editing of palette (and "Cancel" button should work) + clonedGroupList.add(groupList.get(i).clone()); + } + + /*apply changes*/ + Palette.getInstance(myProject).setGroups(clonedGroupList); + } + } + + public void reset() { + final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject); + + /*general*/ + if (configuration.INSTRUMENT_CLASSES) { + myGeneralUI.myRbInstrumentClasses.setSelected(true); + } + else { + myGeneralUI.myRbInstrumentSources.setSelected(true); + } + myGeneralUI.myChkCopyFormsRuntime.setSelected(configuration.COPY_FORMS_RUNTIME_TO_OUTPUT); + + /*palette*/ + final DefaultTreeModel model = buildModel(Palette.getInstance(myProject)); + myPaletteUI.myTree.setModel(model); + myPaletteUI.myTree.setCellRenderer(new MyTreeCellRenderer()); + + // a. Expand and preselect first group + final DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot(); + LOG.assertTrue(root.getChildCount() >= 1); // there should be at least on group + final TreePath path = new TreePath(new Object[]{root, root.getChildAt(0)}); + myPaletteUI.myTree.expandPath(path); + myPaletteUI.myTree.setSelectionPath(path); + } + + public void disposeUIResources() { + myGeneralUI = null; + myPaletteUI = null; + } + + /** Helper method.*/ + private static DefaultMutableTreeNode buildNodeForComponent(final ComponentItem item){ + LOG.assertTrue(item != null); + final DefaultMutableTreeNode node = new DefaultMutableTreeNode(item); + return node; + } + + /** Helper method.*/ + private static DefaultMutableTreeNode buildNodeForGroup(final GroupItem groupItem){ + LOG.assertTrue(groupItem != null); + + final GroupItem _groupItem = groupItem.clone(); + final DefaultMutableTreeNode result = new DefaultMutableTreeNode(_groupItem); + final ArrayList items = _groupItem.getItems(); + for(int i = 0; i < items.size(); i++){ + final DefaultMutableTreeNode node = buildNodeForComponent(items.get(i)); + result.add(node); + } + + return result; + } + + /** + * @return list of all groups from the tree. Returned groups have the same order as in the tree. + */ + private ArrayList getGroupsFromTree(){ + final ArrayList result = new ArrayList(); + final DefaultMutableTreeNode root = (DefaultMutableTreeNode)myPaletteUI.myTree.getModel().getRoot(); + for(int i = 0; i < root.getChildCount(); i++){ + final DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)root.getChildAt(i); + final GroupItem group = (GroupItem)groupNode.getUserObject(); + result.add(group); + } + return result; + } + + /** Helper method.*/ + private static DefaultTreeModel buildModel(final Palette palette){ + LOG.assertTrue(palette != null); + + final DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + final ArrayList groups = palette.getGroups(); + for(int i = 0; i < groups.size(); i++){ + final DefaultMutableTreeNode node = buildNodeForGroup(groups.get(i)); + root.add(node); + } + + return new DefaultTreeModel(root); + } + + /** + * Creates and adds {@link GroupItem} just after the last selected {@link GroupItem} + */ + private void addGroupItem(){ + // Ask group name + final String groupName = Messages.showInputDialog( + myPaletteUI.myPanel, + "Enter a new group name:", + "Add Group", + Messages.getQuestionIcon() + ); + if(groupName == null){ + return; + } + + // Check that name of the group is unique + final ArrayList groups = getGroupsFromTree(); + for(int i = groups.size() - 1; i >= 0; i--){ + if(groupName.equals(groups.get(i).getName())){ + Messages.showErrorDialog(myPaletteUI.myPanel, "Group name should be unique", "Error"); + return; + } + } + + final GroupItem groupToBeAdded = new GroupItem(groupName); + final DefaultMutableTreeNode nodeToBeAdded = new DefaultMutableTreeNode(groupToBeAdded); + + final ArrayList expandedPaths = new ArrayList(); + TreeUtil.collectExpandedPaths(myPaletteUI.myTree, expandedPaths); + + // Add new group to the model + final DefaultTreeModel model = (DefaultTreeModel)myPaletteUI.myTree.getModel(); + final DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot(); + final DefaultMutableTreeNode lastSelectedNode = (DefaultMutableTreeNode)myPaletteUI.myTree.getLastSelectedPathComponent(); + if(lastSelectedNode != null){ + final DefaultMutableTreeNode selectedGroupNode; + if(lastSelectedNode.getUserObject() instanceof GroupItem){ + selectedGroupNode = lastSelectedNode; + } + else if(lastSelectedNode.getUserObject() instanceof ComponentItem){ + selectedGroupNode = (DefaultMutableTreeNode)lastSelectedNode.getParent(); + } + else{ + throw new RuntimeException("unknown userObject: " + lastSelectedNode.getUserObject()); + } + + final int index = root.getIndex(selectedGroupNode); + LOG.assertTrue(index != -1); + root.insert(nodeToBeAdded, index + 1); + } + else{ + // Add new group to the end + root.add(nodeToBeAdded); + } + + // Select and scroll to the added node + model.nodeStructureChanged(root); + TreeUtil.restoreExpandedPaths(myPaletteUI.myTree, expandedPaths); + TreeUtil.selectNode(myPaletteUI.myTree, nodeToBeAdded); + } + + /** + * @return currently TreeNode for selected {@link GroupItem}. If {@link ComponentItem} is currently selected + * then the method return parent node of of the selected item. + */ + private DefaultMutableTreeNode getSelectedGroupNode(){ + final DefaultMutableTreeNode lastSelectedNode = (DefaultMutableTreeNode)myPaletteUI.myTree.getLastSelectedPathComponent(); + if(lastSelectedNode == null){ + return null; + } + + final DefaultMutableTreeNode groupNode; + if(lastSelectedNode.getUserObject() instanceof GroupItem){ + groupNode = lastSelectedNode; + } + else{ + groupNode = (DefaultMutableTreeNode)lastSelectedNode.getParent(); + } + LOG.assertTrue(groupNode != null); + + return groupNode; + } + + private void editGroupItem(){ + final DefaultMutableTreeNode groupNode = getSelectedGroupNode(); + LOG.assertTrue(groupNode != null); + final GroupItem groupToBeEdited = (GroupItem)groupNode.getUserObject(); + + // Ask group name + final String groupName = Messages.showInputDialog( + myPaletteUI.myPanel, + "Enter a group name:", + "Edit Group", + Messages.getQuestionIcon(), + groupToBeEdited.getName(), + null + ); + if(groupName == null){ + return; + } + + // Check that group name is unique + final ArrayList groups = getGroupsFromTree(); + for(int i = groups.size() - 1; i >= 0; i--){ + if(groupName.equals(groups.get(i).getName())){ + Messages.showErrorDialog(myPaletteUI.myPanel, "Group name should be unique", "Error"); + return; + } + } + + // Update tree + groupToBeEdited.setName(groupName); + final DefaultTreeModel model = (DefaultTreeModel)myPaletteUI.myTree.getModel(); + model.nodeChanged(groupNode); + } + + private void removeGroupItem(){ + final DefaultMutableTreeNode groupNode = getSelectedGroupNode(); + LOG.assertTrue(groupNode != null); + final GroupItem groupToBeRemoved = (GroupItem)groupNode.getUserObject(); + + if(!isRemovable(groupToBeRemoved)){ + Messages.showInfoMessage( + myPaletteUI.myPanel, + "You cannot remove group that contains default palette component(s)", + "Error" + ); + return; + } + + // Remove group and try to restore selection + final ArrayList expandedPaths = new ArrayList(); + TreeUtil.collectExpandedPaths(myPaletteUI.myTree, expandedPaths); + TreeUtil.removeLastPathComponent( + myPaletteUI.myTree, + new TreePath(groupNode.getPath()) + ); + TreeUtil.restoreExpandedPaths(myPaletteUI.myTree, expandedPaths); + } + + /** + * Creates and adds {@link ComponentItem} to the currently selected {@link GroupItem} + */ + private void addComponentItem(){ + final TreePath path = myPaletteUI.myTree.getSelectionPath(); + final DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode)path.getLastPathComponent(); + LOG.assertTrue(lastPathComponent != null); + + // Determine group. #getUserObject() is a GroupItem + final DefaultMutableTreeNode groupNode; + + if(lastPathComponent.getUserObject() instanceof GroupItem){ + groupNode = lastPathComponent; + } + else { + final Object userObject = lastPathComponent.getUserObject(); + if(userObject instanceof ComponentItem){ + groupNode = (DefaultMutableTreeNode)lastPathComponent.getParent(); + } + else{ + throw new RuntimeException("unknown user object: " + lastPathComponent.getUserObject()); + } + } + + LOG.assertTrue(groupNode != null); + + // Show dialog + final ComponentItem itemToBeAdded = new ComponentItem( + "", + null, + null, + new GridConstraints(), + new HashMap(), + true/*all user defined components are removable*/ + ); + final ComponentItemDialog dialog = new ComponentItemDialog(myProject, myPaletteUI.myPanel, itemToBeAdded); + dialog.setTitle("Add Component"); + dialog.show(); + if(!dialog.isOK()){ + return; + } + + + final GroupItem groupItem = (GroupItem)groupNode.getUserObject(); + + // If the itemToBeAdded is already in palette do nothing + if(groupItem.containsItem(itemToBeAdded)){ + return; + } + + // add to the group + groupItem.addItem(itemToBeAdded); + + // add to the tree + final DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(itemToBeAdded); + groupNode.add(itemNode); + final DefaultTreeModel model = (DefaultTreeModel)myPaletteUI.myTree.getModel(); + model.nodeStructureChanged(groupNode); + TreeUtil.selectNode(myPaletteUI.myTree, itemNode); + } + + /** + * Edits properties of currently selected {@link ComponentItem}. This method should be called + * only when {@link ComponentItem} is selected in the tree. + */ + private void editComponentItem(){ + final DefaultMutableTreeNode lastNode = (DefaultMutableTreeNode)myPaletteUI.myTree.getLastSelectedPathComponent(); + final ComponentItem selectedItem = (ComponentItem)lastNode.getUserObject(); + LOG.assertTrue(selectedItem != null); + + /*Edit selected item*/ + final ComponentItem itemToBeEdited = selectedItem.clone(); /*"Cancel" should work, so we need edit copy*/ + final ComponentItemDialog dialog = new ComponentItemDialog(myProject, myPaletteUI.myPanel, itemToBeEdited); + dialog.setTitle("Edit Component"); + dialog.show(); + if(!dialog.isOK()){ + return; + } + + /*Replace selected item with the edited one*/ + final DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)lastNode.getParent(); + final GroupItem group = (GroupItem)groupNode.getUserObject(); + group.replaceItem(selectedItem, itemToBeEdited); + + lastNode.setUserObject(itemToBeEdited); + final DefaultTreeModel model = (DefaultTreeModel)myPaletteUI.myTree.getModel(); + model.nodeChanged(lastNode); + } + + /** + * Removed currently selected {@link ComponentItem}. This method should be called + * only when {@link ComponentItem} is selected in the tree. If item is not removable + * (belong to default palatte) the method shows warning dialog and does nothing. + */ + private void removeComponentItem(){ + final DefaultMutableTreeNode lastNode = (DefaultMutableTreeNode)myPaletteUI.myTree.getLastSelectedPathComponent(); + final ComponentItem selectedItem = (ComponentItem)lastNode.getUserObject(); + + LOG.assertTrue(selectedItem != null); + + if(!selectedItem.isRemovable()){ + Messages.showInfoMessage( + myPaletteUI.myPanel, + "You cannot remove default palette component", + "Error" + ); + return; + } + + final DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)lastNode.getParent(); + final GroupItem group = (GroupItem)groupNode.getUserObject(); + + group.removeItem(selectedItem); + TreeUtil.removeSelected(myPaletteUI.myTree); + } + + /*UI for "General" tab*/ + private static final class MyGeneralUI { + public JPanel myPanel; + public JRadioButton myRbInstrumentClasses; + public JRadioButton myRbInstrumentSources; + public JCheckBox myChkCopyFormsRuntime; + + public MyGeneralUI() { + final ButtonGroup group = new ButtonGroup(); + group.add(myRbInstrumentClasses); + group.add(myRbInstrumentSources); + } + } + + /*UI for "Palette" tab*/ + private final class MyPaletteUI{ + private JPanel myPanel; + private JTree myTree; + private JButton myBtnAddComponent; + private JButton myBtnEditComponent; + private JButton myBtnRemoveComponent; + private JButton myBtnAddGroup; + private JButton myBtnEditGroup; + private JButton myBtnRemoveGroup; + + public MyPaletteUI() { + final TreeSelectionModel selectionModel = myTree.getSelectionModel(); + selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + + selectionModel.addTreeSelectionListener( + new TreeSelectionListener() { + public void valueChanged(final TreeSelectionEvent e) { + updateButtonStates(); + } + } + ); + + myBtnAddGroup.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + addGroupItem(); + } + } + ); + + myBtnEditGroup.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + editGroupItem(); + } + } + ); + + myBtnRemoveGroup.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + removeGroupItem(); + } + } + ); + + myBtnAddComponent.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + addComponentItem(); + } + } + ); + + /*INSERT adds new component*/ + myPanel.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + if(isAddComponentButtonEnabled()){ + addComponentItem(); + } + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + + myBtnEditComponent.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + editComponentItem(); + } + } + ); + + /*Double click start editing of selected component*/ + myTree.addMouseListener( + new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + if(e.getClickCount() != 2){ + return; + } + + if(isEditComponentButtonEnabled()){ + editComponentItem(); + } + else if(isEditGroupButtonEnabled()){ + editGroupItem(); + } + + e.consume(); + } + } + ); + + myBtnRemoveComponent.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + removeComponentItem(); + } + } + ); + + /*DELETE remoeds selected component*/ + myPanel.registerKeyboardAction( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + if(isRemoveComponentButtonEnabled()){ + removeComponentItem(); + } + } + }, + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + } + + /*Helper method*/ + private boolean isAddComponentButtonEnabled(){ + final DefaultMutableTreeNode lastNode = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent(); + return lastNode != null; + } + + /*Helper method*/ + private boolean isEditGroupButtonEnabled(){ + return getSelectedGroupNode() != null; + } + + /*Helper method*/ + private boolean isRemoveGroupButtonEnabled(){ + return getSelectedGroupNode() != null; + } + + /*Helper method*/ + private boolean isEditComponentButtonEnabled(){ + final DefaultMutableTreeNode lastNode = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent(); + return lastNode != null && (lastNode.getUserObject() instanceof ComponentItem); + } + + /*Helper method*/ + private boolean isRemoveComponentButtonEnabled(){ + return isEditComponentButtonEnabled(); + } + + private void updateButtonStates(){ + myBtnEditGroup.setEnabled(isEditGroupButtonEnabled()); + myBtnRemoveGroup.setEnabled(isRemoveGroupButtonEnabled()); + + myBtnAddComponent.setEnabled(isAddComponentButtonEnabled()); + myBtnEditComponent.setEnabled(isEditComponentButtonEnabled()); + myBtnRemoveComponent.setEnabled(isRemoveComponentButtonEnabled()); + } + } + + private final class MyApplyRunnable implements Runnable { + private final DispatchThreadProgressWindow myProgressWindow; + private final boolean myInstrumentClasses; + + public MyApplyRunnable(final DispatchThreadProgressWindow progressWindow, final boolean instrumentClasses) { + myProgressWindow = progressWindow; + myInstrumentClasses = instrumentClasses; + } + + /** + * Removes all generated sources + */ + private void vanishGeneratedSources() { + final PsiShortNamesCache cache = PsiManager.getInstance(myProject).getShortNamesCache(); + final PsiMethod[] methods = cache.getMethodsByName(FormSourceCodeGenerator.METHOD_NAME, + GlobalSearchScope.projectScope(myProject)); + + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + final PsiClass aClass = method.getContainingClass(); + if (aClass != null) { + try { + final PsiFile psiFile = aClass.getContainingFile(); + LOG.assertTrue(psiFile != null); + final VirtualFile vFile = psiFile.getVirtualFile(); + LOG.assertTrue(vFile != null); + myProgressWindow.setText("Converting: " + vFile.getPresentableUrl()); + myProgressWindow.setFraction(((double)i) / ((double)methods.length)); + FormSourceCodeGenerator.cleanup(aClass); + } + catch (IncorrectOperationException e) { + e.printStackTrace(); + } + } + } + } + + /** + * Launches vanish/generate sources processes + */ + private void applyImpl(final boolean instrumentClasses) { + final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject); + configuration.INSTRUMENT_CLASSES = instrumentClasses; + + if (configuration.INSTRUMENT_CLASSES && !myProject.isDefault()) { + CommandProcessor.getInstance().executeCommand( + myProject, + new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + vanishGeneratedSources(); + } + } + ); + } + }, + "", + null + ); + } + } + + public void run() { + ProgressManager.getInstance().runProcess( + new Runnable() { + public void run() { + applyImpl(myInstrumentClasses); + } + }, + myProgressWindow + ); + } + } + + private static final class MyTreeCellRenderer extends ColoredTreeCellRenderer{ + private final SimpleTextAttributes myAttr; + private final SimpleTextAttributes myAttr2; + + public MyTreeCellRenderer() { + myAttr = SimpleTextAttributes.REGULAR_ATTRIBUTES; + myAttr2 = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.GRAY); + } + + public void customizeCellRenderer( + final JTree tree, + final Object value, + final boolean selected, + final boolean expanded, + final boolean leaf, + final int row, + final boolean hasFocus + ) { + LOG.assertTrue(value != null); + final Object obj = ((DefaultMutableTreeNode)value).getUserObject(); + + if(obj instanceof ComponentItem){ + final ComponentItem item = ((ComponentItem)obj); + setIcon(item.getSmallIcon()); + + final String className = item.getClassName(); + final int lastDotIndex = className.lastIndexOf('.'); + if (lastDotIndex != -1 && lastDotIndex != className.length() - 1/*not the last char in class name*/) { + append(className.substring(lastDotIndex + 1), myAttr); + append(" (" , myAttr2); + append(className.substring(0, lastDotIndex) , myAttr2); + append(")" , myAttr2); + } + else{ + append(className, myAttr); + } + } + else if(obj instanceof GroupItem){ + final GroupItem item = ((GroupItem)obj); + append(item.getName(), myAttr); + } + else if(obj == null/*root node*/){ + // do nothing + } + else{ + throw new RuntimeException("unknown object: " + obj); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfiguration.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfiguration.java new file mode 100644 index 00000000000..4c4cf76581d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiDesignerConfiguration.java @@ -0,0 +1,46 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +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 org.jdom.Element; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class GuiDesignerConfiguration implements ProjectComponent, JDOMExternalizable{ + public static GuiDesignerConfiguration getInstance(final Project project){ + return project.getComponent(GuiDesignerConfiguration.class); + } + + /** + * Defines how the designer generate UI (instrument classes or generate Java code) + */ + public boolean INSTRUMENT_CLASSES = true; + + public boolean COPY_FORMS_RUNTIME_TO_OUTPUT = true; + + public void projectOpened() {} + + public void projectClosed() {} + + public String getComponentName() { + return "uidesigner-configuration"; + } + + public void initComponent() {} + + public void disposeComponent() {} + + public void readExternal(final Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(final Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiEditor.java new file mode 100644 index 00000000000..ef6c1ccd801 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/GuiEditor.java @@ -0,0 +1,804 @@ +package com.intellij.uiDesigner; + +import com.intellij.ide.DeleteProvider; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; +import com.intellij.psi.*; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.componentTree.ComponentSelectionListener; +import com.intellij.uiDesigner.componentTree.ComponentTree; +import com.intellij.uiDesigner.componentTree.ComponentTreeBuilder; +import com.intellij.uiDesigner.core.Util; +import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.uiDesigner.palette.PalettePanel; +import com.intellij.uiDesigner.propertyInspector.PropertyInspector; +import com.intellij.util.Alarm; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.util.EventListener; + +/** + * GuiEditor is a panel with border layout. It has palette at the north, + * tree of component with property editor at the west and editor area at the center. + * This editor area contains internal component where user edit the UI. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class GuiEditor extends JPanel implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.GuiEditor"); + + private final Module myModule; + private final VirtualFile myFile; + + /** + * for debug purposes + */ + private Exception myWhere; + + /** + * All component are on this layer + */ + private static final Integer LAYER_COMPONENT = JLayeredPane.DEFAULT_LAYER; + /** + * This layer contains all "passive" decorators such as component boundaries + * and selection rectangle. + */ + private static final Integer LAYER_PASSIVE_DECORATION = JLayeredPane.POPUP_LAYER; + /** + * We show (and move) dragged component at this layer + */ + private static final Integer LAYER_DND = JLayeredPane.DRAG_LAYER; + /** + * This is the topmost layer. It gets and redispatch all incoming events + */ + private static final Integer LAYER_GLASS = new Integer(JLayeredPane.DRAG_LAYER.intValue() + 100); + /** + * This layer contains all "active" decorators. This layer should be over + * LAYER_GLASS because active decorators must get AWT events to work correctly. + */ + private static final Integer LAYER_ACTIVE_DECORATION = new Integer(LAYER_GLASS.intValue() + 100); + /** + * This layer contains all inplace editors. + */ + private static final Integer LAYER_INPLACE_EDITING = new Integer(LAYER_ACTIVE_DECORATION.intValue() + 100); + + private final EventListenerList myListenerList; + /** + * we have to store document here but not file because there can be a situation when + * document we added listener to has been disposed, and remove listener will be applied to + * a new document (got by file) -> assertion (see SCR 14143) + */ + private final Document myDocument; + + final MainProcessor myProcessor; + /** + * This layered pane contains all layers to lay components out and to + * show all necessary decoration items + */ + private final MyLayeredPane myLayeredPane; + /** + * The component which represents decoration layer. All passive + * decorators are on this layer. + */ + private final PassiveDecorationLayer myDecorationLayer; + /** + * The component which represents layer where located all dragged + * components + */ + private final DragLayer myDragLayer; + /** + * This layer contains all inplace editors + */ + private final InplaceEditingLayer myInplaceEditingLayer; + /** + * Brings functionality to "DEL" button + */ + private final MyDeleteProvider myDeleteProvider; + /** + * Rerun error analizer + */ + private final MyPsiTreeChangeListener myPsiTreeChangeListener; + + private RadRootContainer myRootContainer; + /** + * Panel with components palette. + */ + private final PalettePanel myPalettePanel; + /** + * GuiEditor should not react on own events. If myInsideChange + * is true then we do not react on incoming DocumentEvent. + */ + private boolean myInsideChange; + private final PropertyInspector myPropertyInspector; + private final ComponentTree myComponentTree; + private final DocumentAdapter myDocumentListener; + private final CardLayout myCardLayout; + + private final static String CARD_VALID = "valid"; + private final static String CARD_INVALID = "invalid"; + private final JPanel myValidCard; + private final JPanel myInvalidCard; + + private final CutCopyPasteSupport myCutCopyPasteSupport; + /** + * Implementation of Crtl+W and Ctrl+Shift+W behavior + */ + private final SelectionState mySelectionState; + private final GlassLayer myGlassLayer; + + /** + * @param file file to be edited + * @throws java.lang.IllegalArgumentException + * if the file + * is null or file is not falid PsiFile + */ + public GuiEditor(final Module module, final VirtualFile file) { + ApplicationManager.getApplication().assertIsDispatchThread(); + LOG.assertTrue(module != null); + LOG.assertTrue(file != null); + LOG.assertTrue(file.isValid()); + + myModule = module; + myFile = file; + + myCutCopyPasteSupport = new CutCopyPasteSupport(this); + + myCardLayout = new CardLayout(); + setLayout(myCardLayout); + + myValidCard = new JPanel(new BorderLayout()); + myInvalidCard = createInvalidCard(); + add(myValidCard, CARD_VALID); + add(myInvalidCard, CARD_INVALID); + + myListenerList = new EventListenerList(); + + myDecorationLayer = new PassiveDecorationLayer(this); + myDragLayer = new DragLayer(this); + + myLayeredPane = new MyLayeredPane(); + myInplaceEditingLayer = new InplaceEditingLayer(this); + myLayeredPane.add(myInplaceEditingLayer, LAYER_INPLACE_EDITING); + myLayeredPane.add(new ActiveDecorationLayer(this), LAYER_ACTIVE_DECORATION); + myGlassLayer = new GlassLayer(this); + myLayeredPane.add(myGlassLayer, LAYER_GLASS); + myLayeredPane.add(myDecorationLayer, LAYER_PASSIVE_DECORATION); + myLayeredPane.add(myDragLayer, LAYER_DND); + + // Ctrl+W / Ctrl+Shift+W support + mySelectionState = new SelectionState(this); + + // DeleteProvider + myDeleteProvider = new MyDeleteProvider(); + + // We need to synchronize GUI editor with the document + final Alarm alarm = new Alarm(); + final Runnable request = new Runnable() { + public void run() { + PsiDocumentManager.getInstance(module.getProject()).commitDocument(myDocument); + readFromFile(); + } + }; + myDocumentListener = new DocumentAdapter() { + public void documentChanged(final DocumentEvent e) { + if (!myInsideChange) { + alarm.cancelAllRequests(); + alarm.addRequest(request, 100/*any arbitrary delay*/); + } + } + }; + + // Prepare document + myDocument = FileDocumentManager.getInstance().getDocument(file); + myDocument.addDocumentListener(myDocumentListener); + + // Read form from file + readFromFile(); + + // Tree with component hierarchy and property editor at the left + // It's important that ComponentTree is initializing after the + // RadRootContainer is set. + myComponentTree = new ComponentTree(this); + new ComponentTreeBuilder(myComponentTree, this); + final JScrollPane scrollPane = new JScrollPane(myComponentTree); + scrollPane.setPreferredSize(new Dimension(250, -1)); + + // Splitter with hierarchy and inspector + final Splitter splitter1 = new Splitter(true, 0.33f); + splitter1.setFirstComponent(scrollPane); + myPropertyInspector = new PropertyInspector(this, myComponentTree); + splitter1.setSecondComponent(myPropertyInspector); + + final Splitter splitter2 = new Splitter(false, 0.33f); + splitter2.setFirstComponent(splitter1); + + final JPanel mainPaneAndToolbar = new JPanel(new BorderLayout()); + mainPaneAndToolbar.add(new JScrollPane(myLayeredPane), BorderLayout.CENTER); + + splitter2.setSecondComponent(mainPaneAndToolbar); + myValidCard.add(splitter2, BorderLayout.CENTER); + + final CancelCurrentOperationAction cancelCurrentOperationAction = new CancelCurrentOperationAction(); + cancelCurrentOperationAction.registerCustomShortcutSet(CommonShortcuts.ESCAPE, this); + + // Palette at the top + // It is important to create palette toolbar after root container has been loaded + myPalettePanel = new PalettePanel(this); + mainPaneAndToolbar.add(myPalettePanel, BorderLayout.NORTH); + myProcessor = new MainProcessor(this); + + // PSI listener to restart error highlighter + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + PsiManager.getInstance(module.getProject()).addPsiTreeChangeListener(myPsiTreeChangeListener); + } + + /** + * @return never null. + */ + public SelectionState getSelectionState() { + return mySelectionState; + } + + public void dispose() { + ApplicationManager.getApplication().assertIsDispatchThread(); + + if (myWhere != null) { + LOG.error("Already disposed: old trace: ", myWhere); + LOG.error("Already disposed: new trace: "); + } + else { + myWhere = new Exception(); + } + + myDocument.removeDocumentListener(myDocumentListener); + PsiManager.getInstance(myModule.getProject()).removePsiTreeChangeListener(myPsiTreeChangeListener); + myPsiTreeChangeListener.dispose(); + } + + /** + * @return never null + */ + public Project getProject() { + return myModule.getProject(); + } + + /** + * @return never null + */ + public Module getModule() { + return myModule; + } + + /** + * @return never null + */ + public VirtualFile getFile() { + return myFile; + } + + public boolean isEditable() { + final Document document = FileDocumentManager.getInstance().getDocument(myFile); + return document != null && document.isWritable(); + } + + public void refresh() { + refreshImpl(myRootContainer); + myRootContainer.getDelegee().revalidate(); + repaintLayeredPane(); + + // Collect errors + ErrorAnalizer.analyzeErrors(this, myRootContainer); + } + + public void refreshAndSave(final boolean forceSync) { + // Update property inspector + if (myPropertyInspector != null) { // null when we invoke refresh from constructor + myPropertyInspector.synchWithTree(forceSync); + } + + refresh(); + saveToFile(); + } + + /** + * Refresh error markers in all components + */ + public void refreshErrors() { + // Collect errors + ErrorAnalizer.analyzeErrors(GuiEditor.this, myRootContainer); + if (isShowing()) { + // ComponentTree + myComponentTree.hideIntentionHint(); + myComponentTree.updateIntentionHintVisibility(); + myComponentTree.repaint(myComponentTree.getVisibleRect()); + + // PropertyInspector + myPropertyInspector.hideIntentionHint(); + myPropertyInspector.updateIntentionHintVisibility(); + myPropertyInspector.repaint(myPropertyInspector.getVisibleRect()); + } + } + + private void refreshImpl(final RadComponent component) { + if (component.getParent() != null) { + final Dimension size = component.getSize(); + final int oldWidth = size.width; + final int oldHeight = size.height; + Util.adjustSize(component.getDelegee(), component.getConstraints(), size); + + if (oldWidth != size.width || oldHeight != size.height) { + if (component.getParent().isXY()) { + component.setSize(size); + } + component.getDelegee().invalidate(); + } + } + + if (component instanceof RadContainer) { + final RadContainer container = (RadContainer)component; + for (int i = container.getComponentCount() - 1; i >= 0; i--) { + refreshImpl(container.getComponent(i)); + } + } + } + + public Object getData(final String dataId) { + // Standard Swing cut/copy/paste actions should work if user is editing something inside property inspector + if (myPropertyInspector.isEditing()) { + return null; + } + + if (DataConstantsEx.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + return myDeleteProvider; + } + + if ( + DataConstantsEx.COPY_PROVIDER.equals(dataId) || + DataConstantsEx.CUT_PROVIDER.equals(dataId) || + DataConstantsEx.PASTE_PROVIDER.equals(dataId) + ) { + return myCutCopyPasteSupport; + } + + return null; + } + + private JPanel createInvalidCard() { + final JPanel panel = new JPanel(new GridBagLayout()); + panel.add(new JLabel("Form file is invalid"), + new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + return panel; + } + + /** + * @return the component which represents DnD layer. All currently + * dragged (moved) component are on this layer. + */ + public DragLayer getDragLayer() { + return myDragLayer; + } + + /** + * @return the topmost UiConainer which in the root of + * component hierarchy. This method never returns null. + */ + public RadRootContainer getRootContainer() { + return myRootContainer; + } + + /** + * Fires event that selection changes + */ + public void fireSelectedComponentChanged() { + final EventListener[] listeners = myListenerList.getListeners(ComponentSelectionListener.class); + for (int i = 0; i < listeners.length; i++) { + final ComponentSelectionListener l = (ComponentSelectionListener)listeners[i]; + l.selectedComponentChanged(this); + } + } + + private void fireHierarchyChanged() { + final EventListener[] listeners = myListenerList.getListeners(HierarchyChangeListener.class); + for (int i = 0; i < listeners.length; i++) { + final HierarchyChangeListener listener = (HierarchyChangeListener)listeners[i]; + listener.hierarchyChanged(); + } + } + + /** + * @return never null. + */ + GlassLayer getGlassLayer() { + return myGlassLayer; + } + + /** + * @return the component which represents layer with active decorators + * such as grid edit controls, inplace editors, etc. + */ + public InplaceEditingLayer getInplaceEditingLayer() { + return myInplaceEditingLayer; + } + + /** + * @return never null + */ + public JLayeredPane getLayeredPane() { + return myLayeredPane; + } + + public void repaintLayeredPane() { + myLayeredPane.repaint(); + } + + /** + * Adds specified selection listener. This listener gets notification each time + * the selection in the component the changes. + */ + public void addComponentSelectionListener(final ComponentSelectionListener l) { + myListenerList.add(ComponentSelectionListener.class, l); + } + + /** + * Removes specified selection listener + */ + public void removeComponentSelectionLsistener(final ComponentSelectionListener l) { + myListenerList.remove(ComponentSelectionListener.class, l); + } + + /** + * Adds specified hierarchy change listener + */ + public void addHierarchyChangleListener(final HierarchyChangeListener l) { + LOG.assertTrue(l != null); + myListenerList.add(HierarchyChangeListener.class, l); + } + + /** + * Removes specified hierarchy change listener + */ + public void removeHierarchyChangeListener(final HierarchyChangeListener l) { + LOG.assertTrue(l != null); + myListenerList.remove(HierarchyChangeListener.class, l); + } + + private void saveToFile() { + CommandProcessor.getInstance().executeCommand(myModule.getProject(), new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myInsideChange = true; + try { + final XmlWriter writer = new XmlWriter(); + getRootContainer().write(writer); + final String newText = writer.getText(); + final String oldText = myDocument.getText(); + + try { + final ReplaceInfo replaceInfo = findFragmentToChange(oldText, newText); + if (replaceInfo.getStartOffset() == -1) { + // do nothing - texts are equal + } + else { + myDocument.replaceString(replaceInfo.getStartOffset(), replaceInfo.getEndOffset(), replaceInfo.getReplacement()); + } + } + catch (Exception e) { + LOG.error(e); + myDocument.replaceString(0, oldText.length(), newText); + } + } + finally { + myInsideChange = false; + } + } + }); + } + }, null, null); + + fireHierarchyChanged(); + } + + public static final class ReplaceInfo { + private final int myStartOffset; + private final int myEndOffset; + private final String myReplacement; + + public ReplaceInfo(final int startOffset, final int endOffset, final String replacement) { + myStartOffset = startOffset; + myEndOffset = endOffset; + myReplacement = replacement; + } + + public int getStartOffset() { + return myStartOffset; + } + + public int getEndOffset() { + return myEndOffset; + } + + public String getReplacement() { + return myReplacement; + } + } + + public static ReplaceInfo findFragmentToChange(final String oldText, final String newText) { + if (oldText.equals(newText)) { + return new ReplaceInfo(-1, -1, null); + } + + final int oldLength = oldText.length(); + final int newLength = newText.length(); + + int startOffset = 0; + while ( + startOffset < oldLength && startOffset < newLength && + oldText.charAt(startOffset) == newText.charAt(startOffset) + ) { + startOffset++; + } + + int endOffset = oldLength; + for (; ;) { + if (endOffset <= startOffset) { + break; + } + final int idxInNew = newLength - (oldLength - endOffset) - 1; + if (idxInNew < startOffset) { + break; + } + + final char c1 = oldText.charAt(endOffset - 1); + final char c2 = newText.charAt(idxInNew); + if (c1 != c2) { + break; + } + endOffset--; + } + + return new ReplaceInfo(startOffset, endOffset, newText.substring(startOffset, newLength - (oldLength - endOffset))); + } + + /** + * @param rootContainer new container to be set as a root. + * @throws java.lang.IllegalArgumentException + * if rootContainer + * is null. + */ + private void setRootContainer(final RadRootContainer rootContainer) { + if (rootContainer == null) { + throw new IllegalArgumentException(); + } + if (myRootContainer != null) { + myLayeredPane.remove(myRootContainer.getDelegee()); + } + myRootContainer = rootContainer; + myLayeredPane.add(myRootContainer.getDelegee(), LAYER_COMPONENT); + + fireHierarchyChanged(); + } + + /** + * Creates and sets new RadRootContainer + */ + private void readFromFile() { + try { + final String text = myDocument.getText(); + + final ClassLoader classLoader = LoaderFactory.getInstance(myModule.getProject()).getLoader(myFile); + + final LwRootContainer rootContainer = Utils.getRootContainer(text, new CompiledClassPropertiesProvider(classLoader)); + final RadRootContainer container = XmlReader.createRoot(myModule, rootContainer, classLoader); + setRootContainer(container); + myCardLayout.show(this, CARD_VALID); + refresh(); + } + catch (final Exception exc) { + LOG.info(exc); + exc.printStackTrace(); + // setting fictive container + setRootContainer(new RadRootContainer(myModule, JPanel.class, "0")); + myCardLayout.show(this, CARD_INVALID); + repaint(); + } + } + + public JComponent getPreferredFocusedComponent() { + if (myValidCard.isVisible()) { + return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myValidCard); + } + else { + return myInvalidCard; + } + } + + /** + * @return never null. + */ + public PalettePanel getPalettePanel() { + return myPalettePanel; + } + + /** + * @return never null. + */ + public ComponentTree getComponentTree() { + return myComponentTree; + } + + /** + * @return never null. + */ + public PropertyInspector getPropertyInspector() { + return myPropertyInspector; + } + + /** + * @return id + */ + public String generateId() { + while (true) { + final String id = Integer.toString((int)(Math.random() * 1024 * 1024), 16); + if (!idAlreadyExist(id, getRootContainer())) { + return id; + } + } + } + + private static boolean idAlreadyExist(final String id, final RadComponent component) { + if (id.equals(component.getId())) { + return true; + } + if (component instanceof RadContainer) { + final RadContainer container = (RadContainer)component; + for (int i = 0; i < container.getComponentCount(); i++) { + if (idAlreadyExist(id, container.getComponent(i))) { + return true; + } + } + } + return false; + } + + public static void repaintLayeredPane(final RadComponent component) { + final GuiEditor uiEditor = (GuiEditor)SwingUtilities.getAncestorOfClass(GuiEditor.class, component.getDelegee()); + if (uiEditor != null) { + uiEditor.repaintLayeredPane(); + } + } + + private final class MyLayeredPane extends JLayeredPane { + /** + * All components allocate whole pane's area. + */ + public void doLayout() { + for (int i = getComponentCount() - 1; i >= 0; i--) { + final Component component = getComponent(i); + component.setBounds(0, 0, getWidth(), getHeight()); + } + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getPreferredSize() { + // make sure all components fit + int width = 0; + int height = 0; + for (int i = 0; i < myRootContainer.getComponentCount(); i++) { + final RadComponent component = myRootContainer.getComponent(i); + width = Math.max(width, component.getX() + component.getWidth()); + height = Math.max(height, component.getY() + component.getHeight()); + } + + width += 30; + height += 30; + + return new Dimension(width, height); + } + } + + /** + * Action works only if we are not editing something in the property inspector + */ + private final class CancelCurrentOperationAction extends AnAction { + public void actionPerformed(final AnActionEvent e) { + myProcessor.cancelOperation(); + } + + public void update(final AnActionEvent e) { + e.getPresentation().setEnabled(!myPropertyInspector.isEditing()); + } + } + + /** + * Allows "DEL" button to work through the standard mechanism + */ + private final class MyDeleteProvider implements DeleteProvider { + public void deleteElement(final DataContext dataContext) { + FormEditingUtil.deleteSelection(GuiEditor.this); + } + + public boolean canDeleteElement(final DataContext dataContext) { + return + isEditable() && + !myPropertyInspector.isEditing() && + !myInplaceEditingLayer.isEditing() && + FormEditingUtil.canDeleteSelection(GuiEditor.this); + } + } + + /** + * Listens PSI event and update error highlighting in the UI editor + */ + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter implements Runnable { + private final Alarm myAlarm; + + public MyPsiTreeChangeListener() { + myAlarm = new Alarm(); + } + + /** + * Cancels all pending update requests. You have to cancel all pending requests + * to not access to closed project. + */ + public void dispose() { + myAlarm.cancelAllRequests(); + } + + public void childAdded(final PsiTreeChangeEvent event) { + handleEvent(); + } + + public void childMoved(final PsiTreeChangeEvent event) { + handleEvent(); + } + + public void childrenChanged(final PsiTreeChangeEvent event) { + handleEvent(); + } + + public void propertyChanged(final PsiTreeChangeEvent event) { + if (PsiTreeChangeEvent.PROP_ROOTS.equals(event.getPropertyName())) { + handleEvent(); + } + } + + private void handleEvent() { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(this, 2500); + } + + /** + * Restarts error analyzer + */ + public void run() { + final String classToBind = myRootContainer.getClassToBind(); + if (classToBind == null) { + return; + } + final PsiClass aClass = FormEditingUtil.findClassToBind(myModule, classToBind); + if (aClass != null) { + refreshErrors(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/HSpacer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/HSpacer.java new file mode 100644 index 00000000000..e272c35bb54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/HSpacer.java @@ -0,0 +1,91 @@ +package com.intellij.uiDesigner; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class HSpacer extends DesignSpacer{ + public HSpacer(){ + setSize(50,getHandleHeight()); + } + + protected void paintComponent(final Graphics g){ + final int handleHeight=getHandleHeight(); + final int handleWidth=getHandleWidth(); + + // Paint left handle + final int y=(getHeight()-handleHeight)/2; + drawHandle(g,0,y); + g.setColor(ourColor1); + g.drawLine(handleWidth,y+handleHeight/2,handleWidth+1,y+handleHeight/2); + + // Paint right handle + final int x=getWidth()-handleWidth-1; + drawHandle(g,x,y); + g.drawLine(x,y+handleHeight/2,x-2,y+handleHeight/2); + g.setColor(ourColor1); + + // Draw spring + drawSpring(g,handleWidth+1,y+handleHeight/2,getWidth()-2*handleWidth-4); + } + + private static int getHandleWidth(){ + return HANDLE_ATOM_WIDTH; + } + + private static int getHandleHeight(){ + return HANDLE_ATOM_HEIGHT*3 + HANDLE_ATOM_SPACE*2; + } + + /** + * Paints small spacer's haldle. (x,y) is a top + * left point of a handle. + */ + private static void drawHandle(final Graphics g,final int x,int y){ + g.setColor(ourColor1); + + g.drawRect(x,y,HANDLE_ATOM_WIDTH-1,HANDLE_ATOM_HEIGHT-1); + g.drawLine( + x+HANDLE_ATOM_WIDTH/2, + y+HANDLE_ATOM_HEIGHT, + x+HANDLE_ATOM_WIDTH/2, + y+HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE-1 + ); + + y+=HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE; + + g.drawRect(x,y,HANDLE_ATOM_WIDTH-1,HANDLE_ATOM_HEIGHT-1); + g.drawLine( + x+HANDLE_ATOM_WIDTH/2, + y+HANDLE_ATOM_HEIGHT, + x+HANDLE_ATOM_WIDTH/2, + y+HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE-1 + ); + + y+=HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE; + + g.drawRect(x,y,HANDLE_ATOM_WIDTH-1,HANDLE_ATOM_HEIGHT-1); + } + + private static void drawSpring(final Graphics g,final int x,final int y,final int width){ + for(int _x=x;_xtrue
    then we do not have to react on own events + */ + private boolean myInsideChange; + + public InplaceEditingLayer(final GuiEditor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + myEditor = editor; + myEditor.addComponentSelectionListener(new MyComponentSelectionListener()); + myFocusWatcher = new MyFocusWatcher(); + myPropertyEditorListener = new MyPropertyEditorListener(); + } + + /** + * This is optimization. We do not need to invalidate Swing hierarchy + * upper than InplaceEditingLayer. + */ + public boolean isValidateRoot() { + return true; + } + + /** + * When there is an inplace editor we "listen" all mouse event + * and finish editing by any MOUSE_PRESSED or MOUSE_RELEASED event. + * We are acting like yet another glass pane over the standard glass layer. + */ + protected void processMouseEvent(final MouseEvent e) { + if( + myInplaceComponent != null && + (MouseEvent.MOUSE_PRESSED == e.getID() || MouseEvent.MOUSE_RELEASED == e.getID()) + ){ + finishInplaceEditing(); + } + // [vova] this is very important! Without this code Swing doen't close popup menu on our + // layered pane. Swing adds MouseListeners to all component to close popup. If we do not + // invoke super then we lock all mouse listeners. + super.processMouseEvent(e); + } + + /** + * @return whether the layer is in "editing" state or not + */ + boolean isEditing(){ + return myInplaceComponent != null; + } + + /** + * Starts editing of "inplace" property for the component at the + * specified point (x, y). + * + * @param x x coordinate in the editor coordinate system + * @param y y coordinate in the editor coordinate system + */ + public void startInplaceEditing(final int x, final int y){ + final RadComponent inplaceComponent = FormEditingUtil.getRadComponentAt(myEditor, x, y); + if(inplaceComponent == null){ // nothing to edit + return; + } + + // Try to find property with inplace editor + final Point p = SwingUtilities.convertPoint(this, x, y, inplaceComponent.getDelegee()); + myInplaceProperty = inplaceComponent.getInplaceProperty(p.x, p.y); + if(myInplaceProperty == null){ + return; + } + + // Now we have to cancel previous inplace editing (if any) + + // Start new inplace editing + myInplaceComponent = inplaceComponent; + myInplaceEditor = myInplaceProperty.getEditor(); + LOG.assertTrue(myInplaceEditor != null); + + // 1. Get editor component + myInplaceEditorComponent = myInplaceEditor.getComponent( + myInplaceComponent, + myInplaceProperty.getValue(myInplaceComponent), + true + ); + LOG.assertTrue(myInplaceEditorComponent != null); + myInplaceEditor.addPropertyEditorListener(myPropertyEditorListener); + + // 2. Set editor component bounds + final Rectangle bounds = myInplaceComponent.getInplaceEditorBounds(myInplaceProperty, p.x, p.y); + final Dimension prefSize = myInplaceEditorComponent.getPreferredSize(); + if(bounds != null){ // use bounds provided by the component itself + final Point _p = SwingUtilities.convertPoint(myInplaceComponent.getDelegee(), bounds.x, bounds.y, this); + myPreferredBounds = new Rectangle(_p.x, _p.y, bounds.width, bounds.height); + } + else{ // set some default bounds + final Point _p = SwingUtilities.convertPoint(myInplaceComponent.getDelegee(), 0, 0, this); + myPreferredBounds = new Rectangle(_p.x, _p.y, myInplaceComponent.getWidth(), myInplaceComponent.getHeight()); + } + myInplaceEditorComponent.setBounds( + myPreferredBounds.x, + myPreferredBounds.y + (myPreferredBounds.height - prefSize.height)/2, + Math.min(Math.max(prefSize.width, myPreferredBounds.width), getWidth() - myPreferredBounds.x), + prefSize.height + ); + + // 3. Add it into layer + add(myInplaceEditorComponent); + myInplaceEditorComponent.revalidate(); + myInplaceEditorComponent.requestFocusInWindow(); + + // 4. Request focus into proper component + JComponent componentToFocus = myInplaceEditor.getPreferredFocusedComponent(myInplaceEditorComponent); + if(componentToFocus == null){ + componentToFocus = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myInplaceEditorComponent); + } + if(componentToFocus != null){ + componentToFocus.requestFocusInWindow(); + } + else{ + myInplaceEditorComponent.requestFocusInWindow(); + } + myFocusWatcher.install(myInplaceEditorComponent); + + // 5. Block any mouse event to finish editing by any of them + enableEvents(MouseEvent.MOUSE_EVENT_MASK); + + repaint(); + } + + private void adjustEditorComponentSize(){ + final Dimension preferredSize = myInplaceEditorComponent.getPreferredSize(); + int width = Math.max(preferredSize.width, myPreferredBounds.width); + // Editor component should not be extended to invisible area + width = Math.min(width, getWidth() - myInplaceEditorComponent.getX()); + myInplaceEditorComponent.setSize(width, myInplaceEditorComponent.getHeight()); + myInplaceEditorComponent.revalidate(); + } + + /** + * Finishes current inplace editing + */ + private void finishInplaceEditing(){ + if(myInplaceComponent == null || myInsideChange){ // nothing to finish + return; + } + myInsideChange = true; + try{ + // 1. Apply new value to the component + LOG.assertTrue(myInplaceEditor != null); + try { + final Object value = myInplaceEditor.getValue(); + myInplaceProperty.setValue(myInplaceComponent, value); + } catch (Exception ignored){} + myEditor.refreshAndSave(true); + + // 2. Remove editor from the layer + + removeInplaceEditorComponent(); + + myInplaceEditor.removePropertyEditorListener(myPropertyEditorListener); + myFocusWatcher.deinstall(myInplaceEditorComponent); + + myInplaceComponent = null; + myInplaceEditorComponent = null; + + // 3. Let AWT work + disableEvents(MouseEvent.MOUSE_EVENT_MASK); + }finally{ + myInsideChange = false; + } + + repaint(); + } + + /** + * Cancells current inplace editing + */ + private void cancelInplaceEditing(){ + if(myInplaceComponent == null || myInsideChange){ // nothing to finish + return; + } + myInsideChange = true; + try{ + // 1. Remove editor from the layer + LOG.assertTrue(myInplaceProperty != null); + LOG.assertTrue(myInplaceEditor != null); + + removeInplaceEditorComponent(); + + remove(myInplaceEditorComponent); + + myInplaceEditor.removePropertyEditorListener(myPropertyEditorListener); + myFocusWatcher.deinstall(myInplaceEditorComponent); + + myInplaceComponent = null; + myInplaceEditorComponent = null; + + // 2. Let AWT work + disableEvents(MouseEvent.MOUSE_EVENT_MASK); + }finally{ + myInsideChange = false; + } + + repaint(); + } + + private void removeInplaceEditorComponent() { + // [vova] before removing component from Swing tree we have to + // request component into glass layer. Otherwise focus from component being removed + // can go to some RadComponent. + + // This cast is safe because InplaceEditingLayer is always in TabbedPaneWrapper + final Container ancestor = getFocusCycleRootAncestor(); + LOG.assertTrue(ancestor != null); + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(myEditor.getGlassLayer()); + try { + remove(myInplaceEditorComponent); + } + finally { + LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(null); + } + } + + /** + * Finish inplace editing when selection changes + */ + private final class MyComponentSelectionListener implements ComponentSelectionListener{ + public void selectedComponentChanged(final GuiEditor source) { + finishInplaceEditing(); + } + } + + /** + * Finish inplace editing when inplace editor component loses focus + */ + private final class MyFocusWatcher extends FocusWatcher{ + protected void focusLostImpl(final FocusEvent e) { + final Component opposite = e.getOppositeComponent(); + if( + e.isTemporary() || + opposite != null && SwingUtilities.isDescendingFrom(opposite, getTopComponent()) + ){ + // Do nothing if focus moves inside top component hierarchy + return; + } + // [vova] we need LaterInvocatorEx here to prevent write-access assertions + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + finishInplaceEditing(); + } + }, ModalityState.NON_MMODAL); + } + } + + /** + * Finishes editing by "Enter" and cancels editing by "Esc" + */ + private final class MyPropertyEditorListener extends PropertyEditorAdapter{ + public void valueCommited(final PropertyEditor source) { + finishInplaceEditing(); + } + + public void editingCanceled(final PropertyEditor source) { + cancelInplaceEditing(); + } + + public void preferredSizeChanged(final PropertyEditor source) { + adjustEditorComponentSize(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/InsertComponentProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/InsertComponentProcessor.java new file mode 100644 index 00000000000..1ca83ba50a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/InsertComponentProcessor.java @@ -0,0 +1,295 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiClass; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.uiDesigner.core.Util; +import com.intellij.uiDesigner.lw.IComponent; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.Palette; +import com.intellij.uiDesigner.palette.PalettePanel; +import com.intellij.uiDesigner.quickFixes.CreateFieldFix; +import com.intellij.uiDesigner.compiler.Utils; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class InsertComponentProcessor extends EventProcessor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.InsertComponentProcessor"); + + private final GuiEditor myEditor; + private final PalettePanel myPalette; + private final boolean mySticky; + private DropInfo myDropInfo; + private RadComponent myInsertedComponent; + private Point myInitialPoint; + private Dimension myInitialSize; + private boolean myShouldSetPreferredSizeIfNotResized; + + public InsertComponentProcessor(final GuiEditor editor, final PalettePanel palette, final boolean sticky){ + myEditor = editor; + myPalette = palette; + mySticky = sticky; + } + + protected void processKeyEvent(final KeyEvent e) {} + + /** + * TODO[vova] it would be fine to configure such "input" controls somewhere in palette + * @return whether component is an input control or not + */ + private static boolean isInputComponent(final RadComponent component){ + LOG.assertTrue(component != null); + + final Class aClass = component.getComponentClass(); + if( + AbstractButton.class.isAssignableFrom(aClass) || + JComboBox.class.isAssignableFrom(aClass) || + JList.class.isAssignableFrom(aClass) || + JSpinner.class.isAssignableFrom(aClass) || + JTabbedPane.class.isAssignableFrom(aClass) || + JTable.class.isAssignableFrom(aClass) || + JTextComponent.class.isAssignableFrom(aClass) || + JTree.class.isAssignableFrom(aClass) + ){ + return true; + } + + return false; + } + + /** + * @return never null + */ + private String suggestBinding(final String componentClassName){ + LOG.assertTrue(componentClassName != null); + + final int lastDotIndex = componentClassName.lastIndexOf('.'); + String shortClassName = componentClassName.substring(lastDotIndex + 1); + + // Here is euristic. Chop first 'J' letter for standard Swing classes. + // Without 'J' bindings look better. + if( + shortClassName.length() > 1 && Character.isUpperCase(shortClassName.charAt(1)) && + componentClassName.startsWith("javax.swing.") && + StringUtil.startsWithChar(shortClassName, 'J') + ){ + shortClassName = shortClassName.substring(1); + } + shortClassName = StringUtil.decapitalize(shortClassName); + + LOG.assertTrue(shortClassName.length() > 0); + + // Generate member name based on current code style + for(int i = 0; true; i++){ + final String nameCandidate = shortClassName + (i + 1); + final String binding = CodeStyleManager.getInstance(myEditor.getProject()).propertyNameToVariableName( + nameCandidate, + VariableKind.FIELD + ); + + // Check that binding is unique + final boolean[] isUnique = new boolean[]{true}; + FormEditingUtil.iterate( + myEditor.getRootContainer(), + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final IComponent component) { + if(binding.equals(component.getBinding())){ + isUnique[0] = false; + return false; + } + return true; + } + } + ); + + if(!isUnique[0]){ + continue; // check next candidate + } + + return binding; + } + } + + /** + * Tries to create binding for {@link #myInsertedComponent} + */ + private void createBindingWhenDrop() { + if(isInputComponent(myInsertedComponent)){ + // Now if the inserted component is a input control, we need to automatically create binding + final String binding = suggestBinding(myInsertedComponent.getComponentClassName()); + myInsertedComponent.setBinding(binding); + + // Try to create field in the corresponding bound class + final String classToBind = myEditor.getRootContainer().getClassToBind(); + if(classToBind != null){ + final PsiClass aClass = FormEditingUtil.findClassToBind(myEditor.getModule(), classToBind); + if(aClass != null){ + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand( + myEditor.getProject(), + new Runnable() { + public void run() { + CreateFieldFix.runImpl( + myEditor, + aClass, + myInsertedComponent.getComponentClassName(), + binding, + false // silently skip all errors (if any) + ); + } + }, + "Create binding", + null + ); + } + } + ); + } + } + } + } + + protected void processMouseEvent(final MouseEvent e){ + if (e.getID() == MouseEvent.MOUSE_PRESSED) { + final ComponentItem item = myPalette.getActiveItem(); + final String id = myEditor.generateId(); + if (JScrollPane.class.getName().equals(item.getClassName())) { + myInsertedComponent = new RadScrollPane(myEditor.getModule(), id); + } + else if (item == Palette.getInstance(myEditor.getProject()).getPanelItem()) { + myInsertedComponent = new RadContainer(myEditor.getModule(), id); + } + else { + if (VSpacer.class.getName().equals(item.getClassName())) { + myInsertedComponent = new RadVSpacer(myEditor.getModule(), id); + } + else if (HSpacer.class.getName().equals(item.getClassName())) { + myInsertedComponent = new RadHSpacer(myEditor.getModule(), id); + } + else if (JTabbedPane.class.getName().equals(item.getClassName())) { + myInsertedComponent = new RadTabbedPane(myEditor.getModule(), id); + } + else if (JSplitPane.class.getName().equals(item.getClassName())) { + myInsertedComponent = new RadSplitPane(myEditor.getModule(), id); + } + else { + final ClassLoader loader = LoaderFactory.getInstance(myEditor.getProject()).getLoader(myEditor.getFile()); + try { + final Class aClass = Class.forName(item.getClassName(), true, loader); + myInsertedComponent = new RadAtomicComponent(myEditor.getModule(), aClass, id); + } + catch (final Exception exc) { + String errorDescription = Utils.validateJComponentClass(loader, item.getClassName()); + if (errorDescription == null) { + errorDescription = "Class \"" + item.getClassName() + "\" cannot be instantiated"; + final String message = FormEditingUtil.getExceptionMessage(exc); + if (message != null) { + errorDescription += ": " + message; + } + } + myInsertedComponent = RadErrorComponent.create( + myEditor.getModule(), + id, + item.getClassName(), + null, + errorDescription + ); + } + } + } + myInsertedComponent.init(item); + + if (FormEditingUtil.canDrop(myEditor, e.getX(), e.getY(), 1)) { + CommandProcessor.getInstance().executeCommand( + myEditor.getProject(), + new Runnable(){ + public void run(){ + createBindingWhenDrop(); + + myDropInfo = FormEditingUtil.drop(myEditor, e.getX(), e.getY(), new RadComponent[]{myInsertedComponent}, new int[]{0}, new int[]{0}); + + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + myInsertedComponent.setSelected(true); + + myInitialSize = null; + myShouldSetPreferredSizeIfNotResized = true; + if (myDropInfo.myTargetContainer.isXY()) { + setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)); + myInitialSize = myInsertedComponent.getSize(); + if (myInitialSize.width > 0 && myInitialSize.height > 0) { + myShouldSetPreferredSizeIfNotResized = false; + } + else { + // size was not specified as initial value + myInitialSize = new Dimension(7, 7); + } + Util.adjustSize(myInsertedComponent.getDelegee(), myInsertedComponent.getConstraints(), myInitialSize); + myInsertedComponent.setSize(myInitialSize); + } + + myEditor.refresh(); + + myInitialPoint = e.getPoint(); + } + }, + null, + null + ); + } + } + else if (e.getID() == MouseEvent.MOUSE_RELEASED) { + if (!mySticky) { + myPalette.clearActiveItem(); + } + + if (myDropInfo != null) { + if (myDropInfo.myTargetContainer.isXY()) { + Dimension newSize = myInsertedComponent.getSize(); + if (newSize.equals(myInitialSize) && myShouldSetPreferredSizeIfNotResized) { + // if component dropped into XY and was not resized, make it preferred size + newSize = myInsertedComponent.getPreferredSize(); + } + Util.adjustSize(myInsertedComponent.getDelegee(), myInsertedComponent.getConstraints(), newSize); + myInsertedComponent.setSize(newSize); + } + + myEditor.refreshAndSave(true); + } + } + else if (e.getID() == MouseEvent.MOUSE_DRAGGED) { + if (myDropInfo != null && myDropInfo.myTargetContainer.isXY()) { + final int width = e.getX() - myInitialPoint.x; + final int height = e.getY() - myInitialPoint.y; + + final Dimension newSize = myInsertedComponent.getSize(); + + if (width >= myInitialSize.width) { + newSize.width = width; + } + if (height >= myInitialSize.height) { + newSize.height = height; + } + myInsertedComponent.setSize(newSize); + myEditor.refresh(); + } + } + } + + protected boolean cancelOperation(){ + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/LoaderFactory.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/LoaderFactory.java new file mode 100644 index 00000000000..b491d9a0688 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/LoaderFactory.java @@ -0,0 +1,116 @@ +package com.intellij.uiDesigner; + +import com.intellij.ide.plugins.cl.IdeaClassLoader; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.uiDesigner.core.Spacer; +import com.intellij.util.PathUtil; +import org.jdom.Element; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.StringTokenizer; +import java.util.WeakHashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class LoaderFactory implements ProjectComponent, JDOMExternalizable{ + private final Project myProject; + + private final WeakHashMap myModule2ClassLoader; + private final ModuleRootListener myRootsListener = new ModuleRootListener() { + public void beforeRootsChange(final ModuleRootEvent event) {} + + public void rootsChanged(final ModuleRootEvent event) { + myModule2ClassLoader.clear(); + } + }; + + public static LoaderFactory getInstance(final Project project) { + return project.getComponent(LoaderFactory.class); + } + + LoaderFactory(final Project project, ProjectRootManager projectRootManager) { + myProject = project; + myModule2ClassLoader = new WeakHashMap(); + projectRootManager.addModuleRootListener(myRootsListener); +} + + public void projectOpened() { + } + + public void projectClosed() { + } + + public String getComponentName() { + return "GUI Designer component loader factory"; + } + + public void initComponent() { + } + + public void disposeComponent() { + ProjectRootManager.getInstance(myProject).removeModuleRootListener(myRootsListener); + myModule2ClassLoader.clear(); + } + + public void readExternal(final Element element) { + } + + public void writeExternal(final Element element) { + } + + + /** + * @return never null + */ + public ClassLoader getLoader(final VirtualFile formFile) { + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module == null) { + return getClass().getClassLoader(); + } + + final ClassLoader cachedLoader = myModule2ClassLoader.get(module); + if (cachedLoader != null) { + return cachedLoader; + } + + final String runClasspath = ProjectRootsTraversing.collectRoots(module, ProjectRootsTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString(); + + final ArrayList urls = new ArrayList(); + final StringTokenizer tokenizer = new StringTokenizer(runClasspath, File.pathSeparator); + while (tokenizer.hasMoreTokens()) { + final String s = tokenizer.nextToken(); + try { + urls.add(new File(s).toURI().toURL()); + } + catch (Exception e) { + // ignore ? + } + } + + try { + urls.add(new File(PathUtil.getJarPathForClass(Spacer.class)).toURI().toURL()); + } + catch (MalformedURLException ignored) { + } + + final URL[] _urls = urls.toArray(new URL[urls.size()]); + //final URLClassLoader classLoader = new URLClassLoader(_urls, null); + final ClassLoader classLoader = new IdeaClassLoader(Arrays.asList(_urls), null); + + myModule2ClassLoader.put(module, classLoader); + + return classLoader; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/MainProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/MainProcessor.java new file mode 100644 index 00000000000..6f196ff52ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/MainProcessor.java @@ -0,0 +1,278 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.componentTree.ComponentSelectionListener; +import com.intellij.uiDesigner.palette.ComponentItem; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MainProcessor extends EventProcessor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.MainProcessor"); + + public static final int DRAGGER_SIZE = 10; + + private EventProcessor myCurrentProcessor; + + private final GuiEditor myEditor; + + public MainProcessor(final GuiEditor editor){ + if (editor == null){ + throw new IllegalArgumentException("editor cannot be null"); + } + myEditor = editor; + myEditor.addComponentSelectionListener(new MyComponentSelectionListener()); + } + + protected void processKeyEvent(final KeyEvent e){ + if (!myEditor.isEditable()) { + return; + } + + if (myCurrentProcessor != null) { + myCurrentProcessor.processKeyEvent(e); + } + } + + protected void processMouseEvent(final MouseEvent e){ + // Here is a good place to handle right and wheel mouse clicking. All mouse + // motion events should go further + final int id = e.getID(); + if( + (MouseEvent.BUTTON2 == e.getButton() || MouseEvent.BUTTON3 == e.getButton()) && + ( + MouseEvent.MOUSE_PRESSED == id || + MouseEvent.MOUSE_RELEASED == id || + MouseEvent.MOUSE_CLICKED == id + ) + ){ + if (e.isPopupTrigger()) { + final ActionManager actionManager = ActionManager.getInstance(); + final ActionPopupMenu popupMenu = actionManager.createActionPopupMenu( + ActionPlaces.GUI_DESIGNER_EDITOR_POPUP, + (ActionGroup)actionManager.getAction(IdeActions.GROUP_GUI_DESIGNER_EDITOR_POPUP) + ); + popupMenu.getComponent().show(e.getComponent(), e.getX(), e.getY()); + } + return; + } + + // Handle all left mouse events and all motion events + final RadComponent componentAt = FormEditingUtil.getRadComponentAt(myEditor, e.getX(), e.getY()); + if (componentAt != null) { + final Point p1 = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), componentAt.getDelegee()); + final Component deepestComponentAt = SwingUtilities.getDeepestComponentAt(componentAt.getDelegee(), p1.x, p1.y); + final Point p2 = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), deepestComponentAt); + + componentAt.processMouseEvent(new MouseEvent( + deepestComponentAt, + id, + e.getWhen(), + e.getModifiers(), + p2.x, + p2.y, + e.getClickCount(), + e.isPopupTrigger(), + e.getButton() + )); + } + + Cursor cursor = Cursor.getDefaultCursor(); + if(id==MouseEvent.MOUSE_MOVED){ + if (myEditor.getPalettePanel().getActiveItem() != null) { + cursor = FormEditingUtil.getDropCursor(myEditor, e.getX(), e.getY(), 1); + } + else { + final RadComponent component = FormEditingUtil.getRadComponentAt(myEditor, e.getX(), e.getY()); + if (component != null) { + final Point point = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), component.getDelegee()); + final int resizeMask = Painter.getResizeMask(component, point.x, point.y); + if (resizeMask != 0) { + cursor = Cursor.getPredefinedCursor(Painter.getResizeCursor(resizeMask)); + } + updateDragger(e); + } + } + } + else if (id == MouseEvent.MOUSE_PRESSED) { + processMousePressed(e); + } + else if (id == MouseEvent.MOUSE_RELEASED) { + // not every press sets processor so its not a redundant 'if' + if (myCurrentProcessor != null) { + myCurrentProcessor.processMouseEvent(e); + myCurrentProcessor = null; + } + } + else if(id == MouseEvent.MOUSE_CLICKED){ + processMouseClicked(e); + } + + if (!e.isConsumed() && myCurrentProcessor != null) { + myCurrentProcessor.processMouseEvent(e); + } + + if(myCurrentProcessor!=null && myCurrentProcessor.getCursor()!=null){ + cursor=myCurrentProcessor.getCursor(); + } + myEditor.getLayeredPane().setCursor(cursor); + } + + private void updateDragger(final MouseEvent e){ + final RadComponent component = FormEditingUtil.getRadComponentAt(myEditor, e.getX(), e.getY()); + + LOG.assertTrue(component != null); + + // Dragger + final RadComponent oldDraggerHost = FormEditingUtil.getDraggerHost(myEditor); + RadComponent newDraggerHost = null; + for (RadComponent c = component; !(c instanceof RadRootContainer); c = c.getParent()){ + if (c.isSelected()) { + newDraggerHost = c; + break; + } + } + + boolean keepOldHost = false; + + if (oldDraggerHost != null && oldDraggerHost.isSelected()) { + final Point p = SwingUtilities.convertPoint(oldDraggerHost.getDelegee(), 0, 0, e.getComponent()); + final int deltaX = e.getX() - p.x; + final int deltaY = e.getY() - p.y; + if( + deltaX > -DRAGGER_SIZE && deltaX < oldDraggerHost.getWidth() && + deltaY > -DRAGGER_SIZE && deltaY < oldDraggerHost.getHeight() + ){ + keepOldHost = true; + newDraggerHost = null; + } + } + + boolean shouldRepaint = false; + + if (oldDraggerHost != null && !keepOldHost && oldDraggerHost != newDraggerHost){ + oldDraggerHost.setDragger(false); + shouldRepaint = true; + } + + if (newDraggerHost != null){ + newDraggerHost.setDragger(true); + shouldRepaint = true; + } + + if (shouldRepaint) { + myEditor.repaintLayeredPane(); + } + } + + private void processMousePressed(final MouseEvent e){ + RadComponent component = null; + final RadComponent draggerHost = FormEditingUtil.getDraggerHost(myEditor); + // Try to understand whether we pressed inside dragger area + if(draggerHost != null){ + final JComponent delegee = draggerHost.getDelegee(); + final Point p = SwingUtilities.convertPoint(delegee, 0, 0, e.getComponent()); + if( + p.x - MainProcessor.DRAGGER_SIZE <= e.getX() && e.getX() <= p.x && + p.y - MainProcessor.DRAGGER_SIZE <= e.getY() && e.getY() <= p.y + ){ + component = draggerHost; + } + } + + // If user clicked not inside dragger then we have find RadComponent at the click point + if(component == null){ + component = FormEditingUtil.getRadComponentAt(myEditor, e.getX(), e.getY()); + } + + if (component == null) { + return; + } + + if (!myEditor.isEditable()) { + return; + } + + final ComponentItem selectedItem = myEditor.getPalettePanel().getActiveItem(); + if (selectedItem != null) { + myCurrentProcessor = new InsertComponentProcessor(myEditor, myEditor.getPalettePanel(), e.isControlDown()); + return; + } + + if (e.isControlDown()) { + component.setSelected(!(component.isSelected())); + } + else if (e.isShiftDown()) { + // Do not select component is shift is pressed + } + else { + if (!component.isSelected()) { + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + component.setSelected(true); + } + } + + if(myCurrentProcessor != null){ + // Sun sometimes skips mouse released events... + myCurrentProcessor.cancelOperation(); + myCurrentProcessor = null; + } + + final Point point = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), component.getDelegee()); + final int resizeMask = Painter.getResizeMask(component, point.x, point.y); + + if (resizeMask != 0) { + if (component.getParent().isXY()) { + myCurrentProcessor = new ResizeProcessor(myEditor, component, resizeMask); + } + } + else if (component instanceof RadRootContainer || ((component instanceof RadContainer) && e.isShiftDown())) { + myCurrentProcessor = new GroupSelectionProcessor(myEditor, (RadContainer)component); + } + else if (!e.isShiftDown()) { + myCurrentProcessor = new DragSelectionProcessor(myEditor); + } + + updateDragger(e); + } + + private void processMouseClicked(final MouseEvent e){ + if (!myEditor.isEditable()) { + return; + } + + if(e.getClickCount() != 2){ // inplace editing starts with double click + return; + } + myEditor.getInplaceEditingLayer().startInplaceEditing(e.getX(), e.getY()); + } + + protected boolean cancelOperation(){ + if (myCurrentProcessor != null) { + if (myCurrentProcessor.cancelOperation()){ + myCurrentProcessor = null; + myEditor.getLayeredPane().setCursor(Cursor.getDefaultCursor()); + return true; + } + } + else if (myEditor.getPalettePanel().getActiveItem() != null) { + myEditor.getPalettePanel().clearActiveItem(); + myEditor.getLayeredPane().setCursor(Cursor.getDefaultCursor()); + return true; + } + return false; + } + + private final class MyComponentSelectionListener implements ComponentSelectionListener{ + public void selectedComponentChanged(final GuiEditor source) { + // TODO[vova] stop inplace editing + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Painter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Painter.java new file mode 100644 index 00000000000..252d708e1fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Painter.java @@ -0,0 +1,305 @@ +package com.intellij.uiDesigner; + +import com.intellij.uiDesigner.core.GridLayoutManager; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class Painter { + /** + * This color is used to paint decoration of non selected components + */ + private static final Color NON_SELECTED_BOUNDARY_COLOR = new Color(114, 126, 143); + /** + * This color is used to paint decoration of selected components + */ + private static final Color SELECTED_BOUNDARY_COLOR = new Color(8, 8, 108); + /** + * This color is used to paint grid cell for selected container + */ + private static final Color SELECTED_GRID_COLOR = new Color(47, 67, 96); + /** + * This color is used to paint grid cell for non selected container + */ + private static final Color NON_SELECTED_GRID_COLOR = new Color(130, 140, 155); + + public final static int WEST_MASK = 1; + public final static int EAST_MASK = 2; + public final static int NORTH_MASK = 4; + public final static int SOUTH_MASK = 8; + private final static int R = 2; + private final static int GAP = R; + private static final int NW = 0; + private static final int N = 1; + private static final int NE = 2; + private static final int E = 3; + private static final int SE = 4; + private static final int S = 5; + private static final int SW = 6; + private static final int W = 7; + + public static void paintComponentDecoration(final GuiEditor editor, final RadComponent component, final Graphics g){ + // Collect selected components and paint decoration for non selected components + final ArrayList selection = new ArrayList(); + final Rectangle layeredPaneRect = editor.getLayeredPane().getVisibleRect(); + FormEditingUtil.iterate( + component, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if(!component.getDelegee().isShowing()){ // Skip invisible components + return true; + } + final Shape oldClip = g.getClip(); + final RadContainer parent = component.getParent(); + if(parent != null){ + final Point p = SwingUtilities.convertPoint(component.getDelegee(), 0, 0, editor.getLayeredPane()); + final Rectangle visibleRect = layeredPaneRect.intersection(new Rectangle(p.x, p.y, parent.getWidth(), parent.getHeight())); + g.setClip(visibleRect); + } + if(component.isSelected()){ // we will paint selection later + selection.add(component); + } + else{ + paintComponentBoundsImpl(editor, component, g); + } + paintGridOutlineImpl(editor, component, g); + if(parent != null){ + g.setClip(oldClip); + } + return true; + } + } + ); + + // Let's paint decoration for selected components + for(int i = selection.size() - 1; i >= 0; i--){ + final Shape oldClip = g.getClip(); + final RadComponent c = selection.get(i); + final RadContainer parent = c.getParent(); + if(parent != null){ + final Point p = SwingUtilities.convertPoint(c.getDelegee(), 0, 0, editor.getLayeredPane()); + final Rectangle visibleRect = layeredPaneRect.intersection(new Rectangle(p.x, p.y, parent.getWidth(), parent.getHeight())); + g.setClip(visibleRect); + } + paintComponentBoundsImpl(editor, c, g); + if(parent != null){ + g.setClip(oldClip); + } + } + } + + /** + * Paints container border. For grids the method also paints vertical and + * horizontal lines that indicate bounds of the rows and columns. + * Method does nothing if the component is not an instance + * of RadContainer. + */ + private static void paintComponentBoundsImpl(final GuiEditor editor, final RadComponent component, final Graphics g){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (!(component instanceof RadContainer)){ + return; + } + final Point point = SwingUtilities.convertPoint( + component.getDelegee(), + 0, + 0, + editor.getRootContainer().getDelegee() + ); + g.translate(point.x, point.y); + try{ + if (component.isSelected()) { + g.setColor(SELECTED_BOUNDARY_COLOR); + } + else { + g.setColor(NON_SELECTED_BOUNDARY_COLOR); + } + g.drawRect(0, 0, component.getWidth() - 1, component.getHeight() - 1); + }finally{ + g.translate(-point.x, -point.y); + } + } + + /** + * This method paints grid bounds for "grid" containers + */ + private static void paintGridOutlineImpl(final GuiEditor editor, final RadComponent component, final Graphics g){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (!(component instanceof RadContainer)){ + return; + } + final RadContainer container = (RadContainer)component; + if(!container.isGrid()){ + return; + } + + final Point point = SwingUtilities.convertPoint( + component.getDelegee(), + 0, + 0, + editor.getRootContainer().getDelegee() + ); + g.translate(point.x, point.y); + try{ + // Paint grid + final GridLayoutManager gridLayout = (GridLayoutManager)container.getLayout(); + if (component.isSelected()) { + g.setColor(SELECTED_GRID_COLOR); + } + else { + g.setColor(NON_SELECTED_GRID_COLOR); + } + + // Horizontal lines + final int width = component.getWidth(); + final int[] ys = gridLayout.getYs(); + final int[] heights = gridLayout.getHeights(); + for (int i = 0; i < ys.length - 1; i++) { + final int y = (ys[i] + heights[i] + ys[i + 1]) / 2; + // Draw dotted horizontal line + for(int x = 0; x < width; x+=4){ + g.drawLine(x, y, Math.min(x+2, width - 1), y); + } + } + + // Vertical lines + final int height = component.getHeight(); + final int[] xs = gridLayout.getXs(); + final int[] widths = gridLayout.getWidths(); + for (int i = 0; i < xs.length - 1; i++) { + final int x = (xs[i] + widths[i] + xs[i + 1]) / 2; + // Draw dotted vertical line + for(int y = 0; y < height; y+=4){ + g.drawLine(x, y, x, Math.min(y+2, height - 1)); + } + } + }finally{ + g.translate(-point.x, -point.y); + } + } + + /** + * Paints selection for the specified component. + */ + public static void paintSelectionDecoration(final RadComponent component, final Graphics g){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (component.isSelected()) { + g.setColor(Color.BLUE); + final Point[] points = getPoints(component.getWidth(), component.getHeight()); + for (int i = 0; i < points.length; i++) { + final Point point = points[i]; + g.fillRect(point.x - R, point.y - R, 2*R + 1, 2*R + 1); + } + } + } + + /** + * @param x in component's coord system + * @param y in component's coord system + */ + public static int getResizeMask(final RadComponent component, final int x, final int y) { + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (component.getParent() == null || !component.isSelected()) { + return 0; + } + + // only components in XY can be resized... + if (!component.getParent().isXY()) { + return 0; + } + + final int width=component.getWidth(); + final int height=component.getHeight(); + + final Point[] points = getPoints(width, height); + + if (isInside(x, y, points[SE])) { + return EAST_MASK | SOUTH_MASK; + } + else if (isInside(x,y,points[NW])) { + return WEST_MASK | NORTH_MASK; + } + else if(isInside(x,y,points[N])){ + return NORTH_MASK; + } + else if(isInside(x,y,points[NE])){ + return EAST_MASK | NORTH_MASK; + } + else if (isInside(x, y, points[W])){ + return WEST_MASK; + } + else if (isInside(x, y, points[E])){ + return EAST_MASK; + } + else if (isInside(x, y, points[SW])){ + return WEST_MASK | SOUTH_MASK; + } + else if (isInside(x, y, points[S])){ + return SOUTH_MASK; + } + else{ + return 0; + } + } + + private static boolean isInside(final int x, final int y, final Point r) { + return x >= r.x - R && x <= r.x + R && y >= r.y - R && y <= r.y + R; + } + + public static int getResizeCursor(final int resizeMask){ + if (resizeMask == (WEST_MASK | NORTH_MASK)) { + return Cursor.NW_RESIZE_CURSOR; + } + else if (resizeMask == NORTH_MASK) { + return Cursor.N_RESIZE_CURSOR; + } + else if (resizeMask == (EAST_MASK | NORTH_MASK)) { + return Cursor.NE_RESIZE_CURSOR; + } + else if (resizeMask == WEST_MASK) { + return Cursor.W_RESIZE_CURSOR; + } + else if (resizeMask == EAST_MASK) { + return Cursor.E_RESIZE_CURSOR; + } + else if (resizeMask == (WEST_MASK | SOUTH_MASK)) { + return Cursor.SW_RESIZE_CURSOR; + } + else if (resizeMask == SOUTH_MASK) { + return Cursor.S_RESIZE_CURSOR; + } + else if (resizeMask == (EAST_MASK | SOUTH_MASK)) { + return Cursor.SE_RESIZE_CURSOR; + } + else { + throw new IllegalArgumentException("unknown resizeMask: " + resizeMask); + } + } + + public static Point[] getPoints(final int width, final int height) { + final Point[] points = new Point[8]; + + points[NW] = new Point(GAP, GAP); // NW + points[N] = new Point(width / 2, GAP); // N + points[NE] = new Point(width - GAP - 1, GAP); // NE + points[E] = new Point(width - GAP - 1, height / 2); // E + points[SE] = new Point(width - GAP - 1, height - GAP - 1); // SE + points[S] = new Point(width / 2, height - GAP - 1); // S + points[SW] = new Point(GAP, height - GAP - 1); // SW + points[W] = new Point(GAP, height / 2); // W + + return points; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PassiveDecorationLayer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PassiveDecorationLayer.java new file mode 100644 index 00000000000..5f621a68613 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PassiveDecorationLayer.java @@ -0,0 +1,73 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; +import java.awt.*; + +/** + * Decoration layer is over COMPONENT_LAYER (layer where all components are located). + * It contains all necessary decorators. Decorators are: + * - special borders to show component bounds and cell bounds inside grids + * - special component which marks selected rectangle + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +class PassiveDecorationLayer extends JComponent{ + private final GuiEditor myEditor; + + public PassiveDecorationLayer(final GuiEditor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + myEditor = editor; + } + + /** + * Paints all necessary decoration for the specified component + */ + protected final void paintPassiveDecoration(final RadComponent component, final Graphics g){ + // Paint component bounds and grid markers + Painter.paintComponentDecoration(myEditor, component, g); + + // Paint selection and dragger + FormEditingUtil.iterate( + component, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + final Point point = SwingUtilities.convertPoint( + component.getDelegee(), + 0, + 0, + myEditor.getRootContainer().getDelegee() + ); + g.translate(point.x, point.y); + try{ + Painter.paintSelectionDecoration(component, g); + // Over selection we have to paint dragger + if (component.hasDragger()){ + final Icon icon = IconLoader.getIcon("/com/intellij/uiDesigner/icons/drag.png"); + icon.paintIcon(PassiveDecorationLayer.this, g, - icon.getIconWidth(), - icon.getIconHeight()); + } + }finally{ + g.translate(-point.x, -point.y); + } + return true; + } + } + ); + } + + public void paint(final Graphics g){ + // Passive decoration + final RadRootContainer root = myEditor.getRootContainer(); + for(int i = root.getComponentCount() - 1; i >= 0; i--){ + final RadComponent component = root.getComponent(i); + paintPassiveDecoration(component, g); + } + + // Paint active decorators + paintChildren(g); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Properties.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Properties.java new file mode 100644 index 00000000000..b8c1ea80688 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/Properties.java @@ -0,0 +1,98 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.uiDesigner.lw.LwXmlReader; +import org.jdom.Element; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class Properties implements ApplicationComponent, JDOMExternalizable{ + private final HashMap myClass2InplaceProperty; + private final HashMap> myClass2ExpertProperties; + + public static Properties getInstance() { + return ApplicationManager.getApplication().getComponent(Properties.class); + } + + public Properties(){ + myClass2InplaceProperty = new HashMap(); + myClass2ExpertProperties = new HashMap>(); + } + + /** + * @return it is possible that properties do not exist in class; returned values are ones specified in config. Never null + */ + public boolean isExpertProperty(final Class aClass, final String propertyName) { + for (Class c = aClass; c != null; c = c.getSuperclass()){ + final HashSet properties = myClass2ExpertProperties.get(c.getName()); + if (properties != null && properties.contains(propertyName)){ + return true; + } + } + return false; + } + + /** + * @return it is possible that property does not exist in class; returned value is one specified in config + */ + public String getInplaceProperty(final Class aClass) { + for (Class c = aClass; c != null; c = c.getSuperclass()){ + final String property = myClass2InplaceProperty.get(c.getName()); + if (property != null){ + return property; + } + } + return null; + } + + public String getComponentName(){ + return "gui-designer-properties"; + } + + public void initComponent() { } + + public void disposeComponent() { } + + public void readExternal(final Element element) { + final Iterator i = element.getChildren("class").iterator(); + while (i.hasNext()) { + final Element classElement = (Element)i.next(); + + final String className = LwXmlReader.getRequiredString(classElement, "name"); + + // Read "expert" properties + final Element expertPropertiesElement = classElement.getChild("expert-properties"); + if (expertPropertiesElement != null) { + final HashSet expertProperties = new HashSet(); + + final Iterator iterator = expertPropertiesElement.getChildren("property").iterator(); + while (iterator.hasNext()) { + final Element e = (Element)iterator.next(); + final String name = LwXmlReader.getRequiredString(e, "name"); + expertProperties.add(name); + } + + myClass2ExpertProperties.put(className, expertProperties); + } + + // Read "inplace" property. This property is optional + final Element inplacePropertyElement = classElement.getChild("inplace-property"); + if (inplacePropertyElement != null) { + myClass2InplaceProperty.put(className, LwXmlReader.getRequiredString(inplacePropertyElement, "name")); + } + } + } + + public void writeExternal(final Element element) throws WriteExternalException{ + throw new WriteExternalException(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PsiPropertiesProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PsiPropertiesProvider.java new file mode 100644 index 00000000000..e63c59a5621 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/PsiPropertiesProvider.java @@ -0,0 +1,108 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.uiDesigner.lw.*; + +import java.awt.*; +import java.util.HashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class PsiPropertiesProvider implements PropertiesProvider{ + private final Module myModule; + private final HashMap myCache; + + public PsiPropertiesProvider(final Module module){ + if (module == null){ + throw new IllegalArgumentException("module cannot be null"); + } + myModule = module; + myCache = new HashMap(); + } + + public HashMap getLwProperties(final String className){ + if (myCache.containsKey(className)) { + return (HashMap)myCache.get(className); + } + + final PsiManager psiManager = PsiManager.getInstance(myModule.getProject()); + final PsiClass aClass = psiManager.findClass(className, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule)); + if (aClass == null) { + return null; + } + + final HashMap result = new HashMap(); + + final PsiMethod[] methods = aClass.getAllMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + + // it's a setter candidate.. try to find getter + + if (!PropertyUtil.isSimplePropertySetter(method)) { + continue; + } + final String name = PropertyUtil.getPropertyName(method); + if(name == null){ + throw new IllegalStateException(); + } + final PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, name, false, true); + if(getter == null){ + continue; + } + + if ( + name.equals("preferredSize") || + name.equals("minimumSize") || + name.equals("maximumSize") + ){ + // our own properties must be used instead + continue; + } + + final PsiType type = getter.getReturnType(); + final String propertyClassName = type.getCanonicalText(); + + final LwIntrospectedProperty property; + + if (int.class.getName().equals(propertyClassName)) { // int + property = new LwIntroIntProperty(name); + } + else if (boolean.class.getName().equals(propertyClassName)) { // boolean + property = new LwIntroBooleanProperty(name); + } + else if (double.class.getName().equals(propertyClassName)) { // double + property = new LwIntroDoubleProperty(name); + } + else if (String.class.getName().equals(propertyClassName)){ // java.lang.String + property = new LwRbIntroStringProperty(name); + } + else if (Insets.class.getName().equals(propertyClassName)) { // java.awt.Insets + property = new LwIntroInsetsProperty(name); + } + else if (Dimension.class.getName().equals(propertyClassName)) { // java.awt.Dimension + property = new LwIntroDimensionProperty(name); + } + else if(Rectangle.class.getName().equals(propertyClassName)){ // java.awt.Rectangle + property = new LwIntroRectangleProperty(name); + } + else { + // type is not supported + continue; + } + + result.put(name, property); + } + + myCache.put(className, result); + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadAtomicComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadAtomicComponent.java new file mode 100644 index 00000000000..0b165600dca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadAtomicComponent.java @@ -0,0 +1,30 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class RadAtomicComponent extends RadComponent { + public RadAtomicComponent(final Module module, final Class aClass, final String id){ + super(module, aClass, id); + } + + public final boolean canDrop(final int x, final int y, final int componentCount){ + return false; + } + + public void write(final XmlWriter writer) { + writer.startElement("component"); + try{ + writeId(writer); + writeClass(writer); + writeBinding(writer); + writeConstraints(writer); + writeProperties(writer); + }finally{ + writer.endElement(); // component + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadComponent.java new file mode 100644 index 00000000000..96daba39905 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadComponent.java @@ -0,0 +1,450 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.Util; +import com.intellij.uiDesigner.lw.IComponent; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.Palette; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.Constructor; +import java.util.HashSet; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class RadComponent implements IComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.RadComponent"); + + /** + * Shared instance of empty array of RadComponenets + */ + public static final RadComponent[] EMPTY_ARRAY = new RadComponent[]{}; + /** + * Using this constant as client property of the Swing component + * you can find corresponding RadComponent + */ + public static final String CLIENT_PROP_RAD_COMPONENT = "radComponent"; + /** + * Whether the component selected or not. Value is java.lang.Boolean + */ + public static final String PROP_SELECTED="selected"; + + /** + * Component id is unique per RadRootContainer. + */ + private final String myId; + /** + * @see #getBinding() + */ + private String myBinding; + + private final Module myModule; + private final Class myClass; + /** + * Delegee is the JComponent which really represents the + * component in UI. + */ + private final JComponent myDelegee; + /** + * Parent RadContainer. This field is always not null + * is the component is in hierarchy. But the root of hierarchy + * has null parent indeed. + */ + private RadContainer myParent; + /** + * Defines whether the component selected or not. + */ + private boolean mySelected; + /** + * never null + */ + private final GridConstraints myConstraints; + + private Object myCustomLayoutConstraints; + + private final PropertyChangeSupport myChangeSupport; + + private final HashSet myModifiedPropertyNames; + + private boolean myHasDragger; + + /** + * Creates new RadComponent with the specified + * class of delegee and specified ID. + * + * @param aClass class of the compoent's delegee + * @param id id of the compoent inside the form. id + * should be a unique atring inside the form. + */ + public RadComponent(final Module module, final Class aClass, final String id){ + LOG.assertTrue(module != null); + LOG.assertTrue(aClass != null); + LOG.assertTrue(id != null); + + myModule = module; + myClass = aClass; + myId = id; + + myChangeSupport=new PropertyChangeSupport(this); + myConstraints = new GridConstraints(); + myModifiedPropertyNames = new HashSet(); + + try { + final Constructor constructor = myClass.getConstructor(new Class[0]); + constructor.setAccessible(true); + myDelegee = (JComponent)constructor.newInstance(ArrayUtil.EMPTY_OBJECT_ARRAY); + } + catch (Exception e) { + throw new RuntimeException(e); + } + + myDelegee.putClientProperty(CLIENT_PROP_RAD_COMPONENT, this); + } + + /** + * @return module for the component. Never returns null. + */ + public final Module getModule() { + return myModule; + } + + /** + * Initializes introspected properties into default values and + * sets default component's constraints. + */ + public final void init(final ComponentItem item) { + LOG.assertTrue(item != null); + + final IntrospectedProperty[] properties = Palette.getInstance(myModule.getProject()).getIntrospectedProperties(myClass); + for (int i = 0; i < properties.length; i++) { + final IntrospectedProperty property = properties[i]; + final Object initialValue = item.getInitialValue(property); + if (initialValue != null) { + try { + property.setValue(this, initialValue); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + myConstraints.restore(item.getDefaultConstraints()); + } + + /** + * @return the component's id. It is unique within the form. Never null. + */ + public final String getId(){ + return myId; + } + + public final String getBinding(){ + return myBinding; + } + + public final void setBinding(final String binding){ + //TODO[anton,vova]: check that binding is a valid java identifier!!! + myBinding = binding; + } + + /** + * @return Swing delegee component. The RadComponent has the same + * delegee during all its life. The method never returns null. + */ + public final JComponent getDelegee(){ + return myDelegee; + } + + /** + * Sometime bounds of the inplace editor depends on the point where + * user invoked inplace editor. + * + * @param x x in delegee coordinate system + * @param y y in delegee coordinate system + * + * @return inplace property for the RadComponent if any. + * The method returns null if the component doesn't have + * any inplace property. Please not the method can return different + * instances of the property for each invokation. + */ + public Property getInplaceProperty(final int x, final int y){ + return Palette.getInstance(myModule.getProject()).getInplaceProperty(getComponentClass()); + } + + /** + * Sometime bounds of the inplace editor depends on the point where + * user invoked inplace editor. + * + * @param x x in delegee coordinate system + * @param y y in delegee coordinate system + * + * @return area where editor component is located. This is the hint to the + * designer. Designer can use or not this rectangle. + */ + public Rectangle getInplaceEditorBounds(final Property property, final int x, final int y){ + LOG.assertTrue(property != null); + return null; + } + + /** + * @return never null. + */ + public final Class getComponentClass(){ + return myClass; + } + + /** + * @return never null. + */ + public String getComponentClassName() { + return myClass.getName(); + } + + public final Object getCustomLayoutConstraints(){ + return myCustomLayoutConstraints; + } + + public final void setCustomLayoutConstraints(final Object customConstraints){ + myCustomLayoutConstraints = customConstraints; + } + + public final boolean hasDragger(){ + return myHasDragger; + } + + public final void setDragger(final boolean hasDragger){ + myHasDragger = hasDragger; + } + + public final void addPropertyChangeListener(final PropertyChangeListener l){ + myChangeSupport.addPropertyChangeListener(l); + } + + public final void removePropertyChangeListener(final PropertyChangeListener l){ + myChangeSupport.removePropertyChangeListener(l); + } + + protected final void firePropertyChanged( + final String propertyName, + final Object oldValue, + final Object newValue + ){ + LOG.assertTrue(propertyName != null); + myChangeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + /** + * @return component's constarints. The method never returns null. + */ + public final GridConstraints getConstraints(){ + return myConstraints; + } + + public final RadContainer getParent(){ + return myParent; + } + + public final void setParent(final RadContainer parent){ + myParent = parent; + } + + public boolean isSelected(){ + return mySelected; + } + + public void setSelected(final boolean selected){ + if (mySelected != selected) { + mySelected = selected; + firePropertyChanged(PROP_SELECTED,Boolean.valueOf(!mySelected),Boolean.valueOf(mySelected)); + GuiEditor.repaintLayeredPane(this); + } + } + + /** + * @see JComponent#getClientProperty(Object) + */ + public final Object getClientProperty(final Object key){ + LOG.assertTrue(key != null); + return myDelegee.getClientProperty(key); + } + + /** + * @see JComponent#putClientProperty(Object, Object) + */ + public final void putClientProperty(final Object key, final Object value){ + LOG.assertTrue(key != null); + myDelegee.putClientProperty(key, value); + } + + public final int getX() { + return myDelegee.getX(); + } + + public final int getY() { + return myDelegee.getY(); + } + + public final void setLocation(final Point location){ + myDelegee.setLocation(location); + } + + public final void shift(final int dx, final int dy){ + myDelegee.setLocation(myDelegee.getX() + dx, myDelegee.getY() + dy); + } + + public final int getWidth(){ + return myDelegee.getWidth(); + } + + public final int getHeight(){ + return myDelegee.getHeight(); + } + + public final Dimension getSize() { + return myDelegee.getSize(); + } + + public final void setSize(final Dimension size) { + myDelegee.setSize(size); + } + + /** + * @return bounds of the delegee in the parent container + */ + public final Rectangle getBounds() { + return myDelegee.getBounds(); + } + + public final void setBounds(final Rectangle bounds) { + myDelegee.setBounds(bounds); + } + + public final Dimension getMinimumSize(){ + return Util.getMinimumSize(myDelegee, myConstraints); + } + + public final Dimension getPreferredSize(){ + return Util.getPreferredSize(myDelegee, myConstraints); + } + + /** + * todo[anton] get rid of + * @return + */ + public final RevalidateInfo revalidate() { + final RevalidateInfo info = new RevalidateInfo(); + + for (RadContainer container = this instanceof RadContainer ? (RadContainer)this : getParent(); container != null; container = container.getParent()) { + final RadContainer parent = container.getParent(); + if (parent != null && parent.isXY()) { + final Dimension size = container.getSize(); + final Dimension minimumSize = container.getMinimumSize(); + if (size.width < minimumSize.width || size.height < minimumSize.height) { + info.myContainer = container; + info.myPreviousContainerSize = size; + } + } + } + + if (info.myContainer != null) { + final Dimension minimumSize = info.myContainer.getMinimumSize(); + + minimumSize.width = Math.max(minimumSize.width, info.myContainer.getWidth()); + minimumSize.height = Math.max(minimumSize.height, info.myContainer.getHeight()); + + info.myContainer.getDelegee().setSize(minimumSize); + } + + myDelegee.revalidate(); + + return info; + } + + public final boolean isMarkedAsModified(final Property property) { + return myModifiedPropertyNames.contains(property.getName()); + } + + public final void markPropertyAsModified(final Property property) { + myModifiedPropertyNames.add(property.getName()); + } + + /** + * @param x in delegee coordinates + * @param y in delegee coordinates + * @param componentCount number of components to be dropped; always > 0 + */ + public abstract boolean canDrop(int x, int y, int componentCount); + + public void processMouseEvent(final MouseEvent event) {} + + /** + * Serializes component into the passed writer + */ + public abstract void write(XmlWriter writer); + + /** + * Serializes component's ID + */ + protected final void writeId(final XmlWriter writer){ + writer.addAttribute("id", getId()); + } + + /** + * Serializes component's class + */ + protected final void writeClass(final XmlWriter writer){ + writer.addAttribute("class", getComponentClass().getName()); + } + + protected final void writeBinding(final XmlWriter writer){ + // Binding + if (getBinding() != null){ + writer.addAttribute("binding", getBinding()); + } + } + + protected final void writeConstraints(final XmlWriter writer){ + writer.startElement("constraints"); + try { + getParent().writeConstraints(writer, this); + } finally { + writer.endElement(); // constraints + } + } + + protected final void writeProperties(final XmlWriter writer){ + writer.startElement("properties"); + try{ + final IntrospectedProperty[] introspectedProperties = + Palette.getInstance(myModule.getProject()).getIntrospectedProperties(getComponentClass()); + for (int i = 0; i < introspectedProperties.length; i++) { + final IntrospectedProperty property = introspectedProperties[i]; + if (isMarkedAsModified(property)) { + final Object value = property.getValue(this); + if (value != null) { + writer.startElement(property.getName()); + try{ + property.write(value, writer); + }finally{ + writer.endElement(); + } + } + } + } + }finally{ + writer.endElement(); // properties + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadContainer.java new file mode 100644 index 00000000000..a4490e8eea9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadContainer.java @@ -0,0 +1,570 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.Comparing; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.lw.IContainer; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor; +import com.intellij.uiDesigner.shared.BorderType; +import com.intellij.uiDesigner.shared.XYLayoutManager; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public class RadContainer extends RadComponent implements IContainer { + /** + * value: RadComponent[] + */ + public static final String PROP_CHILDREN = "children"; + /** + * Children components + */ + private final ArrayList myComponents; + private final MyPropertyChangeListener myChangeListener; + /** + * Describes border's type. This member is never null + */ + private BorderType myBorderType; + /** + * Border's title. If border doesn't have any title then + * this member is null. + */ + private StringDescriptor myBorderTitle; + + protected RadContainer(final Module module, final String id){ + this(module, JPanel.class, id); + } + + protected RadContainer(final Module module, final Class aClass, final String id){ + super(module, aClass, id); + + myComponents = new ArrayList(); + myChangeListener = new MyPropertyChangeListener(); + + // By default container doesn't have any special border + setBorderType(BorderType.NONE); + + final AbstractLayout initialLayout = createInitialLayout(); + if (initialLayout != null){ + getDelegee().setLayout(initialLayout); + } + } + + public Property getInplaceProperty(final int x, final int y) { + // 1. We have to check whether user clicked inside border (if any) or not. + // In this case we have return inplace editor for border text + final Insets insets = getDelegee().getInsets(); // border insets + if( + x < insets.left || x > getWidth() - insets.right || + y < 0 || y > insets.top + ){ + return super.getInplaceProperty(x, y); + } + + // 2. Now we are sure that user clicked inside title area + return new MyBorderTitleProperty(); + } + + public Rectangle getInplaceEditorBounds(final Property property, final int x, final int y) { + if(property instanceof MyBorderTitleProperty){ // If this is our property + final MyBorderTitleProperty _property = (MyBorderTitleProperty)property; + final Insets insets = getDelegee().getInsets(); + return new Rectangle( + insets.left, + 0, + getWidth() - insets.left - insets.right, + _property.getPreferredSize().height + ); + } + return super.getInplaceEditorBounds(property, x, y); + } + + protected AbstractLayout createInitialLayout(){ + return new XYLayoutManagerImpl(); + } + + public final LayoutManager getLayout(){ + return getDelegee().getLayout(); + } + + public final void setLayout(final AbstractLayout layout) { + getDelegee().setLayout(layout); + + for (int i=0; i < getComponentCount(); i++) { + final RadComponent c = getComponent(i); + layout.addLayoutComponent(c.getDelegee(), c.getConstraints()); + } + } + + public final boolean isGrid(){ + return getLayout() instanceof GridLayoutManager; + } + + public final boolean isXY(){ + return getLayout() instanceof XYLayoutManager; + } + + /** + * @param component component to be added. + * + * @exception java.lang.IllegalArgumentException if component is null + * @exception java.lang.IllegalArgumentException if component already exist in the + * container + */ + public final void addComponent(final RadComponent component){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if (myComponents.contains(component)) { + throw new IllegalArgumentException("component is already added: " + component); + } + + final RadComponent[] oldChildren = myComponents.toArray(new RadComponent[myComponents.size()]); + + // Remove from old parent + final RadContainer oldParent=component.getParent(); + if(oldParent!=null){ + oldParent.removeComponent(component); + } + + // Attach to new parent + myComponents.add(component); + component.setParent(this); + addToDelegee(component); + + component.addPropertyChangeListener(myChangeListener); + + final RadComponent[] newChildren = myComponents.toArray(new RadComponent[myComponents.size()]); + firePropertyChanged(PROP_CHILDREN, oldChildren, newChildren); + } + + protected void addToDelegee(final RadComponent component){ + getDelegee().add(component.getDelegee(), component.getConstraints(), 0); + } + + /** + * Removes specified component from the container. + * This method also removes component's delegee from the + * container's delegee. Client code is responsible for revalidation + * of invalid Swing hierarchy. + * + * @param component component to be removed. + * + * @exception java.lang.IllegalArgumentException if component + * is null + * @exception java.lang.IllegalArgumentException if component + * doesn't exist in the container + */ + public final void removeComponent(final RadComponent component){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + if(!myComponents.contains(component)){ + throw new IllegalArgumentException("component is not added: " + component); + } + + // Remove child + component.removePropertyChangeListener(myChangeListener); + component.setParent(null); + myComponents.remove(component); + removeFromDelegee(component); + } + + protected void removeFromDelegee(final RadComponent component){ + getDelegee().remove(component.getDelegee()); + } + + public final RadComponent getComponent(final int index) { + return myComponents.get(index); + } + + public final int getComponentCount() { + return myComponents.size(); + } + + /** + * @return new array with all children + */ + public final RadComponent[] getComponents() { + return myComponents.toArray(new RadComponent[myComponents.size()]); + } + + public boolean canDrop(final int x, final int y, final int componentCount){ + if (isXY()) { + return true; + } + else if (isGrid()) { + // Do not allow to drop more then one component into grid + if (componentCount > 1) { + return false; + } + + final GridLayoutManager gridLayout = (GridLayoutManager)getLayout(); + final int row = gridLayout.getRowAt(y); + final int column = gridLayout.getColumnAt(x); + + // If target point doesn't belong to any cell and column then do not allow drop. + if (row == -1 || column == -1) { + return false; + } + + // If the target cell is not empty does not allow drop. + for(int i=0; i 0. Location + * @param dx shift of component relative to x + * @param dx shift of component relative to y + */ + public DropInfo drop(final int x, final int y, final RadComponent[] components, final int[] dx, final int[] dy){ + if (isXY()) { + int patchX = 0; + int patchY = 0; + + for (int i = 0; i < components.length; i++) { + final RadComponent c = components[i]; + + final Point p = new Point(x + dx[i], y + dy[i]); + c.setLocation(p); + + patchX = Math.min(patchX, p.x); + patchY = Math.min(patchY, p.y); + + addComponent(c); + } + + // shift components if necessary to make sure that no component has negative x or y + if (patchX < 0 || patchY < 0) { + for (int i = 0; i < components.length; i++) { + components[i].shift(-patchX, -patchY); + } + } + return new DropInfo(this, null, null); + } + else if (isGrid()) { + + // If target point doesn't belong to any cell and column + // then cancel drop. If the target cell is not empty + // then also cancel drop. + + final GridLayoutManager gridLayout = (GridLayoutManager)getLayout(); + final int row = gridLayout.getRowAt(y); + final int column = gridLayout.getColumnAt(x); + + // Prepare component for drop. + final RadComponent c = components[0]; + + if (c instanceof RadContainer) { + final LayoutManager layout = ((RadContainer)c).getLayout(); + if (layout instanceof XYLayoutManager) { + ((XYLayoutManager)layout).setPreferredSize(c.getSize()); + } + } + + final GridConstraints constraints = c.getConstraints(); + constraints.setRow(row); + constraints.setColumn(column); + constraints.setRowSpan(1); + constraints.setColSpan(1); + addComponent(c); + + // Fill DropInfo + final RevalidateInfo info = c.revalidate(); + + return new DropInfo(this, info.myContainer, info.myPreviousContainerSize); + } + else { + throw new IllegalStateException("unknown layout: " + getLayout()); + } + } + + /** + * @return border's type. The method never return null. + * + * @see com.intellij.uiDesigner.shared.BorderType + */ + public final BorderType getBorderType(){ + return myBorderType; + } + + /** + * @see com.intellij.uiDesigner.shared.BorderType + * + * @exception java.lang.IllegalArgumentException if type + * is null + */ + public final void setBorderType(final BorderType type){ + if(type==null){ + throw new IllegalArgumentException("type cannot be null"); + } + if(myBorderType==type){ + return; + } + myBorderType=type; + updateBorder(); + } + + /** + * @return border's title. If the container doesn't have any title then the + * method returns null. + */ + public final StringDescriptor getBorderTitle(){ + return myBorderTitle; + } + + /** + * @param title new border's title. null means that + * the containr doesn't have have titled border. + */ + public final void setBorderTitle(final StringDescriptor title){ + if(Comparing.equal(title,myBorderTitle)){ + return; + } + myBorderTitle = title; + updateBorder(); + } + + /** + * Updates delegee's border + */ + private void updateBorder(){ + final String title = ResourceBundleLoader.resolve(getModule(), myBorderTitle); + getDelegee().setBorder(myBorderType.createBorder(title)); + } + + /** + * Serializes container's border + */ + protected final void writeBorder(final XmlWriter writer){ + writer.startElement("border"); + try{ + writer.addAttribute("type", getBorderType().getId()); + if (getBorderTitle() != null) { + final StringDescriptor descriptor = getBorderTitle(); + if(descriptor.getValue() != null){ // direct value + writer.addAttribute("title", descriptor.getValue()); + } + else{ // via resource bundle + writer.addAttribute("title-resource-bundle", descriptor.getBundleName()); + writer.addAttribute("title-key", descriptor.getKey()); + } + + } + }finally{ + writer.endElement(); // border + } + } + + /** + * Serializes container's children + */ + protected final void writeChildren(final XmlWriter writer){ + // Children + writer.startElement("children"); + try{ + writeChildrenImpl(writer); + }finally{ + writer.endElement(); // children + } + } + + protected final void writeChildrenImpl(final XmlWriter writer){ + for (int i=0; i < getComponentCount(); i++) { + getComponent(i).write(writer); + } + } + + public void write(final XmlWriter writer) { + if (isXY()) { + writer.startElement("xy"); + } + else if (isGrid()) { + writer.startElement("grid"); + } + else { + throw new IllegalArgumentException("unknown layout: " + getLayout()); + } + try{ + writeId(writer); + writeBinding(writer); + + final AbstractLayout layout = (AbstractLayout)getLayout(); + if (isGrid()) { + final GridLayoutManager _layout = (GridLayoutManager)layout; + writer.addAttribute("row-count", _layout.getRowCount()); + writer.addAttribute("column-count", _layout.getColumnCount()); + + writer.addAttribute("same-size-horizontally", _layout.isSameSizeHorizontally()); + writer.addAttribute("same-size-vertically", _layout.isSameSizeVertically()); + } + // It has sense to save hpap and vgap even for XY layout. The reason is + // that XY was previously GRID with non default gaps, so when the user + // compose XY into the grid again then he will get the same non default gaps. + writer.addAttribute("hgap", layout.getHGap()); + writer.addAttribute("vgap", layout.getVGap()); + + // Margins + final Insets margin = layout.getMargin(); + writer.startElement("margin"); + try { + writer.addAttribute("top", margin.top); + writer.addAttribute("left", margin.left); + writer.addAttribute("bottom", margin.bottom); + writer.addAttribute("right", margin.right); + } + finally { + writer.endElement(); // margin + } + + // Constraints and properties + writeConstraints(writer); + writeProperties(writer); + + // Border + writeBorder(writer); + + // Children + writeChildren(writer); + }finally{ + writer.endElement(); // xy/grid + } + } + + /** + * Serializes child constraints into the currently opened "constraints" tag + */ + public void writeConstraints(final XmlWriter writer, final RadComponent child){ + if (child == null) { + throw new IllegalArgumentException("child cannot be null"); + } + if(child.getParent() != this){ + throw new IllegalArgumentException("parent mismatch: "+child.getParent()); + } + // Constraints of XY layout + writer.startElement("xy"); + try{ + writer.addAttribute("x", child.getX()); + writer.addAttribute("y", child.getY()); + writer.addAttribute("width", child.getWidth()); + writer.addAttribute("height", child.getHeight()); + }finally{ + writer.endElement(); // xy + } + + // Constraints in Grid layout + writer.startElement("grid"); + try { + final GridConstraints constraints = child.getConstraints(); + writer.addAttribute("row",constraints.getRow()); + writer.addAttribute("column",constraints.getColumn()); + writer.addAttribute("row-span",constraints.getRowSpan()); + writer.addAttribute("col-span",constraints.getColSpan()); + writer.addAttribute("vsize-policy",constraints.getVSizePolicy()); + writer.addAttribute("hsize-policy",constraints.getHSizePolicy()); + writer.addAttribute("anchor",constraints.getAnchor()); + writer.addAttribute("fill",constraints.getFill()); + + // preferred size + writer.writeDimension(constraints.myMinimumSize,"minimum-size"); + writer.writeDimension(constraints.myPreferredSize,"preferred-size"); + writer.writeDimension(constraints.myMaximumSize,"maximum-size"); + } finally { + writer.endElement(); // grid + } + } + + private final class MyPropertyChangeListener implements PropertyChangeListener{ + public void propertyChange(final PropertyChangeEvent e){ + if (RadComponent.PROP_SELECTED.equals(e.getPropertyName())) { + if (!((Boolean)e.getNewValue()).booleanValue()) { + return; + } + + if (getComponentCount() > 1 && isXY()) { + final RadComponent component = (RadComponent)e.getSource(); + final Rectangle bounds = component.getBounds(); + // We have to change Z order of the selected component only + // if this component intersects one of its siblings. + for(int i = getComponentCount() - 1; i >= 0; i--){ + final RadComponent _component = getComponent(i); + if(_component == component){ + continue; + } + if(bounds.intersects(_component.getBounds())){ + removeComponent(component); + addComponent(component); + // TODO[anton,vova] the change should be saved to document!!! + break; + } + } + } + } + } + } + + private final class MyBorderTitleProperty extends Property{ + private final StringEditor myEditor; + + public MyBorderTitleProperty() { + super(null, "Title"); + myEditor = new StringEditor(); + } + + public Dimension getPreferredSize(){ + return myEditor.getPreferredSize(); + } + + /** + * @return {@link StringDescriptor} + */ + public Object getValue(final RadComponent component) { + return myBorderTitle; + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception { + setBorderTitle((StringDescriptor)value); + } + + public Property[] getChildren() { + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer() { + return null; + } + + public PropertyEditor getEditor() { + return myEditor; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadErrorComponent.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadErrorComponent.java new file mode 100644 index 00000000000..92a26134912 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadErrorComponent.java @@ -0,0 +1,91 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.diagnostic.Logger; +import org.jdom.Element; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadErrorComponent extends RadAtomicComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.RadErrorComponent"); + + private final String myComponentClassName; + private final Element myProperties; + private final String myErrorDescription; + + public static RadErrorComponent create( + final Module module, + final String id, + final String componentClassName, + final Element properties, + final String errorDescription + ){ + return new RadErrorComponent(module, id, componentClassName, properties, errorDescription); + } + + /** + * @param properties can be null + * @param errorDescription + */ + private RadErrorComponent( + final Module module, + final String id, + final String componentClassName, + final Element properties, + final String errorDescription + ) { + super(module, MyComponent.class, id); + + LOG.assertTrue(componentClassName != null); + myComponentClassName = componentClassName; + + LOG.assertTrue(errorDescription != null); + myErrorDescription = errorDescription; + + myProperties = properties; + } + + public String getComponentClassName(){ + return myComponentClassName; + } + + public String getErrorDescription() { + return myErrorDescription; + } + + public void write(final XmlWriter writer) { + writer.startElement("component"); + try{ + writeId(writer); + + // write class + writer.addAttribute("class", myComponentClassName); + + writeBinding(writer); + writeConstraints(writer); + + // write properties (if any) + if(myProperties != null){ + writer.writeElement(myProperties); + } + }finally{ + writer.endElement(); // component + } + } + + private static final class MyComponent extends JComponent{ + public MyComponent(){ + setMinimumSize(new Dimension(20, 20)); + } + + public void paint(final Graphics g){ + g.setColor(Color.red); + g.fillRect(0,0,getWidth(),getHeight()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadHSpacer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadHSpacer.java new file mode 100644 index 00000000000..e749b20aaaa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadHSpacer.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadHSpacer extends RadAtomicComponent { + public RadHSpacer(final Module module, final String id) { + super(module, HSpacer.class, id); + } + + public void write(final XmlWriter writer) { + writer.startElement("hspacer"); + try{ + writeId(writer); + writeConstraints(writer); + }finally{ + writer.endElement(); // hspacer + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadRootContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadRootContainer.java new file mode 100644 index 00000000000..fde41d5b391 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadRootContainer.java @@ -0,0 +1,68 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.IRootContainer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadRootContainer extends RadContainer implements IRootContainer{ + private String myClassToBind; + private String myMainComponentBinding; + + public RadRootContainer(final Module module, final Class aClass, final String id){ + super(module, aClass, id); + } + + /** + * Always returns false because root group isn't selectable. + */ + public boolean isSelected() { + return false; + } + + /** + * RadRootContainer is not selectable + */ + public void setSelected(final boolean ignored) { } + + /** + * @return full qualified name of the class. If there is no bound class + * then the method returns null. + */ + public String getClassToBind(){ + return myClassToBind; + } + + public void setClassToBind(final String classToBind){ + myClassToBind = classToBind; + } + + public String getMainComponentBinding(){ + return myMainComponentBinding; + } + + public void setMainComponentBinding(final String mainComponentBinding){ + myMainComponentBinding = mainComponentBinding; + } + + public void write(final XmlWriter writer) { + writer.startElement("form", Utils.FORM_NAMESPACE); + try{ + writer.addAttribute("version", 1); + final String classToBind = getClassToBind(); + if (classToBind != null){ + writer.addAttribute("bind-to-class", classToBind); + } + final String mainComponentBinding = getMainComponentBinding(); + if (mainComponentBinding != null) { + writer.addAttribute("stored-main-component-binding", mainComponentBinding); + } + writeChildrenImpl(writer); + }finally{ + writer.endElement(); // form + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadScrollPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadScrollPane.java new file mode 100644 index 00000000000..206865d54b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadScrollPane.java @@ -0,0 +1,63 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.uiDesigner.core.AbstractLayout; + +import javax.swing.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadScrollPane extends RadContainer{ + public static final Class COMPONENT_CLASS = JScrollPane.class; + + public RadScrollPane(final Module module, final String id){ + super(module, COMPONENT_CLASS, id); + } + + protected AbstractLayout createInitialLayout(){ + return null; + } + + public boolean canDrop(final int x, final int y, final int componentCount){ + return componentCount == 1 && getComponentCount() == 0; + } + + public DropInfo drop(final int x, final int y, final RadComponent[] components, final int[] dx, final int[] dy){ + addComponent(components[0]); + return new DropInfo(this, null, null); + } + + protected void addToDelegee(final RadComponent component){ + final JScrollPane scrollPane = (JScrollPane)getDelegee(); + final JComponent delegee = component.getDelegee(); + delegee.setLocation(0,0); + scrollPane.setViewportView(delegee); + } + + protected void removeFromDelegee(final RadComponent component){ + final JScrollPane scrollPane = (JScrollPane)getDelegee(); + scrollPane.setViewportView(null); + } + + public void write(final XmlWriter writer) { + writer.startElement("scrollpane"); + try{ + writeId(writer); + writeBinding(writer); + + // Constraints and properties + writeConstraints(writer); + writeProperties(writer); + + // Margin and border + writeBorder(writer); + writeChildren(writer); + }finally{ + writer.endElement(); // scrollpane + } + } + + public void writeConstraints(final XmlWriter writer, final RadComponent child) {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadSplitPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadSplitPane.java new file mode 100644 index 00000000000..2a3bb00f1cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadSplitPane.java @@ -0,0 +1,100 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.lw.LwSplitPane; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadSplitPane extends RadContainer{ + public RadSplitPane(final Module module, final String id){ + super(module, JSplitPane.class, id); + } + + protected AbstractLayout createInitialLayout(){ + return null; + } + + public boolean canDrop(final int x, final int y, final int componentCount){ + if (componentCount != 1) { + return false; + } + + final Component component; + if (isLeft(x,y)) { + component = getSplitPane().getLeftComponent(); + } + else { + component = getSplitPane().getRightComponent(); + } + + return component == null || ((JComponent)component).getClientProperty(RadComponent.CLIENT_PROP_RAD_COMPONENT) == null; + } + + private boolean isLeft(final int x, final int y){ + final JSplitPane splitPane = getSplitPane(); + if (splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT) { + return y < splitPane.getHeight() / 2; + } + else { + return x < splitPane.getWidth() / 2; + } + } + + private JSplitPane getSplitPane(){ + return (JSplitPane)getDelegee(); + } + + public DropInfo drop(final int x, final int y, final RadComponent[] components, final int[] dx, final int[] dy){ + components[0].setCustomLayoutConstraints(isLeft(x,y) ? LwSplitPane.POSITION_LEFT : LwSplitPane.POSITION_RIGHT); + addComponent(components[0]); + return new DropInfo(this, null, null); + } + + protected void addToDelegee(final RadComponent component){ + final JSplitPane splitPane = getSplitPane(); + final JComponent delegee = component.getDelegee(); + if (LwSplitPane.POSITION_LEFT.equals(component.getCustomLayoutConstraints())){ + splitPane.setLeftComponent(delegee); + } + else { + splitPane.setRightComponent(delegee); + } + } + + public void write(final XmlWriter writer) { + writer.startElement("splitpane"); + try{ + writeId(writer); + writeBinding(writer); + + // Constraints and properties + writeConstraints(writer); + writeProperties(writer); + + // Margin and border + writeBorder(writer); + writeChildren(writer); + }finally{ + writer.endElement(); // scrollpane + } + } + + public void writeConstraints(final XmlWriter writer, final RadComponent child) { + writer.startElement("splitpane"); + try{ + final String position = (String)child.getCustomLayoutConstraints(); + if (!LwSplitPane.POSITION_LEFT.equals(position) && !LwSplitPane.POSITION_RIGHT.equals(position)) { + throw new IllegalStateException("invalid position: " + position); + } + writer.addAttribute("position", position); + }finally{ + writer.endElement(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadTabbedPane.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadTabbedPane.java new file mode 100644 index 00000000000..d482f906a7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadTabbedPane.java @@ -0,0 +1,204 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.lw.LwTabbedPane; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.plaf.TabbedPaneUI; +import java.awt.*; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadTabbedPane extends RadContainer{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.RadTabbedPane"); + /** + * value: HashMap + */ + private static final String CLIENT_PROP_INDEX_2_DESCRIPTOR = "index2descriptor"; + + public RadTabbedPane(final Module module, final String id){ + super(module, JTabbedPane.class, id); + } + + protected AbstractLayout createInitialLayout(){ + return null; + } + + public boolean canDrop(final int x, final int y, final int componentCount){ + return componentCount == 1; + } + + public DropInfo drop(final int x, final int y, final RadComponent[] components, final int[] dx, final int[] dy){ + addComponent(components[0]); + return new DropInfo(this, null, null); + } + + /** + * @return never returns null. + */ + private JTabbedPane getTabbedPane(){ + return (JTabbedPane)getDelegee(); + } + + protected void addToDelegee(final RadComponent component){ + final JTabbedPane tabbedPane = getTabbedPane(); + final String tabName; + if (component.getCustomLayoutConstraints() instanceof LwTabbedPane.Constraints) { + tabName = ((LwTabbedPane.Constraints)component.getCustomLayoutConstraints()).myTitle; + } + else { + tabName = "Untitled"; + } + component.setCustomLayoutConstraints(null); + tabbedPane.addTab(tabName, component.getDelegee()); + } + + protected void removeFromDelegee(final RadComponent component){ + final JTabbedPane tabbedPane = getTabbedPane(); + + final JComponent delegee = component.getDelegee(); + final int i = tabbedPane.indexOfComponent(delegee); + if (i == -1) { + throw new IllegalArgumentException("cannot find tab for " + component); + } + component.setCustomLayoutConstraints(new LwTabbedPane.Constraints(tabbedPane.getTitleAt(i))); + tabbedPane.removeTabAt(i); + } + + /** + * @return inplace property for editing of the title of the clicked tab + */ + public Property getInplaceProperty(final int x, final int y) { + final JTabbedPane tabbedPane = getTabbedPane(); + final TabbedPaneUI ui = tabbedPane.getUI(); + LOG.assertTrue(ui != null); + final int index = ui.tabForCoordinate(tabbedPane, x, y); + return index != -1 ? new MyTitleProperty(index) : null; + } + + public Rectangle getInplaceEditorBounds(final Property property, final int x, final int y) { + final JTabbedPane tabbedPane = getTabbedPane(); + final TabbedPaneUI ui = tabbedPane.getUI(); + LOG.assertTrue(ui != null); + final int index = ui.tabForCoordinate(tabbedPane, x, y); + LOG.assertTrue(index != -1); + final Rectangle tabBounds = ui.getTabBounds(tabbedPane, index); + return tabBounds; + } + + /** + * This allows user to select and scroll tabs via the mouse + */ + public void processMouseEvent(final MouseEvent event){ + event.getComponent().dispatchEvent(event); + } + + public void write(final XmlWriter writer) { + writer.startElement("tabbedpane"); + try{ + writeId(writer); + writeBinding(writer); + + // Constraints and properties + writeConstraints(writer); + writeProperties(writer); + + writeBorder(writer); + writeChildren(writer); + }finally{ + writer.endElement(); + } + } + + public void writeConstraints(final XmlWriter writer, final RadComponent child) { + writer.startElement("tabbedpane"); + try{ + final JComponent delegee = child.getDelegee(); + final JTabbedPane tabbedPane = getTabbedPane(); + final int i = tabbedPane.indexOfComponent(delegee); + if (i == -1) { + throw new IllegalArgumentException("cannot find tab for " + child); + } + + final String title = tabbedPane.getTitleAt(i); + writer.addAttribute("title", title != null ? title : ""); + }finally{ + writer.endElement(); + } + } + + /** + * @return never returns null. + */ + private HashMap getIndex2Descriptor(final RadComponent component){ + HashMap index2Descriptor = (HashMap)component.getClientProperty(CLIENT_PROP_INDEX_2_DESCRIPTOR); + if(index2Descriptor == null){ + index2Descriptor = new HashMap(); + component.putClientProperty(CLIENT_PROP_INDEX_2_DESCRIPTOR, index2Descriptor); + } + return index2Descriptor; + } + + private final class MyTitleProperty extends Property{ + /** + * Index of tab which title should be edited + */ + private final int myIndex; + private final StringEditor myEditor; + + public MyTitleProperty(final int index) { + super(null, "Title"); + myIndex = index; + myEditor = new StringEditor(); + } + + public Object getValue(final RadComponent component) { + // 1. resource bundle + final StringDescriptor descriptor = getIndex2Descriptor(component).get(new Integer(myIndex)); + if(descriptor != null){ + return descriptor; + } + + // 2. plain value + return StringDescriptor.create(getTabbedPane().getTitleAt(myIndex)); + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception { + // 1. Put value into map + final StringDescriptor descriptor = (StringDescriptor)value; + final HashMap index2Descriptor = getIndex2Descriptor(component); + if(descriptor == null || descriptor.getBundleName() == null){ + index2Descriptor.remove(new Integer(myIndex)); + } + else{ + index2Descriptor.put(new Integer(myIndex), descriptor); + } + + // 2. Apply real string value to JComponent peer + getTabbedPane().setTitleAt(myIndex, ResourceBundleLoader.resolve(getModule(), descriptor)); + } + + public Property[] getChildren() { + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer() { + throw new UnsupportedOperationException(); + } + + public PropertyEditor getEditor() { + return myEditor; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadVSpacer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadVSpacer.java new file mode 100644 index 00000000000..d78c082fbf3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/RadVSpacer.java @@ -0,0 +1,24 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.module.Module; + + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RadVSpacer extends RadAtomicComponent { + public RadVSpacer(final Module module, final String id) { + super(module, VSpacer.class, id); + } + + public void write(final XmlWriter writer) { + writer.startElement("vspacer"); + try{ + writeId(writer); + writeConstraints(writer); + }finally{ + writer.endElement(); // vspacer + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ResizeProcessor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ResizeProcessor.java new file mode 100644 index 00000000000..4bf070867a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/ResizeProcessor.java @@ -0,0 +1,124 @@ +package com.intellij.uiDesigner; + +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.Util; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ResizeProcessor extends EventProcessor{ + private RadComponent myComponent; + private int myResizeMask; + private Point myLastPoint; + private Rectangle myBounds; + private Rectangle myOriginalBounds; + private final GuiEditor myEditor; + + public ResizeProcessor(final GuiEditor editor, final RadComponent component, final int resizeMask){ + myEditor = editor; + if (component.getParent() == null) { + throw new IllegalArgumentException("parent is null for " + component); + } + + if (!component.getParent().isXY()) { + throw new IllegalArgumentException("parent must be XY; component=" + component); + } + + myComponent = component; + myResizeMask = resizeMask; + + setCursor(Cursor.getPredefinedCursor(Painter.getResizeCursor(resizeMask))); + } + + protected void processKeyEvent(final KeyEvent e){} + + protected void processMouseEvent(final MouseEvent e){ + + if (e.getID() == MouseEvent.MOUSE_PRESSED) { + myLastPoint = e.getPoint(); + myBounds = myComponent.getBounds(); + myOriginalBounds = new Rectangle(myBounds); + } + else if(e.getID()==MouseEvent.MOUSE_DRAGGED){ + + final int dx = e.getX() - myLastPoint.x; + final int dy = e.getY() - myLastPoint.y; + + final GridConstraints constraints = myComponent.getConstraints(); + + if ((myResizeMask & Painter.WEST_MASK) != 0) { + myBounds.x += dx; + myBounds.width -= dx; + } + if ((myResizeMask & Painter.EAST_MASK) != 0) { + myBounds.width += dx; + } + if ((myResizeMask & Painter.NORTH_MASK) != 0) { + myBounds.y += dy; + myBounds.height -= dy; + } + if ((myResizeMask & Painter.SOUTH_MASK) != 0) { + myBounds.height += dy; + } + + final Dimension minSize = myComponent.getMinimumSize(); + + final Rectangle newBounds = myComponent.getBounds(); + + // Component's bounds cannot be less the some minimum size + if (myBounds.width >= minSize.width) { + newBounds.x = myBounds.x; + newBounds.width = myBounds.width; + } + else { + if((myResizeMask & Painter.WEST_MASK) != 0){ + newBounds.x = newBounds.x+newBounds.width-minSize.width; + newBounds.width = minSize.width; + } + else if ((myResizeMask & Painter.EAST_MASK) != 0) { + newBounds.width = minSize.width; + } + } + + if (myBounds.height >= minSize.height) { + newBounds.y = myBounds.y; + newBounds.height = myBounds.height; + } + else { + if ((myResizeMask & Painter.NORTH_MASK) != 0) { + newBounds.y = newBounds.y + newBounds.height - minSize.height; + newBounds.height = minSize.height; + } + else if ((myResizeMask & Painter.SOUTH_MASK) != 0) { + newBounds.height = minSize.height; + } + } + + final Dimension size = newBounds.getSize(); + Util.adjustSize(myComponent.getDelegee(), constraints, size); + newBounds.width = size.width; + newBounds.height = size.height; + + myComponent.setBounds(newBounds); + + myEditor.refresh(); + + myLastPoint=e.getPoint(); + } + else if (e.getID() == MouseEvent.MOUSE_RELEASED) { + myEditor.refreshAndSave(true); + } + + } + + protected boolean cancelOperation(){ + myComponent.setBounds(myOriginalBounds); + myEditor.refresh(); + return true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionState.java new file mode 100644 index 00000000000..ad97fc82045 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionState.java @@ -0,0 +1,63 @@ +package com.intellij.uiDesigner; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.uiDesigner.componentTree.ComponentPtr; +import com.intellij.uiDesigner.componentTree.ComponentSelectionListener; + +import java.util.ArrayList; +import java.util.Stack; + +/** + * This class implements Ctrl+W / Ctrl+Shift+W functionality in the GuiEditor + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class SelectionState{ + private final Stack mySelectionHistory; + /** We do not need to handle our own events */ + private boolean myInsideChange; + + SelectionState(final GuiEditor editor) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + mySelectionHistory = new Stack(); + editor.addComponentSelectionListener(new MyComponentSelectionListener()); + } + + public boolean isInsideChange(){ + ApplicationManager.getApplication().isDispatchThread(); + return myInsideChange; + } + + public void setInsideChange(final boolean insideChange){ + ApplicationManager.getApplication().isDispatchThread(); + myInsideChange = insideChange; + } + + public Stack getSelectionHistory() { + return mySelectionHistory; + } + + public static ComponentPtr[] getPtrs(final GuiEditor editor){ + final ArrayList selection = FormEditingUtil.getAllSelectedComponents(editor); + final ComponentPtr[] ptrs = new ComponentPtr[selection.size()]; + for(int i = selection.size() - 1; i >= 0; i--){ + ptrs[i] = new ComponentPtr(editor, selection.get(i)); + } + return ptrs; + } + + private final class MyComponentSelectionListener implements ComponentSelectionListener{ + + public void selectedComponentChanged(final GuiEditor source) { + if(myInsideChange){ // do not react on own events + return; + } + mySelectionHistory.clear(); + mySelectionHistory.push(getPtrs(source)); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionWatcher.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionWatcher.java new file mode 100644 index 00000000000..786de4edef5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/SelectionWatcher.java @@ -0,0 +1,64 @@ +package com.intellij.uiDesigner; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class SelectionWatcher { + private final MyPropertyChangeListener myChangeListener; + + public SelectionWatcher(){ + myChangeListener = new MyPropertyChangeListener(); + } + + public final void install(final RadComponent component){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + component.addPropertyChangeListener(myChangeListener); + if(component instanceof RadContainer){ + final RadContainer container = (RadContainer)component; + for(int i = container.getComponentCount() - 1; i>= 0; i--){ + install(container.getComponent(i)); + } + } + } + + public final void deinstall(final RadComponent component){ + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + component.removePropertyChangeListener(myChangeListener); + if(component instanceof RadContainer){ + final RadContainer container = (RadContainer)component; + for(int i = container.getComponentCount() - 1; i>= 0; i--){ + deinstall(container.getComponent(i)); + } + } + } + + protected abstract void selectionChanged(RadComponent component, boolean selected); + + private final class MyPropertyChangeListener implements PropertyChangeListener{ + public void propertyChange(final PropertyChangeEvent e) { + if(RadComponent.PROP_SELECTED.equals(e.getPropertyName())){ + final Boolean selected = (Boolean)e.getNewValue(); + selectionChanged((RadComponent)e.getSource(), selected.booleanValue()); + } + else if(RadContainer.PROP_CHILDREN.equals(e.getPropertyName())){ + final RadComponent[] oldChildren = (RadComponent[])e.getOldValue(); + for(int i = oldChildren.length - 1; i >= 0; i--){ + deinstall(oldChildren[i]); + } + + final RadComponent[] newChildren = (RadComponent[])e.getNewValue(); + for(int i = newChildren.length - 1; i >= 0; i--){ + install(newChildren[i]); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/VSpacer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/VSpacer.java new file mode 100644 index 00000000000..ba20388b618 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/VSpacer.java @@ -0,0 +1,91 @@ +package com.intellij.uiDesigner; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class VSpacer extends DesignSpacer{ + public VSpacer(){ + setSize(getHandleWidth(), 50); + } + + private static int getHandleWidth(){ + return HANDLE_ATOM_HEIGHT*3 + HANDLE_ATOM_SPACE*2; + } + + private static int getHandleHeight(){ + return HANDLE_ATOM_WIDTH; + } + + protected void paintComponent(final Graphics g){ + final int handleHeight=getHandleHeight(); + final int handleWidth=getHandleWidth(); + + // Paint top handle + final int x=(getWidth()-handleWidth)/2; + drawHandle(g,x,0); + g.setColor(ourColor1); + g.drawLine(x+handleWidth/2,handleHeight,x+handleWidth/2,handleHeight+1); + + // Paint bottom handle + final int y=getHeight()-handleHeight-1; + drawHandle(g,x,y); + g.drawLine(x+handleWidth/2,y-2,x+handleWidth/2,y); + g.setColor(ourColor1); + + // Draw spring + drawSpring(g,x+handleWidth/2,handleHeight+1,getHeight()-2*handleHeight-4); + } + + /** + * Paints small spacer's haldle. (x,y) is a top + * left point of a handle. + */ + private static void drawHandle(final Graphics g,int x,final int y){ + g.setColor(ourColor1); + + g.drawRect(x,y,HANDLE_ATOM_HEIGHT-1,HANDLE_ATOM_WIDTH-1); + g.drawLine( + x+HANDLE_ATOM_HEIGHT, + y+HANDLE_ATOM_WIDTH/2, + x+HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE-1, + y+HANDLE_ATOM_WIDTH/2 + ); + + x+=HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE; + + g.drawRect(x,y,HANDLE_ATOM_HEIGHT-1,HANDLE_ATOM_WIDTH-1); + g.drawLine( + x+HANDLE_ATOM_HEIGHT, + y+HANDLE_ATOM_WIDTH/2, + x+HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE-1, + y+HANDLE_ATOM_WIDTH/2 + ); + + x+=HANDLE_ATOM_HEIGHT+HANDLE_ATOM_SPACE; + + g.drawRect(x,y,HANDLE_ATOM_HEIGHT-1,HANDLE_ATOM_WIDTH-1); + } + + private static void drawSpring(final Graphics g,final int x,final int y,final int height){ + for(int _y=y;_y\n"); + } + + public String getText(){ + return myBuffer.toString(); + } + + public void writeDimension(final Dimension dimension, final String elementName) { + if (dimension.width == -1 && dimension.height == -1) { + return; + } + startElement(elementName); + try { + addAttribute("width", dimension.width); + addAttribute("height", dimension.height); + } + finally { + endElement(); + } + } + + public void startElement(final String elementName){ + startElement(elementName, null); + } + + public void startElement(final String elementName, final String namespace){ + if (myElementNames.size() > 0) { + if(!((Boolean)myElementHasBody.peek()).booleanValue()){ + myBuffer.append(">\n"); + } + myElementHasBody.set(myElementHasBody.size()-1,Boolean.TRUE); + } + + writeSpaces(myElementNames.size()*INDENT); + myBuffer.append("<").append(elementName); + + if (namespace != null) { + myBuffer.append(" xmlns=\"").append(namespace).append('"'); + } + + myElementNames.push(elementName); + myElementHasBody.push(Boolean.FALSE); + } + + public void endElement() { + final String elementName = (String)myElementNames.peek(); + final boolean hasBody = ((Boolean)myElementHasBody.peek()).booleanValue(); + + myElementNames.pop(); + myElementHasBody.pop(); + + if (hasBody) { + writeSpaces(myElementNames.size()*INDENT); + myBuffer.append("\n"); + } else { + myBuffer.append("/>\n"); + } + } + + /** + * Helper method + */ + private void addAttributeImpl(final String name,final String value){ + myBuffer.append(' ').append(name).append("=\"").append(value).append('"'); + } + + /** + * Helper method + */ + public void addAttribute(final String name, final String value){ + addAttributeImpl(name, XmlUtil.escapeString(value)); + } + + /** + * Helper method + */ + public void addAttribute(final String name, final int value){ + addAttributeImpl(name, Integer.toString(value)); + } + + /** + * Helper method + */ + public void addAttribute(final String name, final boolean value){ + addAttributeImpl(name, Boolean.toString(value)); + } + + + public void writeElement(final Element element){ + startElement(element.getName()); + try { + for (Iterator iterator = element.getAttributes().iterator(); iterator.hasNext();) { + final Attribute attribute = (Attribute)iterator.next(); + addAttribute(attribute.getName(), attribute.getValue()); + } + for (Iterator iterator = element.getChildren().iterator(); iterator.hasNext(); ){ + final Element child = (Element)iterator.next(); + writeElement(child); + } + } + finally { + endElement(); + } + } + + /** + * Helper method + */ + private void writeSpaces(final int count){ + for (int i=0; i < count; i++) { + myBuffer.append(' '); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/AbstractMoveSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/AbstractMoveSelectionAction.java new file mode 100644 index 00000000000..8ef5660cfa9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/AbstractMoveSelectionAction.java @@ -0,0 +1,123 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.RadAtomicComponent; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.GuiEditor; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +abstract class AbstractMoveSelectionAction extends AnAction{ + private static final Logger LOG=Logger.getInstance("#com.intellij.uiDesigner.actions.MoveSelectionToRightAction"); + + private final GuiEditor myEditor; + + public AbstractMoveSelectionAction(final GuiEditor editor) { + LOG.assertTrue(editor != null); + myEditor = editor; + } + + public final void actionPerformed(final AnActionEvent e) { + final ArrayList selectedComponents = FormEditingUtil.getSelectedComponents(myEditor); + final JComponent rootContainerDelegee = myEditor.getRootContainer().getDelegee(); + if(selectedComponents.size() == 0){ + final int[] minX = new int[]{Integer.MAX_VALUE}; + final int[] minY = new int[]{Integer.MAX_VALUE}; + final RadComponent[] componentToBeSelected = new RadComponent[1]; + FormEditingUtil.iterate( + myEditor.getRootContainer(), + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if (component instanceof RadAtomicComponent) { + final JComponent _delegee = component.getDelegee(); + final Point p = SwingUtilities.convertPoint( + _delegee, + new Point(0, 0), + rootContainerDelegee + ); + if(minX[0] > p.x || minY[0] > p.y){ + minX[0] = p.x; + minY[0] = p.y; + componentToBeSelected[0] = component; + } + } + return true; + } + } + ); + if(componentToBeSelected[0] != null){ + componentToBeSelected[0].setSelected(true); + } + return; + } + final RadComponent selectedComponent = selectedComponents.get(0); + + // 1. We need to get coordinates of all editor's component in the same + // coordinate system. For example, in the RadRootContainer rootContainerDelegee's coordinate system. + + final ArrayList components = new ArrayList(); + final ArrayList points = new ArrayList(); + FormEditingUtil.iterate( + myEditor.getRootContainer(), + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if (component instanceof RadAtomicComponent) { + if(selectedComponent.equals(component)){ + return true; + } + components.add(component); + final JComponent _delegee = component.getDelegee(); + final Point p = SwingUtilities.convertPoint( + _delegee, + new Point(0, 0), + rootContainerDelegee + ); + p.x += _delegee.getWidth() / 2; + p.y += _delegee.getHeight() / 2; + points.add(p); + } + return true; + } + } + ); + if(components.size() == 0){ + return; + } + + // 2. + final Point source = SwingUtilities.convertPoint( + selectedComponent.getDelegee(), + new Point(0, 0), + rootContainerDelegee + ); + source.x += selectedComponent.getDelegee().getWidth() / 2; + source.y += selectedComponent.getDelegee().getHeight() / 2; + int min = Integer.MAX_VALUE; + int nextSelectedIndex = -1; + for(int i = points.size() - 1; i >= 0; i--){ + final int distance = calcDistance(source, points.get(i)); + if(distance < min){ + min = distance; + nextSelectedIndex = i; + } + } + if(min == Integer.MAX_VALUE){ + return; + } + + LOG.assertTrue(nextSelectedIndex != -1); + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + components.get(nextSelectedIndex).setSelected(true); + } + + protected abstract int calcDistance(Point source, Point point); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/CreateDialogAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/CreateDialogAction.java new file mode 100644 index 00000000000..a8dfb85b25b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/CreateDialogAction.java @@ -0,0 +1,256 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.ide.IdeView; +import com.intellij.ide.actions.CreateElementActionBase; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.Icons; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class CreateDialogAction extends CreateElementActionBase { + private boolean myRecentGenerateOK; + private boolean myRecentGenerateCancel; + private boolean myRecentGenerateMain; + + public CreateDialogAction() { + super("Create Dialog Class", "Create new class implementing javax.swing.JDialog", Icons.UI_FORM_ICON); + } + + protected PsiElement[] invokeDialog(final Project project, final PsiDirectory directory) { + final MyInputValidator validator = new MyInputValidator(project, directory); + + final MyContentPane contentPane = new MyContentPane(); + + final DialogWrapper dialog = new DialogWrapper(project, true) { + { + init(); + setTitle("New Dialog"); + } + protected JComponent createCenterPanel() { + return contentPane.getPanel(); + } + + protected void doOKAction() { + myRecentGenerateOK = contentPane.myChkGenerateOK.isSelected(); + myRecentGenerateCancel = contentPane.myChkGenerateCancel.isSelected(); + myRecentGenerateMain = contentPane.myChkGenerateMain.isSelected(); + + final String inputString = contentPane.myTfClassName.getText().trim(); + if ( + validator.checkInput(inputString) && + validator.canClose(inputString) + ) { + close(OK_EXIT_CODE); + } + } + + public JComponent getPreferredFocusedComponent() { + return contentPane.myTfClassName; + } + }; + + dialog.show(); + + return validator.getCreatedElements(); + } + + protected String getCommandName() { + return "Create class"; + } + + protected void checkBeforeCreate(final String newName, final PsiDirectory directory) throws IncorrectOperationException { + directory.checkCreateClass(newName); + } + + protected String getErrorTitle() { + return "Cannot Create Dialog"; + } + + public void update(final AnActionEvent e) { + super.update(e); + final DataContext dataContext = e.getDataContext(); + final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Presentation presentation = e.getPresentation(); + if (presentation.isEnabled()) { + final IdeView view = (IdeView)dataContext.getData(DataConstantsEx.IDE_VIEW); + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final PsiDirectory[] dirs = view.getDirectories(); + for (int i = 0; i < dirs.length; i++) { + final PsiDirectory dir = dirs[i]; + if (projectFileIndex.isInSourceContent(dir.getVirtualFile()) && dir.getPackage() != null) { + return; + } + } + + presentation.setEnabled(false); + presentation.setVisible(false); + } + } + + protected String getActionName(final PsiDirectory directory, final String newName) { + return "Creating class " + directory.getPackage().getQualifiedName() + "." + newName; + } + + private final static String createClassBody( + final String className, + final boolean generateOK, + final boolean generateCancel, + final boolean generateMain + ) { + final StringBuffer result = new StringBuffer(1024); + + result.append("public class " + className + " extends javax.swing.JDialog {\n"); + result.append("private javax.swing.JPanel contentPane;\n"); + result.append("private javax.swing.JButton buttonOK;\n"); + result.append("private javax.swing.JButton buttonCancel;\n"); + result.append("\n"); + result.append("public " + className + "(){\n"); + result.append("setContentPane(contentPane);\n"); + result.append("setModal(true);\n"); + result.append("getRootPane().setDefaultButton(buttonOK);\n"); + + if (generateOK) { + result.append("\n"); + result.append("buttonOK.addActionListener("); + result.append("new java.awt.event.ActionListener(){"); + result.append("public void actionPerformed(java.awt.event.ActionEvent e){"); + result.append("onOK();"); + result.append("}});\n"); + } + + if (generateCancel) { + result.append("\n"); + result.append("buttonCancel.addActionListener("); + result.append("new java.awt.event.ActionListener(){"); + result.append("public void actionPerformed(java.awt.event.ActionEvent e){"); + result.append("onCancel();"); + result.append("}});\n"); + result.append("\n"); + result.append(" // call onCancel() when cross is clicked\n"); + result.append("setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);\n"); + result.append("addWindowListener(new java.awt.event.WindowAdapter() {\n"); + result.append(" public void windowClosing(java.awt.event.WindowEvent e) {\n"); + result.append(" onCancel();\n"); + result.append(" }\n"); + result.append("});\n"); + result.append("\n"); + result.append(" // call onCancel() on ESCAPE\n"); + result.append("contentPane.registerKeyboardAction("); + result.append(" new java.awt.event.ActionListener() {"); + result.append(" public void actionPerformed(java.awt.event.ActionEvent e) {"); + result.append(" onCancel();\n"); + result.append(" }"); + result.append(" },"); + result.append(" KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0),"); + result.append(" javax.swing.JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT"); + result.append(");"); + } + + result.append("}\n"); + + if (generateOK) { + result.append("\n"); + result.append("private void onOK(){\n"); + result.append(" // add your code here\n"); + result.append("dispose();\n"); + result.append("}\n"); + } + + if (generateCancel) { + result.append("\n"); + result.append("private void onCancel(){\n"); + result.append(" // add your code here if necessary\n"); + result.append("dispose();\n"); + result.append("}\n"); + } + + if (generateMain) { + result.append("\n"); + result.append("public static void main(String[] args){\n"); + result.append(className + " dialog = new " + className + "();\n"); + result.append("dialog.pack();\n"); + result.append("dialog.show();\n"); + result.append("System.exit(0);\n"); + result.append("}\n"); + } + + result.append("}\n"); + + return result.toString(); + } + + private final String createFormBody(final String fullQualifiedClassName) throws IncorrectOperationException { + + final String resource = "/com/intellij/uiDesigner/NewDialog.xml"; + final InputStream inputStream = getClass().getResourceAsStream(resource); + + final StringBuffer buffer = new StringBuffer(); + try { + for (int ch; (ch = inputStream.read()) != -1;) { + buffer.append((char)ch); + } + } + catch (IOException e) { + throw new IncorrectOperationException("Cannot read " + resource); + } + + String s = buffer.toString(); + + s = StringUtil.replace(s, "$CLASS$", fullQualifiedClassName); + + return s; + } + + + protected PsiElement[] create(final String newName, final PsiDirectory directory) throws IncorrectOperationException { + PsiFile sourceFile = directory.getManager().getElementFactory().createFileFromText(newName + ".java", createClassBody(newName, myRecentGenerateOK, myRecentGenerateCancel, myRecentGenerateMain)); + sourceFile = (PsiFile)directory.add(sourceFile); + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(directory.getProject()); + codeStyleManager.shortenClassReferences(sourceFile); + codeStyleManager.reformat(sourceFile); + + final PsiPackage aPackage = directory.getPackage(); + final String packageName = aPackage.getQualifiedName(); + final String fqClassName = packageName.length() == 0 ? newName : packageName + "." + newName; + + final PsiFile formFile = directory.getManager().getElementFactory().createFileFromText(newName + ".form", createFormBody(fqClassName)); + PsiElement createdFile = directory.add(formFile); + + PsiClass[] classes = ((PsiJavaFile)sourceFile).getClasses(); + return new PsiElement[]{createdFile, classes[0]}; + } + + private static final class MyContentPane { + private JPanel myPanel; + private JCheckBox myChkGenerateCancel; + private JCheckBox myChkGenerateOK; + private JCheckBox myChkGenerateMain; + private JTextField myTfClassName; + + public MyContentPane() { + } + + public JPanel getPanel() { + return myPanel; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/DataBindingWizardAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/DataBindingWizardAction.java new file mode 100644 index 00000000000..204742cda6e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/DataBindingWizardAction.java @@ -0,0 +1,169 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.lw.LwComponent; +import com.intellij.uiDesigner.lw.LwContainer; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.uiDesigner.wizard.DataBindingWizard; +import com.intellij.uiDesigner.wizard.Generator; +import com.intellij.uiDesigner.wizard.WizardData; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class DataBindingWizardAction extends AnAction{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.actions.DataBindingWizardAction"); + + private final GuiEditor myEditor; + + public DataBindingWizardAction() { + myEditor = null; + } + + public DataBindingWizardAction(final GuiEditor editor) { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_DATA_BINDING_WIZARD)); + myEditor = editor; + } + + public void actionPerformed(final AnActionEvent e) { + final Project project; + final VirtualFile formFile; + if (myEditor == null) { + final DataContext context = e.getDataContext(); + project = (Project)context.getData(DataConstants.PROJECT); + formFile = (VirtualFile)context.getData(DataConstants.VIRTUAL_FILE); + } + else { + project = myEditor.getProject(); + formFile = myEditor.getFile(); + } + + try { + final WizardData wizardData = new WizardData(project, formFile); + + + final Module module = ModuleUtil.getModuleForFile(wizardData.myProject, formFile); + LOG.assertTrue(module != null); + + final LwRootContainer[] rootContainer = new LwRootContainer[1]; + Generator.exposeForm(wizardData.myProject, formFile, rootContainer); + final String classToBind = rootContainer[0].getClassToBind(); + if (classToBind == null) { + Messages.showInfoMessage( + project, + "Nothing to do. Form should be bound to a class.", + "Data Binding Wizard" + ); + return; + } + + final PsiClass boundClass = FormEditingUtil.findClassToBind(module, classToBind); + if(boundClass == null){ + Messages.showErrorDialog( + project, + "Form is bound to class " + classToBind + " that is not found.", + "Data Binding Wizard" + ); + return; + } + + Generator.prepareWizardData(wizardData, boundClass); + + if(!hasBinding(rootContainer[0])){ + Messages.showInfoMessage( + project, + "Nothing to do. Form should contain at least one bound component.", + "Data Binding Wizard" + ); + return; + } + + if (!wizardData.myBindToNewBean) { + final String[] variants = new String[]{"Alter Data Binding", "Bind to Another Bean", "Cancel"}; + final int result = Messages.showDialog( + project, + "Data binding to " + wizardData.myBeanClass.getQualifiedName() + " found.\n" + + "If you continue, generated methods will be re-generated.\n" + + "\n", + "Data Binding", + variants, + 0, + Messages.getQuestionIcon() + ); + if (result == 0) { + // do nothing here + } + else if (result == 1) { + wizardData.myBindToNewBean = true; + } + else { + return; + } + } + + final DataBindingWizard wizard = new DataBindingWizard(project, formFile, wizardData); + wizard.show(); + } + catch (Generator.MyException exc) { + Messages.showErrorDialog( + project, + exc.getMessage(), + "Error" + ); + } + } + + public void update(final AnActionEvent e) { + if (myEditor != null) { + e.getPresentation().setEnabled(true); + return; + } + + final DataContext context = e.getDataContext(); + final Project project = (Project)context.getData(DataConstants.PROJECT); + if(project == null){ + e.getPresentation().setEnabled(false); + return; + } + + final VirtualFile vFile = (VirtualFile)context.getData(DataConstants.VIRTUAL_FILE); + final FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(vFile); + if(!StdFileTypes.GUI_DESIGNER_FORM.equals(fileType)){ + e.getPresentation().setEnabled(false); + return; + } + + e.getPresentation().setEnabled(true); + } + + + private static boolean hasBinding(final LwComponent component) { + if (component.getBinding() != null) { + return true; + } + + if (component instanceof LwContainer) { + final LwContainer container = (LwContainer)component; + for (int i=0; i < container.getComponentCount(); i++) { + if (hasBinding((LwComponent)container.getComponent(i))) { + return true; + } + } + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ExpandSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ExpandSelectionAction.java new file mode 100644 index 00000000000..0e97d47aca0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ExpandSelectionAction.java @@ -0,0 +1,81 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.uiDesigner.*; +import com.intellij.uiDesigner.componentTree.ComponentPtr; + +import java.util.Stack; + +/** + * For each component selects all non selected siblings (if any). If + * all component's siblings are already selected then selects component's + * parent (if any). + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ExpandSelectionAction extends AnAction{ + /** Invoked by reflection */ + public ExpandSelectionAction() {} + + public void actionPerformed(final AnActionEvent e) { + final GuiEditor editor = GuiEditorUtil.getEditorFromContext(e.getDataContext()); + final SelectionState selectionState = editor.getSelectionState(); + selectionState.setInsideChange(true); + + final Stack history = selectionState.getSelectionHistory(); + + try{ + final ComponentPtr[] ptrs = history.peek(); + for(int i = ptrs.length - 1; i >= 0; i--){ + // Skip invalid components + final ComponentPtr ptr = ptrs[i]; + ptr.validate(); + if(!ptr.isValid()){ + continue; + } + + // Extend selection + final RadComponent component = ptr.getComponent(); + final RadContainer parent = component.getParent(); + if(parent == null){ // skip components without parents + continue; + } + boolean shouldSelectParent = true; + for(int j = parent.getComponentCount() - 1; j >= 0; j--){ + final RadComponent sibling = parent.getComponent(j); + if(!sibling.isSelected()){ + shouldSelectParent = false; + sibling.setSelected(true); + } + } + if(shouldSelectParent){ + parent.setSelected(true); + } + } + + // Store new selection + history.push(SelectionState.getPtrs(editor)); + }finally{ + selectionState.setInsideChange(false); + } + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final GuiEditor editor = GuiEditorUtil.getEditorFromContext(e.getDataContext()); + + if(editor == null){ + presentation.setEnabled(false); + return; + } + + final SelectionState selectionState = editor.getSelectionState(); + selectionState.setInsideChange(true); + final Stack history = selectionState.getSelectionHistory(); + + presentation.setEnabled(!history.isEmpty()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToDownAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToDownAction.java new file mode 100644 index 00000000000..be98a6932f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToDownAction.java @@ -0,0 +1,25 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.uiDesigner.GuiEditor; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MoveSelectionToDownAction extends AbstractMoveSelectionAction{ + public MoveSelectionToDownAction(final GuiEditor editor) { + super(editor); + } + + protected int calcDistance(final Point source, final Point point) { + if(source.y >= point.y){ + return Integer.MAX_VALUE; + } + else{ + final int scale = (point.x - source.x) >= 0 ? 3 : 4; + return (point.y - source.y) + Math.abs(point.x - source.x) * scale; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToLeftAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToLeftAction.java new file mode 100644 index 00000000000..8015c38729f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToLeftAction.java @@ -0,0 +1,25 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.uiDesigner.GuiEditor; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MoveSelectionToLeftAction extends AbstractMoveSelectionAction{ + public MoveSelectionToLeftAction(final GuiEditor editor) { + super(editor); + } + + protected int calcDistance(final Point source, final Point point) { + if(source.x <= point.x){ + return Integer.MAX_VALUE; + } + else{ + final int scale = (point.y - source.y) >= 0 ? 3 : 4; + return (source.x - point.x) + Math.abs(point.y - source.y) * scale; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToRightAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToRightAction.java new file mode 100644 index 00000000000..cd63c1aead0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToRightAction.java @@ -0,0 +1,25 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.uiDesigner.GuiEditor; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MoveSelectionToRightAction extends AbstractMoveSelectionAction{ + public MoveSelectionToRightAction(final GuiEditor editor) { + super(editor); + } + + protected int calcDistance(final Point source, final Point point) { + if(source.x >= point.x){ + return Integer.MAX_VALUE; + } + else{ + final int scale = (point.y - source.y) <= 0 ? 3 : 4; + return (point.x - source.x) + Math.abs(point.y - source.y) * scale; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToUpAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToUpAction.java new file mode 100644 index 00000000000..c111ad7bb8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/MoveSelectionToUpAction.java @@ -0,0 +1,25 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.uiDesigner.GuiEditor; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MoveSelectionToUpAction extends AbstractMoveSelectionAction{ + public MoveSelectionToUpAction(final GuiEditor editor) { + super(editor); + } + + protected int calcDistance(final Point source, final Point point) { + if(source.y <= point.y){ + return Integer.MAX_VALUE; + } + else{ + final int scale = (point.x - source.x) <= 0 ? 3 : 4; + return (source.y - point.y) + Math.abs(point.x - source.x) * scale; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/PreviewFormAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/PreviewFormAction.java new file mode 100644 index 00000000000..d8839336e7d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/PreviewFormAction.java @@ -0,0 +1,287 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.execution.CantRunException; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.TextConsoleBuidlerFactory; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.runners.RunStrategy; +import com.intellij.execution.runners.RunnerInfo; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.GuiEditorUtil; +import com.intellij.uiDesigner.compiler.CodeGenerator; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; +import com.intellij.uiDesigner.lw.LwComponent; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.uiDesigner.make.CopyResourcesUtil; +import com.intellij.uiDesigner.make.Form2ByteCodeCompiler; +import com.intellij.util.BcelUtils; +import com.intellij.util.PathsList; +import org.apache.bcel.util.ClassPath; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class PreviewFormAction extends AnAction{ + private final GuiEditor myEditor; + /** + * The problem is that this class is in a default package so it's not + * import this class to refer + */ + private static final String CLASS_TO_BIND_NAME = "FormPreviewFrame"; + + public PreviewFormAction() { + myEditor = null; + } + + public PreviewFormAction(final GuiEditor editor) { + copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIEW_FORM)); + myEditor = editor; + } + + private GuiEditor getEditor(final DataContext context){ + return myEditor != null ? myEditor : GuiEditorUtil.getEditorFromContext(context); + } + + public void actionPerformed(final AnActionEvent e) { + final GuiEditor editor = getEditor(e.getDataContext()); + showPreviewFrame(editor.getModule(), editor.getFile(), e.getDataContext()); + } + + public void update(final AnActionEvent e) { + final GuiEditor editor = getEditor(e.getDataContext()); + + if(editor == null){ + e.getPresentation().setEnabled(false); + return; + } + + final VirtualFile file = editor.getFile(); + e.getPresentation().setEnabled( + FileDocumentManager.getInstance().getDocument(file) != null && + FileTypeManager.getInstance().getFileTypeByFile(file) == StdFileTypes.GUI_DESIGNER_FORM + ); + } + + private static void showPreviewFrame(final Module module, final VirtualFile formFile, final DataContext dataContext) { + if (module == null) { + throw new IllegalArgumentException("module cannot be null"); + } + if (formFile == null) { + throw new IllegalArgumentException("formFile cannot be null"); + } + + final String tempPath; + try { + final File tempDirectory = FileUtil.createTempDirectory("FormPreview", ""); + tempPath = tempDirectory.getAbsolutePath(); + + CopyResourcesUtil.copyFormsRuntime(tempPath, true); + } + catch (IOException e) { + Messages.showErrorDialog( + module.getProject(), + "Cannot preview form '" + formFile.getPath().replace('/', File.separatorChar) + "'\n" + + "Reason: " + e.toString(), + "Error" + ); + return; + } + + final PathsList sources = ProjectRootsTraversing.collectRoots(module, ProjectRootsTraversing.PROJECT_SOURCES); + final String classPath = + ProjectRootsTraversing.collectRoots(module, ProjectRootsTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString() + File.pathSeparator + + sources.getPathsString() + File.pathSeparator + /* resources bundles */ + tempPath; + final ClassLoader loader = Form2ByteCodeCompiler.createClassLoader(classPath); + + com.intellij.util.BcelUtils.initBcel(new ClassPath(classPath)); + + try { + final Document doc = FileDocumentManager.getInstance().getDocument(formFile); + final LwRootContainer rootContainer; + try { + rootContainer = Utils.getRootContainer(doc.getText(), new CompiledClassPropertiesProvider(loader)); + } + catch (Exception e) { + Messages.showErrorDialog( + module.getProject(), + "Cannot read form file '" + formFile.getPath().replace('/', File.separatorChar) + "'.\n" + + "Reason: " + e.getMessage(), + "Error" + ); + return; + } + + if (rootContainer.getComponentCount() == 0) { + Messages.showErrorDialog( + module.getProject(), + "Cannot preview an empty form '" + formFile.getPath().replace('/', File.separatorChar) + "'\n", + "Error" + ); + return; + } + + // 1. Prepare form to preview. We have to change container so that it has only one binding. + rootContainer.setClassToBind(CLASS_TO_BIND_NAME); + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final LwComponent iComponent) { + iComponent.setBinding(null); + return true; + } + } + ); + if (rootContainer.getComponentCount() == 1) { + ((LwComponent)rootContainer.getComponent(0)).setBinding("myComponent"); + } + + // 2. Copy previewer class and all its superclasses into TEMP directory and instrument it. + try { + final File tempFile = CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME, true); + CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME + "$1", true); + CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME + "$MyWindowListener", true); + CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME + "$MyExitAction", true); + CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME + "$MyPackAction", true); + CopyResourcesUtil.copyClass(tempPath, CLASS_TO_BIND_NAME + "$MySetLafAction", true); + + final CodeGenerator codeGenerator = new CodeGenerator(rootContainer, tempFile, loader); + codeGenerator.patch(); + final String[] errors = codeGenerator.getErrors(); + if(errors.length != 0){ + Messages.showErrorDialog( + module.getProject(), + "Cannot preview form '" + formFile.getPath().replace('/', File.separatorChar) + "'\n" + + "Reason: " + errors[0], + "Error" + ); + return; + } + } + catch (Exception e) { + Messages.showErrorDialog( + module.getProject(), + "Cannot preview form '" + formFile.getPath().replace('/', File.separatorChar) + "'\n" + + "Reason: " + (e.getMessage() != null ? e.getMessage() : e.toString()), + "Error" + ); + return; + } + + // 3. Now we are ready to launch Java process + final JavaParameters parameters = new JavaParameters(); + parameters.getClassPath().add(tempPath); + final List paths = sources.getPathList(); + for (Iterator it = paths.iterator(); it.hasNext();) { + parameters.getClassPath().add(it.next()); + } + try { + parameters.configureByModule(module, JavaParameters.JDK_AND_CLASSES); + } + catch (CantRunException e) { + Messages.showErrorDialog( + module.getProject(), + "Cannot preview form '" + formFile.getPath().replace('/', File.separatorChar) + "'\n" + + "Reason: " + e.getMessage(), + "Error" + ); + return; + } + parameters.setMainClass("FormPreviewFrame"); + parameters.setWorkingDirectory(tempPath); + + try { + JavaProgramRunner defaultRunner = ExecutionRegistry.getInstance().getDefaultRunner(); + RunStrategy.getInstance().execute( + new MyRunProfile(module, parameters, formFile.getPresentableUrl() + " preview started"), + dataContext, + defaultRunner, null, null); + } + catch (ExecutionException e) { + Messages.showErrorDialog( + module.getProject(), + "Cannot preview form '" + formFile.getPath().replace('/', File.separatorChar) + "'\nReason: " + e.getMessage(), + "Error" + ); + return; + } + } + finally { + BcelUtils.disposeBcel(); + } + } + + private static final class MyRunProfile implements RunProfile { + private final Module myModule; + private final JavaParameters myParams; + private final String myStatusbarMessage; + + public MyRunProfile(final Module module, final JavaParameters params, final String statusbarMessage) { + myModule = module; + myParams = params; + myStatusbarMessage = statusbarMessage; + } + + public RunProfileState getState(final DataContext context, + final RunnerInfo runnerInfo, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings) { + final JavaCommandLineState state = new JavaCommandLineState(runnerSettings, configurationSettings) { + protected JavaParameters createJavaParameters() { + return myParams; + } + + public ExecutionResult execute() throws ExecutionException { + try { + return super.execute(); + } + finally { + final Project project = myModule.getProject(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + WindowManager.getInstance().getStatusBar(project).setInfo(myStatusbarMessage); + } + }); + } + } + }; + state.setConsoleBuilder(TextConsoleBuidlerFactory.getInstance().createBuilder(myModule.getProject())); + return state; + } + + public String getName() { + return "Form Preview"; + } + + public void checkConfiguration() throws RuntimeConfigurationException { + } + + public Module[] getModules() { + return new Module[] {myModule}; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShowJavadocAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShowJavadocAction.java new file mode 100644 index 00000000000..e7765a086ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShowJavadocAction.java @@ -0,0 +1,84 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.codeInsight.javadoc.JavaDocInfoComponent; +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.wm.FocusWatcher; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.TabbedPaneWrapper; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.PropertyInspectorTable; + +import javax.swing.*; +import java.awt.event.FocusEvent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ShowJavadocAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.actions.ShowJavadocAction"); + + public void actionPerformed(final AnActionEvent e) { + final PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + final IntrospectedProperty introspectedProperty = inspector.getSelectedIntrospectedProperty(); + final PsiClass aClass = inspector.getComponentClass(); + + final PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, introspectedProperty.getName(), false, true); + LOG.assertTrue(getter != null); + + final PsiMethod setter = PropertyUtil.findPropertySetter(aClass, introspectedProperty.getName(), false, true); + LOG.assertTrue(setter != null); + + final JavaDocManager javaDocManager = JavaDocManager.getInstance(aClass.getProject()); + + final JavaDocInfoComponent component1 = new JavaDocInfoComponent(javaDocManager); + final JavaDocInfoComponent component2 = new JavaDocInfoComponent(javaDocManager); + + final TabbedPaneWrapper tabbedPane = new TabbedPaneWrapper(); + + tabbedPane.addTab("Getter", component1); + tabbedPane.addTab("Setter", component2); + + final LightweightHint hint = new LightweightHint(tabbedPane.getComponent()) { + public void hide() { + super.hide(); + inspector.requestFocusInWindow(); + } + }; + + component1.setHint(hint); + component2.setHint(hint); + + javaDocManager.fetchDocInfo(javaDocManager.getDefaultProvider(getter), component1); + javaDocManager.fetchDocInfo(javaDocManager.getDefaultProvider(setter), component2); + + final FocusWatcher focusWatcher = new FocusWatcher() { + protected void focusLostImpl(final FocusEvent e) { + hint.hide(); + } + }; + + focusWatcher.install(hint.getComponent()); + hint.show(inspector, 0, 0, inspector); + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + component1.requestFocus(); + } + } + ); + } + + public void update(final AnActionEvent e) { + final PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + e.getPresentation().setEnabled(inspector != null && + inspector.getSelectedIntrospectedProperty() != null && + inspector.getComponentClass() != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShrinkSelectionAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShrinkSelectionAction.java new file mode 100644 index 00000000000..44be728964f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/ShrinkSelectionAction.java @@ -0,0 +1,52 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.SelectionState; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.GuiEditorUtil; +import com.intellij.uiDesigner.componentTree.ComponentPtr; + +import java.util.Stack; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ShrinkSelectionAction extends AnAction{ + public void actionPerformed(final AnActionEvent e) { + final GuiEditor editor = GuiEditorUtil.getEditorFromContext(e.getDataContext()); + final SelectionState selectionState = editor.getSelectionState(); + selectionState.setInsideChange(true); + + try{ + final Stack history = selectionState.getSelectionHistory(); + history.pop(); + FormEditingUtil.clearSelection(editor.getRootContainer()); + final ComponentPtr[] ptrs = history.peek(); + for(int i = ptrs.length - 1; i >= 0; i--){ + final ComponentPtr ptr = ptrs[i]; + ptr.validate(); + if(ptr.isValid()){ + ptr.getComponent().setSelected(true); + } + } + }finally{ + selectionState.setInsideChange(false); + } + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final GuiEditor editor = GuiEditorUtil.getEditorFromContext(e.getDataContext()); + if(editor == null){ + presentation.setEnabled(false); + return; + } + + final Stack history = editor.getSelectionState().getSelectionHistory(); + presentation.setEnabled(history.size() > 1); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/StartInplaceEditingAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/StartInplaceEditingAction.java new file mode 100644 index 00000000000..fb1523e22a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/actions/StartInplaceEditingAction.java @@ -0,0 +1,53 @@ +package com.intellij.uiDesigner.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.RadComponent; + +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class StartInplaceEditingAction extends AnAction{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.actions.StartInplaceEditingAction"); + + private final GuiEditor myEditor; + + public StartInplaceEditingAction(final GuiEditor editor) { + LOG.assertTrue(editor != null); + myEditor = editor; + } + + public void actionPerformed(final AnActionEvent e) { + final ArrayList selection = FormEditingUtil.getAllSelectedComponents(myEditor); + final RadComponent component = selection.get(0); + + final int x = component.getX() + component.getWidth() / 2; // central X point + final int y = component.getY() + component.getHeight() / 2; // central Y point + + myEditor.getInplaceEditingLayer().startInplaceEditing(x, y); + } + + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final ArrayList selection = FormEditingUtil.getAllSelectedComponents(myEditor); + + // Inplace editing can be started only if single component is selected + if(selection.size() != 1){ + presentation.setEnabled(false); + return; + } + + // Selected component should have "inplace" property + final RadComponent component = selection.get(0); + final int x = component.getX() + component.getWidth() / 2; // central X point + final int y = component.getY() + component.getHeight() / 2; // central Y point + presentation.setEnabled(component.getInplaceProperty(x, y) != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtr.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtr.java new file mode 100644 index 00000000000..e149e258022 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtr.java @@ -0,0 +1,74 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.GuiEditor; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ComponentPtr{ + private final GuiEditor myEditor; + private final String myId; + private RadComponent myComponent; + + /** + * @param component + */ + public ComponentPtr(final GuiEditor editor,final RadComponent component){ + // Check args + if(editor==null){ + throw new IllegalArgumentException("editor cannot be null"); + } + if(component==null){ + throw new IllegalArgumentException("component cannot be null"); + } + + myEditor=editor; + myId=component.getId(); + + validate(); + if(!isValid()){ + throw new IllegalArgumentException("invalid component: "+component); + } + } + + /** + * @return RadComponent which was calculated by the last + * validate method. + */ + public RadComponent getComponent(){ + return myComponent; + } + + /** + * @return true if and only if the pointer is valid. + * It means that last validate call was successful and + * pointer refers to live component. + */ + public boolean isValid(){ + return myComponent!=null; + } + + /** + * Validates (updates) the state of the pointer + */ + public void validate(){ + // Try to find component with myId starting from root container + final RadContainer container=myEditor.getRootContainer(); + myComponent=FormEditingUtil.findComponent(container,myId); + } + + public boolean equals(final Object obj){ + if(!(obj instanceof ComponentPtr)){ + return false; + } + return myId.equals(((ComponentPtr)obj).myId); + } + + public int hashCode(){ + return myId.hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtrDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtrDescriptor.java new file mode 100644 index 00000000000..867ddca1c50 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentPtrDescriptor.java @@ -0,0 +1,56 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.util.Comparing; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadRootContainer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ComponentPtrDescriptor extends NodeDescriptor{ + private ComponentPtr myPtr; + /** + * RadComponent.getBinding() or RadRootContainer.getClassToBind() + */ + private String myBinding; + + public ComponentPtrDescriptor(final NodeDescriptor parentDescriptor,final ComponentPtr ptr){ + super(null,parentDescriptor); + if(parentDescriptor==null){ + throw new IllegalArgumentException("parentDescriptor cannot be null"); + } + if(ptr==null){ + throw new IllegalArgumentException("ptr cannot be null"); + } + + myPtr=ptr; + } + + public boolean update(){ + myPtr.validate(); + if(!myPtr.isValid()){ + myPtr=null; + return true; + } + + final String oldBinding = myBinding; + final RadComponent component = myPtr.getComponent(); + if(component instanceof RadRootContainer){ + myBinding = ((RadRootContainer)component).getClassToBind(); + } + else{ + myBinding = component.getBinding(); + } + return !Comparing.equal(oldBinding,myBinding); + } + + public RadComponent getComponent() { + return myPtr != null ? myPtr.getComponent() : null; + } + + public Object getElement(){ + return myPtr; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentSelectionListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentSelectionListener.java new file mode 100644 index 00000000000..43a32d8e415 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentSelectionListener.java @@ -0,0 +1,13 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.uiDesigner.GuiEditor; + +import java.util.EventListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public interface ComponentSelectionListener extends EventListener{ + public void selectedComponentChanged(GuiEditor source); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTree.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTree.java new file mode 100644 index 00000000000..6a3c4133811 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTree.java @@ -0,0 +1,319 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TreeToolTipHandler; +import com.intellij.uiDesigner.*; +import com.intellij.uiDesigner.actions.StartInplaceEditingAction; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.Palette; +import com.intellij.uiDesigner.quickFixes.QuickFixManager; +import com.intellij.util.ui.Tree; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.plaf.TreeUI; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ComponentTree extends Tree implements DataProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.componentTree.ComponentTree"); + + private SimpleTextAttributes myBindingAttributes; // exists only for performance reason + private SimpleTextAttributes myClassAttributes; // exists only for performance reason + private SimpleTextAttributes myPackageAttributes; // exists only for performance reason + private SimpleTextAttributes myUnknownAttributes; // exists only for performance reason + + private HashMap myAttr2errAttr; // exists only for performance reason + + private final GuiEditor myEditor; + private final QuickFixManager myQuickFixManager; + + public ComponentTree(final GuiEditor editor) { + super(new DefaultTreeModel(new DefaultMutableTreeNode())); + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + myEditor = editor; + + setCellRenderer(new MyTreeCellRenderer()); + setRootVisible(false); + setShowsRootHandles(false); + + // Enable tooltips + ToolTipManager.sharedInstance().registerComponent(this); + + // Install convenient keyboard navigation + TreeUtil.installActions(this); + + // Install advanced tooltips + TreeToolTipHandler.install(this); + + // Install light buld + myQuickFixManager = new QuickFixManagerImpl(editor, this); + + // Popup menu + PopupHandler.installPopupHandler( + this, + (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_GUI_DESIGNER_COMPONENT_TREE_POPUP), + ActionPlaces.GUI_DESIGNER_COMPONENT_TREE_POPUP, ActionManager.getInstance()); + + // F2 should start inplace editing + final StartInplaceEditingAction startInplaceEditingAction = new StartInplaceEditingAction(editor); + startInplaceEditingAction.registerCustomShortcutSet( + new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), + this + ); + } + + public void updateIntentionHintVisibility() { + myQuickFixManager.updateIntentionHintVisibility(); + } + + /** + * Hides intention hint (if any) + */ + public void hideIntentionHint() { + myQuickFixManager.hideIntentionHint(); + } + + public String getToolTipText(final MouseEvent e) { + final TreePath path = getPathForLocation(e.getX(), e.getY()); + String text = null; + if (path != null) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); + LOG.assertTrue(node != null); + final Object userObject = node.getUserObject(); + if (userObject instanceof ComponentPtrDescriptor) { + final NodeDescriptor descriptor = (NodeDescriptor)userObject; + final ComponentPtr ptr = (ComponentPtr)descriptor.getElement(); + if (ptr.isValid()) { + final RadComponent component = ptr.getComponent(); + LOG.assertTrue(component != null); + final ErrorInfo errorInfo = ErrorAnalizer.getErrorForComponent(component); + if (errorInfo != null) { + text = errorInfo.myDescription; + } + } + } + } + return text; + } + + /** + * TODO[vova] should return pair + * + * @return first selected component. The method returns null + * if there is no selection in the tree. + */ + public RadComponent getSelectedComponent() { + final RadComponent[] selectedComponents = getSelectedComponents(); + return selectedComponents.length > 0 ? selectedComponents[0] : null; + } + + /** + * TODO[vova] should return pair + * + * @return currently selected components. This method never returns null. + */ + public RadComponent[] getSelectedComponents() { + final TreePath[] paths = getSelectionPaths(); + if (paths == null) { + return RadComponent.EMPTY_ARRAY; + } + final ArrayList result = new ArrayList(paths.length); + for (int i = 0; i < paths.length; i++) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)paths[i].getLastPathComponent(); + LOG.assertTrue(node != null); + if (node.getUserObject() instanceof ComponentPtrDescriptor) { + final ComponentPtrDescriptor descriptor = (ComponentPtrDescriptor)node.getUserObject(); + final ComponentPtr ptr = (ComponentPtr)descriptor.getElement(); + LOG.assertTrue(ptr.isValid()); + result.add(ptr.getComponent()); + } + } + return result.toArray(new RadComponent[result.size()]); + } + + /** + * Provides {@link DataConstants#NAVIGATABLE} to navigate to + * binding of currently selected component (if any) + */ + public Object getData(final String dataId) { + if (!DataConstants.NAVIGATABLE.equals(dataId)) { + return null; + } + + final RadComponent selectedComponent = getSelectedComponent(); + if (selectedComponent == null) { + return null; + } + + final String classToBind = myEditor.getRootContainer().getClassToBind(); + if (classToBind == null) { + return null; + } + + final PsiClass aClass = FormEditingUtil.findClassToBind(myEditor.getModule(), classToBind); + if (aClass == null) { + return null; + } + + if (selectedComponent instanceof RadRootContainer) { + return EditSourceUtil.getDescriptor(aClass); + } + + final String binding = selectedComponent.getBinding(); + if (binding == null) { + return null; + } + + final PsiField[] fields = aClass.getFields(); + + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + + if (binding.equals(field.getName())) { + return EditSourceUtil.getDescriptor(field); + } + } + + return null; + } + + private SimpleTextAttributes getAttribute(final SimpleTextAttributes attrs, final boolean error) { + if (attrs == null) { + throw new IllegalArgumentException("attrs cannot be null"); + } + if (!error) { + return attrs; + } + SimpleTextAttributes result = myAttr2errAttr.get(attrs); + if (result == null) { + result = new SimpleTextAttributes(attrs.getStyle() | SimpleTextAttributes.STYLE_WAVED, + attrs.getFgColor(), + Color.RED); + myAttr2errAttr.put(attrs, result); + } + return result; + } + + public void setUI(final TreeUI ui) { + super.setUI(ui); + + // [vova] we cannot create this hash in constructor and just clear it here. The + // problem is that setUI is invoked by constructor of superclass. + myAttr2errAttr = new HashMap(); + + myBindingAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, UIManager.getColor("Tree.foreground")); + myClassAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, UIManager.getColor("Tree.foreground")); + myPackageAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.GRAY); + myUnknownAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN | SimpleTextAttributes.STYLE_WAVED, Color.RED); + } + + private final class MyTreeCellRenderer extends ColoredTreeCellRenderer { + public void customizeCellRenderer( + final JTree tree, + final Object value, + final boolean selected, + final boolean expanded, + final boolean leaf, + final int row, + final boolean hasFocus + ) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + if (node.getUserObject() instanceof ComponentPtrDescriptor) { + final ComponentPtrDescriptor descriptor = (ComponentPtrDescriptor)node.getUserObject(); + final ComponentPtr ptr = (ComponentPtr)descriptor.getElement(); + final RadComponent component = ptr.getComponent(); + LOG.assertTrue(component != null); + + final boolean error = ErrorAnalizer.getErrorForComponent(component) != null; + + // Text + final String binding = component.getBinding(); + if (binding != null) { + append(binding, getAttribute(myBindingAttributes, error)); + append(" ", getAttribute(myClassAttributes, error)); + } + + final Class componentClass = component.getComponentClass(); + final String componentClassName = componentClass.getName(); + + if (component instanceof RadVSpacer) { + append("Vertical Spacer", getAttribute(myClassAttributes, error)); + } + else if (component instanceof RadHSpacer) { + append("Horizontal Spacer", getAttribute(myClassAttributes, error)); + } + else if (component instanceof RadErrorComponent) { + final RadErrorComponent c = (RadErrorComponent)component; + append(c.getErrorDescription(), getAttribute(myUnknownAttributes, error)); + } + else if (component instanceof RadRootContainer) { + append("Form ", getAttribute(myClassAttributes, error)); + append("(", getAttribute(myPackageAttributes, error)); + final String classToBind = ((RadRootContainer)component).getClassToBind(); + if (classToBind != null) { + append(classToBind, getAttribute(myPackageAttributes, error)); + } + else { + append("no binding", getAttribute(myPackageAttributes, error)); + } + append(")", getAttribute(myPackageAttributes, error)); + } + else { + final Package aPackage = componentClass.getPackage(); + String packageName = null; + if (aPackage != null/*null for classes in default package*/) { + packageName = aPackage.getName(); + } + + if (packageName != null) { + append(componentClassName.substring(packageName.length() + 1), getAttribute(myClassAttributes, error)); + append(" (", getAttribute(myPackageAttributes, error)); + append(packageName, getAttribute(myPackageAttributes, error)); + append(")", getAttribute(myPackageAttributes, error)); + } + else { + append(componentClassName, getAttribute(myClassAttributes, error)); + } + } + + // Icon + if (!(component instanceof RadErrorComponent)) { + final ComponentItem item = Palette.getInstance(myEditor.getProject()).getItem(componentClassName); + final Icon icon; + if (item != null) { + icon = item.getSmallIcon(); + } + else { + icon = IconLoader.getIcon("/com/intellij/uiDesigner/icons/unknown-small.png"); + } + setIcon(icon); + } + else { + setIcon(IconLoader.getIcon("/com/intellij/uiDesigner/icons/error-small.png")); + } + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeBuilder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeBuilder.java new file mode 100644 index 00000000000..d0c8149a3a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeBuilder.java @@ -0,0 +1,239 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; +import com.intellij.uiDesigner.*; + +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Comparator; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ComponentTreeBuilder extends AbstractTreeBuilder{ + private static final Logger LOG = Logger.getInstance("#com.intellij.componentTree.ComponentTreeBuilder"); + + private final GuiEditor myEditor; + private final MySelectionWatcher mySelectionWatcher; + /** + * More then 0 if we are inside some change. In this case we have not + * react on our own events. + */ + private int myInsideChange; + + public ComponentTreeBuilder(final ComponentTree tree, final GuiEditor editor){ + super(tree,(DefaultTreeModel)tree.getModel(),null,MyComparator.ourComparator); + + if(editor==null){ + throw new IllegalArgumentException("editor cannot be null"); + } + + myEditor = editor; + mySelectionWatcher = new MySelectionWatcher(); + mySelectionWatcher.install(myEditor.getRootContainer()); + myTreeStructure = new ComponentTreeStructure(editor); + + initRootNode(); + syncSelection(); + + myTree.getSelectionModel().addTreeSelectionListener(new MyTreeSelectionListener()); + editor.addHierarchyChangleListener(new MyHierarchyChangeListener()); + } + + private ComponentTreeStructure getComponentTreeStructure(){ + return (ComponentTreeStructure)myTreeStructure; + } + + protected boolean isAlwaysShowPlus(final NodeDescriptor descriptor){ + return false; + } + + protected boolean isAutoExpandNode(final NodeDescriptor descriptor){ + return getComponentTreeStructure().isAutoExpandNode(descriptor); + } + + /** + * This method synchronizes selection in the tree with the selected + * RadComponent in the component hierarchy + */ + private void syncSelection(){ + // Found selected components + final RadContainer rootContainer=myEditor.getRootContainer(); + final ArrayList selection = new ArrayList(); + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if(component.isSelected()){ + selection.add(component); + } + return true; + } + } + ); + if(selection.size() == 0){ + // If there is no selected component in the hierarchy, then + // we have to select RadRootContainer + selection.add(rootContainer); + } + + // Set selection in the tree + myTree.clearSelection(); + TreePath firstSelectedPath = null; + for(int i = selection.size() - 1; i >= 0; i--){ + final ComponentPtr ptr=new ComponentPtr(myEditor, selection.get(i)); + buildNodeForElement(ptr); + final DefaultMutableTreeNode nodeForElement=getNodeForElement(ptr); + if (nodeForElement == null) { + //TODO[anton,vova] investigate!!! + return; + } + +// LOG.assertTrue(nodeForElement!=null); + // Add selected path and scroll it to visible area + final TreePath selectedPath=new TreePath(nodeForElement.getPath()); + myTree.addSelectionPath(selectedPath); + if(firstSelectedPath == null){ + firstSelectedPath = selectedPath; + } + } + LOG.assertTrue(firstSelectedPath != null); + myTree.scrollPathToVisible(firstSelectedPath); + + // Notify the ComponentTree that selected component changed + myEditor.fireSelectedComponentChanged(); + } + + /** + * Compares RadComponent based on their natural order in the container. + */ + private static final class MyComparator implements Comparator{ + public static final MyComparator ourComparator=new MyComparator(); + + private MyComparator(){} + + private static int indexOf(final RadContainer container, final RadComponent component){ + for(int i = container.getComponentCount() - 1; i >= 0 ; i--){ + if(component.equals(container.getComponent(i))){ + return i; + } + } + return -1; + } + + public int compare(final NodeDescriptor descriptor1, final NodeDescriptor descriptor2) { + if (descriptor1 instanceof ComponentPtrDescriptor && descriptor2 instanceof ComponentPtrDescriptor) { + final RadComponent component1 = ((ComponentPtrDescriptor)descriptor1).getComponent(); + final RadComponent component2 = ((ComponentPtrDescriptor)descriptor2).getComponent(); + if (component1 == null || component2 == null) { + return 0; + } + final RadContainer container1 = component1.getParent(); + final RadContainer container2 = component2.getParent(); + if(Comparing.equal(container1, container2)){ + final int i = indexOf(container2, component2) - indexOf(container1, component1); + return i; + } + else{ + return 0; + } + }else{ + return 0; + } + } + } + + /** + * Synchronizes tree with GuiEditor + */ + private final class MyHierarchyChangeListener implements HierarchyChangeListener{ + public void hierarchyChanged(){ + if(myInsideChange>0){ + return; + } + + myInsideChange++; + try{ + updateFromRoot(); + // After updating the tree we have to synchronize the selection in the tree + // with selected elemenet in the hierarchy + final RadRootContainer rootContainer = myEditor.getRootContainer(); + mySelectionWatcher.deinstall(rootContainer); + mySelectionWatcher.install(rootContainer); + syncSelection(); + }finally{ + myInsideChange--; + } + } + } + + /** + * Synchronizes selection in the tree with selection in the editor + */ + private final class MySelectionWatcher extends SelectionWatcher{ + protected void selectionChanged(final RadComponent component, final boolean ignored) { + if(myInsideChange > 0){ + return; + } + myInsideChange++; + try { + updateFromRoot(); + syncSelection(); + } finally { + myInsideChange--; + } + } + } + + /** + * Synchronizes GuiEditor with the tree + */ + private final class MyTreeSelectionListener implements TreeSelectionListener{ + public void valueChanged(final TreeSelectionEvent e){ + if(myInsideChange>0){ + return; + } + final TreePath[] paths = myTree.getSelectionPaths(); + if(paths==null){ + return; + } + + myInsideChange++; + try{ + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + for(int i = paths.length - 1; i >= 0; i--){ + final DefaultMutableTreeNode lastComponent=(DefaultMutableTreeNode)paths[i].getLastPathComponent(); + LOG.assertTrue(lastComponent!=null); + + final ComponentPtrDescriptor descriptor=(ComponentPtrDescriptor)lastComponent.getUserObject(); + if(descriptor==null){ + // It can happen when node is being collapsing and some of its children + // is selected. In that case AbstractTreeBuilder (Valentin) destroyProcess all children nodes and + // mutable nodes contain nulls. + return; + } + + final ComponentPtr ptr=(ComponentPtr)descriptor.getElement(); + if(ptr.isValid()){ + final RadComponent component=ptr.getComponent(); + LOG.assertTrue(component!=null); + component.setSelected(true); + } + } + + // Notify ComponentTree that selected component changed + myEditor.fireSelectedComponentChanged(); + }finally{ + myInsideChange--; + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeStructure.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeStructure.java new file mode 100644 index 00000000000..073e2c82495 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/ComponentTreeStructure.java @@ -0,0 +1,107 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.RadRootContainer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ComponentTreeStructure extends AbstractTreeStructure{ + private static final Logger LOG=Logger.getInstance("#com.intellij.uiDesigner.componentTree.ComponentPtr"); + private static final Object[] ourEmptyObjectArray=new Object[]{}; + + private final Object myRootElement; + private final GuiEditor myEditor; + + public ComponentTreeStructure(final GuiEditor editor){ + if(editor==null){ + throw new IllegalArgumentException("editor cannot be null"); + } + + myRootElement=new Object(); + myEditor=editor; + } + + public Object getRootElement(){ + return myRootElement; + } + + public Object[] getChildElements(final Object element){ + if(element==myRootElement){ + final RadContainer rootContainer=myEditor.getRootContainer(); + return new Object[]{new ComponentPtr(myEditor,rootContainer)}; + } + else if(element instanceof ComponentPtr){ + final ComponentPtr ptr=(ComponentPtr)element; + LOG.assertTrue(ptr.isValid()); // pointer must be valid + final RadComponent component=ptr.getComponent(); + if(component instanceof RadContainer){ + final RadContainer container=(RadContainer)component; + final ComponentPtr[] ptrs=new ComponentPtr[container.getComponentCount()]; + for(int i=0;i{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.componentTree.QuickFixManagerImpl"); + + public QuickFixManagerImpl(final GuiEditor editor, final ComponentTree componentTree) { + super(editor, componentTree); + myComponent.addTreeSelectionListener(new MyTreeSelectionListener()); + } + + protected ErrorInfo getErrorInfo() { + final RadComponent component = myComponent.getSelectedComponent(); + if(component == null){ + return null; + } + return ErrorAnalizer.getErrorForComponent(component); + } + + public Rectangle getErrorBounds() { + final TreePath selectionPath = myComponent.getSelectionPath(); + LOG.assertTrue(selectionPath != null); + return myComponent.getPathBounds(selectionPath); + } + + private final class MyTreeSelectionListener implements TreeSelectionListener{ + public void valueChanged(final TreeSelectionEvent e) { + hideIntentionHint(); + updateIntentionHintVisibility(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/RootDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/RootDescriptor.java new file mode 100644 index 00000000000..367c386ae79 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/componentTree/RootDescriptor.java @@ -0,0 +1,24 @@ +package com.intellij.uiDesigner.componentTree; + +import com.intellij.ide.util.treeView.NodeDescriptor; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class RootDescriptor extends NodeDescriptor{ + private final Object myRootElement; + + public RootDescriptor(final NodeDescriptor parentDescriptor,final Object rootElement){ + super(null,parentDescriptor); + myRootElement=rootElement; + } + + public boolean update(){ + return false; + } + + public Object getElement(){ + return myRootElement; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/MyEditorState.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/MyEditorState.java new file mode 100644 index 00000000000..5da612be0b3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/MyEditorState.java @@ -0,0 +1,43 @@ +package com.intellij.uiDesigner.editor; + +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; + +import java.util.Arrays; + +final class MyEditorState implements FileEditorState{ + private final transient long myDocumentModificationStamp; // should not be serialized + private final String[] mySelectedComponentIds; + + public MyEditorState(final long modificationStamp, final String[] selectedComponents){ + if (selectedComponents == null){ + throw new IllegalArgumentException("selectedComponents cannot be null"); + } + myDocumentModificationStamp = modificationStamp; + mySelectedComponentIds = selectedComponents; + } + + public String[] getSelectedComponentIds(){ + return mySelectedComponentIds; + } + + public boolean equals(final Object o){ + if (this == o) return true; + if (!(o instanceof MyEditorState)) return false; + + final MyEditorState state = (MyEditorState)o; + + if (myDocumentModificationStamp != state.myDocumentModificationStamp) return false; + if (!Arrays.equals(mySelectedComponentIds, state.mySelectedComponentIds)) return false; + + return true; + } + + public int hashCode(){ + return (int)(myDocumentModificationStamp ^ (myDocumentModificationStamp >>> 32)); + } + + public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) { + return otherState instanceof MyEditorState; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditor.java new file mode 100644 index 00000000000..4482c0d9834 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditor.java @@ -0,0 +1,141 @@ +package com.intellij.uiDesigner.editor; + +import com.intellij.codeHighlighting.BackgroundEditorHighlighter; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.RadComponent; + +import javax.swing.*; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class UIFormEditor extends UserDataHolderBase implements FileEditor{ + private final VirtualFile myFile; + private final GuiEditor myEditor; + + public UIFormEditor(final Project project, final VirtualFile file){ + final Module module = ModuleUtil.getModuleForFile(project, file); + if (module == null) { + throw new IllegalArgumentException("no module for file " + file + " in project " + project); + } + myFile = file; + myEditor = new GuiEditor(module, file); + } + + public JComponent getComponent(){ + return myEditor; + } + + void dispose() { + myEditor.dispose(); + } + + public JComponent getPreferredFocusedComponent(){ + return myEditor.getPreferredFocusedComponent(); + } + + public String getName(){ + return "GUI Designer"; + } + + public GuiEditor getEditor() { + return myEditor; + } + + public boolean isModified(){ + //TODO[anton,vova] + return false; + } + + public boolean isValid(){ + //TODO[anton,vova] fire when changed + return + FileDocumentManager.getInstance().getDocument(myFile) != null && + FileTypeManager.getInstance().getFileTypeByFile(myFile) == StdFileTypes.GUI_DESIGNER_FORM; + } + + public void selectNotify(){ + } + + public void deselectNotify(){ + } + + public void addPropertyChangeListener(final PropertyChangeListener listener){ + //TODO[anton,vova] + } + + public void removePropertyChangeListener(final PropertyChangeListener listener){ + //TODO[anton,vova] + } + + public BackgroundEditorHighlighter getBackgroundHighlighter() { + // TODO[jeka]: seems like it actually should be implemented. + return null; + } + + public FileEditorLocation getCurrentLocation() { + return null; + } + + public FileEditorState getState(final FileEditorStateLevel ignored) { + final Document document = FileDocumentManager.getInstance().getDocument(myFile); + final ArrayList selection = FormEditingUtil.getSelectedComponents(myEditor); + final String[] ids = new String[selection.size()]; + for (int i = ids.length - 1; i >= 0; i--) { + ids[i] = selection.get(i).getId(); + } + return new MyEditorState(document.getModificationStamp(), ids); + } + + public void setState(final FileEditorState state){ + if (state == null){ + throw new IllegalArgumentException("state cannot be null"); + } + + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + final String[] ids = ((MyEditorState)state).getSelectedComponentIds(); + for (int i = 0; i < ids.length; i++) { + final String id = ids[i]; + final RadComponent component = FormEditingUtil.findComponent(myEditor.getRootContainer(), id); + if (component != null) { + component.setSelected(true); + } + } + } + + public void selectComponent(final String binding){ + if (binding == null){ + throw new IllegalArgumentException("binding cannot be null"); + } + + FormEditingUtil.clearSelection(myEditor.getRootContainer()); + + FormEditingUtil.iterate(myEditor.getRootContainer(), new FormEditingUtil.ComponentVisitor() { + public boolean visit(final RadComponent component) { + if (binding.equals(component.getBinding())) { + component.setSelected(true); + return false; + } + return true; + } + }); + } + + public StructureViewModel getStructureViewModel() { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditorProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditorProvider.java new file mode 100644 index 00000000000..898e3b920ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/editor/UIFormEditorProvider.java @@ -0,0 +1,73 @@ +package com.intellij.uiDesigner.editor; + +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorPolicy; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; + +public final class UIFormEditorProvider implements FileEditorProvider, ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.editor.UIFormEditorProvider"); + + public boolean accept(final Project project, final VirtualFile file){ + if (file == null){ + throw new IllegalArgumentException("file cannot be null"); + } + return + FileTypeManager.getInstance().getFileTypeByFile(file) == StdFileTypes.GUI_DESIGNER_FORM && + !StdFileTypes.GUI_DESIGNER_FORM.isBinary() && + ModuleUtil.getModuleForFile(project, file) != null; + } + + public FileEditor createEditor(final Project project, final VirtualFile file){ + if (file == null){ + throw new IllegalArgumentException("file cannot be null"); + } + LOG.assertTrue(accept(project, file)); + return new UIFormEditor(project, file); + } + + public void disposeEditor(final FileEditor editor){ + if (editor == null){ + throw new IllegalArgumentException("editor cannot be null"); + } + ((UIFormEditor)editor).dispose(); + } + + public FileEditorState readState(final Element element, final Project project, final VirtualFile file){ + //TODO[anton,vova] implement + return new MyEditorState(-1, ArrayUtil.EMPTY_STRING_ARRAY); + } + + public void writeState(final FileEditorState state, final Project project, final Element element){ + //TODO[anton,vova] implement + } + + public String getEditorTypeId(){ + return "ui-designer"; + } + + public FileEditorPolicy getPolicy() { + return + ApplicationManagerEx.getApplicationEx().isInternal() ? + FileEditorPolicy.NONE : FileEditorPolicy.HIDE_DEFAULT_EDITOR; + } + + public String getComponentName(){ + return "uiDesignerEditorProvider"; + } + + public void initComponent() {} + + public void disposeComponent(){} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/BindingsCache.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/BindingsCache.java new file mode 100644 index 00000000000..b8e291df1c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/BindingsCache.java @@ -0,0 +1,92 @@ +/* + * @author: Eugene Zhuravlev + * Date: Jul 4, 2003 + * Time: 7:39:27 PM + */ +package com.intellij.uiDesigner.make; + +import com.intellij.compiler.impl.StateCache; +import com.intellij.openapi.compiler.CompilerPaths; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.LwRootContainer; + +import java.io.*; + +final class BindingsCache { + private static final String BINDINGS_FILE_NAME = "formbinding.dat"; + private final StateCache myCache; + + public BindingsCache(final Project project) { + final File cacheStoreDirectory = CompilerPaths.getCacheStoreDirectory(project); + myCache = (cacheStoreDirectory != null)? new StateCache(cacheStoreDirectory + File.separator + BINDINGS_FILE_NAME) { + public MyState read(final DataInputStream stream) throws IOException { + return new MyState(stream.readLong(), stream.readUTF()); + } + + public void write(final MyState myState, final DataOutputStream stream) throws IOException { + stream.writeLong(myState.getFormTimeStamp()); + stream.writeUTF(myState.getClassName()); + } + } : null; + } + + public String getBoundClassName(final VirtualFile formFile) throws Exception { + String classToBind = getSavedBinding(formFile); + if (classToBind == null) { + final Document doc = FileDocumentManager.getInstance().getDocument(formFile); + final LwRootContainer rootContainer = Utils.getRootContainer(doc.getText(), null); + classToBind = rootContainer.getClassToBind(); + } + if (classToBind != null) { + updateCache(formFile, classToBind); + } + return classToBind; + } + + public void save() { + if (myCache != null) { + myCache.save(); + } + } + + private String getSavedBinding(final VirtualFile formFile) { + if (myCache != null) { + final String formUrl = formFile.getUrl(); + final MyState state = myCache.getState(formUrl); + if (state != null) { + if (formFile.getTimeStamp() == state.getFormTimeStamp()) { + return state.getClassName(); + } + } + } + return null; + } + + private void updateCache(final VirtualFile formFile, final String classToBind) { + if (myCache != null) { + myCache.update(formFile.getUrl(), new MyState(formFile.getTimeStamp(), classToBind)); + } + } + + private static final class MyState implements Serializable{ + private final long myFormTimeStamp; + private final String myClassName; + + public MyState(final long formTimeStamp, final String className){ + myFormTimeStamp = formTimeStamp; + myClassName = className; + } + + public long getFormTimeStamp(){ + return myFormTimeStamp; + } + + public String getClassName(){ + return myClassName; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/CopyResourcesUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/CopyResourcesUtil.java new file mode 100644 index 00000000000..170f574b07f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/CopyResourcesUtil.java @@ -0,0 +1,55 @@ +package com.intellij.uiDesigner.make; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.uiDesigner.actions.PreviewFormAction; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public final class CopyResourcesUtil { + public static File copyClass(final String targetPath, final String className, final boolean deleteOnExit) throws IOException{ + final File targetDir = new File(targetPath).getAbsoluteFile(); + final File file = new File(targetDir, className + ".class"); + FileUtil.createParentDirs(file); + if (deleteOnExit) { + for (File f = file; f != null && !f.equals(targetDir); f = f.getParentFile()) { + f.deleteOnExit(); + } + } + final String resourceName = "/" + className + ".class"; + final InputStream stream = PreviewFormAction.class.getResourceAsStream(resourceName); + if (stream == null) { + throw new IOException("cannot load " + resourceName); + } + try { + final FileOutputStream outputStream = new FileOutputStream(file); + try { + FileUtil.copy(stream, outputStream); + } + finally { + outputStream.close(); + } + } + finally { + stream.close(); + } + return file; + } + + public static void copyFormsRuntime(final String targetDir, final boolean deleteOnExit) throws IOException { + copyClass(targetDir, "com/intellij/uiDesigner/core/AbstractLayout", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/DimensionInfo", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/GridConstraints", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/GridLayoutManager", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/HorizontalInfo", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/LayoutState", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/Spacer", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/SupportCode$1", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/SupportCode$TextWithMnemonic", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/SupportCode", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/Util", deleteOnExit); + copyClass(targetDir, "com/intellij/uiDesigner/core/VerticalInfo", deleteOnExit); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java new file mode 100644 index 00000000000..821f68b0005 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java @@ -0,0 +1,369 @@ +package com.intellij.uiDesigner.make; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.ex.CompilerPathsEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootsTraversing; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.uiDesigner.GuiDesignerConfiguration; +import com.intellij.uiDesigner.compiler.AlienFormFileException; +import com.intellij.uiDesigner.compiler.CodeGenerator; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.util.BcelUtils; +import org.apache.bcel.util.ClassPath; + +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.StringTokenizer; + +public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.make.Form2ByteCodeCompiler"); + + private final Project myProject; + + public Form2ByteCodeCompiler(final Project project) { + myProject = project; + } + + public String getDescription() { + return "GUI Designer form to bytecode compiler"; + } + + public boolean validateConfiguration(CompileScope scope) { + return true; + } + + /** + * @return never null + */ + public static URLClassLoader createClassLoader(final String classPath){ + if (classPath == null) { + throw new IllegalArgumentException("classPath cannot be null"); + } + final ArrayList urls = new ArrayList(); + for (StringTokenizer tokenizer = new StringTokenizer(classPath, File.pathSeparator); tokenizer.hasMoreTokens();) { + final String s = tokenizer.nextToken(); + try { + urls.add(new File(s).toURI().toURL()); + } + catch (Exception exc) { + throw new RuntimeException(exc); + } + } + return new URLClassLoader(urls.toArray(new URL[urls.size()]), null); + } + + public FileProcessingCompiler.ProcessingItem[] getProcessingItems(final CompileContext context) { + if (!GuiDesignerConfiguration.getInstance(myProject).INSTRUMENT_CLASSES) { + return ProcessingItem.EMPTY_ARRAY; + } + + final ArrayList items = new ArrayList(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final CompileScope scope = context.getCompileScope(); + + final VirtualFile[] formFiles = scope.getFiles(StdFileTypes.GUI_DESIGNER_FORM, true); + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + final BindingsCache bindingsCache = new BindingsCache(myProject); + final VirtualFile[] outputDirectories = CompilerPathsEx.getOutputDirectories( + ModuleManager.getInstance(myProject).getSortedModules() + ); + + final HashMap> module2formFiles = sortByModules(formFiles); + + try { + for (Iterator modules = module2formFiles.keySet().iterator(); modules.hasNext();) { + final Module module = modules.next(); + + final HashMap class2form = new HashMap(); + + final ArrayList list = module2formFiles.get(module); + for (int i = 0; i < list.size(); i++) { + final VirtualFile formFile = (VirtualFile)list.get(i); + + if (compilerConfiguration.isExcludedFromCompilation(formFile)) { + continue; + } + + final String classToBind; + try { + classToBind = bindingsCache.getBoundClassName(formFile); + } + catch (AlienFormFileException e) { + // ignore non-IDEA forms + continue; + } + catch (Exception e) { + addError(context, "Cannot process form file. Reason: " + e, formFile); + continue; + } + + if (classToBind == null) { + continue; + } + + final VirtualFile classFile = findFile(outputDirectories, classToBind, module); + if (classFile == null) { + if (context.getCompileScope().belongs(formFile.getUrl())) { + addError(context, "Class to bind does not exist: " + classToBind, formFile); + } + continue; + } + + final VirtualFile alreadyProcessedForm = class2form.get(classToBind); + if (alreadyProcessedForm != null) { + addError( + context, + "The form is bound to the class " + classToBind + ".\n" + + "Another form " + alreadyProcessedForm.getPresentableUrl() + " is also bound to this class.", + formFile + ); + continue; + } + class2form.put(classToBind, formFile); + + final FileProcessingCompiler.ProcessingItem item = new MyInstrumentationItem(classFile, formFile); + items.add(item); + } + } + } + finally { + bindingsCache.save(); + } + } + }); + + return items.toArray(new FileProcessingCompiler.ProcessingItem[items.size()]); + } + + private HashMap> sortByModules(final VirtualFile[] formFiles) { + final HashMap> module2formFiles = new HashMap>(); + for (int i = 0; i < formFiles.length; i++) { + final VirtualFile formFile = formFiles[i]; + + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module != null) { + ArrayList list = module2formFiles.get(module); + if (list == null) { + list = new ArrayList(); + module2formFiles.put(module, list); + } + list.add(formFile); + } + else { + // todo[anton] handle somehow + } + } + return module2formFiles; + } + + private HashMap> sortByModules(final FileProcessingCompiler.ProcessingItem[] items) { + final HashMap> module2formFiles = new HashMap>(); + for (int i = 0; i < items.length; i++) { + final MyInstrumentationItem item = (MyInstrumentationItem)items[i]; + final VirtualFile formFile = item.getFormFile(); + + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module != null) { + ArrayList list = module2formFiles.get(module); + if (list == null) { + list = new ArrayList(); + module2formFiles.put(module, list); + } + list.add(item); + } + else { + // todo[anton] handle somehow + } + } + return module2formFiles; + } + + private static VirtualFile findFile(final VirtualFile[] outputDirectories, final String className, final Module module) { + final String relativepath = getClassFileName(className.replace('$', '.'), module) + ".class"; + for (int idx = 0; idx < outputDirectories.length; idx++) { + final VirtualFile outputDirectory = outputDirectories[idx]; + final VirtualFile file = outputDirectory.findFileByRelativePath(relativepath); + if (file != null) { + return file; + } + } + return null; + } + + private static String getClassFileName(final String _className, final Module module) { + final PsiClass aClass = PsiManager.getInstance(module.getProject()).findClass(_className, GlobalSearchScope.moduleScope(module)); + if (aClass == null) { + // ? + return _className; + } + + PsiClass outerClass = aClass; + while (outerClass.getParent() instanceof PsiClass) { + outerClass = (PsiClass)outerClass.getParent(); + } + + final String outerQualifiedName = outerClass.getQualifiedName(); + + return outerQualifiedName.replace('.','/') + _className.substring(outerQualifiedName.length()).replace('.','$'); + } + + public FileProcessingCompiler.ProcessingItem[] process(final CompileContext context, + final FileProcessingCompiler.ProcessingItem[] items) { + final ArrayList compiledItems = new ArrayList(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + context.getProgressIndicator().setText("Compiling UI forms..."); + + final HashMap> module2itemsList = sortByModules(items); + + int formsProcessed = 0; + + for (Iterator iterator = module2itemsList.keySet().iterator(); iterator.hasNext();) { + final Module module = iterator.next(); + final String classPath = ProjectRootsTraversing.collectRoots(module, ProjectRootsTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString(); + final ClassLoader loader = createClassLoader(classPath); + + if (GuiDesignerConfiguration.getInstance(myProject).COPY_FORMS_RUNTIME_TO_OUTPUT) { + final String moduleOutputPath = CompilerPaths.getModuleOutputPath(module, false); + try { + if (moduleOutputPath != null) { + CopyResourcesUtil.copyFormsRuntime(moduleOutputPath, false); + } + final String testsOutputPath = CompilerPaths.getModuleOutputPath(module, true); + if (testsOutputPath != null && !testsOutputPath.equals(moduleOutputPath)) { + CopyResourcesUtil.copyFormsRuntime(testsOutputPath, false); + } + } + catch (IOException e) { + addError( + context, + "Cannot copy GUI designer form runtime classes to the output directory of module " + module.getName() + + ".\nReason: " + e.toString(), + null + ); + } + } + + BcelUtils.initBcel(new ClassPath(classPath)); + try { + final ArrayList list = module2itemsList.get(module); + + for (int i = 0; i < list.size(); i++) { + context.getProgressIndicator().setFraction((double)(++formsProcessed) / ((double)items.length)); + + final MyInstrumentationItem item = list.get(i); + + final VirtualFile formFile = item.getFormFile(); + + final Document doc = FileDocumentManager.getInstance().getDocument(formFile); + final LwRootContainer rootContainer; + try { + rootContainer = Utils.getRootContainer(doc.getText(), new CompiledClassPropertiesProvider(loader)); + } + catch (Exception e) { + addError(context, "Cannot process form file. Reason: " + e, formFile); + continue; + } + + final File classFile = VfsUtil.virtualToIoFile(item.getFile()); + LOG.assertTrue(classFile.exists()); + + final CodeGenerator codeGenerator = new CodeGenerator(rootContainer, classFile, loader); + codeGenerator.patch(); + final String[] errors = codeGenerator.getErrors(); + final String[] warnings = codeGenerator.getWarnings(); + for (int j = 0; j < warnings.length; j++) { + addWarning(context, warnings[j], formFile); + } + for (int j = 0; j < errors.length; j++) { + addError(context, errors[j], formFile); + } + if (errors.length == 0) { + compiledItems.add(item); + } + } + } + finally { + BcelUtils.disposeBcel(); + } + } + } + }); + + return compiledItems.toArray(new FileProcessingCompiler.ProcessingItem[compiledItems.size()]); + } + + private static void addError(final CompileContext context, final String message, final VirtualFile formFile) { + if (formFile != null) { + context.addMessage(CompilerMessageCategory.ERROR, formFile.getPresentableUrl() + ": " + message, + formFile.getUrl(), -1, -1); + } + else { + context.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + } + } + + private static void addWarning(final CompileContext context, final String message, final VirtualFile formFile) { + if (formFile != null) { + context.addMessage(CompilerMessageCategory.WARNING, formFile.getPresentableUrl() + ": " + message, + formFile.getUrl(), -1, -1); + } + else { + context.addMessage(CompilerMessageCategory.WARNING, message, null, -1, -1); + } + } + + public ValidityState createValidityState(final DataInputStream is) throws IOException { + return new TimestampValidityState(is.readLong()); + } + + private static final class MyInstrumentationItem implements FileProcessingCompiler.ProcessingItem { + private final VirtualFile myClassFile; + private final VirtualFile myFormFile; + private final TimestampValidityState myState; + + public MyInstrumentationItem(final VirtualFile classFile, final VirtualFile formFile) { + myClassFile = classFile; + myFormFile = formFile; + myState = new TimestampValidityState(formFile.getTimeStamp()); + } + + public VirtualFile getFile() { + return myClassFile; + } + + public VirtualFile getFormFile() { + return myFormFile; + } + + public ValidityState getValidityState() { + return myState; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2SourceCompiler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2SourceCompiler.java new file mode 100644 index 00000000000..05453ac63e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/Form2SourceCompiler.java @@ -0,0 +1,259 @@ +package com.intellij.uiDesigner.make; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiDesignerConfiguration; +import com.intellij.uiDesigner.compiler.AlienFormFileException; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public final class Form2SourceCompiler implements SourceInstrumentingCompiler{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.make.Form2SourceCompiler"); + + private final Project myProject; + + public Form2SourceCompiler(final Project project) { + myProject = project; + } + + public String getDescription() { + return "GUI Designer form to source compiler"; + } + + public boolean validateConfiguration(CompileScope scope) { + return true; + } + + public ProcessingItem[] getProcessingItems(final CompileContext context) { + if (GuiDesignerConfiguration.getInstance(myProject).INSTRUMENT_CLASSES) { + return ProcessingItem.EMPTY_ARRAY; + } + + final ArrayList items = new ArrayList(); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final CompileScope scope = context.getCompileScope(); + + final VirtualFile[] formFiles = scope.getFiles(StdFileTypes.GUI_DESIGNER_FORM, true); + final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + final BindingsCache bindingsCache = new BindingsCache(myProject); + + try { + final HashMap class2form = new HashMap(); + + for (int i = 0; i < formFiles.length; i++) { + final VirtualFile formFile = formFiles[i]; + + if (compilerConfiguration.isExcludedFromCompilation(formFile)) { + continue; + } + + final String classToBind; + try { + classToBind = bindingsCache.getBoundClassName(formFile); + } + catch (AlienFormFileException e) { + // ignore non-IDEA forms + continue; + } + catch (Exception e) { + addError(context, "Cannot process form file. Reason: " + e, formFile); + continue; + } + + if (classToBind == null) { + continue; + } + + final VirtualFile sourceFile = findSourceFile(formFile, classToBind); + if (sourceFile == null) { + if (context.getCompileScope().belongs(formFile.getUrl())) { + addError(context, "Class to bind does not exist: " + classToBind, formFile); + } + continue; + } + + final VirtualFile alreadyProcessedForm = class2form.get(classToBind); + if (alreadyProcessedForm != null) { + addError( + context, + "The form is bound to the class " + classToBind + ".\n" + + "Another form " + alreadyProcessedForm.getPresentableUrl() + " is also bound to this class.", + formFile + ); + continue; + } + class2form.put(classToBind, formFile); + + final ProcessingItem item = new MyInstrumentationItem(sourceFile, formFile); + items.add(item); + } + } + finally { + bindingsCache.save(); + } + } + }); + + return items.toArray(new ProcessingItem[items.size()]); + } + + + private VirtualFile findSourceFile(final VirtualFile formFile, final String className) { + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module == null) { + return null; + } + final PsiClass aClass = FormEditingUtil.findClassToBind(module, className); + if (aClass == null) { + return null; + } + + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile == null){ + return null; + } + + return containingFile.getVirtualFile(); + } + + public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) { + final ArrayList compiledItems = new ArrayList(); + + context.getProgressIndicator().setText("Compiling UI forms..."); + + int formsProcessed = 0; + + final FormSourceCodeGenerator generator = new FormSourceCodeGenerator(myProject); + + final HashSet processedModules = new HashSet(); + + for (int i = 0; i < items.length; i++) { + context.getProgressIndicator().setFraction((double)(++formsProcessed) / ((double)items.length)); + + final MyInstrumentationItem item = (MyInstrumentationItem)items[i]; + + final VirtualFile formFile = item.getFormFile(); + + if (GuiDesignerConfiguration.getInstance(myProject).COPY_FORMS_RUNTIME_TO_OUTPUT) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module != null && !processedModules.contains(module)) { + processedModules.add(module); + final String moduleOutputPath = CompilerPaths.getModuleOutputPath(module, false); + try { + if (moduleOutputPath != null) { + CopyResourcesUtil.copyFormsRuntime(moduleOutputPath, false); + } + final String testsOutputPath = CompilerPaths.getModuleOutputPath(module, true); + if (testsOutputPath != null && !testsOutputPath.equals(moduleOutputPath)) { + CopyResourcesUtil.copyFormsRuntime(testsOutputPath, false); + } + } + catch (IOException e) { + addError( + context, + "Cannot copy GUI designer form runtime classes to the output directory of module " + module.getName() + + ".\nReason: " + e.toString(), + null + ); + } + } + } + }); + } + + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand( + myProject, + new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + generator.generate(formFile); + final ArrayList errors = generator.getErrors(); + if (errors.size() == 0) { + compiledItems.add(item); + } + else { + for (int j = 0; j < errors.size(); j++) { + final String s = errors.get(j); + addError(context, s, formFile); + } + } + FileDocumentManager.getInstance().saveAllDocuments(); + } + } + ); + } + }, + "", + null + ); + } + }, ModalityState.NON_MMODAL); + } + return compiledItems.toArray(new ProcessingItem[compiledItems.size()]); + } + + private static void addError(final CompileContext context, final String message, final VirtualFile formFile) { + if (formFile != null) { + context.addMessage(CompilerMessageCategory.ERROR, formFile.getPresentableUrl() + ": " + message, formFile.getUrl(), -1, -1); + } + else { + context.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + } + } + + public ValidityState createValidityState(final DataInputStream is) throws IOException { + return new TimestampValidityState(is.readLong()); + } + + private static final class MyInstrumentationItem implements ProcessingItem { + private final VirtualFile mySourceFile; + private final VirtualFile myFormFile; + private final TimestampValidityState myState; + + public MyInstrumentationItem(final VirtualFile sourceFile, final VirtualFile formFile) { + mySourceFile = sourceFile; + myFormFile = formFile; + myState = new TimestampValidityState(formFile.getTimeStamp()); + } + + public VirtualFile getFile() { + return mySourceFile; + } + + public VirtualFile getFormFile() { + return myFormFile; + } + + public ValidityState getValidityState() { + return myState; + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/FormSourceCodeGenerator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/FormSourceCodeGenerator.java new file mode 100644 index 00000000000..23209a285e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/make/FormSourceCodeGenerator.java @@ -0,0 +1,783 @@ +package com.intellij.uiDesigner.make; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.uiDesigner.ErrorAnalizer; +import com.intellij.uiDesigner.ErrorInfo; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.PsiPropertiesProvider; +import com.intellij.uiDesigner.compiler.AlienFormFileException; +import com.intellij.uiDesigner.compiler.ClassToBindNotFoundException; +import com.intellij.uiDesigner.compiler.CodeGenerationException; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.core.SupportCode; +import com.intellij.uiDesigner.lw.*; +import com.intellij.uiDesigner.shared.BorderType; +import com.intellij.util.IncorrectOperationException; +import gnu.trove.TIntObjectHashMap; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; + +public final class FormSourceCodeGenerator { + private StringBuffer myBuffer; + private Stack myIsFirstParameterStack; + private final Project myProject; + private final ArrayList myErrors; + + private static final TIntObjectHashMap myAnchors = fillMap(GridConstraints.class, "ANCHOR_"); + private static final TIntObjectHashMap myFills = fillMap(GridConstraints.class, "FILL_"); + + public FormSourceCodeGenerator(final Project project){ + if (project == null){ + throw new IllegalArgumentException("project cannot be null"); + } + myProject = project; + myErrors = new ArrayList(); + } + + public void generate(final VirtualFile formFile) { + final Module module = ModuleUtil.getModuleForFile(myProject, formFile); + if (module == null) { + return; + } + + final PsiPropertiesProvider propertiesProvider = new PsiPropertiesProvider(module); + + final Document doc = FileDocumentManager.getInstance().getDocument(formFile); + final LwRootContainer rootContainer; + try { + rootContainer = Utils.getRootContainer(doc.getText(), propertiesProvider); + } + catch (AlienFormFileException ignored) { + // ignoring this file + return; + } + catch (Exception e) { + myErrors.add("Cannot process form file. Reason: " + e); + return; + } + + if (rootContainer.getClassToBind() == null) { + // form skipped - no class to bind + return; + } + + ErrorAnalizer.analyzeErrors(module, formFile, null, rootContainer); + FormEditingUtil.iterate( + rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final LwComponent iComponent) { + final ErrorInfo errorInfo = ErrorAnalizer.getErrorForComponent(iComponent); + if (errorInfo != null){ + myErrors.add(errorInfo.myDescription); + } + return true; + } + } + ); + + if (myErrors.size() != 0) { + return; + } + + try { + _generate(rootContainer, module); + } + catch (ClassToBindNotFoundException e) { + // ignored + return; + } + catch (CodeGenerationException e) { + myErrors.add(e.getMessage()); + } + catch (IncorrectOperationException e) { + myErrors.add(e.getMessage()); + } + } + + public ArrayList getErrors() { + return myErrors; + } + + private void _generate(final LwRootContainer rootContainer, final Module module) throws CodeGenerationException, IncorrectOperationException{ + myBuffer = new StringBuffer(); + myIsFirstParameterStack = new Stack(); + + final HashMap component2variable = new HashMap(); + final HashMap class2variableIndex = new HashMap(); + + if (rootContainer.getComponentCount() != 1) { + throw new CodeGenerationException("There should be only one component at the top level"); + } + if (containsNotEmptyPanelsWithXYLayout((LwComponent)rootContainer.getComponent(0))) { + throw new CodeGenerationException("There are non empty panels with XY layout. Please lay them out in a grid."); + } + + final GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module); + generateSetupCodeForComponent((LwComponent)rootContainer.getComponent(0), component2variable, class2variableIndex, scope); + + final String methodText = myBuffer.toString(); + + final PsiManager psiManager = PsiManager.getInstance(module.getProject()); + final PsiElementFactory elementFactory = psiManager.getElementFactory(); + + final PsiClass aClass = FormEditingUtil.findClassToBind(module, rootContainer.getClassToBind()); + if (aClass == null) { + throw new ClassToBindNotFoundException("Class to bind not found: " + rootContainer.getClassToBind()); + } + + cleanup(aClass); + + // [anton] the comments are written according to the SCR 26896 + final PsiClass fakeClass = elementFactory.createClassFromText( + "{\n" + + "// GUI initializer generated by IntelliJ IDEA GUI Designer \n" + + "// >>> IMPORTANT!! <<<\n" + + "// DO NOT EDIT OR ADD ANY CODE HERE!\n" + + "" + METHOD_NAME + "();\n" + + "}\n" + + "\n" + + "/** Method generated by IntelliJ IDEA GUI Designer\n" + + " * >>> IMPORTANT!! <<<\n" + + " * DO NOT edit this method OR call it in your code!\t" + + " */\n" + + "private void " + METHOD_NAME + "()\n" + + "{\n" + + methodText + + "}\n", + null + ); + + final PsiElement method = aClass.add(fakeClass.getMethods()[0]); + final PsiElement initializer = aClass.addBefore(fakeClass.getInitializers()[0], method); + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(module.getProject()); + codeStyleManager.shortenClassReferences(method); + codeStyleManager.reformat(method); + codeStyleManager.shortenClassReferences(initializer); + codeStyleManager.reformat(initializer); + } + + public final static String METHOD_NAME = "$$$setupUI$$$"; + + public static void cleanup(final PsiClass aClass) throws IncorrectOperationException{ + final PsiMethod[] methods = aClass.findMethodsByName(METHOD_NAME, false); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + + final PsiClassInitializer[] initializers = aClass.getInitializers(); + for (int j = 0; j < initializers.length; j++) { + final PsiClassInitializer initializer = initializers[j]; + + if (containsMethodIdentifier(initializer, method)) { + initializer.delete(); + } + } + + method.delete(); + } + } + + private static boolean containsMethodIdentifier(final PsiElement element, final PsiMethod setupMethod) { + if (element instanceof PsiMethodCallExpression) { + final PsiMethod psiMethod = ((PsiMethodCallExpression)element).resolveMethod(); + if (setupMethod.equals(psiMethod)){ + return true; + } + } + final PsiElement[] children = element.getChildren(); + for (int i = children.length - 1; i >= 0; i--) { + if (containsMethodIdentifier(children[i], setupMethod)) { + return true; + } + } + return false; + } + + + private static boolean containsNotEmptyPanelsWithXYLayout(final LwComponent component) { + if (!(component instanceof LwContainer)) { + return false; + } + final LwContainer container = (LwContainer)component; + if (container.getComponentCount() == 0){ + return false; + } + if (container.isXY()){ + return true; + } + for (int i=0; i < container.getComponentCount(); i++){ + if (containsNotEmptyPanelsWithXYLayout((LwComponent)container.getComponent(i))) { + return true; + } + } + return false; + } + + private void generateSetupCodeForComponent( + final LwComponent component, + final HashMap component2TempVariable, + final HashMap class2variableIndex, + final GlobalSearchScope globalSearchScope + ) throws CodeGenerationException{ + final LwContainer parent = component.getParent(); + + final String variable = getVariable(component, component2TempVariable, class2variableIndex); + + final String binding = component.getBinding(); + if (binding != null) { + myBuffer.append(binding); + } + else { + myBuffer.append("final "); + myBuffer.append(component.getComponentClassName()); + myBuffer.append(" "); + myBuffer.append(variable); + } + myBuffer.append('='); + startConstructor(component.getComponentClassName()); + endConstructor(); // will finish the line + + // set layout to container + if (component instanceof LwScrollPane) { + // no layout needed + } + else if (component instanceof LwTabbedPane) { + // no layout needed + } + else if (component instanceof LwSplitPane) { + // no layout needed + } + else if (component instanceof LwContainer) { + final LwContainer container = (LwContainer)component; + + if (container.isXY()) { + if (container.getComponentCount() != 0) { + throw new IllegalStateException("only empty xys are accepted"); + } + // no layout needed + } + else { + if (container.isGrid()) { + final GridLayoutManager layout = (GridLayoutManager)container.getLayout(); + + startMethodCall(variable, "setLayout"); + + startConstructor(GridLayoutManager.class.getName()); + + push(layout.getRowCount()); + push(layout.getColumnCount()); + + newInsets(layout.getMargin()); + + push(layout.getHGap()); + push(layout.getVGap()); + + if (layout.isSameSizeHorizontally() || layout.isSameSizeVertically()) { + // values differ from the defaults - use appropriate constructor + push(layout.isSameSizeHorizontally()); + push(layout.isSameSizeVertically()); + } + + endConstructor(); // GridLayoutManager + + endMethod(); + } + else if (container.isXY()) { + throw new IllegalArgumentException("XY is not supported"); + } + else { + throw new IllegalArgumentException("unknown layout: " + container.getLayout()); + } + } + } + + // introspected properties + final LwIntrospectedProperty[] introspectedProperties = component.getAssignedIntrospectedProperties(); + + // see SCR #35990 + Arrays.sort(introspectedProperties, new Comparator() { + public int compare(LwIntrospectedProperty p1, LwIntrospectedProperty p2) { + return p1.getName().compareTo(p2.getName()); + } + }); + + for (int i = 0; i < introspectedProperties.length; i++) { + final LwIntrospectedProperty property = introspectedProperties[i]; + + Object value = component.getPropertyValue(property); + + final String componentClass = component.getComponentClassName(); + final boolean isTextWithMnemonicProperty = + "text".equals(property.getName()) && + (isAssignableFrom(AbstractButton.class.getName(), componentClass, globalSearchScope) || + isAssignableFrom(JLabel.class.getName(), componentClass, globalSearchScope)); + + // handle resource bundles + if (property instanceof LwRbIntroStringProperty) { + final StringDescriptor descriptor = (StringDescriptor)value; + if (descriptor.getValue() == null) { + if (isTextWithMnemonicProperty) { + startStaticMethodCall(SupportCode.class, "setTextFromBundle"); + pushVar(variable); + push(descriptor.getBundleName()); + push(descriptor.getKey()); + endMethod(); + } + else { + startMethodCall(variable, property.getWriteMethodName()); + push(descriptor); + endMethod(); + } + + continue; + } + else { + value = descriptor.getValue(); + } + } + + SupportCode.TextWithMnemonic textWithMnemonic = null; + if (isTextWithMnemonicProperty) { + textWithMnemonic = SupportCode.parseText((String)value); + value = textWithMnemonic.myText; + } + + startMethodCall(variable, property.getWriteMethodName()); + + + final String propertyClass = property.getPropertyClassName(); + if (propertyClass.equals(Dimension.class.getName())) { + newDimension((Dimension)value); + } + else if (propertyClass.equals(Integer.class.getName())){ + push(((Integer)value).intValue()); + } + else if (propertyClass.equals(Double.class.getName())){ + push(((Double)value).doubleValue()); + } + else if (propertyClass.equals(Boolean.class.getName())){ + push(((Boolean)value).booleanValue()); + } + else if (propertyClass.equals(Rectangle.class.getName())) { + newRectangle((Rectangle)value); + } + else if (propertyClass.equals(Insets.class.getName())) { + newInsets((Insets)value); + } + else if (propertyClass.equals(String.class.getName())) { + push((String)value); + } + else { + throw new RuntimeException("unexpected property class: " + propertyClass); + } + + endMethod(); + + // special handling of mnemonics + + if (!isTextWithMnemonicProperty) { + continue; + } + + if (textWithMnemonic.myMnemonicIndex == -1) { + continue; + } + + if (isAssignableFrom(AbstractButton.class.getName(), componentClass, globalSearchScope)) { + startMethodCall(variable, "setMnemonic"); + push(textWithMnemonic.getMnemonicChar()); + endMethod(); + + startStaticMethodCall(SupportCode.class, "setDisplayedMnemonicIndex"); + pushVar(variable); + push(textWithMnemonic.myMnemonicIndex); + endMethod(); + } + else if (isAssignableFrom(JLabel.class.getName(), componentClass, globalSearchScope)) { + startMethodCall(variable, "setDisplayedMnemonic"); + push(textWithMnemonic.getMnemonicChar()); + endMethod(); + + startStaticMethodCall(SupportCode.class, "setDisplayedMnemonicIndex"); + pushVar(variable); + push(textWithMnemonic.myMnemonicIndex); + endMethod(); + } + } + + // add component to parent + if (!(component.getParent() instanceof LwRootContainer)) { + + if (parent instanceof LwScrollPane) { + startMethodCall(getVariable(parent, component2TempVariable, class2variableIndex), "setViewportView"); + pushVar(variable); + endMethod(); + } + else if (parent instanceof LwTabbedPane) { + final LwTabbedPane.Constraints tabConstraints = (LwTabbedPane.Constraints)component.getCustomLayoutConstraints(); + if (tabConstraints == null){ + throw new IllegalArgumentException("tab constraints cannot be null: " + component.getId()); + } + + startMethodCall(getVariable(parent, component2TempVariable, class2variableIndex), "addTab"); + push(tabConstraints.myTitle); + pushVar(variable); + endMethod(); + } + else if (parent instanceof LwSplitPane) { + final String methodName = + LwSplitPane.POSITION_LEFT.equals(component.getCustomLayoutConstraints()) ? + "setLeftComponent" : + "setRightComponent"; + + startMethodCall(getVariable(parent, component2TempVariable, class2variableIndex), methodName); + pushVar(variable); + endMethod(); + } + else { + startMethodCall(getVariable(parent, component2TempVariable, class2variableIndex), "add"); + pushVar(variable); + addNewGridConstraints(component); + endMethod(); + } + } + + if (component instanceof LwContainer) { + final LwContainer container = (LwContainer)component; + + // border + + final BorderType borderType = container.getBorderType(); + final StringDescriptor borderTitle = container.getBorderTitle(); + final String borderFactoryMethodName = borderType.getBorderFactoryMethodName(); + + final boolean borderNone = borderType.equals(BorderType.NONE); + if (!borderNone || borderTitle != null) { + startMethodCall(variable, "setBorder"); + + + startStaticMethodCall(BorderFactory.class, "createTitledBorder"); + + if (!borderNone) { + startStaticMethodCall(BorderFactory.class, borderFactoryMethodName); + endMethod(); + } + + push(borderTitle); + + endMethod(); // createTitledBorder + + endMethod(); // setBorder + } + + for (int i = 0; i < container.getComponentCount(); i++) { + generateSetupCodeForComponent((LwComponent)container.getComponent(i), component2TempVariable, class2variableIndex, globalSearchScope); + } + } + } + + private void push(final StringDescriptor descriptor) { + if (descriptor == null) { + push((String)null); + } + else if (descriptor.getValue() != null) { + push(descriptor.getValue()); + } + else { + startStaticMethodCall(SupportCode.class, "getResourceString"); + push(descriptor.getBundleName()); + push(descriptor.getKey()); + endMethod(); + } + } + + private boolean isAssignableFrom(final String className, final String fromName, final GlobalSearchScope scope) { + final PsiClass aClass = PsiManager.getInstance(myProject).findClass(className, scope); + final PsiClass fromClass = PsiManager.getInstance(myProject).findClass(fromName, scope); + if (aClass == null || fromClass == null) { + return false; + } + return InheritanceUtil.isInheritorOrSelf(fromClass, aClass, true); + } + + /** + * @return variable idx + */ + private static String getVariable( + final LwComponent component, + final HashMap component2variable, + final HashMap class2variableIndex + ){ + if (component2variable.containsKey(component)){ + return component2variable.get(component); + } + + if (component.getBinding() != null) { + return component.getBinding(); + } + + final String className = component.getComponentClassName(); + + final String shortName; + if (className.startsWith("javax.swing.J")) { + shortName = className.substring("javax.swing.J".length()); + } + else { + final int idx = className.lastIndexOf('.'); + if (idx != -1) { + shortName = className.substring(idx + 1); + } + else { + shortName = className; + } + } + + // todo[anton] check that no generated name is equal to class' field + + final Integer indexObj = class2variableIndex.get(className); + final int index = indexObj != null ? indexObj.intValue() : 0; + final Integer newIndexObj = new Integer(index + 1); + class2variableIndex.put(className, newIndexObj); + + final String result = Character.toLowerCase(shortName.charAt(0)) + shortName.substring(1) + newIndexObj; + component2variable.put(component, result); + + return result; + } + + private void addNewGridConstraints(final LwComponent component){ + final GridConstraints constraints = component.getConstraints(); + + startConstructor(GridConstraints.class.getName()); + push(constraints.getRow()); + push(constraints.getColumn()); + push(constraints.getRowSpan()); + push(constraints.getColSpan()); + push(constraints.getAnchor(), myAnchors); + push(constraints.getFill(), myFills); + pushSizePolicy(constraints.getHSizePolicy()); + pushSizePolicy(constraints.getVSizePolicy()); + newDimensionOrNull(constraints.myMinimumSize); + newDimensionOrNull(constraints.myPreferredSize); + newDimensionOrNull(constraints.myMaximumSize); + endConstructor(); + } + + private void newDimensionOrNull(final Dimension dimension) { + if (dimension.width == -1 && dimension.height == -1) { + checkParameter(); + myBuffer.append("null"); + } + else { + newDimension(dimension); + } + } + + private void newDimension(final Dimension dimension) { + startConstructor(Dimension.class.getName()); + push(dimension.width); + push(dimension.height); + endConstructor(); + } + + private void newInsets(final Insets insets){ + startConstructor(Insets.class.getName()); + push(insets.top); + push(insets.left); + push(insets.bottom); + push(insets.right); + endConstructor(); + } + + private void newRectangle(final Rectangle rectangle){ + startConstructor(Insets.class.getName()); + push(rectangle.x); + push(rectangle.y); + push(rectangle.width); + push(rectangle.height); + endConstructor(); + } + + + private void startMethodCall(final String variable, final String methodName) { + checkParameter(); + + appendVarName(variable); + myBuffer.append('.'); + myBuffer.append(methodName); + myBuffer.append('('); + + myIsFirstParameterStack.push(Boolean.TRUE); + } + + private void startStaticMethodCall(final Class aClass, final String methodName) { + checkParameter(); + + myBuffer.append(aClass.getName()); + myBuffer.append('.'); + myBuffer.append(methodName); + myBuffer.append('('); + + myIsFirstParameterStack.push(Boolean.TRUE); + } + + private void endMethod() { + myBuffer.append(')'); + + myIsFirstParameterStack.pop(); + + if (myIsFirstParameterStack.empty()) { + myBuffer.append(";\n"); + } + } + + private void startConstructor(final String className) { + checkParameter(); + + myBuffer.append("new "); + myBuffer.append(className); + myBuffer.append('('); + + myIsFirstParameterStack.push(Boolean.TRUE); + } + + private void endConstructor() { + endMethod(); + } + + private void push(final int value) { + checkParameter(); + myBuffer.append(value); + } + + private void push(final int value, final TIntObjectHashMap map){ + final String stringRepresentation = (String)map.get(value); + if (stringRepresentation != null) { + checkParameter(); + myBuffer.append(stringRepresentation); + } + else { + push(value); + } + } + + private void pushSizePolicy(final int value) { + final String className = GridConstraints.class.getName(); + + String presentation; + if (GridConstraints.SIZEPOLICY_FIXED == value) { + presentation = className + ".SIZEPOLICY_FIXED"; + } + else { + if ((value & GridConstraints.SIZEPOLICY_CAN_SHRINK) != 0) { + presentation = className + ".SIZEPOLICY_CAN_SHRINK"; + } + else { + presentation = null; + } + + if ((value & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) { + if (presentation == null) { + presentation = className + ".SIZEPOLICY_WANT_GROW"; + } + else { + presentation += "|" + className + ".SIZEPOLICY_WANT_GROW"; + } + } + else if ((value & GridConstraints.SIZEPOLICY_CAN_GROW) != 0) { + if (presentation == null) { + presentation = className + ".SIZEPOLICY_CAN_GROW"; + } + else { + presentation += "|" + className + ".SIZEPOLICY_CAN_GROW"; + } + } + else { + // ? + push(value); + return; + } + } + + checkParameter(); + myBuffer.append(presentation); + } + + private void push(final double value) { + checkParameter(); + myBuffer.append(value); + } + + private void push(final boolean value) { + checkParameter(); + myBuffer.append(value); + } + + private void push(final String value) { + checkParameter(); + if (value == null) { + myBuffer.append("null"); + } + else { + myBuffer.append('"'); + myBuffer.append(StringUtil.escapeStringCharacters(value)); + myBuffer.append('"'); + } + } + + private void pushVar(final String variable) { + checkParameter(); + appendVarName(variable); + } + + private void appendVarName(final String variable) { + myBuffer.append(variable); + } + + private void checkParameter() { + if (!myIsFirstParameterStack.empty()) { + final Boolean b = myIsFirstParameterStack.pop(); + if (b.equals(Boolean.FALSE)) { + myBuffer.append(','); + } + myIsFirstParameterStack.push(Boolean.FALSE); + } + } + + private static TIntObjectHashMap fillMap(final Class aClass, final String prefix) { + final TIntObjectHashMap map = new TIntObjectHashMap(); + + final Field[] fields = aClass.getFields(); + for (int i = 0; i < fields.length; i++) { + final Field field = fields[i]; + if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getName().startsWith(prefix)) { + field.setAccessible(true); + try { + final int value = field.getInt(aClass); + map.put(value, aClass.getName() + '.' + field.getName()); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + return map; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItem.java new file mode 100644 index 00000000000..a5d6a8983c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItem.java @@ -0,0 +1,270 @@ +package com.intellij.uiDesigner.palette; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; + +import javax.swing.*; +import java.util.HashMap; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ComponentItem implements Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.palette.ComponentItem"); + + private String myClassName; + private final GridConstraints myDefaultConstraints; + /** + * Do not use this member directly. Use {@link #getIcon()} instead. + */ + private Icon myIcon; + /** + * Do not use this member directly. Use {@link #getSmallIcon()} instead. + */ + private Icon mySmallIcon; + /** + * @see #getIconPath() + * @see #setIconPath(java.lang.String) + */ + private String myIconPath; + /** + * Do not access this field directly. Use {@link #getToolTipText()} instead. + */ + final String myToolTipText; + private final HashMap myPropertyName2intitialValue; + /** Whether item is removable or not */ + private final boolean myRemovable; + + /** + * @param iconPath can be null. + * @param toolTipText if null, will be automatically calculated + * @param propertyName2intitialValue cannot be null + */ + public ComponentItem( + final String className, + final String iconPath, + final String toolTipText, + final GridConstraints defaultConstraints, + final HashMap propertyName2intitialValue, + final boolean removable + ){ + LOG.assertTrue(defaultConstraints != null); + LOG.assertTrue(propertyName2intitialValue != null); + + setClassName(className); + setIconPath(iconPath); + + myToolTipText = toolTipText; + myDefaultConstraints = defaultConstraints; + myPropertyName2intitialValue = propertyName2intitialValue; + + myRemovable = removable; + } + + /** + * @return whether the item is removable from palette or not. + */ + public boolean isRemovable() { + return myRemovable; + } + + private static String calcToolTipText(final String className) { + LOG.assertTrue(className != null); + + final int lastDotIndex = className.lastIndexOf('.'); + if (lastDotIndex != -1 && lastDotIndex != className.length() - 1/*not the last char in class name*/) { + return className.substring(lastDotIndex + 1) + " (" + className.substring(0, lastDotIndex) + ")"; + } + else{ + return className; + } + } + + /** Creates deep copy of the object. You can edit any properties of the returned object. */ + public ComponentItem clone(){ + final ComponentItem result = new ComponentItem( + myClassName, + myIconPath, + myToolTipText, + (GridConstraints)myDefaultConstraints.clone(), + (HashMap)myPropertyName2intitialValue.clone(), + myRemovable + ); + return result; + } + + /** + * @return string that represents path in the JAR file system that was used to load + * icon returned by {@link #getIcon()} method. This method can returns null. + * It means that palette item has some "unknown" item. + */ + String getIconPath(){ + return myIconPath; + } + + /** + * @param iconPath new path inside JAR file system. null means that + * iconPath is not specified and some "unknown" icon should be used + * to represent the {@link ComponentItem} in UI. + */ + void setIconPath(final String iconPath){ + myIcon = null; // reset cached icon + mySmallIcon = null; // reset cached icon + + myIconPath = iconPath; + } + + /** + * @return item's icon. This icon is used to represent item at the toolbar. + * Note, that the method never returns null. It returns some + * default "unknown" icon for the items that has no specified icon in the XML. + */ + public Icon getIcon(){ + // Check cached value first + if(myIcon != null){ + return myIcon; + } + + // Create new icon + if(myIconPath != null){ + myIcon = IconLoader.getIcon(myIconPath); + } + if(myIcon == null){ + myIcon = IconLoader.getIcon("/com/intellij/uiDesigner/icons/unknown.png"); + } + LOG.assertTrue(myIcon != null); + return myIcon; + } + + /** + * @return small item's icon. This icon represents component in the + * component tree. The method never returns null. It returns some + * default "unknown" icon for the items that has no specified icon in the XML. + */ + public Icon getSmallIcon(){ + // Check cached value first + if(mySmallIcon != null){ + return myIcon; + } + + // [vova] It's safe to cast to ImageIcon here because all icons loaded by IconLoader + // are ImageIcon(s). + final ImageIcon icon = (ImageIcon)getIcon(); + mySmallIcon = new MySmallIcon(icon.getImage()); + return mySmallIcon; + } + + /** + * @return name of component's class which is represented by the item. + * This method never returns null. + */ + public String getClassName() { + return myClassName; + } + + /** + * @param className name of the class that will be instanteated when user drop + * item on the form. Cannot be null. If the class does not exist or + * could not be instanteated (for example, class has no default constructor, + * it's not a subclass of JComponent, etc) then placeholder component will be + * added to the form. + */ + public void setClassName(final String className){ + LOG.assertTrue(className != null); + myClassName = className; + } + + public String getToolTipText() { + return myToolTipText != null ? myToolTipText : calcToolTipText(myClassName); + } + + /** + * @return never null. + */ + public GridConstraints getDefaultConstraints() { + return myDefaultConstraints; + } + + /** + * The method returns initial value of the property. Term + * "initial" means that just after creation of RadComponent + * all its properties are set into initial values. + * The method returns null if the + * initial property is not defined. Unfortunately we cannot + * put this method into the constuctor of RadComponent. + * The problem is that RadComponent is used in the + * code genaration and code generation doesn't depend on any + * ComponentItem, so we need to initialize RadComponent + * in all places where it's needed explicitly. + */ + public Object getInitialValue(final IntrospectedProperty property){ + return myPropertyName2intitialValue.get(property.getName()); + } + + /** + * Internal method. It should be used only to externalize initial item's values. + * This method never returns null. + */ + HashMap getInitialValues(){ + return myPropertyName2intitialValue; + } + + public boolean equals(final Object o) { + if (this == o) return true; + if (!(o instanceof ComponentItem)) return false; + + final ComponentItem componentItem = (ComponentItem)o; + + if (myClassName != null ? !myClassName.equals(componentItem.myClassName) : componentItem.myClassName != null) return false; + if (myDefaultConstraints != null + ? !myDefaultConstraints.equals(componentItem.myDefaultConstraints) + : componentItem.myDefaultConstraints != null) { + return false; + } + if (myIconPath != null ? !myIconPath.equals(componentItem.myIconPath) : componentItem.myIconPath != null) return false; + if (myPropertyName2intitialValue != null + ? !myPropertyName2intitialValue.equals(componentItem.myPropertyName2intitialValue) + : componentItem.myPropertyName2intitialValue != null) { + return false; + } + if (myToolTipText != null ? !myToolTipText.equals(componentItem.myToolTipText) : componentItem.myToolTipText != null) return false; + + return true; + } + + public int hashCode() { + int result; + result = (myClassName != null ? myClassName.hashCode() : 0); + result = 29 * result + (myDefaultConstraints != null ? myDefaultConstraints.hashCode() : 0); + result = 29 * result + (myIconPath != null ? myIconPath.hashCode() : 0); + result = 29 * result + (myToolTipText != null ? myToolTipText.hashCode() : 0); + result = 29 * result + (myPropertyName2intitialValue != null ? myPropertyName2intitialValue.hashCode() : 0); + return result; + } + + private static final class MySmallIcon implements Icon{ + private final Image myImage; + + public MySmallIcon(final Image delegate) { + LOG.assertTrue(delegate != null); + myImage = delegate; + } + + public int getIconHeight() { + return 18; + } + + public int getIconWidth() { + return 18; + } + + public void paintIcon(final Component c, final Graphics g, final int x, final int y) { + g.drawImage(myImage, 2, 2, 14, 14, c); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItemDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItemDialog.java new file mode 100644 index 00000000000..c69b0728608 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/ComponentItemDialog.java @@ -0,0 +1,126 @@ +package com.intellij.uiDesigner.palette; + +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.psi.PsiClass; +import com.intellij.uiDesigner.core.GridConstraints; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Vladimir Kondratyev + */ +public final class ComponentItemDialog extends DialogWrapper{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.palette.ComponentItemDialog"); + + private JPanel myPanel; + private TextFieldWithBrowseButton myTfClassName; + private final ComponentItem myItemToBeEdited; + private JLabel myLblClass; + private JLabel myLblIcon; + private JTextField myTfIconPath; + private JCheckBox myChkHorCanShrink; + private JCheckBox myChkHorCanGrow; + private JCheckBox myChkHorWantGrow; + private JCheckBox myChkVerCanShrink; + private JCheckBox myChkVerCanGrow; + private JCheckBox myChkVerWantGrow; + + /** + * @param itemToBeEdited item to be edited. If user closes dialog by "OK" button then + */ + public ComponentItemDialog(final Project project, final Component parent, final ComponentItem itemToBeEdited) { + super(parent, false); + LOG.assertTrue(itemToBeEdited != null); + + myItemToBeEdited = itemToBeEdited; + + myTfClassName.setText(myItemToBeEdited.getClassName()); + myTfClassName.getButton().setEnabled(!project.isDefault()); // chooser should not work in default project + myTfClassName.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final TreeClassChooserDialog chooser = new TreeClassChooserDialog("Choose Component Class", project); + chooser.show(); + final PsiClass result = chooser.getSelectedClass(); + if (result != null) { + myTfClassName.setText(result.getQualifiedName()); + } + } + } + ); + + myTfIconPath.setText(myItemToBeEdited.getIconPath()); + + final GridConstraints defaultConstraints = myItemToBeEdited.getDefaultConstraints(); + + // Horizontal size policy + { + final int hSizePolicy = defaultConstraints.getHSizePolicy(); + myChkHorCanShrink.setSelected((hSizePolicy & GridConstraints.SIZEPOLICY_CAN_SHRINK) != 0); + myChkHorCanGrow.setSelected((hSizePolicy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0); + myChkHorWantGrow.setSelected((hSizePolicy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0); + } + + // Vertical size policy + { + final int vSizePolicy = defaultConstraints.getVSizePolicy(); + myChkVerCanShrink.setSelected((vSizePolicy & GridConstraints.SIZEPOLICY_CAN_SHRINK) != 0); + myChkVerCanGrow.setSelected((vSizePolicy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0); + myChkVerWantGrow.setSelected((vSizePolicy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0); + } + + myLblClass.setLabelFor(myTfClassName); + myLblIcon.setLabelFor(myTfIconPath); + + init(); + } + + + + protected void doOKAction() { + // TODO[vova] implement validation + myItemToBeEdited.setClassName(myTfClassName.getText().trim()); + myItemToBeEdited.setIconPath(myTfIconPath.getText().trim()); + + // Horizontal size policy + { + final GridConstraints defaultConstraints = myItemToBeEdited.getDefaultConstraints(); + defaultConstraints.setHSizePolicy( + (myChkHorCanShrink.isSelected() ? GridConstraints.SIZEPOLICY_CAN_SHRINK : 0) | + (myChkHorCanGrow.isSelected() ? GridConstraints.SIZEPOLICY_CAN_GROW : 0) | + (myChkHorWantGrow.isSelected() ? GridConstraints.SIZEPOLICY_WANT_GROW : 0) + ); + } + + // Vertical size policy + { + final GridConstraints defaultConstraints = myItemToBeEdited.getDefaultConstraints(); + defaultConstraints.setVSizePolicy( + (myChkVerCanShrink.isSelected() ? GridConstraints.SIZEPOLICY_CAN_SHRINK : 0) | + (myChkVerCanGrow.isSelected() ? GridConstraints.SIZEPOLICY_CAN_GROW : 0) | + (myChkVerWantGrow.isSelected() ? GridConstraints.SIZEPOLICY_WANT_GROW : 0) + ); + } + + super.doOKAction(); + } + + protected String getDimensionServiceKey() { + return "#com.intellij.uiDesigner.palette.ComponentItemDialog"; + } + + public JComponent getPreferredFocusedComponent() { + return myTfClassName.getTextField(); + } + + protected JComponent createCenterPanel() { + return myPanel; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/GroupItem.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/GroupItem.java new file mode 100644 index 00000000000..ee56db68630 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/GroupItem.java @@ -0,0 +1,94 @@ +package com.intellij.uiDesigner.palette; + +import com.intellij.openapi.diagnostic.Logger; + +import java.util.ArrayList; + +/** + * @author Vladimir Kondratyev + */ +public final class GroupItem implements Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.palette.GroupItem"); + + private String myName; + private final ArrayList myItems; + + public GroupItem(final String name) { + setName(name); + myItems = new ArrayList(); + } + + /** + * @return deep copy of the {@link GroupItem} with copied items. + */ + public GroupItem clone(){ + final GroupItem result = new GroupItem(myName); + + for(int i = 0; i < myItems.size(); i++){ + result.addItem(myItems.get(i).clone()); + } + + return result; + } + + /** + * @return never null. + */ + public String getName() { + return myName; + } + + /** + * @param name cannot be null. + */ + public void setName(final String name){ + LOG.assertTrue(name != null); + myName = name; + } + + /** + * @return read-only list of items that belong to the group. + * The method never returns null. + */ + public ArrayList getItems() { + return myItems; + } + + /** Adds specified {@link ComponentItem} to the group.*/ + public void addItem(final ComponentItem item){ + LOG.assertTrue(item != null); + LOG.assertTrue(!myItems.contains(item)); + + myItems.add(item); + } + + /** Replaces specified item with the new one. */ + public void replaceItem(final ComponentItem itemToBeReplaced, final ComponentItem replacement){ + LOG.assertTrue(itemToBeReplaced != null); + LOG.assertTrue(myItems.contains(itemToBeReplaced)); + LOG.assertTrue(replacement != null); + + final int index = myItems.indexOf(itemToBeReplaced); + myItems.set(index, replacement); + } + + /** Removed specified {@link ComponentItem} from the group.*/ + public void removeItem(final ComponentItem item){ + LOG.assertTrue(item != null); + LOG.assertTrue(myItems.contains(item)); + + myItems.remove(item); + } + + public boolean containsItem(final ComponentItem item){ + LOG.assertTrue(item != null); + + for(int i = myItems.size() - 1; i >= 0; i--){ + if(item.equals(myItems.get(i))){ + return true; + } + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/Palette.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/Palette.java new file mode 100644 index 00000000000..38f5368eec6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/palette/Palette.java @@ -0,0 +1,828 @@ +package com.intellij.uiDesigner.palette; + +import com.intellij.ide.ui.LafManager; +import com.intellij.ide.ui.LafManagerListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.lw.LwXmlReader; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEnumEditor; +import com.intellij.uiDesigner.propertyInspector.properties.*; +import com.intellij.uiDesigner.propertyInspector.renderers.IntEnumRenderer; +import org.jdom.Element; + +import javax.swing.*; +import java.awt.*; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.*; +import java.util.List; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class Palette implements ProjectComponent, JDOMExternalizable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.palette.Palette"); + + private final MyLafManagerListener myLafManagerListener; + private final HashMap myClass2Properties; + private final HashMap myClassName2Item; + /*All groups in the palette*/ + private final ArrayList myGroups; + /*Listeners, etc*/ + private final ArrayList myListeners; + + /** + * Predefined item for javax.swing.JPanel + */ + private ComponentItem myPanelItem; + + public static Palette getInstance(final Project project) { + LOG.assertTrue(project != null); + return project.getComponent(Palette.class); + } + + /** Invoked by reflection */ + private Palette(){ + myLafManagerListener = new MyLafManagerListener(); + myClass2Properties = new HashMap(); + myClassName2Item = new HashMap(); + myGroups = new ArrayList(); + myListeners = new ArrayList(); + } + + /**Adds specified listener.*/ + public void addListener(final Listener l){ + LOG.assertTrue(l != null); + LOG.assertTrue(!myListeners.contains(l)); + myListeners.add(l); + } + + /**Removes specified listener.*/ + public void removeListener(final Listener l){ + LOG.assertTrue(l != null); + LOG.assertTrue(myListeners.contains(l)); + myListeners.remove(l); + } + + private void fireGroupsChanged(){ + final Listener[] listeners = myListeners.toArray(new Listener[myListeners.size()]); + for(int i = 0; i < listeners.length; i++){ + listeners[i].groupsChanged(this); + } + } + + public String getComponentName(){ + return "Palette2"; + } + + public void projectOpened() { + LafManager.getInstance().addLafManagerListener(myLafManagerListener); + } + + public void projectClosed() { + LafManager.getInstance().removeLafManagerListener(myLafManagerListener); + } + + public void readExternal(final Element element) { + LOG.assertTrue(element != null); + ApplicationManager.getApplication().assertIsDispatchThread(); + + // It seems that IDEA inokes readExternal twice: first time for node in defaults XML + // the second time for node in project file. Stupidity... :( + myClass2Properties.clear(); + myClassName2Item.clear(); + myGroups.clear(); + + // Parse XML + final List groupElements = element.getChildren("group"); + processGroups(groupElements); + + // Ensure that all predefined items are loaded + LOG.assertTrue(myPanelItem != null); + } + + public void writeExternal(final Element element) { + LOG.assertTrue(element != null); + ApplicationManager.getApplication().assertIsDispatchThread(); + + writeGroups(element); + } + + public void initComponent() {} + + public void disposeComponent() {} + + /** + * @return a predefined palette item which corresponds to the JPanel. + * This method never returns null. + */ + public ComponentItem getPanelItem(){ + return myPanelItem; + } + + /** + * @return ComponentItem for the UI bean with the specified componentClassName. + * The method returns null if palette has no information about the specified + * class. + */ + public ComponentItem getItem(final String componentClassName) { + if(componentClassName == null){ + throw new IllegalArgumentException("componentClassName cannot be null"); + } + return myClassName2Item.get(componentClassName); + } + + /** + * @return read-only list of all groups in the palette. + * DO NOT MODIFY OR CACHE THIS LIST. + */ + public ArrayList getGroups(){ + return myGroups; + } + + /** + * @param groups list of new groups. Cannot be null. + */ + public void setGroups(final ArrayList groups){ + LOG.assertTrue(groups != null); + + myGroups.clear(); + myGroups.addAll(groups); + + fireGroupsChanged(); + } + + /** + * Adds specified item to the palette. + * @param item item to be added + * @exception java.lang.IllegalArgumentException if an item for the same class + * is already exists in the palette + */ + private void addItem(final GroupItem group, final ComponentItem item) { + LOG.assertTrue(group != null); + LOG.assertTrue(item != null); + + // class -> item + final String componentClassName = item.getClassName(); + if (getItem(componentClassName) != null) { + Messages.showMessageDialog( + "GUI Designer palette: item for this class already is added: " + componentClassName, + "IntelliJ IDEA", + Messages.getErrorIcon() + ); + return; + } + myClassName2Item.put(componentClassName, item); + + // group -> items + group.addItem(item); + + // Process special predefined item for JPanel + if("javax.swing.JPanel".equals(item.getClassName())){ + myPanelItem = item; + } + } + + /** + * Helper method. + */ + private static GridConstraints processDefaultConstraintsElement(final Element element){ + LOG.assertTrue(element != null); + + final GridConstraints constraints = new GridConstraints(); + + // grid related attributes + constraints.setVSizePolicy(LwXmlReader.getRequiredInt(element, "vsize-policy")); + constraints.setHSizePolicy(LwXmlReader.getRequiredInt(element, "hsize-policy")); + constraints.setAnchor(LwXmlReader.getRequiredInt(element, "anchor")); + constraints.setFill(LwXmlReader.getRequiredInt(element, "fill")); + + // minimum size + final Element minSizeElement = element.getChild("minimum-size"); + if (minSizeElement != null) { + constraints.myMinimumSize.width = LwXmlReader.getRequiredInt(minSizeElement, "width"); + constraints.myMinimumSize.height = LwXmlReader.getRequiredInt(minSizeElement, "height"); + } + + // preferred size + final Element prefSizeElement = element.getChild("preferred-size"); + if (prefSizeElement != null){ + constraints.myPreferredSize.width = LwXmlReader.getRequiredInt(prefSizeElement, "width"); + constraints.myPreferredSize.height = LwXmlReader.getRequiredInt(prefSizeElement, "height"); + } + + // maximum size + final Element maxSizeElement = element.getChild("maximum-size"); + if (maxSizeElement != null) { + constraints.myMaximumSize.width = LwXmlReader.getRequiredInt(maxSizeElement, "width"); + constraints.myMaximumSize.height = LwXmlReader.getRequiredInt(maxSizeElement, "height"); + } + + return constraints; + } + + private void processItemElement(final Element itemElement, final GroupItem group){ + LOG.assertTrue(itemElement != null); + LOG.assertTrue(group != null); + + // Class name. It's OK if class does not exist. + final String className = LwXmlReader.getRequiredString(itemElement, "class"); + + // Icon (optional) + final String iconPath = LwXmlReader.getString(itemElement, "icon"); + + // Tooltip text (optional) + final String toolTipText = LwXmlReader.getString(itemElement, "tooltip-text"); // can be null + + // Default constraint + final GridConstraints constraints; + final Element defaultConstraints = itemElement.getChild("default-constraints"); + if (defaultConstraints != null) { + constraints = processDefaultConstraintsElement(defaultConstraints); + } + else { + constraints = new GridConstraints(); + } + + final HashMap propertyName2intitialValue = new HashMap(); + { + final Element initialValues = itemElement.getChild("initial-values"); + if (initialValues != null){ + final Iterator iterator = initialValues.getChildren("property").iterator(); + while (iterator.hasNext()) { + final Element e = (Element)iterator.next(); + final String name = LwXmlReader.getRequiredString(e, "name"); + // TODO[all] currently all initial values are strings + final StringDescriptor value = StringDescriptor.create(LwXmlReader.getRequiredString(e, "value")); + propertyName2intitialValue.put(name, value); + } + } + } + + final boolean removable = LwXmlReader.getOptionalBoolean(itemElement, "removable", true); + + final ComponentItem item = new ComponentItem( + className, + iconPath, + toolTipText, + constraints, + propertyName2intitialValue, + removable + ); + addItem(group, item); + } + + /** + * Reads PaletteElements from + */ + private void processGroups(final List groupElements){ + for (Iterator i = groupElements.iterator(); i.hasNext();) { + final Element groupElement = (Element)i.next(); + final String groupName = LwXmlReader.getRequiredString(groupElement, "name"); + final GroupItem group = new GroupItem(groupName); + myGroups.add(group); + final Iterator iterator = groupElement.getChildren("item").iterator(); + while (iterator.hasNext()) { + final Element itemElement = (Element)iterator.next(); + try { + processItemElement(itemElement, group); + } + catch(Exception ex) { + LOG.error(ex); + } + } + } + } + + /** Helper method */ + private static void writeDefaultConstraintsElement(final Element itemElement, final GridConstraints c){ + LOG.assertTrue(itemElement != null); + LOG.assertTrue("item".equals(itemElement.getName())); + LOG.assertTrue(c != null); + + final Element element = new Element("default-constraints"); + itemElement.addContent(element); + + // grid related attributes + { + element.setAttribute("vsize-policy", Integer.toString(c.getVSizePolicy())); + element.setAttribute("hsize-policy", Integer.toString(c.getHSizePolicy())); + element.setAttribute("anchor", Integer.toString(c.getAnchor())); + element.setAttribute("fill", Integer.toString(c.getFill())); + } + + // minimum size + { + if (c.myMinimumSize.width != -1 || c.myMinimumSize.height != -1) { + final Element _element = new Element("minimum-size"); + element.addContent(_element); + _element.setAttribute("width", Integer.toString(c.myMinimumSize.width)); + _element.setAttribute("height", Integer.toString(c.myMinimumSize.height)); + } + } + + // preferred size + { + if (c.myPreferredSize.width != -1 || c.myPreferredSize.height != -1) { + final Element _element = new Element("preferred-size"); + element.addContent(_element); + _element.setAttribute("width", Integer.toString(c.myPreferredSize.width)); + _element.setAttribute("height", Integer.toString(c.myPreferredSize.height)); + } + } + + // maximum size + { + if (c.myMaximumSize.width != -1 || c.myMaximumSize.height != -1) { + final Element _element = new Element("maximum-size"); + element.addContent(_element); + _element.setAttribute("width", Integer.toString(c.myMaximumSize.width)); + _element.setAttribute("height", Integer.toString(c.myMaximumSize.height)); + } + } + } + + /** Helper method */ + private static void writeInitialValuesElement( + final Element itemElement, + final HashMap name2value + ){ + LOG.assertTrue(itemElement != null); + LOG.assertTrue("item".equals(itemElement.getName())); + LOG.assertTrue(name2value != null); + + if(name2value.size() == 0){ // do not append 'initial-values' subtag + return; + } + + final Element initialValuesElement = new Element("initial-values"); + itemElement.addContent(initialValuesElement); + + for(final Iterator> i = name2value.entrySet().iterator(); i.hasNext();){ + final Map.Entry entry = i.next(); + final Element propertyElement = new Element("property"); + initialValuesElement.addContent(propertyElement); + propertyElement.setAttribute("name", entry.getKey()); + propertyElement.setAttribute("value", entry.getValue().getValue()/*descriptor is always trivial*/); + } + } + + /** Helper method */ + private static void writeComponentItem(final Element groupElement, final ComponentItem item){ + LOG.assertTrue(groupElement != null); + LOG.assertTrue("group".equals(groupElement.getName())); + LOG.assertTrue(item != null); + + final Element itemElement = new Element("item"); + groupElement.addContent(itemElement); + + // Class + itemElement.setAttribute("class", item.getClassName()); + + // Tooltip text (if any) + if(item.myToolTipText != null){ + itemElement.setAttribute("tooltip-text", item.myToolTipText); + } + + // Icon (if any) + final String iconPath = item.getIconPath(); + if(iconPath != null){ + itemElement.setAttribute("icon", iconPath); + } + + // Removable + itemElement.setAttribute("removable", Boolean.toString(item.isRemovable())); + + // Default constraints + writeDefaultConstraintsElement(itemElement, item.getDefaultConstraints()); + + // Initial values (if any) + writeInitialValuesElement(itemElement, item.getInitialValues()); + } + + /** + * @param parentElement element to which all "group" elements will be appended + */ + private void writeGroups(final Element parentElement){ + LOG.assertTrue(parentElement != null); + + for(Iterator i = myGroups.iterator(); i.hasNext();){ + final GroupItem group = i.next(); + + final Element groupElement = new Element("group"); + parentElement.addContent(groupElement); + groupElement.setAttribute("name", group.getName()); + + final ArrayList itemList = group.getItems(); + for(int j = 0; j < itemList.size(); j++){ + writeComponentItem(groupElement, itemList.get(j)); + } + } + } + + /** + * Helper method + */ + private static IntroIntProperty createIntEnumProperty( + final String name, + final Method readMethod, + final Method writeMethod, + final IntEnumEditor.Pair[] pairs + ){ + return new IntroIntProperty( + name, + readMethod, + writeMethod, + new IntEnumRenderer(pairs), + new IntEnumEditor(pairs) + ); + } + + /** + * @return arrys of all properties that can be introspected from the + * specified class. Only properties with getter and setter methods are + * returned. The method never returns null. + */ + public IntrospectedProperty[] getIntrospectedProperties(final Class aClass){ + if (aClass == null) { + throw new IllegalArgumentException("aClass cannot be null"); + } + + // Try the cache first + // TODO[vova, anton] update cache after class reloading (its properties caould be hanged). + if (myClass2Properties.containsKey(aClass)) { + return myClass2Properties.get(aClass); + } + + final ArrayList result = new ArrayList(); + try { + final BeanInfo beanInfo = Introspector.getBeanInfo(aClass); + final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); + for (int i = 0; i < descriptors.length; i++) { + final PropertyDescriptor descriptor = descriptors[i]; + + final Method readMethod = descriptor.getReadMethod(); + final Method writeMethod = descriptor.getWriteMethod(); + if (writeMethod == null || readMethod == null) { + continue; + } + + final String name = descriptor.getName(); + + if ( + name.equals("preferredSize") || + name.equals("minimumSize") || + name.equals("maximumSize") + ){ + // our own properties must be used instead + continue; + } + + final IntrospectedProperty property; + + final Class propertyType = descriptor.getPropertyType(); + if (int.class.equals(propertyType)) { // int + if( + JSplitPane.class.isAssignableFrom(aClass) && + "orientation".equals(name) + ){ // JSplitPane#orientation + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JSplitPane.HORIZONTAL_SPLIT, "Horizontal"), + new IntEnumEditor.Pair(JSplitPane.VERTICAL_SPLIT, "Vertical") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if (JScrollPane.class.isAssignableFrom(aClass)) { + if("horizontalScrollBarPolicy".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS, "Always"), + new IntEnumEditor.Pair(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED, "As needed"), + new IntEnumEditor.Pair(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER, "Never") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("verticalScrollBarPolicy".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, "Always"), + new IntEnumEditor.Pair(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, "As needed"), + new IntEnumEditor.Pair(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, "Never") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else{ + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if(JTabbedPane.class.isAssignableFrom(aClass)){ // special handling for javax.swing.JTabbedPane + if("tabLayoutPolicy".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JTabbedPane.WRAP_TAB_LAYOUT, "Wrap"), + new IntEnumEditor.Pair(JTabbedPane.SCROLL_TAB_LAYOUT, "Scroll") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("tabPlacement".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JTabbedPane.TOP, "Top"), + new IntEnumEditor.Pair(JTabbedPane.LEFT, "Left"), + new IntEnumEditor.Pair(JTabbedPane.BOTTOM, "Bottom"), + new IntEnumEditor.Pair(JTabbedPane.RIGHT, "Right") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else{ + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if(JLabel.class.isAssignableFrom(aClass)){ // special handling for javax.swing.JLabel + if( + JLabel.class.isAssignableFrom(aClass) && + ("displayedMnemonic".equals(name) || "displayedMnemonicIndex".equals(name)) + ){ // skip JLabel#displayedMnemonic and JLabel#displayedMnemonicIndex + continue; + } + else if("horizontalAlignment".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JLabel.LEFT, "Left"), + new IntEnumEditor.Pair(JLabel.CENTER, "Center"), + new IntEnumEditor.Pair(JLabel.RIGHT, "Right"), + new IntEnumEditor.Pair(JLabel.LEADING, "Leading"), + new IntEnumEditor.Pair(JLabel.TRAILING, "Trailing") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("horizontalTextPosition".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JLabel.LEFT, "Left"), + new IntEnumEditor.Pair(JLabel.CENTER, "Center"), + new IntEnumEditor.Pair(JLabel.RIGHT, "Right"), + new IntEnumEditor.Pair(JLabel.LEADING, "Leading"), + new IntEnumEditor.Pair(JLabel.TRAILING, "Trailing") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("verticalAlignment".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JLabel.TOP, "Top"), + new IntEnumEditor.Pair(JLabel.CENTER, "Center"), + new IntEnumEditor.Pair(JLabel.BOTTOM, "Bottom") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("verticalTextPosition".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JLabel.TOP, "Top"), + new IntEnumEditor.Pair(JLabel.CENTER, "Center"), + new IntEnumEditor.Pair(JLabel.BOTTOM, "Bottom") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else{ + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if(AbstractButton.class.isAssignableFrom(aClass)){ // special handling AbstractButton subclasses + if( + "mnemonic".equals(name) || "displayedMnemonicIndex".equals(name) + ){ // AbstractButton#mnemonic + continue; + } + else if("horizontalAlignment".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(SwingConstants.LEFT, "Left"), + new IntEnumEditor.Pair(SwingConstants.CENTER, "Center"), + new IntEnumEditor.Pair(SwingConstants.RIGHT, "Right"), + new IntEnumEditor.Pair(SwingConstants.LEADING, "Leading"), + new IntEnumEditor.Pair(SwingConstants.TRAILING, "Trailing") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("horizontalTextPosition".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(SwingConstants.LEFT, "Left"), + new IntEnumEditor.Pair(SwingConstants.CENTER, "Center"), + new IntEnumEditor.Pair(SwingConstants.RIGHT, "Right"), + new IntEnumEditor.Pair(SwingConstants.LEADING, "Leading"), + new IntEnumEditor.Pair(SwingConstants.TRAILING, "Trailing") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("verticalAlignment".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(SwingConstants.TOP, "Top"), + new IntEnumEditor.Pair(SwingConstants.CENTER, "Center"), + new IntEnumEditor.Pair(SwingConstants.BOTTOM, "Bottom") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if("verticalTextPosition".equals(name)){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(SwingConstants.TOP, "Top"), + new IntEnumEditor.Pair(SwingConstants.CENTER, "Center"), + new IntEnumEditor.Pair(SwingConstants.BOTTOM, "Bottom") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else{ + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if( + JTextField.class.isAssignableFrom(aClass) && + "horizontalAlignment".equals(name) + ){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(SwingConstants.LEFT, "Left"), + new IntEnumEditor.Pair(SwingConstants.CENTER, "Center"), + new IntEnumEditor.Pair(SwingConstants.RIGHT, "Right"), + new IntEnumEditor.Pair(SwingConstants.LEADING, "Leading"), + new IntEnumEditor.Pair(SwingConstants.TRAILING, "Trailing") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if( + JList.class.isAssignableFrom(aClass) + ){ + if ("layoutOrientation".equals(name)) { + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JList.VERTICAL, "Vertical"), + new IntEnumEditor.Pair(JList.HORIZONTAL_WRAP, "Horizontal Wrap"), + new IntEnumEditor.Pair(JList.VERTICAL_WRAP, "Vertical Wrap") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if ("selectionMode".equals(name)) { + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(ListSelectionModel.SINGLE_SELECTION, "Single"), + new IntEnumEditor.Pair(ListSelectionModel.SINGLE_INTERVAL_SELECTION, "Single Interval"), + new IntEnumEditor.Pair(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, "Multiple Interval") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else { + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if( + JTable.class.isAssignableFrom(aClass) && + "autoResizeMode".equals(name) + ){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JTable.AUTO_RESIZE_OFF, "Off"), + new IntEnumEditor.Pair(JTable.AUTO_RESIZE_NEXT_COLUMN, "Next Column"), + new IntEnumEditor.Pair(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS, "Subsequent Columns"), + new IntEnumEditor.Pair(JTable.AUTO_RESIZE_LAST_COLUMN, "Last Column"), + new IntEnumEditor.Pair(JTable.AUTO_RESIZE_ALL_COLUMNS, "All Columns") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if( + JSlider.class.isAssignableFrom(aClass) && + "orientation".equals(name) + ){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JSlider.HORIZONTAL, "Horizontal"), + new IntEnumEditor.Pair(JSlider.VERTICAL, "Vertical") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else if( + JFormattedTextField.class.isAssignableFrom(aClass) && + "focusLostBehavior".equals(name) + ){ + final IntEnumEditor.Pair[] pairs = new IntEnumEditor.Pair[]{ + new IntEnumEditor.Pair(JFormattedTextField.COMMIT, "Commit"), + new IntEnumEditor.Pair(JFormattedTextField.COMMIT_OR_REVERT, "Commit or Revert"), + new IntEnumEditor.Pair(JFormattedTextField.PERSIST, "Persist"), + new IntEnumEditor.Pair(JFormattedTextField.REVERT, "Revert") + }; + property = createIntEnumProperty(name, readMethod, writeMethod, pairs); + } + else{ + property = new IntroIntProperty(name, readMethod, writeMethod); + } + } + else if (boolean.class.equals(propertyType)) { // boolean + property = new IntroBooleanProperty(name, readMethod, writeMethod); + } + else if(double.class.equals(propertyType)){ // double + property = new IntroDoubleProperty(name, readMethod, writeMethod); + } + else if (String.class.equals(propertyType)){ // java.lang.String + property = new IntroStringProperty(name, readMethod, writeMethod); + } + else if (Insets.class.equals(propertyType)) { // java.awt.Insets + property = new IntroInsetsProperty(name, readMethod, writeMethod); + } + else if (Dimension.class.equals(propertyType)) { // java.awt.Dimension + property = new IntroDimensionProperty(name, readMethod, writeMethod); + } + else if(Rectangle.class.equals(propertyType)){ // java.awt.Rectangle + property = new IntroRectangleProperty(name, readMethod, writeMethod); + } + else { + // other types are not supported (yet?) + continue; + } + + result.add(property); + } + } + catch (IntrospectionException e) { + throw new RuntimeException(e); + } + + final IntrospectedProperty[] properties = result.toArray(new IntrospectedProperty[result.size()]); + myClass2Properties.put(aClass, properties); + return properties; + } + + /** + * @return introspected property with the given name of the + * specified class. The method returns null if there is no + * property with the such name. + */ + public IntrospectedProperty getIntrospectedProperty(final Class aClass, final String name){ + if (aClass == null){ + throw new IllegalArgumentException("aClass cannot be null"); + } + if (name == null) { + throw new IllegalArgumentException("name cannot be null"); + } + final IntrospectedProperty[] properties = getIntrospectedProperties(aClass); + for (int i = 0; i < properties.length; i++) { + final IntrospectedProperty property = properties[i]; + if (name.equals(property.getName())) { + return property; + } + } + return null; + } + + /** + * @return "inplace" property for the component with the specified class. + * DO NOT USE THIS METHOD DIRECTLY. Use {@link com.intellij.uiDesigner.RadComponent#getInplaceProperty(int, int) } + * instead. + */ + public IntrospectedProperty getInplaceProperty(final Class aClass){ + if (aClass == null) { + throw new IllegalArgumentException("aClass cannot be null"); + } + final String inplaceProperty = com.intellij.uiDesigner.Properties.getInstance().getInplaceProperty(aClass); + final IntrospectedProperty[] properties = getIntrospectedProperties(aClass); + for (int i = properties.length - 1; i >= 0; i--) { + final IntrospectedProperty property = properties[i]; + if(property.getName().equals(inplaceProperty)){ + return property; + } + } + return null; + } + + /** + * Updates UI of editors and renderers of all introspected properties + */ + private final class MyLafManagerListener implements LafManagerListener{ + private void updateUI(final Property property){ + final PropertyRenderer renderer = property.getRenderer(); + LOG.assertTrue(renderer != null); + renderer.updateUI(); + final PropertyEditor editor = property.getEditor(); + if(editor != null){ + editor.updateUI(); + } + final Property[] children = property.getChildren(); + for (int i = children.length - 1; i >= 0; i--) { + updateUI(children[i]); + } + } + + public void lookAndFeelChanged(final LafManager source) { + for(Iterator i = myClass2Properties.values().iterator(); i.hasNext();){ + final IntrospectedProperty[] properties=i.next(); + LOG.assertTrue(properties != null); + for (int j = properties.length - 1; j >= 0; j--) { + updateUI(properties[j]); + } + } + } + } + + static interface Listener{ + void groupsChanged(Palette palette); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/IntrospectedProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/IntrospectedProperty.java new file mode 100644 index 00000000000..f6dbcd85870 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/IntrospectedProperty.java @@ -0,0 +1,63 @@ +package com.intellij.uiDesigner.propertyInspector; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.XmlWriter; + +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class IntrospectedProperty extends Property{ + private final static Object[] EMPTY_OBJECT_ARRAY=new Object[]{}; + + /** + * This method is used to set property value to "delegee" JComponent + */ + private final Method myReadMethod; + /** + * This method is used to get property value from "delegee" JComponent + */ + private final Method myWriteMethod; + + public IntrospectedProperty( + final String name, + final Method readMethod, + final Method writeMethod + ){ + super(null, name); + myReadMethod = readMethod; + myWriteMethod = writeMethod; + } + + /** + * Do not overide this method without serious reason! + */ + public Object getValue(final RadComponent component){ + try { + return myReadMethod.invoke(component.getDelegee(), EMPTY_OBJECT_ARRAY); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Do not overide this method without serious reason! + */ + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + myWriteMethod.invoke(component.getDelegee(), new Object[]{value}); + } + + /** + * Serializes (writes) propertie's value + * + * @param value property value which should be serialized. Must not be null. + * @param writer writer which should be used for serialization. It is assumed that + * before invocation of this method writer already has opened tag + * that corresponds to this property. You can just append some attributes + * here or add some subtags. + */ + public abstract void write(Object value, XmlWriter writer); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/Property.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/Property.java new file mode 100644 index 00000000000..256d9f3de1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/Property.java @@ -0,0 +1,101 @@ +package com.intellij.uiDesigner.propertyInspector; + +import com.intellij.uiDesigner.RadComponent; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class Property { + protected static final Property[] EMPTY_ARRAY=new Property[]{}; + + /** + * Parent property + */ + private final Property myParent; + /** + * Propertie's name + */ + private final String myName; + + /** + * @exception java.lang.IllegalArgumentException if name is null + */ + public Property(final Property parent, final String name){ + if(name == null){ + throw new IllegalArgumentException("name cannot be null"); + } + myParent = parent; + myName = name; + } + + /** + * @return property's name. The method always returns not null string. + */ + public final String getName(){ + return myName; + } + + /** + * This method can extract value of the property from the + * instance of the RadComponent. This value is passed to the + * PropertyRenderer and PropertyEditor. + */ + public abstract Object getValue(RadComponent component); + + /** + * Do not invoke this method outside Property class, bacuse + * setValue(Component,Object) does some additional work. + * This method exists only for convenience. + * + * @see #setValue(RadComponent,Object) + */ + protected abstract void setValueImpl(RadComponent component, Object value) throws Exception; + + + /** + * Sets the value of the property. This method is invoked + * after editing is complete. + * + * @param component component which property should be set + * @param value new propertie's value + * + * @exception java.lang.Exception if passed value cannot + * be applied to the component. Note, the exception's + * message will be shown to the user. + */ + public final void setValue(final RadComponent component, final Object value) throws Exception{ + setValueImpl(component, value); + Property topmostParent = this; + while (topmostParent.getParent() != null) { + topmostParent = topmostParent.getParent(); + } + component.markPropertyAsModified(topmostParent); + component.getDelegee().invalidate(); + } + + /** + * @return property which is the parent for this property. + * The method can return null if the property + * doesn't have parent. + */ + public final Property getParent(){ + return myParent; + } + + /** + * @return child properties. The method never returns null. + */ + public abstract Property[] getChildren(); + + /** + * @return property's renderer. This method should never return null. + */ + public abstract PropertyRenderer getRenderer(); + + /** + * @return property's editor. The method allows to return null. + * In this case property is not editable. + */ + public abstract PropertyEditor getEditor(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditor.java new file mode 100644 index 00000000000..a79ba748993 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyEditor.java @@ -0,0 +1,110 @@ +package com.intellij.uiDesigner.propertyInspector; + +import com.intellij.uiDesigner.RadComponent; + +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.util.EventListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class PropertyEditor { + private final EventListenerList myListenerList; + + protected PropertyEditor(){ + myListenerList=new EventListenerList(); + } + + /** + * @return edited value. Note that null is the legal. + * + * @exception java.lang.Exception the method throws exception + * if user enters wrong value and it cannot be applied. Note, that + * exception's message will be shown to the user. + */ + public abstract Object getValue() throws Exception; + + /** + * @param component this component can be used to prepare editor UI + * component + * + * @param value value to be edited. The editor should not + * directly edit the passed object. Instead of this it must edit some + * internal data and return the edited value by getValue + * method. + * + * @param inplace this is hint for the editor. This parameter is true + * in case if the editor is used for inplace editing. This hint is very useful. + * For example string editor doesn't have a border when it is used + * inside property inspector and has border when it is used for inspace editing. + * + * @return the component which is used to edit the property in UI. + * The method must always return not null component. + */ + public abstract JComponent getComponent( + RadComponent component, + Object value, + boolean inplace + ); + + /** + * Property editor can return preferred focused component (if any) inside the component + * which is returned by the {@link #getComponent(RadComponent, Object, boolean) } method. + * This method is used as a hint to implement better focus handling. + * null values means that editor relies on the UI editor in + * determing preferred focused component. + * + * @param component cannot be null + */ + public JComponent getPreferredFocusedComponent(final JComponent component){ + return null; + } + + /** + * Editor should update UI of all its internal components to fit current + * IDEA Look And Feel. We cannot directly update UI of the component + * that is returned by {@link #getComponent(RadComponent, Object, boolean) } method + * because hidden components that are not in the Swing tree can exist. + */ + public abstract void updateUI(); + + /** + * Adds specified listener + */ + public final void addPropertyEditorListener(final PropertyEditorListener l){ + myListenerList.add(PropertyEditorListener.class,l); + } + + /** + * Removes specified listener + */ + public final void removePropertyEditorListener(final PropertyEditorListener l){ + myListenerList.remove(PropertyEditorListener.class,l); + } + + protected final void fireEditingCancelled(){ + final EventListener[] listeners=myListenerList.getListeners(PropertyEditorListener.class); + for(int i=0;i myProperties; + private final MyModel myModel; + private final MyCompositeTableCellRenderer myCellRenderer; + private final MyCellEditor myCellEditor; + private final GuiEditor myEditor; + /** + * This listener gets notifications from current property editor + */ + private final MyPropertyEditorListener myPropertyEditorListener; + /** + * Updates UIs of synthetic properties + */ + private final MyLafManagerListener myLafManagerListener; + /** + * This is property exists in this map then it's expanded. + * It means that its children is visible. + */ + private final HashSet myExpandedProperties; + /** + * Component to be edited + */ + private RadComponent myComponent; + /** + * If true then inspector will show "expert" properties + */ + private boolean myShowExpertProperties; + + private final ClassToBindProperty myClassToBindProperty; + private final BindingProperty myBindingProperty; + private final BorderProperty myBorderProperty; + private final MarginProperty myMarginProperty; + private final HGapProperty myHGapProperty; + private final VGapProperty myVGapProperty; + private final SameSizeHorizontallyProperty mySameSizeHorizontallyProperty; + private final SameSizeVerticallyProperty mySameSizeVerticallyProperty; + private final HSizePolicyProperty myHSizePolicyProperty; + private final VSizePolicyProperty myVSizePolicyProperty; + private final FillProperty myFillProperty; + private final AnchorProperty myAnchorProperty; + private final RowSpanProperty myRowSpanProperty; + private final ColumnSpanProperty myColumnSpanProperty; + private final MinimumSizeProperty myMinimumSizeProperty; + private final PreferredSizeProperty myPreferredSizeProperty; + private final MaximumSizeProperty myMaximumSizeProperty; + + /** + * This two attributes exist here only for performance reason + * and they should be updated when updateUI method is invoked + */ + private SimpleTextAttributes myPropertyNameAttrs; + private SimpleTextAttributes myErrorPropertyNameAttrs; + private boolean myInsideSynch; + + PropertyInspectorTable(final GuiEditor editor,final ComponentTree componentTree){ + LOG.assertTrue(editor != null); + LOG.assertTrue(componentTree != null); + + myClassToBindProperty = new ClassToBindProperty(editor); + myBindingProperty = new BindingProperty(editor); + myBorderProperty = new BorderProperty(); + myMarginProperty = new MarginProperty(); + myHGapProperty = new HGapProperty(); + myVGapProperty = new VGapProperty(); + mySameSizeHorizontallyProperty = new SameSizeHorizontallyProperty(); + mySameSizeVerticallyProperty = new SameSizeVerticallyProperty(); + myHSizePolicyProperty = new HSizePolicyProperty(); + myVSizePolicyProperty = new VSizePolicyProperty(); + myFillProperty = new FillProperty(); + myAnchorProperty = new AnchorProperty(); + myRowSpanProperty = new RowSpanProperty(); + myColumnSpanProperty = new ColumnSpanProperty(); + myMinimumSizeProperty = new MinimumSizeProperty(); + myPreferredSizeProperty = new PreferredSizeProperty(); + myMaximumSizeProperty = new MaximumSizeProperty(); + + myEditor = editor; + myPropertyEditorListener = new MyPropertyEditorListener(); + myLafManagerListener = new MyLafManagerListener(); + myComponentTree=componentTree; + myProperties = new ArrayList(); + myExpandedProperties = new HashSet(); + myModel = new MyModel(); + setModel(myModel); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + myCellRenderer = new MyCompositeTableCellRenderer(); + myCellEditor = new MyCellEditor(); + + addMouseListener(new MyMouseListener()); + + final AnAction quickJavadocAction = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC); + new ShowJavadocAction().registerCustomShortcutSet( + quickJavadocAction.getShortcutSet(), this + ); + + // Popup menu + PopupHandler.installPopupHandler( + this, + (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP), + ActionPlaces.GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP, ActionManager.getInstance()); + } + + /** + * @return currently selected {@link IntrospectedProperty} or null + * if nothing selected or synthetic property is selected. + */ + public IntrospectedProperty getSelectedIntrospectedProperty(){ + final int selectedRow = getSelectedRow(); + if(selectedRow < 0 || selectedRow >= getRowCount()){ + return null; + } + + final Module module = myEditor.getModule(); + + final PsiClass aClass = PsiManager.getInstance(module.getProject()).findClass( + myComponent.getComponentClassName(), + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) + ); + + if (aClass == null){ + return null; + } + + final Property property = myProperties.get(selectedRow); + if (!(property instanceof IntrospectedProperty)) { + return null; + } + + return (IntrospectedProperty)property; + } + + /** + * @return {@link PsiClass} of the component which properties are displayed inside the inspector + */ + public PsiClass getComponentClass(){ + final Module module = myEditor.getModule(); + final PsiClass aClass = PsiManager.getInstance(module.getProject()).findClass( + myComponent.getComponentClassName(), + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) + ); + return aClass; + } + + public Object getData(final String dataId) { + if(getClass().getName().equals(dataId)){ + return this; + } + else if(DataConstants.PSI_ELEMENT.equals(dataId)){ + final IntrospectedProperty introspectedProperty = getSelectedIntrospectedProperty(); + if(introspectedProperty == null){ + return null; + } + final PsiClass aClass = getComponentClass(); + if(aClass == null){ + return null; + } + + final PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, introspectedProperty.getName(), false, true); + if(getter != null){ + return getter; + } + + final PsiMethod setter = PropertyUtil.findPropertySetter(aClass, introspectedProperty.getName(), false, true); + return setter; + } + else{ + return null; + } + } + + public void updateUI() { + myPropertyNameAttrs = SimpleTextAttributes.REGULAR_ATTRIBUTES; + myErrorPropertyNameAttrs = new SimpleTextAttributes( + SimpleTextAttributes.STYLE_PLAIN | SimpleTextAttributes.STYLE_WAVED, + null, Color.RED + ); + super.updateUI(); + } + + /** + * Sets whenther "expert" properties are shown or not + */ + void setShowExpertProperties(final boolean showExpertProperties){ + if(myShowExpertProperties == showExpertProperties){ + return; + } + myShowExpertProperties = showExpertProperties; + synchWithTree(true); + } + + public void addNotify() { + super.addNotify(); + LafManager.getInstance().addLafManagerListener(myLafManagerListener); + } + + public void removeNotify() { + LafManager.getInstance().removeLafManagerListener(myLafManagerListener); + super.removeNotify(); + } + + /** + * Standard JTable's UI has non convenient keybinding for + * editing. Therefore we have to replace some standard actions. + */ + public void setUI(final TableUI ui){ + super.setUI(ui); + + // Customize action and input maps + final ActionMap actionMap=getActionMap(); + final InputMap focusedInputMap=getInputMap(JComponent.WHEN_FOCUSED); + final InputMap ancestorInputMap=getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + actionMap.put("selectPreviousRow",new MySelectPreviousRowAction()); + + actionMap.put("selectNextRow",new MySelectNextRowAction()); + + actionMap.put("startEditing",new MyStartEditingAction()); + focusedInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2,0),"startEditing"); + ancestorInputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_F2,0)); + + actionMap.put("smartEnter",new MyEnterAction()); + focusedInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"smartEnter"); + ancestorInputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0)); + + focusedInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),"cancel"); + ancestorInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),"cancel"); + } + + public void setValueAt(final Object aValue, final int row, final int column) { + super.setValueAt(aValue, row, column); + // We need to repaint whole inspector because change of one property + // might causes change of another property. + repaint(); + } + + /** + * Gets first selected component from ComponentTree and sets it for editing. + * The method tries to keep selection in the list, so if new component has the property + * which is already selected then the new value will be + * also selected. It is very convenient. + * + * @param forceSynch if false and selected component in the ComponentTree + * is the same as current component in the PropertyInspector then method does + * nothing such sace. If true then inspector is forced to resynch. + */ + public void synchWithTree(final boolean forceSynch){ + if (myInsideSynch) { + return; + } + myInsideSynch = true; + try { + final RadComponent newSelectedComponent = myComponentTree.getSelectedComponent(); + LOG.assertTrue(newSelectedComponent != null); + + if(!forceSynch && newSelectedComponent.equals(myComponent)){ + // Nothing changed + return; + } + + if (isEditing()){ + cellEditor.stopCellEditing(); + } + + // Store selected property + final int selectedRow=getSelectedRow(); + Property selectedProperty=null; + if(selectedRow >= 0 && selectedRow < myProperties.size()){ + selectedProperty=myProperties.get(selectedRow); + } + + myComponent = newSelectedComponent; + myProperties.clear(); + collectProperties(myComponent, myProperties); + myExpandedProperties.clear(); + myModel.fireTableDataChanged(); + + // Try to restore selection + final ArrayList reversePath=new ArrayList(2); + while(selectedProperty!=null){ + reversePath.add(selectedProperty); + selectedProperty=selectedProperty.getParent(); + } + int indexToSelect=-1; + for(int i=reversePath.size()-1;i>=0;i--){ + final Property property=reversePath.get(i); + int index=findPropertyByName(property.getName()); + if(index==-1 && indexToSelect!=-1){ // try to expand parent and try again + expandProperty(indexToSelect); + index=findPropertyByName(property.getName()); + if(index!=-1){ + indexToSelect=index; + }else{ + break; + } + }else{ + indexToSelect=index; + } + } + + if(indexToSelect!=-1){ + getSelectionModel().setSelectionInterval(indexToSelect,indexToSelect); + }else if(getRowCount()>0){ + // Select first row if it's impossible to restore selection + getSelectionModel().setSelectionInterval(0,0); + } + TableUtil.scrollSelectionToVisible(this); + } + finally { + myInsideSynch = false; + } + } + + /** + * @return index of the property with specified name. + * If there is no such property then the method returns -1. + */ + private int findPropertyByName(final String name){ + for(int i=myProperties.size()-1;i>=0;i--){ + final Property property=myProperties.get(i); + if(property.getName().equals(name)){ + return i; + } + } + return -1; + } + + /** + * Populates result list with the properties available for the specified + * component + */ + private void collectProperties(final RadComponent component, final ArrayList result) { + if (component instanceof RadRootContainer){ + result.add(myClassToBindProperty); + } + else { + final boolean isVSpacer = component instanceof RadVSpacer; + final boolean isHSpacer = component instanceof RadHSpacer; + final boolean isSpacer = isVSpacer || isHSpacer; + + if (!isSpacer){ + result.add(myBindingProperty); + } + + final RadContainer parent = component.getParent(); + final boolean inGrid = parent != null && parent.isGrid(); + + if(component instanceof RadContainer){ + result.add(myBorderProperty); + } + if (component instanceof RadContainer && ((RadContainer)component).isGrid()) { + result.add(myMarginProperty); + } + + if (component instanceof RadContainer && ((RadContainer)component).getLayout() instanceof AbstractLayout){ + result.add(myHGapProperty); + result.add(myVGapProperty); + } + + if (component instanceof RadContainer && ((RadContainer)component).isGrid()) { + result.add(mySameSizeHorizontallyProperty); + result.add(mySameSizeVerticallyProperty); + } + + if (inGrid) { + if (!isVSpacer){ + result.add(myHSizePolicyProperty); + } + if (!isHSpacer){ + result.add(myVSizePolicyProperty); + } + if (!isSpacer){ + result.add(myFillProperty); + result.add(myAnchorProperty); + } + if (!isHSpacer){ + result.add(myRowSpanProperty); + } + if (!isVSpacer){ + result.add(myColumnSpanProperty); + } + result.add(myMinimumSizeProperty); + result.add(myPreferredSizeProperty); + result.add(myMaximumSizeProperty); + } + + if (!isSpacer && !(component instanceof RadErrorComponent)){ + final Class componentClass = component.getComponentClass(); + final Property[] introspectedProperties = + Palette.getInstance(myEditor.getProject()).getIntrospectedProperties(componentClass); + final Properties properties = Properties.getInstance(); + for (int i = 0; i < introspectedProperties.length; i++) { + final Property property = introspectedProperties[i]; + if(!myShowExpertProperties && properties.isExpertProperty(componentClass, property.getName())){ + continue; + } + result.add(property); + } + } + } + } + + public TableCellEditor getCellEditor(final int row, final int column){ + final PropertyEditor editor = myProperties.get(row).getEditor(); + editor.removePropertyEditorListener(myPropertyEditorListener); // we do not need to add listener on every invocation + editor.addPropertyEditorListener(myPropertyEditorListener); + myCellEditor.setEditor(editor); + return myCellEditor; + } + + public TableCellRenderer getCellRenderer(final int row,final int column){ + return myCellRenderer; + } + + /* + * This method is overriden due to bug in the JTree. The problem is that + * JTree does not properly repaint edited cell if the editor is opaque or + * has opaque child components. + */ + public boolean editCellAt(final int row, final int column, final EventObject e){ + final boolean result = super.editCellAt(row, column, e); + final Rectangle cellRect = getCellRect(row, column, true); + repaint(cellRect); + return result; + } + + /** + * Starts editing property with the specified index. + * The method does nothing is property isn't editable. + */ + private void startEditing(final int index){ + final Property property=myProperties.get(index); + final PropertyEditor editor=property.getEditor(); + if(editor==null){ + return; + } + editCellAt(index,convertColumnIndexToView(1)); + LOG.assertTrue(editorComp!=null); + // Now we have to request focus into the editor component + JComponent prefComponent = editor.getPreferredFocusedComponent((JComponent)editorComp); + if(prefComponent == null){ // use default policy to find preferred focused component + prefComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent((JComponent)editorComp); + LOG.assertTrue(prefComponent != null); + } + prefComponent.requestFocusInWindow(); + } + + private void finishEditing(){ + if(editingRow==-1){ + return; + } + editingStopped(new ChangeEvent(cellEditor)); + } + + public void editingStopped(final ChangeEvent ignored){ + LOG.assertTrue(isEditing()); + LOG.assertTrue(editingRow!=-1); + final Property property=myProperties.get(editingRow); + final PropertyEditor editor=property.getEditor(); + editor.removePropertyEditorListener(myPropertyEditorListener); + try { + final Object value = editor.getValue(); + setValueAt(value, editingRow, editingColumn); + } + catch (final Exception exc) { + final Throwable cause = exc.getCause(); + if(cause != null){ + Messages.showMessageDialog(cause.getMessage(), "Invalid Input", Messages.getErrorIcon()); + } + else{ + Messages.showMessageDialog(exc.getMessage(), "Invalid Input", Messages.getErrorIcon()); + } + } + finally { + removeEditor(); + } + } + + /** + * Expands property with the specified index. The method fires event that + * model changes and keeps currently selected row. + */ + private void expandProperty(final int index){ + final int selectedRow=getSelectedRow(); + + // Expand property + final Property property=myProperties.get(index); + LOG.assertTrue(!myExpandedProperties.contains(property)); + myExpandedProperties.add(property); + + final Property[] children=property.getChildren(); + for (int i = 0; i < children.length; i++) { + myProperties.add(index + i + 1, children[i]); + } + myModel.fireTableDataChanged(); + + // Restore selected row + if(selectedRow!=-1){ + getSelectionModel().setSelectionInterval(selectedRow,selectedRow); + } + } + + /** + * Collapse property with the specified index. The method fires event that + * model changes and keeps currently selected row. + */ + private void collapseProperty(final int index){ + final int selectedRow=getSelectedRow(); + + // Expand property + final Property property=myProperties.get(index); + LOG.assertTrue(myExpandedProperties.contains(property)); + myExpandedProperties.remove(property); + + final Property[] children=property.getChildren(); + for (int i=0; inull. + */ + private String getErrorForRow(final int row){ + LOG.assertTrue(row < myProperties.size()); + final ErrorInfo errorInfo = getErrorInfoForRow(row); + return errorInfo != null ? errorInfo.myDescription : null; + } + + public String getToolTipText(final MouseEvent e) { + final int row = rowAtPoint(e.getPoint()); + if(row == -1){ + return null; + } + return getErrorForRow(row); + } + + /** + * Adapter to TableModel + */ + private final class MyModel extends AbstractTableModel { + private final String[] myColumnNames; + + public MyModel(){ + myColumnNames=new String[]{"Property","Value"}; + } + + public int getColumnCount(){ + return 2; + } + + public String getColumnName(final int column){ + return myColumnNames[column]; + } + + public int getRowCount(){ + return myProperties.size(); + } + + public boolean isCellEditable(final int row, final int column){ + return myEditor.isEditable() && column==1 && myProperties.get(row).getEditor() != null; + } + + public Object getValueAt(final int row, final int column){ + return myProperties.get(row); + } + + public void setValueAt(final Object newValue, final int row, final int column){ + if (column != 1){ + throw new IllegalArgumentException("wrong index: " + column); + } + final Property property=myProperties.get(row); + + // Optimization: do nothing if value doesn't change + final Object oldValue=property.getValue(myComponent); + if(Comparing.equal(oldValue,newValue)){ + return; + } + + try { + property.setValue(myComponent, newValue); + } + catch (Throwable e) { + if(e instanceof InvocationTargetException){ // special handling of warapped exceptions + e = ((InvocationTargetException)e).getTargetException(); + } + Messages.showMessageDialog(e.getMessage(), "Invalid Input", Messages.getErrorIcon()); + return; + } + + myEditor.refreshAndSave(false); + } + } + + private final class MyPropertyEditorListener extends PropertyEditorAdapter{ + public void valueCommited(final PropertyEditor source){ + if(isEditing()){ + final Object value; + try { + value = cellEditor.getCellEditorValue(); + } + catch (final Exception exc) { + final Throwable cause = exc.getCause(); + if(cause != null){ + Messages.showMessageDialog(cause.getMessage(), "Invalid Input", Messages.getErrorIcon()); + } + else{ + Messages.showMessageDialog(exc.getMessage(), "Invalid Input", Messages.getErrorIcon()); + } + return; + } + setValueAt(value, editingRow, editingColumn); + } + } + + public void editingCanceled(final PropertyEditor source) { + if(isEditing()){ + cellEditor.cancelCellEditing(); + } + } + } + + private final class MyCompositeTableCellRenderer implements TableCellRenderer{ + /** + * This renderer paints first column with property names + */ + private final ColoredTableCellRenderer myPropertyNameRenderer; + private final Icon myExpandIcon; + private final Icon myCollapseIcon; + private final Icon myLevel1ShiftIcon; + private final Icon myLevel2ShiftIcon; + + public MyCompositeTableCellRenderer(){ + myPropertyNameRenderer = new ColoredTableCellRenderer() { + protected void customizeCellRenderer( + final JTable table, + final Object value, + final boolean selected, + final boolean hasFocus, + final int row, + final int column + ) { + // We will append text later in the + setPaintFocusBorder(false); + setFocusBorderAroundIcon(true); + } + }; + myExpandIcon=IconLoader.getIcon("/com/intellij/uiDesigner/icons/expandNode.png"); + myCollapseIcon=IconLoader.getIcon("/com/intellij/uiDesigner/icons/collapseNode.png"); + myLevel1ShiftIcon=EmptyIcon.create(9,9); + myLevel2ShiftIcon=EmptyIcon.create(20,9); + } + + public Component getTableCellRendererComponent( + final JTable table, + final Object value, + final boolean selected, + final boolean hasFocus, + final int row, + int column + ){ + LOG.assertTrue(value!=null); + + myPropertyNameRenderer.getTableCellRendererComponent(table,value,selected,hasFocus,row,column); + + column=table.convertColumnIndexToModel(column); + final Property property=(Property)value; + + final Color background; + if (property instanceof IntrospectedProperty){ + background = table.getBackground(); + } + else { + // syntetic property + background = property.getParent() == null ? SYNTETIC_PROPERTY_BACKGROUND : SYNTETIC_SUBPROPERTY_BACKGROUND; + } + + if (!selected){ + myPropertyNameRenderer.setBackground(background); + } + + if(column==0){ // painter for first column + // 1. Text + final boolean hasErrors = getErrorForRow(row) != null; + if(hasErrors){ + myPropertyNameRenderer.append(property.getName(), myErrorPropertyNameAttrs); + } + else{ + myPropertyNameRenderer.append(property.getName(), myPropertyNameAttrs); + } + + // 2. Icon + if(property.getChildren().length>0){ + // This is composite property and we have to show +/- sign + if(myExpandedProperties.contains(property)){ + myPropertyNameRenderer.setIcon(myCollapseIcon); + }else{ + myPropertyNameRenderer.setIcon(myExpandIcon); + } + }else{ + // If property doesn't have children then we have shift its text + // to the right + if(property.getParent()!=null){ + // Second level has larger shift + myPropertyNameRenderer.setIcon(myLevel2ShiftIcon); + }else{ + myPropertyNameRenderer.setIcon(myLevel1ShiftIcon); + } + } + } + else if(column==1){ // painter for second column + final PropertyRenderer renderer=property.getRenderer(); + final JComponent component = renderer.getComponent(property.getValue(myComponent),selected,hasFocus); + if (!selected) { + component.setBackground(background); + } + return component; + } + else{ + throw new IllegalArgumentException("wrong column: "+column); + } + + if (!selected) { + myPropertyNameRenderer.setForeground(PropertyInspectorTable.this.getForeground()); + if(property instanceof IntrospectedProperty){ + final Class componentClass = myComponent.getComponentClass(); + if (Properties.getInstance().isExpertProperty(componentClass, property.getName())) { + myPropertyNameRenderer.setForeground(Color.LIGHT_GRAY); + } + } + } + + return myPropertyNameRenderer; + } + } + + /** + * This is adapter from PropertyEditor to TableCellEditor interface + */ + private final class MyCellEditor extends AbstractCellEditor implements TableCellEditor{ + private PropertyEditor myEditor; + + public void setEditor(final PropertyEditor editor){ + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + myEditor = editor; + } + + public Object getCellEditorValue(){ + try { + return myEditor.getValue(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row, final int column){ + LOG.assertTrue(value!=null); + final Property property=(Property)value; + return myEditor.getComponent(myComponent, property.getValue(myComponent), false); + } + } + + /** + * Expands/collapses rows + */ + private final class MyMouseListener extends MouseAdapter { + public void mousePressed(final MouseEvent e){ + final int row = rowAtPoint(e.getPoint()); + if (row == -1){ + return; + } + final Rectangle rect = getCellRect(row, convertColumnIndexToView(0), false); + if (e.getX() < rect.x || e.getX() > rect.x + 9 || e.getY() < rect.y || e.getY() > rect.y + rect.height) { + return; + } + + final Property property = myProperties.get(row); + final Property[] children = property.getChildren(); + if (children.length == 0) { + return; + } + + if (myExpandedProperties.contains(property)) { + collapseProperty(row); + } + else { + expandProperty(row); + } + } + } + + /** + * Reimplementation of LookAndFeel's SelectPreviousRowAction action. + * Standard implementation isn't smart enough. + * + * @see javax.swing.plaf.basic.BasicTableUI + */ + private final class MySelectPreviousRowAction extends AbstractAction{ + public void actionPerformed(final ActionEvent e){ + final int rowCount=getRowCount(); + LOG.assertTrue(rowCount>0); + int selectedRow=getSelectedRow(); + if(selectedRow!=-1){ + selectedRow=selectedRow-1; + } + selectedRow=(selectedRow+rowCount)%rowCount; + if(isEditing()){ + finishEditing(); + getSelectionModel().setSelectionInterval(selectedRow,selectedRow); + startEditing(selectedRow); + } else { + getSelectionModel().setSelectionInterval(selectedRow,selectedRow); + } + } + } + + /** + * Reimplementation of LookAndFeel's SelectNextRowAction action. + * Standard implementation isn't smart enough. + * + * @see javax.swing.plaf.basic.BasicTableUI + */ + private final class MySelectNextRowAction extends AbstractAction{ + public void actionPerformed(final ActionEvent e){ + final int rowCount=getRowCount(); + LOG.assertTrue(rowCount>0); + final int selectedRow=(getSelectedRow()+1)%rowCount; + if(isEditing()){ + finishEditing(); + getSelectionModel().setSelectionInterval(selectedRow,selectedRow); + startEditing(selectedRow); + }else{ + getSelectionModel().setSelectionInterval(selectedRow,selectedRow); + } + } + } + + /** + * Reimplementation of LookAndFeel's StartEditingAction action. + * Standard implementation isn't smart enough. + * + * @see javax.swing.plaf.basic.BasicTableUI + */ + private final class MyStartEditingAction extends AbstractAction{ + public void actionPerformed(final ActionEvent e){ + final int selectedRow=getSelectedRow(); + if(selectedRow==-1 || isEditing()){ + return; + } + + startEditing(selectedRow); + } + } + + /** + * Expands property which has children or start editing atomic + * property. + */ + private final class MyEnterAction extends AbstractAction{ + public void actionPerformed(final ActionEvent e){ + final int selectedRow=getSelectedRow(); + if(isEditing() || selectedRow==-1){ + return; + } + + final Property property=myProperties.get(selectedRow); + if(property.getChildren().length>0){ + if(myExpandedProperties.contains(property)){ + collapseProperty(selectedRow); + }else{ + expandProperty(selectedRow); + } + }else{ + startEditing(selectedRow); + } + } + } + + /** + * Updates UI of editors and renderers of all introspected properties + */ + private final class MyLafManagerListener implements LafManagerListener{ + /** + * Recursively updates renderer and editor UIs of all synthetic + * properties. + */ + private void updateUI(final Property property){ + final PropertyRenderer renderer = property.getRenderer(); + LOG.assertTrue(renderer != null); + renderer.updateUI(); + final PropertyEditor editor = property.getEditor(); + if(editor != null){ + editor.updateUI(); + } + final Property[] children = property.getChildren(); + for (int i = children.length - 1; i >= 0; i--) { + final Property child = children[i]; + if(!(child instanceof IntrospectedProperty)){ + updateUI(child); + } + } + } + + public void lookAndFeelChanged(final LafManager source) { + updateUI(myBorderProperty); + updateUI(myMarginProperty); + updateUI(myHGapProperty); + updateUI(myVGapProperty); + updateUI(myHSizePolicyProperty); + updateUI(myVSizePolicyProperty); + updateUI(myFillProperty); + updateUI(myAnchorProperty); + updateUI(myRowSpanProperty); + updateUI(myColumnSpanProperty); + updateUI(myMinimumSizeProperty); + updateUI(myPreferredSizeProperty); + updateUI(myMaximumSizeProperty); + } + } + + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyRenderer.java new file mode 100644 index 00000000000..a9b49cdbebf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/PropertyRenderer.java @@ -0,0 +1,25 @@ +package com.intellij.uiDesigner.propertyInspector; + +import javax.swing.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public interface PropertyRenderer { + /** + * @return JComponent to represent the value + * somewhere in UI (for example in the JList of in the JTree). To be + * consistent with other UI additional parameter abount selection and + * focus are also passed. + */ + public JComponent getComponent(Object value, boolean selected, boolean hasFocus); + + /** + * Renderer should update UI of all its internal components to fit current + * IDEA Look And Feel. We cannot directly update UI of the component + * that is returned by {@link #getComponent(Object,boolean,boolean) } method + * because hidden component that are not in the Swing tree can exist. + */ + public abstract void updateUI(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/QuickFixManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/QuickFixManagerImpl.java new file mode 100644 index 00000000000..559ca55ac25 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/QuickFixManagerImpl.java @@ -0,0 +1,55 @@ +package com.intellij.uiDesigner.propertyInspector; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.ErrorInfo; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.quickFixes.QuickFixManager; + +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class QuickFixManagerImpl extends QuickFixManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.propertyInspector.QuickFixManagerImpl"); + + public QuickFixManagerImpl(final GuiEditor editor, final PropertyInspectorTable propertyInspectorTable) { + super(editor, propertyInspectorTable); + propertyInspectorTable.getSelectionModel().addListSelectionListener(new MyListSelectionListener()); + } + + public Rectangle getErrorBounds() { + final int selectedRow = myComponent.getSelectedRow(); + if(selectedRow < 0 || selectedRow >= myComponent.getRowCount()){ + return null; + } + + final Rectangle rowRect = myComponent.getCellRect(selectedRow, 0, true); + LOG.assertTrue(rowRect != null); + final Rectangle visibleRect = myComponent.getVisibleRect(); + if(visibleRect.intersects(rowRect)){ + return visibleRect.intersection(rowRect); + } + else{ + return null; + } + } + + public ErrorInfo getErrorInfo() { + final int selectedRow = myComponent.getSelectedRow(); + if(selectedRow < 0 || selectedRow >= myComponent.getRowCount()){ + return null; + } + return myComponent.getErrorInfoForRow(selectedRow); + } + + private final class MyListSelectionListener implements ListSelectionListener{ + public void valueChanged(final ListSelectionEvent e) { + hideIntentionHint(); + updateIntentionHintVisibility(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BindingEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BindingEditor.java new file mode 100644 index 00000000000..e47577e5af9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BindingEditor.java @@ -0,0 +1,145 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.uiDesigner.*; +import com.intellij.uiDesigner.core.Spacer; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BindingEditor extends ComboBoxPropertyEditor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.propertyInspector.editors.BindingEditor"); + + private final GuiEditor myEditor; + + public BindingEditor(final GuiEditor editor){ + LOG.assertTrue(editor != null); + + myEditor = editor; + myCbx.setEditable(true); + final JComponent editorComponent = (JComponent)myCbx.getEditor().getEditorComponent(); + editorComponent.setBorder(null); + + myCbx.addActionListener( + new ActionListener(){ + public void actionPerformed(final ActionEvent e){ + fireValueCommited(); + } + } + ); + + new AnAction(){ + public void actionPerformed(final AnActionEvent e) { + if (!myCbx.isPopupVisible()) { + fireEditingCancelled(); + SwingUtilities.invokeLater( + new Runnable(){ + public void run(){ + myEditor.getPropertyInspector().requestFocus(); + } + } + ); + } + } + }.registerCustomShortcutSet(CommonShortcuts.ESCAPE, myCbx); + } + + private String[] getFieldNames(final RadComponent component, final String currentName) { + final ArrayList result = new ArrayList(); + if (currentName != null){ + result.add(currentName); + } + + final String className = myEditor.getRootContainer().getClassToBind(); + if (className == null) { + return result.toArray(new String[result.size()]); + } + + final PsiClass aClass = FormEditingUtil.findClassToBind(myEditor.getModule(), className); + if (aClass == null) { + return result.toArray(new String[result.size()]); + } + + final PsiField[] fields = aClass.getFields(); + + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + + if (field.hasModifierProperty(PsiModifier.STATIC)) { + continue; + } + + final String fieldName = field.getName(); + + if (fieldName.equals(currentName)) { + continue; + } + + if (!GuiEditorUtil.isBindingUnique(component, fieldName, myEditor.getRootContainer())) { + continue; + } + + final String componentClassName; + if (component instanceof RadErrorComponent) { + componentClassName = component.getComponentClassName(); + } + else if (component instanceof RadHSpacer || component instanceof RadVSpacer) { + componentClassName = Spacer.class.getName(); + } + else { + componentClassName = component.getComponentClass().getName(); + } + + final PsiType componentType; + try { + componentType = PsiManager.getInstance(myEditor.getProject()).getElementFactory().createTypeFromText(componentClassName, null); + } + catch (IncorrectOperationException e) { + continue; + } + if (componentType == null) { + continue; + } + + final PsiType fieldType = field.getType(); + if (fieldType == null) { + continue; + } + + if (!fieldType.isAssignableFrom(componentType)) { + continue; + } + + result.add(fieldName); + } + + final String[] names = result.toArray(new String[result.size()]); + Arrays.sort(names); + return names; + } + + public Object getValue() throws Exception { + final String value = (String)super.getValue(); + return value != null ? value.replace('$', '.') : null; // PSI works only with dots + } + + public JComponent getComponent(final RadComponent component, final Object value, final boolean inplace){ + final String currentName = (String)value; + final String[] fieldNames = getFieldNames(component, currentName); + myCbx.setModel(new DefaultComboBoxModel(fieldNames)); + myCbx.setSelectedItem(value); + return myCbx; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BooleanEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BooleanEditor.java new file mode 100644 index 00000000000..d6fa0ec25f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BooleanEditor.java @@ -0,0 +1,49 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BooleanEditor extends PropertyEditor{ + private final JCheckBox myCheckBox; + private boolean myInsideChange; + + public BooleanEditor(){ + myCheckBox=new JCheckBox(); + myCheckBox.addActionListener(new MyActionListener()); + } + + public void updateUI() { + SwingUtilities.updateComponentTreeUI(myCheckBox); + } + + public Object getValue() throws Exception{ + return Boolean.valueOf(myCheckBox.isSelected()); + } + + public JComponent getComponent(final RadComponent ignored, final Object value, final boolean inplace){ + myInsideChange=true; + try{ + myCheckBox.setBackground(UIManager.getColor("Table.background")); + myCheckBox.setSelected(((Boolean)value).booleanValue()); + return myCheckBox; + }finally{ + myInsideChange=false; + } + } + + private final class MyActionListener implements ActionListener{ + public void actionPerformed(final ActionEvent e){ + if(!myInsideChange){ + fireValueCommited(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BorderTypeEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BorderTypeEditor.java new file mode 100644 index 00000000000..9cb3f803b2c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/BorderTypeEditor.java @@ -0,0 +1,48 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.shared.BorderType; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BorderTypeEditor extends ComboBoxPropertyEditor{ + public BorderTypeEditor(){ + myCbx.setModel( + new DefaultComboBoxModel( + new BorderType[]{ + BorderType.NONE, + BorderType.BEVEL_LOWERED, + BorderType.BEVEL_RAISED, + BorderType.ETCHED + } + ) + ); + myCbx.setRenderer(new MyListCellRenderer()); + } + + public JComponent getComponent(final RadComponent ignored, final Object value, final boolean inplace){ + if(!(value instanceof BorderType)){ + throw new IllegalArgumentException("wrong value: "+value); + } + myCbx.setSelectedItem(value); + return myCbx; + } + + private static final class MyListCellRenderer extends DefaultListCellRenderer{ + public Component getListCellRendererComponent( + final JList list, + final Object value, + final int index, + final boolean isSelected, + final boolean cellHasFocus + ){ + final BorderType type=(BorderType)value; + return super.getListCellRendererComponent(list,type.getName(),index,isSelected,cellHasFocus); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java new file mode 100644 index 00000000000..2718256d7f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/ComboBoxPropertyEditor.java @@ -0,0 +1,56 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.openapi.ui.ComboBox; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; + +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class ComboBoxPropertyEditor extends PropertyEditor{ + protected final ComboBox myCbx; + + public ComboBoxPropertyEditor() { + myCbx = new ComboBox(-1); + myCbx.setBorder(null); + myCbx.addPopupMenuListener(new MyPopupMenuListener()); + } + + public final void updateUI() { + SwingUtilities.updateComponentTreeUI(myCbx); + SwingUtilities.updateComponentTreeUI((JComponent)myCbx.getRenderer()); + } + + public Object getValue() throws Exception{ + if(myCbx.isEditable()){ + final Component editorComponent = myCbx.getEditor().getEditorComponent(); + return ((JTextField)editorComponent).getText(); + } + else{ + return myCbx.getSelectedItem(); + } + } + + private final class MyPopupMenuListener implements PopupMenuListener{ + private boolean myCancelled; + + public void popupMenuWillBecomeVisible(final PopupMenuEvent e){ + myCancelled=false; + } + + public void popupMenuWillBecomeInvisible(final PopupMenuEvent e){ + if(!myCancelled){ + fireValueCommited(); + } + } + + public void popupMenuCanceled(final PopupMenuEvent e){ + myCancelled=true; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEditor.java new file mode 100644 index 00000000000..951aabbfc2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEditor.java @@ -0,0 +1,63 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntEditor extends PropertyEditor{ + private final int myLowBoundary; + private final JTextField myTf; + + /** + * @param lowBondary minimal integer value that editor accepts. + */ + public IntEditor(final int lowBondary){ + myLowBoundary = lowBondary; + myTf = new JTextField(); + myTf.addActionListener(new MyActionListener()); + } + + public void updateUI() { + SwingUtilities.updateComponentTreeUI(myTf); + } + + public JComponent getComponent(final RadComponent ignored, final Object value, final boolean inplace){ + final Integer integer = (Integer)value; + myTf.setText(integer.toString()); + + if(inplace){ + myTf.setBorder(UIManager.getBorder("TextField.border")); + } + else{ + myTf.setBorder(null); + } + + return myTf; + } + + public Object getValue() throws Exception{ + try { + final Integer value = Integer.valueOf(myTf.getText()); + if(value.intValue() < myLowBoundary){ + throw new RuntimeException("Value should not be less than " + myLowBoundary); + } + return value; + } + catch (final NumberFormatException exc) { + throw new RuntimeException("Entered value is not an integer number"); + } + } + + private final class MyActionListener implements ActionListener{ + public void actionPerformed(final ActionEvent e){ + fireValueCommited(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEnumEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEnumEditor.java new file mode 100644 index 00000000000..21f687235d1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/IntEnumEditor.java @@ -0,0 +1,90 @@ +package com.intellij.uiDesigner.propertyInspector.editors; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; + +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntEnumEditor extends PropertyEditor { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.propertyInspector.editors.IntEnumEditor"); + + private final JComboBox myCbx; + + public IntEnumEditor(final Pair[] pairs) { + LOG.assertTrue(pairs != null); + + myCbx = new JComboBox(pairs); + myCbx.setBorder(BorderFactory.createEmptyBorder()); + myCbx.addPopupMenuListener(new MyPopupMenuListener()); + } + + public final void updateUI() { + SwingUtilities.updateComponentTreeUI(myCbx); + SwingUtilities.updateComponentTreeUI((JComponent)myCbx.getRenderer()); + } + + public final Object getValue() throws Exception { + final Object selectedItem = myCbx.getSelectedItem(); + final Pair pair = (Pair)selectedItem; + return new Integer(pair.myValue); + } + + public JComponent getComponent(final RadComponent ignored, final Object value, final boolean inplace) { + LOG.assertTrue(value != null); + + final Integer _int = (Integer)value; + // Find pair + final ComboBoxModel model = myCbx.getModel(); + for (int i = model.getSize() - 1; i >= 0; i--) { + final Pair pair = (Pair)model.getElementAt(i); + if (pair.myValue == _int.intValue()) { + myCbx.setSelectedIndex(i); + return myCbx; + } + } + throw new IllegalArgumentException("unknown value: " + value); + } + + private final class MyPopupMenuListener implements PopupMenuListener { + private boolean myCancelled; + + public void popupMenuWillBecomeVisible(final PopupMenuEvent e) { + myCancelled = false; + } + + public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) { + if (!myCancelled) { + fireValueCommited(); + } + } + + public void popupMenuCanceled(final PopupMenuEvent e) { + myCancelled = true; + } + } + + public static final class Pair { + public final int myValue; + /** + * Textual description of the myValue. This field is never null + */ + public final String myText; + + public Pair(final int value, final String text) { + LOG.assertTrue(text != null); + myValue = value; + myText = text; + } + + public String toString() { + return myText; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java new file mode 100644 index 00000000000..0077153af93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/KeyChooserDialog.java @@ -0,0 +1,182 @@ +package com.intellij.uiDesigner.propertyInspector.editors.string; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Pair; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.util.ui.Table; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.util.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class KeyChooserDialog extends DialogWrapper{ + private final String myBundleName; + /** List of bundle's pairs*/ + private final ArrayList> myPairs; + private final JComponent myCenterPanel; + /** Table with key/value pairs */ + private final Table myTable; + + /** + * @param bundle resource bundle to be shown. + * + * @param bundleName name of the resource bundle to be shown. We need this + * name to create StringDescriptor in {@link #getDescriptor()} method. + * + * @param keyToPreselect describes row that should be selected in the + * table with key/value pairs. + */ + public KeyChooserDialog( + final Component parent, + final ResourceBundle bundle, + final String bundleName, + final String keyToPreselect + ) { + super(parent, true); + + // Check args + if(bundle == null){ + throw new IllegalArgumentException(); + } + if(bundleName == null){ + throw new IllegalArgumentException(); + } + + myBundleName = bundleName; + + setTitle("Chooser Value"); + + // Read key/value pairs from resource bundle + myPairs = new ArrayList>(); + + for(Enumeration keys = bundle.getKeys(); keys.hasMoreElements();){ + final String key = (String)keys.nextElement(); + final String value = bundle.getString(key); + myPairs.add(new Pair(key, value)); + } + Collections.sort(myPairs, new MyPairComparator()); + + // Create UI + final MyTableModel model = new MyTableModel(); + myTable = new Table(model); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myCenterPanel = ScrollPaneFactory.createScrollPane(myTable); + + // Calculate width for "Key" columns + final FontMetrics metrics = myTable.getFontMetrics(myTable.getFont()); + int width = 0; + for(int i = myPairs.size() - 1; i >= 0; i--){ + final Pair pair = myPairs.get(i); + width = Math.max(width, metrics.stringWidth(pair.getFirst())); + } + width += 30; + width = Math.max(width, metrics.stringWidth(model.getColumnName(0))); + final TableColumn keyColumn = myTable.getColumnModel().getColumn(0); + keyColumn.setMaxWidth(width); + keyColumn.setMinWidth(width); + + // Preselect proper row + int indexToPreselect = -1; + for(int i = myPairs.size() - 1; i >= 0; i--){ + final Pair pair = myPairs.get(i); + if(pair.getFirst().equals(keyToPreselect)){ + indexToPreselect = i; + break; + } + } + if(indexToPreselect != -1){ + myTable.getSelectionModel().setSelectionInterval(indexToPreselect, indexToPreselect); + myTable.scrollRectToVisible(myTable.getCellRect(indexToPreselect, 0, true)); + } + + init(); + } + + protected String getDimensionServiceKey() { + return getClass().getName(); + } + + public JComponent getPreferredFocusedComponent() { + return myTable; + } + + /** + * @return resolved string descriptor. If user chose nothing then the + * method returns null. + */ + StringDescriptor getDescriptor(){ + final int selectedRow = myTable.getSelectedRow(); + if(selectedRow < 0 || selectedRow >= myTable.getRowCount()){ + return null; + } + else{ + final Pair pair = myPairs.get(selectedRow); + final StringDescriptor descriptor = new StringDescriptor(myBundleName, pair.getFirst()); + descriptor.setResolvedValue(pair.getSecond()); + return descriptor; + } + } + + protected JComponent createCenterPanel() { + return myCenterPanel; + } + + private static final class MyPairComparator implements Comparator>{ + public int compare(final Pair p1, final Pair p2) { + return p1.getFirst().compareToIgnoreCase(p2.getSecond()); + } + } + + private final class MyTableModel extends AbstractTableModel{ + public int getColumnCount() { + return 2; + } + + public String getColumnName(final int column) { + if(column == 0){ + return "Key"; + } + else if(column == 1){ + return "Value"; + } + else{ + throw new IllegalArgumentException("unknown column: " + column); + } + } + + public Class getColumnClass(final int column) { + if(column == 0){ + return String.class; + } + else if(column == 1){ + return String.class; + } + else{ + throw new IllegalArgumentException("unknown column: " + column); + } + } + + public Object getValueAt(final int row, final int column) { + if(column == 0){ + return myPairs.get(row).getFirst(); + } + else if(column == 1){ + return myPairs.get(row).getSecond(); + } + else{ + throw new IllegalArgumentException("unknown column: " + column); + } + } + + public int getRowCount() { + return myPairs.size(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditor.java new file mode 100644 index 00000000000..8c4886d863c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditor.java @@ -0,0 +1,152 @@ +package com.intellij.uiDesigner.propertyInspector.editors.string; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.ui.DocumentAdapter; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.editor.UIFormEditor; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class StringEditor extends PropertyEditor{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor"); + + private final TextFieldWithBrowseButton myTfWithButton; + /* Initial value of string property that was passed into getComponent() method */ + private StringDescriptor myValue; + + public StringEditor(){ + myTfWithButton = new TextFieldWithBrowseButton(new MyActionListener()); + myTfWithButton.getTextField().setBorder(null); + + final JTextField textField = myTfWithButton.getTextField(); + textField.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + fireValueCommited(); + } + } + ); + textField.getDocument().addDocumentListener( + new DocumentAdapter() { + protected void textChanged(final DocumentEvent e) { + preferredSizeChanged(); + } + } + ); + + final MyCancelEditingAction cancelEditingAction = new MyCancelEditingAction(); + cancelEditingAction.registerCustomShortcutSet(CommonShortcuts.ESCAPE, myTfWithButton); + } + + /** + * @return current preferred size of the editor component + */ + public Dimension getPreferredSize(){ + return myTfWithButton.getPreferredSize(); + } + + public void updateUI() { + SwingUtilities.updateComponentTreeUI(myTfWithButton); + } + + /** + * Applies specified bundle to the myTfWithBrowseButton + */ + private void setValue(final StringDescriptor descriptor){ + myValue = descriptor; + final JTextField textField = myTfWithButton.getTextField(); + if(descriptor != null){ + final String value = descriptor.getValue(); + if(value != null){ // plain value + textField.setEditable(true); + textField.setText(value); + } + else{ // bundled value + textField.setEditable(false); + textField.setBackground(UIManager.getColor("TextField.background")); + textField.setText("[" + descriptor.getKey() + " / " + descriptor.getBundleName() + "]"); + } + } + else{ + textField.setEditable(true); + textField.setText(null); + } + } + + public JComponent getPreferredFocusedComponent(final JComponent component) { + LOG.assertTrue(component != null); + return ((TextFieldWithBrowseButton)component).getTextField(); + } + + public JComponent getComponent(final RadComponent component, final Object value, final boolean inplace){ + final StringDescriptor descriptor = (StringDescriptor)value; + setValue(descriptor); + + myTfWithButton.getTextField().setBorder(null); + + return myTfWithButton; + } + + public Object getValue(){ + if(myValue == null || myValue.getValue() != null){ // editor is for "trivial" StringDescriptor + final String value = myTfWithButton.getText(); + if (myValue == null && value.length() == 0) { + return null; + } + else{ + return StringDescriptor.create(value); + } + } + else{ // editor is for "bundled" StringDescriptor + return myValue; + } + } + + private final class MyCancelEditingAction extends AnAction{ + public void actionPerformed(final AnActionEvent e) { + fireEditingCancelled(); + } + } + + private final class MyActionListener implements ActionListener{ + public void actionPerformed(final ActionEvent e) { + // 1. Show editor dialog + + final DataContext dataContext = DataManager.getInstance().getDataContext(myTfWithButton.getTextField()); + final UIFormEditor editor = (UIFormEditor)dataContext.getData(DataConstants.FILE_EDITOR); + final Module module = editor.getEditor().getModule(); + + final StringEditorDialog dialog = new StringEditorDialog( + myTfWithButton.getTextField(), + (StringDescriptor)getValue(), // we have pass here "live" (modified) value + module + ); + dialog.show(); + if(!dialog.isOK()){ + return; + } + + // 2. Apply new value + final StringDescriptor descriptor = dialog.getDescriptor(); + if(descriptor == null){ + return; + } + setValue(descriptor); + fireValueCommited(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditorDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditorDialog.java new file mode 100644 index 00000000000..7e08776627f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/editors/string/StringEditorDialog.java @@ -0,0 +1,261 @@ +package com.intellij.uiDesigner.propertyInspector.editors.string; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.uiDesigner.ResourceBundleChooserDialog; +import com.intellij.uiDesigner.ResourceBundleLoader; +import com.intellij.uiDesigner.lw.StringDescriptor; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ResourceBundle; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class StringEditorDialog extends DialogWrapper{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.propertyInspector.editors.string.StringEditorDialog"); + + private final Module myModule; + /** Descriptor to be edited */ + private StringDescriptor myValue; + private final MyForm myForm; + + StringEditorDialog( + final Component parent, + final StringDescriptor descriptor, + final Module module + ) { + super(parent, true); + + if (module == null) { + throw new IllegalArgumentException("module cannot be null"); + } + + myModule = module; + + myForm = new MyForm(); + setTitle("Edit Text"); + setValue(descriptor); + + init(); /* run initialization proc */ + } + + protected String getDimensionServiceKey() { + return this.getClass().getName(); + } + + public JComponent getPreferredFocusedComponent() { + if(myForm.myRbString.isSelected()){ + return myForm.myStringCard.myTfValue; + } + else{ + return super.getPreferredFocusedComponent(); + } + } + + /** + * @return edited descriptor. If initial descriptor was null + * and user didn't change anything then this method returns null. + */ + StringDescriptor getDescriptor(){ + if(myForm.myRbString.isSelected()){ // plain value + final String value = myForm.myStringCard.myTfValue.getText(); + if(myValue == null && value.length() == 0){ + return null; + } + else{ + return StringDescriptor.create(value); + } + } + else{ // bundled value + final String bundleName = myForm.myResourceBundleCard.myTfBundleName.getText(); + final String key = myForm.myResourceBundleCard.myTfKey.getText(); + return new StringDescriptor(bundleName, key); + } + } + + /** + * Applies specified descriptor to the proper card + */ + private void setValue(final StringDescriptor descriptor){ + myValue = descriptor; + final CardLayout cardLayout = (CardLayout)myForm.myCardHolder.getLayout(); + if(descriptor == null || descriptor.getValue() != null){ // trivial descriptor + myForm.myRbString.setSelected(true); + myForm.myStringCard.setDescriptor(descriptor); + cardLayout.show(myForm.myCardHolder, "string"); + } + else{ // bundled property + myForm.myRbResourceBundle.setSelected(true); + myForm.myResourceBundleCard.setDescriptor(descriptor); + cardLayout.show(myForm.myCardHolder, "bundle"); + } + } + + protected JComponent createCenterPanel() { + return myForm.myPanel; + } + + private final class MyForm{ + private JRadioButton myRbString; + private JRadioButton myRbResourceBundle; + private JPanel myCardHolder; + private JPanel myPanel; + /** Card with editor for row string value */ + private final MyStringCard myStringCard; + /** Card with editor for value defined via resource bundle */ + private final MyResourceBundleCard myResourceBundleCard; + + public MyForm() { + myStringCard = new MyStringCard(); + myResourceBundleCard = new MyResourceBundleCard(); + + final ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbString); + buttonGroup.add(myRbResourceBundle); + + final CardLayout cardLayout = new CardLayout(); + myCardHolder.setLayout(cardLayout); + myCardHolder.add(myStringCard.myPanel, "string"); + myCardHolder.add(myResourceBundleCard.myPanel, "bundle"); + + myRbString.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + cardLayout.show(myCardHolder, "string"); + } + } + ); + + myRbResourceBundle.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + cardLayout.show(myCardHolder, "bundle"); + } + } + ); + } + } + + private final class MyStringCard{ + private JTextField myTfValue; + private JPanel myPanel; + private JLabel myLblValue; + + public MyStringCard() { + myLblValue.setLabelFor(myTfValue); + } + + public void setDescriptor(final StringDescriptor descriptor){ + myTfValue.setText(ResourceBundleLoader.resolve(myModule, descriptor)); + } + } + + private final class MyResourceBundleCard{ + private TextFieldWithBrowseButton myTfKey; + private JTextField myTfValue; + private JPanel myPanel; + private TextFieldWithBrowseButton myTfBundleName; + private JLabel myLblBundleName; + private JLabel myLblKey; + + public MyResourceBundleCard() { + // Enable keyboard pressing + myTfBundleName.registerKeyboardAction( + new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + myTfBundleName.getButton().doClick(); + } + }, + KeyStroke.getKeyStroke(myLblBundleName.getDisplayedMnemonic(), KeyEvent.ALT_DOWN_MASK), + JComponent.WHEN_IN_FOCUSED_WINDOW + ); + + myTfBundleName.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final ResourceBundleChooserDialog dialog = new ResourceBundleChooserDialog(myModule.getProject(), null); + dialog.show(); + if(!dialog.isOK()){ + return; + } + final String bundleName = dialog.getBundleName(); + myTfBundleName.setText(bundleName); + } + } + ); + + // Enable keyboard pressing + myTfKey.registerKeyboardAction( + new AbstractAction() { + public void actionPerformed(final ActionEvent e) { + myTfKey.getButton().doClick(); + } + }, + KeyStroke.getKeyStroke(myLblKey.getDisplayedMnemonic(), KeyEvent.ALT_DOWN_MASK), + JComponent.WHEN_IN_FOCUSED_WINDOW + ); + + myTfKey.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + // 1. Check that bundle exist. Otherwise we cannot show key chooser + final String bundleName = myTfBundleName.getText(); + if(bundleName.length() == 0){ + Messages.showErrorDialog( + "Please specify name of the resource bundle", + "Error" + ); + return; + } + final ResourceBundle bundle = ResourceBundleLoader.getResourceBundle(myModule, bundleName); + if(bundle == null){ + Messages.showErrorDialog( + "Bundle \"" + bundleName + "\" does not exist", + "Error" + ); + return; + } + + // 2. Show key chooser + final KeyChooserDialog dialog = new KeyChooserDialog( + myTfKey, + bundle, + bundleName, + myTfKey.getText() // key to preselect + ); + dialog.show(); + if(!dialog.isOK()){ + return; + } + + // 3. Apply new key/value + final StringDescriptor descriptor = dialog.getDescriptor(); + if(descriptor == null){ + return; + } + myTfKey.setText(descriptor.getKey()); + myTfValue.setText(descriptor.getResolvedValue()); + } + } + ); + } + + public void setDescriptor(final StringDescriptor descriptor){ + LOG.assertTrue(descriptor != null); + final String key = descriptor.getKey(); + LOG.assertTrue(key != null); + myTfBundleName.setText(descriptor.getBundleName()); + myTfKey.setText(key); + myTfValue.setText(ResourceBundleLoader.resolve(myModule, descriptor)); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractDimensionPropery.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractDimensionPropery.java new file mode 100644 index 00000000000..bda19dc7cb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractDimensionPropery.java @@ -0,0 +1,121 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.DimensionRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; + +import java.awt.*; + +/** + * This class is a base for implementing such properties + * as "minimum size", "preferred size" and "maximum size". + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class AbstractDimensionPropery extends Property{ + private final Property[] myChildren; + private final DimensionRenderer myRenderer; + + public AbstractDimensionPropery(final String name){ + super(null, name); + myChildren=new Property[]{ + new MyWidthProperty(this), + new MyHeightProperty(this) + }; + myRenderer=new DimensionRenderer(); + } + + public final Property[] getChildren(){ + return myChildren; + } + + public final PropertyRenderer getRenderer(){ + return myRenderer; + } + + /** + * This is not editable property (but it's children are editable) + */ + public final PropertyEditor getEditor(){ + return null; + } + + /** + * Child sub property which describe dimension's width + */ + public final static class MyWidthProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyWidthProperty(final Property parent){ + super(parent, "width"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(-1); + } + + public Object getValue(final RadComponent component){ + final Dimension dimension = (Dimension)getParent().getValue(component); + return new Integer(dimension.width); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Dimension dimension=(Dimension)getParent().getValue(component); + dimension.width = ((Integer)value).intValue(); + getParent().setValue(component, dimension); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Child sub property which describe dimension's height + */ + public final static class MyHeightProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyHeightProperty(final Property parent){ + super(parent, "height"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(-1); + } + + public Object getValue(final RadComponent component){ + final Dimension dimension = (Dimension)getParent().getValue(component); + return new Integer(dimension.height); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Dimension dimension = (Dimension)getParent().getValue(component); + dimension.height = ((Integer)value).intValue(); + getParent().setValue(component, dimension); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractInsetsProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractInsetsProperty.java new file mode 100644 index 00000000000..3cc772e96c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/AbstractInsetsProperty.java @@ -0,0 +1,191 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.InsetsPropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class AbstractInsetsProperty extends Property{ + private final Property[] myChildren; + private final InsetsPropertyRenderer myRenderer; + + public AbstractInsetsProperty(final String name){ + super(null, name); + myChildren=new Property[]{ + new MyTopProperty(this), + new MyLeftProperty(this), + new MyBottomProperty(this), + new MyRightProperty(this) + }; + myRenderer=new InsetsPropertyRenderer(); + } + + public final Property[] getChildren(){ + return myChildren; + } + + public final PropertyRenderer getRenderer(){ + return myRenderer; + } + + public final PropertyEditor getEditor(){ + return null; + } + + /** + * Insets.top + */ + static final class MyTopProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyTopProperty(final Property parent){ + super(parent, "top"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Insets insets=(Insets)getParent().getValue(component); + return new Integer(insets.top); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Insets insets=(Insets)getParent().getValue(component); + final int top = ((Integer)value).intValue(); + getParent().setValue(component,new Insets(top, insets.left, insets.bottom, insets.right)); + } + + public Property[] getChildren(){ + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Insets.left + */ + static final class MyLeftProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyLeftProperty(final Property parent){ + super(parent, "left"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Insets insets=(Insets)getParent().getValue(component); + return new Integer(insets.left); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Insets insets=(Insets)getParent().getValue(component); + final int left=((Integer)value).intValue(); + getParent().setValue(component,new Insets(insets.top, left, insets.bottom, insets.right)); + } + + public Property[] getChildren(){ + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Insets.bottom + */ + static final class MyBottomProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyBottomProperty(final Property parent){ + super(parent, "bottom"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Insets insets=(Insets)getParent().getValue(component); + return new Integer(insets.bottom); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Insets insets=(Insets)getParent().getValue(component); + final int bottom=((Integer)value).intValue(); + getParent().setValue(component,new Insets(insets.top, insets.left, bottom, insets.right)); + } + + public Property[] getChildren(){ + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Insets.right + */ + static final class MyRightProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyRightProperty(final Property parent){ + super(parent, "right"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Insets insets=(Insets)getParent().getValue(component); + return new Integer(insets.right); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Insets insets=(Insets)getParent().getValue(component); + final int right=((Integer)value).intValue(); + getParent().setValue(component,new Insets(insets.top, insets.left, insets.bottom, right)); + } + + public Property[] getChildren(){ + return Property.EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java new file mode 100644 index 00000000000..38acf1ee643 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java @@ -0,0 +1,123 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.refactoring.rename.RenameProcessor; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.GuiEditorUtil; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BindingEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BindingRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BindingProperty extends Property { + private final GuiEditor myGuiEditor; + + private final BindingRenderer myRenderer; + private final BindingEditor myEditor; + + public BindingProperty(final GuiEditor editor){ + super(null, "binding"); + myGuiEditor = editor; + myRenderer = new BindingRenderer(); + myEditor = new BindingEditor(editor); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public Object getValue(final RadComponent component){ + return component.getBinding(); + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception{ + final String newBinding = (String)value; + + if (newBinding.length() == 0) { + component.setBinding(null); + return; + } + + //TODO[anton,vova]: check identifier!!! + + // Check that binding remains unique + + if ( + !GuiEditorUtil.isBindingUnique(component, newBinding, myGuiEditor.getRootContainer()) + ) { + throw new Exception("binding is not unique"); + } + + // Set new value or rename old one. It means that previous binding exists + // and the new one doesn't exist we need to ask user to create new field + // or rename old one. + + final String oldBinding = (String)getValue(component); + + component.setBinding(newBinding); + + if(oldBinding == null){ + return; + } + + final String classToBind = myGuiEditor.getRootContainer().getClassToBind(); + if(classToBind == null){ + return; + } + + final Project project = myGuiEditor.getProject(); + final PsiClass aClass = PsiManager.getInstance(project).findClass(classToBind, GlobalSearchScope.allScope(project)); + if(aClass == null){ + return; + } + + final PsiField oldField = aClass.findFieldByName(oldBinding, true); + if(oldField == null){ + return; + } + + if(aClass.findFieldByName(newBinding, true) != null){ + return; + } + + // Show question to the user + + final int option = Messages.showYesNoDialog( + myGuiEditor, + "Do you want to rename field \"" + oldBinding + "\" to \"" + newBinding + "\" as well?", + "Rename", + Messages.getQuestionIcon() + ); + + if(option != 0/*Yes*/){ + return; + } + + // Commit document before refactoring starts + myGuiEditor.refreshAndSave(false); + PsiDocumentManager.getInstance(myGuiEditor.getProject()).commitAllDocuments(); + + final RenameProcessor processor = new RenameProcessor(project, oldField, newBinding, true, true, false); + processor.run((Object)null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BorderProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BorderProperty.java new file mode 100644 index 00000000000..4fd65dd05db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/BorderProperty.java @@ -0,0 +1,140 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.ResourceBundleLoader; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BorderTypeEditor; +import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BorderTypeRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.StringRenderer; +import com.intellij.uiDesigner.shared.BorderType; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BorderProperty extends Property{ + private final Property[] myChildren; + private final BorderTypeRenderer myRenderer; + + public BorderProperty(){ + super(null, "border"); + myChildren=new Property[]{ + new MyTypeProperty(), + new MyTitleProperty() + }; + myRenderer=new BorderTypeRenderer(); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + return container.getBorderType(); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + } + + public Property[] getChildren(){ + return myChildren; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return null; + } + + /** + * Border type subproperty + */ + private final class MyTypeProperty extends Property{ + private final BorderTypeRenderer myRenderer; + private final BorderTypeEditor myEditor; + + public MyTypeProperty(){ + super(BorderProperty.this, "type"); + myRenderer=new BorderTypeRenderer(); + myEditor=new BorderTypeEditor(); + } + + public Object getValue(final RadComponent component){ + final RadContainer container=(RadContainer)component; + return container.getBorderType(); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final RadContainer container=(RadContainer)component; + final BorderType type=(BorderType)value; + container.setBorderType(type); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Title subproperty + */ + private final class MyTitleProperty extends Property{ + private final StringRenderer myRenderer; + private final StringEditor myEditor; + + public MyTitleProperty(){ + super(BorderProperty.this, "title"); + myRenderer=new StringRenderer(); + myEditor=new StringEditor(); + } + + public Object getValue(final RadComponent component){ + final RadContainer container = (RadContainer)component; + final StringDescriptor descriptor = container.getBorderTitle(); + final String resolvedValue = ResourceBundleLoader.resolve(component.getModule(), descriptor); + if (descriptor != null) { + descriptor.setResolvedValue(resolvedValue); + } + return descriptor; + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final RadContainer container=(RadContainer)component; + StringDescriptor title=(StringDescriptor)value; + if(title != null && ResourceBundleLoader.resolve(component.getModule(), title).length()==0){ + title=null; + } + container.setBorderTitle(title); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java new file mode 100644 index 00000000000..308f281387a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/ClassToBindProperty.java @@ -0,0 +1,141 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadRootContainer; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.ClassToBindRenderer; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ClassToBindProperty extends Property { + private final ClassToBindRenderer myRenderer; + private final MyEditor myEditor; + private final GuiEditor myUiEditor; + + public ClassToBindProperty(final GuiEditor editor){ + super(null, "bind to class"); + myUiEditor = editor; + myRenderer = new ClassToBindRenderer(); + myEditor = new MyEditor(); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public Object getValue(final RadComponent component){ + return ((RadRootContainer)component).getClassToBind(); + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception{ + String className = (String)value; + + if (className != null && className.length() == 0) { + className = null; + } + + ((RadRootContainer)component).setClassToBind(className); + } + + private final class MyEditor extends PropertyEditor{ + private final TextFieldWithBrowseButton myTfWithButton; + private String myInitialValue; + + public MyEditor() { + myTfWithButton = new TextFieldWithBrowseButton(new MyActionListener()); + myTfWithButton.getTextField().setBorder(null); + new MyCancelEditingAction().registerCustomShortcutSet(CommonShortcuts.ESCAPE, myTfWithButton); + myTfWithButton.getTextField().addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + fireValueCommited(); + } + } + ); + } + + public Object getValue() throws Exception { + final String value = myTfWithButton.getText(); + if (value.length() == 0 && myInitialValue == null) { + return null; + } + return value.replace('$', '.'); // PSI works only with dots + } + + public JComponent getComponent(final RadComponent component, final Object value, final boolean inplace) { + final String s = (String)value; + myInitialValue = s; + myTfWithButton.setText(s); + return myTfWithButton; + } + + public void updateUI() { + SwingUtilities.updateComponentTreeUI(myTfWithButton); + } + + private final class MyActionListener implements ActionListener{ + public void actionPerformed(final ActionEvent e){ + final String className = myTfWithButton.getText(); + final PsiClass aClass = FormEditingUtil.findClassToBind(myUiEditor.getModule(), className); + + final Project project = myUiEditor.getProject(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final TreeClassChooserDialog chooser = new TreeClassChooserDialog( + "Choose Class To Bind", + project, + GlobalSearchScope.allScope(project), + new TreeClassChooserDialog.ClassFilter() { // we need show classes from the sources roots only + public boolean isAccepted(final PsiClass aClass) { + final VirtualFile vFile = aClass.getContainingFile().getVirtualFile(); + return fileIndex.isInSource(vFile); + } + }, + aClass + ); + chooser.show(); + + final PsiClass result = chooser.getSelectedClass(); + if (result != null) { + myTfWithButton.setText(result.getQualifiedName()); + } + + myTfWithButton.getTextField().requestFocus(); // todo[anton] make it via providing proper parent + } + } + + private final class MyCancelEditingAction extends AnAction{ + public void actionPerformed(final AnActionEvent e) { + fireEditingCancelled(); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HGapProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HGapProperty.java new file mode 100644 index 00000000000..231d54d16f6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HGapProperty.java @@ -0,0 +1,55 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class HGapProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public HGapProperty(){ + super(null, "Horizontal Gap"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(-1); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + return new Integer(layoutManager.getHGap()); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + layoutManager.setHGap(((Integer)value).intValue()); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HSizePolicyProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HSizePolicyProperty.java new file mode 100644 index 00000000000..64ffbbf25f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/HSizePolicyProperty.java @@ -0,0 +1,21 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.core.GridConstraints; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class HSizePolicyProperty extends SizePolicyProperty{ + public HSizePolicyProperty(){ + super("Horizontal Size Policy"); + } + + protected int getValueImpl(final GridConstraints constraints){ + return constraints.getHSizePolicy(); + } + + protected void setValueImpl(final GridConstraints constraints,final int policy){ + constraints.setHSizePolicy(policy); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroBooleanProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroBooleanProperty.java new file mode 100644 index 00000000000..e95bf9dad09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroBooleanProperty.java @@ -0,0 +1,42 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BooleanEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BooleanRenderer; + +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroBooleanProperty extends IntrospectedProperty { + private final BooleanRenderer myRenderer; + private final BooleanEditor myEditor; + + public IntroBooleanProperty(final String name, final Method readMethod, final Method writeMethod){ + super(name, readMethod, writeMethod); + myRenderer = new BooleanRenderer(); + myEditor = new BooleanEditor(); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + + public void write(final Object value, final XmlWriter writer){ + writer.addAttribute("value", value.toString()); + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDimensionProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDimensionProperty.java new file mode 100644 index 00000000000..f1e383c933e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDimensionProperty.java @@ -0,0 +1,47 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.DimensionRenderer; + +import java.awt.*; +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroDimensionProperty extends IntrospectedProperty { + private final Property[] myChildren; + private final DimensionRenderer myRenderer; + + public IntroDimensionProperty(final String name, final Method readMethod, final Method writeMethod){ + super(name, readMethod, writeMethod); + myChildren = new Property[]{ + new AbstractDimensionPropery.MyWidthProperty(this), + new AbstractDimensionPropery.MyHeightProperty(this) + }; + myRenderer = new DimensionRenderer(); + } + + public void write(final Object value, final XmlWriter writer){ + final Dimension dimension = (Dimension)value; + writer.addAttribute("width", dimension.width); + writer.addAttribute("height", dimension.height); + } + + public Property[] getChildren(){ + return myChildren; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDoubleProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDoubleProperty.java new file mode 100644 index 00000000000..f71162901fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroDoubleProperty.java @@ -0,0 +1,43 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.DoubleEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.DoubleRenderer; + +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroDoubleProperty extends IntrospectedProperty{ + private final DoubleRenderer myRenderer; + private final DoubleEditor myEditor; + + public IntroDoubleProperty(final String name, final Method readMethod, final Method writeMethod){ + super(name, readMethod, writeMethod); + myRenderer = new DoubleRenderer(); + myEditor = new DoubleEditor(); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + + public void write(final Object value, final XmlWriter writer){ + final Double aDouble = (Double)value; + writer.addAttribute("value", aDouble.toString()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroInsetsProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroInsetsProperty.java new file mode 100644 index 00000000000..e4686fc4ac3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroInsetsProperty.java @@ -0,0 +1,51 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.InsetsPropertyRenderer; + +import java.awt.*; +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroInsetsProperty extends IntrospectedProperty{ + private final Property[] myChildren; + private final InsetsPropertyRenderer myRenderer; + + public IntroInsetsProperty(final String name,final Method readMethod,final Method writeMethod){ + super(name, readMethod, writeMethod); + myChildren=new Property[]{ + new AbstractInsetsProperty.MyTopProperty(this), + new AbstractInsetsProperty.MyLeftProperty(this), + new AbstractInsetsProperty.MyBottomProperty(this), + new AbstractInsetsProperty.MyRightProperty(this) + }; + myRenderer=new InsetsPropertyRenderer(); + } + + public void write(final Object value,final XmlWriter writer){ + final Insets insets=(Insets)value; + writer.addAttribute("top",insets.top); + writer.addAttribute("left",insets.left); + writer.addAttribute("bottom",insets.bottom); + writer.addAttribute("right",insets.right); + } + + public Property[] getChildren(){ + return myChildren; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroIntProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroIntProperty.java new file mode 100644 index 00000000000..17514371002 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroIntProperty.java @@ -0,0 +1,52 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; + +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroIntProperty extends IntrospectedProperty { + private final PropertyRenderer myRenderer; + private final PropertyEditor myEditor; + + public IntroIntProperty(final String name, final Method readMethod, final Method writeMethod){ + this(name, readMethod, writeMethod, new IntRenderer(), new IntEditor(Integer.MIN_VALUE)); + } + + public IntroIntProperty( + final String name, + final Method readMethod, + final Method writeMethod, + final PropertyRenderer renderer, + final PropertyEditor editor + ){ + super(name, readMethod, writeMethod); + myRenderer = renderer; + myEditor = editor; + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + + public void write(final Object value, final XmlWriter writer){ + writer.addAttribute("value", ((Integer)value).intValue()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroRectangleProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroRectangleProperty.java new file mode 100644 index 00000000000..4d2a293356b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroRectangleProperty.java @@ -0,0 +1,202 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.RectangleRenderer; + +import java.awt.*; +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroRectangleProperty extends IntrospectedProperty{ + private final RectangleRenderer myRenderer; + private final Property[] myChildren; + + public IntroRectangleProperty(final String name, final Method readMethod, final Method writeMethod){ + super(name, readMethod, writeMethod); + myRenderer=new RectangleRenderer(); + myChildren=new Property[]{ + new MyXProperty(), + new MyYProperty(), + new MyWidthProperty(), + new MyHeightProperty() + }; + } + + public void write(final Object value,final XmlWriter writer){ + final Rectangle r=(Rectangle)value; + writer.addAttribute("x",r.x); + writer.addAttribute("y",r.y); + writer.addAttribute("width",r.width); + writer.addAttribute("height",r.height); + } + + public Property[] getChildren(){ + return myChildren; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return null; + } + + /** + * X subproperty + */ + private final class MyXProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyXProperty(){ + super(IntroRectangleProperty.this, "x"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(Integer.MIN_VALUE); + } + + public Object getValue(final RadComponent component){ + final Rectangle r=(Rectangle)getParent().getValue(component); + return new Integer(r.x); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Rectangle r=(Rectangle)getParent().getValue(component); + r.x=((Integer)value).intValue(); + getParent().setValue(component,r); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Y subproperty + */ + private final class MyYProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyYProperty(){ + super(IntroRectangleProperty.this, "y"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(Integer.MIN_VALUE); + } + + public Object getValue(final RadComponent component){ + final Rectangle r=(Rectangle)getParent().getValue(component); + return new Integer(r.y); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Rectangle r=(Rectangle)getParent().getValue(component); + r.y=((Integer)value).intValue(); + getParent().setValue(component,r); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * WIDTH subproperty + */ + private final class MyWidthProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyWidthProperty(){ + super(IntroRectangleProperty.this, "width"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Rectangle r=(Rectangle)getParent().getValue(component); + return new Integer(r.width); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Rectangle r=(Rectangle)getParent().getValue(component); + r.width=((Integer)value).intValue(); + getParent().setValue(component,r); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * HEIGHT subproperty + */ + private final class MyHeightProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public MyHeightProperty(){ + super(IntroRectangleProperty.this, "height"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(0); + } + + public Object getValue(final RadComponent component){ + final Rectangle r=(Rectangle)getParent().getValue(component); + return new Integer(r.height); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final Rectangle r=(Rectangle)getParent().getValue(component); + r.height=((Integer)value).intValue(); + getParent().setValue(component,r); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroStringProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroStringProperty.java new file mode 100644 index 00000000000..471cbca2c9d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/IntroStringProperty.java @@ -0,0 +1,192 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.ResourceBundleLoader; +import com.intellij.uiDesigner.XmlWriter; +import com.intellij.uiDesigner.core.SupportCode; +import com.intellij.uiDesigner.lw.StringDescriptor; +import com.intellij.uiDesigner.propertyInspector.IntrospectedProperty; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.string.StringEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.StringRenderer; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import java.lang.reflect.Method; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntroStringProperty extends IntrospectedProperty{ + /** + * value: HashMap + */ + private static final String CLIENT_PROP_NAME_2_DESCRIPTOR = "name2descriptor"; + + private final StringRenderer myRenderer; + private final StringEditor myEditor; + + public IntroStringProperty(final String name, final Method readMethod, final Method writeMethod) { + super(name, readMethod, writeMethod); + myRenderer = new StringRenderer(); + myEditor = new StringEditor(); + } + + public Property[] getChildren() { + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer() { + return myRenderer; + } + + public PropertyEditor getEditor() { + return myEditor; + } + + /** + * @return per RadComponent map between string property name and its StringDescriptor value. + * Method never returns null. + */ + private static HashMap getName2Descriptor(final RadComponent component){ + HashMap name2Descriptor = (HashMap)component.getClientProperty(CLIENT_PROP_NAME_2_DESCRIPTOR); + if(name2Descriptor == null){ + name2Descriptor = new HashMap(); + component.putClientProperty(CLIENT_PROP_NAME_2_DESCRIPTOR, name2Descriptor); + } + return name2Descriptor; + } + + /** + * Utility method which merge together text and mnemonic at some position + */ + private static String mergeTextAndMnemonic(final String text, final int mnemonic, final int mnemonicIndex){ + final int index; + if( + mnemonicIndex >= 0 && + mnemonicIndex < text.length() && + Character.toUpperCase(text.charAt(mnemonicIndex)) == mnemonic + ){ + // Index really corresponds to the mnemonic + index = mnemonicIndex; + } + else{ + // Mnemonic exists but index is wrong + index = -1; + } + + final StringBuffer buffer = new StringBuffer(text); + if(index != -1){ + buffer.insert(index, '&'); + // Quote all '&' except inserted one + for(int i = buffer.length() - 1; i >= 0; i--){ + if(buffer.charAt(i) == '&' && i != index){ + buffer.insert(i, '&'); + } + } + } + return buffer.toString(); + } + + /** + * It's good that method is overriden here. + * + * @return instance of {@link StringDescriptor} + */ + public Object getValue(final RadComponent component) { + // 1. resource bundle + { + final StringDescriptor descriptor = getName2Descriptor(component).get(getName()); + if(descriptor != null){ + return descriptor; + } + } + + // 2. plain value + final StringDescriptor result; + final JComponent delegee = component.getDelegee(); + if("text".equals(getName()) && (delegee instanceof JLabel)){ + final JLabel label = (JLabel)delegee; + result = StringDescriptor.create( + mergeTextAndMnemonic(label.getText(), label.getDisplayedMnemonic(), label.getDisplayedMnemonicIndex()) + ); + } + else if("text".equals(getName()) && (delegee instanceof AbstractButton)){ + final AbstractButton button = (AbstractButton)delegee; + result = StringDescriptor.create( + mergeTextAndMnemonic(button.getText(), button.getMnemonic(), button.getDisplayedMnemonicIndex()) + ); + } + else{ + result = StringDescriptor.create((String)super.getValue(component)); + } + + if (result != null) { + result.setResolvedValue(ResourceBundleLoader.resolve(component.getModule(), result)); + } + return result; + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception { + // 1. Put value into map + final StringDescriptor descriptor = (StringDescriptor)value; + if(descriptor == null || descriptor.getBundleName() == null){ + getName2Descriptor(component).remove(getName()); + } + else{ + getName2Descriptor(component).put(getName(), descriptor); + } + + // 2. Apply real string value to JComponent peer + final JComponent delegee = component.getDelegee(); + final String resolvedValue = ResourceBundleLoader.resolve(component.getModule(), descriptor); + if (descriptor != null) { + descriptor.setResolvedValue(resolvedValue); + } + + if("text".equals(getName()) && (delegee instanceof JLabel)){ + final JLabel label = (JLabel)delegee; + final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(resolvedValue); + label.setText(textWithMnemonic.myText); + if(textWithMnemonic.myMnemonicIndex != -1){ + label.setDisplayedMnemonic(textWithMnemonic.getMnemonicChar()); + label.setDisplayedMnemonicIndex(textWithMnemonic.myMnemonicIndex); + } + else{ + label.setDisplayedMnemonic(0); + } + } + else if("text".equals(getName()) && (delegee instanceof AbstractButton)){ + final AbstractButton button = (AbstractButton)delegee; + final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(resolvedValue); + button.setText(textWithMnemonic.myText); + if(textWithMnemonic.myMnemonicIndex != -1){ + button.setMnemonic(textWithMnemonic.getMnemonicChar()); + button.setDisplayedMnemonicIndex(textWithMnemonic.myMnemonicIndex); + } + else{ + button.setMnemonic(0); + } + } + else{ + super.setValueImpl(component, resolvedValue); + } + } + + public void write(final Object value, final XmlWriter writer) { + if (value == null) { + throw new IllegalArgumentException("value cannot be null"); + } + final StringDescriptor descriptor = (StringDescriptor)value; + if(descriptor.getValue() != null){ // direct value + writer.addAttribute("value", descriptor.getValue()); + } + else{ // via resource bundle + writer.addAttribute("resource-bundle", descriptor.getBundleName()); + writer.addAttribute("key", descriptor.getKey()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MarginProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MarginProperty.java new file mode 100644 index 00000000000..c31170095e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MarginProperty.java @@ -0,0 +1,47 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.core.AbstractLayout; + +import java.awt.*; + +/** + * This is "synthetic" property of the RadContainer. + * It represets margins of GridLayoutManager. Note, that + * this property exists only in RadContainer. + * + * @see com.intellij.uiDesigner.core.GridLayoutManager#getMargin + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MarginProperty extends AbstractInsetsProperty{ + public MarginProperty(){ + super("margins"); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + return layoutManager.getMargin(); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + if(value==null){ + throw new IllegalArgumentException("value cannot be null"); + } + + final Insets insets=(Insets)value; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + layoutManager.setMargin(insets); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MaximumSizeProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MaximumSizeProperty.java new file mode 100644 index 00000000000..01d079f4857 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MaximumSizeProperty.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MaximumSizeProperty extends AbstractDimensionPropery{ + public MaximumSizeProperty(){ + super("Maximum Size"); + } + + public Object getValue(final RadComponent component){ + return component.getConstraints().myMaximumSize; + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception{ + component.getConstraints().myMaximumSize.setSize((Dimension)value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MinimumSizeProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MinimumSizeProperty.java new file mode 100644 index 00000000000..b7f261c2de9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/MinimumSizeProperty.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class MinimumSizeProperty extends AbstractDimensionPropery{ + public MinimumSizeProperty(){ + super("Minimum Size"); + } + + public Object getValue(final RadComponent component){ + return component.getConstraints().myMinimumSize; + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception{ + component.getConstraints().myMinimumSize.setSize((Dimension)value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/PreferredSizeProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/PreferredSizeProperty.java new file mode 100644 index 00000000000..244b6f5c106 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/PreferredSizeProperty.java @@ -0,0 +1,23 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class PreferredSizeProperty extends AbstractDimensionPropery{ + public PreferredSizeProperty(){ + super("Preferred Size"); + } + + public Object getValue(final RadComponent component){ + return component.getConstraints().myPreferredSize; + } + + protected void setValueImpl(final RadComponent component, final Object value) throws Exception{ + component.getConstraints().myPreferredSize.setSize((Dimension)value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeHorizontallyProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeHorizontallyProperty.java new file mode 100644 index 00000000000..8dda6276b0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeHorizontallyProperty.java @@ -0,0 +1,64 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BooleanEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BooleanRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class SameSizeHorizontallyProperty extends Property{ + private final BooleanRenderer myRenderer; + private final BooleanEditor myEditor; + + public SameSizeHorizontallyProperty(){ + super(null,"Same Size Horizontally"); + myRenderer = new BooleanRenderer(); + myEditor = new BooleanEditor(); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + if (!(layoutManager instanceof GridLayoutManager)) { + throw new IllegalArgumentException("grid layout expected: "+layoutManager); + } + final GridLayoutManager gridLayoutManager = (GridLayoutManager)layoutManager; + return new Boolean(gridLayoutManager.isSameSizeHorizontally()); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + if (!(layoutManager instanceof GridLayoutManager)) { + throw new IllegalArgumentException("grid layout expected: "+layoutManager); + } + final GridLayoutManager gridLayoutManager = (GridLayoutManager)layoutManager; + gridLayoutManager.setSameSizeHorizontally(((Boolean)value).booleanValue()); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeVerticallyProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeVerticallyProperty.java new file mode 100644 index 00000000000..0910d7a0276 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SameSizeVerticallyProperty.java @@ -0,0 +1,64 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BooleanEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BooleanRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class SameSizeVerticallyProperty extends Property{ + private final BooleanRenderer myRenderer; + private final BooleanEditor myEditor; + + public SameSizeVerticallyProperty(){ + super(null,"Same Size Vertically"); + myRenderer = new BooleanRenderer(); + myEditor = new BooleanEditor(); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + if (!(layoutManager instanceof GridLayoutManager)) { + throw new IllegalArgumentException("grid layout expected: "+layoutManager); + } + final GridLayoutManager gridLayoutManager = (GridLayoutManager)layoutManager; + return new Boolean(gridLayoutManager.isSameSizeVertically()); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + if (!(layoutManager instanceof GridLayoutManager)) { + throw new IllegalArgumentException("grid layout expected: "+layoutManager); + } + final GridLayoutManager gridLayoutManager = (GridLayoutManager)layoutManager; + gridLayoutManager.setSameSizeVertically(((Boolean)value).booleanValue()); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SizePolicyProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SizePolicyProperty.java new file mode 100644 index 00000000000..9256c96a945 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/SizePolicyProperty.java @@ -0,0 +1,137 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.BooleanEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.BooleanRenderer; +import com.intellij.uiDesigner.propertyInspector.renderers.SizePolicyRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class SizePolicyProperty extends Property{ + private final Property[] myChildren; + private final SizePolicyRenderer myRenderer; + + public SizePolicyProperty(final String name){ + super(null, name); + myChildren=new Property[]{ + new MyCanShrinkProperty(), + new MyCanGrowProperty(), + new MyWantGrowProperty() + }; + myRenderer=new SizePolicyRenderer(); + } + + protected abstract int getValueImpl(GridConstraints constraints); + + protected abstract void setValueImpl(GridConstraints constraints,int policy); + + public final Object getValue(final RadComponent component){ + return new Integer(getValueImpl(component.getConstraints())); + } + + protected final void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final int policy=((Integer)value).intValue(); + setValueImpl(component.getConstraints(),policy); + } + + public final Property[] getChildren(){ + return myChildren; + } + + public final PropertyRenderer getRenderer(){ + return myRenderer; + } + + public final PropertyEditor getEditor(){ + return null; + } + + /** + * Subproperty for "can shrink" bit + */ + private abstract class MyBooleanProperty extends Property{ + private final BooleanRenderer myRenderer; + private final BooleanEditor myEditor; + + public MyBooleanProperty(final String name){ + super(SizePolicyProperty.this, name); + myRenderer=new BooleanRenderer(); + myEditor=new BooleanEditor(); + } + + public final Object getValue(final RadComponent component){ + final GridConstraints constraints=component.getConstraints(); + return Boolean.valueOf((getValueImpl(constraints)&getPropertyMask()) != 0); + } + + protected abstract int getPropertyMask(); + + protected final void setValueImpl(final RadComponent component,final Object value) throws Exception{ + final boolean canShrink=((Boolean)value).booleanValue(); + int newValue=getValueImpl(component.getConstraints()); + if(canShrink){ + newValue|=getPropertyMask(); + }else{ + newValue&=~getPropertyMask(); + } + SizePolicyProperty.this.setValueImpl(component.getConstraints(),newValue); + } + + public final Property[] getChildren(){ + return Property.EMPTY_ARRAY; + } + + public final PropertyRenderer getRenderer(){ + return myRenderer; + } + + public final PropertyEditor getEditor(){ + return myEditor; + } + } + + /** + * Subproperty for "can shrink" bit + */ + private final class MyCanShrinkProperty extends MyBooleanProperty{ + public MyCanShrinkProperty(){ + super("Can Shrink"); + } + + protected int getPropertyMask(){ + return GridConstraints.SIZEPOLICY_CAN_SHRINK; + } + } + + /** + * Subproperty for "can grow" bit + */ + private final class MyCanGrowProperty extends MyBooleanProperty{ + public MyCanGrowProperty(){ + super("Can Grow"); + } + + protected int getPropertyMask(){ + return GridConstraints.SIZEPOLICY_CAN_GROW; + } + } + + /** + * Subproperty for "want grow" bit + */ + private final class MyWantGrowProperty extends MyBooleanProperty{ + public MyWantGrowProperty(){ + super("Want Grow"); + } + + protected int getPropertyMask(){ + return GridConstraints.SIZEPOLICY_WANT_GROW; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VGapProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VGapProperty.java new file mode 100644 index 00000000000..41bea29bf30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VGapProperty.java @@ -0,0 +1,55 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.RadComponent; +import com.intellij.uiDesigner.RadContainer; +import com.intellij.uiDesigner.core.AbstractLayout; +import com.intellij.uiDesigner.propertyInspector.Property; +import com.intellij.uiDesigner.propertyInspector.PropertyEditor; +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; +import com.intellij.uiDesigner.propertyInspector.editors.IntEditor; +import com.intellij.uiDesigner.propertyInspector.renderers.IntRenderer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class VGapProperty extends Property{ + private final IntRenderer myRenderer; + private final IntEditor myEditor; + + public VGapProperty(){ + super(null," Vertical Gap"); + myRenderer = new IntRenderer(); + myEditor = new IntEditor(-1); + } + + public Object getValue(final RadComponent component){ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + return new Integer(layoutManager.getVGap()); + } + + protected void setValueImpl(final RadComponent component,final Object value) throws Exception{ + if(!(component instanceof RadContainer)){ + throw new IllegalArgumentException("component must be an instance of RadContainer: "+component); + } + final RadContainer container=(RadContainer)component; + final AbstractLayout layoutManager=(AbstractLayout)container.getLayout(); + layoutManager.setVGap(((Integer)value).intValue()); + } + + public Property[] getChildren(){ + return EMPTY_ARRAY; + } + + public PropertyRenderer getRenderer(){ + return myRenderer; + } + + public PropertyEditor getEditor(){ + return myEditor; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VSizePolicyProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VSizePolicyProperty.java new file mode 100644 index 00000000000..d4347275863 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/properties/VSizePolicyProperty.java @@ -0,0 +1,21 @@ +package com.intellij.uiDesigner.propertyInspector.properties; + +import com.intellij.uiDesigner.core.GridConstraints; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class VSizePolicyProperty extends SizePolicyProperty{ + public VSizePolicyProperty(){ + super("Vertical Size Policy"); + } + + protected int getValueImpl(final GridConstraints constraints){ + return constraints.getVSizePolicy(); + } + + protected void setValueImpl(final GridConstraints constraints,final int policy){ + constraints.setVSizePolicy(policy); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/BooleanRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/BooleanRenderer.java new file mode 100644 index 00000000000..bae3654e2a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/BooleanRenderer.java @@ -0,0 +1,26 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; + +import javax.swing.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class BooleanRenderer extends JCheckBox implements PropertyRenderer{ + public JComponent getComponent(final Object value, final boolean selected, final boolean hasFocus){ + // Background and foreground + if(selected){ + setForeground(UIManager.getColor("Table.selectionForeground")); + setBackground(UIManager.getColor("Table.selectionBackground")); + }else{ + setForeground(UIManager.getColor("Table.foreground")); + setBackground(UIManager.getColor("Table.background")); + } + + setSelected(((Boolean)value).booleanValue()); + + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/ClassToBindRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/ClassToBindRenderer.java new file mode 100644 index 00000000000..67597f1353b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/ClassToBindRenderer.java @@ -0,0 +1,30 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.psi.PsiNameHelper; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class ClassToBindRenderer extends LabelPropertyRenderer{ + public void customize(final Object value){ + final String text; + + if(value != null){ + final String fqName = (String)value; + final String className = PsiNameHelper.getShortClassName(fqName); + if(fqName.length() == className.length()){ // class in default package + text = className; + } + else{ + final String packageName = fqName.substring(0, fqName.length() - className.length() - 1); + text = className + " in " + packageName; + } + } + else{ + text = null; + } + + setText(text); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/DimensionRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/DimensionRenderer.java new file mode 100644 index 00000000000..874a99d9cdd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/DimensionRenderer.java @@ -0,0 +1,14 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class DimensionRenderer extends LabelPropertyRenderer { + protected void customize(final Object value) { + final Dimension dimension = (Dimension)value; + setText("[" + dimension.width + ", " + dimension.height + "]"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/InsetsPropertyRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/InsetsPropertyRenderer.java new file mode 100644 index 00000000000..3472b1c86f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/InsetsPropertyRenderer.java @@ -0,0 +1,26 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class InsetsPropertyRenderer extends LabelPropertyRenderer{ + private final StringBuffer myBuffer; + + public InsetsPropertyRenderer(){ + myBuffer=new StringBuffer(); + } + + protected void customize(final Object value){ + final Insets insets=(Insets)value; + myBuffer.setLength(0); + myBuffer.append('[').append(insets.top).append(", "); + myBuffer.append(insets.left).append(", "); + myBuffer.append(insets.bottom).append(", "); + myBuffer.append(insets.right).append("]"); + + setText(myBuffer.substring(0, myBuffer.length())); // [jeka] important! do not use toString() on the StringBuffer that is reused + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/IntEnumRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/IntEnumRenderer.java new file mode 100644 index 00000000000..be55760c93d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/IntEnumRenderer.java @@ -0,0 +1,33 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.uiDesigner.propertyInspector.editors.IntEnumEditor; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class IntEnumRenderer extends LabelPropertyRenderer{ + private final IntEnumEditor.Pair[] myPairs; + + public IntEnumRenderer(final IntEnumEditor.Pair[] pairs) { + if (pairs == null) { + throw new IllegalArgumentException("pairs cannot be null"); + } + myPairs = pairs; + } + + protected void customize(final Object value) { + if (value == null) { + throw new IllegalArgumentException("value cannot be null"); + } + final Integer _int = (Integer)value; + // Find pair + for(int i = myPairs.length - 1; i >= 0; i--){ + if(myPairs[i].myValue == _int.intValue()){ + setText(myPairs[i].myText); + return; + } + } + throw new IllegalArgumentException("unknown value: " + value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/LabelPropertyRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/LabelPropertyRenderer.java new file mode 100644 index 00000000000..f111c3d571a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/LabelPropertyRenderer.java @@ -0,0 +1,44 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; + +import javax.swing.*; + +/** + * This is convenient class for implementing property renderers which + * are based on JLabel. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class LabelPropertyRenderer extends JLabel implements PropertyRenderer{ + public LabelPropertyRenderer(){ + setOpaque(true); + } + + public final JComponent getComponent(final Object value, final boolean selected, final boolean hasFocus){ + // Reset text and icon + setText(null); + setIcon(null); + + // Background and foreground + if(selected){ + setForeground(UIManager.getColor("Table.selectionForeground")); + setBackground(UIManager.getColor("Table.selectionBackground")); + }else{ + setForeground(UIManager.getColor("Table.foreground")); + setBackground(UIManager.getColor("Table.background")); + } + + customize(value); + + return this; + } + + /** + * Here all subclasses should customize their text, icon and other + * attributes. Note, that background and foreground colors are already + * set. + */ + protected abstract void customize(Object value); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/RectangleRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/RectangleRenderer.java new file mode 100644 index 00000000000..78b2d816161 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/RectangleRenderer.java @@ -0,0 +1,27 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class RectangleRenderer extends LabelPropertyRenderer{ + private final StringBuffer myBuffer; + + public RectangleRenderer(){ + myBuffer=new StringBuffer(); + } + + protected void customize(final Object value){ + final Rectangle r=(Rectangle)value; + + myBuffer.setLength(0); + myBuffer.append('[').append(r.x).append(", "); + myBuffer.append(r.y).append(", "); + myBuffer.append(r.width).append(", "); + myBuffer.append(r.height).append("]"); + + setText(myBuffer.substring(0, myBuffer.length())); // [jeka] important! do not use toString() on the StringBuffer that is reused + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/SizePolicyRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/SizePolicyRenderer.java new file mode 100644 index 00000000000..12f8dd0345c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/SizePolicyRenderer.java @@ -0,0 +1,42 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.uiDesigner.core.GridConstraints; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class SizePolicyRenderer extends LabelPropertyRenderer{ + private final StringBuffer myBuffer; + + public SizePolicyRenderer(){ + myBuffer=new StringBuffer(); + } + + protected void customize(final Object value){ + final int policy=((Integer)value).intValue(); + myBuffer.setLength(0); + + if((policy & GridConstraints.SIZEPOLICY_CAN_SHRINK) != 0){ + myBuffer.append("Can Shrink"); + } + if((policy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0){ + if(myBuffer.length()>0){ + myBuffer.append(", "); + } + myBuffer.append("Can Grow"); + } + if((policy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0){ + if(myBuffer.length()>0){ + myBuffer.append(", "); + } + myBuffer.append("Want Grow"); + } + + if(policy==GridConstraints.SIZEPOLICY_FIXED){ + myBuffer.append("Fixed"); + } + + setText(myBuffer.substring(0, myBuffer.length())); // [jeka] important! do not use toString() on the StringBuffer that is reused + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/StringRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/StringRenderer.java new file mode 100644 index 00000000000..8ed88751524 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/propertyInspector/renderers/StringRenderer.java @@ -0,0 +1,22 @@ +package com.intellij.uiDesigner.propertyInspector.renderers; + +import com.intellij.uiDesigner.lw.StringDescriptor; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class StringRenderer extends LabelPropertyRenderer{ + public StringRenderer() { + } + + protected void customize(final Object value) { + if (value != null) { + final StringDescriptor descriptor = (StringDescriptor)value; + setText(descriptor.getResolvedValue()); + } + else{ + setText(null); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateClassToBindFix.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateClassToBindFix.java new file mode 100644 index 00000000000..71635767a71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateClassToBindFix.java @@ -0,0 +1,112 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.util.IncorrectOperationException; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class CreateClassToBindFix extends QuickFix{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.quickFixes.CreateClassToBindFix"); + + private final String myClassName; + + public CreateClassToBindFix(final GuiEditor editor, final String className) { + super(editor, "Create Class '" + className + "'"); + if (className == null) { + throw new IllegalArgumentException("className cannot be null"); + } + myClassName = className; + } + + public void run() { + final Project project = myEditor.getProject(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(myEditor.getFile()); + if(sourceRoot == null){ + Messages.showErrorDialog( + myEditor, + "Cannot create class because form file does not belong\nto any source root", + "Error" + ); + return; + } + + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand( + project, + new Runnable() { + public void run() { + // 1. Create all necessary packages + final int indexOfLastDot = myClassName.lastIndexOf('.'); + final String packageName = myClassName.substring(0, indexOfLastDot != -1 ? indexOfLastDot : 0); + final PsiDirectory psiDirectory; + if(packageName.length() > 0){ + final PackageWrapper packageWrapper = new PackageWrapper(PsiManager.getInstance(project), packageName); + try { + psiDirectory = RefactoringUtil.createPackageDirectoryInSourceRoot(packageWrapper, sourceRoot); + LOG.assertTrue(psiDirectory != null); + } + catch (final IncorrectOperationException e) { + ApplicationManager.getApplication().invokeLater(new Runnable(){ + public void run() { + Messages.showErrorDialog( + myEditor, + "Cannot create package '" + packageName + "'.\nReason: " + e.getMessage(), + "Error" + ); + } + }); + return; + } + } + else{ + psiDirectory = PsiManager.getInstance(project).findDirectory(sourceRoot); + LOG.assertTrue(psiDirectory != null); + } + + // 2. Create class in the package + try { + psiDirectory.createClass( + myClassName.substring( + indexOfLastDot != -1 ? indexOfLastDot + 1 : 0 + ) + ); + } + catch (final IncorrectOperationException e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + Messages.showErrorDialog( + myEditor, + "Cannot create package '" + packageName + "'.\nReason: " + e.getMessage(), + "Error" + ); + } + }); + return; + } + } + }, + getName(), + null + ); + } + } + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateFieldFix.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateFieldFix.java new file mode 100644 index 00000000000..6b58c3bec04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/CreateFieldFix.java @@ -0,0 +1,155 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.refactoring.util.RefactoringMessageUtil; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.util.IncorrectOperationException; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class CreateFieldFix extends QuickFix{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.quickFixes.CreateFieldFix"); + + private final PsiClass myClass; + private final String myFieldClassName; + private final String myFieldName; + + public CreateFieldFix( + final GuiEditor editor, + final PsiClass aClass, + final String fieldClass, + final String fieldName + ) { + super(editor, "Create Field '" + fieldName + "'"); + if (aClass == null) { + throw new IllegalArgumentException("aClass cannot be null"); + } + if (fieldClass == null) { + throw new IllegalArgumentException("fieldClass cannot be null"); + } + if (fieldName == null) { + throw new IllegalArgumentException("fieldName cannot be null"); + } + myClass = aClass; + myFieldClassName = fieldClass; + myFieldName = fieldName; + } + + /** + * This method should be invoked inside write action. + * + * @param showErrors if true the error messages will be shown to the + * use. Otherwise method works silently. + */ + public static void runImpl( + final GuiEditor editor, + final PsiClass boundClass, + final String fieldClassName, + final String fieldName, + final boolean showErrors + ){ + LOG.assertTrue(editor != null); + LOG.assertTrue(boundClass != null); + LOG.assertTrue(fieldClassName != null); + LOG.assertTrue(fieldName != null); + + final Project project = editor.getProject(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + // Do nothing if file becomes invalid + if(!boundClass.isValid()){ + return; + } + + if(!boundClass.isWritable()){ + if(showErrors){ + ApplicationManager.getApplication().invokeLater( + new Runnable() { + public void run() { + RefactoringMessageUtil.showReadOnlyElementMessage( + boundClass, + project, + "Cannot create field '" + fieldClassName + "'" + ); + } + } + ); + } + return; + } + + final PsiClass fieldClass = PsiManager.getInstance(project).findClass( + fieldClassName, + GlobalSearchScope.moduleWithLibrariesScope(editor.getModule()) + ); + if(fieldClass == null){ + if(showErrors){ + ApplicationManager.getApplication().invokeLater( + new Runnable() { + public void run() { + Messages.showErrorDialog( + editor, + "Cannot create field '" + fieldName + "' because\nclass '" + fieldClassName + "' does not exist.", + "Error" + ); + } + } + ); + } + return; + } + + // 1. Create field + final PsiElementFactory factory = PsiManager.getInstance(project).getElementFactory(); + final PsiType type = factory.createType(fieldClass); + LOG.assertTrue(type != null); + try { + // 2. Insert field into proper place of PsiFile + final PsiField field = factory.createField(fieldName, type); + boundClass.add(field); + } + catch (final IncorrectOperationException exc) { + if (showErrors) { + ApplicationManager.getApplication().invokeLater( + new Runnable() { + public void run() { + Messages.showErrorDialog( + editor, + "Cannot create field '" + fieldName + "'.\nReason: " + exc.getMessage(), + "Error" + ); + } + } + ); + } + return; + } + } + + public void run() { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand( + myEditor.getProject(), + new Runnable() { + public void run() { + runImpl(myEditor, myClass, myFieldClassName, myFieldName, true); + } + }, + getName(), + null + ); + } + } + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/FocusListenerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/FocusListenerImpl.java new file mode 100644 index 00000000000..be6bf1669dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/FocusListenerImpl.java @@ -0,0 +1,34 @@ +package com.intellij.uiDesigner.quickFixes; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +/** + * [vova] This class should be inner but due to bugs in "beta" generics compiler + * I need to use "static" modifier. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class FocusListenerImpl extends FocusAdapter{ + private final QuickFixManager myManager; + + public FocusListenerImpl(final QuickFixManager manager) { + if(manager == null){ + throw new IllegalArgumentException(); + } + myManager = manager; + } + + public void focusGained(final FocusEvent e) { + if(!e.isTemporary()){ + myManager.updateIntentionHintVisibility(); + } + } + + public void focusLost(final FocusEvent e) { + if(!(e.isTemporary())){ + myManager.hideIntentionHint(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/LightBulbComponentImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/LightBulbComponentImpl.java new file mode 100644 index 00000000000..86bb5798cbd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/LightBulbComponentImpl.java @@ -0,0 +1,60 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.keymap.KeymapUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; + +/** + * [vova] This class should be inner but due to bugs in "beta" generics compiler + * I need to use "static" modifier. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class LightBulbComponentImpl extends JComponent{ + private final QuickFixManager myManager; + private final BufferedImage myBackgroundImage; + + public LightBulbComponentImpl(final QuickFixManager manager, final BufferedImage backgroundImage) { + if(manager == null){ + throw new IllegalArgumentException(); + } + if (backgroundImage == null) { + throw new IllegalArgumentException("backgroundImage cannot be null"); + } + myManager = manager; + myBackgroundImage = backgroundImage; + + setPreferredSize(new Dimension(backgroundImage.getWidth(), backgroundImage.getHeight())); + final String acceleratorsText = KeymapUtil.getFirstKeyboardShortcutText( + ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS)); + if (acceleratorsText.length() > 0) { + setToolTipText("Click or press " + acceleratorsText); + } + + addMouseListener( + new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + myManager.showIntentionPopup(); + } + } + ); + } + + protected void paintComponent(final Graphics g) { + // 1. Paint background + g.drawImage(myBackgroundImage, 0, 0, myBackgroundImage.getWidth(), myBackgroundImage.getHeight(), this); + + // 2. Paint rollover border + // TODO[vova] implement + + // 3. Paint dropdown arrow + // TODO[vova] implement + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFix.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFix.java new file mode 100644 index 00000000000..ced610d7bb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFix.java @@ -0,0 +1,34 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.uiDesigner.GuiEditor; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class QuickFix { + public static final QuickFix[] EMPTY_ARRAY = new QuickFix[]{}; + + protected final GuiEditor myEditor; + private final String myName; + + public QuickFix(final GuiEditor editor, final String name){ + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + if (name == null) { + throw new IllegalArgumentException("name cannot be null"); + } + myEditor = editor; + myName = name; + } + + /** + * @return name of the quick fix. Never null. + */ + public final String getName() { + return myName; + } + + public abstract void run(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFixManager.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFixManager.java new file mode 100644 index 00000000000..2e37dbe0ef2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/QuickFixManager.java @@ -0,0 +1,202 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ex.ActionListPopup; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.HeavyweightHint; +import com.intellij.ui.ListPopup; +import com.intellij.uiDesigner.ErrorInfo; +import com.intellij.uiDesigner.GuiEditor; +import com.intellij.util.Alarm; +import com.intellij.util.IJSwingUtilities; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public abstract class QuickFixManager { + private final GuiEditor myEditor; + /** Component on which hint will be shown */ + protected final T myComponent; + /** + * This alarm contains request for showing of hint + */ + private final Alarm myAlarm; + /** + * This request updates visibility of the hint + */ + private final MyShowHintRequest myShowHintRequest; + /** + * My currently visible hint. May be null if there is no visible hint + */ + private HeavyweightHint myHint; + + public QuickFixManager(final GuiEditor editor, final T component) { + if (editor == null) { + throw new IllegalArgumentException("editor cannot be null"); + } + if (component == null) { + throw new IllegalArgumentException("component cannot be null"); + } + myEditor = editor; + myComponent = component; + myAlarm = new Alarm(); + myShowHintRequest = new MyShowHintRequest(this); + + (new VisibilityWatcherImpl(this, component)).install(myComponent); + myComponent.addFocusListener(new FocusListenerImpl(this)); + + // Alt+Enter + new ShowHintAction(this, component); + } + + public final GuiEditor getEditor(){ + return myEditor; + } + + final void setHint(final HeavyweightHint hint){ + if(hint == null){ + throw new IllegalArgumentException(); + } + myHint = hint; + } + + /** + * @return error info for the current {@link #myComponent} state. + */ + protected abstract ErrorInfo getErrorInfo(); + + /** + * @return rectangle (in {@link #myComponent} coordinates) that represents + * area that contains errors. This methods is invoked only if {@link #getErrorInfo()} + * returned non empty list of error infos. null means that + * error bounds are not defined. + */ + protected abstract Rectangle getErrorBounds(); + + /** + * Adds in timer queue requst for updating visibility of the popup hint + */ + public final void updateIntentionHintVisibility(){ + myAlarm.cancelAllRequests(); + myAlarm.addRequest(myShowHintRequest, 500); + } + + /** + * Shows intention hint (light bulb) if it's not visible yet. + */ + final void showIntentionHint(){ + if(!myComponent.isShowing() || !IJSwingUtilities.hasFocus(myComponent)){ + hideIntentionHint(); + return; + } + + // 1. Hide previous hint (if any) + hideIntentionHint(); + + // 2. Found error (if any) + final ErrorInfo errorInfo = getErrorInfo(); + if(errorInfo == null || errorInfo.myFixes.length == 0){ + hideIntentionHint(); + return; + } + + // 3. Determine position where this hint should be shown + final Rectangle bounds = getErrorBounds(); + if(bounds == null){ + return; + } + + // 4. Show light bulb to fix this error + final LightBulbComponentImpl lightBulbComponent; + final int width; + try { + final Robot robot = new Robot(); + final Icon icon = IconLoader.getIcon("/actions/intentionBulb.png"); + final Point locationOnScreen = myComponent.getLocationOnScreen(); + width = icon.getIconWidth() + 4; + final int height = icon.getIconHeight() + 4; + final BufferedImage image = robot.createScreenCapture( + new Rectangle( + locationOnScreen.x + bounds.x - width, + locationOnScreen.y + bounds.y, + width, + height + ) + ); + final Graphics2D g = image.createGraphics(); + try{ + icon.paintIcon(myComponent, g, (width - icon.getIconWidth())/2, (height - icon.getIconHeight())/2); + } + finally{ + g.dispose(); + } + + lightBulbComponent = new LightBulbComponentImpl(this, image); + } + catch (AWTException ignored) { + return; + } + + final HeavyweightHint hint = new HeavyweightHint(lightBulbComponent, false); + setHint(hint); + hint.show(myComponent, bounds.x - width, bounds.y, myComponent); + } + + /** + * Hides currently visible hint (light bulb) .If any. + */ + public final void hideIntentionHint(){ + myAlarm.cancelAllRequests(); + if(myHint != null && myHint.isVisible()){ + myHint.hide(); + myComponent.paintImmediately(myComponent.getVisibleRect()); + } + } + + final void showIntentionPopup(){ + if(myHint == null || !myHint.isVisible()){ + return; + } + final ErrorInfo errorInfo = getErrorInfo(); + if(errorInfo == null || errorInfo.myFixes.length == 0){ + return; + } + + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + for(int i = 0; i < errorInfo.myFixes.length; i++){ + actionGroup.add(new QuickFixActionImpl(myEditor, errorInfo.myFixes[i])); + } + + final ListPopup popup = ActionListPopup.createListPopup( + null, + actionGroup, + DataManager.getInstance().getDataContext(myComponent), + false, + true + ); + final Point locationOnScreen = myHint.getLocationOnScreen(); + popup.show(locationOnScreen.x, locationOnScreen.y + myHint.getPreferredSize().height); + } + + private final class MyShowHintRequest implements Runnable{ + private final QuickFixManager myManager; + + public MyShowHintRequest(final QuickFixManager manager) { + if(manager == null){ + throw new IllegalArgumentException(); + } + myManager = manager; + } + + public void run() { + myManager.showIntentionHint(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/ShowHintAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/ShowHintAction.java new file mode 100644 index 00000000000..a7201059129 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/ShowHintAction.java @@ -0,0 +1,43 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.uiDesigner.propertyInspector.PropertyInspector; + +import javax.swing.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class ShowHintAction extends AnAction{ + private final QuickFixManager myManager; + + public ShowHintAction(final QuickFixManager manager, final JComponent component) { + if(manager == null){ + throw new IllegalArgumentException(); + } + if(component == null){ + throw new IllegalArgumentException(); + } + myManager = manager; + registerCustomShortcutSet( + ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS).getShortcutSet(), + component + ); + } + + public void actionPerformed(final AnActionEvent e) { + // 1. Show light bulb + myManager.showIntentionHint(); + + // 2. Commit possible non committed value and show popup + final PropertyInspector propertyInspector = myManager.getEditor().getPropertyInspector(); + if(propertyInspector.isEditing()){ + propertyInspector.stopEditing(); + } + myManager.showIntentionPopup(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/VisibilityWatcherImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/VisibilityWatcherImpl.java new file mode 100644 index 00000000000..732e3e8cf90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/quickFixes/VisibilityWatcherImpl.java @@ -0,0 +1,31 @@ +package com.intellij.uiDesigner.quickFixes; + +import com.intellij.openapi.wm.impl.VisibilityWatcher; + +import javax.swing.*; + +/** + * [vova] This class should be inner but due to bugs in "beta" generics compiler + * I need to use "static" modifier. + * + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class VisibilityWatcherImpl extends VisibilityWatcher{ + private final QuickFixManager myManager; + private final JComponent myComponent; + + public VisibilityWatcherImpl(final QuickFixManager manager, final JComponent component) { + myManager = manager; + myComponent = component; + } + + public void visibilityChanged() { + if(myComponent.isShowing()){ + myManager.updateIntentionHintVisibility(); + } + else{ + myManager.hideIntentionHint(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanProperty.java new file mode 100644 index 00000000000..318cde9c673 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanProperty.java @@ -0,0 +1,63 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BeanProperty implements Comparable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.BeanProperty"); + + /** + * Property name. Cannot be null. + */ + public final String myName; + /** + * Property type. Cannot be null. + * There are two possible types: + *
      + *
    • java.lang.String
    • + *
    • boolean
    • + *
    + */ + public final String myType; + + public BeanProperty(final String name, final String type) { + LOG.assertTrue(name != null); + LOG.assertTrue(type != null); + + if(!"java.lang.String".equals(type) && !"boolean".equals(type)){ + throw new IllegalArgumentException("unknown type: " + type); + } + + myName = name; + myType = type; + } + + public int compareTo(final BeanProperty property) { + if(property == null){ + return 1; + } + else{ + return myName.compareTo(property.myName); + } + } + + /** + * This method is used by ComboBox editor of {@link BindToExistingBeanStep.MyTableCellEditor} + */ + public String toString() { + return myName; + } + + public boolean equals(final Object obj) { + if (this == obj) return true; + if (!(obj instanceof BeanProperty)) return false; + return myName.equals(((BeanProperty)obj).myName); + } + + public int hashCode() { + return myName.hashCode(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyListCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyListCellRenderer.java new file mode 100644 index 00000000000..111236ab3dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyListCellRenderer.java @@ -0,0 +1,38 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BeanPropertyListCellRenderer extends ColoredListCellRenderer{ + private final SimpleTextAttributes myAttrs1; + private final SimpleTextAttributes myAttrs2; + + public BeanPropertyListCellRenderer() { + myAttrs1 = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; + myAttrs2 = SimpleTextAttributes.REGULAR_ATTRIBUTES; + } + + protected void customizeCellRenderer( + final JList list, + final Object value, + final int index, + final boolean selected, + final boolean hasFocus + ) { + final BeanProperty property = (BeanProperty)value; + if(property == null){ + append("", myAttrs2); + } + else{ + append(property.myName, myAttrs1); + append(" ", myAttrs1); + append(property.myType, myAttrs2); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellEditor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellEditor.java new file mode 100644 index 00000000000..715feb9a5fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellEditor.java @@ -0,0 +1,47 @@ +package com.intellij.uiDesigner.wizard; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BeanPropertyTableCellEditor extends AbstractCellEditor implements TableCellEditor{ + private final JTextField myEditorComponent; + + public BeanPropertyTableCellEditor() { + myEditorComponent = new JTextField(); + myEditorComponent.setBorder(null); + } + + public Object getCellEditorValue() { + final String propertyName = myEditorComponent.getText().trim(); + if(propertyName.length() != 0){ + return new BeanProperty(propertyName, "java.lang.String"/*TODO[vova] provide real implementation*/); + } + else{ + return null; + } + } + + public Component getTableCellEditorComponent( + final JTable table, + final Object value, + final boolean isSelected, + final int row, + final int column + ) { + final BeanProperty property = (BeanProperty)value; + + if(property != null){ + myEditorComponent.setText(property.myName); + } + else{ + myEditorComponent.setText(null); + } + + return myEditorComponent; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellRenderer.java new file mode 100644 index 00000000000..a871935a5e9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanPropertyTableCellRenderer.java @@ -0,0 +1,62 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.ui.SimpleTextAttributes; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BeanPropertyTableCellRenderer extends ColoredTableCellRenderer{ + private final SimpleTextAttributes myAttrs1; + private final SimpleTextAttributes myAttrs2; + private final SimpleTextAttributes myAttrs3; + + BeanPropertyTableCellRenderer() { + myAttrs1 = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; + myAttrs2 = SimpleTextAttributes.REGULAR_ATTRIBUTES; + myAttrs3 = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.GRAY); + } + + protected void customizeCellRenderer( + final JTable table, + final Object value, + final boolean selected, + final boolean hasFocus, + final int row, + final int column + ) { + final BeanProperty property = (BeanProperty)value; + if(property == null){ + append("", myAttrs2); + } + else{ + append(property.myName, myAttrs1); + append(" ", myAttrs1); + + // Short type name + final String shortClassName; + final String packageName; + final int lastDotIndex = property.myType.lastIndexOf('.'); + if(lastDotIndex != -1){ + shortClassName = property.myType.substring(lastDotIndex + 1); + packageName = property.myType.substring(0, lastDotIndex); + } + else{ + shortClassName = property.myType; + packageName = null; + } + + append(shortClassName, myAttrs2); + + if(packageName != null){ + append(" (", myAttrs3); + append(packageName, myAttrs3); + append(")", myAttrs3); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanStep.java new file mode 100644 index 00000000000..5017f774f33 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BeanStep.java @@ -0,0 +1,203 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ide.util.PackageChooserDialog; +import com.intellij.ide.util.TreeClassChooserDialog; +import com.intellij.ide.wizard.CommitStepException; +import com.intellij.ide.wizard.StepAdapter; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.uiDesigner.FormEditingUtil; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BeanStep extends StepAdapter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.BeanStep"); + + private JPanel myComponent; + private TextFieldWithBrowseButton myTfWitgBtnChooseClass; + private JRadioButton myRbBindToNewBean; + private JRadioButton myRbBindToExistingBean; + JTextField myTfShortClassName; + private TextFieldWithBrowseButton myTfWithBtnChoosePackage; + private final WizardData myData; + + public BeanStep(final WizardData data) { + LOG.assertTrue(data != null); + + myData = data; + + final ItemListener itemListener = new ItemListener() { + public void itemStateChanged(final ItemEvent e) { + final boolean state = myRbBindToNewBean.isSelected(); + + myTfShortClassName.setEnabled(state); + myTfWithBtnChoosePackage.setEnabled(state); + + myTfWitgBtnChooseClass.setEnabled(!state); + } + }; + myRbBindToNewBean.addItemListener(itemListener); + myRbBindToExistingBean.addItemListener(itemListener); + + { + final ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(myRbBindToNewBean); + buttonGroup.add(myRbBindToExistingBean); + } + + myTfWitgBtnChooseClass.addActionListener( + new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final TreeClassChooserDialog chooser = TreeClassChooserDialog.withInnerClasses( + "Choose Bean Class", + myData.myProject, + GlobalSearchScope.projectScope(myData.myProject), + new TreeClassChooserDialog.ClassFilter() { + public boolean isAccepted(final PsiClass aClass) { + return aClass.getParent() instanceof PsiJavaFile; + } + }, + null + ); + chooser.show(); + final PsiClass aClass = chooser.getSelectedClass(); + if (aClass == null) { + return; + } + final String fqName = aClass.getQualifiedName(); + myTfWitgBtnChooseClass.setText(fqName); + } + } + ); + + myTfWithBtnChoosePackage.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final PackageChooserDialog dialog = new PackageChooserDialog("Choose Package", myData.myProject); + dialog.selectPackage(myTfWithBtnChoosePackage.getText()); + dialog.show(); + final PsiPackage aPackage = dialog.getSelectedPackage(); + if (aPackage != null) { + myTfWithBtnChoosePackage.setText(aPackage.getQualifiedName()); + } + } + }); + } + + public void _init() { + // Select way of binding + if(myData.myBindToNewBean){ + myRbBindToNewBean.setSelected(true); + } + else{ + myRbBindToExistingBean.setSelected(true); + } + + // New bean + myTfShortClassName.setText(myData.myShortClassName); + myTfWithBtnChoosePackage.setText(myData.myPackageName); + + // Existing bean + myTfWitgBtnChooseClass.setText( + myData.myBeanClass != null ? myData.myBeanClass.getQualifiedName() : null + ); + } + + private void resetBindings(){ + for(int i = myData.myBindings.length - 1; i >= 0; i--){ + myData.myBindings[i].myBeanProperty = null; + } + } + + public void _commit(boolean finishChosen) throws CommitStepException{ + final boolean newBindToNewBean = myRbBindToNewBean.isSelected(); + if(myData.myBindToNewBean != newBindToNewBean){ + resetBindings(); + } + + myData.myBindToNewBean = newBindToNewBean; + + if(myData.myBindToNewBean){ // new bean + final String oldShortClassName = myData.myShortClassName; + final String oldPackageName = myData.myPackageName; + + final String shortClassName = myTfShortClassName.getText().trim(); + if(shortClassName.length() == 0){ + throw new CommitStepException("Please specify class name of the bean to be created"); + } + final PsiManager psiManager = PsiManager.getInstance(myData.myProject); + if(!psiManager.getNameHelper().isIdentifier(shortClassName)){ + throw new CommitStepException("\"" + shortClassName + "\" is not a valid class name"); + } + + final String packageName = myTfWithBtnChoosePackage.getText().trim(); + if(packageName.length() != 0 && psiManager.findPackage(packageName) == null){ + throw new CommitStepException("Package with name \"" + packageName + "\" does not exist"); + } + + myData.myShortClassName = shortClassName; + myData.myPackageName = packageName; + + // check whether new class already exists + { + final String fullClassName = packageName.length() != 0 ? packageName + "." + shortClassName : shortClassName; + final Module module = ModuleUtil.getModuleForFile(myData.myProject, myData.myFormFile); + if (psiManager.findClass(fullClassName, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)) != null) { + throw new CommitStepException("Cannot create class \"" + fullClassName + "\" because it already exists"); + } + } + + if( + !Comparing.equal(oldShortClassName, shortClassName) || + !Comparing.equal(oldPackageName, packageName) + ){ + // After bean class changed we need to reset all previously set bindings + resetBindings(); + } + } + else{ // existing bean + final String oldFqClassName = myData.myBeanClass != null ? myData.myBeanClass.getQualifiedName() : null; + final String newFqClassName = myTfWitgBtnChooseClass.getText().trim(); + if(newFqClassName.length() == 0){ + throw new CommitStepException("Please specify fully qualified name of bean class"); + } + final PsiClass aClass = PsiManager.getInstance(myData.myProject).findClass( + newFqClassName, + GlobalSearchScope.allScope(myData.myProject) + ); + if(aClass == null){ + throw new CommitStepException("Class with name \"" + newFqClassName + "\" does not exist"); + } + myData.myBeanClass = aClass; + + if(!Comparing.equal(oldFqClassName, newFqClassName)){ + // After bean class changed we need to reset all previously set bindings + resetBindings(); + } + } + } + + public JComponent getComponent() { + return myComponent; + } + + public Icon getIcon() { + return IconLoader.getIcon("/com/intellij/uiDesigner/icons/dataBinding.png"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindCompositeStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindCompositeStep.java new file mode 100644 index 00000000000..5badec9a256 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindCompositeStep.java @@ -0,0 +1,68 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ide.wizard.CommitStepException; +import com.intellij.ide.wizard.StepAdapter; +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BindCompositeStep extends StepAdapter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.BindCompositeStep"); + private final WizardData myData; + private final JPanel myCardHolder; + + private final BindToNewBeanStep myBindToNewBeanStep; + private final BindToExistingBeanStep myBindToExistingBeanStep; + + BindCompositeStep(final WizardData data) { + LOG.assertTrue(data != null); + myData = data; + + myBindToNewBeanStep = new BindToNewBeanStep(data); + myBindToExistingBeanStep = new BindToExistingBeanStep(data); + + myCardHolder = new JPanel(new CardLayout()); + myCardHolder.add(myBindToNewBeanStep.getComponent(), "newBean"); + myCardHolder.add(myBindToExistingBeanStep.getComponent(), "existingBean"); + } + + public JComponent getComponent() { + return myCardHolder; + } + + public void _init() { + if(myData.myBindToNewBean){ + myBindToNewBeanStep._init(); + final CardLayout layout = (CardLayout)myCardHolder.getLayout(); + layout.show(myCardHolder, "newBean"); + } + else{ + myBindToExistingBeanStep._init(); + final CardLayout layout = (CardLayout)myCardHolder.getLayout(); + layout.show(myCardHolder, "existingBean"); + } + } + + public void _commit(boolean finishChosen) throws CommitStepException { + if(myData.myBindToNewBean){ + myBindToNewBeanStep._commit(finishChosen); + } + else{ + myBindToExistingBeanStep._commit(finishChosen); + } + } + + public Icon getIcon() { + if(myData.myBindToNewBean){ + return myBindToNewBeanStep.getIcon(); + } + else{ + return myBindToExistingBeanStep.getIcon(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToExistingBeanStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToExistingBeanStep.java new file mode 100644 index 00000000000..cb9f7391c1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToExistingBeanStep.java @@ -0,0 +1,273 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ide.wizard.StepAdapter; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BindToExistingBeanStep extends StepAdapter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.BindToExistingBeanStep"); + + private JScrollPane myScrollPane; + private JTable myTable; + private final WizardData myData; + private final MyTableModel myTableModel; + private JCheckBox myChkIsModified; + private JCheckBox myChkGetData; + private JCheckBox myChkSetData; + private JPanel myPanel; + + BindToExistingBeanStep(final WizardData data) { + LOG.assertTrue(data != null); + myData = data; + myTableModel = new MyTableModel(); + myTable.setModel(myTableModel); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.getColumnModel().setColumnSelectionAllowed(true); + myScrollPane.getViewport().setBackground(myTable.getBackground()); + myTable.setSurrendersFocusOnKeystroke(true); + + // Customize "Form Property" column + { + final TableColumn column = myTable.getColumnModel().getColumn(0/*Form Property*/); + column.setCellRenderer(new FormPropertyTableCellRenderer(myData.myProject)); + } + + // Customize "Bean Property" column + { + final TableColumn column = myTable.getColumnModel().getColumn(1/*Bean Property*/); + column.setCellRenderer(new BeanPropertyTableCellRenderer()); + final MyTableCellEditor cellEditor = new MyTableCellEditor(); + column.setCellEditor(cellEditor); + + final DefaultCellEditor editor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); + editor.setClickCountToStart(1); + + myTable.setRowHeight(cellEditor.myCbx.getPreferredSize().height); + } + + myChkGetData.setSelected(true); + myChkGetData.setEnabled(false); + myChkSetData.setSelected(true); + myChkSetData.setEnabled(false); + myChkIsModified.setSelected(myData.myGenerateIsModified); + } + + public JComponent getComponent() { + return myPanel; + } + + public void _init() { + // Check that data is correct + LOG.assertTrue(!myData.myBindToNewBean); + LOG.assertTrue(myData.myBeanClass != null); + myTableModel.fireTableDataChanged(); + } + + public void _commit(boolean finishChosen) { + // Stop editing if any + final TableCellEditor cellEditor = myTable.getCellEditor(); + if(cellEditor != null){ + cellEditor.stopCellEditing(); + } + + myData.myGenerateIsModified = myChkIsModified.isSelected(); + + // TODO[vova] check that at least one binding field exists + } + + public Icon getIcon() { + return IconLoader.getIcon("/com/intellij/uiDesigner/icons/dataBinding.png"); + } + + private final class MyTableModel extends AbstractTableModel{ + private final String[] myColumnNames; + + public MyTableModel() { + myColumnNames = new String[]{"Form Field", "Bean Property"}; + } + + public int getColumnCount() { + return myColumnNames.length; + } + + public String getColumnName(final int column) { + return myColumnNames[column]; + } + + public int getRowCount() { + return myData.myBindings.length; + } + + public boolean isCellEditable(final int row, final int column) { + return column == 1/*Bean Property*/; + } + + public Object getValueAt(final int row, final int column) { + if(column == 0/*Form Property*/){ + return myData.myBindings[row].myFormProperty; + } + else if(column == 1/*Bean Property*/){ + return myData.myBindings[row].myBeanProperty; + } + else{ + throw new IllegalArgumentException("unknown column: " + column); + } + } + + public void setValueAt(final Object value, final int row, final int column) { + LOG.assertTrue(column == 1/*Bean Property*/); + final FormProperty2BeanProperty binding = myData.myBindings[row]; + binding.myBeanProperty = (BeanProperty)value; + } + } + + private final class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor{ + private final ComboBox myCbx; + /* -1 if not defined*/ + private int myEditingRow; + + public MyTableCellEditor() { + myCbx = new ComboBox(); + myCbx.setEditable(true); + myCbx.setRenderer(new BeanPropertyListCellRenderer()); + myCbx.putClientProperty("tableCellEditor", this); + + final JComponent editorComponent = (JComponent)myCbx.getEditor().getEditorComponent(); + editorComponent.setBorder(null); + + myEditingRow = -1; + } + + /** + * @return whether it's possible to convert type1 into type2 + * and vice versa. + */ + private boolean canConvert(final String type1, final String type2){ + if("boolean".equals(type1) || "boolean".equals(type2)){ + return type1.equals(type2); + } + else{ + return true; + } + } + + public Component getTableCellEditorComponent( + final JTable table, + final Object value, + final boolean isSelected, + final int row, + final int column + ) { + myEditingRow = row; + final DefaultComboBoxModel model = (DefaultComboBoxModel)myCbx.getModel(); + model.removeAllElements(); + model.addElement(null/**/); + + // Fill combobox with available bean's properties + final String[] rProps = PropertyUtil.getReadableProperties(myData.myBeanClass, true); + final String[] wProps = PropertyUtil.getWritableProperties(myData.myBeanClass, true); + final ArrayList rwProps = new ArrayList(); + + outer: for(int i = rProps.length - 1; i >= 0; i--){ + final String propName = rProps[i]; + if(ArrayUtil.find(wProps, propName) != -1){ + LOG.assertTrue(!rwProps.contains(propName)); + final PsiMethod getter = PropertyUtil.findPropertyGetter(myData.myBeanClass, propName, false, true); + LOG.assertTrue(getter != null); + final PsiType returnType = getter.getReturnType(); + LOG.assertTrue(returnType != null); + + // There are two possible types: boolean and java.lang.String + final String typeName = returnType.getCanonicalText(); + LOG.assertTrue(typeName != null); + if(!"boolean".equals(typeName) && !"java.lang.String".equals(typeName)){ + continue; + } + + // Check that the property is not in use yet + for(int j = myData.myBindings.length - 1; j >= 0; j--){ + final BeanProperty _property = myData.myBindings[j].myBeanProperty; + if(j != row && _property != null && propName.equals(_property.myName)){ + continue outer; + } + } + + // Check that we conver types + if( + !canConvert( + myData.myBindings[row].myFormProperty.getComponentPropertyClassName(), + typeName + ) + ){ + continue; + } + + rwProps.add(new BeanProperty(propName, typeName)); + } + } + + Collections.sort(rwProps); + + for(int i = 0; i < rwProps.size(); i++){ + model.addElement(rwProps.get(i)); + } + + // Set initially selected item + if(myData.myBindings[row].myBeanProperty != null){ + myCbx.setSelectedItem(myData.myBindings[row].myBeanProperty); + } + else{ + myCbx.setSelectedIndex(0/**/); + } + + return myCbx; + } + + public Object getCellEditorValue() { + LOG.assertTrue(myEditingRow != -1); + try { + // our ComboBox is editable so its editor can contain: + // 1) BeanProperty object (it user just selected something from ComboBox) + // 2) java.lang.String if user type something into ComboBox + + final Object selectedItem = myCbx.getEditor().getItem(); + if(selectedItem instanceof BeanProperty){ + return selectedItem; + } + else if(selectedItem instanceof String){ + final String fieldName = ((String)selectedItem).trim(); + + if(fieldName.length() == 0){ + return null; // binding is not defined + } + + final String fieldType = myData.myBindings[myEditingRow].myFormProperty.getComponentPropertyClassName(); + return new BeanProperty(fieldName, fieldType); + } + else{ + throw new IllegalArgumentException("unknown selectedItem: " + selectedItem); + } + } + finally { + myEditingRow = -1; // unset editing row. So it's possible to invoke this method only once per editing + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java new file mode 100644 index 00000000000..8d08a862c96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java @@ -0,0 +1,154 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.ide.wizard.CommitStepException; +import com.intellij.ide.wizard.StepAdapter; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiNameHelper; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumn; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class BindToNewBeanStep extends StepAdapter{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.BindToNewBeanStep"); + + private JScrollPane myScrollPane; + private JTable myTable; + private final WizardData myData; + private final MyTableModel myTableModel; + private JCheckBox myChkIsModified; + private JCheckBox myChkSetData; + private JCheckBox myChkGetData; + private JPanel myPanel; + + BindToNewBeanStep(final WizardData data) { + LOG.assertTrue(data != null); + myData = data; + myTableModel = new MyTableModel(); + myTable.setModel(myTableModel); + myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myScrollPane.getViewport().setBackground(myTable.getBackground()); + myTable.setSurrendersFocusOnKeystroke(true); + + // Customize "Form Property" column + { + final TableColumn column = myTable.getColumnModel().getColumn(0/*Form Property*/); + column.setCellRenderer(new FormPropertyTableCellRenderer(myData.myProject)); + } + + // Customize "Bean Property" column + { + final TableColumn column = myTable.getColumnModel().getColumn(1/*Bean Property*/); + column.setCellRenderer(new BeanPropertyTableCellRenderer()); + column.setCellEditor(new BeanPropertyTableCellEditor()); + + final DefaultCellEditor editor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); + editor.setClickCountToStart(1); + } + + myChkGetData.setSelected(true); + myChkGetData.setEnabled(false); + myChkSetData.setSelected(true); + myChkSetData.setEnabled(false); + myChkIsModified.setSelected(myData.myGenerateIsModified); + } + + public JComponent getComponent() { + return myPanel; + } + + public void _init() { + // Check that data is correct + LOG.assertTrue(myData.myBindToNewBean); + myTableModel.fireTableDataChanged(); + } + + public void _commit(boolean finishChosen) throws CommitStepException { + // Stop editing if any + final TableCellEditor cellEditor = myTable.getCellEditor(); + if(cellEditor != null){ + cellEditor.stopCellEditing(); + } + + // Check that all included fields are bound to valid bean properties + final PsiNameHelper nameHelper = PsiManager.getInstance(myData.myProject).getNameHelper(); + for(int i = 0; i null. + */ + public LwComponent getLwComponent() { + return myLwComponent; + } + + /** + * @return never null + */ + public String getComponentPropertyGetterName() { + return myComponentPropertyGetterName; + } + + /** + * @return never null + */ + public String getComponentPropertySetterName() { + return myComponentPropertySetterName; + } + + /** + * @return never null. This method can return only one of the following values: + * "int", "float", "double", "long", "boolean", "char", "byte", "short", "java.lang.String" + */ + public String getComponentPropertyClassName() { + return myComponentPropertyClassName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormProperty2BeanProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormProperty2BeanProperty.java new file mode 100644 index 00000000000..b809adb7559 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormProperty2BeanProperty.java @@ -0,0 +1,22 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class FormProperty2BeanProperty { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.FormProperty2BeanProperty"); + + public final FormProperty myFormProperty; + /** + * This field can be null if nothing is bound. + */ + public BeanProperty myBeanProperty; + + public FormProperty2BeanProperty(final FormProperty formProperty) { + LOG.assertTrue(formProperty != null); + myFormProperty = formProperty; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormPropertyTableCellRenderer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormPropertyTableCellRenderer.java new file mode 100644 index 00000000000..70cb3fa6107 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/FormPropertyTableCellRenderer.java @@ -0,0 +1,90 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.uiDesigner.lw.LwComponent; +import com.intellij.uiDesigner.palette.ComponentItem; +import com.intellij.uiDesigner.palette.Palette; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +final class FormPropertyTableCellRenderer extends ColoredTableCellRenderer{ + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.FormPropertyTableCellRenderer"); + + private final Palette myPalette; + private final SimpleTextAttributes myAttrs1; + private final SimpleTextAttributes myAttrs2; + private final SimpleTextAttributes myAttrs3; + + FormPropertyTableCellRenderer(final Project project) { + LOG.assertTrue(project != null); + + myPalette = Palette.getInstance(project); + myAttrs1 = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; + myAttrs2 = SimpleTextAttributes.REGULAR_ATTRIBUTES; + myAttrs3 = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.GRAY); + + setFocusBorderAroundIcon(true); + } + + protected void customizeCellRenderer( + final JTable table, + final Object value, + final boolean selected, + final boolean hasFocus, + final int row, + final int column + ) { + final FormProperty property = (FormProperty)value; + LOG.assertTrue(property != null); + + final LwComponent component = property.getLwComponent(); + + // Icon + final Icon icon; + final String fqClassName = component.getComponentClassName(); + final ComponentItem item = myPalette.getItem(fqClassName); + if (item != null) { + icon = item.getSmallIcon(); + } + else { + icon = IconLoader.getIcon("/com/intellij/uiDesigner/icons/unknown-small.png"); + } + setIcon(icon); + + // Binding + append(component.getBinding(), myAttrs1); + + // Component class name and package + final String shortClassName; + final String packageName; + final int lastDotIndex = fqClassName.lastIndexOf('.'); + if (lastDotIndex != -1) { + shortClassName = fqClassName.substring(lastDotIndex + 1); + packageName = fqClassName.substring(0, lastDotIndex); + } + else{ // default package + shortClassName = fqClassName; + packageName = null; + } + + LOG.assertTrue(shortClassName.length() > 0); + + append(" ", myAttrs2); /*small gap between icon and class name*/ + append(shortClassName, myAttrs2); + + if(packageName != null){ + append(" (", myAttrs3); + append(packageName, myAttrs3); + append(")", myAttrs3); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/Generator.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/Generator.java new file mode 100644 index 00000000000..c17a7bc4128 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/Generator.java @@ -0,0 +1,726 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.uiDesigner.FormEditingUtil; +import com.intellij.uiDesigner.PsiPropertiesProvider; +import com.intellij.uiDesigner.compiler.AlienFormFileException; +import com.intellij.uiDesigner.compiler.Utils; +import com.intellij.uiDesigner.lw.LwComponent; +import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.util.IncorrectOperationException; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class Generator { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard"); + + /** + * @param rootContainer output parameter; should be LwRootContainer[1] + */ + public static FormProperty[] exposeForm(final Project project, final VirtualFile formFile, final LwRootContainer[] rootContainer) throws MyException{ + final Module module = ModuleUtil.getModuleForFile(project, formFile); + LOG.assertTrue(module != null); + + final PsiPropertiesProvider propertiesProvider = new PsiPropertiesProvider(module); + + final Document doc = FileDocumentManager.getInstance().getDocument(formFile); + final LwRootContainer _rootContainer; + try { + _rootContainer = Utils.getRootContainer(doc.getText(), propertiesProvider); + } + catch (AlienFormFileException e) { + throw new MyException(e.getMessage()); + } + catch (Exception e) { + throw new MyException("Cannot process form file. Reason: " + e); + } + + rootContainer[0] = _rootContainer; + + final String classToBind = _rootContainer.getClassToBind(); + if (classToBind == null) { + throw new MyException("Form is not bound to a class"); + } + + final PsiClass boundClass = FormEditingUtil.findClassToBind(module, classToBind); + if(boundClass == null){ + throw new MyException("Bound class " + classToBind + " does not exist"); + } + + final ArrayList result = new ArrayList(); + final MyException[] exception = new MyException[1]; + + FormEditingUtil.iterate( + _rootContainer, + new FormEditingUtil.ComponentVisitor() { + public boolean visit(final LwComponent component) { + final String binding = component.getBinding(); + if (binding == null) { + return true; + } + + final PsiField[] fields = boundClass.getFields(); + PsiField field = null; + for(int i = fields.length - 1; i >=0 ; i--){ + if(binding.equals(fields[i].getName())){ + field = fields[i]; + break; + } + } + if(field == null){ + exception[0] = new MyException("Field " + binding + " not found in class " + classToBind); + return false; + } + + final PsiClass fieldClass = getClassByType(field.getType()); + if (fieldClass == null) { + exception[0] = new MyException("Invalid binding field type: field " + binding + ", class " + classToBind); + return false; + } + + if (instanceOf(fieldClass, JTextComponent.class.getName())) { + result.add(new FormProperty(component, "getText", "setText", String.class.getName())); + } + else if (instanceOf(fieldClass, JCheckBox.class.getName())) { + result.add(new FormProperty(component, "isSelected", "setSelected", boolean.class.getName())); + } + + return true; + } + } + ); + + if (exception[0] != null) { + throw exception[0]; + } + + return result.toArray(new FormProperty[result.size()]); + } + + private static PsiClass getClassByType(final PsiType type) { + if (!(type instanceof PsiClassType)) { + return null; + } + return ((PsiClassType)type).resolve(); + } + + private static boolean instanceOf(final PsiClass jComponentClass, final String baseClassName) { + for (PsiClass c = jComponentClass; c != null; c = c.getSuperClass()){ + if (baseClassName.equals(c.getQualifiedName())) { + return true; + } + } + return false; + } + + /** + * Should be invoked in command and write action + */ + public static void generateDataBindingMethods(final WizardData data) throws MyException { + if (data.myBindToNewBean) { + final PsiClass beanClass = createBeanClass(data); + LOG.assertTrue(beanClass != null); + data.myBeanClass = beanClass; + } + + final HashMap binding2beanGetter = new HashMap(); + final HashMap binding2beanSetter = new HashMap(); + + final FormProperty2BeanProperty[] bindings = data.myBindings; + for (int i = 0; i < bindings.length; i++) { + final FormProperty2BeanProperty form2bean = bindings[i]; + if (form2bean == null || form2bean.myBeanProperty == null) { + continue; + } + + // check that bean contains the property, and if not, try to add the property to the bean + { + final String setterName = PropertyUtil.suggestSetterName(form2bean.myBeanProperty.myName); + final PsiMethod[] methodsByName = data.myBeanClass.findMethodsByName(setterName, true); + if (methodsByName == null || methodsByName.length < 1) { + // bean does not contain this property + // try to add... + + LOG.assertTrue(!data.myBindToNewBean); // just generated bean class should contain all necessary properties + + if (!data.myBeanClass.isWritable()) { + throw new MyException("Cannot add property to non writable class " + data.myBeanClass.getQualifiedName()); + } + + final StringBuffer membersBuffer = new StringBuffer(); + final StringBuffer methodsBuffer = new StringBuffer(); + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(data.myBeanClass.getProject()); + + generateProperty(codeStyleManager, form2bean.myBeanProperty.myName, form2bean.myBeanProperty.myType, membersBuffer, methodsBuffer); + + final PsiClass fakeClass; + try { + fakeClass = data.myBeanClass.getManager().getElementFactory().createClassFromText( + membersBuffer.toString() + methodsBuffer.toString(), + null + ); + + final PsiField[] fields = fakeClass.getFields(); + { + final PsiElement result = data.myBeanClass.add(fields[0]); + codeStyleManager.shortenClassReferences(result); + codeStyleManager.reformat(result); + } + + final PsiMethod[] methods = fakeClass.getMethods(); + { + final PsiElement result = data.myBeanClass.add(methods[0]); + codeStyleManager.shortenClassReferences(result); + codeStyleManager.reformat(result); + } + { + final PsiElement result = data.myBeanClass.add(methods[1]); + codeStyleManager.shortenClassReferences(result); + codeStyleManager.reformat(result); + } + } + catch (IncorrectOperationException e) { + throw new MyException(e.getMessage()); + } + } + } + + final PsiMethod propertySetter = PropertyUtil.findPropertySetter(data.myBeanClass, form2bean.myBeanProperty.myName, false, true); + final PsiMethod propertyGetter = PropertyUtil.findPropertyGetter(data.myBeanClass, form2bean.myBeanProperty.myName, false, true); + + if (propertyGetter == null) { + // todo + continue; + } + if (propertySetter == null) { + // todo + continue; + } + + final String binding = form2bean.myFormProperty.getLwComponent().getBinding(); + binding2beanGetter.put(binding, propertyGetter.getName()); + binding2beanSetter.put(binding, propertySetter.getName()); + } + + final String dataBeanClassName = data.myBeanClass.getQualifiedName(); + + final LwRootContainer[] rootContainer = new LwRootContainer[1]; + final FormProperty[] formProperties = exposeForm(data.myProject, data.myFormFile, rootContainer); + + final StringBuffer getDataBody = new StringBuffer(); + final StringBuffer setDataBody = new StringBuffer(); + final StringBuffer isModifiedBody = new StringBuffer(); + + // iterate exposed formproperties + + for (int i = 0; i < formProperties.length; i++) { + final FormProperty formProperty = formProperties[i]; + + final String binding = formProperty.getLwComponent().getBinding(); + if (!binding2beanGetter.containsKey(binding)) { + continue; + } + + getDataBody.append("data."); + getDataBody.append(binding2beanSetter.get(binding)); + getDataBody.append("("); + getDataBody.append(binding); + getDataBody.append("."); + getDataBody.append(formProperty.getComponentPropertyGetterName()); + getDataBody.append("());\n"); + + setDataBody.append(binding); + setDataBody.append("."); + setDataBody.append(formProperty.getComponentPropertySetterName()); + setDataBody.append("(data."); + setDataBody.append(binding2beanGetter.get(binding)); + setDataBody.append("());\n"); + + final String propertyClassName = formProperty.getComponentPropertyClassName(); + if ("boolean".equals(propertyClassName)) { + isModifiedBody.append("if ("); + // + isModifiedBody.append(binding); + isModifiedBody.append("."); + isModifiedBody.append(formProperty.getComponentPropertyGetterName()); + isModifiedBody.append("()"); + // + isModifiedBody.append("!= "); + // + isModifiedBody.append("data."); + isModifiedBody.append(binding2beanGetter.get(binding)); + isModifiedBody.append("()"); + // + isModifiedBody.append(") return true;\n"); + } + else { + isModifiedBody.append("if ("); + // + isModifiedBody.append(binding); + isModifiedBody.append("."); + isModifiedBody.append(formProperty.getComponentPropertyGetterName()); + isModifiedBody.append("()"); + // + isModifiedBody.append("!= null ? "); + // + isModifiedBody.append("!"); + // + isModifiedBody.append(binding); + isModifiedBody.append("."); + isModifiedBody.append(formProperty.getComponentPropertyGetterName()); + isModifiedBody.append("()"); + // + isModifiedBody.append(".equals("); + // + isModifiedBody.append("data."); + isModifiedBody.append(binding2beanGetter.get(binding)); + isModifiedBody.append("()"); + isModifiedBody.append(") : "); + // + isModifiedBody.append("data."); + isModifiedBody.append(binding2beanGetter.get(binding)); + isModifiedBody.append("()"); + isModifiedBody.append("!= null"); + // + isModifiedBody.append(") return true;\n"); + } + } + isModifiedBody.append("return false;\n"); + + final String textOfMethods = + "public void setData(" + dataBeanClassName + " data){\n" + + setDataBody.toString() + + "}\n" + + "\n" + + "public void getData(" + dataBeanClassName + " data){\n" + + getDataBody.toString() + + "}\n" + + "\n" + + "public boolean isModified(" + dataBeanClassName + " data){\n" + + isModifiedBody.toString() + + "}\n"; + + // put them to the bound class + + final Module module = ModuleUtil.getModuleForFile(data.myProject, data.myFormFile); + LOG.assertTrue(module != null); + final PsiClass boundClass = FormEditingUtil.findClassToBind(module, rootContainer[0].getClassToBind()); + LOG.assertTrue(boundClass != null); + + // todo: check that this method does not exist yet + + final PsiClass fakeClass; + try { + fakeClass = PsiManager.getInstance(data.myProject).getElementFactory().createClassFromText(textOfMethods, null); + + final PsiMethod methodSetData = fakeClass.getMethods()[0]; + final PsiMethod methodGetData = fakeClass.getMethods()[1]; + final PsiMethod methodIsModified = fakeClass.getMethods()[2]; + + final PsiMethod existing1 = boundClass.findMethodBySignature(methodSetData, false); + final PsiMethod existing2 = boundClass.findMethodBySignature(methodGetData, false); + final PsiMethod existing3 = boundClass.findMethodBySignature(methodIsModified, false); + + // warning already shown + if (existing1 != null) { + existing1.delete(); + } + if (existing2 != null) { + existing2.delete(); + } + if (existing3 != null) { + existing3.delete(); + } + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(module.getProject()); + + final PsiElement setData = boundClass.add(methodSetData); + codeStyleManager.shortenClassReferences(setData); + codeStyleManager.reformat(setData); + + final PsiElement getData = boundClass.add(methodGetData); + codeStyleManager.shortenClassReferences(getData); + codeStyleManager.reformat(getData); + + if (data.myGenerateIsModified) { + final PsiElement isModified = boundClass.add(methodIsModified); + codeStyleManager.shortenClassReferences(isModified); + codeStyleManager.reformat(isModified); + } + + final OpenFileDescriptor descriptor = new OpenFileDescriptor(setData.getProject(), setData.getContainingFile().getVirtualFile(), setData.getTextOffset()); + FileEditorManager.getInstance(data.myProject).openTextEditor(descriptor, true); + } + catch (IncorrectOperationException e) { + throw new MyException(e.getMessage()); + } + } + + private static PsiClass createBeanClass(final WizardData wizardData) throws MyException { + final PsiManager psiManager = PsiManager.getInstance(wizardData.myProject); + + final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(wizardData.myProject); + final ProjectFileIndex fileIndex = projectRootManager.getFileIndex(); + final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(wizardData.myFormFile); + if (sourceRoot == null) { + throw new MyException("Form file is not in source root"); + } + + final PsiDirectory rootDirectory = psiManager.findDirectory(sourceRoot); + LOG.assertTrue(rootDirectory != null); + + final PsiPackage aPackage = psiManager.findPackage(wizardData.myPackageName); + if (aPackage == null) { + throw new MyException("Package does not exist: " + wizardData.myPackageName); + } + + PsiDirectory targetDir = null; + + final PsiDirectory[] directories = aPackage.getDirectories(); + for (int i = 0; i < directories.length; i++) { + final PsiDirectory psiDirectory = directories[i]; + if (PsiTreeUtil.isAncestor(rootDirectory, psiDirectory, false)){ + targetDir = psiDirectory; + break; + } + } + + if (targetDir == null) { + // todo + throw new MyException("Cannot find package: " + wizardData.myPackageName); + } + + final String body = + "public class " + wizardData.myShortClassName + "{\n" + + "public " + wizardData.myShortClassName + "(){}\n" + + "}"; + + try { + PsiFile sourceFile = psiManager.getElementFactory().createFileFromText(wizardData.myShortClassName + ".java", body); + sourceFile = (PsiFile)targetDir.add(sourceFile); + + final PsiClass beanClass = ((PsiJavaFile)sourceFile).getClasses()[0]; + + final ArrayList properties = new ArrayList(); + final HashMap property2fqClassName = new HashMap(); + + final FormProperty2BeanProperty[] bindings = wizardData.myBindings; + for (int i = 0; i < bindings.length; i++) { + final FormProperty2BeanProperty binding = bindings[i]; + if (binding == null || binding.myBeanProperty == null) { + continue; + } + + properties.add(binding.myBeanProperty.myName); + + // todo: handle "casts" ? + + final String propertyClassName = binding.myFormProperty.getComponentPropertyClassName(); + + property2fqClassName.put(binding.myBeanProperty.myName, propertyClassName); + } + + generateBean(beanClass, (String[])properties.toArray(new String[properties.size()]), property2fqClassName); + + return beanClass; + } + catch (IncorrectOperationException e) { + throw new MyException(e.getMessage()); + } + } + + // todo: inline + private static void generateBean( + final PsiClass aClass, + final String[] properties, + final HashMap property2fqClassName + ) throws MyException { + final StringBuffer membersBuffer = new StringBuffer(); + final StringBuffer methodsBuffer = new StringBuffer(); + + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(aClass.getProject()); + + for (int i = 0; i < properties.length; i++) { + final String property = properties[i]; + LOG.assertTrue(property != null); + final String type = property2fqClassName.get(property); + LOG.assertTrue(type != null); + + generateProperty(codeStyleManager, property, type, membersBuffer, methodsBuffer); + } + + final PsiClass fakeClass; + try { + fakeClass = aClass.getManager().getElementFactory().createClassFromText( + membersBuffer.toString() + methodsBuffer.toString(), + null + ); + + final PsiField[] fields = fakeClass.getFields(); + for (int i = 0; i < fields.length; i++) { + final PsiField field = fields[i]; + aClass.add(field); + } + + final PsiMethod[] methods = fakeClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + final PsiMethod method = methods[i]; + aClass.add(method); + } + + codeStyleManager.shortenClassReferences(aClass); + codeStyleManager.reformat(aClass); + } + catch (IncorrectOperationException e) { + throw new MyException(e.getMessage()); + } + } + + private static void generateProperty(final CodeStyleManager codeStyleManager, + final String property, + final String type, + final StringBuffer membersBuffer, final StringBuffer methodsBuffer) { + final String field = codeStyleManager.suggestVariableName(VariableKind.FIELD, property, null, null).names[0]; + + membersBuffer.append("private "); + membersBuffer.append(type); + membersBuffer.append(" "); + membersBuffer.append(field); + membersBuffer.append(";\n"); + + // getter + methodsBuffer.append("public "); + methodsBuffer.append(type); + methodsBuffer.append(" "); + methodsBuffer.append(suggestGetterName(property, type)); + methodsBuffer.append("(){\n"); + methodsBuffer.append("return "); + methodsBuffer.append(field); + methodsBuffer.append(";}\n"); + + // setter + final String parameterName = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, property, null, null).names[0]; + methodsBuffer.append("public void "); + methodsBuffer.append(PropertyUtil.suggestSetterName(property)); + methodsBuffer.append("(final "); + methodsBuffer.append(type); + methodsBuffer.append(" "); + methodsBuffer.append(parameterName); + methodsBuffer.append("){\n"); + if (parameterName.equals(field)) { + methodsBuffer.append("this."); + } + methodsBuffer.append(field); + methodsBuffer.append("="); + methodsBuffer.append(parameterName); + methodsBuffer.append(";}\n"); + } + + private static String suggestGetterName(final String propertyName, final String propertyType) { + final StringBuffer name = new StringBuffer(StringUtil.capitalize(propertyName)); + if ("boolean".equals(propertyType)) { + name.insert(0, "is"); + } + else { + name.insert(0, "get"); + } + return name.toString(); + } + + public static void prepareWizardData(final WizardData data, PsiClass boundClass) throws MyException { + + final PsiMethod[] allGetDataMethods = boundClass.findMethodsByName("getData", false); + final PsiMethod[] allSetDataMethods = boundClass.findMethodsByName("setData", false); + + PsiMethod setDataMethod = null; + PsiClass beanClass = null; + + // find get/set pair and bean class + outer: for (int i = 0; i < allGetDataMethods.length; i++) { + final PsiMethod _getMethod = allGetDataMethods[i]; + + if (_getMethod.getReturnType() != PsiType.VOID) { + continue; + } + + final PsiParameter[] _getMethodParameters = _getMethod.getParameterList().getParameters(); + if (_getMethodParameters.length != 1) { + continue; + } + + final PsiClass _getParameterClass = getClassByType(_getMethodParameters[0].getType()); + if (_getParameterClass == null) { + continue; + } + + for (int j = 0; j < allSetDataMethods.length; j++) { + final PsiMethod _setMethod = allSetDataMethods[j]; + + if (_setMethod.getReturnType() != PsiType.VOID) { + continue; + } + + final PsiParameter[] _setMethodParameters = _setMethod.getParameterList().getParameters(); + if (_setMethodParameters.length != 1) { + continue; + } + + final PsiClass _setParameterClass = getClassByType(_setMethodParameters[0].getType()); + if (_setParameterClass != _getParameterClass) { + continue; + } + + + // pair found !!! + + setDataMethod = _setMethod; + beanClass = _getParameterClass; + break outer; + } + } + + if (beanClass == null) { + // nothing found + return; + } + + data.myBindToNewBean = false; + data.myBeanClass = beanClass; + + // parse setData() and try to associate fields with bean + { + final PsiCodeBlock body = setDataMethod.getBody(); + if (body == null) { + return; + } + + final PsiElement[] children = body.getChildren(); + for (int i = 0; i < children.length; i++) { + // Parses sequences like: a.foo(b.bar()); + final PsiField bindingField; + + final PsiElement child = children[i]; + if (!(child instanceof PsiExpressionStatement)) { + continue; + } + + final PsiExpression expression = ((PsiExpressionStatement)child).getExpression(); + if (!(expression instanceof PsiMethodCallExpression)) { + continue; + } + + final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)expression; + + // find binding field ('a') + int index = -1; + { + final PsiElement psiElement = getObjectForWhichMethodWasCalled(callExpression); + if (!(psiElement instanceof PsiField)) { + continue; + } + + if (((PsiField)psiElement).getContainingClass() != boundClass){ + continue; + } + + bindingField = (PsiField)psiElement; + + // find binding for this field + final FormProperty2BeanProperty[] bindings = data.myBindings; + for (int j = 0; j < bindings.length; j++) { + final FormProperty2BeanProperty binding = bindings[j]; + if (bindingField.getName().equals(binding.myFormProperty.getLwComponent().getBinding())){ + index = j; + break; + } + } + } + + if (index == -1) { + continue; + } + + // find 'bar()' + { + final PsiReferenceParameterList parameterList = callExpression.getMethodExpression().getParameterList(); + if (parameterList == null) { + continue; + } + + final PsiExpressionList argumentList = callExpression.getArgumentList(); + if (argumentList == null) { + continue; + } + + final PsiExpression[] expressions = argumentList.getExpressions(); + if (expressions == null || expressions.length != 1) { + continue; + } + + if (!(expressions[0] instanceof PsiMethodCallExpression)) { + continue; + } + + final PsiMethodCallExpression callExpression2 = ((PsiMethodCallExpression)expressions[0]); + + // check that 'b' is parameter + final PsiElement psiElement = getObjectForWhichMethodWasCalled(callExpression2); + if (!(psiElement instanceof PsiParameter)) { + continue; + } + + final PsiMethod barMethod = ((PsiMethod)callExpression2.getMethodExpression().resolve()); + if (barMethod == null) { + continue; + } + + if (!PropertyUtil.isSimplePropertyGetter(barMethod)) { + continue; + } + + final String propertyName = PropertyUtil.getPropertyName(barMethod); + + data.myBindings[index].myBeanProperty = new BeanProperty(propertyName, barMethod.getReturnType().getCanonicalText()); + } + } + } + } + + private static PsiElement getObjectForWhichMethodWasCalled(final PsiMethodCallExpression callExpression) { + final PsiExpression qualifierExpression = callExpression.getMethodExpression().getQualifierExpression(); + if (!(qualifierExpression instanceof PsiReferenceExpression)) { + return null; + } + return ((PsiReferenceExpression)qualifierExpression).resolve(); + } + + public static final class MyException extends Exception{ + public MyException(final String message) { + super(message); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/WizardData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/WizardData.java new file mode 100644 index 00000000000..89dc6477e94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/uiDesigner/wizard/WizardData.java @@ -0,0 +1,80 @@ +package com.intellij.uiDesigner.wizard; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPackage; +import com.intellij.uiDesigner.lw.LwRootContainer; + +/** + * @author Anton Katilin + * @author Vladimir Kondratyev + */ +public final class WizardData { + private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.WizardData"); + + /** + * Never null. + */ + public final Project myProject; + /** + * Form's file. Never null. + */ + public final VirtualFile myFormFile; + + /** + * If true then {@link #myShortClassName} and {@link #myPackageName} should be + * used, otherwise {@link #myBeanClass} should be used. + */ + public boolean myBindToNewBean; + /** + * + */ + public String myShortClassName; + /** + * + */ + public String myPackageName; + + /** + * Bean's class. If null then bean's class is't defined yet. + */ + public PsiClass myBeanClass; + /** + * Never null. + */ + public final FormProperty2BeanProperty[] myBindings; + + public boolean myGenerateIsModified; + + public WizardData(final Project project, final VirtualFile formFile) throws Generator.MyException { + LOG.assertTrue(formFile != null); + myProject = project; + myFormFile = formFile; + myBindToNewBean = true; + myGenerateIsModified = true; + + final LwRootContainer[] rootContainer = new LwRootContainer[1]; + + // Create initial bingings between form fields and bean's properties. + // TODO[vova] ask Anton to not throw exception if form-field doesn't have corresponded field in the Java class + final FormProperty[] formProperties = Generator.exposeForm(myProject, myFormFile, rootContainer); + myBindings = new FormProperty2BeanProperty[formProperties.length]; + for(int i = formProperties.length - 1; i >= 0; i--){ + myBindings[i] = new FormProperty2BeanProperty(formProperties[i]); + } + + final PsiManager manager = PsiManager.getInstance(myProject); + final VirtualFile directory = formFile.getParent(); + LOG.assertTrue(directory.isDirectory()); + final PsiDirectory psiDirectory = manager.findDirectory(directory); + LOG.assertTrue(psiDirectory != null); + final PsiPackage aPackage = psiDirectory.getPackage(); + if(aPackage != null){ + myPackageName = aPackage.getQualifiedName(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleAction.java new file mode 100644 index 00000000000..223d07de661 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleAction.java @@ -0,0 +1,21 @@ +package com.intellij.unscramble; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public final class UnscrambleAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + UnscrambleDialog dialog = new UnscrambleDialog(project); + dialog.show(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleDialog.java new file mode 100644 index 00000000000..d582b1aeebb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleDialog.java @@ -0,0 +1,356 @@ +/** + * @author cdr + */ +package com.intellij.unscramble; + +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.ExecutionRegistry; +import com.intellij.execution.impl.ConsoleViewImpl; +import com.intellij.execution.runners.JavaProgramRunner; +import com.intellij.execution.ui.*; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.GuiUtils; +import com.intellij.ui.TextFieldWithHistory; +import com.intellij.util.ArrayUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +public class UnscrambleDialog extends DialogWrapper{ + private static final String PROPERTY_LOG_FILE_HISTORY_URLS = "UNSCRAMBLE_LOG_FILE_URL"; + private static final String PROPERTY_LOG_FILE_LAST_URL = "UNSCRAMBLE_LOG_FILE_LAST_URL"; + private static final String PROPERTY_UNSCRAMBLER_NAME_USED = "UNSCRAMBLER_NAME_USED"; + + private final Project myProject; + private JPanel myEditorPanel; + private JPanel myLogFileChooserPanel; + private JComboBox myUnscrambleChooser; + private JPanel myPanel; + private Editor myEditor; + private TextFieldWithHistory myLogFile; + + public UnscrambleDialog(Project project) { + super(false); + myProject = project; + + populateRegisteredUnscramblerList(); + myUnscrambleChooser.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + UnscrambleSupport unscrambleSupport = getSelectedUnscrambler(); + GuiUtils.enableChildren(myLogFileChooserPanel, unscrambleSupport != null, null); + } + }); + createLogFileChooser(); + createEditor(); + reset(); + + setTitle("Unscramble"); + init(); + } + + private void reset() { + final List savedUrls = getSavedLogFileUrls(); + myLogFile.setHistory(savedUrls); + + String lastUrl = getLastUsedLogUrl(); + if (lastUrl == null && savedUrls.size() != 0) { + lastUrl = savedUrls.get(savedUrls.size() - 1); + } + if (lastUrl != null) { + myLogFile.setText(lastUrl); + myLogFile.setSelectedItem(lastUrl); + } + final UnscrambleSupport selectedUnscrambler = getSavedUnscrambler(); + + final int count = myUnscrambleChooser.getItemCount(); + int index = 0; + if (selectedUnscrambler != null) { + for (int i = 0; i < count; i++) { + final UnscrambleSupport unscrambleSupport = (UnscrambleSupport)myUnscrambleChooser.getItemAt(i); + if (unscrambleSupport != null && Comparing.strEqual(unscrambleSupport.getPresentableName(), selectedUnscrambler.getPresentableName())) { + index = i; + break; + } + } + } + myUnscrambleChooser.setSelectedIndex(index); + + pasteTextFromClipboard(); + } + + public static String getLastUsedLogUrl() { + String lastUrl = PropertiesComponent.getInstance().getValue(PROPERTY_LOG_FILE_LAST_URL); + return lastUrl; + } + + public static UnscrambleSupport getSavedUnscrambler() { + final List registeredUnscramblers = getRegisteredUnscramblers(); + final String savedUnscramblerName = PropertiesComponent.getInstance().getValue(PROPERTY_UNSCRAMBLER_NAME_USED); + UnscrambleSupport selectedUnscrambler = null; + for (int i = 0; i < registeredUnscramblers.size(); i++) { + final UnscrambleSupport unscrambleSupport = registeredUnscramblers.get(i); + if (Comparing.strEqual(unscrambleSupport.getPresentableName(), savedUnscramblerName)) { + selectedUnscrambler = unscrambleSupport; + } + } + return selectedUnscrambler; + } + + public static List getSavedLogFileUrls() { + final List res = new ArrayList(); + final String savedUrl = PropertiesComponent.getInstance().getValue(PROPERTY_LOG_FILE_HISTORY_URLS); + final String[] strings = savedUrl == null ? ArrayUtil.EMPTY_STRING_ARRAY : savedUrl.split(":::"); + for (int i = 0; i != strings.length; ++i) { + res.add(strings[i]); + } + return res; + } + + private void pasteTextFromClipboard() { + String text = getTextInClipboard(); + if (text != null) { + final String text1 = text; + Runnable runnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + myEditor.getDocument().insertString(0, StringUtil.convertLineSeparators(text1)); + } + }); + } + }; + CommandProcessor.getInstance().executeCommand(myProject, runnable, "", this); + } + } + + public static String getTextInClipboard() { + String text = null; + try { + Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(UnscrambleDialog.class); + if (contents != null) { + text = (String)contents.getTransferData(DataFlavor.stringFlavor); + } + } + catch (Exception ex) { + } + return text; + } + + private UnscrambleSupport getSelectedUnscrambler() { + return (UnscrambleSupport)myUnscrambleChooser.getSelectedItem(); + } + + private void createEditor() { + EditorFactory editorFactory = EditorFactory.getInstance(); + Document document = editorFactory.createDocument(""); + myEditor = editorFactory.createEditor(document); + EditorSettings settings = myEditor.getSettings(); + settings.setFoldingOutlineShown(false); + settings.setLineMarkerAreaShown(false); + settings.setLineNumbersShown(false); + settings.setRightMarginShown(false); + + EditorPanel editorPanel = new EditorPanel(myEditor); + editorPanel.setPreferredSize(new Dimension(600, 400)); + + myEditorPanel.setLayout(new BorderLayout()); + myEditorPanel.add(editorPanel, BorderLayout.CENTER); + } + + protected Action[] createActions(){ + return new Action[]{new SplitAction(), getOKAction(), getCancelAction()}; + } + + private void createLogFileChooser() { + myLogFile = new TextFieldWithHistory(); + JPanel panel = GuiUtils.constructFieldWithBrowseButton(myLogFile, new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); + VirtualFile[] files = FileChooser.chooseFiles(myLogFile, descriptor); + if (files.length != 0) { + myLogFile.setText(FileUtil.toSystemDependentName(files[files.length-1].getPath())); + } + } + }); + myLogFileChooserPanel.setLayout(new BorderLayout()); + myLogFileChooserPanel.add(panel, BorderLayout.CENTER); + } + + private void populateRegisteredUnscramblerList() { + List unscrambleComponents = getRegisteredUnscramblers(); + + myUnscrambleChooser.addItem(null); + for (int i = 0; i < unscrambleComponents.size(); i++) { + final UnscrambleSupport unscrambleSupport = unscrambleComponents.get(i); + myUnscrambleChooser.addItem(unscrambleSupport); + } + myUnscrambleChooser.setRenderer(new DefaultListCellRenderer() { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + UnscrambleSupport unscrambleSupport = (UnscrambleSupport)value; + setText(unscrambleSupport == null ? "" : unscrambleSupport.getPresentableName()); + return this; + } + }); + } + + private static List getRegisteredUnscramblers() { + List unscrambleComponents = new ArrayList(); + Class[] interfaces = ApplicationManager.getApplication().getComponentInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + final Class anInterface = interfaces[i]; + Object component = ApplicationManager.getApplication().getComponent(anInterface); + if (component instanceof UnscrambleSupport) { + unscrambleComponents.add((UnscrambleSupport)component); + } + } + return unscrambleComponents; + } + + protected JComponent createCenterPanel() { + return myPanel; + } + + public void dispose() { + EditorFactory editorFactory = EditorFactory.getInstance(); + editorFactory.releaseEditor(myEditor); + + if (isOK()){ + final List list = myLogFile.getHistory(); + String res = null; + for (int i = 0; i < list.size(); i++) { + final String s = (String)list.get(i); + if (res == null) + res = s; + else + res = res + ":::" + s; + } + PropertiesComponent.getInstance().setValue(PROPERTY_LOG_FILE_HISTORY_URLS, res); + UnscrambleSupport selectedUnscrambler = getSelectedUnscrambler(); + PropertiesComponent.getInstance().setValue(PROPERTY_UNSCRAMBLER_NAME_USED, selectedUnscrambler == null ? null : selectedUnscrambler.getPresentableName()); + + PropertiesComponent.getInstance().setValue(PROPERTY_LOG_FILE_LAST_URL, myLogFile.getText()); + } + super.dispose(); + } + + private final class SplitAction extends AbstractAction { + public SplitAction(){ + putValue(Action.NAME, "Split using 'at'"); + putValue(DEFAULT_ACTION, Boolean.FALSE); + } + + public void actionPerformed(ActionEvent e){ + String text = myEditor.getDocument().getText(); + final String newText = StringUtil.replace(text, "at ", "\nat "); + CommandProcessor.getInstance().executeCommand( + myProject, new Runnable() { + public void run(){ + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run(){ + myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), newText); + } + }); + } + }, + "", + null + ); + } + } + + private static final class EditorPanel extends JPanel implements DataProvider{ + private final Editor myEditor; + + public EditorPanel(Editor editor) { + super(new BorderLayout()); + myEditor = editor; + add(myEditor.getComponent()); + } + + public Object getData(String dataId) { + if (DataConstants.EDITOR.equals(dataId)) { + return myEditor; + } + return null; + } + } + + protected void doOKAction() { + if (performUnscramble()) { + myLogFile.addCurrentTextToHistory(); + close(OK_EXIT_CODE); + } + } + + private boolean performUnscramble() { + UnscrambleSupport selectedUnscrambler = getSelectedUnscrambler(); + return showUnscrambledText(selectedUnscrambler, myLogFile.getText(), myProject, myEditor.getDocument().getText()); + } + + static boolean showUnscrambledText(UnscrambleSupport unscrambleSupport, String logName, Project project, String textToUnscramble) { + String unscrambledTrace = unscrambleSupport == null ? textToUnscramble : unscrambleSupport.unscramble(project,textToUnscramble, logName); + if (unscrambledTrace == null) return false; + final ConsoleView consoleView = addConsole(project); + consoleView.print(unscrambledTrace, ConsoleViewContentType.ERROR_OUTPUT); + consoleView.performWhenNoDeferredOutput( + new Runnable() { + public void run() { + consoleView.scrollTo(0); + } + } + ); + return true; + } + private static ConsoleView addConsole(final Project project){ + final ConsoleView consoleView = new ConsoleViewImpl(project); + final JavaProgramRunner defaultRunner = ExecutionRegistry.getInstance().getDefaultRunner(); + final DefaultActionGroup toolbarActions = new DefaultActionGroup(); + final RunContentDescriptor descriptor = + new RunContentDescriptor(consoleView, null, new MyConsolePanel(consoleView, toolbarActions), "") { + public boolean isContentReuseProhibited() { + return true; + } + }; + toolbarActions.add(new CloseAction(defaultRunner, descriptor, project)); + ExecutionManager.getInstance(project).getContentManager().showRunContent(defaultRunner, descriptor); + return consoleView; + } + private static final class MyConsolePanel extends JPanel { + public MyConsolePanel(ExecutionConsole consoleView, ActionGroup toolbarActions) { + super(new BorderLayout()); + JPanel toolbarPanel = new JPanel(new BorderLayout()); + toolbarPanel.add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions,false).getComponent()); + add(toolbarPanel, BorderLayout.WEST); + add(consoleView.getComponent(), BorderLayout.CENTER); + } + } + protected String getDimensionServiceKey(){ + return "#com.intellij.unscramble.UnscrambleDialog"; + } + public JComponent getPreferredFocusedComponent() { + return myEditor.getContentComponent(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleFromClipboardAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleFromClipboardAction.java new file mode 100644 index 00000000000..20cd07cd4cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/unscramble/UnscrambleFromClipboardAction.java @@ -0,0 +1,40 @@ +package com.intellij.unscramble; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; + +public final class UnscrambleFromClipboardAction extends AnAction { + public void actionPerformed(AnActionEvent e) { + Project project = (Project)e.getDataContext().getData(DataConstants.PROJECT); + + // If there's a text in clipboard and log is specified or not needed, unscramble w/o extra questions + + String text = UnscrambleDialog.getTextInClipboard(); + if (text != null) { + String file = UnscrambleDialog.getLastUsedLogUrl(); + if (file != null && file.trim().length() == 0) { + file = null; + } + UnscrambleSupport savedUnscrambler = UnscrambleDialog.getSavedUnscrambler(); + if (savedUnscrambler == null || file != null) { + boolean success = UnscrambleDialog.showUnscrambledText(savedUnscrambler, file, project, text); + if (success) { + return; + } + } + } + + // Use regular unscramble dialog + UnscrambleDialog dialog = new UnscrambleDialog(project); + dialog.show(); + } + + public void update(AnActionEvent event){ + Presentation presentation = event.getPresentation(); + Project project = (Project)event.getDataContext().getData(DataConstants.PROJECT); + presentation.setEnabled(project != null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/FindUsagesCommand.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/FindUsagesCommand.java new file mode 100644 index 00000000000..fc1a64a7fb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/FindUsagesCommand.java @@ -0,0 +1,15 @@ +/** + * created at Oct 15, 2001 + * @author Jeka + */ +package com.intellij.usageView; + +import com.intellij.psi.PsiElement; + +public interface FindUsagesCommand { + /** + * elements to search should be used when refreshing since + * the origuinally searched psielement may have become invalid + */ + UsageInfo[] execute(PsiElement[] elementsToSearch); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/UsageViewUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/UsageViewUtil.java new file mode 100644 index 00000000000..7d69aee864c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/UsageViewUtil.java @@ -0,0 +1,534 @@ +package com.intellij.usageView; + +import com.intellij.ant.PsiAntElement; +import com.intellij.aspects.psi.PsiAdvice; +import com.intellij.aspects.psi.PsiPointcutDef; +import com.intellij.aspects.psi.gen.PsiErrorIntroduction; +import com.intellij.aspects.psi.gen.PsiVerificationIntroduction; +import com.intellij.aspects.psi.gen.PsiWarningIntroduction; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.search.ThrowSearchUtil; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlTag; +import gnu.trove.THashSet; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Set; + +/** + * + */ +public class UsageViewUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.usageView.UsageViewUtil"); + public static final String DEFAULT_PACKAGE_NAME = ""; + + public interface UsageViewHandler { + String getType(PsiElement element); + + String getDescriptiveName(PsiElement element); + + String getNodeText(PsiElement element, boolean useFullName); + } + + private static final HashMap usageViewHandlers = new HashMap(); + + public static String createNodeText(PsiElement element, boolean useFullName) { + if (element instanceof PsiDirectory) { + return getPackageName((PsiDirectory)element, false); + } + if (element instanceof PsiPackage) { + return getPackageName((PsiPackage)element); + } + if (element instanceof PsiFile) { + return useFullName ? ((PsiFile)element).getVirtualFile().getPresentableUrl() : ((PsiFile)element).getName(); + } + if (element instanceof PsiFile) { + return useFullName ? ((PsiFile)element).getVirtualFile().getPresentableUrl() : ((PsiFile)element).getName(); + } + if (ThrowSearchUtil.isSearchable(element)) { + return ThrowSearchUtil.getSearchableTypeName(element); + } + + if (element instanceof PsiClass) { + String name = ((PsiClass)element).getQualifiedName(); + if (name == null || !useFullName) { + name = ((PsiClass)element).getName(); + } + return name; + } + if (element instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)element; + if (useFullName) { + String s = PsiFormatUtil.formatMethod((PsiMethod)element, + PsiSubstitutor.EMPTY, PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_TYPE | + PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME); + final PsiClass psiClass = psiMethod.getContainingClass(); + if (psiClass != null) { + final String qName = psiClass.getQualifiedName(); + if (qName != null) { + s = s + " of " + (psiClass.isInterface() ? "interface " : "class ") + qName; + } + } + return s; + } + else { + return PsiFormatUtil.formatMethod(psiMethod, + PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + } + } + else if (element instanceof PsiParameter && ((PsiParameter)element).getDeclarationScope() instanceof PsiMethod) { + PsiMethod method = (PsiMethod)((PsiParameter)element).getDeclarationScope(); + String s = PsiFormatUtil.formatVariable((PsiVariable)element, + PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME, + PsiSubstitutor.EMPTY) + " of " + + PsiFormatUtil.formatMethod(method, + PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + + final PsiClass psiClass = method.getContainingClass(); + if (psiClass != null && psiClass.getQualifiedName() != null) { + s += " of " + (psiClass.isInterface() ? "interface " : "class ") + psiClass.getQualifiedName(); + } + return s; + } + else if (element instanceof PsiPointcutDef) { + final PsiPointcutDef psiPointcutDef = (PsiPointcutDef)element; + String s; + if (useFullName) { + s = PsiFormatUtil.formatPointcut(psiPointcutDef, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME); + PsiClass psiAspect = psiPointcutDef.getContainingClass(); + if (psiAspect != null) { + String qName = psiAspect.getQualifiedName(); + if (qName != null) { + s = s + " of aspect " + qName; + } + } + } + else { + s = PsiFormatUtil.formatPointcut(psiPointcutDef, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, PsiFormatUtil.SHOW_TYPE); + } + return s; + } + else if (element instanceof PsiField) { + PsiField psiField = (PsiField)element; + String s = PsiFormatUtil.formatVariable(psiField, + PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME, + PsiSubstitutor.EMPTY); + PsiClass psiClass = psiField.getContainingClass(); + if (psiClass != null) { + String qName = psiClass.getQualifiedName(); + if (qName != null) { + s = s + " of " + (psiClass.isInterface() ? "interface " : "class ") + qName; + } + } + return s; + } + else if (element instanceof PsiVariable) { + return PsiFormatUtil.formatVariable((PsiVariable)element, + PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME, + PsiSubstitutor.EMPTY); + } + else if (element instanceof XmlTag) { + final XmlTag xmlTag = (XmlTag)element; + return "<" + xmlTag.getName() + "> of file " + xmlTag.getContainingFile().getName(); + } + else if (element instanceof XmlAttributeValue) { + return ((XmlAttributeValue)element).getValue(); + } + else if (element != null) { + PsiFile containingFile = element.getContainingFile(); + UsageViewHandler handler = (containingFile != null) ? usageViewHandlers.get(containingFile.getFileType()) : null; + if (handler != null) { + return handler.getNodeText(element, useFullName); + } + } + + return ""; + } + + public static void registerUsageViewHandler(FileType fileType, UsageViewHandler handler) { + usageViewHandlers.put(fileType, handler); + } + + public static String getPackageName(PsiDirectory directory, boolean includeRootDir) { + PsiPackage aPackage = directory.getPackage(); + if (aPackage == null) { + return directory.getVirtualFile().getPresentableUrl(); + } + else { + String packageName = getPackageName(aPackage); + if (includeRootDir) { + String rootDir = getRootDirectoryForPackage(directory); + if (rootDir != null) { + return packageName + " (in " + rootDir + ")"; + } + } + return packageName; + } + } + + public static String getRootDirectoryForPackage(PsiDirectory directory) { + PsiManager manager = directory.getManager(); + final VirtualFile virtualFile = directory.getVirtualFile(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(manager.getProject()).getFileIndex(); + VirtualFile root = fileIndex.getSourceRootForFile(virtualFile); + + if (root == null) { + root = fileIndex.getClassRootForFile(virtualFile); + } + if (root != null) { + return root.getPresentableUrl(); + } + else { + return null; + } + } + + private static String getPackageName(PsiPackage psiPackage) { + if (psiPackage == null) { + return null; + } + String name = psiPackage.getQualifiedName(); + if (name.length() > 0) { + return name; + } + else { + return DEFAULT_PACKAGE_NAME; + } + } + + public static String capitalize(String s) { + if (s == null || s.length() == 0) { + return s; + } + char c = Character.toUpperCase(s.charAt(0)); + if (s.length() == 1) { + return "" + c; + } + else { + return "" + c + s.substring(1); + } + } + + public static String getShortName(final PsiElement psiElement) { + LOG.assertTrue(psiElement.isValid()); + String ret = ""; + if (psiElement instanceof PsiNamedElement) { + ret = ((PsiNamedElement)psiElement).getName(); + } + else if (psiElement instanceof PsiThrowStatement) { + ret = "Exception"; + } + else if (psiElement instanceof XmlAttributeValue) { + ret = ((XmlAttributeValue)psiElement).getValue(); + } + else if (psiElement instanceof PsiVerificationIntroduction) { + PsiLiteralExpression message = ((PsiVerificationIntroduction)psiElement).getMessage(); + ret = message == null ? "" : (String)message.getValue(); + } + else if (psiElement instanceof PsiAdvice) { + ret = ((PsiAdvice)psiElement).getPointcut().getText(); + } + return ret; + } + + public static String getLongName(final PsiElement psiElement) { + LOG.assertTrue(psiElement.isValid()); + String ret; + if (psiElement instanceof PsiDirectory) { + PsiPackage aPackage = ((PsiDirectory)psiElement).getPackage(); + if (aPackage != null) { + ret = aPackage.getQualifiedName(); + } + else { + ret = ((PsiDirectory)psiElement).getVirtualFile().getPresentableUrl(); + } + } + else if (psiElement instanceof PsiPackage) { + ret = ((PsiPackage)psiElement).getQualifiedName(); + } + else if (psiElement instanceof PsiClass) { + if (psiElement instanceof PsiAnonymousClass) { + ret = "anonymous class"; + } + else { + ret = ((PsiClass)psiElement).getQualifiedName(); // It happens for local classes + if (ret == null) { + ret = ((PsiClass)psiElement).getName(); + } + } + } + else if (psiElement instanceof PsiVariable) { + ret = ((PsiVariable)psiElement).getName(); + } + else if (psiElement instanceof XmlTag) { + ret = ((XmlTag)psiElement).getName(); + } + else if (psiElement instanceof XmlAttributeValue) { + ret = ((XmlAttributeValue)psiElement).getValue(); + } + else if (psiElement instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)psiElement; + ret = + PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, PsiFormatUtil.SHOW_TYPE); + } + else if (psiElement instanceof PsiPointcutDef) { + PsiPointcutDef pointcutDef = (PsiPointcutDef)psiElement; + ret = + PsiFormatUtil.formatPointcut(pointcutDef, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + } + else if (psiElement instanceof PsiVerificationIntroduction) { + PsiErrorIntroduction introduction = (PsiErrorIntroduction)psiElement; + PsiLiteralExpression message = introduction.getMessage(); + ret = message == null ? "" : (String)message.getValue(); + } + else if (psiElement instanceof PsiAdvice) { + ret = ((PsiAdvice)psiElement).getPointcut().getText(); + } + else { + ret = ""; + } + return ret; + } + + public static String getType(PsiElement psiElement) { + if (psiElement instanceof PsiDirectory) { + return "directory"; + } + if (psiElement instanceof PsiFile) { + return "file"; + } + if (ThrowSearchUtil.isSearchable(psiElement)) { + return "exception"; + } + if (psiElement instanceof PsiPackage) { + return "package"; + } + if (psiElement instanceof PsiClass) { + if (((PsiClass)psiElement).isAnnotationType()) { + return "@interface"; + } + else if (((PsiClass)psiElement).isInterface()) { + return "interface"; + } + return "class"; + } + if (psiElement instanceof PsiField) { + return "field"; + } + if (psiElement instanceof PsiParameter) { + return "parameter"; + } + if (psiElement instanceof PsiLocalVariable) { + return "variable"; + } + if (psiElement instanceof XmlTag) { + return "XML tag"; + } + if (psiElement instanceof PsiMethod) { + final PsiMethod psiMethod = (PsiMethod)psiElement; + final boolean isConstructor = psiMethod.isConstructor(); + if (isConstructor) { + return "constructor"; + } + else { + return "method"; + } + } + if (psiElement instanceof PsiPointcutDef) { + return "pointcut"; + } + if (psiElement instanceof PsiErrorIntroduction) { + return "error declaration"; + } + if (psiElement instanceof PsiWarningIntroduction) { + return "warning declaration"; + } + if (psiElement instanceof PsiAdvice) { + return "advice"; + } + if (psiElement instanceof PsiLabeledStatement) { + return "label"; + } + if (psiElement instanceof PsiAntElement) { + return ((PsiAntElement)psiElement).getRole().getName(); + } + + PsiFile containingFile = psiElement.getContainingFile(); + UsageViewHandler handler = (containingFile!=null)?usageViewHandlers.get(containingFile.getFileType()):null; + if (handler != null) { + return handler.getType(psiElement); + } + + return ""; + } + + public static String getDescriptiveName(final PsiElement psiElement) { + LOG.assertTrue(psiElement.isValid()); + String ret = ""; + if (ThrowSearchUtil.isSearchable(psiElement)) { + ret = ThrowSearchUtil.getSearchableTypeName(psiElement); + } + if (psiElement instanceof PsiDirectory) { + ret = getPackageName((PsiDirectory)psiElement, false); + } + else if (psiElement instanceof PsiPackage) { + ret = getPackageName((PsiPackage)psiElement); + } + else if (psiElement instanceof PsiFile) { + ret = ((PsiFile)psiElement).getVirtualFile().getPresentableUrl(); + } + else if (psiElement instanceof PsiClass) { + if (psiElement instanceof PsiAnonymousClass) { + ret = "anonymous class"; + } + else { + ret = ((PsiClass)psiElement).getQualifiedName(); + if (ret == null) { + ret = ((PsiClass)psiElement).getName(); + } + } + } + else if (psiElement instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)psiElement; + ret = PsiFormatUtil.formatMethod(psiMethod, + PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + PsiClass psiClass = psiMethod.getContainingClass(); + if (psiClass != null) { + if (psiClass instanceof PsiAnonymousClass) { + ret = ret + " of anonymous class"; + } + else { + String className = psiClass.getName(); + if (!psiClass.isInterface()) { + ret = ret + " of class " + className; + } + else if (psiClass.isInterface()) { + ret = ret + " of interface " + className; + } + } + } + } + else if (psiElement instanceof PsiField) { + PsiField psiField = (PsiField)psiElement; + ret = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME, PsiSubstitutor.EMPTY); + PsiClass psiClass = psiField.getContainingClass(); + if (psiClass != null) { + if (psiClass instanceof PsiAnonymousClass) { + ret = ret + " of anonymous class"; + } + else { + String className = psiClass.getName(); + if (!psiClass.isInterface()) { + ret = ret + " of class " + className; + } + else if (psiClass.isInterface()) { + ret = ret + " of interface " + className; + } + } + } + } + else if (psiElement instanceof PsiVariable) { + PsiVariable psiVariable = (PsiVariable)psiElement; + ret = PsiFormatUtil.formatVariable(psiVariable, PsiFormatUtil.SHOW_NAME, PsiSubstitutor.EMPTY); + } + else if (psiElement instanceof PsiPointcutDef) { + PsiPointcutDef psiPointcut = (PsiPointcutDef)psiElement; + ret = PsiFormatUtil.formatPointcut(psiPointcut, + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + PsiClass psiClass = psiPointcut.getContainingClass(); + if (psiClass != null) { + ret = ret + " of aspect " + psiClass.getName(); + } + } + else if (psiElement instanceof PsiErrorIntroduction) { + PsiErrorIntroduction introduction = (PsiErrorIntroduction)psiElement; + PsiLiteralExpression message = introduction.getMessage(); + ret = "error \"" + (message == null ? "" : message.getValue()) + "\""; + PsiFile psiFile = introduction.getContainingFile(); + if (psiFile != null) { + ret = ret + " in file " + psiFile.getName(); + } + } + else if (psiElement instanceof PsiWarningIntroduction) { + PsiWarningIntroduction introduction = (PsiWarningIntroduction)psiElement; + PsiLiteralExpression message = introduction.getMessage(); + ret = "warning \"" + (message == null ? "" : message.getValue()) + "\""; + PsiFile psiFile = introduction.getContainingFile(); + if (psiFile != null) { + ret = ret + " in file " + psiFile.getName(); + } + } + else if (psiElement instanceof XmlTag) { + ret = ((XmlTag)psiElement).getName(); + } + else if (psiElement instanceof XmlAttributeValue) { + ret = ((XmlAttributeValue)psiElement).getValue(); + } + else if (psiElement instanceof PsiLabeledStatement) { + ret = ((PsiLabeledStatement)psiElement).getName(); + } + else { + PsiFile containingFile = psiElement.getContainingFile(); + UsageViewHandler handler = (containingFile != null) ? usageViewHandlers.get(containingFile.getFileType()) : null; + if (handler != null) { + return handler.getDescriptiveName(psiElement); + } + } + + return ret; + } + + public static String getUsageCountInfo(int usagesCount, int filesCount, String referenceWord) { + String info; + if (filesCount > 0) { + String files = filesCount != 1 ? " files " : " file "; + if (usagesCount > 1) { + referenceWord += "s"; + } + info = "( " + usagesCount + " " + referenceWord + " in " + filesCount + files + ")"; + } + else { + info = "( Not found )"; + } + return info; + } + + public static boolean hasNonCodeUsages(UsageInfo[] usages) { + for (int i = 0; i < usages.length; i++) { + if (usages[i].isNonCodeUsage) return true; + } + return false; + } + + public static boolean hasReadOnlyUsages(UsageInfo[] usages) { + for (int i = 0; i < usages.length; i++) { + UsageInfo usage = usages[i]; + if (!usage.isWritable()) return true; + } + return false; + } + + public static UsageInfo[] removeDuplicatedUsages(UsageInfo usages[]) { + Set set = new THashSet(Arrays.asList(usages)); + return set.toArray(new UsageInfo[set.size()]); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/SelectInEditorHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/SelectInEditorHandler.java new file mode 100644 index 00000000000..41833b2c208 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/SelectInEditorHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.usageView.impl; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; + +import javax.swing.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * @author dyoma + */ +public class SelectInEditorHandler { + public static void installKeyListener(final JComponent component, final Project project) { + component.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) selectInEditor(component, project); + } + }); + } + + public static void selectInEditor(final JComponent component, final Project project) { + final Navigatable navigatable = (Navigatable)DataManager.getInstance().getDataContext(component).getData(DataConstants.NAVIGATABLE); + + if (navigatable != null) { + navigatable.navigate(false); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/UsageViewManagerImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/UsageViewManagerImpl.java new file mode 100644 index 00000000000..e9e4b6458f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/usageView/impl/UsageViewManagerImpl.java @@ -0,0 +1,176 @@ +package com.intellij.usageView.impl; + +import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.ui.content.*; +import com.intellij.usageView.ProgressFactory; +import com.intellij.usageView.UsageView; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewManager; + +import javax.swing.*; +import java.awt.*; + +public class UsageViewManagerImpl extends UsageViewManager implements ProjectComponent { + private final Key REUSABLE_CONTENT_KEY = Key.create("UsageTreeManager.REUSABLE_CONTENT_KEY"); + private final Key NOT_REUSABLE_CONTENT_KEY = Key.create("UsageTreeManager.NOT_REUSABLE_CONTENT_KEY"); //todo[myakovlev] dont use it + /** + * @deprecated + */ + private final Key USAGE_VIEW_KEY = Key.create("UsageTreeManager.USAGE_VIEW_KEY"); + private final Key NEW_USAGE_VIEW_KEY = Key.create("NEW_USAGE_VIEW_KEY"); + private final Project myProject; + private ContentManager myFindContentManager; + + public UsageViewManagerImpl(Project project) { + myProject = project; + } + + public void disposeComponent() { + } + + public void initComponent() { + } + + public void projectOpened() { + myFindContentManager = PeerFactory.getInstance().getContentFactory().createContentManager(new TabbedPaneContentUI(), true, myProject); + myFindContentManager.addContentManagerListener(new ContentManagerAdapter() { + public void contentRemoved(ContentManagerEvent event) { + event.getContent().release(); + } + }); + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.FIND, myFindContentManager.getComponent(), ToolWindowAnchor.BOTTOM); + toolWindow.setIcon(IconLoader.getIcon("/general/toolWindowFind.png")); + new ContentManagerWatcher(toolWindow, myFindContentManager); + } + + public void projectClosed() { + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.FIND); + myFindContentManager = null; + } + + public UsageView addContent(String contentName, + UsageViewDescriptor viewDescriptor, + boolean isReusable, + boolean isShowReadAccessIcon, + boolean isShowWriteAccessIcon, + boolean isOpenInNewTab, + boolean isLockable) { + UsageViewImpl usageView = new UsageViewImpl(myProject, viewDescriptor, isShowReadAccessIcon, isShowWriteAccessIcon, true); + addContent(contentName, isReusable, usageView, isOpenInNewTab, isLockable); + return usageView; + } + + public UsageView addContent(String contentName, + UsageViewDescriptor viewDescriptor, + boolean isReusable, + boolean isOpenInNewTab, + boolean isLockable, + ProgressFactory progressFactory) { + UsageViewImpl usageView = new UsageViewImpl(myProject, viewDescriptor, progressFactory); + addContent(contentName, isReusable, usageView, isOpenInNewTab, isLockable); + return usageView; + } + + private UsageView addContent(String contentName, boolean reusable, final UsageView usageView, boolean toOpenInNewTab, boolean isLockable) { + Content content = addContent(contentName, reusable, usageView.getComponent(), toOpenInNewTab, isLockable); + + content.setDisposer(usageView); + content.putUserData(USAGE_VIEW_KEY, usageView); + + return usageView; + } + + public Content addContent(String contentName, boolean reusable, final JComponent component, boolean toOpenInNewTab, boolean isLockable) { + Key contentKey = reusable ? REUSABLE_CONTENT_KEY : NOT_REUSABLE_CONTENT_KEY; + + if ((!toOpenInNewTab) && reusable) { + Content[] contents = myFindContentManager.getContents(); + Content contentToDelete = null; + + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + + if (!content.isPinned() && + content.getUserData(contentKey) != null + ) { + UsageView usageView = content.getUserData(USAGE_VIEW_KEY); + if (usageView == null || !usageView.isInAsyncUpdate()) { + contentToDelete = content; + } + } + } + if (contentToDelete != null) { + myFindContentManager.removeContent(contentToDelete); + } + } + Content content = PeerFactory.getInstance().getContentFactory().createContent(component, contentName, isLockable); + content.putUserData(contentKey, Boolean.TRUE); + + myFindContentManager.addContent(content); + myFindContentManager.setSelectedContent(content); + + return content; + } + + public int getReusableContentsCount() { + return getContentCount(true); + } + + private int getContentCount(boolean reusable) { + Key contentKey = reusable ? REUSABLE_CONTENT_KEY : NOT_REUSABLE_CONTENT_KEY; + int count = 0; + Content[] contents = myFindContentManager.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (content.getUserData(contentKey) != null) { + count++; + } + } + return count; + } + + public Content getSelectedContent(boolean reusable) { + Key contentKey = reusable ? REUSABLE_CONTENT_KEY : NOT_REUSABLE_CONTENT_KEY; + Content selectedContent = myFindContentManager.getSelectedContent(); + return selectedContent == null || selectedContent.getUserData(contentKey) == null ? null : selectedContent; + } + + public UsageView getSelectedUsageView() { + Content selectedContent = myFindContentManager.getSelectedContent(); + return selectedContent == null ? null: selectedContent.getUserData(USAGE_VIEW_KEY); + } + + public void closeContent(UsageView usageView) { + if (myFindContentManager == null) { + return; + } + Content[] contents = myFindContentManager.getContents(); + Component component = usageView.getComponent(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (component == content.getComponent()) { + closeContent(content); + return; + } + } + } + + public void closeContent(Content content) { + myFindContentManager.removeContent(content); + content.release(); + } + + public String getComponentName() { + return "UsageViewManager"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ActionRunner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ActionRunner.java new file mode 100644 index 00000000000..2ccac661603 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ActionRunner.java @@ -0,0 +1,107 @@ +/** + * @author cdr + */ +package com.intellij.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.util.Computable; + +import javax.swing.*; + + +public abstract class ActionRunner { + public static void runInsideWriteAction(final InterruptibleRunnable runnable) throws Exception { + final Exception[] exception = new Exception[1]; + Runnable swingRunnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + runnable.run(); + } + catch (Exception e) { + exception[0] = e; + } + } + }); + } + }; + if (SwingUtilities.isEventDispatchThread()) { + swingRunnable.run(); + } + else { + ApplicationManager.getApplication().invokeAndWait(swingRunnable, ModalityState.NON_MMODAL); + } + Exception e = exception[0]; + if (e != null) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + throw new Exception(e); + } + } + //public static void runInsideWriteAction(final InterruptibleRunnable runnable) throws E { + // runInsideWriteAction(new InterruptibleRunnableWithResult(){ + // public Object run() throws E { + // runnable.run(); + // return null; + // } + // }); + //} + public static T runInsideWriteAction(final InterruptibleRunnableWithResult runnable) throws Exception { + final Throwable[] exception = new Throwable[]{null}; + final T[] result = (T[])new Object[1]; + Runnable swingRunnable = new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + result[0] = runnable.run(); + } + catch (Exception e) { + exception[0] = e; + } + } + }); + } + }; + if (SwingUtilities.isEventDispatchThread()) { + swingRunnable.run(); + } + else { + ApplicationManager.getApplication().invokeAndWait(swingRunnable, ModalityState.NON_MMODAL); + } + Throwable e = exception[0]; + if (e != null) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + throw new Exception(e); + } + return result[0]; + } + + public static void runInsideReadAction(final InterruptibleRunnable runnable) throws Exception { + Throwable exception = ApplicationManager.getApplication().runReadAction(new Computable() { + public Throwable compute() { + try { + runnable.run(); + return null; + } + catch (Throwable e) { + return e; + } + } + }); + if (exception != null) { + if (exception instanceof RuntimeException) { + throw (RuntimeException)exception; + } + throw new Exception(exception); + } + } + + public static interface InterruptibleRunnable { + void run() throws Exception; + } + public static interface InterruptibleRunnableWithResult { + T run() throws Exception; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/EditorPopupHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/EditorPopupHandler.java new file mode 100644 index 00000000000..5b18f667b57 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/EditorPopupHandler.java @@ -0,0 +1,28 @@ +package com.intellij.util; + +import com.intellij.openapi.editor.event.EditorMouseAdapter; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.editor.event.EditorMouseEventArea; + +public abstract class EditorPopupHandler extends EditorMouseAdapter { + public abstract void invokePopup(EditorMouseEvent event); + + private void handle(EditorMouseEvent e) { + if (e.getMouseEvent().isPopupTrigger() && e.getArea() == EditorMouseEventArea.EDITING_AREA) { + invokePopup(e); + e.consume(); + } + } + + public void mouseClicked(EditorMouseEvent e) { + handle(e); + } + + public void mousePressed(EditorMouseEvent e) { + handle(e); + } + + public void mouseReleased(EditorMouseEvent e) { + handle(e); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/IJSwingUtilities.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/IJSwingUtilities.java new file mode 100644 index 00000000000..3060f0b9804 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/IJSwingUtilities.java @@ -0,0 +1,160 @@ +package com.intellij.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FilteringIterator; +import gnu.trove.TIntStack; + +import javax.swing.*; +import java.awt.*; +import java.util.Iterator; + +public class IJSwingUtilities { + public static void invoke(Runnable runnable) { + if (ApplicationManager.getApplication().isDispatchThread()) { + runnable.run(); + } else { + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MMODAL); + } + } + + /** + * @return true if javax.swing.SwingUtilities.findFocusOwner(component) != null + */ + public static boolean hasFocus(Component component) { + Component focusOwner = findFocusOwner(component); + return focusOwner != null; + } + + private static Component findFocusOwner(Component c) { + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + + // verify focusOwner is a descendant of c + for (Component temp = focusOwner; temp != null; temp = (temp instanceof Window) ? null : temp.getParent()) + { + if (temp == c) { + return focusOwner; + } + } + + return null; + } + + /** + * @return true if window ancestor of component was most recent focused window and most recent focused component + * in that window was descended from component + */ + public static boolean hasFocus2(Component component) { + WindowManagerEx windowManager = WindowManagerEx.getInstanceEx(); + Window activeWindow=null; + if (windowManager != null) { + activeWindow = windowManager.getMostRecentFocusedWindow(); + } + if(activeWindow==null){ + return false; + } + Component focusedComponent = windowManager.getFocusedComponent(activeWindow); + if (focusedComponent == null) { + return false; + } + + return SwingUtilities.isDescendingFrom(focusedComponent, component); + } + + /** + * This method is copied from SwingUtilities. + * Returns index of the first occurrence of mnemonic + * within string text. Matching algorithm is not + * case-sensitive. + * + * @param text The text to search through, may be null + * @param mnemonic The mnemonic to find the character for. + * @return index into the string if exists, otherwise -1 + */ + public static int findDisplayedMnemonicIndex(String text, int mnemonic) { + if (text == null || mnemonic == '\0') { + return -1; + } + + char uc = Character.toUpperCase((char)mnemonic); + char lc = Character.toLowerCase((char)mnemonic); + + int uci = text.indexOf(uc); + int lci = text.indexOf(lc); + + if (uci == -1) { + return lci; + } else if(lci == -1) { + return uci; + } else { + return (lci < uci) ? lci : uci; + } + } + + public static Iterator getParents(final Component component) { + return new Iterator() { + private Component myCurrent = component; + public boolean hasNext() { + return myCurrent != null && myCurrent.getParent() != null; + } + + public Component next() { + myCurrent = myCurrent.getParent(); + return myCurrent; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * @param component - parent component, won't be reached by iterator. + * @return Component tree traverse {@link Iterator}. + */ + public static Iterator getChildren(final Container component) { + return new Iterator() { + private Container myCurrentParent = component; + private final TIntStack myState = new TIntStack(); + private int myCurrentIndex = 0; + + public boolean hasNext() { + return hasNextChild(); + } + + public Component next() { + Component next = myCurrentParent.getComponent(myCurrentIndex); + myCurrentIndex++; + if (next instanceof Container) { + Container container = ((Container)next); + if (container.getComponentCount() > 0) { + myState.push(myCurrentIndex); + myCurrentIndex = 0; + myCurrentParent = container; + } + } + while (!hasNextChild()) { + if (myState.size() == 0) break; + myCurrentIndex = myState.pop(); + myCurrentParent = myCurrentParent.getParent(); + } + return next; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + private boolean hasNextChild() { + return myCurrentParent.getComponentCount() > myCurrentIndex; + } + }; + } + + public static T findParentOfType(Component focusOwner, Class aClass) { + return (T)ContainerUtil.find(getParents(focusOwner), (FilteringIterator.InstanceOf)FilteringIterator.instanceOf(aClass)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledInputStream.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledInputStream.java new file mode 100644 index 00000000000..42497e9c2c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledInputStream.java @@ -0,0 +1,51 @@ +package com.intellij.util; + +import java.io.InputStream; +import java.io.IOException; + +public class ScrambledInputStream extends InputStream{ + private static final int MASK = ScrambledOutputStream.MASK; + private InputStream myOriginalStream; + + public ScrambledInputStream(InputStream originalStream) { + myOriginalStream = originalStream; + } + + public int read() throws IOException { + int b = myOriginalStream.read(); + if (b == -1) return -1; + return b ^ MASK; + } + + public int read(byte[] b, int off, int len) throws IOException { + int read = myOriginalStream.read(b, off, len); + for(int i = 0; i < read; i++){ + b[off + i] ^= MASK; + } + return read; + } + + public long skip(long n) throws IOException { + return myOriginalStream.skip(n); + } + + public int available() throws IOException { + return myOriginalStream.available(); + } + + public void close() throws IOException { + myOriginalStream.close(); + } + + public synchronized void mark(int readlimit) { + myOriginalStream.mark(readlimit); + } + + public synchronized void reset() throws IOException { + myOriginalStream.reset(); + } + + public boolean markSupported() { + return myOriginalStream.markSupported(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledOutputStream.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledOutputStream.java new file mode 100644 index 00000000000..90e1fba30fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ScrambledOutputStream.java @@ -0,0 +1,34 @@ +package com.intellij.util; + +import java.io.OutputStream; +import java.io.IOException; + +public class ScrambledOutputStream extends OutputStream{ + static final int MASK = 0xAA; + private OutputStream myOriginalStream; + + public ScrambledOutputStream(OutputStream originalStream) { + myOriginalStream = originalStream; + } + + public void write(int b) throws IOException { + myOriginalStream.write(b ^ MASK); + } + + public void write(byte[] b, int off, int len) throws IOException { + byte[] newBytes = new byte[len]; + for(int i = 0; i < len; i++) { + newBytes[i] = (byte)(b[off + i] ^ MASK); + } + myOriginalStream.write(newBytes, 0, len); + } + + public void flush() throws IOException { + myOriginalStream.flush(); + } + + public void close() throws IOException { + myOriginalStream.close(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/AbstractProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/AbstractProperty.java new file mode 100644 index 00000000000..871fc7a5be9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/AbstractProperty.java @@ -0,0 +1,80 @@ +package com.intellij.util.config; + +import com.intellij.openapi.util.Comparing; + +import java.util.Comparator; + +public abstract class AbstractProperty { + public static final Comparator NAME_COMPARATOR = new Comparator() { + public int compare(AbstractProperty property, AbstractProperty property1) { + return property.getName().compareTo(property1.getName()); + } + }; + + public abstract String getName(); + public abstract T getDefault(AbstractPropertyContainer container); + public abstract T copy(T value); + + public boolean areEqual(T value1, T value2) { + return Comparing.equal(value1, value2); + } + + public T get(AbstractPropertyContainer container) { return (T) container.getValueOf(this); } + public void set(AbstractPropertyContainer container, T value) { container.setValueOf(this, value); } + public final T cast(Object value) { return (T) value; } + + public String toString() { + return getName(); + } + + public static abstract class AbstractPropertyContainer { + public static final AbstractPropertyContainer EMPTY = new AbstractPropertyContainer() { + public Object getValueOf(AbstractProperty property) { + return property.getDefault(this); + } + + public void setValueOf(AbstractProperty property, Object value) { + throw new UnsupportedOperationException("Property: " + property.getName() + " value: " + value); + } + + public boolean hasProperty(AbstractProperty property) { + return false; + } + }; + + protected abstract Object getValueOf(PropertyImpl property); + protected abstract void setValueOf(PropertyImpl property, Object value); + public abstract boolean hasProperty(AbstractProperty property); + + /** + * Only containers can delegate to another. + * Other clients should use {@link AbstractProperty#set AbstractProperty.set} + */ + protected final void delegateSet(AbstractPropertyContainer container, AbstractProperty property, T value) { + container.setValueOf(property, value); + } + + /** + * Only containers can delegate to another. + * Other clients should use {@link AbstractProperty#get AbstractProperty.get} + */ + protected final T delegateGet(AbstractPropertyContainer container, AbstractProperty property) { + return (T)container.getValueOf(property); + } + + public final void copyFrom(AbstractPropertyContainer source, AbstractProperty[] properties) { + for (int i = 0; i < properties.length; i++) { + AbstractProperty property = properties[i]; + setValueOf((PropertyImpl)property, source.getValueOf(property)); + } + } + + public final boolean areValueEqual(AbstractPropertyContainer other, AbstractProperty[] properties) { + for (int i = 0; i < properties.length; i++) { + AbstractProperty property = properties[i]; + if (!property.areEqual(getValueOf((PropertyImpl)property), other.getValueOf(property))) return false; + } + return true; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/BooleanProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/BooleanProperty.java new file mode 100644 index 00000000000..16c7a7b8917 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/BooleanProperty.java @@ -0,0 +1,15 @@ +package com.intellij.util.config; + +public class BooleanProperty extends ValueProperty { + public BooleanProperty(String name, boolean defaultValue) { + super(name, Boolean.valueOf(defaultValue)); + } + + public boolean value(AbstractPropertyContainer container) { + return get(container).booleanValue(); + } + + public void primSet(AbstractPropertyContainer container, boolean value) { + set(container, Boolean.valueOf(value)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ExternalizablePropertyContainer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ExternalizablePropertyContainer.java new file mode 100644 index 00000000000..5b107e2c4f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ExternalizablePropertyContainer.java @@ -0,0 +1,145 @@ +package com.intellij.util.config; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.*; + +public class ExternalizablePropertyContainer + extends AbstractProperty.AbstractPropertyContainer + implements JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.config.ExternalizablePropertyContainer"); + private final Map myValues = new HashMap(); + private final Map myExternalizers = new HashMap(); + + public void registerProperty(AbstractProperty property, Externalizer externalizer) { + String name = property.getName(); + LOG.assertTrue(!myExternalizers.containsKey(property), name); + myExternalizers.put(property, externalizer); + } + + public void rememberKey(AbstractProperty property) { + LOG.assertTrue(myExternalizers.get(property) == null, property.getName()); + myExternalizers.put(property, null); + } + + public void registerProperty(BooleanProperty property) { + registerProperty(property, Externalizer.BOOLEAN); + } + + public void registerProperty(StringProperty property) { + registerProperty(property, Externalizer.STRING); + } + + public void registerProperty(IntProperty property) { + registerProperty(property, Externalizer.INTEGER); + } + + public void registerProperty(StorageProperty property) { + registerProperty(property, Externalizer.STORAGE); + } + + public void registerProperty(ListProperty property, String itemTagName, Externalizer itemExternalizer) { + registerProperty(property, createListExternalizer(itemExternalizer, itemTagName)); + } + + /** + * @deprecated + */ + public void registerProperty(ListProperty property, String itemTagName, Factory factory) { + registerProperty(property, itemTagName, Externalizer.FactoryBased.create(factory)); + } + + private Externalizer> createListExternalizer(final Externalizer itemExternalizer, final String itemTagName) { + return new ListExternalizer(itemExternalizer, itemTagName); + } + + public void readExternal(Element element) throws InvalidDataException { + HashMap propertyByName = new HashMap(); + for (Iterator iterator = myExternalizers.keySet().iterator(); iterator.hasNext();) { + AbstractProperty abstractProperty = iterator.next(); + propertyByName.put(abstractProperty.getName(), abstractProperty); + } + List children = element.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element child = iterator.next(); + AbstractProperty property = propertyByName.get(child.getName()); + if (property == null) continue; + Externalizer externalizer = myExternalizers.get(property); + if (externalizer == null) continue; + myValues.put(property, externalizer.readValue(child)); + } + } + + public void writeExternal(Element element) throws WriteExternalException { + List properties = new ArrayList(myExternalizers.keySet()); + Collections.sort(properties, AbstractProperty.NAME_COMPARATOR); + for (Iterator iterator = properties.iterator(); iterator.hasNext();) { + AbstractProperty property = iterator.next(); + Externalizer externalizer = myExternalizers.get(property); + if (externalizer == null) continue; + Element child = new Element(property.getName()); + externalizer.writeValue(child, getValueOf(property)); + element.addContent(child); + } + } + + protected Object getValueOf(AbstractProperty property) { + Object value = myValues.get(property); + return value != null ? value : property.getDefault(this); + } + + protected void setValueOf(AbstractProperty externalizableProperty, Object value) { + myValues.put(externalizableProperty, value); + } + + public boolean hasProperty(AbstractProperty property) { + return myExternalizers.containsKey(property); + } + + private class ListExternalizer implements Externalizer> { + private static final String NULL_ELEMENT = "NULL_VALUE_ELEMENT"; + private final Externalizer myItemExternalizer; + private final String myItemTagName; + + public ListExternalizer(Externalizer itemExternalizer, String itemTagName) { + myItemExternalizer = itemExternalizer; + myItemTagName = itemTagName; + } + + public List readValue(Element dataElement) throws InvalidDataException { + ArrayList list = new ArrayList(); + List children = dataElement.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element element = iterator.next(); + if (NULL_ELEMENT.equals(element.getName())) list.add(null); + else if (myItemTagName.equals(element.getName())) { + T item = myItemExternalizer.readValue(element); + if (item == null) { + LOG.error("Can't create element " + myItemExternalizer); + return list; + } + list.add(item); + } + } + return list; + } + + public void writeValue(Element dataElement, List value) throws WriteExternalException { + for (Iterator iterator = value.iterator(); iterator.hasNext();) { + T item = iterator.next(); + if (item != null) { + Element element = new Element(myItemTagName); + myItemExternalizer.writeValue(element, item); + dataElement.addContent(element); + } + else dataElement.addContent(new Element(NULL_ELEMENT)); + } + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/Externalizer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/Externalizer.java new file mode 100644 index 00000000000..b66eb852024 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/Externalizer.java @@ -0,0 +1,95 @@ +package com.intellij.util.config; + +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; + +import java.util.Iterator; +import java.util.List; + +public interface Externalizer { + String VALUE_ATTRIBUTE = "value"; + Externalizer STRING = new BaseExternalizer(){ + public String readValue(Element dataElement) { + return dataElement.getAttributeValue(VALUE_ATTRIBUTE); + } + }; + Externalizer INTEGER = new BaseExternalizer() { + public Integer readValue(Element dataElement) { + try { + return new Integer(dataElement.getAttributeValue(VALUE_ATTRIBUTE)); + } catch(NumberFormatException e) { + return null; + } + } + }; + Externalizer STORAGE = new StorageExternalizer(); + + abstract class BaseExternalizer implements Externalizer { + + public void writeValue(Element dataElement, T value) { + dataElement.setAttribute(VALUE_ATTRIBUTE, value.toString()); + } + } + Externalizer BOOLEAN = new BaseExternalizer() { + public Boolean readValue(Element dataElement) { + return Boolean.valueOf(dataElement.getAttributeValue(VALUE_ATTRIBUTE)); + } + }; + + T readValue(Element dataElement) throws InvalidDataException; + + void writeValue(Element dataElement, T value) throws WriteExternalException; + + class FactoryBased implements Externalizer { + private final Factory myFactory; + + public FactoryBased(Factory factory) { + myFactory = factory; + } + + public T readValue(Element dataElement) throws InvalidDataException { + T data = myFactory.create(); + data.readExternal(dataElement); + return data; + } + + public void writeValue(Element dataElement, T value) throws WriteExternalException { + value.writeExternal(dataElement); + } + + public static FactoryBased create(Factory factory) { + return new FactoryBased(factory); + } + } + + class StorageExternalizer implements Externalizer { + private static final String ITEM_TAG = "item"; + private static final String KEY_ATTR = "key"; + private static final String VALUE_ATTR = "value"; + + public Storage readValue(Element dataElement) throws InvalidDataException { + Storage.MapStorage storage = new Storage.MapStorage(); + List children = dataElement.getChildren(ITEM_TAG); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Element element = iterator.next(); + storage.put(element.getAttributeValue(KEY_ATTR), element.getAttributeValue(VALUE_ATTR)); + } + return storage; + } + + public void writeValue(Element dataElement, Storage storage) throws WriteExternalException { + Iterator keys = ((Storage.MapStorage)storage).getKeys(); + while (keys.hasNext()) { + String key = keys.next(); + String value = storage.get(key); + Element element = new Element(ITEM_TAG); + element.setAttribute(KEY_ATTR, key); + if (value != null) element.setAttribute(VALUE_ATTR, value); + dataElement.addContent(element); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/IntProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/IntProperty.java new file mode 100644 index 00000000000..df4a7665c9c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/IntProperty.java @@ -0,0 +1,15 @@ +package com.intellij.util.config; + +public class IntProperty extends ValueProperty { + public IntProperty(String name, int defaultValue) { + super(name, new Integer(defaultValue)); + } + + public int value(AbstractPropertyContainer container) { + return get(container).intValue(); + } + + public void primSet(AbstractPropertyContainer container, int value) { + set(container, new Integer(value)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ListProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ListProperty.java new file mode 100644 index 00000000000..dc8d2bd902b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ListProperty.java @@ -0,0 +1,46 @@ +package com.intellij.util.config; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class ListProperty extends AbstractProperty> { + private final String myName; + + public ListProperty(String name) { + myName = name; + } + + public static ListProperty create(String name) { + return new ListProperty(name); + } + + public String getName() { + return myName; + } + + public List getDefault(AbstractProperty.AbstractPropertyContainer container) { + return Collections.EMPTY_LIST; + } + + public List copy(List value) { + return Collections.unmodifiableList(value); + } + + public ArrayList getModifiableList(AbstractPropertyContainer container) { + List list = get(container); + if (list instanceof ArrayList) return (ArrayList)list; + ArrayList modifiableList = new ArrayList(list); + set(container, modifiableList); + return modifiableList; + } + + public void clearList(AbstractPropertyContainer container) { + getModifiableList(container).clear(); + } + + public Iterator getIterator(AbstractPropertyContainer container) { + return get(container).iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageAccessors.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageAccessors.java new file mode 100644 index 00000000000..aed9133809e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageAccessors.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.util.config; + +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; + +/** + * @author dyoma + */ +public class StorageAccessors { + private final Storage myStorage; + + public StorageAccessors(Storage storage) { + myStorage = storage; + } + + public static StorageAccessors createGlobal(String prefix) { + Application application = ApplicationManager.getApplication(); + Storage storage; + if (application != null) storage = new Storage.PropertiesComponentStorage(prefix + "."); + else storage = new Storage.MapStorage(); + return new StorageAccessors(storage); + } + + public float getFloat(String id, float defaultValue) { + String value = myStorage.get(id); + if (value == null) return defaultValue; + try { + return Float.parseFloat(value); + } + catch (NumberFormatException e) { + return defaultValue; + } + } + + public void setFloat(String id, float value) { + myStorage.put(id, String.valueOf(value)); + } + + public boolean getBoolean(String id, boolean defaultValue) { + return "true".equals(myStorage.get(id)); + } + + public void setBoolean(String id, boolean value) { + myStorage.put(id, String.valueOf(value)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageProperty.java new file mode 100644 index 00000000000..47244a9a675 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StorageProperty.java @@ -0,0 +1,33 @@ +package com.intellij.util.config; + +import java.util.Iterator; + +public class StorageProperty extends AbstractProperty { + private final String myName; + + public StorageProperty(String name) { + myName = name; + } + + public Storage getDefault(AbstractProperty.AbstractPropertyContainer container) { + Storage.MapStorage storage = new Storage.MapStorage(); + set(container, storage); + return storage; + } + + public Storage copy(Storage storage) { + if (!(storage instanceof Storage.MapStorage)) + throw new UnsupportedOperationException(storage.getClass().getName()); + Iterator keys = ((Storage.MapStorage)storage).getKeys(); + Storage.MapStorage copy = new Storage.MapStorage(); + while (keys.hasNext()) { + String key = keys.next(); + copy.put(key, storage.get(key)); + } + return copy; + } + + public String getName() { + return myName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StringProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StringProperty.java new file mode 100644 index 00000000000..cc28505fdda --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/StringProperty.java @@ -0,0 +1,13 @@ +package com.intellij.util.config; + +import com.intellij.openapi.util.Comparing; + +public class StringProperty extends ValueProperty { + public StringProperty(String name, String defaultValue) { + super(name, defaultValue); + } + + public boolean areEqual(String value1, String value2) { + return Comparing.strEqual(value1, value2, true); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ToggleBooleanProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ToggleBooleanProperty.java new file mode 100644 index 00000000000..1aa38bc6aff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ToggleBooleanProperty.java @@ -0,0 +1,42 @@ +package com.intellij.util.config; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ToggleAction; + +import javax.swing.*; + +public class ToggleBooleanProperty extends ToggleAction { + private final AbstractProperty.AbstractPropertyContainer myProperties; + private final AbstractProperty myProperty; + + public ToggleBooleanProperty(String text, String description, Icon icon, AbstractProperty.AbstractPropertyContainer properties, BooleanProperty property) { + super(text, description, icon); + myProperties = properties; + myProperty = property; + } + + public boolean isSelected(AnActionEvent e) { + return myProperty.get(myProperties).booleanValue(); + } + + public void setSelected(AnActionEvent e, boolean state) { + myProperty.set(myProperties, Boolean.valueOf(state)); + } + + protected AbstractProperty.AbstractPropertyContainer getProperties() { + return myProperties; + } + + public static abstract class Disablable extends ToggleBooleanProperty { + public Disablable(String text, String description, Icon icon, AbstractProperty.AbstractPropertyContainer properties, BooleanProperty property) { + super(text, description, icon, properties, property); + } + + protected abstract boolean isEnabled(); + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(isEnabled()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ValueProperty.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ValueProperty.java new file mode 100644 index 00000000000..435a7434946 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/config/ValueProperty.java @@ -0,0 +1,26 @@ +package com.intellij.util.config; + +/** + * @author dyoma + */ +public class ValueProperty extends AbstractProperty { + private final T myDefault; + private final String myName; + + public ValueProperty(String name, T defaultValue) { + myName = name; + myDefault = defaultValue; + } + + public T copy(T value) { + return value; + } + + public T getDefault(AbstractProperty.AbstractPropertyContainer container) { + return myDefault; + } + + public String getName() { + return myName; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMap.java new file mode 100644 index 00000000000..3751422ff54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMap.java @@ -0,0 +1,176 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; + +public class ByteBufferMap { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.ByteBufferMap"); + + private final RandomAccessDataInput myBuffer; + private final int myStartOffset; + private final KeyProvider myKeyProvider; + private final ValueProvider myValueProvider; + private int myMod; + private final int myEndOffset; + + public static interface KeyProvider { + int hashCode(Object key); + + void write(DataOutput out, Object key) throws IOException; + + int length(Object key); + + Object get(DataInput in) throws IOException; + + /** + * Should move the buffer pointer to the key end. + */ + boolean equals(DataInput in, Object key) throws IOException; + } + + public static interface ValueProvider { + void write(DataOutput out, Object value) throws IOException; + + int length(Object value); + + Object get(DataInput in) throws IOException; + } + + public static void writeMap(DataOutput stream, + ValueProvider valueProvider, + WriteableMap map, + double searchFactor) throws IOException { + new ByteBufferMapWriteHandler(stream, valueProvider, map, searchFactor).execute(); + } + + public static int calcMapLength(ValueProvider valueProvider, + WriteableMap map, + double searchFactor) throws IOException { + return new ByteBufferMapWriteHandler(null, valueProvider, map, searchFactor).calcLength(); + } + + public ByteBufferMap(RandomAccessDataInput buffer, + int startOffset, + int endOffset, + KeyProvider keyProvider, + ValueProvider valueProvider) { + LOG.assertTrue(keyProvider != null); + LOG.assertTrue(valueProvider != null); + LOG.assertTrue(startOffset < endOffset); + + myBuffer = buffer; + myStartOffset = startOffset; + myEndOffset = endOffset; + myKeyProvider = keyProvider; + myValueProvider = valueProvider; + + buffer.setPosition(startOffset); + try { + myMod = buffer.readInt(); + } + catch (IOException e) { + LOG.error(e); + } + } + + public Object get(Object key) { + int hash = hash(myKeyProvider.hashCode(key)); + int keyGroupOffset = readKeyGroupOffset(hash); + if (keyGroupOffset == -1) return null; + if (!(myStartOffset < keyGroupOffset && keyGroupOffset < myEndOffset)){ + LOG.error("keyGroupOffset = " + keyGroupOffset + " myStartOffset = " + myStartOffset + " myEndOffset = " + myEndOffset); + } + + try { + myBuffer.setPosition(keyGroupOffset); + int keyGroupSize = myBuffer.readInt(); + LOG.assertTrue(keyGroupSize > 0); + for (int i = 0; i < keyGroupSize; i++) { + if (myKeyProvider.equals(myBuffer, key)) { + int valueOffset = myBuffer.readInt(); + LOG.assertTrue(valueOffset > 0); + + myBuffer.setPosition(myStartOffset + valueOffset); + return myValueProvider.get(myBuffer); + } + else { + myBuffer.readInt(); //read offset; + } + } + } + catch (IOException e) { + LOG.error(e); + } + + return null; + } + + public Object[] getKeys(Class keyClass) { + ArrayList result = new ArrayList(); + getKeys(keyClass, result); + return result.toArray((Object[])Array.newInstance(keyClass, result.size())); + } + + public void getKeys(Class keyClass, Collection dst) { + try { + myBuffer.setPosition(myStartOffset + 4 /* mod */); + + int firstKeyGroupOffset = -1; + int lastKeyGroupOffset = -1; + for (int i = 0; i < myMod; i++) { + int value = myBuffer.readInt(); + if (value != -1) { + int offset = value + myStartOffset; + if (firstKeyGroupOffset == -1) firstKeyGroupOffset = offset; + lastKeyGroupOffset = offset; + } + } + if (firstKeyGroupOffset == -1) { + return; + } + LOG.assertTrue(firstKeyGroupOffset > myStartOffset); + LOG.assertTrue(lastKeyGroupOffset > myStartOffset); + LOG.assertTrue(lastKeyGroupOffset >= firstKeyGroupOffset); + + int firstValueOffset = -1; + + myBuffer.setPosition(firstKeyGroupOffset); + while (myBuffer.getPosition() <= lastKeyGroupOffset) { + int groupSize = myBuffer.readInt(); + for (int i = 0; i < groupSize; i++) { + dst.add(myKeyProvider.get(myBuffer)); + + int valueOffset = myBuffer.readInt(); /* value offset */ + if( firstValueOffset == -1 ) firstValueOffset = valueOffset + myStartOffset; + } + } + LOG.assertTrue( myBuffer.getPosition() == firstValueOffset ); + } + catch (IOException e) { + LOG.error(e); + } + } + + private int readKeyGroupOffset(int hash) { + myBuffer.setPosition(myStartOffset + 4 /* mod */ + 4 * hash); + int offset = -1; + try { + offset = myBuffer.readInt(); + } + catch (IOException e) { + LOG.error(e); + } + if (offset == -1) return -1; + return offset + myStartOffset; + } + + private int hash(int hashCode) { + return Math.abs(hashCode) % myMod; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMapWriteHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMapWriteHandler.java new file mode 100644 index 00000000000..93cdac0f480 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferMapWriteHandler.java @@ -0,0 +1,100 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +class ByteBufferMapWriteHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.ByteBufferMapWriteHandler"); + +// private final ByteBufferMap.KeyProvider myKeyProvider; + private final ByteBufferMap.ValueProvider myValueProvider; + private final WriteableMap myMap; + + private final int[] myKeyHashes; + private final int myMod; + private DataOutput myOut; +// private ProgressIndicator myProgress; + + public ByteBufferMapWriteHandler(DataOutput stream, /*ByteBufferMap.KeyProvider keyProvider, */ByteBufferMap.ValueProvider valueProvider, WriteableMap map, double searchFactor) { + myValueProvider = valueProvider; + myMap = map; + + myKeyHashes = myMap.getHashCodesArray(); + int mod = (int)(myKeyHashes.length / searchFactor); + myMod = mod != 0 ? mod : 1; + myOut = stream; + } + + public void execute() throws IOException { +// myProgress = ProgressManager.getInstance().getProgressIndicator(); //Q: not goot to use ProgressManager in util package? + + executeImpl( true ); + } + + public int calcLength() throws IOException { + return executeImpl( false ); + } + + public int executeImpl( boolean write ) throws IOException { + if( write ) myOut.writeInt(myMod); + int offset = 4; + + int overflowList[] = new int[myKeyHashes.length]; + int firstOverflowElem[] = new int[myMod]; + int occurs[] = new int[myMod]; + Arrays.fill(firstOverflowElem, -1); + + // Creating hash table and overflow lists + for( int i = myKeyHashes.length-1; i >= 0; i-- ) { + int hashhash = hash(myKeyHashes[i]); + overflowList[i] = firstOverflowElem[hashhash]; + firstOverflowElem[hashhash] = i; + occurs[hashhash]++; + } + + offset += 4 * myMod; // hash table size + // writing hash table + for( int i = 0; i < myMod; i++ ) { + if( write ) myOut.writeInt( occurs[i] != 0 ? offset : -1 ); + if( occurs[i] != 0 ) offset += 4; // key group size, if key group present + int occurs_i = 0; + for( int j = firstOverflowElem[i]; j != -1; j = overflowList[j] ) { + offset += myMap.getKeyLength( j ) + 4 /* value offset */; + occurs_i++; + } + LOG.assertTrue( occurs_i == occurs[i] ); + } + + // writing key table + for( int i = 0; i < myMod; i++ ) { + if( occurs[i] == 0 ) continue; + + if( write ) myOut.writeInt( occurs[i] ); + for( int j = firstOverflowElem[i]; j != -1; j = overflowList[j] ) { + if( write ) { + myMap.writeKey( myOut, j ); + myOut.writeInt( offset ); + } + Object value = myMap.getValue(j); + offset += myValueProvider.length(value); + } + } + + // writing value table + for( int i = 0; i < myMod; i++ ) { + for( int j = firstOverflowElem[i]; j != -1; j = overflowList[j] ) { + Object value = myMap.getValue(j); + if( write ) myValueProvider.write( myOut, value ); + } + } + + return offset; // total resulting length + } + + private int hash(int hashCode){ + return Math.abs(hashCode) % myMod; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferRADataInput.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferRADataInput.java new file mode 100644 index 00000000000..867db2632e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/ByteBufferRADataInput.java @@ -0,0 +1,91 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * @author max + */ +public class ByteBufferRADataInput implements RandomAccessDataInput { + private static final Logger LOG = Logger.getInstance("com.intellij.util.io.ByteBufferRADataInput"); + + private ByteBuffer myBuffer; + + public ByteBufferRADataInput(ByteBuffer buffer) { + myBuffer = buffer; + } + + public void setPosition(int pos) { + myBuffer.position(pos); + } + + public int getPosition() { + return myBuffer.position(); + } + + public void readFully(byte b[]) throws IOException { + myBuffer.get(b); + } + + public void readFully(byte b[], int off, int len) throws IOException { + myBuffer.get(b, off, len); + } + + public int skipBytes(int n) throws IOException { + int newPos = getPosition() + n; + setPosition(newPos); + return newPos; + } + + public boolean readBoolean() throws IOException { + return myBuffer.get() == 1; + } + + public byte readByte() throws IOException { + return myBuffer.get(); + } + + public int readUnsignedByte() throws IOException { + return 0xFF & ((int)myBuffer.get()); + } + + public short readShort() throws IOException { + return myBuffer.getShort(); + } + + public int readUnsignedShort() throws IOException { + return 0xFFFF & ((int)myBuffer.getShort()); + } + + public char readChar() throws IOException { + return myBuffer.getChar(); + } + + public int readInt() throws IOException { + return myBuffer.getInt(); + } + + public long readLong() throws IOException { + return myBuffer.getLong(); + } + + public float readFloat() throws IOException { + return myBuffer.getFloat(); + } + + public double readDouble() throws IOException { + return myBuffer.getDouble(); + } + + public String readLine() throws IOException { + LOG.error("Not implemented"); + return null; + } + + public String readUTF() throws IOException { + return DataInputStream.readUTF(this); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileByteBuffer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileByteBuffer.java new file mode 100644 index 00000000000..8b18c6111f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileByteBuffer.java @@ -0,0 +1,254 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.IOException; +import java.io.RandomAccessFile; + +public class FileByteBuffer { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.FileByteBuffer"); + + private final RandomAccessFile myFile; + + public FileByteBuffer(RandomAccessFile file) { + myFile = file; + } + + public byte get() { + try{ + return myFile.readByte(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer put(byte b) { + try{ + myFile.write(b); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public byte get(int index) { + try{ + myFile.seek(index); + return myFile.readByte(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer put(int index, byte b) { + try{ + myFile.seek(index); + myFile.write(b); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public char getChar() { + try{ + return myFile.readChar(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putChar(char value) { + try{ + myFile.writeChar(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public char getChar(int index) { + try{ + myFile.seek(index); + return myFile.readChar(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putChar(int index, char value) { + try{ + myFile.seek(index); + myFile.writeChar(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public short getShort() { + try{ + return myFile.readShort(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putShort(short value) { + try{ + myFile.writeShort(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public short getShort(int index) { + try{ + myFile.seek(index); + return myFile.readShort(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putShort(int index, short value) { + try{ + myFile.seek(index); + myFile.writeShort(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public int getInt() { + try{ + return myFile.readInt(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putInt(int value) { + try{ + myFile.writeInt(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public int getInt(int index) { + try{ + myFile.seek(index); + return myFile.readInt(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putInt(int index, int value) { + try{ + myFile.seek(index); + myFile.writeInt(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public long getLong() { + try{ + return myFile.readLong(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putLong(long value) { + try{ + myFile.writeLong(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public long getLong(int index) { + try{ + myFile.seek(index); + return myFile.readLong(); + } + catch(IOException e){ + LOG.error(e); + return 0; + } + } + + public FileByteBuffer putLong(int index, long value) { + try{ + myFile.seek(index); + myFile.writeLong(value); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } + + public void position(int index) { + try{ + myFile.seek(index); + } + catch(IOException e){ + LOG.error(e); + } + } + + public void put(byte[] src, int offset, int length) { + try{ + myFile.write(src, offset, length); + } + catch(IOException e){ + LOG.error(e); + } + } + + public FileByteBuffer get(byte[] dst, int offset, int length) { + try{ + myFile.read(dst, offset, length); + } + catch(IOException e){ + LOG.error(e); + } + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileKeyProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileKeyProvider.java new file mode 100644 index 00000000000..6b4c1d8767d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/FileKeyProvider.java @@ -0,0 +1,48 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import gnu.trove.TObjectIntHashMap; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class FileKeyProvider implements ByteBufferMap.KeyProvider{ + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.FileKeyProvider"); + + private final VirtualFile[] myFileIndex; + private final TObjectIntHashMap myFileToIndexMap; + + public FileKeyProvider(VirtualFile[] fileIndex, TObjectIntHashMap fileToIndexMap) { + myFileIndex = fileIndex; + myFileToIndexMap = fileToIndexMap; + } + + public int hashCode(Object key) { + VirtualFile file = (VirtualFile)key; + int index = myFileToIndexMap.get(file) - 1; + return index; + } + + public void write(DataOutput out, Object key) throws IOException { + VirtualFile file = (VirtualFile)key; + int index = myFileToIndexMap.get(file) - 1; + LOG.assertTrue(index >= 0); + out.writeInt(index); + } + + public int length(Object key) { + return 4; + } + + public Object get(DataInput in) throws IOException { + int index = in.readInt(); + return myFileIndex[index]; + } + + public boolean equals(DataInput in, Object key) throws IOException { + int index = in.readInt(); + return key.equals(myFileIndex[index]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntArrayValueProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntArrayValueProvider.java new file mode 100644 index 00000000000..783978c84d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntArrayValueProvider.java @@ -0,0 +1,85 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.containers.IntArrayList; +import gnu.trove.TIntArrayList; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IntArrayValueProvider implements ByteBufferMap.ValueProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.IntArrayValueProvider"); + public static final IntArrayValueProvider INSTANCE = new IntArrayValueProvider(-1); + + private final int myArraySize; + + public IntArrayValueProvider(int arraySize) { + myArraySize = arraySize; + } + + public void write(DataOutput out, Object value) throws IOException { + if (value instanceof IntArrayList) { + IntArrayList list = (IntArrayList) value; + LOG.assertTrue(myArraySize == -1 || list.size() == myArraySize); + if (myArraySize == -1) out.writeInt(list.size()); + for (int i = 0; i < list.size(); i++) { + out.writeInt(list.get(i)); + } + } else if (value instanceof TIntArrayList) { + TIntArrayList list = (TIntArrayList) value; + LOG.assertTrue(myArraySize == -1 || list.size() == myArraySize); + if (myArraySize == -1) out.writeInt(list.size()); + for (int i = 0; i < list.size(); i++) { + out.writeInt(list.get(i)); + } + } else { + int[] array = (int[])value; + LOG.assertTrue(myArraySize == -1 || array.length == myArraySize); + if (myArraySize == -1) out.writeInt(array.length); + for(int i = 0; i < array.length; i++){ + out.writeInt(array[i]); + } + } + } + + public int length(Object value) { + if (value instanceof IntArrayList) { + IntArrayList list = (IntArrayList) value; + LOG.assertTrue(myArraySize == -1 || list.size() == myArraySize); + + if (myArraySize == -1) return 4 * (list.size() + 1); + + return 4 * myArraySize; + } else if (value instanceof TIntArrayList) { + TIntArrayList list = (TIntArrayList) value; + LOG.assertTrue(myArraySize == -1 || list.size() == myArraySize); + + if (myArraySize == -1) return 4 * (list.size() + 1); + + return 4 * myArraySize; + } else { + int[] array = (int[])value; + LOG.assertTrue(myArraySize == -1 || array.length == myArraySize); + + if (myArraySize == -1) return 4 * (array.length + 1); + + return 4 * myArraySize; + } + } + + public Object get(DataInput in) throws IOException { + final int[] result; + + if (myArraySize >= 0) { + result = new int[myArraySize]; + } else { + result = new int[in.readInt()]; + } + + for(int i = 0; i < result.length; i++){ + result[i] = in.readInt(); + } + return result; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntValueProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntValueProvider.java new file mode 100644 index 00000000000..1fb8047bd59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntValueProvider.java @@ -0,0 +1,27 @@ +package com.intellij.util.io; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author max + */ +public class IntValueProvider implements ByteBufferMap.ValueProvider { + public static IntValueProvider INSTANCE = new IntValueProvider(); + + private IntValueProvider() { + } + + public void write(DataOutput out, Object value) throws IOException { + out.writeInt(((Integer)value).intValue()); + } + + public int length(Object value) { + return 4; + } + + public Object get(DataInput in) throws IOException { + return new Integer(in.readInt()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntegerKeyProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntegerKeyProvider.java new file mode 100644 index 00000000000..6111fe8eb81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/IntegerKeyProvider.java @@ -0,0 +1,44 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: Dmitry.Shtukenberg + * Date: Apr 28, 2004 + * Time: 4:52:43 PM + * To change this template use File | Settings | File Templates. + */ +public class IntegerKeyProvider implements ByteBufferMap.KeyProvider { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.StringKeyProvider"); + + public static final IntegerKeyProvider INSTANCE = new IntegerKeyProvider(); + + private IntegerKeyProvider() { + } + + public int hashCode(Object key) { + return key.hashCode(); + } + + public void write(DataOutput out, Object key) throws IOException { + Integer k = (Integer)key; + out.writeInt(k.intValue()); + } + + public int length(Object key) { + return 4; + } + + public Object get(DataInput in) throws IOException { + return new Integer(in.readInt()); + } + + public boolean equals(DataInput in, Object key) throws IOException { + return ((Integer)key).intValue() == in.readInt(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RandomAccessDataInput.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RandomAccessDataInput.java new file mode 100644 index 00000000000..a8b5ef8cb5c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RandomAccessDataInput.java @@ -0,0 +1,11 @@ +package com.intellij.util.io; + +import java.io.DataInput; + +/** + * @author max + */ +public interface RandomAccessDataInput extends DataInput { + void setPosition(int pos); + int getPosition(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RecordDataOutput.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RecordDataOutput.java new file mode 100644 index 00000000000..a4f657ecc67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/RecordDataOutput.java @@ -0,0 +1,12 @@ +package com.intellij.util.io; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * @author max + */ +public interface RecordDataOutput extends DataOutput { + int getRecordId(); + void close() throws IOException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/StringKeyProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/StringKeyProvider.java new file mode 100644 index 00000000000..61c54266538 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/StringKeyProvider.java @@ -0,0 +1,74 @@ +package com.intellij.util.io; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class StringKeyProvider implements ByteBufferMap.KeyProvider{ + private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.StringKeyProvider"); + + public static final StringKeyProvider INSTANCE = new StringKeyProvider(); + + private StringKeyProvider() { + } + + public int hashCode(Object key) { + return key.hashCode(); + } + + public void write(DataOutput out, Object key) throws IOException { + String keyString = (String)key; + byte[] keyBytes = keyString.getBytes("UTF-8"); + out.writeInt(keyBytes.length); + out.write(keyBytes); + } + + public int length(Object key) { + try{ + String keyString = (String)key; + byte[] keyBytes = keyString.getBytes("UTF-8"); + return 4 + keyBytes.length; + } + catch(UnsupportedEncodingException e){ + LOG.error(e); + return 0; + } + } + + public Object get(DataInput in) throws IOException { + int length = in.readInt(); + byte[] bytes = new byte[length]; + in.readFully(bytes); + try { + return new String(bytes, "UTF-8"); + } + catch (UnsupportedEncodingException e) { + LOG.error(e); + return null; + } + } + + public boolean equals(DataInput in, Object key) throws IOException { + try { + String keyString = (String)key; + byte[] keyBytes = keyString.getBytes("UTF-8"); + + int length = in.readInt(); + byte[] inputBytes = new byte[length]; + in.readFully(inputBytes); + if (length != keyBytes.length) return false; + for (int i = 0; i < length; i++) { + if (keyBytes[i] != inputBytes[i]) return false; + } + + return true; + } + catch (UnsupportedEncodingException e) { + LOG.error(e); + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMap.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMap.java new file mode 100644 index 00000000000..2ede255d1b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMap.java @@ -0,0 +1,17 @@ +package com.intellij.util.io; + +import java.io.DataOutput; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * @author max + */ +public interface WriteableMap { +//Object[] keySet(); +//V get(K key); + int[] getHashCodesArray(); // Returns array of all key hash codes in the map + V getValue( int pos ); + void writeKey( DataOutput stream, int pos ) throws IOException; + int getKeyLength( int pos ) throws UnsupportedEncodingException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMapAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMapAdapter.java new file mode 100644 index 00000000000..36ba8c5734d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableMapAdapter.java @@ -0,0 +1,39 @@ +package com.intellij.util.io; + +import java.io.DataOutput; +import java.io.IOException; +import java.util.Map; + +/** + * @author max + */ +public class WriteableMapAdapter implements WriteableMap { + private Map myMap; + private ByteBufferMap.KeyProvider myKeyProvider; + private K[] myKeys; + + public WriteableMapAdapter(Map map, ByteBufferMap.KeyProvider provider) { + myMap = map; + myKeyProvider = provider; + myKeys = (K[]) myMap.keySet().toArray(); + } + + public int[] getHashCodesArray() { + int[] keyHashCodes = new int[ myKeys.length ]; + for( int i = 0; i < myKeys.length; i++ ) + keyHashCodes[i] = myKeyProvider.hashCode(myKeys[i]); + return keyHashCodes; + } + + public V getValue( int n ) { + return myMap.get( myKeys[n] ); + } + + public int getKeyLength( int n ) { + return myKeyProvider.length( myKeys[n] ); + } + + public void writeKey( DataOutput out, int n ) throws IOException { + myKeyProvider.write( out, myKeys[n] ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableTIntObjectMapAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableTIntObjectMapAdapter.java new file mode 100644 index 00000000000..c0189694209 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/io/WriteableTIntObjectMapAdapter.java @@ -0,0 +1,38 @@ +package com.intellij.util.io; + +import gnu.trove.TIntObjectHashMap; + +import java.io.DataOutput; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: Dmitry.Shtukenberg + * Date: Apr 28, 2004 + * Time: 4:36:27 PM + * To change this template use File | Settings | File Templates. + */ +public class WriteableTIntObjectMapAdapter implements WriteableMap { + private TIntObjectHashMap hashmap; + private int[] hashkeys; + + public WriteableTIntObjectMapAdapter(TIntObjectHashMap map) { + hashmap = map; + } + + public int[] getHashCodesArray() { + return hashkeys = hashmap.keys(); + } + + public Object getValue( int pos ) { + return hashmap.get( hashkeys[pos] ); + } + + public int getKeyLength( int pos ) { + return 4; + } + + public void writeKey( DataOutput out, int pos ) throws IOException { + out.writeInt( hashkeys[pos] ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationDialog.java new file mode 100644 index 00000000000..c94a4d41498 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationDialog.java @@ -0,0 +1,68 @@ +package com.intellij.util.net; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.*; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Oct 7, 2003 + * Time: 3:56:25 PM + * To change this template use Options | File Templates. + */ +public class AuthenticationDialog extends JDialog { + private AuthenticationPanel panel; + + public AuthenticationDialog(String title, String description) { + super(JOptionPane.getRootFrame(), title, true); + + panel = new AuthenticationPanel(description, + HttpConfigurable.getInstance().PROXY_LOGIN, + HttpConfigurable.getInstance().getPlainProxyPassword(), + HttpConfigurable.getInstance().KEEP_PROXY_PASSWORD); + + getContentPane().setLayout(new BorderLayout ()); + getContentPane().add(panel, BorderLayout.CENTER); + + JPanel buttonPanel = new JPanel (); + buttonPanel.setLayout(new GridLayout (1, 2)); + for (int i = 0; i < createActions().length; i++) { + Action action = createActions()[i]; + buttonPanel.add(new JButton (action), i); + } + + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + + Dimension parentSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension ownSize = getPreferredSize(); + + setLocation((parentSize.width - ownSize.width) / 2, (parentSize.height - ownSize.height) / 2); + + pack(); + } + + protected Action[] createActions() { + Action [] actions = + new Action [] { + new AbstractAction ("OK") { + public void actionPerformed(ActionEvent e) { + HttpConfigurable.getInstance().PROXY_LOGIN = panel.getLogin(); + HttpConfigurable.getInstance().setPlainProxyPassword(panel.getPassword()); + HttpConfigurable.getInstance().PROXY_AUTHENTICATION = true; + HttpConfigurable.getInstance().KEEP_PROXY_PASSWORD = panel.isRememberPassword(); + + dispose(); + } + }, + new AbstractAction("Cancel") { + public void actionPerformed(ActionEvent e) { + HttpConfigurable.getInstance().PROXY_AUTHENTICATION = false; + dispose(); + } + } + }; + actions [0].putValue(Action.DEFAULT, "true"); + return actions; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationPanel.java new file mode 100644 index 00000000000..3ff9cf98c88 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/AuthenticationPanel.java @@ -0,0 +1,38 @@ +package com.intellij.util.net; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Sep 12, 2003 + * Time: 8:40:40 PM + * To change this template use Options | File Templates. + */ +public class AuthenticationPanel extends JPanel { + private JPanel myMainPanel; + private JLabel myDescriptionLabel; + private JTextField myLoginTextField; + private JPasswordField myPasswordTextField; + private JCheckBox rememberPasswordCheckBox; + + public AuthenticationPanel(String description, String login, String password, boolean rememberPassword) { + add(myMainPanel); + myDescriptionLabel.setText(description); + myLoginTextField.setText(login); + myPasswordTextField.setText(password); + rememberPasswordCheckBox.setSelected(rememberPassword); + } + + public String getLogin () { + return myLoginTextField.getText(); + } + + public String getPassword () { + return new String (myPasswordTextField.getPassword()); + } + + public boolean isRememberPassword () { + return rememberPasswordCheckBox.isSelected(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsDialog.java new file mode 100644 index 00000000000..4a04cd5d998 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsDialog.java @@ -0,0 +1,47 @@ +package com.intellij.util.net; + +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; +import java.awt.event.ActionEvent; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Oct 21, 2003 + * Time: 4:35:44 PM + * To change this template use Options | File Templates. + */ +public class HTTPProxySettingsDialog extends DialogWrapper { + private HTTPProxySettingsPanel panel; + private Action okAction; + private Action cancelAction; + + public HTTPProxySettingsDialog() { + super(false); + setTitle("HTTP Proxy Settings"); + panel = new HTTPProxySettingsPanel(); + + okAction = new AbstractAction ("OK") { + public void actionPerformed(ActionEvent e) { + panel.apply(); + dispose(); + } + }; + okAction.putValue(DEFAULT_ACTION, "true"); + cancelAction = new AbstractAction("Cancel") { + public void actionPerformed(ActionEvent e) { + dispose(); + } + }; + init(); + } + + protected JComponent createCenterPanel() { + return panel; + } + + protected Action[] createActions() { + return new Action [] {okAction, cancelAction}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsPanel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsPanel.java new file mode 100644 index 00000000000..70f5c7a31c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HTTPProxySettingsPanel.java @@ -0,0 +1,133 @@ +package com.intellij.util.net; + +import javax.swing.*; +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Aug 28, 2003 + * Time: 3:52:47 PM + * To change this template use Options | File Templates. + */ +public class HTTPProxySettingsPanel extends JPanel { + private JPanel myMainPanel; + private JPanel myInternalPanel; + + private JTextField myProxyLoginTextField; + private JPasswordField myProxyPasswordTextField; + private JCheckBox myProxyAuthCheckBox; + private JTextField myProxyPortTextField; + private JTextField myProxyHostTextField; + private JCheckBox myUseProxyCheckBox; + private JCheckBox myRememberProxyPasswordCheckBox; + + private JLabel myProxyLoginLabel; + private JLabel myProxyPasswordLabel; + private JLabel myHostNameLabel; + private JLabel myPortNumberLabel; + + private boolean myModified = false; + private JPanel myAdditionalPanel; + + public boolean isModified() { + return myModified; + } + + private class DocumentModifyListener implements DocumentListener { + public void removeUpdate(DocumentEvent e) { + myModified = true; + } + + public void changedUpdate(DocumentEvent e) { + myModified = true; + } + + public void insertUpdate(DocumentEvent e) { + myModified = true; + } + } + + public HTTPProxySettingsPanel() { + add(myMainPanel); + + myProxyAuthCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myModified = true; + enableProxyAuthentication(myProxyAuthCheckBox.isSelected()); + } + }); + + myUseProxyCheckBox.addActionListener(new ActionListener () { + public void actionPerformed(ActionEvent e) { + myModified = true; + enableProxy(myUseProxyCheckBox.isSelected()); + } + }); + + myRememberProxyPasswordCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myModified = true; + } + }); + + myProxyLoginTextField.getDocument().addDocumentListener(new DocumentModifyListener()); + myProxyPasswordTextField.getDocument().addDocumentListener(new DocumentModifyListener()); + myProxyPortTextField.getDocument().addDocumentListener(new DocumentModifyListener()); + myProxyHostTextField.getDocument().addDocumentListener(new DocumentModifyListener()); + + myUseProxyCheckBox.setSelected(HttpConfigurable.getInstance().USE_HTTP_PROXY); + myProxyAuthCheckBox.setSelected(HttpConfigurable.getInstance().PROXY_AUTHENTICATION); + + enableProxy(HttpConfigurable.getInstance().USE_HTTP_PROXY); + + myProxyLoginTextField.setText(HttpConfigurable.getInstance().PROXY_LOGIN); + myProxyPasswordTextField.setText(HttpConfigurable.getInstance().getPlainProxyPassword()); + + myProxyPortTextField.setText(Integer.toString(HttpConfigurable.getInstance().PROXY_PORT)); + myProxyHostTextField.setText(HttpConfigurable.getInstance().PROXY_HOST); + + myRememberProxyPasswordCheckBox.setSelected(HttpConfigurable.getInstance().KEEP_PROXY_PASSWORD); + } + + public void apply () { + HttpConfigurable.getInstance().USE_HTTP_PROXY = myUseProxyCheckBox.isSelected(); + HttpConfigurable.getInstance().PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected(); + HttpConfigurable.getInstance().KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected(); + + HttpConfigurable.getInstance().PROXY_LOGIN = myProxyLoginTextField.getText(); + HttpConfigurable.getInstance().setPlainProxyPassword(new String (myProxyPasswordTextField.getPassword())); + + try { + HttpConfigurable.getInstance().PROXY_PORT = Integer.valueOf(myProxyPortTextField.getText()).intValue(); + } catch (NumberFormatException e) { + HttpConfigurable.getInstance().PROXY_PORT = 80; + } + HttpConfigurable.getInstance().PROXY_HOST = myProxyHostTextField.getText(); + + myModified = false; + } + + private void enableProxy (boolean enabled) { + myHostNameLabel.setEnabled(enabled); + myPortNumberLabel.setEnabled(enabled); + myProxyHostTextField.setEnabled(enabled); + myProxyPortTextField.setEnabled(enabled); + + myProxyAuthCheckBox.setEnabled(enabled); + enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected()); + } + + private void enableProxyAuthentication (boolean enabled) { + myProxyPasswordLabel.setEnabled(enabled); + myProxyLoginLabel.setEnabled(enabled); + + myProxyLoginTextField.setEnabled(enabled); + myProxyPasswordTextField.setEnabled(enabled); + + myRememberProxyPasswordCheckBox.setEnabled(enabled); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HttpConfigurable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HttpConfigurable.java new file mode 100644 index 00000000000..9233b205b49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/HttpConfigurable.java @@ -0,0 +1,112 @@ +package com.intellij.util.net; + +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.DefaultJDOMExternalizer; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.application.ApplicationManager; +import org.jdom.Element; +import org.apache.xmlrpc.Base64; + +import java.net.Authenticator; +import java.net.PasswordAuthentication; +import java.net.HttpURLConnection; +import java.net.URL; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Oct 7, 2003 + * Time: 3:58:23 PM + * To change this template use Options | File Templates. + */ +public class HttpConfigurable implements JDOMExternalizable, ApplicationComponent { + public boolean USE_HTTP_PROXY = false; + public String PROXY_HOST = ""; + public int PROXY_PORT = 80; + + public boolean PROXY_AUTHENTICATION = false; + public String PROXY_LOGIN = ""; + public String PROXY_PASSWORD_CRYPT = ""; + public boolean KEEP_PROXY_PASSWORD = false; + + public static HttpConfigurable getInstance() { + return ApplicationManager.getApplication().getComponent(HttpConfigurable.class); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + if (!KEEP_PROXY_PASSWORD) + PROXY_PASSWORD_CRYPT = ""; + } + + public void writeExternal(Element element) throws WriteExternalException { + String proxyPassword = PROXY_PASSWORD_CRYPT; + if (!KEEP_PROXY_PASSWORD) + PROXY_PASSWORD_CRYPT = ""; + + DefaultJDOMExternalizer.writeExternal(this, element); + + PROXY_PASSWORD_CRYPT = proxyPassword; + } + + public String getComponentName() { + return "HttpConfigurable"; + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public String getPlainProxyPassword () { + return new String(Base64.decode(HttpConfigurable.getInstance().PROXY_PASSWORD_CRYPT.getBytes())); + } + + public void setPlainProxyPassword (String password) { + PROXY_PASSWORD_CRYPT = new String(Base64.encode(new String(password).getBytes())); + } + + private Authenticator getAuthenticator () { + return new Authenticator () { + protected PasswordAuthentication getPasswordAuthentication() { + if (PROXY_AUTHENTICATION && + ! KEEP_PROXY_PASSWORD) { + AuthenticationDialog dlg = new AuthenticationDialog(getRequestingHost(), getRequestingPrompt()); + dlg.show(); + } + return new PasswordAuthentication(PROXY_LOGIN, + getPlainProxyPassword().toCharArray()); + } + }; + } + + // @todo [all] Call this function before every HTTP connection. + /** + * Call this function before every HTTP connection. + * If system configured to use HTTP proxy, this function + * checks all required parameters and ask password if + * required. + * @param url URL for HTTP connection + * @throws IOException + */ + public void prepareURL (String url) throws IOException { + if (USE_HTTP_PROXY) { + System.setProperty("proxySet", "true"); + System.setProperty("http.proxyHost", PROXY_HOST); + System.setProperty("http.proxyPort", Integer.toString (PROXY_PORT)); + Authenticator.setDefault(getAuthenticator()); + } else { + System.setProperty("proxySet", "false"); + Authenticator.setDefault(null); + } + + HttpURLConnection connection = (HttpURLConnection)new URL (url).openConnection(); + connection.connect(); + connection.getInputStream(); + connection.disconnect(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/IOExceptionDialog.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/IOExceptionDialog.java new file mode 100644 index 00000000000..e61c21dbe7d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/IOExceptionDialog.java @@ -0,0 +1,85 @@ +package com.intellij.util.net; + +import javax.swing.*; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.*; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Nov 19, 2003 + * Time: 10:04:14 PM + * To change this template use Options | File Templates. + */ +public class IOExceptionDialog extends JDialog { + private JPanel mainPanel; + private JButton cancelButton; + private JButton tryAgainButton; + private JButton setupButton; + private JTextArea errorTextArea; + private JLabel errorLabel; + private boolean cancelPressed = false; + + public IOExceptionDialog(IOException e, String title, String errorText) { + super (JOptionPane.getRootFrame(), title, true); + + getContentPane().add(mainPanel); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter (baos); + e.printStackTrace(writer); + writer.flush(); + errorTextArea.setText(baos.toString()); + errorTextArea.setCaretPosition(0); + errorLabel.setText(errorText); + + setupButton.addActionListener(new ActionListener () { + public void actionPerformed(ActionEvent e) { + HTTPProxySettingsDialog dlg = new HTTPProxySettingsDialog(); + dlg.show(); + } + }); + tryAgainButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cancelPressed = false; + dispose(); + } + }); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cancelPressed = true; + dispose(); + } + }); + + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + + Dimension parentSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension ownSize = getPreferredSize(); + + setLocation((parentSize.width - ownSize.width) / 2, (parentSize.height - ownSize.height) / 2); + + pack(); + } + + /** + * Show + * @return true if "Try Again" button pressed + * @return false if "Cancel" button pressed + */ + public static boolean showErrorDialog (IOException e, String title, String text) { + e.printStackTrace(System.err); + + IOExceptionDialog dlg = new IOExceptionDialog(e, title, text); + dlg.show(); + return ! dlg.cancelPressed; + } + + public static void main(String[] args) { + IOExceptionDialog.showErrorDialog(new IOException("test"), "Test", "Something failed"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/LockException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/LockException.java new file mode 100644 index 00000000000..65e7460d698 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/net/LockException.java @@ -0,0 +1,14 @@ +package com.intellij.util.net; + +/** + * Created by IntelliJ IDEA. + * User: stathik + * Date: Dec 16, 2003 + * Time: 9:47:01 PM + * To change this template use Options | File Templates. + */ +public class LockException extends Exception { + public LockException(int port) { + super (Integer.toString(port)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/properties/EncodingAwareProperties.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/properties/EncodingAwareProperties.java new file mode 100644 index 00000000000..e7703a7497b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/properties/EncodingAwareProperties.java @@ -0,0 +1,28 @@ +package com.intellij.util.properties; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.text.StringTokenizer; + +import java.io.File; +import java.io.IOException; + +/** + * @author MYakovlev + * Date: Oct 29, 2002 + * Time: 8:47:43 PM + */ +public class EncodingAwareProperties extends java.util.Properties{ + public void load(File file, String encoding) throws IOException{ + String propText = new String(FileUtil.loadFileText(file, encoding)); + propText = StringUtil.convertLineSeparators(propText, "\n"); + StringTokenizer stringTokenizer = new StringTokenizer(propText, "\n"); + while (stringTokenizer.hasMoreElements()){ + String line = (String)stringTokenizer.nextElement(); + int i = line.indexOf('='); + String propName = i == -1 ? line : line.substring(0,i); + String propValue = i == -1 ? "" : line.substring(i+1); + setProperty(propName, propValue); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/text/ElementPresentation.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/text/ElementPresentation.java new file mode 100644 index 00000000000..61de564c685 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/text/ElementPresentation.java @@ -0,0 +1,349 @@ +package com.intellij.util.text; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlTag; + +public abstract class ElementPresentation { + private final Noun myKind; + + protected ElementPresentation(Noun kind) { + myKind = kind; + } + + public static ElementPresentation forElement(PsiElement psiElement) { + if (psiElement == null || !psiElement.isValid()) return new InvalidPresentation(); + if (psiElement instanceof PsiDirectory) return new ForDirectory(((PsiDirectory)psiElement)); + if (psiElement instanceof PsiFile) return new ForFile(((PsiFile)psiElement)); + if (psiElement instanceof PsiPackage) return new ForPackage(((PsiPackage)psiElement)); + if (psiElement instanceof XmlTag) return new ForXmlTag(((XmlTag)psiElement)); + if (psiElement instanceof PsiAnonymousClass) return new ForAnonymousClass(((PsiAnonymousClass)psiElement)); + if (psiElement instanceof PsiClass) return new ForClass(((PsiClass)psiElement)); + if (psiElement instanceof PsiMethod) return new ForMethod(((PsiMethod)psiElement)); + if (psiElement instanceof PsiField) return new ForField(((PsiField)psiElement)); + return new ForGeneralElement(psiElement); + } + + public static ElementPresentation forVirtualFile(VirtualFile file) { + return new ForVirtualFile(file); + } + + private static boolean validNotNull(VirtualFile virtualFile) { + return virtualFile != null && virtualFile.isValid(); + } + + public abstract String getQualifiedName(); + + public Noun getKind() { + return myKind; + } + + public abstract String getName(); + + public abstract String getComment(); + + public String getNameWithFQComment() { + String comment = getComment(); + String result = getName(); + if (comment.trim().length() == 0) return result; + return result + " (" + comment + ")"; + } + + public static class Noun { + private final String myPlural; + private final String mySingular; + + public static final Noun DIRECTORY = new Noun("directory", "directories"); + public static final Noun PACKAGE = new Noun("package", "packages"); + public static final Noun FILE = new Noun("file", "files"); + public static final Noun CLASS = new Noun("class", "classes"); + public static final Noun METHOD = new Noun("method", "methods"); + public static final Noun FIELD = new Noun("field", "fields"); + public static final Noun FRAGMENT = new Noun("fragment", "fragments"); + public static final Noun XML_TAG = new Noun("tag", "tags"); + + public Noun(String singular, String plural) { + mySingular = singular; + myPlural = plural; + } + + public String getPlural(boolean firstCapitalized) { + return firstCapitalized(myPlural, firstCapitalized); + } + + public String getSingular(boolean firstCapitalized) { + return firstCapitalized(mySingular, firstCapitalized); + } + + private static String firstCapitalized(String word, boolean firstCapitalized) { + if (!firstCapitalized) return word; + char[] chars = word.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return new String(chars); + } + } + + private static class InvalidPresentation extends ElementPresentation { + public InvalidPresentation() { + super(new Noun("INVALID", "INVALID")); + } + + public String getComment() { + return ""; + } + + public String getName() { + return "INVALID"; + } + + public String getQualifiedName() { + return getName(); + } + } + + private static class ForDirectory extends ElementPresentation { + private final PsiDirectory myPsiDirectory; + + public ForDirectory(PsiDirectory psiDirectory) { + super(Noun.DIRECTORY); + myPsiDirectory = psiDirectory; + } + + public String getQualifiedName() { + VirtualFile virtualFile = myPsiDirectory.getVirtualFile(); + if (validNotNull(virtualFile)) return virtualFile.getPresentableUrl(); + return myPsiDirectory.getName(); + } + + public String getName() { + return myPsiDirectory.getName(); + } + + public String getComment() { + PsiDirectory parentDirectory = myPsiDirectory.getParentDirectory(); + if (parentDirectory == null) return ""; + return ElementPresentation.forElement(parentDirectory).getQualifiedName(); + } + } + + private static class ForFile extends ElementPresentation { + private final PsiFile myFile; + + public ForFile(PsiFile file) { + super(Noun.FILE); + myFile = file; + } + + public String getQualifiedName() { + VirtualFile virtualFile = myFile.getVirtualFile(); + if (validNotNull(virtualFile)) return virtualFile.getPresentableUrl(); + return myFile.getName(); + } + + public String getName() { + return myFile.getName(); + } + + public String getComment() { + PsiDirectory directory = myFile.getContainingDirectory(); + if (directory == null) return ""; + return ElementPresentation.forElement(directory).getQualifiedName(); + } + } + + public static class ForPackage extends ElementPresentation { + private final PsiPackage myPsiPackage; + + public ForPackage(PsiPackage psiPackage) { + super(Noun.PACKAGE); + myPsiPackage = psiPackage; + } + + public String getQualifiedName() { + String qualifiedName = myPsiPackage.getQualifiedName(); + if (qualifiedName.length() == 0) return ""; + return qualifiedName; + } + + public String getName() { + return getQualifiedName(); + } + + public String getComment() { + return ""; + } + } + + private static class ForAnonymousClass extends ElementPresentation { + private final PsiAnonymousClass myPsiAnonymousClass; + + public ForAnonymousClass(PsiAnonymousClass psiAnonymousClass) { + super(Noun.FRAGMENT); + myPsiAnonymousClass = psiAnonymousClass; + } + + public String getQualifiedName() { + PsiClass psiClass = PsiTreeUtil.getParentOfType(myPsiAnonymousClass, PsiClass.class); + if (psiClass != null) return "Anonymous in " + forElement(psiClass).getQualifiedName(); + return "Anonymous class"; + } + + public String getName() { + return getQualifiedName(); + } + + public String getComment() { + return ""; + } + } + + private static class ForClass extends ElementPresentation { + private final PsiClass myPsiClass; + + public ForClass(PsiClass psiClass) { + super(Noun.CLASS); + myPsiClass = psiClass; + } + + public String getQualifiedName() { + return myPsiClass.getQualifiedName(); + } + + public String getName() { + return myPsiClass.getName(); + } + + public String getComment() { + PsiPackage psiPackage = myPsiClass.getContainingFile().getContainingDirectory().getPackage(); + if (psiPackage == null) return ""; + return forElement(psiPackage).getQualifiedName(); + } + } + + private static class ForMethod extends ElementPresentation { + private static final int FQ_OPTIONS = PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_FQ_NAME | PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_PARAMETERS; + private static final int NAME_OPTIONS = PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS; + private final PsiMethod myPsiMethod; + + public ForMethod(PsiMethod psiMethod) { + super(Noun.METHOD); + myPsiMethod = psiMethod; + } + + public String getQualifiedName() { + return PsiFormatUtil.formatMethod(myPsiMethod, PsiSubstitutor.EMPTY, FQ_OPTIONS, PsiFormatUtil.SHOW_TYPE); + } + + public String getName() { + return PsiFormatUtil.formatMethod(myPsiMethod, PsiSubstitutor.EMPTY, NAME_OPTIONS, PsiFormatUtil.SHOW_TYPE); + } + + public String getComment() { + PsiClass containingClass = myPsiMethod.getContainingClass(); + if (containingClass == null) return ""; + return forElement(containingClass).getComment(); + } + } + + private static class ForField extends ElementPresentation { + private final PsiField myPsiField; + + public ForField(PsiField psiField) { + super(Noun.FIELD); + myPsiField = psiField; + } + + public String getQualifiedName() { + PsiClass psiClass = myPsiField.getContainingClass(); + String name = myPsiField.getName(); + if (psiClass != null) return forElement(psiClass).getQualifiedName() + "." + name; + else return name; + } + + public String getName() { + PsiClass psiClass = myPsiField.getContainingClass(); + String name = myPsiField.getName(); + if (psiClass == null) return name; + return forElement(psiClass).getName() + "." + name; + } + + public String getComment() { + PsiClass psiClass = myPsiField.getContainingClass(); + if (psiClass == null) return ""; + return forElement(psiClass).getComment(); + } + } + + private static class ForGeneralElement extends ElementPresentation { + private final PsiElement myPsiElement; + + public ForGeneralElement(PsiElement psiElement) { + super(Noun.FRAGMENT); + myPsiElement = psiElement; + } + + public String getQualifiedName() { + PsiFile containingFile = myPsiElement.getContainingFile(); + if (containingFile != null) return "Code from " + forElement(containingFile).getQualifiedName(); + return "Code"; + } + + public String getName() { + return getQualifiedName(); + } + + public String getComment() { + return ""; + } + } + + private static class ForXmlTag extends ElementPresentation { + private final XmlTag myXmlTag; + + public ForXmlTag(XmlTag xmlTag) { + super(Noun.XML_TAG); + myXmlTag = xmlTag; + } + + public String getQualifiedName() { + return "<" + myXmlTag.getLocalName() + ">"; + } + + public String getName() { + return getQualifiedName(); + } + + public String getComment() { + return ""; + } + } + + private static class ForVirtualFile extends ElementPresentation { + private final VirtualFile myFile; + + public ForVirtualFile(VirtualFile file) { + super(file.isDirectory() ? Noun.DIRECTORY : Noun.FILE); + myFile = file; + } + + public String getComment() { + String name = myFile.getName(); + if (!myFile.isValid()) return name; + VirtualFile parent = myFile.getParent(); + if (parent == null) return name; + return parent.getPresentableUrl(); + } + + public String getName() { + return myFile.getName(); + } + + public String getQualifiedName() { + if (!myFile.isValid()) return myFile.getName(); + return myFile.getPresentableUrl(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/CellEditorComponentWithBrowseButton.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/CellEditorComponentWithBrowseButton.java new file mode 100644 index 00000000000..3b15062aabe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/CellEditorComponentWithBrowseButton.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.util.ui; + +import com.intellij.openapi.ui.ComponentWithBrowseButton; + +import javax.swing.*; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ChangeEvent; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +/** + * @author dyoma + */ +public class CellEditorComponentWithBrowseButton extends JPanel { + private final ComponentWithBrowseButton myComponent; + private final TableCellEditor myEditor; + private final CellEditorListener myCellEditorListener = new CellEditorListener() { + public void editingCanceled(ChangeEvent e) { + onEditingFinished(); + } + + public void editingStopped(ChangeEvent e) { + onEditingFinished(); + } + }; + private boolean myEditingFinished = false; + + public CellEditorComponentWithBrowseButton(ComponentWithBrowseButton component, TableCellEditor editor) { + super(new BorderLayout()); + myComponent = component; + myEditor = editor; + add(myComponent, BorderLayout.CENTER); + registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myEditor.stopCellEditing(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myEditor.cancelCellEditing(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + public ComponentWithBrowseButton getComponentWithButton() { + return myComponent; + } + + public Comp getChildComponent() { + return getComponentWithButton().getChildComponent(); + } + + public void requestFocus() { + myComponent.getChildComponent().requestFocus(); + } + + public void setNextFocusableComponent(Component aComponent) { + myComponent.getChildComponent().setNextFocusableComponent(aComponent); + } + + public void addNotify() { + super.addNotify(); + myEditingFinished = false; + myEditor.addCellEditorListener(myCellEditorListener); + } + + public void removeNotify() { + if (!myEditingFinished) { + myEditor.stopCellEditing(); + myEditingFinished = true; + } + super.removeNotify(); + } + + private void onEditingFinished() { + myEditor.removeCellEditorListener(myCellEditorListener); + myEditingFinished = true; + } + + private KeyEvent myCurrentEvent = null; + protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { + if (condition == WHEN_FOCUSED && myCurrentEvent != e) + try { + myCurrentEvent = e; + myComponent.getChildComponent().dispatchEvent(e); + } + finally { + myCurrentEvent = null; + } + if (e.isConsumed()) return true; + return super.processKeyBinding(ks, e, condition, pressed); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/tree/TreeModelAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/tree/TreeModelAdapter.java new file mode 100644 index 00000000000..8f86e7d07d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/util/ui/tree/TreeModelAdapter.java @@ -0,0 +1,21 @@ +package com.intellij.util.ui.tree; + +import javax.swing.event.TreeModelListener; +import javax.swing.event.TreeModelEvent; + +/** + * @author dyoma + */ +public abstract class TreeModelAdapter implements TreeModelListener { + public void treeNodesChanged(TreeModelEvent e) { + } + + public void treeNodesInserted(TreeModelEvent e) { + } + + public void treeNodesRemoved(TreeModelEvent e) { + } + + public void treeStructureChanged(TreeModelEvent e) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlAction.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlAction.java new file mode 100644 index 00000000000..287c01efdca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlAction.java @@ -0,0 +1,64 @@ +package com.intellij.xml.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlFile; + +/** + * @author mike + */ +public class ValidateXmlAction extends AnAction /*extends BaseCodeInsightAction*/ { + public ValidateXmlAction() { + } + + protected CodeInsightActionHandler getHandler(Project project) { + ValidateXmlActionHandler handler = new ValidateXmlActionHandler(true); + handler.setErrorReporter(handler.new StdErrorReporter(project)); + return handler; + } + + public void actionPerformed(AnActionEvent e) { + final PsiFile psiFile = (PsiFile) e.getDataContext().getData(DataConstants.PSI_FILE); + if (psiFile == null) return; + final Project project = psiFile.getProject(); + CommandProcessor.getInstance().executeCommand( + project, new Runnable(){ + public void run(){ + final Runnable action = new Runnable() { + public void run() { + getHandler(project).invoke(project, null, psiFile); + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, + getCommandName(), + null + ); + } + + private String getCommandName(){ + String text = getTemplatePresentation().getText(); + return text != null ? text : ""; + } + + public void update(AnActionEvent event) { + super.update(event); + + Presentation presentation = event.getPresentation(); + PsiElement psiElement = (PsiElement)event.getDataContext().getData(DataConstants.PSI_FILE); + + boolean flag = psiElement instanceof XmlFile; + presentation.setVisible(flag); + boolean value = psiElement instanceof XmlFile; + presentation.setEnabled(value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlActionHandler.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlActionHandler.java new file mode 100644 index 00000000000..2f8784f179f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/actions/ValidateXmlActionHandler.java @@ -0,0 +1,402 @@ +package com.intellij.xml.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.peer.PeerFactory; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.*; +import com.intellij.ui.content.*; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; +import com.intellij.xml.util.XmlResourceResolver; +import org.apache.xerces.impl.Constants; +import org.apache.xerces.jaxp.JAXPConstants; +import org.apache.xerces.jaxp.SAXParserFactoryImpl; +import org.apache.xerces.util.XMLGrammarPoolImpl; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.swing.*; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.StringReader; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Mike + */ +public class ValidateXmlActionHandler implements CodeInsightActionHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.xml.actions.ValidateXmlAction"); + private static final Key KEY = Key.create("ErrorTreeViewPanel.KEY"); + private static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking"; + private static final String GRAMMAR_FEATURE_ID = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; + private static final Key GRAMMARS_KEY = Key.create("ErrorTreeViewPanel.KEY"); + + private Project myProject; + private XmlFile myFile; + private ErrorReporter myErrorReporter; + private Object myParser; + private XmlResourceResolver myXmlResourceResolver; + private boolean forceChecking; + + public ValidateXmlActionHandler(boolean _forceChecking) { + forceChecking = _forceChecking; + } + + public void setErrorReporter(ErrorReporter errorReporter) { + myErrorReporter = errorReporter; + } + + public abstract class ErrorReporter { + public abstract void processError(SAXParseException ex,boolean warning); + + public boolean filterValidationException(Exception ex) { + if (ex instanceof ProcessCanceledException) throw (ProcessCanceledException)ex; + return false; + } + + public void startProcessing() { + doParse(); + } + } + + private static String buildMessageString(SAXParseException ex) { + return "(" + ex.getLineNumber() + ":" + ex.getColumnNumber() + ") " +ex.getMessage(); + } + + public class TestErrorReporter extends ErrorReporter { + private ArrayList errors = new ArrayList(3); + + public void processError(SAXParseException ex, boolean warning) { + errors.add(buildMessageString(ex)); + } + + public List getErrors() { + return errors; + } + } + + class StdErrorReporter extends ErrorReporter { + private NewErrorTreeViewPanel myErrorsView; + private static final String CONTENT_NAME = "Validate"; + private boolean myErrorsDetected = false; + + StdErrorReporter(Project project) { + myErrorsView = new NewErrorTreeViewPanel(project, null); + } + public void startProcessing() { + final Thread thread = new Thread(new Runnable() { + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + StdErrorReporter.super.startProcessing(); + } + }); + + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + if (!myErrorsDetected) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + removeCompileContents(null); + WindowManager.getInstance().getStatusBar(myProject).setInfo("No errors detected"); + } + } + ); + } + } + } + ); + } + }, "Validate XML"); + myErrorsView.setProcessController(new NewErrorTreeViewPanel.ProcessController() { + public void stopProcess() { + if (thread != null) { + thread.stop(); + } + } + + public boolean isProcessStopped() { + return thread == null || !thread.isAlive(); + } + }); + openMessageView(); + thread.start(); + + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW).activate(null); + } + + private void openMessageView() { + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand( + myProject, new Runnable() { + public void run() { + MessageView messageView = myProject.getComponent(MessageView.class); + Content content = PeerFactory.getInstance().getContentFactory().createContent(myErrorsView.getComponent(), CONTENT_NAME, true); + content.putUserData(KEY, myErrorsView); + messageView.addContent(content); + messageView.setSelectedContent(content); + messageView.addContentManagerListener(new CloseListener(content, messageView)); + removeCompileContents(content); + } + }, + "Open message view", + null + ); + } + private void removeCompileContents(Content notToRemove) { + MessageView messageView = myProject.getComponent(MessageView.class); + Content[] contents = messageView.getContents(); + for (int i = 0; i < contents.length; i++) { + Content content = contents[i]; + if (content.isPinned()) continue; + if (CONTENT_NAME.equals(content.getDisplayName()) && content != notToRemove) { + ErrorTreeView listErrorView = (ErrorTreeView)content.getComponent(); + if (listErrorView != null) { + if (messageView.removeContent(content)) { + content.release(); + } + } + } + } + } + + public void processError(final SAXParseException ex, final boolean warning) { + String error = buildMessageString(ex); + if (LOG.isDebugEnabled()) { + LOG.debug("enter: processError(error='" + error + "')"); + } + + myErrorsDetected = true; + + if (!ApplicationManager.getApplication().isUnitTestMode()) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + myErrorsView.addMessage( + warning ? MessageCategory.WARNING : MessageCategory.ERROR, + new String[]{ex.getLocalizedMessage()}, + myFile.getVirtualFile(), + ex.getLineNumber(), + ex.getColumnNumber(), null); + } + } + ); + } + } + + private class CloseListener extends ContentManagerAdapter { + private Content myContent; + private ContentManager myContentManager; + + public CloseListener(Content content, ContentManager contentManager) { + myContent = content; + myContentManager = contentManager; + } + + public void contentRemoved(ContentManagerEvent event) { + if (event.getContent() == myContent) { + myErrorsView.stopProcess(); + + myContentManager.removeContentManagerListener(this); + myContent.release(); + myContent = null; + } + } + + public void contentRemoveQuery(ContentManagerEvent event) { + if (event.getContent() == myContent) { + if (!myErrorsView.isProcessStopped()) { + int result = Messages.showYesNoDialog( + "Validation is running. Terminate it?", + "Validation Is Running", + Messages.getQuestionIcon() + ); + if (result != 0) { + event.consume(); + } + } + } + } + } + } + + public void invoke(Project project, Editor editor, PsiFile file) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + doValidate(project,file); + } + + public void doValidate(Project project, PsiFile file) { + myProject = project; + myFile = (XmlFile)file; + + myXmlResourceResolver = new XmlResourceResolver(myFile, myProject); + + try { + myParser = createParser(); + + if (myParser == null) return; + + myErrorReporter.startProcessing(); + } + catch (Exception exception) { + filterAppException(exception); + } + } + + private void filterAppException(Exception exception) { + if (!myErrorReporter.filterValidationException(exception)) { + LOG.error(exception); + } + } + + public boolean startInWriteAction() { + return true; + } + + private void doParse() { + try { + if (myParser instanceof SAXParser) { + SAXParser parser = (SAXParser)myParser; + + try { + parser.parse(new InputSource(new StringReader(myFile.getText())), new DefaultHandler() { + public void warning(SAXParseException e) { + myErrorReporter.processError(e, true); + } + + public void error(SAXParseException e) { + myErrorReporter.processError(e, false); + } + + public void fatalError(SAXParseException e) { + myErrorReporter.processError(e, false); + } + + public InputSource resolveEntity(String publicId, String systemId) { + final PsiFile psiFile = myXmlResourceResolver.resolve(null, systemId); + if (psiFile == null) return null; + return new InputSource(new StringReader(psiFile.getText())); + } + + public void startDocument() throws SAXException { + super.startDocument(); + ((SAXParser)myParser).setProperty( + "http://apache.org/xml/properties/internal/entity-resolver", + myXmlResourceResolver + ); + } + }); + } + catch (SAXException e) { + LOG.debug(e); +// processError(e.getMessage(), false, 0, 0); + } catch(UnknownHostException ex) { + LOG.debug(ex); + } + } + else { + LOG.error("unknown parser: " + myParser); + } + } + catch (Exception exception) { + filterAppException(exception); + } + } + + private Object createParser() { + try { + if (!needsDtdChecking() && !needsSchemaChecking() && !forceChecking) { + return null; + } + + SAXParserFactory factory = new SAXParserFactoryImpl(); + boolean schemaChecking = false; + + if (hasDtdDeclaration()) { + factory.setValidating(true); + } else if (needsSchemaChecking()) { + factory.setValidating(true); + factory.setNamespaceAware(true); + schemaChecking = true; + } + SAXParser parser = factory.newSAXParser(); + + parser.setProperty("http://apache.org/xml/properties/internal/entity-resolver", myXmlResourceResolver); + XMLGrammarPoolImpl myGrammarPool = myFile.getUserData(GRAMMARS_KEY); + + if (myGrammarPool==null) { + myGrammarPool = new XMLGrammarPoolImpl(); + myFile.putUserData(GRAMMARS_KEY,myGrammarPool); + } + parser.getXMLReader().setProperty(GRAMMAR_FEATURE_ID, myGrammarPool); + + if (schemaChecking) { + parser.setProperty(JAXPConstants.JAXP_SCHEMA_LANGUAGE,JAXPConstants.W3C_XML_SCHEMA); + parser.getXMLReader().setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true); + // bug in Xerces 2.6.2, http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14217 + // parser.getXMLReader().setFeature("http://apache.org/xml/features/validation/warn-on-undeclared-elemdef",Boolean.TRUE); + //setupSchemas(parser); + } + + return parser; + } + catch (Exception e) { + filterAppException(e); + } + + return null; + } + + private boolean hasDtdDeclaration() { + XmlDocument document = myFile.getDocument(); + if (document == null) return false; + XmlProlog prolog = document.getProlog(); + if (prolog == null) return false; + XmlDoctype doctype = prolog.getDoctype(); + if (doctype == null) return false; + + return true; + } + + private boolean needsDtdChecking() { + XmlDocument document = myFile.getDocument(); + if (document == null) return false; + + return (document.getProlog()!=null && document.getProlog().getDoctype()!=null); + } + + private boolean needsSchemaChecking() { + XmlDocument document = myFile.getDocument(); + if (document == null) return false; + XmlTag rootTag = document.getRootTag(); + if (rootTag == null) return false; + + XmlAttribute[] attributes = rootTag.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + XmlAttribute attribute = attributes[i]; + if (attribute.getName().startsWith("xmlns")) return true; + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java new file mode 100644 index 00000000000..ffb4d689495 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java @@ -0,0 +1,56 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Aug 27, 2002 + * Time: 9:55:06 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.xml.impl; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.XmlElement; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.openapi.fileTypes.StdFileTypes; + +public abstract class BasicXmlAttributeDescriptor implements XmlAttributeDescriptor { + public String validateValue(XmlElement context, String value) { + if (isFixed() && getDefaultValue() != null) { + String defaultValue = getDefaultValue(); + + if (!defaultValue.equals(value)) { + return "Attribute " + getName() + " should have fixed value " + defaultValue; + } + } + + if (isEnumerated()) { + String[] values = getEnumeratedValues(); + boolean valueWasFound = false; + + for (int i = 0; i < values.length; i++) { + String enumValue = values[i]; + + if (enumValue.equals(value)) { + valueWasFound = true; + break; + } + } + + if (!valueWasFound) { + return "Wrong attribute value"; + } + } + + return null; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return true; + } + + public String getName(PsiElement context){ + return getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlAttributeDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlAttributeDescriptorImpl.java new file mode 100644 index 00000000000..94ad42fcd51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlAttributeDescriptorImpl.java @@ -0,0 +1,102 @@ +package com.intellij.xml.impl.dtd; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.xml.XmlAttributeDecl; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.impl.BasicXmlAttributeDescriptor; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Mike + */ +public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor { + private XmlAttributeDecl myDecl; + private boolean required; + private String myName; + + public XmlAttributeDescriptorImpl() { + + } + public XmlAttributeDescriptorImpl(XmlAttributeDecl decl) { + init(decl); + } + + public boolean isRequired() { + return required; + } + + public PsiElement getDeclaration(){ + return myDecl; + } + + public String getName() { + if (myName!=null) { + return myName; + } + myName = myDecl.getNameElement().getText(); + return myName; + } + + public void init(PsiElement element){ + myDecl = (XmlAttributeDecl) element; + required = myDecl.isAttributeRequired(); + } + + public Object[] getDependences(){ + return new Object[]{myDecl}; + } + + public boolean isFixed() { + return myDecl.isAttributeFixed(); + } + + public boolean hasIdType() { + return myDecl.isIdAttribute(); + } + + public boolean hasIdRefType() { + return myDecl.isIdRefAttribute(); + } + + public String getDefaultValue() { + XmlAttributeValue value = myDecl.getDefaultValue(); + if (value != null) { + String text = value.getText(); + + return text.substring(1, text.length() - 1); + } + + return null; + } + + public boolean isEnumerated() { + return myDecl.isEnumerated(); + } + + public String[] getEnumeratedValues() { + List result = new ArrayList(); + + XmlElement[] values = myDecl.getEnumeratedValues(); + + for (int i = 0; i < values.length; i++) { + XmlElement value = values[i]; + result.add(value.getText()); + } + + return (String[])result.toArray(new String[result.size()]); + } + + public String getQualifiedName() { + return getName(); + } + + public String getDefaultName() { + return getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlElementDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlElementDescriptorImpl.java new file mode 100644 index 00000000000..4c815ca686a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlElementDescriptorImpl.java @@ -0,0 +1,252 @@ +package com.intellij.xml.impl.dtd; + +import com.intellij.j2ee.openapi.impl.ExternalResourceManagerImpl; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterElementProcessor; +import com.intellij.psi.search.PsiBaseElementProcessor; +import com.intellij.psi.xml.*; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * @author Mike + */ +public class XmlElementDescriptorImpl implements XmlElementDescriptor { + private XmlElementDecl myElementDecl; + private XmlAttlistDecl[] myAttlistDecl; + + public XmlElementDescriptorImpl(XmlElementDecl elementDecl) { + myElementDecl = elementDecl; + } + + public XmlElementDescriptorImpl() {} + + public PsiElement getDeclaration(){ + return myElementDecl; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + final ElementClassHint hint = processor.getHint(ElementClassHint.class); + final XmlTag tag = (XmlTag)context; + final PsiMetaData meta = tag.getMetaData(); + if(meta == null) + return true; + if(hint == null || hint.shouldProcess(XmlAttributeDecl.class)){ + final XmlAttlistDecl[] decls = getAttlistDecls(); + for(int i = 0; i < decls.length; i++){ + if(decls[i].getNameElement() != null && decls[i].getNameElement().getText().equals(meta.getName())){ + final XmlAttributeDecl[] attributes = decls[i].getAttributeDecls(); + for(int j = 0; j < attributes.length; j++){ + if(!processor.execute(attributes[j], substitutor)) return false; + } + } + } + } + if(hint == null || hint.shouldProcess(XmlElementDecl.class)){ + final XmlElementDescriptor[] decls = getElementsDescriptors(tag); + for(int i = 0; i < decls.length; i++){ + final XmlElementDescriptor decl = decls[i]; + if(!processor.execute(decl.getDeclaration(), substitutor)) return false; + } + } + + return true; + } + + public String getName(PsiElement context){ + return getName(); + } + + private String myName; + + public String getName() { + if (myName!=null) return myName; + return myName = myElementDecl.getNameElement().getText(); + } + + public void init(PsiElement element){ + myElementDecl = (XmlElementDecl) element; + } + + public Object[] getDependences(){ + return new Object[]{myElementDecl, ExternalResourceManagerImpl.getInstance()}; + } + + public XmlNSDescriptor getNSDescriptor() { + final PsiFile file = myElementDecl.getContainingFile(); + if(!(file instanceof XmlFile)) return null; + final XmlDocument document = ((XmlFile)file).getDocument(); + XmlNSDescriptor descriptor = (XmlNSDescriptor) document.getMetaData(); + if(descriptor == null){ + final XmlDoctype doctype = document.getProlog().getDoctype(); + if(doctype != null){ + if(doctype.getMarkupDecl() != null){ + descriptor = (XmlNSDescriptor)doctype.getMarkupDecl().getMetaData(); + } + } + } + return descriptor; + } + + private XmlElementDescriptor[] myElementDescriptors = null; + public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { + if(myElementDescriptors != null) return myElementDescriptors; + final List result = new ArrayList(); + + final XmlElementContentSpec contentSpecElement = myElementDecl.getContentSpecElement(); + final XmlNSDescriptor NSDescriptor = getNSDescriptor(); + if(!(NSDescriptor instanceof XmlNSDescriptorImpl)) return XmlElementDescriptor.EMPTY_ARRAY; + contentSpecElement.processElements(new PsiBaseElementProcessor(){ + public boolean execute(PsiElement child){ + if (child instanceof XmlToken) { + final XmlToken token = (XmlToken)child; + + if (token.getTokenType() == XmlTokenType.XML_NAME) { + final String text = child.getText(); + final XmlElementDescriptor element = ((XmlNSDescriptorImpl)NSDescriptor).getElementDescriptor(text); + + if (element != null) { + result.add(element); + } + } + else if (token.getTokenType() == XmlToken.XML_CONTENT_ANY) { + XmlElementDescriptor[] elements = ((XmlNSDescriptorImpl) NSDescriptor).getElements(); + result.addAll(Arrays.asList(elements)); + } + } + return true; + } + }, getDeclaration()); + + return myElementDescriptors = result.toArray(new XmlElementDescriptor[result.size()]); + } + + private XmlAttributeDescriptor[] myAttributeDescriptors; + + public XmlAttributeDescriptor[] getAttributesDescriptors() { + if (myAttributeDescriptors!=null) return myAttributeDescriptors; + + final List result = new ArrayList(); + final XmlAttlistDecl[] attlistDecls = findAttlistDecls(getName()); + + for (int i = 0; i < attlistDecls.length; i++) { + final XmlAttributeDecl[] attributeDecls = attlistDecls[i].getAttributeDecls(); + + for (int j = 0; j < attributeDecls.length; j++) { + result.add(attributeDecls[j].getMetaData()); + } + } + + myAttributeDescriptors = result.toArray(new XmlAttributeDescriptor[result.size()]); + return myAttributeDescriptors; + } + + private HashMap attributeDescriptorsMap; + + public XmlAttributeDescriptor getAttributeDescriptor(String attributeName) { + if (attributeDescriptorsMap==null) { + final XmlAttributeDescriptor[] xmlAttributeDescriptors = getAttributesDescriptors(); + attributeDescriptorsMap = new HashMap(xmlAttributeDescriptors.length); + + for (int i = 0; i < xmlAttributeDescriptors.length; i++) { + final XmlAttributeDescriptor xmlAttributeDescriptor = xmlAttributeDescriptors[i]; + + attributeDescriptorsMap.put(xmlAttributeDescriptor.getName(),xmlAttributeDescriptor); + } + } + + return attributeDescriptorsMap.get(attributeName); + } + + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attr){ + String name = attr.getName(); + //if (attr.getContainingFile().getFileType()==StdFileTypes.HTML) { + // name = name.toLowerCase(); + //} + return getAttributeDescriptor(name); + } + + private XmlAttlistDecl[] findAttlistDecls(String elementName) { + final List result = new ArrayList(); + + final XmlAttlistDecl[] decls = getAttlistDecls(); + + for (int i = 0; i < decls.length; i++) { + final XmlAttlistDecl decl = decls[i]; + final XmlElement nameElement = decl.getNameElement(); + if (nameElement != null && nameElement.textMatches(elementName)) { + result.add(decl); + } + } + + return result.toArray(new XmlAttlistDecl[result.size()]); + } + + private XmlAttlistDecl[] getAttlistDecls() { + if (myAttlistDecl != null) return myAttlistDecl; + + final List result = new ArrayList(); + ((XmlElement)getDeclaration().getParent()).processElements(new FilterElementProcessor(new ClassFilter(XmlAttlistDecl.class), result), getDeclaration()); + myAttlistDecl = (XmlAttlistDecl[])result.toArray(new XmlAttlistDecl[result.size()]); + return myAttlistDecl; + } + + public int getContentType() { + if (myElementDecl.getContentSpecElement().isAny()) { + return CONTENT_TYPE_ANY; + } + if (myElementDecl.getContentSpecElement().hasChildren()) { + return CONTENT_TYPE_CHILDREN; + } + if (myElementDecl.getContentSpecElement().isEmpty()) { + return CONTENT_TYPE_EMPTY; + } + if (myElementDecl.getContentSpecElement().isMixed()) { + return CONTENT_TYPE_MIXED; + } + + return CONTENT_TYPE_ANY; + } + + private HashMap elementDescriptorsMap; + + public XmlElementDescriptor getElementDescriptor(XmlTag element){ + String name = element.getName(); + if(name == null) return null; + //if (element.getContainingFile().getFileType()==StdFileTypes.HTML) { + // name = name.toLowerCase(); + //} + + if (elementDescriptorsMap==null) { + final XmlElementDescriptor[] descriptors = getElementsDescriptors(element); + elementDescriptorsMap = new HashMap(descriptors.length); + + for (int i = 0; i < descriptors.length; i++) { + final XmlElementDescriptor descriptor = descriptors[i]; + elementDescriptorsMap.put(descriptor.getName(),descriptor); + } + } + + return elementDescriptorsMap.get(name); + } + + public String getQualifiedName() { + return getName(); + } + + public String getDefaultName() { + return getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java new file mode 100644 index 00000000000..86db9d1edcf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java @@ -0,0 +1,138 @@ +package com.intellij.xml.impl.dtd; + +import com.intellij.j2ee.openapi.impl.ExternalResourceManagerImpl; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.scope.ElementClassHint; +import com.intellij.psi.scope.NameHint; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.processor.FilterElementProcessor; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlElementDecl; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; + +import java.util.*; + +/** + * @author Mike + */ +public class XmlNSDescriptorImpl implements XmlNSDescriptor { + private XmlElement myElement; + private XmlFile myDescriptorFile; + private CachedValue> myCachedDecls; + + public XmlNSDescriptorImpl() { + } + + public XmlNSDescriptorImpl(XmlElement element) { + init(element); + } + + public XmlFile getDescriptorFile() { + return myDescriptorFile; + } + + public boolean isHierarhyEnabled() { + return false; + } + + + private XmlElementDecl getElement(String elementName) { + return (XmlElementDecl)buildDeclarationMap().get(elementName).getDeclaration(); + } + + + public XmlElementDescriptor[] getElements() { + return buildDeclarationMap().values().toArray(XmlElementDescriptor.EMPTY_ARRAY); + } + + private Map buildDeclarationMap() { + if (myCachedDecls == null) { + myCachedDecls = myElement.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider>() { + public Result> compute() { + final List result = new ArrayList(); + myElement.processElements(new FilterElementProcessor(new ClassFilter(XmlElementDecl.class), result), getDeclaration()); + final Map ret = new LinkedHashMap((int)(result.size() * 1.5)); + final Iterator iterator = result.iterator(); + while(iterator.hasNext()){ + final XmlElementDecl xmlElementDecl = iterator.next(); + final XmlElement nameElement = xmlElementDecl.getNameElement(); + if(nameElement != null) { + String text = nameElement.getText(); + if (!ret.containsKey(text)) { + ret.put(text, new XmlElementDescriptorImpl(xmlElementDecl)); + } + } + } + return new Result>(ret, new Object[]{myDescriptorFile}); + } + }, false); + } + return myCachedDecls.getValue(); + } + + public XmlElementDescriptor getElementDescriptor(XmlTag tag) { + String name = tag.getName(); + return getElementDescriptor(name); + } + + public XmlElementDescriptor[] getRootElementsDescriptors() { + return getElements(); + } + + final XmlElementDescriptor getElementDescriptor(String name){ + return buildDeclarationMap().get(name); + } + + public PsiElement getDeclaration() { + return myElement; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + final ElementClassHint classHint = (ElementClassHint) processor.getHint(ElementClassHint.class); + final NameHint nameHint = (NameHint) processor.getHint(NameHint.class); + + if(classHint == null || classHint.shouldProcess(XmlElementDecl.class)){ + if(nameHint != null){ + final XmlElementDecl element = getElement(nameHint.getName()); + if(element != null) + return processor.execute(element, substitutor); + } + else{ + final Iterator iterator = buildDeclarationMap().values().iterator(); + while (iterator.hasNext()) { + if(!processor.execute(iterator.next().getDeclaration(), substitutor)) return false; + } + } + } + return true; + } + + public String getName(PsiElement context){ + return getName(); + } + + public String getName(){ + return myDescriptorFile.getName(); + } + + public void init(PsiElement element){ + myElement = (XmlElement)element; + myDescriptorFile = (XmlFile)element.getContainingFile(); + + if (myElement instanceof XmlFile) { + myElement = ((XmlFile)myElement).getDocument(); + } + } + + public Object[] getDependences(){ + return new Object[]{myElement, ExternalResourceManagerImpl.getInstance()}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlAttributeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlAttributeDescriptor.java new file mode 100644 index 00000000000..42cff8532bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlAttributeDescriptor.java @@ -0,0 +1,88 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Sep 30, 2002 + * Time: 9:46:52 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.XmlElement; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.util.ArrayUtil; + +class AnyXmlAttributeDescriptor implements XmlAttributeDescriptor { + private final String myAttributeName; + + public AnyXmlAttributeDescriptor(String attributeName) { + myAttributeName = attributeName; + } + + public PsiElement getDeclaration(){ + return null; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return true; + } + + public String getName(PsiElement context){ + return myAttributeName; + } + + public String getName() { + return myAttributeName; + } + + public void init(PsiElement element){ + } + + public Object[] getDependences(){ + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public String getQualifiedName() { + return myAttributeName; + } + + public String getDefaultName() { + return myAttributeName; + } + + public boolean isRequired() { + return false; + } + + public boolean isFixed() { + return false; + } + + public boolean hasIdType() { + return false; + } + + public boolean hasIdRefType() { + return false; + } + + public String getDefaultValue() { + return null; + } + + //todo: refactor to hierarchy of value descriptor? + public boolean isEnumerated() { + return false; + } + + public String[] getEnumeratedValues() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + public String validateValue(XmlElement context, String value) { + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlElementDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlElementDescriptor.java new file mode 100644 index 00000000000..0668eb5ce85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/AnyXmlElementDescriptor.java @@ -0,0 +1,88 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Sep 30, 2002 + * Time: 8:55:08 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.util.ArrayUtil; + +public class AnyXmlElementDescriptor implements XmlElementDescriptor { + private final XmlElementDescriptor myParentDescriptor; + private final XmlNSDescriptor myXmlNSDescriptor; + + public AnyXmlElementDescriptor(XmlElementDescriptor parentDescriptor, XmlNSDescriptor xmlNSDescriptor) { + myParentDescriptor = parentDescriptor; + myXmlNSDescriptor = xmlNSDescriptor; + } + + public XmlNSDescriptor getNSDescriptor() { + return myXmlNSDescriptor; + } + + public PsiElement getDeclaration(){ + return null; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return true; + } + + public String getName(PsiElement context){ + return getName(); + } + + public String getName() { + return myParentDescriptor.getName(); + } + + public void init(PsiElement element){ + } + + public Object[] getDependences(){ + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public String getQualifiedName() { + return myParentDescriptor.getQualifiedName(); + } + + public String getDefaultName() { + return myParentDescriptor.getDefaultName(); + } + + public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { + return myParentDescriptor.getElementsDescriptors(context); + } + + public XmlElementDescriptor getElementDescriptor(XmlTag tag){ + return myParentDescriptor.getElementDescriptor(tag); + } + + public XmlAttributeDescriptor[] getAttributesDescriptors() { + return new XmlAttributeDescriptor[0]; + } + + public XmlAttributeDescriptor getAttributeDescriptor(final String attributeName) { + return new AnyXmlAttributeDescriptor(attributeName); + } + + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attr){ + return myParentDescriptor.getAttributeDescriptor(attr); + } + + public int getContentType() { + return 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java new file mode 100644 index 00000000000..dcec0143fff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java @@ -0,0 +1,369 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; +import com.intellij.xml.impl.XmlLangAttributeDescriptor; + +import java.util.*; + +/** + * @author Mike + */ +public class ComplexTypeDescriptor extends TypeDescriptor { + private XmlNSDescriptorImpl myDocumentDescriptor; + private XmlTag myTag; + private XmlElementDescriptorImpl[] myElementDescriptors = null; + + public ComplexTypeDescriptor(XmlNSDescriptorImpl documentDescriptor, XmlTag tag) { + myDocumentDescriptor = documentDescriptor; + myTag = tag; + } + + public XmlTag getDeclaration(){ + return myTag; + } + + public XmlElementDescriptorImpl[] getElements() { + if(myElementDescriptors != null) return myElementDescriptors; + Map map = new LinkedHashMap(5); + collectElements(map, myTag, new HashSet()); + addSubstitutionGroups(map); + filterAbstractElements(map); + return myElementDescriptors = map.values().toArray( + new XmlElementDescriptorImpl[map.values().size()] + ); + } + + private void addSubstitutionGroups(Map result) { + mainLoop: while (true) { + for (Iterator iterator = result.values().iterator(); iterator.hasNext();) { + XmlElementDescriptorImpl descriptor = (XmlElementDescriptorImpl)iterator.next(); + + final XmlElementDescriptor[] substitutes = myDocumentDescriptor.getSubstitutes(descriptor.getName(), descriptor.getNamespace()); + boolean toContinue = false; + + for (int i = 0; i < substitutes.length; i++) { + XmlElementDescriptor substitute = substitutes[i]; + if (result.get(substitute.getName())==null) { + toContinue = true; + result.put(substitute.getName(),substitute); + } + } + + if (toContinue) continue mainLoop; + } + + break; + } + } + + private void filterAbstractElements(Map result) { + for (Iterator iterator = result.values().iterator(); iterator.hasNext();) { + XmlElementDescriptorImpl descriptor = (XmlElementDescriptorImpl)iterator.next(); + if (descriptor.isAbstract()) iterator.remove(); + } + } + + public XmlAttributeDescriptor[] getAttributes() { + List result = new ArrayList(); + collectAttributes(result, myTag, new ArrayList()); + + addStdAttributes(result); + + return result.toArray(new XmlAttributeDescriptor[result.size()]); + } + + private void addStdAttributes(List result) { + result.add(new XmlLangAttributeDescriptor()); + } + + private void collectElements(Map result, XmlTag tag, Set visited) { + if(visited.contains(tag)) return; + visited.add(tag); + if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "element")) { + String nameAttr = tag.getAttributeValue("name"); + + if (nameAttr != null) { + addElementDescriptor(result, new XmlElementDescriptorImpl(tag)); + } + else { + String ref = tag.getAttributeValue("ref"); + + if (ref != null) { + final String local = XmlUtil.findLocalNameByQualifiedName(ref); + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(ref); + final String namespace = "".equals(namespacePrefix) ? + myDocumentDescriptor.getDefaultNamespace() : + tag.getNamespaceByPrefix(namespacePrefix); + final XmlElementDescriptor element = myDocumentDescriptor.getElementDescriptor(local, namespace); + if (element != null) { + addElementDescriptor(result, element); + } + } + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "group")) { + String ref = tag.getAttributeValue("ref"); + + if (ref != null) { + XmlTag groupTag = myDocumentDescriptor.findGroup(ref); + + if (groupTag != null) { + XmlTag[] tags = groupTag.getSubTags(); + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectElements(result, subTag, visited); + } + } + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "restriction") || + XmlNSDescriptorImpl.equalsToSchemaName(tag, "extension")) { + String base = tag.getAttributeValue("base"); + + if (base != null) { + TypeDescriptor descriptor = myDocumentDescriptor.findTypeDescriptor( + myDocumentDescriptor.myFile.getDocument().getRootTag(), + base); + + if (descriptor instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor complexTypeDescriptor = (ComplexTypeDescriptor)descriptor; + complexTypeDescriptor.collectElements(result, complexTypeDescriptor.myTag, visited); + } + + XmlTag[] tags = tag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectElements(result, subTag, visited); + } + } + } + else { + XmlTag[] tags = tag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectElements(result, subTag, visited); + } + } + } + + private void addElementDescriptor(Map result, XmlElementDescriptor element) { + result.remove(element.getName()); + result.put(element.getName(),element); + } + + private void collectAttributes(List result, XmlTag tag, List visited) { + if(visited.contains(tag)) return; + visited.add(tag); + if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "element")) { + return; + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attribute")) { + String use = tag.getAttributeValue("use"); + String name = tag.getAttributeValue("name"); + + if (name != null) { + if ("prohibited".equals(use)) { + removeAttributeDescriptor(result, name); + } + else { + addAttributeDescriptor(result, tag); + } + } + else { + String ref = tag.getAttributeValue("ref"); + if (ref != null) { + if ("prohibited".equals(use)) { + removeAttributeDescriptor(result, ref); + } + else { + final String local = XmlUtil.findLocalNameByQualifiedName(ref); + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(ref); + final String namespace = "".equals(namespacePrefix) ? + myDocumentDescriptor.getDefaultNamespace() : + tag.getNamespaceByPrefix(namespacePrefix); + + final XmlAttributeDescriptorImpl attributeDescriptor = myDocumentDescriptor.getAttribute(local, namespace); + if (attributeDescriptor != null) { + if (use != null) { + attributeDescriptor.myUse = use; + } + addAttributeDescriptor(result, attributeDescriptor); + } + } + } + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attributeGroup")) { + String ref = tag.getAttributeValue("ref"); + + if (ref != null) { + XmlTag groupTag = myDocumentDescriptor.findAttributeGroup(ref); + + if (groupTag != null) { + XmlTag[] tags = groupTag.getSubTags(); + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectAttributes(result, subTag, visited); + } + } + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "restriction") || + XmlNSDescriptorImpl.equalsToSchemaName(tag, "extension")) { + String base = tag.getAttributeValue("base"); + + if (base != null) { + TypeDescriptor descriptor = myDocumentDescriptor.findTypeDescriptor( + myDocumentDescriptor.myFile.getDocument().getRootTag(), + base); + + if (descriptor instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor complexTypeDescriptor = (ComplexTypeDescriptor)descriptor; + complexTypeDescriptor.collectAttributes(result, complexTypeDescriptor.myTag, visited); + } + + XmlTag[] tags = tag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectAttributes(result, subTag, visited); + } + } + } + else { + XmlTag[] tags = tag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag subTag = tags[i]; + collectAttributes(result, subTag, visited); + } + } + } + + private void removeAttributeDescriptor(List result, String name) { + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + XmlAttributeDescriptorImpl attributeDescriptor = (XmlAttributeDescriptorImpl)iterator.next(); + + if (attributeDescriptor.getName().equals(name)) { + iterator.remove(); + } + } + } + + private void addAttributeDescriptor(List result, XmlTag tag) { + XmlAttributeDescriptorImpl descriptor = new XmlAttributeDescriptorImpl(tag); + addAttributeDescriptor(result, descriptor); + } + + private void addAttributeDescriptor(List result, XmlAttributeDescriptor descriptor) { + String name = descriptor.getName(); + + for (Iterator iterator = result.iterator(); iterator.hasNext();) { + XmlAttributeDescriptorImpl attributeDescriptor = (XmlAttributeDescriptorImpl)iterator.next(); + + if (attributeDescriptor.getName().equals(name)) { + iterator.remove(); + } + } + + result.add(descriptor); + } + + public boolean canContainTag(String localName, String namespace) { + return _canContainTag(localName, namespace, myTag); + } + + private boolean _canContainTag(String localName, String namespace, XmlTag tag) { + if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "any")) { + if ("##other".equals(tag.getAttributeValue("namespace"))) { + return !namespace.equals(myDocumentDescriptor.getDefaultNamespace()); + } + return true; + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "group")) { + String ref = tag.getAttributeValue("ref"); + + if (ref != null) { + XmlTag groupTag = myDocumentDescriptor.findGroup(ref); + if (groupTag != null && _canContainTag(localName, namespace, groupTag)) return true; + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "restriction") || + XmlNSDescriptorImpl.equalsToSchemaName(tag, "extension")) { + String base = tag.getAttributeValue("base"); + + if (base != null) { + TypeDescriptor descriptor = myDocumentDescriptor.findTypeDescriptor( + myDocumentDescriptor.myFile.getDocument().getRootTag(), + base); + + if (descriptor instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor complexTypeDescriptor = (ComplexTypeDescriptor)descriptor; + if (complexTypeDescriptor.canContainTag(localName, namespace)) return true; + } + } + } + + XmlTag[] subTags = tag.getSubTags(); + for (int i = 0; i < subTags.length; i++) { + XmlTag subTag = subTags[i]; + if (_canContainTag(localName, namespace, subTag)) return true; + } + + return false; + } + + public boolean canContainAttribute(String attributeName, String namespace) { + return _canContainAttribute(attributeName, namespace, myTag); + } + + private boolean _canContainAttribute(String name, String namespace, XmlTag tag) { + if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "anyAttribute")) { + String ns = tag.getAttributeValue("namespace"); + if ("##other".equals(ns)) { + return !namespace.equals(myDocumentDescriptor.getDefaultNamespace()); + } + return true; + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attributeGroup")) { + String ref = tag.getAttributeValue("ref"); + + if (ref != null) { + XmlTag groupTag = myDocumentDescriptor.findGroup(ref); + + if (groupTag != null) { + if (_canContainAttribute(name, namespace, groupTag)) return true; + } + } + } + else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "restriction") || + XmlNSDescriptorImpl.equalsToSchemaName(tag, "extension")) { + String base = tag.getAttributeValue("base"); + + if (base != null) { + TypeDescriptor descriptor = myDocumentDescriptor.findTypeDescriptor( + myDocumentDescriptor.myFile.getDocument().getRootTag(), + base); + + if (descriptor instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor complexTypeDescriptor = (ComplexTypeDescriptor)descriptor; + if (complexTypeDescriptor.canContainAttribute(name, namespace)) return true; + } + } + } + + XmlTag[] subTags = tag.getSubTags(); + for (int i = 0; i < subTags.length; i++) { + XmlTag subTag = subTags[i]; + if (_canContainAttribute(name, namespace, subTag)) return true; + } + + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/SimpleTypeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/SimpleTypeDescriptor.java new file mode 100644 index 00000000000..34fcc30ecb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/SimpleTypeDescriptor.java @@ -0,0 +1,12 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.xml.XmlTag; + +/** + * @author Mike + */ +class SimpleTypeDescriptor extends TypeDescriptor { + public SimpleTypeDescriptor(XmlTag tag) { + super(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/StdTypeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/StdTypeDescriptor.java new file mode 100644 index 00000000000..24a97fd0b14 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/StdTypeDescriptor.java @@ -0,0 +1,12 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.xml.XmlTag; + +/** + * @author Mike + */ +class StdTypeDescriptor extends TypeDescriptor { + public StdTypeDescriptor(String name) { + super(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/TypeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/TypeDescriptor.java new file mode 100644 index 00000000000..7a93b03722b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/TypeDescriptor.java @@ -0,0 +1,9 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.xml.XmlTag; + +/** + * @author Mike + */ +public abstract class TypeDescriptor { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java new file mode 100644 index 00000000000..30dc080c8ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java @@ -0,0 +1,83 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.xml.impl.BasicXmlAttributeDescriptor; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.PsiElement; +import com.intellij.util.ArrayUtil; + +/** + * @author Mike + */ +public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor { + private XmlTag myTag; + String myUse; + + public XmlAttributeDescriptorImpl(XmlTag tag) { + myTag = tag; + myUse = myTag.getAttributeValue("use"); + } + + public XmlAttributeDescriptorImpl() {} + + public PsiElement getDeclaration(){ + return myTag; + } + + public String getName() { + return myTag.getAttributeValue("name"); + } + + public void init(PsiElement element){ + myTag = (XmlTag) element; + myUse = myTag.getAttributeValue("use"); + } + + public Object[] getDependences(){ + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public boolean isRequired() { + return "required".equals(myUse); + } + + public boolean isFixed() { + return myTag.getAttributeValue("fixed") != null; + } + + public boolean hasIdType() { + return false; + } + + public boolean hasIdRefType() { + return false; + } + + public String getDefaultValue() { + if (isFixed()) { + return myTag.getAttributeValue("fixed"); + } + + return myTag.getAttributeValue("default"); + } + + //todo: refactor to hierarchy of value descriptor? + public boolean isEnumerated() { + return false; + } + + public String[] getEnumeratedValues() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + + public String getDefaultName() { + final XmlTag rootTag = (((XmlFile) myTag.getContainingFile())).getDocument().getRootTag(); + if ("qualified".equals(rootTag.getAttributeValue("attributeFormDefault"))) { + // TODO: + return getName(); + } + return getName(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java new file mode 100644 index 00000000000..25239ce7dbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorByType.java @@ -0,0 +1,67 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.*; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; + +/** + * @author ik + */ +public class XmlElementDescriptorByType extends XmlElementDescriptorImpl { + private ComplexTypeDescriptor myType; + + public XmlElementDescriptorByType(XmlTag instanceTag, ComplexTypeDescriptor descriptor) { + myDescriptorTag = instanceTag; + myType = descriptor; + } + + public XmlElementDescriptorByType() {} + + public PsiElement getDeclaration(){ + return myDescriptorTag; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return true; + } + + public String getName(PsiElement context){ + return myDescriptorTag.getName(); + } + + public XmlNSDescriptor getNSDescriptor() { + if (NSDescriptor==null) { + final XmlFile file = (XmlFile) XmlUtil.getContainingFile(getType().getDeclaration()); + if(file == null) return null; + final XmlDocument document = file.getDocument(); + if(document == null) return null; + NSDescriptor = (XmlNSDescriptor)document.getMetaData(); + } + + return NSDescriptor; + } + + public ComplexTypeDescriptor getType() { + return myType; + } + + public String getDefaultName() { + XmlTag rootTag = ((XmlFile)getType().getDeclaration().getContainingFile()).getDocument().getRootTag(); + + if ("qualified".equals(rootTag.getAttributeValue("elementFormDefault"))) { + return getQualifiedName(); + } + + return getName(); + } + + public boolean isAbstract() { + return "true".equals(myDescriptorTag.getAttributeValue("abstract")); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java new file mode 100644 index 00000000000..3532d9514ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java @@ -0,0 +1,263 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.*; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; + +/** + * @author Mike + */ +public class XmlElementDescriptorImpl implements XmlElementDescriptor { + protected XmlTag myDescriptorTag; + protected XmlNSDescriptor NSDescriptor; + + public XmlElementDescriptorImpl(XmlTag descriptorTag) { + myDescriptorTag = descriptorTag; + } + + public XmlElementDescriptorImpl() {} + + public PsiElement getDeclaration(){ + return myDescriptorTag; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return true; + } + + public String getName(PsiElement context){ + String value = myDescriptorTag.getAttributeValue("name"); + if(context instanceof XmlElement){ + final String namespace = getNamespaceByContext(context); + final XmlTag tag = PsiTreeUtil.getParentOfType(context, XmlTag.class, false); + if(tag != null){ + final String namespacePrefix = tag.getPrefixByNamespace(namespace); + if(namespacePrefix != null && namespacePrefix.length() > 0) + value = namespacePrefix + ":" + XmlUtil.findLocalNameByQualifiedName(value); + } + } + return value; + } + + /** getter for _local_ name */ + public String getName() { + return XmlUtil.findLocalNameByQualifiedName(getName(null)); + } + + public String getNamespaceByContext(PsiElement context){ + while(context != null){ + if(context instanceof XmlTag){ + final XmlTag contextTag = ((XmlTag)context); + final String typeAttr = contextTag.getAttributeValue("type", XmlUtil.XML_SCHEMA_INSTANCE_URI); + if(typeAttr != null) return contextTag.getNamespace(); + } + context = context.getContext(); + } + return getNamespace(); + } + + public String getNamespace(){ + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(getName(null)); + return "".equals(namespacePrefix) ? + ((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() : + myDescriptorTag.getNamespaceByPrefix(namespacePrefix); + } + + public void init(PsiElement element){ + if (myDescriptorTag!=element && myDescriptorTag!=null) { + NSDescriptor = null; + } + myDescriptorTag = (XmlTag) element; + } + + public Object[] getDependences(){ + return new Object[]{myDescriptorTag}; + } + + public XmlNSDescriptor getNSDescriptor() { + if (NSDescriptor==null) { + final XmlFile file = (XmlFile) XmlUtil.getContainingFile(getDeclaration()); + if(file == null) return null; + final XmlDocument document = file.getDocument(); + if(document == null) return null; + NSDescriptor = (XmlNSDescriptor)document.getMetaData(); + } + + return NSDescriptor; + } + + public TypeDescriptor getType() { + final XmlNSDescriptor nsDescriptor = getNSDescriptor(); + if (nsDescriptor == null) return null; + + TypeDescriptor type = ((XmlNSDescriptorImpl) nsDescriptor).getTypeDescriptor(myDescriptorTag); + if (type == null) { + String substAttr = myDescriptorTag.getAttributeValue("substitutionGroup"); + if (substAttr != null) { + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(substAttr); + final String namespace = "".equals(namespacePrefix) ? + ((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() : + myDescriptorTag.getNamespaceByPrefix(namespacePrefix); + final String local = XmlUtil.findLocalNameByQualifiedName(substAttr); + final XmlElementDescriptorImpl originalElement = (XmlElementDescriptorImpl)((XmlNSDescriptorImpl)getNSDescriptor()).getElementDescriptor(local, namespace); + if (originalElement != null) { + type = originalElement.getType(); + } + } + } + return type; + } + + public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { + return getElementsDescriptors(); + } + + private XmlElementDescriptor[] getElementsDescriptors() { + TypeDescriptor type = getType(); + + if (type instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor typeDescriptor = (ComplexTypeDescriptor)type; + + return typeDescriptor.getElements(); + } + + return EMPTY_ARRAY; + } + + public XmlAttributeDescriptor[] getAttributesDescriptors() { + TypeDescriptor type = getType(); + + if (type instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor typeDescriptor = (ComplexTypeDescriptor)type; + return typeDescriptor.getAttributes(); + } + + return new XmlAttributeDescriptor[0]; + } + + public XmlAttributeDescriptor getAttributeDescriptor(String attributeName){ + final String localName = XmlUtil.findLocalNameByQualifiedName(attributeName); + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(attributeName); + final String namespace = "".equals(namespacePrefix) ? + ((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() : + myDescriptorTag.getNamespaceByPrefix(namespacePrefix); + + return getAttribute(localName, namespace); + } + + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute){ + return getAttributeDescriptor(attribute.getName()); + } + + public XmlAttributeDescriptor getAttribute(String attributeName, String namespace) { + XmlAttributeDescriptor[] descriptors = getAttributesDescriptors(); + + for (int i = 0; i < descriptors.length; i++) { + XmlAttributeDescriptor descriptor = descriptors[i]; + + if (descriptor.getName().equals(attributeName)) { + return descriptor; + } + } + + TypeDescriptor type = getType(); + if (type instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor descriptor = (ComplexTypeDescriptor)type; + if (descriptor.canContainAttribute(attributeName, namespace)) { + return new AnyXmlAttributeDescriptor(attributeName); + } + } + + return null; + } + + public int getContentType() { + TypeDescriptor type = getType(); + + if (type instanceof ComplexTypeDescriptor) { + return CONTENT_TYPE_CHILDREN; + } + + return CONTENT_TYPE_MIXED; + } + + public XmlElementDescriptor getElementDescriptor(final String name) { + final String localName = XmlUtil.findLocalNameByQualifiedName(name); + final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(name); + final String namespace = "".equals(namespacePrefix) ? + ((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() : + myDescriptorTag.getNamespaceByPrefix(namespacePrefix); + return getElementDescriptor(localName, namespace, null); + } + + protected XmlElementDescriptor getElementDescriptor(final String localName, final String namespace, XmlElement context) { + XmlElementDescriptor[] elements = getElementsDescriptors(); + + for (int i = 0; i < elements.length; i++) { + XmlElementDescriptorImpl element = (XmlElementDescriptorImpl) elements[i]; + if (element.getName().equals(localName) && element.getNamespaceByContext(context).equals(namespace)) { + return element; + } + } + + TypeDescriptor type = getType(); + if (type instanceof ComplexTypeDescriptor) { + ComplexTypeDescriptor descriptor = (ComplexTypeDescriptor)type; + if (descriptor.canContainTag(localName, namespace)) { + return new AnyXmlElementDescriptor(this, getNSDescriptor()); + } + } + + return null; + } + + public XmlElementDescriptor getElementDescriptor(XmlTag element){ + XmlElementDescriptor elementDescriptor = getElementDescriptor(element.getLocalName(), element.getNamespace(), (XmlElement)element.getParent()); + if(elementDescriptor == null){ + final String type = element.getAttributeValue("type", XmlUtil.XML_SCHEMA_INSTANCE_URI); + if(type != null){ + final String namespaceByPrefix = element.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(type)); + final XmlNSDescriptor typeDecr = element.getNSDescriptor(namespaceByPrefix, false); + if(typeDecr instanceof XmlNSDescriptorImpl){ + final XmlNSDescriptorImpl schemaDescriptor = ((XmlNSDescriptorImpl)typeDecr); + final XmlElementDescriptor descriptorByType = schemaDescriptor.getDescriptorByType(type, element); + elementDescriptor = descriptorByType; + } + } + } + return elementDescriptor; + } + + public String getQualifiedName() { + if (!"".equals(getNS())) { + return getNS() + ":" + getName(); + } + + return getName(); + } + + private String getNS(){ + return XmlUtil.findNamespacePrefixByURI((XmlFile) myDescriptorTag.getContainingFile(), getNamespace()); + } + + public String getDefaultName() { + XmlTag rootTag = ((XmlFile)myDescriptorTag.getContainingFile()).getDocument().getRootTag(); + + if ("qualified".equals(rootTag.getAttributeValue("elementFormDefault"))) { + return getQualifiedName(); + } + + return getName(); + } + + public boolean isAbstract() { + return "true".equals(myDescriptorTag.getAttributeValue("abstract")); + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java new file mode 100644 index 00000000000..96d6392d862 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java @@ -0,0 +1,484 @@ +package com.intellij.xml.impl.schema; + +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.xml.*; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; + +import java.util.*; + +/** + * @author Mike + */ +public class XmlNSDescriptorImpl implements XmlNSDescriptor { + private static final Set STD_TYPES = new HashSet(); + XmlFile myFile; + private String myTargetNamespace; + + public XmlNSDescriptorImpl(XmlFile file) { + init(file.getDocument()); + } + + public XmlNSDescriptorImpl() { + } + + public XmlFile getDescriptorFile() { + return myFile; + } + + public boolean isHierarhyEnabled() { + return true; + } + + public String getDefaultNamespace(){ + return myTargetNamespace != null ? myTargetNamespace : ""; + } + + private final Map, CachedValue> myDescriptorsMap = new HashMap, CachedValue>(); + private final Map, CachedValue> myTypesMap = new HashMap, CachedValue>(); + + public XmlElementDescriptor getElementDescriptor(String localName, String namespace) { + return getElementDescriptor(localName, namespace, new HashSet()); + } + + private XmlElementDescriptor getElementDescriptor(String localName, String namespace, Set visited) { + if(visited.contains(this)) return null; + final Pair pair = new Pair(namespace, localName); + final CachedValue descriptor = myDescriptorsMap.get(pair); + if(descriptor != null) return descriptor.getValue(); + XmlDocument document = myFile.getDocument(); + XmlTag rootTag = document.getRootTag(); + if (rootTag == null) return null; + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + final XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag, "element")) { + String name = tag.getAttributeValue("name"); + + if (name != null) { + if(checkElementNameEquivalence(localName, namespace, name, tag)) { + final CachedValue cachedValue = tag.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public Result compute() { + final XmlElementDescriptorImpl xmlElementDescriptor = new XmlElementDescriptorImpl(tag); + return new Result(xmlElementDescriptor, xmlElementDescriptor.getDependences()); + } + },false); + myDescriptorsMap.put(pair, cachedValue); + return cachedValue.getValue(); + } + } + } + else if (equalsToSchemaName(tag, "include")) { + final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation", XmlUtil.ALL_NAMESPACE); + if (schemaLocation != null) { + final XmlFile xmlFile = XmlUtil.findXmlFile(rootTag.getContainingFile(), schemaLocation.getValue()); + if (xmlFile != null) { + final XmlDocument includedDocument = xmlFile.getDocument(); + if (includedDocument != null) { + final PsiMetaData data = includedDocument.getMetaData(); + if(data instanceof XmlNSDescriptorImpl){ + final XmlElementDescriptor elementDescriptor = ((XmlNSDescriptorImpl)data).getElementDescriptor(localName, namespace); + if(elementDescriptor != null){ + final CachedValue value = includedDocument.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider(){ + public Result compute() { + return new Result(elementDescriptor, elementDescriptor.getDependences()); + } + },false); + return value.getValue(); + } + } + } + } + } + } + } + + return null; + } + + private boolean checkElementNameEquivalence(String localName, String namespace, String fqn, XmlTag context){ + final String localAttrName = XmlUtil.findLocalNameByQualifiedName(fqn); + if (!localAttrName.equals(localName)) return false; + if(myTargetNamespace == null){ + final String attrNamespace = context.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(fqn)); + if(attrNamespace.equals(namespace)) + return true; + } + else return myTargetNamespace.equals(namespace); + return false; + } + + protected XmlAttributeDescriptorImpl getAttribute(String localName, String namespace) { + XmlDocument document = myFile.getDocument(); + XmlTag rootTag = document.getRootTag(); + if (rootTag == null) return null; + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag, "attribute")) { + String name = tag.getAttributeValue("name"); + + if (name != null) { + if (checkElementNameEquivalence(localName, namespace, name, tag)) { + return new XmlAttributeDescriptorImpl(tag); + } + } + } + } + + return null; + } + + protected TypeDescriptor getTypeDescriptor(XmlTag descriptorTag) { + String type = descriptorTag.getAttributeValue("type"); + + if (type != null) { + return getTypeDescriptor(type, descriptorTag); + } + + return findTypeDescriptor(descriptorTag, null); + } + + protected TypeDescriptor getTypeDescriptor(final String name, XmlTag context) { + if(checkSchemaNamespace(name, context) && STD_TYPES.contains(name)){ + return new StdTypeDescriptor(name); + } + + final XmlDocument document = myFile.getDocument(); + if (document == null) return null; + return findTypeDescriptor(document.getRootTag(), name); + } + + public XmlElementDescriptor getDescriptorByType(String qName, XmlTag instanceTag){ + final XmlDocument document = myFile.getDocument(); + if(document == null) return null; + final XmlTag tag = document.getRootTag(); + if(tag == null) return null; + final TypeDescriptor typeDescriptor = findTypeDescriptor(tag, qName); + if(!(typeDescriptor instanceof ComplexTypeDescriptor)) return null; + return new XmlElementDescriptorByType(instanceTag, (ComplexTypeDescriptor)typeDescriptor); + } + + private boolean checkSchemaNamespace(String name, XmlTag context){ + final String namespace = context.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(name)); + if(namespace != null && namespace.length() > 0){ + return XmlUtil.XML_SCHEMA_URI.equals(namespace); + } + return "xsd".equals(XmlUtil.findPrefixByQualifiedName(name)); + } + + private static boolean checkSchemaNamespace(XmlTag context){ + final String namespace = context.getNamespace(); + if(namespace != null && namespace.length() > 0){ + return XmlUtil.XML_SCHEMA_URI.equals(namespace); + } + return context.getName().startsWith("xsd:"); + } + + + protected TypeDescriptor findTypeDescriptor(XmlTag rootTag, final String name) { + final Pair pair = new Pair(name, rootTag); + final CachedValue descriptor = myTypesMap.get(pair); + if(descriptor != null) return descriptor.getValue(); + + if (rootTag == null) return null; + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + final XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag, "complexType")) { + if (name == null) { + CachedValue value = createAndPutTypesCachedValue(tag, pair); + return value.getValue(); + } + + String nameAttribute = tag.getAttributeValue("name"); + + if (nameAttribute != null) { + if (nameAttribute.equals(name) || (name.indexOf(":") >= 0 && nameAttribute.equals(name.substring(name.indexOf(":") + 1)))) { + CachedValue cachedValue = createAndPutTypesCachedValue(tag, pair); + return cachedValue.getValue(); + } + } + } + else if (equalsToSchemaName(tag, "simpleType")) { + if (name == null) { + return new SimpleTypeDescriptor(tag); + } + + String nameAttribute = tag.getAttributeValue("name"); + + if (name.equals(nameAttribute) + || name.indexOf(":") >= 0 && name.substring(name.indexOf(":") + 1).equals(nameAttribute)) { + return new SimpleTypeDescriptor(tag); + } + } + else if (equalsToSchemaName(tag, "include")) { + final String schemaLocation = tag.getAttributeValue("schemaLocation"); + if (schemaLocation != null) { + final XmlFile xmlFile = XmlUtil.findXmlFile(rootTag.getContainingFile(), schemaLocation); + if (xmlFile != null) { + final XmlDocument document = xmlFile.getDocument(); + if (document != null) { + final XmlTag rTag = document.getRootTag(); + + final CachedValue value = tag.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public Result compute() { + final TypeDescriptor complexTypeDescriptor = findTypeDescriptor(rTag, name); + return new Result(complexTypeDescriptor, new Object[]{rTag}); + } + }, false); + if (value.getValue() != null) { + myTypesMap.put(pair, value); + return value.getValue(); + } + } + } + } + } + } + return null; + } + + private CachedValue createAndPutTypesCachedValue(final XmlTag tag, final Pair pair) { + final CachedValue value = tag.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + final ComplexTypeDescriptor complexTypeDescriptor = new ComplexTypeDescriptor(XmlNSDescriptorImpl.this, tag); + return new Result(complexTypeDescriptor, new Object[]{tag}); + } + }, false); + myTypesMap.put(pair, value); + return value; + } + + public XmlElementDescriptor getElementDescriptor(XmlTag tag) { + XmlElement parent = (XmlElement)tag.getParent(); + final String namespace = tag.getNamespace(); + while(parent instanceof XmlTag && !namespace.equals(((XmlTag)parent).getNamespace())) + parent = (XmlElement)parent.getContext(); + if (parent instanceof XmlTag) { + final XmlTag parentTag = (XmlTag)parent; + final XmlElementDescriptor parentDescriptor = getElementDescriptor(parentTag); + + if(parentDescriptor != null){ + return parentDescriptor.getElementDescriptor(tag); + } + else{ + return null; + } + } + else { + return getElementDescriptor(tag.getLocalName(), tag.getNamespace()); + } + } + + public XmlElementDescriptor[] getRootElementsDescriptors() { + final List result = new ArrayList(); + XmlDocument document = myFile.getDocument(); + XmlTag rootTag = document.getRootTag(); + if (rootTag == null) return null; + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag, "element")) { + String name = tag.getAttributeValue("name"); + + if (name != null) { + final XmlElementDescriptor elementDescriptor = getElementDescriptor(name, getDefaultNamespace()); + if(elementDescriptor != null) + result.add(elementDescriptor); + } + } + } + + return result.toArray(new XmlElementDescriptor[result.size()]); + } + + protected static boolean equalsToSchemaName(XmlTag tag, String schemaName) { + return schemaName.equals(tag.getLocalName()) && checkSchemaNamespace(tag); + } + + private static XmlTag findSpecialTag(String name, String specialName, XmlTag rootTag) { + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag, specialName)) { + String attribute = tag.getAttributeValue("name"); + + if (name.equals(attribute) + || name.indexOf(":") >= 0 && name.substring(name.indexOf(":") + 1).equals(attribute)) { + return tag; + } + } else if (equalsToSchemaName(tag,"include")) { + final String schemaLocation = tag.getAttributeValue("schemaLocation"); + + if (schemaLocation != null) { + final XmlFile xmlFile = XmlUtil.findXmlFile(rootTag.getContainingFile(), schemaLocation); + + if (xmlFile != null) { + final XmlDocument document = xmlFile.getDocument(); + if (document != null) { + final XmlTag rTag = findSpecialTag(name,specialName,document.getRootTag()); + + if (rTag != null) return rTag; + } + } + } + } + } + + return null; + } + + public XmlTag findGroup(String name) { + return findSpecialTag(name,"group",myFile.getDocument().getRootTag()); + } + + public XmlTag findAttributeGroup(String name) { + return findSpecialTag(name,"attributeGroup",myFile.getDocument().getRootTag()); + } + + private Map> substituions; + + public XmlElementDescriptor[] getSubstitutes(String localName, String namespace) { + List result = new ArrayList(); + + if (substituions==null) { + XmlDocument document = myFile.getDocument(); + substituions = new HashMap>(); + XmlTag rootTag = document.getRootTag(); + + XmlTag[] tags = rootTag.getSubTags(); + + for (int i = 0; i < tags.length; i++) { + XmlTag tag = tags[i]; + + if (equalsToSchemaName(tag,"element")) { + final String substAttr = tag.getAttributeValue("substitutionGroup"); + if (substAttr != null) { + String substLocalName = XmlUtil.findLocalNameByQualifiedName(substAttr); + List list = substituions.get(substLocalName); + if (list==null) { + list = new LinkedList(); + substituions.put(substLocalName,list); + } + list.add(tag); + } + } + } + } + + List substitutions = substituions.get(localName); + if (substitutions==null) return XmlElementDescriptor.EMPTY_ARRAY; + for (Iterator i=substitutions.iterator();i.hasNext();) { + XmlTag tag = i.next(); + + final String substAttr = tag.getAttributeValue("substitutionGroup"); + if (substAttr != null && checkElementNameEquivalence(localName, namespace, substAttr, tag)) { + result.add(new XmlElementDescriptorImpl(tag)); + } + } + + return result.toArray(new XmlElementDescriptor[result.size()]); + } + + public static String getSchemaNamespace(XmlFile file) { + return XmlUtil.findNamespacePrefixByURI(file, "http://www.w3.org/2001/XMLSchema"); + } + + public PsiElement getDeclaration(){ + return myFile.getDocument(); + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + return PsiScopesUtil.walkChildrenScopes(context, processor, substitutor, lastElement, place); + } + + public String getName(PsiElement context){ + return getName(); + } + + public String getName(){ + return ""; + } + + public void init(PsiElement element){ + myFile = (XmlFile) element.getContainingFile(); + + final XmlDocument document = myFile.getDocument(); + if (document != null) { + final XmlTag rootTag = document.getRootTag(); + if (rootTag != null) { + myTargetNamespace = rootTag.getAttributeValue("targetNamespace"); + } + } + } + + public Object[] getDependences(){ + return new Object[]{myFile, }; + } + + static { + STD_TYPES.add("string"); + STD_TYPES.add("normalizedString"); + STD_TYPES.add("token"); + STD_TYPES.add("byte"); + STD_TYPES.add("unsignedByte"); + STD_TYPES.add("base64Binary"); + STD_TYPES.add("hexBinary"); + STD_TYPES.add("integer"); + STD_TYPES.add("positiveInteger"); + STD_TYPES.add("negativeInteger"); + STD_TYPES.add("nonNegativeInteger"); + STD_TYPES.add("nonPositiveInteger"); + STD_TYPES.add("int"); + STD_TYPES.add("unsignedInt"); + STD_TYPES.add("long"); + STD_TYPES.add("unsignedLong"); + STD_TYPES.add("short"); + STD_TYPES.add("unsignedShort"); + STD_TYPES.add("decimal"); + STD_TYPES.add("float"); + STD_TYPES.add("double"); + STD_TYPES.add("boolean"); + STD_TYPES.add("time"); + STD_TYPES.add("dateTime"); + STD_TYPES.add("duration"); + STD_TYPES.add("date"); + STD_TYPES.add("gMonth"); + STD_TYPES.add("gYear"); + STD_TYPES.add("gYearMonth"); + STD_TYPES.add("gDay"); + STD_TYPES.add("gMonthDay"); + STD_TYPES.add("Name"); + STD_TYPES.add("QName"); + STD_TYPES.add("NCName"); + STD_TYPES.add("anyURI"); + STD_TYPES.add("language"); + STD_TYPES.add("ID"); + STD_TYPES.add("IDREF"); + STD_TYPES.add("IDREFS"); + STD_TYPES.add("ENTITY"); + STD_TYPES.add("ENTITIES"); + STD_TYPES.add("NOTATION"); + STD_TYPES.add("NMTOKEN"); + STD_TYPES.add("NMTOKENS"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/HtmlUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/HtmlUtil.java new file mode 100644 index 00000000000..fda23276126 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/HtmlUtil.java @@ -0,0 +1,122 @@ +package com.intellij.xml.util; + +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.documentation.HtmlDescriptorsTable; +import com.intellij.psi.xml.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.html.HtmlTag; +import java.util.*; +import gnu.trove.THashSet; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Sep 18, 2004 + * Time: 6:59:31 PM + * To change this template use File | Settings | File Templates. + */ +public class HtmlUtil { + private HtmlUtil() {} + private static final String EMPTY_TAGS[] = { "base","hr","meta","link","frame","br","basefont","param","img","area","input","isindex","col" }; + private static final Set EMPTY_TAGS_MAP = new THashSet(); + private static final String OPTIONAL_END_TAGS[] = { + //"html", + "head", + //"body", + "p", "li", "dd", "dt", "thead", "tfoot", "tbody", "colgroup", "tr", "th", "td", "option" + }; + private static final Set OPTIONAL_END_TAGS_MAP = new THashSet(); + + private static final String BLOCK_TAGS[] = { "p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "dir", "menu", "pre", + "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address", + // nonexplicitly specified + "map", + // flow elements + "body", "object", "applet", "ins", "del", "dd", "li", "button", "th", "td", "iframe" + }; + private static final Set BLOCK_TAGS_MAP = new THashSet(); + + private static final String INLINE_ELEMENTS_CONTAINER[] = { "p", "h1", "h2", "h3", "h4", "h5", "h6", "pre", "dt" }; + private static final Set INLINE_ELEMENTS_CONTAINER_MAP = new THashSet(); + + private static final String EMPTY_ATTRS[] = { "nowrap", "compact", "disabled", "readonly", "selected", "multiple", "nohref", "ismap", "declare", "noshade" }; + private static final Set EMPTY_ATTRS_MAP = new THashSet(); + + static { + for(int i=0;i variants) { + // add html block completions for tags with optional ends! + String name = descriptor.getName(element); + + if (isOptionalEndForHtmlTag(name)) { + PsiElement parent = element.getParent(); + + if (parent!=null) { + // we need grand parent since completion already uses parent's descriptor + parent = parent.getParent(); + } + + if (parent instanceof HtmlTag) { + final XmlElementDescriptor parentDescriptor = ((HtmlTag)parent).getDescriptor(); + + if (parentDescriptor!=descriptor && parentDescriptor!=null) { + final XmlElementDescriptor[] elementsDescriptors = parentDescriptor.getElementsDescriptors((XmlTag)parent); + for (int i = 0; i < elementsDescriptors.length; i++) { + final XmlElementDescriptor elementsDescriptor = elementsDescriptors[i]; + + if (isHtmlBlockTag(elementsDescriptor.getName())) { + variants.add(elementsDescriptor); + } + } + } + } + } + } + + public static String[] getHtmlTagNames() { + return HtmlDescriptorsTable.getHtmlTagNames(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlNSDescriptorSequence.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlNSDescriptorSequence.java new file mode 100644 index 00000000000..f03bded94a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlNSDescriptorSequence.java @@ -0,0 +1,137 @@ +package com.intellij.xml.util; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: ik + * Date: 08.09.2003 + * Time: 17:27:43 + * To change this template use Options | File Templates. + */ +public class XmlNSDescriptorSequence implements XmlNSDescriptor{ + final List sequence = new ArrayList(); + + public XmlNSDescriptorSequence(){ + } + + public XmlNSDescriptorSequence(XmlNSDescriptor[] descriptors){ + for(int i = 0; i < descriptors.length; i++){ + final XmlNSDescriptor descriptor = descriptors[i]; + add(descriptor); + } + } + + public void add(XmlNSDescriptor descriptor){ + sequence.add(descriptor); + } + + public XmlElementDescriptor getElementDescriptor(XmlTag tag){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + final XmlElementDescriptor elementDescriptor = descriptor.getElementDescriptor(tag); + if(elementDescriptor != null) return elementDescriptor; + } + return null; + } + + public XmlElementDescriptor[] getRootElementsDescriptors() { + final List descriptors = new ArrayList(); + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + descriptors.addAll(Arrays.asList(descriptor.getRootElementsDescriptors())); + } + + return descriptors.toArray(new XmlElementDescriptor[descriptors.size()]); + } + + public XmlFile getDescriptorFile(){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + final XmlFile file = descriptor.getDescriptorFile(); + if(file != null) return file; + } + return null; + } + + public boolean isHierarhyEnabled() { + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + if(descriptor.isHierarhyEnabled()) return true; + } + return false; + } + + public PsiElement getDeclaration(){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + final PsiElement declaration = descriptor.getDeclaration(); + if(declaration != null) return declaration; + } + return null; + } + + public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + if(!descriptor.processDeclarations(context, processor, substitutor, lastElement, place)) return false; + } + + return true; + } + + public String getName(PsiElement context){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + final String name = descriptor.getName(context); + if(name != null) return name; + } + return null; + } + + public String getName(){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + final String name = descriptor.getName(); + if(name != null) return name; + } + return null; + } + + public void init(PsiElement element){ + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + descriptor.init(element); + } + } + + public Object[] getDependences(){ + final List ret = new ArrayList(); + final Iterator iterator = sequence.iterator(); + while(iterator.hasNext()){ + final XmlNSDescriptor descriptor = (XmlNSDescriptor) iterator.next(); + ret.addAll(Arrays.asList(descriptor.getDependences())); + } + return ret.toArray(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlResourceResolver.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlResourceResolver.java new file mode 100644 index 00000000000..22c5c6f11ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlResourceResolver.java @@ -0,0 +1,130 @@ +package com.intellij.xml.util; + +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.util.Map; +import java.net.URL; +import java.net.MalformedURLException; + +import org.apache.xerces.xni.parser.XMLInputSource; +import org.apache.xerces.xni.parser.XMLEntityResolver; +import org.apache.xerces.xni.XMLResourceIdentifier; +import org.apache.xerces.xni.XNIException; + +/** + * Created by IntelliJ IDEA. + * User: Maxim.Mossienko + * Date: Aug 6, 2004 + * Time: 6:48:55 PM + * To change this template use File | Settings | File Templates. + */ +public class XmlResourceResolver implements XMLEntityResolver { + private static Logger LOG = Logger.getInstance("#com.intellij.xml.util.XmlResourceResolver"); + private XmlFile myFile; + private Project myProject; + + public XmlResourceResolver(XmlFile _xmlFile, Project _project) { + myFile = _xmlFile; + myProject = _project; + } + + public PsiFile resolve(final String baseSystemId, final String systemId) { + if (LOG.isDebugEnabled()) { + LOG.debug("enter: resolveEntity(baseSystemId='" + baseSystemId + "' systemId='" + systemId + "')"); + } + if (systemId == null) return null; + + final PsiFile[] result = new PsiFile[] { null }; + final Runnable action = new Runnable() { + public void run() { + PsiFile baseFile = null; + VirtualFile vFile = null; + + if (baseSystemId != null) { + baseFile = (XmlFile)resolve(null,baseSystemId); + + if (baseFile == null) { + File workingFile = new File(""); + String workingDir = workingFile.getAbsoluteFile().getAbsolutePath().replace(File.separatorChar, '/'); + String id = StringUtil.replace(baseSystemId, workingDir, myFile.getVirtualFile().getParent().getPath()); + vFile = VfsUtil.findRelativeFile(id, null); + + if (vFile == null) { + vFile = VfsUtil.findRelativeFile(baseSystemId, null); + + if (vFile == null) { + try { + vFile = VfsUtil.findFileByURL(new URL(baseSystemId)); + } catch(MalformedURLException ex) { + + } + } + } + } + + if (vFile != null) { + baseFile = PsiManager.getInstance(myProject).findFile(vFile); + } + } + if (baseFile == null) { + baseFile = myFile; + } + + PsiFile psiFile = XmlUtil.findXmlFile(baseFile, systemId); + + if (psiFile == null && baseSystemId!=null && baseFile!=null) { + String fullUrl = baseSystemId.substring( 0, baseSystemId.lastIndexOf('/') + 1 ) + systemId; + psiFile = XmlUtil.findXmlFile(baseFile,fullUrl); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("resolveEntity: psiFile='" + (psiFile != null ? psiFile.getVirtualFile() : null) + "'"); + } + result[0] = psiFile; + } + }; + ApplicationManager.getApplication().runReadAction(action); + + return result[0]; + } + + public XMLInputSource resolveEntity(XMLResourceIdentifier xmlResourceIdentifier) throws XNIException, IOException { + String publicId; + + PsiFile psiFile = resolve( + xmlResourceIdentifier.getBaseSystemId(), + publicId = (xmlResourceIdentifier.getLiteralSystemId() != null ? + xmlResourceIdentifier.getLiteralSystemId(): + xmlResourceIdentifier.getNamespace()) + ); + if (psiFile==null && xmlResourceIdentifier.getLiteralSystemId()!=null && xmlResourceIdentifier.getNamespace()!=null) { + psiFile = resolve( + xmlResourceIdentifier.getBaseSystemId(), + publicId = xmlResourceIdentifier.getNamespace() + ); + } + if (psiFile == null) return null; + + XMLInputSource source = new XMLInputSource(xmlResourceIdentifier); + //VirtualFile virtualFile = psiFile.getVirtualFile(); + //final String url = VfsUtil.fixIDEAUrl(virtualFile.getUrl()); + //source.setBaseSystemId(url); + //source.setSystemId(url); + source.setPublicId(publicId); + source.setCharacterStream(new StringReader(psiFile.getText())); + + return source; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlUtil.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlUtil.java new file mode 100644 index 00000000000..bce026da233 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/XmlUtil.java @@ -0,0 +1,824 @@ +package com.intellij.xml.util; + +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.j2ee.openapi.ex.ExternalResourceManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.filters.ClassFilter; +import com.intellij.psi.scope.processor.FilterElementProcessor; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ArrayUtil; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.impl.ant.AntPropertyDeclaration; + +import java.io.File; +import java.util.*; + +/** + * @author Mike + */ +public class XmlUtil { + public static final String TAGLIB_1_1_URI = "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"; + public static final String TAGLIB_1_2_URI = "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"; + public static final String TAGLIB_1_2_a_URI = "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd"; + public static final String TAGLIB_1_2_b_URI = "http://java.sun.com/JSP/TagLibraryDescriptor"; + public static final String TAGLIB_2_0_URI = "http://java.sun.com/xml/ns/j2ee"; + + public static final String XML_SCHEMA_URI = "http://www.w3.org/2001/XMLSchema"; + public static final String XML_SCHEMA_URI2 = "http://www.w3.org/1999/XMLSchema"; + public static final String XML_SCHEMA_URI3 = "http://www.w3.org/2000/10/XMLSchema"; + public static final String XML_SCHEMA_INSTANCE_URI = "http://www.w3.org/2001/XMLSchema-instance"; + public static final String ANT_URI = "http://ant.apache.org/schema.xsd"; + public static final String XHTML_URI = "http://www.w3.org/1999/xhtml"; + public static final String EMPTY_NAMESPACE = ""; + public static final Key TEST_PATH = Key.create("TEST PATH"); + public static final String JSP_NAMESPACE = "http://java.sun.com/JSP/Page"; + public static final String ALL_NAMESPACE = "http://www.intellij.net/ns/all"; + + static { + PsiSearchScopeUtil.registerAccessScopeHandler(StdFileTypes.DTD, new PsiSearchScopeUtil.AccessScopeHandler() { + public SearchScope getAccessScope(PsiElement element) { + return GlobalSearchScope.projectScope(element.getProject()); + } + }); + } + + public static String getSchemaLocation(XmlTag tag, String namespace) { + final String uri = ExternalResourceManagerEx.getInstanceEx().getResourceLocation(namespace); + if (uri != null && !uri.equals(namespace)) return uri; + + while (true) { + if ("".equals(namespace)) { + final String attributeValue = tag.getAttributeValue("noNamespaceSchemaLocation", XML_SCHEMA_INSTANCE_URI); + if(attributeValue != null) return attributeValue; + } + else { + String schemaLocation = tag.getAttributeValue("schemaLocation", XML_SCHEMA_INSTANCE_URI); + if (schemaLocation != null) { + int start = schemaLocation.indexOf(namespace); + if (start >= 0) { + start += namespace.length(); + final StringTokenizer tokenizer = new StringTokenizer(schemaLocation.substring(start + 1)); + if (tokenizer.hasMoreTokens()) { + return tokenizer.nextToken(); + } + else { + return null; + } + } + } + } + if (tag.getParent() instanceof XmlTag) { + tag = (XmlTag)tag.getParent(); + } + else { + break; + } + } + return null; + } + + public static String findNamespacePrefixByURI(XmlFile file, String uri) { + if (file == null) return null; + final XmlDocument document = file.getDocument(); + if (document == null) return null; + final XmlTag tag = document.getRootTag(); + if (tag == null) return null; + XmlAttribute[] attributes = tag.getAttributes(); + + + for (int i = 0; i < attributes.length; i++) { + XmlAttribute attribute = attributes[i]; + if (attribute.getName().startsWith("xmlns:") && + attribute.getValue().equals(uri)) { + String ns = attribute.getName().substring("xmlns:".length()); + return ns; + } + if ("xmlns".equals(attribute.getName()) && attribute.getValue().equals(uri)) return ""; + } + + return null; + } + + public static String[] findNamespacesByURI(XmlFile file, String uri) { + if (file == null) return ArrayUtil.EMPTY_STRING_ARRAY; + final XmlDocument document = file.getDocument(); + if (document == null) return ArrayUtil.EMPTY_STRING_ARRAY; + final XmlTag tag = document.getRootTag(); + if (tag == null) return ArrayUtil.EMPTY_STRING_ARRAY; + XmlAttribute[] attributes = tag.getAttributes(); + + + List result = new ArrayList(); + + for (int i = 0; i < attributes.length; i++) { + XmlAttribute attribute = attributes[i]; + if (attribute.getName().startsWith("xmlns:") && + attribute.getValue().equals(uri)) { + result.add(attribute.getName().substring("xmlns:".length())); + } + if ("xmlns".equals(attribute.getName()) && attribute.getValue().equals(uri)) result.add(""); + } + + return result.toArray(new String[result.size()]); + } + + public static String getXsiNamespace(XmlFile file) { + return findNamespacePrefixByURI(file, XML_SCHEMA_INSTANCE_URI); + } + + public static XmlFile findXmlFile(PsiFile base, String uri) { + PsiFile result = null; + if (ApplicationManager.getApplication().isUnitTestMode()) { + String data = base.getUserData(TEST_PATH); + + if (data == null && base.getOriginalFile() != null) { + data = base.getOriginalFile().getUserData(TEST_PATH); + } + if (data != null) { + String filePath = data + "/" + uri; + final VirtualFile path = LocalFileSystem.getInstance().findFileByPath(filePath.replace(File.separatorChar, '/')); + if (path != null) { + result = base.getManager().findFile(path); + } + } + } + if (result == null) { + result = PsiUtil.findRelativeFile(uri, base); + } + + if (result instanceof XmlFile) { + XmlFile xmlFile = (XmlFile)result; + return xmlFile; + } + + return null; + } + + public static XmlToken getTokenOfType(PsiElement element, IElementType type) { + if (element == null) { + return null; + } + + PsiElement[] children = element.getChildren(); + + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; + + if (child instanceof XmlToken) { + XmlToken token = (XmlToken)child; + + if (token.getTokenType() == type) { + return token; + } + } + } + + return null; + } + + public static boolean processXmlElements(XmlElement element, PsiElementProcessor processor, boolean deepFlag) { + return processXmlElements(element, processor, deepFlag, false); + } + + public static boolean processXmlElements(XmlElement element, PsiElementProcessor processor, boolean deepFlag, boolean wideFlag) { + if (element == null) return true; + PsiFile baseFile = element.getContainingFile(); + return _processXmlElements(element, processor, baseFile, deepFlag, wideFlag); + } + + private static boolean _processXmlElements(PsiElement element, + PsiElementProcessor processor, + PsiFile targetFile, + boolean deepFlag, + boolean wideFlag) { + if (deepFlag) if (!processor.execute(element)) return false; + + if (element instanceof XmlEntityRef) { + XmlEntityRef ref = (XmlEntityRef)element; + + PsiElement newElement = parseEntityRef(targetFile, ref, true); + if (newElement == null) return true; + + while (newElement != null) { + if (!processElement(newElement, processor, targetFile, deepFlag, wideFlag)) return false; + newElement = newElement.getNextSibling(); + } + + return true; + } + + for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) { + if (!processElement(child, processor, targetFile, deepFlag, wideFlag) && !wideFlag) return false; + } + + return true; + } + + private static boolean processElement(PsiElement child, + PsiElementProcessor processor, + PsiFile targetFile, + boolean deepFlag, + boolean wideFlag) { + if (deepFlag) { + if (!_processXmlElements(child, processor, targetFile, true, wideFlag)) { + return false; + } + } + else { + if (child instanceof XmlEntityRef) { + if (!_processXmlElements(child, processor, targetFile, false, wideFlag)) return false; + } + else if (!processor.execute(child)) return false; + } + return true; + } + + private static PsiElement parseEntityRef(PsiFile targetFile, XmlEntityRef ref, boolean cacheValue) { + int type = getContextType(ref); + + { + final XmlEntityDecl entityDecl = ref.resolve(targetFile); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + } + + PsiElement e = ref; + while (e != null) { + if (e.getUserData(XmlElement.ORIGINAL_ELEMENT) != null) { + e = (PsiElement)e.getUserData(XmlElement.ORIGINAL_ELEMENT); + final PsiFile f = e.getContainingFile(); + if (f != null) { + final XmlEntityDecl entityDecl = ref.resolve(targetFile); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + } + + continue; + } + if (e instanceof PsiFile) { + PsiFile refFile = (PsiFile)e; + final XmlEntityDecl entityDecl = ref.resolve(refFile); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + break; + } + + e = e.getParent(); + } + return null; + } + + private static int getContextType(XmlEntityRef ref) { + int type = XmlEntityDecl.CONTEXT_GENERIC_XML; + PsiElement temp = ref; + while (temp != null) { + if (temp instanceof XmlAttributeDecl) { + type = XmlEntityDecl.CONTEXT_ATTRIBUTE_SPEC; + } + else if (temp instanceof XmlElementDecl) { + type = XmlEntityDecl.CONTEXT_ELEMENT_CONTENT_SPEC; + } + else if (temp instanceof XmlAttlistDecl) { + type = XmlEntityDecl.CONTEXT_ATTLIST_SPEC; + } + else if (temp instanceof XmlEntityDecl) { + type = XmlEntityDecl.CONTEXT_ENTITY_DECL_CONTENT; + } + else if (temp instanceof XmlEnumeratedType) { + type = XmlEntityDecl.CONTEXT_ENUMERATED_TYPE; + } + else { + temp = temp.getContext(); + continue; + } + break; + } + return type; + } + + private static final Key PARSED_DECL_KEY = Key.create("PARSED_DECL_KEY"); + + private static PsiElement parseEntityDecl(final XmlEntityDecl entityDecl, + final PsiFile targetFile, + final int type, + boolean cacheValue, + final XmlEntityRef entityRef) { + if (!cacheValue) return entityDecl.parse(targetFile, type, entityRef); + + CachedValue value = entityRef.getUserData(PARSED_DECL_KEY); +// return entityDecl.parse(targetFile, type); + + if (value == null) { + value = entityDecl.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + public CachedValueProvider.Result compute() { + final PsiElement res = entityDecl.parse(targetFile, type, entityRef); + if (res == null) return new Result(res, new Object[]{targetFile}); + return new CachedValueProvider.Result(res, new Object[]{res.getUserData(XmlElement.DEPENDING_ELEMENT), entityDecl, targetFile, entityRef}); + } + }, false); + entityRef.putUserData(PARSED_DECL_KEY, value); + } + + return (PsiElement)value.getValue(); + } + + /** + * add child to the parent according to DTD/Schema element ordering + * + * @return newly added child + */ + public static XmlTag addChildTag(XmlTag parent, XmlTag child) throws IncorrectOperationException { + return addChildTag(parent, child, -1); + } + + public static XmlTag addChildTag(XmlTag parent, XmlTag child, int index) throws IncorrectOperationException { + + // bug in PSI: cannot add child to + if (parent.getSubTags().length == 0 && parent.getText().endsWith("/>")) { + final PsiElementFactory factory = parent.getManager().getElementFactory(); + final String name = parent.getName(); + final String text = parent.getText(); + final XmlTag tag = factory.createTagFromText(text.substring(0, text.length() - 2) + ">"); + parent = (XmlTag)parent.replace(tag); + } + + final XmlElementDescriptor parentDescriptor = parent.getDescriptor(); + final XmlTag[] subTags = parent.getSubTags(); + if (parentDescriptor == null || subTags.length == 0) return (XmlTag)parent.add(child); + final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(parent); + int subTagNum = -1; + for (int i = 0; i < childElementDescriptors.length; i++) { + XmlElementDescriptor childElementDescriptor = childElementDescriptors[i]; + final String childElementName = childElementDescriptor.getName(); + int prevSubTagNum = subTagNum; + while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) { + subTagNum++; + } + if (childElementName.equals(child.getName())) { + // insert child just after anchor + // insert into the position specified by index + subTagNum = index == -1 || index > subTagNum - prevSubTagNum ? subTagNum : prevSubTagNum + index; + return (XmlTag)(subTagNum == -1 ? parent.addBefore(child, subTags[0]) : parent.addAfter(child, subTags[subTagNum])); + } + } + return (XmlTag)parent.add(child); + } + + public static String getAttributeValue(XmlTag tag, String name) { + final XmlAttribute[] attributes = tag.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + XmlAttribute attribute = attributes[i]; + if (name.equals(attribute.getName())) return attribute.getValue(); + } + return null; + } + + public static XmlTag findOnAnyLevel(XmlTag root, String[] chain) { + XmlTag curTag = root; + for (int i = 0; i < chain.length; i++) { + String s = chain[i]; + curTag = curTag.findFirstSubTag(s); + if (curTag == null) return null; + } + + return curTag; + } + + public static XmlTag findSubTag(XmlTag rootTag, String path) { + String[] pathElements = path.split("/"); + + XmlTag curTag = rootTag; + for (int i = 0; i < pathElements.length; i++) { + String curTagName = pathElements[i]; + curTag = curTag.findFirstSubTag(curTagName); + if (curTag == null) break; + } + return curTag; + } + + public static XmlTag findSubTagWithValue(XmlTag rootTag, String tagName, String tagValue) { + if (rootTag == null) return null; + final XmlTag[] subTags = rootTag.findSubTags(tagName); + for (int i = 0; i < subTags.length; i++) { + XmlTag subTag = subTags[i]; + if (subTag.getValue().getTrimmedText().equals(tagValue)) { + return subTag; + } + } + return null; + } + + public static XmlTag findSubTagWithValueOnAnyLevel(XmlTag baseTag, String tagName, String tagValue) { + final String baseValue = baseTag.getValue().getTrimmedText(); + if (baseValue != null && baseValue.equals(tagValue)) { + return baseTag; + } + else { + final XmlTag[] subTags = baseTag.getSubTags(); + for (int i = 0; i < subTags.length; i++) { + XmlTag subTag = subTags[i]; + + // It will return the first entry of subtag in the tree + final XmlTag subTagFound = findSubTagWithValueOnAnyLevel(subTag, tagName, tagValue); + if (subTagFound != null) return subTagFound; + + } + } + return null; + } + + // Read the function name and parameter names to find out what this function does... :-) + public static XmlTag find(String subTag, String withValue, String forTag, XmlTag insideRoot) { + final XmlTag[] forTags = insideRoot.findSubTags(forTag); + for (int i = 0; i < forTags.length; i++) { + XmlTag tag = forTags[i]; + final XmlTag[] allTags = tag.findSubTags(subTag); + for (int j = 0; j < allTags.length; j++) { + XmlTag curTag = allTags[j]; + if (curTag.getName().equals(subTag) && curTag.getValue().getTrimmedText().equalsIgnoreCase(withValue)) { + return tag; + } + } + } + + return null; + } + + public static boolean isInAntBuildFile(XmlFile file){ + if(file == null) return false; + if (file.getCopyableUserData(XmlFile.ANT_BUILD_FILE) != null) { + return true; + } + XmlDocument document = file.getDocument(); + if(document != null){ + XmlTag rootTag = document.getRootTag(); + if(rootTag != null){ + return ANT_URI.equals(rootTag.getNamespace()); + } + } + return false; + } + + public static boolean isAntTargetDefinition(XmlAttribute attr) { + if (!isInAntBuildFile((XmlFile)attr.getContainingFile())) return false; + final XmlTag tag = attr.getParent(); + + return tag.getName().equals("target") && attr.getName().equals("name"); + } + + public static boolean isAntPropertyDefinition(XmlAttribute attr) { + final XmlTag parentTag = attr.getParent(); + if(parentTag != null){ + final PsiMetaData data = parentTag.getMetaData(); + if(data instanceof AntPropertyDeclaration){ + if(data.getDeclaration() == attr.getValueElement()) return true; + } + } + return false; + } + + + + public static String getDefaultNamespace(final XmlDocument document) { + final XmlFile file = XmlUtil.getContainingFile(document); + if (file != null && file.getCopyableUserData(XmlFile.ANT_BUILD_FILE) != null) { + return ANT_URI; + } + + XmlTag tag = document.getRootTag(); + if (tag == null) return EMPTY_NAMESPACE; + if ("project".equals(tag.getName()) && tag.getContext() instanceof XmlDocument) { + if (tag.getAttributeValue("default") != null) { + return ANT_URI; + } + } + + String namespace = getDtdUri(document); + if (namespace != null) return EMPTY_NAMESPACE; + + if ("taglib".equals(tag.getName())) { + return TAGLIB_1_2_URI; + } + + if (file != null) { + final FileType fileType = file.getFileType(); + + if (fileType == StdFileTypes.HTML || + fileType == StdFileTypes.XHTML) { + return XHTML_URI; + } else if (fileType == StdFileTypes.JSPX) { + return JSP_NAMESPACE; + } + } + + return EMPTY_NAMESPACE; + } + + + public static String getDtdUri(XmlDocument document) { + if (document.getProlog() != null) { + final XmlDoctype doctype = document.getProlog().getDoctype(); + if (doctype != null) { + return doctype.getDtdUri(); + } + } + return null; + } + + private static void computeTag(XmlTag tag, final Map> tagsMap, final Map> attributesMap) { + if (tag == null) { + return; + } + final String tagName = tag.getName(); + + { + List list = attributesMap.get(tagName); + if (list == null) { + list = new ArrayList(); + final XmlAttribute[] attributes = tag.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + final XmlAttribute attribute = attributes[i]; + list.add(new MyAttributeInfo(attribute.getName())); + } + } + else { + final XmlAttribute[] attributes = tag.getAttributes(); + Collections.sort((List)list); + Arrays.sort(attributes, new Comparator() { + public int compare(Object o1, Object o2) { + return ((XmlAttribute)o1).getName().compareTo(((XmlAttribute)o2).getName()); + } + }); + + final Iterator iter = list.iterator(); + int index = 0; + list = new ArrayList(); + while (iter.hasNext()) { + final MyAttributeInfo info = iter.next(); + boolean requiredFlag = false; + while (attributes.length > index) { + if (info.compareTo(attributes[index]) != 0) { + if (info.compareTo(attributes[index]) < 0) { + break; + } + if (attributes[index].getValue() != null) list.add(new MyAttributeInfo(attributes[index].getName(), false)); + index++; + } + else { + requiredFlag = true; + index++; + break; + } + } + info.myRequired &= requiredFlag; + list.add(info); + } + while (attributes.length > index) { + if (attributes[index].getValue() != null) list.add(new MyAttributeInfo(attributes[index++].getName(), false)); + else index++; + } + } + attributesMap.put(tagName, list); + } + { + final List tags = tagsMap.get(tagName) != null ? tagsMap.get(tagName) : new ArrayList(); + tagsMap.put(tagName, tags); + tag.processElements(new FilterElementProcessor(new ClassFilter(XmlTag.class)) { + public void add(PsiElement element) { + XmlTag tag = (XmlTag)element; + if (!tags.contains(tag.getName())) { + tags.add(tag.getName()); + } + computeTag(tag, tagsMap, attributesMap); + } + }, tag); + } + } + + private static class MyAttributeInfo implements Comparable { + boolean myRequired = true; + String myName = null; + + MyAttributeInfo(String name) { + myName = name; + } + + MyAttributeInfo(String name, boolean flag) { + myName = name; + myRequired = flag; + } + + public int compareTo(Object o) { + if (o instanceof MyAttributeInfo) { + return myName.compareTo(((MyAttributeInfo)o).myName); + } + else if (o instanceof XmlAttribute) { + return myName.compareTo(((XmlAttribute)o).getName()); + } + return -1; + } + } + + public static String generateDocumentDTD(XmlDocument doc) { + final StringBuffer buffer = new StringBuffer(); + final Map> tags = new com.intellij.util.containers.HashMap>(); + final Map> attributes = new com.intellij.util.containers.HashMap>(); + computeTag(doc.getRootTag(), tags, attributes); + final Iterator iter = tags.keySet().iterator(); + while (iter.hasNext()) { + final String tagName = iter.next(); + buffer.append(generateElementDTD(tagName, tags.get(tagName), attributes.get(tagName))); + } + return buffer.toString(); + } + + public static String generateElementDTD(String name, List tags, List attributes) { + if (name == null || "".equals(name)) return ""; + if (name.endsWith(CompletionUtil.DUMMY_IDENTIFIER.trim())) return ""; + + final StringBuffer buffer = new StringBuffer(); + { + buffer.append("\n"); + } + else { + buffer.append("("); + final Iterator iter = tags.iterator(); + while (iter.hasNext()) { + final String tagName = iter.next(); + buffer.append(tagName); + if (iter.hasNext()) { + buffer.append("|"); + } + else { + buffer.append(")*"); + } + } + buffer.append(">\n"); + } + } + { + if (!attributes.isEmpty()) { + buffer.append(" iter = attributes.iterator(); + while (iter.hasNext()) { + final MyAttributeInfo info = iter.next(); + buffer.append("\n " + generateAttributeDTD(info)); + } + buffer.append(">\n"); + } + } + return buffer.toString(); + } + + private static String generateAttributeDTD(MyAttributeInfo info) { + if (info.myName.endsWith(CompletionUtil.DUMMY_IDENTIFIER.trim())) return ""; + final StringBuffer buffer = new StringBuffer(); + buffer.append(info.myName + " "); + //if ("id".equals(info.myName)) { + // buffer.append("ID"); + //} + //else if ("ref".equals(info.myName)) { + // buffer.append("IDREF"); + //} else { + buffer.append("CDATA"); + //} + if (info.myRequired) { + buffer.append(" #REQUIRED"); + } + else { + buffer.append(" #IMPLIED"); + } + return buffer.toString(); + } + + public static String trimLeadingSpacesInMultilineTagValue(String tagValue) { + return tagValue == null ? null : tagValue.replaceAll("\n\\s*", "\n"); + } + + public static String findNamespaceByPrefix(final String prefix, XmlTag contextTag) { + final String s = contextTag.getNamespaceByPrefix(prefix); + if (s != null) return s; + return EMPTY_NAMESPACE; + } + + public static final String findPrefixByQualifiedName(String name) { + final int prefixEnd = name.indexOf(':'); + if (prefixEnd > 0) { + return name.substring(0, prefixEnd); + } + return ""; + } + + public static final String findLocalNameByQualifiedName(String name) { + return name.substring(name.indexOf(':') + 1); + } + + + public static String escapeString(String str) { + if (str == null) return null; + StringBuffer buffer = null; + for (int i = 0; i < str.length(); i++) { + String entity; + char ch = str.charAt(i); + switch (ch) { + case '\"': + entity = """; + break; + case '<': + entity = "<"; + break; + case '>': + entity = ">"; + break; + case '&': + entity = "&"; + break; + default : + entity = null; + break; + } + if (buffer == null) { + if (entity != null) { + // An entity occurred, so we'll have to use StringBuffer + // (allocate room for it plus a few more entities). + buffer = new StringBuffer(str.length() + 20); + // Copy previous skipped characters and fall through + // to pickup current character + buffer.append(str.substring(0, i)); + buffer.append(entity); + } + } + else { + if (entity == null) { + buffer.append(ch); + } + else { + buffer.append(entity); + } + } + } + + // If there were any entities, return the escaped characters + // that we put in the StringBuffer. Otherwise, just return + // the unmodified input string. + return buffer == null ? str : buffer.toString(); + } + + public static XmlFile getContainingFile(PsiElement element) { + while (!(element instanceof XmlFile) && element != null) { + element = element.getContext(); + } + return (XmlFile)element; + } + + public static String getSubTagValue(XmlTag tag, final String subTagName) { + final XmlTag subTag = tag.findFirstSubTag(subTagName); + if (subTag != null) { + return subTag.getValue().getTrimmedText(); + } + return null; + } + + public static int getStartOffsetInFile(XmlTag xmlTag) { + int off = 0; + while (true) { + off += xmlTag.getStartOffsetInParent(); + final PsiElement parent = xmlTag.getParent(); + if (!(parent instanceof XmlTag)) break; + xmlTag = (XmlTag)parent; + } + return off; + } + + public static XmlElement setNewValue(XmlElement tag, String value) throws IncorrectOperationException { + if (tag instanceof XmlTag) { + ((XmlTag)tag).getValue().setText(value); + return tag; + } + else if (tag instanceof XmlAttribute) { + XmlAttribute attr = (XmlAttribute)tag; + attr.setValue(value); + return attr; + } + else { + throw new IncorrectOperationException(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/CompositeAttributeTagDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/CompositeAttributeTagDescriptor.java new file mode 100644 index 00000000000..8ee9363edc1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/CompositeAttributeTagDescriptor.java @@ -0,0 +1,33 @@ +package com.intellij.xml.util.documentation; + +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.util.documentation.HtmlAttributeDescriptor; + +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:53:45 + * To change this template use File | Settings | File Templates. + */ +class CompositeAttributeTagDescriptor extends HtmlAttributeDescriptor { + List attributes = new LinkedList(); + + HtmlAttributeDescriptor findHtmlAttributeInContext(XmlTag tag) { + String contextName = tag.getName(); + + for (Iterator iterator = attributes.iterator(); iterator.hasNext();) { + HtmlAttributeDescriptor attributeDescriptor = iterator.next(); + + if (attributeDescriptor.isValidParentTagName(contextName)) { + return attributeDescriptor; + } + } + + return null; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/EntityDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/EntityDescriptor.java new file mode 100644 index 00000000000..58e6025429d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/EntityDescriptor.java @@ -0,0 +1,50 @@ +package com.intellij.xml.util.documentation; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:53:29 + * To change this template use File | Settings | File Templates. + */ +class EntityDescriptor { + private String description; + private String helpRef; + private String name; + private char dtd; + + static final char LOOSE_DTD = 'L'; + static final char FRAME_DTD = 'D'; + + char getDtd() { + return dtd; + } + + void setDtd(char dtd) { + this.dtd = dtd; + } + + String getDescription() { + return description; + } + + void setDescription(String description) { + this.description = description; + } + + String getHelpRef() { + return helpRef; + } + + void setHelpRef(String helpRef) { + this.helpRef = helpRef; + } + + String getName() { + return name; + } + + void setName(String name) { + this.name = name; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlAttributeDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlAttributeDescriptor.java new file mode 100644 index 00000000000..0d4656f7e52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlAttributeDescriptor.java @@ -0,0 +1,54 @@ +package com.intellij.xml.util.documentation; + +import java.util.Arrays; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:54:11 + * To change this template use File | Settings | File Templates. + */ +class HtmlAttributeDescriptor extends EntityDescriptor { + private String myType; + private boolean myHasDefaultValue; + private String[] mySetOfParentTags; + private boolean myParentSetIsExclusionSet; + + boolean isValidParentTagName(String str) { + boolean containsInSet = Arrays.binarySearch(mySetOfParentTags, str) >= 0; + return containsInSet == !myParentSetIsExclusionSet; + } + + String getType() { + return myType; + } + + void setType(String type) { + this.myType = type; + } + + boolean isHasDefaultValue() { + return myHasDefaultValue; + } + + void setHasDefaultValue(boolean hasDefaultValue) { + this.myHasDefaultValue = hasDefaultValue; + } + + String[] getSetOfParentTags() { + return mySetOfParentTags; + } + + boolean isParentSetIsExclusionSet() { + return myParentSetIsExclusionSet; + } + + void setParentSetIsExclusionSet(boolean _parentSetIsExclusionSet) { + myParentSetIsExclusionSet = _parentSetIsExclusionSet; + } + + void setSetOfParentTags(String[] _setOfParentTags) { + mySetOfParentTags = _setOfParentTags; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDescriptorsTable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDescriptorsTable.java new file mode 100644 index 00000000000..aa5322b8e64 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDescriptorsTable.java @@ -0,0 +1,127 @@ +package com.intellij.xml.util.documentation; + +import org.jdom.Document; +import org.jdom.Element; + +import java.util.*; + +import com.intellij.openapi.util.JDOMUtil; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:56:32 + * To change this template use File | Settings | File Templates. + */ +public class HtmlDescriptorsTable { + private static final HashMap ourTagTable = new HashMap(); + private static final HashMap ourAttributeTable = new HashMap(); + private static String[] ourHtmlTagNames; + + static { + try { + final Document document = JDOMUtil.loadDocument(HtmlDescriptorsTable.class.getResourceAsStream("htmltable.xml")); + final List elements = document.getRootElement().getChildren("tag"); + HtmlDocumentationProvider.setBaseHtmlExtDocUrl( + document.getRootElement().getAttribute("baseHelpRef").getValue() + ); + + ourHtmlTagNames = new String[elements.size()]; + + int i = 0; + for (Iterator iterator = elements.iterator(); iterator.hasNext();) { + final Element element = (Element) iterator.next(); + ourHtmlTagNames[i] = element.getAttributeValue("name"); + + HtmlTagDescriptor value = new HtmlTagDescriptor(); + ourTagTable.put(ourHtmlTagNames[i],value); + value.setHelpRef( element.getAttributeValue("helpref") ); + value.setDescription( element.getAttributeValue("description") ); + value.setName(ourHtmlTagNames[i]); + + value.setHasStartTag(element.getAttribute("startTag").getBooleanValue()); + value.setHasEndTag(element.getAttribute("endTag").getBooleanValue()); + value.setEmpty(element.getAttribute("empty").getBooleanValue()); + + String attributeValue = element.getAttributeValue("dtd"); + if (attributeValue.length() > 0) { + value.setDtd(attributeValue.charAt(0)); + } + + ++i; + } + + final List attributes = document.getRootElement().getChildren("attribute"); + for (Iterator iterator = attributes.iterator(); iterator.hasNext();) { + final Element element = (Element) iterator.next(); + String attrName = element.getAttributeValue("name"); + + HtmlAttributeDescriptor value = new HtmlAttributeDescriptor(); + HtmlAttributeDescriptor previousDescriptor = ourAttributeTable.get(attrName); + + if (previousDescriptor==null) + ourAttributeTable.put(attrName,value); + else { + CompositeAttributeTagDescriptor parentDescriptor; + + if (!(previousDescriptor instanceof CompositeAttributeTagDescriptor)) { + parentDescriptor = new CompositeAttributeTagDescriptor(); + ourAttributeTable.put(attrName,parentDescriptor); + parentDescriptor.attributes.add(previousDescriptor); + } else { + parentDescriptor = (CompositeAttributeTagDescriptor)previousDescriptor; + } + + parentDescriptor.attributes.add(value); + } + + value.setHelpRef( element.getAttributeValue("helpref") ); + value.setDescription( element.getAttributeValue("description") ); + value.setName(attrName); + + String attributeValue = element.getAttributeValue("dtd"); + if (attributeValue.length() > 0) { + value.setDtd(attributeValue.charAt(0)); + } + + value.setType( element.getAttributeValue("type") ); + value.setHasDefaultValue( element.getAttribute("default").getBooleanValue() ); + + StringTokenizer tokenizer = new StringTokenizer(element.getAttributeValue("relatedTags"),","); + int tokenCount = tokenizer.countTokens(); + + for(i = 0;i < tokenCount;++i) { + final String s = tokenizer.nextToken(); + + if (s.equals("!")) { + value.setParentSetIsExclusionSet(true); + } + else { + if (value.getSetOfParentTags() == null) { + value.setSetOfParentTags(new String[tokenCount - (value.isParentSetIsExclusionSet() ? 1 : 0)]); + } + value.getSetOfParentTags()[i-(value.isParentSetIsExclusionSet() ? 1 : 0)] = s; + } + } + + Arrays.sort(value.getSetOfParentTags()); + } + } catch (Exception ex) { + ex.printStackTrace(); + ourHtmlTagNames = new String[0]; + } + } + + static HtmlTagDescriptor getTagDescriptor(String tagName) { + return ourTagTable.get(tagName); + } + + static HtmlAttributeDescriptor getAttributeDescriptor(String attributeName) { + return ourAttributeTable.get(attributeName); + } + + public static String[] getHtmlTagNames() { + return ourHtmlTagNames; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java new file mode 100644 index 00000000000..0b3d6bb471a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java @@ -0,0 +1,245 @@ +package com.intellij.xml.util.documentation; + +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.codeInsight.javadoc.JavaDocUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.xml.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.util.XmlUtil; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:55:08 + * To change this template use File | Settings | File Templates. + */ +public class HtmlDocumentationProvider implements JavaDocManager.DocumentationProvider { + private static String baseHtmlExtDocUrl; + private static JavaDocManager.DocumentationProvider styleProvider; + protected Project myProject; + + public HtmlDocumentationProvider(Project project) { + myProject = project; + } + + public void registerStyleDocumentationProvider(JavaDocManager.DocumentationProvider documentationProvider) { + styleProvider = documentationProvider; + } + + public String getUrlFor(PsiElement element, PsiElement originalElement) { + String result = getUrlForHtml(element, PsiTreeUtil.getParentOfType(originalElement,XmlTag.class,false)); + + if (result == null && styleProvider!=null) { + result = styleProvider.getUrlFor(element, originalElement); + } + + return result; + } + + public String getUrlForHtml(PsiElement element, XmlTag context) { + final EntityDescriptor descriptor = findDocumentationDescriptor(element, context); + + if (descriptor!=null) { + return baseHtmlExtDocUrl + descriptor.getHelpRef(); + } else { + return null; + } + } + + private EntityDescriptor findDocumentationDescriptor(PsiElement element, XmlTag context) { + boolean isTag = true; + PsiElement nameElement = null; + String key = null; + + if (element instanceof XmlElementDecl) { + nameElement = ((XmlElementDecl)element).getNameElement(); + } else if (element instanceof XmlAttributeDecl) { + nameElement = ((XmlAttributeDecl)element).getNameElement(); + isTag = false; + } else if (element instanceof XmlTag) { + // TODO: set schema + } else if (element.getParent() instanceof XmlAttributeValue) { + isTag = false; + key = ((XmlAttribute)element.getParent().getParent()).getName(); + } else { + nameElement = element; + } + + if (nameElement!=null) { + key = nameElement.getText(); + } + + key = (key != null)?key.toLowerCase():""; + + if (isTag) { + return HtmlDescriptorsTable.getTagDescriptor(key); + } else { + return getDescriptor(key, context); + } + } + + HtmlAttributeDescriptor getDescriptor(String name, XmlTag context) { + + HtmlAttributeDescriptor attributeDescriptor = HtmlDescriptorsTable.getAttributeDescriptor(name); + if (attributeDescriptor instanceof CompositeAttributeTagDescriptor) { + return ((CompositeAttributeTagDescriptor)attributeDescriptor).findHtmlAttributeInContext(context); + } + + return attributeDescriptor; + } + + public String generateDoc(PsiElement element, PsiElement originalElement) { + String result = generateDocForHtml(element, false, PsiTreeUtil.getParentOfType(originalElement,XmlTag.class,false)); + + if (result == null && styleProvider!=null) { + result = styleProvider.generateDoc(element, originalElement); + } + + return result; + } + + public String generateDocForHtml(PsiElement element) { + return generateDocForHtml(element,true, null); + } + + protected String generateDocForHtml(PsiElement element, boolean ommitHtmlSpecifics, XmlTag context) { + final EntityDescriptor descriptor = findDocumentationDescriptor(element,context); + + if (descriptor!=null) { + return generateJavaDoc(descriptor, ommitHtmlSpecifics); + } + return null; + } + + private String generateJavaDoc(EntityDescriptor descriptor, boolean ommitHtmlSpecifics) { + StringBuffer buf = new StringBuffer(); + + String entityType; + + if (descriptor instanceof HtmlTagDescriptor) { + entityType = "Tag"; + } else { + entityType = "Attribute"; + } + + JavaDocUtil.formatEntityName(entityType + " name",descriptor.getName(),buf); + + buf.append("Description : ").append(descriptor.getDescription()).append("
    "); + + if (descriptor instanceof HtmlTagDescriptor) { + final HtmlTagDescriptor tagDescriptor = (HtmlTagDescriptor)descriptor; + + if (!ommitHtmlSpecifics) { + boolean hasStartTag = tagDescriptor.isHasStartTag(); + if (!hasStartTag) { + buf.append("Start tag : ").append("could be ommitted").append("
    "); + } + if (!tagDescriptor.isEmpty() && !tagDescriptor.isHasEndTag()) { + buf.append("End tag : ").append("could be ommitted").append("
    "); + } + } + + if (tagDescriptor.isEmpty()) { + buf.append("Is empty : ").append("true").append("
    "); + } + } else { + final HtmlAttributeDescriptor attributeDescriptor = (HtmlAttributeDescriptor)descriptor; + + buf.append( "Attr type : ").append(attributeDescriptor.getType()).append("
    "); + if (!attributeDescriptor.isHasDefaultValue()) + buf.append("Attr default : ").append("required").append("
    "); + } + + char dtdId = descriptor.getDtd(); + boolean deprecated = dtdId == HtmlTagDescriptor.LOOSE_DTD; + if (deprecated) { + buf.append("Deprecated : ").append(deprecated).append("
    "); + } + + String dtd = (dtdId == HtmlTagDescriptor.LOOSE_DTD)? "loose": (dtdId == HtmlTagDescriptor.FRAME_DTD)?"frameset":"any"; + dtd += " dtd"; + buf.append("Defined in : ").append(dtd).append("
    "); + + return buf.toString(); + } + + public PsiElement getDocumentationElementForLookupItem(Object object, PsiElement element) { + PsiElement result = createNavigationElementHTML(object.toString(),element); + + if (result== null && styleProvider!=null) { + result = styleProvider.getDocumentationElementForLookupItem(object, element); + } + return result; + } + + public PsiElement getDocumentationElementForLink(String link, PsiElement context) { + PsiElement result = createNavigationElementHTML(link, context); + + if (result== null && styleProvider!=null) { + result = styleProvider.getDocumentationElementForLink(link,context); + } + return result; + } + + public PsiElement createNavigationElementHTML(String text, PsiElement context) { + String key = text.toLowerCase(); + final HtmlTagDescriptor descriptor = HtmlDescriptorsTable.getTagDescriptor(key); + + if (descriptor!=null && !isAttributeContext(context) ) { + PsiManager manager = PsiManager.getInstance(myProject); + final XmlNSDescriptor nsDescriptor = manager.getJspElementFactory().getXHTMLDescriptor(); + if (nsDescriptor!=null) { + try { + final XmlTag tagFromText = manager.getElementFactory().createTagFromText("<"+ key + " xmlns=\"" + XmlUtil.XHTML_URI + "\"/>"); + + if(tagFromText != null){ + final XmlElementDescriptor elementDescriptor = nsDescriptor.getElementDescriptor(tagFromText); + return elementDescriptor.getDeclaration(); + } + } catch(Exception ex) {} + } + } else { + XmlTag tagContext = findTagContext(context); + HtmlAttributeDescriptor myAttributeDescriptor = getDescriptor(key,tagContext); + if (myAttributeDescriptor!=null && tagContext!=null) { + XmlElementDescriptor tagDescriptor = tagContext.getDescriptor(); + XmlAttributeDescriptor attributeDescriptor = tagDescriptor.getAttributeDescriptor(text); + return attributeDescriptor.getDeclaration(); + } + } + return null; + } + + protected boolean isAttributeContext(PsiElement context) { + if(context instanceof XmlAttribute) return true; + + if (context instanceof PsiWhiteSpace) { + PsiElement prevSibling = context.getPrevSibling(); + if (prevSibling instanceof XmlAttribute) + return true; + } + + return false; + } + + protected XmlTag findTagContext(PsiElement context) { + if (context instanceof PsiWhiteSpace) { + PsiElement prevSibling = context.getPrevSibling(); + if (prevSibling instanceof XmlTag) + return (XmlTag)prevSibling; + } + + return PsiTreeUtil.getParentOfType(context,XmlTag.class,false); + } + + public static void setBaseHtmlExtDocUrl(String baseHtmlExtDocUrl) { + HtmlDocumentationProvider.baseHtmlExtDocUrl = baseHtmlExtDocUrl; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlTagDescriptor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlTagDescriptor.java new file mode 100644 index 00000000000..4d846e5ae55 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/HtmlTagDescriptor.java @@ -0,0 +1,38 @@ +package com.intellij.xml.util.documentation; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:54:27 + * To change this template use File | Settings | File Templates. + */ +class HtmlTagDescriptor extends EntityDescriptor { + boolean isHasStartTag() { + return hasStartTag; + } + + void setHasStartTag(boolean hasStartTag) { + this.hasStartTag = hasStartTag; + } + + boolean isHasEndTag() { + return hasEndTag; + } + + void setHasEndTag(boolean hasEndTag) { + this.hasEndTag = hasEndTag; + } + + boolean isEmpty() { + return empty; + } + + void setEmpty(boolean empty) { + this.empty = empty; + } + + private boolean hasStartTag; + private boolean hasEndTag; + private boolean empty; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java new file mode 100644 index 00000000000..350d07b818f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java @@ -0,0 +1,50 @@ +package com.intellij.xml.util.documentation; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlText; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 24.12.2004 + * Time: 23:55:20 + * To change this template use File | Settings | File Templates. + */ +public class XHtmlDocumentationProvider extends HtmlDocumentationProvider { + public XHtmlDocumentationProvider(Project project) { + super(project); + } + + protected String generateDocForHtml(PsiElement element, boolean ommitHtmlSpecifics, XmlTag context) { + return super.generateDocForHtml(element, true, context); + } + + protected XmlTag findTagContext(PsiElement context) { + XmlTag tagBeforeWhiteSpace = findTagBeforeWhiteSpace(context); + if (tagBeforeWhiteSpace!=null) return tagBeforeWhiteSpace; + return super.findTagContext(context); + } + + private XmlTag findTagBeforeWhiteSpace(PsiElement context) { + if (context instanceof PsiWhiteSpace) { + PsiElement parent = context.getParent(); + if (parent instanceof XmlText) { + PsiElement prevSibling = parent.getPrevSibling(); + if (prevSibling instanceof XmlTag) return (XmlTag)prevSibling; + } else if (parent instanceof XmlTag) { + return (XmlTag)parent; + } + } + + return null; + } + + protected boolean isAttributeContext(PsiElement context) { + if (findTagBeforeWhiteSpace(context)!=null) return false; + + return super.isAttributeContext(context); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XmlDocumentationProvider.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XmlDocumentationProvider.java new file mode 100644 index 00000000000..0468be232c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/source/com/intellij/xml/util/documentation/XmlDocumentationProvider.java @@ -0,0 +1,157 @@ +package com.intellij.xml.util.documentation; + +import com.intellij.codeInsight.javadoc.JavaDocManager; +import com.intellij.codeInsight.javadoc.JavaDocUtil; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.util.XmlUtil; +import com.intellij.xml.impl.schema.XmlElementDescriptorImpl; +import com.intellij.xml.impl.schema.TypeDescriptor; +import com.intellij.xml.impl.schema.ComplexTypeDescriptor; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlElementDecl; +import com.intellij.psi.xml.XmlComment; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.IncorrectOperationException; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 25.12.2004 + * Time: 0:00:05 + * To change this template use File | Settings | File Templates. + */ +public class XmlDocumentationProvider implements JavaDocManager.DocumentationProvider { + private static final Key DESCRIPTOR_KEY = Key.create("Original element"); + + public String getUrlFor(PsiElement element, PsiElement originalElement) { + return null; + } + + public String generateDoc(PsiElement element, PsiElement originalElement) { + if (element instanceof XmlElementDecl) { + PsiElement curElement = element; + + while(curElement!=null && !(curElement instanceof XmlComment)) { + curElement = curElement.getPrevSibling(); + if (curElement!=null && curElement.getClass() == element.getClass()) { + curElement = null; // finding comment fails, we found another similar declaration + break; + } + } + + if (curElement!=null) { + String text = curElement.getText(); + text = text.substring("".length()).trim(); + return generateDoc(text,((XmlElementDecl)element).getNameElement().getText(),null); + } + } else if (element instanceof XmlTag) { + XmlTag tag = (XmlTag)element; + + MyPsiElementProcessor processor = new MyPsiElementProcessor(); + XmlUtil.processXmlElements(tag,processor, true); + String name = tag.getAttributeValue("name"); + String typeName = null; + + if (processor.result == null) { + XmlElementDescriptor descriptor = element.getUserData(DESCRIPTOR_KEY); + if (descriptor == null && originalElement.getParent() instanceof XmlTag) { + descriptor = ((XmlTag)originalElement.getParent()).getDescriptor(); + } + + if (descriptor instanceof XmlElementDescriptorImpl) { + TypeDescriptor type = ((XmlElementDescriptorImpl)descriptor).getType(); + + if (type instanceof ComplexTypeDescriptor) { + XmlTag declaration = ((ComplexTypeDescriptor)type).getDeclaration(); + XmlUtil.processXmlElements(declaration,processor, true); + typeName = declaration.getName(); + } + } + } + + return generateDoc(processor.result, name, typeName); + } + + return null; + } + + private String generateDoc(String str, String name, String typeName) { + if (str == null) return null; + StringBuffer buf = new StringBuffer(str.length() + 20); + + if (typeName==null) { + JavaDocUtil.formatEntityName("Tag name",name,buf); + } else { + JavaDocUtil.formatEntityName("Complex type",name,buf); + } + + buf.append("Description : ").append(str); + + return buf.toString(); + } + + public PsiElement getDocumentationElementForLookupItem(Object object, PsiElement element) { + element = PsiTreeUtil.getParentOfType(element, XmlTag.class, false); + + if (element instanceof XmlTag) { + XmlTag xmlTag = (XmlTag)element; + XmlElementDescriptor elementDescriptor = null; + + try { + String tagText = object.toString(); + String namespace = xmlTag.getNamespace(); + + if (namespace!=null && namespace.length() > 0) { + tagText+=" xmlns=\""+namespace+"\""; + } + + tagText = "<" + tagText +"/>"; + + XmlTag tagFromText = xmlTag.getManager().getElementFactory().createTagFromText(tagText); + elementDescriptor = xmlTag.getDescriptor().getElementDescriptor(tagFromText); + + if (elementDescriptor==null) { + PsiElement parent = xmlTag.getParent(); + if (parent instanceof XmlTag) { + elementDescriptor = ((XmlTag)parent).getDescriptor().getElementDescriptor(tagFromText); + } + } + + if (elementDescriptor!=null) { + PsiElement declaration = elementDescriptor.getDeclaration(); + declaration.putUserData(DESCRIPTOR_KEY,elementDescriptor); + return declaration; + } + } + catch (IncorrectOperationException e) { + e.printStackTrace(); + } + } + return null; + } + + public PsiElement getDocumentationElementForLink(String link, PsiElement context) { + return null; + } + + private static class MyPsiElementProcessor implements PsiElementProcessor { + String result; + + public boolean execute(PsiElement element) { + if (element instanceof XmlTag && + ((XmlTag)element).getLocalName().equals("documentation") + ) { + result = ((XmlTag)element).getValue().getText().trim(); + return false; + } + return true; + } + + public Object getHint(Class hintClass) { + return null; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class1.java new file mode 100644 index 00000000000..ef39d8c575e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class1.java @@ -0,0 +1,7 @@ +package com.package1; + +public class Class1 { + public static void main(String[] args){ + Class2 class2; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class2.java new file mode 100644 index 00000000000..58f58a44dfa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/dependencies/dependencies/src/com/package1/Class2.java @@ -0,0 +1,4 @@ +package com.package1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6073/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6073/src/A.java new file mode 100644 index 00000000000..5705517aac4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6073/src/A.java @@ -0,0 +1,6 @@ +final class A { + int b; + A(int c) { + b=c; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6781/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6781/src/A.java new file mode 100644 index 00000000000..aac49bc9b40 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6781/src/A.java @@ -0,0 +1,12 @@ +final class A { + int m; + int k; + A() { + k=0; + m=0; + } + A(int n) { + this(); + k=n; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6845/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6845/src/A.java new file mode 100644 index 00000000000..17728b9126f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6845/src/A.java @@ -0,0 +1,3 @@ +final class A { + int k; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6861/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6861/src/A.java new file mode 100644 index 00000000000..479e1ab88fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR6861/src/A.java @@ -0,0 +1,12 @@ +final class A { + int k; + int m; + { + k = 0; + m = 0; + } + + A() { + m = 0; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/ext_src/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/ext_src/B.java new file mode 100644 index 00000000000..0cc51c4b2cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/ext_src/B.java @@ -0,0 +1,6 @@ +// B.java +class B extends A { + public void run() { + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/src/A.java new file mode 100644 index 00000000000..aee28c806e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/SCR7737/src/A.java @@ -0,0 +1,6 @@ +// A.java +class A implements Runnable { + public void run() { + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fieldAndTryBlock/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fieldAndTryBlock/src/Foo.java new file mode 100644 index 00000000000..6341b220dcd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fieldAndTryBlock/src/Foo.java @@ -0,0 +1,10 @@ +public final class Foo { + private String s; + + public Foo() { + try { + s = "test"; + } catch (Exception e) { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fields/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fields/src/Foo.java new file mode 100644 index 00000000000..792b58521e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/fields/src/Foo.java @@ -0,0 +1,23 @@ +public final class Foo { + private Object f1 = new Object(); // Can be final + private Object f2; // Can be final + private Object f3; // Cannot be final + private Object f4; // cannot + private Object f5 = new Object(); // cannot + + + public Foo() { + f2 = new Object(); + try { + f3 = "test"; + } catch (Exception e) { + } + f5 = new Object(); + } + + public Foo(int i) { + f2 = new Object(); + f4 = new Object(); + f5 = new Object(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/methodInheritance/src/a.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/methodInheritance/src/a.java new file mode 100644 index 00000000000..e91ac02c054 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/methodInheritance/src/a.java @@ -0,0 +1,10 @@ +public final class a { + public final void foo() { + } +} + +final class b extends a { + public void foo() {} +} + + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/privateInners/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/privateInners/src/Foo.java new file mode 100644 index 00000000000..2257f005ed2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/privateInners/src/Foo.java @@ -0,0 +1,10 @@ +public final class Foo { + private class InnerSuper { + } + + private final class InnerInheritor1 extends InnerSuper { + } + + private class InnerInheritor2 extends InnerSuper { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance/src/Foo.java new file mode 100644 index 00000000000..620b67fc26d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance/src/Foo.java @@ -0,0 +1,5 @@ +public final class Foo extends Bar { +} + +class Bar { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance1/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance1/src/Foo.java new file mode 100644 index 00000000000..3c0d442d366 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/canBeFinal/simpleClassInheritance1/src/Foo.java @@ -0,0 +1,5 @@ +public class Foo extends Bar { +} + +class Bar { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/CatchParameterCantBeNull/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/CatchParameterCantBeNull/src/Test.java new file mode 100644 index 00000000000..d08fbacdaad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/CatchParameterCantBeNull/src/Test.java @@ -0,0 +1,16 @@ +import java.io.*; + +public class Foo { + public void foo() { + try { + throw new EOFException("aaa"); + } catch (Exception e) { + if (e == null) { + System.out.println("Can't be here."); + } + if (e instanceof FileNotFoundException) { + System.out.println("Can't be here."); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/GenericInstanceof/src/GenericInstanceof.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/GenericInstanceof/src/GenericInstanceof.java new file mode 100644 index 00000000000..69cf77793df --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/GenericInstanceof/src/GenericInstanceof.java @@ -0,0 +1,12 @@ +class Generic { + Generic() {} +} + +class Test { + void foo () { + Generic g = new Generic (); + if (g instanceof Generic) { + return; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/Instanceof/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/Instanceof/src/Foo.java new file mode 100644 index 00000000000..01617032d86 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/Instanceof/src/Foo.java @@ -0,0 +1,14 @@ +class A { +} + + +class B extends A { +} + +class C { + void foo(Object o) { + if (o instanceof A || o instanceof B) { + System.out.println("Something"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13626/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13626/src/Test.java new file mode 100644 index 00000000000..4617cf702bc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13626/src/Test.java @@ -0,0 +1,16 @@ +class Test +{ +class Test +{ + public void x() + { + boolean a = false; + boolean b = true; + + do + { + a = true; + } + while( !a && b ); + } +}} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13702/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13702/src/Foo.java new file mode 100644 index 00000000000..84c31a6bf5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13702/src/Foo.java @@ -0,0 +1,5 @@ +public class Foo { + public void foo() { + do {} while(false); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13871/src/Aaa.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13871/src/Aaa.java new file mode 100644 index 00000000000..793f5314fc6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR13871/src/Aaa.java @@ -0,0 +1,12 @@ +public class Aaa { + Object getObject() { + return null; + } + + void f() { + Object obj = getObject(); + if (obj instanceof Aaa || obj == null) { + Aaa a = (Aaa) obj; // inspection reports that ClassCastException can be thrown + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14314/src/Finally.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14314/src/Finally.java new file mode 100644 index 00000000000..2d8b0486510 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14314/src/Finally.java @@ -0,0 +1,37 @@ +import java.io.*; + +public class Finally { + public void foo(Object o) { + try { + if (o == null) return; + } + finally { + System.out.println(o.hashCode()); // Error here. + } + System.out.println(o.hashCode()); // No error here. + } + + public void bar(Object o) { + boolean rearrangeChildren = false; + Object typePattern; + try { + typePattern = parseTypePattern(); + } catch (FileNotFoundException followsFailure) { + if (o != null) { + typePattern = followsFailure.getParsingResult(); + } else { + throw followsFailure; + } + + rearrangeChildren = true; + } + + if (rearrangeChildren) { + System.out.println("Can be here."); + } + } + + Object parseTypePattern() throws IOException { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14819/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14819/src/Test.java new file mode 100644 index 00000000000..daf1450dec9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR14819/src/Test.java @@ -0,0 +1,17 @@ +public class Test { + public Test foo(Test t) { + if (t instanceof Test) { // redundant instanceof error here. t can be null + foo(null); + } + } + public Object bar(Test t) { + if (t == null) return; + if (t instanceof Test) { // always true error here. t can't be null + foo(null); + } + + if (bar(null) instanceof Test) return null; // no error here. + if (foo(null) instanceof Test) return null; // redundant instanceof error here. foo(null) can be null + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15162/src/NullTest.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15162/src/NullTest.java new file mode 100644 index 00000000000..c598e755c32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15162/src/NullTest.java @@ -0,0 +1,9 @@ +public class NullTest { + int m; + void f() {}; + public void x() { + NullTest t = null; + t.m = 12; + t.f(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15406/src/CodeFlowTest.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15406/src/CodeFlowTest.java new file mode 100644 index 00000000000..187d602f646 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR15406/src/CodeFlowTest.java @@ -0,0 +1,28 @@ +public class CodeFlowTest { + public static void main (String[] args) { + String string; + Exception exception; + try { + string = getString(); + exception = null; + } catch (SomeException e1) { + string = null; + exception = e1; + } + + if (string != null) + System.out.println ("Not null"); + else + exception.printStackTrace(); + } + + private static String getString () throws SomeException { + if (Math.random() < 0.5) + throw new SomeException(); + else + return ""; + } + + private static class SomeException extends Exception { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR18186/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR18186/src/Test.java new file mode 100644 index 00000000000..5c0f3fdb52b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR18186/src/Test.java @@ -0,0 +1,61 @@ +import java.sql.*; + +public class Test { + + /** + * L�dt den Datensatz. + */ + private boolean loadValues(Transaction transaction) { + try { + boolean res=false; + PreparedStatement stmt=transaction.dirty() ? transaction.dbstore().stmtGetDirty(this) : transaction.dbstore().stmtGetClean(this); + if (stmt==null) return false; + synchronized(stmt) { + try { + transaction.dbmanager.dbstore().loadsCount++; + try { + fillPHPK(stmt, transaction); + } catch (SQLException e) { + DBManager.resetThread(stmt); + throw e; + } + ResultSet rs=stmt.executeQuery(); + try { + if (rs.next()) { + loadOrdered(rs); + res=true; + } else if (transaction.dbmanager.accessCommitBug()) { + // Scheint manchmal in Access zu passieren.... + PreparedStatement stmt1=transaction.dirty() ? stmtGetDirty(transaction.dbstore()) : stmtGetClean(transaction.dbstore()); + synchronized(stmt1) + { + fillPHPK(stmt1, transaction); + ResultSet rs1=stmt1.executeQuery(); + if (rs1.next()) { + Dbg.pw("Second try to load object returns an object: "+toString()+"???"); + loadOrdered(rs1); + res=true; + } + rs1.close(); + stmt1.close(); + } + } + } finally { + try { + rs.close(); + } catch (SQLException e) { + Dbg.pw(e); + } + } + } catch (SQLException e) { + handleSQLException(e, stmt); + } + } + if (res) loadBlobs(transaction); + return res; + } catch (SQLException e) { + throw new ExceptionBag(e); + } + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR39950/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR39950/src/Test.java new file mode 100644 index 00000000000..c31d7cff7cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/SCR39950/src/Test.java @@ -0,0 +1,12 @@ +interface Inter {} + +class Impl implements Inter {} + +class TestGenericsInstanceof +{ + I member; + + { + boolean test = member instanceof Impl; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/andEq/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/andEq/src/Test.java new file mode 100644 index 00000000000..8919f1582c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/andEq/src/Test.java @@ -0,0 +1,8 @@ +public class Test { + public void foo(boolean x, boolean y, boolean z) { + boolean r = true; + r &= x; + r &= y; + r &= z; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/caseAndNpe/src/CaseAndNpe.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/caseAndNpe/src/CaseAndNpe.java new file mode 100644 index 00000000000..91643d5815b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/caseAndNpe/src/CaseAndNpe.java @@ -0,0 +1,122 @@ +/* + * Created by IntelliJ IDEA. + * User: max + * Date: Jan 4, 2002 + * Time: 4:01:21 PM + * To change template for new interface use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package test.deadcode; + +import java.io.IOException; + +public class aaa { + int a; + int b; + + void x(int i, Object o) { + if (o == null) { + i = 2; + } + + if (o instanceof String) { + o.equals(o); + } + + o.equals(o); + + if (i == 3) { + System.out.println(""); + } + if (i == 3) { + o.equals(o); + o.equals(o); + } + + o.equals(o); + + + if (i == 2) { + i = 6; + } else { + i = 5; + } + + //System.exit(0); + + switch(i) { + case 1: System.out.println("1 not reachable"); break; + case 2: System.out.println("2 not reachable"); break; + case 6: System.out.println("6 reachable"); break; + case 5: System.out.println("5 reachable"); break; + default: System.out.println("Default not reachable"); break; + } + int j = 0; + + for (; i < 5; i++, j++) {} + } + + void canBeStatic() { + for (int i = 15; i >= 0; --i) + { + if ((i==4) || (i==10)) + { + //actual block body removed + } + } + + for (int i = 0; i < null; i++) { + a = i; + this.a = i; + } + + if (a != b && a != 5) { + a = 3; + } else { + a = 4; + } + + if (a != null && a instanceof aaa) { + if (true) { + //a = new aaa(); + } + } + + a = 6 + 1; + } +} + + +class Test +{ + public static int myunusedfield1 = 0; + // --Recycle Bin (3/29/02 6:44 PM)public static int myunusedfield2 = 0; + public static int myunusedfield3 = 0; + // --Recycle Bin (3/29/02 6:44 PM)public static int myunusedfield4 = 0; + public static int myunusedfield5 = 0; + + + void testMethod1() throws IOException {} + void testMethod2() throws IOException {} + + public void main(String argv[]) + { + boolean callingMethod1 = false; + try + { + int i = (int) 0; + callingMethod1 = true; + testMethod1(); + callingMethod1 = false; + testMethod2(); + } + catch (IOException e) + { + if (callingMethod1) + System.err.println("Error while calling method 1"); + else + System.err.println("Error while calling method 2"); + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/cce/src/Cce.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/cce/src/Cce.java new file mode 100644 index 00000000000..a8bc96ef8b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/cce/src/Cce.java @@ -0,0 +1,19 @@ +class A { +} + +class B { +} + +public class Cce { + public void a() { + Object o = getObject(); + + if (o instanceof A) { + B b = (B) o; + } + } + + Object getObject() { + return new A(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/exceptionCFG/src/ExceptionCFG.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/exceptionCFG/src/ExceptionCFG.java new file mode 100644 index 00000000000..659fd1f5112 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/exceptionCFG/src/ExceptionCFG.java @@ -0,0 +1,34 @@ +import java.io.*; + +class Test +{ + public static int myunusedfield1 = 0; + // --Recycle Bin (3/29/02 6:44 PM)public static int myunusedfield2 = 0; + public static int myunusedfield3 = 0; + // --Recycle Bin (3/29/02 6:44 PM)public static int myunusedfield4 = 0; + public static int myunusedfield5 = 0; + + + void testMethod1() throws IOException {} + void testMethod2() throws IOException {} + + public void main(String argv[]) + { + boolean callingMethod1 = false; + try + { + int i = (int) 0; + callingMethod1 = true; + testMethod1(); + callingMethod1 = false; + testMethod2(); + } + catch (IOException e) + { + if (callingMethod1) + System.err.println("Error while calling method 1"); + else + System.err.println("Error while calling method 2"); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/inst/src/Inst.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/inst/src/Inst.java new file mode 100644 index 00000000000..abe5fcfe4a6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/inst/src/Inst.java @@ -0,0 +1,27 @@ +class A { + +} + +class B extends A { + +} + +public class Inst { + public void x() { + Object a = new Object(); + + + if (a instanceof B) { + A aa =(A) a; + if (a instanceof A) { + System.out.println("HeHe"); + } + System.out.println(aa); + } + } + + public void y(Object a) { + if (a instanceof A) {} + if (a instanceof B) {} + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/npe1/src/Npe.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/npe1/src/Npe.java new file mode 100644 index 00000000000..10152e0516e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/npe1/src/Npe.java @@ -0,0 +1,9 @@ +public class Npe { + public void a(Object o) { + if (o != null) { + // Do something + } + + o.equals(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/nullableField/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/nullableField/src/Test.java new file mode 100644 index 00000000000..ddc0dbec52a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/nullableField/src/Test.java @@ -0,0 +1,8 @@ +public class Test { + public String s; + + public void foo() { + s = null; + boolean b = s.equals(s); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/orBug/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/orBug/src/Test.java new file mode 100644 index 00000000000..b89e24d343e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/orBug/src/Test.java @@ -0,0 +1,8 @@ +public class Test { + public boolean abc(Object o1, Object o2) { + if (o1 == null || o2 == null) { + return o1 == o2; + } + return false; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/scrIDEA1/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/scrIDEA1/src/Test.java new file mode 100644 index 00000000000..bd444a97514 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/scrIDEA1/src/Test.java @@ -0,0 +1,16 @@ +import java.io.FileOutputStream; + +class Test { + static void foo() throws Exception { + FileOutputStream fos = null; + + try { + fos = new FileOutputStream("c:\\myfile"); + } catch (Exception ex) { + throw new Exception("Oh, dear me.", ex); + } finally { + if (fos != null) { + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/thisInstanceof/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/thisInstanceof/src/Test.java new file mode 100644 index 00000000000..c72dd6d2499 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/thisInstanceof/src/Test.java @@ -0,0 +1,5 @@ +public class Test { + public void foo() { + boolean b = this instanceof Object; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/wrongEqualTypes/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/wrongEqualTypes/src/Test.java new file mode 100644 index 00000000000..e514b19a236 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/wrongEqualTypes/src/Test.java @@ -0,0 +1,8 @@ +import java.util.Calendar; + +public class Test { + public void foo(Object c) { + if (c instanceof Calendar) return; + if (c == Calendar.getInstance()) {} + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/xor/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/xor/src/Test.java new file mode 100644 index 00000000000..a4d45845a38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/dataFlow/xor/src/Test.java @@ -0,0 +1,8 @@ +public class Test { + public static void test(final Object a, final Object b) { + if ((a == null ^ b == null) + || (a != null && a.hashCode() != b.hashCode())) { + System.out.println("aaa"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR28019/src/AsynchronousImageLoader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR28019/src/AsynchronousImageLoader.java new file mode 100644 index 00000000000..e09f950af6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR28019/src/AsynchronousImageLoader.java @@ -0,0 +1,17 @@ +import java.util.Stack; + +public class AsynchronousImageLoader extends Thread { + private final Stack _tasks = new Stack(); + + private void threadBody() throws InterruptedException { + while (true) { + final Runnable task; + synchronized (this) { + while (_tasks.isEmpty()) + wait(); + task = (Runnable) _tasks.pop(); + } + task.run(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR40364/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR40364/src/Test.java new file mode 100644 index 00000000000..f066e3c24f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR40364/src/Test.java @@ -0,0 +1,16 @@ +package spike; + +public class A +{ + public static void main (String[] args) + { + boolean thereIsMoreToParse; + do { + thereIsMoreToParse = buildNextObject (); + } while (thereIsMoreToParse); + } + + private static boolean buildNextObject () { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR5144/src/AssignTest.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR5144/src/AssignTest.java new file mode 100644 index 00000000000..4a1fe58c7a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR5144/src/AssignTest.java @@ -0,0 +1,10 @@ +public class AssignTest { + public static void main(String[] args) { + int foo = 0; + + while (true) { + if (foo != 12) System.out.println("Test"); + if (Math.random() > 0.5) foo = 22; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR6843/src/NotUsedTest.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR6843/src/NotUsedTest.java new file mode 100644 index 00000000000..b961b19b037 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/SCR6843/src/NotUsedTest.java @@ -0,0 +1,7 @@ +public class NotUsedTest { + public static void main(String[] args) { + boolean unused = true; + unused = true; + unused = true; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/arrayIndexUsages/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/arrayIndexUsages/src/Foo.java new file mode 100644 index 00000000000..2a7decddb7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/arrayIndexUsages/src/Foo.java @@ -0,0 +1,11 @@ +public class Foo { + int myOffset; + void foo() { + int offset = myOffset + 4; + byte[] a = new byte[10]; + byte b1 = a[offset++]; + byte b2 = a[offset++]; + System.out.println(b1); + System.out.println(b2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/unusedVariable/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/unusedVariable/src/Foo.java new file mode 100644 index 00000000000..e72ecec1bb7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/defUse/unusedVariable/src/Foo.java @@ -0,0 +1,5 @@ +public class Foo { + public void foo() { + int i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapter.java new file mode 100644 index 00000000000..3ba1002260f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapter.java @@ -0,0 +1,5 @@ +public class MyAdapter implements MyListener { + public void myListen1() {} + public void myListen2() {} + public void myListen3() {} +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapterUsage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapterUsage.java new file mode 100644 index 00000000000..53e4ec7127d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyAdapterUsage.java @@ -0,0 +1,8 @@ +public class MyAdapterUsage extends MyAdapter { + public void myListen1(){ + super.myListen1(); + } + public void myListen2(){ + System.out.println("code here"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyListener.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyListener.java new file mode 100644 index 00000000000..5e4ec637a52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/SCR8321/src/MyListener.java @@ -0,0 +1,5 @@ +public interface MyListener { + void myListen1(); + void myListen2(); + void myListen3(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/ext_src/Derived.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/ext_src/Derived.java new file mode 100644 index 00000000000..e9b4d3d03d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/ext_src/Derived.java @@ -0,0 +1,5 @@ +public class Derived extends Base { + public void foo() {} + public void bar() { System.out.println("Hello"); } + public void foobar() { super.foobar(); } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/src/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/src/Base.java new file mode 100644 index 00000000000..2a950b1c99a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/externalOverride/src/Base.java @@ -0,0 +1,5 @@ +public class Base { + public void foo() {} + public void bar() {} + public void foobar() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Base.java new file mode 100644 index 00000000000..38396c551f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Base.java @@ -0,0 +1,3 @@ +public class Base { + public void foo() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Derived.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Derived.java new file mode 100644 index 00000000000..506a17561d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/emptyMethod/superCall/src/Derived.java @@ -0,0 +1,5 @@ +public class Derived extends Base { + public void foo() { + super.foo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR11757/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR11757/src/Test.java new file mode 100644 index 00000000000..9891721408e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR11757/src/Test.java @@ -0,0 +1,24 @@ +public class Test { + public int fib(int n) { + switch (n) { + case 0: + return 0; + // you can comment out the next three lines -- same thing + case 1: + case 2: + return 1; + default: + int a; + int b = 1; + int c = 2; + n -= 3; + while (n-- > 0) { + a = b; + b = c; + c = a + b; + } + return c; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_1/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_1/src/foo/Test.java new file mode 100644 index 00000000000..eee442218aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_1/src/foo/Test.java @@ -0,0 +1,6 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_2/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_2/src/foo/Test.java new file mode 100644 index 00000000000..06ff2f3fa27 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_2/src/foo/Test.java @@ -0,0 +1,7 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + int foo = 12; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_3/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_3/src/foo/Test.java new file mode 100644 index 00000000000..8400897ce59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_3/src/foo/Test.java @@ -0,0 +1,7 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + final int foo = 12; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_4/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_4/src/foo/Test.java new file mode 100644 index 00000000000..38d7c37f384 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_4/src/foo/Test.java @@ -0,0 +1,8 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + final int foo = 12; + final int bar = 24; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_5/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_5/src/foo/Test.java new file mode 100644 index 00000000000..80fc34b33f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_5/src/foo/Test.java @@ -0,0 +1,9 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + final int foo = 12; + final int bar = 24; + final int gazonk = 48; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_6/src/foo/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_6/src/foo/Test.java new file mode 100644 index 00000000000..e0bda3b46aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR6744_6/src/foo/Test.java @@ -0,0 +1,10 @@ +package foo; + +public class Test { + public static void main(final String[] args) { + final int foo = 12; + final int bar = 24; + final int gazonk = 48; + final int banana = 96; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428/src/Junk.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428/src/Junk.java new file mode 100644 index 00000000000..bc26cc4f959 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428/src/Junk.java @@ -0,0 +1,20 @@ +public final class Junk + { + public void sillyMethod() + { + String bar = "bar"; + try + { + int i = 1; + String foo = "foo"; + System.out.println("[" + bar + "|" + i + "|" + foo + "]"); + //throw new Exception(); + } + catch (Exception e) + { + int j = 2; + System.out.println("j = [" + j + "]"); + } + } + } + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428_1/src/Junk.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428_1/src/Junk.java new file mode 100644 index 00000000000..b8b201c6c7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7428_1/src/Junk.java @@ -0,0 +1,24 @@ +public final class Junk + { + public void sillyMethod() + { + String bar = "bar"; + try + { + int i = 1; + String foo = "foo"; + System.out.println("[" + bar + "|" + i + "|" + foo + "]"); + throw new Exception(); + } + catch (Exception e) + { + int j = 2; + System.out.println("j = [" + j + "]"); + } + finally + { + System.out.println("In finally"); + } + } + } + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7601/src/TestFinal2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7601/src/TestFinal2.java new file mode 100644 index 00000000000..47e1d07457b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/SCR7601/src/TestFinal2.java @@ -0,0 +1,8 @@ +public class TestFinal2 { + static void foo(final boolean b) { + if (b) { + int i = 12; + System.out.println("i = " + i); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/if/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/if/src/Test.java new file mode 100644 index 00000000000..e329d6360cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/if/src/Test.java @@ -0,0 +1,11 @@ +public class Test{ + + public void t() { + Object v; + if (true) { + v = new Object(); + } else { + v = new Object(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/incompleteAssignment/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/incompleteAssignment/src/Test.java new file mode 100644 index 00000000000..ec4ab9130e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/incompleteAssignment/src/Test.java @@ -0,0 +1,13 @@ +public class Test{ + + public void t() { + Object v; + Object o; + if (true) { + v = new Object(); + o = new Object(); + } else { + } + System.out.println(v); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/multiWriteNoRead/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/multiWriteNoRead/src/Test.java new file mode 100644 index 00000000000..6a08490b204 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/multiWriteNoRead/src/Test.java @@ -0,0 +1,9 @@ +public class Test{ + + public void t() { + Object v; + for (int i = 0;i<10;i++) { + v = new Object(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/parameters/src/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/parameters/src/Test.java new file mode 100644 index 00000000000..c104d3f7fff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/localCanBeFinal/parameters/src/Test.java @@ -0,0 +1,19 @@ +public class Test +{ + public static void main(String[] args) { + System.out.println(args[0]); + } + + public static void foo(String cannotBeFinal) { + cannotBeFinal = ""; + System.out.println(cannotBeFinal); + } + + public static void bar(final String alreadyFinal) { + System.out.println(alreadyFinal); + } + + public static void bar1(final String alreadyFinal) { + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR14543/src/E.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR14543/src/E.java new file mode 100644 index 00000000000..39908e0b92e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR14543/src/E.java @@ -0,0 +1,14 @@ +class D extends E { + + protected void doSomething() throws Exception { + throw new Exception(); + } + +} + + +public abstract class E { + + protected abstract void doSomething() throws Exception; + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR6858/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR6858/src/Foo.java new file mode 100644 index 00000000000..87999871dfb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR6858/src/Foo.java @@ -0,0 +1,6 @@ +import java.io.*; + +public class Foo { + public Foo() throws IOException { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClass.java new file mode 100644 index 00000000000..aab32421904 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClass.java @@ -0,0 +1,13 @@ +package aPackage; + +import java.io.IOException; + +public class AClass implements AnInterface{ + int aField_1; + int aField_2; + + public void methodA(int myInt) throws IOException { + //some code here + aField_1 = 1; + } + } diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClassTwo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClassTwo.java new file mode 100644 index 00000000000..cd05bdd4367 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AClassTwo.java @@ -0,0 +1,10 @@ +package aPackage; + +import java.io.IOException; + +public class AClassTwo implements AnInterface { + + public void methodA(int myInt) throws IOException{ + //some code here + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AnInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AnInterface.java new file mode 100644 index 00000000000..5fb88255580 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/redundantThrow/SCR8322/src/aPackage/AnInterface.java @@ -0,0 +1,7 @@ +package aPackage; + +import java.io.IOException; + +public interface AnInterface { + void methodA(int myInt) throws IOException; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR11792/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR11792/src/Foo.java new file mode 100644 index 00000000000..6b57ff94598 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR11792/src/Foo.java @@ -0,0 +1,10 @@ +class Foo { + private void method() { + final class MyClass{} + Object o = new MyClass(); + } + + private void foo() { + method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SubClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SubClass.java new file mode 100644 index 00000000000..bfd92b2975c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SubClass.java @@ -0,0 +1,6 @@ +package marti.p1; +class SubClass extends SuperClass{ + public SubClass() { + super(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SuperClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SuperClass.java new file mode 100644 index 00000000000..328175d0d38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR5008/src/marti/p1/SuperClass.java @@ -0,0 +1,5 @@ +package marti.p1; +class SuperClass { + public SuperClass() { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR6856/src/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR6856/src/A.java new file mode 100644 index 00000000000..8db06689cef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/SCR6856/src/A.java @@ -0,0 +1,12 @@ +class A { + static class B { + int k=0; + { + System.out.println(k); + } + } + public static void main(String[] args) { + new B(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/innerConstructor/src/Foo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/innerConstructor/src/Foo.java new file mode 100644 index 00000000000..61590164fe0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/innerConstructor/src/Foo.java @@ -0,0 +1,7 @@ +class Foo { + private final Bar bar = new Bar(); + private class Bar { + public Bar() { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PackageLevelServer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PackageLevelServer.java new file mode 100644 index 00000000000..656f2b9cb1e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PackageLevelServer.java @@ -0,0 +1,5 @@ +package package1; + +public class PackageLevelServer { + public static void foo() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PublicServer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PublicServer.java new file mode 100644 index 00000000000..398dc0e97aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package1/PublicServer.java @@ -0,0 +1,5 @@ +package package1; + +public class PublicServer { + public static void foo() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package2/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package2/Client.java new file mode 100644 index 00000000000..5b55de3fdc9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/inspection/visibility/packageLevelTops/src/package2/Client.java @@ -0,0 +1,9 @@ +package package2; + +import package1.PublicServer; + +class Client { + public static void main(String args[]) { + PublicServer.foo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class1.java new file mode 100644 index 00000000000..9fc5f3f76d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class1.java @@ -0,0 +1,4 @@ +package com.package1; + +public class Class1 { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class2.java new file mode 100644 index 00000000000..00c893c7578 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class2.java @@ -0,0 +1,8 @@ +package com.package1; + +public class Class2 { +} + +class Class3 { + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class4.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class4.java new file mode 100644 index 00000000000..73eeb93a4ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Class4.java @@ -0,0 +1,4 @@ +package com.package1; + +public Class4 { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Form1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Form1.java new file mode 100644 index 00000000000..24fb0ad4995 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/projectView/standardProviders/src/com/package1/Form1.java @@ -0,0 +1,4 @@ +package com.package1; + +public class Form1 { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Bla.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Bla.java new file mode 100644 index 00000000000..0b0955c30f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Bla.java @@ -0,0 +1,4 @@ +package bla; + +public class Bla { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Blu.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Blu.java new file mode 100644 index 00000000000..13283b2f86a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/arrayIndexOutOfBounds/src/bla/Blu.java @@ -0,0 +1,4 @@ +package bla; + +public class Blu { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/constantValues/ClassWithConstants.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/constantValues/ClassWithConstants.java new file mode 100644 index 00000000000..e0e015ede07 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/constantValues/ClassWithConstants.java @@ -0,0 +1,19 @@ +public class ClassWithConstants { + public static final int INT_CONST1 = 1; + public static final int INT_CONST2 = -1; + public static final int INT_CONST3 = -2147483648; + public static final long LONG_CONST1 = 2; + public static final long LONG_CONST2 = 1000000000000L; + public static final long LONG_CONST3 = -9223372036854775808L; + public static final short SHORT_CONST = 3; + public static final byte BYTE_CONST = 4; + public static final char CHAR_CONST = '5'; + public static final boolean BOOL_CONST = true; + public static final float FLOAT_CONST = 1.234f; + public static final double DOUBLE_CONST = 3.456; + public static final java.lang.String STRING_CONST = "a\r\n\"bcd"; + + public static final double d1 = Double.POSITIVE_INFINITY; + public static final double d2 = Double.NEGATIVE_INFINITY; + public static final double d3 = Double.NaN; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1.java new file mode 100644 index 00000000000..de28d4e3f1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1.java @@ -0,0 +1,5 @@ +class A{ + { + AAA[] x[], y, z; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1_after.java new file mode 100644 index 00000000000..af20328429f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/1_after.java @@ -0,0 +1,7 @@ +class A{ + { + AAA[][] x; + AAA[] y; + AAA[] z; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2.java new file mode 100644 index 00000000000..c78020d764c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2.java @@ -0,0 +1,5 @@ +class A{ + { + AAA[] x [][], y, z; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2_after.java new file mode 100644 index 00000000000..6713d93c26c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/2_after.java @@ -0,0 +1,7 @@ +class A{ + { + AAA[][][] x ; + AAA[] y; + AAA[] z; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549.java new file mode 100644 index 00000000000..e43504ff426 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549.java @@ -0,0 +1,5 @@ +class A{ + { + long x, y; // comment + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549_after.java new file mode 100644 index 00000000000..7027e93b0e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR6549_after.java @@ -0,0 +1,6 @@ +class A{ + { + long x; // comment + long y; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467.java new file mode 100644 index 00000000000..336648d903f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467.java @@ -0,0 +1,5 @@ +class A{ + { + final int a = 1, b = 2, c = 3; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1.java new file mode 100644 index 00000000000..719e53ddebd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1.java @@ -0,0 +1,3 @@ +class A{ + final int a = 1, b = 2, c = 3; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1_after.java new file mode 100644 index 00000000000..e1b2d3ad898 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_1_after.java @@ -0,0 +1,5 @@ +class A{ + final int a = 1; + final int b = 2; + final int c = 3; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_after.java new file mode 100644 index 00000000000..acacab68975 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/psi/normalizeDeclaration/SCR9467_after.java @@ -0,0 +1,7 @@ +class A{ + { + final int a = 1; + final int b = 2; + final int c = 3; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/AddParam.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/AddParam.java new file mode 100644 index 00000000000..7adfcf047b6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/AddParam.java @@ -0,0 +1,9 @@ +class L {} +class C { +} + +class Usage extends C { + { + C c = new C(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/NoParams.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/NoParams.java new file mode 100644 index 00000000000..84071ab3499 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/NoParams.java @@ -0,0 +1,10 @@ +class C { +} + +class Usage extends C { + { + C c = new C(); + + C c = new C() { } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/RemoveAllParams.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/RemoveAllParams.java new file mode 100644 index 00000000000..fa4e6a0d371 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/RemoveAllParams.java @@ -0,0 +1,5 @@ +class C { + { + C c = new C(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/ReorderParams.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/ReorderParams.java new file mode 100644 index 00000000000..5edc5bcf35b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeClassSignature/ReorderParams.java @@ -0,0 +1,8 @@ +class C { +} + +class Usage extends C { + { + C = new C(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AddRuntimeException.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AddRuntimeException.java new file mode 100644 index 00000000000..cf59542ef50 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AddRuntimeException.java @@ -0,0 +1,8 @@ +class Test { + void foo () { + } + + void bar () { + foo(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AlreadyHandled.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AlreadyHandled.java new file mode 100644 index 00000000000..43ecdda106a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/AlreadyHandled.java @@ -0,0 +1,8 @@ +class Test { + void foo () { + } + + void bar () throws Exception { + foo(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/CovariantReturnType.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/CovariantReturnType.java new file mode 100644 index 00000000000..4498755a3cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/CovariantReturnType.java @@ -0,0 +1,19 @@ +import java.util.*; + +class A { + List method() { } +} + +class Q implements List, Runnable { +} + +class Z implements List { +} + +class B extends A { + Q method() { } +} + +class C extends A { + Z method() { } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/DefaultConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/DefaultConstructor.java new file mode 100644 index 00000000000..e3306bd1fba --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/DefaultConstructor.java @@ -0,0 +1,11 @@ +class C { + C() { + } +} + +class C1 extends C { + int i; + C1(int i, int k) { + this.i = i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/EnumConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/EnumConstructor.java new file mode 100644 index 00000000000..5047f3326b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/EnumConstructor.java @@ -0,0 +1,7 @@ +enum En { + A {}, + B {}, + C; + + En() { } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegate.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegate.java new file mode 100644 index 00000000000..48b3e4b82c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegate.java @@ -0,0 +1,16 @@ +class C { + void method() { + } +} + +class C1 extends C { + void method() { + } +} + +class Usage { + { + new C().method(); + new C1().method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateConstructor.java new file mode 100644 index 00000000000..48cfaa08926 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateConstructor.java @@ -0,0 +1,10 @@ +public class C { + public C(int i) { + } +} + +class Usage { + { + C c = new C(10); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateDefaultConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateDefaultConstructor.java new file mode 100644 index 00000000000..2c160ef3c24 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateDefaultConstructor.java @@ -0,0 +1,15 @@ +public class C { + public C() { + } +} + +public class C1 extends C { + public C1(String s) { + } +} + +class Usage { + { + C c = new C(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateForAbstract.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateForAbstract.java new file mode 100644 index 00000000000..06b48f546a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateForAbstract.java @@ -0,0 +1,8 @@ +abstract class C { + abstract void method(); +} + +class C1 extends C { + void method() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithParametersReordering.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithParametersReordering.java new file mode 100644 index 00000000000..9daa31d2179 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithParametersReordering.java @@ -0,0 +1,18 @@ +class C { + void method(int i, String s) { + System.out.println("i = " + i + " s = " + s); + } +} + +class C1 extends C { + void method(int i, String s) { + System.out.println("i = " + i + " s = " + s); + } +} + +class Usage { + { + new C().method(1, null); + new C1().method(1, null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithReturn.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithReturn.java new file mode 100644 index 00000000000..ecf94ad4c4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenerateDelegateWithReturn.java @@ -0,0 +1,9 @@ +class C { + String method() { + } +} + +class C1 extends C { + String method() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypes.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypes.java new file mode 100644 index 00000000000..7797cb7f964 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypes.java @@ -0,0 +1,7 @@ +class C { + void method(); +} + +class C1 extends C { + void method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypesInOldParameters.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypesInOldParameters.java new file mode 100644 index 00000000000..6bddf122aeb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/GenericTypesInOldParameters.java @@ -0,0 +1,11 @@ +class C { + void put(Object o) { + System.out.println(o); + } +} + +class CString extends C { + void put(Object o) { + System.out.println(o+"Text"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ParameterReorder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ParameterReorder.java new file mode 100644 index 00000000000..4481a35676f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ParameterReorder.java @@ -0,0 +1,11 @@ +class A { + public int method(int i, int j) { + return i - j; + } +} + +class B extends A { + public void method(int j, int i) { + return i - j; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ReorderExceptions.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ReorderExceptions.java new file mode 100644 index 00000000000..d492b54f226 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/ReorderExceptions.java @@ -0,0 +1,34 @@ +class MyException extends Exception{ +} + +class MyException1 extends Exception{ +} + +class Test { + void foo () throws MyException, + MyException1 { + } + + void bar () { + try { + foo(); + } + catch (MyException e) {} + catch (MyException1 myException1) {} + } +} + +class Derived extends Test { + void foo() throws MyException, + MyException1 { + + } + + void bar () { + try { + foo(); + } + catch (MyException e) {} + catch (MyException1 myException1) {} + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/SCR40895.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/SCR40895.java new file mode 100644 index 00000000000..05e4785c2e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/SCR40895.java @@ -0,0 +1,9 @@ +class X { + + /** + * Has a method called {@link #mymethod(int,int)}. + */ + public class TestRefactorLink { + public void mymethod(int y, int z) { } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Simple.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Simple.java new file mode 100644 index 00000000000..7c644e4eac7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Simple.java @@ -0,0 +1,7 @@ +class A { + void method(int i); +} + +class B extends A { + void method(int k); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/TypeParametersInMethod.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/TypeParametersInMethod.java new file mode 100644 index 00000000000..d91d98d3f0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/TypeParametersInMethod.java @@ -0,0 +1,9 @@ +class C { + protected U method(){ + } +} + +class C1 extends C { + protected V method(){ + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/UseAnyVariable.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/UseAnyVariable.java new file mode 100644 index 00000000000..b86284eaeb8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/UseAnyVariable.java @@ -0,0 +1,14 @@ +import java.util.List; + +class C { + void method() { + } +} + +class Usage { + List myList; + { + C c = new C(); + c.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Varargs1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Varargs1.java new file mode 100644 index 00000000000..b26fd25bf97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/changeSignature/Varargs1.java @@ -0,0 +1,10 @@ +class C { + void method(int... args) { + } + + { + method(1,2); + method(1,2,3); + method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface.java new file mode 100644 index 00000000000..07f45aeefa0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface.java @@ -0,0 +1,22 @@ +interface I { +} + +interface J extends I { +} + +class IImpl implements I { +} + +class JImpl implements J { +} + +class X { + static void method(int i, I intf) { + System.out.println("i = " + i + ", intf = " + intf); + } + + { + J j = new JImpl(); + method(0, j); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface2.java new file mode 100644 index 00000000000..1915b88b312 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Interface2.java @@ -0,0 +1,16 @@ +interface I { +} + +class C implements I { +} + +interface J extends I { +} + +class D extends C implements J { +} + +class X { + static void m(I i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/InterfaceTypeParameter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/InterfaceTypeParameter.java new file mode 100644 index 00000000000..c22af57f90a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/InterfaceTypeParameter.java @@ -0,0 +1,13 @@ +interface Intf { + T get(); +} + +class Impl implements Intf { +} + +class X { + static X method(Intf p, U value) { + U v = p.get(); + return new X(v,value); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Simple.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Simple.java new file mode 100644 index 00000000000..f038672a0c2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/Simple.java @@ -0,0 +1,16 @@ +public class Y { + public void foo() { + } +} +public class X { + static void method(Y y) { + System.out.println(y); + y.foo(); + } + + { + Y y = new Y(); + method(y); + method(new Y()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/TypeParameter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/TypeParameter.java new file mode 100644 index 00000000000..945f09e7739 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/convertToInstanceMethod/TypeParameter.java @@ -0,0 +1,7 @@ +class C { + T get() { return null; } + static void method(C c, V value, X x) { + V v = c.get(); + System.out.println(v + " " + value); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner.java new file mode 100644 index 00000000000..34a32465f82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner.java @@ -0,0 +1,21 @@ + +import javax.swing.*; +import java.awt.event.ActionEvent; + +public class ExtractMethods { } +abstract class MyButton + extends JButton + { + protected MyButton( String text ) { + super( text ); + } +} +class Foo { + private JButton createOKButton() { + return new MyButton( "OK" ) { + public void actionPerformed( ActionEvent e ) { + setVisible( false ); + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner_after.java new file mode 100644 index 00000000000..64daea1fa04 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/AnonInner_after.java @@ -0,0 +1,25 @@ + +import javax.swing.*; +import java.awt.event.ActionEvent; + +public class ExtractMethods { } +abstract class MyButton + extends JButton + { + protected MyButton( String text ) { + super( text ); + } +} +class Foo { + private JButton createOKButton() { + return new MyButton( "OK" ) { + public void actionPerformed( ActionEvent e ) { + newMethod(); + } + }; + } + + private void newMethod() { + setVisible( false ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression.java new file mode 100644 index 00000000000..e039152086e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression.java @@ -0,0 +1,5 @@ +class Test { + void method(int i) { + boolean isDirty = i == 0 || otherTests(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression_after.java new file mode 100644 index 00000000000..859d12c4388 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/BooleanExpression_after.java @@ -0,0 +1,9 @@ +class Test { + void method(int i) { + boolean isDirty = newMethod(i) || otherTests(); + } + + private boolean newMethod(int i) { + return i == 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates.java new file mode 100644 index 00000000000..291e623a151 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates.java @@ -0,0 +1,8 @@ +class C { + { + int i; + + System.out.println(i); + System.out.println(128); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2.java new file mode 100644 index 00000000000..0ac81a21b96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2.java @@ -0,0 +1,15 @@ +class C { + { + Object[] array; + + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + + + Object[] array1; + for (int i = 0; i < array1.length; i++) { + System.out.println(array[i]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2_after.java new file mode 100644 index 00000000000..e4a1b396e91 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates2_after.java @@ -0,0 +1,19 @@ +class C { + { + Object[] array; + + newMethod(array); + + + Object[] array1; + for (int i = 0; i < array1.length; i++) { + System.out.println(array[i]); + } + } + + private void newMethod(Object[] array) { + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3.java new file mode 100644 index 00000000000..70538c646ea --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3.java @@ -0,0 +1,15 @@ +class C { + { + Object[] array; + + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + + + Object[] array1; + for (int i = 0; i < array1.length; i++) { + System.out.println(array1[i]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3_after.java new file mode 100644 index 00000000000..f2b59d1bcd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates3_after.java @@ -0,0 +1,17 @@ +class C { + { + Object[] array; + + newMethod(array); + + + Object[] array1; + newMethod(array1); + } + + private void newMethod(Object[] array) { + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4.java new file mode 100644 index 00000000000..f22baf62e3d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4.java @@ -0,0 +1,15 @@ +class C { + { + Object[] array; + + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + + + Object[] array1; + for (int j = 0; j < array1.length; j++) { + System.out.println(array1[j]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4_after.java new file mode 100644 index 00000000000..f2b59d1bcd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates4_after.java @@ -0,0 +1,17 @@ +class C { + { + Object[] array; + + newMethod(array); + + + Object[] array1; + newMethod(array1); + } + + private void newMethod(Object[] array) { + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5.java new file mode 100644 index 00000000000..c1cd3fc3be0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5.java @@ -0,0 +1,23 @@ +class C { + int myField = 10; + int myOtherField = 10; + + { + int i = 5; + myField = i; + myOtherField = i; + + C c = new C(); + + c.myField = 12; + c.myOtherField = 12; + + C c1 = new C(); + c1.myField = 12; + myOtherField = 12; + + + c.myField = 15; + c1.myOtherField = 15; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5_after.java new file mode 100644 index 00000000000..5adc4375a9a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates5_after.java @@ -0,0 +1,26 @@ +class C { + int myField = 10; + int myOtherField = 10; + + { + int i = 5; + newMethod(i); + + C c = new C(); + + c.newMethod(12); + + C c1 = new C(); + c1.myField = 12; + myOtherField = 12; + + + c.myField = 15; + c1.myOtherField = 15; + } + + private void newMethod(int i) { + myField = i; + myOtherField = i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue.java new file mode 100644 index 00000000000..74a2dfa1639 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue.java @@ -0,0 +1,16 @@ +import java.util.*; + +class C { + { + Object[] array; + + List l1 = new ArrayList(Arrays.asList(array)); + + List l2 = new ArrayList(Arrays.asList(getObjects())); + + System.out.println("l1 = " + l1 + ", l2 = " + l2); + } + + String[] getObjects() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1.java new file mode 100644 index 00000000000..549aafd9a13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1.java @@ -0,0 +1,19 @@ +import java.util.*; + +class C { + { + Object[] array; + + List l1 = null; + l1 = new ArrayList(Arrays.asList(array)); + + List l2 = null; + l2 = new ArrayList(Arrays.asList(getObjects())); + + System.out.println("l1 = " + l1 + ", l2 = " + l2); + } + + + String[] getObjects() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1_after.java new file mode 100644 index 00000000000..81ebc680633 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue1_after.java @@ -0,0 +1,23 @@ +import java.util.*; + +class C { + { + Object[] array; + + List l1 = newMethod(array); + + List l2 = newMethod(getObjects()); + + System.out.println("l1 = " + l1 + ", l2 = " + l2); + } + + private List newMethod(Object[] array) { + List l1 = null; + l1 = new ArrayList(Arrays.asList(array)); + return l1; + } + + + String[] getObjects() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue_after.java new file mode 100644 index 00000000000..a5e51c3985b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithOutputValue_after.java @@ -0,0 +1,21 @@ +import java.util.*; + +class C { + { + Object[] array; + + List l1 = newMethod(array); + + List l2 = newMethod(getObjects()); + + System.out.println("l1 = " + l1 + ", l2 = " + l2); + } + + private List newMethod(Object[] array) { + List l1 = new ArrayList(Arrays.asList(array)); + return l1; + } + + String[] getObjects() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn.java new file mode 100644 index 00000000000..451960db33b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn.java @@ -0,0 +1,13 @@ +class C { + String method(Object o) { + System.out.println(o); + Integer i = new Integer(o.hashCode()); + return i.toString(); + } + + { + String k; + Integer j = new Integer(Boolean.TRUE.hashCode()); + k = j.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2.java new file mode 100644 index 00000000000..81b99174c30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2.java @@ -0,0 +1,12 @@ +class C { + String method(Object o) { + System.out.println(o); + Integer i = new Integer(o.hashCode()); + return i.toString(); + } + + { + Integer j = new Integer(Boolean.TRUE.hashCode()); + String k = j.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2_after.java new file mode 100644 index 00000000000..7ccc2380d71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn2_after.java @@ -0,0 +1,15 @@ +class C { + String method(Object o) { + System.out.println(o); + return newMethod(o); + } + + private String newMethod(Object o) { + Integer i = new Integer(o.hashCode()); + return i.toString(); + } + + { + String k = newMethod(Boolean.TRUE); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn_after.java new file mode 100644 index 00000000000..9901f3b87d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicatesWithReturn_after.java @@ -0,0 +1,16 @@ +class C { + String method(Object o) { + System.out.println(o); + return newMethod(o); + } + + private String newMethod(Object o) { + Integer i = new Integer(o.hashCode()); + return i.toString(); + } + + { + String k; + k = newMethod(Boolean.TRUE); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates_after.java new file mode 100644 index 00000000000..e6b481d2e84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/CodeDuplicates_after.java @@ -0,0 +1,12 @@ +class C { + { + int i; + + newMethod(i); + newMethod(128); + } + + private void newMethod(int i) { + System.out.println(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints1.java new file mode 100644 index 00000000000..c6436dc7e56 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints1.java @@ -0,0 +1,9 @@ +class Test{ + public void foo() { + if (cond1){ + if (cond2) return; + } + else if (cond3){ + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints2.java new file mode 100644 index 00000000000..d291d24c451 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints2.java @@ -0,0 +1,10 @@ +class Test{ + public void foo() { + if (cond1){ + if (cond2) return; + } + else if (cond3){ + } + x(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints3.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints3.java new file mode 100644 index 00000000000..acc314bad83 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints3.java @@ -0,0 +1,10 @@ +class Test{ + void foo() { + if (cond1){ + if (cond2) return; + x(); + } + else if (cond3){ + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints4.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints4.java new file mode 100644 index 00000000000..6c6c395cb81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints4.java @@ -0,0 +1,12 @@ +class Test { + int method() { + try { + if(cond1) return 0; + else if(cond2) return 1; + System.out.println("Text"); + } finally { + doSomething(); + } + return 12; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5.java new file mode 100644 index 00000000000..954782bed34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5.java @@ -0,0 +1,12 @@ +class Test { + int method() { + try { + if(cond1) return 0; + else if(cond2) return 1; + return 27; + } finally { + doSomething(); + } + return 12; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5_after.java new file mode 100644 index 00000000000..217c29dd44c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPoints5_after.java @@ -0,0 +1,16 @@ +class Test { + int method() { + return newMethod(); + return 12; + } + + private int newMethod() { + try { + if(cond1) return 0; + else if(cond2) return 1; + return 27; + } finally { + doSomething(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPointsInsideLoop.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPointsInsideLoop.java new file mode 100644 index 00000000000..938c66db814 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExitPointsInsideLoop.java @@ -0,0 +1,9 @@ +class s { + void f(boolean b) { + for (;;) { + if (b) { + break; + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates.java new file mode 100644 index 00000000000..fe163dc3cc6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates.java @@ -0,0 +1,10 @@ +import java.util.*; + +class C { + { + Object[] o = null; + List l = new ArrayList(Arrays.asList(o)); + + List l1 = new ArrayList(Arrays.asList(new Object[0])); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates_after.java new file mode 100644 index 00000000000..a564ab13bde --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExpressionDuplicates_after.java @@ -0,0 +1,14 @@ +import java.util.*; + +class C { + { + Object[] o = null; + List l = newMethod(o); + + List l1 = newMethod(new Object[0]); + } + + private ArrayList newMethod(Object[] o) { + return new ArrayList(Arrays.asList(o)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous.java new file mode 100644 index 00000000000..fff14549581 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous.java @@ -0,0 +1,9 @@ +class Test { + public static void main() { + new Runnable() { + public void run() { + System.out.println("Text"); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous_after.java new file mode 100644 index 00000000000..ab504143f7b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromAnonymous_after.java @@ -0,0 +1,16 @@ + +import java.io.PrintStream; + +class Test { + public static void main() { + new Runnable() { + public void run() { + newMethod().println("Text"); + } + } + } + + private static PrintStream newMethod() { + return System.out; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock.java new file mode 100644 index 00000000000..60d31d8650e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock.java @@ -0,0 +1,10 @@ +class Test { + void method() { + System.out.println("1"); + { + System.out.println("2"); + System.out.println("3"); + } + System.out.println("4"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock_after.java new file mode 100644 index 00000000000..505534408b4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromCodeBlock_after.java @@ -0,0 +1,12 @@ +class Test { + void method() { + System.out.println("1"); + newMethod(); + System.out.println("4"); + } + + private void newMethod() { + System.out.println("2"); + System.out.println("3"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally.java new file mode 100644 index 00000000000..f398c31b5af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally.java @@ -0,0 +1,11 @@ +public class Test { + int method() { + try { + System.out.println("Text"); + return 0; + } finally { + System.out.println("!!!"); + return 1; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally_after.java new file mode 100644 index 00000000000..561cc007c24 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromFinally_after.java @@ -0,0 +1,15 @@ +public class Test { + int method() { + try { + System.out.println("Text"); + return 0; + } finally { + return newMethod(); + } + } + + private int newMethod() { + System.out.println("!!!"); + return 1; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally.java new file mode 100644 index 00000000000..ca866c1671e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally.java @@ -0,0 +1,10 @@ +public class S { + { + String s; + try { + s = ""; + } finally { + } + System.out.print(s); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally_after.java new file mode 100644 index 00000000000..52900ce6ee0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ExtractFromTryFinally_after.java @@ -0,0 +1,16 @@ +public class S { + { + String s; + try { + s = newMethod(); + } finally { + } + System.out.print(s); + } + + private String newMethod() { + String s; + s = ""; + return s; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar.java new file mode 100644 index 00000000000..61758edefc5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar.java @@ -0,0 +1,8 @@ +class C { + { + final int i = 128; + System.out.println("i = " + i); + + final int j = 128; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar_after.java new file mode 100644 index 00000000000..1c73b56ea94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/FinalOutputVar_after.java @@ -0,0 +1,13 @@ +class C { + { + final int i = newMethod(); + System.out.println("i = " + i); + + final int j = newMethod(); + } + + private int newMethod() { + final int i = 128; + return i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally.java new file mode 100644 index 00000000000..1b2b12d6885 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally.java @@ -0,0 +1,22 @@ +class Test { + void method(){ + try { + process.waitFor(); + } + catch(InterruptedException e) { + process.destroy(); + } + finally { + try { + myParsingThread.join(); + } + catch(InterruptedException e) { + } + compilerHandler.processTerminated(); + } + synchronized (this) { + myParsingThread = null; + } + someOtherCode(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally_after.java new file mode 100644 index 00000000000..73485d3a386 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Finally_after.java @@ -0,0 +1,26 @@ +class Test { + void method(){ + newMethod(); + someOtherCode(); + } + + private void newMethod() { + try { + process.waitFor(); + } + catch(InterruptedException e) { + process.destroy(); + } + finally { + try { + myParsingThread.join(); + } + catch(InterruptedException e) { + } + compilerHandler.processTerminated(); + } + synchronized (this) { + myParsingThread = null; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach.java new file mode 100644 index 00000000000..38a27a6bcbc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach.java @@ -0,0 +1,9 @@ +class Foo { + { + String[] args = getArgs(); + + for(String arg : args) { + System.out.println("arg = " + arg); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach_after.java new file mode 100644 index 00000000000..27a92aeba2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/ForEach_after.java @@ -0,0 +1,13 @@ +class Foo { + { + String[] args = getArgs(); + + for(String arg : args) { + newMethod(arg); + } + } + + private void newMethod(String arg) { + System.out.println("arg = " + arg); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug.java new file mode 100644 index 00000000000..a292e860e1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug.java @@ -0,0 +1,15 @@ +import java.io.OutputStream; + +class A { + { + try { + OutputStream out = null; + + try { + } finally { + out.close(); + } + } catch(Throwable t) { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug_after.java new file mode 100644 index 00000000000..8b344176f7d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/LesyaBug_after.java @@ -0,0 +1,20 @@ +import java.io.OutputStream; +import java.io.IOException; + +class A { + { + try { + OutputStream out = null; + + newMethod(out); + } catch(Throwable t) { + } + } + + private void newMethod(OutputStream out) throws IOException { + try { + } finally { + out.close(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment.java new file mode 100644 index 00000000000..6f6504888b7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment.java @@ -0,0 +1,13 @@ +class A{ + public static Object test(Object a) { + boolean value; + + if (a == null){ + value = true; + } + else{ + } + + return Boolean.valueOf(value); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment_after.java new file mode 100644 index 00000000000..bd5ba223522 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/OneBranchAssignment_after.java @@ -0,0 +1,19 @@ +class A{ + public static Object test(Object a) { + boolean value; + + if (a == null){ + value = newMethod(); + } + else{ + } + + return Boolean.valueOf(value); + } + + private static boolean newMethod() { + boolean value; + value = true; + return value; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245.java new file mode 100644 index 00000000000..36f799bb5c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245.java @@ -0,0 +1,11 @@ +public class A { + private void foo() { + Runnable a = new Runnable() { + private int a; + + public void run() { + a = 2; + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245_after.java new file mode 100644 index 00000000000..e7291744cb3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR12245_after.java @@ -0,0 +1,15 @@ +public class A { + private void foo() { + Runnable a = new Runnable() { + private int a; + + public void run() { + newMethod(); + } + + private void newMethod() { + a = 2; + } + }; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815.java new file mode 100644 index 00000000000..0473440cf1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815.java @@ -0,0 +1,11 @@ +public class Foo { + static Foo + f1 = new Foo(){ + public String toString() { + return "a" + "b"; + } + }, + f2 = new Foo(){} + ; + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815_after.java new file mode 100644 index 00000000000..f3cb01b50d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR15815_after.java @@ -0,0 +1,16 @@ +public class Foo { + static Foo + f1 = new Foo(){ + public String toString() { + return newMethod(); + } + }; + + private static String newMethod() { + return "a" + "b"; + } + + static Foo f2 = new Foo(){} + ; + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887.java new file mode 100644 index 00000000000..b4a7b33b021 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887.java @@ -0,0 +1,41 @@ +package extractMethod; + +import java.io.*; +import java.util.Iterator; + +public class SCR27887 { + public int publishx(OutputStream out, boolean includeCode) throws IOException { + if (VERBOSE) System.err.println("PUBLISH: publishing subsystem '" + subsystem.refQualifiedIdentifyingName() + "' with" + (includeCode ? "" : "out") + " code"); + ZippingXMLGeneratorFactory genFac = new ZippingXMLGeneratorFactory(out); +//======== + RefObjectUList included = makeIncludedSet(); + if (!included.isEmpty()) { + ScatteringDocBuilder docBuilder = new MyDocBuilder(repository, included); + new RepositorySaver(repository).saveTo(genFac, docBuilder); + } +//======== + if (includeCode) { + for (Iterator i = subsystem.getModule().iterator(); i.hasNext();) { + OptimalModule module = (OptimalModule) i.next(); + if (module.getPublished()) { + FileObject[] files = getModuleProducts(module); + if (files != null && files.length > 0) { + for (int j = 0; j < files.length; j++) { + FileObject file = files[j]; + OutputStream os = genFac.getOutputStream(file.getFileName()); + InputStream is = file.getInputStream(); + try { + copyStream(is, os); + } finally { + os.close(); + is.close(); + } + } + } + } + } + } + genFac.close(); + return included.size(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887_after.java new file mode 100644 index 00000000000..b2e5e334853 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR27887_after.java @@ -0,0 +1,46 @@ +package extractMethod; + +import java.io.*; +import java.util.Iterator; + +public class SCR27887 { + public int publishx(OutputStream out, boolean includeCode) throws IOException { + if (VERBOSE) System.err.println("PUBLISH: publishing subsystem '" + subsystem.refQualifiedIdentifyingName() + "' with" + (includeCode ? "" : "out") + " code"); + ZippingXMLGeneratorFactory genFac = new ZippingXMLGeneratorFactory(out); +//======== + RefObjectUList included = newMethod(genFac); +//======== + if (includeCode) { + for (Iterator i = subsystem.getModule().iterator(); i.hasNext();) { + OptimalModule module = (OptimalModule) i.next(); + if (module.getPublished()) { + FileObject[] files = getModuleProducts(module); + if (files != null && files.length > 0) { + for (int j = 0; j < files.length; j++) { + FileObject file = files[j]; + OutputStream os = genFac.getOutputStream(file.getFileName()); + InputStream is = file.getInputStream(); + try { + copyStream(is, os); + } finally { + os.close(); + is.close(); + } + } + } + } + } + } + genFac.close(); + return included.size(); + } + + private RefObjectUList newMethod(ZippingXMLGeneratorFactory genFac) { + RefObjectUList included = makeIncludedSet(); + if (!included.isEmpty()) { + ScatteringDocBuilder docBuilder = new MyDocBuilder(repository, included); + new RepositorySaver(repository).saveTo(genFac, docBuilder); + } + return included; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427.java new file mode 100644 index 00000000000..5f91e0ca6a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427.java @@ -0,0 +1,5 @@ +class TestCase { + boolean a = true; + boolean b = false; + boolean x = a && b; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427_after.java new file mode 100644 index 00000000000..aabffdfb488 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR28427_after.java @@ -0,0 +1,9 @@ +class TestCase { + boolean a = true; + boolean b = false; + boolean x = newMethod(); + + private boolean newMethod() { + return a && b; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924.java new file mode 100644 index 00000000000..1500589a148 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924.java @@ -0,0 +1,6 @@ +public class Test { + void m() { + Object x = null; + System.out.println("x = " + x); // [...] = selection + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924_after.java new file mode 100644 index 00000000000..edb9a94916c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/SCR32924_after.java @@ -0,0 +1,10 @@ +public class Test { + void m() { + Object x = null; + System.out.println("x = " + newMethod(x)); // [...] = selection + } + + private Object newMethod(Object x) { + return x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464.java new file mode 100644 index 00000000000..4e1d36314cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464.java @@ -0,0 +1,9 @@ +class Test { + public Object method() { + bar(); + return null; + } + + public void bar() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464_after.java new file mode 100644 index 00000000000..1cf0b588c23 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr10464_after.java @@ -0,0 +1,13 @@ +class Test { + public Object method() { + newMethod(); + return null; + } + + private void newMethod() { + bar(); + } + + public void bar() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241.java new file mode 100644 index 00000000000..e7c8a2ed2d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241.java @@ -0,0 +1,7 @@ +import java.util.*; + +class Test extends GregorianCalendar { + public boolean isSaturday() { + return get( Calendar.DAY_OF_WEEK ) == SATURDAY; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241_after.java new file mode 100644 index 00000000000..6dc9793981d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr6241_after.java @@ -0,0 +1,11 @@ +import java.util.*; + +class Test extends GregorianCalendar { + public boolean isSaturday() { + return newMethod() == SATURDAY; + } + + private int newMethod() { + return get( Calendar.DAY_OF_WEEK ); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091.java new file mode 100644 index 00000000000..b625d62521b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091.java @@ -0,0 +1,29 @@ +public class IdeaTestBug { + public static final int MAP_HEIGHT = 1000; + + Object[][] _map; + + public int checkAndRemoveConditions() { + int conditionsFound = 0; + for (int y = 0; y < MAP_HEIGHT; y++) { + while (isCheckCondition(y)) { + ++conditionsFound; + + final Object[] temp = _map[y]; + for (int x = 0; x < temp.length; x++) { + temp[x] = null; + } + for (int yy = y + 1; yy < MAP_HEIGHT; ++yy) { + _map[yy - 1] = _map[yy]; + } + _map[MAP_HEIGHT - 1] = temp; + } + } + return conditionsFound; + } + + private boolean isCheckCondition(int y) { + return false; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091_after.java new file mode 100644 index 00000000000..da55234fb0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr7091_after.java @@ -0,0 +1,33 @@ +public class IdeaTestBug { + public static final int MAP_HEIGHT = 1000; + + Object[][] _map; + + public int checkAndRemoveConditions() { + int conditionsFound = 0; + for (int y = 0; y < MAP_HEIGHT; y++) { + while (isCheckCondition(y)) { + ++conditionsFound; + + newMethod(y); + } + } + return conditionsFound; + } + + private void newMethod(int y) { + final Object[] temp = _map[y]; + for (int x = 0; x < temp.length; x++) { + temp[x] = null; + } + for (int yy = y + 1; yy < MAP_HEIGHT; ++yy) { + _map[yy - 1] = _map[yy]; + } + _map[MAP_HEIGHT - 1] = temp; + } + + private boolean isCheckCondition(int y) { + return false; + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852.java new file mode 100644 index 00000000000..2ea69e41295 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852.java @@ -0,0 +1,9 @@ +class Test { + int f() { + try { + int k = 0; + return k; + } finally { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852_after.java new file mode 100644 index 00000000000..5d301c54b02 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/Scr9852_after.java @@ -0,0 +1,13 @@ +class Test { + int f() { + try { + return newMethod(); + } finally { + } + } + + private int newMethod() { + int k = 0; + return k; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally.java new file mode 100644 index 00000000000..0a633e474c1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally.java @@ -0,0 +1,13 @@ +class TryFinally { + int method() { + String s = "abcd"; + + StringBuffer buffer = new StringBuffer(); + try { + buffer.append(s); + return buffer.length(); + } finally { + buffer.clear(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor.java new file mode 100644 index 00000000000..d6e93052e45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor.java @@ -0,0 +1,17 @@ +package extractMethod; + +import java.io.*; +import java.util.Iterator; + +public class SCR27887 { + public int publishx(OutputStream out, boolean includeCode) throws IOException { + ScatteringDocBuilder docBuilder = new MyDocBuilder(repository, included); + while(true){ + OutputStream os = null; + try { + } finally { + os.close(); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor_after.java new file mode 100644 index 00000000000..1b5cd973b32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinallyInsideFor_after.java @@ -0,0 +1,21 @@ +package extractMethod; + +import java.io.*; +import java.util.Iterator; + +public class SCR27887 { + public int publishx(OutputStream out, boolean includeCode) throws IOException { + newMethod(); + while(true){ + OutputStream os = null; + try { + } finally { + os.close(); + } + } + } + + private void newMethod() { + ScatteringDocBuilder docBuilder = new MyDocBuilder(repository, included); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally_after.java new file mode 100644 index 00000000000..b4b7112c389 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/TryFinally_after.java @@ -0,0 +1,17 @@ +class TryFinally { + int method() { + String s = "abcd"; + + return newMethod(s); + } + + private int newMethod(String s) { + StringBuffer buffer = new StringBuffer(); + try { + buffer.append(s); + return buffer.length(); + } finally { + buffer.clear(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar.java new file mode 100644 index 00000000000..d5a5d63b89a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar.java @@ -0,0 +1,14 @@ +class Foo { + private void bar() { + String text = null; + try { + text = getString(); + } + catch(Exception e) { + System.out.println(text); + } + } + private void getString() { + return "hello"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar_after.java new file mode 100644 index 00000000000..f6954c8db6f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UnusedInitializedVar_after.java @@ -0,0 +1,21 @@ +class Foo { + private void bar() { + String text = null; + try { + text = newMethod(); + } + catch(Exception e) { + System.out.println(text); + } + } + + private String newMethod() { + String text; + text = getString(); + return text; + } + + private void getString() { + return "hello"; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry.java new file mode 100644 index 00000000000..0699236cd72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry.java @@ -0,0 +1,13 @@ +class A { + { + Object o; + + try { + o = foo(); + } + catch (Exception e) { + } + + o.f(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry_after.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry_after.java new file mode 100644 index 00000000000..05b3b89e3b9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/extractMethod/UseVarAfterTry_after.java @@ -0,0 +1,19 @@ +class A { + { + Object o; + + try { + o = newMethod(); + } + catch (Exception e) { + } + + o.f(); + } + + private Object newMethod() { + Object o; + o = foo(); + return o; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/A.java new file mode 100644 index 00000000000..0b1132dd50b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/A.java @@ -0,0 +1,11 @@ +public abstract class A { + public final MyBase myDelegate = new MyBase(); + + protected abstract void run(); + + private class MyBase extends Base { + public void run() { + A.this.run(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/Base.java new file mode 100644 index 00000000000..f237a7f667b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/after/Base.java @@ -0,0 +1,2 @@ +public abstract class Base implements Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/A.java new file mode 100644 index 00000000000..24195727e43 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/A.java @@ -0,0 +1,2 @@ +public abstract class A extends Base { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/Base.java new file mode 100644 index 00000000000..f237a7f667b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase/before/Base.java @@ -0,0 +1,2 @@ +public abstract class Base implements Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/A.java new file mode 100644 index 00000000000..4b81db722af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/A.java @@ -0,0 +1,9 @@ +public class A { + private final MyBase myDelegate = new MyBase(); + + private class MyBase extends Base { + public void run() { + System.out.println("From A"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/Base.java new file mode 100644 index 00000000000..f237a7f667b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/after/Base.java @@ -0,0 +1,2 @@ +public abstract class Base implements Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/A.java new file mode 100644 index 00000000000..976cbf52853 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/A.java @@ -0,0 +1,5 @@ +public class A extends Base { + public void run() { + System.out.println("From A"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/Base.java new file mode 100644 index 00000000000..f237a7f667b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/abstractBase1/before/Base.java @@ -0,0 +1,2 @@ +public abstract class Base implements Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/A.java new file mode 100644 index 00000000000..e913171fe87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/A.java @@ -0,0 +1,7 @@ +class A { + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/B.java new file mode 100644 index 00000000000..d6c49854d26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/after/B.java @@ -0,0 +1,15 @@ +class B { + private final A myDelegate = new A(); + + public A getMyDelegate() { + return myDelegate; + } + + public void methodFromA() { + myDelegate.methodFromA(); + } + + public int intMethodFromA(int i) { + return myDelegate.intMethodFromA(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/A.java new file mode 100644 index 00000000000..e913171fe87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/A.java @@ -0,0 +1,7 @@ +class A { + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/B.java new file mode 100644 index 00000000000..776583fa48f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/getter/before/B.java @@ -0,0 +1,2 @@ +class B extends A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/A.java new file mode 100644 index 00000000000..e15113ea476 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/A.java @@ -0,0 +1,4 @@ +public class A { + void methodFromA() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Base.java new file mode 100644 index 00000000000..24b0a3d452c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Base.java @@ -0,0 +1,2 @@ +public class Base extends A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Test.java new file mode 100644 index 00000000000..403790e30fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/Test.java @@ -0,0 +1,3 @@ +public interface Test { + A getA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/X.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/X.java new file mode 100644 index 00000000000..2e2966015be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/after/X.java @@ -0,0 +1,10 @@ +public class X { + A myField; + private final Base myDelegate = new Base(); + + public void method(Test t) { + myField = t.getA(); + myField.methodFromA(); + t.getA().methodFromA(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/A.java new file mode 100644 index 00000000000..e15113ea476 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/A.java @@ -0,0 +1,4 @@ +public class A { + void methodFromA() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Base.java new file mode 100644 index 00000000000..24b0a3d452c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Base.java @@ -0,0 +1,2 @@ +public class Base extends A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Test.java new file mode 100644 index 00000000000..403790e30fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/Test.java @@ -0,0 +1,3 @@ +public interface Test { + A getA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/X.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/X.java new file mode 100644 index 00000000000..112110b42b2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/hierarchy/before/X.java @@ -0,0 +1,8 @@ +public class X extends Base { + A myField; + public void method(Test t) { + myField = t.getA(); + myField.methodFromA(); + t.getA().methodFromA(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/A.java new file mode 100644 index 00000000000..1e063b9a3e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/A.java @@ -0,0 +1,17 @@ +public class A { + public final MyBase myDelegate; + + public A() { + myDelegate = new MyBase(27); + } + + private class MyBase extends Base { + public MyBase(int i) { + super(i); + } + + public void methodToOverride() { + System.out.println("Hello from B"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/Base.java new file mode 100644 index 00000000000..20e97de4639 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/after/Base.java @@ -0,0 +1,11 @@ +public class Base { + protected int baseField; + public Base() { + } + public Base(int i) { + baseField = i; + } + public void methodToOverride() { + System.out.println("Hello from Base"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/A.java new file mode 100644 index 00000000000..705e8fac668 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/A.java @@ -0,0 +1,8 @@ +public class A extends Base { + public A() { + super(27); + } + public void methodToOverride() { + System.out.println("Hello from B"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/Base.java new file mode 100644 index 00000000000..20e97de4639 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClass/before/Base.java @@ -0,0 +1,11 @@ +public class Base { + protected int baseField; + public Base() { + } + public Base(int i) { + baseField = i; + } + public void methodToOverride() { + System.out.println("Hello from Base"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/A.java new file mode 100644 index 00000000000..db951a5c2a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/A.java @@ -0,0 +1,20 @@ +public class A extends BaseClass { + private final MyBaseInterface myBaseInterface = new MyBaseInterface(); + + public A() { + } + + public A(String s) { + super(27); + } + + public void baseInterfaceMethod() { + myBaseInterface.baseInterfaceMethod(); + } + + private class MyBaseInterface implements BaseInterface { + public void baseInterfaceMethod() { + System.out.println("Hi!"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseClass.java new file mode 100644 index 00000000000..f06f893268f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseClass.java @@ -0,0 +1,7 @@ +public BaseClass { + public BaseClass() { + } + + public BaseClass(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseInterface.java new file mode 100644 index 00000000000..72f2c9848d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/after/BaseInterface.java @@ -0,0 +1,3 @@ +public interface BaseInterface { + void baseInterfaceMethod(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/A.java new file mode 100644 index 00000000000..8d0bd26babe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/A.java @@ -0,0 +1,12 @@ +public class A extends BaseClass implements BaseInterface { + public A() { + } + + public A(String s) { + super(27); + } + + public void baseInterfaceMethod() { + System.out.println("Hi!"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseClass.java new file mode 100644 index 00000000000..f06f893268f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseClass.java @@ -0,0 +1,7 @@ +public BaseClass { + public BaseClass() { + } + + public BaseClass(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseInterface.java new file mode 100644 index 00000000000..72f2c9848d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterface/before/BaseInterface.java @@ -0,0 +1,3 @@ +public interface BaseInterface { + void baseInterfaceMethod(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/A.java new file mode 100644 index 00000000000..236c2e8251f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/A.java @@ -0,0 +1,18 @@ +public abstract class A extends BaseClass { + private final MyBaseInterface myBaseInterface = new MyBaseInterface(); + + public A() { + } + + public A(String s) { + super(27); + } + + public abstract void baseInterfaceMethod(); + + private class MyBaseInterface implements BaseInterface { + public void baseInterfaceMethod() { + A.this.baseInterfaceMethod(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseClass.java new file mode 100644 index 00000000000..f06f893268f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseClass.java @@ -0,0 +1,7 @@ +public BaseClass { + public BaseClass() { + } + + public BaseClass(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseInterface.java new file mode 100644 index 00000000000..72f2c9848d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/after/BaseInterface.java @@ -0,0 +1,3 @@ +public interface BaseInterface { + void baseInterfaceMethod(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/A.java new file mode 100644 index 00000000000..8c64cc67ac0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/A.java @@ -0,0 +1,8 @@ +public abstract class A extends BaseClass implements BaseInterface { + public A() { + } + + public A(String s) { + super(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseClass.java new file mode 100644 index 00000000000..f06f893268f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseClass.java @@ -0,0 +1,7 @@ +public BaseClass { + public BaseClass() { + } + + public BaseClass(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseInterface.java new file mode 100644 index 00000000000..72f2c9848d2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/innerClassForInterfaceAbstract/before/BaseInterface.java @@ -0,0 +1,3 @@ +public interface BaseInterface { + void baseInterfaceMethod(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/A.java new file mode 100644 index 00000000000..a972e85e8ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/A.java @@ -0,0 +1,21 @@ +public class A { + private final MyIntf myDelegate = new MyIntf(); + + public Intf getMyDelegate() { + return myDelegate; + } + + public void method1() { + myDelegate.method1(); + } + + private class MyIntf implements Intf { + public void method1 () { + System.out.println("1"); + } + + public void method2 () { + System.out.println("2"); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Intf.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Intf.java new file mode 100644 index 00000000000..6e8322fbb82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Intf.java @@ -0,0 +1,4 @@ +public interface Intf { + void method1(); + void method2(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Usage.java new file mode 100644 index 00000000000..1cabfd90361 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/after/Usage.java @@ -0,0 +1,12 @@ +public class Usage { + A a = new A(); + + public void usage() { + a.method1(); + a.getMyDelegate().method2(); + use(a.getMyDelegate()); + } + + private void use(Intf i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/A.java new file mode 100644 index 00000000000..4c7a0c9f65d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/A.java @@ -0,0 +1,9 @@ +public class A implements Intf { + public void method1 () { + System.out.println("1"); + } + + public void method2 () { + System.out.println("2"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Intf.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Intf.java new file mode 100644 index 00000000000..6e8322fbb82 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Intf.java @@ -0,0 +1,4 @@ +public interface Intf { + void method1(); + void method2(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Usage.java new file mode 100644 index 00000000000..f367f27c453 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaceDelegation/before/Usage.java @@ -0,0 +1,12 @@ +public class Usage { + A a = new A(); + + public void usage() { + a.method1(); + a.method2(); + use(a); + } + + private void use(Intf i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/A.java new file mode 100644 index 00000000000..da60cb932f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/A.java @@ -0,0 +1,11 @@ +public class A implements I { + private final Base myDelegate = new Base(); + + public Base getMyDelegate() { + return myDelegate; + } + + public void methodFromI() { + myDelegate.methodFromI(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Base.java new file mode 100644 index 00000000000..6a5e0848aaf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Base.java @@ -0,0 +1,7 @@ +public class Base implements I, J { + public void methodFromI() { + } + + public void methodFromJ() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/I.java new file mode 100644 index 00000000000..006dc52f35f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/I.java @@ -0,0 +1,3 @@ +public interface I { + void methodFromI(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/J.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/J.java new file mode 100644 index 00000000000..efd19d66144 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/J.java @@ -0,0 +1,3 @@ +public interface J { + void methodFromJ(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Usage.java new file mode 100644 index 00000000000..019f386a24d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/after/Usage.java @@ -0,0 +1,23 @@ +class Usage { + private A myA = new A(); + public void methodExpectingI(I i) { + i.methodFromI(); + } + + public J methodReturningJ() { + return myA.getMyDelegate(); + } + + public void methodExpectingJ(J j) { + j.methodFromJ(); + } + + public void main() { + A a = new A(); + a.methodFromI(); + a.getMyDelegate().methodFromJ(); + methodExpectingI(a); + methodExpectingJ(a.getMyDelegate()); + methodExpectingJ(myA.getMyDelegate()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/A.java new file mode 100644 index 00000000000..e31cfab248e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/A.java @@ -0,0 +1,2 @@ +public class A extends Base { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Base.java new file mode 100644 index 00000000000..6a5e0848aaf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Base.java @@ -0,0 +1,7 @@ +public class Base implements I, J { + public void methodFromI() { + } + + public void methodFromJ() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/I.java new file mode 100644 index 00000000000..006dc52f35f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/I.java @@ -0,0 +1,3 @@ +public interface I { + void methodFromI(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/J.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/J.java new file mode 100644 index 00000000000..efd19d66144 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/J.java @@ -0,0 +1,3 @@ +public interface J { + void methodFromJ(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Usage.java new file mode 100644 index 00000000000..c536b34b72a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/interfaces/before/Usage.java @@ -0,0 +1,23 @@ +class Usage { + private A myA = new A(); + public void methodExpectingI(I i) { + i.methodFromI(); + } + + public J methodReturningJ() { + return myA; + } + + public void methodExpectingJ(J j) { + j.methodFromJ(); + } + + public void main() { + A a = new A(); + a.methodFromI(); + a.methodFromJ(); + methodExpectingI(a); + methodExpectingJ(a); + methodExpectingJ(myA); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/A.java new file mode 100644 index 00000000000..f9de8b45ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/A.java @@ -0,0 +1,23 @@ +class A { + int fieldFromA; + private final MyBase myDelegate = new MyBase(); + + public void firstMethodFromBase() { + myDelegate.firstMethodFromBase(); + } + + private class MyBase extends Base { + public void firstMethodFromBase() { + super.firstMethodFromBase(); + } + + public void secondMethodFromBase() { + fieldFromA = 27; + A.this.fieldFromA++; + } + + Base getInstance() { + return this; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/Base.java new file mode 100644 index 00000000000..45d37c5b1f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/after/Base.java @@ -0,0 +1,12 @@ +public class Base implements Runnable { + void firstMethodFromBase() { + } + void secondMethodFromBase() { + } + Base getInstance() { + return null; + } + public void run() { + // do nothing + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/A.java new file mode 100644 index 00000000000..9198acf293f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/A.java @@ -0,0 +1,13 @@ +class A extends Base { + int fieldFromA; + public void firstMethodFromBase() { + super.firstMethodFromBase(); + } + public void secondMethodFromBase() { + fieldFromA = 27; + this.fieldFromA++; + } + Base getInstance() { + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/Base.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/Base.java new file mode 100644 index 00000000000..45d37c5b1f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/overridenMethods/before/Base.java @@ -0,0 +1,12 @@ +public class Base implements Runnable { + void firstMethodFromBase() { + } + void secondMethodFromBase() { + } + Base getInstance() { + return null; + } + public void run() { + // do nothing + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java new file mode 100644 index 00000000000..99dc5c6339c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/after/xxx/SCR20557.java @@ -0,0 +1,531 @@ +package xxx; + +import java.sql.*; +import java.util.Calendar; +import java.util.Map; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; + +/** + * @author dsl + */ +public class SCR20557 { + private final MyResultSet myResultSet = new MyResultSet(); + + public Date getDate(int columnIndex) throws SQLException { + return myResultSet.getDate(columnIndex); + } + + public Date getDate(String columnName) throws SQLException { + return myResultSet.getDate(columnName); + } + + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + return myResultSet.getDate(columnIndex, cal); + } + + public Date getDate(String columnName, Calendar cal) throws SQLException { + return myResultSet.getDate(columnName, cal); + } + + private class MyResultSet implements ResultSet { + public void updateLong(int columnIndex, long x) throws SQLException { + } + + public void updateLong(String columnName, long x) throws SQLException { + } + + public boolean getBoolean(int columnIndex) throws SQLException { + return false; + } + + public boolean getBoolean(String columnName) throws SQLException { + return false; + } + + public boolean wasNull() throws SQLException { + return false; + } + + public int getRow() throws SQLException { + return 0; + } + + public int getConcurrency() throws SQLException { + return 0; + } + + public int getFetchSize() throws SQLException { + return 0; + } + + public Ref getRef(int i) throws SQLException { + return null; + } + + public Ref getRef(String colName) throws SQLException { + return null; + } + + public Date getDate(int columnIndex) throws SQLException { + return null; + } + + public Date getDate(String columnName) throws SQLException { + return null; + } + + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Date getDate(String columnName, Calendar cal) throws SQLException { + return null; + } + + public Statement getStatement() throws SQLException { + return null; + } + + public boolean isFirst() throws SQLException { + return false; + } + + public boolean previous() throws SQLException { + return false; + } + + public void updateFloat(int columnIndex, float x) throws SQLException { + } + + public void updateFloat(String columnName, float x) throws SQLException { + } + + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + } + + public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException { + } + + public void updateRow() throws SQLException { + } + + public long getLong(int columnIndex) throws SQLException { + return 0; + } + + public long getLong(String columnName) throws SQLException { + return 0; + } + + public void updateRef(int columnIndex, Ref x) throws SQLException { + } + + public void updateRef(String columnName, Ref x) throws SQLException { + } + + public void updateByte(int columnIndex, byte x) throws SQLException { + } + + public void updateByte(String columnName, byte x) throws SQLException { + } + + public void cancelRowUpdates() throws SQLException { + } + + public Reader getCharacterStream(int columnIndex) throws SQLException { + return null; + } + + public Reader getCharacterStream(String columnName) throws SQLException { + return null; + } + + public boolean absolute(int row) throws SQLException { + return false; + } + + public boolean first() throws SQLException { + return false; + } + + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + } + + public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException { + } + + public void moveToInsertRow() throws SQLException { + } + + public SQLWarning getWarnings() throws SQLException { + return null; + } + + public void updateDate(int columnIndex, Date x) throws SQLException { + } + + public void updateDate(String columnName, Date x) throws SQLException { + } + + public InputStream getBinaryStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getBinaryStream(String columnName) throws SQLException { + return null; + } + + public Time getTime(int columnIndex) throws SQLException { + return null; + } + + public Time getTime(String columnName) throws SQLException { + return null; + } + + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Time getTime(String columnName, Calendar cal) throws SQLException { + return null; + } + + public String getCursorName() throws SQLException { + return null; + } + + public void updateBytes(int columnIndex, byte x[]) throws SQLException { + } + + public void updateBytes(String columnName, byte x[]) throws SQLException { + } + + public boolean last() throws SQLException { + return false; + } + + public Timestamp getTimestamp(int columnIndex) throws SQLException { + return null; + } + + public Timestamp getTimestamp(String columnName) throws SQLException { + return null; + } + + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { + return null; + } + + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + } + + public void updateBoolean(String columnName, boolean x) throws SQLException { + } + + public void beforeFirst() throws SQLException { + } + + public int getFetchDirection() throws SQLException { + return 0; + } + + public void updateDouble(int columnIndex, double x) throws SQLException { + } + + public void updateDouble(String columnName, double x) throws SQLException { + } + + public void setFetchDirection(int direction) throws SQLException { + } + + public boolean rowDeleted() throws SQLException { + return false; + } + + public void moveToCurrentRow() throws SQLException { + } + + public void insertRow() throws SQLException { + } + + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(String columnName) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { + return null; + } + + public URL getURL(int columnIndex) throws SQLException { + return null; + } + + public URL getURL(String columnName) throws SQLException { + return null; + } + + public boolean isAfterLast() throws SQLException { + return false; + } + + public short getShort(int columnIndex) throws SQLException { + return 0; + } + + public short getShort(String columnName) throws SQLException { + return 0; + } + + public void updateInt(int columnIndex, int x) throws SQLException { + } + + public void updateInt(String columnName, int x) throws SQLException { + } + + public void clearWarnings() throws SQLException { + } + + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + } + + public void updateCharacterStream(String columnName, Reader reader, int length) throws SQLException { + } + + public Blob getBlob(int i) throws SQLException { + return null; + } + + public Blob getBlob(String colName) throws SQLException { + return null; + } + + public void refreshRow() throws SQLException { + } + + public void updateTime(int columnIndex, Time x) throws SQLException { + } + + public void updateTime(String columnName, Time x) throws SQLException { + } + + public void updateArray(int columnIndex, Array x) throws SQLException { + } + + public void updateArray(String columnName, Array x) throws SQLException { + } + + public void updateObject(int columnIndex, Object x) throws SQLException { + } + + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { + } + + public void updateObject(String columnName, Object x) throws SQLException { + } + + public void updateObject(String columnName, Object x, int scale) throws SQLException { + } + + public void updateNull(int columnIndex) throws SQLException { + } + + public void updateNull(String columnName) throws SQLException { + } + + public void close() throws SQLException { + } + + public boolean rowInserted() throws SQLException { + return false; + } + + public Clob getClob(int i) throws SQLException { + return null; + } + + public Clob getClob(String colName) throws SQLException { + return null; + } + + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + } + + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + } + + public int getType() throws SQLException { + return 0; + } + + public boolean next() throws SQLException { + return false; + } + + public int getInt(int columnIndex) throws SQLException { + return 0; + } + + public int getInt(String columnName) throws SQLException { + return 0; + } + + public void updateBlob(int columnIndex, Blob x) throws SQLException { + } + + public void updateBlob(String columnName, Blob x) throws SQLException { + } + + public ResultSetMetaData getMetaData() throws SQLException { + return null; + } + + public boolean rowUpdated() throws SQLException { + return false; + } + + public Array getArray(int i) throws SQLException { + return null; + } + + public Array getArray(String colName) throws SQLException { + return null; + } + + public byte getByte(int columnIndex) throws SQLException { + return 0; + } + + public byte getByte(String columnName) throws SQLException { + return 0; + } + + public InputStream getAsciiStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getAsciiStream(String columnName) throws SQLException { + return null; + } + + public double getDouble(int columnIndex) throws SQLException { + return 0; + } + + public double getDouble(String columnName) throws SQLException { + return 0; + } + + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + } + + public void updateTimestamp(String columnName, Timestamp x) throws SQLException { + } + + public void updateClob(int columnIndex, Clob x) throws SQLException { + } + + public void updateClob(String columnName, Clob x) throws SQLException { + } + + public boolean isBeforeFirst() throws SQLException { + return false; + } + + public void deleteRow() throws SQLException { + } + + public void afterLast() throws SQLException { + } + + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getUnicodeStream(String columnName) throws SQLException { + return null; + } + + public byte[] getBytes(int columnIndex) throws SQLException { + return new byte[0]; + } + + public byte[] getBytes(String columnName) throws SQLException { + return new byte[0]; + } + + public void updateString(int columnIndex, String x) throws SQLException { + } + + public void updateString(String columnName, String x) throws SQLException { + } + + public float getFloat(int columnIndex) throws SQLException { + return 0; + } + + public float getFloat(String columnName) throws SQLException { + return 0; + } + + public Object getObject(int columnIndex) throws SQLException { + return null; + } + + public Object getObject(String columnName) throws SQLException { + return null; + } + + public Object getObject(int i, Map map) throws SQLException { + return null; + } + + public Object getObject(String colName, Map map) throws SQLException { + return null; + } + + public void setFetchSize(int rows) throws SQLException { + } + + public boolean isLast() throws SQLException { + return false; + } + + public void updateShort(int columnIndex, short x) throws SQLException { + } + + public void updateShort(String columnName, short x) throws SQLException { + } + + public String getString(int columnIndex) throws SQLException { + return null; + } + + public String getString(String columnName) throws SQLException { + return null; + } + + public int findColumn(String columnName) throws SQLException { + return 0; + } + + public boolean relative(int rows) throws SQLException { + return false; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/before/xxx/SCR20557.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/before/xxx/SCR20557.java new file mode 100644 index 00000000000..52732927df7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/scr20557/before/xxx/SCR20557.java @@ -0,0 +1,511 @@ +package xxx; + +import java.sql.*; +import java.util.Calendar; +import java.util.Map; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; + +/** + * @author dsl + */ +public class SCR20557 implements ResultSet { + public void updateLong(int columnIndex, long x) throws SQLException { + } + + public void updateLong(String columnName, long x) throws SQLException { + } + + public boolean getBoolean(int columnIndex) throws SQLException { + return false; + } + + public boolean getBoolean(String columnName) throws SQLException { + return false; + } + + public boolean wasNull() throws SQLException { + return false; + } + + public int getRow() throws SQLException { + return 0; + } + + public int getConcurrency() throws SQLException { + return 0; + } + + public int getFetchSize() throws SQLException { + return 0; + } + + public Ref getRef(int i) throws SQLException { + return null; + } + + public Ref getRef(String colName) throws SQLException { + return null; + } + + public Date getDate(int columnIndex) throws SQLException { + return null; + } + + public Date getDate(String columnName) throws SQLException { + return null; + } + + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Date getDate(String columnName, Calendar cal) throws SQLException { + return null; + } + + public Statement getStatement() throws SQLException { + return null; + } + + public boolean isFirst() throws SQLException { + return false; + } + + public boolean previous() throws SQLException { + return false; + } + + public void updateFloat(int columnIndex, float x) throws SQLException { + } + + public void updateFloat(String columnName, float x) throws SQLException { + } + + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + } + + public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException { + } + + public void updateRow() throws SQLException { + } + + public long getLong(int columnIndex) throws SQLException { + return 0; + } + + public long getLong(String columnName) throws SQLException { + return 0; + } + + public void updateRef(int columnIndex, Ref x) throws SQLException { + } + + public void updateRef(String columnName, Ref x) throws SQLException { + } + + public void updateByte(int columnIndex, byte x) throws SQLException { + } + + public void updateByte(String columnName, byte x) throws SQLException { + } + + public void cancelRowUpdates() throws SQLException { + } + + public Reader getCharacterStream(int columnIndex) throws SQLException { + return null; + } + + public Reader getCharacterStream(String columnName) throws SQLException { + return null; + } + + public boolean absolute(int row) throws SQLException { + return false; + } + + public boolean first() throws SQLException { + return false; + } + + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + } + + public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException { + } + + public void moveToInsertRow() throws SQLException { + } + + public SQLWarning getWarnings() throws SQLException { + return null; + } + + public void updateDate(int columnIndex, Date x) throws SQLException { + } + + public void updateDate(String columnName, Date x) throws SQLException { + } + + public InputStream getBinaryStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getBinaryStream(String columnName) throws SQLException { + return null; + } + + public Time getTime(int columnIndex) throws SQLException { + return null; + } + + public Time getTime(String columnName) throws SQLException { + return null; + } + + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Time getTime(String columnName, Calendar cal) throws SQLException { + return null; + } + + public String getCursorName() throws SQLException { + return null; + } + + public void updateBytes(int columnIndex, byte x[]) throws SQLException { + } + + public void updateBytes(String columnName, byte x[]) throws SQLException { + } + + public boolean last() throws SQLException { + return false; + } + + public Timestamp getTimestamp(int columnIndex) throws SQLException { + return null; + } + + public Timestamp getTimestamp(String columnName) throws SQLException { + return null; + } + + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + return null; + } + + public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { + return null; + } + + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + } + + public void updateBoolean(String columnName, boolean x) throws SQLException { + } + + public void beforeFirst() throws SQLException { + } + + public int getFetchDirection() throws SQLException { + return 0; + } + + public void updateDouble(int columnIndex, double x) throws SQLException { + } + + public void updateDouble(String columnName, double x) throws SQLException { + } + + public void setFetchDirection(int direction) throws SQLException { + } + + public boolean rowDeleted() throws SQLException { + return false; + } + + public void moveToCurrentRow() throws SQLException { + } + + public void insertRow() throws SQLException { + } + + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(String columnName) throws SQLException { + return null; + } + + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { + return null; + } + + public URL getURL(int columnIndex) throws SQLException { + return null; + } + + public URL getURL(String columnName) throws SQLException { + return null; + } + + public boolean isAfterLast() throws SQLException { + return false; + } + + public short getShort(int columnIndex) throws SQLException { + return 0; + } + + public short getShort(String columnName) throws SQLException { + return 0; + } + + public void updateInt(int columnIndex, int x) throws SQLException { + } + + public void updateInt(String columnName, int x) throws SQLException { + } + + public void clearWarnings() throws SQLException { + } + + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + } + + public void updateCharacterStream(String columnName, Reader reader, int length) throws SQLException { + } + + public Blob getBlob(int i) throws SQLException { + return null; + } + + public Blob getBlob(String colName) throws SQLException { + return null; + } + + public void refreshRow() throws SQLException { + } + + public void updateTime(int columnIndex, Time x) throws SQLException { + } + + public void updateTime(String columnName, Time x) throws SQLException { + } + + public void updateArray(int columnIndex, Array x) throws SQLException { + } + + public void updateArray(String columnName, Array x) throws SQLException { + } + + public void updateObject(int columnIndex, Object x) throws SQLException { + } + + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { + } + + public void updateObject(String columnName, Object x) throws SQLException { + } + + public void updateObject(String columnName, Object x, int scale) throws SQLException { + } + + public void updateNull(int columnIndex) throws SQLException { + } + + public void updateNull(String columnName) throws SQLException { + } + + public void close() throws SQLException { + } + + public boolean rowInserted() throws SQLException { + return false; + } + + public Clob getClob(int i) throws SQLException { + return null; + } + + public Clob getClob(String colName) throws SQLException { + return null; + } + + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + } + + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + } + + public int getType() throws SQLException { + return 0; + } + + public boolean next() throws SQLException { + return false; + } + + public int getInt(int columnIndex) throws SQLException { + return 0; + } + + public int getInt(String columnName) throws SQLException { + return 0; + } + + public void updateBlob(int columnIndex, Blob x) throws SQLException { + } + + public void updateBlob(String columnName, Blob x) throws SQLException { + } + + public ResultSetMetaData getMetaData() throws SQLException { + return null; + } + + public boolean rowUpdated() throws SQLException { + return false; + } + + public Array getArray(int i) throws SQLException { + return null; + } + + public Array getArray(String colName) throws SQLException { + return null; + } + + public byte getByte(int columnIndex) throws SQLException { + return 0; + } + + public byte getByte(String columnName) throws SQLException { + return 0; + } + + public InputStream getAsciiStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getAsciiStream(String columnName) throws SQLException { + return null; + } + + public double getDouble(int columnIndex) throws SQLException { + return 0; + } + + public double getDouble(String columnName) throws SQLException { + return 0; + } + + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + } + + public void updateTimestamp(String columnName, Timestamp x) throws SQLException { + } + + public void updateClob(int columnIndex, Clob x) throws SQLException { + } + + public void updateClob(String columnName, Clob x) throws SQLException { + } + + public boolean isBeforeFirst() throws SQLException { + return false; + } + + public void deleteRow() throws SQLException { + } + + public void afterLast() throws SQLException { + } + + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + return null; + } + + public InputStream getUnicodeStream(String columnName) throws SQLException { + return null; + } + + public byte[] getBytes(int columnIndex) throws SQLException { + return new byte[0]; + } + + public byte[] getBytes(String columnName) throws SQLException { + return new byte[0]; + } + + public void updateString(int columnIndex, String x) throws SQLException { + } + + public void updateString(String columnName, String x) throws SQLException { + } + + public float getFloat(int columnIndex) throws SQLException { + return 0; + } + + public float getFloat(String columnName) throws SQLException { + return 0; + } + + public Object getObject(int columnIndex) throws SQLException { + return null; + } + + public Object getObject(String columnName) throws SQLException { + return null; + } + + public Object getObject(int i, Map map) throws SQLException { + return null; + } + + public Object getObject(String colName, Map map) throws SQLException { + return null; + } + + public void setFetchSize(int rows) throws SQLException { + } + + public boolean isLast() throws SQLException { + return false; + } + + public void updateShort(int columnIndex, short x) throws SQLException { + } + + public void updateShort(String columnName, short x) throws SQLException { + } + + public String getString(int columnIndex) throws SQLException { + return null; + } + + public String getString(String columnName) throws SQLException { + return null; + } + + public int findColumn(String columnName) throws SQLException { + return 0; + } + + public boolean relative(int rows) throws SQLException { + return false; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/A.java new file mode 100644 index 00000000000..e913171fe87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/A.java @@ -0,0 +1,7 @@ +class A { + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/B.java new file mode 100644 index 00000000000..0b27acd76a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/after/B.java @@ -0,0 +1,11 @@ +class B { + public final A myDelegate = new A(); + + public void methodFromA() { + myDelegate.methodFromA(); + } + + public int intMethodFromA(int i) { + return myDelegate.intMethodFromA(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/A.java new file mode 100644 index 00000000000..e913171fe87 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/A.java @@ -0,0 +1,7 @@ +class A { + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/B.java new file mode 100644 index 00000000000..776583fa48f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/simpleInsertion/before/B.java @@ -0,0 +1,2 @@ +class B extends A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/A.java new file mode 100644 index 00000000000..1892816fc55 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/A.java @@ -0,0 +1,20 @@ +public class A { + private final DelegatedBase myDelegate = new DelegatedBase(); + + int methodFromA() { + delegatedBaseMethod(); + return myDelegate.delegatedBaseField; + } + + DelegatedBase getSomething() { + return myDelegate; + } + + public DelegatedBase getMyDelegate() { + return myDelegate; + } + + void delegatedBaseMethod() { + myDelegate.delegatedBaseMethod(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/B.java new file mode 100644 index 00000000000..9c40fcc08f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/B.java @@ -0,0 +1,5 @@ +public class B extends A { + void methodFromB() { + super.delegatedBaseMethod(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/DelegatedBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/DelegatedBase.java new file mode 100644 index 00000000000..8f1274ea944 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/DelegatedBase.java @@ -0,0 +1,7 @@ +public class DelegatedBase { + int delegatedBaseField; + + void delegatedBaseMethod() { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/Usage.java new file mode 100644 index 00000000000..ad278a5bc85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/after/Usage.java @@ -0,0 +1,20 @@ +public class Usage { + public void parameterUsageMethod(DelegatedBase b) { + b.delegatedBaseMethod(); + } + + public int testMethod() { + A a = new A(); + B b = new B(); + parameterUsageMethod(a.getMyDelegate()); + parameterUsageMethod(b.getMyDelegate()); + a.delegatedBaseMethod(); + b.delegatedBaseMethod(); + a.equals(b); + return a.getMyDelegate().delegatedBaseField + b.getMyDelegate().delegatedBaseField; + } + + DelegatedBase getDelegatedBase(A a) { + return a.getMyDelegate(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/A.java new file mode 100644 index 00000000000..d6e5ef4c1b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/A.java @@ -0,0 +1,10 @@ +public class A extends DelegatedBase{ + int methodFromA() { + delegatedBaseMethod(); + return delegatedBaseField; + } + + DelegatedBase getSomething() { + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/B.java new file mode 100644 index 00000000000..9c40fcc08f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/B.java @@ -0,0 +1,5 @@ +public class B extends A { + void methodFromB() { + super.delegatedBaseMethod(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/DelegatedBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/DelegatedBase.java new file mode 100644 index 00000000000..8f1274ea944 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/DelegatedBase.java @@ -0,0 +1,7 @@ +public class DelegatedBase { + int delegatedBaseField; + + void delegatedBaseMethod() { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/Usage.java new file mode 100644 index 00000000000..72e1eaebcf2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClass/before/Usage.java @@ -0,0 +1,20 @@ +public class Usage { + public void parameterUsageMethod(DelegatedBase b) { + b.delegatedBaseMethod(); + } + + public int testMethod() { + A a = new A(); + B b = new B(); + parameterUsageMethod(a); + parameterUsageMethod(b); + a.delegatedBaseMethod(); + b.delegatedBaseMethod(); + a.equals(b); + return a.delegatedBaseField + b.delegatedBaseField; + } + + DelegatedBase getDelegatedBase(A a) { + return a; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/A.java new file mode 100644 index 00000000000..18ee3bdfe3b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/A.java @@ -0,0 +1,16 @@ +public class A { + protected final DelegatedBase myDelegate = new DelegatedBase(); + + int methodFromA() { + myDelegate.delegatedBaseMethod(); + return myDelegate.delegatedBaseField; + } + + DelegatedBase getSomething() { + return myDelegate; + } + + public DelegatedBase getMyDelegate() { + return myDelegate; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/B.java new file mode 100644 index 00000000000..b752a62e91c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/B.java @@ -0,0 +1,5 @@ +public class B extends A { + void methodFromB() { + myDelegate.delegatedBaseMethod(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/DelegatedBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/DelegatedBase.java new file mode 100644 index 00000000000..8f1274ea944 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/DelegatedBase.java @@ -0,0 +1,7 @@ +public class DelegatedBase { + int delegatedBaseField; + + void delegatedBaseMethod() { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/Usage.java new file mode 100644 index 00000000000..59c5e9140fd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/after/Usage.java @@ -0,0 +1,20 @@ +public class Usage { + public void parameterUsageMethod(DelegatedBase b) { + b.delegatedBaseMethod(); + } + + public int testMethod() { + A a = new A(); + B b = new B(); + parameterUsageMethod(a.getMyDelegate()); + parameterUsageMethod(b.getMyDelegate()); + a.getMyDelegate().delegatedBaseMethod(); + b.getMyDelegate().delegatedBaseMethod(); + a.equals(b); + return a.getMyDelegate().delegatedBaseField + b.getMyDelegate().delegatedBaseField; + } + + DelegatedBase getDelegatedBase(A a) { + return a.getMyDelegate(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/A.java new file mode 100644 index 00000000000..d6e5ef4c1b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/A.java @@ -0,0 +1,10 @@ +public class A extends DelegatedBase{ + int methodFromA() { + delegatedBaseMethod(); + return delegatedBaseField; + } + + DelegatedBase getSomething() { + return this; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/B.java new file mode 100644 index 00000000000..9c40fcc08f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/B.java @@ -0,0 +1,5 @@ +public class B extends A { + void methodFromB() { + super.delegatedBaseMethod(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/DelegatedBase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/DelegatedBase.java new file mode 100644 index 00000000000..8f1274ea944 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/DelegatedBase.java @@ -0,0 +1,7 @@ +public class DelegatedBase { + int delegatedBaseField; + + void delegatedBaseMethod() { + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/Usage.java new file mode 100644 index 00000000000..72e1eaebcf2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subClassNoMethods/before/Usage.java @@ -0,0 +1,20 @@ +public class Usage { + public void parameterUsageMethod(DelegatedBase b) { + b.delegatedBaseMethod(); + } + + public int testMethod() { + A a = new A(); + B b = new B(); + parameterUsageMethod(a); + parameterUsageMethod(b); + a.delegatedBaseMethod(); + b.delegatedBaseMethod(); + a.equals(b); + return a.delegatedBaseField + b.delegatedBaseField; + } + + DelegatedBase getDelegatedBase(A a) { + return a; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/A.java new file mode 100644 index 00000000000..5fa4f8deb55 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/A.java @@ -0,0 +1,12 @@ +public class A extends B { + private final MyJ myDelegate = new MyJ(); + + public J getMyDelegate() { + return myDelegate; + } + + private class MyJ implements J { + public void run() { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/B.java new file mode 100644 index 00000000000..253834b48f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/B.java @@ -0,0 +1,2 @@ +class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/J.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/J.java new file mode 100644 index 00000000000..e10fdb13290 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/J.java @@ -0,0 +1,2 @@ +interface J extends Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/Usage.java new file mode 100644 index 00000000000..0dcb69335d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/after/Usage.java @@ -0,0 +1,6 @@ +class Usage { + public static void main() { + A a = new A(); + a.getMyDelegate().run(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/A.java new file mode 100644 index 00000000000..b497edc17a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/A.java @@ -0,0 +1,4 @@ +public class A extends B implements J { + public void run() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/B.java new file mode 100644 index 00000000000..253834b48f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/B.java @@ -0,0 +1,2 @@ +class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/J.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/J.java new file mode 100644 index 00000000000..e10fdb13290 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/J.java @@ -0,0 +1,2 @@ +interface J extends Runnable { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/Usage.java new file mode 100644 index 00000000000..604ea3be719 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/subinterface/before/Usage.java @@ -0,0 +1,6 @@ +class Usage { + public static void main() { + A a = new A(); + a.run(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/A.java new file mode 100644 index 00000000000..2dce668d31d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/A.java @@ -0,0 +1,9 @@ +class A { + public A(int i) { + } + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/B.java new file mode 100644 index 00000000000..3a8fa1f6ce7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/after/B.java @@ -0,0 +1,11 @@ +class B { + public final A myDelegate; + + public B() { + myDelegate = new A(1); + } + + public B(int i) { + myDelegate = new A(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/A.java new file mode 100644 index 00000000000..2dce668d31d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/A.java @@ -0,0 +1,9 @@ +class A { + public A(int i) { + } + public void methodFromA() { + } + public int intMethodFromA(int i) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/B.java new file mode 100644 index 00000000000..3458c3e9c4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inheritanceToDelegation/superCalls/before/B.java @@ -0,0 +1,9 @@ +class B extends A { + public B() { + super(1); + } + + public B(int i) { + super(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Inference.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Inference.java new file mode 100644 index 00000000000..b56ce4fe35b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Inference.java @@ -0,0 +1,12 @@ +class Inference { + public T getX() { + return null; + } + + void foo (String s) {} + + { + String v2 = new Inference().getX(); + foo(v2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Qualifier.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Qualifier.java new file mode 100644 index 00000000000..77cf624d2c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineLocal/Qualifier.java @@ -0,0 +1,12 @@ +class Outer { + String getValue() { return "";} + void doSomething (String x) { } + void foo() { + new Runnable() { + public void run() { + final String value = getValue(); + doSomething(value); + } + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ArrayAccess.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ArrayAccess.java new file mode 100644 index 00000000000..443a7fa60e8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ArrayAccess.java @@ -0,0 +1,11 @@ +class A { + public void usage() { + int array[150]; + for (int i = 0; i < array.length; i++) { + method(array[i]); + } + } + public void method(int i) { + System.out.println(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallInFor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallInFor.java new file mode 100644 index 00000000000..f659ed40925 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallInFor.java @@ -0,0 +1,19 @@ +public class C { + public void doSomething() { + for (Iterator it = getSomeObjects().iterator(); it.hasNext();) { + String text = (String)it.next(); + System.out.println("text = " + text); + } + } + + private Collection getSomeObjects() { + final String text = "hello"; + return getSomeObjects(text); + } + + private Collection getSomeObjects(String text) { + final List list = new ArrayList(); + list.add(text); + return list; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallUnderIf.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallUnderIf.java new file mode 100644 index 00000000000..0db3e15a85d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/CallUnderIf.java @@ -0,0 +1,14 @@ +public class Foo { + String getComponent(Integer i) { return null; } + Integer myI; + + public void usage() { + if (myI != null) + method(myI); + } + + void method(Integer i) { + System.out.println(getComponent(myI) + getComponent(i)); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ChainingConstructor.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ChainingConstructor.java new file mode 100644 index 00000000000..58b16bc567e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ChainingConstructor.java @@ -0,0 +1,22 @@ +class InlineMethodTest { + public static InlineMethodTest createInstance() { + return new InlineMethodTest(0); + } + + protected InlineMethodTest(int y) { + this("hello world", y); + } + + protected InlineMethodTest() { + this(0); + } + + public InlineMethodTest(String text, int i) { + } +} + +class Derived extends InlineMethodTest { + public Derived(int i) { + super(i); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ConflictingField.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ConflictingField.java new file mode 100644 index 00000000000..b59fbb18ac3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/ConflictingField.java @@ -0,0 +1,11 @@ +class Test { + public int i; + + public int getI() { + return i; + } + + public void usage() { + int i = getI(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FieldInitializer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FieldInitializer.java new file mode 100644 index 00000000000..6f26859d3d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FieldInitializer.java @@ -0,0 +1,7 @@ +class A{ + int field = foo(); + + int foo(){ + return 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters.java new file mode 100644 index 00000000000..99d11ecc9ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters.java @@ -0,0 +1,10 @@ +class Test { + void method(Object x) { + String s = null; + s = (String) x; + toInline(s.length()); + } + void toInline(final int i) { + System.out.println(i); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters1.java new file mode 100644 index 00000000000..7800b742a93 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/FinalParameters1.java @@ -0,0 +1,15 @@ +class Test { + void method(Object x) { + String s = null; + s = (String) x; + toInline(s.length()); + } + void toInline(final int i) { + Runnable r = new Runnable() { + public void run() { + System.out.println(i); + } + }; + System.out.println(i); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineParms.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineParms.java new file mode 100644 index 00000000000..a46df7d0daf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineParms.java @@ -0,0 +1,30 @@ +public class Test { + public int foo(int p1, int p2) { + p2++; + return someMethod(p1, p2); + } + + public void use1() { + int r = foo(x, y); + } + + public void use2() { + int r = foo(field1, field1); + } + + public void use3() { + int r = foo(field2, field2); + } + + public void use4() { + int r = foo(field3, field3); + } + + { + field2++; + } + + private final int field1; + private int field2; + private int field3; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifier.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifier.java new file mode 100644 index 00000000000..db992dc9584 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifier.java @@ -0,0 +1,33 @@ +class Element { + String id; + + String getName() { + return getID(); + } + String getID() { + return id; + } + + public String method(Element element) { + return getName() + element.getName(); + } + + public String staticMethod(Element element) { + StringBuffer buffer = new StringBuffer(); + buffer.append(element.getName()); + return buffer.toString(); + } + static Element toXML(Element element){ + X el= new X("El") + el.setAttribute("attr", element.getName()); + return el; + } +} + +class Usage { + public String staticMethod(Element element) { + StringBuffer buffer = new StringBuffer(); + buffer.append(element.getName()); + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifierFromSuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifierFromSuper.java new file mode 100644 index 00000000000..aee2cd07e4e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithQualifierFromSuper.java @@ -0,0 +1,17 @@ +class Base { + String id; + public String getID() { + return id; + } +} + +class Derived extends Base { + String getName() { + return getID(); + } + + static void usage(Derived element) { + StringBuffer buffer = new StringBuffer(); + buffer.add(element.getName()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithTry.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithTry.java new file mode 100644 index 00000000000..7e750033dec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/InlineWithTry.java @@ -0,0 +1,12 @@ +class A { + { + g(); + } + int g() { + try { + return 0; + } catch (Error e) { + throw e; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/LocalVariableResult.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/LocalVariableResult.java new file mode 100644 index 00000000000..ce1b06e3b96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/LocalVariableResult.java @@ -0,0 +1,17 @@ +class A { + + Integer f(int i) { + return g(i); + } + + Integer g(int i) { + if (i > 0) { + return new Integer(i); + } + else { + Integer result; + result = new Integer(0); + return result; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/NameClash.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/NameClash.java new file mode 100644 index 00000000000..7cf58b26e1a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/NameClash.java @@ -0,0 +1,12 @@ +public class Foo +{ + public static void main( String[] args ) + { + Object value = null; + log( "float", new Float( 5.5f ) ); + } + + private static void log(String title, Object value) { + System.out.println( title + ":" + value ); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR20655.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR20655.java new file mode 100644 index 00000000000..7a7d7b79cf9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR20655.java @@ -0,0 +1,11 @@ +class Super { + public void message() { + System.out.println(this); + } +} + +class Sub extends Super { + public void message() { + super.message(); // <-- Inline this method call. + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR22644.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR22644.java new file mode 100644 index 00000000000..52dadb9d9d0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR22644.java @@ -0,0 +1,17 @@ +public class SuperClass { + public void doSomething() { + UtilClass.doSomething(this); + } +} + +public class SubClass extends SuperClass { + public void doSomethingElse() { + doSomething(); + } +} + +public class UtilClass { + public static void doSomething(SuperClass superClass) { + // ... + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR31093.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR31093.java new file mode 100644 index 00000000000..8061a2d4950 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR31093.java @@ -0,0 +1,10 @@ +class A { + private void f() {} +} + +class B { + private A b; + public void g() { + b.f(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR37742.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR37742.java new file mode 100644 index 00000000000..7c14ed8a9ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SCR37742.java @@ -0,0 +1,12 @@ +import java.util.List; +import java.util.ArrayList; + +class Test { + void foo(T t) { + List l = new ArrayList(); + } + + void bar () { + foo(new String()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr10884.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr10884.java new file mode 100644 index 00000000000..3c593cf76a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr10884.java @@ -0,0 +1,16 @@ +public class Scr10884 { + int foo() { + return 1; + } + Y bar() { + return new Y(foo()) { + }; + } +} + +class Y { + Y(int x) {} + int foo() { + return 2; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr13831.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr13831.java new file mode 100644 index 00000000000..6491710ebf8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Scr13831.java @@ -0,0 +1,12 @@ +public class Foo +{ + public static void main( String[] args ) + { + log( "integer", new Integer( 5 ) ); + log( "float", new Float( 5.5f ) ); + } + + private static void log(String title, Object value) { + System.out.println( title + ":" + value ); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SideEffect.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SideEffect.java new file mode 100644 index 00000000000..0ac33e58edc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/SideEffect.java @@ -0,0 +1,11 @@ +class Test { + private String s; + String method() { + s = "Hello"; + return s; + } + void test() { + System.out.println(method()); + System.out.println(s); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/StaticFieldInitializer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/StaticFieldInitializer.java new file mode 100644 index 00000000000..400541c189e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/StaticFieldInitializer.java @@ -0,0 +1,8 @@ +class A{ + static int field = foo(); + + static int foo(){ + doSomething(); + return 1; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Try.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Try.java new file mode 100644 index 00000000000..27409a95652 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/Try.java @@ -0,0 +1,14 @@ +public class Try { + public int test() { + return another(); + } + + public int another() { + try { + return Integer.parseInt("1"); + } + catch (NumberFormatException ex) { + throw ex; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/TrySynchronized.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/TrySynchronized.java new file mode 100644 index 00000000000..6f080226ce8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/TrySynchronized.java @@ -0,0 +1,14 @@ +public class Try { + public int test() { + return another(); + } + + public synchronized int another() { + try { + return Integer.parseInt("1"); + } + catch (NumberFormatException ex) { + throw ex; + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/VoidWithReturn.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/VoidWithReturn.java new file mode 100644 index 00000000000..54072d1c475 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/inlineMethod/VoidWithReturn.java @@ -0,0 +1,9 @@ +class Test { + void method() { + otherMethod(); + System.out.println("Here"); + } + void otherMethod() { + return; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/after1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/after1.java new file mode 100644 index 00000000000..033edeaac16 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/after1.java @@ -0,0 +1,8 @@ +class InStaticInitializer { + public static final String x = "Hello World"; + + static { + System.out.println(x); + } + //Field must be placed before initializer or illegal forward reference will happen +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/before1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/before1.java new file mode 100644 index 00000000000..97717e3d0ff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceField/before1.java @@ -0,0 +1,6 @@ +class InStaticInitializer { + static { + System.out.println("Hello World"); + } + //Field must be placed before initializer or illegal forward reference will happen +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after01.java new file mode 100644 index 00000000000..c4061d03a69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after01.java @@ -0,0 +1,5 @@ +class Test { + public int m(int a, int b, int anObject) { + return anObject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after02.java new file mode 100644 index 00000000000..1f99aa9a865 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after02.java @@ -0,0 +1,18 @@ +class Test { + public int m(int a, int b, int anObject) { + if(a > b) { + return anObject; + } + else { + return anObject; + } + } +} + +class Test1 { + Test t; + + public int n(int v) { + return t.m(v, 1, 0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after03.java new file mode 100644 index 00000000000..966092828f4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after03.java @@ -0,0 +1,12 @@ +class Test { + int m(int anObject) { + return anObject; + } +} + +class X3 { + int n() { + Test t; + return t.m(0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after04.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after04.java new file mode 100644 index 00000000000..52eb5b9ec0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after04.java @@ -0,0 +1,13 @@ +class Test { + int method(int a, int b, int anObject) { + return anObject; + } +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2, 1 + 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after05.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after05.java new file mode 100644 index 00000000000..b188dcc2dd7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after05.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b, Test anObject) { + return anObject.i; + } + private int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2, t); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after06.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after06.java new file mode 100644 index 00000000000..97c6e50bc09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after06.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b, int anObject) { + return anObject; + } + private int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2, t.i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after07.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after07.java new file mode 100644 index 00000000000..325e364621d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after07.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b, int anObject) { + return anObject; + } + int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2, t.i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after08.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after08.java new file mode 100644 index 00000000000..0f57f5919cf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after08.java @@ -0,0 +1,18 @@ +class Test { + int method(int a, int b, int anObject) { + return anObject; + } + int i; + + int anotherMethod(int x) { + return x; + } +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2, t.anotherMethod(1 + 2)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after09.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after09.java new file mode 100644 index 00000000000..62c25913644 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after09.java @@ -0,0 +1,16 @@ +class Test { + public static int i; + + int method(int a, int anObject) { + return anObject; + } +} + +class X { + public static int i; + + int yyy(int z) { + Test t; + return t.method(z, z+Test.i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after10.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after10.java new file mode 100644 index 00000000000..6bc974bd22c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after10.java @@ -0,0 +1,16 @@ +class Test { + int i; + + public int getI() { return i; } + + int method(int a, int anObject) { + return anObject; + } +} + +class XXX { + public int m() { + Test t; + return t.method(1, 1 + t.getI()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after11.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after11.java new file mode 100644 index 00000000000..ce9537b963a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after11.java @@ -0,0 +1,16 @@ +class Test { + public int i; + + public int getI() { return i; } + + int method(int a, int anObject) { + return anObject; + } +} + +class XXX { + public int m() { + Test t; + return t.method(1, 1 + t.i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after12.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after12.java new file mode 100644 index 00000000000..d6d2f5edad0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after12.java @@ -0,0 +1,16 @@ +public class Test { + int method(int i) { + return 0; + } + + int m(int i, int j, int anObject) { + return i + anObject; + } +} + +class X { + public int n(int a) { + final Test test = new Test(); + return test.m(a, a*2, test.method(a*2)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after13.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after13.java new file mode 100644 index 00000000000..965c5422070 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after13.java @@ -0,0 +1,18 @@ +class T1 { + int method(int i) { + return 0; + } +} + +class T2 extends T1 { + int method(int i, int anObject) { + return anObject; + } +} + +class Usage { + int m() { + T2 test; + return test.method(0, test.method(0) + 1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after14.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after14.java new file mode 100644 index 00000000000..b38d4982132 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after14.java @@ -0,0 +1,6 @@ +class Test { + public Test method(Test anObject) { + return anObject; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after15.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after15.java new file mode 100644 index 00000000000..ff97ffa236a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after15.java @@ -0,0 +1,16 @@ +public class Test { + int method(int i) { + return 0; + } + + int m(int i, int j, Test t, int anObject) { + return i + anObject; + } +} + +class X { + public int n(int a) { + final Test t = new Test(); + return (new Test()).m(a, a*2, t, t.method(a*2)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after16.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after16.java new file mode 100644 index 00000000000..bf0d6ef4e77 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after16.java @@ -0,0 +1,19 @@ +class A { + int i; + public A(int anObject) { + i = anObject; + } +} + +class B extends A { + int k; + + public B() { + super(27); + k = 10; + } +} + +class Usage { + A a = new B(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after17.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after17.java new file mode 100644 index 00000000000..4c1ff818a49 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after17.java @@ -0,0 +1,16 @@ +class A { + int i; + public A(int anObject) { + i = anObject; + } +} + +class B extends A { + B() { + super(27); + } +} + +class Usage { + A a = new B(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after18.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after18.java new file mode 100644 index 00000000000..2fdf39f3834 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after18.java @@ -0,0 +1,5 @@ +class Foo { + void f(int anObject) { + int k = anObject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after19.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after19.java new file mode 100644 index 00000000000..6fb79511ee7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after19.java @@ -0,0 +1,23 @@ +import java.util.*; + +public class Test { + int field; + int method(int anObject) { + return anObject; + } +} + +public class Usage { + int usage(Test[] tests) { + int sum = 0; + for(int i = 0; i < tests.length;) { + final Test test = tests[i++]; + sum += test.method(test.field); + } + List list = Arrays.asList(tests); + for(int i = 0; i < list.size();) { + final Test test = (Test) list.get(i++); + sum += test.method(test.field); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after20.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after20.java new file mode 100644 index 00000000000..f99acd5c136 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after20.java @@ -0,0 +1,10 @@ +class Test { + class A { + class B { + } + } + + Object method(A.B anObject) { + return anObject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after21.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after21.java new file mode 100644 index 00000000000..e8d67426279 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after21.java @@ -0,0 +1,10 @@ +public class Test { + public Test(int anObject) { + int i = anObject; + } + + public Test get() { + return new Test(0) { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after22.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after22.java new file mode 100644 index 00000000000..2aabb52f50a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after22.java @@ -0,0 +1,18 @@ +class T1 { + int method(int i) { + return 0; + } +} + +class T2 extends T1 { + int method(int i, int anObject) { + return anObject; + } +} + +class Usage { + int m() { + final T2 t2 = new T2(); + return t2.method(0, t2.method(0) + 1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after23.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after23.java new file mode 100644 index 00000000000..3aaa7648d67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after23.java @@ -0,0 +1,25 @@ +public class Test { + public int i; + public void method(int i) { + } +} + +public class Test1 extends Test { + public void method(int i) { + System.out.println(i); + System.out.println(this.i); + } +} + +public class Test2 extends Test1 { + public void method(int i) { + System.out.println(this.i); + } +} + +public class Usage { + { + Test t = new Test2(); + t.method(1 + 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after24.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after24.java new file mode 100644 index 00000000000..0554977bbbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after24.java @@ -0,0 +1,9 @@ +import java.util.*; + +class XX { + public void g(List l, Iterator it) { + for(; it.hasNext();) { + Object o = it.next(): + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after25.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after25.java new file mode 100644 index 00000000000..68485e00c85 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after25.java @@ -0,0 +1,8 @@ +class Test { + /** + * @param anObject + */ + int method(final int anObject) { + return anObject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after26.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after26.java new file mode 100644 index 00000000000..860dc5080eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after26.java @@ -0,0 +1,9 @@ +class Test { + /** + * @param s + * @param anObject + */ + int method(String s, final int anObject) { + return anObject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after27.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after27.java new file mode 100644 index 00000000000..4bffc29e183 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after27.java @@ -0,0 +1,8 @@ +class Test { + /** + * Incomplete JavaDoc + */ + int method(String s, final int anObject) { + return anObject; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after28.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after28.java new file mode 100644 index 00000000000..15660bc8f7f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after28.java @@ -0,0 +1,14 @@ +class C { + /** + * @param i + * @param s + */ + void method(final int i, String... s) { + System.out.println(s[i]); + } + + { + method(0, "a", "b", "c"); + method(0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after29.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after29.java new file mode 100644 index 00000000000..b2d5a2eaaa8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after29.java @@ -0,0 +1,17 @@ +public class InnerOuter { + String myField = ""; + + interface Inner { + void exec(final String myField); + } + + Inner instance = new Inner() { + public void exec(final String myField) { + myField.charAt(1); + } + }; + + void foo() { + instance.exec(myField); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after30.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after30.java new file mode 100644 index 00000000000..27621220536 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/after30.java @@ -0,0 +1,12 @@ +class Test { + void f (String s) {} + + void u(final String aString) { + f(aString); + } + + void y () { + String name = ""; + u(name); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before01.java new file mode 100644 index 00000000000..1ebe5c93f3f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before01.java @@ -0,0 +1,5 @@ +class Test { + public int m(int a, int b) { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before02.java new file mode 100644 index 00000000000..0a250d0a739 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before02.java @@ -0,0 +1,18 @@ +class Test { + public int m(int a, int b) { + if(a > b) { + return 0; + } + else { + return 0; + } + } +} + +class Test1 { + Test t; + + public int n(int v) { + return t.m(v, 1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before03.java new file mode 100644 index 00000000000..1f1df145e2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before03.java @@ -0,0 +1,12 @@ +class Test { + int m() { + return 0; + } +} + +class X3 { + int n() { + Test t; + return t.m(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before04.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before04.java new file mode 100644 index 00000000000..5f5455bf0c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before04.java @@ -0,0 +1,13 @@ +class Test { + int method(int a, int b) { + return a + b; + } +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before05.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before05.java new file mode 100644 index 00000000000..3fc8f46b53e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before05.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b) { + return this.i; + } + private int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before06.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before06.java new file mode 100644 index 00000000000..f4dc05b1daf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before06.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b) { + return this.i; + } + private int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before07.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before07.java new file mode 100644 index 00000000000..a2a96367052 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before07.java @@ -0,0 +1,14 @@ +class Test { + int method(int a, int b) { + return i; + } + int i; +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before08.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before08.java new file mode 100644 index 00000000000..26d0c800a59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before08.java @@ -0,0 +1,18 @@ +class Test { + int method(int a, int b) { + return anotherMethod(a + b); + } + int i; + + int anotherMethod(int x) { + return x; + } +} + +class XTest { + int n() { + Test t; + + return t.method(1, 2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before09.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before09.java new file mode 100644 index 00000000000..dfc5fccbb8f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before09.java @@ -0,0 +1,16 @@ +class Test { + public static int i; + + int method(int a) { + return a+i; + } +} + +class X { + public static int i; + + int yyy(int z) { + Test t; + return t.method(z); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before10.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before10.java new file mode 100644 index 00000000000..425c99d8821 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before10.java @@ -0,0 +1,16 @@ +class Test { + int i; + + public int getI() { return i; } + + int method(int a) { + return a + i; + } +} + +class XXX { + public int m() { + Test t; + return t.method(1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before11.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before11.java new file mode 100644 index 00000000000..24079f18988 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before11.java @@ -0,0 +1,16 @@ +class Test { + public int i; + + public int getI() { return i; } + + int method(int a) { + return a + i; + } +} + +class XXX { + public int m() { + Test t; + return t.method(1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before12.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before12.java new file mode 100644 index 00000000000..477945db1ca --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before12.java @@ -0,0 +1,15 @@ +public class Test { + int method(int i) { + return 0; + } + + int m(int i, int j) { + return i + method(j); + } +} + +class X { + public int n(int a) { + return (new Test()).m(a, a*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before13.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before13.java new file mode 100644 index 00000000000..58d16577a2c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before13.java @@ -0,0 +1,18 @@ +class T1 { + int method(int i) { + return 0; + } +} + +class T2 extends T1 { + int method(int i) { + return super.method(i) + 1; + } +} + +class Usage { + int m() { + T2 test; + return test.method(0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before14.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before14.java new file mode 100644 index 00000000000..7e0f200d926 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before14.java @@ -0,0 +1,6 @@ +class Test { + public Test method() { + return null; + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before15.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before15.java new file mode 100644 index 00000000000..eb192d151f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before15.java @@ -0,0 +1,15 @@ +public class Test { + int method(int i) { + return 0; + } + + int m(int i, int j, Test t) { + return i + t.method(j); + } +} + +class X { + public int n(int a) { + return (new Test()).m(a, a*2, new Test()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before16.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before16.java new file mode 100644 index 00000000000..c0d009bfc00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before16.java @@ -0,0 +1,18 @@ +class A { + int i; + public A() { + i = 27; + } +} + +class B extends A { + int k; + + public B() { + k = 10; + } +} + +class Usage { + A a = new B(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before17.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before17.java new file mode 100644 index 00000000000..90a06c09a52 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before17.java @@ -0,0 +1,13 @@ +class A { + int i; + public A() { + i = 27; + } +} + +class B extends A { +} + +class Usage { + A a = new B(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before18.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before18.java new file mode 100644 index 00000000000..a18a1043144 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before18.java @@ -0,0 +1,5 @@ +class Foo { + void f() { + int k = 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before19.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before19.java new file mode 100644 index 00000000000..7204448d32c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before19.java @@ -0,0 +1,21 @@ +import java.util.*; + +public class Test { + int field; + int method() { + return field; + } +} + +public class Usage { + int usage(Test[] tests) { + int sum = 0; + for(int i = 0; i < tests.length;) { + sum += tests[i++].method(); + } + List list = Arrays.asList(tests); + for(int i = 0; i < list.size();) { + sum += ((Test)list.get(i++)).method(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before20.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before20.java new file mode 100644 index 00000000000..0f70592dc8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before20.java @@ -0,0 +1,10 @@ +class Test { + class A { + class B { + } + } + + Object method() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before21.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before21.java new file mode 100644 index 00000000000..0772b12fed5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before21.java @@ -0,0 +1,10 @@ +public class Test { + public Test() { + int i = 0; + } + + public Test get() { + return new Test() { + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before22.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before22.java new file mode 100644 index 00000000000..5568c5f8245 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before22.java @@ -0,0 +1,17 @@ +class T1 { + int method(int i) { + return 0; + } +} + +class T2 extends T1 { + int method(int i) { + return super.method(i) + 1; + } +} + +class Usage { + int m() { + return new T2().method(0); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before23.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before23.java new file mode 100644 index 00000000000..673a35aa3a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before23.java @@ -0,0 +1,25 @@ +public class Test { + public int i; + public void method() { + } +} + +public class Test1 extends Test { + public void method() { + System.out.println(1 + 2); + System.out.println(i); + } +} + +public class Test2 extends Test1 { + public void method() { + System.out.println(i); + } +} + +public class Usage { + { + Test t = new Test2(); + t.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before24.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before24.java new file mode 100644 index 00000000000..066c64cbeaa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before24.java @@ -0,0 +1,9 @@ +import java.util.*; + +class XX { + public void g(List l) { + for(Iterator it = l.iterator(); it.hasNext();) { + Object o = it.next(): + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before25.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before25.java new file mode 100644 index 00000000000..87d84765dc5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before25.java @@ -0,0 +1,7 @@ +class Test { + /** + */ + int method() { + return 10; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before26.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before26.java new file mode 100644 index 00000000000..c5f7a4cda9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before26.java @@ -0,0 +1,8 @@ +class Test { + /** + * @param s + */ + int method(String s) { + return 10; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before27.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before27.java new file mode 100644 index 00000000000..22dfcd69f12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before27.java @@ -0,0 +1,8 @@ +class Test { + /** + * Incomplete JavaDoc + */ + int method(String s) { + return 10; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before28.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before28.java new file mode 100644 index 00000000000..ff576522f13 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before28.java @@ -0,0 +1,13 @@ +class C { + /** + * @param s + */ + void method(String... s) { + System.out.println(s[0]); + } + + { + method("a", "b", "c"); + method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before29.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before29.java new file mode 100644 index 00000000000..f4def593e0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before29.java @@ -0,0 +1,17 @@ +public class InnerOuter { + String myField = ""; + + interface Inner { + void exec(); + } + + Inner instance = new Inner() { + public void exec() { + myField.charAt(1); + } + }; + + void foo() { + instance.exec(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before30.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before30.java new file mode 100644 index 00000000000..d48fce07024 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/introduceParameter/before30.java @@ -0,0 +1,12 @@ +class Test { + void f (String s) {} + + void u () { + f(name); + } + + void y () { + String name = ""; + u(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after1.java new file mode 100644 index 00000000000..4c16989103a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after1.java @@ -0,0 +1,4 @@ +public class Foo { + public static void method(Foo anObject) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10-np.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10-np.java new file mode 100644 index 00000000000..4a197040b84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10-np.java @@ -0,0 +1,13 @@ +public class Foo { + public int myData; + static int method(int i) { + return myData + i; + } +} + +class Bar { + public Foo myFoo; + int a(int b) { + return Foo.method(b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10.java new file mode 100644 index 00000000000..e4e9a03f91b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after10.java @@ -0,0 +1,13 @@ +public class Foo { + public int myData; + static int method(Foo anObject, int i) { + return anObject.myData + i; + } +} + +class Bar { + public Foo myFoo; + int a(int b) { + return Foo.method(myFoo, b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after11.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after11.java new file mode 100644 index 00000000000..bba17791f20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after11.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + static int method(Foo anObject, int i) { + return anObject.myData + i; + } +} + +public class Bar extends Foo { + int method(int b) { + return super.method(this, b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after12.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after12.java new file mode 100644 index 00000000000..18e7a237cac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after12.java @@ -0,0 +1,6 @@ +class Foo extends java.util.Vector { + static int method(Foo anObject) { + return anObject.toString(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after13.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after13.java new file mode 100644 index 00000000000..dd1c65b442a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after13.java @@ -0,0 +1,5 @@ +class Foo { + static Foo bar(Foo anObject) { + return anObject; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after14.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after14.java new file mode 100644 index 00000000000..439ba36cd5b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after14.java @@ -0,0 +1,11 @@ +public class Test { + static Test method(final Test anObject) { + final Test[] result = new int[1]; + new Runnable() { + public void run() { + result[0] = anObject; + } + }.run(); + return result[0]; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after15.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after15.java new file mode 100644 index 00000000000..b9b3959b2dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after15.java @@ -0,0 +1,9 @@ +public class Foo { + Foo getAnotherFoo() {} + + static void tryMakeMeStatic(Foo anObject, boolean b) { + if (b) { + Foo.tryMakeMeStatic(anObject.getAnotherFoo(), !b); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after16.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after16.java new file mode 100644 index 00000000000..6513f14c973 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after16.java @@ -0,0 +1,11 @@ +public class Test { + void anotherMethod(String s); + String field; + /** + * @param anObject + * @param field1 + */ + static void method(Test anObject, String field1) { + anObject.anotherMethod(field1); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after17.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after17.java new file mode 100644 index 00000000000..93fe28e7dad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after17.java @@ -0,0 +1,10 @@ +public class Test { + String field; + + /** + * @param field1 + */ + static String method(String field1) { + return field1; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after18.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after18.java new file mode 100644 index 00000000000..27e59aea2f1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after18.java @@ -0,0 +1,5 @@ +class C { + static void method(C anObject) { + System.out.println(anObject); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after19.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after19.java new file mode 100644 index 00000000000..73ea1699247 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after19.java @@ -0,0 +1,7 @@ +class C { + int myField; + + static void method(C anObject, int i) { + anObject.myField = i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after2.java new file mode 100644 index 00000000000..42f2479a94c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after2.java @@ -0,0 +1,6 @@ +public class Foo { + static int i; + public static int method(Foo anObject) { + return i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after3.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after3.java new file mode 100644 index 00000000000..6497b0dc530 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after3.java @@ -0,0 +1,6 @@ +public class Foo { + int i; + public static int method(Foo anObject) { + return anObject.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after4.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after4.java new file mode 100644 index 00000000000..658455a6f69 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after4.java @@ -0,0 +1,6 @@ +public class Foo { + public int i; + public static int method(Foo anObject) { + return anObject.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after5.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after5.java new file mode 100644 index 00000000000..b24fd43023b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after5.java @@ -0,0 +1,6 @@ +public class Foo { + public int i; + public static int method(Foo anObject) { + return anObject.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after6.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after6.java new file mode 100644 index 00000000000..1d6dffabf67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after6.java @@ -0,0 +1,6 @@ +public class Foo extends Bar { + public int i; + public static int method(Foo anObject) { + return anObject.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after7.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after7.java new file mode 100644 index 00000000000..8d37037a179 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after7.java @@ -0,0 +1,10 @@ +public class Foo { + + public int f(int i) { + return 0; + } + + public static int method(Foo anObject, int i) { + return anObject.f(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after8.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after8.java new file mode 100644 index 00000000000..8dcfc43a7dc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after8.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + static int method(final Foo anObject, int i) { + new Runnable () { + void f() {}; + public void run() { + this.f(anObject.myData); + } + } + return anObject.myData + anObject.myData; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after9.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after9.java new file mode 100644 index 00000000000..e2fd2948ee6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/after9.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + static int method(Foo anObject, int i) { + return anObject.myData + i; + } +} + +public class Bar extends Foo { + int a(int b) { + return method(this, b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before1.java new file mode 100644 index 00000000000..8d957154dbb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before1.java @@ -0,0 +1,4 @@ +public class Foo { + public void method() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before10.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before10.java new file mode 100644 index 00000000000..78279c69891 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before10.java @@ -0,0 +1,13 @@ +public class Foo { + public int myData; + int method(int i) { + return myData + i; + } +} + +class Bar { + public Foo myFoo; + int a(int b) { + return myFoo.method(b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before11.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before11.java new file mode 100644 index 00000000000..a0d077d681c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before11.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + int method(int i) { + return myData + i; + } +} + +public class Bar extends Foo { + int method(int b) { + return super.method(b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before12.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before12.java new file mode 100644 index 00000000000..daaa57dc325 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before12.java @@ -0,0 +1,6 @@ +class Foo extends java.util.Vector { + int method() { + return super.toString(); + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before13.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before13.java new file mode 100644 index 00000000000..9d253c91e59 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before13.java @@ -0,0 +1,5 @@ +class Foo { + Foo bar() { + return this; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before14.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before14.java new file mode 100644 index 00000000000..47a673323f3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before14.java @@ -0,0 +1,11 @@ +public class Test { + Test method() { + final Test[] result = new int[1]; + new Runnable() { + public void run() { + result[0] = Test.this; + } + }.run(); + return result[0]; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before15.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before15.java new file mode 100644 index 00000000000..0002778f3fc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before15.java @@ -0,0 +1,9 @@ +public class Foo { + Foo getAnotherFoo() {} + + void tryMakeMeStatic(boolean b) { + if (b) { + getAnotherFoo().tryMakeMeStatic(!b); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before16.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before16.java new file mode 100644 index 00000000000..569694ae49c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before16.java @@ -0,0 +1,9 @@ +public class Test { + void anotherMethod(String s); + String field; + /** + */ + void method() { + anotherMethod(field); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before17.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before17.java new file mode 100644 index 00000000000..ca5e0aa980e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before17.java @@ -0,0 +1,9 @@ +public class Test { + String field; + + /** + */ + String method() { + return field; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before18.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before18.java new file mode 100644 index 00000000000..bde40fd875b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before18.java @@ -0,0 +1,5 @@ +class C { + void method() { + System.out.println(this); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before19.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before19.java new file mode 100644 index 00000000000..e110e1aab60 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before19.java @@ -0,0 +1,7 @@ +class C { + int myField; + + void method(int i) { + myField = i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before2.java new file mode 100644 index 00000000000..2432f2d0382 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before2.java @@ -0,0 +1,6 @@ +public class Foo { + static int i; + public int method() { + return i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before3.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before3.java new file mode 100644 index 00000000000..421a8e5155d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before3.java @@ -0,0 +1,6 @@ +public class Foo { + int i; + public int method() { + return i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before4.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before4.java new file mode 100644 index 00000000000..68153f1aa7c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before4.java @@ -0,0 +1,6 @@ +public class Foo { + public int i; + public int method() { + return this.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before5.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before5.java new file mode 100644 index 00000000000..1a7ed458c2f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before5.java @@ -0,0 +1,6 @@ +public class Foo { + public int i; + public int method() { + return super.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before6.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before6.java new file mode 100644 index 00000000000..240fa316ad0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before6.java @@ -0,0 +1,6 @@ +public class Foo extends Bar { + public int i; + public int method() { + return super.i; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before7.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before7.java new file mode 100644 index 00000000000..333c0cac4a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before7.java @@ -0,0 +1,10 @@ +public class Foo { + + public int f(int i) { + return 0; + } + + public int method(int i) { + return f(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before8.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before8.java new file mode 100644 index 00000000000..aa9bf4754a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before8.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + int method(int i) { + new Runnable () { + void f() {}; + public void run() { + this.f(myData); + } + } + return this.myData + myData; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before9.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before9.java new file mode 100644 index 00000000000..6d4a1e51830 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/makeMethodStatic/before9.java @@ -0,0 +1,12 @@ +public class Foo { + public int myData; + int method(int i) { + return myData + i; + } +} + +public class Bar extends Foo { + int a(int b) { + return method(b*2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C.java new file mode 100644 index 00000000000..7f6f25b86b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import java.lang.AAA; + +class C { + AAA a = new AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C1.java new file mode 100644 index 00000000000..45dfd1298db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/after/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import java.lang.*; + +class C { + java.lang.AAA a = new java.lang.AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C.java new file mode 100644 index 00000000000..93161dc3234 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.AAA; + +class C { + AAA a = new AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C1.java new file mode 100644 index 00000000000..447164b3119 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/package/before/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.*; + +class C { + qqq.AAA a = new qqq.AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C.java new file mode 100644 index 00000000000..e531d54e4cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import zzz.bbb.AAA; + +class C { + AAA a = new AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C1.java new file mode 100644 index 00000000000..bd90b587446 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/after/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import zzz.bbb.*; + +class C { + zzz.bbb.AAA a = new zzz.bbb.AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C.java new file mode 100644 index 00000000000..93161dc3234 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.AAA; + +class C { + AAA a = new AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C1.java new file mode 100644 index 00000000000..447164b3119 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/packageToNonExistentPackage/before/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.*; + +class C { + qqq.AAA a = new qqq.AAA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C.java new file mode 100644 index 00000000000..197b1039a12 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import zzz.bbb.QQQ; + +class C { + QQQ you = new QQQ(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C1.java new file mode 100644 index 00000000000..7ba43027180 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/after/p1/C1.java @@ -0,0 +1,8 @@ +package p1; + +import qqq.aaa.*; +import zzz.bbb.QQQ; + +class C1 { + QQQ you = new QQQ(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C.java new file mode 100644 index 00000000000..c8927efdc26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.aaa.Yahoo; + +class C { + Yahoo you = new Yahoo(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C1.java new file mode 100644 index 00000000000..55a71bd7b0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/toNonExistentClass/before/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.aaa.*; + +class C1 { + Yahoo you = new Yahoo(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C.java new file mode 100644 index 00000000000..3183a0febd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import java.lang.String; + +class C { + String you = new String(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C1.java new file mode 100644 index 00000000000..f9533bbf456 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/after/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.aaa.*; + +class C1 { + String you = new String(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C.java new file mode 100644 index 00000000000..c8927efdc26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.aaa.Yahoo; + +class C { + Yahoo you = new Yahoo(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C1.java new file mode 100644 index 00000000000..55a71bd7b0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/migration/unexistingClassInUnexistingPackage/before/p1/C1.java @@ -0,0 +1,7 @@ +package p1; + +import qqq.aaa.*; + +class C1 { + Yahoo you = new Yahoo(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack1/Class2.java new file mode 100644 index 00000000000..f9df1b306a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack1/Class2.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack2/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack2/Class1.java new file mode 100644 index 00000000000..51582a601d7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/after/pack2/Class1.java @@ -0,0 +1,7 @@ +package pack2; + +import pack1.Class2; + +public class Class1 { + Class2 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class1.java new file mode 100644 index 00000000000..52baf9146bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class1.java @@ -0,0 +1,5 @@ +package pack1; + +public class Class1 { + Class2 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class2.java new file mode 100644 index 00000000000..f9df1b306a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange1/before/pack1/Class2.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack1/Class2.java new file mode 100644 index 00000000000..f9df1b306a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack1/Class2.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack2/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack2/Class1.java new file mode 100644 index 00000000000..a35a0b3b0e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/after/pack2/Class1.java @@ -0,0 +1,9 @@ +package pack2; + +import pack1.Class2; + +public class Class1 { + void foo(){ + Class2.xxx(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class1.java new file mode 100644 index 00000000000..ce4014f276d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class1.java @@ -0,0 +1,7 @@ +package pack1; + +public class Class1 { + void foo(){ + Class2.xxx(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class2.java new file mode 100644 index 00000000000..f9df1b306a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/contextChange2/before/pack1/Class2.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/WEB-INF/TestTEI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/WEB-INF/TestTEI.java new file mode 100644 index 00000000000..17e0dfd1c9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/WEB-INF/TestTEI.java @@ -0,0 +1,13 @@ + +import javax.servlet.jsp.tagext.TagExtraInfo; +import javax.servlet.jsp.tagext.VariableInfo; +import javax.servlet.jsp.tagext.TagData; + +/** + * @author mike + */ +public class TestTEI extends TagExtraInfo { + public VariableInfo[] getVariableInfo(TagData tagData) { + return new VariableInfo[] { new VariableInfo("testVar", tagData.getAttributeString("class"), true, VariableInfo.AT_BEGIN) }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/pack2/TestClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/pack2/TestClass.java new file mode 100644 index 00000000000..61b88da37cd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/after/pack2/TestClass.java @@ -0,0 +1,4 @@ +package pack2; + +public class TestClass { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/WEB-INF/TestTEI.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/WEB-INF/TestTEI.java new file mode 100644 index 00000000000..17e0dfd1c9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/WEB-INF/TestTEI.java @@ -0,0 +1,13 @@ + +import javax.servlet.jsp.tagext.TagExtraInfo; +import javax.servlet.jsp.tagext.VariableInfo; +import javax.servlet.jsp.tagext.TagData; + +/** + * @author mike + */ +public class TestTEI extends TagExtraInfo { + public VariableInfo[] getVariableInfo(TagData tagData) { + return new VariableInfo[] { new VariableInfo("testVar", tagData.getAttributeString("class"), true, VariableInfo.AT_BEGIN) }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/pack1/TestClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/pack1/TestClass.java new file mode 100644 index 00000000000..b4a713ed1dd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/jsp/before/pack1/TestClass.java @@ -0,0 +1,4 @@ +package pack1; + +public class TestClass { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/after/pack2/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/after/pack2/A.java new file mode 100644 index 00000000000..360dfe386ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/after/pack2/A.java @@ -0,0 +1,9 @@ +package pack2; + +public class A { + public void method () { + class X { + } + X x = new X(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/before/pack1/A.java new file mode 100644 index 00000000000..af81f5cf533 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/localClass/before/pack1/A.java @@ -0,0 +1,9 @@ +package pack1; + +public class A { + public void method () { + class X { + } + X x = new X(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class1.java new file mode 100644 index 00000000000..02b02d6239e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class1.java @@ -0,0 +1,6 @@ +package pack2; + +public class Class1 { + Class2 a; + Class2 b; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class2.java new file mode 100644 index 00000000000..107efb81ee7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/after/pack2/Class2.java @@ -0,0 +1,4 @@ +package pack2; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class1.java new file mode 100644 index 00000000000..2346fc1bf9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class1.java @@ -0,0 +1,6 @@ +package pack1; + +public class Class1 { + Class2 a; + Class2 b; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class2.java new file mode 100644 index 00000000000..f9df1b306a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/moveMultiple1/before/pack1/Class2.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/after/pack2/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/after/pack2/Class1.java new file mode 100644 index 00000000000..9ad5269a89f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/after/pack2/Class1.java @@ -0,0 +1,4 @@ +package pack2; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/before/pack1/Class1.java new file mode 100644 index 00000000000..231fe0676ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/nonJava/before/pack1/Class1.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/Client.java new file mode 100644 index 00000000000..5e86faf2058 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/Client.java @@ -0,0 +1,6 @@ +public class Client { + String s = "pack2.Class1"; + // pack2.Class1 + // apack1.Class1 + // Class1 +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/pack2/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/pack2/Class1.java new file mode 100644 index 00000000000..9ad5269a89f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/after/pack2/Class1.java @@ -0,0 +1,4 @@ +package pack2; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/Client.java new file mode 100644 index 00000000000..85a72320414 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/Client.java @@ -0,0 +1,6 @@ +public class Client { + String s = "pack1.Class1"; + // pack1.Class1 + // apack1.Class1 + // Class1 +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/pack1/Class1.java new file mode 100644 index 00000000000..231fe0676ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments/before/pack1/Class1.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/after/pack2/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/after/pack2/AClass.java new file mode 100644 index 00000000000..4e4dc162d1f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/after/pack2/AClass.java @@ -0,0 +1,5 @@ +package pack2; + +public class AClass { + String s = "pack2.AClass"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/before/pack1/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/before/pack1/AClass.java new file mode 100644 index 00000000000..7cde37cc9ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveClass/stringsAndComments2/before/pack1/AClass.java @@ -0,0 +1,5 @@ +package pack1; + +public class AClass { + String s = "pack1.AClass"; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Inner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Inner.java new file mode 100644 index 00000000000..39ded8a86c8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Inner.java @@ -0,0 +1,4 @@ +package pack1; + +public class Inner { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Outer.java new file mode 100644 index 00000000000..d772ed9c7e5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/after/pack1/Outer.java @@ -0,0 +1,6 @@ +package pack1; + +public class Outer { + // pack1.Inner + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/before/pack1/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/before/pack1/Outer.java new file mode 100644 index 00000000000..97879caa377 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/nonJavaFiles/before/pack1/Outer.java @@ -0,0 +1,8 @@ +package pack1; + +public class Outer { + // pack1.Outer.Inner + + public class Inner { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/Client.java new file mode 100644 index 00000000000..c7a48d68de6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/Client.java @@ -0,0 +1,12 @@ +package pack1; + +public class Client { + public static void main(String[] args) { + StaticInner staticInner = new StaticInner(); + + StaticInner.NonStaticInnerInner nonStaticInnerInner + = staticInner.new NonStaticInnerInner("Joe"); + + System.out.println(nonStaticInnerInner.toString()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/StaticInner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/StaticInner.java new file mode 100644 index 00000000000..d381eba6742 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/StaticInner.java @@ -0,0 +1,15 @@ +package pack1; + +public class StaticInner { + public class NonStaticInnerInner { + private String name; + + public NonStaticInnerInner(String name) { + this.name = name; + } + + public String toString() { + return name; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/TopLevel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/TopLevel.java new file mode 100644 index 00000000000..755ed74aeef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/after/pack1/TopLevel.java @@ -0,0 +1,4 @@ +package pack1; + +public class TopLevel { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/Client.java new file mode 100644 index 00000000000..f6c343a39d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/Client.java @@ -0,0 +1,12 @@ +package pack1; + +public class Client { + public static void main(String[] args) { + TopLevel.StaticInner staticInner = new TopLevel.StaticInner(); + + TopLevel.StaticInner.NonStaticInnerInner nonStaticInnerInner + = staticInner.new NonStaticInnerInner("Joe"); + + System.out.println(nonStaticInnerInner.toString()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/TopLevel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/TopLevel.java new file mode 100644 index 00000000000..c9a25f9531b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr13730/before/pack1/TopLevel.java @@ -0,0 +1,17 @@ +package pack1; + +public class TopLevel { + public static class StaticInner { + public class NonStaticInnerInner { + private String name; + + public NonStaticInnerInner(String name) { + this.name = name; + } + + public String toString() { + return name; + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Inner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Inner.java new file mode 100644 index 00000000000..d81fca04bfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Inner.java @@ -0,0 +1,4 @@ +package xxx; + +public class Inner { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Outer.java new file mode 100644 index 00000000000..0a402971e51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/after/xxx/Outer.java @@ -0,0 +1,8 @@ +package xxx; + +public class Outer { + { + Inner inner = new Inner(); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/before/xxx/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/before/xxx/Outer.java new file mode 100644 index 00000000000..8ba873b36e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr15142/before/xxx/Outer.java @@ -0,0 +1,10 @@ +package xxx; + +public class Outer { + { + Inner inner = new Inner(); + } + + public class Inner { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Inner.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Inner.java new file mode 100644 index 00000000000..22289afc3c4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Inner.java @@ -0,0 +1,9 @@ +package xxx; + +class Inner { + private Outer outer; + + public Inner(Outer outer) { + this.outer = outer; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Outer.java new file mode 100644 index 00000000000..74ee17e1857 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/after/xxx/Outer.java @@ -0,0 +1,7 @@ +package xxx; +class Outer { + + { + Object o = new Inner; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/before/xxx/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/before/xxx/Outer.java new file mode 100644 index 00000000000..02629ef1145 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr22592/before/xxx/Outer.java @@ -0,0 +1,9 @@ +package xxx; +class Outer { + class Inner { + } + + { + Object o = new Inner; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/A.java new file mode 100644 index 00000000000..a3a09030d84 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/A.java @@ -0,0 +1,4 @@ +package p; + +public class A extends X { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/B.java new file mode 100644 index 00000000000..6fa9162793b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/B.java @@ -0,0 +1,13 @@ +package p; + +public class B extends X { + { + method(); + } + + private A outer; + + public B(A outer) { + this.outer = outer; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/X.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/X.java new file mode 100644 index 00000000000..f133448a182 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/after/p/X.java @@ -0,0 +1,5 @@ +package p; + +public class X { + void method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/A.java new file mode 100644 index 00000000000..387bf4b6ddc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/A.java @@ -0,0 +1,9 @@ +package p; + +public class A extends X { + public class B extends X { + { + method(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/X.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/X.java new file mode 100644 index 00000000000..f133448a182 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveInner/scr30106/before/p/X.java @@ -0,0 +1,5 @@ +package p; + +public class X { + void method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/A.java new file mode 100644 index 00000000000..61ff2abcc95 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/A.java @@ -0,0 +1,2 @@ +public class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/B.java new file mode 100644 index 00000000000..05e1b2c7279 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/B.java @@ -0,0 +1,9 @@ +public class B { + Inner i = new Inner(); + + public static class Inner { + public boolean equals(Object o) { + return o instanceof Inner; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/C.java new file mode 100644 index 00000000000..b19d0053026 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/after/C.java @@ -0,0 +1,3 @@ +public class C { + B.Inner i = new B.Inner(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/A.java new file mode 100644 index 00000000000..f36406d6384 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/A.java @@ -0,0 +1,7 @@ +public class A { + public static class Inner { + public boolean equals(Object o) { + return o instanceof Inner; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/B.java new file mode 100644 index 00000000000..56d29d82ca2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/B.java @@ -0,0 +1,3 @@ +public class B { + A.Inner i = new A.Inner(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/C.java new file mode 100644 index 00000000000..66d09a5031d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/innerClass/before/C.java @@ -0,0 +1,3 @@ +public class C { + A.Inner i = new A.Inner(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class1.java new file mode 100644 index 00000000000..6f20cd05baa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class1.java @@ -0,0 +1,9 @@ + +public class Class1 { + + /** + * @see Class2#foo Some text {@link Class2#foo label} + */ + void test() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class2.java new file mode 100644 index 00000000000..845fda18b96 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/Class2.java @@ -0,0 +1,5 @@ + +public class Class2 { + public static void foo(){ + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/User.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/User.java new file mode 100644 index 00000000000..d676cceda19 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/after/User.java @@ -0,0 +1,6 @@ + +/** + * @see Class2#foo Some text {@link Class2#foo label} + */ +public class User { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class1.java new file mode 100644 index 00000000000..47a94458fbc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class1.java @@ -0,0 +1,11 @@ + +public class Class1 { + public static void foo(){ + } + + /** + * @see #foo Some text {@link #foo label} + */ + void test() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class2.java new file mode 100644 index 00000000000..2999267a491 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/Class2.java @@ -0,0 +1,3 @@ + +public class Class2 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/User.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/User.java new file mode 100644 index 00000000000..b726fd502f7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/javadocRefs/before/User.java @@ -0,0 +1,6 @@ + +/** + * @see Class1#foo Some text {@link Class1#foo label} + */ +public class User { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/A.java new file mode 100644 index 00000000000..b53d354d83c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/A.java @@ -0,0 +1,7 @@ +package pack1; + +import java.util.ArrayList; +import java.util.List; + +public class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/Outer.java new file mode 100644 index 00000000000..528ed8f0d7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack1/Outer.java @@ -0,0 +1,6 @@ +package pack1; + +public class Outer { + public static class Inner{ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2/B.java new file mode 100644 index 00000000000..f36b623cccb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/after/pack2/B.java @@ -0,0 +1,12 @@ +package pack2; + +import pack1.Outer; + +import java.util.ArrayList; +import java.util.List; + +public class B { + public static void foo(){ + Outer.Inner x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/A.java new file mode 100644 index 00000000000..9b6b73ff773 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/A.java @@ -0,0 +1,10 @@ +package pack1; + +import java.util.ArrayList; +import java.util.List; + +public class A { + public static void foo(){ + Outer.Inner x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/Outer.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/Outer.java new file mode 100644 index 00000000000..528ed8f0d7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack1/Outer.java @@ -0,0 +1,6 @@ +package pack1; + +public class Outer { + public static class Inner{ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2/B.java new file mode 100644 index 00000000000..0f963b5af7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/outerClassTypeParameters/before/pack2/B.java @@ -0,0 +1,4 @@ +package pack2; + +public class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/A.java new file mode 100644 index 00000000000..9ab38d29515 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/A.java @@ -0,0 +1,7 @@ +package pack1; + +public class A { + + class Inner { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/B.java new file mode 100644 index 00000000000..6897475c147 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/after/pack1/B.java @@ -0,0 +1,7 @@ +package pack1; + +public class B { + static void method() { + A.Inner i = new A.Inner(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/A.java new file mode 100644 index 00000000000..8d90f9224a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/A.java @@ -0,0 +1,10 @@ +package pack1; + +public class A { + static void method() { + Inner i = new Inner(); + } + + class Inner { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/B.java new file mode 100644 index 00000000000..078a6fc9e8d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr11871/before/pack1/B.java @@ -0,0 +1,4 @@ +package pack1; + +public class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/after/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/after/Test.java new file mode 100644 index 00000000000..169ea81b3af --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/after/Test.java @@ -0,0 +1,16 @@ +import static Test1.i; + +class Test { + + void u() { + + } +} + +class Test1 { + { + i = 0; + } + + static int i; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/before/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/before/Test.java new file mode 100644 index 00000000000..10cd1b9d489 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40064/before/Test.java @@ -0,0 +1,15 @@ +import static Test.i; + +class Test { + static int i; + + void u() { + + } +} + +class Test1 { + { + i = 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/after/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/after/Test.java new file mode 100644 index 00000000000..b8ac7593e2a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/after/Test.java @@ -0,0 +1,11 @@ +class A { +} + +class Test { + + static void foo() { + bar(); // note redundant "A" qualifier + } + + static void bar() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/before/Test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/before/Test.java new file mode 100644 index 00000000000..0ebf7c5061f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/scr40947/before/Test.java @@ -0,0 +1,10 @@ +class A { + static void foo() { + A.bar(); // note redundant "A" qualifier + } + static void bar() {} +} + +class Test { + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/A.java new file mode 100644 index 00000000000..526099a640e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/A.java @@ -0,0 +1,5 @@ +package pack1; + +public class A { + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/C.java new file mode 100644 index 00000000000..fa2b3eb764e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack1/C.java @@ -0,0 +1,14 @@ +package pack1; + +public class C { + public static int ourField = 10; + + private static void bar() { + foo(); + ourField = 11; + } + + public static void foo() { + bar(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack2/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack2/B.java new file mode 100644 index 00000000000..0f963b5af7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/after/pack2/B.java @@ -0,0 +1,4 @@ +package pack2; + +public class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/A.java new file mode 100644 index 00000000000..5d8b7288c58 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/A.java @@ -0,0 +1,13 @@ +package pack1; + +public class A { + public static int ourField = 10; + private static void bar() { + foo(); + ourField = 11; + } + + public static void foo() { + bar(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/C.java new file mode 100644 index 00000000000..bb7e3e00160 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack1/C.java @@ -0,0 +1,4 @@ +package pack1; + +public class C { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack2/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack2/B.java new file mode 100644 index 00000000000..0f963b5af7a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/twoMethods/before/pack2/B.java @@ -0,0 +1,4 @@ +package pack2; + +public class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/A.java new file mode 100644 index 00000000000..5bd71b2e520 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/A.java @@ -0,0 +1,3 @@ +public class A { + final static String RIGHT_JUSTIFIED_PREFIX = "%l" ; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/B.java new file mode 100644 index 00000000000..02cd883fc51 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/after/B.java @@ -0,0 +1,4 @@ +public class B { + final static String + LEFT_JUSTIFIED_PREFIX = "%r"; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/A.java new file mode 100644 index 00000000000..f1e6696aa0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/A.java @@ -0,0 +1,5 @@ +public class A { + final static String + LEFT_JUSTIFIED_PREFIX = "%r" , + RIGHT_JUSTIFIED_PREFIX = "%l" ; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/B.java new file mode 100644 index 00000000000..ebbe4dc08cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/moveMembers/weirdDeclaration/before/B.java @@ -0,0 +1,2 @@ +public class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/after/a/b/a/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/after/a/b/a/A.java new file mode 100644 index 00000000000..e2f77b1df42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/after/a/b/a/A.java @@ -0,0 +1,4 @@ +package a.b.a; + +class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/before/a/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/before/a/A.java new file mode 100644 index 00000000000..de9985c0426 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/insidePackage/before/a/A.java @@ -0,0 +1,4 @@ +package a; + +class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User1.java new file mode 100644 index 00000000000..47a6d0ff3be --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User1.java @@ -0,0 +1,7 @@ +package pack2; + +import target.pack1.Class1; + +public class User1 { + Class1 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User2.java new file mode 100644 index 00000000000..7e781947fa3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/pack2/User2.java @@ -0,0 +1,7 @@ +package pack2; + +import target.pack1.*; + +public class User1 { + Class1 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/target/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/target/pack1/Class1.java new file mode 100644 index 00000000000..094eaade0cb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/after/target/pack1/Class1.java @@ -0,0 +1,4 @@ +package target.pack1; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack1/Class1.java new file mode 100644 index 00000000000..231fe0676ab --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack1/Class1.java @@ -0,0 +1,4 @@ +package pack1; + +public class Class1 { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User1.java new file mode 100644 index 00000000000..07287a4a6ef --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User1.java @@ -0,0 +1,7 @@ +package pack2; + +import pack1.Class1; + +public class User1 { + Class1 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User2.java new file mode 100644 index 00000000000..acf3ce5cc76 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/moveSingle/before/pack2/User2.java @@ -0,0 +1,7 @@ +package pack2; + +import pack1.*; + +public class User1 { + Class1 a; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/Usage.java new file mode 100644 index 00000000000..023411e05fe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/Usage.java @@ -0,0 +1,5 @@ +public class Usage { + Object method() { + return package2.test.A.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/package2/test/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/package2/test/A.java new file mode 100644 index 00000000000..fe0e58db26e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/after/package2/test/A.java @@ -0,0 +1,7 @@ +package package2.test; + +public class A { + static Object method() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/Usage.java new file mode 100644 index 00000000000..ab22a555242 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/Usage.java @@ -0,0 +1,5 @@ +public class Usage { + Object method() { + return package1.test.A.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/package1/test/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/package1/test/A.java new file mode 100644 index 00000000000..b48961d05d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackage/qualifiedRef/before/package1/test/A.java @@ -0,0 +1,7 @@ +package package1.test; + +public class A { + static Object method() { + return null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1/A.java new file mode 100644 index 00000000000..7911f65242c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src1/target/pack1/A.java @@ -0,0 +1,4 @@ +package target.pack1; + +class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1/B.java new file mode 100644 index 00000000000..e4cdd3142c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/after/src2/target/pack1/B.java @@ -0,0 +1,4 @@ +package pack2; + +class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1/A.java new file mode 100644 index 00000000000..20aa8107437 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src1/pack1/A.java @@ -0,0 +1,4 @@ +package pack1; + +class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1/B.java new file mode 100644 index 00000000000..e4cdd3142c9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/movePackageMultiroot/movePackage/before/src2/pack1/B.java @@ -0,0 +1,4 @@ +package pack2; + +class B { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack1/List.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack1/List.java new file mode 100644 index 00000000000..68b821c06aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack1/List.java @@ -0,0 +1,4 @@ +package pack1; + +public class List { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage.java new file mode 100644 index 00000000000..992102368d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; +import pack1.*; + +public class Usage { + int method() { + java.util.List list = null; + List myList = null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage2.java new file mode 100644 index 00000000000..5e8108ad3ee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/after/pack2/Usage2.java @@ -0,0 +1,9 @@ +package pack2; +import java.util.*; + +public class Usage2 { + int method() { + List list = null; + pack1.List myList = null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack1/MyList.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack1/MyList.java new file mode 100644 index 00000000000..e988724e42e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack1/MyList.java @@ -0,0 +1,4 @@ +package pack1; + +public class MyList { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage.java new file mode 100644 index 00000000000..902c87bc215 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage.java @@ -0,0 +1,10 @@ +package pack2; +import java.util.List; +import pack1.*; + +public class Usage { + int method() { + List list = null; + MyList myList = null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage2.java new file mode 100644 index 00000000000..0cd1bea4efc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/collision/before/pack2/Usage2.java @@ -0,0 +1,9 @@ +package pack2; +import java.util.*; + +public class Usage2 { + int method() { + List list = null; + pack1.MyList myList = null; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/FooBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/FooBar.java new file mode 100644 index 00000000000..e3c0dfb0c0c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/FooBar.java @@ -0,0 +1,5 @@ +import a.BlubFoo; + +public class FooBar { + BlubFoo blubfoo; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/a/BlubFoo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/a/BlubFoo.java new file mode 100644 index 00000000000..f319ceb52f9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/after/a/BlubFoo.java @@ -0,0 +1,4 @@ +package a; + +public class BlubFoo { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/FooBar.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/FooBar.java new file mode 100644 index 00000000000..1a295478d90 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/FooBar.java @@ -0,0 +1,5 @@ +import a.Blubfoo; + +public class FooBar { + Blubfoo blubfoo; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/a/Blubfoo.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/a/Blubfoo.java new file mode 100644 index 00000000000..d5c77473de6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/import/before/a/Blubfoo.java @@ -0,0 +1,4 @@ +package a; + +public class Blubfoo { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/after/pack1/OuterClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/after/pack1/OuterClass.java new file mode 100644 index 00000000000..270c8842feb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/after/pack1/OuterClass.java @@ -0,0 +1,9 @@ +package pack1; + +public class OuterClass { + public static class NewInnerClass { + + } + + String classLoaderString = "pack1.OuterClass$NewInnerClass"; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/before/pack1/OuterClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/before/pack1/OuterClass.java new file mode 100644 index 00000000000..1317739c645 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/innerClass/before/pack1/OuterClass.java @@ -0,0 +1,9 @@ +package pack1; + +public class OuterClass { + public static class InnerClass { + + } + + String classLoaderString = "pack1.OuterClass$InnerClass"; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/after/pack1/Class1New.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/after/pack1/Class1New.java new file mode 100644 index 00000000000..e09cbfe404f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/after/pack1/Class1New.java @@ -0,0 +1,3 @@ +package pack1; + +class Class1New{} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/before/pack1/Class1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/before/pack1/Class1.java new file mode 100644 index 00000000000..f71c1bc0626 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameClass/nonJava/before/pack1/Class1.java @@ -0,0 +1,3 @@ +package pack1; + +class Class1{} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after01.java new file mode 100644 index 00000000000..248c554a3e2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after01.java @@ -0,0 +1,9 @@ +class A { + int myNewField; +} + +class B { + int method(A a) { + return A.myNewField; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after02.java new file mode 100644 index 00000000000..cffa38bd92d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after02.java @@ -0,0 +1,14 @@ +class A { + int newFieldName; + + int method(int newFieldName) { + if(newFieldName == 0) { + return this.newFieldName; + } + else { + int newFieldName = this.newFieldName; + return this.newFieldName + newFieldName; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after03.java new file mode 100644 index 00000000000..4afd18edc27 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/after03.java @@ -0,0 +1,16 @@ +class A { + int newFieldName; +} + +class B extends A { + int method(int newFieldName) { + if(newFieldName == 0) { + return this.newFieldName; + } + else { + int newFieldName = this.newFieldName; + return this.newFieldName + newFieldName; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before01.java new file mode 100644 index 00000000000..575525bf4ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before01.java @@ -0,0 +1,9 @@ +class A { + int myField; +} + +class B { + int method(A a) { + return A.myField; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before02.java new file mode 100644 index 00000000000..c9a9da94705 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before02.java @@ -0,0 +1,14 @@ +class A { + int fieldToBeRenamed; + + int method(int newFieldName) { + if(newFieldName == 0) { + return fieldToBeRenamed; + } + else { + int newFieldName = fieldToBeRenamed; + return fieldToBeRenamed + newFieldName; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before03.java new file mode 100644 index 00000000000..4cbfb8510a4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameField/before03.java @@ -0,0 +1,16 @@ +class A { + int fieldToBeRenamed; +} + +class B extends A { + int method(int newFieldName) { + if(newFieldName == 0) { + return fieldToBeRenamed; + } + else { + int newFieldName = fieldToBeRenamed; + return fieldToBeRenamed + newFieldName; + } + } +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack1/A.java new file mode 100644 index 00000000000..659a2d218b3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack1/A.java @@ -0,0 +1,6 @@ +package pack1; + +public class A { + public static void renamedStaticMethod(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack2/Usage.java new file mode 100644 index 00000000000..1ac9fbe1a4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/after/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.renamedStaticMethod; + +class Usage { + { + renamedStaticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack1/A.java new file mode 100644 index 00000000000..293f4d3908c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack1/A.java @@ -0,0 +1,6 @@ +package pack1; + +public class A { + public static void staticMethod(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack2/Usage.java new file mode 100644 index 00000000000..233877984ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport1/before/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.staticMethod; + +class Usage { + { + staticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack1/A.java new file mode 100644 index 00000000000..659a2d218b3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack1/A.java @@ -0,0 +1,6 @@ +package pack1; + +public class A { + public static void renamedStaticMethod(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack2/Usage.java new file mode 100644 index 00000000000..08707eeab8b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/after/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.*; + +class Usage { + { + renamedStaticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack1/A.java new file mode 100644 index 00000000000..293f4d3908c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack1/A.java @@ -0,0 +1,6 @@ +package pack1; + +public class A { + public static void staticMethod(int i) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack2/Usage.java new file mode 100644 index 00000000000..b50b933c75f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport2/before/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.*; + +class Usage { + { + staticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack1/A.java new file mode 100644 index 00000000000..ece551733c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack1/A.java @@ -0,0 +1,9 @@ +package pack1; + +public class A { + public static void renamedStaticMethod(int i) { + } + + public static void staticMethod(String s) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack2/Usage.java new file mode 100644 index 00000000000..671aa156d50 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/after/pack2/Usage.java @@ -0,0 +1,10 @@ +package pack2; + +import static pack1.A.staticMethod; +import pack1.A; + +class Usage { + { + A.renamedStaticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack1/A.java new file mode 100644 index 00000000000..bfff831db94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack1/A.java @@ -0,0 +1,9 @@ +package pack1; + +public class A { + public static void staticMethod(int i) { + } + + public static void staticMethod(String s) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack2/Usage.java new file mode 100644 index 00000000000..233877984ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport3/before/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.staticMethod; + +class Usage { + { + staticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack1/A.java new file mode 100644 index 00000000000..edf51cd56fa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack1/A.java @@ -0,0 +1,9 @@ +package pack1; + +public class A { + public static void renamedStaticMethod(int i) { + } + + private static void staticMethod(String s) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack2/Usage.java new file mode 100644 index 00000000000..1ac9fbe1a4b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/after/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.renamedStaticMethod; + +class Usage { + { + renamedStaticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack1/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack1/A.java new file mode 100644 index 00000000000..e9b34ebac5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack1/A.java @@ -0,0 +1,9 @@ +package pack1; + +public class A { + public static void staticMethod(int i) { + } + + private static void staticMethod(String s) { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack2/Usage.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack2/Usage.java new file mode 100644 index 00000000000..233877984ec --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/renameMethod/multi/staticImport4/before/pack2/Usage.java @@ -0,0 +1,9 @@ +package pack2; + +import static pack1.A.staticMethod; + +class Usage { + { + staticMethod(27); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after01.java new file mode 100644 index 00000000000..55ba35cb2b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after01.java @@ -0,0 +1,8 @@ +class A { + private A() { + } + + static A newA() { + return new A(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after02.java new file mode 100644 index 00000000000..1de911ceae3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after02.java @@ -0,0 +1,22 @@ +class A { + A(int i) { + } + + A method() { + return newA(10); + } + + public static A newA(int i) { + return new A(i); + } +} + +class B extends A { + B(int j) { + super(j+1); + } +} + +class Usage { + A a = A.newA(2); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after03.java new file mode 100644 index 00000000000..691d92552f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after03.java @@ -0,0 +1,12 @@ +class A { + private A() { + } + + static A newA() { + return new A(); + } +} + +public class B { + A a = A.newA(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after04.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after04.java new file mode 100644 index 00000000000..e3c874d8a68 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after04.java @@ -0,0 +1,17 @@ +class OuterClass { + InnerClass newInnerClass(int _i) { + return new InnerClass(_i); + } + + class InnerClass { + int i; + private InnerClass(int _i) { + i = _i; + } + } + InnerClass myInner = newInnerClass(27); + static int method() { + OuterClass test = new OuterClass(); + InnerClass inner = test.newInnerClass(15); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after05.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after05.java new file mode 100644 index 00000000000..1dbd44a37d8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after05.java @@ -0,0 +1,14 @@ +class A { + A(int i) { + } + + static A newA(int i) { + return new A(i); + } +} + +class B extends A { + B(int i) { + super(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after06.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after06.java new file mode 100644 index 00000000000..91fbd4d8118 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after06.java @@ -0,0 +1,13 @@ +class A { + A() { + } + + static A newA() { + return new A(); + } +} + +class B extends A { + B() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after07.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after07.java new file mode 100644 index 00000000000..55ba35cb2b5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/after07.java @@ -0,0 +1,8 @@ +class A { + private A() { + } + + static A newA() { + return new A(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before01.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before01.java new file mode 100644 index 00000000000..ff426d1c0d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before01.java @@ -0,0 +1,4 @@ +class A { + A() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before02.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before02.java new file mode 100644 index 00000000000..1223112eaee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before02.java @@ -0,0 +1,18 @@ +class A { + public A(int i) { + } + + A method() { + return new A(10); + } +} + +class B extends A { + B(int j) { + super(j+1); + } +} + +class Usage { + A a = new A(2); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before03.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before03.java new file mode 100644 index 00000000000..813c5367146 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before03.java @@ -0,0 +1,6 @@ +class A { +} + +public class B { + A a = new A(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before04.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before04.java new file mode 100644 index 00000000000..2260e2f3272 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before04.java @@ -0,0 +1,13 @@ +class OuterClass { + class InnerClass { + int i; + InnerClass(int _i) { + i = _i; + } + } + InnerClass myInner = new InnerClass(27); + static int method() { + OuterClass test = new OuterClass(); + InnerClass inner = test.new InnerClass(15); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before05.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before05.java new file mode 100644 index 00000000000..398322d17a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before05.java @@ -0,0 +1,10 @@ +class A { + A(int i) { + } +} + +class B extends A { + B(int i) { + super(i); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before06.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before06.java new file mode 100644 index 00000000000..dd50cca0262 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before06.java @@ -0,0 +1,9 @@ +class A { + A() { + } +} + +class B extends A { + B() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before07.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before07.java new file mode 100644 index 00000000000..928a66472f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/replaceConstructorWithFactory/before07.java @@ -0,0 +1,2 @@ +class A { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/C.java new file mode 100644 index 00000000000..a9fcfe3180a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/C.java @@ -0,0 +1,2 @@ +public class C implements I{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/Client.java new file mode 100644 index 00000000000..5b55119399b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/Client.java @@ -0,0 +1,10 @@ +public class Client { + I[] array; + + { + array = new I[0]; + for(int i = 0; i < array.length; i++){ + array[i] = new C(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/I.java new file mode 100644 index 00000000000..288bec1ad20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/after/I.java @@ -0,0 +1,2 @@ +public interface I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/C.java new file mode 100644 index 00000000000..a9fcfe3180a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/C.java @@ -0,0 +1,2 @@ +public class C implements I{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/Client.java new file mode 100644 index 00000000000..5eb112ac863 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/Client.java @@ -0,0 +1,10 @@ +public class Client { + C[] array; + + { + array = new C[0]; + for(int i = 0; i < array.length; i++){ + array[i] = new C(); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/I.java new file mode 100644 index 00000000000..288bec1ad20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/arrayElementAssignment/before/I.java @@ -0,0 +1,2 @@ +public interface I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/A.java new file mode 100644 index 00000000000..5148345b148 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/A.java @@ -0,0 +1,5 @@ +class A implements I { + int method() { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/Client.java new file mode 100644 index 00000000000..e58b3599914 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/Client.java @@ -0,0 +1,11 @@ +class Client { + I getI() { return null; }; + + void method() { + I a = getI(); + } + + int anotherMethod() { + return getI().method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/I.java new file mode 100644 index 00000000000..27f3c66aa97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/after/I.java @@ -0,0 +1,3 @@ +interface I { + int method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/A.java new file mode 100644 index 00000000000..5148345b148 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/A.java @@ -0,0 +1,5 @@ +class A implements I { + int method() { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/Client.java new file mode 100644 index 00000000000..0fe5cd06b1d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/Client.java @@ -0,0 +1,11 @@ +class Client { + I getI() { return null; }; + + void method() { + A a = (A) getI(); + } + + int anotherMethod() { + return ((A) getI()).method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/I.java new file mode 100644 index 00000000000..27f3c66aa97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/cast/before/I.java @@ -0,0 +1,3 @@ +interface I { + int method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/A.java new file mode 100644 index 00000000000..92b7623e48c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/A.java @@ -0,0 +1,5 @@ +class A implements I { + int method() { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/Client.java new file mode 100644 index 00000000000..9b39f0136d5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/Client.java @@ -0,0 +1,9 @@ +public class Client { + Class getClass() { + return A.class; + } + + int m(I a) { + return I.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/I.java new file mode 100644 index 00000000000..27f3c66aa97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/after/I.java @@ -0,0 +1,3 @@ +interface I { + int method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/A.java new file mode 100644 index 00000000000..92b7623e48c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/A.java @@ -0,0 +1,5 @@ +class A implements I { + int method() { + return 0; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/Client.java new file mode 100644 index 00000000000..6a2f88e0fb0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/Client.java @@ -0,0 +1,9 @@ +public class Client { + Class getClass() { + return A.class; + } + + int m(A a) { + return A.method(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/I.java new file mode 100644 index 00000000000..27f3c66aa97 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/classUsage/before/I.java @@ -0,0 +1,3 @@ +interface I { + int method(); +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/after/Client.java new file mode 100644 index 00000000000..e7ba92bebaf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/after/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + int method(L v) { return 0; } + } + + interface I { int method(L v); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/before/Client.java new file mode 100644 index 00000000000..6ae4064519b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritor/before/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + int method(V v) { return 0; } + } + + interface I { int method(V v); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/after/Client.java new file mode 100644 index 00000000000..cfdcd95134a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/after/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + int method(V v) { v.q(); return 0; } + } + + interface I { int method(V v); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/before/Client.java new file mode 100644 index 00000000000..cfdcd95134a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorFail/before/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + int method(V v) { v.q(); return 0; } + } + + interface I { int method(V v); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/after/Client.java new file mode 100644 index 00000000000..3ddf23d7e3e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/after/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + L method() { L res = new V (); return res; } + } + + interface I { L method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/before/Client.java new file mode 100644 index 00000000000..ac42c3c4844 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResults/before/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + V method() { V res = new V (); return res; } + } + + interface I { V method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after/Client.java new file mode 100644 index 00000000000..1791f27cedf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/after/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + L method() { V res = new V (); res.q(); return res; } + } + + interface I { L method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before/Client.java new file mode 100644 index 00000000000..25f7879b579 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail/before/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + V method() { V res = new V (); res.q(); return res; } + } + + interface I { V method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after/Client.java new file mode 100644 index 00000000000..2d4317e89ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/after/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + V method() { V res = new V (); method().q(); return res; } + } + + interface I { V method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before/Client.java new file mode 100644 index 00000000000..2d4317e89ed --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/commonInheritorResultsFail2/before/Client.java @@ -0,0 +1,20 @@ +class Client +{ + + interface L { void m (); } + + class V implements L { + void m () { } + void q () { } + } + + //------------------------------------ + + class C { + V method() { V res = new V (); method().q(); return res; } + } + + interface I { V method(); } + + class D extends C implements I { } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/Component1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/Component1.java new file mode 100644 index 00000000000..86168a57e6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/Component1.java @@ -0,0 +1,11 @@ +import javax.swing.*; + +public class Component1 extends JComponent implements IDoSomething { + public Component1() { + } + + + public void doSomething(){ + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/ComponentCaller.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/ComponentCaller.java new file mode 100644 index 00000000000..81cf4aca07d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/ComponentCaller.java @@ -0,0 +1,20 @@ +import java.awt.BorderLayout; +import javax.swing.*; + +public class ComponentCaller extends JComponent{ + Component1 component1; + + public ComponentCaller() { + component1 = new Component1(); + buildUI(); + } + + private void buildUI() { + setLayout(new BorderLayout()); + add(new JScrollPane(component1)); + } + + public void doSomething(){ + component1.doSomething(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/IDoSomething.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/IDoSomething.java new file mode 100644 index 00000000000..56079702f3d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/after/IDoSomething.java @@ -0,0 +1,3 @@ +public interface IDoSomething { + void doSomething(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/Component1.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/Component1.java new file mode 100644 index 00000000000..86168a57e6b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/Component1.java @@ -0,0 +1,11 @@ +import javax.swing.*; + +public class Component1 extends JComponent implements IDoSomething { + public Component1() { + } + + + public void doSomething(){ + + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/ComponentCaller.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/ComponentCaller.java new file mode 100644 index 00000000000..81cf4aca07d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/ComponentCaller.java @@ -0,0 +1,20 @@ +import java.awt.BorderLayout; +import javax.swing.*; + +public class ComponentCaller extends JComponent{ + Component1 component1; + + public ComponentCaller() { + component1 = new Component1(); + buildUI(); + } + + private void buildUI() { + setLayout(new BorderLayout()); + add(new JScrollPane(component1)); + } + + public void doSomething(){ + component1.doSomething(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/IDoSomething.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/IDoSomething.java new file mode 100644 index 00000000000..56079702f3d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/fieldTest/before/IDoSomething.java @@ -0,0 +1,3 @@ +public interface IDoSomething { + void doSomething(); +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/A.java new file mode 100644 index 00000000000..f4ba62924c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/A.java @@ -0,0 +1,2 @@ +class A implements I { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/Client.java new file mode 100644 index 00000000000..cf9b78acf09 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/Client.java @@ -0,0 +1,5 @@ +class Client { + int method(I a) { + return a instanceof A; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/I.java new file mode 100644 index 00000000000..f0ff965a804 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/after/I.java @@ -0,0 +1,2 @@ +interface I { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/A.java new file mode 100644 index 00000000000..f4ba62924c6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/A.java @@ -0,0 +1,2 @@ +class A implements I { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/Client.java new file mode 100644 index 00000000000..56c3c42f3bd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/Client.java @@ -0,0 +1,5 @@ +class Client { + int method(A a) { + return a instanceof A; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/I.java new file mode 100644 index 00000000000..f0ff965a804 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/instanceOf/before/I.java @@ -0,0 +1,2 @@ +interface I { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/AClass.java new file mode 100644 index 00000000000..52838345d38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/AClass.java @@ -0,0 +1,5 @@ + +public class AClass extends ASuper2 { + public void foo() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper.java new file mode 100644 index 00000000000..4b6b35bfa30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper.java @@ -0,0 +1,4 @@ + +public class ASuper { + public void foo(){} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper2.java new file mode 100644 index 00000000000..378333fbf21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/ASuper2.java @@ -0,0 +1,3 @@ + +public class ASuper2 extends ASuper { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/Client.java new file mode 100644 index 00000000000..81ffde95cb1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/after/Client.java @@ -0,0 +1,7 @@ + +public class Client { + { + ASuper aClass; + aClass.foo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/AClass.java new file mode 100644 index 00000000000..52838345d38 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/AClass.java @@ -0,0 +1,5 @@ + +public class AClass extends ASuper2 { + public void foo() { + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper.java new file mode 100644 index 00000000000..4b6b35bfa30 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper.java @@ -0,0 +1,4 @@ + +public class ASuper { + public void foo(){} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper2.java new file mode 100644 index 00000000000..378333fbf21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/ASuper2.java @@ -0,0 +1,3 @@ + +public class ASuper2 extends ASuper { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/Client.java new file mode 100644 index 00000000000..28af224eacd --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/methodFromSuper/before/Client.java @@ -0,0 +1,7 @@ + +public class Client { + { + AClass aClass; + aClass.foo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AClass.java new file mode 100644 index 00000000000..915b5a850eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AClass.java @@ -0,0 +1,5 @@ + +package pack1; + +public class AClass implements AnInterface { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AnInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AnInterface.java new file mode 100644 index 00000000000..23669d782e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack1/AnInterface.java @@ -0,0 +1,5 @@ + +package pack1; + +public interface AnInterface { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client.java new file mode 100644 index 00000000000..8d3fe5f8d94 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client.java @@ -0,0 +1,10 @@ + +package pack2; + +import pack1.AnInterface; + +public class Client { + { + AnInterface aClass; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client2.java new file mode 100644 index 00000000000..32ddf7636f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/after/pack2/Client2.java @@ -0,0 +1,11 @@ + +package pack2; + +import pack1.AClass; +import pack1.AnInterface; + +public class Client { + { + AnInterface aClass = new AClass(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AClass.java new file mode 100644 index 00000000000..915b5a850eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AClass.java @@ -0,0 +1,5 @@ + +package pack1; + +public class AClass implements AnInterface { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AnInterface.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AnInterface.java new file mode 100644 index 00000000000..23669d782e4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack1/AnInterface.java @@ -0,0 +1,5 @@ + +package pack1; + +public interface AnInterface { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client.java new file mode 100644 index 00000000000..a8093becaee --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client.java @@ -0,0 +1,10 @@ + +package pack2; + +import pack1.AClass; + +public class Client { + { + AClass aClass; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client2.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client2.java new file mode 100644 index 00000000000..dab0869ba81 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/removeImport/before/pack2/Client2.java @@ -0,0 +1,10 @@ + +package pack2; + +import pack1.AClass; + +public class Client { + { + AClass aClass = new AClass(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/B.java new file mode 100644 index 00000000000..ab916981e32 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/B.java @@ -0,0 +1,13 @@ +import java.util.ArrayList; + +class B { + I[] getA() { return null; }; + + int method(ArrayList list) { + I[] a = getA(); + + for(i = 0; i < a.length; i++) { + I item = a[i]; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/after/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/B.java new file mode 100644 index 00000000000..8d9bf45596a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/B.java @@ -0,0 +1,13 @@ +import java.util.ArrayList; + +class B { + A[] getA() { return null; }; + + int method(ArrayList list) { + A[] a = getA(); + + for(i = 0; i < a.length; i++) { + A item = a[i]; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue/before/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/B.java new file mode 100644 index 00000000000..7f1d3bf0f34 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/B.java @@ -0,0 +1,13 @@ +import java.util.ArrayList; + +class B { + I getA() { return new A(); }; + void test(I a) { + } + + int method(ArrayList list) { + I a = getA(); + + test(a); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/after/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/B.java new file mode 100644 index 00000000000..4c91f698350 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/B.java @@ -0,0 +1,13 @@ +import java.util.ArrayList; + +class B { + A getA() { return new A(); }; + void test(A a) { + } + + int method(ArrayList list) { + A a = getA(); + + test(a); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/returnValue2/before/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Main.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Main.java new file mode 100644 index 00000000000..d2944a37a3a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Main.java @@ -0,0 +1,10 @@ +public class Main { + private static void install() { + Model simpleModel = new SimpleModel(); + View view = new View(simpleModel); + } + public void foo() { + Model simpleModel = new SimpleModel(); + simpleModel.doIt(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Model.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Model.java new file mode 100644 index 00000000000..412ea632e91 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/Model.java @@ -0,0 +1,3 @@ +public class Model { + public void doIt() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/SimpleModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/SimpleModel.java new file mode 100644 index 00000000000..a36790a59c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/SimpleModel.java @@ -0,0 +1,2 @@ +class SimpleModel extends Model { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/View.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/View.java new file mode 100644 index 00000000000..f1a23ddaaad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/after/View.java @@ -0,0 +1,3 @@ +public class View { + public View(Model model) {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Main.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Main.java new file mode 100644 index 00000000000..8a04b25d618 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Main.java @@ -0,0 +1,10 @@ +public class Main { + private static void install() { + SimpleModel simpleModel = new SimpleModel(); + View view = new View(simpleModel); + } + public void foo() { + SimpleModel simpleModel = new SimpleModel(); + simpleModel.doIt(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Model.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Model.java new file mode 100644 index 00000000000..412ea632e91 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/Model.java @@ -0,0 +1,3 @@ +public class Model { + public void doIt() {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/SimpleModel.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/SimpleModel.java new file mode 100644 index 00000000000..a36790a59c3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/SimpleModel.java @@ -0,0 +1,2 @@ +class SimpleModel extends Model { +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/View.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/View.java new file mode 100644 index 00000000000..f1a23ddaaad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34000/before/View.java @@ -0,0 +1,3 @@ +public class View { + public View(Model model) {} +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/after/test/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/after/test/C.java new file mode 100644 index 00000000000..6c7526b5418 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/after/test/C.java @@ -0,0 +1,17 @@ +package test; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: dsl + * Date: Jun 17, 2004 + * Time: 1:28:14 PM + * To change this template use File | Settings | File Templates. + */ +public class C { + { + List l = new ArrayList(); + Collections.binarySearch(l, null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/before/test/C.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/before/test/C.java new file mode 100644 index 00000000000..6c7526b5418 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/scr34020/before/test/C.java @@ -0,0 +1,17 @@ +package test; + +import java.util.*; + +/** + * Created by IntelliJ IDEA. + * User: dsl + * Date: Jun 17, 2004 + * Time: 1:28:14 PM + * To change this template use File | Settings | File Templates. + */ +public class C { + { + List l = new ArrayList(); + Collections.binarySearch(l, null); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/AClass.java new file mode 100644 index 00000000000..88fb2796d29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/AClass.java @@ -0,0 +1,7 @@ +public class AClass extends ASuper { + + public void sayBar() + { + System.out.println("Bar"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/ASuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/ASuper.java new file mode 100644 index 00000000000..bf19e4d57c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/ASuper.java @@ -0,0 +1,6 @@ +public class ASuper { + public void sayFoo() + { + System.out.println("Foo"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/Client.java new file mode 100644 index 00000000000..395ec1820f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/after/Client.java @@ -0,0 +1,6 @@ +public class Client { + { + ASuper b = new AClass(); + b.sayFoo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/AClass.java new file mode 100644 index 00000000000..88fb2796d29 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/AClass.java @@ -0,0 +1,7 @@ +public class AClass extends ASuper { + + public void sayBar() + { + System.out.println("Bar"); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/ASuper.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/ASuper.java new file mode 100644 index 00000000000..bf19e4d57c7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/ASuper.java @@ -0,0 +1,6 @@ +public class ASuper { + public void sayFoo() + { + System.out.println("Foo"); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/Client.java new file mode 100644 index 00000000000..25b6ad18f5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/superClass/before/Client.java @@ -0,0 +1,6 @@ +public class Client { + { + AClass b = new AClass(); + b.sayFoo(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/B.java new file mode 100644 index 00000000000..2c7cd2b491c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/B.java @@ -0,0 +1,11 @@ +import java.util.ArrayList; + +class B { + int method(ArrayList list) { + I[] a = (I[])list.toArray(new I[0]); + + for(i = 0; i < a.length; i++) { + I member = a[i]; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/after/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/A.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/A.java new file mode 100644 index 00000000000..73c334c20f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/A.java @@ -0,0 +1,2 @@ +class A implements I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/B.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/B.java new file mode 100644 index 00000000000..f208a4e96c5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/B.java @@ -0,0 +1,11 @@ +import java.util.ArrayList; + +class B { + int method(ArrayList list) { + A[] a = (A[])list.toArray(new A[0]); + + for(i = 0; i < a.length; i++) { + A member = a[i]; + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/I.java new file mode 100644 index 00000000000..84885be3c0b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/toArray/before/I.java @@ -0,0 +1,4 @@ +import java.util.ArrayList; +interface I { +} + diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/AClass.java new file mode 100644 index 00000000000..8e196014740 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/AClass.java @@ -0,0 +1,3 @@ + +public class AClass implements Runnable, I{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/Client.java new file mode 100644 index 00000000000..56136148c80 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/Client.java @@ -0,0 +1,14 @@ + +import javax.swing.*; + +public class Client { + { + AClass aClass = new AClass(); + SwingUtilities.invokeLater(aClass); + } + + void method(void) { + Runnable r = new AClass(); + SwingUtilities.invokeLater(r); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/I.java new file mode 100644 index 00000000000..e9c4c0d9855 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/after/I.java @@ -0,0 +1,3 @@ + +public interface I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/AClass.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/AClass.java new file mode 100644 index 00000000000..8e196014740 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/AClass.java @@ -0,0 +1,3 @@ + +public class AClass implements Runnable, I{ +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/Client.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/Client.java new file mode 100644 index 00000000000..56136148c80 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/Client.java @@ -0,0 +1,14 @@ + +import javax.swing.*; + +public class Client { + { + AClass aClass = new AClass(); + SwingUtilities.invokeLater(aClass); + } + + void method(void) { + Runnable r = new AClass(); + SwingUtilities.invokeLater(r); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/I.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/I.java new file mode 100644 index 00000000000..e9c4c0d9855 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/turnRefsToSuper/useAsArg/before/I.java @@ -0,0 +1,3 @@ + +public interface I { +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/after/test.java new file mode 100644 index 00000000000..a7af03c160e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x=k; + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/before/test.java new file mode 100644 index 00000000000..a7af03c160e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t01/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x=k; + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/after/test.java new file mode 100644 index 00000000000..129dbd335a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x.set(new Integer()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/before/test.java new file mode 100644 index 00000000000..129dbd335a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t02/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x.set(new Integer()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/after/test.java new file mode 100644 index 00000000000..e2ed3fcfebe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x=k; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/before/test.java new file mode 100644 index 00000000000..e2ed3fcfebe --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t03/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList k; + LinkedList x; + + void f(){ + x=k; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/after/test.java new file mode 100644 index 00000000000..ecb41c606d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/after/test.java @@ -0,0 +1,18 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + void f(){ + Simple s = (Simple) x.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/before/test.java new file mode 100644 index 00000000000..ecb41c606d6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t04/before/test.java @@ -0,0 +1,18 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + void f(){ + Simple s = (Simple) x.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/after/test.java new file mode 100644 index 00000000000..70516599e67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set((Simple) x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/before/test.java new file mode 100644 index 00000000000..70516599e67 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t05/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set((Simple) x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/after/test.java new file mode 100644 index 00000000000..e64e2354864 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/before/test.java new file mode 100644 index 00000000000..e64e2354864 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t06/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/after/test.java new file mode 100644 index 00000000000..7835414497f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) x.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/before/test.java new file mode 100644 index 00000000000..7835414497f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t07/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) x.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/after/test.java new file mode 100644 index 00000000000..38be159110d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/after/test.java @@ -0,0 +1,21 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) x.get(); + y.set(new Test()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/before/test.java new file mode 100644 index 00000000000..38be159110d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t08/before/test.java @@ -0,0 +1,21 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) x.get(); + y.set(new Test()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/after/test.java new file mode 100644 index 00000000000..d83140fbeb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList[] x; + LinkedList y; + + void f(){ + y.set(x[0].get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/before/test.java new file mode 100644 index 00000000000..d83140fbeb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t09/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList[] x; + LinkedList y; + + void f(){ + y.set(x[0].get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/after/test.java new file mode 100644 index 00000000000..70c046aab2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList[] x; + LinkedList y; + + void f(){ + x[0].set (new Simple()); + x[1].set (new Test()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/before/test.java new file mode 100644 index 00000000000..70c046aab2e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t10/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList[] x; + LinkedList y; + + void f(){ + x[0].set (new Simple()); + x[1].set (new Test()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/after/test.java new file mode 100644 index 00000000000..5ace483debb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/after/test.java @@ -0,0 +1,11 @@ +class List { + void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/before/test.java new file mode 100644 index 00000000000..5ace483debb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t100/before/test.java @@ -0,0 +1,11 @@ +class List { + void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/after/test.java new file mode 100644 index 00000000000..930f33c8493 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/after/test.java @@ -0,0 +1,11 @@ +class List { + void f (T a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/before/test.java new file mode 100644 index 00000000000..930f33c8493 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t101/before/test.java @@ -0,0 +1,11 @@ +class List { + void f (T a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/after/test.java new file mode 100644 index 00000000000..8f1db94845e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/after/test.java @@ -0,0 +1,11 @@ +class List { + void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/before/test.java new file mode 100644 index 00000000000..8f1db94845e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t102/before/test.java @@ -0,0 +1,11 @@ +class List { + void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/after/test.java new file mode 100644 index 00000000000..09b1f8a72aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/after/test.java @@ -0,0 +1,15 @@ +class List { + > void f (A a){ + } +} + +class Mist extends List{ +} + +class Test { + void foo (){ + Mist y = null; + List x = null; + x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/before/test.java new file mode 100644 index 00000000000..09b1f8a72aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t103/before/test.java @@ -0,0 +1,15 @@ +class List { + > void f (A a){ + } +} + +class Mist extends List{ +} + +class Test { + void foo (){ + Mist y = null; + List x = null; + x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/after/test.java new file mode 100644 index 00000000000..82a21f70978 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/after/test.java @@ -0,0 +1,17 @@ +class List { +} + +class Mist extends List{ +} + +class foo{ + X x; +} + +class Test { + void foo (){ + Mist y = null; + foo x = null; + x.x = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/before/test.java new file mode 100644 index 00000000000..82a21f70978 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t104/before/test.java @@ -0,0 +1,17 @@ +class List { +} + +class Mist extends List{ +} + +class foo{ + X x; +} + +class Test { + void foo (){ + Mist y = null; + foo x = null; + x.x = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/after/test.java new file mode 100644 index 00000000000..827af95faa0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/after/test.java @@ -0,0 +1,15 @@ +class List { + void f (A x){ + } +} + +class Mist { + List x; +} + +class Test { + void foo (){ + Mist x = null; + x.x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/before/test.java new file mode 100644 index 00000000000..827af95faa0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t105/before/test.java @@ -0,0 +1,15 @@ +class List { + void f (A x){ + } +} + +class Mist { + List x; +} + +class Test { + void foo (){ + Mist x = null; + x.x.f(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/after/test.java new file mode 100644 index 00000000000..af95dc13976 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/after/test.java @@ -0,0 +1,12 @@ +class List { + A[] f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + String[] y = (String[]) x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/before/test.java new file mode 100644 index 00000000000..af95dc13976 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t106/before/test.java @@ -0,0 +1,12 @@ +class List { + A[] f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + String[] y = (String[]) x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/after/test.java new file mode 100644 index 00000000000..250510494a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/after/test.java @@ -0,0 +1,12 @@ +class List { + A[] f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + String[] y = (String[]) x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/before/test.java new file mode 100644 index 00000000000..250510494a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t107/before/test.java @@ -0,0 +1,12 @@ +class List { + A[] f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + String[] y = (String[]) x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/after/test.java new file mode 100644 index 00000000000..d3002ae65f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/after/test.java @@ -0,0 +1,14 @@ +class List { + List f (List x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + List y = null; + + x = x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/before/test.java new file mode 100644 index 00000000000..d3002ae65f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t108/before/test.java @@ -0,0 +1,14 @@ +class List { + List f (List x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + List y = null; + + x = x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/after/test.java new file mode 100644 index 00000000000..f0e93b2a3a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/after/test.java @@ -0,0 +1,12 @@ +class List { + List f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + x = x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/before/test.java new file mode 100644 index 00000000000..f0e93b2a3a7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t109/before/test.java @@ -0,0 +1,12 @@ +class List { + List f (A[] x){ + return x; + } +} + +class Test { + void foo (){ + List x = null; + x = x.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/after/test.java new file mode 100644 index 00000000000..f4994e3e6d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/after/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set(true ? x.get() : x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/before/test.java new file mode 100644 index 00000000000..f4994e3e6d9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t11/before/test.java @@ -0,0 +1,19 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set(true ? x.get() : x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/after/test.java new file mode 100644 index 00000000000..b6db3ae7d01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/after/test.java @@ -0,0 +1,15 @@ +class List { + List f (A[] x){ + return x; + } + + List(List y){ + } +} + +class Test { + void foo (){ + List x = null; + List y = new List(x.f(new String[] {})); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/before/test.java new file mode 100644 index 00000000000..b6db3ae7d01 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t110/before/test.java @@ -0,0 +1,15 @@ +class List { + List f (A[] x){ + return x; + } + + List(List y){ + } +} + +class Test { + void foo (){ + List x = null; + List y = new List(x.f(new String[] {})); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/after/test.java new file mode 100644 index 00000000000..4921dd1ccd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/after/test.java @@ -0,0 +1,15 @@ +class List { + List f (List x){ + return x; + } + T t; +} + +class Test { + void foo (){ + List x = null; + List y = x.f(x); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/before/test.java new file mode 100644 index 00000000000..4921dd1ccd3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t111/before/test.java @@ -0,0 +1,15 @@ +class List { + List f (List x){ + return x; + } + T t; +} + +class Test { + void foo (){ + List x = null; + List y = x.f(x); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/after/test.java new file mode 100644 index 00000000000..c1b768925a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/after/test.java @@ -0,0 +1,13 @@ +class List { + List(A x){ + t = x; + } + + T t; +} + +class Test { + void foo (){ + List y = new List(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/before/test.java new file mode 100644 index 00000000000..c1b768925a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t112/before/test.java @@ -0,0 +1,13 @@ +class List { + List(A x){ + t = x; + } + + T t; +} + +class Test { + void foo (){ + List y = new List(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/after/test.java new file mode 100644 index 00000000000..c1b768925a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/after/test.java @@ -0,0 +1,13 @@ +class List { + List(A x){ + t = x; + } + + T t; +} + +class Test { + void foo (){ + List y = new List(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/before/test.java new file mode 100644 index 00000000000..c1b768925a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t113/before/test.java @@ -0,0 +1,13 @@ +class List { + List(A x){ + t = x; + } + + T t; +} + +class Test { + void foo (){ + List y = new List(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/after/test.java new file mode 100644 index 00000000000..b6463d19ece --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/after/test.java @@ -0,0 +1,12 @@ +class List { + void f(T[] x){ + } +} + +class Test { + void foo (){ + List y = null; + + y.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/before/test.java new file mode 100644 index 00000000000..b6463d19ece --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t114/before/test.java @@ -0,0 +1,12 @@ +class List { + void f(T[] x){ + } +} + +class Test { + void foo (){ + List y = null; + + y.f(new String[] {}); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/after/test.java new file mode 100644 index 00000000000..1801e964a42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/after/test.java @@ -0,0 +1,13 @@ +class List { + T[] f(){ + return null; + } +} + +class Test { + void foo (){ + List y = null; + + String[] x = (String[]) y.f(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/before/test.java new file mode 100644 index 00000000000..1801e964a42 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t115/before/test.java @@ -0,0 +1,13 @@ +class List { + T[] f(){ + return null; + } +} + +class Test { + void foo (){ + List y = null; + + String[] x = (String[]) y.f(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/after/test.java new file mode 100644 index 00000000000..c2383c2e06b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/after/test.java @@ -0,0 +1,13 @@ +class List { + T[] f(){ + return null; + } +} + +class Test { + void foo (){ + List y = null; + + String x = (String) (y.f()[0]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/before/test.java new file mode 100644 index 00000000000..c2383c2e06b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t116/before/test.java @@ -0,0 +1,13 @@ +class List { + T[] f(){ + return null; + } +} + +class Test { + void foo (){ + List y = null; + + String x = (String) (y.f()[0]); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/after/test.java new file mode 100644 index 00000000000..035b3089fc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/after/test.java @@ -0,0 +1,12 @@ +class List { + static > void f(A x, B y){ + } +} + +class Test { + void foo (){ + List y = null; + + List.f("", y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/before/test.java new file mode 100644 index 00000000000..035b3089fc4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t117/before/test.java @@ -0,0 +1,12 @@ +class List { + static > void f(A x, B y){ + } +} + +class Test { + void foo (){ + List y = null; + + List.f("", y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/after/test.java new file mode 100644 index 00000000000..c5cbc6c63eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/after/test.java @@ -0,0 +1,19 @@ +class List { + static > void f(A x, B y){ + } + T t; +} + +class Mist extends List{ +} + +class Test { + void foo (){ + List y = null; + Mist z = null; + + List.f(y.t, z); + + z.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/before/test.java new file mode 100644 index 00000000000..c5cbc6c63eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t118/before/test.java @@ -0,0 +1,19 @@ +class List { + static > void f(A x, B y){ + } + T t; +} + +class Mist extends List{ +} + +class Test { + void foo (){ + List y = null; + Mist z = null; + + List.f(y.t, z); + + z.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/after/test.java new file mode 100644 index 00000000000..83f433b7765 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/after/test.java @@ -0,0 +1,15 @@ +class List { + List(List x){ + } + + T t; +} + +class Test { + void foo (){ + List x = null; + List y = new List(x); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/before/test.java new file mode 100644 index 00000000000..83f433b7765 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t119/before/test.java @@ -0,0 +1,15 @@ +class List { + List(List x){ + } + + T t; +} + +class Test { + void foo (){ + List x = null; + List y = new List(x); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/after/test.java new file mode 100644 index 00000000000..819342b0ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/after/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set(((Simple) y.get()).f() ? x.get() : x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/before/test.java new file mode 100644 index 00000000000..819342b0ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t12/before/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set(((Simple) y.get()).f() ? x.get() : x.get()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/after/test.java new file mode 100644 index 00000000000..6bbdc6cd74c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/after/test.java @@ -0,0 +1,15 @@ +class A {} + +class List extends A { + T t; +} + + +class Test { + void foo (){ + List y = null; + A a = y; + + y.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/before/test.java new file mode 100644 index 00000000000..6bbdc6cd74c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t120/before/test.java @@ -0,0 +1,15 @@ +class A {} + +class List extends A { + T t; +} + + +class Test { + void foo (){ + List y = null; + A a = y; + + y.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/after/test.java new file mode 100644 index 00000000000..03476c73ba7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/after/test.java @@ -0,0 +1,15 @@ +class A {} + +class List extends A { + T t; +} + + +class Test { + void foo (){ + List y = null; + A a = y; + + y.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/before/test.java new file mode 100644 index 00000000000..03476c73ba7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t121/before/test.java @@ -0,0 +1,15 @@ +class A {} + +class List extends A { + T t; +} + + +class Test { + void foo (){ + List y = null; + A a = y; + + y.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/after/test.java new file mode 100644 index 00000000000..81c1cbf6a5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/after/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class Mist extends List { +} + +class Test { + void foo (List y){ + y.t = ""; + Mist z = (Mist) y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/before/test.java new file mode 100644 index 00000000000..81c1cbf6a5d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t122/before/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class Mist extends List { +} + +class Test { + void foo (List y){ + y.t = ""; + Mist z = (Mist) y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/after/test.java new file mode 100644 index 00000000000..9a197a43201 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/after/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class A extends List{ +} + +class Test { + void foo (List y){ + y.t = ""; + A z = (A) y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/before/test.java new file mode 100644 index 00000000000..9a197a43201 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t123/before/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class A extends List{ +} + +class Test { + void foo (List y){ + y.t = ""; + A z = (A) y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/after/test.java new file mode 100644 index 00000000000..c115ddca12c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/after/test.java @@ -0,0 +1,12 @@ +interface Map { +} + +class THashMap implements Map { +} + +class Test { + void f() { + Map[] readVariables = null; + readVariables[0] = new THashMap(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/before/test.java new file mode 100644 index 00000000000..c115ddca12c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t124/before/test.java @@ -0,0 +1,12 @@ +interface Map { +} + +class THashMap implements Map { +} + +class Test { + void f() { + Map[] readVariables = null; + readVariables[0] = new THashMap(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/after/test.java new file mode 100644 index 00000000000..0b7813340a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/after/test.java @@ -0,0 +1,20 @@ +class Map{ + A a; + B b; +} + +class List{ +} + +class Test { + void f() { + List x = null; + List y = null; + + Map z = null; + + z.a = ""; + z.b = x; + z.b = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/before/test.java new file mode 100644 index 00000000000..0b7813340a5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t125/before/test.java @@ -0,0 +1,20 @@ +class Map{ + A a; + B b; +} + +class List{ +} + +class Test { + void f() { + List x = null; + List y = null; + + Map z = null; + + z.a = ""; + z.b = x; + z.b = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/after/test.java new file mode 100644 index 00000000000..f4244b5a6e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/after/test.java @@ -0,0 +1,19 @@ +class Map{ + A a; + B b; +} + +class List{ +} + +class Test { + void f() { + Map> x = null; + Map> y = null; + + Map z = null; + + z = x; + z = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/before/test.java new file mode 100644 index 00000000000..f4244b5a6e1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t126/before/test.java @@ -0,0 +1,19 @@ +class Map{ + A a; + B b; +} + +class List{ +} + +class Test { + void f() { + Map> x = null; + Map> y = null; + + Map z = null; + + z = x; + z = y; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/after/test.java new file mode 100644 index 00000000000..3dee6a20417 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/after/test.java @@ -0,0 +1,32 @@ +class A { +} + +class B extends A { +} + +class Collection{ +} + +class List extends Collection { + List(Collection a){ + } + + T t; +} + +class Convertor{ + static List asList (X[] x){ + return null; + } +} + +class Test { + + void f() { + A[] a = null; + List b = new List(Convertor.asList(a)); + B c = null; + b.t = c; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/before/test.java new file mode 100644 index 00000000000..3dee6a20417 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t127/before/test.java @@ -0,0 +1,32 @@ +class A { +} + +class B extends A { +} + +class Collection{ +} + +class List extends Collection { + List(Collection a){ + } + + T t; +} + +class Convertor{ + static List asList (X[] x){ + return null; + } +} + +class Test { + + void f() { + A[] a = null; + List b = new List(Convertor.asList(a)); + B c = null; + b.t = c; + } + +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/after/test.java new file mode 100644 index 00000000000..5fefa86deb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/after/test.java @@ -0,0 +1,21 @@ +class A {} +class B extends A {} + +class Collection{ + T t; +} + +class Set extends Collection{ + +} + +class Test { + void g(Collection ancestors) { + A a = (A) ancestors.t; + } + + void f() { + Set x = null; + g(x); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/before/test.java new file mode 100644 index 00000000000..5fefa86deb6 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t128/before/test.java @@ -0,0 +1,21 @@ +class A {} +class B extends A {} + +class Collection{ + T t; +} + +class Set extends Collection{ + +} + +class Test { + void g(Collection ancestors) { + A a = (A) ancestors.t; + } + + void f() { + Set x = null; + g(x); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/after/test.java new file mode 100644 index 00000000000..221ea837ebb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/after/test.java @@ -0,0 +1,22 @@ +class A {} +class B extends A {} + +class Collection{ + T t; +} + +class Set extends Collection{ + +} + +class Test { + void g(Collection ancestors) { + A a = (A) ancestors.t; + } + + void f() { + Set x = null; + x.t = new B(); + g(x); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/before/test.java new file mode 100644 index 00000000000..221ea837ebb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t129/before/test.java @@ -0,0 +1,22 @@ +class A {} +class B extends A {} + +class Collection{ + T t; +} + +class Set extends Collection{ + +} + +class Test { + void g(Collection ancestors) { + A a = (A) ancestors.t; + } + + void f() { + Set x = null; + x.t = new B(); + g(x); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/after/test.java new file mode 100644 index 00000000000..214675601a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/after/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x = (LinkedList) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/before/test.java new file mode 100644 index 00000000000..214675601a3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t13/before/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x = (LinkedList) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/after/test.java new file mode 100644 index 00000000000..6f5d6d3f488 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/after/test.java @@ -0,0 +1,25 @@ +class A {} +class B {} + +class Map{ + Y get (X x){ + return null; + } +} + +interface List { + void add(T t); +} + +class ArrayList implements List{ + public void add(E e){ + } +} + +public class Test { + private static void f(Map requestMap) { + ArrayList requests = (ArrayList)requestMap.get(new A()); + requests.add(new Object()); + f(new Map> ()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/before/test.java new file mode 100644 index 00000000000..6f5d6d3f488 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t130/before/test.java @@ -0,0 +1,25 @@ +class A {} +class B {} + +class Map{ + Y get (X x){ + return null; + } +} + +interface List { + void add(T t); +} + +class ArrayList implements List{ + public void add(E e){ + } +} + +public class Test { + private static void f(Map requestMap) { + ArrayList requests = (ArrayList)requestMap.get(new A()); + requests.add(new Object()); + f(new Map> ()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/after/test.java new file mode 100644 index 00000000000..75258bc7f72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/after/test.java @@ -0,0 +1,19 @@ +class List { + T t; +} + +class MyList

    extends List

    { + +} + +public class Test { + MyList[] l; + + List[] f (){ + return l; + } + + void g(){ + l[0].t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/before/test.java new file mode 100644 index 00000000000..75258bc7f72 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t131/before/test.java @@ -0,0 +1,19 @@ +class List { + T t; +} + +class MyList

    extends List

    { + +} + +public class Test { + MyList[] l; + + List[] f (){ + return l; + } + + void g(){ + l[0].t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/after/test.java new file mode 100644 index 00000000000..508cc5aed20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/after/test.java @@ -0,0 +1,32 @@ +public class Test { + class A{} + class B extends A{} + + class List { + List(X x){ + + } + } + + interface I { + List f (); + } + + I i1 = new I(){ + public List f(){ + return i2.f(); + } + }; + + I i2 = new I(){ + public List f(){ + return new List(new A()); + } + }; + + I i3 = new I(){ + public List f(){ + return new List(new B()); + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/before/test.java new file mode 100644 index 00000000000..508cc5aed20 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t132/before/test.java @@ -0,0 +1,32 @@ +public class Test { + class A{} + class B extends A{} + + class List { + List(X x){ + + } + } + + interface I { + List f (); + } + + I i1 = new I(){ + public List f(){ + return i2.f(); + } + }; + + I i2 = new I(){ + public List f(){ + return new List(new A()); + } + }; + + I i3 = new I(){ + public List f(){ + return new List(new B()); + } + }; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/after/test.java new file mode 100644 index 00000000000..b22b4113eb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/after/test.java @@ -0,0 +1,13 @@ +class List{ + X x; +} + +interface I {} + +public class Test { + void foo(){ + List x = null; + x.x = new I(){ + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/before/test.java new file mode 100644 index 00000000000..b22b4113eb4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t133/before/test.java @@ -0,0 +1,13 @@ +class List{ + X x; +} + +interface I {} + +public class Test { + void foo(){ + List x = null; + x.x = new I(){ + }; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/after/test.java new file mode 100644 index 00000000000..3df28550063 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/after/test.java @@ -0,0 +1,20 @@ +interface List{} + +class ArrayList

    implements List

    {} + +class Pair{} + +class C {} +class A {} +class B extends A{} + +class Test { + void buildAllMaps(){ + List> methods = new ArrayList>(); + ArrayList s = null; + g(methods); + } + + void g(List> list) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/before/test.java new file mode 100644 index 00000000000..3df28550063 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t134/before/test.java @@ -0,0 +1,20 @@ +interface List{} + +class ArrayList

    implements List

    {} + +class Pair{} + +class C {} +class A {} +class B extends A{} + +class Test { + void buildAllMaps(){ + List> methods = new ArrayList>(); + ArrayList s = null; + g(methods); + } + + void g(List> list) { + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/after/test.java new file mode 100644 index 00000000000..3a253ed08ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/after/test.java @@ -0,0 +1,17 @@ +class List

    { + P p; +} + +class Pair{ + X x; + Y y; +} + +class Test { + void f(){ + List a = null; + + a.p.x = ""; + a.p.y = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/before/test.java new file mode 100644 index 00000000000..3a253ed08ae --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t135/before/test.java @@ -0,0 +1,17 @@ +class List

    { + P p; +} + +class Pair{ + X x; + Y y; +} + +class Test { + void f(){ + List a = null; + + a.p.x = ""; + a.p.y = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/after/test.java new file mode 100644 index 00000000000..9445e2517d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/after/test.java @@ -0,0 +1,14 @@ +class List

    { + P p; +} + +class Pair{ + X x; + Y y; +} + +class Test { + void f(){ + List a = new List> (); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/before/test.java new file mode 100644 index 00000000000..9445e2517d3 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t136/before/test.java @@ -0,0 +1,14 @@ +class List

    { + P p; +} + +class Pair{ + X x; + Y y; +} + +class Test { + void f(){ + List a = new List> (); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/after/test.java new file mode 100644 index 00000000000..cfaad2fa7a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/after/test.java @@ -0,0 +1,19 @@ +interface Comparable { + boolean compare (X a, X b); +} + +class Test { + void sort(T[] x, Comparable c){ + } + + void f(){ + sort( + new String[1], + new Comparable(){ + public boolean compare(Object a, Object b) { + return true; + } + } + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/before/test.java new file mode 100644 index 00000000000..cfaad2fa7a1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t137/before/test.java @@ -0,0 +1,19 @@ +interface Comparable { + boolean compare (X a, X b); +} + +class Test { + void sort(T[] x, Comparable c){ + } + + void f(){ + sort( + new String[1], + new Comparable(){ + public boolean compare(Object a, Object b) { + return true; + } + } + ); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/after/test.java new file mode 100644 index 00000000000..d4b1c10dd08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/after/test.java @@ -0,0 +1,25 @@ +class Map{ + void put (X x, Y y){ + } + + Y get(X x){ + return null; + } +} + +class List{ + Z z; +} + +class Test{ + Map y; + + void foo(){ + List li = null; + y.put(li, ""); + } + + void f (List x, T z){ + y.put(x, z); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/before/test.java new file mode 100644 index 00000000000..d4b1c10dd08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t138/before/test.java @@ -0,0 +1,25 @@ +class Map{ + void put (X x, Y y){ + } + + Y get(X x){ + return null; + } +} + +class List{ + Z z; +} + +class Test{ + Map y; + + void foo(){ + List li = null; + y.put(li, ""); + } + + void f (List x, T z){ + y.put(x, z); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/after/test.java new file mode 100644 index 00000000000..c9aa527d073 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/after/test.java @@ -0,0 +1,16 @@ +class List{ + void put(T t){ + } + + void mut(List t){ + } +} + + +class Test{ + void foo(){ + List x = null; + + x.mut(new List()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/before/test.java new file mode 100644 index 00000000000..c9aa527d073 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t139/before/test.java @@ -0,0 +1,16 @@ +class List{ + void put(T t){ + } + + void mut(List t){ + } +} + + +class Test{ + void foo(){ + List x = null; + + x.mut(new List()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/after/test.java new file mode 100644 index 00000000000..81cb032f474 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/after/test.java @@ -0,0 +1,23 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x = y.get(); + y.set(new LinkedList ()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/before/test.java new file mode 100644 index 00000000000..81cb032f474 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t14/before/test.java @@ -0,0 +1,23 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x = y.get(); + y.set(new LinkedList ()); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/after/test.java new file mode 100644 index 00000000000..a1cc4ca3288 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/after/test.java @@ -0,0 +1,21 @@ +interface Iterator { + E next(); +} + +interface Collection { + Iterator iterator(); +} + +interface Map { + V put(K key, V value); + Collection values(); +} + +class Test { + public void doTest () { + Map map; + map.put ("key", new Integer (0)); + + Integer res = (Integer) map.values ().iterator ().next (); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/before/test.java new file mode 100644 index 00000000000..a1cc4ca3288 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t140/before/test.java @@ -0,0 +1,21 @@ +interface Iterator { + E next(); +} + +interface Collection { + Iterator iterator(); +} + +interface Map { + V put(K key, V value); + Collection values(); +} + +class Test { + public void doTest () { + Map map; + map.put ("key", new Integer (0)); + + Integer res = (Integer) map.values ().iterator ().next (); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t141/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t141/before/test.java new file mode 100644 index 00000000000..510c708fc44 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t141/before/test.java @@ -0,0 +1,8 @@ +interface I{} + +class Pair, Y extends I> { +} + +public class Test { + Pair pair; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t142/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t142/before/test.java new file mode 100644 index 00000000000..e4bdf395515 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t142/before/test.java @@ -0,0 +1,8 @@ +interface I{} + +class Pair>, Y extends I>> { +} + +public class Test { + Pair pair; +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t143/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t143/before/test.java new file mode 100644 index 00000000000..148ed4397a8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t143/before/test.java @@ -0,0 +1,13 @@ +interface I {} + +class Pair { + void foo (I i){} +} + +public class Test { + Pair pair; + + void bar(){ + pair.foo (new I ()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t144/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t144/before/test.java new file mode 100644 index 00000000000..08e1dbcf425 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t144/before/test.java @@ -0,0 +1,15 @@ +interface I {} + +class Pair implements I{ + X t; +} + +class Test { + Pair pair; + + X foo (I i){return null;} + + void bar(){ + String u = (String) foo (pair); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t145/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t145/before/test.java new file mode 100644 index 00000000000..37c40624e92 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t145/before/test.java @@ -0,0 +1,13 @@ +interface I {} + +class Pair { + void goo (I> i){} +} + +public class Test { + Pair pair; + + void bar(){ + pair.goo (new I ()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/after/test.java new file mode 100644 index 00000000000..ea6f07f11f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/after/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/before/test.java new file mode 100644 index 00000000000..ea6f07f11f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t15/before/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/after/test.java new file mode 100644 index 00000000000..ff6a9b22e54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/after/test.java @@ -0,0 +1,23 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x.set(y.get()); + Simple t = (Simple) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/before/test.java new file mode 100644 index 00000000000..ff6a9b22e54 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t16/before/test.java @@ -0,0 +1,23 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { + boolean f(){ + return false; + } +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x.set(y.get()); + Simple t = (Simple) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/after/test.java new file mode 100644 index 00000000000..171673bacc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/before/test.java new file mode 100644 index 00000000000..171673bacc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t17/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + void f(){ + y.set(x.get()); + Simple t = (Simple) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/after/test.java new file mode 100644 index 00000000000..233f559cb21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x=y; + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/before/test.java new file mode 100644 index 00000000000..233f559cb21 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t18/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + x=y; + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/after/test.java new file mode 100644 index 00000000000..cc24c1b423d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set((LinkedList) x.get()); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/before/test.java new file mode 100644 index 00000000000..cc24c1b423d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t19/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } +} + +class Simple { +} + +class Test{ + LinkedList y; + LinkedList x; + + void f(){ + y.set((LinkedList) x.get()); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/after/test.java new file mode 100644 index 00000000000..5f0129f3e63 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/after/test.java @@ -0,0 +1,26 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + void f(){ + LinkedList y; + y.set(new Integer(3)); + Iterator i; + i = y.iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/before/test.java new file mode 100644 index 00000000000..5f0129f3e63 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t20/before/test.java @@ -0,0 +1,26 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + void f(){ + LinkedList y; + y.set(new Integer(3)); + Iterator i; + i = y.iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/after/test.java new file mode 100644 index 00000000000..46437e3c834 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/after/test.java @@ -0,0 +1,29 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/before/test.java new file mode 100644 index 00000000000..46437e3c834 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t21/before/test.java @@ -0,0 +1,29 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public T get(){return t;} + public void set (T t){ + this.t = t; + } + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/after/test.java new file mode 100644 index 00000000000..4cc128c583d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/after/test.java @@ -0,0 +1,25 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/before/test.java new file mode 100644 index 00000000000..4cc128c583d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t22/before/test.java @@ -0,0 +1,25 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public Iterator iterator(){ + return null; + } +} + +class Simple { +} + +class Test{ + LinkedList x; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/after/test.java new file mode 100644 index 00000000000..2780b6240cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/after/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = y.get(); + y.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/before/test.java new file mode 100644 index 00000000000..2780b6240cc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t23/before/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = y.get(); + y.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/after/test.java new file mode 100644 index 00000000000..16a838e79a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/after/test.java @@ -0,0 +1,31 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + int i; + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = y.get(); + y.z.t = new String(); + x.i = 3; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/before/test.java new file mode 100644 index 00000000000..16a838e79a0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t24/before/test.java @@ -0,0 +1,31 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + int i; + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + x.t = y.get(); + y.z.t = new String(); + x.i = 3; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/after/test.java new file mode 100644 index 00000000000..1d747780448 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/after/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + y.z.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/before/test.java new file mode 100644 index 00000000000..1d747780448 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t25/before/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + y.z.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/after/test.java new file mode 100644 index 00000000000..b92e0db0d89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/after/test.java @@ -0,0 +1,18 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + Iterator> t; +} + +class Simple { +} + +class Test{ + LinkedList y; + + void f (){ + y.t = new Iterator>(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/before/test.java new file mode 100644 index 00000000000..b92e0db0d89 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t26/before/test.java @@ -0,0 +1,18 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + Iterator> t; +} + +class Simple { +} + +class Test{ + LinkedList y; + + void f (){ + y.t = new Iterator>(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/after/test.java new file mode 100644 index 00000000000..713ebfc1646 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/after/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + y.z.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/before/test.java new file mode 100644 index 00000000000..713ebfc1646 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t27/before/test.java @@ -0,0 +1,28 @@ +class Iterator{ + public T get(){return null;} +} + +class LinkedList{ + LinkedList z; + T t; + public Iterator iterator(){ + return null; + } + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList y; + + Test(Test t){ + x = t.x; + } + + void f (){ + y.z.t = new String(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/after/test.java new file mode 100644 index 00000000000..7fab6bd69eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/after/test.java @@ -0,0 +1,13 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y = x; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/before/test.java new file mode 100644 index 00000000000..7fab6bd69eb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t28/before/test.java @@ -0,0 +1,13 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + LinkedList x; + LinkedList y = x; +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/after/test.java new file mode 100644 index 00000000000..04390c727bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/after/test.java @@ -0,0 +1,15 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList x; + LinkedList y = x; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/before/test.java new file mode 100644 index 00000000000..04390c727bb --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t29/before/test.java @@ -0,0 +1,15 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList x; + LinkedList y = x; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/after/test.java new file mode 100644 index 00000000000..0b2e273760e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/after/test.java @@ -0,0 +1,15 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList y = new LinkedList(); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/before/test.java new file mode 100644 index 00000000000..0b2e273760e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t30/before/test.java @@ -0,0 +1,15 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList y = new LinkedList(); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/after/test.java new file mode 100644 index 00000000000..e2026fbe9aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/after/test.java @@ -0,0 +1,16 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList y; + y = new LinkedList(); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/before/test.java new file mode 100644 index 00000000000..e2026fbe9aa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t31/before/test.java @@ -0,0 +1,16 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class Simple { +} + +class Test{ + void f (){ + LinkedList y; + y = new LinkedList(); + y.set(new Integer(3)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/after/test.java new file mode 100644 index 00000000000..2811159dcbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/after/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class A { +} + +class B extends A { +} + +class C extends A { +} + +class Test{ + void f (){ + LinkedList y = new LinkedList(); + B b = (B) y.get(); + C c = (C) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/before/test.java new file mode 100644 index 00000000000..2811159dcbf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t32/before/test.java @@ -0,0 +1,22 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class A { +} + +class B extends A { +} + +class C extends A { +} + +class Test{ + void f (){ + LinkedList y = new LinkedList(); + B b = (B) y.get(); + C c = (C) y.get(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/after/test.java new file mode 100644 index 00000000000..d3b88f99773 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/after/test.java @@ -0,0 +1,14 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class List extends LinkedList{ +} + +class Test{ + void f (){ + LinkedList y = new List(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/before/test.java new file mode 100644 index 00000000000..d3b88f99773 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t33/before/test.java @@ -0,0 +1,14 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class List extends LinkedList{ +} + +class Test{ + void f (){ + LinkedList y = new List(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/after/test.java new file mode 100644 index 00000000000..efcf239aa5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/after/test.java @@ -0,0 +1,17 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class List extends LinkedList{ +} + +class Mist extends List{ +} + +class Test{ + void f (){ + LinkedList y = new Mist(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/before/test.java new file mode 100644 index 00000000000..efcf239aa5f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t34/before/test.java @@ -0,0 +1,17 @@ +class LinkedList{ + T t; + T get(){return t;} + void set(T t){} +} + +class List extends LinkedList{ +} + +class Mist extends List{ +} + +class Test{ + void f (){ + LinkedList y = new Mist(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/after/test.java new file mode 100644 index 00000000000..7849ee2fe98 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/after/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + E e; + T get(){return t;} + void set(E t){} +} + +class ListLinked extends LinkedList{ +} + +class Test{ + + void f (){ + ListLinked x = new ListLinked(); + LinkedList y = x; + + Integer i = (Integer) x.get(); + x.set(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/before/test.java new file mode 100644 index 00000000000..7849ee2fe98 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t35/before/test.java @@ -0,0 +1,20 @@ +class LinkedList{ + T t; + E e; + T get(){return t;} + void set(E t){} +} + +class ListLinked extends LinkedList{ +} + +class Test{ + + void f (){ + ListLinked x = new ListLinked(); + LinkedList y = x; + + Integer i = (Integer) x.get(); + x.set(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/after/test.java new file mode 100644 index 00000000000..afa7453bc9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/after/test.java @@ -0,0 +1,21 @@ +class LinkedList{ + T t; + E e; + T get(){return t;} + void set(E t){} +} + +class ListLinked extends LinkedList{ +} + +class Test{ + + void f (){ + ListLinked x = new ListLinked(); + LinkedList y = x; + + Integer i = (Integer) x.get(); + x.set(""); + y.set(new Integer(2)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/before/test.java new file mode 100644 index 00000000000..afa7453bc9b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t36/before/test.java @@ -0,0 +1,21 @@ +class LinkedList{ + T t; + E e; + T get(){return t;} + void set(E t){} +} + +class ListLinked extends LinkedList{ +} + +class Test{ + + void f (){ + ListLinked x = new ListLinked(); + LinkedList y = x; + + Integer i = (Integer) x.get(); + x.set(""); + y.set(new Integer(2)); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/after/test.java new file mode 100644 index 00000000000..c0bc9cc5d26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/after/test.java @@ -0,0 +1,25 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + y.t = new Integer(3); + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/before/test.java new file mode 100644 index 00000000000..c0bc9cc5d26 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t37/before/test.java @@ -0,0 +1,25 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + y.t = new Integer(3); + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/after/test.java new file mode 100644 index 00000000000..8837a7bc656 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/after/test.java @@ -0,0 +1,25 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + x.t = new Integer(3); + x.e = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/before/test.java new file mode 100644 index 00000000000..8837a7bc656 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t38/before/test.java @@ -0,0 +1,25 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + x.t = new Integer(3); + x.e = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/after/test.java new file mode 100644 index 00000000000..bc8535d3229 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/after/test.java @@ -0,0 +1,29 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + LinkedList f (LinkedList x){ + return x; + } + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + y.t = new Integer(3); + y = f (y); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/before/test.java new file mode 100644 index 00000000000..bc8535d3229 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t39/before/test.java @@ -0,0 +1,29 @@ +class LinkedList { + T t; + E e; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + LinkedList f (LinkedList x){ + return x; + } + + void f() { + ListLinked x = new ListLinked(); + LinkedList y = x; + + y.t = new Integer(3); + y = f (y); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/after/test.java new file mode 100644 index 00000000000..25d18397b9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/after/test.java @@ -0,0 +1,26 @@ +class LinkedList { + T t; + E e; + + LinkedList u; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + + y.u.t = new Integer(3); + y.u.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/before/test.java new file mode 100644 index 00000000000..25d18397b9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t40/before/test.java @@ -0,0 +1,26 @@ +class LinkedList { + T t; + E e; + + LinkedList u; + + T get() { + return t; + } + + void set(E t) { + } +} + +class ListLinked extends LinkedList { +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + + y.u.t = new Integer(3); + y.u.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/after/test.java new file mode 100644 index 00000000000..7e18f1dacc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/after/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T t; + + T get() { + return t; + } +} + + +class Test { + + void f (LinkedList x){ + x.t = ""; + } + + void f() { + LinkedList x = new LinkedList(); + + f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/before/test.java new file mode 100644 index 00000000000..7e18f1dacc0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t41/before/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T t; + + T get() { + return t; + } +} + + +class Test { + + void f (LinkedList x){ + x.t = ""; + } + + void f() { + LinkedList x = new LinkedList(); + + f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/after/test.java new file mode 100644 index 00000000000..8c187162ea9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/after/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T t; + + T get() { + return t; + } +} + + +class Test { + + void f (LinkedList x){ + return x.t = ""; + } + + void f() { + LinkedList x = new LinkedList(); + + f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/before/test.java new file mode 100644 index 00000000000..8c187162ea9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t42/before/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T t; + + T get() { + return t; + } +} + + +class Test { + + void f (LinkedList x){ + return x.t = ""; + } + + void f() { + LinkedList x = new LinkedList(); + + f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/after/test.java new file mode 100644 index 00000000000..5d4e0d8966a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/after/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T e; + + void set(LinkedList t) { + e=t.e; + } +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + LinkedList z=null; + + y.set(z); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/before/test.java new file mode 100644 index 00000000000..5d4e0d8966a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t43/before/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T e; + + void set(LinkedList t) { + e=t.e; + } +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + LinkedList z=null; + + y.set(z); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/after/test.java new file mode 100644 index 00000000000..bc50cfe4b0a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/after/test.java @@ -0,0 +1,19 @@ +class LinkedList { + T e; + + void set(LinkedList t) { + e=t.e; + } +} + +class ListInt extends LinkedList{} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + ListInt z=null; + + y.set(z); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/before/test.java new file mode 100644 index 00000000000..bc50cfe4b0a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t44/before/test.java @@ -0,0 +1,19 @@ +class LinkedList { + T e; + + void set(LinkedList t) { + e=t.e; + } +} + +class ListInt extends LinkedList{} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + ListInt z=null; + + y.set(z); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/after/test.java new file mode 100644 index 00000000000..30207548792 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/after/test.java @@ -0,0 +1,16 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + + (y.get()).e = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/before/test.java new file mode 100644 index 00000000000..30207548792 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t45/before/test.java @@ -0,0 +1,16 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + void f() { + LinkedList y = new LinkedList(); + + (y.get()).e = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/after/test.java new file mode 100644 index 00000000000..84f4c489f28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/after/test.java @@ -0,0 +1,18 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + LinkedList f() { + return null; + } + + void foo(){ + f().e = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/before/test.java new file mode 100644 index 00000000000..84f4c489f28 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t46/before/test.java @@ -0,0 +1,18 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + LinkedList f() { + return null; + } + + void foo(){ + f().e = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/after/test.java new file mode 100644 index 00000000000..5b2738f8bfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/after/test.java @@ -0,0 +1,18 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + LinkedList f() { + return null; + } + + void foo(){ + LinkedList x = (LinkedList) f(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/before/test.java new file mode 100644 index 00000000000..5b2738f8bfc --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t47/before/test.java @@ -0,0 +1,18 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + LinkedList f() { + return null; + } + + void foo(){ + LinkedList x = (LinkedList) f(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/after/test.java new file mode 100644 index 00000000000..e9e9df6c11a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/after/test.java @@ -0,0 +1,20 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + void f(LinkedList x) { + x.e = ""; + } + + void foo(){ + LinkedList y = new LinkedList(); + y.e = new Integer(3); + f(y); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/before/test.java new file mode 100644 index 00000000000..e9e9df6c11a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t48/before/test.java @@ -0,0 +1,20 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + void f(LinkedList x) { + x.e = ""; + } + + void foo(){ + LinkedList y = new LinkedList(); + y.e = new Integer(3); + f(y); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/after/test.java new file mode 100644 index 00000000000..5303a92851c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/after/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + Test x = new Test(new LinkedList()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/before/test.java new file mode 100644 index 00000000000..5303a92851c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t49/before/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + Test x = new Test(new LinkedList()); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/after/test.java new file mode 100644 index 00000000000..29e9a4f1716 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/after/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + LinkedList y = new LinkedList(); + + Test x = new Test(y); + + y.e = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/before/test.java new file mode 100644 index 00000000000..29e9a4f1716 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t50/before/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + LinkedList y = new LinkedList(); + + Test x = new Test(y); + + y.e = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/after/test.java new file mode 100644 index 00000000000..dbd7d24c491 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/after/test.java @@ -0,0 +1,19 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + LinkedList y = null; + + Test x = new Test(null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/before/test.java new file mode 100644 index 00000000000..dbd7d24c491 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t51/before/test.java @@ -0,0 +1,19 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + + Test(LinkedList x){ + } + + void foo(){ + LinkedList y = null; + + Test x = new Test(null); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/after/test.java new file mode 100644 index 00000000000..da93dabf6a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/after/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Aux{ + LinkedList x; +} + +class Test { + Aux a = null; + + void foo(){ + LinkedList y = a.x; + + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/before/test.java new file mode 100644 index 00000000000..da93dabf6a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t52/before/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Aux{ + LinkedList x; +} + +class Test { + Aux a = null; + + void foo(){ + LinkedList y = a.x; + + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/after/test.java new file mode 100644 index 00000000000..d4a5f4ac18c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/after/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Aux{ + LinkedList x; +} + +class Test { + Aux a = null; + + void foo(){ + LinkedList y = a.x; + + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/before/test.java new file mode 100644 index 00000000000..d4a5f4ac18c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t53/before/test.java @@ -0,0 +1,21 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Aux{ + LinkedList x; +} + +class Test { + Aux a = null; + + void foo(){ + LinkedList y = a.x; + + y.e = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/after/test.java new file mode 100644 index 00000000000..aead3a84f9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/after/test.java @@ -0,0 +1,15 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + LinkedList x; + + Test(Test y){ + x = y.x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/before/test.java new file mode 100644 index 00000000000..aead3a84f9e --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t54/before/test.java @@ -0,0 +1,15 @@ +class LinkedList { + T e; + + LinkedList get() { + return this; + } +} + +class Test { + LinkedList x; + + Test(Test y){ + x = y.x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/after/test.java new file mode 100644 index 00000000000..0e9814e238a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/after/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T t; + E e; + + LinkedList get() { + return this; + } +} + +class Test { + LinkedList x; + + void foo(){ + x.get().t = ""; + x.get().e = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/before/test.java new file mode 100644 index 00000000000..0e9814e238a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t55/before/test.java @@ -0,0 +1,17 @@ +class LinkedList { + T t; + E e; + + LinkedList get() { + return this; + } +} + +class Test { + LinkedList x; + + void foo(){ + x.get().t = ""; + x.get().e = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/after/test.java new file mode 100644 index 00000000000..bf38b674482 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/after/test.java @@ -0,0 +1,28 @@ +class LinkedList { + T e; + + T get() { + return e; + } + + void set(T t) { + + } +} + + + +class Test { + + void foo() { + LinkedList x = null; + LinkedList y = null; + LinkedList z = null; + + y = x.get(); + z = x.get(); + + y.set(new Integer(3)); + z.set(""); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/before/test.java new file mode 100644 index 00000000000..bf38b674482 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t56/before/test.java @@ -0,0 +1,28 @@ +class LinkedList { + T e; + + T get() { + return e; + } + + void set(T t) { + + } +} + + + +class Test { + + void foo() { + LinkedList x = null; + LinkedList y = null; + LinkedList z = null; + + y = x.get(); + z = x.get(); + + y.set(new Integer(3)); + z.set(""); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/after/test.java new file mode 100644 index 00000000000..5b2da96f133 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/after/test.java @@ -0,0 +1,16 @@ +class Coll { + X f; + Y s; + Coll a; +} + + + +class Test { + + void foo() { + Coll x; + x.f = ""; + x.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/before/test.java new file mode 100644 index 00000000000..5b2da96f133 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t57/before/test.java @@ -0,0 +1,16 @@ +class Coll { + X f; + Y s; + Coll a; +} + + + +class Test { + + void foo() { + Coll x; + x.f = ""; + x.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/after/test.java new file mode 100644 index 00000000000..a5ef4f53b00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/after/test.java @@ -0,0 +1,14 @@ +class Coll { + X f; + Y s; + Coll a; +} + +class Test { + + void foo() { + Coll x; + x.a.f = ""; + x.a.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/before/test.java new file mode 100644 index 00000000000..a5ef4f53b00 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t58/before/test.java @@ -0,0 +1,14 @@ +class Coll { + X f; + Y s; + Coll a; +} + +class Test { + + void foo() { + Coll x; + x.a.f = ""; + x.a.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/after/test.java new file mode 100644 index 00000000000..40f9ff21a71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/after/test.java @@ -0,0 +1,16 @@ +class Coll { + X f; + Y s; + Coll a; +} + + + +class Test { + + void foo() { + Coll x; + x.a.a.f = ""; + x.a.a.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/before/test.java new file mode 100644 index 00000000000..40f9ff21a71 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t59/before/test.java @@ -0,0 +1,16 @@ +class Coll { + X f; + Y s; + Coll a; +} + + + +class Test { + + void foo() { + Coll x; + x.a.a.f = ""; + x.a.a.s = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/after/test.java new file mode 100644 index 00000000000..3fc1ee3db8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/after/test.java @@ -0,0 +1,20 @@ +class OhYeah{ + T t; +} + +class Coll { + X f; + Y s; + OhYeah> a; +} + + + +class Test { + + void foo() { + Coll x; + x.f = ""; + x.a.t = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/before/test.java new file mode 100644 index 00000000000..3fc1ee3db8c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t60/before/test.java @@ -0,0 +1,20 @@ +class OhYeah{ + T t; +} + +class Coll { + X f; + Y s; + OhYeah> a; +} + + + +class Test { + + void foo() { + Coll x; + x.f = ""; + x.a.t = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/after/test.java new file mode 100644 index 00000000000..e804cb33907 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/after/test.java @@ -0,0 +1,14 @@ +class OhYeah { + Z t; +} + +class Coll > { + X f; +} + +class Test { + void foo() { + Coll x; + x.f.t = new Integer(2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/before/test.java new file mode 100644 index 00000000000..e804cb33907 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t61/before/test.java @@ -0,0 +1,14 @@ +class OhYeah { + Z t; +} + +class Coll > { + X f; +} + +class Test { + void foo() { + Coll x; + x.f.t = new Integer(2); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/after/test.java new file mode 100644 index 00000000000..07b753ab2ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/after/test.java @@ -0,0 +1,11 @@ +class Coll { + T t; + Coll x; +} + +class Test { + void foo() { + Coll x; + x.x.t = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/before/test.java new file mode 100644 index 00000000000..07b753ab2ac --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t62/before/test.java @@ -0,0 +1,11 @@ +class Coll { + T t; + Coll x; +} + +class Test { + void foo() { + Coll x; + x.x.t = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/after/test.java new file mode 100644 index 00000000000..874a002ecf9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/after/test.java @@ -0,0 +1,14 @@ +class Coll { + T t; + X x; + Coll f() {return null;}; +} + +class Test { + void foo() { + Coll x; + + x.f().t = ""; + x.t = new Integer(4); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/before/test.java new file mode 100644 index 00000000000..874a002ecf9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t63/before/test.java @@ -0,0 +1,14 @@ +class Coll { + T t; + X x; + Coll f() {return null;}; +} + +class Test { + void foo() { + Coll x; + + x.f().t = ""; + x.t = new Integer(4); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/after/test.java new file mode 100644 index 00000000000..cf0f96d0bff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/after/test.java @@ -0,0 +1,17 @@ +class OhYeah{ + Z z; +} + +class Coll > { + T t; + X x; + X f() {return null;}; +} + +class Test { + void foo() { + Coll x; + + x.f().z = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/before/test.java new file mode 100644 index 00000000000..cf0f96d0bff --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t64/before/test.java @@ -0,0 +1,17 @@ +class OhYeah{ + Z z; +} + +class Coll > { + T t; + X x; + X f() {return null;}; +} + +class Test { + void foo() { + Coll x; + + x.f().z = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/after/test.java new file mode 100644 index 00000000000..8a4534ce8db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/after/test.java @@ -0,0 +1,13 @@ +class Map { + T t; + X x; +} + +class Test { + void foo() { + Map x = new Map(); + + x.t = ""; + x.x = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/before/test.java new file mode 100644 index 00000000000..8a4534ce8db --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t65/before/test.java @@ -0,0 +1,13 @@ +class Map { + T t; + X x; +} + +class Test { + void foo() { + Map x = new Map(); + + x.t = ""; + x.x = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/after/test.java new file mode 100644 index 00000000000..0c9b66808ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/after/test.java @@ -0,0 +1,14 @@ +class Map { + T t; + X x; +} + +class Test { + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/before/test.java new file mode 100644 index 00000000000..0c9b66808ad --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t66/before/test.java @@ -0,0 +1,14 @@ +class Map { + T t; + X x; +} + +class Test { + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/after/test.java new file mode 100644 index 00000000000..517e52cfb45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/after/test.java @@ -0,0 +1,22 @@ +class Map { + T t; + X x; +} + +class Pam extends Map { +} + +class Test { + + Map f (Pam x){ + return x; + } + + void foo() { + Pam x = new Pam (); + + x.x = ""; + + Map y = f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/before/test.java new file mode 100644 index 00000000000..517e52cfb45 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t67/before/test.java @@ -0,0 +1,22 @@ +class Map { + T t; + X x; +} + +class Pam extends Map { +} + +class Test { + + Map f (Pam x){ + return x; + } + + void foo() { + Pam x = new Pam (); + + x.x = ""; + + Map y = f (x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/after/test.java new file mode 100644 index 00000000000..ed298c000e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/after/test.java @@ -0,0 +1,20 @@ +class Map { + T t; + X x; + + int size(){ + return 0; + } +} + +class Test { + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + + Test[] t = new Test[x.size()]; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/before/test.java new file mode 100644 index 00000000000..ed298c000e7 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t68/before/test.java @@ -0,0 +1,20 @@ +class Map { + T t; + X x; + + int size(){ + return 0; + } +} + +class Test { + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + + Test[] t = new Test[x.size()]; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/after/test.java new file mode 100644 index 00000000000..dae5a2d5009 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/after/test.java @@ -0,0 +1,29 @@ +class Map { + T t; + X x; + + T get(){ + return null; + } + + int size(){ + return 0; + } +} + +class Test { + + void f (Map x){ + String i = (String) x.get(); + } + + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + + f(x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/before/test.java new file mode 100644 index 00000000000..dae5a2d5009 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t69/before/test.java @@ -0,0 +1,29 @@ +class Map { + T t; + X x; + + T get(){ + return null; + } + + int size(){ + return 0; + } +} + +class Test { + + void f (Map x){ + String i = (String) x.get(); + } + + void foo() { + Map x = new Map(); + Map y = x; + + x.t = ""; + x.x = new Integer(3); + + f(x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/after/test.java new file mode 100644 index 00000000000..312eb231b2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/after/test.java @@ -0,0 +1,21 @@ +class External{ + static void f (List x){ + } +} + +class List { + T t; + + void set(T t, E e){ + this.t = t; + } +} + +class Test { + + void f (){ + List x = new List(); + x.set("", ""); + External.f(x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/before/test.java new file mode 100644 index 00000000000..312eb231b2d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t70/before/test.java @@ -0,0 +1,21 @@ +class External{ + static void f (List x){ + } +} + +class List { + T t; + + void set(T t, E e){ + this.t = t; + } +} + +class Test { + + void f (){ + List x = new List(); + x.set("", ""); + External.f(x); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/after/test.java new file mode 100644 index 00000000000..6777febc235 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/after/test.java @@ -0,0 +1,22 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + + static List x = new List(); + + static void f (){ + x.set(""); + } +} + +class External{ + static List f (){ + return Test.x; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/before/test.java new file mode 100644 index 00000000000..6777febc235 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t71/before/test.java @@ -0,0 +1,22 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + + static List x = new List(); + + static void f (){ + x.set(""); + } +} + +class External{ + static List f (){ + return Test.x; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/after/test.java new file mode 100644 index 00000000000..593141f5b0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/after/test.java @@ -0,0 +1,17 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + + y.set(""); + + List[] x = new List[] {y}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/before/test.java new file mode 100644 index 00000000000..593141f5b0d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t72/before/test.java @@ -0,0 +1,17 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + + y.set(""); + + List[] x = new List[] {y}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/after/test.java new file mode 100644 index 00000000000..b9352abaa10 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/after/test.java @@ -0,0 +1,16 @@ +class List { + T t; +} + +class Test { + void foo (){ + List y = new List(); + List x = new List(); + + x.t = y.t; + y.t = x.t; + + x.t = ""; + y.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/before/test.java new file mode 100644 index 00000000000..b9352abaa10 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t73/before/test.java @@ -0,0 +1,16 @@ +class List { + T t; +} + +class Test { + void foo (){ + List y = new List(); + List x = new List(); + + x.t = y.t; + y.t = x.t; + + x.t = ""; + y.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/after/test.java new file mode 100644 index 00000000000..b6672d7c831 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/after/test.java @@ -0,0 +1,16 @@ +class List { + T t; +} + +class Test { + void foo (){ + //List y = new List(); + List x = new List(); + + //x.t = y.t; + // y.t = x.t; + + x.t.t = ""; + //y.t.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/before/test.java new file mode 100644 index 00000000000..b6672d7c831 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t74/before/test.java @@ -0,0 +1,16 @@ +class List { + T t; +} + +class Test { + void foo (){ + //List y = new List(); + List x = new List(); + + //x.t = y.t; + // y.t = x.t; + + x.t.t = ""; + //y.t.t = new Integer(3); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/after/test.java new file mode 100644 index 00000000000..2f6c35c6555 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/after/test.java @@ -0,0 +1,31 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set().iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/before/test.java new file mode 100644 index 00000000000..2f6c35c6555 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t75/before/test.java @@ -0,0 +1,31 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set().iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/after/test.java new file mode 100644 index 00000000000..5bb0134b2de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/after/test.java @@ -0,0 +1,33 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + u.d = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/before/test.java new file mode 100644 index 00000000000..5bb0134b2de --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t76/before/test.java @@ -0,0 +1,33 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + u.d = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/after/test.java new file mode 100644 index 00000000000..2834bfa0ab9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/after/test.java @@ -0,0 +1,33 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + String s = (String) u.d; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/before/test.java new file mode 100644 index 00000000000..2834bfa0ab9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t77/before/test.java @@ -0,0 +1,33 @@ +class List { + A t; + + Set set(){ + return null; + } +} + +class OfList extends List { + +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + String s = (String) u.d; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/after/test.java new file mode 100644 index 00000000000..72e499a8a64 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/after/test.java @@ -0,0 +1,25 @@ +class List { + A t; + + Set set; +} + +class OfList extends List { + +} + +class Iterator { + C get; +} + +class Set { + Iterator iterator; +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set.iterator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/before/test.java new file mode 100644 index 00000000000..72e499a8a64 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t78/before/test.java @@ -0,0 +1,25 @@ +class List { + A t; + + Set set; +} + +class OfList extends List { + +} + +class Iterator { + C get; +} + +class Set { + Iterator iterator; +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set.iterator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/after/test.java new file mode 100644 index 00000000000..7766bbed717 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/after/test.java @@ -0,0 +1,21 @@ +class OfList { + B t; + + Set set; +} + +class Iterator { + C get; +} + +class Set { + Iterator iterator; +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set.iterator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/before/test.java new file mode 100644 index 00000000000..7766bbed717 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t79/before/test.java @@ -0,0 +1,21 @@ +class OfList { + B t; + + Set set; +} + +class Iterator { + C get; +} + +class Set { + Iterator iterator; +} + +class Test { + void foo (){ + OfList x = new OfList(); + x.t = ""; + Iterator i = x.set.iterator; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/after/test.java new file mode 100644 index 00000000000..ad6dbb9f1a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/after/test.java @@ -0,0 +1,29 @@ +class OfList { + B t; + + Set set(){ + return null; + } +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + u.d = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/before/test.java new file mode 100644 index 00000000000..ad6dbb9f1a9 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t80/before/test.java @@ -0,0 +1,29 @@ +class OfList { + B t; + + Set set(){ + return null; + } +} + +class Iterator { + C get (){ + return null; + } +} + +class Set { + D d; + Iterator iterator(){ + return null; + } +} + +class Test { + void foo (){ + OfList x = new OfList(); + Iterator i = x.set().iterator(); + Set u = (Set) i.get(); + u.d = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/after/test.java new file mode 100644 index 00000000000..76e2016004b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/after/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class Test { + void foo (){ + List[] y = new List [10]; + List x = y[0]; + + y[1].t = ""; + x.t = new Integer(2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/before/test.java new file mode 100644 index 00000000000..76e2016004b --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t81/before/test.java @@ -0,0 +1,13 @@ +class List { + T t; +} + +class Test { + void foo (){ + List[] y = new List [10]; + List x = y[0]; + + y[1].t = ""; + x.t = new Integer(2); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/after/test.java new file mode 100644 index 00000000000..2802a5a3a22 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/after/test.java @@ -0,0 +1,19 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + List z = new List(); + + y.set(""); + z.set(new Integer(3)); + + List[] x = new List[] {y, z}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/before/test.java new file mode 100644 index 00000000000..2802a5a3a22 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t82/before/test.java @@ -0,0 +1,19 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + List z = new List(); + + y.set(""); + z.set(new Integer(3)); + + List[] x = new List[] {y, z}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/after/test.java new file mode 100644 index 00000000000..9eae2a52f9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/after/test.java @@ -0,0 +1,18 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + List z = new List(); + + y.set(""); + + List[] x = new List[] {y, z}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/before/test.java new file mode 100644 index 00000000000..9eae2a52f9f --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t83/before/test.java @@ -0,0 +1,18 @@ +class List { + T t; + + void set(T t){ + this.t = t; + } +} + +class Test { + void foo (){ + List y = new List(); + List z = new List(); + + y.set(""); + + List[] x = new List[] {y, z}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/after/test.java new file mode 100644 index 00000000000..92fdf0e34ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/after/test.java @@ -0,0 +1,12 @@ +class List { + T t; +} + +class Test { + List[] foo (){ + List x = null; + x.t = ""; + + return new List[]{x}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/before/test.java new file mode 100644 index 00000000000..92fdf0e34ce --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t84/before/test.java @@ -0,0 +1,12 @@ +class List { + T t; +} + +class Test { + List[] foo (){ + List x = null; + x.t = ""; + + return new List[]{x}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/after/test.java new file mode 100644 index 00000000000..987c8fb92f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/after/test.java @@ -0,0 +1,12 @@ +class List { + > void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + List y = null; + x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/before/test.java new file mode 100644 index 00000000000..987c8fb92f5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t85/before/test.java @@ -0,0 +1,12 @@ +class List { + > void f (A a){ + } +} + +class Test { + void foo (){ + List x = null; + List y = null; + x.f(y); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/after/test.java new file mode 100644 index 00000000000..b8be5c73e08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/after/test.java @@ -0,0 +1,15 @@ +class List { + T t; +} + +class Mist extends List{ + +} + +class Test { + void foo (){ + List x = new Mist(); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/before/test.java new file mode 100644 index 00000000000..b8be5c73e08 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t86/before/test.java @@ -0,0 +1,15 @@ +class List { + T t; +} + +class Mist extends List{ + +} + +class Test { + void foo (){ + List x = new Mist(); + + x.t = ""; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/after/test.java new file mode 100644 index 00000000000..8a7206fc533 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/after/test.java @@ -0,0 +1,11 @@ +class List { + T t; +} + +class Test { + void foo (){ + List x = new List(); + + int [] y = (int[]) x.t; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/before/test.java new file mode 100644 index 00000000000..8a7206fc533 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t87/before/test.java @@ -0,0 +1,11 @@ +class List { + T t; +} + +class Test { + void foo (){ + List x = new List(); + + int [] y = (int[]) x.t; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/after/test.java new file mode 100644 index 00000000000..9bf39b64323 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/after/test.java @@ -0,0 +1,11 @@ +class List { + T t; +} + +class Test { + void foo (){ + List x = new List(); + + x.t = new int[3]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/before/test.java new file mode 100644 index 00000000000..9bf39b64323 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t88/before/test.java @@ -0,0 +1,11 @@ +class List { + T t; +} + +class Test { + void foo (){ + List x = new List(); + + x.t = new int[3]; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/after/test.java new file mode 100644 index 00000000000..c84f2a537d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/after/test.java @@ -0,0 +1,14 @@ +class List { + T t; +} + +class Test { + Test(List x){ + } + + void foo (){ + List x = null; + x.t = ""; + Test y = new Test(x) {}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/before/test.java new file mode 100644 index 00000000000..c84f2a537d4 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t89/before/test.java @@ -0,0 +1,14 @@ +class List { + T t; +} + +class Test { + Test(List x){ + } + + void foo (){ + List x = null; + x.t = ""; + Test y = new Test(x) {}; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/after/test.java new file mode 100644 index 00000000000..6dfd2b0b788 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/after/test.java @@ -0,0 +1,23 @@ +class List { + T t; +} + +class Super { + void f (List x){ + } +} + +class Test extends Super { + void f (List x){ + x.t = ""; + } + + void g (List x){ + x.t = ""; + } +} + +class Sub extends Test{ + void g (List x){ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/before/test.java new file mode 100644 index 00000000000..6dfd2b0b788 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t90/before/test.java @@ -0,0 +1,23 @@ +class List { + T t; +} + +class Super { + void f (List x){ + } +} + +class Test extends Super { + void f (List x){ + x.t = ""; + } + + void g (List x){ + x.t = ""; + } +} + +class Sub extends Test{ + void g (List x){ + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/after/test.java new file mode 100644 index 00000000000..e96b88501f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/after/test.java @@ -0,0 +1,25 @@ +class List { + T t; +} + +class Test{ + class Super { + void f (List x){ + } + } + + class Middle extends Super { + void f (List x){ + x.t = ""; + } + + void g (List x){ + x.t = ""; + } + } + + class Sub extends Middle{ + void g (List x){ + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/before/test.java new file mode 100644 index 00000000000..e96b88501f8 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t91/before/test.java @@ -0,0 +1,25 @@ +class List { + T t; +} + +class Test{ + class Super { + void f (List x){ + } + } + + class Middle extends Super { + void f (List x){ + x.t = ""; + } + + void g (List x){ + x.t = ""; + } + } + + class Sub extends Middle{ + void g (List x){ + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/after/test.java new file mode 100644 index 00000000000..17c02e6d41d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/after/test.java @@ -0,0 +1,27 @@ +class List { + T t; +} + +class Test{ + class Super { + void f (List x){ + x = new List(); + } + } + + class Middle extends Super { + void f (List x){ + x.t = ""; + } + + List g (){ + return new List(); + } + } + + class Sub extends Middle{ + List g (){ + + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/before/test.java new file mode 100644 index 00000000000..17c02e6d41d --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t92/before/test.java @@ -0,0 +1,27 @@ +class List { + T t; +} + +class Test{ + class Super { + void f (List x){ + x = new List(); + } + } + + class Middle extends Super { + void f (List x){ + x.t = ""; + } + + List g (){ + return new List(); + } + } + + class Sub extends Middle{ + List g (){ + + } + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/after/test.java new file mode 100644 index 00000000000..6c2a1ba5ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/after/test.java @@ -0,0 +1,9 @@ +class List { + T t; +} + +class Test{ + List g (){ + return new List(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/before/test.java new file mode 100644 index 00000000000..6c2a1ba5ae2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t93/before/test.java @@ -0,0 +1,9 @@ +class List { + T t; +} + +class Test{ + List g (){ + return new List(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/after/test.java new file mode 100644 index 00000000000..d6752052dd5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/after/test.java @@ -0,0 +1,12 @@ +class List { + T t; +} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + (true ? x : y).t = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/before/test.java new file mode 100644 index 00000000000..d6752052dd5 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t94/before/test.java @@ -0,0 +1,12 @@ +class List { + T t; +} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + (true ? x : y).t = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/after/test.java new file mode 100644 index 00000000000..41fbd4ae991 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/after/test.java @@ -0,0 +1,15 @@ +class List { + T t; +} + +class A {} +class B extends A {} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + x = y; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/before/test.java new file mode 100644 index 00000000000..41fbd4ae991 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t95/before/test.java @@ -0,0 +1,15 @@ +class List { + T t; +} + +class A {} +class B extends A {} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + x = y; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/after/test.java new file mode 100644 index 00000000000..615d5386465 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/after/test.java @@ -0,0 +1,17 @@ +class List { + T t; +} + +class A {} +class B extends A {} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + x.t.t = ""; + y.t = x.t; + y.t.t = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/before/test.java new file mode 100644 index 00000000000..615d5386465 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t96/before/test.java @@ -0,0 +1,17 @@ +class List { + T t; +} + +class A {} +class B extends A {} + +class Test{ + void foo(){ + List x = new List(); + List y = new List(); + + x.t.t = ""; + y.t = x.t; + y.t.t = new Integer(3); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/after/test.java new file mode 100644 index 00000000000..a524a2664c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/after/test.java @@ -0,0 +1,14 @@ +class List { + T t; +} + +interface A {} + +class Test{ + A foo(){ + List x = null; + x.t = ""; + + return (A) x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/before/test.java new file mode 100644 index 00000000000..a524a2664c0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t97/before/test.java @@ -0,0 +1,14 @@ +class List { + T t; +} + +interface A {} + +class Test{ + A foo(){ + List x = null; + x.t = ""; + + return (A) x; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/after/test.java new file mode 100644 index 00000000000..d911705e84c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/after/test.java @@ -0,0 +1,15 @@ +class List { + class Mist{ + A a; + } + + T t; + Mist m; +} + +class Test{ + void foo(){ + List x = null; + x.m.a = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/before/test.java new file mode 100644 index 00000000000..d911705e84c --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t98/before/test.java @@ -0,0 +1,15 @@ +class List { + class Mist{ + A a; + } + + T t; + Mist m; +} + +class Test{ + void foo(){ + List x = null; + x.m.a = ""; + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/after/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/after/test.java new file mode 100644 index 00000000000..1f34151d6bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/after/test.java @@ -0,0 +1,18 @@ +class List { + T t; +} + +interface A { + List get(); +} + +class Test{ + + void foo(){ + List x = new A() { + public List get(){ + return new List(); + } + }.get(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/before/test.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/before/test.java new file mode 100644 index 00000000000..1f34151d6bf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testData/refactoring/typeCook/t99/before/test.java @@ -0,0 +1,18 @@ +class List { + T t; +} + +interface A { + List get(); +} + +class Test{ + + void foo(){ + List x = new A() { + public List get(){ + return new List(); + } + }.get(); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/AllTests.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/AllTests.java new file mode 100644 index 00000000000..3e5035ecefa --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/AllTests.java @@ -0,0 +1,10 @@ +import junit.framework.Test; + +/** + * @author mike + */ +public class AllTests { + public static Test suite() throws Throwable { + return new com.intellij.TestAll(""); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ClassFinder.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ClassFinder.java new file mode 100644 index 00000000000..c1a4192e1f0 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/ClassFinder.java @@ -0,0 +1,55 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jun 7, 2002 + * Time: 8:27:57 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.Vector; + +public class ClassFinder { + private final Vector classNameList = new Vector(); + private final int startPackageName; + + public ClassFinder(final File classPathRoot, final String packageRoot) throws IOException { + startPackageName = classPathRoot.getAbsolutePath().length() + 1; + String directoryOffset = packageRoot.replace('.', File.separatorChar); + findAndStoreTestClasses(new File(classPathRoot, directoryOffset)); + } + + private String computeClassName(final File file) { + String absPath = file.getAbsolutePath(); + String packageBase = absPath.substring(startPackageName, absPath.length() - 6); + return packageBase.replace(File.separatorChar, '.'); + } + + private void findAndStoreTestClasses(final File currentDirectory) throws IOException { + String[] files = currentDirectory.list(); + if (files == null) return; + for (int i = 0; i < files.length; i++) { + File file = new File(currentDirectory, files[i]); + String fileName = file.getName(); + String suffix = "Test.class"; + int idx = fileName.indexOf(suffix); + + if (idx != -1 && (fileName.length() - idx) == suffix.length()) { + String className = computeClassName(file); + classNameList.add(className); + } else { + if (file.isDirectory()) { + findAndStoreTestClasses(file); + } + } + } + } + + public Iterator getClasses() { + return classNameList.iterator(); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestAll.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestAll.java new file mode 100644 index 00000000000..0a071392fa2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestAll.java @@ -0,0 +1,375 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jun 7, 2002 + * Time: 8:27:04 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij; + +import com.intellij.intellijac.CompileProjectTestcase; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.testFramework.IdeaTestCase; +import com.intellij.testFramework.LightIdeaTestCase; +import com.intellij.testFramework.TestLoggerFactory; +import com.intellij.util.ProfilingUtil; +import junit.framework.Test; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +import java.io.*; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +public class TestAll implements Test { + + static { + Logger.setFactory(TestLoggerFactory.getInstance()); + } + + private static final Logger LOG = Logger.getInstance("#com.intellij.TestAll"); + + private TestCaseLoader myTestCaseLoader; + private long myStartTime = 0; + private boolean myInterruptedByOutOfMemory = false; + private boolean myInterruptedByOutOfTime = false; + private long myLastTestStartTime = 0; + private String myLastTestClass; + private int myRunTests = -1; + private boolean mySavingMemorySnapshot; + private static final long MAX_MEMORY_SIZE = 128000000L; + + private static int SAVE_MEMORY_SNAPSHOT = 1; + private static int START_GUARD = 2; + private static int RUN_GC = 4; + private static int CHECK_MEMORY = 8; + private static int FILTER_CLASSES = 16; + + public static int ourMode = SAVE_MEMORY_SNAPSHOT | START_GUARD | RUN_GC | CHECK_MEMORY | FILTER_CLASSES; + private int myLastTestTestMethodCount = 0; + + public int countTestCases() { + List classes = myTestCaseLoader.getClasses(); + + int count = 0; + + for (Iterator i = classes.iterator(); i.hasNext();) { + Class testCaseClass = (Class)i.next(); + Test test = getTest(testCaseClass); + if (test != null) count += test.countTestCases(); + } + + return count; + } + + private void beforeFirstTest() { + if ((ourMode & START_GUARD) != 0) { + Thread timeAndMemoryGuard = new Thread() { + public void run() { + System.out.println("Starting Time and Memory Guard"); + while (true) { + try { + try { + Thread.sleep(10000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + // check for time spent on current test + if (myLastTestStartTime != 0) { + long currTime = System.currentTimeMillis(); + long secondsSpent = (currTime - myLastTestStartTime) / 1000L; + Thread currentThread = getCurrentThread(); + if (!mySavingMemorySnapshot) { + if (secondsSpent > (IdeaTestCase.ourTestTime * myLastTestTestMethodCount)) { + System.out.println("Interrupting current Test (out of time)! Seconds spent = " + secondsSpent); + myInterruptedByOutOfTime = true; + if (currentThread != null) { + currentThread.interrupt(); + if (!currentThread.isInterrupted()) { + currentThread.stop(new RuntimeException("Current Test Interrupted: OUT OF TIME!")); + } + + break; + } + } + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + System.out.println("Time and Memory Guard finished."); + } + }; + timeAndMemoryGuard.setDaemon(true); + timeAndMemoryGuard.start(); + } + myStartTime = System.currentTimeMillis(); + } + + private Thread getCurrentThread() { + if (IdeaTestCase.ourTestThread != null) { + return IdeaTestCase.ourTestThread; + } + else if (LightIdeaTestCase.ourTestThread != null) { + return LightIdeaTestCase.ourTestThread; + } + else { + return null; + } + } + + private void addErrorMessage(TestResult testResult, String message) { + String processedTestsMessage = myRunTests <= 0 ? "Noone test was run" : myRunTests + " tests processed"; + try { + testResult.startTest(this); + testResult.addError(this, new Throwable(processedTestsMessage + " before: " + message)); + testResult.endTest(this); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void run(final TestResult testResult) { + List classes = myTestCaseLoader.getClasses(); + int totalTests = classes.size(); + for (Iterator i = classes.iterator(); i.hasNext();) { + runNextTest(testResult, totalTests, i); + if (testResult.shouldStop()) break; + } + tryGc(10); + } + + private void runNextTest(final TestResult testResult, int totalTests, Iterator i) { + myRunTests++; + if (!checkAvaliableMemory(35, testResult)) { + testResult.stop(); + return; + } + if (testResult.errorCount() + testResult.failureCount() > 30) { + addErrorMessage(testResult, "Too many errors. Tests stopped. Total " + myRunTests + " of " + totalTests + " tests run"); + testResult.stop(); + return; + } + if (myStartTime == 0) { + boolean ourClassLoader = this.getClass().getClassLoader().getClass().getName().startsWith("com.intellij."); + if (!ourClassLoader) { + beforeFirstTest(); + } + } + else { + if (myInterruptedByOutOfMemory) { + addErrorMessage(testResult, + "Current Test Interrupted: OUT OF MEMORY! Class = " + myLastTestClass + " Total " + myRunTests + " of " + + totalTests + + " tests run"); + testResult.stop(); + } + else if (myInterruptedByOutOfTime) { + addErrorMessage(testResult, + "Current Test Interrupted: OUT OF TIME! Class = " + myLastTestClass + " Total " + myRunTests + " of " + + totalTests + + " tests run"); + testResult.stop(); + } + } + + Class testCaseClass = (Class)i.next(); + + System.out.println("\nRunning " + testCaseClass.getName()); + LOG.info("Running " + testCaseClass.getName()); + final Test test = getTest(testCaseClass); + + if (test != null) { + myLastTestClass = null; + + CompileProjectTestcase.setEcho(false); + + myLastTestClass = testCaseClass.getName(); + myLastTestStartTime = System.currentTimeMillis(); + myLastTestTestMethodCount = test.countTestCases(); + + try { + try { + Thread.sleep(100); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + test.run(testResult); + try { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + try { + Application application = ApplicationManager.getApplication(); + if (application != null) { + application.runWriteAction(new Runnable() { + public void run() { + //todo[myakovlev] is it necessary? + FileDocumentManager manager = FileDocumentManager.getInstance(); + if (manager instanceof FileDocumentManagerImpl) { + ((FileDocumentManagerImpl)manager).dropAllUnsavedDocuments(); + } + } + }); + } + } + catch (Throwable e) { + e.printStackTrace(System.err); + } + } + }, ModalityState.NON_MMODAL); + } + catch (Exception e) { + e.printStackTrace(); + } + } + catch (Throwable t) { + if (t instanceof OutOfMemoryError) { + if ((ourMode & SAVE_MEMORY_SNAPSHOT) != 0) { + try { + mySavingMemorySnapshot = true; + System.out.println("OutOfMemoryError detected. Saving memory snapshot started"); + ProfilingUtil.captureMemorySnapshot("allTests"); + } + finally { + System.out.println("Saving memory snapshot finished"); + mySavingMemorySnapshot = false; + } + } + } + testResult.addError(test, t); + } + } + } + + private boolean checkAvaliableMemory(int neededMemory, TestResult testResult) { + if ((ourMode & CHECK_MEMORY) == 0) return true; + + boolean possibleOutOfMemoryError = possibleOutOfMemory(neededMemory); + if (possibleOutOfMemoryError) { + tryGc(5); + possibleOutOfMemoryError = possibleOutOfMemory(neededMemory); + if (possibleOutOfMemoryError) { + System.out.println("OutOfMemoryError: dumping memory"); + Runtime runtime = Runtime.getRuntime(); + long total = runtime.totalMemory(); + long free = runtime.freeMemory(); + String errorMessage = "Too much memory used. Total: " + total + " free: " + free + " used: " + (total - free) + "\n"; + String message = ProfilingUtil.forceCaptureMemorySnapshot("AllTestsOutOfMemory"); + if (message != null) errorMessage += message; + addErrorMessage(testResult, errorMessage); + } + } + return !possibleOutOfMemoryError; + } + + private boolean possibleOutOfMemory(int neededMemory) { + Runtime runtime = Runtime.getRuntime(); + long maxMemory = runtime.maxMemory(); + long realFreeMemory = runtime.freeMemory() + (maxMemory - runtime.totalMemory()); + long meg = 1024 * 1024; + long needed = neededMemory * meg; + boolean possibleOutOfMemoryError = realFreeMemory < needed; + return possibleOutOfMemoryError; + } + + private Test getTest(Class testCaseClass) { + if ((testCaseClass.getModifiers() & Modifier.PUBLIC) == 0) return null; + + try { + Method suiteMethod = testCaseClass.getMethod("suite", new Class[0]); + return (Test)suiteMethod.invoke(null, new Class[0]); + } + catch (NoSuchMethodException e) { + return new TestSuite(testCaseClass); + } + catch (Exception e) { + System.err.println("Failed to execute suite ()"); + e.printStackTrace(); + } + + return null; + } + + private static String [] getClassRoots() { + return System.getProperty("java.class.path").split(File.pathSeparator); + } + + private static String[] getClassRootsByStas() { + String classpathFileName = System.getProperty("idea.test.classpath"); + if (classpathFileName == null) + throw new IllegalArgumentException("System property 'idea.test.classpath' should be point to file with classpath."); + + List classRoots = new ArrayList(); + try { + FileInputStream fis = new FileInputStream(classpathFileName); + ByteArrayOutputStream baos = new ByteArrayOutputStream(fis.available()); + FileUtil.copy(fis, baos); + fis.close(); + + StringTokenizer tokenizer = new StringTokenizer(baos.toString(), System.getProperty("line.separator"), false); + while (tokenizer.hasMoreTokens()) { + String path = tokenizer.nextToken(); + // skip jars + if (!path.endsWith(".jar")) + classRoots.add(path); + } + + return classRoots.toArray(new String [0]); + } + catch (FileNotFoundException e) { + throw new IllegalArgumentException("File " + classpathFileName + " is not exists."); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + public TestAll(String packageRoot) throws Throwable { + this(packageRoot, getClassRoots()); + } + + public TestAll(String packageRoot, String[] classRoots) throws IOException, ClassNotFoundException { + myTestCaseLoader = new TestCaseLoader((ourMode & FILTER_CLASSES) != 0 ? "tests/testGroups.properties" : ""); + myTestCaseLoader.addClassIfTestCase(Class.forName("_FirstInSuiteTest")); + + for (int i = 0; i < classRoots.length; i++) { + ClassFinder classFinder = new ClassFinder(new File(classRoots[i]), packageRoot); + myTestCaseLoader.loadTestCases(classFinder.getClasses()); + } + + System.out.println("Number of test classes found: " + myTestCaseLoader.getClasses().size()); + } + + // [myakovlev] Do not delete - it is for debugging + public static void tryGc(int times) { + if ((ourMode & RUN_GC) == 0) return; + + for (int qqq = 1; qqq < times; qqq++) { + try { + Thread.sleep(qqq * 1000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + java.lang.System.gc(); + //long mem = Runtime.getRuntime().totalMemory(); + System.out.println("Runtime.getRuntime().totalMemory() = " + Runtime.getRuntime().totalMemory()); + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestCaseLoader.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestCaseLoader.java new file mode 100644 index 00000000000..4f636d57582 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestCaseLoader.java @@ -0,0 +1,124 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Jun 7, 2002 + * Time: 8:30:35 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.*; + +public class TestCaseLoader { + public static final String TEST_NAME_SUFFIX = "Test"; + /** + * If true only loads tests that have a corresponding class without ``Test'' suffix. + */ + public static boolean USE_ADVANCED_LOGIC = false; + private final List myClassList = new ArrayList(); + private final TestClassesFilter myTestClassesFilter; + private final String myTestGroupName; + + public TestCaseLoader(String classFilterName) { + InputStream excludedStream = getClass().getClassLoader().getResourceAsStream(classFilterName); + if (excludedStream != null) { + try { + myTestClassesFilter = TestClassesFilter.createOn(new InputStreamReader(excludedStream)); + } + finally { + try { + excludedStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + } + else { + myTestClassesFilter = TestClassesFilter.EMPTY_CLASSES_FILTER; + } + + myTestGroupName = System.getProperty("idea.test.group"); + + System.out.println("Using test group: [" + (myTestGroupName == null ? "" : myTestGroupName) + "]"); + } + + /** + * Adds testCaseClass to the list of classdes + * if the class is a test case we wish to load. Calls + * shouldLoadTestCase () to determine that. + */ + void addClassIfTestCase(final Class testCaseClass) { + if (shouldAddTestCase(testCaseClass)) { + myClassList.add(testCaseClass); + } + } + + /** + * Determine if we should load this test case. + */ + private boolean shouldAddTestCase(final Class testCaseClass) { + boolean shouldAdd = false; + if ((testCaseClass.getModifiers() & Modifier.ABSTRACT) != 0) return false; + if ((TestCase.class.isAssignableFrom(testCaseClass) || TestSuite.class.isAssignableFrom(testCaseClass)) && + testCaseClass.getName().endsWith(TEST_NAME_SUFFIX)) { + if (shouldExcludeTestClass(testCaseClass)) return false; + if (USE_ADVANCED_LOGIC) { + String name = testCaseClass.getName().substring(0, testCaseClass.getName().length() - TEST_NAME_SUFFIX.length()); + try { + Class.forName(name); + shouldAdd = true; + } + catch (ClassNotFoundException ignored) { + } + } + else { + shouldAdd = true; + } + } + return shouldAdd; + } + + /** + * Determine if we should exclude this test case. + */ + private boolean shouldExcludeTestClass(Class testCaseClass) { + return !myTestClassesFilter.matches(testCaseClass.getName(), myTestGroupName); + } + + public void loadTestCases(final Iterator classNamesIterator) { + while (classNamesIterator.hasNext()) { + String className = (String)classNamesIterator.next(); + try { + Class candidateClass = Class.forName(className); + addClassIfTestCase(candidateClass); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + System.err.println("Cannot load class: " + className + " " + e.getMessage()); + } + catch (NoClassDefFoundError e) { + e.printStackTrace(); + System.err.println("Cannot load class that " + className + " is dependant on"); + } + catch (ExceptionInInitializerError e) { + e.printStackTrace(); + e.getException().printStackTrace(); + System.err.println("Cannot load class: " + className + " " + e.getException().getMessage()); + } + } + } + + public List getClasses() { + return Collections.unmodifiableList(myClassList); + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestClassesFilter.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestClassesFilter.java new file mode 100644 index 00000000000..9c5a0a1dbdf --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/TestClassesFilter.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduct the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * Neither the name of JetBrains or IntelliJ IDEA + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT + * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT + * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN + * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package com.intellij; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.*; +import java.util.regex.Pattern; + +public class TestClassesFilter { + + private final Map> myPatterns = new HashMap>(); + public static final TestClassesFilter EMPTY_CLASSES_FILTER = new TestClassesFilter(new HashMap>()); + public static final ArrayList EMPTY_LIST = new ArrayList(); + private List myAllPatterns = new ArrayList(); + public static final String ALL_EXCLUDE_DEFINED = "ALL_EXCLUDE_DEFINED"; + + private TestClassesFilter(Map> filters) { + + for (Iterator eachGroupName = filters.keySet().iterator(); eachGroupName.hasNext();) { + String groupName = eachGroupName.next(); + List filterList = filters.get(groupName); + ArrayList patterns = new ArrayList(); + myPatterns.put(groupName, patterns); + for (Iterator iterator = filterList.iterator(); iterator.hasNext();) { + String filter = iterator.next().trim(); + if (filter.length() == 0) continue; + filter = filter.replaceAll("\\*", ".\\*"); + Pattern pattern = Pattern.compile(filter); + myAllPatterns.add(pattern); + patterns.add(pattern); + } + } + } + + public static TestClassesFilter createOn(InputStreamReader inputStreamReader) { + try { + Map> groupNameToPatternsMap = new HashMap>(); + String currentGroupName = ""; + LineNumberReader lineNumberReader = new LineNumberReader(inputStreamReader); + String line; + while ((line = lineNumberReader.readLine()) != null) { + if (line.startsWith("[") && line.endsWith("]")) { + currentGroupName = line.substring(1, line.length() - 1); + } + else { + if (!groupNameToPatternsMap.containsKey(currentGroupName)) { + groupNameToPatternsMap.put(currentGroupName, new ArrayList()); + } + groupNameToPatternsMap.get(currentGroupName).add(line); + } + } + + return new TestClassesFilter(groupNameToPatternsMap); + } + catch (IOException e) { + return EMPTY_CLASSES_FILTER; + } + } + + private boolean matches(Collection patterns, String className) { + for (Iterator iterator = patterns.iterator(); iterator.hasNext();) { + Pattern pattern = iterator.next(); + if (pattern.matcher(className).matches()) { + return true; + } + } + return false; + + } + + + public boolean matches(String className, String groupName) { + List patterns = collectPatternsFor(groupName); + boolean result = matches(patterns, className); + //null group means all patterns from each defined group should be excluded + if (isAllExcludeDefinedGroup(groupName)) { + return !result; + } + else { + return result; + } + } + + private boolean isAllExcludeDefinedGroup(String groupName) { + if (groupName == null){ + return true; + } + + if (ALL_EXCLUDE_DEFINED.equals(groupName)){ + return true; + } + + return false; + } + + private List collectPatternsFor(String groupName) { + if (isAllExcludeDefinedGroup(groupName)){ + return myAllPatterns; + } else { + if (!myPatterns.containsKey(groupName)){ + return EMPTY_LIST; + } else { + return myPatterns.get(groupName); + } + } + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestCase.java new file mode 100644 index 00000000000..8e210b89079 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestCase.java @@ -0,0 +1,389 @@ +package com.intellij.codeInsight; + +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.PsiTestCase; +import com.intellij.testFramework.PsiTestData; + +import java.io.File; +import java.io.IOException; +import java.io.Writer; + +/** + * @author Mike + */ +public abstract class CodeInsightTestCase extends PsiTestCase { + protected Editor myEditor; + + public CodeInsightTestCase() { + myRunCommandForTest = true; + } + + protected Editor createEditor(VirtualFile file) { + return FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, file, 0), false); + } + + protected void tearDown() throws Exception { + FileEditorManager editorManager = FileEditorManager.getInstance(myProject); + VirtualFile[] openFiles = editorManager.getOpenFiles(); + for (int i = 0; i < openFiles.length; i++) { + editorManager.closeFile(openFiles[i]); + } + myEditor = null; + super.tearDown(); + } + + protected PsiTestData createData() { + return new CodeInsightTestData(); + } + + public static final String CARET_MARKER = ""; + public static final String SELECTION_START_MARKER = ""; + public static final String SELECTION_END_MARKER = ""; + + protected void configureByFile(String filePath) throws Exception { + configureByFile(filePath, null); + } + protected void configureByFile(String filePath, String projectRoot) throws Exception { + String fullPath = getTestDataPath() + filePath; + + final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + assertNotNull("file " + fullPath + " not found", vFile); + + File projectFile = projectRoot == null ? null : new File(getTestDataPath() + projectRoot); + + configureByFile(vFile, projectFile); + } + + protected String getTestDataPath() { + return PathManagerEx.getTestDataPath(); + } + + protected void configureByFile(final VirtualFile vFile) throws IOException { + configureByFile(vFile, null); + } + + protected VirtualFile configureByFiles(final VirtualFile[] vFiles, final File projectRoot) throws IOException { + myFile = null; + myEditor = null; + + final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + if (clearModelBeforeConfiguring()) { + rootModel.clear(); + } + File dir = createTempDirectory(); + myFilesToDelete.add(dir); + VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/')); + final VirtualFile[] newVFiles = new VirtualFile[vFiles.length]; + final RangeMarker[] caretMarkers = new RangeMarker[vFiles.length]; + final RangeMarker[] selStartMarkers = new RangeMarker[vFiles.length]; + final RangeMarker[] selEndMarkers = new RangeMarker[vFiles.length]; + final String[] newFileTexts = new String[vFiles.length]; + + for (int i = 0; i < vFiles.length; i++) { + VirtualFile vFile = vFiles[i]; + + assertNotNull(vFile); + String fileText = new String(vFile.contentsToCharArray()); + fileText = StringUtil.convertLineSeparators(fileText, "\n"); + Document document = EditorFactory.getInstance().createDocument(fileText); + + int caretIndex = fileText.indexOf(CARET_MARKER); + int selStartIndex = fileText.indexOf(SELECTION_START_MARKER); + int selEndIndex = fileText.indexOf(SELECTION_END_MARKER); + + final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null; + final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null; + final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null; + + if (caretMarker != null) { + document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length()); + } + if (selStartMarker != null) { + document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length()); + } + if (selEndMarker != null) { + document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length()); + } + + String newFileText = document.getText(); + + final VirtualFile newVFile; + if (projectRoot == null) { + newVFile = vDir.createChildData(this, vFile.getName()); + Writer writer = newVFile.getWriter(this); + writer.write(newFileText); + writer.close(); + } + else { + FileUtil.copyDir(projectRoot, dir); + //vFile.getPath().substring(PathManagerEx.getTestDataPath().length()) + newVFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(vDir.getPath() + vFile.getPath().substring(projectRoot.getPath().length())); + } + + newVFiles[i]=newVFile; + newFileTexts[i]=newFileText; + selEndMarkers[i]=selEndMarker; + selStartMarkers[i]=selStartMarker; + caretMarkers[i]=caretMarker; + } + + final ContentEntry contentEntry = rootModel.addContentEntry(vDir); + if (isAddDirToSource()) contentEntry.addSourceFolder(vDir, false); + rootModel.commit(); + + for (int i = 0; i < newVFiles.length; i++) { + VirtualFile newVFile = newVFiles[i]; + + PsiFile file = myPsiManager.findFile(newVFile); + if (myFile==null) myFile = file; + + Editor editor = createEditor(newVFile); + if (myEditor==null) myEditor = editor; + + if (caretMarkers[i] != null) { + int caretLine = StringUtil.offsetToLineNumber(newFileTexts[i], caretMarkers[i].getStartOffset()); + int caretCol = caretMarkers[i].getStartOffset() - StringUtil.lineColToOffset(newFileTexts[i], caretLine, 0); + LogicalPosition pos = new LogicalPosition(caretLine, caretCol); + editor.getCaretModel().moveToLogicalPosition(pos); + } + + if (selStartMarkers[i] != null) { + editor.getSelectionModel().setSelection(selStartMarkers[i].getStartOffset(), selEndMarkers[i].getStartOffset()); + } + } + + return vDir; + } + + protected File createTempDirectory() throws IOException { + File dir = FileUtil.createTempDirectory("unitTest", null); + return dir; + } + + protected boolean isAddDirToSource() { + return true; + } + + protected VirtualFile configureByFile(final VirtualFile vFile, final File projectRoot) throws IOException { + return configureByFiles(new VirtualFile[] {vFile},projectRoot); + } + + protected boolean clearModelBeforeConfiguring() { + return true; + } + + protected void setupCursorAndSelection(Editor editor) { + Document document = editor.getDocument(); + final String text = document.getText(); + + int caretIndex = text.indexOf(CARET_MARKER); + int selStartIndex = text.indexOf(SELECTION_START_MARKER); + int selEndIndex = text.indexOf(SELECTION_END_MARKER); + + final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null; + final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null; + final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null; + + if (caretMarker != null) { + document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length()); + } + if (selStartMarker != null) { + document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length()); + } + if (selEndMarker != null) { + document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length()); + } + + final String newText = document.getText(); + + if (caretMarker != null) { + int caretLine = StringUtil.offsetToLineNumber(newText, caretMarker.getStartOffset()); + int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newText, caretLine, 0); + LogicalPosition pos = new LogicalPosition(caretLine, caretCol); + editor.getCaretModel().moveToLogicalPosition(pos); + } + + if (selStartMarker != null) { + editor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset()); + } + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + } + + protected void configure(String path, String dataName) throws Exception { + super.configure(path, dataName); + + myEditor = createEditor(myFile.getVirtualFile()); + + com.intellij.codeInsight.CodeInsightTestData data = (com.intellij.codeInsight.CodeInsightTestData) myTestDataBefore; + + int selectionStart; + int selectionEnd; + + LogicalPosition pos = new LogicalPosition(data.getLineNumber() - 1, data.getColumnNumber() - 1); + myEditor.getCaretModel().moveToLogicalPosition(pos); + + selectionStart = selectionEnd = myEditor.getCaretModel().getOffset(); + + if (data.getSelectionStartColumnNumber() >= 0) { + selectionStart = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionStartColumnNumber() - 1)); + selectionEnd = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionEndColumnNumber() - 1)); + } + + myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd); + } + + protected void checkResultByFile(String filePath) throws Exception { + checkResultByFile(filePath, false); + } + + protected void checkResultByFile(String filePath, boolean stripTrailingSpaces) throws Exception { + if (stripTrailingSpaces) { + ((DocumentEx) myEditor.getDocument()).stripTrailingSpaces(false); + } + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + String fullPath = getTestDataPath() + filePath; + + final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + assertNotNull("Cannot find file " + fullPath, vFile); + String fileText = new String(vFile.contentsToCharArray()); + fileText = StringUtil.convertLineSeparators(fileText, "\n"); + Document document = EditorFactory.getInstance().createDocument(fileText); + + int caretIndex = fileText.indexOf(CARET_MARKER); + int selStartIndex = fileText.indexOf(SELECTION_START_MARKER); + int selEndIndex = fileText.indexOf(SELECTION_END_MARKER); + + final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null; + final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null; + final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null; + + if (caretMarker != null) { + document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length()); + } + if (selStartMarker != null) { + document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length()); + } + if (selEndMarker != null) { + document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length()); + } + + String newFileText = document.getText(); + String newFileText1 = newFileText; + if (stripTrailingSpaces) { + Document document1 = EditorFactory.getInstance().createDocument(newFileText); + ((DocumentEx) document1).stripTrailingSpaces(false); + newFileText1 = document1.getText(); + } + + String text = myFile.getText(); + text = StringUtil.convertLineSeparators(text, "\n"); + + assertEquals("Text mismatch in file " + filePath, newFileText1, text); + + if (caretMarker != null) { + int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset()); + int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0); + + assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1); + assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1); + } + + if (selStartMarker != null && selEndMarker != null) { + int selStartLine = StringUtil.offsetToLineNumber(newFileText, selStartMarker.getStartOffset()); + int selStartCol = selStartMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0); + + int selEndLine = StringUtil.offsetToLineNumber(newFileText, selEndMarker.getEndOffset()); + int selEndCol = selEndMarker.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0); + + assertEquals( + "selectionStartLine", + selStartLine + 1, + StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1); + + assertEquals( + "selectionStartCol", + selStartCol + 1, + myEditor.getSelectionModel().getSelectionStart() - StringUtil.lineColToOffset(newFileText, selStartLine, 0) + 1); + + assertEquals( + "selectionEndLine", + selEndLine + 1, + StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1); + + assertEquals( + "selectionEndCol", + selEndCol + 1, + myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + 1); + } + else { + assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection()); + } + } + + protected void checkResult(String dataName) throws Exception { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + super.checkResult(dataName); + + com.intellij.codeInsight.CodeInsightTestData data = (com.intellij.codeInsight.CodeInsightTestData) myTestDataAfter; + + if (data.getColumnNumber() >= 0) { + assertEquals(dataName + ":caretColumn", data.getColumnNumber(), myEditor.getCaretModel().getLogicalPosition().column + 1); + } + if (data.getLineNumber() >= 0) { + assertEquals(dataName + ":caretLine", data.getLineNumber(), myEditor.getCaretModel().getLogicalPosition().line + 1); + } + + int selectionStart = myEditor.getSelectionModel().getSelectionStart(); + int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); + LogicalPosition startPosition = myEditor.offsetToLogicalPosition(selectionStart); + LogicalPosition endPosition = myEditor.offsetToLogicalPosition(selectionEnd); + + if (data.getSelectionStartColumnNumber() >= 0) { + assertEquals(dataName + ":selectionStartColumn", data.getSelectionStartColumnNumber(), startPosition.column + 1); + } + if (data.getSelectionStartLineNumber() >= 0) { + assertEquals(dataName + ":selectionStartLine", data.getSelectionStartLineNumber(), startPosition.line + 1); + } + if (data.getSelectionEndColumnNumber() >= 0) { + assertEquals(dataName + ":selectionEndColumn", data.getSelectionEndColumnNumber(), endPosition.column + 1); + } + if (data.getSelectionEndLineNumber() >= 0) { + assertEquals(dataName + ":selectionEndLine", data.getSelectionEndLineNumber(), endPosition.line + 1); + } + } + + public Object getData(String dataId) { + if (dataId.equals(DataConstants.EDITOR)) { + return myEditor; + } + else { + return super.getData(dataId); + } + } + + protected VirtualFile getVirtualFile(String filePath) { + String fullPath = getTestDataPath() + filePath; + + final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + assertNotNull("file " + fullPath + " not found", vFile); + return vFile; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestData.java new file mode 100644 index 00000000000..80477924949 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/CodeInsightTestData.java @@ -0,0 +1,42 @@ +package com.intellij.codeInsight; + +import com.intellij.testFramework.PsiTestData; + +/** + * @author Mike + */ +public class CodeInsightTestData extends PsiTestData{ + public int LINE_NUMBER = -1; + public int COLUMN_NUMBER = -1; + public int SELECTION_START_LINE_NUMBER = -1; + public int SELECTION_START_COLUMN_NUMBER = -1; + public int SELECTION_END_LINE_NUMBER = -1; + public int SELECTION_END_COLUMN_NUMBER = -1; + + public CodeInsightTestData() { + } + + public int getLineNumber() { + return LINE_NUMBER; + } + + public int getColumnNumber() { + return COLUMN_NUMBER; + } + + public int getSelectionStartLineNumber() { + return SELECTION_START_LINE_NUMBER; + } + + public int getSelectionStartColumnNumber() { + return SELECTION_START_COLUMN_NUMBER; + } + + public int getSelectionEndLineNumber() { + return SELECTION_END_LINE_NUMBER; + } + + public int getSelectionEndColumnNumber() { + return SELECTION_END_COLUMN_NUMBER; + } +} diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java new file mode 100644 index 00000000000..a0e793cf30a --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java @@ -0,0 +1,80 @@ +package com.intellij.codeInsight.daemon; + +import com.intellij.codeInsight.CodeInsightTestCase; +import com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.PostHighlightingPass; +import com.intellij.mock.MockProgressInidicator; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.psi.PsiDocumentManager; + +import java.util.ArrayList; + +public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase { + protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos) throws Exception { + configureByFile(filePath); + doDoTest(checkWarnings, checkInfos); + } + protected void doTest(String filePath, String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception { + configureByFile(filePath, projectRoot); + doDoTest(checkWarnings, checkInfos); + } + + protected void doTest(VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception { + doTest(new VirtualFile[] { vFile }, checkWarnings, checkInfos ); + } + + protected void doTest(VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception { + configureByFiles(vFile,null); + doDoTest(checkWarnings, checkInfos); + } + + protected void doDoTest(boolean checkWarnings, boolean checkInfos) { + ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(),checkWarnings, checkInfos); + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + myFile.getText(); //to load text + VirtualFileFilter javaFilesFilter = new VirtualFileFilter() { + public boolean accept(VirtualFile file) { + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + return fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS; + } + }; + myPsiManager.setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work + + HighlightInfo[] infos = doHighlighting(); + + myPsiManager.setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); + + data.checkResult(infos, myEditor.getDocument().getText()); + } + + protected HighlightInfo[] doHighlighting() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + Document document = myEditor.getDocument(); + GeneralHighlightingPass action1 = new GeneralHighlightingPass( + myProject, myFile, document, 0, myFile.getTextLength(), false, true); + action1.doCollectInformation(new MockProgressInidicator()); + HighlightInfo[] highlights1 = action1.getHighlights(); + + PostHighlightingPass action2 = new PostHighlightingPass(myProject, myFile, myEditor, 0, myFile.getTextLength(), false); + action2.doCollectInformation(new MockProgressInidicator()); + HighlightInfo[] highlights2 = action2.getHighlights(); + + ArrayList list = new ArrayList(); + for (int i = 0; i < highlights1.length; i++) { + list.add(highlights1[i]); + } + for (int i = 0; i < highlights2.length; i++) { + list.add(highlights2[i]); + } + return list.toArray(new HighlightInfo[list.size()]); + } + +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/ExpectedHighlightingData.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/ExpectedHighlightingData.java new file mode 100644 index 00000000000..0c5acd051f2 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/ExpectedHighlightingData.java @@ -0,0 +1,237 @@ +/** + * @author cdr + */ +package com.intellij.codeInsight.daemon; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import junit.framework.Assert; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class ExpectedHighlightingData { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.ExpectedHighlightingData"); + + private static final String ERROR_MARKER = "error"; + private static final String WARNING_MARKER = "warning"; + private static final String INFO_MARKER = "info"; + private static final String END_LINE_HIGHLIGHT_MARKER = "EOLError"; + + static class ExpectedHighlightingSet { + public final String marker; + private final boolean endOfLine; + final boolean enabled; + Set infos; + HighlightInfoType defaultErrorType; + HighlightInfo.Severity severity; + + public ExpectedHighlightingSet(String marker, HighlightInfoType defaultErrorType,HighlightInfo.Severity severity, boolean endOfLine, boolean enabled) { + this.marker = marker; + this.endOfLine = endOfLine; + this.enabled = enabled; + infos = new com.intellij.util.containers.HashSet(); + this.defaultErrorType = defaultErrorType; + this.severity = severity; + } + } + Map highlightingTypes; + + public ExpectedHighlightingData(Document document,boolean checkWarnings, boolean checkInfos) { + highlightingTypes = new com.intellij.util.containers.HashMap(); + highlightingTypes.put(ERROR_MARKER, new ExpectedHighlightingSet(ERROR_MARKER, HighlightInfoType.ERROR, HighlightInfo.ERROR, false, true)); + highlightingTypes.put(WARNING_MARKER, new ExpectedHighlightingSet(WARNING_MARKER, HighlightInfoType.UNUSED_SYMBOL, HighlightInfo.WARNING, false, checkWarnings)); + highlightingTypes.put(INFO_MARKER, new ExpectedHighlightingSet(INFO_MARKER, HighlightInfoType.TODO, HighlightInfo.INFORMATION, false, checkInfos)); + highlightingTypes.put(END_LINE_HIGHLIGHT_MARKER, new ExpectedHighlightingSet(END_LINE_HIGHLIGHT_MARKER, HighlightInfoType.ERROR, HighlightInfo.ERROR, true, true)); + extractExpectedHighlightsSet(document); + } + + /** + * remove highlights (bounded with ...) from test case file + * @param document + */ + private void extractExpectedHighlightsSet(Document document) { + String text = document.getText(); + + String typesRegex = ""; + for (Iterator iterator = highlightingTypes.keySet().iterator(); iterator.hasNext();) { + String marker = iterator.next(); + typesRegex += (typesRegex.length()==0 ? "" : "|") + "(?:"+marker+")"; + } + + // er... + // any code then (with optional descr="...") then any code then then any code + String pat = ".*?(<(" + typesRegex + ")(?: descr=\\\"((?:[^\\\"\\\\]|\\\\\\\")*)\\\")?(?: type=\\\"([0-9A-Z_]+)\\\")?(/)?>)(.*)"; + //"(.+?)).*"; + Pattern p = Pattern.compile(pat, Pattern.DOTALL); + for (; ;) { + Matcher m = p.matcher(text); + if (m.matches()) { + int startOffset = m.start(1); + String marker = m.group(2); + final ExpectedHighlightingSet expectedHighlightingSet = highlightingTypes.get(marker); + + String descr = m.group(3); + if (descr == null) { + // no descr means any string by default + descr = "*"; + } + else if (descr.equals("null")) { + // explicit "null" descr + descr = null; + } + + String typeString = m.group(4); + String closeTagMarker = m.group(5); + String rest = m.group(6); + + String content; + int endOffset; + if (closeTagMarker == null) { + Pattern pat2 = Pattern.compile("(.*?)(.*)", Pattern.DOTALL); + final Matcher matcher2 = pat2.matcher(rest); + LOG.assertTrue(matcher2.matches()); + content = matcher2.group(1); + endOffset = m.start(6) + matcher2.start(2); + } + else { + // + content = ""; + endOffset = m.start(6); + } + + document.replaceString(startOffset, endOffset, content); + + final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(expectedHighlightingSet.defaultErrorType, startOffset, startOffset + content.length(), descr); + + HighlightInfoType type = null; + + if (typeString != null) { + Field[] fields = HighlightInfoType.class.getFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + try { + if (field.getName().equals(typeString)) type = (HighlightInfoType)field.get(null); + } + catch (Exception e) { + } + } + + if (type == null) LOG.assertTrue(false,"Wrong highlight type: " + typeString); + } + + highlightInfo.type = type; + highlightInfo.isAfterEndOfLine = expectedHighlightingSet.endOfLine; + LOG.assertTrue(expectedHighlightingSet.enabled); + expectedHighlightingSet.infos.add(highlightInfo); + } else { + break; + } + text = document.getText(); + } + } + + void checkResult(HighlightInfo[] infos, String text) { + for (int i = 0; i < infos.length; i++) { + HighlightInfo info = infos[i]; + if (!expectedInfosContainsInfo(this, info)) { + final int startOffset = info.startOffset; + final int endOffset = info.endOffset; + String s = text.substring(startOffset, endOffset); + String desc = info.description; + + int y1 = StringUtil.offsetToLineNumber(text, startOffset); + int y2 = StringUtil.offsetToLineNumber(text, endOffset); + int x1 = startOffset - StringUtil.lineColToOffset(text, y1, 0); + int x2 = endOffset - StringUtil.lineColToOffset(text, y2, 0); + + Assert.assertTrue("Extra text fragment highlighted " + + "(" + (x1 + 1) + ", " + (y1 + 1) + ")" + "-" + + "(" + (x2 + 1) + ", " + (y2 + 1) + ")" + + " :'" + + s + + "'" + (desc == null ? "" : " (" + desc + ")"), + false); + } + } + final Collection expectedHighlights = highlightingTypes.values(); + for (Iterator iterator = expectedHighlights.iterator(); + iterator.hasNext();) { + ExpectedHighlightingSet highlightingSet = iterator.next(); + + final Set expInfos = highlightingSet.infos; + for (Iterator iterator1 = expInfos.iterator(); iterator1.hasNext();) { + HighlightInfo expectedInfo = iterator1.next(); + if (!infosContainsExpectedInfo(infos, expectedInfo) && highlightingSet.enabled) { + final int startOffset = expectedInfo.startOffset; + final int endOffset = expectedInfo.endOffset; + String s = text.substring(startOffset, endOffset); + String desc = expectedInfo.description; + + int y1 = StringUtil.offsetToLineNumber(text, startOffset); + int y2 = StringUtil.offsetToLineNumber(text, endOffset); + int x1 = startOffset - StringUtil.lineColToOffset(text, y1, 0); + int x2 = endOffset - StringUtil.lineColToOffset(text, y2, 0); + + Assert.assertTrue("Text fragment was not highlighted " + + "(" + (x1 + 1) + ", " + (y1 + 1) + ")" + "-" + + "(" + (x2 + 1) + ", " + (y2 + 1) + ")" + + " :'" + + s + + "'" + (desc == null ? "" : " (" + desc + ")"), + false); + } + } + } + + } + + private static boolean infosContainsExpectedInfo(HighlightInfo[] infos, HighlightInfo expectedInfo) { + for (int i = 0; i < infos.length; i++) { + HighlightInfo info = infos[i]; + if (infoEquals(expectedInfo, info)) { + return true; + } + } + return false; + } + + private static boolean expectedInfosContainsInfo(ExpectedHighlightingData expectedHighlightsSet, HighlightInfo info) { + final Collection expectedHighlights = expectedHighlightsSet.highlightingTypes.values(); + for (Iterator iterator = expectedHighlights.iterator(); iterator.hasNext();) { + ExpectedHighlightingSet highlightingSet = iterator.next(); + if (highlightingSet.severity == info.getSeverity() && !highlightingSet.enabled) return true; + final Set infos = highlightingSet.infos; + for (Iterator iterator1 = infos.iterator(); iterator1.hasNext();) { + HighlightInfo expectedInfo = iterator1.next(); + if (infoEquals(expectedInfo, info)) { + return true; + } + } + } + return false; + } + + private static boolean infoEquals(HighlightInfo expectedInfo, HighlightInfo info) { + if (expectedInfo == info) return true; + return + info.getSeverity() == expectedInfo.getSeverity() && + info.startOffset + (info.isAfterEndOfLine ? 1 : 0) == expectedInfo.startOffset && + info.endOffset == expectedInfo.endOffset && + info.isAfterEndOfLine == expectedInfo.isAfterEndOfLine && + (expectedInfo.type == null || info.type == expectedInfo.type) && + + (Comparing.strEqual("*",expectedInfo.description) ? true : + expectedInfo.description == null || info.description == null ? info.description == expectedInfo.description : + Comparing.strEqual(info.description,expectedInfo.description)); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java new file mode 100644 index 00000000000..f5738cda1b1 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java @@ -0,0 +1,61 @@ +package com.intellij.codeInsight.daemon; + +import com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.PostHighlightingPass; +import com.intellij.mock.MockProgressInidicator; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.testFramework.LightCodeInsightTestCase; +import com.intellij.util.ArrayUtil; + +public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCase { + protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos) throws Exception { + configureByFile(filePath); + doDoTest(checkWarnings, checkInfos); + } + + private void doDoTest(boolean checkWarnings, boolean checkInfos) { + ((PsiManagerImpl) getPsiManager()).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); + + ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(),checkWarnings, checkInfos); + + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + getFile().getText(); //to load text + VirtualFileFilter javaFilesFilter = new VirtualFileFilter() { + public boolean accept(VirtualFile file) { + FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file); + return fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS; + } + }; + ((PsiManagerImpl) getPsiManager()).setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work + + HighlightInfo[] infos = doHighlighting(); + + ((PsiManagerImpl) getPsiManager()).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); + + expectedData.checkResult(infos, getEditor().getDocument().getText()); + } + + + protected HighlightInfo[] doHighlighting() { + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + + Document document = getEditor().getDocument(); + GeneralHighlightingPass action1 = new GeneralHighlightingPass(getProject(), getFile(), document, 0, getFile().getTextLength(), false, true); + action1.doCollectInformation(new MockProgressInidicator()); + HighlightInfo[] highlights1 = action1.getHighlights(); + + PostHighlightingPass action2 = new PostHighlightingPass(getProject(), getFile(), getEditor(), 0, getFile().getTextLength(), false); + action2.doCollectInformation(new MockProgressInidicator()); + HighlightInfo[] highlights2 = action2.getHighlights(); + + return ArrayUtil.mergeArrays(highlights1, highlights2, HighlightInfo.class); + } +} \ No newline at end of file diff --git a/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java new file mode 100644 index 00000000000..e847f91b455 --- /dev/null +++ b/src/test/resources/oracle/commits/intellij-community-7460e5adae69c7b17c951f1198a6b6900721a1ee/testSource/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java @@ -0,0 +1,113 @@ +package com.intellij.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.xml.XmlFile; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase { + protected void doTestFor(final String testName) throws Exception { + final String relativePath = getBasePath() + "/before" + testName; + final String testFullPath = getTestDataPath().replace(File.separatorChar, '/') + relativePath; + final File ioFile = new File(testFullPath); + String contents = StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(ioFile)), "\n"); + configureFromFileText(ioFile.getName(), contents); + + String comment = getFile() instanceof XmlFile ? "